@nimbus-sh/worker 0.1.3 → 0.1.5
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/index.js +2 -2
- package/dist/loaders/loader-pool.d.ts +7 -0
- package/dist/loaders/loader-pool.d.ts.map +1 -1
- package/dist/loaders/loader-pool.js +3 -1
- package/dist/router/index.d.ts +1 -1
- package/dist/router/index.js +1 -1
- package/dist/runtime/clang-runner.d.ts +2 -2
- package/dist/runtime/clang-runner.d.ts.map +1 -1
- package/dist/runtime/clang-runner.js +63 -39
- package/dist/runtime/package-manager.d.ts +31 -0
- package/dist/runtime/package-manager.d.ts.map +1 -1
- package/dist/runtime/package-manager.js +132 -10
- package/dist/runtime/python-repl.d.ts +1 -0
- package/dist/runtime/python-repl.d.ts.map +1 -1
- package/dist/runtime/python-repl.js +8 -4
- package/dist/runtime/python-runner.d.ts.map +1 -1
- package/dist/runtime/python-runner.js +86 -82
- package/dist/session/init.d.ts.map +1 -1
- package/dist/session/init.js +49 -3
- package/dist/session/nimbus-session.d.ts +1 -0
- package/dist/session/nimbus-session.d.ts.map +1 -1
- package/dist/session/nimbus-session.js +49 -23
- package/dist/shell/unix-commands.d.ts.map +1 -1
- package/dist/shell/unix-commands.js +44 -39
- package/package.json +1 -1
- package/public/s/index.html +169 -7
package/README.md
CHANGED
|
@@ -67,7 +67,7 @@ export default createNimbusHandler({
|
|
|
67
67
|
```
|
|
68
68
|
|
|
69
69
|
`wrangler.jsonc` (use `@nimbus-sh/config` to generate, or adapt
|
|
70
|
-
`apps/
|
|
70
|
+
`apps/hosted-demo/wrangler.jsonc`):
|
|
71
71
|
|
|
72
72
|
```jsonc
|
|
73
73
|
{
|
|
@@ -246,7 +246,7 @@ export default createNimbusHandler({
|
|
|
246
246
|
|
|
247
247
|
## Required bindings
|
|
248
248
|
|
|
249
|
-
Every binding is load-bearing — see `apps/
|
|
249
|
+
Every binding is load-bearing — see `apps/hosted-demo/wrangler.jsonc` or
|
|
250
250
|
`@nimbus-sh/config` for the canonical set:
|
|
251
251
|
|
|
252
252
|
- `NIMBUS_SESSION` (Durable Object) — per-session SQLite state
|
package/dist/index.js
CHANGED
|
@@ -64,8 +64,8 @@ export function getCtxExports() {
|
|
|
64
64
|
return _getCtxExports();
|
|
65
65
|
}
|
|
66
66
|
// Worker default export — a `createNimbusHandler()` instance running in
|
|
67
|
-
// auto auth mode. The live demo and
|
|
67
|
+
// auto auth mode. The live demo and hosted-demo embedder are bit-identical
|
|
68
68
|
// from here on; the only difference is `NIMBUS_LEGACY_PUBLIC=1` env var
|
|
69
|
-
// (set on the live demo, unset for the
|
|
69
|
+
// (set on the live demo, unset for the hosted-demo) flipping auth.mode to
|
|
70
70
|
// 'legacy' inside the auto-resolver.
|
|
71
71
|
export default createNimbusHandler();
|
|
@@ -50,6 +50,13 @@ export interface NimbusLoaderPoolOptions {
|
|
|
50
50
|
* that don't need DO callbacks (e.g. a pure CPU compute pool).
|
|
51
51
|
*/
|
|
52
52
|
omitSupervisor?: boolean;
|
|
53
|
+
/**
|
|
54
|
+
* Loader cache scope. Defaults to `session`, which bakes the owning DO id
|
|
55
|
+
* into the loader key so stateful facets cannot leak bindings or globals
|
|
56
|
+
* across sessions. Use `global` only for stateless compute modules that do
|
|
57
|
+
* not receive a Supervisor binding and do not retain user state.
|
|
58
|
+
*/
|
|
59
|
+
cacheScope?: 'session' | 'global';
|
|
53
60
|
/**
|
|
54
61
|
* Override the `doId` baked into the auto-injected SUPERVISOR binding.
|
|
55
62
|
* Default: `ctx.id.toString()` (the DO that constructs the pool).
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"loader-pool.d.ts","sourceRoot":"","sources":["../../src/loaders/loader-pool.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AAeH,wDAAwD;AACxD,MAAM,WAAW,uBAAuB;IACtC,sDAAsD;IACtD,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,8CAA8C;IAC9C,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB;;;OAGG;IACH,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB;;;;OAIG;IACH,aAAa,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACxC;;;OAGG;IACH,GAAG,CAAC,EAAE,MAAM,CAAC;IACb;;;OAGG;IACH,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB;;;;;;;;;;;;;;;;OAgBG;IACH,sBAAsB,CAAC,EAAE,MAAM,CAAC;IAChC;;;;;;;;;;;;;;OAcG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB;;;;;;;;;;;;;;;;;;;;;;;;;;;OA2BG;IACH,WAAW,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,WAAW,CAAC,CAAC;CAC3C;AAED,qDAAqD;AACrD,MAAM,WAAW,uBAAuB;IACtC,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB;;;OAGG;IACH,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAClC;;;;;;;;;;;;;;;;;;;;;;;;;;;;OA4BG;IACH,WAAW,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,WAAW,CAAC,CAAC;CAC3C;AAED,oEAAoE;AACpE,MAAM,WAAW,sBAAuB,SAAQ,uBAAuB;IACrE,0EAA0E;IAC1E,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB;;;;;;OAMG;IACH,OAAO,CAAC,EAAE,OAAO,GAAG,MAAM,GAAG,MAAM,CAAC;CACrC;AAwBD;;;;;;;;;;;;;;;GAeG;AACH,qBAAa,gBAAgB;;IAC3B,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAe;IACtC,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAS;IACrC,OAAO,CAAC,QAAQ,CAAC,gBAAgB,CAAS;IAC1C,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAS;IACxC,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAS;IAC7B,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAsC;IAE/D,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAqB;IAC9C,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAS;IACtC;;;;;OAKG;IACH,OAAO,CAAC,QAAQ,CAAC,WAAW,CAOzB;IACH;;;;4DAIwD;IACxD,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAS;IAClC;;;;;;;;;OASG;IACH,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAS;gBAGjC,GAAG,EAAE,GAAG,EACR,GAAG,EAAE,kBAAkB,EACvB,IAAI,CAAC,EAAE,uBAAuB;
|
|
1
|
+
{"version":3,"file":"loader-pool.d.ts","sourceRoot":"","sources":["../../src/loaders/loader-pool.ts"],"names":[],"mappings":"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"}
|
|
@@ -109,7 +109,9 @@ export class NimbusLoaderPool {
|
|
|
109
109
|
// Include preamble in the cache-bucket key so changes to bundled helpers
|
|
110
110
|
// invalidate warm slots. Empty preamble → '0' suffix (stable).
|
|
111
111
|
this.preambleHash = this.preamble ? hashSource(this.preamble) : '0';
|
|
112
|
-
this.doIdShort =
|
|
112
|
+
this.doIdShort = opts?.cacheScope === 'global'
|
|
113
|
+
? 'global'
|
|
114
|
+
: ctx.id.toString().slice(0, 12);
|
|
113
115
|
// Materialise the wasm-modules table. Sanitise each name into a
|
|
114
116
|
// valid JS identifier for the static import binding; key collisions
|
|
115
117
|
// (e.g. 'esbuild.wasm' and 'esbuild_wasm' both sanitise to
|
package/dist/router/index.d.ts
CHANGED
|
@@ -29,7 +29,7 @@
|
|
|
29
29
|
* - Hooks let embedders observe lifecycle without forking the DO. They
|
|
30
30
|
* run alongside, never block (errors are caught + logged).
|
|
31
31
|
* - The default `createNimbusHandler()` (zero args) is the
|
|
32
|
-
* "ship-Nimbus-as-is" case — exactly what `apps/
|
|
32
|
+
* "ship-Nimbus-as-is" case — exactly what `apps/hosted-demo/` does.
|
|
33
33
|
*/
|
|
34
34
|
import { type NimbusSdkRouterConfig } from './remote-api.js';
|
|
35
35
|
export type { NimbusConfig as NimbusSdkConfig, NimbusRemoteApiConfig, NimbusRuntimePolicy, NimbusSandboxProfile, NimbusSdkRouterConfig, } from './remote-api.js';
|
package/dist/router/index.js
CHANGED
|
@@ -29,7 +29,7 @@
|
|
|
29
29
|
* - Hooks let embedders observe lifecycle without forking the DO. They
|
|
30
30
|
* run alongside, never block (errors are caught + logged).
|
|
31
31
|
* - The default `createNimbusHandler()` (zero args) is the
|
|
32
|
-
* "ship-Nimbus-as-is" case — exactly what `apps/
|
|
32
|
+
* "ship-Nimbus-as-is" case — exactly what `apps/hosted-demo/` does.
|
|
33
33
|
*/
|
|
34
34
|
import { generateSessionId, isValidSessionId, } from '../_shared/session-id.js';
|
|
35
35
|
import { parseSessionRoute, forwardToSession, renderInvalidSessionHtml, SESSION_ROUTE_PREFIX, LEGACY_PUBLIC_DO_SEGMENT, } from '../_shared/session-router.js';
|
|
@@ -19,8 +19,8 @@
|
|
|
19
19
|
* tiny .o = ~20 MiB.
|
|
20
20
|
*
|
|
21
21
|
* Sysroot subset extraction happens supervisor-side via a small ustar
|
|
22
|
-
* parser. The full
|
|
23
|
-
*
|
|
22
|
+
* parser. The full sysroot.tar is parsed once when the clang runtime
|
|
23
|
+
* warms for a session; compile/link calls reuse the filtered subsets.
|
|
24
24
|
*
|
|
25
25
|
* Dispatch stays direct: no sleeps, no caller-side retries, and no
|
|
26
26
|
* catch-and-continue around loader failures.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"clang-runner.d.ts","sourceRoot":"","sources":["../../src/runtime/clang-runner.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AAEH,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAC;AAC5D,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,sBAAsB,CAAC;AACtD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;
|
|
1
|
+
{"version":3,"file":"clang-runner.d.ts","sourceRoot":"","sources":["../../src/runtime/clang-runner.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AAEH,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAC;AAC5D,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,sBAAsB,CAAC;AACtD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;AAGzD,4DAA4D;AAC5D,wBAAgB,sBAAsB,CAAC,IAAI,EAAE;IAC3C,QAAQ,EAAE,YAAY,CAAC;IACvB,GAAG,EAAE,SAAS,CAAC;CAChB,GAAG,CAAC,QAAQ,EAAE,eAAe,EAAE,WAAW,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,SAAS,KAC7F,CAAC,GAAG,EAAE,GAAG,KAAK,OAAO,CAAC,MAAM,CAAC,CAyShC;AAgcD,eAAO,MAAM,qBAAqB,imXA4UjC,CAAC"}
|
|
@@ -19,8 +19,8 @@
|
|
|
19
19
|
* tiny .o = ~20 MiB.
|
|
20
20
|
*
|
|
21
21
|
* Sysroot subset extraction happens supervisor-side via a small ustar
|
|
22
|
-
* parser. The full
|
|
23
|
-
*
|
|
22
|
+
* parser. The full sysroot.tar is parsed once when the clang runtime
|
|
23
|
+
* warms for a session; compile/link calls reuse the filtered subsets.
|
|
24
24
|
*
|
|
25
25
|
* Dispatch stays direct: no sleeps, no caller-side retries, and no
|
|
26
26
|
* catch-and-continue around loader failures.
|
|
@@ -37,6 +37,7 @@ export function makeClangRunnerFactory(deps) {
|
|
|
37
37
|
const lldVfsPath = findFile('bin/wasm-ld');
|
|
38
38
|
const memfsVfsPath = findFile('share/clang/memfs.wasm');
|
|
39
39
|
const sysrootVfsPath = findFile('share/clang/sysroot.tar');
|
|
40
|
+
let runtimePromise = null;
|
|
40
41
|
return async function clangBinHandler(ctx) {
|
|
41
42
|
const argv = ctx.args || [];
|
|
42
43
|
const cwd = ctx.cwd || '/home/user';
|
|
@@ -66,8 +67,6 @@ export function makeClangRunnerFactory(deps) {
|
|
|
66
67
|
ctx.stderr.write(`${binName}: clang/wasm-ld missing from install\n`);
|
|
67
68
|
return 127;
|
|
68
69
|
}
|
|
69
|
-
const memfsBytes = vfs.readFile(memfsVfsPath);
|
|
70
|
-
const sysrootBytes = vfs.readFile(sysrootVfsPath);
|
|
71
70
|
// Parse argv: find input .c + output path.
|
|
72
71
|
const parsed = parseUserArgv(argv);
|
|
73
72
|
if (parsed.error) {
|
|
@@ -80,8 +79,6 @@ export function makeClangRunnerFactory(deps) {
|
|
|
80
79
|
ctx.stderr.write(`${binName}: direct wasm-ld invocation not yet wired (v1.2)\n`);
|
|
81
80
|
return 2;
|
|
82
81
|
}
|
|
83
|
-
// Parse sysroot.tar ONCE on supervisor side.
|
|
84
|
-
const sysroot = parseUstar(sysrootBytes);
|
|
85
82
|
// Validate all user-supplied source inputs exist in the user's
|
|
86
83
|
// session VFS. Collect their bytes for memfs population.
|
|
87
84
|
const userSourceFiles = {};
|
|
@@ -110,6 +107,24 @@ export function makeClangRunnerFactory(deps) {
|
|
|
110
107
|
ctx.stderr.write(`${binName}: no compilable / linkable inputs\n`);
|
|
111
108
|
return 1;
|
|
112
109
|
}
|
|
110
|
+
let runtime;
|
|
111
|
+
try {
|
|
112
|
+
if (!runtimePromise) {
|
|
113
|
+
runtimePromise = createClangFacetRuntime(facetMgr, {
|
|
114
|
+
clangVfsPath,
|
|
115
|
+
lldVfsPath,
|
|
116
|
+
memfsVfsPath,
|
|
117
|
+
sysrootVfsPath,
|
|
118
|
+
vfs,
|
|
119
|
+
});
|
|
120
|
+
}
|
|
121
|
+
runtime = await runtimePromise;
|
|
122
|
+
}
|
|
123
|
+
catch (e) {
|
|
124
|
+
runtimePromise = null;
|
|
125
|
+
ctx.stderr.write(`${binName}: clang runtime warm-up failed: ${e?.message || e}\n`);
|
|
126
|
+
return 1;
|
|
127
|
+
}
|
|
113
128
|
// Walk the user's cwd to gather headers (.h/.hpp/.hxx/.inc/...)
|
|
114
129
|
// and any sibling headers users typically expect to be visible
|
|
115
130
|
// to #include "..." resolution. Real clang/gcc auto-search the
|
|
@@ -122,10 +137,8 @@ export function makeClangRunnerFactory(deps) {
|
|
|
122
137
|
// are vastly under the cap.
|
|
123
138
|
const userIncludeBundle = collectIncludeBundle(vfs, cwd.replace(/^\/+/, ''));
|
|
124
139
|
// ── COMPILE PHASE ────────────────────────────────────────────
|
|
125
|
-
//
|
|
126
|
-
//
|
|
127
|
-
const compileSysroot = filterSysrootForCompile(sysroot);
|
|
128
|
-
const clangBytes = vfs.readFile(clangVfsPath);
|
|
140
|
+
// Reuse the warm clang/memfs pool and ship only the C-include
|
|
141
|
+
// subset plus user source/header files for this invocation.
|
|
129
142
|
// Build -I flag list. We pass each user -I path verbatim AND add
|
|
130
143
|
// an implicit '.' (cwd) for quote-form lookup. wasm-clang's -cc1
|
|
131
144
|
// mode does NOT add cwd to the quote search list by default
|
|
@@ -170,12 +183,9 @@ export function makeClangRunnerFactory(deps) {
|
|
|
170
183
|
// so sibling sources stay out of memfs (smaller payload, no
|
|
171
184
|
// surface for unintended cross-TU textual inclusion via -I.).
|
|
172
185
|
const oneSourceFile = { [src]: userSourceFiles[src] };
|
|
173
|
-
const compileResult = await dispatchClangFacet(
|
|
174
|
-
primaryName: 'clang',
|
|
175
|
-
primaryBytes: clangBytes,
|
|
176
|
-
memfsBytes,
|
|
186
|
+
const compileResult = await dispatchClangFacet(runtime.compile, {
|
|
177
187
|
sysrootFiles: {
|
|
178
|
-
...
|
|
188
|
+
...runtime.compile.sysrootFiles,
|
|
179
189
|
...oneSourceFile,
|
|
180
190
|
// User's headers from cwd tree (so quote-form #include
|
|
181
191
|
// resolves; this is the primary clang-include-fix payload).
|
|
@@ -235,9 +245,8 @@ export function makeClangRunnerFactory(deps) {
|
|
|
235
245
|
preBuiltBytesMap[lp] = userSourceFiles[lp];
|
|
236
246
|
}
|
|
237
247
|
// ── LINK PHASE ───────────────────────────────────────────────
|
|
238
|
-
//
|
|
239
|
-
|
|
240
|
-
const lldBytes = vfs.readFile(lldVfsPath);
|
|
248
|
+
// Reuse the warm wasm-ld/memfs pool and ship only the link
|
|
249
|
+
// sysroot subset plus object/archive inputs for this invocation.
|
|
241
250
|
const stackSize = 1024 * 1024;
|
|
242
251
|
// User-supplied -L paths and -l libraries flow through. The user
|
|
243
252
|
// -L paths point at user-VFS dirs; we currently don't ship user
|
|
@@ -270,11 +279,8 @@ export function makeClangRunnerFactory(deps) {
|
|
|
270
279
|
'-lclang_rt.builtins-wasm32',
|
|
271
280
|
'-o', parsed.outputPath,
|
|
272
281
|
];
|
|
273
|
-
const linkResult = await dispatchClangFacet(
|
|
274
|
-
|
|
275
|
-
primaryBytes: lldBytes,
|
|
276
|
-
memfsBytes,
|
|
277
|
-
sysrootFiles: { ...linkSysroot, ...objBytesMap, ...preBuiltBytesMap },
|
|
282
|
+
const linkResult = await dispatchClangFacet(runtime.link, {
|
|
283
|
+
sysrootFiles: { ...runtime.link.sysrootFiles, ...objBytesMap, ...preBuiltBytesMap },
|
|
278
284
|
argv: linkArgv,
|
|
279
285
|
outputPaths: [parsed.outputPath],
|
|
280
286
|
});
|
|
@@ -600,23 +606,45 @@ function filterSysrootForLink(all) {
|
|
|
600
606
|
}
|
|
601
607
|
return out;
|
|
602
608
|
}
|
|
603
|
-
async function
|
|
609
|
+
async function createClangFacetRuntime(facetMgr, args) {
|
|
610
|
+
if (!args.clangVfsPath || !args.lldVfsPath || !args.memfsVfsPath || !args.sysrootVfsPath) {
|
|
611
|
+
throw new Error('installed clang manifest is missing required files');
|
|
612
|
+
}
|
|
604
613
|
const toAB = (u8) => u8.buffer.slice(u8.byteOffset, u8.byteOffset + u8.byteLength);
|
|
614
|
+
const memfsBytes = args.vfs.readFile(args.memfsVfsPath);
|
|
615
|
+
const clangBytes = args.vfs.readFile(args.clangVfsPath);
|
|
616
|
+
const lldBytes = args.vfs.readFile(args.lldVfsPath);
|
|
617
|
+
const sysroot = parseUstar(args.vfs.readFile(args.sysrootVfsPath));
|
|
618
|
+
const { NimbusLoaderPool } = await import('../loaders/loader-pool.js');
|
|
619
|
+
const env = facetMgr.env;
|
|
620
|
+
const ctx = facetMgr.ctx;
|
|
621
|
+
const makeTarget = (primaryName, primaryBytes, sysrootFiles) => ({
|
|
622
|
+
primaryName,
|
|
623
|
+
sysrootFiles,
|
|
624
|
+
pool: new NimbusLoaderPool(env, ctx, {
|
|
625
|
+
tag: `clang-runner-${primaryName}`,
|
|
626
|
+
concurrency: 1,
|
|
627
|
+
omitSupervisor: true,
|
|
628
|
+
cacheScope: 'global',
|
|
629
|
+
preamble: CLANG_RUNNER_PREAMBLE,
|
|
630
|
+
wasmModules: {
|
|
631
|
+
'memfs.wasm': toAB(memfsBytes),
|
|
632
|
+
'primary.wasm': toAB(primaryBytes),
|
|
633
|
+
},
|
|
634
|
+
}),
|
|
635
|
+
});
|
|
636
|
+
return {
|
|
637
|
+
compile: makeTarget('clang', clangBytes, filterSysrootForCompile(sysroot)),
|
|
638
|
+
link: makeTarget('wasm-ld', lldBytes, filterSysrootForLink(sysroot)),
|
|
639
|
+
};
|
|
640
|
+
}
|
|
641
|
+
async function dispatchClangFacet(target, args) {
|
|
605
642
|
// Encode sysroot files as base64 for context ferrying. We do this on
|
|
606
643
|
// the supervisor to keep the facet preamble small and CPU-light.
|
|
607
644
|
const filesB64 = {};
|
|
608
645
|
for (const [path, bytes] of Object.entries(args.sysrootFiles)) {
|
|
609
646
|
filesB64[path] = uint8ToBase64(bytes);
|
|
610
647
|
}
|
|
611
|
-
const { NimbusLoaderPool } = await import('../loaders/loader-pool.js');
|
|
612
|
-
const env = facetMgr.env;
|
|
613
|
-
const ctx = facetMgr.ctx;
|
|
614
|
-
const pool = new NimbusLoaderPool(env, ctx, {
|
|
615
|
-
tag: `clang-runner-${args.primaryName}`,
|
|
616
|
-
concurrency: 1,
|
|
617
|
-
omitSupervisor: true,
|
|
618
|
-
preamble: CLANG_RUNNER_PREAMBLE,
|
|
619
|
-
});
|
|
620
648
|
const facetFn = async function clangFacetCall(inArgs) {
|
|
621
649
|
const wasmTable = globalThis.__NIMBUS_WASM || {};
|
|
622
650
|
const memfsMod = wasmTable['memfs.wasm'];
|
|
@@ -646,16 +674,12 @@ async function dispatchClangFacet(facetMgr, args) {
|
|
|
646
674
|
});
|
|
647
675
|
};
|
|
648
676
|
try {
|
|
649
|
-
const result = await pool.submit(facetFn, {
|
|
650
|
-
primaryName:
|
|
677
|
+
const result = await target.pool.submit(facetFn, {
|
|
678
|
+
primaryName: target.primaryName,
|
|
651
679
|
argv: args.argv,
|
|
652
680
|
filesB64,
|
|
653
681
|
outputPaths: args.outputPaths,
|
|
654
682
|
}, {
|
|
655
|
-
wasmModules: {
|
|
656
|
-
'memfs.wasm': toAB(args.memfsBytes),
|
|
657
|
-
'primary.wasm': toAB(args.primaryBytes),
|
|
658
|
-
},
|
|
659
683
|
timeoutMs: 300_000,
|
|
660
684
|
});
|
|
661
685
|
// Decode outputFiles from base64 → Uint8Array.
|
|
@@ -27,12 +27,31 @@
|
|
|
27
27
|
*/
|
|
28
28
|
import { type RuntimeCatalogEnv, type RuntimeManifest } from './runtime-catalog.js';
|
|
29
29
|
import type { SqliteVFS } from '../vfs/sqlite-vfs.js';
|
|
30
|
+
/** Minimal shell ctx shape we depend on (matches existing handlers). */
|
|
31
|
+
export interface ShellCtx {
|
|
32
|
+
args: string[];
|
|
33
|
+
env: Record<string, string>;
|
|
34
|
+
cwd: string;
|
|
35
|
+
stdout: {
|
|
36
|
+
write(s: string): void;
|
|
37
|
+
};
|
|
38
|
+
stderr: {
|
|
39
|
+
write(s: string): void;
|
|
40
|
+
};
|
|
41
|
+
}
|
|
30
42
|
/** Minimal shell-registry shape we depend on. */
|
|
31
43
|
export interface MinShellRegistry {
|
|
32
44
|
register(name: string, handler: (ctx: any) => Promise<number>): void;
|
|
33
45
|
unregister?(name: string): void;
|
|
34
46
|
resolve?(name: string): any;
|
|
35
47
|
}
|
|
48
|
+
export interface RuntimeWarmTarget {
|
|
49
|
+
name: string;
|
|
50
|
+
version: string;
|
|
51
|
+
root: string;
|
|
52
|
+
manifest: RuntimeManifest;
|
|
53
|
+
}
|
|
54
|
+
export type RuntimeWarmHook = (target: RuntimeWarmTarget, ctx: ShellCtx) => Promise<void>;
|
|
36
55
|
/** Runner-factory contract. Each registered runner produces a shell-
|
|
37
56
|
* command handler given the manifest + the installed root dir. The
|
|
38
57
|
* package manager invokes the factory at install-time + at boot-time
|
|
@@ -54,6 +73,17 @@ export interface RuntimeSummary {
|
|
|
54
73
|
sizeBytes: number;
|
|
55
74
|
license: string;
|
|
56
75
|
}
|
|
76
|
+
export interface RuntimeInstallTarget {
|
|
77
|
+
runtimeName: string;
|
|
78
|
+
versionOverride: string | null;
|
|
79
|
+
requestedName: string;
|
|
80
|
+
}
|
|
81
|
+
export interface RuntimeCommandHint {
|
|
82
|
+
command: string;
|
|
83
|
+
runtimeName: string;
|
|
84
|
+
installSpec: string;
|
|
85
|
+
}
|
|
86
|
+
export declare function createRuntimeCommandHintResolver(env: RuntimeCatalogEnv): (command: string) => Promise<RuntimeCommandHint | null>;
|
|
57
87
|
/** Compute the per-user install root for (name, version). Uses
|
|
58
88
|
* `process.env.HOME` if present; falls back to `/home/user`. */
|
|
59
89
|
export declare function installRoot(homeDir: string, name: string, version: string): string;
|
|
@@ -109,5 +139,6 @@ export declare function makeNimbusVerbHandler(deps: {
|
|
|
109
139
|
/** Returns `process.env.HOME` for the session. Computed by the
|
|
110
140
|
* caller (init.ts) from the shell env. */
|
|
111
141
|
getHome(): string;
|
|
142
|
+
warmRuntime?: RuntimeWarmHook;
|
|
112
143
|
}): (ctx: any) => Promise<number>;
|
|
113
144
|
//# sourceMappingURL=package-manager.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"package-manager.d.ts","sourceRoot":"","sources":["../../src/runtime/package-manager.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AAEH,OAAO,EAA0C,KAAK,iBAAiB,
|
|
1
|
+
{"version":3,"file":"package-manager.d.ts","sourceRoot":"","sources":["../../src/runtime/package-manager.ts"],"names":[],"mappings":"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"}
|
|
@@ -34,6 +34,98 @@ export function registerRunnerFactory(key, factory) {
|
|
|
34
34
|
export function getRegisteredRunners() {
|
|
35
35
|
return Object.keys(runnerFactories);
|
|
36
36
|
}
|
|
37
|
+
const RUNTIME_NAME_ALIASES = {
|
|
38
|
+
python3: 'python',
|
|
39
|
+
ruby3: 'ruby',
|
|
40
|
+
'wasm-ld': 'clang',
|
|
41
|
+
};
|
|
42
|
+
function splitRuntimeSpec(spec) {
|
|
43
|
+
const atIdx = spec.indexOf('@');
|
|
44
|
+
return {
|
|
45
|
+
name: atIdx >= 0 ? spec.slice(0, atIdx) : spec,
|
|
46
|
+
versionOverride: atIdx >= 0 ? spec.slice(atIdx + 1) : null,
|
|
47
|
+
};
|
|
48
|
+
}
|
|
49
|
+
async function resolveRuntimeInstallTarget(env, catalog, spec) {
|
|
50
|
+
const parsed = splitRuntimeSpec(spec);
|
|
51
|
+
const aliased = RUNTIME_NAME_ALIASES[parsed.name] ?? parsed.name;
|
|
52
|
+
if (catalog.runtimes[aliased]) {
|
|
53
|
+
return {
|
|
54
|
+
runtimeName: aliased,
|
|
55
|
+
versionOverride: parsed.versionOverride,
|
|
56
|
+
requestedName: parsed.name,
|
|
57
|
+
};
|
|
58
|
+
}
|
|
59
|
+
for (const [runtimeName, entry] of Object.entries(catalog.runtimes)) {
|
|
60
|
+
const version = entry.default;
|
|
61
|
+
const versionEntry = entry.versions[version];
|
|
62
|
+
if (!versionEntry)
|
|
63
|
+
continue;
|
|
64
|
+
try {
|
|
65
|
+
const manifest = await fetchManifest(env, versionEntry.manifest);
|
|
66
|
+
if (manifest.entrypoints.some((ep) => ep.binName === parsed.name)) {
|
|
67
|
+
return {
|
|
68
|
+
runtimeName,
|
|
69
|
+
versionOverride: parsed.versionOverride,
|
|
70
|
+
requestedName: parsed.name,
|
|
71
|
+
};
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
catch {
|
|
75
|
+
// A bad manifest should not prevent canonical catalog names from
|
|
76
|
+
// resolving; it only suppresses bin-name aliasing for that runtime.
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
return null;
|
|
80
|
+
}
|
|
81
|
+
export function createRuntimeCommandHintResolver(env) {
|
|
82
|
+
let hintsPromise = null;
|
|
83
|
+
const loadHints = async () => {
|
|
84
|
+
const catalog = await fetchCatalog(env);
|
|
85
|
+
const hints = new Map();
|
|
86
|
+
const add = (command, runtimeName) => {
|
|
87
|
+
if (!command || command.includes('/'))
|
|
88
|
+
return;
|
|
89
|
+
if (!hints.has(command)) {
|
|
90
|
+
hints.set(command, { command, runtimeName, installSpec: command });
|
|
91
|
+
}
|
|
92
|
+
};
|
|
93
|
+
for (const runtimeName of Object.keys(catalog.runtimes)) {
|
|
94
|
+
add(runtimeName, runtimeName);
|
|
95
|
+
}
|
|
96
|
+
for (const [alias, runtimeName] of Object.entries(RUNTIME_NAME_ALIASES)) {
|
|
97
|
+
if (catalog.runtimes[runtimeName])
|
|
98
|
+
add(alias, runtimeName);
|
|
99
|
+
}
|
|
100
|
+
for (const [runtimeName, entry] of Object.entries(catalog.runtimes)) {
|
|
101
|
+
const versionEntry = entry.versions[entry.default];
|
|
102
|
+
if (!versionEntry)
|
|
103
|
+
continue;
|
|
104
|
+
try {
|
|
105
|
+
const manifest = await fetchManifest(env, versionEntry.manifest);
|
|
106
|
+
for (const ep of manifest.entrypoints)
|
|
107
|
+
add(ep.binName, runtimeName);
|
|
108
|
+
}
|
|
109
|
+
catch {
|
|
110
|
+
// Hints are best-effort UX. Install itself still surfaces the
|
|
111
|
+
// manifest/catalog error through the normal package-manager path.
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
return hints;
|
|
115
|
+
};
|
|
116
|
+
return async (command) => {
|
|
117
|
+
if (!command || command.includes('/'))
|
|
118
|
+
return null;
|
|
119
|
+
if (!hintsPromise) {
|
|
120
|
+
hintsPromise = loadHints().catch((e) => {
|
|
121
|
+
hintsPromise = null;
|
|
122
|
+
throw e;
|
|
123
|
+
});
|
|
124
|
+
}
|
|
125
|
+
const hints = await hintsPromise;
|
|
126
|
+
return hints.get(command) ?? null;
|
|
127
|
+
};
|
|
128
|
+
}
|
|
37
129
|
/** Compute the per-user install root for (name, version). Uses
|
|
38
130
|
* `process.env.HOME` if present; falls back to `/home/user`. */
|
|
39
131
|
export function installRoot(homeDir, name, version) {
|
|
@@ -151,13 +243,13 @@ export async function ensureRuntimesProgrammatic(deps, specs, opts = {}) {
|
|
|
151
243
|
* `nimbus uninstall …`. Registered under the name `nimbus`.
|
|
152
244
|
*/
|
|
153
245
|
export function makeNimbusVerbHandler(deps) {
|
|
154
|
-
const { env, vfs, registry, getHome } = deps;
|
|
246
|
+
const { env, vfs, registry, getHome, warmRuntime } = deps;
|
|
155
247
|
return async function nimbus(ctx) {
|
|
156
248
|
const argv = ctx.args || [];
|
|
157
249
|
const verb = argv[0];
|
|
158
250
|
const rest = argv.slice(1);
|
|
159
251
|
if (verb === 'install') {
|
|
160
|
-
return runInstall(rest, ctx, { env, vfs, registry, getHome });
|
|
252
|
+
return runInstall(rest, ctx, { env, vfs, registry, getHome, warmRuntime });
|
|
161
253
|
}
|
|
162
254
|
if (verb === 'uninstall') {
|
|
163
255
|
return runUninstall(rest, ctx, { vfs, registry, getHome });
|
|
@@ -184,11 +276,7 @@ async function runInstall(args, ctx, deps) {
|
|
|
184
276
|
ctx.stderr.write('usage: nimbus install <name>[@<version>]\n');
|
|
185
277
|
return 2;
|
|
186
278
|
}
|
|
187
|
-
// Parse `<name>` or `<name>@<version>`.
|
|
188
279
|
const spec = positional[0];
|
|
189
|
-
const atIdx = spec.indexOf('@');
|
|
190
|
-
const name = atIdx >= 0 ? spec.slice(0, atIdx) : spec;
|
|
191
|
-
const versionOverride = atIdx >= 0 ? spec.slice(atIdx + 1) : null;
|
|
192
280
|
// Fetch catalog.
|
|
193
281
|
let catalog;
|
|
194
282
|
try {
|
|
@@ -198,13 +286,16 @@ async function runInstall(args, ctx, deps) {
|
|
|
198
286
|
ctx.stderr.write(`nimbus install: ${e?.message || e}\n`);
|
|
199
287
|
return 1;
|
|
200
288
|
}
|
|
201
|
-
const
|
|
202
|
-
if (!
|
|
203
|
-
|
|
289
|
+
const target = await resolveRuntimeInstallTarget(deps.env, catalog, spec);
|
|
290
|
+
if (!target) {
|
|
291
|
+
const parsed = splitRuntimeSpec(spec);
|
|
292
|
+
ctx.stderr.write(`nimbus install: '${parsed.name}' is not in catalog\n`);
|
|
204
293
|
ctx.stderr.write(`nimbus install: try 'nimbus install --available' to see installable runtimes\n`);
|
|
205
294
|
return 1;
|
|
206
295
|
}
|
|
207
|
-
const
|
|
296
|
+
const name = target.runtimeName;
|
|
297
|
+
const runtimeEntry = catalog.runtimes[name];
|
|
298
|
+
const version = target.versionOverride || runtimeEntry.default;
|
|
208
299
|
const versionEntry = runtimeEntry.versions[version];
|
|
209
300
|
if (!versionEntry) {
|
|
210
301
|
ctx.stderr.write(`nimbus install: '${name}@${version}' not in catalog\n`);
|
|
@@ -219,6 +310,21 @@ async function runInstall(args, ctx, deps) {
|
|
|
219
310
|
ctx.stdout.write(`[${name}] already installed at ${root} (use --reinstall to refetch)\n`);
|
|
220
311
|
// Still re-register bins in case the registry lost them — idempotent.
|
|
221
312
|
rehydrateInstalledRuntimes(deps.vfs, deps.registry, home);
|
|
313
|
+
let manifest = null;
|
|
314
|
+
try {
|
|
315
|
+
manifest = JSON.parse(deps.vfs.readFileString(`${root}/manifest.json`));
|
|
316
|
+
}
|
|
317
|
+
catch {
|
|
318
|
+
manifest = null;
|
|
319
|
+
}
|
|
320
|
+
if (manifest) {
|
|
321
|
+
await warmRuntimeIfConfigured(ctx, deps, {
|
|
322
|
+
name,
|
|
323
|
+
version,
|
|
324
|
+
root,
|
|
325
|
+
manifest,
|
|
326
|
+
});
|
|
327
|
+
}
|
|
222
328
|
return 0;
|
|
223
329
|
}
|
|
224
330
|
// Fetch manifest from R2.
|
|
@@ -310,8 +416,24 @@ async function runInstall(args, ctx, deps) {
|
|
|
310
416
|
deps.registry.register(ep.binName, handler);
|
|
311
417
|
}
|
|
312
418
|
ctx.stdout.write(`[${name}] installed at ${root} (${(totalBytes / 1024 / 1024).toFixed(1)} MiB)\n`);
|
|
419
|
+
await warmRuntimeIfConfigured(ctx, deps, {
|
|
420
|
+
name,
|
|
421
|
+
version,
|
|
422
|
+
root,
|
|
423
|
+
manifest,
|
|
424
|
+
});
|
|
313
425
|
return 0;
|
|
314
426
|
}
|
|
427
|
+
async function warmRuntimeIfConfigured(ctx, deps, target) {
|
|
428
|
+
if (!deps.warmRuntime)
|
|
429
|
+
return;
|
|
430
|
+
try {
|
|
431
|
+
await deps.warmRuntime(target, ctx);
|
|
432
|
+
}
|
|
433
|
+
catch (e) {
|
|
434
|
+
ctx.stderr.write(`[${target.name}] warning: runtime warm-up failed: ${e?.message || e}\n`);
|
|
435
|
+
}
|
|
436
|
+
}
|
|
315
437
|
// ── --list ───────────────────────────────────────────────────────────
|
|
316
438
|
async function runList(ctx, deps) {
|
|
317
439
|
const home = deps.getHome();
|
|
@@ -62,4 +62,5 @@ export interface PythonReplDeps {
|
|
|
62
62
|
* runs `python` with no args.
|
|
63
63
|
*/
|
|
64
64
|
export declare function runPythonRepl(deps: PythonReplDeps): Promise<number>;
|
|
65
|
+
export declare function warmPythonRepl(deps: Pick<PythonReplDeps, 'facetMgr' | 'vfs' | 'installRoot'>): Promise<void>;
|
|
65
66
|
//# sourceMappingURL=python-repl.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"python-repl.d.ts","sourceRoot":"","sources":["../../src/runtime/python-repl.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AAEH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,sBAAsB,CAAC;AACtD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;AACzD,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAC;AAKlE,yDAAyD;AACzD,MAAM,WAAW,cAAc;IAC7B,QAAQ,EAAE,YAAY,CAAC;IACvB,GAAG,EAAE,SAAS,CAAC;IACf,QAAQ,EAAE,iBAAiB,CAAC;IAC5B,iFAAiF;IACjF,WAAW,EAAE,MAAM,CAAC;IACpB;;;;;;;;;;;;;;;OAeG;IACH,KAAK,CAAC,EAAE,GAAG,CAAC;CACb;
|
|
1
|
+
{"version":3,"file":"python-repl.d.ts","sourceRoot":"","sources":["../../src/runtime/python-repl.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AAEH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,sBAAsB,CAAC;AACtD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;AACzD,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAC;AAKlE,yDAAyD;AACzD,MAAM,WAAW,cAAc;IAC7B,QAAQ,EAAE,YAAY,CAAC;IACvB,GAAG,EAAE,SAAS,CAAC;IACf,QAAQ,EAAE,iBAAiB,CAAC;IAC5B,iFAAiF;IACjF,WAAW,EAAE,MAAM,CAAC;IACpB;;;;;;;;;;;;;;;OAeG;IACH,KAAK,CAAC,EAAE,GAAG,CAAC;CACb;AAuhBD;;;;;;GAMG;AACH,wBAAsB,aAAa,CAAC,IAAI,EAAE,cAAc,GAAG,OAAO,CAAC,MAAM,CAAC,CAOzE;AAED,wBAAsB,cAAc,CAClC,IAAI,EAAE,IAAI,CAAC,cAAc,EAAE,UAAU,GAAG,KAAK,GAAG,aAAa,CAAC,GAC7D,OAAO,CAAC,IAAI,CAAC,CAIf"}
|
|
@@ -153,14 +153,13 @@ class PythonReplAdapter {
|
|
|
153
153
|
concurrency: 1,
|
|
154
154
|
omitSupervisor: true,
|
|
155
155
|
preamble,
|
|
156
|
+
wasmModules: {
|
|
157
|
+
'pyodide.asm.wasm': toAB(wasmBytes),
|
|
158
|
+
},
|
|
156
159
|
});
|
|
157
|
-
// Stash the wasm bytes for first submit's wasmModules.
|
|
158
|
-
this.__wasmBytesAB = toAB(wasmBytes);
|
|
159
160
|
}
|
|
160
161
|
async submitFacetFn(args) {
|
|
161
|
-
const wasmModules = { 'pyodide.asm.wasm': this.__wasmBytesAB };
|
|
162
162
|
return await this.pool.submit(replStepFacetFn, args, {
|
|
163
|
-
wasmModules,
|
|
164
163
|
timeoutMs: 60_000,
|
|
165
164
|
});
|
|
166
165
|
}
|
|
@@ -560,3 +559,8 @@ export async function runPythonRepl(deps) {
|
|
|
560
559
|
const session = new ReplSession(adapter, deps.terminal, deps.shell);
|
|
561
560
|
return await session.run();
|
|
562
561
|
}
|
|
562
|
+
export async function warmPythonRepl(deps) {
|
|
563
|
+
const adapter = new PythonReplAdapter(deps);
|
|
564
|
+
await adapter.push('');
|
|
565
|
+
await adapter.close();
|
|
566
|
+
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"python-runner.d.ts","sourceRoot":"","sources":["../../src/runtime/python-runner.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AAEH,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAC;AAC5D,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,sBAAsB,CAAC;AACtD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;
|
|
1
|
+
{"version":3,"file":"python-runner.d.ts","sourceRoot":"","sources":["../../src/runtime/python-runner.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AAEH,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAC;AAC5D,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,sBAAsB,CAAC;AACtD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;AAGzD;;;;GAIG;AACH,wBAAgB,uBAAuB,CAAC,IAAI,EAAE;IAC5C,QAAQ,EAAE,YAAY,CAAC;IACvB,GAAG,EAAE,SAAS,CAAC;CAChB,GAAG,CAAC,QAAQ,EAAE,eAAe,EAAE,WAAW,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,SAAS,KAC7F,CAAC,GAAG,EAAE,GAAG,KAAK,OAAO,CAAC,MAAM,CAAC,CAuIhC;AA6ND;;;;;;GAMG;AAKH,wBAAgB,oBAAoB,CAAC,QAAQ,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,MAAM,CAyFhF"}
|