@langchain/langgraph-sdk 1.10.3-rc.0 → 1.10.3-rc.2

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.
@@ -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;EA+J0B;;;;;EAA7C,WAAA,CAAY,OAAA,EAAS,uBAAA,CAAwB,SAAA;EAgyBF;;;;;;;EAAA,IAtqBvC,gBAAA,CAAA,GAAoB,OAAA;EA20BS;;;;;;;;EAlxB3B,OAAA,CAAQ,QAAA,mBAA2B,OAAA;EAogCpB;;;;;;;;;;;;;;EA7pBf,wBAAA,CAAyB,UAAA,WAAqB,OAAA;EA9rB5B;;;;;;;;EAk8BlB,MAAA,CACJ,KAAA,WACA,OAAA,GAAU,mBAAA,CAAoB,SAAA,EAAW,gBAAA,IACxC,OAAA;EAl8B4B;;;;;;EA48BzB,IAAA,CAAK,OAAA,GAAU,iBAAA,GAAoB,OAAA;EA18BtB;;;;EA89Bb,UAAA,CAAA,GAAc,OAAA;EArsBhB;;;;;;;;;;;EAqwBE,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
+ {"version":3,"file":"controller.d.cts","names":[],"sources":["../../src/stream/controller.ts"],"mappings":";;;;;;;;;;;;;;AA6KA;;cAAa,kBAAA,WAA6B,OAAA;;AAwC1C;;;;;;;;;;;;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;EAiK0B;;;;;EAA7C,WAAA,CAAY,OAAA,EAAS,uBAAA,CAAwB,SAAA;EAiyBF;;;;;;;EAAA,IAtqBvC,gBAAA,CAAA,GAAoB,OAAA;EA20BS;;;;;;;;EAlxB3B,OAAA,CAAQ,QAAA,mBAA2B,OAAA;EAogCpB;;;;;;;;;;;;;;EA7pBf,wBAAA,CAAyB,UAAA,WAAqB,OAAA;EAjsB5B;;;;;;;;EAq8BlB,MAAA,CACJ,KAAA,WACA,OAAA,GAAU,mBAAA,CAAoB,SAAA,EAAW,gBAAA,IACxC,OAAA;EAr8B4B;;;;;;EA+8BzB,IAAA,CAAK,OAAA,GAAU,iBAAA,GAAoB,OAAA;EA78BtB;;;;EAi+Bb,UAAA,CAAA,GAAc,OAAA;EArsBhB;;;;;;;;;;;EAqwBE,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;;;;;EA+JnB,WAAA,CAAY,OAAA,EAAS,uBAAA,CAAwB,SAAA;EAgyBb;;;;;;;EAAA,IAtqB5B,gBAAA,CAAA,GAAoB,OAAA;EA4wBJ;;;;;;;;EAntBd,OAAA,CAAQ,QAAA,mBAA2B,OAAA;EAw/B5B;;;;;;;;;;;;;;EAjpBP,wBAAA,CAAyB,UAAA,WAAqB,OAAA;EA9rB3C;;;;;;;;EAk8BH,MAAA,CACJ,KAAA,WACA,OAAA,GAAU,mBAAA,CAAoB,SAAA,EAAW,gBAAA,IACxC,OAAA;EAl8BM;;;;;;EA48BH,IAAA,CAAK,OAAA,GAAU,iBAAA,GAAoB,OAAA;EA18BhC;;;;EA89BH,UAAA,CAAA,GAAc,OAAA;EA/zBR;;;;;;;;;;;EA+3BN,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"}
1
+ {"version":3,"file":"controller.d.ts","names":[],"sources":["../../src/stream/controller.ts"],"mappings":";;;;;;;;;;;;;;;AA6KA;cAAa,kBAAA,WAA6B,OAAA;;;AAwC1C;;;;;;;;;;;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;;;;;EAiKnB,WAAA,CAAY,OAAA,EAAS,uBAAA,CAAwB,SAAA;EAiyBb;;;;;;;EAAA,IAtqB5B,gBAAA,CAAA,GAAoB,OAAA;EA4wBJ;;;;;;;;EAntBd,OAAA,CAAQ,QAAA,mBAA2B,OAAA;EAw/B5B;;;;;;;;;;;;;;EAjpBP,wBAAA,CAAyB,UAAA,WAAqB,OAAA;EAjsB3C;;;;;;;;EAq8BH,MAAA,CACJ,KAAA,WACA,OAAA,GAAU,mBAAA,CAAoB,SAAA,EAAW,gBAAA,IACxC,OAAA;EAr8BM;;;;;;EA+8BH,IAAA,CAAK,OAAA,GAAU,iBAAA,GAAoB,OAAA;EA78BhC;;;;EAi+BH,UAAA,CAAA,GAAc,OAAA;EAh0BR;;;;;;;;;;;EAg4BN,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"}
@@ -104,6 +104,8 @@ const ROOT_PUMP_CHANNELS = [
104
104
  "messages",
105
105
  "tools"
106
106
  ];
