@nimbus-sh/worker 0.1.5 → 0.1.6
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 +37 -0
- package/dist/_shared/crypto.d.ts +15 -0
- package/dist/_shared/crypto.d.ts.map +1 -0
- package/dist/_shared/crypto.js +122 -0
- package/dist/facets/manager.d.ts +24 -0
- package/dist/facets/manager.d.ts.map +1 -1
- package/dist/facets/manager.js +279 -70
- package/dist/facets/process.d.ts +11 -2
- package/dist/facets/process.d.ts.map +1 -1
- package/dist/facets/process.js +187 -21
- package/dist/facets/vite-dev-server.d.ts +2 -0
- package/dist/facets/vite-dev-server.d.ts.map +1 -1
- package/dist/facets/vite-dev-server.js +39 -12
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -0
- package/dist/loaders/child-process/spawn-facet.d.ts +1 -3
- package/dist/loaders/child-process/spawn-facet.d.ts.map +1 -1
- package/dist/loaders/child-process/spawn-facet.js +1 -12
- package/dist/loaders/child-process/spawn-pool.d.ts +1 -1
- package/dist/loaders/child-process/spawn-pool.d.ts.map +1 -1
- package/dist/loaders/child-process/spawn-pool.js +1 -6
- package/dist/npm/installer.d.ts.map +1 -1
- package/dist/npm/installer.js +47 -27
- package/dist/npm/pre-bundle-facet.d.ts.map +1 -1
- package/dist/npm/pre-bundle-facet.js +2 -1
- package/dist/npm/resolve-one-facet.d.ts.map +1 -1
- package/dist/npm/resolve-one-facet.js +41 -13
- package/dist/npm/resolver.d.ts.map +1 -1
- package/dist/npm/resolver.js +70 -35
- package/dist/router/index.d.ts.map +1 -1
- package/dist/router/index.js +45 -21
- package/dist/router/remote-api.d.ts.map +1 -1
- package/dist/router/remote-api.js +29 -8
- package/dist/runtime/barrel-synthesizer.d.ts +7 -0
- package/dist/runtime/barrel-synthesizer.d.ts.map +1 -1
- package/dist/runtime/barrel-synthesizer.js +11 -0
- package/dist/runtime/clang-runner.d.ts.map +1 -1
- package/dist/runtime/clang-runner.js +1 -8
- package/dist/runtime/esbuild-service.d.ts +12 -5
- package/dist/runtime/esbuild-service.d.ts.map +1 -1
- package/dist/runtime/esbuild-service.js +28 -14
- package/dist/runtime/node-runner.d.ts +2 -0
- package/dist/runtime/node-runner.d.ts.map +1 -1
- package/dist/runtime/node-shims.d.ts +4 -2
- package/dist/runtime/node-shims.d.ts.map +1 -1
- package/dist/runtime/node-shims.js +404 -55
- package/dist/runtime/os-contracts.d.ts +128 -0
- package/dist/runtime/os-contracts.d.ts.map +1 -0
- package/dist/runtime/os-contracts.js +1 -0
- package/dist/runtime/package-manager.d.ts.map +1 -1
- package/dist/runtime/package-manager.js +32 -7
- package/dist/runtime/port-registry.d.ts +5 -0
- package/dist/runtime/port-registry.d.ts.map +1 -1
- package/dist/runtime/port-registry.js +22 -1
- package/dist/runtime/pyodide-runtime-assets.d.ts +19 -0
- package/dist/runtime/pyodide-runtime-assets.d.ts.map +1 -0
- package/dist/runtime/pyodide-runtime-assets.js +44 -0
- package/dist/runtime/python-repl.d.ts +3 -1
- package/dist/runtime/python-repl.d.ts.map +1 -1
- package/dist/runtime/python-repl.js +11 -29
- package/dist/runtime/python-runner.d.ts +8 -9
- package/dist/runtime/python-runner.d.ts.map +1 -1
- package/dist/runtime/python-runner.js +897 -61
- package/dist/runtime/python-socket-shim.d.ts +11 -0
- package/dist/runtime/python-socket-shim.d.ts.map +1 -0
- package/dist/runtime/python-socket-shim.js +526 -0
- package/dist/runtime/require-resolver.d.ts.map +1 -1
- package/dist/runtime/require-resolver.js +2 -11
- package/dist/runtime/ruby-gems.d.ts +25 -0
- package/dist/runtime/ruby-gems.d.ts.map +1 -0
- package/dist/runtime/ruby-gems.js +582 -0
- package/dist/runtime/ruby-runner.d.ts +2 -4
- package/dist/runtime/ruby-runner.d.ts.map +1 -1
- package/dist/runtime/ruby-runner.js +335 -34
- package/dist/runtime/runtime-catalog.d.ts +16 -4
- package/dist/runtime/runtime-catalog.d.ts.map +1 -1
- package/dist/runtime/runtime-catalog.js +21 -10
- package/dist/runtime/runtime-registry.d.ts +3 -0
- package/dist/runtime/runtime-registry.d.ts.map +1 -1
- package/dist/runtime/runtime-registry.js +4 -0
- package/dist/runtime/sqlite-runtime-fs-bridge.d.ts +43 -0
- package/dist/runtime/sqlite-runtime-fs-bridge.d.ts.map +1 -0
- package/dist/runtime/sqlite-runtime-fs-bridge.js +224 -0
- package/dist/runtime/static-server.d.ts +3 -0
- package/dist/runtime/static-server.d.ts.map +1 -0
- package/dist/runtime/static-server.js +121 -0
- package/dist/runtime/vfs-snapshot.d.ts +57 -0
- package/dist/runtime/vfs-snapshot.d.ts.map +1 -0
- package/dist/runtime/vfs-snapshot.js +141 -0
- package/dist/runtime/virtual-socket-kernel.d.ts +16 -0
- package/dist/runtime/virtual-socket-kernel.d.ts.map +1 -0
- package/dist/runtime/virtual-socket-kernel.js +360 -0
- package/dist/runtime/wasi-instance.d.ts +6 -3
- package/dist/runtime/wasi-instance.d.ts.map +1 -1
- package/dist/runtime/wasm-runner.d.ts +1 -25
- package/dist/runtime/wasm-runner.d.ts.map +1 -1
- package/dist/runtime/wasm-runner.js +1 -160
- package/dist/session/agent.d.ts +43 -0
- package/dist/session/agent.d.ts.map +1 -0
- package/dist/session/agent.js +1252 -0
- package/dist/session/init.d.ts.map +1 -1
- package/dist/session/init.js +15 -16
- package/dist/session/nimbus-session.d.ts +13 -2
- package/dist/session/nimbus-session.d.ts.map +1 -1
- package/dist/session/nimbus-session.js +55 -7
- package/dist/session/programmatic.d.ts +10 -0
- package/dist/session/programmatic.d.ts.map +1 -1
- package/dist/session/programmatic.js +121 -0
- package/dist/session/routes.d.ts.map +1 -1
- package/dist/session/routes.js +19 -1
- package/dist/session/rpc.d.ts +11 -0
- package/dist/session/rpc.d.ts.map +1 -1
- package/dist/session/rpc.js +56 -43
- package/dist/session/supervisor-rpc.d.ts +15 -0
- package/dist/session/supervisor-rpc.d.ts.map +1 -1
- package/dist/session/supervisor-rpc.js +32 -0
- package/dist/session/ws.d.ts +4 -3
- package/dist/session/ws.d.ts.map +1 -1
- package/dist/session/ws.js +11 -1
- package/dist/shell/unix-commands.js +12 -16
- package/dist/vfs/path.d.ts +8 -4
- package/dist/vfs/path.d.ts.map +1 -1
- package/dist/vfs/path.js +16 -4
- package/dist/vfs/sqlite-vfs.d.ts +2 -0
- package/dist/vfs/sqlite-vfs.d.ts.map +1 -1
- package/dist/vfs/sqlite-vfs.js +11 -0
- package/dist/vfs/symlink-registry.d.ts +7 -1
- package/dist/vfs/symlink-registry.d.ts.map +1 -1
- package/dist/vfs/symlink-registry.js +16 -11
- package/package.json +4 -1
- package/public/index.html +240 -0
- package/public/s/index.html +1172 -146
- package/runtime-contracts/pyodide-workerd-adapter.json +18 -0
- package/scripts/bundle-runtime.mjs +99 -24
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
{
|
|
2
|
+
"id": "pyodide-0.29.4-workerd-adapter-v1",
|
|
3
|
+
"pyodideVersion": "0.29.4",
|
|
4
|
+
"artifactPath": "share/pyodide/pyodide.asm.js",
|
|
5
|
+
"sentinel": "/* Nimbus Pyodide workerd adapter: pyodide-0.29.4-workerd-adapter-v1 */",
|
|
6
|
+
"patches": [
|
|
7
|
+
{
|
|
8
|
+
"name": "workerd-runtime-environment-fallback",
|
|
9
|
+
"find": "else throw new Error(\"Cannot determine runtime environment\")",
|
|
10
|
+
"replace": "else {/* Nimbus workerd adapter: browser-like runtime fallback */}"
|
|
11
|
+
},
|
|
12
|
+
{
|
|
13
|
+
"name": "workerd-main-thread-loader",
|
|
14
|
+
"find": "if(d.IN_BROWSER_MAIN_THREAD)",
|
|
15
|
+
"replace": "if(true||d.IN_BROWSER_MAIN_THREAD)"
|
|
16
|
+
}
|
|
17
|
+
]
|
|
18
|
+
}
|
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
* node scripts/bundle-runtime.mjs python 0.29.4 [--bucket nimbus-runtime-cache]
|
|
9
9
|
*
|
|
10
10
|
* Per `2026-05-10-true-os/plan.md` §2.4:
|
|
11
|
-
* - Blobs are content-addressed under `blobs/<name>-<version>/<file>`.
|
|
11
|
+
* - Blobs are content-addressed under `blobs/<name>-<version>/<sha256>/<file>`.
|
|
12
12
|
* - Per-version manifest at `manifests/<name>-<version>.json` lists
|
|
13
13
|
* the files (path-in-VFS, content R2 key, sha256, size, mode).
|
|
14
14
|
* - Top-level `catalog/v1.json` lists known runtimes.
|
|
@@ -31,7 +31,7 @@
|
|
|
31
31
|
*/
|
|
32
32
|
|
|
33
33
|
import { createHash } from 'node:crypto';
|
|
34
|
-
import { mkdirSync, readFileSync, writeFileSync, existsSync } from 'node:fs';
|
|
34
|
+
import { mkdirSync, readFileSync, writeFileSync, existsSync, rmSync } from 'node:fs';
|
|
35
35
|
import { execSync } from 'node:child_process';
|
|
36
36
|
import { tmpdir } from 'node:os';
|
|
37
37
|
import { basename, join } from 'node:path';
|
|
@@ -42,6 +42,9 @@ if (!ACCOUNT) {
|
|
|
42
42
|
process.exit(1);
|
|
43
43
|
}
|
|
44
44
|
const WRANGLER = './node_modules/.bin/wrangler';
|
|
45
|
+
const PYODIDE_WORKERD_ADAPTER = JSON.parse(
|
|
46
|
+
readFileSync(new URL('../runtime-contracts/pyodide-workerd-adapter.json', import.meta.url), 'utf8'),
|
|
47
|
+
);
|
|
45
48
|
|
|
46
49
|
const rawArgs = process.argv.slice(2);
|
|
47
50
|
const positionalArgs = [];
|
|
@@ -152,10 +155,11 @@ const SPECS = {
|
|
|
152
155
|
// user-VFS layout matches binji-clang's convention (bin/ for
|
|
153
156
|
// exec entry, share/<name>/ for runtime-private blobs).
|
|
154
157
|
{ src: 'pyodide.asm.wasm', vfs: 'share/pyodide/pyodide.asm.wasm' },
|
|
155
|
-
// The Emscripten JS half.
|
|
156
|
-
//
|
|
157
|
-
//
|
|
158
|
-
|
|
158
|
+
// The Emscripten JS half. Runtime sync adapts it once for
|
|
159
|
+
// workerd and records that contract in manifest metadata; the
|
|
160
|
+
// Python runner consumes the resulting artifact without patching
|
|
161
|
+
// it during session boot.
|
|
162
|
+
{ src: 'pyodide.asm.js', vfs: 'share/pyodide/pyodide.asm.js', transform: 'pyodide-workerd-adapter' },
|
|
159
163
|
// Python 3.13 stdlib. Pyodide writes this into its Emscripten
|
|
160
164
|
// MEMFS at /lib/python313.zip and CPython imports from there
|
|
161
165
|
// via the ZipImporter on sys.path.
|
|
@@ -255,6 +259,7 @@ if (!spec) {
|
|
|
255
259
|
}
|
|
256
260
|
|
|
257
261
|
const workDir = join(tmpdir(), `bundle-runtime-${RUNTIME}-${VERSION}`);
|
|
262
|
+
rmSync(workDir, { recursive: true, force: true });
|
|
258
263
|
mkdirSync(workDir, { recursive: true });
|
|
259
264
|
|
|
260
265
|
console.log(`[bundle-runtime] ${RUNTIME} ${VERSION}`);
|
|
@@ -308,9 +313,16 @@ for (const f of spec.files) {
|
|
|
308
313
|
execSync(`curl -sS -L -o "${local}" "${url}"`, { stdio: 'inherit' });
|
|
309
314
|
}
|
|
310
315
|
}
|
|
311
|
-
const
|
|
316
|
+
const sourceBytes = readFileSync(local);
|
|
317
|
+
const transformed = applyRuntimeTransform(f, sourceBytes);
|
|
318
|
+
if (transformed.bytes !== sourceBytes) {
|
|
319
|
+
writeFileSync(local, transformed.bytes);
|
|
320
|
+
console.log(`[bundle-runtime] transform ${f.src}: ${transformed.metadata.id}`);
|
|
321
|
+
}
|
|
322
|
+
const bytes = transformed.bytes;
|
|
312
323
|
const sha256 = createHash('sha256').update(bytes).digest('hex');
|
|
313
|
-
|
|
324
|
+
const r2Key = runtimeBlobKey(f.src, sha256);
|
|
325
|
+
downloaded.push({ ...f, local, bytes, sha256, size: bytes.length, r2Key, transformMetadata: transformed.metadata });
|
|
314
326
|
console.log(`[bundle-runtime] ${f.vfs} (← ${f.src}) → ${(bytes.length / 1024 / 1024).toFixed(2)} MiB sha256=${sha256.slice(0, 16)}…`);
|
|
315
327
|
}
|
|
316
328
|
|
|
@@ -323,22 +335,21 @@ if (!spec.ingest_only) {
|
|
|
323
335
|
const licenseSha256 = createHash('sha256').update(licenseBytes).digest('hex');
|
|
324
336
|
downloaded.push({
|
|
325
337
|
src: 'LICENSE', vfs: 'LICENSE', local: licenseLocal, bytes: licenseBytes,
|
|
326
|
-
sha256: licenseSha256, size: licenseBytes.length,
|
|
338
|
+
sha256: licenseSha256, size: licenseBytes.length, r2Key: runtimeBlobKey('LICENSE', licenseSha256),
|
|
327
339
|
});
|
|
328
340
|
console.log(`[bundle-runtime] LICENSE → ${licenseBytes.length} bytes sha256=${licenseSha256.slice(0, 16)}…`);
|
|
329
341
|
}
|
|
330
342
|
|
|
331
343
|
// ── 2. Upload each file as a content-addressed blob (deduped) ──────
|
|
332
|
-
// Content path: blobs/<name>-<version>/<src-name>. Multiple
|
|
333
|
-
// entries pointing at
|
|
334
|
-
const
|
|
344
|
+
// Content path: blobs/<name>-<version>/<sha256>/<src-name>. Multiple
|
|
345
|
+
// manifest entries pointing at identical content share one R2 upload.
|
|
346
|
+
const uploadedBlobKeys = new Set();
|
|
335
347
|
for (const f of downloaded) {
|
|
336
|
-
if (
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
console.log(`[bundle-runtime] put r2://${BUCKET}/${r2Key}`);
|
|
348
|
+
if (uploadedBlobKeys.has(f.r2Key)) continue;
|
|
349
|
+
uploadedBlobKeys.add(f.r2Key);
|
|
350
|
+
console.log(`[bundle-runtime] put r2://${BUCKET}/${f.r2Key}`);
|
|
340
351
|
execSync(
|
|
341
|
-
`CLOUDFLARE_ACCOUNT_ID=${ACCOUNT} ${WRANGLER} r2 object put ${BUCKET}/${r2Key} --file "${f.local}" --remote`,
|
|
352
|
+
`CLOUDFLARE_ACCOUNT_ID=${ACCOUNT} ${WRANGLER} r2 object put ${BUCKET}/${f.r2Key} --file "${f.local}" --remote`,
|
|
342
353
|
{ stdio: 'inherit' },
|
|
343
354
|
);
|
|
344
355
|
}
|
|
@@ -356,6 +367,16 @@ if (spec.ingest_only) {
|
|
|
356
367
|
console.log(`[bundle-runtime] catalog: UNCHANGED (swap wave will flip default)`);
|
|
357
368
|
} else {
|
|
358
369
|
// ── 3. Write the per-version manifest ────────────────────────────
|
|
370
|
+
const runtimeArtifacts = downloaded
|
|
371
|
+
.filter((f) => f.transformMetadata)
|
|
372
|
+
.map((f) => ({
|
|
373
|
+
path: f.vfs,
|
|
374
|
+
kind: f.transformMetadata.kind,
|
|
375
|
+
id: f.transformMetadata.id,
|
|
376
|
+
source_sha256: f.transformMetadata.source_sha256,
|
|
377
|
+
sha256: f.sha256,
|
|
378
|
+
}));
|
|
379
|
+
|
|
359
380
|
const manifest = {
|
|
360
381
|
name: RUNTIME,
|
|
361
382
|
version: VERSION,
|
|
@@ -364,7 +385,7 @@ if (spec.ingest_only) {
|
|
|
364
385
|
memfs_companion: spec.memfs_companion || null,
|
|
365
386
|
files: downloaded.map((f) => ({
|
|
366
387
|
path: f.vfs,
|
|
367
|
-
content:
|
|
388
|
+
content: f.r2Key,
|
|
368
389
|
sha256: f.sha256,
|
|
369
390
|
size: f.size,
|
|
370
391
|
...(f.mode ? { mode: f.mode } : {}),
|
|
@@ -377,6 +398,7 @@ if (spec.ingest_only) {
|
|
|
377
398
|
args: [],
|
|
378
399
|
...(f.kind ? { kind: f.kind } : {}),
|
|
379
400
|
})),
|
|
401
|
+
...(runtimeArtifacts.length ? { runtime_artifacts: runtimeArtifacts } : {}),
|
|
380
402
|
};
|
|
381
403
|
|
|
382
404
|
const manifestLocal = join(workDir, 'manifest.json');
|
|
@@ -403,16 +425,14 @@ if (spec.ingest_only) {
|
|
|
403
425
|
}
|
|
404
426
|
|
|
405
427
|
if (!catalog.runtimes[RUNTIME]) catalog.runtimes[RUNTIME] = { default: VERSION, versions: {} };
|
|
406
|
-
// Catalog size_bytes counts unique blob content
|
|
407
|
-
// manifest entries
|
|
408
|
-
// Pyodide P1 (05c4ce6), where `python` and `python3` share one
|
|
409
|
-
// BIN_MARKER blob.
|
|
428
|
+
// Catalog size_bytes counts unique blob content, not duplicate
|
|
429
|
+
// manifest entries.
|
|
410
430
|
const catalogSize = (() => {
|
|
411
431
|
const seen = new Set();
|
|
412
432
|
let total = 0;
|
|
413
433
|
for (const f of downloaded) {
|
|
414
|
-
if (seen.has(f.
|
|
415
|
-
seen.add(f.
|
|
434
|
+
if (seen.has(f.r2Key)) continue;
|
|
435
|
+
seen.add(f.r2Key);
|
|
416
436
|
total += f.size;
|
|
417
437
|
}
|
|
418
438
|
return total;
|
|
@@ -440,6 +460,61 @@ if (spec.ingest_only) {
|
|
|
440
460
|
console.log(`[bundle-runtime] catalog: r2://${BUCKET}/${catalogR2Key}`);
|
|
441
461
|
}
|
|
442
462
|
|
|
463
|
+
// ── Runtime transforms ───────────────────────────────────────────────
|
|
464
|
+
|
|
465
|
+
function runtimeBlobKey(src, sha256) {
|
|
466
|
+
return `blobs/${RUNTIME}-${VERSION}/${sha256}/${src}`;
|
|
467
|
+
}
|
|
468
|
+
|
|
469
|
+
function applyRuntimeTransform(fileSpec, sourceBytes) {
|
|
470
|
+
if (!fileSpec.transform) return { bytes: sourceBytes, metadata: null };
|
|
471
|
+
if (fileSpec.transform !== 'pyodide-workerd-adapter') {
|
|
472
|
+
throw new Error(`unknown transform '${fileSpec.transform}' for ${fileSpec.src}`);
|
|
473
|
+
}
|
|
474
|
+
const sourceSha256 = createHash('sha256').update(sourceBytes).digest('hex');
|
|
475
|
+
const sourceText = sourceBytes.toString('utf8');
|
|
476
|
+
const transformedText = applyPyodideWorkerdAdapter(sourceText, fileSpec.src);
|
|
477
|
+
const bytes = Buffer.from(transformedText, 'utf8');
|
|
478
|
+
return {
|
|
479
|
+
bytes,
|
|
480
|
+
metadata: {
|
|
481
|
+
kind: 'workerd-adapter',
|
|
482
|
+
id: PYODIDE_WORKERD_ADAPTER.id,
|
|
483
|
+
source_sha256: sourceSha256,
|
|
484
|
+
},
|
|
485
|
+
};
|
|
486
|
+
}
|
|
487
|
+
|
|
488
|
+
function applyPyodideWorkerdAdapter(sourceText, label) {
|
|
489
|
+
if (sourceText.startsWith(PYODIDE_WORKERD_ADAPTER.sentinel)) {
|
|
490
|
+
throw new Error(`${label} already contains ${PYODIDE_WORKERD_ADAPTER.id}; expected pristine upstream source`);
|
|
491
|
+
}
|
|
492
|
+
let out = sourceText;
|
|
493
|
+
for (const patch of PYODIDE_WORKERD_ADAPTER.patches) {
|
|
494
|
+
const matches = countOccurrences(out, patch.find);
|
|
495
|
+
if (matches !== 1) {
|
|
496
|
+
throw new Error(
|
|
497
|
+
`${label}: adapter ${PYODIDE_WORKERD_ADAPTER.id} expected exactly one ` +
|
|
498
|
+
`'${patch.name}' target, found ${matches}`,
|
|
499
|
+
);
|
|
500
|
+
}
|
|
501
|
+
out = out.replace(patch.find, patch.replace);
|
|
502
|
+
}
|
|
503
|
+
return `${PYODIDE_WORKERD_ADAPTER.sentinel}\n${out}`;
|
|
504
|
+
}
|
|
505
|
+
|
|
506
|
+
function countOccurrences(haystack, needle) {
|
|
507
|
+
if (!needle) return 0;
|
|
508
|
+
let count = 0;
|
|
509
|
+
let offset = 0;
|
|
510
|
+
while (true) {
|
|
511
|
+
const idx = haystack.indexOf(needle, offset);
|
|
512
|
+
if (idx < 0) return count;
|
|
513
|
+
count++;
|
|
514
|
+
offset = idx + needle.length;
|
|
515
|
+
}
|
|
516
|
+
}
|
|
517
|
+
|
|
443
518
|
// ── Repackage step (sysroot-prep wave) ──────────────────────────────
|
|
444
519
|
//
|
|
445
520
|
// Downloads an upstream `.tar.gz`, extracts it, and re-tars a subset of
|