@upstash/workflow 0.2.21 → 0.2.22
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/README.md +39 -0
- package/astro.d.mts +2 -2
- package/astro.d.ts +2 -2
- package/astro.js +124 -71
- package/astro.mjs +1 -1
- package/{chunk-NQDNC5P4.mjs → chunk-BON2RKOR.mjs} +93 -76
- package/cloudflare.d.mts +2 -2
- package/cloudflare.d.ts +2 -2
- package/cloudflare.js +124 -71
- package/cloudflare.mjs +1 -1
- package/express.d.mts +2 -2
- package/express.d.ts +2 -2
- package/express.js +139 -23895
- package/express.mjs +8 -23805
- package/h3.d.mts +2 -2
- package/h3.d.ts +2 -2
- package/h3.js +124 -71
- package/h3.mjs +1 -1
- package/hono.d.mts +2 -2
- package/hono.d.ts +2 -2
- package/hono.js +124 -71
- package/hono.mjs +1 -1
- package/index.d.mts +10 -2
- package/index.d.ts +10 -2
- package/index.js +128 -73
- package/index.mjs +5 -3
- package/nextjs.d.mts +2 -2
- package/nextjs.d.ts +2 -2
- package/nextjs.js +126 -72
- package/nextjs.mjs +3 -2
- package/package.json +1 -1
- package/{serve-many-CXqQP3RI.d.ts → serve-many-BXDr30rl.d.ts} +1 -1
- package/{serve-many-BNusWYgt.d.mts → serve-many-CctdYIfB.d.mts} +1 -1
- package/solidjs.d.mts +1 -1
- package/solidjs.d.ts +1 -1
- package/solidjs.js +124 -71
- package/solidjs.mjs +1 -1
- package/svelte.d.mts +2 -2
- package/svelte.d.ts +2 -2
- package/svelte.js +124 -71
- package/svelte.mjs +1 -1
- package/tanstack.d.mts +2 -2
- package/tanstack.d.ts +2 -2
- package/tanstack.js +124 -71
- package/tanstack.mjs +1 -1
- package/{types-Q3dM0UlR.d.ts → types-9nCq6bRP.d.mts} +12 -1
- package/{types-Q3dM0UlR.d.mts → types-9nCq6bRP.d.ts} +12 -1
package/cloudflare.js
CHANGED
|
@@ -39,7 +39,7 @@ var WORKFLOW_PROTOCOL_VERSION_HEADER = "Upstash-Workflow-Sdk-Version";
|
|
|
39
39
|
var DEFAULT_CONTENT_TYPE = "application/json";
|
|
40
40
|
var NO_CONCURRENCY = 1;
|
|
41
41
|
var DEFAULT_RETRIES = 3;
|
|
42
|
-
var VERSION = "v0.2.
|
|
42
|
+
var VERSION = "v0.2.22";
|
|
43
43
|
var SDK_TELEMETRY = `@upstash/workflow@${VERSION}`;
|
|
44
44
|
var TELEMETRY_HEADER_SDK = "Upstash-Telemetry-Sdk";
|
|
45
45
|
var TELEMETRY_HEADER_FRAMEWORK = "Upstash-Telemetry-Framework";
|
|
@@ -47,61 +47,11 @@ var TELEMETRY_HEADER_RUNTIME = "Upstash-Telemetry-Runtime";
|
|
|
47
47
|
var TELEMETRY_HEADER_AGENT = "Upstash-Telemetry-Agent";
|
|
48
48
|
|
|
49
49
|
// src/client/utils.ts
|
|
50
|
-
var
|
|
51
|
-
var makeNotifyRequest = async (requester, eventId, eventData) => {
|
|
52
|
-
const result = await requester.request({
|
|
53
|
-
path: ["v2", "notify", eventId],
|
|
54
|
-
method: "POST",
|
|
55
|
-
body: typeof eventData === "string" ? eventData : JSON.stringify(eventData)
|
|
56
|
-
});
|
|
57
|
-
return result;
|
|
58
|
-
};
|
|
59
|
-
var makeCancelRequest = async (requester, workflowRunId) => {
|
|
60
|
-
await requester.request({
|
|
61
|
-
path: ["v2", "workflows", "runs", `${workflowRunId}?cancel=true`],
|
|
62
|
-
method: "DELETE",
|
|
63
|
-
parseResponseAsJson: false
|
|
64
|
-
});
|
|
65
|
-
return true;
|
|
66
|
-
};
|
|
67
|
-
var getSteps = async (requester, workflowRunId, messageId, debug) => {
|
|
68
|
-
try {
|
|
69
|
-
const steps = await requester.request({
|
|
70
|
-
path: ["v2", "workflows", "runs", workflowRunId],
|
|
71
|
-
parseResponseAsJson: true
|
|
72
|
-
});
|
|
73
|
-
if (!messageId) {
|
|
74
|
-
await debug?.log("INFO", "ENDPOINT_START", {
|
|
75
|
-
message: `Pulled ${steps.length} steps from QStashand returned them without filtering with messageId.`
|
|
76
|
-
});
|
|
77
|
-
return { steps, workflowRunEnded: false };
|
|
78
|
-
} else {
|
|
79
|
-
const index = steps.findIndex((item) => item.messageId === messageId);
|
|
80
|
-
if (index === -1) {
|
|
81
|
-
return { steps: [], workflowRunEnded: false };
|
|
82
|
-
}
|
|
83
|
-
const filteredSteps = steps.slice(0, index + 1);
|
|
84
|
-
await debug?.log("INFO", "ENDPOINT_START", {
|
|
85
|
-
message: `Pulled ${steps.length} steps from QStash and filtered them to ${filteredSteps.length} using messageId.`
|
|
86
|
-
});
|
|
87
|
-
return { steps: filteredSteps, workflowRunEnded: false };
|
|
88
|
-
}
|
|
89
|
-
} catch (error) {
|
|
90
|
-
if (error instanceof import_qstash.QstashError && error.status === 404) {
|
|
91
|
-
await debug?.log("WARN", "ENDPOINT_START", {
|
|
92
|
-
message: "Couldn't fetch workflow run steps. This can happen if the workflow run succesfully ends before some callback is executed.",
|
|
93
|
-
error
|
|
94
|
-
});
|
|
95
|
-
return { steps: void 0, workflowRunEnded: true };
|
|
96
|
-
} else {
|
|
97
|
-
throw error;
|
|
98
|
-
}
|
|
99
|
-
}
|
|
100
|
-
};
|
|
50
|
+
var import_qstash2 = require("@upstash/qstash");
|
|
101
51
|
|
|
102
52
|
// src/error.ts
|
|
103
|
-
var
|
|
104
|
-
var WorkflowError = class extends
|
|
53
|
+
var import_qstash = require("@upstash/qstash");
|
|
54
|
+
var WorkflowError = class extends import_qstash.QstashError {
|
|
105
55
|
constructor(message) {
|
|
106
56
|
super(message);
|
|
107
57
|
this.name = "WorkflowError";
|
|
@@ -140,6 +90,19 @@ var WorkflowNonRetryableError = class extends WorkflowAbort {
|
|
|
140
90
|
if (message) this.message = message;
|
|
141
91
|
}
|
|
142
92
|
};
|
|
93
|
+
var WorkflowRetryAfterError = class extends WorkflowAbort {
|
|
94
|
+
retryAfter;
|
|
95
|
+
/**
|
|
96
|
+
* @param retryAfter time in seconds after which the workflow should be retried
|
|
97
|
+
* @param message error message to be displayed
|
|
98
|
+
*/
|
|
99
|
+
constructor(message, retryAfter) {
|
|
100
|
+
super("retry", void 0, false);
|
|
101
|
+
this.name = "WorkflowRetryAfterError";
|
|
102
|
+
this.retryAfter = retryAfter;
|
|
103
|
+
if (message) this.message = message;
|
|
104
|
+
}
|
|
105
|
+
};
|
|
143
106
|
var formatWorkflowError = (error) => {
|
|
144
107
|
return error instanceof Error ? {
|
|
145
108
|
error: error.name,
|
|
@@ -150,6 +113,79 @@ var formatWorkflowError = (error) => {
|
|
|
150
113
|
message: `An error occured while executing workflow: '${typeof error === "string" ? error : JSON.stringify(error)}'`
|
|
151
114
|
};
|
|
152
115
|
};
|
|
116
|
+
function getConstructorName(obj) {
|
|
117
|
+
if (obj === null || obj === void 0) {
|
|
118
|
+
return null;
|
|
119
|
+
}
|
|
120
|
+
const ctor = obj.constructor;
|
|
121
|
+
if (!ctor || ctor.name === "Object") {
|
|
122
|
+
return null;
|
|
123
|
+
}
|
|
124
|
+
return ctor.name;
|
|
125
|
+
}
|
|
126
|
+
function getConstructorNames(obj) {
|
|
127
|
+
const proto = Object.getPrototypeOf(obj);
|
|
128
|
+
const name = getConstructorName(proto);
|
|
129
|
+
if (name === null) {
|
|
130
|
+
return [];
|
|
131
|
+
}
|
|
132
|
+
return [name, ...getConstructorNames(proto)];
|
|
133
|
+
}
|
|
134
|
+
function isInstanceOf(v, ctor) {
|
|
135
|
+
return getConstructorNames(v).includes(ctor.name);
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
// src/client/utils.ts
|
|
139
|
+
var makeNotifyRequest = async (requester, eventId, eventData) => {
|
|
140
|
+
const result = await requester.request({
|
|
141
|
+
path: ["v2", "notify", eventId],
|
|
142
|
+
method: "POST",
|
|
143
|
+
body: typeof eventData === "string" ? eventData : JSON.stringify(eventData)
|
|
144
|
+
});
|
|
145
|
+
return result;
|
|
146
|
+
};
|
|
147
|
+
var makeCancelRequest = async (requester, workflowRunId) => {
|
|
148
|
+
await requester.request({
|
|
149
|
+
path: ["v2", "workflows", "runs", `${workflowRunId}?cancel=true`],
|
|
150
|
+
method: "DELETE",
|
|
151
|
+
parseResponseAsJson: false
|
|
152
|
+
});
|
|
153
|
+
return true;
|
|
154
|
+
};
|
|
155
|
+
var getSteps = async (requester, workflowRunId, messageId, debug) => {
|
|
156
|
+
try {
|
|
157
|
+
const steps = await requester.request({
|
|
158
|
+
path: ["v2", "workflows", "runs", workflowRunId],
|
|
159
|
+
parseResponseAsJson: true
|
|
160
|
+
});
|
|
161
|
+
if (!messageId) {
|
|
162
|
+
await debug?.log("INFO", "ENDPOINT_START", {
|
|
163
|
+
message: `Pulled ${steps.length} steps from QStashand returned them without filtering with messageId.`
|
|
164
|
+
});
|
|
165
|
+
return { steps, workflowRunEnded: false };
|
|
166
|
+
} else {
|
|
167
|
+
const index = steps.findIndex((item) => item.messageId === messageId);
|
|
168
|
+
if (index === -1) {
|
|
169
|
+
return { steps: [], workflowRunEnded: false };
|
|
170
|
+
}
|
|
171
|
+
const filteredSteps = steps.slice(0, index + 1);
|
|
172
|
+
await debug?.log("INFO", "ENDPOINT_START", {
|
|
173
|
+
message: `Pulled ${steps.length} steps from QStash and filtered them to ${filteredSteps.length} using messageId.`
|
|
174
|
+
});
|
|
175
|
+
return { steps: filteredSteps, workflowRunEnded: false };
|
|
176
|
+
}
|
|
177
|
+
} catch (error) {
|
|
178
|
+
if (isInstanceOf(error, import_qstash2.QstashError) && error.status === 404) {
|
|
179
|
+
await debug?.log("WARN", "ENDPOINT_START", {
|
|
180
|
+
message: "Couldn't fetch workflow run steps. This can happen if the workflow run succesfully ends before some callback is executed.",
|
|
181
|
+
error
|
|
182
|
+
});
|
|
183
|
+
return { steps: void 0, workflowRunEnded: true };
|
|
184
|
+
} else {
|
|
185
|
+
throw error;
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
};
|
|
153
189
|
|
|
154
190
|
// src/context/auto-executor.ts
|
|
155
191
|
var import_qstash5 = require("@upstash/qstash");
|
|
@@ -710,17 +746,17 @@ var triggerRouteFunction = async ({
|
|
|
710
746
|
return ok("workflow-finished");
|
|
711
747
|
} catch (error) {
|
|
712
748
|
const error_ = error;
|
|
713
|
-
if (error
|
|
749
|
+
if (isInstanceOf(error, import_qstash3.QstashError) && error.status === 400) {
|
|
714
750
|
await debug?.log("WARN", "RESPONSE_WORKFLOW", {
|
|
715
751
|
message: `tried to append to a cancelled workflow. exiting without publishing.`,
|
|
716
752
|
name: error.name,
|
|
717
753
|
errorMessage: error.message
|
|
718
754
|
});
|
|
719
755
|
return ok("workflow-was-finished");
|
|
720
|
-
} else if (
|
|
721
|
-
return err(error_);
|
|
722
|
-
} else if (error_ instanceof WorkflowNonRetryableError) {
|
|
756
|
+
} else if (isInstanceOf(error_, WorkflowNonRetryableError) || isInstanceOf(error_, WorkflowRetryAfterError)) {
|
|
723
757
|
return ok(error_);
|
|
758
|
+
} else if (!isInstanceOf(error_, WorkflowAbort)) {
|
|
759
|
+
return err(error_);
|
|
724
760
|
} else if (error_.cancelWorkflow) {
|
|
725
761
|
await onCancel();
|
|
726
762
|
return ok("workflow-finished");
|
|
@@ -2027,7 +2063,7 @@ var AutoExecutor = class _AutoExecutor {
|
|
|
2027
2063
|
});
|
|
2028
2064
|
throw new WorkflowAbort(parallelStep.stepName, resultStep);
|
|
2029
2065
|
} catch (error) {
|
|
2030
|
-
if (error
|
|
2066
|
+
if (isInstanceOf(error, WorkflowAbort) || isInstanceOf(error, import_qstash5.QstashError) && error.status === 400) {
|
|
2031
2067
|
throw error;
|
|
2032
2068
|
}
|
|
2033
2069
|
throw new WorkflowError(
|
|
@@ -2134,7 +2170,7 @@ var validateParallelSteps = (lazySteps, stepsFromRequest) => {
|
|
|
2134
2170
|
validateStep(lazySteps[index], stepFromRequest);
|
|
2135
2171
|
}
|
|
2136
2172
|
} catch (error) {
|
|
2137
|
-
if (error
|
|
2173
|
+
if (isInstanceOf(error, WorkflowError)) {
|
|
2138
2174
|
const lazyStepNames = lazySteps.map((lazyStep) => lazyStep.stepName);
|
|
2139
2175
|
const lazyStepTypes = lazySteps.map((lazyStep) => lazyStep.stepType);
|
|
2140
2176
|
const requestStepNames = stepsFromRequest.map((step) => step.stepName);
|
|
@@ -2315,7 +2351,7 @@ var fetchWithContextCall = async (context, agentCallParams, ...params) => {
|
|
|
2315
2351
|
headers: responseHeaders
|
|
2316
2352
|
});
|
|
2317
2353
|
} catch (error) {
|
|
2318
|
-
if (error instanceof Error && error
|
|
2354
|
+
if (error instanceof Error && isInstanceOf(error, WorkflowAbort)) {
|
|
2319
2355
|
throw error;
|
|
2320
2356
|
} else {
|
|
2321
2357
|
console.error("Error in fetch implementation:", error);
|
|
@@ -2417,10 +2453,10 @@ var Agent = class {
|
|
|
2417
2453
|
});
|
|
2418
2454
|
return { text: result.text };
|
|
2419
2455
|
} catch (error) {
|
|
2420
|
-
if (error
|
|
2421
|
-
if (error.cause instanceof Error && error.cause
|
|
2456
|
+
if (isInstanceOf(error, import_ai2.ToolExecutionError)) {
|
|
2457
|
+
if (error.cause instanceof Error && isInstanceOf(error.cause, WorkflowAbort)) {
|
|
2422
2458
|
throw error.cause;
|
|
2423
|
-
} else if (error.cause
|
|
2459
|
+
} else if (isInstanceOf(error.cause, import_ai2.ToolExecutionError) && isInstanceOf(error.cause.cause, WorkflowAbort)) {
|
|
2424
2460
|
throw error.cause.cause;
|
|
2425
2461
|
} else {
|
|
2426
2462
|
throw error;
|
|
@@ -3169,7 +3205,7 @@ var DisabledWorkflowContext = class _DisabledWorkflowContext extends WorkflowCon
|
|
|
3169
3205
|
try {
|
|
3170
3206
|
await routeFunction(disabledContext);
|
|
3171
3207
|
} catch (error) {
|
|
3172
|
-
if (error
|
|
3208
|
+
if (isInstanceOf(error, WorkflowAbort) && error.stepName === this.disabledMessage || isInstanceOf(error, WorkflowNonRetryableError) || isInstanceOf(error, WorkflowRetryAfterError)) {
|
|
3173
3209
|
return ok("step-found");
|
|
3174
3210
|
}
|
|
3175
3211
|
console.warn(
|
|
@@ -3422,13 +3458,24 @@ var processOptions = (options) => {
|
|
|
3422
3458
|
},
|
|
3423
3459
|
status: 489
|
|
3424
3460
|
});
|
|
3425
|
-
} else if (detailedFinishCondition?.condition === "
|
|
3426
|
-
return new Response(detailedFinishCondition.result
|
|
3427
|
-
status: 200,
|
|
3461
|
+
} else if (detailedFinishCondition?.condition === "retry-after-error") {
|
|
3462
|
+
return new Response(JSON.stringify(formatWorkflowError(detailedFinishCondition.result)), {
|
|
3428
3463
|
headers: {
|
|
3464
|
+
"Retry-After": detailedFinishCondition.result.retryAfter.toString(),
|
|
3429
3465
|
[WORKFLOW_PROTOCOL_VERSION_HEADER]: WORKFLOW_PROTOCOL_VERSION
|
|
3430
|
-
}
|
|
3466
|
+
},
|
|
3467
|
+
status: 429
|
|
3431
3468
|
});
|
|
3469
|
+
} else if (detailedFinishCondition?.condition === "failure-callback") {
|
|
3470
|
+
return new Response(
|
|
3471
|
+
JSON.stringify({ result: detailedFinishCondition.result ?? void 0 }),
|
|
3472
|
+
{
|
|
3473
|
+
status: 200,
|
|
3474
|
+
headers: {
|
|
3475
|
+
[WORKFLOW_PROTOCOL_VERSION_HEADER]: WORKFLOW_PROTOCOL_VERSION
|
|
3476
|
+
}
|
|
3477
|
+
}
|
|
3478
|
+
);
|
|
3432
3479
|
}
|
|
3433
3480
|
return new Response(JSON.stringify({ workflowRunId }), {
|
|
3434
3481
|
status: 200,
|
|
@@ -3638,12 +3685,18 @@ var serveBase = (routeFunction, telemetry2, options) => {
|
|
|
3638
3685
|
},
|
|
3639
3686
|
debug
|
|
3640
3687
|
});
|
|
3641
|
-
if (result.isOk() && result.value
|
|
3688
|
+
if (result.isOk() && isInstanceOf(result.value, WorkflowNonRetryableError)) {
|
|
3642
3689
|
return onStepFinish(workflowRunId, result.value, {
|
|
3643
3690
|
condition: "non-retryable-error",
|
|
3644
3691
|
result: result.value
|
|
3645
3692
|
});
|
|
3646
3693
|
}
|
|
3694
|
+
if (result.isOk() && isInstanceOf(result.value, WorkflowRetryAfterError)) {
|
|
3695
|
+
return onStepFinish(workflowRunId, result.value, {
|
|
3696
|
+
condition: "retry-after-error",
|
|
3697
|
+
result: result.value
|
|
3698
|
+
});
|
|
3699
|
+
}
|
|
3647
3700
|
if (result.isErr()) {
|
|
3648
3701
|
await debug?.log("ERROR", "ERROR", { error: result.error.message });
|
|
3649
3702
|
throw result.error;
|
|
@@ -3674,7 +3727,7 @@ var serveBase = (routeFunction, telemetry2, options) => {
|
|
|
3674
3727
|
const errorMessage = `Error while running onError callback: '${formattedOnErrorError.message}'.
|
|
3675
3728
|
Original error: '${formattedError.message}'`;
|
|
3676
3729
|
console.error(errorMessage);
|
|
3677
|
-
return new Response(errorMessage, {
|
|
3730
|
+
return new Response(JSON.stringify({ error: errorMessage }), {
|
|
3678
3731
|
status: 500,
|
|
3679
3732
|
headers: {
|
|
3680
3733
|
[WORKFLOW_PROTOCOL_VERSION_HEADER]: WORKFLOW_PROTOCOL_VERSION
|
package/cloudflare.mjs
CHANGED
package/express.d.mts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import * as express_serve_static_core from 'express-serve-static-core';
|
|
2
|
-
import { R as RouteFunction, W as WorkflowServeOptions,
|
|
2
|
+
import { R as RouteFunction, W as WorkflowServeOptions, z as InvokableWorkflow } from './types-9nCq6bRP.mjs';
|
|
3
3
|
import { Router } from 'express';
|
|
4
|
-
import { s as serveManyBase } from './serve-many-
|
|
4
|
+
import { s as serveManyBase } from './serve-many-CctdYIfB.mjs';
|
|
5
5
|
import '@upstash/qstash';
|
|
6
6
|
import 'zod';
|
|
7
7
|
import 'ai';
|
package/express.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import * as express_serve_static_core from 'express-serve-static-core';
|
|
2
|
-
import { R as RouteFunction, W as WorkflowServeOptions,
|
|
2
|
+
import { R as RouteFunction, W as WorkflowServeOptions, z as InvokableWorkflow } from './types-9nCq6bRP.js';
|
|
3
3
|
import { Router } from 'express';
|
|
4
|
-
import { s as serveManyBase } from './serve-many-
|
|
4
|
+
import { s as serveManyBase } from './serve-many-BXDr30rl.js';
|
|
5
5
|
import '@upstash/qstash';
|
|
6
6
|
import 'zod';
|
|
7
7
|
import 'ai';
|