Skip to content

[swc-plugin] Preserve imports referenced by hoisted nested steps#1944

Merged
TooTallNate merged 3 commits intomainfrom
swc-plugin/preserve-imports-for-hoisted-steps
May 5, 2026
Merged

[swc-plugin] Preserve imports referenced by hoisted nested steps#1944
TooTallNate merged 3 commits intomainfrom
swc-plugin/preserve-imports-for-hoisted-steps

Conversation

@TooTallNate
Copy link
Copy Markdown
Member

Summary

Fixes a bug in the SWC plugin where step-mode bundles dropped module-level imports that were referenced by step functions hoisted out of workflow bodies, causing a ReferenceError at runtime.

Root Cause

Ordering bug in the transform pipeline:

  1. StepTransform::visit_mut_module_items runs and, at the end, invokes remove_dead_code, which strips any import not referenced by current top-level code.
  2. StepTransform::visit_mut_program then hoists nested step functions out of workflow bodies onto the module top level (e.g. var _anonymousStep0 = async (input) => db.query(input.query);).
  3. The hoisted body references db, but the import was already deleted in step 1.

This only affected steps nested inside workflow function bodies — top-level steps already worked because their bodies were inlined in items before DCE ran. Three pre-existing fixtures (nested-step-with-closure, nested-steps-in-object-constructor, factory-with-step-method) had committed buggy outputs that this change corrects.

For example, given:

import { db } from './db';

async function w() {
  'use workflow';
  const agent = new WorkflowAgent({
    tools: () => ({
      queryDatabase: tool({
        execute: async (input) => {
          'use step';
          return db.query(input.query);
        },
      }),
    }),
  });
}

The previous step-mode output omitted import { db } from './db'; while still emitting var _anonymousStep0 = async (input) => db.query(input.query);.

Fix

In packages/swc-plugin-workflow/transform/src/lib.rs:

  • Removed the early remove_dead_code call from the end of visit_mut_module_items.
  • Added a single remove_dead_code(&mut module.body) call in visit_mut_program, after nested step hoisting completes (right before metadata-comment insertion).

Verification

  • Added regression fixture tests/fixture/nested-step-references-module-import/ covering both kept-imports (used by hoisted step) and stripped-imports (truly unused, or only used by replaced workflow body).
  • All 124 SWC fixture tests pass.
  • Three pre-existing fixtures had their output-step.js files updated to now correctly include the imports their hoisted steps reference.
  • spec.md already documented the desired behavior — no spec change needed; this is purely an implementation conformance fix.

Dead-code elimination ran before nested step functions were hoisted out of workflow bodies, so imports referenced only by hoisted step bodies were incorrectly stripped from the step bundle, causing a ReferenceError at runtime. Move DCE to run after hoisting in visit_mut_program.
Copilot AI review requested due to automatic review settings May 5, 2026 20:21
@vercel
Copy link
Copy Markdown
Contributor

vercel Bot commented May 5, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
example-nextjs-workflow-turbopack Ready Ready Preview, Comment May 5, 2026 9:22pm
example-nextjs-workflow-webpack Ready Ready Preview, Comment May 5, 2026 9:22pm
example-workflow Ready Ready Preview, Comment May 5, 2026 9:22pm
workbench-astro-workflow Ready Ready Preview, Comment May 5, 2026 9:22pm
workbench-express-workflow Ready Ready Preview, Comment May 5, 2026 9:22pm
workbench-fastify-workflow Ready Ready Preview, Comment May 5, 2026 9:22pm
workbench-hono-workflow Ready Ready Preview, Comment May 5, 2026 9:22pm
workbench-nitro-workflow Ready Ready Preview, Comment May 5, 2026 9:22pm
workbench-nuxt-workflow Ready Ready Preview, Comment May 5, 2026 9:22pm
workbench-sveltekit-workflow Ready Ready Preview, Comment May 5, 2026 9:22pm
workbench-tanstack-start-workflow Ready Ready Preview, Comment May 5, 2026 9:22pm
workbench-vite-workflow Ready Ready Preview, Comment May 5, 2026 9:22pm
workflow-docs Ready Ready Preview, Comment, Open in v0 May 5, 2026 9:22pm
workflow-swc-playground Ready Ready Preview, Comment May 5, 2026 9:22pm
workflow-tarballs Ready Ready Preview, Comment May 5, 2026 9:22pm
workflow-web Ready Ready Preview, Comment May 5, 2026 9:22pm

@changeset-bot
Copy link
Copy Markdown

changeset-bot Bot commented May 5, 2026

🦋 Changeset detected

Latest commit: 9d132e5

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 19 packages
Name Type
@workflow/swc-plugin Patch
@workflow/astro Patch
@workflow/builders Patch
@workflow/cli Patch
@workflow/nest Patch
@workflow/next Patch
@workflow/nitro Patch
@workflow/rollup Patch
@workflow/sveltekit Patch
tarballs Patch
workflow Patch
@workflow/vite Patch
@workflow/vitest Patch
@workflow/world-testing Patch
@workflow/nuxt Patch
@workflow/ai Patch
@workflow/core Patch
@workflow/web-shared Patch
@workflow/web Patch

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

@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented May 5, 2026

🧪 E2E Test Results

All tests passed

Summary

Passed Failed Skipped Total
✅ ▲ Vercel Production 1200 0 219 1419
✅ 💻 Local Development 1587 0 219 1806
✅ 📦 Local Production 1587 0 219 1806
✅ 🐘 Local Postgres 1587 0 219 1806
✅ 🪟 Windows 129 0 0 129
✅ 📋 Other 727 0 176 903
Total 6817 0 1052 7869

Details by Category

