@areumtecnologia/wasockets 2.0.0-alpha.1 → 2.2.3

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 (46) hide show
  1. package/README.md +1929 -1649
  2. package/lib/Defaults/baileys-version.json +1 -1
  3. package/lib/Defaults/connection.js +14 -1
  4. package/lib/Socket/index.js +51 -48
  5. package/lib/Socket/messages-recv.js +74 -13
  6. package/lib/Socket/messages-send.js +50 -25
  7. package/lib/Socket/socket.js +13 -0
  8. package/lib/Socket/voip.js +123 -0
  9. package/lib/Store/make-cache-manager-store.js +14 -5
  10. package/lib/Types/index.d.ts +4 -0
  11. package/lib/Utils/auth-utils.js +16 -1
  12. package/lib/Utils/browser-utils.js +6 -2
  13. package/lib/Utils/generics.js +47 -8
  14. package/lib/Utils/index.d.ts +1 -0
  15. package/lib/Utils/messages-media.js +44 -21
  16. package/lib/Utils/pre-key-manager.js +16 -1
  17. package/lib/Utils/validate-connection.js +10 -11
  18. package/lib/VoIP/VoIPCrypto.js +150 -0
  19. package/lib/VoIP/VoIPManager.js +469 -0
  20. package/lib/VoIP/VoIPMediaEngine.js +224 -0
  21. package/lib/VoIP/VoIPProtocol.js +354 -0
  22. package/lib/VoIP/VoIPRelayTransport.js +173 -0
  23. package/lib/VoIP/VoIPSession.js +314 -0
  24. package/lib/VoIP/assets/wasm/loader.js +5 -0
  25. package/lib/VoIP/assets/wasm/whatsapp.wasm +0 -0
  26. package/lib/VoIP/assets/wasm/worker-modules.js +305 -0
  27. package/lib/VoIP/engine/audio-feeder.d.mts +15 -0
  28. package/lib/VoIP/engine/audio-feeder.mjs +243 -0
  29. package/lib/VoIP/engine/index.d.mts +91 -0
  30. package/lib/VoIP/engine/index.mjs +1683 -0
  31. package/lib/VoIP/engine/relay-transport.d.mts +43 -0
  32. package/lib/VoIP/engine/relay-transport.mjs +607 -0
  33. package/lib/VoIP/engine/signaling.d.mts +44 -0
  34. package/lib/VoIP/engine/signaling.mjs +893 -0
  35. package/lib/VoIP/engine/types.d.mts +183 -0
  36. package/lib/VoIP/engine/types.mjs +17 -0
  37. package/lib/VoIP/engine/wasm-engine.d.mts +103 -0
  38. package/lib/VoIP/engine/wasm-engine.mjs +1397 -0
  39. package/lib/VoIP/engine/worker-bootstrap.mjs +1049 -0
  40. package/lib/VoIP/index.js +51 -0
  41. package/lib/VoIP/utils/audio.d.ts +28 -0
  42. package/lib/VoIP/utils/audio.js +148 -0
  43. package/lib/WABinary/generic-utils.js +22 -6
  44. package/lib/index.d.ts +382 -274
  45. package/lib/index.js +5 -0
  46. package/package.json +28 -32
