@japofc/baileys 2.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 (342) hide show
  1. package/NOTICE.md +111 -0
  2. package/README.md +1254 -0
  3. package/WAProto/index.d.ts +9 -0
  4. package/WAProto/index.js +142276 -0
  5. package/engine-requirements.js +13 -0
  6. package/lib/Builders/A2UI.d.ts +242 -0
  7. package/lib/Builders/A2UI.js +308 -0
  8. package/lib/Builders/AIRich.d.ts +105 -0
  9. package/lib/Builders/AIRich.js +2286 -0
  10. package/lib/Builders/Button.d.ts +103 -0
  11. package/lib/Builders/Button.js +883 -0
  12. package/lib/Builders/ButtonV2.d.ts +28 -0
  13. package/lib/Builders/ButtonV2.js +144 -0
  14. package/lib/Builders/ButtonV3.d.ts +25 -0
  15. package/lib/Builders/ButtonV3.js +184 -0
  16. package/lib/Builders/Carousel.d.ts +22 -0
  17. package/lib/Builders/Carousel.js +111 -0
  18. package/lib/Builders/JapBaileys.d.ts +34 -0
  19. package/lib/Builders/JapBaileys.js +108 -0
  20. package/lib/Builders/Poll.d.ts +25 -0
  21. package/lib/Builders/Poll.js +128 -0
  22. package/lib/Builders/index.d.ts +17 -0
  23. package/lib/Builders/index.js +11 -0
  24. package/lib/Builders/shared.d.ts +67 -0
  25. package/lib/Builders/shared.js +652 -0
  26. package/lib/Defaults/index.d.ts +154 -0
  27. package/lib/Defaults/index.js +178 -0
  28. package/lib/Framework/Bot.d.ts +61 -0
  29. package/lib/Framework/Bot.js +248 -0
  30. package/lib/Framework/Context.d.ts +21 -0
  31. package/lib/Framework/Context.js +89 -0
  32. package/lib/Framework/MediaManager.d.ts +17 -0
  33. package/lib/Framework/MediaManager.js +151 -0
  34. package/lib/Framework/SessionManager.d.ts +13 -0
  35. package/lib/Framework/SessionManager.js +33 -0
  36. package/lib/Framework/StatsManager.d.ts +26 -0
  37. package/lib/Framework/StatsManager.js +119 -0
  38. package/lib/Framework/Store/SQLiteStore.d.ts +11 -0
  39. package/lib/Framework/Store/SQLiteStore.js +73 -0
  40. package/lib/Framework/index.d.ts +9 -0
  41. package/lib/Framework/index.js +10 -0
  42. package/lib/Signal/Group/ciphertext-message.d.ts +9 -0
  43. package/lib/Signal/Group/ciphertext-message.js +11 -0
  44. package/lib/Signal/Group/group-session-builder.d.ts +7 -0
  45. package/lib/Signal/Group/group-session-builder.js +29 -0
  46. package/lib/Signal/Group/group_cipher.d.ts +10 -0
  47. package/lib/Signal/Group/group_cipher.js +81 -0
  48. package/lib/Signal/Group/index.d.ts +11 -0
  49. package/lib/Signal/Group/index.js +11 -0
  50. package/lib/Signal/Group/keyhelper.d.ts +6 -0
  51. package/lib/Signal/Group/keyhelper.js +17 -0
  52. package/lib/Signal/Group/sender-chain-key.d.ts +13 -0
  53. package/lib/Signal/Group/sender-chain-key.js +25 -0
  54. package/lib/Signal/Group/sender-key-distribution-message.d.ts +16 -0
  55. package/lib/Signal/Group/sender-key-distribution-message.js +62 -0
  56. package/lib/Signal/Group/sender-key-message.d.ts +18 -0
  57. package/lib/Signal/Group/sender-key-message.js +65 -0
  58. package/lib/Signal/Group/sender-key-name.d.ts +11 -0
  59. package/lib/Signal/Group/sender-key-name.js +47 -0
  60. package/lib/Signal/Group/sender-key-record.d.ts +12 -0
  61. package/lib/Signal/Group/sender-key-record.js +40 -0
  62. package/lib/Signal/Group/sender-key-state.d.ts +16 -0
  63. package/lib/Signal/Group/sender-key-state.js +83 -0
  64. package/lib/Signal/Group/sender-message-key.d.ts +11 -0
  65. package/lib/Signal/Group/sender-message-key.js +25 -0
  66. package/lib/Signal/libsignal.d.ts +54 -0
  67. package/lib/Signal/libsignal.js +430 -0
  68. package/lib/Signal/lid-mapping.d.ts +20 -0
  69. package/lib/Signal/lid-mapping.js +276 -0
  70. package/lib/Socket/Client/index.d.ts +2 -0
  71. package/lib/Socket/Client/index.js +2 -0
  72. package/lib/Socket/Client/types.d.ts +5 -0
  73. package/lib/Socket/Client/types.js +10 -0
  74. package/lib/Socket/Client/websocket.d.ts +12 -0
  75. package/lib/Socket/Client/websocket.js +53 -0
  76. package/lib/Socket/business.d.ts +395 -0
  77. package/lib/Socket/business.js +379 -0
  78. package/lib/Socket/chats.d.ts +136 -0
  79. package/lib/Socket/chats.js +1327 -0
  80. package/lib/Socket/communities.d.ts +562 -0
  81. package/lib/Socket/communities.js +439 -0
  82. package/lib/Socket/dugong.d.ts +117 -0
  83. package/lib/Socket/dugong.js +798 -0
  84. package/lib/Socket/groups.d.ts +285 -0
  85. package/lib/Socket/groups.js +354 -0
  86. package/lib/Socket/index.d.ts +585 -0
  87. package/lib/Socket/index.js +52 -0
  88. package/lib/Socket/messages-recv.d.ts +333 -0
  89. package/lib/Socket/messages-recv.js +1781 -0
  90. package/lib/Socket/messages-send.d.ts +353 -0
  91. package/lib/Socket/messages-send.js +1524 -0
  92. package/lib/Socket/mex.d.ts +1 -0
  93. package/lib/Socket/mex.js +41 -0
  94. package/lib/Socket/newsletter.d.ts +286 -0
  95. package/lib/Socket/newsletter.js +364 -0
  96. package/lib/Socket/socket.d.ts +60 -0
  97. package/lib/Socket/socket.js +1012 -0
  98. package/lib/Socket/username.d.ts +82 -0
  99. package/lib/Socket/username.js +159 -0
  100. package/lib/Store/index.d.ts +3 -0
  101. package/lib/Store/index.js +3 -0
  102. package/lib/Store/make-in-memory-store.d.ts +62 -0
  103. package/lib/Store/make-in-memory-store.js +428 -0
  104. package/lib/Store/make-ordered-dictionary.d.ts +12 -0
  105. package/lib/Store/make-ordered-dictionary.js +78 -0
  106. package/lib/Store/object-repository.d.ts +10 -0
  107. package/lib/Store/object-repository.js +23 -0
  108. package/lib/Types/Auth.d.ts +117 -0
  109. package/lib/Types/Auth.js +1 -0
  110. package/lib/Types/Bussines.d.ts +25 -0
  111. package/lib/Types/Call.d.ts +15 -0
  112. package/lib/Types/Call.js +1 -0
  113. package/lib/Types/Chat.d.ts +124 -0
  114. package/lib/Types/Chat.js +7 -0
  115. package/lib/Types/Contact.d.ts +26 -0
  116. package/lib/Types/Contact.js +1 -0
  117. package/lib/Types/Events.d.ts +256 -0
  118. package/lib/Types/Events.js +1 -0
  119. package/lib/Types/GroupMetadata.d.ts +71 -0
  120. package/lib/Types/GroupMetadata.js +1 -0
  121. package/lib/Types/Label.d.ts +5 -0
  122. package/lib/Types/Label.js +24 -0
  123. package/lib/Types/LabelAssociation.d.ts +6 -0
  124. package/lib/Types/LabelAssociation.js +6 -0
  125. package/lib/Types/Message.d.ts +62 -0
  126. package/lib/Types/Message.js +17 -0
  127. package/lib/Types/Mex.d.ts +2 -0
  128. package/lib/Types/Mex.js +38 -0
  129. package/lib/Types/Product.d.ts +79 -0
  130. package/lib/Types/Product.js +1 -0
  131. package/lib/Types/RichType.d.ts +2 -0
  132. package/lib/Types/RichType.js +22 -0
  133. package/lib/Types/Signal.d.ts +87 -0
  134. package/lib/Types/Signal.js +1 -0
  135. package/lib/Types/Socket.d.ts +138 -0
  136. package/lib/Types/Socket.js +1 -0
  137. package/lib/Types/State.d.ts +8 -0
  138. package/lib/Types/State.js +55 -0
  139. package/lib/Types/USync.d.ts +26 -0
  140. package/lib/Types/index.d.ts +68 -0
  141. package/lib/Types/index.js +27 -0
  142. package/lib/Utils/MessageBuilder.d.ts +2 -0
  143. package/lib/Utils/MessageBuilder.js +2 -0
  144. package/lib/Utils/PersistentStore.d.ts +60 -0
  145. package/lib/Utils/PersistentStore.js +592 -0
  146. package/lib/Utils/anti-delete.d.ts +74 -0
  147. package/lib/Utils/anti-delete.js +221 -0
  148. package/lib/Utils/auth-secure.d.ts +86 -0
  149. package/lib/Utils/auth-secure.js +764 -0
  150. package/lib/Utils/auth-utils.d.ts +57 -0
  151. package/lib/Utils/auth-utils.js +306 -0
  152. package/lib/Utils/auto-reply.d.ts +47 -0
  153. package/lib/Utils/auto-reply.js +157 -0
  154. package/lib/Utils/baileys-event-stream.d.ts +8 -0
  155. package/lib/Utils/baileys-event-stream.js +62 -0
  156. package/lib/Utils/browser-utils.d.ts +8 -0
  157. package/lib/Utils/browser-utils.js +27 -0
  158. package/lib/Utils/business.d.ts +49 -0
  159. package/lib/Utils/business.js +239 -0
  160. package/lib/Utils/button-helper-utils.d.ts +53 -0
  161. package/lib/Utils/button-helper-utils.js +312 -0
  162. package/lib/Utils/button-sender.d.ts +54 -0
  163. package/lib/Utils/button-sender.js +822 -0
  164. package/lib/Utils/chat-control.d.ts +159 -0
  165. package/lib/Utils/chat-control.js +230 -0
  166. package/lib/Utils/chat-history-helpers.d.ts +21 -0
  167. package/lib/Utils/chat-history-helpers.js +70 -0
  168. package/lib/Utils/chat-utils.d.ts +407 -0
  169. package/lib/Utils/chat-utils.js +885 -0
  170. package/lib/Utils/companion-reg-client-utils.d.ts +4 -0
  171. package/lib/Utils/companion-reg-client-utils.js +39 -0
  172. package/lib/Utils/crypto.d.ts +41 -0
  173. package/lib/Utils/crypto.js +147 -0
  174. package/lib/Utils/decode-wa-message.d.ts +83 -0
  175. package/lib/Utils/decode-wa-message.js +316 -0
  176. package/lib/Utils/event-buffer.d.ts +12 -0
  177. package/lib/Utils/event-buffer.js +635 -0
  178. package/lib/Utils/generics.d.ts +69 -0
  179. package/lib/Utils/generics.js +438 -0
  180. package/lib/Utils/history-share.d.ts +11 -0
  181. package/lib/Utils/history-share.js +70 -0
  182. package/lib/Utils/history.d.ts +90 -0
  183. package/lib/Utils/history.js +146 -0
  184. package/lib/Utils/humanizer.d.ts +12 -0
  185. package/lib/Utils/humanizer.js +73 -0
  186. package/lib/Utils/identity-change-handler.d.ts +13 -0
  187. package/lib/Utils/identity-change-handler.js +49 -0
  188. package/lib/Utils/index.d.ts +57 -0
  189. package/lib/Utils/index.js +56 -0
  190. package/lib/Utils/jid-tools.d.ts +6 -0
  191. package/lib/Utils/jid-tools.js +77 -0
  192. package/lib/Utils/link-preview.d.ts +12 -0
  193. package/lib/Utils/link-preview.js +84 -0
  194. package/lib/Utils/logger.d.ts +4 -0
  195. package/lib/Utils/logger.js +2 -0
  196. package/lib/Utils/lt-hash.d.ts +12 -0
  197. package/lib/Utils/lt-hash.js +26 -0
  198. package/lib/Utils/make-mutex.d.ts +6 -0
  199. package/lib/Utils/make-mutex.js +32 -0
  200. package/lib/Utils/media-messages.d.ts +18 -0
  201. package/lib/Utils/media-messages.js +70 -0
  202. package/lib/Utils/media-set.d.ts +13 -0
  203. package/lib/Utils/media-set.js +171 -0
  204. package/lib/Utils/message-kind.d.ts +32 -0
  205. package/lib/Utils/message-kind.js +136 -0
  206. package/lib/Utils/message-retry-manager.d.ts +79 -0
  207. package/lib/Utils/message-retry-manager.js +264 -0
  208. package/lib/Utils/message-search.d.ts +44 -0
  209. package/lib/Utils/message-search.js +188 -0
  210. package/lib/Utils/messages-media.d.ts +135 -0
  211. package/lib/Utils/messages-media.js +868 -0
  212. package/lib/Utils/messages.d.ts +44 -0
  213. package/lib/Utils/messages.js +2326 -0
  214. package/lib/Utils/meta-ai.d.ts +13 -0
  215. package/lib/Utils/meta-ai.js +74 -0
  216. package/lib/Utils/mini-app.d.ts +35 -0
  217. package/lib/Utils/mini-app.js +213 -0
  218. package/lib/Utils/noise-handler.d.ts +20 -0
  219. package/lib/Utils/noise-handler.js +200 -0
  220. package/lib/Utils/offline-node-processor.d.ts +9 -0
  221. package/lib/Utils/offline-node-processor.js +39 -0
  222. package/lib/Utils/past-participants.d.ts +14 -0
  223. package/lib/Utils/past-participants.js +40 -0
  224. package/lib/Utils/pre-key-manager.d.ts +25 -0
  225. package/lib/Utils/pre-key-manager.js +105 -0
  226. package/lib/Utils/process-message.d.ts +82 -0
  227. package/lib/Utils/process-message.js +808 -0
  228. package/lib/Utils/qr-render.d.ts +59 -0
  229. package/lib/Utils/qr-render.js +179 -0
  230. package/lib/Utils/qrcodegen.d.ts +79 -0
  231. package/lib/Utils/qrcodegen.js +848 -0
  232. package/lib/Utils/reporting-utils.d.ts +12 -0
  233. package/lib/Utils/reporting-utils.js +257 -0
  234. package/lib/Utils/rich-message-utils.d.ts +48 -0
  235. package/lib/Utils/rich-message-utils.js +444 -0
  236. package/lib/Utils/router.d.ts +37 -0
  237. package/lib/Utils/router.js +165 -0
  238. package/lib/Utils/scheduled-posts.d.ts +30 -0
  239. package/lib/Utils/scheduled-posts.js +110 -0
  240. package/lib/Utils/scheduling.d.ts +42 -0
  241. package/lib/Utils/scheduling.js +139 -0
  242. package/lib/Utils/signal.d.ts +82 -0
  243. package/lib/Utils/signal.js +200 -0
  244. package/lib/Utils/stanza-ack.d.ts +16 -0
  245. package/lib/Utils/stanza-ack.js +37 -0
  246. package/lib/Utils/status.d.ts +50 -0
  247. package/lib/Utils/status.js +107 -0
  248. package/lib/Utils/stickerpack.d.ts +51 -0
  249. package/lib/Utils/stickerpack.js +274 -0
  250. package/lib/Utils/sync-action-utils.d.ts +2 -0
  251. package/lib/Utils/sync-action-utils.js +48 -0
  252. package/lib/Utils/tag.d.ts +12 -0
  253. package/lib/Utils/tag.js +44 -0
  254. package/lib/Utils/tc-token-utils.d.ts +29 -0
  255. package/lib/Utils/tc-token-utils.js +162 -0
  256. package/lib/Utils/templates.d.ts +76 -0
  257. package/lib/Utils/templates.js +150 -0
  258. package/lib/Utils/transcribe.d.ts +12 -0
  259. package/lib/Utils/transcribe.js +107 -0
  260. package/lib/Utils/use-cache-manager-auth-state.d.ts +13 -0
  261. package/lib/Utils/use-cache-manager-auth-state.js +81 -0
  262. package/lib/Utils/use-multi-file-auth-state.d.ts +10 -0
  263. package/lib/Utils/use-multi-file-auth-state.js +166 -0
  264. package/lib/Utils/use-single-file-auth-state.d.ts +10 -0
  265. package/lib/Utils/use-single-file-auth-state.js +113 -0
  266. package/lib/Utils/use-sqlite-auth-state.d.ts +11 -0
  267. package/lib/Utils/use-sqlite-auth-state.js +169 -0
  268. package/lib/Utils/validate-connection.d.ts +42 -0
  269. package/lib/Utils/validate-connection.js +198 -0
  270. package/lib/Utils/vcard.d.ts +58 -0
  271. package/lib/Utils/vcard.js +104 -0
  272. package/lib/Utils/voice-note.d.ts +15 -0
  273. package/lib/Utils/voice-note.js +63 -0
  274. package/lib/VoIP/audio-feeder.d.ts +18 -0
  275. package/lib/VoIP/audio-feeder.js +160 -0
  276. package/lib/VoIP/call-recorder.d.ts +13 -0
  277. package/lib/VoIP/call-recorder.js +73 -0
  278. package/lib/VoIP/index.d.ts +86 -0
  279. package/lib/VoIP/index.js +611 -0
  280. package/lib/VoIP/relay-transport.d.ts +43 -0
  281. package/lib/VoIP/relay-transport.js +563 -0
  282. package/lib/VoIP/signaling.d.ts +26 -0
  283. package/lib/VoIP/signaling.js +662 -0
  284. package/lib/VoIP/types.d.ts +69 -0
  285. package/lib/VoIP/types.js +17 -0
  286. package/lib/VoIP/wasm-engine.d.ts +120 -0
  287. package/lib/VoIP/wasm-engine.js +1358 -0
  288. package/lib/VoIP/worker-bootstrap.d.ts +4 -0
  289. package/lib/VoIP/worker-bootstrap.js +1046 -0
  290. package/lib/WABinary/constants.d.ts +61 -0
  291. package/lib/WABinary/constants.js +1466 -0
  292. package/lib/WABinary/decode.d.ts +9 -0
  293. package/lib/WABinary/decode.js +261 -0
  294. package/lib/WABinary/encode.d.ts +2 -0
  295. package/lib/WABinary/encode.js +219 -0
  296. package/lib/WABinary/generic-utils.d.ts +74 -0
  297. package/lib/WABinary/generic-utils.js +276 -0
  298. package/lib/WABinary/index.d.ts +5 -0
  299. package/lib/WABinary/index.js +5 -0
  300. package/lib/WABinary/jid-utils.d.ts +28 -0
  301. package/lib/WABinary/jid-utils.js +95 -0
  302. package/lib/WABinary/types.d.ts +19 -0
  303. package/lib/WABinary/types.js +1 -0
  304. package/lib/WAM/BinaryInfo.d.ts +7 -0
  305. package/lib/WAM/BinaryInfo.js +9 -0
  306. package/lib/WAM/constants.d.ts +34926 -0
  307. package/lib/WAM/constants.js +22852 -0
  308. package/lib/WAM/encode.d.ts +1 -0
  309. package/lib/WAM/encode.js +149 -0
  310. package/lib/WAM/index.d.ts +3 -0
  311. package/lib/WAM/index.js +3 -0
  312. package/lib/WAUSync/Protocols/USyncContactProtocol.d.ts +36 -0
  313. package/lib/WAUSync/Protocols/USyncContactProtocol.js +51 -0
  314. package/lib/WAUSync/Protocols/USyncDeviceProtocol.d.ts +29 -0
  315. package/lib/WAUSync/Protocols/USyncDeviceProtocol.js +62 -0
  316. package/lib/WAUSync/Protocols/USyncDisappearingModeProtocol.d.ts +12 -0
  317. package/lib/WAUSync/Protocols/USyncDisappearingModeProtocol.js +26 -0
  318. package/lib/WAUSync/Protocols/USyncStatusProtocol.d.ts +12 -0
  319. package/lib/WAUSync/Protocols/USyncStatusProtocol.js +37 -0
  320. package/lib/WAUSync/Protocols/USyncUsernameProtocol.d.ts +9 -0
  321. package/lib/WAUSync/Protocols/USyncUsernameProtocol.js +24 -0
  322. package/lib/WAUSync/Protocols/UsyncBotProfileProtocol.d.ts +38 -0
  323. package/lib/WAUSync/Protocols/UsyncBotProfileProtocol.js +50 -0
  324. package/lib/WAUSync/Protocols/UsyncLIDProtocol.d.ts +14 -0
  325. package/lib/WAUSync/Protocols/UsyncLIDProtocol.js +28 -0
  326. package/lib/WAUSync/Protocols/index.d.ts +7 -0
  327. package/lib/WAUSync/Protocols/index.js +7 -0
  328. package/lib/WAUSync/USyncQuery.d.ts +20 -0
  329. package/lib/WAUSync/USyncQuery.js +121 -0
  330. package/lib/WAUSync/USyncUser.d.ts +16 -0
  331. package/lib/WAUSync/USyncUser.js +30 -0
  332. package/lib/WAUSync/index.d.ts +3 -0
  333. package/lib/WAUSync/index.js +3 -0
  334. package/lib/assets/wasm/loader.d.ts +5 -0
  335. package/lib/assets/wasm/loader.js +5 -0
  336. package/lib/assets/wasm/whatsapp.wasm +0 -0
  337. package/lib/assets/wasm/worker-modules.d.ts +5 -0
  338. package/lib/assets/wasm/worker-modules.js +273 -0
  339. package/lib/index.d.ts +18 -0
  340. package/lib/index.js +23 -0
  341. package/package.json +180 -0
  342. package/postinstall-banner.js +82 -0
