@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,95 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* session/ws.ts — WebSocket lifecycle for the supervisor DO.
|
|
3
|
+
*
|
|
4
|
+
* One DO can host multiple WS kinds simultaneously: the user's shell
|
|
5
|
+
* terminal, cirrus-real HMR clients (one per browser tab on /preview),
|
|
6
|
+
* and process-log streams (one per `logs -f`). Without a discriminator
|
|
7
|
+
* a close on the HMR socket would null the shell's terminal and the
|
|
8
|
+
* user's tab would freeze (Audit F1). The wsKind() classifier reads
|
|
9
|
+
* the attachment tag set at upgrade time to route each lifecycle
|
|
10
|
+
* event to the right handler.
|
|
11
|
+
*
|
|
12
|
+
* Surfaces:
|
|
13
|
+
* - wsKind(ws) — pure attachment-tag classifier.
|
|
14
|
+
* - wsMessage(self, ws, m) — route by kind to terminal/HMR/process-logs.
|
|
15
|
+
* - wsClose(self, ws, ...) — Audit F1: HMR/process-logs close does
|
|
16
|
+
* NOT null shell/terminal/kernel; only shell-kind close does.
|
|
17
|
+
* - wsError(self, ws, err) — same discriminator; W5 ring-persist +
|
|
18
|
+
* W9 flush-on-close + recordFailure on error.
|
|
19
|
+
* - safePersistRing(self) — bridges _w5PersistRing → ctx.waitUntil.
|
|
20
|
+
*
|
|
21
|
+
* Per plan §IX.2 R3: this module does NOT export accept-* helpers
|
|
22
|
+
* (they live in -routes.ts when S9a lands). Routes call
|
|
23
|
+
* `self.acceptShellWebSocket(req)` via class delegators (when those
|
|
24
|
+
* land in S9a).
|
|
25
|
+
*
|
|
26
|
+
* Per plan §IX.4 R1: class delegators preserve method NAMES so DO
|
|
27
|
+
* runtime contract holds (`webSocketMessage`, `webSocketClose`,
|
|
28
|
+
* `webSocketError`).
|
|
29
|
+
*
|
|
30
|
+
* DEFECT-D1 pattern: `ctx` taken via `host.ctx` would TS-2412 against
|
|
31
|
+
* parent's `protected ctx`. Free functions accept ctx implicitly via
|
|
32
|
+
* `host as any` patterns where required (here only `safePersistRing`
|
|
33
|
+
* touches ctx.waitUntil; uses `(host.ctx as any)` cast).
|
|
34
|
+
*/
|
|
35
|
+
import { type FsWatchSub } from './fs-watch.js';
|
|
36
|
+
import type { ProcessLogStore } from '../runtime/process-logs.js';
|
|
37
|
+
import type { SqliteVFS } from '../vfs/sqlite-vfs.js';
|
|
38
|
+
import type { CirrusReal } from '../facets/cirrus-real.js';
|
|
39
|
+
import type { WebSocketTerminal } from '../facets/ws-terminal.js';
|
|
40
|
+
import type { Kernel, Shell } from '@lifo-sh/core';
|
|
41
|
+
/**
|
|
42
|
+
* Minimal host shape for WS lifecycle. Per plan §IX.1 b': fields here
|
|
43
|
+
* drop `private` on the class. `ctx` NOT on the interface (D1).
|
|
44
|
+
*/
|
|
45
|
+
export interface WsHost {
|
|
46
|
+
sqliteFs: SqliteVFS | null;
|
|
47
|
+
shell: Shell | null;
|
|
48
|
+
terminal: WebSocketTerminal | null;
|
|
49
|
+
kernel: Kernel | null;
|
|
50
|
+
cirrusReal: CirrusReal | null;
|
|
51
|
+
_cirrusHmrWsClients: Map<WebSocket, string> | null;
|
|
52
|
+
/** file-tree-watch (2026-05-15): per-WS fs-watch subscriptions.
|
|
53
|
+
* Keyed on the live WebSocket; cleaned up unconditionally in
|
|
54
|
+
* wsClose / wsError. See src/session/fs-watch.ts for the protocol
|
|
55
|
+
* + lifecycle. Optional (undefined) until first subscribe so
|
|
56
|
+
* memory stays at 0 for terminal-only sessions. */
|
|
57
|
+
_fsWatchSubs?: Map<WebSocket, FsWatchSub[]>;
|
|
58
|
+
processLogs: ProcessLogStore;
|
|
59
|
+
wranglerAliasBannerShown: boolean;
|
|
60
|
+
_w9PersistWired: boolean;
|
|
61
|
+
_w9FlushTimer: any;
|
|
62
|
+
_w9SchemaInit: boolean;
|
|
63
|
+
_w9IsolateGen: number;
|
|
64
|
+
_w9IsolateGenPersisted: boolean;
|
|
65
|
+
_w9WsConfig: any;
|
|
66
|
+
_diagPeakRss: number;
|
|
67
|
+
_diagPeakHeapUsed: number;
|
|
68
|
+
_w5LastPersistAt: number;
|
|
69
|
+
_w5LastPersistRingSize: number;
|
|
70
|
+
/** [B'.4] live phase indicator — see nimbus-session-internal.d.ts */
|
|
71
|
+
_b4Phase: import('../observability/oom-discriminator.js').SessionState | null;
|
|
72
|
+
_w5PersistRing(): Promise<void> | null;
|
|
73
|
+
_w9FlushOnClose(): void;
|
|
74
|
+
}
|
|
75
|
+
/**
|
|
76
|
+
* Classify a closing/erroring WebSocket by its serialized attachment.
|
|
77
|
+
* Shell sockets carry `{kind:'shell'}` (set at the /ws upgrade site);
|
|
78
|
+
* HMR sockets carry `{kind:'cirrus-hmr', clientId}` (set at :1240).
|
|
79
|
+
* Any other (undefined/unknown) attachment falls back to 'shell' to
|
|
80
|
+
* preserve pre-F1 behaviour for legacy accept sites.
|
|
81
|
+
*/
|
|
82
|
+
export declare function wsKind(ws: WebSocket): {
|
|
83
|
+
kind: string;
|
|
84
|
+
clientId?: string;
|
|
85
|
+
};
|
|
86
|
+
export declare function wsMessage(self: WsHost, ws: WebSocket, message: string | ArrayBuffer): Promise<void>;
|
|
87
|
+
export declare function wsClose(self: WsHost, ws: WebSocket, _code?: number, _reason?: string, _wasClean?: boolean): Promise<void>;
|
|
88
|
+
export declare function wsError(self: WsHost, ws: WebSocket, _error?: any): Promise<void>;
|
|
89
|
+
/**
|
|
90
|
+
* W5 Lever 5: bridge between _w5PersistRing (which returns a Promise)
|
|
91
|
+
* and ctx.waitUntil. Skipped silently if ctx.waitUntil isn't available
|
|
92
|
+
* (test contexts). Takes ctx via `(self as any).ctx` cast — D1 escape.
|
|
93
|
+
*/
|
|
94
|
+
export declare function safePersistRing(self: WsHost): void;
|
|
95
|
+
//# sourceMappingURL=ws.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ws.d.ts","sourceRoot":"","sources":["../../src/session/ws.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiCG;AAMH,OAAO,EAIL,KAAK,UAAU,EAChB,MAAM,eAAe,CAAC;AACvB,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,4BAA4B,CAAC;AAClE,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,sBAAsB,CAAC;AACtD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,0BAA0B,CAAC;AAC3D,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAC;AAClE,OAAO,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,eAAe,CAAC;AAEnD;;;GAGG;AACH,MAAM,WAAW,MAAM;IACrB,QAAQ,EAAE,SAAS,GAAG,IAAI,CAAC;IAC3B,KAAK,EAAE,KAAK,GAAG,IAAI,CAAC;IACpB,QAAQ,EAAE,iBAAiB,GAAG,IAAI,CAAC;IACnC,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,UAAU,EAAE,UAAU,GAAG,IAAI,CAAC;IAC9B,mBAAmB,EAAE,GAAG,CAAC,SAAS,EAAE,MAAM,CAAC,GAAG,IAAI,CAAC;IACnD;;;;wDAIoD;IACpD,YAAY,CAAC,EAAE,GAAG,CAAC,SAAS,EAAE,UAAU,EAAE,CAAC,CAAC;IAC5C,WAAW,EAAE,eAAe,CAAC;IAC7B,wBAAwB,EAAE,OAAO,CAAC;IAClC,eAAe,EAAE,OAAO,CAAC;IACzB,aAAa,EAAE,GAAG,CAAC;IACnB,aAAa,EAAE,OAAO,CAAC;IACvB,aAAa,EAAE,MAAM,CAAC;IACtB,sBAAsB,EAAE,OAAO,CAAC;IAChC,WAAW,EAAE,GAAG,CAAC;IACjB,YAAY,EAAE,MAAM,CAAC;IACrB,iBAAiB,EAAE,MAAM,CAAC;IAC1B,gBAAgB,EAAE,MAAM,CAAC;IACzB,sBAAsB,EAAE,MAAM,CAAC;IAC/B,qEAAqE;IACrE,QAAQ,EAAE,OAAO,uCAAuC,EAAE,YAAY,GAAG,IAAI,CAAC;IAC9E,cAAc,IAAI,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC;IACvC,eAAe,IAAI,IAAI,CAAC;CACzB;AAgDD;;;;;;GAMG;AACH,wBAAgB,MAAM,CAAC,EAAE,EAAE,SAAS,GAAG;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,EAAE,MAAM,CAAA;CAAE,CAQzE;AAED,wBAAsB,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE,SAAS,EAAE,OAAO,EAAE,MAAM,GAAG,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC,CAkEzG;AAED,wBAAsB,OAAO,CAC3B,IAAI,EAAE,MAAM,EACZ,EAAE,EAAE,SAAS,EACb,KAAK,CAAC,EAAE,MAAM,EACd,OAAO,CAAC,EAAE,MAAM,EAChB,SAAS,CAAC,EAAE,OAAO,GAClB,OAAO,CAAC,IAAI,CAAC,CAoGf;AAED,wBAAsB,OAAO,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE,SAAS,EAAE,MAAM,CAAC,EAAE,GAAG,GAAG,OAAO,CAAC,IAAI,CAAC,CA4EtF;AAED;;;;GAIG;AACH,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAUlD"}
|
|
@@ -0,0 +1,395 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* session/ws.ts — WebSocket lifecycle for the supervisor DO.
|
|
3
|
+
*
|
|
4
|
+
* One DO can host multiple WS kinds simultaneously: the user's shell
|
|
5
|
+
* terminal, cirrus-real HMR clients (one per browser tab on /preview),
|
|
6
|
+
* and process-log streams (one per `logs -f`). Without a discriminator
|
|
7
|
+
* a close on the HMR socket would null the shell's terminal and the
|
|
8
|
+
* user's tab would freeze (Audit F1). The wsKind() classifier reads
|
|
9
|
+
* the attachment tag set at upgrade time to route each lifecycle
|
|
10
|
+
* event to the right handler.
|
|
11
|
+
*
|
|
12
|
+
* Surfaces:
|
|
13
|
+
* - wsKind(ws) — pure attachment-tag classifier.
|
|
14
|
+
* - wsMessage(self, ws, m) — route by kind to terminal/HMR/process-logs.
|
|
15
|
+
* - wsClose(self, ws, ...) — Audit F1: HMR/process-logs close does
|
|
16
|
+
* NOT null shell/terminal/kernel; only shell-kind close does.
|
|
17
|
+
* - wsError(self, ws, err) — same discriminator; W5 ring-persist +
|
|
18
|
+
* W9 flush-on-close + recordFailure on error.
|
|
19
|
+
* - safePersistRing(self) — bridges _w5PersistRing → ctx.waitUntil.
|
|
20
|
+
*
|
|
21
|
+
* Per plan §IX.2 R3: this module does NOT export accept-* helpers
|
|
22
|
+
* (they live in -routes.ts when S9a lands). Routes call
|
|
23
|
+
* `self.acceptShellWebSocket(req)` via class delegators (when those
|
|
24
|
+
* land in S9a).
|
|
25
|
+
*
|
|
26
|
+
* Per plan §IX.4 R1: class delegators preserve method NAMES so DO
|
|
27
|
+
* runtime contract holds (`webSocketMessage`, `webSocketClose`,
|
|
28
|
+
* `webSocketError`).
|
|
29
|
+
*
|
|
30
|
+
* DEFECT-D1 pattern: `ctx` taken via `host.ctx` would TS-2412 against
|
|
31
|
+
* parent's `protected ctx`. Free functions accept ctx implicitly via
|
|
32
|
+
* `host as any` patterns where required (here only `safePersistRing`
|
|
33
|
+
* touches ctx.waitUntil; uses `(host.ctx as any)` cast).
|
|
34
|
+
*/
|
|
35
|
+
import { dec } from '../_shared/bytes.js';
|
|
36
|
+
import { recordFailure, getLastRpcFrame, getLastFacetId, recordRecoveryEvent } from '../observability/oom-discriminator.js';
|
|
37
|
+
import { persistShellState } from './state-store.js';
|
|
38
|
+
import { handleFsWatchSubscribe, handleFsWatchUnsubscribe, cleanupFsWatchOnClose, } from './fs-watch.js';
|
|
39
|
+
/**
|
|
40
|
+
* Snapshot the live Shell state and write it through to DO SQLite
|
|
41
|
+
* [Phase 3 B'.1].
|
|
42
|
+
*
|
|
43
|
+
* Called from wsMessage (post-process, every inbound keystroke) and
|
|
44
|
+
* once more in the wsClose / wsError shell-kind branch as a final
|
|
45
|
+
* safety net before the in-memory Shell is torn down.
|
|
46
|
+
*
|
|
47
|
+
* Read-only and synchronous (DO storage SQL is sync inside a request
|
|
48
|
+
* context). Cheap: one read of `shell.getCwd()` + `shell.getEnv()`,
|
|
49
|
+
* a JSON.stringify of env, and an INSERT-OR-REPLACE into the small
|
|
50
|
+
* nimbus_session_kv table. Skips the SQL write entirely when nothing
|
|
51
|
+
* has changed since the previous snapshot — the comparison is
|
|
52
|
+
* pointer-equality on cwd plus env reference, since Shell.getEnv()
|
|
53
|
+
* returns a live Record and `cd` mutates `this.cwd` in place.
|
|
54
|
+
*
|
|
55
|
+
* Failure model: persistShellState throws ONLY on env-too-large
|
|
56
|
+
* (the SESSION_ENV_MAX_BYTES gate). We surface that via console.warn
|
|
57
|
+
* — it indicates a misbehaving session that's exporting unbounded
|
|
58
|
+
* data, not an architectural bug. Suppressing the throw keeps the
|
|
59
|
+
* WS message handler running; the next snapshot retries.
|
|
60
|
+
*/
|
|
61
|
+
function snapshotShellState(self) {
|
|
62
|
+
const shell = self.shell;
|
|
63
|
+
if (!shell)
|
|
64
|
+
return;
|
|
65
|
+
const ctx = self.ctx;
|
|
66
|
+
if (!ctx?.storage?.sql)
|
|
67
|
+
return;
|
|
68
|
+
let cwd = null;
|
|
69
|
+
let env = null;
|
|
70
|
+
try {
|
|
71
|
+
cwd = shell.getCwd() || null;
|
|
72
|
+
}
|
|
73
|
+
catch { /* best-effort */ }
|
|
74
|
+
try {
|
|
75
|
+
const rawEnv = shell.getEnv();
|
|
76
|
+
if (rawEnv && typeof rawEnv === 'object') {
|
|
77
|
+
// Defensive copy. The Shell mutates this.env in place on
|
|
78
|
+
// export; we want the SQL write to reflect a stable view.
|
|
79
|
+
env = { ...rawEnv };
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
catch { /* best-effort */ }
|
|
83
|
+
if (!cwd && !env)
|
|
84
|
+
return;
|
|
85
|
+
try {
|
|
86
|
+
persistShellState(ctx, { cwd, env });
|
|
87
|
+
}
|
|
88
|
+
catch (e) {
|
|
89
|
+
console.warn('[nimbus/B\'.1] persistShellState failed:', e?.message || e);
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
/**
|
|
93
|
+
* Classify a closing/erroring WebSocket by its serialized attachment.
|
|
94
|
+
* Shell sockets carry `{kind:'shell'}` (set at the /ws upgrade site);
|
|
95
|
+
* HMR sockets carry `{kind:'cirrus-hmr', clientId}` (set at :1240).
|
|
96
|
+
* Any other (undefined/unknown) attachment falls back to 'shell' to
|
|
97
|
+
* preserve pre-F1 behaviour for legacy accept sites.
|
|
98
|
+
*/
|
|
99
|
+
export function wsKind(ws) {
|
|
100
|
+
try {
|
|
101
|
+
const att = ws.deserializeAttachment?.();
|
|
102
|
+
if (att && typeof att === 'object' && typeof att.kind === 'string') {
|
|
103
|
+
return att;
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
catch { /* deserializeAttachment is optional */ }
|
|
107
|
+
return { kind: 'shell' };
|
|
108
|
+
}
|
|
109
|
+
export async function wsMessage(self, ws, message) {
|
|
110
|
+
try {
|
|
111
|
+
// HMR clients: route messages to the facet via HmrBridge.
|
|
112
|
+
// We identify HMR sockets by the attachment tag set at accept time.
|
|
113
|
+
const attach = ws.deserializeAttachment?.();
|
|
114
|
+
if (attach?.kind === 'cirrus-hmr') {
|
|
115
|
+
const data = typeof message === 'string' ? message : dec.decode(message);
|
|
116
|
+
self.cirrusReal?.deliverHmrClientMessage(attach.clientId, data);
|
|
117
|
+
return;
|
|
118
|
+
}
|
|
119
|
+
// W9: process-logs sockets are output-only by contract. Drop
|
|
120
|
+
// any inbound frame; never let it parse-fail to the shell.
|
|
121
|
+
if (attach?.kind === 'process-logs') {
|
|
122
|
+
return;
|
|
123
|
+
}
|
|
124
|
+
const data = typeof message === 'string' ? message : dec.decode(message);
|
|
125
|
+
const msg = JSON.parse(data);
|
|
126
|
+
// file-tree-watch (2026-05-15): handle fs-watch-* on this WS BEFORE
|
|
127
|
+
// delegating to the terminal. These messages are WS-scoped (the
|
|
128
|
+
// bus listener captures `ws`), so the dispatch site needs the live
|
|
129
|
+
// ws ref — the terminal.onFs callback only has (msg, reply). Reply
|
|
130
|
+
// pattern mirrors the fs-* reqId-echo at ws-terminal.ts:142-150.
|
|
131
|
+
if (msg && (msg.type === 'fs-watch-subscribe' || msg.type === 'fs-watch-unsubscribe')) {
|
|
132
|
+
const reqId = msg.reqId;
|
|
133
|
+
const reply = (frame) => {
|
|
134
|
+
try {
|
|
135
|
+
const merged = (reqId !== undefined && frame && typeof frame === 'object')
|
|
136
|
+
? { ...frame, reqId }
|
|
137
|
+
: frame;
|
|
138
|
+
ws.send(JSON.stringify(merged));
|
|
139
|
+
}
|
|
140
|
+
catch { /* WS may be closing */ }
|
|
141
|
+
};
|
|
142
|
+
try {
|
|
143
|
+
if (msg.type === 'fs-watch-subscribe') {
|
|
144
|
+
const r = handleFsWatchSubscribe(self, ws, msg);
|
|
145
|
+
if (r.ok) {
|
|
146
|
+
reply({ type: 'fs-watch-subscribe-result', ok: true, subId: r.subId });
|
|
147
|
+
}
|
|
148
|
+
else {
|
|
149
|
+
reply({ type: 'fs-watch-subscribe-result', ok: false, error: r.error });
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
else {
|
|
153
|
+
const r = handleFsWatchUnsubscribe(self, ws, msg);
|
|
154
|
+
reply({ type: 'fs-watch-unsubscribe-result', ok: true, removed: r.removed });
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
catch (e) {
|
|
158
|
+
reply({
|
|
159
|
+
type: msg.type + '-result',
|
|
160
|
+
ok: false,
|
|
161
|
+
error: 'fs-watch handler threw: ' + (e?.message || String(e)),
|
|
162
|
+
});
|
|
163
|
+
}
|
|
164
|
+
return;
|
|
165
|
+
}
|
|
166
|
+
if (self.terminal)
|
|
167
|
+
self.terminal.handleMessage(msg);
|
|
168
|
+
// ── B'.1 snapshot ───────────────────────────────────────────────
|
|
169
|
+
// Persist Shell state to DO SQLite after the terminal has handled
|
|
170
|
+
// the user's keystroke. The Shell builtin `cd` mutates this.cwd
|
|
171
|
+
// synchronously inside executeLine, so by the time we reach this
|
|
172
|
+
// line a `cd app\r` has already taken effect and we capture the
|
|
173
|
+
// new cwd. Cheap when nothing has changed; SESSION_ENV_MAX_BYTES
|
|
174
|
+
// is the only failure mode and is logged, not thrown.
|
|
175
|
+
snapshotShellState(self);
|
|
176
|
+
}
|
|
177
|
+
catch (e) {
|
|
178
|
+
// Never let a message parsing error crash the DO
|
|
179
|
+
console.error('[nimbus] webSocketMessage error:', e?.message);
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
export async function wsClose(self, ws, _code, _reason, _wasClean) {
|
|
183
|
+
// Audit F1: discriminate by socket kind. Previously BOTH parameters
|
|
184
|
+
// were absent and every close — including preview-iframe HMR sockets
|
|
185
|
+
// closed by `vite stop` / navigation — nulled the session's
|
|
186
|
+
// shell/terminal/kernel, silently freezing the user's terminal tab.
|
|
187
|
+
const att = wsKind(ws);
|
|
188
|
+
// file-tree-watch (2026-05-15): drop any fs-watch subscriptions on
|
|
189
|
+
// this WS regardless of kind. Shell WS is the canonical carrier in
|
|
190
|
+
// practice; unconditional cleanup is defensive against any future
|
|
191
|
+
// WS kind that might subscribe. Idempotent + no-op when map empty.
|
|
192
|
+
try {
|
|
193
|
+
cleanupFsWatchOnClose(self, ws);
|
|
194
|
+
}
|
|
195
|
+
catch { /* best-effort */ }
|
|
196
|
+
// W9: process-logs sockets close routinely (user closes a log tab).
|
|
197
|
+
// Don't touch shell/terminal — and don't bother flushing here either
|
|
198
|
+
// because process-logs ws close doesn't imply session lifecycle.
|
|
199
|
+
if (att.kind === 'process-logs') {
|
|
200
|
+
return;
|
|
201
|
+
}
|
|
202
|
+
if (att.kind === 'cirrus-hmr') {
|
|
203
|
+
// HMR socket closed. Detach from the bridge + drop from the map.
|
|
204
|
+
// Do NOT touch shell/terminal/kernel — the user's terminal tab
|
|
205
|
+
// is still alive and has nothing to do with this HMR close.
|
|
206
|
+
try {
|
|
207
|
+
const clientId = att.clientId || self._cirrusHmrWsClients?.get(ws);
|
|
208
|
+
self._cirrusHmrWsClients?.delete(ws);
|
|
209
|
+
if (clientId)
|
|
210
|
+
self.cirrusReal?.detachHmrClient(clientId);
|
|
211
|
+
}
|
|
212
|
+
catch { /* best-effort */ }
|
|
213
|
+
return;
|
|
214
|
+
}
|
|
215
|
+
// Shell (or unknown legacy) socket close. Dev servers (vite,
|
|
216
|
+
// wrangler dev) + long-running facets must still survive the
|
|
217
|
+
// terminal reconnect (see 607e472 — do NOT kill running processes
|
|
218
|
+
// here). Only reap per-tab state.
|
|
219
|
+
// ── Phase 3 B'.1: transitionTo('drained') ──────────────────────────
|
|
220
|
+
// The Track B' state-machine transition. Persist final shell
|
|
221
|
+
// state + record a recovery_event BEFORE we null the in-memory
|
|
222
|
+
// Shell instance. The next /ws upgrade reads the SQL row and
|
|
223
|
+
// rebuilds the Shell with cwd + env intact — that's what makes
|
|
224
|
+
// recovery transparent.
|
|
225
|
+
//
|
|
226
|
+
// Order matters: snapshot first (so SQL has the latest cwd),
|
|
227
|
+
// then record the lifecycle event (so the C'.2 ring shows the
|
|
228
|
+
// transition AFTER the persist completed).
|
|
229
|
+
snapshotShellState(self);
|
|
230
|
+
try {
|
|
231
|
+
recordRecoveryEvent({
|
|
232
|
+
at: Date.now(),
|
|
233
|
+
fromState: 'active',
|
|
234
|
+
toState: 'drained',
|
|
235
|
+
trigger: 'ws-close',
|
|
236
|
+
isolateGen: self._w9IsolateGen,
|
|
237
|
+
dataLoss: false,
|
|
238
|
+
snapshotKeysRehydrated: 0,
|
|
239
|
+
});
|
|
240
|
+
}
|
|
241
|
+
catch { /* observability is non-critical */ }
|
|
242
|
+
// [B'.4] Update live phase indicator. The recordRecoveryEvent above
|
|
243
|
+
// is the legacy ring entry (active→drained); the field assignment
|
|
244
|
+
// surfaces the live phase via /api/_diag/session.phase.
|
|
245
|
+
self._b4Phase = 'drained';
|
|
246
|
+
if (self.sqliteFs) {
|
|
247
|
+
// Audit C1: flushAll() now throws when any chunk failed both
|
|
248
|
+
// its first attempt and the one-shot retry. Log loudly and
|
|
249
|
+
// clear so the next close doesn't re-throw.
|
|
250
|
+
try {
|
|
251
|
+
self.sqliteFs.flushAll();
|
|
252
|
+
}
|
|
253
|
+
catch (e) {
|
|
254
|
+
console.error('[nimbus] webSocketClose: flushAll failed —', e?.message || e);
|
|
255
|
+
try {
|
|
256
|
+
self.sqliteFs.clearWriteFailures();
|
|
257
|
+
}
|
|
258
|
+
catch { }
|
|
259
|
+
}
|
|
260
|
+
}
|
|
261
|
+
// W5 Lever 5: persist the OOM ring on close so cf-tail-style
|
|
262
|
+
// forensics survive DO hibernation. Gated on ctx.waitUntil so
|
|
263
|
+
// the close handler doesn't hang on storage. Skipped if ring
|
|
264
|
+
// is empty / unchanged.
|
|
265
|
+
safePersistRing(self);
|
|
266
|
+
// W9: flush any pending log writes so a hibernation cycle right
|
|
267
|
+
// after this close doesn't strand the in-memory ring. Synchronous
|
|
268
|
+
// SQL writes wrapped in transactionSync — fast (microseconds for
|
|
269
|
+
// typical buffer sizes); blocking is safer than racing waitUntil
|
|
270
|
+
// because flush() is what makes the logs survive.
|
|
271
|
+
self._w9FlushOnClose();
|
|
272
|
+
// [B'.5] Do NOT null self.shell / self.terminal / self.kernel. The
|
|
273
|
+
// DO is still alive (we're running this code right now); only the
|
|
274
|
+
// WS connection died. The Shell instance still holds the live
|
|
275
|
+
// cwd/env/lineBuffer state — keeping it in-memory means the next
|
|
276
|
+
// /ws upgrade can JOIN it (skip Phase B) instead of rebuilding from
|
|
277
|
+
// SQL. The terminal's underlying ws ref is stale, but a write
|
|
278
|
+
// attempt will throw on send() and be swallowed; the next /ws
|
|
279
|
+
// upgrade calls terminal.attach(newWs) to swap in the new socket.
|
|
280
|
+
//
|
|
281
|
+
// Pre-B'.5 we nulled these three fields to avoid two-tab cross-
|
|
282
|
+
// wiring (the 409 in nimbus-session-routes.ts:97 protected against
|
|
283
|
+
// overwriting an active shell). With phase=drained surfaced on the
|
|
284
|
+
// host, the /ws handler can disambiguate "warm session waiting for
|
|
285
|
+
// rejoin" (warmJoin path) from "active session busy" (still 409).
|
|
286
|
+
// Reset the one-shot "wrangler alias" banner so a reconnecting user
|
|
287
|
+
// sees it again — terminal-lifetime state, not session-lifetime.
|
|
288
|
+
self.wranglerAliasBannerShown = false;
|
|
289
|
+
}
|
|
290
|
+
export async function wsError(self, ws, _error) {
|
|
291
|
+
// Audit F1: same discriminator as webSocketClose. A socket error
|
|
292
|
+
// on an HMR WS must not take down the terminal tab.
|
|
293
|
+
const att = wsKind(ws);
|
|
294
|
+
// file-tree-watch (2026-05-15): drop fs-watch subscriptions on this
|
|
295
|
+
// WS. Mirror of the cleanup in wsClose above.
|
|
296
|
+
try {
|
|
297
|
+
cleanupFsWatchOnClose(self, ws);
|
|
298
|
+
}
|
|
299
|
+
catch { /* best-effort */ }
|
|
300
|
+
// W9: process-logs error — same drop-and-return policy as close.
|
|
301
|
+
if (att.kind === 'process-logs') {
|
|
302
|
+
return;
|
|
303
|
+
}
|
|
304
|
+
if (att.kind === 'cirrus-hmr') {
|
|
305
|
+
try {
|
|
306
|
+
const clientId = att.clientId || self._cirrusHmrWsClients?.get(ws);
|
|
307
|
+
self._cirrusHmrWsClients?.delete(ws);
|
|
308
|
+
if (clientId)
|
|
309
|
+
self.cirrusReal?.detachHmrClient(clientId);
|
|
310
|
+
}
|
|
311
|
+
catch { /* best-effort */ }
|
|
312
|
+
return;
|
|
313
|
+
}
|
|
314
|
+
// ── Phase 3 B'.1: transitionTo('drained') ──────────────────────────
|
|
315
|
+
// Same architectural step as wsClose: persist shell state + record
|
|
316
|
+
// a drained event before nulling. wsError is a different physical
|
|
317
|
+
// trigger (workerd cancelled the WS handler — typically the 5-s
|
|
318
|
+
// setHibernatableWebSocketEventTimeout cap) but the recovery
|
|
319
|
+
// shape is identical. The trigger label distinguishes them in
|
|
320
|
+
// the recovery_event ring.
|
|
321
|
+
snapshotShellState(self);
|
|
322
|
+
try {
|
|
323
|
+
recordRecoveryEvent({
|
|
324
|
+
at: Date.now(),
|
|
325
|
+
fromState: 'active',
|
|
326
|
+
toState: 'drained',
|
|
327
|
+
trigger: 'ws-error',
|
|
328
|
+
isolateGen: self._w9IsolateGen,
|
|
329
|
+
dataLoss: false,
|
|
330
|
+
snapshotKeysRehydrated: 0,
|
|
331
|
+
});
|
|
332
|
+
}
|
|
333
|
+
catch { /* observability is non-critical */ }
|
|
334
|
+
// [B'.4] Live phase indicator — same as wsClose path.
|
|
335
|
+
self._b4Phase = 'drained';
|
|
336
|
+
if (self.sqliteFs) {
|
|
337
|
+
try {
|
|
338
|
+
self.sqliteFs.flushAll();
|
|
339
|
+
}
|
|
340
|
+
catch (e) {
|
|
341
|
+
console.error('[nimbus] webSocketError: flushAll failed —', e?.message || e);
|
|
342
|
+
try {
|
|
343
|
+
self.sqliteFs.clearWriteFailures();
|
|
344
|
+
}
|
|
345
|
+
catch { }
|
|
346
|
+
}
|
|
347
|
+
}
|
|
348
|
+
// W5 Lever 5: persist OOM ring (same rationale as webSocketClose).
|
|
349
|
+
// Also synthesize a DiagFailure for the WS error itself if one
|
|
350
|
+
// hasn't already been recorded. Helps when a session vanishes
|
|
351
|
+
// without ever recording an explicit failure.
|
|
352
|
+
if (_error) {
|
|
353
|
+
try {
|
|
354
|
+
recordFailure({
|
|
355
|
+
at: Date.now(),
|
|
356
|
+
phase: 'ws',
|
|
357
|
+
cause: 'unknown',
|
|
358
|
+
rssEstimateBytes: self._diagPeakRss,
|
|
359
|
+
heapUsedBytes: self._diagPeakHeapUsed,
|
|
360
|
+
lruBytes: 0, inFlightBytes: 0,
|
|
361
|
+
lastRpcFrame: getLastRpcFrame(),
|
|
362
|
+
lastFacetId: getLastFacetId(),
|
|
363
|
+
message: _error?.message ?? String(_error),
|
|
364
|
+
});
|
|
365
|
+
}
|
|
366
|
+
catch { /* fail-soft */ }
|
|
367
|
+
}
|
|
368
|
+
safePersistRing(self);
|
|
369
|
+
// W9: same flush rationale as webSocketClose. An error on the shell
|
|
370
|
+
// socket commonly precedes hibernation by milliseconds.
|
|
371
|
+
self._w9FlushOnClose();
|
|
372
|
+
// [B'.5] Do NOT null shell/terminal/kernel — same rationale as
|
|
373
|
+
// wsClose. The Shell stays alive in-memory for the next /ws to
|
|
374
|
+
// join via the warmJoin path.
|
|
375
|
+
}
|
|
376
|
+
/**
|
|
377
|
+
* W5 Lever 5: bridge between _w5PersistRing (which returns a Promise)
|
|
378
|
+
* and ctx.waitUntil. Skipped silently if ctx.waitUntil isn't available
|
|
379
|
+
* (test contexts). Takes ctx via `(self as any).ctx` cast — D1 escape.
|
|
380
|
+
*/
|
|
381
|
+
export function safePersistRing(self) {
|
|
382
|
+
try {
|
|
383
|
+
const p = self._w5PersistRing();
|
|
384
|
+
const ctx = self.ctx;
|
|
385
|
+
if (p && ctx && typeof ctx.waitUntil === 'function') {
|
|
386
|
+
try {
|
|
387
|
+
ctx.waitUntil(p);
|
|
388
|
+
}
|
|
389
|
+
catch { /* best-effort */ }
|
|
390
|
+
}
|
|
391
|
+
}
|
|
392
|
+
catch (e) {
|
|
393
|
+
console.warn('[nimbus/W5] _w5SafePersistRing threw:', e?.message);
|
|
394
|
+
}
|
|
395
|
+
}
|