@evolu/common 8.12.0 → 8.13.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.
Files changed (59) hide show
  1. package/dist/src/Callbacks.d.ts +12 -1
  2. package/dist/src/Callbacks.d.ts.map +1 -1
  3. package/dist/src/Callbacks.js +3 -0
  4. package/dist/src/Error.d.ts +10 -4
  5. package/dist/src/Error.d.ts.map +1 -1
  6. package/dist/src/Error.js +10 -4
  7. package/dist/src/Object.d.ts +65 -0
  8. package/dist/src/Object.d.ts.map +1 -1
  9. package/dist/src/Object.js +142 -0
  10. package/dist/src/Resource.d.ts +0 -5
  11. package/dist/src/Resource.d.ts.map +1 -1
  12. package/dist/src/Resource.js +6 -13
  13. package/dist/src/Sqlite.d.ts.map +1 -1
  14. package/dist/src/Sqlite.js +7 -0
  15. package/dist/src/Task.d.ts +10 -8
  16. package/dist/src/Task.d.ts.map +1 -1
  17. package/dist/src/Task.js +41 -5
  18. package/dist/src/Worker.d.ts +3 -3
  19. package/dist/src/local-first/Db.d.ts +8 -3
  20. package/dist/src/local-first/Db.d.ts.map +1 -1
  21. package/dist/src/local-first/Db.js +56 -19
  22. package/dist/src/local-first/Evolu.d.ts +81 -37
  23. package/dist/src/local-first/Evolu.d.ts.map +1 -1
  24. package/dist/src/local-first/Evolu.js +31 -6
  25. package/dist/src/local-first/Owner.d.ts +9 -0
  26. package/dist/src/local-first/Owner.d.ts.map +1 -1
  27. package/dist/src/local-first/Owner.js +9 -0
  28. package/dist/src/local-first/Protocol.d.ts +6 -4
  29. package/dist/src/local-first/Protocol.d.ts.map +1 -1
  30. package/dist/src/local-first/Protocol.js +1 -6
  31. package/dist/src/local-first/Schema.d.ts +7 -1
  32. package/dist/src/local-first/Schema.d.ts.map +1 -1
  33. package/dist/src/local-first/Shared.d.ts +523 -133
  34. package/dist/src/local-first/Shared.d.ts.map +1 -1
  35. package/dist/src/local-first/Shared.js +696 -256
  36. package/dist/src/local-first/Storage.d.ts +16 -12
  37. package/dist/src/local-first/Storage.d.ts.map +1 -1
  38. package/package.json +1 -1
  39. package/src/Callbacks.test.ts +20 -0
  40. package/src/Callbacks.ts +17 -1
  41. package/src/Error.ts +10 -4
  42. package/src/Object.test.ts +296 -0
  43. package/src/Object.ts +163 -0
  44. package/src/Resource.test.ts +20 -16
  45. package/src/Resource.ts +6 -20
  46. package/src/Sqlite.ts +7 -0
  47. package/src/Task.test.ts +233 -62
  48. package/src/Task.ts +47 -13
  49. package/src/Worker.ts +3 -3
  50. package/src/local-first/Db.ts +88 -18
  51. package/src/local-first/Evolu.test.ts +281 -1
  52. package/src/local-first/Evolu.ts +124 -46
  53. package/src/local-first/Owner.ts +9 -0
  54. package/src/local-first/Protocol.test.ts +42 -60
  55. package/src/local-first/Protocol.ts +7 -9
  56. package/src/local-first/Schema.ts +8 -2
  57. package/src/local-first/Shared.test.ts +2633 -646
  58. package/src/local-first/Shared.ts +1192 -364
  59. package/src/local-first/Storage.ts +18 -19
package/src/Task.test.ts CHANGED
@@ -1,4 +1,5 @@
1
1
  import { describe, it, mock } from "node:test";
2
+ import { runInNewContext } from "node:vm";
2
3
  import {
3
4
  assertEqual,
4
5
  assertErr,
@@ -673,6 +674,211 @@ describe("Run", () => {
673
674
  );
674
675
  });
675
676
 
