cojson 0.20.7 → 0.20.8

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 (209) hide show
  1. package/.turbo/turbo-build.log +1 -1
  2. package/CHANGELOG.md +18 -0
  3. package/dist/SyncStateManager.d.ts.map +1 -1
  4. package/dist/SyncStateManager.js +0 -2
  5. package/dist/SyncStateManager.js.map +1 -1
  6. package/dist/base64url.d.ts +15 -0
  7. package/dist/base64url.d.ts.map +1 -1
  8. package/dist/base64url.js +101 -5
  9. package/dist/base64url.js.map +1 -1
  10. package/dist/base64url.test.js +76 -1
  11. package/dist/base64url.test.js.map +1 -1
  12. package/dist/coValue.d.ts +2 -1
  13. package/dist/coValue.d.ts.map +1 -1
  14. package/dist/coValue.js.map +1 -1
  15. package/dist/coValueCore/coValueCore.d.ts +9 -11
  16. package/dist/coValueCore/coValueCore.d.ts.map +1 -1
  17. package/dist/coValueCore/coValueCore.js +92 -65
  18. package/dist/coValueCore/coValueCore.js.map +1 -1
  19. package/dist/coValueCore/verifiedState.d.ts +38 -7
  20. package/dist/coValueCore/verifiedState.d.ts.map +1 -1
  21. package/dist/coValueCore/verifiedState.js +226 -30
  22. package/dist/coValueCore/verifiedState.js.map +1 -1
  23. package/dist/coValues/binaryCoStream.d.ts +63 -0
  24. package/dist/coValues/binaryCoStream.d.ts.map +1 -0
  25. package/dist/coValues/binaryCoStream.js +125 -0
  26. package/dist/coValues/binaryCoStream.js.map +1 -0
  27. package/dist/coValues/coList.d.ts +3 -1
  28. package/dist/coValues/coList.d.ts.map +1 -1
  29. package/dist/coValues/coList.js +15 -6
  30. package/dist/coValues/coList.js.map +1 -1
  31. package/dist/coValues/coMap.d.ts +1 -1
  32. package/dist/coValues/coMap.d.ts.map +1 -1
  33. package/dist/coValues/coMap.js +2 -2
  34. package/dist/coValues/coMap.js.map +1 -1
  35. package/dist/coValues/coStream.d.ts +0 -38
  36. package/dist/coValues/coStream.d.ts.map +1 -1
  37. package/dist/coValues/coStream.js +0 -86
  38. package/dist/coValues/coStream.js.map +1 -1
  39. package/dist/coValues/group.d.ts +44 -6
  40. package/dist/coValues/group.d.ts.map +1 -1
  41. package/dist/coValues/group.js +198 -17
  42. package/dist/coValues/group.js.map +1 -1
  43. package/dist/coreToCoValue.d.ts +2 -1
  44. package/dist/coreToCoValue.d.ts.map +1 -1
  45. package/dist/coreToCoValue.js +2 -1
  46. package/dist/coreToCoValue.js.map +1 -1
  47. package/dist/crypto/NapiCrypto.d.ts +18 -24
  48. package/dist/crypto/NapiCrypto.d.ts.map +1 -1
  49. package/dist/crypto/NapiCrypto.js +98 -60
  50. package/dist/crypto/NapiCrypto.js.map +1 -1
  51. package/dist/crypto/RNCrypto.d.ts +16 -3
  52. package/dist/crypto/RNCrypto.d.ts.map +1 -1
  53. package/dist/crypto/RNCrypto.js +117 -54
  54. package/dist/crypto/RNCrypto.js.map +1 -1
  55. package/dist/crypto/WasmCrypto.d.ts +18 -24
  56. package/dist/crypto/WasmCrypto.d.ts.map +1 -1
  57. package/dist/crypto/WasmCrypto.js +100 -61
  58. package/dist/crypto/WasmCrypto.js.map +1 -1
  59. package/dist/crypto/crypto.d.ts +55 -19
  60. package/dist/crypto/crypto.d.ts.map +1 -1
  61. package/dist/crypto/crypto.js +14 -3
  62. package/dist/crypto/crypto.js.map +1 -1
  63. package/dist/exports.d.ts +7 -3
  64. package/dist/exports.d.ts.map +1 -1
  65. package/dist/exports.js +4 -2
  66. package/dist/exports.js.map +1 -1
  67. package/dist/localNode.d.ts +3 -1
  68. package/dist/localNode.d.ts.map +1 -1
  69. package/dist/localNode.js +10 -3
  70. package/dist/localNode.js.map +1 -1
  71. package/dist/media.d.ts +1 -1
  72. package/dist/media.d.ts.map +1 -1
  73. package/dist/permissions.d.ts +2 -1
  74. package/dist/permissions.d.ts.map +1 -1
  75. package/dist/permissions.js +19 -3
  76. package/dist/permissions.js.map +1 -1
  77. package/dist/storage/sqliteAsync/client.d.ts +24 -12
  78. package/dist/storage/sqliteAsync/client.d.ts.map +1 -1
  79. package/dist/storage/sqliteAsync/client.js +70 -58
  80. package/dist/storage/sqliteAsync/client.js.map +1 -1
  81. package/dist/storage/sqliteAsync/types.d.ts +1 -1
  82. package/dist/storage/sqliteAsync/types.d.ts.map +1 -1
  83. package/dist/storage/types.d.ts +1 -0
  84. package/dist/storage/types.d.ts.map +1 -1
  85. package/dist/sync.d.ts.map +1 -1
  86. package/dist/sync.js +7 -1
  87. package/dist/sync.js.map +1 -1
  88. package/dist/tests/CojsonMessageChannel.test.js +2 -2
  89. package/dist/tests/SQLiteClientAsync.test.d.ts +2 -0
  90. package/dist/tests/SQLiteClientAsync.test.d.ts.map +1 -0
  91. package/dist/tests/SQLiteClientAsync.test.js +64 -0
  92. package/dist/tests/SQLiteClientAsync.test.js.map +1 -0
  93. package/dist/tests/StorageApiAsync.test.js +2 -8
  94. package/dist/tests/StorageApiAsync.test.js.map +1 -1
  95. package/dist/tests/SyncStateManager.test.js +2 -2
  96. package/dist/tests/WasmCrypto.test.js +1 -15
  97. package/dist/tests/WasmCrypto.test.js.map +1 -1
  98. package/dist/tests/coList.test.js +24 -5
  99. package/dist/tests/coList.test.js.map +1 -1
  100. package/dist/tests/coStream.test.js +4 -3
  101. package/dist/tests/coStream.test.js.map +1 -1
  102. package/dist/tests/coValueCore.initTransaction.test.d.ts +2 -0
  103. package/dist/tests/coValueCore.initTransaction.test.d.ts.map +1 -0
  104. package/dist/tests/coValueCore.initTransaction.test.js +438 -0
  105. package/dist/tests/coValueCore.initTransaction.test.js.map +1 -0
  106. package/dist/tests/coValueCore.test.js +11 -19
  107. package/dist/tests/coValueCore.test.js.map +1 -1
  108. package/dist/tests/crypto.test.js +83 -0
  109. package/dist/tests/crypto.test.js.map +1 -1
  110. package/dist/tests/deleteCoValue.test.js +5 -5
  111. package/dist/tests/deleteCoValue.test.js.map +1 -1
  112. package/dist/tests/group.inheritance.test.js +11 -0
  113. package/dist/tests/group.inheritance.test.js.map +1 -1
  114. package/dist/tests/group.test.js +24 -1
  115. package/dist/tests/group.test.js.map +1 -1
  116. package/dist/tests/groupSealer.test.d.ts +2 -0
  117. package/dist/tests/groupSealer.test.d.ts.map +1 -0
  118. package/dist/tests/groupSealer.test.js +913 -0
  119. package/dist/tests/groupSealer.test.js.map +1 -0
  120. package/dist/tests/setup.js +5 -0
  121. package/dist/tests/setup.js.map +1 -1
  122. package/dist/tests/sync.auth.test.js +10 -10
  123. package/dist/tests/sync.concurrentLoad.test.js +12 -12
  124. package/dist/tests/sync.deleted.test.js +8 -8
  125. package/dist/tests/sync.garbageCollection.test.js +10 -10
  126. package/dist/tests/sync.invite.test.js +12 -12
  127. package/dist/tests/sync.known.test.js +2 -2
  128. package/dist/tests/sync.load.test.js +107 -107
  129. package/dist/tests/sync.mesh.test.js +164 -46
  130. package/dist/tests/sync.mesh.test.js.map +1 -1
  131. package/dist/tests/sync.multipleServers.test.js +43 -43
  132. package/dist/tests/sync.peerReconciliation.test.js +29 -29
  133. package/dist/tests/sync.sharding.test.js +3 -3
  134. package/dist/tests/sync.storage.test.js +104 -104
  135. package/dist/tests/sync.storage.test.js.map +1 -1
  136. package/dist/tests/sync.storageAsync.test.js +56 -56
  137. package/dist/tests/sync.upload.test.js +22 -22
  138. package/dist/tests/testStorage.d.ts +2 -0
  139. package/dist/tests/testStorage.d.ts.map +1 -1
  140. package/dist/tests/testStorage.js +30 -6
  141. package/dist/tests/testStorage.js.map +1 -1
  142. package/dist/typeUtils/isCoValue.js +1 -1
  143. package/dist/typeUtils/isCoValue.js.map +1 -1
  144. package/package.json +4 -4
  145. package/src/SyncStateManager.ts +0 -2
  146. package/src/base64url.test.ts +89 -1
  147. package/src/base64url.ts +134 -6
  148. package/src/coValue.ts +2 -1
  149. package/src/coValueCore/coValueCore.ts +126 -84
  150. package/src/coValueCore/verifiedState.ts +335 -53
  151. package/src/coValues/binaryCoStream.ts +217 -0
  152. package/src/coValues/coList.ts +21 -8
  153. package/src/coValues/coMap.ts +3 -0
  154. package/src/coValues/coStream.ts +0 -170
  155. package/src/coValues/group.ts +270 -21
  156. package/src/coreToCoValue.ts +2 -1
  157. package/src/crypto/NapiCrypto.ts +198 -95
  158. package/src/crypto/RNCrypto.ts +229 -102
  159. package/src/crypto/WasmCrypto.ts +201 -95
  160. package/src/crypto/crypto.ts +118 -45
  161. package/src/exports.ts +11 -5
  162. package/src/localNode.ts +17 -1
  163. package/src/media.ts +1 -1
  164. package/src/permissions.ts +30 -7
  165. package/src/storage/sqliteAsync/client.ts +136 -115
  166. package/src/storage/sqliteAsync/types.ts +3 -1
  167. package/src/storage/types.ts +4 -0
  168. package/src/sync.ts +10 -1
  169. package/src/tests/CojsonMessageChannel.test.ts +2 -2
  170. package/src/tests/SQLiteClientAsync.test.ts +75 -0
  171. package/src/tests/StorageApiAsync.test.ts +4 -9
  172. package/src/tests/SyncStateManager.test.ts +2 -2
  173. package/src/tests/WasmCrypto.test.ts +1 -25
  174. package/src/tests/coList.test.ts +39 -5
  175. package/src/tests/coStream.test.ts +4 -5
  176. package/src/tests/coValueCore.initTransaction.test.ts +836 -0
  177. package/src/tests/coValueCore.test.ts +11 -22
  178. package/src/tests/crypto.test.ts +107 -0
  179. package/src/tests/deleteCoValue.test.ts +5 -5
  180. package/src/tests/group.inheritance.test.ts +16 -0
  181. package/src/tests/group.test.ts +29 -1
  182. package/src/tests/groupSealer.test.ts +1473 -0
  183. package/src/tests/setup.ts +6 -0
  184. package/src/tests/sync.auth.test.ts +10 -10
  185. package/src/tests/sync.concurrentLoad.test.ts +12 -12
  186. package/src/tests/sync.deleted.test.ts +8 -8
  187. package/src/tests/sync.garbageCollection.test.ts +10 -10
  188. package/src/tests/sync.invite.test.ts +12 -12
  189. package/src/tests/sync.known.test.ts +2 -2
  190. package/src/tests/sync.load.test.ts +107 -107
  191. package/src/tests/sync.mesh.test.ts +189 -46
  192. package/src/tests/sync.multipleServers.test.ts +43 -43
  193. package/src/tests/sync.peerReconciliation.test.ts +29 -29
  194. package/src/tests/sync.sharding.test.ts +3 -3
  195. package/src/tests/sync.storage.test.ts +104 -104
  196. package/src/tests/sync.storageAsync.test.ts +56 -56
  197. package/src/tests/sync.upload.test.ts +22 -22
  198. package/src/tests/testStorage.ts +39 -9
  199. package/src/typeUtils/isCoValue.ts +1 -1
  200. package/dist/coValueCore/SessionMap.d.ts +0 -55
  201. package/dist/coValueCore/SessionMap.d.ts.map +0 -1
  202. package/dist/coValueCore/SessionMap.js +0 -206
  203. package/dist/coValueCore/SessionMap.js.map +0 -1
  204. package/dist/tests/coreWasm.test.d.ts +0 -2
  205. package/dist/tests/coreWasm.test.d.ts.map +0 -1
  206. package/dist/tests/coreWasm.test.js +0 -203
  207. package/dist/tests/coreWasm.test.js.map +0 -1
  208. package/src/coValueCore/SessionMap.ts +0 -394
  209. package/src/tests/coreWasm.test.ts +0 -452
