Inline all SWC plugin step registrations, remove workflow/internal/private#1632
Inline all SWC plugin step registrations, remove workflow/internal/private#1632TooTallNate merged 5 commits intomainfrom
Conversation
…/private
The SWC compiler plugin no longer generates import statements. All step
function registrations and closure variable access are now self-contained
inline IIFEs with zero module dependencies:
- Step registration uses an IIFE that writes to
globalThis[Symbol.for('@workflow/core//registeredSteps')]
- Closure variable access uses an IIFE that reads from
globalThis[Symbol.for('WORKFLOW_STEP_CONTEXT_STORAGE')]
- Registrations are placed immediately after each function definition
instead of being batched at the bottom of the file
This enables 3rd-party node_modules packages to define step functions
without needing the 'workflow' package available at runtime.
Also removes the @workflow/core/private and workflow/internal/private
public subpath exports since they are no longer referenced by generated
code.
🦋 Changeset detectedLatest commit: 0fb7721 The changes in this PR will be included in the next version bump. This PR includes changesets to release 17 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 |
📊 Benchmark Results
workflow with no steps💻 Local Development
▲ Production (Vercel)
🔍 Observability: Nitro | Express | Next.js (Turbopack) workflow with 1 step💻 Local Development
▲ Production (Vercel)
🔍 Observability: Nitro | Next.js (Turbopack) | Express workflow with 10 sequential steps💻 Local Development
▲ Production (Vercel)
🔍 Observability: Nitro | Express | Next.js (Turbopack) workflow with 25 sequential steps💻 Local Development
▲ Production (Vercel)
🔍 Observability: Nitro | Express | Next.js (Turbopack) workflow with 50 sequential steps💻 Local Development
▲ Production (Vercel)
🔍 Observability: Nitro | Express | Next.js (Turbopack) Promise.all with 10 concurrent steps💻 Local Development
▲ Production (Vercel)
🔍 Observability: Nitro | Express | Next.js (Turbopack) Promise.all with 25 concurrent steps💻 Local Development
▲ Production (Vercel)
🔍 Observability: Nitro | Express | Next.js (Turbopack) Promise.all with 50 concurrent steps💻 Local Development
▲ Production (Vercel)
🔍 Observability: Express | Next.js (Turbopack) | Nitro Promise.race with 10 concurrent steps💻 Local Development
▲ Production (Vercel)
🔍 Observability: Nitro | Express | Next.js (Turbopack) Promise.race with 25 concurrent steps💻 Local Development
▲ Production (Vercel)
🔍 Observability: Nitro | Express | Next.js (Turbopack) Promise.race with 50 concurrent steps💻 Local Development
▲ Production (Vercel)
🔍 Observability: Nitro | Express | Next.js (Turbopack) workflow with 10 sequential data payload steps (10KB)💻 Local Development
▲ Production (Vercel)
🔍 Observability: Next.js (Turbopack) | Nitro | Express workflow with 25 sequential data payload steps (10KB)💻 Local Development
▲ Production (Vercel)
🔍 Observability: Nitro | Next.js (Turbopack) | Express workflow with 50 sequential data payload steps (10KB)💻 Local Development
▲ Production (Vercel)
🔍 Observability: Express | Nitro | Next.js (Turbopack) workflow with 10 concurrent data payload steps (10KB)💻 Local Development
▲ Production (Vercel)
🔍 Observability: Nitro | Express | Next.js (Turbopack) workflow with 25 concurrent data payload steps (10KB)💻 Local Development
▲ Production (Vercel)
🔍 Observability: Express | Nitro | Next.js (Turbopack) workflow with 50 concurrent data payload steps (10KB)💻 Local Development
▲ Production (Vercel)
🔍 Observability: Nitro | Next.js (Turbopack) | Express Stream Benchmarks (includes TTFB metrics)workflow with stream💻 Local Development
▲ Production (Vercel)
🔍 Observability: Express | Nitro | Next.js (Turbopack) stream pipeline with 5 transform steps (1MB)💻 Local Development
▲ Production (Vercel)
🔍 Observability: Next.js (Turbopack) | Nitro | Express 10 parallel streams (1MB each)💻 Local Development
▲ Production (Vercel)
🔍 Observability: Express | Nitro | Next.js (Turbopack) fan-out fan-in 10 streams (1MB each)💻 Local Development
▲ Production (Vercel)
🔍 Observability: Nitro | Express | Next.js (Turbopack) SummaryFastest Framework by WorldWinner determined by most benchmark wins
Fastest World by FrameworkWinner determined by most benchmark wins
Column Definitions
Worlds:
Check the workflow run for details. |
🧪 E2E Test Results❌ Some tests failed Summary
❌ Failed Tests🌍 Community Worlds (65 failed)mongodb (4 failed):
redis (3 failed):
turso (58 failed):
Details by Category✅ ▲ Vercel Production
✅ 💻 Local Development
✅ 📦 Local Production
✅ 🐘 Local Postgres
✅ 🪟 Windows
❌ 🌍 Community Worlds
✅ 📋 Other
|
There was a problem hiding this comment.
Pull request overview
This PR updates the SWC workflow transform to inline step registrations and closure-var access so transformed step bundles have zero runtime module imports, enabling 3rd-party packages to define step functions without requiring workflow to be installed at runtime. It also removes now-unneeded public subpath exports and updates docs/tests/fixtures accordingly.
Changes:
- Inline step registrations as self-contained IIFEs writing to
globalThis[Symbol.for("@workflow/core//registeredSteps")](step mode) and inline closure-var access viaSymbol.for("WORKFLOW_STEP_CONTEXT_STORAGE"). - Remove
@workflow/core/privateandworkflow/internal/privateexports/re-exports; update internal tests/imports and docs/spec examples. - Refresh SWC fixture outputs and e2e stack-trace assertions to match new emitted code patterns.
Reviewed changes
Copilot reviewed 52 out of 52 changed files in this pull request and generated 7 comments.
Show a summary per file
| File | Description |
|---|---|
| packages/workflow/src/internal/private.ts | Removes the workflow/internal/private re-export shim. |
| packages/workflow/package.json | Drops the ./internal/private export entry. |
| packages/swc-plugin-workflow/transform/tests/fixture/var-named-step-function/output-step.js | Updates expected output to inline registration IIFEs. |
| packages/swc-plugin-workflow/transform/tests/fixture/using-declaration-step/output-step.js | Updates expected output to inline registration IIFEs. |
| packages/swc-plugin-workflow/transform/tests/fixture/unused-variables-and-types/output-step.js | Updates expected output to inline registration IIFEs. |
| packages/swc-plugin-workflow/transform/tests/fixture/unused-exports/output-step.js | Updates expected output to inline registration IIFEs. |
| packages/swc-plugin-workflow/transform/tests/fixture/step-with-this-arguments-super/output-step.js | Updates expected output to inline registration IIFEs for functions/methods. |
| packages/swc-plugin-workflow/transform/tests/fixture/step-with-imports/output-step.js | Updates expected output to inline registration IIFEs. |
| packages/swc-plugin-workflow/transform/tests/fixture/step-arrow-function/output-step.js | Updates expected output to inline registration IIFEs. |
| packages/swc-plugin-workflow/transform/tests/fixture/static-method-step/output-step.js | Updates expected output to inline registration IIFEs for static methods. |
| packages/swc-plugin-workflow/transform/tests/fixture/single-step/output-step.js | Updates expected output to inline registration IIFEs. |
| packages/swc-plugin-workflow/transform/tests/fixture/separate-export-statement/output-step.js | Updates expected output to inline registration IIFEs. |
| packages/swc-plugin-workflow/transform/tests/fixture/object-property-step/output-step.js | Updates expected output to inline registration IIFEs for hoisted object-property steps. |
| packages/swc-plugin-workflow/transform/tests/fixture/object-property-step/output-client.js | Moves stepId assignments to match new placement rules. |
| packages/swc-plugin-workflow/transform/tests/fixture/nested-steps-in-object-constructor/output-step.js | Updates expected output to inline registration IIFEs for nested steps. |
| packages/swc-plugin-workflow/transform/tests/fixture/nested-step-with-closure/output-step.js | Updates expected output to inline registration IIFEs + inlined closure-var access. |
| packages/swc-plugin-workflow/transform/tests/fixture/nested-step-in-workflow/output-step.js | Updates expected output to inline registration IIFEs for workflow-nested steps. |
| packages/swc-plugin-workflow/transform/tests/fixture/multiple-const-step-functions/output-step.js | Updates expected output to inline registration IIFEs for multi-declarator var statements. |
| packages/swc-plugin-workflow/transform/tests/fixture/module-level-step/output-step.js | Updates expected output to inline registration IIFEs. |
| packages/swc-plugin-workflow/transform/tests/fixture/mixed-functions/output-step.js | Updates expected output to inline registration IIFEs. |
| packages/swc-plugin-workflow/transform/tests/fixture/let-arrow-step-function/output-step.js | Updates expected output to inline registration IIFEs. |
| packages/swc-plugin-workflow/transform/tests/fixture/instance-method-step/output-step.js | Updates expected output to inline registration IIFEs for instance methods. |
| packages/swc-plugin-workflow/transform/tests/fixture/instance-method-nested-step/output-step.js | Updates expected output to inline registration IIFEs for helper + instance method. |
| packages/swc-plugin-workflow/transform/tests/fixture/factory-with-step-method/output-step.js | Updates expected output to inline registration IIFEs for factory step method. |
| packages/swc-plugin-workflow/transform/tests/fixture/factory-with-step-method/output-client.js | Moves stepId assignment to match new placement rules. |
| packages/swc-plugin-workflow/transform/tests/fixture/export-default-class-named/output-step.js | Updates expected output to inline registration IIFEs for default-export class method. |
| packages/swc-plugin-workflow/transform/tests/fixture/export-default-class-anonymous/output-step.js | Updates expected output to inline registration IIFEs for rewritten default class binding. |
| packages/swc-plugin-workflow/transform/tests/fixture/export-default-class-anonymous-step-only/output-step.js | Updates expected output to inline registration IIFEs for rewritten default class binding. |
| packages/swc-plugin-workflow/transform/tests/fixture/destructuring/output-step.js | Updates expected output to inline registration IIFEs. |
| packages/swc-plugin-workflow/transform/tests/fixture/deeply-nested-step/output-step.js | Updates expected output to inline registration IIFEs. |
| packages/swc-plugin-workflow/transform/tests/fixture/deeply-nested-step/output-client.js | Moves stepId assignment to match new placement rules. |
| packages/swc-plugin-workflow/transform/tests/fixture/closure-typescript-expressions/output-step.js | Updates expected output to inline registration + inlined closure-var access. |
| packages/swc-plugin-workflow/transform/tests/fixture/closure-new-expr-and-module-declarations/output-step.js | Updates expected output to inline registration + inlined closure-var access. |
| packages/swc-plugin-workflow/transform/tests/fixture/class-expression-binding-name-step-methods/output-step.js | Updates expected output to inline registration IIFEs for binding-name class expr methods. |
| packages/swc-plugin-workflow/transform/tests/fixture/agent-with-tool-step/output-step.js | Updates expected output to inline registration IIFEs for tool execute steps. |
| packages/swc-plugin-workflow/transform/tests/fixture/agent-with-tool-step/output-client.js | Moves stepId assignment to match new placement rules. |
| packages/swc-plugin-workflow/transform/tests/fixture/agent-with-tool-step-shorthand-method/output-step.js | Updates expected output to inline registration IIFEs for shorthand methods. |
| packages/swc-plugin-workflow/transform/tests/fixture/agent-with-tool-step-shorthand-method/output-client.js | Moves stepId assignment to match new placement rules. |
| packages/swc-plugin-workflow/transform/tests/errors/non-async-functions/output-step.js | Updates expected error fixture output to inline registration IIFEs. |
| packages/swc-plugin-workflow/transform/tests/errors/misplaced-function-directive/output-step.js | Updates expected error fixture output to inline registration IIFEs. |
| packages/swc-plugin-workflow/transform/tests/errors/invalid-exports/output-step.js | Updates expected error fixture output to inline registration IIFEs. |
| packages/swc-plugin-workflow/transform/tests/errors/instance-methods/output-step.js | Updates expected error fixture output to inline registration IIFEs for methods. |
| packages/swc-plugin-workflow/transform/tests/errors/conflicting-directives/output-step.js | Updates expected error fixture output to inline registration IIFEs. |
| packages/swc-plugin-workflow/transform/src/lib.rs | Implements inline step registration + inline closure-var accessor; removes private imports/registration batching. |
| packages/swc-plugin-workflow/spec.md | Updates spec examples and narrative to describe new inline IIFE patterns. |
| packages/core/src/serialization.test.ts | Updates internal test to import closure-var helper from its direct module. |
| packages/core/src/private.ts | Documents new inline registration approach; stops re-exporting __private_getClosureVars. |
| packages/core/package.json | Removes ./private export. |
| packages/core/e2e/e2e.test.ts | Updates stack-trace assertions to stop referencing registerStepFunction. |
| docs/content/docs/how-it-works/code-transform.mdx | Updates docs example to show inline IIFE registration output. |
| .changeset/remove-private-subpath.md | Adds changeset for removing private subpath exports. |
| .changeset/inline-step-registration.md | Adds changeset for SWC plugin output change to inline IIFEs. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
…row behavior - Remove stale 'Collect registration calls' comment from StepTransform - Fix 'everyhwere' typo in e2e test comments - Closure vars IIFE now throws when called outside a step function context, matching the original __private_getClosureVars behavior
VaguelySerious
left a comment
There was a problem hiding this comment.
AI review: blocking issues found
packages/swc-plugin-workflow/transform/tests/fixture/instance-getter-step/output-step.js
Outdated
Show resolved
Hide resolved
Address review feedback: - Replace registerStepFunction() calls in getter step registrations with self.create_inline_step_registration() to match the inline IIFE pattern used by all other step registrations (the import was removed by this PR) - Update spec.md closure vars example to include throw guard - Update spec.md getter sections to show inline IIFE pattern instead of registerStepFunction
Summary
importstatements. All step function registrations and closure variable access are now self-contained inline IIFEs with zero module dependencies.globalThis[Symbol.for("@workflow/core//registeredSteps")], matching the pattern already used for class serialization registration.globalThis[Symbol.for("WORKFLOW_STEP_CONTEXT_STORAGE")], eliminating the__private_getClosureVarsimport.@workflow/core/privateandworkflow/internal/privatepublic subpath exports since they are no longer referenced by generated code.Motivation
The previous
import { registerStepFunction } from "workflow/internal/private"pattern was problematic for 3rd-partynode_modulespackages that define step functions but don't have theworkflowpackage available at runtime. By inlining all registrations as self-contained IIFEs (the same pattern already used for class serialization), the transformed code has zero module dependencies.Changed packages
@workflow/swc-plugin— Rust transform: replacedcreate_private_imports()withcreate_inline_step_registration()andcreate_inline_get_closure_vars()IIFEs; moved registration placement from end-of-file to immediately after each function definition; removedregistration_callsfield@workflow/core— Removed./privatefrom package.json exports; updated serialization test to import__private_getClosureVarsdirectlyworkflow— Removed./internal/privatefrom package.json exports; deletedsrc/internal/private.tsre-export filecode-transform.mdxwith new inline IIFE examplespec.mdwith all new code patternsregisterStepFunction)Test plan
@workflow/coreunit tests pass@workflow/builderstests passUPDATE=1 cargo test