mirror of
https://github.com/vercel/workflow.git
synced 2026-09-14 19:59:43 +08:00
Apply workflow function transformation in "step" mode (#420)
This commit is contained in:
@@ -0,0 +1,5 @@
|
||||
---
|
||||
"@workflow/swc-plugin": patch
|
||||
---
|
||||
|
||||
Apply workflow function transformation in "step" mode
|
||||
@@ -189,8 +189,8 @@ pub struct StepTransform {
|
||||
// Track all declared identifiers in module scope to avoid collisions
|
||||
declared_identifiers: HashSet<String>,
|
||||
// Track object property step functions for hoisting in step mode
|
||||
// (parent_var_name, prop_name, arrow_expr, span)
|
||||
object_property_step_functions: Vec<(String, String, ArrowExpr, swc_core::common::Span)>,
|
||||
// (parent_var_name, prop_name, arrow_expr, span, parent_workflow_name)
|
||||
object_property_step_functions: Vec<(String, String, ArrowExpr, swc_core::common::Span, String)>,
|
||||
// Track nested step functions inside workflow functions for hoisting in step mode
|
||||
// (fn_name, fn_expr, span, closure_vars, was_arrow, parent_workflow_name)
|
||||
nested_step_functions: Vec<(
|
||||
@@ -688,6 +688,42 @@ fn is_global_identifier(name: &str) -> bool {
|
||||
)
|
||||
}
|
||||
|
||||
// Visitor to normalize the SyntaxContext of closure variables in a function body.
|
||||
// This ensures that identifiers in the body match the ones we create in the
|
||||
// closure destructuring pattern (which use SyntaxContext::empty()).
|
||||
struct ClosureVariableNormalizer {
|
||||
closure_vars: HashSet<String>,
|
||||
}
|
||||
|
||||
impl ClosureVariableNormalizer {
|
||||
fn new(closure_vars: &[String]) -> Self {
|
||||
Self {
|
||||
closure_vars: closure_vars.iter().cloned().collect(),
|
||||
}
|
||||
}
|
||||
|
||||
fn normalize_function_body(closure_vars: &[String], body: &mut BlockStmt) {
|
||||
let mut normalizer = Self::new(closure_vars);
|
||||
body.visit_mut_with(&mut normalizer);
|
||||
}
|
||||
}
|
||||
|
||||
impl VisitMut for ClosureVariableNormalizer {
|
||||
fn visit_mut_ident(&mut self, ident: &mut Ident) {
|
||||
if self.closure_vars.contains(&ident.sym.to_string()) {
|
||||
// Replace with a new identifier that has SyntaxContext::empty()
|
||||
// This ensures it matches the destructuring pattern we create
|
||||
*ident = Ident::new(ident.sym.clone(), ident.span, SyntaxContext::empty());
|
||||
}
|
||||
}
|
||||
|
||||
// Don't descend into nested functions - their closure vars are handled separately
|
||||
fn visit_mut_function(&mut self, _: &mut Function) {}
|
||||
fn visit_mut_arrow_expr(&mut self, _: &mut ArrowExpr) {}
|
||||
|
||||
noop_visit_mut_type!();
|
||||
}
|
||||
|
||||
impl StepTransform {
|
||||
fn process_stmt(&mut self, stmt: &mut Stmt) {
|
||||
match stmt {
|
||||
@@ -874,10 +910,47 @@ impl StepTransform {
|
||||
} else if self.should_transform_workflow_function(&fn_decl.function, false) {
|
||||
if self.validate_async_function(&fn_decl.function, fn_decl.function.span) {
|
||||
self.workflow_function_names.insert(fn_name.clone());
|
||||
let fn_span = fn_decl.function.span;
|
||||
|
||||
match self.mode {
|
||||
TransformMode::Step => {
|
||||
// First visit children to process nested step functions
|
||||
stmt.visit_mut_children_with(self);
|
||||
|
||||
// After step hoisting, re-extract fn_decl and replace workflow body with throw error
|
||||
if let Stmt::Decl(Decl::Fn(fn_decl)) = stmt {
|
||||
self.remove_use_workflow_directive(&mut fn_decl.function.body);
|
||||
if let Some(body) = &mut fn_decl.function.body {
|
||||
let error_msg = format!(
|
||||
"You attempted to execute workflow {} function directly. To start a workflow, use start({}) from workflow/api",
|
||||
fn_name, fn_name
|
||||
);
|
||||
let error_expr = Expr::New(NewExpr {
|
||||
span: DUMMY_SP,
|
||||
ctxt: SyntaxContext::empty(),
|
||||
callee: Box::new(Expr::Ident(Ident::new(
|
||||
"Error".into(),
|
||||
DUMMY_SP,
|
||||
SyntaxContext::empty(),
|
||||
))),
|
||||
args: Some(vec![ExprOrSpread {
|
||||
spread: None,
|
||||
expr: Box::new(Expr::Lit(Lit::Str(Str {
|
||||
span: DUMMY_SP,
|
||||
value: error_msg.into(),
|
||||
raw: None,
|
||||
}))),
|
||||
}]),
|
||||
type_args: None,
|
||||
});
|
||||
body.stmts = vec![Stmt::Throw(ThrowStmt {
|
||||
span: DUMMY_SP,
|
||||
arg: Box::new(error_expr),
|
||||
})];
|
||||
}
|
||||
}
|
||||
self.workflow_functions_needing_id
|
||||
.push((fn_name.clone(), fn_span));
|
||||
}
|
||||
TransformMode::Workflow => {
|
||||
self.remove_use_workflow_directive(&mut fn_decl.function.body);
|
||||
@@ -914,7 +987,7 @@ impl StepTransform {
|
||||
})];
|
||||
}
|
||||
self.workflow_functions_needing_id
|
||||
.push((fn_name.clone(), fn_decl.function.span));
|
||||
.push((fn_name.clone(), fn_span));
|
||||
stmt.visit_mut_children_with(self);
|
||||
}
|
||||
}
|
||||
@@ -1157,8 +1230,13 @@ impl StepTransform {
|
||||
parent_var_name: &str,
|
||||
prop_name: &str,
|
||||
is_workflow: bool,
|
||||
workflow_name: Option<&str>,
|
||||
) -> String {
|
||||
let fn_name = format!("{}/{}", parent_var_name, prop_name);
|
||||
let fn_name = if let Some(wf_name) = workflow_name {
|
||||
format!("{}/{}/{}", wf_name, parent_var_name, prop_name)
|
||||
} else {
|
||||
format!("{}/{}", parent_var_name, prop_name)
|
||||
};
|
||||
let prefix = if is_workflow { "workflow" } else { "step" };
|
||||
naming::format_name(prefix, &self.filename, &fn_name)
|
||||
}
|
||||
@@ -1210,6 +1288,9 @@ impl StepTransform {
|
||||
prop_key.clone(),
|
||||
arrow_expr.clone(),
|
||||
arrow_expr.span,
|
||||
self.current_workflow_function_name
|
||||
.clone()
|
||||
.unwrap_or_default(),
|
||||
));
|
||||
|
||||
let span = arrow_expr.span;
|
||||
@@ -1271,6 +1352,9 @@ impl StepTransform {
|
||||
prop_key.clone(),
|
||||
arrow_from_fn,
|
||||
span,
|
||||
self.current_workflow_function_name
|
||||
.clone()
|
||||
.unwrap_or_default(),
|
||||
));
|
||||
|
||||
let _ = fn_expr; // Drop the mutable reference
|
||||
@@ -1340,18 +1424,27 @@ impl StepTransform {
|
||||
prop_key.clone(),
|
||||
arrow_from_method,
|
||||
span,
|
||||
self.current_workflow_function_name
|
||||
.clone()
|
||||
.unwrap_or_default(),
|
||||
));
|
||||
|
||||
// Now handle the transformation based on mode
|
||||
match self.mode {
|
||||
TransformMode::Step => {
|
||||
// In step mode, replace method with key-value property referencing the hoisted variable
|
||||
let hoist_var_name =
|
||||
format!("{}${}", parent_var_name, prop_key);
|
||||
let hoist_var_name = if let Some(ref workflow_name) =
|
||||
self.current_workflow_function_name
|
||||
{
|
||||
format!("{}${}${}", workflow_name, parent_var_name, prop_key)
|
||||
} else {
|
||||
format!("{}${}", parent_var_name, prop_key)
|
||||
};
|
||||
let step_id = self.create_object_property_id(
|
||||
parent_var_name,
|
||||
&prop_key,
|
||||
false,
|
||||
self.current_workflow_function_name.as_deref(),
|
||||
);
|
||||
// Replace the method with a key-value property referencing the hoisted function
|
||||
*boxed_prop = Box::new(Prop::KeyValue(KeyValueProp {
|
||||
@@ -1374,6 +1467,7 @@ impl StepTransform {
|
||||
parent_var_name,
|
||||
&prop_key,
|
||||
false,
|
||||
self.current_workflow_function_name.as_deref(),
|
||||
);
|
||||
*boxed_prop = Box::new(Prop::KeyValue(KeyValueProp {
|
||||
key: method_prop.key.clone(),
|
||||
@@ -1406,12 +1500,23 @@ impl StepTransform {
|
||||
prop_key: &str,
|
||||
_span: swc_core::common::Span,
|
||||
) {
|
||||
let step_id = self.create_object_property_id(parent_var_name, prop_key, false);
|
||||
let step_id = self.create_object_property_id(
|
||||
parent_var_name,
|
||||
prop_key,
|
||||
false,
|
||||
self.current_workflow_function_name.as_deref(),
|
||||
);
|
||||
|
||||
match self.mode {
|
||||
TransformMode::Step => {
|
||||
// In step mode, replace with reference to hoisted variable
|
||||
let hoist_var_name = format!("{}${}", parent_var_name, prop_key);
|
||||
let hoist_var_name = if let Some(ref workflow_name) =
|
||||
self.current_workflow_function_name
|
||||
{
|
||||
format!("{}${}${}", workflow_name, parent_var_name, prop_key)
|
||||
} else {
|
||||
format!("{}${}", parent_var_name, prop_key)
|
||||
};
|
||||
*kv_prop.value = Expr::Ident(Ident::new(
|
||||
hoist_var_name.into(),
|
||||
DUMMY_SP,
|
||||
@@ -2880,6 +2985,13 @@ impl VisitMut for StepTransform {
|
||||
// If there are closure variables, add destructuring as first statement
|
||||
if !closure_vars.is_empty() {
|
||||
if let Some(body) = &mut fn_expr.function.body {
|
||||
// First, normalize the SyntaxContext of closure variable references in the body
|
||||
// This ensures they match the identifiers we create in the destructuring pattern
|
||||
ClosureVariableNormalizer::normalize_function_body(
|
||||
&closure_vars,
|
||||
body,
|
||||
);
|
||||
|
||||
// Create destructuring statement: const { var1, var2 } = __private_getClosureVars();
|
||||
let closure_destructure =
|
||||
Stmt::Decl(Decl::Var(Box::new(VarDecl {
|
||||
@@ -3020,10 +3132,19 @@ impl VisitMut for StepTransform {
|
||||
let hoisting_info: Vec<_> = self
|
||||
.object_property_step_functions
|
||||
.iter()
|
||||
.map(|(parent_var, prop_name, arrow_expr, _span)| {
|
||||
let hoist_var_name = format!("{}${}", parent_var, prop_name);
|
||||
.map(|(parent_var, prop_name, arrow_expr, _span, workflow_name)| {
|
||||
let hoist_var_name = if !workflow_name.is_empty() {
|
||||
format!("{}${}${}", workflow_name, parent_var, prop_name)
|
||||
} else {
|
||||
format!("{}${}", parent_var, prop_name)
|
||||
};
|
||||
let wf_name = if workflow_name.is_empty() {
|
||||
None
|
||||
} else {
|
||||
Some(workflow_name.as_str())
|
||||
};
|
||||
let step_id =
|
||||
self.create_object_property_id(parent_var, prop_name, false);
|
||||
self.create_object_property_id(parent_var, prop_name, false, wf_name);
|
||||
(
|
||||
hoist_var_name,
|
||||
arrow_expr.clone(),
|
||||
@@ -3348,7 +3469,7 @@ impl VisitMut for StepTransform {
|
||||
if let ModuleItem::Stmt(Stmt::Expr(ExprStmt { expr, .. })) = &items[0] {
|
||||
if let Expr::Lit(Lit::Str(Str { value, .. })) = &**expr {
|
||||
let should_remove = match self.mode {
|
||||
TransformMode::Step => value == "use step",
|
||||
TransformMode::Step => value == "use step" || value == "use workflow",
|
||||
TransformMode::Workflow => value == "use workflow",
|
||||
TransformMode::Client => value == "use step" || value == "use workflow",
|
||||
};
|
||||
@@ -3556,7 +3677,7 @@ impl VisitMut for StepTransform {
|
||||
item.visit_mut_with(self);
|
||||
|
||||
// After visiting the item, check if we need to add a workflowId assignment
|
||||
if matches!(self.mode, TransformMode::Client) {
|
||||
if matches!(self.mode, TransformMode::Client | TransformMode::Step) {
|
||||
match item {
|
||||
ModuleItem::ModuleDecl(ModuleDecl::ExportDecl(export_decl)) => {
|
||||
if let Decl::Fn(fn_decl) = &export_decl.decl {
|
||||
@@ -3671,11 +3792,10 @@ impl VisitMut for StepTransform {
|
||||
}
|
||||
}
|
||||
|
||||
// Handle default workflow exports (workflow and client modes)
|
||||
// Handle default workflow exports (all modes)
|
||||
// We need to: 1) find the export default position, 2) replace it with const declaration,
|
||||
// 3) add workflowId assignment, 4) add export default at the end
|
||||
if (self.mode == TransformMode::Workflow || self.mode == TransformMode::Client)
|
||||
&& !self.default_workflow_exports.is_empty()
|
||||
if !self.default_workflow_exports.is_empty()
|
||||
{
|
||||
let default_workflows: Vec<_> = self.default_workflow_exports.drain(..).collect();
|
||||
let default_exports: Vec<_> = self.default_exports_to_replace.drain(..).collect();
|
||||
@@ -4106,9 +4226,8 @@ impl VisitMut for StepTransform {
|
||||
|
||||
match self.mode {
|
||||
TransformMode::Step => {
|
||||
// Workflow functions are not processed in step mode, but we need to visit
|
||||
// their children to handle nested step functions
|
||||
// (visiting happens at the end of the function)
|
||||
// Workflow functions need step hoisting first, then transformation
|
||||
// Store fn_name for later use after visiting children
|
||||
}
|
||||
TransformMode::Workflow => {
|
||||
// Remove directive before cloning (for the metadata)
|
||||
@@ -4176,13 +4295,13 @@ impl VisitMut for StepTransform {
|
||||
// Visit children for workflow functions OUTSIDE the match to avoid borrow issues
|
||||
export_decl.visit_mut_children_with(self);
|
||||
|
||||
// After visiting, process the function again for cleanup
|
||||
// After visiting, process the function again for cleanup and Step mode transformation
|
||||
if let Decl::Fn(fn_decl) = &mut export_decl.decl {
|
||||
let fn_name = fn_decl.ident.sym.to_string();
|
||||
|
||||
// Remove empty statements from the function body (left by nested step hoisting)
|
||||
// and filter out var declarations with Invalid expressions
|
||||
let had_nested_steps = if let Some(body) = &mut fn_decl.function.body {
|
||||
let original_len = body.stmts.len();
|
||||
|
||||
if let Some(body) = &mut fn_decl.function.body {
|
||||
// Remove empty statements
|
||||
body.stmts.retain(|stmt| !matches!(stmt, Stmt::Empty(_)));
|
||||
|
||||
@@ -4199,15 +4318,41 @@ impl VisitMut for StepTransform {
|
||||
body.stmts.retain(|stmt| {
|
||||
!matches!(stmt, Stmt::Decl(Decl::Var(var_decl)) if var_decl.decls.is_empty())
|
||||
});
|
||||
}
|
||||
|
||||
body.stmts.len() != original_len
|
||||
} else {
|
||||
false
|
||||
};
|
||||
|
||||
// In Step mode, only remove workflow directive if there were nested steps
|
||||
if matches!(self.mode, TransformMode::Step) && had_nested_steps {
|
||||
// In Step mode, transform workflow function AFTER step hoisting
|
||||
if matches!(self.mode, TransformMode::Step) {
|
||||
self.remove_use_workflow_directive(&mut fn_decl.function.body);
|
||||
if let Some(body) = &mut fn_decl.function.body {
|
||||
let error_msg = format!(
|
||||
"You attempted to execute workflow {} function directly. To start a workflow, use start({}) from workflow/api",
|
||||
fn_name, fn_name
|
||||
);
|
||||
let error_expr = Expr::New(NewExpr {
|
||||
span: DUMMY_SP,
|
||||
ctxt: SyntaxContext::empty(),
|
||||
callee: Box::new(Expr::Ident(Ident::new(
|
||||
"Error".into(),
|
||||
DUMMY_SP,
|
||||
SyntaxContext::empty(),
|
||||
))),
|
||||
args: Some(vec![ExprOrSpread {
|
||||
spread: None,
|
||||
expr: Box::new(Expr::Lit(Lit::Str(Str {
|
||||
span: DUMMY_SP,
|
||||
value: error_msg.into(),
|
||||
raw: None,
|
||||
}))),
|
||||
}]),
|
||||
type_args: None,
|
||||
});
|
||||
body.stmts = vec![Stmt::Throw(ThrowStmt {
|
||||
span: DUMMY_SP,
|
||||
arg: Box::new(error_expr),
|
||||
})];
|
||||
}
|
||||
self.workflow_functions_needing_id
|
||||
.push((fn_name.clone(), fn_decl.function.span));
|
||||
}
|
||||
}
|
||||
} else {
|
||||
@@ -4274,7 +4419,48 @@ impl VisitMut for StepTransform {
|
||||
|
||||
match self.mode {
|
||||
TransformMode::Step => {
|
||||
// Workflow functions are not processed in step mode
|
||||
// In step mode, transform workflow function expression with throw error
|
||||
self.remove_use_workflow_directive(
|
||||
&mut fn_expr.function.body,
|
||||
);
|
||||
|
||||
if let Some(body) = &mut fn_expr.function.body {
|
||||
let error_msg = format!(
|
||||
"You attempted to execute workflow {} function directly. To start a workflow, use start({}) from workflow/api",
|
||||
name, name
|
||||
);
|
||||
let error_expr = Expr::New(NewExpr {
|
||||
span: DUMMY_SP,
|
||||
ctxt: SyntaxContext::empty(),
|
||||
callee: Box::new(Expr::Ident(
|
||||
Ident::new(
|
||||
"Error".into(),
|
||||
DUMMY_SP,
|
||||
SyntaxContext::empty(),
|
||||
),
|
||||
)),
|
||||
args: Some(vec![ExprOrSpread {
|
||||
spread: None,
|
||||
expr: Box::new(Expr::Lit(
|
||||
Lit::Str(Str {
|
||||
span: DUMMY_SP,
|
||||
value: error_msg.into(),
|
||||
raw: None,
|
||||
}),
|
||||
)),
|
||||
}]),
|
||||
type_args: None,
|
||||
});
|
||||
body.stmts = vec![Stmt::Throw(ThrowStmt {
|
||||
span: DUMMY_SP,
|
||||
arg: Box::new(error_expr),
|
||||
})];
|
||||
}
|
||||
|
||||
self.workflow_functions_needing_id.push((
|
||||
name.clone(),
|
||||
fn_expr.function.span,
|
||||
));
|
||||
}
|
||||
TransformMode::Workflow => {
|
||||
// In workflow mode, just remove the directive
|
||||
@@ -4406,7 +4592,52 @@ impl VisitMut for StepTransform {
|
||||
|
||||
match self.mode {
|
||||
TransformMode::Step => {
|
||||
// Workflow functions are not processed in step mode
|
||||
// In step mode, transform workflow arrow function with throw error
|
||||
self.remove_use_workflow_directive_arrow(
|
||||
&mut arrow_expr.body,
|
||||
);
|
||||
|
||||
let error_msg = format!(
|
||||
"You attempted to execute workflow {} function directly. To start a workflow, use start({}) from workflow/api",
|
||||
name, name
|
||||
);
|
||||
let error_expr = Expr::New(NewExpr {
|
||||
span: DUMMY_SP,
|
||||
ctxt: SyntaxContext::empty(),
|
||||
callee: Box::new(Expr::Ident(
|
||||
Ident::new(
|
||||
"Error".into(),
|
||||
DUMMY_SP,
|
||||
SyntaxContext::empty(),
|
||||
),
|
||||
)),
|
||||
args: Some(vec![ExprOrSpread {
|
||||
spread: None,
|
||||
expr: Box::new(Expr::Lit(
|
||||
Lit::Str(Str {
|
||||
span: DUMMY_SP,
|
||||
value: error_msg.into(),
|
||||
raw: None,
|
||||
}),
|
||||
)),
|
||||
}]),
|
||||
type_args: None,
|
||||
});
|
||||
arrow_expr.body = Box::new(
|
||||
BlockStmtOrExpr::BlockStmt(BlockStmt {
|
||||
span: DUMMY_SP,
|
||||
ctxt: SyntaxContext::empty(),
|
||||
stmts: vec![Stmt::Throw(
|
||||
ThrowStmt {
|
||||
span: DUMMY_SP,
|
||||
arg: Box::new(error_expr),
|
||||
},
|
||||
)],
|
||||
}),
|
||||
);
|
||||
|
||||
self.workflow_functions_needing_id
|
||||
.push((name.clone(), arrow_expr.span));
|
||||
}
|
||||
TransformMode::Workflow => {
|
||||
// In workflow mode, just remove the directive
|
||||
@@ -4637,7 +4868,40 @@ impl VisitMut for StepTransform {
|
||||
|
||||
match self.mode {
|
||||
TransformMode::Step => {
|
||||
// Workflow functions are not processed in step mode
|
||||
// In step mode, transform workflow function with throw error
|
||||
self.remove_use_workflow_directive(
|
||||
&mut fn_expr.function.body,
|
||||
);
|
||||
if let Some(body) = &mut fn_expr.function.body {
|
||||
let error_msg = format!(
|
||||
"You attempted to execute workflow {} function directly. To start a workflow, use start({}) from workflow/api",
|
||||
name, name
|
||||
);
|
||||
let error_expr = Expr::New(NewExpr {
|
||||
span: DUMMY_SP,
|
||||
ctxt: SyntaxContext::empty(),
|
||||
callee: Box::new(Expr::Ident(Ident::new(
|
||||
"Error".into(),
|
||||
DUMMY_SP,
|
||||
SyntaxContext::empty(),
|
||||
))),
|
||||
args: Some(vec![ExprOrSpread {
|
||||
spread: None,
|
||||
expr: Box::new(Expr::Lit(Lit::Str(Str {
|
||||
span: DUMMY_SP,
|
||||
value: error_msg.into(),
|
||||
raw: None,
|
||||
}))),
|
||||
}]),
|
||||
type_args: None,
|
||||
});
|
||||
body.stmts = vec![Stmt::Throw(ThrowStmt {
|
||||
span: DUMMY_SP,
|
||||
arg: Box::new(error_expr),
|
||||
})];
|
||||
}
|
||||
self.workflow_functions_needing_id
|
||||
.push((name.clone(), fn_expr.function.span));
|
||||
}
|
||||
TransformMode::Workflow => {
|
||||
// In workflow mode, just remove the directive
|
||||
@@ -4905,7 +5169,43 @@ impl VisitMut for StepTransform {
|
||||
|
||||
match self.mode {
|
||||
TransformMode::Step => {
|
||||
// Workflow functions are not processed in step mode
|
||||
// In step mode, transform workflow arrow function with throw error
|
||||
self.remove_use_workflow_directive_arrow(
|
||||
&mut arrow_expr.body,
|
||||
);
|
||||
let error_msg = format!(
|
||||
"You attempted to execute workflow {} function directly. To start a workflow, use start({}) from workflow/api",
|
||||
name, name
|
||||
);
|
||||
let error_expr = Expr::New(NewExpr {
|
||||
span: DUMMY_SP,
|
||||
ctxt: SyntaxContext::empty(),
|
||||
callee: Box::new(Expr::Ident(Ident::new(
|
||||
"Error".into(),
|
||||
DUMMY_SP,
|
||||
SyntaxContext::empty(),
|
||||
))),
|
||||
args: Some(vec![ExprOrSpread {
|
||||
spread: None,
|
||||
expr: Box::new(Expr::Lit(Lit::Str(Str {
|
||||
span: DUMMY_SP,
|
||||
value: error_msg.into(),
|
||||
raw: None,
|
||||
}))),
|
||||
}]),
|
||||
type_args: None,
|
||||
});
|
||||
arrow_expr.body =
|
||||
Box::new(BlockStmtOrExpr::BlockStmt(BlockStmt {
|
||||
span: DUMMY_SP,
|
||||
ctxt: SyntaxContext::empty(),
|
||||
stmts: vec![Stmt::Throw(ThrowStmt {
|
||||
span: DUMMY_SP,
|
||||
arg: Box::new(error_expr),
|
||||
})],
|
||||
}));
|
||||
self.workflow_functions_needing_id
|
||||
.push((name.clone(), arrow_expr.span));
|
||||
}
|
||||
TransformMode::Workflow => {
|
||||
// In workflow mode, just remove the directive
|
||||
@@ -5167,9 +5467,14 @@ impl VisitMut for StepTransform {
|
||||
}
|
||||
TransformMode::Workflow => {
|
||||
// Replace with proxy reference
|
||||
// Use current_parent_function_name to match step mode's ID generation
|
||||
let step_fn_name =
|
||||
if let Some(parent) = &self.current_workflow_function_name {
|
||||
format!("{}/{}", parent, name)
|
||||
if let Some(parent) = &self.current_parent_function_name {
|
||||
if !parent.is_empty() {
|
||||
format!("{}/{}", parent, name)
|
||||
} else {
|
||||
name.clone()
|
||||
}
|
||||
} else {
|
||||
name.clone()
|
||||
};
|
||||
@@ -5288,9 +5593,14 @@ impl VisitMut for StepTransform {
|
||||
}
|
||||
TransformMode::Workflow => {
|
||||
// Replace with proxy reference
|
||||
// Use current_parent_function_name to match step mode's ID generation
|
||||
let step_fn_name =
|
||||
if let Some(parent) = &self.current_workflow_function_name {
|
||||
format!("{}/{}", parent, name)
|
||||
if let Some(parent) = &self.current_parent_function_name {
|
||||
if !parent.is_empty() {
|
||||
format!("{}/{}", parent, name)
|
||||
} else {
|
||||
name.clone()
|
||||
}
|
||||
} else {
|
||||
name.clone()
|
||||
};
|
||||
@@ -5349,44 +5659,8 @@ impl VisitMut for StepTransform {
|
||||
self.workflow_function_names.insert("default".to_string());
|
||||
|
||||
match self.mode {
|
||||
TransformMode::Step => {
|
||||
// Workflow functions are not processed in step mode
|
||||
}
|
||||
TransformMode::Workflow => {
|
||||
// In workflow mode, just remove the directive
|
||||
self.remove_use_workflow_directive(&mut fn_expr.function.body);
|
||||
|
||||
if fn_name == "default" {
|
||||
// Anonymous default export: convert to const declaration
|
||||
// Track for const declaration and workflowId assignment
|
||||
self.default_workflow_exports.push((
|
||||
const_name.clone(),
|
||||
Expr::Fn(fn_expr.clone()),
|
||||
fn_expr.function.span,
|
||||
));
|
||||
|
||||
// Track for replacement with identifier
|
||||
self.default_exports_to_replace.push((
|
||||
fn_name.clone(),
|
||||
Expr::Ident(Ident::new(
|
||||
const_name.into(),
|
||||
DUMMY_SP,
|
||||
SyntaxContext::empty(),
|
||||
)),
|
||||
));
|
||||
} else {
|
||||
// Named default export: can reference by name
|
||||
// export default async function name() { ... }
|
||||
// name.workflowId = "...";
|
||||
self.workflow_exports_to_expand.push((
|
||||
const_name,
|
||||
Expr::Fn(fn_expr.clone()),
|
||||
fn_expr.function.span,
|
||||
));
|
||||
}
|
||||
}
|
||||
TransformMode::Client => {
|
||||
// In client mode, replace workflow function body with error throw
|
||||
TransformMode::Step | TransformMode::Client => {
|
||||
// In step/client mode, replace workflow function body with error throw
|
||||
self.remove_use_workflow_directive(&mut fn_expr.function.body);
|
||||
|
||||
let error_msg = format!(
|
||||
@@ -5440,7 +5714,40 @@ impl VisitMut for StepTransform {
|
||||
} else {
|
||||
// Named function can be referenced directly, just add workflowId
|
||||
self.workflow_functions_needing_id
|
||||
.push((const_name, fn_expr.function.span));
|
||||
.push((const_name.clone(), fn_expr.function.span));
|
||||
}
|
||||
}
|
||||
TransformMode::Workflow => {
|
||||
// In workflow mode, just remove the directive
|
||||
self.remove_use_workflow_directive(&mut fn_expr.function.body);
|
||||
|
||||
if fn_name == "default" {
|
||||
// Anonymous default export: convert to const declaration
|
||||
// Track for const declaration and workflowId assignment
|
||||
self.default_workflow_exports.push((
|
||||
const_name.clone(),
|
||||
Expr::Fn(fn_expr.clone()),
|
||||
fn_expr.function.span,
|
||||
));
|
||||
|
||||
// Track for replacement with identifier
|
||||
self.default_exports_to_replace.push((
|
||||
fn_name.clone(),
|
||||
Expr::Ident(Ident::new(
|
||||
const_name.into(),
|
||||
DUMMY_SP,
|
||||
SyntaxContext::empty(),
|
||||
)),
|
||||
));
|
||||
} else {
|
||||
// Named default export: can reference by name
|
||||
// export default async function name() { ... }
|
||||
// name.workflowId = "...";
|
||||
self.workflow_exports_to_expand.push((
|
||||
const_name,
|
||||
Expr::Fn(fn_expr.clone()),
|
||||
fn_expr.function.span,
|
||||
));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -5522,32 +5829,8 @@ impl VisitMut for StepTransform {
|
||||
self.workflow_function_names.insert("default".to_string());
|
||||
|
||||
match self.mode {
|
||||
TransformMode::Step => {
|
||||
// Workflow functions are not processed in step mode
|
||||
}
|
||||
TransformMode::Workflow => {
|
||||
// In workflow mode, convert to const declaration
|
||||
self.remove_use_workflow_directive(&mut fn_expr.function.body);
|
||||
|
||||
// Track for const declaration and workflowId assignment
|
||||
self.default_workflow_exports.push((
|
||||
unique_name.clone(),
|
||||
Expr::Fn(fn_expr.clone()),
|
||||
fn_expr.function.span,
|
||||
));
|
||||
|
||||
// Track for replacement with identifier
|
||||
self.default_exports_to_replace.push((
|
||||
"default".to_string(),
|
||||
Expr::Ident(Ident::new(
|
||||
unique_name.into(),
|
||||
DUMMY_SP,
|
||||
SyntaxContext::empty(),
|
||||
)),
|
||||
));
|
||||
}
|
||||
TransformMode::Client => {
|
||||
// In client mode, replace workflow function body with error throw
|
||||
TransformMode::Step | TransformMode::Client => {
|
||||
// In step/client mode, replace workflow function body with error throw
|
||||
self.remove_use_workflow_directive(&mut fn_expr.function.body);
|
||||
let error_msg = format!(
|
||||
"You attempted to execute workflow {} function directly. To start a workflow, use start({}) from workflow/api",
|
||||
@@ -5585,6 +5868,27 @@ impl VisitMut for StepTransform {
|
||||
fn_expr.function.span,
|
||||
));
|
||||
|
||||
// Track for replacement with identifier
|
||||
self.default_exports_to_replace.push((
|
||||
"default".to_string(),
|
||||
Expr::Ident(Ident::new(
|
||||
unique_name.into(),
|
||||
DUMMY_SP,
|
||||
SyntaxContext::empty(),
|
||||
)),
|
||||
));
|
||||
}
|
||||
TransformMode::Workflow => {
|
||||
// In workflow mode, convert to const declaration
|
||||
self.remove_use_workflow_directive(&mut fn_expr.function.body);
|
||||
|
||||
// Track for const declaration and workflowId assignment
|
||||
self.default_workflow_exports.push((
|
||||
unique_name.clone(),
|
||||
Expr::Fn(fn_expr.clone()),
|
||||
fn_expr.function.span,
|
||||
));
|
||||
|
||||
// Track for replacement with identifier
|
||||
self.default_exports_to_replace.push((
|
||||
"default".to_string(),
|
||||
@@ -5623,32 +5927,8 @@ impl VisitMut for StepTransform {
|
||||
self.workflow_function_names.insert("default".to_string());
|
||||
|
||||
match self.mode {
|
||||
TransformMode::Step => {
|
||||
// Workflow functions are not processed in step mode
|
||||
}
|
||||
TransformMode::Workflow => {
|
||||
// In workflow mode, convert to const declaration
|
||||
self.remove_use_workflow_directive_arrow(&mut arrow_expr.body);
|
||||
|
||||
// Track for const declaration and workflowId assignment
|
||||
self.default_workflow_exports.push((
|
||||
unique_name.clone(),
|
||||
Expr::Arrow(arrow_expr.clone()),
|
||||
arrow_expr.span,
|
||||
));
|
||||
|
||||
// Track for replacement with identifier
|
||||
self.default_exports_to_replace.push((
|
||||
"default".to_string(),
|
||||
Expr::Ident(Ident::new(
|
||||
unique_name.into(),
|
||||
DUMMY_SP,
|
||||
SyntaxContext::empty(),
|
||||
)),
|
||||
));
|
||||
}
|
||||
TransformMode::Client => {
|
||||
// In client mode, convert to const declaration so we can assign workflowId
|
||||
TransformMode::Step | TransformMode::Client => {
|
||||
// In step/client mode, replace arrow body with throw error
|
||||
self.remove_use_workflow_directive_arrow(&mut arrow_expr.body);
|
||||
let error_msg = format!(
|
||||
"You attempted to execute workflow {} function directly. To start a workflow, use start({}) from workflow/api",
|
||||
@@ -5689,6 +5969,27 @@ impl VisitMut for StepTransform {
|
||||
arrow_expr.span,
|
||||
));
|
||||
|
||||
// Track for replacement with identifier
|
||||
self.default_exports_to_replace.push((
|
||||
"default".to_string(),
|
||||
Expr::Ident(Ident::new(
|
||||
unique_name.into(),
|
||||
DUMMY_SP,
|
||||
SyntaxContext::empty(),
|
||||
)),
|
||||
));
|
||||
}
|
||||
TransformMode::Workflow => {
|
||||
// In workflow mode, convert to const declaration
|
||||
self.remove_use_workflow_directive_arrow(&mut arrow_expr.body);
|
||||
|
||||
// Track for const declaration and workflowId assignment
|
||||
self.default_workflow_exports.push((
|
||||
unique_name.clone(),
|
||||
Expr::Arrow(arrow_expr.clone()),
|
||||
arrow_expr.span,
|
||||
));
|
||||
|
||||
// Track for replacement with identifier
|
||||
self.default_exports_to_replace.push((
|
||||
"default".to_string(),
|
||||
|
||||
+2
-2
@@ -22,7 +22,7 @@ export async function validStep() {
|
||||
return 42;
|
||||
}
|
||||
export const validWorkflow = async ()=>{
|
||||
'use workflow';
|
||||
return 'test';
|
||||
throw new Error("You attempted to execute workflow validWorkflow function directly. To start a workflow, use start(validWorkflow) from workflow/api");
|
||||
};
|
||||
validWorkflow.workflowId = "workflow//input.js//validWorkflow";
|
||||
registerStepFunction("step//input.js//validStep", validStep);
|
||||
|
||||
+5
-5
@@ -1,7 +1,7 @@
|
||||
// Test anonymous default export workflow
|
||||
/**__internal_workflows{"workflows":{"input.js":{"default":{"workflowId":"workflow//input.js//__default"}}}}*/;
|
||||
export default async function() {
|
||||
'use workflow';
|
||||
const result = await someStep();
|
||||
return result;
|
||||
}
|
||||
const __default = async function() {
|
||||
throw new Error("You attempted to execute workflow __default function directly. To start a workflow, use start(__default) from workflow/api");
|
||||
};
|
||||
__default.workflowId = "workflow//input.js//__default";
|
||||
export default __default;
|
||||
|
||||
+5
-5
@@ -1,7 +1,7 @@
|
||||
// Test default export arrow workflow
|
||||
/**__internal_workflows{"workflows":{"input.js":{"default":{"workflowId":"workflow//input.js//__default"}}}}*/;
|
||||
export default (async (data)=>{
|
||||
'use workflow';
|
||||
const processed = await processData(data);
|
||||
return processed;
|
||||
});
|
||||
const __default = async (data)=>{
|
||||
throw new Error("You attempted to execute workflow __default function directly. To start a workflow, use start(__default) from workflow/api");
|
||||
};
|
||||
__default.workflowId = "workflow//input.js//__default";
|
||||
export default __default;
|
||||
|
||||
+2
-7
@@ -15,11 +15,6 @@ async function convertToLanguageModelPrompt({ prompt, supportedUrls, download =
|
||||
};
|
||||
}
|
||||
export async function myWorkflow(input) {
|
||||
'use workflow';
|
||||
const result = await convertToLanguageModelPrompt({
|
||||
prompt: input.prompt,
|
||||
supportedUrls: {},
|
||||
download: undefined
|
||||
});
|
||||
return result;
|
||||
throw new Error("You attempted to execute workflow myWorkflow function directly. To start a workflow, use start(myWorkflow) from workflow/api");
|
||||
}
|
||||
myWorkflow.workflowId = "workflow//input.js//myWorkflow";
|
||||
|
||||
+5
-6
@@ -3,9 +3,8 @@
|
||||
const __default = "existing variable";
|
||||
// Use it to avoid unused variable
|
||||
console.log(__default);
|
||||
// Anonymous default export should get unique name (__default$1)
|
||||
export default async function() {
|
||||
'use workflow';
|
||||
const result = await someStep();
|
||||
return result;
|
||||
}
|
||||
const __default$1 = async function() {
|
||||
throw new Error("You attempted to execute workflow __default$1 function directly. To start a workflow, use start(__default$1) from workflow/api");
|
||||
};
|
||||
__default$1.workflowId = "workflow//input.js//__default$1";
|
||||
export default __default$1;
|
||||
|
||||
+5
-5
@@ -1,6 +1,6 @@
|
||||
/**__internal_workflows{"workflows":{"input.js":{"default":{"workflowId":"workflow//input.js//__default"}}}}*/;
|
||||
export default async function() {
|
||||
'use workflow';
|
||||
const result = await someStep();
|
||||
return result;
|
||||
}
|
||||
const __default = async function() {
|
||||
throw new Error("You attempted to execute workflow __default function directly. To start a workflow, use start(__default) from workflow/api");
|
||||
};
|
||||
__default.workflowId = "workflow//input.js//__default";
|
||||
export default __default;
|
||||
|
||||
@@ -7,11 +7,9 @@ async function stepFunctionWithoutExport(a, b) {
|
||||
return a - b;
|
||||
}
|
||||
export async function workflowFunction(a, b) {
|
||||
'use workflow';
|
||||
const result = await stepFunction(a, b);
|
||||
const result2 = await stepFunctionWithoutExport(a, b);
|
||||
return result + result2;
|
||||
throw new Error("You attempted to execute workflow workflowFunction function directly. To start a workflow, use start(workflowFunction) from workflow/api");
|
||||
}
|
||||
workflowFunction.workflowId = "workflow//input.js//workflowFunction";
|
||||
export async function normalFunction(a, b) {
|
||||
return a * b;
|
||||
}
|
||||
|
||||
+4
-3
@@ -1,5 +1,4 @@
|
||||
/**__internal_workflows{"workflows":{"input.js":{"arrowWorkflow":{"workflowId":"workflow//input.js//arrowWorkflow"},"workflow":{"workflowId":"workflow//input.js//workflow"}}}}*/;
|
||||
'use workflow';
|
||||
async function local(input) {
|
||||
return input.foo;
|
||||
}
|
||||
@@ -7,8 +6,10 @@ const localArrow = async (input)=>{
|
||||
return input.bar;
|
||||
};
|
||||
export async function workflow(input) {
|
||||
return input.foo;
|
||||
throw new Error("You attempted to execute workflow workflow function directly. To start a workflow, use start(workflow) from workflow/api");
|
||||
}
|
||||
workflow.workflowId = "workflow//input.js//workflow";
|
||||
export const arrowWorkflow = async (input)=>{
|
||||
return input.bar;
|
||||
throw new Error("You attempted to execute workflow arrowWorkflow function directly. To start a workflow, use start(arrowWorkflow) from workflow/api");
|
||||
};
|
||||
arrowWorkflow.workflowId = "workflow//input.js//arrowWorkflow";
|
||||
|
||||
+5
-21
@@ -1,5 +1,5 @@
|
||||
import { registerStepFunction } from "workflow/internal/private";
|
||||
/**__internal_workflows{"workflows":{"input.js":{"example":{"workflowId":"workflow//input.js//example"}}},"steps":{"input.js":{"arrowStep":{"stepId":"step//input.js//arrowStep"},"helpers/objectStep":{"stepId":"step//input.js//helpers/objectStep"},"letArrowStep":{"stepId":"step//input.js//letArrowStep"},"step":{"stepId":"step//input.js//step"},"varArrowStep":{"stepId":"step//input.js//varArrowStep"}}}}*/;
|
||||
/**__internal_workflows{"workflows":{"input.js":{"example":{"workflowId":"workflow//input.js//example"}}},"steps":{"input.js":{"arrowStep":{"stepId":"step//input.js//arrowStep"},"helpers/objectStep":{"stepId":"step//input.js//example/helpers/objectStep"},"letArrowStep":{"stepId":"step//input.js//letArrowStep"},"step":{"stepId":"step//input.js//step"},"varArrowStep":{"stepId":"step//input.js//varArrowStep"}}}}*/;
|
||||
// Function declaration step
|
||||
async function example$step(a, b) {
|
||||
return a + b;
|
||||
@@ -7,31 +7,15 @@ async function example$step(a, b) {
|
||||
var example$arrowStep = async (x, y)=>x * y;
|
||||
var example$letArrowStep = async (x, y)=>x - y;
|
||||
var example$varArrowStep = async (x, y)=>x / y;
|
||||
var helpers$objectStep = async (x, y)=>{
|
||||
var example$helpers$objectStep = async (x, y)=>{
|
||||
return x + y + 10;
|
||||
};
|
||||
export async function example(a, b) {
|
||||
"use workflow";
|
||||
const step = example$step;
|
||||
// Arrow function with const
|
||||
const arrowStep = example$arrowStep;
|
||||
// Arrow function with let
|
||||
let letArrowStep = example$letArrowStep;
|
||||
// Arrow function with var
|
||||
var varArrowStep = example$varArrowStep;
|
||||
// Object with step method
|
||||
const helpers = {
|
||||
objectStep: helpers$objectStep
|
||||
};
|
||||
const val = await step(a, b);
|
||||
const val2 = await arrowStep(a, b);
|
||||
const val3 = await letArrowStep(a, b);
|
||||
const val4 = await varArrowStep(a, b);
|
||||
const val5 = await helpers.objectStep(a, b);
|
||||
return val + val2 + val3 + val4 + val5;
|
||||
throw new Error("You attempted to execute workflow example function directly. To start a workflow, use start(example) from workflow/api");
|
||||
}
|
||||
example.workflowId = "workflow//input.js//example";
|
||||
registerStepFunction("step//input.js//example/step", example$step);
|
||||
registerStepFunction("step//input.js//example/arrowStep", example$arrowStep);
|
||||
registerStepFunction("step//input.js//example/letArrowStep", example$letArrowStep);
|
||||
registerStepFunction("step//input.js//example/varArrowStep", example$varArrowStep);
|
||||
registerStepFunction("step//input.js//helpers/objectStep", helpers$objectStep);
|
||||
registerStepFunction("step//input.js//example/helpers/objectStep", example$helpers$objectStep);
|
||||
|
||||
+2
-2
@@ -1,4 +1,4 @@
|
||||
/**__internal_workflows{"workflows":{"input.js":{"example":{"workflowId":"workflow//input.js//example"}}},"steps":{"input.js":{"arrowStep":{"stepId":"step//input.js//arrowStep"},"helpers/objectStep":{"stepId":"step//input.js//helpers/objectStep"},"letArrowStep":{"stepId":"step//input.js//letArrowStep"},"step":{"stepId":"step//input.js//step"},"varArrowStep":{"stepId":"step//input.js//varArrowStep"}}}}*/;
|
||||
/**__internal_workflows{"workflows":{"input.js":{"example":{"workflowId":"workflow//input.js//example"}}},"steps":{"input.js":{"arrowStep":{"stepId":"step//input.js//arrowStep"},"helpers/objectStep":{"stepId":"step//input.js//example/helpers/objectStep"},"letArrowStep":{"stepId":"step//input.js//letArrowStep"},"step":{"stepId":"step//input.js//step"},"varArrowStep":{"stepId":"step//input.js//varArrowStep"}}}}*/;
|
||||
export async function example(a, b) {
|
||||
var step = globalThis[Symbol.for("WORKFLOW_USE_STEP")]("step//input.js//example/step");
|
||||
// Arrow function with const
|
||||
@@ -9,7 +9,7 @@ export async function example(a, b) {
|
||||
var varArrowStep = globalThis[Symbol.for("WORKFLOW_USE_STEP")]("step//input.js//example/varArrowStep");
|
||||
// Object with step method
|
||||
const helpers = {
|
||||
objectStep: globalThis[Symbol.for("WORKFLOW_USE_STEP")]("step//input.js//helpers/objectStep")
|
||||
objectStep: globalThis[Symbol.for("WORKFLOW_USE_STEP")]("step//input.js//example/helpers/objectStep")
|
||||
};
|
||||
const val = await step(a, b);
|
||||
const val2 = await arrowStep(a, b);
|
||||
|
||||
+2
-16
@@ -80,23 +80,9 @@ const arrowWrapperReturnNamedFunctionVar = (a, b, c)=>{
|
||||
return fn;
|
||||
};
|
||||
export async function wflow() {
|
||||
'use workflow';
|
||||
let count = 42;
|
||||
const namedStepWithClosureVars = wflow$namedStepWithClosureVars;
|
||||
const agent = new DurableAgent({
|
||||
arrowFunctionWithClosureVars: _anonymousStep2,
|
||||
namedFunctionWithClosureVars: _anonymousStep3,
|
||||
methodWithClosureVars: _anonymousStep4
|
||||
});
|
||||
await stepWrapperReturnArrowFunctionVar(1, 2, 3)();
|
||||
await stepWrapperReturnNamedFunction(1, 2, 3)();
|
||||
await stepWrapperReturnArrowFunction(1, 2, 3)();
|
||||
await stepWrapperReturnNamedFunctionVar(1, 2, 3)();
|
||||
await arrowWrapperReturnArrowFunctionVar(1, 2, 3)();
|
||||
await arrowWrapperReturnNamedFunction(1, 2, 3)();
|
||||
await arrowWrapperReturnArrowFunction(1, 2, 3)();
|
||||
await arrowWrapperReturnNamedFunctionVar(1, 2, 3)();
|
||||
throw new Error("You attempted to execute workflow wflow function directly. To start a workflow, use start(wflow) from workflow/api");
|
||||
}
|
||||
wflow.workflowId = "workflow//input.js//wflow";
|
||||
registerStepFunction("step//input.js//stepWrapperReturnArrowFunctionVar/fn", stepWrapperReturnArrowFunctionVar$fn);
|
||||
registerStepFunction("step//input.js//stepWrapperReturnNamedFunction/f", stepWrapperReturnNamedFunction$f);
|
||||
registerStepFunction("step//input.js//stepWrapperReturnArrowFunction/_anonymousStep0", stepWrapperReturnArrowFunction$_anonymousStep0);
|
||||
|
||||
+4
-4
@@ -9,14 +9,14 @@ function stepWrapperReturnArrowFunctionVar(a, b, c) {
|
||||
return fn;
|
||||
}
|
||||
function stepWrapperReturnNamedFunction(a, b, c) {
|
||||
return globalThis[Symbol.for("WORKFLOW_USE_STEP")]("step//input.js//f", ()=>({
|
||||
return globalThis[Symbol.for("WORKFLOW_USE_STEP")]("step//input.js//stepWrapperReturnNamedFunction/f", ()=>({
|
||||
a,
|
||||
b,
|
||||
c
|
||||
}));
|
||||
}
|
||||
function stepWrapperReturnArrowFunction(a, b, c) {
|
||||
return globalThis[Symbol.for("WORKFLOW_USE_STEP")]("step//input.js//_anonymousStep0", ()=>({
|
||||
return globalThis[Symbol.for("WORKFLOW_USE_STEP")]("step//input.js//stepWrapperReturnArrowFunction/_anonymousStep0", ()=>({
|
||||
a,
|
||||
b,
|
||||
c
|
||||
@@ -39,14 +39,14 @@ const arrowWrapperReturnArrowFunctionVar = (a, b, c)=>{
|
||||
return fn;
|
||||
};
|
||||
const arrowWrapperReturnNamedFunction = (a, b, c)=>{
|
||||
return globalThis[Symbol.for("WORKFLOW_USE_STEP")]("step//input.js//f", ()=>({
|
||||
return globalThis[Symbol.for("WORKFLOW_USE_STEP")]("step//input.js//arrowWrapperReturnNamedFunction/f", ()=>({
|
||||
a,
|
||||
b,
|
||||
c
|
||||
}));
|
||||
};
|
||||
const arrowWrapperReturnArrowFunction = (a, b, c)=>{
|
||||
return globalThis[Symbol.for("WORKFLOW_USE_STEP")]("step//input.js//_anonymousStep1", ()=>({
|
||||
return globalThis[Symbol.for("WORKFLOW_USE_STEP")]("step//input.js//arrowWrapperReturnArrowFunction/_anonymousStep1", ()=>({
|
||||
a,
|
||||
b,
|
||||
c
|
||||
|
||||
+2
-21
@@ -6,27 +6,8 @@ import * as z from 'zod';
|
||||
var test$_anonymousStep0 = async ()=>gateway('openai/gpt-5');
|
||||
var test$_anonymousStep1 = async ({ location })=>`Weather in ${location}: Sunny, 72°F`;
|
||||
export async function test() {
|
||||
'use workflow';
|
||||
const agent = new DurableAgent({
|
||||
model: _anonymousStep0,
|
||||
tools: {
|
||||
getWeather: tool({
|
||||
description: 'Get weather for a location',
|
||||
inputSchema: z.object({
|
||||
location: z.string()
|
||||
}),
|
||||
execute: _anonymousStep1
|
||||
})
|
||||
}
|
||||
});
|
||||
await agent.stream({
|
||||
messages: [
|
||||
{
|
||||
role: 'user',
|
||||
content: 'What is the weather in San Francisco?'
|
||||
}
|
||||
]
|
||||
});
|
||||
throw new Error("You attempted to execute workflow test function directly. To start a workflow, use start(test) from workflow/api");
|
||||
}
|
||||
test.workflowId = "workflow//input.js//test";
|
||||
registerStepFunction("step//input.js//test/_anonymousStep0", test$_anonymousStep0);
|
||||
registerStepFunction("step//input.js//test/_anonymousStep1", test$_anonymousStep1);
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/**__internal_workflows{"workflows":{"input.js":{"workflow":{"workflowId":"workflow//input.js//workflow"}}}}*/;
|
||||
export async function workflow(a, b) {
|
||||
'use workflow';
|
||||
return add(a, b);
|
||||
throw new Error("You attempted to execute workflow workflow function directly. To start a workflow, use start(workflow) from workflow/api");
|
||||
}
|
||||
workflow.workflowId = "workflow//input.js//workflow";
|
||||
|
||||
+2
-2
@@ -1,5 +1,5 @@
|
||||
/**__internal_workflows{"workflows":{"input.js":{"processData":{"workflowId":"workflow//input.js//processData"}}}}*/;
|
||||
export const processData = async (data)=>{
|
||||
'use workflow';
|
||||
return data.processed;
|
||||
throw new Error("You attempted to execute workflow processData function directly. To start a workflow, use start(processData) from workflow/api");
|
||||
};
|
||||
processData.workflowId = "workflow//input.js//processData";
|
||||
|
||||
+8
-10
@@ -1,24 +1,22 @@
|
||||
// Test workflow functions in client mode
|
||||
/**__internal_workflows{"workflows":{"input.js":{"arrowWorkflow":{"workflowId":"workflow//input.js//arrowWorkflow"},"default":{"workflowId":"workflow//input.js//defaultWorkflow"},"internalWorkflow":{"workflowId":"workflow//input.js//internalWorkflow"},"myWorkflow":{"workflowId":"workflow//input.js//myWorkflow"}}}}*/;
|
||||
export async function myWorkflow() {
|
||||
'use workflow';
|
||||
const result = await someStep();
|
||||
return result;
|
||||
throw new Error("You attempted to execute workflow myWorkflow function directly. To start a workflow, use start(myWorkflow) from workflow/api");
|
||||
}
|
||||
myWorkflow.workflowId = "workflow//input.js//myWorkflow";
|
||||
export const arrowWorkflow = async ()=>{
|
||||
'use workflow';
|
||||
const data = await fetchData();
|
||||
return data;
|
||||
throw new Error("You attempted to execute workflow arrowWorkflow function directly. To start a workflow, use start(arrowWorkflow) from workflow/api");
|
||||
};
|
||||
arrowWorkflow.workflowId = "workflow//input.js//arrowWorkflow";
|
||||
export default async function defaultWorkflow() {
|
||||
'use workflow';
|
||||
return await process();
|
||||
throw new Error("You attempted to execute workflow defaultWorkflow function directly. To start a workflow, use start(defaultWorkflow) from workflow/api");
|
||||
}
|
||||
defaultWorkflow.workflowId = "workflow//input.js//defaultWorkflow";
|
||||
// Non-export workflow function
|
||||
async function internalWorkflow() {
|
||||
'use workflow';
|
||||
return 'internal';
|
||||
throw new Error("You attempted to execute workflow internalWorkflow function directly. To start a workflow, use start(internalWorkflow) from workflow/api");
|
||||
}
|
||||
internalWorkflow.workflowId = "workflow//input.js//internalWorkflow";
|
||||
// Use the internal workflow to avoid lint warning
|
||||
regularFunction(internalWorkflow);
|
||||
// Regular function should not be affected
|
||||
|
||||
Reference in New Issue
Block a user