cojson 0.15.8 → 0.15.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 (218) hide show
  1. package/.turbo/turbo-build.log +1 -1
  2. package/CHANGELOG.md +12 -0
  3. package/dist/IncomingMessagesQueue.d.ts +27 -0
  4. package/dist/IncomingMessagesQueue.d.ts.map +1 -0
  5. package/dist/IncomingMessagesQueue.js +114 -0
  6. package/dist/IncomingMessagesQueue.js.map +1 -0
  7. package/dist/PeerState.d.ts +2 -10
  8. package/dist/PeerState.d.ts.map +1 -1
  9. package/dist/PeerState.js +9 -90
  10. package/dist/PeerState.js.map +1 -1
  11. package/dist/PriorityBasedMessageQueue.d.ts +2 -1
  12. package/dist/PriorityBasedMessageQueue.d.ts.map +1 -1
  13. package/dist/PriorityBasedMessageQueue.js +9 -6
  14. package/dist/PriorityBasedMessageQueue.js.map +1 -1
  15. package/dist/SyncStateManager.d.ts +1 -0
  16. package/dist/SyncStateManager.d.ts.map +1 -1
  17. package/dist/SyncStateManager.js +1 -1
  18. package/dist/SyncStateManager.js.map +1 -1
  19. package/dist/coValue.d.ts +1 -1
  20. package/dist/coValueCore/coValueCore.d.ts +9 -17
  21. package/dist/coValueCore/coValueCore.d.ts.map +1 -1
  22. package/dist/coValueCore/coValueCore.js +75 -50
  23. package/dist/coValueCore/coValueCore.js.map +1 -1
  24. package/dist/coValueCore/verifiedState.d.ts +10 -3
  25. package/dist/coValueCore/verifiedState.d.ts.map +1 -1
  26. package/dist/coValueCore/verifiedState.js +73 -14
  27. package/dist/coValueCore/verifiedState.js.map +1 -1
  28. package/dist/coValues/coMap.d.ts +3 -3
  29. package/dist/coValues/coStream.d.ts +2 -2
  30. package/dist/coValues/group.d.ts +1 -1
  31. package/dist/coValues/group.d.ts.map +1 -1
  32. package/dist/coValues/group.js +2 -4
  33. package/dist/coValues/group.js.map +1 -1
  34. package/dist/config.d.ts +19 -0
  35. package/dist/config.d.ts.map +1 -0
  36. package/dist/config.js +23 -0
  37. package/dist/config.js.map +1 -0
  38. package/dist/crypto/WasmCrypto.d.ts.map +1 -1
  39. package/dist/crypto/WasmCrypto.js +2 -1
  40. package/dist/crypto/WasmCrypto.js.map +1 -1
  41. package/dist/exports.d.ts +18 -7
  42. package/dist/exports.d.ts.map +1 -1
  43. package/dist/exports.js +11 -8
  44. package/dist/exports.js.map +1 -1
  45. package/dist/localNode.d.ts +8 -2
  46. package/dist/localNode.d.ts.map +1 -1
  47. package/dist/localNode.js +19 -12
  48. package/dist/localNode.js.map +1 -1
  49. package/dist/storage/StoreQueue.d.ts +15 -0
  50. package/dist/storage/StoreQueue.d.ts.map +1 -0
  51. package/dist/storage/StoreQueue.js +35 -0
  52. package/dist/storage/StoreQueue.js.map +1 -0
  53. package/dist/storage/index.d.ts +6 -0
  54. package/dist/storage/index.d.ts.map +1 -0
  55. package/dist/storage/index.js +6 -0
  56. package/dist/storage/index.js.map +1 -0
  57. package/dist/storage/knownState.d.ts +18 -0
  58. package/dist/storage/knownState.d.ts.map +1 -0
  59. package/dist/storage/knownState.js +63 -0
  60. package/dist/storage/knownState.js.map +1 -0
  61. package/dist/storage/sqlite/client.d.ts +37 -0
  62. package/dist/storage/sqlite/client.d.ts.map +1 -0
  63. package/dist/storage/sqlite/client.js +89 -0
  64. package/dist/storage/sqlite/client.js.map +1 -0
  65. package/dist/storage/sqlite/index.d.ts +5 -0
  66. package/dist/storage/sqlite/index.d.ts.map +1 -0
  67. package/dist/storage/sqlite/index.js +13 -0
  68. package/dist/storage/sqlite/index.js.map +1 -0
  69. package/dist/storage/sqlite/sqliteMigrations.d.ts +3 -0
  70. package/dist/storage/sqlite/sqliteMigrations.d.ts.map +1 -0
  71. package/dist/storage/sqlite/sqliteMigrations.js +44 -0
  72. package/dist/storage/sqlite/sqliteMigrations.js.map +1 -0
  73. package/dist/storage/sqlite/types.d.ts +8 -0
  74. package/dist/storage/sqlite/types.d.ts.map +1 -0
  75. package/dist/storage/sqlite/types.js +2 -0
  76. package/dist/storage/sqlite/types.js.map +1 -0
  77. package/dist/storage/sqliteAsync/client.d.ts +37 -0
  78. package/dist/storage/sqliteAsync/client.d.ts.map +1 -0
  79. package/dist/storage/sqliteAsync/client.js +88 -0
  80. package/dist/storage/sqliteAsync/client.js.map +1 -0
  81. package/dist/storage/sqliteAsync/index.d.ts +6 -0
  82. package/dist/storage/sqliteAsync/index.d.ts.map +1 -0
  83. package/dist/storage/sqliteAsync/index.js +15 -0
  84. package/dist/storage/sqliteAsync/index.js.map +1 -0
  85. package/dist/storage/sqliteAsync/types.d.ts +9 -0
  86. package/dist/storage/sqliteAsync/types.d.ts.map +1 -0
  87. package/dist/storage/sqliteAsync/types.js +2 -0
  88. package/dist/storage/sqliteAsync/types.js.map +1 -0
  89. package/dist/storage/storageAsync.d.ts +22 -0
  90. package/dist/storage/storageAsync.d.ts.map +1 -0
  91. package/dist/storage/storageAsync.js +214 -0
  92. package/dist/storage/storageAsync.js.map +1 -0
  93. package/dist/storage/storageSync.d.ts +21 -0
  94. package/dist/storage/storageSync.d.ts.map +1 -0
  95. package/dist/storage/storageSync.js +206 -0
  96. package/dist/storage/storageSync.js.map +1 -0
  97. package/dist/storage/syncUtils.d.ts +13 -0
  98. package/dist/storage/syncUtils.d.ts.map +1 -0
  99. package/dist/storage/syncUtils.js +25 -0
  100. package/dist/storage/syncUtils.js.map +1 -0
  101. package/dist/storage/types.d.ts +82 -0
  102. package/dist/storage/types.d.ts.map +1 -0
  103. package/dist/storage/types.js +2 -0
  104. package/dist/storage/types.js.map +1 -0
  105. package/dist/streamUtils.d.ts +13 -9
  106. package/dist/streamUtils.d.ts.map +1 -1
  107. package/dist/streamUtils.js +46 -13
  108. package/dist/streamUtils.js.map +1 -1
  109. package/dist/sync.d.ts +22 -14
  110. package/dist/sync.d.ts.map +1 -1
  111. package/dist/sync.js +143 -125
  112. package/dist/sync.js.map +1 -1
  113. package/dist/tests/IncomingMessagesQueue.test.d.ts +2 -0
  114. package/dist/tests/IncomingMessagesQueue.test.d.ts.map +1 -0
  115. package/dist/tests/IncomingMessagesQueue.test.js +437 -0
  116. package/dist/tests/IncomingMessagesQueue.test.js.map +1 -0
  117. package/dist/tests/PeerState.test.js +6 -94
  118. package/dist/tests/PeerState.test.js.map +1 -1
  119. package/dist/tests/PriorityBasedMessageQueue.test.js +14 -14
  120. package/dist/tests/PriorityBasedMessageQueue.test.js.map +1 -1
  121. package/dist/tests/StoreQueue.test.d.ts +2 -0
  122. package/dist/tests/StoreQueue.test.d.ts.map +1 -0
  123. package/dist/tests/StoreQueue.test.js +208 -0
  124. package/dist/tests/StoreQueue.test.js.map +1 -0
  125. package/dist/tests/SyncStateManager.test.js +3 -1
  126. package/dist/tests/SyncStateManager.test.js.map +1 -1
  127. package/dist/tests/account.test.js +9 -9
  128. package/dist/tests/account.test.js.map +1 -1
  129. package/dist/tests/coStream.test.js +1 -1
  130. package/dist/tests/coStream.test.js.map +1 -1
  131. package/dist/tests/coValueCore.test.js +208 -1
  132. package/dist/tests/coValueCore.test.js.map +1 -1
  133. package/dist/tests/coValueCoreLoadingState.test.js +2 -2
  134. package/dist/tests/coValueCoreLoadingState.test.js.map +1 -1
  135. package/dist/tests/group.addMember.test.js.map +1 -1
  136. package/dist/tests/group.removeMember.test.js +1 -1
  137. package/dist/tests/group.removeMember.test.js.map +1 -1
  138. package/dist/tests/messagesTestUtils.js +1 -1
  139. package/dist/tests/messagesTestUtils.js.map +1 -1
  140. package/dist/tests/sync.auth.test.js +23 -15
  141. package/dist/tests/sync.auth.test.js.map +1 -1
  142. package/dist/tests/sync.invite.test.js +10 -16
  143. package/dist/tests/sync.invite.test.js.map +1 -1
  144. package/dist/tests/sync.load.test.js +52 -50
  145. package/dist/tests/sync.load.test.js.map +1 -1
  146. package/dist/tests/sync.mesh.test.js +173 -56
  147. package/dist/tests/sync.mesh.test.js.map +1 -1
  148. package/dist/tests/sync.peerReconciliation.test.js +42 -32
  149. package/dist/tests/sync.peerReconciliation.test.js.map +1 -1
  150. package/dist/tests/sync.storage.test.js +162 -62
  151. package/dist/tests/sync.storage.test.js.map +1 -1
  152. package/dist/tests/sync.storageAsync.test.d.ts +2 -0
  153. package/dist/tests/sync.storageAsync.test.d.ts.map +1 -0
  154. package/dist/tests/sync.storageAsync.test.js +361 -0
  155. package/dist/tests/sync.storageAsync.test.js.map +1 -0
  156. package/dist/tests/sync.test.js +16 -21
  157. package/dist/tests/sync.test.js.map +1 -1
  158. package/dist/tests/sync.upload.test.js +28 -25
  159. package/dist/tests/sync.upload.test.js.map +1 -1
  160. package/dist/tests/testStorage.d.ts +12 -0
  161. package/dist/tests/testStorage.d.ts.map +1 -0
  162. package/dist/tests/testStorage.js +151 -0
  163. package/dist/tests/testStorage.js.map +1 -0
  164. package/dist/tests/testUtils.d.ts +20 -15
  165. package/dist/tests/testUtils.d.ts.map +1 -1
  166. package/dist/tests/testUtils.js +79 -45
  167. package/dist/tests/testUtils.js.map +1 -1
  168. package/package.json +2 -2
  169. package/src/IncomingMessagesQueue.ts +142 -0
  170. package/src/PeerState.ts +11 -110
  171. package/src/PriorityBasedMessageQueue.ts +13 -5
  172. package/src/SyncStateManager.ts +1 -1
  173. package/src/coValueCore/coValueCore.ts +100 -66
  174. package/src/coValueCore/verifiedState.ts +91 -21
  175. package/src/coValues/group.ts +2 -4
  176. package/src/config.ts +26 -0
  177. package/src/crypto/WasmCrypto.ts +3 -1
  178. package/src/exports.ts +20 -27
  179. package/src/localNode.ts +27 -12
  180. package/src/storage/StoreQueue.ts +56 -0
  181. package/src/storage/index.ts +5 -0
  182. package/src/storage/knownState.ts +88 -0
  183. package/src/storage/sqlite/client.ts +180 -0
  184. package/src/storage/sqlite/index.ts +19 -0
  185. package/src/storage/sqlite/sqliteMigrations.ts +44 -0
  186. package/src/storage/sqlite/types.ts +7 -0
  187. package/src/storage/sqliteAsync/client.ts +179 -0
  188. package/src/storage/sqliteAsync/index.ts +25 -0
  189. package/src/storage/sqliteAsync/types.ts +8 -0
  190. package/src/storage/storageAsync.ts +367 -0
  191. package/src/storage/storageSync.ts +343 -0
  192. package/src/storage/syncUtils.ts +50 -0
  193. package/src/storage/types.ts +162 -0
  194. package/src/streamUtils.ts +61 -19
  195. package/src/sync.ts +191 -160
  196. package/src/tests/IncomingMessagesQueue.test.ts +626 -0
  197. package/src/tests/PeerState.test.ts +6 -118
  198. package/src/tests/PriorityBasedMessageQueue.test.ts +18 -14
  199. package/src/tests/StoreQueue.test.ts +283 -0
  200. package/src/tests/SyncStateManager.test.ts +4 -1
  201. package/src/tests/account.test.ts +11 -12
  202. package/src/tests/coStream.test.ts +1 -3
  203. package/src/tests/coValueCore.test.ts +270 -1
  204. package/src/tests/coValueCoreLoadingState.test.ts +2 -2
  205. package/src/tests/group.addMember.test.ts +1 -0
  206. package/src/tests/group.removeMember.test.ts +2 -8
  207. package/src/tests/messagesTestUtils.ts +2 -2
  208. package/src/tests/sync.auth.test.ts +24 -14
  209. package/src/tests/sync.invite.test.ts +11 -17
  210. package/src/tests/sync.load.test.ts +53 -49
  211. package/src/tests/sync.mesh.test.ts +198 -56
  212. package/src/tests/sync.peerReconciliation.test.ts +44 -34
  213. package/src/tests/sync.storage.test.ts +231 -64
  214. package/src/tests/sync.storageAsync.test.ts +486 -0
  215. package/src/tests/sync.test.ts +17 -23
  216. package/src/tests/sync.upload.test.ts +29 -24
  217. package/src/tests/testStorage.ts +216 -0
  218. package/src/tests/testUtils.ts +89 -54
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/storage/types.ts"],"names":[],"mappings":""}
@@ -1,13 +1,17 @@
1
- import { Channel } from "queueueue";
2
- import { Peer, PeerID, SyncMessage } from "./sync.js";
3
- export { Channel } from "queueueue";
4
- export declare function connectedPeers(peer1id: PeerID, peer2id: PeerID, { peer1role, peer2role, crashOnClose, }?: {
1
+ import { DisconnectedError, IncomingPeerChannel, OutgoingPeerChannel, Peer, PeerID, SyncMessage } from "./sync.js";
2
+ export declare function connectedPeers(peer1id: PeerID, peer2id: PeerID, { peer1role, peer2role, }?: {
5
3
  peer1role?: Peer["role"];
6
4
  peer2role?: Peer["role"];
7
- crashOnClose?: boolean;
8
5
  }): [Peer, Peer];
9
- export declare function newQueuePair(): [
10
- AsyncIterable<SyncMessage>,
11
- Channel<SyncMessage>
12
- ];
6
+ export declare function newQueuePair(): [ConnectedPeerChannel, ConnectedPeerChannel];
7
+ export declare class ConnectedPeerChannel implements IncomingPeerChannel, OutgoingPeerChannel {
8
+ buffer: (SyncMessage | DisconnectedError)[];
9
+ push(msg: SyncMessage | DisconnectedError): void;
10
+ close(): void;
11
+ listeners: Set<(msg: SyncMessage | DisconnectedError) => void>;
12
+ onMessage(callback: (msg: SyncMessage | DisconnectedError) => void): void;
13
+ closed: boolean;
14
+ closeListeners: Set<() => void>;
15
+ onClose(callback: () => void): void;
16
+ }
13
17
  //# sourceMappingURL=streamUtils.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"streamUtils.d.ts","sourceRoot":"","sources":["../src/streamUtils.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,WAAW,CAAC;AACtD,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAEpC,wBAAgB,cAAc,CAC5B,OAAO,EAAE,MAAM,EACf,OAAO,EAAE,MAAM,EACf,EACE,SAAoB,EACpB,SAAoB,EACpB,YAAoB,GACrB,GAAE;IACD,SAAS,CAAC,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC;IACzB,SAAS,CAAC,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC;IACzB,YAAY,CAAC,EAAE,OAAO,CAAC;CACnB,GACL,CAAC,IAAI,EAAE,IAAI,CAAC,CAqBd;AAED,wBAAgB,YAAY,IAAI;IAC9B,aAAa,CAAC,WAAW,CAAC;IAC1B,OAAO,CAAC,WAAW,CAAC;CACrB,CAIA"}
1
+ {"version":3,"file":"streamUtils.d.ts","sourceRoot":"","sources":["../src/streamUtils.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,iBAAiB,EACjB,mBAAmB,EACnB,mBAAmB,EACnB,IAAI,EACJ,MAAM,EACN,WAAW,EACZ,MAAM,WAAW,CAAC;AAEnB,wBAAgB,cAAc,CAC5B,OAAO,EAAE,MAAM,EACf,OAAO,EAAE,MAAM,EACf,EACE,SAAoB,EACpB,SAAoB,GACrB,GAAE;IACD,SAAS,CAAC,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC;IACzB,SAAS,CAAC,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC;CACrB,GACL,CAAC,IAAI,EAAE,IAAI,CAAC,CAmBd;AAED,wBAAgB,YAAY,IAAI,CAAC,oBAAoB,EAAE,oBAAoB,CAAC,CAI3E;AAED,qBAAa,oBACX,YAAW,mBAAmB,EAAE,mBAAmB;IAEnD,MAAM,EAAE,CAAC,WAAW,GAAG,iBAAiB,CAAC,EAAE,CAAM;IAEjD,IAAI,CAAC,GAAG,EAAE,WAAW,GAAG,iBAAiB;IAWzC,KAAK;IASL,SAAS,YAAiB,WAAW,GAAG,iBAAiB,KAAK,IAAI,EAAI;IACtE,SAAS,CAAC,QAAQ,EAAE,CAAC,GAAG,EAAE,WAAW,GAAG,iBAAiB,KAAK,IAAI;IAWlE,MAAM,UAAS;IACf,cAAc,YAAiB,IAAI,EAAI;IACvC,OAAO,CAAC,QAAQ,EAAE,MAAM,IAAI;CAG7B"}
@@ -1,26 +1,59 @@
1
- import { Channel } from "queueueue";
2
- export { Channel } from "queueueue";
3
- export function connectedPeers(peer1id, peer2id, { peer1role = "client", peer2role = "client", crashOnClose = false, } = {}) {
4
- const [from1to2Rx, from1to2Tx] = newQueuePair();
5
- const [from2to1Rx, from2to1Tx] = newQueuePair();
1
+ export function connectedPeers(peer1id, peer2id, { peer1role = "client", peer2role = "client", } = {}) {
2
+ const from1to2 = new ConnectedPeerChannel();
3
+ const from2to1 = new ConnectedPeerChannel();
6
4
  const peer2AsPeer = {
7
5
  id: peer2id,
8
- incoming: from2to1Rx,
9
- outgoing: from1to2Tx,
6
+ incoming: from2to1,
7
+ outgoing: from1to2,
10
8
  role: peer2role,
11
- crashOnClose: crashOnClose,
12
9
  };
13
10
  const peer1AsPeer = {
14
11
  id: peer1id,
15
- incoming: from1to2Rx,
16
- outgoing: from2to1Tx,
12
+ incoming: from1to2,
13
+ outgoing: from2to1,
17
14
  role: peer1role,
18
- crashOnClose: crashOnClose,
19
15
  };
20
16
  return [peer1AsPeer, peer2AsPeer];
21
17
  }
22
18
  export function newQueuePair() {
23
- const channel = new Channel();
24
- return [channel.wrap(), channel];
19
+ const channel = new ConnectedPeerChannel();
20
+ return [channel, channel];
21
+ }
22
+ export class ConnectedPeerChannel {
23
+ constructor() {
24
+ this.buffer = [];
25
+ this.listeners = new Set();
26
+ this.closed = false;
27
+ this.closeListeners = new Set();
28
+ }
29
+ push(msg) {
30
+ if (!this.listeners.size) {
31
+ this.buffer.push(msg);
32
+ return;
33
+ }
34
+ for (const listener of this.listeners) {
35
+ listener(msg);
36
+ }
37
+ }
38
+ close() {
39
+ this.closed = true;
40
+ for (const listener of this.closeListeners) {
41
+ listener();
42
+ }
43
+ this.closeListeners.clear();
44
+ this.listeners.clear();
45
+ }
46
+ onMessage(callback) {
47
+ if (this.buffer.length) {
48
+ for (const msg of this.buffer) {
49
+ callback(msg);
50
+ }
51
+ this.buffer = [];
52
+ }
53
+ this.listeners.add(callback);
54
+ }
55
+ onClose(callback) {
56
+ this.closeListeners.add(callback);
57
+ }
25
58
  }
26
59
  //# sourceMappingURL=streamUtils.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"streamUtils.js","sourceRoot":"","sources":["../src/streamUtils.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAEpC,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAEpC,MAAM,UAAU,cAAc,CAC5B,OAAe,EACf,OAAe,EACf,EACE,SAAS,GAAG,QAAQ,EACpB,SAAS,GAAG,QAAQ,EACpB,YAAY,GAAG,KAAK,MAKlB,EAAE;IAEN,MAAM,CAAC,UAAU,EAAE,UAAU,CAAC,GAAG,YAAY,EAAE,CAAC;IAChD,MAAM,CAAC,UAAU,EAAE,UAAU,CAAC,GAAG,YAAY,EAAE,CAAC;IAEhD,MAAM,WAAW,GAAS;QACxB,EAAE,EAAE,OAAO;QACX,QAAQ,EAAE,UAAU;QACpB,QAAQ,EAAE,UAAU;QACpB,IAAI,EAAE,SAAS;QACf,YAAY,EAAE,YAAY;KAC3B,CAAC;IAEF,MAAM,WAAW,GAAS;QACxB,EAAE,EAAE,OAAO;QACX,QAAQ,EAAE,UAAU;QACpB,QAAQ,EAAE,UAAU;QACpB,IAAI,EAAE,SAAS;QACf,YAAY,EAAE,YAAY;KAC3B,CAAC;IAEF,OAAO,CAAC,WAAW,EAAE,WAAW,CAAC,CAAC;AACpC,CAAC;AAED,MAAM,UAAU,YAAY;IAI1B,MAAM,OAAO,GAAG,IAAI,OAAO,EAAe,CAAC;IAE3C,OAAO,CAAC,OAAO,CAAC,IAAI,EAAE,EAAE,OAAO,CAAC,CAAC;AACnC,CAAC"}
1
+ {"version":3,"file":"streamUtils.js","sourceRoot":"","sources":["../src/streamUtils.ts"],"names":[],"mappings":"AASA,MAAM,UAAU,cAAc,CAC5B,OAAe,EACf,OAAe,EACf,EACE,SAAS,GAAG,QAAQ,EACpB,SAAS,GAAG,QAAQ,MAIlB,EAAE;IAEN,MAAM,QAAQ,GAAG,IAAI,oBAAoB,EAAE,CAAC;IAC5C,MAAM,QAAQ,GAAG,IAAI,oBAAoB,EAAE,CAAC;IAE5C,MAAM,WAAW,GAAS;QACxB,EAAE,EAAE,OAAO;QACX,QAAQ,EAAE,QAAQ;QAClB,QAAQ,EAAE,QAAQ;QAClB,IAAI,EAAE,SAAS;KAChB,CAAC;IAEF,MAAM,WAAW,GAAS;QACxB,EAAE,EAAE,OAAO;QACX,QAAQ,EAAE,QAAQ;QAClB,QAAQ,EAAE,QAAQ;QAClB,IAAI,EAAE,SAAS;KAChB,CAAC;IAEF,OAAO,CAAC,WAAW,EAAE,WAAW,CAAC,CAAC;AACpC,CAAC;AAED,MAAM,UAAU,YAAY;IAC1B,MAAM,OAAO,GAAG,IAAI,oBAAoB,EAAE,CAAC;IAE3C,OAAO,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;AAC5B,CAAC;AAED,MAAM,OAAO,oBAAoB;IAAjC;QAGE,WAAM,GAAwC,EAAE,CAAC;QAsBjD,cAAS,GAAG,IAAI,GAAG,EAAkD,CAAC;QAYtE,WAAM,GAAG,KAAK,CAAC;QACf,mBAAc,GAAG,IAAI,GAAG,EAAc,CAAC;IAIzC,CAAC;IArCC,IAAI,CAAC,GAAoC;QACvC,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,IAAI,EAAE,CAAC;YACzB,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;YACtB,OAAO;QACT,CAAC;QAED,KAAK,MAAM,QAAQ,IAAI,IAAI,CAAC,SAAS,EAAE,CAAC;YACtC,QAAQ,CAAC,GAAG,CAAC,CAAC;QAChB,CAAC;IACH,CAAC;IAED,KAAK;QACH,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC;QACnB,KAAK,MAAM,QAAQ,IAAI,IAAI,CAAC,cAAc,EAAE,CAAC;YAC3C,QAAQ,EAAE,CAAC;QACb,CAAC;QACD,IAAI,CAAC,cAAc,CAAC,KAAK,EAAE,CAAC;QAC5B,IAAI,CAAC,SAAS,CAAC,KAAK,EAAE,CAAC;IACzB,CAAC;IAGD,SAAS,CAAC,QAAwD;QAChE,IAAI,IAAI,CAAC,MAAM,CAAC,MAAM,EAAE,CAAC;YACvB,KAAK,MAAM,GAAG,IAAI,IAAI,CAAC,MAAM,EAAE,CAAC;gBAC9B,QAAQ,CAAC,GAAG,CAAC,CAAC;YAChB,CAAC;YACD,IAAI,CAAC,MAAM,GAAG,EAAE,CAAC;QACnB,CAAC;QAED,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;IAC/B,CAAC;IAID,OAAO,CAAC,QAAoB;QAC1B,IAAI,CAAC,cAAc,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;IACpC,CAAC;CACF"}
package/dist/sync.d.ts CHANGED
@@ -1,3 +1,4 @@
1
+ import { IncomingMessagesQueue } from "./IncomingMessagesQueue.js";
1
2
  import { PeerState } from "./PeerState.js";
2
3
  import { SyncStateManager } from "./SyncStateManager.js";
3
4
  import { CoValueCore } from "./coValueCore/coValueCore.js";
@@ -31,6 +32,9 @@ export type NewContentMessage = {
31
32
  new: {
32
33
  [sessionID: SessionID]: SessionNewContent;
33
34
  };
35
+ expectContentUntil?: {
36
+ [sessionID: SessionID]: number;
37
+ };
34
38
  };
35
39
  export type SessionNewContent = {
36
40
  after: number;
@@ -43,19 +47,22 @@ export type DoneMessage = {
43
47
  };
44
48
  export type PeerID = string;
45
49
  export type DisconnectedError = "Disconnected";
46
- export type PingTimeoutError = "PingTimeout";
47
- export type IncomingSyncStream = AsyncIterable<SyncMessage | DisconnectedError | PingTimeoutError>;
48
- export type OutgoingSyncQueue = {
49
- push: (msg: SyncMessage) => Promise<unknown>;
50
+ export interface IncomingPeerChannel {
50
51
  close: () => void;
51
- };
52
+ onMessage: (callback: (msg: SyncMessage | DisconnectedError) => void) => void;
53
+ onClose: (callback: () => void) => void;
54
+ }
55
+ export interface OutgoingPeerChannel {
56
+ push: (msg: SyncMessage | DisconnectedError) => void;
57
+ close: () => void;
58
+ onClose: (callback: () => void) => void;
59
+ }
52
60
  export interface Peer {
53
61
  id: PeerID;
54
- incoming: IncomingSyncStream;
55
- outgoing: OutgoingSyncQueue;
56
- role: "server" | "client" | "storage";
62
+ incoming: IncomingPeerChannel;
63
+ outgoing: OutgoingPeerChannel;
64
+ role: "server" | "client";
57
65
  priority?: number;
58
- crashOnClose: boolean;
59
66
  deletePeerStateOnClose?: boolean;
60
67
  }
61
68
  export declare function combinedKnownStates(stateA: CoValueKnownState, stateB: CoValueKnownState): CoValueKnownState;
@@ -70,11 +77,12 @@ export declare class SyncManager {
70
77
  syncState: SyncStateManager;
71
78
  peersInPriorityOrder(): PeerState[];
72
79
  getPeers(): PeerState[];
73
- getServerAndStoragePeers(excludePeerId?: PeerID): PeerState[];
74
- hasStoragePeers(): boolean;
80
+ getServerPeers(excludePeerId?: PeerID): PeerState[];
75
81
  handleSyncMessage(msg: SyncMessage, peer: PeerState): void;
76
82
  sendNewContentIncludingDependencies(id: RawCoID, peer: PeerState, seen?: Set<RawCoID>): void;
77
83
  startPeerReconciliation(peer: PeerState): void;
84
+ messagesQueue: IncomingMessagesQueue;
85
+ pushMessage(incoming: SyncMessage, peer: PeerState): void;
78
86
  addPeer(peer: Peer): void;
79
87
  trySendToPeer(peer: PeerState, msg: SyncMessage): void;
80
88
  /**
@@ -88,14 +96,14 @@ export declare class SyncManager {
88
96
  handleLoad(msg: LoadMessage, peer: PeerState): void;
89
97
  handleKnownState(msg: KnownStateMessage, peer: PeerState): void;
90
98
  recordTransactionsSize(newTransactions: Transaction[], source: string): void;
91
- handleNewContent(msg: NewContentMessage, peer: PeerState): void;
99
+ handleNewContent(msg: NewContentMessage, from: PeerState | "storage"): void;
92
100
  handleCorrection(msg: KnownStateMessage, peer: PeerState): void;
93
- handleUnsubscribe(_msg: DoneMessage): void;
94
101
  requestedSyncs: Set<`co_z${string}`>;
95
102
  requestCoValueSync(coValue: CoValueCore): void;
103
+ storeCoValue(coValue: CoValueCore, data: NewContentMessage[] | undefined): void;
96
104
  syncCoValue(coValue: CoValueCore): void;
97
105
  waitForSyncWithPeer(peerId: PeerID, id: RawCoID, timeout: number): Promise<unknown> | undefined;
98
- waitForStorageSync(id: RawCoID, timeout?: number): Promise<unknown[]>;
106
+ waitForStorageSync(id: RawCoID): Promise<void> | undefined;
99
107
  waitForSync(id: RawCoID, timeout?: number): Promise<unknown[]>;
100
108
  waitForAllCoValuesSync(timeout?: number): Promise<unknown[][]>;
101
109
  gracefulShutdown(): void;
@@ -1 +1 @@
1
- {"version":3,"file":"sync.d.ts","sourceRoot":"","sources":["../src/sync.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"sync.d.ts","sourceRoot":"","sources":["../src/sync.ts"],"names":[],"mappings":"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"}
package/dist/sync.js CHANGED
@@ -1,4 +1,5 @@
1
1
  import { ValueType, metrics } from "@opentelemetry/api";
2
+ import { IncomingMessagesQueue } from "./IncomingMessagesQueue.js";
2
3
  import { PeerState } from "./PeerState.js";
3
4
  import { SyncStateManager } from "./SyncStateManager.js";
4
5
  import { getDependedOnCoValuesFromRawData } from "./coValueCore/utils.js";
@@ -37,6 +38,7 @@ export class SyncManager {
37
38
  valueType: ValueType.INT,
38
39
  unit: "peer",
39
40
  });
41
+ this.messagesQueue = new IncomingMessagesQueue();
40
42
  this.requestedSyncs = new Set();
41
43
  this.local = local;
42
44
  this.syncState = new SyncStateManager(this);
@@ -58,13 +60,8 @@ export class SyncManager {
58
60
  getPeers() {
59
61
  return Object.values(this.peers);
60
62
  }
61
- getServerAndStoragePeers(excludePeerId) {
62
- return this.peersInPriorityOrder().filter((peer) => peer.isServerOrStoragePeer() &&
63
- peer.id !== excludePeerId &&
64
- !peer.closed);
65
- }
66
- hasStoragePeers() {
67
- return this.getPeers().some((peer) => peer.role === "storage" && !peer.closed);
63
+ getServerPeers(excludePeerId) {
64
+ return this.getPeers().filter((peer) => peer.role === "server" && peer.id !== excludePeerId && !peer.closed);
68
65
  }
69
66
  handleSyncMessage(msg, peer) {
70
67
  if (msg.id === undefined || msg.id === null) {
@@ -97,7 +94,7 @@ export class SyncManager {
97
94
  case "content":
98
95
  return this.handleNewContent(msg, peer);
99
96
  case "done":
100
- return this.handleUnsubscribe(msg);
97
+ return;
101
98
  default:
102
99
  throw new Error(`Unknown message type ${msg.action}`);
103
100
  }
@@ -124,7 +121,7 @@ export class SyncManager {
124
121
  else if (!peer.toldKnownState.has(id)) {
125
122
  this.trySendToPeer(peer, {
126
123
  action: "known",
127
- ...coValue.knownState(),
124
+ ...coValue.knownStateWithStreaming(),
128
125
  });
129
126
  }
130
127
  peer.trackToldKnownState(id);
@@ -183,6 +180,15 @@ export class SyncManager {
183
180
  });
184
181
  }
185
182
  }
183
+ pushMessage(incoming, peer) {
184
+ this.messagesQueue.push(incoming, peer);
185
+ if (this.messagesQueue.processing) {
186
+ return;
187
+ }
188
+ this.messagesQueue.processQueue((msg, peer) => {
189
+ this.handleSyncMessage(msg, peer);
190
+ });
191
+ }
186
192
  addPeer(peer) {
187
193
  const prevPeer = this.peers[peer.id];
188
194
  if (prevPeer && !prevPeer.closed) {
@@ -194,36 +200,17 @@ export class SyncManager {
194
200
  const unsubscribeFromKnownStatesUpdates = peerState.knownStates.subscribe((id) => {
195
201
  this.syncState.triggerUpdate(peer.id, id);
196
202
  });
197
- if (peerState.isServerOrStoragePeer()) {
203
+ if (peerState.role === "server") {
198
204
  void this.startPeerReconciliation(peerState);
199
205
  }
200
- peerState
201
- .processIncomingMessages((msg) => {
202
- this.handleSyncMessage(msg, peerState);
203
- })
204
- .then(() => {
205
- if (peer.crashOnClose) {
206
- logger.error("Unexepcted close from peer", {
207
- peerId: peer.id,
208
- peerRole: peer.role,
209
- });
210
- this.local.crashed = new Error("Unexpected close from peer");
211
- throw new Error("Unexpected close from peer");
212
- }
213
- })
214
- .catch((e) => {
215
- logger.error("Error processing messages from peer", {
216
- err: e,
217
- peerId: peer.id,
218
- peerRole: peer.role,
219
- });
220
- if (peer.crashOnClose) {
221
- this.local.crashed = e;
222
- throw new Error(e);
206
+ peerState.incoming.onMessage((msg) => {
207
+ if (msg === "Disconnected") {
208
+ peerState.gracefulShutdown();
209
+ return;
223
210
  }
224
- })
225
- .finally(() => {
226
- peerState.gracefulShutdown();
211
+ this.pushMessage(msg, peerState);
212
+ });
213
+ peerState.addCloseListener(() => {
227
214
  unsubscribeFromKnownStatesUpdates();
228
215
  this.peersCounter.add(-1, { role: peer.role });
229
216
  if (peer.deletePeerStateOnClose && this.peers[peer.id] === peerState) {
@@ -255,11 +242,13 @@ export class SyncManager {
255
242
  this.sendNewContentIncludingDependencies(msg.id, peer);
256
243
  return;
257
244
  }
258
- const eligiblePeers = this.getServerAndStoragePeers(peer.id);
259
- if (eligiblePeers.length === 0) {
260
- // We don't have any eligible peers to load the coValue from
261
- // so we send a known state back to the sender to let it know
262
- // that the coValue is unavailable
245
+ const peers = this.getServerPeers(peer.id);
246
+ coValue.load(peers);
247
+ const handleLoadResult = () => {
248
+ if (coValue.isAvailable()) {
249
+ this.sendNewContentIncludingDependencies(msg.id, peer);
250
+ return;
251
+ }
263
252
  peer.trackToldKnownState(msg.id);
264
253
  this.trySendToPeer(peer, {
265
254
  action: "known",
@@ -267,35 +256,13 @@ export class SyncManager {
267
256
  header: false,
268
257
  sessions: {},
269
258
  });
270
- return;
259
+ };
260
+ if (peers.length > 0 || this.local.storage) {
261
+ coValue.waitForAvailableOrUnavailable().then(handleLoadResult);
262
+ }
263
+ else {
264
+ handleLoadResult();
271
265
  }
272
- coValue.loadFromPeers(eligiblePeers).catch((e) => {
273
- logger.error("Error loading coValue in handleLoad", { err: e });
274
- });
275
- // We need to return from handleLoad immediately and wait for the CoValue to be loaded
276
- // in a new task, otherwise we might block further incoming content messages that would
277
- // resolve the CoValue as available. This can happen when we receive fresh
278
- // content from a client, but we are a server with our own upstream server(s)
279
- coValue
280
- .waitForAvailableOrUnavailable()
281
- .then((value) => {
282
- if (!value.isAvailable()) {
283
- peer.trackToldKnownState(msg.id);
284
- this.trySendToPeer(peer, {
285
- action: "known",
286
- id: msg.id,
287
- header: false,
288
- sessions: {},
289
- });
290
- return;
291
- }
292
- this.sendNewContentIncludingDependencies(msg.id, peer);
293
- })
294
- .catch((e) => {
295
- logger.error("Error loading coValue in handleLoad loading state", {
296
- err: e,
297
- });
298
- });
299
266
  }
300
267
  handleKnownState(msg, peer) {
301
268
  const coValue = this.local.getCoValue(msg.id);
@@ -320,40 +287,56 @@ export class SyncManager {
320
287
  });
321
288
  }
322
289
  }
323
- handleNewContent(msg, peer) {
290
+ handleNewContent(msg, from) {
324
291
  const coValue = this.local.getCoValue(msg.id);
325
- if (!coValue.verified) {
292
+ const peer = from === "storage" ? undefined : from;
293
+ if (!coValue.hasVerifiedContent()) {
326
294
  if (!msg.header) {
327
- this.trySendToPeer(peer, {
328
- action: "known",
329
- isCorrection: true,
330
- id: msg.id,
331
- header: false,
332
- sessions: {},
333
- });
295
+ if (peer) {
296
+ this.trySendToPeer(peer, {
297
+ action: "known",
298
+ isCorrection: true,
299
+ id: msg.id,
300
+ header: false,
301
+ sessions: {},
302
+ });
303
+ }
304
+ else {
305
+ logger.error("Received new content with no header on a missing CoValue", {
306
+ id: msg.id,
307
+ });
308
+ }
334
309
  return;
335
310
  }
336
311
  const sessionIDs = Object.keys(msg.new);
337
312
  const transactions = Object.values(msg.new).map((content) => content.newTransactions);
338
313
  for (const dependency of getDependedOnCoValuesFromRawData(msg.id, msg.header, sessionIDs, transactions)) {
339
314
  const dependencyCoValue = this.local.getCoValue(dependency);
340
- if (!dependencyCoValue.verified) {
315
+ if (!dependencyCoValue.hasVerifiedContent()) {
341
316
  coValue.markMissingDependency(dependency);
342
- if (!dependencyCoValue.verified) {
343
- const peers = this.getServerAndStoragePeers();
344
- // if the peer that sent the content is a client, we add it to the list of peers
345
- // to also ask them for the dependency
346
- if (peer.role === "client") {
347
- peers.push(peer);
348
- }
349
- dependencyCoValue.loadFromPeers(peers);
317
+ const peers = this.getServerPeers();
318
+ // if the peer that sent the content is a client, we add it to the list of peers
319
+ // to also ask them for the dependency
320
+ if (peer?.role === "client") {
321
+ peers.push(peer);
350
322
  }
323
+ dependencyCoValue.load(peers);
324
+ }
325
+ else if (!dependencyCoValue.isAvailable()) {
326
+ coValue.markMissingDependency(dependency);
351
327
  }
352
328
  }
353
- peer.updateHeader(msg.id, true);
354
- coValue.provideHeader(msg.header, peer.id);
329
+ peer?.updateHeader(msg.id, true);
330
+ coValue.provideHeader(msg.header, peer?.id ?? "storage", msg.expectContentUntil);
331
+ if (msg.expectContentUntil) {
332
+ peer?.combineWith(msg.id, {
333
+ id: msg.id,
334
+ header: true,
335
+ sessions: msg.expectContentUntil,
336
+ });
337
+ }
355
338
  }
356
- if (!coValue.verified) {
339
+ if (!coValue.hasVerifiedContent()) {
357
340
  throw new Error("Unreachable: CoValue should always have a verified state at this point");
358
341
  }
359
342
  let invalidStateAssumed = false;
@@ -379,13 +362,13 @@ export class SyncManager {
379
362
  // This covers the case where we are getting a new session on an already loaded coValue
380
363
  // where we need to load the account to get their public key
381
364
  if (!coValue.missingDependencies.has(accountId)) {
382
- const peers = this.getServerAndStoragePeers();
383
- if (peer.role === "client") {
365
+ const peers = this.getServerPeers();
366
+ if (peer?.role === "client") {
384
367
  // if the peer that sent the content is a client, we add it to the list of peers
385
368
  // to also ask them for the dependency
386
369
  peers.push(peer);
387
370
  }
388
- account.loadFromPeers(peers);
371
+ account.load(peers);
389
372
  }
390
373
  // We need to wait for the account to be available before we can verify the transaction
391
374
  // Currently doing this by delaying the handleNewContent for the session to when we have the account
@@ -405,35 +388,50 @@ export class SyncManager {
405
388
  [sessionID]: newContentForSession,
406
389
  },
407
390
  priority: msg.priority,
408
- }, peer);
391
+ }, from);
409
392
  });
410
393
  continue;
411
394
  }
412
395
  }
413
396
  const result = coValue.tryAddTransactions(sessionID, newTransactions, undefined, newContentForSession.lastSignature, "immediate");
414
397
  if (result.isErr()) {
415
- console.error("Failed to add transactions", {
416
- peerId: peer.id,
417
- peerRole: peer.role,
418
- id: msg.id,
419
- err: result.error,
420
- });
421
- coValue.markErrored(peer.id, result.error);
398
+ if (peer) {
399
+ logger.error("Failed to add transactions", {
400
+ peerId: peer.id,
401
+ peerRole: peer.role,
402
+ id: msg.id,
403
+ err: result.error,
404
+ });
405
+ coValue.markErrored(peer.id, result.error);
406
+ }
407
+ else {
408
+ logger.error("Failed to add transactions from storage", {
409
+ id: msg.id,
410
+ err: result.error,
411
+ });
412
+ }
422
413
  continue;
423
414
  }
424
- this.recordTransactionsSize(newTransactions, peer.role);
425
- peer.updateSessionCounter(msg.id, sessionID, newContentForSession.after +
415
+ this.recordTransactionsSize(newTransactions, peer?.role ?? "storage");
416
+ peer?.updateSessionCounter(msg.id, sessionID, newContentForSession.after +
426
417
  newContentForSession.newTransactions.length);
427
418
  }
428
419
  if (invalidStateAssumed) {
429
- this.trySendToPeer(peer, {
430
- action: "known",
431
- isCorrection: true,
432
- ...coValue.knownState(),
433
- });
434
- peer.trackToldKnownState(msg.id);
420
+ if (peer) {
421
+ this.trySendToPeer(peer, {
422
+ action: "known",
423
+ isCorrection: true,
424
+ ...coValue.knownState(),
425
+ });
426
+ peer.trackToldKnownState(msg.id);
427
+ }
428
+ else {
429
+ logger.error("Invalid state assumed when handling new content from storage", {
430
+ id: msg.id,
431
+ });
432
+ }
435
433
  }
436
- else {
434
+ else if (peer) {
437
435
  /**
438
436
  * We are sending a known state message to the peer to acknowledge the
439
437
  * receipt of the new content.
@@ -447,18 +445,15 @@ export class SyncManager {
447
445
  });
448
446
  peer.trackToldKnownState(msg.id);
449
447
  }
450
- const sourcePeer = peer;
451
448
  const syncedPeers = [];
449
+ if (from !== "storage") {
450
+ this.storeCoValue(coValue, [msg]);
451
+ }
452
452
  for (const peer of this.peersInPriorityOrder()) {
453
453
  /**
454
454
  * We sync the content against the source peer if it is a client or server peers
455
455
  * to upload any content that is available on the current node and not on the source peer.
456
- *
457
- * We don't need to do this with storage peers because we don't get updates from those peers,
458
- * only load and store content.
459
456
  */
460
- if (peer.id === sourcePeer.id && sourcePeer.role === "storage")
461
- continue;
462
457
  if (peer.closed)
463
458
  continue;
464
459
  if (coValue.isErroredInPeer(peer.id))
@@ -468,7 +463,7 @@ export class SyncManager {
468
463
  this.sendNewContentIncludingDependencies(coValue.id, peer);
469
464
  syncedPeers.push(peer);
470
465
  }
471
- else if (peer.isServerOrStoragePeer() &&
466
+ else if (peer.role === "server" &&
472
467
  !peer.loadRequestSent.has(coValue.id)) {
473
468
  const state = coValue.getStateForPeer(peer.id)?.type;
474
469
  // Check if there is a inflight load operation and we
@@ -478,7 +473,7 @@ export class SyncManager {
478
473
  // before sending the new content
479
474
  this.trySendToPeer(peer, {
480
475
  action: "load",
481
- ...coValue.knownState(),
476
+ ...coValue.knownStateWithStreaming(),
482
477
  });
483
478
  peer.trackLoadRequestSent(coValue.id);
484
479
  syncedPeers.push(peer);
@@ -493,7 +488,6 @@ export class SyncManager {
493
488
  peer.setKnownState(msg.id, knownStateIn(msg));
494
489
  return this.sendNewContentIncludingDependencies(msg.id, peer);
495
490
  }
496
- handleUnsubscribe(_msg) { }
497
491
  requestCoValueSync(coValue) {
498
492
  if (this.requestedSyncs.has(coValue.id)) {
499
493
  return;
@@ -505,8 +499,33 @@ export class SyncManager {
505
499
  });
506
500
  this.requestedSyncs.add(coValue.id);
507
501
  }
502
+ storeCoValue(coValue, data) {
503
+ const storage = this.local.storage;
504
+ if (!storage || !data)
505
+ return;
506
+ // Try to store the content as-is for performance
507
+ // In case that some transactions are missing, a correction will be requested, but it's an edge case
508
+ storage.store(data, (correction) => {
509
+ if (!coValue.hasVerifiedContent())
510
+ return;
511
+ const newContentPieces = coValue.verified.newContentSince(correction);
512
+ if (!newContentPieces)
513
+ return;
514
+ storage.store(newContentPieces, (response) => {
515
+ logger.error("Correction requested by storage after sending a correction content", {
516
+ response,
517
+ knownState: coValue.knownState(),
518
+ });
519
+ });
520
+ });
521
+ }
508
522
  syncCoValue(coValue) {
509
523
  this.requestedSyncs.delete(coValue.id);
524
+ if (this.local.storage && coValue.hasVerifiedContent()) {
525
+ const knownState = this.local.storage.getKnownState(coValue.id);
526
+ const newContentPieces = coValue.verified.newContentSince(knownState);
527
+ this.storeCoValue(coValue, newContentPieces);
528
+ }
510
529
  for (const peer of this.peersInPriorityOrder()) {
511
530
  if (peer.closed)
512
531
  continue;
@@ -554,15 +573,14 @@ export class SyncManager {
554
573
  }, timeout);
555
574
  });
556
575
  }
557
- waitForStorageSync(id, timeout = 30000) {
558
- const peers = this.getPeers();
559
- return Promise.all(peers
560
- .filter((peer) => peer.role === "storage")
561
- .map((peer) => this.waitForSyncWithPeer(peer.id, id, timeout)));
576
+ waitForStorageSync(id) {
577
+ return this.local.storage?.waitForSync(id, this.local.getCoValue(id));
562
578
  }
563
579
  waitForSync(id, timeout = 30000) {
564
580
  const peers = this.getPeers();
565
- return Promise.all(peers.map((peer) => this.waitForSyncWithPeer(peer.id, id, timeout)));
581
+ return Promise.all(peers
582
+ .map((peer) => this.waitForSyncWithPeer(peer.id, id, timeout))
583
+ .concat(this.waitForStorageSync(id)));
566
584
  }
567
585
  waitForAllCoValuesSync(timeout = 60000) {
568
586
  const coValues = this.local.allCoValues();