mirror of
https://github.com/vercel/workflow.git
synced 2026-09-14 19:59:43 +08:00
Support nested "use step" declarations in non-workflow functions (#418)
This commit is contained in:
@@ -0,0 +1,5 @@
|
||||
---
|
||||
"@workflow/swc-plugin": patch
|
||||
---
|
||||
|
||||
Support nested "use step" declarations in non-workflow functions
|
||||
@@ -174,6 +174,8 @@ pub struct StepTransform {
|
||||
in_workflow_function: bool,
|
||||
// Track the current workflow function name (for nested step naming)
|
||||
current_workflow_function_name: Option<String>,
|
||||
// Track the current parent function name (for all functions, not just workflows)
|
||||
current_parent_function_name: Option<String>,
|
||||
// Track workflow functions that need to be expanded into multiple exports
|
||||
workflow_exports_to_expand: Vec<(String, Expr, swc_core::common::Span)>,
|
||||
// Track workflow functions that need workflowId property in client mode
|
||||
@@ -191,7 +193,14 @@ pub struct StepTransform {
|
||||
object_property_step_functions: Vec<(String, String, ArrowExpr, swc_core::common::Span)>,
|
||||
// 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<(String, FnExpr, swc_core::common::Span, Vec<String>, bool, String)>,
|
||||
nested_step_functions: Vec<(
|
||||
String,
|
||||
FnExpr,
|
||||
swc_core::common::Span,
|
||||
Vec<String>,
|
||||
bool,
|
||||
String,
|
||||
)>,
|
||||
// Counter for anonymous function names
|
||||
#[allow(dead_code)]
|
||||
anonymous_fn_counter: usize,
|
||||
@@ -698,7 +707,7 @@ impl StepTransform {
|
||||
if self.validate_async_function(&fn_decl.function, fn_decl.function.span) {
|
||||
self.step_function_names.insert(fn_name.clone());
|
||||
|
||||
if self.in_workflow_function {
|
||||
if !self.in_module_level {
|
||||
match self.mode {
|
||||
TransformMode::Step => {
|
||||
// Clone the function and remove the directive before hoisting
|
||||
@@ -722,14 +731,54 @@ impl StepTransform {
|
||||
fn_decl.function.span,
|
||||
closure_vars,
|
||||
false, // Regular function, not arrow
|
||||
self.current_workflow_function_name.clone().unwrap_or_default(),
|
||||
self.current_parent_function_name
|
||||
.clone()
|
||||
.unwrap_or_default(),
|
||||
));
|
||||
*stmt = Stmt::Empty(EmptyStmt { span: DUMMY_SP });
|
||||
|
||||
// Replace with const declaration referencing the hoisted function
|
||||
let hoisted_name =
|
||||
if let Some(parent) = &self.current_parent_function_name {
|
||||
if !parent.is_empty() {
|
||||
format!("{}${}", parent, fn_name)
|
||||
} else {
|
||||
fn_name.clone()
|
||||
}
|
||||
} else {
|
||||
fn_name.clone()
|
||||
};
|
||||
|
||||
let var_decl = Decl::Var(Box::new(VarDecl {
|
||||
span: DUMMY_SP,
|
||||
ctxt: SyntaxContext::empty(),
|
||||
kind: VarDeclKind::Const,
|
||||
decls: vec![VarDeclarator {
|
||||
span: DUMMY_SP,
|
||||
name: Pat::Ident(BindingIdent {
|
||||
id: Ident::new(
|
||||
fn_name.clone().into(),
|
||||
DUMMY_SP,
|
||||
SyntaxContext::empty(),
|
||||
),
|
||||
type_ann: None,
|
||||
}),
|
||||
init: Some(Box::new(Expr::Ident(Ident::new(
|
||||
hoisted_name.into(),
|
||||
DUMMY_SP,
|
||||
SyntaxContext::empty(),
|
||||
)))),
|
||||
definite: false,
|
||||
}],
|
||||
declare: false,
|
||||
}));
|
||||
*stmt = Stmt::Decl(var_decl);
|
||||
return;
|
||||
}
|
||||
TransformMode::Workflow => {
|
||||
// Include parent workflow name in step ID
|
||||
let step_fn_name = if let Some(parent) = &self.current_workflow_function_name {
|
||||
let step_fn_name = if let Some(parent) =
|
||||
&self.current_workflow_function_name
|
||||
{
|
||||
format!("{}/{}", parent, fn_name)
|
||||
} else {
|
||||
fn_name.clone()
|
||||
@@ -773,7 +822,8 @@ impl StepTransform {
|
||||
return;
|
||||
}
|
||||
TransformMode::Client => {
|
||||
*stmt = Stmt::Empty(EmptyStmt { span: DUMMY_SP });
|
||||
// In client mode, just remove the directive and keep the function
|
||||
self.remove_use_step_directive(&mut fn_decl.function.body);
|
||||
return;
|
||||
}
|
||||
}
|
||||
@@ -879,7 +929,7 @@ impl StepTransform {
|
||||
if let Some(init) = &mut declarator.init {
|
||||
if let Pat::Ident(binding) = &declarator.name {
|
||||
let name = binding.id.sym.to_string();
|
||||
|
||||
|
||||
// Check if the initializer is an arrow function with object literal body
|
||||
if let Expr::Arrow(arrow_expr) = &mut **init {
|
||||
match &mut *arrow_expr.body {
|
||||
@@ -896,9 +946,11 @@ impl StepTransform {
|
||||
}
|
||||
_ => None,
|
||||
};
|
||||
|
||||
|
||||
if let Some(obj_lit) = obj_lit_mut {
|
||||
self.process_object_properties_for_step_functions(obj_lit, &name);
|
||||
self.process_object_properties_for_step_functions(
|
||||
obj_lit, &name,
|
||||
);
|
||||
}
|
||||
}
|
||||
_ => {}
|
||||
@@ -932,6 +984,7 @@ impl StepTransform {
|
||||
in_step_function: false,
|
||||
in_workflow_function: false,
|
||||
current_workflow_function_name: None,
|
||||
current_parent_function_name: None,
|
||||
workflow_exports_to_expand: Vec::new(),
|
||||
workflow_functions_needing_id: Vec::new(),
|
||||
step_exports_to_convert: Vec::new(),
|
||||
@@ -2239,13 +2292,6 @@ impl StepTransform {
|
||||
ModuleItem::Stmt(Stmt::Decl(Decl::Var(var_decl))) => {
|
||||
// Check if all variables in this declaration are unused
|
||||
var_decl.decls.iter().all(|declarator| {
|
||||
// Don't remove if the initializer contains functions (which might have directives)
|
||||
if let Some(init) = &declarator.init {
|
||||
if self.contains_function_expr(init) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
match &declarator.name {
|
||||
Pat::Ident(binding) => {
|
||||
let name = binding.id.sym.to_string();
|
||||
@@ -2340,20 +2386,6 @@ impl StepTransform {
|
||||
}
|
||||
}
|
||||
|
||||
// Helper to check if an expression contains a function expression or object with methods
|
||||
fn contains_function_expr(&self, expr: &Expr) -> bool {
|
||||
match expr {
|
||||
Expr::Fn(_) | Expr::Arrow(_) => true,
|
||||
Expr::Object(obj_lit) => {
|
||||
// Check if object contains any method properties
|
||||
obj_lit.props.iter().any(
|
||||
|prop| matches!(prop, PropOrSpread::Prop(p) if matches!(&**p, Prop::Method(_))),
|
||||
)
|
||||
}
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
|
||||
// Helper to check if all bindings in an array pattern are unused
|
||||
fn all_bindings_unused(
|
||||
&self,
|
||||
@@ -2680,6 +2712,11 @@ impl<'a> VisitMut for ComprehensiveUsageCollector<'a> {
|
||||
let prev_function = self.current_function.clone();
|
||||
self.current_function = Some(fn_name.clone());
|
||||
|
||||
// Visit function parameters (which can contain default values that use other identifiers)
|
||||
for param in &mut fn_decl.function.params {
|
||||
param.visit_mut_with(self);
|
||||
}
|
||||
|
||||
// Visit the function content to find used identifiers (but don't mark the function name itself as used)
|
||||
if let Some(body) = &mut fn_decl.function.body {
|
||||
body.visit_mut_with(self);
|
||||
@@ -2824,8 +2861,16 @@ impl VisitMut for StepTransform {
|
||||
|
||||
// Process nested step functions FIRST (they typically appear earlier in source)
|
||||
let nested_functions: Vec<_> = self.nested_step_functions.drain(..).collect();
|
||||
|
||||
for (fn_name, mut fn_expr, span, closure_vars, was_arrow, parent_workflow_name) in nested_functions {
|
||||
|
||||
for (
|
||||
fn_name,
|
||||
mut fn_expr,
|
||||
span,
|
||||
closure_vars,
|
||||
was_arrow,
|
||||
parent_workflow_name,
|
||||
) in nested_functions
|
||||
{
|
||||
// Generate hoisted name including parent workflow function name
|
||||
let hoisted_name = if parent_workflow_name.is_empty() {
|
||||
fn_name.clone()
|
||||
@@ -3960,7 +4005,14 @@ impl VisitMut for StepTransform {
|
||||
}
|
||||
}
|
||||
|
||||
// Track parent function name for nested step hoisting
|
||||
let old_parent_name = self.current_parent_function_name.clone();
|
||||
self.current_parent_function_name = Some(fn_name);
|
||||
|
||||
fn_decl.visit_mut_children_with(self);
|
||||
|
||||
// Restore parent function name
|
||||
self.current_parent_function_name = old_parent_name;
|
||||
}
|
||||
|
||||
fn visit_mut_stmt(&mut self, stmt: &mut Stmt) {
|
||||
@@ -4496,8 +4548,12 @@ impl VisitMut for StepTransform {
|
||||
|
||||
match &mut **init {
|
||||
Expr::Fn(fn_expr) => {
|
||||
let has_step = self.has_step_directive(&fn_expr.function, false);
|
||||
let has_workflow =
|
||||
self.has_workflow_directive(&fn_expr.function, false);
|
||||
|
||||
// Check for step directive first
|
||||
if self.has_step_directive(&fn_expr.function, false) {
|
||||
if has_step {
|
||||
// Validate that it's async - emit error if not
|
||||
if !fn_expr.function.is_async {
|
||||
emit_error(WorkflowErrorKind::NonAsyncFunction {
|
||||
@@ -4568,7 +4624,7 @@ impl VisitMut for StepTransform {
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if self.has_workflow_directive(&fn_expr.function, false) {
|
||||
} else if has_workflow {
|
||||
// Validate that it's async - emit error if not
|
||||
if !fn_expr.function.is_async {
|
||||
emit_error(WorkflowErrorKind::NonAsyncFunction {
|
||||
@@ -4628,11 +4684,24 @@ impl VisitMut for StepTransform {
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// Regular function expression (not step/workflow) - track parent context for nested steps
|
||||
let old_parent = self.current_parent_function_name.clone();
|
||||
let old_in_module = self.in_module_level;
|
||||
self.current_parent_function_name = Some(name.clone());
|
||||
self.in_module_level = false;
|
||||
fn_expr.visit_mut_children_with(self);
|
||||
self.current_parent_function_name = old_parent;
|
||||
self.in_module_level = old_in_module;
|
||||
// Continue to next declarator (don't return early)
|
||||
}
|
||||
}
|
||||
Expr::Arrow(arrow_expr) => {
|
||||
let has_step = self.has_step_directive_arrow(arrow_expr, false);
|
||||
let has_workflow = self.has_workflow_directive_arrow(arrow_expr, false);
|
||||
|
||||
// Check for step directive first
|
||||
if self.has_step_directive_arrow(arrow_expr, false) {
|
||||
if has_step {
|
||||
// Validate that it's async - emit error if not
|
||||
if !arrow_expr.is_async {
|
||||
emit_error(WorkflowErrorKind::NonAsyncFunction {
|
||||
@@ -4643,8 +4712,8 @@ impl VisitMut for StepTransform {
|
||||
// It's valid - proceed with transformation
|
||||
self.step_function_names.insert(name.clone());
|
||||
|
||||
// Check if we're inside a workflow function
|
||||
if self.in_workflow_function {
|
||||
// Check if we're inside any function (nested), not just workflow functions
|
||||
if !self.in_module_level {
|
||||
match self.mode {
|
||||
TransformMode::Step => {
|
||||
// Hoist arrow function to module scope
|
||||
@@ -4711,18 +4780,35 @@ impl VisitMut for StepTransform {
|
||||
arrow_expr.span,
|
||||
closure_vars,
|
||||
true, // Was an arrow function
|
||||
self.current_workflow_function_name.clone().unwrap_or_default(),
|
||||
self.current_parent_function_name
|
||||
.clone()
|
||||
.unwrap_or_default(),
|
||||
));
|
||||
|
||||
// Mark the entire var declarator for removal by nulling out the init
|
||||
*init = Box::new(Expr::Invalid(Invalid {
|
||||
span: DUMMY_SP,
|
||||
}));
|
||||
// Replace with identifier reference to the hoisted function
|
||||
let hoisted_name = if let Some(parent) =
|
||||
&self.current_parent_function_name
|
||||
{
|
||||
if !parent.is_empty() {
|
||||
format!("{}${}", parent, name)
|
||||
} else {
|
||||
name
|
||||
}
|
||||
} else {
|
||||
name
|
||||
};
|
||||
*init = Box::new(Expr::Ident(Ident::new(
|
||||
hoisted_name.into(),
|
||||
DUMMY_SP,
|
||||
SyntaxContext::empty(),
|
||||
)));
|
||||
}
|
||||
TransformMode::Workflow => {
|
||||
// Replace with proxy reference (not a function call)
|
||||
// Include parent workflow name in step ID
|
||||
let step_fn_name = if let Some(parent) = &self.current_workflow_function_name {
|
||||
let step_fn_name = if let Some(parent) =
|
||||
&self.current_workflow_function_name
|
||||
{
|
||||
format!("{}/{}", parent, name)
|
||||
} else {
|
||||
name.clone()
|
||||
@@ -4741,14 +4827,14 @@ impl VisitMut for StepTransform {
|
||||
));
|
||||
}
|
||||
TransformMode::Client => {
|
||||
// In client mode, remove the nested step
|
||||
*init = Box::new(Expr::Invalid(Invalid {
|
||||
span: DUMMY_SP,
|
||||
}));
|
||||
// In client mode, just remove the directive and keep the function
|
||||
self.remove_use_step_directive_arrow(
|
||||
&mut arrow_expr.body,
|
||||
);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// Not in a workflow function - handle normally
|
||||
// At module level - handle normally
|
||||
match self.mode {
|
||||
TransformMode::Step => {
|
||||
self.remove_use_step_directive_arrow(
|
||||
@@ -4806,7 +4892,7 @@ impl VisitMut for StepTransform {
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if self.has_workflow_directive_arrow(arrow_expr, false) {
|
||||
} else if has_workflow {
|
||||
// Validate that it's async - emit error if not
|
||||
if !arrow_expr.is_async {
|
||||
emit_error(WorkflowErrorKind::NonAsyncFunction {
|
||||
@@ -4869,6 +4955,16 @@ impl VisitMut for StepTransform {
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// Regular arrow function (not step/workflow) - track parent context for nested steps
|
||||
let old_parent = self.current_parent_function_name.clone();
|
||||
let old_in_module = self.in_module_level;
|
||||
self.current_parent_function_name = Some(name.clone());
|
||||
self.in_module_level = false;
|
||||
arrow_expr.visit_mut_children_with(self);
|
||||
self.current_parent_function_name = old_parent;
|
||||
self.in_module_level = old_in_module;
|
||||
// Continue to next declarator (don't return early)
|
||||
}
|
||||
}
|
||||
Expr::Object(obj_lit) => {
|
||||
@@ -4977,8 +5073,9 @@ impl VisitMut for StepTransform {
|
||||
assign.visit_mut_children_with(self);
|
||||
}
|
||||
|
||||
// Override visit_mut_expr to track closure variables
|
||||
// Override visit_mut_expr to track closure variables and handle step functions
|
||||
fn visit_mut_expr(&mut self, expr: &mut Expr) {
|
||||
// Track closure variables first
|
||||
if !self.in_module_level && self.should_track_names {
|
||||
if let Ok(name) = Name::try_from(&*expr) {
|
||||
if self.in_callee {
|
||||
@@ -4989,6 +5086,236 @@ impl VisitMut for StepTransform {
|
||||
}
|
||||
}
|
||||
|
||||
// Handle step functions that appear in expressions (e.g., return statements)
|
||||
// but are not in var declarators (those are handled in visit_mut_var_decl)
|
||||
match expr {
|
||||
Expr::Fn(fn_expr) => {
|
||||
if self.has_step_directive(&fn_expr.function, false) {
|
||||
if !fn_expr.function.is_async {
|
||||
emit_error(WorkflowErrorKind::NonAsyncFunction {
|
||||
span: fn_expr.function.span,
|
||||
directive: "use step",
|
||||
});
|
||||
} else if !self.in_module_level {
|
||||
// Nested step function in an expression (e.g., return statement)
|
||||
let name = fn_expr
|
||||
.ident
|
||||
.as_ref()
|
||||
.map(|i| i.sym.to_string())
|
||||
.unwrap_or_else(|| {
|
||||
// Generate a name for anonymous functions
|
||||
let name = format!("_anonymousStep{}", self.anonymous_fn_counter);
|
||||
self.anonymous_fn_counter += 1;
|
||||
name
|
||||
});
|
||||
|
||||
if fn_expr.ident.is_some() {
|
||||
// Only increment if we didn't use it above
|
||||
// (the closure above already incremented)
|
||||
}
|
||||
|
||||
self.step_function_names.insert(name.clone());
|
||||
|
||||
match self.mode {
|
||||
TransformMode::Step => {
|
||||
// Hoist to module scope
|
||||
let mut cloned_function = fn_expr.function.clone();
|
||||
self.remove_use_step_directive(&mut cloned_function.body);
|
||||
|
||||
let closure_vars = ClosureVariableCollector::collect_from_function(
|
||||
&cloned_function,
|
||||
&self.module_imports,
|
||||
);
|
||||
|
||||
let hoisted_fn_expr = FnExpr {
|
||||
ident: Some(Ident::new(
|
||||
name.clone().into(),
|
||||
DUMMY_SP,
|
||||
SyntaxContext::empty(),
|
||||
)),
|
||||
function: cloned_function,
|
||||
};
|
||||
|
||||
self.nested_step_functions.push((
|
||||
name.clone(),
|
||||
hoisted_fn_expr,
|
||||
fn_expr.function.span,
|
||||
closure_vars,
|
||||
false, // Not an arrow function
|
||||
self.current_parent_function_name
|
||||
.clone()
|
||||
.unwrap_or_default(),
|
||||
));
|
||||
|
||||
// Replace with identifier reference
|
||||
let hoisted_name =
|
||||
if let Some(parent) = &self.current_parent_function_name {
|
||||
if !parent.is_empty() {
|
||||
format!("{}${}", parent, name)
|
||||
} else {
|
||||
name
|
||||
}
|
||||
} else {
|
||||
name
|
||||
};
|
||||
*expr = Expr::Ident(Ident::new(
|
||||
hoisted_name.into(),
|
||||
DUMMY_SP,
|
||||
SyntaxContext::empty(),
|
||||
));
|
||||
return; // Don't visit children since we replaced the expr
|
||||
}
|
||||
TransformMode::Workflow => {
|
||||
// Replace with proxy reference
|
||||
let step_fn_name =
|
||||
if let Some(parent) = &self.current_workflow_function_name {
|
||||
format!("{}/{}", parent, name)
|
||||
} else {
|
||||
name.clone()
|
||||
};
|
||||
let step_id = self.create_id(
|
||||
Some(&step_fn_name),
|
||||
fn_expr.function.span,
|
||||
false,
|
||||
);
|
||||
|
||||
let closure_vars = ClosureVariableCollector::collect_from_function(
|
||||
&fn_expr.function,
|
||||
&self.module_imports,
|
||||
);
|
||||
*expr = self.create_step_proxy_reference(&step_id, &closure_vars);
|
||||
return; // Don't visit children since we replaced the expr
|
||||
}
|
||||
TransformMode::Client => {
|
||||
// In client mode, just remove the directive and keep the function
|
||||
self.remove_use_step_directive(&mut fn_expr.function.body);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Expr::Arrow(arrow_expr) => {
|
||||
if self.has_step_directive_arrow(arrow_expr, false) {
|
||||
if !arrow_expr.is_async {
|
||||
emit_error(WorkflowErrorKind::NonAsyncFunction {
|
||||
span: arrow_expr.span,
|
||||
directive: "use step",
|
||||
});
|
||||
} else if !self.in_module_level {
|
||||
// Nested step arrow function in an expression (e.g., return statement)
|
||||
let name = format!("_anonymousStep{}", self.anonymous_fn_counter);
|
||||
self.anonymous_fn_counter += 1;
|
||||
self.step_function_names.insert(name.clone());
|
||||
|
||||
match self.mode {
|
||||
TransformMode::Step => {
|
||||
// Hoist to module scope
|
||||
let mut cloned_arrow = arrow_expr.clone();
|
||||
self.remove_use_step_directive_arrow(&mut cloned_arrow.body);
|
||||
|
||||
let closure_vars =
|
||||
ClosureVariableCollector::collect_from_arrow_expr(
|
||||
&cloned_arrow,
|
||||
&self.module_imports,
|
||||
);
|
||||
|
||||
// Convert to function expression for hoisting
|
||||
let fn_expr = FnExpr {
|
||||
ident: Some(Ident::new(
|
||||
name.clone().into(),
|
||||
DUMMY_SP,
|
||||
SyntaxContext::empty(),
|
||||
)),
|
||||
function: Box::new(Function {
|
||||
params: cloned_arrow
|
||||
.params
|
||||
.iter()
|
||||
.map(|pat| Param {
|
||||
span: DUMMY_SP,
|
||||
decorators: vec![],
|
||||
pat: pat.clone(),
|
||||
})
|
||||
.collect(),
|
||||
decorators: vec![],
|
||||
span: cloned_arrow.span,
|
||||
ctxt: SyntaxContext::empty(),
|
||||
body: match *cloned_arrow.body {
|
||||
BlockStmtOrExpr::BlockStmt(block) => Some(block),
|
||||
BlockStmtOrExpr::Expr(expr) => Some(BlockStmt {
|
||||
span: DUMMY_SP,
|
||||
ctxt: SyntaxContext::empty(),
|
||||
stmts: vec![Stmt::Return(ReturnStmt {
|
||||
span: DUMMY_SP,
|
||||
arg: Some(expr),
|
||||
})],
|
||||
}),
|
||||
},
|
||||
is_generator: false,
|
||||
is_async: cloned_arrow.is_async,
|
||||
type_params: cloned_arrow.type_params.clone(),
|
||||
return_type: cloned_arrow.return_type.clone(),
|
||||
}),
|
||||
};
|
||||
|
||||
self.nested_step_functions.push((
|
||||
name.clone(),
|
||||
fn_expr,
|
||||
arrow_expr.span,
|
||||
closure_vars,
|
||||
true, // Was an arrow function
|
||||
self.current_parent_function_name
|
||||
.clone()
|
||||
.unwrap_or_default(),
|
||||
));
|
||||
|
||||
// Replace with identifier reference
|
||||
let hoisted_name =
|
||||
if let Some(parent) = &self.current_parent_function_name {
|
||||
if !parent.is_empty() {
|
||||
format!("{}${}", parent, name)
|
||||
} else {
|
||||
name
|
||||
}
|
||||
} else {
|
||||
name
|
||||
};
|
||||
*expr = Expr::Ident(Ident::new(
|
||||
hoisted_name.into(),
|
||||
DUMMY_SP,
|
||||
SyntaxContext::empty(),
|
||||
));
|
||||
return; // Don't visit children since we replaced the expr
|
||||
}
|
||||
TransformMode::Workflow => {
|
||||
// Replace with proxy reference
|
||||
let step_fn_name =
|
||||
if let Some(parent) = &self.current_workflow_function_name {
|
||||
format!("{}/{}", parent, name)
|
||||
} else {
|
||||
name.clone()
|
||||
};
|
||||
let step_id =
|
||||
self.create_id(Some(&step_fn_name), arrow_expr.span, false);
|
||||
|
||||
let closure_vars =
|
||||
ClosureVariableCollector::collect_from_arrow_expr(
|
||||
arrow_expr,
|
||||
&self.module_imports,
|
||||
);
|
||||
*expr = self.create_step_proxy_reference(&step_id, &closure_vars);
|
||||
return; // Don't visit children since we replaced the expr
|
||||
}
|
||||
TransformMode::Client => {
|
||||
// In client mode, just remove the directive and keep the function
|
||||
self.remove_use_step_directive_arrow(&mut arrow_expr.body);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
|
||||
expr.visit_mut_children_with(self);
|
||||
}
|
||||
|
||||
@@ -5519,7 +5846,9 @@ impl VisitMut for StepTransform {
|
||||
arrow_expr.span,
|
||||
closure_vars,
|
||||
true, // Was an arrow function
|
||||
self.current_workflow_function_name.clone().unwrap_or_default(),
|
||||
self.current_workflow_function_name
|
||||
.clone()
|
||||
.unwrap_or_default(),
|
||||
));
|
||||
|
||||
// Replace with identifier reference
|
||||
@@ -5535,7 +5864,9 @@ impl VisitMut for StepTransform {
|
||||
&mut arrow_expr.body,
|
||||
);
|
||||
// Include parent workflow name in step ID
|
||||
let step_fn_name = if let Some(parent) = &self.current_workflow_function_name {
|
||||
let step_fn_name = if let Some(parent) =
|
||||
&self.current_workflow_function_name
|
||||
{
|
||||
format!("{}/{}", parent, generated_name)
|
||||
} else {
|
||||
generated_name.clone()
|
||||
@@ -5607,7 +5938,9 @@ impl VisitMut for StepTransform {
|
||||
fn_expr.function.span,
|
||||
closure_vars,
|
||||
false, // Was a function expression
|
||||
self.current_workflow_function_name.clone().unwrap_or_default(),
|
||||
self.current_workflow_function_name
|
||||
.clone()
|
||||
.unwrap_or_default(),
|
||||
));
|
||||
|
||||
// Replace with identifier reference
|
||||
@@ -5623,7 +5956,9 @@ impl VisitMut for StepTransform {
|
||||
&mut fn_expr.function.body,
|
||||
);
|
||||
// Include parent workflow name in step ID
|
||||
let step_fn_name = if let Some(parent) = &self.current_workflow_function_name {
|
||||
let step_fn_name = if let Some(parent) =
|
||||
&self.current_workflow_function_name
|
||||
{
|
||||
format!("{}/{}", parent, generated_name)
|
||||
} else {
|
||||
generated_name.clone()
|
||||
@@ -5702,7 +6037,9 @@ impl VisitMut for StepTransform {
|
||||
method_prop.function.span,
|
||||
closure_vars,
|
||||
false, // Was a method
|
||||
self.current_workflow_function_name.clone().unwrap_or_default(),
|
||||
self.current_workflow_function_name
|
||||
.clone()
|
||||
.unwrap_or_default(),
|
||||
));
|
||||
|
||||
// Replace method with property pointing to identifier
|
||||
@@ -5722,7 +6059,9 @@ impl VisitMut for StepTransform {
|
||||
&mut method_prop.function.body,
|
||||
);
|
||||
// Include parent workflow name in step ID
|
||||
let step_fn_name = if let Some(parent) = &self.current_workflow_function_name {
|
||||
let step_fn_name = if let Some(parent) =
|
||||
&self.current_workflow_function_name
|
||||
{
|
||||
format!("{}/{}", parent, generated_name)
|
||||
} else {
|
||||
generated_name.clone()
|
||||
|
||||
-7
@@ -9,13 +9,6 @@ export const syncWorkflow = ()=>{
|
||||
'use workflow';
|
||||
return 'test';
|
||||
};
|
||||
// Error: sync method with use step
|
||||
const obj = {
|
||||
syncMethod () {
|
||||
'use step';
|
||||
return true;
|
||||
}
|
||||
};
|
||||
// These are ok
|
||||
export async function validStep() {
|
||||
return 42;
|
||||
|
||||
-7
@@ -9,13 +9,6 @@ export const syncWorkflow = ()=>{
|
||||
'use workflow';
|
||||
return 'test';
|
||||
};
|
||||
// Error: sync method with use step
|
||||
const obj = {
|
||||
syncMethod () {
|
||||
'use step';
|
||||
return true;
|
||||
}
|
||||
};
|
||||
// These are ok
|
||||
export var validStep = globalThis[Symbol.for("WORKFLOW_USE_STEP")]("step//input.js//validStep");
|
||||
export const validWorkflow = async ()=>{
|
||||
|
||||
@@ -0,0 +1,32 @@
|
||||
// Test case for functions used in default parameter values
|
||||
// The createDefaultDownloadFunction should NOT be removed by DCE
|
||||
|
||||
const createDefaultDownloadFunction = (download = defaultDownload) => (requestedDownloads) =>
|
||||
Promise.all(requestedDownloads.map(async (r) => r.isUrlSupportedByModel ? null : download(r)));
|
||||
|
||||
async function defaultDownload(request) {
|
||||
return fetch(request.url);
|
||||
}
|
||||
|
||||
// This function uses createDefaultDownloadFunction in a default parameter value
|
||||
// DCE must NOT remove createDefaultDownloadFunction
|
||||
async function convertToLanguageModelPrompt({
|
||||
prompt,
|
||||
supportedUrls,
|
||||
download = createDefaultDownloadFunction()
|
||||
}) {
|
||||
return { prompt, supportedUrls, download };
|
||||
}
|
||||
|
||||
export async function myWorkflow(input) {
|
||||
'use workflow';
|
||||
|
||||
const result = await convertToLanguageModelPrompt({
|
||||
prompt: input.prompt,
|
||||
supportedUrls: {},
|
||||
download: undefined
|
||||
});
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
+7
@@ -0,0 +1,7 @@
|
||||
// Test case for functions used in default parameter values
|
||||
// The createDefaultDownloadFunction should NOT be removed by DCE
|
||||
/**__internal_workflows{"workflows":{"input.js":{"myWorkflow":{"workflowId":"workflow//input.js//myWorkflow"}}}}*/;
|
||||
export async function myWorkflow(input) {
|
||||
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";
|
||||
+25
@@ -0,0 +1,25 @@
|
||||
// Test case for functions used in default parameter values
|
||||
// The createDefaultDownloadFunction should NOT be removed by DCE
|
||||
/**__internal_workflows{"workflows":{"input.js":{"myWorkflow":{"workflowId":"workflow//input.js//myWorkflow"}}}}*/;
|
||||
const createDefaultDownloadFunction = (download = defaultDownload)=>(requestedDownloads)=>Promise.all(requestedDownloads.map(async (r)=>r.isUrlSupportedByModel ? null : download(r)));
|
||||
async function defaultDownload(request) {
|
||||
return fetch(request.url);
|
||||
}
|
||||
// This function uses createDefaultDownloadFunction in a default parameter value
|
||||
// DCE must NOT remove createDefaultDownloadFunction
|
||||
async function convertToLanguageModelPrompt({ prompt, supportedUrls, download = createDefaultDownloadFunction() }) {
|
||||
return {
|
||||
prompt,
|
||||
supportedUrls,
|
||||
download
|
||||
};
|
||||
}
|
||||
export async function myWorkflow(input) {
|
||||
'use workflow';
|
||||
const result = await convertToLanguageModelPrompt({
|
||||
prompt: input.prompt,
|
||||
supportedUrls: {},
|
||||
download: undefined
|
||||
});
|
||||
return result;
|
||||
}
|
||||
+25
@@ -0,0 +1,25 @@
|
||||
// Test case for functions used in default parameter values
|
||||
// The createDefaultDownloadFunction should NOT be removed by DCE
|
||||
/**__internal_workflows{"workflows":{"input.js":{"myWorkflow":{"workflowId":"workflow//input.js//myWorkflow"}}}}*/;
|
||||
const createDefaultDownloadFunction = (download = defaultDownload)=>(requestedDownloads)=>Promise.all(requestedDownloads.map(async (r)=>r.isUrlSupportedByModel ? null : download(r)));
|
||||
async function defaultDownload(request) {
|
||||
return fetch(request.url);
|
||||
}
|
||||
// This function uses createDefaultDownloadFunction in a default parameter value
|
||||
// DCE must NOT remove createDefaultDownloadFunction
|
||||
async function convertToLanguageModelPrompt({ prompt, supportedUrls, download = createDefaultDownloadFunction() }) {
|
||||
return {
|
||||
prompt,
|
||||
supportedUrls,
|
||||
download
|
||||
};
|
||||
}
|
||||
export async function myWorkflow(input) {
|
||||
const result = await convertToLanguageModelPrompt({
|
||||
prompt: input.prompt,
|
||||
supportedUrls: {},
|
||||
download: undefined
|
||||
});
|
||||
return result;
|
||||
}
|
||||
myWorkflow.workflowId = "workflow//input.js//myWorkflow";
|
||||
-3
@@ -1,7 +1,4 @@
|
||||
/**__internal_workflows{"steps":{"input.js":{"step":{"stepId":"step//input.js//step"},"stepArrow":{"stepId":"step//input.js//stepArrow"}}}}*/;
|
||||
const localArrow = async (input)=>{
|
||||
return input.bar;
|
||||
};
|
||||
export async function step(input) {
|
||||
return input.foo;
|
||||
}
|
||||
|
||||
-3
@@ -1,7 +1,4 @@
|
||||
/**__internal_workflows{"steps":{"input.js":{"step":{"stepId":"step//input.js//step"},"stepArrow":{"stepId":"step//input.js//stepArrow"}}}}*/;
|
||||
'use step';
|
||||
const localArrow = async (input)=>{
|
||||
return input.bar;
|
||||
};
|
||||
export var step = globalThis[Symbol.for("WORKFLOW_USE_STEP")]("step//input.js//step");
|
||||
export const stepArrow = globalThis[Symbol.for("WORKFLOW_USE_STEP")]("step//input.js//stepArrow");
|
||||
|
||||
-3
@@ -1,7 +1,4 @@
|
||||
/**__internal_workflows{"workflows":{"input.js":{"arrowWorkflow":{"workflowId":"workflow//input.js//arrowWorkflow"},"workflow":{"workflowId":"workflow//input.js//workflow"}}}}*/;
|
||||
const localArrow = async (input)=>{
|
||||
return input.bar;
|
||||
};
|
||||
export async function workflow(input) {
|
||||
return input.foo;
|
||||
}
|
||||
|
||||
-3
@@ -1,7 +1,4 @@
|
||||
/**__internal_workflows{"workflows":{"input.js":{"arrowWorkflow":{"workflowId":"workflow//input.js//arrowWorkflow"},"workflow":{"workflowId":"workflow//input.js//workflow"}}}}*/;
|
||||
const localArrow = async (input)=>{
|
||||
return input.bar;
|
||||
};
|
||||
export async function workflow(input) {
|
||||
return input.foo;
|
||||
}
|
||||
|
||||
+13
@@ -14,3 +14,16 @@ export const fn3 = async () => {
|
||||
return 4;
|
||||
};
|
||||
|
||||
// Test case: regular function BEFORE step function in same declaration
|
||||
// This verifies that processing doesn't skip the step function
|
||||
const regularArrow = () => 1, stepAfterRegular = async () => {
|
||||
'use step';
|
||||
return 5;
|
||||
};
|
||||
|
||||
// Test case: regular function expression BEFORE step function
|
||||
const regularFn = function() { return 2; }, stepAfterRegularFn = async function() {
|
||||
'use step';
|
||||
return 6;
|
||||
};
|
||||
|
||||
|
||||
+12
-1
@@ -1,4 +1,4 @@
|
||||
/**__internal_workflows{"steps":{"input.js":{"fn1":{"stepId":"step//input.js//fn1"},"fn2":{"stepId":"step//input.js//fn2"},"fn3":{"stepId":"step//input.js//fn3"},"fn4":{"stepId":"step//input.js//fn4"}}}}*/;
|
||||
/**__internal_workflows{"steps":{"input.js":{"fn1":{"stepId":"step//input.js//fn1"},"fn2":{"stepId":"step//input.js//fn2"},"fn3":{"stepId":"step//input.js//fn3"},"fn4":{"stepId":"step//input.js//fn4"},"stepAfterRegular":{"stepId":"step//input.js//stepAfterRegular"},"stepAfterRegularFn":{"stepId":"step//input.js//stepAfterRegularFn"}}}}*/;
|
||||
const fn1 = async ()=>{
|
||||
return 1;
|
||||
}, fn2 = async ()=>{
|
||||
@@ -9,3 +9,14 @@ export const fn3 = async ()=>{
|
||||
}, fn4 = async ()=>{
|
||||
return 4;
|
||||
};
|
||||
// Test case: regular function BEFORE step function in same declaration
|
||||
// This verifies that processing doesn't skip the step function
|
||||
const regularArrow = ()=>1, stepAfterRegular = async ()=>{
|
||||
return 5;
|
||||
};
|
||||
// Test case: regular function expression BEFORE step function
|
||||
const regularFn = function() {
|
||||
return 2;
|
||||
}, stepAfterRegularFn = async function() {
|
||||
return 6;
|
||||
};
|
||||
|
||||
+14
-1
@@ -1,5 +1,5 @@
|
||||
import { registerStepFunction } from "workflow/internal/private";
|
||||
/**__internal_workflows{"steps":{"input.js":{"fn1":{"stepId":"step//input.js//fn1"},"fn2":{"stepId":"step//input.js//fn2"},"fn3":{"stepId":"step//input.js//fn3"},"fn4":{"stepId":"step//input.js//fn4"}}}}*/;
|
||||
/**__internal_workflows{"steps":{"input.js":{"fn1":{"stepId":"step//input.js//fn1"},"fn2":{"stepId":"step//input.js//fn2"},"fn3":{"stepId":"step//input.js//fn3"},"fn4":{"stepId":"step//input.js//fn4"},"stepAfterRegular":{"stepId":"step//input.js//stepAfterRegular"},"stepAfterRegularFn":{"stepId":"step//input.js//stepAfterRegularFn"}}}}*/;
|
||||
const fn1 = async ()=>{
|
||||
return 1;
|
||||
}, fn2 = async ()=>{
|
||||
@@ -10,7 +10,20 @@ export const fn3 = async ()=>{
|
||||
}, fn4 = async ()=>{
|
||||
return 4;
|
||||
};
|
||||
// Test case: regular function BEFORE step function in same declaration
|
||||
// This verifies that processing doesn't skip the step function
|
||||
const regularArrow = ()=>1, stepAfterRegular = async ()=>{
|
||||
return 5;
|
||||
};
|
||||
// Test case: regular function expression BEFORE step function
|
||||
const regularFn = function() {
|
||||
return 2;
|
||||
}, stepAfterRegularFn = async function() {
|
||||
return 6;
|
||||
};
|
||||
registerStepFunction("step//input.js//fn1", fn1);
|
||||
registerStepFunction("step//input.js//fn2", fn2);
|
||||
registerStepFunction("step//input.js//fn3", fn3);
|
||||
registerStepFunction("step//input.js//fn4", fn4);
|
||||
registerStepFunction("step//input.js//stepAfterRegular", stepAfterRegular);
|
||||
registerStepFunction("step//input.js//stepAfterRegularFn", stepAfterRegularFn);
|
||||
|
||||
+8
-1
@@ -1,3 +1,10 @@
|
||||
/**__internal_workflows{"steps":{"input.js":{"fn1":{"stepId":"step//input.js//fn1"},"fn2":{"stepId":"step//input.js//fn2"},"fn3":{"stepId":"step//input.js//fn3"},"fn4":{"stepId":"step//input.js//fn4"}}}}*/;
|
||||
/**__internal_workflows{"steps":{"input.js":{"fn1":{"stepId":"step//input.js//fn1"},"fn2":{"stepId":"step//input.js//fn2"},"fn3":{"stepId":"step//input.js//fn3"},"fn4":{"stepId":"step//input.js//fn4"},"stepAfterRegular":{"stepId":"step//input.js//stepAfterRegular"},"stepAfterRegularFn":{"stepId":"step//input.js//stepAfterRegularFn"}}}}*/;
|
||||
const fn1 = globalThis[Symbol.for("WORKFLOW_USE_STEP")]("step//input.js//fn1"), fn2 = globalThis[Symbol.for("WORKFLOW_USE_STEP")]("step//input.js//fn2");
|
||||
export const fn3 = globalThis[Symbol.for("WORKFLOW_USE_STEP")]("step//input.js//fn3"), fn4 = globalThis[Symbol.for("WORKFLOW_USE_STEP")]("step//input.js//fn4");
|
||||
// Test case: regular function BEFORE step function in same declaration
|
||||
// This verifies that processing doesn't skip the step function
|
||||
const regularArrow = ()=>1, stepAfterRegular = globalThis[Symbol.for("WORKFLOW_USE_STEP")]("step//input.js//stepAfterRegular");
|
||||
// Test case: regular function expression BEFORE step function
|
||||
const regularFn = function() {
|
||||
return 2;
|
||||
}, stepAfterRegularFn = globalThis[Symbol.for("WORKFLOW_USE_STEP")]("step//input.js//stepAfterRegularFn");
|
||||
|
||||
+8
@@ -11,6 +11,14 @@ var 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
|
||||
|
||||
+70
@@ -1,6 +1,67 @@
|
||||
import { DurableAgent } from '@workflow/ai/agent';
|
||||
import { gateway } from 'ai';
|
||||
|
||||
function stepWrapperReturnArrowFunctionVar(a, b, c) {
|
||||
const fn = async () => {
|
||||
'use step';
|
||||
return a + b + c;
|
||||
};
|
||||
return fn;
|
||||
}
|
||||
|
||||
function stepWrapperReturnNamedFunction(a, b, c) {
|
||||
return async function f() {
|
||||
'use step';
|
||||
return a + b + c;
|
||||
};
|
||||
}
|
||||
|
||||
function stepWrapperReturnArrowFunction(a, b, c) {
|
||||
return async () => {
|
||||
'use step';
|
||||
return a + b + c;
|
||||
};
|
||||
}
|
||||
|
||||
function stepWrapperReturnNamedFunctionVar(a, b, c) {
|
||||
async function fn() {
|
||||
'use step';
|
||||
return a + b + c;
|
||||
}
|
||||
return fn;
|
||||
}
|
||||
|
||||
const arrowWrapperReturnArrowFunctionVar = (a, b, c) => {
|
||||
const fn = async () => {
|
||||
'use step';
|
||||
return a + b + c;
|
||||
};
|
||||
return fn;
|
||||
}
|
||||
|
||||
const arrowWrapperReturnNamedFunction = (a, b, c) => {
|
||||
return async function f() {
|
||||
'use step';
|
||||
return a + b + c;
|
||||
};
|
||||
}
|
||||
|
||||
const arrowWrapperReturnArrowFunction = (a, b, c) => {
|
||||
return async () => {
|
||||
'use step';
|
||||
return a + b + c;
|
||||
};
|
||||
}
|
||||
|
||||
const arrowWrapperReturnNamedFunctionVar = (a, b, c) => {
|
||||
async function fn() {
|
||||
'use step';
|
||||
return a + b + c;
|
||||
}
|
||||
return fn;
|
||||
}
|
||||
|
||||
|
||||
export async function wflow() {
|
||||
'use workflow';
|
||||
let count = 42;
|
||||
@@ -27,4 +88,13 @@ export async function wflow() {
|
||||
console.log('count', count);
|
||||
},
|
||||
});
|
||||
|
||||
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)();
|
||||
}
|
||||
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
/**__internal_workflows{"workflows":{"input.js":{"wflow":{"workflowId":"workflow//input.js//wflow"}}}}*/;
|
||||
/**__internal_workflows{"workflows":{"input.js":{"wflow":{"workflowId":"workflow//input.js//wflow"}}},"steps":{"input.js":{"_anonymousStep0":{"stepId":"step//input.js//_anonymousStep0"},"_anonymousStep1":{"stepId":"step//input.js//_anonymousStep1"},"f":{"stepId":"step//input.js//f"},"fn":{"stepId":"step//input.js//fn"}}}}*/;
|
||||
export async function wflow() {
|
||||
throw new Error("You attempted to execute workflow wflow function directly. To start a workflow, use start(wflow) from workflow/api");
|
||||
}
|
||||
|
||||
+87
-9
@@ -1,33 +1,111 @@
|
||||
import { __private_getClosureVars, registerStepFunction } from "workflow/internal/private";
|
||||
import { DurableAgent } from '@workflow/ai/agent';
|
||||
import { gateway } from 'ai';
|
||||
/**__internal_workflows{"workflows":{"input.js":{"wflow":{"workflowId":"workflow//input.js//wflow"}}},"steps":{"input.js":{"_anonymousStep0":{"stepId":"step//input.js//_anonymousStep0"},"_anonymousStep1":{"stepId":"step//input.js//_anonymousStep1"},"_anonymousStep2":{"stepId":"step//input.js//_anonymousStep2"},"namedStepWithClosureVars":{"stepId":"step//input.js//namedStepWithClosureVars"}}}}*/;
|
||||
/**__internal_workflows{"workflows":{"input.js":{"wflow":{"workflowId":"workflow//input.js//wflow"}}},"steps":{"input.js":{"_anonymousStep0":{"stepId":"step//input.js//_anonymousStep0"},"_anonymousStep1":{"stepId":"step//input.js//_anonymousStep1"},"_anonymousStep2":{"stepId":"step//input.js//_anonymousStep2"},"_anonymousStep3":{"stepId":"step//input.js//_anonymousStep3"},"_anonymousStep4":{"stepId":"step//input.js//_anonymousStep4"},"f":{"stepId":"step//input.js//f"},"fn":{"stepId":"step//input.js//fn"},"namedStepWithClosureVars":{"stepId":"step//input.js//namedStepWithClosureVars"}}}}*/;
|
||||
var stepWrapperReturnArrowFunctionVar$fn = async ()=>{
|
||||
const { a, b, c } = __private_getClosureVars();
|
||||
return a + b + c;
|
||||
};
|
||||
async function stepWrapperReturnNamedFunction$f() {
|
||||
const { a, b, c } = __private_getClosureVars();
|
||||
return a + b + c;
|
||||
}
|
||||
var stepWrapperReturnArrowFunction$_anonymousStep0 = async ()=>{
|
||||
const { a, b, c } = __private_getClosureVars();
|
||||
return a + b + c;
|
||||
};
|
||||
async function stepWrapperReturnNamedFunctionVar$fn() {
|
||||
const { a, b, c } = __private_getClosureVars();
|
||||
return a + b + c;
|
||||
}
|
||||
var arrowWrapperReturnArrowFunctionVar$fn = async ()=>{
|
||||
const { a, b, c } = __private_getClosureVars();
|
||||
return a + b + c;
|
||||
};
|
||||
async function arrowWrapperReturnNamedFunction$f() {
|
||||
const { a, b, c } = __private_getClosureVars();
|
||||
return a + b + c;
|
||||
}
|
||||
var arrowWrapperReturnArrowFunction$_anonymousStep1 = async ()=>{
|
||||
const { a, b, c } = __private_getClosureVars();
|
||||
return a + b + c;
|
||||
};
|
||||
async function arrowWrapperReturnNamedFunctionVar$fn() {
|
||||
const { a, b, c } = __private_getClosureVars();
|
||||
return a + b + c;
|
||||
}
|
||||
async function wflow$namedStepWithClosureVars() {
|
||||
const { count } = __private_getClosureVars();
|
||||
console.log('count', count);
|
||||
}
|
||||
var wflow$_anonymousStep0 = async ()=>{
|
||||
var wflow$_anonymousStep2 = async ()=>{
|
||||
const { count } = __private_getClosureVars();
|
||||
console.log('count', count);
|
||||
return gateway('openai/gpt-5');
|
||||
};
|
||||
async function wflow$_anonymousStep1() {
|
||||
async function wflow$_anonymousStep3() {
|
||||
const { count } = __private_getClosureVars();
|
||||
console.log('count', count);
|
||||
}
|
||||
async function wflow$_anonymousStep2() {
|
||||
async function wflow$_anonymousStep4() {
|
||||
const { count } = __private_getClosureVars();
|
||||
console.log('count', count);
|
||||
}
|
||||
function stepWrapperReturnArrowFunctionVar(a, b, c) {
|
||||
const fn = stepWrapperReturnArrowFunctionVar$fn;
|
||||
return fn;
|
||||
}
|
||||
function stepWrapperReturnNamedFunction(a, b, c) {
|
||||
return stepWrapperReturnNamedFunction$f;
|
||||
}
|
||||
function stepWrapperReturnArrowFunction(a, b, c) {
|
||||
return stepWrapperReturnArrowFunction$_anonymousStep0;
|
||||
}
|
||||
function stepWrapperReturnNamedFunctionVar(a, b, c) {
|
||||
const fn = stepWrapperReturnNamedFunctionVar$fn;
|
||||
return fn;
|
||||
}
|
||||
const arrowWrapperReturnArrowFunctionVar = (a, b, c)=>{
|
||||
const fn = arrowWrapperReturnArrowFunctionVar$fn;
|
||||
return fn;
|
||||
};
|
||||
const arrowWrapperReturnNamedFunction = (a, b, c)=>{
|
||||
return arrowWrapperReturnNamedFunction$f;
|
||||
};
|
||||
const arrowWrapperReturnArrowFunction = (a, b, c)=>{
|
||||
return arrowWrapperReturnArrowFunction$_anonymousStep1;
|
||||
};
|
||||
const arrowWrapperReturnNamedFunctionVar = (a, b, c)=>{
|
||||
const fn = arrowWrapperReturnNamedFunctionVar$fn;
|
||||
return fn;
|
||||
};
|
||||
export async function wflow() {
|
||||
'use workflow';
|
||||
let count = 42;
|
||||
const namedStepWithClosureVars = wflow$namedStepWithClosureVars;
|
||||
const agent = new DurableAgent({
|
||||
arrowFunctionWithClosureVars: _anonymousStep0,
|
||||
namedFunctionWithClosureVars: _anonymousStep1,
|
||||
methodWithClosureVars: _anonymousStep2
|
||||
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)();
|
||||
}
|
||||
registerStepFunction("step//input.js//stepWrapperReturnArrowFunctionVar/fn", stepWrapperReturnArrowFunctionVar$fn);
|
||||
registerStepFunction("step//input.js//stepWrapperReturnNamedFunction/f", stepWrapperReturnNamedFunction$f);
|
||||
registerStepFunction("step//input.js//stepWrapperReturnArrowFunction/_anonymousStep0", stepWrapperReturnArrowFunction$_anonymousStep0);
|
||||
registerStepFunction("step//input.js//stepWrapperReturnNamedFunctionVar/fn", stepWrapperReturnNamedFunctionVar$fn);
|
||||
registerStepFunction("step//input.js//arrowWrapperReturnArrowFunctionVar/fn", arrowWrapperReturnArrowFunctionVar$fn);
|
||||
registerStepFunction("step//input.js//arrowWrapperReturnNamedFunction/f", arrowWrapperReturnNamedFunction$f);
|
||||
registerStepFunction("step//input.js//arrowWrapperReturnArrowFunction/_anonymousStep1", arrowWrapperReturnArrowFunction$_anonymousStep1);
|
||||
registerStepFunction("step//input.js//arrowWrapperReturnNamedFunctionVar/fn", arrowWrapperReturnNamedFunctionVar$fn);
|
||||
registerStepFunction("step//input.js//wflow/namedStepWithClosureVars", wflow$namedStepWithClosureVars);
|
||||
registerStepFunction("step//input.js//wflow/_anonymousStep0", wflow$_anonymousStep0);
|
||||
registerStepFunction("step//input.js//wflow/_anonymousStep1", wflow$_anonymousStep1);
|
||||
registerStepFunction("step//input.js//wflow/_anonymousStep2", wflow$_anonymousStep2);
|
||||
registerStepFunction("step//input.js//wflow/_anonymousStep3", wflow$_anonymousStep3);
|
||||
registerStepFunction("step//input.js//wflow/_anonymousStep4", wflow$_anonymousStep4);
|
||||
|
||||
+72
-4
@@ -1,20 +1,88 @@
|
||||
import { DurableAgent } from '@workflow/ai/agent';
|
||||
/**__internal_workflows{"workflows":{"input.js":{"wflow":{"workflowId":"workflow//input.js//wflow"}}},"steps":{"input.js":{"_anonymousStep0":{"stepId":"step//input.js//_anonymousStep0"},"_anonymousStep1":{"stepId":"step//input.js//_anonymousStep1"},"_anonymousStep2":{"stepId":"step//input.js//_anonymousStep2"},"namedStepWithClosureVars":{"stepId":"step//input.js//namedStepWithClosureVars"}}}}*/;
|
||||
/**__internal_workflows{"workflows":{"input.js":{"wflow":{"workflowId":"workflow//input.js//wflow"}}},"steps":{"input.js":{"_anonymousStep0":{"stepId":"step//input.js//_anonymousStep0"},"_anonymousStep1":{"stepId":"step//input.js//_anonymousStep1"},"_anonymousStep2":{"stepId":"step//input.js//_anonymousStep2"},"_anonymousStep3":{"stepId":"step//input.js//_anonymousStep3"},"_anonymousStep4":{"stepId":"step//input.js//_anonymousStep4"},"f":{"stepId":"step//input.js//f"},"fn":{"stepId":"step//input.js//fn"},"namedStepWithClosureVars":{"stepId":"step//input.js//namedStepWithClosureVars"}}}}*/;
|
||||
function stepWrapperReturnArrowFunctionVar(a, b, c) {
|
||||
const fn = globalThis[Symbol.for("WORKFLOW_USE_STEP")]("step//input.js//fn", ()=>({
|
||||
a,
|
||||
b,
|
||||
c
|
||||
}));
|
||||
return fn;
|
||||
}
|
||||
function stepWrapperReturnNamedFunction(a, b, c) {
|
||||
return globalThis[Symbol.for("WORKFLOW_USE_STEP")]("step//input.js//f", ()=>({
|
||||
a,
|
||||
b,
|
||||
c
|
||||
}));
|
||||
}
|
||||
function stepWrapperReturnArrowFunction(a, b, c) {
|
||||
return globalThis[Symbol.for("WORKFLOW_USE_STEP")]("step//input.js//_anonymousStep0", ()=>({
|
||||
a,
|
||||
b,
|
||||
c
|
||||
}));
|
||||
}
|
||||
function stepWrapperReturnNamedFunctionVar(a, b, c) {
|
||||
var fn = globalThis[Symbol.for("WORKFLOW_USE_STEP")]("step//input.js//fn", ()=>({
|
||||
a,
|
||||
b,
|
||||
c
|
||||
}));
|
||||
return fn;
|
||||
}
|
||||
const arrowWrapperReturnArrowFunctionVar = (a, b, c)=>{
|
||||
const fn = globalThis[Symbol.for("WORKFLOW_USE_STEP")]("step//input.js//fn", ()=>({
|
||||
a,
|
||||
b,
|
||||
c
|
||||
}));
|
||||
return fn;
|
||||
};
|
||||
const arrowWrapperReturnNamedFunction = (a, b, c)=>{
|
||||
return globalThis[Symbol.for("WORKFLOW_USE_STEP")]("step//input.js//f", ()=>({
|
||||
a,
|
||||
b,
|
||||
c
|
||||
}));
|
||||
};
|
||||
const arrowWrapperReturnArrowFunction = (a, b, c)=>{
|
||||
return globalThis[Symbol.for("WORKFLOW_USE_STEP")]("step//input.js//_anonymousStep1", ()=>({
|
||||
a,
|
||||
b,
|
||||
c
|
||||
}));
|
||||
};
|
||||
const arrowWrapperReturnNamedFunctionVar = (a, b, c)=>{
|
||||
var fn = globalThis[Symbol.for("WORKFLOW_USE_STEP")]("step//input.js//fn", ()=>({
|
||||
a,
|
||||
b,
|
||||
c
|
||||
}));
|
||||
return fn;
|
||||
};
|
||||
export async function wflow() {
|
||||
let count = 42;
|
||||
var namedStepWithClosureVars = globalThis[Symbol.for("WORKFLOW_USE_STEP")]("step//input.js//wflow/namedStepWithClosureVars", ()=>({
|
||||
count
|
||||
}));
|
||||
const agent = new DurableAgent({
|
||||
arrowFunctionWithClosureVars: globalThis[Symbol.for("WORKFLOW_USE_STEP")]("step//input.js//wflow/_anonymousStep0", ()=>({
|
||||
arrowFunctionWithClosureVars: globalThis[Symbol.for("WORKFLOW_USE_STEP")]("step//input.js//wflow/_anonymousStep2", ()=>({
|
||||
count
|
||||
})),
|
||||
namedFunctionWithClosureVars: globalThis[Symbol.for("WORKFLOW_USE_STEP")]("step//input.js//wflow/_anonymousStep1", ()=>({
|
||||
namedFunctionWithClosureVars: globalThis[Symbol.for("WORKFLOW_USE_STEP")]("step//input.js//wflow/_anonymousStep3", ()=>({
|
||||
count
|
||||
})),
|
||||
methodWithClosureVars: globalThis[Symbol.for("WORKFLOW_USE_STEP")]("step//input.js//wflow/_anonymousStep2", ()=>({
|
||||
methodWithClosureVars: globalThis[Symbol.for("WORKFLOW_USE_STEP")]("step//input.js//wflow/_anonymousStep4", ()=>({
|
||||
count
|
||||
}))
|
||||
});
|
||||
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)();
|
||||
}
|
||||
wflow.workflowId = "workflow//input.js//wflow";
|
||||
|
||||
Reference in New Issue
Block a user