zapo-js 0.1.1 → 0.2.0

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 (589) hide show
  1. package/README.md +20 -4
  2. package/dist/appstate/WaAppStateCrypto.js +19 -26
  3. package/dist/appstate/WaAppStateSyncClient.js +293 -181
  4. package/dist/appstate/WaAppStateSyncResponseParser.js +16 -5
  5. package/dist/appstate/constants.js +4 -3
  6. package/dist/appstate/{store/sqlite.js → encoding.js} +13 -8
  7. package/dist/appstate/index.js +8 -6
  8. package/dist/appstate/utils.js +9 -34
  9. package/dist/auth/WaAuthClient.js +43 -61
  10. package/dist/auth/flow/WaAuthCredentialsFlow.js +22 -15
  11. package/dist/auth/index.js +1 -8
  12. package/dist/auth/pairing/WaPairingCodeCrypto.js +6 -4
  13. package/dist/auth/pairing/WaPairingFlow.js +34 -26
  14. package/dist/auth/pairing/WaQrFlow.js +37 -24
  15. package/dist/client/WaClient.js +275 -324
  16. package/dist/client/WaClientFactory.js +500 -133
  17. package/dist/client/connection/WaConnectionManager.js +301 -0
  18. package/dist/client/connection/WaKeyShareCoordinator.js +63 -0
  19. package/dist/client/connection/WaReceiptQueue.js +51 -0
  20. package/dist/client/coordinators/WaAppStateMutationCoordinator.js +471 -0
  21. package/dist/client/coordinators/WaBusinessCoordinator.js +241 -0
  22. package/dist/client/coordinators/WaGroupCoordinator.js +30 -16
  23. package/dist/client/coordinators/WaIncomingNodeCoordinator.js +21 -27
  24. package/dist/client/coordinators/WaMessageDispatchCoordinator.js +439 -701
  25. package/dist/client/coordinators/WaPassiveTasksCoordinator.js +74 -31
  26. package/dist/client/coordinators/WaPrivacyCoordinator.js +134 -0
  27. package/dist/client/coordinators/WaProfileCoordinator.js +212 -0
  28. package/dist/client/coordinators/WaRetryCoordinator.js +242 -57
  29. package/dist/client/coordinators/WaStreamControlCoordinator.js +18 -11
  30. package/dist/client/coordinators/WaTrustedContactTokenCoordinator.js +166 -0
  31. package/dist/client/dirty.js +74 -48
  32. package/dist/client/events/chat.js +4 -3
  33. package/dist/client/events/devices.js +72 -0
  34. package/dist/client/events/group.js +62 -47
  35. package/dist/client/events/identity.js +22 -0
  36. package/dist/client/events/privacy-token.js +39 -0
  37. package/dist/client/history-sync.js +94 -63
  38. package/dist/client/incoming.js +60 -27
  39. package/dist/client/mailbox.js +24 -23
  40. package/dist/client/messages.js +107 -31
  41. package/dist/client/messaging/fanout.js +199 -0
  42. package/dist/client/messaging/key-protocol.js +130 -0
  43. package/dist/client/messaging/participants.js +193 -0
  44. package/dist/client/persistence/WriteBehindPersistence.js +129 -0
  45. package/dist/client/tokens/cs-token.js +50 -0
  46. package/dist/client/tokens/tc-token.js +25 -0
  47. package/dist/crypto/core/hkdf.js +3 -8
  48. package/dist/crypto/core/index.js +2 -5
  49. package/dist/crypto/core/keys.js +6 -7
  50. package/dist/crypto/core/nonce.js +2 -0
  51. package/dist/crypto/core/primitives.js +12 -23
  52. package/dist/crypto/core/random.js +26 -23
  53. package/dist/crypto/curves/Ed25519.js +7 -8
  54. package/dist/crypto/curves/X25519.js +38 -22
  55. package/dist/crypto/index.js +1 -3
  56. package/dist/crypto/math/constants.js +13 -36
  57. package/dist/crypto/math/edwards.js +171 -44
  58. package/dist/crypto/math/fe.js +706 -0
  59. package/dist/crypto/math/mod.js +10 -3
  60. package/dist/esm/appstate/WaAppStateCrypto.js +7 -14
  61. package/dist/esm/appstate/WaAppStateSyncClient.js +284 -172
  62. package/dist/esm/appstate/WaAppStateSyncResponseParser.js +17 -6
  63. package/dist/esm/appstate/constants.js +3 -2
  64. package/dist/esm/appstate/{store/sqlite.js → encoding.js} +13 -8
  65. package/dist/esm/appstate/index.js +2 -2
  66. package/dist/esm/appstate/utils.js +8 -30
  67. package/dist/esm/auth/WaAuthClient.js +43 -61
  68. package/dist/esm/auth/flow/WaAuthCredentialsFlow.js +22 -15
  69. package/dist/esm/auth/index.js +0 -3
  70. package/dist/esm/auth/pairing/WaPairingCodeCrypto.js +6 -4
  71. package/dist/esm/auth/pairing/WaPairingFlow.js +28 -20
  72. package/dist/esm/auth/pairing/WaQrFlow.js +37 -24
  73. package/dist/esm/client/WaClient.js +275 -324
  74. package/dist/esm/client/WaClientFactory.js +501 -134
  75. package/dist/esm/client/connection/WaConnectionManager.js +297 -0
  76. package/dist/esm/client/connection/WaKeyShareCoordinator.js +59 -0
  77. package/dist/esm/client/connection/WaReceiptQueue.js +47 -0
  78. package/dist/esm/client/coordinators/WaAppStateMutationCoordinator.js +467 -0
  79. package/dist/esm/client/coordinators/WaBusinessCoordinator.js +238 -0
  80. package/dist/esm/client/coordinators/WaGroupCoordinator.js +23 -9
  81. package/dist/esm/client/coordinators/WaIncomingNodeCoordinator.js +21 -27
  82. package/dist/esm/client/coordinators/WaMessageDispatchCoordinator.js +443 -705
  83. package/dist/esm/client/coordinators/WaPassiveTasksCoordinator.js +74 -31
  84. package/dist/esm/client/coordinators/WaPrivacyCoordinator.js +131 -0
  85. package/dist/esm/client/coordinators/WaProfileCoordinator.js +209 -0
  86. package/dist/esm/client/coordinators/WaRetryCoordinator.js +244 -59
  87. package/dist/esm/client/coordinators/WaStreamControlCoordinator.js +19 -12
  88. package/dist/esm/client/coordinators/WaTrustedContactTokenCoordinator.js +162 -0
  89. package/dist/esm/client/dirty.js +69 -43
  90. package/dist/esm/client/events/chat.js +4 -3
  91. package/dist/esm/client/events/devices.js +68 -0
  92. package/dist/esm/client/events/group.js +53 -39
  93. package/dist/esm/client/events/identity.js +19 -0
  94. package/dist/esm/client/events/privacy-token.js +36 -0
  95. package/dist/esm/client/history-sync.js +91 -60
  96. package/dist/esm/client/incoming.js +61 -28
  97. package/dist/esm/client/mailbox.js +24 -23
  98. package/dist/esm/client/messages.js +108 -32
  99. package/dist/esm/client/messaging/fanout.js +196 -0
  100. package/dist/esm/client/messaging/key-protocol.js +127 -0
  101. package/dist/esm/client/messaging/participants.js +190 -0
  102. package/dist/esm/client/persistence/WriteBehindPersistence.js +125 -0
  103. package/dist/esm/client/tokens/cs-token.js +46 -0
  104. package/dist/esm/client/tokens/tc-token.js +18 -0
  105. package/dist/esm/crypto/core/hkdf.js +3 -8
  106. package/dist/esm/crypto/core/index.js +2 -3
  107. package/dist/esm/crypto/core/keys.js +3 -4
  108. package/dist/esm/crypto/core/nonce.js +2 -0
  109. package/dist/esm/crypto/core/primitives.js +12 -22
  110. package/dist/esm/crypto/core/random.js +25 -23
  111. package/dist/esm/crypto/curves/Ed25519.js +4 -5
  112. package/dist/esm/crypto/curves/X25519.js +35 -19
  113. package/dist/esm/crypto/index.js +0 -1
  114. package/dist/esm/crypto/math/constants.js +12 -35
  115. package/dist/esm/crypto/math/edwards.js +174 -47
  116. package/dist/esm/crypto/math/fe.js +691 -0
  117. package/dist/esm/crypto/math/mod.js +10 -1
  118. package/dist/esm/index.js +1 -1
  119. package/dist/esm/infra/log/ConsoleLogger.js +18 -17
  120. package/dist/esm/infra/log/PinoLogger.js +15 -9
  121. package/dist/esm/infra/log/types.js +11 -1
  122. package/dist/esm/infra/perf/BackgroundQueue.js +478 -0
  123. package/dist/esm/infra/perf/BoundedTaskQueue.js +16 -18
  124. package/dist/esm/infra/perf/PromiseDedup.js +20 -0
  125. package/dist/esm/infra/perf/SharedExclusiveGate.js +109 -0
  126. package/dist/esm/infra/perf/StoreLock.js +77 -0
  127. package/dist/esm/media/WaMediaCrypto.js +96 -16
  128. package/dist/esm/media/WaMediaTransferClient.js +251 -91
  129. package/dist/esm/media/conn.js +10 -6
  130. package/dist/esm/media/constants.js +6 -2
  131. package/dist/esm/message/WaMessageClient.js +30 -32
  132. package/dist/esm/message/ack.js +6 -6
  133. package/dist/esm/message/addon-crypto.js +59 -0
  134. package/dist/esm/message/content.js +195 -9
  135. package/dist/esm/message/icdc.js +76 -0
  136. package/dist/esm/message/incoming.js +129 -122
  137. package/dist/esm/message/index.js +2 -0
  138. package/dist/esm/message/phash.js +3 -1
  139. package/dist/esm/message/reporting-token.js +425 -0
  140. package/dist/esm/message/use-case-secret.js +49 -0
  141. package/dist/esm/protocol/appstate.js +27 -0
  142. package/dist/esm/protocol/browser.js +10 -18
  143. package/dist/esm/protocol/constants.js +6 -3
  144. package/dist/esm/protocol/defaults.js +6 -0
  145. package/dist/esm/protocol/index.js +2 -11
  146. package/dist/esm/protocol/jid.js +133 -52
  147. package/dist/esm/protocol/media.js +3 -3
  148. package/dist/esm/protocol/message.js +61 -1
  149. package/dist/esm/protocol/nodes.js +4 -0
  150. package/dist/esm/protocol/notification.js +3 -1
  151. package/dist/esm/protocol/privacy-token.js +17 -0
  152. package/dist/esm/protocol/privacy.js +55 -0
  153. package/dist/esm/protocol/stream.js +26 -1
  154. package/dist/esm/protocol/usync.js +11 -0
  155. package/dist/esm/retry/codec.js +216 -0
  156. package/dist/esm/retry/constants.js +1 -1
  157. package/dist/esm/retry/index.js +3 -2
  158. package/dist/esm/retry/parse.js +88 -86
  159. package/dist/esm/retry/replay.js +54 -51
  160. package/dist/esm/retry/tracker.js +94 -0
  161. package/dist/esm/signal/api/SignalDeviceSyncApi.js +276 -92
  162. package/dist/esm/signal/api/SignalDigestSyncApi.js +17 -8
  163. package/dist/esm/signal/api/SignalIdentitySyncApi.js +67 -37
  164. package/dist/esm/signal/api/SignalMissingPreKeysSyncApi.js +86 -67
  165. package/dist/esm/signal/api/SignalRotateKeyApi.js +4 -2
  166. package/dist/esm/signal/api/SignalSessionSyncApi.js +36 -34
  167. package/dist/esm/signal/api/result-map.js +10 -0
  168. package/dist/esm/signal/constants.js +0 -4
  169. package/dist/esm/signal/crypto/WaAdvSignature.js +13 -9
  170. package/dist/esm/signal/{store/sqlite.js → encoding.js} +93 -60
  171. package/dist/esm/signal/group/SenderKeyChain.js +28 -23
  172. package/dist/esm/signal/group/SenderKeyCodec.js +5 -6
  173. package/dist/esm/signal/group/SenderKeyManager.js +144 -115
  174. package/dist/esm/signal/index.js +2 -0
  175. package/dist/esm/signal/registration/keygen.js +6 -2
  176. package/dist/esm/signal/registration/utils.js +1 -0
  177. package/dist/esm/signal/session/SignalProtocol.js +164 -53
  178. package/dist/esm/signal/session/SignalRatchet.js +24 -15
  179. package/dist/esm/signal/session/SignalSession.js +14 -9
  180. package/dist/esm/signal/session/resolver.js +221 -0
  181. package/dist/esm/store/contracts/privacy-token.store.js +1 -0
  182. package/dist/esm/store/createStore.js +100 -188
  183. package/dist/esm/store/index.js +1 -10
  184. package/dist/esm/store/locks/appstate.lock.js +26 -0
  185. package/dist/esm/store/locks/auth.lock.js +15 -0
  186. package/dist/esm/store/locks/contact.lock.js +20 -0
  187. package/dist/esm/store/locks/device-list.lock.js +20 -0
  188. package/dist/esm/store/locks/message.lock.js +21 -0
  189. package/dist/esm/store/locks/participants.lock.js +20 -0
  190. package/dist/esm/store/locks/privacy-token.lock.js +18 -0
  191. package/dist/esm/store/locks/retry.lock.js +29 -0
  192. package/dist/esm/store/locks/sender-key.lock.js +52 -0
  193. package/dist/esm/store/locks/signal.lock.js +63 -0
  194. package/dist/esm/store/locks/thread.lock.js +21 -0
  195. package/dist/esm/store/noop.store.js +4 -7
  196. package/dist/esm/store/providers/memory/appstate.store.js +38 -16
  197. package/dist/esm/store/providers/memory/contact.store.js +5 -0
  198. package/dist/esm/store/providers/memory/device-list.store.js +12 -34
  199. package/dist/esm/store/providers/memory/message.store.js +11 -5
  200. package/dist/esm/store/providers/memory/participants.store.js +1 -8
  201. package/dist/esm/store/providers/memory/privacy-token.store.js +43 -0
  202. package/dist/esm/store/providers/memory/retry.store.js +77 -2
  203. package/dist/esm/store/providers/memory/sender-key.store.js +11 -8
  204. package/dist/esm/store/providers/memory/signal.store.js +47 -18
  205. package/dist/esm/store/providers/memory/thread.store.js +5 -0
  206. package/dist/esm/transport/WaComms.js +28 -24
  207. package/dist/esm/transport/WaWebSocket.js +115 -18
  208. package/dist/esm/transport/binary/constants.js +0 -30
  209. package/dist/esm/transport/binary/decoder.js +8 -8
  210. package/dist/esm/transport/binary/encoder.js +10 -9
  211. package/dist/esm/transport/binary/index.js +0 -1
  212. package/dist/esm/transport/index.js +1 -0
  213. package/dist/esm/transport/keepalive/WaKeepAlive.js +2 -8
  214. package/dist/esm/transport/node/WaNodeOrchestrator.js +25 -21
  215. package/dist/esm/transport/node/WaNodeTransport.js +0 -3
  216. package/dist/esm/transport/node/builders/{accountSync.js → account-sync.js} +16 -36
  217. package/dist/esm/transport/node/builders/business.js +129 -0
  218. package/dist/esm/transport/node/builders/global.js +370 -0
  219. package/dist/esm/transport/node/builders/index.js +7 -3
  220. package/dist/esm/transport/node/builders/message.js +63 -230
  221. package/dist/esm/transport/node/builders/pairing.js +2 -27
  222. package/dist/esm/transport/node/builders/privacy-token.js +41 -0
  223. package/dist/esm/transport/node/builders/privacy.js +48 -0
  224. package/dist/esm/transport/node/builders/profile.js +70 -0
  225. package/dist/esm/transport/node/builders/retry.js +10 -22
  226. package/dist/esm/transport/node/builders/usync.js +45 -0
  227. package/dist/esm/transport/node/helpers.js +125 -5
  228. package/dist/esm/transport/node/usync.js +5 -0
  229. package/dist/esm/transport/node/xml.js +35 -14
  230. package/dist/esm/transport/noise/WaClientPayload.js +10 -10
  231. package/dist/esm/transport/noise/WaFrameCodec.js +48 -33
  232. package/dist/esm/transport/noise/WaNoiseCert.js +4 -7
  233. package/dist/esm/transport/noise/WaNoiseSession.js +77 -29
  234. package/dist/esm/transport/noise/WaNoiseSocket.js +8 -4
  235. package/dist/esm/transport/proxy.js +27 -0
  236. package/dist/esm/transport/stream/parse.js +17 -48
  237. package/dist/esm/util/bytes.js +67 -45
  238. package/dist/esm/util/coercion.js +6 -14
  239. package/dist/esm/util/index.js +5 -0
  240. package/dist/esm/util/primitives.js +40 -14
  241. package/dist/index.js +7 -1
  242. package/dist/infra/log/ConsoleLogger.js +18 -17
  243. package/dist/infra/log/PinoLogger.js +15 -9
  244. package/dist/infra/log/types.js +12 -0
  245. package/dist/infra/perf/BackgroundQueue.js +482 -0
  246. package/dist/infra/perf/BoundedTaskQueue.js +16 -18
  247. package/dist/infra/perf/PromiseDedup.js +24 -0
  248. package/dist/infra/perf/SharedExclusiveGate.js +113 -0
  249. package/dist/infra/perf/StoreLock.js +81 -0
  250. package/dist/media/WaMediaCrypto.js +95 -15
  251. package/dist/media/WaMediaTransferClient.js +284 -91
  252. package/dist/media/conn.js +10 -6
  253. package/dist/media/constants.js +6 -2
  254. package/dist/message/WaMessageClient.js +31 -33
  255. package/dist/message/ack.js +6 -6
  256. package/dist/message/addon-crypto.js +65 -0
  257. package/dist/message/content.js +198 -9
  258. package/dist/message/icdc.js +81 -0
  259. package/dist/message/incoming.js +127 -120
  260. package/dist/message/index.js +2 -0
  261. package/dist/message/phash.js +3 -1
  262. package/dist/message/reporting-token.js +429 -0
  263. package/dist/message/use-case-secret.js +55 -0
  264. package/dist/protocol/appstate.js +28 -1
  265. package/dist/protocol/browser.js +10 -18
  266. package/dist/protocol/constants.js +26 -1
  267. package/dist/protocol/defaults.js +6 -0
  268. package/dist/protocol/index.js +23 -42
  269. package/dist/protocol/jid.js +140 -52
  270. package/dist/protocol/media.js +3 -3
  271. package/dist/protocol/message.js +62 -2
  272. package/dist/protocol/nodes.js +4 -0
  273. package/dist/protocol/notification.js +3 -1
  274. package/dist/protocol/privacy-token.js +20 -0
  275. package/dist/protocol/privacy.js +58 -0
  276. package/dist/protocol/stream.js +27 -2
  277. package/dist/protocol/usync.js +14 -0
  278. package/dist/retry/codec.js +220 -0
  279. package/dist/retry/constants.js +1 -1
  280. package/dist/retry/index.js +7 -5
  281. package/dist/retry/parse.js +88 -85
  282. package/dist/retry/replay.js +52 -49
  283. package/dist/retry/tracker.js +97 -0
  284. package/dist/signal/api/SignalDeviceSyncApi.js +273 -89
  285. package/dist/signal/api/SignalDigestSyncApi.js +17 -8
  286. package/dist/signal/api/SignalIdentitySyncApi.js +66 -36
  287. package/dist/signal/api/SignalMissingPreKeysSyncApi.js +82 -63
  288. package/dist/signal/api/SignalRotateKeyApi.js +4 -2
  289. package/dist/signal/api/SignalSessionSyncApi.js +36 -34
  290. package/dist/signal/api/result-map.js +13 -0
  291. package/dist/signal/constants.js +1 -5
  292. package/dist/signal/crypto/WaAdvSignature.js +11 -7
  293. package/dist/signal/{store/sqlite.js → encoding.js} +94 -61
  294. package/dist/signal/group/SenderKeyChain.js +27 -22
  295. package/dist/signal/group/SenderKeyCodec.js +5 -6
  296. package/dist/signal/group/SenderKeyManager.js +144 -115
  297. package/dist/signal/index.js +15 -1
  298. package/dist/signal/registration/keygen.js +6 -2
  299. package/dist/signal/registration/utils.js +1 -0
  300. package/dist/signal/session/SignalProtocol.js +164 -53
  301. package/dist/signal/session/SignalRatchet.js +24 -15
  302. package/dist/signal/session/SignalSession.js +14 -9
  303. package/dist/signal/session/resolver.js +224 -0
  304. package/dist/store/contracts/privacy-token.store.js +2 -0
  305. package/dist/store/createStore.js +100 -188
  306. package/dist/store/index.js +15 -33
  307. package/dist/store/locks/appstate.lock.js +29 -0
  308. package/dist/store/locks/auth.lock.js +18 -0
  309. package/dist/store/locks/contact.lock.js +23 -0
  310. package/dist/store/locks/device-list.lock.js +23 -0
  311. package/dist/store/locks/message.lock.js +24 -0
  312. package/dist/store/locks/participants.lock.js +23 -0
  313. package/dist/store/locks/privacy-token.lock.js +21 -0
  314. package/dist/store/locks/retry.lock.js +32 -0
  315. package/dist/store/locks/sender-key.lock.js +55 -0
  316. package/dist/store/locks/signal.lock.js +66 -0
  317. package/dist/store/locks/thread.lock.js +24 -0
  318. package/dist/store/noop.store.js +4 -7
  319. package/dist/store/providers/memory/appstate.store.js +36 -14
  320. package/dist/store/providers/memory/contact.store.js +5 -0
  321. package/dist/store/providers/memory/device-list.store.js +12 -34
  322. package/dist/store/providers/memory/message.store.js +11 -5
  323. package/dist/store/providers/memory/participants.store.js +1 -8
  324. package/dist/store/providers/memory/privacy-token.store.js +47 -0
  325. package/dist/store/providers/memory/retry.store.js +77 -2
  326. package/dist/store/providers/memory/sender-key.store.js +14 -11
  327. package/dist/store/providers/memory/signal.store.js +54 -25
  328. package/dist/store/providers/memory/thread.store.js +5 -0
  329. package/dist/transport/WaComms.js +30 -26
  330. package/dist/transport/WaWebSocket.js +148 -18
  331. package/dist/transport/binary/constants.js +1 -31
  332. package/dist/transport/binary/decoder.js +8 -8
  333. package/dist/transport/binary/encoder.js +10 -9
  334. package/dist/transport/binary/index.js +0 -4
  335. package/dist/transport/index.js +7 -1
  336. package/dist/transport/keepalive/WaKeepAlive.js +1 -7
  337. package/dist/transport/node/WaNodeOrchestrator.js +25 -21
  338. package/dist/transport/node/WaNodeTransport.js +0 -3
  339. package/dist/transport/node/builders/{accountSync.js → account-sync.js} +15 -35
  340. package/dist/transport/node/builders/business.js +137 -0
  341. package/dist/transport/node/builders/global.js +375 -0
  342. package/dist/transport/node/builders/index.js +29 -17
  343. package/dist/transport/node/builders/message.js +64 -236
  344. package/dist/transport/node/builders/pairing.js +2 -29
  345. package/dist/transport/node/builders/privacy-token.js +46 -0
  346. package/dist/transport/node/builders/privacy.js +55 -0
  347. package/dist/transport/node/builders/profile.js +78 -0
  348. package/dist/transport/node/builders/retry.js +9 -21
  349. package/dist/transport/node/builders/usync.js +49 -0
  350. package/dist/transport/node/helpers.js +131 -4
  351. package/dist/transport/node/usync.js +8 -0
  352. package/dist/transport/node/xml.js +35 -14
  353. package/dist/transport/noise/WaClientPayload.js +13 -13
  354. package/dist/transport/noise/WaFrameCodec.js +47 -32
  355. package/dist/transport/noise/WaNoiseCert.js +5 -8
  356. package/dist/transport/noise/WaNoiseSession.js +77 -29
  357. package/dist/transport/noise/WaNoiseSocket.js +8 -4
  358. package/dist/transport/proxy.js +34 -0
  359. package/dist/transport/stream/parse.js +20 -52
  360. package/dist/types/appstate/WaAppStateCrypto.d.ts +0 -1
  361. package/dist/types/appstate/WaAppStateSyncClient.d.ts +5 -2
  362. package/dist/types/appstate/constants.d.ts +1 -0
  363. package/dist/types/appstate/encoding.d.ts +7 -0
  364. package/dist/types/appstate/index.d.ts +3 -3
  365. package/dist/types/appstate/utils.d.ts +0 -3
  366. package/dist/types/auth/WaAuthClient.d.ts +10 -12
  367. package/dist/types/auth/flow/WaAuthCredentialsFlow.d.ts +1 -1
  368. package/dist/types/auth/index.d.ts +0 -4
  369. package/dist/types/auth/pairing/WaQrFlow.d.ts +1 -1
  370. package/dist/types/auth/types.d.ts +7 -9
  371. package/dist/types/client/WaClient.d.ts +42 -25
  372. package/dist/types/client/WaClientFactory.d.ts +33 -26
  373. package/dist/types/client/connection/WaConnectionManager.d.ts +66 -0
  374. package/dist/types/client/connection/WaKeyShareCoordinator.d.ts +14 -0
  375. package/dist/types/client/connection/WaReceiptQueue.d.ts +13 -0
  376. package/dist/types/client/coordinators/WaAppStateMutationCoordinator.d.ts +46 -0
  377. package/dist/types/client/coordinators/WaBusinessCoordinator.d.ts +57 -0
  378. package/dist/types/client/coordinators/WaIncomingNodeCoordinator.d.ts +3 -2
  379. package/dist/types/client/coordinators/WaMessageDispatchCoordinator.d.ts +29 -38
  380. package/dist/types/client/coordinators/WaPassiveTasksCoordinator.d.ts +4 -0
  381. package/dist/types/client/coordinators/WaPrivacyCoordinator.d.ts +26 -0
  382. package/dist/types/client/coordinators/WaProfileCoordinator.d.ts +36 -0
  383. package/dist/types/client/coordinators/WaRetryCoordinator.d.ts +8 -0
  384. package/dist/types/client/coordinators/WaStreamControlCoordinator.d.ts +3 -2
  385. package/dist/types/client/coordinators/WaTrustedContactTokenCoordinator.d.ts +45 -0
  386. package/dist/types/client/dirty.d.ts +1 -0
  387. package/dist/types/client/events/devices.d.ts +20 -0
  388. package/dist/types/client/events/group.d.ts +2 -1
  389. package/dist/types/client/events/identity.d.ts +9 -0
  390. package/dist/types/client/events/privacy-token.d.ts +7 -0
  391. package/dist/types/client/history-sync.d.ts +9 -6
  392. package/dist/types/client/incoming.d.ts +3 -1
  393. package/dist/types/client/index.d.ts +1 -1
  394. package/dist/types/client/mailbox.d.ts +3 -5
  395. package/dist/types/client/messages.d.ts +1 -2
  396. package/dist/types/client/messaging/fanout.d.ts +14 -0
  397. package/dist/types/client/messaging/key-protocol.d.ts +18 -0
  398. package/dist/types/client/messaging/participants.d.ts +13 -0
  399. package/dist/types/client/persistence/WriteBehindPersistence.d.ts +34 -0
  400. package/dist/types/client/tokens/cs-token.d.ts +10 -0
  401. package/dist/types/client/tokens/tc-token.d.ts +5 -0
  402. package/dist/types/client/types.d.ts +75 -4
  403. package/dist/types/crypto/core/hkdf.d.ts +0 -6
  404. package/dist/types/crypto/core/index.d.ts +2 -3
  405. package/dist/types/crypto/core/nonce.d.ts +2 -0
  406. package/dist/types/crypto/core/primitives.d.ts +0 -1
  407. package/dist/types/crypto/core/random.d.ts +2 -7
  408. package/dist/types/crypto/index.d.ts +0 -1
  409. package/dist/types/crypto/math/constants.d.ts +4 -2
  410. package/dist/types/crypto/math/fe.d.ts +30 -0
  411. package/dist/types/crypto/math/mod.d.ts +0 -2
  412. package/dist/types/crypto/math/types.d.ts +11 -4
  413. package/dist/types/index.d.ts +5 -3
  414. package/dist/types/infra/log/ConsoleLogger.d.ts +2 -1
  415. package/dist/types/infra/log/PinoLogger.d.ts +1 -1
  416. package/dist/types/infra/log/types.d.ts +1 -0
  417. package/dist/types/infra/perf/BackgroundQueue.d.ts +58 -0
  418. package/dist/types/infra/perf/BoundedTaskQueue.d.ts +1 -1
  419. package/dist/types/infra/perf/PromiseDedup.d.ts +4 -0
  420. package/dist/types/infra/perf/SharedExclusiveGate.d.ts +17 -0
  421. package/dist/types/infra/perf/StoreLock.d.ts +10 -0
  422. package/dist/types/media/WaMediaCrypto.d.ts +3 -2
  423. package/dist/types/media/WaMediaTransferClient.d.ts +16 -15
  424. package/dist/types/media/constants.d.ts +1 -1
  425. package/dist/types/media/index.d.ts +1 -1
  426. package/dist/types/media/types.d.ts +15 -2
  427. package/dist/types/message/addon-crypto.d.ts +25 -0
  428. package/dist/types/message/content.d.ts +8 -0
  429. package/dist/types/message/icdc.d.ts +13 -0
  430. package/dist/types/message/index.d.ts +2 -0
  431. package/dist/types/message/reporting-token.d.ts +18 -0
  432. package/dist/types/message/types.d.ts +45 -6
  433. package/dist/types/message/use-case-secret.d.ts +20 -0
  434. package/dist/types/protocol/appstate.d.ts +47 -0
  435. package/dist/types/protocol/constants.d.ts +8 -3
  436. package/dist/types/protocol/defaults.d.ts +6 -0
  437. package/dist/types/protocol/index.d.ts +2 -11
  438. package/dist/types/protocol/jid.d.ts +22 -5
  439. package/dist/types/protocol/message.d.ts +60 -0
  440. package/dist/types/protocol/nodes.d.ts +4 -0
  441. package/dist/types/protocol/notification.d.ts +2 -0
  442. package/dist/types/protocol/privacy-token.d.ts +17 -0
  443. package/dist/types/protocol/privacy.d.ts +75 -0
  444. package/dist/types/protocol/stream.d.ts +30 -0
  445. package/dist/types/protocol/usync.d.ts +11 -0
  446. package/dist/types/retry/codec.d.ts +3 -0
  447. package/dist/types/retry/index.d.ts +4 -3
  448. package/dist/types/retry/parse.d.ts +5 -2
  449. package/dist/types/retry/replay.d.ts +0 -4
  450. package/dist/types/retry/tracker.d.ts +20 -0
  451. package/dist/types/retry/types.d.ts +10 -4
  452. package/dist/types/signal/api/SignalDeviceSyncApi.d.ts +15 -2
  453. package/dist/types/signal/api/SignalDigestSyncApi.d.ts +6 -0
  454. package/dist/types/signal/api/SignalIdentitySyncApi.d.ts +2 -0
  455. package/dist/types/signal/api/SignalRotateKeyApi.d.ts +4 -5
  456. package/dist/types/signal/api/SignalSessionSyncApi.d.ts +8 -6
  457. package/dist/types/signal/api/result-map.d.ts +1 -0
  458. package/dist/types/signal/constants.d.ts +0 -3
  459. package/dist/types/signal/{store/sqlite.d.ts → encoding.d.ts} +3 -3
  460. package/dist/types/signal/group/SenderKeyCodec.d.ts +4 -6
  461. package/dist/types/signal/group/SenderKeyManager.d.ts +10 -5
  462. package/dist/types/signal/index.d.ts +3 -0
  463. package/dist/types/signal/session/SignalProtocol.d.ts +19 -4
  464. package/dist/types/signal/session/resolver.d.ts +22 -0
  465. package/dist/types/store/contracts/appstate.store.d.ts +4 -1
  466. package/dist/types/store/contracts/contact.store.d.ts +1 -0
  467. package/dist/types/store/contracts/device-list.store.d.ts +0 -3
  468. package/dist/types/store/contracts/message.store.d.ts +1 -0
  469. package/dist/types/store/contracts/participants.store.d.ts +0 -1
  470. package/dist/types/store/contracts/privacy-token.store.d.ts +16 -0
  471. package/dist/types/store/contracts/retry.store.d.ts +7 -0
  472. package/dist/types/store/contracts/sender-key.store.d.ts +0 -1
  473. package/dist/types/store/contracts/signal.store.d.ts +13 -0
  474. package/dist/types/store/contracts/thread.store.d.ts +1 -0
  475. package/dist/types/store/createStore.d.ts +1 -1
  476. package/dist/types/store/index.d.ts +5 -13
  477. package/dist/types/store/locks/appstate.lock.d.ts +3 -0
  478. package/dist/types/store/locks/auth.lock.d.ts +3 -0
  479. package/dist/types/store/locks/contact.lock.d.ts +3 -0
  480. package/dist/types/store/locks/device-list.lock.d.ts +2 -0
  481. package/dist/types/store/locks/message.lock.d.ts +3 -0
  482. package/dist/types/store/locks/participants.lock.d.ts +2 -0
  483. package/dist/types/store/locks/privacy-token.lock.d.ts +2 -0
  484. package/dist/types/store/locks/retry.lock.d.ts +2 -0
  485. package/dist/types/store/locks/sender-key.lock.d.ts +3 -0
  486. package/dist/types/store/locks/signal.lock.d.ts +3 -0
  487. package/dist/types/store/locks/thread.lock.d.ts +3 -0
  488. package/dist/types/store/providers/memory/appstate.store.d.ts +3 -1
  489. package/dist/types/store/providers/memory/contact.store.d.ts +1 -0
  490. package/dist/types/store/providers/memory/device-list.store.d.ts +0 -3
  491. package/dist/types/store/providers/memory/message.store.d.ts +1 -0
  492. package/dist/types/store/providers/memory/participants.store.d.ts +0 -1
  493. package/dist/types/store/providers/memory/privacy-token.store.d.ts +13 -0
  494. package/dist/types/store/providers/memory/retry.store.d.ts +8 -0
  495. package/dist/types/store/providers/memory/sender-key.store.d.ts +0 -1
  496. package/dist/types/store/providers/memory/signal.store.d.ts +8 -1
  497. package/dist/types/store/providers/memory/thread.store.d.ts +1 -0
  498. package/dist/types/store/types.d.ts +49 -58
  499. package/dist/types/transport/WaWebSocket.d.ts +3 -1
  500. package/dist/types/transport/binary/constants.d.ts +0 -30
  501. package/dist/types/transport/binary/index.d.ts +0 -1
  502. package/dist/types/transport/index.d.ts +2 -1
  503. package/dist/types/transport/keepalive/WaKeepAlive.d.ts +0 -1
  504. package/dist/types/transport/node/WaNodeOrchestrator.d.ts +3 -4
  505. package/dist/types/transport/node/WaNodeTransport.d.ts +0 -9
  506. package/dist/types/transport/node/builders/business.d.ts +29 -0
  507. package/dist/types/transport/node/builders/global.d.ts +102 -0
  508. package/dist/types/transport/node/builders/group.d.ts +4 -6
  509. package/dist/types/transport/node/builders/index.d.ts +7 -3
  510. package/dist/types/transport/node/builders/message.d.ts +20 -30
  511. package/dist/types/transport/node/builders/pairing.d.ts +0 -2
  512. package/dist/types/transport/node/builders/privacy-token.d.ts +9 -0
  513. package/dist/types/transport/node/builders/privacy.d.ts +7 -0
  514. package/dist/types/transport/node/builders/profile.d.ts +8 -0
  515. package/dist/types/transport/node/builders/retry.d.ts +2 -5
  516. package/dist/types/transport/node/builders/usync.d.ts +21 -0
  517. package/dist/types/transport/node/helpers.d.ts +13 -0
  518. package/dist/types/transport/node/usync.d.ts +2 -0
  519. package/dist/types/transport/noise/WaFrameCodec.d.ts +3 -0
  520. package/dist/types/transport/noise/WaNoiseSession.d.ts +4 -2
  521. package/dist/types/transport/noise/WaNoiseSocket.d.ts +4 -2
  522. package/dist/types/transport/proxy.d.ts +6 -0
  523. package/dist/types/transport/stream/parse.d.ts +0 -1
  524. package/dist/types/transport/types.d.ts +18 -1
  525. package/dist/types/util/bytes.d.ts +5 -0
  526. package/dist/types/util/index.d.ts +5 -0
  527. package/dist/types/util/primitives.d.ts +2 -0
  528. package/dist/util/bytes.js +72 -46
  529. package/dist/util/coercion.js +6 -14
  530. package/dist/util/index.js +23 -0
  531. package/dist/util/primitives.js +42 -14
  532. package/package.json +52 -9
  533. package/proto/index.js +1 -1
  534. package/dist/crypto/core/constants.js +0 -4
  535. package/dist/crypto/core/encoding.js +0 -29
  536. package/dist/esm/crypto/core/constants.js +0 -1
  537. package/dist/esm/crypto/core/encoding.js +0 -25
  538. package/dist/esm/retry/outbound.js +0 -83
  539. package/dist/esm/store/providers/sqlite/BaseSqliteStore.js +0 -37
  540. package/dist/esm/store/providers/sqlite/appstate.store.js +0 -169
  541. package/dist/esm/store/providers/sqlite/auth.store.js +0 -176
  542. package/dist/esm/store/providers/sqlite/connection.js +0 -240
  543. package/dist/esm/store/providers/sqlite/contact.store.js +0 -61
  544. package/dist/esm/store/providers/sqlite/device-list.store.js +0 -155
  545. package/dist/esm/store/providers/sqlite/message.store.js +0 -119
  546. package/dist/esm/store/providers/sqlite/migrations.js +0 -347
  547. package/dist/esm/store/providers/sqlite/participants.store.js +0 -85
  548. package/dist/esm/store/providers/sqlite/retry.store.js +0 -144
  549. package/dist/esm/store/providers/sqlite/sender-key.store.js +0 -203
  550. package/dist/esm/store/providers/sqlite/signal.store.js +0 -353
  551. package/dist/esm/store/providers/sqlite/thread.store.js +0 -72
  552. package/dist/esm/util/base64.js +0 -18
  553. package/dist/esm/util/signal-address.js +0 -5
  554. package/dist/retry/outbound.js +0 -88
  555. package/dist/store/providers/sqlite/BaseSqliteStore.js +0 -41
  556. package/dist/store/providers/sqlite/appstate.store.js +0 -173
  557. package/dist/store/providers/sqlite/auth.store.js +0 -180
  558. package/dist/store/providers/sqlite/connection.js +0 -276
  559. package/dist/store/providers/sqlite/contact.store.js +0 -65
  560. package/dist/store/providers/sqlite/device-list.store.js +0 -159
  561. package/dist/store/providers/sqlite/message.store.js +0 -123
  562. package/dist/store/providers/sqlite/migrations.js +0 -350
  563. package/dist/store/providers/sqlite/participants.store.js +0 -89
  564. package/dist/store/providers/sqlite/retry.store.js +0 -148
  565. package/dist/store/providers/sqlite/sender-key.store.js +0 -207
  566. package/dist/store/providers/sqlite/signal.store.js +0 -357
  567. package/dist/store/providers/sqlite/thread.store.js +0 -76
  568. package/dist/types/appstate/store/sqlite.d.ts +0 -21
  569. package/dist/types/crypto/core/constants.d.ts +0 -1
  570. package/dist/types/crypto/core/encoding.d.ts +0 -11
  571. package/dist/types/retry/outbound.d.ts +0 -4
  572. package/dist/types/store/providers/sqlite/BaseSqliteStore.d.ts +0 -12
  573. package/dist/types/store/providers/sqlite/appstate.store.d.ts +0 -15
  574. package/dist/types/store/providers/sqlite/auth.store.d.ts +0 -10
  575. package/dist/types/store/providers/sqlite/connection.d.ts +0 -10
  576. package/dist/types/store/providers/sqlite/contact.store.d.ts +0 -10
  577. package/dist/types/store/providers/sqlite/device-list.store.d.ts +0 -18
  578. package/dist/types/store/providers/sqlite/message.store.d.ts +0 -11
  579. package/dist/types/store/providers/sqlite/migrations.d.ts +0 -3
  580. package/dist/types/store/providers/sqlite/participants.store.d.ts +0 -13
  581. package/dist/types/store/providers/sqlite/retry.store.d.ts +0 -16
  582. package/dist/types/store/providers/sqlite/sender-key.store.d.ts +0 -25
  583. package/dist/types/store/providers/sqlite/signal.store.d.ts +0 -46
  584. package/dist/types/store/providers/sqlite/thread.store.d.ts +0 -11
  585. package/dist/types/util/base64.d.ts +0 -4
  586. package/dist/types/util/signal-address.d.ts +0 -2
  587. package/dist/util/base64.js +0 -24
  588. package/dist/util/signal-address.js +0 -8
  589. /package/dist/types/transport/node/builders/{accountSync.d.ts → account-sync.d.ts} +0 -0
