@rivetkit/workflow-engine 2.3.0-rc.9 → 2.3.1
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-SFJQFMCW.cjs → chunk-GQWOLYBA.cjs} +92 -77
- package/dist/tsup/chunk-GQWOLYBA.cjs.map +1 -0
- package/dist/tsup/{chunk-CIDHCIH7.js → chunk-KA2T56AJ.js} +92 -77
- package/dist/tsup/chunk-KA2T56AJ.js.map +1 -0
- package/dist/tsup/index.cjs +2 -2
- package/dist/tsup/index.d.cts +16 -12
- package/dist/tsup/index.d.ts +16 -12
- 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/schemas/serde.ts +1 -3
- package/src/context.ts +47 -49
- package/src/index.ts +41 -21
- package/src/location.ts +1 -1
- package/src/types.ts +3 -1
- package/dist/tsup/chunk-CIDHCIH7.js.map +0 -1
- package/dist/tsup/chunk-SFJQFMCW.cjs.map +0 -1
|
@@ -1664,30 +1664,6 @@ function setEntry(storage, location, entry) {
|
|
|
1664
1664
|
storage.history.entries.set(key, entry);
|
|
1665
1665
|
}
|
|
1666
1666
|
|
|
1667
|
-
// src/utils.ts
|
|
1668
|
-
function sleep(ms) {
|
|
1669
|
-
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
1670
|
-
}
|
|
1671
|
-
var TIMEOUT_MAX = 2147483647;
|
|
1672
|
-
function setLongTimeout(listener, after) {
|
|
1673
|
-
let timeout;
|
|
1674
|
-
function start(remaining) {
|
|
1675
|
-
if (remaining <= TIMEOUT_MAX) {
|
|
1676
|
-
timeout = setTimeout(listener, remaining);
|
|
1677
|
-
} else {
|
|
1678
|
-
timeout = setTimeout(() => {
|
|
1679
|
-
start(remaining - TIMEOUT_MAX);
|
|
1680
|
-
}, TIMEOUT_MAX);
|
|
1681
|
-
}
|
|
1682
|
-
}
|
|
1683
|
-
start(after);
|
|
1684
|
-
return {
|
|
1685
|
-
abort: () => {
|
|
1686
|
-
if (timeout !== void 0) clearTimeout(timeout);
|
|
1687
|
-
}
|
|
1688
|
-
};
|
|
1689
|
-
}
|
|
1690
|
-
|
|
1691
1667
|
// src/context.ts
|
|
1692
1668
|
var DEFAULT_MAX_RETRIES = 3;
|
|
1693
1669
|
var DEFAULT_RETRY_BACKOFF_BASE = 100;
|
|
@@ -1963,7 +1939,7 @@ var WorkflowContextImpl = (_class = class _WorkflowContextImpl {
|
|
|
1963
1939
|
* Throws HistoryDivergedError if duplicate detected.
|
|
1964
1940
|
*/
|
|
1965
1941
|
checkDuplicateName(name) {
|
|
1966
|
-
const fullKey = locationToKey(this.storage, this.currentLocation)
|
|
1942
|
+
const fullKey = `${locationToKey(this.storage, this.currentLocation)}/${name}`;
|
|
1967
1943
|
if (this.usedNamesInExecution.has(fullKey)) {
|
|
1968
1944
|
throw new HistoryDivergedError(
|
|
1969
1945
|
`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.`
|
|
@@ -2017,7 +1993,7 @@ var WorkflowContextImpl = (_class = class _WorkflowContextImpl {
|
|
|
2017
1993
|
validateComplete() {
|
|
2018
1994
|
const prefix = locationToKey(this.storage, this.currentLocation);
|
|
2019
1995
|
for (const key of this.storage.history.entries.keys()) {
|
|
2020
|
-
const isUnderPrefix = prefix === "" ? true : key.startsWith(prefix
|
|
1996
|
+
const isUnderPrefix = prefix === "" ? true : key.startsWith(`${prefix}/`) || key === prefix;
|
|
2021
1997
|
if (isUnderPrefix) {
|
|
2022
1998
|
if (!this.visitedKeys.has(key)) {
|
|
2023
1999
|
throw new HistoryDivergedError(
|
|
@@ -2034,25 +2010,33 @@ var WorkflowContextImpl = (_class = class _WorkflowContextImpl {
|
|
|
2034
2010
|
this.abortController.abort(new EvictedError());
|
|
2035
2011
|
}
|
|
2036
2012
|
/**
|
|
2037
|
-
* Wait for
|
|
2038
|
-
*
|
|
2039
|
-
*
|
|
2040
|
-
*
|
|
2013
|
+
* Wait for `ms`, rejecting early with EvictedError if the workflow is
|
|
2014
|
+
* evicted. Both the timer and the abort listener are torn down on either
|
|
2015
|
+
* outcome, so a completed sleep never leaves a dangling listener on the
|
|
2016
|
+
* long-lived run abort signal.
|
|
2041
2017
|
*/
|
|
2042
|
-
|
|
2043
|
-
|
|
2044
|
-
|
|
2045
|
-
|
|
2046
|
-
|
|
2018
|
+
async sleepOrEvict(ms) {
|
|
2019
|
+
if (this.abortSignal.aborted) {
|
|
2020
|
+
throw new EvictedError();
|
|
2021
|
+
}
|
|
2022
|
+
let timer;
|
|
2023
|
+
let onAbort;
|
|
2024
|
+
try {
|
|
2025
|
+
await new Promise((resolve, reject) => {
|
|
2026
|
+
timer = setTimeout(resolve, ms);
|
|
2027
|
+
onAbort = () => reject(new EvictedError());
|
|
2028
|
+
this.abortSignal.addEventListener("abort", onAbort, {
|
|
2029
|
+
once: true
|
|
2030
|
+
});
|
|
2031
|
+
});
|
|
2032
|
+
} finally {
|
|
2033
|
+
if (timer !== void 0) {
|
|
2034
|
+
clearTimeout(timer);
|
|
2047
2035
|
}
|
|
2048
|
-
|
|
2049
|
-
"abort",
|
|
2050
|
-
|
|
2051
|
-
|
|
2052
|
-
},
|
|
2053
|
-
{ once: true }
|
|
2054
|
-
);
|
|
2055
|
-
});
|
|
2036
|
+
if (onAbort) {
|
|
2037
|
+
this.abortSignal.removeEventListener("abort", onAbort);
|
|
2038
|
+
}
|
|
2039
|
+
}
|
|
2056
2040
|
}
|
|
2057
2041
|
// === Step ===
|
|
2058
2042
|
async step(nameOrConfig, run) {
|
|
@@ -2201,7 +2185,7 @@ var WorkflowContextImpl = (_class = class _WorkflowContextImpl {
|
|
|
2201
2185
|
}
|
|
2202
2186
|
const maxRetries2 = _nullishCoalesce(config2.maxRetries, () => ( DEFAULT_MAX_RETRIES));
|
|
2203
2187
|
if (metadata2.attempts > maxRetries2) {
|
|
2204
|
-
const lastError =
|
|
2188
|
+
const lastError = metadata2.error;
|
|
2205
2189
|
const exhaustedError = new StepExhaustedError(
|
|
2206
2190
|
config2.name,
|
|
2207
2191
|
lastError
|
|
@@ -2290,14 +2274,13 @@ var WorkflowContextImpl = (_class = class _WorkflowContextImpl {
|
|
|
2290
2274
|
});
|
|
2291
2275
|
return output;
|
|
2292
2276
|
} catch (error) {
|
|
2293
|
-
if (
|
|
2294
|
-
|
|
2295
|
-
|
|
2296
|
-
|
|
2297
|
-
|
|
2277
|
+
if (entry.kind.type === "step") {
|
|
2278
|
+
entry.kind.data.error = String(error);
|
|
2279
|
+
}
|
|
2280
|
+
entry.dirty = true;
|
|
2281
|
+
if (error instanceof StepTimeoutError && !config2.retryOnTimeout) {
|
|
2298
2282
|
metadata.status = "exhausted";
|
|
2299
2283
|
metadata.error = String(error);
|
|
2300
|
-
await this.flushStorage();
|
|
2301
2284
|
await this.notifyStepError(config2, metadata.attempts, error, {
|
|
2302
2285
|
willRetry: false
|
|
2303
2286
|
});
|
|
@@ -2311,13 +2294,8 @@ var WorkflowContextImpl = (_class = class _WorkflowContextImpl {
|
|
|
2311
2294
|
);
|
|
2312
2295
|
}
|
|
2313
2296
|
if (error instanceof CriticalError || error instanceof RollbackError) {
|
|
2314
|
-
if (entry.kind.type === "step") {
|
|
2315
|
-
entry.kind.data.error = String(error);
|
|
2316
|
-
}
|
|
2317
|
-
entry.dirty = true;
|
|
2318
2297
|
metadata.status = "exhausted";
|
|
2319
2298
|
metadata.error = String(error);
|
|
2320
|
-
await this.flushStorage();
|
|
2321
2299
|
await this.notifyStepError(config2, metadata.attempts, error, {
|
|
2322
2300
|
willRetry: false
|
|
2323
2301
|
});
|
|
@@ -2330,14 +2308,9 @@ var WorkflowContextImpl = (_class = class _WorkflowContextImpl {
|
|
|
2330
2308
|
})
|
|
2331
2309
|
);
|
|
2332
2310
|
}
|
|
2333
|
-
if (entry.kind.type === "step") {
|
|
2334
|
-
entry.kind.data.error = String(error);
|
|
2335
|
-
}
|
|
2336
|
-
entry.dirty = true;
|
|
2337
2311
|
const willRetry = metadata.attempts <= maxRetries;
|
|
2338
2312
|
metadata.status = willRetry ? "failed" : "exhausted";
|
|
2339
2313
|
metadata.error = String(error);
|
|
2340
|
-
await this.flushStorage();
|
|
2341
2314
|
if (willRetry) {
|
|
2342
2315
|
const retryDelay = calculateBackoff(
|
|
2343
2316
|
metadata.attempts,
|
|
@@ -2361,7 +2334,7 @@ var WorkflowContextImpl = (_class = class _WorkflowContextImpl {
|
|
|
2361
2334
|
attachTryStepFailure(
|
|
2362
2335
|
new StepExhaustedError(config2.name, String(error)),
|
|
2363
2336
|
{
|
|
2364
|
-
kind: "exhausted",
|
|
2337
|
+
kind: error instanceof StepTimeoutError ? "timeout" : "exhausted",
|
|
2365
2338
|
stepName: config2.name,
|
|
2366
2339
|
attempts: metadata.attempts,
|
|
2367
2340
|
error: extractErrorInfo(error)
|
|
@@ -2379,7 +2352,9 @@ var WorkflowContextImpl = (_class = class _WorkflowContextImpl {
|
|
|
2379
2352
|
*
|
|
2380
2353
|
* Note: This does NOT cancel the underlying operation. JavaScript Promises
|
|
2381
2354
|
* cannot be cancelled once started. When a timeout occurs:
|
|
2382
|
-
* - The step is
|
|
2355
|
+
* - The step is rejected with StepTimeoutError. By default this is treated
|
|
2356
|
+
* as a critical failure with no retry. Set retryOnTimeout: true on the
|
|
2357
|
+
* step config to retry timeouts like any other error.
|
|
2383
2358
|
* - The underlying async operation continues running in the background
|
|
2384
2359
|
* - Any side effects from the operation may still occur
|
|
2385
2360
|
*
|
|
@@ -2704,7 +2679,7 @@ var WorkflowContextImpl = (_class = class _WorkflowContextImpl {
|
|
|
2704
2679
|
return;
|
|
2705
2680
|
}
|
|
2706
2681
|
if (remaining < this.driver.workerPollInterval) {
|
|
2707
|
-
await
|
|
2682
|
+
await this.sleepOrEvict(remaining);
|
|
2708
2683
|
this.checkEvicted();
|
|
2709
2684
|
if (entry.kind.type === "sleep") {
|
|
2710
2685
|
entry.kind.data.state = "completed";
|
|
@@ -3515,6 +3490,30 @@ var WorkflowContextImpl = (_class = class _WorkflowContextImpl {
|
|
|
3515
3490
|
}
|
|
3516
3491
|
}, _class);
|
|
3517
3492
|
|
|
3493
|
+
// src/utils.ts
|
|
3494
|
+
function sleep(ms) {
|
|
3495
|
+
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
3496
|
+
}
|
|
3497
|
+
var TIMEOUT_MAX = 2147483647;
|
|
3498
|
+
function setLongTimeout(listener, after) {
|
|
3499
|
+
let timeout;
|
|
3500
|
+
function start(remaining) {
|
|
3501
|
+
if (remaining <= TIMEOUT_MAX) {
|
|
3502
|
+
timeout = setTimeout(listener, remaining);
|
|
3503
|
+
} else {
|
|
3504
|
+
timeout = setTimeout(() => {
|
|
3505
|
+
start(remaining - TIMEOUT_MAX);
|
|
3506
|
+
}, TIMEOUT_MAX);
|
|
3507
|
+
}
|
|
3508
|
+
}
|
|
3509
|
+
start(after);
|
|
3510
|
+
return {
|
|
3511
|
+
abort: () => {
|
|
3512
|
+
if (timeout !== void 0) clearTimeout(timeout);
|
|
3513
|
+
}
|
|
3514
|
+
};
|
|
3515
|
+
}
|
|
3516
|
+
|
|
3518
3517
|
// src/index.ts
|
|
3519
3518
|
var Loop = {
|
|
3520
3519
|
continue: (state) => ({
|
|
@@ -3738,25 +3737,41 @@ async function executeLiveWorkflow(workflowId, workflowFn, input, driver, messag
|
|
|
3738
3737
|
const hasMessages = result.waitingForMessages !== void 0;
|
|
3739
3738
|
const hasDeadline = result.sleepUntil !== void 0;
|
|
3740
3739
|
if (hasMessages && hasDeadline) {
|
|
3740
|
+
const iterationAbort = new AbortController();
|
|
3741
|
+
const onRunAbort = () => iterationAbort.abort();
|
|
3742
|
+
if (abortController.signal.aborted) {
|
|
3743
|
+
iterationAbort.abort();
|
|
3744
|
+
} else {
|
|
3745
|
+
abortController.signal.addEventListener("abort", onRunAbort, {
|
|
3746
|
+
once: true
|
|
3747
|
+
});
|
|
3748
|
+
}
|
|
3749
|
+
const messagePromise = awaitWithEviction(
|
|
3750
|
+
driver.waitForMessages(
|
|
3751
|
+
result.waitingForMessages,
|
|
3752
|
+
iterationAbort.signal
|
|
3753
|
+
),
|
|
3754
|
+
iterationAbort.signal
|
|
3755
|
+
);
|
|
3756
|
+
const sleepPromise = waitForSleep(
|
|
3757
|
+
runtime,
|
|
3758
|
+
result.sleepUntil,
|
|
3759
|
+
iterationAbort.signal
|
|
3760
|
+
);
|
|
3761
|
+
messagePromise.catch(() => {
|
|
3762
|
+
});
|
|
3763
|
+
sleepPromise.catch(() => {
|
|
3764
|
+
});
|
|
3741
3765
|
try {
|
|
3742
|
-
const messagePromise = awaitWithEviction(
|
|
3743
|
-
driver.waitForMessages(
|
|
3744
|
-
result.waitingForMessages,
|
|
3745
|
-
abortController.signal
|
|
3746
|
-
),
|
|
3747
|
-
abortController.signal
|
|
3748
|
-
);
|
|
3749
|
-
const sleepPromise = waitForSleep(
|
|
3750
|
-
runtime,
|
|
3751
|
-
result.sleepUntil,
|
|
3752
|
-
abortController.signal
|
|
3753
|
-
);
|
|
3754
3766
|
await Promise.race([messagePromise, sleepPromise]);
|
|
3755
3767
|
} catch (error) {
|
|
3756
3768
|
if (error instanceof EvictedError) {
|
|
3757
3769
|
return lastResult;
|
|
3758
3770
|
}
|
|
3759
3771
|
throw error;
|
|
3772
|
+
} finally {
|
|
3773
|
+
iterationAbort.abort();
|
|
3774
|
+
abortController.signal.removeEventListener("abort", onRunAbort);
|
|
3760
3775
|
}
|
|
3761
3776
|
continue;
|
|
3762
3777
|
}
|
|
@@ -4209,5 +4224,5 @@ async function executeWorkflow(workflowId, workflowFn, input, driver, messageDri
|
|
|
4209
4224
|
|
|
4210
4225
|
|
|
4211
4226
|
|
|
4212
|
-
exports.extractErrorInfo = extractErrorInfo; exports.CriticalError = CriticalError; exports.RollbackError = RollbackError; exports.RollbackCheckpointError = RollbackCheckpointError; exports.SleepError = SleepError; exports.MessageWaitError = MessageWaitError; exports.EvictedError = EvictedError; exports.HistoryDivergedError = HistoryDivergedError; exports.StepExhaustedError = StepExhaustedError; exports.StepFailedError = StepFailedError; exports.JoinError = JoinError; exports.RaceError = RaceError; exports.CancelledError = CancelledError; exports.EntryInProgressError = EntryInProgressError; exports.keyStartsWith = keyStartsWith; exports.compareKeys = compareKeys; exports.keyToHex = keyToHex; exports.isLoopIterationMarker = isLoopIterationMarker; exports.registerName = registerName; exports.resolveName = resolveName; exports.locationToKey = locationToKey; exports.appendName = appendName; exports.appendLoopIteration = appendLoopIteration; exports.emptyLocation = emptyLocation; exports.parentLocation = parentLocation; exports.isLocationPrefix = isLocationPrefix; exports.locationsEqual = locationsEqual; exports.createStorage = createStorage; exports.createHistorySnapshot = createHistorySnapshot; exports.generateId = generateId; exports.createEntry = createEntry; exports.getOrCreateMetadata = getOrCreateMetadata; exports.loadStorage = loadStorage; exports.loadMetadata = loadMetadata; exports.flush = flush; exports.deleteEntriesWithPrefix = deleteEntriesWithPrefix; exports.getEntry = getEntry; exports.setEntry = setEntry; exports.
|
|
4213
|
-
//# sourceMappingURL=chunk-
|
|
4227
|
+
exports.extractErrorInfo = extractErrorInfo; exports.CriticalError = CriticalError; exports.RollbackError = RollbackError; exports.RollbackCheckpointError = RollbackCheckpointError; exports.SleepError = SleepError; exports.MessageWaitError = MessageWaitError; exports.EvictedError = EvictedError; exports.HistoryDivergedError = HistoryDivergedError; exports.StepExhaustedError = StepExhaustedError; exports.StepFailedError = StepFailedError; exports.JoinError = JoinError; exports.RaceError = RaceError; exports.CancelledError = CancelledError; exports.EntryInProgressError = EntryInProgressError; exports.keyStartsWith = keyStartsWith; exports.compareKeys = compareKeys; exports.keyToHex = keyToHex; exports.isLoopIterationMarker = isLoopIterationMarker; exports.registerName = registerName; exports.resolveName = resolveName; exports.locationToKey = locationToKey; exports.appendName = appendName; exports.appendLoopIteration = appendLoopIteration; exports.emptyLocation = emptyLocation; exports.parentLocation = parentLocation; exports.isLocationPrefix = isLocationPrefix; exports.locationsEqual = locationsEqual; exports.createStorage = createStorage; exports.createHistorySnapshot = createHistorySnapshot; exports.generateId = generateId; exports.createEntry = createEntry; exports.getOrCreateMetadata = getOrCreateMetadata; exports.loadStorage = loadStorage; exports.loadMetadata = loadMetadata; exports.flush = flush; exports.deleteEntriesWithPrefix = deleteEntriesWithPrefix; exports.getEntry = getEntry; exports.setEntry = setEntry; exports.DEFAULT_MAX_RETRIES = DEFAULT_MAX_RETRIES; exports.DEFAULT_RETRY_BACKOFF_BASE = DEFAULT_RETRY_BACKOFF_BASE; exports.DEFAULT_RETRY_BACKOFF_MAX = DEFAULT_RETRY_BACKOFF_MAX; exports.DEFAULT_LOOP_HISTORY_PRUNE_INTERVAL = DEFAULT_LOOP_HISTORY_PRUNE_INTERVAL; exports.DEFAULT_STEP_TIMEOUT = DEFAULT_STEP_TIMEOUT; exports.WorkflowContextImpl = WorkflowContextImpl; exports.sleep = sleep; exports.Loop = Loop; exports.runWorkflow = runWorkflow; exports.replayWorkflowFromStep = replayWorkflowFromStep;
|
|
4228
|
+
//# sourceMappingURL=chunk-GQWOLYBA.cjs.map
|