cojson 0.16.5 → 0.16.7

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 (121) hide show
  1. package/.turbo/turbo-build.log +1 -1
  2. package/CHANGELOG.md +16 -0
  3. package/dist/GarbageCollector.d.ts +12 -0
  4. package/dist/GarbageCollector.d.ts.map +1 -0
  5. package/dist/GarbageCollector.js +37 -0
  6. package/dist/GarbageCollector.js.map +1 -0
  7. package/dist/coValue.d.ts +1 -1
  8. package/dist/coValueContentMessage.d.ts +1 -0
  9. package/dist/coValueContentMessage.d.ts.map +1 -1
  10. package/dist/coValueContentMessage.js +11 -3
  11. package/dist/coValueContentMessage.js.map +1 -1
  12. package/dist/coValueCore/coValueCore.d.ts +2 -1
  13. package/dist/coValueCore/coValueCore.d.ts.map +1 -1
  14. package/dist/coValueCore/coValueCore.js +15 -0
  15. package/dist/coValueCore/coValueCore.js.map +1 -1
  16. package/dist/coValueCore/utils.d.ts.map +1 -1
  17. package/dist/coValueCore/utils.js.map +1 -1
  18. package/dist/coValueCore/verifiedState.d.ts +1 -0
  19. package/dist/coValueCore/verifiedState.d.ts.map +1 -1
  20. package/dist/coValueCore/verifiedState.js.map +1 -1
  21. package/dist/coValues/coMap.d.ts +3 -3
  22. package/dist/coValues/coPlainText.d.ts +1 -0
  23. package/dist/coValues/coPlainText.d.ts.map +1 -1
  24. package/dist/coValues/coPlainText.js +27 -8
  25. package/dist/coValues/coPlainText.js.map +1 -1
  26. package/dist/coValues/coStream.d.ts +2 -2
  27. package/dist/coValues/group.d.ts +1 -1
  28. package/dist/config.d.ts +10 -1
  29. package/dist/config.d.ts.map +1 -1
  30. package/dist/config.js +16 -1
  31. package/dist/config.js.map +1 -1
  32. package/dist/exports.d.ts +11 -4
  33. package/dist/exports.d.ts.map +1 -1
  34. package/dist/exports.js +8 -3
  35. package/dist/exports.js.map +1 -1
  36. package/dist/localNode.d.ts +3 -0
  37. package/dist/localNode.d.ts.map +1 -1
  38. package/dist/localNode.js +11 -0
  39. package/dist/localNode.js.map +1 -1
  40. package/dist/permissions.d.ts.map +1 -1
  41. package/dist/permissions.js +3 -1
  42. package/dist/permissions.js.map +1 -1
  43. package/dist/queue/LocalTransactionsSyncQueue.js +1 -1
  44. package/dist/queue/LocalTransactionsSyncQueue.js.map +1 -1
  45. package/dist/queue/StoreQueue.d.ts +7 -1
  46. package/dist/queue/StoreQueue.d.ts.map +1 -1
  47. package/dist/queue/StoreQueue.js +35 -13
  48. package/dist/queue/StoreQueue.js.map +1 -1
  49. package/dist/storage/sqlite/client.d.ts +4 -4
  50. package/dist/storage/sqlite/client.d.ts.map +1 -1
  51. package/dist/storage/sqlite/client.js +13 -4
  52. package/dist/storage/sqlite/client.js.map +1 -1
  53. package/dist/storage/sqliteAsync/client.d.ts +3 -3
  54. package/dist/storage/sqliteAsync/client.d.ts.map +1 -1
  55. package/dist/storage/sqliteAsync/client.js +12 -3
  56. package/dist/storage/sqliteAsync/client.js.map +1 -1
  57. package/dist/storage/storageAsync.d.ts.map +1 -1
  58. package/dist/storage/storageAsync.js +2 -7
  59. package/dist/storage/storageAsync.js.map +1 -1
  60. package/dist/storage/storageSync.d.ts.map +1 -1
  61. package/dist/storage/storageSync.js +2 -7
  62. package/dist/storage/storageSync.js.map +1 -1
  63. package/dist/storage/types.d.ts +2 -2
  64. package/dist/storage/types.d.ts.map +1 -1
  65. package/dist/sync.d.ts.map +1 -1
  66. package/dist/sync.js +17 -3
  67. package/dist/sync.js.map +1 -1
  68. package/dist/tests/GarbageCollector.test.d.ts +2 -0
  69. package/dist/tests/GarbageCollector.test.d.ts.map +1 -0
  70. package/dist/tests/GarbageCollector.test.js +85 -0
  71. package/dist/tests/GarbageCollector.test.js.map +1 -0
  72. package/dist/tests/coPlainText.test.js +142 -4
  73. package/dist/tests/coPlainText.test.js.map +1 -1
  74. package/dist/tests/coStream.test.js +3 -3
  75. package/dist/tests/coStream.test.js.map +1 -1
  76. package/dist/tests/sync.garbageCollection.test.d.ts +2 -0
  77. package/dist/tests/sync.garbageCollection.test.d.ts.map +1 -0
  78. package/dist/tests/sync.garbageCollection.test.js +133 -0
  79. package/dist/tests/sync.garbageCollection.test.js.map +1 -0
  80. package/dist/tests/sync.mesh.test.js +48 -34
  81. package/dist/tests/sync.mesh.test.js.map +1 -1
  82. package/dist/tests/sync.storage.test.js +31 -21
  83. package/dist/tests/sync.storage.test.js.map +1 -1
  84. package/dist/tests/sync.storageAsync.test.js +76 -29
  85. package/dist/tests/sync.storageAsync.test.js.map +1 -1
  86. package/dist/tests/testStorage.d.ts +1 -0
  87. package/dist/tests/testStorage.d.ts.map +1 -1
  88. package/dist/tests/testStorage.js +1 -1
  89. package/dist/tests/testStorage.js.map +1 -1
  90. package/dist/tests/testUtils.d.ts +1 -0
  91. package/dist/tests/testUtils.d.ts.map +1 -1
  92. package/dist/tests/testUtils.js +1 -0
  93. package/dist/tests/testUtils.js.map +1 -1
  94. package/package.json +1 -1
  95. package/src/GarbageCollector.ts +48 -0
  96. package/src/coValueContentMessage.ts +16 -3
  97. package/src/coValueCore/coValueCore.ts +27 -10
  98. package/src/coValueCore/utils.ts +1 -0
  99. package/src/coValueCore/verifiedState.ts +1 -0
  100. package/src/coValues/coPlainText.ts +40 -8
  101. package/src/config.ts +20 -1
  102. package/src/exports.ts +13 -5
  103. package/src/localNode.ts +15 -1
  104. package/src/permissions.ts +3 -1
  105. package/src/queue/LocalTransactionsSyncQueue.ts +1 -1
  106. package/src/queue/StoreQueue.ts +45 -12
  107. package/src/storage/sqlite/client.ts +24 -10
  108. package/src/storage/sqliteAsync/client.ts +26 -5
  109. package/src/storage/storageAsync.ts +5 -9
  110. package/src/storage/storageSync.ts +2 -9
  111. package/src/storage/types.ts +7 -4
  112. package/src/sync.ts +19 -3
  113. package/src/tests/GarbageCollector.test.ts +127 -0
  114. package/src/tests/coPlainText.test.ts +176 -4
  115. package/src/tests/coStream.test.ts +7 -3
  116. package/src/tests/sync.garbageCollection.test.ts +178 -0
  117. package/src/tests/sync.mesh.test.ts +49 -34
  118. package/src/tests/sync.storage.test.ts +31 -21
  119. package/src/tests/sync.storageAsync.test.ts +81 -29
  120. package/src/tests/testStorage.ts +11 -3
  121. package/src/tests/testUtils.ts +4 -1
