@upstash/workflow 0.2.18 → 0.2.20

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
@@ -105,7 +105,7 @@ var WORKFLOW_PROTOCOL_VERSION_HEADER = "Upstash-Workflow-Sdk-Version";
105
105
  var DEFAULT_CONTENT_TYPE = "application/json";
106
106
  var NO_CONCURRENCY = 1;
107
107
  var DEFAULT_RETRIES = 3;
108
- var VERSION = "v0.2.18";
108
+ var VERSION = "v0.2.20";
109
109
  var SDK_TELEMETRY = `@upstash/workflow@${VERSION}`;
110
110
  var TELEMETRY_HEADER_SDK = "Upstash-Telemetry-Sdk";
111
111
  var TELEMETRY_HEADER_FRAMEWORK = "Upstash-Telemetry-Framework";
@@ -156,7 +156,8 @@ var WorkflowNonRetryableError = class extends WorkflowAbort {
156
156
  var formatWorkflowError = (error) => {
157
157
  return error instanceof Error ? {
158
158
  error: error.name,
159
- message: error.message
159
+ message: error.message,
160
+ stack: error.stack
160
161
  } : {
161
162
  error: "Error",
162
163
  message: `An error occured while executing workflow: '${typeof error === "string" ? error : JSON.stringify(error)}'`
@@ -627,7 +628,7 @@ var triggerFirstInvocation = async (params) => {
627
628
  const firstInvocationParams = Array.isArray(params) ? params : [params];
628
629
  const workflowContextClient = firstInvocationParams[0].workflowContext.qstashClient;
629
630
  const invocationBatch = firstInvocationParams.map(
630
- ({ workflowContext, useJSONContent, telemetry, invokeCount, delay }) => {
631
+ ({ workflowContext, useJSONContent, telemetry, invokeCount, delay, notBefore }) => {
631
632
  const { headers } = getHeaders({
632
633
  initHeaderValue: "true",
633
634
  workflowConfig: {
@@ -658,7 +659,8 @@ var triggerFirstInvocation = async (params) => {
658
659
  method: "POST",
659
660
  body,
660
661
  url: workflowContext.url,
661
- delay
662
+ delay,
663
+ notBefore
662
664
  };
663
665
  }
664
666
  );
@@ -1146,9 +1148,10 @@ var LazyCallStep = class _LazyCallStep extends BaseLazyStep {
1146
1148
  retryDelay;
1147
1149
  timeout;
1148
1150
  flowControl;
1151
+ stringifyBody;
1149
1152
  stepType = "Call";
1150
1153
  allowUndefinedOut = false;
1151
- constructor(stepName, url, method, body, headers, retries, retryDelay, timeout, flowControl) {
1154
+ constructor(stepName, url, method, body, headers, retries, retryDelay, timeout, flowControl, stringifyBody) {
1152
1155
  super(stepName);
1153
1156
  this.url = url;
1154
1157
  this.method = method;
@@ -1158,6 +1161,7 @@ var LazyCallStep = class _LazyCallStep extends BaseLazyStep {
1158
1161
  this.retryDelay = retryDelay;
1159
1162
  this.timeout = timeout;
1160
1163
  this.flowControl = flowControl;
1164
+ this.stringifyBody = stringifyBody;
1161
1165
  }
1162
1166
  getPlanStep(concurrent, targetStep) {
1163
1167
  return {
@@ -1267,10 +1271,22 @@ var LazyCallStep = class _LazyCallStep extends BaseLazyStep {
1267
1271
  };
1268
1272
  }
1269
1273
  async submitStep({ context, headers }) {
1274
+ let callBody;
1275
+ if (this.stringifyBody) {
1276
+ callBody = JSON.stringify(this.body);
1277
+ } else {
1278
+ if (typeof this.body === "string") {
1279
+ callBody = this.body;
1280
+ } else {
1281
+ throw new WorkflowError(
1282
+ "When stringifyBody is false, body must be a string. Please check the body type of your call step."
1283
+ );
1284
+ }
1285
+ }
1270
1286
  return await context.qstashClient.batch([
1271
1287
  {
1272
1288
  headers,
1273
- body: JSON.stringify(this.body),
1289
+ body: callBody,
1274
1290
  method: this.method,
1275
1291
  url: this.url,
1276
1292
  retries: DEFAULT_RETRIES === this.retries ? void 0 : this.retries,
@@ -1405,7 +1421,8 @@ var LazyInvokeStep = class extends BaseLazyStep {
1405
1421
  workflowRunId,
1406
1422
  retries,
1407
1423
  retryDelay,
1408
- flowControl
1424
+ flowControl,
1425
+ stringifyBody = true
1409
1426
  }) {
1410
1427
  super(stepName);
1411
1428
  this.params = {
@@ -1415,7 +1432,8 @@ var LazyInvokeStep = class extends BaseLazyStep {
1415
1432
  workflowRunId: getWorkflowRunId(workflowRunId),
1416
1433
  retries,
1417
1434
  retryDelay,
1418
- flowControl
1435
+ flowControl,
1436
+ stringifyBody
1419
1437
  };
1420
1438
  const { workflowId } = workflow;
1421
1439
  if (!workflowId) {
@@ -1468,8 +1486,20 @@ var LazyInvokeStep = class extends BaseLazyStep {
1468
1486
  invokeCount
1469
1487
  });
1470
1488
  invokerHeaders["Upstash-Workflow-Runid"] = context.workflowRunId;
1489
+ let invokeBody;
1490
+ if (this.params.stringifyBody) {
1491
+ invokeBody = JSON.stringify(this.params.body);
1492
+ } else {
1493
+ if (typeof this.params.body === "string") {
1494
+ invokeBody = this.params.body;
1495
+ } else {
1496
+ throw new WorkflowError(
1497
+ "When stringifyBody is false, body must be a string. Please check the body type of your invoke step."
1498
+ );
1499
+ }
1500
+ }
1471
1501
  const request = {
1472
- body: JSON.stringify(this.params.body),
1502
+ body: invokeBody,
1473
1503
  headers: Object.fromEntries(
1474
1504
  Object.entries(invokerHeaders).map((pairs) => [pairs[0], [pairs[1]]])
1475
1505
  ),
@@ -2877,7 +2907,8 @@ var WorkflowContext = class {
2877
2907
  settings.retries || 0,
2878
2908
  settings.retryDelay,
2879
2909
  settings.timeout,
2880
- settings.flowControl ?? settings.workflow.options.flowControl
2910
+ settings.flowControl ?? settings.workflow.options.flowControl,
2911
+ settings.stringifyBody ?? true
2881
2912
  );
2882
2913
  } else {
2883
2914
  const {
@@ -2888,7 +2919,8 @@ var WorkflowContext = class {
2888
2919
  retries = 0,
2889
2920
  retryDelay,
2890
2921
  timeout,
2891
- flowControl
2922
+ flowControl,
2923
+ stringifyBody = true
2892
2924
  } = settings;
2893
2925
  callStep = new LazyCallStep(
2894
2926
  stepName,
@@ -2899,7 +2931,8 @@ var WorkflowContext = class {
2899
2931
  retries,
2900
2932
  retryDelay,
2901
2933
  timeout,
2902
- flowControl
2934
+ flowControl,
2935
+ stringifyBody
2903
2936
  );
2904
2937
  }
2905
2938
  return await this.addStep(callStep);
@@ -3263,11 +3296,15 @@ var handleFailure = async (request, requestPayload, qstashClient, initialPayload
3263
3296
  const { status, header, body, url, sourceBody, workflowRunId } = JSON.parse(requestPayload);
3264
3297
  const decodedBody = body ? decodeBase64(body) : "{}";
3265
3298
  let errorMessage = "";
3299
+ let failStack = "";
3266
3300
  try {
3267
3301
  const errorPayload = JSON.parse(decodedBody);
3268
3302
  if (errorPayload.message) {
3269
3303
  errorMessage = errorPayload.message;
3270
3304
  }
3305
+ if (errorPayload.stack) {
3306
+ failStack = errorPayload.stack;
3307
+ }
3271
3308
  } catch {
3272
3309
  }
3273
3310
  if (!errorMessage) {
@@ -3305,7 +3342,8 @@ var handleFailure = async (request, requestPayload, qstashClient, initialPayload
3305
3342
  context: workflowContext,
3306
3343
  failStatus: status,
3307
3344
  failResponse: errorMessage,
3308
- failHeaders: header
3345
+ failHeaders: header,
3346
+ failStack
3309
3347
  });
3310
3348
  return ok({ result: "is-failure-callback", response: failureResponse });
3311
3349
  } catch (error) {
@@ -3322,7 +3360,7 @@ var processOptions = (options) => {
3322
3360
  environment.QSTASH_CURRENT_SIGNING_KEY && environment.QSTASH_NEXT_SIGNING_KEY
3323
3361
  );
3324
3362
  return {
3325
- qstashClient: new import_qstash11.Client({
3363
+ qstashClient: options?.qstashClient ?? new import_qstash11.Client({
3326
3364
  baseUrl: environment.QSTASH_URL,
3327
3365
  token: environment.QSTASH_TOKEN
3328
3366
  }),
@@ -3878,7 +3916,8 @@ var Client4 = class {
3878
3916
  return {
3879
3917
  workflowContext: context,
3880
3918
  telemetry: { sdk: SDK_TELEMETRY },
3881
- delay: option.delay
3919
+ delay: option.delay,
3920
+ notBefore: option.notBefore
3882
3921
  };
3883
3922
  });
3884
3923
  const result = await triggerFirstInvocation(invocations);
package/index.mjs CHANGED
@@ -14,7 +14,7 @@ import {
14
14
  prepareFlowControl,
15
15
  serve,
16
16
  triggerFirstInvocation
17
- } from "./chunk-EHL7SSJF.mjs";
17
+ } from "./chunk-LZGX3WMF.mjs";
18
18
 
19
19
  // src/client/index.ts
20
20
  import { Client as QStashClient } from "@upstash/qstash";
@@ -265,7 +265,8 @@ var Client = class {
265
265
  return {
266
266
  workflowContext: context,
267
267
  telemetry: { sdk: SDK_TELEMETRY },
268
- delay: option.delay
268
+ delay: option.delay,
269
+ notBefore: option.notBefore
269
270
  };
270
271
  });
271
272
  const result = await triggerFirstInvocation(invocations);
package/nextjs.d.mts CHANGED
@@ -1,6 +1,6 @@
1
1
  import { NextApiHandler, NextApiRequest, NextApiResponse } from 'next';
2
- import { R as RouteFunction, n as PublicServeOptions, x as InvokableWorkflow } from './types-B7_5AkKQ.mjs';
3
- import { s as serveManyBase } from './serve-many-CEUYWQvV.mjs';
2
+ import { R as RouteFunction, n as PublicServeOptions, y as InvokableWorkflow } from './types-Q3dM0UlR.mjs';
3
+ import { s as serveManyBase } from './serve-many-BNusWYgt.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, n as PublicServeOptions, x as InvokableWorkflow } from './types-B7_5AkKQ.js';
3
- import { s as serveManyBase } from './serve-many-BObe3pdI.js';
2
+ import { R as RouteFunction, n as PublicServeOptions, y as InvokableWorkflow } from './types-Q3dM0UlR.js';
3
+ import { s as serveManyBase } from './serve-many-CXqQP3RI.js';
4
4
  import '@upstash/qstash';
5
5
  import 'zod';
6
6
  import 'ai';
package/nextjs.js CHANGED
@@ -95,7 +95,7 @@ var WORKFLOW_PROTOCOL_VERSION_HEADER = "Upstash-Workflow-Sdk-Version";
95
95
  var DEFAULT_CONTENT_TYPE = "application/json";
96
96
  var NO_CONCURRENCY = 1;
97
97
  var DEFAULT_RETRIES = 3;
98
- var VERSION = "v0.2.18";
98
+ var VERSION = "v0.2.20";
99
99
  var SDK_TELEMETRY = `@upstash/workflow@${VERSION}`;
100
100
  var TELEMETRY_HEADER_SDK = "Upstash-Telemetry-Sdk";
101
101
  var TELEMETRY_HEADER_FRAMEWORK = "Upstash-Telemetry-Framework";
@@ -146,7 +146,8 @@ var WorkflowNonRetryableError = class extends WorkflowAbort {
146
146
  var formatWorkflowError = (error) => {
147
147
  return error instanceof Error ? {
148
148
  error: error.name,
149
- message: error.message
149
+ message: error.message,
150
+ stack: error.stack
150
151
  } : {
151
152
  error: "Error",
152
153
  message: `An error occured while executing workflow: '${typeof error === "string" ? error : JSON.stringify(error)}'`
@@ -617,7 +618,7 @@ var triggerFirstInvocation = async (params) => {
617
618
  const firstInvocationParams = Array.isArray(params) ? params : [params];
618
619
  const workflowContextClient = firstInvocationParams[0].workflowContext.qstashClient;
619
620
  const invocationBatch = firstInvocationParams.map(
620
- ({ workflowContext, useJSONContent, telemetry, invokeCount, delay }) => {
621
+ ({ workflowContext, useJSONContent, telemetry, invokeCount, delay, notBefore }) => {
621
622
  const { headers } = getHeaders({
622
623
  initHeaderValue: "true",
623
624
  workflowConfig: {
@@ -648,7 +649,8 @@ var triggerFirstInvocation = async (params) => {
648
649
  method: "POST",
649
650
  body,
650
651
  url: workflowContext.url,
651
- delay
652
+ delay,
653
+ notBefore
652
654
  };
653
655
  }
654
656
  );
@@ -1136,9 +1138,10 @@ var LazyCallStep = class _LazyCallStep extends BaseLazyStep {
1136
1138
  retryDelay;
1137
1139
  timeout;
1138
1140
  flowControl;
1141
+ stringifyBody;
1139
1142
  stepType = "Call";
1140
1143
  allowUndefinedOut = false;
1141
- constructor(stepName, url, method, body, headers, retries, retryDelay, timeout, flowControl) {
1144
+ constructor(stepName, url, method, body, headers, retries, retryDelay, timeout, flowControl, stringifyBody) {
1142
1145
  super(stepName);
1143
1146
  this.url = url;
1144
1147
  this.method = method;
@@ -1148,6 +1151,7 @@ var LazyCallStep = class _LazyCallStep extends BaseLazyStep {
1148
1151
  this.retryDelay = retryDelay;
1149
1152
  this.timeout = timeout;
1150
1153
  this.flowControl = flowControl;
1154
+ this.stringifyBody = stringifyBody;
1151
1155
  }
1152
1156
  getPlanStep(concurrent, targetStep) {
1153
1157
  return {
@@ -1257,10 +1261,22 @@ var LazyCallStep = class _LazyCallStep extends BaseLazyStep {
1257
1261
  };
1258
1262
  }
1259
1263
  async submitStep({ context, headers }) {
1264
+ let callBody;
1265
+ if (this.stringifyBody) {
1266
+ callBody = JSON.stringify(this.body);
1267
+ } else {
1268
+ if (typeof this.body === "string") {
1269
+ callBody = this.body;
1270
+ } else {
1271
+ throw new WorkflowError(
1272
+ "When stringifyBody is false, body must be a string. Please check the body type of your call step."
1273
+ );
1274
+ }
1275
+ }
1260
1276
  return await context.qstashClient.batch([
1261
1277
  {
1262
1278
  headers,
1263
- body: JSON.stringify(this.body),
1279
+ body: callBody,
1264
1280
  method: this.method,
1265
1281
  url: this.url,
1266
1282
  retries: DEFAULT_RETRIES === this.retries ? void 0 : this.retries,
@@ -1395,7 +1411,8 @@ var LazyInvokeStep = class extends BaseLazyStep {
1395
1411
  workflowRunId,
1396
1412
  retries,
1397
1413
  retryDelay,
1398
- flowControl
1414
+ flowControl,
1415
+ stringifyBody = true
1399
1416
  }) {
1400
1417
  super(stepName);
1401
1418
  this.params = {
@@ -1405,7 +1422,8 @@ var LazyInvokeStep = class extends BaseLazyStep {
1405
1422
  workflowRunId: getWorkflowRunId(workflowRunId),
1406
1423
  retries,
1407
1424
  retryDelay,
1408
- flowControl
1425
+ flowControl,
1426
+ stringifyBody
1409
1427
  };
1410
1428
  const { workflowId } = workflow;
1411
1429
  if (!workflowId) {
@@ -1458,8 +1476,20 @@ var LazyInvokeStep = class extends BaseLazyStep {
1458
1476
  invokeCount
1459
1477
  });
1460
1478
  invokerHeaders["Upstash-Workflow-Runid"] = context.workflowRunId;
1479
+ let invokeBody;
1480
+ if (this.params.stringifyBody) {
1481
+ invokeBody = JSON.stringify(this.params.body);
1482
+ } else {
1483
+ if (typeof this.params.body === "string") {
1484
+ invokeBody = this.params.body;
1485
+ } else {
1486
+ throw new WorkflowError(
1487
+ "When stringifyBody is false, body must be a string. Please check the body type of your invoke step."
1488
+ );
1489
+ }
1490
+ }
1461
1491
  const request = {
1462
- body: JSON.stringify(this.params.body),
1492
+ body: invokeBody,
1463
1493
  headers: Object.fromEntries(
1464
1494
  Object.entries(invokerHeaders).map((pairs) => [pairs[0], [pairs[1]]])
1465
1495
  ),
@@ -2903,7 +2933,8 @@ var WorkflowContext = class {
2903
2933
  settings.retries || 0,
2904
2934
  settings.retryDelay,
2905
2935
  settings.timeout,
2906
- settings.flowControl ?? settings.workflow.options.flowControl
2936
+ settings.flowControl ?? settings.workflow.options.flowControl,
2937
+ settings.stringifyBody ?? true
2907
2938
  );
2908
2939
  } else {
2909
2940
  const {
@@ -2914,7 +2945,8 @@ var WorkflowContext = class {
2914
2945
  retries = 0,
2915
2946
  retryDelay,
2916
2947
  timeout,
2917
- flowControl
2948
+ flowControl,
2949
+ stringifyBody = true
2918
2950
  } = settings;
2919
2951
  callStep = new LazyCallStep(
2920
2952
  stepName,
@@ -2925,7 +2957,8 @@ var WorkflowContext = class {
2925
2957
  retries,
2926
2958
  retryDelay,
2927
2959
  timeout,
2928
- flowControl
2960
+ flowControl,
2961
+ stringifyBody
2929
2962
  );
2930
2963
  }
2931
2964
  return await this.addStep(callStep);
@@ -3289,11 +3322,15 @@ var handleFailure = async (request, requestPayload, qstashClient, initialPayload
3289
3322
  const { status, header, body, url, sourceBody, workflowRunId } = JSON.parse(requestPayload);
3290
3323
  const decodedBody = body ? decodeBase64(body) : "{}";
3291
3324
  let errorMessage = "";
3325
+ let failStack = "";
3292
3326
  try {
3293
3327
  const errorPayload = JSON.parse(decodedBody);
3294
3328
  if (errorPayload.message) {
3295
3329
  errorMessage = errorPayload.message;
3296
3330
  }
3331
+ if (errorPayload.stack) {
3332
+ failStack = errorPayload.stack;
3333
+ }
3297
3334
  } catch {
3298
3335
  }
3299
3336
  if (!errorMessage) {
@@ -3331,7 +3368,8 @@ var handleFailure = async (request, requestPayload, qstashClient, initialPayload
3331
3368
  context: workflowContext,
3332
3369
  failStatus: status,
3333
3370
  failResponse: errorMessage,
3334
- failHeaders: header
3371
+ failHeaders: header,
3372
+ failStack
3335
3373
  });
3336
3374
  return ok({ result: "is-failure-callback", response: failureResponse });
3337
3375
  } catch (error) {
@@ -3348,7 +3386,7 @@ var processOptions = (options) => {
3348
3386
  environment.QSTASH_CURRENT_SIGNING_KEY && environment.QSTASH_NEXT_SIGNING_KEY
3349
3387
  );
3350
3388
  return {
3351
- qstashClient: new import_qstash11.Client({
3389
+ qstashClient: options?.qstashClient ?? new import_qstash11.Client({
3352
3390
  baseUrl: environment.QSTASH_URL,
3353
3391
  token: environment.QSTASH_TOKEN
3354
3392
  }),
package/nextjs.mjs CHANGED
@@ -2,7 +2,7 @@ import {
2
2
  SDK_TELEMETRY,
3
3
  serveBase,
4
4
  serveManyBase
5
- } from "./chunk-EHL7SSJF.mjs";
5
+ } from "./chunk-LZGX3WMF.mjs";
6
6
 
7
7
  // platforms/nextjs.ts
8
8
  var appTelemetry = {
package/package.json CHANGED
@@ -1 +1 @@
1
- {"name":"@upstash/workflow","version":"v0.2.18","description":"Durable, Reliable and Performant Serverless Functions","main":"./index.js","module":"./index.mjs","types":"./index.d.ts","files":["./*"],"exports":{".":{"import":"./index.mjs","require":"./index.js"},"./dist/nextjs":{"import":"./nextjs.mjs","require":"./nextjs.js"},"./nextjs":{"import":"./nextjs.mjs","require":"./nextjs.js"},"./h3":{"import":"./h3.mjs","require":"./h3.js"},"./svelte":{"import":"./svelte.mjs","require":"./svelte.js"},"./solidjs":{"import":"./solidjs.mjs","require":"./solidjs.js"},"./workflow":{"import":"./workflow.mjs","require":"./workflow.js"},"./hono":{"import":"./hono.mjs","require":"./hono.js"},"./cloudflare":{"import":"./cloudflare.mjs","require":"./cloudflare.js"},"./astro":{"import":"./astro.mjs","require":"./astro.js"},"./express":{"import":"./express.mjs","require":"./express.js"}},"scripts":{"build":"tsup && cp README.md ./dist/ && cp package.json ./dist/ && cp LICENSE ./dist/","test":"bun test src","fmt":"prettier --write .","lint":"tsc && eslint \"{src,platforms}/**/*.{js,ts,tsx}\" --quiet --fix","check-exports":"bun run build && cd dist && attw -P"},"repository":{"type":"git","url":"git+https://github.com/upstash/workflow-ts.git"},"keywords":["upstash","qstash","workflow","serverless"],"author":"Cahid Arda Oz","license":"MIT","bugs":{"url":"https://github.com/upstash/workflow-ts/issues"},"homepage":"https://github.com/upstash/workflow-ts#readme","devDependencies":{"@ai-sdk/anthropic":"^1.1.15","@commitlint/cli":"^19.5.0","@commitlint/config-conventional":"^19.5.0","@eslint/js":"^9.11.1","@solidjs/start":"^1.0.8","@sveltejs/kit":"^2.6.1","@types/bun":"^1.1.10","@types/express":"^5.0.3","astro":"^4.16.7","eslint":"^9.11.1","eslint-plugin-unicorn":"^55.0.0","express":"^5.1.0","globals":"^15.10.0","h3":"^1.12.0","hono":"^4.6.20","husky":"^9.1.6","next":"^14.2.14","prettier":"3.3.3","tsup":"^8.3.0","typescript":"^5.7.2","typescript-eslint":"^8.18.0"},"dependencies":{"@ai-sdk/openai":"^1.2.1","@upstash/qstash":"^2.8.2","ai":"^4.1.54","zod":"^3.24.1"},"directories":{"example":"examples"}}
1
+ {"name":"@upstash/workflow","version":"v0.2.20","description":"Durable, Reliable and Performant Serverless Functions","main":"./index.js","module":"./index.mjs","types":"./index.d.ts","files":["./*"],"exports":{".":{"import":"./index.mjs","require":"./index.js"},"./dist/nextjs":{"import":"./nextjs.mjs","require":"./nextjs.js"},"./nextjs":{"import":"./nextjs.mjs","require":"./nextjs.js"},"./h3":{"import":"./h3.mjs","require":"./h3.js"},"./svelte":{"import":"./svelte.mjs","require":"./svelte.js"},"./solidjs":{"import":"./solidjs.mjs","require":"./solidjs.js"},"./workflow":{"import":"./workflow.mjs","require":"./workflow.js"},"./hono":{"import":"./hono.mjs","require":"./hono.js"},"./cloudflare":{"import":"./cloudflare.mjs","require":"./cloudflare.js"},"./astro":{"import":"./astro.mjs","require":"./astro.js"},"./express":{"import":"./express.mjs","require":"./express.js"}},"scripts":{"build":"tsup && cp README.md ./dist/ && cp package.json ./dist/ && cp LICENSE ./dist/","test":"bun test src","fmt":"prettier --write .","lint":"tsc && eslint \"{src,platforms}/**/*.{js,ts,tsx}\" --quiet --fix","check-exports":"bun run build && cd dist && attw -P"},"repository":{"type":"git","url":"git+https://github.com/upstash/workflow-ts.git"},"keywords":["upstash","qstash","workflow","serverless"],"author":"Cahid Arda Oz","license":"MIT","bugs":{"url":"https://github.com/upstash/workflow-ts/issues"},"homepage":"https://github.com/upstash/workflow-ts#readme","devDependencies":{"@ai-sdk/anthropic":"^1.1.15","@commitlint/cli":"^19.5.0","@commitlint/config-conventional":"^19.5.0","@eslint/js":"^9.11.1","@solidjs/start":"^1.0.8","@sveltejs/kit":"^2.6.1","@types/bun":"^1.1.10","@types/express":"^5.0.3","astro":"^4.16.7","eslint":"^9.11.1","eslint-plugin-unicorn":"^55.0.0","express":"^5.1.0","globals":"^15.10.0","h3":"^1.12.0","hono":"^4.6.20","husky":"^9.1.6","next":"^14.2.14","prettier":"3.3.3","tsup":"^8.3.0","typescript":"^5.7.2","typescript-eslint":"^8.18.0"},"dependencies":{"@ai-sdk/openai":"^1.2.1","@upstash/qstash":"^2.8.2","ai":"^4.1.54","zod":"^3.24.1"},"directories":{"example":"examples"}}
@@ -1,4 +1,4 @@
1
- import { n as PublicServeOptions, R as RouteFunction, x as InvokableWorkflow } from './types-B7_5AkKQ.mjs';
1
+ import { n as PublicServeOptions, R as RouteFunction, y as InvokableWorkflow } from './types-Q3dM0UlR.mjs';
2
2
 
3
3
  type OmitOptionsInServeMany<TOptions> = Omit<TOptions, "env" | "url" | "schema" | "initialPayloadParser">;
4
4
  declare const serveManyBase: <THandler extends (...params: any[]) => any, TOptions extends OmitOptionsInServeMany<PublicServeOptions> = OmitOptionsInServeMany<PublicServeOptions>, TServeParams extends [routeFunction: RouteFunction<any, any>, options: TOptions] = [routeFunction: RouteFunction<any, any>, options: TOptions]>({ workflows, getUrl, serveMethod, options, }: {
@@ -1,4 +1,4 @@
1
- import { n as PublicServeOptions, R as RouteFunction, x as InvokableWorkflow } from './types-B7_5AkKQ.js';
1
+ import { n as PublicServeOptions, R as RouteFunction, y as InvokableWorkflow } from './types-Q3dM0UlR.js';
2
2
 
3
3
  type OmitOptionsInServeMany<TOptions> = Omit<TOptions, "env" | "url" | "schema" | "initialPayloadParser">;
4
4
  declare const serveManyBase: <THandler extends (...params: any[]) => any, TOptions extends OmitOptionsInServeMany<PublicServeOptions> = OmitOptionsInServeMany<PublicServeOptions>, TServeParams extends [routeFunction: RouteFunction<any, any>, options: TOptions] = [routeFunction: RouteFunction<any, any>, options: TOptions]>({ workflows, getUrl, serveMethod, options, }: {
package/solidjs.d.mts CHANGED
@@ -1,5 +1,5 @@
1
1
  import { APIEvent } from '@solidjs/start/server';
2
- import { R as RouteFunction, n as PublicServeOptions } from './types-B7_5AkKQ.mjs';
2
+ import { R as RouteFunction, n as PublicServeOptions } from './types-Q3dM0UlR.mjs';
3
3
  import '@upstash/qstash';
4
4
  import 'zod';
5
5
  import 'ai';
package/solidjs.d.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  import { APIEvent } from '@solidjs/start/server';
2
- import { R as RouteFunction, n as PublicServeOptions } from './types-B7_5AkKQ.js';
2
+ import { R as RouteFunction, n as PublicServeOptions } from './types-Q3dM0UlR.js';
3
3
  import '@upstash/qstash';
4
4
  import 'zod';
5
5
  import 'ai';
package/solidjs.js CHANGED
@@ -90,7 +90,7 @@ var WORKFLOW_PROTOCOL_VERSION_HEADER = "Upstash-Workflow-Sdk-Version";
90
90
  var DEFAULT_CONTENT_TYPE = "application/json";
91
91
  var NO_CONCURRENCY = 1;
92
92
  var DEFAULT_RETRIES = 3;
93
- var VERSION = "v0.2.18";
93
+ var VERSION = "v0.2.20";
94
94
  var SDK_TELEMETRY = `@upstash/workflow@${VERSION}`;
95
95
  var TELEMETRY_HEADER_SDK = "Upstash-Telemetry-Sdk";
96
96
  var TELEMETRY_HEADER_FRAMEWORK = "Upstash-Telemetry-Framework";
@@ -141,7 +141,8 @@ var WorkflowNonRetryableError = class extends WorkflowAbort {
141
141
  var formatWorkflowError = (error) => {
142
142
  return error instanceof Error ? {
143
143
  error: error.name,
144
- message: error.message
144
+ message: error.message,
145
+ stack: error.stack
145
146
  } : {
146
147
  error: "Error",
147
148
  message: `An error occured while executing workflow: '${typeof error === "string" ? error : JSON.stringify(error)}'`
@@ -612,7 +613,7 @@ var triggerFirstInvocation = async (params) => {
612
613
  const firstInvocationParams = Array.isArray(params) ? params : [params];
613
614
  const workflowContextClient = firstInvocationParams[0].workflowContext.qstashClient;
614
615
  const invocationBatch = firstInvocationParams.map(
615
- ({ workflowContext, useJSONContent, telemetry, invokeCount, delay }) => {
616
+ ({ workflowContext, useJSONContent, telemetry, invokeCount, delay, notBefore }) => {
616
617
  const { headers } = getHeaders({
617
618
  initHeaderValue: "true",
618
619
  workflowConfig: {
@@ -643,7 +644,8 @@ var triggerFirstInvocation = async (params) => {
643
644
  method: "POST",
644
645
  body,
645
646
  url: workflowContext.url,
646
- delay
647
+ delay,
648
+ notBefore
647
649
  };
648
650
  }
649
651
  );
@@ -1131,9 +1133,10 @@ var LazyCallStep = class _LazyCallStep extends BaseLazyStep {
1131
1133
  retryDelay;
1132
1134
  timeout;
1133
1135
  flowControl;
1136
+ stringifyBody;
1134
1137
  stepType = "Call";
1135
1138
  allowUndefinedOut = false;
1136
- constructor(stepName, url, method, body, headers, retries, retryDelay, timeout, flowControl) {
1139
+ constructor(stepName, url, method, body, headers, retries, retryDelay, timeout, flowControl, stringifyBody) {
1137
1140
  super(stepName);
1138
1141
  this.url = url;
1139
1142
  this.method = method;
@@ -1143,6 +1146,7 @@ var LazyCallStep = class _LazyCallStep extends BaseLazyStep {
1143
1146
  this.retryDelay = retryDelay;
1144
1147
  this.timeout = timeout;
1145
1148
  this.flowControl = flowControl;
1149
+ this.stringifyBody = stringifyBody;
1146
1150
  }
1147
1151
  getPlanStep(concurrent, targetStep) {
1148
1152
  return {
@@ -1252,10 +1256,22 @@ var LazyCallStep = class _LazyCallStep extends BaseLazyStep {
1252
1256
  };
1253
1257
  }
1254
1258
  async submitStep({ context, headers }) {
1259
+ let callBody;
1260
+ if (this.stringifyBody) {
1261
+ callBody = JSON.stringify(this.body);
1262
+ } else {
1263
+ if (typeof this.body === "string") {
1264
+ callBody = this.body;
1265
+ } else {
1266
+ throw new WorkflowError(
1267
+ "When stringifyBody is false, body must be a string. Please check the body type of your call step."
1268
+ );
1269
+ }
1270
+ }
1255
1271
  return await context.qstashClient.batch([
1256
1272
  {
1257
1273
  headers,
1258
- body: JSON.stringify(this.body),
1274
+ body: callBody,
1259
1275
  method: this.method,
1260
1276
  url: this.url,
1261
1277
  retries: DEFAULT_RETRIES === this.retries ? void 0 : this.retries,
@@ -1390,7 +1406,8 @@ var LazyInvokeStep = class extends BaseLazyStep {
1390
1406
  workflowRunId,
1391
1407
  retries,
1392
1408
  retryDelay,
1393
- flowControl
1409
+ flowControl,
1410
+ stringifyBody = true
1394
1411
  }) {
1395
1412
  super(stepName);
1396
1413
  this.params = {
@@ -1400,7 +1417,8 @@ var LazyInvokeStep = class extends BaseLazyStep {
1400
1417
  workflowRunId: getWorkflowRunId(workflowRunId),
1401
1418
  retries,
1402
1419
  retryDelay,
1403
- flowControl
1420
+ flowControl,
1421
+ stringifyBody
1404
1422
  };
1405
1423
  const { workflowId } = workflow;
1406
1424
  if (!workflowId) {
@@ -1453,8 +1471,20 @@ var LazyInvokeStep = class extends BaseLazyStep {
1453
1471
  invokeCount
1454
1472
  });
1455
1473
  invokerHeaders["Upstash-Workflow-Runid"] = context.workflowRunId;
1474
+ let invokeBody;
1475
+ if (this.params.stringifyBody) {
1476
+ invokeBody = JSON.stringify(this.params.body);
1477
+ } else {
1478
+ if (typeof this.params.body === "string") {
1479
+ invokeBody = this.params.body;
1480
+ } else {
1481
+ throw new WorkflowError(
1482
+ "When stringifyBody is false, body must be a string. Please check the body type of your invoke step."
1483
+ );
1484
+ }
1485
+ }
1456
1486
  const request = {
1457
- body: JSON.stringify(this.params.body),
1487
+ body: invokeBody,
1458
1488
  headers: Object.fromEntries(
1459
1489
  Object.entries(invokerHeaders).map((pairs) => [pairs[0], [pairs[1]]])
1460
1490
  ),
@@ -2831,7 +2861,8 @@ var WorkflowContext = class {
2831
2861
  settings.retries || 0,
2832
2862
  settings.retryDelay,
2833
2863
  settings.timeout,
2834
- settings.flowControl ?? settings.workflow.options.flowControl
2864
+ settings.flowControl ?? settings.workflow.options.flowControl,
2865
+ settings.stringifyBody ?? true
2835
2866
  );
2836
2867
  } else {
2837
2868
  const {
@@ -2842,7 +2873,8 @@ var WorkflowContext = class {
2842
2873
  retries = 0,
2843
2874
  retryDelay,
2844
2875
  timeout,
2845
- flowControl
2876
+ flowControl,
2877
+ stringifyBody = true
2846
2878
  } = settings;
2847
2879
  callStep = new LazyCallStep(
2848
2880
  stepName,
@@ -2853,7 +2885,8 @@ var WorkflowContext = class {
2853
2885
  retries,
2854
2886
  retryDelay,
2855
2887
  timeout,
2856
- flowControl
2888
+ flowControl,
2889
+ stringifyBody
2857
2890
  );
2858
2891
  }
2859
2892
  return await this.addStep(callStep);
@@ -3217,11 +3250,15 @@ var handleFailure = async (request, requestPayload, qstashClient, initialPayload
3217
3250
  const { status, header, body, url, sourceBody, workflowRunId } = JSON.parse(requestPayload);
3218
3251
  const decodedBody = body ? decodeBase64(body) : "{}";
3219
3252
  let errorMessage = "";
3253
+ let failStack = "";
3220
3254
  try {
3221
3255
  const errorPayload = JSON.parse(decodedBody);
3222
3256
  if (errorPayload.message) {
3223
3257
  errorMessage = errorPayload.message;
3224
3258
  }
3259
+ if (errorPayload.stack) {
3260
+ failStack = errorPayload.stack;
3261
+ }
3225
3262
  } catch {
3226
3263
  }
3227
3264
  if (!errorMessage) {
@@ -3259,7 +3296,8 @@ var handleFailure = async (request, requestPayload, qstashClient, initialPayload
3259
3296
  context: workflowContext,
3260
3297
  failStatus: status,
3261
3298
  failResponse: errorMessage,
3262
- failHeaders: header
3299
+ failHeaders: header,
3300
+ failStack
3263
3301
  });
3264
3302
  return ok({ result: "is-failure-callback", response: failureResponse });
3265
3303
  } catch (error) {
@@ -3276,7 +3314,7 @@ var processOptions = (options) => {
3276
3314
  environment.QSTASH_CURRENT_SIGNING_KEY && environment.QSTASH_NEXT_SIGNING_KEY
3277
3315
  );
3278
3316
  return {
3279
- qstashClient: new import_qstash11.Client({
3317
+ qstashClient: options?.qstashClient ?? new import_qstash11.Client({
3280
3318
  baseUrl: environment.QSTASH_URL,
3281
3319
  token: environment.QSTASH_TOKEN
3282
3320
  }),
package/solidjs.mjs CHANGED
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  SDK_TELEMETRY,
3
3
  serveBase
4
- } from "./chunk-EHL7SSJF.mjs";
4
+ } from "./chunk-LZGX3WMF.mjs";
5
5
 
6
6
  // platforms/solidjs.ts
7
7
  var serve = (routeFunction, options) => {