@upstash/workflow 0.2.1 → 0.2.2

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/index.js CHANGED
@@ -20,7 +20,7 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
20
20
  // src/index.ts
21
21
  var src_exports = {};
22
22
  __export(src_exports, {
23
- Client: () => Client3,
23
+ Client: () => Client4,
24
24
  StepTypes: () => StepTypes,
25
25
  WorkflowAbort: () => WorkflowAbort,
26
26
  WorkflowContext: () => WorkflowContext,
@@ -30,48 +30,8 @@ __export(src_exports, {
30
30
  });
31
31
  module.exports = __toCommonJS(src_exports);
32
32
 
33
- // src/error.ts
34
- var import_qstash = require("@upstash/qstash");
35
- var WorkflowError = class extends import_qstash.QstashError {
36
- constructor(message) {
37
- super(message);
38
- this.name = "WorkflowError";
39
- }
40
- };
41
- var WorkflowAbort = class extends Error {
42
- stepInfo;
43
- stepName;
44
- /**
45
- * whether workflow is to be canceled on abort
46
- */
47
- cancelWorkflow;
48
- /**
49
- *
50
- * @param stepName name of the aborting step
51
- * @param stepInfo step information
52
- * @param cancelWorkflow
53
- */
54
- constructor(stepName, stepInfo, cancelWorkflow = false) {
55
- super(
56
- `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}'.`
57
- );
58
- this.name = "WorkflowAbort";
59
- this.stepName = stepName;
60
- this.stepInfo = stepInfo;
61
- this.cancelWorkflow = cancelWorkflow;
62
- }
63
- };
64
- var formatWorkflowError = (error) => {
65
- return error instanceof Error ? {
66
- error: error.name,
67
- message: error.message
68
- } : {
69
- error: "Error",
70
- message: "An error occured while executing workflow."
71
- };
72
- };
73
-
74
33
  // src/client/utils.ts
34
+ var import_qstash = require("@upstash/qstash");
75
35
  var makeNotifyRequest = async (requester, eventId, eventData) => {
76
36
  const result = await requester.request({
77
37
  path: ["v2", "notify", eventId],
@@ -105,26 +65,71 @@ var getSteps = async (requester, workflowRunId, messageId, debug) => {
105
65
  await debug?.log("INFO", "ENDPOINT_START", {
106
66
  message: `Pulled ${steps.length} steps from QStashand returned them without filtering with messageId.`
107
67
  });
108
- return steps;
68
+ return { steps, workflowRunEnded: false };
109
69
  } else {
110
70
  const index = steps.findIndex((item) => item.messageId === messageId);
111
71
  if (index === -1) {
112
- return [];
72
+ return { steps: [], workflowRunEnded: false };
113
73
  }
114
74
  const filteredSteps = steps.slice(0, index + 1);
115
75
  await debug?.log("INFO", "ENDPOINT_START", {
116
76
  message: `Pulled ${steps.length} steps from QStash and filtered them to ${filteredSteps.length} using messageId.`
117
77
  });
118
- return filteredSteps;
78
+ return { steps: filteredSteps, workflowRunEnded: false };
119
79
  }
120
80
  } catch (error) {
121
- await debug?.log("ERROR", "ERROR", {
122
- message: "failed while fetching steps.",
123
- error
124
- });
125
- throw new WorkflowError(`Failed while pulling steps. ${error}`);
81
+ if (error instanceof import_qstash.QstashError && error.status === 404) {
82
+ await debug?.log("WARN", "ENDPOINT_START", {
83
+ message: "Couldn't fetch workflow run steps. This can happen if the workflow run succesfully ends before some callback is executed.",
84
+ error
85
+ });
86
+ return { steps: void 0, workflowRunEnded: true };
87
+ } else {
88
+ throw error;
89
+ }
90
+ }
91
+ };
92
+
93
+ // src/error.ts
94
+ var import_qstash2 = require("@upstash/qstash");
95
+ var WorkflowError = class extends import_qstash2.QstashError {
96
+ constructor(message) {
97
+ super(message);
98
+ this.name = "WorkflowError";
99
+ }
100
+ };
101
+ var WorkflowAbort = class extends Error {
102
+ stepInfo;
103
+ stepName;
104
+ /**
105
+ * whether workflow is to be canceled on abort
106
+ */
107
+ cancelWorkflow;
108
+ /**
109
+ *
110
+ * @param stepName name of the aborting step
111
+ * @param stepInfo step information
112
+ * @param cancelWorkflow
113
+ */
114
+ constructor(stepName, stepInfo, cancelWorkflow = false) {
115
+ super(
116
+ `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}'.`
117
+ );
118
+ this.name = "WorkflowAbort";
119
+ this.stepName = stepName;
120
+ this.stepInfo = stepInfo;
121
+ this.cancelWorkflow = cancelWorkflow;
126
122
  }
127
123
  };
124
+ var formatWorkflowError = (error) => {
125
+ return error instanceof Error ? {
126
+ error: error.name,
127
+ message: error.message
128
+ } : {
129
+ error: "Error",
130
+ message: "An error occured while executing workflow."
131
+ };
132
+ };
128
133
 
129
134
  // src/context/steps.ts
130
135
  var BaseLazyStep = class {
@@ -746,8 +751,8 @@ var StepTypes = [
746
751
  ];
747
752
 
748
753
  // src/workflow-requests.ts
749
- var import_qstash2 = require("@upstash/qstash");
750
- var triggerFirstInvocation = async (workflowContext, retries, debug) => {
754
+ var import_qstash3 = require("@upstash/qstash");
755
+ var triggerFirstInvocation = async (workflowContext, retries, useJSONContent, debug) => {
751
756
  const { headers } = getHeaders(
752
757
  "true",
753
758
  workflowContext.workflowRunId,
@@ -757,6 +762,9 @@ var triggerFirstInvocation = async (workflowContext, retries, debug) => {
757
762
  workflowContext.failureUrl,
758
763
  retries
759
764
  );
765
+ if (useJSONContent) {
766
+ headers["content-type"] = "application/json";
767
+ }
760
768
  try {
761
769
  const body = typeof workflowContext.requestPayload === "string" ? workflowContext.requestPayload : JSON.stringify(workflowContext.requestPayload);
762
770
  const result = await workflowContext.qstashClient.publish({
@@ -800,7 +808,7 @@ var triggerRouteFunction = async ({
800
808
  return ok("workflow-finished");
801
809
  } catch (error) {
802
810
  const error_ = error;
803
- if (error instanceof import_qstash2.QstashError && error.status === 400) {
811
+ if (error instanceof import_qstash3.QstashError && error.status === 400) {
804
812
  await debug?.log("WARN", "RESPONSE_WORKFLOW", {
805
813
  message: `tried to append to a cancelled workflow. exiting without publishing.`,
806
814
  name: error.name,
@@ -834,7 +842,7 @@ var triggerWorkflowDelete = async (workflowContext, debug, cancel = false) => {
834
842
  );
835
843
  return { deleted: true };
836
844
  } catch (error) {
837
- if (error instanceof import_qstash2.QstashError && error.status === 404) {
845
+ if (error instanceof import_qstash3.QstashError && error.status === 404) {
838
846
  await debug?.log("WARN", "SUBMIT_CLEANUP", {
839
847
  message: `Failed to remove workflow run ${workflowContext.workflowRunId} as it doesn't exist.`,
840
848
  name: error.name,
@@ -871,11 +879,19 @@ var handleThirdPartyCallResult = async (request, requestPayload, client, workflo
871
879
  if (!workflowRunId2)
872
880
  throw new WorkflowError("workflow run id missing in context.call lazy fetch.");
873
881
  if (!messageId) throw new WorkflowError("message id missing in context.call lazy fetch.");
874
- const steps = await getSteps(client.http, workflowRunId2, messageId, debug);
882
+ const { steps, workflowRunEnded } = await getSteps(
883
+ client.http,
884
+ workflowRunId2,
885
+ messageId,
886
+ debug
887
+ );
888
+ if (workflowRunEnded) {
889
+ return ok("workflow-ended");
890
+ }
875
891
  const failingStep = steps.find((step) => step.messageId === messageId);
876
892
  if (!failingStep)
877
893
  throw new WorkflowError(
878
- "Failed to submit the context.call." + (steps.length === 0 ? "No steps found." : `No step was found with matching messageId ${messageId} out of ${steps.length} steps.`)
894
+ "Failed to submit the context.call. " + (steps.length === 0 ? "No steps found." : `No step was found with matching messageId ${messageId} out of ${steps.length} steps.`)
879
895
  );
880
896
  callbackPayload = atob(failingStep.body);
881
897
  }
@@ -1914,7 +1930,7 @@ function decodeBase64(base64) {
1914
1930
  }
1915
1931
 
1916
1932
  // src/serve/authorization.ts
1917
- var import_qstash3 = require("@upstash/qstash");
1933
+ var import_qstash4 = require("@upstash/qstash");
1918
1934
  var DisabledWorkflowContext = class _DisabledWorkflowContext extends WorkflowContext {
1919
1935
  static disabledMessage = "disabled-qstash-worklfow-run";
1920
1936
  /**
@@ -1945,7 +1961,7 @@ var DisabledWorkflowContext = class _DisabledWorkflowContext extends WorkflowCon
1945
1961
  */
1946
1962
  static async tryAuthentication(routeFunction, context) {
1947
1963
  const disabledContext = new _DisabledWorkflowContext({
1948
- qstashClient: new import_qstash3.Client({
1964
+ qstashClient: new import_qstash4.Client({
1949
1965
  baseUrl: "disabled-client",
1950
1966
  token: "disabled-client"
1951
1967
  }),
@@ -2069,7 +2085,8 @@ var parseRequest = async (requestPayload, isFirstInvocation, workflowRunId, requ
2069
2085
  return {
2070
2086
  rawInitialPayload: requestPayload ?? "",
2071
2087
  steps: [],
2072
- isLastDuplicate: false
2088
+ isLastDuplicate: false,
2089
+ workflowRunEnded: false
2073
2090
  };
2074
2091
  } else {
2075
2092
  let rawSteps;
@@ -2079,7 +2096,21 @@ var parseRequest = async (requestPayload, isFirstInvocation, workflowRunId, requ
2079
2096
  "ENDPOINT_START",
2080
2097
  "request payload is empty, steps will be fetched from QStash."
2081
2098
  );
2082
- rawSteps = await getSteps(requester, workflowRunId, messageId, debug);
2099
+ const { steps: fetchedSteps, workflowRunEnded } = await getSteps(
2100
+ requester,
2101
+ workflowRunId,
2102
+ messageId,
2103
+ debug
2104
+ );
2105
+ if (workflowRunEnded) {
2106
+ return {
2107
+ rawInitialPayload: void 0,
2108
+ steps: void 0,
2109
+ isLastDuplicate: void 0,
2110
+ workflowRunEnded: true
2111
+ };
2112
+ }
2113
+ rawSteps = fetchedSteps;
2083
2114
  } else {
2084
2115
  rawSteps = JSON.parse(requestPayload);
2085
2116
  }
@@ -2089,7 +2120,8 @@ var parseRequest = async (requestPayload, isFirstInvocation, workflowRunId, requ
2089
2120
  return {
2090
2121
  rawInitialPayload,
2091
2122
  steps: deduplicatedSteps,
2092
- isLastDuplicate
2123
+ isLastDuplicate,
2124
+ workflowRunEnded: false
2093
2125
  };
2094
2126
  }
2095
2127
  };
@@ -2143,15 +2175,15 @@ var handleFailure = async (request, requestPayload, qstashClient, initialPayload
2143
2175
  };
2144
2176
 
2145
2177
  // src/serve/options.ts
2146
- var import_qstash4 = require("@upstash/qstash");
2147
2178
  var import_qstash5 = require("@upstash/qstash");
2179
+ var import_qstash6 = require("@upstash/qstash");
2148
2180
  var processOptions = (options) => {
2149
2181
  const environment = options?.env ?? (typeof process === "undefined" ? {} : process.env);
2150
2182
  const receiverEnvironmentVariablesSet = Boolean(
2151
2183
  environment.QSTASH_CURRENT_SIGNING_KEY && environment.QSTASH_NEXT_SIGNING_KEY
2152
2184
  );
2153
2185
  return {
2154
- qstashClient: new import_qstash5.Client({
2186
+ qstashClient: new import_qstash6.Client({
2155
2187
  baseUrl: environment.QSTASH_URL,
2156
2188
  token: environment.QSTASH_TOKEN
2157
2189
  }),
@@ -2185,13 +2217,14 @@ var processOptions = (options) => {
2185
2217
  throw error;
2186
2218
  }
2187
2219
  },
2188
- receiver: receiverEnvironmentVariablesSet ? new import_qstash4.Receiver({
2220
+ receiver: receiverEnvironmentVariablesSet ? new import_qstash5.Receiver({
2189
2221
  currentSigningKey: environment.QSTASH_CURRENT_SIGNING_KEY,
2190
2222
  nextSigningKey: environment.QSTASH_NEXT_SIGNING_KEY
2191
2223
  }) : void 0,
2192
2224
  baseUrl: environment.UPSTASH_WORKFLOW_URL,
2193
2225
  env: environment,
2194
2226
  retries: DEFAULT_RETRIES,
2227
+ useJSONContent: false,
2195
2228
  ...options
2196
2229
  };
2197
2230
  };
@@ -2208,6 +2241,16 @@ var determineUrls = async (request, url, baseUrl, failureFunction, failureUrl, d
2208
2241
  });
2209
2242
  }
2210
2243
  const workflowFailureUrl = failureFunction ? workflowUrl : failureUrl;
2244
+ if (workflowUrl.includes("localhost")) {
2245
+ await debug?.log("WARN", "ENDPOINT_START", {
2246
+ message: `Workflow URL contains localhost. This can happen in local development, but shouldn't happen in production unless you have a route which contains localhost. Received: ${workflowUrl}`
2247
+ });
2248
+ }
2249
+ if (!(workflowUrl.startsWith("http://") || workflowUrl.startsWith("https://"))) {
2250
+ throw new WorkflowError(
2251
+ `Workflow URL should start with 'http://' or 'https://'. Recevied is '${workflowUrl}'`
2252
+ );
2253
+ }
2211
2254
  return {
2212
2255
  workflowUrl,
2213
2256
  workflowFailureUrl
@@ -2216,7 +2259,7 @@ var determineUrls = async (request, url, baseUrl, failureFunction, failureUrl, d
2216
2259
  var AUTH_FAIL_MESSAGE = `Failed to authenticate Workflow request. If this is unexpected, see the caveat https://upstash.com/docs/workflow/basics/caveats#avoid-non-deterministic-code-outside-context-run`;
2217
2260
 
2218
2261
  // src/serve/index.ts
2219
- var serve = (routeFunction, options) => {
2262
+ var serveBase = (routeFunction, options) => {
2220
2263
  const {
2221
2264
  qstashClient,
2222
2265
  onStepFinish,
@@ -2228,7 +2271,8 @@ var serve = (routeFunction, options) => {
2228
2271
  failureFunction,
2229
2272
  baseUrl,
2230
2273
  env,
2231
- retries
2274
+ retries,
2275
+ useJSONContent
2232
2276
  } = processOptions(options);
2233
2277
  const debug = WorkflowLogger.getLogger(verbose);
2234
2278
  const handler = async (request) => {
@@ -2245,7 +2289,7 @@ var serve = (routeFunction, options) => {
2245
2289
  await verifyRequest(requestPayload, request.headers.get("upstash-signature"), receiver);
2246
2290
  const { isFirstInvocation, workflowRunId } = validateRequest(request);
2247
2291
  debug?.setWorkflowRunId(workflowRunId);
2248
- const { rawInitialPayload, steps, isLastDuplicate } = await parseRequest(
2292
+ const { rawInitialPayload, steps, isLastDuplicate, workflowRunEnded } = await parseRequest(
2249
2293
  requestPayload,
2250
2294
  isFirstInvocation,
2251
2295
  workflowRunId,
@@ -2253,8 +2297,11 @@ var serve = (routeFunction, options) => {
2253
2297
  request.headers.get("upstash-message-id"),
2254
2298
  debug
2255
2299
  );
2300
+ if (workflowRunEnded) {
2301
+ return onStepFinish(workflowRunId, "workflow-already-ended");
2302
+ }
2256
2303
  if (isLastDuplicate) {
2257
- return onStepFinish("no-workflow-id", "duplicate-step");
2304
+ return onStepFinish(workflowRunId, "duplicate-step");
2258
2305
  }
2259
2306
  const failureCheck = await handleFailure(
2260
2307
  request,
@@ -2268,7 +2315,7 @@ var serve = (routeFunction, options) => {
2268
2315
  throw failureCheck.error;
2269
2316
  } else if (failureCheck.value === "is-failure-callback") {
2270
2317
  await debug?.log("WARN", "RESPONSE_DEFAULT", "failureFunction executed");
2271
- return onStepFinish("no-workflow-id", "failure-callback");
2318
+ return onStepFinish(workflowRunId, "failure-callback");
2272
2319
  }
2273
2320
  const workflowContext = new WorkflowContext({
2274
2321
  qstashClient,
@@ -2311,7 +2358,7 @@ var serve = (routeFunction, options) => {
2311
2358
  });
2312
2359
  throw callReturnCheck.error;
2313
2360
  } else if (callReturnCheck.value === "continue-workflow") {
2314
- const result = isFirstInvocation ? await triggerFirstInvocation(workflowContext, retries, debug) : await triggerRouteFunction({
2361
+ const result = isFirstInvocation ? await triggerFirstInvocation(workflowContext, retries, useJSONContent, debug) : await triggerRouteFunction({
2315
2362
  onStep: async () => routeFunction(workflowContext),
2316
2363
  onCleanup: async () => {
2317
2364
  await triggerWorkflowDelete(workflowContext, debug);
@@ -2327,6 +2374,8 @@ var serve = (routeFunction, options) => {
2327
2374
  }
2328
2375
  await debug?.log("INFO", "RESPONSE_WORKFLOW");
2329
2376
  return onStepFinish(workflowContext.workflowRunId, "success");
2377
+ } else if (callReturnCheck.value === "workflow-ended") {
2378
+ return onStepFinish(workflowContext.workflowRunId, "workflow-already-ended");
2330
2379
  }
2331
2380
  await debug?.log("INFO", "RESPONSE_DEFAULT");
2332
2381
  return onStepFinish("no-workflow-id", "fromCallback");
@@ -2343,10 +2392,13 @@ var serve = (routeFunction, options) => {
2343
2392
  };
2344
2393
  return { handler: safeHandler };
2345
2394
  };
2395
+ var serve = (routeFunction, options) => {
2396
+ return serveBase(routeFunction, options);
2397
+ };
2346
2398
 
2347
2399
  // src/client/index.ts
2348
- var import_qstash6 = require("@upstash/qstash");
2349
- var Client3 = class {
2400
+ var import_qstash7 = require("@upstash/qstash");
2401
+ var Client4 = class {
2350
2402
  client;
2351
2403
  constructor(clientConfig) {
2352
2404
  if (!clientConfig.token) {
@@ -2354,7 +2406,7 @@ var Client3 = class {
2354
2406
  "QStash token is required for Upstash Workflow!\n\nTo fix this:\n1. Get your token from the Upstash Console (https://console.upstash.com/qstash)\n2. Initialize the workflow client with:\n\n const client = new Client({\n token: '<YOUR_QSTASH_TOKEN>'\n });"
2355
2407
  );
2356
2408
  }
2357
- this.client = new import_qstash6.Client(clientConfig);
2409
+ this.client = new import_qstash7.Client(clientConfig);
2358
2410
  }
2359
2411
  /**
2360
2412
  * Cancel an ongoing workflow
package/index.mjs CHANGED
@@ -1,12 +1,198 @@
1
1
  import {
2
- Client,
2
+ DEFAULT_RETRIES,
3
3
  StepTypes,
4
4
  WorkflowAbort,
5
5
  WorkflowContext,
6
6
  WorkflowError,
7
7
  WorkflowLogger,
8
- serve
9
- } from "./chunk-ADOBNR4O.mjs";
8
+ getWorkflowRunId,
9
+ makeGetWaitersRequest,
10
+ makeNotifyRequest,
11
+ serve,
12
+ triggerFirstInvocation
13
+ } from "./chunk-Z7WS5XIR.mjs";
14
+
15
+ // src/client/index.ts
16
+ import { Client as QStashClient } from "@upstash/qstash";
17
+ var Client = class {
18
+ client;
19
+ constructor(clientConfig) {
20
+ if (!clientConfig.token) {
21
+ console.error(
22
+ "QStash token is required for Upstash Workflow!\n\nTo fix this:\n1. Get your token from the Upstash Console (https://console.upstash.com/qstash)\n2. Initialize the workflow client with:\n\n const client = new Client({\n token: '<YOUR_QSTASH_TOKEN>'\n });"
23
+ );
24
+ }
25
+ this.client = new QStashClient(clientConfig);
26
+ }
27
+ /**
28
+ * Cancel an ongoing workflow
29
+ *
30
+ * Returns true if workflow is canceled succesfully. Otherwise, throws error.
31
+ *
32
+ * There are multiple ways you can cancel workflows:
33
+ * - pass one or more workflow run ids to cancel them
34
+ * - pass a workflow url to cancel all runs starting with this url
35
+ * - cancel all pending or active workflow runs
36
+ *
37
+ * ### Cancel a set of workflow runs
38
+ *
39
+ * ```ts
40
+ * // cancel a single workflow
41
+ * await client.cancel({ ids: "<WORKFLOW_RUN_ID>" })
42
+ *
43
+ * // cancel a set of workflow runs
44
+ * await client.cancel({ ids: [
45
+ * "<WORKFLOW_RUN_ID_1>",
46
+ * "<WORKFLOW_RUN_ID_2>",
47
+ * ]})
48
+ * ```
49
+ *
50
+ * ### Cancel workflows starting with a url
51
+ *
52
+ * If you have an endpoint called `https://your-endpoint.com` and you
53
+ * want to cancel all workflow runs on it, you can use `urlStartingWith`.
54
+ *
55
+ * Note that this will cancel workflows in all endpoints under
56
+ * `https://your-endpoint.com`.
57
+ *
58
+ * ```ts
59
+ * await client.cancel({ urlStartingWith: "https://your-endpoint.com" })
60
+ * ```
61
+ *
62
+ * ### Cancel *all* workflows
63
+ *
64
+ * To cancel all pending and currently running workflows, you can
65
+ * do it like this:
66
+ *
67
+ * ```ts
68
+ * await client.cancel({ all: true })
69
+ * ```
70
+ *
71
+ * @param ids run id of the workflow to delete
72
+ * @param urlStartingWith cancel workflows starting with this url. Will be ignored
73
+ * if `ids` parameter is set.
74
+ * @param all set to true in order to cancel all workflows. Will be ignored
75
+ * if `ids` or `urlStartingWith` parameters are set.
76
+ * @returns true if workflow is succesfully deleted. Otherwise throws QStashError
77
+ */
78
+ async cancel({
79
+ ids,
80
+ urlStartingWith,
81
+ all
82
+ }) {
83
+ let body;
84
+ if (ids) {
85
+ const runIdArray = typeof ids === "string" ? [ids] : ids;
86
+ body = JSON.stringify({ workflowRunIds: runIdArray });
87
+ } else if (urlStartingWith) {
88
+ body = JSON.stringify({ workflowUrl: urlStartingWith });
89
+ } else if (all) {
90
+ body = "{}";
91
+ } else {
92
+ throw new TypeError("The `cancel` method cannot be called without any options.");
93
+ }
94
+ const result = await this.client.http.request({
95
+ path: ["v2", "workflows", "runs"],
96
+ method: "DELETE",
97
+ body,
98
+ headers: {
99
+ "Content-Type": "application/json"
100
+ }
101
+ });
102
+ return result;
103
+ }
104
+ /**
105
+ * Notify a workflow run waiting for an event
106
+ *
107
+ * ```ts
108
+ * import { Client } from "@upstash/workflow";
109
+ *
110
+ * const client = new Client({ token: "<QSTASH_TOKEN>" })
111
+ * await client.notify({
112
+ * eventId: "my-event-id",
113
+ * eventData: "my-data" // data passed to the workflow run
114
+ * });
115
+ * ```
116
+ *
117
+ * @param eventId event id to notify
118
+ * @param eventData data to provide to the workflow
119
+ */
120
+ async notify({
121
+ eventId,
122
+ eventData
123
+ }) {
124
+ return await makeNotifyRequest(this.client.http, eventId, eventData);
125
+ }
126
+ /**
127
+ * Check waiters of an event
128
+ *
129
+ * ```ts
130
+ * import { Client } from "@upstash/workflow";
131
+ *
132
+ * const client = new Client({ token: "<QSTASH_TOKEN>" })
133
+ * const result = await client.getWaiters({
134
+ * eventId: "my-event-id"
135
+ * })
136
+ * ```
137
+ *
138
+ * @param eventId event id to check
139
+ */
140
+ async getWaiters({ eventId }) {
141
+ return await makeGetWaitersRequest(this.client.http, eventId);
142
+ }
143
+ /**
144
+ * Trigger new workflow run and returns the workflow run id
145
+ *
146
+ * ```ts
147
+ * const { workflowRunId } = await client.trigger({
148
+ * url: "https://workflow-endpoint.com",
149
+ * body: "hello there!", // Optional body
150
+ * headers: { ... }, // Optional headers
151
+ * workflowRunId: "my-workflow", // Optional workflow run ID
152
+ * retries: 3 // Optional retries for the initial request
153
+ * });
154
+ *
155
+ * console.log(workflowRunId)
156
+ * // wfr_my-workflow
157
+ * ```
158
+ *
159
+ * @param url URL of the workflow
160
+ * @param body body to start the workflow with
161
+ * @param headers headers to use in the request
162
+ * @param workflowRunId optional workflow run id to use. mind that
163
+ * you should pass different workflow run ids for different runs.
164
+ * The final workflowRunId will be `wfr_${workflowRunId}`, in
165
+ * other words: the workflow run id you pass will be prefixed
166
+ * with `wfr_`.
167
+ * @param retries retry to use in the initial request. in the rest of
168
+ * the workflow, `retries` option of the `serve` will be used.
169
+ * @returns workflow run id
170
+ */
171
+ async trigger({
172
+ url,
173
+ body,
174
+ headers,
175
+ workflowRunId,
176
+ retries
177
+ }) {
178
+ const finalWorkflowRunId = getWorkflowRunId(workflowRunId);
179
+ const context = new WorkflowContext({
180
+ qstashClient: this.client,
181
+ // @ts-expect-error headers type mismatch
182
+ headers: new Headers(headers ?? {}),
183
+ initialPayload: body,
184
+ steps: [],
185
+ url,
186
+ workflowRunId: finalWorkflowRunId
187
+ });
188
+ const result = await triggerFirstInvocation(context, retries ?? DEFAULT_RETRIES);
189
+ if (result.isOk()) {
190
+ return { workflowRunId: finalWorkflowRunId };
191
+ } else {
192
+ throw result.error;
193
+ }
194
+ }
195
+ };
10
196
  export {
11
197
  Client,
12
198
  StepTypes,
package/nextjs.d.mts CHANGED
@@ -1,5 +1,5 @@
1
1
  import { NextApiHandler } from 'next';
2
- import { R as RouteFunction, W as WorkflowServeOptions } from './types-Be4hC1mu.mjs';
2
+ import { R as RouteFunction, j as PublicServeOptions } from './types-APRap-aV.mjs';
3
3
  import '@upstash/qstash';
4
4
 
5
5
  /**
@@ -11,10 +11,10 @@ import '@upstash/qstash';
11
11
  * @param options workflow options
12
12
  * @returns
13
13
  */
14
- declare const serve: <TInitialPayload = unknown>(routeFunction: RouteFunction<TInitialPayload>, options?: Omit<WorkflowServeOptions<Response, TInitialPayload>, "onStepFinish">) => {
14
+ declare const serve: <TInitialPayload = unknown>(routeFunction: RouteFunction<TInitialPayload>, options?: PublicServeOptions<TInitialPayload>) => {
15
15
  POST: (request: Request) => Promise<Response>;
16
16
  };
17
- declare const servePagesRouter: <TInitialPayload = unknown>(routeFunction: RouteFunction<TInitialPayload>, options?: Omit<WorkflowServeOptions<Response, TInitialPayload>, "onStepFinish">) => {
17
+ declare const servePagesRouter: <TInitialPayload = unknown>(routeFunction: RouteFunction<TInitialPayload>, options?: PublicServeOptions<TInitialPayload>) => {
18
18
  handler: NextApiHandler;
19
19
  };
20
20
 
package/nextjs.d.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  import { NextApiHandler } from 'next';
2
- import { R as RouteFunction, W as WorkflowServeOptions } from './types-Be4hC1mu.js';
2
+ import { R as RouteFunction, j as PublicServeOptions } from './types-APRap-aV.js';
3
3
  import '@upstash/qstash';
4
4
 
5
5
  /**
@@ -11,10 +11,10 @@ import '@upstash/qstash';
11
11
  * @param options workflow options
12
12
  * @returns
13
13
  */
14
- declare const serve: <TInitialPayload = unknown>(routeFunction: RouteFunction<TInitialPayload>, options?: Omit<WorkflowServeOptions<Response, TInitialPayload>, "onStepFinish">) => {
14
+ declare const serve: <TInitialPayload = unknown>(routeFunction: RouteFunction<TInitialPayload>, options?: PublicServeOptions<TInitialPayload>) => {
15
15
  POST: (request: Request) => Promise<Response>;
16
16
  };
17
- declare const servePagesRouter: <TInitialPayload = unknown>(routeFunction: RouteFunction<TInitialPayload>, options?: Omit<WorkflowServeOptions<Response, TInitialPayload>, "onStepFinish">) => {
17
+ declare const servePagesRouter: <TInitialPayload = unknown>(routeFunction: RouteFunction<TInitialPayload>, options?: PublicServeOptions<TInitialPayload>) => {
18
18
  handler: NextApiHandler;
19
19
  };
20
20