zapo-js 0.1.1 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (589) hide show
  1. package/README.md +20 -4
  2. package/dist/appstate/WaAppStateCrypto.js +19 -26
  3. package/dist/appstate/WaAppStateSyncClient.js +293 -181
  4. package/dist/appstate/WaAppStateSyncResponseParser.js +16 -5
  5. package/dist/appstate/constants.js +4 -3
  6. package/dist/appstate/{store/sqlite.js → encoding.js} +13 -8
  7. package/dist/appstate/index.js +8 -6
  8. package/dist/appstate/utils.js +9 -34
  9. package/dist/auth/WaAuthClient.js +43 -61
  10. package/dist/auth/flow/WaAuthCredentialsFlow.js +22 -15
  11. package/dist/auth/index.js +1 -8
  12. package/dist/auth/pairing/WaPairingCodeCrypto.js +6 -4
  13. package/dist/auth/pairing/WaPairingFlow.js +34 -26
  14. package/dist/auth/pairing/WaQrFlow.js +37 -24
  15. package/dist/client/WaClient.js +275 -324
  16. package/dist/client/WaClientFactory.js +500 -133
  17. package/dist/client/connection/WaConnectionManager.js +301 -0
  18. package/dist/client/connection/WaKeyShareCoordinator.js +63 -0
  19. package/dist/client/connection/WaReceiptQueue.js +51 -0
  20. package/dist/client/coordinators/WaAppStateMutationCoordinator.js +471 -0
  21. package/dist/client/coordinators/WaBusinessCoordinator.js +241 -0
  22. package/dist/client/coordinators/WaGroupCoordinator.js +30 -16
  23. package/dist/client/coordinators/WaIncomingNodeCoordinator.js +21 -27
  24. package/dist/client/coordinators/WaMessageDispatchCoordinator.js +439 -701
  25. package/dist/client/coordinators/WaPassiveTasksCoordinator.js +74 -31
  26. package/dist/client/coordinators/WaPrivacyCoordinator.js +134 -0
  27. package/dist/client/coordinators/WaProfileCoordinator.js +212 -0
  28. package/dist/client/coordinators/WaRetryCoordinator.js +242 -57
  29. package/dist/client/coordinators/WaStreamControlCoordinator.js +18 -11
  30. package/dist/client/coordinators/WaTrustedContactTokenCoordinator.js +166 -0
  31. package/dist/client/dirty.js +74 -48
  32. package/dist/client/events/chat.js +4 -3
  33. package/dist/client/events/devices.js +72 -0
  34. package/dist/client/events/group.js +62 -47
  35. package/dist/client/events/identity.js +22 -0
  36. package/dist/client/events/privacy-token.js +39 -0
  37. package/dist/client/history-sync.js +94 -63
  38. package/dist/client/incoming.js +60 -27
  39. package/dist/client/mailbox.js +24 -23
  40. package/dist/client/messages.js +107 -31
  41. package/dist/client/messaging/fanout.js +199 -0
  42. package/dist/client/messaging/key-protocol.js +130 -0
  43. package/dist/client/messaging/participants.js +193 -0
  44. package/dist/client/persistence/WriteBehindPersistence.js +129 -0
  45. package/dist/client/tokens/cs-token.js +50 -0
  46. package/dist/client/tokens/tc-token.js +25 -0
  47. package/dist/crypto/core/hkdf.js +3 -8
  48. package/dist/crypto/core/index.js +2 -5
  49. package/dist/crypto/core/keys.js +6 -7
  50. package/dist/crypto/core/nonce.js +2 -0
  51. package/dist/crypto/core/primitives.js +12 -23
  52. package/dist/crypto/core/random.js +26 -23
  53. package/dist/crypto/curves/Ed25519.js +7 -8
  54. package/dist/crypto/curves/X25519.js +38 -22
  55. package/dist/crypto/index.js +1 -3
  56. package/dist/crypto/math/constants.js +13 -36
  57. package/dist/crypto/math/edwards.js +171 -44
  58. package/dist/crypto/math/fe.js +706 -0
  59. package/dist/crypto/math/mod.js +10 -3
  60. package/dist/esm/appstate/WaAppStateCrypto.js +7 -14
  61. package/dist/esm/appstate/WaAppStateSyncClient.js +284 -172
  62. package/dist/esm/appstate/WaAppStateSyncResponseParser.js +17 -6
  63. package/dist/esm/appstate/constants.js +3 -2
  64. package/dist/esm/appstate/{store/sqlite.js → encoding.js} +13 -8
  65. package/dist/esm/appstate/index.js +2 -2
  66. package/dist/esm/appstate/utils.js +8 -30
  67. package/dist/esm/auth/WaAuthClient.js +43 -61
  68. package/dist/esm/auth/flow/WaAuthCredentialsFlow.js +22 -15
  69. package/dist/esm/auth/index.js +0 -3
  70. package/dist/esm/auth/pairing/WaPairingCodeCrypto.js +6 -4
  71. package/dist/esm/auth/pairing/WaPairingFlow.js +28 -20
  72. package/dist/esm/auth/pairing/WaQrFlow.js +37 -24
  73. package/dist/esm/client/WaClient.js +275 -324
  74. package/dist/esm/client/WaClientFactory.js +501 -134
  75. package/dist/esm/client/connection/WaConnectionManager.js +297 -0
  76. package/dist/esm/client/connection/WaKeyShareCoordinator.js +59 -0
  77. package/dist/esm/client/connection/WaReceiptQueue.js +47 -0
  78. package/dist/esm/client/coordinators/WaAppStateMutationCoordinator.js +467 -0
  79. package/dist/esm/client/coordinators/WaBusinessCoordinator.js +238 -0
  80. package/dist/esm/client/coordinators/WaGroupCoordinator.js +23 -9
  81. package/dist/esm/client/coordinators/WaIncomingNodeCoordinator.js +21 -27
  82. package/dist/esm/client/coordinators/WaMessageDispatchCoordinator.js +443 -705
  83. package/dist/esm/client/coordinators/WaPassiveTasksCoordinator.js +74 -31
  84. package/dist/esm/client/coordinators/WaPrivacyCoordinator.js +131 -0
  85. package/dist/esm/client/coordinators/WaProfileCoordinator.js +209 -0
  86. package/dist/esm/client/coordinators/WaRetryCoordinator.js +244 -59
  87. package/dist/esm/client/coordinators/WaStreamControlCoordinator.js +19 -12
  88. package/dist/esm/client/coordinators/WaTrustedContactTokenCoordinator.js +162 -0
  89. package/dist/esm/client/dirty.js +69 -43
  90. package/dist/esm/client/events/chat.js +4 -3
  91. package/dist/esm/client/events/devices.js +68 -0
  92. package/dist/esm/client/events/group.js +53 -39
  93. package/dist/esm/client/events/identity.js +19 -0
  94. package/dist/esm/client/events/privacy-token.js +36 -0
  95. package/dist/esm/client/history-sync.js +91 -60
  96. package/dist/esm/client/incoming.js +61 -28
  97. package/dist/esm/client/mailbox.js +24 -23
  98. package/dist/esm/client/messages.js +108 -32
  99. package/dist/esm/client/messaging/fanout.js +196 -0
  100. package/dist/esm/client/messaging/key-protocol.js +127 -0
  101. package/dist/esm/client/messaging/participants.js +190 -0
  102. package/dist/esm/client/persistence/WriteBehindPersistence.js +125 -0
  103. package/dist/esm/client/tokens/cs-token.js +46 -0
  104. package/dist/esm/client/tokens/tc-token.js +18 -0
  105. package/dist/esm/crypto/core/hkdf.js +3 -8
  106. package/dist/esm/crypto/core/index.js +2 -3
  107. package/dist/esm/crypto/core/keys.js +3 -4
  108. package/dist/esm/crypto/core/nonce.js +2 -0
  109. package/dist/esm/crypto/core/primitives.js +12 -22
  110. package/dist/esm/crypto/core/random.js +25 -23
  111. package/dist/esm/crypto/curves/Ed25519.js +4 -5
  112. package/dist/esm/crypto/curves/X25519.js +35 -19
  113. package/dist/esm/crypto/index.js +0 -1
  114. package/dist/esm/crypto/math/constants.js +12 -35
  115. package/dist/esm/crypto/math/edwards.js +174 -47
  116. package/dist/esm/crypto/math/fe.js +691 -0
  117. package/dist/esm/crypto/math/mod.js +10 -1
  118. package/dist/esm/index.js +1 -1
  119. package/dist/esm/infra/log/ConsoleLogger.js +18 -17
  120. package/dist/esm/infra/log/PinoLogger.js +15 -9
  121. package/dist/esm/infra/log/types.js +11 -1
  122. package/dist/esm/infra/perf/BackgroundQueue.js +478 -0
  123. package/dist/esm/infra/perf/BoundedTaskQueue.js +16 -18
  124. package/dist/esm/infra/perf/PromiseDedup.js +20 -0
  125. package/dist/esm/infra/perf/SharedExclusiveGate.js +109 -0
  126. package/dist/esm/infra/perf/StoreLock.js +77 -0
  127. package/dist/esm/media/WaMediaCrypto.js +96 -16
  128. package/dist/esm/media/WaMediaTransferClient.js +251 -91
  129. package/dist/esm/media/conn.js +10 -6
  130. package/dist/esm/media/constants.js +6 -2
  131. package/dist/esm/message/WaMessageClient.js +30 -32
  132. package/dist/esm/message/ack.js +6 -6
  133. package/dist/esm/message/addon-crypto.js +59 -0
  134. package/dist/esm/message/content.js +195 -9
  135. package/dist/esm/message/icdc.js +76 -0
  136. package/dist/esm/message/incoming.js +129 -122
  137. package/dist/esm/message/index.js +2 -0
  138. package/dist/esm/message/phash.js +3 -1
  139. package/dist/esm/message/reporting-token.js +425 -0
  140. package/dist/esm/message/use-case-secret.js +49 -0
  141. package/dist/esm/protocol/appstate.js +27 -0
  142. package/dist/esm/protocol/browser.js +10 -18
  143. package/dist/esm/protocol/constants.js +6 -3
  144. package/dist/esm/protocol/defaults.js +6 -0
  145. package/dist/esm/protocol/index.js +2 -11
  146. package/dist/esm/protocol/jid.js +133 -52
  147. package/dist/esm/protocol/media.js +3 -3
  148. package/dist/esm/protocol/message.js +61 -1
  149. package/dist/esm/protocol/nodes.js +4 -0
  150. package/dist/esm/protocol/notification.js +3 -1
  151. package/dist/esm/protocol/privacy-token.js +17 -0
  152. package/dist/esm/protocol/privacy.js +55 -0
  153. package/dist/esm/protocol/stream.js +26 -1
  154. package/dist/esm/protocol/usync.js +11 -0
  155. package/dist/esm/retry/codec.js +216 -0
  156. package/dist/esm/retry/constants.js +1 -1
  157. package/dist/esm/retry/index.js +3 -2
  158. package/dist/esm/retry/parse.js +88 -86
  159. package/dist/esm/retry/replay.js +54 -51
  160. package/dist/esm/retry/tracker.js +94 -0
  161. package/dist/esm/signal/api/SignalDeviceSyncApi.js +276 -92
  162. package/dist/esm/signal/api/SignalDigestSyncApi.js +17 -8
  163. package/dist/esm/signal/api/SignalIdentitySyncApi.js +67 -37
  164. package/dist/esm/signal/api/SignalMissingPreKeysSyncApi.js +86 -67
  165. package/dist/esm/signal/api/SignalRotateKeyApi.js +4 -2
  166. package/dist/esm/signal/api/SignalSessionSyncApi.js +36 -34
  167. package/dist/esm/signal/api/result-map.js +10 -0
  168. package/dist/esm/signal/constants.js +0 -4
  169. package/dist/esm/signal/crypto/WaAdvSignature.js +13 -9
  170. package/dist/esm/signal/{store/sqlite.js → encoding.js} +93 -60
  171. package/dist/esm/signal/group/SenderKeyChain.js +28 -23
  172. package/dist/esm/signal/group/SenderKeyCodec.js +5 -6
  173. package/dist/esm/signal/group/SenderKeyManager.js +144 -115
  174. package/dist/esm/signal/index.js +2 -0
  175. package/dist/esm/signal/registration/keygen.js +6 -2
  176. package/dist/esm/signal/registration/utils.js +1 -0
  177. package/dist/esm/signal/session/SignalProtocol.js +164 -53
  178. package/dist/esm/signal/session/SignalRatchet.js +24 -15
  179. package/dist/esm/signal/session/SignalSession.js +14 -9
  180. package/dist/esm/signal/session/resolver.js +221 -0
  181. package/dist/esm/store/contracts/privacy-token.store.js +1 -0
  182. package/dist/esm/store/createStore.js +100 -188
  183. package/dist/esm/store/index.js +1 -10
  184. package/dist/esm/store/locks/appstate.lock.js +26 -0
  185. package/dist/esm/store/locks/auth.lock.js +15 -0
  186. package/dist/esm/store/locks/contact.lock.js +20 -0
  187. package/dist/esm/store/locks/device-list.lock.js +20 -0
  188. package/dist/esm/store/locks/message.lock.js +21 -0
  189. package/dist/esm/store/locks/participants.lock.js +20 -0
  190. package/dist/esm/store/locks/privacy-token.lock.js +18 -0
  191. package/dist/esm/store/locks/retry.lock.js +29 -0
  192. package/dist/esm/store/locks/sender-key.lock.js +52 -0
  193. package/dist/esm/store/locks/signal.lock.js +63 -0
  194. package/dist/esm/store/locks/thread.lock.js +21 -0
  195. package/dist/esm/store/noop.store.js +4 -7
  196. package/dist/esm/store/providers/memory/appstate.store.js +38 -16
  197. package/dist/esm/store/providers/memory/contact.store.js +5 -0
  198. package/dist/esm/store/providers/memory/device-list.store.js +12 -34
  199. package/dist/esm/store/providers/memory/message.store.js +11 -5
  200. package/dist/esm/store/providers/memory/participants.store.js +1 -8
  201. package/dist/esm/store/providers/memory/privacy-token.store.js +43 -0
  202. package/dist/esm/store/providers/memory/retry.store.js +77 -2
  203. package/dist/esm/store/providers/memory/sender-key.store.js +11 -8
  204. package/dist/esm/store/providers/memory/signal.store.js +47 -18
  205. package/dist/esm/store/providers/memory/thread.store.js +5 -0
  206. package/dist/esm/transport/WaComms.js +28 -24
  207. package/dist/esm/transport/WaWebSocket.js +115 -18
  208. package/dist/esm/transport/binary/constants.js +0 -30
  209. package/dist/esm/transport/binary/decoder.js +8 -8
  210. package/dist/esm/transport/binary/encoder.js +10 -9
  211. package/dist/esm/transport/binary/index.js +0 -1
  212. package/dist/esm/transport/index.js +1 -0
  213. package/dist/esm/transport/keepalive/WaKeepAlive.js +2 -8
  214. package/dist/esm/transport/node/WaNodeOrchestrator.js +25 -21
  215. package/dist/esm/transport/node/WaNodeTransport.js +0 -3
  216. package/dist/esm/transport/node/builders/{accountSync.js → account-sync.js} +16 -36
  217. package/dist/esm/transport/node/builders/business.js +129 -0
  218. package/dist/esm/transport/node/builders/global.js +370 -0
  219. package/dist/esm/transport/node/builders/index.js +7 -3
  220. package/dist/esm/transport/node/builders/message.js +63 -230
  221. package/dist/esm/transport/node/builders/pairing.js +2 -27
  222. package/dist/esm/transport/node/builders/privacy-token.js +41 -0
  223. package/dist/esm/transport/node/builders/privacy.js +48 -0
  224. package/dist/esm/transport/node/builders/profile.js +70 -0
  225. package/dist/esm/transport/node/builders/retry.js +10 -22
  226. package/dist/esm/transport/node/builders/usync.js +45 -0
  227. package/dist/esm/transport/node/helpers.js +125 -5
  228. package/dist/esm/transport/node/usync.js +5 -0
  229. package/dist/esm/transport/node/xml.js +35 -14
  230. package/dist/esm/transport/noise/WaClientPayload.js +10 -10
  231. package/dist/esm/transport/noise/WaFrameCodec.js +48 -33
  232. package/dist/esm/transport/noise/WaNoiseCert.js +4 -7
  233. package/dist/esm/transport/noise/WaNoiseSession.js +77 -29
  234. package/dist/esm/transport/noise/WaNoiseSocket.js +8 -4
  235. package/dist/esm/transport/proxy.js +27 -0
  236. package/dist/esm/transport/stream/parse.js +17 -48
  237. package/dist/esm/util/bytes.js +67 -45
  238. package/dist/esm/util/coercion.js +6 -14
  239. package/dist/esm/util/index.js +5 -0
  240. package/dist/esm/util/primitives.js +40 -14
  241. package/dist/index.js +7 -1
  242. package/dist/infra/log/ConsoleLogger.js +18 -17
  243. package/dist/infra/log/PinoLogger.js +15 -9
  244. package/dist/infra/log/types.js +12 -0
  245. package/dist/infra/perf/BackgroundQueue.js +482 -0
  246. package/dist/infra/perf/BoundedTaskQueue.js +16 -18
  247. package/dist/infra/perf/PromiseDedup.js +24 -0
  248. package/dist/infra/perf/SharedExclusiveGate.js +113 -0
  249. package/dist/infra/perf/StoreLock.js +81 -0
  250. package/dist/media/WaMediaCrypto.js +95 -15
  251. package/dist/media/WaMediaTransferClient.js +284 -91
  252. package/dist/media/conn.js +10 -6
  253. package/dist/media/constants.js +6 -2
  254. package/dist/message/WaMessageClient.js +31 -33
  255. package/dist/message/ack.js +6 -6
  256. package/dist/message/addon-crypto.js +65 -0
  257. package/dist/message/content.js +198 -9
  258. package/dist/message/icdc.js +81 -0
  259. package/dist/message/incoming.js +127 -120
  260. package/dist/message/index.js +2 -0
  261. package/dist/message/phash.js +3 -1
  262. package/dist/message/reporting-token.js +429 -0
  263. package/dist/message/use-case-secret.js +55 -0
  264. package/dist/protocol/appstate.js +28 -1
  265. package/dist/protocol/browser.js +10 -18
  266. package/dist/protocol/constants.js +26 -1
  267. package/dist/protocol/defaults.js +6 -0
  268. package/dist/protocol/index.js +23 -42
  269. package/dist/protocol/jid.js +140 -52
  270. package/dist/protocol/media.js +3 -3
  271. package/dist/protocol/message.js +62 -2
  272. package/dist/protocol/nodes.js +4 -0
  273. package/dist/protocol/notification.js +3 -1
  274. package/dist/protocol/privacy-token.js +20 -0
  275. package/dist/protocol/privacy.js +58 -0
  276. package/dist/protocol/stream.js +27 -2
  277. package/dist/protocol/usync.js +14 -0
  278. package/dist/retry/codec.js +220 -0
  279. package/dist/retry/constants.js +1 -1
  280. package/dist/retry/index.js +7 -5
  281. package/dist/retry/parse.js +88 -85
  282. package/dist/retry/replay.js +52 -49
  283. package/dist/retry/tracker.js +97 -0
  284. package/dist/signal/api/SignalDeviceSyncApi.js +273 -89
  285. package/dist/signal/api/SignalDigestSyncApi.js +17 -8
  286. package/dist/signal/api/SignalIdentitySyncApi.js +66 -36
  287. package/dist/signal/api/SignalMissingPreKeysSyncApi.js +82 -63
  288. package/dist/signal/api/SignalRotateKeyApi.js +4 -2
  289. package/dist/signal/api/SignalSessionSyncApi.js +36 -34
  290. package/dist/signal/api/result-map.js +13 -0
  291. package/dist/signal/constants.js +1 -5
  292. package/dist/signal/crypto/WaAdvSignature.js +11 -7
  293. package/dist/signal/{store/sqlite.js → encoding.js} +94 -61
  294. package/dist/signal/group/SenderKeyChain.js +27 -22
  295. package/dist/signal/group/SenderKeyCodec.js +5 -6
  296. package/dist/signal/group/SenderKeyManager.js +144 -115
  297. package/dist/signal/index.js +15 -1
  298. package/dist/signal/registration/keygen.js +6 -2
  299. package/dist/signal/registration/utils.js +1 -0
  300. package/dist/signal/session/SignalProtocol.js +164 -53
  301. package/dist/signal/session/SignalRatchet.js +24 -15
  302. package/dist/signal/session/SignalSession.js +14 -9
  303. package/dist/signal/session/resolver.js +224 -0
  304. package/dist/store/contracts/privacy-token.store.js +2 -0
  305. package/dist/store/createStore.js +100 -188
  306. package/dist/store/index.js +15 -33
  307. package/dist/store/locks/appstate.lock.js +29 -0
  308. package/dist/store/locks/auth.lock.js +18 -0
  309. package/dist/store/locks/contact.lock.js +23 -0
  310. package/dist/store/locks/device-list.lock.js +23 -0
  311. package/dist/store/locks/message.lock.js +24 -0
  312. package/dist/store/locks/participants.lock.js +23 -0
  313. package/dist/store/locks/privacy-token.lock.js +21 -0
  314. package/dist/store/locks/retry.lock.js +32 -0
  315. package/dist/store/locks/sender-key.lock.js +55 -0
  316. package/dist/store/locks/signal.lock.js +66 -0
  317. package/dist/store/locks/thread.lock.js +24 -0
  318. package/dist/store/noop.store.js +4 -7
  319. package/dist/store/providers/memory/appstate.store.js +36 -14
  320. package/dist/store/providers/memory/contact.store.js +5 -0
  321. package/dist/store/providers/memory/device-list.store.js +12 -34
  322. package/dist/store/providers/memory/message.store.js +11 -5
  323. package/dist/store/providers/memory/participants.store.js +1 -8
  324. package/dist/store/providers/memory/privacy-token.store.js +47 -0
  325. package/dist/store/providers/memory/retry.store.js +77 -2
  326. package/dist/store/providers/memory/sender-key.store.js +14 -11
  327. package/dist/store/providers/memory/signal.store.js +54 -25
  328. package/dist/store/providers/memory/thread.store.js +5 -0
  329. package/dist/transport/WaComms.js +30 -26
  330. package/dist/transport/WaWebSocket.js +148 -18
  331. package/dist/transport/binary/constants.js +1 -31
  332. package/dist/transport/binary/decoder.js +8 -8
  333. package/dist/transport/binary/encoder.js +10 -9
  334. package/dist/transport/binary/index.js +0 -4
  335. package/dist/transport/index.js +7 -1
  336. package/dist/transport/keepalive/WaKeepAlive.js +1 -7
  337. package/dist/transport/node/WaNodeOrchestrator.js +25 -21
  338. package/dist/transport/node/WaNodeTransport.js +0 -3
  339. package/dist/transport/node/builders/{accountSync.js → account-sync.js} +15 -35
  340. package/dist/transport/node/builders/business.js +137 -0
  341. package/dist/transport/node/builders/global.js +375 -0
  342. package/dist/transport/node/builders/index.js +29 -17
  343. package/dist/transport/node/builders/message.js +64 -236
  344. package/dist/transport/node/builders/pairing.js +2 -29
  345. package/dist/transport/node/builders/privacy-token.js +46 -0
  346. package/dist/transport/node/builders/privacy.js +55 -0
  347. package/dist/transport/node/builders/profile.js +78 -0
  348. package/dist/transport/node/builders/retry.js +9 -21
  349. package/dist/transport/node/builders/usync.js +49 -0
  350. package/dist/transport/node/helpers.js +131 -4
  351. package/dist/transport/node/usync.js +8 -0
  352. package/dist/transport/node/xml.js +35 -14
  353. package/dist/transport/noise/WaClientPayload.js +13 -13
  354. package/dist/transport/noise/WaFrameCodec.js +47 -32
  355. package/dist/transport/noise/WaNoiseCert.js +5 -8
  356. package/dist/transport/noise/WaNoiseSession.js +77 -29
  357. package/dist/transport/noise/WaNoiseSocket.js +8 -4
  358. package/dist/transport/proxy.js +34 -0
  359. package/dist/transport/stream/parse.js +20 -52
  360. package/dist/types/appstate/WaAppStateCrypto.d.ts +0 -1
  361. package/dist/types/appstate/WaAppStateSyncClient.d.ts +5 -2
  362. package/dist/types/appstate/constants.d.ts +1 -0
  363. package/dist/types/appstate/encoding.d.ts +7 -0
  364. package/dist/types/appstate/index.d.ts +3 -3
  365. package/dist/types/appstate/utils.d.ts +0 -3
  366. package/dist/types/auth/WaAuthClient.d.ts +10 -12
  367. package/dist/types/auth/flow/WaAuthCredentialsFlow.d.ts +1 -1
  368. package/dist/types/auth/index.d.ts +0 -4
  369. package/dist/types/auth/pairing/WaQrFlow.d.ts +1 -1
  370. package/dist/types/auth/types.d.ts +7 -9
  371. package/dist/types/client/WaClient.d.ts +42 -25
  372. package/dist/types/client/WaClientFactory.d.ts +33 -26
  373. package/dist/types/client/connection/WaConnectionManager.d.ts +66 -0
  374. package/dist/types/client/connection/WaKeyShareCoordinator.d.ts +14 -0
  375. package/dist/types/client/connection/WaReceiptQueue.d.ts +13 -0
  376. package/dist/types/client/coordinators/WaAppStateMutationCoordinator.d.ts +46 -0
  377. package/dist/types/client/coordinators/WaBusinessCoordinator.d.ts +57 -0
  378. package/dist/types/client/coordinators/WaIncomingNodeCoordinator.d.ts +3 -2
  379. package/dist/types/client/coordinators/WaMessageDispatchCoordinator.d.ts +29 -38
  380. package/dist/types/client/coordinators/WaPassiveTasksCoordinator.d.ts +4 -0
  381. package/dist/types/client/coordinators/WaPrivacyCoordinator.d.ts +26 -0
  382. package/dist/types/client/coordinators/WaProfileCoordinator.d.ts +36 -0
  383. package/dist/types/client/coordinators/WaRetryCoordinator.d.ts +8 -0
  384. package/dist/types/client/coordinators/WaStreamControlCoordinator.d.ts +3 -2
  385. package/dist/types/client/coordinators/WaTrustedContactTokenCoordinator.d.ts +45 -0
  386. package/dist/types/client/dirty.d.ts +1 -0
  387. package/dist/types/client/events/devices.d.ts +20 -0
  388. package/dist/types/client/events/group.d.ts +2 -1
  389. package/dist/types/client/events/identity.d.ts +9 -0
  390. package/dist/types/client/events/privacy-token.d.ts +7 -0
  391. package/dist/types/client/history-sync.d.ts +9 -6
  392. package/dist/types/client/incoming.d.ts +3 -1
  393. package/dist/types/client/index.d.ts +1 -1
  394. package/dist/types/client/mailbox.d.ts +3 -5
  395. package/dist/types/client/messages.d.ts +1 -2
  396. package/dist/types/client/messaging/fanout.d.ts +14 -0
  397. package/dist/types/client/messaging/key-protocol.d.ts +18 -0
  398. package/dist/types/client/messaging/participants.d.ts +13 -0
  399. package/dist/types/client/persistence/WriteBehindPersistence.d.ts +34 -0
  400. package/dist/types/client/tokens/cs-token.d.ts +10 -0
  401. package/dist/types/client/tokens/tc-token.d.ts +5 -0
  402. package/dist/types/client/types.d.ts +75 -4
  403. package/dist/types/crypto/core/hkdf.d.ts +0 -6
  404. package/dist/types/crypto/core/index.d.ts +2 -3
  405. package/dist/types/crypto/core/nonce.d.ts +2 -0
  406. package/dist/types/crypto/core/primitives.d.ts +0 -1
  407. package/dist/types/crypto/core/random.d.ts +2 -7
  408. package/dist/types/crypto/index.d.ts +0 -1
  409. package/dist/types/crypto/math/constants.d.ts +4 -2
  410. package/dist/types/crypto/math/fe.d.ts +30 -0
  411. package/dist/types/crypto/math/mod.d.ts +0 -2
  412. package/dist/types/crypto/math/types.d.ts +11 -4
  413. package/dist/types/index.d.ts +5 -3
  414. package/dist/types/infra/log/ConsoleLogger.d.ts +2 -1
  415. package/dist/types/infra/log/PinoLogger.d.ts +1 -1
  416. package/dist/types/infra/log/types.d.ts +1 -0
  417. package/dist/types/infra/perf/BackgroundQueue.d.ts +58 -0
  418. package/dist/types/infra/perf/BoundedTaskQueue.d.ts +1 -1
  419. package/dist/types/infra/perf/PromiseDedup.d.ts +4 -0
  420. package/dist/types/infra/perf/SharedExclusiveGate.d.ts +17 -0
  421. package/dist/types/infra/perf/StoreLock.d.ts +10 -0
  422. package/dist/types/media/WaMediaCrypto.d.ts +3 -2
  423. package/dist/types/media/WaMediaTransferClient.d.ts +16 -15
  424. package/dist/types/media/constants.d.ts +1 -1
  425. package/dist/types/media/index.d.ts +1 -1
  426. package/dist/types/media/types.d.ts +15 -2
  427. package/dist/types/message/addon-crypto.d.ts +25 -0
  428. package/dist/types/message/content.d.ts +8 -0
  429. package/dist/types/message/icdc.d.ts +13 -0
  430. package/dist/types/message/index.d.ts +2 -0
  431. package/dist/types/message/reporting-token.d.ts +18 -0
  432. package/dist/types/message/types.d.ts +45 -6
  433. package/dist/types/message/use-case-secret.d.ts +20 -0
  434. package/dist/types/protocol/appstate.d.ts +47 -0
  435. package/dist/types/protocol/constants.d.ts +8 -3
  436. package/dist/types/protocol/defaults.d.ts +6 -0
  437. package/dist/types/protocol/index.d.ts +2 -11
  438. package/dist/types/protocol/jid.d.ts +22 -5
  439. package/dist/types/protocol/message.d.ts +60 -0
  440. package/dist/types/protocol/nodes.d.ts +4 -0
  441. package/dist/types/protocol/notification.d.ts +2 -0
  442. package/dist/types/protocol/privacy-token.d.ts +17 -0
  443. package/dist/types/protocol/privacy.d.ts +75 -0
  444. package/dist/types/protocol/stream.d.ts +30 -0
  445. package/dist/types/protocol/usync.d.ts +11 -0
  446. package/dist/types/retry/codec.d.ts +3 -0
  447. package/dist/types/retry/index.d.ts +4 -3
  448. package/dist/types/retry/parse.d.ts +5 -2
  449. package/dist/types/retry/replay.d.ts +0 -4
  450. package/dist/types/retry/tracker.d.ts +20 -0
  451. package/dist/types/retry/types.d.ts +10 -4
  452. package/dist/types/signal/api/SignalDeviceSyncApi.d.ts +15 -2
  453. package/dist/types/signal/api/SignalDigestSyncApi.d.ts +6 -0
  454. package/dist/types/signal/api/SignalIdentitySyncApi.d.ts +2 -0
  455. package/dist/types/signal/api/SignalRotateKeyApi.d.ts +4 -5
  456. package/dist/types/signal/api/SignalSessionSyncApi.d.ts +8 -6
  457. package/dist/types/signal/api/result-map.d.ts +1 -0
  458. package/dist/types/signal/constants.d.ts +0 -3
  459. package/dist/types/signal/{store/sqlite.d.ts → encoding.d.ts} +3 -3
  460. package/dist/types/signal/group/SenderKeyCodec.d.ts +4 -6
  461. package/dist/types/signal/group/SenderKeyManager.d.ts +10 -5
  462. package/dist/types/signal/index.d.ts +3 -0
  463. package/dist/types/signal/session/SignalProtocol.d.ts +19 -4
  464. package/dist/types/signal/session/resolver.d.ts +22 -0
  465. package/dist/types/store/contracts/appstate.store.d.ts +4 -1
  466. package/dist/types/store/contracts/contact.store.d.ts +1 -0
  467. package/dist/types/store/contracts/device-list.store.d.ts +0 -3
  468. package/dist/types/store/contracts/message.store.d.ts +1 -0
  469. package/dist/types/store/contracts/participants.store.d.ts +0 -1
  470. package/dist/types/store/contracts/privacy-token.store.d.ts +16 -0
  471. package/dist/types/store/contracts/retry.store.d.ts +7 -0
  472. package/dist/types/store/contracts/sender-key.store.d.ts +0 -1
  473. package/dist/types/store/contracts/signal.store.d.ts +13 -0
  474. package/dist/types/store/contracts/thread.store.d.ts +1 -0
  475. package/dist/types/store/createStore.d.ts +1 -1
  476. package/dist/types/store/index.d.ts +5 -13
  477. package/dist/types/store/locks/appstate.lock.d.ts +3 -0
  478. package/dist/types/store/locks/auth.lock.d.ts +3 -0
  479. package/dist/types/store/locks/contact.lock.d.ts +3 -0
  480. package/dist/types/store/locks/device-list.lock.d.ts +2 -0
  481. package/dist/types/store/locks/message.lock.d.ts +3 -0
  482. package/dist/types/store/locks/participants.lock.d.ts +2 -0
  483. package/dist/types/store/locks/privacy-token.lock.d.ts +2 -0
  484. package/dist/types/store/locks/retry.lock.d.ts +2 -0
  485. package/dist/types/store/locks/sender-key.lock.d.ts +3 -0
  486. package/dist/types/store/locks/signal.lock.d.ts +3 -0
  487. package/dist/types/store/locks/thread.lock.d.ts +3 -0
  488. package/dist/types/store/providers/memory/appstate.store.d.ts +3 -1
  489. package/dist/types/store/providers/memory/contact.store.d.ts +1 -0
  490. package/dist/types/store/providers/memory/device-list.store.d.ts +0 -3
  491. package/dist/types/store/providers/memory/message.store.d.ts +1 -0
  492. package/dist/types/store/providers/memory/participants.store.d.ts +0 -1
  493. package/dist/types/store/providers/memory/privacy-token.store.d.ts +13 -0
  494. package/dist/types/store/providers/memory/retry.store.d.ts +8 -0
  495. package/dist/types/store/providers/memory/sender-key.store.d.ts +0 -1
  496. package/dist/types/store/providers/memory/signal.store.d.ts +8 -1
  497. package/dist/types/store/providers/memory/thread.store.d.ts +1 -0
  498. package/dist/types/store/types.d.ts +49 -58
  499. package/dist/types/transport/WaWebSocket.d.ts +3 -1
  500. package/dist/types/transport/binary/constants.d.ts +0 -30
  501. package/dist/types/transport/binary/index.d.ts +0 -1
  502. package/dist/types/transport/index.d.ts +2 -1
  503. package/dist/types/transport/keepalive/WaKeepAlive.d.ts +0 -1
  504. package/dist/types/transport/node/WaNodeOrchestrator.d.ts +3 -4
  505. package/dist/types/transport/node/WaNodeTransport.d.ts +0 -9
  506. package/dist/types/transport/node/builders/business.d.ts +29 -0
  507. package/dist/types/transport/node/builders/global.d.ts +102 -0
  508. package/dist/types/transport/node/builders/group.d.ts +4 -6
  509. package/dist/types/transport/node/builders/index.d.ts +7 -3
  510. package/dist/types/transport/node/builders/message.d.ts +20 -30
  511. package/dist/types/transport/node/builders/pairing.d.ts +0 -2
  512. package/dist/types/transport/node/builders/privacy-token.d.ts +9 -0
  513. package/dist/types/transport/node/builders/privacy.d.ts +7 -0
  514. package/dist/types/transport/node/builders/profile.d.ts +8 -0
  515. package/dist/types/transport/node/builders/retry.d.ts +2 -5
  516. package/dist/types/transport/node/builders/usync.d.ts +21 -0
  517. package/dist/types/transport/node/helpers.d.ts +13 -0
  518. package/dist/types/transport/node/usync.d.ts +2 -0
  519. package/dist/types/transport/noise/WaFrameCodec.d.ts +3 -0
  520. package/dist/types/transport/noise/WaNoiseSession.d.ts +4 -2
  521. package/dist/types/transport/noise/WaNoiseSocket.d.ts +4 -2
  522. package/dist/types/transport/proxy.d.ts +6 -0
  523. package/dist/types/transport/stream/parse.d.ts +0 -1
  524. package/dist/types/transport/types.d.ts +18 -1
  525. package/dist/types/util/bytes.d.ts +5 -0
  526. package/dist/types/util/index.d.ts +5 -0
  527. package/dist/types/util/primitives.d.ts +2 -0
  528. package/dist/util/bytes.js +72 -46
  529. package/dist/util/coercion.js +6 -14
  530. package/dist/util/index.js +23 -0
  531. package/dist/util/primitives.js +42 -14
  532. package/package.json +52 -9
  533. package/proto/index.js +1 -1
  534. package/dist/crypto/core/constants.js +0 -4
  535. package/dist/crypto/core/encoding.js +0 -29
  536. package/dist/esm/crypto/core/constants.js +0 -1
  537. package/dist/esm/crypto/core/encoding.js +0 -25
  538. package/dist/esm/retry/outbound.js +0 -83
  539. package/dist/esm/store/providers/sqlite/BaseSqliteStore.js +0 -37
  540. package/dist/esm/store/providers/sqlite/appstate.store.js +0 -169
  541. package/dist/esm/store/providers/sqlite/auth.store.js +0 -176
  542. package/dist/esm/store/providers/sqlite/connection.js +0 -240
  543. package/dist/esm/store/providers/sqlite/contact.store.js +0 -61
  544. package/dist/esm/store/providers/sqlite/device-list.store.js +0 -155
  545. package/dist/esm/store/providers/sqlite/message.store.js +0 -119
  546. package/dist/esm/store/providers/sqlite/migrations.js +0 -347
  547. package/dist/esm/store/providers/sqlite/participants.store.js +0 -85
  548. package/dist/esm/store/providers/sqlite/retry.store.js +0 -144
  549. package/dist/esm/store/providers/sqlite/sender-key.store.js +0 -203
  550. package/dist/esm/store/providers/sqlite/signal.store.js +0 -353
  551. package/dist/esm/store/providers/sqlite/thread.store.js +0 -72
  552. package/dist/esm/util/base64.js +0 -18
  553. package/dist/esm/util/signal-address.js +0 -5
  554. package/dist/retry/outbound.js +0 -88
  555. package/dist/store/providers/sqlite/BaseSqliteStore.js +0 -41
  556. package/dist/store/providers/sqlite/appstate.store.js +0 -173
  557. package/dist/store/providers/sqlite/auth.store.js +0 -180
  558. package/dist/store/providers/sqlite/connection.js +0 -276
  559. package/dist/store/providers/sqlite/contact.store.js +0 -65
  560. package/dist/store/providers/sqlite/device-list.store.js +0 -159
  561. package/dist/store/providers/sqlite/message.store.js +0 -123
  562. package/dist/store/providers/sqlite/migrations.js +0 -350
  563. package/dist/store/providers/sqlite/participants.store.js +0 -89
  564. package/dist/store/providers/sqlite/retry.store.js +0 -148
  565. package/dist/store/providers/sqlite/sender-key.store.js +0 -207
  566. package/dist/store/providers/sqlite/signal.store.js +0 -357
  567. package/dist/store/providers/sqlite/thread.store.js +0 -76
  568. package/dist/types/appstate/store/sqlite.d.ts +0 -21
  569. package/dist/types/crypto/core/constants.d.ts +0 -1
  570. package/dist/types/crypto/core/encoding.d.ts +0 -11
  571. package/dist/types/retry/outbound.d.ts +0 -4
  572. package/dist/types/store/providers/sqlite/BaseSqliteStore.d.ts +0 -12
  573. package/dist/types/store/providers/sqlite/appstate.store.d.ts +0 -15
  574. package/dist/types/store/providers/sqlite/auth.store.d.ts +0 -10
  575. package/dist/types/store/providers/sqlite/connection.d.ts +0 -10
  576. package/dist/types/store/providers/sqlite/contact.store.d.ts +0 -10
  577. package/dist/types/store/providers/sqlite/device-list.store.d.ts +0 -18
  578. package/dist/types/store/providers/sqlite/message.store.d.ts +0 -11
  579. package/dist/types/store/providers/sqlite/migrations.d.ts +0 -3
  580. package/dist/types/store/providers/sqlite/participants.store.d.ts +0 -13
  581. package/dist/types/store/providers/sqlite/retry.store.d.ts +0 -16
  582. package/dist/types/store/providers/sqlite/sender-key.store.d.ts +0 -25
  583. package/dist/types/store/providers/sqlite/signal.store.d.ts +0 -46
  584. package/dist/types/store/providers/sqlite/thread.store.d.ts +0 -11
  585. package/dist/types/util/base64.d.ts +0 -4
  586. package/dist/types/util/signal-address.d.ts +0 -2
  587. package/dist/util/base64.js +0 -24
  588. package/dist/util/signal-address.js +0 -8
  589. /package/dist/types/transport/node/builders/{accountSync.d.ts → account-sync.d.ts} +0 -0
