@rivetkit/workflow-engine 2.3.0-rc.3 → 2.3.0-rc.5
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/tsup/{chunk-UMFB2AR3.js → chunk-CIDHCIH7.js} +48 -15
- package/dist/tsup/chunk-CIDHCIH7.js.map +1 -0
- package/dist/tsup/{chunk-4SWXLWKL.cjs → chunk-SFJQFMCW.cjs} +48 -15
- package/dist/tsup/chunk-SFJQFMCW.cjs.map +1 -0
- package/dist/tsup/index.cjs +2 -2
- package/dist/tsup/index.d.cts +6 -0
- package/dist/tsup/index.d.ts +6 -0
- package/dist/tsup/index.js +1 -1
- package/dist/tsup/testing.cjs +23 -23
- package/dist/tsup/testing.js +1 -1
- package/package.json +1 -1
- package/src/context.ts +12 -11
- package/src/storage.ts +50 -3
- package/src/types.ts +7 -5
- package/dist/tsup/chunk-4SWXLWKL.cjs.map +0 -1
- package/dist/tsup/chunk-UMFB2AR3.js.map +0 -1
package/dist/tsup/testing.cjs
CHANGED
|
@@ -47,7 +47,7 @@
|
|
|
47
47
|
|
|
48
48
|
|
|
49
49
|
|
|
50
|
-
var
|
|
50
|
+
var _chunkSFJQFMCWcjs = require('./chunk-SFJQFMCW.cjs');
|
|
51
51
|
|
|
52
52
|
// src/testing.ts
|
|
53
53
|
var InMemoryWorkflowMessageDriver = class {
|
|
@@ -97,7 +97,7 @@ var InMemoryWorkflowMessageDriver = class {
|
|
|
97
97
|
}
|
|
98
98
|
async waitForMessages(messageNames, abortSignal) {
|
|
99
99
|
if (abortSignal.aborted) {
|
|
100
|
-
throw new (0,
|
|
100
|
+
throw new (0, _chunkSFJQFMCWcjs.EvictedError)();
|
|
101
101
|
}
|
|
102
102
|
const nameSet = messageNames.length > 0 ? new Set(messageNames) : void 0;
|
|
103
103
|
if (this.#messages.some(
|
|
@@ -118,7 +118,7 @@ var InMemoryWorkflowMessageDriver = class {
|
|
|
118
118
|
},
|
|
119
119
|
abortSignal,
|
|
120
120
|
onAbort: () => {
|
|
121
|
-
waiter.reject(new (0,
|
|
121
|
+
waiter.reject(new (0, _chunkSFJQFMCWcjs.EvictedError)());
|
|
122
122
|
}
|
|
123
123
|
};
|
|
124
124
|
abortSignal.addEventListener("abort", waiter.onAbort, {
|
|
@@ -158,56 +158,56 @@ var InMemoryDriver = (_class = class {constructor() { _class.prototype.__init.ca
|
|
|
158
158
|
__init4() {this.workerPollInterval = 100}
|
|
159
159
|
__init5() {this.messageDriver = this.#inMemoryMessageDriver}
|
|
160
160
|
async get(key) {
|
|
161
|
-
await
|
|
162
|
-
const entry = this.kv.get(
|
|
161
|
+
await _chunkSFJQFMCWcjs.sleep.call(void 0, this.latency);
|
|
162
|
+
const entry = this.kv.get(_chunkSFJQFMCWcjs.keyToHex.call(void 0, key));
|
|
163
163
|
return _nullishCoalesce((entry == null ? void 0 : entry.value), () => ( null));
|
|
164
164
|
}
|
|
165
165
|
async set(key, value) {
|
|
166
|
-
await
|
|
167
|
-
this.kv.set(
|
|
166
|
+
await _chunkSFJQFMCWcjs.sleep.call(void 0, this.latency);
|
|
167
|
+
this.kv.set(_chunkSFJQFMCWcjs.keyToHex.call(void 0, key), { key, value });
|
|
168
168
|
}
|
|
169
169
|
async delete(key) {
|
|
170
|
-
await
|
|
171
|
-
this.kv.delete(
|
|
170
|
+
await _chunkSFJQFMCWcjs.sleep.call(void 0, this.latency);
|
|
171
|
+
this.kv.delete(_chunkSFJQFMCWcjs.keyToHex.call(void 0, key));
|
|
172
172
|
}
|
|
173
173
|
async deletePrefix(prefix) {
|
|
174
|
-
await
|
|
174
|
+
await _chunkSFJQFMCWcjs.sleep.call(void 0, this.latency);
|
|
175
175
|
for (const [hexKey, entry] of this.kv) {
|
|
176
|
-
if (
|
|
176
|
+
if (_chunkSFJQFMCWcjs.keyStartsWith.call(void 0, entry.key, prefix)) {
|
|
177
177
|
this.kv.delete(hexKey);
|
|
178
178
|
}
|
|
179
179
|
}
|
|
180
180
|
}
|
|
181
181
|
async deleteRange(start, end) {
|
|
182
|
-
await
|
|
182
|
+
await _chunkSFJQFMCWcjs.sleep.call(void 0, this.latency);
|
|
183
183
|
for (const [hexKey, entry] of this.kv) {
|
|
184
|
-
if (
|
|
184
|
+
if (_chunkSFJQFMCWcjs.compareKeys.call(void 0, entry.key, start) >= 0 && _chunkSFJQFMCWcjs.compareKeys.call(void 0, entry.key, end) < 0) {
|
|
185
185
|
this.kv.delete(hexKey);
|
|
186
186
|
}
|
|
187
187
|
}
|
|
188
188
|
}
|
|
189
189
|
async list(prefix) {
|
|
190
|
-
await
|
|
190
|
+
await _chunkSFJQFMCWcjs.sleep.call(void 0, this.latency);
|
|
191
191
|
const results = [];
|
|
192
192
|
for (const entry of this.kv.values()) {
|
|
193
|
-
if (
|
|
193
|
+
if (_chunkSFJQFMCWcjs.keyStartsWith.call(void 0, entry.key, prefix)) {
|
|
194
194
|
results.push({ key: entry.key, value: entry.value });
|
|
195
195
|
}
|
|
196
196
|
}
|
|
197
|
-
return results.sort((a, b) =>
|
|
197
|
+
return results.sort((a, b) => _chunkSFJQFMCWcjs.compareKeys.call(void 0, a.key, b.key));
|
|
198
198
|
}
|
|
199
199
|
async batch(writes) {
|
|
200
|
-
await
|
|
200
|
+
await _chunkSFJQFMCWcjs.sleep.call(void 0, this.latency);
|
|
201
201
|
for (const { key, value } of writes) {
|
|
202
|
-
this.kv.set(
|
|
202
|
+
this.kv.set(_chunkSFJQFMCWcjs.keyToHex.call(void 0, key), { key, value });
|
|
203
203
|
}
|
|
204
204
|
}
|
|
205
205
|
async setAlarm(workflowId, wakeAt) {
|
|
206
|
-
await
|
|
206
|
+
await _chunkSFJQFMCWcjs.sleep.call(void 0, this.latency);
|
|
207
207
|
this.alarms.set(workflowId, wakeAt);
|
|
208
208
|
}
|
|
209
209
|
async clearAlarm(workflowId) {
|
|
210
|
-
await
|
|
210
|
+
await _chunkSFJQFMCWcjs.sleep.call(void 0, this.latency);
|
|
211
211
|
this.alarms.delete(workflowId);
|
|
212
212
|
}
|
|
213
213
|
async waitForMessages(messageNames, abortSignal) {
|
|
@@ -218,7 +218,7 @@ var InMemoryDriver = (_class = class {constructor() { _class.prototype.__init.ca
|
|
|
218
218
|
}
|
|
219
219
|
while (true) {
|
|
220
220
|
if (abortSignal.aborted) {
|
|
221
|
-
throw new (0,
|
|
221
|
+
throw new (0, _chunkSFJQFMCWcjs.EvictedError)();
|
|
222
222
|
}
|
|
223
223
|
const messages = await this.messageDriver.receiveMessages({
|
|
224
224
|
names: messageNames.length > 0 ? messageNames : void 0,
|
|
@@ -228,7 +228,7 @@ var InMemoryDriver = (_class = class {constructor() { _class.prototype.__init.ca
|
|
|
228
228
|
if (messages.length > 0) {
|
|
229
229
|
return;
|
|
230
230
|
}
|
|
231
|
-
await
|
|
231
|
+
await _chunkSFJQFMCWcjs.sleep.call(void 0, Math.max(1, this.latency));
|
|
232
232
|
}
|
|
233
233
|
}
|
|
234
234
|
/**
|
|
@@ -324,5 +324,5 @@ var InMemoryDriver = (_class = class {constructor() { _class.prototype.__init.ca
|
|
|
324
324
|
|
|
325
325
|
|
|
326
326
|
|
|
327
|
-
exports.CancelledError =
|
|
327
|
+
exports.CancelledError = _chunkSFJQFMCWcjs.CancelledError; exports.CriticalError = _chunkSFJQFMCWcjs.CriticalError; exports.DEFAULT_LOOP_HISTORY_PRUNE_INTERVAL = _chunkSFJQFMCWcjs.DEFAULT_LOOP_HISTORY_PRUNE_INTERVAL; exports.DEFAULT_MAX_RETRIES = _chunkSFJQFMCWcjs.DEFAULT_MAX_RETRIES; exports.DEFAULT_RETRY_BACKOFF_BASE = _chunkSFJQFMCWcjs.DEFAULT_RETRY_BACKOFF_BASE; exports.DEFAULT_RETRY_BACKOFF_MAX = _chunkSFJQFMCWcjs.DEFAULT_RETRY_BACKOFF_MAX; exports.DEFAULT_STEP_TIMEOUT = _chunkSFJQFMCWcjs.DEFAULT_STEP_TIMEOUT; exports.EntryInProgressError = _chunkSFJQFMCWcjs.EntryInProgressError; exports.EvictedError = _chunkSFJQFMCWcjs.EvictedError; exports.HistoryDivergedError = _chunkSFJQFMCWcjs.HistoryDivergedError; exports.InMemoryDriver = InMemoryDriver; exports.JoinError = _chunkSFJQFMCWcjs.JoinError; exports.Loop = _chunkSFJQFMCWcjs.Loop; exports.MessageWaitError = _chunkSFJQFMCWcjs.MessageWaitError; exports.RaceError = _chunkSFJQFMCWcjs.RaceError; exports.RollbackCheckpointError = _chunkSFJQFMCWcjs.RollbackCheckpointError; exports.RollbackError = _chunkSFJQFMCWcjs.RollbackError; exports.SleepError = _chunkSFJQFMCWcjs.SleepError; exports.StepExhaustedError = _chunkSFJQFMCWcjs.StepExhaustedError; exports.StepFailedError = _chunkSFJQFMCWcjs.StepFailedError; exports.WorkflowContextImpl = _chunkSFJQFMCWcjs.WorkflowContextImpl; exports.appendLoopIteration = _chunkSFJQFMCWcjs.appendLoopIteration; exports.appendName = _chunkSFJQFMCWcjs.appendName; exports.createEntry = _chunkSFJQFMCWcjs.createEntry; exports.createHistorySnapshot = _chunkSFJQFMCWcjs.createHistorySnapshot; exports.createStorage = _chunkSFJQFMCWcjs.createStorage; exports.deleteEntriesWithPrefix = _chunkSFJQFMCWcjs.deleteEntriesWithPrefix; exports.emptyLocation = _chunkSFJQFMCWcjs.emptyLocation; exports.extractErrorInfo = _chunkSFJQFMCWcjs.extractErrorInfo; exports.flush = _chunkSFJQFMCWcjs.flush; exports.generateId = _chunkSFJQFMCWcjs.generateId; exports.getEntry = _chunkSFJQFMCWcjs.getEntry; exports.getOrCreateMetadata = _chunkSFJQFMCWcjs.getOrCreateMetadata; exports.isLocationPrefix = _chunkSFJQFMCWcjs.isLocationPrefix; exports.isLoopIterationMarker = _chunkSFJQFMCWcjs.isLoopIterationMarker; exports.loadMetadata = _chunkSFJQFMCWcjs.loadMetadata; exports.loadStorage = _chunkSFJQFMCWcjs.loadStorage; exports.locationToKey = _chunkSFJQFMCWcjs.locationToKey; exports.locationsEqual = _chunkSFJQFMCWcjs.locationsEqual; exports.parentLocation = _chunkSFJQFMCWcjs.parentLocation; exports.registerName = _chunkSFJQFMCWcjs.registerName; exports.replayWorkflowFromStep = _chunkSFJQFMCWcjs.replayWorkflowFromStep; exports.resolveName = _chunkSFJQFMCWcjs.resolveName; exports.runWorkflow = _chunkSFJQFMCWcjs.runWorkflow; exports.setEntry = _chunkSFJQFMCWcjs.setEntry;
|
|
328
328
|
//# sourceMappingURL=testing.cjs.map
|
package/dist/tsup/testing.js
CHANGED
package/package.json
CHANGED
package/src/context.ts
CHANGED
|
@@ -954,15 +954,12 @@ export class WorkflowContextImpl implements WorkflowContextInterface {
|
|
|
954
954
|
willRetry: false,
|
|
955
955
|
});
|
|
956
956
|
throw markErrorReported(
|
|
957
|
-
attachTryStepFailure(
|
|
958
|
-
|
|
959
|
-
|
|
960
|
-
|
|
961
|
-
|
|
962
|
-
|
|
963
|
-
error: extractErrorInfo(error),
|
|
964
|
-
},
|
|
965
|
-
),
|
|
957
|
+
attachTryStepFailure(new CriticalError(error.message), {
|
|
958
|
+
kind: "timeout",
|
|
959
|
+
stepName: config.name,
|
|
960
|
+
attempts: metadata.attempts,
|
|
961
|
+
error: extractErrorInfo(error),
|
|
962
|
+
}),
|
|
966
963
|
);
|
|
967
964
|
}
|
|
968
965
|
|
|
@@ -1224,8 +1221,12 @@ export class WorkflowContextImpl implements WorkflowContextInterface {
|
|
|
1224
1221
|
}
|
|
1225
1222
|
|
|
1226
1223
|
const historyPruneInterval =
|
|
1227
|
-
config.historyPruneInterval ??
|
|
1228
|
-
|
|
1224
|
+
config.historyPruneInterval ??
|
|
1225
|
+
config.commitInterval ??
|
|
1226
|
+
config.historyEvery ??
|
|
1227
|
+
DEFAULT_LOOP_HISTORY_PRUNE_INTERVAL;
|
|
1228
|
+
const historySize =
|
|
1229
|
+
config.historySize ?? config.historyKeep ?? historyPruneInterval;
|
|
1229
1230
|
|
|
1230
1231
|
// Track the last iteration we pruned up to so we only delete
|
|
1231
1232
|
// newly-expired iterations instead of re-scanning from 0.
|
package/src/storage.ts
CHANGED
|
@@ -40,6 +40,9 @@ import type {
|
|
|
40
40
|
WorkflowHistorySnapshot,
|
|
41
41
|
} from "./types.js";
|
|
42
42
|
|
|
43
|
+
export const MAX_KV_BATCH_ENTRIES = 128;
|
|
44
|
+
export const MAX_KV_BATCH_PAYLOAD_BYTES = 976 * 1024;
|
|
45
|
+
|
|
43
46
|
/**
|
|
44
47
|
* Create an empty storage instance.
|
|
45
48
|
*/
|
|
@@ -238,6 +241,8 @@ export async function flush(
|
|
|
238
241
|
pendingDeletions?: PendingDeletions,
|
|
239
242
|
): Promise<void> {
|
|
240
243
|
const writes: KVWrite[] = [];
|
|
244
|
+
const dirtyEntries: Entry[] = [];
|
|
245
|
+
const dirtyMetadata: EntryMetadata[] = [];
|
|
241
246
|
let historyUpdated = false;
|
|
242
247
|
|
|
243
248
|
// Flush only new names (those added since last flush)
|
|
@@ -263,7 +268,7 @@ export async function flush(
|
|
|
263
268
|
key: buildHistoryKey(entry.location),
|
|
264
269
|
value: serializeEntry(entry),
|
|
265
270
|
});
|
|
266
|
-
entry
|
|
271
|
+
dirtyEntries.push(entry);
|
|
267
272
|
historyUpdated = true;
|
|
268
273
|
}
|
|
269
274
|
}
|
|
@@ -275,7 +280,7 @@ export async function flush(
|
|
|
275
280
|
key: buildEntryMetadataKey(id),
|
|
276
281
|
value: serializeEntryMetadata(metadata),
|
|
277
282
|
});
|
|
278
|
-
metadata
|
|
283
|
+
dirtyMetadata.push(metadata);
|
|
279
284
|
historyUpdated = true;
|
|
280
285
|
}
|
|
281
286
|
}
|
|
@@ -313,7 +318,9 @@ export async function flush(
|
|
|
313
318
|
}
|
|
314
319
|
|
|
315
320
|
if (writes.length > 0) {
|
|
316
|
-
|
|
321
|
+
for (const chunk of splitBatchWrites(writes)) {
|
|
322
|
+
await driver.batch(chunk);
|
|
323
|
+
}
|
|
317
324
|
}
|
|
318
325
|
|
|
319
326
|
// Apply pending deletions after the batch write. These are collected
|
|
@@ -336,6 +343,12 @@ export async function flush(
|
|
|
336
343
|
}
|
|
337
344
|
|
|
338
345
|
// Update flushed tracking after successful write
|
|
346
|
+
for (const entry of dirtyEntries) {
|
|
347
|
+
entry.dirty = false;
|
|
348
|
+
}
|
|
349
|
+
for (const metadata of dirtyMetadata) {
|
|
350
|
+
metadata.dirty = false;
|
|
351
|
+
}
|
|
339
352
|
storage.flushedNameCount = storage.nameRegistry.length;
|
|
340
353
|
storage.flushedState = storage.state;
|
|
341
354
|
storage.flushedOutput = storage.output;
|
|
@@ -346,6 +359,40 @@ export async function flush(
|
|
|
346
359
|
}
|
|
347
360
|
}
|
|
348
361
|
|
|
362
|
+
function splitBatchWrites(writes: KVWrite[]): KVWrite[][] {
|
|
363
|
+
const chunks: KVWrite[][] = [];
|
|
364
|
+
let chunk: KVWrite[] = [];
|
|
365
|
+
let chunkBytes = 0;
|
|
366
|
+
|
|
367
|
+
for (const write of writes) {
|
|
368
|
+
const writeBytes = write.key.byteLength + write.value.byteLength;
|
|
369
|
+
if (writeBytes > MAX_KV_BATCH_PAYLOAD_BYTES) {
|
|
370
|
+
throw new Error(
|
|
371
|
+
`KV batch write is ${writeBytes} bytes, exceeding the ${MAX_KV_BATCH_PAYLOAD_BYTES} byte limit`,
|
|
372
|
+
);
|
|
373
|
+
}
|
|
374
|
+
|
|
375
|
+
if (
|
|
376
|
+
chunk.length >= MAX_KV_BATCH_ENTRIES ||
|
|
377
|
+
(chunk.length > 0 &&
|
|
378
|
+
chunkBytes + writeBytes > MAX_KV_BATCH_PAYLOAD_BYTES)
|
|
379
|
+
) {
|
|
380
|
+
chunks.push(chunk);
|
|
381
|
+
chunk = [];
|
|
382
|
+
chunkBytes = 0;
|
|
383
|
+
}
|
|
384
|
+
|
|
385
|
+
chunk.push(write);
|
|
386
|
+
chunkBytes += writeBytes;
|
|
387
|
+
}
|
|
388
|
+
|
|
389
|
+
if (chunk.length > 0) {
|
|
390
|
+
chunks.push(chunk);
|
|
391
|
+
}
|
|
392
|
+
|
|
393
|
+
return chunks;
|
|
394
|
+
}
|
|
395
|
+
|
|
349
396
|
/**
|
|
350
397
|
* Delete entries with a given location prefix (used for loop forgetting).
|
|
351
398
|
* Also cleans up associated metadata from both memory and driver.
|
package/src/types.ts
CHANGED
|
@@ -422,11 +422,7 @@ export interface TryStepConfig<T> extends StepConfig<T> {
|
|
|
422
422
|
catch?: readonly TryStepCatchKind[];
|
|
423
423
|
}
|
|
424
424
|
|
|
425
|
-
export type TryBlockCatchKind =
|
|
426
|
-
| "step"
|
|
427
|
-
| "join"
|
|
428
|
-
| "race"
|
|
429
|
-
| "rollback";
|
|
425
|
+
export type TryBlockCatchKind = "step" | "join" | "race" | "rollback";
|
|
430
426
|
|
|
431
427
|
export interface TryBlockFailure {
|
|
432
428
|
source: "step" | "join" | "race" | "block";
|
|
@@ -473,6 +469,12 @@ export interface LoopConfig<S, T> {
|
|
|
473
469
|
historyPruneInterval?: number;
|
|
474
470
|
/** Number of past iterations to retain when pruning. Defaults to historyPruneInterval. */
|
|
475
471
|
historySize?: number;
|
|
472
|
+
/** @deprecated Use historyPruneInterval. */
|
|
473
|
+
commitInterval?: number;
|
|
474
|
+
/** @deprecated Use historyPruneInterval. */
|
|
475
|
+
historyEvery?: number;
|
|
476
|
+
/** @deprecated Use historySize. */
|
|
477
|
+
historyKeep?: number;
|
|
476
478
|
}
|
|
477
479
|
|
|
478
480
|
/**
|