zapo-js 0.1.0 → 0.1.2

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 (366) hide show
  1. package/README.md +12 -7
  2. package/dist/appstate/WaAppStateCrypto.js +18 -25
  3. package/dist/appstate/WaAppStateSyncClient.js +181 -114
  4. package/dist/appstate/WaAppStateSyncResponseParser.js +16 -5
  5. package/dist/appstate/constants.js +4 -3
  6. package/dist/appstate/utils.js +10 -30
  7. package/dist/auth/WaAuthClient.js +48 -55
  8. package/dist/auth/flow/WaAuthCredentialsFlow.js +21 -14
  9. package/dist/auth/index.js +1 -3
  10. package/dist/auth/pairing/WaPairingFlow.js +21 -23
  11. package/dist/auth/pairing/WaQrFlow.js +37 -24
  12. package/dist/client/WaClient.js +103 -276
  13. package/dist/client/WaClientFactory.js +227 -110
  14. package/dist/client/connection/WaConnectionManager.js +292 -0
  15. package/dist/client/connection/WaKeyShareCoordinator.js +63 -0
  16. package/dist/client/connection/WaReceiptQueue.js +51 -0
  17. package/dist/client/coordinators/WaAppStateMutationCoordinator.js +471 -0
  18. package/dist/client/coordinators/WaGroupCoordinator.js +27 -17
  19. package/dist/client/coordinators/WaIncomingNodeCoordinator.js +20 -27
  20. package/dist/client/coordinators/WaMessageDispatchCoordinator.js +231 -686
  21. package/dist/client/coordinators/WaRetryCoordinator.js +70 -37
  22. package/dist/client/dirty.js +35 -29
  23. package/dist/client/events/chat.js +4 -3
  24. package/dist/client/events/group.js +59 -36
  25. package/dist/client/history-sync.js +53 -63
  26. package/dist/client/incoming.js +23 -20
  27. package/dist/client/mailbox.js +8 -8
  28. package/dist/client/messages.js +4 -4
  29. package/dist/client/messaging/fanout.js +189 -0
  30. package/dist/client/messaging/key-protocol.js +130 -0
  31. package/dist/client/messaging/participants.js +191 -0
  32. package/dist/crypto/core/hkdf.js +3 -8
  33. package/dist/crypto/core/index.js +1 -4
  34. package/dist/crypto/core/keys.js +2 -3
  35. package/dist/crypto/core/primitives.js +12 -15
  36. package/dist/crypto/core/random.js +7 -26
  37. package/dist/crypto/curves/Ed25519.js +7 -8
  38. package/dist/crypto/curves/X25519.js +13 -16
  39. package/dist/crypto/index.js +0 -5
  40. package/dist/esm/appstate/WaAppStateCrypto.js +6 -13
  41. package/dist/esm/appstate/WaAppStateSyncClient.js +174 -107
  42. package/dist/esm/appstate/WaAppStateSyncResponseParser.js +17 -6
  43. package/dist/esm/appstate/constants.js +3 -2
  44. package/dist/esm/appstate/utils.js +8 -27
  45. package/dist/esm/auth/WaAuthClient.js +48 -55
  46. package/dist/esm/auth/flow/WaAuthCredentialsFlow.js +21 -14
  47. package/dist/esm/auth/index.js +0 -1
  48. package/dist/esm/auth/pairing/WaPairingFlow.js +14 -16
  49. package/dist/esm/auth/pairing/WaQrFlow.js +37 -24
  50. package/dist/esm/client/WaClient.js +103 -276
  51. package/dist/esm/client/WaClientFactory.js +227 -110
  52. package/dist/esm/client/connection/WaConnectionManager.js +288 -0
  53. package/dist/esm/client/connection/WaKeyShareCoordinator.js +59 -0
  54. package/dist/esm/client/connection/WaReceiptQueue.js +47 -0
  55. package/dist/esm/client/coordinators/WaAppStateMutationCoordinator.js +467 -0
  56. package/dist/esm/client/coordinators/WaGroupCoordinator.js +20 -10
  57. package/dist/esm/client/coordinators/WaIncomingNodeCoordinator.js +20 -27
  58. package/dist/esm/client/coordinators/WaMessageDispatchCoordinator.js +232 -687
  59. package/dist/esm/client/coordinators/WaRetryCoordinator.js +71 -38
  60. package/dist/esm/client/dirty.js +30 -24
  61. package/dist/esm/client/events/chat.js +4 -3
  62. package/dist/esm/client/events/group.js +50 -28
  63. package/dist/esm/client/history-sync.js +50 -60
  64. package/dist/esm/client/incoming.js +23 -20
  65. package/dist/esm/client/mailbox.js +8 -8
  66. package/dist/esm/client/messages.js +1 -1
  67. package/dist/esm/client/messaging/fanout.js +186 -0
  68. package/dist/esm/client/messaging/key-protocol.js +127 -0
  69. package/dist/esm/client/messaging/participants.js +188 -0
  70. package/dist/esm/crypto/core/hkdf.js +3 -8
  71. package/dist/esm/crypto/core/index.js +0 -1
  72. package/dist/esm/crypto/core/keys.js +2 -3
  73. package/dist/esm/crypto/core/primitives.js +12 -15
  74. package/dist/esm/crypto/core/random.js +6 -25
  75. package/dist/esm/crypto/curves/Ed25519.js +4 -5
  76. package/dist/esm/crypto/curves/X25519.js +10 -13
  77. package/dist/esm/crypto/index.js +0 -2
  78. package/dist/esm/infra/log/ConsoleLogger.js +18 -17
  79. package/dist/esm/infra/log/PinoLogger.js +15 -9
  80. package/dist/esm/infra/log/types.js +11 -1
  81. package/dist/esm/infra/perf/BoundedTaskQueue.js +13 -17
  82. package/dist/esm/media/WaMediaCrypto.js +2 -4
  83. package/dist/esm/media/WaMediaTransferClient.js +226 -58
  84. package/dist/esm/media/conn.js +10 -6
  85. package/dist/esm/media/constants.js +4 -1
  86. package/dist/esm/message/WaMessageClient.js +4 -13
  87. package/dist/esm/message/ack.js +6 -6
  88. package/dist/esm/message/addon-crypto.js +59 -0
  89. package/dist/esm/message/incoming.js +106 -111
  90. package/dist/esm/message/index.js +2 -0
  91. package/dist/esm/message/reporting-token.js +438 -0
  92. package/dist/esm/message/use-case-secret.js +49 -0
  93. package/dist/esm/protocol/appstate.js +58 -0
  94. package/dist/esm/protocol/constants.js +2 -1
  95. package/dist/esm/protocol/index.js +2 -10
  96. package/dist/esm/protocol/jid.js +63 -51
  97. package/dist/esm/protocol/media.js +3 -3
  98. package/dist/esm/protocol/nodes.js +2 -0
  99. package/dist/esm/protocol/usync.js +11 -0
  100. package/dist/esm/retry/index.js +1 -0
  101. package/dist/esm/retry/outbound.js +4 -5
  102. package/dist/esm/retry/parse.js +58 -76
  103. package/dist/esm/retry/replay.js +48 -49
  104. package/dist/esm/retry/tracker.js +56 -0
  105. package/dist/esm/signal/api/SignalDeviceSyncApi.js +249 -82
  106. package/dist/esm/signal/api/SignalDigestSyncApi.js +6 -1
  107. package/dist/esm/signal/api/SignalIdentitySyncApi.js +49 -34
  108. package/dist/esm/signal/api/SignalMissingPreKeysSyncApi.js +70 -62
  109. package/dist/esm/signal/api/SignalSessionSyncApi.js +23 -30
  110. package/dist/esm/signal/crypto/WaAdvSignature.js +3 -5
  111. package/dist/esm/signal/group/SenderKeyChain.js +28 -23
  112. package/dist/esm/signal/group/SenderKeyCodec.js +2 -4
  113. package/dist/esm/signal/group/SenderKeyManager.js +26 -16
  114. package/dist/esm/signal/index.js +1 -0
  115. package/dist/esm/signal/session/SignalProtocol.js +49 -14
  116. package/dist/esm/signal/session/SignalRatchet.js +24 -15
  117. package/dist/esm/signal/session/SignalSession.js +14 -9
  118. package/dist/esm/signal/session/resolver.js +186 -0
  119. package/dist/esm/signal/store/sqlite.js +16 -37
  120. package/dist/esm/store/createStore.js +16 -18
  121. package/dist/esm/store/noop.store.js +3 -6
  122. package/dist/esm/store/providers/memory/appstate.store.js +30 -6
  123. package/dist/esm/store/providers/memory/contact.store.js +5 -0
  124. package/dist/esm/store/providers/memory/device-list.store.js +3 -30
  125. package/dist/esm/store/providers/memory/message.store.js +11 -5
  126. package/dist/esm/store/providers/memory/participants.store.js +1 -8
  127. package/dist/esm/store/providers/memory/sender-key.store.js +5 -7
  128. package/dist/esm/store/providers/memory/signal.store.js +13 -1
  129. package/dist/esm/store/providers/memory/thread.store.js +5 -0
  130. package/dist/esm/store/providers/sqlite/appstate.store.js +82 -1
  131. package/dist/esm/store/providers/sqlite/connection.js +18 -13
  132. package/dist/esm/store/providers/sqlite/contact.store.js +31 -18
  133. package/dist/esm/store/providers/sqlite/device-list.store.js +7 -35
  134. package/dist/esm/store/providers/sqlite/message.store.js +45 -32
  135. package/dist/esm/store/providers/sqlite/migrations.js +1 -1
  136. package/dist/esm/store/providers/sqlite/participants.store.js +1 -9
  137. package/dist/esm/store/providers/sqlite/retry.store.js +8 -11
  138. package/dist/esm/store/providers/sqlite/sender-key.store.js +25 -30
  139. package/dist/esm/store/providers/sqlite/signal.store.js +104 -22
  140. package/dist/esm/store/providers/sqlite/table-names.js +107 -0
  141. package/dist/esm/store/providers/sqlite/thread.store.js +35 -22
  142. package/dist/esm/transport/WaComms.js +25 -23
  143. package/dist/esm/transport/WaWebSocket.js +115 -12
  144. package/dist/esm/transport/binary/decoder.js +4 -4
  145. package/dist/esm/transport/binary/encoder.js +12 -4
  146. package/dist/esm/transport/index.js +1 -0
  147. package/dist/esm/transport/keepalive/WaKeepAlive.js +2 -8
  148. package/dist/esm/transport/node/WaNodeOrchestrator.js +2 -4
  149. package/dist/esm/transport/node/WaNodeTransport.js +0 -3
  150. package/dist/esm/transport/node/builders/{accountSync.js → account-sync.js} +16 -36
  151. package/dist/esm/transport/node/builders/index.js +2 -1
  152. package/dist/esm/transport/node/builders/message.js +9 -0
  153. package/dist/esm/transport/node/builders/pairing.js +4 -5
  154. package/dist/esm/transport/node/builders/usync.js +41 -0
  155. package/dist/esm/transport/node/helpers.js +107 -5
  156. package/dist/esm/transport/node/usync.js +35 -0
  157. package/dist/esm/transport/noise/WaFrameCodec.js +48 -33
  158. package/dist/esm/transport/noise/WaNoiseCert.js +3 -6
  159. package/dist/esm/transport/noise/WaNoiseSession.js +17 -10
  160. package/dist/esm/transport/proxy.js +27 -0
  161. package/dist/esm/transport/stream/parse.js +13 -48
  162. package/dist/esm/util/bytes.js +50 -32
  163. package/dist/esm/util/coercion.js +6 -14
  164. package/dist/esm/util/primitives.js +39 -14
  165. package/dist/infra/log/ConsoleLogger.js +18 -17
  166. package/dist/infra/log/PinoLogger.js +15 -9
  167. package/dist/infra/log/types.js +12 -0
  168. package/dist/infra/perf/BoundedTaskQueue.js +13 -17
  169. package/dist/media/WaMediaCrypto.js +1 -3
  170. package/dist/media/WaMediaTransferClient.js +259 -58
  171. package/dist/media/conn.js +10 -6
  172. package/dist/media/constants.js +4 -1
  173. package/dist/message/WaMessageClient.js +5 -14
  174. package/dist/message/ack.js +6 -6
  175. package/dist/message/addon-crypto.js +65 -0
  176. package/dist/message/incoming.js +104 -109
  177. package/dist/message/index.js +2 -0
  178. package/dist/message/reporting-token.js +443 -0
  179. package/dist/message/use-case-secret.js +55 -0
  180. package/dist/protocol/appstate.js +59 -1
  181. package/dist/protocol/constants.js +7 -1
  182. package/dist/protocol/index.js +20 -42
  183. package/dist/protocol/jid.js +64 -51
  184. package/dist/protocol/media.js +3 -3
  185. package/dist/protocol/nodes.js +2 -0
  186. package/dist/protocol/usync.js +14 -0
  187. package/dist/retry/index.js +3 -1
  188. package/dist/retry/outbound.js +6 -7
  189. package/dist/retry/parse.js +57 -75
  190. package/dist/retry/replay.js +46 -47
  191. package/dist/retry/tracker.js +59 -0
  192. package/dist/signal/api/SignalDeviceSyncApi.js +247 -80
  193. package/dist/signal/api/SignalDigestSyncApi.js +6 -1
  194. package/dist/signal/api/SignalIdentitySyncApi.js +49 -34
  195. package/dist/signal/api/SignalMissingPreKeysSyncApi.js +67 -59
  196. package/dist/signal/api/SignalSessionSyncApi.js +23 -30
  197. package/dist/signal/crypto/WaAdvSignature.js +2 -4
  198. package/dist/signal/group/SenderKeyChain.js +27 -22
  199. package/dist/signal/group/SenderKeyCodec.js +1 -3
  200. package/dist/signal/group/SenderKeyManager.js +26 -16
  201. package/dist/signal/index.js +3 -1
  202. package/dist/signal/session/SignalProtocol.js +49 -14
  203. package/dist/signal/session/SignalRatchet.js +24 -15
  204. package/dist/signal/session/SignalSession.js +14 -9
  205. package/dist/signal/session/resolver.js +189 -0
  206. package/dist/signal/store/sqlite.js +16 -37
  207. package/dist/store/createStore.js +16 -18
  208. package/dist/store/noop.store.js +3 -6
  209. package/dist/store/providers/memory/appstate.store.js +28 -4
  210. package/dist/store/providers/memory/contact.store.js +5 -0
  211. package/dist/store/providers/memory/device-list.store.js +3 -30
  212. package/dist/store/providers/memory/message.store.js +11 -5
  213. package/dist/store/providers/memory/participants.store.js +1 -8
  214. package/dist/store/providers/memory/sender-key.store.js +8 -10
  215. package/dist/store/providers/memory/signal.store.js +21 -9
  216. package/dist/store/providers/memory/thread.store.js +5 -0
  217. package/dist/store/providers/sqlite/appstate.store.js +81 -0
  218. package/dist/store/providers/sqlite/connection.js +18 -13
  219. package/dist/store/providers/sqlite/contact.store.js +31 -18
  220. package/dist/store/providers/sqlite/device-list.store.js +7 -35
  221. package/dist/store/providers/sqlite/message.store.js +45 -32
  222. package/dist/store/providers/sqlite/migrations.js +1 -1
  223. package/dist/store/providers/sqlite/participants.store.js +1 -9
  224. package/dist/store/providers/sqlite/retry.store.js +8 -11
  225. package/dist/store/providers/sqlite/sender-key.store.js +24 -29
  226. package/dist/store/providers/sqlite/signal.store.js +105 -23
  227. package/dist/store/providers/sqlite/table-names.js +113 -0
  228. package/dist/store/providers/sqlite/thread.store.js +35 -22
  229. package/dist/transport/WaComms.js +27 -25
  230. package/dist/transport/WaWebSocket.js +148 -12
  231. package/dist/transport/binary/decoder.js +4 -4
  232. package/dist/transport/binary/encoder.js +12 -4
  233. package/dist/transport/index.js +7 -1
  234. package/dist/transport/keepalive/WaKeepAlive.js +1 -7
  235. package/dist/transport/node/WaNodeOrchestrator.js +2 -4
  236. package/dist/transport/node/WaNodeTransport.js +0 -3
  237. package/dist/transport/node/builders/{accountSync.js → account-sync.js} +15 -35
  238. package/dist/transport/node/builders/index.js +12 -9
  239. package/dist/transport/node/builders/message.js +9 -0
  240. package/dist/transport/node/builders/pairing.js +4 -5
  241. package/dist/transport/node/builders/usync.js +45 -0
  242. package/dist/transport/node/helpers.js +112 -4
  243. package/dist/transport/node/usync.js +38 -0
  244. package/dist/transport/noise/WaFrameCodec.js +47 -32
  245. package/dist/transport/noise/WaNoiseCert.js +5 -8
  246. package/dist/transport/noise/WaNoiseSession.js +17 -10
  247. package/dist/transport/proxy.js +34 -0
  248. package/dist/transport/stream/parse.js +17 -53
  249. package/dist/types/appstate/WaAppStateCrypto.d.ts +0 -1
  250. package/dist/types/appstate/WaAppStateSyncClient.d.ts +5 -2
  251. package/dist/types/appstate/constants.d.ts +1 -0
  252. package/dist/types/appstate/store/sqlite.d.ts +4 -18
  253. package/dist/types/appstate/utils.d.ts +0 -1
  254. package/dist/types/auth/WaAuthClient.d.ts +10 -12
  255. package/dist/types/auth/index.d.ts +0 -2
  256. package/dist/types/auth/pairing/WaQrFlow.d.ts +1 -1
  257. package/dist/types/auth/types.d.ts +6 -9
  258. package/dist/types/client/WaClient.d.ts +27 -25
  259. package/dist/types/client/WaClientFactory.d.ts +22 -23
  260. package/dist/types/client/connection/WaConnectionManager.d.ts +64 -0
  261. package/dist/types/client/connection/WaKeyShareCoordinator.d.ts +14 -0
  262. package/dist/types/client/connection/WaReceiptQueue.d.ts +13 -0
  263. package/dist/types/client/coordinators/WaAppStateMutationCoordinator.d.ts +46 -0
  264. package/dist/types/client/coordinators/WaIncomingNodeCoordinator.d.ts +0 -1
  265. package/dist/types/client/coordinators/WaMessageDispatchCoordinator.d.ts +18 -41
  266. package/dist/types/client/coordinators/WaRetryCoordinator.d.ts +2 -0
  267. package/dist/types/client/dirty.d.ts +1 -0
  268. package/dist/types/client/events/group.d.ts +2 -1
  269. package/dist/types/client/index.d.ts +1 -1
  270. package/dist/types/client/messaging/fanout.d.ts +14 -0
  271. package/dist/types/client/messaging/key-protocol.d.ts +18 -0
  272. package/dist/types/client/messaging/participants.d.ts +13 -0
  273. package/dist/types/client/types.d.ts +24 -1
  274. package/dist/types/crypto/core/hkdf.d.ts +0 -6
  275. package/dist/types/crypto/core/index.d.ts +0 -1
  276. package/dist/types/crypto/core/random.d.ts +1 -7
  277. package/dist/types/crypto/index.d.ts +0 -2
  278. package/dist/types/index.d.ts +1 -1
  279. package/dist/types/infra/log/ConsoleLogger.d.ts +2 -1
  280. package/dist/types/infra/log/PinoLogger.d.ts +1 -1
  281. package/dist/types/infra/log/types.d.ts +1 -0
  282. package/dist/types/infra/perf/BoundedTaskQueue.d.ts +1 -1
  283. package/dist/types/media/WaMediaTransferClient.d.ts +13 -3
  284. package/dist/types/media/types.d.ts +5 -0
  285. package/dist/types/message/addon-crypto.d.ts +25 -0
  286. package/dist/types/message/index.d.ts +2 -0
  287. package/dist/types/message/reporting-token.d.ts +19 -0
  288. package/dist/types/message/use-case-secret.d.ts +20 -0
  289. package/dist/types/protocol/appstate.d.ts +58 -0
  290. package/dist/types/protocol/constants.d.ts +2 -1
  291. package/dist/types/protocol/index.d.ts +2 -10
  292. package/dist/types/protocol/jid.d.ts +3 -3
  293. package/dist/types/protocol/nodes.d.ts +2 -0
  294. package/dist/types/protocol/usync.d.ts +11 -0
  295. package/dist/types/retry/index.d.ts +1 -0
  296. package/dist/types/retry/replay.d.ts +0 -4
  297. package/dist/types/retry/tracker.d.ts +19 -0
  298. package/dist/types/retry/types.d.ts +4 -3
  299. package/dist/types/signal/api/SignalDeviceSyncApi.d.ts +13 -1
  300. package/dist/types/signal/group/SenderKeyCodec.d.ts +4 -6
  301. package/dist/types/signal/index.d.ts +1 -0
  302. package/dist/types/signal/session/SignalProtocol.d.ts +9 -0
  303. package/dist/types/signal/session/resolver.d.ts +17 -0
  304. package/dist/types/store/contracts/appstate.store.d.ts +3 -0
  305. package/dist/types/store/contracts/contact.store.d.ts +1 -0
  306. package/dist/types/store/contracts/device-list.store.d.ts +0 -3
  307. package/dist/types/store/contracts/message.store.d.ts +1 -0
  308. package/dist/types/store/contracts/participants.store.d.ts +0 -1
  309. package/dist/types/store/contracts/sender-key.store.d.ts +0 -1
  310. package/dist/types/store/contracts/signal.store.d.ts +6 -0
  311. package/dist/types/store/contracts/thread.store.d.ts +1 -0
  312. package/dist/types/store/index.d.ts +1 -1
  313. package/dist/types/store/providers/memory/appstate.store.d.ts +2 -0
  314. package/dist/types/store/providers/memory/contact.store.d.ts +1 -0
  315. package/dist/types/store/providers/memory/device-list.store.d.ts +0 -3
  316. package/dist/types/store/providers/memory/message.store.d.ts +1 -0
  317. package/dist/types/store/providers/memory/participants.store.d.ts +0 -1
  318. package/dist/types/store/providers/memory/sender-key.store.d.ts +0 -1
  319. package/dist/types/store/providers/memory/signal.store.d.ts +6 -0
  320. package/dist/types/store/providers/memory/thread.store.d.ts +1 -0
  321. package/dist/types/store/providers/sqlite/appstate.store.d.ts +2 -0
  322. package/dist/types/store/providers/sqlite/contact.store.d.ts +2 -0
  323. package/dist/types/store/providers/sqlite/device-list.store.d.ts +0 -3
  324. package/dist/types/store/providers/sqlite/message.store.d.ts +2 -0
  325. package/dist/types/store/providers/sqlite/participants.store.d.ts +0 -1
  326. package/dist/types/store/providers/sqlite/retry.store.d.ts +0 -1
  327. package/dist/types/store/providers/sqlite/sender-key.store.d.ts +0 -1
  328. package/dist/types/store/providers/sqlite/signal.store.d.ts +7 -0
  329. package/dist/types/store/providers/sqlite/table-names.d.ts +5 -0
  330. package/dist/types/store/providers/sqlite/thread.store.d.ts +2 -0
  331. package/dist/types/store/types.d.ts +3 -0
  332. package/dist/types/transport/WaWebSocket.d.ts +3 -0
  333. package/dist/types/transport/index.d.ts +2 -1
  334. package/dist/types/transport/keepalive/WaKeepAlive.d.ts +0 -1
  335. package/dist/types/transport/node/WaNodeTransport.d.ts +0 -9
  336. package/dist/types/transport/node/builders/group.d.ts +4 -6
  337. package/dist/types/transport/node/builders/index.d.ts +2 -1
  338. package/dist/types/transport/node/builders/message.d.ts +14 -25
  339. package/dist/types/transport/node/builders/retry.d.ts +2 -4
  340. package/dist/types/transport/node/builders/usync.d.ts +21 -0
  341. package/dist/types/transport/node/helpers.d.ts +8 -0
  342. package/dist/types/transport/node/usync.d.ts +2 -0
  343. package/dist/types/transport/noise/WaFrameCodec.d.ts +3 -0
  344. package/dist/types/transport/noise/WaNoiseSession.d.ts +1 -0
  345. package/dist/types/transport/proxy.d.ts +6 -0
  346. package/dist/types/transport/stream/parse.d.ts +0 -1
  347. package/dist/types/transport/types.d.ts +18 -1
  348. package/dist/types/util/bytes.d.ts +5 -0
  349. package/dist/types/util/primitives.d.ts +3 -0
  350. package/dist/util/bytes.js +55 -33
  351. package/dist/util/coercion.js +6 -14
  352. package/dist/util/primitives.js +42 -14
  353. package/package.json +27 -9
  354. package/proto/index.d.ts +1090 -1048
  355. package/proto/index.js +1 -1
  356. package/scripts/check-node-version.cjs +0 -1
  357. package/dist/crypto/core/encoding.js +0 -29
  358. package/dist/esm/crypto/core/encoding.js +0 -25
  359. package/dist/esm/util/base64.js +0 -18
  360. package/dist/esm/util/signal-address.js +0 -5
  361. package/dist/types/crypto/core/encoding.d.ts +0 -11
  362. package/dist/types/util/base64.d.ts +0 -4
  363. package/dist/types/util/signal-address.d.ts +0 -2
  364. package/dist/util/base64.js +0 -24
  365. package/dist/util/signal-address.js +0 -8
  366. /package/dist/types/transport/node/builders/{accountSync.d.ts → account-sync.d.ts} +0 -0
