pg-workflows 0.13.1 → 0.14.0
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/dist/client.entry.cjs +62 -5
- package/dist/client.entry.d.cts +17 -0
- package/dist/client.entry.d.ts +17 -0
- package/dist/client.entry.js +1 -1
- package/dist/client.entry.js.map +9 -8
- package/dist/index.cjs +125 -77
- package/dist/index.d.cts +20 -1
- package/dist/index.d.ts +20 -1
- package/dist/index.js +67 -74
- package/dist/index.js.map +11 -10
- package/dist/shared/{chunk-5xswmve7.js → chunk-w3qcrrwx.js} +64 -7
- package/dist/shared/chunk-w3qcrrwx.js.map +17 -0
- package/package.json +1 -1
- package/dist/shared/chunk-5xswmve7.js.map +0 -16
package/dist/index.cjs
CHANGED
|
@@ -97,7 +97,7 @@ var isInvokeChildWorkflowTimelineEntry = (entry) => !!entry && typeof entry ===
|
|
|
97
97
|
|
|
98
98
|
// src/db/migration.ts
|
|
99
99
|
var MIGRATION_LOCK_ID = 738291645;
|
|
100
|
-
var CURRENT_SCHEMA_VERSION =
|
|
100
|
+
var CURRENT_SCHEMA_VERSION = 6;
|
|
101
101
|
async function runMigrations(db) {
|
|
102
102
|
if (await isSchemaUpToDate(db)) {
|
|
103
103
|
return;
|
|
@@ -105,6 +105,16 @@ async function runMigrations(db) {
|
|
|
105
105
|
const currentVersion = await getCurrentVersion(db);
|
|
106
106
|
const commands = [];
|
|
107
107
|
if (currentVersion < 1) {
|
|
108
|
+
const existing = await db.executeSql(`SELECT
|
|
109
|
+
to_regclass('workflow_runs') IS NOT NULL AS has_runs_table,
|
|
110
|
+
to_regclass('workflow_schema_version') IS NOT NULL AS has_version_table`, []);
|
|
111
|
+
const row = existing.rows[0];
|
|
112
|
+
if (row?.has_runs_table && !row.has_version_table) {
|
|
113
|
+
throw new Error(`pg-workflows: a "workflow_runs" table already exists in this schema but was not ` + `created by pg-workflows. Point the workflow engine at a dedicated schema/database.`);
|
|
114
|
+
}
|
|
115
|
+
if (!row?.has_runs_table && row?.has_version_table) {
|
|
116
|
+
throw new Error(`pg-workflows: a "workflow_schema_version" table already exists in this schema but was not ` + `created by pg-workflows. Point the workflow engine at a dedicated schema/database.`);
|
|
117
|
+
}
|
|
108
118
|
commands.push(`
|
|
109
119
|
CREATE TABLE IF NOT EXISTS workflow_runs (
|
|
110
120
|
id varchar(32) PRIMARY KEY NOT NULL,
|
|
@@ -163,6 +173,9 @@ async function runMigrations(db) {
|
|
|
163
173
|
if (currentVersion < 5) {
|
|
164
174
|
commands.push("ALTER TABLE workflow_runs ADD COLUMN IF NOT EXISTS scheduled_at timestamp with time zone");
|
|
165
175
|
}
|
|
176
|
+
if (currentVersion < 6) {
|
|
177
|
+
commands.push("ALTER TABLE workflow_runs ADD COLUMN IF NOT EXISTS priority integer DEFAULT 0 NOT NULL");
|
|
178
|
+
}
|
|
166
179
|
if (currentVersion === 0) {
|
|
167
180
|
commands.push(`INSERT INTO workflow_schema_version (version) VALUES (${CURRENT_SCHEMA_VERSION})`);
|
|
168
181
|
} else {
|
|
@@ -224,6 +237,7 @@ function mapRowToWorkflowRun(row) {
|
|
|
224
237
|
timeoutAt: row.timeout_at ? new Date(row.timeout_at) : null,
|
|
225
238
|
retryCount: row.retry_count,
|
|
226
239
|
maxRetries: row.max_retries,
|
|
240
|
+
priority: row.priority,
|
|
227
241
|
jobId: row.job_id,
|
|
228
242
|
idempotencyKey: row.idempotency_key,
|
|
229
243
|
parentRunId: row.parent_run_id,
|
|
@@ -239,6 +253,7 @@ async function insertWorkflowRun({
|
|
|
239
253
|
status,
|
|
240
254
|
input,
|
|
241
255
|
maxRetries,
|
|
256
|
+
priority,
|
|
242
257
|
timeoutAt,
|
|
243
258
|
idempotencyKey,
|
|
244
259
|
parentRunId,
|
|
@@ -256,6 +271,7 @@ async function insertWorkflowRun({
|
|
|
256
271
|
status,
|
|
257
272
|
input,
|
|
258
273
|
max_retries,
|
|
274
|
+
priority,
|
|
259
275
|
timeout_at,
|
|
260
276
|
created_at,
|
|
261
277
|
updated_at,
|
|
@@ -267,7 +283,7 @@ async function insertWorkflowRun({
|
|
|
267
283
|
parent_resource_id,
|
|
268
284
|
scheduled_at
|
|
269
285
|
)
|
|
270
|
-
VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14, $15, $16, $17)
|
|
286
|
+
VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14, $15, $16, $17, $18)
|
|
271
287
|
ON CONFLICT (idempotency_key) WHERE idempotency_key IS NOT NULL DO NOTHING
|
|
272
288
|
RETURNING *`, [
|
|
273
289
|
runId,
|
|
@@ -277,6 +293,7 @@ async function insertWorkflowRun({
|
|
|
277
293
|
status,
|
|
278
294
|
JSON.stringify(input),
|
|
279
295
|
maxRetries,
|
|
296
|
+
priority,
|
|
280
297
|
timeoutAt,
|
|
281
298
|
now,
|
|
282
299
|
now,
|
|
@@ -556,6 +573,30 @@ class WorkflowRunNotFoundError extends WorkflowEngineError {
|
|
|
556
573
|
}
|
|
557
574
|
}
|
|
558
575
|
|
|
576
|
+
// src/priority.ts
|
|
577
|
+
var PRIORITY_LEVELS = { high: 100, normal: 0, low: -100 };
|
|
578
|
+
function priorityToInt(value) {
|
|
579
|
+
if (typeof value === "number") {
|
|
580
|
+
if (!Number.isInteger(value)) {
|
|
581
|
+
throw new WorkflowEngineError(`Invalid priority ${value}: numeric priority must be an integer.`);
|
|
582
|
+
}
|
|
583
|
+
return value;
|
|
584
|
+
}
|
|
585
|
+
const mapped = PRIORITY_LEVELS[value];
|
|
586
|
+
if (mapped === undefined) {
|
|
587
|
+
throw new WorkflowEngineError(`Invalid priority "${value}": expected one of ${Object.keys(PRIORITY_LEVELS).map((k) => `"${k}"`).join(", ")} or an integer.`);
|
|
588
|
+
}
|
|
589
|
+
return mapped;
|
|
590
|
+
}
|
|
591
|
+
function resolvePriority(...candidates) {
|
|
592
|
+
for (const candidate of candidates) {
|
|
593
|
+
if (candidate !== undefined) {
|
|
594
|
+
return priorityToInt(candidate);
|
|
595
|
+
}
|
|
596
|
+
}
|
|
597
|
+
return PRIORITY_LEVELS.normal;
|
|
598
|
+
}
|
|
599
|
+
|
|
559
600
|
// src/types.ts
|
|
560
601
|
var WorkflowStatus;
|
|
561
602
|
((WorkflowStatus2) => {
|
|
@@ -566,6 +607,17 @@ var WorkflowStatus;
|
|
|
566
607
|
WorkflowStatus2["FAILED"] = "failed";
|
|
567
608
|
WorkflowStatus2["CANCELLED"] = "cancelled";
|
|
568
609
|
})(WorkflowStatus ||= {});
|
|
610
|
+
var _STEP_BASE_METHOD_TO_TYPE = {
|
|
611
|
+
run: "run" /* RUN */,
|
|
612
|
+
waitFor: "waitFor" /* WAIT_FOR */,
|
|
613
|
+
waitUntil: "waitUntil" /* WAIT_UNTIL */,
|
|
614
|
+
delay: "delay" /* DELAY */,
|
|
615
|
+
sleep: "delay" /* DELAY */,
|
|
616
|
+
pause: "pause" /* PAUSE */,
|
|
617
|
+
poll: "poll" /* POLL */,
|
|
618
|
+
invokeChildWorkflow: "invokeChildWorkflow" /* INVOKE_CHILD_WORKFLOW */
|
|
619
|
+
};
|
|
620
|
+
var STEP_BASE_METHOD_TYPES = new Map(Object.entries(_STEP_BASE_METHOD_TO_TYPE));
|
|
569
621
|
|
|
570
622
|
// src/client.ts
|
|
571
623
|
var LOG_PREFIX = "[WorkflowClient]";
|
|
@@ -660,6 +712,7 @@ class WorkflowClient {
|
|
|
660
712
|
status: "running" /* RUNNING */,
|
|
661
713
|
input,
|
|
662
714
|
maxRetries: options?.retries ?? 0,
|
|
715
|
+
priority: resolvePriority(options?.priority),
|
|
663
716
|
timeoutAt,
|
|
664
717
|
idempotencyKey
|
|
665
718
|
}, _db);
|
|
@@ -673,6 +726,7 @@ class WorkflowClient {
|
|
|
673
726
|
await this.boss.send(WORKFLOW_RUN_QUEUE_NAME, job, {
|
|
674
727
|
startAfter: new Date,
|
|
675
728
|
expireInSeconds: options?.expireInSeconds ?? defaultExpireInSeconds,
|
|
729
|
+
priority: insertedRun.priority,
|
|
676
730
|
db: _db
|
|
677
731
|
});
|
|
678
732
|
}
|
|
@@ -701,7 +755,8 @@ class WorkflowClient {
|
|
|
701
755
|
}
|
|
702
756
|
};
|
|
703
757
|
await this.boss.send(WORKFLOW_RUN_QUEUE_NAME, job, {
|
|
704
|
-
expireInSeconds: options?.expireInSeconds ?? defaultExpireInSeconds
|
|
758
|
+
expireInSeconds: options?.expireInSeconds ?? defaultExpireInSeconds,
|
|
759
|
+
priority: run.priority
|
|
705
760
|
});
|
|
706
761
|
this.logger.log(`${LOG_PREFIX} Event ${eventName} sent for workflow run ${runId}`);
|
|
707
762
|
return run;
|
|
@@ -880,6 +935,7 @@ function createWorkflowRef(id, options) {
|
|
|
880
935
|
inputSchema: options?.inputSchema,
|
|
881
936
|
timeout: defineOptions?.timeout,
|
|
882
937
|
retries: defineOptions?.retries,
|
|
938
|
+
priority: defineOptions?.priority,
|
|
883
939
|
schedule: defineOptions?.schedule,
|
|
884
940
|
timezone: defineOptions?.timezone
|
|
885
941
|
});
|
|
@@ -891,12 +947,13 @@ function createWorkflowRef(id, options) {
|
|
|
891
947
|
return ref;
|
|
892
948
|
}
|
|
893
949
|
function createWorkflowFactory(plugins = []) {
|
|
894
|
-
const factory = (id, handler, { inputSchema, timeout, retries, schedule, timezone } = {}) => ({
|
|
950
|
+
const factory = (id, handler, { inputSchema, timeout, retries, priority, schedule, timezone } = {}) => ({
|
|
895
951
|
id,
|
|
896
952
|
handler,
|
|
897
953
|
inputSchema,
|
|
898
954
|
timeout,
|
|
899
955
|
retries,
|
|
956
|
+
priority,
|
|
900
957
|
schedule,
|
|
901
958
|
timezone,
|
|
902
959
|
plugins: plugins.length > 0 ? plugins : undefined
|
|
@@ -959,11 +1016,11 @@ function parseWorkflowHandler(handler) {
|
|
|
959
1016
|
const propertyAccess = node.expression;
|
|
960
1017
|
const objectName = propertyAccess.expression.getText(sourceFile);
|
|
961
1018
|
const methodName = propertyAccess.name.text;
|
|
962
|
-
|
|
1019
|
+
const stepType = objectName === "step" ? STEP_BASE_METHOD_TYPES.get(methodName) : undefined;
|
|
1020
|
+
if (stepType !== undefined) {
|
|
963
1021
|
const firstArg = node.arguments[0];
|
|
964
1022
|
if (firstArg) {
|
|
965
1023
|
const { id, isDynamic } = extractStepId(firstArg);
|
|
966
|
-
const stepType = methodName === "sleep" ? "delay" /* DELAY */ : methodName;
|
|
967
1024
|
const stepDefinition = {
|
|
968
1025
|
id,
|
|
969
1026
|
type: stepType,
|
|
@@ -1267,6 +1324,9 @@ class WorkflowEngine {
|
|
|
1267
1324
|
});
|
|
1268
1325
|
return run;
|
|
1269
1326
|
}
|
|
1327
|
+
async createChildWorkflowRun(params) {
|
|
1328
|
+
return this.createWorkflowRun(params);
|
|
1329
|
+
}
|
|
1270
1330
|
async createWorkflowRun({
|
|
1271
1331
|
workflowId,
|
|
1272
1332
|
input,
|
|
@@ -1276,6 +1336,7 @@ class WorkflowEngine {
|
|
|
1276
1336
|
parentRunId,
|
|
1277
1337
|
parentStepId,
|
|
1278
1338
|
parentResourceId,
|
|
1339
|
+
parentPriority,
|
|
1279
1340
|
scheduledAt,
|
|
1280
1341
|
enqueue = true,
|
|
1281
1342
|
db
|
|
@@ -1306,6 +1367,7 @@ class WorkflowEngine {
|
|
|
1306
1367
|
status: "running" /* RUNNING */,
|
|
1307
1368
|
input,
|
|
1308
1369
|
maxRetries: options?.retries ?? workflow2.retries ?? 0,
|
|
1370
|
+
priority: resolvePriority(options?.priority, workflow2.priority, parentPriority),
|
|
1309
1371
|
timeoutAt,
|
|
1310
1372
|
idempotencyKey,
|
|
1311
1373
|
parentRunId,
|
|
@@ -1333,6 +1395,7 @@ class WorkflowEngine {
|
|
|
1333
1395
|
await this.boss.send(WORKFLOW_RUN_QUEUE_NAME, job, {
|
|
1334
1396
|
startAfter: new Date,
|
|
1335
1397
|
expireInSeconds: options?.expireInSeconds ?? defaultExpireInSeconds2,
|
|
1398
|
+
priority: run.priority,
|
|
1336
1399
|
...retrySendOptions(run.maxRetries),
|
|
1337
1400
|
...db ? { db } : {}
|
|
1338
1401
|
});
|
|
@@ -1482,6 +1545,7 @@ class WorkflowEngine {
|
|
|
1482
1545
|
};
|
|
1483
1546
|
await this.boss.send(WORKFLOW_RUN_QUEUE_NAME, job, {
|
|
1484
1547
|
expireInSeconds: options?.expireInSeconds ?? defaultExpireInSeconds2,
|
|
1548
|
+
priority: run.priority,
|
|
1485
1549
|
...retrySendOptions(run.maxRetries)
|
|
1486
1550
|
});
|
|
1487
1551
|
this.logger.log(`event ${eventName} sent for workflow run with id ${runId}`);
|
|
@@ -1653,75 +1717,7 @@ class WorkflowEngine {
|
|
|
1653
1717
|
}, { db });
|
|
1654
1718
|
}, this.pool);
|
|
1655
1719
|
}
|
|
1656
|
-
|
|
1657
|
-
run: async (stepId, handler) => {
|
|
1658
|
-
if (!run) {
|
|
1659
|
-
throw new WorkflowEngineError("Missing workflow run", workflowId, runId);
|
|
1660
|
-
}
|
|
1661
|
-
return this.runStep({ stepId, run, handler });
|
|
1662
|
-
},
|
|
1663
|
-
waitFor: async (stepId, { eventName, timeout }) => {
|
|
1664
|
-
if (!run) {
|
|
1665
|
-
throw new WorkflowEngineError("Missing workflow run", workflowId, runId);
|
|
1666
|
-
}
|
|
1667
|
-
const timeoutDate = timeout ? new Date(Date.now() + timeout) : undefined;
|
|
1668
|
-
return this.waitStep({ run, stepId, eventName, timeoutDate });
|
|
1669
|
-
},
|
|
1670
|
-
waitUntil: async (stepId, dateOrOptions) => {
|
|
1671
|
-
if (!run) {
|
|
1672
|
-
throw new WorkflowEngineError("Missing workflow run", workflowId, runId);
|
|
1673
|
-
}
|
|
1674
|
-
const date = dateOrOptions instanceof Date ? dateOrOptions : typeof dateOrOptions === "string" ? new Date(dateOrOptions) : dateOrOptions.date instanceof Date ? dateOrOptions.date : new Date(dateOrOptions.date);
|
|
1675
|
-
await this.waitStep({ run, stepId, timeoutDate: date });
|
|
1676
|
-
},
|
|
1677
|
-
pause: async (stepId) => {
|
|
1678
|
-
if (!run) {
|
|
1679
|
-
throw new WorkflowEngineError("Missing workflow run", workflowId, runId);
|
|
1680
|
-
}
|
|
1681
|
-
await this.waitStep({ run, stepId, eventName: PAUSE_EVENT_NAME });
|
|
1682
|
-
},
|
|
1683
|
-
delay: async (stepId, duration) => {
|
|
1684
|
-
if (!run) {
|
|
1685
|
-
throw new WorkflowEngineError("Missing workflow run", workflowId, runId);
|
|
1686
|
-
}
|
|
1687
|
-
await this.waitStep({
|
|
1688
|
-
run,
|
|
1689
|
-
stepId,
|
|
1690
|
-
timeoutDate: new Date(Date.now() + parseDuration(duration))
|
|
1691
|
-
});
|
|
1692
|
-
},
|
|
1693
|
-
get sleep() {
|
|
1694
|
-
return this.delay;
|
|
1695
|
-
},
|
|
1696
|
-
poll: async (stepId, conditionFn, options) => {
|
|
1697
|
-
if (!run) {
|
|
1698
|
-
throw new WorkflowEngineError("Missing workflow run", workflowId, runId);
|
|
1699
|
-
}
|
|
1700
|
-
const intervalMs = parseDuration(options?.interval ?? "30s");
|
|
1701
|
-
if (intervalMs < 30000) {
|
|
1702
|
-
throw new WorkflowEngineError(`step.poll interval must be at least 30s (got ${intervalMs}ms)`, workflowId, runId);
|
|
1703
|
-
}
|
|
1704
|
-
const timeoutMs = options?.timeout ? parseDuration(options.timeout) : undefined;
|
|
1705
|
-
return this.pollStep({ run, stepId, conditionFn, intervalMs, timeoutMs });
|
|
1706
|
-
},
|
|
1707
|
-
invokeChildWorkflow: async (stepId, refOrParams, inputArg, optionsArg) => {
|
|
1708
|
-
if (!run) {
|
|
1709
|
-
throw new WorkflowEngineError("Missing workflow run", workflowId, runId);
|
|
1710
|
-
}
|
|
1711
|
-
const resolvedChildCall = this.resolveWorkflowRunParameters(refOrParams, inputArg, optionsArg);
|
|
1712
|
-
const childWorkflowInvocation = {
|
|
1713
|
-
run,
|
|
1714
|
-
stepId,
|
|
1715
|
-
workflowId: resolvedChildCall.workflowId,
|
|
1716
|
-
input: resolvedChildCall.input,
|
|
1717
|
-
options: resolvedChildCall.options,
|
|
1718
|
-
resourceId: resolvedChildCall.resourceId,
|
|
1719
|
-
idempotencyKey: resolvedChildCall.idempotencyKey
|
|
1720
|
-
};
|
|
1721
|
-
return this.invokeChildWorkflowStep(childWorkflowInvocation);
|
|
1722
|
-
}
|
|
1723
|
-
};
|
|
1724
|
-
let step = { ...baseStep };
|
|
1720
|
+
let step = this.createBaseStep(run, workflowId, runId);
|
|
1725
1721
|
const plugins = workflow2.plugins ?? [];
|
|
1726
1722
|
const context = {
|
|
1727
1723
|
input: run.input,
|
|
@@ -1811,6 +1807,55 @@ class WorkflowEngine {
|
|
|
1811
1807
|
workflowId: run.workflowId
|
|
1812
1808
|
});
|
|
1813
1809
|
}
|
|
1810
|
+
createBaseStep(run, workflowId, runId) {
|
|
1811
|
+
return {
|
|
1812
|
+
run: async (stepId, handler) => {
|
|
1813
|
+
return this.runStep({ stepId, run, handler });
|
|
1814
|
+
},
|
|
1815
|
+
waitFor: async (stepId, { eventName, timeout }) => {
|
|
1816
|
+
const timeoutDate = timeout ? new Date(Date.now() + timeout) : undefined;
|
|
1817
|
+
return this.waitStep({ run, stepId, eventName, timeoutDate });
|
|
1818
|
+
},
|
|
1819
|
+
waitUntil: async (stepId, dateOrOptions) => {
|
|
1820
|
+
const date = dateOrOptions instanceof Date ? dateOrOptions : typeof dateOrOptions === "string" ? new Date(dateOrOptions) : dateOrOptions.date instanceof Date ? dateOrOptions.date : new Date(dateOrOptions.date);
|
|
1821
|
+
await this.waitStep({ run, stepId, timeoutDate: date });
|
|
1822
|
+
},
|
|
1823
|
+
pause: async (stepId) => {
|
|
1824
|
+
await this.waitStep({ run, stepId, eventName: PAUSE_EVENT_NAME });
|
|
1825
|
+
},
|
|
1826
|
+
delay: async (stepId, duration) => {
|
|
1827
|
+
await this.waitStep({
|
|
1828
|
+
run,
|
|
1829
|
+
stepId,
|
|
1830
|
+
timeoutDate: new Date(Date.now() + parseDuration(duration))
|
|
1831
|
+
});
|
|
1832
|
+
},
|
|
1833
|
+
get sleep() {
|
|
1834
|
+
return this.delay;
|
|
1835
|
+
},
|
|
1836
|
+
poll: async (stepId, conditionFn, options) => {
|
|
1837
|
+
const intervalMs = parseDuration(options?.interval ?? "30s");
|
|
1838
|
+
if (intervalMs < 30000) {
|
|
1839
|
+
throw new WorkflowEngineError(`step.poll interval must be at least 30s (got ${intervalMs}ms)`, workflowId, runId);
|
|
1840
|
+
}
|
|
1841
|
+
const timeoutMs = options?.timeout ? parseDuration(options.timeout) : undefined;
|
|
1842
|
+
return this.pollStep({ run, stepId, conditionFn, intervalMs, timeoutMs });
|
|
1843
|
+
},
|
|
1844
|
+
invokeChildWorkflow: async (stepId, refOrParams, inputArg, optionsArg) => {
|
|
1845
|
+
const resolvedChildCall = this.resolveWorkflowRunParameters(refOrParams, inputArg, optionsArg);
|
|
1846
|
+
const childWorkflowInvocation = {
|
|
1847
|
+
run,
|
|
1848
|
+
stepId,
|
|
1849
|
+
workflowId: resolvedChildCall.workflowId,
|
|
1850
|
+
input: resolvedChildCall.input,
|
|
1851
|
+
options: resolvedChildCall.options,
|
|
1852
|
+
resourceId: resolvedChildCall.resourceId,
|
|
1853
|
+
idempotencyKey: resolvedChildCall.idempotencyKey
|
|
1854
|
+
};
|
|
1855
|
+
return this.invokeChildWorkflowStep(childWorkflowInvocation);
|
|
1856
|
+
}
|
|
1857
|
+
};
|
|
1858
|
+
}
|
|
1814
1859
|
getCachedStepEntry(timeline, stepId) {
|
|
1815
1860
|
const stepEntry = timeline[stepId];
|
|
1816
1861
|
return stepEntry && typeof stepEntry === "object" && "output" in stepEntry ? stepEntry : null;
|
|
@@ -1901,7 +1946,7 @@ class WorkflowEngine {
|
|
|
1901
1946
|
});
|
|
1902
1947
|
return;
|
|
1903
1948
|
}
|
|
1904
|
-
const result = await this.
|
|
1949
|
+
const result = await this.createChildWorkflowRun({
|
|
1905
1950
|
workflowId,
|
|
1906
1951
|
input,
|
|
1907
1952
|
resourceId: childResourceId,
|
|
@@ -1910,6 +1955,7 @@ class WorkflowEngine {
|
|
|
1910
1955
|
parentRunId: run.id,
|
|
1911
1956
|
parentStepId: stepId,
|
|
1912
1957
|
parentResourceId: run.resourceId ?? undefined,
|
|
1958
|
+
parentPriority: run.priority,
|
|
1913
1959
|
enqueue: true,
|
|
1914
1960
|
db
|
|
1915
1961
|
});
|
|
@@ -2108,6 +2154,7 @@ ${error.stack}` : String(error)
|
|
|
2108
2154
|
await this.boss.send(WORKFLOW_RUN_QUEUE_NAME, job, {
|
|
2109
2155
|
startAfter: timeoutDate.getTime() <= Date.now() ? new Date : timeoutDate,
|
|
2110
2156
|
expireInSeconds: defaultExpireInSeconds2,
|
|
2157
|
+
priority: run.priority,
|
|
2111
2158
|
...retrySendOptions(run.maxRetries)
|
|
2112
2159
|
});
|
|
2113
2160
|
} catch (error) {
|
|
@@ -2226,6 +2273,7 @@ ${error.stack}` : String(error)
|
|
|
2226
2273
|
}, {
|
|
2227
2274
|
startAfter: new Date(Date.now() + intervalMs),
|
|
2228
2275
|
expireInSeconds: defaultExpireInSeconds2,
|
|
2276
|
+
priority: run.priority,
|
|
2229
2277
|
...retrySendOptions(run.maxRetries)
|
|
2230
2278
|
});
|
|
2231
2279
|
} catch (error) {
|
|
@@ -2453,5 +2501,5 @@ function otelPlugin(options = {}) {
|
|
|
2453
2501
|
};
|
|
2454
2502
|
}
|
|
2455
2503
|
|
|
2456
|
-
//# debugId=
|
|
2504
|
+
//# debugId=5FA47CDFF028114064756E2164756E21
|
|
2457
2505
|
//# sourceMappingURL=index.js.map
|
package/dist/index.d.cts
CHANGED
|
@@ -18,6 +18,8 @@ type WorkflowRun = {
|
|
|
18
18
|
timeoutAt: Date | null;
|
|
19
19
|
retryCount: number;
|
|
20
20
|
maxRetries: number;
|
|
21
|
+
/** Resolved scheduling priority (pg-boss integer; higher runs first). */
|
|
22
|
+
priority: number;
|
|
21
23
|
jobId: string | null;
|
|
22
24
|
idempotencyKey: string | null;
|
|
23
25
|
parentRunId: string | null;
|
|
@@ -35,6 +37,18 @@ type DurationObject = {
|
|
|
35
37
|
seconds?: number;
|
|
36
38
|
};
|
|
37
39
|
type Duration = string | DurationObject;
|
|
40
|
+
/**
|
|
41
|
+
* Named priority levels mapped to pg-boss integer priorities. Higher numbers
|
|
42
|
+
* are fetched first (pg-boss orders by `priority DESC`), and `normal = 0`
|
|
43
|
+
* matches pg-boss's own default. The ±100 spacing leaves room for numeric
|
|
44
|
+
* tuning between tiers via the escape hatch.
|
|
45
|
+
*/
|
|
46
|
+
declare const PRIORITY_LEVELS: {
|
|
47
|
+
readonly high: 100;
|
|
48
|
+
readonly normal: 0;
|
|
49
|
+
readonly low: -100;
|
|
50
|
+
};
|
|
51
|
+
type WorkflowPriority = keyof typeof PRIORITY_LEVELS | number;
|
|
38
52
|
type Schedule = string | Exclude<Duration, string>;
|
|
39
53
|
declare enum WorkflowStatus {
|
|
40
54
|
PENDING = "pending",
|
|
@@ -61,11 +75,13 @@ type StartWorkflowOptions = {
|
|
|
61
75
|
retries?: number;
|
|
62
76
|
expireInSeconds?: number;
|
|
63
77
|
idempotencyKey?: string;
|
|
78
|
+
priority?: WorkflowPriority;
|
|
64
79
|
};
|
|
65
80
|
type WorkflowOptions<I extends InputParameters> = {
|
|
66
81
|
timeout?: number;
|
|
67
82
|
retries?: number;
|
|
68
83
|
inputSchema?: I;
|
|
84
|
+
priority?: WorkflowPriority;
|
|
69
85
|
/**
|
|
70
86
|
* Recurring schedule. Accepts a cron expression (`'0 9 * * 1-5'`),
|
|
71
87
|
* a duration string (`'5m'`, `'1 hour'`), or a `DurationObject`.
|
|
@@ -173,6 +189,7 @@ type WorkflowDefinition<TInput extends InputParameters = InputParameters> = {
|
|
|
173
189
|
inputSchema?: TInput;
|
|
174
190
|
timeout?: number;
|
|
175
191
|
retries?: number;
|
|
192
|
+
priority?: WorkflowPriority;
|
|
176
193
|
schedule?: Schedule;
|
|
177
194
|
timezone?: string;
|
|
178
195
|
plugins?: WorkflowPlugin[];
|
|
@@ -365,6 +382,7 @@ declare class WorkflowEngine {
|
|
|
365
382
|
idempotencyKey?: string;
|
|
366
383
|
options?: StartWorkflowOptions;
|
|
367
384
|
}): Promise<WorkflowRun>;
|
|
385
|
+
private createChildWorkflowRun;
|
|
368
386
|
private createWorkflowRun;
|
|
369
387
|
private enqueueWorkflowRun;
|
|
370
388
|
private notifyParentOfChildTerminalRun;
|
|
@@ -441,6 +459,7 @@ declare class WorkflowEngine {
|
|
|
441
459
|
* persisted, falling back to a worker-death message.
|
|
442
460
|
*/
|
|
443
461
|
private handleWorkflowRunDlq;
|
|
462
|
+
private createBaseStep;
|
|
444
463
|
private getCachedStepEntry;
|
|
445
464
|
private getWaitForStepEntry;
|
|
446
465
|
private getInvokeChildWorkflowStepEntry;
|
|
@@ -502,4 +521,4 @@ type OtelPluginOptions = {
|
|
|
502
521
|
attributes?: (context: WorkflowContext) => Record<string, AttributeValue>;
|
|
503
522
|
};
|
|
504
523
|
declare function otelPlugin(options?: OtelPluginOptions): WorkflowPlugin<StepBaseContext, object>;
|
|
505
|
-
export { workflow, otelPlugin, createWorkflowRef, WorkflowStatus, WorkflowRunProgress, WorkflowRunNotFoundError, WorkflowRun, WorkflowRef, WorkflowPlugin, WorkflowOptions, WorkflowLogger, WorkflowEngineOptions, WorkflowEngineError, WorkflowEngine, WorkflowDefinition, WorkflowContext, WorkflowClientOptions, WorkflowClient, StepBaseContext, StartWorkflowOptions, ScheduleContext, Schedule, OtelPluginOptions, InputParameters, InferInputParameters, Duration };
|
|
524
|
+
export { workflow, otelPlugin, createWorkflowRef, WorkflowStatus, WorkflowRunProgress, WorkflowRunNotFoundError, WorkflowRun, WorkflowRef, WorkflowPriority, WorkflowPlugin, WorkflowOptions, WorkflowLogger, WorkflowEngineOptions, WorkflowEngineError, WorkflowEngine, WorkflowDefinition, WorkflowContext, WorkflowClientOptions, WorkflowClient, StepBaseContext, StartWorkflowOptions, ScheduleContext, Schedule, OtelPluginOptions, InputParameters, InferInputParameters, Duration };
|
package/dist/index.d.ts
CHANGED
|
@@ -18,6 +18,8 @@ type WorkflowRun = {
|
|
|
18
18
|
timeoutAt: Date | null;
|
|
19
19
|
retryCount: number;
|
|
20
20
|
maxRetries: number;
|
|
21
|
+
/** Resolved scheduling priority (pg-boss integer; higher runs first). */
|
|
22
|
+
priority: number;
|
|
21
23
|
jobId: string | null;
|
|
22
24
|
idempotencyKey: string | null;
|
|
23
25
|
parentRunId: string | null;
|
|
@@ -35,6 +37,18 @@ type DurationObject = {
|
|
|
35
37
|
seconds?: number;
|
|
36
38
|
};
|
|
37
39
|
type Duration = string | DurationObject;
|
|
40
|
+
/**
|
|
41
|
+
* Named priority levels mapped to pg-boss integer priorities. Higher numbers
|
|
42
|
+
* are fetched first (pg-boss orders by `priority DESC`), and `normal = 0`
|
|
43
|
+
* matches pg-boss's own default. The ±100 spacing leaves room for numeric
|
|
44
|
+
* tuning between tiers via the escape hatch.
|
|
45
|
+
*/
|
|
46
|
+
declare const PRIORITY_LEVELS: {
|
|
47
|
+
readonly high: 100;
|
|
48
|
+
readonly normal: 0;
|
|
49
|
+
readonly low: -100;
|
|
50
|
+
};
|
|
51
|
+
type WorkflowPriority = keyof typeof PRIORITY_LEVELS | number;
|
|
38
52
|
type Schedule = string | Exclude<Duration, string>;
|
|
39
53
|
declare enum WorkflowStatus {
|
|
40
54
|
PENDING = "pending",
|
|
@@ -61,11 +75,13 @@ type StartWorkflowOptions = {
|
|
|
61
75
|
retries?: number;
|
|
62
76
|
expireInSeconds?: number;
|
|
63
77
|
idempotencyKey?: string;
|
|
78
|
+
priority?: WorkflowPriority;
|
|
64
79
|
};
|
|
65
80
|
type WorkflowOptions<I extends InputParameters> = {
|
|
66
81
|
timeout?: number;
|
|
67
82
|
retries?: number;
|
|
68
83
|
inputSchema?: I;
|
|
84
|
+
priority?: WorkflowPriority;
|
|
69
85
|
/**
|
|
70
86
|
* Recurring schedule. Accepts a cron expression (`'0 9 * * 1-5'`),
|
|
71
87
|
* a duration string (`'5m'`, `'1 hour'`), or a `DurationObject`.
|
|
@@ -173,6 +189,7 @@ type WorkflowDefinition<TInput extends InputParameters = InputParameters> = {
|
|
|
173
189
|
inputSchema?: TInput;
|
|
174
190
|
timeout?: number;
|
|
175
191
|
retries?: number;
|
|
192
|
+
priority?: WorkflowPriority;
|
|
176
193
|
schedule?: Schedule;
|
|
177
194
|
timezone?: string;
|
|
178
195
|
plugins?: WorkflowPlugin[];
|
|
@@ -365,6 +382,7 @@ declare class WorkflowEngine {
|
|
|
365
382
|
idempotencyKey?: string;
|
|
366
383
|
options?: StartWorkflowOptions;
|
|
367
384
|
}): Promise<WorkflowRun>;
|
|
385
|
+
private createChildWorkflowRun;
|
|
368
386
|
private createWorkflowRun;
|
|
369
387
|
private enqueueWorkflowRun;
|
|
370
388
|
private notifyParentOfChildTerminalRun;
|
|
@@ -441,6 +459,7 @@ declare class WorkflowEngine {
|
|
|
441
459
|
* persisted, falling back to a worker-death message.
|
|
442
460
|
*/
|
|
443
461
|
private handleWorkflowRunDlq;
|
|
462
|
+
private createBaseStep;
|
|
444
463
|
private getCachedStepEntry;
|
|
445
464
|
private getWaitForStepEntry;
|
|
446
465
|
private getInvokeChildWorkflowStepEntry;
|
|
@@ -502,4 +521,4 @@ type OtelPluginOptions = {
|
|
|
502
521
|
attributes?: (context: WorkflowContext) => Record<string, AttributeValue>;
|
|
503
522
|
};
|
|
504
523
|
declare function otelPlugin(options?: OtelPluginOptions): WorkflowPlugin<StepBaseContext, object>;
|
|
505
|
-
export { workflow, otelPlugin, createWorkflowRef, WorkflowStatus, WorkflowRunProgress, WorkflowRunNotFoundError, WorkflowRun, WorkflowRef, WorkflowPlugin, WorkflowOptions, WorkflowLogger, WorkflowEngineOptions, WorkflowEngineError, WorkflowEngine, WorkflowDefinition, WorkflowContext, WorkflowClientOptions, WorkflowClient, StepBaseContext, StartWorkflowOptions, ScheduleContext, Schedule, OtelPluginOptions, InputParameters, InferInputParameters, Duration };
|
|
524
|
+
export { workflow, otelPlugin, createWorkflowRef, WorkflowStatus, WorkflowRunProgress, WorkflowRunNotFoundError, WorkflowRun, WorkflowRef, WorkflowPriority, WorkflowPlugin, WorkflowOptions, WorkflowLogger, WorkflowEngineOptions, WorkflowEngineError, WorkflowEngine, WorkflowDefinition, WorkflowContext, WorkflowClientOptions, WorkflowClient, StepBaseContext, StartWorkflowOptions, ScheduleContext, Schedule, OtelPluginOptions, InputParameters, InferInputParameters, Duration };
|