cojson 0.20.9 → 0.20.10

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 (169) hide show
  1. package/.turbo/turbo-build.log +1 -1
  2. package/CHANGELOG.md +20 -0
  3. package/dist/PeerState.d.ts +2 -2
  4. package/dist/PeerState.d.ts.map +1 -1
  5. package/dist/PeerState.js +3 -3
  6. package/dist/PeerState.js.map +1 -1
  7. package/dist/StorageReconciliationAckTracker.d.ts +14 -0
  8. package/dist/StorageReconciliationAckTracker.d.ts.map +1 -0
  9. package/dist/StorageReconciliationAckTracker.js +72 -0
  10. package/dist/StorageReconciliationAckTracker.js.map +1 -0
  11. package/dist/SyncStateManager.js +2 -2
  12. package/dist/SyncStateManager.js.map +1 -1
  13. package/dist/coValueCore/coValueCore.d.ts +2 -1
  14. package/dist/coValueCore/coValueCore.d.ts.map +1 -1
  15. package/dist/coValueCore/coValueCore.js +43 -10
  16. package/dist/coValueCore/coValueCore.js.map +1 -1
  17. package/dist/coValues/coList.d.ts +2 -0
  18. package/dist/coValues/coList.d.ts.map +1 -1
  19. package/dist/coValues/coList.js +28 -0
  20. package/dist/coValues/coList.js.map +1 -1
  21. package/dist/coValues/group.d.ts +4 -1
  22. package/dist/coValues/group.d.ts.map +1 -1
  23. package/dist/coValues/group.js +15 -1
  24. package/dist/coValues/group.js.map +1 -1
  25. package/dist/config.d.ts +8 -0
  26. package/dist/config.d.ts.map +1 -1
  27. package/dist/config.js +14 -0
  28. package/dist/config.js.map +1 -1
  29. package/dist/exports.d.ts +9 -1
  30. package/dist/exports.d.ts.map +1 -1
  31. package/dist/exports.js +5 -1
  32. package/dist/exports.js.map +1 -1
  33. package/dist/localNode.d.ts +7 -3
  34. package/dist/localNode.d.ts.map +1 -1
  35. package/dist/localNode.js +13 -5
  36. package/dist/localNode.js.map +1 -1
  37. package/dist/permissions.d.ts +1 -0
  38. package/dist/permissions.d.ts.map +1 -1
  39. package/dist/queue/LinkedList.d.ts +2 -0
  40. package/dist/queue/LinkedList.d.ts.map +1 -1
  41. package/dist/queue/LinkedList.js +7 -0
  42. package/dist/queue/LinkedList.js.map +1 -1
  43. package/dist/queue/OutgoingLoadQueue.d.ts +4 -1
  44. package/dist/queue/OutgoingLoadQueue.d.ts.map +1 -1
  45. package/dist/queue/OutgoingLoadQueue.js +41 -13
  46. package/dist/queue/OutgoingLoadQueue.js.map +1 -1
  47. package/dist/queue/PriorityBasedMessageQueue.d.ts +1 -0
  48. package/dist/queue/PriorityBasedMessageQueue.d.ts.map +1 -1
  49. package/dist/queue/PriorityBasedMessageQueue.js +11 -1
  50. package/dist/queue/PriorityBasedMessageQueue.js.map +1 -1
  51. package/dist/storage/knownState.d.ts +2 -0
  52. package/dist/storage/knownState.d.ts.map +1 -1
  53. package/dist/storage/knownState.js +11 -0
  54. package/dist/storage/knownState.js.map +1 -1
  55. package/dist/storage/sqlite/client.d.ts +10 -1
  56. package/dist/storage/sqlite/client.d.ts.map +1 -1
  57. package/dist/storage/sqlite/client.js +84 -0
  58. package/dist/storage/sqlite/client.js.map +1 -1
  59. package/dist/storage/sqlite/sqliteMigrations.d.ts.map +1 -1
  60. package/dist/storage/sqlite/sqliteMigrations.js +11 -0
  61. package/dist/storage/sqlite/sqliteMigrations.js.map +1 -1
  62. package/dist/storage/sqliteAsync/client.d.ts +10 -1
  63. package/dist/storage/sqliteAsync/client.d.ts.map +1 -1
  64. package/dist/storage/sqliteAsync/client.js +86 -0
  65. package/dist/storage/sqliteAsync/client.js.map +1 -1
  66. package/dist/storage/storageAsync.d.ts +9 -2
  67. package/dist/storage/storageAsync.d.ts.map +1 -1
  68. package/dist/storage/storageAsync.js +19 -0
  69. package/dist/storage/storageAsync.js.map +1 -1
  70. package/dist/storage/storageSync.d.ts +9 -2
  71. package/dist/storage/storageSync.d.ts.map +1 -1
  72. package/dist/storage/storageSync.js +20 -13
  73. package/dist/storage/storageSync.js.map +1 -1
  74. package/dist/storage/types.d.ts +64 -0
  75. package/dist/storage/types.d.ts.map +1 -1
  76. package/dist/storage/types.js.map +1 -1
  77. package/dist/sync.d.ts +44 -2
  78. package/dist/sync.d.ts.map +1 -1
  79. package/dist/sync.js +268 -44
  80. package/dist/sync.js.map +1 -1
  81. package/dist/tests/OutgoingLoadQueue.test.js +137 -39
  82. package/dist/tests/OutgoingLoadQueue.test.js.map +1 -1
  83. package/dist/tests/SQLiteClientAsync.test.js +1 -1
  84. package/dist/tests/SQLiteClientAsync.test.js.map +1 -1
  85. package/dist/tests/StorageApiAsync.test.js +138 -0
  86. package/dist/tests/StorageApiAsync.test.js.map +1 -1
  87. package/dist/tests/StorageApiSync.test.js +154 -0
  88. package/dist/tests/StorageApiSync.test.js.map +1 -1
  89. package/dist/tests/StorageReconciliationAckTracker.test.d.ts +2 -0
  90. package/dist/tests/StorageReconciliationAckTracker.test.d.ts.map +1 -0
  91. package/dist/tests/StorageReconciliationAckTracker.test.js +74 -0
  92. package/dist/tests/StorageReconciliationAckTracker.test.js.map +1 -0
  93. package/dist/tests/SyncStateManager.test.js +18 -0
  94. package/dist/tests/SyncStateManager.test.js.map +1 -1
  95. package/dist/tests/coList.test.js +112 -1
  96. package/dist/tests/coList.test.js.map +1 -1
  97. package/dist/tests/coValueCore.loadFromStorage.test.js +36 -0
  98. package/dist/tests/coValueCore.loadFromStorage.test.js.map +1 -1
  99. package/dist/tests/group.test.js +44 -0
  100. package/dist/tests/group.test.js.map +1 -1
  101. package/dist/tests/knownState.lazyLoading.test.js +6 -0
  102. package/dist/tests/knownState.lazyLoading.test.js.map +1 -1
  103. package/dist/tests/messagesTestUtils.d.ts.map +1 -1
  104. package/dist/tests/messagesTestUtils.js +4 -0
  105. package/dist/tests/messagesTestUtils.js.map +1 -1
  106. package/dist/tests/sync.concurrentLoad.test.js +333 -1
  107. package/dist/tests/sync.concurrentLoad.test.js.map +1 -1
  108. package/dist/tests/sync.garbageCollection.test.js +4 -0
  109. package/dist/tests/sync.garbageCollection.test.js.map +1 -1
  110. package/dist/tests/sync.load.test.js +19 -0
  111. package/dist/tests/sync.load.test.js.map +1 -1
  112. package/dist/tests/sync.mesh.test.js +1 -0
  113. package/dist/tests/sync.mesh.test.js.map +1 -1
  114. package/dist/tests/sync.multipleServers.test.js +41 -3
  115. package/dist/tests/sync.multipleServers.test.js.map +1 -1
  116. package/dist/tests/sync.storage.test.js +2 -0
  117. package/dist/tests/sync.storage.test.js.map +1 -1
  118. package/dist/tests/sync.storageAsync.test.js +1 -0
  119. package/dist/tests/sync.storageAsync.test.js.map +1 -1
  120. package/dist/tests/sync.storageReconciliation.test.d.ts +2 -0
  121. package/dist/tests/sync.storageReconciliation.test.d.ts.map +1 -0
  122. package/dist/tests/sync.storageReconciliation.test.js +501 -0
  123. package/dist/tests/sync.storageReconciliation.test.js.map +1 -0
  124. package/dist/tests/testUtils.d.ts +1 -0
  125. package/dist/tests/testUtils.d.ts.map +1 -1
  126. package/dist/tests/testUtils.js +3 -2
  127. package/dist/tests/testUtils.js.map +1 -1
  128. package/package.json +4 -4
  129. package/src/PeerState.ts +10 -3
  130. package/src/StorageReconciliationAckTracker.ts +83 -0
  131. package/src/SyncStateManager.ts +3 -3
  132. package/src/coValueCore/coValueCore.ts +47 -16
  133. package/src/coValues/coList.ts +23 -0
  134. package/src/coValues/group.ts +18 -0
  135. package/src/config.ts +18 -0
  136. package/src/exports.ts +8 -0
  137. package/src/localNode.ts +18 -0
  138. package/src/permissions.ts +1 -1
  139. package/src/queue/LinkedList.ts +10 -0
  140. package/src/queue/OutgoingLoadQueue.ts +57 -15
  141. package/src/queue/PriorityBasedMessageQueue.ts +15 -1
  142. package/src/storage/knownState.ts +14 -0
  143. package/src/storage/sqlite/client.ts +128 -0
  144. package/src/storage/sqlite/sqliteMigrations.ts +11 -0
  145. package/src/storage/sqliteAsync/client.ts +139 -0
  146. package/src/storage/storageAsync.ts +37 -0
  147. package/src/storage/storageSync.ts +41 -16
  148. package/src/storage/types.ts +110 -0
  149. package/src/sync.ts +311 -14
  150. package/src/tests/OutgoingLoadQueue.test.ts +226 -59
  151. package/src/tests/SQLiteClientAsync.test.ts +1 -1
  152. package/src/tests/StorageApiAsync.test.ts +161 -1
  153. package/src/tests/StorageApiSync.test.ts +176 -0
  154. package/src/tests/StorageReconciliationAckTracker.test.ts +99 -0
  155. package/src/tests/SyncStateManager.test.ts +25 -0
  156. package/src/tests/coList.test.ts +138 -0
  157. package/src/tests/coValueCore.loadFromStorage.test.ts +72 -1
  158. package/src/tests/group.test.ts +87 -0
  159. package/src/tests/knownState.lazyLoading.test.ts +36 -1
  160. package/src/tests/messagesTestUtils.ts +4 -0
  161. package/src/tests/sync.concurrentLoad.test.ts +491 -0
  162. package/src/tests/sync.garbageCollection.test.ts +4 -0
  163. package/src/tests/sync.load.test.ts +26 -0
  164. package/src/tests/sync.mesh.test.ts +1 -0
  165. package/src/tests/sync.multipleServers.test.ts +60 -2
  166. package/src/tests/sync.storage.test.ts +2 -0
  167. package/src/tests/sync.storageAsync.test.ts +1 -0
  168. package/src/tests/sync.storageReconciliation.test.ts +697 -0
  169. package/src/tests/testUtils.ts +10 -1
@@ -0,0 +1,501 @@
1
+ import { beforeEach, describe, expect, test } from "vitest";
2
+ import { cojsonInternals, } from "../exports";
3
+ import { SyncMessagesLog, TEST_NODE_CONFIG, setupTestNode, waitFor, } from "./testUtils";
4
+ import { setStorageReconciliationBatchSize, setStorageReconciliationInterval, setStorageReconciliationLockTTL, STORAGE_RECONCILIATION_CONFIG, } from "../config";
5
+ // We want to simulate a real world communication that happens asynchronously
6
+ TEST_NODE_CONFIG.withAsyncPeers = true;
7
+ let jazzCloud;
8
+ const originalBatchSize = STORAGE_RECONCILIATION_CONFIG.BATCH_SIZE;
9
+ const originalLockTTL = STORAGE_RECONCILIATION_CONFIG.LOCK_TTL_MS;
10
+ const originalInterval = STORAGE_RECONCILIATION_CONFIG.RECONCILIATION_INTERVAL_MS;
11
+ beforeEach(async () => {
12
+ SyncMessagesLog.clear();
13
+ jazzCloud = setupTestNode({ isSyncServer: true });
14
+ setStorageReconciliationBatchSize(originalBatchSize);
15
+ setStorageReconciliationLockTTL(originalLockTTL);
16
+ setStorageReconciliationInterval(originalInterval);
17
+ });
18
+ describe("full storage reconciliation", () => {
19
+ test("startStorageReconciliation sends 'reconcile' message, server responds with 'known' messages for missing CoValues", async () => {
20
+ const client = setupTestNode();
21
+ const { storage } = client.addStorage();
22
+ const group = client.node.createGroup();
23
+ const map = group.createMap();
24
+ map.set("hello", "world", "trusting");
25
+ await map.core.waitForSync();
26
+ const anotherClient = setupTestNode();
27
+ anotherClient.addStorage({ storage });
28
+ anotherClient.connectToSyncServer({
29
+ persistent: true,
30
+ skipReconciliation: true,
31
+ });
32
+ SyncMessagesLog.clear();
33
+ const serverPeer = Object.values(anotherClient.node.syncManager.peers).find((p) => p.role === "server" && p.persistent);
34
+ anotherClient.node.syncManager.startStorageReconciliation(serverPeer);
35
+ await waitForStorageReconciliationBatchAck(anotherClient.node);
36
+ const messages = SyncMessagesLog.getMessages({
37
+ Group: group.core,
38
+ Map: map.core,
39
+ });
40
+ expect(messages).toMatchInlineSnapshot(`
41
+ [
42
+ "client -> storage | GET_KNOWN_STATE Group",
43
+ "storage -> client | GET_KNOWN_STATE_RESULT Group sessions: header/4",
44
+ "client -> storage | GET_KNOWN_STATE Map",
45
+ "storage -> client | GET_KNOWN_STATE_RESULT Map sessions: header/1",
46
+ "client -> server | RECONCILE",
47
+ "server -> client | LOAD Group sessions: empty",
48
+ "server -> client | LOAD Map sessions: empty",
49
+ "server -> client | RECONCILE_ACK",
50
+ "client -> storage | LOAD Group sessions: empty",
51
+ "storage -> client | CONTENT Group header: true new: After: 0 New: 4",
52
+ "client -> server | CONTENT Group header: true new: After: 0 New: 4",
53
+ "client -> server | KNOWN Group sessions: header/4",
54
+ "client -> storage | LOAD Map sessions: empty",
55
+ "storage -> client | CONTENT Map header: true new: After: 0 New: 1",
56
+ "client -> server | CONTENT Map header: true new: After: 0 New: 1",
57
+ "client -> server | KNOWN Map sessions: header/1",
58
+ "server -> client | KNOWN Group sessions: header/4",
59
+ "server -> client | KNOWN Map sessions: header/1",
60
+ ]
61
+ `);
62
+ });
63
+ test("startStorageReconciliation sends 'reconcile' message, server responds with 'known' messages for outdated CoValues", async () => {
64
+ const client = setupTestNode();
65
+ const { storage } = client.addStorage();
66
+ client.connectToSyncServer({ persistent: true });
67
+ const group = client.node.createGroup();
68
+ const map = group.createMap();
69
+ map.set("hello", "world", "trusting");
70
+ await map.core.waitForSync();
71
+ map.set("hello", "world2", "trusting");
72
+ // Restart the client before the latest change is synced to the sync server
73
+ await client.restart();
74
+ client.addStorage({ storage });
75
+ client.connectToSyncServer({ persistent: true, skipReconciliation: true });
76
+ SyncMessagesLog.clear();
77
+ const serverPeer = Object.values(client.node.syncManager.peers).find((p) => p.role === "server" && p.persistent);
78
+ client.node.syncManager.startStorageReconciliation(serverPeer);
79
+ await waitForStorageReconciliationBatchAck(client.node);
80
+ const messages = SyncMessagesLog.getMessages({
81
+ Group: group.core,
82
+ Map: map.core,
83
+ });
84
+ expect(messages).toMatchInlineSnapshot(`
85
+ [
86
+ "client -> storage | GET_KNOWN_STATE Group",
87
+ "storage -> client | GET_KNOWN_STATE_RESULT Group sessions: header/4",
88
+ "client -> storage | GET_KNOWN_STATE Map",
89
+ "storage -> client | GET_KNOWN_STATE_RESULT Map sessions: header/2",
90
+ "client -> server | RECONCILE",
91
+ "server -> client | LOAD Map sessions: header/1",
92
+ "server -> client | RECONCILE_ACK",
93
+ "client -> storage | GET_KNOWN_STATE Map",
94
+ "storage -> client | GET_KNOWN_STATE_RESULT Map sessions: header/2",
95
+ "client -> storage | LOAD Map sessions: empty",
96
+ "storage -> client | CONTENT Group header: true new: After: 0 New: 4",
97
+ "client -> server | LOAD Group sessions: header/4",
98
+ "storage -> client | CONTENT Map header: true new: After: 0 New: 2",
99
+ "client -> server | CONTENT Map header: false new: After: 1 New: 1",
100
+ "client -> server | KNOWN Map sessions: header/2",
101
+ "server -> client | KNOWN Group sessions: header/4",
102
+ "server -> client | KNOWN Map sessions: header/2",
103
+ ]
104
+ `);
105
+ });
106
+ test("pendingReconciliationAck is cleared when 'reconcile-ack' is received", async () => {
107
+ const client = setupTestNode();
108
+ const { storage } = client.addStorage();
109
+ const group = client.node.createGroup();
110
+ const map = group.createMap();
111
+ map.set("hello", "world", "trusting");
112
+ await map.core.waitForSync();
113
+ const anotherClient = setupTestNode();
114
+ anotherClient.addStorage({ storage });
115
+ anotherClient.connectToSyncServer({
116
+ persistent: true,
117
+ skipReconciliation: true,
118
+ });
119
+ const serverPeer = Object.values(anotherClient.node.syncManager.peers).find((p) => p.role === "server" && p.persistent);
120
+ anotherClient.node.syncManager.startStorageReconciliation(serverPeer);
121
+ expect(anotherClient.node.syncManager.pendingReconciliationAck.size).toBeGreaterThan(0);
122
+ await waitFor(() => anotherClient.node.syncManager.pendingReconciliationAck.size === 0);
123
+ });
124
+ test("in-memory CoValues are not reconciled", async () => {
125
+ const client = setupTestNode();
126
+ const { storage } = client.addStorage();
127
+ const group = client.node.createGroup();
128
+ const map = group.createMap();
129
+ map.set("hello", "world", "trusting");
130
+ await map.core.waitForSync();
131
+ const anotherClient = setupTestNode();
132
+ anotherClient.addStorage({ storage });
133
+ anotherClient.connectToSyncServer({
134
+ persistent: true,
135
+ skipReconciliation: true,
136
+ });
137
+ const group2 = anotherClient.node.createGroup();
138
+ const map2 = group2.createMap();
139
+ map2.set("hello2", "world2", "trusting");
140
+ await map2.core.waitForSync();
141
+ SyncMessagesLog.clear();
142
+ const serverPeer = Object.values(anotherClient.node.syncManager.peers).find((p) => p.role === "server" && p.persistent);
143
+ anotherClient.node.syncManager.startStorageReconciliation(serverPeer);
144
+ await waitForStorageReconciliationBatchAck(anotherClient.node);
145
+ const messages = SyncMessagesLog.getMessages({
146
+ Group: group.core,
147
+ Map: map.core,
148
+ });
149
+ // In-memory CoValues are skipped
150
+ expect(messages).toMatchInlineSnapshot(`
151
+ [
152
+ "client -> storage | GET_KNOWN_STATE Group",
153
+ "storage -> client | GET_KNOWN_STATE_RESULT Group sessions: header/4",
154
+ "client -> storage | GET_KNOWN_STATE Map",
155
+ "storage -> client | GET_KNOWN_STATE_RESULT Map sessions: header/1",
156
+ "client -> server | RECONCILE",
157
+ "server -> client | LOAD Group sessions: empty",
158
+ "server -> client | LOAD Map sessions: empty",
159
+ "server -> client | RECONCILE_ACK",
160
+ "client -> storage | LOAD Group sessions: empty",
161
+ "storage -> client | CONTENT Group header: true new: After: 0 New: 4",
162
+ "client -> server | CONTENT Group header: true new: After: 0 New: 4",
163
+ "client -> server | KNOWN Group sessions: header/4",
164
+ "client -> storage | LOAD Map sessions: empty",
165
+ "storage -> client | CONTENT Map header: true new: After: 0 New: 1",
166
+ "client -> server | CONTENT Map header: true new: After: 0 New: 1",
167
+ "client -> server | KNOWN Map sessions: header/1",
168
+ "server -> client | KNOWN Group sessions: header/4",
169
+ "server -> client | KNOWN Map sessions: header/1",
170
+ ]
171
+ `);
172
+ });
173
+ test("'reconcile' message is not sent if there are no CoValues to reconcile", async () => {
174
+ const client = setupTestNode({ connected: true });
175
+ client.addStorage();
176
+ const group = client.node.createGroup();
177
+ const map = group.createMap();
178
+ map.set("hello", "world", "trusting");
179
+ await map.core.waitForSync();
180
+ SyncMessagesLog.clear();
181
+ // CoValue is in memory, so it will be skipped
182
+ const serverPeer = Object.values(client.node.syncManager.peers).find((p) => p.role === "server" && p.persistent);
183
+ client.node.syncManager.startStorageReconciliation(serverPeer);
184
+ // Wait for reconciliation to complete
185
+ await new Promise((resolve) => setTimeout(resolve, 100));
186
+ expect(client.node.syncManager.pendingReconciliationAck.size).toEqual(0);
187
+ const messages = SyncMessagesLog.getMessages({
188
+ Group: group.core,
189
+ Map: map.core,
190
+ });
191
+ expect(messages).toMatchInlineSnapshot(`[]`);
192
+ });
193
+ test("sends reconcile messages for each batch, waits for reconcile-ack, then sends next batch", async () => {
194
+ setStorageReconciliationBatchSize(2);
195
+ const client = setupTestNode();
196
+ client.connectToSyncServer({ persistent: true });
197
+ const { storage } = client.addStorage();
198
+ const group = client.node.createGroup();
199
+ const maps = [];
200
+ for (let i = 0; i < 4; i++) {
201
+ const m = group.createMap();
202
+ m.set("i", i, "trusting");
203
+ maps.push(m);
204
+ }
205
+ await Promise.all(maps.map((m) => m.core.waitForSync()));
206
+ SyncMessagesLog.clear();
207
+ const anotherClient = setupTestNode();
208
+ anotherClient.connectToSyncServer({ persistent: true });
209
+ anotherClient.addStorage({ storage });
210
+ const serverPeer = Object.values(anotherClient.node.syncManager.peers).find((p) => p.role === "server" && p.persistent);
211
+ await new Promise((resolve) => anotherClient.node.syncManager.startStorageReconciliation(serverPeer, 0, resolve));
212
+ const coValueMapping = Object.fromEntries([
213
+ ["Group", group.core],
214
+ ...maps.map((m, i) => [`Map${i}`, m.core]),
215
+ ]);
216
+ const messages = SyncMessagesLog.getMessages(coValueMapping);
217
+ expect(messages).toMatchInlineSnapshot(`
218
+ [
219
+ "client -> storage | GET_KNOWN_STATE Group",
220
+ "storage -> client | GET_KNOWN_STATE_RESULT Group sessions: header/4",
221
+ "client -> storage | GET_KNOWN_STATE Map0",
222
+ "storage -> client | GET_KNOWN_STATE_RESULT Map0 sessions: header/1",
223
+ "client -> server | RECONCILE",
224
+ "server -> client | RECONCILE_ACK",
225
+ "client -> storage | GET_KNOWN_STATE Map1",
226
+ "storage -> client | GET_KNOWN_STATE_RESULT Map1 sessions: header/1",
227
+ "client -> storage | GET_KNOWN_STATE Map2",
228
+ "storage -> client | GET_KNOWN_STATE_RESULT Map2 sessions: header/1",
229
+ "client -> server | RECONCILE",
230
+ "server -> client | RECONCILE_ACK",
231
+ "client -> storage | GET_KNOWN_STATE Map3",
232
+ "storage -> client | GET_KNOWN_STATE_RESULT Map3 sessions: header/1",
233
+ "client -> server | RECONCILE",
234
+ "server -> client | RECONCILE_ACK",
235
+ ]
236
+ `);
237
+ });
238
+ test("aborts reconciliation when peer disconnects during wait for reconcile-ack", async () => {
239
+ const client = setupTestNode();
240
+ const { storage } = client.addStorage();
241
+ const group = client.node.createGroup();
242
+ const map = group.createMap();
243
+ map.set("hello", "world", "trusting");
244
+ await map.core.waitForSync();
245
+ const anotherClient = setupTestNode();
246
+ anotherClient.addStorage({ storage });
247
+ anotherClient.connectToSyncServer({
248
+ persistent: true,
249
+ skipReconciliation: true,
250
+ });
251
+ const serverPeer = Object.values(anotherClient.node.syncManager.peers).find((p) => p.role === "server" && p.persistent);
252
+ let reconciliationFinished = false;
253
+ anotherClient.node.syncManager.startStorageReconciliation(serverPeer, 0, () => {
254
+ reconciliationFinished = true;
255
+ });
256
+ // Prevent "reconcile" message from being processed so that client stays in "waiting" state
257
+ const { promise, resolve } = Promise.withResolvers();
258
+ const syncManager = jazzCloud.node.syncManager;
259
+ syncManager.handleReconcile = () => {
260
+ resolve();
261
+ };
262
+ await promise;
263
+ anotherClient.disconnect();
264
+ // Reconciliation should abort (peer closed) without hanging
265
+ // and clear the pending reconciliation ack
266
+ await waitFor(() => anotherClient.node.syncManager.pendingReconciliationAck.size === 0);
267
+ // onComplete should NOT have been called (we aborted, did not complete)
268
+ expect(reconciliationFinished).toBe(false);
269
+ });
270
+ describe("scheduling", () => {
271
+ test("full storage reconciliation is not run if not enabled", async () => {
272
+ const client = setupTestNode();
273
+ const { storage } = client.addStorage();
274
+ client.connectToSyncServer({ persistent: true });
275
+ const group = client.node.createGroup();
276
+ const map = group.createMap();
277
+ map.set("hello", "world", "trusting");
278
+ await map.core.waitForSync();
279
+ SyncMessagesLog.clear();
280
+ const anotherClient = setupTestNode();
281
+ anotherClient.addStorage({ storage });
282
+ anotherClient.connectToSyncServer({ persistent: true });
283
+ await new Promise((resolve) => setTimeout(resolve, 100));
284
+ const messages = SyncMessagesLog.getMessages({
285
+ Group: group.core,
286
+ Map: map.core,
287
+ });
288
+ expect(messages).toMatchInlineSnapshot(`[]`);
289
+ });
290
+ test("full storage reconciliation is run when adding a new persistent server peer", async () => {
291
+ const client = setupTestNode({ enableFullStorageReconciliation: true });
292
+ const { storage } = client.addStorage();
293
+ const group = client.node.createGroup();
294
+ const map = group.createMap();
295
+ map.set("hello", "world", "trusting");
296
+ await map.core.waitForSync();
297
+ const anotherClient = setupTestNode({
298
+ enableFullStorageReconciliation: true,
299
+ });
300
+ anotherClient.addStorage({ storage });
301
+ SyncMessagesLog.clear();
302
+ // Connecting to the sync server will trigger a full storage reconciliation
303
+ anotherClient.connectToSyncServer({
304
+ persistent: true,
305
+ });
306
+ await waitForStorageReconciliationBatchAck(anotherClient.node);
307
+ const messages = SyncMessagesLog.getMessages({
308
+ Group: group.core,
309
+ Map: map.core,
310
+ });
311
+ expect(messages).toMatchInlineSnapshot(`
312
+ [
313
+ "client -> storage | GET_KNOWN_STATE Group",
314
+ "storage -> client | GET_KNOWN_STATE_RESULT Group sessions: header/4",
315
+ "client -> storage | GET_KNOWN_STATE Map",
316
+ "storage -> client | GET_KNOWN_STATE_RESULT Map sessions: header/1",
317
+ "client -> server | RECONCILE",
318
+ "server -> client | LOAD Group sessions: empty",
319
+ "server -> client | LOAD Map sessions: empty",
320
+ "server -> client | RECONCILE_ACK",
321
+ "client -> storage | LOAD Group sessions: empty",
322
+ "storage -> client | CONTENT Group header: true new: After: 0 New: 4",
323
+ "client -> server | CONTENT Group header: true new: After: 0 New: 4",
324
+ "client -> server | KNOWN Group sessions: header/4",
325
+ "client -> storage | LOAD Map sessions: empty",
326
+ "storage -> client | CONTENT Map header: true new: After: 0 New: 1",
327
+ "client -> server | CONTENT Map header: true new: After: 0 New: 1",
328
+ "client -> server | KNOWN Map sessions: header/1",
329
+ "server -> client | KNOWN Group sessions: header/4",
330
+ "server -> client | KNOWN Map sessions: header/1",
331
+ ]
332
+ `);
333
+ });
334
+ test("reconciliation is not run again until the reconciliation interval passed", async () => {
335
+ const client = setupTestNode({ enableFullStorageReconciliation: true });
336
+ const { storage } = client.addStorage();
337
+ // Connecting to the sync server triggers full storage reconciliation
338
+ const { peer } = client.connectToSyncServer({ persistent: true });
339
+ const group = client.node.createGroup();
340
+ await group.core.waitForSync();
341
+ const storageReconciliationLock = await new Promise((resolve) => storage.tryAcquireStorageReconciliationLock(client.node.currentSessionID, peer.id, resolve));
342
+ expect(storageReconciliationLock.acquired).toBe(false);
343
+ if (!storageReconciliationLock.acquired) {
344
+ expect(storageReconciliationLock.reason).toBe("not_due");
345
+ }
346
+ const anotherClient = setupTestNode({
347
+ enableFullStorageReconciliation: true,
348
+ });
349
+ anotherClient.addStorage({ storage });
350
+ SyncMessagesLog.clear();
351
+ // Since the previous storage reconciliation was run, no other will be run for 30 days
352
+ anotherClient.connectToSyncServer({ persistent: true });
353
+ await new Promise((resolve) => setTimeout(resolve, 100));
354
+ const messages = SyncMessagesLog.getMessages({
355
+ Group: group.core,
356
+ });
357
+ expect(messages).toMatchInlineSnapshot(`[]`);
358
+ });
359
+ test("reconciliation is run for the same peer after reconciliation interval passes", async () => {
360
+ cojsonInternals.setStorageReconciliationInterval(100);
361
+ const client = setupTestNode({ enableFullStorageReconciliation: true });
362
+ const { storage } = client.addStorage();
363
+ // Connecting to the sync server triggers full storage reconciliation
364
+ client.connectToSyncServer({ persistent: true });
365
+ const group = client.node.createGroup();
366
+ await group.core.waitForSync();
367
+ // Wait for the next reconciliation window to start
368
+ await new Promise((resolve) => setTimeout(resolve, 200));
369
+ const anotherClient = setupTestNode({
370
+ enableFullStorageReconciliation: true,
371
+ });
372
+ anotherClient.addStorage({ storage });
373
+ SyncMessagesLog.clear();
374
+ // Runs storage reconciliation again
375
+ anotherClient.connectToSyncServer({ persistent: true });
376
+ await waitForStorageReconciliationBatchAck(anotherClient.node);
377
+ const messages = SyncMessagesLog.getMessages({
378
+ Group: group.core,
379
+ });
380
+ expect(messages).toMatchInlineSnapshot(`
381
+ [
382
+ "client -> storage | GET_KNOWN_STATE Group",
383
+ "storage -> client | GET_KNOWN_STATE_RESULT Group sessions: header/4",
384
+ "client -> server | RECONCILE",
385
+ "server -> client | RECONCILE_ACK",
386
+ ]
387
+ `);
388
+ });
389
+ test("if reconciliation is interrupted, it is not run again until the lock TTL expires", async () => {
390
+ cojsonInternals.setStorageReconciliationInterval(0);
391
+ cojsonInternals.setStorageReconciliationLockTTL(100);
392
+ let client = setupTestNode({ enableFullStorageReconciliation: true });
393
+ const { storage } = client.addStorage();
394
+ client.connectToSyncServer({ persistent: true });
395
+ const group = client.node.createGroup();
396
+ await group.core.waitForSync();
397
+ await client.node.gracefulShutdown();
398
+ client = setupTestNode({ enableFullStorageReconciliation: true });
399
+ client.addStorage({ storage });
400
+ // Connecting to the sync server triggers full storage reconciliation
401
+ const { peer } = client.connectToSyncServer({ persistent: true });
402
+ // Kill the node before the reconciliation completes
403
+ await client.node.gracefulShutdown();
404
+ // Try to acquire the lock in another session, fails because the lock is held by the previous node
405
+ const storageReconciliationLock = await new Promise((resolve) => storage.tryAcquireStorageReconciliationLock("another-session-id", peer.id, resolve));
406
+ expect(storageReconciliationLock.acquired).toBe(false);
407
+ if (!storageReconciliationLock.acquired) {
408
+ expect(storageReconciliationLock.reason).toBe("lock_held");
409
+ }
410
+ // Wait for the lock to expire
411
+ await new Promise((resolve) => setTimeout(resolve, 200));
412
+ client = setupTestNode({ enableFullStorageReconciliation: true });
413
+ client.addStorage({ storage });
414
+ SyncMessagesLog.clear();
415
+ // Runs storage reconciliation again
416
+ client.connectToSyncServer({ persistent: true });
417
+ await new Promise((resolve) => setTimeout(resolve, 100));
418
+ const messages = SyncMessagesLog.getMessages({
419
+ Group: group.core,
420
+ });
421
+ expect(messages).toMatchInlineSnapshot(`
422
+ [
423
+ "client -> storage | GET_KNOWN_STATE Group",
424
+ "storage -> client | GET_KNOWN_STATE_RESULT Group sessions: header/4",
425
+ "client -> server | RECONCILE",
426
+ "server -> client | RECONCILE_ACK",
427
+ ]
428
+ `);
429
+ });
430
+ test("after interrupted run, next acquire returns lastProcessedOffset and reconciliation resumes from that offset", async () => {
431
+ setStorageReconciliationBatchSize(1);
432
+ setStorageReconciliationLockTTL(100);
433
+ setStorageReconciliationInterval(200);
434
+ const client = setupTestNode({ enableFullStorageReconciliation: true });
435
+ const { storage } = client.addStorage();
436
+ const { peer } = client.connectToSyncServer({ persistent: true });
437
+ const group = client.node.createGroup();
438
+ const map = group.createMap();
439
+ map.set("x", "y", "trusting");
440
+ await map.core.waitForSync();
441
+ await client.node.gracefulShutdown();
442
+ // Wait for the reconciliation interval to pass
443
+ await new Promise((resolve) => setTimeout(resolve, 200));
444
+ SyncMessagesLog.clear();
445
+ const anotherClient = setupTestNode({
446
+ enableFullStorageReconciliation: true,
447
+ });
448
+ anotherClient.addStorage({ storage });
449
+ anotherClient.connectToSyncServer({ persistent: true });
450
+ const { promise, resolve } = Promise.withResolvers();
451
+ const syncManager = anotherClient.node.syncManager;
452
+ const originalHandler = syncManager.handleReconcileAck.bind(syncManager);
453
+ let processReconciliationAcks = true;
454
+ syncManager.handleReconcileAck = (msg, peer) => {
455
+ if (processReconciliationAcks) {
456
+ originalHandler(msg, peer);
457
+ processReconciliationAcks = false;
458
+ resolve();
459
+ }
460
+ };
461
+ await promise;
462
+ await anotherClient.node.gracefulShutdown();
463
+ // No need to wait for the lock to expire, since it's held by the same session
464
+ const acquireResult = await new Promise((resolve) => storage.tryAcquireStorageReconciliationLock(anotherClient.node.currentSessionID, peer.id, resolve));
465
+ expect(acquireResult.acquired).toBe(true);
466
+ if (acquireResult.acquired) {
467
+ expect(acquireResult.lastProcessedOffset).toBe(1);
468
+ }
469
+ });
470
+ test("after successful completion, next due run starts from the beginning", async () => {
471
+ setStorageReconciliationInterval(100);
472
+ const client = setupTestNode({ enableFullStorageReconciliation: true });
473
+ const { storage } = client.addStorage();
474
+ client.connectToSyncServer({ persistent: true });
475
+ const group = client.node.createGroup();
476
+ await group.core.waitForSync();
477
+ await client.node.gracefulShutdown();
478
+ await new Promise((resolve) => setTimeout(resolve, 500));
479
+ const anotherClient = setupTestNode({
480
+ enableFullStorageReconciliation: true,
481
+ });
482
+ anotherClient.addStorage({ storage });
483
+ const { peer } = anotherClient.connectToSyncServer({
484
+ persistent: true,
485
+ });
486
+ await waitForStorageReconciliationBatchAck(anotherClient.node);
487
+ await new Promise((resolve) => setTimeout(resolve, 500));
488
+ const acquireResult = await new Promise((resolve) => storage.tryAcquireStorageReconciliationLock(anotherClient.node.currentSessionID, peer.id, resolve));
489
+ expect(acquireResult.acquired).toBe(true);
490
+ if (acquireResult.acquired) {
491
+ expect(acquireResult.lastProcessedOffset).toBe(0);
492
+ }
493
+ });
494
+ });
495
+ });
496
+ function waitForStorageReconciliationBatchAck(node) {
497
+ const pendingReconciliationAck = node.syncManager.pendingReconciliationAck;
498
+ expect(pendingReconciliationAck.size).toBeGreaterThan(0);
499
+ return waitFor(() => pendingReconciliationAck.size === 0);
500
+ }
501
+ //# sourceMappingURL=sync.storageReconciliation.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sync.storageReconciliation.test.js","sourceRoot":"","sources":["../../src/tests/sync.storageReconciliation.test.ts"],"names":[],"mappings":"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"}
@@ -138,6 +138,7 @@ export declare function setupTestNode(opts?: {
138
138
  connected?: boolean;
139
139
  secret?: AgentSecret;
140
140
  syncWhen?: SyncWhen;
141
+ enableFullStorageReconciliation?: boolean;
141
142
  }): {
142
143
  node: LocalNode;
143
144
  connectToSyncServer: (opts?: {
@@ -1 +1 @@
1
- {"version":3,"file":"testUtils.d.ts","sourceRoot":"","sources":["../../src/tests/testUtils.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"testUtils.d.ts","sourceRoot":"","sources":["../../src/tests/testUtils.ts"],"names":[],"mappings":"AACA,OAAO,EAIL,YAAY,EACb,MAAM,4BAA4B,CAAC;AAEpC,OAAO,EAAE,iBAAiB,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AAC5E,OAAO,EAAE,UAAU,EAAE,MAAM,yBAAyB,CAAC;AACrD,OAAO,EACL,KAAK,WAAW,EAChB,aAAa,EACb,KAAK,IAAI,EACT,KAAK,WAAW,EAEhB,eAAe,EACf,KAAK,UAAU,EACf,YAAY,EACZ,QAAQ,EACR,KAAK,UAAU,EACf,UAAU,EACX,MAAM,eAAe,CAAC;AACvB,OAAO,KAAK,EAAE,OAAO,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AACpD,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAE5C,OAAO,KAAK,EAAE,IAAI,EAAE,WAAW,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAI9D,OAAO,EAAE,aAAa,EAAE,MAAM,iCAAiC,CAAC;AAKhE,wBAAgB,4BAA4B,CAAC,MAAM,EAAE,UAAU,QAE9D;AAQD,wBAAgB,uBAAuB,IAAI,CAAC,eAAe,EAAE,SAAS,CAAC,CAMtE;AAED,wBAAgB,2BAA2B,CACzC,MAAM,EAAE,WAAW,GAClB,CAAC,eAAe,EAAE,SAAS,CAAC,CAI9B;AAED,wBAAgB,+BAA+B,cAG9C;AAED,wBAAgB,cAAc,cAG7B;AAED,wBAAsB,uBAAuB,CAC3C,SAAS,EAAE,IAAI,CAAC,MAAM,CAAC,EACvB,SAAS,EAAE,IAAI,CAAC,MAAM,CAAC;;;;;;;;;;;;;GAQxB;AAED,wBAAsB,yBAAyB,CAC7C,SAAS,EAAE,IAAI,CAAC,MAAM,CAAC,EACvB,SAAS,EAAE,IAAI,CAAC,MAAM,CAAC,EACvB,SAAS,EAAE,IAAI,CAAC,MAAM,CAAC;;;;;;;;;;;;;;;;;;;GAaxB;AAED,wBAAsB,qBAAqB,CAAC,GAAG,SAAS,EAAE,IAAI,CAAC,MAAM,CAAC,EAAE;;;;;KAqBvE;AAED,wBAAgB,eAAe,CAC7B,CAAC,EAAE,SAAS,EACZ,CAAC,EAAE,SAAS,EACZ,KAAK,EAAE,QAAQ,GAAG,QAAQ,EAC1B,KAAK,EAAE,QAAQ,GAAG,QAAQ,QAa3B;AAED,wBAAgB,QAAQ;;;;EAkBvB;AAED,wBAAgB,kBAAkB;;;;;;EAgBjC;AAED,wBAAgB,iBAAiB;;;;EAWhC;AAED,wBAAgB,2BAA2B;;;;;EAQ1C;AAED,wBAAgB,gBAAgB,CAAC,CAAC,EAChC,OAAO,EAAE,OAAO,CAAC,CAAC,CAAC,EACnB,GAAG,EAAE;IAAE,OAAO,EAAE,MAAM,CAAA;CAAE,GACvB,OAAO,CAAC,IAAI,CAAC,CAaf;AAED,wBAAgB,OAAO,CACrB,QAAQ,EAAE,MAAM,OAAO,GAAG,IAAI,GAAG,OAAO,CAAC,OAAO,GAAG,IAAI,CAAC,iBA2BzD;AAED,wBAAsB,iBAAiB,CAAC,CAAC,SAAS,UAAU,EAC1D,IAAI,EAAE,SAAS,EACf,EAAE,EAAE,IAAI,CAAC,CAAC,CAAC,EACX,SAAS,CAAC,EAAE,OAAO,GAClB,OAAO,CAAC,CAAC,CAAC,CAMZ;AAED,wBAAgB,8BAA8B,CAC5C,IAAI,EAAE,IAAI,EACV,WAAW,EAAE,WAAW,CAAC,QAAQ,CAAC,EAClC,IAAI,EAAE;IACJ,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,OAAO,CAAC,EAAE,CAAC,GAAG,EAAE,WAAW,KAAK,OAAO,CAAC;CACzC;;;;EAkCF;AAED,wBAAgB,QAAQ,CAAC,EAAE,EAAE,MAAM,UAMlC;AAED;;;;;;GAMG;AACH,cAAM,gBAAiB,SAAQ,YAAY;IACzC,OAAO,CAAC,SAAS,CAEf;IAEF,SAAS,CAAC,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC;IAGrC,SAAS,CAAC,YAAY,IAAI,OAAO,CAAC,IAAI,CAAC;IAIjC,cAAc,CAClB,IAAI,EAAE,MAAM,EACZ,UAAU,GAAE;QAAE,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,GAAG,MAAM,CAAA;KAAO;IAgB/C,gBAAgB,IAAI,OAAO,CAAC,IAAI,CAAC;CAYxC;AAED,wBAAgB,sBAAsB,qBAWrC;AAED,wBAAgB,wBAAwB,SAEvC;AAED,qBAAa,eAAe;IAC1B,MAAM,CAAC,QAAQ,EAAE,eAAe,EAAE,CAAM;IAExC,MAAM,CAAC,GAAG,CAAC,OAAO,EAAE,eAAe;IAInC,MAAM,CAAC,KAAK;IAIZ,MAAM,CAAC,WAAW,CAAC,cAAc,EAAE;QAAE,CAAC,GAAG,EAAE,MAAM,GAAG,WAAW,CAAA;KAAE;IAIjE,MAAM,CAAC,aAAa,CAAC,cAAc,EAAE;QAAE,CAAC,GAAG,EAAE,MAAM,GAAG,WAAW,CAAA;KAAE;CAGpE;AAED,wBAAgB,0BAA0B,CAAC,IAAI,EAAE;IAC/C,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,UAAU,CAAC,EAAE,SAAS,CAAC;IACvB,MAAM,EAAE,MAAM,CAAC;IACf,UAAU,CAAC,EAAE,OAAO,CAAC;CACtB;;;;EAgCA;AAED,eAAO,MAAM,gBAAgB;;CAE5B,CAAC;AAEF,wBAAgB,aAAa,CAC3B,IAAI,GAAE;IACJ,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,MAAM,CAAC,EAAE,WAAW,CAAC;IACrB,QAAQ,CAAC,EAAE,QAAQ,CAAC;IACpB,+BAA+B,CAAC,EAAE,OAAO,CAAC;CACtC;;iCAkB8B;QAClC,cAAc,CAAC,EAAE,MAAM,CAAC;QACxB,OAAO,CAAC,EAAE,MAAM,CAAC;QACjB,UAAU,CAAC,EAAE,SAAS,CAAC;QACvB,UAAU,CAAC,EAAE,OAAO,CAAC;QACrB,kBAAkB,CAAC,EAAE,OAAO,CAAC;KAC9B;;;;;;wBAoByB;QAAE,OAAO,CAAC,EAAE,MAAM,CAAC;QAAC,OAAO,CAAC,EAAE,UAAU,CAAA;KAAE;;;6BAa5D;QAAE,OAAO,CAAC,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;QAAC,WAAW,CAAC,EAAE,MAAM,CAAA;KAAE;;;;;;EA2DtE;AAED,wBAAsB,gBAAgB,CACpC,IAAI,GAAE;IACJ,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,OAAO,CAAC,EAAE,UAAU,CAAC;IACrB,SAAS,CAAC,EAAE,YAAY,CAAC;IACzB,aAAa,CAAC,EAAE,WAAW,CAAC;CACxB;;;;iCA+B8B;QAClC,cAAc,CAAC,EAAE,MAAM,CAAC;QACxB,OAAO,CAAC,EAAE,MAAM,CAAC;QACjB,UAAU,CAAC,EAAE,SAAS,CAAC;KACxB;;;;;;;wBAwByB;QAAE,OAAO,CAAC,EAAE,MAAM,CAAC;QAAC,OAAO,CAAC,EAAE,UAAU,CAAA;KAAE;;;6BAa5D;QAAE,OAAO,CAAC,EAAE,MAAM,CAAC;QAAC,WAAW,CAAC,EAAE,MAAM,CAAA;KAAE;;;;;GA6CnD;AAED,MAAM,MAAM,eAAe,GAAG;IAC5B,MAAM,EAAE,UAAU,CAAC;IACnB,EAAE,EAAE,OAAO,CAAC;CACb,CAAC;AAEF,MAAM,MAAM,qBAAqB,GAAG;IAClC,MAAM,EAAE,gBAAgB,CAAC;IACzB,EAAE,EAAE,OAAO,CAAC;IACZ,MAAM,EAAE,OAAO,CAAC;IAChB,QAAQ,EAAE;QAAE,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,CAAA;KAAE,CAAC;CAC3C,CAAC;AAEF,MAAM,MAAM,eAAe,GAAG;IAC5B,IAAI,EAAE,MAAM,CAAC;IACb,EAAE,EAAE,MAAM,CAAC;IACX,GAAG,EAAE,WAAW,GAAG,eAAe,GAAG,qBAAqB,CAAC;CAC5D,CAAC;AAEF,wBAAgB,kCAAkC,CAAC,IAAI,EAAE;IACvD,KAAK,EAAE;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC;QAAC,IAAI,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;IACzD,KAAK,EAAE;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC;QAAC,IAAI,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;IACzD,UAAU,CAAC,EAAE,OAAO,CAAC;CACtB;;;EA2DA;AAED,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,SAAS,qBAelD;AAED,wBAAgB,qBAAqB,CACnC,IAAI,EAAE,SAAS,EACf,IAAI,GAAE,aAAa,CAAC,MAAM,CAAW;;;;EActC;AAED,wBAAgB,sBAAsB,CAAC,GAAG,EAAE,QAAQ;;gDAanD;AAED,wBAAgB,qBAAqB,CACnC,OAAO,EAAE,WAAW,EACpB,IAAI,EAAE,SAAS,EACf,MAAM,CAAC,EAAE,MAAM,QAUhB;AAMD;;GAEG;AACH,wBAAgB,aAAa,CAAC,GAAG,EAAE,OAAO,GAAG,GAAG,IAAI,WAAW,CAO9D;AAED;;;GAGG;AACH,wBAAgB,2BAA2B,CAAC,IAAI,EAAE;IAChD,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;;;EAkCA;AAED;;;GAGG;AACH,wBAAgB,0BAA0B,CACxC,cAAc,EAAE,CAAC,IAAI,EAAE,eAAe,KAAK,OAAO,CAAC,IAAI,CAAC;;EAWzD"}
@@ -289,7 +289,7 @@ export function setupTestNode(opts = {}) {
289
289
  const [admin, session] = opts.secret
290
290
  ? agentAndSessionIDFromSecret(opts.secret)
291
291
  : randomAgentAndSessionID();
292
- let node = new LocalNode(admin.agentSecret, session, Crypto, opts.syncWhen);
292
+ let node = new LocalNode(admin.agentSecret, session, Crypto, opts.syncWhen, opts.enableFullStorageReconciliation);
293
293
  if (opts.isSyncServer) {
294
294
  syncServer.current = node;
295
295
  }
@@ -340,7 +340,7 @@ export function setupTestNode(opts = {}) {
340
340
  addAsyncStorage,
341
341
  restart: async () => {
342
342
  await node.gracefulShutdown();
343
- ctx.node = node = new LocalNode(admin.agentSecret, session, Crypto, opts.syncWhen);
343
+ ctx.node = node = new LocalNode(admin.agentSecret, session, Crypto, opts.syncWhen, opts.enableFullStorageReconciliation);
344
344
  if (opts.isSyncServer) {
345
345
  syncServer.current = node;
346
346
  }
@@ -351,6 +351,7 @@ export function setupTestNode(opts = {}) {
351
351
  secret: node.agentSecret,
352
352
  connected: opts.connected,
353
353
  isSyncServer: opts.isSyncServer,
354
+ enableFullStorageReconciliation: opts.enableFullStorageReconciliation,
354
355
  });
355
356
  },
356
357
  disconnect: () => {