feat(host-cloudflare): adopt dynamic-worker engine, retire QuickJS#15
feat(host-cloudflare): adopt dynamic-worker engine, retire QuickJS#15amondnet wants to merge 3 commits into
Conversation
Worker Loaders (Dynamic Workers) reached open beta on 2026-03-24, lifting the closed-beta constraint that kept host-cloudflare on the interim QuickJS-WASM substrate. Swap the engine seam to the dynamic-worker executor (the same one apps/cloud uses) behind the existing CodeExecutor seam. - wrangler.jsonc: add the worker_loaders LOADER binding - config.ts: add LOADER: WorkerLoader to CloudflareEnv; bump workers-types - execution.ts: makeCloudflareCodeExecutorProvider(loader) wraps makeDynamicWorkerExecutor; thread the loader through the stack layer - app.ts / session-durable-object.ts: pass env.LOADER explicitly (the host's per-request binding pattern, not cloud's ambient cloudflare:workers env) - remove QuickJS entirely: quickjs.ts, the vendored quickjs-engine.wasm, the vendor-wasm script, and the runtime-quickjs / quickjs-emscripten deps - refresh the stale README seam table (engine + DO-backed mcp session) and the closed-beta comments This gains structured-clone fidelity at the tool boundary (Blob/File/ Uint8Array, Date/Map/Set), nodejs_compat, and isolate-level isolation. Worker Loaders requires a paid Workers plan. Closes #12
|
Note Currently processing new changes in this PR. This may take a few minutes, please wait... ⚙️ Run configurationConfiguration used: Organization UI Review profile: CHILL Plan: Pro Plus Run ID: ⛔ Files ignored due to path filters (2)
📒 Files selected for processing (11)
✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
⚔️ Resolve merge conflicts
Comment |
There was a problem hiding this comment.
Code Review
This pull request replaces the in-process QuickJS-WASM execution engine with the dynamic-worker executor using Cloudflare's Worker Loaders via the LOADER binding, which enables structured-clone fidelity and Node.js compatibility. The review feedback recommends adding runtime validation for the LOADER binding to prevent unexpected failures if the binding is missing or undefined.
Greptile SummaryThis PR replaces the QuickJS-WASM in-process code substrate for
Confidence Score: 5/5Safe to merge. The engine swap is confined entirely to apps/host-cloudflare, all changed call-sites pass env.LOADER consistently, and the fail-fast guard at boot surfaces a missing binding before any execution is attempted. Every seam that previously touched QuickJS has been updated: the executor provider, the execution stack layer, the DO constructor path, app initialization, wrangler config, and docs. The LOADER binding is threaded explicitly rather than captured in module scope, matching the established host pattern. Tests cover both the REST execution path and the MCP path end-to-end on real workerd, including a nodejs_compat regression guard that could not pass on the old engine. No files require special attention. Important Files Changed
Sequence Diagram%%{init: {'theme': 'neutral'}}%%
sequenceDiagram
participant Client
participant Worker as Cloudflare Worker
participant DO as McpSessionDO
participant Loader as LOADER (WorkerLoader)
participant Isolate as Fresh workerd Isolate
Note over Worker: makeCloudflareApp(env)<br/>makeCloudflareCodeExecutorProvider(env.LOADER)
Client->>Worker: POST /api/executions
Worker->>Loader: load(code)
Loader->>Isolate: spawn fresh workerd isolate
Isolate-->>Loader: result
Loader-->>Worker: structured-clone result
Worker-->>Client: "{ status, text }"
Client->>Worker: POST /mcp (initialize)
Worker->>DO: stub.fetch() via MCP_SESSION
Note over DO: buildMcpServer(meta, dbHandle)<br/>makeCloudflareExecutionStackLayer(config, dbHandle, cfEnv.LOADER)
DO->>Loader: load(code) on tools/call
Loader->>Isolate: spawn fresh workerd isolate
Isolate-->>Loader: result
Loader-->>DO: structured-clone result
DO-->>Client: MCP tool result
%%{init: {'theme': 'base', 'themeVariables': {"darkMode": true, "background": "#0d1117", "primaryColor": "#21262d", "primaryTextColor": "#e6edf3", "primaryBorderColor": "#8b949e", "lineColor": "#8b949e", "textColor": "#e6edf3", "edgeLabelBackground": "#161b22", "actorBkg": "#21262d", "actorBorder": "#8b949e", "actorTextColor": "#e6edf3", "actorLineColor": "#8b949e", "signalColor": "#8b949e", "signalTextColor": "#e6edf3", "noteBkgColor": "#373320", "noteBorderColor": "#d4a72c", "noteTextColor": "#f0e6c0", "labelBoxBkgColor": "#21262d", "labelBoxBorderColor": "#8b949e", "labelTextColor": "#e6edf3", "loopTextColor": "#e6edf3", "activationBkgColor": "#30363d", "activationBorderColor": "#8b949e"}}}%%
sequenceDiagram
participant Client
participant Worker as Cloudflare Worker
participant DO as McpSessionDO
participant Loader as LOADER (WorkerLoader)
participant Isolate as Fresh workerd Isolate
Note over Worker: makeCloudflareApp(env)<br/>makeCloudflareCodeExecutorProvider(env.LOADER)
Client->>Worker: POST /api/executions
Worker->>Loader: load(code)
Loader->>Isolate: spawn fresh workerd isolate
Isolate-->>Loader: result
Loader-->>Worker: structured-clone result
Worker-->>Client: "{ status, text }"
Client->>Worker: POST /mcp (initialize)
Worker->>DO: stub.fetch() via MCP_SESSION
Note over DO: buildMcpServer(meta, dbHandle)<br/>makeCloudflareExecutionStackLayer(config, dbHandle, cfEnv.LOADER)
DO->>Loader: load(code) on tools/call
Loader->>Isolate: spawn fresh workerd isolate
Isolate-->>Loader: result
Loader-->>DO: structured-clone result
DO-->>Client: MCP tool result
Reviews (2): Last reviewed commit: "chore(host-cloudflare): guard against a ..." | Re-trigger Greptile |
…pting-dynamic-worker-engine-for-host # Conflicts: # apps/host-cloudflare/wrangler.jsonc
Apply review feedback: makeDynamicWorkerExecutor only reads the loader on the first execute, so a missing binding would surface as an opaque defect mid-execution. Fail at app boot with an actionable message instead.
There was a problem hiding this comment.
0 issues found across 1 file (changes from recent commits).
Requires human review: Swaps core execution engine from QuickJS to dynamic-worker, adds new LOADER binding, and updates config/deps. High-risk infrastructure and business logic change requiring human review.
Re-trigger cubic
Summary
Cloudflare Worker Loaders (Dynamic Workers) reached open beta on 2026-03-24, lifting the closed-beta constraint that kept
apps/host-cloudflareon the interim QuickJS-WASM substrate. This swaps theengineseam to thedynamic-workerexecutor (the same oneapps/clouduses) behind the existingCodeExecutorseam, the "one-Layer change" the prior code comment described, and retires QuickJS entirely for this host.What changed
wrangler.jsonc: add theworker_loadersLOADERbinding.config.ts: addLOADER: WorkerLoadertoCloudflareEnv; bump@cloudflare/workers-typesto the version carrying theWorkerLoadertype.execution.ts:makeCloudflareCodeExecutorProvider(loader)wrapsmakeDynamicWorkerExecutor; the executor stack layer threads the loader.app.ts/session-durable-object.ts: passenv.LOADERexplicitly (the host's per-request binding pattern, not cloud's ambientcloudflare:workersenv); drop the QuickJS preload.quickjs.ts, the vendoredquickjs-engine.wasm, the vendor-wasm script, and theruntime-quickjs/quickjs-emscriptendeps.Why
The dynamic-worker runtime gains capability QuickJS could not provide: structured-clone fidelity at the tool boundary (
Blob/File/Uint8Array,Date/Map/Set),nodejs_compat, configurable outbound, and isolate-level isolation. It also converges host-cloudflare onto the same single engine as cloud.Verification
typecheck(0 errors),lint(0),format:check(clean).apps/host-cloudflaretests: 3 files / 13 tests pass on real workerd + Miniflare (unstable_dev) with theLOADERbinding, covering/api/executions, MCPexecute, DO session survival, and a newBuffer/nodejs_compatcapability test (impossible on QuickJS, so it doubles as a regression guard).--project cloudflare:browser-approvaland the newly-wiredmcp-execute(OAuth-connect then run code in the sandbox) pass.Note on the e2e suite
scenarios/microsoft-graph-full.test.tstimes out at its 300s limit in this environment, but this is pre-existing and unrelated: it does not touch the engine seam (it fetches and parses the full ~37MB Graph spec over the network), and it times out identically with this change reverted. Removing the QuickJS WASM module from the main isolate only reduces its memory footprint.Deployment requirement
Worker Loaders open beta requires a paid Workers plan.
Closes #12
Summary by cubic
Cloudflare 호스트의 실행 엔진을 QuickJS‑WASM에서 동적 워커 엔진(Worker Loaders)로 전환했습니다. 구조화된 복제와
nodejs_compat를 지원하며,LOADER누락 시 부팅 단계에서 명확한 오류로 가드합니다.wrangler.jsonc에worker_loaders바인딩 추가:[{ "binding": "LOADER" }].LOADER: WorkerLoader필요.scripts/vendor-quickjs-wasm.ts,src/quickjs-engine.wasm,src/quickjs.ts,@executor-js/runtime-quickjs,quickjs-emscripten-core,@jitl/quickjs-wasmfile-release-sync.@executor-js/runtime-dynamic-worker.@cloudflare/workers-types최신으로 상향.How to test
wrangler.jsonc에worker_loaders바인딩 추가 후 배포 또는 로컬 실행(wrangler unstable_dev또는wrangler dev).POST /api/executions에export default 6 * 7전송 → 결과42.export default Buffer.from("hello").toString("base64")→aGVsbG8=응답.tools/list와tools/call로execute가 동적 워커 엔진에서 실행되는지 확인.Written for commit f9037f5. Summary will update on new commits.
Summary by CodeRabbit
새 기능
버그 수정