677
+ describe("SuppressedError from cleanup", () => {
678
+ const cleanupAbortError = createAbortError({
679
+ type: "CleanupAbortReason",
680
+ });
681
+ const throwCleanupAbortError = (): void => {
682
+ AbortSignal.abort(cleanupAbortError).throwIfAborted();
683
+ };
684
+
685
+ it("aborts an AbortableFiber whose cleanup observes the abort", async () => {
686
+ await using run = testCreateRun();
687
+
688
+ const fiber = run.abortable(async (run) => {
689
+ await using stack = new AsyncDisposableStack();
690
+ stack.defer(async () => {
691
+ await run(waitForAbort);
692
+ });
693
+ await run(waitForAbort);
694
+ return ok();
695
+ });
696
+ fiber.abort(testAbortReason);
697
+
698
+ assertEqual(await fiber, err(testAbortError));
699
+ assertEqual(run.deps.reportDefect.getDefects(), []);
700
+ assertFalse(run.signal.aborted);
701
+ });
702
+
703
+ it("reports only the panic when cleanup observes its abort", async () => {
704
+ await using run = testCreateRun();
705
+
706
+ const fiber = run(async (run) => {
707
+ await using stack = new AsyncDisposableStack();
708
+ stack.defer(async () => {
709
+ await run(waitForAbort);
710
+ });
711
+ await run(waitForAbort);
712
+ return ok();
713
+ });
714
+ const panicAbortError = run.panic(new Error("boom"));
715
+
716
+ await assertRejects(fiber, panicAbortError);
717
+ assertEqual(run.deps.reportDefect.getDefects(), [panicAbortError]);
718
+ });
719
+
720
+ it("aborts with the last cleanup AbortError as try/finally does", async () => {
721
+ await using run = testCreateRun();
722
+
723
+ const usingFiber = run.abortable(async (run) => {
724
+ using _resource = { [Symbol.dispose]: throwCleanupAbortError };
725
+ await run(waitForAbort);
726
+ return ok();
727
+ });
728
+ const finallyFiber = run.abortable(async (run) => {
729
+ try {
730
+ await run(waitForAbort);
731
+ } finally {
732
+ throwCleanupAbortError();
733
+ }
734
+ return ok();
735
+ });
736
+ usingFiber.abort(testAbortReason);
737
+ finallyFiber.abort(testAbortReason);
738
+
739
+ assertEqual(await usingFiber, err(cleanupAbortError));
740
+ assertEqual(await finallyFiber, err(cleanupAbortError));
741
+ assertEqual(run.deps.reportDefect.getDefects(), []);
742
+ });
743
+
744
+ it("reports a created Run finalizer defect once during abort", async () => {
745
+ await using run = testCreateRun();
746
+ const defect = new Error("finalizer failed");
747
+
748
+ const fiber = run.abortable(async (run) => {
749
+ await using createdRun = run.create();
750
+ createdRun.defer(() => {
751
+ throw defect;
752
+ });
753
+ await run(waitForAbort);
754
+ return ok();
755
+ });
756
+ fiber.abort(testAbortReason);
757
+
758
+ const result = await fiber;
759
+ assertErr(result);
760
+ assertPanicAbortError(result.error, defect);
761
+ assertEqual(run.deps.reportDefect.getDefects(), [result.error]);
762
+ });
763
+
764
+ it("reports a cleanup defect during abort as the whole SuppressedError", async () => {
765
+ await using run = testCreateRun();
766
+ const defect = new Error("cleanup failed");
767
+
768
+ const fiber = run.abortable(async (run) => {
769
+ using _resource = {
770
+ [Symbol.dispose]: () => {
771
+ throw defect;
772
+ },
773
+ };
774
+ await run(waitForAbort);
775
+ return ok();
776
+ });
777
+ fiber.abort(testAbortReason);
778
+
779
+ const result = await fiber;
780
+ assertErr(result);
781
+ assertType(AbortError, result.error);
782
+ const suppressedError = result.error.reason.defect;
783
+ assertInstanceOf(suppressedError, SuppressedError);
784
+ assertSame(suppressedError.error, defect);
785
+ assertEqual(suppressedError.suppressed, testAbortError);
786
+ assertEqual(run.deps.reportDefect.getDefects(), [result.error]);
787
+ });
788
+
789
+ it("reports a Task defect whose cleanup then aborts as the whole SuppressedError", async () => {
790
+ await using run = testCreateRun();
791
+ const defect = new Error("task failed");
792
+
793
+ const fiber = run.abortable(() => {
794
+ using _resource = { [Symbol.dispose]: throwCleanupAbortError };
795
+ throw defect;
796
+ });
797
+
798
+ const result = await fiber;
799
+ assertErr(result);
800
+ assertType(AbortError, result.error);
801
+ const suppressedError = result.error.reason.defect;
802
+ assertInstanceOf(suppressedError, SuppressedError);
803
+ assertEqual(suppressedError.error, cleanupAbortError);
804
+ assertSame(suppressedError.suppressed, defect);
805
+ assertEqual(run.deps.reportDefect.getDefects(), [result.error]);
806
+ });
807
+
808
+ it("aborts when thousands of cleanups observe the abort", async () => {
809
+ await using run = testCreateRun();
810
+
811
+ const fiber = run.abortable(async (run) => {
812
+ using stack = new DisposableStack();
813
+ // Each failing cleanup nests one more SuppressedError.
814
+ for (let i = 0; i < 20_000; i++) stack.defer(throwCleanupAbortError);
815
+ await run(waitForAbort);
816
+ return ok();
817
+ });
818
+ fiber.abort(testAbortReason);
819
+
820
+ assertEqual(await fiber, err(cleanupAbortError));
821
+ assertEqual(run.deps.reportDefect.getDefects(), []);
822
+ assertFalse(run.signal.aborted);
823
+ });
824
+
825
+ it("recognizes a downleveled SuppressedError by its name", async () => {
826
+ await using run = testCreateRun();
827
+ // TypeScript's downleveled `using` throws this without a native
828
+ // SuppressedError.
829
+ const suppressedError = Object.assign(
830
+ new Error("An error was suppressed during disposal."),
831
+ {
832
+ name: "SuppressedError",
833
+ error: testAbortError,
834
+ suppressed: testAbortError,
835
+ },
836
+ );
837
+
838
+ const fiber = run.abortable(() => {
839
+ throw suppressedError;
840
+ });
841
+
842
+ assertEqual(await fiber, err(testAbortError));
843
+ assertEqual(run.deps.reportDefect.getDefects(), []);
844
+ });
845
+
846
+ it("recognizes a SuppressedError from another realm", async () => {
847
+ await using run = testCreateRun();
848
+ const suppressedError = runInNewContext(
849
+ "new SuppressedError(error, suppressed)",
850
+ { error: testAbortError, suppressed: testAbortError },
851
+ ) as SuppressedError;
852
+
853
+ const fiber = run.abortable(() => {
854
+ throw suppressedError;
855
+ });
856
+
857
+ assertEqual(await fiber, err(testAbortError));
858
+ assertEqual(run.deps.reportDefect.getDefects(), []);
859
+ assertFalse(run.signal.aborted);
860
+ });
861
+
862
+ it("reports a defect whose inspection throws", async () => {
863
+ await using run = testCreateRun();
864
+ const defect = new Error("task failed");
865
+ Object.defineProperty(defect, "name", {
866
+ get: () => {
867
+ throw new Error("name getter failed");
868
+ },
869
+ });
870
+
871
+ const fiber = run.abortable(() => {
872
+ throw defect;
873
+ });
874
+
875
+ const result = await fiber;
876
+ assertErr(result);
877
+ assertPanicAbortError(result.error, defect);
878
+ assertEqual(run.deps.reportDefect.getDefects(), [result.error]);
879
+ });
880
+ });
881
+
676
882
  describe("lifecycle", () => {
677
883
  it("aborts Task Run after Task settles", async () => {
678
884
  await using run = createRun();
@@ -2970,6 +3176,24 @@ describe("DisposableRun", () => {
2970
3176
  await run[Symbol.asyncDispose]();
2971
3177
  });
2972
3178
 
3179
+ it("reports a finalizer defect once when another finalizer awaits its Run", async () => {
3180
+ const run = testCreateRun();
3181
+ const createdRun = run.create();
3182
+ const defect = new Error("finalizer failed");
3183
+
3184
+ createdRun.defer(() => {
3185
+ throw defect;
3186
+ });
3187
+ run.defer(() => createdRun[Symbol.asyncDispose]());
3188
+
3189
+ await assertRejects(run[Symbol.asyncDispose](), (disposalError) => {
3190
+ assertPanicAbortError(disposalError, defect);
3191
+ assertEqual(run.deps.reportDefect.getDefectsSnapshot(), [
3192
+ disposalError,
3193
+ ]);
3194
+ });
3195
+ });
3196
+
2973
3197
  it("reports multiple finalizer defects as SuppressedError", async () => {
2974
3198
  const run = testCreateRun();
2975
3199
  const firstDefect = new Error("first finalizer failed");
@@ -9054,7 +9278,6 @@ describe("Semaphore", () => {
9054
9278
  taken: 1,
9055
9279
  waiters: [],
9056
9280
  available: 0,
9057
- isIdle: false,
9058
9281
  });
9059
9282
 
9060
9283
  await completeTask.promise;
@@ -9071,7 +9294,6 @@ describe("Semaphore", () => {
9071
9294
  taken: 0,
9072
9295
  waiters: [],
9073
9296
  available: 1,
9074
- isIdle: true,
9075
9297
  });
9076
9298
  });
9077
9299
  });
@@ -9104,7 +9326,6 @@ describe("Semaphore", () => {
9104
9326
  taken: 2,
9105
9327
  waiters: [],
9106
9328
  available: 1,
9107
- isIdle: false,
9108
9329
  });
9109
9330
  return ok("value");
9110
9331
  }),