107
+ const PARKED_INTERRUPT_SETTLE_MS = 5e3;
108
+ const PARKED_INTERRUPT_SETTLE_POLL_MS = 500;
107
109
  /**
108
110
  * Coordinates one thread's protocol-v2 stream and exposes stable
109
111
  * observable projections for framework bindings.
@@ -142,17 +144,16 @@ var StreamController = class {
142
144
  */
143
145
  #rootPumpDeferred = false;
144
146
  #threadEventUnsubscribe;
147
+ #threadErrorUnsubscribe;
145
148
  #disposed = false;
146
149
  #pendingDisposeTimer = null;
147
150
  /**
148
151
  * Interrupt ids this controller has locally marked resolved via
149
152
  * {@link respond} / {@link respondAll}. Used only to suppress
150
153
  * *historical* SSE replay of those `input.requested` events (there
151
- * is no `input.responded` protocol event). Live events after the
152
- * resume barrier — or a post-resume reconcile against
153
- * `state.tasks[].interrupts` — clear an id from this set so a
154
- * still-pending server interrupt can reappear on
155
- * `rootStore.interrupts`.
154
+ * is no `input.responded` protocol event). A live event after the
155
+ * resume barrier clears an id from this set so an interrupt raised
156
+ * again by a later run can reappear on `rootStore.interrupts`.
156
157
  */
157
158
  #resolvedInterrupts = /* @__PURE__ */ new Set();
158
159
  /**
@@ -175,6 +176,9 @@ var StreamController = class {
175
176
  * from the newly-started run and must be accepted.
176
177
  */
177
178
  #interruptReplayThroughSeq;
179
+ /** Unknown inputs waiting to be classified as live or replayed history. */
180
+ #pendingHydrationInterruptEvents = [];
181
+ #settleParkedInterruptsPromise;
178
182
  /**
179
183
  * Unknown interrupt events received between local command dispatch and its
180
184
  * response. The response supplies the sequence barrier needed to classify
@@ -326,7 +330,8 @@ var StreamController = class {
326
330
  onSubmitStart: () => {
327
331
  this.#submitGeneration += 1;
328
332
  this.#interruptCommandPending = this.#hydratedActiveInterruptIds != null;
329
- this.#pendingInterruptEvents = [];
333
+ this.#pendingInterruptEvents = this.#pendingHydrationInterruptEvents;
334
+ this.#pendingHydrationInterruptEvents = [];
330
335
  },
331
336
  onRunStart: () => this.#markLocalRunStart(),
332
337
  onRunCreated: (runId) => {
@@ -1281,6 +1286,8 @@ var StreamController = class {
1281
1286
  this.registry.bind(void 0);
1282
1287
  this.#threadEventUnsubscribe?.();
1283
1288
  this.#threadEventUnsubscribe = void 0;
1289
+ this.#threadErrorUnsubscribe?.();
1290
+ this.#threadErrorUnsubscribe = void 0;
1284
1291
  /**
1285
1292
  * Persistent lifecycle driver is scoped to the current thread
1286
1293
  * stream. Remove it so a swap to a new thread starts with a clean
@@ -1309,6 +1316,7 @@ var StreamController = class {
1309
1316
  this.#messageMetadata.reset();
1310
1317
  this.#hydratedActiveInterruptIds = null;
1311
1318
  this.#interruptReplayThroughSeq = void 0;
1319
+ this.#pendingHydrationInterruptEvents = [];
1312
1320
  this.#discardPendingInterruptEvents();
1313
1321
  this.queueStore.setState(() => EMPTY_QUEUE);
1314
1322
  try {
@@ -1355,6 +1363,13 @@ var StreamController = class {
1355
1363
  * pump's narrow filter.
1356
1364
  */
