@zapo-js/fake-server 0.3.0 → 1.1.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 (301) hide show
  1. package/README.md +96 -8
  2. package/dist/api/AppStateSyncManager.d.ts +0 -1
  3. package/dist/api/AppStateSyncManager.js +0 -1
  4. package/dist/api/FakePairingDriver.d.ts +0 -1
  5. package/dist/api/FakePairingDriver.js +0 -1
  6. package/dist/api/FakePeer.d.ts +77 -4
  7. package/dist/api/FakePeer.js +208 -2
  8. package/dist/api/FakeServerSession.d.ts +67 -0
  9. package/dist/api/FakeServerSession.js +293 -0
  10. package/dist/api/FakeWaServer.d.ts +77 -31
  11. package/dist/api/FakeWaServer.js +140 -259
  12. package/dist/api/PreKeyDispenser.d.ts +0 -1
  13. package/dist/api/PreKeyDispenser.js +0 -1
  14. package/dist/api/Scenario.d.ts +0 -1
  15. package/dist/api/Scenario.js +0 -1
  16. package/dist/api/ServerRegistries.d.ts +0 -1
  17. package/dist/api/ServerRegistries.js +0 -1
  18. package/dist/api/iq-handlers.d.ts +1 -1
  19. package/dist/api/iq-handlers.js +23 -1
  20. package/dist/{cli.d.ts → bin.d.ts} +0 -1
  21. package/dist/bin.js +296 -0
  22. package/dist/esm/api/AppStateSyncManager.js +146 -0
  23. package/dist/esm/api/FakePairingDriver.js +31 -0
  24. package/dist/esm/api/FakePeer.js +610 -0
  25. package/dist/esm/api/FakeServerSession.js +287 -0
  26. package/dist/esm/api/FakeWaServer.js +528 -0
  27. package/dist/esm/api/PreKeyDispenser.js +93 -0
  28. package/dist/esm/api/Scenario.js +32 -0
  29. package/dist/esm/api/ServerRegistries.js +261 -0
  30. package/dist/esm/api/iq-handlers.js +515 -0
  31. package/dist/{cli.js → esm/bin.js} +70 -25
  32. package/dist/esm/index.js +26 -0
  33. package/dist/esm/infra/WaFakeConnection.js +49 -0
  34. package/dist/esm/infra/WaFakeConnectionPipeline.js +235 -0
  35. package/dist/esm/infra/WaFakeFrameSocket.js +117 -0
  36. package/dist/esm/infra/WaFakeMediaHttpsServer.js +126 -0
  37. package/dist/esm/infra/WaFakeNoiseHandshake.js +67 -0
  38. package/dist/esm/infra/WaFakeTransport.js +31 -0
  39. package/dist/esm/infra/WaFakeWsServer.js +96 -0
  40. package/dist/esm/package.json +3 -0
  41. package/dist/esm/protocol/auth/cert-chain.js +50 -0
  42. package/dist/esm/protocol/auth/client-payload-validate.js +55 -0
  43. package/dist/esm/protocol/auth/fake-primary-device.js +47 -0
  44. package/dist/esm/protocol/auth/pair-device.js +87 -0
  45. package/dist/esm/protocol/auth/success-node.js +26 -0
  46. package/dist/esm/protocol/iq/abprops.js +30 -0
  47. package/dist/esm/protocol/iq/appstate-sync.js +146 -0
  48. package/dist/esm/protocol/iq/business.js +59 -0
  49. package/dist/esm/protocol/iq/dirty-bits.js +19 -0
  50. package/dist/esm/protocol/iq/group-ops.js +154 -0
  51. package/dist/esm/protocol/iq/newsletter.js +14 -0
  52. package/dist/esm/protocol/iq/prekey-fetch.js +88 -0
  53. package/dist/esm/protocol/iq/privacy-token.js +26 -0
  54. package/dist/esm/protocol/iq/privacy.js +123 -0
  55. package/dist/esm/protocol/iq/profile.js +72 -0
  56. package/dist/esm/protocol/iq/router.js +117 -0
  57. package/dist/esm/protocol/iq/usync.js +64 -0
  58. package/dist/esm/protocol/push/app-state-key-share.js +26 -0
  59. package/dist/esm/protocol/push/call-failure.js +27 -0
  60. package/dist/esm/protocol/push/chatstate.js +23 -0
  61. package/dist/esm/protocol/push/error-stanza.js +13 -0
  62. package/dist/esm/protocol/push/history-sync.js +111 -0
  63. package/dist/esm/protocol/push/message.js +38 -0
  64. package/dist/esm/protocol/push/notification.js +29 -0
  65. package/dist/esm/protocol/push/presence.js +14 -0
  66. package/dist/esm/protocol/push/receipt.js +21 -0
  67. package/dist/esm/protocol/signal/fake-app-state-crypto.js +196 -0
  68. package/dist/esm/protocol/signal/fake-peer-double-ratchet.js +398 -0
  69. package/dist/esm/protocol/signal/fake-peer-group-recv-session.js +120 -0
  70. package/dist/esm/protocol/signal/fake-peer-identity.js +8 -0
  71. package/dist/esm/protocol/signal/fake-peer-key-bundle.js +25 -0
  72. package/dist/esm/protocol/signal/fake-sender-key.js +83 -0
  73. package/dist/esm/protocol/signal/prekey-upload.js +107 -0
  74. package/dist/esm/protocol/stream/stream-error.js +56 -0
  75. package/dist/esm/state/fake-app-state-collection.js +134 -0
  76. package/dist/esm/state/fake-media-store.js +53 -0
  77. package/dist/esm/transport/codec.js +8 -0
  78. package/dist/esm/transport/crypto.js +8 -0
  79. package/dist/esm/transport/protos.js +7 -0
  80. package/dist/esm/transport/util.js +8 -0
  81. package/dist/index.d.ts +2 -3
  82. package/dist/index.js +2 -2
  83. package/dist/infra/WaFakeConnection.d.ts +0 -1
  84. package/dist/infra/WaFakeConnection.js +0 -1
  85. package/dist/infra/WaFakeConnectionPipeline.d.ts +10 -3
  86. package/dist/infra/WaFakeConnectionPipeline.js +47 -32
  87. package/dist/infra/WaFakeFrameSocket.d.ts +0 -1
  88. package/dist/infra/WaFakeFrameSocket.js +0 -1
  89. package/dist/infra/WaFakeMediaHttpsServer.d.ts +0 -1
  90. package/dist/infra/WaFakeMediaHttpsServer.js +0 -1
  91. package/dist/infra/WaFakeNoiseHandshake.d.ts +8 -10
  92. package/dist/infra/WaFakeNoiseHandshake.js +19 -24
  93. package/dist/infra/WaFakeTransport.d.ts +2 -4
  94. package/dist/infra/WaFakeTransport.js +2 -1
  95. package/dist/infra/WaFakeWsServer.d.ts +0 -1
  96. package/dist/infra/WaFakeWsServer.js +0 -1
  97. package/dist/protocol/auth/cert-chain.d.ts +4 -1
  98. package/dist/protocol/auth/cert-chain.js +13 -3
  99. package/dist/protocol/auth/client-payload-validate.d.ts +0 -1
  100. package/dist/protocol/auth/client-payload-validate.js +0 -1
  101. package/dist/protocol/auth/fake-primary-device.d.ts +0 -1
  102. package/dist/protocol/auth/fake-primary-device.js +1 -3
  103. package/dist/protocol/auth/pair-device.d.ts +0 -1
  104. package/dist/protocol/auth/pair-device.js +4 -16
  105. package/dist/protocol/auth/success-node.d.ts +0 -1
  106. package/dist/protocol/auth/success-node.js +0 -1
  107. package/dist/protocol/iq/abprops.d.ts +0 -1
  108. package/dist/protocol/iq/abprops.js +0 -1
  109. package/dist/protocol/iq/appstate-sync.d.ts +0 -1
  110. package/dist/protocol/iq/appstate-sync.js +0 -1
  111. package/dist/protocol/iq/business.d.ts +0 -1
  112. package/dist/protocol/iq/business.js +0 -1
  113. package/dist/protocol/iq/dirty-bits.d.ts +0 -1
  114. package/dist/protocol/iq/dirty-bits.js +0 -1
  115. package/dist/protocol/iq/group-ops.d.ts +0 -1
  116. package/dist/protocol/iq/group-ops.js +0 -1
  117. package/dist/protocol/iq/newsletter.d.ts +0 -1
  118. package/dist/protocol/iq/newsletter.js +0 -1
  119. package/dist/protocol/iq/prekey-fetch.d.ts +0 -1
  120. package/dist/protocol/iq/prekey-fetch.js +0 -1
  121. package/dist/protocol/iq/privacy-token.d.ts +0 -1
  122. package/dist/protocol/iq/privacy-token.js +0 -1
  123. package/dist/protocol/iq/privacy.d.ts +0 -1
  124. package/dist/protocol/iq/privacy.js +15 -16
  125. package/dist/protocol/iq/profile.d.ts +0 -1
  126. package/dist/protocol/iq/profile.js +0 -1
  127. package/dist/protocol/iq/router.d.ts +7 -2
  128. package/dist/protocol/iq/router.js +8 -3
  129. package/dist/protocol/iq/usync.d.ts +0 -1
  130. package/dist/protocol/iq/usync.js +0 -1
  131. package/dist/protocol/push/app-state-key-share.d.ts +0 -1
  132. package/dist/protocol/push/app-state-key-share.js +0 -1
  133. package/dist/protocol/push/call-failure.d.ts +0 -1
  134. package/dist/protocol/push/call-failure.js +0 -1
  135. package/dist/protocol/push/chatstate.d.ts +0 -1
  136. package/dist/protocol/push/chatstate.js +0 -1
  137. package/dist/protocol/push/error-stanza.d.ts +0 -1
  138. package/dist/protocol/push/error-stanza.js +0 -1
  139. package/dist/protocol/push/history-sync.d.ts +0 -1
  140. package/dist/protocol/push/history-sync.js +0 -1
  141. package/dist/protocol/push/message.d.ts +0 -1
  142. package/dist/protocol/push/message.js +0 -1
  143. package/dist/protocol/push/notification.d.ts +0 -1
  144. package/dist/protocol/push/notification.js +0 -1
  145. package/dist/protocol/push/presence.d.ts +0 -1
  146. package/dist/protocol/push/presence.js +0 -1
  147. package/dist/protocol/push/receipt.d.ts +0 -1
  148. package/dist/protocol/push/receipt.js +0 -1
  149. package/dist/protocol/signal/fake-app-state-crypto.d.ts +7 -9
  150. package/dist/protocol/signal/fake-app-state-crypto.js +31 -33
  151. package/dist/protocol/signal/fake-peer-double-ratchet.d.ts +0 -1
  152. package/dist/protocol/signal/fake-peer-double-ratchet.js +23 -28
  153. package/dist/protocol/signal/fake-peer-group-recv-session.d.ts +0 -1
  154. package/dist/protocol/signal/fake-peer-group-recv-session.js +6 -10
  155. package/dist/protocol/signal/fake-peer-identity.d.ts +0 -1
  156. package/dist/protocol/signal/fake-peer-identity.js +0 -1
  157. package/dist/protocol/signal/fake-peer-key-bundle.d.ts +0 -1
  158. package/dist/protocol/signal/fake-peer-key-bundle.js +0 -1
  159. package/dist/protocol/signal/fake-sender-key.d.ts +0 -1
  160. package/dist/protocol/signal/fake-sender-key.js +5 -9
  161. package/dist/protocol/signal/prekey-upload.d.ts +0 -1
  162. package/dist/protocol/signal/prekey-upload.js +0 -1
  163. package/dist/protocol/stream/stream-error.d.ts +0 -1
  164. package/dist/protocol/stream/stream-error.js +0 -1
  165. package/dist/state/fake-app-state-collection.d.ts +0 -1
  166. package/dist/state/fake-app-state-collection.js +0 -1
  167. package/dist/state/fake-media-store.d.ts +0 -1
  168. package/dist/state/fake-media-store.js +2 -2
  169. package/dist/transport/codec.d.ts +2 -3
  170. package/dist/transport/codec.js +2 -3
  171. package/dist/transport/crypto.d.ts +5 -7
  172. package/dist/transport/crypto.js +6 -11
  173. package/dist/transport/protos.d.ts +2 -4
  174. package/dist/transport/protos.js +2 -4
  175. package/dist/transport/util.d.ts +8 -0
  176. package/dist/transport/util.js +16 -0
  177. package/package.json +26 -6
  178. package/dist/api/AppStateSyncManager.d.ts.map +0 -1
  179. package/dist/api/AppStateSyncManager.js.map +0 -1
  180. package/dist/api/FakePairingDriver.d.ts.map +0 -1
  181. package/dist/api/FakePairingDriver.js.map +0 -1
  182. package/dist/api/FakePeer.d.ts.map +0 -1
  183. package/dist/api/FakePeer.js.map +0 -1
  184. package/dist/api/FakeWaServer.d.ts.map +0 -1
  185. package/dist/api/FakeWaServer.js.map +0 -1
  186. package/dist/api/PreKeyDispenser.d.ts.map +0 -1
  187. package/dist/api/PreKeyDispenser.js.map +0 -1
  188. package/dist/api/Scenario.d.ts.map +0 -1
  189. package/dist/api/Scenario.js.map +0 -1
  190. package/dist/api/ServerRegistries.d.ts.map +0 -1
  191. package/dist/api/ServerRegistries.js.map +0 -1
  192. package/dist/api/iq-handlers.d.ts.map +0 -1
  193. package/dist/api/iq-handlers.js.map +0 -1
  194. package/dist/cli.d.ts.map +0 -1
  195. package/dist/cli.js.map +0 -1
  196. package/dist/index.d.ts.map +0 -1
  197. package/dist/index.js.map +0 -1
  198. package/dist/infra/WaFakeConnection.d.ts.map +0 -1
  199. package/dist/infra/WaFakeConnection.js.map +0 -1
  200. package/dist/infra/WaFakeConnectionPipeline.d.ts.map +0 -1
  201. package/dist/infra/WaFakeConnectionPipeline.js.map +0 -1
  202. package/dist/infra/WaFakeFrameSocket.d.ts.map +0 -1
  203. package/dist/infra/WaFakeFrameSocket.js.map +0 -1
  204. package/dist/infra/WaFakeMediaHttpsServer.d.ts.map +0 -1
  205. package/dist/infra/WaFakeMediaHttpsServer.js.map +0 -1
  206. package/dist/infra/WaFakeNoiseHandshake.d.ts.map +0 -1
  207. package/dist/infra/WaFakeNoiseHandshake.js.map +0 -1
  208. package/dist/infra/WaFakeTransport.d.ts.map +0 -1
  209. package/dist/infra/WaFakeTransport.js.map +0 -1
  210. package/dist/infra/WaFakeWsServer.d.ts.map +0 -1
  211. package/dist/infra/WaFakeWsServer.js.map +0 -1
  212. package/dist/protocol/auth/cert-chain.d.ts.map +0 -1
  213. package/dist/protocol/auth/cert-chain.js.map +0 -1
  214. package/dist/protocol/auth/client-payload-validate.d.ts.map +0 -1
  215. package/dist/protocol/auth/client-payload-validate.js.map +0 -1
  216. package/dist/protocol/auth/fake-primary-device.d.ts.map +0 -1
  217. package/dist/protocol/auth/fake-primary-device.js.map +0 -1
  218. package/dist/protocol/auth/pair-device.d.ts.map +0 -1
  219. package/dist/protocol/auth/pair-device.js.map +0 -1
  220. package/dist/protocol/auth/success-node.d.ts.map +0 -1
  221. package/dist/protocol/auth/success-node.js.map +0 -1
  222. package/dist/protocol/iq/abprops.d.ts.map +0 -1
  223. package/dist/protocol/iq/abprops.js.map +0 -1
  224. package/dist/protocol/iq/appstate-sync.d.ts.map +0 -1
  225. package/dist/protocol/iq/appstate-sync.js.map +0 -1
  226. package/dist/protocol/iq/business.d.ts.map +0 -1
  227. package/dist/protocol/iq/business.js.map +0 -1
  228. package/dist/protocol/iq/dirty-bits.d.ts.map +0 -1
  229. package/dist/protocol/iq/dirty-bits.js.map +0 -1
  230. package/dist/protocol/iq/group-ops.d.ts.map +0 -1
  231. package/dist/protocol/iq/group-ops.js.map +0 -1
  232. package/dist/protocol/iq/newsletter.d.ts.map +0 -1
  233. package/dist/protocol/iq/newsletter.js.map +0 -1
  234. package/dist/protocol/iq/prekey-fetch.d.ts.map +0 -1
  235. package/dist/protocol/iq/prekey-fetch.js.map +0 -1
  236. package/dist/protocol/iq/privacy-token.d.ts.map +0 -1
  237. package/dist/protocol/iq/privacy-token.js.map +0 -1
  238. package/dist/protocol/iq/privacy.d.ts.map +0 -1
  239. package/dist/protocol/iq/privacy.js.map +0 -1
  240. package/dist/protocol/iq/profile.d.ts.map +0 -1
  241. package/dist/protocol/iq/profile.js.map +0 -1
  242. package/dist/protocol/iq/router.d.ts.map +0 -1
  243. package/dist/protocol/iq/router.js.map +0 -1
  244. package/dist/protocol/iq/usync.d.ts.map +0 -1
  245. package/dist/protocol/iq/usync.js.map +0 -1
  246. package/dist/protocol/push/app-state-key-share.d.ts.map +0 -1
  247. package/dist/protocol/push/app-state-key-share.js.map +0 -1
  248. package/dist/protocol/push/call-failure.d.ts.map +0 -1
  249. package/dist/protocol/push/call-failure.js.map +0 -1
  250. package/dist/protocol/push/chatstate.d.ts.map +0 -1
  251. package/dist/protocol/push/chatstate.js.map +0 -1
  252. package/dist/protocol/push/error-stanza.d.ts.map +0 -1
  253. package/dist/protocol/push/error-stanza.js.map +0 -1
  254. package/dist/protocol/push/history-sync.d.ts.map +0 -1
  255. package/dist/protocol/push/history-sync.js.map +0 -1
  256. package/dist/protocol/push/message.d.ts.map +0 -1
  257. package/dist/protocol/push/message.js.map +0 -1
  258. package/dist/protocol/push/notification.d.ts.map +0 -1
  259. package/dist/protocol/push/notification.js.map +0 -1
  260. package/dist/protocol/push/presence.d.ts.map +0 -1
  261. package/dist/protocol/push/presence.js.map +0 -1
  262. package/dist/protocol/push/receipt.d.ts.map +0 -1
  263. package/dist/protocol/push/receipt.js.map +0 -1
  264. package/dist/protocol/signal/fake-app-state-crypto.d.ts.map +0 -1
  265. package/dist/protocol/signal/fake-app-state-crypto.js.map +0 -1
  266. package/dist/protocol/signal/fake-peer-double-ratchet.d.ts.map +0 -1
  267. package/dist/protocol/signal/fake-peer-double-ratchet.js.map +0 -1
  268. package/dist/protocol/signal/fake-peer-group-recv-session.d.ts.map +0 -1
  269. package/dist/protocol/signal/fake-peer-group-recv-session.js.map +0 -1
  270. package/dist/protocol/signal/fake-peer-identity.d.ts.map +0 -1
  271. package/dist/protocol/signal/fake-peer-identity.js.map +0 -1
  272. package/dist/protocol/signal/fake-peer-key-bundle.d.ts.map +0 -1
  273. package/dist/protocol/signal/fake-peer-key-bundle.js.map +0 -1
  274. package/dist/protocol/signal/fake-peer-recv-session.d.ts +0 -60
  275. package/dist/protocol/signal/fake-peer-recv-session.d.ts.map +0 -1
  276. package/dist/protocol/signal/fake-peer-recv-session.js +0 -284
  277. package/dist/protocol/signal/fake-peer-recv-session.js.map +0 -1
  278. package/dist/protocol/signal/fake-peer-session.d.ts +0 -87
  279. package/dist/protocol/signal/fake-peer-session.d.ts.map +0 -1
  280. package/dist/protocol/signal/fake-peer-session.js +0 -207
  281. package/dist/protocol/signal/fake-peer-session.js.map +0 -1
  282. package/dist/protocol/signal/fake-sender-key.d.ts.map +0 -1
  283. package/dist/protocol/signal/fake-sender-key.js.map +0 -1
  284. package/dist/protocol/signal/prekey-upload.d.ts.map +0 -1
  285. package/dist/protocol/signal/prekey-upload.js.map +0 -1
  286. package/dist/protocol/stream/stream-error.d.ts.map +0 -1
  287. package/dist/protocol/stream/stream-error.js.map +0 -1
  288. package/dist/state/fake-app-state-collection.d.ts.map +0 -1
  289. package/dist/state/fake-app-state-collection.js.map +0 -1
  290. package/dist/state/fake-media-store.d.ts.map +0 -1
  291. package/dist/state/fake-media-store.js.map +0 -1
  292. package/dist/transport/codec.d.ts.map +0 -1
  293. package/dist/transport/codec.js.map +0 -1
  294. package/dist/transport/crypto.d.ts.map +0 -1
  295. package/dist/transport/crypto.js.map +0 -1
  296. package/dist/transport/index.d.ts +0 -4
  297. package/dist/transport/index.d.ts.map +0 -1
  298. package/dist/transport/index.js +0 -20
  299. package/dist/transport/index.js.map +0 -1
  300. package/dist/transport/protos.d.ts.map +0 -1
  301. package/dist/transport/protos.js.map +0 -1
