@upstash/workflow 0.2.8-rc-invoke → 0.2.9
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 +4 -4
- package/astro.d.ts +4 -4
- package/astro.js +282 -135
- package/astro.mjs +17 -15
- package/{chunk-IWAW7GIG.mjs → chunk-IPXJZU3K.mjs} +851 -592
- package/cloudflare.d.mts +4 -4
- package/cloudflare.d.ts +4 -4
- package/cloudflare.js +278 -135
- package/cloudflare.mjs +13 -15
- package/express.d.mts +4 -4
- package/express.d.ts +4 -4
- package/express.js +281 -144
- package/express.mjs +16 -22
- package/h3.d.mts +4 -4
- package/h3.d.ts +4 -4
- package/h3.js +275 -135
- package/h3.mjs +10 -15
- package/hono.d.mts +4 -4
- package/hono.d.ts +4 -4
- package/hono.js +277 -134
- package/hono.mjs +12 -14
- package/index.d.mts +268 -5
- package/index.d.ts +268 -5
- package/index.js +297 -43
- package/index.mjs +60 -3
- package/nextjs.d.mts +6 -6
- package/nextjs.d.ts +6 -6
- package/nextjs.js +286 -143
- package/nextjs.mjs +21 -23
- package/package.json +1 -1
- package/serve-many-BVDpPsF-.d.mts +13 -0
- package/serve-many-e4zufyXN.d.ts +13 -0
- package/solidjs.d.mts +1 -1
- package/solidjs.d.ts +1 -1
- package/solidjs.js +207 -41
- package/solidjs.mjs +1 -1
- package/svelte.d.mts +8 -9
- package/svelte.d.ts +8 -9
- package/svelte.js +278 -135
- package/svelte.mjs +13 -15
- package/{types-C7Y7WUQd.d.mts → types-CYhDXnf8.d.mts} +110 -18
- package/{types-C7Y7WUQd.d.ts → types-CYhDXnf8.d.ts} +110 -18
- package/chunk-LCZMBGEM.mjs +0 -95
- package/serve-many-BlBvXfBS.d.mts +0 -10
- package/serve-many-Dw-UUnH6.d.ts +0 -10
package/nextjs.mjs
CHANGED
|
@@ -1,11 +1,8 @@
|
|
|
1
|
-
import {
|
|
2
|
-
createInvokeCallback,
|
|
3
|
-
serveManyBase
|
|
4
|
-
} from "./chunk-LCZMBGEM.mjs";
|
|
5
1
|
import {
|
|
6
2
|
SDK_TELEMETRY,
|
|
7
|
-
serveBase
|
|
8
|
-
|
|
3
|
+
serveBase,
|
|
4
|
+
serveManyBase
|
|
5
|
+
} from "./chunk-IPXJZU3K.mjs";
|
|
9
6
|
|
|
10
7
|
// platforms/nextjs.ts
|
|
11
8
|
var appTelemetry = {
|
|
@@ -31,21 +28,22 @@ var serve = (routeFunction, options) => {
|
|
|
31
28
|
};
|
|
32
29
|
};
|
|
33
30
|
var createWorkflow = (...params) => {
|
|
34
|
-
const
|
|
31
|
+
const [routeFunction, options = {}] = params;
|
|
35
32
|
return {
|
|
36
|
-
|
|
37
|
-
|
|
33
|
+
routeFunction,
|
|
34
|
+
options,
|
|
38
35
|
workflowId: void 0
|
|
39
36
|
};
|
|
40
37
|
};
|
|
41
|
-
var serveMany = (workflows) => {
|
|
38
|
+
var serveMany = (workflows, options) => {
|
|
42
39
|
return {
|
|
43
40
|
POST: serveManyBase({
|
|
44
41
|
workflows,
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
42
|
+
getUrl(params) {
|
|
43
|
+
return params.url;
|
|
44
|
+
},
|
|
45
|
+
serveMethod: (...params) => serve(...params).POST,
|
|
46
|
+
options
|
|
49
47
|
}).handler
|
|
50
48
|
};
|
|
51
49
|
};
|
|
@@ -74,24 +72,24 @@ var servePagesRouter = (routeFunction, options) => {
|
|
|
74
72
|
};
|
|
75
73
|
};
|
|
76
74
|
var createWorkflowPagesRouter = (...params) => {
|
|
77
|
-
const
|
|
75
|
+
const [routeFunction, options = {}] = params;
|
|
78
76
|
return {
|
|
79
|
-
|
|
80
|
-
|
|
77
|
+
routeFunction,
|
|
78
|
+
options,
|
|
81
79
|
workflowId: void 0
|
|
82
80
|
};
|
|
83
81
|
};
|
|
84
|
-
var serveManyPagesRouter = (workflows) => {
|
|
82
|
+
var serveManyPagesRouter = (workflows, options) => {
|
|
85
83
|
return serveManyBase({
|
|
86
84
|
workflows,
|
|
87
|
-
|
|
85
|
+
getUrl(request_) {
|
|
88
86
|
const protocol = request_.headers["x-forwarded-proto"];
|
|
89
87
|
const host = request_.headers.host;
|
|
90
88
|
const baseUrl = `${protocol}://${host}`;
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
89
|
+
return `${baseUrl}${request_.url}`;
|
|
90
|
+
},
|
|
91
|
+
serveMethod: (...params) => servePagesRouter(...params).handler,
|
|
92
|
+
options
|
|
95
93
|
});
|
|
96
94
|
};
|
|
97
95
|
export {
|
package/package.json
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"name":"@upstash/workflow","version":"v0.2.
|
|
1
|
+
{"name":"@upstash/workflow","version":"v0.2.9","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":{"@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.0","astro":"^4.16.7","eslint":"^9.11.1","eslint-plugin-unicorn":"^55.0.0","express":"^4.21.1","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.0.15","@upstash/qstash":"^2.7.22","ai":"^4.0.30","zod":"^3.24.1"},"directories":{"example":"examples"}}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { k as PublicServeOptions, R as RouteFunction, t as InvokableWorkflow } from './types-CYhDXnf8.mjs';
|
|
2
|
+
|
|
3
|
+
type OmitOptionsInServeMany<TOptions> = Omit<TOptions, "env" | "url" | "schema" | "initialPayloadParser">;
|
|
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, }: {
|
|
5
|
+
workflows: Record<string, InvokableWorkflow<any, any>>;
|
|
6
|
+
getUrl: (...params: Parameters<THandler>) => string;
|
|
7
|
+
serveMethod: (...params: TServeParams) => THandler;
|
|
8
|
+
options?: TOptions;
|
|
9
|
+
}) => {
|
|
10
|
+
handler: (...params: Parameters<THandler>) => Promise<any>;
|
|
11
|
+
};
|
|
12
|
+
|
|
13
|
+
export { serveManyBase as s };
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { k as PublicServeOptions, R as RouteFunction, t as InvokableWorkflow } from './types-CYhDXnf8.js';
|
|
2
|
+
|
|
3
|
+
type OmitOptionsInServeMany<TOptions> = Omit<TOptions, "env" | "url" | "schema" | "initialPayloadParser">;
|
|
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, }: {
|
|
5
|
+
workflows: Record<string, InvokableWorkflow<any, any>>;
|
|
6
|
+
getUrl: (...params: Parameters<THandler>) => string;
|
|
7
|
+
serveMethod: (...params: TServeParams) => THandler;
|
|
8
|
+
options?: TOptions;
|
|
9
|
+
}) => {
|
|
10
|
+
handler: (...params: Parameters<THandler>) => Promise<any>;
|
|
11
|
+
};
|
|
12
|
+
|
|
13
|
+
export { serveManyBase as s };
|
package/solidjs.d.mts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { APIEvent } from '@solidjs/start/server';
|
|
2
|
-
import { R as RouteFunction,
|
|
2
|
+
import { R as RouteFunction, k as PublicServeOptions } from './types-CYhDXnf8.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,
|
|
2
|
+
import { R as RouteFunction, k as PublicServeOptions } from './types-CYhDXnf8.js';
|
|
3
3
|
import '@upstash/qstash';
|
|
4
4
|
import 'zod';
|
|
5
5
|
import 'ai';
|
package/solidjs.js
CHANGED
|
@@ -83,6 +83,7 @@ var WORKFLOW_INIT_HEADER = "Upstash-Workflow-Init";
|
|
|
83
83
|
var WORKFLOW_URL_HEADER = "Upstash-Workflow-Url";
|
|
84
84
|
var WORKFLOW_FAILURE_HEADER = "Upstash-Workflow-Is-Failure";
|
|
85
85
|
var WORKFLOW_FEATURE_HEADER = "Upstash-Feature-Set";
|
|
86
|
+
var WORKFLOW_INVOKE_COUNT_HEADER = "Upstash-Workflow-Invoke-Count";
|
|
86
87
|
var WORKFLOW_PROTOCOL_VERSION = "1";
|
|
87
88
|
var WORKFLOW_PROTOCOL_VERSION_HEADER = "Upstash-Workflow-Sdk-Version";
|
|
88
89
|
var DEFAULT_CONTENT_TYPE = "application/json";
|
|
@@ -264,8 +265,9 @@ var LazyCallStep = class extends BaseLazyStep {
|
|
|
264
265
|
headers;
|
|
265
266
|
retries;
|
|
266
267
|
timeout;
|
|
268
|
+
flowControl;
|
|
267
269
|
stepType = "Call";
|
|
268
|
-
constructor(stepName, url, method, body, headers, retries, timeout) {
|
|
270
|
+
constructor(stepName, url, method, body, headers, retries, timeout, flowControl) {
|
|
269
271
|
super(stepName);
|
|
270
272
|
this.url = url;
|
|
271
273
|
this.method = method;
|
|
@@ -273,6 +275,7 @@ var LazyCallStep = class extends BaseLazyStep {
|
|
|
273
275
|
this.headers = headers;
|
|
274
276
|
this.retries = retries;
|
|
275
277
|
this.timeout = timeout;
|
|
278
|
+
this.flowControl = flowControl;
|
|
276
279
|
}
|
|
277
280
|
getPlanStep(concurrent, targetStep) {
|
|
278
281
|
return {
|
|
@@ -343,14 +346,22 @@ var LazyNotifyStep = class extends LazyFunctionStep {
|
|
|
343
346
|
var LazyInvokeStep = class extends BaseLazyStep {
|
|
344
347
|
stepType = "Invoke";
|
|
345
348
|
params;
|
|
346
|
-
constructor(stepName, {
|
|
349
|
+
constructor(stepName, {
|
|
350
|
+
workflow,
|
|
351
|
+
body,
|
|
352
|
+
headers = {},
|
|
353
|
+
workflowRunId,
|
|
354
|
+
retries,
|
|
355
|
+
flowControl
|
|
356
|
+
}) {
|
|
347
357
|
super(stepName);
|
|
348
358
|
this.params = {
|
|
349
359
|
workflow,
|
|
350
360
|
body,
|
|
351
361
|
headers,
|
|
352
362
|
workflowRunId: getWorkflowRunId(workflowRunId),
|
|
353
|
-
retries
|
|
363
|
+
retries,
|
|
364
|
+
flowControl
|
|
354
365
|
};
|
|
355
366
|
}
|
|
356
367
|
getPlanStep(concurrent, targetStep) {
|
|
@@ -809,7 +820,8 @@ var triggerFirstInvocation = async ({
|
|
|
809
820
|
workflowContext,
|
|
810
821
|
useJSONContent,
|
|
811
822
|
telemetry,
|
|
812
|
-
debug
|
|
823
|
+
debug,
|
|
824
|
+
invokeCount
|
|
813
825
|
}) => {
|
|
814
826
|
const { headers } = getHeaders({
|
|
815
827
|
initHeaderValue: "true",
|
|
@@ -818,7 +830,9 @@ var triggerFirstInvocation = async ({
|
|
|
818
830
|
userHeaders: workflowContext.headers,
|
|
819
831
|
failureUrl: workflowContext.failureUrl,
|
|
820
832
|
retries: workflowContext.retries,
|
|
821
|
-
telemetry
|
|
833
|
+
telemetry,
|
|
834
|
+
invokeCount,
|
|
835
|
+
flowControl: workflowContext.flowControl
|
|
822
836
|
});
|
|
823
837
|
if (workflowContext.headers.get("content-type")) {
|
|
824
838
|
headers["content-type"] = workflowContext.headers.get("content-type");
|
|
@@ -924,6 +938,7 @@ var handleThirdPartyCallResult = async ({
|
|
|
924
938
|
failureUrl,
|
|
925
939
|
retries,
|
|
926
940
|
telemetry,
|
|
941
|
+
flowControl,
|
|
927
942
|
debug
|
|
928
943
|
}) => {
|
|
929
944
|
try {
|
|
@@ -971,6 +986,7 @@ ${atob(callbackMessage.body ?? "")}`
|
|
|
971
986
|
const stepType = request.headers.get("Upstash-Workflow-StepType");
|
|
972
987
|
const concurrentString = request.headers.get("Upstash-Workflow-Concurrent");
|
|
973
988
|
const contentType = request.headers.get("Upstash-Workflow-ContentType");
|
|
989
|
+
const invokeCount = request.headers.get(WORKFLOW_INVOKE_COUNT_HEADER);
|
|
974
990
|
if (!(workflowRunId && stepIdString && stepName && StepTypes.includes(stepType) && concurrentString && contentType)) {
|
|
975
991
|
throw new Error(
|
|
976
992
|
`Missing info in callback message source header: ${JSON.stringify({
|
|
@@ -991,7 +1007,9 @@ ${atob(callbackMessage.body ?? "")}`
|
|
|
991
1007
|
userHeaders,
|
|
992
1008
|
failureUrl,
|
|
993
1009
|
retries,
|
|
994
|
-
telemetry
|
|
1010
|
+
telemetry,
|
|
1011
|
+
invokeCount: Number(invokeCount),
|
|
1012
|
+
flowControl
|
|
995
1013
|
});
|
|
996
1014
|
const callResponse = {
|
|
997
1015
|
status: callbackMessage.status,
|
|
@@ -1047,7 +1065,10 @@ var getHeaders = ({
|
|
|
1047
1065
|
step,
|
|
1048
1066
|
callRetries,
|
|
1049
1067
|
callTimeout,
|
|
1050
|
-
telemetry
|
|
1068
|
+
telemetry,
|
|
1069
|
+
invokeCount,
|
|
1070
|
+
flowControl,
|
|
1071
|
+
callFlowControl
|
|
1051
1072
|
}) => {
|
|
1052
1073
|
const contentType = (userHeaders ? userHeaders.get("Content-Type") : void 0) ?? DEFAULT_CONTENT_TYPE;
|
|
1053
1074
|
const baseHeaders = {
|
|
@@ -1059,6 +1080,9 @@ var getHeaders = ({
|
|
|
1059
1080
|
"content-type": contentType,
|
|
1060
1081
|
...telemetry ? getTelemetryHeaders(telemetry) : {}
|
|
1061
1082
|
};
|
|
1083
|
+
if (invokeCount !== void 0 && !step?.callUrl) {
|
|
1084
|
+
baseHeaders[`Upstash-Forward-${WORKFLOW_INVOKE_COUNT_HEADER}`] = invokeCount.toString();
|
|
1085
|
+
}
|
|
1062
1086
|
if (!step?.callUrl) {
|
|
1063
1087
|
baseHeaders[`Upstash-Forward-${WORKFLOW_PROTOCOL_VERSION_HEADER}`] = WORKFLOW_PROTOCOL_VERSION;
|
|
1064
1088
|
}
|
|
@@ -1067,13 +1091,23 @@ var getHeaders = ({
|
|
|
1067
1091
|
}
|
|
1068
1092
|
if (failureUrl) {
|
|
1069
1093
|
baseHeaders[`Upstash-Failure-Callback-Forward-${WORKFLOW_FAILURE_HEADER}`] = "true";
|
|
1094
|
+
baseHeaders[`Upstash-Failure-Callback-Forward-Upstash-Workflow-Failure-Callback`] = "true";
|
|
1095
|
+
baseHeaders["Upstash-Failure-Callback-Workflow-Runid"] = workflowRunId;
|
|
1096
|
+
baseHeaders["Upstash-Failure-Callback-Workflow-Init"] = "false";
|
|
1097
|
+
baseHeaders["Upstash-Failure-Callback-Workflow-Url"] = workflowUrl;
|
|
1098
|
+
baseHeaders["Upstash-Failure-Callback-Workflow-Calltype"] = "failureCall";
|
|
1099
|
+
if (retries !== void 0) {
|
|
1100
|
+
baseHeaders["Upstash-Failure-Callback-Retries"] = retries.toString();
|
|
1101
|
+
}
|
|
1102
|
+
if (flowControl) {
|
|
1103
|
+
const { flowControlKey, flowControlValue } = prepareFlowControl(flowControl);
|
|
1104
|
+
baseHeaders["Upstash-Failure-Callback-Flow-Control-Key"] = flowControlKey;
|
|
1105
|
+
baseHeaders["Upstash-Failure-Callback-Flow-Control-Value"] = flowControlValue;
|
|
1106
|
+
}
|
|
1070
1107
|
if (!step?.callUrl) {
|
|
1071
1108
|
baseHeaders["Upstash-Failure-Callback"] = failureUrl;
|
|
1072
1109
|
}
|
|
1073
1110
|
}
|
|
1074
|
-
if (step?.stepType === "Invoke") {
|
|
1075
|
-
baseHeaders["upstash-workflow-invoke"] = "true";
|
|
1076
|
-
}
|
|
1077
1111
|
if (step?.callUrl) {
|
|
1078
1112
|
baseHeaders["Upstash-Retries"] = callRetries?.toString() ?? "0";
|
|
1079
1113
|
baseHeaders[WORKFLOW_FEATURE_HEADER] = "WF_NoDelete,InitialBody";
|
|
@@ -1081,9 +1115,26 @@ var getHeaders = ({
|
|
|
1081
1115
|
baseHeaders["Upstash-Callback-Retries"] = retries.toString();
|
|
1082
1116
|
baseHeaders["Upstash-Failure-Callback-Retries"] = retries.toString();
|
|
1083
1117
|
}
|
|
1084
|
-
|
|
1085
|
-
|
|
1086
|
-
|
|
1118
|
+
if (callFlowControl) {
|
|
1119
|
+
const { flowControlKey, flowControlValue } = prepareFlowControl(callFlowControl);
|
|
1120
|
+
baseHeaders["Upstash-Flow-Control-Key"] = flowControlKey;
|
|
1121
|
+
baseHeaders["Upstash-Flow-Control-Value"] = flowControlValue;
|
|
1122
|
+
}
|
|
1123
|
+
if (flowControl) {
|
|
1124
|
+
const { flowControlKey, flowControlValue } = prepareFlowControl(flowControl);
|
|
1125
|
+
baseHeaders["Upstash-Callback-Flow-Control-Key"] = flowControlKey;
|
|
1126
|
+
baseHeaders["Upstash-Callback-Flow-Control-Value"] = flowControlValue;
|
|
1127
|
+
}
|
|
1128
|
+
} else {
|
|
1129
|
+
if (flowControl) {
|
|
1130
|
+
const { flowControlKey, flowControlValue } = prepareFlowControl(flowControl);
|
|
1131
|
+
baseHeaders["Upstash-Flow-Control-Key"] = flowControlKey;
|
|
1132
|
+
baseHeaders["Upstash-Flow-Control-Value"] = flowControlValue;
|
|
1133
|
+
}
|
|
1134
|
+
if (retries !== void 0) {
|
|
1135
|
+
baseHeaders["Upstash-Retries"] = retries.toString();
|
|
1136
|
+
baseHeaders["Upstash-Failure-Callback-Retries"] = retries.toString();
|
|
1137
|
+
}
|
|
1087
1138
|
}
|
|
1088
1139
|
if (userHeaders) {
|
|
1089
1140
|
for (const header of userHeaders.keys()) {
|
|
@@ -1118,6 +1169,7 @@ var getHeaders = ({
|
|
|
1118
1169
|
"Upstash-Callback-Forward-Upstash-Workflow-StepType": step.stepType,
|
|
1119
1170
|
"Upstash-Callback-Forward-Upstash-Workflow-Concurrent": step.concurrent.toString(),
|
|
1120
1171
|
"Upstash-Callback-Forward-Upstash-Workflow-ContentType": contentType,
|
|
1172
|
+
[`Upstash-Callback-Forward-${WORKFLOW_INVOKE_COUNT_HEADER}`]: (invokeCount ?? 0).toString(),
|
|
1121
1173
|
"Upstash-Workflow-CallType": "toCallback"
|
|
1122
1174
|
}
|
|
1123
1175
|
};
|
|
@@ -1175,9 +1227,98 @@ If you want to disable QStash Verification, you should clear env variables QSTAS
|
|
|
1175
1227
|
);
|
|
1176
1228
|
}
|
|
1177
1229
|
};
|
|
1230
|
+
var prepareFlowControl = (flowControl) => {
|
|
1231
|
+
const parallelism = flowControl.parallelism?.toString();
|
|
1232
|
+
const rate = flowControl.ratePerSecond?.toString();
|
|
1233
|
+
const controlValue = [
|
|
1234
|
+
parallelism ? `parallelism=${parallelism}` : void 0,
|
|
1235
|
+
rate ? `rate=${rate}` : void 0
|
|
1236
|
+
].filter(Boolean);
|
|
1237
|
+
if (controlValue.length === 0) {
|
|
1238
|
+
throw new import_qstash3.QstashError("Provide at least one of parallelism or ratePerSecond for flowControl");
|
|
1239
|
+
}
|
|
1240
|
+
return {
|
|
1241
|
+
flowControlKey: flowControl.key,
|
|
1242
|
+
flowControlValue: controlValue.join(", ")
|
|
1243
|
+
};
|
|
1244
|
+
};
|
|
1178
1245
|
|
|
1179
1246
|
// src/context/auto-executor.ts
|
|
1180
1247
|
var import_qstash4 = require("@upstash/qstash");
|
|
1248
|
+
|
|
1249
|
+
// src/serve/serve-many.ts
|
|
1250
|
+
var invokeWorkflow = async ({
|
|
1251
|
+
settings,
|
|
1252
|
+
invokeStep,
|
|
1253
|
+
context,
|
|
1254
|
+
invokeCount,
|
|
1255
|
+
telemetry
|
|
1256
|
+
}) => {
|
|
1257
|
+
const {
|
|
1258
|
+
body,
|
|
1259
|
+
workflow,
|
|
1260
|
+
headers = {},
|
|
1261
|
+
workflowRunId = getWorkflowRunId(),
|
|
1262
|
+
retries,
|
|
1263
|
+
flowControl
|
|
1264
|
+
} = settings;
|
|
1265
|
+
const { workflowId } = workflow;
|
|
1266
|
+
const {
|
|
1267
|
+
retries: workflowRetries,
|
|
1268
|
+
failureFunction,
|
|
1269
|
+
failureUrl,
|
|
1270
|
+
useJSONContent,
|
|
1271
|
+
flowControl: workflowFlowControl
|
|
1272
|
+
} = workflow.options;
|
|
1273
|
+
if (!workflowId) {
|
|
1274
|
+
throw new WorkflowError("You can only invoke workflow which has a workflowId");
|
|
1275
|
+
}
|
|
1276
|
+
const { headers: invokerHeaders } = getHeaders({
|
|
1277
|
+
initHeaderValue: "false",
|
|
1278
|
+
workflowRunId: context.workflowRunId,
|
|
1279
|
+
workflowUrl: context.url,
|
|
1280
|
+
userHeaders: context.headers,
|
|
1281
|
+
failureUrl: context.failureUrl,
|
|
1282
|
+
retries: context.retries,
|
|
1283
|
+
telemetry,
|
|
1284
|
+
invokeCount,
|
|
1285
|
+
flowControl: context.flowControl
|
|
1286
|
+
});
|
|
1287
|
+
invokerHeaders["Upstash-Workflow-Runid"] = context.workflowRunId;
|
|
1288
|
+
const newUrl = context.url.replace(/[^/]+$/, workflowId);
|
|
1289
|
+
const { headers: triggerHeaders } = getHeaders({
|
|
1290
|
+
initHeaderValue: "true",
|
|
1291
|
+
workflowRunId,
|
|
1292
|
+
workflowUrl: newUrl,
|
|
1293
|
+
userHeaders: new Headers(headers),
|
|
1294
|
+
retries: retries ?? workflowRetries,
|
|
1295
|
+
telemetry,
|
|
1296
|
+
failureUrl: failureFunction ? newUrl : failureUrl,
|
|
1297
|
+
invokeCount: invokeCount + 1,
|
|
1298
|
+
flowControl: flowControl ?? workflowFlowControl
|
|
1299
|
+
});
|
|
1300
|
+
triggerHeaders["Upstash-Workflow-Invoke"] = "true";
|
|
1301
|
+
if (useJSONContent) {
|
|
1302
|
+
triggerHeaders["content-type"] = "application/json";
|
|
1303
|
+
}
|
|
1304
|
+
const request = {
|
|
1305
|
+
body: JSON.stringify(body),
|
|
1306
|
+
headers: Object.fromEntries(
|
|
1307
|
+
Object.entries(invokerHeaders).map((pairs) => [pairs[0], [pairs[1]]])
|
|
1308
|
+
),
|
|
1309
|
+
workflowRunId,
|
|
1310
|
+
workflowUrl: context.url,
|
|
1311
|
+
step: invokeStep
|
|
1312
|
+
};
|
|
1313
|
+
await context.qstashClient.publish({
|
|
1314
|
+
headers: triggerHeaders,
|
|
1315
|
+
method: "POST",
|
|
1316
|
+
body: JSON.stringify(request),
|
|
1317
|
+
url: newUrl
|
|
1318
|
+
});
|
|
1319
|
+
};
|
|
1320
|
+
|
|
1321
|
+
// src/context/auto-executor.ts
|
|
1181
1322
|
var AutoExecutor = class _AutoExecutor {
|
|
1182
1323
|
context;
|
|
1183
1324
|
promises = /* @__PURE__ */ new WeakMap();
|
|
@@ -1186,14 +1327,16 @@ var AutoExecutor = class _AutoExecutor {
|
|
|
1186
1327
|
nonPlanStepCount;
|
|
1187
1328
|
steps;
|
|
1188
1329
|
indexInCurrentList = 0;
|
|
1330
|
+
invokeCount;
|
|
1189
1331
|
telemetry;
|
|
1190
1332
|
stepCount = 0;
|
|
1191
1333
|
planStepCount = 0;
|
|
1192
1334
|
executingStep = false;
|
|
1193
|
-
constructor(context, steps, telemetry, debug) {
|
|
1335
|
+
constructor(context, steps, telemetry, invokeCount, debug) {
|
|
1194
1336
|
this.context = context;
|
|
1195
1337
|
this.steps = steps;
|
|
1196
1338
|
this.telemetry = telemetry;
|
|
1339
|
+
this.invokeCount = invokeCount ?? 0;
|
|
1197
1340
|
this.debug = debug;
|
|
1198
1341
|
this.nonPlanStepCount = this.steps.filter((step) => !step.targetStep).length;
|
|
1199
1342
|
}
|
|
@@ -1416,7 +1559,9 @@ var AutoExecutor = class _AutoExecutor {
|
|
|
1416
1559
|
step: waitStep,
|
|
1417
1560
|
failureUrl: this.context.failureUrl,
|
|
1418
1561
|
retries: this.context.retries,
|
|
1419
|
-
telemetry: this.telemetry
|
|
1562
|
+
telemetry: this.telemetry,
|
|
1563
|
+
invokeCount: this.invokeCount,
|
|
1564
|
+
flowControl: this.context.flowControl
|
|
1420
1565
|
});
|
|
1421
1566
|
const waitBody = {
|
|
1422
1567
|
url: this.context.url,
|
|
@@ -1444,17 +1589,13 @@ var AutoExecutor = class _AutoExecutor {
|
|
|
1444
1589
|
if (steps.length === 1 && lazySteps[0] instanceof LazyInvokeStep) {
|
|
1445
1590
|
const invokeStep = steps[0];
|
|
1446
1591
|
const lazyInvokeStep = lazySteps[0];
|
|
1447
|
-
await
|
|
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
|
-
},
|
|
1592
|
+
await invokeWorkflow({
|
|
1593
|
+
settings: lazyInvokeStep.params,
|
|
1455
1594
|
invokeStep,
|
|
1456
|
-
this.context
|
|
1457
|
-
|
|
1595
|
+
context: this.context,
|
|
1596
|
+
invokeCount: this.invokeCount,
|
|
1597
|
+
telemetry: this.telemetry
|
|
1598
|
+
});
|
|
1458
1599
|
throw new WorkflowAbort(invokeStep.stepName, invokeStep);
|
|
1459
1600
|
}
|
|
1460
1601
|
const result = await this.context.qstashClient.batchJSON(
|
|
@@ -1470,11 +1611,14 @@ var AutoExecutor = class _AutoExecutor {
|
|
|
1470
1611
|
retries: this.context.retries,
|
|
1471
1612
|
callRetries: lazyStep instanceof LazyCallStep ? lazyStep.retries : void 0,
|
|
1472
1613
|
callTimeout: lazyStep instanceof LazyCallStep ? lazyStep.timeout : void 0,
|
|
1473
|
-
telemetry: this.telemetry
|
|
1614
|
+
telemetry: this.telemetry,
|
|
1615
|
+
invokeCount: this.invokeCount,
|
|
1616
|
+
flowControl: this.context.flowControl,
|
|
1617
|
+
callFlowControl: lazyStep instanceof LazyCallStep ? lazyStep.flowControl : void 0
|
|
1474
1618
|
});
|
|
1475
1619
|
const willWait = singleStep.concurrent === NO_CONCURRENCY || singleStep.stepId === 0;
|
|
1476
1620
|
singleStep.out = JSON.stringify(singleStep.out);
|
|
1477
|
-
return singleStep.callUrl ? (
|
|
1621
|
+
return singleStep.callUrl && lazyStep instanceof LazyCallStep ? (
|
|
1478
1622
|
// if the step is a third party call, we call the third party
|
|
1479
1623
|
// url (singleStep.callUrl) and pass information about the workflow
|
|
1480
1624
|
// in the headers (handled in getHeaders). QStash makes the request
|
|
@@ -1774,9 +1918,10 @@ var wrapTools = ({
|
|
|
1774
1918
|
return Object.fromEntries(
|
|
1775
1919
|
Object.entries(tools).map((toolInfo) => {
|
|
1776
1920
|
const [toolName, tool3] = toolInfo;
|
|
1921
|
+
const executeAsStep = "executeAsStep" in tool3 ? tool3.executeAsStep : true;
|
|
1777
1922
|
const aiSDKTool = convertToAISDKTool(tool3);
|
|
1778
1923
|
const execute = aiSDKTool.execute;
|
|
1779
|
-
if (execute) {
|
|
1924
|
+
if (execute && executeAsStep) {
|
|
1780
1925
|
const wrappedExecute = (...params) => {
|
|
1781
1926
|
return context.run(`Run tool ${toolName}`, () => execute(...params));
|
|
1782
1927
|
};
|
|
@@ -2130,6 +2275,11 @@ var WorkflowContext = class {
|
|
|
2130
2275
|
* Number of retries
|
|
2131
2276
|
*/
|
|
2132
2277
|
retries;
|
|
2278
|
+
/**
|
|
2279
|
+
* Settings for controlling the number of active requests
|
|
2280
|
+
* and number of requests per second with the same key.
|
|
2281
|
+
*/
|
|
2282
|
+
flowControl;
|
|
2133
2283
|
constructor({
|
|
2134
2284
|
qstashClient,
|
|
2135
2285
|
workflowRunId,
|
|
@@ -2141,7 +2291,9 @@ var WorkflowContext = class {
|
|
|
2141
2291
|
initialPayload,
|
|
2142
2292
|
env,
|
|
2143
2293
|
retries,
|
|
2144
|
-
telemetry
|
|
2294
|
+
telemetry,
|
|
2295
|
+
invokeCount,
|
|
2296
|
+
flowControl
|
|
2145
2297
|
}) {
|
|
2146
2298
|
this.qstashClient = qstashClient;
|
|
2147
2299
|
this.workflowRunId = workflowRunId;
|
|
@@ -2152,7 +2304,8 @@ var WorkflowContext = class {
|
|
|
2152
2304
|
this.requestPayload = initialPayload;
|
|
2153
2305
|
this.env = env ?? {};
|
|
2154
2306
|
this.retries = retries ?? DEFAULT_RETRIES;
|
|
2155
|
-
this.
|
|
2307
|
+
this.flowControl = flowControl;
|
|
2308
|
+
this.executor = new AutoExecutor(this, this.steps, telemetry, invokeCount, debug);
|
|
2156
2309
|
}
|
|
2157
2310
|
/**
|
|
2158
2311
|
* Executes a workflow step
|
|
@@ -2254,7 +2407,7 @@ var WorkflowContext = class {
|
|
|
2254
2407
|
* }
|
|
2255
2408
|
*/
|
|
2256
2409
|
async call(stepName, settings) {
|
|
2257
|
-
const { url, method = "GET", body, headers = {}, retries = 0, timeout } = settings;
|
|
2410
|
+
const { url, method = "GET", body, headers = {}, retries = 0, timeout, flowControl } = settings;
|
|
2258
2411
|
const result = await this.addStep(
|
|
2259
2412
|
new LazyCallStep(
|
|
2260
2413
|
stepName,
|
|
@@ -2263,7 +2416,8 @@ var WorkflowContext = class {
|
|
|
2263
2416
|
body,
|
|
2264
2417
|
headers,
|
|
2265
2418
|
retries,
|
|
2266
|
-
timeout
|
|
2419
|
+
timeout,
|
|
2420
|
+
flowControl
|
|
2267
2421
|
)
|
|
2268
2422
|
);
|
|
2269
2423
|
if (typeof result === "string") {
|
|
@@ -2500,7 +2654,8 @@ var DisabledWorkflowContext = class _DisabledWorkflowContext extends WorkflowCon
|
|
|
2500
2654
|
failureUrl: context.failureUrl,
|
|
2501
2655
|
initialPayload: context.requestPayload,
|
|
2502
2656
|
env: context.env,
|
|
2503
|
-
retries: context.retries
|
|
2657
|
+
retries: context.retries,
|
|
2658
|
+
flowControl: context.flowControl
|
|
2504
2659
|
});
|
|
2505
2660
|
try {
|
|
2506
2661
|
await routeFunction(disabledContext);
|
|
@@ -2653,7 +2808,7 @@ var parseRequest = async (requestPayload, isFirstInvocation, workflowRunId, requ
|
|
|
2653
2808
|
};
|
|
2654
2809
|
}
|
|
2655
2810
|
};
|
|
2656
|
-
var handleFailure = async (request, requestPayload, qstashClient, initialPayloadParser, routeFunction, failureFunction, env, retries, debug) => {
|
|
2811
|
+
var handleFailure = async (request, requestPayload, qstashClient, initialPayloadParser, routeFunction, failureFunction, env, retries, flowControl, debug) => {
|
|
2657
2812
|
if (request.headers.get(WORKFLOW_FAILURE_HEADER) !== "true") {
|
|
2658
2813
|
return ok("not-failure-callback");
|
|
2659
2814
|
}
|
|
@@ -2665,22 +2820,21 @@ var handleFailure = async (request, requestPayload, qstashClient, initialPayload
|
|
|
2665
2820
|
);
|
|
2666
2821
|
}
|
|
2667
2822
|
try {
|
|
2668
|
-
const { status, header, body, url,
|
|
2669
|
-
requestPayload
|
|
2670
|
-
);
|
|
2823
|
+
const { status, header, body, url, sourceBody, workflowRunId } = JSON.parse(requestPayload);
|
|
2671
2824
|
const decodedBody = body ? decodeBase64(body) : "{}";
|
|
2672
2825
|
const errorPayload = JSON.parse(decodedBody);
|
|
2673
2826
|
const workflowContext = new WorkflowContext({
|
|
2674
2827
|
qstashClient,
|
|
2675
2828
|
workflowRunId,
|
|
2676
2829
|
initialPayload: sourceBody ? initialPayloadParser(decodeBase64(sourceBody)) : void 0,
|
|
2677
|
-
headers: recreateUserHeaders(
|
|
2830
|
+
headers: recreateUserHeaders(request.headers),
|
|
2678
2831
|
steps: [],
|
|
2679
2832
|
url,
|
|
2680
2833
|
failureUrl: url,
|
|
2681
2834
|
debug,
|
|
2682
2835
|
env,
|
|
2683
2836
|
retries,
|
|
2837
|
+
flowControl,
|
|
2684
2838
|
telemetry: void 0
|
|
2685
2839
|
// not going to make requests in authentication check
|
|
2686
2840
|
});
|
|
@@ -2807,7 +2961,8 @@ var serveBase = (routeFunction, telemetry, options) => {
|
|
|
2807
2961
|
env,
|
|
2808
2962
|
retries,
|
|
2809
2963
|
useJSONContent,
|
|
2810
|
-
disableTelemetry
|
|
2964
|
+
disableTelemetry,
|
|
2965
|
+
flowControl
|
|
2811
2966
|
} = processOptions(options);
|
|
2812
2967
|
telemetry = disableTelemetry ? void 0 : telemetry;
|
|
2813
2968
|
const debug = WorkflowLogger.getLogger(verbose);
|
|
@@ -2848,6 +3003,7 @@ var serveBase = (routeFunction, telemetry, options) => {
|
|
|
2848
3003
|
failureFunction,
|
|
2849
3004
|
env,
|
|
2850
3005
|
retries,
|
|
3006
|
+
flowControl,
|
|
2851
3007
|
debug
|
|
2852
3008
|
);
|
|
2853
3009
|
if (failureCheck.isErr()) {
|
|
@@ -2856,6 +3012,7 @@ var serveBase = (routeFunction, telemetry, options) => {
|
|
|
2856
3012
|
await debug?.log("WARN", "RESPONSE_DEFAULT", "failureFunction executed");
|
|
2857
3013
|
return onStepFinish(workflowRunId, "failure-callback");
|
|
2858
3014
|
}
|
|
3015
|
+
const invokeCount = Number(request.headers.get(WORKFLOW_INVOKE_COUNT_HEADER) ?? "0");
|
|
2859
3016
|
const workflowContext = new WorkflowContext({
|
|
2860
3017
|
qstashClient,
|
|
2861
3018
|
workflowRunId,
|
|
@@ -2867,7 +3024,9 @@ var serveBase = (routeFunction, telemetry, options) => {
|
|
|
2867
3024
|
debug,
|
|
2868
3025
|
env,
|
|
2869
3026
|
retries,
|
|
2870
|
-
telemetry
|
|
3027
|
+
telemetry,
|
|
3028
|
+
invokeCount,
|
|
3029
|
+
flowControl
|
|
2871
3030
|
});
|
|
2872
3031
|
const authCheck = await DisabledWorkflowContext.tryAuthentication(
|
|
2873
3032
|
routeFunction,
|
|
@@ -2890,6 +3049,7 @@ var serveBase = (routeFunction, telemetry, options) => {
|
|
|
2890
3049
|
workflowUrl,
|
|
2891
3050
|
failureUrl: workflowFailureUrl,
|
|
2892
3051
|
retries,
|
|
3052
|
+
flowControl,
|
|
2893
3053
|
telemetry,
|
|
2894
3054
|
debug
|
|
2895
3055
|
});
|
|
@@ -2899,7 +3059,13 @@ var serveBase = (routeFunction, telemetry, options) => {
|
|
|
2899
3059
|
});
|
|
2900
3060
|
throw callReturnCheck.error;
|
|
2901
3061
|
} else if (callReturnCheck.value === "continue-workflow") {
|
|
2902
|
-
const result = isFirstInvocation ? await triggerFirstInvocation({
|
|
3062
|
+
const result = isFirstInvocation ? await triggerFirstInvocation({
|
|
3063
|
+
workflowContext,
|
|
3064
|
+
useJSONContent,
|
|
3065
|
+
telemetry,
|
|
3066
|
+
debug,
|
|
3067
|
+
invokeCount
|
|
3068
|
+
}) : await triggerRouteFunction({
|
|
2903
3069
|
onStep: async () => routeFunction(workflowContext),
|
|
2904
3070
|
onCleanup: async (result2) => {
|
|
2905
3071
|
await triggerWorkflowDelete(workflowContext, result2, debug);
|