nodebb-plugin-ezoic-infinite 1.8.3 → 1.8.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 (2) hide show
  1. package/package.json +1 -1
  2. package/public/client.js +92 -2
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "nodebb-plugin-ezoic-infinite",
3
- "version": "1.8.3",
3
+ "version": "1.8.5",
4
4
  "description": "Production-ready Ezoic infinite ads integration for NodeBB 4.x",
5
5
  "main": "library.js",
6
6
  "license": "MIT",
package/public/client.js CHANGED
@@ -89,6 +89,11 @@
89
89
  const MAX_DESTROY_BATCH = 4; // ids max par destroyPlaceholders(...ids)
90
90
  const DESTROY_FLUSH_MS = 30; // micro-buffer destroy pour lisser les rafales
91
91
  const BURST_COOLDOWN_MS = 120; // délai min entre deux déclenchements de burst
92
+ const PAGE_WARMUP_MS = 700; // délai minimal avant premiers showAds
93
+ const PAGE_SETTLE_GATE_MS = 5000; // fenêtre où l'on surveille la croissance réelle du contenu
94
+ const CONTENT_SETTLE_WINDOW_MS = 500;
95
+ const CONTENT_SETTLE_MAX_DELAY_MS = 2500;
96
+ const CONTENT_GROWTH_THRESHOLD_PX = 40;
92
97
 
93
98
  // Marges IO larges et fixes — observer créé une seule fois au boot
94
99
  const IO_MARGIN_DESKTOP = '2500px 0px 2500px 0px';
@@ -149,6 +154,12 @@
149
154
  burstDeadline: 0,
150
155
  burstCount: 0,
151
156
  lastBurstTs: 0,
157
+ pageWarmUntil: 0,
158
+ pageSettleUntil: 0,
159
+ settleDelaySince: 0,
160
+ contentStableStreak: 0,
161
+ contentSampleH: 0,
162
+ contentSampleTs: 0,
152
163
  };
153
164
 
154
165
  let blockedUntil = 0;
@@ -260,6 +271,66 @@ function destroyBeforeReuse(ids) {
260
271
  }
261
272
 
262
273
 
274
+ function getContentHeight() {
275
+ try {
276
+ const c = document.getElementById('content') || document.querySelector('main#panel') || document.body;
277
+ if (!c) return 0;
278
+ return Math.max(c.scrollHeight || 0, c.offsetHeight || 0);
279
+ } catch (_) { return 0; }
280
+ }
281
+
282
+ function getShowSettleDelayMs(now = ts()) {
283
+ try {
284
+ // Warmup minimal fixe (évite de tirer des pubs avant le 1er rendu NodeBB)
285
+ if (S.pageWarmUntil && now < S.pageWarmUntil) {
286
+ return Math.max(0, Math.min(250, S.pageWarmUntil - now));
287
+ }
288
+
289
+ // En dehors de la fenêtre "page en train de se construire", pas de gate.
290
+ if (!(S.pageSettleUntil && now < S.pageSettleUntil)) return 0;
291
+
292
+ const h = getContentHeight();
293
+ const prevH = S.contentSampleH || 0;
294
+ const prevTs = S.contentSampleTs || 0;
295
+ const dt = prevTs ? (now - prevTs) : 0;
296
+ const grew = h - prevH;
297
+
298
+ S.contentSampleH = h;
299
+ S.contentSampleTs = now;
300
+
301
+ if (!prevTs || h <= 0) {
302
+ S.contentStableStreak = 0;
303
+ return CONTENT_SETTLE_WINDOW_MS;
304
+ }
305
+
306
+ // Si les samples sont trop rapprochés, on attend une vraie fenêtre d'observation.
307
+ if (dt < Math.max(120, CONTENT_SETTLE_WINDOW_MS * 0.6)) {
308
+ return Math.max(80, CONTENT_SETTLE_WINDOW_MS - dt);
309
+ }
310
+
311
+ const significantGrowth = grew >= CONTENT_GROWTH_THRESHOLD_PX;
312
+ if (significantGrowth) {
313
+ if (!S.settleDelaySince) S.settleDelaySince = now;
314
+ S.contentStableStreak = 0;
315
+ if ((now - S.settleDelaySince) < CONTENT_SETTLE_MAX_DELAY_MS) {
316
+ return CONTENT_SETTLE_WINDOW_MS;
317
+ }
318
+ // plafond atteint : on laisse passer pour ne pas bloquer indéfiniment
319
+ S.settleDelaySince = 0;
320
+ return 0;
321
+ }
322
+
323
+ // Nécessite 2 fenêtres stables de suite avant de laisser partir le batch (début de page)
324
+ S.contentStableStreak = (S.contentStableStreak || 0) + 1;
325
+ if (S.contentStableStreak < 2) return Math.min(200, CONTENT_SETTLE_WINDOW_MS);
326
+
327
+ S.settleDelaySince = 0;
328
+ return 0;
329
+ } catch (_) {}
330
+ return 0;
331
+ }
332
+
333
+
263
334
  // ── Config ─────────────────────────────────────────────────────────────────
