Add support for "use step" functions in class instance methods#777
Conversation
🦋 Changeset detectedLatest commit: 16dd859 The changes in this PR will be included in the next version bump. This PR includes changesets to release 16 packages
Not sure what this means? Click here to learn what changesets are. Click here if you're a maintainer who wants to add another changeset to this PR |
🧪 E2E Test Results❌ Some tests failed Summary
❌ Failed Tests🌍 Community Worlds (169 failed)mongodb (42 failed):
redis (42 failed):
starter (43 failed):
turso (42 failed):
Details by Category✅ ▲ Vercel Production
✅ 💻 Local Development
✅ 📦 Local Production
✅ 🐘 Local Postgres
✅ 🪟 Windows
❌ 🌍 Community Worlds
✅ 📋 Other
|
This stack of pull requests is managed by Graphite. Learn more about stacking. |
2809f4c to
d9a2fca
Compare
84dfb97 to
90402ec
Compare
3fede27 to
96e1c18
Compare
4510234 to
14dfe20
Compare
📊 Benchmark Results
workflow with no steps💻 Local Development
▲ Production (Vercel)
🔍 Observability: Express workflow with 1 step💻 Local Development
▲ Production (Vercel)
🔍 Observability: Express workflow with 10 sequential steps💻 Local Development
▲ Production (Vercel)
🔍 Observability: Express Promise.all with 10 concurrent steps💻 Local Development
▲ Production (Vercel)
🔍 Observability: Express Promise.all with 25 concurrent steps💻 Local Development
▲ Production (Vercel)
🔍 Observability: Express Promise.race with 10 concurrent steps💻 Local Development
▲ Production (Vercel)
🔍 Observability: Express Promise.race with 25 concurrent steps💻 Local Development
▲ Production (Vercel)
🔍 Observability: Express Stream Benchmarks (includes TTFB metrics)workflow with stream💻 Local Development
▲ Production (Vercel)
🔍 Observability: Express SummaryFastest Framework by WorldWinner determined by most benchmark wins
Fastest World by FrameworkWinner determined by most benchmark wins
Column Definitions
Worlds:
|
There was a problem hiding this comment.
Pull request overview
Adds SWC transform + runtime support so class instance methods can be marked with "use step" and invoked as workflow steps while preserving this via serialization.
Changes:
- Update SWC transform to detect
"use step"in instance methods, generateClassName.prototype.methodNamestep registrations, and proxy instance methods in workflow bundles. - Register serialization classes so
thisvalues can be dehydrated/hydrated across workflow ↔ step boundaries. - Add end-to-end coverage plus transform fixtures for instance-method steps (including nested steps), and adjust error fixtures.
Reviewed changes
Copilot reviewed 23 out of 23 changed files in this pull request and generated 7 comments.
Show a summary per file
| File | Description |
|---|---|
| workbench/example/workflows/99_e2e.ts | Adds Counter + instanceMethodStepWorkflow e2e workflow demonstrating instance-method steps with custom serialization. |
| packages/core/e2e/e2e.test.ts | Adds e2e test validating instance-method step execution + step list expectations. |
| packages/swc-plugin-workflow/transform/src/lib.rs | Core transform changes: allow "use step" on instance methods, register prototype step functions, and proxy them in workflow mode. |
| packages/swc-plugin-workflow/transform/tests/fixture/instance-method-step/input.js | New fixture input for instance-method step transformation. |
| packages/swc-plugin-workflow/transform/tests/fixture/instance-method-step/output-client.js | Expected client output for instance-method step fixture. |
| packages/swc-plugin-workflow/transform/tests/fixture/instance-method-step/output-step.js | Expected step-bundle output for instance-method step fixture. |
| packages/swc-plugin-workflow/transform/tests/fixture/instance-method-step/output-workflow.js | Expected workflow-bundle output for instance-method step fixture. |
| packages/swc-plugin-workflow/transform/tests/fixture/instance-method-nested-step/input.js | New fixture input for nested steps inside an instance-method step. |
| packages/swc-plugin-workflow/transform/tests/fixture/instance-method-nested-step/output-client.js | Expected client output for nested instance-method step fixture. |
| packages/swc-plugin-workflow/transform/tests/fixture/instance-method-nested-step/output-step.js | Expected step-bundle output for nested instance-method step fixture. |
| packages/swc-plugin-workflow/transform/tests/fixture/instance-method-nested-step/output-workflow.js | Expected workflow-bundle output for nested instance-method step fixture. |
| packages/swc-plugin-workflow/transform/tests/errors/instance-methods/input.js | Updates error fixture to allow "use step" on instance methods but still forbid "use workflow". |
| packages/swc-plugin-workflow/transform/tests/errors/instance-methods/output-client.js | Expected client output for updated instance-method error fixture. |
| packages/swc-plugin-workflow/transform/tests/errors/instance-methods/output-client.stderr | Updated expected stderr for client mode. |
| packages/swc-plugin-workflow/transform/tests/errors/instance-methods/output-step.js | Expected step output for updated instance-method error fixture. |
| packages/swc-plugin-workflow/transform/tests/errors/instance-methods/output-step.stderr | Updated expected stderr for step mode. |
| packages/swc-plugin-workflow/transform/tests/errors/instance-methods/output-workflow.js | Expected workflow output for updated instance-method error fixture. |
| packages/swc-plugin-workflow/transform/tests/errors/instance-methods/output-workflow.stderr | Updated expected stderr for workflow mode. |
| packages/swc-plugin-workflow/transform/tests/errors/forbidden-expressions/output-step.js | Updates expected output to treat instance method step as supported. |
| packages/swc-plugin-workflow/transform/tests/errors/forbidden-expressions/output-step.stderr | Adjusted expected stderr (now empty). |
| packages/swc-plugin-workflow/transform/tests/errors/forbidden-expressions/output-workflow.js | Updates expected output to proxy/register the instance method step. |
| packages/swc-plugin-workflow/transform/tests/errors/forbidden-expressions/output-workflow.stderr | Adjusted expected stderr (now empty). |
| .changeset/legal-parts-happen.md | Publishes a patch changeset for @workflow/swc-plugin. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| class_decl.class.body.retain(|member| { | ||
| if let ClassMember::Method(method) = member { | ||
| if method.is_static { | ||
| if let PropName::Ident(ident) = &method.key { | ||
| let method_name = ident.sym.to_string(); | ||
| return !methods_to_strip.contains(&method_name); | ||
| if let PropName::Ident(ident) = &method.key { | ||
| let method_name = ident.sym.to_string(); | ||
| if method.is_static { | ||
| return !static_methods_to_strip.contains(&method_name); | ||
| } else { | ||
| return !instance_methods_to_strip.contains(&method_name); | ||
| } | ||
| } |
There was a problem hiding this comment.
The workflow-mode stripping logic only checks PropName::Ident for class methods. Instance (and static) methods with string keys (e.g. async 'foo-bar'() { 'use step' }) are supported earlier, but won’t be removed here, so the original method body can remain in the workflow bundle instead of being replaced by the step proxy. Extend this retain() filter to also handle PropName::Str (and keep the stripping key representation consistent with how method_name is collected).
| const helper = helper; | ||
| const doubled = await helper(input); |
There was a problem hiding this comment.
Callee is not a function: it has type undefined.
| const helper = helper; | |
| const doubled = await helper(input); | |
| const localHelper = helper; | |
| const doubled = await localHelper(input); |
| @@ -1,10 +0,0 @@ | |||
| x Instance methods cannot be marked with "use step". Only static methods, functions, and object methods are supported. | |||
There was a problem hiding this comment.
Should these .stderr files be deleted then?

Added support for
"use step"directive in class instance methods, allowing instance methods to be used as workflow steps.What changed?
ClassName.prototype.methodNamethiscontext across workflow/step boundariesHow to test?
The PR includes a new end-to-end test
instanceMethodStepWorkflowthat demonstrates the functionality:Counterclass with instance methods marked as stepsthiscontextWhy make this change?
This change enables a more natural object-oriented programming model when working with workflows. Previously, only static methods, standalone functions, and object methods could be marked as steps. Now, developers can create classes with instance methods that are steps, allowing for better encapsulation and more intuitive code organization. This is particularly useful for complex workflows that need to maintain state across multiple step invocations.