@kb-labs/workflow-engine 2.96.0 → 2.98.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/index.d.ts +12 -0
- package/dist/index.js +39 -14
- package/dist/index.js.map +1 -1
- package/package.json +11 -11
package/dist/index.d.ts
CHANGED
|
@@ -320,6 +320,18 @@ declare class WorkflowEngine {
|
|
|
320
320
|
private deadLetterJob;
|
|
321
321
|
updateRun(runId: string, mutator: (run: WorkflowRun) => WorkflowRun | void): Promise<WorkflowRun | null>;
|
|
322
322
|
finalizeRun(runId: string, status: WorkflowRun['status'], context?: Partial<RunContext>): Promise<WorkflowRun | null>;
|
|
323
|
+
/**
|
|
324
|
+
* Persist a snapshot for a run that just reached a terminal state, so it
|
|
325
|
+
* can be replayed from any step later (`replayRun`, used by both
|
|
326
|
+
* `workflow runs restart --from-step` and `rerun --failed-only`). Only
|
|
327
|
+
* 'success'/'failed' carry meaningful step output data worth snapshotting.
|
|
328
|
+
*
|
|
329
|
+
* Shared by finalizeRun() and checkRunCompletion() — checkRunCompletion is
|
|
330
|
+
* the run-completion path actually driven by the worker in production, so
|
|
331
|
+
* without this call here, no snapshot is ever created outside of tests
|
|
332
|
+
* that call finalizeRun() directly (issue #263).
|
|
333
|
+
*/
|
|
334
|
+
private snapshotTerminalRun;
|
|
323
335
|
nextJob(): Promise<JobQueueEntry | null>;
|
|
324
336
|
rescheduleJob(entry: JobQueueEntry, delayMs: number): Promise<void>;
|
|
325
337
|
publishRunEvent(type: WorkflowEventName, run: WorkflowRun): Promise<void>;
|
package/dist/index.js
CHANGED
|
@@ -1038,7 +1038,7 @@ var WorkflowEngine = class {
|
|
|
1038
1038
|
return;
|
|
1039
1039
|
}
|
|
1040
1040
|
if (allSuccess) {
|
|
1041
|
-
await this.stateStore.updateRun(runId, (draft) => {
|
|
1041
|
+
const updated = await this.stateStore.updateRun(runId, (draft) => {
|
|
1042
1042
|
draft.status = "success";
|
|
1043
1043
|
draft.finishedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
1044
1044
|
return draft;
|
|
@@ -1056,9 +1056,12 @@ var WorkflowEngine = class {
|
|
|
1056
1056
|
runId,
|
|
1057
1057
|
payload: { status: "success", name: run.name }
|
|
1058
1058
|
});
|
|
1059
|
+
if (updated) {
|
|
1060
|
+
await this.snapshotTerminalRun(updated);
|
|
1061
|
+
}
|
|
1059
1062
|
} else if (anyFailed) {
|
|
1060
1063
|
const failedJob = run.jobs.find((j) => j.status === "failed");
|
|
1061
|
-
await this.stateStore.updateRun(runId, (draft) => {
|
|
1064
|
+
const updated = await this.stateStore.updateRun(runId, (draft) => {
|
|
1062
1065
|
draft.status = "failed";
|
|
1063
1066
|
draft.finishedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
1064
1067
|
if (failedJob?.error) {
|
|
@@ -1086,6 +1089,9 @@ var WorkflowEngine = class {
|
|
|
1086
1089
|
runId,
|
|
1087
1090
|
payload: { status: "failed", name: run.name }
|
|
1088
1091
|
});
|
|
1092
|
+
if (updated) {
|
|
1093
|
+
await this.snapshotTerminalRun(updated);
|
|
1094
|
+
}
|
|
1089
1095
|
}
|
|
1090
1096
|
}
|
|
1091
1097
|
/**
|
|
@@ -1370,21 +1376,40 @@ var WorkflowEngine = class {
|
|
|
1370
1376
|
status === "failed" ? EVENT_NAMES.run.failed : status === "cancelled" ? EVENT_NAMES.run.cancelled : EVENT_NAMES.run.finished,
|
|
1371
1377
|
updated
|
|
1372
1378
|
);
|
|
1373
|
-
|
|
1374
|
-
|
|
1375
|
-
|
|
1376
|
-
|
|
1377
|
-
|
|
1378
|
-
|
|
1379
|
-
|
|
1380
|
-
|
|
1379
|
+
await this.snapshotTerminalRun(updated);
|
|
1380
|
+
}
|
|
1381
|
+
return updated;
|
|
1382
|
+
}
|
|
1383
|
+
/**
|
|
1384
|
+
* Persist a snapshot for a run that just reached a terminal state, so it
|
|
1385
|
+
* can be replayed from any step later (`replayRun`, used by both
|
|
1386
|
+
* `workflow runs restart --from-step` and `rerun --failed-only`). Only
|
|
1387
|
+
* 'success'/'failed' carry meaningful step output data worth snapshotting.
|
|
1388
|
+
*
|
|
1389
|
+
* Shared by finalizeRun() and checkRunCompletion() — checkRunCompletion is
|
|
1390
|
+
* the run-completion path actually driven by the worker in production, so
|
|
1391
|
+
* without this call here, no snapshot is ever created outside of tests
|
|
1392
|
+
* that call finalizeRun() directly (issue #263).
|
|
1393
|
+
*/
|
|
1394
|
+
async snapshotTerminalRun(run) {
|
|
1395
|
+
if (run.status !== "success" && run.status !== "failed") {
|
|
1396
|
+
return;
|
|
1397
|
+
}
|
|
1398
|
+
const stepOutputs = {};
|
|
1399
|
+
for (const job of run.jobs) {
|
|
1400
|
+
for (const step of job.steps) {
|
|
1401
|
+
if (step.outputs && Object.keys(step.outputs).length > 0) {
|
|
1402
|
+
stepOutputs[step.id] = step.outputs;
|
|
1381
1403
|
}
|
|
1382
|
-
await this.snapshotStorage.createSnapshot(updated, stepOutputs, updated.env ?? {}).catch((err) => {
|
|
1383
|
-
this.logger.warn("Failed to create run snapshot", { runId, error: err instanceof Error ? err.message : String(err) });
|
|
1384
|
-
});
|
|
1385
1404
|
}
|
|
1386
1405
|
}
|
|
1387
|
-
|
|
1406
|
+
await this.snapshotStorage.createSnapshot(run, stepOutputs, run.env ?? {}).catch((err) => {
|
|
1407
|
+
this.logger.error(
|
|
1408
|
+
"Failed to create run snapshot \u2014 restart --from-step and rerun --failed-only will not work for this run",
|
|
1409
|
+
err instanceof Error ? err : new Error(String(err)),
|
|
1410
|
+
{ runId: run.id, status: run.status }
|
|
1411
|
+
);
|
|
1412
|
+
});
|
|
1388
1413
|
}
|
|
1389
1414
|
async nextJob() {
|
|
1390
1415
|
return this.scheduler.dequeueJob();
|