@@ -0,0 +1,467 @@
1
+ import { WA_APP_STATE_CHAT_MUTATION_SPECS, WA_APP_STATE_COLLECTION_STATES } from '../../protocol/constants.js';
2
+ import { isGroupJid, isGroupOrBroadcastJid, normalizeDeviceJid, normalizeRecipientJid, toUserJid } from '../../protocol/jid.js';
3
+ import { resolvePositive } from '../../util/coercion.js';
4
+ import { toError } from '../../util/primitives.js';
5
+ const WA_APP_STATE_MUTATION_FLUSH_SUCCESS_STATES = new Set([
6
+ WA_APP_STATE_COLLECTION_STATES.SUCCESS,
7
+ WA_APP_STATE_COLLECTION_STATES.SUCCESS_HAS_MORE
8
+ ]);
9
+ const WA_APP_STATE_ARCHIVE_RANGE_DEFAULT_LIMIT = 256;
10
+ export class WaAppStateMutationCoordinator {
11
+ constructor(options) {
12
+ this.logger = options.logger;
13
+ this.messageStore = options.messageStore;
14
+ this.syncAppState = options.syncAppState;
15
+ this.archiveRangeLimit = resolvePositive(options.archiveRangeLimit, WA_APP_STATE_ARCHIVE_RANGE_DEFAULT_LIMIT, 'WaAppStateMutationCoordinatorOptions.archiveRangeLimit');
16
+ this.pendingMutations = new Map();
17
+ this.flushPromise = null;
18
+ }
19
+ async setChatMute(chatJid, muted, muteEndTimestampMs) {
20
+ const chatIndexJid = this.normalizeChatMutationJid(chatJid);
21
+ const timestamp = Date.now();
22
+ const normalizedMuteEnd = muteEndTimestampMs;
23
+ if (normalizedMuteEnd !== undefined &&
24
+ (!Number.isFinite(normalizedMuteEnd) ||
25
+ !Number.isSafeInteger(normalizedMuteEnd) ||
26
+ normalizedMuteEnd < 0)) {
27
+ throw new Error(`invalid muteEndTimestampMs: ${muteEndTimestampMs}`);
28
+ }
29
+ if (muted && normalizedMuteEnd === undefined) {
30
+ throw new Error('setChatMute requires muteEndTimestampMs when muted is true');
31
+ }
32
+ const mutation = this.createSetMutation({
33
+ spec: WA_APP_STATE_CHAT_MUTATION_SPECS.MUTE,
34
+ chatIndexJid,
35
+ value: {
36
+ muteAction: {
37
+ muted,
38
+ ...(normalizedMuteEnd === undefined
39
+ ? {}
40
+ : { muteEndTimestamp: normalizedMuteEnd })
41
+ }
42
+ },
43
+ timestamp
44
+ });
45
+ await this.enqueueAndFlush([mutation]);
46
+ }
47
+ async setMessageStar(message, starred) {
48
+ const messageIndex = this.buildMessageMutationIndex(message);
49
+ const timestamp = Date.now();
50
+ const mutation = this.createSetMutation({
51
+ spec: WA_APP_STATE_CHAT_MUTATION_SPECS.STAR,
52
+ chatIndexJid: messageIndex.chatIndexJid,
53
+ value: {
54
+ starAction: {
55
+ starred
56
+ }
57
+ },
58
+ timestamp,
59
+ indexPartsTail: messageIndex.indexPartsTail
60
+ });
61
+ await this.enqueueAndFlush([mutation]);
62
+ }
63
+ async setChatRead(chatJid, read) {
64
+ const chatIndexJid = this.normalizeChatMutationJid(chatJid);
65
+ const timestamp = Date.now();
66
+ const messageRange = await this.buildChatMessageRange(chatIndexJid);
67
+ const mutation = this.createSetMutation({
68
+ spec: WA_APP_STATE_CHAT_MUTATION_SPECS.MARK_CHAT_AS_READ,
69
+ chatIndexJid,
70
+ value: {
71
+ markChatAsReadAction: {
72
+ read,
73
+ messageRange
74
+ }
75
+ },
76
+ timestamp
77
+ });
78
+ await this.enqueueAndFlush([mutation]);
79
+ }
80
+ async setChatPin(chatJid, pinned) {
81
+ const chatIndexJid = this.normalizeChatMutationJid(chatJid);
82
+ const timestamp = Date.now();
83
+ const pending = [
84
+ this.createSetMutation({
85
+ spec: WA_APP_STATE_CHAT_MUTATION_SPECS.PIN,
86
+ chatIndexJid,
87
+ value: {
88
+ pinAction: {
89
+ pinned
90
+ }
91
+ },
92
+ timestamp
93
+ })
94
+ ];
95
+ if (pinned) {
96
+ pending.push(await this.createArchiveMutation(chatIndexJid, false, timestamp));
97
+ }
98
+ await this.enqueueAndFlush(pending);
99
+ }
100
+ async setChatArchive(chatJid, archived) {
101
+ const chatIndexJid = this.normalizeChatMutationJid(chatJid);
102
+ const timestamp = Date.now();
103
+ const pending = [
104
+ await this.createArchiveMutation(chatIndexJid, archived, timestamp)
105
+ ];
106
+ if (archived) {
107
+ pending.push(this.createSetMutation({
108
+ spec: WA_APP_STATE_CHAT_MUTATION_SPECS.PIN,
109
+ chatIndexJid,
110
+ value: {
111
+ pinAction: {
112
+ pinned: false
113
+ }
114
+ },
115
+ timestamp
116
+ }));
117
+ }
118
+ await this.enqueueAndFlush(pending);
119
+ }
120
+ async clearChat(chatJid, options = {}) {
121
+ const chatIndexJid = this.normalizeChatMutationJid(chatJid);
122
+ const timestamp = Date.now();
123
+ const deleteStarred = options.deleteStarred === true;
124
+ const deleteMedia = options.deleteMedia === true;
125
+ const messageRange = await this.buildChatMessageRange(chatIndexJid);
126
+ const mutation = this.createSetMutation({
127
+ spec: WA_APP_STATE_CHAT_MUTATION_SPECS.CLEAR_CHAT,
128
+ chatIndexJid,
129
+ value: {
130
+ clearChatAction: {
131
+ messageRange
132
+ }
133
+ },
134
+ timestamp,
135
+ indexPartsTail: [deleteStarred ? '1' : '0', deleteMedia ? '1' : '0']
136
+ });
137
+ await this.enqueueAndFlush([mutation]);
138
+ }
139
+ async deleteChat(chatJid, options = {}) {
140
+ const chatIndexJid = this.normalizeChatMutationJid(chatJid);
141
+ const timestamp = Date.now();
142
+ const deleteMedia = options.deleteMedia === true;
143
+ const messageRange = await this.buildChatMessageRange(chatIndexJid);
144
+ const mutation = this.createSetMutation({
145
+ spec: WA_APP_STATE_CHAT_MUTATION_SPECS.DELETE_CHAT,
146
+ chatIndexJid,
147
+ value: {
148
+ deleteChatAction: {
149
+ messageRange
150
+ }
151
+ },
152
+ timestamp,
153
+ indexPartsTail: [deleteMedia ? '1' : '0']
154
+ });
155
+ await this.enqueueAndFlush([mutation]);
156
+ }
157
+ async deleteMessageForMe(message, options = {}) {
158
+ const messageIndex = this.buildMessageMutationIndex(message);
159
+ const timestamp = Date.now();
160
+ const deleteMedia = options.deleteMedia === true;
161
+ const messageTimestampMs = options.messageTimestampMs;
162
+ let messageTimestamp;
163
+ if (messageTimestampMs !== undefined) {
164
+ if (!Number.isFinite(messageTimestampMs) ||
165
+ !Number.isSafeInteger(messageTimestampMs) ||
166
+ messageTimestampMs < 0) {
167
+ throw new Error(`invalid messageTimestampMs: ${messageTimestampMs}`);
168
+ }
169
+ messageTimestamp = Math.floor(messageTimestampMs / 1000);
170
+ }
171
+ const mutation = this.createSetMutation({
172
+ spec: WA_APP_STATE_CHAT_MUTATION_SPECS.DELETE_MESSAGE_FOR_ME,
173
+ chatIndexJid: messageIndex.chatIndexJid,
174
+ value: {
175
+ deleteMessageForMeAction: {
176
+ deleteMedia,
177
+ ...(messageTimestamp === undefined ? {} : { messageTimestamp })
178
+ }
179
+ },
180
+ timestamp,
181
+ indexPartsTail: messageIndex.indexPartsTail
182
+ });
183
+ await this.enqueueAndFlush([mutation]);
184
+ }
185
+ async setChatLock(chatJid, locked) {
186
+ const chatIndexJid = this.normalizeChatMutationJid(chatJid);
187
+ const timestamp = Date.now();
188
+ const pending = [];
189
+ if (locked) {
190
+ pending.push(await this.createArchiveMutation(chatIndexJid, false, timestamp));
191
+ pending.push(this.createSetMutation({
192
+ spec: WA_APP_STATE_CHAT_MUTATION_SPECS.PIN,
193
+ chatIndexJid,
194
+ value: {
195
+ pinAction: {
196
+ pinned: false
197
+ }
198
+ },
199
+ timestamp
200
+ }));
201
+ }
202
+ pending.push(this.createSetMutation({
203
+ spec: WA_APP_STATE_CHAT_MUTATION_SPECS.LOCK_CHAT,
204
+ chatIndexJid,
205
+ value: {
206
+ lockChatAction: {
207
+ locked
208
+ }
209
+ },
210
+ timestamp
211
+ }));
212
+ await this.enqueueAndFlush(pending);
213
+ }
214
+ async flushMutations() {
215
+ if (this.flushPromise) {
216
+ return this.flushPromise;
217
+ }
218
+ const inFlight = this.flushPendingMutationsLoop();
219
+ this.flushPromise = inFlight;
220
+ try {
221
+ return await inFlight;
222
+ }
223
+ finally {
224
+ if (this.flushPromise === inFlight) {
225
+ this.flushPromise = null;
226
+ }
227
+ }
228
+ }
229
+ async enqueueAndFlush(mutations) {
230
+ for (const mutation of mutations) {
231
+ this.enqueueMutation(mutation);
232
+ }
233
+ await this.flushMutations();
234
+ }
235
+ enqueueMutation(mutation) {
236
+ const key = `${mutation.collection}\u0001${mutation.index}`;
237
+ if (this.pendingMutations.has(key)) {
238
+ this.pendingMutations.delete(key);
239
+ }
240
+ this.pendingMutations.set(key, mutation);
241
+ }
242
+ takePendingMutationsBatch() {
243
+ if (this.pendingMutations.size === 0) {
244
+ return [];
245
+ }
246
+ const batch = [...this.pendingMutations.values()];
247
+ this.pendingMutations.clear();
248
+ return batch;
249
+ }
250
+ async flushPendingMutationsLoop() {
251
+ while (true) {
252
+ const batch = this.takePendingMutationsBatch();
253
+ if (batch.length === 0) {
254
+ return;
255
+ }
256
+ this.logger.debug('app-state mutation flush start', {
257
+ pending: batch.length,
258
+ actions: this.describeMutationActions(batch)
259
+ });
260
+ const collections = [];
261
+ let syncResult;
262
+ try {
263
+ const seenCollections = new Set();
264
+ for (const mutation of batch) {
265
+ if (seenCollections.has(mutation.collection)) {
266
+ continue;
267
+ }
268
+ seenCollections.add(mutation.collection);
269
+ collections.push(mutation.collection);
270
+ }
271
+ syncResult = await this.syncAppState({
272
+ collections,
273
+ pendingMutations: batch
274
+ });
275
+ }
276
+ catch (error) {
277
+ this.requeueMutations(batch);
278
+ this.logger.warn('app-state mutation flush failed', {
279
+ pending: batch.length,
280
+ actions: this.describeMutationActions(batch),
281
+ message: toError(error).message
282
+ });
283
+ throw toError(error);
284
+ }
285
+ const stateByCollection = new Map();
286
+ for (const entry of syncResult.collections) {
287
+ stateByCollection.set(entry.collection, entry.state);
288
+ }
289
+ const failedCollections = collections.filter((collection) => {
290
+ const state = stateByCollection.get(collection);
291
+ return !state || !WA_APP_STATE_MUTATION_FLUSH_SUCCESS_STATES.has(state);
292
+ });
293
+ if (failedCollections.length === 0) {
294
+ this.logger.debug('app-state mutation flush completed', {
295
+ pending: batch.length
296
+ });
297
+ continue;
298
+ }
299
+ this.requeueMutations(batch.filter((mutation) => failedCollections.includes(mutation.collection)));
300
+ const error = new Error(`app-state mutation flush incomplete (${failedCollections.join(',')})`);
301
+ this.logger.warn('app-state mutation flush incomplete', {
302
+ pending: batch.length,
303
+ actions: this.describeMutationActions(batch),
304
+ failedCollections: failedCollections.join(','),
305
+ message: error.message
306
+ });
307
+ throw error;
308
+ }
309
+ }
310
+ requeueMutations(mutations) {
311
+ if (mutations.length === 0) {
312
+ return;
313
+ }
314
+ const existing = [...this.pendingMutations.values()];
315
+ this.pendingMutations.clear();
316
+ for (const mutation of mutations) {
317
+ this.enqueueMutation(mutation);
318
+ }
319
+ for (const mutation of existing) {
320
+ this.enqueueMutation(mutation);
321
+ }
322
+ }
323
+ createSetMutation(input) {
324
+ return {
325
+ collection: input.spec.collection,
326
+ operation: 'set',
327
+ index: this.buildMutationIndex(input.spec.action, input.chatIndexJid, input.indexPartsTail ?? []),
328
+ value: {
329
+ ...input.value,
330
+ timestamp: input.timestamp
331
+ },
332
+ version: input.spec.version,
333
+ timestamp: input.timestamp
334
+ };
335
+ }
336
+ async createArchiveMutation(chatIndexJid, archived, timestamp) {
337
+ const messageRange = await this.buildChatMessageRange(chatIndexJid);
338
+ return this.createSetMutation({
339
+ spec: WA_APP_STATE_CHAT_MUTATION_SPECS.ARCHIVE,
340
+ chatIndexJid,
341
+ value: {
342
+ archiveChatAction: {
343
+ archived,
344
+ messageRange
345
+ }
346
+ },
347
+ timestamp
348
+ });
349
+ }
350
+ async buildChatMessageRange(chatIndexJid) {
351
+ const records = await this.messageStore.listByThread(chatIndexJid, this.archiveRangeLimit);
352
+ const messages = [];
353
+ let lastMessageTimestamp;
354
+ let skippedMissingGroupParticipant = 0;
355
+ for (const record of records) {
356
+ const timestampSeconds = this.toOptionalTimestampSeconds(record.timestampMs);
357
+ const message = this.toChatMessageRangeMessage(record, chatIndexJid, timestampSeconds);
358
+ if (!message) {
359
+ skippedMissingGroupParticipant += 1;
360
+ continue;
361
+ }
362
+ if (timestampSeconds !== undefined &&
363
+ (lastMessageTimestamp === undefined || timestampSeconds > lastMessageTimestamp)) {
364
+ lastMessageTimestamp = timestampSeconds;
365
+ }
366
+ messages.push(message);
367
+ }
368
+ if (skippedMissingGroupParticipant > 0) {
369
+ this.logger.debug('app-state message range skipped invalid group messages', {
370
+ chatJid: chatIndexJid,
371
+ skippedMissingGroupParticipant
372
+ });
373
+ }
374
+ return {
375
+ ...(lastMessageTimestamp === undefined ? {} : { lastMessageTimestamp }),
376
+ messages
377
+ };
378
+ }
379
+ toChatMessageRangeMessage(record, chatIndexJid, timestampSeconds) {
380
+ const key = {
381
+ remoteJid: chatIndexJid,
382
+ fromMe: record.fromMe,
383
+ id: record.id
384
+ };
385
+ if (isGroupJid(chatIndexJid) && !record.fromMe) {
386
+ const participant = record.participantJid ?? record.senderJid;
387
+ if (!participant) {
388
+ return null;
389
+ }
390
+ key.participant = this.normalizeMessageRangeParticipant(participant);
391
+ }
392
+ return {
393
+ key,
394
+ ...(timestampSeconds === undefined ? {} : { timestamp: timestampSeconds })
395
+ };
396
+ }
397
+ normalizeMessageRangeParticipant(participantJid) {
398
+ const normalized = normalizeRecipientJid(participantJid);
399
+ if (isGroupOrBroadcastJid(normalized)) {
400
+ throw new Error(`invalid group/broadcast participant in message range: ${participantJid}`);
401
+ }
402
+ return normalizeDeviceJid(normalized);
403
+ }
404
+ toOptionalTimestampSeconds(timestampMs) {
405
+ if (timestampMs === undefined) {
406
+ return undefined;
407
+ }
408
+ if (!Number.isFinite(timestampMs) ||
409
+ !Number.isSafeInteger(timestampMs) ||
410
+ timestampMs < 0) {
411
+ return undefined;
412
+ }
413
+ return Math.floor(timestampMs / 1000);
414
+ }
415
+ normalizeChatMutationJid(chatJid) {
416
+ const normalized = normalizeRecipientJid(chatJid);
417
+ if (isGroupOrBroadcastJid(normalized)) {
418
+ return normalized;
419
+ }
420
+ return toUserJid(normalized);
421
+ }
422
+ buildMessageMutationIndex(message) {
423
+ const chatIndexJid = this.normalizeChatMutationJid(message.chatJid);
424
+ const messageId = message.id.trim();
425
+ if (messageId.length === 0) {
426
+ throw new Error('message id cannot be empty');
427
+ }
428
+ const fromMe = message.fromMe === true;
429
+ const participant = this.resolveMessageMutationParticipant(chatIndexJid, fromMe, message.participantJid);
430
+ return {
431
+ chatIndexJid,
432
+ indexPartsTail: [messageId, fromMe ? '1' : '0', participant]
433
+ };
434
+ }
435
+ resolveMessageMutationParticipant(chatIndexJid, fromMe, participantJid) {
436
+ if (fromMe || !isGroupOrBroadcastJid(chatIndexJid)) {
437
+ return '0';
438
+ }
439
+ if (!participantJid) {
440
+ throw new Error('participantJid is required for incoming message mutations in group/broadcast chats');
441
+ }
442
+ const normalized = normalizeRecipientJid(participantJid);
443
+ if (isGroupOrBroadcastJid(normalized)) {
444
+ throw new Error(`invalid participantJid for message mutation: ${participantJid}`);
445
+ }
446
+ return normalizeDeviceJid(normalized);
447
+ }
448
+ buildMutationIndex(action, chatIndexJid, indexPartsTail) {
449
+ return JSON.stringify([action, chatIndexJid, ...indexPartsTail]);
450
+ }
451
+ describeMutationActions(mutations) {
452
+ return mutations
453
+ .map((mutation) => {
454
+ try {
455
+ const parsed = JSON.parse(mutation.index);
456
+ if (Array.isArray(parsed) && typeof parsed[0] === 'string') {
457
+ return `${mutation.collection}:${parsed[0]}`;
458
+ }
459
+ }
460
+ catch (error) {
461
+ void error;
462
+ }
463
+ return `${mutation.collection}:unknown`;
464
+ })
465
+ .join(',');
466
+ }
467
+ }
@@ -1,21 +1,27 @@
1
+ import { parseParticipants as parseGroupEventParticipants } from '../events/group.js';
1
2
  import { WA_DEFAULTS } from '../../protocol/defaults.js';
