@upstash/workflow 0.2.9 → 0.2.10-unicode-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/index.js CHANGED
@@ -163,22 +163,21 @@ function getWorkflowRunId(id) {
163
163
  return `wfr_${id ?? nanoid()}`;
164
164
  }
165
165
  function decodeBase64(base64) {
166
+ const binString = atob(base64);
166
167
  try {
167
- const binString = atob(base64);
168
168
  const intArray = Uint8Array.from(binString, (m) => m.codePointAt(0));
169
169
  return new TextDecoder().decode(intArray);
170
170
  } catch (error) {
171
171
  console.warn(
172
172
  `Upstash Qstash: Failed while decoding base64 "${base64}". Decoding with atob and returning it instead. ${error}`
173
173
  );
174
- return atob(base64);
174
+ return binString;
175
175
  }
176
176
  }
177
177
 
178
178
  // src/context/steps.ts
179
- var BaseLazyStep = class {
179
+ var BaseLazyStep = class _BaseLazyStep {
180
180
  stepName;
181
- // will be set in the subclasses
182
181
  constructor(stepName) {
183
182
  if (!stepName) {
184
183
  throw new WorkflowError(
@@ -187,10 +186,58 @@ var BaseLazyStep = class {
187
186
  }
188
187
  this.stepName = stepName;
189
188
  }
189
+ /**
190
+ * parse the out field of a step result.
191
+ *
192
+ * will be called when returning the steps to the context from auto executor
193
+ *
194
+ * @param out field of the step
195
+ * @returns parsed out field
196
+ */
197
+ parseOut(out) {
198
+ if (out === void 0) {
199
+ if (this.allowUndefinedOut) {
200
+ return void 0;
201
+ } else {
202
+ throw new WorkflowError(
203
+ `Error while parsing output of ${this.stepType} step. Expected a string, but got: undefined`
204
+ );
205
+ }
206
+ }
207
+ if (typeof out === "object") {
208
+ if (this.stepType !== "Wait") {
209
+ console.warn(
210
+ `Error while parsing ${this.stepType} step output. Expected a string, but got object. Please reach out to Upstash Support.`
211
+ );
212
+ return out;
213
+ }
214
+ return {
215
+ ...out,
216
+ eventData: _BaseLazyStep.tryParsing(out.eventData)
217
+ };
218
+ }
219
+ if (typeof out !== "string") {
220
+ throw new WorkflowError(
221
+ `Error while parsing output of ${this.stepType} step. Expected a string or undefined, but got: ${typeof out}`
222
+ );
223
+ }
224
+ return this.safeParseOut(out);
225
+ }
226
+ safeParseOut(out) {
227
+ return _BaseLazyStep.tryParsing(out);
228
+ }
229
+ static tryParsing(stepOut) {
230
+ try {
231
+ return JSON.parse(stepOut);
232
+ } catch {
233
+ return stepOut;
234
+ }
235
+ }
190
236
  };
191
237
  var LazyFunctionStep = class extends BaseLazyStep {
192
238
  stepFunction;
193
239
  stepType = "Run";
240
+ allowUndefinedOut = true;
194
241
  constructor(stepName, stepFunction) {
195
242
  super(stepName);
196
243
  this.stepFunction = stepFunction;
@@ -221,6 +268,7 @@ var LazyFunctionStep = class extends BaseLazyStep {
221
268
  var LazySleepStep = class extends BaseLazyStep {
222
269
  sleep;
223
270
  stepType = "SleepFor";
271
+ allowUndefinedOut = true;
224
272
  constructor(stepName, sleep) {
225
273
  super(stepName);
226
274
  this.sleep = sleep;
@@ -248,6 +296,7 @@ var LazySleepStep = class extends BaseLazyStep {
248
296
  var LazySleepUntilStep = class extends BaseLazyStep {
249
297
  sleepUntil;
250
298
  stepType = "SleepUntil";
299
+ allowUndefinedOut = true;
251
300
  constructor(stepName, sleepUntil) {
252
301
  super(stepName);
253
302
  this.sleepUntil = sleepUntil;
@@ -271,8 +320,11 @@ var LazySleepUntilStep = class extends BaseLazyStep {
271
320
  concurrent
272
321
  });
273
322
  }
323
+ safeParseOut() {
324
+ return void 0;
325
+ }
274
326
  };
275
- var LazyCallStep = class extends BaseLazyStep {
327
+ var LazyCallStep = class _LazyCallStep extends BaseLazyStep {
276
328
  url;
277
329
  method;
278
330
  body;
@@ -281,6 +333,7 @@ var LazyCallStep = class extends BaseLazyStep {
281
333
  timeout;
282
334
  flowControl;
283
335
  stepType = "Call";
336
+ allowUndefinedOut = false;
284
337
  constructor(stepName, url, method, body, headers, retries, timeout, flowControl) {
285
338
  super(stepName);
286
339
  this.url = url;
@@ -312,11 +365,53 @@ var LazyCallStep = class extends BaseLazyStep {
312
365
  callHeaders: this.headers
313
366
  });
314
367
  }
368
+ safeParseOut(out) {
369
+ const { header, status, body } = JSON.parse(out);
370
+ const responseHeaders = new Headers(header);
371
+ if (_LazyCallStep.isText(responseHeaders.get("content-type"))) {
372
+ const bytes = new Uint8Array(out.length);
373
+ for (let i = 0; i < out.length; i++) {
374
+ bytes[i] = out.charCodeAt(i);
375
+ }
376
+ const processedResult = new TextDecoder().decode(bytes);
377
+ const newBody = JSON.parse(processedResult).body;
378
+ return {
379
+ status,
380
+ header,
381
+ body: BaseLazyStep.tryParsing(newBody)
382
+ };
383
+ } else {
384
+ return { header, status, body };
385
+ }
386
+ }
387
+ static applicationHeaders = /* @__PURE__ */ new Set([
388
+ "application/json",
389
+ "application/xml",
390
+ "application/javascript",
391
+ "application/x-www-form-urlencoded",
392
+ "application/xhtml+xml",
393
+ "application/ld+json",
394
+ "application/rss+xml",
395
+ "application/atom+xml"
396
+ ]);
397
+ static isText = (contentTypeHeader) => {
398
+ if (!contentTypeHeader) {
399
+ return false;
400
+ }
401
+ if (_LazyCallStep.applicationHeaders.has(contentTypeHeader)) {
402
+ return true;
403
+ }
404
+ if (contentTypeHeader.startsWith("text/")) {
405
+ return true;
406
+ }
407
+ return false;
408
+ };
315
409
  };
316
410
  var LazyWaitForEventStep = class extends BaseLazyStep {
317
411
  eventId;
318
412
  timeout;
319
413
  stepType = "Wait";
414
+ allowUndefinedOut = false;
320
415
  constructor(stepName, eventId, timeout) {
321
416
  super(stepName);
322
417
  this.eventId = eventId;
@@ -343,6 +438,13 @@ var LazyWaitForEventStep = class extends BaseLazyStep {
343
438
  concurrent
344
439
  });
345
440
  }
441
+ safeParseOut(out) {
442
+ const result = JSON.parse(out);
443
+ return {
444
+ ...result,
445
+ eventData: BaseLazyStep.tryParsing(result.eventData)
446
+ };
447
+ }
346
448
  };
347
449
  var LazyNotifyStep = class extends LazyFunctionStep {
348
450
  stepType = "Notify";
@@ -356,10 +458,18 @@ var LazyNotifyStep = class extends LazyFunctionStep {
356
458
  };
357
459
  });
358
460
  }
461
+ safeParseOut(out) {
462
+ const result = JSON.parse(out);
463
+ return {
464
+ ...result,
465
+ eventData: BaseLazyStep.tryParsing(result.eventData)
466
+ };
467
+ }
359
468
  };
360
469
  var LazyInvokeStep = class extends BaseLazyStep {
361
470
  stepType = "Invoke";
362
471
  params;
472
+ allowUndefinedOut = false;
363
473
  constructor(stepName, {
364
474
  workflow,
365
475
  body,
@@ -399,6 +509,13 @@ var LazyInvokeStep = class extends BaseLazyStep {
399
509
  concurrent
400
510
  });
401
511
  }
512
+ safeParseOut(out) {
513
+ const result = JSON.parse(out);
514
+ return {
515
+ ...result,
516
+ body: BaseLazyStep.tryParsing(result.body)
517
+ };
518
+ }
402
519
  };
403
520
 
404
521
  // node_modules/neverthrow/dist/index.es.js
@@ -1434,7 +1551,7 @@ var AutoExecutor = class _AutoExecutor {
1434
1551
  step,
1435
1552
  stepCount: this.stepCount
1436
1553
  });
1437
- return step.out;
1554
+ return lazyStep.parseOut(step.out);
1438
1555
  }
1439
1556
  const resultStep = await lazyStep.getResultStep(NO_CONCURRENCY, this.stepCount);
1440
1557
  await this.debug?.log("INFO", "RUN_SINGLE", {
@@ -1509,7 +1626,9 @@ var AutoExecutor = class _AutoExecutor {
1509
1626
  case "last": {
1510
1627
  const parallelResultSteps = sortedSteps.filter((step) => step.stepId >= initialStepCount).slice(0, parallelSteps.length);
1511
1628
  validateParallelSteps(parallelSteps, parallelResultSteps);
1512
- return parallelResultSteps.map((step) => step.out);
1629
+ return parallelResultSteps.map(
1630
+ (step, index) => parallelSteps[index].parseOut(step.out)
1631
+ );
1513
1632
  }
1514
1633
  }
1515
1634
  const fillValue = void 0;
@@ -2381,7 +2500,7 @@ var WorkflowContext = class {
2381
2500
  */
2382
2501
  async run(stepName, stepFunction) {
2383
2502
  const wrappedStepFunction = () => this.executor.wrapStep(stepName, stepFunction);
2384
- return this.addStep(new LazyFunctionStep(stepName, wrappedStepFunction));
2503
+ return await this.addStep(new LazyFunctionStep(stepName, wrappedStepFunction));
2385
2504
  }
2386
2505
  /**
2387
2506
  * Stops the execution for the duration provided.
@@ -2452,43 +2571,27 @@ var WorkflowContext = class {
2452
2571
  * }
2453
2572
  */
2454
2573
  async call(stepName, settings) {
2455
- const { url, method = "GET", body, headers = {}, retries = 0, timeout, flowControl } = settings;
2456
- const result = await this.addStep(
2574
+ const {
2575
+ url,
2576
+ method = "GET",
2577
+ body: requestBody,
2578
+ headers = {},
2579
+ retries = 0,
2580
+ timeout,
2581
+ flowControl
2582
+ } = settings;
2583
+ return await this.addStep(
2457
2584
  new LazyCallStep(
2458
2585
  stepName,
2459
2586
  url,
2460
2587
  method,
2461
- body,
2588
+ requestBody,
2462
2589
  headers,
2463
2590
  retries,
2464
2591
  timeout,
2465
2592
  flowControl
2466
2593
  )
2467
2594
  );
2468
- if (typeof result === "string") {
2469
- try {
2470
- const body2 = JSON.parse(result);
2471
- return {
2472
- status: 200,
2473
- header: {},
2474
- body: body2
2475
- };
2476
- } catch {
2477
- return {
2478
- status: 200,
2479
- header: {},
2480
- body: result
2481
- };
2482
- }
2483
- }
2484
- try {
2485
- return {
2486
- ...result,
2487
- body: JSON.parse(result.body)
2488
- };
2489
- } catch {
2490
- return result;
2491
- }
2492
2595
  }
2493
2596
  /**
2494
2597
  * Pauses workflow execution until a specific event occurs or a timeout is reached.
@@ -2527,15 +2630,7 @@ var WorkflowContext = class {
2527
2630
  async waitForEvent(stepName, eventId, options = {}) {
2528
2631
  const { timeout = "7d" } = options;
2529
2632
  const timeoutStr = typeof timeout === "string" ? timeout : `${timeout}s`;
2530
- const result = await this.addStep(new LazyWaitForEventStep(stepName, eventId, timeoutStr));
2531
- try {
2532
- return {
2533
- ...result,
2534
- eventData: JSON.parse(result.eventData)
2535
- };
2536
- } catch {
2537
- return result;
2538
- }
2633
+ return await this.addStep(new LazyWaitForEventStep(stepName, eventId, timeoutStr));
2539
2634
  }
2540
2635
  /**
2541
2636
  * Notify workflow runs waiting for an event
@@ -2559,24 +2654,12 @@ var WorkflowContext = class {
2559
2654
  * @returns notify response which has event id, event data and list of waiters which were notified
2560
2655
  */
2561
2656
  async notify(stepName, eventId, eventData) {
2562
- const result = await this.addStep(
2657
+ return await this.addStep(
2563
2658
  new LazyNotifyStep(stepName, eventId, eventData, this.qstashClient.http)
2564
2659
  );
2565
- try {
2566
- return {
2567
- ...result,
2568
- eventData: JSON.parse(result.eventData)
2569
- };
2570
- } catch {
2571
- return result;
2572
- }
2573
2660
  }
2574
2661
  async invoke(stepName, settings) {
2575
- const result = await this.addStep(new LazyInvokeStep(stepName, settings));
2576
- return {
2577
- ...result,
2578
- body: result.body ? JSON.parse(result.body) : void 0
2579
- };
2662
+ return await this.addStep(new LazyInvokeStep(stepName, settings));
2580
2663
  }
2581
2664
  /**
2582
2665
  * Cancel the current workflow run
@@ -2735,10 +2818,6 @@ var processRawSteps = (rawSteps) => {
2735
2818
  const stepsToDecode = encodedSteps.filter((step) => step.callType === "step");
2736
2819
  const otherSteps = stepsToDecode.map((rawStep) => {
2737
2820
  const step = JSON.parse(decodeBase64(rawStep.body));
2738
- try {
2739
- step.out = JSON.parse(step.out);
2740
- } catch {
2741
- }
2742
2821
  if (step.waitEventId) {
2743
2822
  const newOut = {
2744
2823
  eventData: step.out ? decodeBase64(step.out) : void 0,
package/index.mjs CHANGED
@@ -10,7 +10,7 @@ import {
10
10
  makeNotifyRequest,
11
11
  serve,
12
12
  triggerFirstInvocation
13
- } from "./chunk-IPXJZU3K.mjs";
13
+ } from "./chunk-N2WV5VCD.mjs";
14
14
 
15
15
  // src/client/index.ts
16
16
  import { Client as QStashClient } from "@upstash/qstash";
package/nextjs.d.mts CHANGED
@@ -1,6 +1,6 @@
1
1
  import { NextApiHandler, NextApiRequest, NextApiResponse } from 'next';
2
- import { R as RouteFunction, k as PublicServeOptions, t as InvokableWorkflow } from './types-CYhDXnf8.mjs';
3
- import { s as serveManyBase } from './serve-many-BVDpPsF-.mjs';
2
+ import { R as RouteFunction, k as PublicServeOptions, t as InvokableWorkflow } from './types-Dg_9L83G.mjs';
3
+ import { s as serveManyBase } from './serve-many-wMUWrSIP.mjs';
4
4
  import '@upstash/qstash';
5
5
  import 'zod';
6
6
  import 'ai';
package/nextjs.d.ts CHANGED
@@ -1,6 +1,6 @@
1
1
  import { NextApiHandler, NextApiRequest, NextApiResponse } from 'next';
2
- import { R as RouteFunction, k as PublicServeOptions, t as InvokableWorkflow } from './types-CYhDXnf8.js';
3
- import { s as serveManyBase } from './serve-many-e4zufyXN.js';
2
+ import { R as RouteFunction, k as PublicServeOptions, t as InvokableWorkflow } from './types-Dg_9L83G.js';
3
+ import { s as serveManyBase } from './serve-many-jCRazho9.js';
4
4
  import '@upstash/qstash';
5
5
  import 'zod';
6
6
  import 'ai';