@nimbus-sh/worker 0.10.0 → 0.11.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/NOTICE.md +5 -0
- package/README.md +10 -0
- package/dist/_shared/session-router.d.ts +7 -0
- package/dist/_shared/session-router.d.ts.map +1 -1
- package/dist/_shared/session-router.js +7 -0
- package/dist/bindings/body.d.ts +6 -0
- package/dist/bindings/body.d.ts.map +1 -0
- package/dist/bindings/body.js +37 -0
- package/dist/bindings/kv.d.ts +0 -2
- package/dist/bindings/kv.d.ts.map +1 -1
- package/dist/bindings/kv.js +3 -42
- package/dist/bindings/r2.d.ts +0 -2
- package/dist/bindings/r2.d.ts.map +1 -1
- package/dist/bindings/r2.js +4 -44
- package/dist/esbuild-cli-artifact.generated.d.ts +18 -0
- package/dist/esbuild-cli-artifact.generated.d.ts.map +1 -0
- package/dist/esbuild-cli-artifact.generated.js +17 -0
- package/dist/facets/cirrus-real.d.ts.map +1 -1
- package/dist/facets/cirrus-real.js +9 -4
- package/dist/facets/compose.d.ts +11 -7
- package/dist/facets/compose.d.ts.map +1 -1
- package/dist/facets/compose.js +8 -38
- package/dist/facets/data-plan.d.ts +79 -0
- package/dist/facets/data-plan.d.ts.map +1 -0
- package/dist/facets/data-plan.js +477 -0
- package/dist/facets/esbuild-transform.d.ts +36 -10
- package/dist/facets/esbuild-transform.d.ts.map +1 -1
- package/dist/facets/esbuild-transform.js +216 -20
- package/dist/facets/exec-telemetry.d.ts +7 -3
- package/dist/facets/exec-telemetry.d.ts.map +1 -1
- package/dist/facets/manager.d.ts +179 -78
- package/dist/facets/manager.d.ts.map +1 -1
- package/dist/facets/manager.js +1221 -649
- package/dist/facets/opencode-staging.d.ts +0 -2
- package/dist/facets/opencode-staging.d.ts.map +1 -1
- package/dist/facets/opencode-staging.js +5 -11
- package/dist/facets/process.d.ts +4 -0
- package/dist/facets/process.d.ts.map +1 -1
- package/dist/facets/process.js +3 -0
- package/dist/facets/read-profile.d.ts +149 -0
- package/dist/facets/read-profile.d.ts.map +1 -0
- package/dist/facets/read-profile.js +483 -0
- package/dist/facets/resident-identity.d.ts +0 -1
- package/dist/facets/resident-identity.d.ts.map +1 -1
- package/dist/facets/resident-identity.js +0 -3
- package/dist/facets/wasm-swap-registry.d.ts +34 -25
- package/dist/facets/wasm-swap-registry.d.ts.map +1 -1
- package/dist/facets/wasm-swap-registry.js +62 -56
- package/dist/facets/ws-terminal.d.ts +4 -4
- package/dist/facets/ws-terminal.d.ts.map +1 -1
- package/dist/facets/ws-terminal.js +4 -5
- package/dist/git/commands.d.ts +16 -9
- package/dist/git/commands.d.ts.map +1 -1
- package/dist/git/commands.js +1818 -188
- package/dist/git/network-facet.d.ts +10 -2
- package/dist/git/network-facet.d.ts.map +1 -1
- package/dist/git/network-facet.js +62 -16
- package/dist/git/unified-diff.d.ts +74 -0
- package/dist/git/unified-diff.d.ts.map +1 -0
- package/dist/git/unified-diff.js +676 -0
- package/dist/git-bundle.generated.d.ts +7 -11
- package/dist/git-bundle.generated.d.ts.map +1 -1
- package/dist/git-bundle.generated.js +7 -11
- package/dist/hosted/commands.d.ts.map +1 -1
- package/dist/hosted/commands.js +62 -243
- package/dist/hosted/runtime.d.ts +19 -13
- package/dist/hosted/runtime.d.ts.map +1 -1
- package/dist/hosted/runtime.js +71 -14
- package/dist/hosted/services.d.ts +6 -7
- package/dist/hosted/services.d.ts.map +1 -1
- package/dist/hosted/services.js +10 -14
- package/dist/hosted/session.d.ts +165 -0
- package/dist/hosted/session.d.ts.map +1 -0
- package/dist/hosted/session.js +132 -0
- package/dist/loaders/generated-workers.d.ts +5 -2
- package/dist/loaders/generated-workers.d.ts.map +1 -1
- package/dist/loaders/generated-workers.js +6 -3
- package/dist/loaders/npm-resolve-preamble.d.ts.map +1 -1
- package/dist/loaders/npm-resolve-preamble.js +0 -27
- package/dist/node-shims-artifact.generated.d.ts +13 -4
- package/dist/node-shims-artifact.generated.d.ts.map +1 -1
- package/dist/node-shims-artifact.generated.js +16 -7
- package/dist/npm/bin-links.d.ts +3 -1
- package/dist/npm/bin-links.d.ts.map +1 -1
- package/dist/npm/bin-links.js +32 -8
- package/dist/npm/cache.d.ts +5 -0
- package/dist/npm/cache.d.ts.map +1 -1
- package/dist/npm/cache.js +13 -1
- package/dist/npm/install-batch-facet.d.ts +2 -2
- package/dist/npm/install-batch-facet.js +3 -3
- package/dist/npm/installer.d.ts +17 -1
- package/dist/npm/installer.d.ts.map +1 -1
- package/dist/npm/installer.js +159 -20
- package/dist/npm/package-lock.d.ts +32 -0
- package/dist/npm/package-lock.d.ts.map +1 -0
- package/dist/npm/package-lock.js +65 -0
- package/dist/npm/pre-bundle-facet.d.ts +1 -30
- package/dist/npm/pre-bundle-facet.d.ts.map +1 -1
- package/dist/npm/pre-bundle-facet.js +3 -5
- package/dist/npm/r2-cache.d.ts +2 -0
- package/dist/npm/r2-cache.d.ts.map +1 -1
- package/dist/npm/r2-cache.js +2 -0
- package/dist/npm/resolve-one-facet.d.ts.map +1 -1
- package/dist/npm/resolve-one-facet.js +14 -3
- package/dist/npm/resolver.d.ts +0 -7
- package/dist/npm/resolver.d.ts.map +1 -1
- package/dist/npm/resolver.js +0 -22
- package/dist/opencode-artifact.generated.js +2 -2
- package/dist/replica/routing.d.ts +2 -38
- package/dist/replica/routing.d.ts.map +1 -1
- package/dist/replica/routing.js +3 -55
- package/dist/router/index.d.ts.map +1 -1
- package/dist/router/index.js +15 -2
- package/dist/router/public-directory.d.ts +18 -0
- package/dist/router/public-directory.d.ts.map +1 -1
- package/dist/router/public-directory.js +1 -1
- package/dist/router/remote-api.d.ts +3 -1
- package/dist/router/remote-api.d.ts.map +1 -1
- package/dist/router/remote-api.js +42 -79
- package/dist/runtime/bash-repl.js +2 -2
- package/dist/runtime/bun-repl.d.ts.map +1 -1
- package/dist/runtime/bun-repl.js +2 -13
- package/dist/runtime/esbuild-wasm-bytes.d.ts +17 -5
- package/dist/runtime/esbuild-wasm-bytes.d.ts.map +1 -1
- package/dist/runtime/esbuild-wasm-bytes.js +43 -94
- package/dist/runtime/git-bundle-artifact.d.ts +17 -0
- package/dist/runtime/git-bundle-artifact.d.ts.map +1 -0
- package/dist/runtime/git-bundle-artifact.js +25 -0
- package/dist/runtime/node-repl.d.ts.map +1 -1
- package/dist/runtime/node-repl.js +2 -13
- package/dist/runtime/node-shims-artifact.d.ts +22 -23
- package/dist/runtime/node-shims-artifact.d.ts.map +1 -1
- package/dist/runtime/node-shims-artifact.js +48 -78
- package/dist/runtime/node-shims.d.ts.map +1 -1
- package/dist/runtime/node-shims.js +1567 -864
- package/dist/runtime/opencode-artifact.d.ts.map +1 -1
- package/dist/runtime/opencode-artifact.js +17 -53
- package/dist/runtime/opencode-facet-runner.d.ts +3 -6
- package/dist/runtime/opencode-facet-runner.d.ts.map +1 -1
- package/dist/runtime/opencode-facet-runner.js +45 -10
- package/dist/runtime/opentui-wasm-bytes.d.ts.map +1 -1
- package/dist/runtime/opentui-wasm-bytes.js +16 -49
- package/dist/runtime/package-manager.d.ts +0 -2
- package/dist/runtime/package-manager.d.ts.map +1 -1
- package/dist/runtime/package-manager.js +0 -3
- package/dist/runtime/python-repl.d.ts.map +1 -1
- package/dist/runtime/python-repl.js +2 -2
- package/dist/runtime/repl-session.d.ts +10 -0
- package/dist/runtime/repl-session.d.ts.map +1 -1
- package/dist/runtime/repl-session.js +7 -0
- package/dist/runtime/ruby-repl.d.ts.map +1 -1
- package/dist/runtime/ruby-repl.js +2 -2
- package/dist/runtime/ruby-resident.d.ts.map +1 -1
- package/dist/runtime/ruby-resident.js +36 -35
- package/dist/runtime/runtime-catalog.d.ts +10 -3
- package/dist/runtime/runtime-catalog.d.ts.map +1 -1
- package/dist/runtime/runtime-catalog.js +125 -15
- package/dist/runtime/sqlite-wasm-bytes.d.ts +4 -4
- package/dist/runtime/sqlite-wasm-bytes.d.ts.map +1 -1
- package/dist/runtime/sqlite-wasm-bytes.js +21 -57
- package/dist/runtime/staged-source.d.ts +67 -0
- package/dist/runtime/staged-source.d.ts.map +1 -0
- package/dist/runtime/staged-source.js +113 -0
- package/dist/runtime/wasi/preamble.d.ts.map +1 -1
- package/dist/runtime/wasi/preamble.js +0 -24
- package/dist/runtime-catalog.generated.js +1 -1
- package/dist/session/agent.d.ts +14 -2
- package/dist/session/agent.d.ts.map +1 -1
- package/dist/session/agent.js +57 -19
- package/dist/session/ai.d.ts +0 -11
- package/dist/session/ai.d.ts.map +1 -1
- package/dist/session/ai.js +0 -4
- package/dist/session/fs-watch.d.ts +0 -11
- package/dist/session/fs-watch.d.ts.map +1 -1
- package/dist/session/fs-watch.js +0 -21
- package/dist/session/hibernation.d.ts +34 -11
- package/dist/session/hibernation.d.ts.map +1 -1
- package/dist/session/hibernation.js +46 -29
- package/dist/session/init-phases.d.ts +1 -2
- package/dist/session/init-phases.d.ts.map +1 -1
- package/dist/session/init-phases.js +1 -2
- package/dist/session/init.d.ts.map +1 -1
- package/dist/session/init.js +7 -20
- package/dist/session/keys.d.ts +0 -3
- package/dist/session/keys.d.ts.map +1 -1
- package/dist/session/keys.js +0 -3
- package/dist/session/legacy-reset.d.ts +11 -0
- package/dist/session/legacy-reset.d.ts.map +1 -0
- package/dist/session/legacy-reset.js +16 -0
- package/dist/session/nimbus-session.d.ts +41 -15
- package/dist/session/nimbus-session.d.ts.map +1 -1
- package/dist/session/nimbus-session.js +64 -70
- package/dist/session/npm-install-port.d.ts.map +1 -1
- package/dist/session/npm-install-port.js +1 -0
- package/dist/session/programmatic.d.ts +13 -18
- package/dist/session/programmatic.d.ts.map +1 -1
- package/dist/session/programmatic.js +53 -39
- package/dist/session/replica-routes.d.ts +2 -3
- package/dist/session/replica-routes.d.ts.map +1 -1
- package/dist/session/replica-routes.js +3 -10
- package/dist/session/routes.d.ts.map +1 -1
- package/dist/session/routes.js +7 -10
- package/dist/session/rpc.d.ts +104 -20
- package/dist/session/rpc.d.ts.map +1 -1
- package/dist/session/rpc.js +184 -37
- package/dist/session/start-real-vite.js +2 -2
- package/dist/session/state-store.d.ts +1 -17
- package/dist/session/state-store.d.ts.map +1 -1
- package/dist/session/state-store.js +3 -53
- package/dist/session/supervisor-op.d.ts +7 -0
- package/dist/session/supervisor-op.d.ts.map +1 -1
- package/dist/session/supervisor-op.js +6 -1
- package/dist/session/supervisor-rpc.d.ts +104 -15
- package/dist/session/supervisor-rpc.d.ts.map +1 -1
- package/dist/session/supervisor-rpc.js +188 -71
- package/dist/session/vite-command.d.ts.map +1 -1
- package/dist/session/vite-command.js +17 -14
- package/dist/session/ws.d.ts.map +1 -1
- package/dist/session/ws.js +20 -8
- package/dist/shell/npm-bin-entrypoints.d.ts.map +1 -1
- package/dist/shell/npm-bin-entrypoints.js +30 -5
- package/dist/vfs/facet-resident-limits.d.ts +33 -0
- package/dist/vfs/facet-resident-limits.d.ts.map +1 -0
- package/dist/vfs/facet-resident-limits.js +33 -0
- package/dist/vfs/facet-resident-store.d.ts +2 -10
- package/dist/vfs/facet-resident-store.d.ts.map +1 -1
- package/dist/vfs/facet-resident-store.js +1594 -219
- package/dist/workspace-host.d.ts +2 -0
- package/dist/workspace-host.d.ts.map +1 -1
- package/dist/workspace-host.js +2 -0
- package/dist/wrangler/nimbus-wrangler.d.ts +0 -2
- package/dist/wrangler/nimbus-wrangler.d.ts.map +1 -1
- package/dist/wrangler/nimbus-wrangler.js +5 -22
- package/package.json +8 -7
- package/public/_assets/opencode/1.16.2/index-attach.js +2 -2
- package/public/_assets/runtime/esbuild-cli-c4fda380d52befc1.js +6892 -0
- package/public/_assets/runtime/git-de3e60c9f3ff006a.js +103 -0
- package/public/_assets/runtime/{node-shims-7b4dd7a76d95d21e.js → node-shims-06565b121555c194.js} +2089 -861
- package/public/_assets/runtime/resident-store-6ffb1939c53d982f.js +2264 -0
- package/public/_assets/runtime/vfs-write-ledger-e501e8fc793bc2c1.js +889 -0
- package/scripts/build-opencode-attach-entry.mjs +51 -1
- package/scripts/bundle-facet-workers.mjs +114 -3
- package/scripts/bundle-git.mjs +88 -27
- package/scripts/bundle-node-shims.mjs +72 -46
- package/scripts/bundle-runtime.mjs +18 -421
- package/scripts/cf-git-patch.mjs +137 -0
- package/scripts/patch-install-deps.mjs +49 -96
- package/scripts/runtime-specs.mjs +435 -0
- package/vendor/git-http.generated.d.ts +82 -0
- package/vendor/git-upstream.generated.d.ts +4378 -0
- package/vendor/git.LICENSE +7 -0
- package/vendor/git.generated.d.mts +21 -0
- package/vendor/git.generated.mjs +103 -0
- package/dist/replica/suspension.d.ts +0 -36
- package/dist/replica/suspension.d.ts.map +0 -1
- package/dist/replica/suspension.js +0 -49
- package/dist/runtime/static-server.d.ts +0 -3
- package/dist/runtime/static-server.d.ts.map +0 -1
- package/dist/runtime/static-server.js +0 -133
- package/scripts/clean-dist.mjs +0 -7
|
@@ -110,6 +110,56 @@ function stripEmbeddedModelsCatalog(pack) {
|
|
|
110
110
|
return pack;
|
|
111
111
|
}
|
|
112
112
|
|
|
113
|
+
const unicodeEscape = (code) => '\\u' + code.toString(16).padStart(4, '0');
|
|
114
|
+
|
|
115
|
+
/** One regex literal with every non-ASCII code unit written as `\uXXXX`; `\…` is an identity escape of `…`. */
|
|
116
|
+
function escapeRegexLiteral(literal) {
|
|
117
|
+
let out = '';
|
|
118
|
+
for (let i = 0; i < literal.length; i++) {
|
|
119
|
+
const code = literal.charCodeAt(i);
|
|
120
|
+
if (code === 0x5c && i + 1 < literal.length) {
|
|
121
|
+
const next = literal.charCodeAt(i + 1);
|
|
122
|
+
out += next > 0x7f ? unicodeEscape(next) : literal.slice(i, i + 2);
|
|
123
|
+
i++;
|
|
124
|
+
} else {
|
|
125
|
+
out += code > 0x7f ? unicodeEscape(code) : literal[i];
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
return out;
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
/**
|
|
132
|
+
* Make the attach entry pure ASCII. esbuild's default ASCII charset escapes
|
|
133
|
+
* every literal except regular expressions, so opencode's typographic-quote
|
|
134
|
+
* regexes (`/[‘’‚‛]/g`, `/…/g`) survive, and one character above U+00FF makes
|
|
135
|
+
* V8 hold the whole 14 MB source as a two-byte string: 29 MB in the session
|
|
136
|
+
* that assembles the facet's module map and again in the facet that runs it.
|
|
137
|
+
* Fails loud if non-ASCII remains anywhere else.
|
|
138
|
+
*/
|
|
139
|
+
function asciiOnlyAttachEntry(src) {
|
|
140
|
+
const acorn = require('acorn');
|
|
141
|
+
const parts = [];
|
|
142
|
+
let last = 0;
|
|
143
|
+
for (const token of acorn.tokenizer(src, { ecmaVersion: 'latest', sourceType: 'module' })) {
|
|
144
|
+
if (token.type !== acorn.tokTypes.regexp) continue;
|
|
145
|
+
const literal = src.slice(token.start, token.end);
|
|
146
|
+
if (!/[^\x00-\x7f]/.test(literal)) continue;
|
|
147
|
+
parts.push(src.slice(last, token.start), escapeRegexLiteral(literal));
|
|
148
|
+
last = token.end;
|
|
149
|
+
}
|
|
150
|
+
parts.push(src.slice(last));
|
|
151
|
+
const out = parts.join('');
|
|
152
|
+
const residual = out.search(/[^\x00-\x7f]/);
|
|
153
|
+
if (residual >= 0) {
|
|
154
|
+
throw new Error(
|
|
155
|
+
'[build-opencode-attach-entry] non-ASCII outside a regex literal at offset ' +
|
|
156
|
+
`${residual} (${JSON.stringify(out.slice(Math.max(0, residual - 40), residual + 10))}) — ` +
|
|
157
|
+
'escape it here, or the attach source is held as a two-byte string',
|
|
158
|
+
);
|
|
159
|
+
}
|
|
160
|
+
return out;
|
|
161
|
+
}
|
|
162
|
+
|
|
113
163
|
/**
|
|
114
164
|
* Build the attach entry text from in-memory sources.
|
|
115
165
|
* @param entry index.js source text.
|
|
@@ -178,7 +228,7 @@ export async function buildOpencodeAttachEntryFromSources(entry, packInput) {
|
|
|
178
228
|
},
|
|
179
229
|
],
|
|
180
230
|
});
|
|
181
|
-
const out = result.outputFiles[0].text;
|
|
231
|
+
const out = asciiOnlyAttachEntry(result.outputFiles[0].text);
|
|
182
232
|
const residual = [...out.matchAll(/import\(\s*["'](?:\.\/)?(chunk-[a-z0-9]+\.js)["']\s*\)/g)];
|
|
183
233
|
if (residual.length > 0) {
|
|
184
234
|
throw new Error(
|
|
@@ -39,18 +39,26 @@
|
|
|
39
39
|
* WASI_INSTANCE_BODY_SRC: string
|
|
40
40
|
* @nimbus-sh/core src/runtime/bash-runner.generated.ts — exports
|
|
41
41
|
* BASH_RUNNER_BODY_SRC: string
|
|
42
|
+
* public/_assets/runtime/esbuild-cli-<buildId>.js — the `esbuild` command's
|
|
43
|
+
* runner, which only the session's esbuild facet evaluates. Staged as an
|
|
44
|
+
* asset rather than a string in the Worker bundle, like the esbuild
|
|
45
|
+
* adapter and the node shims; src/esbuild-cli-artifact.generated.ts
|
|
46
|
+
* exports ESBUILD_CLI_ASSET_PATH, ESBUILD_CLI_BUILD_ID, ESBUILD_CLI_SHA256.
|
|
42
47
|
*
|
|
43
48
|
* Runs as a postinstall + predev + predeploy step via package.json.
|
|
44
49
|
*/
|
|
45
50
|
|
|
46
51
|
import { build } from 'esbuild';
|
|
47
|
-
import {
|
|
52
|
+
import { createHash } from 'node:crypto';
|
|
53
|
+
import { readFileSync, writeFileSync, mkdirSync, readdirSync, unlinkSync } from 'node:fs';
|
|
48
54
|
import { dirname, join } from 'node:path';
|
|
49
55
|
import { fileURLToPath, pathToFileURL } from 'node:url';
|
|
50
56
|
// core's own parser dependency, reached through the workspace hoist; the
|
|
51
57
|
// script runs under plain node at postinstall, so nothing here is TypeScript.
|
|
52
58
|
import { parse } from 'acorn';
|
|
53
59
|
|
|
60
|
+
import { resolvePackageDir } from './resolve-package-dir.mjs';
|
|
61
|
+
|
|
54
62
|
const __dirname = dirname(fileURLToPath(import.meta.url));
|
|
55
63
|
const root = join(__dirname, '..');
|
|
56
64
|
const coreRoot = join(root, '..', 'core');
|
|
@@ -298,6 +306,87 @@ async function bundleBashRunner() {
|
|
|
298
306
|
return src;
|
|
299
307
|
}
|
|
300
308
|
|
|
309
|
+
/**
|
|
310
|
+
* The `esbuild` command's runner: Go's own js/wasm glue from the installed
|
|
311
|
+
* esbuild-wasm (the package whose esbuild.wasm is staged to ASSETS, so the glue
|
|
312
|
+
* always matches the binary), wrapped so each run hands it its own global and
|
|
313
|
+
* `fs`, followed by the typed runner as an IIFE that installs
|
|
314
|
+
* globalThis.__esbuildCliRun. wasm_exec.js is spliced in verbatim, license
|
|
315
|
+
* header included.
|
|
316
|
+
*/
|
|
317
|
+
async function bundleEsbuildCli() {
|
|
318
|
+
const result = await build({
|
|
319
|
+
entryPoints: [join(coreRoot, 'src', 'runtime', 'esbuild-cli', 'preamble.ts')],
|
|
320
|
+
bundle: true,
|
|
321
|
+
format: 'iife',
|
|
322
|
+
target: 'esnext',
|
|
323
|
+
platform: 'neutral',
|
|
324
|
+
absWorkingDir: root,
|
|
325
|
+
write: false,
|
|
326
|
+
logLevel: 'warning',
|
|
327
|
+
legalComments: 'none',
|
|
328
|
+
});
|
|
329
|
+
if (!result.outputFiles || result.outputFiles.length === 0) {
|
|
330
|
+
throw new Error('[bundle-facet-workers/esbuild-cli] esbuild produced no output');
|
|
331
|
+
}
|
|
332
|
+
const runner = withoutComments(result.outputFiles[0].text);
|
|
333
|
+
if (!/^\s*globalThis\.__esbuildCliRun\s*=/m.test(runner)) {
|
|
334
|
+
throw new Error(
|
|
335
|
+
'[bundle-facet-workers/esbuild-cli] the bundle no longer assigns globalThis.__esbuildCliRun — ' +
|
|
336
|
+
'every esbuild command would fail inside the esbuild facet',
|
|
337
|
+
);
|
|
338
|
+
}
|
|
339
|
+
if (/^\s*(?:import|export)\b/m.test(runner)) {
|
|
340
|
+
throw new Error('[bundle-facet-workers/esbuild-cli] an import/export survived bundling');
|
|
341
|
+
}
|
|
342
|
+
const glue = readFileSync(join(resolvePackageDir('esbuild-wasm', { start: root }), 'wasm_exec.js'), 'utf8');
|
|
343
|
+
if (!/globalThis\.Go\s*=\s*class\b/.test(glue)) {
|
|
344
|
+
throw new Error('[bundle-facet-workers/esbuild-cli] esbuild-wasm/wasm_exec.js no longer defines globalThis.Go');
|
|
345
|
+
}
|
|
346
|
+
return `const __esbuildGoRuntime = function (globalThis, fs) {\n${glue}\nreturn globalThis.Go;\n};\n${runner}`;
|
|
347
|
+
}
|
|
348
|
+
|
|
349
|
+
/**
|
|
350
|
+
* Stage the esbuild CLI runner under public/_assets/runtime/, named by a
|
|
351
|
+
* prefix of its own digest so no cache layer can serve another build's bytes
|
|
352
|
+
* under its name, and pin it in src/esbuild-cli-artifact.generated.ts.
|
|
353
|
+
*/
|
|
354
|
+
function stageEsbuildCli(src) {
|
|
355
|
+
const sha256 = createHash('sha256').update(src, 'utf8').digest('hex');
|
|
356
|
+
const buildId = sha256.slice(0, 16);
|
|
357
|
+
const assetDir = join(root, 'public', '_assets', 'runtime');
|
|
358
|
+
const assetName = `esbuild-cli-${buildId}.js`;
|
|
359
|
+
mkdirSync(assetDir, { recursive: true });
|
|
360
|
+
for (const entry of readdirSync(assetDir)) {
|
|
361
|
+
if (entry.startsWith('esbuild-cli-') && entry !== assetName) unlinkSync(join(assetDir, entry));
|
|
362
|
+
}
|
|
363
|
+
writeFileSync(join(assetDir, assetName), src, 'utf8');
|
|
364
|
+
const assetPath = `/_assets/runtime/${assetName}`;
|
|
365
|
+
const generatedPath = join(root, 'src', 'esbuild-cli-artifact.generated.ts');
|
|
366
|
+
writeFileSync(generatedPath, [
|
|
367
|
+
'/**',
|
|
368
|
+
' * esbuild-cli-artifact.generated.ts — AUTO-GENERATED by',
|
|
369
|
+
' * scripts/bundle-facet-workers.mjs. DO NOT EDIT.',
|
|
370
|
+
' *',
|
|
371
|
+
' * Pins the staged runner of the `esbuild` command: esbuild-wasm/wasm_exec.js',
|
|
372
|
+
' * (Go js/wasm glue, as __esbuildGoRuntime) followed by @nimbus-sh/core',
|
|
373
|
+
' * src/runtime/esbuild-cli/preamble.ts as an IIFE. Only the session\'s esbuild',
|
|
374
|
+
' * facet evaluates it, so src/runtime/esbuild-wasm-bytes.ts fetches it from',
|
|
375
|
+
' * ASSETS when that facet is built, instead of the Worker bundle carrying it.',
|
|
376
|
+
' * ESBUILD_CLI_BUILD_ID is a content-hash prefix, ESBUILD_CLI_SHA256 the',
|
|
377
|
+
' * digest every fetch is verified against.',
|
|
378
|
+
' *',
|
|
379
|
+
` * Size: ${(src.length / 1024).toFixed(2)} KiB`,
|
|
380
|
+
' */',
|
|
381
|
+
'',
|
|
382
|
+
`export const ESBUILD_CLI_ASSET_PATH: string = ${JSON.stringify(assetPath)};`,
|
|
383
|
+
`export const ESBUILD_CLI_BUILD_ID: string = ${JSON.stringify(buildId)};`,
|
|
384
|
+
`export const ESBUILD_CLI_SHA256: string = ${JSON.stringify(sha256)};`,
|
|
385
|
+
'',
|
|
386
|
+
].join('\n'));
|
|
387
|
+
return { assetPath, generatedPath };
|
|
388
|
+
}
|
|
389
|
+
|
|
301
390
|
async function main() {
|
|
302
391
|
// 1. Tar-parser preamble (existing W2.5/W4 hot-path helpers).
|
|
303
392
|
const tarStripped = await bundleAsPreamble(
|
|
@@ -317,6 +406,17 @@ async function main() {
|
|
|
317
406
|
'w7-frame',
|
|
318
407
|
);
|
|
319
408
|
|
|
409
|
+
// 3. Node's ESM resolver, which the node shims embed as source (their
|
|
410
|
+
// process's import() loader). One compile of it, here, so the shims'
|
|
411
|
+
// copy is the same text whatever toolchain later evaluates the shims.
|
|
412
|
+
const esmResolver = await bundleAsPreamble(
|
|
413
|
+
join(coreRoot, 'src', '_shared', 'esm-resolver.ts'),
|
|
414
|
+
'esm-resolver',
|
|
415
|
+
);
|
|
416
|
+
if (!/^function createEsmResolver\(/m.test(esmResolver)) {
|
|
417
|
+
throw new Error('[bundle-facet-workers/esm-resolver] the bundle no longer declares function createEsmResolver');
|
|
418
|
+
}
|
|
419
|
+
|
|
320
420
|
const tarEncoded = JSON.stringify(tarStripped);
|
|
321
421
|
const w7Encoded = JSON.stringify(w7Stripped);
|
|
322
422
|
const outPath = join(root, 'src', 'loaders', 'generated-workers.ts');
|
|
@@ -328,8 +428,9 @@ async function main() {
|
|
|
328
428
|
' * Produced by scripts/bundle-facet-workers.mjs from:',
|
|
329
429
|
' * - @nimbus-sh/core src/_shared/tarball-stream.ts (streaming tar primitives)',
|
|
330
430
|
' * - @nimbus-sh/platform src/w7-frame.ts (W7 streaming bulk-write encoder)',
|
|
431
|
+
' * - @nimbus-sh/core src/_shared/esm-resolver.ts (Node\'s ESM resolver, for the node shims)',
|
|
331
432
|
' *',
|
|
332
|
-
' * Consumed by
|
|
433
|
+
' * Consumed by fabric/isolate-pool.ts callers via the `preamble`',
|
|
333
434
|
' * option. The preamble is injected at the top of every generated',
|
|
334
435
|
' * worker module so user functions can reference the exported',
|
|
335
436
|
' * helpers by name.',
|
|
@@ -347,6 +448,9 @@ async function main() {
|
|
|
347
448
|
'',
|
|
348
449
|
`export const W7_FRAME_PREAMBLE: string = ${w7Encoded};`,
|
|
349
450
|
'',
|
|
451
|
+
'/** Declares `function createEsmResolver(host)`; the node shims call it. */',
|
|
452
|
+
`export const ESM_RESOLVER_PREAMBLE: string = ${JSON.stringify(esmResolver)};`,
|
|
453
|
+
'',
|
|
350
454
|
].join('\n');
|
|
351
455
|
|
|
352
456
|
mkdirSync(dirname(outPath), { recursive: true });
|
|
@@ -418,6 +522,9 @@ async function main() {
|
|
|
418
522
|
'',
|
|
419
523
|
].join('\n'));
|
|
420
524
|
|
|
525
|
+
const esbuildCliSrc = await bundleEsbuildCli();
|
|
526
|
+
const esbuildCli = stageEsbuildCli(esbuildCliSrc);
|
|
527
|
+
|
|
421
528
|
console.log(
|
|
422
529
|
`[bundle-facet-workers] wrote ${kernelOutPath} ` +
|
|
423
530
|
`(kernel=${(kernelSrc.length / 1024).toFixed(2)} KiB)`,
|
|
@@ -430,13 +537,17 @@ async function main() {
|
|
|
430
537
|
`[bundle-facet-workers] wrote ${bashOutPath} ` +
|
|
431
538
|
`(bash=${(bashSrc.length / 1024).toFixed(2)} KiB)`,
|
|
432
539
|
);
|
|
540
|
+
console.log(
|
|
541
|
+
`[bundle-facet-workers] staged ${esbuildCli.assetPath} and wrote ${esbuildCli.generatedPath} ` +
|
|
542
|
+
`(esbuild-cli=${(esbuildCliSrc.length / 1024).toFixed(2)} KiB)`,
|
|
543
|
+
);
|
|
433
544
|
}
|
|
434
545
|
|
|
435
546
|
// The bundle functions are exported so the parity test can re-derive the
|
|
436
547
|
// generated files from source and compare, rather than restating the esbuild
|
|
437
548
|
// settings — a second copy of those settings is exactly the drift such a test
|
|
438
549
|
// exists to catch. main() therefore runs only when this file is the entry point.
|
|
439
|
-
export { bundleWasiInstance, bundleBashRunner };
|
|
550
|
+
export { bundleWasiInstance, bundleBashRunner, bundleEsbuildCli };
|
|
440
551
|
|
|
441
552
|
if (process.argv[1] && pathToFileURL(process.argv[1]).href === import.meta.url) {
|
|
442
553
|
main().catch((e) => {
|
package/scripts/bundle-git.mjs
CHANGED
|
@@ -1,30 +1,37 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
/**
|
|
3
|
-
* bundle-git.mjs —
|
|
3
|
+
* bundle-git.mjs — Build the patched git module for hosts and network facets.
|
|
4
4
|
*
|
|
5
5
|
* WHY this exists:
|
|
6
6
|
* The git-network-facet runs inside a dynamic worker loaded via
|
|
7
7
|
* env.LOADER.load(). Dynamic workers have NO access to node_modules —
|
|
8
8
|
* they only see modules explicitly passed in the `modules` object.
|
|
9
9
|
*
|
|
10
|
-
*
|
|
11
|
-
*
|
|
10
|
+
* Hosts import the executable module shipped in vendor/. Consumers never
|
|
11
|
+
* depend on Nimbus' repository postinstall having patched their dependencies.
|
|
12
12
|
*
|
|
13
13
|
* This script bundles isomorphic-git + isomorphic-git/http/web into ONE
|
|
14
|
-
* ESM
|
|
15
|
-
*
|
|
14
|
+
* ESM module. The same bytes are staged as the asset the facet's
|
|
15
|
+
* LOADER.load() receives as `git-bundle.js`.
|
|
16
16
|
*
|
|
17
17
|
* Output:
|
|
18
|
-
*
|
|
18
|
+
* vendor/git.generated.mjs + self-contained declarations
|
|
19
|
+
* public/_assets/runtime/git-<buildId>.js — byte-identical staged copy
|
|
20
|
+
* src/git-bundle.generated.ts — GIT_BUNDLE_ENTRY / _BUILD_ID / _SHA256 pins
|
|
19
21
|
*
|
|
20
22
|
* Runs as a postinstall step AND on every `bun run dev` / `bun run deploy`
|
|
21
23
|
* via the "bundle:git" npm script.
|
|
22
24
|
*/
|
|
23
25
|
|
|
24
26
|
import { build } from 'esbuild';
|
|
25
|
-
import {
|
|
27
|
+
import { createHash } from 'node:crypto';
|
|
28
|
+
import { writeFileSync, readFileSync, readdirSync, mkdirSync, existsSync, unlinkSync } from 'node:fs';
|
|
26
29
|
import { dirname, join } from 'node:path';
|
|
27
30
|
import { fileURLToPath } from 'node:url';
|
|
31
|
+
import ts from 'typescript';
|
|
32
|
+
|
|
33
|
+
import { assertCfGitPatched } from './cf-git-patch.mjs';
|
|
34
|
+
import { resolvePackageDir } from './resolve-package-dir.mjs';
|
|
28
35
|
|
|
29
36
|
const __dirname = dirname(fileURLToPath(import.meta.url));
|
|
30
37
|
const root = join(__dirname, '..');
|
|
@@ -37,7 +44,43 @@ const ENTRY_CONTENTS = [
|
|
|
37
44
|
|
|
38
45
|
const ENTRY_FILE = join(root, '.git-bundle-entry.js');
|
|
39
46
|
|
|
47
|
+
// Upstream declarations are copied mechanically; only the tracked patch's
|
|
48
|
+
// public signature changes live here. No consumer dependency on the build input.
|
|
49
|
+
const GIT_TYPES = `import type * as Upstream from './git-upstream.generated.js';
|
|
50
|
+
type Add = Parameters<typeof Upstream.add>[0];
|
|
51
|
+
type Remove = Parameters<typeof Upstream.remove>[0];
|
|
52
|
+
type Commit = Parameters<typeof Upstream.commit>[0];
|
|
53
|
+
type Matrix = Parameters<typeof Upstream.statusMatrix>[0];
|
|
54
|
+
type Checkout = Parameters<typeof Upstream.checkout>[0];
|
|
55
|
+
export declare const git: Omit<typeof Upstream, 'add' | 'remove' | 'commit' | 'statusMatrix'> & {
|
|
56
|
+
add(options: Omit<Add, 'filepath'> & { filepath: string | string[] }): ReturnType<typeof Upstream.add>;
|
|
57
|
+
remove(options: Omit<Remove, 'filepath'> & { filepath: string | string[] }): ReturnType<typeof Upstream.remove>;
|
|
58
|
+
commit(options: Commit & { rawMessage?: boolean }): ReturnType<typeof Upstream.commit>;
|
|
59
|
+
statusMatrix(options: Matrix & { deferRefresh?: boolean }): ReturnType<typeof Upstream.statusMatrix>;
|
|
60
|
+
stage(options: Pick<Add, 'fs' | 'dir' | 'gitdir' | 'cache' | 'force' | 'parallel'> & {
|
|
61
|
+
add?: string[]; remove?: string[];
|
|
62
|
+
}): Promise<void>;
|
|
63
|
+
checkoutFreshChunk(options: Pick<Checkout, 'fs' | 'dir' | 'gitdir' | 'ref' | 'cache' | 'onProgress'> & {
|
|
64
|
+
cursor?: object | null; maxEntries: number; maxDecodedBytes: number; maxWallMs: number;
|
|
65
|
+
deferIndexFragmentCleanup?: boolean;
|
|
66
|
+
}): Promise<{ nextCursor: object | null; files: number; decodedBytes: number; treeEntriesVisited: number; indexEntries: number }>;
|
|
67
|
+
};
|
|
68
|
+
export * as gitHttp from './git-http.generated.js';
|
|
69
|
+
`;
|
|
70
|
+
|
|
71
|
+
function declaration(source, destination) {
|
|
72
|
+
const text = readFileSync(source, 'utf8');
|
|
73
|
+
if (ts.preProcessFile(text).importedFiles.length) {
|
|
74
|
+
throw new Error('Git declarations acquired imports; bundle their types before publishing: ' + source);
|
|
75
|
+
}
|
|
76
|
+
writeFileSync(destination, '// Generated by scripts/bundle-git.mjs from the pinned cf-git declarations.\n' + text);
|
|
77
|
+
}
|
|
78
|
+
|
|
40
79
|
async function main() {
|
|
80
|
+
// A copy patched by another revision of the tracked patch would bundle
|
|
81
|
+
// without its fixes, and nothing downstream would notice: refuse instead.
|
|
82
|
+
const gitDir = resolvePackageDir('isomorphic-git', { start: root });
|
|
83
|
+
assertCfGitPatched(join(root, '..', '..'), [gitDir]);
|
|
41
84
|
try {
|
|
42
85
|
writeFileSync(ENTRY_FILE, ENTRY_CONTENTS);
|
|
43
86
|
|
|
@@ -59,6 +102,12 @@ async function main() {
|
|
|
59
102
|
'node:*',
|
|
60
103
|
'cloudflare:workers',
|
|
61
104
|
],
|
|
105
|
+
// The module ships inside the supervisor Worker, which has a size budget
|
|
106
|
+
// (tests/behavioral/assets-fetch/new/worker-bundle-size.mjs), and as a
|
|
107
|
+
// staged asset. Whitespace and syntax minification take ~200 KB off it;
|
|
108
|
+
// identifiers are kept, so stack traces still name cf-git's functions.
|
|
109
|
+
minifyWhitespace: true,
|
|
110
|
+
minifySyntax: true,
|
|
62
111
|
write: false,
|
|
63
112
|
logLevel: 'warning',
|
|
64
113
|
});
|
|
@@ -69,43 +118,55 @@ async function main() {
|
|
|
69
118
|
|
|
70
119
|
const code = result.outputFiles[0].text;
|
|
71
120
|
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
121
|
+
const vendor = join(root, 'vendor');
|
|
122
|
+
mkdirSync(vendor, { recursive: true });
|
|
123
|
+
writeFileSync(join(vendor, 'git.generated.mjs'), code);
|
|
124
|
+
writeFileSync(join(vendor, 'git.LICENSE'), readFileSync(join(gitDir, 'LICENSE.md')));
|
|
125
|
+
declaration(join(gitDir, 'index.d.ts'), join(vendor, 'git-upstream.generated.d.ts'));
|
|
126
|
+
declaration(join(gitDir, 'http', 'web', 'index.d.ts'), join(vendor, 'git-http.generated.d.ts'));
|
|
127
|
+
writeFileSync(join(vendor, 'git.generated.d.mts'), '// Generated by scripts/bundle-git.mjs.\n' + GIT_TYPES);
|
|
75
128
|
|
|
76
|
-
//
|
|
77
|
-
//
|
|
78
|
-
|
|
129
|
+
// The facet's copy is a staged asset, not a string in the Worker bundle:
|
|
130
|
+
// the Worker already carries the executable module above, and a second
|
|
131
|
+
// inlined copy cost ~310 KB of the bundle's size gate
|
|
132
|
+
// (tests/behavioral/assets-fetch/new/worker-bundle-size.mjs). Same
|
|
133
|
+
// mechanism as scripts/bundle-node-shims.mjs; src/runtime/git-bundle-artifact.ts
|
|
134
|
+
// fetches it sha-verified.
|
|
135
|
+
const sha256 = createHash('sha256').update(code, 'utf8').digest('hex');
|
|
136
|
+
const buildId = sha256.slice(0, 16);
|
|
137
|
+
const assetName = `git-${buildId}.js`;
|
|
138
|
+
const assetDir = join(root, 'public', '_assets', 'runtime');
|
|
139
|
+
mkdirSync(assetDir, { recursive: true });
|
|
140
|
+
// Exactly one staged copy: the entry constant pins which one a deploy serves.
|
|
141
|
+
for (const file of readdirSync(assetDir)) {
|
|
142
|
+
if (/^git-[0-9a-f]{16}\.js$/.test(file) && file !== assetName) unlinkSync(join(assetDir, file));
|
|
143
|
+
}
|
|
144
|
+
writeFileSync(join(assetDir, assetName), code);
|
|
79
145
|
|
|
146
|
+
const outPath = join(root, 'src', 'git-bundle.generated.ts');
|
|
80
147
|
const tsWrapper = [
|
|
81
148
|
'/**',
|
|
82
|
-
' * git-bundle.generated.ts — AUTO-GENERATED. DO NOT EDIT.',
|
|
83
|
-
' *',
|
|
84
|
-
' * Produced by scripts/bundle-git.mjs from:',
|
|
85
|
-
" * - isomorphic-git (github:AshishKumar4/cf-git)",
|
|
86
|
-
" * - isomorphic-git/http/web",
|
|
149
|
+
' * git-bundle.generated.ts — AUTO-GENERATED by scripts/bundle-git.mjs. DO NOT EDIT.',
|
|
87
150
|
' *',
|
|
88
|
-
' *
|
|
89
|
-
' *
|
|
90
|
-
|
|
91
|
-
` * Size: ${(code.length / 1024).toFixed(1)} KiB`,
|
|
151
|
+
' * Pins the staged copy of vendor/git.generated.mjs (isomorphic-git from',
|
|
152
|
+
' * github:AshishKumar4/cf-git + isomorphic-git/http/web) that the git network',
|
|
153
|
+
" * facet imports as `git-bundle.js`. GIT_BUNDLE_SHA256 is verified at fetch time.",
|
|
92
154
|
' */',
|
|
93
155
|
'',
|
|
94
|
-
`export const
|
|
95
|
-
|
|
96
|
-
`export const
|
|
156
|
+
`export const GIT_BUNDLE_ENTRY: string = ${JSON.stringify(`/_assets/runtime/${assetName}`)};`,
|
|
157
|
+
`export const GIT_BUNDLE_BUILD_ID: string = ${JSON.stringify(buildId)};`,
|
|
158
|
+
`export const GIT_BUNDLE_SHA256: string = ${JSON.stringify(sha256)};`,
|
|
97
159
|
'',
|
|
98
160
|
].join('\n');
|
|
99
161
|
|
|
100
162
|
mkdirSync(dirname(outPath), { recursive: true });
|
|
101
163
|
writeFileSync(outPath, tsWrapper);
|
|
102
164
|
|
|
103
|
-
console.log(`[bundle-git]
|
|
165
|
+
console.log(`[bundle-git] staged ${assetName} (${(code.length / 1024).toFixed(1)} KiB) and wrote ${outPath}`);
|
|
104
166
|
} finally {
|
|
105
167
|
// Clean up the temp entry file
|
|
106
168
|
try {
|
|
107
169
|
if (existsSync(ENTRY_FILE)) {
|
|
108
|
-
const { unlinkSync } = await import('node:fs');
|
|
109
170
|
unlinkSync(ENTRY_FILE);
|
|
110
171
|
}
|
|
111
172
|
} catch {}
|
|
@@ -1,31 +1,37 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
/**
|
|
3
|
-
* bundle-node-shims.mjs — stage the node-compat
|
|
3
|
+
* bundle-node-shims.mjs — stage the node-compat layer's sources as static assets.
|
|
4
4
|
*
|
|
5
5
|
* Why this exists
|
|
6
6
|
* ───────────────
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
*
|
|
10
|
-
*
|
|
11
|
-
*
|
|
12
|
-
*
|
|
13
|
-
*
|
|
14
|
-
*
|
|
7
|
+
* Every node facet's generated worker text splices three sources that only
|
|
8
|
+
* ever run inside the facet:
|
|
9
|
+
* - `generateShimsCode()` (src/runtime/node-shims.ts), the ~230 KiB
|
|
10
|
+
* node-compat shims;
|
|
11
|
+
* - `VFS_WRITE_LEDGER_SOURCE` (@nimbus-sh/core _shared/vfs-write-ledger.ts),
|
|
12
|
+
* the write ledger the shims' filesystem writes go through;
|
|
13
|
+
* - `FACET_RESIDENT_STORE_SOURCE` (src/vfs/facet-resident-store.ts), a
|
|
14
|
+
* resident facet's SQLite-backed resident set the shims read from.
|
|
15
|
+
* Keeping them inside the worker bundle pushed the main bundle over its size
|
|
16
|
+
* gate (tests/behavioral/assets-fetch/new/worker-bundle-size.mjs), whose
|
|
17
|
+
* intended fix is exactly this promote: large facet-runner source strings
|
|
18
|
+
* belong in the static-assets layer, not the supervisor bundle. Nothing the
|
|
19
|
+
* Worker bundle imports reaches the three modules any more.
|
|
15
20
|
*
|
|
16
|
-
* This script evaluates the COMMITTED dist
|
|
17
|
-
*
|
|
18
|
-
*
|
|
19
|
-
*
|
|
20
|
-
*
|
|
21
|
-
* CURRENT src generateShimsCode() output).
|
|
21
|
+
* This script evaluates the COMMITTED dist — dist is the deployable truth
|
|
22
|
+
* (package "main" points at dist; apps bundle from it), so each staged asset
|
|
23
|
+
* matches what a deploy would have shipped inline. Drift between src and the
|
|
24
|
+
* staged assets is caught by tests/unit/node-shims-artifact-parity.mjs
|
|
25
|
+
* (asserts each asset's bytes equal the CURRENT src output).
|
|
22
26
|
*
|
|
23
27
|
* Output:
|
|
24
|
-
* public/_assets/runtime/node-shims-<buildId>.js
|
|
25
|
-
*
|
|
26
|
-
*
|
|
27
|
-
*
|
|
28
|
-
* export const
|
|
28
|
+
* public/_assets/runtime/node-shims-<buildId>.js
|
|
29
|
+
* public/_assets/runtime/vfs-write-ledger-<buildId>.js
|
|
30
|
+
* public/_assets/runtime/resident-store-<buildId>.js
|
|
31
|
+
* src/node-shims-artifact.generated.ts, per source:
|
|
32
|
+
* export const <NAME>_ENTRY: string; // asset path
|
|
33
|
+
* export const <NAME>_BUILD_ID: string; // content-hash prefix
|
|
34
|
+
* export const <NAME>_SHA256: string; // full digest
|
|
29
35
|
*
|
|
30
36
|
* Fetched at runtime by src/runtime/node-shims-artifact.ts (L2 + ASSETS,
|
|
31
37
|
* sha-verified, memoized per isolate).
|
|
@@ -42,9 +48,9 @@ import { fileURLToPath } from 'node:url';
|
|
|
42
48
|
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
|
43
49
|
const ROOT = path.resolve(__dirname, '..');
|
|
44
50
|
|
|
45
|
-
const { generateShimsCode } = await import(
|
|
46
|
-
|
|
47
|
-
);
|
|
51
|
+
const { generateShimsCode } = await import(path.join(ROOT, 'dist/runtime/node-shims.js'));
|
|
52
|
+
const { FACET_RESIDENT_STORE_SOURCE } = await import(path.join(ROOT, 'dist/vfs/facet-resident-store.js'));
|
|
53
|
+
const { VFS_WRITE_LEDGER_SOURCE } = await import('@nimbus-sh/core/_shared/vfs-write-ledger.js');
|
|
48
54
|
|
|
49
55
|
const shims = generateShimsCode();
|
|
50
56
|
if (typeof shims !== 'string' || shims.length < 100_000) {
|
|
@@ -55,38 +61,58 @@ if (typeof shims !== 'string' || shims.length < 100_000) {
|
|
|
55
61
|
);
|
|
56
62
|
}
|
|
57
63
|
|
|
58
|
-
const
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
64
|
+
const SOURCES = [
|
|
65
|
+
{ name: 'NODE_SHIMS', family: 'node-shims', source: shims, from: 'dist/runtime/node-shims.js generateShimsCode()' },
|
|
66
|
+
{
|
|
67
|
+
name: 'VFS_WRITE_LEDGER',
|
|
68
|
+
family: 'vfs-write-ledger',
|
|
69
|
+
source: VFS_WRITE_LEDGER_SOURCE,
|
|
70
|
+
from: '@nimbus-sh/core dist/_shared/vfs-write-ledger.js VFS_WRITE_LEDGER_SOURCE',
|
|
71
|
+
},
|
|
72
|
+
{
|
|
73
|
+
name: 'RESIDENT_STORE',
|
|
74
|
+
family: 'resident-store',
|
|
75
|
+
source: FACET_RESIDENT_STORE_SOURCE,
|
|
76
|
+
from: 'dist/vfs/facet-resident-store.js FACET_RESIDENT_STORE_SOURCE',
|
|
77
|
+
},
|
|
78
|
+
];
|
|
63
79
|
|
|
80
|
+
const assetDir = path.join(ROOT, 'public/_assets/runtime');
|
|
64
81
|
await fs.mkdir(assetDir, { recursive: true });
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
for (const
|
|
68
|
-
if (
|
|
69
|
-
|
|
82
|
+
const existing = await fs.readdir(assetDir);
|
|
83
|
+
const pins = [];
|
|
84
|
+
for (const { name, family, source, from } of SOURCES) {
|
|
85
|
+
if (typeof source !== 'string' || source.length === 0) {
|
|
86
|
+
throw new Error(`[bundle-node-shims] ${from} is ${typeof source === 'string' ? 'empty' : typeof source}, not the source to stage`);
|
|
87
|
+
}
|
|
88
|
+
const sha256 = createHash('sha256').update(source, 'utf8').digest('hex');
|
|
89
|
+
const buildId = sha256.slice(0, 16);
|
|
90
|
+
const assetName = `${family}-${buildId}.js`;
|
|
91
|
+
// Remove stale same-family assets so the directory carries exactly one blob
|
|
92
|
+
// per family (the entry constant pins which one a deploy serves).
|
|
93
|
+
for (const f of existing) {
|
|
94
|
+
if (f.startsWith(`${family}-`) && f !== assetName) await fs.unlink(path.join(assetDir, f));
|
|
70
95
|
}
|
|
96
|
+
await fs.writeFile(path.join(assetDir, assetName), source, 'utf8');
|
|
97
|
+
pins.push(
|
|
98
|
+
`/** ${from} */`,
|
|
99
|
+
`export const ${name}_ENTRY: string = ${JSON.stringify(`/_assets/runtime/${assetName}`)};`,
|
|
100
|
+
`export const ${name}_BUILD_ID: string = ${JSON.stringify(buildId)};`,
|
|
101
|
+
`export const ${name}_SHA256: string = ${JSON.stringify(sha256)};`,
|
|
102
|
+
'',
|
|
103
|
+
);
|
|
104
|
+
console.log(`[bundle-node-shims] staged ${assetName} (${(source.length / 1024).toFixed(1)} KiB, sha ${buildId}…)`);
|
|
71
105
|
}
|
|
72
|
-
await fs.writeFile(path.join(assetDir, assetName), shims, 'utf8');
|
|
73
106
|
|
|
74
107
|
const generated = `/**
|
|
75
108
|
* node-shims-artifact.generated.ts — AUTO-GENERATED by
|
|
76
109
|
* scripts/bundle-node-shims.mjs. DO NOT EDIT.
|
|
77
110
|
*
|
|
78
|
-
* Pins the staged node-compat
|
|
79
|
-
*
|
|
80
|
-
* prefix so cache layers never serve stale
|
|
81
|
-
*
|
|
111
|
+
* Pins the staged sources of the node-compat layer, promoted out of the worker
|
|
112
|
+
* bundle: the shims, the VFS write ledger and the resident store. Each
|
|
113
|
+
* <NAME>_BUILD_ID is a content-hash prefix so cache layers never serve stale
|
|
114
|
+
* bytes after a rebuild; <NAME>_SHA256 is the full digest verified at fetch time.
|
|
82
115
|
*/
|
|
83
116
|
|
|
84
|
-
|
|
85
|
-
export const NODE_SHIMS_BUILD_ID: string = ${JSON.stringify(buildId)};
|
|
86
|
-
export const NODE_SHIMS_SHA256: string = ${JSON.stringify(sha256)};
|
|
87
|
-
`;
|
|
117
|
+
${pins.join('\n')}`;
|
|
88
118
|
await fs.writeFile(path.join(ROOT, 'src/node-shims-artifact.generated.ts'), generated, 'utf8');
|
|
89
|
-
|
|
90
|
-
console.log(
|
|
91
|
-
`[bundle-node-shims] staged ${assetName} (${(shims.length / 1024).toFixed(1)} KiB, sha ${buildId}…)`,
|
|
92
|
-
);
|