@@ -0,0 +1,51 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", { value: true });
4
+
5
+ const { VoIPCrypto, deriveVoIPKeys, computeSRTPIV, encryptRTPPayload, decryptRTPPayload, computeAuthTag } = require("./VoIPCrypto");
6
+ const { VoIPProtocol, buildOfferStanza, buildAcceptStanza, buildRejectStanza, buildTerminateStanza, buildRelayQueryIq, parseRelayEndpoints, parseCallNode } = require("./VoIPProtocol");
7
+ const { VoIPRelayTransport } = require("./VoIPRelayTransport");
8
+ const { VoIPMediaEngine } = require("./VoIPMediaEngine");
9
+ const { VoIPSession, CallState } = require("./VoIPSession");
10
+ const { VoIPManager, makeVoIPManager } = require("./VoIPManager");
11
+ const { makeVoipSocket } = require("../Socket/voip");
12
+ const audioUtils = require("./utils/audio");
13
+
14
+ module.exports = {
15
+ // Socket Mixin
16
+ makeVoipSocket,
17
+
18
+ // Audio DSP & Format Helpers
19
+ audioUtils,
20
+ ...audioUtils,
21
+
22
+ // High-Level Manager & Engine
23
+ VoIPManager,
24
+ makeVoIPManager,
25
+
26
+ // Session & States
27
+ VoIPSession,
28
+ CallState,
29
+
30
+ // Media & Transport
31
+ VoIPMediaEngine,
32
+ VoIPRelayTransport,
33
+
34
+ // Protocol Stanzas
35
+ VoIPProtocol,
36
+ buildOfferStanza,
37
+ buildAcceptStanza,
38
+ buildRejectStanza,
39
+ buildTerminateStanza,
40
+ buildRelayQueryIq,
41
+ parseRelayEndpoints,
42
+ parseCallNode,
43
+
44
+ // Crypto
45
+ VoIPCrypto,
46
+ deriveVoIPKeys,
47
+ computeSRTPIV,
48
+ encryptRTPPayload,
49
+ decryptRTPPayload,
50
+ computeAuthTag
51
+ };
@@ -0,0 +1,28 @@
1
+ /// <reference types="node" />
2
+
3
+ export interface WavHeaderOptions {
4
+ sampleRate?: number;
5
+ numChannels?: number;
6
+ bitDepth?: number;
7
+ dataByteLength?: number;
8
+ }
9
+
10
+ export interface AudioMetrics {
11
+ rms: number;
12
+ volumeDbfs: number;
13
+ }
14
+
15
+ export declare function float32ToInt16(float32: Float32Array, asBuffer?: false): Int16Array;
16
+ export declare function float32ToInt16(float32: Float32Array, asBuffer: true): Buffer;
17
+ export declare function float32ToInt16(float32: Float32Array, asBuffer?: boolean): Int16Array | Buffer;
18
+
19
+ export declare function int16ToFloat32(int16OrBuffer: Int16Array | Buffer | Uint8Array): Float32Array;
20
+
21
+ export declare function resampleFloat32(inputSamples: Float32Array, fromRate: number, toRate: number): Float32Array;
22
+
23
+ export declare function createWavHeader(options?: WavHeaderOptions): Buffer;
24
+
25
+ export declare function calculateRmsDbfs(float32: Float32Array): AudioMetrics;
26
+
27
+ export declare function createSilenceBuffer(durationMs: number, sampleRate?: number): Float32Array;
28
+
@@ -0,0 +1,148 @@
1
+ "use strict";
2
+
3
+ /**
4
+ * Pure, zero-dependency audio DSP and format conversion utilities for WaSockets VoIP
5
+ */
6
+
7
+ /**
8
+ * Converts a Float32Array (-1.0 to 1.0) to 16-bit signed PCM (Int16Array or Buffer)
9
+ * @param {Float32Array} float32 Samples normalized between -1.0 and 1.0
10
+ * @param {boolean} [asBuffer=false] Whether to return a Node.js Buffer instead of Int16Array
11
+ * @returns {Int16Array|Buffer} 16-bit PCM samples
12
+ */
13
+ function float32ToInt16(float32, asBuffer = false) {
14
+ const len = float32.length;
15
+ const int16 = new Int16Array(len);
16
+ for (let i = 0; i < len; i++) {
17
+ const s = Math.max(-1, Math.min(1, float32[i]));
18
+ int16[i] = s < 0 ? s * 0x8000 : s * 0x7FFF;
19
+ }
20
+ if (asBuffer) {
21
+ return Buffer.from(int16.buffer, int16.byteOffset, int16.byteLength);
22
+ }
23
+ return int16;
24
+ }
25
+
26
+ /**
27
+ * Converts a 16-bit signed PCM (Int16Array or Buffer) to Float32Array (-1.0 to 1.0)
28
+ * @param {Int16Array|Buffer|Uint8Array} int16OrBuffer
29
+ * @returns {Float32Array}
30
+ */
31
+ function int16ToFloat32(int16OrBuffer) {
32
+ let int16;
33
+ if (int16OrBuffer instanceof Int16Array) {
34
+ int16 = int16OrBuffer;
35
+ } else {
36
+ const buf = Buffer.isBuffer(int16OrBuffer) ? int16OrBuffer : Buffer.from(int16OrBuffer);
37
+ int16 = new Int16Array(buf.buffer, buf.byteOffset, Math.floor(buf.byteLength / 2));
38
+ }
39
+ const len = int16.length;
40
+ const float32 = new Float32Array(len);
41
+ for (let i = 0; i < len; i++) {
42
+ float32[i] = int16[i] / 32768.0;
43
+ }
44
+ return float32;
45
+ }
46
+
47
+ /**
48
+ * Fast linear interpolation resampler for PCM audio
49
+ * @param {Float32Array} inputSamples Mono Float32Array samples
50
+ * @param {number} fromRate Source sample rate (e.g. 16000)
51
+ * @param {number} toRate Destination sample rate (e.g. 8000, 24000, 48000)
52
+ * @returns {Float32Array} Resampled Float32Array
53
+ */
54
+ function resampleFloat32(inputSamples, fromRate, toRate) {
55
+ if (fromRate === toRate || inputSamples.length === 0) {
56
+ return new Float32Array(inputSamples);
57
+ }
58
+ const ratio = fromRate / toRate;
59
+ const outputLength = Math.round(inputSamples.length / ratio);
60
+ const output = new Float32Array(outputLength);
61
+
62
+ for (let i = 0; i < outputLength; i++) {
63
+ const srcPos = i * ratio;
64
+ const index = Math.floor(srcPos);
65
+ const frac = srcPos - index;
66
+
67
+ const s0 = inputSamples[index] ?? 0;
68
+ const s1 = inputSamples[index + 1] ?? s0;
69
+ output[i] = s0 + frac * (s1 - s0);
70
+ }
71
+ return output;
72
+ }
73
+
74
+ /**
75
+ * Creates a standard 44-byte RIFF/WAVE header
76
+ * @param {Object} options
77
+ * @param {number} [options.sampleRate=16000]
78
+ * @param {number} [options.numChannels=1]
79
+ * @param {number} [options.bitDepth=16]
80
+ * @param {number} [options.dataByteLength=0]
81
+ * @returns {Buffer}
82
+ */
83
+ function createWavHeader({ sampleRate = 16000, numChannels = 1, bitDepth = 16, dataByteLength = 0 } = {}) {
84
+ const header = Buffer.alloc(44);
85
+ const byteRate = (sampleRate * numChannels * bitDepth) / 8;
86
+ const blockAlign = (numChannels * bitDepth) / 8;
87
+ const chunkSize = 36 + dataByteLength;
88
+
89
+ // RIFF chunk descriptor
90
+ header.write("RIFF", 0);
91
+ header.writeUInt32LE(chunkSize, 4);
92
+ header.write("WAVE", 8);
93
+
94
+ // "fmt " sub-chunk
95
+ header.write("fmt ", 12);
96
+ header.writeUInt32LE(16, 16); // Subchunk1Size for PCM
97
+ header.writeUInt16LE(1, 20); // AudioFormat 1 = PCM
98
+ header.writeUInt16LE(numChannels, 22);
99
+ header.writeUInt32LE(sampleRate, 24);
100
+ header.writeUInt32LE(byteRate, 28);
101
+ header.writeUInt16LE(blockAlign, 32);
102
+ header.writeUInt16LE(bitDepth, 34);
103
+
104
+ // "data" sub-chunk
105
+ header.write("data", 36);
106
+ header.writeUInt32LE(dataByteLength, 40);
107
+
108
+ return header;
109
+ }
110
+
111
+ /**
112
+ * Calculates Root Mean Square (RMS) and volume level in dBFS
113
+ * @param {Float32Array} float32
114
+ * @returns {{ rms: number, volumeDbfs: number }}
115
+ */
116
+ function calculateRmsDbfs(float32) {
117
+ let sum = 0;
118
+ const len = float32.length;
119
+ if (len === 0) return { rms: 0, volumeDbfs: -100 };
120
+
121
+ for (let i = 0; i < len; i++) {
122
+ sum += float32[i] * float32[i];
123
+ }
124
+ const rms = Math.sqrt(sum / len);
125
+ const volumeDbfs = rms > 0.00001 ? Math.round(20 * Math.log10(rms)) : -100;
126
+ return { rms, volumeDbfs };
127
+ }
128
+
129
+ /**
130
+ * Creates a silent audio frame (Float32Array) of specified duration
131
+ * @param {number} durationMs Duration in milliseconds
132
+ * @param {number} [sampleRate=16000] Sample rate in Hz
133
+ * @returns {Float32Array}
134
+ */
135
+ function createSilenceBuffer(durationMs, sampleRate = 16000) {
136
+ const totalSamples = Math.floor((durationMs / 1000) * sampleRate);
137
+ return new Float32Array(totalSamples);
138
+ }
139
+
140
+ module.exports = {
141
+ float32ToInt16,
142
+ int16ToFloat32,
143
+ resampleFloat32,
144
+ createWavHeader,
145
+ calculateRmsDbfs,
146
+ createSilenceBuffer
147
+ };
148
+
@@ -5,12 +5,29 @@ Object.defineProperty(exports, "__esModule", { value: true })
5
5
  const { Boom } = require("@hapi/boom")