@@ -9146,7 +9367,6 @@ describe("Semaphore", () => {
9146
9367
  taken: 2,
9147
9368
  waiters: [{ permits: 1 }],
9148
9369
  available: 0,
9149
- isIdle: false,
9150
9370
  });
9151
9371
  assertEqual(events, ["first acquired"]);
9152
9372
 
@@ -9165,7 +9385,6 @@ describe("Semaphore", () => {
9165
9385
  taken: 0,
9166
9386
  waiters: [],
9167
9387
  available: 2,
9168
- isIdle: true,
9169
9388
  });
9170
9389
  });
9171
9390
 
@@ -9190,7 +9409,6 @@ describe("Semaphore", () => {
9190
9409
  taken: 1,
9191
9410
  waiters: [{ permits: 1 }],
9192
9411
  available: 0,
9193
- isIdle: false,
9194
9412
  });
9195
9413
 
9196
9414
  fiber.abort(testAbortReason);
@@ -9202,7 +9420,6 @@ describe("Semaphore", () => {
9202
9420
  taken: 1,
9203
9421
  waiters: [],
9204
9422
  available: 0,
9205
- isIdle: false,
9206
9423
  });
9207
9424
  assertFalse(taskStarted);
9208
9425
 
@@ -9225,7 +9442,6 @@ describe("Semaphore", () => {
9225
9442
  taken: 0,
9226
9443
  waiters: [],
9227
9444
  available: 2,
9228
- isIdle: true,
9229
9445
  });
