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
@@ -3,14 +3,14 @@ import { downloadExternalBlobReference } from '../appstate/utils.js';
3
3
  import { parseChatEventFromAppStateMutation } from './events/chat.js';
4
4
  import { processHistorySyncNotification } from './history-sync.js';
5
5
  import { persistIncomingMailboxEntities } from './mailbox.js';
6
+ import { WriteBehindPersistence } from './persistence/WriteBehindPersistence.js';
6
7
  import { buildWaClientDependencies, resolveWaClientBase } from './WaClientFactory.js';
7
8
  import { ConsoleLogger } from '../infra/log/ConsoleLogger.js';
8
9
  import { proto } from '../proto.js';
9
- import { WA_APP_STATE_COLLECTION_STATES, WA_DEFAULTS, WA_MESSAGE_TAGS } from '../protocol/constants.js';
10
- import { normalizeDeviceJid, toUserJid } from '../protocol/jid.js';
10
+ import { WA_APP_STATE_COLLECTION_STATES, WA_DEFAULTS } from '../protocol/constants.js';
11
+ import { normalizeDeviceJid, parsePhoneJid, toUserJid } from '../protocol/jid.js';
11
12
  import { queryWithContext as queryNodeWithContext } from '../transport/node/query.js';
12
- import { WaComms } from '../transport/WaComms.js';
13
- import { decodeProtoBytes } from '../util/base64.js';
13
+ import { decodeProtoBytes } from '../util/bytes.js';
14
14
  import { bytesToHex } from '../util/bytes.js';
15
15
  import { toError } from '../util/primitives.js';