264
335
 
265
336
  async function fetchConfig() {
@@ -680,17 +751,19 @@ function enqueueShow(id) {
680
751
  scheduleDrainQueue();
681
752
  }
682
753
 
683
- function scheduleDrainQueue() {
754
+ function scheduleDrainQueue(delayMs = BATCH_FLUSH_MS) {
684
755
  if (isBlocked()) return;
685
756
  if (S.showBatchTimer) return;
686
757
  S.showBatchTimer = setTimeout(() => {
687
758
  S.showBatchTimer = 0;
688
759
  drainQueue();
689
- }, BATCH_FLUSH_MS);
760
+ }, Math.max(0, delayMs|0));
690
761
  }
691
762
 
692
763
  function drainQueue() {
693
764
  if (isBlocked()) return;
765
+ const settleDelay = getShowSettleDelayMs();
766
+ if (settleDelay > 0) { scheduleDrainQueue(Math.max(BATCH_FLUSH_MS, settleDelay)); return; }
694
767
  const free = Math.max(0, MAX_INFLIGHT - S.inflight);
695
768
  if (!free || !S.pending.length) return;
696
769
 
@@ -908,6 +981,12 @@ function startShowBatch(ids) {
908
981
  S.scrollSpeed = 0;
909
982
  S.lastScrollY = 0;
910
983
  S.lastScrollTs = 0;
984
+ S.pageWarmUntil = 0;
985
+ S.pageSettleUntil = 0;
986
+ S.contentStableStreak = 0;
987
+ S.settleDelaySince = 0;
988
+ S.contentSampleH = 0;
989
+ S.contentSampleTs = 0;
911
990
  }
912
991
 
913
992
  // ── MutationObserver ───────────────────────────────────────────────────────
@@ -1013,6 +1092,12 @@ function startShowBatch(ids) {
1013
1092
  S.pageKey = pageKey();
1014
1093
  blockedUntil = 0;
1015
1094
  muteConsole(); ensureTcfLocator(); warmNetwork();
1095
+ S.pageWarmUntil = ts() + PAGE_WARMUP_MS;
1096
+ S.pageSettleUntil = ts() + PAGE_SETTLE_GATE_MS;
1097
+ S.settleDelaySince = 0;
1098
+ S.contentStableStreak = 0;
1099
+ S.contentSampleH = getContentHeight();
1100
+ S.contentSampleTs = ts();
1016
1101
  patchShowAds(); getIO(); ensureDomObserver(); sweepDeadWraps(); requestBurst();
1017
1102
  });
1018
1103
 
@@ -1068,6 +1153,11 @@ function startShowBatch(ids) {
1068
1153
  ensureDomObserver();
1069
1154
  bindNodeBB();
1070
1155
  bindScroll();
1156
+ S.pageWarmUntil = ts() + PAGE_WARMUP_MS;
1157
+ S.pageSettleUntil = ts() + PAGE_SETTLE_GATE_MS;
1158
+ S.contentStableStreak = 0;
1159
+ S.contentSampleH = getContentHeight();
1160
+ S.contentSampleTs = ts();
1071
1161
  blockedUntil = 0;
1072
1162
  requestBurst();
1073
1163