✅ ▲ Vercel Production
App Passed Failed Skipped
✅ astro 103 0 26
✅ example 103 0 26
✅ express 103 0 26
✅ fastify 103 0 26
✅ hono 103 0 26
✅ nextjs-turbopack 127 0 2
✅ nextjs-webpack 127 0 2
✅ nitro 103 0 26
✅ nuxt 103 0 26
✅ sveltekit 122 0 7
✅ vite 103 0 26
✅ 💻 Local Development
App Passed Failed Skipped
✅ astro-stable 104 0 25
✅ express-stable 104 0 25
✅ fastify-stable 104 0 25
✅ hono-stable 104 0 25
✅ nextjs-turbopack-canary 110 0 19
✅ nextjs-turbopack-stable-lazy-discovery-disabled 129 0 0
✅ nextjs-turbopack-stable-lazy-discovery-enabled 129 0 0
✅ nextjs-webpack-canary 110 0 19
✅ nextjs-webpack-stable-lazy-discovery-disabled 129 0 0
✅ nextjs-webpack-stable-lazy-discovery-enabled 129 0 0
✅ nitro-stable 104 0 25
✅ nuxt-stable 104 0 25
✅ sveltekit-stable 123 0 6
✅ vite-stable 104 0 25
✅ 📦 Local Production
App Passed Failed Skipped
✅ astro-stable 104 0 25
✅ express-stable 104 0 25
✅ fastify-stable 104 0 25
✅ hono-stable 104 0 25
✅ nextjs-turbopack-canary 110 0 19
✅ nextjs-turbopack-stable-lazy-discovery-disabled 129 0 0
✅ nextjs-turbopack-stable-lazy-discovery-enabled 129 0 0
✅ nextjs-webpack-canary 110 0 19
✅ nextjs-webpack-stable-lazy-discovery-disabled 129 0 0
✅ nextjs-webpack-stable-lazy-discovery-enabled 129 0 0
✅ nitro-stable 104 0 25
✅ nuxt-stable 104 0 25
✅ sveltekit-stable 123 0 6
✅ vite-stable 104 0 25
✅ 🐘 Local Postgres
App Passed Failed Skipped
✅ astro-stable 104 0 25
✅ express-stable 104 0 25
✅ fastify-stable 104 0 25
✅ hono-stable 104 0 25
✅ nextjs-turbopack-canary 110 0 19
✅ nextjs-turbopack-stable-lazy-discovery-disabled 129 0 0
✅ nextjs-turbopack-stable-lazy-discovery-enabled 129 0 0
✅ nextjs-webpack-canary 110 0 19
✅ nextjs-webpack-stable-lazy-discovery-disabled 129 0 0
✅ nextjs-webpack-stable-lazy-discovery-enabled 129 0 0
✅ nitro-stable 104 0 25
✅ nuxt-stable 104 0 25
✅ sveltekit-stable 123 0 6
✅ vite-stable 104 0 25
✅ 🪟 Windows
App Passed Failed Skipped
✅ nextjs-turbopack 129 0 0
✅ 📋 Other
App Passed Failed Skipped
✅ e2e-local-dev-nest-stable 104 0 25
✅ e2e-local-dev-tanstack-start- 104 0 25
✅ e2e-local-postgres-nest-stable 104 0 25
✅ e2e-local-postgres-tanstack-start- 104 0 25
✅ e2e-local-prod-nest-stable 104 0 25
✅ e2e-local-prod-tanstack-start- 104 0 25
✅ e2e-vercel-prod-tanstack-start 103 0 26

📋 View full workflow run

@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented May 5, 2026

📊 Benchmark Results

📈 Comparing against baseline from main branch. Green 🟢 = faster, Red 🔺 = slower.

workflow with no steps

💻 Local Development

World Framework Workflow Time Wall Time Overhead Samples vs Fastest
💻 Local 🥇 Nitro 0.033s (-22.7% 🟢) 1.005s (~) 0.972s 10 1.00x
💻 Local Express 0.036s (-19.2% 🟢) 1.006s (~) 0.970s 10 1.08x
🐘 Postgres Express 0.045s (-21.7% 🟢) 1.011s (~) 0.965s 10 1.36x
💻 Local Next.js (Turbopack) 0.049s 1.005s 0.956s 10 1.47x
🐘 Postgres Nitro 0.051s (-47.0% 🟢) 1.011s (-3.1%) 0.961s 10 1.52x
🌐 Redis Next.js (Turbopack) 0.052s 1.005s 0.953s 10 1.56x
🐘 Postgres Next.js (Turbopack) 0.057s 1.011s 0.954s 10 1.71x
🌐 MongoDB Next.js (Turbopack) 0.129s 1.007s 0.879s 10 3.86x

▲ Production (Vercel)

World Framework Workflow Time Wall Time Overhead Samples vs Fastest
▲ Vercel 🥇 Nitro 0.220s (-46.4% 🟢) 2.151s (-14.3% 🟢) 1.931s 10 1.00x
▲ Vercel Next.js (Turbopack) 1.154s (+359.0% 🔺) 2.852s (+22.3% 🔺) 1.698s 10 5.25x
▲ Vercel Express ⚠️ missing - - - -

🔍 Observability: Nitro | Next.js (Turbopack)

workflow with 1 step

💻 Local Development

World Framework Workflow Time Wall Time Overhead Samples vs Fastest
💻 Local 🥇 Express 1.075s (-4.5%) 2.007s (~) 0.931s 10 1.00x
💻 Local Nitro 1.075s (-5.0%) 2.006s (~) 0.931s 10 1.00x
🐘 Postgres Nitro 1.083s (-5.0%) 2.009s (~) 0.926s 10 1.01x
🐘 Postgres Express 1.084s (-5.4% 🟢) 2.009s (~) 0.925s 10 1.01x
💻 Local Next.js (Turbopack) 1.110s 2.006s 0.896s 10 1.03x
🌐 Redis Next.js (Turbopack) 1.111s 2.006s 0.895s 10 1.03x
🐘 Postgres Next.js (Turbopack) 1.129s 2.008s 0.879s 10 1.05x
🌐 MongoDB Next.js (Turbopack) 1.169s 2.009s 0.840s 10 1.09x

▲ Production (Vercel)

World Framework Workflow Time Wall Time Overhead Samples vs Fastest
▲ Vercel 🥇 Nitro 1.608s (-58.7% 🟢) 3.463s (-41.4% 🟢) 1.855s 10 1.00x
▲ Vercel Next.js (Turbopack) 3.023s (+48.6% 🔺) 4.583s (+19.6% 🔺) 1.560s 10 1.88x
▲ Vercel Express ⚠️ missing - - - -

🔍 Observability: Nitro | Next.js (Turbopack)

workflow with 10 sequential steps

💻 Local Development