16
16
  const SYNC_RELATED_PROTOCOL_TYPES = new Set([
@@ -24,15 +24,10 @@ const WA_APP_STATE_KEY_SHARE_MAX_RETRIES = 2;
24
24
  export class WaClient extends EventEmitter {
25
25
  constructor(options, logger = new ConsoleLogger('info')) {
26
26
  super();
27
- this.clockSkewMs = null;
28
- this.mediaConnCache = null;
29
- this.comms = null;
30
- this.pairingReconnectPromise = null;
31
27
  this.connectPromise = null;
32
- this.danglingReceipts = [];
33
- this.appStateKeyShareWaiters = new Set();
34
- this.appStateKeyShareVersion = 0;
35
- this.appStateBootstrapKeyShareWaitDone = false;
28
+ this.acceptingIncomingEvents = true;
29
+ this.activeIncomingHandlers = 0;
30
+ this.incomingHandlersDrainedWaiters = [];
36
31
  const base = resolveWaClientBase(options, logger);
37
32
  this.options = base.options;
38
33
  this.logger = base.logger;
@@ -40,36 +35,34 @@ export class WaClient extends EventEmitter {
40
35
  this.contactStore = base.sessionStore.contacts;
41
36
  this.messageStore = base.sessionStore.messages;
42
37
  this.participantsStore = base.sessionStore.participants;
38
+ this.privacyTokenStore = base.sessionStore.privacyToken;
43
39
  this.deviceListStore = base.sessionStore.deviceList;
44
40
  this.retryStore = base.sessionStore.retry;
45
41
  this.signalStore = base.sessionStore.signal;
46
42
  this.senderKeyStore = base.sessionStore.senderKey;
47
43
  this.threadStore = base.sessionStore.threads;
48
- const host = {
49
- sendNode: (node) => this.sendNode(node),
50
- query: (node, timeoutMs) => this.query(node, timeoutMs),
51
- queryWithContext: this.queryWithContext.bind(this),
52
- syncAppState: () => this.syncAppState().then(() => { }),
53
- emitEvent: this.emit.bind(this),
54
- handleIncomingMessageEvent: this.handleIncomingMessageEvent.bind(this),
55
- handleError: this.handleError.bind(this),
56
- scheduleReconnectAfterPairing: this.scheduleReconnectAfterPairing.bind(this),
57
- updateClockSkewFromSuccess: this.updateClockSkewFromSuccess.bind(this),
58
- getComms: () => this.comms,
59
- getMediaConnCache: () => this.mediaConnCache,
60
- setMediaConnCache: (mediaConn) => {
61
- this.mediaConnCache = mediaConn;
62
- },
63
- disconnect: this.disconnect.bind(this),
64
- clearStoredState: this.clearStoredState.bind(this),
65
- connect: this.connect.bind(this),
66
- shouldQueueDanglingReceipt: (node, error) => this.shouldQueueDanglingReceipt(node, error),
67
- enqueueDanglingReceipt: this.enqueueDanglingReceipt.bind(this),
68
- takeDanglingReceipts: () => this.danglingReceipts.splice(0)
69
- };
44
+ this.writeBehind = new WriteBehindPersistence({
45
+ messageStore: this.messageStore,
46
+ threadStore: this.threadStore,
47
+ contactStore: this.contactStore
48
+ }, this.logger, this.options.writeBehind);
70
49
  const dependencies = buildWaClientDependencies({
71
50
  base,
72
- host
51
+ runtime: {
52
+ sendNode: (node) => this.sendNode(node),
53
+ query: (node, timeoutMs) => this.query(node, timeoutMs),
54
+ queryWithContext: this.queryWithContext.bind(this),
55
+ syncAppState: () => this.syncAppState().then(() => { }),
56
+ syncAppStateWithOptions: (syncOptions) => this.syncAppState(syncOptions),
57
+ emitEvent: this.emit.bind(this),
58
+ handleIncomingMessageEvent: this.handleIncomingMessageEvent.bind(this),
59
+ handleError: this.handleError.bind(this),
60
+ handleIncomingFrame: this.handleIncomingFrame.bind(this),
61
+ clearStoredState: this.clearStoredState.bind(this),
62
+ resumeIncomingEvents: () => {
63
+ this.acceptingIncomingEvents = true;
64
+ }
65
+ }
73
66
  });
74
67
  Object.assign(this, dependencies);
75
68
  this.bindNodeTransportEvents();
@@ -87,7 +80,7 @@ export class WaClient extends EventEmitter {
87
80
  return super.emit(event, ...args);
88
81
  }
89
82
  getState() {
90
- const connected = this.comms !== null && this.comms.getCommsState().connected;
83
+ const connected = this.connectionManager.isConnected();
91
84
  this.logger.trace('wa client state requested', { connected });
92
85
  return this.authClient.getState(connected);
93
86
  }
@@ -95,7 +88,7 @@ export class WaClient extends EventEmitter {
95
88
  return this.authClient.getCurrentCredentials();
96
89
  }
97
90
  getClockSkewMs() {
98
- return this.clockSkewMs;
91
+ return this.connectionManager.getClockSkewMs();
99
92
  }
100
93
  async sendNode(node) {
101
94
  try {
@@ -103,13 +96,13 @@ export class WaClient extends EventEmitter {
103
96
  }
104
97
  catch (error) {
105
98
  const normalized = toError(error);
106
- if (this.shouldQueueDanglingReceipt(node, normalized)) {
107
- this.enqueueDanglingReceipt(node);
99
+ if (this.receiptQueue.shouldQueue(node, normalized)) {
100
+ this.receiptQueue.enqueue(node);
108
101
  this.logger.warn('queued dangling receipt after send failure', {
109
102
  id: node.attrs.id,
110
103
  to: node.attrs.to,
111
104
  message: normalized.message,
112
- queueSize: this.danglingReceipts.length
105
+ queueSize: this.receiptQueue.size()
113
106
  });
114
107
  return;
115
108
  }
@@ -117,7 +110,7 @@ export class WaClient extends EventEmitter {
117
110
  }
118
111
  }
119
112
  async query(node, timeoutMs = this.options.iqTimeoutMs ?? WA_DEFAULTS.IQ_TIMEOUT_MS) {
120
- if (!this.comms || !this.comms.getCommsState().connected) {
113
+ if (!this.connectionManager.isConnected()) {
121
114
  throw new Error('client is not connected');
122
115
  }
123
116
  this.logger.debug('wa client query', { tag: node.tag, id: node.attrs.id, timeoutMs });
@@ -140,57 +133,64 @@ export class WaClient extends EventEmitter {
140
133
  });
141
134
  }
142
135
  async handleIncomingMessageEvent(event) {
143
- this.emit('message', event);
144
- void persistIncomingMailboxEntities({
145
- logger: this.logger,
146
- contactStore: this.contactStore,
147
- messageStore: this.messageStore,
148
- event
149
- });
150
- const protocolMessage = event.message?.protocolMessage;
151
- if (!protocolMessage) {
136
+ if (!this.tryEnterIncomingHandler()) {
152
137
  return;
153
138
  }
154
- const protocolEvent = {
155
- ...event,
156
- protocolMessage
157
- };
158
- this.emit('message_protocol', protocolEvent);
159
- const protocolType = protocolMessage.type;
160
- if (protocolType === null || protocolType === undefined) {
161
- this.logger.debug('incoming protocol message without type', {
162
- id: event.stanzaId,
163
- from: event.chatJid
139
+ try {
140
+ this.emit('message', event);
141
+ void persistIncomingMailboxEntities({
142
+ logger: this.logger,
143
+ writeBehind: this.writeBehind,
144
+ event
164
145
  });
165
- return;
166
- }
167
- if (protocolType === proto.Message.ProtocolMessage.Type.APP_STATE_SYNC_KEY_REQUEST) {
168
- await this.handleIncomingAppStateSyncKeyRequest(event, protocolMessage);
169
- return;
170
- }
171
- if (protocolType === proto.Message.ProtocolMessage.Type.APP_STATE_SYNC_KEY_SHARE) {
172
- await this.handleIncomingAppStateSyncKeyShare(event, protocolMessage);
173
- return;
174
- }
175
- if (protocolType === proto.Message.ProtocolMessage.Type.HISTORY_SYNC_NOTIFICATION) {
176
- if (this.options.history?.enabled && protocolMessage.historySyncNotification) {
177
- await this.handleHistorySyncNotification(protocolMessage.historySyncNotification);
146
+ const protocolMessage = event.message?.protocolMessage;
147
+ if (!protocolMessage) {
148
+ return;
178
149
  }
179
- return;
180
- }
181
- if (SYNC_RELATED_PROTOCOL_TYPES.has(protocolType)) {
182
- this.logger.info('incoming sync-related protocol message', {
150
+ const protocolEvent = {
151
+ ...event,
152
+ protocolMessage
153
+ };
154
+ this.emit('message_protocol', protocolEvent);
155
+ const protocolType = protocolMessage.type;
156
+ if (protocolType === null || protocolType === undefined) {
157
+ this.logger.debug('incoming protocol message without type', {
158
+ id: event.stanzaId,
159
+ from: event.chatJid
160
+ });
161
+ return;
162
+ }
163
+ if (protocolType === proto.Message.ProtocolMessage.Type.APP_STATE_SYNC_KEY_REQUEST) {
164
+ await this.handleIncomingAppStateSyncKeyRequest(event, protocolMessage);
165
+ return;
166
+ }
167
+ if (protocolType === proto.Message.ProtocolMessage.Type.APP_STATE_SYNC_KEY_SHARE) {
168
+ await this.handleIncomingAppStateSyncKeyShare(event, protocolMessage);
169
+ return;
170
+ }
171
+ if (protocolType === proto.Message.ProtocolMessage.Type.HISTORY_SYNC_NOTIFICATION) {
172
+ if (this.options.history?.enabled && protocolMessage.historySyncNotification) {
173
+ await this.handleHistorySyncNotification(protocolMessage.historySyncNotification);
174
+ }
175
+ return;
176
+ }
177
+ if (SYNC_RELATED_PROTOCOL_TYPES.has(protocolType)) {
178
+ this.logger.info('incoming sync-related protocol message', {
179
+ id: event.stanzaId,
180
+ from: event.chatJid,
181
+ protocolType
182
+ });
183
+ return;
184
+ }
185
+ this.logger.debug('incoming protocol message received', {
183
186
  id: event.stanzaId,
184
187
  from: event.chatJid,
185
188
  protocolType
186
189
  });
187
- return;
188
190
  }
189
- this.logger.debug('incoming protocol message received', {
190
- id: event.stanzaId,
191
- from: event.chatJid,
192
- protocolType
193
- });
191
+ finally {
192
+ this.leaveIncomingHandler();
193
+ }
194
194
  }
195
195
  async handleIncomingAppStateSyncKeyShare(event, protocolMessage) {
196
196
  const share = protocolMessage.appStateSyncKeyShare;
@@ -209,9 +209,8 @@ export class WaClient extends EventEmitter {
209
209
  imported
210
210
  });
211
211
  if (imported > 0) {
212
- const hadWaiters = this.appStateKeyShareWaiters.size > 0;
213
- this.appStateKeyShareVersion += 1;
214
- this.notifyAppStateKeyShareWaiters(true);
212
+ const hadWaiters = this.keyShareCoordinator.hasWaiters();
213
+ this.keyShareCoordinator.notifyReceived();
215
214
  if (hadWaiters) {
216
215
  this.logger.debug('app-state key share imported and waiters released', {
217
216
  id: event.stanzaId,
@@ -280,9 +279,18 @@ export class WaClient extends EventEmitter {
280
279
  });
281
280
  return;
282
281
  }
283
- const requestedKeys = await Promise.all(requestedKeyIds.map((keyId) => this.appStateStore.getSyncKey(keyId)));
284
- const availableKeys = requestedKeys.filter((key) => key !== null);
285
- const missingKeyIds = requestedKeyIds.filter((_, index) => requestedKeys[index] === null);
282
+ const requestedKeys = await this.appStateStore.getSyncKeysBatch(requestedKeyIds);
283
+ const availableKeys = [];
284
+ const missingKeyIds = [];
285
+ for (let i = 0; i < requestedKeys.length; i += 1) {
286
+ const key = requestedKeys[i];
287
+ if (key !== null) {
288
+ availableKeys.push(key);
289
+ }
290
+ else {
291
+ missingKeyIds.push(requestedKeyIds[i]);
292
+ }
293
+ }
286
294
  try {
287
295
  await this.messageDispatch.sendAppStateSyncKeyShare(requesterDeviceJid, availableKeys, missingKeyIds);
288
296
  this.logger.info('responded to app-state key request', {
@@ -329,20 +337,18 @@ export class WaClient extends EventEmitter {
329
337
  return false;
330
338
  }
331
339
  const candidateUser = toUserJid(candidateJid);
332
- const meUsers = [credentials.meJid, credentials.meLid]
333
- .filter((value) => !!value)
334
- .map((jid) => toUserJid(jid));
335
- return meUsers.includes(candidateUser);
340
+ return ((!!credentials.meJid && toUserJid(credentials.meJid) === candidateUser) ||
341
+ (!!credentials.meLid && toUserJid(credentials.meLid) === candidateUser));
336
342
  }
337
343
  async handleHistorySyncNotification(notification) {
338
344
  try {
339
345
  await processHistorySyncNotification({
340
346
  logger: this.logger,
341
347
  mediaTransfer: this.mediaTransfer,
342
- contactStore: this.contactStore,
343
- messageStore: this.messageStore,
344
- threadStore: this.threadStore,
345
- emitEvent: this.emit.bind(this)
348
+ writeBehind: this.writeBehind,
349
+ emitEvent: this.emit.bind(this),
350
+ onPrivacyTokens: (conversations) => this.trustedContactToken.hydrateFromHistorySync(conversations),
351
+ onNctSalt: (salt) => this.trustedContactToken.hydrateNctSaltFromHistorySync(salt)
346
352
  }, notification);
347
353
  }
348
354
  catch (error) {
@@ -369,144 +375,118 @@ export class WaClient extends EventEmitter {
369
375
  this.logger.trace('wa client connect already in-flight');
370
376
  return this.connectPromise;
371
377
  }
372
- this.connectPromise = this.connectInternal().finally(() => {
378
+ this.acceptingIncomingEvents = true;
379
+ this.connectPromise = this.connectionManager
380
+ .connect((frame) => this.handleIncomingFrame(frame))
381
+ .then(() => {
382
+ this.emit('connection', {
383
+ status: 'open',
384
+ reason: 'connected',
385
+ code: null,
386
+ isLogout: false,
387
+ isNewLogin: this.connectionManager.wasNewLogin()
388
+ });
389
+ })
390
+ .finally(() => {
373
391
  this.connectPromise = null;
374
392
  });
375
393
  return this.connectPromise;
376
394
  }
377
- async connectInternal() {
378
- if (this.comms) {
379
- this.logger.trace('wa client connect skipped: comms already created');
380
- return;
381
- }
382
- this.logger.info('wa client connect start');
383
- let credentials = await this.authClient.loadOrCreateCredentials();
384
- try {
385
- await this.startCommsWithCredentials(credentials);
386
- }
387
- catch (error) {
388
- if (credentials.routingInfo) {
389
- this.logger.warn('connect failed with routing info, retrying without routing info', {
390
- message: toError(error).message
391
- });
392
- await this.disconnect();
393
- credentials = await this.authClient.clearRoutingInfo();
394
- await this.startCommsWithCredentials(credentials);
395
- }
396
- else {
397
- await this.disconnect();
398
- throw error;
399
- }
400
- }
401
- this.logger.info('wa client connected');
402
- this.emit('connection_open', {});
403
- }
404
- scheduleReconnectAfterPairing() {
405
- this.logger.debug('wa client scheduling reconnect after pairing');
406
- setTimeout(() => {
407
- void this.reconnectAsRegisteredAfterPairing().catch((error) => {
408
- this.handleError(toError(error));
395
+ async disconnect() {
396
+ await this.pauseIncomingEventsAndWaitDrain();
397
+ const writeBehindFlush = await this.writeBehind.flush(this.options.writeBehind?.flushTimeoutMs);
398
+ if (writeBehindFlush.remaining > 0) {
399
+ this.logger.warn('disconnect continuing with pending write-behind entries', {
400
+ remaining: writeBehindFlush.remaining
409
401
  });
410
- }, 0);
411
- }
412
- async reconnectAsRegisteredAfterPairing() {
413
- if (this.pairingReconnectPromise) {
414
- this.logger.trace('pairing reconnect already in-flight');
415
- return this.pairingReconnectPromise;
416
402
  }
417
- this.pairingReconnectPromise = this.reconnectAsRegisteredAfterPairingInternal().finally(() => {
418
- this.pairingReconnectPromise = null;
403
+ this.keyShareCoordinator.notifyDisconnected();
404
+ await this.connectionManager.disconnect();
405
+ this.emit('connection', {
406
+ status: 'close',
407
+ reason: 'client_disconnected',
408
+ code: null,
409
+ isLogout: false,
410
+ isNewLogin: false
419
411
  });
420
- return this.pairingReconnectPromise;
421
- }
422
- async reconnectAsRegisteredAfterPairingInternal() {
423
- const credentials = this.authClient.getCurrentCredentials();
424
- if (!credentials?.meJid) {
425
- this.logger.trace('pairing reconnect skipped: still unregistered');
426
- return;
427
- }
428
- const currentComms = this.comms;
429
- if (!currentComms) {
430
- this.logger.trace('pairing reconnect skipped: no active comms');
431
- return;
432
- }
433
- this.logger.info('pairing completed, restarting comms as registered');
434
- this.keepAlive.stop();
435
- this.nodeOrchestrator.clearPending(new Error('restarting comms after pairing'));
436
- this.clearCommsBinding();
437
- try {
438
- await currentComms.stopComms();
439
- }
440
- catch (error) {
441
- this.logger.warn('failed to stop pre-registration comms', {
442
- message: toError(error).message
443
- });
444
- }
445
- try {
446
- await this.startCommsWithCredentials(credentials);
447
- }
448
- catch (error) {
449
- this.logger.warn('pairing reconnect failed while starting registered comms', {
450
- message: toError(error).message
451
- });
452
- throw error;
453
- }
454
- }
455
- async disconnect() {
456
- this.logger.info('wa client disconnect start');
457
- this.keepAlive.stop();
458
- this.notifyAppStateKeyShareWaiters(false);
459
- this.appStateBootstrapKeyShareWaitDone = false;
460
- await this.authClient.clearTransientState();
461
- this.nodeOrchestrator.clearPending(new Error('client disconnected'));
462
- this.clockSkewMs = null;
463
- this.mediaConnCache = null;
464
- this.passiveTasks.resetInFlightState();
465
- const comms = this.comms;
466
- this.clearCommsBinding();
467
- if (comms) {
468
- await comms.stopComms();
469
- this.logger.info('wa client disconnected');
470
- this.emit('connection_close', {});
471
- }
472
412
  }
473
413
  async requestPairingCode(phoneNumber, shouldShowPushNotification = false) {
474
- if (!this.comms || !this.authClient.getCurrentCredentials()) {
414
+ if (!this.connectionManager.isConnected() || !this.authClient.getCurrentCredentials()) {
475
415
  throw new Error('client is not connected');
476
416
  }
477
417
  this.logger.debug('wa client request pairing code');
478
418
  return this.authClient.requestPairingCode(phoneNumber, shouldShowPushNotification);
479
419
  }
480
420
  async fetchPairingCountryCodeIso() {
481
- if (!this.comms || !this.authClient.getCurrentCredentials()) {
421
+ if (!this.connectionManager.isConnected() || !this.authClient.getCurrentCredentials()) {
482
422
  throw new Error('client is not connected');
483
423
  }
484
424
  this.logger.trace('wa client fetch pairing country code iso');
485
425
  return this.authClient.fetchPairingCountryCodeIso();
486
426
  }
487
- async sendMessage(to, content, options = {}) {
427
+ async getLidsByPhoneNumbers(phoneNumbers) {
428
+ if (!this.connectionManager.isConnected() || !this.authClient.getCurrentCredentials()) {
429
+ throw new Error('client is not connected');
430
+ }
431
+ const normalizedPhoneJids = new Array(phoneNumbers.length);
432
+ for (let index = 0; index < phoneNumbers.length; index += 1) {
433
+ normalizedPhoneJids[index] = parsePhoneJid(phoneNumbers[index]);
434
+ }
435
+ this.logger.trace('wa client query lids by phone numbers', {
436
+ phones: normalizedPhoneJids.length
437
+ });
438
+ return this.signalDeviceSync.queryLidsByPhoneJids(normalizedPhoneJids);
439
+ }
440
+ sendMessage(to, content, options = {}) {
488
441
  return this.messageDispatch.sendMessage(to, content, options);
489
442
  }
490
443
  async syncSignalSession(jid, reasonIdentity = false) {
491
444
  await this.messageDispatch.syncSignalSession(jid, reasonIdentity);
445
+ if (reasonIdentity) {
446
+ this.trustedContactToken.reissueOnIdentityChange(jid).catch((err) => this.logger.warn('tc token reissue on identity change failed', {
447
+ jid,
448
+ message: toError(err).message
449
+ }));
450
+ }
451
+ }
452
+ get chat() {
453
+ return this.chatCoordinator;
492
454
  }
493
- async sendReceipt(input) {
494
- await this.messageDispatch.sendReceipt(input);
455
+ get group() {
456
+ return this.groupCoordinator;
457
+ }
458
+ get privacy() {
459
+ return this.privacyCoordinator;
460
+ }
461
+ get profile() {
462
+ return this.profileCoordinator;
463
+ }
464
+ get business() {
465
+ return this.businessCoordinator;
466
+ }
467
+ sendReceipt(input) {
468
+ return this.messageDispatch.sendReceipt(input);
469
+ }
470
+ flushAppStateMutations() {
471
+ return this.chatCoordinator.flushMutations();
472
+ }
473
+ flushWriteBehind(timeoutMs) {
474
+ return this.writeBehind.flush(timeoutMs);
495
475
  }
496
476
  async exportAppState() {
497
477
  return this.appStateSync.exportState();
498
478
  }
499
479
  async syncAppState(options = {}) {
500
- if (!this.comms) {
480
+ if (!this.connectionManager.isConnected()) {
501
481
  throw new Error('client is not connected');
502
482
  }
503
483
  const shouldWaitForKeyShare = (await this.appStateStore.getActiveSyncKey()) === null;
504
- if (shouldWaitForKeyShare && !this.appStateBootstrapKeyShareWaitDone) {
505
- this.appStateBootstrapKeyShareWaitDone = true;
484
+ if (shouldWaitForKeyShare && !this.keyShareCoordinator.isBootstrapDone()) {
485
+ this.keyShareCoordinator.markBootstrapDone();
506
486
  this.logger.info('app-state bootstrap pre-sync waiting for key share', {
507
487
  timeoutMs: WA_APP_STATE_KEY_SHARE_WAIT_TIMEOUT_MS
508
488
  });
509
- const received = await this.waitForAppStateKeyShare(WA_APP_STATE_KEY_SHARE_WAIT_TIMEOUT_MS);
489
+ const received = await this.keyShareCoordinator.waitForShare(WA_APP_STATE_KEY_SHARE_WAIT_TIMEOUT_MS);
510
490
  if (received) {
511
491
  this.logger.info('app-state bootstrap pre-sync received key share, continuing sync');
512
492
  }
@@ -523,17 +503,16 @@ export class WaClient extends EventEmitter {
523
503
  return syncResult;
524
504
  }
525
505
  let retryCount = 0;
526
- let observedKeyShareVersion = this.appStateKeyShareVersion;
527
- while (blockedCollections.length > 0 &&
528
- retryCount < WA_APP_STATE_KEY_SHARE_MAX_RETRIES) {
529
- const hasFreshShare = this.appStateKeyShareVersion !== observedKeyShareVersion;
506
+ let observedKeyShareVersion = this.keyShareCoordinator.getVersion();
507
+ while (blockedCollections.length > 0 && retryCount < WA_APP_STATE_KEY_SHARE_MAX_RETRIES) {
508
+ const hasFreshShare = this.keyShareCoordinator.getVersion() !== observedKeyShareVersion;
530
509
  if (!hasFreshShare) {
531
510
  this.logger.info('app-state bootstrap waiting for key share', {
532
511
  blockedCollections: blockedCollections.join(','),
533
512
  timeoutMs: WA_APP_STATE_KEY_SHARE_WAIT_TIMEOUT_MS,
534
513
  retryCount: retryCount + 1
535
514
  });
536
- const received = await this.waitForAppStateKeyShare(WA_APP_STATE_KEY_SHARE_WAIT_TIMEOUT_MS);
515
+ const received = await this.keyShareCoordinator.waitForShare(WA_APP_STATE_KEY_SHARE_WAIT_TIMEOUT_MS);
537
516
  if (!received) {
538
517
  this.logger.warn('app-state bootstrap key share wait timed out', {
539
518
  blockedCollections: blockedCollections.join(','),
@@ -542,7 +521,7 @@ export class WaClient extends EventEmitter {
542
521
  break;
543
522
  }
544
523
  }
545
- observedKeyShareVersion = this.appStateKeyShareVersion;
524
+ observedKeyShareVersion = this.keyShareCoordinator.getVersion();
546
525
  retryCount += 1;
547
526
  this.logger.info('app-state bootstrap retrying sync after key share', {
548
527
  retryCount,
@@ -569,41 +548,13 @@ export class WaClient extends EventEmitter {
569
548
  });
570
549
  }
571
550
  getBlockedAppStateCollections(syncResult) {
572
- return syncResult.collections
573
- .filter((entry) => entry.state === WA_APP_STATE_COLLECTION_STATES.BLOCKED)
574
- .map((entry) => entry.collection);
575
- }
576
- async waitForAppStateKeyShare(timeoutMs) {
577
- return new Promise((resolve) => {
578
- let settled = false;
579
- let timeoutHandle = null;
580
- const waiter = (received) => {
581
- if (settled) {
582
- return;
583
- }
584
- settled = true;
585
- if (timeoutHandle) {
586
- clearTimeout(timeoutHandle);
587
- timeoutHandle = null;
588
- }
589
- this.appStateKeyShareWaiters.delete(waiter);
590
- resolve(received);
591
- };
592
- this.appStateKeyShareWaiters.add(waiter);
593
- timeoutHandle = setTimeout(() => {
594
- waiter(false);
595
- }, timeoutMs);
596
- });
597
- }
598
- notifyAppStateKeyShareWaiters(received) {
599
- if (this.appStateKeyShareWaiters.size === 0) {
600
- return;
601
- }
602
- const waiters = [...this.appStateKeyShareWaiters.values()];
603
- this.appStateKeyShareWaiters.clear();
604
- for (const waiter of waiters) {
605
- waiter(received);
551
+ const blocked = [];
552
+ for (const entry of syncResult.collections) {
553
+ if (entry.state === WA_APP_STATE_COLLECTION_STATES.BLOCKED) {
554
+ blocked.push(entry.collection);
555
+ }
606
556
  }
557
+ return blocked;
607
558
  }
608
559
  emitChatEventsFromAppStateSyncResult(syncResult) {
609
560
  const shouldEmitSnapshotMutations = this.options.chatEvents?.emitSnapshotMutations === true;
@@ -627,6 +578,7 @@ export class WaClient extends EventEmitter {
627
578
  continue;
628
579
  }
629
580
  try {
581
+ this.handleNctSaltMutation(mutation);
630
582
  const event = parseChatEventFromAppStateMutation(mutation);
631
583
  if (!event) {
632
584
  continue;
@@ -644,102 +596,101 @@ export class WaClient extends EventEmitter {
644
596
  }
645
597
  }
646
598
  }
647
- async startCommsWithCredentials(credentials) {
648
- this.logger.debug('starting comms with credentials', {
649
- registered: credentials.meJid !== null && credentials.meJid !== undefined
650
- });
651
- const commsConfig = this.authClient.buildCommsConfig(this.options);
652
- const comms = new WaComms(commsConfig, this.logger);
653
- this.mediaConnCache = null;
654
- this.nodeTransport.bindComms(comms);
655
- try {
656
- comms.startComms(async (frame) => this.handleIncomingFrame(frame));
657
- await comms.waitForConnection(commsConfig.connectTimeoutMs);
658
- this.comms = comms;
659
- this.logger.info('comms connected');
660
- comms.startHandlingRequests();
661
- if (credentials.meJid) {
662
- this.keepAlive.start();
663
- }
664
- else {
665
- this.keepAlive.stop();
666
- }
667
- const serverStaticKey = comms.getServerStaticKey();
668
- if (!serverStaticKey) {
669
- this.logger.trace('no server static key available to persist');
670
- }
671
- else {
672
- await this.authClient.persistServerStaticKey(serverStaticKey);
673
- this.logger.debug('persisted server static key after comms connect');
674
- }
675
- this.passiveTasks.startPassiveTasksAfterConnect();
599
+ handleNctSaltMutation(mutation) {
600
+ const nctAction = mutation.value?.nctSaltSyncAction;
601
+ if (!nctAction) {
602
+ return;
676
603
  }
677
- catch (error) {
678
- this.clearCommsBinding();
679
- try {
680
- await comms.stopComms();
681
- }
682
- catch (stopError) {
683
- this.logger.warn('failed to cleanup comms after connection start failure', {
684
- message: toError(stopError).message
685
- });
686
- }
687
- throw error;
604
+ if (mutation.operation === 'set' && nctAction.salt) {
605
+ this.trustedContactToken.handleNctSaltSync(nctAction.salt).catch((err) => this.logger.warn('nct salt sync set failed', {
606
+ message: toError(err).message
607
+ }));
608
+ }
609
+ else if (mutation.operation === 'remove') {
610
+ this.trustedContactToken.handleNctSaltSync(null).catch((err) => this.logger.warn('nct salt sync remove failed', {
611
+ message: toError(err).message
612
+ }));
688
613
  }
689
614
  }
690
- shouldQueueDanglingReceipt(node, error) {
691
- if (node.tag !== WA_MESSAGE_TAGS.RECEIPT) {
615
+ async clearStoredState() {
616
+ await this.pauseIncomingEventsAndWaitDrain();
617
+ const writeBehindDestroy = await this.writeBehind.destroy(this.options.writeBehind?.flushTimeoutMs);
618
+ if (writeBehindDestroy.remaining > 0) {
619
+ throw new Error(`clear stored state aborted: write-behind did not fully drain (remaining=${writeBehindDestroy.remaining})`);
620
+ }
621
+ const danglingReceipts = this.receiptQueue.take();
622
+ if (danglingReceipts.length > 0) {
623
+ this.logger.debug('cleared dangling receipts while clearing stored state', {
624
+ count: danglingReceipts.length
625
+ });
626
+ }
627
+ const s = this.options.logoutStoreClear;
628
+ const shouldClear = (key) => s === undefined || s[key] !== false;
629
+ if (shouldClear('auth'))
630
+ await this.authClient.clearStoredCredentials();
631
+ if (shouldClear('appState'))
632
+ await this.appStateStore.clear();
633
+ if (shouldClear('contacts'))
634
+ await this.contactStore.clear();
635
+ if (shouldClear('messages'))
636
+ await this.messageStore.clear();
637
+ if (shouldClear('participants'))
638
+ await this.participantsStore.clear();
639
+ if (shouldClear('deviceList'))
640
+ await this.deviceListStore.clear();
641
+ if (shouldClear('retry'))
642
+ await this.retryStore.clear();
643
+ if (shouldClear('signal'))
644
+ await this.signalStore.clear();
645
+ if (shouldClear('senderKey'))
646
+ await this.senderKeyStore.clear();
647
+ if (shouldClear('threads'))
648
+ await this.threadStore.clear();
649
+ if (shouldClear('privacyToken'))
650
+ await this.privacyTokenStore.clear();
651
+ }
652
+ tryEnterIncomingHandler() {
653
+ if (!this.acceptingIncomingEvents) {
692
654
  return false;
693
655
  }
694
- const normalized = error.message.trim().toLowerCase();
695
- return (normalized === 'comms is not connected' ||
696
- normalized === 'websocket is not connected' ||
697
- normalized === 'noise session socket closed' ||
698
- normalized.startsWith('socket closed ('));
656
+ this.activeIncomingHandlers += 1;
657
+ if (this.acceptingIncomingEvents) {
658
+ return true;
659
+ }
660
+ this.leaveIncomingHandler();
661
+ return false;
699
662
  }
700
- enqueueDanglingReceipt(node) {
701
- if (this.danglingReceipts.length >= WA_DEFAULTS.MAX_DANGLING_RECEIPTS) {
702
- this.danglingReceipts.shift();
663
+ leaveIncomingHandler() {
664
+ if (this.activeIncomingHandlers <= 0) {
665
+ return;
666
+ }
667
+ this.activeIncomingHandlers -= 1;
668
+ if (this.activeIncomingHandlers === 0) {
669
+ this.notifyIncomingHandlersDrained();
703
670
  }
704
- this.danglingReceipts.push(node.content === undefined
705
- ? {
706
- tag: node.tag,
707
- attrs: { ...node.attrs }
708
- }
709
- : {
710
- tag: node.tag,
711
- attrs: { ...node.attrs },
712
- content: node.content
713
- });
714
671
  }
715
- async clearStoredState() {
716
- await this.authClient.clearStoredCredentials();
717
- await this.appStateStore.clear();
718
- await this.contactStore.clear();
719
- await this.messageStore.clear();
720
- await this.participantsStore.clear();
721
- await this.deviceListStore.clear();
722
- await this.retryStore.clear();
723
- await this.signalStore.clear();
724
- await this.senderKeyStore.clear();
725
- await this.threadStore.clear();
672
+ async pauseIncomingEventsAndWaitDrain() {
673
+ this.acceptingIncomingEvents = false;
674
+ if (this.activeIncomingHandlers === 0) {
675
+ return;
676
+ }
677
+ await new Promise((resolve) => {
678
+ this.incomingHandlersDrainedWaiters[this.incomingHandlersDrainedWaiters.length] =
679
+ resolve;
680
+ });
681
+ }
682
+ notifyIncomingHandlersDrained() {
683
+ if (this.incomingHandlersDrainedWaiters.length === 0) {
684
+ return;
685
+ }
686
+ const waitersLength = this.incomingHandlersDrainedWaiters.length;
687
+ for (let index = 0; index < waitersLength; index += 1) {
688
+ this.incomingHandlersDrainedWaiters[index]();
689
+ }
690
+ this.incomingHandlersDrainedWaiters.length = 0;
726
691
  }
727
692
  handleError(error) {
728
693
  this.logger.error('wa client error', { message: error.message });
729
694
  this.emit('client_error', { error });
730
695
  }
731
- clearCommsBinding() {
732
- this.notifyAppStateKeyShareWaiters(false);
733
- this.comms = null;
734
- this.nodeTransport.bindComms(null);
735
- }
736
- updateClockSkewFromSuccess(serverUnixSeconds) {
737
- const serverMs = serverUnixSeconds * 1000;
738
- const nowMs = Date.now();
739
- this.clockSkewMs = serverMs - nowMs;
740
- this.logger.debug('updated clock skew from success', {
741
- serverUnixSeconds,
742
- clockSkewMs: this.clockSkewMs
743
- });
744
- }
745
696
  }