Skip to content

worker-bundler: host-side assets, no DO wrapper, SW preview proxy#1145

Merged
threepointone merged 5 commits intomainfrom
bundler-fixes
Mar 22, 2026
Merged

worker-bundler: host-side assets, no DO wrapper, SW preview proxy#1145
threepointone merged 5 commits intomainfrom
bundler-fixes

Conversation

@threepointone
Copy link
Contributor

@threepointone threepointone commented Mar 22, 2026

Summary

  • Separate assets from the isolate. createApp returns assets, assetManifest, and assetConfig for host-side serving instead of embedding asset content, manifest, and the ~1000-line asset-handler runtime inside the dynamic isolate. The caller uses handleAssetRequest() + createMemoryStorage() (both already exported) to serve assets before forwarding to the isolate. The isolate only contains the user's server code.

  • Remove DO wrapper code generation. The durableObject option and durableObjectClassName result field are gone, along with generateAppWrapper, generateDOAppWrapper, generateAssetPreamble, and the _asset-runtime-code.ts build step. createApp returns the user's server bundle as mainModule directly — how it's mounted (module worker, DO class, facet) is the caller's concern.

  • Replace preview proxy with Service Worker. The 70-line HTML rewriting + fetch/XHR monkey-patching block is replaced by a 7-line Service Worker that intercepts all requests from the preview iframe and rewrites URLs. Catches everything the old approach missed (CSS url(), dynamic import(), EventSource, etc.). One-time reload on first visit per preview.

  • Add design doc at design/worker-bundler.md covering the two key architectural decisions and their tradeoffs.

Net: -249 lines across the package, simpler build, cleaner separation of concerns.

Test plan

  • All 111 worker-bundler tests pass (asset serving, ETag/304, HTML handling, SPA fallback, client bundling, output structure)
  • npm run check passes (sherif, exports, formatting, linting, typecheck across 65 projects)
  • Preview iframe in playground loads generated apps with correct asset + API routing via SW
  • Multiple simultaneous previews don't interfere (separate SW scopes)

Made with Cursor


Open with Devin

Change createApp to return assets separately for host-side serving instead of embedding asset modules/runtime in the isolate. Remove generated asset runtime and durable-object wrapper generation; server bundle is returned directly (mainModule/modules) and assets + assetManifest are provided for the host to serve via handleAssetRequest/createMemoryStorage. Update README, add design doc (design/worker-bundler.md), adjust the playground and tests to use handleAssetRequest and createMemoryStorage, and simplify the build script by removing the asset runtime bundling step. Also remove the generated _asset-runtime-code artifact from .gitignore.
Add an embeddable service worker (PREVIEW_SW) that rewrites same-origin requests to the preview prefix and claim clients on activation. Serve the SW at /preview/:name/sw.js and inject an idempotent navigator.serviceWorker.register script into HTML responses so iframes auto-register the SW and reload once it takes control. Remove the prior HTML attribute rewrites and runtime fetch/XHR patching in favor of the scope-based SW approach, and preserve original response headers/status when returning the modified HTML.
@changeset-bot
Copy link

changeset-bot bot commented Mar 22, 2026

🦋 Changeset detected

Latest commit: 8a4b4e6

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

This PR includes changesets to release 1 package
Name Type
@cloudflare/worker-bundler 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

devin-ai-integration[bot]

This comment was marked as resolved.

@pkg-pr-new
Copy link

pkg-pr-new bot commented Mar 22, 2026

Open in StackBlitz

agents

npm i https://pkg.pr.new/agents@1145

@cloudflare/ai-chat

npm i https://pkg.pr.new/@cloudflare/ai-chat@1145

@cloudflare/codemode

npm i https://pkg.pr.new/@cloudflare/codemode@1145

hono-agents

npm i https://pkg.pr.new/hono-agents@1145

@cloudflare/shell

npm i https://pkg.pr.new/@cloudflare/shell@1145

@cloudflare/think

npm i https://pkg.pr.new/@cloudflare/think@1145

@cloudflare/voice

npm i https://pkg.pr.new/@cloudflare/voice@1145

@cloudflare/worker-bundler

npm i https://pkg.pr.new/@cloudflare/worker-bundler@1145

commit: 8a4b4e6

The delay-0 alarm would auto-fire between RPC calls, causing
getStatus() to hit a destroyed DO. Use a future delay so the alarm
only fires when runDurableObjectAlarm triggers it manually, and
return status from the scheduling call itself to avoid the race.

Made-with: Cursor
@threepointone threepointone merged commit 94fac05 into main Mar 22, 2026
2 checks passed
@threepointone threepointone deleted the bundler-fixes branch March 22, 2026 11:57
@github-actions github-actions bot mentioned this pull request Mar 22, 2026
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.

1 participant