zapo-js 0.1.2 → 0.3.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 (630) hide show
  1. package/README.md +16 -4
  2. package/dist/appstate/WaAppStateCrypto.js +50 -42
  3. package/dist/appstate/WaAppStateSyncClient.js +215 -133
  4. package/dist/appstate/{store/sqlite.js → encoding.js} +13 -8
  5. package/dist/appstate/index.js +9 -7
  6. package/dist/appstate/utils.js +0 -5
  7. package/dist/auth/WaAuthClient.js +55 -57
  8. package/dist/auth/credentials-flow.js +195 -0
  9. package/dist/auth/index.js +1 -6
  10. package/dist/auth/pairing/WaPairingFlow.js +39 -32
  11. package/dist/auth/pairing/{WaPairingCodeCrypto.js → pairing-code-crypto.js} +35 -17
  12. package/dist/client/WaClient.js +338 -174
  13. package/dist/client/WaClientFactory.js +399 -66
  14. package/dist/client/connection/WaConnectionManager.js +23 -11
  15. package/dist/client/coordinators/WaAbPropsCoordinator.js +141 -0
  16. package/dist/client/coordinators/WaBusinessCoordinator.js +232 -0
  17. package/dist/client/coordinators/WaEmailCoordinator.js +63 -0
  18. package/dist/client/coordinators/WaGroupCoordinator.js +11 -7
  19. package/dist/client/coordinators/WaIncomingNodeCoordinator.js +34 -8
  20. package/dist/client/coordinators/WaMessageDispatchCoordinator.js +341 -118
  21. package/dist/client/coordinators/WaOfflineResumeCoordinator.js +114 -0
  22. package/dist/client/coordinators/WaPassiveTasksCoordinator.js +97 -36
  23. package/dist/client/coordinators/WaPrivacyCoordinator.js +134 -0
  24. package/dist/client/coordinators/WaProfileCoordinator.js +214 -0
  25. package/dist/client/coordinators/WaRetryCoordinator.js +184 -30
  26. package/dist/client/coordinators/WaStreamControlCoordinator.js +18 -11
  27. package/dist/client/coordinators/WaTrustedContactTokenCoordinator.js +184 -0
  28. package/dist/client/dirty.js +41 -21
  29. package/dist/client/events/abprops.js +43 -0
  30. package/dist/client/events/devices.js +72 -0
  31. package/dist/client/events/group.js +3 -11
  32. package/dist/client/events/identity.js +22 -0
  33. package/dist/client/events/privacy-token.js +38 -0
  34. package/dist/client/events/registration.js +42 -0
  35. package/dist/client/history-sync.js +50 -9
  36. package/dist/client/incoming.js +74 -7
  37. package/dist/client/mailbox.js +40 -23
  38. package/dist/client/media.js +243 -0
  39. package/dist/client/messages.js +245 -92
  40. package/dist/client/messaging/fanout.js +21 -11
  41. package/dist/client/messaging/participants.js +6 -4
  42. package/dist/client/persistence/WriteBehindPersistence.js +129 -0
  43. package/dist/client/tokens/cs-token.js +50 -0
  44. package/dist/client/tokens/tc-token.js +25 -0
  45. package/dist/crypto/core/index.js +5 -2
  46. package/dist/crypto/core/keys.js +4 -4
  47. package/dist/crypto/core/nonce.js +2 -0
  48. package/dist/crypto/core/primitives.js +0 -8
  49. package/dist/crypto/core/random.js +24 -8
  50. package/dist/crypto/core/xeddsa.js +57 -0
  51. package/dist/crypto/curves/X25519.js +43 -6
  52. package/dist/crypto/curves/constants.js +2 -1
  53. package/dist/crypto/index.js +3 -0
  54. package/dist/crypto/math/constants.js +13 -36
  55. package/dist/crypto/math/edwards.js +171 -44
  56. package/dist/crypto/math/fe.js +706 -0
  57. package/dist/crypto/math/mod.js +10 -3
  58. package/dist/esm/appstate/WaAppStateCrypto.js +40 -32
  59. package/dist/esm/appstate/WaAppStateSyncClient.js +206 -124
  60. package/dist/esm/appstate/{store/sqlite.js → encoding.js} +13 -8
  61. package/dist/esm/appstate/index.js +2 -2
  62. package/dist/esm/appstate/{WaAppStateSyncResponseParser.js → response-parser.js} +1 -1
  63. package/dist/esm/appstate/utils.js +2 -5
  64. package/dist/esm/auth/WaAuthClient.js +52 -54
  65. package/dist/esm/auth/credentials-flow.js +190 -0
  66. package/dist/esm/auth/index.js +0 -2
  67. package/dist/esm/auth/pairing/WaPairingFlow.js +39 -32
  68. package/dist/esm/auth/pairing/{WaPairingCodeCrypto.js → pairing-code-crypto.js} +26 -10
  69. package/dist/esm/client/WaClient.js +339 -175
  70. package/dist/esm/client/WaClientFactory.js +401 -68
  71. package/dist/esm/client/connection/WaConnectionManager.js +23 -11
  72. package/dist/esm/client/coordinators/WaAbPropsCoordinator.js +137 -0
  73. package/dist/esm/client/coordinators/WaBusinessCoordinator.js +229 -0
  74. package/dist/esm/client/coordinators/WaEmailCoordinator.js +60 -0
  75. package/dist/esm/client/coordinators/WaGroupCoordinator.js +11 -7
  76. package/dist/esm/client/coordinators/WaIncomingNodeCoordinator.js +36 -10
  77. package/dist/esm/client/coordinators/WaMessageDispatchCoordinator.js +337 -114
  78. package/dist/esm/client/coordinators/WaOfflineResumeCoordinator.js +110 -0
  79. package/dist/esm/client/coordinators/WaPassiveTasksCoordinator.js +97 -36
  80. package/dist/esm/client/coordinators/WaPrivacyCoordinator.js +131 -0
  81. package/dist/esm/client/coordinators/WaProfileCoordinator.js +211 -0
  82. package/dist/esm/client/coordinators/WaRetryCoordinator.js +186 -32
  83. package/dist/esm/client/coordinators/WaStreamControlCoordinator.js +19 -12
  84. package/dist/esm/client/coordinators/WaTrustedContactTokenCoordinator.js +180 -0
  85. package/dist/esm/client/dirty.js +41 -21
  86. package/dist/esm/client/events/abprops.js +40 -0
  87. package/dist/esm/client/events/devices.js +68 -0
  88. package/dist/esm/client/events/group.js +3 -11
  89. package/dist/esm/client/events/identity.js +19 -0
  90. package/dist/esm/client/events/privacy-token.js +35 -0
  91. package/dist/esm/client/events/registration.js +39 -0
  92. package/dist/esm/client/history-sync.js +50 -9
  93. package/dist/esm/client/incoming.js +74 -8
  94. package/dist/esm/client/mailbox.js +40 -23
  95. package/dist/esm/client/media.js +234 -0
  96. package/dist/esm/client/messages.js +244 -91
  97. package/dist/esm/client/messaging/fanout.js +22 -12
  98. package/dist/esm/client/messaging/participants.js +6 -4
  99. package/dist/esm/client/persistence/WriteBehindPersistence.js +125 -0
  100. package/dist/esm/client/tokens/cs-token.js +46 -0
  101. package/dist/esm/client/tokens/tc-token.js +18 -0
  102. package/dist/esm/crypto/core/index.js +3 -2
  103. package/dist/esm/crypto/core/keys.js +1 -1
  104. package/dist/esm/crypto/core/nonce.js +2 -0
  105. package/dist/esm/crypto/core/primitives.js +0 -7
  106. package/dist/esm/crypto/core/random.js +23 -7
  107. package/dist/esm/crypto/core/xeddsa.js +53 -0
  108. package/dist/esm/crypto/curves/X25519.js +45 -8
  109. package/dist/esm/crypto/curves/constants.js +1 -0
  110. package/dist/esm/crypto/index.js +1 -0
  111. package/dist/esm/crypto/math/constants.js +12 -35
  112. package/dist/esm/crypto/math/edwards.js +174 -47
  113. package/dist/esm/crypto/math/fe.js +691 -0
  114. package/dist/esm/crypto/math/mod.js +10 -1
  115. package/dist/esm/index.js +1 -1
  116. package/dist/esm/infra/perf/BackgroundQueue.js +478 -0
  117. package/dist/esm/infra/perf/BoundedTaskQueue.js +3 -1
  118. package/dist/esm/infra/perf/PromiseDedup.js +20 -0
  119. package/dist/esm/infra/perf/SharedExclusiveGate.js +109 -0
  120. package/dist/esm/infra/perf/StoreLock.js +80 -0
  121. package/dist/esm/media/WaMediaCrypto.js +332 -55
  122. package/dist/esm/media/WaMediaTransferClient.js +69 -220
  123. package/dist/esm/media/constants.js +4 -1
  124. package/dist/esm/media/processor.js +1 -0
  125. package/dist/esm/message/WaMessageClient.js +26 -19
  126. package/dist/esm/message/addon-crypto.js +130 -3
  127. package/dist/esm/message/content.js +206 -14
  128. package/dist/esm/message/icdc.js +76 -0
  129. package/dist/esm/message/incoming.js +38 -24
  130. package/dist/esm/message/phash.js +35 -13
  131. package/dist/esm/message/reporting-token.js +17 -30
  132. package/dist/esm/message/use-case-secret.js +1 -1
  133. package/dist/esm/protocol/abprops.js +159 -0
  134. package/dist/esm/protocol/appstate.js +9 -40
  135. package/dist/esm/protocol/browser.js +24 -18
  136. package/dist/esm/protocol/constants.js +8 -4
  137. package/dist/esm/protocol/defaults.js +6 -0
  138. package/dist/esm/protocol/email.js +30 -0
  139. package/dist/esm/protocol/index.js +1 -2
  140. package/dist/esm/protocol/jid.js +142 -39
  141. package/dist/esm/protocol/message.js +61 -1
  142. package/dist/esm/protocol/nodes.js +8 -2
  143. package/dist/esm/protocol/notification.js +9 -1
  144. package/dist/esm/protocol/privacy-token.js +17 -0
  145. package/dist/esm/protocol/privacy.js +55 -0
  146. package/dist/esm/protocol/stream.js +26 -1
  147. package/dist/esm/retry/codec.js +216 -0
  148. package/dist/esm/retry/constants.js +1 -1
  149. package/dist/esm/retry/index.js +2 -2
  150. package/dist/esm/retry/parse.js +50 -30
  151. package/dist/esm/retry/reason.js +1 -1
  152. package/dist/esm/retry/replay.js +11 -7
  153. package/dist/esm/retry/tracker.js +50 -12
  154. package/dist/esm/signal/api/SignalDeviceSyncApi.js +52 -32
  155. package/dist/esm/signal/api/SignalDigestSyncApi.js +21 -15
  156. package/dist/esm/signal/api/SignalIdentitySyncApi.js +30 -15
  157. package/dist/esm/signal/api/SignalMissingPreKeysSyncApi.js +19 -8
  158. package/dist/esm/signal/api/SignalRotateKeyApi.js +4 -2
  159. package/dist/esm/signal/api/SignalSessionSyncApi.js +17 -8
  160. package/dist/esm/signal/api/result-map.js +10 -0
  161. package/dist/esm/signal/constants.js +0 -4
  162. package/dist/esm/signal/crypto/WaAdvSignature.js +5 -45
  163. package/dist/esm/signal/crypto/constants.js +0 -4
  164. package/dist/esm/signal/{store/sqlite.js → encoding.js} +40 -29
  165. package/dist/esm/signal/group/SenderKeyChain.js +3 -3
  166. package/dist/esm/signal/group/SenderKeyCodec.js +8 -8
  167. package/dist/esm/signal/group/SenderKeyManager.js +131 -109
  168. package/dist/esm/signal/index.js +1 -0
  169. package/dist/esm/signal/registration/keygen.js +8 -5
  170. package/dist/esm/signal/registration/utils.js +3 -2
  171. package/dist/esm/signal/session/SignalProtocol.js +158 -81
  172. package/dist/esm/signal/session/SignalRatchet.js +21 -10
  173. package/dist/esm/signal/session/SignalSerializer.js +5 -6
  174. package/dist/esm/signal/session/SignalSession.js +11 -9
  175. package/dist/esm/signal/session/resolver.js +140 -105
  176. package/dist/esm/store/contracts/identity.store.js +1 -0
  177. package/dist/esm/store/contracts/message-secret.store.js +1 -0
  178. package/dist/esm/store/contracts/pre-key.store.js +1 -0
  179. package/dist/esm/store/contracts/privacy-token.store.js +1 -0
  180. package/dist/esm/store/contracts/session.store.js +1 -0
  181. package/dist/esm/store/createStore.js +143 -193
  182. package/dist/esm/store/index.js +5 -10
  183. package/dist/esm/store/locks/appstate.lock.js +26 -0
  184. package/dist/esm/store/locks/auth.lock.js +15 -0
  185. package/dist/esm/store/locks/contact.lock.js +20 -0
  186. package/dist/esm/store/locks/device-list.lock.js +20 -0
  187. package/dist/esm/store/locks/identity.lock.js +16 -0
  188. package/dist/esm/store/locks/message-secret.lock.js +17 -0
  189. package/dist/esm/store/locks/message.lock.js +21 -0
  190. package/dist/esm/store/locks/participants.lock.js +20 -0
  191. package/dist/esm/store/locks/pre-key.lock.js +27 -0
  192. package/dist/esm/store/locks/privacy-token.lock.js +18 -0
  193. package/dist/esm/store/locks/retry.lock.js +29 -0
  194. package/dist/esm/store/locks/sender-key.lock.js +52 -0
  195. package/dist/esm/store/locks/session.lock.js +19 -0
  196. package/dist/esm/store/locks/signal.lock.js +39 -0
  197. package/dist/esm/store/locks/thread.lock.js +21 -0
  198. package/dist/esm/store/noop.store.js +21 -1
  199. package/dist/esm/store/providers/memory/appstate.store.js +22 -24
  200. package/dist/esm/store/providers/memory/device-list.store.js +13 -5
  201. package/dist/esm/store/providers/memory/identity.store.js +31 -0
  202. package/dist/esm/store/providers/memory/message-secret.store.js +81 -0
  203. package/dist/esm/store/providers/memory/participants.store.js +3 -0
  204. package/dist/esm/store/providers/memory/pre-key.store.js +97 -0
  205. package/dist/esm/store/providers/memory/privacy-token.store.js +43 -0
  206. package/dist/esm/store/providers/memory/retry.store.js +99 -10
  207. package/dist/esm/store/providers/memory/sender-key.store.js +6 -1
  208. package/dist/esm/store/providers/memory/session.store.js +45 -0
  209. package/dist/esm/store/providers/memory/signal.store.js +1 -147
  210. package/dist/esm/transport/WaComms.js +7 -4
  211. package/dist/esm/transport/WaWebSocket.js +9 -7
  212. package/dist/esm/transport/binary/constants.js +0 -30
  213. package/dist/esm/transport/binary/decoder.js +4 -4
  214. package/dist/esm/transport/binary/encoder.js +8 -15
  215. package/dist/esm/transport/binary/index.js +0 -1
  216. package/dist/esm/transport/index.js +6 -0
  217. package/dist/esm/transport/keepalive/WaKeepAlive.js +17 -8
  218. package/dist/esm/transport/node/WaMobileTcpSocket.js +114 -0
  219. package/dist/esm/transport/node/WaNodeOrchestrator.js +37 -22
  220. package/dist/esm/transport/node/builders/abprops.js +20 -0
  221. package/dist/esm/transport/node/builders/business.js +129 -0
  222. package/dist/esm/transport/node/builders/device.js +11 -0
  223. package/dist/esm/transport/node/builders/email.js +65 -0
  224. package/dist/esm/transport/node/builders/global.js +370 -0
  225. package/dist/esm/transport/node/builders/message.js +63 -239
  226. package/dist/esm/transport/node/builders/offline.js +14 -0
  227. package/dist/esm/transport/node/builders/pairing.js +0 -24
  228. package/dist/esm/transport/node/builders/prekeys.js +37 -40
  229. package/dist/esm/transport/node/builders/presence.js +13 -0
  230. package/dist/esm/transport/node/builders/privacy-token.js +37 -0
  231. package/dist/esm/transport/node/builders/privacy.js +48 -0
  232. package/dist/esm/transport/node/builders/profile.js +70 -0
  233. package/dist/esm/transport/node/builders/retry.js +11 -23
  234. package/dist/esm/transport/node/builders/usync.js +6 -2
  235. package/dist/esm/transport/node/helpers.js +43 -1
  236. package/dist/esm/transport/node/mex/argo-decoder.js +152 -0
  237. package/dist/esm/transport/node/mex/client.js +83 -0
  238. package/dist/esm/transport/node/mex/persist-ids.js +10 -0
  239. package/dist/esm/transport/node/usync.js +3 -33
  240. package/dist/esm/transport/node/xml.js +35 -14
  241. package/dist/esm/transport/noise/WaClientPayload.js +24 -19
  242. package/dist/esm/transport/noise/WaFrameCodec.js +2 -2
  243. package/dist/esm/transport/noise/WaMobileClientPayload.js +53 -0
  244. package/dist/esm/transport/noise/WaNoiseCert.js +9 -27
  245. package/dist/esm/transport/noise/WaNoiseSession.js +76 -34
  246. package/dist/esm/transport/noise/WaNoiseSocket.js +8 -4
  247. package/dist/esm/transport/stream/parse.js +8 -4
  248. package/dist/esm/util/bytes.js +22 -18
  249. package/dist/esm/util/index.js +5 -0
  250. package/dist/esm/util/primitives.js +3 -2
  251. package/dist/index.js +7 -1
  252. package/dist/infra/perf/BackgroundQueue.js +482 -0
  253. package/dist/infra/perf/BoundedTaskQueue.js +3 -1
  254. package/dist/infra/perf/PromiseDedup.js +24 -0
  255. package/dist/infra/perf/SharedExclusiveGate.js +113 -0
  256. package/dist/infra/perf/StoreLock.js +84 -0
  257. package/dist/media/WaMediaCrypto.js +328 -51
  258. package/dist/media/WaMediaTransferClient.js +72 -253
  259. package/dist/media/constants.js +5 -2
  260. package/dist/media/processor.js +2 -0
  261. package/dist/message/WaMessageClient.js +26 -19
  262. package/dist/message/addon-crypto.js +131 -0
  263. package/dist/message/content.js +211 -14
  264. package/dist/message/icdc.js +81 -0
  265. package/dist/message/incoming.js +38 -24
  266. package/dist/message/phash.js +35 -13
  267. package/dist/message/reporting-token.js +16 -30
  268. package/dist/message/use-case-secret.js +1 -1
  269. package/dist/protocol/abprops.js +163 -0
  270. package/dist/protocol/appstate.js +10 -41
  271. package/dist/protocol/browser.js +25 -18
  272. package/dist/protocol/constants.js +33 -2
  273. package/dist/protocol/defaults.js +6 -0
  274. package/dist/protocol/email.js +33 -0
  275. package/dist/protocol/index.js +8 -5
  276. package/dist/protocol/jid.js +149 -39
  277. package/dist/protocol/message.js +62 -2
  278. package/dist/protocol/nodes.js +8 -2
  279. package/dist/protocol/notification.js +10 -2
  280. package/dist/protocol/privacy-token.js +20 -0
  281. package/dist/protocol/privacy.js +58 -0
  282. package/dist/protocol/stream.js +27 -2
  283. package/dist/retry/codec.js +220 -0
  284. package/dist/retry/constants.js +1 -1
  285. package/dist/retry/index.js +5 -5
  286. package/dist/retry/parse.js +51 -30
  287. package/dist/retry/reason.js +1 -1
  288. package/dist/retry/replay.js +10 -6
  289. package/dist/retry/tracker.js +50 -12
  290. package/dist/signal/api/SignalDeviceSyncApi.js +51 -31
  291. package/dist/signal/api/SignalDigestSyncApi.js +21 -15
  292. package/dist/signal/api/SignalIdentitySyncApi.js +29 -14
  293. package/dist/signal/api/SignalMissingPreKeysSyncApi.js +17 -6
  294. package/dist/signal/api/SignalRotateKeyApi.js +4 -2
  295. package/dist/signal/api/SignalSessionSyncApi.js +16 -7
  296. package/dist/signal/api/result-map.js +13 -0
  297. package/dist/signal/constants.js +1 -5
  298. package/dist/signal/crypto/WaAdvSignature.js +2 -44
  299. package/dist/signal/crypto/constants.js +1 -5
  300. package/dist/signal/{store/sqlite.js → encoding.js} +41 -25
  301. package/dist/signal/group/SenderKeyChain.js +2 -2
  302. package/dist/signal/group/SenderKeyCodec.js +8 -8
  303. package/dist/signal/group/SenderKeyManager.js +130 -108
  304. package/dist/signal/index.js +13 -1
  305. package/dist/signal/registration/keygen.js +7 -4
  306. package/dist/signal/registration/utils.js +3 -2
  307. package/dist/signal/session/SignalProtocol.js +158 -81
  308. package/dist/signal/session/SignalRatchet.js +19 -8
  309. package/dist/signal/session/SignalSerializer.js +5 -6
  310. package/dist/signal/session/SignalSession.js +11 -9
  311. package/dist/signal/session/resolver.js +138 -103
  312. package/dist/store/contracts/identity.store.js +2 -0
  313. package/dist/store/contracts/message-secret.store.js +2 -0
  314. package/dist/store/contracts/pre-key.store.js +2 -0
  315. package/dist/store/contracts/privacy-token.store.js +2 -0
  316. package/dist/store/contracts/session.store.js +2 -0
  317. package/dist/store/createStore.js +142 -192
  318. package/dist/store/index.js +23 -33
  319. package/dist/store/locks/appstate.lock.js +29 -0
  320. package/dist/store/locks/auth.lock.js +18 -0
  321. package/dist/store/locks/contact.lock.js +23 -0
  322. package/dist/store/locks/device-list.lock.js +23 -0
  323. package/dist/store/locks/identity.lock.js +19 -0
  324. package/dist/store/locks/message-secret.lock.js +20 -0
  325. package/dist/store/locks/message.lock.js +24 -0
  326. package/dist/store/locks/participants.lock.js +23 -0
  327. package/dist/store/locks/pre-key.lock.js +30 -0
  328. package/dist/store/locks/privacy-token.lock.js +21 -0
  329. package/dist/store/locks/retry.lock.js +32 -0
  330. package/dist/store/locks/sender-key.lock.js +55 -0
  331. package/dist/store/locks/session.lock.js +22 -0
  332. package/dist/store/locks/signal.lock.js +42 -0
  333. package/dist/store/locks/thread.lock.js +24 -0
  334. package/dist/store/noop.store.js +22 -2
  335. package/dist/store/providers/memory/appstate.store.js +22 -24
  336. package/dist/store/providers/memory/device-list.store.js +13 -5
  337. package/dist/store/providers/memory/identity.store.js +35 -0
  338. package/dist/store/providers/memory/message-secret.store.js +85 -0
  339. package/dist/store/providers/memory/participants.store.js +3 -0
  340. package/dist/store/providers/memory/pre-key.store.js +101 -0
  341. package/dist/store/providers/memory/privacy-token.store.js +47 -0
  342. package/dist/store/providers/memory/retry.store.js +98 -9
  343. package/dist/store/providers/memory/sender-key.store.js +6 -1
  344. package/dist/store/providers/memory/session.store.js +49 -0
  345. package/dist/store/providers/memory/signal.store.js +1 -147
  346. package/dist/transport/WaComms.js +7 -4
  347. package/dist/transport/WaWebSocket.js +9 -7
  348. package/dist/transport/binary/constants.js +1 -31
  349. package/dist/transport/binary/decoder.js +4 -4
  350. package/dist/transport/binary/encoder.js +8 -15
  351. package/dist/transport/binary/index.js +0 -4
  352. package/dist/transport/index.js +17 -1
  353. package/dist/transport/keepalive/WaKeepAlive.js +17 -8
  354. package/dist/transport/node/WaMobileTcpSocket.js +118 -0
  355. package/dist/transport/node/WaNodeOrchestrator.js +36 -21
  356. package/dist/transport/node/builders/abprops.js +23 -0
  357. package/dist/transport/node/builders/business.js +137 -0
  358. package/dist/transport/node/builders/device.js +14 -0
  359. package/dist/transport/node/builders/email.js +72 -0
  360. package/dist/transport/node/builders/global.js +375 -0
  361. package/dist/transport/node/builders/message.js +64 -245
  362. package/dist/transport/node/builders/offline.js +17 -0
  363. package/dist/transport/node/builders/pairing.js +0 -26
  364. package/dist/transport/node/builders/prekeys.js +36 -39
  365. package/dist/transport/node/builders/presence.js +16 -0
  366. package/dist/transport/node/builders/privacy-token.js +42 -0
  367. package/dist/transport/node/builders/privacy.js +55 -0
  368. package/dist/transport/node/builders/profile.js +78 -0
  369. package/dist/transport/node/builders/retry.js +10 -22
  370. package/dist/transport/node/builders/usync.js +6 -2
  371. package/dist/transport/node/helpers.js +46 -1
  372. package/dist/transport/node/mex/argo-decoder.js +189 -0
  373. package/dist/transport/node/mex/client.js +86 -0
  374. package/dist/transport/node/mex/persist-ids.js +13 -0
  375. package/dist/transport/node/usync.js +2 -32
  376. package/dist/transport/node/xml.js +35 -14
  377. package/dist/transport/noise/WaClientPayload.js +26 -21
  378. package/dist/transport/noise/WaFrameCodec.js +1 -1
  379. package/dist/transport/noise/WaMobileClientPayload.js +56 -0
  380. package/dist/transport/noise/WaNoiseCert.js +8 -26
  381. package/dist/transport/noise/WaNoiseSession.js +75 -33
  382. package/dist/transport/noise/WaNoiseSocket.js +8 -4
  383. package/dist/transport/stream/parse.js +7 -3
  384. package/dist/types/appstate/WaAppStateCrypto.d.ts +11 -8
  385. package/dist/types/appstate/WaAppStateSyncClient.d.ts +6 -2
  386. package/dist/types/appstate/encoding.d.ts +7 -0
  387. package/dist/types/appstate/index.d.ts +3 -3
  388. package/dist/types/appstate/{WaAppStateSyncResponseParser.d.ts → response-parser.d.ts} +1 -1
  389. package/dist/types/appstate/types.d.ts +1 -1
  390. package/dist/types/appstate/utils.d.ts +0 -2
  391. package/dist/types/auth/WaAuthClient.d.ts +9 -3
  392. package/dist/types/auth/credentials-flow.d.ts +20 -0
  393. package/dist/types/auth/index.d.ts +0 -2
  394. package/dist/types/auth/pairing/WaPairingFlow.d.ts +3 -2
  395. package/dist/types/auth/pairing/{WaPairingCodeCrypto.d.ts → pairing-code-crypto.d.ts} +6 -1
  396. package/dist/types/auth/types.d.ts +41 -0
  397. package/dist/types/client/WaClient.d.ts +44 -18
  398. package/dist/types/client/WaClientFactory.d.ts +22 -8
  399. package/dist/types/client/connection/WaConnectionManager.d.ts +2 -0
  400. package/dist/types/client/coordinators/WaAbPropsCoordinator.d.ts +26 -0
  401. package/dist/types/client/coordinators/WaBusinessCoordinator.d.ts +57 -0
  402. package/dist/types/client/coordinators/WaEmailCoordinator.d.ts +24 -0
  403. package/dist/types/client/coordinators/WaIncomingNodeCoordinator.d.ts +9 -2
  404. package/dist/types/client/coordinators/WaMessageDispatchCoordinator.d.ts +29 -2
  405. package/dist/types/client/coordinators/WaOfflineResumeCoordinator.d.ts +31 -0
  406. package/dist/types/client/coordinators/WaPassiveTasksCoordinator.d.ts +16 -1
  407. package/dist/types/client/coordinators/WaPrivacyCoordinator.d.ts +26 -0
  408. package/dist/types/client/coordinators/WaProfileCoordinator.d.ts +38 -0
  409. package/dist/types/client/coordinators/WaRetryCoordinator.d.ts +12 -0
  410. package/dist/types/client/coordinators/WaStreamControlCoordinator.d.ts +3 -2
  411. package/dist/types/client/coordinators/WaTrustedContactTokenCoordinator.d.ts +55 -0
  412. package/dist/types/client/dirty.d.ts +3 -1
  413. package/dist/types/client/events/abprops.d.ts +14 -0
  414. package/dist/types/client/events/devices.d.ts +20 -0
  415. package/dist/types/client/events/identity.d.ts +9 -0
  416. package/dist/types/client/events/privacy-token.d.ts +7 -0
  417. package/dist/types/client/events/registration.d.ts +17 -0
  418. package/dist/types/client/history-sync.d.ts +9 -6
  419. package/dist/types/client/incoming.d.ts +9 -2
  420. package/dist/types/client/index.d.ts +1 -1
  421. package/dist/types/client/mailbox.d.ts +5 -5
  422. package/dist/types/client/media.d.ts +31 -0
  423. package/dist/types/client/messages.d.ts +3 -2
  424. package/dist/types/client/persistence/WriteBehindPersistence.d.ts +34 -0
  425. package/dist/types/client/tokens/cs-token.d.ts +10 -0
  426. package/dist/types/client/tokens/tc-token.d.ts +5 -0
  427. package/dist/types/client/types.d.ts +151 -4
  428. package/dist/types/crypto/core/index.d.ts +3 -2
  429. package/dist/types/crypto/core/nonce.d.ts +2 -0
  430. package/dist/types/crypto/core/primitives.d.ts +1 -2
  431. package/dist/types/crypto/core/random.d.ts +2 -1
  432. package/dist/types/crypto/core/xeddsa.d.ts +2 -0
  433. package/dist/types/crypto/curves/constants.d.ts +1 -0
  434. package/dist/types/crypto/index.d.ts +2 -0
  435. package/dist/types/crypto/math/constants.d.ts +4 -2
  436. package/dist/types/crypto/math/fe.d.ts +30 -0
  437. package/dist/types/crypto/math/mod.d.ts +0 -2
  438. package/dist/types/crypto/math/types.d.ts +11 -4
  439. package/dist/types/index.d.ts +6 -3
  440. package/dist/types/infra/log/ConsoleLogger.d.ts +1 -1
  441. package/dist/types/infra/log/PinoLogger.d.ts +1 -1
  442. package/dist/types/infra/perf/BackgroundQueue.d.ts +58 -0
  443. package/dist/types/infra/perf/PromiseDedup.d.ts +4 -0
  444. package/dist/types/infra/perf/SharedExclusiveGate.d.ts +17 -0
  445. package/dist/types/infra/perf/StoreLock.d.ts +11 -0
  446. package/dist/types/media/WaMediaCrypto.d.ts +16 -6
  447. package/dist/types/media/WaMediaTransferClient.d.ts +6 -23
  448. package/dist/types/media/constants.d.ts +3 -1
  449. package/dist/types/media/index.d.ts +2 -1
  450. package/dist/types/media/processor.d.ts +28 -0
  451. package/dist/types/media/types.d.ts +19 -5
  452. package/dist/types/message/addon-crypto.d.ts +34 -3
  453. package/dist/types/message/content.d.ts +11 -1
  454. package/dist/types/message/icdc.d.ts +13 -0
  455. package/dist/types/message/reporting-token.d.ts +0 -1
  456. package/dist/types/message/types.d.ts +42 -11
  457. package/dist/types/protocol/abprops.d.ts +142 -0
  458. package/dist/types/protocol/appstate.d.ts +0 -11
  459. package/dist/types/protocol/browser.d.ts +1 -0
  460. package/dist/types/protocol/constants.d.ts +12 -4
  461. package/dist/types/protocol/defaults.d.ts +6 -0
  462. package/dist/types/protocol/email.d.ts +32 -0
  463. package/dist/types/protocol/index.d.ts +1 -2
  464. package/dist/types/protocol/jid.d.ts +20 -2
  465. package/dist/types/protocol/message.d.ts +60 -0
  466. package/dist/types/protocol/nodes.d.ts +6 -0
  467. package/dist/types/protocol/notification.d.ts +8 -0
  468. package/dist/types/protocol/privacy-token.d.ts +17 -0
  469. package/dist/types/protocol/privacy.d.ts +75 -0
  470. package/dist/types/protocol/stream.d.ts +31 -0
  471. package/dist/types/retry/codec.d.ts +3 -0
  472. package/dist/types/retry/index.d.ts +3 -3
  473. package/dist/types/retry/parse.d.ts +5 -2
  474. package/dist/types/retry/reason.d.ts +1 -1
  475. package/dist/types/retry/tracker.d.ts +1 -0
  476. package/dist/types/retry/types.d.ts +6 -1
  477. package/dist/types/signal/api/SignalDeviceSyncApi.d.ts +2 -1
  478. package/dist/types/signal/api/SignalDigestSyncApi.d.ts +9 -0
  479. package/dist/types/signal/api/SignalIdentitySyncApi.d.ts +5 -3
  480. package/dist/types/signal/api/SignalRotateKeyApi.d.ts +4 -5
  481. package/dist/types/signal/api/SignalSessionSyncApi.d.ts +8 -6
  482. package/dist/types/signal/api/result-map.d.ts +1 -0
  483. package/dist/types/signal/constants.d.ts +0 -3
  484. package/dist/types/signal/crypto/WaAdvSignature.d.ts +0 -2
  485. package/dist/types/signal/crypto/constants.d.ts +0 -1
  486. package/dist/types/signal/{store/sqlite.d.ts → encoding.d.ts} +9 -3
  487. package/dist/types/signal/group/SenderKeyChain.d.ts +1 -1
  488. package/dist/types/signal/group/SenderKeyManager.d.ts +17 -7
  489. package/dist/types/signal/index.d.ts +2 -0
  490. package/dist/types/signal/registration/utils.d.ts +2 -1
  491. package/dist/types/signal/session/SignalProtocol.d.ts +21 -6
  492. package/dist/types/signal/session/SignalSerializer.d.ts +2 -1
  493. package/dist/types/signal/session/resolver.d.ts +11 -4
  494. package/dist/types/signal/types.d.ts +16 -4
  495. package/dist/types/store/contracts/appstate.store.d.ts +1 -1
  496. package/dist/types/store/contracts/identity.store.d.ts +11 -0
  497. package/dist/types/store/contracts/message-secret.store.d.ts +16 -0
  498. package/dist/types/store/contracts/pre-key.store.d.ts +13 -0
  499. package/dist/types/store/contracts/privacy-token.store.d.ts +16 -0
  500. package/dist/types/store/contracts/retry.store.d.ts +7 -0
  501. package/dist/types/store/contracts/session.store.d.ts +14 -0
  502. package/dist/types/store/contracts/signal.store.d.ts +1 -27
  503. package/dist/types/store/createStore.d.ts +1 -1
  504. package/dist/types/store/index.d.ts +12 -12
  505. package/dist/types/store/locks/appstate.lock.d.ts +3 -0
  506. package/dist/types/store/locks/auth.lock.d.ts +3 -0
  507. package/dist/types/store/locks/contact.lock.d.ts +3 -0
  508. package/dist/types/store/locks/device-list.lock.d.ts +2 -0
  509. package/dist/types/store/locks/identity.lock.d.ts +3 -0
  510. package/dist/types/store/locks/message-secret.lock.d.ts +3 -0
  511. package/dist/types/store/locks/message.lock.d.ts +3 -0
  512. package/dist/types/store/locks/participants.lock.d.ts +2 -0
  513. package/dist/types/store/locks/pre-key.lock.d.ts +3 -0
  514. package/dist/types/store/locks/privacy-token.lock.d.ts +2 -0
  515. package/dist/types/store/locks/retry.lock.d.ts +2 -0
  516. package/dist/types/store/locks/sender-key.lock.d.ts +3 -0
  517. package/dist/types/store/locks/session.lock.d.ts +3 -0
  518. package/dist/types/store/locks/signal.lock.d.ts +3 -0
  519. package/dist/types/store/locks/thread.lock.d.ts +3 -0
  520. package/dist/types/store/noop.store.d.ts +4 -0
  521. package/dist/types/store/providers/memory/appstate.store.d.ts +1 -1
  522. package/dist/types/store/providers/memory/identity.store.d.ts +18 -0
  523. package/dist/types/store/providers/memory/message-secret.store.d.ts +21 -0
  524. package/dist/types/store/providers/memory/pre-key.store.d.ts +23 -0
  525. package/dist/types/store/providers/memory/privacy-token.store.d.ts +13 -0
  526. package/dist/types/store/providers/memory/retry.store.d.ts +15 -1
  527. package/dist/types/store/providers/memory/session.store.d.ts +21 -0
  528. package/dist/types/store/providers/memory/signal.store.d.ts +2 -43
  529. package/dist/types/store/providers/memory/thread.store.d.ts +1 -1
  530. package/dist/types/store/types.d.ts +69 -61
  531. package/dist/types/transport/WaWebSocket.d.ts +1 -1
  532. package/dist/types/transport/binary/constants.d.ts +0 -30
  533. package/dist/types/transport/binary/index.d.ts +0 -1
  534. package/dist/types/transport/index.d.ts +8 -1
  535. package/dist/types/transport/keepalive/WaKeepAlive.d.ts +4 -1
  536. package/dist/types/transport/node/WaMobileTcpSocket.d.ts +18 -0
  537. package/dist/types/transport/node/WaNodeOrchestrator.d.ts +9 -6
  538. package/dist/types/transport/node/builders/abprops.d.ts +5 -0
  539. package/dist/types/transport/node/builders/business.d.ts +29 -0
  540. package/dist/types/transport/node/builders/device.d.ts +2 -0
  541. package/dist/types/transport/node/builders/email.d.ts +11 -0
  542. package/dist/types/transport/node/builders/global.d.ts +102 -0
  543. package/dist/types/transport/node/builders/message.d.ts +8 -7
  544. package/dist/types/transport/node/builders/offline.d.ts +2 -0
  545. package/dist/types/transport/node/builders/pairing.d.ts +0 -2
  546. package/dist/types/transport/node/builders/prekeys.d.ts +4 -3
  547. package/dist/types/transport/node/builders/presence.d.ts +6 -0
  548. package/dist/types/transport/node/builders/privacy-token.d.ts +9 -0
  549. package/dist/types/transport/node/builders/privacy.d.ts +7 -0
  550. package/dist/types/transport/node/builders/profile.d.ts +8 -0
  551. package/dist/types/transport/node/builders/retry.d.ts +0 -1
  552. package/dist/types/transport/node/helpers.d.ts +8 -0
  553. package/dist/types/transport/node/mex/argo-decoder.d.ts +11 -0
  554. package/dist/types/transport/node/mex/client.d.ts +18 -0
  555. package/dist/types/transport/node/mex/persist-ids.d.ts +14 -0
  556. package/dist/types/transport/noise/WaMobileClientPayload.d.ts +29 -0
  557. package/dist/types/transport/noise/WaNoiseCert.d.ts +7 -1
  558. package/dist/types/transport/noise/WaNoiseSession.d.ts +4 -2
  559. package/dist/types/transport/noise/WaNoiseSocket.d.ts +4 -2
  560. package/dist/types/transport/types.d.ts +8 -0
  561. package/dist/types/util/bytes.d.ts +1 -1
  562. package/dist/types/util/index.d.ts +5 -0
  563. package/dist/types/util/primitives.d.ts +0 -1
  564. package/dist/util/bytes.js +22 -18
  565. package/dist/util/index.js +23 -0
  566. package/dist/util/primitives.js +2 -2
  567. package/package.json +34 -10
  568. package/proto/index.js +1 -1
  569. package/dist/auth/flow/WaAuthCredentialsFlow.js +0 -130
  570. package/dist/auth/pairing/constants.js +0 -5
  571. package/dist/client/connection/WaKeyShareCoordinator.js +0 -63
  572. package/dist/crypto/core/constants.js +0 -4
  573. package/dist/esm/auth/flow/WaAuthCredentialsFlow.js +0 -125
  574. package/dist/esm/auth/pairing/constants.js +0 -2
  575. package/dist/esm/client/connection/WaKeyShareCoordinator.js +0 -59
  576. package/dist/esm/crypto/core/constants.js +0 -1
  577. package/dist/esm/retry/outbound.js +0 -82
  578. package/dist/esm/store/providers/sqlite/BaseSqliteStore.js +0 -37
  579. package/dist/esm/store/providers/sqlite/appstate.store.js +0 -250
  580. package/dist/esm/store/providers/sqlite/auth.store.js +0 -176
  581. package/dist/esm/store/providers/sqlite/connection.js +0 -245
  582. package/dist/esm/store/providers/sqlite/contact.store.js +0 -74
  583. package/dist/esm/store/providers/sqlite/device-list.store.js +0 -127
  584. package/dist/esm/store/providers/sqlite/message.store.js +0 -132
  585. package/dist/esm/store/providers/sqlite/migrations.js +0 -347
  586. package/dist/esm/store/providers/sqlite/participants.store.js +0 -77
  587. package/dist/esm/store/providers/sqlite/retry.store.js +0 -141
  588. package/dist/esm/store/providers/sqlite/sender-key.store.js +0 -198
  589. package/dist/esm/store/providers/sqlite/signal.store.js +0 -435
  590. package/dist/esm/store/providers/sqlite/table-names.js +0 -107
  591. package/dist/esm/store/providers/sqlite/thread.store.js +0 -85
  592. package/dist/esm/transport/node/builders/index.js +0 -8
  593. package/dist/retry/outbound.js +0 -87
  594. package/dist/store/providers/sqlite/BaseSqliteStore.js +0 -41
  595. package/dist/store/providers/sqlite/appstate.store.js +0 -254
  596. package/dist/store/providers/sqlite/auth.store.js +0 -180
  597. package/dist/store/providers/sqlite/connection.js +0 -281
  598. package/dist/store/providers/sqlite/contact.store.js +0 -78
  599. package/dist/store/providers/sqlite/device-list.store.js +0 -131
  600. package/dist/store/providers/sqlite/message.store.js +0 -136
  601. package/dist/store/providers/sqlite/migrations.js +0 -350
  602. package/dist/store/providers/sqlite/participants.store.js +0 -81
  603. package/dist/store/providers/sqlite/retry.store.js +0 -145
  604. package/dist/store/providers/sqlite/sender-key.store.js +0 -202
  605. package/dist/store/providers/sqlite/signal.store.js +0 -439
  606. package/dist/store/providers/sqlite/table-names.js +0 -113
  607. package/dist/store/providers/sqlite/thread.store.js +0 -89
  608. package/dist/transport/node/builders/index.js +0 -42
  609. package/dist/types/appstate/store/sqlite.d.ts +0 -7
  610. package/dist/types/auth/flow/WaAuthCredentialsFlow.d.ts +0 -14
  611. package/dist/types/auth/pairing/constants.d.ts +0 -2
  612. package/dist/types/client/connection/WaKeyShareCoordinator.d.ts +0 -14
  613. package/dist/types/crypto/core/constants.d.ts +0 -1
  614. package/dist/types/retry/outbound.d.ts +0 -4
  615. package/dist/types/store/providers/sqlite/BaseSqliteStore.d.ts +0 -12
  616. package/dist/types/store/providers/sqlite/appstate.store.d.ts +0 -17
  617. package/dist/types/store/providers/sqlite/auth.store.d.ts +0 -10
  618. package/dist/types/store/providers/sqlite/connection.d.ts +0 -10
  619. package/dist/types/store/providers/sqlite/contact.store.d.ts +0 -12
  620. package/dist/types/store/providers/sqlite/device-list.store.d.ts +0 -15
  621. package/dist/types/store/providers/sqlite/message.store.d.ts +0 -13
  622. package/dist/types/store/providers/sqlite/migrations.d.ts +0 -3
  623. package/dist/types/store/providers/sqlite/participants.store.d.ts +0 -12
  624. package/dist/types/store/providers/sqlite/retry.store.d.ts +0 -15
  625. package/dist/types/store/providers/sqlite/sender-key.store.d.ts +0 -24
  626. package/dist/types/store/providers/sqlite/signal.store.d.ts +0 -53
  627. package/dist/types/store/providers/sqlite/table-names.d.ts +0 -5
  628. package/dist/types/store/providers/sqlite/thread.store.d.ts +0 -13
  629. package/dist/types/transport/node/builders/index.d.ts +0 -8
  630. /package/dist/appstate/{WaAppStateSyncResponseParser.js → response-parser.js} +0 -0