9230
9446
  });
9231
9447
 
@@ -9242,7 +9458,6 @@ describe("Semaphore", () => {
9242
9458
  taken: 2,
9243
9459
  waiters: [],
9244
9460
  available: 0,
9245
- isIdle: false,
9246
9461
  });
9247
9462
  return err("error");
9248
9463
  }),
@@ -9255,7 +9470,6 @@ describe("Semaphore", () => {
9255
9470
  taken: 0,
9256
9471
  waiters: [],
9257
9472
  available: 2,
9258
- isIdle: true,
9259
9473
  });
9260
9474
  });
9261
9475
 
@@ -9273,7 +9487,6 @@ describe("Semaphore", () => {
9273
9487
  taken: 2,
9274
9488
  waiters: [],
9275
9489
  available: 0,
9276
- isIdle: false,
9277
9490
  });
9278
9491
  taskStarted.resolve();
9279
9492
  await run.ok(
@@ -9295,7 +9508,6 @@ describe("Semaphore", () => {
9295
9508
  taken: 0,
9296
9509
  waiters: [],
9297
9510
  available: 2,
9298
- isIdle: true,
9299
9511
  });
9300
9512
  });
9301
9513
  });
@@ -9328,7 +9540,6 @@ describe("Semaphore", () => {
9328
9540
  taken: 2,
9329
9541
  waiters: [],
9330
9542
  available: 0,
9331
- isIdle: false,
9332
9543
  });
