@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,166 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* heap-estimate.ts — deterministic supervisor-heap estimator [C'.1]
|
|
3
|
+
*
|
|
4
|
+
* Why this module exists
|
|
5
|
+
* ──────────────────────
|
|
6
|
+
* `process.memoryUsage()` returns 0 for every field inside a Durable
|
|
7
|
+
* Object class context (only dynamic-worker isolates under nodejs_compat
|
|
8
|
+
* get the real implementation). The previous `readNodeMem` /
|
|
9
|
+
* `sampleMemory` helpers in nimbus-session-diag.ts called it anyway and
|
|
10
|
+
* therefore reported zero forever — useless for verifying memory-
|
|
11
|
+
* containment work in plan §3 Track A'.
|
|
12
|
+
*
|
|
13
|
+
* Replacement: a deterministic estimator that sums KNOWN supervisor heap
|
|
14
|
+
* allocation sources from runtime counters that ARE accurate
|
|
15
|
+
* (diag-counters.ts singleton + SqliteVFS.getStats()). Every byte has a
|
|
16
|
+
* named contributor; a regression in any one component is locatable.
|
|
17
|
+
*
|
|
18
|
+
* The estimator is INTENTIONALLY conservative: each component reports a
|
|
19
|
+
* peak-or-current value, and the total may overestimate (in-flight bytes
|
|
20
|
+
* are counted before they're freed; LRU bytes are the cap, not always
|
|
21
|
+
* the current footprint). Better to over-report than under-report when
|
|
22
|
+
* the alternative is the zero-everywhere status quo.
|
|
23
|
+
*
|
|
24
|
+
* Eviction-label taxonomy
|
|
25
|
+
* ───────────────────────
|
|
26
|
+
* Workerd (per docs/research/cf-internal-dossier.md §9.2 metrics.h:300)
|
|
27
|
+
* distinguishes five labelled eviction reasons:
|
|
28
|
+
* - lru → memory pressure on the runtime process
|
|
29
|
+
* - condemned → kill (operator / abuse pipeline)
|
|
30
|
+
* - inactive → idle eviction (70-140 s of no traffic)
|
|
31
|
+
* - dynamic_worker → per-owner LRU cap (default 50)
|
|
32
|
+
* - dynamic_worker_banned → Dice abuse-detection ban
|
|
33
|
+
*
|
|
34
|
+
* Nimbus surfaces the labels here so any tool that reads
|
|
35
|
+
* /api/_diag/memory has a fixed, well-known taxonomy to count against.
|
|
36
|
+
* The actual count of evictions Nimbus has observed lives in the C'.2
|
|
37
|
+
* recovery_event ring, separate from this module.
|
|
38
|
+
*/
|
|
39
|
+
import type { DiagCounters } from './diag-counters.js';
|
|
40
|
+
/**
|
|
41
|
+
* Five labelled workerd eviction reasons. Surfaced as a constant
|
|
42
|
+
* taxonomy in /api/_diag/memory so any consumer can count observed
|
|
43
|
+
* events against the well-known set.
|
|
44
|
+
*
|
|
45
|
+
* Source: cloudflare/ew/edgeworker metrics.c++:1778-1790 + metrics.h:300.
|
|
46
|
+
* Cross-cited in docs/research/cf-internal-dossier.md §9.2.
|
|
47
|
+
*/
|
|
48
|
+
export declare const WORKERD_EVICTION_LABELS: readonly ["lru", "condemned", "inactive", "dynamic_worker", "dynamic_worker_banned"];
|
|
49
|
+
export type WorkerdEvictionLabel = typeof WORKERD_EVICTION_LABELS[number];
|
|
50
|
+
/**
|
|
51
|
+
* Supervisor heap snapshot. Components are PEAK-OR-CURRENT bytes from
|
|
52
|
+
* runtime counters; the estimator never calls process.memoryUsage().
|
|
53
|
+
*/
|
|
54
|
+
export interface HeapEstimate {
|
|
55
|
+
/** Sum of all components below. Always equals breakdown sum. */
|
|
56
|
+
estimatedBytes: number;
|
|
57
|
+
/** SUPERVISOR_HEAP_CEILING_BYTES (constant — 64 MiB by design). */
|
|
58
|
+
ceilingBytes: number;
|
|
59
|
+
/** estimatedBytes / ceilingBytes × 100, one decimal place. */
|
|
60
|
+
percentOfCeiling: number;
|
|
61
|
+
/** Per-source byte attribution. */
|
|
62
|
+
breakdown: HeapBreakdown;
|
|
63
|
+
}
|
|
64
|
+
export interface HeapBreakdown {
|
|
65
|
+
/** Static module bundle + runtime baseline. Constant per build. */
|
|
66
|
+
supervisorBaselineBytes: number;
|
|
67
|
+
/** SqliteVFS LRU cache hot-byte count (sqlite-vfs.ts cache.hotBytes). */
|
|
68
|
+
vfsLruBytes: number;
|
|
69
|
+
/** SqliteVFS in-flight write payload bytes (peak observed). */
|
|
70
|
+
vfsInFlightBytes: number;
|
|
71
|
+
/** Resolver in-flight packument bytes (rough cap = live stubs × last
|
|
72
|
+
* packument size). Post A'.1 the resolver runs in a facet and this
|
|
73
|
+
* is always 0; the slot is preserved so a regression that
|
|
74
|
+
* re-introduces supervisor-side resolution is locatable. */
|
|
75
|
+
resolverInFlightBytes: number;
|
|
76
|
+
/** Pre-bundle slice bytes resident in supervisor heap (peak across
|
|
77
|
+
* in-flight pool slots × SLICE_CAP_BYTES). Drops to 0 once
|
|
78
|
+
* A'.2/A'.3 stream the slice through ReadableStream-over-RPC. */
|
|
79
|
+
preBundleSliceBytes: number;
|
|
80
|
+
/** esbuild-wasm bytes resident in supervisor. Phase 2 A'.5 moved
|
|
81
|
+
* these to env.ASSETS; the slot is 0 by construction now. */
|
|
82
|
+
esbuildResidentBytes: number;
|
|
83
|
+
/**
|
|
84
|
+
* In-flight supervisor RPC payload bytes (Phase 2 A'.2).
|
|
85
|
+
*
|
|
86
|
+
* Sum of bytes claimed by RPC handlers in src/supervisor-rpc.ts
|
|
87
|
+
* between RPC entry and exit — writeBatch / writeBatchStream /
|
|
88
|
+
* putRegistryEntries / R2 cache RPC return values. Tracked by
|
|
89
|
+
* `inFlightRpcPayloadBytes` in src/diag-counters.ts; bumped at
|
|
90
|
+
* RPC entry, debited in `finally`.
|
|
91
|
+
*
|
|
92
|
+
* At idle this is 0. Under load it should stay bounded by the
|
|
93
|
+
* largest single in-flight RPC's payload (~few MiB for writeBatch).
|
|
94
|
+
* Persistent non-zero readings here mean an RPC handler isn't
|
|
95
|
+
* decrementing on its failure path — a leak worth fixing.
|
|
96
|
+
*/
|
|
97
|
+
streamingBuffersBytes: number;
|
|
98
|
+
}
|
|
99
|
+
/**
|
|
100
|
+
* Inputs the estimator needs from the SqliteVFS layer. Kept narrow
|
|
101
|
+
* (just the two fields we actually consume) to avoid a circular import
|
|
102
|
+
* between observability/ and the VFS module.
|
|
103
|
+
*/
|
|
104
|
+
export interface VfsHeapInputs {
|
|
105
|
+
/** SqliteVFS.getStats().cache.hotBytes — actual LRU memory in use. */
|
|
106
|
+
cacheHotBytes: number;
|
|
107
|
+
/** Current sum of in-flight write payloads (or 0 if none). */
|
|
108
|
+
inFlightWriteBytes: number;
|
|
109
|
+
}
|
|
110
|
+
/**
|
|
111
|
+
* Maximum SqliteVFS LRU footprint (architectural cap). Used as the
|
|
112
|
+
* upper bound for the LRU contribution when the SqliteVFS hasn't been
|
|
113
|
+
* instantiated yet (cacheHotBytes = 0 from the inputs).
|
|
114
|
+
*
|
|
115
|
+
* Defensive — the live cacheHotBytes is the source of truth once the
|
|
116
|
+
* VFS exists. This value is NOT used in production; the estimator
|
|
117
|
+
* receives the live count via VfsHeapInputs.
|
|
118
|
+
*/
|
|
119
|
+
export declare const VFS_LRU_MAX_BYTES: number;
|
|
120
|
+
/**
|
|
121
|
+
* Estimate resolver in-flight bytes from diag-counters.
|
|
122
|
+
*
|
|
123
|
+
* The resolver in-supervisor path (pre-A'.1) holds packument JSON in
|
|
124
|
+
* memory while parsing. We don't have a "current in-flight bytes"
|
|
125
|
+
* counter directly, but we DO have:
|
|
126
|
+
* - inFlightPackumentFetches (live count of awaited fetches)
|
|
127
|
+
* - lastPackumentBytes (size of the most recent packument)
|
|
128
|
+
*
|
|
129
|
+
* Average packument size on real registries is dominated by the largest
|
|
130
|
+
* outliers (lucide-react, framer-motion at ~5 MiB each) so using
|
|
131
|
+
* lastPackumentBytes as a per-fetch upper bound is a reasonable proxy.
|
|
132
|
+
*
|
|
133
|
+
* Caller can also pass an explicit `cumulativeBytesDecoded` snapshot
|
|
134
|
+
* (resolverPath = 'in-supervisor') for a different estimation strategy
|
|
135
|
+
* — but right now the most useful signal is "is the resolver currently
|
|
136
|
+
* holding bytes in supervisor heap or has it moved to a facet?".
|
|
137
|
+
*
|
|
138
|
+
* After A'.1 lands and resolverPath becomes hard-pinned to 'in-facet',
|
|
139
|
+
* this contribution drops to 0 by construction.
|
|
140
|
+
*/
|
|
141
|
+
export declare function estimateResolverInFlightBytes(c: DiagCounters): number;
|
|
142
|
+
/**
|
|
143
|
+
* Estimate pre-bundle slice bytes resident in the supervisor heap.
|
|
144
|
+
*
|
|
145
|
+
* Pre A'.2: the supervisor builds the slice in heap (up to
|
|
146
|
+
* SLICE_CAP_BYTES = 28 MiB per concurrent slot) before passing to the
|
|
147
|
+
* pre-bundle facet. With PRE_BUNDLE_CONCURRENCY = 1 the cap is 28 MiB.
|
|
148
|
+
*
|
|
149
|
+
* Diag counters track pre-bundle attempts/completions but not
|
|
150
|
+
* in-flight slice bytes specifically. Until A'.2 streams the slice,
|
|
151
|
+
* we treat the slice as PRESENT in supervisor heap iff the pre-bundle
|
|
152
|
+
* phase is active AND a slot is in flight (no completion yet for the
|
|
153
|
+
* current attempted count).
|
|
154
|
+
*
|
|
155
|
+
* After A'.2 lands the slice flows via ReadableStream-over-RPC and
|
|
156
|
+
* supervisor never holds the bytes — this contribution drops to 0.
|
|
157
|
+
*/
|
|
158
|
+
export declare function estimatePreBundleSliceBytes(c: DiagCounters): number;
|
|
159
|
+
/**
|
|
160
|
+
* Build a heap estimate from runtime counters + VFS inputs.
|
|
161
|
+
*
|
|
162
|
+
* Pure function — no I/O, microsecond cost. Called from the
|
|
163
|
+
* /api/_diag/memory request handler.
|
|
164
|
+
*/
|
|
165
|
+
export declare function estimateSupervisorHeap(c: DiagCounters, vfs: VfsHeapInputs): HeapEstimate;
|
|
166
|
+
//# sourceMappingURL=heap-estimate.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"heap-estimate.d.ts","sourceRoot":"","sources":["../../src/observability/heap-estimate.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAqCG;AAGH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAEvD;;;;;;;GAOG;AACH,eAAO,MAAM,uBAAuB,sFAM1B,CAAC;AAEX,MAAM,MAAM,oBAAoB,GAAG,OAAO,uBAAuB,CAAC,MAAM,CAAC,CAAC;AAE1E;;;GAGG;AACH,MAAM,WAAW,YAAY;IAC3B,gEAAgE;IAChE,cAAc,EAAE,MAAM,CAAC;IACvB,mEAAmE;IACnE,YAAY,EAAE,MAAM,CAAC;IACrB,8DAA8D;IAC9D,gBAAgB,EAAE,MAAM,CAAC;IACzB,mCAAmC;IACnC,SAAS,EAAE,aAAa,CAAC;CAC1B;AAED,MAAM,WAAW,aAAa;IAC5B,mEAAmE;IACnE,uBAAuB,EAAE,MAAM,CAAC;IAChC,yEAAyE;IACzE,WAAW,EAAE,MAAM,CAAC;IACpB,+DAA+D;IAC/D,gBAAgB,EAAE,MAAM,CAAC;IACzB;;;iEAG6D;IAC7D,qBAAqB,EAAE,MAAM,CAAC;IAC9B;;sEAEkE;IAClE,mBAAmB,EAAE,MAAM,CAAC;IAC5B;kEAC8D;IAC9D,oBAAoB,EAAE,MAAM,CAAC;IAC7B;;;;;;;;;;;;;OAaG;IACH,qBAAqB,EAAE,MAAM,CAAC;CAC/B;AAED;;;;GAIG;AACH,MAAM,WAAW,aAAa;IAC5B,sEAAsE;IACtE,aAAa,EAAE,MAAM,CAAC;IACtB,8DAA8D;IAC9D,kBAAkB,EAAE,MAAM,CAAC;CAC5B;AAyCD;;;;;;;;GAQG;AACH,eAAO,MAAM,iBAAiB,QAA+B,CAAC;AAE9D;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,wBAAgB,6BAA6B,CAAC,CAAC,EAAE,YAAY,GAAG,MAAM,CAQrE;AAED;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,2BAA2B,CAAC,CAAC,EAAE,YAAY,GAAG,MAAM,CAWnE;AAED;;;;;GAKG;AACH,wBAAgB,sBAAsB,CACpC,CAAC,EAAE,YAAY,EACf,GAAG,EAAE,aAAa,GACjB,YAAY,CA8Bd"}
|
|
@@ -0,0 +1,192 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* heap-estimate.ts — deterministic supervisor-heap estimator [C'.1]
|
|
3
|
+
*
|
|
4
|
+
* Why this module exists
|
|
5
|
+
* ──────────────────────
|
|
6
|
+
* `process.memoryUsage()` returns 0 for every field inside a Durable
|
|
7
|
+
* Object class context (only dynamic-worker isolates under nodejs_compat
|
|
8
|
+
* get the real implementation). The previous `readNodeMem` /
|
|
9
|
+
* `sampleMemory` helpers in nimbus-session-diag.ts called it anyway and
|
|
10
|
+
* therefore reported zero forever — useless for verifying memory-
|
|
11
|
+
* containment work in plan §3 Track A'.
|
|
12
|
+
*
|
|
13
|
+
* Replacement: a deterministic estimator that sums KNOWN supervisor heap
|
|
14
|
+
* allocation sources from runtime counters that ARE accurate
|
|
15
|
+
* (diag-counters.ts singleton + SqliteVFS.getStats()). Every byte has a
|
|
16
|
+
* named contributor; a regression in any one component is locatable.
|
|
17
|
+
*
|
|
18
|
+
* The estimator is INTENTIONALLY conservative: each component reports a
|
|
19
|
+
* peak-or-current value, and the total may overestimate (in-flight bytes
|
|
20
|
+
* are counted before they're freed; LRU bytes are the cap, not always
|
|
21
|
+
* the current footprint). Better to over-report than under-report when
|
|
22
|
+
* the alternative is the zero-everywhere status quo.
|
|
23
|
+
*
|
|
24
|
+
* Eviction-label taxonomy
|
|
25
|
+
* ───────────────────────
|
|
26
|
+
* Workerd (per docs/research/cf-internal-dossier.md §9.2 metrics.h:300)
|
|
27
|
+
* distinguishes five labelled eviction reasons:
|
|
28
|
+
* - lru → memory pressure on the runtime process
|
|
29
|
+
* - condemned → kill (operator / abuse pipeline)
|
|
30
|
+
* - inactive → idle eviction (70-140 s of no traffic)
|
|
31
|
+
* - dynamic_worker → per-owner LRU cap (default 50)
|
|
32
|
+
* - dynamic_worker_banned → Dice abuse-detection ban
|
|
33
|
+
*
|
|
34
|
+
* Nimbus surfaces the labels here so any tool that reads
|
|
35
|
+
* /api/_diag/memory has a fixed, well-known taxonomy to count against.
|
|
36
|
+
* The actual count of evictions Nimbus has observed lives in the C'.2
|
|
37
|
+
* recovery_event ring, separate from this module.
|
|
38
|
+
*/
|
|
39
|
+
import { CHUNK_SIZE, LRU_MAX_ENTRIES, SUPERVISOR_HEAP_CEILING_BYTES } from '../constants.js';
|
|
40
|
+
/**
|
|
41
|
+
* Five labelled workerd eviction reasons. Surfaced as a constant
|
|
42
|
+
* taxonomy in /api/_diag/memory so any consumer can count observed
|
|
43
|
+
* events against the well-known set.
|
|
44
|
+
*
|
|
45
|
+
* Source: cloudflare/ew/edgeworker metrics.c++:1778-1790 + metrics.h:300.
|
|
46
|
+
* Cross-cited in docs/research/cf-internal-dossier.md §9.2.
|
|
47
|
+
*/
|
|
48
|
+
export const WORKERD_EVICTION_LABELS = [
|
|
49
|
+
'lru',
|
|
50
|
+
'condemned',
|
|
51
|
+
'inactive',
|
|
52
|
+
'dynamic_worker',
|
|
53
|
+
'dynamic_worker_banned',
|
|
54
|
+
];
|
|
55
|
+
// ── Architectural constants for non-counter contributors ────────────────
|
|
56
|
+
//
|
|
57
|
+
// Each constant below has a comment explaining the source-of-truth and
|
|
58
|
+
// when it is expected to change (typically: when a Track A' wave lands).
|
|
59
|
+
// They are NOT runtime-measured because the underlying values aren't
|
|
60
|
+
// observable from JS — they're properties of the worker bundle itself.
|
|
61
|
+
/**
|
|
62
|
+
* Static supervisor baseline. The compiled worker bundle resident in V8
|
|
63
|
+
* isolate memory: module sources, class definitions, top-level imports,
|
|
64
|
+
* lookup tables.
|
|
65
|
+
*
|
|
66
|
+
* Phase 2 A'.5 dropped the 16 MiB esbuild-wasm base64 string from the
|
|
67
|
+
* generated module (it now lives in env.ASSETS), shrinking the worker
|
|
68
|
+
* bundle by ~21 MiB UTF-16-resident. Empirical baseline post-A'.5 is
|
|
69
|
+
* ~9 MiB (verified via the heap-estimator probe + bundle size).
|
|
70
|
+
*
|
|
71
|
+
* This is constant across a deploy. A bundle-size shrink (removing an
|
|
72
|
+
* unused dependency, splitting another big constant out to assets)
|
|
73
|
+
* would lower this further.
|
|
74
|
+
*/
|
|
75
|
+
const SUPERVISOR_BASELINE_BYTES = 9 * 1024 * 1024;
|
|
76
|
+
/**
|
|
77
|
+
* esbuild-wasm bytes resident in supervisor heap.
|
|
78
|
+
*
|
|
79
|
+
* Pre-A'.5: 16 MiB module-scope cache in src/esbuild-wasm-bytes.ts —
|
|
80
|
+
* the decoded ArrayBuffer was held for the lifetime of the supervisor
|
|
81
|
+
* isolate so multiple pool constructions amortised the base64 decode.
|
|
82
|
+
*
|
|
83
|
+
* Post-A'.5: 0. The bytes live in env.ASSETS; src/esbuild-wasm-bytes.ts
|
|
84
|
+
* fetches on demand and the supervisor releases its reference after
|
|
85
|
+
* the LOADER hand-off. There IS a transient ~12 MiB pulse during pool
|
|
86
|
+
* construction, but it's not resident — by the time anyone polls the
|
|
87
|
+
* estimator we're back to zero. The constant captures the resident
|
|
88
|
+
* floor; transient bytes don't show up here.
|
|
89
|
+
*/
|
|
90
|
+
const ESBUILD_RESIDENT_BYTES = 0;
|
|
91
|
+
/**
|
|
92
|
+
* Maximum SqliteVFS LRU footprint (architectural cap). Used as the
|
|
93
|
+
* upper bound for the LRU contribution when the SqliteVFS hasn't been
|
|
94
|
+
* instantiated yet (cacheHotBytes = 0 from the inputs).
|
|
95
|
+
*
|
|
96
|
+
* Defensive — the live cacheHotBytes is the source of truth once the
|
|
97
|
+
* VFS exists. This value is NOT used in production; the estimator
|
|
98
|
+
* receives the live count via VfsHeapInputs.
|
|
99
|
+
*/
|
|
100
|
+
export const VFS_LRU_MAX_BYTES = LRU_MAX_ENTRIES * CHUNK_SIZE;
|
|
101
|
+
/**
|
|
102
|
+
* Estimate resolver in-flight bytes from diag-counters.
|
|
103
|
+
*
|
|
104
|
+
* The resolver in-supervisor path (pre-A'.1) holds packument JSON in
|
|
105
|
+
* memory while parsing. We don't have a "current in-flight bytes"
|
|
106
|
+
* counter directly, but we DO have:
|
|
107
|
+
* - inFlightPackumentFetches (live count of awaited fetches)
|
|
108
|
+
* - lastPackumentBytes (size of the most recent packument)
|
|
109
|
+
*
|
|
110
|
+
* Average packument size on real registries is dominated by the largest
|
|
111
|
+
* outliers (lucide-react, framer-motion at ~5 MiB each) so using
|
|
112
|
+
* lastPackumentBytes as a per-fetch upper bound is a reasonable proxy.
|
|
113
|
+
*
|
|
114
|
+
* Caller can also pass an explicit `cumulativeBytesDecoded` snapshot
|
|
115
|
+
* (resolverPath = 'in-supervisor') for a different estimation strategy
|
|
116
|
+
* — but right now the most useful signal is "is the resolver currently
|
|
117
|
+
* holding bytes in supervisor heap or has it moved to a facet?".
|
|
118
|
+
*
|
|
119
|
+
* After A'.1 lands and resolverPath becomes hard-pinned to 'in-facet',
|
|
120
|
+
* this contribution drops to 0 by construction.
|
|
121
|
+
*/
|
|
122
|
+
export function estimateResolverInFlightBytes(c) {
|
|
123
|
+
if (c.resolverPath === 'in-facet')
|
|
124
|
+
return 0;
|
|
125
|
+
if (c.inFlightPackumentFetches === 0)
|
|
126
|
+
return 0;
|
|
127
|
+
// Conservative: each in-flight fetch counted at the size of the
|
|
128
|
+
// most recent packument. This OVER-estimates when the in-flight
|
|
129
|
+
// packuments are smaller than lastPackumentBytes (which they
|
|
130
|
+
// probably are — lastPackumentBytes is a worst-of-recent value).
|
|
131
|
+
return c.inFlightPackumentFetches * c.lastPackumentBytes;
|
|
132
|
+
}
|
|
133
|
+
/**
|
|
134
|
+
* Estimate pre-bundle slice bytes resident in the supervisor heap.
|
|
135
|
+
*
|
|
136
|
+
* Pre A'.2: the supervisor builds the slice in heap (up to
|
|
137
|
+
* SLICE_CAP_BYTES = 28 MiB per concurrent slot) before passing to the
|
|
138
|
+
* pre-bundle facet. With PRE_BUNDLE_CONCURRENCY = 1 the cap is 28 MiB.
|
|
139
|
+
*
|
|
140
|
+
* Diag counters track pre-bundle attempts/completions but not
|
|
141
|
+
* in-flight slice bytes specifically. Until A'.2 streams the slice,
|
|
142
|
+
* we treat the slice as PRESENT in supervisor heap iff the pre-bundle
|
|
143
|
+
* phase is active AND a slot is in flight (no completion yet for the
|
|
144
|
+
* current attempted count).
|
|
145
|
+
*
|
|
146
|
+
* After A'.2 lands the slice flows via ReadableStream-over-RPC and
|
|
147
|
+
* supervisor never holds the bytes — this contribution drops to 0.
|
|
148
|
+
*/
|
|
149
|
+
export function estimatePreBundleSliceBytes(c) {
|
|
150
|
+
// Conservative: if the most recent batch attempted >0 specs and the
|
|
151
|
+
// batch hasn't fully completed, assume one slice's worth of bytes
|
|
152
|
+
// are in flight. The 28 MiB constant must stay in lockstep with
|
|
153
|
+
// PRE_BUNDLE_CONCURRENCY × SLICE_CAP_BYTES in npm-installer.ts.
|
|
154
|
+
const SLICE_CAP_BYTES = 28 * 1024 * 1024;
|
|
155
|
+
const PRE_BUNDLE_CONCURRENCY = 1;
|
|
156
|
+
const f = c.preBundleFacet;
|
|
157
|
+
const inFlight = f.attempted - f.bundlesCompleted - f.errors - f.skipped;
|
|
158
|
+
if (inFlight <= 0)
|
|
159
|
+
return 0;
|
|
160
|
+
return Math.min(inFlight, PRE_BUNDLE_CONCURRENCY) * SLICE_CAP_BYTES;
|
|
161
|
+
}
|
|
162
|
+
/**
|
|
163
|
+
* Build a heap estimate from runtime counters + VFS inputs.
|
|
164
|
+
*
|
|
165
|
+
* Pure function — no I/O, microsecond cost. Called from the
|
|
166
|
+
* /api/_diag/memory request handler.
|
|
167
|
+
*/
|
|
168
|
+
export function estimateSupervisorHeap(c, vfs) {
|
|
169
|
+
const breakdown = {
|
|
170
|
+
supervisorBaselineBytes: SUPERVISOR_BASELINE_BYTES,
|
|
171
|
+
vfsLruBytes: vfs.cacheHotBytes,
|
|
172
|
+
vfsInFlightBytes: vfs.inFlightWriteBytes,
|
|
173
|
+
resolverInFlightBytes: estimateResolverInFlightBytes(c),
|
|
174
|
+
preBundleSliceBytes: estimatePreBundleSliceBytes(c),
|
|
175
|
+
esbuildResidentBytes: ESBUILD_RESIDENT_BYTES,
|
|
176
|
+
streamingBuffersBytes: c.inFlightRpcPayloadBytes,
|
|
177
|
+
};
|
|
178
|
+
const estimatedBytes = breakdown.supervisorBaselineBytes +
|
|
179
|
+
breakdown.vfsLruBytes +
|
|
180
|
+
breakdown.vfsInFlightBytes +
|
|
181
|
+
breakdown.resolverInFlightBytes +
|
|
182
|
+
breakdown.preBundleSliceBytes +
|
|
183
|
+
breakdown.esbuildResidentBytes +
|
|
184
|
+
breakdown.streamingBuffersBytes;
|
|
185
|
+
const percentOfCeiling = Math.round((estimatedBytes / SUPERVISOR_HEAP_CEILING_BYTES) * 1000) / 10;
|
|
186
|
+
return {
|
|
187
|
+
estimatedBytes,
|
|
188
|
+
ceilingBytes: SUPERVISOR_HEAP_CEILING_BYTES,
|
|
189
|
+
percentOfCeiling,
|
|
190
|
+
breakdown,
|
|
191
|
+
};
|
|
192
|
+
}
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* heavy-alloc-coord.ts — supervisor-local back-pressure between the
|
|
3
|
+
* fire-and-forget pre-bundle phase and other heap-heavy supervisor work
|
|
4
|
+
* (today: `npm run dev` booting cirrus-real).
|
|
5
|
+
*
|
|
6
|
+
* Why this exists
|
|
7
|
+
* ───────────────
|
|
8
|
+
* Pre-bundle dispatches up to PRE_BUNDLE_CONCURRENCY facets in parallel.
|
|
9
|
+
* Each holds ~28 MiB slice while the facet RPC is in flight. The Mini-PRD
|
|
10
|
+
* "DO shared isolate issues" reports DO resets at <128 MiB when the
|
|
11
|
+
* isolate is shared with another DO; our 128 MiB headroom calculation
|
|
12
|
+
* is therefore aspirational. Concurrent allocations in the supervisor —
|
|
13
|
+
* notably cirrus-real's user-vite-config bundle + plugin-react +
|
|
14
|
+
* extraSyntheticFiles — can push a shared isolate over the cap mid
|
|
15
|
+
* pre-bundle, causing a reset that surfaces as the user seeing the boot
|
|
16
|
+
* banner reprint several times.
|
|
17
|
+
*
|
|
18
|
+
* Mechanism
|
|
19
|
+
* ─────────
|
|
20
|
+
* A single-bit gate. Heavy-alloc owners (cirrus-real boot today) call
|
|
21
|
+
* `acquireHeavyAlloc()` before allocating, releasing via the returned
|
|
22
|
+
* `release()` once steady-state. Pre-bundle's runSlot awaits
|
|
23
|
+
* `waitForLowAllocPressure()` between iterations — no-op when the gate
|
|
24
|
+
* is open, otherwise a short sleep loop until released.
|
|
25
|
+
*
|
|
26
|
+
* Idempotent / re-entrant: multiple acquires increment a refcount.
|
|
27
|
+
* `release()` is a one-shot (returned by acquire) so callers can't
|
|
28
|
+
* accidentally double-decrement.
|
|
29
|
+
*
|
|
30
|
+
* Why globalThis vs. dependency injection
|
|
31
|
+
* ───────────────────────────────────────
|
|
32
|
+
* Pre-bundle runs in the supervisor isolate, called from npm-installer
|
|
33
|
+
* which is constructed by NimbusSession's command handler. cirrus-real
|
|
34
|
+
* is constructed by a different command handler in the same session.
|
|
35
|
+
* Both share the supervisor's globalThis. Threading an explicit handle
|
|
36
|
+
* from the session through every command path would touch ~10 sites
|
|
37
|
+
* for a one-bit signal. globalThis-keyed singletons are already the
|
|
38
|
+
* pattern for `__NIMBUS_*` symbols in the codebase.
|
|
39
|
+
*
|
|
40
|
+
* Lifetime: the coordinator is process-local, lasts as long as the
|
|
41
|
+
* supervisor isolate. After a DO restart it's re-created — that's
|
|
42
|
+
* acceptable since pre-bundle would also re-dispatch from scratch.
|
|
43
|
+
*/
|
|
44
|
+
/**
|
|
45
|
+
* W5 Lever 8: a registered observer (typically a SqliteVFS) that
|
|
46
|
+
* receives shrink/restore signals when the heavy-alloc refcount
|
|
47
|
+
* transitions 0↔≥1. Kept as a duck-typed pair of callbacks so we
|
|
48
|
+
* don't pull SqliteVFS as a static import (preserves layering: this
|
|
49
|
+
* module is consumed by both the supervisor and tests, and shouldn't
|
|
50
|
+
* acquire a heavy dependency).
|
|
51
|
+
*/
|
|
52
|
+
interface AllocObserver {
|
|
53
|
+
/** Called when refcount transitions 0 → 1 (heavy-alloc phase entered). */
|
|
54
|
+
onAcquire?: () => void;
|
|
55
|
+
/** Called when refcount transitions ≥1 → 0 (phase exited). */
|
|
56
|
+
onRelease?: () => void;
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* W5 Lever 8 hook. Register an observer that fires when the heavy-
|
|
60
|
+
* alloc refcount transitions 0 → 1 (acquire) and ≥1 → 0 (release).
|
|
61
|
+
* Returns an unsubscribe function. Idempotent: registering the same
|
|
62
|
+
* observer twice is a no-op (Set semantics).
|
|
63
|
+
*
|
|
64
|
+
* Wire from NimbusSession constructor: register an observer whose
|
|
65
|
+
* onAcquire calls vfs.shrinkForInstall() and onRelease calls
|
|
66
|
+
* vfs.restoreAfterInstall(). This decouples SqliteVFS from
|
|
67
|
+
* heavy-alloc-coord while keeping the observer pattern simple.
|
|
68
|
+
*/
|
|
69
|
+
export declare function registerAllocObserver(o: AllocObserver): () => void;
|
|
70
|
+
/** True if any heavy-alloc owner has the gate open. */
|
|
71
|
+
export declare function isHeavyAllocActive(): boolean;
|
|
72
|
+
/**
|
|
73
|
+
* Mark a heavy-alloc phase as active. Returns a one-shot release fn —
|
|
74
|
+
* call it once the phase is complete. Safe to discard the release
|
|
75
|
+
* (refcount can drift up if a caller forgets — only blocks pre-bundle,
|
|
76
|
+
* never blocks user work — but please don't).
|
|
77
|
+
*/
|
|
78
|
+
export declare function acquireHeavyAlloc(): () => void;
|
|
79
|
+
/**
|
|
80
|
+
* Wait until the gate is open. Polls every `pollMs` (default 200 ms)
|
|
81
|
+
* up to `maxWaitMs` (default 30 s). Returns whether the gate opened
|
|
82
|
+
* within the window — callers can decide to continue regardless.
|
|
83
|
+
*
|
|
84
|
+
* Why polling vs. a Promise: heavy-alloc events (cirrus boot) happen
|
|
85
|
+
* once per session at most. The few hundred-ms granularity is fine,
|
|
86
|
+
* and a poll loop avoids carrying an event-emitter or extra Promise
|
|
87
|
+
* chain through the coordinator. Pre-bundle wall time is dominated by
|
|
88
|
+
* facet RPC; a 200 ms idle here is invisible.
|
|
89
|
+
*/
|
|
90
|
+
export declare function waitForLowAllocPressure(opts?: {
|
|
91
|
+
pollMs?: number;
|
|
92
|
+
maxWaitMs?: number;
|
|
93
|
+
}): Promise<boolean>;
|
|
94
|
+
export {};
|
|
95
|
+
//# sourceMappingURL=heavy-alloc-coord.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"heavy-alloc-coord.d.ts","sourceRoot":"","sources":["../../src/observability/heavy-alloc-coord.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA0CG;AAIH;;;;;;;GAOG;AACH,UAAU,aAAa;IACrB,0EAA0E;IAC1E,SAAS,CAAC,EAAE,MAAM,IAAI,CAAC;IACvB,8DAA8D;IAC9D,SAAS,CAAC,EAAE,MAAM,IAAI,CAAC;CACxB;AAoBD;;;;;;;;;;GAUG;AACH,wBAAgB,qBAAqB,CAAC,CAAC,EAAE,aAAa,GAAG,MAAM,IAAI,CAIlE;AAwBD,uDAAuD;AACvD,wBAAgB,kBAAkB,IAAI,OAAO,CAE5C;AAED;;;;;GAKG;AACH,wBAAgB,iBAAiB,IAAI,MAAM,IAAI,CAe9C;AAED;;;;;;;;;;GAUG;AACH,wBAAsB,uBAAuB,CAAC,IAAI,CAAC,EAAE;IACnD,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB,GAAG,OAAO,CAAC,OAAO,CAAC,CASnB"}
|
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* heavy-alloc-coord.ts — supervisor-local back-pressure between the
|
|
3
|
+
* fire-and-forget pre-bundle phase and other heap-heavy supervisor work
|
|
4
|
+
* (today: `npm run dev` booting cirrus-real).
|
|
5
|
+
*
|
|
6
|
+
* Why this exists
|
|
7
|
+
* ───────────────
|
|
8
|
+
* Pre-bundle dispatches up to PRE_BUNDLE_CONCURRENCY facets in parallel.
|
|
9
|
+
* Each holds ~28 MiB slice while the facet RPC is in flight. The Mini-PRD
|
|
10
|
+
* "DO shared isolate issues" reports DO resets at <128 MiB when the
|
|
11
|
+
* isolate is shared with another DO; our 128 MiB headroom calculation
|
|
12
|
+
* is therefore aspirational. Concurrent allocations in the supervisor —
|
|
13
|
+
* notably cirrus-real's user-vite-config bundle + plugin-react +
|
|
14
|
+
* extraSyntheticFiles — can push a shared isolate over the cap mid
|
|
15
|
+
* pre-bundle, causing a reset that surfaces as the user seeing the boot
|
|
16
|
+
* banner reprint several times.
|
|
17
|
+
*
|
|
18
|
+
* Mechanism
|
|
19
|
+
* ─────────
|
|
20
|
+
* A single-bit gate. Heavy-alloc owners (cirrus-real boot today) call
|
|
21
|
+
* `acquireHeavyAlloc()` before allocating, releasing via the returned
|
|
22
|
+
* `release()` once steady-state. Pre-bundle's runSlot awaits
|
|
23
|
+
* `waitForLowAllocPressure()` between iterations — no-op when the gate
|
|
24
|
+
* is open, otherwise a short sleep loop until released.
|
|
25
|
+
*
|
|
26
|
+
* Idempotent / re-entrant: multiple acquires increment a refcount.
|
|
27
|
+
* `release()` is a one-shot (returned by acquire) so callers can't
|
|
28
|
+
* accidentally double-decrement.
|
|
29
|
+
*
|
|
30
|
+
* Why globalThis vs. dependency injection
|
|
31
|
+
* ───────────────────────────────────────
|
|
32
|
+
* Pre-bundle runs in the supervisor isolate, called from npm-installer
|
|
33
|
+
* which is constructed by NimbusSession's command handler. cirrus-real
|
|
34
|
+
* is constructed by a different command handler in the same session.
|
|
35
|
+
* Both share the supervisor's globalThis. Threading an explicit handle
|
|
36
|
+
* from the session through every command path would touch ~10 sites
|
|
37
|
+
* for a one-bit signal. globalThis-keyed singletons are already the
|
|
38
|
+
* pattern for `__NIMBUS_*` symbols in the codebase.
|
|
39
|
+
*
|
|
40
|
+
* Lifetime: the coordinator is process-local, lasts as long as the
|
|
41
|
+
* supervisor isolate. After a DO restart it's re-created — that's
|
|
42
|
+
* acceptable since pre-bundle would also re-dispatch from scratch.
|
|
43
|
+
*/
|
|
44
|
+
const KEY = '__NIMBUS_HEAVY_ALLOC_COORD__';
|
|
45
|
+
function getCoord() {
|
|
46
|
+
const g = globalThis;
|
|
47
|
+
if (!g[KEY]) {
|
|
48
|
+
g[KEY] = { count: 0, observers: new Set() };
|
|
49
|
+
}
|
|
50
|
+
// Defensive: older entries (pre-W5) lack observers — add it.
|
|
51
|
+
const c = g[KEY];
|
|
52
|
+
if (!c.observers)
|
|
53
|
+
c.observers = new Set();
|
|
54
|
+
return c;
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* W5 Lever 8 hook. Register an observer that fires when the heavy-
|
|
58
|
+
* alloc refcount transitions 0 → 1 (acquire) and ≥1 → 0 (release).
|
|
59
|
+
* Returns an unsubscribe function. Idempotent: registering the same
|
|
60
|
+
* observer twice is a no-op (Set semantics).
|
|
61
|
+
*
|
|
62
|
+
* Wire from NimbusSession constructor: register an observer whose
|
|
63
|
+
* onAcquire calls vfs.shrinkForInstall() and onRelease calls
|
|
64
|
+
* vfs.restoreAfterInstall(). This decouples SqliteVFS from
|
|
65
|
+
* heavy-alloc-coord while keeping the observer pattern simple.
|
|
66
|
+
*/
|
|
67
|
+
export function registerAllocObserver(o) {
|
|
68
|
+
const c = getCoord();
|
|
69
|
+
c.observers.add(o);
|
|
70
|
+
return () => { c.observers.delete(o); };
|
|
71
|
+
}
|
|
72
|
+
function fireOnAcquire() {
|
|
73
|
+
const c = getCoord();
|
|
74
|
+
for (const o of c.observers) {
|
|
75
|
+
try {
|
|
76
|
+
o.onAcquire?.();
|
|
77
|
+
}
|
|
78
|
+
catch (e) {
|
|
79
|
+
// Observer errors must NOT break the heavy-alloc protocol.
|
|
80
|
+
// Log and continue.
|
|
81
|
+
// eslint-disable-next-line no-console
|
|
82
|
+
console.error('[heavy-alloc-coord] observer.onAcquire threw:', e?.message);
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
function fireOnRelease() {
|
|
87
|
+
const c = getCoord();
|
|
88
|
+
for (const o of c.observers) {
|
|
89
|
+
try {
|
|
90
|
+
o.onRelease?.();
|
|
91
|
+
}
|
|
92
|
+
catch (e) {
|
|
93
|
+
// eslint-disable-next-line no-console
|
|
94
|
+
console.error('[heavy-alloc-coord] observer.onRelease threw:', e?.message);
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
/** True if any heavy-alloc owner has the gate open. */
|
|
99
|
+
export function isHeavyAllocActive() {
|
|
100
|
+
return getCoord().count > 0;
|
|
101
|
+
}
|
|
102
|
+
/**
|
|
103
|
+
* Mark a heavy-alloc phase as active. Returns a one-shot release fn —
|
|
104
|
+
* call it once the phase is complete. Safe to discard the release
|
|
105
|
+
* (refcount can drift up if a caller forgets — only blocks pre-bundle,
|
|
106
|
+
* never blocks user work — but please don't).
|
|
107
|
+
*/
|
|
108
|
+
export function acquireHeavyAlloc() {
|
|
109
|
+
const coord = getCoord();
|
|
110
|
+
const wasZero = coord.count === 0;
|
|
111
|
+
coord.count++;
|
|
112
|
+
// W5 Lever 8: fire onAcquire on the 0→1 edge so SqliteVFS can
|
|
113
|
+
// shrinkForInstall(). Subsequent nested acquires don't re-fire.
|
|
114
|
+
if (wasZero)
|
|
115
|
+
fireOnAcquire();
|
|
116
|
+
let released = false;
|
|
117
|
+
return () => {
|
|
118
|
+
if (released)
|
|
119
|
+
return;
|
|
120
|
+
released = true;
|
|
121
|
+
if (coord.count > 0)
|
|
122
|
+
coord.count--;
|
|
123
|
+
// Fire onRelease on the ≥1→0 edge so SqliteVFS restoreAfterInstall().
|
|
124
|
+
if (coord.count === 0)
|
|
125
|
+
fireOnRelease();
|
|
126
|
+
};
|
|
127
|
+
}
|
|
128
|
+
/**
|
|
129
|
+
* Wait until the gate is open. Polls every `pollMs` (default 200 ms)
|
|
130
|
+
* up to `maxWaitMs` (default 30 s). Returns whether the gate opened
|
|
131
|
+
* within the window — callers can decide to continue regardless.
|
|
132
|
+
*
|
|
133
|
+
* Why polling vs. a Promise: heavy-alloc events (cirrus boot) happen
|
|
134
|
+
* once per session at most. The few hundred-ms granularity is fine,
|
|
135
|
+
* and a poll loop avoids carrying an event-emitter or extra Promise
|
|
136
|
+
* chain through the coordinator. Pre-bundle wall time is dominated by
|
|
137
|
+
* facet RPC; a 200 ms idle here is invisible.
|
|
138
|
+
*/
|
|
139
|
+
export async function waitForLowAllocPressure(opts) {
|
|
140
|
+
const pollMs = opts?.pollMs ?? 200;
|
|
141
|
+
const maxWaitMs = opts?.maxWaitMs ?? 30_000;
|
|
142
|
+
const start = Date.now();
|
|
143
|
+
while (isHeavyAllocActive()) {
|
|
144
|
+
if (Date.now() - start > maxWaitMs)
|
|
145
|
+
return false;
|
|
146
|
+
await new Promise((r) => setTimeout(r, pollMs));
|
|
147
|
+
}
|
|
148
|
+
return true;
|
|
149
|
+
}
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* oom-classify.ts — discriminator for OOM-like errors at Nimbus
|
|
3
|
+
* boundaries. Tagged W5 (Lever 5 / J.1.1 in CF-INTERNAL-OPTIMIZATION-
|
|
4
|
+
* RESEARCH.md).
|
|
5
|
+
*
|
|
6
|
+
* Why this exists
|
|
7
|
+
* ───────────────
|
|
8
|
+
* Nimbus has at least four distinct "the work failed" failure modes
|
|
9
|
+
* that all surface today as either a thrown JS Error or a console
|
|
10
|
+
* line:
|
|
11
|
+
*
|
|
12
|
+
* 1. SQLITE_NOMEM at the storage layer (per-DO SQLite cap, post-
|
|
13
|
+
* STOR/SPEC: Address SQLITE_NOMEM issues).
|
|
14
|
+
* 2. Generic isolate OOM (`Durable Object's isolate exceeded its
|
|
15
|
+
* memory limit and was reset` per ~sha/DOGE Recommendations).
|
|
16
|
+
* 3. Structured-clone refusal (`Cannot deserialize cloned data`)
|
|
17
|
+
* between supervisor ↔ facet RPC (32 MiB cap).
|
|
18
|
+
* 4. RPC timeout (TimeoutError from facet-pool's per-task race).
|
|
19
|
+
*
|
|
20
|
+
* Plus a few platform-side terminations (subrequest cap, condemnation,
|
|
21
|
+
* hard eviction) that the user sees but Nimbus has no first-party
|
|
22
|
+
* signal for.
|
|
23
|
+
*
|
|
24
|
+
* Without a classifier, every recordFailure() call has to stringify-
|
|
25
|
+
* match its own error site. With this module, we pin the regex once
|
|
26
|
+
* and reuse it everywhere.
|
|
27
|
+
*
|
|
28
|
+
* Inputs we accept
|
|
29
|
+
* ────────────────
|
|
30
|
+
* The classifier accepts:
|
|
31
|
+
* - Error instances (read e.message)
|
|
32
|
+
* - plain strings (use directly — for stderr-line classification at
|
|
33
|
+
* facet-exit boundaries where we don't have an Error)
|
|
34
|
+
* - anything else (return 'unknown')
|
|
35
|
+
*
|
|
36
|
+
* Output values
|
|
37
|
+
* ─────────────
|
|
38
|
+
* Same set used by `DiagFailure.cause` in oom-discriminator.ts. Keep
|
|
39
|
+
* the union narrow and additive — adding a new value is fine, but
|
|
40
|
+
* never re-purpose an existing one.
|
|
41
|
+
*/
|
|
42
|
+
export type OomCause = 'sqlite_nomem' | 'oom' | 'clone_refused' | 'rpc_timeout' | 'subrequest_cap' | 'condemnation' | 'hard_evict' | 'unknown';
|
|
43
|
+
/**
|
|
44
|
+
* Classify an error or message string into an OomCause. Returns
|
|
45
|
+
* 'unknown' when no signature matches — callers should still record
|
|
46
|
+
* the message via DiagFailure.message so a human can later widen the
|
|
47
|
+
* classifier rules.
|
|
48
|
+
*/
|
|
49
|
+
export declare function classifyError(input: unknown): OomCause;
|
|
50
|
+
/**
|
|
51
|
+
* Variant for callers that already have the message string. Prefer
|
|
52
|
+
* classifyError() at boundaries; this is exposed for cases where the
|
|
53
|
+
* message has already been extracted (e.g. truncated / sanitised).
|
|
54
|
+
*/
|
|
55
|
+
export declare function classifyMessage(msg: string): OomCause;
|
|
56
|
+
//# sourceMappingURL=oom-classify.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"oom-classify.d.ts","sourceRoot":"","sources":["../../src/observability/oom-classify.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAwCG;AAEH,MAAM,MAAM,QAAQ,GAChB,cAAc,GACd,KAAK,GACL,eAAe,GACf,aAAa,GACb,gBAAgB,GAChB,cAAc,GACd,YAAY,GACZ,SAAS,CAAC;AAEd;;;;;GAKG;AACH,wBAAgB,aAAa,CAAC,KAAK,EAAE,OAAO,GAAG,QAAQ,CAItD;AAED;;;;GAIG;AACH,wBAAgB,eAAe,CAAC,GAAG,EAAE,MAAM,GAAG,QAAQ,CAgCrD"}
|