@nexustechpro/baileys 2.0.2 → 2.0.6

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 (108) hide show
  1. package/LICENSE +1 -1
  2. package/README.md +924 -1299
  3. package/WAProto/index.js +22 -18
  4. package/lib/Defaults/baileys-version.json +6 -2
  5. package/lib/Defaults/index.js +173 -172
  6. package/lib/Signal/libsignal.js +395 -292
  7. package/lib/Signal/lid-mapping.js +264 -171
  8. package/lib/Socket/Client/index.js +2 -2
  9. package/lib/Socket/Client/types.js +10 -10
  10. package/lib/Socket/Client/websocket.js +45 -310
  11. package/lib/Socket/business.js +375 -375
  12. package/lib/Socket/chats.js +916 -963
  13. package/lib/Socket/communities.js +430 -430
  14. package/lib/Socket/groups.js +342 -342
  15. package/lib/Socket/index.js +21 -22
  16. package/lib/Socket/messages-recv.js +963 -743
  17. package/lib/Socket/messages-send.js +273 -321
  18. package/lib/Socket/mex.js +50 -50
  19. package/lib/Socket/newsletter.js +148 -148
  20. package/lib/Socket/nexus-handler.js +296 -247
  21. package/lib/Socket/registration.js +50 -33
  22. package/lib/Socket/socket.js +872 -1201
  23. package/lib/Store/index.js +5 -5
  24. package/lib/Store/make-cache-manager-store.js +81 -81
  25. package/lib/Store/make-in-memory-store.js +416 -416
  26. package/lib/Store/make-ordered-dictionary.js +81 -81
  27. package/lib/Store/object-repository.js +30 -30
  28. package/lib/Types/Auth.js +1 -1
  29. package/lib/Types/Bussines.js +1 -1
  30. package/lib/Types/Call.js +1 -1
  31. package/lib/Types/Chat.js +7 -7
  32. package/lib/Types/Contact.js +1 -1
  33. package/lib/Types/Events.js +1 -1
  34. package/lib/Types/GroupMetadata.js +1 -1
  35. package/lib/Types/Label.js +24 -24
  36. package/lib/Types/LabelAssociation.js +6 -6
  37. package/lib/Types/Message.js +10 -10
  38. package/lib/Types/Newsletter.js +37 -29
  39. package/lib/Types/Product.js +1 -1
  40. package/lib/Types/Signal.js +1 -1
  41. package/lib/Types/Socket.js +2 -2
  42. package/lib/Types/State.js +55 -12
  43. package/lib/Types/USync.js +1 -1
  44. package/lib/Types/index.js +25 -25
  45. package/lib/Utils/auth-utils.js +264 -256
  46. package/lib/Utils/baileys-event-stream.js +55 -55
  47. package/lib/Utils/browser-utils.js +27 -27
  48. package/lib/Utils/business.js +228 -230
  49. package/lib/Utils/chat-utils.js +726 -764
  50. package/lib/Utils/companion-reg-client-utils.js +34 -0
  51. package/lib/Utils/crypto.js +109 -135
  52. package/lib/Utils/decode-wa-message.js +342 -314
  53. package/lib/Utils/event-buffer.js +547 -547
  54. package/lib/Utils/generics.js +295 -297
  55. package/lib/Utils/history.js +91 -83
  56. package/lib/Utils/index.js +25 -20
  57. package/lib/Utils/key-store.js +17 -0
  58. package/lib/Utils/link-preview.js +107 -98
  59. package/lib/Utils/logger.js +2 -2
  60. package/lib/Utils/lt-hash.js +47 -47
  61. package/lib/Utils/make-mutex.js +39 -39
  62. package/lib/Utils/message-retry-manager.js +148 -148
  63. package/lib/Utils/messages-media.js +579 -535
  64. package/lib/Utils/messages.js +821 -706
  65. package/lib/Utils/noise-handler.js +255 -255
  66. package/lib/Utils/pre-key-manager.js +105 -105
  67. package/lib/Utils/process-message.js +430 -412
  68. package/lib/Utils/reporting-utils.js +155 -0
  69. package/lib/Utils/signal.js +191 -159
  70. package/lib/Utils/sync-action-utils.js +33 -0
  71. package/lib/Utils/tc-token-utils.js +162 -0
  72. package/lib/Utils/use-multi-file-auth-state.js +120 -120
  73. package/lib/Utils/validate-connection.js +194 -194
  74. package/lib/WABinary/constants.js +1306 -1300
  75. package/lib/WABinary/decode.js +237 -237
  76. package/lib/WABinary/encode.js +232 -232
  77. package/lib/WABinary/generic-utils.js +252 -211
  78. package/lib/WABinary/index.js +6 -5
  79. package/lib/WABinary/jid-utils.js +279 -95
  80. package/lib/WABinary/types.js +1 -1
  81. package/lib/WAM/BinaryInfo.js +9 -9
  82. package/lib/WAM/constants.js +22852 -22852
  83. package/lib/WAM/encode.js +149 -149
  84. package/lib/WAM/index.js +3 -3
  85. package/lib/WAUSync/Protocols/USyncContactProtocol.js +28 -28
  86. package/lib/WAUSync/Protocols/USyncDeviceProtocol.js +53 -53
  87. package/lib/WAUSync/Protocols/USyncDisappearingModeProtocol.js +26 -26
  88. package/lib/WAUSync/Protocols/USyncStatusProtocol.js +37 -37
  89. package/lib/WAUSync/Protocols/UsyncBotProfileProtocol.js +50 -50
  90. package/lib/WAUSync/Protocols/UsyncLIDProtocol.js +28 -28
  91. package/lib/WAUSync/Protocols/index.js +4 -4
  92. package/lib/WAUSync/USyncQuery.js +93 -93
  93. package/lib/WAUSync/USyncUser.js +22 -22
  94. package/lib/WAUSync/index.js +3 -3
  95. package/lib/index.js +65 -66
  96. package/package.json +172 -143
  97. package/lib/Signal/Group/ciphertext-message.js +0 -12
  98. package/lib/Signal/Group/group-session-builder.js +0 -30
  99. package/lib/Signal/Group/group_cipher.js +0 -100
  100. package/lib/Signal/Group/index.js +0 -12
  101. package/lib/Signal/Group/keyhelper.js +0 -18
  102. package/lib/Signal/Group/sender-chain-key.js +0 -26
  103. package/lib/Signal/Group/sender-key-distribution-message.js +0 -63
  104. package/lib/Signal/Group/sender-key-message.js +0 -66
  105. package/lib/Signal/Group/sender-key-name.js +0 -48
  106. package/lib/Signal/Group/sender-key-record.js +0 -41
  107. package/lib/Signal/Group/sender-key-state.js +0 -84
  108. 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