9333
9544
  return ok("value");
9334
9545
  }),
@@ -9341,7 +9552,6 @@ describe("Semaphore", () => {
9341
9552
  taken: 0,
9342
9553
  waiters: [],
9343
9554
  available: 2,
9344
- isIdle: true,
9345
9555
  });
9346
9556
  });
9347
9557
 
@@ -9366,7 +9576,6 @@ describe("Semaphore", () => {
9366
9576
  taken: 0,
9367
9577
  waiters: [],
9368
9578
  available: 1,
9369
- isIdle: true,
9370
9579
  });
9371
9580
  });
9372
9581
 
@@ -9386,7 +9595,6 @@ describe("Semaphore", () => {
9386
9595
  taken: 2,
9387
9596
  waiters: [{ permits: 2 }],
9388
9597
  available: 0,
9389
- isIdle: false,
9390
9598
  });
9391
9599
 
9392
9600
  const result = await run(
@@ -9419,7 +9627,6 @@ describe("Semaphore", () => {
9419
9627
  taken: 2,
9420
9628
  waiters: [{ permits: 2 }],
9421
9629
  available: 1,
9422
- isIdle: false,
9423
9630
  });
9424
9631
 
9425
9632
  const result = await run(
@@ -9449,7 +9656,6 @@ describe("Semaphore", () => {
9449
9656
  taken: 0,
9450
9657
  waiters: [],
9451
9658
  available: 1,
9452
- isIdle: true,
9453
9659
  });
9454
9660
  });
9455
9661
 
@@ -9467,7 +9673,6 @@ describe("Semaphore", () => {
9467
9673
  taken: 1,
9468
9674
  waiters: [],
9469
9675
  available: 0,
9470
- isIdle: false,
9471
9676
  });
9472
9677
  taskStarted.resolve();
9473
9678
  await run.ok(
@@ -9489,7 +9694,6 @@ describe("Semaphore", () => {
9489
9694
  taken: 0,
9490
9695
  waiters: [],
9491
9696
  available: 1,
9492
- isIdle: true,
9493
9697
  });
9494
9698
  });
9495
9699
  });
@@ -9535,7 +9739,6 @@ describe("Semaphore", () => {
9535
9739
  taken: 1,
9536
9740
  waiters: [{ permits: 1 }],
9537
9741
  available: 0,
9538
- isIdle: false,
9539
9742
  });
9540
9743
  assertEqual(events, ["waiting"]);
9541
9744
 
@@ -9566,7 +9769,6 @@ describe("Semaphore", () => {
9566
9769
  taken: 2,
9567
9770
  waiters: [{ permits: 2 }],
9568
9771
  available: 0,
9569
- isIdle: false,
9570
9772
  });
9571
9773
 
