@upstash/workflow 1.2.0-demo-rc.1 → 1.2.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (51) hide show
  1. package/README.md +1 -0
  2. package/astro.d.mts +2 -2
  3. package/astro.d.ts +2 -2
  4. package/astro.js +72 -69
  5. package/astro.mjs +1 -1
  6. package/{chunk-NZCQPOPR.mjs → chunk-THS5AX2D.mjs} +128 -257
  7. package/cloudflare.d.mts +2 -2
  8. package/cloudflare.d.ts +2 -2
  9. package/cloudflare.js +72 -69
  10. package/cloudflare.mjs +1 -1
  11. package/express.d.mts +2 -2
  12. package/express.d.ts +2 -2
  13. package/express.js +72 -69
  14. package/express.mjs +1 -1
  15. package/h3.d.mts +2 -2
  16. package/h3.d.ts +2 -2
  17. package/h3.js +76 -73
  18. package/h3.mjs +5 -5
  19. package/hono.d.mts +2 -2
  20. package/hono.d.ts +2 -2
  21. package/hono.js +73 -265
  22. package/hono.mjs +2 -7
  23. package/index.d.mts +229 -138
  24. package/index.d.ts +229 -138
  25. package/index.js +275 -454
  26. package/index.mjs +144 -196
  27. package/nextjs.d.mts +2 -2
  28. package/nextjs.d.ts +2 -2
  29. package/nextjs.js +72 -263
  30. package/nextjs.mjs +1 -5
  31. package/package.json +1 -1
  32. package/react-router.d.mts +38 -0
  33. package/react-router.d.ts +38 -0
  34. package/react-router.js +3881 -0
  35. package/react-router.mjs +45 -0
  36. package/{serve-many-Bi8XaOyq.d.ts → serve-many-B-fe7bh7.d.ts} +1 -1
  37. package/{serve-many-CppVPJrh.d.mts → serve-many-C6sa_DxN.d.mts} +1 -1
  38. package/solidjs.d.mts +1 -1
  39. package/solidjs.d.ts +1 -1
  40. package/solidjs.js +72 -69
  41. package/solidjs.mjs +1 -1
  42. package/svelte.d.mts +2 -2
  43. package/svelte.d.ts +2 -2
  44. package/svelte.js +72 -69
  45. package/svelte.mjs +1 -1
  46. package/tanstack.d.mts +2 -2
  47. package/tanstack.d.ts +2 -2
  48. package/tanstack.js +72 -69
  49. package/tanstack.mjs +1 -1
  50. package/{types-CUwgrpCM.d.ts → types-B2S08hRU.d.mts} +18 -3
  51. package/{types-CUwgrpCM.d.mts → types-B2S08hRU.d.ts} +18 -3
package/index.mjs CHANGED
@@ -1,5 +1,4 @@
1
1
  import {
2
- DEV_QSTASH_TOKEN,
3
2
  SDK_TELEMETRY,
4
3
  StepTypes,
5
4
  WORKFLOW_LABEL_HEADER,
@@ -9,22 +8,34 @@ import {
9
8
  WorkflowMiddleware,
10
9
  WorkflowNonRetryableError,
11
10
  WorkflowRetryAfterError,
12
- ensureDevServer,
13
- getDevCredentials,
11
+ buildBulkActionQueryParameters,
14
12
  getWorkflowRunId,
15
13
  loggingMiddleware,
16
14
  makeGetWaitersRequest,
17
15
  makeNotifyRequest,
16
+ normalizeCursor,
18
17
  prepareFlowControl,
19
18
  serve,
20
19
  triggerFirstInvocation
21
- } from "./chunk-NZCQPOPR.mjs";
20
+ } from "./chunk-THS5AX2D.mjs";
22
21
 
23
22
  // src/client/index.ts
24
23
  import { Client as QStashClient } from "@upstash/qstash";
25
24
 
26
25
  // src/client/dlq.ts
