@upstash/workflow 0.2.13 → 0.2.15
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 +2 -2
- package/astro.d.ts +2 -2
- package/astro.js +92 -57
- package/astro.mjs +1 -1
- package/{chunk-XVNSBBDC.mjs → chunk-AC5CQCN3.mjs} +94 -57
- package/cloudflare.d.mts +2 -2
- package/cloudflare.d.ts +2 -2
- package/cloudflare.js +92 -57
- package/cloudflare.mjs +1 -1
- package/express.d.mts +2 -2
- package/express.d.ts +2 -2
- package/express.js +92 -57
- package/express.mjs +1 -1
- package/h3.d.mts +2 -2
- package/h3.d.ts +2 -2
- package/h3.js +92 -57
- package/h3.mjs +1 -1
- package/hono.d.mts +2 -2
- package/hono.d.ts +2 -2
- package/hono.js +92 -57
- package/hono.mjs +1 -1
- package/index.d.mts +270 -42
- package/index.d.ts +270 -42
- package/index.js +206 -119
- package/index.mjs +117 -63
- package/nextjs.d.mts +2 -2
- package/nextjs.d.ts +2 -2
- package/nextjs.js +92 -57
- package/nextjs.mjs +1 -1
- package/package.json +1 -1
- package/{serve-many-BF71QZHQ.d.mts → serve-many-AFwJPR3S.d.mts} +1 -1
- package/{serve-many-BMlN2PAB.d.ts → serve-many-AaKSQyi7.d.ts} +1 -1
- package/solidjs.d.mts +1 -1
- package/solidjs.d.ts +1 -1
- package/solidjs.js +92 -57
- package/solidjs.mjs +1 -1
- package/svelte.d.mts +2 -2
- package/svelte.d.ts +2 -2
- package/svelte.js +92 -57
- package/svelte.mjs +1 -1
- package/{types-C1WIgVLA.d.ts → types-Dd-3bPoU.d.mts} +39 -4
- package/{types-C1WIgVLA.d.mts → types-Dd-3bPoU.d.ts} +39 -4
package/index.js
CHANGED
|
@@ -26,6 +26,7 @@ __export(src_exports, {
|
|
|
26
26
|
WorkflowContext: () => WorkflowContext,
|
|
27
27
|
WorkflowError: () => WorkflowError,
|
|
28
28
|
WorkflowLogger: () => WorkflowLogger,
|
|
29
|
+
WorkflowNonRetryableError: () => WorkflowNonRetryableError,
|
|
29
30
|
WorkflowTool: () => WorkflowTool,
|
|
30
31
|
serve: () => serve
|
|
31
32
|
});
|
|
@@ -103,7 +104,7 @@ var WORKFLOW_PROTOCOL_VERSION_HEADER = "Upstash-Workflow-Sdk-Version";
|
|
|
103
104
|
var DEFAULT_CONTENT_TYPE = "application/json";
|
|
104
105
|
var NO_CONCURRENCY = 1;
|
|
105
106
|
var DEFAULT_RETRIES = 3;
|
|
106
|
-
var VERSION = "v0.2.
|
|
107
|
+
var VERSION = "v0.2.15";
|
|
107
108
|
var SDK_TELEMETRY = `@upstash/workflow@${VERSION}`;
|
|
108
109
|
var TELEMETRY_HEADER_SDK = "Upstash-Telemetry-Sdk";
|
|
109
110
|
var TELEMETRY_HEADER_FRAMEWORK = "Upstash-Telemetry-Framework";
|
|
@@ -141,6 +142,16 @@ var WorkflowAbort = class extends Error {
|
|
|
141
142
|
this.cancelWorkflow = cancelWorkflow;
|
|
142
143
|
}
|
|
143
144
|
};
|
|
145
|
+
var WorkflowNonRetryableError = class extends WorkflowAbort {
|
|
146
|
+
/**
|
|
147
|
+
* @param message error message to be displayed
|
|
148
|
+
*/
|
|
149
|
+
constructor(message) {
|
|
150
|
+
super("fail", void 0, false);
|
|
151
|
+
this.name = "WorkflowNonRetryableError";
|
|
152
|
+
if (message) this.message = message;
|
|
153
|
+
}
|
|
154
|
+
};
|
|
144
155
|
var formatWorkflowError = (error) => {
|
|
145
156
|
return error instanceof Error ? {
|
|
146
157
|
error: error.name,
|
|
@@ -611,59 +622,72 @@ var StepTypes = [
|
|
|
611
622
|
|
|
612
623
|
// src/workflow-requests.ts
|
|
613
624
|
var import_qstash3 = require("@upstash/qstash");
|
|
614
|
-
var triggerFirstInvocation = async ({
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
}
|
|
642
|
-
try {
|
|
643
|
-
const body = typeof workflowContext.requestPayload === "string" ? workflowContext.requestPayload : JSON.stringify(workflowContext.requestPayload);
|
|
644
|
-
const result = await workflowContext.qstashClient.publish({
|
|
645
|
-
headers,
|
|
646
|
-
method: "POST",
|
|
647
|
-
body,
|
|
648
|
-
url: workflowContext.url,
|
|
649
|
-
delay
|
|
650
|
-
});
|
|
651
|
-
if (result.deduplicated) {
|
|
652
|
-
await debug?.log("WARN", "SUBMIT_FIRST_INVOCATION", {
|
|
653
|
-
message: `Workflow run ${workflowContext.workflowRunId} already exists. A new one isn't created.`,
|
|
625
|
+
var triggerFirstInvocation = async (params) => {
|
|
626
|
+
const firstInvocationParams = Array.isArray(params) ? params : [params];
|
|
627
|
+
const workflowContextClient = firstInvocationParams[0].workflowContext.qstashClient;
|
|
628
|
+
const invocationBatch = firstInvocationParams.map(
|
|
629
|
+
({ workflowContext, useJSONContent, telemetry, invokeCount, delay }) => {
|
|
630
|
+
const { headers } = getHeaders({
|
|
631
|
+
initHeaderValue: "true",
|
|
632
|
+
workflowConfig: {
|
|
633
|
+
workflowRunId: workflowContext.workflowRunId,
|
|
634
|
+
workflowUrl: workflowContext.url,
|
|
635
|
+
failureUrl: workflowContext.failureUrl,
|
|
636
|
+
retries: workflowContext.retries,
|
|
637
|
+
telemetry,
|
|
638
|
+
flowControl: workflowContext.flowControl,
|
|
639
|
+
useJSONContent: useJSONContent ?? false
|
|
640
|
+
},
|
|
641
|
+
invokeCount: invokeCount ?? 0,
|
|
642
|
+
userHeaders: workflowContext.headers
|
|
643
|
+
});
|
|
644
|
+
if (workflowContext.headers.get("content-type")) {
|
|
645
|
+
headers["content-type"] = workflowContext.headers.get("content-type");
|
|
646
|
+
}
|
|
647
|
+
if (useJSONContent) {
|
|
648
|
+
headers["content-type"] = "application/json";
|
|
649
|
+
}
|
|
650
|
+
const body = typeof workflowContext.requestPayload === "string" ? workflowContext.requestPayload : JSON.stringify(workflowContext.requestPayload);
|
|
651
|
+
return {
|
|
654
652
|
headers,
|
|
655
|
-
|
|
653
|
+
method: "POST",
|
|
654
|
+
body,
|
|
656
655
|
url: workflowContext.url,
|
|
657
|
-
|
|
658
|
-
}
|
|
656
|
+
delay
|
|
657
|
+
};
|
|
658
|
+
}
|
|
659
|
+
);
|
|
660
|
+
try {
|
|
661
|
+
const results = await workflowContextClient.batch(invocationBatch);
|
|
662
|
+
const invocationStatuses = [];
|
|
663
|
+
for (let i = 0; i < results.length; i++) {
|
|
664
|
+
const result = results[i];
|
|
665
|
+
const invocationParams = firstInvocationParams[i];
|
|
666
|
+
if (result.deduplicated) {
|
|
667
|
+
await invocationParams.debug?.log("WARN", "SUBMIT_FIRST_INVOCATION", {
|
|
668
|
+
message: `Workflow run ${invocationParams.workflowContext.workflowRunId} already exists. A new one isn't created.`,
|
|
669
|
+
headers: invocationBatch[i].headers,
|
|
670
|
+
requestPayload: invocationParams.workflowContext.requestPayload,
|
|
671
|
+
url: invocationParams.workflowContext.url,
|
|
672
|
+
messageId: result.messageId
|
|
673
|
+
});
|
|
674
|
+
invocationStatuses.push("workflow-run-already-exists");
|
|
675
|
+
} else {
|
|
676
|
+
await invocationParams.debug?.log("SUBMIT", "SUBMIT_FIRST_INVOCATION", {
|
|
677
|
+
headers: invocationBatch[i].headers,
|
|
678
|
+
requestPayload: invocationParams.workflowContext.requestPayload,
|
|
679
|
+
url: invocationParams.workflowContext.url,
|
|
680
|
+
messageId: result.messageId
|
|
681
|
+
});
|
|
682
|
+
invocationStatuses.push("success");
|
|
683
|
+
}
|
|
684
|
+
}
|
|
685
|
+
const hasAnyDeduplicated = invocationStatuses.some(
|
|
686
|
+
(status) => status === "workflow-run-already-exists"
|
|
687
|
+
);
|
|
688
|
+
if (hasAnyDeduplicated) {
|
|
659
689
|
return ok("workflow-run-already-exists");
|
|
660
690
|
} else {
|
|
661
|
-
await debug?.log("SUBMIT", "SUBMIT_FIRST_INVOCATION", {
|
|
662
|
-
headers,
|
|
663
|
-
requestPayload: workflowContext.requestPayload,
|
|
664
|
-
url: workflowContext.url,
|
|
665
|
-
messageId: result.messageId
|
|
666
|
-
});
|
|
667
691
|
return ok("success");
|
|
668
692
|
}
|
|
669
693
|
} catch (error) {
|
|
@@ -692,6 +716,8 @@ var triggerRouteFunction = async ({
|
|
|
692
716
|
return ok("workflow-was-finished");
|
|
693
717
|
} else if (!(error_ instanceof WorkflowAbort)) {
|
|
694
718
|
return err(error_);
|
|
719
|
+
} else if (error_ instanceof WorkflowNonRetryableError) {
|
|
720
|
+
return ok(error_);
|
|
695
721
|
} else if (error_.cancelWorkflow) {
|
|
696
722
|
await onCancel();
|
|
697
723
|
return ok("workflow-finished");
|
|
@@ -853,7 +879,7 @@ ${atob(callbackMessage.body ?? "")}`
|
|
|
853
879
|
var getTelemetryHeaders = (telemetry) => {
|
|
854
880
|
return {
|
|
855
881
|
[TELEMETRY_HEADER_SDK]: telemetry.sdk,
|
|
856
|
-
[TELEMETRY_HEADER_FRAMEWORK]: telemetry.framework,
|
|
882
|
+
[TELEMETRY_HEADER_FRAMEWORK]: telemetry.framework ?? "unknown",
|
|
857
883
|
[TELEMETRY_HEADER_RUNTIME]: telemetry.runtime ?? "unknown"
|
|
858
884
|
};
|
|
859
885
|
};
|
|
@@ -1153,7 +1179,7 @@ var LazyCallStep = class _LazyCallStep extends BaseLazyStep {
|
|
|
1153
1179
|
return { header, status, body };
|
|
1154
1180
|
}
|
|
1155
1181
|
}
|
|
1156
|
-
static
|
|
1182
|
+
static applicationContentTypes = [
|
|
1157
1183
|
"application/json",
|
|
1158
1184
|
"application/xml",
|
|
1159
1185
|
"application/javascript",
|
|
@@ -1162,12 +1188,12 @@ var LazyCallStep = class _LazyCallStep extends BaseLazyStep {
|
|
|
1162
1188
|
"application/ld+json",
|
|
1163
1189
|
"application/rss+xml",
|
|
1164
1190
|
"application/atom+xml"
|
|
1165
|
-
]
|
|
1191
|
+
];
|
|
1166
1192
|
static isText = (contentTypeHeader) => {
|
|
1167
1193
|
if (!contentTypeHeader) {
|
|
1168
1194
|
return false;
|
|
1169
1195
|
}
|
|
1170
|
-
if (_LazyCallStep.
|
|
1196
|
+
if (_LazyCallStep.applicationContentTypes.some((type) => contentTypeHeader.includes(type))) {
|
|
1171
1197
|
return true;
|
|
1172
1198
|
}
|
|
1173
1199
|
if (contentTypeHeader.startsWith("text/")) {
|
|
@@ -2935,10 +2961,10 @@ var DisabledWorkflowContext = class _DisabledWorkflowContext extends WorkflowCon
|
|
|
2935
2961
|
throw new WorkflowAbort(_DisabledWorkflowContext.disabledMessage);
|
|
2936
2962
|
}
|
|
2937
2963
|
/**
|
|
2938
|
-
* overwrite cancel method to
|
|
2964
|
+
* overwrite cancel method to throw WorkflowAbort with the disabledMessage
|
|
2939
2965
|
*/
|
|
2940
2966
|
async cancel() {
|
|
2941
|
-
|
|
2967
|
+
throw new WorkflowAbort(_DisabledWorkflowContext.disabledMessage);
|
|
2942
2968
|
}
|
|
2943
2969
|
/**
|
|
2944
2970
|
* copies the passed context to create a DisabledWorkflowContext. Then, runs the
|
|
@@ -2970,7 +2996,7 @@ var DisabledWorkflowContext = class _DisabledWorkflowContext extends WorkflowCon
|
|
|
2970
2996
|
try {
|
|
2971
2997
|
await routeFunction(disabledContext);
|
|
2972
2998
|
} catch (error) {
|
|
2973
|
-
if (error instanceof WorkflowAbort && error.stepName === this.disabledMessage) {
|
|
2999
|
+
if (error instanceof WorkflowAbort && error.stepName === this.disabledMessage || error instanceof WorkflowNonRetryableError) {
|
|
2974
3000
|
return ok("step-found");
|
|
2975
3001
|
}
|
|
2976
3002
|
return err(error);
|
|
@@ -3191,6 +3217,13 @@ var processOptions = (options) => {
|
|
|
3191
3217
|
status: 400
|
|
3192
3218
|
}
|
|
3193
3219
|
);
|
|
3220
|
+
} else if (finishCondition instanceof WorkflowNonRetryableError) {
|
|
3221
|
+
return new Response(JSON.stringify(formatWorkflowError(finishCondition)), {
|
|
3222
|
+
headers: {
|
|
3223
|
+
"Upstash-NonRetryable-Error": "true"
|
|
3224
|
+
},
|
|
3225
|
+
status: 489
|
|
3226
|
+
});
|
|
3194
3227
|
}
|
|
3195
3228
|
return new Response(JSON.stringify({ workflowRunId }), {
|
|
3196
3229
|
status: 200
|
|
@@ -3383,6 +3416,9 @@ var serveBase = (routeFunction, telemetry, options) => {
|
|
|
3383
3416
|
},
|
|
3384
3417
|
debug
|
|
3385
3418
|
});
|
|
3419
|
+
if (result.isOk() && result.value instanceof WorkflowNonRetryableError) {
|
|
3420
|
+
return onStepFinish(workflowRunId, result.value);
|
|
3421
|
+
}
|
|
3386
3422
|
if (result.isErr()) {
|
|
3387
3423
|
await debug?.log("ERROR", "ERROR", { error: result.error.message });
|
|
3388
3424
|
throw result.error;
|
|
@@ -3431,6 +3467,86 @@ var serve = (routeFunction, options) => {
|
|
|
3431
3467
|
|
|
3432
3468
|
// src/client/index.ts
|
|
3433
3469
|
var import_qstash12 = require("@upstash/qstash");
|
|
3470
|
+
|
|
3471
|
+
// src/client/dlq.ts
|
|
3472
|
+
var DLQ = class _DLQ {
|
|
3473
|
+
constructor(client) {
|
|
3474
|
+
this.client = client;
|
|
3475
|
+
}
|
|
3476
|
+
/**
|
|
3477
|
+
* list the items in the DLQ
|
|
3478
|
+
*
|
|
3479
|
+
* @param cursor - Optional cursor for pagination.
|
|
3480
|
+
* @param count - Optional number of items to return.
|
|
3481
|
+
* @param filter - Optional filter options to apply to the DLQ items.
|
|
3482
|
+
* The available filter options are:
|
|
3483
|
+
* - `fromDate`: Filter items which entered the DLQ after this date.
|
|
3484
|
+
* - `toDate`: Filter items which entered the DLQ before this date.
|
|
3485
|
+
* - `url`: Filter items by the URL they were sent to.
|
|
3486
|
+
* - `responseStatus`: Filter items by the response status code.
|
|
3487
|
+
* @returns
|
|
3488
|
+
*/
|
|
3489
|
+
async list(parameters) {
|
|
3490
|
+
const { cursor, count, filter } = parameters || {};
|
|
3491
|
+
return await this.client.http.request({
|
|
3492
|
+
path: ["v2", "dlq"],
|
|
3493
|
+
method: "GET",
|
|
3494
|
+
query: {
|
|
3495
|
+
cursor,
|
|
3496
|
+
count,
|
|
3497
|
+
...filter,
|
|
3498
|
+
source: "workflow"
|
|
3499
|
+
}
|
|
3500
|
+
});
|
|
3501
|
+
}
|
|
3502
|
+
async resume(parameters) {
|
|
3503
|
+
const { headers, queryParams } = _DLQ.handleDLQOptions(parameters);
|
|
3504
|
+
const { workflowRuns } = await this.client.http.request({
|
|
3505
|
+
path: ["v2", "workflows", "dlq", `resume?${queryParams}`],
|
|
3506
|
+
headers,
|
|
3507
|
+
method: "POST"
|
|
3508
|
+
});
|
|
3509
|
+
if (Array.isArray(parameters.dlqId)) {
|
|
3510
|
+
return workflowRuns;
|
|
3511
|
+
}
|
|
3512
|
+
return workflowRuns[0];
|
|
3513
|
+
}
|
|
3514
|
+
async restart(parameters) {
|
|
3515
|
+
const { headers, queryParams } = _DLQ.handleDLQOptions(parameters);
|
|
3516
|
+
const { workflowRuns } = await this.client.http.request({
|
|
3517
|
+
path: ["v2", "workflows", "dlq", `restart?${queryParams}`],
|
|
3518
|
+
headers,
|
|
3519
|
+
method: "POST"
|
|
3520
|
+
});
|
|
3521
|
+
if (Array.isArray(parameters.dlqId)) {
|
|
3522
|
+
return workflowRuns;
|
|
3523
|
+
}
|
|
3524
|
+
return workflowRuns[0];
|
|
3525
|
+
}
|
|
3526
|
+
static handleDLQOptions(options) {
|
|
3527
|
+
const { dlqId, flowControl, retries } = options;
|
|
3528
|
+
const headers = {};
|
|
3529
|
+
if (flowControl) {
|
|
3530
|
+
const { flowControlKey, flowControlValue } = prepareFlowControl(flowControl);
|
|
3531
|
+
headers["Upstash-Flow-Control-Key"] = flowControlKey;
|
|
3532
|
+
headers["Upstash-Flow-Control-Value"] = flowControlValue;
|
|
3533
|
+
}
|
|
3534
|
+
if (retries !== void 0) {
|
|
3535
|
+
headers["Upstash-Retries"] = retries.toString();
|
|
3536
|
+
}
|
|
3537
|
+
return {
|
|
3538
|
+
queryParams: _DLQ.getDlqIdQueryParameter(dlqId),
|
|
3539
|
+
headers
|
|
3540
|
+
};
|
|
3541
|
+
}
|
|
3542
|
+
static getDlqIdQueryParameter(dlqId) {
|
|
3543
|
+
const dlqIds = Array.isArray(dlqId) ? dlqId : [dlqId];
|
|
3544
|
+
const paramsArray = dlqIds.map((id) => ["dlqIds", id]);
|
|
3545
|
+
return new URLSearchParams(paramsArray).toString();
|
|
3546
|
+
}
|
|
3547
|
+
};
|
|
3548
|
+
|
|
3549
|
+
// src/client/index.ts
|
|
3434
3550
|
var Client4 = class {
|
|
3435
3551
|
client;
|
|
3436
3552
|
constructor(clientConfig) {
|
|
@@ -3557,70 +3673,37 @@ var Client4 = class {
|
|
|
3557
3673
|
async getWaiters({ eventId }) {
|
|
3558
3674
|
return await makeGetWaitersRequest(this.client.http, eventId);
|
|
3559
3675
|
}
|
|
3560
|
-
|
|
3561
|
-
|
|
3562
|
-
|
|
3563
|
-
|
|
3564
|
-
|
|
3565
|
-
|
|
3566
|
-
|
|
3567
|
-
|
|
3568
|
-
|
|
3569
|
-
|
|
3570
|
-
|
|
3571
|
-
|
|
3572
|
-
|
|
3573
|
-
|
|
3574
|
-
|
|
3575
|
-
|
|
3576
|
-
|
|
3577
|
-
|
|
3578
|
-
|
|
3579
|
-
|
|
3580
|
-
|
|
3581
|
-
|
|
3582
|
-
|
|
3583
|
-
|
|
3584
|
-
* @param retries retry to use in the initial request. in the rest of
|
|
3585
|
-
* the workflow, `retries` option of the `serve` will be used.
|
|
3586
|
-
* @param flowControl Settings for controlling the number of active requests
|
|
3587
|
-
* and number of requests per second with the same key.
|
|
3588
|
-
* @param delay Delay for the workflow run. This is used to delay the
|
|
3589
|
-
* execution of the workflow run. The delay is in seconds or can be passed
|
|
3590
|
-
* as a string with a time unit (e.g. "1h", "30m", "15s").
|
|
3591
|
-
* @returns workflow run id
|
|
3592
|
-
*/
|
|
3593
|
-
async trigger({
|
|
3594
|
-
url,
|
|
3595
|
-
body,
|
|
3596
|
-
headers,
|
|
3597
|
-
workflowRunId,
|
|
3598
|
-
retries,
|
|
3599
|
-
flowControl,
|
|
3600
|
-
delay
|
|
3601
|
-
}) {
|
|
3602
|
-
const finalWorkflowRunId = getWorkflowRunId(workflowRunId);
|
|
3603
|
-
const context = new WorkflowContext({
|
|
3604
|
-
qstashClient: this.client,
|
|
3605
|
-
// @ts-expect-error headers type mismatch
|
|
3606
|
-
headers: new Headers(headers ?? {}),
|
|
3607
|
-
initialPayload: body,
|
|
3608
|
-
steps: [],
|
|
3609
|
-
url,
|
|
3610
|
-
workflowRunId: finalWorkflowRunId,
|
|
3611
|
-
retries,
|
|
3612
|
-
telemetry: void 0,
|
|
3613
|
-
// can't know workflow telemetry here
|
|
3614
|
-
flowControl
|
|
3615
|
-
});
|
|
3616
|
-
const result = await triggerFirstInvocation({
|
|
3617
|
-
workflowContext: context,
|
|
3618
|
-
telemetry: void 0,
|
|
3619
|
-
// can't know workflow telemetry here
|
|
3620
|
-
delay
|
|
3676
|
+
async trigger(params) {
|
|
3677
|
+
const isBatchInput = Array.isArray(params);
|
|
3678
|
+
const options = isBatchInput ? params : [params];
|
|
3679
|
+
const invocations = options.map((option) => {
|
|
3680
|
+
const failureUrl = option.useFailureFunction ? option.url : option.failureUrl;
|
|
3681
|
+
const finalWorkflowRunId = getWorkflowRunId(option.workflowRunId);
|
|
3682
|
+
const context = new WorkflowContext({
|
|
3683
|
+
qstashClient: this.client,
|
|
3684
|
+
// @ts-expect-error headers type mismatch
|
|
3685
|
+
headers: new Headers(option.headers ?? {}),
|
|
3686
|
+
initialPayload: option.body,
|
|
3687
|
+
steps: [],
|
|
3688
|
+
url: option.url,
|
|
3689
|
+
workflowRunId: finalWorkflowRunId,
|
|
3690
|
+
retries: option.retries,
|
|
3691
|
+
telemetry: { sdk: SDK_TELEMETRY },
|
|
3692
|
+
flowControl: option.flowControl,
|
|
3693
|
+
failureUrl
|
|
3694
|
+
});
|
|
3695
|
+
return {
|
|
3696
|
+
workflowContext: context,
|
|
3697
|
+
telemetry: { sdk: SDK_TELEMETRY },
|
|
3698
|
+
delay: option.delay
|
|
3699
|
+
};
|
|
3621
3700
|
});
|
|
3701
|
+
const result = await triggerFirstInvocation(invocations);
|
|
3702
|
+
const workflowRunIds = invocations.map(
|
|
3703
|
+
(invocation) => invocation.workflowContext.workflowRunId
|
|
3704
|
+
);
|
|
3622
3705
|
if (result.isOk()) {
|
|
3623
|
-
return { workflowRunId:
|
|
3706
|
+
return isBatchInput ? workflowRunIds.map((id) => ({ workflowRunId: id })) : { workflowRunId: workflowRunIds[0] };
|
|
3624
3707
|
} else {
|
|
3625
3708
|
throw result.error;
|
|
3626
3709
|
}
|
|
@@ -3678,6 +3761,9 @@ var Client4 = class {
|
|
|
3678
3761
|
});
|
|
3679
3762
|
return result;
|
|
3680
3763
|
}
|
|
3764
|
+
get dlq() {
|
|
3765
|
+
return new DLQ(this.client);
|
|
3766
|
+
}
|
|
3681
3767
|
};
|
|
3682
3768
|
// Annotate the CommonJS export names for ESM import in node:
|
|
3683
3769
|
0 && (module.exports = {
|
|
@@ -3687,6 +3773,7 @@ var Client4 = class {
|
|
|
3687
3773
|
WorkflowContext,
|
|
3688
3774
|
WorkflowError,
|
|
3689
3775
|
WorkflowLogger,
|
|
3776
|
+
WorkflowNonRetryableError,
|
|
3690
3777
|
WorkflowTool,
|
|
3691
3778
|
serve
|
|
3692
3779
|
});
|
package/index.mjs
CHANGED
|
@@ -1,19 +1,102 @@
|
|
|
1
1
|
import {
|
|
2
|
+
SDK_TELEMETRY,
|
|
2
3
|
StepTypes,
|
|
3
4
|
WorkflowAbort,
|
|
4
5
|
WorkflowContext,
|
|
5
6
|
WorkflowError,
|
|
6
7
|
WorkflowLogger,
|
|
8
|
+
WorkflowNonRetryableError,
|
|
7
9
|
WorkflowTool,
|
|
8
10
|
getWorkflowRunId,
|
|
9
11
|
makeGetWaitersRequest,
|
|
10
12
|
makeNotifyRequest,
|
|
13
|
+
prepareFlowControl,
|
|
11
14
|
serve,
|
|
12
15
|
triggerFirstInvocation
|
|
13
|
-
} from "./chunk-
|
|
16
|
+
} from "./chunk-AC5CQCN3.mjs";
|
|
14
17
|
|
|
15
18
|
// src/client/index.ts
|
|
16
19
|
import { Client as QStashClient } from "@upstash/qstash";
|
|
20
|
+
|
|
21
|
+
// src/client/dlq.ts
|
|
22
|
+
var DLQ = class _DLQ {
|
|
23
|
+
constructor(client) {
|
|
24
|
+
this.client = client;
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* list the items in the DLQ
|
|
28
|
+
*
|
|
29
|
+
* @param cursor - Optional cursor for pagination.
|
|
30
|
+
* @param count - Optional number of items to return.
|
|
31
|
+
* @param filter - Optional filter options to apply to the DLQ items.
|
|
32
|
+
* The available filter options are:
|
|
33
|
+
* - `fromDate`: Filter items which entered the DLQ after this date.
|
|
34
|
+
* - `toDate`: Filter items which entered the DLQ before this date.
|
|
35
|
+
* - `url`: Filter items by the URL they were sent to.
|
|
36
|
+
* - `responseStatus`: Filter items by the response status code.
|
|
37
|
+
* @returns
|
|
38
|
+
*/
|
|
39
|
+
async list(parameters) {
|
|
40
|
+
const { cursor, count, filter } = parameters || {};
|
|
41
|
+
return await this.client.http.request({
|
|
42
|
+
path: ["v2", "dlq"],
|
|
43
|
+
method: "GET",
|
|
44
|
+
query: {
|
|
45
|
+
cursor,
|
|
46
|
+
count,
|
|
47
|
+
...filter,
|
|
48
|
+
source: "workflow"
|
|
49
|
+
}
|
|
50
|
+
});
|
|
51
|
+
}
|
|
52
|
+
async resume(parameters) {
|
|
53
|
+
const { headers, queryParams } = _DLQ.handleDLQOptions(parameters);
|
|
54
|
+
const { workflowRuns } = await this.client.http.request({
|
|
55
|
+
path: ["v2", "workflows", "dlq", `resume?${queryParams}`],
|
|
56
|
+
headers,
|
|
57
|
+
method: "POST"
|
|
58
|
+
});
|
|
59
|
+
if (Array.isArray(parameters.dlqId)) {
|
|
60
|
+
return workflowRuns;
|
|
61
|
+
}
|
|
62
|
+
return workflowRuns[0];
|
|
63
|
+
}
|
|
64
|
+
async restart(parameters) {
|
|
65
|
+
const { headers, queryParams } = _DLQ.handleDLQOptions(parameters);
|
|
66
|
+
const { workflowRuns } = await this.client.http.request({
|
|
67
|
+
path: ["v2", "workflows", "dlq", `restart?${queryParams}`],
|
|
68
|
+
headers,
|
|
69
|
+
method: "POST"
|
|
70
|
+
});
|
|
71
|
+
if (Array.isArray(parameters.dlqId)) {
|
|
72
|
+
return workflowRuns;
|
|
73
|
+
}
|
|
74
|
+
return workflowRuns[0];
|
|
75
|
+
}
|
|
76
|
+
static handleDLQOptions(options) {
|
|
77
|
+
const { dlqId, flowControl, retries } = options;
|
|
78
|
+
const headers = {};
|
|
79
|
+
if (flowControl) {
|
|
80
|
+
const { flowControlKey, flowControlValue } = prepareFlowControl(flowControl);
|
|
81
|
+
headers["Upstash-Flow-Control-Key"] = flowControlKey;
|
|
82
|
+
headers["Upstash-Flow-Control-Value"] = flowControlValue;
|
|
83
|
+
}
|
|
84
|
+
if (retries !== void 0) {
|
|
85
|
+
headers["Upstash-Retries"] = retries.toString();
|
|
86
|
+
}
|
|
87
|
+
return {
|
|
88
|
+
queryParams: _DLQ.getDlqIdQueryParameter(dlqId),
|
|
89
|
+
headers
|
|
90
|
+
};
|
|
91
|
+
}
|
|
92
|
+
static getDlqIdQueryParameter(dlqId) {
|
|
93
|
+
const dlqIds = Array.isArray(dlqId) ? dlqId : [dlqId];
|
|
94
|
+
const paramsArray = dlqIds.map((id) => ["dlqIds", id]);
|
|
95
|
+
return new URLSearchParams(paramsArray).toString();
|
|
96
|
+
}
|
|
97
|
+
};
|
|
98
|
+
|
|
99
|
+
// src/client/index.ts
|
|
17
100
|
var Client = class {
|
|
18
101
|
client;
|
|
19
102
|
constructor(clientConfig) {
|
|
@@ -140,70 +223,37 @@ var Client = class {
|
|
|
140
223
|
async getWaiters({ eventId }) {
|
|
141
224
|
return await makeGetWaitersRequest(this.client.http, eventId);
|
|
142
225
|
}
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
* @param retries retry to use in the initial request. in the rest of
|
|
168
|
-
* the workflow, `retries` option of the `serve` will be used.
|
|
169
|
-
* @param flowControl Settings for controlling the number of active requests
|
|
170
|
-
* and number of requests per second with the same key.
|
|
171
|
-
* @param delay Delay for the workflow run. This is used to delay the
|
|
172
|
-
* execution of the workflow run. The delay is in seconds or can be passed
|
|
173
|
-
* as a string with a time unit (e.g. "1h", "30m", "15s").
|
|
174
|
-
* @returns workflow run id
|
|
175
|
-
*/
|
|
176
|
-
async trigger({
|
|
177
|
-
url,
|
|
178
|
-
body,
|
|
179
|
-
headers,
|
|
180
|
-
workflowRunId,
|
|
181
|
-
retries,
|
|
182
|
-
flowControl,
|
|
183
|
-
delay
|
|
184
|
-
}) {
|
|
185
|
-
const finalWorkflowRunId = getWorkflowRunId(workflowRunId);
|
|
186
|
-
const context = new WorkflowContext({
|
|
187
|
-
qstashClient: this.client,
|
|
188
|
-
// @ts-expect-error headers type mismatch
|
|
189
|
-
headers: new Headers(headers ?? {}),
|
|
190
|
-
initialPayload: body,
|
|
191
|
-
steps: [],
|
|
192
|
-
url,
|
|
193
|
-
workflowRunId: finalWorkflowRunId,
|
|
194
|
-
retries,
|
|
195
|
-
telemetry: void 0,
|
|
196
|
-
// can't know workflow telemetry here
|
|
197
|
-
flowControl
|
|
198
|
-
});
|
|
199
|
-
const result = await triggerFirstInvocation({
|
|
200
|
-
workflowContext: context,
|
|
201
|
-
telemetry: void 0,
|
|
202
|
-
// can't know workflow telemetry here
|
|
203
|
-
delay
|
|
226
|
+
async trigger(params) {
|
|
227
|
+
const isBatchInput = Array.isArray(params);
|
|
228
|
+
const options = isBatchInput ? params : [params];
|
|
229
|
+
const invocations = options.map((option) => {
|
|
230
|
+
const failureUrl = option.useFailureFunction ? option.url : option.failureUrl;
|
|
231
|
+
const finalWorkflowRunId = getWorkflowRunId(option.workflowRunId);
|
|
232
|
+
const context = new WorkflowContext({
|
|
233
|
+
qstashClient: this.client,
|
|
234
|
+
// @ts-expect-error headers type mismatch
|
|
235
|
+
headers: new Headers(option.headers ?? {}),
|
|
236
|
+
initialPayload: option.body,
|
|
237
|
+
steps: [],
|
|
238
|
+
url: option.url,
|
|
239
|
+
workflowRunId: finalWorkflowRunId,
|
|
240
|
+
retries: option.retries,
|
|
241
|
+
telemetry: { sdk: SDK_TELEMETRY },
|
|
242
|
+
flowControl: option.flowControl,
|
|
243
|
+
failureUrl
|
|
244
|
+
});
|
|
245
|
+
return {
|
|
246
|
+
workflowContext: context,
|
|
247
|
+
telemetry: { sdk: SDK_TELEMETRY },
|
|
248
|
+
delay: option.delay
|
|
249
|
+
};
|
|
204
250
|
});
|
|
251
|
+
const result = await triggerFirstInvocation(invocations);
|
|
252
|
+
const workflowRunIds = invocations.map(
|
|
253
|
+
(invocation) => invocation.workflowContext.workflowRunId
|
|
254
|
+
);
|
|
205
255
|
if (result.isOk()) {
|
|
206
|
-
return { workflowRunId:
|
|
256
|
+
return isBatchInput ? workflowRunIds.map((id) => ({ workflowRunId: id })) : { workflowRunId: workflowRunIds[0] };
|
|
207
257
|
} else {
|
|
208
258
|
throw result.error;
|
|
209
259
|
}
|
|
@@ -261,6 +311,9 @@ var Client = class {
|
|
|
261
311
|
});
|
|
262
312
|
return result;
|
|
263
313
|
}
|
|
314
|
+
get dlq() {
|
|
315
|
+
return new DLQ(this.client);
|
|
316
|
+
}
|
|
264
317
|
};
|
|
265
318
|
export {
|
|
266
319
|
Client,
|
|
@@ -269,6 +322,7 @@ export {
|
|
|
269
322
|
WorkflowContext,
|
|
270
323
|
WorkflowError,
|
|
271
324
|
WorkflowLogger,
|
|
325
|
+
WorkflowNonRetryableError,
|
|
272
326
|
WorkflowTool,
|
|
273
327
|
serve
|
|
274
328
|
};
|
package/nextjs.d.mts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { NextApiHandler, NextApiRequest, NextApiResponse } from 'next';
|
|
2
|
-
import { R as RouteFunction,
|
|
3
|
-
import { s as serveManyBase } from './serve-many-
|
|
2
|
+
import { R as RouteFunction, n as PublicServeOptions, w as InvokableWorkflow } from './types-Dd-3bPoU.mjs';
|
|
3
|
+
import { s as serveManyBase } from './serve-many-AFwJPR3S.mjs';
|
|
4
4
|
import '@upstash/qstash';
|
|
5
5
|
import 'zod';
|
|
6
6
|
import 'ai';
|
package/nextjs.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { NextApiHandler, NextApiRequest, NextApiResponse } from 'next';
|
|
2
|
-
import { R as RouteFunction,
|
|
3
|
-
import { s as serveManyBase } from './serve-many-
|
|
2
|
+
import { R as RouteFunction, n as PublicServeOptions, w as InvokableWorkflow } from './types-Dd-3bPoU.js';
|
|
3
|
+
import { s as serveManyBase } from './serve-many-AaKSQyi7.js';
|
|
4
4
|
import '@upstash/qstash';
|
|
5
5
|
import 'zod';
|
|
6
6
|
import 'ai';
|