9572
9774
  const smallerFiber = run(async (run) => {
@@ -9582,7 +9784,6 @@ describe("Semaphore", () => {
9582
9784
  taken: 2,
9583
9785
  waiters: [{ permits: 2 }, { permits: 1 }],
9584
9786
  available: 0,
9585
- isIdle: false,
9586
9787
  });
9587
9788
  assertEqual(events, ["larger requesting", "smaller requesting"]);
9588
9789
 
@@ -9596,7 +9797,6 @@ describe("Semaphore", () => {
9596
9797
  taken: 2,
9597
9798
  waiters: [{ permits: 2 }, { permits: 1 }],
9598
9799
  available: 0,
9599
- isIdle: false,
9600
9800
  });
9601
9801
 
9602
9802
  firstPermit.release();
@@ -9632,7 +9832,6 @@ describe("Semaphore", () => {
9632
9832
  taken: 2,
9633
9833
  waiters: [{ permits: 2 }],
9634
9834
  available: 1,
9635
- isIdle: false,
9636
9835
  });
9637
9836
 
9638
9837
  const smallerFiber = run(async (run) => {
@@ -9689,7 +9888,6 @@ describe("Semaphore", () => {
9689
9888
  taken: 3,
9690
9889
  waiters: [{ permits: 2 }, { permits: 1 }],
9691
9890
  available: 0,
9692
- isIdle: false,
9693
9891
  });
9694
9892
 
9695
9893
  secondPermit.release();
@@ -9706,7 +9904,6 @@ describe("Semaphore", () => {
9706
9904
  taken: 2,
9707
9905
  waiters: [{ permits: 2 }],
9708
9906
  available: 1,
9709
- isIdle: false,
9710
9907
  });
9711
9908
 
9712
9909
  firstPermit.release();
@@ -9733,7 +9930,6 @@ describe("Semaphore", () => {
9733
9930
  taken: 2,
9734
9931
  waiters: [],
9735
9932
  available: 0,
9736
- isIdle: false,
9737
9933
  });
9738
9934
  }
9739
9935
 
@@ -9743,7 +9939,6 @@ describe("Semaphore", () => {
9743
9939
  taken: 0,
9744
9940
  waiters: [],
9745
9941
  available: 2,
9746
- isIdle: true,
9747
9942
  });
9748
9943
  });
9749
9944
 
@@ -9761,7 +9956,6 @@ describe("Semaphore", () => {
9761
9956
  taken: 0,
9762
9957
  waiters: [],
9763
9958
  available: 1,
9764
- isIdle: true,
9765
9959
  });
9766
9960
  });
9767
9961
 
@@ -9780,7 +9974,6 @@ describe("Semaphore", () => {
9780
9974
  taken: 1,
9781
9975
  waiters: [{ permits: 1 }],
9782
9976
  available: 0,
9783
- isIdle: false,
9784
9977
  });
9785
9978
 
9786
9979
  waiterFiber.abort(testAbortReason);
@@ -9792,7 +9985,6 @@ describe("Semaphore", () => {
9792
9985
  taken: 1,
9793
9986
  waiters: [],
9794
9987
  available: 0,
9795
- isIdle: false,
9796
9988
  });
9797
9989
  });
9798
9990
 
@@ -9815,7 +10007,6 @@ describe("Semaphore", () => {
9815
10007
  taken: 2,
9816
10008
  waiters: [{ permits: 2 }, { permits: 1 }],
9817
10009
  available: 0,
9818
- isIdle: false,
9819
10010
  });
9820
10011
 
9821
10012
  largerFiber.abort(testAbortReason);
@@ -9828,7 +10019,6 @@ describe("Semaphore", () => {
9828
10019
  taken: 2,
9829
10020
  waiters: [],
9830
10021
  available: 1,
9831
- isIdle: false,
9832
10022
  });
9833
10023
 
9834
10024
  firstPermit.release();
@@ -9853,7 +10043,6 @@ describe("Semaphore", () => {
9853
10043
  taken: 1,
9854
10044
  waiters: [{ permits: 1 }, { permits: 1 }],
9855
10045
  available: 0,
9856
- isIdle: false,
9857
10046
  });
9858
10047
 
9859
10048
  firstWaiterFiber.abort(testAbortReason);
@@ -9865,7 +10054,6 @@ describe("Semaphore", () => {
9865
10054
  taken: 1,
9866
10055
  waiters: [{ permits: 1 }],
9867
10056
  available: 0,
9868
- isIdle: false,
9869
10057
  });
9870
10058
 
9871
10059
  firstPermit.release();
@@ -9877,7 +10065,6 @@ describe("Semaphore", () => {
9877
10065
  taken: 0,
9878
10066
  waiters: [],
9879
10067
  available: 1,
9880
- isIdle: true,
9881
10068
  });
9882
10069
  });
9883
10070
  });
