@upstash/workflow 0.2.7 → 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/astro.d.mts +8 -3
- package/astro.d.ts +8 -3
- package/astro.js +238 -65
- package/astro.mjs +33 -7
- package/{chunk-U6XFLG7W.mjs → chunk-IWAW7GIG.mjs} +103 -38
- package/chunk-LCZMBGEM.mjs +95 -0
- package/cloudflare.d.mts +9 -4
- package/cloudflare.d.ts +9 -4
- package/cloudflare.js +241 -71
- package/cloudflare.mjs +36 -13
- package/express.d.mts +7 -3
- package/express.d.ts +7 -3
- package/express.js +248 -68
- package/express.mjs +41 -10
- package/h3.d.mts +9 -7
- package/h3.d.ts +9 -7
- package/h3.js +249 -78
- package/h3.mjs +44 -20
- package/hono.d.mts +10 -4
- package/hono.d.ts +10 -4
- package/hono.js +240 -73
- package/hono.mjs +35 -15
- package/index.d.mts +17 -4
- package/index.d.ts +17 -4
- package/index.js +102 -38
- package/index.mjs +2 -2
- package/nextjs.d.mts +14 -5
- package/nextjs.d.ts +14 -5
- package/nextjs.js +249 -52
- package/nextjs.mjs +64 -16
- package/package.json +1 -1
- package/serve-many-BlBvXfBS.d.mts +10 -0
- package/serve-many-Dw-UUnH6.d.ts +10 -0
- package/solidjs.d.mts +3 -3
- package/solidjs.d.ts +3 -3
- package/solidjs.js +107 -46
- package/solidjs.mjs +7 -10
- package/svelte.d.mts +12 -4
- package/svelte.d.ts +12 -4
- package/svelte.js +240 -71
- package/svelte.mjs +35 -13
- package/{types-Cuqlx2Cr.d.mts → types-C7Y7WUQd.d.mts} +31 -3
- package/{types-Cuqlx2Cr.d.ts → types-C7Y7WUQd.d.ts} +31 -3
package/hono.d.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { Context } from 'hono';
|
|
2
|
-
import { R as RouteFunction, j as PublicServeOptions } from './types-
|
|
2
|
+
import { R as RouteFunction, j as PublicServeOptions, t as InvokableWorkflow } from './types-C7Y7WUQd.js';
|
|
3
3
|
import { Variables } from 'hono/types';
|
|
4
|
+
import { s as serveManyBase } from './serve-many-Dw-UUnH6.js';
|
|
4
5
|
import '@upstash/qstash';
|
|
5
6
|
import 'zod';
|
|
6
7
|
import 'ai';
|
|
@@ -14,7 +15,7 @@ type WorkflowBindings = {
|
|
|
14
15
|
UPSTASH_WORKFLOW_URL?: string;
|
|
15
16
|
};
|
|
16
17
|
/**
|
|
17
|
-
* Serve method to serve a Upstash Workflow in a
|
|
18
|
+
* Serve method to serve a Upstash Workflow in a Hono project
|
|
18
19
|
*
|
|
19
20
|
* See for options https://upstash.com/docs/qstash/workflows/basics/serve
|
|
20
21
|
*
|
|
@@ -22,9 +23,14 @@ type WorkflowBindings = {
|
|
|
22
23
|
* @param options workflow options
|
|
23
24
|
* @returns
|
|
24
25
|
*/
|
|
25
|
-
declare const serve: <TInitialPayload = unknown, TBindings extends WorkflowBindings = WorkflowBindings, TVariables extends Variables = object>(routeFunction: RouteFunction<TInitialPayload>, options?: PublicServeOptions<TInitialPayload>) => ((context: Context<{
|
|
26
|
+
declare const serve: <TInitialPayload = unknown, TBindings extends WorkflowBindings = WorkflowBindings, TVariables extends Variables = object, TResult = unknown>(routeFunction: RouteFunction<TInitialPayload, TResult>, options?: PublicServeOptions<TInitialPayload>) => ((context: Context<{
|
|
26
27
|
Bindings: TBindings;
|
|
27
28
|
Variables: TVariables;
|
|
28
29
|
}>) => Promise<Response>);
|
|
30
|
+
declare const createWorkflow: <TInitialPayload, TResult>(routeFunction: RouteFunction<TInitialPayload, TResult>, options?: PublicServeOptions<TInitialPayload> | undefined) => InvokableWorkflow<TInitialPayload, TResult, Parameters<ReturnType<typeof serve<TInitialPayload, WorkflowBindings, Variables, TResult>>>>;
|
|
31
|
+
declare const serveMany: (workflows: Parameters<typeof serveManyBase>[0]["workflows"]) => (context: Context<{
|
|
32
|
+
Bindings: WorkflowBindings;
|
|
33
|
+
Variables: object;
|
|
34
|
+
}, any, {}>) => Promise<any>;
|
|
29
35
|
|
|
30
|
-
export { type WorkflowBindings, serve };
|
|
36
|
+
export { type WorkflowBindings, createWorkflow, serve, serveMany };
|
package/hono.js
CHANGED
|
@@ -20,7 +20,9 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
|
|
|
20
20
|
// platforms/hono.ts
|
|
21
21
|
var hono_exports = {};
|
|
22
22
|
__export(hono_exports, {
|
|
23
|
-
|
|
23
|
+
createWorkflow: () => createWorkflow,
|
|
24
|
+
serve: () => serve,
|
|
25
|
+
serveMany: () => serveMany
|
|
24
26
|
});
|
|
25
27
|
module.exports = __toCommonJS(hono_exports);
|
|
26
28
|
|
|
@@ -88,7 +90,7 @@ var WORKFLOW_PROTOCOL_VERSION_HEADER = "Upstash-Workflow-Sdk-Version";
|
|
|
88
90
|
var DEFAULT_CONTENT_TYPE = "application/json";
|
|
89
91
|
var NO_CONCURRENCY = 1;
|
|
90
92
|
var DEFAULT_RETRIES = 3;
|
|
91
|
-
var VERSION = "v0.2.
|
|
93
|
+
var VERSION = "v0.2.7";
|
|
92
94
|
var SDK_TELEMETRY = `@upstash/workflow@${VERSION}`;
|
|
93
95
|
var TELEMETRY_HEADER_SDK = "Upstash-Telemetry-Sdk";
|
|
94
96
|
var TELEMETRY_HEADER_FRAMEWORK = "Upstash-Telemetry-Framework";
|
|
@@ -135,6 +137,31 @@ var formatWorkflowError = (error) => {
|
|
|
135
137
|
};
|
|
136
138
|
};
|
|
137
139
|
|
|
140
|
+
// src/utils.ts
|
|
141
|
+
var NANOID_CHARS = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-_";
|
|
142
|
+
var NANOID_LENGTH = 21;
|
|
143
|
+
function getRandomInt() {
|
|
144
|
+
return Math.floor(Math.random() * NANOID_CHARS.length);
|
|
145
|
+
}
|
|
146
|
+
function nanoid() {
|
|
147
|
+
return Array.from({ length: NANOID_LENGTH }).map(() => NANOID_CHARS[getRandomInt()]).join("");
|
|
148
|
+
}
|
|
149
|
+
function getWorkflowRunId(id) {
|
|
150
|
+
return `wfr_${id ?? nanoid()}`;
|
|
151
|
+
}
|
|
152
|
+
function decodeBase64(base64) {
|
|
153
|
+
try {
|
|
154
|
+
const binString = atob(base64);
|
|
155
|
+
const intArray = Uint8Array.from(binString, (m) => m.codePointAt(0));
|
|
156
|
+
return new TextDecoder().decode(intArray);
|
|
157
|
+
} catch (error) {
|
|
158
|
+
console.warn(
|
|
159
|
+
`Upstash Qstash: Failed while decoding base64 "${base64}". Decoding with atob and returning it instead. ${error}`
|
|
160
|
+
);
|
|
161
|
+
return atob(base64);
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
|
|
138
165
|
// src/context/steps.ts
|
|
139
166
|
var BaseLazyStep = class {
|
|
140
167
|
stepName;
|
|
@@ -315,6 +342,41 @@ var LazyNotifyStep = class extends LazyFunctionStep {
|
|
|
315
342
|
});
|
|
316
343
|
}
|
|
317
344
|
};
|
|
345
|
+
var LazyInvokeStep = class extends BaseLazyStep {
|
|
346
|
+
stepType = "Invoke";
|
|
347
|
+
params;
|
|
348
|
+
constructor(stepName, { workflow, body, headers = {}, workflowRunId, retries }) {
|
|
349
|
+
super(stepName);
|
|
350
|
+
this.params = {
|
|
351
|
+
workflow,
|
|
352
|
+
body,
|
|
353
|
+
headers,
|
|
354
|
+
workflowRunId: getWorkflowRunId(workflowRunId),
|
|
355
|
+
retries
|
|
356
|
+
};
|
|
357
|
+
}
|
|
358
|
+
getPlanStep(concurrent, targetStep) {
|
|
359
|
+
return {
|
|
360
|
+
stepId: 0,
|
|
361
|
+
stepName: this.stepName,
|
|
362
|
+
stepType: this.stepType,
|
|
363
|
+
concurrent,
|
|
364
|
+
targetStep
|
|
365
|
+
};
|
|
366
|
+
}
|
|
367
|
+
/**
|
|
368
|
+
* won't be used as it's the server who will add the result step
|
|
369
|
+
* in Invoke step.
|
|
370
|
+
*/
|
|
371
|
+
getResultStep(concurrent, stepId) {
|
|
372
|
+
return Promise.resolve({
|
|
373
|
+
stepId,
|
|
374
|
+
stepName: this.stepName,
|
|
375
|
+
stepType: this.stepType,
|
|
376
|
+
concurrent
|
|
377
|
+
});
|
|
378
|
+
}
|
|
379
|
+
};
|
|
318
380
|
|
|
319
381
|
// node_modules/neverthrow/dist/index.es.js
|
|
320
382
|
var defaultErrorConfig = {
|
|
@@ -739,7 +801,8 @@ var StepTypes = [
|
|
|
739
801
|
"SleepUntil",
|
|
740
802
|
"Call",
|
|
741
803
|
"Wait",
|
|
742
|
-
"Notify"
|
|
804
|
+
"Notify",
|
|
805
|
+
"Invoke"
|
|
743
806
|
];
|
|
744
807
|
|
|
745
808
|
// src/workflow-requests.ts
|
|
@@ -747,7 +810,7 @@ var import_qstash3 = require("@upstash/qstash");
|
|
|
747
810
|
var triggerFirstInvocation = async ({
|
|
748
811
|
workflowContext,
|
|
749
812
|
useJSONContent,
|
|
750
|
-
telemetry,
|
|
813
|
+
telemetry: telemetry2,
|
|
751
814
|
debug
|
|
752
815
|
}) => {
|
|
753
816
|
const { headers } = getHeaders({
|
|
@@ -757,7 +820,7 @@ var triggerFirstInvocation = async ({
|
|
|
757
820
|
userHeaders: workflowContext.headers,
|
|
758
821
|
failureUrl: workflowContext.failureUrl,
|
|
759
822
|
retries: workflowContext.retries,
|
|
760
|
-
telemetry
|
|
823
|
+
telemetry: telemetry2
|
|
761
824
|
});
|
|
762
825
|
if (workflowContext.headers.get("content-type")) {
|
|
763
826
|
headers["content-type"] = workflowContext.headers.get("content-type");
|
|
@@ -803,8 +866,8 @@ var triggerRouteFunction = async ({
|
|
|
803
866
|
debug
|
|
804
867
|
}) => {
|
|
805
868
|
try {
|
|
806
|
-
await onStep();
|
|
807
|
-
await onCleanup();
|
|
869
|
+
const result = await onStep();
|
|
870
|
+
await onCleanup(result);
|
|
808
871
|
return ok("workflow-finished");
|
|
809
872
|
} catch (error) {
|
|
810
873
|
const error_ = error;
|
|
@@ -825,14 +888,15 @@ var triggerRouteFunction = async ({
|
|
|
825
888
|
}
|
|
826
889
|
}
|
|
827
890
|
};
|
|
828
|
-
var triggerWorkflowDelete = async (workflowContext, debug, cancel = false) => {
|
|
891
|
+
var triggerWorkflowDelete = async (workflowContext, result, debug, cancel = false) => {
|
|
829
892
|
await debug?.log("SUBMIT", "SUBMIT_CLEANUP", {
|
|
830
893
|
deletedWorkflowRunId: workflowContext.workflowRunId
|
|
831
894
|
});
|
|
832
895
|
await workflowContext.qstashClient.http.request({
|
|
833
896
|
path: ["v2", "workflows", "runs", `${workflowContext.workflowRunId}?cancel=${cancel}`],
|
|
834
897
|
method: "DELETE",
|
|
835
|
-
parseResponseAsJson: false
|
|
898
|
+
parseResponseAsJson: false,
|
|
899
|
+
body: JSON.stringify(result)
|
|
836
900
|
});
|
|
837
901
|
await debug?.log(
|
|
838
902
|
"SUBMIT",
|
|
@@ -861,7 +925,7 @@ var handleThirdPartyCallResult = async ({
|
|
|
861
925
|
workflowUrl,
|
|
862
926
|
failureUrl,
|
|
863
927
|
retries,
|
|
864
|
-
telemetry,
|
|
928
|
+
telemetry: telemetry2,
|
|
865
929
|
debug
|
|
866
930
|
}) => {
|
|
867
931
|
try {
|
|
@@ -929,7 +993,7 @@ ${atob(callbackMessage.body ?? "")}`
|
|
|
929
993
|
userHeaders,
|
|
930
994
|
failureUrl,
|
|
931
995
|
retries,
|
|
932
|
-
telemetry
|
|
996
|
+
telemetry: telemetry2
|
|
933
997
|
});
|
|
934
998
|
const callResponse = {
|
|
935
999
|
status: callbackMessage.status,
|
|
@@ -968,11 +1032,11 @@ ${atob(callbackMessage.body ?? "")}`
|
|
|
968
1032
|
);
|
|
969
1033
|
}
|
|
970
1034
|
};
|
|
971
|
-
var getTelemetryHeaders = (
|
|
1035
|
+
var getTelemetryHeaders = (telemetry2) => {
|
|
972
1036
|
return {
|
|
973
|
-
[TELEMETRY_HEADER_SDK]:
|
|
974
|
-
[TELEMETRY_HEADER_FRAMEWORK]:
|
|
975
|
-
[TELEMETRY_HEADER_RUNTIME]:
|
|
1037
|
+
[TELEMETRY_HEADER_SDK]: telemetry2.sdk,
|
|
1038
|
+
[TELEMETRY_HEADER_FRAMEWORK]: telemetry2.framework,
|
|
1039
|
+
[TELEMETRY_HEADER_RUNTIME]: telemetry2.runtime ?? "unknown"
|
|
976
1040
|
};
|
|
977
1041
|
};
|
|
978
1042
|
var getHeaders = ({
|
|
@@ -985,14 +1049,17 @@ var getHeaders = ({
|
|
|
985
1049
|
step,
|
|
986
1050
|
callRetries,
|
|
987
1051
|
callTimeout,
|
|
988
|
-
telemetry
|
|
1052
|
+
telemetry: telemetry2
|
|
989
1053
|
}) => {
|
|
1054
|
+
const contentType = (userHeaders ? userHeaders.get("Content-Type") : void 0) ?? DEFAULT_CONTENT_TYPE;
|
|
990
1055
|
const baseHeaders = {
|
|
991
1056
|
[WORKFLOW_INIT_HEADER]: initHeaderValue,
|
|
992
1057
|
[WORKFLOW_ID_HEADER]: workflowRunId,
|
|
993
1058
|
[WORKFLOW_URL_HEADER]: workflowUrl,
|
|
994
1059
|
[WORKFLOW_FEATURE_HEADER]: "LazyFetch,InitialBody",
|
|
995
|
-
|
|
1060
|
+
[WORKFLOW_PROTOCOL_VERSION_HEADER]: WORKFLOW_PROTOCOL_VERSION,
|
|
1061
|
+
"content-type": contentType,
|
|
1062
|
+
...telemetry2 ? getTelemetryHeaders(telemetry2) : {}
|
|
996
1063
|
};
|
|
997
1064
|
if (!step?.callUrl) {
|
|
998
1065
|
baseHeaders[`Upstash-Forward-${WORKFLOW_PROTOCOL_VERSION_HEADER}`] = WORKFLOW_PROTOCOL_VERSION;
|
|
@@ -1006,6 +1073,9 @@ var getHeaders = ({
|
|
|
1006
1073
|
baseHeaders["Upstash-Failure-Callback"] = failureUrl;
|
|
1007
1074
|
}
|
|
1008
1075
|
}
|
|
1076
|
+
if (step?.stepType === "Invoke") {
|
|
1077
|
+
baseHeaders["upstash-workflow-invoke"] = "true";
|
|
1078
|
+
}
|
|
1009
1079
|
if (step?.callUrl) {
|
|
1010
1080
|
baseHeaders["Upstash-Retries"] = callRetries?.toString() ?? "0";
|
|
1011
1081
|
baseHeaders[WORKFLOW_FEATURE_HEADER] = "WF_NoDelete,InitialBody";
|
|
@@ -1027,7 +1097,6 @@ var getHeaders = ({
|
|
|
1027
1097
|
baseHeaders[`Upstash-Failure-Callback-Forward-${header}`] = userHeaders.get(header);
|
|
1028
1098
|
}
|
|
1029
1099
|
}
|
|
1030
|
-
const contentType = (userHeaders ? userHeaders.get("Content-Type") : void 0) ?? DEFAULT_CONTENT_TYPE;
|
|
1031
1100
|
if (step?.callHeaders) {
|
|
1032
1101
|
const forwardedHeaders = Object.fromEntries(
|
|
1033
1102
|
Object.entries(step.callHeaders).map(([header, value]) => [
|
|
@@ -1067,8 +1136,8 @@ var getHeaders = ({
|
|
|
1067
1136
|
Object.entries(baseHeaders).map(([header, value]) => [header, [value]])
|
|
1068
1137
|
),
|
|
1069
1138
|
// to include telemetry headers:
|
|
1070
|
-
...
|
|
1071
|
-
Object.entries(getTelemetryHeaders(
|
|
1139
|
+
...telemetry2 ? Object.fromEntries(
|
|
1140
|
+
Object.entries(getTelemetryHeaders(telemetry2)).map(([header, value]) => [
|
|
1072
1141
|
header,
|
|
1073
1142
|
[value]
|
|
1074
1143
|
])
|
|
@@ -1077,8 +1146,7 @@ var getHeaders = ({
|
|
|
1077
1146
|
"Upstash-Workflow-Runid": [workflowRunId],
|
|
1078
1147
|
[WORKFLOW_INIT_HEADER]: ["false"],
|
|
1079
1148
|
[WORKFLOW_URL_HEADER]: [workflowUrl],
|
|
1080
|
-
"Upstash-Workflow-CallType": ["step"]
|
|
1081
|
-
"Content-Type": [contentType]
|
|
1149
|
+
"Upstash-Workflow-CallType": ["step"]
|
|
1082
1150
|
}
|
|
1083
1151
|
};
|
|
1084
1152
|
}
|
|
@@ -1124,10 +1192,10 @@ var AutoExecutor = class _AutoExecutor {
|
|
|
1124
1192
|
stepCount = 0;
|
|
1125
1193
|
planStepCount = 0;
|
|
1126
1194
|
executingStep = false;
|
|
1127
|
-
constructor(context, steps,
|
|
1195
|
+
constructor(context, steps, telemetry2, debug) {
|
|
1128
1196
|
this.context = context;
|
|
1129
1197
|
this.steps = steps;
|
|
1130
|
-
this.telemetry =
|
|
1198
|
+
this.telemetry = telemetry2;
|
|
1131
1199
|
this.debug = debug;
|
|
1132
1200
|
this.nonPlanStepCount = this.steps.filter((step) => !step.targetStep).length;
|
|
1133
1201
|
}
|
|
@@ -1373,7 +1441,23 @@ var AutoExecutor = class _AutoExecutor {
|
|
|
1373
1441
|
method: "POST",
|
|
1374
1442
|
parseResponseAsJson: false
|
|
1375
1443
|
});
|
|
1376
|
-
throw new WorkflowAbort(
|
|
1444
|
+
throw new WorkflowAbort(waitStep.stepName, waitStep);
|
|
1445
|
+
}
|
|
1446
|
+
if (steps.length === 1 && lazySteps[0] instanceof LazyInvokeStep) {
|
|
1447
|
+
const invokeStep = steps[0];
|
|
1448
|
+
const lazyInvokeStep = lazySteps[0];
|
|
1449
|
+
await lazyInvokeStep.params.workflow.callback(
|
|
1450
|
+
{
|
|
1451
|
+
body: lazyInvokeStep.params.body,
|
|
1452
|
+
headers: lazyInvokeStep.params.headers,
|
|
1453
|
+
workflowRunId: lazyInvokeStep.params.workflowRunId,
|
|
1454
|
+
workflow: lazyInvokeStep.params.workflow,
|
|
1455
|
+
retries: lazyInvokeStep.params.retries
|
|
1456
|
+
},
|
|
1457
|
+
invokeStep,
|
|
1458
|
+
this.context
|
|
1459
|
+
);
|
|
1460
|
+
throw new WorkflowAbort(invokeStep.stepName, invokeStep);
|
|
1377
1461
|
}
|
|
1378
1462
|
const result = await this.context.qstashClient.batchJSON(
|
|
1379
1463
|
steps.map((singleStep, index) => {
|
|
@@ -2059,7 +2143,7 @@ var WorkflowContext = class {
|
|
|
2059
2143
|
initialPayload,
|
|
2060
2144
|
env,
|
|
2061
2145
|
retries,
|
|
2062
|
-
telemetry
|
|
2146
|
+
telemetry: telemetry2
|
|
2063
2147
|
}) {
|
|
2064
2148
|
this.qstashClient = qstashClient;
|
|
2065
2149
|
this.workflowRunId = workflowRunId;
|
|
@@ -2070,7 +2154,7 @@ var WorkflowContext = class {
|
|
|
2070
2154
|
this.requestPayload = initialPayload;
|
|
2071
2155
|
this.env = env ?? {};
|
|
2072
2156
|
this.retries = retries ?? DEFAULT_RETRIES;
|
|
2073
|
-
this.executor = new AutoExecutor(this, this.steps,
|
|
2157
|
+
this.executor = new AutoExecutor(this, this.steps, telemetry2, debug);
|
|
2074
2158
|
}
|
|
2075
2159
|
/**
|
|
2076
2160
|
* Executes a workflow step
|
|
@@ -2290,6 +2374,13 @@ var WorkflowContext = class {
|
|
|
2290
2374
|
return result;
|
|
2291
2375
|
}
|
|
2292
2376
|
}
|
|
2377
|
+
async invoke(stepName, settings) {
|
|
2378
|
+
const result = await this.addStep(new LazyInvokeStep(stepName, settings));
|
|
2379
|
+
return {
|
|
2380
|
+
...result,
|
|
2381
|
+
body: result.body ? JSON.parse(result.body) : void 0
|
|
2382
|
+
};
|
|
2383
|
+
}
|
|
2293
2384
|
/**
|
|
2294
2385
|
* Cancel the current workflow run
|
|
2295
2386
|
*
|
|
@@ -2367,31 +2458,6 @@ var WorkflowLogger = class _WorkflowLogger {
|
|
|
2367
2458
|
}
|
|
2368
2459
|
};
|
|
2369
2460
|
|
|
2370
|
-
// src/utils.ts
|
|
2371
|
-
var NANOID_CHARS = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-_";
|
|
2372
|
-
var NANOID_LENGTH = 21;
|
|
2373
|
-
function getRandomInt() {
|
|
2374
|
-
return Math.floor(Math.random() * NANOID_CHARS.length);
|
|
2375
|
-
}
|
|
2376
|
-
function nanoid() {
|
|
2377
|
-
return Array.from({ length: NANOID_LENGTH }).map(() => NANOID_CHARS[getRandomInt()]).join("");
|
|
2378
|
-
}
|
|
2379
|
-
function getWorkflowRunId(id) {
|
|
2380
|
-
return `wfr_${id ?? nanoid()}`;
|
|
2381
|
-
}
|
|
2382
|
-
function decodeBase64(base64) {
|
|
2383
|
-
try {
|
|
2384
|
-
const binString = atob(base64);
|
|
2385
|
-
const intArray = Uint8Array.from(binString, (m) => m.codePointAt(0));
|
|
2386
|
-
return new TextDecoder().decode(intArray);
|
|
2387
|
-
} catch (error) {
|
|
2388
|
-
console.warn(
|
|
2389
|
-
`Upstash Qstash: Failed while decoding base64 "${base64}". Decoding with atob and returning it instead. ${error}`
|
|
2390
|
-
);
|
|
2391
|
-
return atob(base64);
|
|
2392
|
-
}
|
|
2393
|
-
}
|
|
2394
|
-
|
|
2395
2461
|
// src/serve/authorization.ts
|
|
2396
2462
|
var import_qstash8 = require("@upstash/qstash");
|
|
2397
2463
|
var DisabledWorkflowContext = class _DisabledWorkflowContext extends WorkflowContext {
|
|
@@ -2729,7 +2795,7 @@ var determineUrls = async (request, url, baseUrl, failureFunction, failureUrl, d
|
|
|
2729
2795
|
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`;
|
|
2730
2796
|
|
|
2731
2797
|
// src/serve/index.ts
|
|
2732
|
-
var serveBase = (routeFunction,
|
|
2798
|
+
var serveBase = (routeFunction, telemetry2, options) => {
|
|
2733
2799
|
const {
|
|
2734
2800
|
qstashClient,
|
|
2735
2801
|
onStepFinish,
|
|
@@ -2745,7 +2811,7 @@ var serveBase = (routeFunction, telemetry, options) => {
|
|
|
2745
2811
|
useJSONContent,
|
|
2746
2812
|
disableTelemetry
|
|
2747
2813
|
} = processOptions(options);
|
|
2748
|
-
|
|
2814
|
+
telemetry2 = disableTelemetry ? void 0 : telemetry2;
|
|
2749
2815
|
const debug = WorkflowLogger.getLogger(verbose);
|
|
2750
2816
|
const handler = async (request) => {
|
|
2751
2817
|
await debug?.log("INFO", "ENDPOINT_START");
|
|
@@ -2803,7 +2869,7 @@ var serveBase = (routeFunction, telemetry, options) => {
|
|
|
2803
2869
|
debug,
|
|
2804
2870
|
env,
|
|
2805
2871
|
retries,
|
|
2806
|
-
telemetry
|
|
2872
|
+
telemetry: telemetry2
|
|
2807
2873
|
});
|
|
2808
2874
|
const authCheck = await DisabledWorkflowContext.tryAuthentication(
|
|
2809
2875
|
routeFunction,
|
|
@@ -2826,7 +2892,7 @@ var serveBase = (routeFunction, telemetry, options) => {
|
|
|
2826
2892
|
workflowUrl,
|
|
2827
2893
|
failureUrl: workflowFailureUrl,
|
|
2828
2894
|
retries,
|
|
2829
|
-
telemetry,
|
|
2895
|
+
telemetry: telemetry2,
|
|
2830
2896
|
debug
|
|
2831
2897
|
});
|
|
2832
2898
|
if (callReturnCheck.isErr()) {
|
|
@@ -2835,10 +2901,10 @@ var serveBase = (routeFunction, telemetry, options) => {
|
|
|
2835
2901
|
});
|
|
2836
2902
|
throw callReturnCheck.error;
|
|
2837
2903
|
} else if (callReturnCheck.value === "continue-workflow") {
|
|
2838
|
-
const result = isFirstInvocation ? await triggerFirstInvocation({ workflowContext, useJSONContent, telemetry, debug }) : await triggerRouteFunction({
|
|
2904
|
+
const result = isFirstInvocation ? await triggerFirstInvocation({ workflowContext, useJSONContent, telemetry: telemetry2, debug }) : await triggerRouteFunction({
|
|
2839
2905
|
onStep: async () => routeFunction(workflowContext),
|
|
2840
|
-
onCleanup: async () => {
|
|
2841
|
-
await triggerWorkflowDelete(workflowContext, debug);
|
|
2906
|
+
onCleanup: async (result2) => {
|
|
2907
|
+
await triggerWorkflowDelete(workflowContext, result2, debug);
|
|
2842
2908
|
},
|
|
2843
2909
|
onCancel: async () => {
|
|
2844
2910
|
await makeCancelRequest(workflowContext.qstashClient.http, workflowRunId);
|
|
@@ -2870,29 +2936,130 @@ var serveBase = (routeFunction, telemetry, options) => {
|
|
|
2870
2936
|
return { handler: safeHandler };
|
|
2871
2937
|
};
|
|
2872
2938
|
|
|
2939
|
+
// src/serve/serve-many.ts
|
|
2940
|
+
var serveManyBase = ({
|
|
2941
|
+
workflows,
|
|
2942
|
+
getWorkflowId
|
|
2943
|
+
}) => {
|
|
2944
|
+
const workflowIds = [];
|
|
2945
|
+
const workflowMap = Object.fromEntries(
|
|
2946
|
+
Object.entries(workflows).map((workflow) => {
|
|
2947
|
+
const workflowId = workflow[0];
|
|
2948
|
+
if (workflowIds.includes(workflowId)) {
|
|
2949
|
+
throw new WorkflowError(
|
|
2950
|
+
`Duplicate workflow name found: '${workflowId}'. Please set different workflow names in serveMany.`
|
|
2951
|
+
);
|
|
2952
|
+
}
|
|
2953
|
+
if (workflowId.includes("/")) {
|
|
2954
|
+
throw new WorkflowError(
|
|
2955
|
+
`Invalid workflow name found: '${workflowId}'. Workflow name cannot contain '/'.`
|
|
2956
|
+
);
|
|
2957
|
+
}
|
|
2958
|
+
workflowIds.push(workflowId);
|
|
2959
|
+
workflow[1].workflowId = workflowId;
|
|
2960
|
+
return [workflowId, workflow[1].handler];
|
|
2961
|
+
})
|
|
2962
|
+
);
|
|
2963
|
+
return {
|
|
2964
|
+
handler: async (...params) => {
|
|
2965
|
+
const pickedWorkflowId = getWorkflowId(...params);
|
|
2966
|
+
if (!pickedWorkflowId) {
|
|
2967
|
+
throw new WorkflowError(`Unexpected request in serveMany. workflowId not set. Please update the URL of your request.`);
|
|
2968
|
+
}
|
|
2969
|
+
const workflow = workflowMap[pickedWorkflowId];
|
|
2970
|
+
if (!workflow) {
|
|
2971
|
+
throw new WorkflowError(`No workflows in serveMany found for '${pickedWorkflowId}'. Please update the URL of your request.`);
|
|
2972
|
+
}
|
|
2973
|
+
return await workflow(...params);
|
|
2974
|
+
}
|
|
2975
|
+
};
|
|
2976
|
+
};
|
|
2977
|
+
var createInvokeCallback = (telemetry2) => {
|
|
2978
|
+
const invokeCallback = async (settings, invokeStep, context) => {
|
|
2979
|
+
const { body, workflow, headers = {}, workflowRunId = getWorkflowRunId(), retries } = settings;
|
|
2980
|
+
const { workflowId } = workflow;
|
|
2981
|
+
if (!workflowId) {
|
|
2982
|
+
throw new WorkflowError("You can only invoke workflow which has a workflowId");
|
|
2983
|
+
}
|
|
2984
|
+
const { headers: invokerHeaders } = getHeaders({
|
|
2985
|
+
initHeaderValue: "false",
|
|
2986
|
+
workflowRunId: context.workflowRunId,
|
|
2987
|
+
workflowUrl: context.url,
|
|
2988
|
+
userHeaders: context.headers,
|
|
2989
|
+
failureUrl: context.failureUrl,
|
|
2990
|
+
retries: context.retries,
|
|
2991
|
+
telemetry: telemetry2
|
|
2992
|
+
});
|
|
2993
|
+
invokerHeaders["Upstash-Workflow-Runid"] = context.workflowRunId;
|
|
2994
|
+
const newUrl = context.url.replace(/[^/]+$/, workflowId);
|
|
2995
|
+
const { headers: triggerHeaders } = getHeaders({
|
|
2996
|
+
initHeaderValue: "true",
|
|
2997
|
+
workflowRunId,
|
|
2998
|
+
workflowUrl: newUrl,
|
|
2999
|
+
userHeaders: new Headers(headers),
|
|
3000
|
+
retries,
|
|
3001
|
+
telemetry: telemetry2
|
|
3002
|
+
});
|
|
3003
|
+
triggerHeaders["Upstash-Workflow-Invoke"] = "true";
|
|
3004
|
+
const request = {
|
|
3005
|
+
body: JSON.stringify(body),
|
|
3006
|
+
headers: Object.fromEntries(
|
|
3007
|
+
Object.entries(invokerHeaders).map((pairs) => [pairs[0], [pairs[1]]])
|
|
3008
|
+
),
|
|
3009
|
+
workflowRunId,
|
|
3010
|
+
workflowUrl: context.url,
|
|
3011
|
+
step: invokeStep
|
|
3012
|
+
};
|
|
3013
|
+
await context.qstashClient.publish({
|
|
3014
|
+
headers: triggerHeaders,
|
|
3015
|
+
method: "POST",
|
|
3016
|
+
body: JSON.stringify(request),
|
|
3017
|
+
url: newUrl
|
|
3018
|
+
});
|
|
3019
|
+
return void 0;
|
|
3020
|
+
};
|
|
3021
|
+
return invokeCallback;
|
|
3022
|
+
};
|
|
3023
|
+
|
|
2873
3024
|
// platforms/hono.ts
|
|
3025
|
+
var telemetry = {
|
|
3026
|
+
sdk: SDK_TELEMETRY,
|
|
3027
|
+
framework: "hono"
|
|
3028
|
+
};
|
|
2874
3029
|
var serve = (routeFunction, options) => {
|
|
2875
3030
|
const handler = async (context) => {
|
|
2876
3031
|
const environment = context.env;
|
|
2877
3032
|
const request = context.req.raw;
|
|
2878
|
-
const { handler: serveHandler } = serveBase(
|
|
2879
|
-
|
|
2880
|
-
|
|
2881
|
-
|
|
2882
|
-
|
|
2883
|
-
|
|
2884
|
-
{
|
|
2885
|
-
// when hono is used without cf workers, it sends a DebugHTTPServer
|
|
2886
|
-
// object in `context.env`. don't pass env if this is the case:
|
|
2887
|
-
env: "QSTASH_TOKEN" in environment ? environment : void 0,
|
|
2888
|
-
...options
|
|
2889
|
-
}
|
|
2890
|
-
);
|
|
3033
|
+
const { handler: serveHandler } = serveBase(routeFunction, telemetry, {
|
|
3034
|
+
// when hono is used without cf workers, it sends a DebugHTTPServer
|
|
3035
|
+
// object in `context.env`. don't pass env if this is the case:
|
|
3036
|
+
env: "QSTASH_TOKEN" in environment ? environment : void 0,
|
|
3037
|
+
...options
|
|
3038
|
+
});
|
|
2891
3039
|
return await serveHandler(request);
|
|
2892
3040
|
};
|
|
2893
3041
|
return handler;
|
|
2894
3042
|
};
|
|
3043
|
+
var createWorkflow = (...params) => {
|
|
3044
|
+
const handler = serve(...params);
|
|
3045
|
+
return {
|
|
3046
|
+
callback: createInvokeCallback(telemetry),
|
|
3047
|
+
handler,
|
|
3048
|
+
workflowId: void 0
|
|
3049
|
+
};
|
|
3050
|
+
};
|
|
3051
|
+
var serveMany = (workflows) => {
|
|
3052
|
+
return serveManyBase({
|
|
3053
|
+
workflows,
|
|
3054
|
+
getWorkflowId(params) {
|
|
3055
|
+
const components = params.req.url.split("/");
|
|
3056
|
+
return components[components.length - 1];
|
|
3057
|
+
}
|
|
3058
|
+
}).handler;
|
|
3059
|
+
};
|
|
2895
3060
|
// Annotate the CommonJS export names for ESM import in node:
|
|
2896
3061
|
0 && (module.exports = {
|
|
2897
|
-
|
|
3062
|
+
createWorkflow,
|
|
3063
|
+
serve,
|
|
3064
|
+
serveMany
|
|
2898
3065
|
});
|
package/hono.mjs
CHANGED
|
@@ -1,30 +1,50 @@
|
|
|
1
|
+
import {
|
|
2
|
+
createInvokeCallback,
|
|
3
|
+
serveManyBase
|
|
4
|
+
} from "./chunk-LCZMBGEM.mjs";
|
|
1
5
|
import {
|
|
2
6
|
SDK_TELEMETRY,
|
|
3
7
|
serveBase
|
|
4
|
-
} from "./chunk-
|
|
8
|
+
} from "./chunk-IWAW7GIG.mjs";
|
|
5
9
|
|
|
6
10
|
// platforms/hono.ts
|
|
11
|
+
var telemetry = {
|
|
12
|
+
sdk: SDK_TELEMETRY,
|
|
13
|
+
framework: "hono"
|
|
14
|
+
};
|
|
7
15
|
var serve = (routeFunction, options) => {
|
|
8
16
|
const handler = async (context) => {
|
|
9
17
|
const environment = context.env;
|
|
10
18
|
const request = context.req.raw;
|
|
11
|
-
const { handler: serveHandler } = serveBase(
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
{
|
|
18
|
-
// when hono is used without cf workers, it sends a DebugHTTPServer
|
|
19
|
-
// object in `context.env`. don't pass env if this is the case:
|
|
20
|
-
env: "QSTASH_TOKEN" in environment ? environment : void 0,
|
|
21
|
-
...options
|
|
22
|
-
}
|
|
23
|
-
);
|
|
19
|
+
const { handler: serveHandler } = serveBase(routeFunction, telemetry, {
|
|
20
|
+
// when hono is used without cf workers, it sends a DebugHTTPServer
|
|
21
|
+
// object in `context.env`. don't pass env if this is the case:
|
|
22
|
+
env: "QSTASH_TOKEN" in environment ? environment : void 0,
|
|
23
|
+
...options
|
|
24
|
+
});
|
|
24
25
|
return await serveHandler(request);
|
|
25
26
|
};
|
|
26
27
|
return handler;
|
|
27
28
|
};
|
|
29
|
+
var createWorkflow = (...params) => {
|
|
30
|
+
const handler = serve(...params);
|
|
31
|
+
return {
|
|
32
|
+
callback: createInvokeCallback(telemetry),
|
|
33
|
+
handler,
|
|
34
|
+
workflowId: void 0
|
|
35
|
+
};
|
|
36
|
+
};
|
|
37
|
+
var serveMany = (workflows) => {
|
|
38
|
+
return serveManyBase({
|
|
39
|
+
workflows,
|
|
40
|
+
getWorkflowId(params) {
|
|
41
|
+
const components = params.req.url.split("/");
|
|
42
|
+
return components[components.length - 1];
|
|
43
|
+
}
|
|
44
|
+
}).handler;
|
|
45
|
+
};
|
|
28
46
|
export {
|
|
29
|
-
|
|
47
|
+
createWorkflow,
|
|
48
|
+
serve,
|
|
49
|
+
serveMany
|
|
30
50
|
};
|
package/index.d.mts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { R as RouteFunction, W as WorkflowServeOptions, E as ExclusiveValidationOptions, N as NotifyResponse, a as Waiter, S as Step } from './types-
|
|
2
|
-
export { A as AsyncStepFunction, C as CallResponse, q as CallSettings, D as Duration, k as FailureFunctionPayload, F as FinishCondition, H as HeaderParams, L as LogLevel, o as NotifyStepResponse, P as ParallelCallState, j as PublicServeOptions, g as RawStep, l as RequiredExceptFields, i as StepFunction, f as StepType, e as StepTypes, h as SyncStepFunction,
|
|
1
|
+
import { R as RouteFunction, W as WorkflowServeOptions, E as ExclusiveValidationOptions, T as Telemetry, N as NotifyResponse, a as Waiter, S as Step } from './types-C7Y7WUQd.mjs';
|
|
2
|
+
export { A as AsyncStepFunction, C as CallResponse, q as CallSettings, D as Duration, k as FailureFunctionPayload, F as FinishCondition, H as HeaderParams, t as InvokableWorkflow, s as InvokeCallback, r as InvokeStepResponse, I as InvokeWorkflowRequest, L as LogLevel, o as NotifyStepResponse, P as ParallelCallState, j as PublicServeOptions, g as RawStep, l as RequiredExceptFields, i as StepFunction, f as StepType, e as StepTypes, h as SyncStepFunction, p as WaitEventOptions, m as WaitRequest, n as WaitStepResponse, c as WorkflowClient, b as WorkflowContext, v as WorkflowLogger, u as WorkflowLoggerOptions, d as WorkflowReceiver } from './types-C7Y7WUQd.mjs';
|
|
3
3
|
import { Client as Client$1, QstashError } from '@upstash/qstash';
|
|
4
4
|
import 'zod';
|
|
5
5
|
import 'ai';
|
|
@@ -9,13 +9,26 @@ import '@ai-sdk/openai';
|
|
|
9
9
|
* Creates an async method that handles incoming requests and runs the provided
|
|
10
10
|
* route function as a workflow.
|
|
11
11
|
*
|
|
12
|
+
* Not exported in the package. Instead, used in framework specific serve implementations.
|
|
13
|
+
*
|
|
14
|
+
* Only difference from regular serve is the `useJSONContent` parameter.
|
|
15
|
+
*
|
|
12
16
|
* @param routeFunction - A function that uses WorkflowContext as a parameter and runs a workflow.
|
|
13
17
|
* @param options - Options including the client, onFinish callback, and initialPayloadParser.
|
|
14
18
|
* @returns An async method that consumes incoming requests and runs the workflow.
|
|
15
19
|
*/
|
|
16
|
-
declare const
|
|
20
|
+
declare const serveBase: <TInitialPayload = unknown, TRequest extends Request = Request, TResponse extends Response = Response, TResult = unknown>(routeFunction: RouteFunction<TInitialPayload, TResult>, telemetry?: Telemetry, options?: WorkflowServeOptions<TResponse, TInitialPayload>) => {
|
|
17
21
|
handler: (request: TRequest) => Promise<TResponse>;
|
|
18
22
|
};
|
|
23
|
+
/**
|
|
24
|
+
* Creates an async method that handles incoming requests and runs the provided
|
|
25
|
+
* route function as a workflow.
|
|
26
|
+
*
|
|
27
|
+
* @param routeFunction - A function that uses WorkflowContext as a parameter and runs a workflow.
|
|
28
|
+
* @param options - Options including the client, onFinish callback, and initialPayloadParser.
|
|
29
|
+
* @returns An async method that consumes incoming requests and runs the workflow.
|
|
30
|
+
*/
|
|
31
|
+
declare const serve: <TInitialPayload = unknown, TRequest extends Request = Request, TResponse extends Response = Response, TResult = unknown>(routeFunction: RouteFunction<TInitialPayload, TResult>, options?: Omit<WorkflowServeOptions<TResponse, TInitialPayload>, "useJSONContent" | "schema" | "initialPayloadParser"> & ExclusiveValidationOptions<TInitialPayload>) => ReturnType<typeof serveBase<TInitialPayload, TRequest, TResponse, TResult>>;
|
|
19
32
|
|
|
20
33
|
type ClientConfig = ConstructorParameters<typeof Client$1>[0];
|
|
21
34
|
/**
|
|
@@ -192,4 +205,4 @@ declare class WorkflowAbort extends Error {
|
|
|
192
205
|
constructor(stepName: string, stepInfo?: Step, cancelWorkflow?: boolean);
|
|
193
206
|
}
|
|
194
207
|
|
|
195
|
-
export { Client, ExclusiveValidationOptions, NotifyResponse, RouteFunction, Step, Waiter, WorkflowAbort, WorkflowError, WorkflowServeOptions, serve };
|
|
208
|
+
export { Client, ExclusiveValidationOptions, NotifyResponse, RouteFunction, Step, Telemetry, Waiter, WorkflowAbort, WorkflowError, WorkflowServeOptions, serve };
|