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 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
- this._groupMetaCache = new NodeCache({ ttl: GROUP_META_CACHE_TTL });
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
@@ -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
- this._deviceCache = new NodeCache({ ttl: DEVICE_CACHE_TTL });
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
- const entries = Object.assign({}, this._cacheSnapshot);
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(
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "whalibmob",
3
- "version": "5.14.14",
3
+ "version": "5.14.15",
4
4
  "description": "WhatsApp library for interaction with WhatsApp Mobile API and web ",
5
5
  "author": "Kunboruto20",
6
6
  "main": "index.js",