@@ -9909,7 +10096,6 @@ describe("Semaphore", () => {
9909
10096
  taken: 0,
9910
10097
  waiters: [{ permits: 2 }],
9911
10098
  available: 0,
9912
- isIdle: false,
9913
10099
  });
9914
10100
  assertEqual(events, ["waiting"]);
9915
10101
 
@@ -9923,7 +10109,6 @@ describe("Semaphore", () => {
9923
10109
  taken: 0,
9924
10110
  waiters: [],
9925
10111
  available: 2,
9926
- isIdle: true,
9927
10112
  });
9928
10113
  });
9929
10114
 
@@ -9942,7 +10127,6 @@ describe("Semaphore", () => {
9942
10127
  taken: 2,
9943
10128
  waiters: [],
9944
10129
  available: 0,
9945
- isIdle: false,
9946
10130
  });
9947
10131
 
9948
10132
  permit.release();
@@ -9953,7 +10137,6 @@ describe("Semaphore", () => {
9953
10137
  taken: 0,
9954
10138
  waiters: [],
9955
10139
  available: 1,
9956
- isIdle: true,
9957
10140
  });
9958
10141
  });
9959
10142
  });
@@ -9970,7 +10153,6 @@ describe("Semaphore", () => {
9970
10153
  taken: 0,
9971
10154
  waiters: [],
9972
10155
  available: 2,
9973
- isIdle: true,
9974
10156
  });
9975
10157
 
9976
10158
  const firstPermit = await run.ok(semaphore.take(1));
@@ -9985,7 +10167,6 @@ describe("Semaphore", () => {
9985
10167
  taken: 1,
9986
10168
  waiters: [{ permits: 2 }],
9987
10169
  available: 0,
9988
- isIdle: false,
9989
10170
  });
9990
10171
 
9991
10172
  firstPermit.release();
@@ -9997,7 +10178,6 @@ describe("Semaphore", () => {
9997
10178
  taken: 0,
9998
10179
  waiters: [],
9999
10180
  available: 2,
10000
- isIdle: true,
10001
10181
  });
10002
10182
  });
10003
10183
  });
@@ -10075,7 +10255,6 @@ describe("Mutex", () => {
10075
10255
  taken: 1,
10076
10256
  waiters: [{ permits: 1 }],
10077
10257
  available: 0,
10078
- isIdle: false,
10079
10258
  });
10080
10259
  assertEqual(events, ["first acquired"]);
10081
10260
 
@@ -10094,7 +10273,6 @@ describe("Mutex", () => {
10094
10273
  taken: 0,
10095
10274
  waiters: [],
10096
10275
  available: 1,
10097
- isIdle: true,
10098
10276
  });
10099
10277
  });
10100
10278
 
@@ -10111,7 +10289,6 @@ describe("Mutex", () => {
10111
10289
  taken: 1,
10112
10290
  waiters: [],
10113
10291
  available: 0,
10114
- isIdle: false,
10115
10292
  });
10116
10293
  return err("error");
10117
10294
  }),
@@ -10124,7 +10301,6 @@ describe("Mutex", () => {
10124
10301
  taken: 0,
10125
10302
  waiters: [],
10126
10303
  available: 1,
10127
- isIdle: true,
10128
10304
  });
10129
10305
  assertEqual(await run(mutex.withLock(() => ok("next"))), ok("next"));
10130
10306
  });
@@ -10143,7 +10319,6 @@ describe("Mutex", () => {
10143
10319
  taken: 1,
10144
10320
  waiters: [],
10145
10321
  available: 0,
10146
- isIdle: false,
10147
10322
  });
10148
10323
  taskStarted.resolve();
10149
10324
  await run.ok(
@@ -10165,7 +10340,6 @@ describe("Mutex", () => {
10165
10340
  taken: 0,
10166
10341
  waiters: [],
10167
10342
  available: 1,
10168
- isIdle: true,
10169
10343
  });
10170
10344
  assertEqual(await run(mutex.withLock(() => ok("next"))), ok("next"));
10171
10345
  });
