@nimbus-sh/worker 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +219 -0
- package/dist/_shared/bytes.d.ts +18 -0
- package/dist/_shared/bytes.d.ts.map +1 -0
- package/dist/_shared/bytes.js +17 -0
- package/dist/_shared/cache-stats.d.ts +146 -0
- package/dist/_shared/cache-stats.d.ts.map +1 -0
- package/dist/_shared/cache-stats.js +162 -0
- package/dist/_shared/exports-resolver.d.ts +76 -0
- package/dist/_shared/exports-resolver.d.ts.map +1 -0
- package/dist/_shared/exports-resolver.js +284 -0
- package/dist/_shared/install-phase.d.ts +47 -0
- package/dist/_shared/install-phase.d.ts.map +1 -0
- package/dist/_shared/install-phase.js +1 -0
- package/dist/_shared/real-node-imports.d.ts +38 -0
- package/dist/_shared/real-node-imports.d.ts.map +1 -0
- package/dist/_shared/real-node-imports.js +46 -0
- package/dist/_shared/retry.d.ts +93 -0
- package/dist/_shared/retry.d.ts.map +1 -0
- package/dist/_shared/retry.js +161 -0
- package/dist/_shared/session-id.d.ts +39 -0
- package/dist/_shared/session-id.d.ts.map +1 -0
- package/dist/_shared/session-id.js +127 -0
- package/dist/_shared/session-router.d.ts +104 -0
- package/dist/_shared/session-router.d.ts.map +1 -0
- package/dist/_shared/session-router.js +165 -0
- package/dist/_shared/w7-frame.d.ts +93 -0
- package/dist/_shared/w7-frame.d.ts.map +1 -0
- package/dist/_shared/w7-frame.js +402 -0
- package/dist/auth/index.d.ts +16 -0
- package/dist/auth/index.d.ts.map +1 -0
- package/dist/auth/index.js +15 -0
- package/dist/auth/middleware.d.ts +85 -0
- package/dist/auth/middleware.d.ts.map +1 -0
- package/dist/auth/middleware.js +150 -0
- package/dist/auth/token.d.ts +96 -0
- package/dist/auth/token.d.ts.map +1 -0
- package/dist/auth/token.js +226 -0
- package/dist/auth/types.d.ts +141 -0
- package/dist/auth/types.d.ts.map +1 -0
- package/dist/auth/types.js +114 -0
- package/dist/bindings/d1.d.ts +102 -0
- package/dist/bindings/d1.d.ts.map +1 -0
- package/dist/bindings/d1.js +549 -0
- package/dist/bindings/kv.d.ts +82 -0
- package/dist/bindings/kv.d.ts.map +1 -0
- package/dist/bindings/kv.js +290 -0
- package/dist/bindings/r2.d.ts +137 -0
- package/dist/bindings/r2.d.ts.map +1 -0
- package/dist/bindings/r2.js +379 -0
- package/dist/cirrus-npm-cjs.generated.d.ts +17 -0
- package/dist/cirrus-npm-cjs.generated.d.ts.map +1 -0
- package/dist/cirrus-npm-cjs.generated.js +41 -0
- package/dist/cirrus-plugin-react.generated.d.ts +34 -0
- package/dist/cirrus-plugin-react.generated.d.ts.map +1 -0
- package/dist/cirrus-plugin-react.generated.js +33 -0
- package/dist/constants.d.ts +34 -0
- package/dist/constants.d.ts.map +1 -0
- package/dist/constants.js +116 -0
- package/dist/esbuild-wasm-bundle.generated.d.ts +41 -0
- package/dist/esbuild-wasm-bundle.generated.d.ts.map +1 -0
- package/dist/esbuild-wasm-bundle.generated.js +40 -0
- package/dist/facets/cirrus-real.d.ts +147 -0
- package/dist/facets/cirrus-real.d.ts.map +1 -0
- package/dist/facets/cirrus-real.js +981 -0
- package/dist/facets/inner-do-registry.d.ts +41 -0
- package/dist/facets/inner-do-registry.d.ts.map +1 -0
- package/dist/facets/inner-do-registry.js +51 -0
- package/dist/facets/manager.d.ts +314 -0
- package/dist/facets/manager.d.ts.map +1 -0
- package/dist/facets/manager.js +2681 -0
- package/dist/facets/process.d.ts +318 -0
- package/dist/facets/process.d.ts.map +1 -0
- package/dist/facets/process.js +567 -0
- package/dist/facets/real-vite-fs-shim.d.ts +151 -0
- package/dist/facets/real-vite-fs-shim.d.ts.map +1 -0
- package/dist/facets/real-vite-fs-shim.js +1279 -0
- package/dist/facets/real-vite-hmr.d.ts +142 -0
- package/dist/facets/real-vite-hmr.d.ts.map +1 -0
- package/dist/facets/real-vite-hmr.js +476 -0
- package/dist/facets/vite-dev-server.d.ts +293 -0
- package/dist/facets/vite-dev-server.d.ts.map +1 -0
- package/dist/facets/vite-dev-server.js +2580 -0
- package/dist/facets/wasm-swap-registry.d.ts +261 -0
- package/dist/facets/wasm-swap-registry.d.ts.map +1 -0
- package/dist/facets/wasm-swap-registry.js +551 -0
- package/dist/facets/ws-terminal.d.ts +107 -0
- package/dist/facets/ws-terminal.d.ts.map +1 -0
- package/dist/facets/ws-terminal.js +207 -0
- package/dist/git/commands.d.ts +13 -0
- package/dist/git/commands.d.ts.map +1 -0
- package/dist/git/commands.js +633 -0
- package/dist/git/network-facet.d.ts +61 -0
- package/dist/git/network-facet.d.ts.map +1 -0
- package/dist/git/network-facet.js +700 -0
- package/dist/git-bundle.generated.d.ts +16 -0
- package/dist/git-bundle.generated.d.ts.map +1 -0
- package/dist/git-bundle.generated.js +15 -0
- package/dist/index.d.ts +41 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +73 -0
- package/dist/loaders/child-process/spawn-facet.d.ts +90 -0
- package/dist/loaders/child-process/spawn-facet.d.ts.map +1 -0
- package/dist/loaders/child-process/spawn-facet.js +103 -0
- package/dist/loaders/child-process/spawn-pool.d.ts +110 -0
- package/dist/loaders/child-process/spawn-pool.d.ts.map +1 -0
- package/dist/loaders/child-process/spawn-pool.js +161 -0
- package/dist/loaders/fanout-pool.d.ts +195 -0
- package/dist/loaders/fanout-pool.d.ts.map +1 -0
- package/dist/loaders/fanout-pool.js +326 -0
- package/dist/loaders/generated-workers.d.ts +26 -0
- package/dist/loaders/generated-workers.d.ts.map +1 -0
- package/dist/loaders/generated-workers.js +25 -0
- package/dist/loaders/index.d.ts +15 -0
- package/dist/loaders/index.d.ts.map +1 -0
- package/dist/loaders/index.js +13 -0
- package/dist/loaders/loader-pool.d.ts +273 -0
- package/dist/loaders/loader-pool.d.ts.map +1 -0
- package/dist/loaders/loader-pool.js +624 -0
- package/dist/loaders/npm-resolve-preamble.d.ts +34 -0
- package/dist/loaders/npm-resolve-preamble.d.ts.map +1 -0
- package/dist/loaders/npm-resolve-preamble.js +237 -0
- package/dist/loaders/pre-bundle-preamble.d.ts +41 -0
- package/dist/loaders/pre-bundle-preamble.d.ts.map +1 -0
- package/dist/loaders/pre-bundle-preamble.js +114 -0
- package/dist/loaders/vendor/codegen.d.ts +24 -0
- package/dist/loaders/vendor/codegen.d.ts.map +1 -0
- package/dist/loaders/vendor/codegen.js +44 -0
- package/dist/loaders/vendor/errors.d.ts +24 -0
- package/dist/loaders/vendor/errors.d.ts.map +1 -0
- package/dist/loaders/vendor/errors.js +46 -0
- package/dist/loaders/vendor/index.d.ts +16 -0
- package/dist/loaders/vendor/index.d.ts.map +1 -0
- package/dist/loaders/vendor/index.js +11 -0
- package/dist/loaders/vendor/pool.d.ts +88 -0
- package/dist/loaders/vendor/pool.d.ts.map +1 -0
- package/dist/loaders/vendor/pool.js +353 -0
- package/dist/loaders/vendor/primitives.d.ts +11 -0
- package/dist/loaders/vendor/primitives.d.ts.map +1 -0
- package/dist/loaders/vendor/primitives.js +33 -0
- package/dist/loaders/vendor/serialize.d.ts +3 -0
- package/dist/loaders/vendor/serialize.d.ts.map +1 -0
- package/dist/loaders/vendor/serialize.js +25 -0
- package/dist/loaders/vendor/types.d.ts +60 -0
- package/dist/loaders/vendor/types.d.ts.map +1 -0
- package/dist/loaders/vendor/types.js +4 -0
- package/dist/npm/cache.d.ts +136 -0
- package/dist/npm/cache.d.ts.map +1 -0
- package/dist/npm/cache.js +429 -0
- package/dist/npm/install-batch-facet.d.ts +129 -0
- package/dist/npm/install-batch-facet.d.ts.map +1 -0
- package/dist/npm/install-batch-facet.js +598 -0
- package/dist/npm/install-facet.d.ts +29 -0
- package/dist/npm/install-facet.d.ts.map +1 -0
- package/dist/npm/install-facet.js +9 -0
- package/dist/npm/installer.d.ts +239 -0
- package/dist/npm/installer.d.ts.map +1 -0
- package/dist/npm/installer.js +2022 -0
- package/dist/npm/npx-install.d.ts +74 -0
- package/dist/npm/npx-install.d.ts.map +1 -0
- package/dist/npm/npx-install.js +302 -0
- package/dist/npm/pre-bundle-facet.d.ts +168 -0
- package/dist/npm/pre-bundle-facet.d.ts.map +1 -0
- package/dist/npm/pre-bundle-facet.js +653 -0
- package/dist/npm/r2-cache.d.ts +286 -0
- package/dist/npm/r2-cache.d.ts.map +1 -0
- package/dist/npm/r2-cache.js +506 -0
- package/dist/npm/resolve-facet.d.ts +202 -0
- package/dist/npm/resolve-facet.d.ts.map +1 -0
- package/dist/npm/resolve-facet.js +833 -0
- package/dist/npm/resolve-one-facet.d.ts +204 -0
- package/dist/npm/resolve-one-facet.d.ts.map +1 -0
- package/dist/npm/resolve-one-facet.js +437 -0
- package/dist/npm/resolver.d.ts +109 -0
- package/dist/npm/resolver.d.ts.map +1 -0
- package/dist/npm/resolver.js +899 -0
- package/dist/npm/tarball-stream.d.ts +85 -0
- package/dist/npm/tarball-stream.d.ts.map +1 -0
- package/dist/npm/tarball-stream.js +205 -0
- package/dist/npm/tarball.d.ts +51 -0
- package/dist/npm/tarball.d.ts.map +1 -0
- package/dist/npm/tarball.js +185 -0
- package/dist/observability/diag-counters.d.ts +292 -0
- package/dist/observability/diag-counters.d.ts.map +1 -0
- package/dist/observability/diag-counters.js +302 -0
- package/dist/observability/heap-estimate.d.ts +166 -0
- package/dist/observability/heap-estimate.d.ts.map +1 -0
- package/dist/observability/heap-estimate.js +192 -0
- package/dist/observability/heavy-alloc-coord.d.ts +95 -0
- package/dist/observability/heavy-alloc-coord.d.ts.map +1 -0
- package/dist/observability/heavy-alloc-coord.js +149 -0
- package/dist/observability/oom-classify.d.ts +56 -0
- package/dist/observability/oom-classify.d.ts.map +1 -0
- package/dist/observability/oom-classify.js +118 -0
- package/dist/observability/oom-discriminator.d.ts +192 -0
- package/dist/observability/oom-discriminator.d.ts.map +1 -0
- package/dist/observability/oom-discriminator.js +233 -0
- package/dist/real-vite-bundle.generated.d.ts +46 -0
- package/dist/real-vite-bundle.generated.d.ts.map +1 -0
- package/dist/real-vite-bundle.generated.js +53 -0
- package/dist/replica/routing.d.ts +171 -0
- package/dist/replica/routing.d.ts.map +1 -0
- package/dist/replica/routing.js +288 -0
- package/dist/replica/suspension.d.ts +36 -0
- package/dist/replica/suspension.d.ts.map +1 -0
- package/dist/replica/suspension.js +49 -0
- package/dist/router/index.d.ts +156 -0
- package/dist/router/index.d.ts.map +1 -0
- package/dist/router/index.js +220 -0
- package/dist/runtime/assets-loader.d.ts +71 -0
- package/dist/runtime/assets-loader.d.ts.map +1 -0
- package/dist/runtime/assets-loader.js +128 -0
- package/dist/runtime/barrel-detect.d.ts +46 -0
- package/dist/runtime/barrel-detect.d.ts.map +1 -0
- package/dist/runtime/barrel-detect.js +73 -0
- package/dist/runtime/barrel-synthesizer.d.ts +181 -0
- package/dist/runtime/barrel-synthesizer.d.ts.map +1 -0
- package/dist/runtime/barrel-synthesizer.js +541 -0
- package/dist/runtime/bun-repl.d.ts +46 -0
- package/dist/runtime/bun-repl.d.ts.map +1 -0
- package/dist/runtime/bun-repl.js +326 -0
- package/dist/runtime/bun-runner.d.ts +66 -0
- package/dist/runtime/bun-runner.d.ts.map +1 -0
- package/dist/runtime/bun-runner.js +219 -0
- package/dist/runtime/clang-runner.d.ts +38 -0
- package/dist/runtime/clang-runner.d.ts.map +1 -0
- package/dist/runtime/clang-runner.js +1033 -0
- package/dist/runtime/comment-strip.d.ts +37 -0
- package/dist/runtime/comment-strip.d.ts.map +1 -0
- package/dist/runtime/comment-strip.js +74 -0
- package/dist/runtime/esbuild-service.d.ts +201 -0
- package/dist/runtime/esbuild-service.d.ts.map +1 -0
- package/dist/runtime/esbuild-service.js +1444 -0
- package/dist/runtime/esbuild-wasm-bytes.d.ts +87 -0
- package/dist/runtime/esbuild-wasm-bytes.d.ts.map +1 -0
- package/dist/runtime/esbuild-wasm-bytes.js +131 -0
- package/dist/runtime/framework-detect.d.ts +71 -0
- package/dist/runtime/framework-detect.d.ts.map +1 -0
- package/dist/runtime/framework-detect.js +178 -0
- package/dist/runtime/long-running-handle.d.ts +133 -0
- package/dist/runtime/long-running-handle.d.ts.map +1 -0
- package/dist/runtime/long-running-handle.js +192 -0
- package/dist/runtime/node-repl.d.ts +36 -0
- package/dist/runtime/node-repl.d.ts.map +1 -0
- package/dist/runtime/node-repl.js +293 -0
- package/dist/runtime/node-runner.d.ts +111 -0
- package/dist/runtime/node-runner.d.ts.map +1 -0
- package/dist/runtime/node-runner.js +194 -0
- package/dist/runtime/node-shims.d.ts +24 -0
- package/dist/runtime/node-shims.d.ts.map +1 -0
- package/dist/runtime/node-shims.js +3019 -0
- package/dist/runtime/package-manager.d.ts +118 -0
- package/dist/runtime/package-manager.d.ts.map +1 -0
- package/dist/runtime/package-manager.js +420 -0
- package/dist/runtime/port-registry.d.ts +80 -0
- package/dist/runtime/port-registry.d.ts.map +1 -0
- package/dist/runtime/port-registry.js +166 -0
- package/dist/runtime/process-logs-api.d.ts +102 -0
- package/dist/runtime/process-logs-api.d.ts.map +1 -0
- package/dist/runtime/process-logs-api.js +253 -0
- package/dist/runtime/process-logs.d.ts +311 -0
- package/dist/runtime/process-logs.d.ts.map +1 -0
- package/dist/runtime/process-logs.js +656 -0
- package/dist/runtime/process-table.d.ts +65 -0
- package/dist/runtime/process-table.d.ts.map +1 -0
- package/dist/runtime/process-table.js +107 -0
- package/dist/runtime/project-detect.d.ts +21 -0
- package/dist/runtime/project-detect.d.ts.map +1 -0
- package/dist/runtime/project-detect.js +46 -0
- package/dist/runtime/python-repl.d.ts +66 -0
- package/dist/runtime/python-repl.d.ts.map +1 -0
- package/dist/runtime/python-repl.js +563 -0
- package/dist/runtime/python-runner.d.ts +50 -0
- package/dist/runtime/python-runner.d.ts.map +1 -0
- package/dist/runtime/python-runner.js +870 -0
- package/dist/runtime/repl-session.d.ts +160 -0
- package/dist/runtime/repl-session.d.ts.map +1 -0
- package/dist/runtime/repl-session.js +393 -0
- package/dist/runtime/require-resolver.d.ts +52 -0
- package/dist/runtime/require-resolver.d.ts.map +1 -0
- package/dist/runtime/require-resolver.js +690 -0
- package/dist/runtime/router-basename.d.ts +36 -0
- package/dist/runtime/router-basename.d.ts.map +1 -0
- package/dist/runtime/router-basename.js +310 -0
- package/dist/runtime/ruby-repl.d.ts +43 -0
- package/dist/runtime/ruby-repl.d.ts.map +1 -0
- package/dist/runtime/ruby-repl.js +229 -0
- package/dist/runtime/ruby-runner.d.ts +62 -0
- package/dist/runtime/ruby-runner.d.ts.map +1 -0
- package/dist/runtime/ruby-runner.js +737 -0
- package/dist/runtime/runtime-catalog.d.ts +99 -0
- package/dist/runtime/runtime-catalog.d.ts.map +1 -0
- package/dist/runtime/runtime-catalog.js +183 -0
- package/dist/runtime/runtime-registry.d.ts +136 -0
- package/dist/runtime/runtime-registry.d.ts.map +1 -0
- package/dist/runtime/runtime-registry.js +318 -0
- package/dist/runtime/streams.d.ts +13 -0
- package/dist/runtime/streams.d.ts.map +1 -0
- package/dist/runtime/streams.js +402 -0
- package/dist/runtime/wasi-instance.d.ts +190 -0
- package/dist/runtime/wasi-instance.d.ts.map +1 -0
- package/dist/runtime/wasi-instance.js +2044 -0
- package/dist/runtime/wasm-runner.d.ts +117 -0
- package/dist/runtime/wasm-runner.d.ts.map +1 -0
- package/dist/runtime/wasm-runner.js +705 -0
- package/dist/session/bindings.d.ts +168 -0
- package/dist/session/bindings.d.ts.map +1 -0
- package/dist/session/bindings.js +524 -0
- package/dist/session/ctx-exports.d.ts +16 -0
- package/dist/session/ctx-exports.d.ts.map +1 -0
- package/dist/session/ctx-exports.js +22 -0
- package/dist/session/diag.d.ts +62 -0
- package/dist/session/diag.d.ts.map +1 -0
- package/dist/session/diag.js +118 -0
- package/dist/session/fs-watch.d.ts +132 -0
- package/dist/session/fs-watch.d.ts.map +1 -0
- package/dist/session/fs-watch.js +255 -0
- package/dist/session/helpers.d.ts +150 -0
- package/dist/session/helpers.d.ts.map +1 -0
- package/dist/session/helpers.js +472 -0
- package/dist/session/hibernation.d.ts +145 -0
- package/dist/session/hibernation.d.ts.map +1 -0
- package/dist/session/hibernation.js +385 -0
- package/dist/session/init-phases.d.ts +87 -0
- package/dist/session/init-phases.d.ts.map +1 -0
- package/dist/session/init-phases.js +137 -0
- package/dist/session/init.d.ts +46 -0
- package/dist/session/init.d.ts.map +1 -0
- package/dist/session/init.js +3579 -0
- package/dist/session/keys.d.ts +56 -0
- package/dist/session/keys.d.ts.map +1 -0
- package/dist/session/keys.js +55 -0
- package/dist/session/nimbus-session.d.ts +434 -0
- package/dist/session/nimbus-session.d.ts.map +1 -0
- package/dist/session/nimbus-session.js +1084 -0
- package/dist/session/programmatic.d.ts +105 -0
- package/dist/session/programmatic.d.ts.map +1 -0
- package/dist/session/programmatic.js +326 -0
- package/dist/session/replica-routes.d.ts +68 -0
- package/dist/session/replica-routes.d.ts.map +1 -0
- package/dist/session/replica-routes.js +77 -0
- package/dist/session/routes.d.ts +29 -0
- package/dist/session/routes.d.ts.map +1 -0
- package/dist/session/routes.js +1331 -0
- package/dist/session/rpc.d.ts +323 -0
- package/dist/session/rpc.d.ts.map +1 -0
- package/dist/session/rpc.js +808 -0
- package/dist/session/state-store.d.ts +210 -0
- package/dist/session/state-store.d.ts.map +1 -0
- package/dist/session/state-store.js +459 -0
- package/dist/session/supervisor-rpc.d.ts +269 -0
- package/dist/session/supervisor-rpc.d.ts.map +1 -0
- package/dist/session/supervisor-rpc.js +437 -0
- package/dist/session/ws-hibernation-config.d.ts +64 -0
- package/dist/session/ws-hibernation-config.d.ts.map +1 -0
- package/dist/session/ws-hibernation-config.js +89 -0
- package/dist/session/ws.d.ts +95 -0
- package/dist/session/ws.d.ts.map +1 -0
- package/dist/session/ws.js +395 -0
- package/dist/shell/features.d.ts +410 -0
- package/dist/shell/features.d.ts.map +1 -0
- package/dist/shell/features.js +1885 -0
- package/dist/shell/unix-commands.d.ts +15 -0
- package/dist/shell/unix-commands.d.ts.map +1 -0
- package/dist/shell/unix-commands.js +3703 -0
- package/dist/stubs/lifo-ui.d.ts +10 -0
- package/dist/stubs/lifo-ui.d.ts.map +1 -0
- package/dist/stubs/lifo-ui.js +1 -0
- package/dist/tailwind-play.generated.d.ts +19 -0
- package/dist/tailwind-play.generated.d.ts.map +1 -0
- package/dist/tailwind-play.generated.js +18 -0
- package/dist/vfs/dev-provider.d.ts +64 -0
- package/dist/vfs/dev-provider.d.ts.map +1 -0
- package/dist/vfs/dev-provider.js +191 -0
- package/dist/vfs/events.d.ts +51 -0
- package/dist/vfs/events.d.ts.map +1 -0
- package/dist/vfs/events.js +127 -0
- package/dist/vfs/path.d.ts +30 -0
- package/dist/vfs/path.d.ts.map +1 -0
- package/dist/vfs/path.js +41 -0
- package/dist/vfs/seed-project.d.ts +62 -0
- package/dist/vfs/seed-project.d.ts.map +1 -0
- package/dist/vfs/seed-project.js +1045 -0
- package/dist/vfs/sqlite-vfs.d.ts +435 -0
- package/dist/vfs/sqlite-vfs.d.ts.map +1 -0
- package/dist/vfs/sqlite-vfs.js +1670 -0
- package/dist/vfs/symlink-registry.d.ts +64 -0
- package/dist/vfs/symlink-registry.d.ts.map +1 -0
- package/dist/vfs/symlink-registry.js +137 -0
- package/dist/wrangler/nimbus-wrangler.d.ts +157 -0
- package/dist/wrangler/nimbus-wrangler.d.ts.map +1 -0
- package/dist/wrangler/nimbus-wrangler.js +931 -0
- package/package.json +77 -0
- package/public/_assets/cirrus-plugin-react.bundle.js +70740 -0
- package/public/_assets/esbuild-0.24.2.wasm +0 -0
- package/public/_assets/real-vite-bundle.js +101478 -0
- package/public/_assets/rollup.wasm +0 -0
- package/public/favicon.svg +8 -0
- package/public/index.html +565 -0
- package/public/s/index.html +2379 -0
- package/scripts/bundle-esbuild-wasm.mjs +244 -0
- package/scripts/bundle-facet-workers.mjs +137 -0
- package/scripts/bundle-git.mjs +118 -0
- package/scripts/bundle-npm-cjs.mjs +363 -0
- package/scripts/bundle-plugin-react.mjs +480 -0
- package/scripts/bundle-real-vite.mjs +959 -0
- package/scripts/bundle-runtime.mjs +600 -0
- package/scripts/bundle-tailwind-play.mjs +130 -0
- package/scripts/patch-lifo-ui.mjs +131 -0
|
@@ -0,0 +1,600 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* scripts/bundle-runtime.mjs — ingest an upstream runtime into the
|
|
4
|
+
* `nimbus-runtime-cache` R2 bucket.
|
|
5
|
+
*
|
|
6
|
+
* Invocation:
|
|
7
|
+
* node scripts/bundle-runtime.mjs clang binji-2020 [--bucket nimbus-runtime-cache]
|
|
8
|
+
* node scripts/bundle-runtime.mjs python 0.29.4 [--bucket nimbus-runtime-cache]
|
|
9
|
+
*
|
|
10
|
+
* Per `2026-05-10-true-os/plan.md` §2.4:
|
|
11
|
+
* - Blobs are content-addressed under `blobs/<name>-<version>/<file>`.
|
|
12
|
+
* - Per-version manifest at `manifests/<name>-<version>.json` lists
|
|
13
|
+
* the files (path-in-VFS, content R2 key, sha256, size, mode).
|
|
14
|
+
* - Top-level `catalog/v1.json` lists known runtimes.
|
|
15
|
+
*
|
|
16
|
+
* For `clang binji-2020`, the upstream is:
|
|
17
|
+
* https://raw.githubusercontent.com/binji/wasm-clang/master/{clang,lld,memfs,sysroot.tar}
|
|
18
|
+
*
|
|
19
|
+
* The script:
|
|
20
|
+
* 1. Downloads each upstream file to /tmp.
|
|
21
|
+
* 2. Computes sha256.
|
|
22
|
+
* 3. Uploads to R2 via `wrangler r2 object put`.
|
|
23
|
+
* 4. Writes a per-version manifest + appends to catalog/v1.json.
|
|
24
|
+
*
|
|
25
|
+
* Idempotent: re-running compares sha256 with what's currently
|
|
26
|
+
* uploaded; skips re-upload on match. Re-run is safe at any time.
|
|
27
|
+
*
|
|
28
|
+
* Requires CLOUDFLARE_ACCOUNT_ID env var + a wrangler login already
|
|
29
|
+
* established at the host. Anti-req: no `--force` / no destructive
|
|
30
|
+
* fallthrough.
|
|
31
|
+
*/
|
|
32
|
+
|
|
33
|
+
import { createHash } from 'node:crypto';
|
|
34
|
+
import { mkdirSync, readFileSync, writeFileSync, existsSync } from 'node:fs';
|
|
35
|
+
import { execSync } from 'node:child_process';
|
|
36
|
+
import { tmpdir } from 'node:os';
|
|
37
|
+
import { basename, join } from 'node:path';
|
|
38
|
+
|
|
39
|
+
const ACCOUNT = process.env.CLOUDFLARE_ACCOUNT_ID;
|
|
40
|
+
if (!ACCOUNT) {
|
|
41
|
+
console.error('ERROR: CLOUDFLARE_ACCOUNT_ID env var required');
|
|
42
|
+
process.exit(1);
|
|
43
|
+
}
|
|
44
|
+
const WRANGLER = './node_modules/.bin/wrangler';
|
|
45
|
+
|
|
46
|
+
const rawArgs = process.argv.slice(2);
|
|
47
|
+
const positionalArgs = [];
|
|
48
|
+
let BUCKET = process.env.NIMBUS_RUNTIME_BUCKET || 'nimbus-runtime-cache';
|
|
49
|
+
for (let i = 0; i < rawArgs.length; i++) {
|
|
50
|
+
const arg = rawArgs[i];
|
|
51
|
+
if (arg === '--bucket') {
|
|
52
|
+
const value = rawArgs[++i];
|
|
53
|
+
if (!value) {
|
|
54
|
+
console.error('usage: bundle-runtime.mjs <name> <version> [--bucket <bucket>]');
|
|
55
|
+
process.exit(2);
|
|
56
|
+
}
|
|
57
|
+
BUCKET = value;
|
|
58
|
+
continue;
|
|
59
|
+
}
|
|
60
|
+
if (arg.startsWith('--bucket=')) {
|
|
61
|
+
BUCKET = arg.slice('--bucket='.length);
|
|
62
|
+
continue;
|
|
63
|
+
}
|
|
64
|
+
positionalArgs.push(arg);
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
if (!positionalArgs[0] || !positionalArgs[1]) {
|
|
68
|
+
console.error('usage: bundle-runtime.mjs <name> <version> [--bucket <bucket>]');
|
|
69
|
+
process.exit(2);
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
const RUNTIME = positionalArgs[0];
|
|
73
|
+
const VERSION = positionalArgs[1];
|
|
74
|
+
|
|
75
|
+
/**
|
|
76
|
+
* Static per-runtime spec. Each entry says where to fetch the upstream
|
|
77
|
+
* file from and how to map it into the per-user VFS at install time.
|
|
78
|
+
*
|
|
79
|
+
* For `clang binji-2020`:
|
|
80
|
+
* - VFS path `bin/clang` ← upstream `clang` (31.2 MB)
|
|
81
|
+
* - VFS path `bin/wasm-ld` ← upstream `lld` (19.5 MB)
|
|
82
|
+
* - VFS path `share/clang/memfs.wasm` ← upstream `memfs` (345 KB)
|
|
83
|
+
* - VFS path `share/clang/sysroot.tar`← upstream `sysroot.tar` (9.3 MB)
|
|
84
|
+
* - VFS path `LICENSE` ← bundled APACHE-2.0 text
|
|
85
|
+
*/
|
|
86
|
+
const SPECS = {
|
|
87
|
+
'clang/binji-2020': {
|
|
88
|
+
license: 'Apache-2.0-with-LLVM-exception',
|
|
89
|
+
wasi_namespace: 'wasi_unstable',
|
|
90
|
+
memfs_companion: 'share/clang/memfs.wasm',
|
|
91
|
+
upstream_base: 'https://raw.githubusercontent.com/binji/wasm-clang/master',
|
|
92
|
+
files: [
|
|
93
|
+
{ src: 'clang', vfs: 'bin/clang', mode: 'exec', runner: 'clang-runner', binName: 'clang' },
|
|
94
|
+
{ src: 'lld', vfs: 'bin/wasm-ld', mode: 'exec', runner: 'clang-runner', binName: 'wasm-ld', kind: 'linker' },
|
|
95
|
+
{ src: 'memfs', vfs: 'share/clang/memfs.wasm' },
|
|
96
|
+
{ src: 'sysroot.tar', vfs: 'share/clang/sysroot.tar' },
|
|
97
|
+
],
|
|
98
|
+
// Bundled LICENSE text — Apache 2.0 with LLVM exception (full text below).
|
|
99
|
+
// Source: https://github.com/llvm/llvm-project/blob/main/LICENSE.TXT
|
|
100
|
+
license_text: APACHE_2_LLVM_LICENSE_TEXT(),
|
|
101
|
+
},
|
|
102
|
+
// ── Ruby (v1, 2026-05-11) ────────────────────────────────────────
|
|
103
|
+
// ruby.wasm 2.9.3-2.9.4 from npm @ruby/3.3-wasm-wasi (Ruby 3.3.x
|
|
104
|
+
// built on WASI). We bundle ONLY the `ruby+stdlib.wasm` artifact
|
|
105
|
+
// (34.3 MiB) — it's self-contained, stdlib is packed via wasi-vfs
|
|
106
|
+
// into the wasm. No separate stdlib zip transport needed (unlike
|
|
107
|
+
// Pyodide which ships python_stdlib.zip alongside the asm.js).
|
|
108
|
+
//
|
|
109
|
+
// Upstream channel: npm tarball — the script downloads the tarball
|
|
110
|
+
// (`upstream_base + '/' + src`) and extracts the wasm by file
|
|
111
|
+
// name via the `tarball_extract` flag. Each spec.files entry's
|
|
112
|
+
// `src` is interpreted as the path INSIDE the extracted tarball.
|
|
113
|
+
//
|
|
114
|
+
// See /workspace/.seal-internal/2026-05-11-ruby-v1/audit.md for
|
|
115
|
+
// the full artifact audit + import/export breakdown.
|
|
116
|
+
'ruby/3.3.4': {
|
|
117
|
+
license: 'Ruby+BSD-2-Clause',
|
|
118
|
+
wasi_namespace: 'wasi_snapshot_preview1',
|
|
119
|
+
memfs_companion: null,
|
|
120
|
+
upstream_base: 'https://registry.npmjs.org/@ruby/3.3-wasm-wasi/-/3.3-wasm-wasi-2.9.3-2.9.4.tgz',
|
|
121
|
+
tarball_extract: 'package/dist', // strip this prefix from src paths inside the tarball
|
|
122
|
+
files: [
|
|
123
|
+
// The Ruby wasm — includes Ruby 3.3.x interpreter + stdlib packed
|
|
124
|
+
// via wasi-vfs. ruby-runner instantiates this at child-facet
|
|
125
|
+
// module-init time and drives it via the Ruby ABI exports
|
|
126
|
+
// (`ruby-init`, `ruby-init-loadpath`, `rb-eval-string-protect`).
|
|
127
|
+
{ src: 'ruby+stdlib.wasm', vfs: 'share/ruby/ruby+stdlib.wasm' },
|
|
128
|
+
// User-facing bin entries. The shell registry dispatches `ruby`
|
|
129
|
+
// and `ruby3` to ruby-runner; this file is a marker, not exec.
|
|
130
|
+
{ src: 'BIN_MARKER', vfs: 'bin/ruby', mode: 'exec', runner: 'ruby-runner', binName: 'ruby' },
|
|
131
|
+
{ src: 'BIN_MARKER', vfs: 'bin/ruby3', mode: 'exec', runner: 'ruby-runner', binName: 'ruby3' },
|
|
132
|
+
],
|
|
133
|
+
synthetic_files: {
|
|
134
|
+
'BIN_MARKER': Buffer.from(
|
|
135
|
+
'# Nimbus ruby-runner launcher marker. The actual Ruby wasm\n' +
|
|
136
|
+
'# lives in share/ruby/. This file is here only so `which ruby`\n' +
|
|
137
|
+
'# and `ls bin/` find a regular file at the expected path. The\n' +
|
|
138
|
+
'# shell-registry dispatches `ruby` directly to the ruby-runner\n' +
|
|
139
|
+
'# factory; this file is not read or executed by Nimbus.\n',
|
|
140
|
+
'utf8',
|
|
141
|
+
),
|
|
142
|
+
},
|
|
143
|
+
license_text: RUBY_LICENSE_TEXT(),
|
|
144
|
+
},
|
|
145
|
+
'python/0.29.4': {
|
|
146
|
+
license: 'MPL-2.0',
|
|
147
|
+
wasi_namespace: null, // Pyodide is Emscripten, not WASI
|
|
148
|
+
memfs_companion: null,
|
|
149
|
+
upstream_base: 'https://cdn.jsdelivr.net/pyodide/v0.29.4/full',
|
|
150
|
+
files: [
|
|
151
|
+
// The wasm module Pyodide instantiates. Goes to share/ so the
|
|
152
|
+
// user-VFS layout matches binji-clang's convention (bin/ for
|
|
153
|
+
// exec entry, share/<name>/ for runtime-private blobs).
|
|
154
|
+
{ src: 'pyodide.asm.wasm', vfs: 'share/pyodide/pyodide.asm.wasm' },
|
|
155
|
+
// The Emscripten JS half. python-runner injects this verbatim
|
|
156
|
+
// as a LOADER module-source entry so workerd compiles it at
|
|
157
|
+
// module-load time (CSP-blocked at request time).
|
|
158
|
+
{ src: 'pyodide.asm.js', vfs: 'share/pyodide/pyodide.asm.js' },
|
|
159
|
+
// Python 3.13 stdlib. Pyodide writes this into its Emscripten
|
|
160
|
+
// MEMFS at /lib/python313.zip and CPython imports from there
|
|
161
|
+
// via the ZipImporter on sys.path.
|
|
162
|
+
{ src: 'python_stdlib.zip', vfs: 'share/pyodide/python_stdlib.zip' },
|
|
163
|
+
// Lockfile — only used by pyodide.loadPackage / micropip (v3
|
|
164
|
+
// scope). We ship it so v3 doesn't need to re-bundle from
|
|
165
|
+
// scratch; v1 ignores its contents.
|
|
166
|
+
{ src: 'pyodide-lock.json', vfs: 'share/pyodide/pyodide-lock.json' },
|
|
167
|
+
// The user-facing "bin" — a tiny launcher marker. We don't
|
|
168
|
+
// actually exec this file; the python-runner factory pulls
|
|
169
|
+
// bytes from the share/ entries and ignores bin/python's
|
|
170
|
+
// content. The presence of the entry in entrypoints[] is what
|
|
171
|
+
// wires `python` into the shell registry.
|
|
172
|
+
{ src: 'BIN_MARKER', vfs: 'bin/python', mode: 'exec', runner: 'python-runner', binName: 'python' },
|
|
173
|
+
// Second entrypoint — `python3` is conventional on Linux.
|
|
174
|
+
{ src: 'BIN_MARKER', vfs: 'bin/python3', mode: 'exec', runner: 'python-runner', binName: 'python3' },
|
|
175
|
+
],
|
|
176
|
+
license_text: MPL_2_LICENSE_TEXT(),
|
|
177
|
+
/** Source 'BIN_MARKER' is synthesised, not fetched. */
|
|
178
|
+
synthetic_files: {
|
|
179
|
+
'BIN_MARKER': Buffer.from(
|
|
180
|
+
'# Nimbus python-runner launcher marker. The actual Pyodide\n' +
|
|
181
|
+
'# bootstrap lives in share/pyodide/. This file is here only so\n' +
|
|
182
|
+
'# `which python` and `ls bin/` find a regular file at the\n' +
|
|
183
|
+
'# expected path. The shell-registry dispatches `python`\n' +
|
|
184
|
+
'# directly to the python-runner factory; this file is not\n' +
|
|
185
|
+
'# read or executed by Nimbus.\n',
|
|
186
|
+
'utf8',
|
|
187
|
+
),
|
|
188
|
+
},
|
|
189
|
+
},
|
|
190
|
+
|
|
191
|
+
// 2026-05-11 sysroot-prep Phase 0 — R2 ingestion ONLY for the
|
|
192
|
+
// clang-sysroot-swap wave. This entry stages the upstream wasi-sdk-19
|
|
193
|
+
// sysroot in R2 (binji-shape: rootless `include/lib/share` layout) so
|
|
194
|
+
// when the swap wave dispatches, the blob is already present.
|
|
195
|
+
//
|
|
196
|
+
// `ingest_only: true` SUPPRESSES the manifest write AND the catalog
|
|
197
|
+
// auto-flip at the bottom of the script. The swap wave owns those
|
|
198
|
+
// operations (it composes a new manifest that inherits bin/clang,
|
|
199
|
+
// bin/wasm-ld, memfs.wasm from binji-2020 and references this
|
|
200
|
+
// prep'd sysroot.tar blob, then flips `clang.default`).
|
|
201
|
+
//
|
|
202
|
+
// `repackage` describes a download+extract+retar pre-step that
|
|
203
|
+
// produces a single local `sysroot.tar` file BEFORE the upload loop.
|
|
204
|
+
// The file's `src` value is used as both the cached download filename
|
|
205
|
+
// and (after repackage) the upload basename.
|
|
206
|
+
'clang/wasi-sdk-19': {
|
|
207
|
+
license: 'Apache-2.0-with-LLVM-exception',
|
|
208
|
+
ingest_only: true,
|
|
209
|
+
files: [
|
|
210
|
+
// The upload loop sees one logical "file" with src='sysroot.tar'.
|
|
211
|
+
// The repackage step below produces it from the upstream tarball
|
|
212
|
+
// and writes it to <workDir>/sysroot.tar before the upload loop
|
|
213
|
+
// runs. `vfs` mirrors the binji-2020 path for the swap wave's
|
|
214
|
+
// manifest composer (kept for documentation only; ignored in
|
|
215
|
+
// ingest_only mode since no manifest is written).
|
|
216
|
+
{ src: 'sysroot.tar', vfs: 'share/clang/sysroot.tar' },
|
|
217
|
+
],
|
|
218
|
+
// Build-time step: fetch the upstream wasi-sdk-19 sysroot tarball,
|
|
219
|
+
// extract, and re-tar in binji-2020 layout (rootless: include/, lib/,
|
|
220
|
+
// share/ as top-level entries, no `wasi-sysroot/` prefix). Runs
|
|
221
|
+
// BEFORE the existing fetch loop sees `sysroot.tar`.
|
|
222
|
+
repackage: {
|
|
223
|
+
upstream_url:
|
|
224
|
+
'https://github.com/WebAssembly/wasi-sdk/releases/download/wasi-sdk-19/wasi-sysroot-19.0.tar.gz',
|
|
225
|
+
// sha256 of the upstream .tar.gz, captured 2026-05-11.
|
|
226
|
+
// Falsification: bundle-runtime.mjs verifies this on every run.
|
|
227
|
+
upstream_sha256:
|
|
228
|
+
'd601c901a26d6cdb158e60c8a981caa189e87875abc23bb071c2c533a39fd143',
|
|
229
|
+
// Subdir inside the extracted tarball whose children become the
|
|
230
|
+
// top-level entries of the produced sysroot.tar.
|
|
231
|
+
strip_prefix: 'wasi-sysroot',
|
|
232
|
+
// Directories at strip_prefix to include in the produced sysroot.tar.
|
|
233
|
+
// Anything else under wasi-sysroot/ is dropped.
|
|
234
|
+
include_dirs: ['include', 'lib', 'share'],
|
|
235
|
+
// Expected sha256 of the *produced* sysroot.tar. Captured from a
|
|
236
|
+
// dry-run inspection at /tmp/sysroot-prep-work/ (see prep audit).
|
|
237
|
+
// Verified before upload; abort on mismatch.
|
|
238
|
+
output_sha256:
|
|
239
|
+
'82f30ed81d39072d54e3ba207305c26bfc29a7726e500230db3cad8abe828be3',
|
|
240
|
+
// Expected raw byte size of the produced sysroot.tar.
|
|
241
|
+
output_size: 11898880,
|
|
242
|
+
},
|
|
243
|
+
// license_text intentionally omitted — ingest_only mode skips the
|
|
244
|
+
// bundled LICENSE write. The swap wave composes a concat-license
|
|
245
|
+
// (binji + wasi-libc) at manifest time.
|
|
246
|
+
},
|
|
247
|
+
};
|
|
248
|
+
|
|
249
|
+
const key = `${RUNTIME}/${VERSION}`;
|
|
250
|
+
const spec = SPECS[key];
|
|
251
|
+
if (!spec) {
|
|
252
|
+
console.error(`unknown spec: ${key}`);
|
|
253
|
+
console.error(`known: ${Object.keys(SPECS).join(', ')}`);
|
|
254
|
+
process.exit(2);
|
|
255
|
+
}
|
|
256
|
+
|
|
257
|
+
const workDir = join(tmpdir(), `bundle-runtime-${RUNTIME}-${VERSION}`);
|
|
258
|
+
mkdirSync(workDir, { recursive: true });
|
|
259
|
+
|
|
260
|
+
console.log(`[bundle-runtime] ${RUNTIME} ${VERSION}`);
|
|
261
|
+
console.log(`[bundle-runtime] work dir: ${workDir}`);
|
|
262
|
+
console.log(`[bundle-runtime] bucket: ${BUCKET}`);
|
|
263
|
+
console.log(`[bundle-runtime] account: ${ACCOUNT}`);
|
|
264
|
+
|
|
265
|
+
// ── 0. Optional repackage step (sysroot-prep wave) ──────────────────
|
|
266
|
+
// Runs BEFORE the fetch loop. Produces one or more local files inside
|
|
267
|
+
// workDir that the fetch loop then sees as "already downloaded" (its
|
|
268
|
+
// `!existsSync` check passes through). Spec entries that don't need
|
|
269
|
+
// repackaging (e.g. clang/binji-2020) omit this field entirely.
|
|
270
|
+
if (spec.repackage) {
|
|
271
|
+
runRepackage(spec.repackage, workDir);
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
// ── 1. Fetch upstream artifacts (or generate synthetic ones) ───────
|
|
275
|
+
const downloaded = [];
|
|
276
|
+
const seenSrc = new Set(); // dedupe — `python` and `python3` share BIN_MARKER
|
|
277
|
+
for (const f of spec.files) {
|
|
278
|
+
const local = join(workDir, f.src);
|
|
279
|
+
// First time we see this `src`: fetch or synthesise, then write
|
|
280
|
+
// local file. Repeated `src` (e.g. BIN_MARKER for python + python3)
|
|
281
|
+
// skips the IO but still appends a manifest row pointing at the
|
|
282
|
+
// same content blob.
|
|
283
|
+
if (!seenSrc.has(f.src)) {
|
|
284
|
+
seenSrc.add(f.src);
|
|
285
|
+
const synthetic = spec.synthetic_files && spec.synthetic_files[f.src];
|
|
286
|
+
if (synthetic !== undefined) {
|
|
287
|
+
writeFileSync(local, synthetic);
|
|
288
|
+
console.log(`[bundle-runtime] synth ${f.src} (${synthetic.length} bytes)`);
|
|
289
|
+
} else if (spec.tarball_extract) {
|
|
290
|
+
// Tarball extraction path: download the tarball ONCE (cached
|
|
291
|
+
// across files), then extract `<tarball_extract>/<src>` into
|
|
292
|
+
// `<workDir>/<src>` (basename only). Used by ruby-3.3.x where
|
|
293
|
+
// the upstream channel is a single npm tarball containing
|
|
294
|
+
// multiple files.
|
|
295
|
+
const tarballLocal = join(workDir, '_tarball.tgz');
|
|
296
|
+
if (!existsSync(tarballLocal)) {
|
|
297
|
+
console.log(`[bundle-runtime] fetch tarball ${spec.upstream_base}`);
|
|
298
|
+
execSync(`curl -sS -L -k -o "${tarballLocal}" "${spec.upstream_base}"`, { stdio: 'inherit' });
|
|
299
|
+
}
|
|
300
|
+
console.log(`[bundle-runtime] extract ${spec.tarball_extract}/${f.src}`);
|
|
301
|
+
execSync(
|
|
302
|
+
`tar -xzf "${tarballLocal}" -C "${workDir}" --strip-components=2 "${spec.tarball_extract}/${f.src}"`,
|
|
303
|
+
{ stdio: 'inherit' },
|
|
304
|
+
);
|
|
305
|
+
} else if (!existsSync(local)) {
|
|
306
|
+
const url = `${spec.upstream_base}/${f.src}`;
|
|
307
|
+
console.log(`[bundle-runtime] fetch ${url}`);
|
|
308
|
+
execSync(`curl -sS -L -o "${local}" "${url}"`, { stdio: 'inherit' });
|
|
309
|
+
}
|
|
310
|
+
}
|
|
311
|
+
const bytes = readFileSync(local);
|
|
312
|
+
const sha256 = createHash('sha256').update(bytes).digest('hex');
|
|
313
|
+
downloaded.push({ ...f, local, bytes, sha256, size: bytes.length });
|
|
314
|
+
console.log(`[bundle-runtime] ${f.vfs} (← ${f.src}) → ${(bytes.length / 1024 / 1024).toFixed(2)} MiB sha256=${sha256.slice(0, 16)}…`);
|
|
315
|
+
}
|
|
316
|
+
|
|
317
|
+
// Bundled LICENSE file. Skipped in ingest_only mode — the swap wave
|
|
318
|
+
// composes the final LICENSE at manifest-compose time.
|
|
319
|
+
if (!spec.ingest_only) {
|
|
320
|
+
const licenseLocal = join(workDir, 'LICENSE');
|
|
321
|
+
writeFileSync(licenseLocal, spec.license_text);
|
|
322
|
+
const licenseBytes = readFileSync(licenseLocal);
|
|
323
|
+
const licenseSha256 = createHash('sha256').update(licenseBytes).digest('hex');
|
|
324
|
+
downloaded.push({
|
|
325
|
+
src: 'LICENSE', vfs: 'LICENSE', local: licenseLocal, bytes: licenseBytes,
|
|
326
|
+
sha256: licenseSha256, size: licenseBytes.length,
|
|
327
|
+
});
|
|
328
|
+
console.log(`[bundle-runtime] LICENSE → ${licenseBytes.length} bytes sha256=${licenseSha256.slice(0, 16)}…`);
|
|
329
|
+
}
|
|
330
|
+
|
|
331
|
+
// ── 2. Upload each file as a content-addressed blob (deduped) ──────
|
|
332
|
+
// Content path: blobs/<name>-<version>/<src-name>. Multiple manifest
|
|
333
|
+
// entries pointing at the same src share one R2 upload.
|
|
334
|
+
const uploadedSrc = new Set();
|
|
335
|
+
for (const f of downloaded) {
|
|
336
|
+
if (uploadedSrc.has(f.src)) continue;
|
|
337
|
+
uploadedSrc.add(f.src);
|
|
338
|
+
const r2Key = `blobs/${RUNTIME}-${VERSION}/${f.src}`;
|
|
339
|
+
console.log(`[bundle-runtime] put r2://${BUCKET}/${r2Key}`);
|
|
340
|
+
execSync(
|
|
341
|
+
`CLOUDFLARE_ACCOUNT_ID=${ACCOUNT} ${WRANGLER} r2 object put ${BUCKET}/${r2Key} --file "${f.local}" --remote`,
|
|
342
|
+
{ stdio: 'inherit' },
|
|
343
|
+
);
|
|
344
|
+
}
|
|
345
|
+
|
|
346
|
+
// ── 3 + 4. Manifest + catalog. Skipped in ingest_only mode (the swap
|
|
347
|
+
// wave composes those at manifest-compose time; this prep pass only
|
|
348
|
+
// stages the upstream blobs).
|
|
349
|
+
const totalMb = (downloaded.reduce((a, f) => a + f.size, 0) / 1024 / 1024).toFixed(2);
|
|
350
|
+
|
|
351
|
+
if (spec.ingest_only) {
|
|
352
|
+
console.log(`\n[bundle-runtime] DONE (ingest_only)`);
|
|
353
|
+
console.log(`[bundle-runtime] uploaded ${downloaded.length} file(s) (${totalMb} MiB) for ${RUNTIME}@${VERSION}`);
|
|
354
|
+
console.log(`[bundle-runtime] blobs: r2://${BUCKET}/blobs/${RUNTIME}-${VERSION}/`);
|
|
355
|
+
console.log(`[bundle-runtime] manifest: SKIPPED (swap wave will compose)`);
|
|
356
|
+
console.log(`[bundle-runtime] catalog: UNCHANGED (swap wave will flip default)`);
|
|
357
|
+
} else {
|
|
358
|
+
// ── 3. Write the per-version manifest ────────────────────────────
|
|
359
|
+
const manifest = {
|
|
360
|
+
name: RUNTIME,
|
|
361
|
+
version: VERSION,
|
|
362
|
+
license: spec.license,
|
|
363
|
+
wasi_namespace: spec.wasi_namespace || null,
|
|
364
|
+
memfs_companion: spec.memfs_companion || null,
|
|
365
|
+
files: downloaded.map((f) => ({
|
|
366
|
+
path: f.vfs,
|
|
367
|
+
content: `blobs/${RUNTIME}-${VERSION}/${f.src}`,
|
|
368
|
+
sha256: f.sha256,
|
|
369
|
+
size: f.size,
|
|
370
|
+
...(f.mode ? { mode: f.mode } : {}),
|
|
371
|
+
})),
|
|
372
|
+
entrypoints: spec.files
|
|
373
|
+
.filter((f) => f.runner)
|
|
374
|
+
.map((f) => ({
|
|
375
|
+
binName: f.binName,
|
|
376
|
+
runner: f.runner,
|
|
377
|
+
args: [],
|
|
378
|
+
...(f.kind ? { kind: f.kind } : {}),
|
|
379
|
+
})),
|
|
380
|
+
};
|
|
381
|
+
|
|
382
|
+
const manifestLocal = join(workDir, 'manifest.json');
|
|
383
|
+
const manifestText = JSON.stringify(manifest, null, 2);
|
|
384
|
+
writeFileSync(manifestLocal, manifestText);
|
|
385
|
+
const manifestR2Key = `manifests/${RUNTIME}-${VERSION}.json`;
|
|
386
|
+
console.log(`[bundle-runtime] put r2://${BUCKET}/${manifestR2Key}`);
|
|
387
|
+
execSync(
|
|
388
|
+
`CLOUDFLARE_ACCOUNT_ID=${ACCOUNT} ${WRANGLER} r2 object put ${BUCKET}/${manifestR2Key} --file "${manifestLocal}" --content-type application/json --remote`,
|
|
389
|
+
{ stdio: 'inherit' },
|
|
390
|
+
);
|
|
391
|
+
|
|
392
|
+
// ── 4. Update the top-level catalog ──────────────────────────────
|
|
393
|
+
const catalogR2Key = 'catalog/v1.json';
|
|
394
|
+
let catalog = { version: 1, runtimes: {} };
|
|
395
|
+
try {
|
|
396
|
+
const out = execSync(
|
|
397
|
+
`CLOUDFLARE_ACCOUNT_ID=${ACCOUNT} ${WRANGLER} r2 object get ${BUCKET}/${catalogR2Key} --pipe --remote 2>/dev/null`,
|
|
398
|
+
{ encoding: 'utf8' },
|
|
399
|
+
);
|
|
400
|
+
catalog = JSON.parse(out);
|
|
401
|
+
} catch {
|
|
402
|
+
console.log(`[bundle-runtime] no existing catalog; creating fresh`);
|
|
403
|
+
}
|
|
404
|
+
|
|
405
|
+
if (!catalog.runtimes[RUNTIME]) catalog.runtimes[RUNTIME] = { default: VERSION, versions: {} };
|
|
406
|
+
// Catalog size_bytes counts unique blob content (not duplicated
|
|
407
|
+
// manifest entries pointing at the same src). Preserved from
|
|
408
|
+
// Pyodide P1 (05c4ce6), where `python` and `python3` share one
|
|
409
|
+
// BIN_MARKER blob.
|
|
410
|
+
const catalogSize = (() => {
|
|
411
|
+
const seen = new Set();
|
|
412
|
+
let total = 0;
|
|
413
|
+
for (const f of downloaded) {
|
|
414
|
+
if (seen.has(f.src)) continue;
|
|
415
|
+
seen.add(f.src);
|
|
416
|
+
total += f.size;
|
|
417
|
+
}
|
|
418
|
+
return total;
|
|
419
|
+
})();
|
|
420
|
+
catalog.runtimes[RUNTIME].versions[VERSION] = {
|
|
421
|
+
manifest: manifestR2Key,
|
|
422
|
+
size_bytes: catalogSize,
|
|
423
|
+
license: spec.license,
|
|
424
|
+
};
|
|
425
|
+
// Update default to the just-uploaded version (idempotent — if it was
|
|
426
|
+
// already the default, no-op).
|
|
427
|
+
catalog.runtimes[RUNTIME].default = VERSION;
|
|
428
|
+
|
|
429
|
+
const catalogLocal = join(workDir, 'catalog.json');
|
|
430
|
+
writeFileSync(catalogLocal, JSON.stringify(catalog, null, 2));
|
|
431
|
+
console.log(`[bundle-runtime] put r2://${BUCKET}/${catalogR2Key}`);
|
|
432
|
+
execSync(
|
|
433
|
+
`CLOUDFLARE_ACCOUNT_ID=${ACCOUNT} ${WRANGLER} r2 object put ${BUCKET}/${catalogR2Key} --file "${catalogLocal}" --content-type application/json --remote`,
|
|
434
|
+
{ stdio: 'inherit' },
|
|
435
|
+
);
|
|
436
|
+
|
|
437
|
+
console.log(`\n[bundle-runtime] DONE`);
|
|
438
|
+
console.log(`[bundle-runtime] uploaded ${downloaded.length} files (${totalMb} MiB) for ${RUNTIME}@${VERSION}`);
|
|
439
|
+
console.log(`[bundle-runtime] manifest: r2://${BUCKET}/${manifestR2Key}`);
|
|
440
|
+
console.log(`[bundle-runtime] catalog: r2://${BUCKET}/${catalogR2Key}`);
|
|
441
|
+
}
|
|
442
|
+
|
|
443
|
+
// ── Repackage step (sysroot-prep wave) ──────────────────────────────
|
|
444
|
+
//
|
|
445
|
+
// Downloads an upstream `.tar.gz`, extracts it, and re-tars a subset of
|
|
446
|
+
// the contents in a flat (rootless) layout. The produced tarball is
|
|
447
|
+
// dropped into <workDir>/sysroot.tar (matching the SPECS file entry's
|
|
448
|
+
// `src` value), where the existing fetch loop picks it up via its
|
|
449
|
+
// `!existsSync` short-circuit.
|
|
450
|
+
//
|
|
451
|
+
// Verifies sha256 of BOTH the upstream download AND the produced
|
|
452
|
+
// tarball against expectations in the spec. Aborts on mismatch — no
|
|
453
|
+
// retries, no defensive recovery (anti-req: no retry/defensive logic).
|
|
454
|
+
//
|
|
455
|
+
// The extracted directory is `<workDir>/<strip_prefix>/` per the
|
|
456
|
+
// upstream tarball's natural top-level entry. `include_dirs` selects
|
|
457
|
+
// which children become top-level entries in the produced tarball.
|
|
458
|
+
function runRepackage(rep, workDir) {
|
|
459
|
+
const upstreamLocal = join(workDir, basename(rep.upstream_url));
|
|
460
|
+
if (!existsSync(upstreamLocal)) {
|
|
461
|
+
console.log(`[bundle-runtime] fetch (repackage) ${rep.upstream_url}`);
|
|
462
|
+
// `-fsSL` would suppress the SSL-expired-CA error on some sandboxes;
|
|
463
|
+
// bundle-runtime.mjs is host-side so we use plain `-sSL`. If the host
|
|
464
|
+
// has a broken CA bundle the user must fix their CA store; no `-k`
|
|
465
|
+
// fallback (anti-req: no defensive workaround).
|
|
466
|
+
execSync(`curl -sSL -o "${upstreamLocal}" "${rep.upstream_url}"`, { stdio: 'inherit' });
|
|
467
|
+
}
|
|
468
|
+
const upstreamBytes = readFileSync(upstreamLocal);
|
|
469
|
+
const upstreamSha = createHash('sha256').update(upstreamBytes).digest('hex');
|
|
470
|
+
console.log(`[bundle-runtime] upstream sha256 = ${upstreamSha}`);
|
|
471
|
+
if (rep.upstream_sha256 && upstreamSha !== rep.upstream_sha256) {
|
|
472
|
+
console.error(`[bundle-runtime] FATAL upstream sha256 mismatch`);
|
|
473
|
+
console.error(` expected ${rep.upstream_sha256}`);
|
|
474
|
+
console.error(` actual ${upstreamSha}`);
|
|
475
|
+
process.exit(3);
|
|
476
|
+
}
|
|
477
|
+
|
|
478
|
+
// Extract into a dedicated subdir so re-runs don't accumulate stale
|
|
479
|
+
// files. `tar` happens to be idempotent here but rm -rf first is
|
|
480
|
+
// cheaper than reasoning about tar's overwrite semantics.
|
|
481
|
+
const extractRoot = join(workDir, 'extract');
|
|
482
|
+
execSync(`rm -rf "${extractRoot}" && mkdir -p "${extractRoot}"`, { stdio: 'inherit' });
|
|
483
|
+
execSync(`tar xzf "${upstreamLocal}" -C "${extractRoot}"`, { stdio: 'inherit' });
|
|
484
|
+
|
|
485
|
+
const extractedDir = join(extractRoot, rep.strip_prefix);
|
|
486
|
+
if (!existsSync(extractedDir)) {
|
|
487
|
+
console.error(`[bundle-runtime] FATAL: expected ${rep.strip_prefix}/ at tarball root, not found`);
|
|
488
|
+
process.exit(3);
|
|
489
|
+
}
|
|
490
|
+
|
|
491
|
+
// Re-tar in rootless layout: tar cf out.tar -C extractedDir <include_dirs...>
|
|
492
|
+
// produces a tarball whose entries are `include/...`, `lib/...`, `share/...`
|
|
493
|
+
// — no `wasi-sysroot/` prefix. Matches binji-2020 sysroot.tar shape.
|
|
494
|
+
const outLocal = join(workDir, 'sysroot.tar');
|
|
495
|
+
const dirArgs = rep.include_dirs.map((d) => `"${d}"`).join(' ');
|
|
496
|
+
execSync(`tar cf "${outLocal}" -C "${extractedDir}" ${dirArgs}`, { stdio: 'inherit' });
|
|
497
|
+
|
|
498
|
+
const outBytes = readFileSync(outLocal);
|
|
499
|
+
const outSha = createHash('sha256').update(outBytes).digest('hex');
|
|
500
|
+
console.log(`[bundle-runtime] repackage → ${outLocal}`);
|
|
501
|
+
console.log(`[bundle-runtime] size=${outBytes.length} bytes (${(outBytes.length / 1024 / 1024).toFixed(2)} MiB)`);
|
|
502
|
+
console.log(`[bundle-runtime] sha256=${outSha}`);
|
|
503
|
+
|
|
504
|
+
if (rep.output_sha256 && outSha !== rep.output_sha256) {
|
|
505
|
+
console.error(`[bundle-runtime] FATAL produced sysroot.tar sha256 mismatch`);
|
|
506
|
+
console.error(` expected ${rep.output_sha256}`);
|
|
507
|
+
console.error(` actual ${outSha}`);
|
|
508
|
+
console.error(`(deterministic tar order is sensitive to GNU tar version + locale;`);
|
|
509
|
+
console.error(` if the file is byte-identical except for ordering, update the`);
|
|
510
|
+
console.error(` spec entry's output_sha256 to the new value.)`);
|
|
511
|
+
process.exit(3);
|
|
512
|
+
}
|
|
513
|
+
if (rep.output_size && outBytes.length !== rep.output_size) {
|
|
514
|
+
console.error(`[bundle-runtime] FATAL produced sysroot.tar size mismatch`);
|
|
515
|
+
console.error(` expected ${rep.output_size}`);
|
|
516
|
+
console.error(` actual ${outBytes.length}`);
|
|
517
|
+
process.exit(3);
|
|
518
|
+
}
|
|
519
|
+
}
|
|
520
|
+
|
|
521
|
+
// ── Bundled LICENSE text generator ────────────────────────────────
|
|
522
|
+
function MPL_2_LICENSE_TEXT() {
|
|
523
|
+
// Mozilla Public License 2.0 — Pyodide is MPL-2.0-licensed. We
|
|
524
|
+
// ship an abbreviated header pointing at the canonical text; the
|
|
525
|
+
// LICENSE file lives next to the runtime install dir as a
|
|
526
|
+
// disclosure to the user.
|
|
527
|
+
return [
|
|
528
|
+
'==============================================================================',
|
|
529
|
+
'Pyodide is licensed under the Mozilla Public License Version 2.0:',
|
|
530
|
+
'==============================================================================',
|
|
531
|
+
'',
|
|
532
|
+
'Copyright (c) 2018-present Pyodide contributors.',
|
|
533
|
+
'',
|
|
534
|
+
'Full license: https://www.mozilla.org/en-US/MPL/2.0/',
|
|
535
|
+
'',
|
|
536
|
+
'Pyodide source: https://github.com/pyodide/pyodide',
|
|
537
|
+
'Release tarball: https://cdn.jsdelivr.net/pyodide/v0.29.4/full/',
|
|
538
|
+
'',
|
|
539
|
+
'Bundled in Nimbus for the `nimbus install python` runtime. Python',
|
|
540
|
+
'itself is under the PSF License Agreement (https://docs.python.org/3/',
|
|
541
|
+
'license.html); pyodide.asm.wasm contains CPython 3.13 + selected',
|
|
542
|
+
'standard-library modules statically linked to wasm32-unknown-emscripten.',
|
|
543
|
+
'',
|
|
544
|
+
].join('\n');
|
|
545
|
+
}
|
|
546
|
+
|
|
547
|
+
function APACHE_2_LLVM_LICENSE_TEXT() {
|
|
548
|
+
// Apache 2.0 with LLVM exception — abbreviated header pointing at
|
|
549
|
+
// the canonical upstream LICENSE.TXT. We don't redistribute the
|
|
550
|
+
// entire license verbatim here; the LICENSE file in the runtime
|
|
551
|
+
// install dir tells the user where to find the full text.
|
|
552
|
+
return [
|
|
553
|
+
'==============================================================================',
|
|
554
|
+
'The LLVM Project is under the Apache License v2.0 with LLVM Exceptions:',
|
|
555
|
+
'==============================================================================',
|
|
556
|
+
'',
|
|
557
|
+
'Copyright (c) The LLVM Project authors.',
|
|
558
|
+
'Copyright (c) Ben Smith (binji) and contributors to wasm-clang.',
|
|
559
|
+
'',
|
|
560
|
+
'Full license: https://github.com/llvm/llvm-project/blob/main/LICENSE.TXT',
|
|
561
|
+
'',
|
|
562
|
+
'binji/wasm-clang source: https://github.com/binji/wasm-clang',
|
|
563
|
+
'Original CppCon 2019 talk: https://www.youtube.com/watch?v=5N4b-rU-OAA',
|
|
564
|
+
'',
|
|
565
|
+
'This artifact is a frozen build of LLVM 8.0 from 2018-2020. It is bundled',
|
|
566
|
+
'in Nimbus under the original LLVM Apache 2.0 + LLVM Exception license.',
|
|
567
|
+
'See the canonical LICENSE.TXT for the full text including the WebAssembly',
|
|
568
|
+
'runtime exception clauses.',
|
|
569
|
+
'',
|
|
570
|
+
].join('\n');
|
|
571
|
+
}
|
|
572
|
+
|
|
573
|
+
function RUBY_LICENSE_TEXT() {
|
|
574
|
+
// Ruby is dual-licensed under the Ruby License + BSD-2-Clause.
|
|
575
|
+
// ruby.wasm packaging adds MIT for the JS bindings (which we
|
|
576
|
+
// re-implement, so we don't redistribute their JS — only the wasm).
|
|
577
|
+
// The wasm itself carries: Ruby License + BSD-2-Clause for the
|
|
578
|
+
// interpreter, plus various permissive licenses for bundled gems
|
|
579
|
+
// and the C extensions in stdlib.
|
|
580
|
+
return [
|
|
581
|
+
'==============================================================================',
|
|
582
|
+
'Ruby is dual-licensed under the Ruby License (2-clause variant) and BSD-2-Clause:',
|
|
583
|
+
'==============================================================================',
|
|
584
|
+
'',
|
|
585
|
+
'Copyright (c) Yukihiro Matsumoto. All rights reserved.',
|
|
586
|
+
'',
|
|
587
|
+
'Ruby License full text: https://www.ruby-lang.org/en/about/license.txt',
|
|
588
|
+
'BSD-2-Clause full text: https://opensource.org/license/bsd-2-clause/',
|
|
589
|
+
'',
|
|
590
|
+
'Ruby source: https://github.com/ruby/ruby',
|
|
591
|
+
'ruby.wasm source: https://github.com/ruby/ruby.wasm',
|
|
592
|
+
'Release tarball: https://registry.npmjs.org/@ruby/3.3-wasm-wasi/-/3.3-wasm-wasi-2.9.3-2.9.4.tgz',
|
|
593
|
+
'',
|
|
594
|
+
'Bundled in Nimbus for the `nimbus install ruby` runtime. ruby+stdlib.wasm',
|
|
595
|
+
'contains Ruby 3.3.x + the standard library packed via wasi-vfs, compiled',
|
|
596
|
+
'to wasm32-unknown-wasi. The full Ruby standard library license list is in',
|
|
597
|
+
'the upstream LEGAL file: https://github.com/ruby/ruby/blob/master/LEGAL.',
|
|
598
|
+
'',
|
|
599
|
+
].join('\n');
|
|
600
|
+
}
|