@nimbus-sh/worker 0.10.0 → 0.11.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/NOTICE.md +5 -0
- package/README.md +10 -0
- package/dist/_shared/session-router.d.ts +7 -0
- package/dist/_shared/session-router.d.ts.map +1 -1
- package/dist/_shared/session-router.js +7 -0
- package/dist/bindings/body.d.ts +6 -0
- package/dist/bindings/body.d.ts.map +1 -0
- package/dist/bindings/body.js +37 -0
- package/dist/bindings/kv.d.ts +0 -2
- package/dist/bindings/kv.d.ts.map +1 -1
- package/dist/bindings/kv.js +3 -42
- package/dist/bindings/r2.d.ts +0 -2
- package/dist/bindings/r2.d.ts.map +1 -1
- package/dist/bindings/r2.js +4 -44
- package/dist/esbuild-cli-artifact.generated.d.ts +18 -0
- package/dist/esbuild-cli-artifact.generated.d.ts.map +1 -0
- package/dist/esbuild-cli-artifact.generated.js +17 -0
- package/dist/facets/cirrus-real.d.ts.map +1 -1
- package/dist/facets/cirrus-real.js +9 -4
- package/dist/facets/compose.d.ts +11 -7
- package/dist/facets/compose.d.ts.map +1 -1
- package/dist/facets/compose.js +8 -38
- package/dist/facets/data-plan.d.ts +79 -0
- package/dist/facets/data-plan.d.ts.map +1 -0
- package/dist/facets/data-plan.js +477 -0
- package/dist/facets/esbuild-transform.d.ts +36 -10
- package/dist/facets/esbuild-transform.d.ts.map +1 -1
- package/dist/facets/esbuild-transform.js +216 -20
- package/dist/facets/exec-telemetry.d.ts +7 -3
- package/dist/facets/exec-telemetry.d.ts.map +1 -1
- package/dist/facets/manager.d.ts +179 -78
- package/dist/facets/manager.d.ts.map +1 -1
- package/dist/facets/manager.js +1221 -649
- package/dist/facets/opencode-staging.d.ts +0 -2
- package/dist/facets/opencode-staging.d.ts.map +1 -1
- package/dist/facets/opencode-staging.js +5 -11
- package/dist/facets/process.d.ts +4 -0
- package/dist/facets/process.d.ts.map +1 -1
- package/dist/facets/process.js +3 -0
- package/dist/facets/read-profile.d.ts +149 -0
- package/dist/facets/read-profile.d.ts.map +1 -0
- package/dist/facets/read-profile.js +483 -0
- package/dist/facets/resident-identity.d.ts +0 -1
- package/dist/facets/resident-identity.d.ts.map +1 -1
- package/dist/facets/resident-identity.js +0 -3
- package/dist/facets/wasm-swap-registry.d.ts +34 -25
- package/dist/facets/wasm-swap-registry.d.ts.map +1 -1
- package/dist/facets/wasm-swap-registry.js +62 -56
- package/dist/facets/ws-terminal.d.ts +4 -4
- package/dist/facets/ws-terminal.d.ts.map +1 -1
- package/dist/facets/ws-terminal.js +4 -5
- package/dist/git/commands.d.ts +16 -9
- package/dist/git/commands.d.ts.map +1 -1
- package/dist/git/commands.js +1818 -188
- package/dist/git/network-facet.d.ts +10 -2
- package/dist/git/network-facet.d.ts.map +1 -1
- package/dist/git/network-facet.js +62 -16
- package/dist/git/unified-diff.d.ts +74 -0
- package/dist/git/unified-diff.d.ts.map +1 -0
- package/dist/git/unified-diff.js +676 -0
- package/dist/git-bundle.generated.d.ts +7 -11
- package/dist/git-bundle.generated.d.ts.map +1 -1
- package/dist/git-bundle.generated.js +7 -11
- package/dist/hosted/commands.d.ts.map +1 -1
- package/dist/hosted/commands.js +62 -243
- package/dist/hosted/runtime.d.ts +19 -13
- package/dist/hosted/runtime.d.ts.map +1 -1
- package/dist/hosted/runtime.js +71 -14
- package/dist/hosted/services.d.ts +6 -7
- package/dist/hosted/services.d.ts.map +1 -1
- package/dist/hosted/services.js +10 -14
- package/dist/hosted/session.d.ts +165 -0
- package/dist/hosted/session.d.ts.map +1 -0
- package/dist/hosted/session.js +132 -0
- package/dist/loaders/generated-workers.d.ts +5 -2
- package/dist/loaders/generated-workers.d.ts.map +1 -1
- package/dist/loaders/generated-workers.js +6 -3
- package/dist/loaders/npm-resolve-preamble.d.ts.map +1 -1
- package/dist/loaders/npm-resolve-preamble.js +0 -27
- package/dist/node-shims-artifact.generated.d.ts +13 -4
- package/dist/node-shims-artifact.generated.d.ts.map +1 -1
- package/dist/node-shims-artifact.generated.js +16 -7
- package/dist/npm/bin-links.d.ts +3 -1
- package/dist/npm/bin-links.d.ts.map +1 -1
- package/dist/npm/bin-links.js +32 -8
- package/dist/npm/cache.d.ts +5 -0
- package/dist/npm/cache.d.ts.map +1 -1
- package/dist/npm/cache.js +13 -1
- package/dist/npm/install-batch-facet.d.ts +2 -2
- package/dist/npm/install-batch-facet.js +3 -3
- package/dist/npm/installer.d.ts +17 -1
- package/dist/npm/installer.d.ts.map +1 -1
- package/dist/npm/installer.js +159 -20
- package/dist/npm/package-lock.d.ts +32 -0
- package/dist/npm/package-lock.d.ts.map +1 -0
- package/dist/npm/package-lock.js +65 -0
- package/dist/npm/pre-bundle-facet.d.ts +1 -30
- package/dist/npm/pre-bundle-facet.d.ts.map +1 -1
- package/dist/npm/pre-bundle-facet.js +3 -5
- package/dist/npm/r2-cache.d.ts +2 -0
- package/dist/npm/r2-cache.d.ts.map +1 -1
- package/dist/npm/r2-cache.js +2 -0
- package/dist/npm/resolve-one-facet.d.ts.map +1 -1
- package/dist/npm/resolve-one-facet.js +14 -3
- package/dist/npm/resolver.d.ts +0 -7
- package/dist/npm/resolver.d.ts.map +1 -1
- package/dist/npm/resolver.js +0 -22
- package/dist/opencode-artifact.generated.js +2 -2
- package/dist/replica/routing.d.ts +2 -38
- package/dist/replica/routing.d.ts.map +1 -1
- package/dist/replica/routing.js +3 -55
- package/dist/router/index.d.ts.map +1 -1
- package/dist/router/index.js +15 -2
- package/dist/router/public-directory.d.ts +18 -0
- package/dist/router/public-directory.d.ts.map +1 -1
- package/dist/router/public-directory.js +1 -1
- package/dist/router/remote-api.d.ts +3 -1
- package/dist/router/remote-api.d.ts.map +1 -1
- package/dist/router/remote-api.js +42 -79
- package/dist/runtime/bash-repl.js +2 -2
- package/dist/runtime/bun-repl.d.ts.map +1 -1
- package/dist/runtime/bun-repl.js +2 -13
- package/dist/runtime/esbuild-wasm-bytes.d.ts +17 -5
- package/dist/runtime/esbuild-wasm-bytes.d.ts.map +1 -1
- package/dist/runtime/esbuild-wasm-bytes.js +43 -94
- package/dist/runtime/git-bundle-artifact.d.ts +17 -0
- package/dist/runtime/git-bundle-artifact.d.ts.map +1 -0
- package/dist/runtime/git-bundle-artifact.js +25 -0
- package/dist/runtime/node-repl.d.ts.map +1 -1
- package/dist/runtime/node-repl.js +2 -13
- package/dist/runtime/node-shims-artifact.d.ts +22 -23
- package/dist/runtime/node-shims-artifact.d.ts.map +1 -1
- package/dist/runtime/node-shims-artifact.js +48 -78
- package/dist/runtime/node-shims.d.ts.map +1 -1
- package/dist/runtime/node-shims.js +1567 -864
- package/dist/runtime/opencode-artifact.d.ts.map +1 -1
- package/dist/runtime/opencode-artifact.js +17 -53
- package/dist/runtime/opencode-facet-runner.d.ts +3 -6
- package/dist/runtime/opencode-facet-runner.d.ts.map +1 -1
- package/dist/runtime/opencode-facet-runner.js +45 -10
- package/dist/runtime/opentui-wasm-bytes.d.ts.map +1 -1
- package/dist/runtime/opentui-wasm-bytes.js +16 -49
- package/dist/runtime/package-manager.d.ts +0 -2
- package/dist/runtime/package-manager.d.ts.map +1 -1
- package/dist/runtime/package-manager.js +0 -3
- package/dist/runtime/python-repl.d.ts.map +1 -1
- package/dist/runtime/python-repl.js +2 -2
- package/dist/runtime/repl-session.d.ts +10 -0
- package/dist/runtime/repl-session.d.ts.map +1 -1
- package/dist/runtime/repl-session.js +7 -0
- package/dist/runtime/ruby-repl.d.ts.map +1 -1
- package/dist/runtime/ruby-repl.js +2 -2
- package/dist/runtime/ruby-resident.d.ts.map +1 -1
- package/dist/runtime/ruby-resident.js +36 -35
- package/dist/runtime/runtime-catalog.d.ts +10 -3
- package/dist/runtime/runtime-catalog.d.ts.map +1 -1
- package/dist/runtime/runtime-catalog.js +125 -15
- package/dist/runtime/sqlite-wasm-bytes.d.ts +4 -4
- package/dist/runtime/sqlite-wasm-bytes.d.ts.map +1 -1
- package/dist/runtime/sqlite-wasm-bytes.js +21 -57
- package/dist/runtime/staged-source.d.ts +67 -0
- package/dist/runtime/staged-source.d.ts.map +1 -0
- package/dist/runtime/staged-source.js +113 -0
- package/dist/runtime/wasi/preamble.d.ts.map +1 -1
- package/dist/runtime/wasi/preamble.js +0 -24
- package/dist/runtime-catalog.generated.js +1 -1
- package/dist/session/agent.d.ts +14 -2
- package/dist/session/agent.d.ts.map +1 -1
- package/dist/session/agent.js +57 -19
- package/dist/session/ai.d.ts +0 -11
- package/dist/session/ai.d.ts.map +1 -1
- package/dist/session/ai.js +0 -4
- package/dist/session/fs-watch.d.ts +0 -11
- package/dist/session/fs-watch.d.ts.map +1 -1
- package/dist/session/fs-watch.js +0 -21
- package/dist/session/hibernation.d.ts +34 -11
- package/dist/session/hibernation.d.ts.map +1 -1
- package/dist/session/hibernation.js +46 -29
- package/dist/session/init-phases.d.ts +1 -2
- package/dist/session/init-phases.d.ts.map +1 -1
- package/dist/session/init-phases.js +1 -2
- package/dist/session/init.d.ts.map +1 -1
- package/dist/session/init.js +7 -20
- package/dist/session/keys.d.ts +0 -3
- package/dist/session/keys.d.ts.map +1 -1
- package/dist/session/keys.js +0 -3
- package/dist/session/legacy-reset.d.ts +11 -0
- package/dist/session/legacy-reset.d.ts.map +1 -0
- package/dist/session/legacy-reset.js +16 -0
- package/dist/session/nimbus-session.d.ts +41 -15
- package/dist/session/nimbus-session.d.ts.map +1 -1
- package/dist/session/nimbus-session.js +64 -70
- package/dist/session/npm-install-port.d.ts.map +1 -1
- package/dist/session/npm-install-port.js +1 -0
- package/dist/session/programmatic.d.ts +13 -18
- package/dist/session/programmatic.d.ts.map +1 -1
- package/dist/session/programmatic.js +53 -39
- package/dist/session/replica-routes.d.ts +2 -3
- package/dist/session/replica-routes.d.ts.map +1 -1
- package/dist/session/replica-routes.js +3 -10
- package/dist/session/routes.d.ts.map +1 -1
- package/dist/session/routes.js +7 -10
- package/dist/session/rpc.d.ts +104 -20
- package/dist/session/rpc.d.ts.map +1 -1
- package/dist/session/rpc.js +184 -37
- package/dist/session/start-real-vite.js +2 -2
- package/dist/session/state-store.d.ts +1 -17
- package/dist/session/state-store.d.ts.map +1 -1
- package/dist/session/state-store.js +3 -53
- package/dist/session/supervisor-op.d.ts +7 -0
- package/dist/session/supervisor-op.d.ts.map +1 -1
- package/dist/session/supervisor-op.js +6 -1
- package/dist/session/supervisor-rpc.d.ts +104 -15
- package/dist/session/supervisor-rpc.d.ts.map +1 -1
- package/dist/session/supervisor-rpc.js +188 -71
- package/dist/session/vite-command.d.ts.map +1 -1
- package/dist/session/vite-command.js +17 -14
- package/dist/session/ws.d.ts.map +1 -1
- package/dist/session/ws.js +20 -8
- package/dist/shell/npm-bin-entrypoints.d.ts.map +1 -1
- package/dist/shell/npm-bin-entrypoints.js +30 -5
- package/dist/vfs/facet-resident-limits.d.ts +33 -0
- package/dist/vfs/facet-resident-limits.d.ts.map +1 -0
- package/dist/vfs/facet-resident-limits.js +33 -0
- package/dist/vfs/facet-resident-store.d.ts +2 -10
- package/dist/vfs/facet-resident-store.d.ts.map +1 -1
- package/dist/vfs/facet-resident-store.js +1594 -219
- package/dist/workspace-host.d.ts +2 -0
- package/dist/workspace-host.d.ts.map +1 -1
- package/dist/workspace-host.js +2 -0
- package/dist/wrangler/nimbus-wrangler.d.ts +0 -2
- package/dist/wrangler/nimbus-wrangler.d.ts.map +1 -1
- package/dist/wrangler/nimbus-wrangler.js +5 -22
- package/package.json +8 -7
- package/public/_assets/opencode/1.16.2/index-attach.js +2 -2
- package/public/_assets/runtime/esbuild-cli-c4fda380d52befc1.js +6892 -0
- package/public/_assets/runtime/git-de3e60c9f3ff006a.js +103 -0
- package/public/_assets/runtime/{node-shims-7b4dd7a76d95d21e.js → node-shims-06565b121555c194.js} +2089 -861
- package/public/_assets/runtime/resident-store-6ffb1939c53d982f.js +2264 -0
- package/public/_assets/runtime/vfs-write-ledger-e501e8fc793bc2c1.js +889 -0
- package/scripts/build-opencode-attach-entry.mjs +51 -1
- package/scripts/bundle-facet-workers.mjs +114 -3
- package/scripts/bundle-git.mjs +88 -27
- package/scripts/bundle-node-shims.mjs +72 -46
- package/scripts/bundle-runtime.mjs +18 -421
- package/scripts/cf-git-patch.mjs +137 -0
- package/scripts/patch-install-deps.mjs +49 -96
- package/scripts/runtime-specs.mjs +435 -0
- package/vendor/git-http.generated.d.ts +82 -0
- package/vendor/git-upstream.generated.d.ts +4378 -0
- package/vendor/git.LICENSE +7 -0
- package/vendor/git.generated.d.mts +21 -0
- package/vendor/git.generated.mjs +103 -0
- package/dist/replica/suspension.d.ts +0 -36
- package/dist/replica/suspension.d.ts.map +0 -1
- package/dist/replica/suspension.js +0 -49
- package/dist/runtime/static-server.d.ts +0 -3
- package/dist/runtime/static-server.d.ts.map +0 -1
- package/dist/runtime/static-server.js +0 -133
- package/scripts/clean-dist.mjs +0 -7
|
@@ -4,12 +4,15 @@
|
|
|
4
4
|
* Exported from index.ts. Facets receive `env.SUPERVISOR` service binding
|
|
5
5
|
* pointing to this class via ctx.exports loopback binding.
|
|
6
6
|
*
|
|
7
|
-
* Props: { doId: string, pid: number, writerId: string, route: HostRoute }
|
|
7
|
+
* Props: { doId: string, pid: number, writerId: string, route: HostRoute, hostIncarnation?: string }
|
|
8
8
|
* doId — the supervisor DO's durable object ID (for routing)
|
|
9
9
|
* pid — the process ID (for stdout/stderr routing)
|
|
10
10
|
* writerId — the active append-writer incarnation for this process
|
|
11
11
|
* route — the host namespace and dispatch method, minted with the binding
|
|
12
12
|
* in the host's isolate; this entrypoint may answer from another
|
|
13
|
+
* hostIncarnation — the host instance that minted the binding, present
|
|
14
|
+
* when that host applies delivered mutations once
|
|
15
|
+
* (@nimbus-sh/core/workspace/supervisor-delivery.js)
|
|
13
16
|
*
|
|
14
17
|
* Methods callable by facets via RPC:
|
|
15
18
|
* readFile(path) → string | null
|
|
@@ -22,16 +25,29 @@
|
|
|
22
25
|
* fsOpen/fsRead/fsWrite/fsClose/readlink/symlink/rename/rmdir/fsRevision
|
|
23
26
|
* fsReadRange/fsWriteRange/fsAppend/fsAppendAck/fsTruncate
|
|
24
27
|
* → shared RuntimeFsBridge operations
|
|
25
|
-
* fsReadBatch(requests) → per-
|
|
28
|
+
* fsReadBatch(requests) → per-request results (many reads and lstats, one round trip)
|
|
26
29
|
* fsList(after, limit) → one page of what EXISTS, with per-path revisions
|
|
27
30
|
* writeBatch(payload) → { inodes, chunks } (bulk atomic write)
|
|
28
31
|
* stdout(data) → void (pushed to WebSocket + ring buffer)
|
|
29
32
|
* stderr(data) → void
|
|
30
33
|
* reportExit(code, tail?) → void (called from facet's finally block)
|
|
31
34
|
* prefetch(cwd, entryCode) → Record<string, string>
|
|
35
|
+
*
|
|
36
|
+
* Delivery: every call reaches the session over a Durable Object stub the
|
|
37
|
+
* platform can drop ("Network connection lost.", `retryable`). Reads are
|
|
38
|
+
* re-sent on a fresh stub, and hedged: one unanswered after
|
|
39
|
+
* SUPERVISOR_READ_HEDGE_AFTER_MS is sent again while it stays in flight.
|
|
40
|
+
* Filesystem mutations, on a binding that names its
|
|
41
|
+
* host's incarnation, are re-sent under one delivery id that host applies at
|
|
42
|
+
* most once (`_fsMutation`); on any other binding they are sent once.
|
|
43
|
+
* Appends are re-sent under the append ledger's identity. Everything else is
|
|
44
|
+
* sent once and a drop surfaces.
|
|
32
45
|
*/
|
|
33
46
|
import { WorkerEntrypoint } from 'cloudflare:workers';
|
|
34
47
|
import { hostNamespaceBinding, hostOpDispatch } from '@nimbus-sh/fabric/host-dispatch.js';
|
|
48
|
+
import { idempotent } from '@nimbus-sh/fabric/do-calls.js';
|
|
49
|
+
import { SUPERVISOR_DELIVER_OP, } from '@nimbus-sh/core/workspace/supervisor-delivery.js';
|
|
50
|
+
import { VFS_DELIVERY_RETRY_WINDOW_MS } from '@nimbus-sh/core/constants.js';
|
|
35
51
|
// W5: OOM discriminator — record last-known RPC frame on writeBatch entry
|
|
36
52
|
import { setLastRpcFrame } from '@nimbus-sh/platform/oom-discriminator.js';
|
|
37
53
|
// Phase 2 A'.2 — supervisor in-flight RPC payload byte tracking.
|
|
@@ -39,6 +55,7 @@ import { rpcPayloadStart, rpcPayloadEnd } from '@nimbus-sh/platform/diag-counter
|
|
|
39
55
|
// W4: R2 cross-tenant npm cache (tarballs + packuments)
|
|
40
56
|
import { R2CacheClient, MAX_R2_TARBALL_BYTES } from '../npm/r2-cache.js';
|
|
41
57
|
import { useRpcResource } from '@nimbus-sh/platform/rpc-dispose.js';
|
|
58
|
+
import { fsReadBatchRequestBytes } from './rpc.js';
|
|
42
59
|
import { W7_MAX_RECORD_BYTES } from '@nimbus-sh/platform/w7-frame.js';
|
|
43
60
|
/**
|
|
44
61
|
* Drain the per-call event list captured by R2CacheClient during this
|
|
@@ -80,29 +97,104 @@ function _estimateWriteBatchBytes(payload) {
|
|
|
80
97
|
// The fabric mints `env.SUPERVISOR` bindings for the programs it hosts; the
|
|
81
98
|
// worker's composition root (src/index.ts) names this class to the fabric
|
|
82
99
|
// with composeFabric.
|
|
100
|
+
// A process's filesystem read (SupervisorRPC → session) still unanswered
|
|
101
|
+
// after this long is sent again on a fresh stub, the first left running and
|
|
102
|
+
// the first answer taken (fabric do-calls `hedgeAfterMs`). Measured on a
|
|
103
|
+
// throwaway under three concurrent sessions, 2026-09-28: none of the 521
|
|
104
|
+
// read batches that answered took more than 5 s at the facet's side, the
|
|
105
|
+
// session served each read it received without waiting on I/O, and the 11
|
|
106
|
+
// attempts that stalled — none of which reached the session — were still
|
|
107
|
+
// pending 110–560 s later. So an attempt past 5 s is one that is not coming
|
|
108
|
+
// back, and a hedge then costs a duplicate read only when that measurement
|
|
109
|
+
// was wrong.
|
|
110
|
+
export const SUPERVISOR_READ_HEDGE_AFTER_MS = 5_000;
|
|
83
111
|
export class SupervisorRPC extends WorkerEntrypoint {
|
|
84
112
|
/**
|
|
85
|
-
*
|
|
86
|
-
*
|
|
87
|
-
*
|
|
113
|
+
* A fresh stub for the host, by the route the binding carries, per call.
|
|
114
|
+
* The platform serves this entrypoint from whichever isolate it likes; the
|
|
115
|
+
* props were minted in the host's.
|
|
88
116
|
*/
|
|
89
|
-
|
|
90
|
-
const
|
|
91
|
-
const doId = props.doId;
|
|
117
|
+
_host() {
|
|
118
|
+
const doId = this.ctx.props?.doId;
|
|
92
119
|
if (typeof doId !== 'string' || doId.length === 0) {
|
|
93
120
|
throw new Error('SupervisorRPC: missing doId in props');
|
|
94
121
|
}
|
|
95
|
-
const namespace = hostNamespaceBinding(this.env, 'SupervisorRPC',
|
|
96
|
-
|
|
97
|
-
|
|
122
|
+
const namespace = hostNamespaceBinding(this.env, 'SupervisorRPC', this._route());
|
|
123
|
+
return namespace.get(namespace.idFromString(doId));
|
|
124
|
+
}
|
|
125
|
+
_route() {
|
|
126
|
+
return this.ctx.props?.route;
|
|
98
127
|
}
|
|
99
128
|
_op(op, args = [], extra = {}) {
|
|
100
|
-
return this.
|
|
129
|
+
return hostOpDispatch(this._host(), 'SupervisorRPC', this._route())({ op, args, ...extra });
|
|
101
130
|
}
|
|
102
131
|
/** Stamp filesystem credentials from the binding, not the supplied arguments. */
|
|
103
132
|
_fsOp(op, args = []) {
|
|
104
133
|
return this._op(op, args, { pid: this._pid() });
|
|
105
134
|
}
|
|
135
|
+
/**
|
|
136
|
+
* A filesystem read changes nothing on the host, so a call the platform
|
|
137
|
+
* dropped on the way to it is repeated on a fresh stub. Measured: the
|
|
138
|
+
* host's `stat` failing with "Network connection lost." (`retryable`) is
|
|
139
|
+
* what failed CPython's start in about one fresh session in twenty.
|
|
140
|
+
*
|
|
141
|
+
* A read can also never answer: under concurrent sessions a burst of reads
|
|
142
|
+
* from one facet left some attempts pending for minutes without reaching
|
|
143
|
+
* the host, and the program waiting on them never exited
|
|
144
|
+
* (preview/new/lucide-barrel-cache-widens). So a read still unanswered
|
|
145
|
+
* after SUPERVISOR_READ_HEDGE_AFTER_MS is hedged: sent again on a fresh
|
|
146
|
+
* stub, the first attempt left running, the first answer taken.
|
|
147
|
+
*
|
|
148
|
+
* A read can equally be slow at the session — queued behind the read
|
|
149
|
+
* budget, a lazy import, a busy input gate — and a hedge must not make it
|
|
150
|
+
* read again there. So every attempt carries the one read id minted here,
|
|
151
|
+
* and the session joins a repeat to the read it is still serving
|
|
152
|
+
* (`SupervisorDeliveries.joinRead`): a hedge that did arrive costs the
|
|
153
|
+
* session nothing but a second copy of the answer. Mutations are not
|
|
154
|
+
* hedged: their repeats stay bounded by the delivery retry window.
|
|
155
|
+
*/
|
|
156
|
+
_fsRead(op, args = []) {
|
|
157
|
+
return this._resent({ op, args, pid: this._pid(), readId: crypto.randomUUID() }, { hedgeAfterMs: SUPERVISOR_READ_HEDGE_AFTER_MS });
|
|
158
|
+
}
|
|
159
|
+
/**
|
|
160
|
+
* A filesystem mutation, delivered exactly once. The platform drops this
|
|
161
|
+
* hop too — measured: pip's `fsWrite` of a wheel member and a FileHandle
|
|
162
|
+
* write loop, each failing "Network connection lost." (`retryable`) as
|
|
163
|
+
* EIO — and a dropped mutation may or may not have run.
|
|
164
|
+
*
|
|
165
|
+
* So on a binding whose host names its incarnation, every attempt carries
|
|
166
|
+
* the one delivery id minted here, under SUPERVISOR_DELIVER_OP, and that
|
|
167
|
+
* host instance applies the id at most once: a repeat of a mutation that
|
|
168
|
+
* ran is answered from its receipt and never applied again, even over
|
|
169
|
+
* another writer's newer write; one that never arrived applies on the
|
|
170
|
+
* repeat. Any other instance, and any host that predates delivery, refuses
|
|
171
|
+
* the envelope outright, and that refusal is never repeated. Repeats stop
|
|
172
|
+
* VFS_DELIVERY_RETRY_WINDOW_MS after the first attempt, inside the host's
|
|
173
|
+
* receipt retention.
|
|
174
|
+
*
|
|
175
|
+
* A binding minted by a host that dedupes nothing names no incarnation,
|
|
176
|
+
* and its mutations are sent once.
|
|
177
|
+
*
|
|
178
|
+
* The id is random because this entrypoint keeps nothing between calls and
|
|
179
|
+
* may answer from any isolate; the pid still comes from the binding.
|
|
180
|
+
*/
|
|
181
|
+
_fsMutation(op, args) {
|
|
182
|
+
const hostIncarnation = this._hostIncarnation();
|
|
183
|
+
if (hostIncarnation === undefined)
|
|
184
|
+
return this._fsOp(op, args);
|
|
185
|
+
return this._resent({ op: SUPERVISOR_DELIVER_OP, args, pid: this._pid(), delivery: { op, id: crypto.randomUUID(), hostIncarnation } }, { retryWindowMs: VFS_DELIVERY_RETRY_WINDOW_MS });
|
|
186
|
+
}
|
|
187
|
+
/** `envelope`, re-sent as it is on a fresh stub while the platform drops it retryably. */
|
|
188
|
+
_resent(envelope, policy) {
|
|
189
|
+
return idempotent(envelope.delivery?.op ?? envelope.op, () => this._host(), (host) => hostOpDispatch(host, 'SupervisorRPC', this._route())(envelope), policy);
|
|
190
|
+
}
|
|
191
|
+
_hostIncarnation() {
|
|
192
|
+
const props = this.ctx.props;
|
|
193
|
+
if (typeof props !== 'object' || props === null || !('hostIncarnation' in props))
|
|
194
|
+
return undefined;
|
|
195
|
+
const incarnation = props.hostIncarnation;
|
|
196
|
+
return typeof incarnation === 'string' && incarnation.length > 0 ? incarnation : undefined;
|
|
197
|
+
}
|
|
106
198
|
_reportingPid() {
|
|
107
199
|
const pid = this.ctx.props?.pid;
|
|
108
200
|
return typeof pid === 'number' && Number.isInteger(pid) && pid > 0 ? pid : 0;
|
|
@@ -126,14 +218,14 @@ export class SupervisorRPC extends WorkerEntrypoint {
|
|
|
126
218
|
}
|
|
127
219
|
// ── Filesystem RPC ────────────────────────────────────────────────────
|
|
128
220
|
async readFile(path) {
|
|
129
|
-
return this._call(this.
|
|
221
|
+
return this._call(this._fsRead('readFile', [path]));
|
|
130
222
|
}
|
|
131
223
|
/**
|
|
132
224
|
* Read a file as raw bytes. Used by the git network facet for binary
|
|
133
225
|
* object/pack files where the text readFile would corrupt content.
|
|
134
226
|
*/
|
|
135
227
|
async readFileBytes(path) {
|
|
136
|
-
return this._call(this.
|
|
228
|
+
return this._call(this._fsRead('readFileBytes', [path]));
|
|
137
229
|
}
|
|
138
230
|
async writeFile(path, content) {
|
|
139
231
|
// binary-fs wave: accept Uint8Array natively. Pre-fix this RPC was
|
|
@@ -141,55 +233,55 @@ export class SupervisorRPC extends WorkerEntrypoint {
|
|
|
141
233
|
// decode every Uint8Array write — mangling bytes ≥ 0x80 to U+FFFD
|
|
142
234
|
// and corrupting binary content. RPC structured-clone handles
|
|
143
235
|
// Uint8Array transparently; downstream _rpcWriteFile also accepts
|
|
144
|
-
return this._call(this.
|
|
236
|
+
return this._call(this._fsMutation('writeFile', [path, content]));
|
|
145
237
|
}
|
|
146
238
|
async stat(path, options) {
|
|
147
|
-
return this._call(this.
|
|
239
|
+
return this._call(this._fsRead('stat', [path, options]));
|
|
148
240
|
}
|
|
149
241
|
async lstat(path) {
|
|
150
|
-
return this._call(this.
|
|
242
|
+
return this._call(this._fsRead('lstat', [path]));
|
|
151
243
|
}
|
|
152
244
|
async hasLegacySymlinkUnder(path) {
|
|
153
|
-
return this._call(this.
|
|
245
|
+
return this._call(this._fsRead('hasLegacySymlinkUnder', [path]));
|
|
154
246
|
}
|
|
155
247
|
async utimes(path, atimeMs, mtimeMs) {
|
|
156
|
-
return this._call(this.
|
|
248
|
+
return this._call(this._fsMutation('utimes', [path, atimeMs, mtimeMs]));
|
|
157
249
|
}
|
|
158
250
|
async chmod(path, mode) {
|
|
159
|
-
return this._call(this.
|
|
251
|
+
return this._call(this._fsMutation('chmod', [path, mode]));
|
|
160
252
|
}
|
|
161
253
|
async access(path, mode) {
|
|
162
|
-
return this._call(this.
|
|
254
|
+
return this._call(this._fsRead('access', [path, mode]));
|
|
163
255
|
}
|
|
164
256
|
async chown(path, uid, gid, options) {
|
|
165
|
-
return this._call(this.
|
|
257
|
+
return this._call(this._fsMutation('chown', [path, uid, gid, options]));
|
|
166
258
|
}
|
|
167
259
|
async setUmask(mask) {
|
|
168
260
|
return this._call(this._fsOp('setUmask', [mask]));
|
|
169
261
|
}
|
|
170
262
|
async readdir(path) {
|
|
171
|
-
return this._call(this.
|
|
263
|
+
return this._call(this._fsRead('readdir', [path]));
|
|
172
264
|
}
|
|
173
265
|
async exists(path) {
|
|
174
|
-
return this._call(this.
|
|
266
|
+
return this._call(this._fsRead('exists', [path]));
|
|
175
267
|
}
|
|
176
268
|
async mkdir(path, options) {
|
|
177
|
-
return this._call(this.
|
|
269
|
+
return this._call(this._fsMutation('mkdir', [path, options]));
|
|
178
270
|
}
|
|
179
271
|
async rmdir(path) {
|
|
180
|
-
return this._call(this.
|
|
272
|
+
return this._call(this._fsMutation('rmdir', [path]));
|
|
181
273
|
}
|
|
182
274
|
async rename(from, to) {
|
|
183
|
-
return this._call(this.
|
|
275
|
+
return this._call(this._fsMutation('rename', [from, to]));
|
|
184
276
|
}
|
|
185
277
|
async unlink(path) {
|
|
186
|
-
return this._call(this.
|
|
278
|
+
return this._call(this._fsMutation('unlink', [path]));
|
|
187
279
|
}
|
|
188
280
|
async readlink(path) {
|
|
189
|
-
return this._call(this.
|
|
281
|
+
return this._call(this._fsRead('readlink', [path]));
|
|
190
282
|
}
|
|
191
283
|
async symlink(target, path) {
|
|
192
|
-
return this._call(this.
|
|
284
|
+
return this._call(this._fsMutation('symlink', [target, path]));
|
|
193
285
|
}
|
|
194
286
|
/**
|
|
195
287
|
* ACQUIRE: the paths mutated since the facet's cursor, plus a fresh
|
|
@@ -200,13 +292,14 @@ export class SupervisorRPC extends WorkerEntrypoint {
|
|
|
200
292
|
* SupervisorRPC runs in a different isolate from the DO that owns the
|
|
201
293
|
* revision clock, so stamping here would cost its own round trip anyway,
|
|
202
294
|
* and enveloping the existing returns would break `useRpcResource`
|
|
203
|
-
* disposal, which targets the returned value.
|
|
295
|
+
* disposal, which targets the returned value. It only reads the
|
|
296
|
+
* invalidation log, so a dropped call is repeated like any other read.
|
|
204
297
|
*/
|
|
205
|
-
async fsAcquire(epoch, cursor) {
|
|
206
|
-
return this._call(this.
|
|
298
|
+
async fsAcquire(epoch, cursor, options) {
|
|
299
|
+
return this._call(this._fsRead('fsAcquire', options === undefined ? [epoch, cursor] : [epoch, cursor, options]));
|
|
207
300
|
}
|
|
208
301
|
async fsRevision(path) {
|
|
209
|
-
return this._call(this.
|
|
302
|
+
return this._call(this._fsRead('fsRevision', [path]));
|
|
210
303
|
}
|
|
211
304
|
/**
|
|
212
305
|
* Enumerate the session filesystem, one bounded page at a time.
|
|
@@ -225,8 +318,12 @@ export class SupervisorRPC extends WorkerEntrypoint {
|
|
|
225
318
|
* enumerating. `next === null` marks the final page, so a short page is
|
|
226
319
|
* never mistaken for a complete listing.
|
|
227
320
|
*/
|
|
321
|
+
/** N18: `bytes` more for this process's facet store, reporting what it measures. */
|
|
322
|
+
async fsStorageGrant(facet, bytes, databaseSize) {
|
|
323
|
+
return this._call(this._fsOp('fsStorageGrant', [facet, bytes, databaseSize]));
|
|
324
|
+
}
|
|
228
325
|
async fsList(after, limit) {
|
|
229
|
-
return this._call(this.
|
|
326
|
+
return this._call(this._fsRead('fsList', [after ?? null, limit ?? null]));
|
|
230
327
|
}
|
|
231
328
|
/**
|
|
232
329
|
* WebSocket relay. A facet does not open its own sockets: the supervisor
|
|
@@ -249,61 +346,65 @@ export class SupervisorRPC extends WorkerEntrypoint {
|
|
|
249
346
|
return this._call(this._fsOp('wsClose', [id, code, reason]));
|
|
250
347
|
}
|
|
251
348
|
async fsOpen(path, flags) {
|
|
252
|
-
return this._call(this.
|
|
349
|
+
return this._call(this._fsMutation('fsOpen', [path, flags]));
|
|
253
350
|
}
|
|
254
351
|
async fsRead(handleId, offset, length) {
|
|
255
352
|
return this._call(this._fsOp('fsRead', [handleId, offset, length]));
|
|
256
353
|
}
|
|
257
354
|
async fsWrite(handleId, offset, bytes) {
|
|
258
|
-
return this._call(this.
|
|
355
|
+
return this._call(this._fsMutation('fsWrite', [handleId, offset, bytes]));
|
|
259
356
|
}
|
|
357
|
+
/** A descriptor's stat and its directory listing move nothing: re-sent like any read. */
|
|
260
358
|
async fsFstat(...args) {
|
|
261
|
-
return this._call(this.
|
|
359
|
+
return this._call(this._fsRead('fsFstat', args));
|
|
262
360
|
}
|
|
263
361
|
async fsDup(...args) {
|
|
264
|
-
return this._call(this.
|
|
362
|
+
return this._call(this._fsMutation('fsDup', args));
|
|
265
363
|
}
|
|
266
364
|
async fsSeek(...args) {
|
|
267
|
-
return this._call(this.
|
|
365
|
+
return this._call(this._fsMutation('fsSeek', args));
|
|
268
366
|
}
|
|
269
367
|
async fsSetStatus(...args) {
|
|
270
|
-
return this._call(this.
|
|
368
|
+
return this._call(this._fsMutation('fsSetStatus', args));
|
|
271
369
|
}
|
|
272
370
|
async fsReaddirHandle(...args) {
|
|
273
|
-
return this._call(this.
|
|
371
|
+
return this._call(this._fsRead('fsReaddirHandle', args));
|
|
274
372
|
}
|
|
275
373
|
async fsFtruncate(...args) {
|
|
276
|
-
return this._call(this.
|
|
374
|
+
return this._call(this._fsMutation('fsFtruncate', args));
|
|
277
375
|
}
|
|
278
376
|
async fsFchmod(...args) {
|
|
279
|
-
return this._call(this.
|
|
377
|
+
return this._call(this._fsMutation('fsFchmod', args));
|
|
280
378
|
}
|
|
281
379
|
async fsFchown(...args) {
|
|
282
|
-
return this._call(this.
|
|
380
|
+
return this._call(this._fsMutation('fsFchown', args));
|
|
283
381
|
}
|
|
284
382
|
async fsFutimes(...args) {
|
|
285
|
-
return this._call(this.
|
|
383
|
+
return this._call(this._fsMutation('fsFutimes', args));
|
|
286
384
|
}
|
|
287
385
|
async fsSync(...args) {
|
|
288
|
-
return this._call(this.
|
|
386
|
+
return this._call(this._fsMutation('fsSync', args));
|
|
289
387
|
}
|
|
290
388
|
async fsRealpath(...args) {
|
|
291
|
-
return this._call(this.
|
|
389
|
+
return this._call(this._fsRead('fsRealpath', args));
|
|
292
390
|
}
|
|
293
391
|
async fsRemove(...args) {
|
|
294
|
-
return this._call(this.
|
|
392
|
+
return this._call(this._fsMutation('fsRemove', args));
|
|
295
393
|
}
|
|
296
394
|
async fsCopyFile(...args) {
|
|
297
|
-
return this._call(this.
|
|
395
|
+
return this._call(this._fsMutation('fsCopyFile', args));
|
|
396
|
+
}
|
|
397
|
+
async fsCopyTree(...args) {
|
|
398
|
+
return this._call(this._fsMutation('fsCopyTree', args));
|
|
298
399
|
}
|
|
299
400
|
async fsAcquireExclusiveMutation(...args) {
|
|
300
|
-
return this._call(this.
|
|
401
|
+
return this._call(this._fsMutation('fsAcquireExclusiveMutation', args));
|
|
301
402
|
}
|
|
302
403
|
async fsReleaseExclusiveMutation(...args) {
|
|
303
|
-
return this._call(this.
|
|
404
|
+
return this._call(this._fsMutation('fsReleaseExclusiveMutation', args));
|
|
304
405
|
}
|
|
305
406
|
async fsClose(handleId) {
|
|
306
|
-
return this._call(this.
|
|
407
|
+
return this._call(this._fsMutation('fsClose', [handleId]));
|
|
307
408
|
}
|
|
308
409
|
/**
|
|
309
410
|
* Stateless ranged ops. Unlike fsOpen/fsRead/fsWrite they carry no
|
|
@@ -311,7 +412,7 @@ export class SupervisorRPC extends WorkerEntrypoint {
|
|
|
311
412
|
* hibernation and never rewrite whole files for partial updates.
|
|
312
413
|
*/
|
|
313
414
|
async fsReadRange(path, offset, length) {
|
|
314
|
-
return this._call(this.
|
|
415
|
+
return this._call(this._fsRead('fsReadRange', [path, offset, length]));
|
|
315
416
|
}
|
|
316
417
|
/**
|
|
317
418
|
* The same read with the session's content cache bypassed, for a boot spec's
|
|
@@ -320,7 +421,7 @@ export class SupervisorRPC extends WorkerEntrypoint {
|
|
|
320
421
|
* session's heap for the rest of its life.
|
|
321
422
|
*/
|
|
322
423
|
async fsReadRangeUncached(path, offset, length) {
|
|
323
|
-
return this._call(this.
|
|
424
|
+
return this._call(this._fsRead('fsReadRangeUncached', [path, offset, length]));
|
|
324
425
|
}
|
|
325
426
|
/**
|
|
326
427
|
* Read many ranges in ONE round trip — the read-side counterpart to
|
|
@@ -329,8 +430,11 @@ export class SupervisorRPC extends WorkerEntrypoint {
|
|
|
329
430
|
* A file the caller knows is small is one entry; a large one is a run of
|
|
330
431
|
* entries over the same path.
|
|
331
432
|
*
|
|
433
|
+
* A request may instead ask for a path's lstat, so a process learning the
|
|
434
|
+
* metadata of many paths pays one round trip, not one per path.
|
|
435
|
+
*
|
|
332
436
|
* Entries come back positionally, each carrying exactly what the
|
|
333
|
-
* equivalent fsReadRange would have returned. The batch is bounded by
|
|
437
|
+
* equivalent fsReadRange or lstat would have returned. The batch is bounded by
|
|
334
438
|
* FS_READ_BATCH_PATH_LIMIT paths and FS_READ_BATCH_REQUEST_BYTES of
|
|
335
439
|
* requested range, and the supervisor rejects anything past either — never
|
|
336
440
|
* a short result, which a caller could mistake for a short file.
|
|
@@ -340,27 +444,33 @@ export class SupervisorRPC extends WorkerEntrypoint {
|
|
|
340
444
|
// returns at most the range asked for. Counting it keeps the
|
|
341
445
|
// supervisor's heap estimate honest for the duration of the await, the
|
|
342
446
|
// same accounting writeBatch does for its inbound payload.
|
|
343
|
-
const payloadBytes = requests.reduce((total, request) => total + request
|
|
447
|
+
const payloadBytes = requests.reduce((total, request) => total + fsReadBatchRequestBytes(request), 0);
|
|
344
448
|
setLastRpcFrame('fsReadBatch', payloadBytes);
|
|
345
449
|
rpcPayloadStart(payloadBytes);
|
|
346
450
|
try {
|
|
347
|
-
return await this._call(this.
|
|
451
|
+
return await this._call(this._fsRead('fsReadBatch', [requests]));
|
|
348
452
|
}
|
|
349
453
|
finally {
|
|
350
454
|
rpcPayloadEnd(payloadBytes);
|
|
351
455
|
}
|
|
352
456
|
}
|
|
353
457
|
async fsWriteRange(path, offset, bytes) {
|
|
354
|
-
return this._call(this.
|
|
458
|
+
return this._call(this._fsMutation('fsWriteRange', [path, offset, bytes]));
|
|
355
459
|
}
|
|
460
|
+
/**
|
|
461
|
+
* An append and its acknowledgement carry the append ledger's own identity
|
|
462
|
+
* (writer, module incarnation, operation sequence), whose receipt the host
|
|
463
|
+
* keeps until the acknowledgement: a repeat of either applies nothing twice,
|
|
464
|
+
* so a dropped one is simply re-sent.
|
|
465
|
+
*/
|
|
356
466
|
async fsAppend(path, moduleId, operationId, bytes) {
|
|
357
|
-
return this._call(this.
|
|
467
|
+
return this._call(this._resent({ op: 'fsAppend', args: [path, moduleId, operationId, bytes], pid: this._pid(), writerId: this._writerId() }));
|
|
358
468
|
}
|
|
359
469
|
async fsAppendAck(moduleId, operationId) {
|
|
360
|
-
return this._call(this.
|
|
470
|
+
return this._call(this._resent({ op: 'fsAppendAck', args: [moduleId, operationId], pid: this._pid(), writerId: this._writerId() }));
|
|
361
471
|
}
|
|
362
472
|
async fsTruncate(path, size) {
|
|
363
|
-
return this._call(this.
|
|
473
|
+
return this._call(this._fsMutation('fsTruncate', [path, size]));
|
|
364
474
|
}
|
|
365
475
|
/**
|
|
366
476
|
* Bulk-write all inodes + chunks in ONE transactionSync on the supervisor.
|
|
@@ -383,7 +493,7 @@ export class SupervisorRPC extends WorkerEntrypoint {
|
|
|
383
493
|
setLastRpcFrame('writeBatch', payloadBytes);
|
|
384
494
|
rpcPayloadStart(payloadBytes);
|
|
385
495
|
try {
|
|
386
|
-
return await this._call(this.
|
|
496
|
+
return await this._call(this._fsMutation('writeBatch', [payload]));
|
|
387
497
|
}
|
|
388
498
|
finally {
|
|
389
499
|
rpcPayloadEnd(payloadBytes);
|
|
@@ -554,8 +664,8 @@ export class SupervisorRPC extends WorkerEntrypoint {
|
|
|
554
664
|
* has error state it couldn't stream in-band (rare; main path drains
|
|
555
665
|
* via __pendingIO first).
|
|
556
666
|
*/
|
|
557
|
-
async reportExit(code, tail) {
|
|
558
|
-
return this._call(this._op('reportExit', [code, tail || ''], { pid: this._reportingPid() }));
|
|
667
|
+
async reportExit(code, tail, residencyMisses, profileUnread) {
|
|
668
|
+
return this._call(this._op('reportExit', [code, tail || '', residencyMisses ?? [], profileUnread ?? null], { pid: this._reportingPid() }));
|
|
559
669
|
}
|
|
560
670
|
// ── Prefetch ──────────────────────────────────────────────────────────
|
|
561
671
|
async prefetch(cwd, entryCode) {
|
|
@@ -602,11 +712,18 @@ export class SupervisorRPC extends WorkerEntrypoint {
|
|
|
602
712
|
async cpStdinEnd(childPid) {
|
|
603
713
|
return this._call(this._op('cpStdinEnd', [childPid]));
|
|
604
714
|
}
|
|
605
|
-
|
|
606
|
-
|
|
715
|
+
/**
|
|
716
|
+
* The three long polls that deliver to a process — its stdin, and a
|
|
717
|
+
* child's output and exit — carry the process's ACQUIRE arguments, and a
|
|
718
|
+
* reply that delivers anything carries the answer for them (`acquired`,
|
|
719
|
+
* session/rpc.ts `_acquireOnDelivery`), so the process applies it without
|
|
720
|
+
* asking. The caller's pid names whose credential answers it.
|
|
721
|
+
*/
|
|
722
|
+
async cpReadStdin(childPid, waitMs, acquire) {
|
|
723
|
+
return this._call(this._op('cpReadStdin', [childPid, waitMs, acquire ?? null], { pid: this._reportingPid() }));
|
|
607
724
|
}
|
|
608
|
-
async cpReadOutput(childPid, fd, sinceSeq, waitMs) {
|
|
609
|
-
return this._call(this._op('cpReadOutput', [childPid, fd, sinceSeq, waitMs]));
|
|
725
|
+
async cpReadOutput(childPid, fd, sinceSeq, waitMs, acquire) {
|
|
726
|
+
return this._call(this._op('cpReadOutput', [childPid, fd, sinceSeq, waitMs, acquire ?? null], { pid: this._reportingPid() }));
|
|
610
727
|
}
|
|
611
728
|
async cpDrainOutput(childPid) {
|
|
612
729
|
return this._call(this._op('cpDrainOutput', [childPid]));
|
|
@@ -614,8 +731,8 @@ export class SupervisorRPC extends WorkerEntrypoint {
|
|
|
614
731
|
async cpKill(childPid, signal) {
|
|
615
732
|
return this._call(this._op('cpKill', [childPid, signal]));
|
|
616
733
|
}
|
|
617
|
-
async cpWait(childPid, waitMs) {
|
|
618
|
-
return this._call(this._op('cpWait', [childPid, waitMs]));
|
|
734
|
+
async cpWait(childPid, waitMs, acquire) {
|
|
735
|
+
return this._call(this._op('cpWait', [childPid, waitMs, acquire ?? null], { pid: this._reportingPid() }));
|
|
619
736
|
}
|
|
620
737
|
/**
|
|
621
738
|
* child-process isolation gap #1: dispatch a single cp.spawn request inline using
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"vite-command.d.ts","sourceRoot":"","sources":["../../src/session/vite-command.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAyBH,KAAK,QAAQ,GAAG,GAAG,CAAC;AAEpB,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,QAAQ,IAChC,KAAK,GAAG,KAAG,OAAO,CAAC,MAAM,CAAC,
|
|
1
|
+
{"version":3,"file":"vite-command.d.ts","sourceRoot":"","sources":["../../src/session/vite-command.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAyBH,KAAK,QAAQ,GAAG,GAAG,CAAC;AAEpB,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,QAAQ,IAChC,KAAK,GAAG,KAAG,OAAO,CAAC,MAAM,CAAC,CAslBzC"}
|
|
@@ -15,9 +15,9 @@
|
|
|
15
15
|
import { normalizeVfsPath, parentVfsPath, resolveVfsPath, stripLeadingSlashes } from '@nimbus-sh/core/vfs/path.js';
|
|
16
16
|
import { errorText } from '@nimbus-sh/core/_shared/error-text.js';
|
|
17
17
|
import { CRED_KERNEL } from '@nimbus-sh/core/runtime/os-contracts.js';
|
|
18
|
-
import { parseViteConfigSource, viteBuildBlockingPlugins, unhandledVitePlugins } from '@nimbus-sh/core/runtime/vite-config-parser.js';
|
|
18
|
+
import { parseViteConfigSource, parseViteConfigTypeScript, viteBuildBlockingPlugins, unhandledVitePlugins } from '@nimbus-sh/core/runtime/vite-config-parser.js';
|
|
19
19
|
import { findHtmlScriptEntrypoint, rewriteViteBuildHtml } from '../runtime/html-entrypoint.js';
|
|
20
|
-
import {
|
|
20
|
+
import { supervisorEsbuildService } from '../facets/esbuild-transform.js';
|
|
21
21
|
import { ViteDevServer } from '../facets/vite-dev-server.js';
|
|
22
22
|
import { shouldUseRealVite } from '../facets/cirrus-real.js';
|
|
23
23
|
import { makeLongRunningPortStub, resolveLongRunningPort, expandArgvShellDefaults, } from '@nimbus-sh/core/runtime/long-running-handle.js';
|
|
@@ -49,15 +49,18 @@ export function createViteCommand(self) {
|
|
|
49
49
|
const cfgPath = cwd + '/' + cfgName;
|
|
50
50
|
if (kernelFs.exists(cfgPath)) {
|
|
51
51
|
try {
|
|
52
|
-
|
|
53
|
-
//
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
52
|
+
const cfgCode = kernelFs.readFileString(cfgPath);
|
|
53
|
+
// A .ts config needs esbuild only when it holds type syntax
|
|
54
|
+
// (parseViteConfigTypeScript); a plain one is read as is, so a
|
|
55
|
+
// fresh session's `vite` does not wait on the esbuild facet.
|
|
56
|
+
const parsed = cfgName.endsWith('.ts')
|
|
57
|
+
? await parseViteConfigTypeScript(cfgCode, async (source) => {
|
|
58
|
+
if (!self.esbuildService)
|
|
59
|
+
self.esbuildService = supervisorEsbuildService(self.ctx, self.env, self.getFilesystemAuthority().namespaceFs(CRED_KERNEL));
|
|
60
|
+
return (await self.esbuildService.transform(source, { loader: 'ts', format: 'esm' })).code;
|
|
61
|
+
})
|
|
62
|
+
: parseViteConfigSource(cfgCode);
|
|
63
|
+
Object.assign(viteConfig, parsed);
|
|
61
64
|
}
|
|
62
65
|
catch (e) {
|
|
63
66
|
ctx.stderr.write(`Warning: could not parse ${cfgName}: ${e?.message}\n`);
|
|
@@ -89,7 +92,7 @@ export function createViteCommand(self) {
|
|
|
89
92
|
' (' + buildSkippedPlugins.join(', ') + '); output is the plain-Vite bundle.\n');
|
|
90
93
|
}
|
|
91
94
|
if (!self.esbuildService)
|
|
92
|
-
self.esbuildService =
|
|
95
|
+
self.esbuildService = supervisorEsbuildService(self.ctx, self.env, self.getFilesystemAuthority().namespaceFs(CRED_KERNEL));
|
|
93
96
|
const htmlPath = cwd + '/index.html';
|
|
94
97
|
let entryPoint = cwd + '/src/main.tsx';
|
|
95
98
|
let origHtml = '';
|
|
@@ -295,7 +298,7 @@ export function createViteCommand(self) {
|
|
|
295
298
|
}
|
|
296
299
|
// Start vite on the dist directory
|
|
297
300
|
if (!self.esbuildService)
|
|
298
|
-
self.esbuildService =
|
|
301
|
+
self.esbuildService = supervisorEsbuildService(self.ctx, self.env, self.getFilesystemAuthority().namespaceFs(CRED_KERNEL));
|
|
299
302
|
if (self.viteDevServer?.isRunning)
|
|
300
303
|
self.viteDevServer.stop();
|
|
301
304
|
const previewBasePath = self.viteBasePath;
|
|
@@ -502,7 +505,7 @@ export function createViteCommand(self) {
|
|
|
502
505
|
' (' + devSkipped.join(', ') + '); serving the plain-Vite app.\n');
|
|
503
506
|
}
|
|
504
507
|
if (!self.esbuildService)
|
|
505
|
-
self.esbuildService =
|
|
508
|
+
self.esbuildService = supervisorEsbuildService(self.ctx, self.env, self.getFilesystemAuthority().namespaceFs(CRED_KERNEL));
|
|
506
509
|
const previewBasePath = self.viteBasePath;
|
|
507
510
|
const viteDefine = viteConfig.define;
|
|
508
511
|
// Vite dev servers are represented as long-running process-table
|
package/dist/session/ws.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ws.d.ts","sourceRoot":"","sources":["../../src/session/ws.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiCG;AAQH,OAAO,EAIL,KAAK,UAAU,EAChB,MAAM,eAAe,CAAC;AAIvB,OAAO,KAAK,EAAE,wBAAwB,EAAE,MAAM,uDAAuD,CAAC;AACtG,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,mCAAmC,CAAC;AACnE,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,0BAA0B,CAAC;AAC3D,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAC;AAElE,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,WAAW,CAAC;AACpD,OAAO,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,yCAAyC,CAAC;AAG7E;;;GAGG;AACH,MAAM,WAAW,MAAM;IACrB,QAAQ,EAAE,SAAS,GAAG,IAAI,CAAC;IAC3B,KAAK,EAAE,KAAK,GAAG,IAAI,CAAC;IACpB,QAAQ,EAAE,iBAAiB,GAAG,IAAI,CAAC;IACnC,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,UAAU,EAAE,UAAU,GAAG,IAAI,CAAC;IAC9B,mBAAmB,EAAE,GAAG,CAAC,SAAS,EAAE,MAAM,CAAC,GAAG,IAAI,CAAC;IACnD;;;;8DAI0D;IAC1D,YAAY,CAAC,EAAE,GAAG,CAAC,SAAS,EAAE,UAAU,EAAE,CAAC,CAAC;IAC5C,SAAS,EAAE,wBAAwB,CAAC;IACpC,wBAAwB,EAAE,OAAO,CAAC;IAClC,eAAe,EAAE,OAAO,CAAC;IACzB,aAAa,EAAE,GAAG,CAAC;IACnB,aAAa,EAAE,OAAO,CAAC;IACvB,WAAW,EAAE,GAAG,CAAC;IACjB,YAAY,EAAE,MAAM,CAAC;IACrB,iBAAiB,EAAE,MAAM,CAAC;IAC1B,gBAAgB,EAAE,MAAM,CAAC;IACzB,sBAAsB,EAAE,MAAM,CAAC;IAC/B,qEAAqE;IACrE,QAAQ,EAAE,OAAO,0CAA0C,EAAE,YAAY,GAAG,IAAI,CAAC;IACjF,+EAA+E;IAC/E,YAAY,EAAE,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC;IACnC,WAAW,CAAC,EAAE,EAAE,SAAS,EAAE,OAAO,CAAC,EAAE,kBAAkB,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACxE,cAAc,IAAI,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC;IACvC,eAAe,IAAI,IAAI,CAAC;CACzB;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAqCG;AACH,wBAAsB,eAAe,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE,SAAS,GAAG,OAAO,CAAC,OAAO,CAAC,CAoBnF;AAsDD;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,MAAM,GAAG,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAStE;AAED;;;;;;;GAOG;AACH,UAAU,YAAY;IACpB,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,GAAG,CAAC,EAAE,MAAM,CAAC;CACd;AA6CD,wBAAgB,MAAM,CAAC,EAAE,EAAE,SAAS,GAAG,YAAY,CAElD;AAED,wBAAsB,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE,SAAS,EAAE,OAAO,EAAE,MAAM,GAAG,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC,
|
|
1
|
+
{"version":3,"file":"ws.d.ts","sourceRoot":"","sources":["../../src/session/ws.ts"],"names":[],"mappings":"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"}
|
package/dist/session/ws.js
CHANGED
|
@@ -316,15 +316,27 @@ export async function wsMessage(self, ws, message) {
|
|
|
316
316
|
return;
|
|
317
317
|
}
|
|
318
318
|
const terminalMessage = TerminalMessageSchema.safeParse(value);
|
|
319
|
-
if (self.terminal && terminalMessage.success)
|
|
320
|
-
self.terminal
|
|
319
|
+
if (self.terminal && terminalMessage.success) {
|
|
320
|
+
const terminal = self.terminal;
|
|
321
|
+
const completion = terminal.handleMessage(terminalMessage.data);
|
|
322
|
+
if (completion) {
|
|
323
|
+
const task = completion.catch((error) => {
|
|
324
|
+
console.error('[nimbus] terminal input failed:', errorText(error));
|
|
325
|
+
terminal.writeln(`terminal input failed: ${errorText(error)}`);
|
|
326
|
+
}).finally(() => snapshotShellState(self));
|
|
327
|
+
const ctx = self.ctx;
|
|
328
|
+
// Hand the command's completion to waitUntil so its failure is observed and
|
|
329
|
+
// the final snapshot runs, without holding the WebSocket event open or
|
|
330
|
+
// serializing later input. DurableObjectState.waitUntil does not extend the
|
|
331
|
+
// object's lifetime (Cloudflare docs, api/state/#waituntil).
|
|
332
|
+
if (ctx?.waitUntil)
|
|
333
|
+
ctx.waitUntil(task);
|
|
334
|
+
else
|
|
335
|
+
await task;
|
|
336
|
+
}
|
|
337
|
+
}
|
|
321
338
|
// ── B'.1 snapshot ───────────────────────────────────────────────
|
|
322
|
-
//
|
|
323
|
-
// the user's keystroke. The Shell builtin `cd` mutates this.cwd
|
|
324
|
-
// synchronously inside executeLine, so by the time we reach this
|
|
325
|
-
// line a `cd example-app\r` has already taken effect and we capture the
|
|
326
|
-
// new cwd. Cheap when nothing has changed; SESSION_ENV_MAX_BYTES
|
|
327
|
-
// is the only failure mode and is logged, not thrown.
|
|
339
|
+
// Capture immediate keystroke changes; async input completion takes a final snapshot above.
|
|
328
340
|
snapshotShellState(self);
|
|
329
341
|
}
|
|
330
342
|
catch (e) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"npm-bin-entrypoints.d.ts","sourceRoot":"","sources":["../../src/shell/npm-bin-entrypoints.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,mCAAmC,CAAC;AACzE,OAAO,KAAK,EAAE,wBAAwB,EAAE,MAAM,uDAAuD,CAAC;AACtG,OAAO,KAAK,EAAE,YAAY,EAA4B,MAAM,sBAAsB,CAAC;
|
|
1
|
+
{"version":3,"file":"npm-bin-entrypoints.d.ts","sourceRoot":"","sources":["../../src/shell/npm-bin-entrypoints.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,mCAAmC,CAAC;AACzE,OAAO,KAAK,EAAE,wBAAwB,EAAE,MAAM,uDAAuD,CAAC;AACtG,OAAO,KAAK,EAAE,YAAY,EAA4B,MAAM,sBAAsB,CAAC;AAYnF,KAAK,MAAM,GAAG;IAAE,KAAK,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAAA;CAAE,CAAC;AAiB5C,KAAK,YAAY,GAAG;IAClB,OAAO,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,GAAG,OAAO,CAAC;CACnD,CAAC;AAEF,KAAK,kBAAkB,GAAG;IAAE,WAAW,EAAE,MAAM,CAAA;CAAE,GAAG,IAAI,CAAC;AAezD,wBAAgB,6BAA6B,CAC3C,QAAQ,EAAE,YAAY,EACtB,IAAI,EAAE;IACJ,GAAG,EAAE,eAAe,CAAC;IACrB,MAAM,IAAI,MAAM,CAAC;IACjB,SAAS,EAAE,wBAAwB,CAAC;IACpC,eAAe,IAAI,YAAY,CAAC;IAChC,QAAQ,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,mBAAmB,CAAC,KAAK,EAAE;QAAE,IAAI,EAAE,OAAO,GAAG,MAAM,CAAC;QAAC,GAAG,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAC;QAAC,WAAW,CAAC,EAAE,OAAO,CAAC;QAAC,WAAW,CAAC,EAAE,OAAO,CAAC;QAAC,IAAI,CAAC,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI,CAAC;IACxJ,kBAAkB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,kBAAkB,CAAC,CAAC;IAC9D,iBAAiB,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;CAC7F,GACA,IAAI,CAgJN;AAqFD;;;;;;;;;;;;;;;GAeG;AACH,MAAM,MAAM,yBAAyB,GAAG,MAAM,GAAG,QAAQ,GAAG,UAAU,GAAG,SAAS,CAAC;AAEnF,wBAAgB,sBAAsB,CACpC,QAAQ,EAAE,MAAM,EAChB,IAAI,EAAE,MAAM,EAAE,GACb,yBAAyB,CAS3B;AAiGD;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,sBAAsB,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,GAAG,OAAO,CAS/E"}
|