2
3
  import { WA_GROUP_PARTICIPANT_TYPES } from '../../protocol/group.js';
3
4
  import { WA_NODE_TAGS, WA_XMLNS } from '../../protocol/nodes.js';
4
5
  import { buildCreateGroupIq, buildGroupParticipantChangeIq, buildLeaveGroupIq } from '../../transport/node/builders/group.js';
5
- import { findNodeChild, getNodeChildren, getNodeChildrenByTag, hasNodeChild } from '../../transport/node/helpers.js';
6
+ import { findNodeChild, getNodeChildrenByTagFromChildren, hasNodeChild } from '../../transport/node/helpers.js';
6
7
  import { assertIqResult, buildIqNode } from '../../transport/node/query.js';
7
8
  function parseGroupParticipants(node) {
8
- const participantNodes = getNodeChildrenByTag(node, WA_NODE_TAGS.PARTICIPANT);
9
- return participantNodes.map((p) => {
10
- const type = p.attrs.type ?? WA_GROUP_PARTICIPANT_TYPES.REGULAR;
11
- return {
12
- jid: p.attrs.jid,
9
+ const parsed = parseGroupEventParticipants(node);
10
+ const participants = [];
11
+ for (const participant of parsed) {
12
+ if (!participant.jid) {
13
+ continue;
14
+ }
15
+ const type = participant.role ?? WA_GROUP_PARTICIPANT_TYPES.REGULAR;
16
+ participants.push({
17
+ jid: participant.jid,
13
18
  type,
14
19
  isAdmin: type === WA_GROUP_PARTICIPANT_TYPES.ADMIN ||
15
20
  type === WA_GROUP_PARTICIPANT_TYPES.SUPERADMIN,
16
21
  isSuperAdmin: type === WA_GROUP_PARTICIPANT_TYPES.SUPERADMIN
17
- };
18
- });
22
+ });
23
+ }
24
+ return participants;
19
25
  }
