@langchain/langgraph-sdk 1.9.29 → 1.9.31
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/stream/controller.cjs +119 -23
- package/dist/stream/controller.cjs.map +1 -1
- package/dist/stream/controller.d.cts.map +1 -1
- package/dist/stream/controller.d.ts.map +1 -1
- package/dist/stream/controller.js +119 -23
- package/dist/stream/controller.js.map +1 -1
- package/dist/stream/lifecycle-loading-tracker.cjs +12 -2
- package/dist/stream/lifecycle-loading-tracker.cjs.map +1 -1
- package/dist/stream/lifecycle-loading-tracker.js +12 -2
- package/dist/stream/lifecycle-loading-tracker.js.map +1 -1
- package/dist/stream/message-reconciliation.cjs +80 -4
- package/dist/stream/message-reconciliation.cjs.map +1 -1
- package/dist/stream/message-reconciliation.js +80 -4
- package/dist/stream/message-reconciliation.js.map +1 -1
- package/dist/stream/projections/messages.cjs +1 -1
- package/dist/stream/projections/messages.cjs.map +1 -1
- package/dist/stream/projections/messages.js +2 -2
- package/dist/stream/projections/messages.js.map +1 -1
- package/dist/stream/root-message-projection.cjs +12 -6
- package/dist/stream/root-message-projection.cjs.map +1 -1
- package/dist/stream/root-message-projection.js +13 -7
- package/dist/stream/root-message-projection.js.map +1 -1
- package/dist/stream/submit-coordinator.cjs +1 -1
- package/dist/stream/submit-coordinator.cjs.map +1 -1
- package/dist/stream/submit-coordinator.js +1 -1
- package/dist/stream/submit-coordinator.js.map +1 -1
- package/package.json +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"controller.d.cts","names":[],"sources":["../../src/stream/controller.ts"],"mappings":";;;;;;;;;;;;;;AA6KA;;cAAa,kBAAA,WAA6B,OAAA;;AAkC1C;;;;;;;;;;;;cAAa,gBAAA,4BACgB,MAAA,8EAEO,MAAA;EAAA;WAEzB,SAAA,EAAW,WAAA,CAAY,YAAA,CAAa,SAAA,EAAW,aAAA;EAAA,SAC/C,aAAA,EAAe,WAAA,CAAY,WAAA;EAAA,SAC3B,aAAA,EAAe,WAAA,CAAY,WAAA;EAAA,SAC3B,mBAAA,EAAqB,WAAA,CAAY,iBAAA;EAAA,SACjC,oBAAA,EAAsB,WAAA,CAAY,kBAAA;EAAA,SAClC,UAAA,EAAY,WAAA,CAAY,uBAAA,CAAwB,SAAA;EAAA,SAChD,QAAA,EAAU,eAAA;
|
|
1
|
+
{"version":3,"file":"controller.d.cts","names":[],"sources":["../../src/stream/controller.ts"],"mappings":";;;;;;;;;;;;;;AA6KA;;cAAa,kBAAA,WAA6B,OAAA;;AAkC1C;;;;;;;;;;;;cAAa,gBAAA,4BACgB,MAAA,8EAEO,MAAA;EAAA;WAEzB,SAAA,EAAW,WAAA,CAAY,YAAA,CAAa,SAAA,EAAW,aAAA;EAAA,SAC/C,aAAA,EAAe,WAAA,CAAY,WAAA;EAAA,SAC3B,aAAA,EAAe,WAAA,CAAY,WAAA;EAAA,SAC3B,mBAAA,EAAqB,WAAA,CAAY,iBAAA;EAAA,SACjC,oBAAA,EAAsB,WAAA,CAAY,kBAAA;EAAA,SAClC,UAAA,EAAY,WAAA,CAAY,uBAAA,CAAwB,SAAA;EAAA,SAChD,QAAA,EAAU,eAAA;EAqJ0B;;;;;EAA7C,WAAA,CAAY,OAAA,EAAS,uBAAA,CAAwB,SAAA;EAszBF;;;;;;;EAAA,IA5rBvC,gBAAA,CAAA,GAAoB,OAAA;EAi2BS;;;;;;;;EAxyB3B,OAAA,CAAQ,QAAA,mBAA2B,OAAA;EA0hCpB;;;;;;;;;;;;;;EA7pBf,wBAAA,CAAyB,UAAA,WAAqB,OAAA;EA1sB5B;;;;;;;;EA88BlB,MAAA,CACJ,KAAA,WACA,OAAA,GAAU,mBAAA,CAAoB,SAAA,EAAW,gBAAA,IACxC,OAAA;EA98B4B;;;;;;EAw9BzB,IAAA,CAAK,OAAA,GAAU,iBAAA,GAAoB,OAAA;EAt9BtB;;;;EA0+Bb,UAAA,CAAA,GAAc,OAAA;EA3tBhB;;;;;;;;;;;EA2xBE,YAAA,CAAa,EAAA,WAAa,OAAA;EA/FW;;;EAsGrC,UAAA,CAAA,GAAc,OAAA;EA3FC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAwJf,OAAA,CACJ,QAAA,WACA,OAAA,GAAU,oBAAA,CAAqB,gBAAA,IAC9B,OAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAiHG,UAAA,CACJ,aAAA,EAAe,MAAA,mBACf,OAAA,GAAU,uBAAA,CAAwB,gBAAA,IACjC,OAAA;;;;EA4DG,OAAA,CAAA,GAAW,OAAA;;;;;;;;;;;;;;;;EAyBjB,QAAA,CAAA;;;;;;EA4BA,SAAA,CAAA,GAAa,YAAA;;;;;;;;EAWb,eAAA,CACE,QAAA,GAAW,MAAA,EAAQ,YAAA;AAAA"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"controller.d.ts","names":[],"sources":["../../src/stream/controller.ts"],"mappings":";;;;;;;;;;;;;;;AA6KA;cAAa,kBAAA,WAA6B,OAAA;;;AAkC1C;;;;;;;;;;;cAAa,gBAAA,4BACgB,MAAA,8EAEO,MAAA;EAAA;WAEzB,SAAA,EAAW,WAAA,CAAY,YAAA,CAAa,SAAA,EAAW,aAAA;EAAA,SAC/C,aAAA,EAAe,WAAA,CAAY,WAAA;EAAA,SAC3B,aAAA,EAAe,WAAA,CAAY,WAAA;EAAA,SAC3B,mBAAA,EAAqB,WAAA,CAAY,iBAAA;EAAA,SACjC,oBAAA,EAAsB,WAAA,CAAY,kBAAA;EAAA,SAClC,UAAA,EAAY,WAAA,CAAY,uBAAA,CAAwB,SAAA;EAAA,SAChD,QAAA,EAAU,eAAA;EAAA;;;;;
|
|
1
|
+
{"version":3,"file":"controller.d.ts","names":[],"sources":["../../src/stream/controller.ts"],"mappings":";;;;;;;;;;;;;;;AA6KA;cAAa,kBAAA,WAA6B,OAAA;;;AAkC1C;;;;;;;;;;;cAAa,gBAAA,4BACgB,MAAA,8EAEO,MAAA;EAAA;WAEzB,SAAA,EAAW,WAAA,CAAY,YAAA,CAAa,SAAA,EAAW,aAAA;EAAA,SAC/C,aAAA,EAAe,WAAA,CAAY,WAAA;EAAA,SAC3B,aAAA,EAAe,WAAA,CAAY,WAAA;EAAA,SAC3B,mBAAA,EAAqB,WAAA,CAAY,iBAAA;EAAA,SACjC,oBAAA,EAAsB,WAAA,CAAY,kBAAA;EAAA,SAClC,UAAA,EAAY,WAAA,CAAY,uBAAA,CAAwB,SAAA;EAAA,SAChD,QAAA,EAAU,eAAA;EAAA;;;;;EAqJnB,WAAA,CAAY,OAAA,EAAS,uBAAA,CAAwB,SAAA;EAszBb;;;;;;;EAAA,IA5rB5B,gBAAA,CAAA,GAAoB,OAAA;EAkyBJ;;;;;;;;EAzuBd,OAAA,CAAQ,QAAA,mBAA2B,OAAA;EA8gC5B;;;;;;;;;;;;;;EAjpBP,wBAAA,CAAyB,UAAA,WAAqB,OAAA;EA1sB3C;;;;;;;;EA88BH,MAAA,CACJ,KAAA,WACA,OAAA,GAAU,mBAAA,CAAoB,SAAA,EAAW,gBAAA,IACxC,OAAA;EA98BM;;;;;;EAw9BH,IAAA,CAAK,OAAA,GAAU,iBAAA,GAAoB,OAAA;EAt9BhC;;;;EA0+BH,UAAA,CAAA,GAAc,OAAA;EAr1BR;;;;;;;;;;;EAq5BN,YAAA,CAAa,EAAA,WAAa,OAAA;EA/FA;;;EAsG1B,UAAA,CAAA,GAAc,OAAA;EA3Fd;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAwJA,OAAA,CACJ,QAAA,WACA,OAAA,GAAU,oBAAA,CAAqB,gBAAA,IAC9B,OAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAiHG,UAAA,CACJ,aAAA,EAAe,MAAA,mBACf,OAAA,GAAU,uBAAA,CAAwB,gBAAA,IACjC,OAAA;;;;EA4DG,OAAA,CAAA,GAAW,OAAA;;;;;;;;;;;;;;;;EAyBjB,QAAA,CAAA;;;;;;EA4BA,SAAA,CAAA,GAAa,YAAA;;;;;;;;EAWb,eAAA,CACE,QAAA,GAAW,MAAA,EAAQ,YAAA;AAAA"}
|
|
@@ -154,12 +154,25 @@ var StreamController = class {
|
|
|
154
154
|
* SSE replay re-adds historically-requested interrupts that have
|
|
155
155
|
* since been resolved (no `input.responded` event exists in the
|
|
156
156
|
* protocol, so the SDK has no other way to tell replay from live
|
|
157
|
-
* for an idle thread).
|
|
158
|
-
*
|
|
159
|
-
* cleared at the start of `submit()` for the same reason.
|
|
157
|
+
* for an idle thread). After a command is accepted, events newer
|
|
158
|
+
* than {@link #interruptReplayThroughSeq} bypass the allowlist.
|
|
160
159
|
*/
|
|
161
160
|
#hydratedActiveInterruptIds = null;
|
|
162
161
|
/**
|
|
162
|
+
* Highest event sequence already applied when the latest run command
|
|
163
|
+
* was accepted. Interrupts outside the hydrate-time allowlist remain
|
|
164
|
+
* filtered through this sequence, while newer events are live output
|
|
165
|
+
* from the newly-started run and must be accepted.
|
|
166
|
+
*/
|
|
167
|
+
#interruptReplayThroughSeq;
|
|
168
|
+
/**
|
|
169
|
+
* Unknown interrupt events received between local command dispatch and its
|
|
170
|
+
* response. The response supplies the sequence barrier needed to classify
|
|
171
|
+
* each event as historical replay or live output from the new run.
|
|
172
|
+
*/
|
|
173
|
+
#pendingInterruptEvents = [];
|
|
174
|
+
#interruptCommandPending = false;
|
|
175
|
+
/**
|
|
163
176
|
* Monotonic counter bumped at the start of each `submit()` and used
|
|
164
177
|
* by {@link hydrate} to skip its post-fetch allowlist write when a
|
|
165
178
|
* submit started while the state fetch was in flight. Without this
|
|
@@ -169,6 +182,14 @@ var StreamController = class {
|
|
|
169
182
|
*/
|
|
170
183
|
#submitGeneration = 0;
|
|
171
184
|
/**
|
|
185
|
+
* Monotonic counter bumped at the start of each `#teardownThread`.
|
|
186
|
+
* The root pump captures the generation when it starts and drops
|
|
187
|
+
* any event whose generation no longer matches — including queued
|
|
188
|
+
* events that `SubscriptionHandle.close()` still drains after the
|
|
189
|
+
* snapshot has already been cleared by `hydrate()`.
|
|
190
|
+
*/
|
|
191
|
+
#rootPumpGeneration = 0;
|
|
192
|
+
/**
|
|
172
193
|
* Thread ids this controller minted client-side on first `submit()`.
|
|
173
194
|
* `hydrate()` skips `threads.getState()` for these — we know there
|
|
174
195
|
* is nothing checkpointed yet. Cleared once dispatch commits the
|
|
@@ -293,13 +314,20 @@ var StreamController = class {
|
|
|
293
314
|
awaitNextTerminal: (signal) => this.#awaitNextTerminal(signal),
|
|
294
315
|
awaitResumedRunTerminal: (signal) => this.#awaitResumedRunTerminal(signal),
|
|
295
316
|
onSubmitStart: () => {
|
|
296
|
-
this.#hydratedActiveInterruptIds = null;
|
|
297
317
|
this.#submitGeneration += 1;
|
|
318
|
+
this.#interruptCommandPending = this.#hydratedActiveInterruptIds != null;
|
|
319
|
+
this.#pendingInterruptEvents = [];
|
|
298
320
|
},
|
|
299
321
|
onRunStart: () => this.#markLocalRunStart(),
|
|
300
|
-
onRunCreated: (runId) =>
|
|
322
|
+
onRunCreated: (runId) => {
|
|
323
|
+
this.#advanceInterruptReplayBarrier();
|
|
324
|
+
this.#notifyCreated(runId);
|
|
325
|
+
},
|
|
301
326
|
onRunCompleted: (reason, runId) => this.#notifyCompleted(reason, runId),
|
|
302
|
-
onRunEnd: () =>
|
|
327
|
+
onRunEnd: () => {
|
|
328
|
+
this.#interruptCommandPending = false;
|
|
329
|
+
this.#markLocalRunEnd();
|
|
330
|
+
},
|
|
303
331
|
beginOptimistic: (input) => this.#beginOptimistic(input),
|
|
304
332
|
settleOptimistic: (handle, event) => this.#settleOptimistic(handle, event)
|
|
305
333
|
});
|
|
@@ -391,13 +419,16 @@ var StreamController = class {
|
|
|
391
419
|
* Suspense boundary remounted against the new id suspends again.
|
|
392
420
|
*/
|
|
393
421
|
this.#resetHydrationPromise();
|
|
394
|
-
await this.#teardownThread();
|
|
395
422
|
/**
|
|
396
|
-
*
|
|
397
|
-
*
|
|
398
|
-
*
|
|
399
|
-
*
|
|
423
|
+
* Kick teardown so the synchronous abort (unbind, drop onEvent,
|
|
424
|
+
* close the root subscription, reset assemblers) runs before we
|
|
425
|
+
* touch the snapshot. Then reset immediately so the UI does not
|
|
426
|
+
* wait on pump/close. An interrupted thread parks the root pump
|
|
427
|
+
* on `waitForResume()`; awaiting teardown *before* this reset
|
|
428
|
+
* left `threadId` null while `messages` still showed the previous
|
|
429
|
+
* conversation (`useStream` fire-and-forgets `hydrate()`).
|
|
400
430
|
*/
|
|
431
|
+
const teardown = this.#teardownThread();
|
|
401
432
|
this.rootStore.setState(() => ({
|
|
402
433
|
...this.#createInitialSnapshot(),
|
|
403
434
|
threadId: this.#currentThreadId
|
|
@@ -408,6 +439,7 @@ var StreamController = class {
|
|
|
408
439
|
* surprising. Mirrors the legacy `StreamOrchestrator` behaviour.
|
|
409
440
|
*/
|
|
410
441
|
this.queueStore.setState(() => EMPTY_QUEUE);
|
|
442
|
+
await teardown;
|
|
411
443
|
}
|
|
412
444
|
if (this.#currentThreadId == null) {
|
|
413
445
|
this.rootStore.setState((s) => ({
|
|
@@ -549,7 +581,10 @@ var StreamController = class {
|
|
|
549
581
|
interrupts: activeInterrupts,
|
|
550
582
|
interrupt: activeInterrupts[0]
|
|
551
583
|
}));
|
|
552
|
-
if (this.#submitGeneration === generationAtFetch)
|
|
584
|
+
if (this.#submitGeneration === generationAtFetch) {
|
|
585
|
+
this.#hydratedActiveInterruptIds = activeIds;
|
|
586
|
+
this.#interruptReplayThroughSeq = void 0;
|
|
587
|
+
}
|
|
553
588
|
}
|
|
554
589
|
} catch (error) {
|
|
555
590
|
if (error?.status !== 404) {
|
|
@@ -996,9 +1031,11 @@ var StreamController = class {
|
|
|
996
1031
|
config: options?.config,
|
|
997
1032
|
metadata: options?.metadata
|
|
998
1033
|
});
|
|
1034
|
+
this.#advanceInterruptReplayBarrier();
|
|
999
1035
|
this.#markInterruptResolvedInRootStore(resolved.interruptId);
|
|
1000
1036
|
}, prepared?.handle);
|
|
1001
1037
|
} catch (error) {
|
|
1038
|
+
this.#discardPendingInterruptEvents();
|
|
1002
1039
|
if (this.#disposed && isAbortLikeError(error)) return;
|
|
1003
1040
|
throw error;
|
|
1004
1041
|
}
|
|
@@ -1065,9 +1102,11 @@ var StreamController = class {
|
|
|
1065
1102
|
config: options?.config,
|
|
1066
1103
|
metadata: options?.metadata
|
|
1067
1104
|
});
|
|
1105
|
+
this.#advanceInterruptReplayBarrier();
|
|
1068
1106
|
for (const { interrupt_id: interruptId } of responses) this.#markInterruptResolvedInRootStore(interruptId);
|
|
1069
1107
|
}, prepared?.handle);
|
|
1070
1108
|
} catch (error) {
|
|
1109
|
+
this.#discardPendingInterruptEvents();
|
|
1071
1110
|
if (this.#disposed && isAbortLikeError(error)) return;
|
|
1072
1111
|
throw error;
|
|
1073
1112
|
}
|
|
@@ -1235,6 +1274,14 @@ var StreamController = class {
|
|
|
1235
1274
|
* Close the current thread stream and reset per-thread assembly state.
|
|
1236
1275
|
*/
|
|
1237
1276
|
async #teardownThread() {
|
|
1277
|
+
/**
|
|
1278
|
+
* Invalidate the in-flight root pump before `close()` unparks it.
|
|
1279
|
+
* `SubscriptionHandle.close()` leaves queued events intact and the
|
|
1280
|
+
* iterator drains them before observing `closed`, so without this
|
|
1281
|
+
* bump a parked interrupted pump would still dispatch stale
|
|
1282
|
+
* `values` / `messages` into a snapshot `hydrate()` already cleared.
|
|
1283
|
+
*/
|
|
1284
|
+
this.#rootPumpGeneration += 1;
|
|
1238
1285
|
const thread = this.#thread;
|
|
1239
1286
|
this.#thread = void 0;
|
|
1240
1287
|
this.registry.bind(void 0);
|
|
@@ -1247,16 +1294,16 @@ var StreamController = class {
|
|
|
1247
1294
|
*/
|
|
1248
1295
|
this.#rootEventListeners.delete(this.#lifecycleLoading.listener);
|
|
1249
1296
|
this.#rootEventListeners.delete(this.#runLifecycleListener);
|
|
1250
|
-
|
|
1251
|
-
|
|
1252
|
-
|
|
1297
|
+
/**
|
|
1298
|
+
* Close first so a pump parked on `waitForResume()` (interrupted
|
|
1299
|
+
* run) unparks even if the unsubscribe RPC is slow. `close()` is
|
|
1300
|
+
* idempotent; `unsubscribe()` is then a no-op once closed.
|
|
1301
|
+
*/
|
|
1302
|
+
const subscription = this.#rootSubscription;
|
|
1253
1303
|
this.#rootSubscription = void 0;
|
|
1304
|
+
subscription?.close();
|
|
1254
1305
|
this.#rootPumpReady = void 0;
|
|
1255
1306
|
this.#rootPumpDeferred = false;
|
|
1256
|
-
try {
|
|
1257
|
-
await this.#rootPump;
|
|
1258
|
-
} catch {}
|
|
1259
|
-
this.#rootPump = void 0;
|
|
1260
1307
|
this.#rootMessages.reset();
|
|
1261
1308
|
this.#rootToolAssembler = new ToolCallAssembler();
|
|
1262
1309
|
this.#lifecycleLoading.reset();
|
|
@@ -1267,7 +1314,16 @@ var StreamController = class {
|
|
|
1267
1314
|
this.#localRunDepth = 0;
|
|
1268
1315
|
this.#messageMetadata.reset();
|
|
1269
1316
|
this.#hydratedActiveInterruptIds = null;
|
|
1317
|
+
this.#interruptReplayThroughSeq = void 0;
|
|
1318
|
+
this.#discardPendingInterruptEvents();
|
|
1270
1319
|
this.queueStore.setState(() => EMPTY_QUEUE);
|
|
1320
|
+
try {
|
|
1321
|
+
await subscription?.unsubscribe();
|
|
1322
|
+
} catch {}
|
|
1323
|
+
try {
|
|
1324
|
+
await this.#rootPump;
|
|
1325
|
+
} catch {}
|
|
1326
|
+
this.#rootPump = void 0;
|
|
1271
1327
|
if (thread != null) {
|
|
1272
1328
|
try {
|
|
1273
1329
|
await thread.close();
|
|
@@ -1291,6 +1347,7 @@ var StreamController = class {
|
|
|
1291
1347
|
*/
|
|
1292
1348
|
#startRootPump(thread) {
|
|
1293
1349
|
if (this.#rootPump != null) return;
|
|
1350
|
+
const pumpGeneration = this.#rootPumpGeneration;
|
|
1294
1351
|
let resolveReady;
|
|
1295
1352
|
this.#rootPumpReady = new Promise((resolve) => {
|
|
1296
1353
|
resolveReady = resolve;
|
|
@@ -1349,6 +1406,14 @@ var StreamController = class {
|
|
|
1349
1406
|
resolveReady = void 0;
|
|
1350
1407
|
});
|
|
1351
1408
|
const subscription = await subscriptionPromise;
|
|
1409
|
+
if (pumpGeneration !== this.#rootPumpGeneration) {
|
|
1410
|
+
resolveReady?.();
|
|
1411
|
+
resolveReady = void 0;
|
|
1412
|
+
try {
|
|
1413
|
+
subscription.close();
|
|
1414
|
+
} catch {}
|
|
1415
|
+
return;
|
|
1416
|
+
}
|
|
1352
1417
|
resolveReady?.();
|
|
1353
1418
|
resolveReady = void 0;
|
|
1354
1419
|
this.#rootSubscription = subscription;
|
|
@@ -1362,9 +1427,9 @@ var StreamController = class {
|
|
|
1362
1427
|
* for every resumed iteration until the subscription is
|
|
1363
1428
|
* permanently closed or the controller is disposed.
|
|
1364
1429
|
*/
|
|
1365
|
-
while (!this.#disposed) {
|
|
1430
|
+
while (!this.#disposed && pumpGeneration === this.#rootPumpGeneration) {
|
|
1366
1431
|
for await (const event of subscription) {
|
|
1367
|
-
if (this.#disposed) break;
|
|
1432
|
+
if (this.#disposed || pumpGeneration !== this.#rootPumpGeneration) break;
|
|
1368
1433
|
/**
|
|
1369
1434
|
* Resilience: isolate per-event dispatch from the pump loop.
|
|
1370
1435
|
*
|
|
@@ -1396,7 +1461,7 @@ var StreamController = class {
|
|
|
1396
1461
|
this.#onRootEvent(event);
|
|
1397
1462
|
} catch {}
|
|
1398
1463
|
}
|
|
1399
|
-
if (this.#disposed) break;
|
|
1464
|
+
if (this.#disposed || pumpGeneration !== this.#rootPumpGeneration) break;
|
|
1400
1465
|
if (!subscription.isPaused) break;
|
|
1401
1466
|
await subscription.waitForResume();
|
|
1402
1467
|
}
|
|
@@ -1664,7 +1729,13 @@ var StreamController = class {
|
|
|
1664
1729
|
const data = event.params.data;
|
|
1665
1730
|
const interruptId = data?.interrupt_id;
|
|
1666
1731
|
if (typeof interruptId !== "string" || this.#resolvedInterrupts.has(interruptId)) return;
|
|
1667
|
-
|
|
1732
|
+
const eventSeq = typeof event.seq === "number" ? event.seq : void 0;
|
|
1733
|
+
const isUnknownInterrupt = this.#hydratedActiveInterruptIds != null && !this.#hydratedActiveInterruptIds.has(interruptId);
|
|
1734
|
+
if (isUnknownInterrupt && this.#interruptCommandPending) {
|
|
1735
|
+
this.#pendingInterruptEvents.push(event);
|
|
1736
|
+
return;
|
|
1737
|
+
}
|
|
1738
|
+
if (isUnknownInterrupt && (this.#interruptReplayThroughSeq == null || eventSeq != null && eventSeq <= this.#interruptReplayThroughSeq)) return;
|
|
1668
1739
|
const namespace = Array.isArray(event.params.namespace) ? [...event.params.namespace] : [...ROOT_NAMESPACE];
|
|
1669
1740
|
const interrupt = normalizeInterruptForClient({
|
|
1670
1741
|
id: interruptId,
|
|
@@ -1682,6 +1753,31 @@ var StreamController = class {
|
|
|
1682
1753
|
});
|
|
1683
1754
|
}
|
|
1684
1755
|
/**
|
|
1756
|
+
* Convert the hydrate-time allowlist into a replay barrier after a command
|
|
1757
|
+
* is accepted. Built-in transports update `lastAppliedThroughSeq` from the
|
|
1758
|
+
* command response before resolving `submitRun` / `respondInput`.
|
|
1759
|
+
*/
|
|
1760
|
+
#advanceInterruptReplayBarrier() {
|
|
1761
|
+
if (this.#hydratedActiveInterruptIds == null) {
|
|
1762
|
+
this.#discardPendingInterruptEvents();
|
|
1763
|
+
return;
|
|
1764
|
+
}
|
|
1765
|
+
const throughSeq = this.#thread?.ordering?.lastAppliedThroughSeq;
|
|
1766
|
+
if (typeof throughSeq === "number") this.#interruptReplayThroughSeq = throughSeq;
|
|
1767
|
+
else {
|
|
1768
|
+
this.#hydratedActiveInterruptIds = null;
|
|
1769
|
+
this.#interruptReplayThroughSeq = void 0;
|
|
1770
|
+
}
|
|
1771
|
+
this.#interruptCommandPending = false;
|
|
1772
|
+
const pendingEvents = this.#pendingInterruptEvents;
|
|
1773
|
+
this.#pendingInterruptEvents = [];
|
|
1774
|
+
for (const event of pendingEvents) this.#recordInterrupt(event);
|
|
1775
|
+
}
|
|
1776
|
+
#discardPendingInterruptEvents() {
|
|
1777
|
+
this.#interruptCommandPending = false;
|
|
1778
|
+
this.#pendingInterruptEvents = [];
|
|
1779
|
+
}
|
|
1780
|
+
/**
|
|
1685
1781
|
* Resolve the protocol namespace for a targeted resume.
|
|
1686
1782
|
*
|
|
1687
1783
|
* Prefer an explicit caller-supplied namespace, then the matching
|