@@ -2,14 +2,15 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.buildMediaMessageContent = buildMediaMessageContent;
4
4
  exports.getMediaConn = getMediaConn;
5
+ const node_fs_1 = require("node:fs");
6
+ const media_1 = require("./media");
5
7
  const conn_1 = require("../media/conn");
6
8
  const constants_1 = require("../media/constants");
7
9
  const WaMediaCrypto_1 = require("../media/WaMediaCrypto");
8
10
  const content_1 = require("../message/content");
9
11
  const constants_2 = require("../protocol/constants");
10
- const media_1 = require("../transport/node/builders/media");
12
+ const media_2 = require("../transport/node/builders/media");
11
13
  const bytes_1 = require("../util/bytes");
12
- const bytes_2 = require("../util/bytes");
13
14
  const primitives_1 = require("../util/primitives");
14
15
  async function buildMediaMessageContent(options, content) {
15
16
  if (typeof content === 'string') {
@@ -30,91 +31,203 @@ async function getMediaConn(options, forceRefresh = false) {
30
31
  if (!forceRefresh && cached && Date.now() + constants_1.MEDIA_CONN_CACHE_GRACE_MS < cached.expiresAtMs) {
31
32
  return cached;
32
33
  }
33
- const response = await options.queryWithContext('media_conn.fetch', (0, media_1.buildMediaConnIq)(), options.iqTimeoutMs ?? constants_2.WA_DEFAULTS.IQ_TIMEOUT_MS);
34
+ const response = await options.queryWithContext('media_conn.fetch', (0, media_2.buildMediaConnIq)(), options.iqTimeoutMs ?? constants_2.WA_DEFAULTS.IQ_TIMEOUT_MS);
34
35
  const mediaConn = (0, conn_1.parseMediaConnResponse)(response, Date.now());
35
36
  options.setMediaConnCache(mediaConn);
36
37
  return mediaConn;
37
38
  }
39
+ function needsSidecar(content) {
40
+ return content.type === 'video' || content.type === 'ptv' || content.type === 'audio';
41
+ }
42
+ function resolveUploadType(content) {
43
+ if (content.type === 'video' && content.gifPlayback)
44
+ return 'gif';
45
+ if (content.type === 'audio' && content.ptt)
46
+ return 'ptt';
47
+ return content.type;
48
+ }
49
+ function resolveMimetype(content) {
50
+ if (content.mimetype)
51
+ return content.mimetype;
52
+ if (content.type === 'sticker')
53
+ return 'image/webp';
54
+ throw new Error(`mimetype is required for ${content.type} messages`);
55
+ }
38
56
  async function buildMediaMessage(options, content) {
39
- const mediaBytes = (0, bytes_2.toBytesView)(content.media);
40
- const uploaded = await uploadMedia(options, content, mediaBytes);
41
- const mediaKeyTimestamp = Math.floor(Date.now() / 1000);
42
- const common = {
43
- url: uploaded.url,
44
- mimetype: content.mimetype,
45
- fileSha256: uploaded.fileSha256,
46
- fileLength: mediaBytes.byteLength,
47
- mediaKey: uploaded.mediaKey,
48
- fileEncSha256: uploaded.fileEncSha256,
49
- directPath: uploaded.directPath,
50
- mediaKeyTimestamp
51
- };
52
- switch (content.type) {
53
- case 'image':
54
- return {
55
- imageMessage: {
56
- ...common,
57
- caption: content.caption,
58
- width: content.width,
59
- height: content.height
60
- }
61
- };
62
- case 'video':
63
- return {
64
- videoMessage: {
65
- ...common,
66
- caption: content.caption,
67
- gifPlayback: content.gifPlayback,
68
- seconds: content.seconds,
69
- width: content.width,
70
- height: content.height,
71
- metadataUrl: uploaded.metadataUrl
72
- }
73
- };
74
- case 'audio':
75
- return {
76
- audioMessage: {
77
- ...common,
78
- seconds: content.seconds,
79
- ptt: content.ptt
80
- }
81
- };
82
- case 'document':
83
- return {
84
- documentMessage: {
85
- ...common,
86
- caption: content.caption,
87
- fileName: content.fileName ?? 'file',
88
- title: content.fileName ?? undefined
89
- }
90
- };
91
- case 'sticker':
92
- return {
93
- stickerMessage: {
94
- ...common,
95
- width: content.width,
96
- height: content.height
57
+ const needsTempFile = (0, media_1.hasMediaProcessingTasks)(options.media, content) ||
58
+ (content.type === 'sticker' && content.firstFrameLength === undefined);
59
+ const resolved = await (0, media_1.resolveMediaInputs)(needsTempFile, content.media);
60
+ try {
61
+ let detectedFirstFrameLength;
62
+ if (content.type === 'sticker' &&
63
+ content.firstFrameLength === undefined &&
64
+ resolved.processorInput) {
65
+ const input = resolved.processorInput;
66
+ const header = typeof input === 'string' ? await (0, media_1.readFileHead)(input, 100) : input.subarray(0, 100);
67
+ detectedFirstFrameLength = (0, media_1.parseWebpAnimation)(header)?.firstFrameLength;
68
+ }
69
+ const firstFrameLength = content.type === 'sticker'
70
+ ? (content.firstFrameLength ?? detectedFirstFrameLength)
71
+ : undefined;
72
+ const uploadPromise = (0, media_1.isReadableStream)(resolved.uploadMedia)
73
+ ? uploadMediaStream(options, content, resolved.uploadMedia, firstFrameLength)
74
+ : uploadMediaBytes(options, content, resolved.uploadMedia, firstFrameLength);
75
+ const processPromise = (0, media_1.runMediaProcessor)(options.media, resolved.processorInput, content, options.logger);
76
+ const [uploadResult, processResult] = await Promise.allSettled([
77
+ uploadPromise,
78
+ processPromise
79
+ ]);
80
+ if (uploadResult.status === 'rejected')
81
+ throw uploadResult.reason;
82
+ if (processResult.status === 'rejected')
83
+ throw processResult.reason;
84
+ const uploaded = uploadResult.value;
85
+ const processed = processResult.value;
86
+ const mediaKeyTimestamp = Math.floor(Date.now() / 1000);
87
+ const uploadedFields = {
88
+ url: uploaded.url,
89
+ fileSha256: uploaded.fileSha256,
90
+ fileLength: uploaded.fileLength,
91
+ mediaKey: uploaded.mediaKey,
92
+ fileEncSha256: uploaded.fileEncSha256,
93
+ directPath: uploaded.directPath,
94
+ mediaKeyTimestamp,
95
+ mimetype: resolveMimetype(content)
96
+ };
97
+ function spread(c) {
98
+ const result = {};
99
+ for (const key in c) {
100
+ if (key !== 'type' &&
101
+ key !== 'media' &&
102
+ key !== 'fileLength' &&
103
+ key !== 'mimetype') {
104
+ result[key] = c[key];
97
105
  }
98
- };
99
- default:
100
- throw new Error(`unsupported media type: ${content.type}`);
106
+ }
107
+ return result;
108
+ }
109
+ switch (content.type) {
110
+ case 'image':
111
+ return {
112
+ imageMessage: {
113
+ ...spread(content),
114
+ ...uploadedFields,
115
+ width: content.width ?? processed.width,
116
+ height: content.height ?? processed.height,
117
+ jpegThumbnail: content.jpegThumbnail ?? processed.jpegThumbnail
118
+ }
119
+ };
120
+ case 'video':
121
+ return {
122
+ videoMessage: {
123
+ ...spread(content),
124
+ ...uploadedFields,
125
+ seconds: content.seconds ?? processed.seconds,
126
+ width: content.width ?? processed.width,
127
+ height: content.height ?? processed.height,
128
+ jpegThumbnail: content.jpegThumbnail ?? processed.jpegThumbnail,
129
+ streamingSidecar: uploaded.streamingSidecar,
130
+ metadataUrl: uploaded.metadataUrl
131
+ }
132
+ };
133
+ case 'ptv':
134
+ return {
135
+ ptvMessage: {
136
+ ...spread(content),
137
+ ...uploadedFields,
138
+ seconds: content.seconds ?? processed.seconds,
139
+ width: content.width ?? processed.width,
140
+ height: content.height ?? processed.height,
141
+ jpegThumbnail: content.jpegThumbnail ?? processed.jpegThumbnail,
142
+ streamingSidecar: uploaded.streamingSidecar
143
+ }
144
+ };
145
+ case 'audio':
146
+ return {
147
+ audioMessage: {
148
+ ...spread(content),
149
+ ...uploadedFields,
150
+ seconds: content.seconds ?? processed.seconds,
151
+ streamingSidecar: uploaded.streamingSidecar,
152
+ waveform: content.waveform ?? processed.waveform
153
+ }
154
+ };
155
+ case 'document':
156
+ return {
157
+ documentMessage: {
158
+ ...spread(content),
159
+ ...uploadedFields,
160
+ fileName: content.fileName ?? 'file',
161
+ title: content.title ?? content.fileName ?? undefined,
162
+ jpegThumbnail: content.jpegThumbnail ?? processed.jpegThumbnail
163
+ }
164
+ };
165
+ case 'sticker':
166
+ return {
167
+ stickerMessage: {
168
+ ...spread(content),
169
+ ...uploadedFields,
170
+ width: content.width ?? processed.width,
171
+ height: content.height ?? processed.height,
172
+ pngThumbnail: content.pngThumbnail ?? processed.pngThumbnail,
173
+ isAnimated: content.isAnimated ??
174
+ processed.isAnimated ??
175
+ firstFrameLength !== undefined,
176
+ firstFrameLength: content.firstFrameLength ?? uploaded.firstFrameLength,
177
+ firstFrameSidecar: content.firstFrameSidecar ?? uploaded.firstFrameSidecar,
178
+ stickerSentTs: content.stickerSentTs ?? Date.now()
179
+ }
180
+ };
181
+ default:
182
+ throw new Error(`unsupported media message type: ${String(content.type)}`);
183
+ }
184
+ }
185
+ finally {
186
+ if (resolved.tempFilePath) {
187
+ await (0, media_1.cleanupTempFile)(resolved.tempFilePath);
188
+ }
189
+ }
190
+ }
191
+ function buildUploadUrl(host, uploadType, auth, fileEncSha256) {
192
+ const hashToken = (0, bytes_1.bytesToBase64UrlSafe)(fileEncSha256);
193
+ const uploadPath = constants_1.MEDIA_UPLOAD_PATHS[uploadType];
194
+ if (!uploadPath) {
195
+ throw new Error(`unknown media upload type: ${String(uploadType)}`);
196
+ }
197
+ return `https://${host}${uploadPath}/${hashToken}?auth=${encodeURIComponent(auth)}&token=${encodeURIComponent(hashToken)}`;
198
+ }
199
+ function parseUploadResponse(body, status) {
200
+ if (status < 200 || status >= 300) {
201
+ throw new Error(`media upload failed with status ${status}`);
202
+ }
203
+ let parsed;
204
+ try {
205
+ parsed = JSON.parse(bytes_1.TEXT_DECODER.decode(body));
206
+ }
207
+ catch (error) {
208
+ throw new Error(`media upload returned invalid json: ${(0, primitives_1.toError)(error).message}`);
101
209
  }
210
+ if (!parsed.url || !parsed.direct_path) {
211
+ throw new Error('media upload response missing url/direct_path');
212
+ }
213
+ return {
214
+ url: parsed.url,
215
+ directPath: parsed.direct_path,
216
+ ...(parsed.metadata_url ? { metadataUrl: parsed.metadata_url } : {})
217
+ };
102
218
  }
103
- async function uploadMedia(options, content, mediaBytes) {
219
+ async function uploadMediaBytes(options, content, mediaBytes, firstFrameLength) {
220
+ const uploadType = resolveUploadType(content);
104
221
  const mediaKey = await WaMediaCrypto_1.WaMediaCrypto.generateMediaKey();
105
- const uploadType = content.type === 'video' && content.gifPlayback
106
- ? 'gif'
107
- : content.type === 'audio' && content.ptt
108
- ? 'ptt'
109
- : content.type;
110
222
  const [encrypted, mediaConn] = await Promise.all([
111
- WaMediaCrypto_1.WaMediaCrypto.encryptBytes(uploadType, mediaKey, mediaBytes),
223
+ WaMediaCrypto_1.WaMediaCrypto.encryptBytes(uploadType, mediaKey, mediaBytes, {
224
+ sidecar: needsSidecar(content),
225
+ firstFrameLength
226
+ }),
112
227
  getMediaConn(options)
113
228
  ]);
114
229
  const selectedHost = mediaConn.hosts.find((host) => !host.isFallback)?.hostname ?? mediaConn.hosts[0].hostname;
115
- const uploadPath = constants_1.MEDIA_UPLOAD_PATHS[uploadType];
116
- const hashToken = (0, bytes_1.bytesToBase64UrlSafe)(encrypted.fileEncSha256);
117
- const uploadUrl = `https://${selectedHost}${uploadPath}/${hashToken}?auth=${encodeURIComponent(mediaConn.auth)}&token=${encodeURIComponent(hashToken)}`;
230
+ const uploadUrl = buildUploadUrl(selectedHost, uploadType, mediaConn.auth, encrypted.fileEncSha256);
118
231
  options.logger.debug('sending media upload request', {
119
232
  mediaType: content.type,
120
233
  uploadType,
@@ -125,28 +238,68 @@ async function uploadMedia(options, content, mediaBytes) {
125
238
  method: 'POST',
126
239
  body: encrypted.ciphertextHmac,
127
240
  contentLength: encrypted.ciphertextHmac.byteLength,
128
- contentType: content.mimetype
241
+ contentType: resolveMimetype(content)
129
242
  });
130
- const uploadBody = await options.mediaTransfer.readResponseBytes(uploadResponse);
131
- if (!uploadResponse.ok) {
132
- throw new Error(`media upload failed with status ${uploadResponse.status}`);
133
- }
134
- let parsedBody;
135
- try {
136
- parsedBody = JSON.parse(bytes_2.TEXT_DECODER.decode(uploadBody));
137
- }
138
- catch (error) {
139
- throw new Error(`media upload returned invalid json: ${(0, primitives_1.toError)(error).message}`);
140
- }
141
- if (!parsedBody.url || !parsedBody.direct_path) {
142
- throw new Error('media upload response missing url/direct_path');
143
- }
243
+ const responseBody = await options.mediaTransfer.readResponseBytes(uploadResponse);
244
+ const parsed = parseUploadResponse(responseBody, uploadResponse.status);
144
245
  return {
145
- url: parsedBody.url,
146
- directPath: parsedBody.direct_path,
246
+ ...parsed,
147
247
  mediaKey,
148
248
  fileSha256: encrypted.fileSha256,
149
249
  fileEncSha256: encrypted.fileEncSha256,
150
- ...(parsedBody.metadata_url ? { metadataUrl: parsedBody.metadata_url } : {})
250
+ fileLength: mediaBytes.byteLength,
251
+ streamingSidecar: encrypted.streamingSidecar,
252
+ firstFrameSidecar: encrypted.firstFrameSidecar,
253
+ firstFrameLength
151
254
  };
152
255
  }
256
+ async function uploadMediaStream(options, content, stream, firstFrameLength) {
257
+ const uploadType = resolveUploadType(content);
258
+ const mediaKey = await WaMediaCrypto_1.WaMediaCrypto.generateMediaKey();
259
+ const encResult = await WaMediaCrypto_1.WaMediaCrypto.encryptToFile(uploadType, mediaKey, stream, {
260
+ sidecar: needsSidecar(content),
261
+ firstFrameLength
262
+ });
263
+ let readStream;
264
+ try {
265
+ const mediaConn = await getMediaConn(options);
266
+ const selectedHost = mediaConn.hosts.find((host) => !host.isFallback)?.hostname ??
267
+ mediaConn.hosts[0].hostname;
268
+ const uploadUrl = buildUploadUrl(selectedHost, uploadType, mediaConn.auth, encResult.fileEncSha256);
269
+ options.logger.debug('sending media stream upload request', {
270
+ mediaType: content.type,
271
+ uploadType,
272
+ host: selectedHost,
273
+ encryptedSize: encResult.fileSize
274
+ });
275
+ readStream = (0, node_fs_1.createReadStream)(encResult.filePath);
276
+ const uploadResponse = await options.mediaTransfer.uploadStream({
277
+ url: uploadUrl,
278
+ method: 'POST',
279
+ body: readStream,
280
+ contentLength: encResult.fileSize,
281
+ contentType: resolveMimetype(content)
282
+ });
283
+ const responseBody = await options.mediaTransfer.readResponseBytes(uploadResponse);
284
+ const parsed = parseUploadResponse(responseBody, uploadResponse.status);
285
+ return {
286
+ ...parsed,
287
+ mediaKey,
288
+ fileSha256: encResult.fileSha256,
289
+ fileEncSha256: encResult.fileEncSha256,
290
+ fileLength: encResult.plaintextLength,
291
+ streamingSidecar: encResult.streamingSidecar,
292
+ firstFrameSidecar: encResult.firstFrameSidecar,
293
+ firstFrameLength
294
+ };
295
+ }
296
+ finally {
297
+ if (readStream && !readStream.closed) {
298
+ await new Promise((resolve) => {
299
+ readStream.once('close', resolve);
300
+ readStream.destroy();
301
+ });
302
+ }
303
+ await WaMediaCrypto_1.WaMediaCrypto.cleanupEncryptedFile(encResult.filePath);
304
+ }
305
+ }
@@ -1,24 +1,23 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.createDeviceFanoutResolver = createDeviceFanoutResolver;
4
+ const PromiseDedup_1 = require("../../infra/perf/PromiseDedup");
4
5
  const jid_1 = require("../../protocol/jid");
5
6
  const primitives_1 = require("../../util/primitives");
6
7
  function createDeviceFanoutResolver(options) {
7
8
  const { signalDeviceSync, getCurrentMeJid, getCurrentMeLid, logger } = options;
8
- const requireCurrentMeJid = (context) => {
9
- const meJid = getCurrentMeJid();
10
- if (meJid) {
11
- return meJid;
12
- }
13
- throw new Error(`${context} requires registered meJid`);
14
- };
9
+ const dedup = new PromiseDedup_1.PromiseDedup();
15
10
  const resolveDirectFanoutDeviceJids = async (recipientJid, selfDeviceJidForRecipient) => {
16
11
  const recipientUserJid = (0, jid_1.toUserJid)(recipientJid);
17
12
  const meUserJid = (0, jid_1.toUserJid)(selfDeviceJidForRecipient);
18
13
  const targets = recipientUserJid === meUserJid ? [recipientUserJid] : [recipientUserJid, meUserJid];
19
14
  try {
20
15
  const synced = await signalDeviceSync.syncDeviceList(targets);
21
- const byUser = new Map(synced.map((entry) => [(0, jid_1.toUserJid)(entry.jid), entry.deviceJids]));
16
+ const byUser = new Map();
17
+ for (let index = 0; index < synced.length; index += 1) {
18
+ const entry = synced[index];
19
+ byUser.set((0, jid_1.toUserJid)(entry.jid), entry.deviceJids);
20
+ }
22
21
  const fanout = new Set();
23
22
  const recipientDevices = byUser.get(recipientUserJid) ?? [];
24
23
  if (recipientDevices.length === 0) {
@@ -48,7 +47,7 @@ function createDeviceFanoutResolver(options) {
48
47
  return [recipientUserJid];
49
48
  }
50
49
  };
51
- const resolveGroupParticipantDeviceJids = async (participantUserJids) => {
50
+ const resolveGroupParticipantDeviceJidsInternal = async (participantUserJids) => {
52
51
  const meDeviceJids = new Set();
53
52
  const meJid = getCurrentMeJid();
54
53
  if (meJid) {
@@ -74,7 +73,11 @@ function createDeviceFanoutResolver(options) {
74
73
  });
75
74
  }
76
75
  }
77
- const candidateUsers = [...new Set(participantUserJids)];
76
+ const candidateUserSet = new Set();
77
+ for (let index = 0; index < participantUserJids.length; index += 1) {
78
+ candidateUserSet.add(participantUserJids[index]);
79
+ }
80
+ const candidateUsers = Array.from(candidateUserSet);
78
81
  if (candidateUsers.length === 0) {
79
82
  return [];
80
83
  }
@@ -92,6 +95,9 @@ function createDeviceFanoutResolver(options) {
92
95
  }
93
96
  for (const deviceJid of entry.deviceJids) {
94
97
  const normalizedDeviceJid = (0, jid_1.normalizeDeviceJid)(deviceJid);
98
+ if ((0, jid_1.isHostedDeviceJid)(normalizedDeviceJid)) {
99
+ continue;
100
+ }
95
101
  if (meDeviceJids.has(normalizedDeviceJid)) {
96
102
  continue;
97
103
  }
@@ -125,7 +131,10 @@ function createDeviceFanoutResolver(options) {
125
131
  }
126
132
  };
127
133
  const resolveOwnPeerDeviceJids = async () => {
128
- const meJid = requireCurrentMeJid('resolveOwnPeerDeviceJids');
134
+ const meJid = getCurrentMeJid();
135
+ if (!meJid) {
136
+ throw new Error('resolveOwnPeerDeviceJids requires registered meJid');
137
+ }
129
138
  const meUserJid = (0, jid_1.toUserJid)(meJid);
130
139
  const meDevices = new Set();
131
140
  meDevices.add((0, jid_1.normalizeDeviceJid)(meJid));
@@ -180,6 +189,7 @@ function createDeviceFanoutResolver(options) {
180
189
  }
181
190
  return meLid;
182
191
  };
192
+ const resolveGroupParticipantDeviceJids = (participantUserJids) => dedup.run(`group:${participantUserJids.join(',')}`, () => resolveGroupParticipantDeviceJidsInternal(participantUserJids));
183
193
  return {
184
194
  resolveDirectFanoutDeviceJids,
185
195
  resolveGroupParticipantDeviceJids,
@@ -1,10 +1,12 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.createGroupParticipantsCache = createGroupParticipantsCache;
4
+ const PromiseDedup_1 = require("../../infra/perf/PromiseDedup");
4
5
  const jid_1 = require("../../protocol/jid");
5
6
  const primitives_1 = require("../../util/primitives");
6
7
  function createGroupParticipantsCache(options) {
7
8
  const { participantsStore, queryGroupParticipantJids, logger } = options;
9
+ const dedup = new PromiseDedup_1.PromiseDedup();
8
10
  const sanitizeParticipantUsers = (participants) => {
9
11
  const deduped = new Set();
10
12
  for (const participant of participants) {
@@ -120,7 +122,7 @@ function createGroupParticipantsCache(options) {
120
122
  }
121
123
  return sanitizeParticipantUsers(candidates);
122
124
  };
123
- const refreshParticipantUsers = async (groupJid) => {
125
+ const refreshParticipantUsers = (groupJid) => dedup.run(`refresh:${groupJid}`, async () => {
124
126
  const queried = await queryGroupParticipantJids(groupJid);
125
127
  const participants = sanitizeParticipantUsers(queried);
126
128
  await participantsStore.upsertGroupParticipants({
@@ -129,14 +131,14 @@ function createGroupParticipantsCache(options) {
129
131
  updatedAtMs: Date.now()
130
132
  });
131
133
  return participants;
132
- };
133
- const resolveParticipantUsers = async (groupJid) => {
134
+ });
135
+ const resolveParticipantUsers = (groupJid) => dedup.run(`resolve:${groupJid}`, async () => {
134
136
  const cached = await participantsStore.getGroupParticipants(groupJid);
135
137
  if (cached && cached.participants.length > 0) {
136
138
  return sanitizeParticipantUsers(cached.participants);
137
139
  }
138
140
  return refreshParticipantUsers(groupJid);
139
- };
141
+ });
140
142
  const mutateFromGroupEvent = async (event) => {
141
143
  const groupJid = resolveGroupJidForParticipantCacheEvent(event);
142
144
  if (!groupJid) {
@@ -0,0 +1,129 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.WriteBehindPersistence = void 0;
4
+ const BackgroundQueue_1 = require("../../infra/perf/BackgroundQueue");
5
+ const primitives_1 = require("../../util/primitives");
6
+ function mergeThread(previous, incoming) {
7
+ return {
8
+ jid: incoming.jid,
9
+ name: incoming.name ?? previous.name,
10
+ unreadCount: incoming.unreadCount ?? previous.unreadCount,
11
+ archived: incoming.archived ?? previous.archived,
12
+ pinned: incoming.pinned ?? previous.pinned,
13
+ muteEndMs: incoming.muteEndMs ?? previous.muteEndMs,
14
+ markedAsUnread: incoming.markedAsUnread ?? previous.markedAsUnread,
15
+ ephemeralExpiration: incoming.ephemeralExpiration ?? previous.ephemeralExpiration
16
+ };
17
+ }
18
+ function mergeContact(previous, incoming) {
19
+ return {
20
+ jid: incoming.jid,
21
+ displayName: incoming.displayName ?? previous.displayName,
22
+ pushName: incoming.pushName ?? previous.pushName,
23
+ lid: incoming.lid ?? previous.lid,
24
+ phoneNumber: incoming.phoneNumber ?? previous.phoneNumber,
25
+ lastUpdatedMs: Math.max(previous.lastUpdatedMs, incoming.lastUpdatedMs)
26
+ };
27
+ }
28
+ class WriteBehindPersistence {
29
+ constructor(stores, logger, options = {}) {
30
+ this.logger = logger;
31
+ this.flushTimeoutMs = options.flushTimeoutMs ?? 5000;
32
+ const queueOptions = (domain) => ({
33
+ maxPendingKeys: options.maxPendingKeys ?? 4096,
34
+ maxWriteConcurrency: options.maxWriteConcurrency ?? 4,
35
+ flushTimeoutMs: this.flushTimeoutMs,
36
+ onError: (key, error, attempt) => {
37
+ this.logger.warn('write-behind error', {
38
+ domain,
39
+ key,
40
+ attempt,
41
+ message: (0, primitives_1.toError)(error).message
42
+ });
43
+ },
44
+ onPressure: (pendingKeys) => {
45
+ this.logger.warn('write-behind pressure', {
46
+ domain,
47
+ pendingKeys
48
+ });
49
+ },
50
+ onDiscard: (key) => {
51
+ this.logger.warn('write-behind discarded pending write', {
52
+ domain,
53
+ key
54
+ });
55
+ }
56
+ });
57
+ this.queues = {
58
+ messages: new BackgroundQueue_1.BackgroundQueue((_key, value) => stores.messageStore.upsert(value), queueOptions('messages')),
59
+ threads: new BackgroundQueue_1.BackgroundQueue((_key, value) => stores.threadStore.upsert(value), {
60
+ ...queueOptions('threads'),
61
+ coalesce: (previous, incoming) => mergeThread(previous, incoming)
62
+ }),
63
+ contacts: new BackgroundQueue_1.BackgroundQueue((_key, value) => stores.contactStore.upsert(value), {
64
+ ...queueOptions('contacts'),
65
+ coalesce: (previous, incoming) => mergeContact(previous, incoming)
66
+ })
67
+ };
68
+ }
69
+ persistMessage(record) {
70
+ this.queues.messages.enqueue(`msg:${record.id}`, record);
71
+ }
72
+ persistMessageAsync(record) {
73
+ return this.queues.messages.enqueueAsync(`msg:${record.id}`, record);
74
+ }
75
+ persistThread(record) {
76
+ this.queues.threads.enqueue(`thread:${record.jid}`, record);
77
+ }
78
+ persistThreadAsync(record) {
79
+ return this.queues.threads.enqueueAsync(`thread:${record.jid}`, record);
80
+ }
81
+ persistContact(record) {
82
+ this.queues.contacts.enqueue(`contact:${record.jid}`, record);
83
+ }
84
+ persistContactAsync(record) {
85
+ return this.queues.contacts.enqueueAsync(`contact:${record.jid}`, record);
86
+ }
87
+ async flush(timeoutMs = this.flushTimeoutMs) {
88
+ const [messages, threads, contacts] = await Promise.all([
89
+ this.queues.messages.flush(timeoutMs),
90
+ this.queues.threads.flush(timeoutMs),
91
+ this.queues.contacts.flush(timeoutMs)
92
+ ]);
93
+ const result = this.toDrainResult(messages, threads, contacts);
94
+ if (result.remaining > 0) {
95
+ this.logger.warn('write-behind flush finished with pending writes', {
96
+ messagesRemaining: messages.remaining,
97
+ threadsRemaining: threads.remaining,
98
+ contactsRemaining: contacts.remaining
99
+ });
100
+ }
101
+ return result;
102
+ }
103
+ async destroy(timeoutMs = this.flushTimeoutMs) {
104
+ const [messages, threads, contacts] = await Promise.all([
105
+ this.queues.messages.destroy(timeoutMs),
106
+ this.queues.threads.destroy(timeoutMs),
107
+ this.queues.contacts.destroy(timeoutMs)
108
+ ]);
109
+ const result = this.toDrainResult(messages, threads, contacts);
110
+ if (result.remaining > 0) {
111
+ this.logger.warn('write-behind destroy finished with pending writes', {
112
+ messagesRemaining: messages.remaining,
113
+ threadsRemaining: threads.remaining,
114
+ contactsRemaining: contacts.remaining
115
+ });
116
+ }
117
+ return result;
118
+ }
119
+ toDrainResult(messages, threads, contacts) {
120
+ return {
121
+ messages,
122
+ threads,
123
+ contacts,
124
+ flushed: messages.flushed + threads.flushed + contacts.flushed,
125
+ remaining: messages.remaining + threads.remaining + contacts.remaining
126
+ };
127
+ }
128
+ }
129
+ exports.WriteBehindPersistence = WriteBehindPersistence;