cojson 0.18.33 → 0.18.35

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 (93) hide show
  1. package/.turbo/turbo-build.log +1 -1
  2. package/CHANGELOG.md +17 -0
  3. package/dist/SyncStateManager.d.ts.map +1 -1
  4. package/dist/SyncStateManager.js +2 -2
  5. package/dist/SyncStateManager.js.map +1 -1
  6. package/dist/coValueContentMessage.d.ts +5 -2
  7. package/dist/coValueContentMessage.d.ts.map +1 -1
  8. package/dist/coValueContentMessage.js +15 -0
  9. package/dist/coValueContentMessage.js.map +1 -1
  10. package/dist/coValueCore/SessionMap.d.ts +4 -3
  11. package/dist/coValueCore/SessionMap.d.ts.map +1 -1
  12. package/dist/coValueCore/SessionMap.js +21 -30
  13. package/dist/coValueCore/SessionMap.js.map +1 -1
  14. package/dist/coValueCore/coValueCore.d.ts +14 -6
  15. package/dist/coValueCore/coValueCore.d.ts.map +1 -1
  16. package/dist/coValueCore/coValueCore.js +32 -52
  17. package/dist/coValueCore/coValueCore.js.map +1 -1
  18. package/dist/coValueCore/verifiedState.d.ts +6 -4
  19. package/dist/coValueCore/verifiedState.d.ts.map +1 -1
  20. package/dist/coValueCore/verifiedState.js +21 -7
  21. package/dist/coValueCore/verifiedState.js.map +1 -1
  22. package/dist/coValues/group.d.ts.map +1 -1
  23. package/dist/coValues/group.js +20 -15
  24. package/dist/coValues/group.js.map +1 -1
  25. package/dist/knownState.d.ts +9 -1
  26. package/dist/knownState.d.ts.map +1 -1
  27. package/dist/knownState.js +29 -3
  28. package/dist/knownState.js.map +1 -1
  29. package/dist/localNode.d.ts +7 -2
  30. package/dist/localNode.d.ts.map +1 -1
  31. package/dist/localNode.js +10 -15
  32. package/dist/localNode.js.map +1 -1
  33. package/dist/queue/LocalTransactionsSyncQueue.d.ts +10 -9
  34. package/dist/queue/LocalTransactionsSyncQueue.d.ts.map +1 -1
  35. package/dist/queue/LocalTransactionsSyncQueue.js +53 -47
  36. package/dist/queue/LocalTransactionsSyncQueue.js.map +1 -1
  37. package/dist/storage/knownState.js +2 -2
  38. package/dist/storage/knownState.js.map +1 -1
  39. package/dist/sync.d.ts +1 -2
  40. package/dist/sync.d.ts.map +1 -1
  41. package/dist/sync.js +15 -19
  42. package/dist/sync.js.map +1 -1
  43. package/dist/tests/coPlainText.test.js +13 -14
  44. package/dist/tests/coPlainText.test.js.map +1 -1
  45. package/dist/tests/coValueContentMessage.test.js +130 -1
  46. package/dist/tests/coValueContentMessage.test.js.map +1 -1
  47. package/dist/tests/coValueCore.isCompletelyDownloaded.test.js +3 -2
  48. package/dist/tests/coValueCore.isCompletelyDownloaded.test.js.map +1 -1
  49. package/dist/tests/coValueCore.isStreaming.test.js +54 -3
  50. package/dist/tests/coValueCore.isStreaming.test.js.map +1 -1
  51. package/dist/tests/coValueCore.test.js +3 -6
  52. package/dist/tests/coValueCore.test.js.map +1 -1
  53. package/dist/tests/group.childKeyRotation.test.js +9 -9
  54. package/dist/tests/group.childKeyRotation.test.js.map +1 -1
  55. package/dist/tests/knownState.test.js +82 -10
  56. package/dist/tests/knownState.test.js.map +1 -1
  57. package/dist/tests/sync.load.test.js +29 -29
  58. package/dist/tests/sync.mesh.test.js +38 -31
  59. package/dist/tests/sync.mesh.test.js.map +1 -1
  60. package/dist/tests/sync.storage.test.js +24 -23
  61. package/dist/tests/sync.storage.test.js.map +1 -1
  62. package/dist/tests/sync.storageAsync.test.js +24 -23
  63. package/dist/tests/sync.storageAsync.test.js.map +1 -1
  64. package/dist/tests/sync.upload.test.js +58 -58
  65. package/dist/tests/testUtils.d.ts +11 -9
  66. package/dist/tests/testUtils.d.ts.map +1 -1
  67. package/dist/tests/testUtils.js +26 -16
  68. package/dist/tests/testUtils.js.map +1 -1
  69. package/package.json +3 -4
  70. package/src/SyncStateManager.ts +8 -2
  71. package/src/coValueContentMessage.ts +29 -2
  72. package/src/coValueCore/SessionMap.ts +41 -31
  73. package/src/coValueCore/coValueCore.ts +41 -74
  74. package/src/coValueCore/verifiedState.ts +36 -11
  75. package/src/coValues/group.ts +40 -27
  76. package/src/knownState.ts +39 -4
  77. package/src/localNode.ts +16 -21
  78. package/src/queue/LocalTransactionsSyncQueue.ts +77 -93
  79. package/src/storage/knownState.ts +2 -2
  80. package/src/sync.ts +24 -26
  81. package/src/tests/coPlainText.test.ts +13 -14
  82. package/src/tests/coValueContentMessage.test.ts +197 -2
  83. package/src/tests/coValueCore.isCompletelyDownloaded.test.ts +3 -2
  84. package/src/tests/coValueCore.isStreaming.test.ts +84 -2
  85. package/src/tests/coValueCore.test.ts +7 -10
  86. package/src/tests/group.childKeyRotation.test.ts +9 -9
  87. package/src/tests/knownState.test.ts +106 -9
  88. package/src/tests/sync.load.test.ts +29 -29
  89. package/src/tests/sync.mesh.test.ts +38 -31
  90. package/src/tests/sync.storage.test.ts +24 -23
  91. package/src/tests/sync.storageAsync.test.ts +24 -23
  92. package/src/tests/sync.upload.test.ts +58 -58
  93. package/src/tests/testUtils.ts +30 -18
