@rivetkit/workflow-engine 0.0.0-main.6151ab0 → 0.0.0-main.79e97f1

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.
@@ -446,6 +446,23 @@ export function writeRemovedEntry(bc: bare.ByteCursor, x: RemovedEntry): void {
446
446
  write1(bc, x.originalName)
447
447
  }
448
448
 
449
+ export type VersionCheckEntry = {
450
+ readonly resolved: u32,
451
+ readonly latest: u32,
452
+ }
453
+
454
+ export function readVersionCheckEntry(bc: bare.ByteCursor): VersionCheckEntry {
455
+ return {
456
+ resolved: bare.readU32(bc),
457
+ latest: bare.readU32(bc),
458
+ }
459
+ }
460
+
461
+ export function writeVersionCheckEntry(bc: bare.ByteCursor, x: VersionCheckEntry): void {
462
+ bare.writeU32(bc, x.resolved)
463
+ bare.writeU32(bc, x.latest)
464
+ }
465
+
449
466
  export type EntryKind =
450
467
  | { readonly tag: "StepEntry", readonly val: StepEntry }
451
468
  | { readonly tag: "LoopEntry", readonly val: LoopEntry }
@@ -455,6 +472,7 @@ export type EntryKind =
455
472
  | { readonly tag: "JoinEntry", readonly val: JoinEntry }
456
473
  | { readonly tag: "RaceEntry", readonly val: RaceEntry }
457
474
  | { readonly tag: "RemovedEntry", readonly val: RemovedEntry }
475
+ | { readonly tag: "VersionCheckEntry", readonly val: VersionCheckEntry }
458
476
 
459
477
  export function readEntryKind(bc: bare.ByteCursor): EntryKind {
460
478
  const offset = bc.offset
@@ -476,6 +494,8 @@ export function readEntryKind(bc: bare.ByteCursor): EntryKind {
476
494
  return { tag: "RaceEntry", val: readRaceEntry(bc) }
477
495
  case 7:
478
496
  return { tag: "RemovedEntry", val: readRemovedEntry(bc) }
497
+ case 8:
498
+ return { tag: "VersionCheckEntry", val: readVersionCheckEntry(bc) }
479
499
  default: {
480
500
  bc.offset = offset
481
501
  throw new bare.BareError(offset, "invalid tag")
@@ -525,6 +545,11 @@ export function writeEntryKind(bc: bare.ByteCursor, x: EntryKind): void {
525
545
  writeRemovedEntry(bc, x.val)
526
546
  break
527
547
  }
548
+ case "VersionCheckEntry": {
549
+ bare.writeU8(bc, 8)
550
+ writeVersionCheckEntry(bc, x.val)
551
+ break
552
+ }
528
553
  }
529
554
  }
530
555
 
@@ -670,6 +670,16 @@ function writeRemovedEntry(bc, x) {
670
670
  bare.writeString(bc, x.originalType);
671
671
  write1(bc, x.originalName);
672
672
  }
673
+ function readVersionCheckEntry(bc) {
674
+ return {
675
+ resolved: bare.readU32(bc),
676
+ latest: bare.readU32(bc)
677
+ };
678
+ }
679
+ function writeVersionCheckEntry(bc, x) {
680
+ bare.writeU32(bc, x.resolved);
681
+ bare.writeU32(bc, x.latest);
682
+ }
673
683
  function readEntryKind(bc) {
674
684
  const offset = bc.offset;
675
685
  const tag = bare.readU8(bc);
@@ -690,6 +700,8 @@ function readEntryKind(bc) {
690
700
  return { tag: "RaceEntry", val: readRaceEntry(bc) };
691
701
  case 7:
692
702
  return { tag: "RemovedEntry", val: readRemovedEntry(bc) };
703
+ case 8:
704
+ return { tag: "VersionCheckEntry", val: readVersionCheckEntry(bc) };
693
705
  default: {
694
706
  bc.offset = offset;
695
707
  throw new bare.BareError(offset, "invalid tag");
@@ -738,6 +750,11 @@ function writeEntryKind(bc, x) {
738
750
  writeRemovedEntry(bc, x.val);
739
751
  break;
740
752
  }
753
+ case "VersionCheckEntry": {
754
+ bare.writeU8(bc, 8);
755
+ writeVersionCheckEntry(bc, x.val);
756
+ break;
757
+ }
741
758
  }
742
759
  }
743
760
  function readEntry(bc) {
@@ -1182,6 +1199,14 @@ function entryKindToBare(kind) {
1182
1199
  originalName: kind.data.originalName ?? null
1183
1200
  }
1184
1201
  };
1202
+ case "version_check":
1203
+ return {
1204
+ tag: "VersionCheckEntry",
1205
+ val: {
1206
+ resolved: kind.data.resolved,
1207
+ latest: kind.data.latest
1208
+ }
1209
+ };
1185
1210
  }
1186
1211
  }
