@upstash/workflow 0.2.6 → 0.2.8-rc-invoke

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
@@ -88,7 +88,7 @@ var WORKFLOW_PROTOCOL_VERSION_HEADER = "Upstash-Workflow-Sdk-Version";
88
88
  var DEFAULT_CONTENT_TYPE = "application/json";
89
89
  var NO_CONCURRENCY = 1;
90
90
  var DEFAULT_RETRIES = 3;
91
- var VERSION = "v0.2.3";
91
+ var VERSION = "v0.2.7";
92
92
  var SDK_TELEMETRY = `@upstash/workflow@${VERSION}`;
93
93
  var TELEMETRY_HEADER_SDK = "Upstash-Telemetry-Sdk";
94
94
  var TELEMETRY_HEADER_FRAMEWORK = "Upstash-Telemetry-Framework";
@@ -135,6 +135,31 @@ var formatWorkflowError = (error) => {
135
135
  };
136
136
  };
137
137
 
138
+ // src/utils.ts
139
+ var NANOID_CHARS = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-_";
140
+ var NANOID_LENGTH = 21;
141
+ function getRandomInt() {
142
+ return Math.floor(Math.random() * NANOID_CHARS.length);
143
+ }
144
+ function nanoid() {
145
+ return Array.from({ length: NANOID_LENGTH }).map(() => NANOID_CHARS[getRandomInt()]).join("");
146
+ }
147
+ function getWorkflowRunId(id) {
148
+ return `wfr_${id ?? nanoid()}`;
149
+ }
150
+ function decodeBase64(base64) {
151
+ try {
152
+ const binString = atob(base64);
153
+ const intArray = Uint8Array.from(binString, (m) => m.codePointAt(0));
154
+ return new TextDecoder().decode(intArray);
155
+ } catch (error) {
156
+ console.warn(
157
+ `Upstash Qstash: Failed while decoding base64 "${base64}". Decoding with atob and returning it instead. ${error}`
158
+ );
159
+ return atob(base64);
160
+ }
161
+ }
162
+
138
163
  // src/context/steps.ts
139
164
  var BaseLazyStep = class {
140
165
  stepName;
@@ -315,6 +340,41 @@ var LazyNotifyStep = class extends LazyFunctionStep {
315
340
  });
316
341
  }
317
342
  };
343
+ var LazyInvokeStep = class extends BaseLazyStep {
344
+ stepType = "Invoke";
345
+ params;
346
+ constructor(stepName, { workflow, body, headers = {}, workflowRunId, retries }) {
347
+ super(stepName);
348
+ this.params = {
349
+ workflow,
350
+ body,
351
+ headers,
352
+ workflowRunId: getWorkflowRunId(workflowRunId),
353
+ retries
354
+ };
355
+ }
356
+ getPlanStep(concurrent, targetStep) {
357
+ return {
358
+ stepId: 0,
359
+ stepName: this.stepName,
360
+ stepType: this.stepType,
361
+ concurrent,
362
+ targetStep
363
+ };
364
+ }
365
+ /**
366
+ * won't be used as it's the server who will add the result step
367
+ * in Invoke step.
368
+ */
369
+ getResultStep(concurrent, stepId) {
370
+ return Promise.resolve({
371
+ stepId,
372
+ stepName: this.stepName,
373
+ stepType: this.stepType,
374
+ concurrent
375
+ });
376
+ }
377
+ };
318
378
 
319
379
  // node_modules/neverthrow/dist/index.es.js