World Framework Workflow Time Wall Time Overhead Samples vs Fastest
💻 Local 🥇 Nitro 10.404s (-4.9%) 11.023s (~) 0.618s 3 1.00x
🐘 Postgres Express 10.408s (-5.1% 🟢) 11.018s (~) 0.611s 3 1.00x
🐘 Postgres Nitro 10.419s (-4.2%) 11.016s (~) 0.597s 3 1.00x
💻 Local Express 10.424s (-4.6%) 11.022s (~) 0.598s 3 1.00x
🐘 Postgres Next.js (Turbopack) 10.657s 11.016s 0.359s 3 1.02x
💻 Local Next.js (Turbopack) 10.669s 11.021s 0.353s 3 1.03x
🌐 Redis Next.js (Turbopack) 10.691s 11.022s 0.332s 3 1.03x
🌐 MongoDB Next.js (Turbopack) 10.894s 11.352s 0.458s 3 1.05x

▲ Production (Vercel)

World Framework Workflow Time Wall Time Overhead Samples vs Fastest
▲ Vercel 🥇 Nitro 13.342s (-43.8% 🟢) 14.917s (-40.6% 🟢) 1.575s 3 1.00x
▲ Vercel Next.js (Turbopack) 13.784s (-20.4% 🟢) 15.604s (-19.6% 🟢) 1.821s 2 1.03x
▲ Vercel Express ⚠️ missing - - - -

🔍 Observability: Nitro | Next.js (Turbopack)

workflow with 25 sequential steps

💻 Local Development

World Framework Workflow Time Wall Time Overhead Samples vs Fastest
🐘 Postgres 🥇 Express 13.447s (-7.8% 🟢) 14.017s (-6.7% 🟢) 0.570s 5 1.00x
🐘 Postgres Nitro 13.451s (-7.8% 🟢) 14.015s (-6.7% 🟢) 0.565s 5 1.00x
💻 Local Nitro 13.507s (-10.3% 🟢) 14.027s (-12.5% 🟢) 0.520s 5 1.00x
💻 Local Express 13.523s (-9.7% 🟢) 14.028s (-6.7% 🟢) 0.505s 5 1.01x
💻 Local Next.js (Turbopack) 14.061s 14.828s 0.767s 5 1.05x
🌐 Redis Next.js (Turbopack) 14.100s 15.029s 0.929s 4 1.05x
🐘 Postgres Next.js (Turbopack) 14.112s 15.017s 0.905s 4 1.05x
🌐 MongoDB Next.js (Turbopack) 14.354s 15.026s 0.672s 4 1.07x

▲ Production (Vercel)

World Framework Workflow Time Wall Time Overhead Samples vs Fastest
▲ Vercel 🥇 Nitro 21.643s (-66.4% 🟢) 23.304s (-65.0% 🟢) 1.660s 3 1.00x
▲ Vercel Next.js (Turbopack) 23.990s (-54.4% 🟢) 25.981s (-52.4% 🟢) 1.991s 3 1.11x
▲ Vercel Express ⚠️ missing - - - -

🔍 Observability: Nitro | Next.js (Turbopack)

workflow with 50 sequential steps

💻 Local Development

World Framework Workflow Time Wall Time Overhead Samples vs Fastest
🐘 Postgres 🥇 Express 11.854s (-15.4% 🟢) 12.015s (-17.7% 🟢) 0.161s 8 1.00x
💻 Local Nitro 11.930s (-28.9% 🟢) 12.022s (-29.4% 🟢) 0.092s 8 1.01x
🐘 Postgres Nitro 11.936s (-14.5% 🟢) 12.266s (-14.3% 🟢) 0.330s 8 1.01x
💻 Local Express 12.068s (-27.3% 🟢) 12.774s (-25.0% 🟢) 0.706s 8 1.02x
🌐 Redis Next.js (Turbopack) 12.966s 13.310s 0.344s 7 1.09x
💻 Local Next.js (Turbopack) 13.010s 13.167s 0.157s 7 1.10x
🐘 Postgres Next.js (Turbopack) 13.305s 14.016s 0.710s 7 1.12x
🌐 MongoDB Next.js (Turbopack) 13.338s 14.023s 0.684s 7 1.13x

▲ Production (Vercel)

World Framework Workflow Time Wall Time Overhead Samples vs Fastest
▲ Vercel 🥇 Nitro 32.625s (-92.3% 🟢) 34.494s (-91.9% 🟢) 1.869s 3 1.00x
▲ Vercel Next.js (Turbopack) 35.758s (-90.9% 🟢) 37.455s (-90.5% 🟢) 1.697s 3 1.10x
▲ Vercel Express ⚠️ missing - - - -

🔍 Observability: Nitro | Next.js (Turbopack)

Promise.all with 10 concurrent steps

💻 Local Development

World Framework Workflow Time Wall Time Overhead Samples vs Fastest
🐘 Postgres 🥇 Nitro 1.146s (-10.1% 🟢) 2.007s (~) 0.861s 15 1.00x
🐘 Postgres Express 1.149s (-8.8% 🟢) 2.007s (~) 0.857s 15 1.00x
💻 Local Nitro 1.186s (-27.3% 🟢) 2.006s (-3.3%) 0.820s 15 1.04x
💻 Local Express 1.195s (-19.7% 🟢) 2.006s (~) 0.811s 15 1.04x
🐘 Postgres Next.js (Turbopack) 1.235s 2.007s 0.772s 15 1.08x
🌐 Redis Next.js (Turbopack) 1.254s 2.006s 0.752s 15 1.09x
💻 Local Next.js (Turbopack) 1.292s 2.006s 0.714s 15 1.13x
🌐 MongoDB Next.js (Turbopack) 2.028s 2.735s 0.707s 11 1.77x

▲ Production (Vercel)

World Framework Workflow Time Wall Time Overhead Samples vs Fastest
▲ Vercel 🥇 Nitro 2.906s (+3.1%) 4.524s (+4.7%) 1.618s 7 1.00x
▲ Vercel Next.js (Turbopack) 4.911s (+44.6% 🔺) 6.214s (+26.0% 🔺) 1.303s 5 1.69x
▲ Vercel Express ⚠️ missing - - - -

🔍 Observability: Nitro | Next.js (Turbopack)

Promise.all with 25 concurrent steps

💻 Local Development