@@ -10183,7 +10357,6 @@ describe("Mutex", () => {
10183
10357
  taken: 0,
10184
10358
  waiters: [],
10185
10359
  available: 1,
10186
- isIdle: true,
10187
10360
  });
10188
10361
 
10189
10362
  const completeFirstTask = Promise.withResolvers<void>();
@@ -10207,7 +10380,6 @@ describe("Mutex", () => {
10207
10380
  taken: 1,
10208
10381
  waiters: [{ permits: 1 }],
10209
10382
  available: 0,
10210
- isIdle: false,
10211
10383
  });
10212
10384
 
10213
10385
  completeFirstTask.resolve();
@@ -10220,7 +10392,6 @@ describe("Mutex", () => {
10220
10392
  taken: 0,
10221
10393
  waiters: [],
10222
10394
  available: 1,
10223
- isIdle: true,
10224
10395
  });
10225
10396
  });
10226
10397
  });
@@ -10308,7 +10479,6 @@ describe("SemaphoreByKey", () => {
10308
10479
  taken: 1,
10309
10480
  waiters: [{ permits: 1 }],
10310
10481
  available: 0,
10311
- isIdle: false,
10312
10482
  });
10313
10483
  assertEqual(events, ["first acquired"]);
10314
10484
 
@@ -10479,7 +10649,6 @@ describe("SemaphoreByKey", () => {
10479
10649
  taken: 1,
10480
10650
  waiters: [],
10481
10651
  available: 0,
10482
- isIdle: false,
10483
10652
  });
10484
10653
 
10485
10654
  completeTask.resolve();
@@ -10572,7 +10741,6 @@ describe("SemaphoreByKey", () => {
10572
10741
  taken: 1,
10573
10742
  waiters: [{ permits: 1 }],
10574
10743
  available: 0,
10575
- isIdle: false,
10576
10744
  });
10577
10745
 
10578
10746
  secondFiber.abort(testAbortReason);
@@ -10584,7 +10752,6 @@ describe("SemaphoreByKey", () => {
10584
10752
  taken: 1,
10585
10753
  waiters: [],
10586
10754
  available: 0,
10587
- isIdle: false,
10588
10755
  });
10589
10756
 
10590
10757
  completeFirstTask.resolve();
@@ -10672,7 +10839,6 @@ describe("MutexByKey", () => {
10672
10839
  taken: 1,
10673
10840
  waiters: [{ permits: 1 }],
10674
10841
  available: 0,
10675
- isIdle: false,
10676
10842
  });
10677
10843
  assertEqual(events, ["first acquired"]);
10678
10844
 
@@ -10782,7 +10948,6 @@ describe("MutexByKey", () => {
10782
10948
  taken: 1,
10783
10949
  waiters: [],
10784
10950
  available: 0,
10785
- isIdle: false,
10786
10951
  });
10787
10952
 
10788
10953
  completeTask.resolve();
@@ -10927,8 +11092,15 @@ describe("MutexRef", () => {
10927
11092
  const gate = createGate();
10928
11093
  const ref = createMutexRef(0);
10929
11094
  const started = Promise.withResolvers<void>();
11095
+ const idleSnapshot = {
11096
+ policy: "fifo",
11097
+ permits: 1,
11098
+ taken: 0,
11099
+ waiters: [],
11100
+ available: 1,
11101
+ };
10930
11102
 
10931
- assertTrue(ref.snapshot().isIdle);
11103
+ assertEqual(ref.snapshot(), idleSnapshot);
10932
11104
 
10933
11105
  const fiber = run(
10934
11106
  ref.update((current) => async (run) => {
@@ -10946,13 +11118,12 @@ describe("MutexRef", () => {
10946
11118
  taken: 1,
10947
11119
  waiters: [],
10948
11120
  available: 0,
10949
- isIdle: false,
10950
11121
  });
10951
11122
 
10952
11123
  gate.open();
10953
11124
 
10954
11125
  assertEqual(await fiber, ok());
10955
- assertTrue(ref.snapshot().isIdle);
11126
+ assertEqual(ref.snapshot(), idleSnapshot);
10956
11127
  });
10957
11128
 
10958
11129
  it("types: operations infer error and deps from the updater", () => {