@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/hono.js CHANGED
@@ -91,7 +91,7 @@ var WORKFLOW_PROTOCOL_VERSION_HEADER = "Upstash-Workflow-Sdk-Version";
91
91
  var DEFAULT_CONTENT_TYPE = "application/json";
92
92
  var NO_CONCURRENCY = 1;
93
93
  var DEFAULT_RETRIES = 3;
94
- var VERSION = "v0.2.15";
94
+ var VERSION = "v0.2.17";
95
95
  var SDK_TELEMETRY = `@upstash/workflow@${VERSION}`;
96
96
  var TELEMETRY_HEADER_SDK = "Upstash-Telemetry-Sdk";
97
97
  var TELEMETRY_HEADER_FRAMEWORK = "Upstash-Telemetry-Framework";
@@ -621,6 +621,7 @@ var triggerFirstInvocation = async (params) => {
621
621
  workflowUrl: workflowContext.url,
622
622
  failureUrl: workflowContext.failureUrl,
623
623
  retries: workflowContext.retries,
624
+ retryDelay: workflowContext.retryDelay,
624
625
  telemetry: telemetry2,
625
626
  flowControl: workflowContext.flowControl,
626
627
  useJSONContent: useJSONContent ?? false
@@ -750,6 +751,7 @@ var handleThirdPartyCallResult = async ({
750
751
  workflowUrl,
751
752
  failureUrl,
752
753
  retries,
754
+ retryDelay,
753
755
  telemetry: telemetry2,
754
756
  flowControl,
755
757
  debug
@@ -820,6 +822,7 @@ ${atob(callbackMessage.body ?? "")}`
820
822
  workflowUrl,
821
823
  failureUrl,
822
824
  retries,
825
+ retryDelay,
823
826
  telemetry: telemetry2,
824
827
  flowControl
825
828
  },
@@ -970,7 +973,8 @@ var BaseLazyStep = class _BaseLazyStep {
970
973
  workflowRunId: context.workflowRunId,
971
974
  workflowUrl: context.url,
972
975
  failureUrl: context.failureUrl,
973
- retries: context.retries,
976
+ retries: DEFAULT_RETRIES === context.retries ? void 0 : context.retries,
977
+ retryDelay: context.retryDelay,
974
978
  useJSONContent: false,
975
979
  telemetry: telemetry2,
976
980
  flowControl: context.flowControl
@@ -989,6 +993,9 @@ var BaseLazyStep = class _BaseLazyStep {
989
993
  body,
990
994
  headers,
991
995
  method: "POST",
996
+ retries: DEFAULT_RETRIES === context.retries ? void 0 : context.retries,
997
+ retryDelay: context.retryDelay,
998
+ flowControl: context.flowControl,
992
999
  url: context.url
993
1000
  }
994
1001
  ]);
@@ -1059,6 +1066,9 @@ var LazySleepStep = class extends BaseLazyStep {
1059
1066
  headers,
1060
1067
  method: "POST",
1061
1068
  url: context.url,
1069
+ retries: DEFAULT_RETRIES === context.retries ? void 0 : context.retries,
1070
+ retryDelay: context.retryDelay,
1071
+ flowControl: context.flowControl,
1062
1072
  delay: isParallel ? void 0 : this.sleep
1063
1073
  }
1064
1074
  ]);
@@ -1101,6 +1111,9 @@ var LazySleepUntilStep = class extends BaseLazyStep {
1101
1111
  headers,
1102
1112
  method: "POST",
1103
1113
  url: context.url,
1114
+ retries: DEFAULT_RETRIES === context.retries ? void 0 : context.retries,
1115
+ retryDelay: context.retryDelay,
1116
+ flowControl: context.flowControl,
1104
1117
  notBefore: isParallel ? void 0 : this.sleepUntil
1105
1118
  }
1106
1119
  ]);
@@ -1112,17 +1125,19 @@ var LazyCallStep = class _LazyCallStep extends BaseLazyStep {
1112
1125
  body;
1113
1126
  headers;
1114
1127
  retries;
1128
+ retryDelay;
1115
1129
  timeout;
1116
1130
  flowControl;
1117
1131
  stepType = "Call";
1118
1132
  allowUndefinedOut = false;
1119
- constructor(stepName, url, method, body, headers, retries, timeout, flowControl) {
1133
+ constructor(stepName, url, method, body, headers, retries, retryDelay, timeout, flowControl) {
1120
1134
  super(stepName);
1121
1135
  this.url = url;
1122
1136
  this.method = method;
1123
1137
  this.body = body;
1124
1138
  this.headers = headers;
1125
1139
  this.retries = retries;
1140
+ this.retryDelay = retryDelay;
1126
1141
  this.timeout = timeout;
1127
1142
  this.flowControl = flowControl;
1128
1143
  }
@@ -1197,6 +1212,9 @@ var LazyCallStep = class _LazyCallStep extends BaseLazyStep {
1197
1212
  getHeaders({ context, telemetry: telemetry2, invokeCount, step }) {
1198
1213
  const { headers, contentType } = super.getHeaders({ context, telemetry: telemetry2, invokeCount, step });
1199
1214
  headers["Upstash-Retries"] = this.retries.toString();
1215
+ if (this.retryDelay) {
1216
+ headers["Upstash-Retry-Delay"] = this.retryDelay;
1217
+ }
1200
1218
  headers[WORKFLOW_FEATURE_HEADER] = "WF_NoDelete,InitialBody";
1201
1219
  if (this.flowControl) {
1202
1220
  const { flowControlKey, flowControlValue } = prepareFlowControl(this.flowControl);
@@ -1218,7 +1236,7 @@ var LazyCallStep = class _LazyCallStep extends BaseLazyStep {
1218
1236
  "Upstash-Callback-Workflow-CallType": "fromCallback",
1219
1237
  "Upstash-Callback-Workflow-Init": "false",
1220
1238
  "Upstash-Callback-Workflow-Url": context.url,
1221
- "Upstash-Callback-Feature-Set": "LazyFetch,InitialBody",
1239
+ "Upstash-Callback-Feature-Set": "LazyFetch,InitialBody,WF_DetectTrigger",
1222
1240
  "Upstash-Callback-Forward-Upstash-Workflow-Callback": "true",
1223
1241
  "Upstash-Callback-Forward-Upstash-Workflow-StepId": step.stepId.toString(),
1224
1242
  "Upstash-Callback-Forward-Upstash-Workflow-StepName": this.stepName,
@@ -1236,7 +1254,10 @@ var LazyCallStep = class _LazyCallStep extends BaseLazyStep {
1236
1254
  headers,
1237
1255
  body: JSON.stringify(this.body),
1238
1256
  method: this.method,
1239
- url: this.url
1257
+ url: this.url,
1258
+ retries: DEFAULT_RETRIES === this.retries ? void 0 : this.retries,
1259
+ retryDelay: this.retryDelay,
1260
+ flowControl: this.flowControl
1240
1261
  }
1241
1262
  ]);
1242
1263
  }
@@ -1365,6 +1386,7 @@ var LazyInvokeStep = class extends BaseLazyStep {
1365
1386
  headers = {},
1366
1387
  workflowRunId,
1367
1388
  retries,
1389
+ retryDelay,
1368
1390
  flowControl
1369
1391
  }) {
1370
1392
  super(stepName);
@@ -1374,6 +1396,7 @@ var LazyInvokeStep = class extends BaseLazyStep {
1374
1396
  headers,
1375
1397
  workflowRunId: getWorkflowRunId(workflowRunId),
1376
1398
  retries,
1399
+ retryDelay,
1377
1400
  flowControl
1378
1401
  };
1379
1402
  const { workflowId } = workflow;
@@ -1418,6 +1441,7 @@ var LazyInvokeStep = class extends BaseLazyStep {
1418
1441
  workflowUrl: context.url,
1419
1442
  failureUrl: context.failureUrl,
1420
1443
  retries: context.retries,
1444
+ retryDelay: context.retryDelay,
1421
1445
  telemetry: telemetry2,
1422
1446
  flowControl: context.flowControl,
1423
1447
  useJSONContent: false
@@ -1443,11 +1467,13 @@ var LazyInvokeStep = class extends BaseLazyStep {
1443
1467
  headers = {},
1444
1468
  workflowRunId = getWorkflowRunId(),
1445
1469
  retries,
1470
+ retryDelay,
1446
1471
  flowControl
1447
1472
  } = this.params;
1448
1473
  const newUrl = context.url.replace(/[^/]+$/, this.workflowId);
1449
1474
  const {
1450
1475
  retries: workflowRetries,
1476
+ retryDelay: workflowRetryDelay,
1451
1477
  failureFunction,
1452
1478
  failureUrl,
1453
1479
  useJSONContent,
@@ -1459,6 +1485,7 @@ var LazyInvokeStep = class extends BaseLazyStep {
1459
1485
  workflowRunId,
1460
1486
  workflowUrl: newUrl,
1461
1487
  retries: retries ?? workflowRetries,
1488
+ retryDelay: retryDelay ?? workflowRetryDelay,
1462
1489
  telemetry: telemetry2,
1463
1490
  failureUrl: failureFunction ? newUrl : failureUrl,
1464
1491
  flowControl: flowControl ?? workflowFlowControl,
@@ -1525,6 +1552,7 @@ var WorkflowHeaders = class {
1525
1552
  getHeaders() {
1526
1553
  this.addBaseHeaders();
1527
1554
  this.addRetries();
1555
+ this.addRetryDelay();
1528
1556
  this.addFlowControl();
1529
1557
  this.addUserHeaders();
1530
1558
  this.addInvokeCount();
@@ -1538,7 +1566,7 @@ var WorkflowHeaders = class {
1538
1566
  [WORKFLOW_INIT_HEADER]: this.initHeaderValue,
1539
1567
  [WORKFLOW_ID_HEADER]: this.workflowConfig.workflowRunId,
1540
1568
  [WORKFLOW_URL_HEADER]: this.workflowConfig.workflowUrl,
1541
- [WORKFLOW_FEATURE_HEADER]: "LazyFetch,InitialBody",
1569
+ [WORKFLOW_FEATURE_HEADER]: "LazyFetch,InitialBody,WF_DetectTrigger",
1542
1570
  [WORKFLOW_PROTOCOL_VERSION_HEADER]: WORKFLOW_PROTOCOL_VERSION,
1543
1571
  ...this.workflowConfig.telemetry ? getTelemetryHeaders(this.workflowConfig.telemetry) : {},
1544
1572
  ...this.workflowConfig.telemetry && this.stepInfo?.lazyStep instanceof LazyCallStep && this.stepInfo.lazyStep.headers[AGENT_NAME_HEADER] ? { [TELEMETRY_HEADER_AGENT]: "true" } : {}
@@ -1570,6 +1598,16 @@ var WorkflowHeaders = class {
1570
1598
  this.headers.failureHeaders["Retries"] = retries;
1571
1599
  }
1572
1600
  }
1601
+ addRetryDelay() {
1602
+ if (this.workflowConfig.retryDelay === void 0 || this.workflowConfig.retryDelay === "") {
1603
+ return;
1604
+ }
1605
+ const retryDelay = this.workflowConfig.retryDelay.toString();
1606
+ this.headers.workflowHeaders["Retry-Delay"] = retryDelay;
1607
+ if (this.workflowConfig.failureUrl) {
1608
+ this.headers.failureHeaders["Retry-Delay"] = retryDelay;
1609
+ }
1610
+ }
1573
1611
  addFlowControl() {
1574
1612
  if (!this.workflowConfig.flowControl) {
1575
1613
  return;
@@ -1604,10 +1642,13 @@ var WorkflowHeaders = class {
1604
1642
  this.headers.failureHeaders["Workflow-Init"] = "false";
1605
1643
  this.headers.failureHeaders["Workflow-Url"] = this.workflowConfig.workflowUrl;
1606
1644
  this.headers.failureHeaders["Workflow-Calltype"] = "failureCall";
1607
- this.headers.failureHeaders["Feature-Set"] = "LazyFetch,InitialBody";
1645
+ this.headers.failureHeaders["Feature-Set"] = "LazyFetch,InitialBody,WF_DetectTrigger";
1608
1646
  if (this.workflowConfig.retries !== void 0 && this.workflowConfig.retries !== DEFAULT_RETRIES) {
1609
1647
  this.headers.failureHeaders["Retries"] = this.workflowConfig.retries.toString();
1610
1648
  }
1649
+ if (this.workflowConfig.retryDelay !== void 0 && this.workflowConfig.retryDelay !== "") {
1650
+ this.headers.failureHeaders["Retry-Delay"] = this.workflowConfig.retryDelay.toString();
1651
+ }
1611
1652
  }
1612
1653
  addContentType() {
1613
1654
  if (this.workflowConfig.useJSONContent) {
@@ -1689,6 +1730,7 @@ var submitParallelSteps = async ({
1689
1730
  workflowUrl: context.url,
1690
1731
  failureUrl: context.failureUrl,
1691
1732
  retries: context.retries,
1733
+ retryDelay: context.retryDelay,
1692
1734
  flowControl: context.flowControl,
1693
1735
  telemetry: telemetry2
1694
1736
  },
@@ -2109,7 +2151,7 @@ var BaseWorkflowApi = class {
2109
2151
  */
2110
2152
  async callApi(stepName, settings) {
2111
2153
  const { url, appendHeaders, method } = getProviderInfo(settings.api);
2112
- const { method: userMethod, body, headers = {}, retries = 0, timeout } = settings;
2154
+ const { method: userMethod, body, headers = {}, retries = 0, retryDelay, timeout } = settings;
2113
2155
  return await this.context.call(stepName, {
2114
2156
  url,
2115
2157
  method: userMethod ?? method,
@@ -2119,6 +2161,7 @@ var BaseWorkflowApi = class {
2119
2161
  ...headers
2120
2162
  },
2121
2163
  retries,
2164
+ retryDelay,
2122
2165
  timeout
2123
2166
  });
2124
2167
  }
@@ -2208,6 +2251,7 @@ var fetchWithContextCall = async (context, agentCallParams, ...params) => {
2208
2251
  body,
2209
2252
  timeout: agentCallParams?.timeout,
2210
2253
  retries: agentCallParams?.retries,
2254
+ retryDelay: agentCallParams?.retryDelay,
2211
2255
  flowControl: agentCallParams?.flowControl
2212
2256
  });
2213
2257
  const responseHeaders = new Headers(
@@ -2536,7 +2580,10 @@ var serveManyBase = ({
2536
2580
  return new Response(
2537
2581
  `Unexpected request in serveMany. workflowId not set. Please update the URL of your request.`,
2538
2582
  {
2539
- status: 404
2583
+ status: 404,
2584
+ headers: {
2585
+ [WORKFLOW_PROTOCOL_VERSION_HEADER]: WORKFLOW_PROTOCOL_VERSION
2586
+ }
2540
2587
  }
2541
2588
  );
2542
2589
  }
@@ -2545,7 +2592,10 @@ var serveManyBase = ({
2545
2592
  return new Response(
2546
2593
  `No workflows in serveMany found for '${pickedWorkflowId}'. Please update the URL of your request.`,
2547
2594
  {
2548
- status: 404
2595
+ status: 404,
2596
+ headers: {
2597
+ [WORKFLOW_PROTOCOL_VERSION_HEADER]: WORKFLOW_PROTOCOL_VERSION
2598
+ }
2549
2599
  }
2550
2600
  );
2551
2601
  }
@@ -2682,6 +2732,37 @@ var WorkflowContext = class {
2682
2732
  * Number of retries
2683
2733
  */
2684
2734
  retries;
2735
+ /**
2736
+ * Delay between retries.
2737
+ *
2738
+ * By default, the `retryDelay` is exponential backoff.
2739
+ * More details can be found in: https://upstash.com/docs/qstash/features/retry.
2740
+ *
2741
+ * The `retryDelay` option allows you to customize the delay (in milliseconds) between retry attempts when message delivery fails.
2742
+ *
2743
+ * You can use mathematical expressions and the following built-in functions to calculate the delay dynamically.
2744
+ * The special variable `retried` represents the current retry attempt count (starting from 0).
2745
+ *
2746
+ * Supported functions:
2747
+ * - `pow`
2748
+ * - `sqrt`
2749
+ * - `abs`
2750
+ * - `exp`
2751
+ * - `floor`
2752
+ * - `ceil`
2753
+ * - `round`
2754
+ * - `min`
2755
+ * - `max`
2756
+ *
2757
+ * Examples of valid `retryDelay` values:
2758
+ * ```ts
2759
+ * 1000 // 1 second
2760
+ * 1000 * (1 + retried) // 1 second multiplied by the current retry attempt
2761
+ * pow(2, retried) // 2 to the power of the current retry attempt
2762
+ * max(10, pow(2, retried)) // The greater of 10 or 2^retried
2763
+ * ```
2764
+ */
2765
+ retryDelay;
2685
2766
  /**
2686
2767
  * Settings for controlling the number of active requests
2687
2768
  * and number of requests per second with the same key.
@@ -2698,6 +2779,7 @@ var WorkflowContext = class {
2698
2779
  initialPayload,
2699
2780
  env,
2700
2781
  retries,
2782
+ retryDelay,
2701
2783
  telemetry: telemetry2,
2702
2784
  invokeCount,
2703
2785
  flowControl
@@ -2711,6 +2793,7 @@ var WorkflowContext = class {
2711
2793
  this.requestPayload = initialPayload;
2712
2794
  this.env = env ?? {};
2713
2795
  this.retries = retries ?? DEFAULT_RETRIES;
2796
+ this.retryDelay = retryDelay;
2714
2797
  this.flowControl = flowControl;
2715
2798
  this.executor = new AutoExecutor(this, this.steps, telemetry2, invokeCount, debug);
2716
2799
  }
@@ -2792,6 +2875,7 @@ var WorkflowContext = class {
2792
2875
  settings.body,
2793
2876
  settings.headers || {},
2794
2877
  settings.retries || 0,
2878
+ settings.retryDelay,
2795
2879
  settings.timeout,
2796
2880
  settings.flowControl ?? settings.workflow.options.flowControl
2797
2881
  );
@@ -2802,6 +2886,7 @@ var WorkflowContext = class {
2802
2886
  body,
2803
2887
  headers = {},
2804
2888
  retries = 0,
2889
+ retryDelay,
2805
2890
  timeout,
2806
2891
  flowControl
2807
2892
  } = settings;
@@ -2812,6 +2897,7 @@ var WorkflowContext = class {
2812
2897
  body,
2813
2898
  headers,
2814
2899
  retries,
2900
+ retryDelay,
2815
2901
  timeout,
2816
2902
  flowControl
2817
2903
  );
@@ -2822,7 +2908,7 @@ var WorkflowContext = class {
2822
2908
  * Pauses workflow execution until a specific event occurs or a timeout is reached.
2823
2909
  *
2824
2910
  *```ts
2825
- * const result = await workflow.waitForEvent("payment-confirmed", {
2911
+ * const result = await workflow.waitForEvent("payment-confirmed", "payment.confirmed", {
2826
2912
  * timeout: "5m"
2827
2913
  * });
2828
2914
  *```
@@ -2848,7 +2934,7 @@ var WorkflowContext = class {
2848
2934
  * @param stepName
2849
2935
  * @param eventId - Unique identifier for the event to wait for
2850
2936
  * @param options - Configuration options.
2851
- * @returns `{ timeout: boolean, eventData: unknown }`.
2937
+ * @returns `{ timeout: boolean, eventData: TEventData }`.
2852
2938
  * The `timeout` property specifies if the workflow has timed out. The `eventData`
2853
2939
  * is the data passed when notifying this workflow of an event.
2854
2940
  */
@@ -3008,6 +3094,7 @@ var DisabledWorkflowContext = class _DisabledWorkflowContext extends WorkflowCon
3008
3094
  initialPayload: context.requestPayload,
3009
3095
  env: context.env,
3010
3096
  retries: context.retries,
3097
+ retryDelay: context.retryDelay,
3011
3098
  flowControl: context.flowControl
3012
3099
  });
3013
3100
  try {
@@ -3016,6 +3103,9 @@ var DisabledWorkflowContext = class _DisabledWorkflowContext extends WorkflowCon
3016
3103
  if (error instanceof WorkflowAbort && error.stepName === this.disabledMessage || error instanceof WorkflowNonRetryableError) {
3017
3104
  return ok("step-found");
3018
3105
  }
3106
+ console.warn(
3107
+ "Upstash Workflow: Received an error while authorizing request. Please avoid throwing errors before the first step of your workflow."
3108
+ );
3019
3109
  return err(error);
3020
3110
  }
3021
3111
  return ok("run-ended");
@@ -3157,9 +3247,9 @@ var parseRequest = async (requestPayload, isFirstInvocation, workflowRunId, requ
3157
3247
  };
3158
3248
  }
3159
3249
  };
3160
- var handleFailure = async (request, requestPayload, qstashClient, initialPayloadParser, routeFunction, failureFunction, env, retries, flowControl, debug) => {
3250
+ var handleFailure = async (request, requestPayload, qstashClient, initialPayloadParser, routeFunction, failureFunction, env, retries, retryDelay, flowControl, debug) => {
3161
3251
  if (request.headers.get(WORKFLOW_FAILURE_HEADER) !== "true") {
3162
- return ok("not-failure-callback");
3252
+ return ok({ result: "not-failure-callback" });
3163
3253
  }
3164
3254
  if (!failureFunction) {
3165
3255
  return err(
@@ -3171,7 +3261,17 @@ var handleFailure = async (request, requestPayload, qstashClient, initialPayload
3171
3261
  try {
3172
3262
  const { status, header, body, url, sourceBody, workflowRunId } = JSON.parse(requestPayload);
3173
3263
  const decodedBody = body ? decodeBase64(body) : "{}";
3174
- const errorPayload = JSON.parse(decodedBody);
3264
+ let errorMessage = "";
3265
+ try {
3266
+ const errorPayload = JSON.parse(decodedBody);
3267
+ if (errorPayload.message) {
3268
+ errorMessage = errorPayload.message;
3269
+ }
3270
+ } catch {
3271
+ }
3272
+ if (!errorMessage) {
3273
+ errorMessage = `Couldn't parse 'failResponse' in 'failureFunction', received: '${decodedBody}'`;
3274
+ }
3175
3275
  const workflowContext = new WorkflowContext({
3176
3276
  qstashClient,
3177
3277
  workflowRunId,
@@ -3183,6 +3283,7 @@ var handleFailure = async (request, requestPayload, qstashClient, initialPayload
3183
3283
  debug,
3184
3284
  env,
3185
3285
  retries,
3286
+ retryDelay,
3186
3287
  flowControl,
3187
3288
  telemetry: void 0
3188
3289
  // not going to make requests in authentication check
@@ -3197,16 +3298,16 @@ var handleFailure = async (request, requestPayload, qstashClient, initialPayload
3197
3298
  } else if (authCheck.value === "run-ended") {
3198
3299
  return err(new WorkflowError("Not authorized to run the failure function."));
3199
3300
  }
3200
- await failureFunction({
3301
+ const failureResponse = await failureFunction({
3201
3302
  context: workflowContext,
3202
3303
  failStatus: status,
3203
- failResponse: errorPayload.message,
3304
+ failResponse: errorMessage,
3204
3305
  failHeaders: header
3205
3306
  });
3307
+ return ok({ result: "is-failure-callback", response: failureResponse });
3206
3308
  } catch (error) {
3207
3309
  return err(error);
3208
3310
  }
3209
- return ok("is-failure-callback");
3210
3311
  };
3211
3312
 
3212
3313
  // src/serve/options.ts
@@ -3222,8 +3323,8 @@ var processOptions = (options) => {
3222
3323
  baseUrl: environment.QSTASH_URL,
3223
3324
  token: environment.QSTASH_TOKEN
3224
3325
  }),
3225
- onStepFinish: (workflowRunId, finishCondition) => {
3226
- if (finishCondition === "auth-fail") {
3326
+ onStepFinish: (workflowRunId, _finishCondition, detailedFinishCondition) => {
3327
+ if (detailedFinishCondition?.condition === "auth-fail") {
3227
3328
  console.error(AUTH_FAIL_MESSAGE);
3228
3329
  return new Response(
3229
3330
  JSON.stringify({
@@ -3231,19 +3332,33 @@ var processOptions = (options) => {
3231
3332
  workflowRunId
3232
3333
  }),
3233
3334
  {
3234
- status: 400
3335
+ status: 400,
3336
+ headers: {
3337
+ [WORKFLOW_PROTOCOL_VERSION_HEADER]: WORKFLOW_PROTOCOL_VERSION
3338
+ }
3235
3339
  }
3236
3340
  );
3237
- } else if (finishCondition instanceof WorkflowNonRetryableError) {
3238
- return new Response(JSON.stringify(formatWorkflowError(finishCondition)), {
3341
+ } else if (detailedFinishCondition?.condition === "non-retryable-error") {
3342
+ return new Response(JSON.stringify(formatWorkflowError(detailedFinishCondition.result)), {
3239
3343
  headers: {
3240
- "Upstash-NonRetryable-Error": "true"
3344
+ "Upstash-NonRetryable-Error": "true",
3345
+ [WORKFLOW_PROTOCOL_VERSION_HEADER]: WORKFLOW_PROTOCOL_VERSION
3241
3346
  },
3242
3347
  status: 489
3243
3348
  });
3349
+ } else if (detailedFinishCondition?.condition === "failure-callback") {
3350
+ return new Response(detailedFinishCondition.result ?? void 0, {
3351
+ status: 200,
3352
+ headers: {
3353
+ [WORKFLOW_PROTOCOL_VERSION_HEADER]: WORKFLOW_PROTOCOL_VERSION
3354
+ }
3355
+ });
3244
3356
  }
3245
3357
  return new Response(JSON.stringify({ workflowRunId }), {
3246
- status: 200
3358
+ status: 200,
3359
+ headers: {
3360
+ [WORKFLOW_PROTOCOL_VERSION_HEADER]: WORKFLOW_PROTOCOL_VERSION
3361
+ }
3247
3362
  });
3248
3363
  },
3249
3364
  initialPayloadParser: (initialRequest) => {
@@ -3317,6 +3432,7 @@ var serveBase = (routeFunction, telemetry2, options) => {
3317
3432
  baseUrl,
3318
3433
  env,
3319
3434
  retries,
3435
+ retryDelay,
3320
3436
  useJSONContent,
3321
3437
  disableTelemetry,
3322
3438
  flowControl,
@@ -3347,10 +3463,14 @@ var serveBase = (routeFunction, telemetry2, options) => {
3347
3463
  debug
3348
3464
  );
3349
3465
  if (workflowRunEnded) {
3350
- return onStepFinish(workflowRunId, "workflow-already-ended");
3466
+ return onStepFinish(workflowRunId, "workflow-already-ended", {
3467
+ condition: "workflow-already-ended"
3468
+ });
3351
3469
  }
3352
3470
  if (isLastDuplicate) {
3353
- return onStepFinish(workflowRunId, "duplicate-step");
3471
+ return onStepFinish(workflowRunId, "duplicate-step", {
3472
+ condition: "duplicate-step"
3473
+ });
3354
3474
  }
3355
3475
  const failureCheck = await handleFailure(
3356
3476
  request,
@@ -3361,14 +3481,18 @@ var serveBase = (routeFunction, telemetry2, options) => {
3361
3481
  failureFunction,
3362
3482
  env,
3363
3483
  retries,
3484
+ retryDelay,
3364
3485
  flowControl,
3365
3486
  debug
3366
3487
  );
3367
3488
  if (failureCheck.isErr()) {
3368
3489
  throw failureCheck.error;
3369
- } else if (failureCheck.value === "is-failure-callback") {
3490
+ } else if (failureCheck.value.result === "is-failure-callback") {
3370
3491
  await debug?.log("WARN", "RESPONSE_DEFAULT", "failureFunction executed");
3371
- return onStepFinish(workflowRunId, "failure-callback");
3492
+ return onStepFinish(workflowRunId, "failure-callback", {
3493
+ condition: "failure-callback",
3494
+ result: failureCheck.value.response
3495
+ });
3372
3496
  }
3373
3497
  const invokeCount = Number(request.headers.get(WORKFLOW_INVOKE_COUNT_HEADER) ?? "0");
3374
3498
  const workflowContext = new WorkflowContext({
@@ -3382,6 +3506,7 @@ var serveBase = (routeFunction, telemetry2, options) => {
3382
3506
  debug,
3383
3507
  env,
3384
3508
  retries,
3509
+ retryDelay,
3385
3510
  telemetry: telemetry2,
3386
3511
  invokeCount,
3387
3512
  flowControl
@@ -3397,7 +3522,8 @@ var serveBase = (routeFunction, telemetry2, options) => {
3397
3522
  await debug?.log("ERROR", "ERROR", { error: AUTH_FAIL_MESSAGE });
3398
3523
  return onStepFinish(
3399
3524
  isFirstInvocation ? "no-workflow-id" : workflowContext.workflowRunId,
3400
- "auth-fail"
3525
+ "auth-fail",
3526
+ { condition: "auth-fail" }
3401
3527
  );
3402
3528
  }
3403
3529
  const callReturnCheck = await handleThirdPartyCallResult({
@@ -3407,6 +3533,7 @@ var serveBase = (routeFunction, telemetry2, options) => {
3407
3533
  workflowUrl,
3408
3534
  failureUrl: workflowFailureUrl,
3409
3535
  retries,
3536
+ retryDelay,
3410
3537
  flowControl,
3411
3538
  telemetry: telemetry2,
3412
3539
  debug
@@ -3434,19 +3561,28 @@ var serveBase = (routeFunction, telemetry2, options) => {
3434
3561
  debug
3435
3562
  });
3436
3563
  if (result.isOk() && result.value instanceof WorkflowNonRetryableError) {
3437
- return onStepFinish(workflowRunId, result.value);
3564
+ return onStepFinish(workflowRunId, result.value, {
3565
+ condition: "non-retryable-error",
3566
+ result: result.value
3567
+ });
3438
3568
  }
3439
3569
  if (result.isErr()) {
3440
3570
  await debug?.log("ERROR", "ERROR", { error: result.error.message });
3441
3571
  throw result.error;
3442
3572
  }
3443
3573
  await debug?.log("INFO", "RESPONSE_WORKFLOW");
3444
- return onStepFinish(workflowContext.workflowRunId, "success");
3574
+ return onStepFinish(workflowContext.workflowRunId, "success", {
3575
+ condition: "success"
3576
+ });
3445
3577
  } else if (callReturnCheck.value === "workflow-ended") {
3446
- return onStepFinish(workflowContext.workflowRunId, "workflow-already-ended");
3578
+ return onStepFinish(workflowContext.workflowRunId, "workflow-already-ended", {
3579
+ condition: "workflow-already-ended"
3580
+ });
3447
3581
  }
3448
3582
  await debug?.log("INFO", "RESPONSE_DEFAULT");
3449
- return onStepFinish("no-workflow-id", "fromCallback");
3583
+ return onStepFinish("no-workflow-id", "fromCallback", {
3584
+ condition: "fromCallback"
3585
+ });
3450
3586
  };
3451
3587
  const safeHandler = async (request) => {
3452
3588
  try {
@@ -3461,11 +3597,17 @@ var serveBase = (routeFunction, telemetry2, options) => {
3461
3597
  Original error: '${formattedError.message}'`;
3462
3598
  console.error(errorMessage);
3463
3599
  return new Response(errorMessage, {
3464
- status: 500
3600
+ status: 500,
3601
+ headers: {
3602
+ [WORKFLOW_PROTOCOL_VERSION_HEADER]: WORKFLOW_PROTOCOL_VERSION
3603
+ }
3465
3604
  });
3466
3605
  }
3467
3606
  return new Response(JSON.stringify(formattedError), {
3468
- status: 500
3607
+ status: 500,
3608
+ headers: {
3609
+ [WORKFLOW_PROTOCOL_VERSION_HEADER]: WORKFLOW_PROTOCOL_VERSION
3610
+ }
3469
3611
  });
3470
3612
  }
3471
3613
  };
package/hono.mjs CHANGED
@@ -2,7 +2,7 @@ import {
2
2
  SDK_TELEMETRY,
3
3
  serveBase,
4
4
  serveManyBase
5
- } from "./chunk-AC5CQCN3.mjs";
5
+ } from "./chunk-RP7G4UD5.mjs";
6
6
 
7
7
  // platforms/hono.ts
8
8
  var telemetry = {