20
26
  function parseGroupMetadata(node) {
21
27
  const groupNode = node.tag === WA_NODE_TAGS.GROUP ? node : findNodeChild(node, WA_NODE_TAGS.GROUP);
@@ -94,8 +100,12 @@ export function createGroupCoordinator(options) {
94
100
  ]);
95
101
  const result = await queryWithContext('group.list', node);
96
102
  assertIqResult(result, 'group.list');
97
- const groupNodes = getNodeChildren(result).flatMap((child) => getNodeChildrenByTag(child, WA_NODE_TAGS.GROUP));
98
- return groupNodes.map(parseGroupMetadata);
103
+ const groupNodes = getNodeChildrenByTagFromChildren(result, WA_NODE_TAGS.GROUP);
104
+ const metadata = [];
105
+ for (const groupNode of groupNodes) {
106
+ metadata.push(parseGroupMetadata(groupNode));
107
+ }
108
+ return metadata;
99
109
  },
100
110
  queryGroupInviteInfo: async (code) => {
101
111
  const node = buildIqNode('get', WA_DEFAULTS.GROUP_SERVER, WA_XMLNS.GROUPS, [
@@ -1,8 +1,8 @@
1
1
  import { createIncomingBaseEvent, createIncomingFailureHandler, createIncomingGroupNotificationHandler, createIncomingNotificationHandler, createIncomingReceiptHandler, createInfoBulletinNotificationEvent, createUnhandledIncomingNodeEvent } from '../incoming.js';
2
2
  import { WA_IQ_TYPES, WA_MESSAGE_TAGS, WA_NODE_TAGS, WA_NOTIFICATION_TYPES, WA_SIGNALING } from '../../protocol/constants.js';
3
3
  import { decodeNodeContentBase64OrBytes, findNodeChild, getNodeChildrenByTag } from '../../transport/node/helpers.js';
4
- import { parseOptionalInt, parseStreamControlNode, parseSuccessPersistAttributes } from '../../transport/stream/parse.js';
5
- import { toError } from '../../util/primitives.js';
4
+ import { parseStreamControlNode, parseSuccessPersistAttributes } from '../../transport/stream/parse.js';
5
+ import { parseOptionalInt, toError } from '../../util/primitives.js';
6
6
  const INFO_BULLETIN_NOTIFICATION_TYPES = new Set([
7
7
  'offline',
8
8
  'offline_preview',
@@ -77,14 +77,20 @@ export class WaIncomingNodeCoordinator {
77
77
  return true;
78
78
  }
79
79
  async dispatchIncomingNode(node) {
80
+ const handlersByTag = this.nodeHandlerRegistry.get(node.tag);
81
+ const nodeSubtype = node.attrs.type;
80
82
  if (node.tag === WA_MESSAGE_TAGS.RECEIPT) {
81
- const handlers = this.getHandlersForNode(node);
82
- for (const handler of handlers) {
83
- if (await handler(node)) {
84
- if (!this.isRetryReceiptType(node.attrs.type)) {
85
- this.runtime.tryResolvePendingNode(node);
83
+ if (handlersByTag && handlersByTag.length > 0) {
84
+ for (const entry of handlersByTag) {
85
+ if (entry.subtype !== undefined && entry.subtype !== nodeSubtype) {
86
+ continue;
87
+ }
88
+ if (await entry.handler(node)) {
89
+ if (!this.isRetryReceiptType(nodeSubtype)) {
90
+ this.runtime.tryResolvePendingNode(node);
91
+ }
92
+ return true;
86
93
  }
87
- return true;
88
94
  }
89
95
  }
90
96
  return this.runtime.tryResolvePendingNode(node);
@@ -96,12 +102,14 @@ export class WaIncomingNodeCoordinator {
96
102
  if (genericHandled) {
97
103
  return true;
98
104
  }
99
- const handlers = this.getHandlersForNode(node);
100
- if (handlers.length === 0) {
105
+ if (!handlersByTag || handlersByTag.length === 0) {
101
106
  return false;
102
107
  }
103
- for (const handler of handlers) {
104
- if (await handler(node)) {
108
+ for (const entry of handlersByTag) {
109
+ if (entry.subtype !== undefined && entry.subtype !== nodeSubtype) {
110
+ continue;
111
+ }
112
+ if (await entry.handler(node)) {
105
113
  return true;
106
114
  }
107
115
  }
@@ -110,21 +118,6 @@ export class WaIncomingNodeCoordinator {
110
118
  isRetryReceiptType(type) {
111
119
  return type === 'retry' || type === 'enc_rekey_retry';
112
120
  }
113
- getHandlersForNode(node) {
114
- const handlersByTag = this.nodeHandlerRegistry.get(node.tag);
115
- if (!handlersByTag || handlersByTag.length === 0) {
116
- return [];
117
- }
118
- const nodeSubtype = node.attrs.type;
119
- const handlers = [];
120
- for (const entry of handlersByTag) {
121
- if (entry.subtype !== undefined && entry.subtype !== nodeSubtype) {
122
- continue;
123
- }
124
- handlers.push(entry.handler);
125
- }
126
- return handlers;
127
- }
128
121
  registerDefaultIncomingHandlers() {
129
122
  const runtime = this.runtime;
130
123
  this.registerIncomingHandler({