@action-x/ad-sdk 0.1.4 → 0.1.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/dist/index.cjs +4 -4
- package/dist/index.d.ts +7 -2
- package/dist/index.js +191 -190
- package/dist/index.umd.js +4 -4
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
class
|
|
1
|
+
class B {
|
|
2
2
|
constructor() {
|
|
3
3
|
this.events = {};
|
|
4
4
|
}
|
|
@@ -23,8 +23,8 @@ class O {
|
|
|
23
23
|
this.events[e] && this.events[e].forEach((i) => {
|
|
24
24
|
try {
|
|
25
25
|
i(...t);
|
|
26
|
-
} catch (
|
|
27
|
-
console.error(`[EventEmitter] Error in event handler for "${e}":`,
|
|
26
|
+
} catch (s) {
|
|
27
|
+
console.error(`[EventEmitter] Error in event handler for "${e}":`, s);
|
|
28
28
|
}
|
|
29
29
|
});
|
|
30
30
|
}
|
|
@@ -42,7 +42,7 @@ class O {
|
|
|
42
42
|
return ((t = this.events[e]) == null ? void 0 : t.length) || 0;
|
|
43
43
|
}
|
|
44
44
|
}
|
|
45
|
-
class
|
|
45
|
+
class v {
|
|
46
46
|
/**
|
|
47
47
|
* Render Action Card ad as HTML string
|
|
48
48
|
*
|
|
@@ -52,19 +52,19 @@ class b {
|
|
|
52
52
|
*/
|
|
53
53
|
static renderActionCard(e, t = {}) {
|
|
54
54
|
var h;
|
|
55
|
-
const { variant: i = "horizontal", includeWrapper:
|
|
56
|
-
src="${
|
|
57
|
-
alt="${
|
|
55
|
+
const { variant: i = "horizontal", includeWrapper: s = !0 } = t, n = e.adapted, r = e.tracking, a = s ? `<div class="ax-ad-card ax-ad-card-${i}" data-ad-id="${e.original.id}">` : "", c = (h = n.image) != null && h.url ? `<img
|
|
56
|
+
src="${n.image.url}"
|
|
57
|
+
alt="${n.title}"
|
|
58
58
|
class="ax-ad-image"
|
|
59
59
|
loading="lazy"
|
|
60
|
-
/>` : "", d =
|
|
61
|
-
${"★".repeat(Math.floor(
|
|
62
|
-
</div>` : "", u =
|
|
60
|
+
/>` : "", d = n.price ? `<span class="ax-ad-price">${n.price.display || n.price.value}</span>` : "", l = n.rating ? `<div class="ax-ad-rating" aria-label="Rating: ${n.rating}">
|
|
61
|
+
${"★".repeat(Math.floor(n.rating))}${"☆".repeat(5 - Math.floor(n.rating))}
|
|
62
|
+
</div>` : "", u = n.brand ? `<span class="ax-ad-brand">${n.brand}</span>` : "", f = `
|
|
63
63
|
${c}
|
|
64
64
|
<div class="ax-ad-content">
|
|
65
65
|
${u}
|
|
66
|
-
<h3 class="ax-ad-title">${
|
|
67
|
-
${
|
|
66
|
+
<h3 class="ax-ad-title">${n.title}</h3>
|
|
67
|
+
${n.body ? `<p class="ax-ad-body">${n.body}</p>` : ""}
|
|
68
68
|
${l}
|
|
69
69
|
<div class="ax-ad-footer">
|
|
70
70
|
${d}
|
|
@@ -76,11 +76,11 @@ class b {
|
|
|
76
76
|
data-ad-id="${e.original.id}"
|
|
77
77
|
data-impression-url="${r.impressionUrl}"
|
|
78
78
|
>
|
|
79
|
-
${
|
|
79
|
+
${n.ctaText || "Learn More"}
|
|
80
80
|
</a>
|
|
81
81
|
</div>
|
|
82
82
|
</div>
|
|
83
|
-
`, p =
|
|
83
|
+
`, p = s ? "</div>" : "";
|
|
84
84
|
return a + f + p;
|
|
85
85
|
}
|
|
86
86
|
/**
|
|
@@ -117,7 +117,7 @@ class b {
|
|
|
117
117
|
* @returns HTML string
|
|
118
118
|
*/
|
|
119
119
|
static renderSponsoredSource(e) {
|
|
120
|
-
var
|
|
120
|
+
var s;
|
|
121
121
|
const t = e.adapted, i = e.tracking;
|
|
122
122
|
return `
|
|
123
123
|
<div class="ax-ad-source" data-ad-id="${e.original.id}">
|
|
@@ -129,7 +129,7 @@ class b {
|
|
|
129
129
|
data-ad-id="${e.original.id}"
|
|
130
130
|
data-impression-url="${i.impressionUrl}"
|
|
131
131
|
>
|
|
132
|
-
${(
|
|
132
|
+
${(s = t.image) != null && s.url ? `<img src="${t.image.url}" alt="" class="ax-ad-source-icon" />` : ""}
|
|
133
133
|
<div class="ax-ad-source-info">
|
|
134
134
|
<span class="ax-ad-source-name">${t.title}</span>
|
|
135
135
|
${t.body ? `<span class="ax-ad-source-desc">${t.body}</span>` : ""}
|
|
@@ -173,20 +173,20 @@ class b {
|
|
|
173
173
|
* @param renderFn - Render function to use
|
|
174
174
|
* @returns HTML string with all ads
|
|
175
175
|
*/
|
|
176
|
-
static renderAds(e, t =
|
|
176
|
+
static renderAds(e, t = v.renderActionCard.bind(v)) {
|
|
177
177
|
return e.map(t).join(`
|
|
178
178
|
`);
|
|
179
179
|
}
|
|
180
180
|
}
|
|
181
|
-
const
|
|
182
|
-
function
|
|
181
|
+
const O = "ad_session_id";
|
|
182
|
+
function q() {
|
|
183
183
|
if (typeof window < "u") {
|
|
184
184
|
const o = window.__AD_CONFIG__;
|
|
185
185
|
if (o != null && o.apiKey)
|
|
186
186
|
return o.apiKey;
|
|
187
187
|
}
|
|
188
188
|
}
|
|
189
|
-
function
|
|
189
|
+
function C(o) {
|
|
190
190
|
if (o) return o;
|
|
191
191
|
if (typeof window < "u") {
|
|
192
192
|
const e = window.__AD_CONFIG__;
|
|
@@ -197,7 +197,7 @@ function M(o) {
|
|
|
197
197
|
}
|
|
198
198
|
class _ {
|
|
199
199
|
constructor(e = {}) {
|
|
200
|
-
this.memoryCache = /* @__PURE__ */ new Map(), this.sessionKey = e.sessionKey ||
|
|
200
|
+
this.memoryCache = /* @__PURE__ */ new Map(), this.sessionKey = e.sessionKey || O, this.storage = e.storage || "sessionStorage", (typeof window > "u" || typeof window.sessionStorage > "u") && (this.storage = "memory");
|
|
201
201
|
}
|
|
202
202
|
/**
|
|
203
203
|
* 获取 Session ID
|
|
@@ -232,7 +232,7 @@ class _ {
|
|
|
232
232
|
}
|
|
233
233
|
}
|
|
234
234
|
const L = new _(), m = () => L.getSessionId();
|
|
235
|
-
class
|
|
235
|
+
class x {
|
|
236
236
|
constructor(e = {}) {
|
|
237
237
|
this.explicitBaseUrl = e.baseUrl, this.timeout = e.timeout || 1e4, this.retryAttempts = e.retryAttempts ?? 2, this.retryDelay = e.retryDelay || 1e3, this.debug = e.debug || !1;
|
|
238
238
|
}
|
|
@@ -241,7 +241,7 @@ class P {
|
|
|
241
241
|
*/
|
|
242
242
|
async trackImpression(e) {
|
|
243
243
|
return this.sendRequest(
|
|
244
|
-
`${
|
|
244
|
+
`${C(this.explicitBaseUrl)}/ads/impression`,
|
|
245
245
|
e,
|
|
246
246
|
"impression"
|
|
247
247
|
);
|
|
@@ -251,7 +251,7 @@ class P {
|
|
|
251
251
|
*/
|
|
252
252
|
async trackClick(e) {
|
|
253
253
|
return this.sendRequest(
|
|
254
|
-
`${
|
|
254
|
+
`${C(this.explicitBaseUrl)}/ads/click`,
|
|
255
255
|
e,
|
|
256
256
|
"click"
|
|
257
257
|
);
|
|
@@ -261,13 +261,13 @@ class P {
|
|
|
261
261
|
* 自动添加 X-API-Key header
|
|
262
262
|
*/
|
|
263
263
|
async sendRequest(e, t, i) {
|
|
264
|
-
let
|
|
265
|
-
for (let
|
|
264
|
+
let s = null;
|
|
265
|
+
for (let n = 0; n <= this.retryAttempts; n++)
|
|
266
266
|
try {
|
|
267
|
-
this.debug && console.log(`[Analytics] Sending ${i} event (attempt ${
|
|
267
|
+
this.debug && console.log(`[Analytics] Sending ${i} event (attempt ${n + 1}):`, t);
|
|
268
268
|
const r = new AbortController(), a = setTimeout(() => r.abort(), this.timeout), c = {
|
|
269
269
|
"Content-Type": "application/json"
|
|
270
|
-
}, d =
|
|
270
|
+
}, d = q();
|
|
271
271
|
d && (c["X-API-Key"] = d, this.debug && console.log(`[Analytics] Adding X-API-Key header for ${i} event`));
|
|
272
272
|
const l = await fetch(e, {
|
|
273
273
|
method: "POST",
|
|
@@ -281,9 +281,9 @@ class P {
|
|
|
281
281
|
const u = await l.json();
|
|
282
282
|
return this.debug && console.log(`[Analytics] ${i} event tracked successfully:`, u), u;
|
|
283
283
|
} catch (r) {
|
|
284
|
-
|
|
284
|
+
s = r, this.debug && console.warn(`[Analytics] ${i} tracking failed (attempt ${n + 1}):`, r), n < this.retryAttempts && await this.delay(this.retryDelay * (n + 1));
|
|
285
285
|
}
|
|
286
|
-
return console.error(`[Analytics] ${i} tracking failed after ${this.retryAttempts + 1} attempts:`,
|
|
286
|
+
return console.error(`[Analytics] ${i} tracking failed after ${this.retryAttempts + 1} attempts:`, s), null;
|
|
287
287
|
}
|
|
288
288
|
/**
|
|
289
289
|
* 延迟辅助方法
|
|
@@ -292,18 +292,18 @@ class P {
|
|
|
292
292
|
return new Promise((t) => setTimeout(t, e));
|
|
293
293
|
}
|
|
294
294
|
}
|
|
295
|
-
const
|
|
295
|
+
const P = new x(), S = (o, e) => e != null && e.baseUrl ? new x({ baseUrl: e.baseUrl }).trackImpression(o) : P.trackImpression(o), T = (o, e) => e != null && e.baseUrl ? new x({ baseUrl: e.baseUrl }).trackClick(o) : P.trackClick(o);
|
|
296
296
|
function F(o, e) {
|
|
297
297
|
return `vt_${o}_${e}`;
|
|
298
298
|
}
|
|
299
299
|
async function G(o) {
|
|
300
|
-
return Promise.all(o.map((e) =>
|
|
300
|
+
return Promise.all(o.map((e) => S(e)));
|
|
301
301
|
}
|
|
302
302
|
async function D(o) {
|
|
303
|
-
return Promise.all(o.map((e) =>
|
|
303
|
+
return Promise.all(o.map((e) => T(e)));
|
|
304
304
|
}
|
|
305
305
|
function j(o) {
|
|
306
|
-
const e = new
|
|
306
|
+
const e = new x(o);
|
|
307
307
|
return {
|
|
308
308
|
trackImpression: (t) => e.trackImpression(t),
|
|
309
309
|
trackClick: (t) => e.trackClick(t)
|
|
@@ -317,25 +317,25 @@ function z(o = {}) {
|
|
|
317
317
|
clearSessionId: () => e.clearSessionId()
|
|
318
318
|
};
|
|
319
319
|
}
|
|
320
|
-
const
|
|
320
|
+
const M = class M {
|
|
321
321
|
/**
|
|
322
322
|
* Render Action Card ad into container
|
|
323
323
|
*/
|
|
324
324
|
static renderActionCard(e, t, i = {}) {
|
|
325
|
-
t.innerHTML =
|
|
326
|
-
const
|
|
327
|
-
return
|
|
328
|
-
|
|
325
|
+
t.innerHTML = v.renderActionCard(e, i);
|
|
326
|
+
const s = t.querySelector(".ax-ad-cta");
|
|
327
|
+
return s && s.addEventListener("click", (n) => {
|
|
328
|
+
n.preventDefault(), this.handleClick(e, i);
|
|
329
329
|
}), this.trackImpression(e, t, i), t;
|
|
330
330
|
}
|
|
331
331
|
/**
|
|
332
332
|
* Render Suffix ad into container
|
|
333
333
|
*/
|
|
334
334
|
static renderSuffixAd(e, t, i = {}) {
|
|
335
|
-
const
|
|
336
|
-
t.innerHTML = this.generateSuffixAdHTML(e,
|
|
337
|
-
const
|
|
338
|
-
return
|
|
335
|
+
const s = i.variant || "block";
|
|
336
|
+
t.innerHTML = this.generateSuffixAdHTML(e, s);
|
|
337
|
+
const n = t.querySelector(".ax-ad-suffix-link");
|
|
338
|
+
return n && n.addEventListener("click", (r) => {
|
|
339
339
|
r.preventDefault(), this.handleClick(e, i);
|
|
340
340
|
}), this.trackImpression(e, t, i), t;
|
|
341
341
|
}
|
|
@@ -343,10 +343,10 @@ const I = class I {
|
|
|
343
343
|
* Render Sponsored Source ad into container
|
|
344
344
|
*/
|
|
345
345
|
static renderSponsoredSource(e, t, i = {}) {
|
|
346
|
-
const
|
|
347
|
-
t.innerHTML = this.generateSponsoredSourceHTML(e,
|
|
348
|
-
const
|
|
349
|
-
return
|
|
346
|
+
const s = i.variant || "card";
|
|
347
|
+
t.innerHTML = this.generateSponsoredSourceHTML(e, s);
|
|
348
|
+
const n = t.querySelector(".ax-ad-source-link");
|
|
349
|
+
return n && n.addEventListener("click", (r) => {
|
|
350
350
|
r.preventDefault(), this.handleClick(e, i);
|
|
351
351
|
}), this.trackImpression(e, t, i), t;
|
|
352
352
|
}
|
|
@@ -354,30 +354,30 @@ const I = class I {
|
|
|
354
354
|
* Render Lead Gen ad into container
|
|
355
355
|
*/
|
|
356
356
|
static renderLeadGenAd(e, t, i = {}) {
|
|
357
|
-
t.innerHTML =
|
|
358
|
-
const
|
|
359
|
-
return
|
|
360
|
-
|
|
357
|
+
t.innerHTML = v.renderLeadGenAd(e);
|
|
358
|
+
const s = t.querySelector(".ax-ad-leadgen-cta");
|
|
359
|
+
return s && s.addEventListener("click", (n) => {
|
|
360
|
+
n.preventDefault(), this.handleClick(e, i);
|
|
361
361
|
}), this.trackImpression(e, t, i), t;
|
|
362
362
|
}
|
|
363
363
|
/**
|
|
364
364
|
* Render multiple ads into container
|
|
365
365
|
*/
|
|
366
|
-
static renderAds(e, t, i = this.renderActionCard.bind(this),
|
|
366
|
+
static renderAds(e, t, i = this.renderActionCard.bind(this), s) {
|
|
367
367
|
t.innerHTML = "";
|
|
368
|
-
const
|
|
369
|
-
return
|
|
368
|
+
const n = document.createElement("div");
|
|
369
|
+
return n.className = "ax-ads-container", e.forEach((r) => {
|
|
370
370
|
const a = document.createElement("div");
|
|
371
|
-
a.className = "ax-ad-wrapper", i.call(this, r, a,
|
|
372
|
-
}), t.appendChild(
|
|
371
|
+
a.className = "ax-ad-wrapper", i.call(this, r, a, s), n.appendChild(a);
|
|
372
|
+
}), t.appendChild(n), t;
|
|
373
373
|
}
|
|
374
374
|
/**
|
|
375
375
|
* Handle ad click
|
|
376
376
|
* First tracks the click (async, non-blocking), then opens the URL.
|
|
377
377
|
*/
|
|
378
378
|
static handleClick(e, t) {
|
|
379
|
-
const { analytics: i, onClick:
|
|
380
|
-
|
|
379
|
+
const { analytics: i, onClick: s } = t;
|
|
380
|
+
s && s(e), i && T({
|
|
381
381
|
requestId: i.requestId,
|
|
382
382
|
adId: e.original.id,
|
|
383
383
|
destinationUrl: e.tracking.clickUrl,
|
|
@@ -385,8 +385,8 @@ const I = class I {
|
|
|
385
385
|
sessionId: m(),
|
|
386
386
|
adTitle: e.adapted.title,
|
|
387
387
|
format: e.original.type
|
|
388
|
-
}).catch((
|
|
389
|
-
console.error("[DOMRenderer] Analytics click tracking failed:",
|
|
388
|
+
}, { baseUrl: i.apiBaseUrl }).catch((n) => {
|
|
389
|
+
console.error("[DOMRenderer] Analytics click tracking failed:", n);
|
|
390
390
|
}), window.open(e.tracking.clickUrl, "_blank", "noopener,noreferrer");
|
|
391
391
|
}
|
|
392
392
|
/**
|
|
@@ -394,29 +394,29 @@ const I = class I {
|
|
|
394
394
|
* Falls back to immediate tracking if IntersectionObserver is unavailable.
|
|
395
395
|
*/
|
|
396
396
|
static trackImpression(e, t, i) {
|
|
397
|
-
const { analytics:
|
|
397
|
+
const { analytics: s, onImpression: n } = i, r = s ? `${s.requestId}:${s.slotId}:${e.original.id}:${e.tracking.viewToken || ""}` : `no-analytics:${e.original.id}:${e.tracking.viewToken || ""}`;
|
|
398
398
|
if (this.trackedImpressionKeys.has(r))
|
|
399
399
|
return;
|
|
400
400
|
let a = !1;
|
|
401
401
|
const c = () => {
|
|
402
402
|
a || this.trackedImpressionKeys.has(r) || (a = !0, this.trackedImpressionKeys.add(r), d());
|
|
403
403
|
}, d = () => {
|
|
404
|
-
|
|
405
|
-
requestId:
|
|
404
|
+
s ? S({
|
|
405
|
+
requestId: s.requestId,
|
|
406
406
|
adId: e.original.id,
|
|
407
|
-
slotId:
|
|
408
|
-
position:
|
|
409
|
-
totalAds:
|
|
407
|
+
slotId: s.slotId,
|
|
408
|
+
position: s.position,
|
|
409
|
+
totalAds: s.totalAds,
|
|
410
410
|
sessionId: m(),
|
|
411
411
|
adTitle: e.adapted.title,
|
|
412
412
|
format: e.original.type,
|
|
413
413
|
source: "internal",
|
|
414
414
|
viewToken: e.tracking.viewToken
|
|
415
|
-
}).then(() => {
|
|
416
|
-
|
|
415
|
+
}, { baseUrl: s.apiBaseUrl }).then(() => {
|
|
416
|
+
n && n(e);
|
|
417
417
|
}).catch((l) => {
|
|
418
418
|
console.error("[DOMRenderer] Analytics impression tracking failed:", l);
|
|
419
|
-
}) :
|
|
419
|
+
}) : n && n(e);
|
|
420
420
|
};
|
|
421
421
|
if (typeof IntersectionObserver < "u") {
|
|
422
422
|
let l = !1, u = null;
|
|
@@ -438,7 +438,7 @@ const I = class I {
|
|
|
438
438
|
* Generate HTML for Suffix Ad variants
|
|
439
439
|
*/
|
|
440
440
|
static generateSuffixAdHTML(e, t) {
|
|
441
|
-
const i = e.adapted.title || "",
|
|
441
|
+
const i = e.adapted.title || "", s = e.adapted.body || "";
|
|
442
442
|
return t === "inline" ? `
|
|
443
443
|
<span class="ax-ad-suffix-link ax-ad-variant-inline" data-ad-id="${e.original.id}">
|
|
444
444
|
${i}
|
|
@@ -461,7 +461,7 @@ const I = class I {
|
|
|
461
461
|
</svg>
|
|
462
462
|
</div>
|
|
463
463
|
</div>
|
|
464
|
-
${
|
|
464
|
+
${s ? `<p class="ax-ad-suffix-body">${s}</p>` : ""}
|
|
465
465
|
</div>
|
|
466
466
|
`;
|
|
467
467
|
}
|
|
@@ -470,10 +470,10 @@ const I = class I {
|
|
|
470
470
|
*/
|
|
471
471
|
static generateSponsoredSourceHTML(e, t) {
|
|
472
472
|
var r;
|
|
473
|
-
const i = e.adapted.title || "",
|
|
473
|
+
const i = e.adapted.title || "", s = e.adapted.body || "", n = ((r = e.adapted.image) == null ? void 0 : r.url) || "";
|
|
474
474
|
return t === "list-item" ? `
|
|
475
475
|
<div class="ax-ad-source ax-ad-variant-list-item" data-ad-id="${e.original.id}">
|
|
476
|
-
${
|
|
476
|
+
${n ? `<img src="${n}" alt="${i}" loading="lazy" />` : ""}
|
|
477
477
|
<div class="ax-ad-source-info">
|
|
478
478
|
<span class="ax-ad-source-name">${i}</span>
|
|
479
479
|
<span class="ax-ad-sponsored-badge" style="font-size:9px">Ad</span>
|
|
@@ -485,20 +485,20 @@ const I = class I {
|
|
|
485
485
|
` : t === "minimal" ? `
|
|
486
486
|
<div data-ad-id="${e.original.id}" style="display:inline-flex">
|
|
487
487
|
<a class="ax-ad-source-link ax-ad-variant-minimal">
|
|
488
|
-
${
|
|
488
|
+
${n ? `<img src="${n}" alt="${i}" loading="lazy" style="width:16px;height:16px;border-radius:2px;object-fit:cover" />` : ""}
|
|
489
489
|
<span>${i}</span>
|
|
490
490
|
<span class="ax-ad-sponsored-badge" style="font-size:9px">Ad</span>
|
|
491
491
|
</a>
|
|
492
492
|
</div>
|
|
493
493
|
` : `
|
|
494
494
|
<div class="ax-ad-source ax-ad-variant-card" data-ad-id="${e.original.id}">
|
|
495
|
-
${
|
|
495
|
+
${n ? `<img src="${n}" alt="${i}" loading="lazy" style="width:48px;height:48px;border-radius:6px;object-fit:cover;flex-shrink:0" />` : ""}
|
|
496
496
|
<div class="ax-ad-source-info">
|
|
497
497
|
<div style="display:flex;align-items:center;gap:8px;margin-bottom:4px">
|
|
498
498
|
<span class="ax-ad-source-name">${i}</span>
|
|
499
499
|
<span class="ax-ad-sponsored-badge">Sponsored</span>
|
|
500
500
|
</div>
|
|
501
|
-
${
|
|
501
|
+
${s ? `<p class="ax-ad-source-desc">${s}</p>` : ""}
|
|
502
502
|
</div>
|
|
503
503
|
<svg width="16" height="16" fill="none" stroke="#d1d5db" viewBox="0 0 24 24" style="flex-shrink:0">
|
|
504
504
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M10 6H6a2 2 0 00-2 2v10a2 2 0 002 2h10a2 2 0 002-2v-4M14 4h6m0 0v6m0-6L10 14" />
|
|
@@ -507,9 +507,9 @@ const I = class I {
|
|
|
507
507
|
`;
|
|
508
508
|
}
|
|
509
509
|
};
|
|
510
|
-
|
|
511
|
-
let y =
|
|
512
|
-
class
|
|
510
|
+
M.trackedImpressionKeys = /* @__PURE__ */ new Set();
|
|
511
|
+
let y = M;
|
|
512
|
+
class $ {
|
|
513
513
|
constructor() {
|
|
514
514
|
this.cachedStaticInfo = null, this.cacheTimestamp = 0, this.CACHE_TTL = 36e5;
|
|
515
515
|
}
|
|
@@ -524,13 +524,13 @@ class T {
|
|
|
524
524
|
name: "Unknown App",
|
|
525
525
|
publisher: { id: "unknown" }
|
|
526
526
|
};
|
|
527
|
-
const e = this.inferBundle(), t = this.inferAppName(), i = this.inferAppVersion(),
|
|
527
|
+
const e = this.inferBundle(), t = this.inferAppName(), i = this.inferAppVersion(), s = this.inferPublisherId();
|
|
528
528
|
return {
|
|
529
529
|
bundle: e,
|
|
530
530
|
ver: i,
|
|
531
531
|
name: t,
|
|
532
532
|
publisher: {
|
|
533
|
-
id:
|
|
533
|
+
id: s,
|
|
534
534
|
domain: window.location.hostname
|
|
535
535
|
}
|
|
536
536
|
};
|
|
@@ -548,14 +548,14 @@ class T {
|
|
|
548
548
|
* 自动推断应用名称
|
|
549
549
|
*/
|
|
550
550
|
inferAppName() {
|
|
551
|
-
var
|
|
551
|
+
var s, n;
|
|
552
552
|
if (typeof document > "u") return "Unknown App";
|
|
553
553
|
const e = document.title;
|
|
554
554
|
if (e && e !== "Loading..." && e.length < 100)
|
|
555
555
|
return e;
|
|
556
|
-
const t = (
|
|
556
|
+
const t = (s = document.querySelector('meta[property="og:title"]')) == null ? void 0 : s.getAttribute("content");
|
|
557
557
|
if (t) return t;
|
|
558
|
-
const i = (
|
|
558
|
+
const i = (n = document.querySelector('meta[name="application-name"]')) == null ? void 0 : n.getAttribute("content");
|
|
559
559
|
return i || "Unknown App";
|
|
560
560
|
}
|
|
561
561
|
/**
|
|
@@ -575,8 +575,8 @@ class T {
|
|
|
575
575
|
if (i) {
|
|
576
576
|
if (t.includes("manifest"))
|
|
577
577
|
return "1.0.0";
|
|
578
|
-
const
|
|
579
|
-
if (
|
|
578
|
+
const s = i.getAttribute("content");
|
|
579
|
+
if (s) return s;
|
|
580
580
|
}
|
|
581
581
|
}
|
|
582
582
|
return "1.0.0";
|
|
@@ -585,18 +585,18 @@ class T {
|
|
|
585
585
|
* 自动推断publisher ID
|
|
586
586
|
*/
|
|
587
587
|
inferPublisherId() {
|
|
588
|
-
var i,
|
|
588
|
+
var i, s;
|
|
589
589
|
if (typeof document > "u") return "unknown";
|
|
590
590
|
const e = (i = document.querySelector('meta[name="publisher-id"]')) == null ? void 0 : i.getAttribute("content");
|
|
591
591
|
if (e) return e;
|
|
592
|
-
const t = (
|
|
592
|
+
const t = (s = window.location) == null ? void 0 : s.hostname;
|
|
593
593
|
return t ? t.replace(/\./g, "_") : "unknown";
|
|
594
594
|
}
|
|
595
595
|
/**
|
|
596
596
|
* Get singleton instance
|
|
597
597
|
*/
|
|
598
598
|
static getInstance() {
|
|
599
|
-
return this.instance || (this.instance = new
|
|
599
|
+
return this.instance || (this.instance = new $()), this.instance;
|
|
600
600
|
}
|
|
601
601
|
/**
|
|
602
602
|
* Collect all available client information
|
|
@@ -718,11 +718,11 @@ class T {
|
|
|
718
718
|
const i = e.match(/Android (\d+)\.(\d+)/);
|
|
719
719
|
if (i)
|
|
720
720
|
return `${i[1]}.${i[2]}`;
|
|
721
|
-
const
|
|
722
|
-
if (
|
|
723
|
-
return
|
|
724
|
-
const
|
|
725
|
-
return
|
|
721
|
+
const s = e.match(/Windows NT (\d+\.\d+)/);
|
|
722
|
+
if (s)
|
|
723
|
+
return s[1];
|
|
724
|
+
const n = e.match(/Mac OS X (\d+[._]\d+)/);
|
|
725
|
+
return n ? n[1].replace("_", ".") : "Unknown";
|
|
726
726
|
}
|
|
727
727
|
/**
|
|
728
728
|
* Detect Device Type (OpenRTB standard)
|
|
@@ -747,10 +747,10 @@ class T {
|
|
|
747
747
|
const i = e.match(/Samsung-.*(SM-\w+)/);
|
|
748
748
|
if (i) return i[1];
|
|
749
749
|
if (/Pixel/.test(e)) return "Google Pixel";
|
|
750
|
-
const
|
|
751
|
-
if (
|
|
752
|
-
const
|
|
753
|
-
if (
|
|
750
|
+
const s = e.match(/(BARC-|HUAWEI-)?([A-Z]{2}\-\w{4})/);
|
|
751
|
+
if (s) return s[2];
|
|
752
|
+
const n = e.match(/(MI|Redmi|POCO)\s([\w\s]+)/);
|
|
753
|
+
if (n) return n[1] + " " + n[2];
|
|
754
754
|
if (/OnePlus/.test(e)) {
|
|
755
755
|
const r = e.match(/OnePlus\s([A-Z\d]+)/);
|
|
756
756
|
return r ? "OnePlus " + r[1] : "OnePlus";
|
|
@@ -866,9 +866,9 @@ class T {
|
|
|
866
866
|
if (t && i[t])
|
|
867
867
|
return i[t];
|
|
868
868
|
if (e) {
|
|
869
|
-
const
|
|
870
|
-
if (
|
|
871
|
-
return
|
|
869
|
+
const s = e.split("-")[1];
|
|
870
|
+
if (s)
|
|
871
|
+
return s.toUpperCase();
|
|
872
872
|
}
|
|
873
873
|
}
|
|
874
874
|
/**
|
|
@@ -899,35 +899,35 @@ class T {
|
|
|
899
899
|
this.cachedStaticInfo = null, this.cacheTimestamp = 0;
|
|
900
900
|
}
|
|
901
901
|
}
|
|
902
|
-
const
|
|
903
|
-
function
|
|
904
|
-
return
|
|
902
|
+
const I = () => $.getInstance();
|
|
903
|
+
function b(o) {
|
|
904
|
+
return I().collect(o);
|
|
905
905
|
}
|
|
906
906
|
function W() {
|
|
907
|
-
return
|
|
907
|
+
return b().device;
|
|
908
908
|
}
|
|
909
909
|
function K() {
|
|
910
|
-
return
|
|
910
|
+
return b().user;
|
|
911
911
|
}
|
|
912
912
|
function Q() {
|
|
913
|
-
return
|
|
913
|
+
return b().app;
|
|
914
914
|
}
|
|
915
915
|
function J() {
|
|
916
|
-
return
|
|
916
|
+
return b().geo;
|
|
917
917
|
}
|
|
918
918
|
function X() {
|
|
919
919
|
return K().id;
|
|
920
920
|
}
|
|
921
921
|
function Z() {
|
|
922
|
-
|
|
922
|
+
I().clearCache();
|
|
923
923
|
}
|
|
924
924
|
function Y(o) {
|
|
925
|
-
const e =
|
|
925
|
+
const e = b(o);
|
|
926
926
|
return JSON.stringify(e, null, 2);
|
|
927
927
|
}
|
|
928
928
|
function ee() {
|
|
929
929
|
var t;
|
|
930
|
-
const o =
|
|
930
|
+
const o = b();
|
|
931
931
|
return [
|
|
932
932
|
o.device.os,
|
|
933
933
|
o.device.osv,
|
|
@@ -964,9 +964,9 @@ function te(o) {
|
|
|
964
964
|
};
|
|
965
965
|
}
|
|
966
966
|
async function R(o, e = {}) {
|
|
967
|
-
const t = e.apiBaseUrl || "/api/v1",
|
|
967
|
+
const t = e.apiBaseUrl || "/api/v1", s = I().collect(), n = {
|
|
968
968
|
...o,
|
|
969
|
-
clientInfo:
|
|
969
|
+
clientInfo: s
|
|
970
970
|
// Auto-injected
|
|
971
971
|
}, r = {
|
|
972
972
|
"Content-Type": "application/json"
|
|
@@ -975,7 +975,7 @@ async function R(o, e = {}) {
|
|
|
975
975
|
const a = await fetch(`${t}/ads/request`, {
|
|
976
976
|
method: "POST",
|
|
977
977
|
headers: r,
|
|
978
|
-
body: JSON.stringify(
|
|
978
|
+
body: JSON.stringify(n)
|
|
979
979
|
});
|
|
980
980
|
if (!a.ok)
|
|
981
981
|
throw new Error(`Ad request failed: ${a.status} ${a.statusText}`);
|
|
@@ -984,16 +984,16 @@ async function R(o, e = {}) {
|
|
|
984
984
|
throw new Error(c.error || "Ad request failed");
|
|
985
985
|
return c.data;
|
|
986
986
|
}
|
|
987
|
-
const N = { width: 400, height: 200 },
|
|
987
|
+
const N = { width: 400, height: 200 }, A = {
|
|
988
988
|
variant: "horizontal",
|
|
989
989
|
count: 1,
|
|
990
990
|
preferences: {}
|
|
991
991
|
};
|
|
992
|
-
function
|
|
992
|
+
function U(o = {}) {
|
|
993
993
|
const e = {
|
|
994
|
-
variant: o.variant ??
|
|
995
|
-
count: o.count ??
|
|
996
|
-
preferences: { ...
|
|
994
|
+
variant: o.variant ?? A.variant,
|
|
995
|
+
count: o.count ?? A.count,
|
|
996
|
+
preferences: { ...A.preferences, ...o.preferences }
|
|
997
997
|
};
|
|
998
998
|
return [
|
|
999
999
|
{
|
|
@@ -1010,7 +1010,7 @@ function C(o = {}) {
|
|
|
1010
1010
|
}
|
|
1011
1011
|
const g = class g {
|
|
1012
1012
|
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
|
|
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 = U(e.cardOption), typeof window < "u" && (window.__AD_CONFIG__ = {
|
|
1014
1014
|
...window.__AD_CONFIG__ || {},
|
|
1015
1015
|
apiKey: e.apiKey,
|
|
1016
1016
|
apiBaseUrl: e.apiBaseUrl
|
|
@@ -1021,15 +1021,15 @@ const g = class g {
|
|
|
1021
1021
|
});
|
|
1022
1022
|
}
|
|
1023
1023
|
async requestAds(e) {
|
|
1024
|
-
const t = "conversationContext" in e ? e : { conversationContext: e }, i = this.buildRequestKey(t),
|
|
1025
|
-
if (
|
|
1026
|
-
return this.config.debug && console.log("[AdManager] Reusing in-flight request for identical context"),
|
|
1024
|
+
const t = "conversationContext" in e ? e : { conversationContext: e }, i = this.buildRequestKey(t), s = g.inFlightRequests.get(i);
|
|
1025
|
+
if (s)
|
|
1026
|
+
return this.config.debug && console.log("[AdManager] Reusing in-flight request for identical context"), s;
|
|
1027
1027
|
if (!this.enabled)
|
|
1028
1028
|
throw this.config.debug && console.warn("[AdManager] Ads are disabled, skipping request"), new Error("Ads are disabled");
|
|
1029
1029
|
if (this.isLoading)
|
|
1030
1030
|
throw this.config.debug && console.warn("[AdManager] Request already in progress"), new Error("Request already in progress");
|
|
1031
1031
|
this.isLoading = !0, this.eventBus.emit("adsLoading"), this.config.debug && console.log("[AdManager] Starting ad request...");
|
|
1032
|
-
const
|
|
1032
|
+
const n = (async () => {
|
|
1033
1033
|
try {
|
|
1034
1034
|
const r = await R(
|
|
1035
1035
|
{
|
|
@@ -1049,7 +1049,8 @@ const g = class g {
|
|
|
1049
1049
|
requestId: r.requestId,
|
|
1050
1050
|
slotId: c.slotId,
|
|
1051
1051
|
position: l,
|
|
1052
|
-
totalAds: c.ads.length
|
|
1052
|
+
totalAds: c.ads.length,
|
|
1053
|
+
apiBaseUrl: this.config.apiBaseUrl
|
|
1053
1054
|
});
|
|
1054
1055
|
});
|
|
1055
1056
|
});
|
|
@@ -1067,7 +1068,7 @@ const g = class g {
|
|
|
1067
1068
|
this.isLoading = !1, g.inFlightRequests.delete(i);
|
|
1068
1069
|
}
|
|
1069
1070
|
})();
|
|
1070
|
-
return g.inFlightRequests.set(i,
|
|
1071
|
+
return g.inFlightRequests.set(i, n), n;
|
|
1071
1072
|
}
|
|
1072
1073
|
buildRequestKey(e) {
|
|
1073
1074
|
return JSON.stringify({
|
|
@@ -1079,16 +1080,16 @@ const g = class g {
|
|
|
1079
1080
|
});
|
|
1080
1081
|
}
|
|
1081
1082
|
render(e, t, i = {}) {
|
|
1082
|
-
const
|
|
1083
|
+
const s = typeof e != "string", n = s ? g.DEFAULT_SLOT_ID : e, r = s ? e : t, a = (s ? t : i) || {};
|
|
1083
1084
|
if (!r)
|
|
1084
1085
|
return this.config.debug && console.warn("[AdManager] Render container is required"), null;
|
|
1085
|
-
const c = this.slots[
|
|
1086
|
+
const c = this.slots[n];
|
|
1086
1087
|
if (!c || !c.ads || c.ads.length === 0)
|
|
1087
|
-
return this.config.debug && console.warn("[AdManager] No ads in slot:",
|
|
1088
|
+
return this.config.debug && console.warn("[AdManager] No ads in slot:", n), null;
|
|
1088
1089
|
const d = a.adIndex ?? 0, l = c.ads[d];
|
|
1089
1090
|
if (!l)
|
|
1090
|
-
return this.config.debug && console.warn(`[AdManager] Ad at index ${d} not found in slot:`,
|
|
1091
|
-
const u = this.adsAnalyticsMap.get(l.original.id), f = this.slots_config.find((w) => w.slotId ===
|
|
1091
|
+
return this.config.debug && console.warn(`[AdManager] Ad at index ${d} not found in slot:`, n), null;
|
|
1092
|
+
const u = this.adsAnalyticsMap.get(l.original.id), f = this.slots_config.find((w) => w.slotId === n), p = (f == null ? void 0 : f.format) || "action_card";
|
|
1092
1093
|
r.innerHTML = "";
|
|
1093
1094
|
const h = {
|
|
1094
1095
|
analytics: u,
|
|
@@ -1135,7 +1136,7 @@ const g = class g {
|
|
|
1135
1136
|
* Update configuration
|
|
1136
1137
|
*/
|
|
1137
1138
|
updateConfig(e) {
|
|
1138
|
-
this.config = { ...this.config, ...e }, e.cardOption !== void 0 && (this.slots_config =
|
|
1139
|
+
this.config = { ...this.config, ...e }, e.cardOption !== void 0 && (this.slots_config = U(this.config.cardOption)), this.config.debug && console.log("[AdManager] Config updated:", e);
|
|
1139
1140
|
}
|
|
1140
1141
|
/**
|
|
1141
1142
|
* Clear all slot data
|
|
@@ -1179,28 +1180,28 @@ const g = class g {
|
|
|
1179
1180
|
getAdsAnalytics(e) {
|
|
1180
1181
|
const t = /* @__PURE__ */ new Map();
|
|
1181
1182
|
return e.forEach((i) => {
|
|
1182
|
-
const
|
|
1183
|
-
|
|
1183
|
+
const s = this.adsAnalyticsMap.get(i);
|
|
1184
|
+
s && t.set(i, s);
|
|
1184
1185
|
}), t;
|
|
1185
1186
|
}
|
|
1186
1187
|
/**
|
|
1187
1188
|
* Track ad click using Analytics API
|
|
1188
1189
|
*/
|
|
1189
1190
|
async trackAdClick(e, t, i) {
|
|
1190
|
-
const
|
|
1191
|
-
if (!
|
|
1191
|
+
const s = this.adsAnalyticsMap.get(e);
|
|
1192
|
+
if (!s || !this.currentRequestId)
|
|
1192
1193
|
return this.config.debug && console.warn("[AdManager] No analytics info for ad:", e), null;
|
|
1193
|
-
const
|
|
1194
|
+
const n = m(), r = await T({
|
|
1194
1195
|
requestId: this.currentRequestId,
|
|
1195
1196
|
adId: e,
|
|
1196
1197
|
destinationUrl: t,
|
|
1197
|
-
sessionId:
|
|
1198
|
-
slotId:
|
|
1198
|
+
sessionId: n,
|
|
1199
|
+
slotId: s.slotId,
|
|
1199
1200
|
adTitle: i == null ? void 0 : i.title,
|
|
1200
1201
|
format: i == null ? void 0 : i.format,
|
|
1201
1202
|
source: i == null ? void 0 : i.source
|
|
1202
|
-
});
|
|
1203
|
-
return r && (this.eventBus.emit("adClicked", e,
|
|
1203
|
+
}, { baseUrl: s.apiBaseUrl });
|
|
1204
|
+
return r && (this.eventBus.emit("adClicked", e, s.slotId), this.config.debug && console.log("[AdManager] Click tracked via Analytics API:", r.eventId)), r;
|
|
1204
1205
|
}
|
|
1205
1206
|
/**
|
|
1206
1207
|
* Track ad impression using Analytics API
|
|
@@ -1209,19 +1210,19 @@ const g = class g {
|
|
|
1209
1210
|
const i = this.adsAnalyticsMap.get(e);
|
|
1210
1211
|
if (!i || !this.currentRequestId)
|
|
1211
1212
|
return this.config.debug && console.warn("[AdManager] No analytics info for ad:", e), null;
|
|
1212
|
-
const
|
|
1213
|
+
const s = m(), n = await S({
|
|
1213
1214
|
requestId: this.currentRequestId,
|
|
1214
1215
|
adId: e,
|
|
1215
1216
|
slotId: i.slotId,
|
|
1216
1217
|
position: i.position,
|
|
1217
1218
|
totalAds: i.totalAds,
|
|
1218
|
-
sessionId:
|
|
1219
|
+
sessionId: s,
|
|
1219
1220
|
adTitle: t == null ? void 0 : t.title,
|
|
1220
1221
|
format: t == null ? void 0 : t.format,
|
|
1221
1222
|
source: t == null ? void 0 : t.source,
|
|
1222
1223
|
viewToken: t == null ? void 0 : t.viewToken
|
|
1223
|
-
});
|
|
1224
|
-
return
|
|
1224
|
+
}, { baseUrl: i.apiBaseUrl });
|
|
1225
|
+
return n && (this.eventBus.emit("adImpression", e, i.slotId), this.config.debug && console.log("[AdManager] Impression tracked via Analytics API:", n.eventId)), n;
|
|
1225
1226
|
}
|
|
1226
1227
|
/**
|
|
1227
1228
|
* Destroy the manager and clean up
|
|
@@ -1241,14 +1242,14 @@ function E() {
|
|
|
1241
1242
|
}
|
|
1242
1243
|
class H {
|
|
1243
1244
|
constructor(e = {}, t = "/api/v1") {
|
|
1244
|
-
var i,
|
|
1245
|
+
var i, s;
|
|
1245
1246
|
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 = {
|
|
1246
1247
|
minVisiblePercentage: e.minVisiblePercentage ?? 50,
|
|
1247
1248
|
minViewableDuration: e.minViewableDuration ?? 1e3,
|
|
1248
1249
|
maxTrackingDuration: e.maxTrackingDuration ?? 6e4,
|
|
1249
1250
|
batchConfig: {
|
|
1250
1251
|
maxBatchSize: ((i = e.batchConfig) == null ? void 0 : i.maxBatchSize) ?? 5,
|
|
1251
|
-
maxBatchWaitMs: ((
|
|
1252
|
+
maxBatchWaitMs: ((s = e.batchConfig) == null ? void 0 : s.maxBatchWaitMs) ?? 1e4
|
|
1252
1253
|
},
|
|
1253
1254
|
debug: e.debug ?? !1
|
|
1254
1255
|
}, this.baseUrl = t;
|
|
@@ -1256,7 +1257,7 @@ class H {
|
|
|
1256
1257
|
/**
|
|
1257
1258
|
* Start tracking viewability for an ad element
|
|
1258
1259
|
*/
|
|
1259
|
-
startTracking(e, t, i,
|
|
1260
|
+
startTracking(e, t, i, s, n) {
|
|
1260
1261
|
if (this.isTracking.get(e)) {
|
|
1261
1262
|
this.log(`[ViewabilityTracker] Already tracking ${e}, skipping`);
|
|
1262
1263
|
return;
|
|
@@ -1274,14 +1275,14 @@ class H {
|
|
|
1274
1275
|
};
|
|
1275
1276
|
this.metrics.set(e, r), this.isTracking.set(e, !0), this.eventQueue.set(e, []);
|
|
1276
1277
|
const a = new IntersectionObserver(
|
|
1277
|
-
(d) => this.handleIntersection(e, d[0], i,
|
|
1278
|
+
(d) => this.handleIntersection(e, d[0], i, s, n),
|
|
1278
1279
|
{
|
|
1279
1280
|
threshold: this.createThresholds()
|
|
1280
1281
|
}
|
|
1281
1282
|
);
|
|
1282
|
-
a.observe(t), this.observers.set(e, a), this.startMonitoring(e, i,
|
|
1283
|
+
a.observe(t), this.observers.set(e, a), this.startMonitoring(e, i, s, n);
|
|
1283
1284
|
const c = setTimeout(() => {
|
|
1284
|
-
this.endTracking(e, i,
|
|
1285
|
+
this.endTracking(e, i, s, n);
|
|
1285
1286
|
}, this.config.maxTrackingDuration);
|
|
1286
1287
|
this.timers.set(e, c);
|
|
1287
1288
|
}
|
|
@@ -1301,7 +1302,7 @@ class H {
|
|
|
1301
1302
|
* Handle IntersectionObserver callback
|
|
1302
1303
|
* Event-driven: Only process when state actually changes
|
|
1303
1304
|
*/
|
|
1304
|
-
handleIntersection(e, t, i,
|
|
1305
|
+
handleIntersection(e, t, i, s, n) {
|
|
1305
1306
|
const r = this.metrics.get(e);
|
|
1306
1307
|
if (!r || !this.isTracking.get(e)) return;
|
|
1307
1308
|
const a = r.isViewable, c = Math.round(t.intersectionRatio * 100);
|
|
@@ -1310,8 +1311,8 @@ class H {
|
|
|
1310
1311
|
if (l && !r.enteredViewportAt && (r.enteredViewportAt = d, r.enterCount++, this.log(`[ViewabilityTracker] ${e} entered viewport at ${d}`), this.queueEvent(e, {
|
|
1311
1312
|
adId: e,
|
|
1312
1313
|
sessionId: i,
|
|
1313
|
-
requestId:
|
|
1314
|
-
viewToken:
|
|
1314
|
+
requestId: s,
|
|
1315
|
+
viewToken: n,
|
|
1315
1316
|
eventType: "enter_viewport",
|
|
1316
1317
|
visiblePercentage: c,
|
|
1317
1318
|
maxVisiblePercentage: r.maxVisiblePercentage,
|
|
@@ -1323,8 +1324,8 @@ class H {
|
|
|
1323
1324
|
r.totalVisibleTimeMs += u, r.enteredViewportAt = null, r.currentVisibleTimeMs = 0, this.log(`[ViewabilityTracker] ${e} exited viewport, total visible: ${r.totalVisibleTimeMs}ms`), this.queueEvent(e, {
|
|
1324
1325
|
adId: e,
|
|
1325
1326
|
sessionId: i,
|
|
1326
|
-
requestId:
|
|
1327
|
-
viewToken:
|
|
1327
|
+
requestId: s,
|
|
1328
|
+
viewToken: n,
|
|
1328
1329
|
eventType: "exit_viewport",
|
|
1329
1330
|
visiblePercentage: c,
|
|
1330
1331
|
maxVisiblePercentage: r.maxVisiblePercentage,
|
|
@@ -1339,7 +1340,7 @@ class H {
|
|
|
1339
1340
|
* Start monitoring loop for tracking duration
|
|
1340
1341
|
* Runs every 100ms to track continuous visible time
|
|
1341
1342
|
*/
|
|
1342
|
-
startMonitoring(e, t, i,
|
|
1343
|
+
startMonitoring(e, t, i, s) {
|
|
1343
1344
|
const r = setInterval(() => {
|
|
1344
1345
|
const a = this.metrics.get(e);
|
|
1345
1346
|
if (!a || !this.isTracking.get(e)) {
|
|
@@ -1353,7 +1354,7 @@ class H {
|
|
|
1353
1354
|
adId: e,
|
|
1354
1355
|
sessionId: t,
|
|
1355
1356
|
requestId: i,
|
|
1356
|
-
viewToken:
|
|
1357
|
+
viewToken: s,
|
|
1357
1358
|
eventType: "become_viewable",
|
|
1358
1359
|
visiblePercentage: a.visiblePercentage,
|
|
1359
1360
|
maxVisiblePercentage: a.maxVisiblePercentage,
|
|
@@ -1370,15 +1371,15 @@ class H {
|
|
|
1370
1371
|
* Queue an event to be sent (batched)
|
|
1371
1372
|
*/
|
|
1372
1373
|
queueEvent(e, t) {
|
|
1373
|
-
var
|
|
1374
|
+
var n, r;
|
|
1374
1375
|
const i = this.eventQueue.get(e);
|
|
1375
1376
|
if (!i) {
|
|
1376
1377
|
this.log(`[ViewabilityTracker] No queue found for ${e}, skipping event`);
|
|
1377
1378
|
return;
|
|
1378
1379
|
}
|
|
1379
1380
|
i.push(t), this.log(`[ViewabilityTracker] Queued ${t.eventType} for ${e} (queue size: ${i.length})`);
|
|
1380
|
-
const
|
|
1381
|
-
if (i.length >=
|
|
1381
|
+
const s = ((n = this.config.batchConfig) == null ? void 0 : n.maxBatchSize) ?? 5;
|
|
1382
|
+
if (i.length >= s)
|
|
1382
1383
|
this.flushQueue(e);
|
|
1383
1384
|
else {
|
|
1384
1385
|
const a = this.batchTimers.get(e);
|
|
@@ -1398,36 +1399,36 @@ class H {
|
|
|
1398
1399
|
const i = [...t];
|
|
1399
1400
|
t.length = 0, this.log(`[ViewabilityTracker] Flushing ${i.length} events for ${e}`);
|
|
1400
1401
|
try {
|
|
1401
|
-
const
|
|
1402
|
+
const s = {
|
|
1402
1403
|
"Content-Type": "application/json"
|
|
1403
|
-
},
|
|
1404
|
-
|
|
1404
|
+
}, n = E();
|
|
1405
|
+
n && (s["x-api-key"] = n), await fetch(`${this.baseUrl}/ads/viewability/batch`, {
|
|
1405
1406
|
method: "POST",
|
|
1406
|
-
headers:
|
|
1407
|
+
headers: s,
|
|
1407
1408
|
body: JSON.stringify({ events: i })
|
|
1408
1409
|
}), this.log(`[ViewabilityTracker] Successfully sent ${i.length} events for ${e}`);
|
|
1409
|
-
} catch (
|
|
1410
|
-
this.log(`[ViewabilityTracker] Failed to send events for ${e}:`,
|
|
1410
|
+
} catch (s) {
|
|
1411
|
+
this.log(`[ViewabilityTracker] Failed to send events for ${e}:`, s), t.unshift(...i);
|
|
1411
1412
|
}
|
|
1412
1413
|
}
|
|
1413
1414
|
/**
|
|
1414
1415
|
* End tracking and send final metrics
|
|
1415
1416
|
*/
|
|
1416
|
-
endTracking(e, t, i,
|
|
1417
|
-
const
|
|
1418
|
-
if (!
|
|
1417
|
+
endTracking(e, t, i, s) {
|
|
1418
|
+
const n = this.metrics.get(e);
|
|
1419
|
+
if (!n) return;
|
|
1419
1420
|
this.log(`[ViewabilityTracker] Ending tracking for ${e}`), this.flushQueue(e);
|
|
1420
1421
|
const r = Date.now();
|
|
1421
1422
|
this.queueEvent(e, {
|
|
1422
1423
|
adId: e,
|
|
1423
1424
|
sessionId: t,
|
|
1424
1425
|
requestId: i,
|
|
1425
|
-
viewToken:
|
|
1426
|
+
viewToken: s,
|
|
1426
1427
|
eventType: "end_tracking",
|
|
1427
|
-
visiblePercentage:
|
|
1428
|
-
maxVisiblePercentage:
|
|
1429
|
-
totalVisibleTimeMs:
|
|
1430
|
-
isViewable:
|
|
1428
|
+
visiblePercentage: n.visiblePercentage,
|
|
1429
|
+
maxVisiblePercentage: n.maxVisiblePercentage,
|
|
1430
|
+
totalVisibleTimeMs: n.totalVisibleTimeMs,
|
|
1431
|
+
isViewable: n.isViewable,
|
|
1431
1432
|
timestamp: r
|
|
1432
1433
|
}), this.flushQueue(e), this.cleanup(e);
|
|
1433
1434
|
}
|
|
@@ -1439,10 +1440,10 @@ class H {
|
|
|
1439
1440
|
t && (t.disconnect(), this.observers.delete(e));
|
|
1440
1441
|
const i = this.timers.get(e);
|
|
1441
1442
|
i && (clearTimeout(i), this.timers.delete(e));
|
|
1442
|
-
const
|
|
1443
|
-
|
|
1444
|
-
const
|
|
1445
|
-
|
|
1443
|
+
const s = this.timers.get(`${e}_monitoring`);
|
|
1444
|
+
s && (clearInterval(s), this.timers.delete(`${e}_monitoring`));
|
|
1445
|
+
const n = this.batchTimers.get(e);
|
|
1446
|
+
n && (clearTimeout(n), this.batchTimers.delete(e)), this.flushQueue(e), this.isTracking.delete(e), this.metrics.delete(e), this.eventQueue.delete(e);
|
|
1446
1447
|
}
|
|
1447
1448
|
/**
|
|
1448
1449
|
* Create thresholds for IntersectionObserver
|
|
@@ -1474,8 +1475,8 @@ class H {
|
|
|
1474
1475
|
if (t && t.length > 0) {
|
|
1475
1476
|
const i = {
|
|
1476
1477
|
"Content-Type": "application/json"
|
|
1477
|
-
},
|
|
1478
|
-
|
|
1478
|
+
}, s = E();
|
|
1479
|
+
s && (i["x-api-key"] = s), fetch(`${this.baseUrl}/ads/viewability/batch`, {
|
|
1479
1480
|
method: "POST",
|
|
1480
1481
|
headers: i,
|
|
1481
1482
|
keepalive: !0,
|
|
@@ -1490,14 +1491,14 @@ let k = null;
|
|
|
1490
1491
|
function ie(o, e) {
|
|
1491
1492
|
return k || (k = new H(o, e), k.setupBeforeUnload()), k;
|
|
1492
1493
|
}
|
|
1493
|
-
const
|
|
1494
|
+
const se = "0.1.0";
|
|
1494
1495
|
export {
|
|
1495
1496
|
V as AdManager,
|
|
1496
|
-
|
|
1497
|
-
|
|
1497
|
+
x as AnalyticsSender,
|
|
1498
|
+
$ as ClientInfoCollector,
|
|
1498
1499
|
y as DOMRenderer,
|
|
1499
|
-
|
|
1500
|
-
|
|
1500
|
+
v as HTMLRenderer,
|
|
1501
|
+
se as SDK_VERSION,
|
|
1501
1502
|
_ as SessionManager,
|
|
1502
1503
|
H as ViewabilityTracker,
|
|
1503
1504
|
te as adaptAdToKoahAd,
|
|
@@ -1507,8 +1508,8 @@ export {
|
|
|
1507
1508
|
R as fetchAds,
|
|
1508
1509
|
F as generateViewToken,
|
|
1509
1510
|
Q as getAppInfo,
|
|
1510
|
-
|
|
1511
|
-
|
|
1511
|
+
b as getClientInfo,
|
|
1512
|
+
I as getClientInfoCollector,
|
|
1512
1513
|
Y as getClientInfoJSON,
|
|
1513
1514
|
ee as getClientInfoSummary,
|
|
1514
1515
|
W as getDeviceInfo,
|
|
@@ -1517,8 +1518,8 @@ export {
|
|
|
1517
1518
|
X as getUserId,
|
|
1518
1519
|
K as getUserInfo,
|
|
1519
1520
|
ie as getViewabilityTracker,
|
|
1520
|
-
|
|
1521
|
-
|
|
1521
|
+
T as trackAdClick,
|
|
1522
|
+
S as trackAdImpression,
|
|
1522
1523
|
D as trackClicksBatch,
|
|
1523
1524
|
G as trackImpressionsBatch
|
|
1524
1525
|
};
|