@dudousxd/nestjs-durable-testing 0.17.0 → 0.18.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.js CHANGED
@@ -187,7 +187,7 @@ async function assertOutput(store, runId, expected) {
187
187
  }
188
188
  __name(assertOutput, "assertOutput");
189
189
  async function recordedSteps(store, runId) {
190
- return (await store.listCheckpoints(runId)).map((cp) => cp.name);
190
+ return (await store.listCheckpoints(runId)).map((cp2) => cp2.name);
191
191
  }
192
192
  __name(recordedSteps, "recordedSteps");
193
193
  async function assertStepsRan(store, runId, names) {
@@ -200,10 +200,10 @@ async function assertStepsRan(store, runId, names) {
200
200
  }
201
201
  __name(assertStepsRan, "assertStepsRan");
202
202
  async function assertStepAttempts(store, runId, name, attempts) {
203
- const cp = (await store.listCheckpoints(runId)).find((c) => c.name === name);
204
- if (!cp) throw new Error(`expected step "${name}" to have run, but it did not`);
205
- if (cp.attempts !== attempts) {
206
- throw new Error(`expected step "${name}" to take ${attempts} attempt(s), took ${cp.attempts}`);
203
+ const cp2 = (await store.listCheckpoints(runId)).find((c) => c.name === name);
204
+ if (!cp2) throw new Error(`expected step "${name}" to have run, but it did not`);
205
+ if (cp2.attempts !== attempts) {
206
+ throw new Error(`expected step "${name}" to take ${attempts} attempt(s), took ${cp2.attempts}`);
207
207
  }
208
208
  }
209
209
  __name(assertStepAttempts, "assertStepAttempts");
@@ -341,11 +341,11 @@ var MutableClock = class {
341
341
  this.current = current;
342
342
  }
343
343
  now = /* @__PURE__ */ __name(() => this.current, "now");
344
- set(ms) {
345
- this.current = ms;
344
+ set(ms2) {
345
+ this.current = ms2;
346
346
  }
347
- advance(ms) {
348
- this.current += ms;
347
+ advance(ms2) {
348
+ this.current += ms2;
349
349
  }
350
350
  };
351
351
  function createTestEngine() {
@@ -362,8 +362,8 @@ function createTestEngine() {
362
362
  store,
363
363
  transport,
364
364
  clock,
365
- async tick(ms) {
366
- clock.advance(ms);
365
+ async tick(ms2) {
366
+ clock.advance(ms2);
367
367
  return engine.resumeDueTimers(clock.now());
368
368
  },
369
369
  async run(workflow, input, runId, opts) {
@@ -384,7 +384,7 @@ async function assertReplayable(register, history) {
384
384
  lockedBy: void 0,
385
385
  lockedUntil: void 0
386
386
  });
387
- for (const cp of history.checkpoints) await store.saveCheckpoint(cp);
387
+ for (const cp2 of history.checkpoints) await store.saveCheckpoint(cp2);
388
388
  const engine = new WorkflowEngine2({
389
389
  store
390
390
  });
@@ -400,7 +400,352 @@ __name(assertReplayable, "assertReplayable");
400
400
 
401
401
  // src/state-store-conformance.ts
402
402
  import { SINGLETON_ADMITTED_TAG, WorkflowEngine as WorkflowEngine3 } from "@dudousxd/nestjs-durable-core";
403
- import { beforeEach, describe as describe2, expect as expect2, it as it2 } from "vitest";
403
+ import { beforeEach, describe as describe2, expect as expect3, it as it2 } from "vitest";
404
+
405
+ // src/checkpoint-aggregation-contract.ts
406
+ import { SUMMARY_CHILD_LIMIT, aggregatesCheckpoints, checkpointStatsOf, childIdsOf, pageFan, pageFanFromStore, queryCheckpointsOf, summarizeRunFromStore, summarizeTimeline } from "@dudousxd/nestjs-durable-core";
407
+ import { expect as expect2 } from "vitest";
408
+ var base = Date.parse("2026-06-11T00:00:00.000Z");
409
+ var ms = /* @__PURE__ */ __name((n) => new Date(base + n), "ms");
410
+ function cp(seq, over = {}) {
411
+ return {
412
+ runId: "r1",
413
+ seq,
414
+ name: "Lines.process",
415
+ kind: "remote",
416
+ stepId: `r1:${seq}`,
417
+ status: "completed",
418
+ output: {
419
+ n: seq
420
+ },
421
+ attempts: 1,
422
+ enqueuedAt: ms(seq * 10),
423
+ startedAt: ms(seq * 10 + 3),
424
+ finishedAt: ms(seq * 10 + 7),
425
+ ...over
426
+ };
427
+ }
428
+ __name(cp, "cp");
429
+ var child = /* @__PURE__ */ __name((seq, group, over = {}) => cp(seq, {
430
+ name: `signal:child:r1.all.${group.split(":")[1]}.${seq}`,
431
+ kind: "signal",
432
+ parallelGroup: group,
433
+ output: {
434
+ ok: true,
435
+ value: seq
436
+ },
437
+ ...over
438
+ }), "child");
439
+ var folded = /* @__PURE__ */ __name((seq, group, wave, from, n) => cp(seq, {
440
+ name: `fan:r1.all.${group.split(":")[1]}.w${wave}.`,
441
+ kind: "signal",
442
+ parallelGroup: group,
443
+ output: {
444
+ from,
445
+ values: Array.from({
446
+ length: n
447
+ }, (_, i) => i)
448
+ }
449
+ }), "folded");
450
+ function aggregationFixture() {
451
+ const rows = [
452
+ cp(0, {
453
+ name: "Lines.load",
454
+ kind: "local"
455
+ })
456
+ ];
457
+ rows.push(cp(1, {
458
+ name: "spawn:audit-1",
459
+ kind: "local",
460
+ output: "audit-1"
461
+ }));
462
+ for (let i = 0; i < 120; i++) {
463
+ const seq = 2 + i;
464
+ rows.push(cp(seq, {
465
+ parallelGroup: "steps:2:120",
466
+ ...i % 4 === 0 && i < 100 ? {
467
+ status: "failed",
468
+ attempts: 3,
469
+ error: {
470
+ message: `bad ${i}`
471
+ }
472
+ } : i >= 100 && i < 120 && i !== 105 && i !== 106 ? {
473
+ status: "pending",
474
+ output: void 0
475
+ } : i === 105 || i === 106 ? {
476
+ status: "running",
477
+ output: void 0
478
+ } : {}
479
+ }));
480
+ }
481
+ for (let i = 0; i < 5; i++) rows.push(cp(122 + i, {
482
+ parallelGroup: "steps:122:5"
483
+ }));
484
+ for (let i = 0; i < 30; i++) {
485
+ rows.push(cp(127 + i, {
486
+ parallelGroup: "steps:127:40000",
487
+ name: "Rows.score",
488
+ ...i >= 12 ? {
489
+ status: "pending",
490
+ output: void 0
491
+ } : {}
492
+ }));
493
+ }
494
+ for (let i = 0; i < 30; i++) {
495
+ rows.push(cp(157 + i, {
496
+ parallelGroup: "steps:157:60:failFast",
497
+ name: i % 2 === 0 ? "Check.a" : "Check.b",
498
+ ...i === 7 ? {
499
+ status: "failed",
500
+ error: {
501
+ message: "stop"
502
+ }
503
+ } : {}
504
+ }));
505
+ }
506
+ for (let i = 0; i < 60; i++) {
507
+ const seq = 187 + i;
508
+ rows.push(child(seq, "all:187:n80", {
509
+ ...i >= 50 ? {
510
+ status: "running",
511
+ output: void 0
512
+ } : i % 3 === 0 ? {
513
+ output: {
514
+ ok: false,
515
+ error: `child ${i}`
516
+ }
517
+ } : i % 7 === 1 ? {
518
+ status: "failed",
519
+ error: {
520
+ message: "lost"
521
+ }
522
+ } : {}
523
+ }));
524
+ }
525
+ rows.push(folded(247, "all:187:n80", 9, 60, 20));
526
+ rows.push(folded(300, "all:300:n3000:failFast", 0, 0, 1e3));
527
+ rows.push(folded(301, "all:300:n3000:failFast", 1, 1e3, 1e3));
528
+ rows.push(folded(302, "all:300:n3000:failFast", 2, 2e3, 0));
529
+ for (let i = 0; i < 4; i++) {
530
+ rows.push(child(303 + i, "all:300:n3000:failFast", {
531
+ status: "running",
532
+ output: void 0
533
+ }));
534
+ }
535
+ rows.push(child(400, "all:400:n3"));
536
+ rows.push(child(401, "all:400:n3", {
537
+ output: {
538
+ ok: false,
539
+ error: "narrow"
540
+ }
541
+ }));
542
+ rows.push(child(402, "all:400:n3", {
543
+ status: "running",
544
+ output: void 0
545
+ }));
546
+ for (let i = 0; i < 55; i++) {
547
+ rows.push(child(450 + i, "all:450", i === 54 ? {
548
+ output: {
549
+ ok: false
550
+ }
551
+ } : {}));
552
+ }
553
+ rows.push(cp(600, {
554
+ name: "Lines.report",
555
+ kind: "local",
556
+ status: "failed"
557
+ }));
558
+ return rows;
559
+ }
560
+ __name(aggregationFixture, "aggregationFixture");
561
+ var GROUPS = [
562
+ "steps:2:120",
563
+ "steps:122:5",
564
+ "steps:127:40000",
565
+ "steps:157:60:failFast",
566
+ "all:187:n80",
567
+ "all:300:n3000:failFast",
568
+ "all:400:n3",
569
+ "all:450",
570
+ "absent"
571
+ ];
572
+ var QUERIES = [
573
+ {},
574
+ {
575
+ offset: 10,
576
+ limit: 7
577
+ },
578
+ {
579
+ offset: 0,
580
+ limit: 500
581
+ },
582
+ {
583
+ offset: 118,
584
+ limit: 50
585
+ },
586
+ {
587
+ offset: 5e3
588
+ },
589
+ {
590
+ failedOnly: true
591
+ },
592
+ {
593
+ failedOnly: true,
594
+ offset: 3,
595
+ limit: 4
596
+ },
597
+ {
598
+ failedOnly: true,
599
+ offset: 15,
600
+ limit: 10
601
+ },
602
+ {
603
+ failedOnly: true,
604
+ offset: 1e3
605
+ }
606
+ ];
607
+ function comparable(stats) {
608
+ return stats.map(({ minName, maxName, ...rest }) => ({
609
+ ...rest,
610
+ uniform: minName === maxName
611
+ })).sort((a, b) => `${a.group}|${a.status}|${a.nameKind}`.localeCompare(`${b.group}|${b.status}|${b.nameKind}`));
612
+ }
613
+ __name(comparable, "comparable");
614
+ async function seed(store, run2) {
615
+ await store.createRun(run2());
616
+ for (const row of aggregationFixture()) await store.saveCheckpoint(row);
617
+ await store.createRun(run2({
618
+ id: "r2"
619
+ }));
620
+ for (let i = 0; i < 3; i++) {
621
+ await store.saveCheckpoint(cp(2 + i, {
622
+ runId: "r2",
623
+ stepId: `r2:${i}`,
624
+ parallelGroup: "steps:2:120",
625
+ status: "failed"
626
+ }));
627
+ }
628
+ }
629
+ __name(seed, "seed");
630
+ function registerCheckpointAggregationCases(t, getStore, run2) {
631
+ t("checkpointStats and queryCheckpoints agree with the in-memory reference", async () => {
632
+ const store = getStore();
633
+ expect2(store.checkpointStats).toBeDefined();
634
+ expect2(store.queryCheckpoints).toBeDefined();
635
+ if (!aggregatesCheckpoints(store)) return;
636
+ await seed(store, run2);
637
+ const full = await store.listCheckpoints("r1");
638
+ expect2(comparable(await store.checkpointStats("r1"))).toEqual(comparable(checkpointStatsOf(full)));
639
+ for (const group of GROUPS) {
640
+ expect2(comparable(await store.checkpointStats("r1", {
641
+ group
642
+ }))).toEqual(comparable(checkpointStatsOf(full, {
643
+ group
644
+ })));
645
+ }
646
+ expect2(await store.checkpointStats("nope")).toEqual([]);
647
+ const queries = [
648
+ {},
649
+ {
650
+ group: "steps:2:120"
651
+ },
652
+ {
653
+ group: "steps:2:120",
654
+ statuses: [
655
+ "failed"
656
+ ],
657
+ limit: 20
658
+ },
659
+ {
660
+ group: "steps:2:120",
661
+ offset: 30,
662
+ limit: 5
663
+ },
664
+ {
665
+ group: "all:187:n80",
666
+ statuses: [
667
+ "completed"
668
+ ],
669
+ namePrefixes: [
670
+ "signal:child:"
671
+ ]
672
+ },
673
+ {
674
+ excludeGroups: [
675
+ "steps:2:120",
676
+ "all:187:n80",
677
+ "all:450"
678
+ ]
679
+ },
680
+ {
681
+ excludeGroups: []
682
+ },
683
+ {
684
+ namePrefixes: [
685
+ "signal:child:",
686
+ "fan:",
687
+ "spawn:"
688
+ ],
689
+ offset: 200,
690
+ limit: 200
691
+ },
692
+ {
693
+ namePrefixes: [
694
+ "fan:"
695
+ ]
696
+ },
697
+ {
698
+ statuses: []
699
+ },
700
+ {
701
+ namePrefixes: []
702
+ },
703
+ {
704
+ statuses: [
705
+ "pending",
706
+ "running"
707
+ ],
708
+ offset: 3
709
+ }
710
+ ];
711
+ for (const query of queries) {
712
+ expect2(await store.queryCheckpoints("r1", query)).toEqual(queryCheckpointsOf(full, query));
713
+ }
714
+ });
715
+ t("a run detail read through the aggregates is the one summarizeTimeline builds", async () => {
716
+ const store = getStore();
717
+ if (!aggregatesCheckpoints(store)) return;
718
+ await seed(store, run2);
719
+ const full = await store.listCheckpoints("r1");
720
+ for (const over of [
721
+ 50,
722
+ 0,
723
+ 1e3
724
+ ]) {
725
+ const ids = childIdsOf(full);
726
+ const expected = {
727
+ ...summarizeTimeline(full, over),
728
+ children: ids.slice(0, SUMMARY_CHILD_LIMIT),
729
+ childCount: ids.length
730
+ };
731
+ expect2(await summarizeRunFromStore(store, "r1", over)).toEqual(expected);
732
+ }
733
+ });
734
+ t("a fan page read through the aggregates is the one pageFan builds", async () => {
735
+ const store = getStore();
736
+ if (!aggregatesCheckpoints(store)) return;
737
+ await seed(store, run2);
738
+ const full = await store.listCheckpoints("r1");
739
+ for (const group of GROUPS) {
740
+ for (const query of QUERIES) {
741
+ expect2(await pageFanFromStore(store, "r1", group, query)).toEqual(pageFan(full, group, query));
742
+ }
743
+ }
744
+ });
745
+ }
746
+ __name(registerCheckpointAggregationCases, "registerCheckpointAggregationCases");
747
+
748
+ // src/state-store-conformance.ts
404
749
  var StateStoreUnavailableError = class extends Error {
405
750
  static {
406
751
  __name(this, "StateStoreUnavailableError");
@@ -486,7 +831,7 @@ function runStateStoreContract(name, makeStore) {
486
831
  });
487
832
  }, "t");
488
833
  t("atomically admits holders without displacement by later same-millisecond IDs", async () => {
489
- expect2(store.tryAdmitSingleton).toBeTypeOf("function");
834
+ expect3(store.tryAdmitSingleton).toBeTypeOf("function");
490
835
  const claim = /* @__PURE__ */ __name((id, limit = 1) => store.tryAdmitSingleton?.(id, "singleton:k", "checkout", limit), "claim");
491
836
  await store.createRun(run({
492
837
  id: "z-holder",
@@ -495,12 +840,12 @@ function runStateStoreContract(name, makeStore) {
495
840
  "user-tag"
496
841
  ]
497
842
  }));
498
- expect2(await claim("z-holder")).toBe(true);
843
+ expect3(await claim("z-holder")).toBe(true);
499
844
  await store.updateRun("z-holder", {
500
845
  status: "suspended",
501
846
  wakeAt: 1e4
502
847
  });
503
- expect2(await claim("z-holder")).toBe(true);
848
+ expect3(await claim("z-holder")).toBe(true);
504
849
  await store.updateRun("z-holder", {
505
850
  status: "blocked",
506
851
  lockedBy: "expired",
@@ -512,25 +857,25 @@ function runStateStoreContract(name, makeStore) {
512
857
  "singleton:k"
513
858
  ]
514
859
  }));
515
- expect2(await claim("a-waiter")).toBe(false);
516
- expect2(await claim("z-holder")).toBe(true);
860
+ expect3(await claim("a-waiter")).toBe(false);
861
+ expect3(await claim("z-holder")).toBe(true);
517
862
  await store.updateRun("z-holder", {
518
863
  status: "cancelling"
519
864
  });
520
- expect2(await claim("a-waiter")).toBe(false);
865
+ expect3(await claim("a-waiter")).toBe(false);
521
866
  await store.updateRun("z-holder", {
522
867
  status: "completed"
523
868
  });
524
- expect2((await store.getRun("z-holder"))?.tags).toEqual([
869
+ expect3((await store.getRun("z-holder"))?.tags).toEqual([
525
870
  "singleton:k",
526
871
  "user-tag"
527
872
  ]);
528
- expect2(await claim("a-waiter")).toBe(true);
873
+ expect3(await claim("a-waiter")).toBe(true);
529
874
  await store.updateRun("z-holder", {
530
875
  status: "running"
531
876
  });
532
- expect2(await claim("z-holder")).toBe(false);
533
- expect2(await claim("missing")).toBe(false);
877
+ expect3(await claim("z-holder")).toBe(false);
878
+ expect3(await claim("missing")).toBe(false);
534
879
  });
535
880
  t("singleton denial atomically parks waiters and preserves cancelling/terminal state", async () => {
536
881
  await store.createRun(run({
@@ -539,15 +884,15 @@ function runStateStoreContract(name, makeStore) {
539
884
  "singleton:k"
540
885
  ]
541
886
  }));
542
- expect2(await store.tryAdmitSingleton?.("holder", "singleton:k", "checkout", 1)).toBe(true);
887
+ expect3(await store.tryAdmitSingleton?.("holder", "singleton:k", "checkout", 1)).toBe(true);
543
888
  await store.createRun(run({
544
889
  id: "waiter",
545
890
  tags: [
546
891
  "singleton:k"
547
892
  ]
548
893
  }));
549
- expect2(await peerStore.tryAdmitSingleton?.("waiter", "singleton:k", "checkout", 1, 12e3)).toBe(false);
550
- expect2(await store.getRun("waiter")).toMatchObject({
894
+ expect3(await peerStore.tryAdmitSingleton?.("waiter", "singleton:k", "checkout", 1, 12e3)).toBe(false);
895
+ expect3(await store.getRun("waiter")).toMatchObject({
551
896
  status: "suspended",
552
897
  wakeAt: 12e3
553
898
  });
@@ -555,16 +900,16 @@ function runStateStoreContract(name, makeStore) {
555
900
  status: "cancelling",
556
901
  wakeAt: void 0
557
902
  });
558
- expect2(await peerStore.tryAdmitSingleton?.("waiter", "singleton:k", "checkout", 1, 14e3)).toBe(false);
559
- expect2(await store.getRun("waiter")).toMatchObject({
903
+ expect3(await peerStore.tryAdmitSingleton?.("waiter", "singleton:k", "checkout", 1, 14e3)).toBe(false);
904
+ expect3(await store.getRun("waiter")).toMatchObject({
560
905
  status: "cancelling"
561
906
  });
562
- expect2((await store.getRun("waiter"))?.wakeAt).toBeUndefined();
907
+ expect3((await store.getRun("waiter"))?.wakeAt).toBeUndefined();
563
908
  await store.updateRun("waiter", {
564
909
  status: "cancelled"
565
910
  });
566
- expect2(await peerStore.tryAdmitSingleton?.("waiter", "singleton:k", "checkout", 1, 16e3)).toBe(false);
567
- expect2((await store.getRun("waiter"))?.status).toBe("cancelled");
911
+ expect3(await peerStore.tryAdmitSingleton?.("waiter", "singleton:k", "checkout", 1, 16e3)).toBe(false);
912
+ expect3((await store.getRun("waiter"))?.status).toBe("cancelled");
568
913
  await store.updateRun("holder", {
569
914
  status: "completed"
570
915
  });
@@ -575,8 +920,8 @@ function runStateStoreContract(name, makeStore) {
575
920
  "singleton:k"
576
921
  ]
577
922
  }));
578
- expect2(await store.tryAdmitSingleton?.("cancelling", "singleton:k", "checkout", 1, 18e3)).toBe(false);
579
- expect2((await store.getRun("cancelling"))?.tags).not.toContain(SINGLETON_ADMITTED_TAG);
923
+ expect3(await store.tryAdmitSingleton?.("cancelling", "singleton:k", "checkout", 1, 18e3)).toBe(false);
924
+ expect3((await store.getRun("cancelling"))?.tags).not.toContain(SINGLETON_ADMITTED_TAG);
580
925
  });
581
926
  t("competing store instances atomically claim an empty singleton slot", async () => {
582
927
  for (const id of [
@@ -596,13 +941,13 @@ function runStateStoreContract(name, makeStore) {
596
941
  store.tryAdmitSingleton?.("a-first", "singleton:k", "checkout", 1),
597
942
  peerStore.tryAdmitSingleton?.("c-third", "singleton:k", "checkout", 1)
598
943
  ]);
599
- expect2(results).toEqual([
944
+ expect3(results).toEqual([
600
945
  false,
601
946
  true,
602
947
  false
603
948
  ]);
604
- expect2(await peerStore.tryAdmitSingleton?.("a-first", "singleton:k", "checkout", 1)).toBe(true);
605
- expect2((await store.getRun("a-first"))?.tags).toContain(SINGLETON_ADMITTED_TAG);
949
+ expect3(await peerStore.tryAdmitSingleton?.("a-first", "singleton:k", "checkout", 1)).toBe(true);
950
+ expect3((await store.getRun("a-first"))?.tags).toContain(SINGLETON_ADMITTED_TAG);
606
951
  });
607
952
  t("concurrent singleton claims honor limits and independent keys/workflows", async () => {
608
953
  const claim = /* @__PURE__ */ __name((id, tag = "singleton:k", workflow = "checkout") => store.tryAdmitSingleton?.(id, tag, workflow, 2), "claim");
@@ -616,7 +961,7 @@ function runStateStoreContract(name, makeStore) {
616
961
  "singleton:k"
617
962
  ]
618
963
  }));
619
- expect2(await claim(id)).toBe(true);
964
+ expect3(await claim(id)).toBe(true);
620
965
  }
621
966
  for (const id of [
622
967
  "a-waiter",
@@ -631,7 +976,7 @@ function runStateStoreContract(name, makeStore) {
631
976
  ]
632
977
  }));
633
978
  }
634
- expect2(await Promise.all([
979
+ expect3(await Promise.all([
635
980
  "a-waiter",
636
981
  "b-waiter",
637
982
  "c-waiter"
@@ -643,7 +988,7 @@ function runStateStoreContract(name, makeStore) {
643
988
  await store.updateRun("z-holder", {
644
989
  status: "failed"
645
990
  });
646
- expect2(await Promise.all([
991
+ expect3(await Promise.all([
647
992
  "c-waiter",
648
993
  "b-waiter",
649
994
  "a-waiter"
@@ -659,14 +1004,14 @@ function runStateStoreContract(name, makeStore) {
659
1004
  "pending"
660
1005
  ]
661
1006
  });
662
- expect2(active.filter((r) => r.tags?.includes(SINGLETON_ADMITTED_TAG))).toHaveLength(2);
1007
+ expect3(active.filter((r) => r.tags?.includes(SINGLETON_ADMITTED_TAG))).toHaveLength(2);
663
1008
  await store.createRun(run({
664
1009
  id: "other-key",
665
1010
  tags: [
666
1011
  "singleton:other"
667
1012
  ]
668
1013
  }));
669
- expect2(await claim("other-key", "singleton:other")).toBe(true);
1014
+ expect3(await claim("other-key", "singleton:other")).toBe(true);
670
1015
  await store.createRun(run({
671
1016
  id: "other-workflow",
672
1017
  workflow: "other",
@@ -674,18 +1019,18 @@ function runStateStoreContract(name, makeStore) {
674
1019
  "singleton:k"
675
1020
  ]
676
1021
  }));
677
- expect2(await claim("other-workflow", "singleton:k", "other")).toBe(true);
1022
+ expect3(await claim("other-workflow", "singleton:k", "other")).toBe(true);
678
1023
  });
679
1024
  t("creates a run and reads it back with its JSON input", async () => {
680
1025
  await store.createRun(run());
681
1026
  const loaded = await store.getRun("r1");
682
- expect2(loaded?.workflow).toBe("checkout");
683
- expect2(loaded?.input).toEqual({
1027
+ expect3(loaded?.workflow).toBe("checkout");
1028
+ expect3(loaded?.input).toEqual({
684
1029
  orderId: "o1"
685
1030
  });
686
1031
  });
687
1032
  t("returns null for a missing run", async () => {
688
- expect2(await store.getRun("nope")).toBeNull();
1033
+ expect3(await store.getRun("nope")).toBeNull();
689
1034
  });
690
1035
  t("updates a run (status/output) and round-trips recoveryAttempts + dead status", async () => {
691
1036
  await store.createRun(run({
@@ -699,18 +1044,18 @@ function runStateStoreContract(name, makeStore) {
699
1044
  updatedAt: at
700
1045
  });
701
1046
  const done = await store.getRun("r1");
702
- expect2(done?.status).toBe("completed");
703
- expect2(done?.output).toEqual({
1047
+ expect3(done?.status).toBe("completed");
1048
+ expect3(done?.output).toEqual({
704
1049
  total: 42
705
1050
  });
706
- expect2(done?.recoveryAttempts).toBe(3);
1051
+ expect3(done?.recoveryAttempts).toBe(3);
707
1052
  await store.updateRun("r1", {
708
1053
  status: "dead",
709
1054
  recoveryAttempts: 4
710
1055
  });
711
1056
  const dead = await store.getRun("r1");
712
- expect2(dead?.status).toBe("dead");
713
- expect2(dead?.recoveryAttempts).toBe(4);
1057
+ expect3(dead?.status).toBe("dead");
1058
+ expect3(dead?.recoveryAttempts).toBe(4);
714
1059
  });
715
1060
  t("round-trips a run dispatch priority", async () => {
716
1061
  await store.createRun(run({
@@ -720,8 +1065,8 @@ function runStateStoreContract(name, makeStore) {
720
1065
  await store.createRun(run({
721
1066
  id: "noprio"
722
1067
  }));
723
- expect2((await store.getRun("withprio"))?.priority).toBe(7);
724
- expect2((await store.getRun("noprio"))?.priority).toBeUndefined();
1068
+ expect3((await store.getRun("withprio"))?.priority).toBe(7);
1069
+ expect3((await store.getRun("noprio"))?.priority).toBeUndefined();
725
1070
  });
726
1071
  t("deleteRun removes the run and all its rows (checkpoints, waiters, attributes)", async () => {
727
1072
  await store.createRun(run({
@@ -736,10 +1081,10 @@ function runStateStoreContract(name, makeStore) {
736
1081
  seq: 0
737
1082
  });
738
1083
  await store.deleteRun("r1");
739
- expect2(await store.getRun("r1")).toBeNull();
740
- expect2(await store.listCheckpoints("r1")).toEqual([]);
741
- expect2(await store.listSignalWaiters("approve-")).toEqual([]);
742
- expect2(await store.listRuns({
1084
+ expect3(await store.getRun("r1")).toBeNull();
1085
+ expect3(await store.listCheckpoints("r1")).toEqual([]);
1086
+ expect3(await store.listSignalWaiters("approve-")).toEqual([]);
1087
+ expect3(await store.listRuns({
743
1088
  attributes: [
744
1089
  {
745
1090
  key: "tier",
@@ -750,7 +1095,7 @@ function runStateStoreContract(name, makeStore) {
750
1095
  })).toEqual([]);
751
1096
  });
752
1097
  t("deleteRun is a no-op for a missing run", async () => {
753
- await expect2(store.deleteRun("nope")).resolves.toBeUndefined();
1098
+ await expect3(store.deleteRun("nope")).resolves.toBeUndefined();
754
1099
  });
755
1100
  t("deleteRuns removes every listed run with its rows and ignores missing ids", async () => {
756
1101
  await store.createRun(run({
@@ -774,18 +1119,18 @@ function runStateStoreContract(name, makeStore) {
774
1119
  runId: "d2",
775
1120
  seq: 0
776
1121
  });
777
- expect2(typeof store.deleteRuns).toBe("function");
1122
+ expect3(typeof store.deleteRuns).toBe("function");
778
1123
  await store.deleteRuns?.([
779
1124
  "d1",
780
1125
  "d2",
781
1126
  "ghost"
782
1127
  ]);
783
- expect2(await store.getRun("d1")).toBeNull();
784
- expect2(await store.getRun("d2")).toBeNull();
785
- expect2(await store.getRun("keep")).not.toBeNull();
786
- expect2(await store.listCheckpoints("d1")).toEqual([]);
787
- expect2(await store.listSignalWaiters("approve-")).toEqual([]);
788
- expect2(await store.listRuns({
1128
+ expect3(await store.getRun("d1")).toBeNull();
1129
+ expect3(await store.getRun("d2")).toBeNull();
1130
+ expect3(await store.getRun("keep")).not.toBeNull();
1131
+ expect3(await store.listCheckpoints("d1")).toEqual([]);
1132
+ expect3(await store.listSignalWaiters("approve-")).toEqual([]);
1133
+ expect3(await store.listRuns({
789
1134
  attributes: [
790
1135
  {
791
1136
  key: "tier",
@@ -794,7 +1139,7 @@ function runStateStoreContract(name, makeStore) {
794
1139
  }
795
1140
  ]
796
1141
  })).toEqual([]);
797
- await expect2(store.deleteRuns?.([])).resolves.toBeUndefined();
1142
+ await expect3(store.deleteRuns?.([])).resolves.toBeUndefined();
798
1143
  });
799
1144
  const aged = /* @__PURE__ */ __name((id, ageDays, over = {}) => run({
800
1145
  id,
@@ -817,7 +1162,7 @@ function runStateStoreContract(name, makeStore) {
817
1162
  runId: "old-done",
818
1163
  stepId: "old-done:0"
819
1164
  }));
820
- expect2(typeof store.pruneTerminalRuns).toBe("function");
1165
+ expect3(typeof store.pruneTerminalRuns).toBe("function");
821
1166
  const deleted = await store.pruneTerminalRuns?.({
822
1167
  statuses: [
823
1168
  "completed",
@@ -826,12 +1171,12 @@ function runStateStoreContract(name, makeStore) {
826
1171
  ],
827
1172
  maxAge: "7d"
828
1173
  }, NOW, 100);
829
- expect2(deleted).toBe(2);
830
- expect2(await ids()).toEqual([
1174
+ expect3(deleted).toBe(2);
1175
+ expect3(await ids()).toEqual([
831
1176
  "fresh-done",
832
1177
  "old-live"
833
1178
  ]);
834
- expect2(await store.listCheckpoints("old-done")).toEqual([]);
1179
+ expect3(await store.listCheckpoints("old-done")).toEqual([]);
835
1180
  });
836
1181
  t("pruneTerminalRuns keeps only the newest maxCount and drains in batches of limit", async () => {
837
1182
  for (let i = 1; i <= 5; i++) await store.createRun(aged(`c${i}`, i));
@@ -841,10 +1186,10 @@ function runStateStoreContract(name, makeStore) {
841
1186
  ],
842
1187
  maxCount: 2
843
1188
  };
844
- expect2(await store.pruneTerminalRuns?.(policy, NOW, 2)).toBe(2);
845
- expect2(await store.pruneTerminalRuns?.(policy, NOW, 2)).toBe(1);
846
- expect2(await store.pruneTerminalRuns?.(policy, NOW, 2)).toBe(0);
847
- expect2(await ids()).toEqual([
1189
+ expect3(await store.pruneTerminalRuns?.(policy, NOW, 2)).toBe(2);
1190
+ expect3(await store.pruneTerminalRuns?.(policy, NOW, 2)).toBe(1);
1191
+ expect3(await store.pruneTerminalRuns?.(policy, NOW, 2)).toBe(0);
1192
+ expect3(await ids()).toEqual([
848
1193
  "c1",
849
1194
  "c2"
850
1195
  ]);
@@ -871,7 +1216,7 @@ function runStateStoreContract(name, makeStore) {
871
1216
  namespace: "acme"
872
1217
  }
873
1218
  }, NOW, 100);
874
- expect2(await ids()).toEqual([
1219
+ expect3(await ids()).toEqual([
875
1220
  "acme-new",
876
1221
  "beta-old",
877
1222
  "report-old"
@@ -887,7 +1232,7 @@ function runStateStoreContract(name, makeStore) {
887
1232
  ]
888
1233
  }
889
1234
  }, NOW, 100);
890
- expect2(await ids()).toEqual([
1235
+ expect3(await ids()).toEqual([
891
1236
  "acme-new",
892
1237
  "beta-old"
893
1238
  ]);
@@ -903,7 +1248,7 @@ function runStateStoreContract(name, makeStore) {
903
1248
  namespace: "acme"
904
1249
  }
905
1250
  }, NOW, 100);
906
- expect2(await ids()).toEqual([
1251
+ expect3(await ids()).toEqual([
907
1252
  "acme-new",
908
1253
  "beta-old"
909
1254
  ]);
@@ -942,7 +1287,7 @@ function runStateStoreContract(name, makeStore) {
942
1287
  ]
943
1288
  }
944
1289
  }, NOW, 100);
945
- expect2(await ids()).toEqual([
1290
+ expect3(await ids()).toEqual([
946
1291
  "attr-old",
947
1292
  "attr-other",
948
1293
  "chatty-old"
@@ -962,7 +1307,7 @@ function runStateStoreContract(name, makeStore) {
962
1307
  ]
963
1308
  }
964
1309
  }, NOW, 100);
965
- expect2(await ids()).toEqual([
1310
+ expect3(await ids()).toEqual([
966
1311
  "attr-other",
967
1312
  "chatty-old"
968
1313
  ]);
@@ -979,21 +1324,21 @@ function runStateStoreContract(name, makeStore) {
979
1324
  engine.register("p-other", "1", async () => "done");
980
1325
  await engine.start("p-root", {}, "pr");
981
1326
  await engine.start("p-other", {}, "po");
982
- expect2((await engine.waitForRun("pc", {
1327
+ expect3((await engine.waitForRun("pc", {
983
1328
  timeoutMs: 2e4
984
1329
  })).status).toBe("suspended");
985
- expect2((await engine.waitForRun("po", {
1330
+ expect3((await engine.waitForRun("po", {
986
1331
  timeoutMs: 2e4
987
1332
  })).status).toBe("completed");
988
- await expect2(engine.purgeRuns({})).rejects.toThrow(/empty scope/);
989
- expect2(await engine.purgeRuns({
1333
+ await expect3(engine.purgeRuns({})).rejects.toThrow(/empty scope/);
1334
+ expect3(await engine.purgeRuns({
990
1335
  workflows: [
991
1336
  "p-root"
992
1337
  ]
993
1338
  })).toBe(2);
994
- expect2(await store.getRun("pr")).toBeNull();
995
- expect2(await store.getRun("pc")).toBeNull();
996
- expect2(await store.getRun("po")).not.toBeNull();
1339
+ expect3(await store.getRun("pr")).toBeNull();
1340
+ expect3(await store.getRun("pc")).toBeNull();
1341
+ expect3(await store.getRun("po")).not.toBeNull();
997
1342
  });
998
1343
  t("updateRun maps every patchable field \u2014 clears error and patches tags/lockedBy/input/timers", async () => {
999
1344
  await store.createRun(run({
@@ -1025,29 +1370,29 @@ function runStateStoreContract(name, makeStore) {
1025
1370
  updatedAt: at
1026
1371
  });
1027
1372
  const r = await store.getRun("r1");
1028
- expect2(r?.status).toBe("completed");
1029
- expect2(r?.output).toEqual({
1373
+ expect3(r?.status).toBe("completed");
1374
+ expect3(r?.output).toEqual({
1030
1375
  ok: true
1031
1376
  });
1032
- expect2(r?.error).toBeUndefined();
1033
- expect2(r?.input).toEqual({
1377
+ expect3(r?.error).toBeUndefined();
1378
+ expect3(r?.input).toEqual({
1034
1379
  orderId: "o2"
1035
1380
  });
1036
- expect2(r?.tags).toEqual([
1381
+ expect3(r?.tags).toEqual([
1037
1382
  "x",
1038
1383
  "y"
1039
1384
  ]);
1040
- expect2(r?.lockedBy).toBe("owner-2");
1041
- expect2(r?.wakeAt).toBe(123456);
1042
- expect2(r?.lockedUntil).toBe(222222);
1385
+ expect3(r?.lockedBy).toBe("owner-2");
1386
+ expect3(r?.wakeAt).toBe(123456);
1387
+ expect3(r?.lockedUntil).toBe(222222);
1043
1388
  await store.updateRun("r1", {
1044
1389
  awaitingDecisionTaskId: "turn-7"
1045
1390
  });
1046
- expect2((await store.getRun("r1"))?.awaitingDecisionTaskId).toBe("turn-7");
1391
+ expect3((await store.getRun("r1"))?.awaitingDecisionTaskId).toBe("turn-7");
1047
1392
  await store.updateRun("r1", {
1048
1393
  awaitingDecisionTaskId: void 0
1049
1394
  });
1050
- expect2((await store.getRun("r1"))?.awaitingDecisionTaskId).toBeUndefined();
1395
+ expect3((await store.getRun("r1"))?.awaitingDecisionTaskId).toBeUndefined();
1051
1396
  });
1052
1397
  t("listDueTimers returns the most overdue first, capped at limit", async () => {
1053
1398
  for (const [id, wakeAt] of [
@@ -1074,18 +1419,18 @@ function runStateStoreContract(name, makeStore) {
1074
1419
  wakeAt
1075
1420
  }));
1076
1421
  }
1077
- expect2((await store.listDueTimers(5e3)).map((r) => r.id)).toEqual([
1422
+ expect3((await store.listDueTimers(5e3)).map((r) => r.id)).toEqual([
1078
1423
  "earliest",
1079
1424
  "middle",
1080
1425
  "late"
1081
1426
  ]);
1082
- expect2((await store.listDueTimers(5e3, void 0, 2)).map((r) => r.id)).toEqual([
1427
+ expect3((await store.listDueTimers(5e3, void 0, 2)).map((r) => r.id)).toEqual([
1083
1428
  "earliest",
1084
1429
  "middle"
1085
1430
  ]);
1086
1431
  });
1087
1432
  t("countCheckpoints counts a seq range by status", async () => {
1088
- expect2(store.countCheckpoints).toBeDefined();
1433
+ expect3(store.countCheckpoints).toBeDefined();
1089
1434
  if (!store.countCheckpoints) return;
1090
1435
  await store.createRun(run());
1091
1436
  for (const [seq, status] of [
@@ -1125,32 +1470,33 @@ function runStateStoreContract(name, makeStore) {
1125
1470
  status: "pending",
1126
1471
  stepId: "other:2"
1127
1472
  }));
1128
- expect2(await store.countCheckpoints("r1", 1, 3, [
1473
+ expect3(await store.countCheckpoints("r1", 1, 3, [
1129
1474
  "pending"
1130
1475
  ])).toBe(2);
1131
- expect2(await store.countCheckpoints("r1", 0, 4, [
1476
+ expect3(await store.countCheckpoints("r1", 0, 4, [
1132
1477
  "pending",
1133
1478
  "failed"
1134
1479
  ])).toBe(4);
1135
- expect2(await store.countCheckpoints("r1", 2, 2, [
1480
+ expect3(await store.countCheckpoints("r1", 2, 2, [
1136
1481
  "pending"
1137
1482
  ])).toBe(1);
1138
- expect2(await store.countCheckpoints("r1", 1, 4, [
1483
+ expect3(await store.countCheckpoints("r1", 1, 4, [
1139
1484
  "pending"
1140
1485
  ])).toBe(3);
1141
- expect2(await store.countCheckpoints("r1", 0, 0, [
1486
+ expect3(await store.countCheckpoints("r1", 0, 0, [
1142
1487
  "completed"
1143
1488
  ])).toBe(1);
1144
- expect2(await store.countCheckpoints("other", 0, 4, [
1489
+ expect3(await store.countCheckpoints("other", 0, 4, [
1145
1490
  "pending"
1146
1491
  ])).toBe(1);
1147
- expect2(await store.countCheckpoints("r1", 5, 9, [
1492
+ expect3(await store.countCheckpoints("r1", 5, 9, [
1148
1493
  "pending"
1149
1494
  ])).toBe(0);
1150
- expect2(await store.countCheckpoints("r1", 0, 4, [])).toBe(0);
1495
+ expect3(await store.countCheckpoints("r1", 0, 4, [])).toBe(0);
1151
1496
  });
1497
+ registerCheckpointAggregationCases(t, () => store, run);
1152
1498
  t("saveCheckpointIfPending writes over a pending row only", async () => {
1153
- expect2(store.saveCheckpointIfPending).toBeDefined();
1499
+ expect3(store.saveCheckpointIfPending).toBeDefined();
1154
1500
  if (!store.saveCheckpointIfPending) return;
1155
1501
  await store.createRun(run());
1156
1502
  const pending = checkpoint({
@@ -1158,11 +1504,11 @@ function runStateStoreContract(name, makeStore) {
1158
1504
  output: void 0
1159
1505
  });
1160
1506
  await store.saveCheckpoint(pending);
1161
- expect2(await store.saveCheckpointIfPending({
1507
+ expect3(await store.saveCheckpointIfPending({
1162
1508
  ...pending,
1163
1509
  wakeAt: 5e3
1164
1510
  })).toBe(true);
1165
- expect2((await store.getCheckpoint("r1", 0))?.wakeAt).toBe(5e3);
1511
+ expect3((await store.getCheckpoint("r1", 0))?.wakeAt).toBe(5e3);
1166
1512
  const done = {
1167
1513
  ...pending,
1168
1514
  status: "completed",
@@ -1170,33 +1516,190 @@ function runStateStoreContract(name, makeStore) {
1170
1516
  ok: true
1171
1517
  }
1172
1518
  };
1173
- expect2(await store.saveCheckpointIfPending(done)).toBe(true);
1174
- expect2(await store.saveCheckpointIfPending({
1519
+ expect3(await store.saveCheckpointIfPending(done)).toBe(true);
1520
+ expect3(await store.saveCheckpointIfPending({
1175
1521
  ...pending,
1176
1522
  wakeAt: 9e3
1177
1523
  })).toBe(false);
1178
1524
  const after = await store.getCheckpoint("r1", 0);
1179
- expect2(after?.status).toBe("completed");
1180
- expect2(after?.output).toEqual({
1525
+ expect3(after?.status).toBe("completed");
1526
+ expect3(after?.output).toEqual({
1181
1527
  ok: true
1182
1528
  });
1183
- expect2(after?.wakeAt).toBeUndefined();
1529
+ expect3(after?.wakeAt).toBeUndefined();
1184
1530
  await store.saveCheckpoint(checkpoint({
1185
1531
  seq: 1,
1186
1532
  status: "failed",
1187
1533
  stepId: "r1:1"
1188
1534
  }));
1189
- expect2(await store.saveCheckpointIfPending({
1535
+ expect3(await store.saveCheckpointIfPending({
1190
1536
  ...pending,
1191
1537
  seq: 1,
1192
1538
  stepId: "r1:1"
1193
1539
  })).toBe(false);
1194
- expect2((await store.getCheckpoint("r1", 1))?.status).toBe("failed");
1195
- expect2(await store.saveCheckpointIfPending({
1540
+ expect3((await store.getCheckpoint("r1", 1))?.status).toBe("failed");
1541
+ expect3(await store.saveCheckpointIfPending({
1196
1542
  ...pending,
1197
1543
  seq: 9
1198
1544
  })).toBe(false);
1199
- expect2(await store.getCheckpoint("r1", 9)).toBeNull();
1545
+ expect3(await store.getCheckpoint("r1", 9)).toBeNull();
1546
+ });
1547
+ t("saveCheckpointsIfPending settles a batch row by row, in order", async () => {
1548
+ expect3(store.saveCheckpointsIfPending).toBeDefined();
1549
+ if (!store.saveCheckpointsIfPending) return;
1550
+ expect3(await store.saveCheckpointsIfPending([])).toEqual([]);
1551
+ await store.createRun(run());
1552
+ await store.createRun(run({
1553
+ id: "r2"
1554
+ }));
1555
+ const pending = /* @__PURE__ */ __name((runId, seq) => checkpoint({
1556
+ runId,
1557
+ seq,
1558
+ stepId: `${runId}:${seq}`,
1559
+ status: "pending",
1560
+ output: void 0,
1561
+ wakeAt: 5e3
1562
+ }), "pending");
1563
+ for (const seq of [
1564
+ 0,
1565
+ 1,
1566
+ 2,
1567
+ 3
1568
+ ]) await store.saveCheckpoint(pending("r1", seq));
1569
+ await store.saveCheckpoint(pending("r2", 0));
1570
+ await store.saveCheckpoint({
1571
+ ...pending("r1", 1),
1572
+ status: "completed",
1573
+ output: {
1574
+ first: 1
1575
+ }
1576
+ });
1577
+ const done = /* @__PURE__ */ __name((runId, seq, output) => ({
1578
+ ...pending(runId, seq),
1579
+ status: "completed",
1580
+ output,
1581
+ wakeAt: void 0
1582
+ }), "done");
1583
+ const wrote = await store.saveCheckpointsIfPending([
1584
+ done("r1", 0, {
1585
+ n: 0
1586
+ }),
1587
+ done("r1", 1, {
1588
+ n: 1
1589
+ }),
1590
+ // A second copy of the same row: compared against the first copy's write, so refused.
1591
+ done("r1", 0, {
1592
+ n: "dup"
1593
+ }),
1594
+ {
1595
+ ...pending("r1", 2),
1596
+ status: "failed",
1597
+ error: {
1598
+ message: "boom"
1599
+ },
1600
+ wakeAt: void 0
1601
+ },
1602
+ // No such row: nothing is written.
1603
+ done("r1", 9, {
1604
+ n: 9
1605
+ }),
1606
+ // Another run's row, same seq as one above.
1607
+ done("r2", 0, {
1608
+ n: "r2"
1609
+ })
1610
+ ]);
1611
+ expect3(wrote).toEqual([
1612
+ true,
1613
+ false,
1614
+ false,
1615
+ true,
1616
+ false,
1617
+ true
1618
+ ]);
1619
+ const r1 = await store.listCheckpoints("r1");
1620
+ expect3(r1.map((c) => [
1621
+ c.seq,
1622
+ c.status,
1623
+ c.output
1624
+ ])).toEqual([
1625
+ [
1626
+ 0,
1627
+ "completed",
1628
+ {
1629
+ n: 0
1630
+ }
1631
+ ],
1632
+ [
1633
+ 1,
1634
+ "completed",
1635
+ {
1636
+ first: 1
1637
+ }
1638
+ ],
1639
+ [
1640
+ 2,
1641
+ "failed",
1642
+ void 0
1643
+ ],
1644
+ [
1645
+ 3,
1646
+ "pending",
1647
+ void 0
1648
+ ]
1649
+ ]);
1650
+ expect3(r1[2]?.error).toEqual({
1651
+ message: "boom"
1652
+ });
1653
+ expect3(r1[0]?.wakeAt).toBeUndefined();
1654
+ expect3(r1[3]?.wakeAt).toBe(5e3);
1655
+ expect3(await store.getCheckpoint("r1", 9)).toBeNull();
1656
+ expect3((await store.getCheckpoint("r2", 0))?.output).toEqual({
1657
+ n: "r2"
1658
+ });
1659
+ expect3(await store.saveCheckpointsIfPending([
1660
+ {
1661
+ ...pending("r1", 3),
1662
+ wakeAt: 9e3
1663
+ },
1664
+ done("r1", 3, {
1665
+ n: 3
1666
+ })
1667
+ ])).toEqual([
1668
+ true,
1669
+ true
1670
+ ]);
1671
+ expect3((await store.getCheckpoint("r1", 3))?.output).toEqual({
1672
+ n: 3
1673
+ });
1674
+ });
1675
+ t("saveCheckpointsIfPending writes a wide batch", async () => {
1676
+ if (!store.saveCheckpointsIfPending) return;
1677
+ await store.createRun(run());
1678
+ const n = 600;
1679
+ const rows = Array.from({
1680
+ length: n
1681
+ }, (_, seq) => checkpoint({
1682
+ seq,
1683
+ stepId: `r1:${seq}`,
1684
+ status: "pending",
1685
+ output: void 0
1686
+ }));
1687
+ for (const row of rows) await store.saveCheckpoint(row);
1688
+ const wrote = await store.saveCheckpointsIfPending(rows.map((row) => ({
1689
+ ...row,
1690
+ status: "completed",
1691
+ output: {
1692
+ seq: row.seq
1693
+ }
1694
+ })));
1695
+ expect3(wrote.every((w) => w === true)).toBe(true);
1696
+ expect3(wrote).toHaveLength(n);
1697
+ expect3(await store.countCheckpoints?.("r1", 0, n - 1, [
1698
+ "completed"
1699
+ ])).toBe(n);
1700
+ expect3((await store.getCheckpoint("r1", n - 1))?.output).toEqual({
1701
+ seq: n - 1
1702
+ });
1200
1703
  });
1201
1704
  t("upserts checkpoints, reads them by (runId, seq), and lists them ordered by seq", async () => {
1202
1705
  await store.createRun(run());
@@ -1214,13 +1717,13 @@ function runStateStoreContract(name, makeStore) {
1214
1717
  again: true
1215
1718
  }
1216
1719
  }));
1217
- expect2((await store.getCheckpoint("r1", 0))?.output).toEqual({
1720
+ expect3((await store.getCheckpoint("r1", 0))?.output).toEqual({
1218
1721
  ok: true,
1219
1722
  again: true
1220
1723
  });
1221
- expect2((await store.getCheckpoint("r1", 1))?.name).toBe("charge");
1724
+ expect3((await store.getCheckpoint("r1", 1))?.name).toBe("charge");
1222
1725
  const list = await store.listCheckpoints("r1");
1223
- expect2(list.map((c) => c.seq)).toEqual([
1726
+ expect3(list.map((c) => c.seq)).toEqual([
1224
1727
  0,
1225
1728
  1
1226
1729
  ]);
@@ -1256,14 +1759,14 @@ function runStateStoreContract(name, makeStore) {
1256
1759
  }
1257
1760
  }));
1258
1761
  const getLatestCheckpointByName = store.getLatestCheckpointByName;
1259
- expect2(getLatestCheckpointByName).toBeDefined();
1762
+ expect3(getLatestCheckpointByName).toBeDefined();
1260
1763
  if (!getLatestCheckpointByName) return;
1261
1764
  const latest = await getLatestCheckpointByName.call(store, "r1", "event:progress");
1262
- expect2(latest?.seq).toBe(3);
1263
- expect2(latest?.output).toEqual({
1765
+ expect3(latest?.seq).toBe(3);
1766
+ expect3(latest?.output).toEqual({
1264
1767
  pct: 90
1265
1768
  });
1266
- expect2(await getLatestCheckpointByName.call(store, "r1", "event:missing")).toBeUndefined();
1769
+ expect3(await getLatestCheckpointByName.call(store, "r1", "event:missing")).toBeUndefined();
1267
1770
  });
1268
1771
  t("listCheckpointsByNamePrefix returns prefix matches ordered by seq (empty => none)", async () => {
1269
1772
  await store.createRun(run());
@@ -1290,18 +1793,48 @@ function runStateStoreContract(name, makeStore) {
1290
1793
  output: "child-b"
1291
1794
  }));
1292
1795
  const listCheckpointsByNamePrefix = store.listCheckpointsByNamePrefix;
1293
- expect2(listCheckpointsByNamePrefix).toBeDefined();
1796
+ expect3(listCheckpointsByNamePrefix).toBeDefined();
1294
1797
  if (!listCheckpointsByNamePrefix) return;
1295
1798
  const matches = await listCheckpointsByNamePrefix.call(store, "r1", [
1296
1799
  "signal:child:",
1297
1800
  "spawn:"
1298
1801
  ]);
1299
- expect2(matches.map((c) => c.name)).toEqual([
1802
+ expect3(matches.map((c) => c.name)).toEqual([
1300
1803
  "spawn:0",
1301
1804
  "signal:child:c2",
1302
1805
  "spawn:1"
1303
1806
  ]);
1304
- expect2(await listCheckpointsByNamePrefix.call(store, "r1", [])).toEqual([]);
1807
+ expect3(await listCheckpointsByNamePrefix.call(store, "r1", [])).toEqual([]);
1808
+ });
1809
+ t("a name or token prefix matches literally \u2014 `_` and `%` are not wildcards", async () => {
1810
+ await store.createRun(run());
1811
+ await store.saveCheckpoint(checkpoint({
1812
+ seq: 0,
1813
+ name: "signal:child:job_1.onError.0"
1814
+ }));
1815
+ await store.saveCheckpoint(checkpoint({
1816
+ seq: 1,
1817
+ name: "signal:child:jobX1.onError.0"
1818
+ }));
1819
+ await store.putSignalWaiter({
1820
+ token: "child:job_1.child.0",
1821
+ runId: "r1",
1822
+ seq: 2
1823
+ });
1824
+ await store.putSignalWaiter({
1825
+ token: "child:jobX1.child.0",
1826
+ runId: "r1",
1827
+ seq: 3
1828
+ });
1829
+ const matches = await store.listCheckpointsByNamePrefix?.("r1", [
1830
+ "signal:child:job_1."
1831
+ ]);
1832
+ expect3(matches?.map((c) => c.name)).toEqual([
1833
+ "signal:child:job_1.onError.0"
1834
+ ]);
1835
+ expect3((await store.listSignalWaiters("child:job_1.")).map((w) => w.token)).toEqual([
1836
+ "child:job_1.child.0"
1837
+ ]);
1305
1838
  });
1306
1839
  t("round-trips checkpoint events and reads back a missing checkpoint as null", async () => {
1307
1840
  await store.createRun(run());
@@ -1316,7 +1849,7 @@ function runStateStoreContract(name, makeStore) {
1316
1849
  }
1317
1850
  ]
1318
1851
  }));
1319
- expect2((await store.getCheckpoint("r1", 0))?.events).toEqual([
1852
+ expect3((await store.getCheckpoint("r1", 0))?.events).toEqual([
1320
1853
  {
1321
1854
  at: 1,
1322
1855
  level: "error",
@@ -1325,7 +1858,7 @@ function runStateStoreContract(name, makeStore) {
1325
1858
  status: "failed"
1326
1859
  }
1327
1860
  ]);
1328
- expect2(await store.getCheckpoint("r1", 99)).toBeNull();
1861
+ expect3(await store.getCheckpoint("r1", 99)).toBeNull();
1329
1862
  });
1330
1863
  t("lists incomplete runs, pending runs (FIFO), and due timers", async () => {
1331
1864
  await store.createRun(run({
@@ -1351,20 +1884,20 @@ function runStateStoreContract(name, makeStore) {
1351
1884
  status: "pending",
1352
1885
  createdAt: /* @__PURE__ */ new Date("2026-06-11T00:00:01.000Z")
1353
1886
  }));
1354
- expect2((await store.listIncompleteRuns()).map((r) => r.id)).toEqual([
1887
+ expect3((await store.listIncompleteRuns()).map((r) => r.id)).toEqual([
1355
1888
  "running1"
1356
1889
  ]);
1357
- expect2((await store.listPendingRuns(10)).map((r) => r.id)).toEqual([
1890
+ expect3((await store.listPendingRuns(10)).map((r) => r.id)).toEqual([
1358
1891
  "pending1",
1359
1892
  "pending2"
1360
1893
  ]);
1361
- expect2((await store.listPendingRuns(1)).map((r) => r.id)).toEqual([
1894
+ expect3((await store.listPendingRuns(1)).map((r) => r.id)).toEqual([
1362
1895
  "pending1"
1363
1896
  ]);
1364
- expect2((await store.listDueTimers(1e4)).map((r) => r.id)).toEqual([
1897
+ expect3((await store.listDueTimers(1e4)).map((r) => r.id)).toEqual([
1365
1898
  "suspended1"
1366
1899
  ]);
1367
- expect2(await store.listDueTimers(1e3)).toHaveLength(0);
1900
+ expect3(await store.listDueTimers(1e3)).toHaveLength(0);
1368
1901
  });
1369
1902
  t("keeps a worker inside its own namespace on every path that picks work up", async () => {
1370
1903
  await store.createRun(run({
@@ -1399,33 +1932,33 @@ function runStateStoreContract(name, makeStore) {
1399
1932
  wakeAt: 5e3,
1400
1933
  namespace: "beta"
1401
1934
  }));
1402
- expect2((await store.listPendingRuns(10, "alpha")).map((r) => r.id)).toEqual([
1935
+ expect3((await store.listPendingRuns(10, "alpha")).map((r) => r.id)).toEqual([
1403
1936
  "a-pending"
1404
1937
  ]);
1405
- expect2((await store.listIncompleteRuns("alpha")).map((r) => r.id)).toEqual([
1938
+ expect3((await store.listIncompleteRuns("alpha")).map((r) => r.id)).toEqual([
1406
1939
  "a-running"
1407
1940
  ]);
1408
- expect2((await store.listDueTimers(1e4, "alpha")).map((r) => r.id)).toEqual([
1941
+ expect3((await store.listDueTimers(1e4, "alpha")).map((r) => r.id)).toEqual([
1409
1942
  "a-timer"
1410
1943
  ]);
1411
- expect2((await store.listRuns({
1944
+ expect3((await store.listRuns({
1412
1945
  namespace: "alpha",
1413
1946
  status: "running"
1414
1947
  })).map((r) => r.id)).toEqual([
1415
1948
  "a-running"
1416
1949
  ]);
1417
- expect2((await store.listPendingRuns(1, "alpha")).map((r) => r.id)).toEqual([
1950
+ expect3((await store.listPendingRuns(1, "alpha")).map((r) => r.id)).toEqual([
1418
1951
  "a-pending"
1419
1952
  ]);
1420
- expect2((await store.listPendingRuns(10)).map((r) => r.id).sort()).toEqual([
1953
+ expect3((await store.listPendingRuns(10)).map((r) => r.id).sort()).toEqual([
1421
1954
  "a-pending",
1422
1955
  "b-pending"
1423
1956
  ]);
1424
- expect2((await store.listIncompleteRuns()).map((r) => r.id).sort()).toEqual([
1957
+ expect3((await store.listIncompleteRuns()).map((r) => r.id).sort()).toEqual([
1425
1958
  "a-running",
1426
1959
  "b-running"
1427
1960
  ]);
1428
- expect2((await store.listDueTimers(1e4)).map((r) => r.id).sort()).toEqual([
1961
+ expect3((await store.listDueTimers(1e4)).map((r) => r.id).sort()).toEqual([
1429
1962
  "a-timer",
1430
1963
  "b-timer"
1431
1964
  ]);
@@ -1434,20 +1967,20 @@ function runStateStoreContract(name, makeStore) {
1434
1967
  await store.createRun(run({
1435
1968
  id: "r1"
1436
1969
  }));
1437
- expect2(await store.tryLockRun("r1", "A", 2e3, 1e3)).toBe(true);
1438
- expect2(await store.tryLockRun("r1", "B", 3e3, 1500)).toBe(false);
1439
- expect2(await store.tryLockRun("r1", "B", 4e3, 2500)).toBe(true);
1970
+ expect3(await store.tryLockRun("r1", "A", 2e3, 1e3)).toBe(true);
1971
+ expect3(await store.tryLockRun("r1", "B", 3e3, 1500)).toBe(false);
1972
+ expect3(await store.tryLockRun("r1", "B", 4e3, 2500)).toBe(true);
1440
1973
  await store.releaseRunLock("r1");
1441
- expect2(await store.tryLockRun("r1", "C", 9e3, 2600)).toBe(true);
1974
+ expect3(await store.tryLockRun("r1", "C", 9e3, 2600)).toBe(true);
1442
1975
  });
1443
1976
  t("renewRunLock only succeeds for the current owner", async () => {
1444
1977
  await store.createRun(run({
1445
1978
  id: "r1"
1446
1979
  }));
1447
- expect2(await store.tryLockRun("r1", "A", 2e3, 1e3)).toBe(true);
1448
- expect2(await store.renewRunLock("r1", "A", 5e3)).toBe(true);
1449
- expect2(await store.renewRunLock("r1", "B", 9e3)).toBe(false);
1450
- expect2(await store.tryLockRun("r1", "B", 6e3, 4e3)).toBe(false);
1980
+ expect3(await store.tryLockRun("r1", "A", 2e3, 1e3)).toBe(true);
1981
+ expect3(await store.renewRunLock("r1", "A", 5e3)).toBe(true);
1982
+ expect3(await store.renewRunLock("r1", "B", 9e3)).toBe(false);
1983
+ expect3(await store.tryLockRun("r1", "B", 6e3, 4e3)).toBe(false);
1451
1984
  });
1452
1985
  t("filters listRuns by workflow and by status", async () => {
1453
1986
  await store.createRun(run({
@@ -1465,19 +1998,19 @@ function runStateStoreContract(name, makeStore) {
1465
1998
  workflow: "checkout",
1466
1999
  status: "completed"
1467
2000
  }));
1468
- expect2((await store.listRuns({
2001
+ expect3((await store.listRuns({
1469
2002
  workflow: "checkout"
1470
2003
  })).map((r) => r.id).sort()).toEqual([
1471
2004
  "a",
1472
2005
  "c"
1473
2006
  ]);
1474
- expect2((await store.listRuns({
2007
+ expect3((await store.listRuns({
1475
2008
  status: "running"
1476
2009
  })).map((r) => r.id).sort()).toEqual([
1477
2010
  "a",
1478
2011
  "b"
1479
2012
  ]);
1480
- expect2((await store.listRuns({
2013
+ expect3((await store.listRuns({
1481
2014
  workflow: "checkout",
1482
2015
  status: "running"
1483
2016
  })).map((r) => r.id)).toEqual([
@@ -1501,7 +2034,7 @@ function runStateStoreContract(name, makeStore) {
1501
2034
  id: "d",
1502
2035
  status: "pending"
1503
2036
  }));
1504
- expect2((await store.listRuns({
2037
+ expect3((await store.listRuns({
1505
2038
  statuses: [
1506
2039
  "running",
1507
2040
  "suspended"
@@ -1510,7 +2043,7 @@ function runStateStoreContract(name, makeStore) {
1510
2043
  "a",
1511
2044
  "b"
1512
2045
  ]);
1513
- expect2((await store.listRuns({
2046
+ expect3((await store.listRuns({
1514
2047
  status: "running",
1515
2048
  statuses: [
1516
2049
  "running",
@@ -1519,7 +2052,7 @@ function runStateStoreContract(name, makeStore) {
1519
2052
  })).map((r) => r.id)).toEqual([
1520
2053
  "a"
1521
2054
  ]);
1522
- expect2(await store.listRuns({
2055
+ expect3(await store.listRuns({
1523
2056
  statuses: []
1524
2057
  })).toHaveLength(0);
1525
2058
  });
@@ -1541,21 +2074,21 @@ function runStateStoreContract(name, makeStore) {
1541
2074
  await store.createRun(run({
1542
2075
  id: "c"
1543
2076
  }));
1544
- expect2((await store.getRun("a"))?.tags).toEqual([
2077
+ expect3((await store.getRun("a"))?.tags).toEqual([
1545
2078
  "etl",
1546
2079
  "critical"
1547
2080
  ]);
1548
- expect2((await store.listRuns({
2081
+ expect3((await store.listRuns({
1549
2082
  tag: "etl"
1550
2083
  })).map((r) => r.id)).toEqual([
1551
2084
  "a"
1552
2085
  ]);
1553
- expect2((await store.listRuns({
2086
+ expect3((await store.listRuns({
1554
2087
  tag: "etl-foo"
1555
2088
  })).map((r) => r.id)).toEqual([
1556
2089
  "b"
1557
2090
  ]);
1558
- expect2(await store.listRuns({
2091
+ expect3(await store.listRuns({
1559
2092
  tag: "nope"
1560
2093
  })).toHaveLength(0);
1561
2094
  });
@@ -1571,17 +2104,17 @@ function runStateStoreContract(name, makeStore) {
1571
2104
  await store.createRun(run({
1572
2105
  id: "c"
1573
2106
  }));
1574
- expect2((await store.getRun("a"))?.origin).toBe("@dudousxd/nestjs-catalog-pipeline");
1575
- expect2((await store.getRun("c"))?.origin).toBeUndefined();
1576
- expect2((await store.listRuns({
2107
+ expect3((await store.getRun("a"))?.origin).toBe("@dudousxd/nestjs-catalog-pipeline");
2108
+ expect3((await store.getRun("c"))?.origin).toBeUndefined();
2109
+ expect3((await store.listRuns({
1577
2110
  origin: "@dudousxd/nestjs-catalog-pipeline"
1578
2111
  })).map((r) => r.id)).toEqual([
1579
2112
  "a"
1580
2113
  ]);
1581
- expect2(await store.listRuns({
2114
+ expect3(await store.listRuns({
1582
2115
  origin: "unknown"
1583
2116
  })).toEqual([]);
1584
- expect2((await store.listRuns({})).map((r) => r.id).sort()).toEqual([
2117
+ expect3((await store.listRuns({})).map((r) => r.id).sort()).toEqual([
1585
2118
  "a",
1586
2119
  "b",
1587
2120
  "c"
@@ -1598,7 +2131,7 @@ function runStateStoreContract(name, makeStore) {
1598
2131
  await store.createRun(run({
1599
2132
  id: "c"
1600
2133
  }));
1601
- expect2((await store.listRuns({
2134
+ expect3((await store.listRuns({
1602
2135
  origin: null
1603
2136
  })).map((r) => r.id).sort()).toEqual([
1604
2137
  "b",
@@ -1608,7 +2141,7 @@ function runStateStoreContract(name, makeStore) {
1608
2141
  id: "d",
1609
2142
  status: "dead"
1610
2143
  }));
1611
- expect2((await store.listRuns({
2144
+ expect3((await store.listRuns({
1612
2145
  origin: null,
1613
2146
  status: "dead"
1614
2147
  })).map((r) => r.id)).toEqual([
@@ -1641,22 +2174,22 @@ function runStateStoreContract(name, makeStore) {
1641
2174
  status: "failed"
1642
2175
  }));
1643
2176
  const facets = await store.runFacets({});
1644
- expect2(facets).toContainEqual({
2177
+ expect3(facets).toContainEqual({
1645
2178
  status: "completed",
1646
2179
  origin: "pkg-a",
1647
2180
  count: 2
1648
2181
  });
1649
- expect2(facets).toContainEqual({
2182
+ expect3(facets).toContainEqual({
1650
2183
  status: "failed",
1651
2184
  origin: "pkg-b",
1652
2185
  count: 1
1653
2186
  });
1654
- expect2(facets).toContainEqual({
2187
+ expect3(facets).toContainEqual({
1655
2188
  status: "failed",
1656
2189
  origin: null,
1657
2190
  count: 2
1658
2191
  });
1659
- expect2(facets.reduce((n, f) => n + f.count, 0)).toBe(5);
2192
+ expect3(facets.reduce((n, f) => n + f.count, 0)).toBe(5);
1660
2193
  });
1661
2194
  t("narrows runFacets on the same predicates listRuns pages", async () => {
1662
2195
  if (!store.runFacets) return;
@@ -1670,7 +2203,7 @@ function runStateStoreContract(name, makeStore) {
1670
2203
  status: "failed",
1671
2204
  namespace: "globex"
1672
2205
  }));
1673
- expect2(await store.runFacets({
2206
+ expect3(await store.runFacets({
1674
2207
  namespace: "acme"
1675
2208
  })).toEqual([
1676
2209
  {
@@ -1699,7 +2232,7 @@ function runStateStoreContract(name, makeStore) {
1699
2232
  namespace: "initech",
1700
2233
  workflow: "wc"
1701
2234
  }));
1702
- expect2((await store.listRuns({
2235
+ expect3((await store.listRuns({
1703
2236
  statuses: [
1704
2237
  "failed",
1705
2238
  "dead"
@@ -1708,7 +2241,7 @@ function runStateStoreContract(name, makeStore) {
1708
2241
  "a",
1709
2242
  "b"
1710
2243
  ]);
1711
- expect2((await store.listRuns({
2244
+ expect3((await store.listRuns({
1712
2245
  namespaces: [
1713
2246
  "acme",
1714
2247
  "globex"
@@ -1717,7 +2250,7 @@ function runStateStoreContract(name, makeStore) {
1717
2250
  "a",
1718
2251
  "b"
1719
2252
  ]);
1720
- expect2((await store.listRuns({
2253
+ expect3((await store.listRuns({
1721
2254
  workflows: [
1722
2255
  "wa",
1723
2256
  "wc"
@@ -1739,7 +2272,7 @@ function runStateStoreContract(name, makeStore) {
1739
2272
  await store.createRun(run({
1740
2273
  id: "c"
1741
2274
  }));
1742
- expect2((await store.listRuns({
2275
+ expect3((await store.listRuns({
1743
2276
  origins: [
1744
2277
  "pkg-a",
1745
2278
  null
@@ -1748,7 +2281,7 @@ function runStateStoreContract(name, makeStore) {
1748
2281
  "a",
1749
2282
  "c"
1750
2283
  ]);
1751
- expect2((await store.listRuns({
2284
+ expect3((await store.listRuns({
1752
2285
  origins: [
1753
2286
  "pkg-a",
1754
2287
  "pkg-b"
@@ -1769,7 +2302,7 @@ function runStateStoreContract(name, makeStore) {
1769
2302
  status: "dead",
1770
2303
  namespace: "acme"
1771
2304
  }));
1772
- expect2((await store.listRuns({
2305
+ expect3((await store.listRuns({
1773
2306
  namespaces: [
1774
2307
  "acme"
1775
2308
  ],
@@ -1779,13 +2312,13 @@ function runStateStoreContract(name, makeStore) {
1779
2312
  })).map((r) => r.id)).toEqual([
1780
2313
  "b"
1781
2314
  ]);
1782
- expect2(await store.listRuns({
2315
+ expect3(await store.listRuns({
1783
2316
  namespaces: []
1784
2317
  })).toEqual([]);
1785
- expect2(await store.listRuns({
2318
+ expect3(await store.listRuns({
1786
2319
  statuses: []
1787
2320
  })).toEqual([]);
1788
- expect2(await store.listRuns({
2321
+ expect3(await store.listRuns({
1789
2322
  origins: []
1790
2323
  })).toEqual([]);
1791
2324
  });
@@ -1810,7 +2343,7 @@ function runStateStoreContract(name, makeStore) {
1810
2343
  "adhoc"
1811
2344
  ]
1812
2345
  }));
1813
- expect2((await store.listRuns({
2346
+ expect3((await store.listRuns({
1814
2347
  tags: [
1815
2348
  "etl",
1816
2349
  "nightly"
@@ -1819,7 +2352,7 @@ function runStateStoreContract(name, makeStore) {
1819
2352
  "a",
1820
2353
  "b"
1821
2354
  ]);
1822
- expect2(await store.listRuns({
2355
+ expect3(await store.listRuns({
1823
2356
  tags: []
1824
2357
  })).toEqual([]);
1825
2358
  });
@@ -1860,7 +2393,7 @@ function runStateStoreContract(name, makeStore) {
1860
2393
  }
1861
2394
  ]
1862
2395
  });
1863
- expect2(inSet.map((r) => r.id).sort()).toEqual([
2396
+ expect3(inSet.map((r) => r.id).sort()).toEqual([
1864
2397
  "a",
1865
2398
  "b"
1866
2399
  ]);
@@ -1876,10 +2409,10 @@ function runStateStoreContract(name, makeStore) {
1876
2409
  }
1877
2410
  ]
1878
2411
  });
1879
- expect2(mixed.map((r) => r.id)).toEqual([
2412
+ expect3(mixed.map((r) => r.id)).toEqual([
1880
2413
  "d"
1881
2414
  ]);
1882
- expect2(await store.listRuns({
2415
+ expect3(await store.listRuns({
1883
2416
  attributes: [
1884
2417
  {
1885
2418
  key: "tier",
@@ -1888,7 +2421,7 @@ function runStateStoreContract(name, makeStore) {
1888
2421
  }
1889
2422
  ]
1890
2423
  })).toEqual([]);
1891
- expect2((await store.listRuns({
2424
+ expect3((await store.listRuns({
1892
2425
  attributes: [
1893
2426
  {
1894
2427
  key: "tier",
@@ -1916,7 +2449,7 @@ function runStateStoreContract(name, makeStore) {
1916
2449
  id: "c",
1917
2450
  namespace: "globex"
1918
2451
  }));
1919
- expect2(await store.runValueFacets({
2452
+ expect3(await store.runValueFacets({
1920
2453
  field: "namespace"
1921
2454
  }, {})).toEqual([
1922
2455
  {
@@ -1941,11 +2474,11 @@ function runStateStoreContract(name, makeStore) {
1941
2474
  const values = await store.runValueFacets({
1942
2475
  field: "origin"
1943
2476
  }, {});
1944
- expect2(values).toContainEqual({
2477
+ expect3(values).toContainEqual({
1945
2478
  value: "pkg-a",
1946
2479
  count: 1
1947
2480
  });
1948
- expect2(values).toContainEqual({
2481
+ expect3(values).toContainEqual({
1949
2482
  value: null,
1950
2483
  count: 1
1951
2484
  });
@@ -1967,7 +2500,7 @@ function runStateStoreContract(name, makeStore) {
1967
2500
  "nightly"
1968
2501
  ]
1969
2502
  }));
1970
- expect2(await store.runValueFacets({
2503
+ expect3(await store.runValueFacets({
1971
2504
  field: "tag"
1972
2505
  }, {
1973
2506
  namespace: "acme"
@@ -1999,7 +2532,7 @@ function runStateStoreContract(name, makeStore) {
1999
2532
  tier: "free"
2000
2533
  }
2001
2534
  }));
2002
- expect2(await store.runValueFacets({
2535
+ expect3(await store.runValueFacets({
2003
2536
  field: "tag"
2004
2537
  }, {})).toEqual([
2005
2538
  {
@@ -2011,7 +2544,7 @@ function runStateStoreContract(name, makeStore) {
2011
2544
  count: 1
2012
2545
  }
2013
2546
  ]);
2014
- expect2(await store.runValueFacets({
2547
+ expect3(await store.runValueFacets({
2015
2548
  field: "attributeKey"
2016
2549
  }, {})).toEqual([
2017
2550
  {
@@ -2019,7 +2552,7 @@ function runStateStoreContract(name, makeStore) {
2019
2552
  count: 2
2020
2553
  }
2021
2554
  ]);
2022
- expect2((await store.runValueFacets({
2555
+ expect3((await store.runValueFacets({
2023
2556
  field: "attributeValue",
2024
2557
  key: "tier"
2025
2558
  }, {})).map((r) => r.value).sort()).toEqual([
@@ -2050,18 +2583,18 @@ function runStateStoreContract(name, makeStore) {
2050
2583
  }, {}, {
2051
2584
  search: "acme"
2052
2585
  });
2053
- expect2(matches.map((row) => row.value).sort()).toEqual([
2586
+ expect3(matches.map((row) => row.value).sort()).toEqual([
2054
2587
  "acme-prod",
2055
2588
  "acme-staging"
2056
2589
  ]);
2057
- expect2((await store.runValueFacets({
2590
+ expect3((await store.runValueFacets({
2058
2591
  field: "namespace"
2059
2592
  }, {}, {
2060
2593
  limit: 1
2061
2594
  })).map((r) => r.value)).toEqual([
2062
2595
  "globex"
2063
2596
  ]);
2064
- expect2((await store.runValueFacets({
2597
+ expect3((await store.runValueFacets({
2065
2598
  field: "namespace"
2066
2599
  }, {}, {
2067
2600
  limit: 1,
@@ -2107,7 +2640,7 @@ function runStateStoreContract(name, makeStore) {
2107
2640
  limit: 2,
2108
2641
  offset: 2
2109
2642
  });
2110
- expect2(first).toEqual([
2643
+ expect3(first).toEqual([
2111
2644
  {
2112
2645
  value: "one",
2113
2646
  count: 3
@@ -2117,13 +2650,13 @@ function runStateStoreContract(name, makeStore) {
2117
2650
  count: 2
2118
2651
  }
2119
2652
  ]);
2120
- expect2(second).toEqual([
2653
+ expect3(second).toEqual([
2121
2654
  {
2122
2655
  value: "three",
2123
2656
  count: 1
2124
2657
  }
2125
2658
  ]);
2126
- expect2(new Set([
2659
+ expect3(new Set([
2127
2660
  ...first,
2128
2661
  ...second
2129
2662
  ].map((r) => r.value)).size).toBe(3);
@@ -2151,7 +2684,7 @@ function runStateStoreContract(name, makeStore) {
2151
2684
  "etl"
2152
2685
  ]
2153
2686
  }));
2154
- expect2((await store.runValueFacets({
2687
+ expect3((await store.runValueFacets({
2155
2688
  field: "tag"
2156
2689
  }, {}, {
2157
2690
  search: "type:"
@@ -2159,7 +2692,7 @@ function runStateStoreContract(name, makeStore) {
2159
2692
  "type:mel",
2160
2693
  "type:mvr"
2161
2694
  ]);
2162
- expect2(await store.runValueFacets({
2695
+ expect3(await store.runValueFacets({
2163
2696
  field: "tag"
2164
2697
  }, {}, {
2165
2698
  limit: 1
@@ -2184,7 +2717,7 @@ function runStateStoreContract(name, makeStore) {
2184
2717
  id: "c",
2185
2718
  namespace: "globex"
2186
2719
  }));
2187
- expect2(await store.runValueFacets({
2720
+ expect3(await store.runValueFacets({
2188
2721
  field: "namespace"
2189
2722
  }, {}, {
2190
2723
  limit: 1
@@ -2196,7 +2729,7 @@ function runStateStoreContract(name, makeStore) {
2196
2729
  ]);
2197
2730
  });
2198
2731
  t("countRuns counts the same set listRuns returns, without the paging", async () => {
2199
- expect2(typeof store.countRuns).toBe("function");
2732
+ expect3(typeof store.countRuns).toBe("function");
2200
2733
  await store.createRun(run({
2201
2734
  id: "n1",
2202
2735
  status: "running",
@@ -2226,22 +2759,22 @@ function runStateStoreContract(name, makeStore) {
2226
2759
  "q"
2227
2760
  ]
2228
2761
  }));
2229
- expect2(await store.countRuns?.({})).toBe(4);
2230
- expect2(await store.countRuns?.({
2762
+ expect3(await store.countRuns?.({})).toBe(4);
2763
+ expect3(await store.countRuns?.({
2231
2764
  namespace: "a"
2232
2765
  })).toBe(3);
2233
- expect2(await store.countRuns?.({
2766
+ expect3(await store.countRuns?.({
2234
2767
  namespace: "a",
2235
2768
  statuses: [
2236
2769
  "pending",
2237
2770
  "running"
2238
2771
  ]
2239
2772
  })).toBe(2);
2240
- expect2(await store.countRuns?.({
2773
+ expect3(await store.countRuns?.({
2241
2774
  statuses: []
2242
2775
  })).toBe(0);
2243
2776
  if (supportsTagFilter) {
2244
- expect2(await store.countRuns?.({
2777
+ expect3(await store.countRuns?.({
2245
2778
  tag: "q",
2246
2779
  statuses: [
2247
2780
  "running",
@@ -2268,28 +2801,28 @@ function runStateStoreContract(name, makeStore) {
2268
2801
  await engine.start("q-wait", {}, "q1", {
2269
2802
  concurrency: quota
2270
2803
  });
2271
- expect2((await engine.waitForRun("q1", {
2804
+ expect3((await engine.waitForRun("q1", {
2272
2805
  timeoutMs: 2e4
2273
2806
  })).status).toBe("suspended");
2274
- await expect2(engine.start("q-wait", {}, "q2", {
2807
+ await expect3(engine.start("q-wait", {}, "q2", {
2275
2808
  concurrency: quota
2276
2809
  })).rejects.toThrow(/concurrency limit/);
2277
- expect2(await store.getRun("q2")).toBeNull();
2810
+ expect3(await store.getRun("q2")).toBeNull();
2278
2811
  await engine.start("q-wait", {}, "q3", {
2279
2812
  concurrency: {
2280
2813
  ...quota,
2281
2814
  key: "tenant:b"
2282
2815
  }
2283
2816
  });
2284
- expect2((await engine.waitForRun("q1", {
2817
+ expect3((await engine.waitForRun("q1", {
2285
2818
  timeoutMs: 2e4
2286
2819
  })).status).toBe("suspended");
2287
2820
  await engine.cancel("q1");
2288
- expect2((await store.getRun("q1"))?.status).toBe("cancelled");
2821
+ expect3((await store.getRun("q1"))?.status).toBe("cancelled");
2289
2822
  await engine.start("q-wait", {}, "q4", {
2290
2823
  concurrency: quota
2291
2824
  });
2292
- expect2(await store.getRun("q4")).not.toBeNull();
2825
+ expect3(await store.getRun("q4")).not.toBeNull();
2293
2826
  for (const id of [
2294
2827
  "q3",
2295
2828
  "q4"
@@ -2328,10 +2861,10 @@ function runStateStoreContract(name, makeStore) {
2328
2861
  ...over
2329
2862
  }), "schedule");
2330
2863
  t("saves, reads back, replaces and deletes a schedule", async () => {
2331
- expect2(typeof store.saveSchedule).toBe("function");
2864
+ expect3(typeof store.saveSchedule).toBe("function");
2332
2865
  await store.saveSchedule?.(schedule());
2333
2866
  const loaded = await store.getSchedule?.("s1");
2334
- expect2(loaded).toMatchObject({
2867
+ expect3(loaded).toMatchObject({
2335
2868
  id: "s1",
2336
2869
  namespace: "default",
2337
2870
  workflow: "digest",
@@ -2357,27 +2890,27 @@ function runStateStoreContract(name, makeStore) {
2357
2890
  window: NOW + 6e4
2358
2891
  }
2359
2892
  });
2360
- expect2(loaded?.createdAt.getTime()).toBe(at.getTime());
2893
+ expect3(loaded?.createdAt.getTime()).toBe(at.getTime());
2361
2894
  await store.saveSchedule?.(schedule({
2362
2895
  workflow: "digest2",
2363
2896
  nextFireAt: null,
2364
2897
  tags: void 0
2365
2898
  }));
2366
2899
  const replaced = await store.getSchedule?.("s1");
2367
- expect2(replaced?.workflow).toBe("digest2");
2368
- expect2(replaced?.nextFireAt).toBeNull();
2369
- expect2(replaced?.tags ?? []).toEqual([]);
2370
- expect2(await store.getSchedule?.("nope")).toBeNull();
2371
- expect2(await store.deleteSchedule?.("s1")).toBe(true);
2372
- expect2(await store.deleteSchedule?.("s1")).toBe(false);
2373
- expect2(await store.getSchedule?.("s1")).toBeNull();
2900
+ expect3(replaced?.workflow).toBe("digest2");
2901
+ expect3(replaced?.nextFireAt).toBeNull();
2902
+ expect3(replaced?.tags ?? []).toEqual([]);
2903
+ expect3(await store.getSchedule?.("nope")).toBeNull();
2904
+ expect3(await store.deleteSchedule?.("s1")).toBe(true);
2905
+ expect3(await store.deleteSchedule?.("s1")).toBe(false);
2906
+ expect3(await store.getSchedule?.("s1")).toBeNull();
2374
2907
  });
2375
2908
  t("updateSchedule patches, and compare-and-sets on nextFireAt", async () => {
2376
2909
  await store.saveSchedule?.(schedule());
2377
- expect2(await store.updateSchedule?.("s1", {
2910
+ expect3(await store.updateSchedule?.("s1", {
2378
2911
  paused: true
2379
2912
  })).toBe(true);
2380
- expect2((await store.getSchedule?.("s1"))?.paused).toBe(true);
2913
+ expect3((await store.getSchedule?.("s1"))?.paused).toBe(true);
2381
2914
  const next = {
2382
2915
  nextFireAt: NOW + 12e4,
2383
2916
  state: {
@@ -2385,24 +2918,24 @@ function runStateStoreContract(name, makeStore) {
2385
2918
  fires: 1
2386
2919
  }
2387
2920
  };
2388
- expect2(await store.updateSchedule?.("s1", next, NOW + 6e4)).toBe(true);
2389
- expect2(await store.updateSchedule?.("s1", next, NOW + 6e4)).toBe(false);
2921
+ expect3(await store.updateSchedule?.("s1", next, NOW + 6e4)).toBe(true);
2922
+ expect3(await store.updateSchedule?.("s1", next, NOW + 6e4)).toBe(false);
2390
2923
  const after = await store.getSchedule?.("s1");
2391
- expect2(after?.nextFireAt).toBe(NOW + 12e4);
2392
- expect2(after?.state).toEqual({
2924
+ expect3(after?.nextFireAt).toBe(NOW + 12e4);
2925
+ expect3(after?.state).toEqual({
2393
2926
  window: NOW + 12e4,
2394
2927
  fires: 1
2395
2928
  });
2396
2929
  await store.updateSchedule?.("s1", {
2397
2930
  nextFireAt: null
2398
2931
  });
2399
- expect2(await store.updateSchedule?.("s1", {
2932
+ expect3(await store.updateSchedule?.("s1", {
2400
2933
  nextFireAt: NOW
2401
2934
  }, NOW + 1)).toBe(false);
2402
- expect2(await store.updateSchedule?.("s1", {
2935
+ expect3(await store.updateSchedule?.("s1", {
2403
2936
  nextFireAt: NOW
2404
2937
  }, null)).toBe(true);
2405
- expect2(await store.updateSchedule?.("ghost", {
2938
+ expect3(await store.updateSchedule?.("ghost", {
2406
2939
  paused: true
2407
2940
  })).toBe(false);
2408
2941
  });
@@ -2434,47 +2967,47 @@ function runStateStoreContract(name, makeStore) {
2434
2967
  ]
2435
2968
  }));
2436
2969
  const ids2 = /* @__PURE__ */ __name(async (q) => (await store.listSchedules?.(q) ?? []).map((r) => r.id), "ids");
2437
- expect2(await ids2({})).toEqual([
2970
+ expect3(await ids2({})).toEqual([
2438
2971
  "c",
2439
2972
  "b",
2440
2973
  "a",
2441
2974
  "d",
2442
2975
  "e"
2443
2976
  ]);
2444
- expect2(await ids2({
2977
+ expect3(await ids2({
2445
2978
  dueBy: NOW
2446
2979
  })).toEqual([
2447
2980
  "b",
2448
2981
  "a"
2449
2982
  ]);
2450
- expect2(await ids2({
2983
+ expect3(await ids2({
2451
2984
  dueBy: NOW,
2452
2985
  namespace: "default"
2453
2986
  })).toEqual([
2454
2987
  "a"
2455
2988
  ]);
2456
- expect2(await ids2({
2989
+ expect3(await ids2({
2457
2990
  dueBy: NOW,
2458
2991
  limit: 1
2459
2992
  })).toEqual([
2460
2993
  "b"
2461
2994
  ]);
2462
- expect2(await ids2({
2995
+ expect3(await ids2({
2463
2996
  workflow: "other"
2464
2997
  })).toEqual([
2465
2998
  "d"
2466
2999
  ]);
2467
- expect2(await ids2({
3000
+ expect3(await ids2({
2468
3001
  paused: true
2469
3002
  })).toEqual([
2470
3003
  "c"
2471
3004
  ]);
2472
- if (supportsTagFilter) expect2(await ids2({
3005
+ if (supportsTagFilter) expect3(await ids2({
2473
3006
  tag: "tenant:b"
2474
3007
  })).toEqual([
2475
3008
  "e"
2476
3009
  ]);
2477
- expect2(await ids2({
3010
+ expect3(await ids2({
2478
3011
  limit: 2,
2479
3012
  offset: 1
2480
3013
  })).toEqual([
@@ -2495,18 +3028,18 @@ function runStateStoreContract(name, makeStore) {
2495
3028
  id: "new",
2496
3029
  createdAt: /* @__PURE__ */ new Date("2026-06-11T00:00:02.000Z")
2497
3030
  }));
2498
- expect2((await store.listRuns({})).map((r) => r.id)).toEqual([
3031
+ expect3((await store.listRuns({})).map((r) => r.id)).toEqual([
2499
3032
  "new",
2500
3033
  "mid",
2501
3034
  "old"
2502
3035
  ]);
2503
- expect2((await store.listRuns({
3036
+ expect3((await store.listRuns({
2504
3037
  limit: 2
2505
3038
  })).map((r) => r.id)).toEqual([
2506
3039
  "new",
2507
3040
  "mid"
2508
3041
  ]);
2509
- expect2((await store.listRuns({
3042
+ expect3((await store.listRuns({
2510
3043
  limit: 2,
2511
3044
  offset: 1
2512
3045
  })).map((r) => r.id)).toEqual([
@@ -2536,11 +3069,11 @@ function runStateStoreContract(name, makeStore) {
2536
3069
  tier: "pro"
2537
3070
  }
2538
3071
  }));
2539
- expect2((await store.getRun("b"))?.searchAttributes).toEqual({
3072
+ expect3((await store.getRun("b"))?.searchAttributes).toEqual({
2540
3073
  amount: 200,
2541
3074
  tier: "pro"
2542
3075
  });
2543
- expect2((await store.listRuns({
3076
+ expect3((await store.listRuns({
2544
3077
  attributes: [
2545
3078
  {
2546
3079
  key: "amount",
@@ -2552,7 +3085,7 @@ function runStateStoreContract(name, makeStore) {
2552
3085
  "b",
2553
3086
  "c"
2554
3087
  ]);
2555
- expect2((await store.listRuns({
3088
+ expect3((await store.listRuns({
2556
3089
  attributes: [
2557
3090
  {
2558
3091
  key: "tier",
@@ -2568,7 +3101,7 @@ function runStateStoreContract(name, makeStore) {
2568
3101
  })).map((r) => r.id)).toEqual([
2569
3102
  "b"
2570
3103
  ]);
2571
- expect2((await store.listRuns({
3104
+ expect3((await store.listRuns({
2572
3105
  attributes: [
2573
3106
  {
2574
3107
  key: "tier",
@@ -2600,7 +3133,7 @@ function runStateStoreContract(name, makeStore) {
2600
3133
  other: 1
2601
3134
  }
2602
3135
  }));
2603
- expect2((await store.listRuns({
3136
+ expect3((await store.listRuns({
2604
3137
  attributes: [
2605
3138
  {
2606
3139
  key: "vip",
@@ -2611,7 +3144,7 @@ function runStateStoreContract(name, makeStore) {
2611
3144
  })).map((r) => r.id)).toEqual([
2612
3145
  "a"
2613
3146
  ]);
2614
- expect2((await store.listRuns({
3147
+ expect3((await store.listRuns({
2615
3148
  attributes: [
2616
3149
  {
2617
3150
  key: "vip",
@@ -2638,7 +3171,7 @@ function runStateStoreContract(name, makeStore) {
2638
3171
  "lt",
2639
3172
  "lte"
2640
3173
  ]) {
2641
- expect2(await store.listRuns({
3174
+ expect3(await store.listRuns({
2642
3175
  attributes: [
2643
3176
  {
2644
3177
  key: "missing",
@@ -2657,7 +3190,7 @@ function runStateStoreContract(name, makeStore) {
2657
3190
  amount: 10
2658
3191
  }
2659
3192
  }));
2660
- expect2((await store.listRuns({
3193
+ expect3((await store.listRuns({
2661
3194
  attributes: [
2662
3195
  {
2663
3196
  key: "tier",
@@ -2673,7 +3206,7 @@ function runStateStoreContract(name, makeStore) {
2673
3206
  tier: "pro"
2674
3207
  }
2675
3208
  });
2676
- expect2((await store.listRuns({
3209
+ expect3((await store.listRuns({
2677
3210
  attributes: [
2678
3211
  {
2679
3212
  key: "tier",
@@ -2684,7 +3217,7 @@ function runStateStoreContract(name, makeStore) {
2684
3217
  })).map((r) => r.id)).toEqual([
2685
3218
  "a"
2686
3219
  ]);
2687
- expect2(await store.listRuns({
3220
+ expect3(await store.listRuns({
2688
3221
  attributes: [
2689
3222
  {
2690
3223
  key: "tier",
@@ -2693,7 +3226,7 @@ function runStateStoreContract(name, makeStore) {
2693
3226
  }
2694
3227
  ]
2695
3228
  })).toHaveLength(0);
2696
- expect2(await store.listRuns({
3229
+ expect3(await store.listRuns({
2697
3230
  attributes: [
2698
3231
  {
2699
3232
  key: "amount",
@@ -2736,7 +3269,7 @@ function runStateStoreContract(name, makeStore) {
2736
3269
  ],
2737
3270
  limit: 10
2738
3271
  });
2739
- expect2(res.map((r) => r.id)).toEqual([
3272
+ expect3(res.map((r) => r.id)).toEqual([
2740
3273
  "a"
2741
3274
  ]);
2742
3275
  });
@@ -2756,12 +3289,12 @@ function runStateStoreContract(name, makeStore) {
2756
3289
  runId: "r3",
2757
3290
  seq: 5
2758
3291
  });
2759
- expect2((await store.listSignalWaiters("approve-")).map((w) => w.token).sort()).toEqual([
3292
+ expect3((await store.listSignalWaiters("approve-")).map((w) => w.token).sort()).toEqual([
2760
3293
  "approve-1",
2761
3294
  "approve-2"
2762
3295
  ]);
2763
- expect2((await store.takeSignalWaiter("approve-1"))?.seq).toBe(3);
2764
- expect2(await store.takeSignalWaiter("approve-1")).toBeNull();
3296
+ expect3((await store.takeSignalWaiter("approve-1"))?.seq).toBe(3);
3297
+ expect3(await store.takeSignalWaiter("approve-1")).toBeNull();
2765
3298
  });
2766
3299
  t("round-trips a signal waiter parallelGroup (child-fan tag) through put \u2192 take \u2192 list", async () => {
2767
3300
  await store.putSignalWaiter({
@@ -2776,13 +3309,13 @@ function runStateStoreContract(name, makeStore) {
2776
3309
  seq: 9
2777
3310
  });
2778
3311
  const listed = await store.listSignalWaiters("child:");
2779
- expect2(listed.find((w) => w.token === "child:r.child.0")?.parallelGroup).toBe("gather:0");
2780
- expect2(listed.find((w) => w.token === "child:r.child.9")?.parallelGroup).toBeUndefined();
2781
- expect2((await store.takeSignalWaiter("child:r.child.0"))?.parallelGroup).toBe("gather:0");
2782
- expect2((await store.takeSignalWaiter("child:r.child.9"))?.parallelGroup).toBeUndefined();
3312
+ expect3(listed.find((w) => w.token === "child:r.child.0")?.parallelGroup).toBe("gather:0");
3313
+ expect3(listed.find((w) => w.token === "child:r.child.9")?.parallelGroup).toBeUndefined();
3314
+ expect3((await store.takeSignalWaiter("child:r.child.0"))?.parallelGroup).toBe("gather:0");
3315
+ expect3((await store.takeSignalWaiter("child:r.child.9"))?.parallelGroup).toBeUndefined();
2783
3316
  });
2784
3317
  t("registerChildWaits writes every waiter and placeholder, and upserts on repeat", async () => {
2785
- expect2(store.registerChildWaits).toBeTypeOf("function");
3318
+ expect3(store.registerChildWaits).toBeTypeOf("function");
2786
3319
  await store.createRun(run({
2787
3320
  id: "p"
2788
3321
  }));
@@ -2808,24 +3341,24 @@ function runStateStoreContract(name, makeStore) {
2808
3341
  }, (_, i) => entry(i, "running"));
2809
3342
  await store.registerChildWaits?.(entries);
2810
3343
  const waiters = await store.listSignalWaiters("child:p.all.0.");
2811
- expect2(waiters).toHaveLength(250);
2812
- expect2(waiters.find((w) => w.token === "child:p.all.0.7")).toEqual(entries[7]?.waiter);
3344
+ expect3(waiters).toHaveLength(250);
3345
+ expect3(waiters.find((w) => w.token === "child:p.all.0.7")).toEqual(entries[7]?.waiter);
2813
3346
  const cps = await store.listCheckpoints("p");
2814
- expect2(cps).toHaveLength(250);
2815
- expect2(cps[7]).toMatchObject({
3347
+ expect3(cps).toHaveLength(250);
3348
+ expect3(cps[7]).toMatchObject({
2816
3349
  name: "signal:child:p.all.0.7",
2817
3350
  status: "running"
2818
3351
  });
2819
- expect2(cps[7]?.parallelGroup).toBe("all:0");
3352
+ expect3(cps[7]?.parallelGroup).toBe("all:0");
2820
3353
  await store.registerChildWaits?.([
2821
3354
  entry(7, "completed")
2822
3355
  ]);
2823
- expect2((await store.getCheckpoint("p", 7))?.status).toBe("completed");
2824
- expect2(await store.listCheckpoints("p")).toHaveLength(250);
2825
- await expect2(store.registerChildWaits?.([])).resolves.toBeUndefined();
3356
+ expect3((await store.getCheckpoint("p", 7))?.status).toBe("completed");
3357
+ expect3(await store.listCheckpoints("p")).toHaveLength(250);
3358
+ await expect3(store.registerChildWaits?.([])).resolves.toBeUndefined();
2826
3359
  });
2827
3360
  t("compactCheckpoints replaces a seq range with one checkpoint, atomically", async () => {
2828
- expect2(store.compactCheckpoints).toBeTypeOf("function");
3361
+ expect3(store.compactCheckpoints).toBeTypeOf("function");
2829
3362
  await store.createRun(run({
2830
3363
  id: "r"
2831
3364
  }));
@@ -2864,18 +3397,18 @@ function runStateStoreContract(name, makeStore) {
2864
3397
  });
2865
3398
  await store.compactCheckpoints?.("r", 2, 7, into);
2866
3399
  const left = await store.listCheckpoints("r");
2867
- expect2(left.map((cp) => cp.seq)).toEqual([
3400
+ expect3(left.map((cp2) => cp2.seq)).toEqual([
2868
3401
  0,
2869
3402
  1,
2870
3403
  2,
2871
3404
  8,
2872
3405
  9
2873
3406
  ]);
2874
- expect2(left[2]).toMatchObject({
3407
+ expect3(left[2]).toMatchObject({
2875
3408
  name: "fan:r.all.2.",
2876
3409
  parallelGroup: "all:2"
2877
3410
  });
2878
- expect2(left[2]?.output).toEqual({
3411
+ expect3(left[2]?.output).toEqual({
2879
3412
  from: 0,
2880
3413
  values: [
2881
3414
  {
@@ -2885,10 +3418,10 @@ function runStateStoreContract(name, makeStore) {
2885
3418
  null
2886
3419
  ]
2887
3420
  });
2888
- expect2(await store.listCheckpoints("other")).toHaveLength(1);
3421
+ expect3(await store.listCheckpoints("other")).toHaveLength(1);
2889
3422
  });
2890
3423
  t("listSignalWaitersByRun returns only the given runs' waiters", async () => {
2891
- expect2(store.listSignalWaitersByRun).toBeTypeOf("function");
3424
+ expect3(store.listSignalWaitersByRun).toBeTypeOf("function");
2892
3425
  await store.putSignalWaiter({
2893
3426
  token: "child:a.all.0.0",
2894
3427
  runId: "a",
@@ -2911,7 +3444,7 @@ function runStateStoreContract(name, makeStore) {
2911
3444
  seq: 0
2912
3445
  });
2913
3446
  const tokens = /* @__PURE__ */ __name(async (ids2) => (await store.listSignalWaitersByRun?.(ids2) ?? []).map((w) => w.token).sort(), "tokens");
2914
- expect2(await tokens([
3447
+ expect3(await tokens([
2915
3448
  "a",
2916
3449
  "b"
2917
3450
  ])).toEqual([
@@ -2919,11 +3452,11 @@ function runStateStoreContract(name, makeStore) {
2919
3452
  "approve-b",
2920
3453
  "child:a.all.0.0"
2921
3454
  ]);
2922
- expect2(await tokens([
3455
+ expect3(await tokens([
2923
3456
  "missing"
2924
3457
  ])).toEqual([]);
2925
- expect2(await tokens([])).toEqual([]);
2926
- expect2((await store.listSignalWaitersByRun?.([
3458
+ expect3(await tokens([])).toEqual([]);
3459
+ expect3((await store.listSignalWaitersByRun?.([
2927
3460
  "a"
2928
3461
  ]))?.find((w) => w.seq === 0)).toEqual({
2929
3462
  token: "child:a.all.0.0",
@@ -2933,7 +3466,7 @@ function runStateStoreContract(name, makeStore) {
2933
3466
  });
2934
3467
  });
2935
3468
  t("hasSignalWaiter answers by run and exact token prefix", async () => {
2936
- expect2(store.hasSignalWaiter).toBeTypeOf("function");
3469
+ expect3(store.hasSignalWaiter).toBeTypeOf("function");
2937
3470
  const has = /* @__PURE__ */ __name((runId, prefix) => store.hasSignalWaiter?.(runId, prefix), "has");
2938
3471
  await store.putSignalWaiter({
2939
3472
  token: "child:p_1.all.3.0",
@@ -2951,13 +3484,13 @@ function runStateStoreContract(name, makeStore) {
2951
3484
  runId: "p_1",
2952
3485
  seq: 9
2953
3486
  });
2954
- expect2(await has("p_1", "child:p_1.all.3.")).toBe(true);
2955
- expect2(await has("p_1", "child:p_1.all.4.")).toBe(false);
2956
- expect2(await has("other", "child:p_1.all.3.")).toBe(false);
2957
- expect2(await has("p_1", "child:p%.all.3.")).toBe(false);
2958
- expect2(await has("p_1", "CHILD:p_1.all.3.")).toBe(false);
3487
+ expect3(await has("p_1", "child:p_1.all.3.")).toBe(true);
3488
+ expect3(await has("p_1", "child:p_1.all.4.")).toBe(false);
3489
+ expect3(await has("other", "child:p_1.all.3.")).toBe(false);
3490
+ expect3(await has("p_1", "child:p%.all.3.")).toBe(false);
3491
+ expect3(await has("p_1", "CHILD:p_1.all.3.")).toBe(false);
2959
3492
  await store.takeSignalWaiter("child:p_1.all.3.0");
2960
- expect2(await has("p_1", "child:p_1.all.3.")).toBe(false);
3493
+ expect3(await has("p_1", "child:p_1.all.3.")).toBe(false);
2961
3494
  });
2962
3495
  t("removeSignalWaiter deletes only the exact (token, runId, seq) row, never a different run's", async () => {
2963
3496
  await store.putSignalWaiter({
@@ -2975,7 +3508,7 @@ function runStateStoreContract(name, makeStore) {
2975
3508
  runId: "r1",
2976
3509
  seq: 3
2977
3510
  });
2978
- expect2((await store.listSignalWaiters("approve-")).map((w) => w.runId)).toEqual([
3511
+ expect3((await store.listSignalWaiters("approve-")).map((w) => w.runId)).toEqual([
2979
3512
  "r2"
2980
3513
  ]);
2981
3514
  await store.removeSignalWaiter({
@@ -2983,7 +3516,7 @@ function runStateStoreContract(name, makeStore) {
2983
3516
  runId: "r2",
2984
3517
  seq: 999
2985
3518
  });
2986
- expect2((await store.listSignalWaiters("approve-")).map((w) => w.runId)).toEqual([
3519
+ expect3((await store.listSignalWaiters("approve-")).map((w) => w.runId)).toEqual([
2987
3520
  "r2"
2988
3521
  ]);
2989
3522
  await store.removeSignalWaiter({
@@ -2991,7 +3524,7 @@ function runStateStoreContract(name, makeStore) {
2991
3524
  runId: "r2",
2992
3525
  seq: 7
2993
3526
  });
2994
- expect2(await store.listSignalWaiters("approve-")).toEqual([]);
3527
+ expect3(await store.listSignalWaiters("approve-")).toEqual([]);
2995
3528
  await store.removeSignalWaiter({
2996
3529
  token: "never-registered",
2997
3530
  runId: "r1",
@@ -3008,18 +3541,18 @@ function runStateStoreContract(name, makeStore) {
3008
3541
  await store.bufferSignal("other", {
3009
3542
  n: 9
3010
3543
  });
3011
- expect2(await store.takeBufferedSignal("sig")).toEqual({
3544
+ expect3(await store.takeBufferedSignal("sig")).toEqual({
3012
3545
  payload: {
3013
3546
  n: 1
3014
3547
  }
3015
3548
  });
3016
- expect2(await store.takeBufferedSignal("sig")).toEqual({
3549
+ expect3(await store.takeBufferedSignal("sig")).toEqual({
3017
3550
  payload: {
3018
3551
  n: 2
3019
3552
  }
3020
3553
  });
3021
- expect2(await store.takeBufferedSignal("sig")).toBeNull();
3022
- expect2(await store.takeBufferedSignal("other")).toEqual({
3554
+ expect3(await store.takeBufferedSignal("sig")).toBeNull();
3555
+ expect3(await store.takeBufferedSignal("other")).toEqual({
3023
3556
  payload: {
3024
3557
  n: 9
3025
3558
  }
@@ -3051,7 +3584,7 @@ function runStateStoreContract(name, makeStore) {
3051
3584
  publishedAt: 50
3052
3585
  });
3053
3586
  const listed = await store.listBufferedEvents("order.paid", 10);
3054
- expect2(listed.map((e) => e.payload)).toEqual([
3587
+ expect3(listed.map((e) => e.payload)).toEqual([
3055
3588
  {
3056
3589
  n: 1
3057
3590
  },
@@ -3059,13 +3592,13 @@ function runStateStoreContract(name, makeStore) {
3059
3592
  n: 2
3060
3593
  }
3061
3594
  ]);
3062
- expect2(listed.map((e) => e.id)).toEqual([
3595
+ expect3(listed.map((e) => e.id)).toEqual([
3063
3596
  "e1",
3064
3597
  "e2"
3065
3598
  ]);
3066
- expect2(listed[0]?.publishedAt).toBe(100);
3067
- expect2(await store.listBufferedEvents("order.paid", 10)).toHaveLength(2);
3068
- expect2(await store.listBufferedEvents("other.event", 10)).toEqual([
3599
+ expect3(listed[0]?.publishedAt).toBe(100);
3600
+ expect3(await store.listBufferedEvents("order.paid", 10)).toHaveLength(2);
3601
+ expect3(await store.listBufferedEvents("other.event", 10)).toEqual([
3069
3602
  {
3070
3603
  id: "e3",
3071
3604
  payload: {
@@ -3094,7 +3627,7 @@ function runStateStoreContract(name, makeStore) {
3094
3627
  id: "c",
3095
3628
  publishedAt: 3
3096
3629
  });
3097
- expect2(await store.listBufferedEvents("evt", 2)).toHaveLength(2);
3630
+ expect3(await store.listBufferedEvents("evt", 2)).toHaveLength(2);
3098
3631
  });
3099
3632
  t("removeBufferedEvent atomically deletes by id \u2014 true iff a row existed, false on a repeat/absent id", async () => {
3100
3633
  await store.bufferEvent({
@@ -3105,10 +3638,10 @@ function runStateStoreContract(name, makeStore) {
3105
3638
  id: "x1",
3106
3639
  publishedAt: 1
3107
3640
  });
3108
- expect2(await store.removeBufferedEvent("x1")).toBe(true);
3109
- expect2(await store.listBufferedEvents("evt", 10)).toEqual([]);
3110
- expect2(await store.removeBufferedEvent("x1")).toBe(false);
3111
- expect2(await store.removeBufferedEvent("never-buffered")).toBe(false);
3641
+ expect3(await store.removeBufferedEvent("x1")).toBe(true);
3642
+ expect3(await store.listBufferedEvents("evt", 10)).toEqual([]);
3643
+ expect3(await store.removeBufferedEvent("x1")).toBe(false);
3644
+ expect3(await store.removeBufferedEvent("never-buffered")).toBe(false);
3112
3645
  });
3113
3646
  t("transaction commits the checkpoint atomically and returns the work result", async () => {
3114
3647
  if (!store.transaction) return;
@@ -3124,10 +3657,10 @@ function runStateStoreContract(name, makeStore) {
3124
3657
  }));
3125
3658
  return "ok";
3126
3659
  });
3127
- expect2(result).toBe("ok");
3128
- const cp = await store.getCheckpoint("r1", 7);
3129
- expect2(cp?.name).toBe("tx-step");
3130
- expect2(cp?.output).toEqual({
3660
+ expect3(result).toBe("ok");
3661
+ const cp2 = await store.getCheckpoint("r1", 7);
3662
+ expect3(cp2?.name).toBe("tx-step");
3663
+ expect3(cp2?.output).toEqual({
3131
3664
  paid: true
3132
3665
  });
3133
3666
  });
@@ -3154,11 +3687,11 @@ function runStateStoreContract(name, makeStore) {
3154
3687
  await engine.start("wf", {
3155
3688
  x: 1
3156
3689
  }, "run1");
3157
- expect2((await engine.waitForRun("run1")).status).toBe("failed");
3690
+ expect3((await engine.waitForRun("run1")).status).toBe("failed");
3158
3691
  const resumed = await engine.resume("run1");
3159
- expect2(resumed.status).toBe("completed");
3160
- expect2(resumed.output).toBe(15);
3161
- expect2(aRuns).toBe(1);
3692
+ expect3(resumed.status).toBe("completed");
3693
+ expect3(resumed.output).toBe(15);
3694
+ expect3(aRuns).toBe(1);
3162
3695
  });
3163
3696
  t("starts the version the caller pinned, and refuses one that is not registered", async () => {
3164
3697
  const engine = new WorkflowEngine3({
@@ -3179,19 +3712,19 @@ function runStateStoreContract(name, makeStore) {
3179
3712
  const pinned = await engine.waitForRun("pinned-run", {
3180
3713
  timeoutMs: 2e4
3181
3714
  });
3182
- expect2(pinned.output).toBe("v1-output");
3183
- expect2(ran).toEqual([
3715
+ expect3(pinned.output).toBe("v1-output");
3716
+ expect3(ran).toEqual([
3184
3717
  "v1"
3185
3718
  ]);
3186
- expect2((await store.getRun("pinned-run"))?.workflowVersion).toBe("1");
3719
+ expect3((await store.getRun("pinned-run"))?.workflowVersion).toBe("1");
3187
3720
  await engine.start("vwf", {}, "newest-run");
3188
- expect2((await engine.waitForRun("newest-run", {
3721
+ expect3((await engine.waitForRun("newest-run", {
3189
3722
  timeoutMs: 2e4
3190
3723
  })).output).toBe("v2-output");
3191
- await expect2(engine.start("vwf", {}, "ghost-run", {
3724
+ await expect3(engine.start("vwf", {}, "ghost-run", {
3192
3725
  version: "9"
3193
3726
  })).rejects.toThrow(/vwf@9 is not registered/);
3194
- expect2(await store.getRun("ghost-run")).toBeNull();
3727
+ expect3(await store.getRun("ghost-run")).toBeNull();
3195
3728
  });
3196
3729
  t("cancels a timed-out run\u2019s live child subtree, not just the run itself", async () => {
3197
3730
  const engine = new WorkflowEngine3({
@@ -3214,16 +3747,16 @@ function runStateStoreContract(name, makeStore) {
3214
3747
  "tc",
3215
3748
  "tgc"
3216
3749
  ]) {
3217
- expect2((await engine.waitForRun(id, {
3750
+ expect3((await engine.waitForRun(id, {
3218
3751
  timeoutMs: 2e4
3219
3752
  })).status).toBe("suspended");
3220
3753
  }
3221
3754
  await engine.sweepTimeouts(Date.now() + 37e5);
3222
3755
  const parent = await store.getRun("tp");
3223
- expect2(parent?.status).toBe("cancelled");
3224
- expect2(parent?.error?.code).toBe("execution_timeout");
3225
- expect2((await store.getRun("tc"))?.status).toBe("cancelled");
3226
- expect2((await store.getRun("tgc"))?.status).toBe("cancelled");
3756
+ expect3(parent?.status).toBe("cancelled");
3757
+ expect3(parent?.error?.code).toBe("execution_timeout");
3758
+ expect3((await store.getRun("tc"))?.status).toBe("cancelled");
3759
+ expect3((await store.getRun("tgc"))?.status).toBe("cancelled");
3227
3760
  });
3228
3761
  });
3229
3762
  }
@@ -3295,6 +3828,7 @@ export {
3295
3828
  DURABLE_CANONICAL_COLUMNS,
3296
3829
  MutableClock,
3297
3830
  StateStoreUnavailableError,
3831
+ aggregationFixture,
3298
3832
  assertDurableColumns,
3299
3833
  assertOutput,
3300
3834
  assertReplayable,
@@ -3307,6 +3841,7 @@ export {
3307
3841
  failTimes,
3308
3842
  preserveColumnExpectation,
3309
3843
  recordedSteps,
3844
+ registerCheckpointAggregationCases,
3310
3845
  runAdmissionBackendContract,
3311
3846
  runStateStoreContract
3312
3847
  };