@runtimed/node 0.5.4 → 0.5.6-nightly.36505591006
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 +148 -5
- package/package.json +24 -11
- package/src/binding.cjs +53 -52
- package/src/binding.d.ts +39 -2
- package/src/execution-store.cjs +397 -0
- package/src/execution-store.d.cts +66 -0
- package/src/index.d.ts +52 -43
- package/src/relay.d.ts +10 -1
- package/src/session.cjs +8 -68
|
@@ -0,0 +1,397 @@
|
|
|
1
|
+
// Generated by scripts/build-execution-store.mjs. Do not edit.
|
|
2
|
+
"use strict";
|
|
3
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
4
|
+
exports.createNotebookExecutionStore = createNotebookExecutionStore;
|
|
5
|
+
const EMPTY_NOTEBOOK_QUEUE = Object.freeze({
|
|
6
|
+
executing_cell_id: null,
|
|
7
|
+
queued_cell_ids: Object.freeze([]),
|
|
8
|
+
});
|
|
9
|
+
/** Independent synchronous notebook state. Construction performs no I/O. */
|
|
10
|
+
function createNotebookExecutionStore() {
|
|
11
|
+
const _executionMap = new Map();
|
|
12
|
+
const _runtimeOwnedExecutionIds = new Set();
|
|
13
|
+
/** Per-cell reverse index: cell_id -> latest execution_id. */
|
|
14
|
+
const _cellToExecution = new Map();
|
|
15
|
+
const _executionToCell = new Map();
|
|
16
|
+
let _notebookQueueProjection = EMPTY_NOTEBOOK_QUEUE;
|
|
17
|
+
let _queue = null;
|
|
18
|
+
let _snapshot;
|
|
19
|
+
const _subscribers = new Map();
|
|
20
|
+
const _cellExecutionSubscribers = new Map();
|
|
21
|
+
const _queueProjectionSubscribers = new Set();
|
|
22
|
+
let _executionStructureVersion = 0;
|
|
23
|
+
const _executionStructureVersionSubscribers = new Set();
|
|
24
|
+
function emitExecutionChange(execution_id) {
|
|
25
|
+
const subs = _subscribers.get(execution_id);
|
|
26
|
+
if (!subs)
|
|
27
|
+
return;
|
|
28
|
+
// Snapshot listeners so subscriptions added during delivery wait for the next notification.
|
|
29
|
+
// eslint-disable-next-line unicorn/no-useless-spread
|
|
30
|
+
for (const cb of [...subs]) {
|
|
31
|
+
if (!subs.has(cb))
|
|
32
|
+
continue;
|
|
33
|
+
try {
|
|
34
|
+
cb();
|
|
35
|
+
}
|
|
36
|
+
catch {
|
|
37
|
+
// subscriber errors must not break the dispatch loop
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
function emitCellExecutionPointerChange(cell_id) {
|
|
42
|
+
const subs = _cellExecutionSubscribers.get(cell_id);
|
|
43
|
+
if (!subs)
|
|
44
|
+
return;
|
|
45
|
+
// Snapshot listeners so subscriptions added during delivery wait for the next notification.
|
|
46
|
+
// eslint-disable-next-line unicorn/no-useless-spread
|
|
47
|
+
for (const cb of [...subs]) {
|
|
48
|
+
if (!subs.has(cb))
|
|
49
|
+
continue;
|
|
50
|
+
try {
|
|
51
|
+
cb();
|
|
52
|
+
}
|
|
53
|
+
catch { }
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
function emitQueueProjectionChange() {
|
|
57
|
+
// Snapshot listeners so subscriptions added during delivery wait for the next notification.
|
|
58
|
+
// eslint-disable-next-line unicorn/no-useless-spread
|
|
59
|
+
for (const cb of [..._queueProjectionSubscribers]) {
|
|
60
|
+
if (!_queueProjectionSubscribers.has(cb))
|
|
61
|
+
continue;
|
|
62
|
+
try {
|
|
63
|
+
cb();
|
|
64
|
+
}
|
|
65
|
+
catch { }
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
function emitExecutionStructureChange() {
|
|
69
|
+
_executionStructureVersion = (_executionStructureVersion + 1) | 0;
|
|
70
|
+
// Snapshot listeners so subscriptions added during delivery wait for the next notification.
|
|
71
|
+
// eslint-disable-next-line unicorn/no-useless-spread
|
|
72
|
+
for (const cb of [..._executionStructureVersionSubscribers]) {
|
|
73
|
+
if (!_executionStructureVersionSubscribers.has(cb))
|
|
74
|
+
continue;
|
|
75
|
+
try {
|
|
76
|
+
cb();
|
|
77
|
+
}
|
|
78
|
+
catch { }
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
// ── Subscription helpers ────────────────────────────────────────────────
|
|
82
|
+
function subscribeExecutionById(execution_id) {
|
|
83
|
+
return (callback) => {
|
|
84
|
+
let subs = _subscribers.get(execution_id);
|
|
85
|
+
if (!subs) {
|
|
86
|
+
subs = new Set();
|
|
87
|
+
_subscribers.set(execution_id, subs);
|
|
88
|
+
}
|
|
89
|
+
const set = subs;
|
|
90
|
+
set.add(callback);
|
|
91
|
+
let active = true;
|
|
92
|
+
return () => {
|
|
93
|
+
if (!active)
|
|
94
|
+
return;
|
|
95
|
+
active = false;
|
|
96
|
+
set.delete(callback);
|
|
97
|
+
if (set.size === 0 && _subscribers.get(execution_id) === set)
|
|
98
|
+
_subscribers.delete(execution_id);
|
|
99
|
+
};
|
|
100
|
+
};
|
|
101
|
+
}
|
|
102
|
+
function getExecutionSnapshotGetter(execution_id) {
|
|
103
|
+
return () => (execution_id ? _executionMap.get(execution_id) : undefined);
|
|
104
|
+
}
|
|
105
|
+
function subscribeCellExecutionPointer(cell_id) {
|
|
106
|
+
return (callback) => {
|
|
107
|
+
let subs = _cellExecutionSubscribers.get(cell_id);
|
|
108
|
+
if (!subs) {
|
|
109
|
+
subs = new Set();
|
|
110
|
+
_cellExecutionSubscribers.set(cell_id, subs);
|
|
111
|
+
}
|
|
112
|
+
const set = subs;
|
|
113
|
+
set.add(callback);
|
|
114
|
+
let active = true;
|
|
115
|
+
return () => {
|
|
116
|
+
if (!active)
|
|
117
|
+
return;
|
|
118
|
+
active = false;
|
|
119
|
+
set.delete(callback);
|
|
120
|
+
if (set.size === 0 && _cellExecutionSubscribers.get(cell_id) === set)
|
|
121
|
+
_cellExecutionSubscribers.delete(cell_id);
|
|
122
|
+
};
|
|
123
|
+
};
|
|
124
|
+
}
|
|
125
|
+
function getCellExecutionIdGetter(cell_id) {
|
|
126
|
+
return () => _cellToExecution.get(cell_id) ?? null;
|
|
127
|
+
}
|
|
128
|
+
function subscribeNotebookQueueProjection(callback) {
|
|
129
|
+
_queueProjectionSubscribers.add(callback);
|
|
130
|
+
let active = true;
|
|
131
|
+
return () => {
|
|
132
|
+
if (!active)
|
|
133
|
+
return;
|
|
134
|
+
active = false;
|
|
135
|
+
_queueProjectionSubscribers.delete(callback);
|
|
136
|
+
};
|
|
137
|
+
}
|
|
138
|
+
function getNotebookQueueProjection() {
|
|
139
|
+
return _notebookQueueProjection;
|
|
140
|
+
}
|
|
141
|
+
function subscribeExecutionStructureVersion(callback) {
|
|
142
|
+
_executionStructureVersionSubscribers.add(callback);
|
|
143
|
+
let active = true;
|
|
144
|
+
return () => {
|
|
145
|
+
if (!active)
|
|
146
|
+
return;
|
|
147
|
+
active = false;
|
|
148
|
+
_executionStructureVersionSubscribers.delete(callback);
|
|
149
|
+
};
|
|
150
|
+
}
|
|
151
|
+
function getExecutionStructureVersionSnapshot() {
|
|
152
|
+
return _executionStructureVersion;
|
|
153
|
+
}
|
|
154
|
+
// ── Write operations ────────────────────────────────────────────────────
|
|
155
|
+
/**
|
|
156
|
+
* Upsert an execution snapshot. Notifies only that execution's subscribers.
|
|
157
|
+
*
|
|
158
|
+
* Does NOT update the cell -> execution pointer. `RuntimeStateDoc` keeps
|
|
159
|
+
* historical executions per cell, so iterating it cannot reliably pick
|
|
160
|
+
* the current one. Callers set the cell pointer explicitly via
|
|
161
|
+
* `setCellExecutionPointer`, driven by the canonical `cells/{id}/execution_id`
|
|
162
|
+
* field in the notebook doc.
|
|
163
|
+
*/
|
|
164
|
+
function setExecution(execution_id, snap) {
|
|
165
|
+
const prev = _executionMap.get(execution_id);
|
|
166
|
+
const sameOutputs = prev !== undefined && stringArraysEqual(prev.output_ids, snap.output_ids);
|
|
167
|
+
if (prev &&
|
|
168
|
+
sameOutputs &&
|
|
169
|
+
prev.execution_count === snap.execution_count &&
|
|
170
|
+
prev.status === snap.status &&
|
|
171
|
+
prev.success === snap.success &&
|
|
172
|
+
(prev.submitted_by_actor_label ?? null) === (snap.submitted_by_actor_label ?? null))
|
|
173
|
+
return;
|
|
174
|
+
const owned = Object.freeze({
|
|
175
|
+
...snap,
|
|
176
|
+
output_ids: sameOutputs ? prev.output_ids : Object.freeze([...snap.output_ids]),
|
|
177
|
+
});
|
|
178
|
+
_executionMap.set(execution_id, owned);
|
|
179
|
+
_snapshot = undefined;
|
|
180
|
+
emitExecutionChange(execution_id);
|
|
181
|
+
if (!prev || prev.execution_count !== snap.execution_count || !sameOutputs)
|
|
182
|
+
emitExecutionStructureChange();
|
|
183
|
+
}
|
|
184
|
+
/**
|
|
185
|
+
* Mark execution snapshots whose authoritative source is RuntimeStateDoc.
|
|
186
|
+
*
|
|
187
|
+
* Projection placeholders can seed the same execution id before runtime sync
|
|
188
|
+
* catches up. Runtime upserts call this even when the snapshot is unchanged so
|
|
189
|
+
* projector cleanup can release ownership without deleting the runtime record.
|
|
190
|
+
*/
|
|
191
|
+
function markExecutionsRuntimeOwned(execution_ids) {
|
|
192
|
+
for (const execution_id of execution_ids) {
|
|
193
|
+
_runtimeOwnedExecutionIds.add(execution_id);
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
function isExecutionRuntimeOwned(execution_id) {
|
|
197
|
+
return _runtimeOwnedExecutionIds.has(execution_id);
|
|
198
|
+
}
|
|
199
|
+
/**
|
|
200
|
+
* Explicitly set the active execution_id for a cell.
|
|
201
|
+
*
|
|
202
|
+
* Used on execution_started broadcasts and on clearOutputs (pass null).
|
|
203
|
+
*/
|
|
204
|
+
function setCellExecutionPointer(cell_id, execution_id) {
|
|
205
|
+
const prev = _cellToExecution.get(cell_id) ?? null;
|
|
206
|
+
if (prev === execution_id)
|
|
207
|
+
return;
|
|
208
|
+
if (prev !== null && _executionToCell.get(prev) === cell_id) {
|
|
209
|
+
_executionToCell.delete(prev);
|
|
210
|
+
}
|
|
211
|
+
if (execution_id === null) {
|
|
212
|
+
_cellToExecution.delete(cell_id);
|
|
213
|
+
}
|
|
214
|
+
else {
|
|
215
|
+
_cellToExecution.set(cell_id, execution_id);
|
|
216
|
+
_executionToCell.set(execution_id, cell_id);
|
|
217
|
+
}
|
|
218
|
+
_snapshot = undefined;
|
|
219
|
+
emitCellExecutionPointerChange(cell_id);
|
|
220
|
+
emitExecutionStructureChange();
|
|
221
|
+
}
|
|
222
|
+
function setNotebookQueueProjection(projection) {
|
|
223
|
+
const next = notebookQueuesEqual(_notebookQueueProjection, projection)
|
|
224
|
+
? _notebookQueueProjection
|
|
225
|
+
: Object.freeze({
|
|
226
|
+
executing_cell_id: projection.executing_cell_id,
|
|
227
|
+
queued_cell_ids: Object.freeze([...projection.queued_cell_ids]),
|
|
228
|
+
});
|
|
229
|
+
// A cell-only projection cannot invent execution queue membership, but it
|
|
230
|
+
// must keep an existing aggregate queue current before notifying readers.
|
|
231
|
+
if (_queue && !notebookQueuesEqual(_queue.notebook, next)) {
|
|
232
|
+
_queue = Object.freeze({ ..._queue, notebook: next });
|
|
233
|
+
_snapshot = undefined;
|
|
234
|
+
}
|
|
235
|
+
updateNotebookQueueProjection(next);
|
|
236
|
+
}
|
|
237
|
+
/** Accept an owned projection; wire updates preserve absent/null adapters. */
|
|
238
|
+
function updateNotebookQueueProjection(projection) {
|
|
239
|
+
if (notebookQueuesEqual(_notebookQueueProjection, projection))
|
|
240
|
+
return;
|
|
241
|
+
_notebookQueueProjection = projection;
|
|
242
|
+
emitQueueProjectionChange();
|
|
243
|
+
}
|
|
244
|
+
/**
|
|
245
|
+
* Drop a batch of executions from the store.
|
|
246
|
+
*
|
|
247
|
+
* Notifies per-execution subscribers with `undefined` and clears any cell
|
|
248
|
+
* pointer that referenced one of the removed ids. Used by the projection
|
|
249
|
+
* when the daemon trims an execution out of `RuntimeStateDoc` so the
|
|
250
|
+
* store doesn't drift monotonically larger.
|
|
251
|
+
*/
|
|
252
|
+
function deleteExecutions(execution_ids) {
|
|
253
|
+
for (const eid of execution_ids) {
|
|
254
|
+
const existed = _executionMap.delete(eid);
|
|
255
|
+
_runtimeOwnedExecutionIds.delete(eid);
|
|
256
|
+
const cellId = _executionToCell.get(eid);
|
|
257
|
+
_executionToCell.delete(eid);
|
|
258
|
+
const cleared = cellId !== undefined && _cellToExecution.get(cellId) === eid;
|
|
259
|
+
if (cleared)
|
|
260
|
+
_cellToExecution.delete(cellId);
|
|
261
|
+
if (!existed && !cleared)
|
|
262
|
+
continue;
|
|
263
|
+
_snapshot = undefined;
|
|
264
|
+
if (existed)
|
|
265
|
+
emitExecutionChange(eid);
|
|
266
|
+
if (cleared)
|
|
267
|
+
emitCellExecutionPointerChange(cellId);
|
|
268
|
+
emitExecutionStructureChange();
|
|
269
|
+
}
|
|
270
|
+
}
|
|
271
|
+
/** Read a snapshot without subscribing. */
|
|
272
|
+
function getExecutionById(execution_id) {
|
|
273
|
+
return _executionMap.get(execution_id);
|
|
274
|
+
}
|
|
275
|
+
/** Read the cell's current execution_id without subscribing. */
|
|
276
|
+
function getCellExecutionId(cell_id) {
|
|
277
|
+
return _cellToExecution.get(cell_id) ?? null;
|
|
278
|
+
}
|
|
279
|
+
/** Read the current cell id for an execution pointer without subscribing. */
|
|
280
|
+
function getCellIdForExecutionId(execution_id) {
|
|
281
|
+
return _executionToCell.get(execution_id) ?? null;
|
|
282
|
+
}
|
|
283
|
+
/** Reset the entire store. Called on notebook switch or full reset. */
|
|
284
|
+
function resetNotebookExecutions() {
|
|
285
|
+
const eids = [..._executionMap.keys()];
|
|
286
|
+
const cells = [..._cellToExecution.keys()];
|
|
287
|
+
_executionMap.clear();
|
|
288
|
+
_runtimeOwnedExecutionIds.clear();
|
|
289
|
+
_cellToExecution.clear();
|
|
290
|
+
_executionToCell.clear();
|
|
291
|
+
_notebookQueueProjection = EMPTY_NOTEBOOK_QUEUE;
|
|
292
|
+
_queue = null;
|
|
293
|
+
_snapshot = undefined;
|
|
294
|
+
for (const eid of eids)
|
|
295
|
+
emitExecutionChange(eid);
|
|
296
|
+
for (const cid of cells)
|
|
297
|
+
emitCellExecutionPointerChange(cid);
|
|
298
|
+
emitQueueProjectionChange();
|
|
299
|
+
if (eids.length > 0 || cells.length > 0) {
|
|
300
|
+
emitExecutionStructureChange();
|
|
301
|
+
}
|
|
302
|
+
}
|
|
303
|
+
function stringArraysEqual(a, b) {
|
|
304
|
+
if (a.length !== b.length)
|
|
305
|
+
return false;
|
|
306
|
+
for (let i = 0; i < a.length; i++) {
|
|
307
|
+
if (a[i] !== b[i])
|
|
308
|
+
return false;
|
|
309
|
+
}
|
|
310
|
+
return true;
|
|
311
|
+
}
|
|
312
|
+
/** Lazily materialize a stable, immutable aggregate for headless consumers. */
|
|
313
|
+
function getSnapshot() {
|
|
314
|
+
return (_snapshot ??= Object.freeze({
|
|
315
|
+
cell_execution_ids: Object.freeze(Object.fromEntries(_cellToExecution)),
|
|
316
|
+
executions: Object.freeze(Object.fromEntries(_executionMap)),
|
|
317
|
+
queue: _queue,
|
|
318
|
+
}));
|
|
319
|
+
}
|
|
320
|
+
/**
|
|
321
|
+
* Apply Rust's projection in frontend order: upserts, removals, pointers, queue.
|
|
322
|
+
* Notifications are synchronous per write, not an atomic changeset batch.
|
|
323
|
+
* Reads inside notifications are current; retained snapshots never change.
|
|
324
|
+
*/
|
|
325
|
+
function applyChangeset(changeset, options = {}) {
|
|
326
|
+
if (!changeset)
|
|
327
|
+
return;
|
|
328
|
+
for (const [id, snapshot] of changeset.execution_upserts ?? []) {
|
|
329
|
+
markExecutionsRuntimeOwned([id]);
|
|
330
|
+
setExecution(id, snapshot);
|
|
331
|
+
options.onExecutionSnapshot?.(id, getExecutionById(id));
|
|
332
|
+
}
|
|
333
|
+
deleteExecutions(changeset.removed_execution_ids ?? []);
|
|
334
|
+
for (const [cell, id] of changeset.cell_pointer_changes ?? [])
|
|
335
|
+
setCellExecutionPointer(cell, id);
|
|
336
|
+
if (Object.prototype.hasOwnProperty.call(changeset, "queue")) {
|
|
337
|
+
const queue = changeset.queue;
|
|
338
|
+
const next = queue == null
|
|
339
|
+
? null
|
|
340
|
+
: Object.freeze({
|
|
341
|
+
executing_execution_id: queue.executing_execution_id ?? null,
|
|
342
|
+
queued_execution_ids: Object.freeze([...queue.queued_execution_ids]),
|
|
343
|
+
notebook: queue.notebook == null
|
|
344
|
+
? queue.notebook
|
|
345
|
+
: Object.freeze({
|
|
346
|
+
executing_cell_id: queue.notebook.executing_cell_id ?? null,
|
|
347
|
+
queued_cell_ids: Object.freeze([...queue.notebook.queued_cell_ids]),
|
|
348
|
+
}),
|
|
349
|
+
});
|
|
350
|
+
if (!queuesEqual(_queue, next)) {
|
|
351
|
+
_queue = next;
|
|
352
|
+
_snapshot = undefined;
|
|
353
|
+
}
|
|
354
|
+
updateNotebookQueueProjection(next?.notebook ?? EMPTY_NOTEBOOK_QUEUE);
|
|
355
|
+
}
|
|
356
|
+
}
|
|
357
|
+
function queuesEqual(a, b) {
|
|
358
|
+
if (a === b)
|
|
359
|
+
return true;
|
|
360
|
+
if (!a || !b)
|
|
361
|
+
return false;
|
|
362
|
+
if (a.executing_execution_id !== b.executing_execution_id ||
|
|
363
|
+
!stringArraysEqual(a.queued_execution_ids, b.queued_execution_ids))
|
|
364
|
+
return false;
|
|
365
|
+
return notebookQueuesEqual(a.notebook, b.notebook);
|
|
366
|
+
}
|
|
367
|
+
function notebookQueuesEqual(a, b) {
|
|
368
|
+
if (a === b)
|
|
369
|
+
return true;
|
|
370
|
+
if (!a || !b)
|
|
371
|
+
return false;
|
|
372
|
+
return (a.executing_cell_id === b.executing_cell_id &&
|
|
373
|
+
stringArraysEqual(a.queued_cell_ids, b.queued_cell_ids));
|
|
374
|
+
}
|
|
375
|
+
return {
|
|
376
|
+
subscribeNotebookQueueProjection,
|
|
377
|
+
getNotebookQueueProjection,
|
|
378
|
+
setExecution,
|
|
379
|
+
markExecutionsRuntimeOwned,
|
|
380
|
+
isExecutionRuntimeOwned,
|
|
381
|
+
setCellExecutionPointer,
|
|
382
|
+
setNotebookQueueProjection,
|
|
383
|
+
deleteExecutions,
|
|
384
|
+
getExecutionById,
|
|
385
|
+
getCellExecutionId,
|
|
386
|
+
getCellIdForExecutionId,
|
|
387
|
+
resetNotebookExecutions,
|
|
388
|
+
subscribeExecutionById,
|
|
389
|
+
getExecutionSnapshotGetter,
|
|
390
|
+
subscribeCellExecutionPointer,
|
|
391
|
+
getCellExecutionIdGetter,
|
|
392
|
+
subscribeExecutionStructureVersion,
|
|
393
|
+
getExecutionStructureVersionSnapshot,
|
|
394
|
+
getSnapshot,
|
|
395
|
+
applyChangeset,
|
|
396
|
+
};
|
|
397
|
+
}
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
// Generated by scripts/build-execution-store.mjs. Do not edit.
|
|
2
|
+
export interface ExecutionViewSnapshot {
|
|
3
|
+
execution_count: number | null;
|
|
4
|
+
status: "queued" | "running" | "done" | "error" | "cancelled" | (string & {});
|
|
5
|
+
success: boolean | null;
|
|
6
|
+
output_ids: string[];
|
|
7
|
+
submitted_by_actor_label?: string | null;
|
|
8
|
+
}
|
|
9
|
+
export interface ExecutionQueueProjection {
|
|
10
|
+
executing_execution_id?: string | null;
|
|
11
|
+
queued_execution_ids: string[];
|
|
12
|
+
notebook?: {
|
|
13
|
+
executing_cell_id?: string | null;
|
|
14
|
+
queued_cell_ids: string[];
|
|
15
|
+
} | null;
|
|
16
|
+
}
|
|
17
|
+
export interface ExecutionViewChangeset {
|
|
18
|
+
cell_pointer_changes?: Array<[cell_id: string, execution_id: string | null]>;
|
|
19
|
+
execution_upserts?: Array<[execution_id: string, snapshot: ExecutionViewSnapshot]>;
|
|
20
|
+
removed_execution_ids?: string[];
|
|
21
|
+
queue?: ExecutionQueueProjection | null;
|
|
22
|
+
}
|
|
23
|
+
/** Immutable consumer snapshots; wire payload types above remain mutable. */
|
|
24
|
+
export type ExecutionSnapshot = Readonly<Omit<ExecutionViewSnapshot, "output_ids">> & {
|
|
25
|
+
readonly output_ids: readonly string[];
|
|
26
|
+
};
|
|
27
|
+
export interface NotebookQueueProjectionSnapshot {
|
|
28
|
+
readonly executing_cell_id: string | null;
|
|
29
|
+
readonly queued_cell_ids: readonly string[];
|
|
30
|
+
}
|
|
31
|
+
export interface ExecutionQueueSnapshot {
|
|
32
|
+
readonly executing_execution_id: string | null;
|
|
33
|
+
readonly queued_execution_ids: readonly string[];
|
|
34
|
+
readonly notebook?: NotebookQueueProjectionSnapshot | null;
|
|
35
|
+
}
|
|
36
|
+
export interface ExecutionView {
|
|
37
|
+
readonly cell_execution_ids: Readonly<Record<string, string>>;
|
|
38
|
+
readonly executions: Readonly<Record<string, ExecutionSnapshot>>;
|
|
39
|
+
readonly queue: ExecutionQueueSnapshot | null;
|
|
40
|
+
}
|
|
41
|
+
/** Independent synchronous notebook state. Construction performs no I/O. */
|
|
42
|
+
export declare function createNotebookExecutionStore(): {
|
|
43
|
+
subscribeNotebookQueueProjection: (callback: () => void) => () => void;
|
|
44
|
+
getNotebookQueueProjection: () => NotebookQueueProjectionSnapshot;
|
|
45
|
+
setExecution: (execution_id: string, snap: ExecutionSnapshot) => void;
|
|
46
|
+
markExecutionsRuntimeOwned: (execution_ids: Iterable<string>) => void;
|
|
47
|
+
isExecutionRuntimeOwned: (execution_id: string) => boolean;
|
|
48
|
+
setCellExecutionPointer: (cell_id: string, execution_id: string | null) => void;
|
|
49
|
+
setNotebookQueueProjection: (projection: NotebookQueueProjectionSnapshot) => void;
|
|
50
|
+
deleteExecutions: (execution_ids: Iterable<string>) => void;
|
|
51
|
+
getExecutionById: (execution_id: string) => ExecutionSnapshot | undefined;
|
|
52
|
+
getCellExecutionId: (cell_id: string) => string | null;
|
|
53
|
+
getCellIdForExecutionId: (execution_id: string) => string | null;
|
|
54
|
+
resetNotebookExecutions: () => void;
|
|
55
|
+
subscribeExecutionById: (execution_id: string) => (cb: () => void) => () => void;
|
|
56
|
+
getExecutionSnapshotGetter: (execution_id: string) => () => ExecutionSnapshot | undefined;
|
|
57
|
+
subscribeCellExecutionPointer: (cell_id: string) => (cb: () => void) => () => void;
|
|
58
|
+
getCellExecutionIdGetter: (cell_id: string) => () => string | null;
|
|
59
|
+
subscribeExecutionStructureVersion: (callback: () => void) => () => void;
|
|
60
|
+
getExecutionStructureVersionSnapshot: () => number;
|
|
61
|
+
getSnapshot: () => ExecutionView;
|
|
62
|
+
applyChangeset: (changeset: ExecutionViewChangeset | null | undefined, options?: {
|
|
63
|
+
onExecutionSnapshot?: (id: string, snapshot: ExecutionSnapshot) => void;
|
|
64
|
+
}) => void;
|
|
65
|
+
};
|
|
66
|
+
export type NotebookExecutionStore = ReturnType<typeof createNotebookExecutionStore>;
|
package/src/index.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { Observable } from "rxjs";
|
|
2
2
|
|
|
3
|
-
export { RelaySession, connectRelay, createRelay, openRelayPath } from "./relay";
|
|
3
|
+
export { RelaySession, connectRelay, createRelay, openRelayPath, queryDaemonInfo } from "./relay";
|
|
4
4
|
export type {
|
|
5
5
|
CommentsNotebookRef,
|
|
6
6
|
CreateRelayOptions,
|
|
@@ -11,16 +11,14 @@ export type {
|
|
|
11
11
|
RelayInfo,
|
|
12
12
|
} from "./relay";
|
|
13
13
|
|
|
14
|
-
export type
|
|
15
|
-
export type
|
|
14
|
+
export type ConnectionState = "Connected" | "Disconnected";
|
|
15
|
+
export type NotebookDocPhase = "Pending" | "Syncing" | "Interactive";
|
|
16
|
+
export type RuntimeStatePhase = "Pending" | "Syncing" | "Ready";
|
|
16
17
|
|
|
17
|
-
export type InitialLoadPhase =
|
|
18
|
-
| { phase: "not_needed" }
|
|
19
|
-
| { phase: "streaming" }
|
|
20
|
-
| { phase: "ready" }
|
|
21
|
-
| { phase: "failed"; reason: string };
|
|
18
|
+
export type InitialLoadPhase = "NotNeeded" | "Streaming" | "Ready" | { Failed: { reason: string } };
|
|
22
19
|
|
|
23
20
|
export interface SessionStatus {
|
|
21
|
+
connection: ConnectionState;
|
|
24
22
|
notebook_doc: NotebookDocPhase;
|
|
25
23
|
runtime_state: RuntimeStatePhase;
|
|
26
24
|
initial_load: InitialLoadPhase;
|
|
@@ -32,41 +30,20 @@ export interface ExecutionTransition {
|
|
|
32
30
|
execution_count: number | null;
|
|
33
31
|
}
|
|
34
32
|
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
} | null;
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
export interface ExecutionViewChangeset {
|
|
53
|
-
cell_pointer_changes?: Array<[cell_id: string, execution_id: string | null]>;
|
|
54
|
-
execution_upserts?: Array<[execution_id: string, snapshot: ExecutionViewSnapshot]>;
|
|
55
|
-
removed_execution_ids?: string[];
|
|
56
|
-
queue?: ExecutionQueueProjection;
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
export interface ExecutionView {
|
|
60
|
-
/**
|
|
61
|
-
* Current non-null NotebookDoc cell -> execution_id pointers.
|
|
62
|
-
*
|
|
63
|
-
* Cleared or deleted cells are omitted. Subscribe to `executionViewChanges$`
|
|
64
|
-
* when null pointer transitions matter.
|
|
65
|
-
*/
|
|
66
|
-
cell_execution_ids: Record<string, string>;
|
|
67
|
-
executions: Record<string, ExecutionViewSnapshot>;
|
|
68
|
-
queue: ExecutionQueueProjection | null;
|
|
69
|
-
}
|
|
33
|
+
import type {
|
|
34
|
+
ExecutionViewChangeset,
|
|
35
|
+
ExecutionView,
|
|
36
|
+
NotebookExecutionStore,
|
|
37
|
+
} from "./execution-store.cjs";
|
|
38
|
+
export type {
|
|
39
|
+
ExecutionViewSnapshot,
|
|
40
|
+
ExecutionQueueProjection,
|
|
41
|
+
ExecutionViewChangeset,
|
|
42
|
+
ExecutionSnapshot,
|
|
43
|
+
ExecutionQueueSnapshot,
|
|
44
|
+
ExecutionView,
|
|
45
|
+
NotebookExecutionStore,
|
|
46
|
+
} from "./execution-store.cjs";
|
|
70
47
|
|
|
71
48
|
export type RuntimeState = Record<string, unknown>;
|
|
72
49
|
|
|
@@ -247,6 +224,14 @@ export class Session {
|
|
|
247
224
|
runCell(source: string, options?: RunCellOptions): Promise<CellResult>;
|
|
248
225
|
saveNotebook(path?: string): Promise<void>;
|
|
249
226
|
exportSnapshotPair(): Promise<SnapshotPair>;
|
|
227
|
+
/**
|
|
228
|
+
* Return the current NotebookDoc heads after the connected daemon accepts them.
|
|
229
|
+
* Later edits are not covered. Rejects on timeout, close, disconnect, rejection,
|
|
230
|
+
* and unsupported peers (including hosted bridges). Persistent local rooms
|
|
231
|
+
* preserve recovery-journal-before-acceptance; ephemeral rooms promise acceptance
|
|
232
|
+
* only. Does not export an .ipynb or acknowledge runtime, comments, or widgets.
|
|
233
|
+
*/
|
|
234
|
+
confirmNotebookSync(): Promise<string[]>;
|
|
250
235
|
listCells(): Promise<CellSnapshot[]>;
|
|
251
236
|
getCell(cellId: string): Promise<CellSnapshot | null>;
|
|
252
237
|
createCell(source: string, options?: CreateCellOptions): Promise<string>;
|
|
@@ -265,7 +250,9 @@ export class Session {
|
|
|
265
250
|
removeDependencies(packages: string[], options?: DependencyEditOptions): Promise<number>;
|
|
266
251
|
getDependencyStatus(): Promise<DependencyStatus>;
|
|
267
252
|
getRuntimeStatus(): Promise<RuntimeStatus>;
|
|
253
|
+
/** Stable immutable state; explicitly copy it if mutable ownership is needed. */
|
|
268
254
|
getExecutionView(): ExecutionView;
|
|
255
|
+
readonly executions: NotebookExecutionStore;
|
|
269
256
|
dependencyFingerprint(): Promise<string | null>;
|
|
270
257
|
approveTrust(observedHeads?: string[]): Promise<void>;
|
|
271
258
|
syncEnvironment(): Promise<void>;
|
|
@@ -276,6 +263,28 @@ export const NativeSession: unknown;
|
|
|
276
263
|
|
|
277
264
|
export function defaultSocketPath(): string;
|
|
278
265
|
export function socketPathForChannel(channel: "stable" | "nightly"): string;
|
|
266
|
+
|
|
267
|
+
export interface InitializeEnvironmentYmlOptions {
|
|
268
|
+
/** Existing absolute directory the local host is authorized to write. */
|
|
269
|
+
directory: string;
|
|
270
|
+
/** Optional name containing only letters, numbers, '.', '_' and '-'. */
|
|
271
|
+
name?: string;
|
|
272
|
+
/** Conda match specs. Pip subsections are not supported by this initializer. */
|
|
273
|
+
dependencies: string[];
|
|
274
|
+
/** Python version constraint, e.g. "3.12" or ">=3.11,<3.13". */
|
|
275
|
+
python?: string;
|
|
276
|
+
/** At least one channel, in priority order. No channels are inferred. */
|
|
277
|
+
channels: string[];
|
|
278
|
+
}
|
|
279
|
+
|
|
280
|
+
/**
|
|
281
|
+
* Explicitly create environment.yml using the local host's filesystem authority.
|
|
282
|
+
* Returns its filesystem-canonical absolute path. Rejects existing files/symlinks.
|
|
283
|
+
* Checks for environment.yaml first; hosts must coordinate other writers of it.
|
|
284
|
+
* Does not install packages, approve trust, contact a daemon or change a kernel.
|
|
285
|
+
*/
|
|
286
|
+
export function initializeEnvironmentYml(options: InitializeEnvironmentYmlOptions): Promise<string>;
|
|
287
|
+
|
|
279
288
|
export function createNotebook(options?: CreateNotebookOptions): Promise<Session>;
|
|
280
289
|
export function openNotebook(notebookId: string, options?: OpenNotebookOptions): Promise<Session>;
|
|
281
290
|
export function openNotebookPath(path: string, options?: OpenNotebookOptions): Promise<Session>;
|
package/src/relay.d.ts
CHANGED
|
@@ -32,6 +32,11 @@ export interface QueryDaemonOptions {
|
|
|
32
32
|
|
|
33
33
|
export interface DaemonInfo {
|
|
34
34
|
version: string;
|
|
35
|
+
protocolVersion: number;
|
|
36
|
+
/** Zero means the daemon predates semantic API version reporting. */
|
|
37
|
+
daemonApiVersion: number;
|
|
38
|
+
/** Shared Rust compatibility diagnostic; absent when supported by this client. */
|
|
39
|
+
compatibilityError?: string;
|
|
35
40
|
socketPath: string;
|
|
36
41
|
isDevMode: boolean;
|
|
37
42
|
blobPort?: number;
|
|
@@ -82,5 +87,9 @@ export function connectRelay(notebookId: string, options?: OpenRelayOptions): Pr
|
|
|
82
87
|
export function defaultSocketPath(): string;
|
|
83
88
|
/** Resolve a stable or nightly daemon endpoint independently of this package's build channel. */
|
|
84
89
|
export function socketPathForChannel(channel: "stable" | "nightly"): string;
|
|
85
|
-
/**
|
|
90
|
+
/**
|
|
91
|
+
* Return null when metadata is unavailable. A responding incompatible daemon
|
|
92
|
+
* returns metadata with compatibilityError. This probe does not authenticate
|
|
93
|
+
* a process or guarantee compatibility of a later notebook connection.
|
|
94
|
+
*/
|
|
86
95
|
export function queryDaemonInfo(options?: QueryDaemonOptions): Promise<DaemonInfo | null>;
|