@@ -49,10 +49,10 @@ describe("client with storage syncs with server", () => {
49
49
  "client -> storage | LOAD Map sessions: empty",
50
50
  "storage -> client | KNOWN Map sessions: empty",
51
51
  "client -> server | LOAD Map sessions: empty",
52
- "server -> client | CONTENT Group header: true new: After: 0 New: 3",
52
+ "server -> client | CONTENT Group header: true new: After: 0 New: 4",
53
53
  "server -> client | CONTENT Map header: true new: After: 0 New: 1",
54
- "client -> server | KNOWN Group sessions: header/3",
55
- "client -> storage | CONTENT Group header: true new: After: 0 New: 3",
54
+ "client -> server | KNOWN Group sessions: header/4",
55
+ "client -> storage | CONTENT Group header: true new: After: 0 New: 4",
56
56
  "client -> server | KNOWN Map sessions: header/1",
57
57
  "client -> storage | CONTENT Map header: true new: After: 0 New: 1",
58
58
  ]
@@ -93,8 +93,8 @@ describe("client with storage syncs with server", () => {
93
93
  ).toMatchInlineSnapshot(`
94
94
  [
95
95
  "client -> storage | LOAD Map sessions: empty",
96
- "storage -> client | CONTENT Group header: true new: After: 0 New: 3",
97
- "client -> server | LOAD Group sessions: header/3",
96
+ "storage -> client | CONTENT Group header: true new: After: 0 New: 4",
97
+ "client -> server | LOAD Group sessions: header/4",
98
98
  "storage -> client | CONTENT Map header: true new: After: 0 New: 1",
99
99
  "client -> server | LOAD Map sessions: header/1",
100
100
  ]
@@ -130,13 +130,13 @@ describe("client with storage syncs with server", () => {
130
130
  "client -> storage | LOAD Map sessions: empty",
131
131
  "storage -> client | KNOWN Map sessions: empty",
132
132
  "client -> server | LOAD Map sessions: empty",
133
- "server -> client | CONTENT ParentGroup header: true new: After: 0 New: 5",
134
- "server -> client | CONTENT Group header: true new: After: 0 New: 5",
133
+ "server -> client | CONTENT ParentGroup header: true new: After: 0 New: 6",
134
+ "server -> client | CONTENT Group header: true new: After: 0 New: 6",
135
135
  "server -> client | CONTENT Map header: true new: After: 0 New: 1",
136
- "client -> server | KNOWN ParentGroup sessions: header/5",
137
- "client -> storage | CONTENT ParentGroup header: true new: After: 0 New: 5",
138
- "client -> server | KNOWN Group sessions: header/5",
139
- "client -> storage | CONTENT Group header: true new: After: 0 New: 5",
136
+ "client -> server | KNOWN ParentGroup sessions: header/6",
137
+ "client -> storage | CONTENT ParentGroup header: true new: After: 0 New: 6",
138
+ "client -> server | KNOWN Group sessions: header/6",
139
+ "client -> storage | CONTENT Group header: true new: After: 0 New: 6",
140
140
  "client -> server | KNOWN Map sessions: header/1",
141
141
  "client -> storage | CONTENT Map header: true new: After: 0 New: 1",
142
142
  ]
@@ -176,10 +176,10 @@ describe("client with storage syncs with server", () => {
176
176
  }),
177
177
  ).toMatchInlineSnapshot(`
178
178
  [
179
- "client -> server | LOAD Group sessions: header/3",
179
+ "client -> server | LOAD Group sessions: header/4",
180
180
  "client -> server | LOAD Map sessions: header/1",
181
181
  "server -> client | CONTENT Map header: false new: After: 1 New: 1",
182
- "server -> client | KNOWN Group sessions: header/3",
182
+ "server -> client | KNOWN Group sessions: header/4",
183
183
  "server -> client | CONTENT Map header: false new: After: 1 New: 1",
184
184
  "client -> server | KNOWN Map sessions: header/2",
185
185
  "client -> storage | CONTENT Map header: false new: After: 1 New: 1",
@@ -210,7 +210,7 @@ describe("client with storage syncs with server", () => {
210
210
  }),
211
211
  ).toMatchInlineSnapshot(`
212
212
  [
213
- "client -> storage | CONTENT Group header: true new: After: 0 New: 3",
213
+ "client -> storage | CONTENT Group header: true new: After: 0 New: 4",
214
214
  "client -> storage | CONTENT InitialMap header: true new: ",
215
215
  "client -> storage | CONTENT ChildMap header: true new: After: 0 New: 1",
216
216
  "client -> storage | CONTENT InitialMap header: false new: After: 0 New: 1",
@@ -253,10 +253,10 @@ describe("client syncs with a server with storage", () => {
253
253
  }),
254
254
  ).toMatchInlineSnapshot(`
255
255
  [
256
- "client -> server | CONTENT Group header: true new: After: 0 New: 3",
256
+ "client -> server | CONTENT Group header: true new: After: 0 New: 4",
257
257
  "client -> server | CONTENT Map header: true new: After: 0 New: 1",
258
- "server -> client | KNOWN Group sessions: header/3",
259
- "server -> storage | CONTENT Group header: true new: After: 0 New: 3",
258
+ "server -> client | KNOWN Group sessions: header/4",
259
+ "server -> storage | CONTENT Group header: true new: After: 0 New: 4",
260
260
  "server -> client | KNOWN Map sessions: header/1",
261
261
  "server -> storage | CONTENT Map header: true new: After: 0 New: 1",
262
262
  ]
@@ -290,16 +290,16 @@ describe("client syncs with a server with storage", () => {
290
290
  }),
291
291
  ).toMatchInlineSnapshot(`
292
292
  [
293
- "client -> storage | CONTENT Group header: true new: After: 0 New: 5",
294
- "client -> server | CONTENT Group header: true new: After: 0 New: 5",
293
+ "client -> storage | CONTENT Group header: true new: After: 0 New: 6",
294
+ "client -> server | CONTENT Group header: true new: After: 0 New: 6",
295
295
  "client -> storage | CONTENT Map header: true new: After: 0 New: 73 expectContentUntil: header/200",
296
296
  "client -> server | CONTENT Map header: true new: After: 0 New: 73 expectContentUntil: header/200",
297
297
  "client -> storage | CONTENT Map header: false new: After: 73 New: 73",
298
298
  "client -> server | CONTENT Map header: false new: After: 73 New: 73",
299
299
  "client -> storage | CONTENT Map header: false new: After: 146 New: 54",
300
300
  "client -> server | CONTENT Map header: false new: After: 146 New: 54",
301
- "server -> client | KNOWN Group sessions: header/5",
302
- "server -> storage | CONTENT Group header: true new: After: 0 New: 5",
301
+ "server -> client | KNOWN Group sessions: header/6",
302
+ "server -> storage | CONTENT Group header: true new: After: 0 New: 6",
303
303
  "server -> client | KNOWN Map sessions: header/73",
304
304
  "server -> storage | CONTENT Map header: true new: After: 0 New: 73",
305
305
  "server -> client | KNOWN Map sessions: header/146",
@@ -335,13 +335,13 @@ describe("client syncs with a server with storage", () => {
335
335
  ).toMatchInlineSnapshot(`
336
336
  [
337
337
  "client -> storage | LOAD Map sessions: empty",
338
- "storage -> client | CONTENT Group header: true new: After: 0 New: 5",
339
- "client -> server | LOAD Group sessions: header/5",
338
+ "storage -> client | CONTENT Group header: true new: After: 0 New: 6",
339
+ "client -> server | LOAD Group sessions: header/6",
340
340
  "storage -> client | CONTENT Map header: true new: After: 0 New: 73 expectContentUntil: header/200",
341
341
  "client -> server | LOAD Map sessions: header/200",
342
342
  "storage -> client | CONTENT Map header: true new: After: 73 New: 73",
343
343
  "storage -> client | CONTENT Map header: true new: After: 146 New: 54",
344
- "server -> client | KNOWN Group sessions: header/5",
344
+ "server -> client | KNOWN Group sessions: header/6",
345
345
  "server -> client | KNOWN Map sessions: header/200",
346
346
  ]
347
347
  `);
@@ -449,8 +449,8 @@ describe("client syncs with a server with storage", () => {
449
449
  ).toMatchInlineSnapshot(`
450
450
  [
451
451
  "client -> storage | LOAD Map sessions: empty",
452
- "storage -> client | CONTENT Group header: true new: After: 0 New: 5",
453
- "client -> server | LOAD Group sessions: header/5",
452
+ "storage -> client | CONTENT Group header: true new: After: 0 New: 6",
453
+ "client -> server | LOAD Group sessions: header/6",
454
454
  "storage -> client | CONTENT Map header: true new: After: 0 New: 73 expectContentUntil: header/603",
455
455
  "client -> server | LOAD Map sessions: header/603",
456
456
  "storage -> client | CONTENT Map header: true new: After: 73 New: 73",
@@ -462,7 +462,7 @@ describe("client syncs with a server with storage", () => {
462
462
  "storage -> client | CONTENT Map header: true new: After: 73 New: 73",
463
463
  "storage -> client | CONTENT Map header: true new: After: 146 New: 54",
464
464
  "storage -> client | CONTENT Map header: true new: After: 0 New: 1",
465
- "server -> client | KNOWN Group sessions: header/5",
465
+ "server -> client | KNOWN Group sessions: header/6",
466
466
  "server -> client | KNOWN Map sessions: header/292",
467
467
  "client -> server | CONTENT Map header: false new: After: 146 New: 54 | After: 0 New: 1 | After: 146 New: 54 expectContentUntil: header/603",
468
468
  "client -> server | CONTENT Map header: false new: After: 0 New: 73",
@@ -598,8 +598,8 @@ describe("client syncs with a server with storage", () => {
598
598
  ).toMatchInlineSnapshot(`
599
599
  [
600
600
  "client -> storage | LOAD Map sessions: empty",
601
- "storage -> client | CONTENT Group header: true new: After: 0 New: 5",
602
- "client -> server | LOAD Group sessions: header/5",
601
+ "storage -> client | CONTENT Group header: true new: After: 0 New: 6",
602
+ "client -> server | LOAD Group sessions: header/6",
603
603
  "storage -> client | CONTENT Map header: true new: After: 0 New: 73 expectContentUntil: header/200",
604
604
  "client -> server | LOAD Map sessions: header/200",
605
605
  "storage -> client | CONTENT Map header: true new: After: 73 New: 73",
@@ -677,25 +677,25 @@ describe("client syncs with a server with storage", () => {
677
677
  }),
678
678
  ).toMatchInlineSnapshot(`
679
679
  [
680
- "client -> server | CONTENT ParentGroup header: true new: After: 0 New: 3",
681
- "client -> server | CONTENT Group header: true new: After: 0 New: 5",
680
+ "client -> server | CONTENT ParentGroup header: true new: After: 0 New: 4",
681
+ "client -> server | CONTENT Group header: true new: After: 0 New: 6",
682
682
  "client -> server | CONTENT Map header: true new: ",
683
- "client -> server | CONTENT ParentGroup header: false new: After: 3 New: 73 expectContentUntil: header/205",
684
- "client -> server | CONTENT ParentGroup header: false new: After: 76 New: 73",
685
- "client -> server | CONTENT ParentGroup header: false new: After: 149 New: 56",
683
+ "client -> server | CONTENT ParentGroup header: false new: After: 4 New: 73 expectContentUntil: header/206",
684
+ "client -> server | CONTENT ParentGroup header: false new: After: 77 New: 73",
685
+ "client -> server | CONTENT ParentGroup header: false new: After: 150 New: 56",
686
686
  "client -> server | CONTENT Map header: false new: After: 0 New: 1",
687
- "server -> client | KNOWN ParentGroup sessions: header/3",
688
- "syncServer -> storage | CONTENT ParentGroup header: true new: After: 0 New: 3",
689
- "server -> client | KNOWN Group sessions: header/5",
690
- "syncServer -> storage | CONTENT Group header: true new: After: 0 New: 5",
687
+ "server -> client | KNOWN ParentGroup sessions: header/4",
688
+ "syncServer -> storage | CONTENT ParentGroup header: true new: After: 0 New: 4",
689
+ "server -> client | KNOWN Group sessions: header/6",
690
+ "syncServer -> storage | CONTENT Group header: true new: After: 0 New: 6",
691
691
  "server -> client | KNOWN Map sessions: header/0",
692
692
  "syncServer -> storage | CONTENT Map header: true new: ",
693
- "server -> client | KNOWN ParentGroup sessions: header/76",
694
- "syncServer -> storage | CONTENT ParentGroup header: false new: After: 3 New: 73",
695
- "server -> client | KNOWN ParentGroup sessions: header/149",
696
- "syncServer -> storage | CONTENT ParentGroup header: false new: After: 76 New: 73",
697
- "server -> client | KNOWN ParentGroup sessions: header/205",
698
- "syncServer -> storage | CONTENT ParentGroup header: false new: After: 149 New: 56",
693
+ "server -> client | KNOWN ParentGroup sessions: header/77",
694
+ "syncServer -> storage | CONTENT ParentGroup header: false new: After: 4 New: 73",
695
+ "server -> client | KNOWN ParentGroup sessions: header/150",
696
+ "syncServer -> storage | CONTENT ParentGroup header: false new: After: 77 New: 73",
697
+ "server -> client | KNOWN ParentGroup sessions: header/206",
698
+ "syncServer -> storage | CONTENT ParentGroup header: false new: After: 150 New: 56",
699
699
  "server -> client | KNOWN Map sessions: header/1",
700
700
  "syncServer -> storage | CONTENT Map header: false new: After: 0 New: 1",
701
701
  ]
@@ -729,20 +729,20 @@ describe("client syncs with a server with storage", () => {
729
729
  [
730
730
  "bob -> server | LOAD Map sessions: empty",
731
731
  "syncServer -> storage | LOAD Map sessions: empty",
732
- "storage -> syncServer | CONTENT ParentGroup header: true new: After: 0 New: 76 expectContentUntil: header/205",
733
- "storage -> syncServer | CONTENT ParentGroup header: true new: After: 76 New: 73",
734
- "storage -> syncServer | CONTENT ParentGroup header: true new: After: 149 New: 56",
735
- "storage -> syncServer | CONTENT Group header: true new: After: 0 New: 5",
732
+ "storage -> syncServer | CONTENT ParentGroup header: true new: After: 0 New: 77 expectContentUntil: header/206",
733
+ "storage -> syncServer | CONTENT ParentGroup header: true new: After: 77 New: 73",
734
+ "storage -> syncServer | CONTENT ParentGroup header: true new: After: 150 New: 56",
735
+ "storage -> syncServer | CONTENT Group header: true new: After: 0 New: 6",
736
736
  "storage -> syncServer | CONTENT Map header: true new: After: 0 New: 1",
737
- "server -> bob | CONTENT ParentGroup header: true new: After: 0 New: 76 expectContentUntil: header/205",
738
- "server -> bob | CONTENT ParentGroup header: false new: After: 76 New: 73",
739
- "server -> bob | CONTENT ParentGroup header: false new: After: 149 New: 56",
740
- "server -> bob | CONTENT Group header: true new: After: 0 New: 5",
737
+ "server -> bob | CONTENT ParentGroup header: true new: After: 0 New: 77 expectContentUntil: header/206",
738
+ "server -> bob | CONTENT ParentGroup header: false new: After: 77 New: 73",
739
+ "server -> bob | CONTENT ParentGroup header: false new: After: 150 New: 56",
740
+ "server -> bob | CONTENT Group header: true new: After: 0 New: 6",
741
741
  "server -> bob | CONTENT Map header: true new: After: 0 New: 1",
742
- "bob -> server | KNOWN ParentGroup sessions: header/76",
743
- "bob -> server | KNOWN ParentGroup sessions: header/149",
744
- "bob -> server | KNOWN ParentGroup sessions: header/205",
745
- "bob -> server | KNOWN Group sessions: header/5",
742
+ "bob -> server | KNOWN ParentGroup sessions: header/77",
743
+ "bob -> server | KNOWN ParentGroup sessions: header/150",
744
+ "bob -> server | KNOWN ParentGroup sessions: header/206",
745
+ "bob -> server | KNOWN Group sessions: header/6",
746
746
  "bob -> server | KNOWN Map sessions: header/1",
747
747
  ]
748
748
  `);
@@ -45,9 +45,9 @@ describe("client to server upload", () => {
45
45
  }),
46
46
  ).toMatchInlineSnapshot(`
47
47
  [
48
- "client -> server | CONTENT Group header: true new: After: 0 New: 3",
48
+ "client -> server | CONTENT Group header: true new: After: 0 New: 4",
49
49
  "client -> server | CONTENT Map header: true new: After: 0 New: 1",
50
- "server -> client | KNOWN Group sessions: header/3",
50
+ "server -> client | KNOWN Group sessions: header/4",
51
51
  "server -> client | KNOWN Map sessions: header/1",
52
52
  ]
53
53
  `);
@@ -89,9 +89,9 @@ describe("client to server upload", () => {
89
89
  ).toMatchInlineSnapshot(`
90
90
  [
91
91
  "client -> server | LOAD Map sessions: empty",
92
- "server -> client | CONTENT Group header: true new: After: 0 New: 5",
92
+ "server -> client | CONTENT Group header: true new: After: 0 New: 6",
93
93
  "server -> client | CONTENT Map header: true new: After: 0 New: 2",
94
- "client -> server | KNOWN Group sessions: header/5",
94
+ "client -> server | KNOWN Group sessions: header/6",
95
95
  "client -> server | KNOWN Map sessions: header/2",
96
96
  "client -> server | CONTENT Branch header: true new: After: 0 New: 1",
97
97
  "client -> server | CONTENT Map header: false new: After: 0 New: 1",
@@ -129,9 +129,9 @@ describe("client to server upload", () => {
129
129
  }),
130
130
  ).toMatchInlineSnapshot(`
131
131
  [
132
- "client -> server | CONTENT Group header: true new: After: 0 New: 3",
132
+ "client -> server | CONTENT Group header: true new: After: 0 New: 4",
133
133
  "client -> server | CONTENT Map header: true new: After: 0 New: 1",
134
- "server -> client | KNOWN Group sessions: header/3",
134
+ "server -> client | KNOWN Group sessions: header/4",
135
135
  "server -> client | KNOWN Map sessions: header/1",
136
136
  ]
137
137
  `);
@@ -164,13 +164,13 @@ describe("client to server upload", () => {
164
164
  }),
165
165
  ).toMatchInlineSnapshot(`
166
166
  [
167
- "client -> server | CONTENT Group header: true new: After: 0 New: 3",
168
- "client -> server | CONTENT ParentGroup header: true new: After: 0 New: 5",
169
- "client -> server | CONTENT Group header: false new: After: 3 New: 2",
167
+ "client -> server | CONTENT Group header: true new: After: 0 New: 4",
168
+ "client -> server | CONTENT ParentGroup header: true new: After: 0 New: 6",
169
+ "client -> server | CONTENT Group header: false new: After: 4 New: 2",
170
170
  "client -> server | CONTENT Map header: true new: After: 0 New: 1",
171
- "server -> client | KNOWN Group sessions: header/3",
172
- "server -> client | KNOWN ParentGroup sessions: header/5",
173
- "server -> client | KNOWN Group sessions: header/5",
171
+ "server -> client | KNOWN Group sessions: header/4",
172
+ "server -> client | KNOWN ParentGroup sessions: header/6",
173
+ "server -> client | KNOWN Group sessions: header/6",
174
174
  "server -> client | KNOWN Map sessions: header/1",
175
175
  ]
176
176
  `);
@@ -204,9 +204,9 @@ describe("client to server upload", () => {
204
204
  }),
205
205
  ).toMatchInlineSnapshot(`
206
206
  [
207
- "client -> server | CONTENT Group header: true new: After: 0 New: 3",
207
+ "client -> server | CONTENT Group header: true new: After: 0 New: 4",
208
208
  "client -> server | CONTENT Map header: true new: After: 0 New: 1",
209
- "server -> client | KNOWN Group sessions: header/3",
209
+ "server -> client | KNOWN Group sessions: header/4",
210
210
  "server -> client | KNOWN Map sessions: header/1",
211
211
  "client -> server | CONTENT Map header: false new: After: 1 New: 1",
212
212
  "server -> client | KNOWN Map sessions: header/2",
@@ -249,9 +249,9 @@ describe("client to server upload", () => {
249
249
  }),
250
250
  ).toMatchInlineSnapshot(`
251
251
  [
252
- "client -> server | CONTENT Group header: true new: After: 0 New: 5",
252
+ "client -> server | CONTENT Group header: true new: After: 0 New: 6",
253
253
  "client -> server | CONTENT Map header: true new: After: 0 New: 1",
254
- "server -> client | KNOWN Group sessions: header/5",
254
+ "server -> client | KNOWN Group sessions: header/6",
255
255
  "server -> client | KNOWN Map sessions: header/1",
256
256
  "client -> server | CONTENT Map header: false new: After: 1 New: 1",
257
257
  "server -> client | KNOWN CORRECTION Map sessions: empty",
@@ -363,11 +363,11 @@ describe("client to server upload", () => {
363
363
  }),
364
364
  ).toMatchInlineSnapshot(`
365
365
  [
366
- "client -> server | CONTENT Group header: true new: After: 0 New: 3",
366
+ "client -> server | CONTENT Group header: true new: After: 0 New: 4",
367
367
  "client -> server | CONTENT InitialMap header: true new: ",
368
368
  "client -> server | CONTENT ChildMap header: true new: After: 0 New: 1",
369
369
  "client -> server | CONTENT InitialMap header: false new: After: 0 New: 1",
370
- "server -> client | KNOWN Group sessions: header/3",
370
+ "server -> client | KNOWN Group sessions: header/4",
371
371
  "server -> client | KNOWN InitialMap sessions: header/0",
372
372
  "server -> client | KNOWN ChildMap sessions: header/1",
373
373
  "server -> client | KNOWN InitialMap sessions: header/1",
@@ -396,11 +396,11 @@ describe("client to server upload", () => {
396
396
  }),
397
397
  ).toMatchInlineSnapshot(`
398
398
  [
399
- "client -> server | CONTENT Group header: true new: After: 0 New: 5",
399
+ "client -> server | CONTENT Group header: true new: After: 0 New: 6",
400
400
  "client -> server | CONTENT Map header: true new: After: 0 New: 73 expectContentUntil: header/200",
401
401
  "client -> server | CONTENT Map header: false new: After: 73 New: 73",
402
402
  "client -> server | CONTENT Map header: false new: After: 146 New: 54",
403
- "server -> client | KNOWN Group sessions: header/5",
403
+ "server -> client | KNOWN Group sessions: header/6",
404
404
  "server -> client | KNOWN Map sessions: header/73",
405
405
  "server -> client | KNOWN Map sessions: header/146",
406
406
  "server -> client | KNOWN Map sessions: header/200",
@@ -431,12 +431,12 @@ describe("client to server upload", () => {
431
431
  }),
432
432
  ).toMatchInlineSnapshot(`
433
433
  [
434
- "client -> server | CONTENT Group header: true new: After: 0 New: 5",
434
+ "client -> server | CONTENT Group header: true new: After: 0 New: 6",
435
435
  "client -> server | CONTENT Map header: true new: ",
436
436
  "client -> server | CONTENT Map header: false new: After: 0 New: 73 expectContentUntil: header/200",
437
437
  "client -> server | CONTENT Map header: false new: After: 73 New: 73",
438
438
  "client -> server | CONTENT Map header: false new: After: 146 New: 54",
439
- "server -> client | KNOWN Group sessions: header/5",
439
+ "server -> client | KNOWN Group sessions: header/6",
440
440
  "server -> client | KNOWN Map sessions: header/0",
441
441
  "server -> client | KNOWN Map sessions: header/73",
442
442
  "server -> client | KNOWN Map sessions: header/146",
@@ -11,7 +11,7 @@ import {
11
11
  SQLiteDatabaseDriverAsync,
12
12
  getSqliteStorageAsync,
13
13
  } from "../storage/sqliteAsync";
14
- import { SyncMessagesLog, SyncTestMessage } from "./testUtils";
14
+ import { SyncMessagesLog } from "./testUtils";
15
15
  import { knownStateFromContent } from "../coValueContentMessage";
16
16
 
17
17
  class LibSQLSqliteAsyncDriver implements SQLiteDatabaseDriverAsync {
@@ -37,14 +37,15 @@ class LibSQLSqliteAsyncDriver implements SQLiteDatabaseDriverAsync {
37
37
  return this.db.prepare(sql).get(params) as T | undefined;
38
38
  }
39
39
 
40
- async transaction(callback: () => unknown) {
40
+ async transaction(callback: (tx: LibSQLSqliteAsyncDriver) => unknown) {
41
41
  await this.run("BEGIN TRANSACTION", []);
42
42
 
43
43
  try {
44
- await callback();
44
+ await callback(this);
45
45
  await this.run("COMMIT", []);
46
46
  } catch (error) {
47
47
  await this.run("ROLLBACK", []);
48
+ throw error;
48
49
  }
49
50
  }
50
51
 
@@ -92,14 +93,41 @@ class LibSQLSqliteSyncDriver implements SQLiteDatabaseDriver {
92
93
  }
93
94
  }
94
95
 
95
- function deleteDb(dbPath: string) {
96
+ /** Cleanup functions registered by createAsyncStorage/createSyncStorage; run by the runner hook (registered first so it runs last). */
97
+ const storageCleanupFns: Array<() => void | Promise<void>> = [];
98
+
99
+ function registerStorageCleanup(fn: () => void | Promise<void>): void {
100
+ storageCleanupFns.push(fn);
101
+ }
102
+
103
+ /** Call from beforeEach so this hook is registered first and thus runs last (LIFO), after node shutdown hooks. */
104
+ export function registerStorageCleanupRunner(): void {
105
+ // Clear cleanup functions from previous test
106
+ storageCleanupFns.length = 0;
107
+ onTestFinished(async () => {
108
+ for (const fn of storageCleanupFns) {
109
+ await fn();
110
+ }
111
+ });
112
+ }
113
+
114
+ function unlinkIfExists(path: string): void {
96
115
  try {
97
- unlinkSync(dbPath);
98
- } catch (error) {
99
- console.error(error);
116
+ unlinkSync(path);
117
+ } catch (error: unknown) {
118
+ const err = error as NodeJS.ErrnoException;
119
+ if (err?.code !== "ENOENT") {
120
+ console.error(error);
121
+ }
100
122
  }
101
123
  }
102
124
 
125
+ function deleteDb(dbPath: string): void {
126
+ unlinkIfExists(dbPath);
127
+ unlinkIfExists(`${dbPath}-wal`);
128
+ unlinkIfExists(`${dbPath}-shm`);
129
+ }
130
+
103
131
  export async function createAsyncStorage({
104
132
  filename,
105
133
  nodeName = "client",
@@ -110,11 +138,12 @@ export async function createAsyncStorage({
110
138
  storageName: string;
111
139
  }) {
112
140
  const dbPath = getDbPath(filename);
141
+
113
142
  const storage = await getSqliteStorageAsync(
114
143
  new LibSQLSqliteAsyncDriver(dbPath),
115
144
  );
116
145
 
117
- onTestFinished(async () => {
146
+ registerStorageCleanup(async () => {
118
147
  await storage.close();
119
148
  deleteDb(dbPath);
120
149
  });
@@ -134,11 +163,12 @@ export function createSyncStorage({
134
163
  storageName: string;
135
164
  }) {
136
165
  const dbPath = getDbPath(filename);
166
+
137
167
  const storage = getSqliteStorage(
138
168
  new LibSQLSqliteSyncDriver(getDbPath(filename)),
139
169
  );
140
170
 
141
- onTestFinished(() => {
171
+ registerStorageCleanup(() => {
142
172
  storage.close();
143
173
  deleteDb(dbPath);
144
174
  });
@@ -2,7 +2,7 @@ import { type RawCoValue } from "../coValue.js";
2
2
  import { RawCoList } from "../coValues/coList.js";
3
3
  import { RawCoMap } from "../coValues/coMap.js";
4
4
  import { RawCoStream } from "../coValues/coStream.js";
5
- import { RawBinaryCoStream } from "../coValues/coStream.js";
5
+ import { RawBinaryCoStream } from "../coValues/binaryCoStream.js";
6
6
  import type { JsonValue } from "../jsonValue.js";
7
7
 
8
8
  export function isCoValue(
@@ -1,55 +0,0 @@
1
- import { ControlledAccountOrAgent } from "../coValues/account.js";
2
- import type { CryptoProvider, KeyID, KeySecret, SessionLogImpl, Signature, SignerID } from "../crypto/crypto.js";
3
- import { RawCoID, SessionID } from "../ids.js";
4
- import { JsonObject, JsonValue } from "../jsonValue.js";
5
- import { Transaction } from "./verifiedState.js";
6
- import { CoValueKnownState, KnownStateSessions } from "../knownState.js";
7
- export type SessionLog = {
8
- signerID?: SignerID;
9
- impl: SessionLogImpl;
10
- transactions: Transaction[];
11
- lastSignature: Signature | undefined;
12
- signatureAfter: {
13
- [txIdx: number]: Signature | undefined;
14
- };
15
- txSizeSinceLastInbetweenSignature: number;
16
- sessionID: SessionID;
17
- };
18
- export declare class SessionMap {
19
- private readonly id;
20
- private readonly crypto;
21
- private isDeleted;
22
- sessions: Map<SessionID, SessionLog>;
23
- knownState: CoValueKnownState;
24
- knownStateWithStreaming: CoValueKnownState | undefined;
25
- private immutableKnownState;
26
- private immutableKnownStateWithStreaming;
27
- streamingKnownState?: KnownStateSessions;
28
- constructor(id: RawCoID, crypto: CryptoProvider, streamingKnownState?: KnownStateSessions);
29
- markAsDeleted(): void;
30
- setStreamingKnownState(streamingKnownState: KnownStateSessions): void;
31
- invalidateKnownStateCache(): void;
32
- getImmutableKnownState(): CoValueKnownState;
33
- getImmutableKnownStateWithStreaming(): CoValueKnownState;
34
- get(sessionID: SessionID): SessionLog | undefined;
35
- private getOrCreateSessionLog;
36
- signerID: SignerID | undefined;
37
- addTransaction(sessionID: SessionID, signerID: SignerID | undefined, newTransactions: Transaction[], newSignature: Signature, skipVerify?: boolean): void;
38
- makeNewPrivateTransaction(sessionID: SessionID, signerAgent: ControlledAccountOrAgent, changes: JsonValue[], keyID: KeyID, keySecret: KeySecret, meta: JsonObject | undefined, madeAt: number): {
39
- signature: Signature;
40
- transaction: Transaction;
41
- };
42
- makeNewTrustingTransaction(sessionID: SessionID, signerAgent: ControlledAccountOrAgent, changes: JsonValue[], meta: JsonObject | undefined, madeAt: number): {
43
- signature: Signature;
44
- transaction: Transaction;
45
- };
46
- private addTransactionsToJsLog;
47
- decryptTransaction(sessionID: SessionID, txIndex: number, keySecret: KeySecret): JsonValue[] | undefined;
48
- decryptTransactionMeta(sessionID: SessionID, txIndex: number, keySecret: KeySecret): JsonObject | undefined;
49
- get size(): number;
50
- entries(): MapIterator<[SessionID, SessionLog]>;
51
- values(): MapIterator<SessionLog>;
52
- keys(): MapIterator<SessionID>;
53
- clone(): SessionMap;
54
- }
55
- //# sourceMappingURL=SessionMap.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"SessionMap.d.ts","sourceRoot":"","sources":["../../src/coValueCore/SessionMap.ts"],"names":[],"mappings":"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"}