nexus-fca 2.1.1 → 2.1.2

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/CHANGELOG.md CHANGED
@@ -1,5 +1,16 @@
1
1
  # Changelog
2
2
 
3
+ ## [2.1.2] - Unreleased - CONTINUOUS IDLE RECOVERY
4
+ ### Added
5
+ - Soft-stale probing at 2 minutes idle (ping + conditional forced reconnect if no events within 5-8s)
6
+ - Wrapper around `listenMqtt` to automatically feed events into safety heartbeat (`recordEvent`) for precise idle detection
7
+
8
+ ### Improved
9
+ - Faster recovery from silent idle states (previously required >5 min or external trigger)
10
+ - Reduced chance of appearing online but unresponsive after short inactivity
11
+
12
+ ---
13
+
3
14
  ## [2.1.1] - 2025-08-27 - ADVANCED SESSION STABILITY
4
15
  ### 🛠 Added
5
16
  - Adaptive safe session refresh interval (dynamic based on risk level)
package/index.js CHANGED
@@ -239,6 +239,26 @@ function buildAPI(globalOptions, html, jar) {
239
239
  api[v.replace(".js", "")] = require("./src/" + v)(defaultFuncs, api, ctx);
240
240
  });
241
241
  api.listen = api.listenMqtt;
242
+ // Safety wrapper: ensure every inbound MQTT event updates safety lastEvent timestamp
243
+ if (!api._safetyWrappedListen) {
244
+ const _origListen = api.listenMqtt;
245
+ api.listenMqtt = function(callback) {
246
+ const wrapped = (err, evt) => {
247
+ if (!err && evt) {
248
+ try { globalSafety.recordEvent(); } catch(_) {}
249
+ }
250
+ if (typeof callback === 'function') callback(err, evt);
251
+ };
252
+ const emitter = _origListen(wrapped);
253
+ // Redundant defensive hooks
254
+ try {
255
+ emitter.on('message', () => globalSafety.recordEvent());
256
+ emitter.on('error', () => globalSafety.recordEvent());
257
+ } catch(_) {}
258
+ return emitter;
259
+ };
260
+ api._safetyWrappedListen = true;
261
+ }
242
262
  setInterval(async () => {
243
263
  api
244
264
  .refreshFb_dtsg()
@@ -66,6 +66,8 @@ class FacebookSafety {
66
66
  this._destroyed = false;
67
67
  this._postRefreshChecks = [];
68
68
  this._inFlightRefreshId = 0;
69
+ // New: probing guard to avoid overlapping soft-stale probes
70
+ this._probing = false;
69
71
 
70
72
  this.initSafety();
71
73
  }
@@ -306,10 +308,41 @@ class FacebookSafety {
306
308
  async _ensureMqttAlive() {
307
309
  if (!this.api || this._destroyed) return;
308
310
  try {
311
+ const now = Date.now();
309
312
  const disconnected = !this.ctx || !this.ctx.mqttClient || !this.ctx.mqttClient.connected;
310
- const stale = Date.now() - this._lastEventTs > 5 * 60 * 1000; // >5 min no events
313
+ const idle = now - this._lastEventTs;
314
+ const softStale = idle > 2 * 60 * 1000; // >2 min no events
315
+ const hardStale = idle > 5 * 60 * 1000; // >5 min no events (legacy threshold)
316
+ const stale = hardStale; // backwards compat naming
317
+
318
+ // If totally disconnected or hard stale -> reconnect immediately
311
319
  if (disconnected || stale) {
312
- await this._reconnectMqttWithBackoff(disconnected ? 'disconnected' : 'stale');
320
+ await this._reconnectMqttWithBackoff(disconnected ? 'disconnected' : 'hard-stale');
321
+ return;
322
+ }
323
+
324
+ // Soft-stale probing: connection claims to be open but no events for 2-5 minutes.
325
+ // We issue a ping and if still no events after probe window, we force a reconnect.
326
+ if (softStale && !this._probing) {
327
+ this._probing = true;
328
+ const prevTs = this._lastEventTs;
329
+ try {
330
+ if (this.ctx && this.ctx.mqttClient && this.ctx.mqttClient.connected) {
331
+ if (typeof this.ctx.mqttClient.ping === 'function') {
332
+ try { this.ctx.mqttClient.ping(); } catch(_) {}
333
+ }
334
+ }
335
+ } catch(_) {}
336
+ setTimeout(() => {
337
+ if (this._destroyed) return;
338
+ // If no new events arrived since probe start, treat as latent-dead connection
339
+ if (this._lastEventTs <= prevTs) {
340
+ // Reset backoff to allow immediate reconnect (latency sensitive)
341
+ this._backoff.attempt = 0;
342
+ this._reconnectMqttWithBackoff('soft-stale');
343
+ }
344
+ this._probing = false;
345
+ }, 5000 + Math.random() * 3000); // 5-8s probe window
313
346
  }
314
347
  } catch (_) { /* swallow */ }
315
348
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "nexus-fca",
3
- "version": "2.1.1",
3
+ "version": "2.1.2",
4
4
  "description": "A modern, safe, and advanced Facebook Chat API for Node.js with fully integrated Nexus Login System. NPM-ready with ID/password/2FA support, ultra-low ban rate protection, and zero external dependencies.",
5
5
  "main": "index.js",
6
6
  "repository": {