World Framework Workflow Time Wall Time Overhead Samples vs Fastest
🐘 Postgres 🥇 Express 1.219s (-48.4% 🟢) 2.008s (-33.3% 🟢) 0.789s 15 1.00x
🐘 Postgres Nitro 1.230s (-47.7% 🟢) 2.007s (-33.3% 🟢) 0.777s 15 1.01x
🐘 Postgres Next.js (Turbopack) 1.355s 2.007s 0.652s 15 1.11x
💻 Local Nitro 1.777s (-43.5% 🟢) 2.006s (-48.4% 🟢) 0.228s 15 1.46x
💻 Local Next.js (Turbopack) 1.824s 2.006s 0.183s 15 1.50x
💻 Local Express 1.879s (-36.4% 🟢) 2.223s (-35.6% 🟢) 0.344s 14 1.54x
🌐 Redis Next.js (Turbopack) 2.358s 3.008s 0.650s 10 1.93x
🌐 MongoDB Next.js (Turbopack) 3.576s 4.009s 0.433s 8 2.93x

▲ Production (Vercel)

World Framework Workflow Time Wall Time Overhead Samples vs Fastest
▲ Vercel 🥇 Nitro 3.582s (-11.6% 🟢) 5.158s (-12.9% 🟢) 1.577s 7 1.00x
▲ Vercel Next.js (Turbopack) 5.608s (-21.0% 🟢) 7.256s (-18.5% 🟢) 1.648s 5 1.57x
▲ Vercel Express ⚠️ missing - - - -

🔍 Observability: Nitro | Next.js (Turbopack)

Promise.all with 50 concurrent steps

💻 Local Development

World Framework Workflow Time Wall Time Overhead Samples vs Fastest
🐘 Postgres 🥇 Express 1.367s (-60.8% 🟢) 2.007s (-49.9% 🟢) 0.640s 15 1.00x
🐘 Postgres Nitro 1.376s (-60.5% 🟢) 2.007s (-49.9% 🟢) 0.632s 15 1.01x
🐘 Postgres Next.js (Turbopack) 1.639s 2.074s 0.435s 15 1.20x
🌐 Redis Next.js (Turbopack) 3.586s 4.010s 0.423s 8 2.62x
💻 Local Nitro 5.274s (-36.8% 🟢) 5.846s (-35.2% 🟢) 0.572s 6 3.86x
💻 Local Express 5.587s (-33.0% 🟢) 6.213s (-31.2% 🟢) 0.626s 5 4.09x
💻 Local Next.js (Turbopack) 5.748s 6.213s 0.465s 5 4.20x
🌐 MongoDB Next.js (Turbopack) 6.301s 7.013s 0.712s 5 4.61x

▲ Production (Vercel)

World Framework Workflow Time Wall Time Overhead Samples vs Fastest
▲ Vercel 🥇 Nitro 5.978s (+69.6% 🔺) 8.125s (+46.8% 🔺) 2.147s 4 1.00x
▲ Vercel Next.js (Turbopack) 7.377s (-17.3% 🟢) 9.561s (-12.8% 🟢) 2.184s 4 1.23x
▲ Vercel Express ⚠️ missing - - - -

🔍 Observability: Nitro | Next.js (Turbopack)

Promise.race with 10 concurrent steps

💻 Local Development

World Framework Workflow Time Wall Time Overhead Samples vs Fastest
🐘 Postgres 🥇 Express 1.150s (-8.5% 🟢) 2.008s (~) 0.858s 15 1.00x
🐘 Postgres Nitro 1.169s (-7.0% 🟢) 2.008s (~) 0.839s 15 1.02x
🐘 Postgres Next.js (Turbopack) 1.218s 2.008s 0.790s 15 1.06x
🌐 Redis Next.js (Turbopack) 1.240s 2.006s 0.766s 15 1.08x
💻 Local Next.js (Turbopack) 1.322s 2.006s 0.684s 15 1.15x
💻 Local Nitro 1.398s (-25.1% 🟢) 2.006s (-14.3% 🟢) 0.608s 15 1.22x
💻 Local Express 1.423s (-24.8% 🟢) 2.006s (-15.1% 🟢) 0.583s 15 1.24x
🌐 MongoDB Next.js (Turbopack) 2.029s 2.675s 0.645s 12 1.76x

▲ Production (Vercel)

World Framework Workflow Time Wall Time Overhead Samples vs Fastest
▲ Vercel 🥇 Nitro 2.689s (+9.3% 🔺) 4.494s (+7.8% 🔺) 1.805s 7 1.00x
▲ Vercel Next.js (Turbopack) 3.798s (+29.5% 🔺) 5.672s (+22.2% 🔺) 1.874s 6 1.41x
▲ Vercel Express ⚠️ missing - - - -

🔍 Observability: Nitro | Next.js (Turbopack)

Promise.race with 25 concurrent steps

💻 Local Development

World Framework Workflow Time Wall Time Overhead Samples vs Fastest
🐘 Postgres 🥇 Express 1.229s (-47.5% 🟢) 2.008s (-33.3% 🟢) 0.779s 15 1.00x
🐘 Postgres Nitro 1.247s (-46.7% 🟢) 2.008s (-33.3% 🟢) 0.760s 15 1.02x
🐘 Postgres Next.js (Turbopack) 1.386s 2.008s 0.622s 15 1.13x
💻 Local Express 2.079s (-33.6% 🟢) 2.510s (-33.3% 🟢) 0.430s 12 1.69x
💻 Local Next.js (Turbopack) 2.117s 2.735s 0.617s 11 1.72x
💻 Local Nitro 2.169s (-29.2% 🟢) 2.593s (-33.3% 🟢) 0.424s 12 1.77x
🌐 Redis Next.js (Turbopack) 2.343s 3.008s 0.665s 10 1.91x
🌐 MongoDB Next.js (Turbopack) 3.579s 4.009s 0.430s 8 2.91x

▲ Production (Vercel)

World Framework Workflow Time Wall Time Overhead Samples vs Fastest
▲ Vercel 🥇 Nitro 3.315s (+2.5%) 4.910s (-3.3%) 1.595s 7 1.00x
▲ Vercel Next.js (Turbopack) 5.136s (+63.4% 🔺) 7.036s (+55.6% 🔺) 1.901s 5 1.55x
▲ Vercel Express ⚠️ missing - - - -

🔍 Observability: Nitro | Next.js (Turbopack)

Promise.race with 50 concurrent steps

💻 Local Development

