@action-x/ad-sdk 0.1.5 → 0.1.6
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/dist/index.cjs +33 -33
- package/dist/index.d.ts +14 -3
- package/dist/index.js +300 -258
- package/dist/index.umd.js +25 -25
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -42,7 +42,16 @@ class B {
|
|
|
42
42
|
return ((t = this.events[e]) == null ? void 0 : t.length) || 0;
|
|
43
43
|
}
|
|
44
44
|
}
|
|
45
|
-
class
|
|
45
|
+
class w {
|
|
46
|
+
static getClickUrl(e) {
|
|
47
|
+
return e.tracking.clickUrl || e.tracking.click_url || "#";
|
|
48
|
+
}
|
|
49
|
+
static getImpressionUrl(e) {
|
|
50
|
+
return e.tracking.impressionUrl || e.tracking.impression_url || "";
|
|
51
|
+
}
|
|
52
|
+
static getCtaText(e) {
|
|
53
|
+
return e.adapted.ctaText || e.adapted.cta_text || "Learn More";
|
|
54
|
+
}
|
|
46
55
|
/**
|
|
47
56
|
* Render Action Card ad as HTML string
|
|
48
57
|
*
|
|
@@ -51,37 +60,37 @@ class v {
|
|
|
51
60
|
* @returns HTML string
|
|
52
61
|
*/
|
|
53
62
|
static renderActionCard(e, t = {}) {
|
|
54
|
-
var
|
|
55
|
-
const { variant: i = "horizontal", includeWrapper: s = !0 } = t, n = e.adapted,
|
|
63
|
+
var m;
|
|
64
|
+
const { variant: i = "horizontal", includeWrapper: s = !0 } = t, n = e.adapted, o = this.getClickUrl(e), a = this.getImpressionUrl(e), c = s ? `<div class="ax-ad-card ax-ad-card-${i}" data-ad-id="${e.original.id}">` : "", l = (m = n.image) != null && m.url ? `<img
|
|
56
65
|
src="${n.image.url}"
|
|
57
66
|
alt="${n.title}"
|
|
58
67
|
class="ax-ad-image"
|
|
59
68
|
loading="lazy"
|
|
60
|
-
/>` : "", d = n.price ? `<span class="ax-ad-price">${n.price.display || n.price.value}</span>` : "",
|
|
69
|
+
/>` : "", d = n.price ? `<span class="ax-ad-price">${n.price.display || n.price.value}</span>` : "", u = n.rating ? `<div class="ax-ad-rating" aria-label="Rating: ${n.rating}">
|
|
61
70
|
${"★".repeat(Math.floor(n.rating))}${"☆".repeat(5 - Math.floor(n.rating))}
|
|
62
|
-
</div>` : "",
|
|
63
|
-
${
|
|
71
|
+
</div>` : "", h = n.brand ? `<span class="ax-ad-brand">${n.brand}</span>` : "", p = `
|
|
72
|
+
${l}
|
|
64
73
|
<div class="ax-ad-content">
|
|
65
|
-
${
|
|
74
|
+
${h}
|
|
66
75
|
<h3 class="ax-ad-title">${n.title}</h3>
|
|
67
76
|
${n.body ? `<p class="ax-ad-body">${n.body}</p>` : ""}
|
|
68
|
-
${
|
|
77
|
+
${u}
|
|
69
78
|
<div class="ax-ad-footer">
|
|
70
79
|
${d}
|
|
71
80
|
<a
|
|
72
|
-
href="${
|
|
81
|
+
href="${o}"
|
|
73
82
|
class="ax-ad-cta"
|
|
74
83
|
target="_blank"
|
|
75
84
|
rel="sponsored noopener noreferrer"
|
|
76
85
|
data-ad-id="${e.original.id}"
|
|
77
|
-
data-impression-url="${
|
|
86
|
+
data-impression-url="${a}"
|
|
78
87
|
>
|
|
79
|
-
${
|
|
88
|
+
${this.getCtaText(e)}
|
|
80
89
|
</a>
|
|
81
90
|
</div>
|
|
82
91
|
</div>
|
|
83
|
-
`,
|
|
84
|
-
return
|
|
92
|
+
`, f = s ? "</div>" : "";
|
|
93
|
+
return c + p + f;
|
|
85
94
|
}
|
|
86
95
|
/**
|
|
87
96
|
* Render Suffix ad as HTML string
|
|
@@ -90,21 +99,21 @@ class v {
|
|
|
90
99
|
* @returns HTML string
|
|
91
100
|
*/
|
|
92
101
|
static renderSuffixAd(e) {
|
|
93
|
-
const t = e.adapted, i = e.
|
|
102
|
+
const t = e.adapted, i = this.getClickUrl(e), s = this.getImpressionUrl(e);
|
|
94
103
|
return `
|
|
95
104
|
<div class="ax-ad-suffix" data-ad-id="${e.original.id}">
|
|
96
105
|
<div class="ax-ad-suffix-content">
|
|
97
106
|
${t.title ? `<h4 class="ax-ad-suffix-title">${t.title}</h4>` : ""}
|
|
98
107
|
${t.body ? `<p class="ax-ad-suffix-body">${t.body}</p>` : ""}
|
|
99
108
|
<a
|
|
100
|
-
href="${i
|
|
109
|
+
href="${i}"
|
|
101
110
|
class="ax-ad-suffix-link"
|
|
102
111
|
target="_blank"
|
|
103
112
|
rel="sponsored noopener noreferrer"
|
|
104
113
|
data-ad-id="${e.original.id}"
|
|
105
|
-
data-impression-url="${
|
|
114
|
+
data-impression-url="${s}"
|
|
106
115
|
>
|
|
107
|
-
${
|
|
116
|
+
${this.getCtaText(e)}
|
|
108
117
|
</a>
|
|
109
118
|
</div>
|
|
110
119
|
</div>
|
|
@@ -117,19 +126,19 @@ class v {
|
|
|
117
126
|
* @returns HTML string
|
|
118
127
|
*/
|
|
119
128
|
static renderSponsoredSource(e) {
|
|
120
|
-
var
|
|
121
|
-
const t = e.adapted, i = e.
|
|
129
|
+
var n;
|
|
130
|
+
const t = e.adapted, i = this.getClickUrl(e), s = this.getImpressionUrl(e);
|
|
122
131
|
return `
|
|
123
132
|
<div class="ax-ad-source" data-ad-id="${e.original.id}">
|
|
124
133
|
<a
|
|
125
|
-
href="${i
|
|
134
|
+
href="${i}"
|
|
126
135
|
class="ax-ad-source-link"
|
|
127
136
|
target="_blank"
|
|
128
137
|
rel="sponsored noopener noreferrer"
|
|
129
138
|
data-ad-id="${e.original.id}"
|
|
130
|
-
data-impression-url="${
|
|
139
|
+
data-impression-url="${s}"
|
|
131
140
|
>
|
|
132
|
-
${(
|
|
141
|
+
${(n = t.image) != null && n.url ? `<img src="${t.image.url}" alt="" class="ax-ad-source-icon" />` : ""}
|
|
133
142
|
<div class="ax-ad-source-info">
|
|
134
143
|
<span class="ax-ad-source-name">${t.title}</span>
|
|
135
144
|
${t.body ? `<span class="ax-ad-source-desc">${t.body}</span>` : ""}
|
|
@@ -146,21 +155,21 @@ class v {
|
|
|
146
155
|
* @returns HTML string
|
|
147
156
|
*/
|
|
148
157
|
static renderLeadGenAd(e) {
|
|
149
|
-
const t = e.adapted, i = e.
|
|
158
|
+
const t = e.adapted, i = this.getClickUrl(e), s = this.getImpressionUrl(e);
|
|
150
159
|
return `
|
|
151
160
|
<div class="ax-ad-leadgen" data-ad-id="${e.original.id}">
|
|
152
161
|
<div class="ax-ad-leadgen-content">
|
|
153
162
|
${t.title ? `<h3 class="ax-ad-leadgen-title">${t.title}</h3>` : ""}
|
|
154
163
|
${t.body ? `<p class="ax-ad-leadgen-body">${t.body}</p>` : ""}
|
|
155
164
|
<a
|
|
156
|
-
href="${i
|
|
165
|
+
href="${i}"
|
|
157
166
|
class="ax-ad-leadgen-cta"
|
|
158
167
|
target="_blank"
|
|
159
168
|
rel="sponsored noopener noreferrer"
|
|
160
169
|
data-ad-id="${e.original.id}"
|
|
161
|
-
data-impression-url="${
|
|
170
|
+
data-impression-url="${s}"
|
|
162
171
|
>
|
|
163
|
-
${
|
|
172
|
+
${this.getCtaText(e)}
|
|
164
173
|
</a>
|
|
165
174
|
</div>
|
|
166
175
|
</div>
|
|
@@ -173,21 +182,25 @@ class v {
|
|
|
173
182
|
* @param renderFn - Render function to use
|
|
174
183
|
* @returns HTML string with all ads
|
|
175
184
|
*/
|
|
176
|
-
static renderAds(e, t =
|
|
185
|
+
static renderAds(e, t = w.renderActionCard.bind(w)) {
|
|
177
186
|
return e.map(t).join(`
|
|
178
187
|
`);
|
|
179
188
|
}
|
|
180
189
|
}
|
|
181
|
-
const
|
|
182
|
-
function
|
|
190
|
+
const q = "ad_session_id";
|
|
191
|
+
function L() {
|
|
183
192
|
if (typeof window < "u") {
|
|
184
|
-
const
|
|
185
|
-
if (
|
|
186
|
-
return
|
|
193
|
+
const r = window.__AD_CONFIG__;
|
|
194
|
+
if (r != null && r.apiKey)
|
|
195
|
+
return r.apiKey;
|
|
187
196
|
}
|
|
188
197
|
}
|
|
189
|
-
function
|
|
190
|
-
|
|
198
|
+
function R() {
|
|
199
|
+
var r;
|
|
200
|
+
return typeof window < "u" ? !!((r = window.__AD_CONFIG__) != null && r.debug) : !1;
|
|
201
|
+
}
|
|
202
|
+
function U(r) {
|
|
203
|
+
if (r) return r;
|
|
191
204
|
if (typeof window < "u") {
|
|
192
205
|
const e = window.__AD_CONFIG__;
|
|
193
206
|
if (e != null && e.apiBaseUrl)
|
|
@@ -195,9 +208,9 @@ function C(o) {
|
|
|
195
208
|
}
|
|
196
209
|
return "/api/v1";
|
|
197
210
|
}
|
|
198
|
-
class
|
|
211
|
+
class P {
|
|
199
212
|
constructor(e = {}) {
|
|
200
|
-
this.memoryCache = /* @__PURE__ */ new Map(), this.sessionKey = e.sessionKey ||
|
|
213
|
+
this.memoryCache = /* @__PURE__ */ new Map(), this.sessionKey = e.sessionKey || q, this.storage = e.storage || "sessionStorage", (typeof window > "u" || typeof window.sessionStorage > "u") && (this.storage = "memory");
|
|
201
214
|
}
|
|
202
215
|
/**
|
|
203
216
|
* 获取 Session ID
|
|
@@ -231,7 +244,7 @@ class _ {
|
|
|
231
244
|
this.storage === "sessionStorage" ? sessionStorage.removeItem(this.sessionKey) : this.memoryCache.delete(this.sessionKey);
|
|
232
245
|
}
|
|
233
246
|
}
|
|
234
|
-
const
|
|
247
|
+
const K = new P(), y = () => K.getSessionId();
|
|
235
248
|
class x {
|
|
236
249
|
constructor(e = {}) {
|
|
237
250
|
this.explicitBaseUrl = e.baseUrl, this.timeout = e.timeout || 1e4, this.retryAttempts = e.retryAttempts ?? 2, this.retryDelay = e.retryDelay || 1e3, this.debug = e.debug || !1;
|
|
@@ -241,7 +254,7 @@ class x {
|
|
|
241
254
|
*/
|
|
242
255
|
async trackImpression(e) {
|
|
243
256
|
return this.sendRequest(
|
|
244
|
-
`${
|
|
257
|
+
`${U(this.explicitBaseUrl)}/ads/impression`,
|
|
245
258
|
e,
|
|
246
259
|
"impression"
|
|
247
260
|
);
|
|
@@ -251,7 +264,7 @@ class x {
|
|
|
251
264
|
*/
|
|
252
265
|
async trackClick(e) {
|
|
253
266
|
return this.sendRequest(
|
|
254
|
-
`${
|
|
267
|
+
`${U(this.explicitBaseUrl)}/ads/click`,
|
|
255
268
|
e,
|
|
256
269
|
"click"
|
|
257
270
|
);
|
|
@@ -262,27 +275,29 @@ class x {
|
|
|
262
275
|
*/
|
|
263
276
|
async sendRequest(e, t, i) {
|
|
264
277
|
let s = null;
|
|
265
|
-
for (let n = 0; n <= this.retryAttempts; n++)
|
|
278
|
+
for (let n = 0; n <= this.retryAttempts; n++) {
|
|
279
|
+
const o = this.debug || R();
|
|
266
280
|
try {
|
|
267
|
-
|
|
268
|
-
const
|
|
281
|
+
o && (console.log(`[Analytics] Request URL (${i}):`, e), console.log(`[Analytics] Sending ${i} event (attempt ${n + 1}):`, t));
|
|
282
|
+
const a = new AbortController(), c = setTimeout(() => a.abort(), this.timeout), l = {
|
|
269
283
|
"Content-Type": "application/json"
|
|
270
|
-
}, d =
|
|
271
|
-
d && (
|
|
272
|
-
const
|
|
284
|
+
}, d = L();
|
|
285
|
+
d && (l["X-API-Key"] = d, o && console.log(`[Analytics] Adding X-API-Key header for ${i} event`));
|
|
286
|
+
const u = await fetch(e, {
|
|
273
287
|
method: "POST",
|
|
274
|
-
headers:
|
|
288
|
+
headers: l,
|
|
275
289
|
body: JSON.stringify(t),
|
|
276
290
|
keepalive: !0,
|
|
277
|
-
signal:
|
|
291
|
+
signal: a.signal
|
|
278
292
|
});
|
|
279
|
-
if (clearTimeout(
|
|
280
|
-
throw new Error(`HTTP ${
|
|
281
|
-
const
|
|
282
|
-
return
|
|
283
|
-
} catch (
|
|
284
|
-
s =
|
|
293
|
+
if (clearTimeout(c), !u.ok)
|
|
294
|
+
throw new Error(`HTTP ${u.status}: ${u.statusText}`);
|
|
295
|
+
const h = await u.json();
|
|
296
|
+
return o && console.log(`[Analytics] ${i} event tracked successfully:`, h), h;
|
|
297
|
+
} catch (a) {
|
|
298
|
+
s = a, o && console.warn(`[Analytics] ${i} tracking failed (attempt ${n + 1}):`, a), n < this.retryAttempts && await this.delay(this.retryDelay * (n + 1));
|
|
285
299
|
}
|
|
300
|
+
}
|
|
286
301
|
return console.error(`[Analytics] ${i} tracking failed after ${this.retryAttempts + 1} attempts:`, s), null;
|
|
287
302
|
}
|
|
288
303
|
/**
|
|
@@ -292,37 +307,47 @@ class x {
|
|
|
292
307
|
return new Promise((t) => setTimeout(t, e));
|
|
293
308
|
}
|
|
294
309
|
}
|
|
295
|
-
const
|
|
296
|
-
function
|
|
297
|
-
return `vt_${
|
|
310
|
+
const O = new x(), I = (r, e) => e != null && e.baseUrl ? new x({ baseUrl: e.baseUrl }).trackImpression(r) : O.trackImpression(r), T = (r, e) => e != null && e.baseUrl ? new x({ baseUrl: e.baseUrl }).trackClick(r) : O.trackClick(r);
|
|
311
|
+
function G(r, e) {
|
|
312
|
+
return `vt_${r}_${e}`;
|
|
298
313
|
}
|
|
299
|
-
async function
|
|
300
|
-
return Promise.all(
|
|
314
|
+
async function j(r) {
|
|
315
|
+
return Promise.all(r.map((e) => I(e)));
|
|
301
316
|
}
|
|
302
|
-
async function
|
|
303
|
-
return Promise.all(
|
|
317
|
+
async function z(r) {
|
|
318
|
+
return Promise.all(r.map((e) => T(e)));
|
|
304
319
|
}
|
|
305
|
-
function
|
|
306
|
-
const e = new x(
|
|
320
|
+
function W(r) {
|
|
321
|
+
const e = new x(r);
|
|
307
322
|
return {
|
|
308
323
|
trackImpression: (t) => e.trackImpression(t),
|
|
309
324
|
trackClick: (t) => e.trackClick(t)
|
|
310
325
|
};
|
|
311
326
|
}
|
|
312
|
-
function
|
|
313
|
-
const e = new
|
|
327
|
+
function Q(r = {}) {
|
|
328
|
+
const e = new P(r);
|
|
314
329
|
return {
|
|
315
330
|
getSessionId: () => e.getSessionId(),
|
|
316
331
|
regenerateSessionId: () => e.regenerateSessionId(),
|
|
317
332
|
clearSessionId: () => e.clearSessionId()
|
|
318
333
|
};
|
|
319
334
|
}
|
|
320
|
-
const
|
|
335
|
+
const C = class C {
|
|
336
|
+
static isDebugEnabled() {
|
|
337
|
+
var e;
|
|
338
|
+
return typeof window < "u" ? !!((e = window.__AD_CONFIG__) != null && e.debug) : !1;
|
|
339
|
+
}
|
|
340
|
+
static getClickUrl(e) {
|
|
341
|
+
return e.tracking.clickUrl || e.tracking.click_url || "";
|
|
342
|
+
}
|
|
343
|
+
static getViewToken(e) {
|
|
344
|
+
return e.tracking.viewToken || e.tracking.view_token;
|
|
345
|
+
}
|
|
321
346
|
/**
|
|
322
347
|
* Render Action Card ad into container
|
|
323
348
|
*/
|
|
324
349
|
static renderActionCard(e, t, i = {}) {
|
|
325
|
-
t.innerHTML =
|
|
350
|
+
t.innerHTML = w.renderActionCard(e, i);
|
|
326
351
|
const s = t.querySelector(".ax-ad-cta");
|
|
327
352
|
return s && s.addEventListener("click", (n) => {
|
|
328
353
|
n.preventDefault(), this.handleClick(e, i);
|
|
@@ -335,8 +360,8 @@ const M = class M {
|
|
|
335
360
|
const s = i.variant || "block";
|
|
336
361
|
t.innerHTML = this.generateSuffixAdHTML(e, s);
|
|
337
362
|
const n = t.querySelector(".ax-ad-suffix-link");
|
|
338
|
-
return n && n.addEventListener("click", (
|
|
339
|
-
|
|
363
|
+
return n && n.addEventListener("click", (o) => {
|
|
364
|
+
o.preventDefault(), this.handleClick(e, i);
|
|
340
365
|
}), this.trackImpression(e, t, i), t;
|
|
341
366
|
}
|
|
342
367
|
/**
|
|
@@ -346,15 +371,15 @@ const M = class M {
|
|
|
346
371
|
const s = i.variant || "card";
|
|
347
372
|
t.innerHTML = this.generateSponsoredSourceHTML(e, s);
|
|
348
373
|
const n = t.querySelector(".ax-ad-source-link");
|
|
349
|
-
return n && n.addEventListener("click", (
|
|
350
|
-
|
|
374
|
+
return n && n.addEventListener("click", (o) => {
|
|
375
|
+
o.preventDefault(), this.handleClick(e, i);
|
|
351
376
|
}), this.trackImpression(e, t, i), t;
|
|
352
377
|
}
|
|
353
378
|
/**
|
|
354
379
|
* Render Lead Gen ad into container
|
|
355
380
|
*/
|
|
356
381
|
static renderLeadGenAd(e, t, i = {}) {
|
|
357
|
-
t.innerHTML =
|
|
382
|
+
t.innerHTML = w.renderLeadGenAd(e);
|
|
358
383
|
const s = t.querySelector(".ax-ad-leadgen-cta");
|
|
359
384
|
return s && s.addEventListener("click", (n) => {
|
|
360
385
|
n.preventDefault(), this.handleClick(e, i);
|
|
@@ -366,9 +391,9 @@ const M = class M {
|
|
|
366
391
|
static renderAds(e, t, i = this.renderActionCard.bind(this), s) {
|
|
367
392
|
t.innerHTML = "";
|
|
368
393
|
const n = document.createElement("div");
|
|
369
|
-
return n.className = "ax-ads-container", e.forEach((
|
|
394
|
+
return n.className = "ax-ads-container", e.forEach((o) => {
|
|
370
395
|
const a = document.createElement("div");
|
|
371
|
-
a.className = "ax-ad-wrapper", i.call(this,
|
|
396
|
+
a.className = "ax-ad-wrapper", i.call(this, o, a, s), n.appendChild(a);
|
|
372
397
|
}), t.appendChild(n), t;
|
|
373
398
|
}
|
|
374
399
|
/**
|
|
@@ -376,61 +401,67 @@ const M = class M {
|
|
|
376
401
|
* First tracks the click (async, non-blocking), then opens the URL.
|
|
377
402
|
*/
|
|
378
403
|
static handleClick(e, t) {
|
|
379
|
-
const { analytics: i, onClick: s } = t;
|
|
404
|
+
const { analytics: i, onClick: s } = t, n = this.getClickUrl(e);
|
|
405
|
+
if (!n) {
|
|
406
|
+
console.warn("[DOMRenderer] Missing click url for ad:", e.original.id);
|
|
407
|
+
return;
|
|
408
|
+
}
|
|
380
409
|
s && s(e), i && T({
|
|
381
410
|
requestId: i.requestId,
|
|
382
411
|
adId: e.original.id,
|
|
383
|
-
destinationUrl:
|
|
412
|
+
destinationUrl: n,
|
|
384
413
|
slotId: i.slotId,
|
|
385
|
-
sessionId:
|
|
414
|
+
sessionId: y(),
|
|
386
415
|
adTitle: e.adapted.title,
|
|
387
|
-
format: e.original.type
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
416
|
+
format: e.original.type,
|
|
417
|
+
userId: i.userId
|
|
418
|
+
}, { baseUrl: i.apiBaseUrl }).catch((o) => {
|
|
419
|
+
console.error("[DOMRenderer] Analytics click tracking failed:", o);
|
|
420
|
+
}), this.isDebugEnabled() && console.log("[DOMRenderer] Redirect URL:", n), window.open(n, "_blank", "noopener,noreferrer");
|
|
391
421
|
}
|
|
392
422
|
/**
|
|
393
423
|
* Track ad impression using IntersectionObserver (50% visible + 1000ms delay)
|
|
394
424
|
* Falls back to immediate tracking if IntersectionObserver is unavailable.
|
|
395
425
|
*/
|
|
396
426
|
static trackImpression(e, t, i) {
|
|
397
|
-
const { analytics: s, onImpression: n } = i,
|
|
398
|
-
if (this.trackedImpressionKeys.has(
|
|
427
|
+
const { analytics: s, onImpression: n } = i, o = s ? `${s.requestId}:${s.slotId}:${e.original.id}:${this.getViewToken(e) || ""}` : `no-analytics:${e.original.id}:${this.getViewToken(e) || ""}`;
|
|
428
|
+
if (this.trackedImpressionKeys.has(o))
|
|
399
429
|
return;
|
|
400
430
|
let a = !1;
|
|
401
431
|
const c = () => {
|
|
402
|
-
a || this.trackedImpressionKeys.has(
|
|
403
|
-
},
|
|
404
|
-
s ?
|
|
432
|
+
a || this.trackedImpressionKeys.has(o) || (a = !0, this.trackedImpressionKeys.add(o), l());
|
|
433
|
+
}, l = () => {
|
|
434
|
+
s ? I({
|
|
405
435
|
requestId: s.requestId,
|
|
406
436
|
adId: e.original.id,
|
|
407
437
|
slotId: s.slotId,
|
|
408
438
|
position: s.position,
|
|
409
439
|
totalAds: s.totalAds,
|
|
410
|
-
sessionId:
|
|
440
|
+
sessionId: y(),
|
|
411
441
|
adTitle: e.adapted.title,
|
|
412
442
|
format: e.original.type,
|
|
413
443
|
source: "internal",
|
|
414
|
-
viewToken: e
|
|
444
|
+
viewToken: this.getViewToken(e),
|
|
445
|
+
userId: s.userId
|
|
415
446
|
}, { baseUrl: s.apiBaseUrl }).then(() => {
|
|
416
447
|
n && n(e);
|
|
417
|
-
}).catch((
|
|
418
|
-
console.error("[DOMRenderer] Analytics impression tracking failed:",
|
|
448
|
+
}).catch((d) => {
|
|
449
|
+
console.error("[DOMRenderer] Analytics impression tracking failed:", d);
|
|
419
450
|
}) : n && n(e);
|
|
420
451
|
};
|
|
421
452
|
if (typeof IntersectionObserver < "u") {
|
|
422
|
-
let
|
|
423
|
-
const
|
|
424
|
-
(
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
u = null,
|
|
453
|
+
let d = !1, u = null;
|
|
454
|
+
const h = new IntersectionObserver(
|
|
455
|
+
(f) => {
|
|
456
|
+
f.forEach((m) => {
|
|
457
|
+
d = m.isIntersecting && m.intersectionRatio >= 0.5, d ? u || (u = setTimeout(() => {
|
|
458
|
+
u = null, d && (c(), h.disconnect());
|
|
428
459
|
}, 1e3)) : u && (clearTimeout(u), u = null);
|
|
429
460
|
});
|
|
430
461
|
},
|
|
431
462
|
{ threshold: 0.5 }
|
|
432
463
|
), p = t.querySelector(`[data-ad-id="${e.original.id}"]`) || t;
|
|
433
|
-
|
|
464
|
+
h.observe(p);
|
|
434
465
|
} else
|
|
435
466
|
c();
|
|
436
467
|
}
|
|
@@ -469,8 +500,8 @@ const M = class M {
|
|
|
469
500
|
* Generate HTML for Sponsored Source Ad variants
|
|
470
501
|
*/
|
|
471
502
|
static generateSponsoredSourceHTML(e, t) {
|
|
472
|
-
var
|
|
473
|
-
const i = e.adapted.title || "", s = e.adapted.body || "", n = ((
|
|
503
|
+
var o;
|
|
504
|
+
const i = e.adapted.title || "", s = e.adapted.body || "", n = ((o = e.adapted.image) == null ? void 0 : o.url) || "";
|
|
474
505
|
return t === "list-item" ? `
|
|
475
506
|
<div class="ax-ad-source ax-ad-variant-list-item" data-ad-id="${e.original.id}">
|
|
476
507
|
${n ? `<img src="${n}" alt="${i}" loading="lazy" />` : ""}
|
|
@@ -507,9 +538,9 @@ const M = class M {
|
|
|
507
538
|
`;
|
|
508
539
|
}
|
|
509
540
|
};
|
|
510
|
-
|
|
511
|
-
let
|
|
512
|
-
class
|
|
541
|
+
C.trackedImpressionKeys = /* @__PURE__ */ new Set();
|
|
542
|
+
let b = C;
|
|
543
|
+
class S {
|
|
513
544
|
constructor() {
|
|
514
545
|
this.cachedStaticInfo = null, this.cacheTimestamp = 0, this.CACHE_TTL = 36e5;
|
|
515
546
|
}
|
|
@@ -596,7 +627,7 @@ class $ {
|
|
|
596
627
|
* Get singleton instance
|
|
597
628
|
*/
|
|
598
629
|
static getInstance() {
|
|
599
|
-
return this.instance || (this.instance = new
|
|
630
|
+
return this.instance || (this.instance = new S()), this.instance;
|
|
600
631
|
}
|
|
601
632
|
/**
|
|
602
633
|
* Collect all available client information
|
|
@@ -677,7 +708,7 @@ class $ {
|
|
|
677
708
|
collectUserInfo() {
|
|
678
709
|
let e;
|
|
679
710
|
try {
|
|
680
|
-
e = localStorage.getItem("
|
|
711
|
+
e = localStorage.getItem("actionx_user_id") || "", e || (e = this.generateUUID(), localStorage.setItem("actionx_user_id", e));
|
|
681
712
|
} catch {
|
|
682
713
|
e = this.generateUUID();
|
|
683
714
|
}
|
|
@@ -752,8 +783,8 @@ class $ {
|
|
|
752
783
|
const n = e.match(/(MI|Redmi|POCO)\s([\w\s]+)/);
|
|
753
784
|
if (n) return n[1] + " " + n[2];
|
|
754
785
|
if (/OnePlus/.test(e)) {
|
|
755
|
-
const
|
|
756
|
-
return
|
|
786
|
+
const o = e.match(/OnePlus\s([A-Z\d]+)/);
|
|
787
|
+
return o ? "OnePlus " + o[1] : "OnePlus";
|
|
757
788
|
}
|
|
758
789
|
}
|
|
759
790
|
/**
|
|
@@ -899,101 +930,105 @@ class $ {
|
|
|
899
930
|
this.cachedStaticInfo = null, this.cacheTimestamp = 0;
|
|
900
931
|
}
|
|
901
932
|
}
|
|
902
|
-
const
|
|
903
|
-
function
|
|
904
|
-
return
|
|
905
|
-
}
|
|
906
|
-
function W() {
|
|
907
|
-
return b().device;
|
|
908
|
-
}
|
|
909
|
-
function K() {
|
|
910
|
-
return b().user;
|
|
911
|
-
}
|
|
912
|
-
function Q() {
|
|
913
|
-
return b().app;
|
|
933
|
+
const $ = () => S.getInstance();
|
|
934
|
+
function v(r) {
|
|
935
|
+
return $().collect(r);
|
|
914
936
|
}
|
|
915
937
|
function J() {
|
|
916
|
-
return
|
|
938
|
+
return v().device;
|
|
939
|
+
}
|
|
940
|
+
function N() {
|
|
941
|
+
return v().user;
|
|
917
942
|
}
|
|
918
943
|
function X() {
|
|
919
|
-
return
|
|
944
|
+
return v().app;
|
|
920
945
|
}
|
|
921
946
|
function Z() {
|
|
922
|
-
|
|
947
|
+
return v().geo;
|
|
923
948
|
}
|
|
924
|
-
function Y(
|
|
925
|
-
|
|
926
|
-
return JSON.stringify(e, null, 2);
|
|
949
|
+
function Y() {
|
|
950
|
+
return N().id;
|
|
927
951
|
}
|
|
928
952
|
function ee() {
|
|
953
|
+
$().clearCache();
|
|
954
|
+
}
|
|
955
|
+
function te(r) {
|
|
956
|
+
const e = v(r);
|
|
957
|
+
return JSON.stringify(e, null, 2);
|
|
958
|
+
}
|
|
959
|
+
function ie() {
|
|
929
960
|
var t;
|
|
930
|
-
const
|
|
961
|
+
const r = v();
|
|
931
962
|
return [
|
|
932
|
-
|
|
933
|
-
|
|
934
|
-
|
|
935
|
-
|
|
936
|
-
((t =
|
|
963
|
+
r.device.os,
|
|
964
|
+
r.device.osv,
|
|
965
|
+
r.app.name,
|
|
966
|
+
r.user.id.slice(0, 8) + "...",
|
|
967
|
+
((t = r.geo) == null ? void 0 : t.country) || "Unknown"
|
|
937
968
|
].join(" / ");
|
|
938
969
|
}
|
|
939
|
-
function
|
|
970
|
+
function M() {
|
|
971
|
+
var r;
|
|
972
|
+
return typeof window < "u" ? !!((r = window.__AD_CONFIG__) != null && r.debug) : !1;
|
|
973
|
+
}
|
|
974
|
+
function se(r) {
|
|
940
975
|
var e, t;
|
|
941
976
|
return {
|
|
942
|
-
id:
|
|
943
|
-
type:
|
|
944
|
-
score:
|
|
977
|
+
id: r.original.id,
|
|
978
|
+
type: r.original.type,
|
|
979
|
+
score: r.original.score,
|
|
945
980
|
source: "internal",
|
|
946
981
|
// Default source
|
|
947
982
|
content: {
|
|
948
|
-
title:
|
|
949
|
-
body:
|
|
950
|
-
image: (e =
|
|
951
|
-
cta_text:
|
|
952
|
-
price: (t =
|
|
953
|
-
rating:
|
|
954
|
-
brand:
|
|
983
|
+
title: r.adapted.title,
|
|
984
|
+
body: r.adapted.body,
|
|
985
|
+
image: (e = r.adapted.image) == null ? void 0 : e.url,
|
|
986
|
+
cta_text: r.adapted.ctaText,
|
|
987
|
+
price: (t = r.adapted.price) == null ? void 0 : t.display,
|
|
988
|
+
rating: r.adapted.rating,
|
|
989
|
+
brand: r.adapted.brand
|
|
955
990
|
},
|
|
956
991
|
tracking: {
|
|
957
|
-
click_url:
|
|
958
|
-
impression_url:
|
|
992
|
+
click_url: r.tracking.clickUrl || r.tracking.click_url || "",
|
|
993
|
+
impression_url: r.tracking.impressionUrl || r.tracking.impression_url || ""
|
|
959
994
|
},
|
|
960
995
|
metadata: {
|
|
961
|
-
viewToken:
|
|
962
|
-
styling:
|
|
996
|
+
viewToken: r.tracking.viewToken || r.tracking.view_token,
|
|
997
|
+
styling: r.adapted.styling
|
|
963
998
|
}
|
|
964
999
|
};
|
|
965
1000
|
}
|
|
966
|
-
async function
|
|
967
|
-
const t = e.apiBaseUrl || "/api/v1", s =
|
|
968
|
-
...
|
|
1001
|
+
async function D(r, e = {}) {
|
|
1002
|
+
const t = e.apiBaseUrl || "/api/v1", s = $().collect(), n = {
|
|
1003
|
+
...r,
|
|
969
1004
|
clientInfo: s
|
|
970
1005
|
// Auto-injected
|
|
971
|
-
},
|
|
1006
|
+
}, o = {
|
|
972
1007
|
"Content-Type": "application/json"
|
|
973
1008
|
};
|
|
974
|
-
e.apiKey && (
|
|
1009
|
+
e.apiKey && (o["X-API-Key"] = e.apiKey), M() && (console.log("[fetchAds] Request URL:", `${t}/ads/request`), console.log("[fetchAds] Request params:", r), console.log("[fetchAds] Request body:", n));
|
|
975
1010
|
const a = await fetch(`${t}/ads/request`, {
|
|
976
1011
|
method: "POST",
|
|
977
|
-
headers:
|
|
1012
|
+
headers: o,
|
|
978
1013
|
body: JSON.stringify(n)
|
|
979
1014
|
});
|
|
980
1015
|
if (!a.ok)
|
|
981
1016
|
throw new Error(`Ad request failed: ${a.status} ${a.statusText}`);
|
|
982
1017
|
const c = await a.json();
|
|
983
|
-
if (!c.success)
|
|
1018
|
+
if (M() && console.log("[fetchAds] Response:", c), !c.success)
|
|
984
1019
|
throw new Error(c.error || "Ad request failed");
|
|
985
1020
|
return c.data;
|
|
986
1021
|
}
|
|
987
|
-
const
|
|
1022
|
+
const H = { width: 400, height: 200 }, A = {
|
|
988
1023
|
variant: "horizontal",
|
|
989
1024
|
count: 1,
|
|
990
1025
|
preferences: {}
|
|
991
1026
|
};
|
|
992
|
-
function
|
|
1027
|
+
function _(r = {}) {
|
|
993
1028
|
const e = {
|
|
994
|
-
variant:
|
|
995
|
-
count:
|
|
996
|
-
preferences: { ...A.preferences, ...
|
|
1029
|
+
variant: r.variant ?? A.variant,
|
|
1030
|
+
count: r.count ?? A.count,
|
|
1031
|
+
preferences: { ...A.preferences, ...r.preferences }
|
|
997
1032
|
};
|
|
998
1033
|
return [
|
|
999
1034
|
{
|
|
@@ -1001,7 +1036,7 @@ function U(o = {}) {
|
|
|
1001
1036
|
slotName: "Action Card",
|
|
1002
1037
|
format: "action_card",
|
|
1003
1038
|
variant: e.variant,
|
|
1004
|
-
size:
|
|
1039
|
+
size: H,
|
|
1005
1040
|
count: e.count,
|
|
1006
1041
|
preferences: e.preferences,
|
|
1007
1042
|
placement: { position: "below_fold", context: "post_response" }
|
|
@@ -1010,10 +1045,11 @@ function U(o = {}) {
|
|
|
1010
1045
|
}
|
|
1011
1046
|
const g = class g {
|
|
1012
1047
|
constructor(e) {
|
|
1013
|
-
this.slots = {}, this.isLoading = !1, this.currentRequestId = null, this.adsAnalyticsMap = /* @__PURE__ */ new Map(), this.config = e, this.enabled = e.enabled !== !1, this.eventBus = new B(), this.slots_config =
|
|
1048
|
+
this.slots = {}, this.isLoading = !1, this.currentRequestId = null, this.adsAnalyticsMap = /* @__PURE__ */ new Map(), this.config = e, this.enabled = e.enabled !== !1, this.eventBus = new B(), this.slots_config = _(e.cardOption), typeof window < "u" && (window.__AD_CONFIG__ = {
|
|
1014
1049
|
...window.__AD_CONFIG__ || {},
|
|
1015
1050
|
apiKey: e.apiKey,
|
|
1016
|
-
apiBaseUrl: e.apiBaseUrl
|
|
1051
|
+
apiBaseUrl: e.apiBaseUrl,
|
|
1052
|
+
debug: !!e.debug
|
|
1017
1053
|
}), this.config.debug && console.log("[AdManager] Initialized with config:", {
|
|
1018
1054
|
apiBaseUrl: e.apiBaseUrl,
|
|
1019
1055
|
hasApiKey: !!e.apiKey,
|
|
@@ -1021,7 +1057,10 @@ const g = class g {
|
|
|
1021
1057
|
});
|
|
1022
1058
|
}
|
|
1023
1059
|
async requestAds(e) {
|
|
1024
|
-
|
|
1060
|
+
var o;
|
|
1061
|
+
const t = "conversationContext" in e ? e : { conversationContext: e };
|
|
1062
|
+
this.currentUserId = (o = t.userContext) == null ? void 0 : o.userId;
|
|
1063
|
+
const i = this.buildRequestKey(t), s = g.inFlightRequests.get(i);
|
|
1025
1064
|
if (s)
|
|
1026
1065
|
return this.config.debug && console.log("[AdManager] Reusing in-flight request for identical context"), s;
|
|
1027
1066
|
if (!this.enabled)
|
|
@@ -1031,10 +1070,10 @@ const g = class g {
|
|
|
1031
1070
|
this.isLoading = !0, this.eventBus.emit("adsLoading"), this.config.debug && console.log("[AdManager] Starting ad request...");
|
|
1032
1071
|
const n = (async () => {
|
|
1033
1072
|
try {
|
|
1034
|
-
const
|
|
1073
|
+
const a = await D(
|
|
1035
1074
|
{
|
|
1036
1075
|
conversationContext: t.conversationContext,
|
|
1037
|
-
userContext: t.userContext ? { ...t.userContext, sessionId: t.userContext.sessionId ??
|
|
1076
|
+
userContext: t.userContext ? { ...t.userContext, sessionId: t.userContext.sessionId ?? y() } : { sessionId: y() },
|
|
1038
1077
|
slots: this.slots_config
|
|
1039
1078
|
},
|
|
1040
1079
|
{
|
|
@@ -1042,28 +1081,29 @@ const g = class g {
|
|
|
1042
1081
|
apiKey: this.config.apiKey
|
|
1043
1082
|
}
|
|
1044
1083
|
);
|
|
1045
|
-
this.currentRequestId =
|
|
1046
|
-
|
|
1047
|
-
const
|
|
1048
|
-
this.adsAnalyticsMap.set(
|
|
1049
|
-
requestId:
|
|
1050
|
-
slotId:
|
|
1051
|
-
position:
|
|
1052
|
-
totalAds:
|
|
1053
|
-
apiBaseUrl: this.config.apiBaseUrl
|
|
1084
|
+
this.currentRequestId = a.requestId, this.adsAnalyticsMap.clear(), a.slots.forEach((l) => {
|
|
1085
|
+
l.ads.forEach((d, u) => {
|
|
1086
|
+
const h = d.original.id;
|
|
1087
|
+
this.adsAnalyticsMap.set(h, {
|
|
1088
|
+
requestId: a.requestId,
|
|
1089
|
+
slotId: l.slotId,
|
|
1090
|
+
position: u,
|
|
1091
|
+
totalAds: l.ads.length,
|
|
1092
|
+
apiBaseUrl: this.config.apiBaseUrl,
|
|
1093
|
+
userId: this.currentUserId
|
|
1054
1094
|
});
|
|
1055
1095
|
});
|
|
1056
1096
|
});
|
|
1057
|
-
const
|
|
1058
|
-
return
|
|
1059
|
-
|
|
1060
|
-
}), this.slots =
|
|
1097
|
+
const c = {};
|
|
1098
|
+
return a.slots.forEach((l) => {
|
|
1099
|
+
c[l.slotId] = l;
|
|
1100
|
+
}), this.slots = c, this.eventBus.emit("adsUpdated", this.slots), this.config.debug && console.log("[AdManager] Ads received:", {
|
|
1061
1101
|
slotCount: Object.keys(this.slots).length,
|
|
1062
1102
|
slots: Object.keys(this.slots)
|
|
1063
|
-
}),
|
|
1064
|
-
} catch (
|
|
1065
|
-
const
|
|
1066
|
-
throw this.eventBus.emit("adsError",
|
|
1103
|
+
}), a;
|
|
1104
|
+
} catch (a) {
|
|
1105
|
+
const c = a;
|
|
1106
|
+
throw this.eventBus.emit("adsError", c), c;
|
|
1067
1107
|
} finally {
|
|
1068
1108
|
this.isLoading = !1, g.inFlightRequests.delete(i);
|
|
1069
1109
|
}
|
|
@@ -1080,24 +1120,24 @@ const g = class g {
|
|
|
1080
1120
|
});
|
|
1081
1121
|
}
|
|
1082
1122
|
render(e, t, i = {}) {
|
|
1083
|
-
const s = typeof e != "string", n = s ? g.DEFAULT_SLOT_ID : e,
|
|
1084
|
-
if (!
|
|
1123
|
+
const s = typeof e != "string", n = s ? g.DEFAULT_SLOT_ID : e, o = s ? e : t, a = (s ? t : i) || {};
|
|
1124
|
+
if (!o)
|
|
1085
1125
|
return this.config.debug && console.warn("[AdManager] Render container is required"), null;
|
|
1086
1126
|
const c = this.slots[n];
|
|
1087
1127
|
if (!c || !c.ads || c.ads.length === 0)
|
|
1088
1128
|
return this.config.debug && console.warn("[AdManager] No ads in slot:", n), null;
|
|
1089
|
-
const
|
|
1090
|
-
if (!
|
|
1091
|
-
return this.config.debug && console.warn(`[AdManager] Ad at index ${
|
|
1092
|
-
const u = this.adsAnalyticsMap.get(
|
|
1093
|
-
|
|
1094
|
-
const
|
|
1129
|
+
const l = a.adIndex ?? 0, d = c.ads[l];
|
|
1130
|
+
if (!d)
|
|
1131
|
+
return this.config.debug && console.warn(`[AdManager] Ad at index ${l} not found in slot:`, n), null;
|
|
1132
|
+
const u = this.adsAnalyticsMap.get(d.original.id), h = this.slots_config.find((m) => m.slotId === n), p = (h == null ? void 0 : h.format) || "action_card";
|
|
1133
|
+
o.innerHTML = "";
|
|
1134
|
+
const f = {
|
|
1095
1135
|
analytics: u,
|
|
1096
1136
|
variant: a.variant,
|
|
1097
1137
|
onClick: a.onClick,
|
|
1098
1138
|
onImpression: a.onImpression
|
|
1099
1139
|
};
|
|
1100
|
-
return p === "suffix" ?
|
|
1140
|
+
return p === "suffix" ? b.renderSuffixAd(d, o, f) : p === "source" ? b.renderSponsoredSource(d, o, f) : p === "lead_gen" ? b.renderLeadGenAd(d, o, f) : b.renderActionCard(d, o, f);
|
|
1101
1141
|
}
|
|
1102
1142
|
/**
|
|
1103
1143
|
* Get ad slots data
|
|
@@ -1136,7 +1176,7 @@ const g = class g {
|
|
|
1136
1176
|
* Update configuration
|
|
1137
1177
|
*/
|
|
1138
1178
|
updateConfig(e) {
|
|
1139
|
-
this.config = { ...this.config, ...e }, e.cardOption !== void 0 && (this.slots_config =
|
|
1179
|
+
this.config = { ...this.config, ...e }, e.cardOption !== void 0 && (this.slots_config = _(this.config.cardOption)), this.config.debug && console.log("[AdManager] Config updated:", e);
|
|
1140
1180
|
}
|
|
1141
1181
|
/**
|
|
1142
1182
|
* Clear all slot data
|
|
@@ -1191,7 +1231,7 @@ const g = class g {
|
|
|
1191
1231
|
const s = this.adsAnalyticsMap.get(e);
|
|
1192
1232
|
if (!s || !this.currentRequestId)
|
|
1193
1233
|
return this.config.debug && console.warn("[AdManager] No analytics info for ad:", e), null;
|
|
1194
|
-
const n =
|
|
1234
|
+
const n = y(), o = await T({
|
|
1195
1235
|
requestId: this.currentRequestId,
|
|
1196
1236
|
adId: e,
|
|
1197
1237
|
destinationUrl: t,
|
|
@@ -1199,9 +1239,10 @@ const g = class g {
|
|
|
1199
1239
|
slotId: s.slotId,
|
|
1200
1240
|
adTitle: i == null ? void 0 : i.title,
|
|
1201
1241
|
format: i == null ? void 0 : i.format,
|
|
1202
|
-
source: i == null ? void 0 : i.source
|
|
1242
|
+
source: i == null ? void 0 : i.source,
|
|
1243
|
+
userId: s.userId ?? this.currentUserId
|
|
1203
1244
|
}, { baseUrl: s.apiBaseUrl });
|
|
1204
|
-
return
|
|
1245
|
+
return o && (this.eventBus.emit("adClicked", e, s.slotId), this.config.debug && console.log("[AdManager] Click tracked via Analytics API:", o.eventId)), o;
|
|
1205
1246
|
}
|
|
1206
1247
|
/**
|
|
1207
1248
|
* Track ad impression using Analytics API
|
|
@@ -1210,7 +1251,7 @@ const g = class g {
|
|
|
1210
1251
|
const i = this.adsAnalyticsMap.get(e);
|
|
1211
1252
|
if (!i || !this.currentRequestId)
|
|
1212
1253
|
return this.config.debug && console.warn("[AdManager] No analytics info for ad:", e), null;
|
|
1213
|
-
const s =
|
|
1254
|
+
const s = y(), n = await I({
|
|
1214
1255
|
requestId: this.currentRequestId,
|
|
1215
1256
|
adId: e,
|
|
1216
1257
|
slotId: i.slotId,
|
|
@@ -1220,7 +1261,8 @@ const g = class g {
|
|
|
1220
1261
|
adTitle: t == null ? void 0 : t.title,
|
|
1221
1262
|
format: t == null ? void 0 : t.format,
|
|
1222
1263
|
source: t == null ? void 0 : t.source,
|
|
1223
|
-
viewToken: t == null ? void 0 : t.viewToken
|
|
1264
|
+
viewToken: t == null ? void 0 : t.viewToken,
|
|
1265
|
+
userId: i.userId ?? this.currentUserId
|
|
1224
1266
|
}, { baseUrl: i.apiBaseUrl });
|
|
1225
1267
|
return n && (this.eventBus.emit("adImpression", e, i.slotId), this.config.debug && console.log("[AdManager] Impression tracked via Analytics API:", n.eventId)), n;
|
|
1226
1268
|
}
|
|
@@ -1235,12 +1277,12 @@ g.DEFAULT_SLOT_ID = "action_card", g.inFlightRequests = /* @__PURE__ */ new Map(
|
|
|
1235
1277
|
let V = g;
|
|
1236
1278
|
function E() {
|
|
1237
1279
|
if (typeof window < "u") {
|
|
1238
|
-
const
|
|
1239
|
-
if (
|
|
1240
|
-
return
|
|
1280
|
+
const r = window.__AD_CONFIG__;
|
|
1281
|
+
if (r != null && r.apiKey)
|
|
1282
|
+
return r.apiKey;
|
|
1241
1283
|
}
|
|
1242
1284
|
}
|
|
1243
|
-
class
|
|
1285
|
+
class F {
|
|
1244
1286
|
constructor(e = {}, t = "/api/v1") {
|
|
1245
1287
|
var i, s;
|
|
1246
1288
|
this.observers = /* @__PURE__ */ new Map(), this.metrics = /* @__PURE__ */ new Map(), this.timers = /* @__PURE__ */ new Map(), this.batchTimers = /* @__PURE__ */ new Map(), this.eventQueue = /* @__PURE__ */ new Map(), this.isTracking = /* @__PURE__ */ new Map(), this.config = {
|
|
@@ -1263,7 +1305,7 @@ class H {
|
|
|
1263
1305
|
return;
|
|
1264
1306
|
}
|
|
1265
1307
|
this.log(`[ViewabilityTracker] Starting tracking for ${e}`);
|
|
1266
|
-
const
|
|
1308
|
+
const o = {
|
|
1267
1309
|
visiblePercentage: 0,
|
|
1268
1310
|
maxVisiblePercentage: 0,
|
|
1269
1311
|
totalVisibleTimeMs: 0,
|
|
@@ -1273,9 +1315,9 @@ class H {
|
|
|
1273
1315
|
enteredViewportAt: null,
|
|
1274
1316
|
enterCount: 0
|
|
1275
1317
|
};
|
|
1276
|
-
this.metrics.set(e,
|
|
1318
|
+
this.metrics.set(e, o), this.isTracking.set(e, !0), this.eventQueue.set(e, []);
|
|
1277
1319
|
const a = new IntersectionObserver(
|
|
1278
|
-
(
|
|
1320
|
+
(l) => this.handleIntersection(e, l[0], i, s, n),
|
|
1279
1321
|
{
|
|
1280
1322
|
threshold: this.createThresholds()
|
|
1281
1323
|
}
|
|
@@ -1303,54 +1345,54 @@ class H {
|
|
|
1303
1345
|
* Event-driven: Only process when state actually changes
|
|
1304
1346
|
*/
|
|
1305
1347
|
handleIntersection(e, t, i, s, n) {
|
|
1306
|
-
const
|
|
1307
|
-
if (!
|
|
1308
|
-
const a =
|
|
1309
|
-
|
|
1310
|
-
const
|
|
1311
|
-
if (
|
|
1348
|
+
const o = this.metrics.get(e);
|
|
1349
|
+
if (!o || !this.isTracking.get(e)) return;
|
|
1350
|
+
const a = o.isViewable, c = Math.round(t.intersectionRatio * 100);
|
|
1351
|
+
o.visiblePercentage = c, o.maxVisiblePercentage = Math.max(o.maxVisiblePercentage, c);
|
|
1352
|
+
const l = Date.now(), d = c >= this.config.minVisiblePercentage;
|
|
1353
|
+
if (d && !o.enteredViewportAt && (o.enteredViewportAt = l, o.enterCount++, this.log(`[ViewabilityTracker] ${e} entered viewport at ${l}`), this.queueEvent(e, {
|
|
1312
1354
|
adId: e,
|
|
1313
1355
|
sessionId: i,
|
|
1314
1356
|
requestId: s,
|
|
1315
1357
|
viewToken: n,
|
|
1316
1358
|
eventType: "enter_viewport",
|
|
1317
1359
|
visiblePercentage: c,
|
|
1318
|
-
maxVisiblePercentage:
|
|
1319
|
-
totalVisibleTimeMs:
|
|
1360
|
+
maxVisiblePercentage: o.maxVisiblePercentage,
|
|
1361
|
+
totalVisibleTimeMs: o.totalVisibleTimeMs,
|
|
1320
1362
|
isViewable: !1,
|
|
1321
|
-
timestamp:
|
|
1322
|
-
})), !
|
|
1323
|
-
const u =
|
|
1324
|
-
|
|
1363
|
+
timestamp: l
|
|
1364
|
+
})), !d && o.enteredViewportAt) {
|
|
1365
|
+
const u = l - o.enteredViewportAt;
|
|
1366
|
+
o.totalVisibleTimeMs += u, o.enteredViewportAt = null, o.currentVisibleTimeMs = 0, this.log(`[ViewabilityTracker] ${e} exited viewport, total visible: ${o.totalVisibleTimeMs}ms`), this.queueEvent(e, {
|
|
1325
1367
|
adId: e,
|
|
1326
1368
|
sessionId: i,
|
|
1327
1369
|
requestId: s,
|
|
1328
1370
|
viewToken: n,
|
|
1329
1371
|
eventType: "exit_viewport",
|
|
1330
1372
|
visiblePercentage: c,
|
|
1331
|
-
maxVisiblePercentage:
|
|
1332
|
-
totalVisibleTimeMs:
|
|
1333
|
-
isViewable:
|
|
1334
|
-
timestamp:
|
|
1373
|
+
maxVisiblePercentage: o.maxVisiblePercentage,
|
|
1374
|
+
totalVisibleTimeMs: o.totalVisibleTimeMs,
|
|
1375
|
+
isViewable: o.isViewable,
|
|
1376
|
+
timestamp: l
|
|
1335
1377
|
});
|
|
1336
1378
|
}
|
|
1337
|
-
|
|
1379
|
+
o.isViewable !== a && o.isViewable && this.log(`[ViewabilityTracker] ${e} became VIEWABLE!`), this.metrics.set(e, o);
|
|
1338
1380
|
}
|
|
1339
1381
|
/**
|
|
1340
1382
|
* Start monitoring loop for tracking duration
|
|
1341
1383
|
* Runs every 100ms to track continuous visible time
|
|
1342
1384
|
*/
|
|
1343
1385
|
startMonitoring(e, t, i, s) {
|
|
1344
|
-
const
|
|
1386
|
+
const o = setInterval(() => {
|
|
1345
1387
|
const a = this.metrics.get(e);
|
|
1346
1388
|
if (!a || !this.isTracking.get(e)) {
|
|
1347
|
-
clearInterval(
|
|
1389
|
+
clearInterval(o);
|
|
1348
1390
|
return;
|
|
1349
1391
|
}
|
|
1350
|
-
const c = Date.now(),
|
|
1392
|
+
const c = Date.now(), l = a.isViewable;
|
|
1351
1393
|
if (a.enteredViewportAt) {
|
|
1352
|
-
const
|
|
1353
|
-
a.currentVisibleTimeMs =
|
|
1394
|
+
const d = c - a.enteredViewportAt;
|
|
1395
|
+
a.currentVisibleTimeMs = d, d >= this.config.minViewableDuration && a.visiblePercentage >= this.config.minVisiblePercentage && (a.isViewable = !0, l || (a.viewableAt = a.enteredViewportAt, this.log(`[ViewabilityTracker] ${e} BECAME VIEWABLE at ${a.viewableAt}`), this.queueEvent(e, {
|
|
1354
1396
|
adId: e,
|
|
1355
1397
|
sessionId: t,
|
|
1356
1398
|
requestId: i,
|
|
@@ -1365,13 +1407,13 @@ class H {
|
|
|
1365
1407
|
}
|
|
1366
1408
|
a.enteredViewportAt && (a.totalVisibleTimeMs += 100), this.metrics.set(e, a);
|
|
1367
1409
|
}, 100);
|
|
1368
|
-
this.timers.set(`${e}_monitoring`,
|
|
1410
|
+
this.timers.set(`${e}_monitoring`, o);
|
|
1369
1411
|
}
|
|
1370
1412
|
/**
|
|
1371
1413
|
* Queue an event to be sent (batched)
|
|
1372
1414
|
*/
|
|
1373
1415
|
queueEvent(e, t) {
|
|
1374
|
-
var n,
|
|
1416
|
+
var n, o;
|
|
1375
1417
|
const i = this.eventQueue.get(e);
|
|
1376
1418
|
if (!i) {
|
|
1377
1419
|
this.log(`[ViewabilityTracker] No queue found for ${e}, skipping event`);
|
|
@@ -1384,10 +1426,10 @@ class H {
|
|
|
1384
1426
|
else {
|
|
1385
1427
|
const a = this.batchTimers.get(e);
|
|
1386
1428
|
a && clearTimeout(a);
|
|
1387
|
-
const c = ((
|
|
1429
|
+
const c = ((o = this.config.batchConfig) == null ? void 0 : o.maxBatchWaitMs) ?? 1e4, l = setTimeout(() => {
|
|
1388
1430
|
this.flushQueue(e);
|
|
1389
1431
|
}, c);
|
|
1390
|
-
this.batchTimers.set(e,
|
|
1432
|
+
this.batchTimers.set(e, l);
|
|
1391
1433
|
}
|
|
1392
1434
|
}
|
|
1393
1435
|
/**
|
|
@@ -1418,7 +1460,7 @@ class H {
|
|
|
1418
1460
|
const n = this.metrics.get(e);
|
|
1419
1461
|
if (!n) return;
|
|
1420
1462
|
this.log(`[ViewabilityTracker] Ending tracking for ${e}`), this.flushQueue(e);
|
|
1421
|
-
const
|
|
1463
|
+
const o = Date.now();
|
|
1422
1464
|
this.queueEvent(e, {
|
|
1423
1465
|
adId: e,
|
|
1424
1466
|
sessionId: t,
|
|
@@ -1429,7 +1471,7 @@ class H {
|
|
|
1429
1471
|
maxVisiblePercentage: n.maxVisiblePercentage,
|
|
1430
1472
|
totalVisibleTimeMs: n.totalVisibleTimeMs,
|
|
1431
1473
|
isViewable: n.isViewable,
|
|
1432
|
-
timestamp:
|
|
1474
|
+
timestamp: o
|
|
1433
1475
|
}), this.flushQueue(e), this.cleanup(e);
|
|
1434
1476
|
}
|
|
1435
1477
|
/**
|
|
@@ -1488,38 +1530,38 @@ class H {
|
|
|
1488
1530
|
}
|
|
1489
1531
|
}
|
|
1490
1532
|
let k = null;
|
|
1491
|
-
function
|
|
1492
|
-
return k || (k = new
|
|
1533
|
+
function ne(r, e) {
|
|
1534
|
+
return k || (k = new F(r, e), k.setupBeforeUnload()), k;
|
|
1493
1535
|
}
|
|
1494
|
-
const
|
|
1536
|
+
const re = "0.1.0";
|
|
1495
1537
|
export {
|
|
1496
1538
|
V as AdManager,
|
|
1497
1539
|
x as AnalyticsSender,
|
|
1498
|
-
|
|
1499
|
-
|
|
1500
|
-
|
|
1501
|
-
|
|
1502
|
-
|
|
1503
|
-
|
|
1504
|
-
|
|
1505
|
-
|
|
1506
|
-
|
|
1507
|
-
|
|
1508
|
-
|
|
1509
|
-
|
|
1510
|
-
|
|
1511
|
-
|
|
1512
|
-
|
|
1513
|
-
|
|
1514
|
-
|
|
1515
|
-
|
|
1516
|
-
|
|
1517
|
-
|
|
1518
|
-
|
|
1519
|
-
|
|
1520
|
-
|
|
1540
|
+
S as ClientInfoCollector,
|
|
1541
|
+
b as DOMRenderer,
|
|
1542
|
+
w as HTMLRenderer,
|
|
1543
|
+
re as SDK_VERSION,
|
|
1544
|
+
P as SessionManager,
|
|
1545
|
+
F as ViewabilityTracker,
|
|
1546
|
+
se as adaptAdToKoahAd,
|
|
1547
|
+
ee as clearClientInfoCache,
|
|
1548
|
+
W as createAnalytics,
|
|
1549
|
+
Q as createSession,
|
|
1550
|
+
D as fetchAds,
|
|
1551
|
+
G as generateViewToken,
|
|
1552
|
+
X as getAppInfo,
|
|
1553
|
+
v as getClientInfo,
|
|
1554
|
+
$ as getClientInfoCollector,
|
|
1555
|
+
te as getClientInfoJSON,
|
|
1556
|
+
ie as getClientInfoSummary,
|
|
1557
|
+
J as getDeviceInfo,
|
|
1558
|
+
Z as getGeoInfo,
|
|
1559
|
+
y as getSessionId,
|
|
1560
|
+
Y as getUserId,
|
|
1561
|
+
N as getUserInfo,
|
|
1562
|
+
ne as getViewabilityTracker,
|
|
1521
1563
|
T as trackAdClick,
|
|
1522
|
-
|
|
1523
|
-
|
|
1524
|
-
|
|
1564
|
+
I as trackAdImpression,
|
|
1565
|
+
z as trackClicksBatch,
|
|
1566
|
+
j as trackImpressionsBatch
|
|
1525
1567
|
};
|