@upstash/workflow 0.2.22-rc → 0.2.23-rc

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/solidjs.js CHANGED
@@ -25,7 +25,95 @@ __export(solidjs_exports, {
25
25
  module.exports = __toCommonJS(solidjs_exports);
26
26
 
27
27
  // src/client/utils.ts
28
+ var import_qstash2 = require("@upstash/qstash");
29
+
30
+ // src/error.ts
28
31
  var import_qstash = require("@upstash/qstash");
32
+ var WorkflowError = class extends import_qstash.QstashError {
33
+ constructor(message) {
34
+ super(message);
35
+ this.name = "WorkflowError";
36
+ }
37
+ };
38
+ var WorkflowAbort = class extends Error {
39
+ stepInfo;
40
+ stepName;
41
+ /**
42
+ * whether workflow is to be canceled on abort
43
+ */
44
+ cancelWorkflow;
45
+ /**
46
+ *
47
+ * @param stepName name of the aborting step
48
+ * @param stepInfo step information
49
+ * @param cancelWorkflow
50
+ */
51
+ constructor(stepName, stepInfo, cancelWorkflow = false) {
52
+ super(
53
+ `This is an Upstash Workflow error thrown after a step executes. It is expected to be raised. Make sure that you await for each step. Also, if you are using try/catch blocks, you should not wrap context.run/sleep/sleepUntil/call methods with try/catch. Aborting workflow after executing step '${stepName}'.`
54
+ );
55
+ this.name = "WorkflowAbort";
56
+ this.stepName = stepName;
57
+ this.stepInfo = stepInfo;
58
+ this.cancelWorkflow = cancelWorkflow;
59
+ }
60
+ };
61
+ var WorkflowNonRetryableError = class extends WorkflowAbort {
62
+ /**
63
+ * @param message error message to be displayed
64
+ */
65
+ constructor(message) {
66
+ super("fail", void 0, false);
67
+ this.name = "WorkflowNonRetryableError";
68
+ if (message) this.message = message;
69
+ }
70
+ };
71
+ var WorkflowRetryAfterError = class extends WorkflowAbort {
72
+ retryAfter;
73
+ /**
74
+ * @param retryAfter time in seconds after which the workflow should be retried
75
+ * @param message error message to be displayed
76
+ */
77
+ constructor(message, retryAfter) {
78
+ super("retry", void 0, false);
79
+ this.name = "WorkflowRetryAfterError";
80
+ this.retryAfter = retryAfter;
81
+ if (message) this.message = message;
82
+ }
83
+ };
84
+ var formatWorkflowError = (error) => {
85
+ return error instanceof Error ? {
86
+ error: error.name,
87
+ message: error.message,
88
+ stack: error.stack
89
+ } : {
90
+ error: "Error",
91
+ message: `An error occured while executing workflow: '${typeof error === "string" ? error : JSON.stringify(error)}'`
92
+ };
93
+ };
94
+ function getConstructorName(obj) {
95
+ if (obj === null || obj === void 0) {
96
+ return null;
97
+ }
98
+ const ctor = obj.constructor;
99
+ if (!ctor || ctor.name === "Object") {
100
+ return null;
101
+ }
102
+ return ctor.name;
103
+ }
104
+ function getConstructorNames(obj) {
105
+ const proto = Object.getPrototypeOf(obj);
106
+ const name = getConstructorName(proto);
107
+ if (name === null) {
108
+ return [];
109
+ }
110
+ return [name, ...getConstructorNames(proto)];
111
+ }
112
+ function isInstanceOf(v, ctor) {
113
+ return getConstructorNames(v).includes(ctor.name);
114
+ }
115
+
116
+ // src/client/utils.ts
29
117
  var makeNotifyRequest = async (requester, eventId, eventData) => {
30
118
  const result = await requester.request({
31
119
  path: ["v2", "notify", eventId],
@@ -65,7 +153,7 @@ var getSteps = async (requester, workflowRunId, messageId, debug) => {
65
153
  return { steps: filteredSteps, workflowRunEnded: false };
66
154
  }
67
155
  } catch (error) {
68
- if (error instanceof import_qstash.QstashError && error.status === 404) {
156
+ if (isInstanceOf(error, import_qstash2.QstashError) && error.status === 404) {
69
157
  await debug?.log("WARN", "ENDPOINT_START", {
70
158
  message: "Couldn't fetch workflow run steps. This can happen if the workflow run succesfully ends before some callback is executed.",
71
159
  error
@@ -90,65 +178,13 @@ var WORKFLOW_PROTOCOL_VERSION_HEADER = "Upstash-Workflow-Sdk-Version";
90
178
  var DEFAULT_CONTENT_TYPE = "application/json";
91
179
  var NO_CONCURRENCY = 1;
92
180
  var DEFAULT_RETRIES = 3;
93
- var VERSION = "v0.2.21";
181
+ var VERSION = "v0.2.22";
94
182
  var SDK_TELEMETRY = `@upstash/workflow@${VERSION}`;
95
183
  var TELEMETRY_HEADER_SDK = "Upstash-Telemetry-Sdk";
96
184
  var TELEMETRY_HEADER_FRAMEWORK = "Upstash-Telemetry-Framework";
97
185
  var TELEMETRY_HEADER_RUNTIME = "Upstash-Telemetry-Runtime";
98
186
  var TELEMETRY_HEADER_AGENT = "Upstash-Telemetry-Agent";
99
187
 
100
- // src/error.ts
101
- var import_qstash2 = require("@upstash/qstash");
102
- var WorkflowError = class extends import_qstash2.QstashError {
103
- constructor(message) {
104
- super(message);
105
- this.name = "WorkflowError";
106
- }
107
- };
108
- var WorkflowAbort = class extends Error {
109
- stepInfo;
110
- stepName;
111
- /**
112
- * whether workflow is to be canceled on abort
113
- */
114
- cancelWorkflow;
115
- /**
116
- *
117
- * @param stepName name of the aborting step
118
- * @param stepInfo step information
119
- * @param cancelWorkflow
120
- */
121
- constructor(stepName, stepInfo, cancelWorkflow = false) {
122
- super(
123
- `This is an Upstash Workflow error thrown after a step executes. It is expected to be raised. Make sure that you await for each step. Also, if you are using try/catch blocks, you should not wrap context.run/sleep/sleepUntil/call methods with try/catch. Aborting workflow after executing step '${stepName}'.`
124
- );
125
- this.name = "WorkflowAbort";
126
- this.stepName = stepName;
127
- this.stepInfo = stepInfo;
128
- this.cancelWorkflow = cancelWorkflow;
129
- }
130
- };
131
- var WorkflowNonRetryableError = class extends WorkflowAbort {
132
- /**
133
- * @param message error message to be displayed
134
- */
135
- constructor(message) {
136
- super("fail", void 0, false);
137
- this.name = "WorkflowNonRetryableError";
138
- if (message) this.message = message;
139
- }
140
- };
141
- var formatWorkflowError = (error) => {
142
- return error instanceof Error ? {
143
- error: error.name,
144
- message: error.message,
145
- stack: error.stack
146
- } : {
147
- error: "Error",
148
- message: `An error occured while executing workflow: '${typeof error === "string" ? error : JSON.stringify(error)}'`
149
- };
150
- };
151
-
152
188
  // src/context/auto-executor.ts
153
189
  var import_qstash5 = require("@upstash/qstash");
154
190
 
@@ -161,8 +197,8 @@ var NANOID_LENGTH = 21;
161
197
  function getRandomInt() {
162
198
  return Math.floor(Math.random() * NANOID_CHARS.length);
163
199
  }
164
- function nanoid() {
165
- return Array.from({ length: NANOID_LENGTH }).map(() => NANOID_CHARS[getRandomInt()]).join("");
200
+ function nanoid(length = NANOID_LENGTH) {
201
+ return Array.from({ length }).map(() => NANOID_CHARS[getRandomInt()]).join("");
166
202
  }
167
203
  function getWorkflowRunId(id) {
168
204
  return `wfr_${id ?? nanoid()}`;
@@ -179,6 +215,37 @@ function decodeBase64(base64) {
179
215
  return binString;
180
216
  }
181
217
  }
218
+ function getUserIdFromToken(qstashClient) {
219
+ try {
220
+ const token = qstashClient.token;
221
+ const decodedToken = decodeBase64(token);
222
+ const tokenPayload = JSON.parse(decodedToken);
223
+ const userId = tokenPayload.UserID;
224
+ if (!userId) {
225
+ throw new WorkflowError("QStash token payload does not contain userId");
226
+ }
227
+ return userId;
228
+ } catch (error) {
229
+ throw new WorkflowError(
230
+ `Failed to decode QStash token while running create webhook step: ${error.message}`
231
+ );
232
+ }
233
+ }
234
+ function getQStashUrl(qstashClient) {
235
+ try {
236
+ const requester = qstashClient.http;
237
+ const baseUrl = requester.baseUrl;
238
+ if (!baseUrl) {
239
+ throw new WorkflowError("QStash client does not have a baseUrl");
240
+ }
241
+ return baseUrl;
242
+ } catch (error) {
243
+ throw new WorkflowError(`Failed to get QStash URL from client: ${error.message}`);
244
+ }
245
+ }
246
+ function getEventId() {
247
+ return `evt_${nanoid(15)}`;
248
+ }
182
249
 
183
250
  // node_modules/neverthrow/dist/index.es.js
184
251
  var defaultErrorConfig = {
@@ -604,7 +671,9 @@ var StepTypes = [
604
671
  "Call",
605
672
  "Wait",
606
673
  "Notify",
607
- "Invoke"
674
+ "Invoke",
675
+ "CreateWebhook",
676
+ "WaitForWebhook"
608
677
  ];
609
678
 
610
679
  // src/workflow-requests.ts
@@ -708,17 +777,17 @@ var triggerRouteFunction = async ({
708
777
  return ok("workflow-finished");
709
778
  } catch (error) {
710
779
  const error_ = error;
711
- if (error instanceof import_qstash3.QstashError && error.status === 400) {
780
+ if (isInstanceOf(error, import_qstash3.QstashError) && error.status === 400) {
712
781
  await debug?.log("WARN", "RESPONSE_WORKFLOW", {
713
782
  message: `tried to append to a cancelled workflow. exiting without publishing.`,
714
783
  name: error.name,
715
784
  errorMessage: error.message
716
785
  });
717
786
  return ok("workflow-was-finished");
718
- } else if (!(error_ instanceof WorkflowAbort)) {
719
- return err(error_);
720
- } else if (error_ instanceof WorkflowNonRetryableError) {
787
+ } else if (isInstanceOf(error_, WorkflowNonRetryableError) || isInstanceOf(error_, WorkflowRetryAfterError)) {
721
788
  return ok(error_);
789
+ } else if (!isInstanceOf(error_, WorkflowAbort)) {
790
+ return err(error_);
722
791
  } else if (error_.cancelWorkflow) {
723
792
  await onCancel();
724
793
  return ok("workflow-finished");
@@ -916,7 +985,9 @@ If you want to disable QStash Verification, you should clear env variables QSTAS
916
985
  // src/context/steps.ts
917
986
  var BaseLazyStep = class _BaseLazyStep {
918
987
  stepName;
919
- constructor(stepName) {
988
+ context;
989
+ constructor(context, stepName) {
990
+ this.context = context;
920
991
  if (!stepName) {
921
992
  throw new WorkflowError(
922
993
  "A workflow step name cannot be undefined or an empty string. Please provide a name for your workflow step."
@@ -934,13 +1005,14 @@ var BaseLazyStep = class _BaseLazyStep {
934
1005
  *
935
1006
  * will be called when returning the steps to the context from auto executor
936
1007
  *
937
- * @param out field of the step
1008
+ * @param step step
938
1009
  * @returns parsed out field
939
1010
  */
940
- parseOut(out) {
1011
+ parseOut(step) {
1012
+ const out = step.out;
941
1013
  if (out === void 0) {
942
1014
  if (this.allowUndefinedOut) {
943
- return void 0;
1015
+ return this.handleUndefinedOut(step);
944
1016
  } else {
945
1017
  throw new WorkflowError(
946
1018
  `Error while parsing output of ${this.stepType} step. Expected a string, but got: undefined`
@@ -948,27 +1020,26 @@ var BaseLazyStep = class _BaseLazyStep {
948
1020
  }
949
1021
  }
950
1022
  if (typeof out === "object") {
951
- if (this.stepType !== "Wait") {
952
- console.warn(
953
- `Error while parsing ${this.stepType} step output. Expected a string, but got object. Please reach out to Upstash Support.`
954
- );
955
- return out;
956
- }
957
- return {
958
- ...out,
959
- eventData: _BaseLazyStep.tryParsing(out.eventData)
960
- };
1023
+ console.warn(
1024
+ `Error while parsing ${this.stepType} step output. Expected a string, but got object. Please reach out to Upstash Support.`
1025
+ );
1026
+ return out;
961
1027
  }
962
1028
  if (typeof out !== "string") {
963
1029
  throw new WorkflowError(
964
1030
  `Error while parsing output of ${this.stepType} step. Expected a string or undefined, but got: ${typeof out}`
965
1031
  );
966
1032
  }
967
- return this.safeParseOut(out);
1033
+ return this.safeParseOut(out, step);
968
1034
  }
969
- safeParseOut(out) {
1035
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
1036
+ safeParseOut(out, step) {
970
1037
  return _BaseLazyStep.tryParsing(out);
971
1038
  }
1039
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
1040
+ handleUndefinedOut(step) {
1041
+ return void 0;
1042
+ }
972
1043
  static tryParsing(stepOut) {
973
1044
  try {
974
1045
  return JSON.parse(stepOut);
@@ -1019,8 +1090,8 @@ var LazyFunctionStep = class extends BaseLazyStep {
1019
1090
  stepFunction;
1020
1091
  stepType = "Run";
1021
1092
  allowUndefinedOut = true;
1022
- constructor(stepName, stepFunction) {
1023
- super(stepName);
1093
+ constructor(context, stepName, stepFunction) {
1094
+ super(context, stepName);
1024
1095
  this.stepFunction = stepFunction;
1025
1096
  }
1026
1097
  getPlanStep(concurrent, targetStep) {
@@ -1050,8 +1121,8 @@ var LazySleepStep = class extends BaseLazyStep {
1050
1121
  sleep;
1051
1122
  stepType = "SleepFor";
1052
1123
  allowUndefinedOut = true;
1053
- constructor(stepName, sleep) {
1054
- super(stepName);
1124
+ constructor(context, stepName, sleep) {
1125
+ super(context, stepName);
1055
1126
  this.sleep = sleep;
1056
1127
  }
1057
1128
  getPlanStep(concurrent, targetStep) {
@@ -1092,8 +1163,8 @@ var LazySleepUntilStep = class extends BaseLazyStep {
1092
1163
  sleepUntil;
1093
1164
  stepType = "SleepUntil";
1094
1165
  allowUndefinedOut = true;
1095
- constructor(stepName, sleepUntil) {
1096
- super(stepName);
1166
+ constructor(context, stepName, sleepUntil) {
1167
+ super(context, stepName);
1097
1168
  this.sleepUntil = sleepUntil;
1098
1169
  }
1099
1170
  getPlanStep(concurrent, targetStep) {
@@ -1145,8 +1216,8 @@ var LazyCallStep = class _LazyCallStep extends BaseLazyStep {
1145
1216
  stringifyBody;
1146
1217
  stepType = "Call";
1147
1218
  allowUndefinedOut = false;
1148
- constructor(stepName, url, method, body, headers, retries, retryDelay, timeout, flowControl, stringifyBody) {
1149
- super(stepName);
1219
+ constructor(context, stepName, url, method, body, headers, retries, retryDelay, timeout, flowControl, stringifyBody) {
1220
+ super(context, stepName);
1150
1221
  this.url = url;
1151
1222
  this.method = method;
1152
1223
  this.body = body;
@@ -1290,13 +1361,12 @@ var LazyCallStep = class _LazyCallStep extends BaseLazyStep {
1290
1361
  ]);
1291
1362
  }
1292
1363
  };
1293
- var LazyWaitForEventStep = class extends BaseLazyStep {
1364
+ var LazyWaitEventStep = class extends BaseLazyStep {
1294
1365
  eventId;
1295
1366
  timeout;
1296
- stepType = "Wait";
1297
1367
  allowUndefinedOut = false;
1298
- constructor(stepName, eventId, timeout) {
1299
- super(stepName);
1368
+ constructor(context, stepName, eventId, timeout) {
1369
+ super(context, stepName);
1300
1370
  this.eventId = eventId;
1301
1371
  this.timeout = timeout;
1302
1372
  }
@@ -1321,13 +1391,6 @@ var LazyWaitForEventStep = class extends BaseLazyStep {
1321
1391
  concurrent
1322
1392
  });
1323
1393
  }
1324
- safeParseOut(out) {
1325
- const result = JSON.parse(out);
1326
- return {
1327
- ...result,
1328
- eventData: BaseLazyStep.tryParsing(result.eventData)
1329
- };
1330
- }
1331
1394
  getHeaders({ context, telemetry, invokeCount, step }) {
1332
1395
  const headers = super.getHeaders({ context, telemetry, invokeCount, step });
1333
1396
  headers.headers["Upstash-Workflow-CallType"] = "step";
@@ -1361,7 +1424,7 @@ var LazyWaitForEventStep = class extends BaseLazyStep {
1361
1424
  timeoutHeaders,
1362
1425
  step: {
1363
1426
  stepId: step.stepId,
1364
- stepType: "Wait",
1427
+ stepType: this.stepType,
1365
1428
  stepName: step.stepName,
1366
1429
  concurrent: step.concurrent,
1367
1430
  targetStep: step.targetStep
@@ -1382,8 +1445,8 @@ var LazyWaitForEventStep = class extends BaseLazyStep {
1382
1445
  };
1383
1446
  var LazyNotifyStep = class extends LazyFunctionStep {
1384
1447
  stepType = "Notify";
1385
- constructor(stepName, eventId, eventData, requester) {
1386
- super(stepName, async () => {
1448
+ constructor(context, stepName, eventId, eventData, requester) {
1449
+ super(context, stepName, async () => {
1387
1450
  const notifyResponse = await makeNotifyRequest(requester, eventId, eventData);
1388
1451
  return {
1389
1452
  eventId,
@@ -1408,7 +1471,7 @@ var LazyInvokeStep = class extends BaseLazyStep {
1408
1471
  * workflow id of the invoked workflow
1409
1472
  */
1410
1473
  workflowId;
1411
- constructor(stepName, {
1474
+ constructor(context, stepName, {
1412
1475
  workflow,
1413
1476
  body,
1414
1477
  headers = {},
@@ -1418,7 +1481,7 @@ var LazyInvokeStep = class extends BaseLazyStep {
1418
1481
  flowControl,
1419
1482
  stringifyBody = true
1420
1483
  }) {
1421
- super(stepName);
1484
+ super(context, stepName);
1422
1485
  this.params = {
1423
1486
  workflow,
1424
1487
  body,
@@ -1479,6 +1542,9 @@ var LazyInvokeStep = class extends BaseLazyStep {
1479
1542
  userHeaders: context.headers,
1480
1543
  invokeCount
1481
1544
  });
1545
+ context.qstashClient.http.headers?.forEach((value, key) => {
1546
+ invokerHeaders[key] = value;
1547
+ });
1482
1548
  invokerHeaders["Upstash-Workflow-Runid"] = context.workflowRunId;
1483
1549
  let invokeBody;
1484
1550
  if (this.params.stringifyBody) {
@@ -1550,6 +1616,91 @@ var LazyInvokeStep = class extends BaseLazyStep {
1550
1616
  return [result];
1551
1617
  }
1552
1618
  };
1619
+ var LazyCreateWebhookStep = class extends BaseLazyStep {
1620
+ stepType = "CreateWebhook";
1621
+ allowUndefinedOut = false;
1622
+ getPlanStep(concurrent, targetStep) {
1623
+ return {
1624
+ stepId: 0,
1625
+ stepName: this.stepName,
1626
+ stepType: this.stepType,
1627
+ concurrent,
1628
+ targetStep
1629
+ };
1630
+ }
1631
+ async getResultStep(concurrent, stepId) {
1632
+ return {
1633
+ stepId,
1634
+ stepName: this.stepName,
1635
+ stepType: this.stepType,
1636
+ out: void 0,
1637
+ concurrent
1638
+ };
1639
+ }
1640
+ getBody({ step, context }) {
1641
+ const userId = getUserIdFromToken(context.qstashClient);
1642
+ const out = [userId, context.workflowRunId, getEventId()].join("/");
1643
+ return JSON.stringify({
1644
+ ...step,
1645
+ out
1646
+ });
1647
+ }
1648
+ safeParseOut(out) {
1649
+ const [userId, workflowRunId, eventId] = out.split("/");
1650
+ const qstashUrl = getQStashUrl(this.context.qstashClient);
1651
+ return {
1652
+ webhookUrl: `${qstashUrl}/v2/workflows/hooks/${userId}/${workflowRunId}/${eventId}`,
1653
+ eventId
1654
+ };
1655
+ }
1656
+ };
1657
+ var LazyWaitForWebhookStep = class extends LazyWaitEventStep {
1658
+ stepType = "WaitForWebhook";
1659
+ allowUndefinedOut = true;
1660
+ constructor(context, stepName, webhook, timeout) {
1661
+ super(context, stepName, webhook.eventId, timeout);
1662
+ }
1663
+ safeParseOut(out) {
1664
+ const eventData = decodeBase64(out);
1665
+ const parsedEventData = BaseLazyStep.tryParsing(eventData);
1666
+ const body = parsedEventData.body;
1667
+ const parsedBody = typeof body === "string" ? decodeBase64(body) : void 0;
1668
+ const request = new Request(
1669
+ `${parsedEventData.proto}://${parsedEventData.host}${parsedEventData.url}`,
1670
+ {
1671
+ method: parsedEventData.method,
1672
+ headers: parsedEventData.header,
1673
+ body: parsedBody
1674
+ }
1675
+ );
1676
+ return {
1677
+ request,
1678
+ timeout: false
1679
+ };
1680
+ }
1681
+ handleUndefinedOut() {
1682
+ return {
1683
+ timeout: true,
1684
+ request: void 0
1685
+ };
1686
+ }
1687
+ };
1688
+ var LazyWaitForEventStep = class extends LazyWaitEventStep {
1689
+ stepType = "Wait";
1690
+ allowUndefinedOut = true;
1691
+ parseWaitForEventOut(out, waitTimeout) {
1692
+ return {
1693
+ eventData: out ? BaseLazyStep.tryParsing(decodeBase64(out)) : void 0,
1694
+ timeout: waitTimeout ?? false
1695
+ };
1696
+ }
1697
+ safeParseOut(out, step) {
1698
+ return this.parseWaitForEventOut(out, step.waitTimeout);
1699
+ }
1700
+ handleUndefinedOut(step) {
1701
+ return this.parseWaitForEventOut(void 0, step.waitTimeout);
1702
+ }
1703
+ };
1553
1704
 
1554
1705
  // src/agents/constants.ts
1555
1706
  var AGENT_NAME_HEADER = "upstash-agent-name";
@@ -1954,7 +2105,7 @@ var AutoExecutor = class _AutoExecutor {
1954
2105
  step,
1955
2106
  stepCount: this.stepCount
1956
2107
  });
1957
- return lazyStep.parseOut(step.out);
2108
+ return lazyStep.parseOut(step);
1958
2109
  }
1959
2110
  const resultStep = await submitSingleStep({
1960
2111
  context: this.context,
@@ -2025,7 +2176,7 @@ var AutoExecutor = class _AutoExecutor {
2025
2176
  });
2026
2177
  throw new WorkflowAbort(parallelStep.stepName, resultStep);
2027
2178
  } catch (error) {
2028
- if (error instanceof WorkflowAbort || error instanceof import_qstash5.QstashError && error.status === 400) {
2179
+ if (isInstanceOf(error, WorkflowAbort) || isInstanceOf(error, import_qstash5.QstashError) && error.status === 400) {
2029
2180
  throw error;
2030
2181
  }
2031
2182
  throw new WorkflowError(
@@ -2041,7 +2192,7 @@ var AutoExecutor = class _AutoExecutor {
2041
2192
  const parallelResultSteps = sortedSteps.filter((step) => step.stepId >= initialStepCount).slice(0, parallelSteps.length);
2042
2193
  validateParallelSteps(parallelSteps, parallelResultSteps);
2043
2194
  return parallelResultSteps.map(
2044
- (step, index) => parallelSteps[index].parseOut(step.out)
2195
+ (step, index) => parallelSteps[index].parseOut(step)
2045
2196
  );
2046
2197
  }
2047
2198
  }
@@ -2097,7 +2248,6 @@ var AutoExecutor = class _AutoExecutor {
2097
2248
  * @param index index of the current step
2098
2249
  * @returns result[index] if lazyStepList > 1, otherwise result
2099
2250
  */
2100
- // eslint-disable-next-line @typescript-eslint/no-unnecessary-type-parameters
2101
2251
  static getResult(lazyStepList, result, index) {
2102
2252
  if (lazyStepList.length === 1) {
2103
2253
  return result;
@@ -2132,7 +2282,7 @@ var validateParallelSteps = (lazySteps, stepsFromRequest) => {
2132
2282
  validateStep(lazySteps[index], stepFromRequest);
2133
2283
  }
2134
2284
  } catch (error) {
2135
- if (error instanceof WorkflowError) {
2285
+ if (isInstanceOf(error, WorkflowError)) {
2136
2286
  const lazyStepNames = lazySteps.map((lazyStep) => lazyStep.stepName);
2137
2287
  const lazyStepTypes = lazySteps.map((lazyStep) => lazyStep.stepType);
2138
2288
  const requestStepNames = stepsFromRequest.map((step) => step.stepName);
@@ -2313,7 +2463,7 @@ var fetchWithContextCall = async (context, agentCallParams, ...params) => {
2313
2463
  headers: responseHeaders
2314
2464
  });
2315
2465
  } catch (error) {
2316
- if (error instanceof Error && error.name === "WorkflowAbort") {
2466
+ if (error instanceof Error && isInstanceOf(error, WorkflowAbort)) {
2317
2467
  throw error;
2318
2468
  } else {
2319
2469
  console.error("Error in fetch implementation:", error);
@@ -2415,10 +2565,10 @@ var Agent = class {
2415
2565
  });
2416
2566
  return { text: result.text };
2417
2567
  } catch (error) {
2418
- if (error instanceof import_ai2.ToolExecutionError) {
2419
- if (error.cause instanceof Error && error.cause.name === "WorkflowAbort") {
2568
+ if (isInstanceOf(error, import_ai2.ToolExecutionError)) {
2569
+ if (error.cause instanceof Error && isInstanceOf(error.cause, WorkflowAbort)) {
2420
2570
  throw error.cause;
2421
- } else if (error.cause instanceof import_ai2.ToolExecutionError && error.cause.cause instanceof Error && error.cause.cause.name === "WorkflowAbort") {
2571
+ } else if (isInstanceOf(error.cause, import_ai2.ToolExecutionError) && isInstanceOf(error.cause.cause, WorkflowAbort)) {
2422
2572
  throw error.cause.cause;
2423
2573
  } else {
2424
2574
  throw error;
@@ -2822,7 +2972,7 @@ var WorkflowContext = class {
2822
2972
  */
2823
2973
  async run(stepName, stepFunction) {
2824
2974
  const wrappedStepFunction = () => this.executor.wrapStep(stepName, stepFunction);
2825
- return await this.addStep(new LazyFunctionStep(stepName, wrappedStepFunction));
2975
+ return await this.addStep(new LazyFunctionStep(this, stepName, wrappedStepFunction));
2826
2976
  }
2827
2977
  /**
2828
2978
  * Stops the execution for the duration provided.
@@ -2836,7 +2986,7 @@ var WorkflowContext = class {
2836
2986
  * @returns undefined
2837
2987
  */
2838
2988
  async sleep(stepName, duration) {
2839
- await this.addStep(new LazySleepStep(stepName, duration));
2989
+ await this.addStep(new LazySleepStep(this, stepName, duration));
2840
2990
  }
2841
2991
  /**
2842
2992
  * Stops the execution until the date time provided.
@@ -2858,13 +3008,14 @@ var WorkflowContext = class {
2858
3008
  datetime = typeof datetime === "string" ? new Date(datetime) : datetime;
2859
3009
  time = Math.round(datetime.getTime() / 1e3);
2860
3010
  }
2861
- await this.addStep(new LazySleepUntilStep(stepName, time));
3011
+ await this.addStep(new LazySleepUntilStep(this, stepName, time));
2862
3012
  }
2863
3013
  async call(stepName, settings) {
2864
3014
  let callStep;
2865
3015
  if ("workflow" in settings) {
2866
3016
  const url = getNewUrlFromWorkflowId(this.url, settings.workflow.workflowId);
2867
3017
  callStep = new LazyCallStep(
3018
+ this,
2868
3019
  stepName,
2869
3020
  url,
2870
3021
  "POST",
@@ -2889,6 +3040,7 @@ var WorkflowContext = class {
2889
3040
  stringifyBody = true
2890
3041
  } = settings;
2891
3042
  callStep = new LazyCallStep(
3043
+ this,
2892
3044
  stepName,
2893
3045
  url,
2894
3046
  method,
@@ -2940,7 +3092,9 @@ var WorkflowContext = class {
2940
3092
  async waitForEvent(stepName, eventId, options = {}) {
2941
3093
  const { timeout = "7d" } = options;
2942
3094
  const timeoutStr = typeof timeout === "string" ? timeout : `${timeout}s`;
2943
- return await this.addStep(new LazyWaitForEventStep(stepName, eventId, timeoutStr));
3095
+ return await this.addStep(
3096
+ new LazyWaitForEventStep(this, stepName, eventId, timeoutStr)
3097
+ );
2944
3098
  }
2945
3099
  /**
2946
3100
  * Notify workflow runs waiting for an event
@@ -2965,11 +3119,19 @@ var WorkflowContext = class {
2965
3119
  */
2966
3120
  async notify(stepName, eventId, eventData) {
2967
3121
  return await this.addStep(
2968
- new LazyNotifyStep(stepName, eventId, eventData, this.qstashClient.http)
3122
+ new LazyNotifyStep(this, stepName, eventId, eventData, this.qstashClient.http)
2969
3123
  );
2970
3124
  }
2971
3125
  async invoke(stepName, settings) {
2972
- return await this.addStep(new LazyInvokeStep(stepName, settings));
3126
+ return await this.addStep(
3127
+ new LazyInvokeStep(this, stepName, settings)
3128
+ );
3129
+ }
3130
+ async createWebhook(stepName) {
3131
+ return await this.addStep(new LazyCreateWebhookStep(this, stepName));
3132
+ }
3133
+ async waitForWebhook(stepName, webhook, timeout) {
3134
+ return await this.addStep(new LazyWaitForWebhookStep(this, stepName, webhook, timeout));
2973
3135
  }
2974
3136
  /**
2975
3137
  * Cancel the current workflow run
@@ -3100,7 +3262,7 @@ var DisabledWorkflowContext = class _DisabledWorkflowContext extends WorkflowCon
3100
3262
  try {
3101
3263
  await routeFunction(disabledContext);
3102
3264
  } catch (error) {
3103
- if (error instanceof WorkflowAbort && error.stepName === this.disabledMessage || error instanceof WorkflowNonRetryableError) {
3265
+ if (isInstanceOf(error, WorkflowAbort) && error.stepName === this.disabledMessage || isInstanceOf(error, WorkflowNonRetryableError) || isInstanceOf(error, WorkflowRetryAfterError)) {
3104
3266
  return ok("step-found");
3105
3267
  }
3106
3268
  console.warn(
@@ -3133,13 +3295,6 @@ var processRawSteps = (rawSteps) => {
3133
3295
  const stepsToDecode = encodedSteps.filter((step) => step.callType === "step");
3134
3296
  const otherSteps = stepsToDecode.map((rawStep) => {
3135
3297
  const step = JSON.parse(decodeBase64(rawStep.body));
3136
- if (step.waitEventId) {
3137
- const newOut = {
3138
- eventData: step.out ? decodeBase64(step.out) : void 0,
3139
- timeout: step.waitTimeout ?? false
3140
- };
3141
- step.out = newOut;
3142
- }
3143
3298
  return step;
3144
3299
  });
3145
3300
  const steps = [initialStep, ...otherSteps];
@@ -3353,13 +3508,24 @@ var processOptions = (options) => {
3353
3508
  },
3354
3509
  status: 489
3355
3510
  });
3356
- } else if (detailedFinishCondition?.condition === "failure-callback") {
3357
- return new Response(detailedFinishCondition.result ?? void 0, {
3358
- status: 200,
3511
+ } else if (detailedFinishCondition?.condition === "retry-after-error") {
3512
+ return new Response(JSON.stringify(formatWorkflowError(detailedFinishCondition.result)), {
3359
3513
  headers: {
3514
+ "Retry-After": detailedFinishCondition.result.retryAfter.toString(),
3360
3515
  [WORKFLOW_PROTOCOL_VERSION_HEADER]: WORKFLOW_PROTOCOL_VERSION
3361
- }
3516
+ },
3517
+ status: 429
3362
3518
  });
3519
+ } else if (detailedFinishCondition?.condition === "failure-callback") {
3520
+ return new Response(
3521
+ JSON.stringify({ result: detailedFinishCondition.result ?? void 0 }),
3522
+ {
3523
+ status: 200,
3524
+ headers: {
3525
+ [WORKFLOW_PROTOCOL_VERSION_HEADER]: WORKFLOW_PROTOCOL_VERSION
3526
+ }
3527
+ }
3528
+ );
3363
3529
  }
3364
3530
  return new Response(JSON.stringify({ workflowRunId }), {
3365
3531
  status: 200,
@@ -3569,12 +3735,18 @@ var serveBase = (routeFunction, telemetry, options) => {
3569
3735
  },
3570
3736
  debug
3571
3737
  });
3572
- if (result.isOk() && result.value instanceof WorkflowNonRetryableError) {
3738
+ if (result.isOk() && isInstanceOf(result.value, WorkflowNonRetryableError)) {
3573
3739
  return onStepFinish(workflowRunId, result.value, {
3574
3740
  condition: "non-retryable-error",
3575
3741
  result: result.value
3576
3742
  });
3577
3743
  }
3744
+ if (result.isOk() && isInstanceOf(result.value, WorkflowRetryAfterError)) {
3745
+ return onStepFinish(workflowRunId, result.value, {
3746
+ condition: "retry-after-error",
3747
+ result: result.value
3748
+ });
3749
+ }
3578
3750
  if (result.isErr()) {
3579
3751
  await debug?.log("ERROR", "ERROR", { error: result.error.message });
3580
3752
  throw result.error;
@@ -3605,7 +3777,7 @@ var serveBase = (routeFunction, telemetry, options) => {
3605
3777
  const errorMessage = `Error while running onError callback: '${formattedOnErrorError.message}'.
3606
3778
  Original error: '${formattedError.message}'`;
3607
3779
  console.error(errorMessage);
3608
- return new Response(errorMessage, {
3780
+ return new Response(JSON.stringify({ error: errorMessage }), {
3609
3781
  status: 500,
3610
3782
  headers: {
3611
3783
  [WORKFLOW_PROTOCOL_VERSION_HEADER]: WORKFLOW_PROTOCOL_VERSION