World Framework Workflow Time Wall Time Overhead Samples vs Fastest
🐘 Postgres 🥇 Nitro 1.377s (-60.4% 🟢) 2.007s (-49.9% 🟢) 0.630s 15 1.00x
🐘 Postgres Express 1.386s (-60.4% 🟢) 2.008s (-49.9% 🟢) 0.622s 15 1.01x
🐘 Postgres Next.js (Turbopack) 1.637s 2.007s 0.370s 15 1.19x
🌐 Redis Next.js (Turbopack) 3.635s 4.009s 0.374s 8 2.64x
💻 Local Nitro 5.492s (-39.9% 🟢) 6.214s (-38.0% 🟢) 0.722s 5 3.99x
💻 Local Next.js (Turbopack) 5.810s 6.413s 0.603s 5 4.22x
💻 Local Express 5.859s (-33.4% 🟢) 6.616s (-28.7% 🟢) 0.757s 5 4.25x
🌐 MongoDB Next.js (Turbopack) 6.297s 7.013s 0.716s 5 4.57x

▲ Production (Vercel)

World Framework Workflow Time Wall Time Overhead Samples vs Fastest
▲ Vercel 🥇 Next.js (Turbopack) 6.088s (-9.9% 🟢) 8.239s (-3.6%) 2.151s 4 1.00x
▲ Vercel Nitro 6.546s (+28.5% 🔺) 8.394s (+23.1% 🔺) 1.849s 4 1.08x
▲ Vercel Express ⚠️ missing - - - -

🔍 Observability: Next.js (Turbopack) | Nitro

workflow with 10 sequential data payload steps (10KB)

💻 Local Development

World Framework Workflow Time Wall Time Overhead Samples vs Fastest
🐘 Postgres 🥇 Nitro 0.440s (-46.4% 🟢) 1.006s (~) 0.566s 60 1.00x
🐘 Postgres Express 0.454s (-45.8% 🟢) 1.006s (-1.7%) 0.552s 60 1.03x
💻 Local Express 0.504s (-48.8% 🟢) 1.005s (-6.6% 🟢) 0.500s 60 1.15x
💻 Local Nitro 0.524s (-46.5% 🟢) 1.022s (-6.6% 🟢) 0.498s 59 1.19x
🌐 Redis Next.js (Turbopack) 0.617s 1.004s 0.388s 60 1.40x
🐘 Postgres Next.js (Turbopack) 0.665s 1.006s 0.341s 60 1.51x
💻 Local Next.js (Turbopack) 0.726s 1.004s 0.278s 60 1.65x
🌐 MongoDB Next.js (Turbopack) 0.744s 1.006s 0.262s 60 1.69x

▲ Production (Vercel)

World Framework Workflow Time Wall Time Overhead Samples vs Fastest
▲ Vercel 🥇 Nitro 5.295s (-76.0% 🟢) 7.121s (-70.4% 🟢) 1.826s 9 1.00x
▲ Vercel Next.js (Turbopack) 6.625s (-54.3% 🟢) 8.457s (-47.4% 🟢) 1.832s 8 1.25x
▲ Vercel Express ⚠️ missing - - - -

🔍 Observability: Nitro | Next.js (Turbopack)

workflow with 25 sequential data payload steps (10KB)

💻 Local Development

World Framework Workflow Time Wall Time Overhead Samples vs Fastest
🐘 Postgres 🥇 Nitro 1.015s (-47.4% 🟢) 1.532s (-27.1% 🟢) 0.518s 59 1.00x
🐘 Postgres Express 1.052s (-46.8% 🟢) 1.632s (-27.7% 🟢) 0.580s 56 1.04x
💻 Local Nitro 1.204s (-60.3% 🟢) 2.006s (-46.6% 🟢) 0.801s 45 1.19x
💻 Local Express 1.286s (-57.4% 🟢) 2.006s (-44.0% 🟢) 0.720s 45 1.27x
🌐 Redis Next.js (Turbopack) 1.476s 2.006s 0.529s 45 1.46x
🐘 Postgres Next.js (Turbopack) 1.585s 2.007s 0.423s 45 1.56x
💻 Local Next.js (Turbopack) 1.764s 2.006s 0.241s 45 1.74x
🌐 MongoDB Next.js (Turbopack) 1.840s 2.007s 0.168s 45 1.81x

▲ Production (Vercel)

World Framework Workflow Time Wall Time Overhead Samples vs Fastest
▲ Vercel 🥇 Nitro 12.861s (-67.4% 🟢) 14.586s (-64.7% 🟢) 1.725s 7 1.00x
▲ Vercel Next.js (Turbopack) 16.086s (-67.7% 🟢) 18.350s (-64.5% 🟢) 2.264s 5 1.25x
▲ Vercel Express ⚠️ missing - - - -

🔍 Observability: Nitro | Next.js (Turbopack)

workflow with 50 sequential data payload steps (10KB)

💻 Local Development

World Framework Workflow Time Wall Time Overhead Samples vs Fastest
🐘 Postgres 🥇 Nitro 2.063s (-49.7% 🟢) 2.549s (-44.6% 🟢) 0.486s 48 1.00x
🐘 Postgres Express 2.126s (-46.7% 🟢) 2.719s (-37.8% 🟢) 0.592s 45 1.03x
💻 Local Nitro 2.678s (-71.2% 🟢) 3.008s (-70.0% 🟢) 0.330s 40 1.30x
💻 Local Express 2.803s (-69.6% 🟢) 3.033s (-69.7% 🟢) 0.230s 40 1.36x
🌐 Redis Next.js (Turbopack) 2.963s 3.135s 0.173s 39 1.44x
🐘 Postgres Next.js (Turbopack) 3.131s 4.008s 0.877s 30 1.52x
💻 Local Next.js (Turbopack) 3.767s 4.007s 0.240s 30 1.83x
🌐 MongoDB Next.js (Turbopack) 4.174s 5.012s 0.838s 24 2.02x

▲ Production (Vercel)

World Framework Workflow Time Wall Time Overhead Samples vs Fastest
▲ Vercel 🥇 Nitro 40.280s (-58.4% 🟢) 42.530s (-56.8% 🟢) 2.250s 3 1.00x
▲ Vercel Next.js (Turbopack) 46.873s (-56.3% 🟢) 48.931s (-55.1% 🟢) 2.058s 3 1.16x
▲ Vercel Express ⚠️ missing - - - -

🔍 Observability: Nitro | Next.js (Turbopack)

workflow with 10 concurrent data payload steps (10KB)

💻 Local Development

