@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/express.js
CHANGED
|
@@ -23704,6 +23704,7 @@ var WORKFLOW_INIT_HEADER = "Upstash-Workflow-Init";
|
|
|
23704
23704
|
var WORKFLOW_URL_HEADER = "Upstash-Workflow-Url";
|
|
23705
23705
|
var WORKFLOW_FAILURE_HEADER = "Upstash-Workflow-Is-Failure";
|
|
23706
23706
|
var WORKFLOW_FEATURE_HEADER = "Upstash-Feature-Set";
|
|
23707
|
+
var WORKFLOW_INVOKE_COUNT_HEADER = "Upstash-Workflow-Invoke-Count";
|
|
23707
23708
|
var WORKFLOW_PROTOCOL_VERSION = "1";
|
|
23708
23709
|
var WORKFLOW_PROTOCOL_VERSION_HEADER = "Upstash-Workflow-Sdk-Version";
|
|
23709
23710
|
var DEFAULT_CONTENT_TYPE = "application/json";
|
|
@@ -23938,8 +23939,9 @@ var LazyCallStep = class extends BaseLazyStep {
|
|
|
23938
23939
|
headers;
|
|
23939
23940
|
retries;
|
|
23940
23941
|
timeout;
|
|
23942
|
+
flowControl;
|
|
23941
23943
|
stepType = "Call";
|
|
23942
|
-
constructor(stepName, url, method, body, headers, retries, timeout) {
|
|
23944
|
+
constructor(stepName, url, method, body, headers, retries, timeout, flowControl) {
|
|
23943
23945
|
super(stepName);
|
|
23944
23946
|
this.url = url;
|
|
23945
23947
|
this.method = method;
|
|
@@ -23947,6 +23949,7 @@ var LazyCallStep = class extends BaseLazyStep {
|
|
|
23947
23949
|
this.headers = headers;
|
|
23948
23950
|
this.retries = retries;
|
|
23949
23951
|
this.timeout = timeout;
|
|
23952
|
+
this.flowControl = flowControl;
|
|
23950
23953
|
}
|
|
23951
23954
|
getPlanStep(concurrent, targetStep) {
|
|
23952
23955
|
return {
|
|
@@ -24017,14 +24020,22 @@ var LazyNotifyStep = class extends LazyFunctionStep {
|
|
|
24017
24020
|
var LazyInvokeStep = class extends BaseLazyStep {
|
|
24018
24021
|
stepType = "Invoke";
|
|
24019
24022
|
params;
|
|
24020
|
-
constructor(stepName, {
|
|
24023
|
+
constructor(stepName, {
|
|
24024
|
+
workflow,
|
|
24025
|
+
body,
|
|
24026
|
+
headers = {},
|
|
24027
|
+
workflowRunId,
|
|
24028
|
+
retries,
|
|
24029
|
+
flowControl
|
|
24030
|
+
}) {
|
|
24021
24031
|
super(stepName);
|
|
24022
24032
|
this.params = {
|
|
24023
24033
|
workflow,
|
|
24024
24034
|
body,
|
|
24025
24035
|
headers,
|
|
24026
24036
|
workflowRunId: getWorkflowRunId(workflowRunId),
|
|
24027
|
-
retries
|
|
24037
|
+
retries,
|
|
24038
|
+
flowControl
|
|
24028
24039
|
};
|
|
24029
24040
|
}
|
|
24030
24041
|
getPlanStep(concurrent, targetStep) {
|
|
@@ -24483,7 +24494,8 @@ var triggerFirstInvocation = async ({
|
|
|
24483
24494
|
workflowContext,
|
|
24484
24495
|
useJSONContent,
|
|
24485
24496
|
telemetry: telemetry2,
|
|
24486
|
-
debug
|
|
24497
|
+
debug,
|
|
24498
|
+
invokeCount
|
|
24487
24499
|
}) => {
|
|
24488
24500
|
const { headers } = getHeaders({
|
|
24489
24501
|
initHeaderValue: "true",
|
|
@@ -24492,7 +24504,9 @@ var triggerFirstInvocation = async ({
|
|
|
24492
24504
|
userHeaders: workflowContext.headers,
|
|
24493
24505
|
failureUrl: workflowContext.failureUrl,
|
|
24494
24506
|
retries: workflowContext.retries,
|
|
24495
|
-
telemetry: telemetry2
|
|
24507
|
+
telemetry: telemetry2,
|
|
24508
|
+
invokeCount,
|
|
24509
|
+
flowControl: workflowContext.flowControl
|
|
24496
24510
|
});
|
|
24497
24511
|
if (workflowContext.headers.get("content-type")) {
|
|
24498
24512
|
headers["content-type"] = workflowContext.headers.get("content-type");
|
|
@@ -24598,6 +24612,7 @@ var handleThirdPartyCallResult = async ({
|
|
|
24598
24612
|
failureUrl,
|
|
24599
24613
|
retries,
|
|
24600
24614
|
telemetry: telemetry2,
|
|
24615
|
+
flowControl,
|
|
24601
24616
|
debug
|
|
24602
24617
|
}) => {
|
|
24603
24618
|
try {
|
|
@@ -24645,6 +24660,7 @@ ${atob(callbackMessage.body ?? "")}`
|
|
|
24645
24660
|
const stepType = request.headers.get("Upstash-Workflow-StepType");
|
|
24646
24661
|
const concurrentString = request.headers.get("Upstash-Workflow-Concurrent");
|
|
24647
24662
|
const contentType = request.headers.get("Upstash-Workflow-ContentType");
|
|
24663
|
+
const invokeCount = request.headers.get(WORKFLOW_INVOKE_COUNT_HEADER);
|
|
24648
24664
|
if (!(workflowRunId && stepIdString && stepName && StepTypes.includes(stepType) && concurrentString && contentType)) {
|
|
24649
24665
|
throw new Error(
|
|
24650
24666
|
`Missing info in callback message source header: ${JSON.stringify({
|
|
@@ -24665,7 +24681,9 @@ ${atob(callbackMessage.body ?? "")}`
|
|
|
24665
24681
|
userHeaders,
|
|
24666
24682
|
failureUrl,
|
|
24667
24683
|
retries,
|
|
24668
|
-
telemetry: telemetry2
|
|
24684
|
+
telemetry: telemetry2,
|
|
24685
|
+
invokeCount: Number(invokeCount),
|
|
24686
|
+
flowControl
|
|
24669
24687
|
});
|
|
24670
24688
|
const callResponse = {
|
|
24671
24689
|
status: callbackMessage.status,
|
|
@@ -24721,7 +24739,10 @@ var getHeaders = ({
|
|
|
24721
24739
|
step,
|
|
24722
24740
|
callRetries,
|
|
24723
24741
|
callTimeout,
|
|
24724
|
-
telemetry: telemetry2
|
|
24742
|
+
telemetry: telemetry2,
|
|
24743
|
+
invokeCount,
|
|
24744
|
+
flowControl,
|
|
24745
|
+
callFlowControl
|
|
24725
24746
|
}) => {
|
|
24726
24747
|
const contentType = (userHeaders ? userHeaders.get("Content-Type") : void 0) ?? DEFAULT_CONTENT_TYPE;
|
|
24727
24748
|
const baseHeaders = {
|
|
@@ -24733,6 +24754,9 @@ var getHeaders = ({
|
|
|
24733
24754
|
"content-type": contentType,
|
|
24734
24755
|
...telemetry2 ? getTelemetryHeaders(telemetry2) : {}
|
|
24735
24756
|
};
|
|
24757
|
+
if (invokeCount !== void 0 && !step?.callUrl) {
|
|
24758
|
+
baseHeaders[`Upstash-Forward-${WORKFLOW_INVOKE_COUNT_HEADER}`] = invokeCount.toString();
|
|
24759
|
+
}
|
|
24736
24760
|
if (!step?.callUrl) {
|
|
24737
24761
|
baseHeaders[`Upstash-Forward-${WORKFLOW_PROTOCOL_VERSION_HEADER}`] = WORKFLOW_PROTOCOL_VERSION;
|
|
24738
24762
|
}
|
|
@@ -24741,13 +24765,23 @@ var getHeaders = ({
|
|
|
24741
24765
|
}
|
|
24742
24766
|
if (failureUrl) {
|
|
24743
24767
|
baseHeaders[`Upstash-Failure-Callback-Forward-${WORKFLOW_FAILURE_HEADER}`] = "true";
|
|
24768
|
+
baseHeaders[`Upstash-Failure-Callback-Forward-Upstash-Workflow-Failure-Callback`] = "true";
|
|
24769
|
+
baseHeaders["Upstash-Failure-Callback-Workflow-Runid"] = workflowRunId;
|
|
24770
|
+
baseHeaders["Upstash-Failure-Callback-Workflow-Init"] = "false";
|
|
24771
|
+
baseHeaders["Upstash-Failure-Callback-Workflow-Url"] = workflowUrl;
|
|
24772
|
+
baseHeaders["Upstash-Failure-Callback-Workflow-Calltype"] = "failureCall";
|
|
24773
|
+
if (retries !== void 0) {
|
|
24774
|
+
baseHeaders["Upstash-Failure-Callback-Retries"] = retries.toString();
|
|
24775
|
+
}
|
|
24776
|
+
if (flowControl) {
|
|
24777
|
+
const { flowControlKey, flowControlValue } = prepareFlowControl(flowControl);
|
|
24778
|
+
baseHeaders["Upstash-Failure-Callback-Flow-Control-Key"] = flowControlKey;
|
|
24779
|
+
baseHeaders["Upstash-Failure-Callback-Flow-Control-Value"] = flowControlValue;
|
|
24780
|
+
}
|
|
24744
24781
|
if (!step?.callUrl) {
|
|
24745
24782
|
baseHeaders["Upstash-Failure-Callback"] = failureUrl;
|
|
24746
24783
|
}
|
|
24747
24784
|
}
|
|
24748
|
-
if (step?.stepType === "Invoke") {
|
|
24749
|
-
baseHeaders["upstash-workflow-invoke"] = "true";
|
|
24750
|
-
}
|
|
24751
24785
|
if (step?.callUrl) {
|
|
24752
24786
|
baseHeaders["Upstash-Retries"] = callRetries?.toString() ?? "0";
|
|
24753
24787
|
baseHeaders[WORKFLOW_FEATURE_HEADER] = "WF_NoDelete,InitialBody";
|
|
@@ -24755,9 +24789,26 @@ var getHeaders = ({
|
|
|
24755
24789
|
baseHeaders["Upstash-Callback-Retries"] = retries.toString();
|
|
24756
24790
|
baseHeaders["Upstash-Failure-Callback-Retries"] = retries.toString();
|
|
24757
24791
|
}
|
|
24758
|
-
|
|
24759
|
-
|
|
24760
|
-
|
|
24792
|
+
if (callFlowControl) {
|
|
24793
|
+
const { flowControlKey, flowControlValue } = prepareFlowControl(callFlowControl);
|
|
24794
|
+
baseHeaders["Upstash-Flow-Control-Key"] = flowControlKey;
|
|
24795
|
+
baseHeaders["Upstash-Flow-Control-Value"] = flowControlValue;
|
|
24796
|
+
}
|
|
24797
|
+
if (flowControl) {
|
|
24798
|
+
const { flowControlKey, flowControlValue } = prepareFlowControl(flowControl);
|
|
24799
|
+
baseHeaders["Upstash-Callback-Flow-Control-Key"] = flowControlKey;
|
|
24800
|
+
baseHeaders["Upstash-Callback-Flow-Control-Value"] = flowControlValue;
|
|
24801
|
+
}
|
|
24802
|
+
} else {
|
|
24803
|
+
if (flowControl) {
|
|
24804
|
+
const { flowControlKey, flowControlValue } = prepareFlowControl(flowControl);
|
|
24805
|
+
baseHeaders["Upstash-Flow-Control-Key"] = flowControlKey;
|
|
24806
|
+
baseHeaders["Upstash-Flow-Control-Value"] = flowControlValue;
|
|
24807
|
+
}
|
|
24808
|
+
if (retries !== void 0) {
|
|
24809
|
+
baseHeaders["Upstash-Retries"] = retries.toString();
|
|
24810
|
+
baseHeaders["Upstash-Failure-Callback-Retries"] = retries.toString();
|
|
24811
|
+
}
|
|
24761
24812
|
}
|
|
24762
24813
|
if (userHeaders) {
|
|
24763
24814
|
for (const header of userHeaders.keys()) {
|
|
@@ -24792,6 +24843,7 @@ var getHeaders = ({
|
|
|
24792
24843
|
"Upstash-Callback-Forward-Upstash-Workflow-StepType": step.stepType,
|
|
24793
24844
|
"Upstash-Callback-Forward-Upstash-Workflow-Concurrent": step.concurrent.toString(),
|
|
24794
24845
|
"Upstash-Callback-Forward-Upstash-Workflow-ContentType": contentType,
|
|
24846
|
+
[`Upstash-Callback-Forward-${WORKFLOW_INVOKE_COUNT_HEADER}`]: (invokeCount ?? 0).toString(),
|
|
24795
24847
|
"Upstash-Workflow-CallType": "toCallback"
|
|
24796
24848
|
}
|
|
24797
24849
|
};
|
|
@@ -24849,9 +24901,159 @@ If you want to disable QStash Verification, you should clear env variables QSTAS
|
|
|
24849
24901
|
);
|
|
24850
24902
|
}
|
|
24851
24903
|
};
|
|
24904
|
+
var prepareFlowControl = (flowControl) => {
|
|
24905
|
+
const parallelism = flowControl.parallelism?.toString();
|
|
24906
|
+
const rate = flowControl.ratePerSecond?.toString();
|
|
24907
|
+
const controlValue = [
|
|
24908
|
+
parallelism ? `parallelism=${parallelism}` : void 0,
|
|
24909
|
+
rate ? `rate=${rate}` : void 0
|
|
24910
|
+
].filter(Boolean);
|
|
24911
|
+
if (controlValue.length === 0) {
|
|
24912
|
+
throw new import_qstash3.QstashError("Provide at least one of parallelism or ratePerSecond for flowControl");
|
|
24913
|
+
}
|
|
24914
|
+
return {
|
|
24915
|
+
flowControlKey: flowControl.key,
|
|
24916
|
+
flowControlValue: controlValue.join(", ")
|
|
24917
|
+
};
|
|
24918
|
+
};
|
|
24852
24919
|
|
|
24853
24920
|
// src/context/auto-executor.ts
|
|
24854
24921
|
var import_qstash4 = require("@upstash/qstash");
|
|
24922
|
+
|
|
24923
|
+
// src/serve/serve-many.ts
|
|
24924
|
+
var getWorkflowId = (url) => {
|
|
24925
|
+
const components = url.split("/");
|
|
24926
|
+
const lastComponent = components[components.length - 1];
|
|
24927
|
+
return lastComponent.split("?")[0];
|
|
24928
|
+
};
|
|
24929
|
+
var serveManyBase = ({
|
|
24930
|
+
workflows,
|
|
24931
|
+
getUrl,
|
|
24932
|
+
serveMethod,
|
|
24933
|
+
options
|
|
24934
|
+
}) => {
|
|
24935
|
+
const workflowIds = [];
|
|
24936
|
+
const workflowMap = Object.fromEntries(
|
|
24937
|
+
Object.entries(workflows).map((workflow) => {
|
|
24938
|
+
const workflowId = workflow[0];
|
|
24939
|
+
if (workflowIds.includes(workflowId)) {
|
|
24940
|
+
throw new WorkflowError(
|
|
24941
|
+
`Duplicate workflow name found: '${workflowId}'. Please set different workflow names in serveMany.`
|
|
24942
|
+
);
|
|
24943
|
+
}
|
|
24944
|
+
if (workflowId.includes("/")) {
|
|
24945
|
+
throw new WorkflowError(
|
|
24946
|
+
`Invalid workflow name found: '${workflowId}'. Workflow name cannot contain '/'.`
|
|
24947
|
+
);
|
|
24948
|
+
}
|
|
24949
|
+
workflowIds.push(workflowId);
|
|
24950
|
+
workflow[1].workflowId = workflowId;
|
|
24951
|
+
workflow[1].options = {
|
|
24952
|
+
...options,
|
|
24953
|
+
...workflow[1].options
|
|
24954
|
+
};
|
|
24955
|
+
const params = [workflow[1].routeFunction, workflow[1].options];
|
|
24956
|
+
const handler = serveMethod(...params);
|
|
24957
|
+
return [workflowId, handler];
|
|
24958
|
+
})
|
|
24959
|
+
);
|
|
24960
|
+
return {
|
|
24961
|
+
handler: async (...params) => {
|
|
24962
|
+
const url = getUrl(...params);
|
|
24963
|
+
const pickedWorkflowId = getWorkflowId(url);
|
|
24964
|
+
if (!pickedWorkflowId) {
|
|
24965
|
+
return new Response(
|
|
24966
|
+
`Unexpected request in serveMany. workflowId not set. Please update the URL of your request.`,
|
|
24967
|
+
{
|
|
24968
|
+
status: 404
|
|
24969
|
+
}
|
|
24970
|
+
);
|
|
24971
|
+
}
|
|
24972
|
+
const workflow = workflowMap[pickedWorkflowId];
|
|
24973
|
+
if (!workflow) {
|
|
24974
|
+
return new Response(
|
|
24975
|
+
`No workflows in serveMany found for '${pickedWorkflowId}'. Please update the URL of your request.`,
|
|
24976
|
+
{
|
|
24977
|
+
status: 404
|
|
24978
|
+
}
|
|
24979
|
+
);
|
|
24980
|
+
}
|
|
24981
|
+
return await workflow(...params);
|
|
24982
|
+
}
|
|
24983
|
+
};
|
|
24984
|
+
};
|
|
24985
|
+
var invokeWorkflow = async ({
|
|
24986
|
+
settings,
|
|
24987
|
+
invokeStep,
|
|
24988
|
+
context,
|
|
24989
|
+
invokeCount,
|
|
24990
|
+
telemetry: telemetry2
|
|
24991
|
+
}) => {
|
|
24992
|
+
const {
|
|
24993
|
+
body,
|
|
24994
|
+
workflow,
|
|
24995
|
+
headers = {},
|
|
24996
|
+
workflowRunId = getWorkflowRunId(),
|
|
24997
|
+
retries,
|
|
24998
|
+
flowControl
|
|
24999
|
+
} = settings;
|
|
25000
|
+
const { workflowId } = workflow;
|
|
25001
|
+
const {
|
|
25002
|
+
retries: workflowRetries,
|
|
25003
|
+
failureFunction,
|
|
25004
|
+
failureUrl,
|
|
25005
|
+
useJSONContent,
|
|
25006
|
+
flowControl: workflowFlowControl
|
|
25007
|
+
} = workflow.options;
|
|
25008
|
+
if (!workflowId) {
|
|
25009
|
+
throw new WorkflowError("You can only invoke workflow which has a workflowId");
|
|
25010
|
+
}
|
|
25011
|
+
const { headers: invokerHeaders } = getHeaders({
|
|
25012
|
+
initHeaderValue: "false",
|
|
25013
|
+
workflowRunId: context.workflowRunId,
|
|
25014
|
+
workflowUrl: context.url,
|
|
25015
|
+
userHeaders: context.headers,
|
|
25016
|
+
failureUrl: context.failureUrl,
|
|
25017
|
+
retries: context.retries,
|
|
25018
|
+
telemetry: telemetry2,
|
|
25019
|
+
invokeCount,
|
|
25020
|
+
flowControl: context.flowControl
|
|
25021
|
+
});
|
|
25022
|
+
invokerHeaders["Upstash-Workflow-Runid"] = context.workflowRunId;
|
|
25023
|
+
const newUrl = context.url.replace(/[^/]+$/, workflowId);
|
|
25024
|
+
const { headers: triggerHeaders } = getHeaders({
|
|
25025
|
+
initHeaderValue: "true",
|
|
25026
|
+
workflowRunId,
|
|
25027
|
+
workflowUrl: newUrl,
|
|
25028
|
+
userHeaders: new Headers(headers),
|
|
25029
|
+
retries: retries ?? workflowRetries,
|
|
25030
|
+
telemetry: telemetry2,
|
|
25031
|
+
failureUrl: failureFunction ? newUrl : failureUrl,
|
|
25032
|
+
invokeCount: invokeCount + 1,
|
|
25033
|
+
flowControl: flowControl ?? workflowFlowControl
|
|
25034
|
+
});
|
|
25035
|
+
triggerHeaders["Upstash-Workflow-Invoke"] = "true";
|
|
25036
|
+
if (useJSONContent) {
|
|
25037
|
+
triggerHeaders["content-type"] = "application/json";
|
|
25038
|
+
}
|
|
25039
|
+
const request = {
|
|
25040
|
+
body: JSON.stringify(body),
|
|
25041
|
+
headers: Object.fromEntries(
|
|
25042
|
+
Object.entries(invokerHeaders).map((pairs) => [pairs[0], [pairs[1]]])
|
|
25043
|
+
),
|
|
25044
|
+
workflowRunId,
|
|
25045
|
+
workflowUrl: context.url,
|
|
25046
|
+
step: invokeStep
|
|
25047
|
+
};
|
|
25048
|
+
await context.qstashClient.publish({
|
|
25049
|
+
headers: triggerHeaders,
|
|
25050
|
+
method: "POST",
|
|
25051
|
+
body: JSON.stringify(request),
|
|
25052
|
+
url: newUrl
|
|
25053
|
+
});
|
|
25054
|
+
};
|
|
25055
|
+
|
|
25056
|
+
// src/context/auto-executor.ts
|
|
24855
25057
|
var AutoExecutor = class _AutoExecutor {
|
|
24856
25058
|
context;
|
|
24857
25059
|
promises = /* @__PURE__ */ new WeakMap();
|
|
@@ -24860,14 +25062,16 @@ var AutoExecutor = class _AutoExecutor {
|
|
|
24860
25062
|
nonPlanStepCount;
|
|
24861
25063
|
steps;
|
|
24862
25064
|
indexInCurrentList = 0;
|
|
25065
|
+
invokeCount;
|
|
24863
25066
|
telemetry;
|
|
24864
25067
|
stepCount = 0;
|
|
24865
25068
|
planStepCount = 0;
|
|
24866
25069
|
executingStep = false;
|
|
24867
|
-
constructor(context, steps, telemetry2, debug) {
|
|
25070
|
+
constructor(context, steps, telemetry2, invokeCount, debug) {
|
|
24868
25071
|
this.context = context;
|
|
24869
25072
|
this.steps = steps;
|
|
24870
25073
|
this.telemetry = telemetry2;
|
|
25074
|
+
this.invokeCount = invokeCount ?? 0;
|
|
24871
25075
|
this.debug = debug;
|
|
24872
25076
|
this.nonPlanStepCount = this.steps.filter((step) => !step.targetStep).length;
|
|
24873
25077
|
}
|
|
@@ -25090,7 +25294,9 @@ var AutoExecutor = class _AutoExecutor {
|
|
|
25090
25294
|
step: waitStep,
|
|
25091
25295
|
failureUrl: this.context.failureUrl,
|
|
25092
25296
|
retries: this.context.retries,
|
|
25093
|
-
telemetry: this.telemetry
|
|
25297
|
+
telemetry: this.telemetry,
|
|
25298
|
+
invokeCount: this.invokeCount,
|
|
25299
|
+
flowControl: this.context.flowControl
|
|
25094
25300
|
});
|
|
25095
25301
|
const waitBody = {
|
|
25096
25302
|
url: this.context.url,
|
|
@@ -25118,17 +25324,13 @@ var AutoExecutor = class _AutoExecutor {
|
|
|
25118
25324
|
if (steps.length === 1 && lazySteps[0] instanceof LazyInvokeStep) {
|
|
25119
25325
|
const invokeStep = steps[0];
|
|
25120
25326
|
const lazyInvokeStep = lazySteps[0];
|
|
25121
|
-
await
|
|
25122
|
-
|
|
25123
|
-
body: lazyInvokeStep.params.body,
|
|
25124
|
-
headers: lazyInvokeStep.params.headers,
|
|
25125
|
-
workflowRunId: lazyInvokeStep.params.workflowRunId,
|
|
25126
|
-
workflow: lazyInvokeStep.params.workflow,
|
|
25127
|
-
retries: lazyInvokeStep.params.retries
|
|
25128
|
-
},
|
|
25327
|
+
await invokeWorkflow({
|
|
25328
|
+
settings: lazyInvokeStep.params,
|
|
25129
25329
|
invokeStep,
|
|
25130
|
-
this.context
|
|
25131
|
-
|
|
25330
|
+
context: this.context,
|
|
25331
|
+
invokeCount: this.invokeCount,
|
|
25332
|
+
telemetry: this.telemetry
|
|
25333
|
+
});
|
|
25132
25334
|
throw new WorkflowAbort(invokeStep.stepName, invokeStep);
|
|
25133
25335
|
}
|
|
25134
25336
|
const result = await this.context.qstashClient.batchJSON(
|
|
@@ -25144,11 +25346,14 @@ var AutoExecutor = class _AutoExecutor {
|
|
|
25144
25346
|
retries: this.context.retries,
|
|
25145
25347
|
callRetries: lazyStep instanceof LazyCallStep ? lazyStep.retries : void 0,
|
|
25146
25348
|
callTimeout: lazyStep instanceof LazyCallStep ? lazyStep.timeout : void 0,
|
|
25147
|
-
telemetry: this.telemetry
|
|
25349
|
+
telemetry: this.telemetry,
|
|
25350
|
+
invokeCount: this.invokeCount,
|
|
25351
|
+
flowControl: this.context.flowControl,
|
|
25352
|
+
callFlowControl: lazyStep instanceof LazyCallStep ? lazyStep.flowControl : void 0
|
|
25148
25353
|
});
|
|
25149
25354
|
const willWait = singleStep.concurrent === NO_CONCURRENCY || singleStep.stepId === 0;
|
|
25150
25355
|
singleStep.out = JSON.stringify(singleStep.out);
|
|
25151
|
-
return singleStep.callUrl ? (
|
|
25356
|
+
return singleStep.callUrl && lazyStep instanceof LazyCallStep ? (
|
|
25152
25357
|
// if the step is a third party call, we call the third party
|
|
25153
25358
|
// url (singleStep.callUrl) and pass information about the workflow
|
|
25154
25359
|
// in the headers (handled in getHeaders). QStash makes the request
|
|
@@ -25448,9 +25653,10 @@ var wrapTools = ({
|
|
|
25448
25653
|
return Object.fromEntries(
|
|
25449
25654
|
Object.entries(tools).map((toolInfo) => {
|
|
25450
25655
|
const [toolName, tool3] = toolInfo;
|
|
25656
|
+
const executeAsStep = "executeAsStep" in tool3 ? tool3.executeAsStep : true;
|
|
25451
25657
|
const aiSDKTool = convertToAISDKTool(tool3);
|
|
25452
25658
|
const execute = aiSDKTool.execute;
|
|
25453
|
-
if (execute) {
|
|
25659
|
+
if (execute && executeAsStep) {
|
|
25454
25660
|
const wrappedExecute = (...params) => {
|
|
25455
25661
|
return context.run(`Run tool ${toolName}`, () => execute(...params));
|
|
25456
25662
|
};
|
|
@@ -25804,6 +26010,11 @@ var WorkflowContext = class {
|
|
|
25804
26010
|
* Number of retries
|
|
25805
26011
|
*/
|
|
25806
26012
|
retries;
|
|
26013
|
+
/**
|
|
26014
|
+
* Settings for controlling the number of active requests
|
|
26015
|
+
* and number of requests per second with the same key.
|
|
26016
|
+
*/
|
|
26017
|
+
flowControl;
|
|
25807
26018
|
constructor({
|
|
25808
26019
|
qstashClient,
|
|
25809
26020
|
workflowRunId,
|
|
@@ -25815,7 +26026,9 @@ var WorkflowContext = class {
|
|
|
25815
26026
|
initialPayload,
|
|
25816
26027
|
env,
|
|
25817
26028
|
retries,
|
|
25818
|
-
telemetry: telemetry2
|
|
26029
|
+
telemetry: telemetry2,
|
|
26030
|
+
invokeCount,
|
|
26031
|
+
flowControl
|
|
25819
26032
|
}) {
|
|
25820
26033
|
this.qstashClient = qstashClient;
|
|
25821
26034
|
this.workflowRunId = workflowRunId;
|
|
@@ -25826,7 +26039,8 @@ var WorkflowContext = class {
|
|
|
25826
26039
|
this.requestPayload = initialPayload;
|
|
25827
26040
|
this.env = env ?? {};
|
|
25828
26041
|
this.retries = retries ?? DEFAULT_RETRIES;
|
|
25829
|
-
this.
|
|
26042
|
+
this.flowControl = flowControl;
|
|
26043
|
+
this.executor = new AutoExecutor(this, this.steps, telemetry2, invokeCount, debug);
|
|
25830
26044
|
}
|
|
25831
26045
|
/**
|
|
25832
26046
|
* Executes a workflow step
|
|
@@ -25928,7 +26142,7 @@ var WorkflowContext = class {
|
|
|
25928
26142
|
* }
|
|
25929
26143
|
*/
|
|
25930
26144
|
async call(stepName, settings) {
|
|
25931
|
-
const { url, method = "GET", body, headers = {}, retries = 0, timeout } = settings;
|
|
26145
|
+
const { url, method = "GET", body, headers = {}, retries = 0, timeout, flowControl } = settings;
|
|
25932
26146
|
const result = await this.addStep(
|
|
25933
26147
|
new LazyCallStep(
|
|
25934
26148
|
stepName,
|
|
@@ -25937,7 +26151,8 @@ var WorkflowContext = class {
|
|
|
25937
26151
|
body,
|
|
25938
26152
|
headers,
|
|
25939
26153
|
retries,
|
|
25940
|
-
timeout
|
|
26154
|
+
timeout,
|
|
26155
|
+
flowControl
|
|
25941
26156
|
)
|
|
25942
26157
|
);
|
|
25943
26158
|
if (typeof result === "string") {
|
|
@@ -26174,7 +26389,8 @@ var DisabledWorkflowContext = class _DisabledWorkflowContext extends WorkflowCon
|
|
|
26174
26389
|
failureUrl: context.failureUrl,
|
|
26175
26390
|
initialPayload: context.requestPayload,
|
|
26176
26391
|
env: context.env,
|
|
26177
|
-
retries: context.retries
|
|
26392
|
+
retries: context.retries,
|
|
26393
|
+
flowControl: context.flowControl
|
|
26178
26394
|
});
|
|
26179
26395
|
try {
|
|
26180
26396
|
await routeFunction(disabledContext);
|
|
@@ -26327,7 +26543,7 @@ var parseRequest = async (requestPayload, isFirstInvocation, workflowRunId, requ
|
|
|
26327
26543
|
};
|
|
26328
26544
|
}
|
|
26329
26545
|
};
|
|
26330
|
-
var handleFailure = async (request, requestPayload, qstashClient, initialPayloadParser, routeFunction, failureFunction, env, retries, debug) => {
|
|
26546
|
+
var handleFailure = async (request, requestPayload, qstashClient, initialPayloadParser, routeFunction, failureFunction, env, retries, flowControl, debug) => {
|
|
26331
26547
|
if (request.headers.get(WORKFLOW_FAILURE_HEADER) !== "true") {
|
|
26332
26548
|
return ok("not-failure-callback");
|
|
26333
26549
|
}
|
|
@@ -26339,22 +26555,21 @@ var handleFailure = async (request, requestPayload, qstashClient, initialPayload
|
|
|
26339
26555
|
);
|
|
26340
26556
|
}
|
|
26341
26557
|
try {
|
|
26342
|
-
const { status, header, body, url,
|
|
26343
|
-
requestPayload
|
|
26344
|
-
);
|
|
26558
|
+
const { status, header, body, url, sourceBody, workflowRunId } = JSON.parse(requestPayload);
|
|
26345
26559
|
const decodedBody = body ? decodeBase64(body) : "{}";
|
|
26346
26560
|
const errorPayload = JSON.parse(decodedBody);
|
|
26347
26561
|
const workflowContext = new WorkflowContext({
|
|
26348
26562
|
qstashClient,
|
|
26349
26563
|
workflowRunId,
|
|
26350
26564
|
initialPayload: sourceBody ? initialPayloadParser(decodeBase64(sourceBody)) : void 0,
|
|
26351
|
-
headers: recreateUserHeaders(
|
|
26565
|
+
headers: recreateUserHeaders(request.headers),
|
|
26352
26566
|
steps: [],
|
|
26353
26567
|
url,
|
|
26354
26568
|
failureUrl: url,
|
|
26355
26569
|
debug,
|
|
26356
26570
|
env,
|
|
26357
26571
|
retries,
|
|
26572
|
+
flowControl,
|
|
26358
26573
|
telemetry: void 0
|
|
26359
26574
|
// not going to make requests in authentication check
|
|
26360
26575
|
});
|
|
@@ -26481,7 +26696,8 @@ var serveBase = (routeFunction, telemetry2, options) => {
|
|
|
26481
26696
|
env,
|
|
26482
26697
|
retries,
|
|
26483
26698
|
useJSONContent,
|
|
26484
|
-
disableTelemetry
|
|
26699
|
+
disableTelemetry,
|
|
26700
|
+
flowControl
|
|
26485
26701
|
} = processOptions(options);
|
|
26486
26702
|
telemetry2 = disableTelemetry ? void 0 : telemetry2;
|
|
26487
26703
|
const debug = WorkflowLogger.getLogger(verbose);
|
|
@@ -26522,6 +26738,7 @@ var serveBase = (routeFunction, telemetry2, options) => {
|
|
|
26522
26738
|
failureFunction,
|
|
26523
26739
|
env,
|
|
26524
26740
|
retries,
|
|
26741
|
+
flowControl,
|
|
26525
26742
|
debug
|
|
26526
26743
|
);
|
|
26527
26744
|
if (failureCheck.isErr()) {
|
|
@@ -26530,6 +26747,7 @@ var serveBase = (routeFunction, telemetry2, options) => {
|
|
|
26530
26747
|
await debug?.log("WARN", "RESPONSE_DEFAULT", "failureFunction executed");
|
|
26531
26748
|
return onStepFinish(workflowRunId, "failure-callback");
|
|
26532
26749
|
}
|
|
26750
|
+
const invokeCount = Number(request.headers.get(WORKFLOW_INVOKE_COUNT_HEADER) ?? "0");
|
|
26533
26751
|
const workflowContext = new WorkflowContext({
|
|
26534
26752
|
qstashClient,
|
|
26535
26753
|
workflowRunId,
|
|
@@ -26541,7 +26759,9 @@ var serveBase = (routeFunction, telemetry2, options) => {
|
|
|
26541
26759
|
debug,
|
|
26542
26760
|
env,
|
|
26543
26761
|
retries,
|
|
26544
|
-
telemetry: telemetry2
|
|
26762
|
+
telemetry: telemetry2,
|
|
26763
|
+
invokeCount,
|
|
26764
|
+
flowControl
|
|
26545
26765
|
});
|
|
26546
26766
|
const authCheck = await DisabledWorkflowContext.tryAuthentication(
|
|
26547
26767
|
routeFunction,
|
|
@@ -26564,6 +26784,7 @@ var serveBase = (routeFunction, telemetry2, options) => {
|
|
|
26564
26784
|
workflowUrl,
|
|
26565
26785
|
failureUrl: workflowFailureUrl,
|
|
26566
26786
|
retries,
|
|
26787
|
+
flowControl,
|
|
26567
26788
|
telemetry: telemetry2,
|
|
26568
26789
|
debug
|
|
26569
26790
|
});
|
|
@@ -26573,7 +26794,13 @@ var serveBase = (routeFunction, telemetry2, options) => {
|
|
|
26573
26794
|
});
|
|
26574
26795
|
throw callReturnCheck.error;
|
|
26575
26796
|
} else if (callReturnCheck.value === "continue-workflow") {
|
|
26576
|
-
const result = isFirstInvocation ? await triggerFirstInvocation({
|
|
26797
|
+
const result = isFirstInvocation ? await triggerFirstInvocation({
|
|
26798
|
+
workflowContext,
|
|
26799
|
+
useJSONContent,
|
|
26800
|
+
telemetry: telemetry2,
|
|
26801
|
+
debug,
|
|
26802
|
+
invokeCount
|
|
26803
|
+
}) : await triggerRouteFunction({
|
|
26577
26804
|
onStep: async () => routeFunction(workflowContext),
|
|
26578
26805
|
onCleanup: async (result2) => {
|
|
26579
26806
|
await triggerWorkflowDelete(workflowContext, result2, debug);
|
|
@@ -26610,93 +26837,6 @@ var serveBase = (routeFunction, telemetry2, options) => {
|
|
|
26610
26837
|
|
|
26611
26838
|
// platforms/express.ts
|
|
26612
26839
|
var import_express = __toESM(require_express2());
|
|
26613
|
-
|
|
26614
|
-
// src/serve/serve-many.ts
|
|
26615
|
-
var serveManyBase = ({
|
|
26616
|
-
workflows,
|
|
26617
|
-
getWorkflowId
|
|
26618
|
-
}) => {
|
|
26619
|
-
const workflowIds = [];
|
|
26620
|
-
const workflowMap = Object.fromEntries(
|
|
26621
|
-
Object.entries(workflows).map((workflow) => {
|
|
26622
|
-
const workflowId = workflow[0];
|
|
26623
|
-
if (workflowIds.includes(workflowId)) {
|
|
26624
|
-
throw new WorkflowError(
|
|
26625
|
-
`Duplicate workflow name found: '${workflowId}'. Please set different workflow names in serveMany.`
|
|
26626
|
-
);
|
|
26627
|
-
}
|
|
26628
|
-
if (workflowId.includes("/")) {
|
|
26629
|
-
throw new WorkflowError(
|
|
26630
|
-
`Invalid workflow name found: '${workflowId}'. Workflow name cannot contain '/'.`
|
|
26631
|
-
);
|
|
26632
|
-
}
|
|
26633
|
-
workflowIds.push(workflowId);
|
|
26634
|
-
workflow[1].workflowId = workflowId;
|
|
26635
|
-
return [workflowId, workflow[1].handler];
|
|
26636
|
-
})
|
|
26637
|
-
);
|
|
26638
|
-
return {
|
|
26639
|
-
handler: async (...params) => {
|
|
26640
|
-
const pickedWorkflowId = getWorkflowId(...params);
|
|
26641
|
-
if (!pickedWorkflowId) {
|
|
26642
|
-
throw new WorkflowError(`Unexpected request in serveMany. workflowId not set. Please update the URL of your request.`);
|
|
26643
|
-
}
|
|
26644
|
-
const workflow = workflowMap[pickedWorkflowId];
|
|
26645
|
-
if (!workflow) {
|
|
26646
|
-
throw new WorkflowError(`No workflows in serveMany found for '${pickedWorkflowId}'. Please update the URL of your request.`);
|
|
26647
|
-
}
|
|
26648
|
-
return await workflow(...params);
|
|
26649
|
-
}
|
|
26650
|
-
};
|
|
26651
|
-
};
|
|
26652
|
-
var createInvokeCallback = (telemetry2) => {
|
|
26653
|
-
const invokeCallback = async (settings, invokeStep, context) => {
|
|
26654
|
-
const { body, workflow, headers = {}, workflowRunId = getWorkflowRunId(), retries } = settings;
|
|
26655
|
-
const { workflowId } = workflow;
|
|
26656
|
-
if (!workflowId) {
|
|
26657
|
-
throw new WorkflowError("You can only invoke workflow which has a workflowId");
|
|
26658
|
-
}
|
|
26659
|
-
const { headers: invokerHeaders } = getHeaders({
|
|
26660
|
-
initHeaderValue: "false",
|
|
26661
|
-
workflowRunId: context.workflowRunId,
|
|
26662
|
-
workflowUrl: context.url,
|
|
26663
|
-
userHeaders: context.headers,
|
|
26664
|
-
failureUrl: context.failureUrl,
|
|
26665
|
-
retries: context.retries,
|
|
26666
|
-
telemetry: telemetry2
|
|
26667
|
-
});
|
|
26668
|
-
invokerHeaders["Upstash-Workflow-Runid"] = context.workflowRunId;
|
|
26669
|
-
const newUrl = context.url.replace(/[^/]+$/, workflowId);
|
|
26670
|
-
const { headers: triggerHeaders } = getHeaders({
|
|
26671
|
-
initHeaderValue: "true",
|
|
26672
|
-
workflowRunId,
|
|
26673
|
-
workflowUrl: newUrl,
|
|
26674
|
-
userHeaders: new Headers(headers),
|
|
26675
|
-
retries,
|
|
26676
|
-
telemetry: telemetry2
|
|
26677
|
-
});
|
|
26678
|
-
triggerHeaders["Upstash-Workflow-Invoke"] = "true";
|
|
26679
|
-
const request = {
|
|
26680
|
-
body: JSON.stringify(body),
|
|
26681
|
-
headers: Object.fromEntries(
|
|
26682
|
-
Object.entries(invokerHeaders).map((pairs) => [pairs[0], [pairs[1]]])
|
|
26683
|
-
),
|
|
26684
|
-
workflowRunId,
|
|
26685
|
-
workflowUrl: context.url,
|
|
26686
|
-
step: invokeStep
|
|
26687
|
-
};
|
|
26688
|
-
await context.qstashClient.publish({
|
|
26689
|
-
headers: triggerHeaders,
|
|
26690
|
-
method: "POST",
|
|
26691
|
-
body: JSON.stringify(request),
|
|
26692
|
-
url: newUrl
|
|
26693
|
-
});
|
|
26694
|
-
return void 0;
|
|
26695
|
-
};
|
|
26696
|
-
return invokeCallback;
|
|
26697
|
-
};
|
|
26698
|
-
|
|
26699
|
-
// platforms/express.ts
|
|
26700
26840
|
var isEmptyRequest = (req) => {
|
|
26701
26841
|
return req.headers["content-type"] === "application/json" && req.headers["content-length"] === "0";
|
|
26702
26842
|
};
|
|
@@ -26730,14 +26870,10 @@ function createExpressHandler(params) {
|
|
|
26730
26870
|
headers: new Headers(request_.headers),
|
|
26731
26871
|
body: requestBody
|
|
26732
26872
|
});
|
|
26733
|
-
const { handler: serveHandler } = serveBase(
|
|
26734
|
-
|
|
26735
|
-
|
|
26736
|
-
|
|
26737
|
-
...options,
|
|
26738
|
-
useJSONContent: true
|
|
26739
|
-
}
|
|
26740
|
-
);
|
|
26873
|
+
const { handler: serveHandler } = serveBase(routeFunction, telemetry, {
|
|
26874
|
+
...options,
|
|
26875
|
+
useJSONContent: true
|
|
26876
|
+
});
|
|
26741
26877
|
const response = await serveHandler(webRequest);
|
|
26742
26878
|
res.status(response.status).json(await response.json());
|
|
26743
26879
|
};
|
|
@@ -26749,21 +26885,22 @@ function serve(routeFunction, options) {
|
|
|
26749
26885
|
return router;
|
|
26750
26886
|
}
|
|
26751
26887
|
var createWorkflow = (...params) => {
|
|
26752
|
-
const
|
|
26888
|
+
const [routeFunction, options = {}] = params;
|
|
26753
26889
|
return {
|
|
26754
|
-
|
|
26755
|
-
|
|
26890
|
+
routeFunction,
|
|
26891
|
+
options,
|
|
26756
26892
|
workflowId: void 0
|
|
26757
26893
|
};
|
|
26758
26894
|
};
|
|
26759
|
-
var serveMany = (workflows) => {
|
|
26895
|
+
var serveMany = (workflows, options) => {
|
|
26760
26896
|
const router = (0, import_express.Router)();
|
|
26761
26897
|
const { handler } = serveManyBase({
|
|
26762
26898
|
workflows,
|
|
26763
|
-
|
|
26764
|
-
|
|
26765
|
-
|
|
26766
|
-
|
|
26899
|
+
getUrl(...params) {
|
|
26900
|
+
return params[0].url;
|
|
26901
|
+
},
|
|
26902
|
+
serveMethod: (...params) => createExpressHandler(params),
|
|
26903
|
+
options
|
|
26767
26904
|
});
|
|
26768
26905
|
router.all("*", handler);
|
|
26769
26906
|
return router;
|