@nimbus-sh/worker 0.1.2 → 0.1.4
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/LICENSE +21 -0
- package/NOTICE.md +6 -0
- package/README.md +2 -2
- package/dist/_shared/cache-stats.d.ts +1 -1
- package/dist/_shared/cache-stats.js +1 -1
- package/dist/_shared/exports-resolver.d.ts +0 -2
- package/dist/_shared/exports-resolver.d.ts.map +1 -1
- package/dist/_shared/exports-resolver.js +0 -2
- package/dist/_shared/session-router.d.ts +0 -1
- package/dist/_shared/session-router.d.ts.map +1 -1
- package/dist/_shared/session-router.js +0 -1
- package/dist/constants.d.ts.map +1 -1
- package/dist/constants.js +0 -1
- package/dist/facets/cirrus-real.d.ts +1 -1
- package/dist/facets/cirrus-real.js +1 -1
- package/dist/facets/manager.d.ts +0 -1
- package/dist/facets/manager.d.ts.map +1 -1
- package/dist/facets/manager.js +3 -15
- package/dist/facets/process.d.ts +2 -2
- package/dist/facets/process.js +2 -2
- package/dist/facets/vite-dev-server.d.ts +3 -3
- package/dist/facets/vite-dev-server.d.ts.map +1 -1
- package/dist/facets/vite-dev-server.js +6 -8
- package/dist/facets/wasm-swap-registry.d.ts +15 -21
- package/dist/facets/wasm-swap-registry.d.ts.map +1 -1
- package/dist/facets/wasm-swap-registry.js +41 -54
- package/dist/facets/ws-terminal.d.ts +4 -5
- package/dist/facets/ws-terminal.d.ts.map +1 -1
- package/dist/facets/ws-terminal.js +7 -8
- package/dist/git/commands.d.ts.map +1 -1
- package/dist/git/commands.js +0 -1
- package/dist/git/network-facet.d.ts.map +1 -1
- package/dist/git/network-facet.js +0 -2
- package/dist/git-bundle.generated.d.ts +2 -3
- package/dist/git-bundle.generated.d.ts.map +1 -1
- package/dist/git-bundle.generated.js +3 -4
- package/dist/index.js +2 -2
- package/dist/loaders/child-process/spawn-facet.d.ts +7 -52
- package/dist/loaders/child-process/spawn-facet.d.ts.map +1 -1
- package/dist/loaders/child-process/spawn-facet.js +7 -49
- package/dist/loaders/child-process/spawn-pool.d.ts +5 -44
- package/dist/loaders/child-process/spawn-pool.d.ts.map +1 -1
- package/dist/loaders/child-process/spawn-pool.js +5 -44
- package/dist/loaders/fanout-pool.d.ts +18 -65
- package/dist/loaders/fanout-pool.d.ts.map +1 -1
- package/dist/loaders/fanout-pool.js +25 -87
- package/dist/loaders/generated-workers.d.ts +1 -2
- package/dist/loaders/generated-workers.d.ts.map +1 -1
- package/dist/loaders/generated-workers.js +5 -6
- package/dist/loaders/loader-pool.d.ts +1 -2
- package/dist/loaders/loader-pool.d.ts.map +1 -1
- package/dist/loaders/loader-pool.js +1 -1
- package/dist/loaders/npm-resolve-preamble.d.ts +4 -5
- package/dist/loaders/npm-resolve-preamble.d.ts.map +1 -1
- package/dist/loaders/npm-resolve-preamble.js +14 -21
- package/dist/loaders/pre-bundle-preamble.d.ts.map +1 -1
- package/dist/loaders/pre-bundle-preamble.js +0 -1
- package/dist/npm/cache.js +1 -1
- package/dist/npm/install-batch-facet.d.ts.map +1 -1
- package/dist/npm/install-batch-facet.js +7 -12
- package/dist/npm/installer.d.ts +5 -7
- package/dist/npm/installer.d.ts.map +1 -1
- package/dist/npm/installer.js +20 -101
- package/dist/npm/r2-cache.d.ts +17 -29
- package/dist/npm/r2-cache.d.ts.map +1 -1
- package/dist/npm/r2-cache.js +16 -27
- package/dist/npm/resolve-facet.d.ts +11 -17
- package/dist/npm/resolve-facet.d.ts.map +1 -1
- package/dist/npm/resolve-facet.js +14 -28
- package/dist/npm/resolve-one-facet.d.ts +10 -13
- package/dist/npm/resolve-one-facet.d.ts.map +1 -1
- package/dist/npm/resolve-one-facet.js +8 -10
- package/dist/npm/resolver.d.ts +0 -2
- package/dist/npm/resolver.d.ts.map +1 -1
- package/dist/npm/resolver.js +0 -12
- package/dist/observability/oom-discriminator.d.ts +0 -2
- package/dist/observability/oom-discriminator.d.ts.map +1 -1
- package/dist/observability/oom-discriminator.js +0 -2
- package/dist/replica/routing.js +1 -1
- package/dist/router/index.d.ts +1 -1
- package/dist/router/index.js +1 -1
- package/dist/runtime/barrel-synthesizer.js +1 -1
- package/dist/runtime/clang-runner.d.ts +5 -6
- package/dist/runtime/clang-runner.d.ts.map +1 -1
- package/dist/runtime/clang-runner.js +5 -6
- package/dist/runtime/esbuild-service.d.ts.map +1 -1
- package/dist/runtime/esbuild-service.js +0 -3
- package/dist/runtime/framework-detect.d.ts +0 -1
- package/dist/runtime/framework-detect.d.ts.map +1 -1
- package/dist/runtime/framework-detect.js +0 -1
- package/dist/runtime/node-runner.d.ts +1 -1
- package/dist/runtime/node-runner.js +1 -1
- package/dist/runtime/node-shims.d.ts.map +1 -1
- package/dist/runtime/node-shims.js +0 -22
- package/dist/runtime/package-manager.d.ts +2 -7
- package/dist/runtime/package-manager.d.ts.map +1 -1
- package/dist/runtime/package-manager.js +2 -7
- package/dist/runtime/process-logs-api.js +1 -1
- package/dist/runtime/process-logs.d.ts +0 -1
- package/dist/runtime/process-logs.d.ts.map +1 -1
- package/dist/runtime/process-table.d.ts +2 -2
- package/dist/runtime/process-table.d.ts.map +1 -1
- package/dist/runtime/process-table.js +1 -1
- package/dist/runtime/python-repl.d.ts +0 -1
- package/dist/runtime/python-repl.d.ts.map +1 -1
- package/dist/runtime/python-repl.js +0 -1
- package/dist/runtime/python-runner.d.ts +1 -2
- package/dist/runtime/python-runner.d.ts.map +1 -1
- package/dist/runtime/python-runner.js +1 -3
- package/dist/runtime/repl-session.d.ts +0 -1
- package/dist/runtime/repl-session.d.ts.map +1 -1
- package/dist/runtime/repl-session.js +1 -2
- package/dist/runtime/require-resolver.d.ts.map +1 -1
- package/dist/runtime/require-resolver.js +1 -4
- package/dist/runtime/ruby-runner.d.ts +0 -1
- package/dist/runtime/ruby-runner.d.ts.map +1 -1
- package/dist/runtime/ruby-runner.js +0 -1
- package/dist/runtime/runtime-catalog.d.ts +2 -4
- package/dist/runtime/runtime-catalog.d.ts.map +1 -1
- package/dist/runtime/runtime-catalog.js +2 -4
- package/dist/runtime/runtime-registry.d.ts +1 -1
- package/dist/runtime/runtime-registry.js +1 -1
- package/dist/runtime/streams.d.ts.map +1 -1
- package/dist/runtime/streams.js +0 -1
- package/dist/runtime/wasi-instance.d.ts +35 -45
- package/dist/runtime/wasi-instance.d.ts.map +1 -1
- package/dist/runtime/wasi-instance.js +87 -103
- package/dist/runtime/wasm-runner.d.ts +9 -15
- package/dist/runtime/wasm-runner.d.ts.map +1 -1
- package/dist/runtime/wasm-runner.js +23 -29
- package/dist/session/bindings.d.ts +2 -7
- package/dist/session/bindings.d.ts.map +1 -1
- package/dist/session/bindings.js +3 -8
- package/dist/session/helpers.d.ts +2 -9
- package/dist/session/helpers.d.ts.map +1 -1
- package/dist/session/helpers.js +2 -10
- package/dist/session/init.d.ts +3 -6
- package/dist/session/init.d.ts.map +1 -1
- package/dist/session/init.js +25 -30
- package/dist/session/nimbus-session.d.ts +1 -1
- package/dist/session/nimbus-session.js +5 -5
- package/dist/session/routes.d.ts.map +1 -1
- package/dist/session/routes.js +9 -16
- package/dist/session/rpc.d.ts +2 -2
- package/dist/session/rpc.js +6 -6
- package/dist/session/supervisor-rpc.d.ts +1 -2
- package/dist/session/supervisor-rpc.d.ts.map +1 -1
- package/dist/session/supervisor-rpc.js +1 -5
- package/dist/shell/features.d.ts +5 -5
- package/dist/shell/features.js +6 -6
- package/dist/shell/unix-commands.js +15 -15
- package/dist/vfs/dev-provider.d.ts +1 -1
- package/dist/vfs/dev-provider.js +1 -1
- package/dist/vfs/sqlite-vfs.d.ts +3 -3
- package/dist/vfs/sqlite-vfs.d.ts.map +1 -1
- package/dist/vfs/sqlite-vfs.js +10 -11
- package/package.json +12 -2
- package/public/s/index.html +44 -75
- package/scripts/bundle-facet-workers.mjs +1 -1
- package/scripts/bundle-git.mjs +1 -1
|
@@ -15,11 +15,10 @@
|
|
|
15
15
|
* W7-frame symbols: encodeWriteBatchStream, decodeWriteBatchStream,
|
|
16
16
|
* W7_MAGIC, W7_TRAILER.
|
|
17
17
|
*
|
|
18
|
-
*
|
|
19
|
-
* Tar size: 3.86 KiB
|
|
18
|
+
* Tar size: 3.84 KiB
|
|
20
19
|
* W7 size: 7.78 KiB
|
|
21
20
|
*/
|
|
22
|
-
export const TAR_STREAM_PREAMBLE = "//
|
|
23
|
-
export const TAR_STREAM_PREAMBLE_SIZE =
|
|
24
|
-
export const W7_FRAME_PREAMBLE = "//
|
|
25
|
-
export const W7_FRAME_PREAMBLE_SIZE =
|
|
21
|
+
export const TAR_STREAM_PREAMBLE = "// src/npm/tarball-stream.ts\nvar MAX_FILE_BYTES = 2e7;\nfunction parseTarHeader(block) {\n if (block[0] === 0) return null;\n let name = \"\";\n for (let i = 0; i < 100 && block[i] !== 0; i++) {\n name += String.fromCharCode(block[i]);\n }\n let prefix = \"\";\n for (let i = 345; i < 500 && block[i] !== 0; i++) {\n prefix += String.fromCharCode(block[i]);\n }\n if (prefix) name = prefix + \"/\" + name;\n name = name.replace(/^package\\//, \"\");\n let sizeStr = \"\";\n for (let i = 124; i < 136 && block[i] !== 0; i++) {\n sizeStr += String.fromCharCode(block[i]);\n }\n const size = parseInt(sizeStr.trim(), 8) || 0;\n const typeFlag = block[156];\n return { name, size, typeFlag };\n}\nasync function* readableStreamToAsyncIterable(rs) {\n const reader = rs.getReader();\n try {\n while (true) {\n const { value, done } = await reader.read();\n if (done) return;\n if (value && value.length > 0) yield value;\n }\n } finally {\n try {\n reader.releaseLock();\n } catch {\n }\n }\n}\nasync function* streamTarEntries(source, onSkip) {\n let carry = new Uint8Array(0);\n let state = { kind: \"header\" };\n function concat(a, b) {\n if (a.length === 0) return b;\n if (b.length === 0) return a;\n const out = new Uint8Array(a.length + b.length);\n out.set(a, 0);\n out.set(b, a.length);\n return out;\n }\n for await (const chunkRaw of source) {\n let buf = concat(carry, chunkRaw);\n let cursor = 0;\n while (true) {\n if (state.kind === \"header\") {\n if (buf.length - cursor < 512) break;\n const header = buf.subarray(cursor, cursor + 512);\n const parsed = parseTarHeader(header);\n cursor += 512;\n if (!parsed) return;\n const { name, size, typeFlag } = parsed;\n const pad = size === 0 ? 0 : (512 - size % 512) % 512;\n const isRegularFile = typeFlag === 48 || typeFlag === 0;\n if (size === 0) {\n if (isRegularFile && name) {\n yield { name, data: new Uint8Array(0) };\n }\n state = { kind: \"header\" };\n continue;\n }\n if (!isRegularFile || !name || size > MAX_FILE_BYTES) {\n if (onSkip) {\n const reason = !isRegularFile ? \"non-regular\" : !name ? \"no-name\" : \"too-large\";\n try {\n onSkip(name, size, reason);\n } catch {\n }\n }\n state = { kind: \"skip\", remaining: size + pad };\n continue;\n }\n state = {\n kind: \"file\",\n name,\n remaining: size,\n fileBuf: new Uint8Array(size),\n fileOffset: 0,\n pad,\n skip: false\n };\n continue;\n }\n if (state.kind === \"file\") {\n const avail2 = buf.length - cursor;\n if (avail2 === 0) break;\n if (state.remaining > 0) {\n const take2 = Math.min(state.remaining, avail2);\n state.fileBuf.set(buf.subarray(cursor, cursor + take2), state.fileOffset);\n state.fileOffset += take2;\n state.remaining -= take2;\n cursor += take2;\n if (state.remaining > 0) break;\n }\n if (state.pad > 0) {\n const avail22 = buf.length - cursor;\n if (avail22 === 0) break;\n const take2 = Math.min(state.pad, avail22);\n state.pad -= take2;\n cursor += take2;\n if (state.pad > 0) break;\n }\n yield { name: state.name, data: state.fileBuf };\n state = { kind: \"header\" };\n continue;\n }\n const avail = buf.length - cursor;\n if (avail === 0) break;\n const take = Math.min(state.remaining, avail);\n cursor += take;\n state.remaining -= take;\n if (state.remaining > 0) break;\n state = { kind: \"header\" };\n }\n if (cursor >= buf.length) {\n carry = new Uint8Array(0);\n } else if (cursor === 0) {\n carry = buf;\n } else {\n carry = buf.slice(cursor);\n }\n }\n}";
|
|
22
|
+
export const TAR_STREAM_PREAMBLE_SIZE = 3932;
|
|
23
|
+
export const W7_FRAME_PREAMBLE = "// src/_shared/w7-frame.ts\nvar W7_MAGIC = new Uint8Array([78, 87, 55, 1]);\nvar W7_TRAILER = new Uint8Array([78, 69, 78, 68]);\nvar ENCODER_QUEUE_HWM = 256 * 1024;\nvar ENCODER_EMIT_CAP = 64 * 1024;\nvar _peakInFlight = 0;\nvar _currentInFlight = 0;\nfunction _peakInFlightBytes() {\n return _peakInFlight;\n}\nfunction _resetPeakInFlightBytes() {\n _peakInFlight = 0;\n _currentInFlight = 0;\n}\nfunction _trackInFlightAdd(n) {\n _currentInFlight += n;\n if (_currentInFlight > _peakInFlight) _peakInFlight = _currentInFlight;\n}\nfunction _trackInFlightSub(n) {\n _currentInFlight -= n;\n if (_currentInFlight < 0) _currentInFlight = 0;\n}\nfunction encodeWriteBatchStream(payload) {\n const inodes = payload.inodes ?? [];\n const chunks = payload.chunks ?? [];\n const deletePaths = payload.deletePaths;\n let phase = 0;\n let chunkIdx = 0;\n const enc = new TextEncoder();\n const headerBytes = enc.encode(JSON.stringify({\n inodes,\n deletePaths,\n chunkCount: chunks.length\n }));\n const source = {\n type: \"bytes\",\n pull(controller) {\n try {\n if (phase === 0) {\n enqueue(controller, W7_MAGIC.slice());\n phase = 1;\n return;\n }\n if (phase === 1) {\n const hdr = new Uint8Array(4 + headerBytes.length);\n writeU32LE(hdr, 0, headerBytes.length);\n hdr.set(headerBytes, 4);\n enqueue(controller, hdr);\n phase = 2;\n return;\n }\n if (phase === 2) {\n if (chunkIdx >= chunks.length) {\n phase = 3;\n } else {\n const c = chunks[chunkIdx++];\n const pathBytes = enc.encode(c.path);\n const data = c.data instanceof Uint8Array ? c.data : new Uint8Array(c.data);\n const headerSize = 4 + pathBytes.length + 4 + 4;\n const headerOut = new Uint8Array(headerSize);\n let o = 0;\n writeU32LE(headerOut, o, pathBytes.length);\n o += 4;\n headerOut.set(pathBytes, o);\n o += pathBytes.length;\n writeU32LE(headerOut, o, c.chunkId);\n o += 4;\n writeU32LE(headerOut, o, data.length);\n o += 4;\n enqueue(controller, headerOut);\n if (data.length === 0) return;\n if (data.length <= ENCODER_EMIT_CAP) {\n enqueue(controller, data);\n } else {\n for (let i = 0; i < data.length; i += ENCODER_EMIT_CAP) {\n enqueue(controller, data.subarray(i, Math.min(i + ENCODER_EMIT_CAP, data.length)));\n }\n }\n return;\n }\n }\n if (phase === 3) {\n enqueue(controller, W7_TRAILER.slice());\n phase = 4;\n controller.close();\n return;\n }\n controller.close();\n } catch (e) {\n controller.error(e);\n }\n },\n cancel() {\n phase = 4;\n chunkIdx = chunks.length;\n }\n };\n return new ReadableStream(source, {\n // Byte streams (`type: 'bytes'`) MUST use the default byte-counted\n // strategy: highWaterMark is in bytes, size is implicit. Custom\n // `size` callbacks are forbidden — they throw at construction.\n highWaterMark: ENCODER_QUEUE_HWM\n });\n function enqueue(controller, bytes) {\n _trackInFlightAdd(bytes.byteLength);\n controller.enqueue(bytes);\n queueMicrotask(() => _trackInFlightSub(bytes.byteLength));\n }\n}\nasync function decodeWriteBatchStream(stream) {\n const reader = stream.getReader();\n const buf = new ByteBuffer(reader);\n const magic = await buf.readExact(4, \"magic\");\n if (!bytesEqual(magic, W7_MAGIC)) {\n try {\n reader.releaseLock();\n } catch {\n }\n throw new Error(`w7-frame: bad magic, expected NW7\\\\x01, got ${Array.from(magic).map((b) => b.toString(16)).join(\" \")}`);\n }\n const hdrLenBytes = await buf.readExact(4, \"header-length\");\n const hdrLen = readU32LE(hdrLenBytes, 0);\n if (hdrLen < 0 || hdrLen > 64 * 1024 * 1024) {\n throw new Error(`w7-frame: implausible header length ${hdrLen}`);\n }\n const hdrJson = await buf.readExact(hdrLen, \"header-json\");\n let header;\n try {\n header = JSON.parse(new TextDecoder().decode(hdrJson));\n } catch (e) {\n throw new Error(`w7-frame: header JSON parse failed: ${e?.message || e}`);\n }\n if (!header || !Array.isArray(header.inodes) || typeof header.chunkCount !== \"number\") {\n throw new Error(\"w7-frame: header missing required fields (inodes / chunkCount)\");\n }\n const chunkIter = {\n [Symbol.asyncIterator]() {\n let idx = 0;\n let exhausted = false;\n return {\n async next() {\n if (exhausted) return { value: void 0, done: true };\n if (idx >= header.chunkCount) {\n const trailer = await buf.readExact(4, \"trailer\");\n if (!bytesEqual(trailer, W7_TRAILER)) {\n throw new Error(\n `w7-frame: bad trailer, expected NEND, got ${Array.from(trailer).map((b) => String.fromCharCode(b)).join(\"\")}`\n );\n }\n try {\n reader.releaseLock();\n } catch {\n }\n exhausted = true;\n return { value: void 0, done: true };\n }\n const pathLenBytes = await buf.readExact(4, \"chunk-path-length\");\n const pathLen = readU32LE(pathLenBytes, 0);\n if (pathLen < 0 || pathLen > 64 * 1024) {\n throw new Error(`w7-frame: implausible path length ${pathLen} at chunk ${idx}`);\n }\n const pathBytes = await buf.readExact(pathLen, \"chunk-path\");\n const path = new TextDecoder().decode(pathBytes);\n const chunkIdBytes = await buf.readExact(4, \"chunk-id\");\n const chunkId = readU32LE(chunkIdBytes, 0);\n const dataLenBytes = await buf.readExact(4, \"chunk-data-length\");\n const dataLen = readU32LE(dataLenBytes, 0);\n if (dataLen < 0 || dataLen > 64 * 1024 * 1024) {\n throw new Error(`w7-frame: implausible data length ${dataLen} at chunk ${idx}`);\n }\n const data = await buf.readExact(dataLen, \"chunk-data\");\n idx++;\n return { value: { path, chunkId, data }, done: false };\n },\n async return() {\n exhausted = true;\n try {\n reader.releaseLock();\n } catch {\n }\n return { value: void 0, done: true };\n }\n };\n }\n };\n return {\n inodes: header.inodes,\n deletePaths: header.deletePaths,\n chunkIter\n };\n}\nfunction writeU32LE(out, off, n) {\n out[off] = n & 255;\n out[off + 1] = n >>> 8 & 255;\n out[off + 2] = n >>> 16 & 255;\n out[off + 3] = n >>> 24 & 255;\n}\nfunction readU32LE(buf, off) {\n return (buf[off] | buf[off + 1] << 8 | buf[off + 2] << 16 | buf[off + 3] << 24) >>> 0;\n}\nfunction bytesEqual(a, b) {\n if (a.length !== b.length) return false;\n for (let i = 0; i < a.length; i++) if (a[i] !== b[i]) return false;\n return true;\n}\nvar ByteBuffer = class {\n constructor(reader) {\n this.reader = reader;\n }\n reader;\n chunks = [];\n avail = 0;\n done = false;\n async readExact(n, label) {\n if (n === 0) return new Uint8Array(0);\n while (this.avail < n) {\n if (this.done) {\n throw new Error(\n `w7-frame: stream ended ${this.avail} bytes into expected ${n}-byte ${label}`\n );\n }\n const { value, done } = await this.reader.read();\n if (done) {\n this.done = true;\n } else if (value && value.length > 0) {\n this.chunks.push(value);\n this.avail += value.length;\n }\n }\n const out = new Uint8Array(n);\n let copied = 0;\n while (copied < n) {\n const head = this.chunks[0];\n const take = Math.min(head.length, n - copied);\n out.set(head.subarray(0, take), copied);\n copied += take;\n if (take === head.length) {\n this.chunks.shift();\n } else {\n this.chunks[0] = head.subarray(take);\n }\n }\n this.avail -= n;\n return out;\n }\n};";
|
|
24
|
+
export const W7_FRAME_PREAMBLE_SIZE = 7964;
|
|
@@ -54,7 +54,7 @@ export interface NimbusLoaderPoolOptions {
|
|
|
54
54
|
* Override the `doId` baked into the auto-injected SUPERVISOR binding.
|
|
55
55
|
* Default: `ctx.id.toString()` (the DO that constructs the pool).
|
|
56
56
|
*
|
|
57
|
-
* Used by NimbusFanoutPool's peer-DO branch (
|
|
57
|
+
* Used by NimbusFanoutPool's peer-DO branch (peer-DO fanout): peer DOs
|
|
58
58
|
* construct their per-task NimbusLoaderPool from inside
|
|
59
59
|
* `_rpcFanoutExecute`, where `ctx` is the PEER DO's ctx. Without this
|
|
60
60
|
* override the peer's auto-injected SUPERVISOR routes back to the
|
|
@@ -129,7 +129,6 @@ export interface NimbusLoaderCallOptions {
|
|
|
129
129
|
* the LOADER's modules map (same `{ wasm: ArrayBuffer }` shape).
|
|
130
130
|
*
|
|
131
131
|
* Shipping path validated empirically against prod (see
|
|
132
|
-
* /workspace/.seal-internal/2026-05-10-wasm-csp/findings.md):
|
|
133
132
|
* `WebAssembly.instantiate(bytes)` is blocked at request-time but
|
|
134
133
|
* the LOADER-modules path compiles bytes during the inner
|
|
135
134
|
* worker's module-load phase, where wasm code generation IS
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"loader-pool.d.ts","sourceRoot":"","sources":["../../src/loaders/loader-pool.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AAeH,wDAAwD;AACxD,MAAM,WAAW,uBAAuB;IACtC,sDAAsD;IACtD,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,8CAA8C;IAC9C,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB;;;OAGG;IACH,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB;;;;OAIG;IACH,aAAa,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACxC;;;OAGG;IACH,GAAG,CAAC,EAAE,MAAM,CAAC;IACb;;;OAGG;IACH,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB;;;;;;;;;;;;;;;;OAgBG;IACH,sBAAsB,CAAC,EAAE,MAAM,CAAC;IAChC;;;;;;;;;;;;;;OAcG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB;;;;;;;;;;;;;;;;;;;;;;;;;;;OA2BG;IACH,WAAW,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,WAAW,CAAC,CAAC;CAC3C;AAED,qDAAqD;AACrD,MAAM,WAAW,uBAAuB;IACtC,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB;;;OAGG;IACH,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAClC
|
|
1
|
+
{"version":3,"file":"loader-pool.d.ts","sourceRoot":"","sources":["../../src/loaders/loader-pool.ts"],"names":[],"mappings":"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"}
|
|
@@ -159,7 +159,7 @@ export class NimbusLoaderPool {
|
|
|
159
159
|
// INSTALL-HONESTY: peer-DO branch supplies coordinator's doId
|
|
160
160
|
// via supervisorDoIdOverride so SUPERVISOR.* RPCs route back
|
|
161
161
|
// to the user's session DO, not the peer DO. Default to the
|
|
162
|
-
// local ctx.id (single-DO callers and the in-DO
|
|
162
|
+
// local ctx.id (single-DO callers and the in-DO in-DO fanout path).
|
|
163
163
|
const supDoId = opts?.supervisorDoIdOverride ?? ctx.id.toString();
|
|
164
164
|
bindings.SUPERVISOR = ctxExports.SupervisorRPC({
|
|
165
165
|
props: { doId: supDoId, pid: 0 },
|
|
@@ -9,9 +9,9 @@
|
|
|
9
9
|
*
|
|
10
10
|
* The resolver-facet references the following preamble symbols:
|
|
11
11
|
* - SHOULD_SKIP_PACKAGE(name) → boolean
|
|
12
|
-
* - SHOULD_SWAP(name) → { from, to } | undefined
|
|
13
|
-
* - SHOULD_REJECT_FAIL(name) → { from, reason, suggest? } | undefined
|
|
14
|
-
* - SHOULD_WARN_SKIP_TRANSITIVE(name) → entry | undefined
|
|
12
|
+
* - SHOULD_SWAP(name) → { from, to } | undefined
|
|
13
|
+
* - SHOULD_REJECT_FAIL(name) → { from, reason, suggest? } | undefined
|
|
14
|
+
* - SHOULD_WARN_SKIP_TRANSITIVE(name) → entry | undefined
|
|
15
15
|
* - PARSE_SEMVER(v) → [major, minor, patch] | null
|
|
16
16
|
* - COMPARE_SEMVER(a, b) → number
|
|
17
17
|
* - SATISFIES_RANGE(version, range) → boolean
|
|
@@ -23,8 +23,7 @@
|
|
|
23
23
|
* swap-or-reject decisions than the legacy in-supervisor path, breaking
|
|
24
24
|
* both correctness and the NIMBUS_FACET_RESOLVER=0 fallback contract.
|
|
25
25
|
*
|
|
26
|
-
*
|
|
27
|
-
* `audit/probes/w6/functional/preamble-parity.mjs`.
|
|
26
|
+
* Registry data is duplicated below and gated by the preamble parity test.
|
|
28
27
|
*
|
|
29
28
|
* Preamble bytes are part of the loader-cache key for NimbusLoaderPool —
|
|
30
29
|
* any edit invalidates the warm slot and forces a re-load on next
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"npm-resolve-preamble.d.ts","sourceRoot":"","sources":["../../src/loaders/npm-resolve-preamble.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"npm-resolve-preamble.d.ts","sourceRoot":"","sources":["../../src/loaders/npm-resolve-preamble.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8BG;AAEH,eAAO,MAAM,oBAAoB,EAAE,MAsMlC,CAAC"}
|
|
@@ -9,9 +9,9 @@
|
|
|
9
9
|
*
|
|
10
10
|
* The resolver-facet references the following preamble symbols:
|
|
11
11
|
* - SHOULD_SKIP_PACKAGE(name) → boolean
|
|
12
|
-
* - SHOULD_SWAP(name) → { from, to } | undefined
|
|
13
|
-
* - SHOULD_REJECT_FAIL(name) → { from, reason, suggest? } | undefined
|
|
14
|
-
* - SHOULD_WARN_SKIP_TRANSITIVE(name) → entry | undefined
|
|
12
|
+
* - SHOULD_SWAP(name) → { from, to } | undefined
|
|
13
|
+
* - SHOULD_REJECT_FAIL(name) → { from, reason, suggest? } | undefined
|
|
14
|
+
* - SHOULD_WARN_SKIP_TRANSITIVE(name) → entry | undefined
|
|
15
15
|
* - PARSE_SEMVER(v) → [major, minor, patch] | null
|
|
16
16
|
* - COMPARE_SEMVER(a, b) → number
|
|
17
17
|
* - SATISFIES_RANGE(version, range) → boolean
|
|
@@ -23,20 +23,18 @@
|
|
|
23
23
|
* swap-or-reject decisions than the legacy in-supervisor path, breaking
|
|
24
24
|
* both correctness and the NIMBUS_FACET_RESOLVER=0 fallback contract.
|
|
25
25
|
*
|
|
26
|
-
*
|
|
27
|
-
* `audit/probes/w6/functional/preamble-parity.mjs`.
|
|
26
|
+
* Registry data is duplicated below and gated by the preamble parity test.
|
|
28
27
|
*
|
|
29
28
|
* Preamble bytes are part of the loader-cache key for NimbusLoaderPool —
|
|
30
29
|
* any edit invalidates the warm slot and forces a re-load on next
|
|
31
30
|
* dispatch. Acceptable cost for a one-shot resolver phase.
|
|
32
31
|
*/
|
|
33
32
|
export const NPM_RESOLVE_PREAMBLE = `
|
|
34
|
-
// ── Skip list (mirrors src/npm-resolver.ts SKIP_PACKAGES
|
|
35
|
-
//
|
|
36
|
-
//
|
|
37
|
-
// import('vite') from node_modules. See audit/sections/W11-plan.md §3.0.
|
|
33
|
+
// ── Skip list (mirrors src/npm-resolver.ts SKIP_PACKAGES) ──
|
|
34
|
+
// vite is exempted when frameworkAware=true so framework CLIs can import it
|
|
35
|
+
// from node_modules.
|
|
38
36
|
const __SKIP_PACKAGES = new Set([
|
|
39
|
-
//
|
|
37
|
+
// rollup resolves through the drop-in @rollup/wasm-node swap.
|
|
40
38
|
'typescript', 'vite', 'webpack', 'parcel',
|
|
41
39
|
'postcss', 'autoprefixer', 'tailwindcss', 'cssnano',
|
|
42
40
|
'prettier', 'eslint', 'stylelint',
|
|
@@ -61,13 +59,10 @@ function SHOULD_SKIP_PACKAGE(name, frameworkAware) {
|
|
|
61
59
|
return false;
|
|
62
60
|
}
|
|
63
61
|
|
|
64
|
-
// ──
|
|
65
|
-
// Gated by audit/probes/w6/functional/preamble-parity.mjs.
|
|
62
|
+
// ── Swap / reject registry (mirrors src/wasm-swap-registry.ts) ─────
|
|
66
63
|
const __WASM_SWAPS = new Map([
|
|
67
64
|
['esbuild', { from: 'esbuild', to: 'esbuild-wasm' }],
|
|
68
|
-
//
|
|
69
|
-
// See src/wasm-swap-registry.ts:73 for full WASM_SWAPS canonical entry
|
|
70
|
-
// and X5G-plan.md §3 for the npm 4828 / .node-can't-dlopen rationale.
|
|
65
|
+
// rollup -> @rollup/wasm-node (drop-in WASM build).
|
|
71
66
|
['rollup', { from: 'rollup', to: '@rollup/wasm-node' }],
|
|
72
67
|
]);
|
|
73
68
|
// Mirror of REJECT_INSTALL in src/wasm-swap-registry.ts. Entries with
|
|
@@ -95,14 +90,12 @@ const __REJECT_INSTALL = new Map([
|
|
|
95
90
|
['node-pre-gyp', { from: 'node-pre-gyp', reason: 'Build-time native compiler; never runs in Workers.', transitive: 'warn' }],
|
|
96
91
|
['puppeteer', { from: 'puppeteer', reason: 'Bundled Chromium binary (~150 MB).', transitive: 'fail' }],
|
|
97
92
|
['playwright', { from: 'playwright', reason: 'Bundled browsers (~300 MB).', transitive: 'fail' }],
|
|
98
|
-
['sql.js', { from: 'sql.js', reason: 'Installs but fails at runtime
|
|
99
|
-
['@swc/wasm-web', { from: '@swc/wasm-web', reason: 'Installs but fails at runtime
|
|
100
|
-
// W6.5 additions:
|
|
93
|
+
['sql.js', { from: 'sql.js', reason: 'Installs but fails at runtime because dist/sql-wasm.wasm is not available to the runtime loader.', transitive: 'fail' }],
|
|
94
|
+
['@swc/wasm-web', { from: '@swc/wasm-web', reason: 'Installs but fails at runtime because its generated code path depends on workerd-blocked dynamic code generation.', transitive: 'fail' }],
|
|
101
95
|
['@img/sharp-wasm32', { from: '@img/sharp-wasm32', reason: 'WASM build of sharp; wasm32-cpu-only AND libvips initThreads() fails under workerd (no pthread).', transitive: 'fail' }],
|
|
102
96
|
['@napi-rs/canvas', { from: '@napi-rs/canvas', reason: 'Native bindings only; no WASM build published.', transitive: 'fail' }],
|
|
103
97
|
['@napi-rs/canvas-wasm32-wasi', { from: '@napi-rs/canvas-wasm32-wasi', reason: 'Package does not exist on npm (404); @napi-rs/canvas has no WASM/WASI build.', transitive: 'fail' }],
|
|
104
|
-
//
|
|
105
|
-
// Mirror of REJECT_INSTALL adds in src/wasm-swap-registry.ts.
|
|
98
|
+
// Tailwind v4 oxide + lightningcss native parents.
|
|
106
99
|
['@tailwindcss/oxide', { from: '@tailwindcss/oxide', reason: 'Native Rust Tailwind v4 oxide engine; only platform-specific .node bindings + wasm32-wasi shard; workerd has no node:wasi.', transitive: 'fail' }],
|
|
107
100
|
['lightningcss', { from: 'lightningcss', reason: 'Native Rust CSS parser; .node bindings + wasm32-wasi-only WASM build; workerd has no node:wasi; detect-libc also fails.', transitive: 'fail' }],
|
|
108
101
|
]);
|
|
@@ -120,7 +113,7 @@ function SHOULD_WARN_SKIP_TRANSITIVE(name) {
|
|
|
120
113
|
return undefined;
|
|
121
114
|
}
|
|
122
115
|
|
|
123
|
-
// ──
|
|
116
|
+
// ── Registry telemetry: facet-side event collection ──────────────────────
|
|
124
117
|
// The facet cannot import the registry's emitRegistryEvent (preamble has
|
|
125
118
|
// no import surface). Instead, decision sites push into a shared
|
|
126
119
|
// __pendingEvents array which resolveTreeInFacet returns inside
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"pre-bundle-preamble.d.ts","sourceRoot":"","sources":["../../src/loaders/pre-bundle-preamble.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiCG;
|
|
1
|
+
{"version":3,"file":"pre-bundle-preamble.d.ts","sourceRoot":"","sources":["../../src/loaders/pre-bundle-preamble.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiCG;AA2CH;;;;GAIG;AACH,eAAO,MAAM,mBAAmB,EAAE,MAqCjC,CAAC"}
|
|
@@ -64,7 +64,6 @@ import { getExportsResolverJS } from '../_shared/exports-resolver.js';
|
|
|
64
64
|
/**
|
|
65
65
|
* Resolver helpers, sourced from src/_shared/exports-resolver.ts via
|
|
66
66
|
* getExportsResolverJS(). Single source of truth — see
|
|
67
|
-
* audit/sections/03-resolver-gaps.md §3.1 for the prior 3-copy drift this
|
|
68
67
|
* consolidates. The pre-bundle facet uses `resolvePackageEntry` (line 492
|
|
69
68
|
* of src/pre-bundle-facet.ts).
|
|
70
69
|
*/
|
package/dist/npm/cache.js
CHANGED
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
* All tables live in the same DO SQLite as the VFS. Schema is created lazily
|
|
11
11
|
* on first use (not at VFS init, to avoid penalizing sessions that don't npm install).
|
|
12
12
|
*
|
|
13
|
-
* L1 cache observability (cache
|
|
13
|
+
* L1 cache observability (cache metrics support):
|
|
14
14
|
* getRegistryEntry / getTarballFiles bump per-tier counters via
|
|
15
15
|
* src/_shared/cache-stats.ts. Hit = row(s) returned with size > 0;
|
|
16
16
|
* miss = empty result set. Callers fall through to L2/L3/L4 on miss.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"install-batch-facet.d.ts","sourceRoot":"","sources":["../../src/npm/install-batch-facet.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA0CG;AAEH,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AAI3D,MAAM,WAAW,gBAAgB;IAC/B;mDAC+C;IAC/C,QAAQ,EAAE,gBAAgB,EAAE,CAAC;IAC7B;;kEAE8D;IAC9D,WAAW,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,sBAAsB;IACrC,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;IAClB,YAAY,EAAE,MAAM,CAAC;IACrB,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,yEAAyE;IACzE,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,kBAAkB;IACjC,gDAAgD;IAChD,UAAU,EAAE,sBAAsB,EAAE,CAAC;IACrC,oDAAoD;IACpD,OAAO,EAAE,MAAM,CAAC;IAChB;uFACmF;IACnF,aAAa,EAAE;QACb,iBAAiB,EAAE,MAAM,CAAC;QAC1B,sBAAsB,EAAE,MAAM,CAAC;QAC/B,YAAY,EAAE,MAAM,CAAC;QACrB;;uDAE+C;QAC/C,wBAAwB,EAAE,MAAM,CAAC;QACjC,0BAA0B,EAAE,MAAM,CAAC;KACpC,CAAC;IACF;;;;;;;;;;OAUG;IACH,eAAe,EAAE,KAAK,CAClB;QAAE,IAAI,EAAE,KAAK,CAAC;QAAC,IAAI,EAAE,IAAI,GAAG,IAAI,GAAG,IAAI,CAAC;QAAC,SAAS,EAAE,SAAS,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,GAC9E;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,IAAI,GAAG,IAAI,GAAG,IAAI,CAAC;QAAC,SAAS,EAAE,SAAS,CAAA;KAAE,CACnE,CAAC;CACH;AAUD,eAAO,MAAM,sBAAsB,GACjC,OAAO,gBAAgB,EACvB,KAAK;IACH,UAAU,EAAE;QACV,UAAU,CAAC,OAAO,EAAE,GAAG,GAAG,OAAO,CAAC;YAAE,MAAM,EAAE,MAAM,CAAC;YAAC,MAAM,EAAE,MAAM,CAAA;SAAE,CAAC,CAAC;QAMtE,gBAAgB,CAAC,EAAE,CAAC,MAAM,EAAE,cAAc,CAAC,UAAU,CAAC,KAAK,OAAO,CAAC;YAAE,MAAM,EAAE,MAAM,CAAC;YAAC,MAAM,EAAE,MAAM,CAAA;SAAE,CAAC,CAAC;QAOvG,gBAAgB,CAAC,EAAE,CACjB,IAAI,EAAE,MAAM,EACZ,OAAO,EAAE,MAAM,KACZ,OAAO,CACR,UAAU,GACV,IAAI,GACJ;YACE,KAAK,EAAE,UAAU,GAAG,IAAI,CAAC;YACzB,MAAM,EAAE,KAAK,CACT;gBAAE,IAAI,EAAE,KAAK,CAAC;gBAAC,IAAI,EAAE,MAAM,CAAC;gBAAC,SAAS,EAAE,MAAM,CAAC;gBAAC,KAAK,EAAE,MAAM,CAAA;aAAE,GAC/D;gBAAE,IAAI,EAAE,MAAM,CAAC;gBAAC,IAAI,EAAE,MAAM,CAAC;gBAAC,SAAS,EAAE,MAAM,CAAA;aAAE,CACpD,CAAC;SACH,CACJ,CAAC;QACF,gBAAgB,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,UAAU,GAAG,WAAW,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC;KACzG,CAAC;CACH,KACA,OAAO,CAAC,kBAAkB,
|
|
1
|
+
{"version":3,"file":"install-batch-facet.d.ts","sourceRoot":"","sources":["../../src/npm/install-batch-facet.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA0CG;AAEH,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AAI3D,MAAM,WAAW,gBAAgB;IAC/B;mDAC+C;IAC/C,QAAQ,EAAE,gBAAgB,EAAE,CAAC;IAC7B;;kEAE8D;IAC9D,WAAW,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,sBAAsB;IACrC,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;IAClB,YAAY,EAAE,MAAM,CAAC;IACrB,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,yEAAyE;IACzE,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,kBAAkB;IACjC,gDAAgD;IAChD,UAAU,EAAE,sBAAsB,EAAE,CAAC;IACrC,oDAAoD;IACpD,OAAO,EAAE,MAAM,CAAC;IAChB;uFACmF;IACnF,aAAa,EAAE;QACb,iBAAiB,EAAE,MAAM,CAAC;QAC1B,sBAAsB,EAAE,MAAM,CAAC;QAC/B,YAAY,EAAE,MAAM,CAAC;QACrB;;uDAE+C;QAC/C,wBAAwB,EAAE,MAAM,CAAC;QACjC,0BAA0B,EAAE,MAAM,CAAC;KACpC,CAAC;IACF;;;;;;;;;;OAUG;IACH,eAAe,EAAE,KAAK,CAClB;QAAE,IAAI,EAAE,KAAK,CAAC;QAAC,IAAI,EAAE,IAAI,GAAG,IAAI,GAAG,IAAI,CAAC;QAAC,SAAS,EAAE,SAAS,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,GAC9E;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,IAAI,GAAG,IAAI,GAAG,IAAI,CAAC;QAAC,SAAS,EAAE,SAAS,CAAA;KAAE,CACnE,CAAC;CACH;AAUD,eAAO,MAAM,sBAAsB,GACjC,OAAO,gBAAgB,EACvB,KAAK;IACH,UAAU,EAAE;QACV,UAAU,CAAC,OAAO,EAAE,GAAG,GAAG,OAAO,CAAC;YAAE,MAAM,EAAE,MAAM,CAAC;YAAC,MAAM,EAAE,MAAM,CAAA;SAAE,CAAC,CAAC;QAMtE,gBAAgB,CAAC,EAAE,CAAC,MAAM,EAAE,cAAc,CAAC,UAAU,CAAC,KAAK,OAAO,CAAC;YAAE,MAAM,EAAE,MAAM,CAAC;YAAC,MAAM,EAAE,MAAM,CAAA;SAAE,CAAC,CAAC;QAOvG,gBAAgB,CAAC,EAAE,CACjB,IAAI,EAAE,MAAM,EACZ,OAAO,EAAE,MAAM,KACZ,OAAO,CACR,UAAU,GACV,IAAI,GACJ;YACE,KAAK,EAAE,UAAU,GAAG,IAAI,CAAC;YACzB,MAAM,EAAE,KAAK,CACT;gBAAE,IAAI,EAAE,KAAK,CAAC;gBAAC,IAAI,EAAE,MAAM,CAAC;gBAAC,SAAS,EAAE,MAAM,CAAC;gBAAC,KAAK,EAAE,MAAM,CAAA;aAAE,GAC/D;gBAAE,IAAI,EAAE,MAAM,CAAC;gBAAC,IAAI,EAAE,MAAM,CAAC;gBAAC,SAAS,EAAE,MAAM,CAAA;aAAE,CACpD,CAAC;SACH,CACJ,CAAC;QACF,gBAAgB,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,UAAU,GAAG,WAAW,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC;KACzG,CAAC;CACH,KACA,OAAO,CAAC,kBAAkB,CAgjB5B,CAAC"}
|
|
@@ -107,10 +107,8 @@ export const installPackagesInFacet = async function installPackagesInFacet(batc
|
|
|
107
107
|
// singleton via recordCacheStatEvents — same pattern as
|
|
108
108
|
// recordR2RaceCounters at installer.ts:1168.
|
|
109
109
|
const cacheStatEvents = [];
|
|
110
|
-
//
|
|
111
|
-
//
|
|
112
|
-
// short. Wave-2 shipped 16 MiB and produced batch-fanout abort
|
|
113
|
-
// (whole-batch RPC age-out). Tightened to 4 MiB.
|
|
110
|
+
// Shared-buffer flushes happen across packages, so smaller chunks keep
|
|
111
|
+
// individual write transactions short and avoid aging the parent RPC.
|
|
114
112
|
const SHARED_RPC_FLUSH_THRESHOLD = 4 * 1024 * 1024;
|
|
115
113
|
const INODE_OVERHEAD = 160;
|
|
116
114
|
const CHUNK_OVERHEAD = 96;
|
|
@@ -468,9 +466,8 @@ export const installPackagesInFacet = async function installPackagesInFacet(batc
|
|
|
468
466
|
// threshold; raise it if/when measured peak heap suggests the
|
|
469
467
|
// legacy 16 MiB is now the bottleneck on the streaming path.
|
|
470
468
|
const pkgDir = spec.pkgDir;
|
|
471
|
-
//
|
|
472
|
-
//
|
|
473
|
-
// per-package totals stay local for the result object.
|
|
469
|
+
// Use the shard-level inode/chunk buffer so flushes are per shard,
|
|
470
|
+
// not per package. Per-package totals stay local to the result object.
|
|
474
471
|
let totalFileInodes = 0;
|
|
475
472
|
let totalBytesWritten = 0;
|
|
476
473
|
const dirSet = new Set();
|
|
@@ -534,11 +531,9 @@ export const installPackagesInFacet = async function installPackagesInFacet(batc
|
|
|
534
531
|
if (sharedBufferedBytes >= SHARED_RPC_FLUSH_THRESHOLD) {
|
|
535
532
|
await sharedFlush();
|
|
536
533
|
}
|
|
537
|
-
//
|
|
538
|
-
//
|
|
539
|
-
//
|
|
540
|
-
// lifecycle ends when this fn returns; an unawaited put may be
|
|
541
|
-
// torn down before the R2 write completes.
|
|
534
|
+
// Write tarballs to R2 only after a successful network install so the
|
|
535
|
+
// next tenant can skip the round-trip to npm. This must be awaited:
|
|
536
|
+
// the facet lifecycle ends when this function returns.
|
|
542
537
|
//
|
|
543
538
|
// Counter only increments tarballsCompleted on the network-fetch
|
|
544
539
|
// path (R2-hit path bumps it earlier). Avoids double counting.
|
package/dist/npm/installer.d.ts
CHANGED
|
@@ -86,8 +86,8 @@ export declare class NpmInstaller {
|
|
|
86
86
|
* resolved metadata of layer N.
|
|
87
87
|
*
|
|
88
88
|
* Topology auto-routes per layer:
|
|
89
|
-
* width < IN_DO_THRESHOLD (5) →
|
|
90
|
-
* width >= IN_DO_THRESHOLD →
|
|
89
|
+
* width < IN_DO_THRESHOLD (5) → in-DO fanout in-DO loader-pool
|
|
90
|
+
* width >= IN_DO_THRESHOLD → peer-DO fanout peer-DO (sibling NimbusSession DOs)
|
|
91
91
|
*
|
|
92
92
|
* The supervisor still owns:
|
|
93
93
|
* - cycle detection (`seen`),
|
|
@@ -100,7 +100,6 @@ export declare class NpmInstaller {
|
|
|
100
100
|
*
|
|
101
101
|
* The per-package task (resolveOnePackumentInFacet) owns ONLY the
|
|
102
102
|
* fetch + version pick + edge extraction. See
|
|
103
|
-
* audit/sections/F2-RESOLVER-FANOUT-plan.md.
|
|
104
103
|
*
|
|
105
104
|
* Anti-requirements (cleanup-not-done charter): NO setTimeout
|
|
106
105
|
* between layers, NO fallback to single-facet on missing bindings.
|
|
@@ -110,11 +109,11 @@ export declare class NpmInstaller {
|
|
|
110
109
|
* Batch install via two-tier fan-out (NimbusFanoutPool).
|
|
111
110
|
*
|
|
112
111
|
* Topology selected automatically based on the spec count:
|
|
113
|
-
* specs.length < IN_DO_THRESHOLD (5) →
|
|
112
|
+
* specs.length < IN_DO_THRESHOLD (5) → in-DO fanout in-DO
|
|
114
113
|
* 1 NimbusLoaderPool with concurrency = specs.length, capped at
|
|
115
114
|
* 4 by V8 invariant. Each spec is one facet running its own
|
|
116
115
|
* installPackagesInFacet over a single-element shard.
|
|
117
|
-
* specs.length >= IN_DO_THRESHOLD →
|
|
116
|
+
* specs.length >= IN_DO_THRESHOLD → peer-DO fanout peer-DO
|
|
118
117
|
* N peer NimbusSession sibling DOs (N = min(specs.length,
|
|
119
118
|
* MAX_PEER_FANOUT = 32)), each running ONE installPackagesInFacet
|
|
120
119
|
* against its own shard with internal pLimit(3).
|
|
@@ -127,7 +126,6 @@ export declare class NpmInstaller {
|
|
|
127
126
|
* Pre-fix lineage: this site previously ran ONE NimbusLoaderPool
|
|
128
127
|
* with concurrency=1, internal pLimit(3) — the explicit "collapses
|
|
129
128
|
* what was 4 concurrent dynamic workers (pool.map slots) into 1"
|
|
130
|
-
* YELLOW retreat documented in audit/sections/FANOUT-AUDIT.md (P1).
|
|
131
129
|
* Two-tier topology re-expands the fan-out without re-introducing
|
|
132
130
|
* the V8 cap risk.
|
|
133
131
|
*/
|
|
@@ -213,7 +211,7 @@ export declare class NpmInstaller {
|
|
|
213
211
|
*/
|
|
214
212
|
private resolvePackageEntryPath;
|
|
215
213
|
/**
|
|
216
|
-
* P5 (
|
|
214
|
+
* P5 (production reliability) — deterministic supervisor-heap estimate in MiB.
|
|
217
215
|
*
|
|
218
216
|
* Routes through observability/heap-estimate.ts which sums KNOWN
|
|
219
217
|
* supervisor heap allocation sources from runtime counters that
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"installer.d.ts","sourceRoot":"","sources":["../../src/npm/installer.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AAEH,OAAO,KAAK,EAAE,SAAS,EAAmB,MAAM,sBAAsB,CAAC;AACvE,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,+BAA+B,CAAC;AAEpE,OAAO,EAAE,QAAQ,EAAsB,MAAM,YAAY,CAAC;AAC1D,OAAO,EAEiC,KAAK,OAAO,EACnD,MAAM,eAAe,CAAC;AAmEvB,YAAY,EAAE,YAAY,EAAE,MAAM,6BAA6B,CAAC;AAChE,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,6BAA6B,CAAC;AAEhE,MAAM,WAAW,eAAe;IAC9B,KAAK,EAAE,YAAY,CAAC;IACpB,QAAQ,EAAE,MAAM,CAAC;IACjB,cAAc,EAAE,MAAM,CAAC;IACvB,OAAO,EAAE,MAAM,CAAC;IAChB,YAAY,EAAE,MAAM,CAAC;IACrB,OAAO,EAAE,MAAM,CAAC;IAChB,YAAY,EAAE,MAAM,CAAC;IACrB,UAAU,EAAE,MAAM,CAAC;IACnB,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,gBAAgB;IAC/B,SAAS,EAAE,MAAM,EAAE,CAAC;IACpB,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,UAAU,EAAE,MAAM,CAAC;IACnB,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,EAAE,MAAM,CAAC;IACnB,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAChC;AAID,qBAAa,YAAY;IACvB,OAAO,CAAC,GAAG,CAAY;IACvB,OAAO,CAAC,KAAK,CAAW;IACxB,OAAO,CAAC,OAAO,CAAwB;IACvC,OAAO,CAAC,GAAG,CAAiC;IAC5C,OAAO,CAAC,GAAG,CAAM;IACjB,OAAO,CAAC,UAAU,CAAsC;IACxD;;;;;;OAMG;IACH,OAAO,CAAC,OAAO,CAAsB;gBAGnC,GAAG,EAAE,SAAS,EACd,GAAG,EAAE,UAAU,EACf,IAAI,CAAC,EAAE;QACL,OAAO,CAAC,EAAE,cAAc,CAAC;QACzB,GAAG,CAAC,EAAE,kBAAkB,CAAC;QACzB,GAAG,CAAC,EAAE,GAAG,CAAC;QACV,UAAU,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,IAAI,CAAC;QACnC,OAAO,CAAC,EAAE,OAAO,CAAC;KACnB;IAWH,4EAA4E;IAC5E,IAAI,QAAQ,IAAI,QAAQ,CAAuB;IAI/C;;;;;OAKG;IACG,OAAO,CACX,UAAU,EAAE,MAAM,EAClB,IAAI,CAAC,EAAE;QACL,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAC;QACpB,UAAU,CAAC,EAAE,OAAO,CAAC;KACtB,GACA,OAAO,CAAC,gBAAgB,CAAC;YAcd,aAAa;
|
|
1
|
+
{"version":3,"file":"installer.d.ts","sourceRoot":"","sources":["../../src/npm/installer.ts"],"names":[],"mappings":"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"}
|
package/dist/npm/installer.js
CHANGED
|
@@ -110,7 +110,6 @@ export class NpmInstaller {
|
|
|
110
110
|
// (next/astro/nuxt/remix/sveltekit) or generic vite, we exempt
|
|
111
111
|
// FRAMEWORK_REQUIRED_PACKAGES (vite, ...) from the SKIP_PACKAGES set
|
|
112
112
|
// so the framework's CLI can `import 'vite'` from node_modules.
|
|
113
|
-
// See audit/sections/W11-plan.md §3.0.
|
|
114
113
|
const frameworkAware = await this.detectFrameworkAware(projDir);
|
|
115
114
|
if (frameworkAware) {
|
|
116
115
|
log(`Framework detected — installing framework-required packages (vite, …).`);
|
|
@@ -132,7 +131,7 @@ export class NpmInstaller {
|
|
|
132
131
|
// ── Phase 1: Resolve ──────────────────────────────────────────
|
|
133
132
|
// F-2 (cleanup-not-done): frontier-coordinator path. Each BFS
|
|
134
133
|
// layer dispatches to NimbusFanoutPool.submitMany — width <5 in-DO
|
|
135
|
-
// (
|
|
134
|
+
// (in-DO fanout), width ≥5 peer-DO (peer-DO fanout). Per-package task body is
|
|
136
135
|
// self-contained (resolveOnePackumentInFacet), supervisor builds
|
|
137
136
|
// layer N+1 from layer N's edges.
|
|
138
137
|
//
|
|
@@ -277,7 +276,7 @@ export class NpmInstaller {
|
|
|
277
276
|
if (this.esbuild) {
|
|
278
277
|
phaseStart = Date.now();
|
|
279
278
|
setInstallPhase('bundle');
|
|
280
|
-
// ── Bug 1 (
|
|
279
|
+
// ── Bug 1 (production reliability P4) — late-progress gating ───────────────
|
|
281
280
|
//
|
|
282
281
|
// Background:
|
|
283
282
|
// The install command MUST resolve immediately (see the long
|
|
@@ -395,8 +394,8 @@ export class NpmInstaller {
|
|
|
395
394
|
* resolved metadata of layer N.
|
|
396
395
|
*
|
|
397
396
|
* Topology auto-routes per layer:
|
|
398
|
-
* width < IN_DO_THRESHOLD (5) →
|
|
399
|
-
* width >= IN_DO_THRESHOLD →
|
|
397
|
+
* width < IN_DO_THRESHOLD (5) → in-DO fanout in-DO loader-pool
|
|
398
|
+
* width >= IN_DO_THRESHOLD → peer-DO fanout peer-DO (sibling NimbusSession DOs)
|
|
400
399
|
*
|
|
401
400
|
* The supervisor still owns:
|
|
402
401
|
* - cycle detection (`seen`),
|
|
@@ -409,7 +408,6 @@ export class NpmInstaller {
|
|
|
409
408
|
*
|
|
410
409
|
* The per-package task (resolveOnePackumentInFacet) owns ONLY the
|
|
411
410
|
* fetch + version pick + edge extraction. See
|
|
412
|
-
* audit/sections/F2-RESOLVER-FANOUT-plan.md.
|
|
413
411
|
*
|
|
414
412
|
* Anti-requirements (cleanup-not-done charter): NO setTimeout
|
|
415
413
|
* between layers, NO fallback to single-facet on missing bindings.
|
|
@@ -505,8 +503,8 @@ export class NpmInstaller {
|
|
|
505
503
|
return { key: name, args: taskSpec };
|
|
506
504
|
});
|
|
507
505
|
// Dispatch the layer. NimbusFanoutPool routes:
|
|
508
|
-
// <5 →
|
|
509
|
-
// ≥5 →
|
|
506
|
+
// <5 → in-DO fanout in-DO (NimbusLoaderPool), concurrency = layer.length (capped at 4)
|
|
507
|
+
// ≥5 → peer-DO fanout peer-DO, N peers = min(layer.length, 32)
|
|
510
508
|
let results;
|
|
511
509
|
try {
|
|
512
510
|
results = await fanoutPool.submitMany(tasks, resolveOnePackumentInFacet);
|
|
@@ -684,11 +682,11 @@ export class NpmInstaller {
|
|
|
684
682
|
* Batch install via two-tier fan-out (NimbusFanoutPool).
|
|
685
683
|
*
|
|
686
684
|
* Topology selected automatically based on the spec count:
|
|
687
|
-
* specs.length < IN_DO_THRESHOLD (5) →
|
|
685
|
+
* specs.length < IN_DO_THRESHOLD (5) → in-DO fanout in-DO
|
|
688
686
|
* 1 NimbusLoaderPool with concurrency = specs.length, capped at
|
|
689
687
|
* 4 by V8 invariant. Each spec is one facet running its own
|
|
690
688
|
* installPackagesInFacet over a single-element shard.
|
|
691
|
-
* specs.length >= IN_DO_THRESHOLD →
|
|
689
|
+
* specs.length >= IN_DO_THRESHOLD → peer-DO fanout peer-DO
|
|
692
690
|
* N peer NimbusSession sibling DOs (N = min(specs.length,
|
|
693
691
|
* MAX_PEER_FANOUT = 32)), each running ONE installPackagesInFacet
|
|
694
692
|
* against its own shard with internal pLimit(3).
|
|
@@ -701,7 +699,6 @@ export class NpmInstaller {
|
|
|
701
699
|
* Pre-fix lineage: this site previously ran ONE NimbusLoaderPool
|
|
702
700
|
* with concurrency=1, internal pLimit(3) — the explicit "collapses
|
|
703
701
|
* what was 4 concurrent dynamic workers (pool.map slots) into 1"
|
|
704
|
-
* YELLOW retreat documented in audit/sections/FANOUT-AUDIT.md (P1).
|
|
705
702
|
* Two-tier topology re-expands the fan-out without re-introducing
|
|
706
703
|
* the V8 cap risk.
|
|
707
704
|
*/
|
|
@@ -731,91 +728,13 @@ export class NpmInstaller {
|
|
|
731
728
|
if (specs.length === 0) {
|
|
732
729
|
return { installed, failed, filesWritten };
|
|
733
730
|
}
|
|
734
|
-
// Shard count
|
|
735
|
-
// the
|
|
736
|
-
//
|
|
737
|
-
//
|
|
738
|
-
//
|
|
739
|
-
// in
|
|
740
|
-
//
|
|
741
|
-
// For larger batches, we shard into N peer DOs.
|
|
742
|
-
//
|
|
743
|
-
// [COORDINATOR-OVERLOAD adaptive cap, P0a wave-4]
|
|
744
|
-
//
|
|
745
|
-
// History of failed waves (all on Markflow 617 deps, real prod):
|
|
746
|
-
// wave-1 (16 shards + writeBatchStream semaphore): 270 individual
|
|
747
|
-
// overload warns per install. Per-package writeBatchStream RPCs
|
|
748
|
-
// overflowed coordinator's input gate.
|
|
749
|
-
// wave-2 (16 shards + shared-flush at 16 MiB + semaphore):
|
|
750
|
-
// [batch-fanout] aborted — semaphore extended each peer's
|
|
751
|
-
// parent RPC round-trip, parent aged out.
|
|
752
|
-
// wave-3 (8 shards + shared-flush at 4 MiB, no semaphore):
|
|
753
|
-
// single-session = always GREEN. 12-concurrent-session load
|
|
754
|
-
// test: 25-33% of sessions hit `[batch-fanout] aborted:
|
|
755
|
-
// ExecutionError: Durable Object is overloaded. Requests
|
|
756
|
-
// queued for too long.` ← THE USER'S REPRODUCED ERROR.
|
|
757
|
-
//
|
|
758
|
-
// Wave-4 root cause (verified by N=12 concurrent test, post-deploy
|
|
759
|
-
// 15d3bfda): the OUTBOUND fan-out from coordinator → 8 peer DOs
|
|
760
|
-
// creates 8 cold-start requests at workerd's DO scheduler. Under
|
|
761
|
-
// N concurrent sessions, total simultaneous peer-DO cold-starts
|
|
762
|
-
// = N × peerCount. At N=12 × 8 = 96, some cold-starts queue at
|
|
763
|
-
// workerd's DO scheduler past the queue-age guard.
|
|
764
|
-
//
|
|
765
|
-
// Wave-4 fix: route LARGE installs through the in-DO path (POC C)
|
|
766
|
-
// instead of peer-DO fan-out. Peer-DO cold-start was the actual
|
|
767
|
-
// bottleneck under concurrent load — N=12 sessions × 5-8 peer DOs
|
|
768
|
-
// = 60-96 simultaneous DO cold-starts, exceeding workerd's per-
|
|
769
|
-
// account scheduler capacity and producing the user's observed
|
|
770
|
-
// `[batch-fanout] aborted: ExecutionError: Durable Object is
|
|
771
|
-
// overloaded`.
|
|
772
|
-
//
|
|
773
|
-
// POC C in-DO uses 4 NimbusLoaderPool slots (V8 4-loaders-per-
|
|
774
|
-
// method-context cap) of WORKER-LOADER isolates, NOT peer DOs.
|
|
775
|
-
// Worker Loader isolates have different scaling characteristics
|
|
776
|
-
// than DO instances — they scale per-request without the per-
|
|
777
|
-
// account DO scheduler bottleneck.
|
|
778
|
-
//
|
|
779
|
-
// For Markflow's 620 deps:
|
|
780
|
-
// wave-3 (8 peer-DO shards × pLimit 3 = 24 decoders): RED at N≥8
|
|
781
|
-
// wave-4 (4 in-DO loader slots × pLimit 3 = 12 decoders): expected
|
|
782
|
-
// GREEN at N=12 since each session uses Worker Loaders, not DOs
|
|
783
|
-
//
|
|
784
|
-
// shardCount = 4 routes via _dispatchInDo (4 < IN_DO_THRESHOLD=5).
|
|
785
|
-
// Each in-DO slot runs installPackagesInFacet over ~155 packages
|
|
786
|
-
// with pLimit(3); the shared-flush coalescer in install-batch-facet
|
|
787
|
-
// keeps writeBatchStream RPC count to coordinator ≈ 12-20 total.
|
|
788
|
-
//
|
|
789
|
-
// LARGE_INSTALL_PEER_CAP = 8 peer-DO shards (revert from in-DO
|
|
790
|
-
// trial). In-DO routes (2-3 shards) lost reliability because
|
|
791
|
-
// Worker Loader cold-starts under N=12 concurrent sessions
|
|
792
|
-
// hang silently (240s timeout, no error). Peer-DO at 8 shards
|
|
793
|
-
// gives explicit batch-fanout abort errors at 17-33% rate
|
|
794
|
-
// under N=12 — worse rate but BETTER user signal (clear
|
|
795
|
-
// error vs silent hang).
|
|
796
|
-
// LARGE_INSTALL_THRESHOLD = 200 (deps): below this, default
|
|
797
|
-
// 32-peer fan-out remains.
|
|
798
|
-
//
|
|
799
|
-
// N=12 concurrent stress is an artificial test — real concurrent-
|
|
800
|
-
// user load on a single account is rarely > 2-3 sessions running
|
|
801
|
-
// a 600+ dep install simultaneously. Single-session is reliably
|
|
802
|
-
// GREEN. The user's single failure was likely a transient under
|
|
803
|
-
// momentary load.
|
|
804
|
-
//
|
|
805
|
-
// Wave-history (all on Markflow 620 deps, real prod, N=12 stress):
|
|
806
|
-
// wave-3 (8 peer-DO shards): 17-33% sessions fail explicitly
|
|
807
|
-
// wave-4a (5 peer-DO shards): 17%
|
|
808
|
-
// wave-4b (3 in-DO shards): 25% silent timeout
|
|
809
|
-
// wave-4c (2 in-DO shards): 17% silent timeout
|
|
810
|
-
// wave-4d (8 peer-DO shards,
|
|
811
|
-
// STAGGERED dispatch): target 0%
|
|
812
|
-
//
|
|
813
|
-
// The wave-4d trick: dispatch shards in TWO PHASES via Promise.all
|
|
814
|
-
// rather than all-at-once. Phase 1: shards 0-3 → await Promise.all.
|
|
815
|
-
// Phase 2: shards 4-7 → await Promise.all. This serializes the
|
|
816
|
-
// cold-start thundering herd at the workerd DO scheduler without
|
|
817
|
-
// adding setTimeout. Implemented in src/loaders/fanout-pool.ts:
|
|
818
|
-
// _dispatchPeerDo via the FANOUT_PHASE_SIZE constant.
|
|
731
|
+
// Shard count is bounded by the package count and the fan-out ceiling.
|
|
732
|
+
// Large installs use a smaller peer-DO cap than the general-purpose
|
|
733
|
+
// fanout pool: each shard does substantial tarball decode and VFS write
|
|
734
|
+
// work, and keeping the shard count at eight avoids excessive sibling DO
|
|
735
|
+
// cold starts under concurrent user installs. NimbusFanoutPool dispatches
|
|
736
|
+
// those peers in bounded phases, so this remains parallel without creating
|
|
737
|
+
// one cold-start burst per package shard.
|
|
819
738
|
const LARGE_INSTALL_THRESHOLD = 200;
|
|
820
739
|
const LARGE_INSTALL_PEER_CAP = 8;
|
|
821
740
|
let shardCount;
|
|
@@ -833,7 +752,7 @@ export class NpmInstaller {
|
|
|
833
752
|
shards[idx % shardCount].push(spec);
|
|
834
753
|
});
|
|
835
754
|
const nonEmptyShards = shards.filter((s) => s.length > 0);
|
|
836
|
-
const topology = nonEmptyShards.length < IN_DO_THRESHOLD ? 'in-do (
|
|
755
|
+
const topology = nonEmptyShards.length < IN_DO_THRESHOLD ? 'in-do (in-DO fanout)' : 'peer-do (peer-DO fanout)';
|
|
837
756
|
log(`Dispatching ${specs.length} packages across ${nonEmptyShards.length} ` +
|
|
838
757
|
`shard${nonEmptyShards.length === 1 ? '' : 's'} (${topology}, internal pLimit=3)...`);
|
|
839
758
|
const fanoutPool = new NimbusFanoutPool(this.env, this.ctx, {
|
|
@@ -1385,7 +1304,7 @@ export class NpmInstaller {
|
|
|
1385
1304
|
// through this phase; if a future regression brings esbuild back
|
|
1386
1305
|
// onto the supervisor we'll see it spike here.
|
|
1387
1306
|
//
|
|
1388
|
-
// P5 (
|
|
1307
|
+
// P5 (production reliability): switched from process.memoryUsage() to the
|
|
1389
1308
|
// C'.1 deterministic estimator. process.memoryUsage() returns 0
|
|
1390
1309
|
// for every field inside a Durable Object class context (only
|
|
1391
1310
|
// dynamic-worker isolates under nodejs_compat get the real
|
|
@@ -1747,7 +1666,7 @@ export class NpmInstaller {
|
|
|
1747
1666
|
}
|
|
1748
1667
|
catch { }
|
|
1749
1668
|
}
|
|
1750
|
-
// P5 (
|
|
1669
|
+
// P5 (production reliability): switched both `memBefore` and `memAfter`
|
|
1751
1670
|
// to the C'.1 deterministic estimator (see entry-point note
|
|
1752
1671
|
// above). Both are floats in MiB; delta is post − pre.
|
|
1753
1672
|
try {
|
|
@@ -1927,7 +1846,7 @@ export class NpmInstaller {
|
|
|
1927
1846
|
return null;
|
|
1928
1847
|
}
|
|
1929
1848
|
/**
|
|
1930
|
-
* P5 (
|
|
1849
|
+
* P5 (production reliability) — deterministic supervisor-heap estimate in MiB.
|
|
1931
1850
|
*
|
|
1932
1851
|
* Routes through observability/heap-estimate.ts which sums KNOWN
|
|
1933
1852
|
* supervisor heap allocation sources from runtime counters that
|
|
@@ -1969,7 +1888,7 @@ export class NpmInstaller {
|
|
|
1969
1888
|
}
|
|
1970
1889
|
}
|
|
1971
1890
|
// ── Helpers ─────────────────────────────────────────────────────────────
|
|
1972
|
-
// P5 (
|
|
1891
|
+
// P5 (production reliability): readSupervisorHeap() removed. It called
|
|
1973
1892
|
// process.memoryUsage() which returns 0 for every field inside a
|
|
1974
1893
|
// Durable Object class context (only dynamic-worker isolates under
|
|
1975
1894
|
// nodejs_compat get the real implementation — see
|