World Framework Workflow Time Wall Time Overhead Samples vs Fastest
🐘 Postgres 🥇 Nitro 0.187s (-33.9% 🟢) 1.006s (~) 0.818s 60 1.00x
🐘 Postgres Express 0.190s (-32.8% 🟢) 1.006s (~) 0.816s 60 1.01x
🐘 Postgres Next.js (Turbopack) 0.236s 1.006s 0.770s 60 1.26x
🌐 Redis Next.js (Turbopack) 0.242s 1.004s 0.762s 60 1.30x
💻 Local Nitro 0.469s (-22.5% 🟢) 1.021s (~) 0.553s 59 2.50x
💻 Local Express 0.483s (-13.8% 🟢) 1.005s (~) 0.522s 60 2.58x
💻 Local Next.js (Turbopack) 0.554s 1.005s 0.451s 60 2.96x
🌐 MongoDB Next.js (Turbopack) 1.030s 1.825s 0.794s 33 5.50x

▲ Production (Vercel)

World Framework Workflow Time Wall Time Overhead Samples vs Fastest
▲ Vercel 🥇 Nitro 2.619s (+57.7% 🔺) 4.178s (+24.7% 🔺) 1.559s 15 1.00x
▲ Vercel Next.js (Turbopack) 3.871s (+91.4% 🔺) 5.504s (+45.1% 🔺) 1.633s 12 1.48x
▲ Vercel Express ⚠️ missing - - - -

🔍 Observability: Nitro | Next.js (Turbopack)

workflow with 25 concurrent data payload steps (10KB)

💻 Local Development

World Framework Workflow Time Wall Time Overhead Samples vs Fastest
🐘 Postgres 🥇 Nitro 0.315s (-36.6% 🟢) 1.006s (~) 0.691s 90 1.00x
🐘 Postgres Express 0.325s (-36.3% 🟢) 1.007s (~) 0.682s 90 1.03x
🌐 Redis Next.js (Turbopack) 0.410s 1.004s 0.594s 90 1.30x
🐘 Postgres Next.js (Turbopack) 0.458s 1.006s 0.548s 90 1.45x
💻 Local Nitro 2.270s (-10.6% 🟢) 2.944s (-2.2%) 0.675s 31 7.21x
💻 Local Express 2.282s (-9.2% 🟢) 3.009s (~) 0.727s 30 7.25x
💻 Local Next.js (Turbopack) 2.466s 3.042s 0.576s 30 7.84x
🌐 MongoDB Next.js (Turbopack) 2.605s 3.007s 0.402s 30 8.28x

▲ Production (Vercel)

World Framework Workflow Time Wall Time Overhead Samples vs Fastest
▲ Vercel 🥇 Next.js (Turbopack) 8.211s (+132.3% 🔺) 9.775s (+88.2% 🔺) 1.564s 10 1.00x
▲ Vercel Nitro 9.758s (+202.5% 🔺) 11.351s (+135.4% 🔺) 1.593s 8 1.19x
▲ Vercel Express ⚠️ missing - - - -

🔍 Observability: Next.js (Turbopack) | Nitro

workflow with 50 concurrent data payload steps (10KB)

💻 Local Development

World Framework Workflow Time Wall Time Overhead Samples vs Fastest
🐘 Postgres 🥇 Nitro 0.652s (-17.5% 🟢) 1.006s (~) 0.354s 120 1.00x
🐘 Postgres Express 0.697s (-14.9% 🟢) 1.007s (-1.0%) 0.310s 120 1.07x
🌐 Redis Next.js (Turbopack) 0.755s 1.004s 0.249s 120 1.16x
🐘 Postgres Next.js (Turbopack) 0.944s 1.340s 0.397s 90 1.45x
🌐 MongoDB Next.js (Turbopack) 5.389s 6.013s 0.624s 20 8.27x
💻 Local Nitro 10.289s (-8.1% 🟢) 10.781s (-7.6% 🟢) 0.492s 12 15.78x
💻 Local Express 11.054s (-1.2%) 11.668s (-2.3%) 0.615s 11 16.96x
💻 Local Next.js (Turbopack) 11.576s 12.233s 0.657s 10 17.76x

▲ Production (Vercel)

World Framework Workflow Time Wall Time Overhead Samples vs Fastest
▲ Vercel 🥇 Next.js (Turbopack) 19.155s (+85.5% 🔺) 21.092s (+71.7% 🔺) 1.938s 6 1.00x
▲ Vercel Nitro 23.620s (+205.8% 🔺) 25.372s (+169.9% 🔺) 1.753s 5 1.23x
▲ Vercel Express ⚠️ missing - - - -

🔍 Observability: Next.js (Turbopack) | Nitro

Stream Benchmarks (includes TTFB metrics)
workflow with stream

💻 Local Development

World Framework Workflow Time TTFB Slurp Wall Time Overhead Samples vs Fastest
🐘 Postgres 🥇 Express 1.133s (+452.2% 🔺) 1.997s (+100.0% 🔺) 0.001s (-18.8% 🟢) 2.011s (+98.8% 🔺) 0.878s 10 1.00x
🐘 Postgres Nitro 1.140s (+456.1% 🔺) 1.997s (+99.8% 🔺) 0.001s (-13.3% 🟢) 2.011s (+98.8% 🔺) 0.871s 10 1.01x
💻 Local Nitro 1.141s (+434.1% 🔺) 2.005s (+99.6% 🔺) 0.013s (+1.6%) 2.021s (+98.3% 🔺) 0.879s 10 1.01x
💻 Local Express 1.142s (+473.8% 🔺) 2.006s (+99.7% 🔺) 0.013s (+4.1%) 2.021s (+98.5% 🔺) 0.878s 10 1.01x
💻 Local Next.js (Turbopack) 1.176s 2.004s 0.012s 2.020s 0.844s 10 1.04x
🐘 Postgres Next.js (Turbopack) 1.196s 2.001s 0.002s 2.011s 0.816s 10 1.06x
🌐 MongoDB Next.js (Turbopack) ⚠️ missing - - - - -
🌐 Redis Next.js (Turbopack) ⚠️ missing - - - - -

▲ Production (Vercel)

World Framework Workflow Time TTFB Slurp Wall Time Overhead Samples vs Fastest
▲ Vercel 🥇 Nitro 2.149s (-43.9% 🟢) 3.058s (-42.1% 🟢) 1.931s (+160.2% 🔺) 5.669s (-12.6% 🟢) 3.520s 10 1.00x
▲ Vercel Next.js (Turbopack) 4.815s (-29.7% 🟢) 5.037s (-41.8% 🟢) 0.879s (+39.1% 🔺) 7.516s (-23.2% 🟢) 2.701s 10 2.24x
▲ Vercel Express ⚠️ missing - - - - -

