@dudousxd/nestjs-durable-core 0.32.1 → 0.33.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.cjs +121 -6
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +85 -2
- package/dist/index.d.ts +85 -2
- package/dist/index.js +118 -6
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -29,6 +29,7 @@ __export(index_exports, {
|
|
|
29
29
|
Entities: () => Entities,
|
|
30
30
|
EventAccumulators: () => EventAccumulators,
|
|
31
31
|
FatalError: () => FatalError,
|
|
32
|
+
GatherError: () => GatherError,
|
|
32
33
|
InMemoryAdmissionBackend: () => InMemoryAdmissionBackend,
|
|
33
34
|
InMemoryStateStore: () => InMemoryStateStore,
|
|
34
35
|
InMemoryTransport: () => InMemoryTransport,
|
|
@@ -37,6 +38,7 @@ __export(index_exports, {
|
|
|
37
38
|
RemoteStepError: () => RemoteStepError,
|
|
38
39
|
RemoteStepTimeout: () => RemoteStepTimeout,
|
|
39
40
|
RemoteWorkflowExecutor: () => RemoteWorkflowExecutor,
|
|
41
|
+
RemoteWorkflowTimeout: () => RemoteWorkflowTimeout,
|
|
40
42
|
STATE_STORE: () => STATE_STORE,
|
|
41
43
|
STATE_STORE_CANONICAL: () => STATE_STORE_CANONICAL,
|
|
42
44
|
SignalTimeoutError: () => SignalTimeoutError,
|
|
@@ -51,6 +53,7 @@ __export(index_exports, {
|
|
|
51
53
|
attributeOperand: () => attributeOperand,
|
|
52
54
|
breakpointToken: () => breakpointToken,
|
|
53
55
|
collectMetrics: () => collectMetrics,
|
|
56
|
+
createStepLogger: () => createStepLogger,
|
|
54
57
|
eventMatchOf: () => eventMatchOf,
|
|
55
58
|
eventMatches: () => eventMatches,
|
|
56
59
|
eventPrefix: () => eventPrefix,
|
|
@@ -453,6 +456,7 @@ function stepCheckpoint(p) {
|
|
|
453
456
|
attempts: p.attempts,
|
|
454
457
|
workerGroup: p.workerGroup,
|
|
455
458
|
wakeAt: p.wakeAt,
|
|
459
|
+
parallelGroup: p.parallelGroup,
|
|
456
460
|
enqueuedAt: p.enqueuedAt,
|
|
457
461
|
startedAt: p.startedAt,
|
|
458
462
|
finishedAt: p.finishedAt
|
|
@@ -470,6 +474,7 @@ function instantCheckpoint(p) {
|
|
|
470
474
|
status: p.status ?? "completed",
|
|
471
475
|
output: p.output,
|
|
472
476
|
wakeAt: p.wakeAt,
|
|
477
|
+
parallelGroup: p.parallelGroup,
|
|
473
478
|
attempts: 1,
|
|
474
479
|
enqueuedAt: at,
|
|
475
480
|
startedAt: at,
|
|
@@ -531,6 +536,19 @@ var RemoteStepTimeout = class extends Error {
|
|
|
531
536
|
this.timeoutMs = timeoutMs;
|
|
532
537
|
}
|
|
533
538
|
};
|
|
539
|
+
var RemoteWorkflowTimeout = class extends Error {
|
|
540
|
+
static {
|
|
541
|
+
__name(this, "RemoteWorkflowTimeout");
|
|
542
|
+
}
|
|
543
|
+
taskId;
|
|
544
|
+
timeoutMs;
|
|
545
|
+
constructor(taskId, timeoutMs) {
|
|
546
|
+
super(`remote workflow task ${taskId} produced no decision within ${timeoutMs}ms \u2014 presumed dropped; re-driving via recovery`);
|
|
547
|
+
this.name = "RemoteWorkflowTimeout";
|
|
548
|
+
this.taskId = taskId;
|
|
549
|
+
this.timeoutMs = timeoutMs;
|
|
550
|
+
}
|
|
551
|
+
};
|
|
534
552
|
var NonDeterminismError = class extends Error {
|
|
535
553
|
static {
|
|
536
554
|
__name(this, "NonDeterminismError");
|
|
@@ -544,6 +562,19 @@ var NonDeterminismError = class extends Error {
|
|
|
544
562
|
this.seq = seq;
|
|
545
563
|
}
|
|
546
564
|
};
|
|
565
|
+
var GatherError = class extends Error {
|
|
566
|
+
static {
|
|
567
|
+
__name(this, "GatherError");
|
|
568
|
+
}
|
|
569
|
+
failures;
|
|
570
|
+
constructor(failures, total) {
|
|
571
|
+
const ids = failures.map((f) => f.id).join(", ");
|
|
572
|
+
const denom = total ?? failures.length;
|
|
573
|
+
super(`ctx.all: ${failures.length} of ${denom} child(ren) failed: ${ids}`);
|
|
574
|
+
this.name = "GatherError";
|
|
575
|
+
this.failures = failures;
|
|
576
|
+
}
|
|
577
|
+
};
|
|
547
578
|
var WorkflowSuspended = class extends Error {
|
|
548
579
|
static {
|
|
549
580
|
__name(this, "WorkflowSuspended");
|
|
@@ -1213,6 +1244,72 @@ function createWorkflowCtx(host, runId, compensations, workflow = "") {
|
|
|
1213
1244
|
}
|
|
1214
1245
|
throw new WorkflowSuspended();
|
|
1215
1246
|
}, "child");
|
|
1247
|
+
const all = /* @__PURE__ */ __name(async (workflow2, inputs, opts) => {
|
|
1248
|
+
if (inputs.length === 0) return [];
|
|
1249
|
+
const mode = opts?.mode ?? "waitAll";
|
|
1250
|
+
const name = workflowName(workflow2);
|
|
1251
|
+
const positions = inputs.map(() => pos.next());
|
|
1252
|
+
const group = `all:${positions[0]}`;
|
|
1253
|
+
const id = /* @__PURE__ */ __name((i) => `${runId}.all.${positions[0]}.${i}`, "id");
|
|
1254
|
+
const existing = await Promise.all(positions.map((seq) => readCheckpoint(seq)));
|
|
1255
|
+
if (mode === "failFast") {
|
|
1256
|
+
for (let i = 0; i < inputs.length; i += 1) {
|
|
1257
|
+
const cp = existing[i];
|
|
1258
|
+
const c = cp?.status === "completed" ? cp.output : null;
|
|
1259
|
+
if (c && c.ok === false) {
|
|
1260
|
+
throw new GatherError([
|
|
1261
|
+
{
|
|
1262
|
+
index: i,
|
|
1263
|
+
id: id(i),
|
|
1264
|
+
error: c.error ?? "unknown"
|
|
1265
|
+
}
|
|
1266
|
+
], inputs.length);
|
|
1267
|
+
}
|
|
1268
|
+
}
|
|
1269
|
+
}
|
|
1270
|
+
let pending = false;
|
|
1271
|
+
for (let i = 0; i < inputs.length; i += 1) {
|
|
1272
|
+
const cp = existing[i];
|
|
1273
|
+
if (cp?.status === "completed") continue;
|
|
1274
|
+
pending = true;
|
|
1275
|
+
const seq = positions[i];
|
|
1276
|
+
const childId = id(i);
|
|
1277
|
+
await store.putSignalWaiter({
|
|
1278
|
+
token: `child:${childId}`,
|
|
1279
|
+
runId,
|
|
1280
|
+
seq
|
|
1281
|
+
});
|
|
1282
|
+
if (!await store.getRun(childId)) host.startChild(name, inputs[i], childId);
|
|
1283
|
+
if (!cp) {
|
|
1284
|
+
await writeCheckpoint(instantCheckpoint({
|
|
1285
|
+
runId,
|
|
1286
|
+
seq,
|
|
1287
|
+
name: `signal:child:${childId}`,
|
|
1288
|
+
kind: "signal",
|
|
1289
|
+
status: "running",
|
|
1290
|
+
parallelGroup: group
|
|
1291
|
+
}));
|
|
1292
|
+
}
|
|
1293
|
+
}
|
|
1294
|
+
if (pending) throw new WorkflowSuspended();
|
|
1295
|
+
const outputs = [];
|
|
1296
|
+
const failures = [];
|
|
1297
|
+
for (let i = 0; i < inputs.length; i += 1) {
|
|
1298
|
+
const c = existing[i]?.output;
|
|
1299
|
+
if (c && typeof c === "object" && "ok" in c && c.ok === false) {
|
|
1300
|
+
failures.push({
|
|
1301
|
+
index: i,
|
|
1302
|
+
id: id(i),
|
|
1303
|
+
error: c.error ?? "unknown"
|
|
1304
|
+
});
|
|
1305
|
+
outputs.push(void 0);
|
|
1306
|
+
} else {
|
|
1307
|
+
outputs.push(c?.value);
|
|
1308
|
+
}
|
|
1309
|
+
}
|
|
1310
|
+
if (failures.length > 0) throw new GatherError(failures, inputs.length);
|
|
1311
|
+
return outputs;
|
|
1312
|
+
}, "all");
|
|
1216
1313
|
const startChild = /* @__PURE__ */ __name(async (workflow2, input, options) => {
|
|
1217
1314
|
const { childId, priority } = normalizeChildOptions(options);
|
|
1218
1315
|
const current = pos.next();
|
|
@@ -1347,6 +1444,7 @@ function createWorkflowCtx(host, runId, compensations, workflow = "") {
|
|
|
1347
1444
|
waitForEvent,
|
|
1348
1445
|
task,
|
|
1349
1446
|
child,
|
|
1447
|
+
all,
|
|
1350
1448
|
startChild,
|
|
1351
1449
|
breakpoint,
|
|
1352
1450
|
webhook,
|
|
@@ -2336,7 +2434,8 @@ var WorkflowEngine = class {
|
|
|
2336
2434
|
attempts: 1,
|
|
2337
2435
|
enqueuedAt: startedAt,
|
|
2338
2436
|
startedAt,
|
|
2339
|
-
finishedAt: startedAt
|
|
2437
|
+
finishedAt: startedAt,
|
|
2438
|
+
parallelGroup: event.parallelGroup
|
|
2340
2439
|
}));
|
|
2341
2440
|
this.emit({
|
|
2342
2441
|
type: "step.started",
|
|
@@ -2360,7 +2459,8 @@ var WorkflowEngine = class {
|
|
|
2360
2459
|
attempts: 1,
|
|
2361
2460
|
enqueuedAt: startedAt,
|
|
2362
2461
|
startedAt,
|
|
2363
|
-
finishedAt: event.finishedAt != null ? new Date(event.finishedAt) : /* @__PURE__ */ new Date()
|
|
2462
|
+
finishedAt: event.finishedAt != null ? new Date(event.finishedAt) : /* @__PURE__ */ new Date(),
|
|
2463
|
+
parallelGroup: event.parallelGroup
|
|
2364
2464
|
}));
|
|
2365
2465
|
this.emit({
|
|
2366
2466
|
type: failed ? "step.failed" : "step.completed",
|
|
@@ -2597,6 +2697,13 @@ var WorkflowEngine = class {
|
|
|
2597
2697
|
try {
|
|
2598
2698
|
decision = await remote.executor.advance(run, history);
|
|
2599
2699
|
} catch (err) {
|
|
2700
|
+
if (err instanceof RemoteWorkflowTimeout) {
|
|
2701
|
+
await this.store.releaseRunLock(run.id);
|
|
2702
|
+
return {
|
|
2703
|
+
runId: run.id,
|
|
2704
|
+
status: "running"
|
|
2705
|
+
};
|
|
2706
|
+
}
|
|
2600
2707
|
const error = {
|
|
2601
2708
|
message: err instanceof Error ? err.message : String(err),
|
|
2602
2709
|
stack: err instanceof Error ? err.stack : void 0
|
|
@@ -2716,7 +2823,11 @@ var WorkflowEngine = class {
|
|
|
2716
2823
|
attempts: 1,
|
|
2717
2824
|
enqueuedAt: startedAt,
|
|
2718
2825
|
startedAt,
|
|
2719
|
-
finishedAt
|
|
2826
|
+
finishedAt,
|
|
2827
|
+
// Carry the worker's `parallelGroup` (a Python `ctx.gather` tags every step in the fan with
|
|
2828
|
+
// the same group) onto the checkpoint, so the dashboard can render the steps as one parallel
|
|
2829
|
+
// group instead of a sequential list. Additive: undefined for ordinary sequential steps.
|
|
2830
|
+
parallelGroup: cmd.parallelGroup
|
|
2720
2831
|
}));
|
|
2721
2832
|
this.emit({
|
|
2722
2833
|
type: cmd.error ? "step.failed" : "step.completed",
|
|
@@ -3351,11 +3462,12 @@ var RemoteWorkflowExecutor = class {
|
|
|
3351
3462
|
};
|
|
3352
3463
|
const decision = new Promise((resolve, reject) => {
|
|
3353
3464
|
this.pending.set(taskId, resolve);
|
|
3354
|
-
|
|
3465
|
+
const { timeoutMs } = this.opts;
|
|
3466
|
+
if (timeoutMs) {
|
|
3355
3467
|
const timer = setTimeout(() => {
|
|
3356
3468
|
this.pending.delete(taskId);
|
|
3357
|
-
reject(new
|
|
3358
|
-
},
|
|
3469
|
+
reject(new RemoteWorkflowTimeout(taskId, timeoutMs));
|
|
3470
|
+
}, timeoutMs);
|
|
3359
3471
|
timer.unref?.();
|
|
3360
3472
|
}
|
|
3361
3473
|
});
|
|
@@ -4083,6 +4195,7 @@ var InMemoryTransport = class {
|
|
|
4083
4195
|
Entities,
|
|
4084
4196
|
EventAccumulators,
|
|
4085
4197
|
FatalError,
|
|
4198
|
+
GatherError,
|
|
4086
4199
|
InMemoryAdmissionBackend,
|
|
4087
4200
|
InMemoryStateStore,
|
|
4088
4201
|
InMemoryTransport,
|
|
@@ -4091,6 +4204,7 @@ var InMemoryTransport = class {
|
|
|
4091
4204
|
RemoteStepError,
|
|
4092
4205
|
RemoteStepTimeout,
|
|
4093
4206
|
RemoteWorkflowExecutor,
|
|
4207
|
+
RemoteWorkflowTimeout,
|
|
4094
4208
|
STATE_STORE,
|
|
4095
4209
|
STATE_STORE_CANONICAL,
|
|
4096
4210
|
SignalTimeoutError,
|
|
@@ -4105,6 +4219,7 @@ var InMemoryTransport = class {
|
|
|
4105
4219
|
attributeOperand,
|
|
4106
4220
|
breakpointToken,
|
|
4107
4221
|
collectMetrics,
|
|
4222
|
+
createStepLogger,
|
|
4108
4223
|
eventMatchOf,
|
|
4109
4224
|
eventMatches,
|
|
4110
4225
|
eventPrefix,
|