@@ -3,9 +3,12 @@ import {
3
3
  SyncMessagesLog,
4
4
  TEST_NODE_CONFIG,
5
5
  loadCoValueOrFail,
6
+ setupTestAccount,
6
7
  setupTestNode,
7
8
  waitFor,
8
9
  } from "./testUtils";
10
+ import type { RawCoMap } from "../exports";
11
+ import type { CoID } from "../coValue";
9
12
 
10
13
  let jazzCloud: ReturnType<typeof setupTestNode>;
11
14
 
@@ -82,7 +85,7 @@ describe("isStreaming", () => {
82
85
  expect(mapInNewSession.core.isStreaming()).toBe(false);
83
86
  });
84
87
 
85
- test("loading a large content update should be streaming until all chunks are sent", async () => {
88
+ test("loading a large content update should be streaming until all chunks are sent", async () => {
86
89
  const client = setupTestNode({
87
90
  connected: true,
88
91
  });
@@ -222,7 +225,8 @@ describe("isStreaming", () => {
222
225
  await map.core.waitForSync();
223
226
  const newSession = client.spawnNewSession();
224
227
 
225
- await loadCoValueOrFail(newSession.node, map.id);
228
+ const mapInNewSession1 = await loadCoValueOrFail(newSession.node, map.id);
229
+ await mapInNewSession1.core.waitForFullStreaming();
226
230
 
227
231
  const content = map.core.verified.newContentSince(undefined);
228
232
  assert(content);
@@ -268,4 +272,82 @@ describe("isStreaming", () => {
268
272
 
269
273
  expect(mapInNewSession.core.isStreaming()).toBe(false);
270
274
  });
275
+
276
+ test("mixed updates should not leave isStreaming to true (3 sessions)", async () => {
277
+ const aliceLaptop = await setupTestAccount({
278
+ connected: true,
279
+ });
280
+
281
+ const group = aliceLaptop.node.createGroup();
282
+ const map = group.createMap();
283
+
284
+ map.set("count", 0, "trusting");
285
+ map.set("count", 1, "trusting");
286
+
287
+ await map.core.waitForSync();
288
+
289
+ const alicePhone = await aliceLaptop.spawnNewSession();
290
+
291
+ const mapOnPhone = await loadCoValueOrFail(alicePhone.node, map.id);
292
+
293
+ mapOnPhone.set("count", 2, "trusting");
294
+ mapOnPhone.set("count", 3, "trusting");
295
+ mapOnPhone.set("count", 4, "trusting");
296
+
297
+ await mapOnPhone.core.waitForSync();
298
+
299
+ const aliceTablet = await alicePhone.spawnNewSession();
300
+ const mapOnTablet = await loadCoValueOrFail(aliceTablet.node, map.id);
301
+
302
+ mapOnTablet.set("count", 5, "trusting");
303
+ mapOnTablet.set("count", 6, "trusting");
304
+ mapOnTablet.set("count", 7, "trusting");
305
+
306
+ await mapOnTablet.core.waitForSync();
307
+
308
+ map.set("count", 8, "trusting");
309
+ map.set("count", 9, "trusting");
310
+ map.set("count", 10, "trusting");
311
+
312
+ mapOnPhone.set("count", 11, "trusting");
313
+ mapOnTablet.set("count", 12, "trusting");
314
+
315
+ await map.core.waitForSync();
316
+ await mapOnPhone.core.waitForSync();
317
+ await mapOnTablet.core.waitForSync();
318
+
319
+ expect(map.core.isStreaming()).toBe(false);
320
+ expect(mapOnPhone.core.isStreaming()).toBe(false);
321
+ expect(mapOnTablet.core.isStreaming()).toBe(false);
322
+
323
+ const mapBranch = map.core.createBranch("test-branch");
324
+
325
+ const aliceTv = await aliceTablet.spawnNewSession();
326
+
327
+ const mapBranchOnTv = await loadCoValueOrFail(
328
+ aliceTv.node,
329
+ mapBranch.id as unknown as CoID<RawCoMap>,
330
+ );
331
+
332
+ mapBranchOnTv.set("count", 13, "trusting");
333
+ mapBranchOnTv.set("count", 14, "trusting");
334
+ mapBranchOnTv.set("count", 15, "trusting");
335
+
336
+ await mapBranchOnTv.core.waitForSync();
337
+
338
+ group.addMember("everyone", "reader");
339
+
340
+ const bob = await setupTestAccount({
341
+ connected: true,
342
+ });
343
+
344
+ const mapBranchOnBob = await loadCoValueOrFail(bob.node, mapBranchOnTv.id);
345
+
346
+ expect(mapBranchOnBob.core.isStreaming()).toBe(false);
347
+ expect(map.core.isStreaming()).toBe(false);
348
+ expect(mapOnPhone.core.isStreaming()).toBe(false);
349
+ expect(mapOnTablet.core.isStreaming()).toBe(false);
350
+
351
+ expect(mapBranchOnBob.get("count")).toBe(15);
352
+ });
271
353
  });
@@ -78,14 +78,13 @@ test("transactions with wrong signature are rejected", () => {
78
78
 
79
79
  const newEntry = node.getCoValue(coValue.id);
80
80
 
81
- // eslint-disable-next-line neverthrow/must-use-result
82
- const result = newEntry.tryAddTransactions(
81
+ const error = newEntry.tryAddTransactions(
83
82
  node.currentSessionID,
84
83
  [transaction],
85
84
  signature,
86
85
  );
87
86
 
88
- expect(result.isErr()).toBe(true);
87
+ expect(Boolean(error)).toBe(true);
89
88
  expect(newEntry.getValidSortedTransactions().length).toBe(0);
90
89
  });
91
90
 
@@ -448,13 +447,11 @@ test("getValidTransactions should skip private transactions with invalid JSON",
448
447
  map.set("hello", "world");
449
448
 
450
449
  // This should fail silently, because the encryptedChanges will be outputted as gibberish
451
- map.core
452
- .tryAddTransactions(
453
- fixtures.session,
454
- [fixtures.transaction],
455
- fixtures.signature,
456
- )
457
- ._unsafeUnwrap();
450
+ map.core.tryAddTransactions(
451
+ fixtures.session,
452
+ [fixtures.transaction],
453
+ fixtures.signature,
454
+ );
458
455
 
459
456
  // Get valid transactions - should only include the valid one
460
457
  const validTransactions = map.core.getValidTransactions();
@@ -89,7 +89,7 @@ describe("Group.childKeyRotation", () => {
89
89
  const newBobSession = await bob.spawnNewSession();
90
90
 
91
91
  const childGroupOnNewBobNode = await loadCoValueOrFail(
92
- newBobSession,
92
+ newBobSession.node,
93
93
  childGroup.id,
94
94
  );
95
95
 
@@ -138,15 +138,15 @@ describe("Group.childKeyRotation", () => {
138
138
  const newBobSession = await bob.spawnNewSession();
139
139
 
140
140
  for (const chunk of content) {
141
- newBobSession.syncManager.handleNewContent(chunk, "import");
141
+ newBobSession.node.syncManager.handleNewContent(chunk, "import");
142
142
  }
143
143
 
144
144
  const childGroupOnNewBobNode = await loadCoValueOrFail(
145
- newBobSession,
145
+ newBobSession.node,
146
146
  childGroup.id,
147
147
  );
148
148
 
149
- newBobSession.syncManager.handleNewContent(lastChunk, "import");
149
+ newBobSession.node.syncManager.handleNewContent(lastChunk, "import");
150
150
 
151
151
  // The migration waits for the group to be completely downloaded
152
152
  await childGroupOnNewBobNode.core.waitForAsync((core) =>
@@ -205,15 +205,15 @@ describe("Group.childKeyRotation", () => {
205
205
  const newBobSession = await bob.spawnNewSession();
206
206
 
207
207
  for (const chunk of content) {
208
- newBobSession.syncManager.handleNewContent(chunk, "import");
208
+ newBobSession.node.syncManager.handleNewContent(chunk, "import");
209
209
  }
210
210
 
211
211
  const childGroupOnNewBobNode = await loadCoValueOrFail(
212
- newBobSession,
212
+ newBobSession.node,
213
213
  childGroup.id,
214
214
  );
215
215
 
216
- newBobSession.syncManager.handleNewContent(lastChunk, "import");
216
+ newBobSession.node.syncManager.handleNewContent(lastChunk, "import");
217
217
 
218
218
  // The migration waits for the group to be completely downloaded, this includes full streaming of the parent group
219
219
  await childGroupOnNewBobNode.core.waitForAsync((core) =>
@@ -268,7 +268,7 @@ describe("Group.childKeyRotation", () => {
268
268
 
269
269
  // Instead Bob is an admin, so when loading the child group he can rotate the readKey
270
270
  const newBobSession = await bob.spawnNewSession();
271
- const mapOnNewBobNode = await loadCoValueOrFail(newBobSession, map.id);
271
+ const mapOnNewBobNode = await loadCoValueOrFail(newBobSession.node, map.id);
272
272
 
273
273
  mapOnNewBobNode.set("test", "Not readable by charlie");
274
274
 
@@ -416,7 +416,7 @@ describe("Group.childKeyRotation", () => {
416
416
 
417
417
  const newBobSession = await bob.spawnNewSession();
418
418
  const childGroupOnNewBobNode = await loadCoValueOrFail(
419
- newBobSession,
419
+ newBobSession.node,
420
420
  childGroup.id,
421
421
  );
422
422
 
@@ -10,6 +10,7 @@ import {
10
10
  isKnownStateSubsetOf,
11
11
  type CoValueKnownState,
12
12
  type KnownStateSessions,
13
+ areCurrentSessionsInSyncWith,
13
14
  } from "../knownState.js";
14
15
  import { RawCoID, SessionID } from "../ids.js";
15
16
 
@@ -547,14 +548,14 @@ describe("knownState", () => {
547
548
  });
548
549
  });
549
550
 
550
- describe("isKnownStateSubsetOf", () => {
551
+ describe("areCurrentSessionsInSyncWith", () => {
551
552
  test("should return true when all counters match", () => {
552
553
  const session1 = "session-1" as SessionID;
553
554
  const session2 = "session-2" as SessionID;
554
555
  const from = { [session1]: 5, [session2]: 10 };
555
556
  const to = { [session1]: 5, [session2]: 10 };
556
557
 
557
- const result = isKnownStateSubsetOf(from, to);
558
+ const result = areCurrentSessionsInSyncWith(from, to);
558
559
 
559
560
  expect(result).toBe(true);
560
561
  });
@@ -564,7 +565,7 @@ describe("knownState", () => {
564
565
  const from = { [session1]: 5 };
565
566
  const to = { [session1]: 3 };
566
567
 
567
- const result = isKnownStateSubsetOf(from, to);
568
+ const result = areCurrentSessionsInSyncWith(from, to);
568
569
 
569
570
  expect(result).toBe(false);
570
571
  });
@@ -574,7 +575,7 @@ describe("knownState", () => {
574
575
  const from = { [session1]: 5 };
575
576
  const to = {};
576
577
 
577
- const result = isKnownStateSubsetOf(from, to);
578
+ const result = areCurrentSessionsInSyncWith(from, to);
578
579
 
579
580
  expect(result).toBe(false);
580
581
  });
@@ -584,7 +585,7 @@ describe("knownState", () => {
584
585
  const from = {};
585
586
  const to = { [session1]: 5 };
586
587
 
587
- const result = isKnownStateSubsetOf(from, to);
588
+ const result = areCurrentSessionsInSyncWith(from, to);
588
589
 
589
590
  expect(result).toBe(true);
590
591
  });
@@ -593,7 +594,7 @@ describe("knownState", () => {
593
594
  const from = {};
594
595
  const to = {};
595
596
 
596
- const result = isKnownStateSubsetOf(from, to);
597
+ const result = areCurrentSessionsInSyncWith(from, to);
597
598
 
598
599
  expect(result).toBe(true);
599
600
  });
@@ -613,7 +614,7 @@ describe("knownState", () => {
613
614
  [session3]: 15,
614
615
  };
615
616
 
616
- const result = isKnownStateSubsetOf(from, to);
617
+ const result = areCurrentSessionsInSyncWith(from, to);
617
618
 
618
619
  expect(result).toBe(true);
619
620
  });
@@ -633,7 +634,7 @@ describe("knownState", () => {
633
634
  [session3]: 15,
634
635
  };
635
636
 
636
- const result = isKnownStateSubsetOf(from, to);
637
+ const result = areCurrentSessionsInSyncWith(from, to);
637
638
 
638
639
  expect(result).toBe(false);
639
640
  });
@@ -647,7 +648,7 @@ describe("knownState", () => {
647
648
  [session2]: 10,
648
649
  };
649
650
 
650
- const result = isKnownStateSubsetOf(from, to);
651
+ const result = areCurrentSessionsInSyncWith(from, to);
651
652
 
652
653
  expect(result).toBe(true);
653
654
  });
@@ -657,9 +658,105 @@ describe("knownState", () => {
657
658
  const from = { [session1]: 5 };
658
659
  const to = { [session1]: 10 };
659
660
 
661
+ const result = areCurrentSessionsInSyncWith(from, to);
662
+
663
+ expect(result).toBe(false);
664
+ });
665
+ });
666
+
667
+ describe("isKnownStateSubsetOf", () => {
668
+ test("should return true when all counters match", () => {
669
+ const session1 = "session-1" as SessionID;
670
+ const session2 = "session-2" as SessionID;
671
+ const from = { [session1]: 5, [session2]: 10 };
672
+ const to = { [session1]: 5, [session2]: 10 };
673
+
674
+ const result = isKnownStateSubsetOf(from, to);
675
+
676
+ expect(result).toBe(true);
677
+ });
678
+
679
+ test("should return false when the current session counter is higher than the target", () => {
680
+ const session1 = "session-1" as SessionID;
681
+ const from = { [session1]: 5 };
682
+ const to = { [session1]: 3 };
683
+
660
684
  const result = isKnownStateSubsetOf(from, to);
661
685
 
662
686
  expect(result).toBe(false);
663
687
  });
688
+
689
+ test("should return true when the target session counter is higher than the target", () => {
690
+ const session1 = "session-1" as SessionID;
691
+ const from = { [session1]: 5 };
692
+ const to = { [session1]: 10 };
693
+
694
+ const result = isKnownStateSubsetOf(from, to);
695
+
696
+ expect(result).toBe(true);
697
+ });
698
+
699
+ test("should return false when session is missing in to", () => {
700
+ const session1 = "session-1" as SessionID;
701
+ const from = { [session1]: 5 };
702
+ const to = {};
703
+
704
+ const result = isKnownStateSubsetOf(from, to);
705
+
706
+ expect(result).toBe(false);
707
+ });
708
+
709
+ test("should return true when from is empty", () => {
710
+ const session1 = "session-1" as SessionID;
711
+ const from = {};
712
+ const to = { [session1]: 5 };
713
+
714
+ const result = isKnownStateSubsetOf(from, to);
715
+
716
+ expect(result).toBe(true);
717
+ });
718
+
719
+ test("should return true when both are empty", () => {
720
+ const from = {};
721
+ const to = {};
722
+
723
+ const result = isKnownStateSubsetOf(from, to);
724
+
725
+ expect(result).toBe(true);
726
+ });
727
+
728
+ test("should handle multiple sessions", () => {
729
+ const session1 = "session-1" as SessionID;
730
+ const session2 = "session-2" as SessionID;
731
+ const session3 = "session-3" as SessionID;
732
+ const from = {
733
+ [session1]: 5,
734
+ [session2]: 10,
735
+ [session3]: 15,
736
+ };
737
+ const to = {
738
+ [session1]: 5,
739
+ [session2]: 10,
740
+ [session3]: 15,
741
+ };
742
+
743
+ const result = isKnownStateSubsetOf(from, to);
744
+
745
+ expect(result).toBe(true);
746
+ });
747
+
748
+ test("should not check sessions in to that are not in from", () => {
749
+ const session1 = "session-1" as SessionID;
750
+ const session2 = "session-2" as SessionID;
751
+ const from = { [session1]: 5 };
752
+ const to = {
753
+ [session1]: 5,
754
+ [session2]: 10,
755
+ };
756
+
757
+ const result = isKnownStateSubsetOf(from, to);
758
+
759
+ expect(result).toBe(true);
760
+ });
664
761
  });
665
762
  });
@@ -654,35 +654,35 @@ describe("loading coValues from server", () => {
654
654
  "server -> client | CONTENT Map header: true new: ",
655
655
  "client -> server | KNOWN Group sessions: header/5",
656
656
  "client -> server | KNOWN Map sessions: header/0",
657
- "server -> client | CONTENT Map header: false new: After: 0 New: 72 expectContentUntil: header/1024",
658
- "server -> client | CONTENT Map header: false new: After: 72 New: 73",
659
- "server -> client | CONTENT Map header: false new: After: 145 New: 73",
660
- "server -> client | CONTENT Map header: false new: After: 218 New: 73",
661
- "server -> client | CONTENT Map header: false new: After: 291 New: 73",
662
- "server -> client | CONTENT Map header: false new: After: 364 New: 73",
663
- "server -> client | CONTENT Map header: false new: After: 437 New: 73",
664
- "server -> client | CONTENT Map header: false new: After: 510 New: 73",
665
- "server -> client | CONTENT Map header: false new: After: 583 New: 73",
666
- "server -> client | CONTENT Map header: false new: After: 656 New: 73",
667
- "server -> client | CONTENT Map header: false new: After: 729 New: 73",
668
- "server -> client | CONTENT Map header: false new: After: 802 New: 73",
669
- "server -> client | CONTENT Map header: false new: After: 875 New: 73",
670
- "server -> client | CONTENT Map header: false new: After: 948 New: 73",
671
- "server -> client | CONTENT Map header: false new: After: 1021 New: 3",
672
- "client -> server | KNOWN Map sessions: header/72",
673
- "client -> server | KNOWN Map sessions: header/145",
674
- "client -> server | KNOWN Map sessions: header/218",
675
- "client -> server | KNOWN Map sessions: header/291",
676
- "client -> server | KNOWN Map sessions: header/364",
677
- "client -> server | KNOWN Map sessions: header/437",
678
- "client -> server | KNOWN Map sessions: header/510",
679
- "client -> server | KNOWN Map sessions: header/583",
680
- "client -> server | KNOWN Map sessions: header/656",
681
- "client -> server | KNOWN Map sessions: header/729",
682
- "client -> server | KNOWN Map sessions: header/802",
683
- "client -> server | KNOWN Map sessions: header/875",
684
- "client -> server | KNOWN Map sessions: header/948",
685
- "client -> server | KNOWN Map sessions: header/1021",
657
+ "server -> client | CONTENT Map header: false new: After: 0 New: 73 expectContentUntil: header/1024",
658
+ "server -> client | CONTENT Map header: false new: After: 73 New: 73",
659
+ "server -> client | CONTENT Map header: false new: After: 146 New: 73",
660
+ "server -> client | CONTENT Map header: false new: After: 219 New: 73",
661
+ "server -> client | CONTENT Map header: false new: After: 292 New: 73",
662
+ "server -> client | CONTENT Map header: false new: After: 365 New: 73",
663
+ "server -> client | CONTENT Map header: false new: After: 438 New: 73",
664
+ "server -> client | CONTENT Map header: false new: After: 511 New: 73",
665
+ "server -> client | CONTENT Map header: false new: After: 584 New: 73",
666
+ "server -> client | CONTENT Map header: false new: After: 657 New: 73",
667
+ "server -> client | CONTENT Map header: false new: After: 730 New: 73",
668
+ "server -> client | CONTENT Map header: false new: After: 803 New: 73",
669
+ "server -> client | CONTENT Map header: false new: After: 876 New: 73",
670
+ "server -> client | CONTENT Map header: false new: After: 949 New: 73",
671
+ "server -> client | CONTENT Map header: false new: After: 1022 New: 2",
672
+ "client -> server | KNOWN Map sessions: header/73",
673
+ "client -> server | KNOWN Map sessions: header/146",
674
+ "client -> server | KNOWN Map sessions: header/219",
675
+ "client -> server | KNOWN Map sessions: header/292",
676
+ "client -> server | KNOWN Map sessions: header/365",
677
+ "client -> server | KNOWN Map sessions: header/438",
678
+ "client -> server | KNOWN Map sessions: header/511",
679
+ "client -> server | KNOWN Map sessions: header/584",
680
+ "client -> server | KNOWN Map sessions: header/657",
681
+ "client -> server | KNOWN Map sessions: header/730",
682
+ "client -> server | KNOWN Map sessions: header/803",
683
+ "client -> server | KNOWN Map sessions: header/876",
684
+ "client -> server | KNOWN Map sessions: header/949",
685
+ "client -> server | KNOWN Map sessions: header/1022",
686
686
  "client -> server | KNOWN Map sessions: header/1024",
687
687
  ]
688
688
  `);
@@ -498,11 +498,11 @@ describe("multiple clients syncing with the a cloud-like server mesh", () => {
498
498
  ).toMatchInlineSnapshot(`
499
499
  [
500
500
  "edge -> storage | CONTENT Group header: true new: After: 0 New: 5",
501
- "edge -> storage | CONTENT Map header: true new: After: 0 New: 20 expectContentUntil: header/100",
502
- "edge -> storage | CONTENT Map header: false new: After: 20 New: 21",
503
- "edge -> storage | CONTENT Map header: false new: After: 41 New: 21",
504
- "edge -> storage | CONTENT Map header: false new: After: 62 New: 21",
505
- "edge -> storage | CONTENT Map header: false new: After: 83 New: 17",
501
+ "edge -> storage | CONTENT Map header: true new: After: 0 New: 21 expectContentUntil: header/100",
502
+ "edge -> storage | CONTENT Map header: false new: After: 21 New: 21",
503
+ "edge -> storage | CONTENT Map header: false new: After: 42 New: 21",
504
+ "edge -> storage | CONTENT Map header: false new: After: 63 New: 21",
505
+ "edge -> storage | CONTENT Map header: false new: After: 84 New: 16",
506
506
  ]
507
507
  `);
508
508
 
@@ -549,10 +549,10 @@ describe("multiple clients syncing with the a cloud-like server mesh", () => {
549
549
  "edge -> storage | LOAD Map sessions: empty",
550
550
  "storage -> edge | CONTENT Group header: true new: After: 0 New: 5",
551
551
  "edge -> core | LOAD Group sessions: header/5",
552
- "storage -> edge | CONTENT Map header: true new: After: 0 New: 41 expectContentUntil: header/100",
552
+ "storage -> edge | CONTENT Map header: true new: After: 0 New: 21 expectContentUntil: header/100",
553
553
  "edge -> core | LOAD Map sessions: header/100",
554
554
  "edge -> client | CONTENT Group header: true new: After: 0 New: 5",
555
- "edge -> client | CONTENT Map header: true new: After: 0 New: 41 expectContentUntil: header/100",
555
+ "edge -> client | CONTENT Map header: true new: After: 0 New: 21 expectContentUntil: header/100",
556
556
  "core -> storage | LOAD Group sessions: empty",
557
557
  "storage -> core | KNOWN Group sessions: empty",
558
558
  "core -> edge | KNOWN Group sessions: empty",
@@ -561,35 +561,42 @@ describe("multiple clients syncing with the a cloud-like server mesh", () => {
561
561
  "core -> edge | KNOWN Map sessions: empty",
562
562
  "client -> edge | KNOWN Group sessions: header/5",
563
563
  "client -> storage | CONTENT Group header: true new: After: 0 New: 5",
564
- "client -> edge | KNOWN Map sessions: header/41",
565
- "client -> storage | CONTENT Map header: true new: After: 0 New: 41",
566
- "storage -> edge | CONTENT Map header: true new: After: 41 New: 21",
567
- "edge -> client | CONTENT Map header: false new: After: 41 New: 21 expectContentUntil: header/100",
564
+ "client -> edge | KNOWN Map sessions: header/21",
565
+ "client -> storage | CONTENT Map header: true new: After: 0 New: 21",
566
+ "storage -> edge | CONTENT Map header: true new: After: 21 New: 21",
567
+ "edge -> client | CONTENT Map header: false new: After: 21 New: 21 expectContentUntil: header/100",
568
568
  "edge -> core | CONTENT Group header: true new: After: 0 New: 5",
569
- "edge -> core | CONTENT Map header: true new: After: 0 New: 41 expectContentUntil: header/100",
570
- "edge -> core | CONTENT Map header: false new: After: 41 New: 21",
571
- "client -> edge | KNOWN Map sessions: header/62",
572
- "client -> storage | CONTENT Map header: false new: After: 41 New: 21",
573
- "storage -> edge | CONTENT Map header: true new: After: 62 New: 21",
574
- "edge -> core | CONTENT Map header: false new: After: 62 New: 21 expectContentUntil: header/100",
575
- "edge -> client | CONTENT Map header: false new: After: 62 New: 21 expectContentUntil: header/100",
569
+ "edge -> core | CONTENT Map header: true new: After: 0 New: 21 expectContentUntil: header/100",
570
+ "edge -> core | CONTENT Map header: false new: After: 21 New: 21",
571
+ "client -> edge | KNOWN Map sessions: header/42",
572
+ "client -> storage | CONTENT Map header: false new: After: 21 New: 21",
573
+ "storage -> edge | CONTENT Map header: true new: After: 42 New: 21",
574
+ "edge -> core | CONTENT Map header: false new: After: 42 New: 21 expectContentUntil: header/100",
575
+ "edge -> client | CONTENT Map header: false new: After: 42 New: 21 expectContentUntil: header/100",
576
576
  "core -> edge | KNOWN Group sessions: header/5",
577
577
  "core -> storage | CONTENT Group header: true new: After: 0 New: 5",
578
- "core -> edge | KNOWN Map sessions: header/41",
579
- "core -> storage | CONTENT Map header: true new: After: 0 New: 41",
580
- "core -> edge | KNOWN Map sessions: header/62",
581
- "core -> storage | CONTENT Map header: false new: After: 41 New: 21",
582
- "core -> edge | KNOWN Map sessions: header/83",
583
- "core -> storage | CONTENT Map header: false new: After: 62 New: 21",
584
- "client -> edge | KNOWN Map sessions: header/83",
585
- "client -> storage | CONTENT Map header: false new: After: 62 New: 21",
586
- "storage -> edge | CONTENT Map header: true new: After: 83 New: 17",
587
- "edge -> core | CONTENT Map header: false new: After: 83 New: 17",
588
- "edge -> client | CONTENT Map header: false new: After: 83 New: 17",
578
+ "core -> edge | KNOWN Map sessions: header/21",
579
+ "core -> storage | CONTENT Map header: true new: After: 0 New: 21",
580
+ "core -> edge | KNOWN Map sessions: header/42",
581
+ "core -> storage | CONTENT Map header: false new: After: 21 New: 21",
582
+ "core -> edge | KNOWN Map sessions: header/63",
583
+ "core -> storage | CONTENT Map header: false new: After: 42 New: 21",
584
+ "client -> edge | KNOWN Map sessions: header/63",
585
+ "client -> storage | CONTENT Map header: false new: After: 42 New: 21",
586
+ "storage -> edge | CONTENT Map header: true new: After: 63 New: 21",
587
+ "edge -> core | CONTENT Map header: false new: After: 63 New: 21 expectContentUntil: header/100",
588
+ "edge -> client | CONTENT Map header: false new: After: 63 New: 21 expectContentUntil: header/100",
589
+ "core -> edge | KNOWN Map sessions: header/84",
590
+ "core -> storage | CONTENT Map header: false new: After: 63 New: 21",
591
+ "client -> edge | KNOWN Map sessions: header/84",
592
+ "client -> storage | CONTENT Map header: false new: After: 63 New: 21",
593
+ "storage -> edge | CONTENT Map header: true new: After: 84 New: 16",
594
+ "edge -> core | CONTENT Map header: false new: After: 84 New: 16",
595
+ "edge -> client | CONTENT Map header: false new: After: 84 New: 16",
589
596
  "core -> edge | KNOWN Map sessions: header/100",
590
- "core -> storage | CONTENT Map header: false new: After: 83 New: 17",
597
+ "core -> storage | CONTENT Map header: false new: After: 84 New: 16",
591
598
  "client -> edge | KNOWN Map sessions: header/100",
592
- "client -> storage | CONTENT Map header: false new: After: 83 New: 17",
599
+ "client -> storage | CONTENT Map header: false new: After: 84 New: 16",
593
600
  ]
594
601
  `);
595
602
 
@@ -382,28 +382,28 @@ describe("client syncs with a server with storage", () => {
382
382
  [
383
383
  "client -> storage | CONTENT Group header: true new: After: 0 New: 5",
384
384
  "client -> server | CONTENT Group header: true new: After: 0 New: 5",
385
- "client -> storage | CONTENT Map header: true new: After: 0 New: 20 expectContentUntil: header/100",
386
- "client -> server | CONTENT Map header: true new: After: 0 New: 20 expectContentUntil: header/100",
387
- "client -> storage | CONTENT Map header: false new: After: 20 New: 21",
388
- "client -> server | CONTENT Map header: false new: After: 20 New: 21",
389
- "client -> storage | CONTENT Map header: false new: After: 41 New: 21",
390
- "client -> server | CONTENT Map header: false new: After: 41 New: 21",
391
- "client -> storage | CONTENT Map header: false new: After: 62 New: 21",
392
- "client -> server | CONTENT Map header: false new: After: 62 New: 21",
393
- "client -> storage | CONTENT Map header: false new: After: 83 New: 17",
394
- "client -> server | CONTENT Map header: false new: After: 83 New: 17",
385
+ "client -> storage | CONTENT Map header: true new: After: 0 New: 21 expectContentUntil: header/100",
386
+ "client -> server | CONTENT Map header: true new: After: 0 New: 21 expectContentUntil: header/100",
387
+ "client -> storage | CONTENT Map header: false new: After: 21 New: 21",
388
+ "client -> server | CONTENT Map header: false new: After: 21 New: 21",
389
+ "client -> storage | CONTENT Map header: false new: After: 42 New: 21",
390
+ "client -> server | CONTENT Map header: false new: After: 42 New: 21",
391
+ "client -> storage | CONTENT Map header: false new: After: 63 New: 21",
392
+ "client -> server | CONTENT Map header: false new: After: 63 New: 21",
393
+ "client -> storage | CONTENT Map header: false new: After: 84 New: 16",
394
+ "client -> server | CONTENT Map header: false new: After: 84 New: 16",
395
395
  "server -> client | KNOWN Group sessions: header/5",
396
396
  "server -> storage | CONTENT Group header: true new: After: 0 New: 5",
397
- "server -> client | KNOWN Map sessions: header/20",
398
- "server -> storage | CONTENT Map header: true new: After: 0 New: 20",
399
- "server -> client | KNOWN Map sessions: header/41",
400
- "server -> storage | CONTENT Map header: false new: After: 20 New: 21",
401
- "server -> client | KNOWN Map sessions: header/62",
402
- "server -> storage | CONTENT Map header: false new: After: 41 New: 21",
403
- "server -> client | KNOWN Map sessions: header/83",
404
- "server -> storage | CONTENT Map header: false new: After: 62 New: 21",
397
+ "server -> client | KNOWN Map sessions: header/21",
398
+ "server -> storage | CONTENT Map header: true new: After: 0 New: 21",
399
+ "server -> client | KNOWN Map sessions: header/42",
400
+ "server -> storage | CONTENT Map header: false new: After: 21 New: 21",
401
+ "server -> client | KNOWN Map sessions: header/63",
402
+ "server -> storage | CONTENT Map header: false new: After: 42 New: 21",
403
+ "server -> client | KNOWN Map sessions: header/84",
404
+ "server -> storage | CONTENT Map header: false new: After: 63 New: 21",
405
405
  "server -> client | KNOWN Map sessions: header/100",
406
- "server -> storage | CONTENT Map header: false new: After: 83 New: 17",
406
+ "server -> storage | CONTENT Map header: false new: After: 84 New: 16",
407
407
  ]
408
408
  `);
409
409
 
@@ -456,13 +456,14 @@ describe("client syncs with a server with storage", () => {
456
456
  "client -> storage | LOAD Map sessions: empty",
457
457
  "storage -> client | CONTENT Group header: true new: After: 0 New: 5",
458
458
  "client -> server | LOAD Group sessions: header/5",
459
- "storage -> client | CONTENT Map header: true new: After: 0 New: 41 expectContentUntil: header/100",
459
+ "storage -> client | CONTENT Map header: true new: After: 0 New: 21 expectContentUntil: header/100",
460
460
  "client -> server | LOAD Map sessions: header/100",
461
461
  "server -> client | KNOWN Group sessions: header/5",
462
462
  "server -> client | KNOWN Map sessions: header/100",
463
- "storage -> client | CONTENT Map header: true new: After: 41 New: 21",
464
- "storage -> client | CONTENT Map header: true new: After: 62 New: 21",
465
- "storage -> client | CONTENT Map header: true new: After: 83 New: 17",
463
+ "storage -> client | CONTENT Map header: true new: After: 21 New: 21",
464
+ "storage -> client | CONTENT Map header: true new: After: 42 New: 21",
465
+ "storage -> client | CONTENT Map header: true new: After: 63 New: 21",
466
+ "storage -> client | CONTENT Map header: true new: After: 84 New: 16",
466
467
  ]
467
468
  `);
468
469
  });