@@ -2,13 +2,14 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.WaAppStateSyncClient = exports.WaAppStateMissingKeyError = void 0;
4
4
  const constants_1 = require("./constants");
5
- const utils_1 = require("./utils");
6
5
  const WaAppStateCrypto_1 = require("./WaAppStateCrypto");
7
6
  const WaAppStateSyncResponseParser_1 = require("./WaAppStateSyncResponseParser");
8
7
  const _proto_1 = require("../proto.js");
9
8
  const constants_2 = require("../protocol/constants");
10
- const base64_1 = require("../util/base64");
9
+ const jid_1 = require("../protocol/jid");
10
+ const query_1 = require("../transport/node/query");
11
11
  const bytes_1 = require("../util/bytes");
12
+ const bytes_2 = require("../util/bytes");
12
13
  const primitives_1 = require("../util/primitives");
13
14
  class WaAppStateMissingKeyError extends Error {
14
15
  constructor(message, keyId, collection) {
@@ -24,6 +25,7 @@ class WaAppStateSyncClient {
24
25
  this.logger = options.logger;
25
26
  this.query = options.query;
26
27
  this.store = options.store;
28
+ this.getCurrentMeJid = options.getCurrentMeJid;
27
29
  this.hostDomain = options.hostDomain ?? constants_2.WA_DEFAULTS.HOST_DOMAIN;
28
30
  this.defaultTimeoutMs = options.defaultTimeoutMs ?? constants_2.WA_DEFAULTS.APP_STATE_SYNC_TIMEOUT_MS;
29
31
  this.onMissingKeys = options.onMissingKeys;
@@ -47,14 +49,14 @@ class WaAppStateSyncClient {
47
49
  async importSyncKeyShare(share) {
48
50
  const keys = [];
49
51
  for (const item of share.keys ?? []) {
50
- const keyId = (0, base64_1.decodeProtoBytes)(item.keyId?.keyId, 'appStateSyncKeyShare.keys[].keyId.keyId');
52
+ const keyId = (0, bytes_1.decodeProtoBytes)(item.keyId?.keyId, 'appStateSyncKeyShare.keys[].keyId.keyId');
51
53
  if (!item.keyData?.keyData) {
52
54
  this.logger.debug('app-state sync key share entry missing key data', {
53
- keyId: (0, utils_1.keyIdToHex)(keyId)
55
+ keyId: (0, bytes_2.bytesToHex)(keyId)
54
56
  });
55
57
  continue;
56
58
  }
57
- const keyData = (0, base64_1.decodeProtoBytes)(item.keyData?.keyData, 'appStateSyncKeyShare.keys[].keyData.keyData');
59
+ const keyData = (0, bytes_1.decodeProtoBytes)(item.keyData?.keyData, 'appStateSyncKeyShare.keys[].keyData.keyData');
58
60
  keys.push({
59
61
  keyId,
60
62
  keyData,
@@ -93,6 +95,10 @@ class WaAppStateSyncClient {
93
95
  ...new Set(options.collections ?? constants_1.APP_STATE_DEFAULT_COLLECTIONS)
94
96
  ];
95
97
  try {
98
+ const initialCollectionStates = await this.store.getCollectionStates(collections);
99
+ for (let index = 0; index < collections.length; index += 1) {
100
+ context.collections.set(collections[index], initialCollectionStates[index]);
101
+ }
96
102
  this.logger.info('app-state sync start', {
97
103
  collections: collections.length,
98
104
  pendingMutations: options.pendingMutations?.length ?? 0
@@ -162,36 +168,18 @@ class WaAppStateSyncClient {
162
168
  }
163
169
  }
164
170
  async syncCollectionsRound(collections, pendingByCollection, options) {
165
- const prepared = await this.prepareSyncRoundRequest(collections, pendingByCollection);
166
- const iqNode = this.buildSyncIqNode(prepared.collectionNodes);
167
- const payloadByCollection = await this.fetchSyncPayloadByCollection(iqNode, options.timeoutMs ?? this.defaultTimeoutMs);
168
- const collectionOutcomes = await Promise.all(collections.map((collection) => this.processCollectionRound({
169
- collection,
170
- payloadByCollection,
171
- pendingByCollection,
172
- options,
173
- outgoingContexts: prepared.outgoingContexts,
174
- skippedUploadCollections: prepared.skippedUploadCollections
175
- })));
176
- return {
177
- results: collectionOutcomes.map((entry) => entry.result),
178
- collectionsToRefetch: collectionOutcomes
179
- .filter((entry) => entry.shouldRefetch)
180
- .map((entry) => entry.collection),
181
- stateChanged: collectionOutcomes.some((entry) => entry.stateChanged),
182
- missingKeyIds: this.collectDistinctMissingKeyIds(collectionOutcomes
183
- .map((entry) => entry.missingKeyId)
184
- .filter((value) => value !== null)),
185
- blockedCollections: collectionOutcomes
186
- .filter((entry) => entry.result.state === constants_2.WA_APP_STATE_COLLECTION_STATES.BLOCKED)
187
- .map((entry) => entry.collection)
188
- };
189
- }
190
- async prepareSyncRoundRequest(collections, pendingByCollection) {
191
- const requests = await Promise.all(collections.map((collection) => this.buildCollectionSyncRequest(collection, pendingByCollection)));
171
+ const activeSyncKey = await this.store.getActiveSyncKey();
172
+ const requestPromises = new Array(collections.length);
173
+ for (let index = 0; index < collections.length; index += 1) {
174
+ requestPromises[index] = this.buildCollectionSyncRequest(collections[index], pendingByCollection, activeSyncKey);
175
+ }
176
+ const requests = await Promise.all(requestPromises);
177
+ const collectionNodes = new Array(requests.length);
192
178
  const outgoingContexts = new Map();
193
179
  const skippedUploadCollections = new Set();
194
- for (const request of requests) {
180
+ for (let index = 0; index < requests.length; index += 1) {
181
+ const request = requests[index];
182
+ collectionNodes[index] = request.node;
195
183
  if (request.outgoingContext) {
196
184
  outgoingContexts.set(request.collection, request.outgoingContext);
197
185
  }
@@ -199,26 +187,62 @@ class WaAppStateSyncClient {
199
187
  skippedUploadCollections.add(request.collection);
200
188
  }
201
189
  }
190
+ const iqNode = this.buildSyncIqNode(collectionNodes);
191
+ const payloadByCollection = await this.fetchSyncPayloadByCollection(iqNode, options.timeoutMs ?? this.defaultTimeoutMs);
192
+ const collectionOutcomePromises = new Array(collections.length);
193
+ for (let index = 0; index < collections.length; index += 1) {
194
+ collectionOutcomePromises[index] = this.processCollectionRound({
195
+ collection: collections[index],
196
+ payloadByCollection,
197
+ pendingByCollection,
198
+ options,
199
+ outgoingContexts,
200
+ skippedUploadCollections
201
+ });
202
+ }
203
+ const collectionOutcomes = await Promise.all(collectionOutcomePromises);
204
+ const results = [];
205
+ const collectionsToRefetch = [];
206
+ const blockedCollections = [];
207
+ const missingKeyIds = [];
208
+ const missingKeyIdHexes = new Set();
209
+ let stateChanged = false;
210
+ for (let index = 0; index < collectionOutcomes.length; index += 1) {
211
+ const entry = collectionOutcomes[index];
212
+ results.push(entry.result);
213
+ if (entry.shouldRefetch) {
214
+ collectionsToRefetch.push(entry.collection);
215
+ }
216
+ if (entry.stateChanged) {
217
+ stateChanged = true;
218
+ }
219
+ if (entry.result.state === constants_2.WA_APP_STATE_COLLECTION_STATES.BLOCKED) {
220
+ blockedCollections.push(entry.collection);
221
+ }
222
+ if (entry.missingKeyId) {
223
+ const keyHex = (0, bytes_2.bytesToHex)(entry.missingKeyId);
224
+ if (!missingKeyIdHexes.has(keyHex)) {
225
+ missingKeyIdHexes.add(keyHex);
226
+ missingKeyIds.push(entry.missingKeyId);
227
+ }
228
+ }
229
+ }
202
230
  return {
203
- collectionNodes: requests.map((request) => request.node),
204
- outgoingContexts,
205
- skippedUploadCollections
231
+ results,
232
+ collectionsToRefetch,
233
+ stateChanged,
234
+ missingKeyIds,
235
+ blockedCollections
206
236
  };
207
237
  }
208
- async buildCollectionSyncRequest(collection, pendingByCollection) {
238
+ async buildCollectionSyncRequest(collection, pendingByCollection, activeSyncKey) {
209
239
  const collectionState = await this.getCollectionState(collection);
210
- const hasPersistedState = collectionState.version > 0 ||
211
- collectionState.indexValueMap.size > 0 ||
212
- !(0, bytes_1.uint8Equal)(collectionState.hash, constants_1.APP_STATE_EMPTY_LT_HASH);
240
+ const hasPersistedState = collectionState.initialized;
213
241
  const attrs = {
214
- name: collection
242
+ name: collection,
243
+ version: String(hasPersistedState ? collectionState.version : constants_1.APP_STATE_DEFAULT_COLLECTION_VERSION),
244
+ return_snapshot: hasPersistedState ? 'false' : 'true'
215
245
  };
216
- if (hasPersistedState) {
217
- attrs.version = String(collectionState.version);
218
- }
219
- else {
220
- attrs.return_snapshot = 'true';
221
- }
222
246
  const children = [];
223
247
  const pendingMutations = pendingByCollection.get(collection) ?? [];
224
248
  let outgoingContext;
@@ -232,7 +256,7 @@ class WaAppStateSyncClient {
232
256
  });
233
257
  }
234
258
  else {
235
- const outgoing = await this.buildOutgoingPatch(collection, collectionState, pendingMutations);
259
+ const outgoing = await this.buildOutgoingPatch(collection, collectionState, pendingMutations, activeSyncKey);
236
260
  outgoingContext = outgoing.context;
237
261
  children.push({
238
262
  tag: constants_2.WA_NODE_TAGS.PATCH,
@@ -275,6 +299,7 @@ class WaAppStateSyncClient {
275
299
  tag: responseNode.tag,
276
300
  type: responseNode.attrs.type
277
301
  });
302
+ (0, query_1.assertIqResult)(responseNode, 'app-state sync');
278
303
  const payloads = (0, WaAppStateSyncResponseParser_1.parseSyncResponse)(responseNode);
279
304
  this.logger.debug('app-state sync payloads parsed', { count: payloads.length });
280
305
  const payloadByCollection = new Map();
@@ -296,20 +321,16 @@ class WaAppStateSyncClient {
296
321
  return this.createCollectionOutcome(collection, payload.state, payload.version);
297
322
  }
298
323
  const pendingMutationsCount = pendingByCollection.get(collection)?.length ?? 0;
299
- if (payload.state === constants_2.WA_APP_STATE_COLLECTION_STATES.CONFLICT_HAS_MORE) {
300
- shouldRefetch = true;
301
- }
302
- else if (payload.state === constants_2.WA_APP_STATE_COLLECTION_STATES.CONFLICT &&
303
- pendingMutationsCount > 0) {
304
- shouldRefetch = true;
305
- }
306
- if (payload.state === constants_2.WA_APP_STATE_COLLECTION_STATES.CONFLICT) {
307
- return this.createCollectionOutcome(collection, pendingMutationsCount > 0
308
- ? constants_2.WA_APP_STATE_COLLECTION_STATES.CONFLICT
309
- : constants_2.WA_APP_STATE_COLLECTION_STATES.SUCCESS, payload.version, shouldRefetch);
310
- }
311
- if (payload.state === constants_2.WA_APP_STATE_COLLECTION_STATES.CONFLICT_HAS_MORE) {
312
- return this.createCollectionOutcome(collection, payload.state, payload.version, shouldRefetch);
324
+ if (payload.state === constants_2.WA_APP_STATE_COLLECTION_STATES.CONFLICT ||
325
+ payload.state === constants_2.WA_APP_STATE_COLLECTION_STATES.CONFLICT_HAS_MORE) {
326
+ shouldRefetch =
327
+ payload.state === constants_2.WA_APP_STATE_COLLECTION_STATES.CONFLICT_HAS_MORE ||
328
+ pendingMutationsCount > 0;
329
+ return this.createCollectionOutcome(collection, payload.state === constants_2.WA_APP_STATE_COLLECTION_STATES.CONFLICT
330
+ ? pendingMutationsCount > 0
331
+ ? constants_2.WA_APP_STATE_COLLECTION_STATES.CONFLICT
332
+ : constants_2.WA_APP_STATE_COLLECTION_STATES.SUCCESS
333
+ : payload.state, payload.version, shouldRefetch);
313
334
  }
314
335
  try {
315
336
  let appliedMutations = [];
@@ -321,14 +342,14 @@ class WaAppStateSyncClient {
321
342
  const snapshotBytes = await downloader(payload.collection, 'snapshot', payload.snapshotReference);
322
343
  const snapshot = this.validateSnapshot(payload.collection, _proto_1.proto.SyncdSnapshot.decode(snapshotBytes));
323
344
  const snapshotMutations = await this.applySnapshot(payload.collection, snapshot);
324
- appliedMutations = appliedMutations.concat(snapshotMutations);
345
+ appliedMutations.push(...snapshotMutations);
325
346
  collectionStateChanged = true;
326
347
  }
327
348
  if (payload.patches.length > 0) {
328
349
  const readyPatches = await this.resolveReadyPatches(payload, options);
329
350
  for (const readyPatch of readyPatches) {
330
351
  const patchMutations = await this.applyPatch(payload.collection, readyPatch);
331
- appliedMutations = appliedMutations.concat(patchMutations);
352
+ appliedMutations.push(...patchMutations);
332
353
  collectionStateChanged = true;
333
354
  }
334
355
  }
@@ -341,13 +362,17 @@ class WaAppStateSyncClient {
341
362
  collectionStateChanged = true;
342
363
  }
343
364
  }
344
- if (payload.state === constants_2.WA_APP_STATE_COLLECTION_STATES.SUCCESS_HAS_MORE) {
345
- shouldRefetch = true;
346
- }
347
- if (payload.state === constants_2.WA_APP_STATE_COLLECTION_STATES.SUCCESS &&
348
- skippedUploadCollections.has(collection)) {
349
- shouldRefetch = true;
365
+ const currentCollectionState = await this.getCollectionState(collection);
366
+ if (!currentCollectionState.initialized &&
367
+ payload.state === constants_2.WA_APP_STATE_COLLECTION_STATES.SUCCESS) {
368
+ this.setCollectionState(collection, payload.version ?? currentCollectionState.version, currentCollectionState.hash, currentCollectionState.indexValueMap);
369
+ collectionStateChanged = true;
350
370
  }
371
+ shouldRefetch =
372
+ shouldRefetch ||
373
+ payload.state === constants_2.WA_APP_STATE_COLLECTION_STATES.SUCCESS_HAS_MORE ||
374
+ (payload.state === constants_2.WA_APP_STATE_COLLECTION_STATES.SUCCESS &&
375
+ skippedUploadCollections.has(collection));
351
376
  this.logger.debug('app-state collection processed', {
352
377
  collection: payload.collection,
353
378
  state: payload.state,
@@ -386,24 +411,13 @@ class WaAppStateSyncClient {
386
411
  }
387
412
  };
388
413
  }
389
- collectDistinctMissingKeyIds(keyIds) {
390
- const byHex = new Map();
391
- for (const keyId of keyIds) {
392
- const keyHex = (0, utils_1.keyIdToHex)(keyId);
393
- if (byHex.has(keyHex)) {
394
- continue;
395
- }
396
- byHex.set(keyHex, keyId);
397
- }
398
- return [...byHex.values()];
399
- }
400
414
  async notifyMissingKeys(input) {
401
- const keyIds = this.collectDistinctMissingKeyIds(input.keyIds);
402
- const collections = [...new Set(input.collections)];
415
+ const keyIds = input.keyIds;
416
+ const collections = input.collections;
403
417
  if (keyIds.length === 0 || collections.length === 0) {
404
418
  return;
405
419
  }
406
- const keyIdsHex = keyIds.map((keyId) => (0, utils_1.keyIdToHex)(keyId));
420
+ const keyIdsHex = keyIds.map((keyId) => (0, bytes_2.bytesToHex)(keyId));
407
421
  this.logger.info('app-state requesting missing sync keys', {
408
422
  keys: keyIdsHex.length,
409
423
  keyIds: keyIdsHex.join(','),
@@ -424,13 +438,12 @@ class WaAppStateSyncClient {
424
438
  }
425
439
  }
426
440
  async resolveReadyPatches(payload, options) {
427
- const sortedPatches = payload.patches
428
- .map((patch) => ({
429
- patch,
430
- sortVersion: this.parseCollectionPatchVersion(payload.collection, patch)
431
- }))
432
- .sort((left, right) => left.sortVersion - right.sortVersion)
433
- .map((entry) => entry.patch);
441
+ const sortedPatches = payload.patches.slice();
442
+ const sortVersions = new Map();
443
+ for (const patch of sortedPatches) {
444
+ sortVersions.set(patch, this.parseCollectionPatchVersion(payload.collection, patch));
445
+ }
446
+ sortedPatches.sort((left, right) => sortVersions.get(left) - sortVersions.get(right));
434
447
  return Promise.all(sortedPatches.map(async (patch) => {
435
448
  let readyPatch = patch;
436
449
  if ((!readyPatch.mutations || readyPatch.mutations.length === 0) &&
@@ -493,16 +506,16 @@ class WaAppStateSyncClient {
493
506
  }
494
507
  async applySnapshot(collection, snapshot) {
495
508
  const version = this.normalizeProtoLong(snapshot.version?.version, `snapshot.version.version (${collection})`);
496
- const keyId = (0, base64_1.decodeProtoBytes)(snapshot.keyId?.id, `snapshot.keyId.id (${collection})`);
509
+ const keyId = (0, bytes_1.decodeProtoBytes)(snapshot.keyId?.id, `snapshot.keyId.id (${collection})`);
497
510
  const keyData = await this.getKeyData(keyId);
498
511
  if (!keyData) {
499
- throw new WaAppStateMissingKeyError(`missing snapshot key ${(0, utils_1.keyIdToHex)(keyId)} for ${collection}`, keyId, collection);
512
+ throw new WaAppStateMissingKeyError(`missing snapshot key ${(0, bytes_2.bytesToHex)(keyId)} for ${collection}`, keyId, collection);
500
513
  }
501
514
  const indexValueMap = new Map();
502
515
  const mutations = [];
503
516
  const decryptedRecords = await this.decryptSnapshotRecords(collection, snapshot);
504
517
  for (const { decrypted, recordKeyId } of decryptedRecords) {
505
- const indexMacHex = (0, utils_1.keyIdToHex)(decrypted.indexMac);
518
+ const indexMacHex = (0, bytes_2.bytesToHex)(decrypted.indexMac);
506
519
  indexValueMap.set(indexMacHex, decrypted.valueMac);
507
520
  mutations.push({
508
521
  collection,
@@ -517,9 +530,15 @@ class WaAppStateSyncClient {
517
530
  timestamp: this.normalizeProtoLong(decrypted.value?.timestamp, `snapshot.record.value.timestamp (${collection})`)
518
531
  });
519
532
  }
520
- const ltHash = await this.crypto.ltHashAdd(constants_1.APP_STATE_EMPTY_LT_HASH, Array.from(indexValueMap.values()));
533
+ const ltHashInput = new Array(indexValueMap.size);
534
+ let ltHashInputIndex = 0;
535
+ for (const valueMac of indexValueMap.values()) {
536
+ ltHashInput[ltHashInputIndex] = valueMac;
537
+ ltHashInputIndex += 1;
538
+ }
539
+ const ltHash = await this.crypto.ltHashAdd(constants_1.APP_STATE_EMPTY_LT_HASH, ltHashInput);
521
540
  const expectedSnapshotMac = await this.crypto.generateSnapshotMac(keyData, ltHash, version, collection);
522
- if (!(0, bytes_1.uint8Equal)(expectedSnapshotMac, snapshot.mac)) {
541
+ if (!(0, bytes_2.uint8Equal)(expectedSnapshotMac, snapshot.mac)) {
523
542
  throw new Error(`snapshot MAC mismatch for ${collection}`);
524
543
  }
525
544
  this.setCollectionState(collection, version, ltHash, indexValueMap);
@@ -531,48 +550,72 @@ class WaAppStateSyncClient {
531
550
  if (current.version !== patchVersion - 1) {
532
551
  throw new Error(`patch version mismatch for ${collection}: local=${current.version}, incoming=${patchVersion}`);
533
552
  }
534
- const patchKeyId = (0, base64_1.decodeProtoBytes)(patch.keyId?.id, `patch.keyId.id (${collection})`);
553
+ const patchKeyId = (0, bytes_1.decodeProtoBytes)(patch.keyId?.id, `patch.keyId.id (${collection})`);
535
554
  const patchKeyData = await this.getKeyData(patchKeyId);
536
555
  if (!patchKeyData) {
537
- throw new WaAppStateMissingKeyError(`missing patch key ${(0, utils_1.keyIdToHex)(patchKeyId)} for ${collection}`, patchKeyId, collection);
556
+ throw new WaAppStateMissingKeyError(`missing patch key ${(0, bytes_2.bytesToHex)(patchKeyId)} for ${collection}`, patchKeyId, collection);
538
557
  }
539
558
  const decryptedMutations = await this.decryptPatchMutations(collection, patch);
540
- const nextState = await this.computeNextCollectionState(current.hash, current.indexValueMap, decryptedMutations.map((mutation) => ({
541
- operation: mutation.operationCode,
542
- indexMac: mutation.indexMac,
543
- valueMac: mutation.valueMac
544
- })), collection);
545
- await this.assertPatchMacsMatch(patch, collection, patchKeyData, patchVersion, nextState.hash, decryptedMutations);
559
+ const macMutations = new Array(decryptedMutations.length);
560
+ const valueMacs = new Array(decryptedMutations.length);
561
+ for (let index = 0; index < decryptedMutations.length; index += 1) {
562
+ const mutation = decryptedMutations[index];
563
+ valueMacs[index] = mutation.valueMac;
564
+ macMutations[index] = {
565
+ operation: mutation.operationCode,
566
+ indexMac: mutation.indexMac,
567
+ valueMac: mutation.valueMac
568
+ };
569
+ }
570
+ const nextState = await this.computeNextCollectionState(current.hash, current.indexValueMap, macMutations, collection);
571
+ await this.assertPatchMacsMatch(patch, collection, patchKeyData, patchVersion, nextState.hash, valueMacs);
546
572
  this.setCollectionState(collection, patchVersion, nextState.hash, nextState.indexValueMap);
547
- return decryptedMutations.map(({ operationCode, ...mutation }) => {
548
- void operationCode;
549
- return mutation;
550
- });
573
+ return decryptedMutations;
551
574
  }
552
575
  async decryptSnapshotRecords(collection, snapshot) {
553
- return Promise.all((snapshot.records ?? []).map(async (record) => {
554
- const indexMac = (0, base64_1.decodeProtoBytes)(record.index?.blob, `snapshot.record.index.blob (${collection})`);
555
- const valueBlob = (0, base64_1.decodeProtoBytes)(record.value?.blob, `snapshot.record.value.blob (${collection})`);
556
- const recordKeyId = (0, base64_1.decodeProtoBytes)(record.keyId?.id, `snapshot.record.keyId.id (${collection})`);
557
- const recordKeyData = await this.getKeyData(recordKeyId);
558
- if (!recordKeyData) {
559
- throw new WaAppStateMissingKeyError(`missing snapshot mutation key ${(0, utils_1.keyIdToHex)(recordKeyId)} for ${collection}`, recordKeyId, collection);
560
- }
561
- const decrypted = await this.crypto.decryptMutation({
562
- operation: _proto_1.proto.SyncdMutation.SyncdOperation.SET,
563
- keyId: recordKeyId,
564
- keyData: recordKeyData,
565
- indexMac,
566
- valueBlob
567
- });
568
- return {
569
- decrypted,
576
+ const rawRecords = snapshot.records ?? [];
577
+ const records = new Array(rawRecords.length);
578
+ const recordKeyIds = new Array(rawRecords.length);
579
+ for (let i = 0; i < rawRecords.length; i += 1) {
580
+ const record = rawRecords[i];
581
+ const recordKeyId = (0, bytes_1.decodeProtoBytes)(record.keyId?.id, `snapshot.record.keyId.id (${collection})`);
582
+ records[i] = {
583
+ indexMac: (0, bytes_1.decodeProtoBytes)(record.index?.blob, `snapshot.record.index.blob (${collection})`),
584
+ valueBlob: (0, bytes_1.decodeProtoBytes)(record.value?.blob, `snapshot.record.value.blob (${collection})`),
570
585
  recordKeyId
571
586
  };
572
- }));
587
+ recordKeyIds[i] = recordKeyId;
588
+ }
589
+ await this.preloadKeyData(recordKeyIds);
590
+ const decryptTasks = new Array(records.length);
591
+ for (let i = 0; i < records.length; i += 1) {
592
+ const { indexMac, valueBlob, recordKeyId } = records[i];
593
+ decryptTasks[i] = (async () => {
594
+ const recordKeyData = await this.getKeyData(recordKeyId);
595
+ if (!recordKeyData) {
596
+ throw new WaAppStateMissingKeyError(`missing snapshot mutation key ${(0, bytes_2.bytesToHex)(recordKeyId)} for ${collection}`, recordKeyId, collection);
597
+ }
598
+ const decrypted = await this.crypto.decryptMutation({
599
+ operation: _proto_1.proto.SyncdMutation.SyncdOperation.SET,
600
+ keyId: recordKeyId,
601
+ keyData: recordKeyData,
602
+ indexMac,
603
+ valueBlob
604
+ });
605
+ return {
606
+ decrypted,
607
+ recordKeyId
608
+ };
609
+ })();
610
+ }
611
+ return Promise.all(decryptTasks);
573
612
  }
574
613
  async decryptPatchMutations(collection, patch) {
575
- return Promise.all((patch.mutations ?? []).map(async (mutation) => {
614
+ const rawMutations = patch.mutations ?? [];
615
+ const parsedMutations = new Array(rawMutations.length);
616
+ const mutationKeyIds = new Array(rawMutations.length);
617
+ for (let i = 0; i < rawMutations.length; i += 1) {
618
+ const mutation = rawMutations[i];
576
619
  const operationCode = mutation.operation;
577
620
  if (operationCode === null || operationCode === undefined) {
578
621
  throw new Error(`patch mutation is missing operation (${collection})`);
@@ -581,51 +624,63 @@ class WaAppStateSyncClient {
581
624
  if (!record) {
582
625
  throw new Error(`patch mutation is missing record (${collection})`);
583
626
  }
584
- const indexMac = (0, base64_1.decodeProtoBytes)(record.index?.blob, `patch.record.index.blob (${collection})`);
585
- const valueBlob = (0, base64_1.decodeProtoBytes)(record.value?.blob, `patch.record.value.blob (${collection})`);
586
- const recordKeyId = (0, base64_1.decodeProtoBytes)(record.keyId?.id, `patch.record.keyId.id (${collection})`);
587
- const recordKeyData = await this.getKeyData(recordKeyId);
588
- if (!recordKeyData) {
589
- throw new WaAppStateMissingKeyError(`missing mutation key ${(0, utils_1.keyIdToHex)(recordKeyId)} for ${collection}`, recordKeyId, collection);
590
- }
591
- const decrypted = await this.crypto.decryptMutation({
592
- operation: operationCode,
593
- keyId: recordKeyId,
594
- keyData: recordKeyData,
595
- indexMac,
596
- valueBlob
597
- });
598
- return {
599
- collection,
600
- operation: operationCode === _proto_1.proto.SyncdMutation.SyncdOperation.REMOVE
601
- ? 'remove'
602
- : 'set',
603
- source: 'patch',
627
+ const recordKeyId = (0, bytes_1.decodeProtoBytes)(record.keyId?.id, `patch.record.keyId.id (${collection})`);
628
+ parsedMutations[i] = {
604
629
  operationCode,
605
- index: decrypted.index,
606
- value: decrypted.value,
607
- version: decrypted.version,
608
- indexMac: decrypted.indexMac,
609
- valueMac: decrypted.valueMac,
610
- keyId: recordKeyId,
611
- timestamp: this.normalizeProtoLong(decrypted.value?.timestamp, `patch.record.value.timestamp (${collection})`)
630
+ indexMac: (0, bytes_1.decodeProtoBytes)(record.index?.blob, `patch.record.index.blob (${collection})`),
631
+ valueBlob: (0, bytes_1.decodeProtoBytes)(record.value?.blob, `patch.record.value.blob (${collection})`),
632
+ recordKeyId
612
633
  };
613
- }));
634
+ mutationKeyIds[i] = recordKeyId;
635
+ }
636
+ await this.preloadKeyData(mutationKeyIds);
637
+ const decryptTasks = new Array(parsedMutations.length);
638
+ for (let i = 0; i < parsedMutations.length; i += 1) {
639
+ const { operationCode, indexMac, valueBlob, recordKeyId } = parsedMutations[i];
640
+ decryptTasks[i] = (async () => {
641
+ const recordKeyData = await this.getKeyData(recordKeyId);
642
+ if (!recordKeyData) {
643
+ throw new WaAppStateMissingKeyError(`missing mutation key ${(0, bytes_2.bytesToHex)(recordKeyId)} for ${collection}`, recordKeyId, collection);
644
+ }
645
+ const decrypted = await this.crypto.decryptMutation({
646
+ operation: operationCode,
647
+ keyId: recordKeyId,
648
+ keyData: recordKeyData,
649
+ indexMac,
650
+ valueBlob
651
+ });
652
+ return {
653
+ collection,
654
+ operation: operationCode === _proto_1.proto.SyncdMutation.SyncdOperation.REMOVE
655
+ ? 'remove'
656
+ : 'set',
657
+ source: 'patch',
658
+ operationCode,
659
+ index: decrypted.index,
660
+ value: decrypted.value,
661
+ version: decrypted.version,
662
+ indexMac: decrypted.indexMac,
663
+ valueMac: decrypted.valueMac,
664
+ keyId: recordKeyId,
665
+ timestamp: this.normalizeProtoLong(decrypted.value?.timestamp, `patch.record.value.timestamp (${collection})`)
666
+ };
667
+ })();
668
+ }
669
+ return Promise.all(decryptTasks);
614
670
  }
615
- async assertPatchMacsMatch(patch, collection, patchKeyData, patchVersion, nextHash, decryptedMutations) {
616
- const snapshotMac = (0, base64_1.decodeProtoBytes)(patch.snapshotMac, `patch.snapshotMac (${collection})`);
671
+ async assertPatchMacsMatch(patch, collection, patchKeyData, patchVersion, nextHash, valueMacs) {
672
+ const snapshotMac = (0, bytes_1.decodeProtoBytes)(patch.snapshotMac, `patch.snapshotMac (${collection})`);
617
673
  const expectedSnapshotMac = await this.crypto.generateSnapshotMac(patchKeyData, nextHash, patchVersion, collection);
618
- if (!(0, bytes_1.uint8Equal)(expectedSnapshotMac, snapshotMac)) {
674
+ if (!(0, bytes_2.uint8Equal)(expectedSnapshotMac, snapshotMac)) {
619
675
  throw new Error(`patch snapshot MAC mismatch for ${collection}`);
620
676
  }
621
- const patchMac = (0, base64_1.decodeProtoBytes)(patch.patchMac, `patch.patchMac (${collection})`);
622
- const expectedPatchMac = await this.crypto.generatePatchMac(patchKeyData, snapshotMac, decryptedMutations.map((mutation) => mutation.valueMac), patchVersion, collection);
623
- if (!(0, bytes_1.uint8Equal)(expectedPatchMac, patchMac)) {
677
+ const patchMac = (0, bytes_1.decodeProtoBytes)(patch.patchMac, `patch.patchMac (${collection})`);
678
+ const expectedPatchMac = await this.crypto.generatePatchMac(patchKeyData, snapshotMac, valueMacs, patchVersion, collection);
679
+ if (!(0, bytes_2.uint8Equal)(expectedPatchMac, patchMac)) {
624
680
  throw new Error(`patch MAC mismatch for ${collection}`);
625
681
  }
626
682
  }
627
- async buildOutgoingPatch(collection, snapshot, pendingMutations) {
628
- const activeKey = await this.store.getActiveSyncKey();
683
+ async buildOutgoingPatch(collection, snapshot, pendingMutations, activeKey) {
629
684
  if (!activeKey) {
630
685
  throw new WaAppStateMissingKeyError(`no sync key available to upload ${collection}`, null, collection);
631
686
  }
@@ -644,29 +699,39 @@ class WaAppStateSyncClient {
644
699
  });
645
700
  return { operationCode, encrypted };
646
701
  }));
647
- const encryptedMutations = encryptedResults.map(({ operationCode, encrypted }) => ({
648
- operation: operationCode,
649
- record: {
650
- keyId: { id: activeKey.keyId },
651
- index: { blob: encrypted.indexMac },
652
- value: { blob: encrypted.valueBlob }
653
- }
654
- }));
655
- const macMutations = encryptedResults.map(({ operationCode, encrypted }) => ({
656
- operation: operationCode,
657
- indexMac: encrypted.indexMac,
658
- valueMac: encrypted.valueMac
659
- }));
702
+ const encryptedMutations = new Array(encryptedResults.length);
703
+ const macMutations = new Array(encryptedResults.length);
704
+ const valueMacs = new Array(encryptedResults.length);
705
+ for (let i = 0; i < encryptedResults.length; i += 1) {
706
+ const { operationCode, encrypted } = encryptedResults[i];
707
+ encryptedMutations[i] = {
708
+ operation: operationCode,
709
+ record: {
710
+ keyId: { id: activeKey.keyId },
711
+ index: { blob: encrypted.indexMac },
712
+ value: { blob: encrypted.valueBlob }
713
+ }
714
+ };
715
+ macMutations[i] = {
716
+ operation: operationCode,
717
+ indexMac: encrypted.indexMac,
718
+ valueMac: encrypted.valueMac
719
+ };
720
+ valueMacs[i] = encrypted.valueMac;
721
+ }
660
722
  const nextState = await this.computeNextCollectionState(snapshot.hash, snapshot.indexValueMap, macMutations, collection);
661
723
  const patchVersion = snapshot.version + 1;
662
724
  const snapshotMac = await this.crypto.generateSnapshotMac(activeKey.keyData, nextState.hash, patchVersion, collection);
663
- const patchMac = await this.crypto.generatePatchMac(activeKey.keyData, snapshotMac, macMutations.map((item) => item.valueMac), patchVersion, collection);
725
+ const patchMac = await this.crypto.generatePatchMac(activeKey.keyData, snapshotMac, valueMacs, patchVersion, collection);
726
+ const deviceIndex = this.resolveDeviceIndex();
727
+ const clientDebugData = this.buildPatchClientDebugData();
664
728
  const encodedPatch = _proto_1.proto.SyncdPatch.encode({
665
- version: { version: patchVersion },
666
729
  mutations: encryptedMutations,
667
730
  snapshotMac,
668
731
  patchMac,
669
- keyId: { id: activeKey.keyId }
732
+ keyId: { id: activeKey.keyId },
733
+ ...(deviceIndex === undefined ? {} : { deviceIndex }),
734
+ clientDebugData
670
735
  }).finish();
671
736
  return {
672
737
  encodedPatch,
@@ -678,13 +743,35 @@ class WaAppStateSyncClient {
678
743
  }
679
744
  };
680
745
  }
746
+ resolveDeviceIndex() {
747
+ const meJid = this.getCurrentMeJid?.();
748
+ if (!meJid) {
749
+ return undefined;
750
+ }
751
+ try {
752
+ return (0, jid_1.parseSignalAddressFromJid)(meJid).device;
753
+ }
754
+ catch (error) {
755
+ this.logger.debug('app-state could not parse device index from me jid', {
756
+ meJid
757
+ });
758
+ void error;
759
+ return undefined;
760
+ }
761
+ }
762
+ buildPatchClientDebugData() {
763
+ return _proto_1.proto.PatchDebugData.encode({
764
+ isSenderPrimary: false,
765
+ senderPlatform: _proto_1.proto.PatchDebugData.Platform.WEB
766
+ }).finish();
767
+ }
681
768
  async computeNextCollectionState(baseHash, baseMap, mutations, collection) {
682
769
  const indexValueMap = new Map(baseMap);
683
770
  const addValues = [];
684
771
  const removeValues = [];
685
772
  let missingRemoveCount = 0;
686
773
  for (const mutation of mutations) {
687
- const indexMacHex = (0, utils_1.keyIdToHex)(mutation.indexMac);
774
+ const indexMacHex = (0, bytes_2.bytesToHex)(mutation.indexMac);
688
775
  const existing = indexValueMap.get(indexMacHex);
689
776
  if (mutation.operation === _proto_1.proto.SyncdMutation.SyncdOperation.REMOVE) {
690
777
  if (!existing) {
@@ -749,9 +836,33 @@ class WaAppStateSyncClient {
749
836
  }
750
837
  return compacted;
751
838
  }
839
+ async preloadKeyData(keyIds) {
840
+ if (keyIds.length === 0) {
841
+ return;
842
+ }
843
+ const context = this.requireSyncContext();
844
+ const missingKeyIds = [];
845
+ const missingKeyHexes = new Set();
846
+ for (let index = 0; index < keyIds.length; index += 1) {
847
+ const keyId = keyIds[index];
848
+ const keyHex = (0, bytes_2.bytesToHex)(keyId);
849
+ if (context.keys.has(keyHex) || missingKeyHexes.has(keyHex)) {
850
+ continue;
851
+ }
852
+ missingKeyHexes.add(keyHex);
853
+ missingKeyIds.push(keyId);
854
+ }
855
+ if (missingKeyIds.length === 0) {
856
+ return;
857
+ }
858
+ const loadedKeyData = await this.store.getSyncKeyDataBatch(missingKeyIds);
859
+ for (let index = 0; index < missingKeyIds.length; index += 1) {
860
+ context.keys.set((0, bytes_2.bytesToHex)(missingKeyIds[index]), loadedKeyData[index] ?? null);
861
+ }
862
+ }
752
863
  async getKeyData(keyId) {
753
864
  const context = this.requireSyncContext();
754
- const keyHex = (0, utils_1.keyIdToHex)(keyId);
865
+ const keyHex = (0, bytes_2.bytesToHex)(keyId);
755
866
  if (context.keys.has(keyHex)) {
756
867
  return context.keys.get(keyHex) ?? null;
757
868
  }
@@ -772,6 +883,7 @@ class WaAppStateSyncClient {
772
883
  setCollectionState(collection, version, hash, indexValueMap) {
773
884
  const context = this.requireSyncContext();
774
885
  context.collections.set(collection, {
886
+ initialized: true,
775
887
  version,
776
888
  hash,
777
889
  indexValueMap