🔍 Observability: Nitro | Next.js (Turbopack)

stream pipeline with 5 transform steps (1MB)

💻 Local Development

World Framework Workflow Time TTFB Slurp Wall Time Overhead Samples vs Fastest
🐘 Postgres 🥇 Nitro 1.522s (+143.9% 🔺) 1.999s (+98.6% 🔺) 0.004s (-9.7% 🟢) 2.025s (+98.1% 🔺) 0.503s 30 1.00x
🐘 Postgres Express 1.563s (+148.0% 🔺) 2.005s (+99.2% 🔺) 0.004s (-4.3%) 2.025s (+98.0% 🔺) 0.463s 30 1.03x
💻 Local Next.js (Turbopack) 1.664s 2.010s 0.009s 2.023s 0.359s 30 1.09x
🐘 Postgres Next.js (Turbopack) 1.669s 2.009s 0.004s 2.024s 0.355s 30 1.10x
💻 Local Nitro 1.705s (+103.2% 🔺) 2.011s (+98.7% 🔺) 0.009s (-7.0% 🟢) 2.201s (+97.2% 🔺) 0.496s 28 1.12x
💻 Local Express 1.755s (+131.8% 🔺) 2.012s (+95.6% 🔺) 0.011s (+14.6% 🔺) 2.204s (+112.0% 🔺) 0.449s 28 1.15x
🌐 MongoDB Next.js (Turbopack) ⚠️ missing - - - - -
🌐 Redis Next.js (Turbopack) ⚠️ missing - - - - -

▲ Production (Vercel)

World Framework Workflow Time TTFB Slurp Wall Time Overhead Samples vs Fastest
▲ Vercel 🥇 Nitro 5.949s (-79.8% 🟢) 7.135s (-76.8% 🟢) 0.212s (+89.2% 🔺) 7.803s (-75.4% 🟢) 1.855s 8 1.00x
▲ Vercel Next.js (Turbopack) 12.421s (-26.6% 🟢) 12.915s (-29.2% 🟢) 0.180s (-14.7% 🟢) 14.203s (-25.0% 🟢) 1.782s 5 2.09x
▲ Vercel Express ⚠️ missing - - - - -

🔍 Observability: Nitro | Next.js (Turbopack)

10 parallel streams (1MB each)

💻 Local Development

World Framework Workflow Time TTFB Slurp Wall Time Overhead Samples vs Fastest
🐘 Postgres 🥇 Nitro 0.674s (-30.4% 🟢) 1.050s (-15.9% 🟢) 0.000s (-15.8% 🟢) 1.064s (-15.4% 🟢) 0.390s 57 1.00x
🐘 Postgres Express 0.714s (-25.7% 🟢) 1.031s (-19.3% 🟢) 0.000s (-100.0% 🟢) 1.043s (-20.1% 🟢) 0.329s 58 1.06x
🐘 Postgres Next.js (Turbopack) 0.787s 1.035s 0.000s 1.049s 0.262s 58 1.17x
💻 Local Nitro 1.303s (+6.6% 🔺) 2.015s (~) 0.000s (+166.7% 🔺) 2.017s (~) 0.714s 30 1.93x
💻 Local Express 1.426s (+16.4% 🔺) 2.015s (~) 0.000s (-20.0% 🟢) 2.018s (~) 0.591s 30 2.11x
💻 Local Next.js (Turbopack) 1.611s 2.014s 0.000s 2.197s 0.586s 28 2.39x
🌐 MongoDB Next.js (Turbopack) ⚠️ missing - - - - -
🌐 Redis Next.js (Turbopack) ⚠️ missing - - - - -

▲ Production (Vercel)

World Framework Workflow Time TTFB Slurp Wall Time Overhead Samples vs Fastest
▲ Vercel 🥇 Nitro 3.728s (+22.2% 🔺) 4.649s (+5.8% 🔺) 0.001s (+766.7% 🔺) 5.068s (+5.4% 🔺) 1.340s 12 1.00x
▲ Vercel Next.js (Turbopack) 7.287s (-28.4% 🟢) 7.260s (-37.0% 🟢) 0.000s (NaN%) 9.165s (-23.9% 🟢) 1.878s 7 1.95x
▲ Vercel Express ⚠️ missing - - - - -

🔍 Observability: Nitro | Next.js (Turbopack)

fan-out fan-in 10 streams (1MB each)

💻 Local Development

World Framework Workflow Time TTFB Slurp Wall Time Overhead Samples vs Fastest
🐘 Postgres 🥇 Nitro 1.383s (-22.8% 🟢) 2.141s (~) 0.000s (+100.0% 🔺) 2.153s (-1.0%) 0.770s 28 1.00x
🐘 Postgres Express 1.504s (-15.1% 🟢) 2.097s (-3.7%) 0.000s (NaN%) 2.131s (-3.1%) 0.627s 29 1.09x
🐘 Postgres Next.js (Turbopack) 1.667s 2.224s 0.000s 2.233s 0.566s 27 1.21x
💻 Local Next.js (Turbopack) 2.804s 3.361s 0.000s 3.365s 0.561s 18 2.03x
💻 Local Nitro 3.108s (-8.2% 🟢) 3.841s (-4.7%) 0.000s (-18.0% 🟢) 3.843s (-4.8%) 0.735s 16 2.25x
💻 Local Express 3.249s (-6.3% 🟢) 3.842s (-4.7%) 0.001s (-21.9% 🟢) 3.845s (-4.7%) 0.596s 16 2.35x
🌐 MongoDB Next.js (Turbopack) ⚠️ missing - - - - -
🌐 Redis Next.js (Turbopack) ⚠️ missing - - - - -

▲ Production (Vercel)

World Framework Workflow Time TTFB Slurp Wall Time Overhead Samples vs Fastest
▲ Vercel 🥇 Nitro 5.969s (+45.8% 🔺) 7.219s (+34.3% 🔺) 0.000s (-100.0% 🟢) 7.627s (+31.6% 🔺) 1.658s 8 1.00x
▲ Vercel Next.js (Turbopack) 9.307s (+65.7% 🔺) 9.811s (+40.5% 🔺) 0.001s (+300.0% 🔺) 11.072s (+46.8% 🔺) 1.765s 6 1.56x
▲ Vercel Express ⚠️ missing - - - - -