@@ -0,0 +1,287 @@
1
+ /** Per-session isolated server state: registries, prekeys, app-state, IQ routing, capture. */
2
+ import { WaFakeIqRouter } from '../protocol/iq/router.js';
3
+ import { AppStateSyncManager } from './AppStateSyncManager.js';
4
+ import { registerDefaultIqHandlers } from './iq-handlers.js';
5
+ import { PreKeyDispenser } from './PreKeyDispenser.js';
6
+ import { ServerRegistries } from './ServerRegistries.js';
7
+ /**
8
+ * One isolated logical device's worth of server state. Every `WaClient`
9
+ * connected to a `FakeWaServer` is bound to exactly one session; peers,
10
+ * groups, privacy, prekeys, app-state, and captured stanzas never leak across
11
+ * sessions. A single-client server uses one default session, which is why the
12
+ * legacy `FakeWaServer` surface delegates straight through to it.
13
+ */
14
+ export class FakeServerSession {
15
+ constructor(id, host, options) {
16
+ this.registries = new ServerRegistries();
17
+ this.preKeyDispenser = new PreKeyDispenser();
18
+ this.appStateSync = new AppStateSyncManager();
19
+ this.iqRouter = new WaFakeIqRouter();
20
+ this.capturedStanzas = [];
21
+ this.pendingIqExpectations = new Set();
22
+ this.pendingStanzaExpectations = new Set();
23
+ this.capturedStanzaListeners = new Set();
24
+ this.inboundStanzaListeners = new Set();
25
+ this.id = id;
26
+ if (options.defaultIqHandlers) {
27
+ registerDefaultIqHandlers(this.iqRouter, this.buildIqHandlerDeps(host));
28
+ }
29
+ }
30
+ registerIqHandler(matcher, respond, label) {
31
+ const handler = { matcher, respond, label };
32
+ return this.iqRouter.register(handler, { priority: 'high' });
33
+ }
34
+ routeIq(iq) {
35
+ return this.iqRouter.route(iq);
36
+ }
37
+ handleCapturedStanza(node) {
38
+ this.capturedStanzas.push(node);
39
+ for (const listener of this.capturedStanzaListeners) {
40
+ try {
41
+ listener(node);
42
+ }
43
+ catch (error) {
44
+ void error;
45
+ }
46
+ }
47
+ for (const listener of this.inboundStanzaListeners) {
48
+ try {
49
+ listener(node);
50
+ }
51
+ catch (error) {
52
+ void error;
53
+ }
54
+ }
55
+ for (const expectation of this.pendingStanzaExpectations) {
56
+ if (matchesStanza(node, expectation.matcher)) {
57
+ expectation.resolve(node);
58
+ break;
59
+ }
60
+ }
61
+ if (node.tag !== 'iq') {
62
+ return;
63
+ }
64
+ for (const expectation of this.pendingIqExpectations) {
65
+ if (matchesIq(node, expectation.matcher)) {
66
+ expectation.resolve(node);
67
+ return;
68
+ }
69
+ }
70
+ }
71
+ subscribeInboundMessages(listener) {
72
+ const wrapped = (node) => {
73
+ if (node.tag !== 'message')
74
+ return;
75
+ listener(node);
76
+ };
77
+ this.inboundStanzaListeners.add(wrapped);
78
+ return () => {
79
+ this.inboundStanzaListeners.delete(wrapped);
80
+ };
81
+ }
82
+ onCapturedStanza(listener) {
83
+ this.capturedStanzaListeners.add(listener);
84
+ return () => {
85
+ this.capturedStanzaListeners.delete(listener);
86
+ };
87
+ }
88
+ capturedStanzaSnapshot() {
89
+ return this.capturedStanzas.slice();
90
+ }
91
+ expectIq(matcher, options = {}) {
92
+ const timeoutMs = options.timeoutMs ?? 2000;
93
+ for (const captured of this.capturedStanzas) {
94
+ if (matchesIq(captured, matcher)) {
95
+ return Promise.resolve(captured);
96
+ }
97
+ }
98
+ return new Promise((resolve, reject) => {
99
+ const expectation = {
100
+ matcher,
101
+ resolve: (iq) => {
102
+ this.pendingIqExpectations.delete(expectation);
103
+ clearTimeout(expectation.timer);
104
+ resolve(iq);
105
+ },
106
+ reject: (error) => {
107
+ this.pendingIqExpectations.delete(expectation);
108
+ clearTimeout(expectation.timer);
109
+ reject(error);
110
+ },
111
+ timer: setTimeout(() => {
112
+ this.pendingIqExpectations.delete(expectation);
113
+ reject(new Error(`expectIq timed out after ${timeoutMs}ms (${describeMatcher(matcher)})`));
114
+ }, timeoutMs)
115
+ };
116
+ this.pendingIqExpectations.add(expectation);
117
+ });
118
+ }
119
+ expectStanza(matcher, options = {}) {
120
+ const timeoutMs = options.timeoutMs ?? 2000;
121
+ for (const captured of this.capturedStanzas) {
122
+ if (matchesStanza(captured, matcher)) {
123
+ return Promise.resolve(captured);
124
+ }
125
+ }
126
+ return new Promise((resolve, reject) => {
127
+ const expectation = {
128
+ matcher,
129
+ resolve: (node) => {
130
+ this.pendingStanzaExpectations.delete(expectation);
131
+ clearTimeout(expectation.timer);
132
+ resolve(node);
133
+ },
134
+ reject: (error) => {
135
+ this.pendingStanzaExpectations.delete(expectation);
136
+ clearTimeout(expectation.timer);
137
+ reject(error);
138
+ },
139
+ timer: setTimeout(() => {
140
+ this.pendingStanzaExpectations.delete(expectation);
141
+ reject(new Error(`expectStanza timed out after ${timeoutMs}ms (${describeStanzaMatcher(matcher)})`));
142
+ }, timeoutMs)
143
+ };
144
+ this.pendingStanzaExpectations.add(expectation);
145
+ });
146
+ }
147
+ buildIqHandlerDeps(host) {
148
+ const reg = this.registries;
149
+ const preKey = this.preKeyDispenser;
150
+ const appState = this.appStateSync;
151
+ return {
152
+ get peerRegistry() {
153
+ return reg.peerRegistry;
154
+ },
155
+ get groupRegistry() {
156
+ return reg.groupRegistry;
157
+ },
158
+ get privacySettings() {
159
+ return reg.privacySettings;
160
+ },
161
+ get blocklistJids() {
162
+ return reg.blocklistJids;
163
+ },
164
+ get profilePicturesByJid() {
165
+ return reg.profilePicturesByJid;
166
+ },
167
+ get businessProfilesByJid() {
168
+ return reg.businessProfilesByJid;
169
+ },
170
+ get abPropsInput() {
171
+ return reg.abPropsInput;
172
+ },
173
+ get issuedPrivacyTokens() {
174
+ return reg.issuedPrivacyTokens;
175
+ },
176
+ get latestStatusText() {
177
+ return reg.latestStatusText;
178
+ },
179
+ setLatestStatusText: (text) => {
180
+ reg.latestStatusText = text;
181
+ },
182
+ lookupDeviceIdsForUser: (userJid) => reg.lookupDeviceIdsForUser(userJid),
183
+ notifyGroupOp: (op) => reg.notifyGroupOp(op),
184
+ mutatePrivacySettings: (category, value) => reg.mutatePrivacySettings(category, value),
185
+ mutateBlocklist: (action, jid) => reg.mutateBlocklist(action, jid),
186
+ notifyProfilePictureSet: (op) => reg.notifyProfilePictureSet(op),
187
+ handleProfilePictureSet: (targetJid, newId) => reg.handleProfilePictureSet(targetJid, newId),
188
+ notifyStatusSet: (text) => reg.notifyStatusSet(text),
189
+ notifyLogout: () => reg.notifyLogout(),
190
+ notifyPrivacyTokenIssue: (token) => reg.notifyPrivacyTokenIssue(token),
191
+ notifyDirtyBitsClear: (op) => reg.notifyDirtyBitsClear(op),
192
+ notifyPrivacySet: (change) => {
193
+ for (const listener of reg.privacySetListeners) {
194
+ try {
195
+ listener(change);
196
+ }
197
+ catch (error) {
198
+ void error;
199
+ }
200
+ }
201
+ },
202
+ notifyBlocklistChange: (change) => {
203
+ for (const listener of reg.blocklistChangeListeners) {
204
+ try {
205
+ listener(change);
206
+ }
207
+ catch (error) {
208
+ void error;
209
+ }
210
+ }
211
+ },
212
+ capturePreKeyBundle: (bundle) => preKey.captureBundle(bundle),
213
+ countServerPreKeys: () => preKey.preKeysAvailable(),
214
+ consumeOutboundAppStatePatches: (iq) => appState.consumeOutboundAppStatePatches(iq),
215
+ get appStateCollectionProviders() {
216
+ return appState.appStateCollectionProviders;
217
+ },
218
+ requireMediaHttpsInfo: () => host.requireMediaHttpsInfo()
219
+ };
220
+ }
221
+ }
222
+ export function matchesIq(iq, matcher) {
223
+ if (iq.tag !== 'iq')
224
+ return false;
225
+ if (matcher.id !== undefined && iq.attrs.id !== matcher.id)
226
+ return false;
227
+ if (matcher.type !== undefined && iq.attrs.type !== matcher.type)
228
+ return false;
229
+ if (matcher.xmlns !== undefined && iq.attrs.xmlns !== matcher.xmlns)
230
+ return false;
231
+ if (matcher.childTag !== undefined) {
232
+ const children = Array.isArray(iq.content) ? iq.content : null;
233
+ if (!children || children.length === 0)
234
+ return false;
235
+ if (children[0].tag !== matcher.childTag)
236
+ return false;
237
+ }
238
+ return true;
239
+ }
240
+ function describeMatcher(matcher) {
241
+ const parts = [];
242
+ if (matcher.id !== undefined)
243
+ parts.push(`id=${matcher.id}`);
244
+ if (matcher.type !== undefined)
245
+ parts.push(`type=${matcher.type}`);
246
+ if (matcher.xmlns !== undefined)
247
+ parts.push(`xmlns=${matcher.xmlns}`);
248
+ if (matcher.childTag !== undefined)
249
+ parts.push(`childTag=${matcher.childTag}`);
250
+ return parts.length > 0 ? parts.join(', ') : 'any iq';
251
+ }
252
+ export function matchesStanza(node, matcher) {
253
+ if (matcher.tag !== undefined && node.tag !== matcher.tag)
254
+ return false;
255
+ if (matcher.type !== undefined && node.attrs.type !== matcher.type)
256
+ return false;
257
+ if (matcher.xmlns !== undefined && node.attrs.xmlns !== matcher.xmlns)
258
+ return false;
259
+ if (matcher.from !== undefined && node.attrs.from !== matcher.from)
260
+ return false;
261
+ if (matcher.to !== undefined && node.attrs.to !== matcher.to)
262
+ return false;
263
+ if (matcher.childTag !== undefined) {
264
+ const children = Array.isArray(node.content) ? node.content : null;
265
+ if (!children || children.length === 0)
266
+ return false;
267
+ if (children[0].tag !== matcher.childTag)
268
+ return false;
269
+ }
270
+ return true;
271
+ }
272
+ function describeStanzaMatcher(matcher) {
273
+ const parts = [];
274
+ if (matcher.tag !== undefined)
275
+ parts.push(`tag=${matcher.tag}`);
276
+ if (matcher.type !== undefined)
277
+ parts.push(`type=${matcher.type}`);
278
+ if (matcher.xmlns !== undefined)
279
+ parts.push(`xmlns=${matcher.xmlns}`);
280
+ if (matcher.from !== undefined)
281
+ parts.push(`from=${matcher.from}`);
282
+ if (matcher.to !== undefined)
283
+ parts.push(`to=${matcher.to}`);
284
+ if (matcher.childTag !== undefined)
285
+ parts.push(`childTag=${matcher.childTag}`);
286
+ return parts.length > 0 ? parts.join(', ') : 'any stanza';
287
+ }