@@ -5,36 +5,37 @@ const LOG_LEVEL_PRIORITY = {
5
5
  warn: 40,
6
6
  error: 50
7
7
  };
8
+ const CONSOLE_WRITERS = {
9
+ trace: console.debug,
10
+ debug: console.debug,
11
+ info: console.info,
12
+ warn: console.warn,
13
+ error: console.error
14
+ };
8
15
  export class ConsoleLogger {
9
16
  constructor(level = 'info') {
10
17
  this.level = level;
18
+ this.minLevelPriority = LOG_LEVEL_PRIORITY[level];
11
19
  }
12
20
  trace(message, context) {
13
- if (this.canLog('trace')) {
14
- console.debug(message, context);
15
- }
21
+ this.write('trace', message, context);
16
22
  }
17
23
  debug(message, context) {
18
- if (this.canLog('debug')) {
19
- console.debug(message, context);
20
- }
24
+ this.write('debug', message, context);
21
25
  }
22
26
  info(message, context) {
23
- if (this.canLog('info')) {
24
- console.info(message, context);
25
- }
27
+ this.write('info', message, context);
26
28
  }
27
29
  warn(message, context) {
28
- if (this.canLog('warn')) {
29
- console.warn(message, context);
30
- }
30
+ this.write('warn', message, context);
31
31
  }
32
32
  error(message, context) {
33
- if (this.canLog('error')) {
34
- console.error(message, context);
35
- }
33
+ this.write('error', message, context);
36
34
  }
37
- canLog(level) {
38
- return LOG_LEVEL_PRIORITY[level] >= LOG_LEVEL_PRIORITY[this.level];
35
+ write(level, message, context) {
36
+ if (LOG_LEVEL_PRIORITY[level] < this.minLevelPriority) {
37
+ return;
38
+ }
39
+ CONSOLE_WRITERS[level](message, context);
39
40
  }
40
41
  }
@@ -23,26 +23,32 @@ export class PinoLogger {
23
23
  this.logger.level = level;
24
24
  }
25
25
  trace(message, context) {
26
- this.writeLog('trace', message, context);
26
+ this.write('trace', message, context);
27
27
  }
28
28
  debug(message, context) {
29
- this.writeLog('debug', message, context);
29
+ this.write('debug', message, context);
30
30
  }
31
31
  info(message, context) {
32
- this.writeLog('info', message, context);
32
+ this.write('info', message, context);
33
33
  }
34
34
  warn(message, context) {
35
- this.writeLog('warn', message, context);
35
+ this.write('warn', message, context);
36
36
  }
37
37
  error(message, context) {
38
- this.writeLog('error', message, context);
38
+ this.write('error', message, context);
39
39
  }
40
- writeLog(method, message, context) {
41
- if (!context || Object.keys(context).length === 0) {
42
- this.logger[method](message);
40
+ write(level, message, context) {
41
+ if (context === null || context === undefined) {
42
+ this.logger[level](message);
43
43
  return;
44
44
  }
45
- this.logger[method](context, message);
45
+ for (const key in context) {
46
+ if (Object.prototype.hasOwnProperty.call(context, key)) {
47
+ this.logger[level](context, message);
48
+ return;
49
+ }
50
+ }
51
+ this.logger[level](message);
46
52
  }
47
53
  }
48
54
  export async function createPinoLogger(options = {}) {
@@ -1 +1,11 @@
1
- export {};
1
+ function noop() { }
2
+ export function createNoopLogger(level = 'trace') {
3
+ return {
4
+ level,
5
+ trace: noop,
6
+ debug: noop,
7
+ info: noop,
8
+ warn: noop,
9
+ error: noop
10
+ };
11
+ }
@@ -0,0 +1,478 @@
1
+ import { toError } from '../../util/primitives.js';
2
+ const DEFAULT_MAX_PENDING_KEYS = 4096;
3
+ const DEFAULT_FLUSH_TIMEOUT_MS = 5000;
4
+ const RETRY_BACKOFF_BASE_MS = 100;
5
+ const RETRY_BACKOFF_MAX_MS = 2000;
6
+ export class BackgroundQueue {
7
+ constructor(writer, options = {}) {
8
+ this.writer = writer;
9
+ this.coalesce = options.coalesce ?? ((_p, i) => i);
10
+ const maxPendingKeys = options.maxPendingKeys ?? DEFAULT_MAX_PENDING_KEYS;
11
+ if (!Number.isSafeInteger(maxPendingKeys) || maxPendingKeys < 1) {
12
+ throw new Error('BackgroundQueue maxPendingKeys must be a positive integer');
13
+ }
14
+ this.maxPendingKeys = maxPendingKeys;
15
+ const maxWriteConcurrency = options.maxWriteConcurrency ?? 1;
16
+ if (!Number.isSafeInteger(maxWriteConcurrency) || maxWriteConcurrency < 1) {
17
+ throw new Error('BackgroundQueue maxWriteConcurrency must be a positive integer');
18
+ }
19
+ this.maxWriteConcurrency = maxWriteConcurrency;
20
+ const flushTimeoutMs = options.flushTimeoutMs ?? DEFAULT_FLUSH_TIMEOUT_MS;
21
+ if (!Number.isFinite(flushTimeoutMs) || flushTimeoutMs < 1) {
22
+ throw new Error('BackgroundQueue flushTimeoutMs must be a positive finite number');
23
+ }
24
+ this.flushTimeoutMs = flushTimeoutMs;
25
+ this.onError = options.onError;
26
+ this.onPressure = options.onPressure;
27
+ this.onDiscard = options.onDiscard;
28
+ this.pendingByKey = new Map();
29
+ this.retryTimersByKey = new Map();
30
+ this.stateWaiters = [];
31
+ this.drainingPromise = null;
32
+ this.inFlight = 0;
33
+ this.flushedCount = 0;
34
+ this.shutdownRequested = false;
35
+ this.retryDisabled = false;
36
+ }
37
+ enqueue(key, value) {
38
+ if (this.shutdownRequested) {
39
+ this.invokeOnDiscard(key, value);
40
+ return;
41
+ }
42
+ if (this.pendingByKey.has(key) || this.retryTimersByKey.has(key)) {
43
+ this.addPendingEntry(key, value);
44
+ this.notifyStateChange();
45
+ this.ensureDrain();
46
+ return;
47
+ }
48
+ if (this.trackedKeys() < this.maxPendingKeys) {
49
+ this.addPendingEntry(key, value);
50
+ this.notifyStateChange();
51
+ this.ensureDrain();
52
+ return;
53
+ }
54
+ this.invokeOnPressure(this.trackedKeys());
55
+ this.invokeOnDiscard(key, value);
56
+ }
57
+ async enqueueAsync(key, value) {
58
+ if (this.shutdownRequested) {
59
+ this.invokeOnDiscard(key, value);
60
+ throw new Error('background queue is destroyed');
61
+ }
62
+ await this.waitForCapacity(key, value);
63
+ return new Promise((resolve, reject) => {
64
+ const waiter = { resolve, reject };
65
+ this.addPendingEntry(key, value, waiter);
66
+ this.notifyStateChange();
67
+ this.ensureDrain();
68
+ });
69
+ }
70
+ async waitForCapacity(key, value) {
71
+ while (!this.pendingByKey.has(key) &&
72
+ !this.retryTimersByKey.has(key) &&
73
+ this.trackedKeys() >= this.maxPendingKeys) {
74
+ this.invokeOnPressure(this.trackedKeys());
75
+ await this.waitForStateChange(this.flushTimeoutMs);
76
+ if (this.shutdownRequested) {
77
+ this.invokeOnDiscard(key, value);
78
+ throw new Error('background queue is destroyed');
79
+ }
80
+ }
81
+ }
82
+ addPendingEntry(key, value, waiter) {
83
+ const scheduledRetryTimer = this.retryTimersByKey.get(key) ?? null;
84
+ const scheduledRetry = scheduledRetryTimer?.entry ?? null;
85
+ const existing = this.pendingByKey.get(key);
86
+ if (existing) {
87
+ let coalescedValue = existing.value;
88
+ let coalescedAttempt = existing.attempt;
89
+ try {
90
+ if (scheduledRetry) {
91
+ coalescedValue = this.coalesce(scheduledRetry.value, coalescedValue, key);
92
+ coalescedAttempt = Math.max(coalescedAttempt, scheduledRetry.attempt);
93
+ }
94
+ coalescedValue = this.coalesce(coalescedValue, value, key);
95
+ }
96
+ catch (error) {
97
+ this.invokeOnError(key, error, Math.max(coalescedAttempt + 1, scheduledRetry?.attempt ?? 0));
98
+ if (waiter) {
99
+ waiter.reject(error === undefined
100
+ ? new Error('background queue coalesce failed')
101
+ : toError(error));
102
+ }
103
+ else {
104
+ this.invokeOnDiscard(key, value);
105
+ }
106
+ return;
107
+ }
108
+ if (scheduledRetry) {
109
+ this.detachRetryEntry(key, scheduledRetryTimer);
110
+ if (scheduledRetry.waiters.length > 0) {
111
+ const mergedWaiters = new Array(scheduledRetry.waiters.length + existing.waiters.length);
112
+ let writeIndex = 0;
113
+ for (let i = 0; i < scheduledRetry.waiters.length; i += 1) {
114
+ mergedWaiters[writeIndex++] = scheduledRetry.waiters[i];
115
+ }
116
+ for (let i = 0; i < existing.waiters.length; i += 1) {
117
+ mergedWaiters[writeIndex++] = existing.waiters[i];
118
+ }
119
+ existing.waiters = mergedWaiters;
120
+ }
121
+ existing.attempt = Math.max(coalescedAttempt, scheduledRetry.attempt);
122
+ }
123
+ existing.value = coalescedValue;
124
+ existing.attempt = coalescedAttempt;
125
+ if (waiter) {
126
+ existing.waiters[existing.waiters.length] = waiter;
127
+ }
128
+ return;
129
+ }
130
+ if (scheduledRetry) {
131
+ let coalescedValue;
132
+ try {
133
+ coalescedValue = this.coalesce(scheduledRetry.value, value, key);
134
+ }
135
+ catch (error) {
136
+ this.invokeOnError(key, error, scheduledRetry.attempt + 1);
137
+ if (waiter) {
138
+ waiter.reject(error === undefined
139
+ ? new Error('background queue coalesce failed')
140
+ : toError(error));
141
+ }
142
+ else {
143
+ this.invokeOnDiscard(key, value);
144
+ }
145
+ return;
146
+ }
147
+ this.detachRetryEntry(key, scheduledRetryTimer);
148
+ const scheduledWaiterCount = scheduledRetry.waiters.length;
149
+ const waiters = new Array(scheduledWaiterCount + (waiter ? 1 : 0));
150
+ for (let i = 0; i < scheduledWaiterCount; i += 1) {
151
+ waiters[i] = scheduledRetry.waiters[i];
152
+ }
153
+ if (waiter) {
154
+ waiters[scheduledWaiterCount] = waiter;
155
+ }
156
+ this.pendingByKey.set(key, {
157
+ value: coalescedValue,
158
+ waiters,
159
+ attempt: scheduledRetry.attempt
160
+ });
161
+ return;
162
+ }
163
+ this.pendingByKey.set(key, {
164
+ value,
165
+ waiters: waiter ? [waiter] : [],
166
+ attempt: 0
167
+ });
168
+ }
169
+ detachRetryEntry(key, retry) {
170
+ if (!retry) {
171
+ return;
172
+ }
173
+ const current = this.retryTimersByKey.get(key);
174
+ if (!current || current !== retry) {
175
+ return;
176
+ }
177
+ this.retryTimersByKey.delete(key);
178
+ clearTimeout(retry.timer);
179
+ }
180
+ async flush(timeoutMs = this.flushTimeoutMs) {
181
+ const normalizedTimeoutMs = Math.max(0, Number.isFinite(timeoutMs) ? timeoutMs : this.flushTimeoutMs);
182
+ const startFlushed = this.flushedCount;
183
+ const deadline = Date.now() + normalizedTimeoutMs;
184
+ while (true) {
185
+ const remaining = this.remaining();
186
+ if (remaining === 0) {
187
+ return {
188
+ flushed: this.flushedCount - startFlushed,
189
+ remaining: 0
190
+ };
191
+ }
192
+ const remainingMs = deadline - Date.now();
193
+ if (remainingMs <= 0) {
194
+ return {
195
+ flushed: this.flushedCount - startFlushed,
196
+ remaining
197
+ };
198
+ }
199
+ await this.waitForStateChange(remainingMs, true);
200
+ }
201
+ }
202
+ async destroy(timeoutMs = this.flushTimeoutMs) {
203
+ const normalizedTimeoutMs = Math.max(0, Number.isFinite(timeoutMs) ? timeoutMs : this.flushTimeoutMs);
204
+ this.shutdownRequested = true;
205
+ this.notifyStateChange();
206
+ const flushed = await this.flush(normalizedTimeoutMs);
207
+ if (flushed.remaining > 0) {
208
+ this.retryDisabled = true;
209
+ this.discardPending();
210
+ }
211
+ return {
212
+ flushed: flushed.flushed,
213
+ remaining: this.remaining()
214
+ };
215
+ }
216
+ ensureDrain() {
217
+ if (this.drainingPromise) {
218
+ return;
219
+ }
220
+ this.drainingPromise = this.drainLoop().finally(() => {
221
+ this.drainingPromise = null;
222
+ this.notifyStateChange();
223
+ if (this.pendingByKey.size > 0) {
224
+ this.ensureDrain();
225
+ }
226
+ });
227
+ }
228
+ async drainLoop() {
229
+ while (true) {
230
+ const batch = this.takeBatch();
231
+ if (batch.length === 0) {
232
+ return;
233
+ }
234
+ if (batch.length === 1) {
235
+ await this.processEntry(batch[0].key, batch[0].entry);
236
+ continue;
237
+ }
238
+ const tasks = new Array(batch.length);
239
+ for (let i = 0; i < batch.length; i += 1) {
240
+ tasks[i] = this.processEntry(batch[i].key, batch[i].entry);
241
+ }
242
+ await Promise.all(tasks);
243
+ }
244
+ }
245
+ takeBatch() {
246
+ const batch = [];
247
+ for (let i = 0; i < this.maxWriteConcurrency; i += 1) {
248
+ const next = this.takeNext();
249
+ if (!next) {
250
+ break;
251
+ }
252
+ batch.push(next);
253
+ }
254
+ return batch;
255
+ }
256
+ async processEntry(key, entry) {
257
+ this.inFlight += 1;
258
+ try {
259
+ await this.writer(key, entry.value);
260
+ this.flushedCount += 1;
261
+ this.resolveEntry(entry);
262
+ }
263
+ catch (error) {
264
+ if (this.retryDisabled) {
265
+ this.discardEntry(key, entry);
266
+ }
267
+ else {
268
+ const merged = this.mergeForRetry(key, entry);
269
+ const attempt = merged.attempt + 1;
270
+ merged.attempt = attempt;
271
+ this.invokeOnError(key, error, attempt);
272
+ this.scheduleRetry(key, merged, this.retryDelayMs(attempt));
273
+ }
274
+ }
275
+ finally {
276
+ this.inFlight -= 1;
277
+ this.notifyStateChange();
278
+ }
279
+ }
280
+ takeNext() {
281
+ const next = this.pendingByKey.entries().next().value;
282
+ if (!next) {
283
+ return null;
284
+ }
285
+ const [key, entry] = next;
286
+ this.pendingByKey.delete(key);
287
+ return { key, entry };
288
+ }
289
+ mergeForRetry(key, failedEntry) {
290
+ const pending = this.pendingByKey.get(key);
291
+ if (!pending) {
292
+ return failedEntry;
293
+ }
294
+ const mergedWaiters = new Array(failedEntry.waiters.length + pending.waiters.length);
295
+ let mergedIndex = 0;
296
+ for (let i = 0; i < failedEntry.waiters.length; i += 1) {
297
+ mergedWaiters[mergedIndex++] = failedEntry.waiters[i];
298
+ }
299
+ for (let i = 0; i < pending.waiters.length; i += 1) {
300
+ mergedWaiters[mergedIndex++] = pending.waiters[i];
301
+ }
302
+ let mergedValue;
303
+ try {
304
+ mergedValue = this.coalesce(failedEntry.value, pending.value, key);
305
+ }
306
+ catch (error) {
307
+ const fallbackAttempt = Math.max(failedEntry.attempt, pending.attempt);
308
+ this.invokeOnError(key, error, fallbackAttempt + 1);
309
+ this.pendingByKey.delete(key);
310
+ this.invokeOnDiscard(key, pending.value);
311
+ if (pending.waiters.length > 0) {
312
+ const queueError = error === undefined
313
+ ? new Error('background queue coalesce failed')
314
+ : toError(error);
315
+ for (let index = 0; index < pending.waiters.length; index += 1) {
316
+ pending.waiters[index].reject(queueError);
317
+ }
318
+ }
319
+ return failedEntry;
320
+ }
321
+ this.pendingByKey.delete(key);
322
+ return {
323
+ value: mergedValue,
324
+ waiters: mergedWaiters,
325
+ attempt: Math.max(failedEntry.attempt, pending.attempt)
326
+ };
327
+ }
328
+ retryDelayMs(attempt) {
329
+ if (attempt <= 1) {
330
+ return RETRY_BACKOFF_BASE_MS;
331
+ }
332
+ const unbounded = RETRY_BACKOFF_BASE_MS * 2 ** Math.min(6, attempt - 1);
333
+ return Math.min(RETRY_BACKOFF_MAX_MS, unbounded);
334
+ }
335
+ scheduleRetry(key, entry, retryMs) {
336
+ const existing = this.retryTimersByKey.get(key);
337
+ if (existing) {
338
+ clearTimeout(existing.timer);
339
+ }
340
+ const timer = setTimeout(() => {
341
+ this.retryTimersByKey.delete(key);
342
+ if (this.retryDisabled) {
343
+ this.discardEntry(key, entry);
344
+ this.notifyStateChange();
345
+ return;
346
+ }
347
+ const latest = this.mergeForRetry(key, entry);
348
+ this.pendingByKey.set(key, latest);
349
+ this.notifyStateChange();
350
+ this.ensureDrain();
351
+ }, retryMs);
352
+ timer.unref?.();
353
+ this.retryTimersByKey.set(key, { entry, timer });
354
+ this.notifyStateChange();
355
+ }
356
+ resolveEntry(entry) {
357
+ if (entry.waiters.length === 0) {
358
+ return;
359
+ }
360
+ for (const waiter of entry.waiters) {
361
+ waiter.resolve();
362
+ }
363
+ }
364
+ discardEntry(key, entry) {
365
+ this.invokeOnDiscard(key, entry.value);
366
+ if (entry.waiters.length === 0) {
367
+ return;
368
+ }
369
+ const error = toError('background queue destroyed before write was flushed');
370
+ for (const waiter of entry.waiters) {
371
+ waiter.reject(error);
372
+ }
373
+ }
374
+ discardPending() {
375
+ if (this.pendingByKey.size > 0) {
376
+ for (const [key, entry] of this.pendingByKey) {
377
+ this.pendingByKey.delete(key);
378
+ this.discardEntry(key, entry);
379
+ }
380
+ }
381
+ if (this.retryTimersByKey.size > 0) {
382
+ for (const [key, retry] of this.retryTimersByKey) {
383
+ this.retryTimersByKey.delete(key);
384
+ clearTimeout(retry.timer);
385
+ this.discardEntry(key, retry.entry);
386
+ }
387
+ }
388
+ this.notifyStateChange();
389
+ }
390
+ remaining() {
391
+ return this.pendingByKey.size + this.retryTimersByKey.size + this.inFlight;
392
+ }
393
+ trackedKeys() {
394
+ return this.pendingByKey.size + this.retryTimersByKey.size;
395
+ }
396
+ notifyStateChange() {
397
+ if (this.stateWaiters.length === 0) {
398
+ return;
399
+ }
400
+ const waiterCount = this.stateWaiters.length;
401
+ for (let index = 0; index < waiterCount; index += 1) {
402
+ const waiter = this.stateWaiters[index];
403
+ waiter.index = -1;
404
+ waiter.done();
405
+ }
406
+ this.stateWaiters.length = 0;
407
+ }
408
+ waitForStateChange(timeoutMs, ref = false) {
409
+ return new Promise((resolve) => {
410
+ let active = true;
411
+ const waiter = {
412
+ done: () => {
413
+ if (!active) {
414
+ return;
415
+ }
416
+ active = false;
417
+ clearTimeout(timer);
418
+ this.removeStateWaiter(waiter);
419
+ resolve();
420
+ },
421
+ index: -1
422
+ };
423
+ const timer = setTimeout(waiter.done, timeoutMs);
424
+ if (!ref) {
425
+ timer.unref?.();
426
+ }
427
+ waiter.index = this.stateWaiters.length;
428
+ this.stateWaiters[waiter.index] = waiter;
429
+ });
430
+ }
431
+ removeStateWaiter(waiter) {
432
+ const index = waiter.index;
433
+ if (index < 0) {
434
+ return;
435
+ }
436
+ const lastIndex = this.stateWaiters.length - 1;
437
+ if (index !== lastIndex) {
438
+ const last = this.stateWaiters[lastIndex];
439
+ this.stateWaiters[index] = last;
440
+ last.index = index;
441
+ }
442
+ this.stateWaiters.length = lastIndex;
443
+ waiter.index = -1;
444
+ }
445
+ invokeOnError(key, error, attempt) {
446
+ if (!this.onError) {
447
+ return;
448
+ }
449
+ try {
450
+ this.onError(key, error, attempt);
451
+ }
452
+ catch {
453
+ return;
454
+ }
455
+ }
456
+ invokeOnPressure(pendingKeys) {
457
+ if (!this.onPressure) {
458
+ return;
459
+ }
460
+ try {
461
+ this.onPressure(pendingKeys);
462
+ }
463
+ catch {
464
+ return;
465
+ }
466
+ }
467
+ invokeOnDiscard(key, value) {
468
+ if (!this.onDiscard) {
469
+ return;
470
+ }
471
+ try {
472
+ this.onDiscard(key, value);
473
+ }
474
+ catch {
475
+ return;
476
+ }
477
+ }
478
+ }
@@ -7,6 +7,16 @@ export class BoundedTaskQueueFullError extends Error {
7
7
  }
8
8
  export class BoundedTaskQueue {
9
9
  constructor(maxQueueSize = 256, maxConcurrency = 1) {
10
+ this.settleTask = () => {
11
+ this.running--;
12
+ if (this.head >= 1024 && this.head * 2 >= this.queue.length) {
13
+ const remaining = this.queue.length - this.head;
14
+ this.queue.copyWithin(0, this.head);
15
+ this.queue.length = remaining;
16
+ this.head = 0;
17
+ }
18
+ this.drain();
19
+ };
10
20
  if (maxQueueSize <= 0) {
11
21
  throw new Error('maxQueueSize must be > 0');
12
22
  }
@@ -25,8 +35,8 @@ export class BoundedTaskQueue {
25
35
  }
26
36
  return new Promise((resolve, reject) => {
27
37
  this.queue.push({
28
- task,
29
- resolve: (value) => resolve(value),
38
+ task: task,
39
+ resolve: resolve,
30
40
  reject
31
41
  });
32
42
  this.drain();
@@ -40,23 +50,11 @@ export class BoundedTaskQueue {
40
50
  }
41
51
  drain() {
42
52
  while (this.running < this.maxConcurrency && this.head < this.queue.length) {
43
- const item = this.queue[this.head++];
53
+ const item = this.queue[this.head];
54
+ this.queue[this.head] = null;
55
+ this.head++;
44
56
  this.running++;
45
- item.task()
46
- .then(item.resolve)
47
- .catch(item.reject)
48
- .finally(() => {
49
- this.running--;
50
- this.compactIfNeeded();
51
- this.drain();
52
- });
57
+ void item.task().then(item.resolve, item.reject).finally(this.settleTask);
53
58
  }
54
59
  }
55
- compactIfNeeded() {
56
- if (this.head < 1024 || this.head * 2 < this.queue.length) {
57
- return;
58
- }
59
- this.queue.splice(0, this.head);
60
- this.head = 0;
61
- }
62
60
  }
@@ -0,0 +1,20 @@
1
+ export class PromiseDedup {
2
+ constructor() {
3
+ this.inFlight = new Map();
4
+ }
5
+ run(key, task) {
6
+ const existing = this.inFlight.get(key);
7
+ if (existing) {
8
+ return existing;
9
+ }
10
+ const created = Promise.resolve()
11
+ .then(() => task())
12
+ .finally(() => {
13
+ if (this.inFlight.get(key) === created) {
14
+ this.inFlight.delete(key);
15
+ }
16
+ });
17
+ this.inFlight.set(key, created);
18
+ return created;
19
+ }
20
+ }