whalibmob 5.14.14 → 5.14.15
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.
- package/lib/Client.js +5 -1
- package/lib/DeviceManager.js +24 -2
- package/package.json +1 -1
package/lib/Client.js
CHANGED
|
@@ -407,7 +407,11 @@ class WhalibmobClient extends EventEmitter {
|
|
|
407
407
|
// groupJid → parsed metadata. Mirrors DeviceManager's device cache: a TTL
|
|
408
408
|
// so membership changes we never saw a notification for still heal, plus
|
|
409
409
|
// in-flight dedup so a burst of sends to the same group issues one IQ.
|
|
410
|
-
|
|
410
|
+
// `stdTTL`, not `ttl` — see the note in DeviceManager. Written the other
|
|
411
|
+
// way this held a group's participant list for the life of the connection,
|
|
412
|
+
// so anyone who joined or left after it was first read stayed wrong until
|
|
413
|
+
// a reconnect or an explicit { force: true }.
|
|
414
|
+
this._groupMetaCache = new NodeCache({ stdTTL: GROUP_META_CACHE_TTL });
|
|
411
415
|
this._groupMetaInflight = new Map(); // groupJid → Promise<metadata>
|
|
412
416
|
this._groupMembers = new Map(); // groupJid → Set<memberJid>
|
|
413
417
|
this._lidToPn = new Map(); // LID user → phone number
|
package/lib/DeviceManager.js
CHANGED
|
@@ -153,7 +153,16 @@ class DeviceManager {
|
|
|
153
153
|
constructor(client) {
|
|
154
154
|
this._client = client;
|
|
155
155
|
// phone → deviceId[] (TTL-based: expires after 5 min, triggers fresh usync)
|
|
156
|
-
|
|
156
|
+
//
|
|
157
|
+
// The option is `stdTTL`. It was `ttl`, which is the name of the per-entry
|
|
158
|
+
// argument to set(), not of the default in the constructor — an unknown
|
|
159
|
+
// option is simply ignored, so the cache was built with no expiry at all
|
|
160
|
+
// and a contact's device list, once learned, was never asked about again
|
|
161
|
+
// for the life of the connection. Someone who linked WhatsApp Web or a
|
|
162
|
+
// desktop while the client was up stayed invisible: their new device was
|
|
163
|
+
// left out of every stanza, and a stanza that does not cover a recipient's
|
|
164
|
+
// current devices is refused by the server.
|
|
165
|
+
this._deviceCache = new NodeCache({ stdTTL: DEVICE_CACHE_TTL });
|
|
157
166
|
// phone → Promise<jids[]> (in-flight usync dedup)
|
|
158
167
|
this._usyncInflight = new Map();
|
|
159
168
|
// own device list cache + expiry timestamp (refreshed every 5 min)
|
|
@@ -259,7 +268,20 @@ class DeviceManager {
|
|
|
259
268
|
_saveToDisk() {
|
|
260
269
|
if (!this._sessionDir || !this._cacheFile) return;
|
|
261
270
|
try {
|
|
262
|
-
|
|
271
|
+
// The snapshot mirrors the cache on every write, but nothing tells it
|
|
272
|
+
// when an entry expires — so once entries actually start expiring it
|
|
273
|
+
// keeps them, and writing it out unfiltered would put a device list on
|
|
274
|
+
// disk after the cache had already decided it was too old to trust. The
|
|
275
|
+
// next start reads that file back in, and the expiry never happens.
|
|
276
|
+
//
|
|
277
|
+
// Ask the cache what it still holds. `keys()` is no use here: it lists
|
|
278
|
+
// expired entries too, until the periodic sweep gets to them. `has()`
|
|
279
|
+
// answers for the entry itself.
|
|
280
|
+
const entries = {};
|
|
281
|
+
for (const key of Object.keys(this._cacheSnapshot)) {
|
|
282
|
+
if (this._deviceCache.has(key)) entries[key] = this._cacheSnapshot[key];
|
|
283
|
+
else delete this._cacheSnapshot[key];
|
|
284
|
+
}
|
|
263
285
|
|
|
264
286
|
// ── Combined cache file ─────────────────────────────────────────────────
|
|
265
287
|
fs.writeFileSync(
|