@@ -1,6 +1,7 @@
1
1
  import { beforeEach, describe, expect, test, vi } from "vitest";
2
2
 
3
3
  import { expectMap } from "../coValue";
4
+ import { setMaxRecommendedTxSize } from "../config";
4
5
  import {
5
6
  SyncMessagesLog,
6
7
  TEST_NODE_CONFIG,
@@ -14,6 +15,10 @@ import {
14
15
  // We want to simulate a real world communication that happens asynchronously
15
16
  TEST_NODE_CONFIG.withAsyncPeers = true;
16
17
 
18
+ beforeEach(() => {
19
+ setMaxRecommendedTxSize(100 * 1024);
20
+ });
21
+
17
22
  function setupMesh() {
18
23
  const coreServer = setupTestNode();
19
24
 
@@ -254,6 +259,9 @@ describe("multiple clients syncing with the a cloud-like server mesh", () => {
254
259
 
255
260
  // Forcefully delete the coValue from the edge (simulating some data loss)
256
261
  mesh.edgeItaly.node.internalDeleteCoValue(map.id);
262
+ mesh.edgeItaly.addStorage({
263
+ ourName: "edge-italy",
264
+ });
257
265
 
258
266
  mapOnClient.set("fromClient", "updated", "trusting");
259
267
  mapOnCoreServer.set("fromServer", "updated", "trusting");
@@ -483,6 +491,7 @@ describe("multiple clients syncing with the a cloud-like server mesh", () => {
483
491
  });
484
492
 
485
493
  test("large coValue streaming from an edge to the core server and a client at the same time", async () => {
494
+ setMaxRecommendedTxSize(1000);
486
495
  const edge = setupTestNode();
487
496
 
488
497
  const { storage } = edge.addStorage({
@@ -494,12 +503,9 @@ describe("multiple clients syncing with the a cloud-like server mesh", () => {
494
503
 
495
504
  const largeMap = group.createMap();
496
505
 
497
- // Generate a large amount of data (about 100MB)
498
- const dataSize = 1 * 200 * 1024;
499
- const chunkSize = 1024; // 1KB chunks
500
- const chunks = dataSize / chunkSize;
506
+ const chunks = 100;
501
507
 
502
- const value = Buffer.alloc(chunkSize, `value$`).toString("base64");
508
+ const value = "1".repeat(10);
503
509
 
504
510
  for (let i = 0; i < chunks; i++) {
505
511
  const key = `key${i}`;
@@ -516,9 +522,11 @@ describe("multiple clients syncing with the a cloud-like server mesh", () => {
516
522
  ).toMatchInlineSnapshot(`
517
523
  [
518
524
  "edge -> storage | CONTENT Group header: true new: After: 0 New: 5",
519
- "edge -> storage | CONTENT Map header: true new: After: 0 New: 73",
520
- "edge -> storage | CONTENT Map header: false new: After: 73 New: 73",
521
- "edge -> storage | CONTENT Map header: false new: After: 146 New: 54",
525
+ "edge -> storage | CONTENT Map header: true new: After: 0 New: 20",
526
+ "edge -> storage | CONTENT Map header: false new: After: 20 New: 21",
527
+ "edge -> storage | CONTENT Map header: false new: After: 41 New: 21",
528
+ "edge -> storage | CONTENT Map header: false new: After: 62 New: 21",
529
+ "edge -> storage | CONTENT Map header: false new: After: 83 New: 17",
522
530
  ]
523
531
  `);
524
532
 
@@ -565,11 +573,11 @@ describe("multiple clients syncing with the a cloud-like server mesh", () => {
565
573
  "edge -> storage | LOAD Map sessions: empty",
566
574
  "storage -> edge | CONTENT Group header: true new: After: 0 New: 5",
567
575
  "edge -> core | LOAD Group sessions: header/5",
568
- "storage -> edge | CONTENT Map header: true new: After: 0 New: 73 expectContentUntil: header/200",
569
- "edge -> core | LOAD Map sessions: header/200",
576
+ "storage -> edge | CONTENT Map header: true new: After: 0 New: 41 expectContentUntil: header/100",
577
+ "edge -> core | LOAD Map sessions: header/100",
570
578
  "edge -> client | CONTENT Group header: true new: After: 0 New: 5",
571
- "edge -> client | CONTENT Map header: true new: expectContentUntil: header/200",
572
- "edge -> client | CONTENT Map header: false new: After: 0 New: 73",
579
+ "edge -> client | CONTENT Map header: true new: expectContentUntil: header/100",
580
+ "edge -> client | CONTENT Map header: false new: After: 0 New: 41",
573
581
  "core -> storage | LOAD Group sessions: empty",
574
582
  "storage -> core | KNOWN Group sessions: empty",
575
583
  "core -> edge | KNOWN Group sessions: empty",
@@ -579,32 +587,39 @@ describe("multiple clients syncing with the a cloud-like server mesh", () => {
579
587
  "client -> edge | KNOWN Group sessions: header/5",
580
588
  "client -> storage | CONTENT Group header: true new: After: 0 New: 5",
581
589
  "client -> edge | KNOWN Map sessions: header/0",
582
- "client -> storage | CONTENT Map header: true new: expectContentUntil: header/200",
583
- "client -> edge | KNOWN Map sessions: header/73",
584
- "client -> storage | CONTENT Map header: false new: After: 0 New: 73",
585
- "storage -> edge | CONTENT Map header: true new: After: 73 New: 73",
586
- "edge -> client | CONTENT Map header: false new: After: 73 New: 73",
590
+ "client -> storage | CONTENT Map header: true new: expectContentUntil: header/100",
591
+ "client -> edge | KNOWN Map sessions: header/41",
592
+ "client -> storage | CONTENT Map header: false new: After: 0 New: 41",
593
+ "storage -> edge | CONTENT Map header: true new: After: 41 New: 21",
594
+ "edge -> client | CONTENT Map header: false new: After: 41 New: 21",
587
595
  "edge -> core | CONTENT Group header: true new: After: 0 New: 5",
588
- "edge -> core | CONTENT Map header: true new: expectContentUntil: header/200",
589
- "edge -> core | CONTENT Map header: false new: After: 0 New: 73",
590
- "edge -> core | CONTENT Map header: false new: After: 73 New: 73",
591
- "client -> edge | KNOWN Map sessions: header/146",
592
- "client -> storage | CONTENT Map header: false new: After: 73 New: 73",
593
- "storage -> edge | CONTENT Map header: true new: After: 146 New: 54",
594
- "edge -> core | CONTENT Map header: false new: After: 146 New: 54",
595
- "edge -> client | CONTENT Map header: false new: After: 146 New: 54",
596
+ "edge -> core | CONTENT Map header: true new: expectContentUntil: header/100",
597
+ "edge -> core | CONTENT Map header: false new: After: 0 New: 41",
598
+ "edge -> core | CONTENT Map header: false new: After: 41 New: 21",
599
+ "client -> edge | KNOWN Map sessions: header/62",
600
+ "client -> storage | CONTENT Map header: false new: After: 41 New: 21",
601
+ "storage -> edge | CONTENT Map header: true new: After: 62 New: 21",
602
+ "edge -> core | CONTENT Map header: false new: After: 62 New: 21",
603
+ "edge -> client | CONTENT Map header: false new: After: 62 New: 21",
596
604
  "core -> edge | KNOWN Group sessions: header/5",
597
605
  "core -> storage | CONTENT Group header: true new: After: 0 New: 5",
598
606
  "core -> edge | KNOWN Map sessions: header/0",
599
- "core -> storage | CONTENT Map header: true new: expectContentUntil: header/200",
600
- "core -> edge | KNOWN Map sessions: header/73",
601
- "core -> storage | CONTENT Map header: false new: After: 0 New: 73",
602
- "core -> edge | KNOWN Map sessions: header/146",
603
- "core -> storage | CONTENT Map header: false new: After: 73 New: 73",
604
- "core -> edge | KNOWN Map sessions: header/200",
605
- "core -> storage | CONTENT Map header: false new: After: 146 New: 54",
606
- "client -> edge | KNOWN Map sessions: header/200",
607
- "client -> storage | CONTENT Map header: false new: After: 146 New: 54",
607
+ "core -> storage | CONTENT Map header: true new: expectContentUntil: header/100",
608
+ "core -> edge | KNOWN Map sessions: header/41",
609
+ "core -> storage | CONTENT Map header: false new: After: 0 New: 41",
610
+ "core -> edge | KNOWN Map sessions: header/62",
611
+ "core -> storage | CONTENT Map header: false new: After: 41 New: 21",
612
+ "core -> edge | KNOWN Map sessions: header/83",
613
+ "core -> storage | CONTENT Map header: false new: After: 62 New: 21",
614
+ "client -> edge | KNOWN Map sessions: header/83",
615
+ "client -> storage | CONTENT Map header: false new: After: 62 New: 21",
616
+ "storage -> edge | CONTENT Map header: true new: After: 83 New: 17",
617
+ "edge -> core | CONTENT Map header: false new: After: 83 New: 17",
618
+ "edge -> client | CONTENT Map header: false new: After: 83 New: 17",
619
+ "core -> edge | KNOWN Map sessions: header/100",
620
+ "core -> storage | CONTENT Map header: false new: After: 83 New: 17",
621
+ "client -> edge | KNOWN Map sessions: header/100",
622
+ "client -> storage | CONTENT Map header: false new: After: 83 New: 17",
608
623
  ]
609
624
  `);
610
625
 
@@ -8,6 +8,7 @@ import {
8
8
  vi,
9
9
  } from "vitest";
10
10
 
11
+ import { setMaxRecommendedTxSize } from "../config";
11
12
  import { emptyKnownState } from "../exports";
12
13
  import {
13
14
  SyncMessagesLog,
@@ -27,6 +28,7 @@ describe("client with storage syncs with server", () => {
27
28
 
28
29
  beforeEach(async () => {
29
30
  SyncMessagesLog.clear();
31
+ setMaxRecommendedTxSize(100 * 1024);
30
32
  jazzCloud = setupTestNode({
31
33
  isSyncServer: true,
32
34
  });
@@ -244,6 +246,7 @@ describe("client syncs with a server with storage", () => {
244
246
  });
245
247
 
246
248
  test("loading a large coValue from storage", async () => {
249
+ setMaxRecommendedTxSize(1000);
247
250
  const client = setupTestNode();
248
251
 
249
252
  client.connectToSyncServer({
@@ -260,11 +263,9 @@ describe("client syncs with a server with storage", () => {
260
263
  const largeMap = group.createMap();
261
264
 
262
265
  // Generate a large amount of data (about 100MB)
263
- const dataSize = 1 * 200 * 1024;
264
- const chunkSize = 1024; // 1KB chunks
265
- const chunks = dataSize / chunkSize;
266
+ const chunks = 100;
266
267
 
267
- const value = Buffer.alloc(chunkSize, `value$`).toString("base64");
268
+ const value = "1".repeat(10);
268
269
 
269
270
  for (let i = 0; i < chunks; i++) {
270
271
  const key = `key${i}`;
@@ -289,20 +290,28 @@ describe("client syncs with a server with storage", () => {
289
290
  [
290
291
  "client -> storage | CONTENT Group header: true new: After: 0 New: 5",
291
292
  "client -> server | CONTENT Group header: true new: After: 0 New: 5",
292
- "client -> storage | CONTENT Map header: true new: After: 0 New: 73",
293
- "client -> server | CONTENT Map header: true new: After: 0 New: 73",
294
- "client -> storage | CONTENT Map header: false new: After: 73 New: 73",
295
- "client -> server | CONTENT Map header: false new: After: 73 New: 73",
296
- "client -> storage | CONTENT Map header: false new: After: 146 New: 54",
297
- "client -> server | CONTENT Map header: false new: After: 146 New: 54",
293
+ "client -> storage | CONTENT Map header: true new: After: 0 New: 20",
294
+ "client -> server | CONTENT Map header: true new: After: 0 New: 20",
295
+ "client -> storage | CONTENT Map header: false new: After: 20 New: 21",
296
+ "client -> server | CONTENT Map header: false new: After: 20 New: 21",
297
+ "client -> storage | CONTENT Map header: false new: After: 41 New: 21",
298
+ "client -> server | CONTENT Map header: false new: After: 41 New: 21",
299
+ "client -> storage | CONTENT Map header: false new: After: 62 New: 21",
300
+ "client -> server | CONTENT Map header: false new: After: 62 New: 21",
301
+ "client -> storage | CONTENT Map header: false new: After: 83 New: 17",
302
+ "client -> server | CONTENT Map header: false new: After: 83 New: 17",
298
303
  "server -> client | KNOWN Group sessions: header/5",
299
304
  "server -> storage | CONTENT Group header: true new: After: 0 New: 5",
300
- "server -> client | KNOWN Map sessions: header/73",
301
- "server -> storage | CONTENT Map header: true new: After: 0 New: 73",
302
- "server -> client | KNOWN Map sessions: header/146",
303
- "server -> storage | CONTENT Map header: false new: After: 73 New: 73",
304
- "server -> client | KNOWN Map sessions: header/200",
305
- "server -> storage | CONTENT Map header: false new: After: 146 New: 54",
305
+ "server -> client | KNOWN Map sessions: header/20",
306
+ "server -> storage | CONTENT Map header: true new: After: 0 New: 20",
307
+ "server -> client | KNOWN Map sessions: header/41",
308
+ "server -> storage | CONTENT Map header: false new: After: 20 New: 21",
309
+ "server -> client | KNOWN Map sessions: header/62",
310
+ "server -> storage | CONTENT Map header: false new: After: 41 New: 21",
311
+ "server -> client | KNOWN Map sessions: header/83",
312
+ "server -> storage | CONTENT Map header: false new: After: 62 New: 21",
313
+ "server -> client | KNOWN Map sessions: header/100",
314
+ "server -> storage | CONTENT Map header: false new: After: 83 New: 17",
306
315
  ]
307
316
  `);
308
317
 
@@ -355,12 +364,13 @@ describe("client syncs with a server with storage", () => {
355
364
  "client -> storage | LOAD Map sessions: empty",
356
365
  "storage -> client | CONTENT Group header: true new: After: 0 New: 5",
357
366
  "client -> server | LOAD Group sessions: header/5",
358
- "storage -> client | CONTENT Map header: true new: After: 0 New: 73 expectContentUntil: header/200",
359
- "client -> server | LOAD Map sessions: header/200",
367
+ "storage -> client | CONTENT Map header: true new: After: 0 New: 41 expectContentUntil: header/100",
368
+ "client -> server | LOAD Map sessions: header/100",
360
369
  "server -> client | KNOWN Group sessions: header/5",
361
- "server -> client | KNOWN Map sessions: header/200",
362
- "storage -> client | CONTENT Map header: true new: After: 73 New: 73",
363
- "storage -> client | CONTENT Map header: true new: After: 146 New: 54",
370
+ "server -> client | KNOWN Map sessions: header/100",
371
+ "storage -> client | CONTENT Map header: true new: After: 41 New: 21",
372
+ "storage -> client | CONTENT Map header: true new: After: 62 New: 21",
373
+ "storage -> client | CONTENT Map header: true new: After: 83 New: 17",
364
374
  ]
365
375
  `);
366
376
  });
@@ -1,5 +1,6 @@
1
1
  import { assert, beforeEach, describe, expect, test, vi } from "vitest";
2
2
 
3
+ import { setMaxRecommendedTxSize } from "../config";
3
4
  import { emptyKnownState } from "../exports";
4
5
  import {
5
6
  SyncMessagesLog,
@@ -8,6 +9,7 @@ import {
8
9
  setupTestNode,
9
10
  waitFor,
10
11
  } from "./testUtils";
12
+ import { getDbPath } from "./testStorage";
11
13
 
12
14
  // We want to simulate a real world communication that happens asynchronously
13
15
  TEST_NODE_CONFIG.withAsyncPeers = true;
@@ -17,6 +19,7 @@ describe("client with storage syncs with server", () => {
17
19
 
18
20
  beforeEach(async () => {
19
21
  vi.resetAllMocks();
22
+ setMaxRecommendedTxSize(100 * 1024);
20
23
  SyncMessagesLog.clear();
21
24
  jazzCloud = setupTestNode({
22
25
  isSyncServer: true,
@@ -262,6 +265,7 @@ describe("client syncs with a server with storage", () => {
262
265
  });
263
266
 
264
267
  test("large coValue streaming", async () => {
268
+ setMaxRecommendedTxSize(1000);
265
269
  const client = setupTestNode();
266
270
 
267
271
  client.connectToSyncServer({
@@ -278,11 +282,9 @@ describe("client syncs with a server with storage", () => {
278
282
  const largeMap = group.createMap();
279
283
 
280
284
  // Generate a large amount of data (about 100MB)
281
- const dataSize = 1 * 200 * 1024;
282
- const chunkSize = 1024; // 1KB chunks
283
- const chunks = dataSize / chunkSize;
285
+ const chunks = 100;
284
286
 
285
- const value = Buffer.alloc(chunkSize, `value$`).toString("base64");
287
+ const value = "1".repeat(10);
286
288
 
287
289
  for (let i = 0; i < chunks; i++) {
288
290
  const key = `key${i}`;
@@ -300,20 +302,28 @@ describe("client syncs with a server with storage", () => {
300
302
  [
301
303
  "client -> storage | CONTENT Group header: true new: After: 0 New: 5",
302
304
  "client -> server | CONTENT Group header: true new: After: 0 New: 5",
303
- "client -> storage | CONTENT Map header: true new: After: 0 New: 73",
304
- "client -> server | CONTENT Map header: true new: After: 0 New: 73",
305
- "client -> storage | CONTENT Map header: false new: After: 73 New: 73",
306
- "client -> server | CONTENT Map header: false new: After: 73 New: 73",
307
- "client -> storage | CONTENT Map header: false new: After: 146 New: 54",
308
- "client -> server | CONTENT Map header: false new: After: 146 New: 54",
305
+ "client -> storage | CONTENT Map header: true new: After: 0 New: 20",
306
+ "client -> server | CONTENT Map header: true new: After: 0 New: 20",
307
+ "client -> storage | CONTENT Map header: false new: After: 20 New: 21",
308
+ "client -> server | CONTENT Map header: false new: After: 20 New: 21",
309
+ "client -> storage | CONTENT Map header: false new: After: 41 New: 21",
310
+ "client -> server | CONTENT Map header: false new: After: 41 New: 21",
311
+ "client -> storage | CONTENT Map header: false new: After: 62 New: 21",
312
+ "client -> server | CONTENT Map header: false new: After: 62 New: 21",
313
+ "client -> storage | CONTENT Map header: false new: After: 83 New: 17",
314
+ "client -> server | CONTENT Map header: false new: After: 83 New: 17",
309
315
  "server -> client | KNOWN Group sessions: header/5",
310
316
  "server -> storage | CONTENT Group header: true new: After: 0 New: 5",
311
- "server -> client | KNOWN Map sessions: header/73",
312
- "server -> storage | CONTENT Map header: true new: After: 0 New: 73",
313
- "server -> client | KNOWN Map sessions: header/146",
314
- "server -> storage | CONTENT Map header: false new: After: 73 New: 73",
315
- "server -> client | KNOWN Map sessions: header/200",
316
- "server -> storage | CONTENT Map header: false new: After: 146 New: 54",
317
+ "server -> client | KNOWN Map sessions: header/20",
318
+ "server -> storage | CONTENT Map header: true new: After: 0 New: 20",
319
+ "server -> client | KNOWN Map sessions: header/41",
320
+ "server -> storage | CONTENT Map header: false new: After: 20 New: 21",
321
+ "server -> client | KNOWN Map sessions: header/62",
322
+ "server -> storage | CONTENT Map header: false new: After: 41 New: 21",
323
+ "server -> client | KNOWN Map sessions: header/83",
324
+ "server -> storage | CONTENT Map header: false new: After: 62 New: 21",
325
+ "server -> client | KNOWN Map sessions: header/100",
326
+ "server -> storage | CONTENT Map header: false new: After: 83 New: 17",
317
327
  ]
318
328
  `);
319
329
 
@@ -345,12 +355,13 @@ describe("client syncs with a server with storage", () => {
345
355
  "client -> storage | LOAD Map sessions: empty",
346
356
  "storage -> client | CONTENT Group header: true new: After: 0 New: 5",
347
357
  "client -> server | LOAD Group sessions: header/5",
348
- "storage -> client | CONTENT Map header: true new: After: 0 New: 73 expectContentUntil: header/200",
349
- "client -> server | LOAD Map sessions: header/200",
350
- "storage -> client | CONTENT Map header: true new: After: 73 New: 73",
351
- "storage -> client | CONTENT Map header: true new: After: 146 New: 54",
358
+ "storage -> client | CONTENT Map header: true new: After: 0 New: 41 expectContentUntil: header/100",
359
+ "client -> server | LOAD Map sessions: header/100",
360
+ "storage -> client | CONTENT Map header: true new: After: 41 New: 21",
361
+ "storage -> client | CONTENT Map header: true new: After: 62 New: 21",
362
+ "storage -> client | CONTENT Map header: true new: After: 83 New: 17",
352
363
  "server -> client | KNOWN Group sessions: header/5",
353
- "server -> client | KNOWN Map sessions: header/200",
364
+ "server -> client | KNOWN Map sessions: header/100",
354
365
  ]
355
366
  `);
356
367
  });
@@ -446,8 +457,8 @@ describe("client syncs with a server with storage", () => {
446
457
 
447
458
  const largeMap = group.createMap();
448
459
 
449
- // Generate a large amount of data (about 100MB)
450
- const dataSize = 1 * 200 * 1024;
460
+ // Generate a large amount of data
461
+ const dataSize = 1 * 10 * 1024;
451
462
  const chunkSize = 1024; // 1KB chunks
452
463
  const chunks = dataSize / chunkSize;
453
464
 
@@ -495,17 +506,58 @@ describe("client syncs with a server with storage", () => {
495
506
  "client -> storage | LOAD Map sessions: empty",
496
507
  "storage -> client | CONTENT Group header: true new: After: 0 New: 5",
497
508
  "client -> server | LOAD Group sessions: header/5",
498
- "storage -> client | CONTENT Map header: true new: After: 0 New: 73 expectContentUntil: header/200",
499
- "client -> server | LOAD Map sessions: header/200",
500
- "storage -> client | CONTENT Map header: true new: After: 73 New: 73",
501
- "storage -> client | CONTENT Map header: true new: After: 146 New: 54",
509
+ "storage -> client | CONTENT Map header: true new: After: 0 New: 1 expectContentUntil: header/10",
510
+ "client -> server | LOAD Map sessions: header/10",
511
+ "storage -> client | CONTENT Map header: true new: After: 1 New: 1",
512
+ "storage -> client | CONTENT Map header: true new: After: 2 New: 1",
513
+ "storage -> client | CONTENT Map header: true new: After: 3 New: 1",
514
+ "storage -> client | CONTENT Map header: true new: After: 4 New: 1",
515
+ "storage -> client | CONTENT Map header: true new: After: 5 New: 1",
516
+ "storage -> client | CONTENT Map header: true new: After: 6 New: 1",
517
+ "storage -> client | CONTENT Map header: true new: After: 7 New: 1",
518
+ "storage -> client | CONTENT Map header: true new: After: 8 New: 1",
519
+ "storage -> client | CONTENT Map header: true new: After: 9 New: 1",
520
+ "storage -> client | CONTENT Map header: true new: After: 10 New: 0",
502
521
  "server -> storage | LOAD Group sessions: empty",
503
522
  "storage -> server | CONTENT Group header: true new: After: 0 New: 5",
504
523
  "server -> client | KNOWN Group sessions: header/5",
505
524
  "server -> storage | LOAD Map sessions: empty",
506
- "storage -> server | CONTENT Map header: true new: After: 0 New: 73 expectContentUntil: header/200",
507
- "server -> client | KNOWN Map sessions: header/200",
525
+ "storage -> server | CONTENT Map header: true new: After: 0 New: 1 expectContentUntil: header/10",
526
+ "server -> client | KNOWN Map sessions: header/10",
508
527
  ]
509
528
  `);
510
529
  });
530
+
531
+ test("two storage instances open on the same file should not conflict with each other", async () => {
532
+ const client = setupTestNode();
533
+
534
+ client.connectToSyncServer({
535
+ syncServer: jazzCloud.node,
536
+ });
537
+ const dbPath = getDbPath();
538
+ await client.addAsyncStorage({
539
+ ourName: "client",
540
+ filename: dbPath,
541
+ });
542
+
543
+ const client2 = setupTestNode();
544
+ client2.connectToSyncServer({
545
+ syncServer: jazzCloud.node,
546
+ });
547
+ await client2.addAsyncStorage({
548
+ ourName: "client2",
549
+ filename: dbPath,
550
+ });
551
+
552
+ for (let i = 0; i < 10; i++) {
553
+ for (const node of [client.node, client2.node]) {
554
+ const group = node.createGroup();
555
+ const map = group.createMap();
556
+ map.set("hello", "world", "trusting");
557
+ }
558
+ }
559
+
560
+ await client.node.syncManager.waitForAllCoValuesSync();
561
+ await client2.node.syncManager.waitForAllCoValuesSync();
562
+ });
511
563
  });
@@ -95,7 +95,11 @@ export async function createAsyncStorage({
95
95
  filename,
96
96
  nodeName = "client",
97
97
  storageName = "storage",
98
- }: { filename?: string; nodeName: string; storageName: string }) {
98
+ }: {
99
+ filename?: string;
100
+ nodeName: string;
101
+ storageName: string;
102
+ }) {
99
103
  const storage = await getSqliteStorageAsync(
100
104
  new LibSQLSqliteAsyncDriver(getDbPath(filename)),
101
105
  );
@@ -113,7 +117,11 @@ export function createSyncStorage({
113
117
  filename,
114
118
  nodeName = "client",
115
119
  storageName = "storage",
116
- }: { filename?: string; nodeName: string; storageName: string }) {
120
+ }: {
121
+ filename?: string;
122
+ nodeName: string;
123
+ storageName: string;
124
+ }) {
117
125
  const storage = getSqliteStorage(
118
126
  new LibSQLSqliteSyncDriver(getDbPath(filename)),
119
127
  );
@@ -123,7 +131,7 @@ export function createSyncStorage({
123
131
  return storage;
124
132
  }
125
133
 
126
- function getDbPath(defaultDbPath?: string) {
134
+ export function getDbPath(defaultDbPath?: string) {
127
135
  const dbPath = defaultDbPath ?? join(tmpdir(), `test-${randomUUID()}.db`);
128
136
 
129
137
  if (!defaultDbPath) {
@@ -530,10 +530,13 @@ export function setupTestNode(
530
530
  return { storage };
531
531
  }
532
532
 
533
- async function addAsyncStorage(opts: { ourName?: string } = {}) {
533
+ async function addAsyncStorage(
534
+ opts: { ourName?: string; filename?: string } = {},
535
+ ) {
534
536
  const storage = await createAsyncStorage({
535
537
  nodeName: opts.ourName ?? "client",
536
538
  storageName: "storage",
539
+ filename: opts.filename,
537
540
  });
538
541
  node.setStorage(storage);
539
542