@nimbus-sh/core 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 +47 -26
- package/dist/_shared/byte-stream.d.ts +5 -4
- package/dist/_shared/byte-stream.d.ts.map +1 -1
- package/dist/_shared/cache-stats.d.ts +23 -1
- package/dist/_shared/cache-stats.d.ts.map +1 -1
- package/dist/_shared/cache-stats.js +13 -1
- package/dist/_shared/exports-resolver.d.ts +1 -1
- package/dist/_shared/exports-resolver.js +1 -1
- package/dist/_shared/real-node-imports.d.ts +7 -0
- package/dist/_shared/real-node-imports.d.ts.map +1 -1
- package/dist/_shared/real-node-imports.js +8 -0
- package/dist/_shared/retry.js +1 -1
- package/dist/_shared/tarball.d.ts +23 -5
- package/dist/_shared/tarball.d.ts.map +1 -1
- package/dist/_shared/tarball.js +38 -5
- package/dist/_shared/vfs-write-ledger.d.ts.map +1 -1
- package/dist/_shared/vfs-write-ledger.js +22 -16
- package/dist/constants.d.ts +5 -11
- package/dist/constants.d.ts.map +1 -1
- package/dist/constants.js +16 -56
- package/dist/runtime/assets-loader.js +1 -1
- package/dist/runtime/comment-strip.d.ts +0 -35
- package/dist/runtime/comment-strip.d.ts.map +1 -1
- package/dist/runtime/comment-strip.js +48 -20
- package/dist/runtime/esbuild-service.d.ts +38 -42
- package/dist/runtime/esbuild-service.d.ts.map +1 -1
- package/dist/runtime/esbuild-service.js +494 -197
- package/dist/runtime/javascript-ast.d.ts.map +1 -1
- package/dist/runtime/javascript-ast.js +45 -7
- package/dist/runtime/opentui-wasm-backend.d.ts.map +1 -1
- package/dist/runtime/opentui-wasm-backend.js +18 -16
- package/dist/runtime/port-registry.d.ts +4 -2
- package/dist/runtime/port-registry.d.ts.map +1 -1
- package/dist/runtime/port-registry.js +60 -8
- package/dist/runtime/virtual-socket-kernel.generated.d.ts +1 -1
- package/dist/runtime/virtual-socket-kernel.generated.js +1 -1
- package/dist/shell/stdin-adapter.d.ts +11 -0
- package/dist/shell/stdin-adapter.d.ts.map +1 -0
- package/dist/shell/stdin-adapter.js +59 -0
- package/dist/shell/unix-commands.d.ts +2 -1
- package/dist/shell/unix-commands.d.ts.map +1 -1
- package/dist/shell/unix-commands.js +1078 -50
- package/dist/substrate/lifo/commands/io/dd.js +1 -1
- package/dist/substrate/lifo/commands/net/curl.d.ts.map +1 -1
- package/dist/substrate/lifo/commands/net/curl.js +270 -54
- package/dist/substrate/lifo/commands/system/npm.d.ts +18 -1
- package/dist/substrate/lifo/commands/system/npm.d.ts.map +1 -1
- package/dist/substrate/lifo/commands/system/npm.js +26 -43
- package/dist/substrate/lifo/commands/text/head.d.ts.map +1 -1
- package/dist/substrate/lifo/commands/text/head.js +2 -1
- package/dist/substrate/lifo/commands/text/sed.d.ts.map +1 -1
- package/dist/substrate/lifo/commands/text/sed.js +499 -117
- package/dist/substrate/lifo/commands/types.d.ts +8 -4
- package/dist/substrate/lifo/commands/types.d.ts.map +1 -1
- package/dist/substrate/lifo/node-compat/zlib.d.ts +37 -18
- package/dist/substrate/lifo/node-compat/zlib.d.ts.map +1 -1
- package/dist/substrate/lifo/node-compat/zlib.js +122 -23
- package/dist/substrate/lifo/shell/interpreter.d.ts +9 -1
- package/dist/substrate/lifo/shell/interpreter.d.ts.map +1 -1
- package/dist/substrate/lifo/shell/interpreter.js +79 -29
- package/dist/substrate/lifo/shell/pipe.d.ts +16 -0
- package/dist/substrate/lifo/shell/pipe.d.ts.map +1 -1
- package/dist/substrate/lifo/shell/pipe.js +62 -18
- package/dist/substrate/lifo/shell/terminal-stdin.d.ts +20 -3
- package/dist/substrate/lifo/shell/terminal-stdin.d.ts.map +1 -1
- package/dist/substrate/lifo/shell/terminal-stdin.js +60 -24
- package/dist/vfs/seed-project.d.ts.map +1 -1
- package/dist/vfs/seed-project.js +1 -1
- package/dist/vfs/sqlite-vfs.d.ts +21 -30
- package/dist/vfs/sqlite-vfs.d.ts.map +1 -1
- package/dist/vfs/sqlite-vfs.js +113 -29
- package/dist/workspace/nimbus-workspace.d.ts +15 -0
- package/dist/workspace/nimbus-workspace.d.ts.map +1 -1
- package/dist/workspace/nimbus-workspace.js +20 -3
- package/dist/workspace/supervisor-op.d.ts +23 -0
- package/dist/workspace/supervisor-op.d.ts.map +1 -0
- package/dist/workspace/supervisor-op.js +92 -0
- package/package.json +3 -2
- package/src/_shared/byte-stream.ts +5 -4
- package/src/_shared/cache-stats.ts +27 -1
- package/src/_shared/exports-resolver.ts +1 -1
- package/src/_shared/real-node-imports.ts +8 -0
- package/src/_shared/retry.ts +1 -1
- package/src/_shared/tarball.ts +56 -5
- package/src/_shared/vfs-write-ledger.ts +22 -16
- package/src/constants.ts +30 -60
- package/src/runtime/assets-loader.ts +1 -1
- package/src/runtime/comment-strip.ts +42 -23
- package/src/runtime/esbuild-service.ts +566 -217
- package/src/runtime/javascript-ast.ts +40 -9
- package/src/runtime/opentui-wasm-backend.ts +19 -17
- package/src/runtime/port-registry.ts +66 -8
- package/src/runtime/virtual-socket-kernel.generated.ts +1 -1
- package/src/shell/stdin-adapter.ts +58 -0
- package/src/shell/unix-commands.ts +1054 -50
- package/src/substrate/lifo/commands/io/dd.ts +2 -2
- package/src/substrate/lifo/commands/net/curl.ts +310 -58
- package/src/substrate/lifo/commands/system/npm.ts +58 -38
- package/src/substrate/lifo/commands/text/head.ts +2 -1
- package/src/substrate/lifo/commands/text/sed.ts +519 -109
- package/src/substrate/lifo/commands/types.ts +8 -5
- package/src/substrate/lifo/node-compat/zlib.ts +155 -26
- package/src/substrate/lifo/shell/interpreter.ts +74 -27
- package/src/substrate/lifo/shell/pipe.ts +65 -24
- package/src/substrate/lifo/shell/terminal-stdin.ts +66 -30
- package/src/vfs/seed-project.ts +3 -3
- package/src/vfs/sqlite-vfs.ts +128 -64
- package/src/workspace/nimbus-workspace.ts +26 -2
- package/src/workspace/supervisor-op.ts +117 -0
- package/dist/_shared/install-phase.d.ts +0 -47
- package/dist/_shared/install-phase.d.ts.map +0 -1
- package/dist/_shared/install-phase.js +0 -1
- package/dist/_shared/rpc-dispose.d.ts +0 -4
- package/dist/_shared/rpc-dispose.d.ts.map +0 -1
- package/dist/_shared/rpc-dispose.js +0 -30
- package/dist/_shared/w7-frame.d.ts +0 -79
- package/dist/_shared/w7-frame.d.ts.map +0 -1
- package/dist/_shared/w7-frame.js +0 -840
- package/dist/_shared/weighted-credit-pool.d.ts +0 -61
- package/dist/_shared/weighted-credit-pool.d.ts.map +0 -1
- package/dist/_shared/weighted-credit-pool.js +0 -196
- package/dist/observability/diag-counters.d.ts +0 -236
- package/dist/observability/diag-counters.d.ts.map +0 -1
- package/dist/observability/diag-counters.js +0 -195
- package/dist/observability/heap-estimate.d.ts +0 -225
- package/dist/observability/heap-estimate.d.ts.map +0 -1
- package/dist/observability/heap-estimate.js +0 -185
- package/dist/observability/heavy-alloc-coord.d.ts +0 -93
- package/dist/observability/heavy-alloc-coord.d.ts.map +0 -1
- package/dist/observability/heavy-alloc-coord.js +0 -181
- package/dist/observability/oom-classify.d.ts +0 -138
- package/dist/observability/oom-classify.d.ts.map +0 -1
- package/dist/observability/oom-classify.js +0 -268
- package/dist/observability/oom-discriminator.d.ts +0 -176
- package/dist/observability/oom-discriminator.d.ts.map +0 -1
- package/dist/observability/oom-discriminator.js +0 -272
- package/src/_shared/install-phase.ts +0 -56
- package/src/_shared/rpc-dispose.ts +0 -31
- package/src/_shared/w7-frame.ts +0 -1013
- package/src/_shared/weighted-credit-pool.ts +0 -244
- package/src/observability/diag-counters.ts +0 -343
- package/src/observability/heap-estimate.ts +0 -331
- package/src/observability/heavy-alloc-coord.ts +0 -241
- package/src/observability/oom-classify.ts +0 -260
- package/src/observability/oom-discriminator.ts +0 -405
|
@@ -1,272 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* oom-discriminator.ts — singleton ring buffer for OOM / failure
|
|
3
|
-
* forensics + last-known-RPC-frame + last-known-facet-id +
|
|
4
|
-
* session-recovery-event ring, plus snapshot/rehydrate hooks for DO
|
|
5
|
-
* storage persistence.
|
|
6
|
-
*
|
|
7
|
-
* W5 (Lever 5 / J.1.1) — original module. Pairs with oom-classify.ts.
|
|
8
|
-
* C'.2 — added the recovery_event ring.
|
|
9
|
-
*
|
|
10
|
-
* Why singleton-per-isolate
|
|
11
|
-
* ─────────────────────────
|
|
12
|
-
* Same pattern as src/observability/diag-counters.ts. The supervisor bundle
|
|
13
|
-
* is the consumer; all writers (sqlite-vfs, facet-pool, facet-manager,
|
|
14
|
-
* supervisor-rpc, npm-installer, nimbus-session) live in the same
|
|
15
|
-
* isolate. Module scope provides one process-local diagnostic without
|
|
16
|
-
* threading a handle through each writer.
|
|
17
|
-
*
|
|
18
|
-
* Two distinct rings
|
|
19
|
-
* ──────────────────
|
|
20
|
-
* - failures: things that failed (the original W5 ring).
|
|
21
|
-
* - recoveryEvents: lifecycle transitions of the session. Cold isolate
|
|
22
|
-
* boot → 'cold' → 'hydrated' → 'active' → 'drained'.
|
|
23
|
-
*
|
|
24
|
-
* Bounded-size guarantees
|
|
25
|
-
* ───────────────────────
|
|
26
|
-
* - failures ring: 50 entries (RING_SIZE).
|
|
27
|
-
* - recoveryEvents ring: 50 entries (RECOVERY_RING_SIZE).
|
|
28
|
-
* - per-message cap: 200 chars (truncated at insert).
|
|
29
|
-
* - per-RPC-frame: single slot, one object.
|
|
30
|
-
* - per-facet-id: single slot, one object.
|
|
31
|
-
*
|
|
32
|
-
* Snapshot size stays bounded even with both rings full.
|
|
33
|
-
*/
|
|
34
|
-
import { isOomCause } from './oom-classify.js';
|
|
35
|
-
const RING_SIZE = 50;
|
|
36
|
-
const RECOVERY_RING_SIZE = 50;
|
|
37
|
-
const MESSAGE_CAP = 200;
|
|
38
|
-
const state = {
|
|
39
|
-
failures: [],
|
|
40
|
-
recoveryEvents: [],
|
|
41
|
-
lastRpcFrame: null,
|
|
42
|
-
lastFacetId: null,
|
|
43
|
-
};
|
|
44
|
-
function getState() {
|
|
45
|
-
return state;
|
|
46
|
-
}
|
|
47
|
-
/** Append a failure to the ring. Newest first. Capped at RING_SIZE. */
|
|
48
|
-
export function recordFailure(f) {
|
|
49
|
-
const s = getState();
|
|
50
|
-
// Defensive copy + message cap.
|
|
51
|
-
const entry = {
|
|
52
|
-
at: Number(f.at) || Date.now(),
|
|
53
|
-
phase: String(f.phase ?? 'unknown'),
|
|
54
|
-
cause: f.cause,
|
|
55
|
-
rssEstimateBytes: Number(f.rssEstimateBytes) || 0,
|
|
56
|
-
heapUsedBytes: Number(f.heapUsedBytes) || 0,
|
|
57
|
-
lruBytes: Number(f.lruBytes) || 0,
|
|
58
|
-
inFlightBytes: Number(f.inFlightBytes) || 0,
|
|
59
|
-
lastRpcFrame: f.lastRpcFrame ?? s.lastRpcFrame,
|
|
60
|
-
lastFacetId: f.lastFacetId ?? s.lastFacetId,
|
|
61
|
-
};
|
|
62
|
-
if (typeof f.exitCode === 'number')
|
|
63
|
-
entry.exitCode = f.exitCode;
|
|
64
|
-
if (typeof f.pid === 'number')
|
|
65
|
-
entry.pid = f.pid;
|
|
66
|
-
if (f.message) {
|
|
67
|
-
const m = String(f.message);
|
|
68
|
-
entry.message = m.length > MESSAGE_CAP ? m.slice(0, MESSAGE_CAP) : m;
|
|
69
|
-
}
|
|
70
|
-
s.failures.unshift(entry);
|
|
71
|
-
if (s.failures.length > RING_SIZE)
|
|
72
|
-
s.failures.length = RING_SIZE;
|
|
73
|
-
}
|
|
74
|
-
/** Read a snapshot of the ring. Newest first. Caller-side mutations
|
|
75
|
-
* do not affect the singleton. */
|
|
76
|
-
export function getFailures() {
|
|
77
|
-
return getState().failures.slice(0);
|
|
78
|
-
}
|
|
79
|
-
/** Record the current RPC frame (called at every RPC entry). Bounded
|
|
80
|
-
* to a single slot — the LATEST frame wins. */
|
|
81
|
-
export function setLastRpcFrame(method, payloadBytes) {
|
|
82
|
-
const s = getState();
|
|
83
|
-
s.lastRpcFrame = {
|
|
84
|
-
method: String(method),
|
|
85
|
-
payloadBytes: Number(payloadBytes) || 0,
|
|
86
|
-
atMs: Date.now(),
|
|
87
|
-
};
|
|
88
|
-
}
|
|
89
|
-
export function getLastRpcFrame() {
|
|
90
|
-
return getState().lastRpcFrame;
|
|
91
|
-
}
|
|
92
|
-
/** Record the most recent facet dispatch. */
|
|
93
|
-
export function setLastFacetId(codeId, slotIndex) {
|
|
94
|
-
const s = getState();
|
|
95
|
-
s.lastFacetId = {
|
|
96
|
-
codeId: String(codeId),
|
|
97
|
-
slotIndex: Number(slotIndex) || 0,
|
|
98
|
-
atMs: Date.now(),
|
|
99
|
-
};
|
|
100
|
-
}
|
|
101
|
-
export function getLastFacetId() {
|
|
102
|
-
return getState().lastFacetId;
|
|
103
|
-
}
|
|
104
|
-
// ── C'.2 recovery_event ring ────────────────────────────────────────────
|
|
105
|
-
//
|
|
106
|
-
// The ring is bounded at RECOVERY_RING_SIZE; the diag endpoint reads via
|
|
107
|
-
// getRecoveryEvents() (newest first).
|
|
108
|
-
/** Append a recovery event to the ring. Newest first. Capped at
|
|
109
|
-
* RECOVERY_RING_SIZE. */
|
|
110
|
-
export function recordRecoveryEvent(e) {
|
|
111
|
-
const s = getState();
|
|
112
|
-
// Defensive copy + notes cap. We intentionally do NOT validate the
|
|
113
|
-
// state-machine direction here (e.g. that 'drained' only follows
|
|
114
|
-
// 'active') — the state machine lives elsewhere; this ring is a
|
|
115
|
-
// recorder, not an enforcer. If a probe sees an impossible
|
|
116
|
-
// transition, that's a real bug in the state machine and the
|
|
117
|
-
// probe must fail.
|
|
118
|
-
const entry = {
|
|
119
|
-
at: Number(e.at) || Date.now(),
|
|
120
|
-
fromState: e.fromState,
|
|
121
|
-
toState: e.toState,
|
|
122
|
-
trigger: String(e.trigger ?? 'unknown'),
|
|
123
|
-
isolateGen: Number(e.isolateGen) || 0,
|
|
124
|
-
dataLoss: !!e.dataLoss,
|
|
125
|
-
snapshotKeysRehydrated: Number(e.snapshotKeysRehydrated) || 0,
|
|
126
|
-
};
|
|
127
|
-
if (e.notes) {
|
|
128
|
-
const n = String(e.notes);
|
|
129
|
-
entry.notes = n.length > MESSAGE_CAP ? n.slice(0, MESSAGE_CAP) : n;
|
|
130
|
-
}
|
|
131
|
-
s.recoveryEvents.unshift(entry);
|
|
132
|
-
if (s.recoveryEvents.length > RECOVERY_RING_SIZE) {
|
|
133
|
-
s.recoveryEvents.length = RECOVERY_RING_SIZE;
|
|
134
|
-
}
|
|
135
|
-
}
|
|
136
|
-
/** Read a snapshot of the recovery ring. Newest first. */
|
|
137
|
-
export function getRecoveryEvents() {
|
|
138
|
-
return getState().recoveryEvents.slice(0);
|
|
139
|
-
}
|
|
140
|
-
/** Reset the recovery ring. Tests + manual operator use only. */
|
|
141
|
-
export function resetRecoveryEvents() {
|
|
142
|
-
getState().recoveryEvents.length = 0;
|
|
143
|
-
}
|
|
144
|
-
export function snapshotForStorage() {
|
|
145
|
-
const s = getState();
|
|
146
|
-
return {
|
|
147
|
-
v: 2,
|
|
148
|
-
failures: s.failures.slice(0),
|
|
149
|
-
recoveryEvents: s.recoveryEvents.slice(0),
|
|
150
|
-
lastRpcFrame: s.lastRpcFrame,
|
|
151
|
-
lastFacetId: s.lastFacetId,
|
|
152
|
-
};
|
|
153
|
-
}
|
|
154
|
-
/**
|
|
155
|
-
* Restore from a snapshot. Garbage / null / wrong-shape input is
|
|
156
|
-
* silently ignored. Does NOT throw — constructor-time rehydration must
|
|
157
|
-
* never block DO startup.
|
|
158
|
-
*
|
|
159
|
-
* Only the current v2 schema is accepted.
|
|
160
|
-
*/
|
|
161
|
-
export function rehydrateFromStorage(blob) {
|
|
162
|
-
if (!isRecord(blob) || blob.v !== 2)
|
|
163
|
-
return;
|
|
164
|
-
const b = blob;
|
|
165
|
-
if (!Array.isArray(b.failures))
|
|
166
|
-
return;
|
|
167
|
-
const s = getState();
|
|
168
|
-
s.failures.length = 0;
|
|
169
|
-
for (const f of b.failures) {
|
|
170
|
-
const entry = parseFailure(f);
|
|
171
|
-
if (!entry)
|
|
172
|
-
continue;
|
|
173
|
-
s.failures.push(entry);
|
|
174
|
-
if (s.failures.length >= RING_SIZE)
|
|
175
|
-
break;
|
|
176
|
-
}
|
|
177
|
-
s.recoveryEvents.length = 0;
|
|
178
|
-
if (Array.isArray(b.recoveryEvents)) {
|
|
179
|
-
for (const e of b.recoveryEvents) {
|
|
180
|
-
const entry = parseRecoveryEvent(e);
|
|
181
|
-
if (!entry)
|
|
182
|
-
continue;
|
|
183
|
-
s.recoveryEvents.push(entry);
|
|
184
|
-
if (s.recoveryEvents.length >= RECOVERY_RING_SIZE)
|
|
185
|
-
break;
|
|
186
|
-
}
|
|
187
|
-
}
|
|
188
|
-
const lastRpcFrame = parseRpcFrame(b.lastRpcFrame);
|
|
189
|
-
if (lastRpcFrame)
|
|
190
|
-
s.lastRpcFrame = lastRpcFrame;
|
|
191
|
-
const lastFacetId = parseFacetId(b.lastFacetId);
|
|
192
|
-
if (lastFacetId)
|
|
193
|
-
s.lastFacetId = lastFacetId;
|
|
194
|
-
}
|
|
195
|
-
function isRecord(value) {
|
|
196
|
-
return typeof value === 'object' && value !== null;
|
|
197
|
-
}
|
|
198
|
-
function parseRpcFrame(value) {
|
|
199
|
-
if (!isRecord(value)
|
|
200
|
-
|| typeof value.method !== 'string'
|
|
201
|
-
|| typeof value.payloadBytes !== 'number'
|
|
202
|
-
|| typeof value.atMs !== 'number')
|
|
203
|
-
return null;
|
|
204
|
-
return { method: value.method, payloadBytes: value.payloadBytes, atMs: value.atMs };
|
|
205
|
-
}
|
|
206
|
-
function parseFacetId(value) {
|
|
207
|
-
if (!isRecord(value)
|
|
208
|
-
|| typeof value.codeId !== 'string'
|
|
209
|
-
|| typeof value.slotIndex !== 'number'
|
|
210
|
-
|| typeof value.atMs !== 'number')
|
|
211
|
-
return null;
|
|
212
|
-
return { codeId: value.codeId, slotIndex: value.slotIndex, atMs: value.atMs };
|
|
213
|
-
}
|
|
214
|
-
function parseFailure(value) {
|
|
215
|
-
if (!isRecord(value)
|
|
216
|
-
|| typeof value.at !== 'number'
|
|
217
|
-
|| typeof value.phase !== 'string'
|
|
218
|
-
|| !isOomCause(value.cause)
|
|
219
|
-
|| typeof value.rssEstimateBytes !== 'number'
|
|
220
|
-
|| typeof value.heapUsedBytes !== 'number'
|
|
221
|
-
|| typeof value.lruBytes !== 'number'
|
|
222
|
-
|| typeof value.inFlightBytes !== 'number')
|
|
223
|
-
return null;
|
|
224
|
-
const entry = {
|
|
225
|
-
at: value.at,
|
|
226
|
-
phase: value.phase,
|
|
227
|
-
cause: value.cause,
|
|
228
|
-
rssEstimateBytes: value.rssEstimateBytes,
|
|
229
|
-
heapUsedBytes: value.heapUsedBytes,
|
|
230
|
-
lruBytes: value.lruBytes,
|
|
231
|
-
inFlightBytes: value.inFlightBytes,
|
|
232
|
-
lastRpcFrame: parseRpcFrame(value.lastRpcFrame),
|
|
233
|
-
lastFacetId: parseFacetId(value.lastFacetId),
|
|
234
|
-
};
|
|
235
|
-
if (typeof value.exitCode === 'number')
|
|
236
|
-
entry.exitCode = value.exitCode;
|
|
237
|
-
if (typeof value.pid === 'number')
|
|
238
|
-
entry.pid = value.pid;
|
|
239
|
-
if (typeof value.message === 'string')
|
|
240
|
-
entry.message = value.message.slice(0, MESSAGE_CAP);
|
|
241
|
-
return entry;
|
|
242
|
-
}
|
|
243
|
-
const SESSION_STATES = [
|
|
244
|
-
'cold', 'hydrated', 'active', 'drained',
|
|
245
|
-
'rehydrate', 'build', 'wire', 'online',
|
|
246
|
-
];
|
|
247
|
-
function isSessionState(value) {
|
|
248
|
-
return SESSION_STATES.some((state) => state === value);
|
|
249
|
-
}
|
|
250
|
-
function parseRecoveryEvent(value) {
|
|
251
|
-
if (!isRecord(value)
|
|
252
|
-
|| typeof value.at !== 'number'
|
|
253
|
-
|| !isSessionState(value.fromState)
|
|
254
|
-
|| !isSessionState(value.toState)
|
|
255
|
-
|| typeof value.trigger !== 'string'
|
|
256
|
-
|| typeof value.isolateGen !== 'number'
|
|
257
|
-
|| typeof value.dataLoss !== 'boolean'
|
|
258
|
-
|| typeof value.snapshotKeysRehydrated !== 'number')
|
|
259
|
-
return null;
|
|
260
|
-
const entry = {
|
|
261
|
-
at: value.at,
|
|
262
|
-
fromState: value.fromState,
|
|
263
|
-
toState: value.toState,
|
|
264
|
-
trigger: value.trigger,
|
|
265
|
-
isolateGen: value.isolateGen,
|
|
266
|
-
dataLoss: value.dataLoss,
|
|
267
|
-
snapshotKeysRehydrated: value.snapshotKeysRehydrated,
|
|
268
|
-
};
|
|
269
|
-
if (typeof value.notes === 'string')
|
|
270
|
-
entry.notes = value.notes.slice(0, MESSAGE_CAP);
|
|
271
|
-
return entry;
|
|
272
|
-
}
|
|
@@ -1,56 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* _shared/install-phase.ts — single source of truth for the npm-install
|
|
3
|
-
* state-machine phase enum.
|
|
4
|
-
*
|
|
5
|
-
* History: CLN-1 (2026-05-11) — consolidated from two diverged copies.
|
|
6
|
-
* - `npm/installer.ts:93-95` was the progress-event variant. Included
|
|
7
|
-
* 'lock-check' (a real progress event emitted while parsing
|
|
8
|
-
* package-lock.json) but lacked 'idle'.
|
|
9
|
-
* - `observability/diag-counters.ts:33-35` was the counter-state variant.
|
|
10
|
-
* Included 'idle' (the resting state when no install is in flight)
|
|
11
|
-
* but lacked 'lock-check'. The diag-counter's `setInstallPhase()`
|
|
12
|
-
* was actually called with 'idle' (installer.ts:184,201) — passing
|
|
13
|
-
* a value not declared in installer.ts's local type. The type check
|
|
14
|
-
* fell through to diag-counters' type because installer.ts imports
|
|
15
|
-
* setInstallPhase from there; the local `InstallPhase` definition
|
|
16
|
-
* in installer.ts was only used by `InstallProgress.phase`.
|
|
17
|
-
*
|
|
18
|
-
* Going forward both consumers import from this module; any new phase
|
|
19
|
-
* value added here is automatically available everywhere.
|
|
20
|
-
*
|
|
21
|
-
* Phase semantics (chronological order for a single install run):
|
|
22
|
-
*
|
|
23
|
-
* idle resting state, no install in flight
|
|
24
|
-
* ↓
|
|
25
|
-
* lock-check parsing existing package-lock.json (if present)
|
|
26
|
-
* ↓
|
|
27
|
-
* resolve walking the dep tree, fetching packuments
|
|
28
|
-
* ↓
|
|
29
|
-
* hoist hoisting peer-deps + flattening node_modules
|
|
30
|
-
* ↓
|
|
31
|
-
* diff comparing target tree against current install state
|
|
32
|
-
* ↓
|
|
33
|
-
* fetch downloading missing tarballs
|
|
34
|
-
* ↓
|
|
35
|
-
* write extracting tarballs into the VFS
|
|
36
|
-
* ↓
|
|
37
|
-
* link-bins creating bin/ symlinks
|
|
38
|
-
* ↓
|
|
39
|
-
* bundle (post-install) pre-bundling for esbuild fast path
|
|
40
|
-
* ↓
|
|
41
|
-
* done install complete; about to return to 'idle'
|
|
42
|
-
*
|
|
43
|
-
* The phase strings are surfaced via /api/_diag/install-pipeline and
|
|
44
|
-
* displayed in the install-progress UI; treat them as a public API.
|
|
45
|
-
*/
|
|
46
|
-
export type InstallPhase =
|
|
47
|
-
| 'idle'
|
|
48
|
-
| 'lock-check'
|
|
49
|
-
| 'resolve'
|
|
50
|
-
| 'hoist'
|
|
51
|
-
| 'diff'
|
|
52
|
-
| 'fetch'
|
|
53
|
-
| 'write'
|
|
54
|
-
| 'link-bins'
|
|
55
|
-
| 'bundle'
|
|
56
|
-
| 'done';
|
|
@@ -1,31 +0,0 @@
|
|
|
1
|
-
type DisposableSymbolConstructor = SymbolConstructor & { readonly dispose?: symbol };
|
|
2
|
-
|
|
3
|
-
export function disposeRpcResource(value: unknown): boolean {
|
|
4
|
-
if ((typeof value !== 'object' && typeof value !== 'function') || value === null) return false;
|
|
5
|
-
const disposerKey = (Symbol as DisposableSymbolConstructor).dispose;
|
|
6
|
-
if (!disposerKey) return false;
|
|
7
|
-
const disposer = Reflect.get(value, disposerKey);
|
|
8
|
-
if (typeof disposer !== 'function') return false;
|
|
9
|
-
try {
|
|
10
|
-
Reflect.apply(disposer, value, []);
|
|
11
|
-
return true;
|
|
12
|
-
} catch {
|
|
13
|
-
return false;
|
|
14
|
-
}
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
export function disposeRpcResources(values: Iterable<unknown>): void {
|
|
18
|
-
for (const value of values) disposeRpcResource(value);
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
export async function useRpcResource<T, R>(
|
|
22
|
-
promise: Promise<T>,
|
|
23
|
-
use: (value: T) => R | Promise<R>,
|
|
24
|
-
): Promise<R> {
|
|
25
|
-
const value = await promise;
|
|
26
|
-
try {
|
|
27
|
-
return await use(value);
|
|
28
|
-
} finally {
|
|
29
|
-
disposeRpcResource(value);
|
|
30
|
-
}
|
|
31
|
-
}
|