@nexustechpro/baileys 2.0.2 → 2.0.5

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 (102) hide show
  1. package/LICENSE +1 -1
  2. package/README.md +924 -1299
  3. package/lib/Defaults/baileys-version.json +6 -2
  4. package/lib/Defaults/index.js +172 -172
  5. package/lib/Signal/libsignal.js +380 -292
  6. package/lib/Signal/lid-mapping.js +264 -171
  7. package/lib/Socket/Client/index.js +2 -2
  8. package/lib/Socket/Client/types.js +10 -10
  9. package/lib/Socket/Client/websocket.js +45 -310
  10. package/lib/Socket/business.js +375 -375
  11. package/lib/Socket/chats.js +909 -963
  12. package/lib/Socket/communities.js +430 -430
  13. package/lib/Socket/groups.js +342 -342
  14. package/lib/Socket/index.js +22 -22
  15. package/lib/Socket/messages-recv.js +777 -743
  16. package/lib/Socket/messages-send.js +295 -305
  17. package/lib/Socket/mex.js +50 -50
  18. package/lib/Socket/newsletter.js +148 -148
  19. package/lib/Socket/nexus-handler.js +75 -261
  20. package/lib/Socket/socket.js +709 -1201
  21. package/lib/Store/index.js +5 -5
  22. package/lib/Store/make-cache-manager-store.js +81 -81
  23. package/lib/Store/make-in-memory-store.js +416 -416
  24. package/lib/Store/make-ordered-dictionary.js +81 -81
  25. package/lib/Store/object-repository.js +30 -30
  26. package/lib/Types/Auth.js +1 -1
  27. package/lib/Types/Bussines.js +1 -1
  28. package/lib/Types/Call.js +1 -1
  29. package/lib/Types/Chat.js +7 -7
  30. package/lib/Types/Contact.js +1 -1
  31. package/lib/Types/Events.js +1 -1
  32. package/lib/Types/GroupMetadata.js +1 -1
  33. package/lib/Types/Label.js +24 -24
  34. package/lib/Types/LabelAssociation.js +6 -6
  35. package/lib/Types/Message.js +10 -10
  36. package/lib/Types/Newsletter.js +28 -28
  37. package/lib/Types/Product.js +1 -1
  38. package/lib/Types/Signal.js +1 -1
  39. package/lib/Types/Socket.js +2 -2
  40. package/lib/Types/State.js +12 -12
  41. package/lib/Types/USync.js +1 -1
  42. package/lib/Types/index.js +25 -25
  43. package/lib/Utils/auth-utils.js +264 -256
  44. package/lib/Utils/baileys-event-stream.js +55 -55
  45. package/lib/Utils/browser-utils.js +27 -27
  46. package/lib/Utils/business.js +228 -230
  47. package/lib/Utils/chat-utils.js +694 -764
  48. package/lib/Utils/crypto.js +109 -135
  49. package/lib/Utils/decode-wa-message.js +310 -314
  50. package/lib/Utils/event-buffer.js +547 -547
  51. package/lib/Utils/generics.js +297 -297
  52. package/lib/Utils/history.js +91 -83
  53. package/lib/Utils/index.js +21 -20
  54. package/lib/Utils/key-store.js +17 -0
  55. package/lib/Utils/link-preview.js +97 -98
  56. package/lib/Utils/logger.js +2 -2
  57. package/lib/Utils/lt-hash.js +47 -47
  58. package/lib/Utils/make-mutex.js +39 -39
  59. package/lib/Utils/message-retry-manager.js +148 -148
  60. package/lib/Utils/messages-media.js +534 -534
  61. package/lib/Utils/messages.js +705 -705
  62. package/lib/Utils/noise-handler.js +255 -255
  63. package/lib/Utils/pre-key-manager.js +105 -105
  64. package/lib/Utils/process-message.js +412 -412
  65. package/lib/Utils/signal.js +160 -158
  66. package/lib/Utils/use-multi-file-auth-state.js +120 -120
  67. package/lib/Utils/validate-connection.js +194 -194
  68. package/lib/WABinary/constants.js +1300 -1300
  69. package/lib/WABinary/decode.js +237 -237
  70. package/lib/WABinary/encode.js +232 -232
  71. package/lib/WABinary/generic-utils.js +252 -211
  72. package/lib/WABinary/index.js +5 -5
  73. package/lib/WABinary/jid-utils.js +279 -95
  74. package/lib/WABinary/types.js +1 -1
  75. package/lib/WAM/BinaryInfo.js +9 -9
  76. package/lib/WAM/constants.js +22852 -22852
  77. package/lib/WAM/encode.js +149 -149
  78. package/lib/WAM/index.js +3 -3
  79. package/lib/WAUSync/Protocols/USyncContactProtocol.js +28 -28
  80. package/lib/WAUSync/Protocols/USyncDeviceProtocol.js +53 -53
  81. package/lib/WAUSync/Protocols/USyncDisappearingModeProtocol.js +26 -26
  82. package/lib/WAUSync/Protocols/USyncStatusProtocol.js +37 -37
  83. package/lib/WAUSync/Protocols/UsyncBotProfileProtocol.js +50 -50
  84. package/lib/WAUSync/Protocols/UsyncLIDProtocol.js +28 -28
  85. package/lib/WAUSync/Protocols/index.js +4 -4
  86. package/lib/WAUSync/USyncQuery.js +93 -93
  87. package/lib/WAUSync/USyncUser.js +22 -22
  88. package/lib/WAUSync/index.js +3 -3
  89. package/lib/index.js +66 -66
  90. package/package.json +171 -144
  91. package/lib/Signal/Group/ciphertext-message.js +0 -12
  92. package/lib/Signal/Group/group-session-builder.js +0 -30
  93. package/lib/Signal/Group/group_cipher.js +0 -100
  94. package/lib/Signal/Group/index.js +0 -12
  95. package/lib/Signal/Group/keyhelper.js +0 -18
  96. package/lib/Signal/Group/sender-chain-key.js +0 -26
  97. package/lib/Signal/Group/sender-key-distribution-message.js +0 -63
  98. package/lib/Signal/Group/sender-key-message.js +0 -66
  99. package/lib/Signal/Group/sender-key-name.js +0 -48
  100. package/lib/Signal/Group/sender-key-record.js +0 -41
  101. package/lib/Signal/Group/sender-key-state.js +0 -84
  102. package/lib/Signal/Group/sender-message-key.js +0 -26