1357
1365
  this.#threadEventUnsubscribe = thread.onEvent((event) => this.#onWildcardEvent(event));
1366
+ this.#threadErrorUnsubscribe = thread.onError((error) => {
1367
+ this.rootStore.setState((s) => ({
1368
+ ...s,
1369
+ error,
1370
+ isLoading: false
1371
+ }));
1372
+ });
1358
1373
  /**
1359
1374
  * Persistent isLoading driver. Drives `isLoading` from
1360
1375
  * root-namespace lifecycle events so that in-flight runs observed
@@ -1493,6 +1508,7 @@ var StreamController = class {
1493
1508
  * resume targeting.
1494
1509
  */
1495
1510
  this.#recordInterrupt(event);
1511
+ this.#settleParkedInterruptsOnTerminal(event);
1496
1512
  }
1497
1513
  /**
1498
1514
  * Process one root-pump event and update all root projections.
@@ -1733,7 +1749,12 @@ var StreamController = class {
1733
1749
  this.#pendingInterruptEvents.push(event);
1734
1750
  return;
1735
1751
  }
1736
- if (isUnknownInterrupt && (this.#interruptReplayThroughSeq == null || eventSeq != null && eventSeq <= this.#interruptReplayThroughSeq)) return;
1752
+ const barrier = this.#interruptReplayThroughSeq;
1753
+ if (isUnknownInterrupt && barrier == null) {
1754
+ this.#pendingHydrationInterruptEvents.push(event);
1755
+ return;
1756
+ }
1757
+ if (isUnknownInterrupt && barrier != null && eventSeq != null && eventSeq <= barrier) return;
1737
1758
  const namespace = Array.isArray(event.params.namespace) ? [...event.params.namespace] : [...ROOT_NAMESPACE];
1738
1759
  const interrupt = normalizeInterruptForClient({
1739
1760
  id: interruptId,
@@ -1795,8 +1816,7 @@ var StreamController = class {
1795
1816
  * mirror the removal into the root snapshot the framework hooks read.
1796
1817
  *
1797
1818
  * Tombstones are not permanent: a live `input.requested` after the
1798
- * resume barrier, or {@link #reconcilePendingInterruptsFromServer},
1799
- * clears the id when the server still reports it as pending.
1819
+ * resume barrier clears the id when the same interrupt is raised again.
1800
1820
  */
1801
1821
  #markInterruptResolvedInRootStore(interruptId) {
1802
1822
  this.#resolvedInterrupts.add(interruptId);
