From 1502135eb4b7a9fca2ddaa4ef8d80b61b7044fa5 Mon Sep 17 00:00:00 2001 From: Nathan Rajlich Date: Tue, 18 Nov 2025 00:37:32 -0800 Subject: [PATCH 1/2] WIP factory-with-step-method fixture --- .../tests/fixture/factory-with-step-method/input.js | 11 +++++++++++ .../fixture/factory-with-step-method/output-client.js | 8 ++++++++ .../fixture/factory-with-step-method/output-step.js | 8 ++++++++ .../factory-with-step-method/output-workflow.js | 8 ++++++++ 4 files changed, 35 insertions(+) create mode 100644 packages/swc-plugin-workflow/transform/tests/fixture/factory-with-step-method/input.js create mode 100644 packages/swc-plugin-workflow/transform/tests/fixture/factory-with-step-method/output-client.js create mode 100644 packages/swc-plugin-workflow/transform/tests/fixture/factory-with-step-method/output-step.js create mode 100644 packages/swc-plugin-workflow/transform/tests/fixture/factory-with-step-method/output-workflow.js diff --git a/packages/swc-plugin-workflow/transform/tests/fixture/factory-with-step-method/input.js b/packages/swc-plugin-workflow/transform/tests/fixture/factory-with-step-method/input.js new file mode 100644 index 000000000..6032e01ea --- /dev/null +++ b/packages/swc-plugin-workflow/transform/tests/fixture/factory-with-step-method/input.js @@ -0,0 +1,11 @@ +import fs from 'fs/promises'; + +const myFactory = () => ({ + myStep: async () => { + 'use step'; + await fs.mkdir('test'); + }, +}); + +export default myFactory; + diff --git a/packages/swc-plugin-workflow/transform/tests/fixture/factory-with-step-method/output-client.js b/packages/swc-plugin-workflow/transform/tests/fixture/factory-with-step-method/output-client.js new file mode 100644 index 000000000..f81b10cce --- /dev/null +++ b/packages/swc-plugin-workflow/transform/tests/fixture/factory-with-step-method/output-client.js @@ -0,0 +1,8 @@ +import fs from 'fs/promises'; +const myFactory = ()=>({ + myStep: async ()=>{ + 'use step'; + await fs.mkdir('test'); + } + }); +export default myFactory; diff --git a/packages/swc-plugin-workflow/transform/tests/fixture/factory-with-step-method/output-step.js b/packages/swc-plugin-workflow/transform/tests/fixture/factory-with-step-method/output-step.js new file mode 100644 index 000000000..f81b10cce --- /dev/null +++ b/packages/swc-plugin-workflow/transform/tests/fixture/factory-with-step-method/output-step.js @@ -0,0 +1,8 @@ +import fs from 'fs/promises'; +const myFactory = ()=>({ + myStep: async ()=>{ + 'use step'; + await fs.mkdir('test'); + } + }); +export default myFactory; diff --git a/packages/swc-plugin-workflow/transform/tests/fixture/factory-with-step-method/output-workflow.js b/packages/swc-plugin-workflow/transform/tests/fixture/factory-with-step-method/output-workflow.js new file mode 100644 index 000000000..f81b10cce --- /dev/null +++ b/packages/swc-plugin-workflow/transform/tests/fixture/factory-with-step-method/output-workflow.js @@ -0,0 +1,8 @@ +import fs from 'fs/promises'; +const myFactory = ()=>({ + myStep: async ()=>{ + 'use step'; + await fs.mkdir('test'); + } + }); +export default myFactory; From 40ab7685152003ba12bdf2a0e7f5f7d6bb540822 Mon Sep 17 00:00:00 2001 From: Nathan Rajlich Date: Tue, 18 Nov 2025 12:28:45 -0800 Subject: [PATCH 2/2] Apply SWC transformation on step functions returned from factory function --- .changeset/metal-cycles-slide.md | 5 +++ .../swc-plugin-workflow/transform/src/lib.rs | 35 ++++++++++++++++++- .../factory-with-step-method/output-client.js | 1 - .../factory-with-step-method/output-step.js | 11 +++--- .../output-workflow.js | 7 ++-- 5 files changed, 48 insertions(+), 11 deletions(-) create mode 100644 .changeset/metal-cycles-slide.md diff --git a/.changeset/metal-cycles-slide.md b/.changeset/metal-cycles-slide.md new file mode 100644 index 000000000..d6e090e78 --- /dev/null +++ b/.changeset/metal-cycles-slide.md @@ -0,0 +1,5 @@ +--- +"@workflow/swc-plugin": patch +--- + +Apply SWC transformation on step functions returned from factory function diff --git a/packages/swc-plugin-workflow/transform/src/lib.rs b/packages/swc-plugin-workflow/transform/src/lib.rs index 5f7ac2a0d..f5785d570 100644 --- a/packages/swc-plugin-workflow/transform/src/lib.rs +++ b/packages/swc-plugin-workflow/transform/src/lib.rs @@ -864,7 +864,40 @@ impl StepTransform { stmt.visit_mut_children_with(self); } } - Stmt::Decl(Decl::Var(_)) => { + Stmt::Decl(Decl::Var(var_decl)) => { + // Check if any declarators contain arrow functions with object literal bodies + for declarator in &mut var_decl.decls { + 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 { + BlockStmtOrExpr::Expr(expr) => { + // Handle both direct object literals and parenthesized ones + let obj_lit_mut = match &mut **expr { + Expr::Object(obj) => Some(obj), + Expr::Paren(paren) => { + if let Expr::Object(obj) = &mut *paren.expr { + Some(obj) + } else { + None + } + } + _ => None, + }; + + if let Some(obj_lit) = obj_lit_mut { + self.process_object_properties_for_step_functions(obj_lit, &name); + } + } + _ => {} + } + } + } + } + } stmt.visit_mut_children_with(self); } _ => { diff --git a/packages/swc-plugin-workflow/transform/tests/fixture/factory-with-step-method/output-client.js b/packages/swc-plugin-workflow/transform/tests/fixture/factory-with-step-method/output-client.js index f81b10cce..9bbd17614 100644 --- a/packages/swc-plugin-workflow/transform/tests/fixture/factory-with-step-method/output-client.js +++ b/packages/swc-plugin-workflow/transform/tests/fixture/factory-with-step-method/output-client.js @@ -1,7 +1,6 @@ import fs from 'fs/promises'; const myFactory = ()=>({ myStep: async ()=>{ - 'use step'; await fs.mkdir('test'); } }); diff --git a/packages/swc-plugin-workflow/transform/tests/fixture/factory-with-step-method/output-step.js b/packages/swc-plugin-workflow/transform/tests/fixture/factory-with-step-method/output-step.js index f81b10cce..f80c440c8 100644 --- a/packages/swc-plugin-workflow/transform/tests/fixture/factory-with-step-method/output-step.js +++ b/packages/swc-plugin-workflow/transform/tests/fixture/factory-with-step-method/output-step.js @@ -1,8 +1,11 @@ +import { registerStepFunction } from "workflow/internal/private"; import fs from 'fs/promises'; +/**__internal_workflows{"steps":{"input.js":{"myFactory/myStep":{"stepId":"step//input.js//myFactory/myStep"}}}}*/; +var myFactory$myStep = async ()=>{ + await fs.mkdir('test'); +}; const myFactory = ()=>({ - myStep: async ()=>{ - 'use step'; - await fs.mkdir('test'); - } + myStep: myFactory$myStep }); export default myFactory; +registerStepFunction("step//input.js//myFactory/myStep", myFactory$myStep); diff --git a/packages/swc-plugin-workflow/transform/tests/fixture/factory-with-step-method/output-workflow.js b/packages/swc-plugin-workflow/transform/tests/fixture/factory-with-step-method/output-workflow.js index f81b10cce..08caf239b 100644 --- a/packages/swc-plugin-workflow/transform/tests/fixture/factory-with-step-method/output-workflow.js +++ b/packages/swc-plugin-workflow/transform/tests/fixture/factory-with-step-method/output-workflow.js @@ -1,8 +1,5 @@ -import fs from 'fs/promises'; +/**__internal_workflows{"steps":{"input.js":{"myFactory/myStep":{"stepId":"step//input.js//myFactory/myStep"}}}}*/; const myFactory = ()=>({ - myStep: async ()=>{ - 'use step'; - await fs.mkdir('test'); - } + myStep: globalThis[Symbol.for("WORKFLOW_USE_STEP")]("step//input.js//myFactory/myStep") }); export default myFactory;