1187
1212
  function entryKindFromBare(kind) {
@@ -1263,6 +1288,14 @@ function entryKindFromBare(kind) {
1263
1288
  originalName: kind.val.originalName ?? void 0
1264
1289
  }
1265
1290
  };
1291
+ case "VersionCheckEntry":
1292
+ return {
1293
+ type: "version_check",
1294
+ data: {
1295
+ resolved: kind.val.resolved,
1296
+ latest: kind.val.latest
1297
+ }
1298
+ };
1266
1299
  default:
1267
1300
  throw new Error(
1268
1301
  `Unknown entry kind: ${kind.tag}`
@@ -1402,6 +1435,8 @@ function deserializeName(bytes) {
1402
1435
  }
1403
1436
 
1404
1437
  // src/storage.ts
1438
+ var MAX_KV_BATCH_ENTRIES = 128;
1439
+ var MAX_KV_BATCH_PAYLOAD_BYTES = 976 * 1024;
1405
1440
  function createStorage() {
1406
1441
  return {
1407
1442
  nameRegistry: [],
@@ -1519,6 +1554,8 @@ async function loadMetadata(storage, driver, entryId) {
1519
1554
  }
1520
1555
  async function flush(storage, driver, onHistoryUpdated, pendingDeletions) {
1521
1556
  const writes = [];
1557
+ const dirtyEntries = [];
1558
+ const dirtyMetadata = [];
1522
1559
  let historyUpdated = false;
1523
1560
  for (let i = storage.flushedNameCount; i < storage.nameRegistry.length; i++) {
1524
1561
  const name = storage.nameRegistry[i];
@@ -1536,7 +1573,7 @@ async function flush(storage, driver, onHistoryUpdated, pendingDeletions) {
1536
1573
  key: buildHistoryKey(entry.location),
1537
1574
  value: serializeEntry(entry)
1538
1575
  });
1539
- entry.dirty = false;
1576
+ dirtyEntries.push(entry);
1540
1577
  historyUpdated = true;
1541
1578
  }
1542
1579
  }
@@ -1546,7 +1583,7 @@ async function flush(storage, driver, onHistoryUpdated, pendingDeletions) {
1546
1583
  key: buildEntryMetadataKey(id),
1547
1584
  value: serializeEntryMetadata(metadata)
1548
1585
  });
1549
- metadata.dirty = false;
1586
+ dirtyMetadata.push(metadata);
1550
1587
  historyUpdated = true;
1551
1588
  }
1552
1589
  }
@@ -1570,7 +1607,13 @@ async function flush(storage, driver, onHistoryUpdated, pendingDeletions) {
1570
1607
  });
1571
1608
  }
1572
1609
  if (writes.length > 0) {
1573
- await driver.batch(writes);
1610
+ if (driver.atomicBatch) {
1611
+ await driver.batch(writes);
1612
+ } else {
1613
+ for (const chunk of splitBatchWrites(writes)) {
1614
+ await driver.batch(chunk);
1615
+ }
1616
+ }
1574
1617
  }