@@ -0,0 +1,1358 @@
1
+ var _a;
2
+ /**
3
+ * WhatsApp VoIP WASM engine.
4
+ *
5
+ * Loads the WhatsApp Web VoIP WASM stack inside a Node.js `vm.Context`,
6
+ * spawns a 20-thread `worker_threads` pool to mirror the browser's pthread
7
+ * model, and exposes a callback-based JS bridge. Audio-only (no video).
8
+ *
9
+ * @author J.AP
10
+ */
11
+ import * as vm from "node:vm";
12
+ import * as fs from "node:fs";
13
+ import * as path from "node:path";
14
+ import { randomFillSync } from "node:crypto";
15
+ import { Worker } from "node:worker_threads";
16
+ import { fileURLToPath } from "node:url";
17
+ const __filename = fileURLToPath(import.meta.url);
18
+ const __dirname = path.dirname(__filename);
19
+ const CALL_WASM_AB_PROPS_JSON = process.env.CALL_WASM_AB_PROPS_JSON ?? "";
20
+ const PTHREAD_POOL_SIZE = 20;
21
+ const VOIP_READY_TIMEOUT_MS = 15_000;
22
+ const parseJsonObjectEnv = (raw) => {
23
+ if (!raw)
24
+ return {};
25
+ try {
26
+ const parsed = JSON.parse(raw);
27
+ if (parsed && typeof parsed === "object" && !Array.isArray(parsed))
28
+ return parsed;
29
+ }
30
+ catch { }
31
+ return {};
32
+ };
33
+ const toByteArray = (input) => {
34
+ if (!input)
35
+ return new Uint8Array(0);
36
+ if (input instanceof Uint8Array)
37
+ return input;
38
+ if (typeof input === "string")
39
+ return new TextEncoder().encode(input);
40
+ if (ArrayBuffer.isView(input))
41
+ return new Uint8Array(input.buffer, input.byteOffset, input.byteLength);
42
+ if (input instanceof ArrayBuffer)
43
+ return new Uint8Array(input);
44
+ if (typeof input === "object" && typeof input.length === "number") {
45
+ const arr = new Uint8Array(input.length);
46
+ for (let i = 0; i < input.length; i += 1)
47
+ arr[i] = input[i] ?? 0;
48
+ return arr;
49
+ }
50
+ return new Uint8Array(0);
51
+ };
52
+ const filterWorkerStderr = (chunk) => {
53
+ const line = chunk.toString().trim();
54
+ if (line && !line.startsWith("voip:") && !line.startsWith("still waiting")) {
55
+ process.stderr.write(chunk);
56
+ }
57
+ };
58
+ const resolveWorkerScriptPath = () => {
59
+ const compiled = path.join(__dirname, "worker-bootstrap.js");
60
+ return fs.existsSync(compiled) ? compiled : path.join(__dirname, "worker-bootstrap.mts");
61
+ };
62
+ class NodeWorkerMessagePort {
63
+ #listeners = new Map();
64
+ #worker;
65
+ fullyConnected;
66
+ name;
67
+ workerID = 0;
68
+ pthread_ptr = 0;
69
+ constructor(worker, name = "WAWebVoipWebWasmWorker") {
70
+ this.#worker = worker;
71
+ this.name = name;
72
+ this.fullyConnected = new Promise((resolve) => {
73
+ const loadedHandler = (msg) => {
74
+ if (msg && msg.cmd === "loaded") {
75
+ this.workerID = msg.workerID ?? 0;
76
+ resolve(this);
77
+ }
78
+ };
79
+ this.addMessageListener("cmd", loadedHandler);
80
+ });
81
+ if (typeof worker.on === "function") {
82
+ worker.on("message", (data) => this.#handleMessage(data));
83
+ worker.on("error", () => { });
84
+ }
85
+ else if (typeof worker.addEventListener === "function") {
86
+ worker.addEventListener("message", (ev) => this.#handleMessage(ev?.data ?? ev));
87
+ }
88
+ }
89
+ postMessage = (msg, transferList) => {
90
+ const out = msg && typeof msg === "object" && msg.cmd && !msg.type ? { ...msg, type: "cmd" } : msg;
91
+ this.#worker.postMessage(out, transferList);
92
+ };
93
+ addMessageListener = (type, handler) => {
94
+ let set = this.#listeners.get(type);
95
+ if (!set) {
96
+ set = new Set();
97
+ this.#listeners.set(type, set);
98
+ }
99
+ set.add(handler);
100
+ return handler;
101
+ };
102
+ removeMessageListener = (type, handler) => this.#listeners.get(type)?.delete(handler) ?? false;
103
+ removeAllMessageListeners = (type) => {
104
+ if (type)
105
+ this.#listeners.get(type)?.clear();
106
+ else
107
+ this.#listeners.clear();
108
+ };
109
+ terminate = () => { this.#worker.terminate(); };
110
+ close = () => { };
111
+ isWrappingVirtualMessagePort = () => false;
112
+ getWorker = () => this.#worker;
113
+ #handleMessage = (data) => {
114
+ if (!data || typeof data !== "object")
115
+ return;
116
+ if (data.type === "callback" || data.type === "waWasmWorkerCompatibleCallback") {
117
+ let callbackName;
118
+ let callbackArgs;
119
+ if (data.__name) {
120
+ callbackName = data.__name;
121
+ callbackArgs = {};
122
+ for (const key in data) {
123
+ if (key !== "type" && key !== "__name" && key !== "prototype" && key !== "args" && !key.startsWith("__")) {
124
+ callbackArgs[key] = data[key];
125
+ }
126
+ }
127
+ }
128
+ else if (data.name) {
129
+ callbackName = data.name;
130
+ callbackArgs = data.args ?? {};
131
+ }
132
+ else if (data.payload?.name) {
133
+ callbackName = data.payload.name;
134
+ callbackArgs = data.payload.args ?? {};
135
+ }
136
+ else {
137
+ return;
138
+ }
139
+ if (callbackName === "onSignalingXmpp" &&
140
+ (!callbackArgs || Object.keys(callbackArgs).length === 0)) {
141
+ callbackArgs = {
142
+ peerJid: data.peerJid, callId: data.callId, xmlPayload: data.xmlPayload,
143
+ };
144
+ }
145
+ let listenerData = callbackArgs;
146
+ if (!callbackArgs || Object.keys(callbackArgs).length === 0 ||
147
+ (Object.keys(callbackArgs).length === 1 && callbackArgs.prototype)) {
148
+ listenerData = {};
149
+ for (const key in data) {
150
+ if (key !== "type" && key !== "__name" && key !== "prototype" && key !== "args" && !key.startsWith("__")) {
151
+ listenerData[key] = data[key];
152
+ }
153
+ }
154
+ }
155
+ else if (callbackName === "sendDataToRelay") {
156
+ listenerData = { ...callbackArgs };
157
+ if (data.data !== undefined)
158
+ listenerData.data = data.data;
159
+ if (data.len !== undefined)
160
+ listenerData.len = data.len;
161
+ if (data.ip !== undefined)
162
+ listenerData.ip = data.ip;
163
+ if (data.port !== undefined)
164
+ listenerData.port = data.port;
165
+ }
166
+ else if (callbackName === "onCallEvent") {
167
+ listenerData = { ...callbackArgs };
168
+ if (data.eventType !== undefined)
169
+ listenerData.eventType = data.eventType;
170
+ if (data.userData !== undefined)
171
+ listenerData.userData = data.userData;
172
+ if (data.eventDataJson !== undefined)
173
+ listenerData.eventDataJson = data.eventDataJson;
174
+ }
175
+ WasmEngine.notifyGlobalCallbackListeners(callbackName, listenerData);
176
+ return;
177
+ }
178
+ const dispatch = (key) => {
179
+ if (!key)
180
+ return;
181
+ for (const handler of this.#listeners.get(key) ?? []) {
182
+ try {
183
+ handler(data);
184
+ }
185
+ catch { }
186
+ }
187
+ };
188
+ dispatch(data.type);
189
+ if (data.cmd !== data.type)
190
+ dispatch(data.cmd);
191
+ };
192
+ }
193
+ export class WasmEngine {
194
+ static #globalCallbackListeners = new Map();
195
+ static #globalCallbacksRegistered = false;
196
+ static registerGlobalCallbackListener = (callbackName, handler) => {
197
+ const key = `callback:${callbackName}`;
198
+ let set = _a.#globalCallbackListeners.get(key);
199
+ if (!set) {
200
+ set = new Set();
201
+ _a.#globalCallbackListeners.set(key, set);
202
+ }
203
+ set.add(handler);
204
+ };
205
+ static notifyGlobalCallbackListeners = (callbackName, data) => {
206
+ const set = _a.#globalCallbackListeners.get(`callback:${callbackName}`);
207
+ if (!set)
208
+ return;
209
+ for (const handler of set) {
210
+ try {
211
+ handler(data);
212
+ }
213
+ catch { }
214
+ }
215
+ };
216
+ #config;
217
+ #instance = null;
218
+ #initialized = false;
219
+ #moduleRegistry = new Map();
220
+ #vmContext = null;
221
+ #unusedWorkers = [];
222
+ #runningWorkers = [];
223
+ #pthreads = {};
224
+ #nextWorkerID = 1;
225
+ #wasmModule = null;
226
+ #wasmMemory = null;
227
+ #removeRunDependencyCallback = null;
228
+ #workersLoadedCount = 0;
229
+ #audioPlaybackLoopInterval = null;
230
+ #audioPlaybackBuffer = null;
231
+ #isPlaybackActive = false;
232
+ #voipStackInitialized = false;
233
+ #voipStackInitPromise = null;
234
+ #voipReadyResolver = null;
235
+ #voipReadyPromise = null;
236
+ #workerModulesCode = "";
237
+ #loaderCode = "";
238
+ constructor(config = {}) {
239
+ const basePath = config.resourcesPath
240
+ ? (path.isAbsolute(config.resourcesPath) ? config.resourcesPath : path.resolve(process.cwd(), config.resourcesPath))
241
+ : path.resolve(__dirname, "..");
242
+ const wasmPath = config.wasmPath
243
+ ? (path.isAbsolute(config.wasmPath) ? config.wasmPath : path.resolve(process.cwd(), config.wasmPath))
244
+ : path.join(basePath, "assets", "wasm", "whatsapp.wasm");
245
+ this.#config = {
246
+ ...config,
247
+ wasmPath,
248
+ resourcesPath: basePath,
249
+ enableLogs: config.enableLogs ?? true,
250
+ options: {
251
+ heartbeatInterval: 30,
252
+ lobbyTimeout: 1,
253
+ maxParticipantsScreenShare: 32,
254
+ maxGroupSizeLongRingtone: 32,
255
+ ...config.options,
256
+ },
257
+ };
258
+ }
259
+ initialize = async () => {
260
+ if (this.#initialized)
261
+ throw new Error("WasmEngine already initialized");
262
+ const voipStorageDir = "/tmp/voip";
263
+ try {
264
+ if (!fs.existsSync(voipStorageDir))
265
+ fs.mkdirSync(voipStorageDir, { recursive: true });
266
+ }
267
+ catch { }
268
+ const loaderFile = path.join(this.#config.resourcesPath, "assets", "wasm", "loader.js");
269
+ const workerFile = path.join(this.#config.resourcesPath, "assets", "wasm", "worker-modules.js");
270
+ if (!this.#config.wasmBinary && !fs.existsSync(this.#config.wasmPath)) {
271
+ throw new Error(`WASM file not found: ${this.#config.wasmPath}`);
272
+ }
273
+ const wasmBuffer = this.#config.wasmBinary
274
+ ? Buffer.from(this.#config.wasmBinary)
275
+ : fs.readFileSync(this.#config.wasmPath);
276
+ const diskWorkerCode = fs.existsSync(workerFile) ? fs.readFileSync(workerFile, "utf8") : "";
277
+ this.#workerModulesCode = this.#config.workerModulesCode ?? diskWorkerCode;
278
+ const workerBundleHasLoader = typeof this.#workerModulesCode === "string" && /WAWebVoipWebWasmLoader/.test(this.#workerModulesCode);
279
+ // Skip the on-disk loader.js if the worker bundle already has a loader —
280
+ // the standalone loader.js is older and would clobber the freshly fetched
281
+ // bindings inside worker-modules.js.
282
+ this.#loaderCode = this.#config.loaderCode ??
283
+ (workerBundleHasLoader ? "" : fs.existsSync(loaderFile) ? fs.readFileSync(loaderFile, "utf8") : "");
284
+ if (!this.#loaderCode && !this.#workerModulesCode) {
285
+ throw new Error("No loader/worker code available to initialize VoIP");
286
+ }
287
+ const memory = new WebAssembly.Memory({ initial: 256, maximum: 32768, shared: true });
288
+ this.#wasmMemory = memory;
289
+ this.#wasmModule = await WebAssembly.compile(wasmBuffer);
290
+ this.#vmContext = this.#createVMContext(memory);
291
+ const runModuleCode = (code) => { if (code)
292
+ vm.runInContext(code, this.#vmContext); };
293
+ runModuleCode(this.#workerModulesCode);
294
+ runModuleCode(this.#loaderCode);
295
+ this.#vmContext.WAWebVoipWebWasmWorkerResource = this.#requireModule("WAWebVoipWebWasmWorkerResource");
296
+ const loaderModuleNames = [
297
+ this.#config.loaderModuleName,
298
+ "WAWebVoipWebWasmLoader",
299
+ "WAWebVoipWebWasmLoader.worker",
300
+ "WAWebVoipWebWasmLoader_ProdLab_internal.worker",
301
+ "WAWebVoipWebWasmLoader_ProdLabvideo_internal.worker",
302
+ ].filter((v, i, a) => !!v && a.indexOf(v) === i);
303
+ let wasmLoader = null;
304
+ for (const moduleName of loaderModuleNames) {
305
+ const candidate = this.#requireModule(moduleName);
306
+ if (typeof candidate === "function") {
307
+ wasmLoader = candidate;
308
+ break;
309
+ }
310
+ if (typeof candidate?.default === "function") {
311
+ wasmLoader = candidate.default;
312
+ break;
313
+ }
314
+ }
315
+ if (typeof wasmLoader !== "function") {
316
+ throw new Error(`No compatible WASM loader found. Tried: ${loaderModuleNames.join(", ")}`);
317
+ }
318
+ if (!_a.#globalCallbacksRegistered)
319
+ this.#registerGlobalCallbacks();
320
+ await this.#initPThreadPool();
321
+ const workersLoadingPromise = this.#loadWasmModuleToAllWorkers();
322
+ const readyPromise = wasmLoader({
323
+ wasmBinary: wasmBuffer,
324
+ wasmMemory: memory,
325
+ locateFile: () => this.#config.wasmPath,
326
+ onRuntimeInitialized: () => { },
327
+ });
328
+ const [instance] = await Promise.all([readyPromise, workersLoadingPromise]);
329
+ this.#instance = instance;
330
+ this.#initialized = true;
331
+ };
332
+ isInitialized = () => this.#initialized;
333
+ destroy = () => {
334
+ this.#stopAudioPlaybackLoop();
335
+ if (this.#instance && typeof this.#instance.endCall === "function") {
336
+ try {
337
+ this.#instance.endCall(0, false);
338
+ }
339
+ catch { }
340
+ }
341
+ for (const worker of [...this.#runningWorkers, ...this.#unusedWorkers]) {
342
+ try {
343
+ worker.terminate();
344
+ }
345
+ catch { }
346
+ }
347
+ this.#runningWorkers = [];
348
+ this.#unusedWorkers = [];
349
+ this.#instance = null;
350
+ this.#vmContext = null;
351
+ this.#moduleRegistry.clear();
352
+ this.#wasmModule = null;
353
+ this.#wasmMemory = null;
354
+ this.#initialized = false;
355
+ };
356
+ initVoipStack = (selfJid, meUserJid, selfLid) => {
357
+ this.#ensureInitialized();
358
+ if (this.#voipStackInitialized || this.#voipStackInitPromise)
359
+ return;
360
+ this.#voipStackInitPromise = new Promise((resolveInit) => {
361
+ this.#voipReadyPromise = new Promise((readyResolve) => {
362
+ this.#voipReadyResolver = () => {
363
+ this.#voipStackInitialized = true;
364
+ this.#voipReadyResolver = null;
365
+ this.#voipReadyPromise = null;
366
+ readyResolve();
367
+ };
368
+ });
369
+ try {
370
+ this.#applyDefaultAbProps();
371
+ try {
372
+ this.#instance.initVoipStack(selfJid, meUserJid, selfLid);
373
+ }
374
+ catch (modernErr) {
375
+ if (modernErr?.name === "BindingError" &&
376
+ (String(modernErr?.message ?? "").includes("expected 8 args") ||
377
+ String(modernErr?.message ?? "").includes("takes 8"))) {
378
+ this.#instance.initVoipStack(selfJid, meUserJid, selfLid, true, 5, 0, 8, 16);
379
+ }
380
+ else {
381
+ throw modernErr;
382
+ }
383
+ }
384
+ Promise.race([
385
+ this.#voipReadyPromise,
386
+ new Promise((r) => setTimeout(() => {
387
+ this.#voipStackInitialized = true;
388
+ r();
389
+ }, VOIP_READY_TIMEOUT_MS)),
390
+ ]).finally(() => {
391
+ this.#voipStackInitPromise = null;
392
+ resolveInit();
393
+ });
394
+ }
395
+ catch {
396
+ this.#voipReadyResolver = null;
397
+ this.#voipReadyPromise = null;
398
+ this.#voipStackInitPromise = null;
399
+ resolveInit();
400
+ }
401
+ });
402
+ };
403
+ waitForVoipStackReady = async () => {
404
+ if (this.#voipStackInitialized)
405
+ return;
406
+ if (this.#voipStackInitPromise) {
407
+ await this.#voipStackInitPromise;
408
+ }
409
+ else {
410
+ await new Promise((r) => setTimeout(r, 100));
411
+ }
412
+ };
413
+ isVoipStackReady = () => this.#voipStackInitialized;
414
+ startCall = (options) => {
415
+ this.#ensureInitialized();
416
+ const peers = this.#makeStringList(options.peerList ?? [options.peerJid]);
417
+ const tcToken = this.#createUint8List(options.extraData);
418
+ const isLidCall = options.isLidCall ?? options.peerJid.includes("@lid");
419
+ const isFromDialer = options.isFromDialer ?? false;
420
+ const peerJid = String(options.peerJid);
421
+ try {
422
+ try {
423
+ return this.#instance.startVoipCall(peerJid, peers, options.callId, options.isVideo, options.peerPn, isLidCall, isFromDialer, tcToken);
424
+ }
425
+ catch (error) {
426
+ if (error?.name !== "BindingError")
427
+ throw error;
428
+ return this.#instance.startVoipCall(peerJid, peers, options.callId, options.isVideo, options.peerPn, isFromDialer, tcToken);
429
+ }
430
+ }
431
+ finally {
432
+ peers?.delete?.();
433
+ tcToken?.delete?.();
434
+ }
435
+ };
436
+ endCall = (reason = 0, sendTerminate = true) => {
437
+ this.#ensureInitialized();
438
+ this.#instance.endCall(reason, sendTerminate);
439
+ };
440
+ setMute = (muted) => {
441
+ this.#ensureInitialized();
442
+ return this.#instance.setCallMute(muted);
443
+ };
444
+ // ─── JAP@Add: inbound answer ──────────────────────────────────────────
445
+ acceptCall = ({ isMicEnabled = true, isCameraEnabled = false } = {}) => {
446
+ this.#ensureInitialized();
447
+ if (typeof this.#instance.acceptCall !== 'function') {
448
+ throw new Error('This WASM build has no acceptCall export — refresh resources (npm run voip:fetch-wasm)');
449
+ }
450
+ this.#instance.acceptCall(isMicEnabled, isCameraEnabled);
451
+ };
452
+ rejectCall = () => {
453
+ this.#ensureInitialized();
454
+ if (typeof this.#instance.rejectCall !== 'function') {
455
+ throw new Error('This WASM build has no rejectCall export');
456
+ }
457
+ this.#instance.rejectCall();
458
+ };
459
+ rejectCallWithoutCallContext = ({ callId = '', isGroupCall = false, peerJid = '', callCreatorJid = '', reason = '', retryCount = 0, registration = 0 } = {}) => {
460
+ this.#ensureInitialized();
461
+ if (typeof this.#instance.rejectCallWithoutCallContext !== 'function') {
462
+ throw new Error('This WASM build has no rejectCallWithoutCallContext export');
463
+ }
464
+ this.#instance.rejectCallWithoutCallContext(String(callId), !!isGroupCall, String(peerJid), String(callCreatorJid), String(reason), Number(retryCount), Number(registration));
465
+ };
466
+ // ─── JAP@Add: group / multi-party calls ───────────────────────────────
467
+ startGroupCall = ({ pnUserJids = [], lidUserJids = [], deviceJidsCsv = [], callId = '', useVideo = false, groupJid = '', isLightWeight = false, scheduleId = '', chatName = '', chatIcon = '', callFromUI = 0, lobbyEntryType = 0, username = '' } = {}) => {
468
+ this.#ensureInitialized();
469
+ if (typeof this.#instance.startVoipGroupCall !== 'function') {
470
+ throw new Error('This WASM build has no startVoipGroupCall export');
471
+ }
472
+ const f = this.#makeStringList(pnUserJids);
473
+ const g = this.#makeStringList(lidUserJids);
474
+ const h = this.#makeStringList(deviceJidsCsv);
475
+ try {
476
+ return this.#instance.startVoipGroupCall(f, g, h, String(callId), !!useVideo, String(groupJid), !!isLightWeight, String(scheduleId), String(chatName), String(chatIcon), Number(callFromUI), Number(lobbyEntryType), String(username));
477
+ }
478
+ finally {
479
+ f?.delete?.(); g?.delete?.(); h?.delete?.();
480
+ }
481
+ };
482
+ joinOngoingCall = ({ callId = '', callCreatorJid = '', initialPeerJid = '', groupParticipantsPnUserJid = [], groupParticipantsLidUserJid = [], groupParticipantsDeviceJidsCsv = [], hasVideo = false, groupJid = '', initialGroupTransactionId = 0, callCreatorIsNotContact = false, callLinkCode = '', isLightweight = false, scheduledId = '', joinAndAccept = true, chatName = '', lobbyEntryType = 0, isDeviceSwitch = false } = {}) => {
483
+ this.#ensureInitialized();
484
+ if (typeof this.#instance.joinVoipOngoingCall !== 'function') {
485
+ throw new Error('This WASM build has no joinVoipOngoingCall export');
486
+ }
487
+ const y = this.#makeStringList(groupParticipantsPnUserJid);
488
+ const c = this.#makeStringList(groupParticipantsLidUserJid);
489
+ const b = this.#makeStringList(groupParticipantsDeviceJidsCsv);
490
+ try {
491
+ return this.#instance.joinVoipOngoingCall(String(callId), String(callCreatorJid), String(initialPeerJid), y, c, b, !!hasVideo, String(groupJid), Number(initialGroupTransactionId), !!callCreatorIsNotContact, String(callLinkCode), !!isLightweight, String(scheduledId), !!joinAndAccept, String(chatName), Number(lobbyEntryType), !!isDeviceSwitch);
492
+ }
493
+ finally {
494
+ y?.delete?.(); c?.delete?.(); b?.delete?.();
495
+ }
496
+ };
497
+ inviteToCall = ({ invitedParticipantPnUserJid = '', invitedParticipantLidUserJid = '', deviceJids = [] } = {}) => {
498
+ this.#ensureInitialized();
499
+ if (typeof this.#instance.inviteToCall !== 'function') {
500
+ throw new Error('This WASM build has no inviteToCall export');
501
+ }
502
+ const m = this.#makeStringList(deviceJids);
503
+ try {
504
+ return this.#instance.inviteToCall(String(invitedParticipantPnUserJid), String(invitedParticipantLidUserJid), m);
505
+ }
506
+ finally {
507
+ m?.delete?.();
508
+ }
509
+ };
510
+ removeCallParticipant = (peerJid) => {
511
+ this.#ensureInitialized();
512
+ if (typeof this.#instance.removeCallParticipant !== 'function') {
513
+ throw new Error('This WASM build has no removeCallParticipant export');
514
+ }
515
+ return this.#instance.removeCallParticipant(String(peerJid));
516
+ };
517
+ requestPeerMute = (peerJid) => {
518
+ this.#ensureInitialized();
519
+ if (typeof this.#instance.requestPeerMute !== 'function') {
520
+ throw new Error('This WASM build has no requestPeerMute export');
521
+ }
522
+ return this.#instance.requestPeerMute(String(peerJid));
523
+ };
524
+ // ─── JAP@Add: call links ──────────────────────────────────────────────
525
+ previewCallLink = ({ token = '', videoEnabled = false, lobbyEntryType = 0, username = '' } = {}) => {
526
+ this.#ensureInitialized();
527
+ if (typeof this.#instance.previewCallLink !== 'function') {
528
+ throw new Error('This WASM build has no previewCallLink export');
529
+ }
530
+ return this.#instance.previewCallLink(String(token), !!videoEnabled, Number(lobbyEntryType), String(username));
531
+ };
532
+ joinCallLink = () => {
533
+ this.#ensureInitialized();
534
+ if (typeof this.#instance.joinCallLink !== 'function') {
535
+ throw new Error('This WASM build has no joinCallLink export');
536
+ }
537
+ return this.#instance.joinCallLink();
538
+ };
539
+ // ─── JAP@Add: recovery ────────────────────────────────────────────────
540
+ resendOfferOnDecryptionFailure = (peerJid, callId) => {
541
+ this.#ensureInitialized();
542
+ if (typeof this.#instance.resendOfferOnDecryptionFailure !== 'function') {
543
+ throw new Error('This WASM build has no resendOfferOnDecryptionFailure export');
544
+ }
545
+ this.#instance.resendOfferOnDecryptionFailure(String(peerJid), String(callId));
546
+ };
547
+ resendEncRekeyRetry = (peerJid, retryCount = 1) => {
548
+ this.#ensureInitialized();
549
+ if (typeof this.#instance.resendEncRekeyRetry !== 'function') {
550
+ throw new Error('This WASM build has no resendEncRekeyRetry export');
551
+ }
552
+ this.#instance.resendEncRekeyRetry(String(peerJid), Number(retryCount));
553
+ };
554
+ checkOngoingCalls = (callIds = [], callCreatorJids = []) => {
555
+ this.#ensureInitialized();
556
+ if (typeof this.#instance.checkOngoingCalls !== 'function') return;
557
+ const w = this.#makeStringList(callIds);
558
+ const a = this.#makeStringList(callCreatorJids);
559
+ try {
560
+ this.#instance.checkOngoingCalls(w, a);
561
+ }
562
+ finally {
563
+ w?.delete?.(); a?.delete?.();
564
+ }
565
+ };
566
+ // ─── JAP@Add: introspection ───────────────────────────────────────────
567
+ getCallInfo = () => {
568
+ this.#ensureInitialized();
569
+ return typeof this.#instance.getCallInfo === 'function' ? this.#instance.getCallInfo() : null;
570
+ };
571
+ getCallStats = (debug = false) => {
572
+ this.#ensureInitialized();
573
+ const fn = debug ? this.#instance.getDebugStatisticString : this.#instance.getShortStatisticString;
574
+ return typeof fn === 'function' ? fn.call(this.#instance) : '';
575
+ };
576
+ sendReaction = (reaction) => {
577
+ this.#ensureInitialized();
578
+ if (typeof this.#instance.sendReaction !== 'function') return false;
579
+ this.#instance.sendReaction(String(reaction));
580
+ return true;
581
+ };
582
+ raiseHand = (raised) => {
583
+ this.#ensureInitialized();
584
+ if (typeof this.#instance.raiseHand !== 'function') return false;
585
+ this.#instance.raiseHand(!!raised);
586
+ return true;
587
+ };
588
+ updateNetworkMedium = (networkMedium, networkMtu = 0) => {
589
+ this.#ensureInitialized();
590
+ this.#instance.updateNetworkMedium?.(networkMedium, networkMtu);
591
+ };
592
+ handleSignalingOffer = (msg) => {
593
+ this.#ensureInitialized();
594
+ const tcTokenList = this.#createUint8List(msg.tcToken);
595
+ try {
596
+ this.#instance.handleIncomingSignalingOffer(msg.payload, String(msg.peerPlatform ?? 0), String(msg.peerAppVersion ?? "0"), String(msg.epochId ?? "0"), String(msg.timestamp ?? "0"), msg.isOffline ?? false, msg.isOfferNotContact ?? false, String(msg.peerJid), tcTokenList);
597
+ }
598
+ finally {
599
+ tcTokenList?.delete?.();
600
+ }
601
+ };
602
+ handleSignalingMessage = (msg) => {
603
+ this.#ensureInitialized();
604
+ const tcTokenList = this.#createUint8List(msg.tcToken);
605
+ try {
606
+ this.#instance.handleIncomingSignalingMessage(msg.payload, String(msg.peerPlatform ?? "0"), String(msg.peerAppVersion ?? "0"), String(msg.epochId ?? "0"), String(msg.timestamp ?? "0"), msg.isOffline ?? false, String(msg.peerJid), tcTokenList);
607
+ }
608
+ finally {
609
+ tcTokenList?.delete?.();
610
+ }
611
+ };
612
+ handleSignalingAck = (msg) => {
613
+ this.#ensureInitialized();
614
+ const options = this.#createUint8List(msg.extraData);
615
+ try {
616
+ this.#instance.handleIncomingSignalingAck(msg.payload, String(msg.ackError ?? "0"), String(msg.msgType ?? ""), msg.peerJid ?? "", options);
617
+ }
618
+ finally {
619
+ options?.delete?.();
620
+ }
621
+ };
622
+ handleSignalingReceipt = (msg) => {
623
+ this.#ensureInitialized();
624
+ const tcTokenList = this.#createUint8List(msg.tcToken);
625
+ try {
626
+ this.#instance.handleIncomingSignalingReceipt?.(msg.payload, msg.peerJid, tcTokenList);
627
+ }
628
+ finally {
629
+ tcTokenList?.delete?.();
630
+ }
631
+ };
632
+ handleOnTransportMessage = (data, ip, port) => {
633
+ this.#ensureInitialized();
634
+ if (typeof this.#instance.handleOnMessageFromHeap === "function") {
635
+ const ptr = this.malloc(data.byteLength);
636
+ if (!ptr)
637
+ return;
638
+ try {
639
+ const heapU8 = this.#instance.GROWABLE_HEAP_U8?.() ?? this.#instance.HEAPU8;
640
+ if (!heapU8)
641
+ return;
642
+ heapU8.set(data, ptr);
643
+ this.#instance.handleOnMessageFromHeap(ptr, data.byteLength, ip, port);
644
+ }
645
+ finally {
646
+ this.free(ptr);
647
+ }
648
+ return;
649
+ }
650
+ if (typeof this.#instance.handleOnMessage !== "function")
651
+ return;
652
+ const dataList = this.#createUint8List(data);
653
+ try {
654
+ this.#instance.handleOnMessage(dataList, ip, port);
655
+ }
656
+ finally {
657
+ dataList?.delete?.();
658
+ }
659
+ };
660
+ updateIceRtt = (rttMs, relayIp, relayPort) => {
661
+ this.#ensureInitialized();
662
+ this.#instance.updateIceRtt?.(rttMs, relayIp, relayPort);
663
+ };
664
+ sendAudioData = (data, ptr) => {
665
+ this.#ensureInitialized();
666
+ if (!data || data.length === 0 || !ptr)
667
+ return;
668
+ if (typeof this.#instance.onAudioDataFromJs !== "function")
669
+ return;
670
+ try {
671
+ const heapF32 = this.#instance.GROWABLE_HEAP_F32?.();
672
+ if (!heapF32)
673
+ return;
674
+ const index = Math.floor(ptr / 4);
675
+ if (index < 0 || index + data.length > heapF32.length)
676
+ return;
677
+ heapF32.set(data, index);
678
+ this.#instance.onAudioDataFromJs(ptr, data.length);
679
+ }
680
+ catch { }
681
+ };
682
+ malloc = (size) => {
683
+ this.#ensureInitialized();
684
+ return this.#instance._malloc(size);
685
+ };
686
+ free = (ptr) => {
687
+ this.#ensureInitialized();
688
+ this.#instance._free(ptr);
689
+ };
690
+ // ─── private ──────────────────────────────────────────────────────────────
691
+ #ensureInitialized = () => {
692
+ if (!this.#initialized || !this.#instance) {
693
+ throw new Error("WasmEngine not initialized. Call initialize() first.");
694
+ }
695
+ };
696
+ #makeStringList = (arr) => {
697
+ const list = new this.#instance.StringList();
698
+ for (const v of arr)
699
+ list.push_back(v);
700
+ return list;
701
+ };
702
+ #createUint8List = (data) => {
703
+ if (!this.#instance?.Uint8List)
704
+ return null;
705
+ const list = new this.#instance.Uint8List();
706
+ if (data)
707
+ data.forEach((byte) => list.push_back(byte));
708
+ return list;
709
+ };
710
+ #startAudioPlaybackLoop = () => {
711
+ if (this.#audioPlaybackLoopInterval)
712
+ return;
713
+ this.#ensureInitialized();
714
+ this.#isPlaybackActive = true;
715
+ if (typeof this.#instance.requestAudioDataFromWasmVoip !== "function")
716
+ return;
717
+ const framesPerChunk = 320;
718
+ const bufferSize = framesPerChunk * 4;
719
+ try {
720
+ const _malloc = this.#instance._malloc ?? this.#instance.malloc;
721
+ if (!_malloc)
722
+ return;
723
+ this.#audioPlaybackBuffer = _malloc(bufferSize);
724
+ }
725
+ catch {
726
+ return;
727
+ }
728
+ if (!this.#audioPlaybackBuffer || this.#audioPlaybackBuffer <= 0)
729
+ return;
730
+ this.#audioPlaybackLoopInterval = setInterval(() => {
731
+ if (!this.#isPlaybackActive || !this.#instance || !this.#initialized) {
732
+ this.#stopAudioPlaybackLoop();
733
+ return;
734
+ }
735
+ try {
736
+ this.#instance.requestAudioDataFromWasmVoip(this.#audioPlaybackBuffer, bufferSize);
737
+ const heapF32 = this.#instance.GROWABLE_HEAP_F32?.();
738
+ if (!heapF32)
739
+ return;
740
+ const index = Math.floor(this.#audioPlaybackBuffer / 4);
741
+ const numFloats = Math.floor(bufferSize / 4);
742
+ if (index < 0 || index + numFloats > heapF32.length)
743
+ return;
744
+ const audioData = new Float32Array(heapF32.buffer, heapF32.byteOffset + index * 4, numFloats);
745
+ const hasNonZero = audioData.some((s) => Math.abs(s) > 0.0001);
746
+ if (hasNonZero)
747
+ this.#config.callbacks?.onAudioPlaybackData?.(audioData);
748
+ }
749
+ catch { }
750
+ }, 16);
751
+ };
752
+ #stopAudioPlaybackLoop = () => {
753
+ this.#isPlaybackActive = false;
754
+ if (this.#audioPlaybackLoopInterval) {
755
+ clearInterval(this.#audioPlaybackLoopInterval);
756
+ this.#audioPlaybackLoopInterval = null;
757
+ }
758
+ if (this.#audioPlaybackBuffer && this.#audioPlaybackBuffer > 0) {
759
+ try {
760
+ this.#instance?._free?.(this.#audioPlaybackBuffer);
761
+ }
762
+ catch { }
763
+ this.#audioPlaybackBuffer = null;
764
+ }
765
+ };
766
+ #applyDefaultAbProps = () => {
767
+ if (!this.#instance)
768
+ return;
769
+ const setInt = typeof this.#instance.setABPropInt === "function"
770
+ ? (k, v) => { this.#instance.setABPropInt(k, v); }
771
+ : null;
772
+ const setBool = typeof this.#instance.setABPropBool === "function"
773
+ ? (k, v) => { this.#instance.setABPropBool(k, v); }
774
+ : null;
775
+ const setString = typeof this.#instance.setABPropString === "function"
776
+ ? (k, v) => { this.#instance.setABPropString(k, v); }
777
+ : null;
778
+ if (!setInt && !setBool && !setString)
779
+ return;
780
+ const opts = this.#config.options ?? {};
781
+ const intProps = {
782
+ heartbeat_interval_s: opts.heartbeatInterval ?? 30,
783
+ lobby_timeout_min: opts.lobbyTimeout ?? 1,
784
+ max_num_participants_for_ss: opts.maxParticipantsScreenShare ?? 32,
785
+ max_group_size_for_long_ringtone: opts.maxGroupSizeLongRingtone ?? 32,
786
+ app_exit_reason_version: 1,
787
+ log_level: opts.logLevel ?? 3,
788
+ calling_rust_migration_bitmap: 0,
789
+ calling_rust_migration_incoming_stanza_bitmap: 0,
790
+ default_endpoint_thread_poll_timeout: 0,
791
+ aigc_version: 0,
792
+ call_admin_version: 0,
793
+ vid_stream_pause_resume_jb_reset_threshold_ms: 0,
794
+ // Opus: max bandwidth WB (16 kHz). FB (48 kHz) needs native audio device
795
+ // hooks not available in this JS-only WASM context.
796
+ opus_max_bandwidth: 1103, // OPUS_BANDWIDTH_WIDEBAND
797
+ };
798
+ const boolProps = {
799
+ enable_av_downgrade: false,
800
+ enable_new_user_action_stanza_for_raise_hand_sender: false,
801
+ enable_webcodec_video_encode: false,
802
+ enable_init_bwe_for_group_call: false,
803
+ enable_ring_for_gc_on_offer_expire: false,
804
+ allow_reporting_call_replayer_id: false,
805
+ enable_offer_v2_upgrade: false,
806
+ enable_silent_offer: false,
807
+ voice_ai_conversation_starter_latency_tracking: false,
808
+ enable_waiting_room_logging: false,
809
+ attach_transport_rtx: false,
810
+ ignore_joinable_terminate_on_expired_offer: false,
811
+ enable_passthrough_video_decoder: false,
812
+ };
813
+ for (const [key, value] of Object.entries(intProps)) {
814
+ if (setInt && Number.isFinite(value))
815
+ try {
816
+ setInt(key, value);
817
+ }
818
+ catch { }
819
+ }
820
+ for (const [key, value] of Object.entries(boolProps)) {
821
+ if (setBool)
822
+ try {
823
+ setBool(key, value);
824
+ }
825
+ catch { }
826
+ }
827
+ const overrideProps = parseJsonObjectEnv(CALL_WASM_AB_PROPS_JSON);
828
+ for (const [key, value] of Object.entries(overrideProps)) {
829
+ try {
830
+ if (typeof value === "boolean" && setBool)
831
+ setBool(key, value);
832
+ else if (typeof value === "number" && setInt)
833
+ setInt(key, value);
834
+ else if (typeof value === "string" && setString)
835
+ setString(key, value);
836
+ }
837
+ catch { }
838
+ }
839
+ };
840
+ #allocateUnusedWorker = () => {
841
+ const workerScriptPath = resolveWorkerScriptPath();
842
+ if (!fs.existsSync(workerScriptPath))
843
+ return;
844
+ try {
845
+ const worker = new Worker(workerScriptPath, {
846
+ stdout: true, stderr: true,
847
+ workerData: {
848
+ wasmPath: this.#config.wasmPath,
849
+ wasmBinary: this.#config.wasmBinary,
850
+ workerModulesCode: this.#workerModulesCode,
851
+ loaderCode: this.#loaderCode,
852
+ loaderModuleName: this.#config.loaderModuleName,
853
+ resourcesPath: this.#config.resourcesPath,
854
+ enableLogs: this.#config.enableLogs,
855
+ },
856
+ });
857
+ const port = new NodeWorkerMessagePort(worker, "WAWebVoipWebWasmWorker");
858
+ worker.stdout?.on("data", () => { }); // suppress noisy worker stdout
859
+ worker.stderr?.on("data", filterWorkerStderr);
860
+ this.#unusedWorkers.push(port);
861
+ }
862
+ catch { }
863
+ };
864
+ #initPThreadPool = async () => {
865
+ for (let i = 0; i < PTHREAD_POOL_SIZE; i += 1)
866
+ this.#allocateUnusedWorker();
867
+ };
868
+ #loadWasmModuleToWorker = (worker) => new Promise((resolve) => {
869
+ const loadedHandler = (msg) => {
870
+ if (msg && msg.cmd === "loaded") {
871
+ worker.removeMessageListener("cmd", loadedHandler);
872
+ this.#workersLoadedCount += 1;
873
+ if (this.#workersLoadedCount >= PTHREAD_POOL_SIZE && this.#removeRunDependencyCallback) {
874
+ this.#removeRunDependencyCallback("loading-workers");
875
+ }
876
+ resolve();
877
+ }
878
+ };
879
+ worker.addMessageListener("cmd", loadedHandler);
880
+ worker.workerID = this.#nextWorkerID++;
881
+ worker.postMessage({
882
+ cmd: "load", type: "cmd",
883
+ wasmMemory: this.#wasmMemory,
884
+ wasmModule: this.#wasmModule,
885
+ workerID: worker.workerID,
886
+ handlers: [],
887
+ });
888
+ });
889
+ #loadWasmModuleToAllWorkers = async () => {
890
+ this.#workersLoadedCount = 0;
891
+ await Promise.all(this.#unusedWorkers.map((w) => this.#loadWasmModuleToWorker(w)));
892
+ };
893
+ #registerGlobalCallbacks = () => {
894
+ const callbacks = this.#config.callbacks ?? {};
895
+ _a.registerGlobalCallbackListener("loggingCallback", (data) => {
896
+ if (!this.#config.enableLogs)
897
+ return;
898
+ const level = data?.level;
899
+ const msg = data?.message ?? "";
900
+ const mapped = level === 1 ? "error" : level === 2 ? "warn" : level === 3 ? "log" : "debug";
901
+ callbacks.onLog?.(mapped, msg);
902
+ });
903
+ if (callbacks.onAudioCaptureInit) {
904
+ _a.registerGlobalCallbackListener("initCaptureDriverJS", (data) => {
905
+ callbacks.onAudioCaptureInit({
906
+ sampleRate: data?.sample_rate ?? data?.sampleRate,
907
+ channels: data?.channels,
908
+ bitsPerSample: data?.bits_per_sample ?? data?.bitsPerSample,
909
+ framesPerChunk: data?.frames_per_chunk ?? data?.framesPerChunk,
910
+ });
911
+ });
912
+ }
913
+ _a.registerGlobalCallbackListener("startCaptureJS", () => callbacks.onAudioCaptureStart?.());
914
+ _a.registerGlobalCallbackListener("stopCaptureJS", () => callbacks.onAudioCaptureStop?.());
915
+ if (callbacks.onAudioPlaybackInit) {
916
+ _a.registerGlobalCallbackListener("initPlaybackDriverJS", (data) => {
917
+ callbacks.onAudioPlaybackInit({
918
+ sampleRate: data?.sample_rate ?? data?.sampleRate,
919
+ channels: data?.channels,
920
+ bitsPerSample: data?.bits_per_sample ?? data?.bitsPerSample,
921
+ framesPerChunk: data?.frames_per_chunk ?? data?.framesPerChunk,
922
+ });
923
+ });
924
+ }
925
+ _a.registerGlobalCallbackListener("startPlaybackJS", () => {
926
+ callbacks.onAudioPlaybackStart?.();
927
+ this.#startAudioPlaybackLoop();
928
+ });
929
+ _a.registerGlobalCallbackListener("stopPlaybackJS", () => {
930
+ this.#stopAudioPlaybackLoop();
931
+ callbacks.onAudioPlaybackStop?.();
932
+ });
933
+ if (callbacks.onSignalingXmpp) {
934
+ _a.registerGlobalCallbackListener("onSignalingXmpp", (data) => {
935
+ const peerJid = data.peerJid ?? data.args?.peerJid;
936
+ const callId = data.callId ?? data.args?.callId;
937
+ let xmlPayload = data.xmlPayload ?? data.args?.xmlPayload;
938
+ if (Array.isArray(xmlPayload))
939
+ xmlPayload = new Uint8Array(xmlPayload);
940
+ else if (xmlPayload && typeof xmlPayload === "object" &&
941
+ !(xmlPayload instanceof Uint8Array) && !Buffer.isBuffer(xmlPayload)) {
942
+ xmlPayload = new Uint8Array(xmlPayload);
943
+ }
944
+ callbacks.onSignalingXmpp(peerJid, callId, xmlPayload);
945
+ });
946
+ }
947
+ if (callbacks.onCallEvent) {
948
+ _a.registerGlobalCallbackListener("onCallEvent", (data) => {
949
+ callbacks.onCallEvent(data.eventType, data.eventDataJson);
950
+ });
951
+ }
952
+ if (callbacks.sendDataToRelay) {
953
+ _a.registerGlobalCallbackListener("sendDataToRelay", (data) => {
954
+ let relayData = data.data ?? data.args?.data;
955
+ const ip = data.ip ?? data.args?.ip;
956
+ const portNum = data.port ?? data.args?.port;
957
+ if (relayData instanceof Uint8Array) { /* ok */ }
958
+ else if (Array.isArray(relayData))
959
+ relayData = new Uint8Array(relayData);
960
+ else if (Buffer.isBuffer(relayData))
961
+ relayData = new Uint8Array(relayData);
962
+ else if (relayData && typeof relayData === "object" && relayData.buffer) {
963
+ relayData = new Uint8Array(relayData.buffer, relayData.byteOffset ?? 0, relayData.byteLength ?? relayData.length);
964
+ }
965
+ else if (relayData instanceof ArrayBuffer)
966
+ relayData = new Uint8Array(relayData);
967
+ else
968
+ return 0;
969
+ if (!ip || !portNum)
970
+ return 0;
971
+ callbacks.sendDataToRelay(relayData, ip, portNum);
972
+ return relayData.byteLength;
973
+ });
974
+ }
975
+ _a.#globalCallbacksRegistered = true;
976
+ };
977
+ #requireModule = (name) => {
978
+ const preDefinedModules = {
979
+ Promise,
980
+ WAWebVoipWebWasmWorkerResource: {
981
+ resourcePath: resolveWorkerScriptPath(),
982
+ name: "WAWebVoipWebWasmWorker",
983
+ },
984
+ WorkerBundleResource: {
985
+ createDedicatedWebWorker: (resource) => {
986
+ const scriptPath = resource?.resourcePath && fs.existsSync(resource.resourcePath)
987
+ ? resource.resourcePath
988
+ : resolveWorkerScriptPath();
989
+ const worker = new Worker(scriptPath, {
990
+ stdout: true, stderr: true,
991
+ workerData: {
992
+ wasmPath: this.#config.wasmPath,
993
+ wasmBinary: this.#config.wasmBinary,
994
+ workerModulesCode: this.#workerModulesCode,
995
+ loaderCode: this.#loaderCode,
996
+ loaderModuleName: this.#config.loaderModuleName,
997
+ resourcesPath: this.#config.resourcesPath,
998
+ enableLogs: this.#config.enableLogs,
999
+ },
1000
+ });
1001
+ worker.stdout?.on("data", () => { });
1002
+ worker.stderr?.on("data", filterWorkerStderr);
1003
+ return worker;
1004
+ },
1005
+ },
1006
+ WorkerClient: { init: () => { } },
1007
+ WorkerMessagePort: {
1008
+ WorkerMessagePort: NodeWorkerMessagePort,
1009
+ CastWorkerMessagePort: (w) => w,
1010
+ WorkerSyncedMessagePort: NodeWorkerMessagePort,
1011
+ },
1012
+ bx: Object.assign((id) => String(id), { getURL: () => "" }),
1013
+ HasteSupportData: { handle: () => { } },
1014
+ ServiceWorkerDynamicModules: { handle: () => { } },
1015
+ WhatsAppWebServiceWorker: { default: true },
1016
+ WAWebLogger: { initializeWAWebLogger: () => { } },
1017
+ WAWebSw: { initHandlers: () => { } },
1018
+ WAWebWamRuntimeProvider: { setWamRuntime: () => { } },
1019
+ WAWebWamWorkerInterface: { commit: () => { }, set: () => { } },
1020
+ ServerJSDefine: { handleDefine: () => { } },
1021
+ ix: { add: () => { } },
1022
+ MetaConfigMap: { add: () => { } },
1023
+ QPLHasteSupportDataStorage: { default: { add: () => { }, get: () => null } },
1024
+ getFalcoLogPolicy_DO_NOT_USE: { add: () => { } },
1025
+ gkx: { add: () => { } },
1026
+ justknobx: { add: () => { } },
1027
+ qex: { add: () => { } },
1028
+ };
1029
+ if (preDefinedModules[name])
1030
+ return preDefinedModules[name];
1031
+ const mod = this.#moduleRegistry.get(name);
1032
+ if (!mod)
1033
+ return {};
1034
+ if (mod.exports !== undefined)
1035
+ return mod.exports;
1036
+ const requireFn = this.#requireModule;
1037
+ const normalizeModuleResult = (value) => {
1038
+ if (value && typeof value === "object" && "exports" in value && Object.keys(value).length === 1) {
1039
+ return value.exports;
1040
+ }
1041
+ return value;
1042
+ };
1043
+ const importDefaultFn = (dep) => {
1044
+ const v = requireFn(dep);
1045
+ return v && v.__esModule ? v.default : v;
1046
+ };
1047
+ const importAllFn = (dep) => {
1048
+ const v = requireFn(dep);
1049
+ if (v == null)
1050
+ return { default: v };
1051
+ if (v.__esModule)
1052
+ return v;
1053
+ if (typeof v !== "object" && typeof v !== "function")
1054
+ return { default: v };
1055
+ const ns = {};
1056
+ for (const key of Object.keys(v))
1057
+ ns[key] = v[key];
1058
+ ns.default = v;
1059
+ return ns;
1060
+ };
1061
+ const tryMetro = () => {
1062
+ const module = { exports: {} };
1063
+ mod.factory(this.#vmContext ?? globalThis, requireFn, importDefaultFn, importAllFn, null, module, module.exports);
1064
+ return normalizeModuleResult(module.exports);
1065
+ };
1066
+ const tryLegacy = () => {
1067
+ const exports = {};
1068
+ const module = { exports };
1069
+ const resolvedDeps = mod.deps.map((dep) => requireFn(dep));
1070
+ mod.factory(this.#vmContext ?? globalThis, requireFn, requireFn, requireFn, module, exports, ...resolvedDeps);
1071
+ return normalizeModuleResult(module.exports);
1072
+ };
1073
+ let result = {};
1074
+ let metroError = null;
1075
+ try {
1076
+ result = tryMetro();
1077
+ }
1078
+ catch (e) {
1079
+ metroError = e;
1080
+ }
1081
+ if (metroError != null || (result && typeof result === "object" && Object.keys(result).length === 0)) {
1082
+ try {
1083
+ const legacyResult = tryLegacy();
1084
+ if (typeof legacyResult === "function" || (legacyResult && Object.keys(legacyResult).length > 0)) {
1085
+ result = legacyResult;
1086
+ }
1087
+ }
1088
+ catch { }
1089
+ }
1090
+ mod.exports = result;
1091
+ return result;
1092
+ };
1093
+ #createVMContext = (memory) => {
1094
+ const callbacks = this.#config.callbacks ?? {};
1095
+ const wasmCallbacks = {
1096
+ onVoipReady: () => {
1097
+ this.#voipReadyResolver?.();
1098
+ callbacks.onVoipReady?.();
1099
+ },
1100
+ onSignalingXmpp: (data) => callbacks.onSignalingXmpp?.(data?.peerJid, data?.callId, data?.xmlPayload),
1101
+ onCallEvent: (data) => callbacks.onCallEvent?.(data?.eventType, data?.eventDataJson),
1102
+ sendDataToRelay: (data) => callbacks.sendDataToRelay?.(data?.data, data?.ip, data?.port),
1103
+ loggingCallback: (data) => {
1104
+ if (!this.#config.enableLogs)
1105
+ return;
1106
+ const level = data?.level;
1107
+ const msg = data?.message ?? "";
1108
+ const mapped = level === 1 ? "error" : level === 2 ? "warn" : level === 3 ? "log" : "debug";
1109
+ callbacks.onLog?.(mapped, msg);
1110
+ },
1111
+ initCaptureDriverJS: (data) => {
1112
+ callbacks.onAudioCaptureInit?.({
1113
+ sampleRate: data?.sample_rate, channels: data?.channels,
1114
+ bitsPerSample: data?.bits_per_sample, framesPerChunk: data?.frames_per_chunk,
1115
+ });
1116
+ return 0;
1117
+ },
1118
+ startCaptureJS: () => { callbacks.onAudioCaptureStart?.(); return 0; },
1119
+ stopCaptureJS: () => { callbacks.onAudioCaptureStop?.(); return 0; },
1120
+ initPlaybackDriverJS: (data) => {
1121
+ callbacks.onAudioPlaybackInit?.({
1122
+ sampleRate: data?.sample_rate, channels: data?.channels,
1123
+ bitsPerSample: data?.bits_per_sample, framesPerChunk: data?.frames_per_chunk,
1124
+ });
1125
+ return 0;
1126
+ },
1127
+ startPlaybackJS: () => {
1128
+ callbacks.onAudioPlaybackStart?.();
1129
+ this.#startAudioPlaybackLoop();
1130
+ return 0;
1131
+ },
1132
+ stopPlaybackJS: () => {
1133
+ this.#stopAudioPlaybackLoop();
1134
+ callbacks.onAudioPlaybackStop?.();
1135
+ return 0;
1136
+ },
1137
+ startVideoCaptureJS: () => 0,
1138
+ stopVideoCaptureJS: () => 0,
1139
+ startDesktopCaptureJS: () => 0,
1140
+ stopDesktopCaptureJS: () => 0,
1141
+ dataChannelStateCallback: () => 0,
1142
+ getBrowserAudioProcessingStatus: () => 7,
1143
+ getBweModelPath: () => null,
1144
+ videoFrameConsumed: () => 0,
1145
+ cryptoHkdfExtractWithSaltAndExpand: (data) => {
1146
+ const key = toByteArray(data?.key_);
1147
+ const salt = data?.salt_ ? toByteArray(data.salt_) : new Uint8Array(0);
1148
+ const info = toByteArray(data?.info_);
1149
+ const length = data?.length ?? 32;
1150
+ return callbacks.cryptoHkdf?.(key, salt, info, length) ?? new Uint8Array(length);
1151
+ },
1152
+ hmacSha256KeyGenerator: (data) => {
1153
+ const hmacData = new Uint8Array(data?.data_ ?? []);
1154
+ const hmacKey = new Uint8Array(data?.key_ ?? []);
1155
+ return callbacks.hmacSha256?.(hmacData, hmacKey) ?? new Uint8Array(32);
1156
+ },
1157
+ isParticipantKnownContact: () => true,
1158
+ getPersistentDirectoryPath: () => {
1159
+ const dir = "/tmp/voip";
1160
+ try {
1161
+ if (!fs.existsSync(dir))
1162
+ fs.mkdirSync(dir, { recursive: true });
1163
+ }
1164
+ catch { }
1165
+ return dir;
1166
+ },
1167
+ };
1168
+ const __d = (name, deps, factory) => {
1169
+ this.#moduleRegistry.set(name, { deps, factory, exports: undefined });
1170
+ };
1171
+ const babelHelpers = {
1172
+ extends: Object.assign,
1173
+ inheritsLoose: (sub, sup) => {
1174
+ sub.prototype = Object.create(sup.prototype);
1175
+ sub.prototype.constructor = sub;
1176
+ sub.__proto__ = sup;
1177
+ },
1178
+ objectWithoutPropertiesLoose: (source, excluded) => {
1179
+ if (source == null)
1180
+ return {};
1181
+ const target = {};
1182
+ for (const key of Object.keys(source)) {
1183
+ if (excluded.indexOf(key) >= 0)
1184
+ continue;
1185
+ target[key] = source[key];
1186
+ }
1187
+ return target;
1188
+ },
1189
+ taggedTemplateLiteralLoose: (strings, raw) => {
1190
+ if (!raw)
1191
+ raw = strings.slice(0);
1192
+ strings.raw = raw;
1193
+ return strings;
1194
+ },
1195
+ wrapNativeSuper: (Class) => Class,
1196
+ };
1197
+ const addRunDependency = (dep) => {
1198
+ if (dep === "loading-workers" && this.#workersLoadedCount >= PTHREAD_POOL_SIZE) {
1199
+ setImmediate(() => this.#removeRunDependencyCallback?.(dep));
1200
+ }
1201
+ };
1202
+ const removeRunDependency = (_dep) => { };
1203
+ this.#removeRunDependencyCallback = removeRunDependency;
1204
+ const webCrypto = {
1205
+ getRandomValues: (arr) => {
1206
+ if (!arr || !ArrayBuffer.isView(arr)) {
1207
+ throw new TypeError("crypto.getRandomValues expects a TypedArray");
1208
+ }
1209
+ const bytes = Buffer.from(arr.buffer, arr.byteOffset, arr.byteLength);
1210
+ randomFillSync(bytes);
1211
+ return arr;
1212
+ },
1213
+ };
1214
+ const selfObj = {
1215
+ __swData: { dynamic_data: { hsdp: {}, dynamic_modules: [] } },
1216
+ WhatsAppVoipWasmCallbacks: wasmCallbacks,
1217
+ WhatsAppVoipWasmWorkerCompatibleCallbacks: wasmCallbacks,
1218
+ crypto: webCrypto,
1219
+ };
1220
+ selfObj.self = selfObj;
1221
+ selfObj.window = selfObj;
1222
+ selfObj.globalThis = selfObj;
1223
+ if (typeof global !== "undefined") {
1224
+ global.WhatsAppVoipWasmCallbacks = wasmCallbacks;
1225
+ global.WhatsAppVoipWasmWorkerCompatibleCallbacks = wasmCallbacks;
1226
+ }
1227
+ const context = vm.createContext({
1228
+ self: selfObj, globalThis: selfObj, global: selfObj, window: selfObj,
1229
+ console, setTimeout, setInterval, clearTimeout, clearInterval,
1230
+ queueMicrotask, performance, babelHelpers, __d,
1231
+ require: this.#requireModule,
1232
+ addRunDependency, removeRunDependency,
1233
+ WebAssembly, SharedArrayBuffer,
1234
+ Atomics: this.#createAtomicsWrapper(memory),
1235
+ Int8Array, Uint8Array, Int16Array, Uint16Array, Int32Array, Uint32Array,
1236
+ Float32Array, Float64Array, BigInt64Array, BigUint64Array,
1237
+ ArrayBuffer, DataView, Error, TypeError, RangeError, Promise,
1238
+ Map, Set, WeakMap, WeakSet, Symbol, Object, Array, String, Number,
1239
+ Boolean, Math, Date, JSON, RegExp, Function, Proxy, Reflect,
1240
+ crypto: webCrypto,
1241
+ WhatsAppVoipWasmCallbacks: wasmCallbacks,
1242
+ WhatsAppVoipWasmWorkerCompatibleCallbacks: wasmCallbacks,
1243
+ navigator: {
1244
+ userAgent: "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36",
1245
+ hardwareConcurrency: 4,
1246
+ },
1247
+ process: undefined,
1248
+ document: { currentScript: null },
1249
+ location: { href: "file:///wasm" },
1250
+ Worker: class {
1251
+ constructor() { }
1252
+ postMessage() { }
1253
+ terminate() { }
1254
+ addEventListener() { }
1255
+ },
1256
+ fetch: async () => { throw new Error("fetch not supported"); },
1257
+ XMLHttpRequest: class {
1258
+ open() { }
1259
+ send() { }
1260
+ setRequestHeader() { }
1261
+ },
1262
+ Blob: class {
1263
+ constructor() { }
1264
+ },
1265
+ URL: { createObjectURL: () => "blob:fake", revokeObjectURL: () => { } },
1266
+ Image: class {
1267
+ src = "";
1268
+ onload = null;
1269
+ onerror = null;
1270
+ },
1271
+ Audio: class {
1272
+ src = "";
1273
+ addEventListener() { }
1274
+ },
1275
+ __NODE_PTHREAD: {
1276
+ getUnusedWorker: () => {
1277
+ if (this.#unusedWorkers.length === 0)
1278
+ return null;
1279
+ const worker = this.#unusedWorkers.pop();
1280
+ this.#runningWorkers.push(worker);
1281
+ return worker;
1282
+ },
1283
+ returnWorkerToPool: (worker) => {
1284
+ const idx = this.#runningWorkers.indexOf(worker);
1285
+ if (idx >= 0) {
1286
+ this.#runningWorkers.splice(idx, 1);
1287
+ this.#unusedWorkers.push(worker);
1288
+ }
1289
+ },
1290
+ spawnThread: (params) => {
1291
+ const worker = this.#unusedWorkers.pop();
1292
+ if (!worker)
1293
+ return 6;
1294
+ this.#runningWorkers.push(worker);
1295
+ this.#pthreads[params.pthread_ptr] = worker;
1296
+ worker.pthread_ptr = params.pthread_ptr;
1297
+ const pthreadTable = this.#instance?.PThread?.pthreads;
1298
+ if (pthreadTable)
1299
+ pthreadTable[params.pthread_ptr] = worker;
1300
+ worker.postMessage({
1301
+ cmd: "run",
1302
+ start_routine: params.startRoutine,
1303
+ arg: params.arg,
1304
+ pthread_ptr: params.pthread_ptr,
1305
+ });
1306
+ return 0;
1307
+ },
1308
+ unusedWorkersCount: () => this.#unusedWorkers.length,
1309
+ runningWorkersCount: () => this.#runningWorkers.length,
1310
+ },
1311
+ __IS_NODE_PTHREAD_ENV: true,
1312
+ });
1313
+ context.self = context;
1314
+ context.globalThis = context;
1315
+ context.global = context;
1316
+ context.window = context;
1317
+ return context;
1318
+ };
1319
+ #createAtomicsWrapper = (_memory) => {
1320
+ const atomicsWrapper = {
1321
+ add: Atomics.add.bind(Atomics),
1322
+ and: Atomics.and.bind(Atomics),
1323
+ compareExchange: Atomics.compareExchange.bind(Atomics),
1324
+ exchange: Atomics.exchange.bind(Atomics),
1325
+ isLockFree: Atomics.isLockFree.bind(Atomics),
1326
+ load: Atomics.load.bind(Atomics),
1327
+ or: Atomics.or.bind(Atomics),
1328
+ store: Atomics.store.bind(Atomics),
1329
+ sub: Atomics.sub.bind(Atomics),
1330
+ xor: Atomics.xor.bind(Atomics),
1331
+ notify: (typedArray, index, count) => {
1332
+ try {
1333
+ return Atomics.notify(typedArray, index, count);
1334
+ }
1335
+ catch (e) {
1336
+ if (e?.message?.includes("futex_wake") || e?.message?.includes("main_browser_thread"))
1337
+ return 0;
1338
+ throw e;
1339
+ }
1340
+ },
1341
+ waitAsync: Atomics.waitAsync
1342
+ ? Atomics.waitAsync.bind(Atomics)
1343
+ : () => ({ async: true, value: Promise.resolve("ok") }),
1344
+ wait: (typedArray, index, value, timeout) => {
1345
+ const currentValue = Atomics.load(typedArray, index);
1346
+ if (currentValue !== value)
1347
+ return "not-equal";
1348
+ if (timeout !== undefined && timeout <= 0)
1349
+ return "timed-out";
1350
+ return "timed-out";
1351
+ },
1352
+ [Symbol.toStringTag]: "Atomics",
1353
+ };
1354
+ return atomicsWrapper;
1355
+ };
1356
+ }
1357
+ _a = WasmEngine;
1358
+ export default WasmEngine;