320
380
  var defaultErrorConfig = {
@@ -739,7 +799,8 @@ var StepTypes = [
739
799
  "SleepUntil",
740
800
  "Call",
741
801
  "Wait",
742
- "Notify"
802
+ "Notify",
803
+ "Invoke"
743
804
  ];
744
805
 
745
806
  // src/workflow-requests.ts
@@ -759,6 +820,9 @@ var triggerFirstInvocation = async ({
759
820
  retries: workflowContext.retries,
760
821
  telemetry
761
822
  });
823
+ if (workflowContext.headers.get("content-type")) {
824
+ headers["content-type"] = workflowContext.headers.get("content-type");
825
+ }
762
826
  if (useJSONContent) {
763
827
  headers["content-type"] = "application/json";
764
828
  }
@@ -800,8 +864,8 @@ var triggerRouteFunction = async ({
800
864
  debug
801
865
  }) => {
802
866
  try {
803
- await onStep();
804
- await onCleanup();
867
+ const result = await onStep();
868
+ await onCleanup(result);
805
869
  return ok("workflow-finished");
806
870
  } catch (error) {
807
871
  const error_ = error;
@@ -822,14 +886,15 @@ var triggerRouteFunction = async ({
822
886
  }
823
887
  }
824
888
  };
825
- var triggerWorkflowDelete = async (workflowContext, debug, cancel = false) => {
889
+ var triggerWorkflowDelete = async (workflowContext, result, debug, cancel = false) => {
826
890
  await debug?.log("SUBMIT", "SUBMIT_CLEANUP", {
827
891
  deletedWorkflowRunId: workflowContext.workflowRunId
828
892
  });
829
893
  await workflowContext.qstashClient.http.request({
830
894
  path: ["v2", "workflows", "runs", `${workflowContext.workflowRunId}?cancel=${cancel}`],
831
895
  method: "DELETE",
832
- parseResponseAsJson: false
896
+ parseResponseAsJson: false,
897
+ body: JSON.stringify(result)
833
898
  });
834
899
  await debug?.log(
835
900
  "SUBMIT",
@@ -984,11 +1049,14 @@ var getHeaders = ({
984
1049
  callTimeout,
985
1050
  telemetry
986
1051
  }) => {
1052
+ const contentType = (userHeaders ? userHeaders.get("Content-Type") : void 0) ?? DEFAULT_CONTENT_TYPE;
987
1053
  const baseHeaders = {
988
1054
  [WORKFLOW_INIT_HEADER]: initHeaderValue,
989
1055
  [WORKFLOW_ID_HEADER]: workflowRunId,
990
1056
  [WORKFLOW_URL_HEADER]: workflowUrl,
991
1057
  [WORKFLOW_FEATURE_HEADER]: "LazyFetch,InitialBody",
1058
+ [WORKFLOW_PROTOCOL_VERSION_HEADER]: WORKFLOW_PROTOCOL_VERSION,
1059
+ "content-type": contentType,
992
1060
  ...telemetry ? getTelemetryHeaders(telemetry) : {}
993
1061
  };
994
1062
  if (!step?.callUrl) {
@@ -1003,6 +1071,9 @@ var getHeaders = ({
1003
1071
  baseHeaders["Upstash-Failure-Callback"] = failureUrl;
1004
1072
  }
1005
1073
  }
1074
+ if (step?.stepType === "Invoke") {
1075
+ baseHeaders["upstash-workflow-invoke"] = "true";
1076
+ }
1006
1077
  if (step?.callUrl) {
1007
1078
  baseHeaders["Upstash-Retries"] = callRetries?.toString() ?? "0";
1008
1079
  baseHeaders[WORKFLOW_FEATURE_HEADER] = "WF_NoDelete,InitialBody";
@@ -1024,7 +1095,6 @@ var getHeaders = ({
1024
1095
  baseHeaders[`Upstash-Failure-Callback-Forward-${header}`] = userHeaders.get(header);
1025
1096
  }
1026
1097
  }
1027
- const contentType = (userHeaders ? userHeaders.get("Content-Type") : void 0) ?? DEFAULT_CONTENT_TYPE;
1028
1098
  if (step?.callHeaders) {
1029
1099
  const forwardedHeaders = Object.fromEntries(
1030
1100
  Object.entries(step.callHeaders).map(([header, value]) => [
@@ -1074,8 +1144,7 @@ var getHeaders = ({
1074
1144
  "Upstash-Workflow-Runid": [workflowRunId],
1075
1145
  [WORKFLOW_INIT_HEADER]: ["false"],
1076
1146
  [WORKFLOW_URL_HEADER]: [workflowUrl],
1077
- "Upstash-Workflow-CallType": ["step"],
1078
- "Content-Type": [contentType]
1147
+ "Upstash-Workflow-CallType": ["step"]
1079
1148
  }
1080
1149
  };
1081
1150
  }
@@ -1370,7 +1439,23 @@ var AutoExecutor = class _AutoExecutor {
1370
1439
  method: "POST",
1371
1440
  parseResponseAsJson: false
1372
1441
  });
1373
- throw new WorkflowAbort(steps[0].stepName, steps[0]);
1442
+ throw new WorkflowAbort(waitStep.stepName, waitStep);
1443
+ }
1444
+ if (steps.length === 1 && lazySteps[0] instanceof LazyInvokeStep) {
1445
+ const invokeStep = steps[0];
1446
+ const lazyInvokeStep = lazySteps[0];
1447
+ await lazyInvokeStep.params.workflow.callback(
1448
+ {
1449
+ body: lazyInvokeStep.params.body,
1450
+ headers: lazyInvokeStep.params.headers,
1451
+ workflowRunId: lazyInvokeStep.params.workflowRunId,
1452
+ workflow: lazyInvokeStep.params.workflow,
1453
+ retries: lazyInvokeStep.params.retries
1454
+ },
1455
+ invokeStep,
1456
+ this.context
1457
+ );
1458
+ throw new WorkflowAbort(invokeStep.stepName, invokeStep);
1374
1459
  }
1375
1460
  const result = await this.context.qstashClient.batchJSON(
1376
1461
  steps.map((singleStep, index) => {
@@ -2287,6 +2372,13 @@ var WorkflowContext = class {
2287
2372
  return result;
2288
2373
  }
2289
2374
  }
2375
+ async invoke(stepName, settings) {
2376
+ const result = await this.addStep(new LazyInvokeStep(stepName, settings));
2377
+ return {
2378
+ ...result,
2379
+ body: result.body ? JSON.parse(result.body) : void 0
2380
+ };
2381
+ }
2290
2382
  /**
2291
2383
  * Cancel the current workflow run
2292
2384
  *
@@ -2364,31 +2456,6 @@ var WorkflowLogger = class _WorkflowLogger {
2364
2456
  }
2365
2457
  };
2366
2458
 
2367
- // src/utils.ts
2368
- var NANOID_CHARS = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-_";
2369
- var NANOID_LENGTH = 21;
2370
- function getRandomInt() {
2371
- return Math.floor(Math.random() * NANOID_CHARS.length);
2372
- }
2373
- function nanoid() {
2374
- return Array.from({ length: NANOID_LENGTH }).map(() => NANOID_CHARS[getRandomInt()]).join("");
2375
- }
2376
- function getWorkflowRunId(id) {
2377
- return `wfr_${id ?? nanoid()}`;
2378
- }
2379
- function decodeBase64(base64) {
2380
- try {
2381
- const binString = atob(base64);
2382
- const intArray = Uint8Array.from(binString, (m) => m.codePointAt(0));
2383
- return new TextDecoder().decode(intArray);
2384
- } catch (error) {
2385
- console.warn(
2386
- `Upstash Qstash: Failed while decoding base64 "${base64}". Decoding with atob and returning it instead. ${error}`
2387
- );
2388
- return atob(base64);
2389
- }
2390
- }
2391
-
2392
2459
  // src/serve/authorization.ts
2393
2460
  var import_qstash8 = require("@upstash/qstash");
2394
2461
  var DisabledWorkflowContext = class _DisabledWorkflowContext extends WorkflowContext {
@@ -2834,8 +2901,8 @@ var serveBase = (routeFunction, telemetry, options) => {
2834
2901
  } else if (callReturnCheck.value === "continue-workflow") {
2835
2902
  const result = isFirstInvocation ? await triggerFirstInvocation({ workflowContext, useJSONContent, telemetry, debug }) : await triggerRouteFunction({
2836
2903
  onStep: async () => routeFunction(workflowContext),
2837
- onCleanup: async () => {
2838
- await triggerWorkflowDelete(workflowContext, debug);
2904
+ onCleanup: async (result2) => {
2905
+ await triggerWorkflowDelete(workflowContext, result2, debug);
2839
2906
  },
2840
2907
  onCancel: async () => {
2841
2908
  await makeCancelRequest(workflowContext.qstashClient.http, workflowRunId);
@@ -2869,6 +2936,11 @@ var serveBase = (routeFunction, telemetry, options) => {
2869
2936
 
2870
2937
  // platforms/solidjs.ts
2871
2938
  var serve = (routeFunction, options) => {
2939
+ const telemetry = {
2940
+ sdk: SDK_TELEMETRY,
2941
+ framework: "solidjs",
2942
+ runtime: process.versions.bun ? `bun@${process.versions.bun}/node@${process.version}` : `node@${process.version}`
2943
+ };
2872
2944
  const handler = async (event) => {
2873
2945
  const method = event.request.method;
2874
2946
  if (method.toUpperCase() !== "POST") {
@@ -2876,15 +2948,7 @@ var serve = (routeFunction, options) => {
2876
2948
  status: 405
2877
2949
  });
2878
2950
  }
2879
- const { handler: serveHandler } = serveBase(
2880
- routeFunction,
2881
- {
2882
- sdk: SDK_TELEMETRY,
2883
- framework: "solidjs",
2884
- runtime: process.versions.bun ? `bun@${process.versions.bun}/node@${process.version}` : `node@${process.version}`
2885
- },
2886
- options
2887
- );
2951
+ const { handler: serveHandler } = serveBase(routeFunction, telemetry, options);
2888
2952
  return await serveHandler(event.request);
2889
2953
  };
2890
2954
  return { POST: handler };
package/solidjs.mjs CHANGED
@@ -1,10 +1,15 @@
1
1
  import {
2
2
  SDK_TELEMETRY,
3
3
  serveBase
4
- } from "./chunk-OLNSY3BB.mjs";
4
+ } from "./chunk-IWAW7GIG.mjs";
5
5
 
6
6
  // platforms/solidjs.ts
7
7
  var serve = (routeFunction, options) => {
8
+ const telemetry = {
9
+ sdk: SDK_TELEMETRY,
10
+ framework: "solidjs",
11
+ runtime: process.versions.bun ? `bun@${process.versions.bun}/node@${process.version}` : `node@${process.version}`
12
+ };
8
13
  const handler = async (event) => {
9
14
  const method = event.request.method;
10
15
  if (method.toUpperCase() !== "POST") {
@@ -12,15 +17,7 @@ var serve = (routeFunction, options) => {
12
17
  status: 405
13
18
  });
14
19
  }
15
- const { handler: serveHandler } = serveBase(
16
- routeFunction,
17
- {
18
- sdk: SDK_TELEMETRY,
19
- framework: "solidjs",
20
- runtime: process.versions.bun ? `bun@${process.versions.bun}/node@${process.version}` : `node@${process.version}`
21
- },
22
- options
23
- );
20
+ const { handler: serveHandler } = serveBase(routeFunction, telemetry, options);
24
21
  return await serveHandler(event.request);
25
22
  };
26
23
  return { POST: handler };
package/svelte.d.mts CHANGED
@@ -1,12 +1,14 @@
1
+ import * as _sveltejs_kit from '@sveltejs/kit';
1
2
  import { RequestHandler } from '@sveltejs/kit';
2
- import { R as RouteFunction, j as PublicServeOptions } from './types-Cuqlx2Cr.mjs';
3
+ import { R as RouteFunction, j as PublicServeOptions, t as InvokableWorkflow } from './types-C7Y7WUQd.mjs';
4
+ import { s as serveManyBase } from './serve-many-BlBvXfBS.mjs';
3
5
  import '@upstash/qstash';
4
6
  import 'zod';
5
7
  import 'ai';
6
8
  import '@ai-sdk/openai';
7
9
 
8
10
  /**
9
- * Serve method to serve a Upstash Workflow in a Nextjs project
11
+ * Serve method to serve a Upstash Workflow in a Svelte project
10
12
  *
11
13
  * See for options https://upstash.com/docs/qstash/workflows/basics/serve
12
14
  *
@@ -14,10 +16,16 @@ import '@ai-sdk/openai';
14
16
  * @param options workflow options
15
17
  * @returns
16
18
  */
17
- declare const serve: <TInitialPayload = unknown>(routeFunction: RouteFunction<TInitialPayload>, options: PublicServeOptions<TInitialPayload> & {
19
+ declare const serve: <TInitialPayload = unknown, TResult = unknown>(routeFunction: RouteFunction<TInitialPayload, TResult>, options: PublicServeOptions<TInitialPayload> & {
18
20
  env: PublicServeOptions["env"];
19
21
  }) => {
20
22
  POST: RequestHandler;
21
23
  };
24
+ declare const createWorkflow: <TInitialPayload, TResult>(routeFunction: RouteFunction<TInitialPayload, TResult>, options: PublicServeOptions<TInitialPayload> & {
25
+ env: PublicServeOptions["env"];
26
+ }) => InvokableWorkflow<TInitialPayload, TResult, Parameters<ReturnType<typeof serve<TInitialPayload, TResult>>["POST"]>>;
27
+ declare const serveMany: (workflows: Parameters<typeof serveManyBase>[0]["workflows"]) => {
28
+ POST: (event: _sveltejs_kit.RequestEvent<Partial<Record<string, string>>, string | null>) => Promise<any>;
29
+ };
22
30
 
23
- export { serve };
31
+ export { createWorkflow, serve, serveMany };
package/svelte.d.ts CHANGED
@@ -1,12 +1,14 @@
1
+ import * as _sveltejs_kit from '@sveltejs/kit';
1
2
  import { RequestHandler } from '@sveltejs/kit';
2
- import { R as RouteFunction, j as PublicServeOptions } from './types-Cuqlx2Cr.js';
3
+ import { R as RouteFunction, j as PublicServeOptions, t as InvokableWorkflow } from './types-C7Y7WUQd.js';
4
+ import { s as serveManyBase } from './serve-many-Dw-UUnH6.js';
3
5
  import '@upstash/qstash';
4
6
  import 'zod';
5
7
  import 'ai';
6
8
  import '@ai-sdk/openai';
7
9
 
8
10
  /**
9
- * Serve method to serve a Upstash Workflow in a Nextjs project
11
+ * Serve method to serve a Upstash Workflow in a Svelte project
10
12
  *
11
13
  * See for options https://upstash.com/docs/qstash/workflows/basics/serve
12
14
  *
@@ -14,10 +16,16 @@ import '@ai-sdk/openai';
14
16
  * @param options workflow options
15
17
  * @returns
16
18
  */
17
- declare const serve: <TInitialPayload = unknown>(routeFunction: RouteFunction<TInitialPayload>, options: PublicServeOptions<TInitialPayload> & {
19
+ declare const serve: <TInitialPayload = unknown, TResult = unknown>(routeFunction: RouteFunction<TInitialPayload, TResult>, options: PublicServeOptions<TInitialPayload> & {
18
20
  env: PublicServeOptions["env"];
19
21
  }) => {
20
22
  POST: RequestHandler;
21
23
  };
24
+ declare const createWorkflow: <TInitialPayload, TResult>(routeFunction: RouteFunction<TInitialPayload, TResult>, options: PublicServeOptions<TInitialPayload> & {
25
+ env: PublicServeOptions["env"];
26
+ }) => InvokableWorkflow<TInitialPayload, TResult, Parameters<ReturnType<typeof serve<TInitialPayload, TResult>>["POST"]>>;
27
+ declare const serveMany: (workflows: Parameters<typeof serveManyBase>[0]["workflows"]) => {
28
+ POST: (event: _sveltejs_kit.RequestEvent<Partial<Record<string, string>>, string | null>) => Promise<any>;
29
+ };
22
30
 
23
- export { serve };
31
+ export { createWorkflow, serve, serveMany };