1575
1618
  if (pendingDeletions) {
1576
1619
  const deleteOps = [];
@@ -1588,6 +1631,12 @@ async function flush(storage, driver, onHistoryUpdated, pendingDeletions) {
1588
1631
  historyUpdated = true;
1589
1632
  }
1590
1633
  }
1634
+ for (const entry of dirtyEntries) {
1635
+ entry.dirty = false;
1636
+ }
1637
+ for (const metadata of dirtyMetadata) {
1638
+ metadata.dirty = false;
1639
+ }
1591
1640
  storage.flushedNameCount = storage.nameRegistry.length;
1592
1641
  storage.flushedState = storage.state;
1593
1642
  storage.flushedOutput = storage.output;
@@ -1596,6 +1645,30 @@ async function flush(storage, driver, onHistoryUpdated, pendingDeletions) {
1596
1645
  onHistoryUpdated();
1597
1646
  }
1598
1647
  }
1648
+ function splitBatchWrites(writes) {
1649
+ const chunks = [];
1650
+ let chunk = [];
1651
+ let chunkBytes = 0;
1652
+ for (const write of writes) {
1653
+ const writeBytes = write.key.byteLength + write.value.byteLength;
1654
+ if (writeBytes > MAX_KV_BATCH_PAYLOAD_BYTES) {
1655
+ throw new Error(
1656
+ `KV batch write is ${writeBytes} bytes, exceeding the ${MAX_KV_BATCH_PAYLOAD_BYTES} byte limit`
1657
+ );
1658
+ }
1659
+ if (chunk.length >= MAX_KV_BATCH_ENTRIES || chunk.length > 0 && chunkBytes + writeBytes > MAX_KV_BATCH_PAYLOAD_BYTES) {
1660
+ chunks.push(chunk);
1661
+ chunk = [];
1662
+ chunkBytes = 0;
1663
+ }
1664
+ chunk.push(write);
1665
+ chunkBytes += writeBytes;
1666
+ }
1667
+ if (chunk.length > 0) {
1668
+ chunks.push(chunk);
1669
+ }
1670
+ return chunks;
1671
+ }
1599
1672
  async function deleteEntriesWithPrefix(storage, driver, prefixLocation, onHistoryUpdated) {
1600
1673
  const deletions = collectDeletionsForPrefix(storage, prefixLocation);
1601
1674
  await driver.deletePrefix(deletions.prefixes[0]);
@@ -1628,30 +1701,6 @@ function setEntry(storage, location, entry) {
1628
1701
  storage.history.entries.set(key, entry);
1629
1702
  }
1630
1703
 
1631
- // src/utils.ts
1632
- function sleep(ms) {
1633
- return new Promise((resolve) => setTimeout(resolve, ms));
1634
- }
1635
- var TIMEOUT_MAX = 2147483647;
1636
- function setLongTimeout(listener, after) {
1637
- let timeout;
1638
- function start(remaining) {
1639
- if (remaining <= TIMEOUT_MAX) {
1640
- timeout = setTimeout(listener, remaining);
1641
- } else {
1642
- timeout = setTimeout(() => {
1643
- start(remaining - TIMEOUT_MAX);
1644
- }, TIMEOUT_MAX);
1645
- }
1646
- }
1647
- start(after);
1648
- return {
1649
- abort: () => {
1650
- if (timeout !== void 0) clearTimeout(timeout);
1651
- }
1652
- };
1653
- }
1654
-
1655
1704
  // src/context.ts
1656
1705
  var DEFAULT_MAX_RETRIES = 3;
1657
1706
  var DEFAULT_RETRY_BACKOFF_BASE = 100;
@@ -1927,7 +1976,7 @@ var WorkflowContextImpl = class _WorkflowContextImpl {
1927
1976
  * Throws HistoryDivergedError if duplicate detected.
1928
1977
  */
1929
1978
  checkDuplicateName(name) {
1930
- const fullKey = locationToKey(this.storage, this.currentLocation) + "/" + name;
1979
+ const fullKey = `${locationToKey(this.storage, this.currentLocation)}/${name}`;
1931
1980
  if (this.usedNamesInExecution.has(fullKey)) {
1932
1981
  throw new HistoryDivergedError(
1933
1982
  `Duplicate entry name "${name}" at location "${locationToKey(this.storage, this.currentLocation)}". Each step/loop/sleep/queue.next/join/race must have a unique name within its scope.`
@@ -1981,7 +2030,7 @@ var WorkflowContextImpl = class _WorkflowContextImpl {
1981
2030
  validateComplete() {
1982
2031
  const prefix = locationToKey(this.storage, this.currentLocation);
1983
2032
  for (const key of this.storage.history.entries.keys()) {
1984
- const isUnderPrefix = prefix === "" ? true : key.startsWith(prefix + "/") || key === prefix;
2033
+ const isUnderPrefix = prefix === "" ? true : key.startsWith(`${prefix}/`) || key === prefix;
1985
2034
  if (isUnderPrefix) {
1986
2035
  if (!this.visitedKeys.has(key)) {
1987
2036
  throw new HistoryDivergedError(
@@ -1998,25 +2047,33 @@ var WorkflowContextImpl = class _WorkflowContextImpl {
1998
2047
  this.abortController.abort(new EvictedError());
1999
2048
  }
2000
2049
  /**
2001
- * Wait for eviction message.
2002
- *
2003
- * The event listener uses { once: true } to auto-remove after firing,
2004
- * preventing memory leaks if this method is called multiple times.
2050
+ * Wait for `ms`, rejecting early with EvictedError if the workflow is
2051
+ * evicted. Both the timer and the abort listener are torn down on either
2052
+ * outcome, so a completed sleep never leaves a dangling listener on the
2053
+ * long-lived run abort signal.
2005
2054
  */
2006
- waitForEviction() {
2007
- return new Promise((_, reject) => {
2008
- if (this.abortSignal.aborted) {
2009
- reject(new EvictedError());
2010
- return;
2055
+ async sleepOrEvict(ms) {
2056
+ if (this.abortSignal.aborted) {
2057
+ throw new EvictedError();
2058
+ }
2059
+ let timer;
2060
+ let onAbort;
2061
+ try {
2062
+ await new Promise((resolve, reject) => {
2063
+ timer = setTimeout(resolve, ms);
2064
+ onAbort = () => reject(new EvictedError());
2065
+ this.abortSignal.addEventListener("abort", onAbort, {
2066
+ once: true
2067
+ });
2068
+ });
2069
+ } finally {
2070
+ if (timer !== void 0) {
2071
+ clearTimeout(timer);
2011
2072
  }
2012
- this.abortSignal.addEventListener(
2013
- "abort",
2014
- () => {
2015
- reject(new EvictedError());
2016
- },
2017
- { once: true }
2018
- );
2019
- });
2073
+ if (onAbort) {
2074
+ this.abortSignal.removeEventListener("abort", onAbort);
2075
+ }
2076
+ }
2020
2077
  }
2021
2078
  // === Step ===
2022
2079
  async step(nameOrConfig, run) {
@@ -2165,7 +2222,7 @@ var WorkflowContextImpl = class _WorkflowContextImpl {
2165
2222
  }
2166
2223
  const maxRetries2 = config2.maxRetries ?? DEFAULT_MAX_RETRIES;
2167
2224
  if (metadata2.attempts > maxRetries2) {
2168
- const lastError = stepData.error ?? metadata2.error;
2225
+ const lastError = metadata2.error;
2169
2226
  const exhaustedError = new StepExhaustedError(
2170
2227
  config2.name,
2171
2228
  lastError
@@ -2254,37 +2311,28 @@ var WorkflowContextImpl = class _WorkflowContextImpl {
2254
2311
  });
2255
2312
  return output;
2256
2313
  } catch (error) {
2257
- if (error instanceof StepTimeoutError) {
2258
- if (entry.kind.type === "step") {
2259
- entry.kind.data.error = String(error);
2260
- }
2261
- entry.dirty = true;
2314
+ if (entry.kind.type === "step") {
2315
+ entry.kind.data.error = String(error);
2316
+ }
2317
+ entry.dirty = true;
2318
+ if (error instanceof StepTimeoutError && !config2.retryOnTimeout) {
2262
2319
  metadata.status = "exhausted";
2263
2320
  metadata.error = String(error);
2264
- await this.flushStorage();
2265
2321
  await this.notifyStepError(config2, metadata.attempts, error, {
2266
2322
  willRetry: false
2267
2323
  });
2268
2324
  throw markErrorReported(
2269
- attachTryStepFailure(
2270
- new CriticalError(error.message),
2271
- {
2272
- kind: "timeout",
2273
- stepName: config2.name,
2274
- attempts: metadata.attempts,
2275
- error: extractErrorInfo(error)
2276
- }
2277
- )
2325
+ attachTryStepFailure(new CriticalError(error.message), {
2326
+ kind: "timeout",
2327
+ stepName: config2.name,
2328
+ attempts: metadata.attempts,
2329
+ error: extractErrorInfo(error)
2330
+ })
2278
2331
  );
2279
2332
  }
2280
2333
  if (error instanceof CriticalError || error instanceof RollbackError) {
2281
- if (entry.kind.type === "step") {
2282
- entry.kind.data.error = String(error);
2283
- }
2284
- entry.dirty = true;
2285
2334
  metadata.status = "exhausted";
2286
2335
  metadata.error = String(error);
2287
- await this.flushStorage();
2288
2336
  await this.notifyStepError(config2, metadata.attempts, error, {
2289
2337
  willRetry: false
2290
2338
  });
@@ -2297,14 +2345,9 @@ var WorkflowContextImpl = class _WorkflowContextImpl {
2297
2345
  })
2298
2346
  );
2299
2347
  }
2300
- if (entry.kind.type === "step") {
2301
- entry.kind.data.error = String(error);
2302
- }
2303
- entry.dirty = true;
2304
2348
  const willRetry = metadata.attempts <= maxRetries;
2305
2349
  metadata.status = willRetry ? "failed" : "exhausted";
2306
2350
  metadata.error = String(error);
2307
- await this.flushStorage();
2308
2351
  if (willRetry) {
2309
2352
  const retryDelay = calculateBackoff(
2310
2353
  metadata.attempts,
@@ -2328,7 +2371,7 @@ var WorkflowContextImpl = class _WorkflowContextImpl {
2328
2371
  attachTryStepFailure(
2329
2372
  new StepExhaustedError(config2.name, String(error)),
2330
2373
  {
2331
- kind: "exhausted",
2374
+ kind: error instanceof StepTimeoutError ? "timeout" : "exhausted",
2332
2375
  stepName: config2.name,
2333
2376
  attempts: metadata.attempts,
2334
2377
  error: extractErrorInfo(error)
@@ -2346,7 +2389,9 @@ var WorkflowContextImpl = class _WorkflowContextImpl {
2346
2389
  *
2347
2390
  * Note: This does NOT cancel the underlying operation. JavaScript Promises
2348
2391
  * cannot be cancelled once started. When a timeout occurs:
2349
- * - The step is marked as failed with StepTimeoutError
2392
+ * - The step is rejected with StepTimeoutError. By default this is treated
2393
+ * as a critical failure with no retry. Set retryOnTimeout: true on the
2394
+ * step config to retry timeouts like any other error.
2350
2395
  * - The underlying async operation continues running in the background
2351
2396
  * - Any side effects from the operation may still occur
2352
2397
  *
@@ -2481,8 +2526,8 @@ var WorkflowContextImpl = class _WorkflowContextImpl {
2481
2526
  metadata.error = void 0;
2482
2527
  metadata.dirty = true;
2483
2528
  }
2484
- const historyPruneInterval = config2.historyPruneInterval ?? DEFAULT_LOOP_HISTORY_PRUNE_INTERVAL;
2485
- const historySize = config2.historySize ?? historyPruneInterval;
2529
+ const historyPruneInterval = config2.historyPruneInterval ?? config2.commitInterval ?? config2.historyEvery ?? DEFAULT_LOOP_HISTORY_PRUNE_INTERVAL;
2530
+ const historySize = config2.historySize ?? config2.historyKeep ?? historyPruneInterval;
2486
2531
  let lastPrunedUpTo = 0;
2487
2532
  let deferredFlush = null;
2488
2533
  while (true) {
@@ -2671,7 +2716,7 @@ var WorkflowContextImpl = class _WorkflowContextImpl {
2671
2716
  return;
2672
2717
  }
2673
2718
  if (remaining < this.driver.workerPollInterval) {
2674
- await Promise.race([sleep(remaining), this.waitForEviction()]);
2719
+ await this.sleepOrEvict(remaining);
2675
2720
  this.checkEvicted();
2676
2721
  if (entry.kind.type === "sleep") {
2677
2722
  entry.kind.data.state = "completed";
@@ -3480,8 +3525,91 @@ var WorkflowContextImpl = class _WorkflowContextImpl {
3480
3525
  setEntry(this.storage, location, entry);
3481
3526
  await this.flushStorage();
3482
3527
  }
3528
+ // === Version ===
3529
+ async getVersion(name, latest) {
3530
+ this.assertNotInProgress();
3531
+ this.checkEvicted();
3532
+ this.entryInProgress = true;
3533
+ try {
3534
+ return await this.executeGetVersion(name, latest);
3535
+ } finally {
3536
+ this.entryInProgress = false;
3537
+ }
3538
+ }
3539
+ async executeGetVersion(name, latest) {
3540
+ if (!Number.isInteger(latest) || latest < 1) {
3541
+ throw new Error(
3542
+ `getVersion("${name}", ${latest}): latest must be an integer >= 1`
3543
+ );
3544
+ }
3545
+ this.checkDuplicateName(name);
3546
+ const location = appendName(this.storage, this.currentLocation, name);
3547
+ const key = locationToKey(this.storage, location);
3548
+ const existing = this.storage.history.entries.get(key);
3549
+ this.markVisited(key);
3550
+ this.stopRollbackIfMissing(existing);
3551
+ if (existing) {
3552
+ if (existing.kind.type !== "version_check") {
3553
+ throw new HistoryDivergedError(
3554
+ `Expected version_check at ${key}, found ${existing.kind.type}`
3555
+ );
3556
+ }
3557
+ return existing.kind.data.resolved;
3558
+ }
3559
+ const resolved = this.hasUnvisitedUnderCurrentScope(key) ? 1 : latest;
3560
+ const entry = createEntry(location, {
3561
+ type: "version_check",
3562
+ data: { resolved, latest }
3563
+ });
3564
+ setEntry(this.storage, location, entry);
3565
+ await this.flushStorage();
3566
+ return resolved;
3567
+ }
3568
+ /**
3569
+ * Returns true if any history entry under the current location scope
3570
+ * (other than `excludeKey`) has not yet been visited this run. Used by
3571
+ * getVersion to detect an old in-flight instance whose scope was already
3572
+ * executed by code that predates a version gate.
3573
+ */
3574
+ hasUnvisitedUnderCurrentScope(excludeKey) {
3575
+ const prefix = locationToKey(this.storage, this.currentLocation);
3576
+ for (const key of this.storage.history.entries.keys()) {
3577
+ if (key === excludeKey) {
3578
+ continue;
3579
+ }
3580
+ const isUnderPrefix = prefix === "" ? true : key.startsWith(`${prefix}/`) || key === prefix;
3581
+ if (isUnderPrefix && !this.visitedKeys.has(key)) {
3582
+ return true;
3583
+ }
3584
+ }
3585
+ return false;
3586
+ }
3483
3587
  };
3484
3588
 
3589
+ // src/utils.ts
3590
+ function sleep(ms) {
3591
+ return new Promise((resolve) => setTimeout(resolve, ms));
3592
+ }
3593
+ var TIMEOUT_MAX = 2147483647;
3594
+ function setLongTimeout(listener, after) {
3595
+ let timeout;
3596
+ function start(remaining) {
3597
+ if (remaining <= TIMEOUT_MAX) {
3598
+ timeout = setTimeout(listener, remaining);
3599
+ } else {
3600
+ timeout = setTimeout(() => {
3601
+ start(remaining - TIMEOUT_MAX);
3602
+ }, TIMEOUT_MAX);
3603
+ }
3604
+ }
3605
+ start(after);
3606
+ return {
3607
+ abort: () => {
3608
+ if (timeout !== void 0) clearTimeout(timeout);
3609
+ }
3610
+ };
3611
+ }
3612
+
3485
3613
  // src/index.ts
3486
3614
  var Loop = {
3487
3615
  continue: (state) => ({
@@ -3705,25 +3833,41 @@ async function executeLiveWorkflow(workflowId, workflowFn, input, driver, messag
3705
3833
  const hasMessages = result.waitingForMessages !== void 0;
3706
3834
  const hasDeadline = result.sleepUntil !== void 0;
3707
3835
  if (hasMessages && hasDeadline) {
3836
+ const iterationAbort = new AbortController();
3837
+ const onRunAbort = () => iterationAbort.abort();
3838
+ if (abortController.signal.aborted) {
3839
+ iterationAbort.abort();
3840
+ } else {
3841
+ abortController.signal.addEventListener("abort", onRunAbort, {
3842
+ once: true
3843
+ });
3844
+ }
3845
+ const messagePromise = awaitWithEviction(
3846
+ driver.waitForMessages(
3847
+ result.waitingForMessages,
3848
+ iterationAbort.signal
3849
+ ),
3850
+ iterationAbort.signal
3851
+ );
3852
+ const sleepPromise = waitForSleep(
3853
+ runtime,
3854
+ result.sleepUntil,
3855
+ iterationAbort.signal
3856
+ );
3857
+ messagePromise.catch(() => {
3858
+ });
3859
+ sleepPromise.catch(() => {
3860
+ });
3708
3861
  try {
3709
- const messagePromise = awaitWithEviction(
3710
- driver.waitForMessages(
3711
- result.waitingForMessages,
3712
- abortController.signal
3713
- ),
3714
- abortController.signal
3715
- );
3716
- const sleepPromise = waitForSleep(
3717
- runtime,
3718
- result.sleepUntil,
3719
- abortController.signal
3720
- );
3721
3862
  await Promise.race([messagePromise, sleepPromise]);
3722
3863
  } catch (error) {
3723
3864
  if (error instanceof EvictedError) {
3724
3865
  return lastResult;
3725
3866
  }
3726
3867
  throw error;
3868
+ } finally {
3869
+ iterationAbort.abort();
3870
+ abortController.signal.removeEventListener("abort", onRunAbort);
3727
3871
  }
3728
3872
  continue;
3729
3873
  }
@@ -4166,15 +4310,15 @@ export {
4166
4310
  deleteEntriesWithPrefix,
4167
4311
  getEntry,
4168
4312
  setEntry,
4169
- sleep,
4170
4313
  DEFAULT_MAX_RETRIES,
4171
4314
  DEFAULT_RETRY_BACKOFF_BASE,
4172
4315
  DEFAULT_RETRY_BACKOFF_MAX,
4173
4316
  DEFAULT_LOOP_HISTORY_PRUNE_INTERVAL,
4174
4317
  DEFAULT_STEP_TIMEOUT,
4175
4318
  WorkflowContextImpl,
4319
+ sleep,
4176
4320
  Loop,
4177
4321
  runWorkflow,
4178
4322
  replayWorkflowFromStep
4179
4323
  };
4180
- //# sourceMappingURL=chunk-UMFB2AR3.js.map
4324
+ //# sourceMappingURL=chunk-DTS4S7RT.js.map