@nimbus-sh/worker 0.7.0 → 0.9.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/dist/facets/compose.d.ts +3 -0
- package/dist/facets/compose.d.ts.map +1 -1
- package/dist/facets/compose.js +1 -1
- package/dist/facets/manager.d.ts +26 -15
- package/dist/facets/manager.d.ts.map +1 -1
- package/dist/facets/manager.js +154 -112
- package/dist/facets/real-vite-hmr.d.ts +3 -1
- package/dist/facets/real-vite-hmr.d.ts.map +1 -1
- package/dist/facets/real-vite-hmr.js +18 -8
- package/dist/facets/ws-terminal.d.ts +9 -31
- package/dist/facets/ws-terminal.d.ts.map +1 -1
- package/dist/facets/ws-terminal.js +58 -51
- package/dist/hosted/commands.d.ts +12 -0
- package/dist/hosted/commands.d.ts.map +1 -0
- package/dist/hosted/commands.js +1647 -0
- package/dist/hosted/runtime.d.ts +135 -0
- package/dist/hosted/runtime.d.ts.map +1 -0
- package/dist/hosted/runtime.js +344 -0
- package/dist/hosted/services.d.ts +44 -0
- package/dist/hosted/services.d.ts.map +1 -0
- package/dist/hosted/services.js +522 -0
- package/dist/loaders/generated-workers.d.ts +1 -1
- package/dist/loaders/generated-workers.d.ts.map +1 -1
- package/dist/loaders/generated-workers.js +2 -2
- package/dist/node-shims-artifact.generated.js +3 -3
- package/dist/runtime/bash-repl.d.ts +6 -4
- package/dist/runtime/bash-repl.d.ts.map +1 -1
- package/dist/runtime/bash-repl.js +46 -7
- package/dist/runtime/bun-runner.js +1 -1
- package/dist/runtime/facet-loader-host.d.ts.map +1 -1
- package/dist/runtime/facet-loader-host.js +1 -3
- package/dist/runtime/node-runner.d.ts +1 -1
- package/dist/runtime/node-runner.d.ts.map +1 -1
- package/dist/runtime/node-runner.js +2 -2
- package/dist/runtime/node-shims.d.ts.map +1 -1
- package/dist/runtime/node-shims.js +14 -1
- package/dist/runtime/opencode-facet-runner.js +14 -14
- package/dist/runtime/package-manager.d.ts +35 -122
- package/dist/runtime/package-manager.d.ts.map +1 -1
- package/dist/runtime/package-manager.js +61 -596
- package/dist/runtime/process-logs-api.d.ts +1 -1
- package/dist/runtime/process-logs-api.d.ts.map +1 -1
- package/dist/runtime/process-logs-api.js +1 -1
- package/dist/runtime/python-repl.d.ts +6 -4
- package/dist/runtime/python-repl.d.ts.map +1 -1
- package/dist/runtime/python-repl.js +92 -67
- package/dist/runtime/repl-session.d.ts +9 -47
- package/dist/runtime/repl-session.d.ts.map +1 -1
- package/dist/runtime/repl-session.js +105 -105
- package/dist/runtime/ruby-repl.d.ts +3 -2
- package/dist/runtime/ruby-repl.d.ts.map +1 -1
- package/dist/runtime/ruby-repl.js +7 -6
- package/dist/runtime/runtime-catalog.d.ts +13 -0
- package/dist/runtime/runtime-catalog.d.ts.map +1 -1
- package/dist/runtime/runtime-catalog.js +88 -0
- package/dist/runtime/wasi/preamble.d.ts.map +1 -1
- package/dist/runtime/wasi/preamble.js +74 -56
- package/dist/runtime-catalog.generated.js +1 -1
- package/dist/session/agent.d.ts +1 -21
- package/dist/session/agent.d.ts.map +1 -1
- package/dist/session/ai.d.ts +5 -1
- package/dist/session/ai.d.ts.map +1 -1
- package/dist/session/ai.js +7 -0
- package/dist/session/hibernation.d.ts +2 -1
- package/dist/session/hibernation.d.ts.map +1 -1
- package/dist/session/hibernation.js +7 -4
- package/dist/session/init.d.ts +1 -36
- package/dist/session/init.d.ts.map +1 -1
- package/dist/session/init.js +18 -1773
- package/dist/session/loopback.d.ts +2 -29
- package/dist/session/loopback.d.ts.map +1 -1
- package/dist/session/loopback.js +3 -27
- package/dist/session/nimbus-session.d.ts +28 -34
- package/dist/session/nimbus-session.d.ts.map +1 -1
- package/dist/session/nimbus-session.js +78 -518
- package/dist/session/npm-install-port.d.ts +3 -1
- package/dist/session/npm-install-port.d.ts.map +1 -1
- package/dist/session/port-capability.d.ts.map +1 -1
- package/dist/session/port-capability.js +11 -1
- package/dist/session/programmatic.d.ts +5 -38
- package/dist/session/programmatic.d.ts.map +1 -1
- package/dist/session/programmatic.js +17 -49
- package/dist/session/rpc.d.ts +3 -43
- package/dist/session/rpc.d.ts.map +1 -1
- package/dist/session/rpc.js +8 -67
- package/dist/session/supervisor-op.d.ts +10 -5
- package/dist/session/supervisor-op.d.ts.map +1 -1
- package/dist/session/supervisor-op.js +21 -48
- package/dist/session/supervisor-rpc.d.ts +33 -16
- package/dist/session/supervisor-rpc.d.ts.map +1 -1
- package/dist/session/supervisor-rpc.js +49 -4
- package/dist/vfs/facet-resident-store.d.ts.map +1 -1
- package/dist/vfs/facet-resident-store.js +4 -2
- package/dist/workspace-host.d.ts +7 -0
- package/dist/workspace-host.d.ts.map +1 -0
- package/dist/workspace-host.js +5 -0
- package/dist/workspace.d.ts +2 -0
- package/dist/workspace.d.ts.map +1 -0
- package/dist/workspace.js +1 -0
- package/package.json +17 -12
- package/public/_assets/runtime/{node-shims-8f8c64edd2a1f0f5.js → node-shims-acaa037e6d26ec0d.js} +14 -1
- package/scripts/bundle-runtime.mjs +35 -8
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
import type { NimbusWorkspace } from '@nimbus-sh/core/workspace';
|
|
2
|
+
import type { PortRegistry } from '@nimbus-sh/core/runtime/port-registry.js';
|
|
3
|
+
import type { ProcessLogReadOptions } from '@nimbus-sh/core/runtime/process-logs.js';
|
|
4
|
+
import type { VfsCred } from '@nimbus-sh/core/runtime/os-contracts.js';
|
|
5
|
+
import type { SandboxFs } from '@nimbus-sh/core/substrate/lifo/sandbox/types.js';
|
|
6
|
+
import { type SupervisorOpEnvelope } from '@nimbus-sh/core/workspace/supervisor-op.js';
|
|
7
|
+
import type { FacetManagerHostHooks } from '../facets/compose.js';
|
|
8
|
+
import { WebSocketTerminal } from '../facets/ws-terminal.js';
|
|
9
|
+
import * as operations from '../session/programmatic.js';
|
|
10
|
+
import * as services from './services.js';
|
|
11
|
+
import { z } from 'zod/v4';
|
|
12
|
+
declare const HostedTask: z.ZodEnum<{
|
|
13
|
+
"resident-launch": "resident-launch";
|
|
14
|
+
"log-flush": "log-flush";
|
|
15
|
+
"log-janitor": "log-janitor";
|
|
16
|
+
}>;
|
|
17
|
+
export type HostedRuntimeTask = z.infer<typeof HostedTask>;
|
|
18
|
+
export interface HostedRuntimeLifecycle {
|
|
19
|
+
waitUntil(task: Promise<void>): void;
|
|
20
|
+
schedule(reason: HostedRuntimeTask, at: number): Promise<void>;
|
|
21
|
+
cancel(reason: HostedRuntimeTask): Promise<void>;
|
|
22
|
+
}
|
|
23
|
+
export interface HostedRuntimeOptions {
|
|
24
|
+
workspace: NimbusWorkspace;
|
|
25
|
+
ctx: DurableObjectState;
|
|
26
|
+
env: services.HostedRuntimeEnv;
|
|
27
|
+
ports: PortRegistry;
|
|
28
|
+
lifecycle: HostedRuntimeLifecycle;
|
|
29
|
+
resolveWorkerLaunch?: FacetManagerHostHooks['resolveWorkerLaunch'];
|
|
30
|
+
basePath?: string;
|
|
31
|
+
origin?: string;
|
|
32
|
+
}
|
|
33
|
+
export interface RuntimeFiles extends SandboxFs {
|
|
34
|
+
as(cred: VfsCred): RuntimeFiles;
|
|
35
|
+
}
|
|
36
|
+
export declare function composeHostedRuntime(options: HostedRuntimeOptions): Promise<{
|
|
37
|
+
workspace: NimbusWorkspace;
|
|
38
|
+
terminal: WebSocketTerminal;
|
|
39
|
+
files: RuntimeFiles;
|
|
40
|
+
runtimes: import("@nimbus-sh/core/runtime/runtime-manager.js").RuntimeManager;
|
|
41
|
+
ready: (options?: operations.ProgrammaticReadyOptions | undefined) => Promise<{
|
|
42
|
+
ok: true;
|
|
43
|
+
preinstalled: string[];
|
|
44
|
+
}>;
|
|
45
|
+
exec: (command: string, options?: operations.ProgrammaticExecOptions | undefined) => Promise<operations.ProgrammaticExecResult>;
|
|
46
|
+
runCode: (code: string, options?: (operations.ProgrammaticExecOptions & {
|
|
47
|
+
language?: "javascript" | "typescript" | "python" | "ruby" | "shell";
|
|
48
|
+
install?: "never" | "ifMissing";
|
|
49
|
+
}) | undefined) => Promise<operations.ProgrammaticExecResult>;
|
|
50
|
+
startProcess: (command: string, options?: operations.ProgrammaticExecOptions | undefined) => Promise<operations.ProgrammaticStartResult>;
|
|
51
|
+
listProcesses: () => Promise<operations.SerializedProcess[]>;
|
|
52
|
+
killProcess: (pid: number) => Promise<{
|
|
53
|
+
ok: boolean;
|
|
54
|
+
pid: number;
|
|
55
|
+
}>;
|
|
56
|
+
writeProcessInput: (pid: number, data: string) => Promise<{
|
|
57
|
+
ok: boolean;
|
|
58
|
+
pid: number;
|
|
59
|
+
}>;
|
|
60
|
+
endProcessInput: (pid: number) => Promise<{
|
|
61
|
+
ok: boolean;
|
|
62
|
+
pid: number;
|
|
63
|
+
}>;
|
|
64
|
+
resizeProcess: (pid: number, size: {
|
|
65
|
+
columns: number;
|
|
66
|
+
rows: number;
|
|
67
|
+
}) => Promise<{
|
|
68
|
+
ok: boolean;
|
|
69
|
+
pid: number;
|
|
70
|
+
}>;
|
|
71
|
+
signalProcess: (pid: number, signal: string) => Promise<{
|
|
72
|
+
ok: boolean;
|
|
73
|
+
pid: number;
|
|
74
|
+
}>;
|
|
75
|
+
processLogs: (pid: number, options?: ProcessLogReadOptions) => Promise<{
|
|
76
|
+
pid: number;
|
|
77
|
+
chunks: import("@nimbus-sh/core/runtime/process-logs.js").SequencedLogChunk[];
|
|
78
|
+
text: string;
|
|
79
|
+
cursor: number;
|
|
80
|
+
truncated: boolean;
|
|
81
|
+
exit: import("@nimbus-sh/core/runtime/process-logs.js").ProcessExitInfo | null;
|
|
82
|
+
}>;
|
|
83
|
+
listPorts: () => Promise<operations.SerializedPort[]>;
|
|
84
|
+
listApps: () => Promise<operations.ListedApp[]>;
|
|
85
|
+
ensureDurableApp: (input: {
|
|
86
|
+
owner: string;
|
|
87
|
+
preferredPort?: number;
|
|
88
|
+
visibility?: "scoped" | "public";
|
|
89
|
+
name?: string;
|
|
90
|
+
}) => Promise<{
|
|
91
|
+
port: number;
|
|
92
|
+
capability: string | null;
|
|
93
|
+
visibility: "scoped" | "public";
|
|
94
|
+
}>;
|
|
95
|
+
unexposePort: (port: number) => Promise<{
|
|
96
|
+
port: number;
|
|
97
|
+
ok: boolean;
|
|
98
|
+
}>;
|
|
99
|
+
removeDurableApp: (owner: string) => Promise<{
|
|
100
|
+
owner: string;
|
|
101
|
+
removed: boolean;
|
|
102
|
+
port: number | null;
|
|
103
|
+
}>;
|
|
104
|
+
exposeApp: (target: operations.AppTarget, options?: {
|
|
105
|
+
visibility?: "scoped" | "public";
|
|
106
|
+
name?: string;
|
|
107
|
+
} | undefined) => Promise<operations.ExposedAppResult>;
|
|
108
|
+
removeApp: (target: operations.AppTarget) => Promise<{
|
|
109
|
+
owner: string;
|
|
110
|
+
removed: boolean;
|
|
111
|
+
port: number | null;
|
|
112
|
+
}>;
|
|
113
|
+
rotateLink: (target: operations.AppTarget) => Promise<operations.ExposedAppResult>;
|
|
114
|
+
installRuntime: (spec: string, options?: {
|
|
115
|
+
force?: boolean;
|
|
116
|
+
} | undefined) => Promise<import("../runtime/package-manager.js").RuntimeInstallSummary>;
|
|
117
|
+
ensureRuntimes: (specs: string[], options?: {
|
|
118
|
+
force?: boolean;
|
|
119
|
+
} | undefined) => Promise<import("../runtime/package-manager.js").RuntimeInstallSummary[]>;
|
|
120
|
+
listRuntimes: () => Promise<{
|
|
121
|
+
installed: import("@nimbus-sh/core/runtime/installed-runtimes.js").RuntimeSummary[];
|
|
122
|
+
available: import("@nimbus-sh/core/runtime/runtime-package.js").RuntimeAvailability[];
|
|
123
|
+
}>;
|
|
124
|
+
spawnWorker: (workerCode: string, command: string, cwd: string, opts?: import("../facets/manager.js").LongRunningWorkerSpawnOptions | undefined) => Promise<import("../facets/manager.js").SpawnedWorker>;
|
|
125
|
+
routeCapabilityPort: (port: number, capability: string, request: Request<unknown, CfProperties<unknown>>, innerPath: string) => Promise<Response>;
|
|
126
|
+
supervisorOp: (envelope: SupervisorOpEnvelope) => Promise<unknown>;
|
|
127
|
+
onScheduled: (task: HostedRuntimeTask) => Promise<void>;
|
|
128
|
+
attachTerminal: (ws: WebSocket) => Promise<void>;
|
|
129
|
+
terminalFrame: (ws: WebSocket, message: string | ArrayBuffer) => Promise<void>;
|
|
130
|
+
terminalClose: (ws: WebSocket) => void;
|
|
131
|
+
close: () => Promise<void>;
|
|
132
|
+
}>;
|
|
133
|
+
export type HostedRuntime = Awaited<ReturnType<typeof composeHostedRuntime>>;
|
|
134
|
+
export {};
|
|
135
|
+
//# sourceMappingURL=runtime.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"runtime.d.ts","sourceRoot":"","sources":["../../src/hosted/runtime.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,2BAA2B,CAAC;AAEjE,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,0CAA0C,CAAC;AAC7E,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,yCAAyC,CAAC;AACrF,OAAO,KAAK,EAA6B,OAAO,EAAE,MAAM,yCAAyC,CAAC;AAIlG,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,iDAAiD,CAAC;AACjF,OAAO,EAAqD,KAAK,oBAAoB,EAAE,MAAM,4CAA4C,CAAC;AAE1I,OAAO,KAAK,EAAwB,qBAAqB,EAAE,MAAM,sBAAsB,CAAC;AASxF,OAAO,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAC;AAO7D,OAAO,KAAK,UAAU,MAAM,4BAA4B,CAAC;AACzD,OAAO,KAAK,QAAQ,MAAM,eAAe,CAAC;AAE1C,OAAO,EAAE,CAAC,EAAE,MAAM,QAAQ,CAAC;AAI3B,QAAA,MAAM,UAAU;;;;EAA0D,CAAC;AAC3E,MAAM,MAAM,iBAAiB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,UAAU,CAAC,CAAC;AAE3D,MAAM,WAAW,sBAAsB;IACrC,SAAS,CAAC,IAAI,EAAE,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC;IACrC,QAAQ,CAAC,MAAM,EAAE,iBAAiB,EAAE,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC/D,MAAM,CAAC,MAAM,EAAE,iBAAiB,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CAClD;AAED,MAAM,WAAW,oBAAoB;IACnC,SAAS,EAAE,eAAe,CAAC;IAC3B,GAAG,EAAE,kBAAkB,CAAC;IACxB,GAAG,EAAE,QAAQ,CAAC,gBAAgB,CAAC;IAC/B,KAAK,EAAE,YAAY,CAAC;IACpB,SAAS,EAAE,sBAAsB,CAAC;IAClC,mBAAmB,CAAC,EAAE,qBAAqB,CAAC,qBAAqB,CAAC,CAAC;IACnE,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,YAAa,SAAQ,SAAS;IAC7C,EAAE,CAAC,IAAI,EAAE,OAAO,GAAG,YAAY,CAAC;CACjC;AAqRD,wBAAsB,oBAAoB,CAAC,OAAO,EAAE,oBAAoB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;uBAkBjD,MAAM,YAAY,qBAAqB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;6BAiBjC,oBAAoB;wBACzB,iBAAiB;yBAChB,SAAS;wBACV,SAAS,WAAW,MAAM,GAAG,WAAW;wBACxC,SAAS;;GAGhC;AAED,MAAM,MAAM,aAAa,GAAG,OAAO,CAAC,UAAU,CAAC,OAAO,oBAAoB,CAAC,CAAC,CAAC"}
|
|
@@ -0,0 +1,344 @@
|
|
|
1
|
+
import { requireVfsCred } from '@nimbus-sh/core/runtime/os-contracts.js';
|
|
2
|
+
import { SandboxFsImpl } from '@nimbus-sh/core/substrate/lifo/sandbox/SandboxFs.js';
|
|
3
|
+
import { ExecutionFs } from '@nimbus-sh/core/shell/execution-fs.js';
|
|
4
|
+
import { SUPERVISOR_OP_ROUTES, createSupervisorBridgeStore } from '@nimbus-sh/core/workspace/supervisor-op.js';
|
|
5
|
+
import { WebSocketTerminal } from '../facets/ws-terminal.js';
|
|
6
|
+
import { buildSessionSupervisorOps } from '../session/supervisor-op.js';
|
|
7
|
+
import { installLogPersistence } from '../session/hibernation.js';
|
|
8
|
+
import { appendScrollback, ensureSessionStateSchema, loadScrollback, loadShellState, persistShellState } from '../session/state-store.js';
|
|
9
|
+
import { wireProcessLogSocketBroadcast } from '../runtime/process-logs-api.js';
|
|
10
|
+
import { routeRuntimeLoopback } from '../session/loopback.js';
|
|
11
|
+
import * as rpc from '../session/rpc.js';
|
|
12
|
+
import * as operations from '../session/programmatic.js';
|
|
13
|
+
import * as services from './services.js';
|
|
14
|
+
import { registerHostedCommands } from './commands.js';
|
|
15
|
+
import { z } from 'zod/v4';
|
|
16
|
+
import { adoptCtxExports, supervisorEntrypoint } from '@nimbus-sh/fabric/composition.js';
|
|
17
|
+
import { hostNamespaceBinding } from '@nimbus-sh/fabric/host-dispatch.js';
|
|
18
|
+
const HostedTask = z.enum(['resident-launch', 'log-flush', 'log-janitor']);
|
|
19
|
+
const InputFrame = z.discriminatedUnion('type', [
|
|
20
|
+
z.object({ type: z.literal('input'), data: z.string() }),
|
|
21
|
+
z.object({ type: z.literal('resize'), cols: z.number().int().positive(), rows: z.number().int().positive() }),
|
|
22
|
+
]);
|
|
23
|
+
class RuntimeOwner {
|
|
24
|
+
options;
|
|
25
|
+
terminal;
|
|
26
|
+
_cpRegistry;
|
|
27
|
+
_programmaticShellQueues = new Map();
|
|
28
|
+
_hostedProcesses = new Map();
|
|
29
|
+
_hostedProcessWaiters = new Map();
|
|
30
|
+
_cirrusHmrWsClients = new Map();
|
|
31
|
+
closing = null;
|
|
32
|
+
_w9PersistWired = false;
|
|
33
|
+
_w9SchemaInit = false;
|
|
34
|
+
_viteShimPid = null;
|
|
35
|
+
_viteShimPort = null;
|
|
36
|
+
wranglerAliasBannerShown = false;
|
|
37
|
+
facetManagerComposed = null;
|
|
38
|
+
facetProcessManager = null;
|
|
39
|
+
esbuildService = null;
|
|
40
|
+
bundlePool = null;
|
|
41
|
+
npmInstaller = null;
|
|
42
|
+
fetchProxyEntrypoint = null;
|
|
43
|
+
viteDevServer = null;
|
|
44
|
+
cirrusReal = null;
|
|
45
|
+
nimbusWrangler = null;
|
|
46
|
+
webSocketRelay = null;
|
|
47
|
+
readyPromise = null;
|
|
48
|
+
supervisor = null;
|
|
49
|
+
flushScheduled = false;
|
|
50
|
+
janitorScheduled = false;
|
|
51
|
+
recoveryNotice = false;
|
|
52
|
+
scheduling = new Set();
|
|
53
|
+
fileLeases = new Map();
|
|
54
|
+
services;
|
|
55
|
+
constructor(options) {
|
|
56
|
+
this.options = options;
|
|
57
|
+
hostNamespaceBinding(options.env, 'HostedRuntime');
|
|
58
|
+
const exports = Reflect.get(options.ctx, 'exports');
|
|
59
|
+
if (!supervisorEntrypoint(exports)) {
|
|
60
|
+
throw new Error('Export the configured supervisor entrypoint and call composeFabric before composing a hosted runtime');
|
|
61
|
+
}
|
|
62
|
+
adoptCtxExports(exports);
|
|
63
|
+
ensureSessionStateSchema(options.ctx);
|
|
64
|
+
this.terminal = new WebSocketTerminal(null, (data) => {
|
|
65
|
+
appendScrollback(options.ctx, data, Date.now());
|
|
66
|
+
persistShellState(options.ctx, { cwd: this.shell.getCwd(), env: this.shell.getEnv() });
|
|
67
|
+
});
|
|
68
|
+
this._cpRegistry = options.workspace.registry;
|
|
69
|
+
this.services = services.bindRuntimeServices(this, {
|
|
70
|
+
ctx: options.ctx,
|
|
71
|
+
env: options.env,
|
|
72
|
+
notify: (line) => this._notifySession(line),
|
|
73
|
+
requestLaunchTurn: (at) => this._scheduleLaunchTurn(at),
|
|
74
|
+
resolveWorkerLaunch: options.resolveWorkerLaunch,
|
|
75
|
+
filesystem: () => options.workspace.filesystem,
|
|
76
|
+
});
|
|
77
|
+
options.workspace.shell.bindTerminal(this.terminal);
|
|
78
|
+
installLogPersistence(this, options.ctx, () => this.scheduleLogs());
|
|
79
|
+
wireProcessLogSocketBroadcast(this.processes, options.ctx);
|
|
80
|
+
}
|
|
81
|
+
get ctx() { return this.options.ctx; }
|
|
82
|
+
get _w1SessionDestroyed() { return this.closing !== null; }
|
|
83
|
+
get env() { return this.options.env; }
|
|
84
|
+
get sqliteFs() { return this.options.workspace.vfs; }
|
|
85
|
+
get kernel() { return this.options.workspace.kernel; }
|
|
86
|
+
get shell() { return this.options.workspace.shell; }
|
|
87
|
+
get shellProcessPid() { return this.options.workspace.shellProcessPid; }
|
|
88
|
+
get runtimeManager() { return this.options.workspace.runtimes; }
|
|
89
|
+
get processes() { return this.options.workspace.processes; }
|
|
90
|
+
get portRegistry() { return this.options.ports; }
|
|
91
|
+
get facetManager() { return this.facetManagerComposed?.manager ?? null; }
|
|
92
|
+
get sessionBasePath() { return this.options.basePath ?? ''; }
|
|
93
|
+
get sessionOrigin() { return this.options.origin ?? ''; }
|
|
94
|
+
get viteBasePath() { return `${this.sessionBasePath}/preview`; }
|
|
95
|
+
get nimbusDebug() { return Reflect.get(this.env, 'NIMBUS_DEBUG') === '1'; }
|
|
96
|
+
assertOpen() {
|
|
97
|
+
if (this._w1SessionDestroyed)
|
|
98
|
+
throw new Error('Nimbus runtime is closed');
|
|
99
|
+
}
|
|
100
|
+
ensureRuntimeReady() {
|
|
101
|
+
this.assertOpen();
|
|
102
|
+
this.readyPromise ??= (async () => {
|
|
103
|
+
const saved = loadShellState(this.ctx);
|
|
104
|
+
this.recoveryNotice = saved.hasPersistedState;
|
|
105
|
+
if (saved.cwd)
|
|
106
|
+
this.shell.setCwd(saved.cwd);
|
|
107
|
+
if (saved.env)
|
|
108
|
+
Object.assign(this.shell.getEnv(), saved.env);
|
|
109
|
+
await registerHostedCommands(this, this.options.workspace);
|
|
110
|
+
await this.options.workspace.start();
|
|
111
|
+
})();
|
|
112
|
+
return this.readyPromise;
|
|
113
|
+
}
|
|
114
|
+
ensureSqliteFs() { return this.sqliteFs; }
|
|
115
|
+
routeLoopback(port, request) { return routeRuntimeLoopback(this.portRegistry, port, request); }
|
|
116
|
+
ensureBundlePool() { this.assertOpen(); return this.services.ensureBundlePool(); }
|
|
117
|
+
ensureFacetManager() { this.assertOpen(); return this.services.ensureFacetManager(); }
|
|
118
|
+
ensureFetchProxy(log) { return this.services.ensureFetchProxy(log); }
|
|
119
|
+
buildFetchFn(log) { return this.services.buildFetchFn(log); }
|
|
120
|
+
ensureNpmInstaller(onProgress) { this.assertOpen(); return this.services.ensureNpmInstaller(onProgress); }
|
|
121
|
+
ensureGlobalPrefixDirs(prefix) { return this.services.ensureGlobalPrefixDirs(prefix); }
|
|
122
|
+
_envFlagDefaultOn(name) { return this.services._envFlagDefaultOn(name); }
|
|
123
|
+
_ensureFacetProcessManager() { this.assertOpen(); return this.services._ensureFacetProcessManager(); }
|
|
124
|
+
_ensureWebSocketRelay() { this.assertOpen(); return this.services._ensureWebSocketRelay(); }
|
|
125
|
+
_setCpRegistry(registry) {
|
|
126
|
+
if (registry !== this._cpRegistry)
|
|
127
|
+
throw new Error('Nimbus runtime cannot replace the workspace registry');
|
|
128
|
+
}
|
|
129
|
+
_notifySession(line) { this.terminal.write(`${line}\r\n`); }
|
|
130
|
+
_scheduleLaunchTurn(notBefore = Date.now()) {
|
|
131
|
+
const pending = this.schedule('resident-launch', Math.max(Date.now(), notBefore));
|
|
132
|
+
this.options.lifecycle.waitUntil(pending);
|
|
133
|
+
return pending;
|
|
134
|
+
}
|
|
135
|
+
schedule(reason, at) {
|
|
136
|
+
if (this._w1SessionDestroyed)
|
|
137
|
+
return Promise.reject(new Error('Nimbus runtime is closed'));
|
|
138
|
+
// Registered before the deferred call runs, so close() waits for a turn
|
|
139
|
+
// issued in the same tick; the second closed check keeps that turn from
|
|
140
|
+
// arming an alarm the shutdown has already decided against.
|
|
141
|
+
const pending = Promise.resolve().then(() => {
|
|
142
|
+
if (this._w1SessionDestroyed)
|
|
143
|
+
return;
|
|
144
|
+
return this.options.lifecycle.schedule(reason, at);
|
|
145
|
+
});
|
|
146
|
+
this.scheduling.add(pending);
|
|
147
|
+
void pending.then(() => this.scheduling.delete(pending), () => this.scheduling.delete(pending));
|
|
148
|
+
return pending;
|
|
149
|
+
}
|
|
150
|
+
_reportExternalExit(pid, code, reason) { return rpc._reportExternalExit(this, pid, code, reason); }
|
|
151
|
+
_emitExitDump(pid, code) { return rpc._emitExitDump(this, pid, code); }
|
|
152
|
+
_emitShellExecDone(pid, command, code, duration) { return rpc._emitShellExecDone(this, pid, command, code, duration); }
|
|
153
|
+
_rpcStdout(pid, data) { return rpc._rpcStdout(this, pid, data); }
|
|
154
|
+
_rpcStderr(pid, data) { return rpc._rpcStderr(this, pid, data); }
|
|
155
|
+
supervisorOps() {
|
|
156
|
+
this.supervisor ??= buildSessionSupervisorOps(this, createSupervisorBridgeStore({
|
|
157
|
+
vfs: this.options.workspace.vfs,
|
|
158
|
+
filesystem: this.options.workspace.filesystem,
|
|
159
|
+
processes: this.processes,
|
|
160
|
+
}), Object.fromEntries(Object.values(SUPERVISOR_OP_ROUTES).map(({ method }) => {
|
|
161
|
+
const handler = Reflect.get(rpc, method);
|
|
162
|
+
if (typeof handler !== 'function')
|
|
163
|
+
throw new Error(`Missing Nimbus supervisor implementation: ${method}`);
|
|
164
|
+
return [method, (...args) => Reflect.apply(handler, undefined, [this, ...args])];
|
|
165
|
+
})));
|
|
166
|
+
return this.supervisor;
|
|
167
|
+
}
|
|
168
|
+
supervisorOp(envelope) {
|
|
169
|
+
this.assertOpen();
|
|
170
|
+
return this.supervisorOps().dispatch(envelope);
|
|
171
|
+
}
|
|
172
|
+
supervisorBridge(pid) { return this.supervisorOps().bridge(pid); }
|
|
173
|
+
supervisorForgetBridge(pid) { this.supervisorOps().forget(pid); }
|
|
174
|
+
scheduleLogs() {
|
|
175
|
+
if (this._w1SessionDestroyed)
|
|
176
|
+
return;
|
|
177
|
+
if (!this.flushScheduled) {
|
|
178
|
+
this.flushScheduled = true;
|
|
179
|
+
this.options.lifecycle.waitUntil(this.schedule('log-flush', Date.now() + 250).catch((error) => {
|
|
180
|
+
this.flushScheduled = false;
|
|
181
|
+
throw error;
|
|
182
|
+
}));
|
|
183
|
+
}
|
|
184
|
+
if (!this.janitorScheduled) {
|
|
185
|
+
this.janitorScheduled = true;
|
|
186
|
+
this.options.lifecycle.waitUntil(this.schedule('log-janitor', Date.now() + 60_000).catch((error) => {
|
|
187
|
+
this.janitorScheduled = false;
|
|
188
|
+
throw error;
|
|
189
|
+
}));
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
async onScheduled(task) {
|
|
193
|
+
if (this._w1SessionDestroyed)
|
|
194
|
+
return;
|
|
195
|
+
if (task === 'resident-launch') {
|
|
196
|
+
await this.ensureFacetManager().pumpLaunches();
|
|
197
|
+
}
|
|
198
|
+
else if (task === 'log-flush') {
|
|
199
|
+
this.flushScheduled = false;
|
|
200
|
+
this.processes.flushLogs();
|
|
201
|
+
}
|
|
202
|
+
else {
|
|
203
|
+
this.janitorScheduled = false;
|
|
204
|
+
this.processes.dropLogsOlderThan(undefined, (pid) => !this.processes.get(pid));
|
|
205
|
+
if (this.processes.stats.running > 0 || this.processes.logStats.totalPids > 0)
|
|
206
|
+
this.scheduleLogs();
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
async attachTerminal(ws, resume = 'reconnect') {
|
|
210
|
+
await this.ensureRuntimeReady();
|
|
211
|
+
if (this.terminal.ws === ws)
|
|
212
|
+
return;
|
|
213
|
+
this.terminal.attach(ws);
|
|
214
|
+
if (resume === 'reconnect')
|
|
215
|
+
this.terminal.write(loadScrollback(this.ctx));
|
|
216
|
+
if (this.recoveryNotice) {
|
|
217
|
+
this.terminal.write('\r\n[Runtime resumed; files and shell settings restored. Previous interpreter state was not retained.]\r\n');
|
|
218
|
+
this.recoveryNotice = false;
|
|
219
|
+
}
|
|
220
|
+
if (!this.shell.running)
|
|
221
|
+
this.shell.printPrompt();
|
|
222
|
+
this.terminal.flushNow();
|
|
223
|
+
ws.send(JSON.stringify({ type: 'ready' }));
|
|
224
|
+
}
|
|
225
|
+
async terminalFrame(ws, frame) {
|
|
226
|
+
await this.attachTerminal(ws, 'wake');
|
|
227
|
+
const text = typeof frame === 'string' ? frame : new TextDecoder().decode(frame);
|
|
228
|
+
const input = InputFrame.parse(JSON.parse(text));
|
|
229
|
+
this.terminal.handleMessage(input);
|
|
230
|
+
persistShellState(this.ctx, { cwd: this.shell.getCwd(), env: this.shell.getEnv() });
|
|
231
|
+
}
|
|
232
|
+
terminalClose(ws) {
|
|
233
|
+
if (this.terminal.ws !== ws)
|
|
234
|
+
return;
|
|
235
|
+
this.terminal.flushNow();
|
|
236
|
+
persistShellState(this.ctx, { cwd: this.shell.getCwd(), env: this.shell.getEnv() });
|
|
237
|
+
this.terminal.detach();
|
|
238
|
+
this.processes.flushLogs();
|
|
239
|
+
}
|
|
240
|
+
files(cred) {
|
|
241
|
+
this.assertOpen();
|
|
242
|
+
const workspace = this.options.workspace;
|
|
243
|
+
const identity = requireVfsCred(cred, 'runtime files');
|
|
244
|
+
// One host lease per credential, not per `.as()` call: the descriptor
|
|
245
|
+
// scope behind a lease lives until close(), so re-deriving a view for an
|
|
246
|
+
// identity the runtime already opened must reuse that scope.
|
|
247
|
+
const key = `${identity.uid}:${identity.gid}:${identity.groups.join(',')}:${identity.umask}`;
|
|
248
|
+
let lease = this.fileLeases.get(key);
|
|
249
|
+
if (!lease) {
|
|
250
|
+
lease = workspace.filesystem.openHost(identity);
|
|
251
|
+
this.fileLeases.set(key, lease);
|
|
252
|
+
}
|
|
253
|
+
const view = new SandboxFsImpl(new ExecutionFs(lease.fs), () => workspace.shell.getCwd());
|
|
254
|
+
return Object.assign(view, { as: (next) => this.files(next) });
|
|
255
|
+
}
|
|
256
|
+
close() {
|
|
257
|
+
this.closing ??= Promise.resolve().then(async () => {
|
|
258
|
+
const failures = [];
|
|
259
|
+
const clean = async (action) => {
|
|
260
|
+
try {
|
|
261
|
+
await action();
|
|
262
|
+
}
|
|
263
|
+
catch (error) {
|
|
264
|
+
failures.push(error instanceof Error ? error : new Error(String(error)));
|
|
265
|
+
}
|
|
266
|
+
};
|
|
267
|
+
await clean(() => this.terminal.disposeRepl());
|
|
268
|
+
await clean(() => this.terminal.sendData('\x03'));
|
|
269
|
+
for (const process of this.processes.getAll()) {
|
|
270
|
+
await clean(() => this.webSocketRelay?.closeForPid(process.pid));
|
|
271
|
+
if (process.state !== 'running')
|
|
272
|
+
continue;
|
|
273
|
+
await clean(() => { if (!this.facetManager?.kill(process.pid))
|
|
274
|
+
this.processes.kill(process.pid); });
|
|
275
|
+
await clean(() => { this.portRegistry.unregisterByPid(process.pid); });
|
|
276
|
+
}
|
|
277
|
+
await clean(() => this.viteDevServer?.stop());
|
|
278
|
+
await clean(() => this.cirrusReal?.stop(this.ctx));
|
|
279
|
+
await clean(() => this.nimbusWrangler?.stop());
|
|
280
|
+
await clean(() => this.bundlePool?.dispose());
|
|
281
|
+
await clean(() => this.processes.flushLogs());
|
|
282
|
+
this.terminal.flushNow();
|
|
283
|
+
this.terminal.close();
|
|
284
|
+
for (const ws of this.ctx.getWebSockets('process-logs')) {
|
|
285
|
+
await clean(() => ws.close(1000, 'runtime closed'));
|
|
286
|
+
}
|
|
287
|
+
await clean(() => this.facetManager?.closeLaunches());
|
|
288
|
+
await Promise.allSettled(this.scheduling);
|
|
289
|
+
await clean(() => this.supervisor?.dispose());
|
|
290
|
+
for (const lease of this.fileLeases.values())
|
|
291
|
+
await clean(() => lease.dispose());
|
|
292
|
+
this.fileLeases.clear();
|
|
293
|
+
await clean(() => this.options.workspace.close());
|
|
294
|
+
for (const task of HostedTask.options)
|
|
295
|
+
await clean(() => this.options.lifecycle.cancel(task));
|
|
296
|
+
if (failures.length > 0)
|
|
297
|
+
throw new AggregateError(failures, 'Nimbus runtime cleanup failed');
|
|
298
|
+
});
|
|
299
|
+
return this.closing;
|
|
300
|
+
}
|
|
301
|
+
}
|
|
302
|
+
export async function composeHostedRuntime(options) {
|
|
303
|
+
const owner = new RuntimeOwner(options);
|
|
304
|
+
await owner.ensureRuntimeReady();
|
|
305
|
+
return {
|
|
306
|
+
workspace: options.workspace,
|
|
307
|
+
terminal: owner.terminal,
|
|
308
|
+
files: owner.files(owner.processes.cred(owner.shellProcessPid)),
|
|
309
|
+
runtimes: owner.runtimeManager,
|
|
310
|
+
ready: operations.ensureProgrammaticReady.bind(null, owner),
|
|
311
|
+
exec: operations.rpcExec.bind(null, owner),
|
|
312
|
+
runCode: operations.rpcRunCode.bind(null, owner),
|
|
313
|
+
startProcess: operations.rpcStartProcess.bind(null, owner),
|
|
314
|
+
listProcesses: operations.rpcListProcesses.bind(null, owner),
|
|
315
|
+
killProcess: operations.rpcKillProcess.bind(null, owner),
|
|
316
|
+
writeProcessInput: operations.rpcWriteProcessInput.bind(null, owner),
|
|
317
|
+
endProcessInput: operations.rpcEndProcessInput.bind(null, owner),
|
|
318
|
+
resizeProcess: operations.rpcResizeProcess.bind(null, owner),
|
|
319
|
+
signalProcess: operations.rpcSignalProcess.bind(null, owner),
|
|
320
|
+
processLogs: (pid, options) => operations.rpcProcessLogs(owner, pid, options),
|
|
321
|
+
listPorts: operations.rpcListPorts.bind(null, owner),
|
|
322
|
+
listApps: operations.rpcListApps.bind(null, owner),
|
|
323
|
+
ensureDurableApp: operations.rpcEnsureDurableApp.bind(null, owner),
|
|
324
|
+
unexposePort: operations.rpcUnexposePort.bind(null, owner),
|
|
325
|
+
removeDurableApp: operations.rpcRemoveDurableApp.bind(null, owner),
|
|
326
|
+
exposeApp: operations.rpcExposeApp.bind(null, owner),
|
|
327
|
+
removeApp: operations.rpcRemoveApp.bind(null, owner),
|
|
328
|
+
rotateLink: operations.rpcRotateLink.bind(null, owner),
|
|
329
|
+
installRuntime: operations.rpcInstallRuntime.bind(null, owner),
|
|
330
|
+
ensureRuntimes: operations.rpcEnsureRuntimes.bind(null, owner),
|
|
331
|
+
listRuntimes: operations.rpcListRuntimes.bind(null, owner),
|
|
332
|
+
spawnWorker: operations.rpcSpawnWorker.bind(null, owner),
|
|
333
|
+
routeCapabilityPort: async (...args) => {
|
|
334
|
+
await operations.ensureProgrammaticReady(owner);
|
|
335
|
+
return owner.ensureFacetManager().apps.routeCapabilityPort(...args);
|
|
336
|
+
},
|
|
337
|
+
supervisorOp: (envelope) => owner.supervisorOp(envelope),
|
|
338
|
+
onScheduled: (task) => owner.onScheduled(task),
|
|
339
|
+
attachTerminal: (ws) => owner.attachTerminal(ws),
|
|
340
|
+
terminalFrame: (ws, message) => owner.terminalFrame(ws, message),
|
|
341
|
+
terminalClose: (ws) => owner.terminalClose(ws),
|
|
342
|
+
close: () => owner.close(),
|
|
343
|
+
};
|
|
344
|
+
}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import { type ComposedFacetManager, type FacetManagerHostHooks } from "../facets/compose.js";
|
|
2
|
+
import { type NimbusFilesystemAuthority } from "@nimbus-sh/core/runtime/os-contracts.js";
|
|
3
|
+
import { EsbuildBundlePool } from "../facets/esbuild-bundle-pool.js";
|
|
4
|
+
import type { NpmInstaller } from "../npm/installer.js";
|
|
5
|
+
import { WebSocketRelay } from "../session/ws-relay.js";
|
|
6
|
+
import type { SessionInternal } from '../session/internal.js';
|
|
7
|
+
import type { RuntimeCatalogEnv } from '../runtime/runtime-catalog.js';
|
|
8
|
+
import type { IsolatePoolEnv } from '@nimbus-sh/fabric/isolate-pool.js';
|
|
9
|
+
export interface HostedRuntimeEnv extends RuntimeCatalogEnv, IsolatePoolEnv {
|
|
10
|
+
ASSETS?: Fetcher;
|
|
11
|
+
}
|
|
12
|
+
export type RuntimeServiceHost = Pick<SessionInternal, '_cpRegistry' | '_envFlagDefaultOn' | '_reportExternalExit' | 'buildFetchFn' | 'bundlePool' | 'ensureBundlePool' | 'ensureFacetManager' | 'ensureFetchProxy' | 'ensureSqliteFs' | 'esbuildService' | 'facetManagerComposed' | 'facetProcessManager' | 'fetchProxyEntrypoint' | 'npmInstaller' | 'portRegistry' | 'processes' | 'shell' | 'sqliteFs' | 'terminal'> & {
|
|
13
|
+
webSocketRelay: WebSocketRelay | null;
|
|
14
|
+
};
|
|
15
|
+
export interface RuntimeServiceContext {
|
|
16
|
+
readonly ctx: DurableObjectState;
|
|
17
|
+
readonly env: HostedRuntimeEnv;
|
|
18
|
+
notify(line: string): void;
|
|
19
|
+
requestLaunchTurn(notBefore?: number): Promise<void>;
|
|
20
|
+
resolveWorkerLaunch?: FacetManagerHostHooks['resolveWorkerLaunch'];
|
|
21
|
+
/** The host's own authority: a session has exactly one, and this is it. */
|
|
22
|
+
filesystem: () => NimbusFilesystemAuthority;
|
|
23
|
+
}
|
|
24
|
+
export declare function ensureBundlePool(self: RuntimeServiceHost, runtimeContext: RuntimeServiceContext): EsbuildBundlePool;
|
|
25
|
+
export declare function ensureFacetManager(self: RuntimeServiceHost, runtimeContext: RuntimeServiceContext): ComposedFacetManager;
|
|
26
|
+
export declare function _ensureWebSocketRelay(self: RuntimeServiceHost, runtimeContext: RuntimeServiceContext): WebSocketRelay;
|
|
27
|
+
export declare function _ensureFacetProcessManager(self: RuntimeServiceHost, runtimeContext: RuntimeServiceContext): any;
|
|
28
|
+
export declare function ensureFetchProxy(self: RuntimeServiceHost, runtimeContext: RuntimeServiceContext, log?: (msg: string) => void): any | null;
|
|
29
|
+
export declare function buildFetchFn(self: RuntimeServiceHost, runtimeContext: RuntimeServiceContext, log?: (msg: string) => void): ((url: string, init?: RequestInit) => Promise<Response>) | undefined;
|
|
30
|
+
export declare function ensureNpmInstaller(self: RuntimeServiceHost, runtimeContext: RuntimeServiceContext, onProgress?: (msg: string) => void): Promise<NpmInstaller>;
|
|
31
|
+
export declare function _envFlagDefaultOn(self: RuntimeServiceHost, runtimeContext: RuntimeServiceContext, name: string): boolean;
|
|
32
|
+
export declare function ensureGlobalPrefixDirs(self: RuntimeServiceHost, runtimeContext: RuntimeServiceContext, prefix: string): void;
|
|
33
|
+
export declare function bindRuntimeServices(host: RuntimeServiceHost, context: RuntimeServiceContext): {
|
|
34
|
+
ensureBundlePool: () => EsbuildBundlePool;
|
|
35
|
+
ensureFacetManager: () => ComposedFacetManager;
|
|
36
|
+
_ensureWebSocketRelay: () => WebSocketRelay;
|
|
37
|
+
_ensureFacetProcessManager: () => any;
|
|
38
|
+
ensureFetchProxy: (log?: ((msg: string) => void) | undefined) => any;
|
|
39
|
+
buildFetchFn: (log?: ((msg: string) => void) | undefined) => ((url: string, init?: RequestInit) => Promise<Response>) | undefined;
|
|
40
|
+
ensureNpmInstaller: (onProgress?: ((msg: string) => void) | undefined) => Promise<NpmInstaller>;
|
|
41
|
+
_envFlagDefaultOn: (name: string) => boolean;
|
|
42
|
+
ensureGlobalPrefixDirs: (prefix: string) => void;
|
|
43
|
+
};
|
|
44
|
+
//# sourceMappingURL=services.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"services.d.ts","sourceRoot":"","sources":["../../src/hosted/services.ts"],"names":[],"mappings":"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"}
|