@@ -1,171 +1,264 @@
1
- import { LRUCache } from 'lru-cache';
2
- import { isHostedPnUser, isLidUser, isPnUser, jidDecode, jidNormalizedUser, WAJIDDomains } from '../WABinary/index.js';
3
- export class LIDMappingStore {
4
- constructor(keys, logger, pnToLIDFunc) {
5
- this.mappingCache = new LRUCache({
6
- ttl: 7 * 24 * 60 * 60 * 1000, // 7 days
7
- ttlAutopurge: true,
8
- updateAgeOnGet: true
9
- });
10
- this.keys = keys;
11
- this.pnToLIDFunc = pnToLIDFunc;
12
- this.logger = logger;
13
- }
14
- /**
15
- * Store LID-PN mapping - USER LEVEL
16
- */
17
- async storeLIDPNMappings(pairs) {
18
- // Validate inputs
19
- const pairMap = {};
20
- for (const { lid, pn } of pairs) {
21
- if (!((isLidUser(lid) && isPnUser(pn)) || (isPnUser(lid) && isLidUser(pn)))) {
22
- this.logger.warn(`Invalid LID-PN mapping: ${lid}, ${pn}`);
23
- continue;
24
- }
25
- const lidDecoded = jidDecode(lid);
26
- const pnDecoded = jidDecode(pn);
27
- if (!lidDecoded || !pnDecoded)
28
- return;
29
- const pnUser = pnDecoded.user;
30
- const lidUser = lidDecoded.user;
31
- let existingLidUser = this.mappingCache.get(`pn:${pnUser}`);
32
- if (!existingLidUser) {
33
- this.logger.trace(`Cache miss for PN user ${pnUser}; checking database`);
34
- const stored = await this.keys.get('lid-mapping', [pnUser]);
35
- existingLidUser = stored[pnUser];
36
- if (existingLidUser) {
37
- // Update cache with database value
38
- this.mappingCache.set(`pn:${pnUser}`, existingLidUser);
39
- this.mappingCache.set(`lid:${existingLidUser}`, pnUser);
40
- }
41
- }
42
- if (existingLidUser === lidUser) {
43
- this.logger.debug({ pnUser, lidUser }, 'LID mapping already exists, skipping');
44
- continue;
45
- }
46
- pairMap[pnUser] = lidUser;
47
- }
48
- this.logger.trace({ pairMap }, `Storing ${Object.keys(pairMap).length} pn mappings`);
49
- await this.keys.transaction(async () => {
50
- for (const [pnUser, lidUser] of Object.entries(pairMap)) {
51
- await this.keys.set({
52
- 'lid-mapping': {
53
- [pnUser]: lidUser,
54
- [`${lidUser}_reverse`]: pnUser
55
- }
56
- });
57
- this.mappingCache.set(`pn:${pnUser}`, lidUser);
58
- this.mappingCache.set(`lid:${lidUser}`, pnUser);
59
- }
60
- }, 'lid-mapping');
61
- }
62
- /**
63
- * Get LID for PN - Returns device-specific LID based on user mapping
64
- */
65
- async getLIDForPN(pn) {
66
- return (await this.getLIDsForPNs([pn]))?.[0]?.lid || null;
67
- }
68
- async getLIDsForPNs(pns) {
69
- const usyncFetch = {};
70
- // mapped from pn to lid mapping to prevent duplication in results later
71
- const successfulPairs = {};
72
- for (const pn of pns) {
73
- if (!isPnUser(pn) && !isHostedPnUser(pn))
74
- continue;
75
- const decoded = jidDecode(pn);
76
- if (!decoded)
77
- continue;
78
- // Check cache first for PN LID mapping
79
- const pnUser = decoded.user;
80
- let lidUser = this.mappingCache.get(`pn:${pnUser}`);
81
- if (!lidUser) {
82
- // Cache miss - check database
83
- const stored = await this.keys.get('lid-mapping', [pnUser]);
84
- lidUser = stored[pnUser];
85
- if (lidUser) {
86
- this.mappingCache.set(`pn:${pnUser}`, lidUser);
87
- this.mappingCache.set(`lid:${lidUser}`, pnUser);
88
- }
89
- else {
90
- this.logger.trace(`No LID mapping found for PN user ${pnUser}; batch getting from USync`);
91
- const device = decoded.device || 0;
92
- let normalizedPn = jidNormalizedUser(pn);
93
- if (isHostedPnUser(normalizedPn)) {
94
- normalizedPn = `${pnUser}@s.whatsapp.net`;
95
- }
96
- if (!usyncFetch[normalizedPn]) {
97
- usyncFetch[normalizedPn] = [device];
98
- }
99
- else {
100
- usyncFetch[normalizedPn]?.push(device);
101
- }
102
- continue;
103
- }
104
- }
105
- lidUser = lidUser.toString();
106
- if (!lidUser) {
107
- this.logger.warn(`Invalid or empty LID user for PN ${pn}: lidUser = "${lidUser}"`);
108
- return null;
109
- }
110
- // Push the PN device ID to the LID to maintain device separation
111
- const pnDevice = decoded.device !== undefined ? decoded.device : 0;
112
- const deviceSpecificLid = `${lidUser}${!!pnDevice ? `:${pnDevice}` : ``}@${decoded.server === 'hosted' ? 'hosted.lid' : 'lid'}`;
113
- this.logger.trace(`getLIDForPN: ${pn} → ${deviceSpecificLid} (user mapping with device ${pnDevice})`);
114
- successfulPairs[pn] = { lid: deviceSpecificLid, pn };
115
- }
116
- if (Object.keys(usyncFetch).length > 0) {
117
- const result = await this.pnToLIDFunc?.(Object.keys(usyncFetch)); // this function already adds LIDs to mapping
118
- if (result && result.length > 0) {
119
- this.storeLIDPNMappings(result);
120
- for (const pair of result) {
121
- const pnDecoded = jidDecode(pair.pn);
122
- const pnUser = pnDecoded?.user;
123
- if (!pnUser)
124
- continue;
125
- const lidUser = jidDecode(pair.lid)?.user;
126
- if (!lidUser)
127
- continue;
128
- for (const device of usyncFetch[pair.pn]) {
129
- const deviceSpecificLid = `${lidUser}${!!device ? `:${device}` : ``}@${device === 99 ? 'hosted.lid' : 'lid'}`;
130
- this.logger.trace(`getLIDForPN: USYNC success for ${pair.pn} → ${deviceSpecificLid} (user mapping with device ${device})`);
131
- const deviceSpecificPn = `${pnUser}${!!device ? `:${device}` : ``}@${device === 99 ? 'hosted' : 's.whatsapp.net'}`;
132
- successfulPairs[deviceSpecificPn] = { lid: deviceSpecificLid, pn: deviceSpecificPn };
133
- }
134
- }
135
- }
136
- else {
137
- return null;
138
- }
139
- }
140
- return Object.values(successfulPairs);
141
- }
142
- /**
143
- * Get PN for LID - USER LEVEL with device construction
144
- */
145
- async getPNForLID(lid) {
146
- if (!isLidUser(lid))
147
- return null;
148
- const decoded = jidDecode(lid);
149
- if (!decoded)
150
- return null;
151
- // Check cache first for LID → PN mapping
152
- const lidUser = decoded.user;
153
- let pnUser = this.mappingCache.get(`lid:${lidUser}`);
154
- if (!pnUser || typeof pnUser !== 'string') {
155
- // Cache miss - check database
156
- const stored = await this.keys.get('lid-mapping', [`${lidUser}_reverse`]);
157
- pnUser = stored[`${lidUser}_reverse`];
158
- if (!pnUser || typeof pnUser !== 'string') {
159
- this.logger.trace(`No reverse mapping found for LID user: ${lidUser}`);
160
- return null;
161
- }
162
- this.mappingCache.set(`lid:${lidUser}`, pnUser);
163
- }
164
- // Construct device-specific PN JID
165
- const lidDevice = decoded.device !== undefined ? decoded.device : 0;
166
- const pnJid = `${pnUser}:${lidDevice}@${decoded.domainType === WAJIDDomains.HOSTED_LID ? 'hosted' : 's.whatsapp.net'}`;
167
- this.logger.trace(`Found reverse mapping: ${lid} → ${pnJid}`);
168
- return pnJid;
169
- }
170
- }
171
- //# sourceMappingURL=lid-mapping.js.map
1
+ import { LRUCache } from 'lru-cache'
2
+ import { isHostedPnUser, isLidUser, isPnUser, jidDecode, jidNormalizedUser, WAJIDDomains } from '../WABinary/index.js'
3
+
4
+ export class LIDMappingStore {
5
+ constructor(keys, logger, pnToLIDFunc) {
6
+ this.mappingCache = new LRUCache({ ttl: 3 * 24 * 60 * 60 * 1000, ttlAutopurge: true, updateAgeOnGet: true })
7
+ this.inflightLIDLookups = new Map()
8
+ this.inflightPNLookups = new Map()
9
+ this.keys = keys
10
+ this.logger = logger
11
+ this.pnToLIDFunc = pnToLIDFunc
12
+ }
13
+
14
+ async storeLIDPNMappings(pairs) {
15
+ if (!pairs.length) return
16
+
17
+ const validatedPairs = []
18
+ for (const { lid, pn } of pairs) {
19
+ if (!((isLidUser(lid) && isPnUser(pn)) || (isPnUser(lid) && isLidUser(pn)))) {
20
+ this.logger.warn(`Invalid LID-PN mapping: ${lid}, ${pn}`)
21
+ continue
22
+ }
23
+ const lidDecoded = jidDecode(lid)
24
+ const pnDecoded = jidDecode(pn)
25
+ if (!lidDecoded || !pnDecoded) continue // fixed: was `return`, skips only this pair
26
+ validatedPairs.push({ pnUser: pnDecoded.user, lidUser: lidDecoded.user })
27
+ }
28
+
29
+ if (!validatedPairs.length) return
30
+
31
+ // Batch check all cache misses in one DB call
32
+ const cacheMissSet = new Set()
33
+ const existingMappings = new Map()
34
+
35
+ for (const { pnUser } of validatedPairs) {
36
+ const cached = this.mappingCache.get(`pn:${pnUser}`)
37
+ if (cached) existingMappings.set(pnUser, cached)
38
+ else cacheMissSet.add(pnUser)
39
+ }
40
+
41
+ if (cacheMissSet.size > 0) {
42
+ this.logger.trace(`Batch fetching ${cacheMissSet.size} LID mappings from database`)
43
+ const stored = await this.keys.get('lid-mapping', [...cacheMissSet])
44
+ for (const pnUser of cacheMissSet) {
45
+ const lidUser = stored[pnUser]
46
+ if (lidUser) {
47
+ existingMappings.set(pnUser, lidUser)
48
+ this.mappingCache.set(`pn:${pnUser}`, lidUser)
49
+ this.mappingCache.set(`lid:${lidUser}`, pnUser)
50
+ }
51
+ }
52
+ }
53
+
54
+ const pairMap = {}
55
+ for (const { pnUser, lidUser } of validatedPairs) {
56
+ if (existingMappings.get(pnUser) === lidUser) {
57
+ this.logger.debug({ pnUser, lidUser }, 'LID mapping already exists, skipping')
58
+ continue
59
+ }
60
+ pairMap[pnUser] = lidUser
61
+ }
62
+
63
+ if (!Object.keys(pairMap).length) return
64
+
65
+ this.logger.trace({ pairMap }, `Storing ${Object.keys(pairMap).length} pn mappings`)
66
+
67
+ // Single batched keys.set inside transaction
68
+ const batchData = {}
69
+ for (const [pnUser, lidUser] of Object.entries(pairMap)) {
70
+ batchData[pnUser] = lidUser
71
+ batchData[`${lidUser}_reverse`] = pnUser
72
+ }
73
+
74
+ await this.keys.transaction(async () => {
75
+ await this.keys.set({ 'lid-mapping': batchData })
76
+ }, 'lid-mapping')
77
+
78
+ // Update cache only after successful DB write
79
+ for (const [pnUser, lidUser] of Object.entries(pairMap)) {
80
+ this.mappingCache.set(`pn:${pnUser}`, lidUser)
81
+ this.mappingCache.set(`lid:${lidUser}`, pnUser)
82
+ }
83
+ }
84
+
85
+ async getLIDForPN(pn) {
86
+ return (await this.getLIDsForPNs([pn]))?.[0]?.lid || null
87
+ }
88
+
89
+ async getLIDsForPNs(pns) {
90
+ if (!pns.length) return null
91
+ const sortedPns = [...new Set(pns)].sort()
92
+ const cacheKey = sortedPns.join(',')
93
+
94
+ const inflight = this.inflightLIDLookups.get(cacheKey)
95
+ if (inflight) {
96
+ this.logger.trace(`Coalescing getLIDsForPNs for ${sortedPns.length} PNs`)
97
+ return inflight
98
+ }
99
+
100
+ const promise = this._getLIDsForPNsImpl(pns)
101
+ this.inflightLIDLookups.set(cacheKey, promise)
102
+ try {
103
+ return await promise
104
+ } finally {
105
+ this.inflightLIDLookups.delete(cacheKey)
106
+ }
107
+ }
108
+
109
+ async _getLIDsForPNsImpl(pns) {
110
+ const usyncFetch = {}
111
+ const successfulPairs = {}
112
+ const pending = []
113
+
114
+ const addResolvedPair = (pn, decoded, lidUser) => {
115
+ const normalizedLidUser = lidUser.toString()
116
+ if (!normalizedLidUser) {
117
+ this.logger.warn(`Invalid or empty LID user for PN ${pn}: lidUser = "${lidUser}"`)
118
+ return false
119
+ }
120
+ const pnDevice = decoded.device !== undefined ? decoded.device : 0
121
+ const deviceSpecificLid = `${normalizedLidUser}${pnDevice ? `:${pnDevice}` : ''}@${decoded.server === 'hosted' ? 'hosted.lid' : 'lid'}`
122
+ this.logger.trace(`getLIDForPN: ${pn} ${deviceSpecificLid} (user mapping with device ${pnDevice})`)
123
+ successfulPairs[pn] = { lid: deviceSpecificLid, pn }
124
+ return true
125
+ }
126
+
127
+ for (const pn of pns) {
128
+ if (!isPnUser(pn) && !isHostedPnUser(pn)) continue
129
+ const decoded = jidDecode(pn)
130
+ if (!decoded) continue
131
+ const pnUser = decoded.user
132
+ const cached = this.mappingCache.get(`pn:${pnUser}`)
133
+ if (cached) {
134
+ addResolvedPair(pn, decoded, cached)
135
+ } else {
136
+ pending.push({ pn, pnUser, decoded })
137
+ }
138
+ }
139
+
140
+ if (pending.length) {
141
+ // Single batched DB fetch for all cache misses
142
+ const pnUsers = [...new Set(pending.map(p => p.pnUser))]
143
+ const stored = await this.keys.get('lid-mapping', pnUsers)
144
+
145
+ for (const pnUser of pnUsers) {
146
+ const lidUser = stored[pnUser]
147
+ if (lidUser) {
148
+ this.mappingCache.set(`pn:${pnUser}`, lidUser)
149
+ this.mappingCache.set(`lid:${lidUser}`, pnUser)
150
+ }
151
+ }
152
+
153
+ for (const { pn, pnUser, decoded } of pending) {
154
+ const cached = this.mappingCache.get(`pn:${pnUser}`)
155
+ if (cached) {
156
+ addResolvedPair(pn, decoded, cached)
157
+ } else {
158
+ this.logger.trace(`No LID mapping found for PN user ${pnUser}; batch getting from USync`)
159
+ const device = decoded.device || 0
160
+ let normalizedPn = jidNormalizedUser(pn)
161
+ if (isHostedPnUser(normalizedPn)) normalizedPn = `${pnUser}@s.whatsapp.net`
162
+ if (!usyncFetch[normalizedPn]) usyncFetch[normalizedPn] = [device]
163
+ else usyncFetch[normalizedPn].push(device)
164
+ }
165
+ }
166
+ }
167
+
168
+ if (Object.keys(usyncFetch).length > 0) {
169
+ const result = await this.pnToLIDFunc?.(Object.keys(usyncFetch))
170
+ if (result?.length > 0) {
171
+ await this.storeLIDPNMappings(result) // fixed: was fire-and-forget
172
+ for (const pair of result) {
173
+ const pnDecoded = jidDecode(pair.pn)
174
+ const pnUser = pnDecoded?.user
175
+ if (!pnUser) continue
176
+ const lidUser = jidDecode(pair.lid)?.user
177
+ if (!lidUser) continue
178
+ for (const device of usyncFetch[pair.pn] || []) {
179
+ const deviceSpecificLid = `${lidUser}${device ? `:${device}` : ''}@${device === 99 ? 'hosted.lid' : 'lid'}`
180
+ const deviceSpecificPn = `${pnUser}${device ? `:${device}` : ''}@${device === 99 ? 'hosted' : 's.whatsapp.net'}`
181
+ this.logger.trace(`getLIDForPN: USYNC success for ${pair.pn} → ${deviceSpecificLid} (user mapping with device ${device})`)
182
+ successfulPairs[deviceSpecificPn] = { lid: deviceSpecificLid, pn: deviceSpecificPn }
183
+ }
184
+ }
185
+ } else {
186
+ return null
187
+ }
188
+ }
189
+
190
+ return Object.values(successfulPairs).length ? Object.values(successfulPairs) : null
191
+ }
192
+
193
+ async getPNForLID(lid) {
194
+ return (await this.getPNsForLIDs([lid]))?.[0]?.pn || null
195
+ }
196
+
197
+ async getPNsForLIDs(lids) {
198
+ if (!lids.length) return null
199
+ const sortedLids = [...new Set(lids)].sort()
200
+ const cacheKey = sortedLids.join(',')
201
+
202
+ const inflight = this.inflightPNLookups.get(cacheKey)
203
+ if (inflight) {
204
+ this.logger.trace(`Coalescing getPNsForLIDs for ${sortedLids.length} LIDs`)
205
+ return inflight
206
+ }
207
+
208
+ const promise = this._getPNsForLIDsImpl(lids)
209
+ this.inflightPNLookups.set(cacheKey, promise)
210
+ try {
211
+ return await promise
212
+ } finally {
213
+ this.inflightPNLookups.delete(cacheKey)
214
+ }
215
+ }
216
+
217
+ async _getPNsForLIDsImpl(lids) {
218
+ const successfulPairs = {}
219
+ const pending = []
220
+
221
+ const addResolvedPair = (lid, decoded, pnUser) => {
222
+ if (!pnUser || typeof pnUser !== 'string') return false
223
+ const lidDevice = decoded.device !== undefined ? decoded.device : 0
224
+ const pnJid = `${pnUser}:${lidDevice}@${decoded.domainType === WAJIDDomains.HOSTED_LID ? 'hosted' : 's.whatsapp.net'}`
225
+ this.logger.trace(`Found reverse mapping: ${lid} → ${pnJid}`)
226
+ successfulPairs[lid] = { lid, pn: pnJid }
227
+ return true
228
+ }
229
+
230
+ for (const lid of lids) {
231
+ if (!isLidUser(lid)) continue
232
+ const decoded = jidDecode(lid)
233
+ if (!decoded) continue
234
+ const lidUser = decoded.user
235
+ const cached = this.mappingCache.get(`lid:${lidUser}`)
236
+ if (cached) {
237
+ addResolvedPair(lid, decoded, cached)
238
+ } else {
239
+ pending.push({ lid, lidUser, decoded })
240
+ }
241
+ }
242
+
243
+ if (pending.length) {
244
+ // Single batched DB fetch for all cache misses
245
+ const reverseKeys = [...new Set(pending.map(p => `${p.lidUser}_reverse`))]
246
+ const stored = await this.keys.get('lid-mapping', reverseKeys)
247
+
248
+ for (const { lid, lidUser, decoded } of pending) {
249
+ let pnUser = this.mappingCache.get(`lid:${lidUser}`)
250
+ if (!pnUser || typeof pnUser !== 'string') {
251
+ pnUser = stored[`${lidUser}_reverse`]
252
+ if (pnUser && typeof pnUser === 'string') {
253
+ this.mappingCache.set(`lid:${lidUser}`, pnUser)
254
+ this.mappingCache.set(`pn:${pnUser}`, lidUser)
255
+ }
256
+ }
257
+ if (pnUser) addResolvedPair(lid, decoded, pnUser)
258
+ else this.logger.trace(`No reverse mapping found for LID user: ${lidUser}`)
259
+ }
260
+ }
261
+
262
+ return Object.values(successfulPairs).length ? Object.values(successfulPairs) : null
263
+ }
264
+ }
@@ -1,3 +1,3 @@
1
- export * from './types.js';
2
- export * from './websocket.js';
1
+ export * from './types.js';
2
+ export * from './websocket.js';
3
3
  //# sourceMappingURL=index.js.map
@@ -1,11 +1,11 @@
1
- import { EventEmitter } from 'events';
2
- import { URL } from 'url';
3
- export class AbstractSocketClient extends EventEmitter {
4
- constructor(url, config) {
5
- super();
6
- this.url = url;
7
- this.config = config;
8
- this.setMaxListeners(0);
9
- }
10
- }
1
+ import { EventEmitter } from 'events';
2
+ import { URL } from 'url';
3
+ export class AbstractSocketClient extends EventEmitter {
4
+ constructor(url, config) {
5
+ super();
6
+ this.url = url;
7
+ this.config = config;
8
+ this.setMaxListeners(0);
9
+ }
10
+ }
11
11
  //# sourceMappingURL=types.js.map