@upstash/workflow 0.2.15 → 0.2.17
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/astro.d.mts +2 -2
- package/astro.d.ts +2 -2
- package/astro.js +178 -36
- package/astro.mjs +1 -1
- package/{chunk-AC5CQCN3.mjs → chunk-RP7G4UD5.mjs} +178 -36
- package/cloudflare.d.mts +2 -2
- package/cloudflare.d.ts +2 -2
- package/cloudflare.js +178 -36
- package/cloudflare.mjs +1 -1
- package/express.d.mts +2 -2
- package/express.d.ts +2 -2
- package/express.js +7060 -7193
- package/express.mjs +6706 -6981
- package/h3.d.mts +2 -2
- package/h3.d.ts +2 -2
- package/h3.js +178 -36
- package/h3.mjs +1 -1
- package/hono.d.mts +2 -2
- package/hono.d.ts +2 -2
- package/hono.js +178 -36
- package/hono.mjs +1 -1
- package/index.d.mts +115 -11
- package/index.d.ts +115 -11
- package/index.js +186 -35
- package/index.mjs +17 -2
- package/nextjs.d.mts +2 -2
- package/nextjs.d.ts +2 -2
- package/nextjs.js +181 -36
- package/nextjs.mjs +4 -1
- package/package.json +1 -1
- package/{serve-many-AaKSQyi7.d.ts → serve-many-B3DfoTFt.d.ts} +1 -1
- package/{serve-many-AFwJPR3S.d.mts → serve-many-DgDSOvQs.d.mts} +1 -1
- package/solidjs.d.mts +1 -1
- package/solidjs.d.ts +1 -1
- package/solidjs.js +170 -34
- package/solidjs.mjs +1 -1
- package/svelte.d.mts +2 -2
- package/svelte.d.ts +2 -2
- package/svelte.js +178 -36
- package/svelte.mjs +1 -1
- package/{types-Dd-3bPoU.d.ts → types--R_3XZXz.d.mts} +101 -14
- package/{types-Dd-3bPoU.d.mts → types--R_3XZXz.d.ts} +101 -14
package/index.js
CHANGED
|
@@ -104,7 +104,7 @@ var WORKFLOW_PROTOCOL_VERSION_HEADER = "Upstash-Workflow-Sdk-Version";
|
|
|
104
104
|
var DEFAULT_CONTENT_TYPE = "application/json";
|
|
105
105
|
var NO_CONCURRENCY = 1;
|
|
106
106
|
var DEFAULT_RETRIES = 3;
|
|
107
|
-
var VERSION = "v0.2.
|
|
107
|
+
var VERSION = "v0.2.17";
|
|
108
108
|
var SDK_TELEMETRY = `@upstash/workflow@${VERSION}`;
|
|
109
109
|
var TELEMETRY_HEADER_SDK = "Upstash-Telemetry-Sdk";
|
|
110
110
|
var TELEMETRY_HEADER_FRAMEWORK = "Upstash-Telemetry-Framework";
|
|
@@ -634,6 +634,7 @@ var triggerFirstInvocation = async (params) => {
|
|
|
634
634
|
workflowUrl: workflowContext.url,
|
|
635
635
|
failureUrl: workflowContext.failureUrl,
|
|
636
636
|
retries: workflowContext.retries,
|
|
637
|
+
retryDelay: workflowContext.retryDelay,
|
|
637
638
|
telemetry,
|
|
638
639
|
flowControl: workflowContext.flowControl,
|
|
639
640
|
useJSONContent: useJSONContent ?? false
|
|
@@ -763,6 +764,7 @@ var handleThirdPartyCallResult = async ({
|
|
|
763
764
|
workflowUrl,
|
|
764
765
|
failureUrl,
|
|
765
766
|
retries,
|
|
767
|
+
retryDelay,
|
|
766
768
|
telemetry,
|
|
767
769
|
flowControl,
|
|
768
770
|
debug
|
|
@@ -833,6 +835,7 @@ ${atob(callbackMessage.body ?? "")}`
|
|
|
833
835
|
workflowUrl,
|
|
834
836
|
failureUrl,
|
|
835
837
|
retries,
|
|
838
|
+
retryDelay,
|
|
836
839
|
telemetry,
|
|
837
840
|
flowControl
|
|
838
841
|
},
|
|
@@ -983,7 +986,8 @@ var BaseLazyStep = class _BaseLazyStep {
|
|
|
983
986
|
workflowRunId: context.workflowRunId,
|
|
984
987
|
workflowUrl: context.url,
|
|
985
988
|
failureUrl: context.failureUrl,
|
|
986
|
-
retries: context.retries,
|
|
989
|
+
retries: DEFAULT_RETRIES === context.retries ? void 0 : context.retries,
|
|
990
|
+
retryDelay: context.retryDelay,
|
|
987
991
|
useJSONContent: false,
|
|
988
992
|
telemetry,
|
|
989
993
|
flowControl: context.flowControl
|
|
@@ -1002,6 +1006,9 @@ var BaseLazyStep = class _BaseLazyStep {
|
|
|
1002
1006
|
body,
|
|
1003
1007
|
headers,
|
|
1004
1008
|
method: "POST",
|
|
1009
|
+
retries: DEFAULT_RETRIES === context.retries ? void 0 : context.retries,
|
|
1010
|
+
retryDelay: context.retryDelay,
|
|
1011
|
+
flowControl: context.flowControl,
|
|
1005
1012
|
url: context.url
|
|
1006
1013
|
}
|
|
1007
1014
|
]);
|
|
@@ -1072,6 +1079,9 @@ var LazySleepStep = class extends BaseLazyStep {
|
|
|
1072
1079
|
headers,
|
|
1073
1080
|
method: "POST",
|
|
1074
1081
|
url: context.url,
|
|
1082
|
+
retries: DEFAULT_RETRIES === context.retries ? void 0 : context.retries,
|
|
1083
|
+
retryDelay: context.retryDelay,
|
|
1084
|
+
flowControl: context.flowControl,
|
|
1075
1085
|
delay: isParallel ? void 0 : this.sleep
|
|
1076
1086
|
}
|
|
1077
1087
|
]);
|
|
@@ -1114,6 +1124,9 @@ var LazySleepUntilStep = class extends BaseLazyStep {
|
|
|
1114
1124
|
headers,
|
|
1115
1125
|
method: "POST",
|
|
1116
1126
|
url: context.url,
|
|
1127
|
+
retries: DEFAULT_RETRIES === context.retries ? void 0 : context.retries,
|
|
1128
|
+
retryDelay: context.retryDelay,
|
|
1129
|
+
flowControl: context.flowControl,
|
|
1117
1130
|
notBefore: isParallel ? void 0 : this.sleepUntil
|
|
1118
1131
|
}
|
|
1119
1132
|
]);
|
|
@@ -1125,17 +1138,19 @@ var LazyCallStep = class _LazyCallStep extends BaseLazyStep {
|
|
|
1125
1138
|
body;
|
|
1126
1139
|
headers;
|
|
1127
1140
|
retries;
|
|
1141
|
+
retryDelay;
|
|
1128
1142
|
timeout;
|
|
1129
1143
|
flowControl;
|
|
1130
1144
|
stepType = "Call";
|
|
1131
1145
|
allowUndefinedOut = false;
|
|
1132
|
-
constructor(stepName, url, method, body, headers, retries, timeout, flowControl) {
|
|
1146
|
+
constructor(stepName, url, method, body, headers, retries, retryDelay, timeout, flowControl) {
|
|
1133
1147
|
super(stepName);
|
|
1134
1148
|
this.url = url;
|
|
1135
1149
|
this.method = method;
|
|
1136
1150
|
this.body = body;
|
|
1137
1151
|
this.headers = headers;
|
|
1138
1152
|
this.retries = retries;
|
|
1153
|
+
this.retryDelay = retryDelay;
|
|
1139
1154
|
this.timeout = timeout;
|
|
1140
1155
|
this.flowControl = flowControl;
|
|
1141
1156
|
}
|
|
@@ -1210,6 +1225,9 @@ var LazyCallStep = class _LazyCallStep extends BaseLazyStep {
|
|
|
1210
1225
|
getHeaders({ context, telemetry, invokeCount, step }) {
|
|
1211
1226
|
const { headers, contentType } = super.getHeaders({ context, telemetry, invokeCount, step });
|
|
1212
1227
|
headers["Upstash-Retries"] = this.retries.toString();
|
|
1228
|
+
if (this.retryDelay) {
|
|
1229
|
+
headers["Upstash-Retry-Delay"] = this.retryDelay;
|
|
1230
|
+
}
|
|
1213
1231
|
headers[WORKFLOW_FEATURE_HEADER] = "WF_NoDelete,InitialBody";
|
|
1214
1232
|
if (this.flowControl) {
|
|
1215
1233
|
const { flowControlKey, flowControlValue } = prepareFlowControl(this.flowControl);
|
|
@@ -1231,7 +1249,7 @@ var LazyCallStep = class _LazyCallStep extends BaseLazyStep {
|
|
|
1231
1249
|
"Upstash-Callback-Workflow-CallType": "fromCallback",
|
|
1232
1250
|
"Upstash-Callback-Workflow-Init": "false",
|
|
1233
1251
|
"Upstash-Callback-Workflow-Url": context.url,
|
|
1234
|
-
"Upstash-Callback-Feature-Set": "LazyFetch,InitialBody",
|
|
1252
|
+
"Upstash-Callback-Feature-Set": "LazyFetch,InitialBody,WF_DetectTrigger",
|
|
1235
1253
|
"Upstash-Callback-Forward-Upstash-Workflow-Callback": "true",
|
|
1236
1254
|
"Upstash-Callback-Forward-Upstash-Workflow-StepId": step.stepId.toString(),
|
|
1237
1255
|
"Upstash-Callback-Forward-Upstash-Workflow-StepName": this.stepName,
|
|
@@ -1249,7 +1267,10 @@ var LazyCallStep = class _LazyCallStep extends BaseLazyStep {
|
|
|
1249
1267
|
headers,
|
|
1250
1268
|
body: JSON.stringify(this.body),
|
|
1251
1269
|
method: this.method,
|
|
1252
|
-
url: this.url
|
|
1270
|
+
url: this.url,
|
|
1271
|
+
retries: DEFAULT_RETRIES === this.retries ? void 0 : this.retries,
|
|
1272
|
+
retryDelay: this.retryDelay,
|
|
1273
|
+
flowControl: this.flowControl
|
|
1253
1274
|
}
|
|
1254
1275
|
]);
|
|
1255
1276
|
}
|
|
@@ -1378,6 +1399,7 @@ var LazyInvokeStep = class extends BaseLazyStep {
|
|
|
1378
1399
|
headers = {},
|
|
1379
1400
|
workflowRunId,
|
|
1380
1401
|
retries,
|
|
1402
|
+
retryDelay,
|
|
1381
1403
|
flowControl
|
|
1382
1404
|
}) {
|
|
1383
1405
|
super(stepName);
|
|
@@ -1387,6 +1409,7 @@ var LazyInvokeStep = class extends BaseLazyStep {
|
|
|
1387
1409
|
headers,
|
|
1388
1410
|
workflowRunId: getWorkflowRunId(workflowRunId),
|
|
1389
1411
|
retries,
|
|
1412
|
+
retryDelay,
|
|
1390
1413
|
flowControl
|
|
1391
1414
|
};
|
|
1392
1415
|
const { workflowId } = workflow;
|
|
@@ -1431,6 +1454,7 @@ var LazyInvokeStep = class extends BaseLazyStep {
|
|
|
1431
1454
|
workflowUrl: context.url,
|
|
1432
1455
|
failureUrl: context.failureUrl,
|
|
1433
1456
|
retries: context.retries,
|
|
1457
|
+
retryDelay: context.retryDelay,
|
|
1434
1458
|
telemetry,
|
|
1435
1459
|
flowControl: context.flowControl,
|
|
1436
1460
|
useJSONContent: false
|
|
@@ -1456,11 +1480,13 @@ var LazyInvokeStep = class extends BaseLazyStep {
|
|
|
1456
1480
|
headers = {},
|
|
1457
1481
|
workflowRunId = getWorkflowRunId(),
|
|
1458
1482
|
retries,
|
|
1483
|
+
retryDelay,
|
|
1459
1484
|
flowControl
|
|
1460
1485
|
} = this.params;
|
|
1461
1486
|
const newUrl = context.url.replace(/[^/]+$/, this.workflowId);
|
|
1462
1487
|
const {
|
|
1463
1488
|
retries: workflowRetries,
|
|
1489
|
+
retryDelay: workflowRetryDelay,
|
|
1464
1490
|
failureFunction,
|
|
1465
1491
|
failureUrl,
|
|
1466
1492
|
useJSONContent,
|
|
@@ -1472,6 +1498,7 @@ var LazyInvokeStep = class extends BaseLazyStep {
|
|
|
1472
1498
|
workflowRunId,
|
|
1473
1499
|
workflowUrl: newUrl,
|
|
1474
1500
|
retries: retries ?? workflowRetries,
|
|
1501
|
+
retryDelay: retryDelay ?? workflowRetryDelay,
|
|
1475
1502
|
telemetry,
|
|
1476
1503
|
failureUrl: failureFunction ? newUrl : failureUrl,
|
|
1477
1504
|
flowControl: flowControl ?? workflowFlowControl,
|
|
@@ -1538,6 +1565,7 @@ var WorkflowHeaders = class {
|
|
|
1538
1565
|
getHeaders() {
|
|
1539
1566
|
this.addBaseHeaders();
|
|
1540
1567
|
this.addRetries();
|
|
1568
|
+
this.addRetryDelay();
|
|
1541
1569
|
this.addFlowControl();
|
|
1542
1570
|
this.addUserHeaders();
|
|
1543
1571
|
this.addInvokeCount();
|
|
@@ -1551,7 +1579,7 @@ var WorkflowHeaders = class {
|
|
|
1551
1579
|
[WORKFLOW_INIT_HEADER]: this.initHeaderValue,
|
|
1552
1580
|
[WORKFLOW_ID_HEADER]: this.workflowConfig.workflowRunId,
|
|
1553
1581
|
[WORKFLOW_URL_HEADER]: this.workflowConfig.workflowUrl,
|
|
1554
|
-
[WORKFLOW_FEATURE_HEADER]: "LazyFetch,InitialBody",
|
|
1582
|
+
[WORKFLOW_FEATURE_HEADER]: "LazyFetch,InitialBody,WF_DetectTrigger",
|
|
1555
1583
|
[WORKFLOW_PROTOCOL_VERSION_HEADER]: WORKFLOW_PROTOCOL_VERSION,
|
|
1556
1584
|
...this.workflowConfig.telemetry ? getTelemetryHeaders(this.workflowConfig.telemetry) : {},
|
|
1557
1585
|
...this.workflowConfig.telemetry && this.stepInfo?.lazyStep instanceof LazyCallStep && this.stepInfo.lazyStep.headers[AGENT_NAME_HEADER] ? { [TELEMETRY_HEADER_AGENT]: "true" } : {}
|
|
@@ -1583,6 +1611,16 @@ var WorkflowHeaders = class {
|
|
|
1583
1611
|
this.headers.failureHeaders["Retries"] = retries;
|
|
1584
1612
|
}
|
|
1585
1613
|
}
|
|
1614
|
+
addRetryDelay() {
|
|
1615
|
+
if (this.workflowConfig.retryDelay === void 0 || this.workflowConfig.retryDelay === "") {
|
|
1616
|
+
return;
|
|
1617
|
+
}
|
|
1618
|
+
const retryDelay = this.workflowConfig.retryDelay.toString();
|
|
1619
|
+
this.headers.workflowHeaders["Retry-Delay"] = retryDelay;
|
|
1620
|
+
if (this.workflowConfig.failureUrl) {
|
|
1621
|
+
this.headers.failureHeaders["Retry-Delay"] = retryDelay;
|
|
1622
|
+
}
|
|
1623
|
+
}
|
|
1586
1624
|
addFlowControl() {
|
|
1587
1625
|
if (!this.workflowConfig.flowControl) {
|
|
1588
1626
|
return;
|
|
@@ -1617,10 +1655,13 @@ var WorkflowHeaders = class {
|
|
|
1617
1655
|
this.headers.failureHeaders["Workflow-Init"] = "false";
|
|
1618
1656
|
this.headers.failureHeaders["Workflow-Url"] = this.workflowConfig.workflowUrl;
|
|
1619
1657
|
this.headers.failureHeaders["Workflow-Calltype"] = "failureCall";
|
|
1620
|
-
this.headers.failureHeaders["Feature-Set"] = "LazyFetch,InitialBody";
|
|
1658
|
+
this.headers.failureHeaders["Feature-Set"] = "LazyFetch,InitialBody,WF_DetectTrigger";
|
|
1621
1659
|
if (this.workflowConfig.retries !== void 0 && this.workflowConfig.retries !== DEFAULT_RETRIES) {
|
|
1622
1660
|
this.headers.failureHeaders["Retries"] = this.workflowConfig.retries.toString();
|
|
1623
1661
|
}
|
|
1662
|
+
if (this.workflowConfig.retryDelay !== void 0 && this.workflowConfig.retryDelay !== "") {
|
|
1663
|
+
this.headers.failureHeaders["Retry-Delay"] = this.workflowConfig.retryDelay.toString();
|
|
1664
|
+
}
|
|
1624
1665
|
}
|
|
1625
1666
|
addContentType() {
|
|
1626
1667
|
if (this.workflowConfig.useJSONContent) {
|
|
@@ -1702,6 +1743,7 @@ var submitParallelSteps = async ({
|
|
|
1702
1743
|
workflowUrl: context.url,
|
|
1703
1744
|
failureUrl: context.failureUrl,
|
|
1704
1745
|
retries: context.retries,
|
|
1746
|
+
retryDelay: context.retryDelay,
|
|
1705
1747
|
flowControl: context.flowControl,
|
|
1706
1748
|
telemetry
|
|
1707
1749
|
},
|
|
@@ -2122,7 +2164,7 @@ var BaseWorkflowApi = class {
|
|
|
2122
2164
|
*/
|
|
2123
2165
|
async callApi(stepName, settings) {
|
|
2124
2166
|
const { url, appendHeaders, method } = getProviderInfo(settings.api);
|
|
2125
|
-
const { method: userMethod, body, headers = {}, retries = 0, timeout } = settings;
|
|
2167
|
+
const { method: userMethod, body, headers = {}, retries = 0, retryDelay, timeout } = settings;
|
|
2126
2168
|
return await this.context.call(stepName, {
|
|
2127
2169
|
url,
|
|
2128
2170
|
method: userMethod ?? method,
|
|
@@ -2132,6 +2174,7 @@ var BaseWorkflowApi = class {
|
|
|
2132
2174
|
...headers
|
|
2133
2175
|
},
|
|
2134
2176
|
retries,
|
|
2177
|
+
retryDelay,
|
|
2135
2178
|
timeout
|
|
2136
2179
|
});
|
|
2137
2180
|
}
|
|
@@ -2221,6 +2264,7 @@ var fetchWithContextCall = async (context, agentCallParams, ...params) => {
|
|
|
2221
2264
|
body,
|
|
2222
2265
|
timeout: agentCallParams?.timeout,
|
|
2223
2266
|
retries: agentCallParams?.retries,
|
|
2267
|
+
retryDelay: agentCallParams?.retryDelay,
|
|
2224
2268
|
flowControl: agentCallParams?.flowControl
|
|
2225
2269
|
});
|
|
2226
2270
|
const responseHeaders = new Headers(
|
|
@@ -2665,6 +2709,37 @@ var WorkflowContext = class {
|
|
|
2665
2709
|
* Number of retries
|
|
2666
2710
|
*/
|
|
2667
2711
|
retries;
|
|
2712
|
+
/**
|
|
2713
|
+
* Delay between retries.
|
|
2714
|
+
*
|
|
2715
|
+
* By default, the `retryDelay` is exponential backoff.
|
|
2716
|
+
* More details can be found in: https://upstash.com/docs/qstash/features/retry.
|
|
2717
|
+
*
|
|
2718
|
+
* The `retryDelay` option allows you to customize the delay (in milliseconds) between retry attempts when message delivery fails.
|
|
2719
|
+
*
|
|
2720
|
+
* You can use mathematical expressions and the following built-in functions to calculate the delay dynamically.
|
|
2721
|
+
* The special variable `retried` represents the current retry attempt count (starting from 0).
|
|
2722
|
+
*
|
|
2723
|
+
* Supported functions:
|
|
2724
|
+
* - `pow`
|
|
2725
|
+
* - `sqrt`
|
|
2726
|
+
* - `abs`
|
|
2727
|
+
* - `exp`
|
|
2728
|
+
* - `floor`
|
|
2729
|
+
* - `ceil`
|
|
2730
|
+
* - `round`
|
|
2731
|
+
* - `min`
|
|
2732
|
+
* - `max`
|
|
2733
|
+
*
|
|
2734
|
+
* Examples of valid `retryDelay` values:
|
|
2735
|
+
* ```ts
|
|
2736
|
+
* 1000 // 1 second
|
|
2737
|
+
* 1000 * (1 + retried) // 1 second multiplied by the current retry attempt
|
|
2738
|
+
* pow(2, retried) // 2 to the power of the current retry attempt
|
|
2739
|
+
* max(10, pow(2, retried)) // The greater of 10 or 2^retried
|
|
2740
|
+
* ```
|
|
2741
|
+
*/
|
|
2742
|
+
retryDelay;
|
|
2668
2743
|
/**
|
|
2669
2744
|
* Settings for controlling the number of active requests
|
|
2670
2745
|
* and number of requests per second with the same key.
|
|
@@ -2681,6 +2756,7 @@ var WorkflowContext = class {
|
|
|
2681
2756
|
initialPayload,
|
|
2682
2757
|
env,
|
|
2683
2758
|
retries,
|
|
2759
|
+
retryDelay,
|
|
2684
2760
|
telemetry,
|
|
2685
2761
|
invokeCount,
|
|
2686
2762
|
flowControl
|
|
@@ -2694,6 +2770,7 @@ var WorkflowContext = class {
|
|
|
2694
2770
|
this.requestPayload = initialPayload;
|
|
2695
2771
|
this.env = env ?? {};
|
|
2696
2772
|
this.retries = retries ?? DEFAULT_RETRIES;
|
|
2773
|
+
this.retryDelay = retryDelay;
|
|
2697
2774
|
this.flowControl = flowControl;
|
|
2698
2775
|
this.executor = new AutoExecutor(this, this.steps, telemetry, invokeCount, debug);
|
|
2699
2776
|
}
|
|
@@ -2775,6 +2852,7 @@ var WorkflowContext = class {
|
|
|
2775
2852
|
settings.body,
|
|
2776
2853
|
settings.headers || {},
|
|
2777
2854
|
settings.retries || 0,
|
|
2855
|
+
settings.retryDelay,
|
|
2778
2856
|
settings.timeout,
|
|
2779
2857
|
settings.flowControl ?? settings.workflow.options.flowControl
|
|
2780
2858
|
);
|
|
@@ -2785,6 +2863,7 @@ var WorkflowContext = class {
|
|
|
2785
2863
|
body,
|
|
2786
2864
|
headers = {},
|
|
2787
2865
|
retries = 0,
|
|
2866
|
+
retryDelay,
|
|
2788
2867
|
timeout,
|
|
2789
2868
|
flowControl
|
|
2790
2869
|
} = settings;
|
|
@@ -2795,6 +2874,7 @@ var WorkflowContext = class {
|
|
|
2795
2874
|
body,
|
|
2796
2875
|
headers,
|
|
2797
2876
|
retries,
|
|
2877
|
+
retryDelay,
|
|
2798
2878
|
timeout,
|
|
2799
2879
|
flowControl
|
|
2800
2880
|
);
|
|
@@ -2805,7 +2885,7 @@ var WorkflowContext = class {
|
|
|
2805
2885
|
* Pauses workflow execution until a specific event occurs or a timeout is reached.
|
|
2806
2886
|
*
|
|
2807
2887
|
*```ts
|
|
2808
|
-
* const result = await workflow.waitForEvent("payment-confirmed", {
|
|
2888
|
+
* const result = await workflow.waitForEvent("payment-confirmed", "payment.confirmed", {
|
|
2809
2889
|
* timeout: "5m"
|
|
2810
2890
|
* });
|
|
2811
2891
|
*```
|
|
@@ -2831,7 +2911,7 @@ var WorkflowContext = class {
|
|
|
2831
2911
|
* @param stepName
|
|
2832
2912
|
* @param eventId - Unique identifier for the event to wait for
|
|
2833
2913
|
* @param options - Configuration options.
|
|
2834
|
-
* @returns `{ timeout: boolean, eventData:
|
|
2914
|
+
* @returns `{ timeout: boolean, eventData: TEventData }`.
|
|
2835
2915
|
* The `timeout` property specifies if the workflow has timed out. The `eventData`
|
|
2836
2916
|
* is the data passed when notifying this workflow of an event.
|
|
2837
2917
|
*/
|
|
@@ -2991,6 +3071,7 @@ var DisabledWorkflowContext = class _DisabledWorkflowContext extends WorkflowCon
|
|
|
2991
3071
|
initialPayload: context.requestPayload,
|
|
2992
3072
|
env: context.env,
|
|
2993
3073
|
retries: context.retries,
|
|
3074
|
+
retryDelay: context.retryDelay,
|
|
2994
3075
|
flowControl: context.flowControl
|
|
2995
3076
|
});
|
|
2996
3077
|
try {
|
|
@@ -2999,6 +3080,9 @@ var DisabledWorkflowContext = class _DisabledWorkflowContext extends WorkflowCon
|
|
|
2999
3080
|
if (error instanceof WorkflowAbort && error.stepName === this.disabledMessage || error instanceof WorkflowNonRetryableError) {
|
|
3000
3081
|
return ok("step-found");
|
|
3001
3082
|
}
|
|
3083
|
+
console.warn(
|
|
3084
|
+
"Upstash Workflow: Received an error while authorizing request. Please avoid throwing errors before the first step of your workflow."
|
|
3085
|
+
);
|
|
3002
3086
|
return err(error);
|
|
3003
3087
|
}
|
|
3004
3088
|
return ok("run-ended");
|
|
@@ -3140,9 +3224,9 @@ var parseRequest = async (requestPayload, isFirstInvocation, workflowRunId, requ
|
|
|
3140
3224
|
};
|
|
3141
3225
|
}
|
|
3142
3226
|
};
|
|
3143
|
-
var handleFailure = async (request, requestPayload, qstashClient, initialPayloadParser, routeFunction, failureFunction, env, retries, flowControl, debug) => {
|
|
3227
|
+
var handleFailure = async (request, requestPayload, qstashClient, initialPayloadParser, routeFunction, failureFunction, env, retries, retryDelay, flowControl, debug) => {
|
|
3144
3228
|
if (request.headers.get(WORKFLOW_FAILURE_HEADER) !== "true") {
|
|
3145
|
-
return ok("not-failure-callback");
|
|
3229
|
+
return ok({ result: "not-failure-callback" });
|
|
3146
3230
|
}
|
|
3147
3231
|
if (!failureFunction) {
|
|
3148
3232
|
return err(
|
|
@@ -3154,7 +3238,17 @@ var handleFailure = async (request, requestPayload, qstashClient, initialPayload
|
|
|
3154
3238
|
try {
|
|
3155
3239
|
const { status, header, body, url, sourceBody, workflowRunId } = JSON.parse(requestPayload);
|
|
3156
3240
|
const decodedBody = body ? decodeBase64(body) : "{}";
|
|
3157
|
-
|
|
3241
|
+
let errorMessage = "";
|
|
3242
|
+
try {
|
|
3243
|
+
const errorPayload = JSON.parse(decodedBody);
|
|
3244
|
+
if (errorPayload.message) {
|
|
3245
|
+
errorMessage = errorPayload.message;
|
|
3246
|
+
}
|
|
3247
|
+
} catch {
|
|
3248
|
+
}
|
|
3249
|
+
if (!errorMessage) {
|
|
3250
|
+
errorMessage = `Couldn't parse 'failResponse' in 'failureFunction', received: '${decodedBody}'`;
|
|
3251
|
+
}
|
|
3158
3252
|
const workflowContext = new WorkflowContext({
|
|
3159
3253
|
qstashClient,
|
|
3160
3254
|
workflowRunId,
|
|
@@ -3166,6 +3260,7 @@ var handleFailure = async (request, requestPayload, qstashClient, initialPayload
|
|
|
3166
3260
|
debug,
|
|
3167
3261
|
env,
|
|
3168
3262
|
retries,
|
|
3263
|
+
retryDelay,
|
|
3169
3264
|
flowControl,
|
|
3170
3265
|
telemetry: void 0
|
|
3171
3266
|
// not going to make requests in authentication check
|
|
@@ -3180,16 +3275,16 @@ var handleFailure = async (request, requestPayload, qstashClient, initialPayload
|
|
|
3180
3275
|
} else if (authCheck.value === "run-ended") {
|
|
3181
3276
|
return err(new WorkflowError("Not authorized to run the failure function."));
|
|
3182
3277
|
}
|
|
3183
|
-
await failureFunction({
|
|
3278
|
+
const failureResponse = await failureFunction({
|
|
3184
3279
|
context: workflowContext,
|
|
3185
3280
|
failStatus: status,
|
|
3186
|
-
failResponse:
|
|
3281
|
+
failResponse: errorMessage,
|
|
3187
3282
|
failHeaders: header
|
|
3188
3283
|
});
|
|
3284
|
+
return ok({ result: "is-failure-callback", response: failureResponse });
|
|
3189
3285
|
} catch (error) {
|
|
3190
3286
|
return err(error);
|
|
3191
3287
|
}
|
|
3192
|
-
return ok("is-failure-callback");
|
|
3193
3288
|
};
|
|
3194
3289
|
|
|
3195
3290
|
// src/serve/options.ts
|
|
@@ -3205,8 +3300,8 @@ var processOptions = (options) => {
|
|
|
3205
3300
|
baseUrl: environment.QSTASH_URL,
|
|
3206
3301
|
token: environment.QSTASH_TOKEN
|
|
3207
3302
|
}),
|
|
3208
|
-
onStepFinish: (workflowRunId,
|
|
3209
|
-
if (
|
|
3303
|
+
onStepFinish: (workflowRunId, _finishCondition, detailedFinishCondition) => {
|
|
3304
|
+
if (detailedFinishCondition?.condition === "auth-fail") {
|
|
3210
3305
|
console.error(AUTH_FAIL_MESSAGE);
|
|
3211
3306
|
return new Response(
|
|
3212
3307
|
JSON.stringify({
|
|
@@ -3214,19 +3309,33 @@ var processOptions = (options) => {
|
|
|
3214
3309
|
workflowRunId
|
|
3215
3310
|
}),
|
|
3216
3311
|
{
|
|
3217
|
-
status: 400
|
|
3312
|
+
status: 400,
|
|
3313
|
+
headers: {
|
|
3314
|
+
[WORKFLOW_PROTOCOL_VERSION_HEADER]: WORKFLOW_PROTOCOL_VERSION
|
|
3315
|
+
}
|
|
3218
3316
|
}
|
|
3219
3317
|
);
|
|
3220
|
-
} else if (
|
|
3221
|
-
return new Response(JSON.stringify(formatWorkflowError(
|
|
3318
|
+
} else if (detailedFinishCondition?.condition === "non-retryable-error") {
|
|
3319
|
+
return new Response(JSON.stringify(formatWorkflowError(detailedFinishCondition.result)), {
|
|
3222
3320
|
headers: {
|
|
3223
|
-
"Upstash-NonRetryable-Error": "true"
|
|
3321
|
+
"Upstash-NonRetryable-Error": "true",
|
|
3322
|
+
[WORKFLOW_PROTOCOL_VERSION_HEADER]: WORKFLOW_PROTOCOL_VERSION
|
|
3224
3323
|
},
|
|
3225
3324
|
status: 489
|
|
3226
3325
|
});
|
|
3326
|
+
} else if (detailedFinishCondition?.condition === "failure-callback") {
|
|
3327
|
+
return new Response(detailedFinishCondition.result ?? void 0, {
|
|
3328
|
+
status: 200,
|
|
3329
|
+
headers: {
|
|
3330
|
+
[WORKFLOW_PROTOCOL_VERSION_HEADER]: WORKFLOW_PROTOCOL_VERSION
|
|
3331
|
+
}
|
|
3332
|
+
});
|
|
3227
3333
|
}
|
|
3228
3334
|
return new Response(JSON.stringify({ workflowRunId }), {
|
|
3229
|
-
status: 200
|
|
3335
|
+
status: 200,
|
|
3336
|
+
headers: {
|
|
3337
|
+
[WORKFLOW_PROTOCOL_VERSION_HEADER]: WORKFLOW_PROTOCOL_VERSION
|
|
3338
|
+
}
|
|
3230
3339
|
});
|
|
3231
3340
|
},
|
|
3232
3341
|
initialPayloadParser: (initialRequest) => {
|
|
@@ -3300,6 +3409,7 @@ var serveBase = (routeFunction, telemetry, options) => {
|
|
|
3300
3409
|
baseUrl,
|
|
3301
3410
|
env,
|
|
3302
3411
|
retries,
|
|
3412
|
+
retryDelay,
|
|
3303
3413
|
useJSONContent,
|
|
3304
3414
|
disableTelemetry,
|
|
3305
3415
|
flowControl,
|
|
@@ -3330,10 +3440,14 @@ var serveBase = (routeFunction, telemetry, options) => {
|
|
|
3330
3440
|
debug
|
|
3331
3441
|
);
|
|
3332
3442
|
if (workflowRunEnded) {
|
|
3333
|
-
return onStepFinish(workflowRunId, "workflow-already-ended"
|
|
3443
|
+
return onStepFinish(workflowRunId, "workflow-already-ended", {
|
|
3444
|
+
condition: "workflow-already-ended"
|
|
3445
|
+
});
|
|
3334
3446
|
}
|
|
3335
3447
|
if (isLastDuplicate) {
|
|
3336
|
-
return onStepFinish(workflowRunId, "duplicate-step"
|
|
3448
|
+
return onStepFinish(workflowRunId, "duplicate-step", {
|
|
3449
|
+
condition: "duplicate-step"
|
|
3450
|
+
});
|
|
3337
3451
|
}
|
|
3338
3452
|
const failureCheck = await handleFailure(
|
|
3339
3453
|
request,
|
|
@@ -3344,14 +3458,18 @@ var serveBase = (routeFunction, telemetry, options) => {
|
|
|
3344
3458
|
failureFunction,
|
|
3345
3459
|
env,
|
|
3346
3460
|
retries,
|
|
3461
|
+
retryDelay,
|
|
3347
3462
|
flowControl,
|
|
3348
3463
|
debug
|
|
3349
3464
|
);
|
|
3350
3465
|
if (failureCheck.isErr()) {
|
|
3351
3466
|
throw failureCheck.error;
|
|
3352
|
-
} else if (failureCheck.value === "is-failure-callback") {
|
|
3467
|
+
} else if (failureCheck.value.result === "is-failure-callback") {
|
|
3353
3468
|
await debug?.log("WARN", "RESPONSE_DEFAULT", "failureFunction executed");
|
|
3354
|
-
return onStepFinish(workflowRunId, "failure-callback"
|
|
3469
|
+
return onStepFinish(workflowRunId, "failure-callback", {
|
|
3470
|
+
condition: "failure-callback",
|
|
3471
|
+
result: failureCheck.value.response
|
|
3472
|
+
});
|
|
3355
3473
|
}
|
|
3356
3474
|
const invokeCount = Number(request.headers.get(WORKFLOW_INVOKE_COUNT_HEADER) ?? "0");
|
|
3357
3475
|
const workflowContext = new WorkflowContext({
|
|
@@ -3365,6 +3483,7 @@ var serveBase = (routeFunction, telemetry, options) => {
|
|
|
3365
3483
|
debug,
|
|
3366
3484
|
env,
|
|
3367
3485
|
retries,
|
|
3486
|
+
retryDelay,
|
|
3368
3487
|
telemetry,
|
|
3369
3488
|
invokeCount,
|
|
3370
3489
|
flowControl
|
|
@@ -3380,7 +3499,8 @@ var serveBase = (routeFunction, telemetry, options) => {
|
|
|
3380
3499
|
await debug?.log("ERROR", "ERROR", { error: AUTH_FAIL_MESSAGE });
|
|
3381
3500
|
return onStepFinish(
|
|
3382
3501
|
isFirstInvocation ? "no-workflow-id" : workflowContext.workflowRunId,
|
|
3383
|
-
"auth-fail"
|
|
3502
|
+
"auth-fail",
|
|
3503
|
+
{ condition: "auth-fail" }
|
|
3384
3504
|
);
|
|
3385
3505
|
}
|
|
3386
3506
|
const callReturnCheck = await handleThirdPartyCallResult({
|
|
@@ -3390,6 +3510,7 @@ var serveBase = (routeFunction, telemetry, options) => {
|
|
|
3390
3510
|
workflowUrl,
|
|
3391
3511
|
failureUrl: workflowFailureUrl,
|
|
3392
3512
|
retries,
|
|
3513
|
+
retryDelay,
|
|
3393
3514
|
flowControl,
|
|
3394
3515
|
telemetry,
|
|
3395
3516
|
debug
|
|
@@ -3417,19 +3538,28 @@ var serveBase = (routeFunction, telemetry, options) => {
|
|
|
3417
3538
|
debug
|
|
3418
3539
|
});
|
|
3419
3540
|
if (result.isOk() && result.value instanceof WorkflowNonRetryableError) {
|
|
3420
|
-
return onStepFinish(workflowRunId, result.value
|
|
3541
|
+
return onStepFinish(workflowRunId, result.value, {
|
|
3542
|
+
condition: "non-retryable-error",
|
|
3543
|
+
result: result.value
|
|
3544
|
+
});
|
|
3421
3545
|
}
|
|
3422
3546
|
if (result.isErr()) {
|
|
3423
3547
|
await debug?.log("ERROR", "ERROR", { error: result.error.message });
|
|
3424
3548
|
throw result.error;
|
|
3425
3549
|
}
|
|
3426
3550
|
await debug?.log("INFO", "RESPONSE_WORKFLOW");
|
|
3427
|
-
return onStepFinish(workflowContext.workflowRunId, "success"
|
|
3551
|
+
return onStepFinish(workflowContext.workflowRunId, "success", {
|
|
3552
|
+
condition: "success"
|
|
3553
|
+
});
|
|
3428
3554
|
} else if (callReturnCheck.value === "workflow-ended") {
|
|
3429
|
-
return onStepFinish(workflowContext.workflowRunId, "workflow-already-ended"
|
|
3555
|
+
return onStepFinish(workflowContext.workflowRunId, "workflow-already-ended", {
|
|
3556
|
+
condition: "workflow-already-ended"
|
|
3557
|
+
});
|
|
3430
3558
|
}
|
|
3431
3559
|
await debug?.log("INFO", "RESPONSE_DEFAULT");
|
|
3432
|
-
return onStepFinish("no-workflow-id", "fromCallback"
|
|
3560
|
+
return onStepFinish("no-workflow-id", "fromCallback", {
|
|
3561
|
+
condition: "fromCallback"
|
|
3562
|
+
});
|
|
3433
3563
|
};
|
|
3434
3564
|
const safeHandler = async (request) => {
|
|
3435
3565
|
try {
|
|
@@ -3444,11 +3574,17 @@ var serveBase = (routeFunction, telemetry, options) => {
|
|
|
3444
3574
|
Original error: '${formattedError.message}'`;
|
|
3445
3575
|
console.error(errorMessage);
|
|
3446
3576
|
return new Response(errorMessage, {
|
|
3447
|
-
status: 500
|
|
3577
|
+
status: 500,
|
|
3578
|
+
headers: {
|
|
3579
|
+
[WORKFLOW_PROTOCOL_VERSION_HEADER]: WORKFLOW_PROTOCOL_VERSION
|
|
3580
|
+
}
|
|
3448
3581
|
});
|
|
3449
3582
|
}
|
|
3450
3583
|
return new Response(JSON.stringify(formattedError), {
|
|
3451
|
-
status: 500
|
|
3584
|
+
status: 500,
|
|
3585
|
+
headers: {
|
|
3586
|
+
[WORKFLOW_PROTOCOL_VERSION_HEADER]: WORKFLOW_PROTOCOL_VERSION
|
|
3587
|
+
}
|
|
3452
3588
|
});
|
|
3453
3589
|
}
|
|
3454
3590
|
};
|
|
@@ -3523,6 +3659,20 @@ var DLQ = class _DLQ {
|
|
|
3523
3659
|
}
|
|
3524
3660
|
return workflowRuns[0];
|
|
3525
3661
|
}
|
|
3662
|
+
/**
|
|
3663
|
+
* Retry the failure callback of a workflow run whose failureUrl/failureFunction
|
|
3664
|
+
* request has failed.
|
|
3665
|
+
*
|
|
3666
|
+
* @param dlqId - The ID of the DLQ message to retry.
|
|
3667
|
+
* @returns
|
|
3668
|
+
*/
|
|
3669
|
+
async retryFailureFunction({ dlqId }) {
|
|
3670
|
+
const response = await this.client.http.request({
|
|
3671
|
+
path: ["v2", "workflows", "dlq", "callback", dlqId],
|
|
3672
|
+
method: "POST"
|
|
3673
|
+
});
|
|
3674
|
+
return response;
|
|
3675
|
+
}
|
|
3526
3676
|
static handleDLQOptions(options) {
|
|
3527
3677
|
const { dlqId, flowControl, retries } = options;
|
|
3528
3678
|
const headers = {};
|
|
@@ -3681,13 +3831,14 @@ var Client4 = class {
|
|
|
3681
3831
|
const finalWorkflowRunId = getWorkflowRunId(option.workflowRunId);
|
|
3682
3832
|
const context = new WorkflowContext({
|
|
3683
3833
|
qstashClient: this.client,
|
|
3684
|
-
// @ts-expect-error
|
|
3834
|
+
// @ts-expect-error header type mismatch because of bun
|
|
3685
3835
|
headers: new Headers(option.headers ?? {}),
|
|
3686
3836
|
initialPayload: option.body,
|
|
3687
3837
|
steps: [],
|
|
3688
3838
|
url: option.url,
|
|
3689
3839
|
workflowRunId: finalWorkflowRunId,
|
|
3690
3840
|
retries: option.retries,
|
|
3841
|
+
retryDelay: option.retryDelay,
|
|
3691
3842
|
telemetry: { sdk: SDK_TELEMETRY },
|
|
3692
3843
|
flowControl: option.flowControl,
|
|
3693
3844
|
failureUrl
|
package/index.mjs
CHANGED
|
@@ -13,7 +13,7 @@ import {
|
|
|
13
13
|
prepareFlowControl,
|
|
14
14
|
serve,
|
|
15
15
|
triggerFirstInvocation
|
|
16
|
-
} from "./chunk-
|
|
16
|
+
} from "./chunk-RP7G4UD5.mjs";
|
|
17
17
|
|
|
18
18
|
// src/client/index.ts
|
|
19
19
|
import { Client as QStashClient } from "@upstash/qstash";
|
|
@@ -73,6 +73,20 @@ var DLQ = class _DLQ {
|
|
|
73
73
|
}
|
|
74
74
|
return workflowRuns[0];
|
|
75
75
|
}
|
|
76
|
+
/**
|
|
77
|
+
* Retry the failure callback of a workflow run whose failureUrl/failureFunction
|
|
78
|
+
* request has failed.
|
|
79
|
+
*
|
|
80
|
+
* @param dlqId - The ID of the DLQ message to retry.
|
|
81
|
+
* @returns
|
|
82
|
+
*/
|
|
83
|
+
async retryFailureFunction({ dlqId }) {
|
|
84
|
+
const response = await this.client.http.request({
|
|
85
|
+
path: ["v2", "workflows", "dlq", "callback", dlqId],
|
|
86
|
+
method: "POST"
|
|
87
|
+
});
|
|
88
|
+
return response;
|
|
89
|
+
}
|
|
76
90
|
static handleDLQOptions(options) {
|
|
77
91
|
const { dlqId, flowControl, retries } = options;
|
|
78
92
|
const headers = {};
|
|
@@ -231,13 +245,14 @@ var Client = class {
|
|
|
231
245
|
const finalWorkflowRunId = getWorkflowRunId(option.workflowRunId);
|
|
232
246
|
const context = new WorkflowContext({
|
|
233
247
|
qstashClient: this.client,
|
|
234
|
-
// @ts-expect-error
|
|
248
|
+
// @ts-expect-error header type mismatch because of bun
|
|
235
249
|
headers: new Headers(option.headers ?? {}),
|
|
236
250
|
initialPayload: option.body,
|
|
237
251
|
steps: [],
|
|
238
252
|
url: option.url,
|
|
239
253
|
workflowRunId: finalWorkflowRunId,
|
|
240
254
|
retries: option.retries,
|
|
255
|
+
retryDelay: option.retryDelay,
|
|
241
256
|
telemetry: { sdk: SDK_TELEMETRY },
|
|
242
257
|
flowControl: option.flowControl,
|
|
243
258
|
failureUrl
|
package/nextjs.d.mts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { NextApiHandler, NextApiRequest, NextApiResponse } from 'next';
|
|
2
|
-
import { R as RouteFunction, n as PublicServeOptions,
|
|
3
|
-
import { s as serveManyBase } from './serve-many-
|
|
2
|
+
import { R as RouteFunction, n as PublicServeOptions, x as InvokableWorkflow } from './types--R_3XZXz.mjs';
|
|
3
|
+
import { s as serveManyBase } from './serve-many-DgDSOvQs.mjs';
|
|
4
4
|
import '@upstash/qstash';
|
|
5
5
|
import 'zod';
|
|
6
6
|
import 'ai';
|
package/nextjs.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { NextApiHandler, NextApiRequest, NextApiResponse } from 'next';
|
|
2
|
-
import { R as RouteFunction, n as PublicServeOptions,
|
|
3
|
-
import { s as serveManyBase } from './serve-many-
|
|
2
|
+
import { R as RouteFunction, n as PublicServeOptions, x as InvokableWorkflow } from './types--R_3XZXz.js';
|
|
3
|
+
import { s as serveManyBase } from './serve-many-B3DfoTFt.js';
|
|
4
4
|
import '@upstash/qstash';
|
|
5
5
|
import 'zod';
|
|
6
6
|
import 'ai';
|