🔍 Observability: Nitro | Next.js (Turbopack)

Summary

Fastest Framework by World

Winner determined by most benchmark wins

World 🥇 Fastest Framework Wins
💻 Local Nitro 15/21
🐘 Postgres Nitro 12/21
▲ Vercel Nitro 18/21
Fastest World by Framework

Winner determined by most benchmark wins

Framework 🥇 Fastest World Wins
Express 🐘 Postgres 19/21
Next.js (Turbopack) 🐘 Postgres 10/21
Nitro 🐘 Postgres 17/21
Column Definitions
  • Workflow Time: Runtime reported by workflow (completedAt - createdAt) - primary metric
  • TTFB: Time to First Byte - time from workflow start until first stream byte received (stream benchmarks only)
  • Slurp: Time from first byte to complete stream consumption (stream benchmarks only)
  • Wall Time: Total testbench time (trigger workflow + poll for result)
  • Overhead: Testbench overhead (Wall Time - Workflow Time)
  • Samples: Number of benchmark iterations run
  • vs Fastest: How much slower compared to the fastest configuration for this benchmark

Worlds:

  • 💻 Local: In-memory filesystem world (local development)
  • 🐘 Postgres: PostgreSQL database world (local development)
  • ▲ Vercel: Vercel production/preview deployment
  • 🌐 Turso: Community world (local development)
  • 🌐 MongoDB: Community world (local development)
  • 🌐 Redis: Community world (local development)
  • 🌐 Jazz: Community world (local development)

📋 View full workflow run


Some benchmark jobs failed:

  • Local: success
  • Postgres: success
  • Vercel: failure

Check the workflow run for details.

Copy link
Copy Markdown
Contributor

@karthikscale3 karthikscale3 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM. Verified it in the SWC playground.

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR adjusts the SWC workflow transform so dead-code elimination runs after nested step hoisting, with the goal of preserving module imports that hoisted step bodies still reference in step-mode output.

Changes:

  • Moves remove_dead_code from visit_mut_module_items to the end of visit_mut_program.
  • Updates existing step-mode fixtures whose hoisted steps now correctly retain required imports.
  • Adds a regression fixture covering nested steps that reference module-level imports.

Reviewed changes

Copilot reviewed 8 out of 8 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
packages/swc-plugin-workflow/transform/tests/fixture/nested-steps-in-object-constructor/output-step.js Updates expected step output to retain an import used by a hoisted nested step.
packages/swc-plugin-workflow/transform/tests/fixture/nested-step-with-closure/output-step.js Updates expected step output to retain an import referenced from hoisted closure-based steps.
packages/swc-plugin-workflow/transform/tests/fixture/nested-step-references-module-import/output-workflow.js Adds workflow-mode regression output for the new nested-import fixture.
packages/swc-plugin-workflow/transform/tests/fixture/nested-step-references-module-import/output-step.js Adds step-mode regression output showing preserved imports for a hoisted nested step.
packages/swc-plugin-workflow/transform/tests/fixture/nested-step-references-module-import/input.js Adds the new regression input covering nested step references to module imports.
packages/swc-plugin-workflow/transform/tests/fixture/factory-with-step-method/output-step.js Updates expected step output to retain an import used by a hoisted step method.
packages/swc-plugin-workflow/transform/src/lib.rs Defers dead-code elimination until after nested step hoisting completes.
.changeset/preserve-imports-used-by-hoisted-steps.md Records the patch release note for the SWC plugin fix.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread packages/swc-plugin-workflow/transform/src/lib.rs
…nctions

Anonymous steps nested inside callback properties of a non-exported workflow function were registered with an unnamespaced step ID in step mode while the workflow-mode proxy looked them up under the workflow function name, causing a runtime 'step not found' failure. Set current_workflow_function_name in visit_mut_fn_decl for non-exported workflow functions to match the behavior in visit_mut_export_decl. Also clarify the fixture comment to distinguish step-mode and workflow-mode behavior per reviewer feedback.
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 8 out of 8 changed files in this pull request and generated 4 comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread packages/swc-plugin-workflow/transform/src/lib.rs
Comment thread .changeset/preserve-imports-used-by-hoisted-steps.md Outdated
…n shapes

Extends the previous fix to cover all three non-exported workflow declaration forms (async function decl, const arrow, const fn-expr) by visiting the workflow body with workflow context before replacing it, and corrects the __internal_workflows manifest comment to report the same prefixed step IDs that are registered at runtime and looked up by the workflow-mode WORKFLOW_USE_STEP proxy. Adds a dedicated regression fixture covering all three shapes.
@TooTallNate TooTallNate enabled auto-merge (squash) May 5, 2026 21:34
@TooTallNate TooTallNate merged commit 1d4f83a into main May 5, 2026
113 of 114 checks passed
@TooTallNate TooTallNate deleted the swc-plugin/preserve-imports-for-hoisted-steps branch May 5, 2026 21:36
github-actions Bot added a commit that referenced this pull request May 5, 2026
* [swc-plugin] Preserve imports referenced by hoisted nested steps

Dead-code elimination ran before nested step functions were hoisted out of workflow bodies, so imports referenced only by hoisted step bodies were incorrectly stripped from the step bundle, causing a ReferenceError at runtime. Move DCE to run after hoisting in visit_mut_program.

* [swc-plugin] Namespace nested step IDs under non-exported workflow functions

Anonymous steps nested inside callback properties of a non-exported workflow function were registered with an unnamespaced step ID in step mode while the workflow-mode proxy looked them up under the workflow function name, causing a runtime 'step not found' failure. Set current_workflow_function_name in visit_mut_fn_decl for non-exported workflow functions to match the behavior in visit_mut_export_decl. Also clarify the fixture comment to distinguish step-mode and workflow-mode behavior per reviewer feedback.

* [swc-plugin] Namespace nested step IDs across all workflow declaration shapes

Extends the previous fix to cover all three non-exported workflow declaration forms (async function decl, const arrow, const fn-expr) by visiting the workflow body with workflow context before replacing it, and corrects the __internal_workflows manifest comment to report the same prefixed step IDs that are registered at runtime and looked up by the workflow-mode WORKFLOW_USE_STEP proxy. Adds a dedicated regression fixture covering all three shapes.

Signed-off-by: Nathan Rajlich <n@n8.io>
@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented May 5, 2026

Backport PR opened against stable: #1946. Merge conflicts were resolved by AI — please review carefully.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants