cojson 0.18.26 → 0.18.28

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 (161) hide show
  1. package/.turbo/turbo-build.log +1 -1
  2. package/CHANGELOG.md +17 -0
  3. package/dist/PeerKnownStates.d.ts +4 -3
  4. package/dist/PeerKnownStates.d.ts.map +1 -1
  5. package/dist/PeerKnownStates.js +27 -18
  6. package/dist/PeerKnownStates.js.map +1 -1
  7. package/dist/PeerState.d.ts +3 -2
  8. package/dist/PeerState.d.ts.map +1 -1
  9. package/dist/PeerState.js.map +1 -1
  10. package/dist/SyncStateManager.d.ts +2 -2
  11. package/dist/SyncStateManager.d.ts.map +1 -1
  12. package/dist/SyncStateManager.js +2 -10
  13. package/dist/SyncStateManager.js.map +1 -1
  14. package/dist/coValueContentMessage.d.ts +1 -1
  15. package/dist/coValueContentMessage.d.ts.map +1 -1
  16. package/dist/coValueContentMessage.js +1 -1
  17. package/dist/coValueContentMessage.js.map +1 -1
  18. package/dist/coValueCore/SessionMap.d.ts +6 -3
  19. package/dist/coValueCore/SessionMap.d.ts.map +1 -1
  20. package/dist/coValueCore/SessionMap.js +41 -8
  21. package/dist/coValueCore/SessionMap.js.map +1 -1
  22. package/dist/coValueCore/branching.d.ts +5 -4
  23. package/dist/coValueCore/branching.d.ts.map +1 -1
  24. package/dist/coValueCore/branching.js +22 -4
  25. package/dist/coValueCore/branching.js.map +1 -1
  26. package/dist/coValueCore/coValueCore.d.ts +29 -25
  27. package/dist/coValueCore/coValueCore.d.ts.map +1 -1
  28. package/dist/coValueCore/coValueCore.js +163 -126
  29. package/dist/coValueCore/coValueCore.js.map +1 -1
  30. package/dist/coValueCore/decryptTransactionChangesAndMeta.d.ts +3 -0
  31. package/dist/coValueCore/decryptTransactionChangesAndMeta.d.ts.map +1 -0
  32. package/dist/coValueCore/decryptTransactionChangesAndMeta.js +34 -0
  33. package/dist/coValueCore/decryptTransactionChangesAndMeta.js.map +1 -0
  34. package/dist/coValueCore/verifiedState.d.ts +12 -6
  35. package/dist/coValueCore/verifiedState.d.ts.map +1 -1
  36. package/dist/coValueCore/verifiedState.js +28 -56
  37. package/dist/coValueCore/verifiedState.js.map +1 -1
  38. package/dist/coValues/coMap.d.ts.map +1 -1
  39. package/dist/coValues/coMap.js.map +1 -1
  40. package/dist/coValues/coStream.d.ts.map +1 -1
  41. package/dist/coValues/coStream.js.map +1 -1
  42. package/dist/exports.d.ts +3 -2
  43. package/dist/exports.d.ts.map +1 -1
  44. package/dist/exports.js +2 -1
  45. package/dist/exports.js.map +1 -1
  46. package/dist/knownState.d.ts +58 -2
  47. package/dist/knownState.d.ts.map +1 -1
  48. package/dist/knownState.js +79 -5
  49. package/dist/knownState.js.map +1 -1
  50. package/dist/localNode.js +1 -1
  51. package/dist/localNode.js.map +1 -1
  52. package/dist/permissions.d.ts.map +1 -1
  53. package/dist/permissions.js +18 -20
  54. package/dist/permissions.js.map +1 -1
  55. package/dist/storage/knownState.d.ts +1 -1
  56. package/dist/storage/knownState.d.ts.map +1 -1
  57. package/dist/storage/knownState.js +2 -3
  58. package/dist/storage/knownState.js.map +1 -1
  59. package/dist/storage/storageAsync.d.ts +2 -1
  60. package/dist/storage/storageAsync.d.ts.map +1 -1
  61. package/dist/storage/storageAsync.js +5 -6
  62. package/dist/storage/storageAsync.js.map +1 -1
  63. package/dist/storage/storageSync.d.ts +2 -1
  64. package/dist/storage/storageSync.d.ts.map +1 -1
  65. package/dist/storage/storageSync.js +5 -5
  66. package/dist/storage/storageSync.js.map +1 -1
  67. package/dist/storage/types.d.ts +2 -1
  68. package/dist/storage/types.d.ts.map +1 -1
  69. package/dist/sync.d.ts +2 -12
  70. package/dist/sync.d.ts.map +1 -1
  71. package/dist/sync.js +9 -38
  72. package/dist/sync.js.map +1 -1
  73. package/dist/tests/PeerKnownStates.test.js +1 -1
  74. package/dist/tests/PeerKnownStates.test.js.map +1 -1
  75. package/dist/tests/PeerState.test.js +19 -0
  76. package/dist/tests/PeerState.test.js.map +1 -1
  77. package/dist/tests/PureJSCrypto.test.js.map +1 -1
  78. package/dist/tests/StorageApiAsync.test.js +1 -1
  79. package/dist/tests/StorageApiAsync.test.js.map +1 -1
  80. package/dist/tests/StorageApiSync.test.js +1 -2
  81. package/dist/tests/StorageApiSync.test.js.map +1 -1
  82. package/dist/tests/StoreQueue.test.js.map +1 -1
  83. package/dist/tests/SyncStateManager.test.js +1 -1
  84. package/dist/tests/SyncStateManager.test.js.map +1 -1
  85. package/dist/tests/branching.test.js +237 -28
  86. package/dist/tests/branching.test.js.map +1 -1
  87. package/dist/tests/coValueContentMessage.test.js +1 -1
  88. package/dist/tests/coValueContentMessage.test.js.map +1 -1
  89. package/dist/tests/coValueCore.loadFromStorage.test.d.ts +2 -0
  90. package/dist/tests/coValueCore.loadFromStorage.test.d.ts.map +1 -0
  91. package/dist/tests/coValueCore.loadFromStorage.test.js +395 -0
  92. package/dist/tests/coValueCore.loadFromStorage.test.js.map +1 -0
  93. package/dist/tests/coValueCore.loadingState.test.d.ts +2 -0
  94. package/dist/tests/coValueCore.loadingState.test.d.ts.map +1 -0
  95. package/dist/tests/{coValueCoreLoadingState.test.js → coValueCore.loadingState.test.js} +4 -12
  96. package/dist/tests/coValueCore.loadingState.test.js.map +1 -0
  97. package/dist/tests/coValueCore.test.js +30 -5
  98. package/dist/tests/coValueCore.test.js.map +1 -1
  99. package/dist/tests/knownState.test.d.ts +2 -0
  100. package/dist/tests/knownState.test.d.ts.map +1 -0
  101. package/dist/tests/knownState.test.js +510 -0
  102. package/dist/tests/knownState.test.js.map +1 -0
  103. package/dist/tests/messagesTestUtils.d.ts.map +1 -1
  104. package/dist/tests/messagesTestUtils.js.map +1 -1
  105. package/dist/tests/priority.test.js.map +1 -1
  106. package/dist/tests/sync.mesh.test.js +4 -34
  107. package/dist/tests/sync.mesh.test.js.map +1 -1
  108. package/dist/tests/sync.storage.test.js.map +1 -1
  109. package/dist/tests/sync.upload.test.js.map +1 -1
  110. package/dist/tests/testUtils.d.ts +7 -1
  111. package/dist/tests/testUtils.d.ts.map +1 -1
  112. package/dist/tests/testUtils.js +12 -0
  113. package/dist/tests/testUtils.js.map +1 -1
  114. package/package.json +3 -3
  115. package/src/PeerKnownStates.ts +36 -22
  116. package/src/PeerState.ts +2 -1
  117. package/src/SyncStateManager.ts +4 -17
  118. package/src/coValueContentMessage.ts +2 -1
  119. package/src/coValueCore/SessionMap.ts +66 -11
  120. package/src/coValueCore/branching.ts +37 -13
  121. package/src/coValueCore/coValueCore.ts +224 -177
  122. package/src/coValueCore/decryptTransactionChangesAndMeta.ts +56 -0
  123. package/src/coValueCore/verifiedState.ts +32 -64
  124. package/src/coValues/coMap.ts +1 -5
  125. package/src/coValues/coStream.ts +1 -5
  126. package/src/exports.ts +2 -2
  127. package/src/knownState.ts +118 -12
  128. package/src/localNode.ts +1 -1
  129. package/src/permissions.ts +21 -22
  130. package/src/storage/knownState.ts +9 -3
  131. package/src/storage/storageAsync.ts +15 -7
  132. package/src/storage/storageSync.ts +16 -8
  133. package/src/storage/types.ts +2 -1
  134. package/src/sync.ts +14 -60
  135. package/src/tests/PeerKnownStates.test.ts +1 -1
  136. package/src/tests/PeerState.test.ts +29 -3
  137. package/src/tests/PureJSCrypto.test.ts +0 -1
  138. package/src/tests/StorageApiAsync.test.ts +3 -6
  139. package/src/tests/StorageApiSync.test.ts +2 -6
  140. package/src/tests/StoreQueue.test.ts +3 -2
  141. package/src/tests/SyncStateManager.test.ts +1 -1
  142. package/src/tests/branching.test.ts +392 -45
  143. package/src/tests/coValueContentMessage.test.ts +2 -2
  144. package/src/tests/coValueCore.loadFromStorage.test.ts +540 -0
  145. package/src/tests/{coValueCoreLoadingState.test.ts → coValueCore.loadingState.test.ts} +3 -16
  146. package/src/tests/coValueCore.test.ts +40 -5
  147. package/src/tests/knownState.test.ts +665 -0
  148. package/src/tests/messagesTestUtils.ts +2 -1
  149. package/src/tests/priority.test.ts +0 -2
  150. package/src/tests/sync.mesh.test.ts +11 -38
  151. package/src/tests/sync.storage.test.ts +0 -1
  152. package/src/tests/sync.upload.test.ts +0 -1
  153. package/src/tests/testUtils.ts +22 -2
  154. package/dist/coValueCore/decodeTransactionChangesAndMeta.d.ts +0 -3
  155. package/dist/coValueCore/decodeTransactionChangesAndMeta.d.ts.map +0 -1
  156. package/dist/coValueCore/decodeTransactionChangesAndMeta.js +0 -59
  157. package/dist/coValueCore/decodeTransactionChangesAndMeta.js.map +0 -1
  158. package/dist/tests/coValueCoreLoadingState.test.d.ts +0 -2
  159. package/dist/tests/coValueCoreLoadingState.test.d.ts.map +0 -1
  160. package/dist/tests/coValueCoreLoadingState.test.js.map +0 -1
  161. package/src/coValueCore/decodeTransactionChangesAndMeta.ts +0 -81
@@ -0,0 +1,665 @@
1
+ import { describe, expect, test } from "vitest";
2
+ import {
3
+ emptyKnownState,
4
+ knownStateFrom,
5
+ combineKnownStates,
6
+ combineKnownStateSessions,
7
+ setSessionCounter,
8
+ updateSessionCounter,
9
+ cloneKnownState,
10
+ areLocalSessionsUploaded,
11
+ type CoValueKnownState,
12
+ type KnownStateSessions,
13
+ } from "../knownState.js";
14
+ import { RawCoID, SessionID } from "../ids.js";
15
+
16
+ describe("knownState", () => {
17
+ describe("emptyKnownState", () => {
18
+ test("should create an empty known state with the given id", () => {
19
+ const id = "test-id" as RawCoID;
20
+ const result = emptyKnownState(id);
21
+
22
+ expect(result).toEqual({
23
+ id: "test-id",
24
+ header: false,
25
+ sessions: {},
26
+ });
27
+ });
28
+
29
+ test("should have no sessions", () => {
30
+ const id = "test-id" as RawCoID;
31
+ const result = emptyKnownState(id);
32
+
33
+ expect(Object.keys(result.sessions)).toHaveLength(0);
34
+ });
35
+
36
+ test("should have header set to false", () => {
37
+ const id = "test-id" as RawCoID;
38
+ const result = emptyKnownState(id);
39
+
40
+ expect(result.header).toBe(false);
41
+ });
42
+ });
43
+
44
+ describe("knownStateFrom", () => {
45
+ test("should extract known state properties from input", () => {
46
+ const id = "test-id" as RawCoID;
47
+ const session1 = "session-1" as SessionID;
48
+ const input: CoValueKnownState = {
49
+ id,
50
+ header: true,
51
+ sessions: { [session1]: 5 },
52
+ };
53
+
54
+ const result = knownStateFrom(input);
55
+
56
+ expect(result).toEqual({
57
+ id: "test-id",
58
+ header: true,
59
+ sessions: { [session1]: 5 },
60
+ });
61
+ });
62
+
63
+ test("should create a shallow copy of sessions", () => {
64
+ const id = "test-id" as RawCoID;
65
+ const session1 = "session-1" as SessionID;
66
+ const sessions = { [session1]: 5 };
67
+ const input: CoValueKnownState = {
68
+ id,
69
+ header: true,
70
+ sessions,
71
+ };
72
+
73
+ const result = knownStateFrom(input);
74
+
75
+ expect(result.sessions).toBe(sessions);
76
+ });
77
+
78
+ test("should work with empty sessions", () => {
79
+ const id = "test-id" as RawCoID;
80
+ const input = emptyKnownState(id);
81
+
82
+ const result = knownStateFrom(input);
83
+
84
+ expect(result).toEqual({
85
+ id: "test-id",
86
+ header: false,
87
+ sessions: {},
88
+ });
89
+ });
90
+ });
91
+
92
+ describe("combineKnownStates", () => {
93
+ test("should combine sessions from source to target", () => {
94
+ const id = "test-id" as RawCoID;
95
+ const session1 = "session-1" as SessionID;
96
+ const session2 = "session-2" as SessionID;
97
+ const target: CoValueKnownState = {
98
+ id,
99
+ header: false,
100
+ sessions: { [session1]: 3 },
101
+ };
102
+ const source: CoValueKnownState = {
103
+ id,
104
+ header: false,
105
+ sessions: { [session2]: 7 },
106
+ };
107
+
108
+ const result = combineKnownStates(target, source);
109
+
110
+ expect(result.sessions).toEqual({
111
+ [session1]: 3,
112
+ [session2]: 7,
113
+ });
114
+ });
115
+
116
+ test("should update target when source has higher counter", () => {
117
+ const id = "test-id" as RawCoID;
118
+ const session1 = "session-1" as SessionID;
119
+ const target: CoValueKnownState = {
120
+ id,
121
+ header: false,
122
+ sessions: { [session1]: 3 },
123
+ };
124
+ const source: CoValueKnownState = {
125
+ id,
126
+ header: false,
127
+ sessions: { [session1]: 7 },
128
+ };
129
+
130
+ combineKnownStates(target, source);
131
+
132
+ expect(target.sessions[session1]).toBe(7);
133
+ });
134
+
135
+ test("should not update target when source has lower counter", () => {
136
+ const id = "test-id" as RawCoID;
137
+ const session1 = "session-1" as SessionID;
138
+ const target: CoValueKnownState = {
139
+ id,
140
+ header: false,
141
+ sessions: { [session1]: 10 },
142
+ };
143
+ const source: CoValueKnownState = {
144
+ id,
145
+ header: false,
146
+ sessions: { [session1]: 5 },
147
+ };
148
+
149
+ combineKnownStates(target, source);
150
+
151
+ expect(target.sessions[session1]).toBe(10);
152
+ });
153
+
154
+ test("should set header to true when source has header true", () => {
155
+ const id = "test-id" as RawCoID;
156
+ const target: CoValueKnownState = {
157
+ id,
158
+ header: false,
159
+ sessions: {},
160
+ };
161
+ const source: CoValueKnownState = {
162
+ id,
163
+ header: true,
164
+ sessions: {},
165
+ };
166
+
167
+ combineKnownStates(target, source);
168
+
169
+ expect(target.header).toBe(true);
170
+ });
171
+
172
+ test("should not change header when both have header true", () => {
173
+ const id = "test-id" as RawCoID;
174
+ const target: CoValueKnownState = {
175
+ id,
176
+ header: true,
177
+ sessions: {},
178
+ };
179
+ const source: CoValueKnownState = {
180
+ id,
181
+ header: true,
182
+ sessions: {},
183
+ };
184
+
185
+ combineKnownStates(target, source);
186
+
187
+ expect(target.header).toBe(true);
188
+ });
189
+
190
+ test("should not change header when source has header false", () => {
191
+ const id = "test-id" as RawCoID;
192
+ const target: CoValueKnownState = {
193
+ id,
194
+ header: true,
195
+ sessions: {},
196
+ };
197
+ const source: CoValueKnownState = {
198
+ id,
199
+ header: false,
200
+ sessions: {},
201
+ };
202
+
203
+ combineKnownStates(target, source);
204
+
205
+ expect(target.header).toBe(true);
206
+ });
207
+
208
+ test("should return the target object", () => {
209
+ const id = "test-id" as RawCoID;
210
+ const target: CoValueKnownState = {
211
+ id,
212
+ header: false,
213
+ sessions: {},
214
+ };
215
+ const source: CoValueKnownState = {
216
+ id,
217
+ header: false,
218
+ sessions: {},
219
+ };
220
+
221
+ const result = combineKnownStates(target, source);
222
+
223
+ expect(result).toBe(target);
224
+ });
225
+
226
+ test("should mutate the target object", () => {
227
+ const id = "test-id" as RawCoID;
228
+ const session1 = "session-1" as SessionID;
229
+ const target: CoValueKnownState = {
230
+ id,
231
+ header: false,
232
+ sessions: {},
233
+ };
234
+ const source: CoValueKnownState = {
235
+ id,
236
+ header: true,
237
+ sessions: { [session1]: 5 },
238
+ };
239
+
240
+ combineKnownStates(target, source);
241
+
242
+ expect(target.header).toBe(true);
243
+ expect(target.sessions[session1]).toBe(5);
244
+ });
245
+ });
246
+
247
+ describe("combineKnownStateSessions", () => {
248
+ test("should add new sessions from source to target", () => {
249
+ const session1 = "session-1" as SessionID;
250
+ const session2 = "session-2" as SessionID;
251
+ const target: KnownStateSessions = { [session1]: 3 };
252
+ const source: KnownStateSessions = { [session2]: 7 };
253
+
254
+ combineKnownStateSessions(target, source);
255
+
256
+ expect(target).toEqual({
257
+ [session1]: 3,
258
+ [session2]: 7,
259
+ });
260
+ });
261
+
262
+ test("should update session when source has higher counter", () => {
263
+ const session1 = "session-1" as SessionID;
264
+ const target: KnownStateSessions = { [session1]: 3 };
265
+ const source: KnownStateSessions = { [session1]: 7 };
266
+
267
+ combineKnownStateSessions(target, source);
268
+
269
+ expect(target[session1]).toBe(7);
270
+ });
271
+
272
+ test("should not update session when source has lower counter", () => {
273
+ const session1 = "session-1" as SessionID;
274
+ const target: KnownStateSessions = { [session1]: 10 };
275
+ const source: KnownStateSessions = { [session1]: 5 };
276
+
277
+ combineKnownStateSessions(target, source);
278
+
279
+ expect(target[session1]).toBe(10);
280
+ });
281
+
282
+ test("should add session when target has no counter for that session", () => {
283
+ const session1 = "session-1" as SessionID;
284
+ const target: KnownStateSessions = {};
285
+ const source: KnownStateSessions = { [session1]: 5 };
286
+
287
+ combineKnownStateSessions(target, source);
288
+
289
+ expect(target[session1]).toBe(5);
290
+ });
291
+
292
+ test("should handle empty source", () => {
293
+ const session1 = "session-1" as SessionID;
294
+ const target: KnownStateSessions = { [session1]: 3 };
295
+ const source: KnownStateSessions = {};
296
+
297
+ combineKnownStateSessions(target, source);
298
+
299
+ expect(target).toEqual({ [session1]: 3 });
300
+ });
301
+
302
+ test("should handle empty target", () => {
303
+ const session1 = "session-1" as SessionID;
304
+ const target: KnownStateSessions = {};
305
+ const source: KnownStateSessions = { [session1]: 5 };
306
+
307
+ combineKnownStateSessions(target, source);
308
+
309
+ expect(target).toEqual({ [session1]: 5 });
310
+ });
311
+
312
+ test("should handle multiple sessions", () => {
313
+ const session1 = "session-1" as SessionID;
314
+ const session2 = "session-2" as SessionID;
315
+ const session3 = "session-3" as SessionID;
316
+ const target: KnownStateSessions = {
317
+ [session1]: 5,
318
+ [session2]: 10,
319
+ };
320
+ const source: KnownStateSessions = {
321
+ [session1]: 3,
322
+ [session2]: 15,
323
+ [session3]: 8,
324
+ };
325
+
326
+ combineKnownStateSessions(target, source);
327
+
328
+ expect(target).toEqual({
329
+ [session1]: 5,
330
+ [session2]: 15,
331
+ [session3]: 8,
332
+ });
333
+ });
334
+
335
+ test("should return the target object", () => {
336
+ const session1 = "session-1" as SessionID;
337
+ const target: KnownStateSessions = { [session1]: 3 };
338
+ const source: KnownStateSessions = { [session1]: 7 };
339
+
340
+ const result = combineKnownStateSessions(target, source);
341
+
342
+ expect(result).toBe(target);
343
+ });
344
+ });
345
+
346
+ describe("setSessionCounter", () => {
347
+ test("should set counter for a new session", () => {
348
+ const session1 = "session-1" as SessionID;
349
+ const knownState: KnownStateSessions = {};
350
+
351
+ setSessionCounter(knownState, session1, 5);
352
+
353
+ expect(knownState[session1]).toBe(5);
354
+ });
355
+
356
+ test("should update counter for an existing session", () => {
357
+ const session1 = "session-1" as SessionID;
358
+ const knownState: KnownStateSessions = { [session1]: 3 };
359
+
360
+ setSessionCounter(knownState, session1, 10);
361
+
362
+ expect(knownState[session1]).toBe(10);
363
+ });
364
+
365
+ test("should allow setting counter to 0", () => {
366
+ const session1 = "session-1" as SessionID;
367
+ const knownState: KnownStateSessions = { [session1]: 5 };
368
+
369
+ setSessionCounter(knownState, session1, 0);
370
+
371
+ expect(knownState[session1]).toBe(0);
372
+ });
373
+
374
+ test("should allow setting counter to a lower value", () => {
375
+ const session1 = "session-1" as SessionID;
376
+ const knownState: KnownStateSessions = { [session1]: 10 };
377
+
378
+ setSessionCounter(knownState, session1, 3);
379
+
380
+ expect(knownState[session1]).toBe(3);
381
+ });
382
+
383
+ test("should mutate the input object", () => {
384
+ const session1 = "session-1" as SessionID;
385
+ const knownState: KnownStateSessions = {};
386
+
387
+ setSessionCounter(knownState, session1, 5);
388
+
389
+ expect(knownState).toEqual({ [session1]: 5 });
390
+ });
391
+ });
392
+
393
+ describe("updateSessionCounter", () => {
394
+ test("should set counter for a new session", () => {
395
+ const session1 = "session-1" as SessionID;
396
+ const knownState: KnownStateSessions = {};
397
+
398
+ updateSessionCounter(knownState, session1, 5);
399
+
400
+ expect(knownState[session1]).toBe(5);
401
+ });
402
+
403
+ test("should update counter when new value is higher", () => {
404
+ const session1 = "session-1" as SessionID;
405
+ const knownState: KnownStateSessions = { [session1]: 3 };
406
+
407
+ updateSessionCounter(knownState, session1, 10);
408
+
409
+ expect(knownState[session1]).toBe(10);
410
+ });
411
+
412
+ test("should not update counter when new value is lower", () => {
413
+ const session1 = "session-1" as SessionID;
414
+ const knownState: KnownStateSessions = { [session1]: 10 };
415
+
416
+ updateSessionCounter(knownState, session1, 3);
417
+
418
+ expect(knownState[session1]).toBe(10);
419
+ });
420
+
421
+ test("should not update counter when new value is equal", () => {
422
+ const session1 = "session-1" as SessionID;
423
+ const knownState: KnownStateSessions = { [session1]: 5 };
424
+
425
+ updateSessionCounter(knownState, session1, 5);
426
+
427
+ expect(knownState[session1]).toBe(5);
428
+ });
429
+
430
+ test("should handle zero value for existing session", () => {
431
+ const session1 = "session-1" as SessionID;
432
+ const knownState: KnownStateSessions = { [session1]: 5 };
433
+
434
+ updateSessionCounter(knownState, session1, 0);
435
+
436
+ expect(knownState[session1]).toBe(5);
437
+ });
438
+
439
+ test("should set to 0 when counter does not exist and value is 0", () => {
440
+ const session1 = "session-1" as SessionID;
441
+ const knownState: KnownStateSessions = {};
442
+
443
+ updateSessionCounter(knownState, session1, 0);
444
+
445
+ expect(knownState[session1]).toBe(0);
446
+ });
447
+
448
+ test("should mutate the input object", () => {
449
+ const session1 = "session-1" as SessionID;
450
+ const knownState: KnownStateSessions = {};
451
+
452
+ updateSessionCounter(knownState, session1, 5);
453
+
454
+ expect(knownState).toEqual({ [session1]: 5 });
455
+ });
456
+ });
457
+
458
+ describe("cloneKnownState", () => {
459
+ test("should create a copy with the same values", () => {
460
+ const id = "test-id" as RawCoID;
461
+ const session1 = "session-1" as SessionID;
462
+ const original: CoValueKnownState = {
463
+ id,
464
+ header: true,
465
+ sessions: { [session1]: 5 },
466
+ };
467
+
468
+ const cloned = cloneKnownState(original);
469
+
470
+ expect(cloned).toEqual(original);
471
+ });
472
+
473
+ test("should create a new object", () => {
474
+ const id = "test-id" as RawCoID;
475
+ const original: CoValueKnownState = {
476
+ id,
477
+ header: true,
478
+ sessions: {},
479
+ };
480
+
481
+ const cloned = cloneKnownState(original);
482
+
483
+ expect(cloned).not.toBe(original);
484
+ });
485
+
486
+ test("should create a new sessions object", () => {
487
+ const id = "test-id" as RawCoID;
488
+ const session1 = "session-1" as SessionID;
489
+ const original: CoValueKnownState = {
490
+ id,
491
+ header: true,
492
+ sessions: { [session1]: 5 },
493
+ };
494
+
495
+ const cloned = cloneKnownState(original);
496
+
497
+ expect(cloned.sessions).not.toBe(original.sessions);
498
+ });
499
+
500
+ test("should not affect original when modifying clone", () => {
501
+ const id = "test-id" as RawCoID;
502
+ const session1 = "session-1" as SessionID;
503
+ const session2 = "session-2" as SessionID;
504
+ const original: CoValueKnownState = {
505
+ id,
506
+ header: false,
507
+ sessions: { [session1]: 5 },
508
+ };
509
+
510
+ const cloned = cloneKnownState(original);
511
+ cloned.header = true;
512
+ cloned.sessions[session2] = 10;
513
+
514
+ expect(original.header).toBe(false);
515
+ expect(original.sessions[session2]).toBeUndefined();
516
+ });
517
+
518
+ test("should work with empty sessions", () => {
519
+ const id = "test-id" as RawCoID;
520
+ const original = emptyKnownState(id);
521
+
522
+ const cloned = cloneKnownState(original);
523
+
524
+ expect(cloned).toEqual(original);
525
+ expect(cloned).not.toBe(original);
526
+ });
527
+
528
+ test("should work with multiple sessions", () => {
529
+ const id = "test-id" as RawCoID;
530
+ const session1 = "session-1" as SessionID;
531
+ const session2 = "session-2" as SessionID;
532
+ const session3 = "session-3" as SessionID;
533
+ const original: CoValueKnownState = {
534
+ id,
535
+ header: true,
536
+ sessions: {
537
+ [session1]: 5,
538
+ [session2]: 10,
539
+ [session3]: 15,
540
+ },
541
+ };
542
+
543
+ const cloned = cloneKnownState(original);
544
+
545
+ expect(cloned).toEqual(original);
546
+ expect(cloned.sessions).not.toBe(original.sessions);
547
+ });
548
+ });
549
+
550
+ describe("areLocalSessionsUploaded", () => {
551
+ test("should return true when all counters match", () => {
552
+ const session1 = "session-1" as SessionID;
553
+ const session2 = "session-2" as SessionID;
554
+ const from = { [session1]: 5, [session2]: 10 };
555
+ const to = { [session1]: 5, [session2]: 10 };
556
+
557
+ const result = areLocalSessionsUploaded(from, to);
558
+
559
+ expect(result).toBe(true);
560
+ });
561
+
562
+ test("should return false when counter differs", () => {
563
+ const session1 = "session-1" as SessionID;
564
+ const from = { [session1]: 5 };
565
+ const to = { [session1]: 3 };
566
+
567
+ const result = areLocalSessionsUploaded(from, to);
568
+
569
+ expect(result).toBe(false);
570
+ });
571
+
572
+ test("should return false when session is missing in to", () => {
573
+ const session1 = "session-1" as SessionID;
574
+ const from = { [session1]: 5 };
575
+ const to = {};
576
+
577
+ const result = areLocalSessionsUploaded(from, to);
578
+
579
+ expect(result).toBe(false);
580
+ });
581
+
582
+ test("should return true when from is empty", () => {
583
+ const session1 = "session-1" as SessionID;
584
+ const from = {};
585
+ const to = { [session1]: 5 };
586
+
587
+ const result = areLocalSessionsUploaded(from, to);
588
+
589
+ expect(result).toBe(true);
590
+ });
591
+
592
+ test("should return true when both are empty", () => {
593
+ const from = {};
594
+ const to = {};
595
+
596
+ const result = areLocalSessionsUploaded(from, to);
597
+
598
+ expect(result).toBe(true);
599
+ });
600
+
601
+ test("should handle multiple sessions", () => {
602
+ const session1 = "session-1" as SessionID;
603
+ const session2 = "session-2" as SessionID;
604
+ const session3 = "session-3" as SessionID;
605
+ const from = {
606
+ [session1]: 5,
607
+ [session2]: 10,
608
+ [session3]: 15,
609
+ };
610
+ const to = {
611
+ [session1]: 5,
612
+ [session2]: 10,
613
+ [session3]: 15,
614
+ };
615
+
616
+ const result = areLocalSessionsUploaded(from, to);
617
+
618
+ expect(result).toBe(true);
619
+ });
620
+
621
+ test("should return false if any session counter differs", () => {
622
+ const session1 = "session-1" as SessionID;
623
+ const session2 = "session-2" as SessionID;
624
+ const session3 = "session-3" as SessionID;
625
+ const from = {
626
+ [session1]: 5,
627
+ [session2]: 10,
628
+ [session3]: 15,
629
+ };
630
+ const to = {
631
+ [session1]: 5,
632
+ [session2]: 8,
633
+ [session3]: 15,
634
+ };
635
+
636
+ const result = areLocalSessionsUploaded(from, to);
637
+
638
+ expect(result).toBe(false);
639
+ });
640
+
641
+ test("should not check sessions in to that are not in from", () => {
642
+ const session1 = "session-1" as SessionID;
643
+ const session2 = "session-2" as SessionID;
644
+ const from = { [session1]: 5 };
645
+ const to = {
646
+ [session1]: 5,
647
+ [session2]: 10,
648
+ };
649
+
650
+ const result = areLocalSessionsUploaded(from, to);
651
+
652
+ expect(result).toBe(true);
653
+ });
654
+
655
+ test("should return false when counter in to is higher", () => {
656
+ const session1 = "session-1" as SessionID;
657
+ const from = { [session1]: 5 };
658
+ const to = { [session1]: 10 };
659
+
660
+ const result = areLocalSessionsUploaded(from, to);
661
+
662
+ expect(result).toBe(false);
663
+ });
664
+ });
665
+ });
@@ -1,5 +1,6 @@
1
1
  import { CoValueCore, LocalNode } from "../exports";
2
- import { CoValueKnownState, NewContentMessage, SyncMessage } from "../sync";
2
+ import { NewContentMessage, SyncMessage } from "../sync";
3
+ import { CoValueKnownState } from "../knownState.js";
3
4
 
4
5
  function simplifySessions(msg: Pick<CoValueKnownState, "sessions" | "header">) {
5
6
  const count = Object.values(msg.sessions).reduce(
@@ -1,11 +1,9 @@
1
1
  import { describe, expect, test } from "vitest";
2
2
  import { WasmCrypto } from "../crypto/WasmCrypto.js";
3
- import { LocalNode } from "../localNode.js";
4
3
  import { CO_VALUE_PRIORITY, getPriorityFromHeader } from "../priority.js";
5
4
  import {
6
5
  createAccountInNode,
7
6
  nodeWithRandomAgentAndSessionID,
8
- randomAgentAndSessionID,
9
7
  } from "./testUtils.js";
10
8
 
11
9
  const Crypto = await WasmCrypto.create();