Followup fixes for sync step function support#1664
Conversation
Address review feedback from #1633 (merged): - Remove dangling incomplete comment from validate_async_function removal - Restore export validation for file-level 'use step' files: allow sync/async function exports, reject non-function exports (constants, classes, re-exports) which can pull Node-only code into bundles - Fix InvalidExport error message: 'Only functions can be exported' for step files vs 'Only async functions can be exported' for workflow - Update spec.md error table and supported function forms to document sync step support - Add sync-step-class test fixture (sync static methods, sync function expressions with var/let) - Add sync-workflow error test (sync workflow still errors)
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
🧪 E2E Test Results❌ Some tests failed Summary
❌ Failed Tests🌍 Community Worlds (64 failed)mongodb (3 failed):
redis (3 failed):
turso (58 failed):
Details by Category✅ ▲ Vercel Production
✅ 💻 Local Development
✅ 📦 Local Production
✅ 🐘 Local Postgres
✅ 🪟 Windows
❌ 🌍 Community Worlds
✅ 📋 Other
|
🦋 Changeset detectedLatest commit: 02d6d56 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: Express | Nitro | Next.js (Turbopack) workflow with 1 step💻 Local Development
▲ Production (Vercel)
🔍 Observability: Express | Nitro | Next.js (Turbopack) workflow with 10 sequential steps💻 Local Development
▲ Production (Vercel)
🔍 Observability: Express | Nitro | Next.js (Turbopack) workflow with 25 sequential steps💻 Local Development
▲ Production (Vercel)
🔍 Observability: Express | Next.js (Turbopack) | Nitro workflow with 50 sequential steps💻 Local Development
▲ Production (Vercel)
🔍 Observability: Express | Nitro | Next.js (Turbopack) Promise.all with 10 concurrent steps💻 Local Development
▲ Production (Vercel)
🔍 Observability: Next.js (Turbopack) | Express | Nitro Promise.all with 25 concurrent steps💻 Local Development
▲ Production (Vercel)
🔍 Observability: Express | Nitro | Next.js (Turbopack) Promise.all with 50 concurrent steps💻 Local Development
▲ Production (Vercel)
🔍 Observability: Nitro | Express | Next.js (Turbopack) Promise.race with 10 concurrent steps💻 Local Development
▲ Production (Vercel)
🔍 Observability: Express | Next.js (Turbopack) | Nitro 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: Nitro | Express | Next.js (Turbopack) workflow with 25 sequential data payload steps (10KB)💻 Local Development
▲ Production (Vercel)
🔍 Observability: Express | Next.js (Turbopack) | Nitro workflow with 50 sequential data payload steps (10KB)💻 Local Development
▲ Production (Vercel)
🔍 Observability: Nitro | Next.js (Turbopack) | Express workflow with 10 concurrent data payload steps (10KB)💻 Local Development
▲ Production (Vercel)
🔍 Observability: Express | Nitro | Next.js (Turbopack) workflow with 25 concurrent data payload steps (10KB)💻 Local Development
▲ Production (Vercel)
🔍 Observability: Express | Next.js (Turbopack) | Nitro workflow with 50 concurrent data payload steps (10KB)💻 Local Development
▲ Production (Vercel)
🔍 Observability: Express | Nitro | Next.js (Turbopack) Stream Benchmarks (includes TTFB metrics)workflow with stream💻 Local Development
▲ Production (Vercel)
🔍 Observability: Nitro | Express | 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: Express | Next.js (Turbopack) | Nitro 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
Follow-up fixes to the @workflow/swc-plugin SWC transform to fully support synchronous "use step" functions while preserving "use workflow" async-only behavior, including stricter module-level export validation to prevent Node-only code from leaking into workflow/client bundles.
Changes:
- Restore/extend file-level
"use step"export validation (allow only function exports; reject non-function exports and re-exports) and refineInvalidExportmessaging to distinguish step vs workflow rules. - Add/adjust SWC plugin fixtures to cover sync step usage (including class static methods and
var/letfunction expressions) and to assert sync"use workflow"still errors. - Update
spec.mderror table + supported forms docs, and add a patch changeset for@workflow/swc-plugin.
Reviewed changes
Copilot reviewed 17 out of 17 changed files in this pull request and generated 2 comments.
Show a summary per file
| File | Description |
|---|---|
| packages/swc-plugin-workflow/transform/src/lib.rs | Adjusts InvalidExport messaging and reintroduces file-level "use step" export validation logic. |
| packages/swc-plugin-workflow/spec.md | Documents sync step support and clarifies export restrictions for "use step" vs "use workflow". |
| .changeset/sync-step-followup.md | Publishes the export-validation behavior change as a patch. |
| packages/swc-plugin-workflow/transform/tests/fixture/sync-step-class/input.js | New fixture input covering sync step usage in class + function-expression contexts. |
| packages/swc-plugin-workflow/transform/tests/fixture/sync-step-class/output-workflow.js | Expected workflow-bundle output for the new sync-step-class fixture. |
| packages/swc-plugin-workflow/transform/tests/fixture/sync-step-class/output-step.js | Expected step-bundle output for the new sync-step-class fixture. |
| packages/swc-plugin-workflow/transform/tests/fixture/sync-step-class/output-client.js | Expected client-bundle output for the new sync-step-class fixture. |
| packages/swc-plugin-workflow/transform/tests/errors/sync-workflow/input.js | New error fixture asserting sync "use workflow" errors while sync "use step" passes. |
| packages/swc-plugin-workflow/transform/tests/errors/sync-workflow/output-workflow.js | Expected workflow-mode output for sync-workflow error fixture. |
| packages/swc-plugin-workflow/transform/tests/errors/sync-workflow/output-step.js | Expected step-mode output for sync-workflow error fixture. |
| packages/swc-plugin-workflow/transform/tests/errors/sync-workflow/output-client.js | Expected client-mode output for sync-workflow error fixture. |
| packages/swc-plugin-workflow/transform/tests/errors/sync-workflow/output-workflow.stderr | Expected workflow-mode stderr for sync-workflow error fixture. |
| packages/swc-plugin-workflow/transform/tests/errors/sync-workflow/output-step.stderr | Expected step-mode stderr for sync-workflow error fixture. |
| packages/swc-plugin-workflow/transform/tests/errors/sync-workflow/output-client.stderr | Expected client-mode stderr for sync-workflow error fixture. |
| packages/swc-plugin-workflow/transform/tests/errors/invalid-exports/output-workflow.stderr | Updates/records expected stderr for invalid exports in file-level "use step" files. |
| packages/swc-plugin-workflow/transform/tests/errors/invalid-exports/output-step.stderr | Updates/records expected stderr for invalid exports in file-level "use step" files. |
| packages/swc-plugin-workflow/transform/tests/errors/invalid-exports/output-client.stderr | Updates/records expected stderr for invalid exports in file-level "use step" files. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
VaguelySerious
left a comment
There was a problem hiding this comment.
AI review: no blocking issues
- Reject uninitialized var exports (export let x) in step files
- Reject local named exports (export { value }) in step files since
we cannot statically verify the binding is a function
- Add test coverage for both new rejection cases
- Add sync variants for let/var arrow functions in spec.md
- Add re-export with specifiers to invalid-exports (export { x } from)
- Add error fixture for default class export in step files
- Add fixture for sync default function export (should pass)
- Total: 220 tests (165 fixture + 33 error + 22 unit)
Summary
Addresses review feedback from #1633 (already merged):
validate_async_functionremoval"use step"files: sync/async function exports are allowed, but non-function exports (constants, classes, re-exports) emit an error since they can pull Node-only code into the workflow/client bundlesInvalidExporterror message to say "Only functions can be exported" for step files vs "Only async functions can be exported" for workflow filesspec.mderror table and supported function forms to document sync step supportsync-step-classtest fixture covering sync static class methods and sync function expressions (var/let)sync-workflowerror test verifying sync"use workflow"still errors while sync"use step"passes