nodebb-plugin-ezoic-infinite 1.9.4 → 1.9.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.
package/library.js CHANGED
@@ -101,6 +101,7 @@ async function getSettings() {
101
101
  messageIntervalPosts: Math.max(1, parseInt(s.messageIntervalPosts, 10) || 3),
102
102
  excludedGroups: normalizeExcludedGroups(s.excludedGroups),
103
103
  };
104
+ data.excludedSet = new Set(data.excludedGroups);
104
105
  if (_settingsGen === gen) {
105
106
  _settingsCacheAt = Date.now();
106
107
  _settingsCache = data;
@@ -113,7 +114,7 @@ async function getSettings() {
113
114
  return _settingsInflight;
114
115
  }
115
116
 
116
- async function isUserExcluded(uid, excludedGroups) {
117
+ async function isUserExcluded(uid, excludedGroups, excludedSet) {
117
118
  if (!uid || !excludedGroups.length) return false;
118
119
 
119
120
  const key = `${uid}|${excludedGroups.join('|')}`;
@@ -121,16 +122,21 @@ async function isUserExcluded(uid, excludedGroups) {
121
122
  const hit = _excludeCache.get(key);
122
123
  if (hit && (t - hit.at) < EXCLUDE_TTL) return hit.value;
123
124
 
124
- const excludedSet = new Set(excludedGroups);
125
125
  const userGroups = await groups.getUserGroups([uid]);
126
126
  const value = (userGroups[0] || []).some(g => excludedSet.has(g.name));
127
127
 
128
128
  _excludeCache.set(key, { value, at: Date.now() });
129
129
  if (_excludeCache.size > 1000) {
130
- let n = 100;
131
- for (const k of _excludeCache.keys()) {
132
- if (!n--) break;
133
- _excludeCache.delete(k);
130
+ const expire = Date.now() - EXCLUDE_TTL;
131
+ for (const [k, v] of _excludeCache) {
132
+ if (v.at < expire) _excludeCache.delete(k);
133
+ }
134
+ if (_excludeCache.size > 900) {
135
+ let n = 100;
136
+ for (const k of _excludeCache.keys()) {
137
+ if (!n--) break;
138
+ _excludeCache.delete(k);
139
+ }
134
140
  }
135
141
  }
136
142
 
@@ -148,16 +154,13 @@ function clearCaches() {
148
154
  _excludeCache.clear();
149
155
  _inlineCfgNormal = null;
150
156
  _inlineCfgExcluded = null;
151
- _allGroupsGen++;
152
- _allGroupsCache = null;
153
- _allGroupsCacheAt = 0;
154
- _allGroupsInflight = null;
157
+ // _allGroupsCache is NOT cleared: the group list is independent of plugin settings.
155
158
  }
156
159
 
157
160
  // ── Client config ────────────────────────────────────────────────────────────
158
161
 
159
162
  function buildClientConfig(settings, excluded) {
160
- const { excludedGroups, ...rest } = settings;
163
+ const { excludedGroups, excludedSet, ...rest } = settings;
161
164
  return { excluded, ...rest };
162
165
  }
163
166
 
@@ -168,12 +171,20 @@ function serializeInlineConfig(cfg) {
168
171
  // ── Head injection ───────────────────────────────────────────────────────────
169
172
 
170
173
  const HEAD_PRECONNECTS = [
174
+ // Ezoic ad serving
171
175
  '<link rel="preconnect" href="https://g.ezoic.net" crossorigin>',
172
176
  '<link rel="preconnect" href="https://go.ezoic.net" crossorigin>',
173
177
  '<link rel="preconnect" href="https://securepubads.g.doubleclick.net" crossorigin>',
174
178
  '<link rel="preconnect" href="https://pagead2.googlesyndication.com" crossorigin>',
179
+ // Synchronous blocking scripts — preconnect to establish TCP+TLS before the parser reaches them
180
+ '<link rel="preconnect" href="https://cmp.gatekeeperconsent.com" crossorigin>',
181
+ '<link rel="preconnect" href="https://the.gatekeeperconsent.com" crossorigin>',
182
+ '<link rel="preconnect" href="https://www.ezojs.com" crossorigin>',
175
183
  '<link rel="dns-prefetch" href="https://g.ezoic.net">',
176
184
  '<link rel="dns-prefetch" href="https://securepubads.g.doubleclick.net">',
185
+ '<link rel="dns-prefetch" href="https://cmp.gatekeeperconsent.com">',
186
+ '<link rel="dns-prefetch" href="https://the.gatekeeperconsent.com">',
187
+ '<link rel="dns-prefetch" href="https://www.ezojs.com">',
177
188
  ].join('\n');
178
189
 
179
190
  // Working config: sa.min.js loaded synchronously (no async).
@@ -219,7 +230,7 @@ plugin.injectEzoicHead = async (data) => {
219
230
 
220
231
  const settings = await getSettings();
221
232
  const uid = data.req?.uid ?? 0;
222
- const excluded = await isUserExcluded(uid, settings.excludedGroups);
233
+ const excluded = await isUserExcluded(uid, settings.excludedGroups, settings.excludedSet);
223
234
 
224
235
  if (!_inlineCfgNormal) {
225
236
  _inlineCfgNormal = serializeInlineConfig(buildClientConfig(settings, false));
@@ -274,7 +285,7 @@ plugin.init = async ({ router, middleware }) => {
274
285
  router.get('/api/plugins/ezoic-infinite/config', async (req, res) => {
275
286
  try {
276
287
  const settings = await getSettings();
277
- const excluded = await isUserExcluded(req.uid, settings.excludedGroups);
288
+ const excluded = await isUserExcluded(req.uid, settings.excludedGroups, settings.excludedSet);
278
289
  res.json(buildClientConfig(settings, excluded));
279
290
  } catch (err) {
280
291
  console.error('[ezoic-infinite] config API error:', err.message);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "nodebb-plugin-ezoic-infinite",
3
- "version": "1.9.4",
3
+ "version": "1.9.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
@@ -32,7 +32,7 @@
32
32
  BURST_COOLDOWN_MS: 200,
33
33
  BLOCK_DURATION_MS: 1_000,
34
34
  SHOW_TIMEOUT_MS: 4_500,
35
- SHOW_RELEASE_MS: 150,
35
+ SHOW_RELEASE_MS: 50,
36
36
  RECYCLE_DELAY_MS: 50,
37
37
  UNCOLLAPSE_CHECK_MS: [500, 5_000],
38
38
  };
@@ -580,7 +580,8 @@
580
580
  scheduleEmptyCheck(id, t);
581
581
  setTimeout(() => { clearTimeout(timer); release(); }, TIMING.SHOW_RELEASE_MS);
582
582
  };
583
- typeof ez.cmd?.push === 'function' ? ez.cmd.push(doShow) : doShow();
583
+ const ezReady = ez.loadingStatus === 'complete';
584
+ typeof ez.cmd?.push === 'function' && !ezReady ? ez.cmd.push(doShow) : doShow();
584
585
  } catch (_) { clearTimeout(timer); release(); }
585
586
  }
586
587