@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,833 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* npm-resolve-facet.ts — NimbusLoaderPool entry for the npm resolver phase.
|
|
3
|
+
*
|
|
4
|
+
* Why this exists
|
|
5
|
+
* ───────────────
|
|
6
|
+
* The resolver crashes the supervisor DO during `npm install` of any
|
|
7
|
+
* non-trivial app:
|
|
8
|
+
* 1. `await resp.json()` at src/npm-resolver.ts:306 deserializes the
|
|
9
|
+
* ENTIRE packument as a JS object. Packuments for widely-versioned
|
|
10
|
+
* packages (lucide-react, react-router-dom, framer-motion, …) can
|
|
11
|
+
* be 5–20 MB; parsed object expands ~3× in V8. With pLimit(6),
|
|
12
|
+
* 6 concurrent slots can hold ~360 MB transient peak — well over
|
|
13
|
+
* the 128 MB DO heap cap.
|
|
14
|
+
* 2. The fetch-proxy worker (src/nimbus-session.ts:1666-1714) is a
|
|
15
|
+
* singleton that buffers each response via `resp.arrayBuffer()`.
|
|
16
|
+
* With 6 concurrent calls in flight, ONE 128 MB isolate holds
|
|
17
|
+
* 6 × packument-bytes simultaneously.
|
|
18
|
+
*
|
|
19
|
+
* The fix is to dispatch the entire resolver phase to a NimbusLoaderPool
|
|
20
|
+
* isolate. The facet has its own 128 MB; the supervisor's heap stays
|
|
21
|
+
* flat through phase 1 (the smoking gun: cumulativePackumentBytesDecoded
|
|
22
|
+
* stays near 0 in the supervisor counters post-fix).
|
|
23
|
+
*
|
|
24
|
+
* Topology choice (per /workspace plan): ONE facet for the whole walk,
|
|
25
|
+
* not pool.map per-spec. Rationale:
|
|
26
|
+
* - 456-spec walk × per-spec dispatch overhead = excessive cold-starts.
|
|
27
|
+
* - The CPU work per spec is small; the heap is the issue.
|
|
28
|
+
* - A single facet running the breadth-first walk has its own 128 MB,
|
|
29
|
+
* reuses the same fetch handle, batches RPC writes back via
|
|
30
|
+
* env.SUPERVISOR.putRegistryEntries, and has its heap fully released
|
|
31
|
+
* when the facet returns.
|
|
32
|
+
*
|
|
33
|
+
* Concurrency inside the facet uses pLimit(6) — same value as today's
|
|
34
|
+
* in-supervisor resolver, but now with a fresh 128 MB to absorb the
|
|
35
|
+
* transient parse spikes.
|
|
36
|
+
*
|
|
37
|
+
* Worst-case facet heap budget (with concurrency 4, set by the
|
|
38
|
+
* supervisor dispatcher):
|
|
39
|
+
* - cachedEntries map: ≤ 2.5 MiB (capped at 5000 × ~500 B)
|
|
40
|
+
* - 4 concurrent packument text+parse buffers: up to 4 × ~20 MiB
|
|
41
|
+
* for pathologically large packuments = 80 MiB transient peak.
|
|
42
|
+
* For typical npm packages (<2 MiB packument), this is ~8 MiB.
|
|
43
|
+
* - resolved Map: ~228 KiB for a 456-package install.
|
|
44
|
+
* - Total worst-case: ~85 MiB. Comfortably under the 128 MB cap with
|
|
45
|
+
* ~40 MiB headroom for V8 overhead + esbuild-runtime shim.
|
|
46
|
+
*
|
|
47
|
+
* Stability invariants (cloudflare-parallel serialises via fn.toString):
|
|
48
|
+
* - No `this` references.
|
|
49
|
+
* - No closure capture other than args + preamble names.
|
|
50
|
+
* - All helpers (semver match, exports field, skip list) live in the
|
|
51
|
+
* preamble (src/parallel/npm-resolve-preamble.ts) so the facet has
|
|
52
|
+
* them in its lexical scope.
|
|
53
|
+
*
|
|
54
|
+
* Cache strategy:
|
|
55
|
+
* The supervisor pre-loads cached registry entries (already-resolved
|
|
56
|
+
* packages from prior installs) and ships them in the spec. The facet
|
|
57
|
+
* reconstructs a name → versions[] map and uses it to short-circuit
|
|
58
|
+
* fetches on hits. For cold sessions, the cache is empty (~0 bytes
|
|
59
|
+
* over the wire). For warm sessions, ~500 B per cached entry × at
|
|
60
|
+
* most 5000 entries = 2.5 MB, well under the 32 MB RPC cap.
|
|
61
|
+
*
|
|
62
|
+
* Cache writes flow back via env.SUPERVISOR.putRegistryEntries in
|
|
63
|
+
* waves (every 50 resolved packages or end-of-phase, whichever first).
|
|
64
|
+
* Doesn't block forward progress.
|
|
65
|
+
*/
|
|
66
|
+
// ── Facet function ──────────────────────────────────────────────────────
|
|
67
|
+
//
|
|
68
|
+
// `resolveTreeInFacet` is serialised via fn.toString() and run inside a
|
|
69
|
+
// NimbusLoaderPool isolate. It references the following symbols by bare
|
|
70
|
+
// identifier; they are declared in the preamble
|
|
71
|
+
// (src/parallel/npm-resolve-preamble.ts) at facet-load time:
|
|
72
|
+
//
|
|
73
|
+
// - SHOULD_SKIP_PACKAGE(name) → boolean
|
|
74
|
+
// - PARSE_SEMVER(v) → [maj, min, patch] | null
|
|
75
|
+
// - COMPARE_SEMVER(a, b) → number
|
|
76
|
+
// - SATISFIES_RANGE(version, range) → boolean
|
|
77
|
+
// - RESOLVE_VERSION(versions, range) → string | null
|
|
78
|
+
//
|
|
79
|
+
// The function does NOT import them statically — that would pull the
|
|
80
|
+
// entire npm-resolver.ts into the supervisor's bundle, defeating the
|
|
81
|
+
// point of moving the work elsewhere.
|
|
82
|
+
export const resolveTreeInFacet = async function resolveTreeInFacet(spec, env) {
|
|
83
|
+
const t0 = Date.now();
|
|
84
|
+
const messages = [];
|
|
85
|
+
if (!spec || typeof spec !== 'object') {
|
|
86
|
+
throw new Error('resolveTreeInFacet: missing spec');
|
|
87
|
+
}
|
|
88
|
+
if (!env || !env.SUPERVISOR || typeof env.SUPERVISOR.putRegistryEntries !== 'function') {
|
|
89
|
+
throw new Error('resolveTreeInFacet: env.SUPERVISOR.putRegistryEntries missing');
|
|
90
|
+
}
|
|
91
|
+
// ── In-memory cache reconstructed from the spec ─────────────────────
|
|
92
|
+
// Map: name → { version → FacetCachedEntry }
|
|
93
|
+
const cacheByName = new Map();
|
|
94
|
+
for (const entry of spec.cachedEntries || []) {
|
|
95
|
+
if (!entry || !entry.name || !entry.version)
|
|
96
|
+
continue;
|
|
97
|
+
let inner = cacheByName.get(entry.name);
|
|
98
|
+
if (!inner) {
|
|
99
|
+
inner = new Map();
|
|
100
|
+
cacheByName.set(entry.name, inner);
|
|
101
|
+
}
|
|
102
|
+
inner.set(entry.version, entry);
|
|
103
|
+
}
|
|
104
|
+
// ── Counters (facet-local; copied into result.facetCounters at end) ──
|
|
105
|
+
let inFlight = 0;
|
|
106
|
+
let inFlightPeak = 0;
|
|
107
|
+
let cumulativeBytesDecoded = 0;
|
|
108
|
+
let packumentsDecoded = 0;
|
|
109
|
+
let lastPackumentName = '';
|
|
110
|
+
let lastPackumentBytes = 0;
|
|
111
|
+
// [W4] Pipelined-RPC race outcomes. Folded into supervisor diag via
|
|
112
|
+
// recordR2RaceCounters() in npm-installer.
|
|
113
|
+
let pipelinedPackumentRaceWins = 0;
|
|
114
|
+
let pipelinedPackumentRaceLosses = 0;
|
|
115
|
+
// cache-obs-2: per-tier event accumulator (L2/L3 from supervisor
|
|
116
|
+
// RPC return.events; L4 from local registry fetches).
|
|
117
|
+
const cacheStatEvents = [];
|
|
118
|
+
// [W4] Cap on how long we wait for an R2 packument GET before
|
|
119
|
+
// committing to the network response. 250 ms covers typical regional
|
|
120
|
+
// R2 latency (30-150 ms) with margin; bounded enough that worst-case
|
|
121
|
+
// miss adds only 250 ms × packumentsDecoded / pLimit-bound to wall
|
|
122
|
+
// clock — typically ≤ 1 s on Mossaic-class. Tunable via spec, but
|
|
123
|
+
// the default suits prod; keep a constant here to avoid wire changes.
|
|
124
|
+
const R2_PACKUMENT_RACE_TIMEOUT_MS = 250;
|
|
125
|
+
// ── Concurrency limiter (inline; preamble doesn't carry pLimit) ─────
|
|
126
|
+
// Identical semantics to npm-resolver.ts:31-50.
|
|
127
|
+
const concurrency = Math.max(1, Math.min(spec.concurrency || 6, 16));
|
|
128
|
+
let active = 0;
|
|
129
|
+
const queue = [];
|
|
130
|
+
const limit = (fn) => {
|
|
131
|
+
return new Promise((resolve, reject) => {
|
|
132
|
+
const run = async () => {
|
|
133
|
+
active++;
|
|
134
|
+
try {
|
|
135
|
+
resolve(await fn());
|
|
136
|
+
}
|
|
137
|
+
catch (e) {
|
|
138
|
+
reject(e);
|
|
139
|
+
}
|
|
140
|
+
finally {
|
|
141
|
+
active--;
|
|
142
|
+
if (queue.length > 0)
|
|
143
|
+
queue.shift()();
|
|
144
|
+
}
|
|
145
|
+
};
|
|
146
|
+
if (active < concurrency)
|
|
147
|
+
run();
|
|
148
|
+
else
|
|
149
|
+
queue.push(run);
|
|
150
|
+
});
|
|
151
|
+
};
|
|
152
|
+
// ── Cache write batcher ──────────────────────────────────────────────
|
|
153
|
+
// Flushes every FLUSH_THRESHOLD entries OR at end-of-phase. RPC arg
|
|
154
|
+
// size is dominated by depsJson + exportsJson — typical entry ~500 B,
|
|
155
|
+
// so 50 × 500 = 25 KB per flush. Trivially under workerd's 32 MB cap.
|
|
156
|
+
const FLUSH_THRESHOLD = 50;
|
|
157
|
+
let pendingCacheWrites = [];
|
|
158
|
+
let totalCacheWrites = 0;
|
|
159
|
+
const flushCache = async () => {
|
|
160
|
+
if (pendingCacheWrites.length === 0)
|
|
161
|
+
return;
|
|
162
|
+
const batch = pendingCacheWrites;
|
|
163
|
+
pendingCacheWrites = [];
|
|
164
|
+
try {
|
|
165
|
+
const r = await env.SUPERVISOR.putRegistryEntries(batch);
|
|
166
|
+
totalCacheWrites += r.written;
|
|
167
|
+
if (r.failed > 0) {
|
|
168
|
+
messages.push(`[resolve-facet] cache write: ${r.failed} entries failed`);
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
catch (e) {
|
|
172
|
+
messages.push(`[resolve-facet] cache flush failed: ${e?.message || e}`);
|
|
173
|
+
}
|
|
174
|
+
};
|
|
175
|
+
const enqueueCacheWrite = (entry) => {
|
|
176
|
+
pendingCacheWrites.push(entry);
|
|
177
|
+
if (pendingCacheWrites.length >= FLUSH_THRESHOLD) {
|
|
178
|
+
// Fire-and-forget flush; don't block resolve progress on it.
|
|
179
|
+
// We awaited flushCache below at end-of-phase to ensure
|
|
180
|
+
// durability; intermediate flushes are best-effort.
|
|
181
|
+
flushCache().catch(() => { });
|
|
182
|
+
}
|
|
183
|
+
};
|
|
184
|
+
// ── Resolution helpers ────────────────────────────────────────────────
|
|
185
|
+
const NPM_REGISTRY = 'https://registry.npmjs.org';
|
|
186
|
+
const versionToResolved = (vData) => {
|
|
187
|
+
const binField = vData.bin || {};
|
|
188
|
+
const bin = typeof binField === 'string'
|
|
189
|
+
? { [vData.name.split('/').pop()]: binField }
|
|
190
|
+
: binField;
|
|
191
|
+
// X.5-F R2: surface required peerDeps (optionals filtered) so the
|
|
192
|
+
// BFS walk can enqueue them. Mirrors npm-resolver.ts versionToResolved.
|
|
193
|
+
let peerDependencies;
|
|
194
|
+
let allPeers;
|
|
195
|
+
const peers = vData.peerDependencies;
|
|
196
|
+
if (peers && typeof peers === 'object') {
|
|
197
|
+
const meta = vData.peerDependenciesMeta;
|
|
198
|
+
const required = {};
|
|
199
|
+
const all = {};
|
|
200
|
+
for (const [n, r] of Object.entries(peers)) {
|
|
201
|
+
if (typeof r !== 'string')
|
|
202
|
+
continue;
|
|
203
|
+
all[n] = r;
|
|
204
|
+
if (meta && meta[n] && meta[n].optional === true)
|
|
205
|
+
continue;
|
|
206
|
+
required[n] = r;
|
|
207
|
+
}
|
|
208
|
+
if (Object.keys(required).length > 0)
|
|
209
|
+
peerDependencies = required;
|
|
210
|
+
if (Object.keys(all).length > 0)
|
|
211
|
+
allPeers = all;
|
|
212
|
+
}
|
|
213
|
+
// X.5-G G1: optionalDependencies + platform constraints (mirror of
|
|
214
|
+
// npm-resolver.ts:504). Surfaced for the BFS walk so the resolver
|
|
215
|
+
// knows which deps are best-effort and can apply silent-skip rules.
|
|
216
|
+
const optionalDependencies = vData.optionalDependencies && typeof vData.optionalDependencies === 'object'
|
|
217
|
+
? Object.fromEntries(Object.entries(vData.optionalDependencies)
|
|
218
|
+
.filter(([, r]) => typeof r === 'string'))
|
|
219
|
+
: undefined;
|
|
220
|
+
const out = {
|
|
221
|
+
name: vData.name,
|
|
222
|
+
version: vData.version,
|
|
223
|
+
tarballUrl: vData.dist?.tarball || '',
|
|
224
|
+
integrity: vData.dist?.integrity || vData.dist?.shasum || '',
|
|
225
|
+
dependencies: vData.dependencies || {},
|
|
226
|
+
peerDependencies,
|
|
227
|
+
optionalDependencies,
|
|
228
|
+
os: Array.isArray(vData.os) ? vData.os : undefined,
|
|
229
|
+
cpu: Array.isArray(vData.cpu) ? vData.cpu : undefined,
|
|
230
|
+
libc: Array.isArray(vData.libc) ? vData.libc : undefined,
|
|
231
|
+
exports: vData.exports ?? null,
|
|
232
|
+
main: vData.main || '',
|
|
233
|
+
module: vData.module || '',
|
|
234
|
+
bin,
|
|
235
|
+
};
|
|
236
|
+
if (allPeers)
|
|
237
|
+
out.__allPeerDependencies = allPeers;
|
|
238
|
+
return out;
|
|
239
|
+
};
|
|
240
|
+
const cachedEntryToResolved = (entry) => {
|
|
241
|
+
let deps = {}, peers = {}, exp = null, bin = {};
|
|
242
|
+
try {
|
|
243
|
+
deps = JSON.parse(entry.depsJson);
|
|
244
|
+
}
|
|
245
|
+
catch { }
|
|
246
|
+
try {
|
|
247
|
+
peers = entry.peerDepsJson ? JSON.parse(entry.peerDepsJson) : {};
|
|
248
|
+
}
|
|
249
|
+
catch { }
|
|
250
|
+
try {
|
|
251
|
+
exp = JSON.parse(entry.exportsJson);
|
|
252
|
+
}
|
|
253
|
+
catch { }
|
|
254
|
+
try {
|
|
255
|
+
bin = JSON.parse(entry.binJson);
|
|
256
|
+
}
|
|
257
|
+
catch { }
|
|
258
|
+
return {
|
|
259
|
+
name: entry.name,
|
|
260
|
+
version: entry.version,
|
|
261
|
+
tarballUrl: entry.tarballUrl,
|
|
262
|
+
integrity: entry.integrity,
|
|
263
|
+
dependencies: deps,
|
|
264
|
+
// X.5-F R2: surface peerDeps from cache hits so the BFS still
|
|
265
|
+
// enqueues peers when we don't re-fetch the packument.
|
|
266
|
+
peerDependencies: Object.keys(peers).length > 0 ? peers : undefined,
|
|
267
|
+
exports: exp,
|
|
268
|
+
main: entry.main,
|
|
269
|
+
module: entry.moduleField,
|
|
270
|
+
bin,
|
|
271
|
+
};
|
|
272
|
+
};
|
|
273
|
+
const fetchWithTimeout = async (url, timeoutMs) => {
|
|
274
|
+
const ctl = new AbortController();
|
|
275
|
+
const t = setTimeout(() => ctl.abort(), timeoutMs);
|
|
276
|
+
try {
|
|
277
|
+
return await fetch(url, {
|
|
278
|
+
headers: { 'Accept': 'application/json' },
|
|
279
|
+
signal: ctl.signal,
|
|
280
|
+
});
|
|
281
|
+
}
|
|
282
|
+
finally {
|
|
283
|
+
clearTimeout(t);
|
|
284
|
+
}
|
|
285
|
+
};
|
|
286
|
+
const fetchPackumentWithRetry = async (name) => {
|
|
287
|
+
const safeName = name.startsWith('@')
|
|
288
|
+
? '@' + encodeURIComponent(name.slice(1))
|
|
289
|
+
: encodeURIComponent(name);
|
|
290
|
+
const url = NPM_REGISTRY + '/' + safeName;
|
|
291
|
+
const BACKOFF = [500, 1500, 4500];
|
|
292
|
+
const totalRetries = Math.max(0, spec.retries ?? 3);
|
|
293
|
+
// [W4] R2 packument cache race. Kick off the cache lookup with a
|
|
294
|
+
// bounded wait; if it returns fresh JSON before the timeout, we
|
|
295
|
+
// skip the network entirely. Soft-fail when env.SUPERVISOR.getCachedPackument
|
|
296
|
+
// isn't available (older deployment).
|
|
297
|
+
const r2Available = typeof env.SUPERVISOR.getCachedPackument === 'function';
|
|
298
|
+
if (r2Available) {
|
|
299
|
+
try {
|
|
300
|
+
const r2P = Promise.race([
|
|
301
|
+
env.SUPERVISOR.getCachedPackument(name),
|
|
302
|
+
new Promise((rs) => setTimeout(() => rs(null), R2_PACKUMENT_RACE_TIMEOUT_MS)),
|
|
303
|
+
]).catch(() => null);
|
|
304
|
+
const r2Raw = await r2P;
|
|
305
|
+
// cache-obs-2: adapt to BOTH supervisor return shapes.
|
|
306
|
+
let cachedEntry = null;
|
|
307
|
+
if (r2Raw && typeof r2Raw === 'object') {
|
|
308
|
+
if ('cached' in r2Raw && 'events' in r2Raw) {
|
|
309
|
+
cachedEntry = r2Raw.cached;
|
|
310
|
+
const supEvents = r2Raw.events;
|
|
311
|
+
if (Array.isArray(supEvents)) {
|
|
312
|
+
for (const e of supEvents) {
|
|
313
|
+
if (!e || (e.kind !== 'hit' && e.kind !== 'miss'))
|
|
314
|
+
continue;
|
|
315
|
+
if (e.tier !== 'L2' && e.tier !== 'L3')
|
|
316
|
+
continue;
|
|
317
|
+
if (e.cacheKind !== 'packument')
|
|
318
|
+
continue;
|
|
319
|
+
if (e.kind === 'hit') {
|
|
320
|
+
cacheStatEvents.push({
|
|
321
|
+
kind: 'hit',
|
|
322
|
+
tier: e.tier,
|
|
323
|
+
cacheKind: 'packument',
|
|
324
|
+
bytes: typeof e.bytes === 'number' ? e.bytes : 0,
|
|
325
|
+
});
|
|
326
|
+
}
|
|
327
|
+
else {
|
|
328
|
+
cacheStatEvents.push({ kind: 'miss', tier: e.tier, cacheKind: 'packument' });
|
|
329
|
+
}
|
|
330
|
+
}
|
|
331
|
+
}
|
|
332
|
+
}
|
|
333
|
+
else if ('json' in r2Raw) {
|
|
334
|
+
cachedEntry = r2Raw;
|
|
335
|
+
}
|
|
336
|
+
}
|
|
337
|
+
if (cachedEntry && !cachedEntry.expired && cachedEntry.json) {
|
|
338
|
+
pipelinedPackumentRaceWins++;
|
|
339
|
+
lastPackumentBytes = cachedEntry.json.length;
|
|
340
|
+
lastPackumentName = name;
|
|
341
|
+
cumulativeBytesDecoded += cachedEntry.json.length;
|
|
342
|
+
packumentsDecoded++;
|
|
343
|
+
try {
|
|
344
|
+
return JSON.parse(cachedEntry.json);
|
|
345
|
+
}
|
|
346
|
+
catch {
|
|
347
|
+
// Malformed cache entry: fall through to network.
|
|
348
|
+
messages.push(`[resolve-facet] ${name}: malformed R2 packument; falling through`);
|
|
349
|
+
}
|
|
350
|
+
}
|
|
351
|
+
}
|
|
352
|
+
catch {
|
|
353
|
+
// best-effort; fall through to network
|
|
354
|
+
}
|
|
355
|
+
}
|
|
356
|
+
pipelinedPackumentRaceLosses++;
|
|
357
|
+
let lastErr;
|
|
358
|
+
for (let attempt = 0; attempt <= totalRetries; attempt++) {
|
|
359
|
+
try {
|
|
360
|
+
inFlight++;
|
|
361
|
+
if (inFlight > inFlightPeak)
|
|
362
|
+
inFlightPeak = inFlight;
|
|
363
|
+
const resp = await fetchWithTimeout(url, spec.fetchTimeoutMs ?? 15000);
|
|
364
|
+
try {
|
|
365
|
+
if (resp.ok) {
|
|
366
|
+
const text = await resp.text();
|
|
367
|
+
lastPackumentBytes = text.length;
|
|
368
|
+
lastPackumentName = name;
|
|
369
|
+
cumulativeBytesDecoded += text.length;
|
|
370
|
+
packumentsDecoded++;
|
|
371
|
+
// cache-obs-2: record L4 hit (registry.npmjs.org fetched).
|
|
372
|
+
cacheStatEvents.push({
|
|
373
|
+
kind: 'hit',
|
|
374
|
+
tier: 'L4',
|
|
375
|
+
cacheKind: 'packument',
|
|
376
|
+
bytes: text.length,
|
|
377
|
+
});
|
|
378
|
+
// [W4] Write back to R2 cache (best-effort, non-blocking).
|
|
379
|
+
// The packument JSON gets a 5-minute TTL via supervisor.
|
|
380
|
+
// We DO await this RPC: per W4-plan §11 finding #2, the
|
|
381
|
+
// facet's lifecycle ends when resolveTreeInFacet returns;
|
|
382
|
+
// unawaited puts may be torn down before R2 commits.
|
|
383
|
+
// Cost: one extra ~30 ms RPC per network-miss packument;
|
|
384
|
+
// mitigated by pLimit hiding it behind concurrent work.
|
|
385
|
+
if (typeof env.SUPERVISOR.putCachedPackument === 'function') {
|
|
386
|
+
try {
|
|
387
|
+
await env.SUPERVISOR.putCachedPackument(name, text);
|
|
388
|
+
}
|
|
389
|
+
catch {
|
|
390
|
+
// best-effort cache write
|
|
391
|
+
}
|
|
392
|
+
}
|
|
393
|
+
return JSON.parse(text);
|
|
394
|
+
}
|
|
395
|
+
if (resp.status >= 400 && resp.status < 500)
|
|
396
|
+
return null;
|
|
397
|
+
// 5xx → drain + retry
|
|
398
|
+
try {
|
|
399
|
+
await resp.body?.cancel();
|
|
400
|
+
}
|
|
401
|
+
catch { }
|
|
402
|
+
lastErr = new Error('HTTP ' + resp.status);
|
|
403
|
+
}
|
|
404
|
+
finally {
|
|
405
|
+
inFlight--;
|
|
406
|
+
}
|
|
407
|
+
}
|
|
408
|
+
catch (e) {
|
|
409
|
+
inFlight = Math.max(0, inFlight - 1);
|
|
410
|
+
lastErr = e;
|
|
411
|
+
}
|
|
412
|
+
if (attempt < totalRetries) {
|
|
413
|
+
const base = BACKOFF[Math.min(attempt, BACKOFF.length - 1)];
|
|
414
|
+
const jitter = Math.round(base + (Math.random() * 2 - 1) * base * 0.25);
|
|
415
|
+
await new Promise((r) => setTimeout(r, Math.max(0, jitter)));
|
|
416
|
+
}
|
|
417
|
+
}
|
|
418
|
+
messages.push(`[resolve-facet] ${name}: fetch exhausted: ${lastErr?.message || lastErr}`);
|
|
419
|
+
return null;
|
|
420
|
+
};
|
|
421
|
+
/** Try to resolve a package using only the in-memory cache. Returns
|
|
422
|
+
* null if no cached version satisfies the range. */
|
|
423
|
+
const resolveFromCache = (name, range) => {
|
|
424
|
+
const inner = cacheByName.get(name);
|
|
425
|
+
if (!inner || inner.size === 0)
|
|
426
|
+
return null;
|
|
427
|
+
const cleanRange = range.replace(/^[~^>=<\s]+/, '');
|
|
428
|
+
if (cleanRange.match(/^\d+\.\d+\.\d+$/)) {
|
|
429
|
+
const exact = inner.get(cleanRange);
|
|
430
|
+
if (exact)
|
|
431
|
+
return cachedEntryToResolved(exact);
|
|
432
|
+
}
|
|
433
|
+
const versions = [...inner.keys()];
|
|
434
|
+
// @ts-ignore — RESOLVE_VERSION provided by preamble.
|
|
435
|
+
const picked = RESOLVE_VERSION(versions, range);
|
|
436
|
+
if (!picked)
|
|
437
|
+
return null;
|
|
438
|
+
const entry = inner.get(picked);
|
|
439
|
+
return entry ? cachedEntryToResolved(entry) : null;
|
|
440
|
+
};
|
|
441
|
+
// X.5-F R1: names the user typed at the top level + required peer-deps
|
|
442
|
+
// bypass SKIP_PACKAGES. Populated lazily as the BFS walk discovers
|
|
443
|
+
// peer-deps. See audit/sections/X5F-plan.md §6.1-§6.2.
|
|
444
|
+
const topLevelNames = new Set(Object.keys(spec.specs));
|
|
445
|
+
/** Resolve one spec: cache-hit or fetch packument. */
|
|
446
|
+
const resolveOne = async (name, range) => {
|
|
447
|
+
// @ts-ignore — SHOULD_SKIP_PACKAGE provided by preamble.
|
|
448
|
+
if (!topLevelNames.has(name) && SHOULD_SKIP_PACKAGE(name, !!spec.frameworkAware))
|
|
449
|
+
return null;
|
|
450
|
+
// W6: registry transitive policy. Swap rewrites name in flight;
|
|
451
|
+
// 'fail' rejects throw; 'warn' rejects log [skip] and drop.
|
|
452
|
+
// W6.5: each decision also pushes a RegistryEvent into __pendingEvents
|
|
453
|
+
// (preamble-provided), drained by the supervisor after the facet
|
|
454
|
+
// returns. NOTE: the throw-path reject case below stops execution
|
|
455
|
+
// BEFORE __DRAIN_EVENTS is read by the caller — so reject events
|
|
456
|
+
// from the facet are an accepted incomplete-coverage gap (W6.5-plan
|
|
457
|
+
// §5.3). We still push them in case a future caller change drains
|
|
458
|
+
// events from the rejected ResolveFacetResult.
|
|
459
|
+
let effName = name;
|
|
460
|
+
// @ts-ignore — SHOULD_SWAP provided by preamble.
|
|
461
|
+
const __swap = SHOULD_SWAP(name);
|
|
462
|
+
if (__swap) {
|
|
463
|
+
messages.push(`[npm] \x1b[33m[swap]\x1b[0m ${__swap.from} → ${__swap.to}`);
|
|
464
|
+
// @ts-ignore — preamble.
|
|
465
|
+
__EMIT_EVENT({ type: 'swap', from: __swap.from, to: __swap.to, ctx: 'transitive' });
|
|
466
|
+
effName = __swap.to;
|
|
467
|
+
}
|
|
468
|
+
else {
|
|
469
|
+
// @ts-ignore — preamble.
|
|
470
|
+
const __warn = SHOULD_WARN_SKIP_TRANSITIVE(name);
|
|
471
|
+
if (__warn) {
|
|
472
|
+
messages.push(`[npm] \x1b[33m[skip]\x1b[0m ${__warn.from} — ${__warn.reason}`);
|
|
473
|
+
// @ts-ignore — preamble.
|
|
474
|
+
__EMIT_EVENT({ type: 'transitive-skip', from: __warn.from, reason: __warn.reason });
|
|
475
|
+
return null;
|
|
476
|
+
}
|
|
477
|
+
// @ts-ignore — preamble.
|
|
478
|
+
const __fail = SHOULD_REJECT_FAIL(name);
|
|
479
|
+
if (__fail) {
|
|
480
|
+
// @ts-ignore — preamble.
|
|
481
|
+
__EMIT_EVENT({
|
|
482
|
+
type: 'reject',
|
|
483
|
+
from: __fail.from,
|
|
484
|
+
reason: __fail.reason,
|
|
485
|
+
suggest: __fail.suggest,
|
|
486
|
+
ctx: 'transitive',
|
|
487
|
+
});
|
|
488
|
+
// Tag with own-property so the BFS catch can identify a
|
|
489
|
+
// registry reject without relying on message-prefix string
|
|
490
|
+
// matching. Mirror of supervisor-side RegistryRejectError.
|
|
491
|
+
const err = new Error(`npm install rejected: ${__fail.from} — ${__fail.reason}`);
|
|
492
|
+
err.__w6_reject = true;
|
|
493
|
+
err.__w6_reject_from = __fail.from;
|
|
494
|
+
err.__w6_reject_reason = __fail.reason;
|
|
495
|
+
throw err;
|
|
496
|
+
}
|
|
497
|
+
}
|
|
498
|
+
const cached = resolveFromCache(effName, range);
|
|
499
|
+
if (cached)
|
|
500
|
+
return cached;
|
|
501
|
+
const data = await fetchPackumentWithRetry(effName);
|
|
502
|
+
if (!data || !data.versions)
|
|
503
|
+
return null;
|
|
504
|
+
// Pick a version
|
|
505
|
+
let version = null;
|
|
506
|
+
if (range && data.versions[range])
|
|
507
|
+
version = range;
|
|
508
|
+
if (!version && range && range !== 'latest') {
|
|
509
|
+
const allVersions = Object.keys(data.versions);
|
|
510
|
+
// @ts-ignore — preamble.
|
|
511
|
+
version = RESOLVE_VERSION(allVersions, range);
|
|
512
|
+
}
|
|
513
|
+
if (!version) {
|
|
514
|
+
version = data['dist-tags']?.[range] || data['dist-tags']?.latest || null;
|
|
515
|
+
}
|
|
516
|
+
if (!version || !data.versions[version]) {
|
|
517
|
+
messages.push(`[resolve-facet] ${effName}: no version satisfies ${range}`);
|
|
518
|
+
return null;
|
|
519
|
+
}
|
|
520
|
+
const vData = data.versions[version];
|
|
521
|
+
const pkg = versionToResolved(vData);
|
|
522
|
+
// Stage cache writes for the resolved version + a few popular ones.
|
|
523
|
+
enqueueCacheWrite({
|
|
524
|
+
name: pkg.name,
|
|
525
|
+
version: pkg.version,
|
|
526
|
+
tarballUrl: pkg.tarballUrl,
|
|
527
|
+
integrity: pkg.integrity,
|
|
528
|
+
depsJson: JSON.stringify(pkg.dependencies),
|
|
529
|
+
peerDepsJson: JSON.stringify(pkg.peerDependencies ?? {}),
|
|
530
|
+
exportsJson: JSON.stringify(pkg.exports ?? {}),
|
|
531
|
+
main: pkg.main,
|
|
532
|
+
moduleField: pkg.module,
|
|
533
|
+
binJson: JSON.stringify(pkg.bin),
|
|
534
|
+
fetchedAt: Date.now(),
|
|
535
|
+
});
|
|
536
|
+
// Cache other recent versions to dodge re-fetches on retransitive deps.
|
|
537
|
+
const sorted = Object.keys(data.versions)
|
|
538
|
+
// @ts-ignore — preamble.
|
|
539
|
+
.map((v) => ({ v, p: PARSE_SEMVER(v) }))
|
|
540
|
+
.filter((x) => x.p !== null)
|
|
541
|
+
// @ts-ignore — preamble.
|
|
542
|
+
.sort((a, b) => COMPARE_SEMVER(b.p, a.p));
|
|
543
|
+
for (let i = 0; i < Math.min(5, sorted.length); i++) {
|
|
544
|
+
const otherVer = sorted[i].v;
|
|
545
|
+
if (otherVer === pkg.version)
|
|
546
|
+
continue;
|
|
547
|
+
const otherData = data.versions[otherVer];
|
|
548
|
+
if (!otherData)
|
|
549
|
+
continue;
|
|
550
|
+
try {
|
|
551
|
+
const otherPkg = versionToResolved(otherData);
|
|
552
|
+
enqueueCacheWrite({
|
|
553
|
+
name: otherPkg.name,
|
|
554
|
+
version: otherPkg.version,
|
|
555
|
+
tarballUrl: otherPkg.tarballUrl,
|
|
556
|
+
integrity: otherPkg.integrity,
|
|
557
|
+
depsJson: JSON.stringify(otherPkg.dependencies),
|
|
558
|
+
peerDepsJson: JSON.stringify(otherPkg.peerDependencies ?? {}),
|
|
559
|
+
exportsJson: JSON.stringify(otherPkg.exports ?? {}),
|
|
560
|
+
main: otherPkg.main,
|
|
561
|
+
moduleField: otherPkg.module,
|
|
562
|
+
binJson: JSON.stringify(otherPkg.bin),
|
|
563
|
+
fetchedAt: Date.now(),
|
|
564
|
+
});
|
|
565
|
+
// Also keep the in-memory cache up to date for further iterations.
|
|
566
|
+
let inner = cacheByName.get(otherPkg.name);
|
|
567
|
+
if (!inner) {
|
|
568
|
+
inner = new Map();
|
|
569
|
+
cacheByName.set(otherPkg.name, inner);
|
|
570
|
+
}
|
|
571
|
+
inner.set(otherPkg.version, {
|
|
572
|
+
name: otherPkg.name,
|
|
573
|
+
version: otherPkg.version,
|
|
574
|
+
tarballUrl: otherPkg.tarballUrl,
|
|
575
|
+
integrity: otherPkg.integrity,
|
|
576
|
+
depsJson: JSON.stringify(otherPkg.dependencies),
|
|
577
|
+
peerDepsJson: JSON.stringify(otherPkg.peerDependencies ?? {}),
|
|
578
|
+
exportsJson: JSON.stringify(otherPkg.exports ?? {}),
|
|
579
|
+
main: otherPkg.main,
|
|
580
|
+
moduleField: otherPkg.module,
|
|
581
|
+
binJson: JSON.stringify(otherPkg.bin),
|
|
582
|
+
fetchedAt: Date.now(),
|
|
583
|
+
});
|
|
584
|
+
}
|
|
585
|
+
catch { /* skip malformed */ }
|
|
586
|
+
}
|
|
587
|
+
return pkg;
|
|
588
|
+
};
|
|
589
|
+
// X.5-G G1: facet-side mirror of isOptionalNativeBinding from
|
|
590
|
+
// src/wasm-swap-registry.ts. The facet body is serialised via
|
|
591
|
+
// fn.toString() and cannot import — local helpers are inlined here.
|
|
592
|
+
// Keep this byte-equivalent in shape with the registry export.
|
|
593
|
+
const NATIVE_SHARD_PREFIXES_FACET = [
|
|
594
|
+
'@rollup/rollup-', '@parcel/watcher-', '@swc/core-', '@next/swc-',
|
|
595
|
+
'@tailwindcss/oxide-', '@img/sharp-', '@napi-rs/canvas-',
|
|
596
|
+
'@biomejs/cli-', '@esbuild/',
|
|
597
|
+
];
|
|
598
|
+
const isOptionalNativeBindingFacet = (p) => {
|
|
599
|
+
if (!p)
|
|
600
|
+
return false;
|
|
601
|
+
if (Array.isArray(p.os) && p.os.length > 0)
|
|
602
|
+
return true;
|
|
603
|
+
if (Array.isArray(p.cpu) && p.cpu.length > 0)
|
|
604
|
+
return true;
|
|
605
|
+
if (Array.isArray(p.libc) && p.libc.length > 0)
|
|
606
|
+
return true;
|
|
607
|
+
if (typeof p.main === 'string' && /\.node$/.test(p.main))
|
|
608
|
+
return true;
|
|
609
|
+
if (typeof p.name === 'string') {
|
|
610
|
+
for (const prefix of NATIVE_SHARD_PREFIXES_FACET) {
|
|
611
|
+
if (p.name.startsWith(prefix) && p.name.length > prefix.length) {
|
|
612
|
+
if (p.name === '@rollup/wasm-node')
|
|
613
|
+
return false;
|
|
614
|
+
return true;
|
|
615
|
+
}
|
|
616
|
+
}
|
|
617
|
+
}
|
|
618
|
+
return false;
|
|
619
|
+
};
|
|
620
|
+
// ── Breadth-first walk (mirror of npm-resolver.ts:resolveTree) ───────
|
|
621
|
+
const resolved = new Map();
|
|
622
|
+
const seen = new Set();
|
|
623
|
+
const optionalNames = new Set(); // X.5-G G1
|
|
624
|
+
// X.5-drizzle: names enqueued by the X.5-J top-level optional-peer
|
|
625
|
+
// path (R2.5) and ALL their transitive descendants. The user did not
|
|
626
|
+
// explicitly ask for them — npm CLI's --include=peer pulls them as a
|
|
627
|
+
// best-effort convenience. When a `transitive: 'fail'` REJECT_INSTALL
|
|
628
|
+
// fires for a name in this set, we silent-skip the offending name +
|
|
629
|
+
// log a notice, instead of throwing and killing the parent install.
|
|
630
|
+
// Pre-X.5-drizzle, drizzle-orm's optional peer `expo-sqlite` (its
|
|
631
|
+
// peer `expo` → dep `@expo/metro-config` → dep `lightningcss`) hard-
|
|
632
|
+
// killed the install once X.5-26b made lightningcss `transitive:
|
|
633
|
+
// 'fail'`. The user only typed `npm install drizzle-orm`; expo-sqlite
|
|
634
|
+
// and its mobile-build chain are best-effort by intent. See
|
|
635
|
+
// audit/sections/X5-drizzle-plan.md §2 (revised) and the trace probe
|
|
636
|
+
// audit/probes/x5-drizzle/investigation/04-trace-lightningcss-from-drizzle.mjs.
|
|
637
|
+
const bestEffortNames = new Set();
|
|
638
|
+
const queue2 = Object.entries(spec.specs);
|
|
639
|
+
// F-2 profiling: emit per-layer width when host marks the diag flag.
|
|
640
|
+
// The facet doesn't see process.env directly (preamble), so we
|
|
641
|
+
// surface via messages array (already piped to install log via
|
|
642
|
+
// result.messages → for (const m of result.messages) log(m)).
|
|
643
|
+
// Probe sets spec.__f2DiagWidths = true to opt-in.
|
|
644
|
+
// @ts-ignore — extra field on spec for diag opt-in.
|
|
645
|
+
const __f2Diag = !!spec.__f2DiagWidths;
|
|
646
|
+
let __f2LayerN = 0;
|
|
647
|
+
while (queue2.length > 0) {
|
|
648
|
+
const batch = queue2.splice(0, Math.min(queue2.length, concurrency));
|
|
649
|
+
if (__f2Diag) {
|
|
650
|
+
messages.push(`[f2-layer-width] N=${__f2LayerN} width=${batch.length} queueRemain=${queue2.length} resolved=${resolved.size} seen=${seen.size}`);
|
|
651
|
+
__f2LayerN++;
|
|
652
|
+
}
|
|
653
|
+
const results = await Promise.all(batch.map(([name, range]) => limit(async () => {
|
|
654
|
+
if (seen.has(name))
|
|
655
|
+
return null;
|
|
656
|
+
seen.add(name);
|
|
657
|
+
// @ts-ignore — preamble.
|
|
658
|
+
// X.5-F R1: top-level + required peer-deps bypass SKIP_PACKAGES.
|
|
659
|
+
if (!topLevelNames.has(name) && SHOULD_SKIP_PACKAGE(name, !!spec.frameworkAware))
|
|
660
|
+
return null;
|
|
661
|
+
const isOptional = optionalNames.has(name);
|
|
662
|
+
try {
|
|
663
|
+
const pkg = await resolveOne(name, range);
|
|
664
|
+
// X.5-G G1: silent-skip platform-native bindings sourced
|
|
665
|
+
// from optionalDependencies. Mirrors npm-resolver.ts.
|
|
666
|
+
if (pkg && isOptional && isOptionalNativeBindingFacet({
|
|
667
|
+
name: pkg.name,
|
|
668
|
+
os: pkg.os, cpu: pkg.cpu, libc: pkg.libc,
|
|
669
|
+
main: pkg.main,
|
|
670
|
+
})) {
|
|
671
|
+
const reason = `optional native binding (os=${pkg.os ?? '*'}, cpu=${pkg.cpu ?? '*'}, libc=${pkg.libc ?? '*'}, main=${pkg.main || '?'})`;
|
|
672
|
+
messages.push(`[resolve-facet] [skip] ${name} — ${reason}`);
|
|
673
|
+
// @ts-ignore — preamble.
|
|
674
|
+
__EMIT_EVENT({ type: 'transitive-skip', from: name, reason });
|
|
675
|
+
return null;
|
|
676
|
+
}
|
|
677
|
+
return pkg;
|
|
678
|
+
}
|
|
679
|
+
catch (e) {
|
|
680
|
+
// W6: REJECT_INSTALL with transitive='fail' throws from
|
|
681
|
+
// resolveOne tagged with `__w6_reject = true`. Propagate
|
|
682
|
+
// those — turning them into "UNHANDLED" log lines would
|
|
683
|
+
// silently partial-install. Other UNHANDLEDs continue to
|
|
684
|
+
// log + drop. Detection via own-property survives the
|
|
685
|
+
// postMessage / fn.toString() boundary (prototype is lost
|
|
686
|
+
// on that boundary, so `instanceof` would not work).
|
|
687
|
+
if (e && typeof e === 'object' && e.__w6_reject === true) {
|
|
688
|
+
// X.5-drizzle: REJECT_INSTALL transitive='fail' that fires
|
|
689
|
+
// INSIDE an X.5-J best-effort optional-peer subtree
|
|
690
|
+
// (R2.5 enqueue) softly skips the offending package
|
|
691
|
+
// instead of failing the parent install. The user did
|
|
692
|
+
// not explicitly ask for the optional-peer-rooted
|
|
693
|
+
// subtree; mirror npm's --omit=optional behaviour for
|
|
694
|
+
// its descendants. See VERIFY-9D4B61D §6 + the trace
|
|
695
|
+
// probe at audit/probes/x5-drizzle/investigation/
|
|
696
|
+
// 04-trace-lightningcss-from-drizzle.mjs for the
|
|
697
|
+
// canonical drizzle-orm → expo-sqlite → expo → @expo/
|
|
698
|
+
// metro-config → lightningcss chain.
|
|
699
|
+
if (bestEffortNames.has(name)) {
|
|
700
|
+
const reason = `inside best-effort optional-peer subtree (X.5-drizzle): ${e?.message ?? 'reject'}`;
|
|
701
|
+
messages.push(`[resolve-facet] [skip] ${name} — ${reason}`);
|
|
702
|
+
// @ts-ignore — preamble.
|
|
703
|
+
__EMIT_EVENT({ type: 'transitive-skip', from: name, reason });
|
|
704
|
+
return null;
|
|
705
|
+
}
|
|
706
|
+
throw e;
|
|
707
|
+
}
|
|
708
|
+
// X.5-G G1: optional-dep fetch failures silent-skip rather
|
|
709
|
+
// than propagating as UNHANDLED.
|
|
710
|
+
if (isOptional) {
|
|
711
|
+
const reason = `optional dep fetch failed: ${e?.message ?? 'unknown'}`;
|
|
712
|
+
messages.push(`[resolve-facet] [skip] ${name} — ${reason}`);
|
|
713
|
+
// @ts-ignore — preamble.
|
|
714
|
+
__EMIT_EVENT({ type: 'transitive-skip', from: name, reason });
|
|
715
|
+
return null;
|
|
716
|
+
}
|
|
717
|
+
const msg = e?.message || String(e);
|
|
718
|
+
messages.push(`[resolve-facet] ${name}: UNHANDLED: ${msg}`);
|
|
719
|
+
return null;
|
|
720
|
+
}
|
|
721
|
+
})));
|
|
722
|
+
for (const pkg of results) {
|
|
723
|
+
if (!pkg || resolved.has(pkg.name))
|
|
724
|
+
continue;
|
|
725
|
+
resolved.set(pkg.name, pkg);
|
|
726
|
+
// X.5-drizzle: when this pkg was best-effort (a child of an
|
|
727
|
+
// X.5-J optional-peer subtree), its newly-enqueued descendants
|
|
728
|
+
// inherit the best-effort flag so a deep `transitive: 'fail'`
|
|
729
|
+
// REJECT_INSTALL silent-skips instead of killing the parent.
|
|
730
|
+
const inheritBestEffort = bestEffortNames.has(pkg.name);
|
|
731
|
+
for (const [depName, depRange] of Object.entries(pkg.dependencies)) {
|
|
732
|
+
if (!resolved.has(depName) && !seen.has(depName)) {
|
|
733
|
+
if (inheritBestEffort)
|
|
734
|
+
bestEffortNames.add(depName);
|
|
735
|
+
queue2.push([depName, depRange]);
|
|
736
|
+
}
|
|
737
|
+
}
|
|
738
|
+
// X.5-G G1: enqueue transitive optionalDependencies (tagged so
|
|
739
|
+
// resolveOne silent-skips platform-native bindings). Mirrors
|
|
740
|
+
// npm-resolver.ts.
|
|
741
|
+
const optDeps = pkg.optionalDependencies;
|
|
742
|
+
if (optDeps) {
|
|
743
|
+
for (const [depName, depRange] of Object.entries(optDeps)) {
|
|
744
|
+
if (!resolved.has(depName) && !seen.has(depName)) {
|
|
745
|
+
optionalNames.add(depName);
|
|
746
|
+
if (inheritBestEffort)
|
|
747
|
+
bestEffortNames.add(depName);
|
|
748
|
+
queue2.push([depName, depRange]);
|
|
749
|
+
}
|
|
750
|
+
}
|
|
751
|
+
}
|
|
752
|
+
// X.5-F R2: enqueue REQUIRED peerDeps. Mirrors npm-resolver.ts
|
|
753
|
+
// resolveTree. Mark them as topLevel so they bypass SKIP_PACKAGES
|
|
754
|
+
// (typescript is a peer of ts-jest).
|
|
755
|
+
if (pkg.peerDependencies) {
|
|
756
|
+
for (const [peerName, peerRange] of Object.entries(pkg.peerDependencies)) {
|
|
757
|
+
if (resolved.has(peerName) || seen.has(peerName))
|
|
758
|
+
continue;
|
|
759
|
+
topLevelNames.add(peerName);
|
|
760
|
+
if (inheritBestEffort)
|
|
761
|
+
bestEffortNames.add(peerName);
|
|
762
|
+
queue2.push([peerName, peerRange]);
|
|
763
|
+
}
|
|
764
|
+
}
|
|
765
|
+
// X.5-F R2.5: when THIS pkg is the user's top-level request,
|
|
766
|
+
// also enqueue OPTIONAL peer-deps (npm CLI's --include=peer
|
|
767
|
+
// default). Without this, framer-motion installs but its
|
|
768
|
+
// compiled CJS still imports react/jsx-runtime.
|
|
769
|
+
//
|
|
770
|
+
// X.5-J: optional peers whose target is in REJECT_INSTALL get
|
|
771
|
+
// SOFT-SKIPPED at enqueue time. Mirror of npm-resolver.ts:R2.5.
|
|
772
|
+
// Uses preamble-injected SHOULD_REJECT_FAIL +
|
|
773
|
+
// SHOULD_WARN_SKIP_TRANSITIVE accessors (the facet body is
|
|
774
|
+
// serialised via fn.toString() and cannot import lookupReject).
|
|
775
|
+
// See audit/sections/X5J-plan.md §3 for the full rationale and
|
|
776
|
+
// §3.6 for why we soft-skip BOTH transitive='fail' (loud reject)
|
|
777
|
+
// and transitive='warn' optional peers — symmetry with the
|
|
778
|
+
// existing transitive walk's silent-skip of warn-tier peers, plus
|
|
779
|
+
// a small efficiency win (no resolveOne roundtrip needed).
|
|
780
|
+
if (topLevelNames.has(pkg.name)) {
|
|
781
|
+
const allPeers = pkg.__allPeerDependencies;
|
|
782
|
+
if (allPeers) {
|
|
783
|
+
for (const [peerName, peerRange] of Object.entries(allPeers)) {
|
|
784
|
+
if (resolved.has(peerName) || seen.has(peerName))
|
|
785
|
+
continue;
|
|
786
|
+
// X.5-J: filter optional peers through REJECT_INSTALL.
|
|
787
|
+
// @ts-ignore — preamble.
|
|
788
|
+
const __peerFail = SHOULD_REJECT_FAIL(peerName);
|
|
789
|
+
// @ts-ignore — preamble.
|
|
790
|
+
const __peerWarn = SHOULD_WARN_SKIP_TRANSITIVE(peerName);
|
|
791
|
+
const __peerReject = __peerFail || __peerWarn;
|
|
792
|
+
if (__peerReject) {
|
|
793
|
+
const reason = `optional peer in REJECT_INSTALL: ${peerName} — ${__peerReject.reason}`;
|
|
794
|
+
messages.push(`[resolve-facet] [skip] ${peerName} — ${reason}`);
|
|
795
|
+
// @ts-ignore — preamble.
|
|
796
|
+
__EMIT_EVENT({ type: 'transitive-skip', from: peerName, reason });
|
|
797
|
+
continue; // do NOT seen.add — let a later required-dep
|
|
798
|
+
// walk hit it via its own resolveOne path.
|
|
799
|
+
}
|
|
800
|
+
topLevelNames.add(peerName);
|
|
801
|
+
// X.5-drizzle: tag the optional-peer enqueue as best-effort
|
|
802
|
+
// so a deep `transitive: 'fail'` REJECT (e.g.,
|
|
803
|
+
// expo-sqlite → expo → @expo/metro-config → lightningcss)
|
|
804
|
+
// silent-skips the offending sub-tree instead of killing
|
|
805
|
+
// the parent (drizzle-orm) install.
|
|
806
|
+
bestEffortNames.add(peerName);
|
|
807
|
+
queue2.push([peerName, peerRange]);
|
|
808
|
+
}
|
|
809
|
+
}
|
|
810
|
+
}
|
|
811
|
+
}
|
|
812
|
+
}
|
|
813
|
+
// Final cache flush before returning.
|
|
814
|
+
await flushCache();
|
|
815
|
+
return {
|
|
816
|
+
resolved: [...resolved.values()],
|
|
817
|
+
messages,
|
|
818
|
+
// @ts-ignore — preamble-provided drain helper.
|
|
819
|
+
registryEvents: typeof __DRAIN_EVENTS === 'function' ? __DRAIN_EVENTS() : [],
|
|
820
|
+
facetCounters: {
|
|
821
|
+
inFlightPeak,
|
|
822
|
+
cumulativeBytesDecoded,
|
|
823
|
+
packumentsDecoded,
|
|
824
|
+
lastPackumentName,
|
|
825
|
+
lastPackumentBytes,
|
|
826
|
+
pipelinedPackumentRaceWins,
|
|
827
|
+
pipelinedPackumentRaceLosses,
|
|
828
|
+
},
|
|
829
|
+
cacheStatEvents,
|
|
830
|
+
elapsed: Date.now() - t0,
|
|
831
|
+
cacheWriteCount: totalCacheWrites,
|
|
832
|
+
};
|
|
833
|
+
};
|