@rivetkit/workflow-engine 2.1.0-rc.1 → 2.1.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.
@@ -181,8 +181,6 @@ interface WorkflowQueueNextOptions {
181
181
  * If omitted, receives from all queue names.
182
182
  */
183
183
  names?: readonly string[];
184
- /** Maximum number of messages to receive. Defaults to 1. */
185
- count?: number;
186
184
  /**
187
185
  * Timeout in milliseconds.
188
186
  * Omit to wait indefinitely.
@@ -191,6 +189,13 @@ interface WorkflowQueueNextOptions {
191
189
  /** Whether returned messages must be manually completed. */
192
190
  completable?: boolean;
193
191
  }
192
+ /**
193
+ * Options for receiving a batch of queue messages in workflows.
194
+ */
195
+ interface WorkflowQueueNextBatchOptions extends WorkflowQueueNextOptions {
196
+ /** Maximum number of messages to receive. Defaults to 1. */
197
+ count?: number;
198
+ }
194
199
  /**
195
200
  * Message returned by workflow queue operations.
196
201
  */
@@ -205,7 +210,8 @@ interface WorkflowQueueMessage<TBody = unknown> {
205
210
  * Workflow queue interface.
206
211
  */
207
212
  interface WorkflowQueue {
208
- next<TBody = unknown>(name: string, opts?: WorkflowQueueNextOptions): Promise<Array<WorkflowQueueMessage<TBody>>>;
213
+ next<TBody = unknown>(name: string, opts?: WorkflowQueueNextOptions): Promise<WorkflowQueueMessage<TBody>>;
214
+ nextBatch<TBody = unknown>(name: string, opts?: WorkflowQueueNextBatchOptions): Promise<Array<WorkflowQueueMessage<TBody>>>;
209
215
  send(name: string, body: unknown): Promise<void>;
210
216
  }
211
217
  /**
@@ -313,13 +319,20 @@ type LoopResult<S, T> = {
313
319
  break: true;
314
320
  value: T;
315
321
  };
322
+ /**
323
+ * Return type for a loop iteration callback.
324
+ *
325
+ * Stateless loops (state = undefined) may return void/undefined, which is treated as
326
+ * `Loop.continue(undefined)`.
327
+ */
328
+ type LoopIterationResult<S, T> = Promise<LoopResult<S, T> | (S extends undefined ? void : never)>;
316
329
  /**
317
330
  * Configuration for a loop.
318
331
  */
319
332
  interface LoopConfig<S, T> {
320
333
  name: string;
321
334
  state?: S;
322
- run: (ctx: WorkflowContextInterface, state: S) => Promise<LoopResult<S, T>>;
335
+ run: (ctx: WorkflowContextInterface, state: S) => LoopIterationResult<S, T>;
323
336
  commitInterval?: number;
324
337
  /** Trim loop history every N iterations. Defaults to commitInterval or 20. */
325
338
  historyEvery?: number;
@@ -345,7 +358,7 @@ interface WorkflowContextInterface {
345
358
  readonly queue: WorkflowQueue;
346
359
  step<T>(name: string, run: () => Promise<T>): Promise<T>;
347
360
  step<T>(config: StepConfig<T>): Promise<T>;
348
- loop<T>(name: string, run: (ctx: WorkflowContextInterface) => Promise<LoopResult<undefined, T>>): Promise<T>;
361
+ loop<T>(name: string, run: (ctx: WorkflowContextInterface) => LoopIterationResult<undefined, T>): Promise<T>;
349
362
  loop<S, T>(config: LoopConfig<S, T>): Promise<T>;
350
363
  sleep(name: string, durationMs: number): Promise<void>;
351
364
  sleepUntil(name: string, timestampMs: number): Promise<void>;
@@ -623,7 +636,7 @@ declare class WorkflowContextImpl implements WorkflowContextInterface {
623
636
  */
624
637
  private executeStepRollback;
625
638
  private executeWithTimeout;
626
- loop<S, T>(nameOrConfig: string | LoopConfig<S, T>, run?: (ctx: WorkflowContextInterface) => Promise<LoopResult<undefined, T>>): Promise<T>;
639
+ loop<S, T>(nameOrConfig: string | LoopConfig<S, T>, run?: (ctx: WorkflowContextInterface) => LoopIterationResult<undefined, T>): Promise<T>;
627
640
  private executeLoop;
628
641
  /**
629
642
  * Delete old loop iteration entries to save storage space.
@@ -647,7 +660,8 @@ declare class WorkflowContextImpl implements WorkflowContextInterface {
647
660
  private executeRollbackCheckpoint;
648
661
  private queueSend;
649
662
  private queueNext;
650
- private executeQueueNext;
663
+ private queueNextBatch;
664
+ private executeQueueNextBatch;
651
665
  private normalizeQueueNames;
652
666
  private messageNamesLabel;
653
667
  private receiveMessagesNow;
@@ -881,4 +895,4 @@ declare const Loop: {
881
895
 
882
896
  declare function runWorkflow<TInput, TOutput>(workflowId: string, workflowFn: WorkflowFunction<TInput, TOutput>, input: TInput, driver: EngineDriver, options?: RunWorkflowOptions): WorkflowHandle<TOutput>;
883
897
 
884
- export { type BranchConfig, type BranchOutput, type BranchStatus, type BranchStatusType, CancelledError, CriticalError, DEFAULT_LOOP_COMMIT_INTERVAL, DEFAULT_LOOP_HISTORY_EVERY, DEFAULT_LOOP_HISTORY_KEEP, DEFAULT_MAX_RETRIES, DEFAULT_RETRY_BACKOFF_BASE, DEFAULT_RETRY_BACKOFF_MAX, DEFAULT_STEP_TIMEOUT, type EngineDriver, type Entry, EntryInProgressError, type EntryKind, type EntryKindType, type EntryMetadata, type EntryStatus, EvictedError, type History, HistoryDivergedError, type JoinEntry, JoinError, type KVEntry, type KVWrite, type Location, Loop, type LoopConfig, type LoopEntry, type LoopIterationMarker, type LoopResult, type Message, type MessageEntry, MessageWaitError, type NameIndex, type PathSegment, type RaceEntry, RaceError, type RemovedEntry, type RollbackCheckpointEntry, RollbackCheckpointError, type RollbackContextInterface, RollbackError, type RunWorkflowOptions, type SleepEntry, SleepError, type SleepState, type StepConfig, type StepEntry, StepExhaustedError, StepFailedError, type Storage, WorkflowContextImpl, type WorkflowContextInterface, type WorkflowEntryMetadataSnapshot, type WorkflowFunction, type WorkflowHandle, type WorkflowHistoryEntry, type WorkflowHistorySnapshot, type WorkflowMessageDriver, type WorkflowQueue, type WorkflowQueueMessage, type WorkflowQueueNextOptions, type WorkflowResult, type WorkflowRunMode, type WorkflowState, appendLoopIteration, appendName, createEntry, createHistorySnapshot, createStorage, deleteEntriesWithPrefix, emptyLocation, flush, generateId, getEntry, getOrCreateMetadata, isLocationPrefix, isLoopIterationMarker, loadMetadata, loadStorage, locationToKey, locationsEqual, parentLocation, registerName, resolveName, runWorkflow, setEntry };
898
+ export { type BranchConfig, type BranchOutput, type BranchStatus, type BranchStatusType, CancelledError, CriticalError, DEFAULT_LOOP_COMMIT_INTERVAL, DEFAULT_LOOP_HISTORY_EVERY, DEFAULT_LOOP_HISTORY_KEEP, DEFAULT_MAX_RETRIES, DEFAULT_RETRY_BACKOFF_BASE, DEFAULT_RETRY_BACKOFF_MAX, DEFAULT_STEP_TIMEOUT, type EngineDriver, type Entry, EntryInProgressError, type EntryKind, type EntryKindType, type EntryMetadata, type EntryStatus, EvictedError, type History, HistoryDivergedError, type JoinEntry, JoinError, type KVEntry, type KVWrite, type Location, Loop, type LoopConfig, type LoopEntry, type LoopIterationMarker, type LoopResult, type Message, type MessageEntry, MessageWaitError, type NameIndex, type PathSegment, type RaceEntry, RaceError, type RemovedEntry, type RollbackCheckpointEntry, RollbackCheckpointError, type RollbackContextInterface, RollbackError, type RunWorkflowOptions, type SleepEntry, SleepError, type SleepState, type StepConfig, type StepEntry, StepExhaustedError, StepFailedError, type Storage, WorkflowContextImpl, type WorkflowContextInterface, type WorkflowEntryMetadataSnapshot, type WorkflowFunction, type WorkflowHandle, type WorkflowHistoryEntry, type WorkflowHistorySnapshot, type WorkflowMessageDriver, type WorkflowQueue, type WorkflowQueueMessage, type WorkflowQueueNextBatchOptions, type WorkflowQueueNextOptions, type WorkflowResult, type WorkflowRunMode, type WorkflowState, appendLoopIteration, appendName, createEntry, createHistorySnapshot, createStorage, deleteEntriesWithPrefix, emptyLocation, flush, generateId, getEntry, getOrCreateMetadata, isLocationPrefix, isLoopIterationMarker, loadMetadata, loadStorage, locationToKey, locationsEqual, parentLocation, registerName, resolveName, runWorkflow, setEntry };
@@ -181,8 +181,6 @@ interface WorkflowQueueNextOptions {
181
181
  * If omitted, receives from all queue names.
182
182
  */
183
183
  names?: readonly string[];
184
- /** Maximum number of messages to receive. Defaults to 1. */
185
- count?: number;
186
184
  /**
187
185
  * Timeout in milliseconds.
188
186
  * Omit to wait indefinitely.
@@ -191,6 +189,13 @@ interface WorkflowQueueNextOptions {
191
189
  /** Whether returned messages must be manually completed. */
192
190
  completable?: boolean;
193
191
  }
192
+ /**
193
+ * Options for receiving a batch of queue messages in workflows.
194
+ */
195
+ interface WorkflowQueueNextBatchOptions extends WorkflowQueueNextOptions {
196
+ /** Maximum number of messages to receive. Defaults to 1. */
197
+ count?: number;
198
+ }
194
199
  /**
195
200
  * Message returned by workflow queue operations.
196
201
  */
@@ -205,7 +210,8 @@ interface WorkflowQueueMessage<TBody = unknown> {
205
210
  * Workflow queue interface.
206
211
  */
207
212
  interface WorkflowQueue {
208
- next<TBody = unknown>(name: string, opts?: WorkflowQueueNextOptions): Promise<Array<WorkflowQueueMessage<TBody>>>;
213
+ next<TBody = unknown>(name: string, opts?: WorkflowQueueNextOptions): Promise<WorkflowQueueMessage<TBody>>;
214
+ nextBatch<TBody = unknown>(name: string, opts?: WorkflowQueueNextBatchOptions): Promise<Array<WorkflowQueueMessage<TBody>>>;
209
215
  send(name: string, body: unknown): Promise<void>;
210
216
  }
211
217
  /**
@@ -313,13 +319,20 @@ type LoopResult<S, T> = {
313
319
  break: true;
314
320
  value: T;
315
321
  };
322
+ /**
323
+ * Return type for a loop iteration callback.
324
+ *
325
+ * Stateless loops (state = undefined) may return void/undefined, which is treated as
326
+ * `Loop.continue(undefined)`.
327
+ */
328
+ type LoopIterationResult<S, T> = Promise<LoopResult<S, T> | (S extends undefined ? void : never)>;
316
329
  /**
317
330
  * Configuration for a loop.
318
331
  */
319
332
  interface LoopConfig<S, T> {
320
333
  name: string;
321
334
  state?: S;
322
- run: (ctx: WorkflowContextInterface, state: S) => Promise<LoopResult<S, T>>;
335
+ run: (ctx: WorkflowContextInterface, state: S) => LoopIterationResult<S, T>;
323
336
  commitInterval?: number;
324
337
  /** Trim loop history every N iterations. Defaults to commitInterval or 20. */
325
338
  historyEvery?: number;
@@ -345,7 +358,7 @@ interface WorkflowContextInterface {
345
358
  readonly queue: WorkflowQueue;
346
359
  step<T>(name: string, run: () => Promise<T>): Promise<T>;
347
360
  step<T>(config: StepConfig<T>): Promise<T>;
348
- loop<T>(name: string, run: (ctx: WorkflowContextInterface) => Promise<LoopResult<undefined, T>>): Promise<T>;
361
+ loop<T>(name: string, run: (ctx: WorkflowContextInterface) => LoopIterationResult<undefined, T>): Promise<T>;
349
362
  loop<S, T>(config: LoopConfig<S, T>): Promise<T>;
350
363
  sleep(name: string, durationMs: number): Promise<void>;
351
364
  sleepUntil(name: string, timestampMs: number): Promise<void>;
@@ -623,7 +636,7 @@ declare class WorkflowContextImpl implements WorkflowContextInterface {
623
636
  */
624
637
  private executeStepRollback;
625
638
  private executeWithTimeout;
626
- loop<S, T>(nameOrConfig: string | LoopConfig<S, T>, run?: (ctx: WorkflowContextInterface) => Promise<LoopResult<undefined, T>>): Promise<T>;
639
+ loop<S, T>(nameOrConfig: string | LoopConfig<S, T>, run?: (ctx: WorkflowContextInterface) => LoopIterationResult<undefined, T>): Promise<T>;
627
640
  private executeLoop;
628
641
  /**
629
642
  * Delete old loop iteration entries to save storage space.
@@ -647,7 +660,8 @@ declare class WorkflowContextImpl implements WorkflowContextInterface {
647
660
  private executeRollbackCheckpoint;
648
661
  private queueSend;
649
662
  private queueNext;
650
- private executeQueueNext;
663
+ private queueNextBatch;
664
+ private executeQueueNextBatch;
651
665
  private normalizeQueueNames;
652
666
  private messageNamesLabel;
653
667
  private receiveMessagesNow;
@@ -881,4 +895,4 @@ declare const Loop: {
881
895
 
882
896
  declare function runWorkflow<TInput, TOutput>(workflowId: string, workflowFn: WorkflowFunction<TInput, TOutput>, input: TInput, driver: EngineDriver, options?: RunWorkflowOptions): WorkflowHandle<TOutput>;
883
897
 
884
- export { type BranchConfig, type BranchOutput, type BranchStatus, type BranchStatusType, CancelledError, CriticalError, DEFAULT_LOOP_COMMIT_INTERVAL, DEFAULT_LOOP_HISTORY_EVERY, DEFAULT_LOOP_HISTORY_KEEP, DEFAULT_MAX_RETRIES, DEFAULT_RETRY_BACKOFF_BASE, DEFAULT_RETRY_BACKOFF_MAX, DEFAULT_STEP_TIMEOUT, type EngineDriver, type Entry, EntryInProgressError, type EntryKind, type EntryKindType, type EntryMetadata, type EntryStatus, EvictedError, type History, HistoryDivergedError, type JoinEntry, JoinError, type KVEntry, type KVWrite, type Location, Loop, type LoopConfig, type LoopEntry, type LoopIterationMarker, type LoopResult, type Message, type MessageEntry, MessageWaitError, type NameIndex, type PathSegment, type RaceEntry, RaceError, type RemovedEntry, type RollbackCheckpointEntry, RollbackCheckpointError, type RollbackContextInterface, RollbackError, type RunWorkflowOptions, type SleepEntry, SleepError, type SleepState, type StepConfig, type StepEntry, StepExhaustedError, StepFailedError, type Storage, WorkflowContextImpl, type WorkflowContextInterface, type WorkflowEntryMetadataSnapshot, type WorkflowFunction, type WorkflowHandle, type WorkflowHistoryEntry, type WorkflowHistorySnapshot, type WorkflowMessageDriver, type WorkflowQueue, type WorkflowQueueMessage, type WorkflowQueueNextOptions, type WorkflowResult, type WorkflowRunMode, type WorkflowState, appendLoopIteration, appendName, createEntry, createHistorySnapshot, createStorage, deleteEntriesWithPrefix, emptyLocation, flush, generateId, getEntry, getOrCreateMetadata, isLocationPrefix, isLoopIterationMarker, loadMetadata, loadStorage, locationToKey, locationsEqual, parentLocation, registerName, resolveName, runWorkflow, setEntry };
898
+ export { type BranchConfig, type BranchOutput, type BranchStatus, type BranchStatusType, CancelledError, CriticalError, DEFAULT_LOOP_COMMIT_INTERVAL, DEFAULT_LOOP_HISTORY_EVERY, DEFAULT_LOOP_HISTORY_KEEP, DEFAULT_MAX_RETRIES, DEFAULT_RETRY_BACKOFF_BASE, DEFAULT_RETRY_BACKOFF_MAX, DEFAULT_STEP_TIMEOUT, type EngineDriver, type Entry, EntryInProgressError, type EntryKind, type EntryKindType, type EntryMetadata, type EntryStatus, EvictedError, type History, HistoryDivergedError, type JoinEntry, JoinError, type KVEntry, type KVWrite, type Location, Loop, type LoopConfig, type LoopEntry, type LoopIterationMarker, type LoopResult, type Message, type MessageEntry, MessageWaitError, type NameIndex, type PathSegment, type RaceEntry, RaceError, type RemovedEntry, type RollbackCheckpointEntry, RollbackCheckpointError, type RollbackContextInterface, RollbackError, type RunWorkflowOptions, type SleepEntry, SleepError, type SleepState, type StepConfig, type StepEntry, StepExhaustedError, StepFailedError, type Storage, WorkflowContextImpl, type WorkflowContextInterface, type WorkflowEntryMetadataSnapshot, type WorkflowFunction, type WorkflowHandle, type WorkflowHistoryEntry, type WorkflowHistorySnapshot, type WorkflowMessageDriver, type WorkflowQueue, type WorkflowQueueMessage, type WorkflowQueueNextBatchOptions, type WorkflowQueueNextOptions, type WorkflowResult, type WorkflowRunMode, type WorkflowState, appendLoopIteration, appendName, createEntry, createHistorySnapshot, createStorage, deleteEntriesWithPrefix, emptyLocation, flush, generateId, getEntry, getOrCreateMetadata, isLocationPrefix, isLoopIterationMarker, loadMetadata, loadStorage, locationToKey, locationsEqual, parentLocation, registerName, resolveName, runWorkflow, setEntry };
@@ -43,7 +43,7 @@ import {
43
43
  resolveName,
44
44
  runWorkflow,
45
45
  setEntry
46
- } from "./chunk-JWHWQBZP.js";
46
+ } from "./chunk-WA4TXB6Y.js";
47
47
  export {
48
48
  CancelledError,
49
49
  CriticalError,
@@ -47,7 +47,7 @@
47
47
 
48
48
 
49
49
 
50
- var _chunkGJ66YE5Wcjs = require('./chunk-GJ66YE5W.cjs');
50
+ var _chunk6TTCEQL3cjs = require('./chunk-6TTCEQL3.cjs');
51
51
 
52
52
  // src/testing.ts
53
53
  var InMemoryWorkflowMessageDriver = class {
@@ -95,7 +95,7 @@ var InMemoryWorkflowMessageDriver = class {
95
95
  }
96
96
  async waitForMessages(messageNames, abortSignal) {
97
97
  if (abortSignal.aborted) {
98
- throw new (0, _chunkGJ66YE5Wcjs.EvictedError)();
98
+ throw new (0, _chunk6TTCEQL3cjs.EvictedError)();
99
99
  }
100
100
  const nameSet = messageNames.length > 0 ? new Set(messageNames) : void 0;
101
101
  if (this.#messages.some(
@@ -116,7 +116,7 @@ var InMemoryWorkflowMessageDriver = class {
116
116
  },
117
117
  abortSignal,
118
118
  onAbort: () => {
119
- waiter.reject(new (0, _chunkGJ66YE5Wcjs.EvictedError)());
119
+ waiter.reject(new (0, _chunk6TTCEQL3cjs.EvictedError)());
120
120
  }
121
121
  };
122
122
  abortSignal.addEventListener("abort", waiter.onAbort, { once: true });
@@ -154,48 +154,48 @@ var InMemoryDriver = (_class = class {constructor() { _class.prototype.__init.ca
154
154
  __init4() {this.workerPollInterval = 100}
155
155
  __init5() {this.messageDriver = this.#inMemoryMessageDriver}
156
156
  async get(key) {
157
- await _chunkGJ66YE5Wcjs.sleep.call(void 0, this.latency);
158
- const entry = this.kv.get(_chunkGJ66YE5Wcjs.keyToHex.call(void 0, key));
157
+ await _chunk6TTCEQL3cjs.sleep.call(void 0, this.latency);
158
+ const entry = this.kv.get(_chunk6TTCEQL3cjs.keyToHex.call(void 0, key));
159
159
  return _nullishCoalesce((entry == null ? void 0 : entry.value), () => ( null));
160
160
  }
161
161
  async set(key, value) {
162
- await _chunkGJ66YE5Wcjs.sleep.call(void 0, this.latency);
163
- this.kv.set(_chunkGJ66YE5Wcjs.keyToHex.call(void 0, key), { key, value });
162
+ await _chunk6TTCEQL3cjs.sleep.call(void 0, this.latency);
163
+ this.kv.set(_chunk6TTCEQL3cjs.keyToHex.call(void 0, key), { key, value });
164
164
  }
165
165
  async delete(key) {
166
- await _chunkGJ66YE5Wcjs.sleep.call(void 0, this.latency);
167
- this.kv.delete(_chunkGJ66YE5Wcjs.keyToHex.call(void 0, key));
166
+ await _chunk6TTCEQL3cjs.sleep.call(void 0, this.latency);
167
+ this.kv.delete(_chunk6TTCEQL3cjs.keyToHex.call(void 0, key));
168
168
  }
169
169
  async deletePrefix(prefix) {
170
- await _chunkGJ66YE5Wcjs.sleep.call(void 0, this.latency);
170
+ await _chunk6TTCEQL3cjs.sleep.call(void 0, this.latency);
171
171
  for (const [hexKey, entry] of this.kv) {
172
- if (_chunkGJ66YE5Wcjs.keyStartsWith.call(void 0, entry.key, prefix)) {
172
+ if (_chunk6TTCEQL3cjs.keyStartsWith.call(void 0, entry.key, prefix)) {
173
173
  this.kv.delete(hexKey);
174
174
  }
175
175
  }
176
176
  }
177
177
  async list(prefix) {
178
- await _chunkGJ66YE5Wcjs.sleep.call(void 0, this.latency);
178
+ await _chunk6TTCEQL3cjs.sleep.call(void 0, this.latency);
179
179
  const results = [];
180
180
  for (const entry of this.kv.values()) {
181
- if (_chunkGJ66YE5Wcjs.keyStartsWith.call(void 0, entry.key, prefix)) {
181
+ if (_chunk6TTCEQL3cjs.keyStartsWith.call(void 0, entry.key, prefix)) {
182
182
  results.push({ key: entry.key, value: entry.value });
183
183
  }
184
184
  }
185
- return results.sort((a, b) => _chunkGJ66YE5Wcjs.compareKeys.call(void 0, a.key, b.key));
185
+ return results.sort((a, b) => _chunk6TTCEQL3cjs.compareKeys.call(void 0, a.key, b.key));
186
186
  }
187
187
  async batch(writes) {
188
- await _chunkGJ66YE5Wcjs.sleep.call(void 0, this.latency);
188
+ await _chunk6TTCEQL3cjs.sleep.call(void 0, this.latency);
189
189
  for (const { key, value } of writes) {
190
- this.kv.set(_chunkGJ66YE5Wcjs.keyToHex.call(void 0, key), { key, value });
190
+ this.kv.set(_chunk6TTCEQL3cjs.keyToHex.call(void 0, key), { key, value });
191
191
  }
192
192
  }
193
193
  async setAlarm(workflowId, wakeAt) {
194
- await _chunkGJ66YE5Wcjs.sleep.call(void 0, this.latency);
194
+ await _chunk6TTCEQL3cjs.sleep.call(void 0, this.latency);
195
195
  this.alarms.set(workflowId, wakeAt);
196
196
  }
197
197
  async clearAlarm(workflowId) {
198
- await _chunkGJ66YE5Wcjs.sleep.call(void 0, this.latency);
198
+ await _chunk6TTCEQL3cjs.sleep.call(void 0, this.latency);
199
199
  this.alarms.delete(workflowId);
200
200
  }
201
201
  async waitForMessages(messageNames, abortSignal) {
@@ -206,7 +206,7 @@ var InMemoryDriver = (_class = class {constructor() { _class.prototype.__init.ca
206
206
  }
207
207
  while (true) {
208
208
  if (abortSignal.aborted) {
209
- throw new (0, _chunkGJ66YE5Wcjs.EvictedError)();
209
+ throw new (0, _chunk6TTCEQL3cjs.EvictedError)();
210
210
  }
211
211
  const messages = await this.messageDriver.receiveMessages({
212
212
  names: messageNames.length > 0 ? messageNames : void 0,
@@ -216,7 +216,7 @@ var InMemoryDriver = (_class = class {constructor() { _class.prototype.__init.ca
216
216
  if (messages.length > 0) {
217
217
  return;
218
218
  }
219
- await _chunkGJ66YE5Wcjs.sleep.call(void 0, Math.max(1, this.latency));
219
+ await _chunk6TTCEQL3cjs.sleep.call(void 0, Math.max(1, this.latency));
220
220
  }
221
221
  }
222
222
  /**
@@ -312,5 +312,5 @@ var InMemoryDriver = (_class = class {constructor() { _class.prototype.__init.ca
312
312
 
313
313
 
314
314
 
315
- exports.CancelledError = _chunkGJ66YE5Wcjs.CancelledError; exports.CriticalError = _chunkGJ66YE5Wcjs.CriticalError; exports.DEFAULT_LOOP_COMMIT_INTERVAL = _chunkGJ66YE5Wcjs.DEFAULT_LOOP_COMMIT_INTERVAL; exports.DEFAULT_LOOP_HISTORY_EVERY = _chunkGJ66YE5Wcjs.DEFAULT_LOOP_HISTORY_EVERY; exports.DEFAULT_LOOP_HISTORY_KEEP = _chunkGJ66YE5Wcjs.DEFAULT_LOOP_HISTORY_KEEP; exports.DEFAULT_MAX_RETRIES = _chunkGJ66YE5Wcjs.DEFAULT_MAX_RETRIES; exports.DEFAULT_RETRY_BACKOFF_BASE = _chunkGJ66YE5Wcjs.DEFAULT_RETRY_BACKOFF_BASE; exports.DEFAULT_RETRY_BACKOFF_MAX = _chunkGJ66YE5Wcjs.DEFAULT_RETRY_BACKOFF_MAX; exports.DEFAULT_STEP_TIMEOUT = _chunkGJ66YE5Wcjs.DEFAULT_STEP_TIMEOUT; exports.EntryInProgressError = _chunkGJ66YE5Wcjs.EntryInProgressError; exports.EvictedError = _chunkGJ66YE5Wcjs.EvictedError; exports.HistoryDivergedError = _chunkGJ66YE5Wcjs.HistoryDivergedError; exports.InMemoryDriver = InMemoryDriver; exports.JoinError = _chunkGJ66YE5Wcjs.JoinError; exports.Loop = _chunkGJ66YE5Wcjs.Loop; exports.MessageWaitError = _chunkGJ66YE5Wcjs.MessageWaitError; exports.RaceError = _chunkGJ66YE5Wcjs.RaceError; exports.RollbackCheckpointError = _chunkGJ66YE5Wcjs.RollbackCheckpointError; exports.RollbackError = _chunkGJ66YE5Wcjs.RollbackError; exports.SleepError = _chunkGJ66YE5Wcjs.SleepError; exports.StepExhaustedError = _chunkGJ66YE5Wcjs.StepExhaustedError; exports.StepFailedError = _chunkGJ66YE5Wcjs.StepFailedError; exports.WorkflowContextImpl = _chunkGJ66YE5Wcjs.WorkflowContextImpl; exports.appendLoopIteration = _chunkGJ66YE5Wcjs.appendLoopIteration; exports.appendName = _chunkGJ66YE5Wcjs.appendName; exports.createEntry = _chunkGJ66YE5Wcjs.createEntry; exports.createHistorySnapshot = _chunkGJ66YE5Wcjs.createHistorySnapshot; exports.createStorage = _chunkGJ66YE5Wcjs.createStorage; exports.deleteEntriesWithPrefix = _chunkGJ66YE5Wcjs.deleteEntriesWithPrefix; exports.emptyLocation = _chunkGJ66YE5Wcjs.emptyLocation; exports.flush = _chunkGJ66YE5Wcjs.flush; exports.generateId = _chunkGJ66YE5Wcjs.generateId; exports.getEntry = _chunkGJ66YE5Wcjs.getEntry; exports.getOrCreateMetadata = _chunkGJ66YE5Wcjs.getOrCreateMetadata; exports.isLocationPrefix = _chunkGJ66YE5Wcjs.isLocationPrefix; exports.isLoopIterationMarker = _chunkGJ66YE5Wcjs.isLoopIterationMarker; exports.loadMetadata = _chunkGJ66YE5Wcjs.loadMetadata; exports.loadStorage = _chunkGJ66YE5Wcjs.loadStorage; exports.locationToKey = _chunkGJ66YE5Wcjs.locationToKey; exports.locationsEqual = _chunkGJ66YE5Wcjs.locationsEqual; exports.parentLocation = _chunkGJ66YE5Wcjs.parentLocation; exports.registerName = _chunkGJ66YE5Wcjs.registerName; exports.resolveName = _chunkGJ66YE5Wcjs.resolveName; exports.runWorkflow = _chunkGJ66YE5Wcjs.runWorkflow; exports.setEntry = _chunkGJ66YE5Wcjs.setEntry;
315
+ exports.CancelledError = _chunk6TTCEQL3cjs.CancelledError; exports.CriticalError = _chunk6TTCEQL3cjs.CriticalError; exports.DEFAULT_LOOP_COMMIT_INTERVAL = _chunk6TTCEQL3cjs.DEFAULT_LOOP_COMMIT_INTERVAL; exports.DEFAULT_LOOP_HISTORY_EVERY = _chunk6TTCEQL3cjs.DEFAULT_LOOP_HISTORY_EVERY; exports.DEFAULT_LOOP_HISTORY_KEEP = _chunk6TTCEQL3cjs.DEFAULT_LOOP_HISTORY_KEEP; exports.DEFAULT_MAX_RETRIES = _chunk6TTCEQL3cjs.DEFAULT_MAX_RETRIES; exports.DEFAULT_RETRY_BACKOFF_BASE = _chunk6TTCEQL3cjs.DEFAULT_RETRY_BACKOFF_BASE; exports.DEFAULT_RETRY_BACKOFF_MAX = _chunk6TTCEQL3cjs.DEFAULT_RETRY_BACKOFF_MAX; exports.DEFAULT_STEP_TIMEOUT = _chunk6TTCEQL3cjs.DEFAULT_STEP_TIMEOUT; exports.EntryInProgressError = _chunk6TTCEQL3cjs.EntryInProgressError; exports.EvictedError = _chunk6TTCEQL3cjs.EvictedError; exports.HistoryDivergedError = _chunk6TTCEQL3cjs.HistoryDivergedError; exports.InMemoryDriver = InMemoryDriver; exports.JoinError = _chunk6TTCEQL3cjs.JoinError; exports.Loop = _chunk6TTCEQL3cjs.Loop; exports.MessageWaitError = _chunk6TTCEQL3cjs.MessageWaitError; exports.RaceError = _chunk6TTCEQL3cjs.RaceError; exports.RollbackCheckpointError = _chunk6TTCEQL3cjs.RollbackCheckpointError; exports.RollbackError = _chunk6TTCEQL3cjs.RollbackError; exports.SleepError = _chunk6TTCEQL3cjs.SleepError; exports.StepExhaustedError = _chunk6TTCEQL3cjs.StepExhaustedError; exports.StepFailedError = _chunk6TTCEQL3cjs.StepFailedError; exports.WorkflowContextImpl = _chunk6TTCEQL3cjs.WorkflowContextImpl; exports.appendLoopIteration = _chunk6TTCEQL3cjs.appendLoopIteration; exports.appendName = _chunk6TTCEQL3cjs.appendName; exports.createEntry = _chunk6TTCEQL3cjs.createEntry; exports.createHistorySnapshot = _chunk6TTCEQL3cjs.createHistorySnapshot; exports.createStorage = _chunk6TTCEQL3cjs.createStorage; exports.deleteEntriesWithPrefix = _chunk6TTCEQL3cjs.deleteEntriesWithPrefix; exports.emptyLocation = _chunk6TTCEQL3cjs.emptyLocation; exports.flush = _chunk6TTCEQL3cjs.flush; exports.generateId = _chunk6TTCEQL3cjs.generateId; exports.getEntry = _chunk6TTCEQL3cjs.getEntry; exports.getOrCreateMetadata = _chunk6TTCEQL3cjs.getOrCreateMetadata; exports.isLocationPrefix = _chunk6TTCEQL3cjs.isLocationPrefix; exports.isLoopIterationMarker = _chunk6TTCEQL3cjs.isLoopIterationMarker; exports.loadMetadata = _chunk6TTCEQL3cjs.loadMetadata; exports.loadStorage = _chunk6TTCEQL3cjs.loadStorage; exports.locationToKey = _chunk6TTCEQL3cjs.locationToKey; exports.locationsEqual = _chunk6TTCEQL3cjs.locationsEqual; exports.parentLocation = _chunk6TTCEQL3cjs.parentLocation; exports.registerName = _chunk6TTCEQL3cjs.registerName; exports.resolveName = _chunk6TTCEQL3cjs.resolveName; exports.runWorkflow = _chunk6TTCEQL3cjs.runWorkflow; exports.setEntry = _chunk6TTCEQL3cjs.setEntry;
316
316
  //# sourceMappingURL=testing.cjs.map
@@ -1,5 +1,5 @@
1
1
  import { EngineDriver, WorkflowMessageDriver, KVEntry, KVWrite } from './index.cjs';
2
- export { BranchConfig, BranchOutput, BranchStatus, BranchStatusType, CancelledError, CriticalError, DEFAULT_LOOP_COMMIT_INTERVAL, DEFAULT_LOOP_HISTORY_EVERY, DEFAULT_LOOP_HISTORY_KEEP, DEFAULT_MAX_RETRIES, DEFAULT_RETRY_BACKOFF_BASE, DEFAULT_RETRY_BACKOFF_MAX, DEFAULT_STEP_TIMEOUT, Entry, EntryInProgressError, EntryKind, EntryKindType, EntryMetadata, EntryStatus, EvictedError, History, HistoryDivergedError, JoinEntry, JoinError, Location, Loop, LoopConfig, LoopEntry, LoopIterationMarker, LoopResult, Message, MessageEntry, MessageWaitError, NameIndex, PathSegment, RaceEntry, RaceError, RemovedEntry, RollbackCheckpointEntry, RollbackCheckpointError, RollbackContextInterface, RollbackError, RunWorkflowOptions, SleepEntry, SleepError, SleepState, StepConfig, StepEntry, StepExhaustedError, StepFailedError, Storage, WorkflowContextImpl, WorkflowContextInterface, WorkflowEntryMetadataSnapshot, WorkflowFunction, WorkflowHandle, WorkflowHistoryEntry, WorkflowHistorySnapshot, WorkflowQueue, WorkflowQueueMessage, WorkflowQueueNextOptions, WorkflowResult, WorkflowRunMode, WorkflowState, appendLoopIteration, appendName, createEntry, createHistorySnapshot, createStorage, deleteEntriesWithPrefix, emptyLocation, flush, generateId, getEntry, getOrCreateMetadata, isLocationPrefix, isLoopIterationMarker, loadMetadata, loadStorage, locationToKey, locationsEqual, parentLocation, registerName, resolveName, runWorkflow, setEntry } from './index.cjs';
2
+ export { BranchConfig, BranchOutput, BranchStatus, BranchStatusType, CancelledError, CriticalError, DEFAULT_LOOP_COMMIT_INTERVAL, DEFAULT_LOOP_HISTORY_EVERY, DEFAULT_LOOP_HISTORY_KEEP, DEFAULT_MAX_RETRIES, DEFAULT_RETRY_BACKOFF_BASE, DEFAULT_RETRY_BACKOFF_MAX, DEFAULT_STEP_TIMEOUT, Entry, EntryInProgressError, EntryKind, EntryKindType, EntryMetadata, EntryStatus, EvictedError, History, HistoryDivergedError, JoinEntry, JoinError, Location, Loop, LoopConfig, LoopEntry, LoopIterationMarker, LoopResult, Message, MessageEntry, MessageWaitError, NameIndex, PathSegment, RaceEntry, RaceError, RemovedEntry, RollbackCheckpointEntry, RollbackCheckpointError, RollbackContextInterface, RollbackError, RunWorkflowOptions, SleepEntry, SleepError, SleepState, StepConfig, StepEntry, StepExhaustedError, StepFailedError, Storage, WorkflowContextImpl, WorkflowContextInterface, WorkflowEntryMetadataSnapshot, WorkflowFunction, WorkflowHandle, WorkflowHistoryEntry, WorkflowHistorySnapshot, WorkflowQueue, WorkflowQueueMessage, WorkflowQueueNextBatchOptions, WorkflowQueueNextOptions, WorkflowResult, WorkflowRunMode, WorkflowState, appendLoopIteration, appendName, createEntry, createHistorySnapshot, createStorage, deleteEntriesWithPrefix, emptyLocation, flush, generateId, getEntry, getOrCreateMetadata, isLocationPrefix, isLoopIterationMarker, loadMetadata, loadStorage, locationToKey, locationsEqual, parentLocation, registerName, resolveName, runWorkflow, setEntry } from './index.cjs';
3
3
  import 'pino';
4
4
 
5
5
  /**
@@ -1,5 +1,5 @@
1
1
  import { EngineDriver, WorkflowMessageDriver, KVEntry, KVWrite } from './index.js';
2
- export { BranchConfig, BranchOutput, BranchStatus, BranchStatusType, CancelledError, CriticalError, DEFAULT_LOOP_COMMIT_INTERVAL, DEFAULT_LOOP_HISTORY_EVERY, DEFAULT_LOOP_HISTORY_KEEP, DEFAULT_MAX_RETRIES, DEFAULT_RETRY_BACKOFF_BASE, DEFAULT_RETRY_BACKOFF_MAX, DEFAULT_STEP_TIMEOUT, Entry, EntryInProgressError, EntryKind, EntryKindType, EntryMetadata, EntryStatus, EvictedError, History, HistoryDivergedError, JoinEntry, JoinError, Location, Loop, LoopConfig, LoopEntry, LoopIterationMarker, LoopResult, Message, MessageEntry, MessageWaitError, NameIndex, PathSegment, RaceEntry, RaceError, RemovedEntry, RollbackCheckpointEntry, RollbackCheckpointError, RollbackContextInterface, RollbackError, RunWorkflowOptions, SleepEntry, SleepError, SleepState, StepConfig, StepEntry, StepExhaustedError, StepFailedError, Storage, WorkflowContextImpl, WorkflowContextInterface, WorkflowEntryMetadataSnapshot, WorkflowFunction, WorkflowHandle, WorkflowHistoryEntry, WorkflowHistorySnapshot, WorkflowQueue, WorkflowQueueMessage, WorkflowQueueNextOptions, WorkflowResult, WorkflowRunMode, WorkflowState, appendLoopIteration, appendName, createEntry, createHistorySnapshot, createStorage, deleteEntriesWithPrefix, emptyLocation, flush, generateId, getEntry, getOrCreateMetadata, isLocationPrefix, isLoopIterationMarker, loadMetadata, loadStorage, locationToKey, locationsEqual, parentLocation, registerName, resolveName, runWorkflow, setEntry } from './index.js';
2
+ export { BranchConfig, BranchOutput, BranchStatus, BranchStatusType, CancelledError, CriticalError, DEFAULT_LOOP_COMMIT_INTERVAL, DEFAULT_LOOP_HISTORY_EVERY, DEFAULT_LOOP_HISTORY_KEEP, DEFAULT_MAX_RETRIES, DEFAULT_RETRY_BACKOFF_BASE, DEFAULT_RETRY_BACKOFF_MAX, DEFAULT_STEP_TIMEOUT, Entry, EntryInProgressError, EntryKind, EntryKindType, EntryMetadata, EntryStatus, EvictedError, History, HistoryDivergedError, JoinEntry, JoinError, Location, Loop, LoopConfig, LoopEntry, LoopIterationMarker, LoopResult, Message, MessageEntry, MessageWaitError, NameIndex, PathSegment, RaceEntry, RaceError, RemovedEntry, RollbackCheckpointEntry, RollbackCheckpointError, RollbackContextInterface, RollbackError, RunWorkflowOptions, SleepEntry, SleepError, SleepState, StepConfig, StepEntry, StepExhaustedError, StepFailedError, Storage, WorkflowContextImpl, WorkflowContextInterface, WorkflowEntryMetadataSnapshot, WorkflowFunction, WorkflowHandle, WorkflowHistoryEntry, WorkflowHistorySnapshot, WorkflowQueue, WorkflowQueueMessage, WorkflowQueueNextBatchOptions, WorkflowQueueNextOptions, WorkflowResult, WorkflowRunMode, WorkflowState, appendLoopIteration, appendName, createEntry, createHistorySnapshot, createStorage, deleteEntriesWithPrefix, emptyLocation, flush, generateId, getEntry, getOrCreateMetadata, isLocationPrefix, isLoopIterationMarker, loadMetadata, loadStorage, locationToKey, locationsEqual, parentLocation, registerName, resolveName, runWorkflow, setEntry } from './index.js';
3
3
  import 'pino';
4
4
 
5
5
  /**
@@ -47,7 +47,7 @@ import {
47
47
  runWorkflow,
48
48
  setEntry,
49
49
  sleep
50
- } from "./chunk-JWHWQBZP.js";
50
+ } from "./chunk-WA4TXB6Y.js";
51
51
 
52
52
  // src/testing.ts
53
53
  var InMemoryWorkflowMessageDriver = class {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rivetkit/workflow-engine",
3
- "version": "2.1.0-rc.1",
3
+ "version": "2.1.0",
4
4
  "description": "Durable workflow engine with reentrant execution",
5
5
  "license": "Apache-2.0",
6
6
  "keywords": [
package/src/context.ts CHANGED
@@ -40,6 +40,7 @@ import type {
40
40
  EntryMetadata,
41
41
  Location,
42
42
  LoopConfig,
43
+ LoopIterationResult,
43
44
  LoopResult,
44
45
  Message,
45
46
  RollbackContextInterface,
@@ -48,6 +49,7 @@ import type {
48
49
  WorkflowContextInterface,
49
50
  WorkflowQueue,
50
51
  WorkflowQueueMessage,
52
+ WorkflowQueueNextBatchOptions,
51
53
  WorkflowQueueNextOptions,
52
54
  WorkflowMessageDriver,
53
55
  } from "./types.js";
@@ -145,6 +147,7 @@ export class WorkflowContextImpl implements WorkflowContextInterface {
145
147
  get queue(): WorkflowQueue {
146
148
  return {
147
149
  next: async (name, opts) => await this.queueNext(name, opts),
150
+ nextBatch: async (name, opts) => await this.queueNextBatch(name, opts),
148
151
  send: async (name, body) => await this.queueSend(name, body),
149
152
  };
150
153
  }
@@ -591,7 +594,7 @@ export class WorkflowContextImpl implements WorkflowContextInterface {
591
594
  nameOrConfig: string | LoopConfig<S, T>,
592
595
  run?: (
593
596
  ctx: WorkflowContextInterface,
594
- ) => Promise<LoopResult<undefined, T>>,
597
+ ) => LoopIterationResult<undefined, T>,
595
598
  ): Promise<T> {
596
599
  this.assertNotInProgress();
597
600
  this.checkEvicted();
@@ -708,7 +711,16 @@ export class WorkflowContextImpl implements WorkflowContextInterface {
708
711
  const branchCtx = this.createBranch(iterationLocation);
709
712
 
710
713
  // Execute iteration
711
- const result = await config.run(branchCtx, state);
714
+ const iterationResult = await config.run(branchCtx, state);
715
+ if (iterationResult === undefined && state !== undefined) {
716
+ throw new Error(
717
+ `Loop "${config.name}" returned undefined for a stateful iteration. Return Loop.continue(state) or Loop.break(value).`,
718
+ );
719
+ }
720
+ const result =
721
+ iterationResult === undefined
722
+ ? ({ continue: true, state } as LoopResult<S, T>)
723
+ : iterationResult;
712
724
 
713
725
  // Validate branch completed cleanly
714
726
  branchCtx.validateComplete();
@@ -975,21 +987,38 @@ export class WorkflowContextImpl implements WorkflowContextInterface {
975
987
  private async queueNext<T>(
976
988
  name: string,
977
989
  opts?: WorkflowQueueNextOptions,
990
+ ): Promise<WorkflowQueueMessage<T>> {
991
+ const messages = await this.queueNextBatch<T>(name, {
992
+ ...(opts ?? {}),
993
+ count: 1,
994
+ });
995
+ const message = messages[0];
996
+ if (!message) {
997
+ throw new Error(
998
+ `queue.next("${name}") timed out before receiving a message. Use queue.nextBatch(...) for optional/time-limited reads.`,
999
+ );
1000
+ }
1001
+ return message;
1002
+ }
1003
+
1004
+ private async queueNextBatch<T>(
1005
+ name: string,
1006
+ opts?: WorkflowQueueNextBatchOptions,
978
1007
  ): Promise<Array<WorkflowQueueMessage<T>>> {
979
1008
  this.assertNotInProgress();
980
1009
  this.checkEvicted();
981
1010
 
982
1011
  this.entryInProgress = true;
983
1012
  try {
984
- return await this.executeQueueNext<T>(name, opts);
1013
+ return await this.executeQueueNextBatch<T>(name, opts);
985
1014
  } finally {
986
1015
  this.entryInProgress = false;
987
1016
  }
988
1017
  }
989
1018
 
990
- private async executeQueueNext<T>(
1019
+ private async executeQueueNextBatch<T>(
991
1020
  name: string,
992
- opts?: WorkflowQueueNextOptions,
1021
+ opts?: WorkflowQueueNextBatchOptions,
993
1022
  ): Promise<Array<WorkflowQueueMessage<T>>> {
994
1023
  if (this.pendingCompletableMessageIds.size > 0) {
995
1024
  throw new Error(
package/src/index.ts CHANGED
@@ -99,6 +99,7 @@ export type {
99
99
  WorkflowHandle,
100
100
  WorkflowQueue,
101
101
  WorkflowQueueMessage,
102
+ WorkflowQueueNextBatchOptions,
102
103
  WorkflowQueueNextOptions,
103
104
  WorkflowMessageDriver,
104
105
  WorkflowResult,
package/src/types.ts CHANGED
@@ -212,8 +212,6 @@ export interface WorkflowQueueNextOptions {
212
212
  * If omitted, receives from all queue names.
213
213
  */
214
214
  names?: readonly string[];
215
- /** Maximum number of messages to receive. Defaults to 1. */
216
- count?: number;
217
215
  /**
218
216
  * Timeout in milliseconds.
219
217
  * Omit to wait indefinitely.
@@ -223,6 +221,16 @@ export interface WorkflowQueueNextOptions {
223
221
  completable?: boolean;
224
222
  }
225
223
 
224
+ /**
225
+ * Options for receiving a batch of queue messages in workflows.
226
+ */
227
+ export interface WorkflowQueueNextBatchOptions
228
+ extends WorkflowQueueNextOptions
229
+ {
230
+ /** Maximum number of messages to receive. Defaults to 1. */
231
+ count?: number;
232
+ }
233
+
226
234
  /**
227
235
  * Message returned by workflow queue operations.
228
236
  */
@@ -241,6 +249,10 @@ export interface WorkflowQueue {
241
249
  next<TBody = unknown>(
242
250
  name: string,
243
251
  opts?: WorkflowQueueNextOptions,
252
+ ): Promise<WorkflowQueueMessage<TBody>>;
253
+ nextBatch<TBody = unknown>(
254
+ name: string,
255
+ opts?: WorkflowQueueNextBatchOptions,
244
256
  ): Promise<Array<WorkflowQueueMessage<TBody>>>;
245
257
  send(name: string, body: unknown): Promise<void>;
246
258
  }
@@ -356,13 +368,26 @@ export type LoopResult<S, T> =
356
368
  | { continue: true; state: S }
357
369
  | { break: true; value: T };
358
370
 
371
+ /**
372
+ * Return type for a loop iteration callback.
373
+ *
374
+ * Stateless loops (state = undefined) may return void/undefined, which is treated as
375
+ * `Loop.continue(undefined)`.
376
+ */
377
+ export type LoopIterationResult<S, T> = Promise<
378
+ LoopResult<S, T> | (S extends undefined ? void : never)
379
+ >;
380
+
359
381
  /**
360
382
  * Configuration for a loop.
361
383
  */
362
384
  export interface LoopConfig<S, T> {
363
385
  name: string;
364
386
  state?: S;
365
- run: (ctx: WorkflowContextInterface, state: S) => Promise<LoopResult<S, T>>;
387
+ run: (
388
+ ctx: WorkflowContextInterface,
389
+ state: S,
390
+ ) => LoopIterationResult<S, T>;
366
391
  commitInterval?: number;
367
392
  /** Trim loop history every N iterations. Defaults to commitInterval or 20. */
368
393
  historyEvery?: number;
@@ -397,7 +422,7 @@ export interface WorkflowContextInterface {
397
422
  name: string,
398
423
  run: (
399
424
  ctx: WorkflowContextInterface,
400
- ) => Promise<LoopResult<undefined, T>>,
425
+ ) => LoopIterationResult<undefined, T>,
401
426
  ): Promise<T>;
402
427
  loop<S, T>(config: LoopConfig<S, T>): Promise<T>;
403
428