@nimbus-sh/worker 0.5.0 → 0.7.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +2 -2
- package/dist/_shared/preview-host.d.ts +26 -8
- package/dist/_shared/preview-host.d.ts.map +1 -1
- package/dist/_shared/preview-host.js +51 -11
- package/dist/cirrus-npm-cjs.generated.d.ts +1 -1
- package/dist/cirrus-npm-cjs.generated.js +1 -1
- package/dist/facets/cirrus-real.d.ts.map +1 -1
- package/dist/facets/cirrus-real.js +6 -5
- package/dist/facets/compose.d.ts +148 -0
- package/dist/facets/compose.d.ts.map +1 -0
- package/dist/facets/compose.js +146 -0
- package/dist/facets/durable-images.d.ts +18 -5
- package/dist/facets/durable-images.d.ts.map +1 -1
- package/dist/facets/durable-images.js +36 -7
- package/dist/facets/durable-slots.d.ts +1 -1
- package/dist/facets/durable-slots.d.ts.map +1 -1
- package/dist/facets/durable-slots.js +2 -1
- package/dist/facets/esbuild-bundle-pool.d.ts +49 -0
- package/dist/facets/esbuild-bundle-pool.d.ts.map +1 -0
- package/dist/facets/esbuild-bundle-pool.js +122 -0
- package/dist/facets/exec-telemetry.d.ts +8 -0
- package/dist/facets/exec-telemetry.d.ts.map +1 -1
- package/dist/facets/manager.d.ts +337 -123
- package/dist/facets/manager.d.ts.map +1 -1
- package/dist/facets/manager.js +1100 -449
- package/dist/facets/process.d.ts +20 -16
- package/dist/facets/process.d.ts.map +1 -1
- package/dist/facets/process.js +59 -28
- package/dist/facets/real-vite-fs-shim.js +2 -2
- package/dist/facets/resident-identity.d.ts +23 -0
- package/dist/facets/resident-identity.d.ts.map +1 -0
- package/dist/facets/resident-identity.js +31 -0
- package/dist/facets/vite-dev-server.d.ts +25 -47
- package/dist/facets/vite-dev-server.d.ts.map +1 -1
- package/dist/facets/vite-dev-server.js +185 -219
- package/dist/facets/wasm-image-digest.d.ts +25 -0
- package/dist/facets/wasm-image-digest.d.ts.map +1 -0
- package/dist/facets/wasm-image-digest.js +25 -0
- package/dist/facets/wasm-swap-registry.d.ts +51 -92
- package/dist/facets/wasm-swap-registry.d.ts.map +1 -1
- package/dist/facets/wasm-swap-registry.js +68 -227
- package/dist/git/commands.d.ts +0 -1
- package/dist/git/commands.d.ts.map +1 -1
- package/dist/git/commands.js +0 -3
- package/dist/git/network-facet.d.ts.map +1 -1
- package/dist/git/network-facet.js +6 -5
- package/dist/loaders/child-process/spawn-pool.d.ts +3 -2
- package/dist/loaders/child-process/spawn-pool.d.ts.map +1 -1
- package/dist/loaders/child-process/spawn-pool.js +3 -2
- package/dist/loaders/generated-workers.d.ts +2 -2
- package/dist/loaders/generated-workers.d.ts.map +1 -1
- package/dist/loaders/generated-workers.js +3 -3
- package/dist/loaders/npm-resolve-preamble.d.ts +3 -6
- package/dist/loaders/npm-resolve-preamble.d.ts.map +1 -1
- package/dist/loaders/npm-resolve-preamble.js +34 -108
- package/dist/node-shims-artifact.generated.js +3 -3
- package/dist/npm/install-batch-facet.d.ts +3 -2
- package/dist/npm/install-batch-facet.d.ts.map +1 -1
- package/dist/npm/install-batch-facet.js +45 -15
- package/dist/npm/installer.d.ts +22 -17
- package/dist/npm/installer.d.ts.map +1 -1
- package/dist/npm/installer.js +209 -193
- package/dist/npm/pre-bundle-facet.d.ts +1 -1
- package/dist/npm/pre-bundle-facet.d.ts.map +1 -1
- package/dist/npm/pre-bundle-facet.js +1 -1
- package/dist/npm/resolve-facet.d.ts +6 -0
- package/dist/npm/resolve-facet.d.ts.map +1 -1
- package/dist/npm/resolve-one-facet.d.ts +21 -20
- package/dist/npm/resolve-one-facet.d.ts.map +1 -1
- package/dist/npm/resolve-one-facet.js +85 -84
- package/dist/npm/semver.d.ts +59 -0
- package/dist/npm/semver.d.ts.map +1 -0
- package/dist/npm/semver.js +226 -0
- package/dist/router/index.d.ts.map +1 -1
- package/dist/router/index.js +47 -10
- package/dist/router/public-directory.d.ts +5 -1
- package/dist/router/public-directory.d.ts.map +1 -1
- package/dist/router/public-directory.js +9 -2
- package/dist/router/remote-api.d.ts +18 -0
- package/dist/router/remote-api.d.ts.map +1 -1
- package/dist/router/remote-api.js +64 -5
- package/dist/runtime/cpython-resident.d.ts.map +1 -1
- package/dist/runtime/cpython-resident.js +3 -1
- package/dist/runtime/html-entrypoint.d.ts +7 -0
- package/dist/runtime/html-entrypoint.d.ts.map +1 -1
- package/dist/runtime/html-entrypoint.js +18 -2
- package/dist/runtime/node-runner.d.ts +3 -0
- package/dist/runtime/node-runner.d.ts.map +1 -1
- package/dist/runtime/node-runner.js +7 -0
- package/dist/runtime/node-shims.d.ts.map +1 -1
- package/dist/runtime/node-shims.js +305 -29
- package/dist/runtime/opencode-facet-runner.js +2 -2
- package/dist/runtime/package-manager.d.ts +44 -1
- package/dist/runtime/package-manager.d.ts.map +1 -1
- package/dist/runtime/package-manager.js +168 -3
- package/dist/runtime/ruby-resident.d.ts.map +1 -1
- package/dist/runtime/ruby-resident.js +2 -0
- package/dist/session/agent.d.ts.map +1 -1
- package/dist/session/agent.js +28 -1
- package/dist/session/helpers.d.ts +38 -0
- package/dist/session/helpers.d.ts.map +1 -1
- package/dist/session/helpers.js +76 -0
- package/dist/session/init-phases.d.ts +1 -1
- package/dist/session/init-phases.d.ts.map +1 -1
- package/dist/session/init-phases.js +2 -12
- package/dist/session/init.d.ts +15 -1
- package/dist/session/init.d.ts.map +1 -1
- package/dist/session/init.js +91 -603
- package/dist/session/keys.d.ts +4 -0
- package/dist/session/keys.d.ts.map +1 -1
- package/dist/session/keys.js +4 -0
- package/dist/session/nimbus-session.d.ts +90 -23
- package/dist/session/nimbus-session.d.ts.map +1 -1
- package/dist/session/nimbus-session.js +200 -110
- package/dist/session/npm-install-port.d.ts +16 -0
- package/dist/session/npm-install-port.d.ts.map +1 -0
- package/dist/session/npm-install-port.js +37 -0
- package/dist/session/port-capability.d.ts +90 -0
- package/dist/session/port-capability.d.ts.map +1 -1
- package/dist/session/port-capability.js +219 -9
- package/dist/session/programmatic.d.ts +125 -5
- package/dist/session/programmatic.d.ts.map +1 -1
- package/dist/session/programmatic.js +439 -89
- package/dist/session/routes.d.ts +39 -17
- package/dist/session/routes.d.ts.map +1 -1
- package/dist/session/routes.js +67 -131
- package/dist/session/rpc.d.ts +39 -16
- package/dist/session/rpc.d.ts.map +1 -1
- package/dist/session/rpc.js +137 -130
- package/dist/session/serving-port.d.ts +27 -0
- package/dist/session/serving-port.d.ts.map +1 -0
- package/dist/session/serving-port.js +27 -0
- package/dist/session/start-real-vite.d.ts +12 -0
- package/dist/session/start-real-vite.d.ts.map +1 -1
- package/dist/session/start-real-vite.js +4 -4
- package/dist/session/supervisor-op.d.ts +41 -4
- package/dist/session/supervisor-op.d.ts.map +1 -1
- package/dist/session/supervisor-op.js +101 -73
- package/dist/session/supervisor-rpc.d.ts +7 -7
- package/dist/session/supervisor-rpc.d.ts.map +1 -1
- package/dist/session/supervisor-rpc.js +6 -3
- package/dist/session/vite-command.d.ts +18 -0
- package/dist/session/vite-command.d.ts.map +1 -0
- package/dist/session/vite-command.js +609 -0
- package/dist/session/ws.d.ts +61 -0
- package/dist/session/ws.d.ts.map +1 -1
- package/dist/session/ws.js +122 -12
- package/dist/shell/npm-bin-entrypoints.d.ts +0 -35
- package/dist/shell/npm-bin-entrypoints.d.ts.map +1 -1
- package/dist/shell/npm-bin-entrypoints.js +12 -85
- package/package.json +24 -4
- package/public/_assets/runtime/{node-shims-9e1380d9ee430fcc.js → node-shims-8f8c64edd2a1f0f5.js} +305 -29
- package/public/index.html +1 -1
- package/scripts/bundle-facet-workers.mjs +1 -1
- package/scripts/bundle-npm-cjs.mjs +2 -2
- package/dist/facets/on-demand-bundle-gate.d.ts +0 -65
- package/dist/facets/on-demand-bundle-gate.d.ts.map +0 -1
- package/dist/facets/on-demand-bundle-gate.js +0 -125
- package/dist/npm/install-args.d.ts +0 -21
- package/dist/npm/install-args.d.ts.map +0 -1
- package/dist/npm/install-args.js +0 -70
- package/dist/npm/npm-log.d.ts +0 -31
- package/dist/npm/npm-log.d.ts.map +0 -1
- package/dist/npm/npm-log.js +0 -51
package/dist/session/rpc.js
CHANGED
|
@@ -21,13 +21,12 @@
|
|
|
21
21
|
* these ~3 sites would each need ctx threaded through; cast at boundary
|
|
22
22
|
* is acceptable per plan §IX recommendation 1.
|
|
23
23
|
*/
|
|
24
|
-
import { enc,
|
|
24
|
+
import { enc, StreamTextDecoders } from '@nimbus-sh/core/_shared/bytes.js';
|
|
25
25
|
import { normalizeTerminalNewlines } from '@nimbus-sh/core/_shared/terminal.js';
|
|
26
26
|
import { disposeRpcResource } from '@nimbus-sh/platform/rpc-dispose.js';
|
|
27
27
|
import { getInnerDoClass } from '@nimbus-sh/fabric/inner-do-registry.js';
|
|
28
28
|
import { NpmCache } from '../npm/cache.js';
|
|
29
29
|
import { EsbuildService } from '@nimbus-sh/core/runtime/esbuild-service.js';
|
|
30
|
-
import { SqliteRuntimeFsBridge } from '@nimbus-sh/core/runtime/sqlite-runtime-fs-bridge.js';
|
|
31
30
|
import { notifyTerminalEvent } from '../runtime/process-logs-api.js';
|
|
32
31
|
import { IsolatePool } from '@nimbus-sh/fabric/isolate-pool.js';
|
|
33
32
|
import { residentBootSpecSchema, } from '@nimbus-sh/fabric/process-fabric.js';
|
|
@@ -39,12 +38,11 @@ import { recordFailure, getLastRpcFrame, getLastFacetId, } from '@nimbus-sh/plat
|
|
|
39
38
|
import { classifyError } from '@nimbus-sh/platform/oom-classify.js';
|
|
40
39
|
import { acquireSupervisorReadAllocation, } from '@nimbus-sh/platform/heavy-alloc-coord.js';
|
|
41
40
|
import { rpcPayloadEnd, rpcPayloadStart, } from '@nimbus-sh/platform/diag-counters.js';
|
|
42
|
-
import { CRED_KERNEL, CRED_SESSION_USER, } from '@nimbus-sh/core/runtime/os-contracts.js';
|
|
43
|
-
import { getSymlinkRegistry } from '@nimbus-sh/core/vfs/symlink-registry.js';
|
|
41
|
+
import { CRED_KERNEL, CRED_SESSION_USER, requireVfsCred, } from '@nimbus-sh/core/runtime/os-contracts.js';
|
|
44
42
|
import { MAX_RPC_SAFE_PAYLOAD_BYTES } from '@nimbus-sh/platform/limits.js';
|
|
45
43
|
import { FS_LIST_PAGE_LIMIT, FS_READ_BATCH_PATH_LIMIT, FS_READ_BATCH_REQUEST_BYTES, } from '@nimbus-sh/core/constants.js';
|
|
46
44
|
import { routeSessionLoopback } from './loopback.js';
|
|
47
|
-
import {
|
|
45
|
+
import { registerServingPort } from './serving-port.js';
|
|
48
46
|
import { normalizeVfsPath, parentVfsPath } from '@nimbus-sh/core/vfs/path.js';
|
|
49
47
|
import { z } from 'zod/v4';
|
|
50
48
|
const WriteBatchInodeSchema = z.object({
|
|
@@ -68,11 +66,6 @@ const WriteBatchPayloadSchema = z.object({
|
|
|
68
66
|
chunks: z.array(WriteBatchChunkSchema).default([]),
|
|
69
67
|
deletePaths: z.array(z.string()).optional(),
|
|
70
68
|
}).passthrough();
|
|
71
|
-
/**
|
|
72
|
-
* Bridge key for the pid-less (host caller) filesystem view. ProcessTable
|
|
73
|
-
* allocates pids from 1 upwards, so 0 can never collide with a process.
|
|
74
|
-
*/
|
|
75
|
-
const HOST_CALLER_KEY = 0;
|
|
76
69
|
function processPid(pid) {
|
|
77
70
|
if (!Number.isInteger(pid) || typeof pid !== 'number' || pid <= 0) {
|
|
78
71
|
throw new Error('filesystem RPC requires a valid process pid');
|
|
@@ -88,30 +81,24 @@ function processPid(pid) {
|
|
|
88
81
|
* binding, the remote `/rpc` dispatcher, the static asset server — and those
|
|
89
82
|
* act as the unprivileged session user, the same identity `exec` runs as.
|
|
90
83
|
* A supplied-but-invalid pid still throws: only an absent pid is a host call.
|
|
84
|
+
*
|
|
85
|
+
* A host call may name the credential it acts as (`cred`) — the same
|
|
86
|
+
* `SqliteVFS.as(cred)` view an in-process caller has, reached over the RPC
|
|
87
|
+
* surface. That is the embedder's trusted surface: the SDK over the DO
|
|
88
|
+
* binding hands it through `files.as(cred)`; the remote `/rpc` dispatcher
|
|
89
|
+
* refuses it, exactly as it refuses `cred` on exec, because a token
|
|
90
|
+
* authenticates a session and not a user inside it. Absent, every file op
|
|
91
|
+
* keeps the identity it has always had. A pid and a cred together are
|
|
92
|
+
* refused, so a process can never widen its own identity.
|
|
91
93
|
*/
|
|
92
|
-
function callerCred(self, pid) {
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
return self.
|
|
98
|
-
}
|
|
99
|
-
function
|
|
100
|
-
const key = pid === undefined ? HOST_CALLER_KEY : processPid(pid);
|
|
101
|
-
const vfs = processVfs(self, pid);
|
|
102
|
-
if (!self.runtimeFsBridges)
|
|
103
|
-
self.runtimeFsBridges = new Map();
|
|
104
|
-
let bridge = self.runtimeFsBridges.get(key);
|
|
105
|
-
if (!bridge) {
|
|
106
|
-
bridge = new SqliteRuntimeFsBridge(vfs, self.sqliteFs);
|
|
107
|
-
self.runtimeFsBridges.set(key, bridge);
|
|
108
|
-
}
|
|
109
|
-
else {
|
|
110
|
-
bridge.updateCredential(vfs);
|
|
111
|
-
}
|
|
112
|
-
return bridge;
|
|
113
|
-
}
|
|
114
|
-
function checkedReadPayloadBytes(bytes) {
|
|
94
|
+
function callerCred(self, pid, cred) {
|
|
95
|
+
if (pid === undefined)
|
|
96
|
+
return cred === undefined ? CRED_SESSION_USER : requireVfsCred(cred, 'filesystem RPC');
|
|
97
|
+
if (cred !== undefined)
|
|
98
|
+
throw new Error('filesystem RPC: a process acts as its own credential; cred cannot ride a pid');
|
|
99
|
+
return self.processes.cred(processPid(pid));
|
|
100
|
+
}
|
|
101
|
+
export function checkedReadPayloadBytes(bytes) {
|
|
115
102
|
if (!Number.isSafeInteger(bytes) || bytes < 0) {
|
|
116
103
|
throw new RangeError(`filesystem RPC read size must be a non-negative safe integer: ${bytes}`);
|
|
117
104
|
}
|
|
@@ -129,13 +116,13 @@ function checkedReadPayloadBytes(bytes) {
|
|
|
129
116
|
* `stat` here is a local SQLite lookup inside the DO — the same one
|
|
130
117
|
* `_rpcReadFile` makes for the same reason — not a second round trip.
|
|
131
118
|
*/
|
|
132
|
-
async function rangeReadBytes(fs, path, offset, length) {
|
|
119
|
+
export async function rangeReadBytes(fs, path, offset, length) {
|
|
133
120
|
const stat = await fs.stat(path);
|
|
134
121
|
if (!stat)
|
|
135
122
|
return 0;
|
|
136
123
|
return Math.max(0, Math.min(length, stat.size - offset));
|
|
137
124
|
}
|
|
138
|
-
async function withReadAllocation(bytes, read) {
|
|
125
|
+
export async function withReadAllocation(bytes, read) {
|
|
139
126
|
const payloadBytes = checkedReadPayloadBytes(bytes);
|
|
140
127
|
if (payloadBytes === 0)
|
|
141
128
|
return read();
|
|
@@ -149,27 +136,21 @@ async function withReadAllocation(bytes, read) {
|
|
|
149
136
|
lease.release();
|
|
150
137
|
}
|
|
151
138
|
}
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
return bytes ? dec.decode(bytes) : null;
|
|
160
|
-
});
|
|
139
|
+
/**
|
|
140
|
+
* `files.readFile` — the read with the supervisor's allocation lease.
|
|
141
|
+
* The body lives in `buildSessionSupervisorOps`'s `readFile` override so
|
|
142
|
+
* direct `_rpc*` calls and the supervisor envelope share it.
|
|
143
|
+
*/
|
|
144
|
+
export async function _rpcReadFile(self, path, pid, cred) {
|
|
145
|
+
return self.supervisorOp({ op: 'readFile', args: [path], pid, cred });
|
|
161
146
|
}
|
|
162
147
|
/**
|
|
163
148
|
* Read a file as raw bytes (Uint8Array). Used by git network facet for
|
|
164
149
|
* binary .git/objects/** and packfile reads, where TextDecoder/TextEncoder
|
|
165
150
|
* round-tripping through readFile (string) would corrupt bytes.
|
|
166
151
|
*/
|
|
167
|
-
export async function _rpcReadFileBytes(self, path, pid) {
|
|
168
|
-
|
|
169
|
-
const stat = await fs.stat(path);
|
|
170
|
-
if (!stat)
|
|
171
|
-
return null;
|
|
172
|
-
return withReadAllocation(stat.size, () => fs.readFile(path));
|
|
152
|
+
export async function _rpcReadFileBytes(self, path, pid, cred) {
|
|
153
|
+
return self.supervisorOp({ op: 'readFileBytes', args: [path], pid, cred });
|
|
173
154
|
}
|
|
174
155
|
/**
|
|
175
156
|
* Phase-3 inner-DO fetch dispatcher. Called by NimbusDOStub.fetch()
|
|
@@ -234,14 +215,11 @@ export async function _rpcInnerDoFetch(self, req) {
|
|
|
234
215
|
};
|
|
235
216
|
}
|
|
236
217
|
}
|
|
237
|
-
export async function _rpcWriteFile(self, path, content, pid) {
|
|
238
|
-
// binary-fs wave:
|
|
239
|
-
//
|
|
240
|
-
//
|
|
241
|
-
|
|
242
|
-
// a Buffer flows through node-shims.ts:writeFileSync which stores it as
|
|
243
|
-
// a plain Uint8Array on the cell — the shape that arrives here.
|
|
244
|
-
return runtimeFs(self, pid).writeFile(path, content);
|
|
218
|
+
export async function _rpcWriteFile(self, path, content, pid, cred) {
|
|
219
|
+
// binary-fs wave: the bridge's writeFile already accepts
|
|
220
|
+
// string | Uint8Array — the shape arrives unchanged across structured
|
|
221
|
+
// clone.
|
|
222
|
+
return self.supervisorOp({ op: 'writeFile', args: [path, content], pid, cred });
|
|
245
223
|
}
|
|
246
224
|
/**
|
|
247
225
|
* Write one host-governed file at a session root and let ordinary Unix
|
|
@@ -274,54 +252,53 @@ export async function _rpcWriteProtectedRootFile(self, rootPath, path, content)
|
|
|
274
252
|
fs.chown(protectedPath, CRED_KERNEL.uid, CRED_KERNEL.gid);
|
|
275
253
|
fs.chmod(protectedPath, 0o444);
|
|
276
254
|
}
|
|
277
|
-
export async function _rpcStat(self, path, pid) {
|
|
278
|
-
return
|
|
255
|
+
export async function _rpcStat(self, path, pid, cred) {
|
|
256
|
+
return self.supervisorOp({ op: 'stat', args: [path], pid, cred });
|
|
279
257
|
}
|
|
280
|
-
export async function _rpcLstat(self, path, pid) {
|
|
281
|
-
return
|
|
258
|
+
export async function _rpcLstat(self, path, pid, cred) {
|
|
259
|
+
return self.supervisorOp({ op: 'lstat', args: [path], pid, cred });
|
|
282
260
|
}
|
|
283
261
|
export async function _rpcHasLegacySymlinkUnder(self, path, pid) {
|
|
284
|
-
|
|
285
|
-
return getSymlinkRegistry(self.sqliteFs).hasAtOrBelow(path);
|
|
262
|
+
return self.supervisorOp({ op: 'hasLegacySymlinkUnder', args: [path], pid });
|
|
286
263
|
}
|
|
287
264
|
export async function _rpcUtimes(self, path, atimeMs, mtimeMs, pid) {
|
|
288
|
-
await
|
|
265
|
+
await self.supervisorOp({ op: 'utimes', args: [path, atimeMs, mtimeMs], pid });
|
|
289
266
|
}
|
|
290
|
-
export async function _rpcChmod(self, path, mode, pid) {
|
|
291
|
-
await
|
|
267
|
+
export async function _rpcChmod(self, path, mode, pid, cred) {
|
|
268
|
+
await self.supervisorOp({ op: 'chmod', args: [path, mode], pid, cred });
|
|
292
269
|
}
|
|
293
270
|
export async function _rpcAccess(self, path, mode, pid) {
|
|
294
|
-
await
|
|
271
|
+
await self.supervisorBridge(pid).access(path, mode);
|
|
295
272
|
}
|
|
296
273
|
export async function _rpcChown(self, path, uid, gid, pid, options) {
|
|
297
|
-
await
|
|
274
|
+
await self.supervisorBridge(pid).chown(path, uid, gid, options);
|
|
298
275
|
}
|
|
299
276
|
export async function _rpcSetUmask(self, mask, pid) {
|
|
300
277
|
return self.processes.setUmask(processPid(pid), mask);
|
|
301
278
|
}
|
|
302
|
-
export async function _rpcReaddir(self, path, pid) {
|
|
303
|
-
return
|
|
279
|
+
export async function _rpcReaddir(self, path, pid, cred) {
|
|
280
|
+
return self.supervisorOp({ op: 'readdir', args: [path], pid, cred });
|
|
304
281
|
}
|
|
305
|
-
export async function _rpcExists(self, path, pid) {
|
|
306
|
-
return (
|
|
282
|
+
export async function _rpcExists(self, path, pid, cred) {
|
|
283
|
+
return self.supervisorOp({ op: 'exists', args: [path], pid, cred });
|
|
307
284
|
}
|
|
308
|
-
export async function _rpcMkdir(self, path, pid) {
|
|
309
|
-
await
|
|
285
|
+
export async function _rpcMkdir(self, path, pid, cred) {
|
|
286
|
+
await self.supervisorOp({ op: 'mkdir', args: [path], pid, cred });
|
|
310
287
|
}
|
|
311
288
|
export async function _rpcRmdir(self, path, pid) {
|
|
312
|
-
await
|
|
289
|
+
await self.supervisorOp({ op: 'rmdir', args: [path], pid });
|
|
313
290
|
}
|
|
314
|
-
export async function _rpcRename(self, from, to, pid) {
|
|
315
|
-
await
|
|
291
|
+
export async function _rpcRename(self, from, to, pid, cred) {
|
|
292
|
+
await self.supervisorOp({ op: 'rename', args: [from, to], pid, cred });
|
|
316
293
|
}
|
|
317
294
|
export async function _rpcReadlink(self, path, pid) {
|
|
318
|
-
return
|
|
295
|
+
return self.supervisorOp({ op: 'readlink', args: [path], pid });
|
|
319
296
|
}
|
|
320
297
|
export async function _rpcSymlink(self, target, path, pid) {
|
|
321
|
-
await
|
|
298
|
+
await self.supervisorOp({ op: 'symlink', args: [target, path], pid });
|
|
322
299
|
}
|
|
323
300
|
const FsRangeOffsetSchema = z.number().int().min(0).finite();
|
|
324
|
-
const FsReadRangeArgsSchema = z.object({
|
|
301
|
+
export const FsReadRangeArgsSchema = z.object({
|
|
325
302
|
path: z.string(),
|
|
326
303
|
offset: FsRangeOffsetSchema,
|
|
327
304
|
length: FsRangeOffsetSchema,
|
|
@@ -366,7 +343,7 @@ const FsListArgsSchema = z.object({
|
|
|
366
343
|
limit: z.number().int().min(1).max(FS_LIST_PAGE_LIMIT).nullable(),
|
|
367
344
|
});
|
|
368
345
|
export async function _rpcFsRevision(self, path, pid) {
|
|
369
|
-
return
|
|
346
|
+
return self.supervisorOp({ op: 'fsRevision', args: [path], pid });
|
|
370
347
|
}
|
|
371
348
|
/**
|
|
372
349
|
* The facet's WebSocket relay. A facet does not open its own sockets: the
|
|
@@ -416,23 +393,21 @@ export async function _rpcWsClose(self, id, code, reason, pid) {
|
|
|
416
393
|
*/
|
|
417
394
|
export async function _rpcFsAcquire(self, epoch, cursor, pid) {
|
|
418
395
|
const args = FsAcquireArgsSchema.parse({ epoch, cursor });
|
|
419
|
-
return
|
|
396
|
+
return self.supervisorBridge(pid).acquire(args.epoch, args.cursor);
|
|
420
397
|
}
|
|
421
398
|
/**
|
|
422
399
|
* Enumerate the session filesystem for a process, one bounded page at a time.
|
|
423
400
|
*
|
|
424
|
-
* Goes through `
|
|
401
|
+
* Goes through `self.supervisorBridge(pid)` like every other fs RPC, so the listing
|
|
425
402
|
* is filtered by the calling process's own credential rather than the kernel's
|
|
426
403
|
* — a process must not learn of a path it could not stat.
|
|
427
404
|
*/
|
|
428
405
|
export async function _rpcFsList(self, after, limit, pid) {
|
|
429
406
|
const args = FsListArgsSchema.parse({ after: after ?? null, limit: limit ?? null });
|
|
430
|
-
return
|
|
407
|
+
return self.supervisorBridge(pid).list(args.after, args.limit ?? undefined);
|
|
431
408
|
}
|
|
432
|
-
export async function _rpcFsReadRange(self, path, offset, length, pid) {
|
|
433
|
-
|
|
434
|
-
const fs = runtimeFs(self, pid);
|
|
435
|
-
return withReadAllocation(await rangeReadBytes(fs, args.path, args.offset, args.length), () => fs.readRange(args.path, args.offset, args.length));
|
|
409
|
+
export async function _rpcFsReadRange(self, path, offset, length, pid, cred) {
|
|
410
|
+
return self.supervisorOp({ op: 'fsReadRange', args: [path, offset, length], pid, cred });
|
|
436
411
|
}
|
|
437
412
|
/**
|
|
438
413
|
* The same read, through the same process credential and the same bridge, with
|
|
@@ -449,9 +424,7 @@ export async function _rpcFsReadRange(self, path, offset, length, pid) {
|
|
|
449
424
|
* substrate that was supposed to relieve the coordinator damages it instead.
|
|
450
425
|
*/
|
|
451
426
|
export async function _rpcFsReadRangeUncached(self, path, offset, length, pid) {
|
|
452
|
-
|
|
453
|
-
const fs = runtimeFs(self, pid);
|
|
454
|
-
return withReadAllocation(await rangeReadBytes(fs, args.path, args.offset, args.length), () => fs.readRange(args.path, args.offset, args.length, { cached: false }));
|
|
427
|
+
return self.supervisorOp({ op: 'fsReadRangeUncached', args: [path, offset, length], pid });
|
|
455
428
|
}
|
|
456
429
|
/**
|
|
457
430
|
* Read many ranges in ONE round trip.
|
|
@@ -481,7 +454,7 @@ export async function _rpcFsReadBatch(self, requests, pid) {
|
|
|
481
454
|
// Sizing pass. A path this process may not stat contributes nothing and
|
|
482
455
|
// still gets its own entry below — denying one path must not deny the
|
|
483
456
|
// batch, which is what N separate reads would have done.
|
|
484
|
-
const fs =
|
|
457
|
+
const fs = self.supervisorBridge(pid);
|
|
485
458
|
let residentBytes = 0;
|
|
486
459
|
for (const request of args) {
|
|
487
460
|
try {
|
|
@@ -520,7 +493,7 @@ function readBatchEntryError(error) {
|
|
|
520
493
|
}
|
|
521
494
|
export async function _rpcFsWriteRange(self, path, offset, bytes, pid) {
|
|
522
495
|
const args = FsWriteRangeArgsSchema.parse({ path, offset });
|
|
523
|
-
return
|
|
496
|
+
return self.supervisorBridge(pid).writeRange(args.path, args.offset, normalizeWriteBatchChunkData(bytes));
|
|
524
497
|
}
|
|
525
498
|
export async function _rpcFsAppend(self, path, writerId, moduleId, operationId, bytes, pid) {
|
|
526
499
|
const args = FsAppendArgsSchema.parse({ path, writerId, moduleId, operationId });
|
|
@@ -532,7 +505,7 @@ export async function _rpcFsAppend(self, path, writerId, moduleId, operationId,
|
|
|
532
505
|
const data = normalizeWriteBatchChunkData(bytes);
|
|
533
506
|
const digestBytes = new Uint8Array(await crypto.subtle.digest('SHA-256', data));
|
|
534
507
|
const digest = Array.from(digestBytes, (byte) => byte.toString(16).padStart(2, '0')).join('');
|
|
535
|
-
return
|
|
508
|
+
return self.supervisorBridge(pid).appendOnce(args.path, processId, args.writerId, args.moduleId, sequence, digest, data);
|
|
536
509
|
}
|
|
537
510
|
export async function _rpcFsAppendAck(self, writerId, moduleId, operationId, pid) {
|
|
538
511
|
const args = FsAppendAckArgsSchema.parse({ writerId, moduleId, operationId });
|
|
@@ -541,17 +514,16 @@ export async function _rpcFsAppendAck(self, writerId, moduleId, operationId, pid
|
|
|
541
514
|
throw new Error('filesystem append operation exceeds the safe integer range');
|
|
542
515
|
}
|
|
543
516
|
const processId = processPid(pid);
|
|
544
|
-
await
|
|
517
|
+
await self.supervisorBridge(processId).acknowledgeAppend(processId, args.writerId, args.moduleId, sequence);
|
|
545
518
|
}
|
|
546
519
|
export async function _rpcFsTruncate(self, path, size, pid) {
|
|
547
|
-
|
|
548
|
-
await runtimeFs(self, pid).truncate(args.path, args.size);
|
|
520
|
+
await self.supervisorOp({ op: 'fsTruncate', args: [path, size], pid });
|
|
549
521
|
}
|
|
550
522
|
export async function _rpcFsOpen(self, path, flags, pid) {
|
|
551
|
-
return
|
|
523
|
+
return self.supervisorBridge(pid).open(path, flags || {});
|
|
552
524
|
}
|
|
553
525
|
export async function _rpcFsRead(self, handleId, offset, length, pid) {
|
|
554
|
-
return withReadAllocation(length, () =>
|
|
526
|
+
return withReadAllocation(length, () => self.supervisorBridge(pid).read(handleId, offset, length));
|
|
555
527
|
}
|
|
556
528
|
export async function _rpcFsWrite(self, handleId, offset, bytes, pid) {
|
|
557
529
|
let data;
|
|
@@ -561,10 +533,10 @@ export async function _rpcFsWrite(self, handleId, offset, bytes, pid) {
|
|
|
561
533
|
data = new Uint8Array(bytes);
|
|
562
534
|
else
|
|
563
535
|
data = new Uint8Array(bytes || []);
|
|
564
|
-
return
|
|
536
|
+
return self.supervisorBridge(pid).write(handleId, offset, data);
|
|
565
537
|
}
|
|
566
538
|
export async function _rpcFsClose(self, handleId, pid) {
|
|
567
|
-
await
|
|
539
|
+
await self.supervisorBridge(pid).close(handleId);
|
|
568
540
|
}
|
|
569
541
|
/**
|
|
570
542
|
* Called by CirrusHmrRPC.hmrSend. Runs in the DO's own context so
|
|
@@ -577,7 +549,7 @@ export async function _rpcHmrRelay(self, clientId, msg) {
|
|
|
577
549
|
self.cirrusReal.hmr.relayToBrowser(clientId, msg);
|
|
578
550
|
}
|
|
579
551
|
export async function _rpcUnlink(self, path, pid) {
|
|
580
|
-
await
|
|
552
|
+
await self.supervisorOp({ op: 'unlink', args: [path], pid });
|
|
581
553
|
}
|
|
582
554
|
/**
|
|
583
555
|
* Bulk-write files and directories via one transactionSync().
|
|
@@ -601,7 +573,7 @@ export async function _rpcWriteBatch(self, payload, pid) {
|
|
|
601
573
|
chunkId: c.chunkId,
|
|
602
574
|
data: normalizeWriteBatchChunkData(c.data),
|
|
603
575
|
}));
|
|
604
|
-
return
|
|
576
|
+
return self.sqliteFs.as(callerCred(self, pid)).writeBatch({
|
|
605
577
|
inodes,
|
|
606
578
|
chunks,
|
|
607
579
|
deletePaths,
|
|
@@ -660,10 +632,8 @@ export async function _rpcWriteBatchStream(self, stream, mutationOwner, pid) {
|
|
|
660
632
|
// total writeBatchStream RPCs at the coordinator (vs 620+ pre-fix).
|
|
661
633
|
// Workerd's input-gate queue depth on the coordinator stays well
|
|
662
634
|
// under the queue-age threshold without any user-space semaphore.
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
decodeDrainStartedAt,
|
|
666
|
-
mutationOwner,
|
|
635
|
+
return self.supervisorOp({
|
|
636
|
+
op: 'writeBatchStream', stream, mutationOwner, pid,
|
|
667
637
|
});
|
|
668
638
|
}
|
|
669
639
|
/**
|
|
@@ -695,6 +665,17 @@ function isPriorGenerationPid(self, pid) {
|
|
|
695
665
|
return pid > 0 && pid <= self.processes.pidBase;
|
|
696
666
|
}
|
|
697
667
|
export const PRIOR_GENERATION_EXIT_REASON = 'process lost: instance reset';
|
|
668
|
+
/**
|
|
669
|
+
* A process's output arrives as bytes: the relay from the facet carries
|
|
670
|
+
* Uint8Array so a binary protocol or an image survives it. The two text
|
|
671
|
+
* consumers here decode at their own edge — the log ring inside
|
|
672
|
+
* `appendOutputBytes`, and the terminal tee through these per-(pid, stream)
|
|
673
|
+
* streaming decoders, dropped when the process reports its exit.
|
|
674
|
+
*/
|
|
675
|
+
const _terminalTeeDecoders = new StreamTextDecoders();
|
|
676
|
+
function decodeForTerminal(pid, stream, data) {
|
|
677
|
+
return _terminalTeeDecoders.decode(`${pid}:${stream}`, data);
|
|
678
|
+
}
|
|
698
679
|
export async function _rpcStdout(self, pid, data) {
|
|
699
680
|
// Prior-generation straggler (facet outlived a DO instance reset): drop —
|
|
700
681
|
// its output must not merge into this generation's logs or shell.
|
|
@@ -707,9 +688,11 @@ export async function _rpcStdout(self, pid, data) {
|
|
|
707
688
|
// un-traceable facets.
|
|
708
689
|
try {
|
|
709
690
|
if (pid > 0)
|
|
710
|
-
self.processes.
|
|
691
|
+
self.processes.appendOutputBytes(pid, 'stdout', data);
|
|
711
692
|
if (self.terminal && shouldMirrorProcessOutputToShell(self, pid)) {
|
|
712
|
-
|
|
693
|
+
const text = decodeForTerminal(pid, 'stdout', data);
|
|
694
|
+
if (text.length > 0)
|
|
695
|
+
self.terminal.write(normalizeTerminalNewlines(text));
|
|
713
696
|
}
|
|
714
697
|
}
|
|
715
698
|
catch (e) {
|
|
@@ -730,11 +713,13 @@ export async function _rpcStderr(self, pid, data) {
|
|
|
730
713
|
return;
|
|
731
714
|
try {
|
|
732
715
|
if (pid > 0)
|
|
733
|
-
self.processes.
|
|
716
|
+
self.processes.appendOutputBytes(pid, 'stderr', data);
|
|
734
717
|
// Terminal gets red wrapping; the ring buffer keeps it raw so the
|
|
735
718
|
// stream tag can drive color decisions at replay time.
|
|
736
719
|
if (self.terminal && shouldMirrorProcessOutputToShell(self, pid)) {
|
|
737
|
-
|
|
720
|
+
const text = decodeForTerminal(pid, 'stderr', data);
|
|
721
|
+
if (text.length > 0)
|
|
722
|
+
self.terminal.write(`\x1b[31m${normalizeTerminalNewlines(text)}\x1b[0m`);
|
|
738
723
|
}
|
|
739
724
|
}
|
|
740
725
|
catch (e) {
|
|
@@ -782,6 +767,12 @@ export async function _rpcReportExit(self, pid, code, tail) {
|
|
|
782
767
|
self.processes.closeInput(pid);
|
|
783
768
|
}
|
|
784
769
|
catch { }
|
|
770
|
+
for (const stream of ['stdout', 'stderr']) {
|
|
771
|
+
const rest = _terminalTeeDecoders.drop(`${pid}:${stream}`);
|
|
772
|
+
if (rest.length > 0 && self.terminal && shouldMirrorProcessOutputToShell(self, pid)) {
|
|
773
|
+
self.terminal.write(normalizeTerminalNewlines(rest));
|
|
774
|
+
}
|
|
775
|
+
}
|
|
785
776
|
// A relayed socket is held open by the supervisor on the process's behalf,
|
|
786
777
|
// so it does not die when the facet does. Nothing else would ever close
|
|
787
778
|
// it, and a live one keeps buffering into the supervisor's heap.
|
|
@@ -789,7 +780,7 @@ export async function _rpcReportExit(self, pid, code, tail) {
|
|
|
789
780
|
self.webSocketRelay?.closeForPid(pid);
|
|
790
781
|
}
|
|
791
782
|
catch { }
|
|
792
|
-
self.
|
|
783
|
+
self.supervisorForgetBridge?.(pid);
|
|
793
784
|
if (tail)
|
|
794
785
|
self.processes.appendOutput(pid, 'stderr', tail);
|
|
795
786
|
// Guard against double-reporting: if we've already recorded exit
|
|
@@ -951,7 +942,7 @@ export function _reportExternalExit(self, pid, code, reason) {
|
|
|
951
942
|
self.webSocketRelay?.closeForPid(pid);
|
|
952
943
|
}
|
|
953
944
|
catch { }
|
|
954
|
-
self.
|
|
945
|
+
self.supervisorForgetBridge?.(pid);
|
|
955
946
|
if (reason) {
|
|
956
947
|
self.processes.appendOutput(pid, 'stderr', `[process killed: ${reason}]\n`);
|
|
957
948
|
}
|
|
@@ -1005,23 +996,21 @@ export async function _rpcPrefetch(self, cwd, entryCode) {
|
|
|
1005
996
|
// want to refresh the bundle mid-execution; today only the
|
|
1006
997
|
// SupervisorRPC.prefetch surface exposes it externally.
|
|
1007
998
|
self.ensureSqliteFs();
|
|
1008
|
-
|
|
1009
|
-
|
|
999
|
+
// Dynamic import stays: keeps the resolver out of this module's eager
|
|
1000
|
+
// graph (the original reason for the lazy load above).
|
|
1001
|
+
const { prefetchForRequire, ClosureBoundExceededError } = await import('@nimbus-sh/core/runtime/require-resolver.js');
|
|
1002
|
+
const outcome = prefetchForRequire(self.sqliteFs, entryCode, cwd);
|
|
1003
|
+
if ('kind' in outcome)
|
|
1004
|
+
throw new ClosureBoundExceededError(outcome);
|
|
1005
|
+
return outcome.bundle;
|
|
1010
1006
|
}
|
|
1011
1007
|
export async function _rpcRegisterPort(self, pid, port) {
|
|
1012
1008
|
// Port registration stores the facet association — the actual facet stub
|
|
1013
|
-
// is stored by FacetManager separately.
|
|
1014
|
-
//
|
|
1015
|
-
//
|
|
1016
|
-
//
|
|
1017
|
-
|
|
1018
|
-
await self.facetManager.registerPort(pid, port);
|
|
1019
|
-
return;
|
|
1020
|
-
}
|
|
1021
|
-
// No facet manager yet means nothing resident is running — a bare
|
|
1022
|
-
// registration retires the previous occupant's preview capability.
|
|
1023
|
-
await clearPortCapability(self, port);
|
|
1024
|
-
self.portRegistry.register(port, pid);
|
|
1009
|
+
// is stored by FacetManager separately. The same registration every
|
|
1010
|
+
// serving process uses: through the manager, so the pid's identity —
|
|
1011
|
+
// its journal row, or the process table — decides whether a reservation's
|
|
1012
|
+
// capability is re-adopted or retired.
|
|
1013
|
+
await registerServingPort(self, pid, port);
|
|
1025
1014
|
}
|
|
1026
1015
|
export async function _rpcUnregisterPort(self, port) {
|
|
1027
1016
|
self.portRegistry.unregister(port);
|
|
@@ -1062,14 +1051,29 @@ export async function _rpcCpSpawn(self, req) {
|
|
|
1062
1051
|
const fpm = self._ensureFacetProcessManager();
|
|
1063
1052
|
return fpm.spawn(req);
|
|
1064
1053
|
}
|
|
1054
|
+
/**
|
|
1055
|
+
* A child's stdin is bytes: esbuild's service protocol is binary packets,
|
|
1056
|
+
* and so is any pipe carrying an image or an archive. The facet queue and
|
|
1057
|
+
* this contract carry Uint8Array; the interactive input store is a text
|
|
1058
|
+
* channel fed by a terminal, so it decodes at its own edge with a streaming
|
|
1059
|
+
* decoder held per child, which keeps a multibyte character split across two
|
|
1060
|
+
* writes correct.
|
|
1061
|
+
*/
|
|
1062
|
+
const _cpStdinDecoders = new Map();
|
|
1065
1063
|
export async function _rpcCpStdinWrite(self, childPid, data) {
|
|
1066
1064
|
if (self.processes.hasInput(childPid)) {
|
|
1067
|
-
|
|
1065
|
+
let decoder = _cpStdinDecoders.get(childPid);
|
|
1066
|
+
if (!decoder) {
|
|
1067
|
+
decoder = new TextDecoder('utf-8');
|
|
1068
|
+
_cpStdinDecoders.set(childPid, decoder);
|
|
1069
|
+
}
|
|
1070
|
+
return self.processes.writeInput(childPid, decoder.decode(data, { stream: true }));
|
|
1068
1071
|
}
|
|
1069
1072
|
const fpm = self._ensureFacetProcessManager();
|
|
1070
1073
|
return fpm.stdinWrite(childPid, data);
|
|
1071
1074
|
}
|
|
1072
1075
|
export async function _rpcCpStdinEnd(self, childPid) {
|
|
1076
|
+
_cpStdinDecoders.delete(childPid);
|
|
1073
1077
|
if (self.processes.hasInput(childPid)) {
|
|
1074
1078
|
self.processes.endInput(childPid);
|
|
1075
1079
|
return;
|
|
@@ -1086,7 +1090,10 @@ export async function _rpcCpReadStdin(self, childPid, waitMs) {
|
|
|
1086
1090
|
return { signal: 'SIGKILL', ended: true };
|
|
1087
1091
|
}
|
|
1088
1092
|
if (self.processes.hasInput(childPid)) {
|
|
1089
|
-
|
|
1093
|
+
// The interactive input store holds text packets; the child's stdin
|
|
1094
|
+
// pump takes bytes, so this text producer encodes at its edge.
|
|
1095
|
+
const packet = await self.processes.readInput(childPid, waitMs);
|
|
1096
|
+
return { ...packet, data: enc.encode(packet.data) };
|
|
1090
1097
|
}
|
|
1091
1098
|
const fpm = self._ensureFacetProcessManager();
|
|
1092
1099
|
return fpm.cpReadStdin(childPid, waitMs);
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* session/serving-port.ts — how a process that serves a port is registered.
|
|
3
|
+
*
|
|
4
|
+
* One path for every serving pid, whether the facet manager launched it (a
|
|
5
|
+
* node/runtime resident with a journal row) or the session runs it in
|
|
6
|
+
* process (the Cirrus Vite shim, real-vite, `vite preview`, a builtin that
|
|
7
|
+
* adopted a shell wrapper pid). The manager's registration stamps the
|
|
8
|
+
* journal row when there is one, reads the process table's identity when
|
|
9
|
+
* there is not, and re-adopts a reservation the identity owns instead of
|
|
10
|
+
* retiring its capability — which is what lets a dev server exposed under a
|
|
11
|
+
* name come back on the same shared link after a restart or a hibernation.
|
|
12
|
+
*
|
|
13
|
+
* The bare registration below is only for a session that has no manager at
|
|
14
|
+
* all; every DO route that serves a port stands one up first.
|
|
15
|
+
*/
|
|
16
|
+
import type { PortRegistry } from '@nimbus-sh/core/runtime/port-registry.js';
|
|
17
|
+
import { type PortCapabilityHost } from './port-capability.js';
|
|
18
|
+
export interface ServingPortHost {
|
|
19
|
+
ctx: PortCapabilityHost['ctx'];
|
|
20
|
+
portRegistry: PortRegistry;
|
|
21
|
+
facetManager: {
|
|
22
|
+
registerPort(pid: number, port: number): Promise<void>;
|
|
23
|
+
} | null;
|
|
24
|
+
ensureFacetManager?(): void;
|
|
25
|
+
}
|
|
26
|
+
export declare function registerServingPort(self: ServingPortHost, pid: number, port: number): Promise<void>;
|
|
27
|
+
//# sourceMappingURL=serving-port.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"serving-port.d.ts","sourceRoot":"","sources":["../../src/session/serving-port.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,0CAA0C,CAAC;AAC7E,OAAO,EAAuB,KAAK,kBAAkB,EAAE,MAAM,sBAAsB,CAAC;AAEpF,MAAM,WAAW,eAAe;IAC9B,GAAG,EAAE,kBAAkB,CAAC,KAAK,CAAC,CAAC;IAC/B,YAAY,EAAE,YAAY,CAAC;IAC3B,YAAY,EAAE;QAAE,YAAY,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAA;KAAE,GAAG,IAAI,CAAC;IAChF,kBAAkB,CAAC,IAAI,IAAI,CAAC;CAC7B;AAED,wBAAsB,mBAAmB,CAAC,IAAI,EAAE,eAAe,EAAE,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAUzG"}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* session/serving-port.ts — how a process that serves a port is registered.
|
|
3
|
+
*
|
|
4
|
+
* One path for every serving pid, whether the facet manager launched it (a
|
|
5
|
+
* node/runtime resident with a journal row) or the session runs it in
|
|
6
|
+
* process (the Cirrus Vite shim, real-vite, `vite preview`, a builtin that
|
|
7
|
+
* adopted a shell wrapper pid). The manager's registration stamps the
|
|
8
|
+
* journal row when there is one, reads the process table's identity when
|
|
9
|
+
* there is not, and re-adopts a reservation the identity owns instead of
|
|
10
|
+
* retiring its capability — which is what lets a dev server exposed under a
|
|
11
|
+
* name come back on the same shared link after a restart or a hibernation.
|
|
12
|
+
*
|
|
13
|
+
* The bare registration below is only for a session that has no manager at
|
|
14
|
+
* all; every DO route that serves a port stands one up first.
|
|
15
|
+
*/
|
|
16
|
+
import { clearPortCapability } from './port-capability.js';
|
|
17
|
+
export async function registerServingPort(self, pid, port) {
|
|
18
|
+
self.ensureFacetManager?.();
|
|
19
|
+
if (self.facetManager) {
|
|
20
|
+
await self.facetManager.registerPort(pid, port);
|
|
21
|
+
return;
|
|
22
|
+
}
|
|
23
|
+
// No manager means nothing resident is running — a bare registration
|
|
24
|
+
// retires the previous occupant's preview capability.
|
|
25
|
+
await clearPortCapability(self, port);
|
|
26
|
+
self.portRegistry.register(port, pid);
|
|
27
|
+
}
|
|
@@ -26,6 +26,18 @@ export interface StartRealViteOptions {
|
|
|
26
26
|
/** Directory the user's vite.config.{ts,js,mjs} is searched in (the shell
|
|
27
27
|
* cwd at start). Persisted so restore can re-bundle it. */
|
|
28
28
|
configDir: string;
|
|
29
|
+
/**
|
|
30
|
+
* The process-table cwd+argv the dev server's pid is given — what the app
|
|
31
|
+
* verbs derive its identity from. The `vite` builtin passes the wrapper
|
|
32
|
+
* pid's own (or the argv it was invoked with); restore passes what was
|
|
33
|
+
* persisted, so the restored server is the same application. Absent for
|
|
34
|
+
* configs written before identity was persisted: those keep the bare
|
|
35
|
+
* `[]` at the root, the same across every restore.
|
|
36
|
+
*/
|
|
37
|
+
identity?: {
|
|
38
|
+
cwd: string;
|
|
39
|
+
argv: string[];
|
|
40
|
+
};
|
|
29
41
|
/** Optional abort signal threaded into the heavy-alloc gate. */
|
|
30
42
|
signal?: AbortSignal;
|
|
31
43
|
/** Called with a human message if vite.config pre-bundling fails (so the
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"start-real-vite.d.ts","sourceRoot":"","sources":["../../src/session/start-real-vite.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAKH,OAAO,EAAE,UAAU,EAAE,MAAM,0BAA0B,CAAC;AAMtD,MAAM,WAAW,oBAAoB;IACnC,2CAA2C;IAC3C,IAAI,EAAE,MAAM,CAAC;IACb,uDAAuD;IACvD,IAAI,EAAE,MAAM,CAAC;IACb,4DAA4D;IAC5D,QAAQ,EAAE,MAAM,CAAC;IACjB;gEAC4D;IAC5D,SAAS,EAAE,MAAM,CAAC;IAClB,gEAAgE;IAChE,MAAM,CAAC,EAAE,WAAW,CAAC;IACrB;4EACwE;IACxE,aAAa,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC;CAC3C;AAED,MAAM,WAAW,mBAAmB;IAClC,UAAU,EAAE,UAAU,CAAC;IACvB,+EAA+E;IAC/E,gBAAgB,EAAE,MAAM,GAAG,IAAI,CAAC;IAChC,8CAA8C;IAC9C,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;CACxB;AAED;;;GAGG;AACH,wBAAsB,aAAa,CAAC,IAAI,EAAE,GAAG,EAAE,IAAI,EAAE,oBAAoB,GAAG,OAAO,CAAC,mBAAmB,CAAC,CA8GvG"}
|
|
1
|
+
{"version":3,"file":"start-real-vite.d.ts","sourceRoot":"","sources":["../../src/session/start-real-vite.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAKH,OAAO,EAAE,UAAU,EAAE,MAAM,0BAA0B,CAAC;AAMtD,MAAM,WAAW,oBAAoB;IACnC,2CAA2C;IAC3C,IAAI,EAAE,MAAM,CAAC;IACb,uDAAuD;IACvD,IAAI,EAAE,MAAM,CAAC;IACb,4DAA4D;IAC5D,QAAQ,EAAE,MAAM,CAAC;IACjB;gEAC4D;IAC5D,SAAS,EAAE,MAAM,CAAC;IAClB;;;;;;;OAOG;IACH,QAAQ,CAAC,EAAE;QAAE,GAAG,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,EAAE,CAAA;KAAE,CAAC;IAC3C,gEAAgE;IAChE,MAAM,CAAC,EAAE,WAAW,CAAC;IACrB;4EACwE;IACxE,aAAa,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC;CAC3C;AAED,MAAM,WAAW,mBAAmB;IAClC,UAAU,EAAE,UAAU,CAAC;IACvB,+EAA+E;IAC/E,gBAAgB,EAAE,MAAM,GAAG,IAAI,CAAC;IAChC,8CAA8C;IAC9C,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;CACxB;AAED;;;GAGG;AACH,wBAAsB,aAAa,CAAC,IAAI,EAAE,GAAG,EAAE,IAAI,EAAE,oBAAoB,GAAG,OAAO,CAAC,mBAAmB,CAAC,CA8GvG"}
|