@nimbus-sh/worker 0.5.0 → 0.7.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +2 -2
- package/dist/_shared/preview-host.d.ts +26 -8
- package/dist/_shared/preview-host.d.ts.map +1 -1
- package/dist/_shared/preview-host.js +51 -11
- package/dist/cirrus-npm-cjs.generated.d.ts +1 -1
- package/dist/cirrus-npm-cjs.generated.js +1 -1
- package/dist/facets/cirrus-real.d.ts.map +1 -1
- package/dist/facets/cirrus-real.js +6 -5
- package/dist/facets/compose.d.ts +148 -0
- package/dist/facets/compose.d.ts.map +1 -0
- package/dist/facets/compose.js +146 -0
- package/dist/facets/durable-images.d.ts +18 -5
- package/dist/facets/durable-images.d.ts.map +1 -1
- package/dist/facets/durable-images.js +36 -7
- package/dist/facets/durable-slots.d.ts +1 -1
- package/dist/facets/durable-slots.d.ts.map +1 -1
- package/dist/facets/durable-slots.js +2 -1
- package/dist/facets/esbuild-bundle-pool.d.ts +49 -0
- package/dist/facets/esbuild-bundle-pool.d.ts.map +1 -0
- package/dist/facets/esbuild-bundle-pool.js +122 -0
- package/dist/facets/exec-telemetry.d.ts +8 -0
- package/dist/facets/exec-telemetry.d.ts.map +1 -1
- package/dist/facets/manager.d.ts +337 -123
- package/dist/facets/manager.d.ts.map +1 -1
- package/dist/facets/manager.js +1100 -449
- package/dist/facets/process.d.ts +20 -16
- package/dist/facets/process.d.ts.map +1 -1
- package/dist/facets/process.js +59 -28
- package/dist/facets/real-vite-fs-shim.js +2 -2
- package/dist/facets/resident-identity.d.ts +23 -0
- package/dist/facets/resident-identity.d.ts.map +1 -0
- package/dist/facets/resident-identity.js +31 -0
- package/dist/facets/vite-dev-server.d.ts +25 -47
- package/dist/facets/vite-dev-server.d.ts.map +1 -1
- package/dist/facets/vite-dev-server.js +185 -219
- package/dist/facets/wasm-image-digest.d.ts +25 -0
- package/dist/facets/wasm-image-digest.d.ts.map +1 -0
- package/dist/facets/wasm-image-digest.js +25 -0
- package/dist/facets/wasm-swap-registry.d.ts +51 -92
- package/dist/facets/wasm-swap-registry.d.ts.map +1 -1
- package/dist/facets/wasm-swap-registry.js +68 -227
- package/dist/git/commands.d.ts +0 -1
- package/dist/git/commands.d.ts.map +1 -1
- package/dist/git/commands.js +0 -3
- package/dist/git/network-facet.d.ts.map +1 -1
- package/dist/git/network-facet.js +6 -5
- package/dist/loaders/child-process/spawn-pool.d.ts +3 -2
- package/dist/loaders/child-process/spawn-pool.d.ts.map +1 -1
- package/dist/loaders/child-process/spawn-pool.js +3 -2
- package/dist/loaders/generated-workers.d.ts +2 -2
- package/dist/loaders/generated-workers.d.ts.map +1 -1
- package/dist/loaders/generated-workers.js +3 -3
- package/dist/loaders/npm-resolve-preamble.d.ts +3 -6
- package/dist/loaders/npm-resolve-preamble.d.ts.map +1 -1
- package/dist/loaders/npm-resolve-preamble.js +34 -108
- package/dist/node-shims-artifact.generated.js +3 -3
- package/dist/npm/install-batch-facet.d.ts +3 -2
- package/dist/npm/install-batch-facet.d.ts.map +1 -1
- package/dist/npm/install-batch-facet.js +45 -15
- package/dist/npm/installer.d.ts +22 -17
- package/dist/npm/installer.d.ts.map +1 -1
- package/dist/npm/installer.js +209 -193
- package/dist/npm/pre-bundle-facet.d.ts +1 -1
- package/dist/npm/pre-bundle-facet.d.ts.map +1 -1
- package/dist/npm/pre-bundle-facet.js +1 -1
- package/dist/npm/resolve-facet.d.ts +6 -0
- package/dist/npm/resolve-facet.d.ts.map +1 -1
- package/dist/npm/resolve-one-facet.d.ts +21 -20
- package/dist/npm/resolve-one-facet.d.ts.map +1 -1
- package/dist/npm/resolve-one-facet.js +85 -84
- package/dist/npm/semver.d.ts +59 -0
- package/dist/npm/semver.d.ts.map +1 -0
- package/dist/npm/semver.js +226 -0
- package/dist/router/index.d.ts.map +1 -1
- package/dist/router/index.js +47 -10
- package/dist/router/public-directory.d.ts +5 -1
- package/dist/router/public-directory.d.ts.map +1 -1
- package/dist/router/public-directory.js +9 -2
- package/dist/router/remote-api.d.ts +18 -0
- package/dist/router/remote-api.d.ts.map +1 -1
- package/dist/router/remote-api.js +64 -5
- package/dist/runtime/cpython-resident.d.ts.map +1 -1
- package/dist/runtime/cpython-resident.js +3 -1
- package/dist/runtime/html-entrypoint.d.ts +7 -0
- package/dist/runtime/html-entrypoint.d.ts.map +1 -1
- package/dist/runtime/html-entrypoint.js +18 -2
- package/dist/runtime/node-runner.d.ts +3 -0
- package/dist/runtime/node-runner.d.ts.map +1 -1
- package/dist/runtime/node-runner.js +7 -0
- package/dist/runtime/node-shims.d.ts.map +1 -1
- package/dist/runtime/node-shims.js +305 -29
- package/dist/runtime/opencode-facet-runner.js +2 -2
- package/dist/runtime/package-manager.d.ts +44 -1
- package/dist/runtime/package-manager.d.ts.map +1 -1
- package/dist/runtime/package-manager.js +168 -3
- package/dist/runtime/ruby-resident.d.ts.map +1 -1
- package/dist/runtime/ruby-resident.js +2 -0
- package/dist/session/agent.d.ts.map +1 -1
- package/dist/session/agent.js +28 -1
- package/dist/session/helpers.d.ts +38 -0
- package/dist/session/helpers.d.ts.map +1 -1
- package/dist/session/helpers.js +76 -0
- package/dist/session/init-phases.d.ts +1 -1
- package/dist/session/init-phases.d.ts.map +1 -1
- package/dist/session/init-phases.js +2 -12
- package/dist/session/init.d.ts +15 -1
- package/dist/session/init.d.ts.map +1 -1
- package/dist/session/init.js +91 -603
- package/dist/session/keys.d.ts +4 -0
- package/dist/session/keys.d.ts.map +1 -1
- package/dist/session/keys.js +4 -0
- package/dist/session/nimbus-session.d.ts +90 -23
- package/dist/session/nimbus-session.d.ts.map +1 -1
- package/dist/session/nimbus-session.js +200 -110
- package/dist/session/npm-install-port.d.ts +16 -0
- package/dist/session/npm-install-port.d.ts.map +1 -0
- package/dist/session/npm-install-port.js +37 -0
- package/dist/session/port-capability.d.ts +90 -0
- package/dist/session/port-capability.d.ts.map +1 -1
- package/dist/session/port-capability.js +219 -9
- package/dist/session/programmatic.d.ts +125 -5
- package/dist/session/programmatic.d.ts.map +1 -1
- package/dist/session/programmatic.js +439 -89
- package/dist/session/routes.d.ts +39 -17
- package/dist/session/routes.d.ts.map +1 -1
- package/dist/session/routes.js +67 -131
- package/dist/session/rpc.d.ts +39 -16
- package/dist/session/rpc.d.ts.map +1 -1
- package/dist/session/rpc.js +137 -130
- package/dist/session/serving-port.d.ts +27 -0
- package/dist/session/serving-port.d.ts.map +1 -0
- package/dist/session/serving-port.js +27 -0
- package/dist/session/start-real-vite.d.ts +12 -0
- package/dist/session/start-real-vite.d.ts.map +1 -1
- package/dist/session/start-real-vite.js +4 -4
- package/dist/session/supervisor-op.d.ts +41 -4
- package/dist/session/supervisor-op.d.ts.map +1 -1
- package/dist/session/supervisor-op.js +101 -73
- package/dist/session/supervisor-rpc.d.ts +7 -7
- package/dist/session/supervisor-rpc.d.ts.map +1 -1
- package/dist/session/supervisor-rpc.js +6 -3
- package/dist/session/vite-command.d.ts +18 -0
- package/dist/session/vite-command.d.ts.map +1 -0
- package/dist/session/vite-command.js +609 -0
- package/dist/session/ws.d.ts +61 -0
- package/dist/session/ws.d.ts.map +1 -1
- package/dist/session/ws.js +122 -12
- package/dist/shell/npm-bin-entrypoints.d.ts +0 -35
- package/dist/shell/npm-bin-entrypoints.d.ts.map +1 -1
- package/dist/shell/npm-bin-entrypoints.js +12 -85
- package/package.json +24 -4
- package/public/_assets/runtime/{node-shims-9e1380d9ee430fcc.js → node-shims-8f8c64edd2a1f0f5.js} +305 -29
- package/public/index.html +1 -1
- package/scripts/bundle-facet-workers.mjs +1 -1
- package/scripts/bundle-npm-cjs.mjs +2 -2
- package/dist/facets/on-demand-bundle-gate.d.ts +0 -65
- package/dist/facets/on-demand-bundle-gate.d.ts.map +0 -1
- package/dist/facets/on-demand-bundle-gate.js +0 -125
- package/dist/npm/install-args.d.ts +0 -21
- package/dist/npm/install-args.d.ts.map +0 -1
- package/dist/npm/install-args.js +0 -70
- package/dist/npm/npm-log.d.ts +0 -31
- package/dist/npm/npm-log.d.ts.map +0 -1
- package/dist/npm/npm-log.js +0 -51
|
@@ -26,7 +26,7 @@ import { getSharedRuntimeExternals, BUNDLER_VERSION } from '@nimbus-sh/core/runt
|
|
|
26
26
|
import { NpmCache } from '../npm/cache.js';
|
|
27
27
|
import { sha256Base64Url } from '@nimbus-sh/core/_shared/crypto.js';
|
|
28
28
|
import { LruMap } from '@nimbus-sh/core/_shared/lru-map.js';
|
|
29
|
-
import {
|
|
29
|
+
import { acquireSupervisorAllocation } from '@nimbus-sh/platform/heavy-alloc-coord.js';
|
|
30
30
|
import { VITE_MODULE_CACHE_MAX_ENTRIES, ON_DEMAND_SLICE_CAP_BYTES } from '@nimbus-sh/core/constants.js';
|
|
31
31
|
import { countPackageFiles, BARREL_PKG_FILE_THRESHOLD, packageNameFromSpecifier } from '@nimbus-sh/core/runtime/barrel-detect.js';
|
|
32
32
|
import { scanNamedImports, namedImportSignature, buildSyntheticEntry, buildScopedSliceForSynthetic, syntheticEntryPath, } from '../runtime/barrel-synthesizer.js';
|
|
@@ -1168,15 +1168,10 @@ export class ViteDevServer {
|
|
|
1168
1168
|
npmCache = null;
|
|
1169
1169
|
/** Inject React Router basename into entry files? Default: true. */
|
|
1170
1170
|
injectBasename;
|
|
1171
|
-
/** Worker env (LOADER, ctx.exports) for the on-demand-bundle facet path.
|
|
1172
|
-
* Null = legacy in-supervisor esbuild fallback. */
|
|
1173
1171
|
env;
|
|
1174
1172
|
ctx = null;
|
|
1175
|
-
/**
|
|
1176
|
-
|
|
1177
|
-
* cold-path /preview/@modules/<spec> request. */
|
|
1178
|
-
onDemandPool = null;
|
|
1179
|
-
onDemandPoolPromise = null;
|
|
1173
|
+
/** The session's esbuild facet pool; null = legacy in-supervisor esbuild. */
|
|
1174
|
+
bundlePool;
|
|
1180
1175
|
/**
|
|
1181
1176
|
* In-flight on-demand-bundle coalescing map. When the browser fires
|
|
1182
1177
|
* multiple parallel requests for the same /preview/@modules/<spec>
|
|
@@ -1194,21 +1189,6 @@ export class ViteDevServer {
|
|
|
1194
1189
|
* crashes the supervisor for N≥3 on a busy isolate.
|
|
1195
1190
|
*/
|
|
1196
1191
|
pendingBundles = new Map();
|
|
1197
|
-
/**
|
|
1198
|
-
* Byte-budget admission gate for the on-demand bundle slow path.
|
|
1199
|
-
* Replaces the former single-slot semaphore: instead of serializing
|
|
1200
|
-
* every cold bundle (which made a fresh-React first load multi-second
|
|
1201
|
-
* because each distinct /@modules/ spec waited for the previous), it
|
|
1202
|
-
* bounds the TOTAL slice BYTES resident in the supervisor at once.
|
|
1203
|
-
*
|
|
1204
|
-
* Many small slices' facet RPC round-trips overlap; a single large
|
|
1205
|
-
* (~28 MiB) slice still serializes the rest. Peak resident slice bytes
|
|
1206
|
-
* never exceed ON_DEMAND_SLICE_CAP_BYTES — the same one-slice envelope
|
|
1207
|
-
* the install-time pre-bundler proved safe on shared DO isolates — so
|
|
1208
|
-
* this is a latency win with no supervisor-heap regression. Coupled
|
|
1209
|
-
* with pendingBundles (same-spec coalescing) as before.
|
|
1210
|
-
*/
|
|
1211
|
-
onDemandGate = new OnDemandBundleGate(ON_DEMAND_SLICE_CAP_BYTES);
|
|
1212
1192
|
/**
|
|
1213
1193
|
* process diagnostics support: the supervisor's per-PID log store. When set
|
|
1214
1194
|
* (alongside `pid`), every diagnostic emitted by the dev server is
|
|
@@ -1238,6 +1218,7 @@ export class ViteDevServer {
|
|
|
1238
1218
|
this.aliases = opts.aliases || {};
|
|
1239
1219
|
this.env = opts.env;
|
|
1240
1220
|
this.ctx = opts.ctx ?? null;
|
|
1221
|
+
this.bundlePool = opts.bundlePool ?? null;
|
|
1241
1222
|
if (opts.sql) {
|
|
1242
1223
|
this.npmCache = new NpmCache(opts.sql);
|
|
1243
1224
|
}
|
|
@@ -1262,48 +1243,16 @@ export class ViteDevServer {
|
|
|
1262
1243
|
this.detectTailwind();
|
|
1263
1244
|
}
|
|
1264
1245
|
/**
|
|
1265
|
-
*
|
|
1266
|
-
*
|
|
1267
|
-
*
|
|
1268
|
-
*
|
|
1269
|
-
*
|
|
1270
|
-
*
|
|
1271
|
-
* Returns null when env/ctx aren't available (legacy fallback used).
|
|
1246
|
+
* The session's shared esbuild pool for on-demand bundling of
|
|
1247
|
+
* /preview/@modules/<spec> requests that miss both the in-memory and
|
|
1248
|
+
* pkg_esm_bundles caches. Null when no pool was provided (legacy
|
|
1249
|
+
* in-supervisor fallback). Acquired BEFORE the slice lease — see
|
|
1250
|
+
* EsbuildBundlePool.acquire.
|
|
1272
1251
|
*/
|
|
1273
1252
|
async ensureOnDemandPool() {
|
|
1274
|
-
if (this.
|
|
1275
|
-
return this.onDemandPool;
|
|
1276
|
-
if (this.onDemandPoolPromise)
|
|
1277
|
-
return this.onDemandPoolPromise;
|
|
1278
|
-
if (!this.env || !this.ctx)
|
|
1253
|
+
if (!this.bundlePool)
|
|
1279
1254
|
return null;
|
|
1280
|
-
this.
|
|
1281
|
-
const { IsolatePool } = await import('@nimbus-sh/fabric/isolate-pool.js');
|
|
1282
|
-
const { PRE_BUNDLE_PREAMBLE } = await import('../loaders/pre-bundle-preamble.js');
|
|
1283
|
-
const { fetchEsbuildWasmBytes } = await import('../runtime/esbuild-wasm-bytes.js');
|
|
1284
|
-
const wasmBytes = await fetchEsbuildWasmBytes(this.env);
|
|
1285
|
-
const pool = new IsolatePool(this.env, this.ctx, {
|
|
1286
|
-
concurrency: 1,
|
|
1287
|
-
timeoutMs: 60_000,
|
|
1288
|
-
retries: 0,
|
|
1289
|
-
// Use a distinct tag so the on-demand pool's cached worker
|
|
1290
|
-
// doesn't collide with the install-time pre-bundle pool.
|
|
1291
|
-
// Sharing fnHash + preamble + wasm fingerprint between pools
|
|
1292
|
-
// would otherwise alias them in workerd's loader cache.
|
|
1293
|
-
tag: 'on-demand-bundle',
|
|
1294
|
-
preamble: PRE_BUNDLE_PREAMBLE,
|
|
1295
|
-
wasmModules: { 'esbuild.wasm': wasmBytes },
|
|
1296
|
-
});
|
|
1297
|
-
this.onDemandPool = pool;
|
|
1298
|
-
return pool;
|
|
1299
|
-
})();
|
|
1300
|
-
try {
|
|
1301
|
-
return await this.onDemandPoolPromise;
|
|
1302
|
-
}
|
|
1303
|
-
catch (e) {
|
|
1304
|
-
this.onDemandPoolPromise = null;
|
|
1305
|
-
throw e;
|
|
1306
|
-
}
|
|
1255
|
+
return this.bundlePool.acquire();
|
|
1307
1256
|
}
|
|
1308
1257
|
/** Detect TailwindCSS usage in the project */
|
|
1309
1258
|
detectTailwind() {
|
|
@@ -1756,39 +1705,40 @@ export class ViteDevServer {
|
|
|
1756
1705
|
});
|
|
1757
1706
|
}
|
|
1758
1707
|
}
|
|
1759
|
-
// ── Cold path coalescing
|
|
1708
|
+
// ── Cold path coalescing ──────────────────────────────────────
|
|
1760
1709
|
// Multiple parallel browser requests for the same module are
|
|
1761
1710
|
// common on first preview load; coalesce so exactly ONE bundle
|
|
1762
|
-
// attempt runs per spec. Across DIFFERENT specs, the
|
|
1763
|
-
//
|
|
1764
|
-
//
|
|
1765
|
-
//
|
|
1711
|
+
// attempt runs per spec. Across DIFFERENT specs, the cold path
|
|
1712
|
+
// leases its slice bytes from the shared supervisor allocation
|
|
1713
|
+
// budget before building, so it queues behind every other heavy
|
|
1714
|
+
// owner in this isolate (the pre-bundler included) instead of
|
|
1715
|
+
// stacking slices beside them. See `pendingBundles`.
|
|
1716
|
+
//
|
|
1717
|
+
// The shared promise resolves to a Response nobody consumes
|
|
1718
|
+
// directly: a Response body is readable once, so every coalesced
|
|
1719
|
+
// consumer — the initiator included — takes its own clone.
|
|
1766
1720
|
const inflight = this.pendingBundles.get(cacheKey);
|
|
1767
1721
|
if (inflight)
|
|
1768
|
-
return inflight;
|
|
1769
|
-
const coldPromise = this.
|
|
1722
|
+
return inflight.then((response) => response.clone());
|
|
1723
|
+
const coldPromise = this.serveModuleCold(specifier, headers, base, barrelInfo);
|
|
1770
1724
|
this.pendingBundles.set(cacheKey, coldPromise);
|
|
1771
|
-
|
|
1772
|
-
|
|
1773
|
-
|
|
1774
|
-
|
|
1775
|
-
|
|
1776
|
-
});
|
|
1777
|
-
return coldPromise;
|
|
1725
|
+
// Drop the coalescing entry once settled. Subsequent requests
|
|
1726
|
+
// for the same spec will hit the moduleCache (set inside the
|
|
1727
|
+
// cold path) on the hot path, not re-enter the slow path.
|
|
1728
|
+
coldPromise.then(() => this.pendingBundles.delete(cacheKey), () => this.pendingBundles.delete(cacheKey));
|
|
1729
|
+
return coldPromise.then((response) => response.clone());
|
|
1778
1730
|
}
|
|
1779
1731
|
/**
|
|
1780
1732
|
* Cold path of serveModule: package resolution → on-demand facet
|
|
1781
1733
|
* bundle (synthetic-entry for barrels) → hard-error if bundle fails.
|
|
1782
1734
|
* NO CDN fallback (100% edge contract). Extracted so the coalescing
|
|
1783
|
-
*
|
|
1784
|
-
* the
|
|
1785
|
-
*
|
|
1786
|
-
*
|
|
1787
|
-
*
|
|
1788
|
-
* exactly once, right after the slice is built and before the facet
|
|
1789
|
-
* submit; bail-out paths that never build a slice simply never call it.
|
|
1735
|
+
* wrapper in serveModule() reads cleanly. The slice this body builds is
|
|
1736
|
+
* leased from the shared supervisor allocation budget for its worst
|
|
1737
|
+
* case before it is built, shrunk to its real size once built, and
|
|
1738
|
+
* released only after the facet result has been rewritten, cached and
|
|
1739
|
+
* wrapped in the Response — the pre-bundler's per-slice pattern.
|
|
1790
1740
|
*/
|
|
1791
|
-
async serveModuleCold(specifier, headers, base, knownBarrelInfo = null
|
|
1741
|
+
async serveModuleCold(specifier, headers, base, knownBarrelInfo = null) {
|
|
1792
1742
|
const JS_CT = 'application/javascript; charset=utf-8';
|
|
1793
1743
|
const cacheKey = this.ck(base, `@modules/${specifier}`);
|
|
1794
1744
|
// 3. On-demand bundle (cold path — resolve from node_modules, bundle via esbuild)
|
|
@@ -1797,12 +1747,13 @@ export class ViteDevServer {
|
|
|
1797
1747
|
// supervisor isolate. For large modules (lucide-react, ~18 MiB
|
|
1798
1748
|
// unpacked) that OOM'd the supervisor and surfaced as CF error
|
|
1799
1749
|
// 1101 on /preview/@modules/lucide-react, taking down the entire
|
|
1800
|
-
// preview. We now dispatch the bundle work to
|
|
1801
|
-
//
|
|
1802
|
-
// pre-
|
|
1750
|
+
// preview. We now dispatch the bundle work to the session's shared
|
|
1751
|
+
// esbuild IsolatePool — the same pool, isolate and 128 MiB heap the
|
|
1752
|
+
// install-time pre-bundler uses. Supervisor never bundles esbuild
|
|
1753
|
+
// for any path.
|
|
1803
1754
|
//
|
|
1804
|
-
// Falls back to in-supervisor esbuild ONLY if
|
|
1805
|
-
//
|
|
1755
|
+
// Falls back to in-supervisor esbuild ONLY if no bundle pool was
|
|
1756
|
+
// provided (legacy callers / tests).
|
|
1806
1757
|
const resolved = this.resolvePackage(specifier);
|
|
1807
1758
|
// Barrel packages (lucide-react, @phosphor-icons/react, react-icons,
|
|
1808
1759
|
// @mui/icons-material, …) ship hundreds/thousands of tiny re-export
|
|
@@ -1894,148 +1845,163 @@ export class ViteDevServer {
|
|
|
1894
1845
|
this.log('warn', `[vite-dev] synthesized entry for ${specifier} ` +
|
|
1895
1846
|
`(barrel: ${fileCount} files; ${names.size} static imports → tree-shaken bundle)`);
|
|
1896
1847
|
}
|
|
1897
|
-
|
|
1898
|
-
|
|
1899
|
-
|
|
1900
|
-
|
|
1901
|
-
|
|
1902
|
-
|
|
1903
|
-
|
|
1904
|
-
|
|
1905
|
-
|
|
1906
|
-
|
|
1907
|
-
|
|
1908
|
-
//
|
|
1909
|
-
//
|
|
1910
|
-
|
|
1911
|
-
|
|
1912
|
-
|
|
1913
|
-
|
|
1914
|
-
|
|
1915
|
-
|
|
1916
|
-
|
|
1917
|
-
|
|
1918
|
-
|
|
1919
|
-
|
|
1920
|
-
|
|
1921
|
-
|
|
1922
|
-
|
|
1923
|
-
|
|
1924
|
-
|
|
1848
|
+
// Held from before the slice is built until the Response wrapping
|
|
1849
|
+
// its bundle exists — see the method doc. Null on the legacy path.
|
|
1850
|
+
let sliceLease = null;
|
|
1851
|
+
try {
|
|
1852
|
+
if (onDemandPool) {
|
|
1853
|
+
// Facet path — supervisor stays at 0 esbuild bytes.
|
|
1854
|
+
try {
|
|
1855
|
+
const { buildSliceForSpecifierWithCap, prebundleOne, BUNDLER_VERSION, } = await import('../npm/pre-bundle-facet.js');
|
|
1856
|
+
const SLICE_CAP_BYTES = ON_DEMAND_SLICE_CAP_BYTES;
|
|
1857
|
+
const projDir = this.root;
|
|
1858
|
+
const nmDir = projDir + '/node_modules';
|
|
1859
|
+
// Lease the slice's worst-case supervisor footprint BEFORE it is
|
|
1860
|
+
// allocated. FIFO byte credit is what stops this slice from
|
|
1861
|
+
// stacking beside a pre-bundle slice, a streamed install write or
|
|
1862
|
+
// a VFS read that independently claimed the same shared-isolate
|
|
1863
|
+
// headroom. The pool was acquired above, so nothing this waits
|
|
1864
|
+
// on is waiting on us.
|
|
1865
|
+
sliceLease = await acquireSupervisorAllocation(SLICE_CAP_BYTES);
|
|
1866
|
+
let slice = null;
|
|
1867
|
+
if (synthetic && syntheticReferencedFiles) {
|
|
1868
|
+
// SCOPED slice: only the files the synthetic entry directly
|
|
1869
|
+
// references (+ transitive relative imports + package.json).
|
|
1870
|
+
// Skips the full package walk so icon-libraries with
|
|
1871
|
+
// thousands of files don't blow the 28 MiB cap.
|
|
1872
|
+
const scoped = buildScopedSliceForSynthetic(this.vfs, nmDir, pkgName, syntheticReferencedFiles);
|
|
1873
|
+
const built = {
|
|
1874
|
+
slice: scoped.entries,
|
|
1875
|
+
totalBytes: scoped.totalBytes,
|
|
1876
|
+
};
|
|
1877
|
+
try {
|
|
1878
|
+
const bytes = this.vfs.readFile(bundleEntryPath);
|
|
1879
|
+
const parentDir = bundleEntryPath.substring(0, bundleEntryPath.lastIndexOf('/'));
|
|
1880
|
+
built.slice.push({ path: '/' + parentDir.replace(/^\/+/, ''), isDir: true });
|
|
1881
|
+
built.slice.push({
|
|
1882
|
+
path: '/' + bundleEntryPath.replace(/^\/+/, ''),
|
|
1883
|
+
bytes,
|
|
1884
|
+
isDir: false,
|
|
1885
|
+
});
|
|
1886
|
+
built.totalBytes += bytes.length + bundleEntryPath.length;
|
|
1887
|
+
}
|
|
1888
|
+
catch (e) {
|
|
1889
|
+
this.log('error', '[vite-dev] synthetic entry unreadable for ' + specifier + ': ' + (e?.message || e));
|
|
1890
|
+
}
|
|
1891
|
+
slice = built;
|
|
1892
|
+
}
|
|
1893
|
+
else {
|
|
1894
|
+
slice = buildSliceForSpecifierWithCap(this.vfs, specifier, nmDir, SLICE_CAP_BYTES);
|
|
1925
1895
|
}
|
|
1926
|
-
|
|
1927
|
-
|
|
1896
|
+
if (slice) {
|
|
1897
|
+
// The real size is known now: give back the credit the slice
|
|
1898
|
+
// did not use so smaller owners can proceed beside it. The
|
|
1899
|
+
// lease only shrinks to a positive size no larger than itself.
|
|
1900
|
+
if (slice.totalBytes > 0 && slice.totalBytes < sliceLease.bytes) {
|
|
1901
|
+
sliceLease.shrinkTo(slice.totalBytes);
|
|
1902
|
+
}
|
|
1903
|
+
// Build the spec, then drop our supervisor-side handle to
|
|
1904
|
+
// the slice array immediately — `spec` is the only thing
|
|
1905
|
+
// that needs to keep it alive until the RPC structured-clone
|
|
1906
|
+
// completes. Mirrors the install-time runSlot pattern (see
|
|
1907
|
+
// commit 40cfc01); the lease above keeps every other budget
|
|
1908
|
+
// owner from allocating beside it until the Response exists.
|
|
1909
|
+
let spec = {
|
|
1910
|
+
specifier,
|
|
1911
|
+
entryPath: bundleEntryPath,
|
|
1912
|
+
externals,
|
|
1913
|
+
slice: slice.slice,
|
|
1914
|
+
bundlerVersion: BUNDLER_VERSION,
|
|
1915
|
+
// Base-neutral: the @modules bundle is persisted raw and shared
|
|
1916
|
+
// across mounts, so BASE_URL is fixed to '/' here (module URLs
|
|
1917
|
+
// get the per-request base applied at serve time, not baked in).
|
|
1918
|
+
define: this.defineFor(''),
|
|
1919
|
+
};
|
|
1920
|
+
slice = null;
|
|
1921
|
+
let result = null;
|
|
1922
|
+
try {
|
|
1923
|
+
result = await onDemandPool.submit(prebundleOne, spec);
|
|
1924
|
+
}
|
|
1925
|
+
finally {
|
|
1926
|
+
spec = null;
|
|
1927
|
+
}
|
|
1928
|
+
if (result && result.ok && result.esmCode) {
|
|
1929
|
+
bundled = result.esmCode;
|
|
1930
|
+
}
|
|
1931
|
+
else if (result && result.errorText) {
|
|
1932
|
+
this.log('error', '[vite-dev] facet bundle failed for ' + specifier + ': ' + result.errorText);
|
|
1933
|
+
}
|
|
1934
|
+
result = null;
|
|
1935
|
+
}
|
|
1936
|
+
else {
|
|
1937
|
+
this.log('error', '[vite-dev] slice walker exceeded cap for ' + specifier);
|
|
1928
1938
|
}
|
|
1929
|
-
slice = built;
|
|
1930
1939
|
}
|
|
1931
|
-
|
|
1932
|
-
|
|
1940
|
+
catch (e) {
|
|
1941
|
+
this.log('error', '[vite-dev] on-demand facet dispatch failed for ' + specifier + ': ' + (e?.message || e));
|
|
1933
1942
|
}
|
|
1934
|
-
|
|
1935
|
-
|
|
1936
|
-
|
|
1937
|
-
|
|
1938
|
-
|
|
1939
|
-
|
|
1940
|
-
|
|
1941
|
-
|
|
1942
|
-
|
|
1943
|
-
|
|
1944
|
-
|
|
1945
|
-
// commit 40cfc01) so peak supervisor heap during a flurry of
|
|
1946
|
-
// /preview/@modules/* requests stays bounded by the gate.
|
|
1947
|
-
let spec = {
|
|
1948
|
-
specifier,
|
|
1949
|
-
entryPath: bundleEntryPath,
|
|
1950
|
-
externals,
|
|
1951
|
-
slice: slice.slice,
|
|
1952
|
-
bundlerVersion: BUNDLER_VERSION,
|
|
1953
|
-
// Base-neutral: the @modules bundle is persisted raw and shared
|
|
1954
|
-
// across mounts, so BASE_URL is fixed to '/' here (module URLs
|
|
1955
|
-
// get the per-request base applied at serve time, not baked in).
|
|
1943
|
+
}
|
|
1944
|
+
else {
|
|
1945
|
+
// Legacy fallback — in-supervisor esbuild. Used only when no
|
|
1946
|
+
// bundle pool was provided.
|
|
1947
|
+
try {
|
|
1948
|
+
const result = await this.esbuild.build([bundleEntryPath], {
|
|
1949
|
+
bundle: true,
|
|
1950
|
+
format: 'esm',
|
|
1951
|
+
platform: 'browser',
|
|
1952
|
+
target: 'esnext',
|
|
1953
|
+
// Base-neutral (see the pooled build above).
|
|
1956
1954
|
define: this.defineFor(''),
|
|
1957
|
-
|
|
1958
|
-
|
|
1959
|
-
|
|
1960
|
-
|
|
1961
|
-
result = await onDemandPool.submit(prebundleOne, spec);
|
|
1962
|
-
}
|
|
1963
|
-
finally {
|
|
1964
|
-
spec = null;
|
|
1965
|
-
}
|
|
1966
|
-
if (result && result.ok && result.esmCode) {
|
|
1967
|
-
bundled = result.esmCode;
|
|
1968
|
-
}
|
|
1969
|
-
else if (result && result.errorText) {
|
|
1970
|
-
this.log('error', '[vite-dev] facet bundle failed for ' + specifier + ': ' + result.errorText);
|
|
1955
|
+
external: externals.length > 0 ? externals : undefined,
|
|
1956
|
+
});
|
|
1957
|
+
if (result.outputFiles?.length) {
|
|
1958
|
+
bundled = result.outputFiles[0].contents;
|
|
1971
1959
|
}
|
|
1972
|
-
result = null;
|
|
1973
1960
|
}
|
|
1974
|
-
|
|
1975
|
-
this.log('error', '[vite-dev]
|
|
1961
|
+
catch (e) {
|
|
1962
|
+
this.log('error', '[vite-dev] esbuild bundle failed for ' + specifier + ': ' + (e?.message || e));
|
|
1976
1963
|
}
|
|
1977
1964
|
}
|
|
1978
|
-
|
|
1979
|
-
|
|
1980
|
-
|
|
1981
|
-
|
|
1982
|
-
|
|
1983
|
-
|
|
1984
|
-
|
|
1985
|
-
|
|
1986
|
-
|
|
1987
|
-
|
|
1988
|
-
|
|
1989
|
-
|
|
1990
|
-
|
|
1991
|
-
|
|
1992
|
-
|
|
1993
|
-
|
|
1994
|
-
|
|
1995
|
-
|
|
1996
|
-
|
|
1965
|
+
if (bundled !== null) {
|
|
1966
|
+
// Persist the RAW esbuild output. It is base-independent — the only
|
|
1967
|
+
// base-dependent step is the module-URL rewrite below, applied at
|
|
1968
|
+
// serve time — so one persisted bundle serves every mount (the
|
|
1969
|
+
// `/preview/` path and the `<port>--<sid>` host alike). Caching the
|
|
1970
|
+
// post-rewrite text instead would pin the bundle to whichever base
|
|
1971
|
+
// built it first and 404 the other. Cache ONLY successful bundles;
|
|
1972
|
+
// a failed build left `bundled` null and never reaches here.
|
|
1973
|
+
if (this.npmCache) {
|
|
1974
|
+
try {
|
|
1975
|
+
this.npmCache.putEsmBundle({
|
|
1976
|
+
specifier,
|
|
1977
|
+
bundleHash: BUNDLER_VERSION,
|
|
1978
|
+
esmCode: bundled,
|
|
1979
|
+
builtAt: Date.now(),
|
|
1980
|
+
inputHash: barrelInfo?.inputHash ?? '',
|
|
1981
|
+
});
|
|
1982
|
+
}
|
|
1983
|
+
catch { /* non-fatal */ }
|
|
1997
1984
|
}
|
|
1998
|
-
|
|
1999
|
-
|
|
2000
|
-
|
|
1985
|
+
// Convert `__require("external")` calls (from CJS source with esbuild
|
|
1986
|
+
// externals) into ESM `import * as` + dispatch, and rewrite any bare
|
|
1987
|
+
// imports esbuild marked external so they carry the mount base.
|
|
1988
|
+
// Without the base prefix, `import X from "scheduler"` 404s.
|
|
1989
|
+
let code = rewriteExternalRequires(bundled, base);
|
|
1990
|
+
code = rewriteAllImports(code, this.aliases, base);
|
|
1991
|
+
// For CJS-only packages (react, react-dom), esbuild's __commonJS
|
|
1992
|
+
// wrapper only emits `export default` — named imports like
|
|
1993
|
+
// `import { createRoot } from "react-dom/client"` would fail. Statically
|
|
1994
|
+
// scan the bundled source for CJS export patterns and synthesize
|
|
1995
|
+
// named exports.
|
|
1996
|
+
code = synthesizeCjsNamedExports(code);
|
|
1997
|
+
this.moduleCache.set(cacheKey, { code, timestamp: Date.now(), inputHash: barrelInfo?.inputHash ?? '' });
|
|
1998
|
+
return new Response(code, {
|
|
1999
|
+
headers: { ...headers, 'Content-Type': JS_CT },
|
|
2000
|
+
});
|
|
2001
2001
|
}
|
|
2002
2002
|
}
|
|
2003
|
-
|
|
2004
|
-
|
|
2005
|
-
// base-dependent step is the module-URL rewrite below, applied at
|
|
2006
|
-
// serve time — so one persisted bundle serves every mount (the
|
|
2007
|
-
// `/preview/` path and the `<port>--<sid>` host alike). Caching the
|
|
2008
|
-
// post-rewrite text instead would pin the bundle to whichever base
|
|
2009
|
-
// built it first and 404 the other. Cache ONLY successful bundles;
|
|
2010
|
-
// a failed build left `bundled` null and never reaches here.
|
|
2011
|
-
if (this.npmCache) {
|
|
2012
|
-
try {
|
|
2013
|
-
this.npmCache.putEsmBundle({
|
|
2014
|
-
specifier,
|
|
2015
|
-
bundleHash: BUNDLER_VERSION,
|
|
2016
|
-
esmCode: bundled,
|
|
2017
|
-
builtAt: Date.now(),
|
|
2018
|
-
inputHash: barrelInfo?.inputHash ?? '',
|
|
2019
|
-
});
|
|
2020
|
-
}
|
|
2021
|
-
catch { /* non-fatal */ }
|
|
2022
|
-
}
|
|
2023
|
-
// Convert `__require("external")` calls (from CJS source with esbuild
|
|
2024
|
-
// externals) into ESM `import * as` + dispatch, and rewrite any bare
|
|
2025
|
-
// imports esbuild marked external so they carry the mount base.
|
|
2026
|
-
// Without the base prefix, `import X from "scheduler"` 404s.
|
|
2027
|
-
let code = rewriteExternalRequires(bundled, base);
|
|
2028
|
-
code = rewriteAllImports(code, this.aliases, base);
|
|
2029
|
-
// For CJS-only packages (react, react-dom), esbuild's __commonJS
|
|
2030
|
-
// wrapper only emits `export default` — named imports like
|
|
2031
|
-
// `import { createRoot } from "react-dom/client"` would fail. Statically
|
|
2032
|
-
// scan the bundled source for CJS export patterns and synthesize
|
|
2033
|
-
// named exports.
|
|
2034
|
-
code = synthesizeCjsNamedExports(code);
|
|
2035
|
-
this.moduleCache.set(cacheKey, { code, timestamp: Date.now(), inputHash: barrelInfo?.inputHash ?? '' });
|
|
2036
|
-
return new Response(code, {
|
|
2037
|
-
headers: { ...headers, 'Content-Type': JS_CT },
|
|
2038
|
-
});
|
|
2003
|
+
finally {
|
|
2004
|
+
sliceLease?.release();
|
|
2039
2005
|
}
|
|
2040
2006
|
// Bundle failed — fall through to the hard-error response below.
|
|
2041
2007
|
// Previously fell through to a CDN fallback (esm.sh) but that
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* wasm-image-digest.ts — the content key a wasm image is registered under.
|
|
3
|
+
*
|
|
4
|
+
* A launch stages every wasm image its program's closure holds as a
|
|
5
|
+
* module-map member, compiled by the loader, and registers it by VFS path
|
|
6
|
+
* AND by a digest of its bytes. The node-shims WebAssembly seam answers
|
|
7
|
+
* `new WebAssembly.Module(bytes)` / `WebAssembly.compile(bytes)` with the
|
|
8
|
+
* compiled module when the bytes match a registered digest — whether the
|
|
9
|
+
* program read them off the filesystem, inlined them as base64 in its own
|
|
10
|
+
* source, or received them some other way. The key is what wasm IS, not how
|
|
11
|
+
* it arrived.
|
|
12
|
+
*
|
|
13
|
+
* Length and FNV-1a over every byte. Synchronous because
|
|
14
|
+
* `new WebAssembly.Module(bytes)` is, and SubtleCrypto is not. Duplicated in
|
|
15
|
+
* node-shims.ts (`__nimbusWasmDigest`) because that copy runs inside a facet
|
|
16
|
+
* with no imports; both must compute the same value, which a unit test pins.
|
|
17
|
+
*/
|
|
18
|
+
export declare function wasmImageDigest(bytes: Uint8Array): string;
|
|
19
|
+
/** One wasm image a launch registers: where the program reads it, and its content key. */
|
|
20
|
+
export interface WasmImageRecord {
|
|
21
|
+
/** Absolute VFS path (leading slash). */
|
|
22
|
+
vfsPath: string;
|
|
23
|
+
digest: string;
|
|
24
|
+
}
|
|
25
|
+
//# sourceMappingURL=wasm-image-digest.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"wasm-image-digest.d.ts","sourceRoot":"","sources":["../../src/facets/wasm-image-digest.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,eAAe,CAAC,KAAK,EAAE,UAAU,GAAG,MAAM,CAOzD;AAED,0FAA0F;AAC1F,MAAM,WAAW,eAAe;IAC9B,yCAAyC;IACzC,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC;CAChB"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* wasm-image-digest.ts — the content key a wasm image is registered under.
|
|
3
|
+
*
|
|
4
|
+
* A launch stages every wasm image its program's closure holds as a
|
|
5
|
+
* module-map member, compiled by the loader, and registers it by VFS path
|
|
6
|
+
* AND by a digest of its bytes. The node-shims WebAssembly seam answers
|
|
7
|
+
* `new WebAssembly.Module(bytes)` / `WebAssembly.compile(bytes)` with the
|
|
8
|
+
* compiled module when the bytes match a registered digest — whether the
|
|
9
|
+
* program read them off the filesystem, inlined them as base64 in its own
|
|
10
|
+
* source, or received them some other way. The key is what wasm IS, not how
|
|
11
|
+
* it arrived.
|
|
12
|
+
*
|
|
13
|
+
* Length and FNV-1a over every byte. Synchronous because
|
|
14
|
+
* `new WebAssembly.Module(bytes)` is, and SubtleCrypto is not. Duplicated in
|
|
15
|
+
* node-shims.ts (`__nimbusWasmDigest`) because that copy runs inside a facet
|
|
16
|
+
* with no imports; both must compute the same value, which a unit test pins.
|
|
17
|
+
*/
|
|
18
|
+
export function wasmImageDigest(bytes) {
|
|
19
|
+
let hash = 0x811c9dc5;
|
|
20
|
+
for (let i = 0; i < bytes.length; i++) {
|
|
21
|
+
hash ^= bytes[i];
|
|
22
|
+
hash = Math.imul(hash, 0x01000193) >>> 0;
|
|
23
|
+
}
|
|
24
|
+
return bytes.length + ':' + hash.toString(16);
|
|
25
|
+
}
|