nodebb-plugin-ezoic-infinite 1.8.4 → 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 +50 -11
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "nodebb-plugin-ezoic-infinite",
3
- "version": "1.8.4",
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,10 +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; // laisse NodeBB rendre le contenu avant les premiers showAds
93
- const CONTENT_SETTLE_WINDOW_MS = 350;
94
- const CONTENT_SETTLE_MAX_DELAY_MS = 1500;
95
- const CONTENT_GROWTH_THRESHOLD_PX = 120;
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;
96
97
 
97
98
  // Marges IO larges et fixes — observer créé une seule fois au boot
98
99
  const IO_MARGIN_DESKTOP = '2500px 0px 2500px 0px';
@@ -154,7 +155,9 @@
154
155
  burstCount: 0,
155
156
  lastBurstTs: 0,
156
157
  pageWarmUntil: 0,
158
+ pageSettleUntil: 0,
157
159
  settleDelaySince: 0,
160
+ contentStableStreak: 0,
158
161
  contentSampleH: 0,
159
162
  contentSampleTs: 0,
160
163
  };
@@ -278,21 +281,51 @@ function destroyBeforeReuse(ids) {
278
281
 
279
282
  function getShowSettleDelayMs(now = ts()) {
280
283
  try {
281
- if (S.pageWarmUntil && now < S.pageWarmUntil) return Math.max(0, Math.min(120, S.pageWarmUntil - now));
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
+
282
292
  const h = getContentHeight();
283
293
  const prevH = S.contentSampleH || 0;
284
294
  const prevTs = S.contentSampleTs || 0;
295
+ const dt = prevTs ? (now - prevTs) : 0;
296
+ const grew = h - prevH;
297
+
285
298
  S.contentSampleH = h;
286
299
  S.contentSampleTs = now;
287
- if (!prevTs || h <= 0) { S.settleDelaySince = 0; return 0; }
288
- const grew = h - prevH;
289
- const recent = (now - prevTs) <= CONTENT_SETTLE_WINDOW_MS;
290
- if (recent && grew >= CONTENT_GROWTH_THRESHOLD_PX) {
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) {
291
313
  if (!S.settleDelaySince) S.settleDelaySince = now;
292
- if ((now - S.settleDelaySince) < CONTENT_SETTLE_MAX_DELAY_MS) return CONTENT_SETTLE_WINDOW_MS;
293
- } else {
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
294
319
  S.settleDelaySince = 0;
320
+ return 0;
295
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;
296
329
  } catch (_) {}
297
330
  return 0;
298
331
  }
@@ -949,6 +982,8 @@ function startShowBatch(ids) {
949
982
  S.lastScrollY = 0;
950
983
  S.lastScrollTs = 0;
951
984
  S.pageWarmUntil = 0;
985
+ S.pageSettleUntil = 0;
986
+ S.contentStableStreak = 0;
952
987
  S.settleDelaySince = 0;
953
988
  S.contentSampleH = 0;
954
989
  S.contentSampleTs = 0;
@@ -1058,7 +1093,9 @@ function startShowBatch(ids) {
1058
1093
  blockedUntil = 0;
1059
1094
  muteConsole(); ensureTcfLocator(); warmNetwork();
1060
1095
  S.pageWarmUntil = ts() + PAGE_WARMUP_MS;
1096
+ S.pageSettleUntil = ts() + PAGE_SETTLE_GATE_MS;
1061
1097
  S.settleDelaySince = 0;
1098
+ S.contentStableStreak = 0;
1062
1099
  S.contentSampleH = getContentHeight();
1063
1100
  S.contentSampleTs = ts();
1064
1101
  patchShowAds(); getIO(); ensureDomObserver(); sweepDeadWraps(); requestBurst();
@@ -1117,6 +1154,8 @@ function startShowBatch(ids) {
1117
1154
  bindNodeBB();
1118
1155
  bindScroll();
1119
1156
  S.pageWarmUntil = ts() + PAGE_WARMUP_MS;
1157
+ S.pageSettleUntil = ts() + PAGE_SETTLE_GATE_MS;
1158
+ S.contentStableStreak = 0;
1120
1159
  S.contentSampleH = getContentHeight();
1121
1160
  S.contentSampleTs = ts();
1122
1161
  blockedUntil = 0;