@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,93 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* w7-frame.ts — Wire protocol for streaming bulk-write payloads
|
|
3
|
+
* from facet to supervisor over RPC, bypassing the 32 MiB
|
|
4
|
+
* structured-clone cap.
|
|
5
|
+
*
|
|
6
|
+
* Frame format (W7 wire protocol v1):
|
|
7
|
+
*
|
|
8
|
+
* ┌─────────────────────────────────────────────────────────┐
|
|
9
|
+
* │ MAGIC: 4 bytes — 'NW7\x01' (Nimbus W7 v1) │
|
|
10
|
+
* │ HDR_LEN: 4 bytes uint32-LE — length of header JSON │
|
|
11
|
+
* │ HDR_JSON: HDR_LEN bytes UTF-8 JSON │
|
|
12
|
+
* │ { inodes: BatchInodeEntry[], deletePaths?: string[], │
|
|
13
|
+
* │ chunkCount: number } │
|
|
14
|
+
* │ For each chunk (chunkCount times): │
|
|
15
|
+
* │ PATH_LEN: 4 bytes uint32-LE │
|
|
16
|
+
* │ PATH_BYTES: PATH_LEN bytes UTF-8 │
|
|
17
|
+
* │ CHUNK_ID: 4 bytes uint32-LE │
|
|
18
|
+
* │ DATA_LEN: 4 bytes uint32-LE │
|
|
19
|
+
* │ DATA: DATA_LEN bytes raw │
|
|
20
|
+
* │ TRAILER: 4 bytes — 'NEND' │
|
|
21
|
+
* └─────────────────────────────────────────────────────────┘
|
|
22
|
+
*
|
|
23
|
+
* Why a custom frame and not CBOR / protobuf:
|
|
24
|
+
* - We control both ends; no schema-evolution constraint.
|
|
25
|
+
* - The whole point is byte-counted streaming with type: 'bytes'.
|
|
26
|
+
* - Adding a transport dep would bloat the facet preamble.
|
|
27
|
+
*
|
|
28
|
+
* Contract per Cloudflare Workers RPC docs
|
|
29
|
+
* (https://developers.cloudflare.com/workers/runtime-apis/rpc/):
|
|
30
|
+
*
|
|
31
|
+
* - Only byte-oriented streams (`type: 'bytes'`) traverse RPC.
|
|
32
|
+
* - Ownership transfers — sender cannot read after sending.
|
|
33
|
+
* - Flow control is automatic on the byte-stream.
|
|
34
|
+
*
|
|
35
|
+
* The encoder uses `type: 'bytes'` so the resulting stream is
|
|
36
|
+
* byob-readable, which is the precise requirement for RPC transit.
|
|
37
|
+
*/
|
|
38
|
+
import type { BatchInodeEntry, BatchChunkEntry, BatchWritePayload } from '../vfs/sqlite-vfs.js';
|
|
39
|
+
/** Magic bytes 'NW7\x01' — start of every W7 frame.
|
|
40
|
+
* Not Object.freeze'd: typed-array storage isn't a configurable property,
|
|
41
|
+
* so freezing throws on any later byte-write. We rely on internal
|
|
42
|
+
* discipline + .slice() at every emission point. */
|
|
43
|
+
export declare const W7_MAGIC: Uint8Array<ArrayBuffer>;
|
|
44
|
+
/** Trailer 'NEND' — sanity terminator. Same freeze caveat applies. */
|
|
45
|
+
export declare const W7_TRAILER: Uint8Array<ArrayBuffer>;
|
|
46
|
+
/** Diagnostics — peak in-flight bytes resident inside any active encoder
|
|
47
|
+
* queue since last reset. Used by the heap-peak probe to verify the
|
|
48
|
+
* ≤ 30 MiB acceptance gate. */
|
|
49
|
+
export declare function _peakInFlightBytes(): number;
|
|
50
|
+
/** Diagnostics — reset both peak and current counters. Intended for
|
|
51
|
+
* test isolation between scenarios. */
|
|
52
|
+
export declare function _resetPeakInFlightBytes(): void;
|
|
53
|
+
/**
|
|
54
|
+
* Encode a BatchWritePayload as a byte-oriented ReadableStream.
|
|
55
|
+
*
|
|
56
|
+
* Returns a `ReadableStream<Uint8Array>` with `type: 'bytes'` (BYOB
|
|
57
|
+
* readable, RPC-transferable). The stream:
|
|
58
|
+
* 1. Emits MAGIC.
|
|
59
|
+
* 2. Emits HDR_LEN + HDR_JSON encoding inode metadata, deletePaths,
|
|
60
|
+
* and chunkCount.
|
|
61
|
+
* 3. Emits each chunk record (PATH_LEN, PATH, CHUNK_ID, DATA_LEN, DATA).
|
|
62
|
+
* 4. Emits TRAILER.
|
|
63
|
+
* 5. Closes.
|
|
64
|
+
*
|
|
65
|
+
* Backpressure: the source uses `pull()` — the encoder produces the
|
|
66
|
+
* NEXT chunk only when the consumer has drained the queue below the
|
|
67
|
+
* HWM. Module-level `_currentInFlight` tracks queue residency for the
|
|
68
|
+
* heap-peak probe.
|
|
69
|
+
*/
|
|
70
|
+
export declare function encodeWriteBatchStream(payload: BatchWritePayload): ReadableStream<Uint8Array>;
|
|
71
|
+
/**
|
|
72
|
+
* Decode a W7 stream into a structured handle:
|
|
73
|
+
* - `inodes` and `deletePaths` are read eagerly (the header arrives
|
|
74
|
+
* in the first frame; metadata is small).
|
|
75
|
+
* - `chunkIter` is an AsyncIterable that yields `BatchChunkEntry`
|
|
76
|
+
* items one at a time, lazily, as bytes arrive.
|
|
77
|
+
*
|
|
78
|
+
* The chunk iterator is resumable but NOT seekable. The caller must
|
|
79
|
+
* iterate it linearly. Closing the iterator early is permitted (the
|
|
80
|
+
* underlying reader is released).
|
|
81
|
+
*
|
|
82
|
+
* Errors propagate:
|
|
83
|
+
* - Magic mismatch → rejects on the returned promise.
|
|
84
|
+
* - Truncated header → rejects on the returned promise.
|
|
85
|
+
* - Truncated chunk record → the iterator throws the error.
|
|
86
|
+
* - Source error mid-stream → the iterator throws the error.
|
|
87
|
+
*/
|
|
88
|
+
export declare function decodeWriteBatchStream(stream: ReadableStream<Uint8Array>): Promise<{
|
|
89
|
+
inodes: BatchInodeEntry[];
|
|
90
|
+
chunkIter: AsyncIterable<BatchChunkEntry>;
|
|
91
|
+
deletePaths?: string[];
|
|
92
|
+
}>;
|
|
93
|
+
//# sourceMappingURL=w7-frame.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"w7-frame.d.ts","sourceRoot":"","sources":["../../src/_shared/w7-frame.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAoCG;AAEH,OAAO,KAAK,EAAE,eAAe,EAAE,eAAe,EAAE,iBAAiB,EAAE,MAAM,sBAAsB,CAAC;AAIhG;;;qDAGqD;AACrD,eAAO,MAAM,QAAQ,yBAA2C,CAAC;AAEjE,sEAAsE;AACtE,eAAO,MAAM,UAAU,yBAA2C,CAAC;AAsBnE;;gCAEgC;AAChC,wBAAgB,kBAAkB,IAAI,MAAM,CAE3C;AAED;wCACwC;AACxC,wBAAgB,uBAAuB,IAAI,IAAI,CAG9C;AAcD;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,sBAAsB,CAAC,OAAO,EAAE,iBAAiB,GAAG,cAAc,CAAC,UAAU,CAAC,CAqH7F;AAID;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAsB,sBAAsB,CAC1C,MAAM,EAAE,cAAc,CAAC,UAAU,CAAC,GACjC,OAAO,CAAC;IACT,MAAM,EAAE,eAAe,EAAE,CAAC;IAC1B,SAAS,EAAE,aAAa,CAAC,eAAe,CAAC,CAAC;IAC1C,WAAW,CAAC,EAAE,MAAM,EAAE,CAAC;CACxB,CAAC,CAkFD"}
|
|
@@ -0,0 +1,402 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* w7-frame.ts — Wire protocol for streaming bulk-write payloads
|
|
3
|
+
* from facet to supervisor over RPC, bypassing the 32 MiB
|
|
4
|
+
* structured-clone cap.
|
|
5
|
+
*
|
|
6
|
+
* Frame format (W7 wire protocol v1):
|
|
7
|
+
*
|
|
8
|
+
* ┌─────────────────────────────────────────────────────────┐
|
|
9
|
+
* │ MAGIC: 4 bytes — 'NW7\x01' (Nimbus W7 v1) │
|
|
10
|
+
* │ HDR_LEN: 4 bytes uint32-LE — length of header JSON │
|
|
11
|
+
* │ HDR_JSON: HDR_LEN bytes UTF-8 JSON │
|
|
12
|
+
* │ { inodes: BatchInodeEntry[], deletePaths?: string[], │
|
|
13
|
+
* │ chunkCount: number } │
|
|
14
|
+
* │ For each chunk (chunkCount times): │
|
|
15
|
+
* │ PATH_LEN: 4 bytes uint32-LE │
|
|
16
|
+
* │ PATH_BYTES: PATH_LEN bytes UTF-8 │
|
|
17
|
+
* │ CHUNK_ID: 4 bytes uint32-LE │
|
|
18
|
+
* │ DATA_LEN: 4 bytes uint32-LE │
|
|
19
|
+
* │ DATA: DATA_LEN bytes raw │
|
|
20
|
+
* │ TRAILER: 4 bytes — 'NEND' │
|
|
21
|
+
* └─────────────────────────────────────────────────────────┘
|
|
22
|
+
*
|
|
23
|
+
* Why a custom frame and not CBOR / protobuf:
|
|
24
|
+
* - We control both ends; no schema-evolution constraint.
|
|
25
|
+
* - The whole point is byte-counted streaming with type: 'bytes'.
|
|
26
|
+
* - Adding a transport dep would bloat the facet preamble.
|
|
27
|
+
*
|
|
28
|
+
* Contract per Cloudflare Workers RPC docs
|
|
29
|
+
* (https://developers.cloudflare.com/workers/runtime-apis/rpc/):
|
|
30
|
+
*
|
|
31
|
+
* - Only byte-oriented streams (`type: 'bytes'`) traverse RPC.
|
|
32
|
+
* - Ownership transfers — sender cannot read after sending.
|
|
33
|
+
* - Flow control is automatic on the byte-stream.
|
|
34
|
+
*
|
|
35
|
+
* The encoder uses `type: 'bytes'` so the resulting stream is
|
|
36
|
+
* byob-readable, which is the precise requirement for RPC transit.
|
|
37
|
+
*/
|
|
38
|
+
// ── Constants ──────────────────────────────────────────────────────────
|
|
39
|
+
/** Magic bytes 'NW7\x01' — start of every W7 frame.
|
|
40
|
+
* Not Object.freeze'd: typed-array storage isn't a configurable property,
|
|
41
|
+
* so freezing throws on any later byte-write. We rely on internal
|
|
42
|
+
* discipline + .slice() at every emission point. */
|
|
43
|
+
export const W7_MAGIC = new Uint8Array([0x4e, 0x57, 0x37, 0x01]);
|
|
44
|
+
/** Trailer 'NEND' — sanity terminator. Same freeze caveat applies. */
|
|
45
|
+
export const W7_TRAILER = new Uint8Array([0x4e, 0x45, 0x4e, 0x44]);
|
|
46
|
+
/** Highwater mark for the encoder's queueing strategy. Bounds backpressure. */
|
|
47
|
+
const ENCODER_QUEUE_HWM = 256 * 1024;
|
|
48
|
+
/** Chunk-emit boundary inside the encoder (max bytes per ReadableStream
|
|
49
|
+
* enqueue). 64 KiB matches typical SqliteVFS chunk size. */
|
|
50
|
+
const ENCODER_EMIT_CAP = 64 * 1024;
|
|
51
|
+
// ── Diagnostics ────────────────────────────────────────────────────────
|
|
52
|
+
//
|
|
53
|
+
// W7-plan §9.4 — the heap-peak harness needs visibility into how many
|
|
54
|
+
// bytes are simultaneously resident inside the encoder's queue. We
|
|
55
|
+
// maintain a module-scoped peak counter that the test harness reads.
|
|
56
|
+
//
|
|
57
|
+
// Production code must NOT depend on this. It's purely diagnostic.
|
|
58
|
+
// `_resetPeakInFlightBytes()` is called at the start of each test
|
|
59
|
+
// scenario to isolate measurements.
|
|
60
|
+
let _peakInFlight = 0;
|
|
61
|
+
let _currentInFlight = 0;
|
|
62
|
+
/** Diagnostics — peak in-flight bytes resident inside any active encoder
|
|
63
|
+
* queue since last reset. Used by the heap-peak probe to verify the
|
|
64
|
+
* ≤ 30 MiB acceptance gate. */
|
|
65
|
+
export function _peakInFlightBytes() {
|
|
66
|
+
return _peakInFlight;
|
|
67
|
+
}
|
|
68
|
+
/** Diagnostics — reset both peak and current counters. Intended for
|
|
69
|
+
* test isolation between scenarios. */
|
|
70
|
+
export function _resetPeakInFlightBytes() {
|
|
71
|
+
_peakInFlight = 0;
|
|
72
|
+
_currentInFlight = 0;
|
|
73
|
+
}
|
|
74
|
+
function _trackInFlightAdd(n) {
|
|
75
|
+
_currentInFlight += n;
|
|
76
|
+
if (_currentInFlight > _peakInFlight)
|
|
77
|
+
_peakInFlight = _currentInFlight;
|
|
78
|
+
}
|
|
79
|
+
function _trackInFlightSub(n) {
|
|
80
|
+
_currentInFlight -= n;
|
|
81
|
+
if (_currentInFlight < 0)
|
|
82
|
+
_currentInFlight = 0;
|
|
83
|
+
}
|
|
84
|
+
// ── Encoder ────────────────────────────────────────────────────────────
|
|
85
|
+
/**
|
|
86
|
+
* Encode a BatchWritePayload as a byte-oriented ReadableStream.
|
|
87
|
+
*
|
|
88
|
+
* Returns a `ReadableStream<Uint8Array>` with `type: 'bytes'` (BYOB
|
|
89
|
+
* readable, RPC-transferable). The stream:
|
|
90
|
+
* 1. Emits MAGIC.
|
|
91
|
+
* 2. Emits HDR_LEN + HDR_JSON encoding inode metadata, deletePaths,
|
|
92
|
+
* and chunkCount.
|
|
93
|
+
* 3. Emits each chunk record (PATH_LEN, PATH, CHUNK_ID, DATA_LEN, DATA).
|
|
94
|
+
* 4. Emits TRAILER.
|
|
95
|
+
* 5. Closes.
|
|
96
|
+
*
|
|
97
|
+
* Backpressure: the source uses `pull()` — the encoder produces the
|
|
98
|
+
* NEXT chunk only when the consumer has drained the queue below the
|
|
99
|
+
* HWM. Module-level `_currentInFlight` tracks queue residency for the
|
|
100
|
+
* heap-peak probe.
|
|
101
|
+
*/
|
|
102
|
+
export function encodeWriteBatchStream(payload) {
|
|
103
|
+
const inodes = payload.inodes ?? [];
|
|
104
|
+
const chunks = payload.chunks ?? [];
|
|
105
|
+
const deletePaths = payload.deletePaths;
|
|
106
|
+
// Stream emission state:
|
|
107
|
+
// phase 0 = magic
|
|
108
|
+
// phase 1 = header (length-prefixed JSON)
|
|
109
|
+
// phase 2 = chunks (iterating)
|
|
110
|
+
// phase 3 = trailer
|
|
111
|
+
// phase 4 = closed
|
|
112
|
+
let phase = 0;
|
|
113
|
+
let chunkIdx = 0;
|
|
114
|
+
const enc = new TextEncoder();
|
|
115
|
+
const headerBytes = enc.encode(JSON.stringify({
|
|
116
|
+
inodes,
|
|
117
|
+
deletePaths,
|
|
118
|
+
chunkCount: chunks.length,
|
|
119
|
+
}));
|
|
120
|
+
// The DOM `ReadableStream<R>` constructor has two overloads keyed by
|
|
121
|
+
// the literal type of `source.type`. When the object literal's
|
|
122
|
+
// `type` is widened to `string` (as happens through @cloudflare's
|
|
123
|
+
// ambient-typed mods), TS picks the default-controller overload and
|
|
124
|
+
// rejects `'bytes'`. Build the source as `UnderlyingByteSource` and
|
|
125
|
+
// pass it through an explicit cast — runtime behaviour is unchanged.
|
|
126
|
+
const source = {
|
|
127
|
+
type: 'bytes',
|
|
128
|
+
pull(controller) {
|
|
129
|
+
// Each pull() emits ONE bounded record. The HWM combined with
|
|
130
|
+
// pull-on-demand means the queue holds at most ~1 emit-cap of
|
|
131
|
+
// bytes at a time — backpressure is automatic.
|
|
132
|
+
try {
|
|
133
|
+
if (phase === 0) {
|
|
134
|
+
enqueue(controller, W7_MAGIC.slice());
|
|
135
|
+
phase = 1;
|
|
136
|
+
return;
|
|
137
|
+
}
|
|
138
|
+
if (phase === 1) {
|
|
139
|
+
// HDR_LEN (uint32 LE) + HDR_JSON.
|
|
140
|
+
const hdr = new Uint8Array(4 + headerBytes.length);
|
|
141
|
+
writeU32LE(hdr, 0, headerBytes.length);
|
|
142
|
+
hdr.set(headerBytes, 4);
|
|
143
|
+
enqueue(controller, hdr);
|
|
144
|
+
phase = 2;
|
|
145
|
+
return;
|
|
146
|
+
}
|
|
147
|
+
if (phase === 2) {
|
|
148
|
+
if (chunkIdx >= chunks.length) {
|
|
149
|
+
phase = 3;
|
|
150
|
+
// Tail-call the trailer immediately so we don't waste a
|
|
151
|
+
// pull() iteration on a no-op.
|
|
152
|
+
}
|
|
153
|
+
else {
|
|
154
|
+
const c = chunks[chunkIdx++];
|
|
155
|
+
const pathBytes = enc.encode(c.path);
|
|
156
|
+
const data = c.data instanceof Uint8Array
|
|
157
|
+
? c.data
|
|
158
|
+
: new Uint8Array(c.data);
|
|
159
|
+
// Emit the chunk record. If the data exceeds the emit cap,
|
|
160
|
+
// split into multiple enqueues (header chunk first, then
|
|
161
|
+
// data segments). This bounds the per-pull queue load even
|
|
162
|
+
// for very large chunk payloads (rare in practice; SqliteVFS
|
|
163
|
+
// chunks are 64 KiB max).
|
|
164
|
+
const headerSize = 4 + pathBytes.length + 4 + 4;
|
|
165
|
+
const headerOut = new Uint8Array(headerSize);
|
|
166
|
+
let o = 0;
|
|
167
|
+
writeU32LE(headerOut, o, pathBytes.length);
|
|
168
|
+
o += 4;
|
|
169
|
+
headerOut.set(pathBytes, o);
|
|
170
|
+
o += pathBytes.length;
|
|
171
|
+
writeU32LE(headerOut, o, c.chunkId);
|
|
172
|
+
o += 4;
|
|
173
|
+
writeU32LE(headerOut, o, data.length);
|
|
174
|
+
o += 4;
|
|
175
|
+
enqueue(controller, headerOut);
|
|
176
|
+
// Chunk data — split by emit cap if oversize.
|
|
177
|
+
if (data.length === 0)
|
|
178
|
+
return;
|
|
179
|
+
if (data.length <= ENCODER_EMIT_CAP) {
|
|
180
|
+
enqueue(controller, data);
|
|
181
|
+
}
|
|
182
|
+
else {
|
|
183
|
+
for (let i = 0; i < data.length; i += ENCODER_EMIT_CAP) {
|
|
184
|
+
enqueue(controller, data.subarray(i, Math.min(i + ENCODER_EMIT_CAP, data.length)));
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
return;
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
if (phase === 3) {
|
|
191
|
+
enqueue(controller, W7_TRAILER.slice());
|
|
192
|
+
phase = 4;
|
|
193
|
+
controller.close();
|
|
194
|
+
return;
|
|
195
|
+
}
|
|
196
|
+
// phase === 4 — already closed; defensive.
|
|
197
|
+
controller.close();
|
|
198
|
+
}
|
|
199
|
+
catch (e) {
|
|
200
|
+
controller.error(e);
|
|
201
|
+
}
|
|
202
|
+
},
|
|
203
|
+
cancel() {
|
|
204
|
+
// Reset diagnostics on cancellation so a leaked counter doesn't
|
|
205
|
+
// pollute subsequent measurements.
|
|
206
|
+
phase = 4;
|
|
207
|
+
chunkIdx = chunks.length;
|
|
208
|
+
},
|
|
209
|
+
};
|
|
210
|
+
return new ReadableStream(source, {
|
|
211
|
+
// Byte streams (`type: 'bytes'`) MUST use the default byte-counted
|
|
212
|
+
// strategy: highWaterMark is in bytes, size is implicit. Custom
|
|
213
|
+
// `size` callbacks are forbidden — they throw at construction.
|
|
214
|
+
highWaterMark: ENCODER_QUEUE_HWM,
|
|
215
|
+
});
|
|
216
|
+
function enqueue(controller, bytes) {
|
|
217
|
+
_trackInFlightAdd(bytes.byteLength);
|
|
218
|
+
controller.enqueue(bytes);
|
|
219
|
+
// The bytes leave our queue once the consumer reads them. We can't
|
|
220
|
+
// observe that directly; we approximate by decrementing on the
|
|
221
|
+
// next microtask, which is when the read settles in workerd.
|
|
222
|
+
queueMicrotask(() => _trackInFlightSub(bytes.byteLength));
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
// ── Decoder ────────────────────────────────────────────────────────────
|
|
226
|
+
/**
|
|
227
|
+
* Decode a W7 stream into a structured handle:
|
|
228
|
+
* - `inodes` and `deletePaths` are read eagerly (the header arrives
|
|
229
|
+
* in the first frame; metadata is small).
|
|
230
|
+
* - `chunkIter` is an AsyncIterable that yields `BatchChunkEntry`
|
|
231
|
+
* items one at a time, lazily, as bytes arrive.
|
|
232
|
+
*
|
|
233
|
+
* The chunk iterator is resumable but NOT seekable. The caller must
|
|
234
|
+
* iterate it linearly. Closing the iterator early is permitted (the
|
|
235
|
+
* underlying reader is released).
|
|
236
|
+
*
|
|
237
|
+
* Errors propagate:
|
|
238
|
+
* - Magic mismatch → rejects on the returned promise.
|
|
239
|
+
* - Truncated header → rejects on the returned promise.
|
|
240
|
+
* - Truncated chunk record → the iterator throws the error.
|
|
241
|
+
* - Source error mid-stream → the iterator throws the error.
|
|
242
|
+
*/
|
|
243
|
+
export async function decodeWriteBatchStream(stream) {
|
|
244
|
+
const reader = stream.getReader();
|
|
245
|
+
// Pull byte-buffer of unread data; we accumulate as needed.
|
|
246
|
+
const buf = new ByteBuffer(reader);
|
|
247
|
+
// 1. Magic.
|
|
248
|
+
const magic = await buf.readExact(4, 'magic');
|
|
249
|
+
if (!bytesEqual(magic, W7_MAGIC)) {
|
|
250
|
+
try {
|
|
251
|
+
reader.releaseLock();
|
|
252
|
+
}
|
|
253
|
+
catch { /* best-effort */ }
|
|
254
|
+
throw new Error(`w7-frame: bad magic, expected NW7\\x01, got ${Array.from(magic).map(b => b.toString(16)).join(' ')}`);
|
|
255
|
+
}
|
|
256
|
+
// 2. Header length + JSON.
|
|
257
|
+
const hdrLenBytes = await buf.readExact(4, 'header-length');
|
|
258
|
+
const hdrLen = readU32LE(hdrLenBytes, 0);
|
|
259
|
+
if (hdrLen < 0 || hdrLen > 64 * 1024 * 1024) {
|
|
260
|
+
throw new Error(`w7-frame: implausible header length ${hdrLen}`);
|
|
261
|
+
}
|
|
262
|
+
const hdrJson = await buf.readExact(hdrLen, 'header-json');
|
|
263
|
+
let header;
|
|
264
|
+
try {
|
|
265
|
+
header = JSON.parse(new TextDecoder().decode(hdrJson));
|
|
266
|
+
}
|
|
267
|
+
catch (e) {
|
|
268
|
+
throw new Error(`w7-frame: header JSON parse failed: ${e?.message || e}`);
|
|
269
|
+
}
|
|
270
|
+
if (!header || !Array.isArray(header.inodes) || typeof header.chunkCount !== 'number') {
|
|
271
|
+
throw new Error('w7-frame: header missing required fields (inodes / chunkCount)');
|
|
272
|
+
}
|
|
273
|
+
// 3. Chunk iterator.
|
|
274
|
+
const chunkIter = {
|
|
275
|
+
[Symbol.asyncIterator]() {
|
|
276
|
+
let idx = 0;
|
|
277
|
+
let exhausted = false;
|
|
278
|
+
return {
|
|
279
|
+
async next() {
|
|
280
|
+
if (exhausted)
|
|
281
|
+
return { value: undefined, done: true };
|
|
282
|
+
if (idx >= header.chunkCount) {
|
|
283
|
+
// Read trailer.
|
|
284
|
+
const trailer = await buf.readExact(4, 'trailer');
|
|
285
|
+
if (!bytesEqual(trailer, W7_TRAILER)) {
|
|
286
|
+
throw new Error(`w7-frame: bad trailer, expected NEND, got ${Array.from(trailer).map(b => String.fromCharCode(b)).join('')}`);
|
|
287
|
+
}
|
|
288
|
+
try {
|
|
289
|
+
reader.releaseLock();
|
|
290
|
+
}
|
|
291
|
+
catch { /* best-effort */ }
|
|
292
|
+
exhausted = true;
|
|
293
|
+
return { value: undefined, done: true };
|
|
294
|
+
}
|
|
295
|
+
// PATH_LEN, PATH, CHUNK_ID, DATA_LEN, DATA.
|
|
296
|
+
const pathLenBytes = await buf.readExact(4, 'chunk-path-length');
|
|
297
|
+
const pathLen = readU32LE(pathLenBytes, 0);
|
|
298
|
+
if (pathLen < 0 || pathLen > 64 * 1024) {
|
|
299
|
+
throw new Error(`w7-frame: implausible path length ${pathLen} at chunk ${idx}`);
|
|
300
|
+
}
|
|
301
|
+
const pathBytes = await buf.readExact(pathLen, 'chunk-path');
|
|
302
|
+
const path = new TextDecoder().decode(pathBytes);
|
|
303
|
+
const chunkIdBytes = await buf.readExact(4, 'chunk-id');
|
|
304
|
+
const chunkId = readU32LE(chunkIdBytes, 0);
|
|
305
|
+
const dataLenBytes = await buf.readExact(4, 'chunk-data-length');
|
|
306
|
+
const dataLen = readU32LE(dataLenBytes, 0);
|
|
307
|
+
if (dataLen < 0 || dataLen > 64 * 1024 * 1024) {
|
|
308
|
+
throw new Error(`w7-frame: implausible data length ${dataLen} at chunk ${idx}`);
|
|
309
|
+
}
|
|
310
|
+
const data = await buf.readExact(dataLen, 'chunk-data');
|
|
311
|
+
idx++;
|
|
312
|
+
return { value: { path, chunkId, data }, done: false };
|
|
313
|
+
},
|
|
314
|
+
async return() {
|
|
315
|
+
exhausted = true;
|
|
316
|
+
try {
|
|
317
|
+
reader.releaseLock();
|
|
318
|
+
}
|
|
319
|
+
catch { /* best-effort */ }
|
|
320
|
+
return { value: undefined, done: true };
|
|
321
|
+
},
|
|
322
|
+
};
|
|
323
|
+
},
|
|
324
|
+
};
|
|
325
|
+
return {
|
|
326
|
+
inodes: header.inodes,
|
|
327
|
+
deletePaths: header.deletePaths,
|
|
328
|
+
chunkIter,
|
|
329
|
+
};
|
|
330
|
+
}
|
|
331
|
+
// ── Helpers ────────────────────────────────────────────────────────────
|
|
332
|
+
function writeU32LE(out, off, n) {
|
|
333
|
+
out[off] = n & 0xff;
|
|
334
|
+
out[off + 1] = (n >>> 8) & 0xff;
|
|
335
|
+
out[off + 2] = (n >>> 16) & 0xff;
|
|
336
|
+
out[off + 3] = (n >>> 24) & 0xff;
|
|
337
|
+
}
|
|
338
|
+
function readU32LE(buf, off) {
|
|
339
|
+
return (buf[off] | (buf[off + 1] << 8) | (buf[off + 2] << 16) | (buf[off + 3] << 24)) >>> 0;
|
|
340
|
+
}
|
|
341
|
+
function bytesEqual(a, b) {
|
|
342
|
+
if (a.length !== b.length)
|
|
343
|
+
return false;
|
|
344
|
+
for (let i = 0; i < a.length; i++)
|
|
345
|
+
if (a[i] !== b[i])
|
|
346
|
+
return false;
|
|
347
|
+
return true;
|
|
348
|
+
}
|
|
349
|
+
/**
|
|
350
|
+
* Lazy byte buffer over a ReadableStreamDefaultReader<Uint8Array>.
|
|
351
|
+
* `readExact(n, label)` returns a contiguous Uint8Array of exactly N
|
|
352
|
+
* bytes. Reads from the underlying reader as needed; throws if the
|
|
353
|
+
* stream ends before N bytes are available.
|
|
354
|
+
*
|
|
355
|
+
* NOTE: returns a fresh Uint8Array (copy). This costs a memcpy per
|
|
356
|
+
* read but simplifies lifetime — callers can hold the slice past the
|
|
357
|
+
* next read without worrying about buffer overwrites.
|
|
358
|
+
*/
|
|
359
|
+
class ByteBuffer {
|
|
360
|
+
reader;
|
|
361
|
+
chunks = [];
|
|
362
|
+
avail = 0;
|
|
363
|
+
done = false;
|
|
364
|
+
constructor(reader) {
|
|
365
|
+
this.reader = reader;
|
|
366
|
+
}
|
|
367
|
+
async readExact(n, label) {
|
|
368
|
+
if (n === 0)
|
|
369
|
+
return new Uint8Array(0);
|
|
370
|
+
while (this.avail < n) {
|
|
371
|
+
if (this.done) {
|
|
372
|
+
throw new Error(`w7-frame: stream ended ${this.avail} bytes into expected ${n}-byte ${label}`);
|
|
373
|
+
}
|
|
374
|
+
const { value, done } = await this.reader.read();
|
|
375
|
+
if (done) {
|
|
376
|
+
this.done = true;
|
|
377
|
+
}
|
|
378
|
+
else if (value && value.length > 0) {
|
|
379
|
+
this.chunks.push(value);
|
|
380
|
+
this.avail += value.length;
|
|
381
|
+
}
|
|
382
|
+
}
|
|
383
|
+
// Copy the first N bytes into a fresh slice; advance the buffer.
|
|
384
|
+
const out = new Uint8Array(n);
|
|
385
|
+
let copied = 0;
|
|
386
|
+
while (copied < n) {
|
|
387
|
+
const head = this.chunks[0];
|
|
388
|
+
const take = Math.min(head.length, n - copied);
|
|
389
|
+
out.set(head.subarray(0, take), copied);
|
|
390
|
+
copied += take;
|
|
391
|
+
if (take === head.length) {
|
|
392
|
+
this.chunks.shift();
|
|
393
|
+
}
|
|
394
|
+
else {
|
|
395
|
+
// Replace head with the unconsumed tail.
|
|
396
|
+
this.chunks[0] = head.subarray(take);
|
|
397
|
+
}
|
|
398
|
+
}
|
|
399
|
+
this.avail -= n;
|
|
400
|
+
return out;
|
|
401
|
+
}
|
|
402
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* auth/index.ts — Public re-exports for the Nimbus auth surface.
|
|
3
|
+
*
|
|
4
|
+
* Imported by:
|
|
5
|
+
* - `src/index.ts` (worker entry) for verify + idFromName scoping.
|
|
6
|
+
* - `src/_shared/session-router.ts` for the tenant-scoped DO instance name.
|
|
7
|
+
* - `@nimbus-sh/sdk/token` subpath re-exports issue/verify for embedder
|
|
8
|
+
* use in their own Worker (token mint endpoint) and CLI (`token mint`).
|
|
9
|
+
*
|
|
10
|
+
* Stable surface — anything not exported here is considered internal and
|
|
11
|
+
* may move/rename without notice. Anything exported here follows semver.
|
|
12
|
+
*/
|
|
13
|
+
export { issueNimbusToken, verifyNimbusToken, type NimbusAuthEnv, } from './token.js';
|
|
14
|
+
export { extractBearerToken, verifyRequestToken, requireScopes, requireSessionPin, setNimbusTokenCookie, authErrorResponse, NIMBUS_TOKEN_COOKIE, NIMBUS_TOKEN_QUERY, } from './middleware.js';
|
|
15
|
+
export { NimbusAuthError, NimbusAuthConfigError, NimbusTokenMalformedError, NimbusTokenSignatureError, NimbusTokenClaimsError, NimbusTokenExpiredError, NimbusTokenTtlError, NimbusScopeError, NimbusSessionPinError, DEFAULT_TOKEN_TTL_MS, MAX_TOKEN_TTL_MS, ID_COMPONENT_RE, type NimbusTokenClaims, type VerifiedNimbusToken, type IssueTokenOptions, } from './types.js';
|
|
16
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/auth/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,EACL,gBAAgB,EAChB,iBAAiB,EACjB,KAAK,aAAa,GACnB,MAAM,YAAY,CAAC;AAEpB,OAAO,EACL,kBAAkB,EAClB,kBAAkB,EAClB,aAAa,EACb,iBAAiB,EACjB,oBAAoB,EACpB,iBAAiB,EACjB,mBAAmB,EACnB,kBAAkB,GACnB,MAAM,iBAAiB,CAAC;AAEzB,OAAO,EACL,eAAe,EACf,qBAAqB,EACrB,yBAAyB,EACzB,yBAAyB,EACzB,sBAAsB,EACtB,uBAAuB,EACvB,mBAAmB,EACnB,gBAAgB,EAChB,qBAAqB,EACrB,oBAAoB,EACpB,gBAAgB,EAChB,eAAe,EACf,KAAK,iBAAiB,EACtB,KAAK,mBAAmB,EACxB,KAAK,iBAAiB,GACvB,MAAM,YAAY,CAAC"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* auth/index.ts — Public re-exports for the Nimbus auth surface.
|
|
3
|
+
*
|
|
4
|
+
* Imported by:
|
|
5
|
+
* - `src/index.ts` (worker entry) for verify + idFromName scoping.
|
|
6
|
+
* - `src/_shared/session-router.ts` for the tenant-scoped DO instance name.
|
|
7
|
+
* - `@nimbus-sh/sdk/token` subpath re-exports issue/verify for embedder
|
|
8
|
+
* use in their own Worker (token mint endpoint) and CLI (`token mint`).
|
|
9
|
+
*
|
|
10
|
+
* Stable surface — anything not exported here is considered internal and
|
|
11
|
+
* may move/rename without notice. Anything exported here follows semver.
|
|
12
|
+
*/
|
|
13
|
+
export { issueNimbusToken, verifyNimbusToken, } from './token.js';
|
|
14
|
+
export { extractBearerToken, verifyRequestToken, requireScopes, requireSessionPin, setNimbusTokenCookie, authErrorResponse, NIMBUS_TOKEN_COOKIE, NIMBUS_TOKEN_QUERY, } from './middleware.js';
|
|
15
|
+
export { NimbusAuthError, NimbusAuthConfigError, NimbusTokenMalformedError, NimbusTokenSignatureError, NimbusTokenClaimsError, NimbusTokenExpiredError, NimbusTokenTtlError, NimbusScopeError, NimbusSessionPinError, DEFAULT_TOKEN_TTL_MS, MAX_TOKEN_TTL_MS, ID_COMPONENT_RE, } from './types.js';
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* auth/middleware.ts — Request-time extract + verify glue.
|
|
3
|
+
*
|
|
4
|
+
* `extractBearerToken(request)` pulls the token from one of three places,
|
|
5
|
+
* in order of precedence:
|
|
6
|
+
* 1. `Authorization: Bearer <token>` header (canonical).
|
|
7
|
+
* 2. `?nimbus_token=<token>` query parameter (for `<iframe src>`).
|
|
8
|
+
* 3. `nimbus_token=<token>` cookie (for browser nav after the iframe
|
|
9
|
+
* sets it; the iframe can read its own cookie because cookies are
|
|
10
|
+
* scoped to the Nimbus origin, not the embedder's).
|
|
11
|
+
*
|
|
12
|
+
* The query/cookie fallbacks exist because `<iframe>` URLs are the
|
|
13
|
+
* canonical embed shape for `<NimbusTerminal>` and browsers don't let
|
|
14
|
+
* cross-origin iframes carry custom request headers on the initial
|
|
15
|
+
* navigation request. The cookie path is used for post-load nav inside
|
|
16
|
+
* the iframe (e.g. browser back/forward).
|
|
17
|
+
*
|
|
18
|
+
* NOTE: when the request comes from inside an `<iframe src="...?nimbus_token=...">`,
|
|
19
|
+
* we set the cookie on the response so subsequent in-iframe navigations
|
|
20
|
+
* don't need to re-pass the query param. See `setNimbusTokenCookie`.
|
|
21
|
+
*/
|
|
22
|
+
import { type NimbusAuthEnv } from './token.js';
|
|
23
|
+
import { type VerifiedNimbusToken } from './types.js';
|
|
24
|
+
/** Cookie name used for in-iframe token persistence. */
|
|
25
|
+
export declare const NIMBUS_TOKEN_COOKIE = "nimbus_token";
|
|
26
|
+
/** Query parameter name. */
|
|
27
|
+
export declare const NIMBUS_TOKEN_QUERY = "nimbus_token";
|
|
28
|
+
/**
|
|
29
|
+
* Pull a token from a Request. Returns null if absent (caller decides
|
|
30
|
+
* whether absence is an auth failure or just "anonymous").
|
|
31
|
+
*
|
|
32
|
+
* Precedence: Authorization header → query → cookie.
|
|
33
|
+
*/
|
|
34
|
+
export declare function extractBearerToken(request: Request): string | null;
|
|
35
|
+
/**
|
|
36
|
+
* Verify a token from a Request. Convenience wrapper around
|
|
37
|
+
* {@link extractBearerToken} + {@link verifyNimbusToken}.
|
|
38
|
+
*
|
|
39
|
+
* @throws {NimbusTokenMalformedError} when no token is present and
|
|
40
|
+
* `requireToken` is true (default).
|
|
41
|
+
* @throws Any error from {@link verifyNimbusToken}.
|
|
42
|
+
*/
|
|
43
|
+
export declare function verifyRequestToken(request: Request, env: NimbusAuthEnv, opts?: {
|
|
44
|
+
requireToken?: boolean;
|
|
45
|
+
}): Promise<VerifiedNimbusToken | null>;
|
|
46
|
+
/**
|
|
47
|
+
* Assert that the verified token carries every required scope.
|
|
48
|
+
*
|
|
49
|
+
* Tokens with `scopes === undefined` are treated as "all permitted"
|
|
50
|
+
* (legacy/full-trust). Tokens with an explicit `scopes` array must
|
|
51
|
+
* contain every entry in `required`.
|
|
52
|
+
*
|
|
53
|
+
* @throws {NimbusScopeError} on the first missing scope.
|
|
54
|
+
*/
|
|
55
|
+
export declare function requireScopes(verified: VerifiedNimbusToken, required: readonly string[]): void;
|
|
56
|
+
/**
|
|
57
|
+
* Assert that a sid-pinned token matches the session being attached. No-op
|
|
58
|
+
* if the token isn't sid-pinned.
|
|
59
|
+
*
|
|
60
|
+
* @throws {NimbusSessionPinError} on mismatch.
|
|
61
|
+
*/
|
|
62
|
+
export declare function requireSessionPin(verified: VerifiedNimbusToken, attemptedSessionId: string): void;
|
|
63
|
+
/**
|
|
64
|
+
* Build a Set-Cookie header value persisting the token in-iframe so
|
|
65
|
+
* subsequent navigations don't need the `?nimbus_token=` query.
|
|
66
|
+
*
|
|
67
|
+
* Cookie attributes:
|
|
68
|
+
* - HttpOnly: NO — JS in the iframe shell needs to forward the token
|
|
69
|
+
* to its WebSocket via subprotocol. Keep this in mind for XSS posture
|
|
70
|
+
* (Nimbus's xterm shell never executes embedder JS, mitigating risk).
|
|
71
|
+
* - Secure: YES (production).
|
|
72
|
+
* - SameSite=None: required because the iframe is cross-origin from
|
|
73
|
+
* the embedder's app. Pairs with Secure.
|
|
74
|
+
* - Path: scoped to `/s/` so non-session paths don't see the cookie.
|
|
75
|
+
* - Max-Age: matches the token's remaining lifetime.
|
|
76
|
+
*/
|
|
77
|
+
export declare function setNimbusTokenCookie(token: string, expSec: number, opts?: {
|
|
78
|
+
secure?: boolean;
|
|
79
|
+
}): string;
|
|
80
|
+
/**
|
|
81
|
+
* Map a NimbusAuthError to a `Response` suitable for the embedder's
|
|
82
|
+
* `fetch` handler to return. JSON body with `{ error, code }`.
|
|
83
|
+
*/
|
|
84
|
+
export declare function authErrorResponse(e: unknown): Response;
|
|
85
|
+
//# sourceMappingURL=middleware.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"middleware.d.ts","sourceRoot":"","sources":["../../src/auth/middleware.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AAEH,OAAO,EAAqB,KAAK,aAAa,EAAE,MAAM,YAAY,CAAC;AACnE,OAAO,EAKL,KAAK,mBAAmB,EACzB,MAAM,YAAY,CAAC;AAEpB,wDAAwD;AACxD,eAAO,MAAM,mBAAmB,iBAAiB,CAAC;AAElD,4BAA4B;AAC5B,eAAO,MAAM,kBAAkB,iBAAiB,CAAC;AAEjD;;;;;GAKG;AACH,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,OAAO,GAAG,MAAM,GAAG,IAAI,CAoBlE;AAED;;;;;;;GAOG;AACH,wBAAsB,kBAAkB,CACtC,OAAO,EAAE,OAAO,EAChB,GAAG,EAAE,aAAa,EAClB,IAAI,GAAE;IAAE,YAAY,CAAC,EAAE,OAAO,CAAA;CAAO,GACpC,OAAO,CAAC,mBAAmB,GAAG,IAAI,CAAC,CASrC;AAED;;;;;;;;GAQG;AACH,wBAAgB,aAAa,CAC3B,QAAQ,EAAE,mBAAmB,EAC7B,QAAQ,EAAE,SAAS,MAAM,EAAE,GAC1B,IAAI,CAON;AAED;;;;;GAKG;AACH,wBAAgB,iBAAiB,CAC/B,QAAQ,EAAE,mBAAmB,EAC7B,kBAAkB,EAAE,MAAM,GACzB,IAAI,CAIN;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,IAAI,GAAE;IAAE,MAAM,CAAC,EAAE,OAAO,CAAA;CAAO,GAAG,MAAM,CAY3G;AAED;;;GAGG;AACH,wBAAgB,iBAAiB,CAAC,CAAC,EAAE,OAAO,GAAG,QAAQ,CAoBtD"}
|