27
- var DLQ = class _DLQ {
26
+ function buildResumeRestartHeaders(options) {
27
+ const headers = {};
28
+ if (options?.flowControl) {
29
+ const { flowControlKey, flowControlValue } = prepareFlowControl(options.flowControl);
30
+ headers["Upstash-Flow-Control-Key"] = flowControlKey;
31
+ headers["Upstash-Flow-Control-Value"] = flowControlValue;
32
+ }
33
+ if (options?.retries !== void 0) {
34
+ headers["Upstash-Retries"] = options.retries.toString();
35
+ }
36
+ return headers;
37
+ }
38
+ var DLQ = class {
28
39
  constructor(client) {
29
40
  this.client = client;
30
41
  }
@@ -47,40 +58,66 @@ var DLQ = class _DLQ {
47
58
  */
48
59
  async list(parameters) {
49
60
  const { cursor, count, filter } = parameters || {};
50
- return await this.client.http.request({
51
- path: ["v2", "dlq"],
52
- method: "GET",
53
- query: {
54
- cursor,
55
- count,
56
- ...filter,
57
- source: "workflow"
58
- }
59
- });
61
+ return normalizeCursor(
62
+ await this.client.http.request({
63
+ path: ["v2", "dlq"],
64
+ method: "GET",
65
+ query: {
66
+ cursor,
67
+ count,
68
+ ...filter,
69
+ source: "workflow"
70
+ }
71
+ })
72
+ );
60
73
  }
61
- async resume(parameters) {
62
- const { headers, queryParams } = _DLQ.handleDLQOptions(parameters);
63
- const { workflowRuns } = await this.client.http.request({
64
- path: ["v2", "workflows", "dlq", `resume?${queryParams}`],
65
- headers,
66
- method: "POST"
67
- });
68
- if (Array.isArray(parameters.dlqId)) {
69
- return workflowRuns;
74
+ async resume(request, options) {
75
+ if (typeof request === "object" && !Array.isArray(request) && "dlqId" in request) {
76
+ const { dlqId, flowControl, retries } = request;
77
+ const dlqIds = Array.isArray(dlqId) ? dlqId : [dlqId];
78
+ const { workflowRuns } = await this.client.http.request({
79
+ path: ["v2", "workflows", "dlq", "resume"],
80
+ query: { dlqIds },
81
+ method: "POST",
82
+ headers: buildResumeRestartHeaders({ flowControl, retries })
83
+ });
84
+ return Array.isArray(dlqId) ? workflowRuns : workflowRuns[0];
70
85
  }
71
- return workflowRuns[0];
86
+ if (typeof request === "string") request = [request];
87
+ if (Array.isArray(request) && request.length === 0) return { workflowRuns: [] };
88
+ const filters = Array.isArray(request) ? { dlqIds: request } : request;
89
+ return normalizeCursor(
90
+ await this.client.http.request({
91
+ path: ["v2", "workflows", "dlq", "resume"],
92
+ query: buildBulkActionQueryParameters(filters),
93
+ method: "POST",
94
+ headers: buildResumeRestartHeaders(options)
95
+ })
96
+ );
72
97
  }
73
- async restart(parameters) {
74
- const { headers, queryParams } = _DLQ.handleDLQOptions(parameters);
75
- const { workflowRuns } = await this.client.http.request({
76
- path: ["v2", "workflows", "dlq", `restart?${queryParams}`],
77
- headers,
78
- method: "POST"
79
- });
80
- if (Array.isArray(parameters.dlqId)) {
81
- return workflowRuns;
98
+ async restart(request, options) {
99
+ if (typeof request === "object" && !Array.isArray(request) && "dlqId" in request) {
100
+ const { dlqId, flowControl, retries } = request;
101
+ const dlqIds = Array.isArray(dlqId) ? dlqId : [dlqId];
102
+ const { workflowRuns } = await this.client.http.request({
103
+ path: ["v2", "workflows", "dlq", "restart"],
104
+ query: { dlqIds },
105
+ method: "POST",
106
+ headers: buildResumeRestartHeaders({ flowControl, retries })
107
+ });
108
+ return Array.isArray(dlqId) ? workflowRuns : workflowRuns[0];
82
109
  }
83
- return workflowRuns[0];
110
+ if (typeof request === "string") request = [request];
111
+ if (Array.isArray(request) && request.length === 0) return { workflowRuns: [] };
112
+ const filters = Array.isArray(request) ? { dlqIds: request } : request;
113
+ return normalizeCursor(
114
+ await this.client.http.request({
115
+ path: ["v2", "workflows", "dlq", "restart"],
116
+ query: buildBulkActionQueryParameters(filters),
117
+ method: "POST",
118
+ headers: buildResumeRestartHeaders(options)
119
+ })
120
+ );
84
121
  }
85
122
  /**
86
123
  * Retry the failure callback of a workflow run whose failureUrl/failureFunction
@@ -97,148 +134,64 @@ var DLQ = class _DLQ {
97
134
  return response;
98
135
  }
99
136
  /**
100
- * Handles DLQ options and prepares headers and query parameters.
137
+ * Delete DLQ messages.
101
138
  *
102
- * @param options - DLQ resume/restart options
103
- */
104
- static handleDLQOptions(options) {
105
- const { dlqId, flowControl, retries } = options;
106
- const headers = {};
107
- if (flowControl) {
108
- const { flowControlKey, flowControlValue } = prepareFlowControl(flowControl);
109
- headers["Upstash-Flow-Control-Key"] = flowControlKey;
110
- headers["Upstash-Flow-Control-Value"] = flowControlValue;
111
- }
112
- if (retries !== void 0) {
113
- headers["Upstash-Retries"] = retries.toString();
114
- }
115
- return {
116
- queryParams: _DLQ.getDlqIdQueryParameter(dlqId),
117
- headers
118
- };
119
- }
120
- /**
121
- * Converts DLQ ID(s) to query parameter string.
139
+ * Can be called with:
140
+ * - A single dlqId: `delete("id")`
141
+ * - An array of dlqIds: `delete(["id1", "id2"])`
142
+ * - A filter object: `delete({ filter: { label: "my-label", fromDate: 1640995200000 } })`
143
+ * - To target all entries: `delete({ all: true })`
144
+ *
145
+ * Processes up to `count` messages per call (defaults to 100).
146
+ * Call in a loop until cursor is undefined to process all:
122
147
  *
123
- * @param dlqId - Single DLQ ID or array of DLQ IDs
148
+ * ```ts
149
+ * let cursor: string | undefined;
150
+ * do {
151
+ * const result = await client.dlq.delete({ all: true, count: 100, cursor });
152
+ * cursor = result.cursor;
153
+ * } while (cursor);
154
+ * ```
124
155
  */
125
- static getDlqIdQueryParameter(dlqId) {
126
- const dlqIds = Array.isArray(dlqId) ? dlqId : [dlqId];
127
- const paramsArray = dlqIds.map((id) => ["dlqIds", id]);
128
- return new URLSearchParams(paramsArray).toString();
156
+ async delete(request) {
157
+ if (typeof request === "string") request = [request];
158
+ if (Array.isArray(request) && request.length === 0) return { deleted: 0 };
159
+ const filters = Array.isArray(request) ? { dlqIds: request } : request;
160
+ return normalizeCursor(
161
+ await this.client.http.request({
162
+ path: ["v2", "workflows", "dlq"],
163
+ method: "DELETE",
164
+ query: buildBulkActionQueryParameters(filters)
165
+ })
166
+ );
129
167
  }
130
168
  };
131
169
 
132
170
  // src/client/index.ts
133
171
  var Client = class {
134
172
  client;
135
- devMode;
136
173
  constructor(clientConfig) {
137
- const env = typeof process === "undefined" ? {} : process.env;
138
- this.devMode = env.WORKFLOW_DEV === "true";
139
- if (this.devMode) {
140
- const port = Number(env.WORKFLOW_DEV_PORT) || 8080;
141
- const creds = getDevCredentials(port);
142
- this.client = new QStashClient({
143
- ...clientConfig,
144
- token: DEV_QSTASH_TOKEN,
145
- baseUrl: creds.QSTASH_URL
146
- });
147
- } else if (!clientConfig) {
148
- throw new Error(
149
- "[Upstash Workflow] Client requires a token. Either pass { token: '...' } or set WORKFLOW_DEV=true."
150
- );
151
- } else {
152
- this.client = new QStashClient(clientConfig);
153
- }
154
- }
155
- /**
156
- * In dev mode, ensures the dev server is running before making requests.
157
- * If a server is already listening on the port (started by another process
158
- * or by a platform's serve()), this is a no-op.
159
- */
160
- async ensureReady() {
161
- if (this.devMode) {
162
- await ensureDevServer(process.env);
163
- }
174
+ this.client = new QStashClient(clientConfig);
164
175
  }
165
- /**
166
- * Cancel an ongoing workflow
167
- *
168
- * Returns true if workflow is canceled succesfully. Otherwise, throws error.
169
- *
170
- * There are multiple ways you can cancel workflows:
171
- * - pass one or more workflow run ids to cancel them
172
- * - pass a workflow url to cancel all runs starting with this url
173
- * - cancel all pending or active workflow runs
174
- *
175
- * ### Cancel a set of workflow runs
176
- *
177
- * ```ts
178
- * // cancel a single workflow
179
- * await client.cancel({ ids: "<WORKFLOW_RUN_ID>" })
180
- *
181
- * // cancel a set of workflow runs
182
- * await client.cancel({ ids: [
183
- * "<WORKFLOW_RUN_ID_1>",
184
- * "<WORKFLOW_RUN_ID_2>",
185
- * ]})
186
- * ```
187
- *
188
- * ### Cancel workflows starting with a url
189
- *
190
- * If you have an endpoint called `https://your-endpoint.com` and you
191
- * want to cancel all workflow runs on it, you can use `urlStartingWith`.
192
- *
193
- * Note that this will cancel workflows in all endpoints under
194
- * `https://your-endpoint.com`.
195
- *
196
- * ```ts
197
- * await client.cancel({ urlStartingWith: "https://your-endpoint.com" })
198
- * ```
199
- *
200
- * ### Cancel *all* workflows
201
- *
202
- * To cancel all pending and currently running workflows, you can
203
- * do it like this:
204
- *
205
- * ```ts
206
- * await client.cancel({ all: true })
207
- * ```
208
- *
209
- * @param ids run id of the workflow to delete
210
- * @param urlStartingWith cancel workflows starting with this url. Will be ignored
211
- * if `ids` parameter is set.
212
- * @param all set to true in order to cancel all workflows. Will be ignored
213
- * if `ids` or `urlStartingWith` parameters are set.
214
- * @returns true if workflow is succesfully deleted. Otherwise throws QStashError
215
- */
216
- async cancel({
217
- ids,
218
- urlStartingWith,
219
- all
220
- }) {
221
- await this.ensureReady();
222
- let body;
223
- if (ids) {
224
- const runIdArray = typeof ids === "string" ? [ids] : ids;
225
- body = JSON.stringify({ workflowRunIds: runIdArray });
226
- } else if (urlStartingWith) {
227
- body = JSON.stringify({ workflowUrl: urlStartingWith });
228
- } else if (all) {
229
- body = "{}";
230
- } else {
231
- throw new TypeError("The `cancel` method cannot be called without any options.");
176
+ async cancel(request) {
177
+ if (typeof request === "object" && !Array.isArray(request) && ("ids" in request || "urlStartingWith" in request)) {
178
+ const legacy = request;
179
+ if (legacy.ids) {
180
+ const ids = typeof legacy.ids === "string" ? [legacy.ids] : legacy.ids;
181
+ return this.cancel(ids);
182
+ }
183
+ if (legacy.urlStartingWith) {
184
+ return this.cancel({ filter: { workflowUrlStartingWith: legacy.urlStartingWith } });
185
+ }
232
186
  }
233
- const result = await this.client.http.request({
187
+ if (typeof request === "string") request = [request];
188
+ if (Array.isArray(request) && request.length === 0) return { cancelled: 0 };
189
+ const filters = Array.isArray(request) ? { workflowRunIds: request } : request;
190
+ return await this.client.http.request({
234
191
  path: ["v2", "workflows", "runs"],
235
192
  method: "DELETE",
236
- body,
237
- headers: {
238
- "Content-Type": "application/json"
239
- }
193
+ query: buildBulkActionQueryParameters(filters, { translateWorkflowUrl: true })
240
194
  });
241
- return result;
242
195
  }
243
196
  /**
244
197
  * Notify a workflow run waiting for an event
@@ -253,15 +206,26 @@ var Client = class {
253
206
  * });
254
207
  * ```
255
208
  *
209
+ * Optionally, you can pass a workflowRunId to enable lookback functionality:
210
+ *
211
+ * ```ts
212
+ * await client.notify({
213
+ * eventId: "my-event-id",
214
+ * eventData: "my-data",
215
+ * workflowRunId: "wfr_123" // enables lookback
216
+ * });
217
+ * ```
218
+ *
256
219
  * @param eventId event id to notify
257
220
  * @param eventData data to provide to the workflow
221
+ * @param workflowRunId optional workflow run id for lookback support
258
222
  */
259
223
  async notify({
260
224
  eventId,
261
- eventData
225
+ eventData,
226
+ workflowRunId
262
227
  }) {
263
- await this.ensureReady();
264
- return await makeNotifyRequest(this.client.http, eventId, eventData);
228
+ return await makeNotifyRequest(this.client.http, eventId, eventData, workflowRunId);
265
229
  }
266
230
  /**
267
231
  * Check waiters of an event
@@ -278,11 +242,9 @@ var Client = class {
278
242
  * @param eventId event id to check
279
243
  */
280
244
  async getWaiters({ eventId }) {
281
- await this.ensureReady();
282
245
  return await makeGetWaitersRequest(this.client.http, eventId);
283
246
  }
284
247
  async trigger(params) {
285
- await this.ensureReady();
286
248
  const isBatchInput = Array.isArray(params);
287
249
  const options = isBatchInput ? params : [params];
288
250
  const invocations = options.map((option) => {
@@ -299,7 +261,9 @@ var Client = class {
299
261
  url: option.url,
300
262
  workflowRunId: finalWorkflowRunId,
301
263
  telemetry: option.disableTelemetry ? void 0 : { sdk: SDK_TELEMETRY },
302
- label: option.label
264
+ label: option.label,
265
+ workflowRunCreatedAt: Date.now()
266
+ // pass a timestamp (server will override it)
303
267
  });
304
268
  return {
305
269
  workflowContext: context,
@@ -309,7 +273,8 @@ var Client = class {
309
273
  failureUrl,
310
274
  retries: option.retries,
311
275
  retryDelay: option.retryDelay,
312
- flowControl: option.flowControl
276
+ flowControl: option.flowControl,
277
+ redact: option.redact
313
278
  };
314
279
  });
315
280
  const result = await triggerFirstInvocation(invocations);
@@ -350,34 +315,17 @@ var Client = class {
350
315
  * ```
351
316
  */
352
317
  async logs(params) {
353
- await this.ensureReady();
354
- const { workflowRunId, cursor, count, state, workflowUrl, workflowCreatedAt } = params ?? {};
355
- const urlParams = new URLSearchParams({ groupBy: "workflowRunId" });
356
- if (workflowRunId) {
357
- urlParams.append("workflowRunId", workflowRunId);
358
- }
359
- if (cursor) {
360
- urlParams.append("cursor", cursor);
361
- }
362
- if (count) {
363
- urlParams.append("count", count.toString());
364
- }
365
- if (state) {
366
- urlParams.append("state", state);
367
- }
368
- if (workflowUrl) {
369
- urlParams.append("workflowUrl", workflowUrl);
370
- }
371
- if (workflowCreatedAt) {
372
- urlParams.append("workflowCreatedAt", workflowCreatedAt.toString());
373
- }
374
- if (params?.label) {
375
- urlParams.append("label", params.label);
376
- }
377
- const result = await this.client.http.request({
378
- path: ["v2", "workflows", `events?${urlParams.toString()}`]
318
+ const { cursor, count, filter, ...legacyFilter } = params ?? {};
319
+ return await this.client.http.request({
320
+ path: ["v2", "workflows", "events"],
321
+ query: {
322
+ groupBy: "workflowRunId",
323
+ ...legacyFilter,
324
+ cursor,
325
+ count,
326
+ ...filter
327
+ }
379
328
  });
380
- return result;
381
329
  }
382
330
  get dlq() {
383
331
  return new DLQ(this.client);
package/nextjs.d.mts CHANGED
@@ -1,6 +1,6 @@
1
1
  import { NextApiHandler, NextApiRequest, NextApiResponse } from 'next';
2
- import { c as RouteFunction, d as WorkflowServeOptions, x as InvokableWorkflow } from './types-CUwgrpCM.mjs';
3
- import { s as serveManyBase } from './serve-many-CppVPJrh.mjs';
2
+ import { c as RouteFunction, d as WorkflowServeOptions, I as InvokableWorkflow } from './types-B2S08hRU.mjs';
3
+ import { s as serveManyBase } from './serve-many-C6sa_DxN.mjs';
4
4
  import '@upstash/qstash';
5
5
  import 'zod';
6
6
 
package/nextjs.d.ts CHANGED
@@ -1,6 +1,6 @@
1
1
  import { NextApiHandler, NextApiRequest, NextApiResponse } from 'next';
2
- import { c as RouteFunction, d as WorkflowServeOptions, x as InvokableWorkflow } from './types-CUwgrpCM.js';
3
- import { s as serveManyBase } from './serve-many-Bi8XaOyq.js';
2
+ import { c as RouteFunction, d as WorkflowServeOptions, I as InvokableWorkflow } from './types-B2S08hRU.js';
3
+ import { s as serveManyBase } from './serve-many-B-fe7bh7.js';
4
4
  import '@upstash/qstash';
5
5
  import 'zod';
6
6