@nimbus-sh/worker 0.1.4 → 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/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/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 +2 -2
- package/dist/runtime/clang-runner.d.ts.map +1 -1
- package/dist/runtime/clang-runner.js +64 -47
- 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 +31 -0
- package/dist/runtime/package-manager.d.ts.map +1 -1
- package/dist/runtime/package-manager.js +162 -15
- 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 -0
- package/dist/runtime/python-repl.d.ts.map +1 -1
- package/dist/runtime/python-repl.js +18 -32
- 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 +958 -118
- 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 +64 -19
- package/dist/session/nimbus-session.d.ts +14 -2
- package/dist/session/nimbus-session.d.ts.map +1 -1
- package/dist/session/nimbus-session.js +104 -30
- 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.d.ts.map +1 -1
- package/dist/shell/unix-commands.js +52 -51
- 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 +1316 -128
- package/runtime-contracts/pyodide-workerd-adapter.json +18 -0
- package/scripts/bundle-runtime.mjs +99 -24
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
import type { VfsEvent } from '../vfs/events.js';
|
|
2
|
+
export type RuntimeFileType = 'file' | 'directory' | 'symlink';
|
|
3
|
+
export interface RuntimeVfsStat {
|
|
4
|
+
type: RuntimeFileType;
|
|
5
|
+
size: number;
|
|
6
|
+
ctime: number;
|
|
7
|
+
mtime: number;
|
|
8
|
+
mode: number;
|
|
9
|
+
revision: number;
|
|
10
|
+
}
|
|
11
|
+
export interface RuntimeVfsDirEntry {
|
|
12
|
+
name: string;
|
|
13
|
+
type: RuntimeFileType;
|
|
14
|
+
}
|
|
15
|
+
export interface RuntimeOpenFlags {
|
|
16
|
+
read?: boolean;
|
|
17
|
+
write?: boolean;
|
|
18
|
+
append?: boolean;
|
|
19
|
+
create?: boolean;
|
|
20
|
+
truncate?: boolean;
|
|
21
|
+
followSymlinks?: boolean;
|
|
22
|
+
expectedRevision?: number;
|
|
23
|
+
}
|
|
24
|
+
export interface RuntimeFileHandle {
|
|
25
|
+
id: number;
|
|
26
|
+
path: string;
|
|
27
|
+
flags: Required<Omit<RuntimeOpenFlags, 'expectedRevision'>> & {
|
|
28
|
+
expectedRevision?: number;
|
|
29
|
+
};
|
|
30
|
+
position: number;
|
|
31
|
+
baseRevision: number;
|
|
32
|
+
closed: boolean;
|
|
33
|
+
}
|
|
34
|
+
export interface RuntimeFsBridge {
|
|
35
|
+
stat(path: string, options?: {
|
|
36
|
+
followSymlinks?: boolean;
|
|
37
|
+
}): Promise<RuntimeVfsStat | null>;
|
|
38
|
+
readFile(path: string, options?: {
|
|
39
|
+
followSymlinks?: boolean;
|
|
40
|
+
}): Promise<Uint8Array | null>;
|
|
41
|
+
writeFile(path: string, bytes: string | Uint8Array, options?: {
|
|
42
|
+
createParents?: boolean;
|
|
43
|
+
expectedRevision?: number;
|
|
44
|
+
}): Promise<void>;
|
|
45
|
+
open(path: string, flags: RuntimeOpenFlags): Promise<RuntimeFileHandle>;
|
|
46
|
+
read(handleId: number, offset: number | null, length: number): Promise<Uint8Array>;
|
|
47
|
+
write(handleId: number, offset: number | null, bytes: Uint8Array): Promise<number>;
|
|
48
|
+
close(handleId: number): Promise<void>;
|
|
49
|
+
readdir(path: string, options?: {
|
|
50
|
+
followSymlinks?: boolean;
|
|
51
|
+
}): Promise<RuntimeVfsDirEntry[]>;
|
|
52
|
+
mkdir(path: string, options?: {
|
|
53
|
+
recursive?: boolean;
|
|
54
|
+
mode?: number;
|
|
55
|
+
}): Promise<void>;
|
|
56
|
+
unlink(path: string): Promise<void>;
|
|
57
|
+
rmdir(path: string): Promise<void>;
|
|
58
|
+
rename(from: string, to: string): Promise<void>;
|
|
59
|
+
readlink(path: string): Promise<string | null>;
|
|
60
|
+
symlink(target: string, path: string): Promise<void>;
|
|
61
|
+
fsync(handleId?: number): Promise<void>;
|
|
62
|
+
revision(path?: string): Promise<number>;
|
|
63
|
+
subscribe?(path: string, listener: (event: VfsEvent) => void): () => void;
|
|
64
|
+
}
|
|
65
|
+
export interface RuntimeProcessBridge {
|
|
66
|
+
spawn(command: string, args: string[], options?: {
|
|
67
|
+
cwd?: string;
|
|
68
|
+
env?: Record<string, string>;
|
|
69
|
+
tty?: RuntimeTtyOptions;
|
|
70
|
+
}): Promise<{
|
|
71
|
+
pid: number;
|
|
72
|
+
}>;
|
|
73
|
+
writeStdin(pid: number, bytes: string | Uint8Array): Promise<void>;
|
|
74
|
+
endStdin(pid: number): Promise<void>;
|
|
75
|
+
kill(pid: number, signal?: string): Promise<void>;
|
|
76
|
+
wait(pid: number, timeoutMs?: number): Promise<{
|
|
77
|
+
exitCode: number | null;
|
|
78
|
+
}>;
|
|
79
|
+
}
|
|
80
|
+
export interface RuntimeTtyOptions {
|
|
81
|
+
stdinIsTTY?: boolean;
|
|
82
|
+
stdoutIsTTY?: boolean;
|
|
83
|
+
stderrIsTTY?: boolean;
|
|
84
|
+
columns?: number;
|
|
85
|
+
rows?: number;
|
|
86
|
+
raw?: boolean;
|
|
87
|
+
}
|
|
88
|
+
export interface RuntimePortBridge {
|
|
89
|
+
register(port: number, processId: number, handler: (request: Request) => Promise<Response>): Promise<void>;
|
|
90
|
+
unregister(port: number, processId?: number): Promise<void>;
|
|
91
|
+
list(): Promise<Array<{
|
|
92
|
+
port: number;
|
|
93
|
+
processId: number;
|
|
94
|
+
registeredAt: number;
|
|
95
|
+
}>>;
|
|
96
|
+
}
|
|
97
|
+
export type RuntimePackageAbi = 'javascript' | 'wasm32-wasi-nimbus' | 'pyodide' | 'ruby-wasm' | 'native-unsupported';
|
|
98
|
+
export interface RuntimeCommandProvider {
|
|
99
|
+
runtimeName: string;
|
|
100
|
+
version: string;
|
|
101
|
+
abi: RuntimePackageAbi;
|
|
102
|
+
commands: string[];
|
|
103
|
+
packageManagers?: string[];
|
|
104
|
+
libraries?: string[];
|
|
105
|
+
}
|
|
106
|
+
export type RuntimeDiagnosticEvent = {
|
|
107
|
+
type: 'fs-cache';
|
|
108
|
+
hit: boolean;
|
|
109
|
+
path: string;
|
|
110
|
+
bytes?: number;
|
|
111
|
+
revision?: number;
|
|
112
|
+
} | {
|
|
113
|
+
type: 'fs-flush';
|
|
114
|
+
path?: string;
|
|
115
|
+
bytes: number;
|
|
116
|
+
durationMs: number;
|
|
117
|
+
} | {
|
|
118
|
+
type: 'fs-invalidation';
|
|
119
|
+
path: string;
|
|
120
|
+
revision: number;
|
|
121
|
+
lagMs?: number;
|
|
122
|
+
} | {
|
|
123
|
+
type: 'unsupported-abi';
|
|
124
|
+
packageName?: string;
|
|
125
|
+
abi: string;
|
|
126
|
+
message: string;
|
|
127
|
+
};
|
|
128
|
+
//# sourceMappingURL=os-contracts.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"os-contracts.d.ts","sourceRoot":"","sources":["../../src/runtime/os-contracts.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -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,123 @@ 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
|
+
pip: 'python',
|
|
40
|
+
pip3: 'python',
|
|
41
|
+
ruby3: 'ruby',
|
|
42
|
+
gem: 'ruby',
|
|
43
|
+
bundle: 'ruby',
|
|
44
|
+
bundler: 'ruby',
|
|
45
|
+
'wasm-ld': 'clang',
|
|
46
|
+
};
|
|
47
|
+
function runtimeEntrypoints(manifest) {
|
|
48
|
+
const out = [...manifest.entrypoints];
|
|
49
|
+
const seen = new Set(out.map((ep) => ep.binName));
|
|
50
|
+
const add = (binName, runner, kind) => {
|
|
51
|
+
if (seen.has(binName))
|
|
52
|
+
return;
|
|
53
|
+
out.push({ binName, runner, kind, args: [] });
|
|
54
|
+
seen.add(binName);
|
|
55
|
+
};
|
|
56
|
+
if (manifest.name === 'python') {
|
|
57
|
+
add('pip', 'python-runner', 'pip');
|
|
58
|
+
add('pip3', 'python-runner', 'pip');
|
|
59
|
+
}
|
|
60
|
+
if (manifest.name === 'ruby') {
|
|
61
|
+
add('gem', 'ruby-runner', 'gem');
|
|
62
|
+
add('bundle', 'ruby-runner', 'bundle');
|
|
63
|
+
add('bundler', 'ruby-runner', 'bundle');
|
|
64
|
+
}
|
|
65
|
+
return out;
|
|
66
|
+
}
|
|
67
|
+
function splitRuntimeSpec(spec) {
|
|
68
|
+
const atIdx = spec.indexOf('@');
|
|
69
|
+
return {
|
|
70
|
+
name: atIdx >= 0 ? spec.slice(0, atIdx) : spec,
|
|
71
|
+
versionOverride: atIdx >= 0 ? spec.slice(atIdx + 1) : null,
|
|
72
|
+
};
|
|
73
|
+
}
|
|
74
|
+
async function resolveRuntimeInstallTarget(env, catalog, spec) {
|
|
75
|
+
const parsed = splitRuntimeSpec(spec);
|
|
76
|
+
const aliased = RUNTIME_NAME_ALIASES[parsed.name] ?? parsed.name;
|
|
77
|
+
if (catalog.runtimes[aliased]) {
|
|
78
|
+
return {
|
|
79
|
+
runtimeName: aliased,
|
|
80
|
+
versionOverride: parsed.versionOverride,
|
|
81
|
+
requestedName: parsed.name,
|
|
82
|
+
};
|
|
83
|
+
}
|
|
84
|
+
for (const [runtimeName, entry] of Object.entries(catalog.runtimes)) {
|
|
85
|
+
const version = entry.default;
|
|
86
|
+
const versionEntry = entry.versions[version];
|
|
87
|
+
if (!versionEntry)
|
|
88
|
+
continue;
|
|
89
|
+
try {
|
|
90
|
+
const manifest = await fetchManifest(env, versionEntry.manifest);
|
|
91
|
+
if (runtimeEntrypoints(manifest).some((ep) => ep.binName === parsed.name)) {
|
|
92
|
+
return {
|
|
93
|
+
runtimeName,
|
|
94
|
+
versionOverride: parsed.versionOverride,
|
|
95
|
+
requestedName: parsed.name,
|
|
96
|
+
};
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
catch {
|
|
100
|
+
// A bad manifest should not prevent canonical catalog names from
|
|
101
|
+
// resolving; it only suppresses bin-name aliasing for that runtime.
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
return null;
|
|
105
|
+
}
|
|
106
|
+
export function createRuntimeCommandHintResolver(env) {
|
|
107
|
+
let hintsPromise = null;
|
|
108
|
+
const loadHints = async () => {
|
|
109
|
+
const catalog = await fetchCatalog(env);
|
|
110
|
+
const hints = new Map();
|
|
111
|
+
const add = (command, runtimeName) => {
|
|
112
|
+
if (!command || command.includes('/'))
|
|
113
|
+
return;
|
|
114
|
+
if (!hints.has(command)) {
|
|
115
|
+
hints.set(command, { command, runtimeName, installSpec: command });
|
|
116
|
+
}
|
|
117
|
+
};
|
|
118
|
+
for (const runtimeName of Object.keys(catalog.runtimes)) {
|
|
119
|
+
add(runtimeName, runtimeName);
|
|
120
|
+
}
|
|
121
|
+
for (const [alias, runtimeName] of Object.entries(RUNTIME_NAME_ALIASES)) {
|
|
122
|
+
if (catalog.runtimes[runtimeName])
|
|
123
|
+
add(alias, runtimeName);
|
|
124
|
+
}
|
|
125
|
+
for (const [runtimeName, entry] of Object.entries(catalog.runtimes)) {
|
|
126
|
+
const versionEntry = entry.versions[entry.default];
|
|
127
|
+
if (!versionEntry)
|
|
128
|
+
continue;
|
|
129
|
+
try {
|
|
130
|
+
const manifest = await fetchManifest(env, versionEntry.manifest);
|
|
131
|
+
for (const ep of runtimeEntrypoints(manifest))
|
|
132
|
+
add(ep.binName, runtimeName);
|
|
133
|
+
}
|
|
134
|
+
catch {
|
|
135
|
+
// Hints are best-effort UX. Install itself still surfaces the
|
|
136
|
+
// manifest/catalog error through the normal package-manager path.
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
return hints;
|
|
140
|
+
};
|
|
141
|
+
return async (command) => {
|
|
142
|
+
if (!command || command.includes('/'))
|
|
143
|
+
return null;
|
|
144
|
+
if (!hintsPromise) {
|
|
145
|
+
hintsPromise = loadHints().catch((e) => {
|
|
146
|
+
hintsPromise = null;
|
|
147
|
+
throw e;
|
|
148
|
+
});
|
|
149
|
+
}
|
|
150
|
+
const hints = await hintsPromise;
|
|
151
|
+
return hints.get(command) ?? null;
|
|
152
|
+
};
|
|
153
|
+
}
|
|
37
154
|
/** Compute the per-user install root for (name, version). Uses
|
|
38
155
|
* `process.env.HOME` if present; falls back to `/home/user`. */
|
|
39
156
|
export function installRoot(homeDir, name, version) {
|
|
@@ -83,7 +200,7 @@ export function listInstalledManifests(vfs, homeDir) {
|
|
|
83
200
|
export function rehydrateInstalledRuntimes(vfs, registry, homeDir) {
|
|
84
201
|
const bins = [];
|
|
85
202
|
for (const { root, manifest } of listInstalledManifests(vfs, homeDir)) {
|
|
86
|
-
for (const ep of manifest
|
|
203
|
+
for (const ep of runtimeEntrypoints(manifest)) {
|
|
87
204
|
const factory = runnerFactories[ep.runner];
|
|
88
205
|
if (!factory)
|
|
89
206
|
continue; // runner not registered yet — skip
|
|
@@ -99,7 +216,7 @@ export function listInstalledRuntimes(vfs, homeDir) {
|
|
|
99
216
|
name: manifest.name,
|
|
100
217
|
version: manifest.version,
|
|
101
218
|
root,
|
|
102
|
-
bins: manifest.
|
|
219
|
+
bins: runtimeEntrypoints(manifest).map((e) => e.binName),
|
|
103
220
|
sizeBytes: manifest.files.reduce((a, f) => a + f.size, 0),
|
|
104
221
|
license: manifest.license,
|
|
105
222
|
}));
|
|
@@ -151,13 +268,13 @@ export async function ensureRuntimesProgrammatic(deps, specs, opts = {}) {
|
|
|
151
268
|
* `nimbus uninstall …`. Registered under the name `nimbus`.
|
|
152
269
|
*/
|
|
153
270
|
export function makeNimbusVerbHandler(deps) {
|
|
154
|
-
const { env, vfs, registry, getHome } = deps;
|
|
271
|
+
const { env, vfs, registry, getHome, warmRuntime } = deps;
|
|
155
272
|
return async function nimbus(ctx) {
|
|
156
273
|
const argv = ctx.args || [];
|
|
157
274
|
const verb = argv[0];
|
|
158
275
|
const rest = argv.slice(1);
|
|
159
276
|
if (verb === 'install') {
|
|
160
|
-
return runInstall(rest, ctx, { env, vfs, registry, getHome });
|
|
277
|
+
return runInstall(rest, ctx, { env, vfs, registry, getHome, warmRuntime });
|
|
161
278
|
}
|
|
162
279
|
if (verb === 'uninstall') {
|
|
163
280
|
return runUninstall(rest, ctx, { vfs, registry, getHome });
|
|
@@ -184,11 +301,7 @@ async function runInstall(args, ctx, deps) {
|
|
|
184
301
|
ctx.stderr.write('usage: nimbus install <name>[@<version>]\n');
|
|
185
302
|
return 2;
|
|
186
303
|
}
|
|
187
|
-
// Parse `<name>` or `<name>@<version>`.
|
|
188
304
|
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
305
|
// Fetch catalog.
|
|
193
306
|
let catalog;
|
|
194
307
|
try {
|
|
@@ -198,13 +311,16 @@ async function runInstall(args, ctx, deps) {
|
|
|
198
311
|
ctx.stderr.write(`nimbus install: ${e?.message || e}\n`);
|
|
199
312
|
return 1;
|
|
200
313
|
}
|
|
201
|
-
const
|
|
202
|
-
if (!
|
|
203
|
-
|
|
314
|
+
const target = await resolveRuntimeInstallTarget(deps.env, catalog, spec);
|
|
315
|
+
if (!target) {
|
|
316
|
+
const parsed = splitRuntimeSpec(spec);
|
|
317
|
+
ctx.stderr.write(`nimbus install: '${parsed.name}' is not in catalog\n`);
|
|
204
318
|
ctx.stderr.write(`nimbus install: try 'nimbus install --available' to see installable runtimes\n`);
|
|
205
319
|
return 1;
|
|
206
320
|
}
|
|
207
|
-
const
|
|
321
|
+
const name = target.runtimeName;
|
|
322
|
+
const runtimeEntry = catalog.runtimes[name];
|
|
323
|
+
const version = target.versionOverride || runtimeEntry.default;
|
|
208
324
|
const versionEntry = runtimeEntry.versions[version];
|
|
209
325
|
if (!versionEntry) {
|
|
210
326
|
ctx.stderr.write(`nimbus install: '${name}@${version}' not in catalog\n`);
|
|
@@ -219,6 +335,21 @@ async function runInstall(args, ctx, deps) {
|
|
|
219
335
|
ctx.stdout.write(`[${name}] already installed at ${root} (use --reinstall to refetch)\n`);
|
|
220
336
|
// Still re-register bins in case the registry lost them — idempotent.
|
|
221
337
|
rehydrateInstalledRuntimes(deps.vfs, deps.registry, home);
|
|
338
|
+
let manifest = null;
|
|
339
|
+
try {
|
|
340
|
+
manifest = JSON.parse(deps.vfs.readFileString(`${root}/manifest.json`));
|
|
341
|
+
}
|
|
342
|
+
catch {
|
|
343
|
+
manifest = null;
|
|
344
|
+
}
|
|
345
|
+
if (manifest) {
|
|
346
|
+
await warmRuntimeIfConfigured(ctx, deps, {
|
|
347
|
+
name,
|
|
348
|
+
version,
|
|
349
|
+
root,
|
|
350
|
+
manifest,
|
|
351
|
+
});
|
|
352
|
+
}
|
|
222
353
|
return 0;
|
|
223
354
|
}
|
|
224
355
|
// Fetch manifest from R2.
|
|
@@ -300,7 +431,7 @@ async function runInstall(args, ctx, deps) {
|
|
|
300
431
|
});
|
|
301
432
|
await Promise.all(workers);
|
|
302
433
|
// Register entrypoints.
|
|
303
|
-
for (const ep of manifest
|
|
434
|
+
for (const ep of runtimeEntrypoints(manifest)) {
|
|
304
435
|
const factory = runnerFactories[ep.runner];
|
|
305
436
|
if (!factory) {
|
|
306
437
|
ctx.stderr.write(`[${name}] warning: runner '${ep.runner}' not registered; bin '${ep.binName}' will not be invokable\n`);
|
|
@@ -310,8 +441,24 @@ async function runInstall(args, ctx, deps) {
|
|
|
310
441
|
deps.registry.register(ep.binName, handler);
|
|
311
442
|
}
|
|
312
443
|
ctx.stdout.write(`[${name}] installed at ${root} (${(totalBytes / 1024 / 1024).toFixed(1)} MiB)\n`);
|
|
444
|
+
await warmRuntimeIfConfigured(ctx, deps, {
|
|
445
|
+
name,
|
|
446
|
+
version,
|
|
447
|
+
root,
|
|
448
|
+
manifest,
|
|
449
|
+
});
|
|
313
450
|
return 0;
|
|
314
451
|
}
|
|
452
|
+
async function warmRuntimeIfConfigured(ctx, deps, target) {
|
|
453
|
+
if (!deps.warmRuntime)
|
|
454
|
+
return;
|
|
455
|
+
try {
|
|
456
|
+
await deps.warmRuntime(target, ctx);
|
|
457
|
+
}
|
|
458
|
+
catch (e) {
|
|
459
|
+
ctx.stderr.write(`[${target.name}] warning: runtime warm-up failed: ${e?.message || e}\n`);
|
|
460
|
+
}
|
|
461
|
+
}
|
|
315
462
|
// ── --list ───────────────────────────────────────────────────────────
|
|
316
463
|
async function runList(ctx, deps) {
|
|
317
464
|
const home = deps.getHome();
|
|
@@ -323,7 +470,7 @@ async function runList(ctx, deps) {
|
|
|
323
470
|
ctx.stdout.write(`installed runtimes (${installed.length}):\n`);
|
|
324
471
|
for (const { root, manifest } of installed) {
|
|
325
472
|
const totalBytes = manifest.files.reduce((a, f) => a + f.size, 0);
|
|
326
|
-
const bins = manifest.
|
|
473
|
+
const bins = runtimeEntrypoints(manifest).map((e) => e.binName).join(', ');
|
|
327
474
|
ctx.stdout.write(` ${manifest.name}@${manifest.version} ${(totalBytes / 1024 / 1024).toFixed(1)} MiB bins=[${bins}] ${root}\n`);
|
|
328
475
|
}
|
|
329
476
|
return 0;
|
|
@@ -374,7 +521,7 @@ async function runUninstall(args, ctx, deps) {
|
|
|
374
521
|
}
|
|
375
522
|
for (const m of matches) {
|
|
376
523
|
// Unregister bins.
|
|
377
|
-
for (const ep of m.manifest
|
|
524
|
+
for (const ep of runtimeEntrypoints(m.manifest)) {
|
|
378
525
|
// We don't have a guaranteed `unregister`; bins shadowing is OK
|
|
379
526
|
// because boot-rehydration only re-registers what's still on disk.
|
|
380
527
|
if (typeof deps.registry.unregister === 'function') {
|
|
@@ -38,6 +38,9 @@ export interface PortEntry {
|
|
|
38
38
|
}
|
|
39
39
|
export declare class PortRegistry {
|
|
40
40
|
private ports;
|
|
41
|
+
private facetStubsByPid;
|
|
42
|
+
/** Remember the routeable facet stub for a running process. */
|
|
43
|
+
bindFacetStub(pid: number, facetStub: any): void;
|
|
41
44
|
/** Register a facet as listening on a port. */
|
|
42
45
|
register(port: number, pid: number, facetStub: any): void;
|
|
43
46
|
/** Unregister a port. */
|
|
@@ -46,6 +49,8 @@ export declare class PortRegistry {
|
|
|
46
49
|
unregisterByPid(pid: number): number;
|
|
47
50
|
/** Look up a port entry. */
|
|
48
51
|
get(port: number): PortEntry | undefined;
|
|
52
|
+
/** Attach a routeable facet stub to ports previously reserved by a PID. */
|
|
53
|
+
attachFacetStubByPid(pid: number, facetStub: any): number[];
|
|
49
54
|
/** Check if a port is registered. */
|
|
50
55
|
has(port: number): boolean;
|
|
51
56
|
/** Get all registered ports. */
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"port-registry.d.ts","sourceRoot":"","sources":["../../src/runtime/port-registry.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AAEH,MAAM,WAAW,SAAS;IACxB,IAAI,EAAE,MAAM,CAAC;IACb,GAAG,EAAE,MAAM,CAAC;IACZ;;;;OAIG;IACH,SAAS,EAAE,GAAG,CAAC;IACf,YAAY,EAAE,MAAM,CAAC;CACtB;AAED,qBAAa,YAAY;IACvB,OAAO,CAAC,KAAK,CAAgC;
|
|
1
|
+
{"version":3,"file":"port-registry.d.ts","sourceRoot":"","sources":["../../src/runtime/port-registry.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AAEH,MAAM,WAAW,SAAS;IACxB,IAAI,EAAE,MAAM,CAAC;IACb,GAAG,EAAE,MAAM,CAAC;IACZ;;;;OAIG;IACH,SAAS,EAAE,GAAG,CAAC;IACf,YAAY,EAAE,MAAM,CAAC;CACtB;AAED,qBAAa,YAAY;IACvB,OAAO,CAAC,KAAK,CAAgC;IAC7C,OAAO,CAAC,eAAe,CAA0B;IAEjD,+DAA+D;IAC/D,aAAa,CAAC,GAAG,EAAE,MAAM,EAAE,SAAS,EAAE,GAAG,GAAG,IAAI;IAMhD,+CAA+C;IAC/C,QAAQ,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,SAAS,EAAE,GAAG,GAAG,IAAI;IAKzD,yBAAyB;IACzB,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO;IAIjC,oDAAoD;IACpD,eAAe,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM;IAYpC,4BAA4B;IAC5B,GAAG,CAAC,IAAI,EAAE,MAAM,GAAG,SAAS,GAAG,SAAS;IAIxC,2EAA2E;IAC3E,oBAAoB,CAAC,GAAG,EAAE,MAAM,EAAE,SAAS,EAAE,GAAG,GAAG,MAAM,EAAE;IAU3D,qCAAqC;IACrC,GAAG,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO;IAI1B,gCAAgC;IAChC,MAAM,IAAI,SAAS,EAAE;IAIrB;;;;;;;;;;;;;;;;;OAiBG;IACG,YAAY,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,QAAQ,GAAG,IAAI,CAAC;IA8F9F,IAAI,KAAK;;;;;;MAKR;CACF"}
|
|
@@ -27,9 +27,18 @@
|
|
|
27
27
|
*/
|
|
28
28
|
export class PortRegistry {
|
|
29
29
|
ports = new Map();
|
|
30
|
+
facetStubsByPid = new Map();
|
|
31
|
+
/** Remember the routeable facet stub for a running process. */
|
|
32
|
+
bindFacetStub(pid, facetStub) {
|
|
33
|
+
if (!facetStub)
|
|
34
|
+
return;
|
|
35
|
+
this.facetStubsByPid.set(pid, facetStub);
|
|
36
|
+
this.attachFacetStubByPid(pid, facetStub);
|
|
37
|
+
}
|
|
30
38
|
/** Register a facet as listening on a port. */
|
|
31
39
|
register(port, pid, facetStub) {
|
|
32
|
-
|
|
40
|
+
const routeableStub = facetStub || this.facetStubsByPid.get(pid) || null;
|
|
41
|
+
this.ports.set(port, { port, pid, facetStub: routeableStub, registeredAt: Date.now() });
|
|
33
42
|
}
|
|
34
43
|
/** Unregister a port. */
|
|
35
44
|
unregister(port) {
|
|
@@ -44,12 +53,24 @@ export class PortRegistry {
|
|
|
44
53
|
count++;
|
|
45
54
|
}
|
|
46
55
|
}
|
|
56
|
+
this.facetStubsByPid.delete(pid);
|
|
47
57
|
return count;
|
|
48
58
|
}
|
|
49
59
|
/** Look up a port entry. */
|
|
50
60
|
get(port) {
|
|
51
61
|
return this.ports.get(port);
|
|
52
62
|
}
|
|
63
|
+
/** Attach a routeable facet stub to ports previously reserved by a PID. */
|
|
64
|
+
attachFacetStubByPid(pid, facetStub) {
|
|
65
|
+
const ports = [];
|
|
66
|
+
for (const entry of this.ports.values()) {
|
|
67
|
+
if (entry.pid !== pid || entry.facetStub)
|
|
68
|
+
continue;
|
|
69
|
+
entry.facetStub = facetStub;
|
|
70
|
+
ports.push(entry.port);
|
|
71
|
+
}
|
|
72
|
+
return ports;
|
|
73
|
+
}
|
|
53
74
|
/** Check if a port is registered. */
|
|
54
75
|
has(port) {
|
|
55
76
|
return this.ports.has(port);
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import type { RuntimeManifest } from './runtime-catalog.js';
|
|
2
|
+
import type { SqliteVFS } from '../vfs/sqlite-vfs.js';
|
|
3
|
+
export interface PyodideRuntimeAssetPaths {
|
|
4
|
+
asmWasmVfs: string | null;
|
|
5
|
+
asmJsVfs: string | null;
|
|
6
|
+
stdlibVfs: string | null;
|
|
7
|
+
lockfileVfs: string | null;
|
|
8
|
+
manifest: RuntimeManifest;
|
|
9
|
+
vfs: SqliteVFS;
|
|
10
|
+
}
|
|
11
|
+
export interface PyodideRuntimeFiles {
|
|
12
|
+
asmWasmBytes: Uint8Array;
|
|
13
|
+
asmJsSrc: string;
|
|
14
|
+
stdlibB64: string;
|
|
15
|
+
lockfileText: string;
|
|
16
|
+
}
|
|
17
|
+
export declare function readPyodideRuntimeFiles(args: PyodideRuntimeAssetPaths): PyodideRuntimeFiles;
|
|
18
|
+
export declare function uint8ToBase64(u8: Uint8Array): string;
|
|
19
|
+
//# sourceMappingURL=pyodide-runtime-assets.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pyodide-runtime-assets.d.ts","sourceRoot":"","sources":["../../src/runtime/pyodide-runtime-assets.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAC;AAC5D,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,sBAAsB,CAAC;AAWtD,MAAM,WAAW,wBAAwB;IACvC,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,QAAQ,EAAE,eAAe,CAAC;IAC1B,GAAG,EAAE,SAAS,CAAC;CAChB;AAED,MAAM,WAAW,mBAAmB;IAClC,YAAY,EAAE,UAAU,CAAC;IACzB,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,MAAM,CAAC;IAClB,YAAY,EAAE,MAAM,CAAC;CACtB;AAED,wBAAgB,uBAAuB,CAAC,IAAI,EAAE,wBAAwB,GAAG,mBAAmB,CAoB3F;AA6BD,wBAAgB,aAAa,CAAC,EAAE,EAAE,UAAU,GAAG,MAAM,CAUpD"}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import pyodideWorkerdAdapter from '../../runtime-contracts/pyodide-workerd-adapter.json';
|
|
2
|
+
const WORKERD_ADAPTER = pyodideWorkerdAdapter;
|
|
3
|
+
export function readPyodideRuntimeFiles(args) {
|
|
4
|
+
if (!args.asmWasmVfs || !args.asmJsVfs || !args.stdlibVfs) {
|
|
5
|
+
throw new Error('installed Pyodide manifest is missing required files');
|
|
6
|
+
}
|
|
7
|
+
const asmWasmBytes = args.vfs.readFile(args.asmWasmVfs);
|
|
8
|
+
const asmJsSrc = new TextDecoder('utf-8').decode(args.vfs.readFile(args.asmJsVfs));
|
|
9
|
+
const stdlibBytes = args.vfs.readFile(args.stdlibVfs);
|
|
10
|
+
const lockfileText = args.lockfileVfs && args.vfs.exists(args.lockfileVfs)
|
|
11
|
+
? new TextDecoder('utf-8').decode(args.vfs.readFile(args.lockfileVfs))
|
|
12
|
+
: '{"packages":{}}';
|
|
13
|
+
assertPyodideWorkerdAdapter(args.manifest, asmJsSrc);
|
|
14
|
+
return {
|
|
15
|
+
asmWasmBytes,
|
|
16
|
+
asmJsSrc,
|
|
17
|
+
stdlibB64: uint8ToBase64(stdlibBytes),
|
|
18
|
+
lockfileText,
|
|
19
|
+
};
|
|
20
|
+
}
|
|
21
|
+
function assertPyodideWorkerdAdapter(manifest, asmJsSrc) {
|
|
22
|
+
const metadata = (manifest.runtime_artifacts || []).find((entry) => entry.path === WORKERD_ADAPTER.artifactPath && entry.kind === 'workerd-adapter');
|
|
23
|
+
if (!metadata) {
|
|
24
|
+
throw new Error(`pyodide.asm.js is missing Nimbus workerd adapter metadata (${WORKERD_ADAPTER.id}); ` +
|
|
25
|
+
`sync the python runtime and reinstall it with 'nimbus install python --reinstall'`);
|
|
26
|
+
}
|
|
27
|
+
if (metadata.id !== WORKERD_ADAPTER.id) {
|
|
28
|
+
throw new Error(`pyodide.asm.js adapter mismatch: installed ${metadata.id}, expected ${WORKERD_ADAPTER.id}`);
|
|
29
|
+
}
|
|
30
|
+
if (manifest.version !== WORKERD_ADAPTER.pyodideVersion) {
|
|
31
|
+
throw new Error(`Pyodide version mismatch: installed ${manifest.version}, expected ${WORKERD_ADAPTER.pyodideVersion}`);
|
|
32
|
+
}
|
|
33
|
+
if (!asmJsSrc.startsWith(WORKERD_ADAPTER.sentinel)) {
|
|
34
|
+
throw new Error(`pyodide.asm.js does not contain the Nimbus workerd adapter sentinel (${WORKERD_ADAPTER.id})`);
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
export function uint8ToBase64(u8) {
|
|
38
|
+
const chunk = 0x8000;
|
|
39
|
+
let s = '';
|
|
40
|
+
for (let i = 0; i < u8.length; i += chunk) {
|
|
41
|
+
s += String.fromCharCode.apply(null, Array.from(u8.subarray(i, Math.min(i + chunk, u8.length))));
|
|
42
|
+
}
|
|
43
|
+
return btoa(s);
|
|
44
|
+
}
|
|
@@ -29,6 +29,7 @@
|
|
|
29
29
|
import type { SqliteVFS } from '../vfs/sqlite-vfs.js';
|
|
30
30
|
import type { FacetManager } from '../facets/manager.js';
|
|
31
31
|
import type { WebSocketTerminal } from '../facets/ws-terminal.js';
|
|
32
|
+
import type { RuntimeManifest } from './runtime-catalog.js';
|
|
32
33
|
/** Inputs needed to bootstrap a Pyodide REPL session. */
|
|
33
34
|
export interface PythonReplDeps {
|
|
34
35
|
facetMgr: FacetManager;
|
|
@@ -36,6 +37,7 @@ export interface PythonReplDeps {
|
|
|
36
37
|
terminal: WebSocketTerminal;
|
|
37
38
|
/** Per-user-VFS install dir, e.g. 'home/user/.nimbus/runtimes/python/0.29.4'. */
|
|
38
39
|
installRoot: string;
|
|
40
|
+
manifest: RuntimeManifest;
|
|
39
41
|
/**
|
|
40
42
|
* REPL-R7-1 (2026-05-12): optional lifo-sh Shell reference.
|
|
41
43
|
*
|
|
@@ -62,4 +64,5 @@ export interface PythonReplDeps {
|
|
|
62
64
|
* runs `python` with no args.
|
|
63
65
|
*/
|
|
64
66
|
export declare function runPythonRepl(deps: PythonReplDeps): Promise<number>;
|
|
67
|
+
export declare function warmPythonRepl(deps: Pick<PythonReplDeps, 'facetMgr' | 'vfs' | 'installRoot' | 'manifest'>): Promise<void>;
|
|
65
68
|
//# 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;
|
|
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;AAElE,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAC;AAK5D,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,QAAQ,EAAE,eAAe,CAAC;IAC1B;;;;;;;;;;;;;;;OAeG;IACH,KAAK,CAAC,EAAE,GAAG,CAAC;CACb;AA8fD;;;;;;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,GAAG,UAAU,CAAC,GAC1E,OAAO,CAAC,IAAI,CAAC,CAIf"}
|