@@ -1815,10 +1835,11 @@ var StreamController = class {
1815
1835
  * `state.tasks[].interrupts` after a resumed run settles.
1816
1836
  *
1817
1837
  * Sequential `respond()` of parallel interrupts optimistically clears
1818
- * each id client-side. When the server still has siblings pending and
1819
- * does not re-emit `input.requested` for them (session map already
1820
- * holds the id), this restore keeps `stream.interrupts` truthful so
1821
- * callers do not free-text `submit()` into an ambiguous resume.
1838
+ * each targeted id client-side. The server checkpoint can continue to
1839
+ * list the original interrupt batch after accepting a partial response,
1840
+ * so locally-resolved ids remain filtered while untouched siblings are
1841
+ * restored. This keeps `stream.interrupts` truthful without re-exposing
1842
+ * an already-consumed interrupt.
1822
1843
  *
1823
1844
  * Uses the same transport-aware state fetch as {@link hydrate}, and
1824
1845
  * drops the result if the thread swapped or a new submit/respond
@@ -1826,21 +1847,69 @@ var StreamController = class {
1826
1847
  */
1827
1848
  async #reconcilePendingInterruptsFromServer() {
1828
1849
  const threadId = this.#currentThreadId;
1829
- if (threadId == null || this.#disposed) return;
1850
+ if (threadId == null || this.#disposed) return null;
1830
1851
  const generationAtFetch = this.#submitGeneration;
1831
1852
  try {
1832
1853
  const state = await this.#fetchHydrationState();
1833
- if (this.#disposed || this.#currentThreadId !== threadId || this.#submitGeneration !== generationAtFetch) return;
1834
- if (!Array.isArray(state?.tasks)) return;
1854
+ if (this.#disposed || this.#currentThreadId !== threadId || this.#submitGeneration !== generationAtFetch) return null;
1855
+ if (!Array.isArray(state?.tasks)) return null;
1835
1856
  const { activeInterrupts, activeIds } = collectActiveInterruptsFromTasks(state.tasks);
1836
- for (const id of activeIds) this.#resolvedInterrupts.delete(id);
1857
+ const pendingInterrupts = activeInterrupts.filter((interrupt) => interrupt.id == null || !this.#resolvedInterrupts.has(interrupt.id));
1837
1858
  this.rootStore.setState((s) => ({
1838
1859
  ...s,
1839
- interrupts: activeInterrupts,
1840
- interrupt: activeInterrupts[0]
1860
+ interrupts: pendingInterrupts,
1861
+ interrupt: pendingInterrupts[0]
1841
1862
  }));
1842
1863
  this.#hydratedActiveInterruptIds = activeIds;
1843
- } catch {}
1864
+ return state;
1865
+ } catch {
1866
+ return null;
1867
+ }
1868
+ }
1869
+ #settleParkedInterruptsOnTerminal(event) {
1870
+ if (this.#pendingHydrationInterruptEvents.length === 0) return;
1871
+ if (event.method !== "lifecycle") return;
1872
+ if (!isRootNamespace(event.params.namespace)) return;
1873
+ const status = event.params.data?.event;
1874
+ if (status !== "interrupted" && status !== "completed" && status !== "failed") return;
1875
+ this.#settleParkedInterrupts();
1876
+ }
1877
+ /**
1878
+ * Decide parked interrupts with server state instead of a stream marker.
1879
+ *
1880
+ * After a passive rejoin the stream cannot tell a replayed, already
1881
+ * resolved `input.requested` from one the current run just raised: the
1882
+ * SSE replays the thread buffer on connect with no marker for where the
1883
+ * replay ends. `state.tasks[].interrupts` is authoritative: parked ids it
1884
+ * lists are live, the rest are history.
1885
+ */
1886
+ async #settleParkedInterrupts() {
1887
+ const makePromise = async () => {
1888
+ try {
1889
+ const threadId = this.#currentThreadId;
1890
+ const generation = this.#submitGeneration;
1891
+ const deadline = Date.now() + PARKED_INTERRUPT_SETTLE_MS;
1892
+ for (;;) {
1893
+ if (this.#disposed || this.#currentThreadId !== threadId || this.#submitGeneration !== generation || this.#pendingHydrationInterruptEvents.length === 0) return;
1894
+ const parkedIds = new Set(this.#pendingHydrationInterruptEvents.map((event) => event.params.data.interrupt_id));
1895
+ const state = await this.#reconcilePendingInterruptsFromServer();
1896
+ if (state != null) {
1897
+ if ([...this.#hydratedActiveInterruptIds ?? []].some((id) => parkedIds.has(id)) || !isThreadStateActive(state)) {
1898
+ this.#pendingHydrationInterruptEvents = [];
1899
+ return;
1900
+ }
1901
+ }
1902
+ if (Date.now() >= deadline) return;
1903
+ await new Promise((resolve) => {
1904
+ setTimeout(resolve, PARKED_INTERRUPT_SETTLE_POLL_MS);
1905
+ });
1906
+ }
1907
+ } finally {
1908
+ this.#settleParkedInterruptsPromise = void 0;
1909
+ }
1910
+ };
1911
+ this.#settleParkedInterruptsPromise ??= makePromise();
1912
+ return this.#settleParkedInterruptsPromise;
1844
1913
  }
1845
1914
  /**
1846
1915
  * Resolve on the next root-namespace terminal lifecycle event
@@ -1886,6 +1955,7 @@ var StreamController = class {
1886
1955
  settled = true;
1887
1956
  unsubscribeRoot?.();
1888
1957
  unsubscribeThread?.();
1958
+ unsubscribeError?.();
1889
1959
  signal.removeEventListener("abort", finishAborted);
1890
1960
  resolve(result);
1891
1961
  }
@@ -1911,6 +1981,10 @@ var StreamController = class {
1911
1981
  };
1912
1982
  const unsubscribeRoot = this.#rootBus.subscribe(onEvent);
1913
1983
  const unsubscribeThread = this.#thread?.onEvent(onEvent);
1984
+ const unsubscribeError = this.#thread?.onError((error) => finish({
1985
+ event: "failed",
1986
+ error: error.message
1987
+ }));
1914
1988
  if (signal.aborted) finishAborted();
1915
1989
  else signal.addEventListener("abort", finishAborted, { once: true });
1916
1990
  });