6
6
  const { proto } = require("../../WAProto")
7
7
 
8
+ const binaryNodeChildrenCache = new WeakMap()
9
+
8
10
  // some extra useful utilities
9
11
  const getBinaryNodeChildren = (node, childTag) => {
10
- if (Array.isArray(node?.content)) {
11
- return node.content.filter(item => item.tag === childTag)
12
+ if (!Array.isArray(node?.content)) {
13
+ return []
12
14
  }
13
- return []
15
+ let map = binaryNodeChildrenCache.get(node)
16
+ if (!map) {
17
+ map = new Map()
18
+ for (const item of node.content) {
19
+ if (item && typeof item === 'object' && item.tag) {
20
+ let list = map.get(item.tag)
21
+ if (!list) {
22
+ list = []
23
+ map.set(item.tag, list)
24
+ }
25
+ list.push(item)
26
+ }
27
+ }
28
+ binaryNodeChildrenCache.set(node, map)
29
+ }
30
+ return map.get(childTag) || []
14
31
  }
15
32
 
16
33
  const getAllBinaryNodeChildren = ({ content }) => {
@@ -21,9 +38,8 @@ const getAllBinaryNodeChildren = ({ content }) => {
21
38
  }
22
39
 
23
40
  const getBinaryNodeChild = (node, childTag) => {
24
- if (Array.isArray(node?.content)) {
25
- return node?.content.find(item => item.tag === childTag)
26
- }
41
+ const children = getBinaryNodeChildren(node, childTag)
42
+ return children[0]
27
43
  }
28
44
 
29
45
  const getBinaryNodeChildBuffer = (node, childTag) => {