@action-x/ad-sdk 0.1.6 → 0.1.8
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 +9 -13
- package/dist/index.d.ts +6 -5
- package/dist/index.js +200 -192
- package/dist/index.umd.js +10 -14
- package/dist/style.css +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
class
|
|
1
|
+
class O {
|
|
2
2
|
constructor() {
|
|
3
3
|
this.events = {};
|
|
4
4
|
}
|
|
@@ -60,25 +60,21 @@ class w {
|
|
|
60
60
|
* @returns HTML string
|
|
61
61
|
*/
|
|
62
62
|
static renderActionCard(e, t = {}) {
|
|
63
|
-
var
|
|
64
|
-
const { variant: i = "horizontal", includeWrapper: s = !0 } = t, n = e.adapted,
|
|
63
|
+
var f;
|
|
64
|
+
const { variant: i = "horizontal", includeWrapper: s = !0 } = t, n = e.adapted, r = this.getClickUrl(e), a = this.getImpressionUrl(e), c = s ? `<div class="ax-ad-card ax-ad-card-${i}" data-ad-id="${e.original.id}">` : "", d = (f = n.image) != null && f.url ? `<img
|
|
65
65
|
src="${n.image.url}"
|
|
66
66
|
alt="${n.title}"
|
|
67
67
|
class="ax-ad-image"
|
|
68
68
|
loading="lazy"
|
|
69
|
-
/>` : "",
|
|
70
|
-
|
|
71
|
-
</div>` : "", h = n.brand ? `<span class="ax-ad-brand">${n.brand}</span>` : "", p = `
|
|
72
|
-
${l}
|
|
69
|
+
/>` : "", l = (n.brand || "").trim(), u = l && l.toLowerCase() !== "unknown" ? `<span class="ax-ad-brand">${n.brand}</span>` : "", h = `
|
|
70
|
+
${d}
|
|
73
71
|
<div class="ax-ad-content">
|
|
74
|
-
${
|
|
72
|
+
${u}
|
|
75
73
|
<h3 class="ax-ad-title">${n.title}</h3>
|
|
76
74
|
${n.body ? `<p class="ax-ad-body">${n.body}</p>` : ""}
|
|
77
|
-
${u}
|
|
78
75
|
<div class="ax-ad-footer">
|
|
79
|
-
${d}
|
|
80
76
|
<a
|
|
81
|
-
href="${
|
|
77
|
+
href="${r}"
|
|
82
78
|
class="ax-ad-cta"
|
|
83
79
|
target="_blank"
|
|
84
80
|
rel="sponsored noopener noreferrer"
|
|
@@ -89,8 +85,8 @@ class w {
|
|
|
89
85
|
</a>
|
|
90
86
|
</div>
|
|
91
87
|
</div>
|
|
92
|
-
`,
|
|
93
|
-
return c +
|
|
88
|
+
`, p = s ? "</div>" : "";
|
|
89
|
+
return c + h + p;
|
|
94
90
|
}
|
|
95
91
|
/**
|
|
96
92
|
* Render Suffix ad as HTML string
|
|
@@ -190,17 +186,17 @@ class w {
|
|
|
190
186
|
const q = "ad_session_id";
|
|
191
187
|
function L() {
|
|
192
188
|
if (typeof window < "u") {
|
|
193
|
-
const
|
|
194
|
-
if (
|
|
195
|
-
return
|
|
189
|
+
const o = window.__AD_CONFIG__;
|
|
190
|
+
if (o != null && o.apiKey)
|
|
191
|
+
return o.apiKey;
|
|
196
192
|
}
|
|
197
193
|
}
|
|
198
194
|
function R() {
|
|
199
|
-
var
|
|
200
|
-
return typeof window < "u" ? !!((
|
|
195
|
+
var o;
|
|
196
|
+
return typeof window < "u" ? !!((o = window.__AD_CONFIG__) != null && o.debug) : !1;
|
|
201
197
|
}
|
|
202
|
-
function U(
|
|
203
|
-
if (
|
|
198
|
+
function U(o) {
|
|
199
|
+
if (o) return o;
|
|
204
200
|
if (typeof window < "u") {
|
|
205
201
|
const e = window.__AD_CONFIG__;
|
|
206
202
|
if (e != null && e.apiBaseUrl)
|
|
@@ -244,7 +240,7 @@ class P {
|
|
|
244
240
|
this.storage === "sessionStorage" ? sessionStorage.removeItem(this.sessionKey) : this.memoryCache.delete(this.sessionKey);
|
|
245
241
|
}
|
|
246
242
|
}
|
|
247
|
-
const K = new P(),
|
|
243
|
+
const K = new P(), m = () => K.getSessionId();
|
|
248
244
|
class x {
|
|
249
245
|
constructor(e = {}) {
|
|
250
246
|
this.explicitBaseUrl = e.baseUrl, this.timeout = e.timeout || 1e4, this.retryAttempts = e.retryAttempts ?? 2, this.retryDelay = e.retryDelay || 1e3, this.debug = e.debug || !1;
|
|
@@ -276,16 +272,16 @@ class x {
|
|
|
276
272
|
async sendRequest(e, t, i) {
|
|
277
273
|
let s = null;
|
|
278
274
|
for (let n = 0; n <= this.retryAttempts; n++) {
|
|
279
|
-
const
|
|
275
|
+
const r = this.debug || R();
|
|
280
276
|
try {
|
|
281
|
-
|
|
282
|
-
const a = new AbortController(), c = setTimeout(() => a.abort(), this.timeout),
|
|
277
|
+
r && (console.log(`[Analytics] Request URL (${i}):`, e), console.log(`[Analytics] Sending ${i} event (attempt ${n + 1}):`, t));
|
|
278
|
+
const a = new AbortController(), c = setTimeout(() => a.abort(), this.timeout), d = {
|
|
283
279
|
"Content-Type": "application/json"
|
|
284
|
-
},
|
|
285
|
-
|
|
280
|
+
}, l = L();
|
|
281
|
+
l && (d["X-API-Key"] = l, r && console.log(`[Analytics] Adding X-API-Key header for ${i} event`));
|
|
286
282
|
const u = await fetch(e, {
|
|
287
283
|
method: "POST",
|
|
288
|
-
headers:
|
|
284
|
+
headers: d,
|
|
289
285
|
body: JSON.stringify(t),
|
|
290
286
|
keepalive: !0,
|
|
291
287
|
signal: a.signal
|
|
@@ -293,9 +289,9 @@ class x {
|
|
|
293
289
|
if (clearTimeout(c), !u.ok)
|
|
294
290
|
throw new Error(`HTTP ${u.status}: ${u.statusText}`);
|
|
295
291
|
const h = await u.json();
|
|
296
|
-
return
|
|
292
|
+
return r && console.log(`[Analytics] ${i} event tracked successfully:`, h), h;
|
|
297
293
|
} catch (a) {
|
|
298
|
-
s = a,
|
|
294
|
+
s = a, r && console.warn(`[Analytics] ${i} tracking failed (attempt ${n + 1}):`, a), n < this.retryAttempts && await this.delay(this.retryDelay * (n + 1));
|
|
299
295
|
}
|
|
300
296
|
}
|
|
301
297
|
return console.error(`[Analytics] ${i} tracking failed after ${this.retryAttempts + 1} attempts:`, s), null;
|
|
@@ -307,25 +303,25 @@ class x {
|
|
|
307
303
|
return new Promise((t) => setTimeout(t, e));
|
|
308
304
|
}
|
|
309
305
|
}
|
|
310
|
-
const
|
|
311
|
-
function
|
|
312
|
-
return `vt_${
|
|
306
|
+
const B = new x(), I = (o, e) => e != null && e.baseUrl ? new x({ baseUrl: e.baseUrl }).trackImpression(o) : B.trackImpression(o), T = (o, e) => e != null && e.baseUrl ? new x({ baseUrl: e.baseUrl }).trackClick(o) : B.trackClick(o);
|
|
307
|
+
function z(o, e) {
|
|
308
|
+
return `vt_${o}_${e}`;
|
|
313
309
|
}
|
|
314
|
-
async function j(
|
|
315
|
-
return Promise.all(
|
|
310
|
+
async function j(o) {
|
|
311
|
+
return Promise.all(o.map((e) => I(e)));
|
|
316
312
|
}
|
|
317
|
-
async function
|
|
318
|
-
return Promise.all(
|
|
313
|
+
async function W(o) {
|
|
314
|
+
return Promise.all(o.map((e) => T(e)));
|
|
319
315
|
}
|
|
320
|
-
function
|
|
321
|
-
const e = new x(
|
|
316
|
+
function Q(o) {
|
|
317
|
+
const e = new x(o);
|
|
322
318
|
return {
|
|
323
319
|
trackImpression: (t) => e.trackImpression(t),
|
|
324
320
|
trackClick: (t) => e.trackClick(t)
|
|
325
321
|
};
|
|
326
322
|
}
|
|
327
|
-
function
|
|
328
|
-
const e = new P(
|
|
323
|
+
function J(o = {}) {
|
|
324
|
+
const e = new P(o);
|
|
329
325
|
return {
|
|
330
326
|
getSessionId: () => e.getSessionId(),
|
|
331
327
|
regenerateSessionId: () => e.regenerateSessionId(),
|
|
@@ -360,8 +356,8 @@ const C = class C {
|
|
|
360
356
|
const s = i.variant || "block";
|
|
361
357
|
t.innerHTML = this.generateSuffixAdHTML(e, s);
|
|
362
358
|
const n = t.querySelector(".ax-ad-suffix-link");
|
|
363
|
-
return n && n.addEventListener("click", (
|
|
364
|
-
|
|
359
|
+
return n && n.addEventListener("click", (r) => {
|
|
360
|
+
r.preventDefault(), this.handleClick(e, i);
|
|
365
361
|
}), this.trackImpression(e, t, i), t;
|
|
366
362
|
}
|
|
367
363
|
/**
|
|
@@ -371,8 +367,8 @@ const C = class C {
|
|
|
371
367
|
const s = i.variant || "card";
|
|
372
368
|
t.innerHTML = this.generateSponsoredSourceHTML(e, s);
|
|
373
369
|
const n = t.querySelector(".ax-ad-source-link");
|
|
374
|
-
return n && n.addEventListener("click", (
|
|
375
|
-
|
|
370
|
+
return n && n.addEventListener("click", (r) => {
|
|
371
|
+
r.preventDefault(), this.handleClick(e, i);
|
|
376
372
|
}), this.trackImpression(e, t, i), t;
|
|
377
373
|
}
|
|
378
374
|
/**
|
|
@@ -391,9 +387,9 @@ const C = class C {
|
|
|
391
387
|
static renderAds(e, t, i = this.renderActionCard.bind(this), s) {
|
|
392
388
|
t.innerHTML = "";
|
|
393
389
|
const n = document.createElement("div");
|
|
394
|
-
return n.className = "ax-ads-container", e.forEach((
|
|
390
|
+
return n.className = "ax-ads-container", e.forEach((r) => {
|
|
395
391
|
const a = document.createElement("div");
|
|
396
|
-
a.className = "ax-ad-wrapper", i.call(this,
|
|
392
|
+
a.className = "ax-ad-wrapper", i.call(this, r, a, s), n.appendChild(a);
|
|
397
393
|
}), t.appendChild(n), t;
|
|
398
394
|
}
|
|
399
395
|
/**
|
|
@@ -411,12 +407,12 @@ const C = class C {
|
|
|
411
407
|
adId: e.original.id,
|
|
412
408
|
destinationUrl: n,
|
|
413
409
|
slotId: i.slotId,
|
|
414
|
-
sessionId:
|
|
410
|
+
sessionId: m(),
|
|
415
411
|
adTitle: e.adapted.title,
|
|
416
412
|
format: e.original.type,
|
|
417
413
|
userId: i.userId
|
|
418
|
-
}, { baseUrl: i.apiBaseUrl }).catch((
|
|
419
|
-
console.error("[DOMRenderer] Analytics click tracking failed:",
|
|
414
|
+
}, { baseUrl: i.apiBaseUrl }).catch((r) => {
|
|
415
|
+
console.error("[DOMRenderer] Analytics click tracking failed:", r);
|
|
420
416
|
}), this.isDebugEnabled() && console.log("[DOMRenderer] Redirect URL:", n), window.open(n, "_blank", "noopener,noreferrer");
|
|
421
417
|
}
|
|
422
418
|
/**
|
|
@@ -424,20 +420,20 @@ const C = class C {
|
|
|
424
420
|
* Falls back to immediate tracking if IntersectionObserver is unavailable.
|
|
425
421
|
*/
|
|
426
422
|
static trackImpression(e, t, i) {
|
|
427
|
-
const { analytics: s, onImpression: n } = i,
|
|
428
|
-
if (this.trackedImpressionKeys.has(
|
|
423
|
+
const { analytics: s, onImpression: n } = i, r = s ? `${s.requestId}:${s.slotId}:${e.original.id}:${this.getViewToken(e) || ""}` : `no-analytics:${e.original.id}:${this.getViewToken(e) || ""}`;
|
|
424
|
+
if (this.trackedImpressionKeys.has(r))
|
|
429
425
|
return;
|
|
430
426
|
let a = !1;
|
|
431
427
|
const c = () => {
|
|
432
|
-
a || this.trackedImpressionKeys.has(
|
|
433
|
-
},
|
|
428
|
+
a || this.trackedImpressionKeys.has(r) || (a = !0, this.trackedImpressionKeys.add(r), d());
|
|
429
|
+
}, d = () => {
|
|
434
430
|
s ? I({
|
|
435
431
|
requestId: s.requestId,
|
|
436
432
|
adId: e.original.id,
|
|
437
433
|
slotId: s.slotId,
|
|
438
434
|
position: s.position,
|
|
439
435
|
totalAds: s.totalAds,
|
|
440
|
-
sessionId:
|
|
436
|
+
sessionId: m(),
|
|
441
437
|
adTitle: e.adapted.title,
|
|
442
438
|
format: e.original.type,
|
|
443
439
|
source: "internal",
|
|
@@ -445,17 +441,17 @@ const C = class C {
|
|
|
445
441
|
userId: s.userId
|
|
446
442
|
}, { baseUrl: s.apiBaseUrl }).then(() => {
|
|
447
443
|
n && n(e);
|
|
448
|
-
}).catch((
|
|
449
|
-
console.error("[DOMRenderer] Analytics impression tracking failed:",
|
|
444
|
+
}).catch((l) => {
|
|
445
|
+
console.error("[DOMRenderer] Analytics impression tracking failed:", l);
|
|
450
446
|
}) : n && n(e);
|
|
451
447
|
};
|
|
452
448
|
if (typeof IntersectionObserver < "u") {
|
|
453
|
-
let
|
|
449
|
+
let l = !1, u = null;
|
|
454
450
|
const h = new IntersectionObserver(
|
|
455
451
|
(f) => {
|
|
456
|
-
f.forEach((
|
|
457
|
-
|
|
458
|
-
u = null,
|
|
452
|
+
f.forEach((v) => {
|
|
453
|
+
l = v.isIntersecting && v.intersectionRatio >= 0.5, l ? u || (u = setTimeout(() => {
|
|
454
|
+
u = null, l && (c(), h.disconnect());
|
|
459
455
|
}, 1e3)) : u && (clearTimeout(u), u = null);
|
|
460
456
|
});
|
|
461
457
|
},
|
|
@@ -500,8 +496,8 @@ const C = class C {
|
|
|
500
496
|
* Generate HTML for Sponsored Source Ad variants
|
|
501
497
|
*/
|
|
502
498
|
static generateSponsoredSourceHTML(e, t) {
|
|
503
|
-
var
|
|
504
|
-
const i = e.adapted.title || "", s = e.adapted.body || "", n = ((
|
|
499
|
+
var r;
|
|
500
|
+
const i = e.adapted.title || "", s = e.adapted.body || "", n = ((r = e.adapted.image) == null ? void 0 : r.url) || "";
|
|
505
501
|
return t === "list-item" ? `
|
|
506
502
|
<div class="ax-ad-source ax-ad-variant-list-item" data-ad-id="${e.original.id}">
|
|
507
503
|
${n ? `<img src="${n}" alt="${i}" loading="lazy" />` : ""}
|
|
@@ -539,7 +535,7 @@ const C = class C {
|
|
|
539
535
|
}
|
|
540
536
|
};
|
|
541
537
|
C.trackedImpressionKeys = /* @__PURE__ */ new Set();
|
|
542
|
-
let
|
|
538
|
+
let y = C;
|
|
543
539
|
class S {
|
|
544
540
|
constructor() {
|
|
545
541
|
this.cachedStaticInfo = null, this.cacheTimestamp = 0, this.CACHE_TTL = 36e5;
|
|
@@ -783,8 +779,8 @@ class S {
|
|
|
783
779
|
const n = e.match(/(MI|Redmi|POCO)\s([\w\s]+)/);
|
|
784
780
|
if (n) return n[1] + " " + n[2];
|
|
785
781
|
if (/OnePlus/.test(e)) {
|
|
786
|
-
const
|
|
787
|
-
return
|
|
782
|
+
const r = e.match(/OnePlus\s([A-Z\d]+)/);
|
|
783
|
+
return r ? "OnePlus " + r[1] : "OnePlus";
|
|
788
784
|
}
|
|
789
785
|
}
|
|
790
786
|
/**
|
|
@@ -931,85 +927,85 @@ class S {
|
|
|
931
927
|
}
|
|
932
928
|
}
|
|
933
929
|
const $ = () => S.getInstance();
|
|
934
|
-
function
|
|
935
|
-
return $().collect(
|
|
930
|
+
function b(o) {
|
|
931
|
+
return $().collect(o);
|
|
936
932
|
}
|
|
937
|
-
function
|
|
938
|
-
return
|
|
933
|
+
function X() {
|
|
934
|
+
return b().device;
|
|
939
935
|
}
|
|
940
936
|
function N() {
|
|
941
|
-
return
|
|
942
|
-
}
|
|
943
|
-
function X() {
|
|
944
|
-
return v().app;
|
|
937
|
+
return b().user;
|
|
945
938
|
}
|
|
946
939
|
function Z() {
|
|
947
|
-
return
|
|
940
|
+
return b().app;
|
|
948
941
|
}
|
|
949
942
|
function Y() {
|
|
943
|
+
return b().geo;
|
|
944
|
+
}
|
|
945
|
+
function D() {
|
|
950
946
|
return N().id;
|
|
951
947
|
}
|
|
952
948
|
function ee() {
|
|
953
949
|
$().clearCache();
|
|
954
950
|
}
|
|
955
|
-
function te(
|
|
956
|
-
const e =
|
|
951
|
+
function te(o) {
|
|
952
|
+
const e = b(o);
|
|
957
953
|
return JSON.stringify(e, null, 2);
|
|
958
954
|
}
|
|
959
955
|
function ie() {
|
|
960
956
|
var t;
|
|
961
|
-
const
|
|
957
|
+
const o = b();
|
|
962
958
|
return [
|
|
963
|
-
|
|
964
|
-
|
|
965
|
-
|
|
966
|
-
|
|
967
|
-
((t =
|
|
959
|
+
o.device.os,
|
|
960
|
+
o.device.osv,
|
|
961
|
+
o.app.name,
|
|
962
|
+
o.user.id.slice(0, 8) + "...",
|
|
963
|
+
((t = o.geo) == null ? void 0 : t.country) || "Unknown"
|
|
968
964
|
].join(" / ");
|
|
969
965
|
}
|
|
970
966
|
function M() {
|
|
971
|
-
var
|
|
972
|
-
return typeof window < "u" ? !!((
|
|
967
|
+
var o;
|
|
968
|
+
return typeof window < "u" ? !!((o = window.__AD_CONFIG__) != null && o.debug) : !1;
|
|
973
969
|
}
|
|
974
|
-
function se(
|
|
970
|
+
function se(o) {
|
|
975
971
|
var e, t;
|
|
976
972
|
return {
|
|
977
|
-
id:
|
|
978
|
-
type:
|
|
979
|
-
score:
|
|
973
|
+
id: o.original.id,
|
|
974
|
+
type: o.original.type,
|
|
975
|
+
score: o.original.score,
|
|
980
976
|
source: "internal",
|
|
981
977
|
// Default source
|
|
982
978
|
content: {
|
|
983
|
-
title:
|
|
984
|
-
body:
|
|
985
|
-
image: (e =
|
|
986
|
-
cta_text:
|
|
987
|
-
price: (t =
|
|
988
|
-
rating:
|
|
989
|
-
brand:
|
|
979
|
+
title: o.adapted.title,
|
|
980
|
+
body: o.adapted.body,
|
|
981
|
+
image: (e = o.adapted.image) == null ? void 0 : e.url,
|
|
982
|
+
cta_text: o.adapted.ctaText,
|
|
983
|
+
price: (t = o.adapted.price) == null ? void 0 : t.display,
|
|
984
|
+
rating: o.adapted.rating,
|
|
985
|
+
brand: o.adapted.brand
|
|
990
986
|
},
|
|
991
987
|
tracking: {
|
|
992
|
-
click_url:
|
|
993
|
-
impression_url:
|
|
988
|
+
click_url: o.tracking.clickUrl || o.tracking.click_url || "",
|
|
989
|
+
impression_url: o.tracking.impressionUrl || o.tracking.impression_url || ""
|
|
994
990
|
},
|
|
995
991
|
metadata: {
|
|
996
|
-
viewToken:
|
|
997
|
-
styling:
|
|
992
|
+
viewToken: o.tracking.viewToken || o.tracking.view_token,
|
|
993
|
+
styling: o.adapted.styling
|
|
998
994
|
}
|
|
999
995
|
};
|
|
1000
996
|
}
|
|
1001
|
-
async function
|
|
997
|
+
async function H(o, e = {}) {
|
|
1002
998
|
const t = e.apiBaseUrl || "/api/v1", s = $().collect(), n = {
|
|
1003
|
-
...
|
|
999
|
+
...o,
|
|
1004
1000
|
clientInfo: s
|
|
1005
1001
|
// Auto-injected
|
|
1006
|
-
},
|
|
1002
|
+
}, r = {
|
|
1007
1003
|
"Content-Type": "application/json"
|
|
1008
1004
|
};
|
|
1009
|
-
e.apiKey && (
|
|
1005
|
+
e.apiKey && (r["X-API-Key"] = e.apiKey), M() && (console.log("[fetchAds] Request URL:", `${t}/ads/request`), console.log("[fetchAds] Request params:", o), console.log("[fetchAds] Request body:", n));
|
|
1010
1006
|
const a = await fetch(`${t}/ads/request`, {
|
|
1011
1007
|
method: "POST",
|
|
1012
|
-
headers:
|
|
1008
|
+
headers: r,
|
|
1013
1009
|
body: JSON.stringify(n)
|
|
1014
1010
|
});
|
|
1015
1011
|
if (!a.ok)
|
|
@@ -1019,16 +1015,16 @@ async function D(r, e = {}) {
|
|
|
1019
1015
|
throw new Error(c.error || "Ad request failed");
|
|
1020
1016
|
return c.data;
|
|
1021
1017
|
}
|
|
1022
|
-
const
|
|
1018
|
+
const F = { width: 400, height: 200 }, A = {
|
|
1023
1019
|
variant: "horizontal",
|
|
1024
1020
|
count: 1,
|
|
1025
1021
|
preferences: {}
|
|
1026
1022
|
};
|
|
1027
|
-
function _(
|
|
1023
|
+
function _(o = {}) {
|
|
1028
1024
|
const e = {
|
|
1029
|
-
variant:
|
|
1030
|
-
count:
|
|
1031
|
-
preferences: { ...A.preferences, ...
|
|
1025
|
+
variant: o.variant ?? A.variant,
|
|
1026
|
+
count: o.count ?? A.count,
|
|
1027
|
+
preferences: { ...A.preferences, ...o.preferences }
|
|
1032
1028
|
};
|
|
1033
1029
|
return [
|
|
1034
1030
|
{
|
|
@@ -1036,7 +1032,7 @@ function _(r = {}) {
|
|
|
1036
1032
|
slotName: "Action Card",
|
|
1037
1033
|
format: "action_card",
|
|
1038
1034
|
variant: e.variant,
|
|
1039
|
-
size:
|
|
1035
|
+
size: F,
|
|
1040
1036
|
count: e.count,
|
|
1041
1037
|
preferences: e.preferences,
|
|
1042
1038
|
placement: { position: "below_fold", context: "post_response" }
|
|
@@ -1045,7 +1041,7 @@ function _(r = {}) {
|
|
|
1045
1041
|
}
|
|
1046
1042
|
const g = class g {
|
|
1047
1043
|
constructor(e) {
|
|
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
|
|
1044
|
+
this.slots = {}, this.isLoading = !1, this.currentRequestId = null, this.adsAnalyticsMap = /* @__PURE__ */ new Map(), this.config = e, this.enabled = e.enabled !== !1, this.eventBus = new O(), this.slots_config = _(e.cardOption), typeof window < "u" && (window.__AD_CONFIG__ = {
|
|
1049
1045
|
...window.__AD_CONFIG__ || {},
|
|
1050
1046
|
apiKey: e.apiKey,
|
|
1051
1047
|
apiBaseUrl: e.apiBaseUrl,
|
|
@@ -1057,9 +1053,8 @@ const g = class g {
|
|
|
1057
1053
|
});
|
|
1058
1054
|
}
|
|
1059
1055
|
async requestAds(e) {
|
|
1060
|
-
var o;
|
|
1061
1056
|
const t = "conversationContext" in e ? e : { conversationContext: e };
|
|
1062
|
-
this.currentUserId = (
|
|
1057
|
+
this.currentUserId = this.resolveUserId(t.userContext);
|
|
1063
1058
|
const i = this.buildRequestKey(t), s = g.inFlightRequests.get(i);
|
|
1064
1059
|
if (s)
|
|
1065
1060
|
return this.config.debug && console.log("[AdManager] Reusing in-flight request for identical context"), s;
|
|
@@ -1070,10 +1065,14 @@ const g = class g {
|
|
|
1070
1065
|
this.isLoading = !0, this.eventBus.emit("adsLoading"), this.config.debug && console.log("[AdManager] Starting ad request...");
|
|
1071
1066
|
const n = (async () => {
|
|
1072
1067
|
try {
|
|
1073
|
-
const
|
|
1068
|
+
const r = await H(
|
|
1074
1069
|
{
|
|
1075
1070
|
conversationContext: t.conversationContext,
|
|
1076
|
-
userContext: t.userContext ? {
|
|
1071
|
+
userContext: t.userContext ? {
|
|
1072
|
+
...t.userContext,
|
|
1073
|
+
userId: t.userContext.userId ?? this.currentUserId,
|
|
1074
|
+
sessionId: t.userContext.sessionId ?? m()
|
|
1075
|
+
} : { userId: this.currentUserId, sessionId: m() },
|
|
1077
1076
|
slots: this.slots_config
|
|
1078
1077
|
},
|
|
1079
1078
|
{
|
|
@@ -1081,29 +1080,29 @@ const g = class g {
|
|
|
1081
1080
|
apiKey: this.config.apiKey
|
|
1082
1081
|
}
|
|
1083
1082
|
);
|
|
1084
|
-
this.currentRequestId =
|
|
1085
|
-
|
|
1086
|
-
const
|
|
1087
|
-
this.adsAnalyticsMap.set(
|
|
1088
|
-
requestId:
|
|
1089
|
-
slotId:
|
|
1090
|
-
position:
|
|
1091
|
-
totalAds:
|
|
1083
|
+
this.currentRequestId = r.requestId, this.adsAnalyticsMap.clear(), r.slots.forEach((c) => {
|
|
1084
|
+
c.ads.forEach((d, l) => {
|
|
1085
|
+
const u = d.original.id;
|
|
1086
|
+
this.adsAnalyticsMap.set(u, {
|
|
1087
|
+
requestId: r.requestId,
|
|
1088
|
+
slotId: c.slotId,
|
|
1089
|
+
position: l,
|
|
1090
|
+
totalAds: c.ads.length,
|
|
1092
1091
|
apiBaseUrl: this.config.apiBaseUrl,
|
|
1093
1092
|
userId: this.currentUserId
|
|
1094
1093
|
});
|
|
1095
1094
|
});
|
|
1096
1095
|
});
|
|
1097
|
-
const
|
|
1098
|
-
return
|
|
1099
|
-
c
|
|
1100
|
-
}), this.slots =
|
|
1096
|
+
const a = {};
|
|
1097
|
+
return r.slots.forEach((c) => {
|
|
1098
|
+
a[c.slotId] = c;
|
|
1099
|
+
}), this.slots = a, this.eventBus.emit("adsUpdated", this.slots), this.config.debug && console.log("[AdManager] Ads received:", {
|
|
1101
1100
|
slotCount: Object.keys(this.slots).length,
|
|
1102
1101
|
slots: Object.keys(this.slots)
|
|
1103
|
-
}),
|
|
1104
|
-
} catch (
|
|
1105
|
-
const
|
|
1106
|
-
throw this.eventBus.emit("adsError",
|
|
1102
|
+
}), r;
|
|
1103
|
+
} catch (r) {
|
|
1104
|
+
const a = r;
|
|
1105
|
+
throw this.eventBus.emit("adsError", a), a;
|
|
1107
1106
|
} finally {
|
|
1108
1107
|
this.isLoading = !1, g.inFlightRequests.delete(i);
|
|
1109
1108
|
}
|
|
@@ -1119,25 +1118,34 @@ const g = class g {
|
|
|
1119
1118
|
slots: this.slots_config
|
|
1120
1119
|
});
|
|
1121
1120
|
}
|
|
1121
|
+
resolveUserId(e) {
|
|
1122
|
+
if (e != null && e.userId)
|
|
1123
|
+
return e.userId;
|
|
1124
|
+
try {
|
|
1125
|
+
return D();
|
|
1126
|
+
} catch {
|
|
1127
|
+
return;
|
|
1128
|
+
}
|
|
1129
|
+
}
|
|
1122
1130
|
render(e, t, i = {}) {
|
|
1123
|
-
const s = typeof e != "string", n = s ? g.DEFAULT_SLOT_ID : e,
|
|
1124
|
-
if (!
|
|
1131
|
+
const s = typeof e != "string", n = s ? g.DEFAULT_SLOT_ID : e, r = s ? e : t, a = (s ? t : i) || {};
|
|
1132
|
+
if (!r)
|
|
1125
1133
|
return this.config.debug && console.warn("[AdManager] Render container is required"), null;
|
|
1126
1134
|
const c = this.slots[n];
|
|
1127
1135
|
if (!c || !c.ads || c.ads.length === 0)
|
|
1128
1136
|
return this.config.debug && console.warn("[AdManager] No ads in slot:", n), null;
|
|
1129
|
-
const
|
|
1130
|
-
if (!
|
|
1131
|
-
return this.config.debug && console.warn(`[AdManager] Ad at index ${
|
|
1132
|
-
const u = this.adsAnalyticsMap.get(
|
|
1133
|
-
|
|
1137
|
+
const d = a.adIndex ?? 0, l = c.ads[d];
|
|
1138
|
+
if (!l)
|
|
1139
|
+
return this.config.debug && console.warn(`[AdManager] Ad at index ${d} not found in slot:`, n), null;
|
|
1140
|
+
const u = this.adsAnalyticsMap.get(l.original.id), h = this.slots_config.find((v) => v.slotId === n), p = (h == null ? void 0 : h.format) || "action_card";
|
|
1141
|
+
r.innerHTML = "";
|
|
1134
1142
|
const f = {
|
|
1135
1143
|
analytics: u,
|
|
1136
1144
|
variant: a.variant,
|
|
1137
1145
|
onClick: a.onClick,
|
|
1138
1146
|
onImpression: a.onImpression
|
|
1139
1147
|
};
|
|
1140
|
-
return p === "suffix" ?
|
|
1148
|
+
return p === "suffix" ? y.renderSuffixAd(l, r, f) : p === "source" ? y.renderSponsoredSource(l, r, f) : p === "lead_gen" ? y.renderLeadGenAd(l, r, f) : y.renderActionCard(l, r, f);
|
|
1141
1149
|
}
|
|
1142
1150
|
/**
|
|
1143
1151
|
* Get ad slots data
|
|
@@ -1231,7 +1239,7 @@ const g = class g {
|
|
|
1231
1239
|
const s = this.adsAnalyticsMap.get(e);
|
|
1232
1240
|
if (!s || !this.currentRequestId)
|
|
1233
1241
|
return this.config.debug && console.warn("[AdManager] No analytics info for ad:", e), null;
|
|
1234
|
-
const n =
|
|
1242
|
+
const n = m(), r = await T({
|
|
1235
1243
|
requestId: this.currentRequestId,
|
|
1236
1244
|
adId: e,
|
|
1237
1245
|
destinationUrl: t,
|
|
@@ -1242,7 +1250,7 @@ const g = class g {
|
|
|
1242
1250
|
source: i == null ? void 0 : i.source,
|
|
1243
1251
|
userId: s.userId ?? this.currentUserId
|
|
1244
1252
|
}, { baseUrl: s.apiBaseUrl });
|
|
1245
|
-
return
|
|
1253
|
+
return r && (this.eventBus.emit("adClicked", e, s.slotId), this.config.debug && console.log("[AdManager] Click tracked via Analytics API:", r.eventId)), r;
|
|
1246
1254
|
}
|
|
1247
1255
|
/**
|
|
1248
1256
|
* Track ad impression using Analytics API
|
|
@@ -1251,7 +1259,7 @@ const g = class g {
|
|
|
1251
1259
|
const i = this.adsAnalyticsMap.get(e);
|
|
1252
1260
|
if (!i || !this.currentRequestId)
|
|
1253
1261
|
return this.config.debug && console.warn("[AdManager] No analytics info for ad:", e), null;
|
|
1254
|
-
const s =
|
|
1262
|
+
const s = m(), n = await I({
|
|
1255
1263
|
requestId: this.currentRequestId,
|
|
1256
1264
|
adId: e,
|
|
1257
1265
|
slotId: i.slotId,
|
|
@@ -1277,12 +1285,12 @@ g.DEFAULT_SLOT_ID = "action_card", g.inFlightRequests = /* @__PURE__ */ new Map(
|
|
|
1277
1285
|
let V = g;
|
|
1278
1286
|
function E() {
|
|
1279
1287
|
if (typeof window < "u") {
|
|
1280
|
-
const
|
|
1281
|
-
if (
|
|
1282
|
-
return
|
|
1288
|
+
const o = window.__AD_CONFIG__;
|
|
1289
|
+
if (o != null && o.apiKey)
|
|
1290
|
+
return o.apiKey;
|
|
1283
1291
|
}
|
|
1284
1292
|
}
|
|
1285
|
-
class
|
|
1293
|
+
class G {
|
|
1286
1294
|
constructor(e = {}, t = "/api/v1") {
|
|
1287
1295
|
var i, s;
|
|
1288
1296
|
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 = {
|
|
@@ -1305,7 +1313,7 @@ class F {
|
|
|
1305
1313
|
return;
|
|
1306
1314
|
}
|
|
1307
1315
|
this.log(`[ViewabilityTracker] Starting tracking for ${e}`);
|
|
1308
|
-
const
|
|
1316
|
+
const r = {
|
|
1309
1317
|
visiblePercentage: 0,
|
|
1310
1318
|
maxVisiblePercentage: 0,
|
|
1311
1319
|
totalVisibleTimeMs: 0,
|
|
@@ -1315,9 +1323,9 @@ class F {
|
|
|
1315
1323
|
enteredViewportAt: null,
|
|
1316
1324
|
enterCount: 0
|
|
1317
1325
|
};
|
|
1318
|
-
this.metrics.set(e,
|
|
1326
|
+
this.metrics.set(e, r), this.isTracking.set(e, !0), this.eventQueue.set(e, []);
|
|
1319
1327
|
const a = new IntersectionObserver(
|
|
1320
|
-
(
|
|
1328
|
+
(d) => this.handleIntersection(e, d[0], i, s, n),
|
|
1321
1329
|
{
|
|
1322
1330
|
threshold: this.createThresholds()
|
|
1323
1331
|
}
|
|
@@ -1345,54 +1353,54 @@ class F {
|
|
|
1345
1353
|
* Event-driven: Only process when state actually changes
|
|
1346
1354
|
*/
|
|
1347
1355
|
handleIntersection(e, t, i, s, n) {
|
|
1348
|
-
const
|
|
1349
|
-
if (!
|
|
1350
|
-
const a =
|
|
1351
|
-
|
|
1352
|
-
const
|
|
1353
|
-
if (
|
|
1356
|
+
const r = this.metrics.get(e);
|
|
1357
|
+
if (!r || !this.isTracking.get(e)) return;
|
|
1358
|
+
const a = r.isViewable, c = Math.round(t.intersectionRatio * 100);
|
|
1359
|
+
r.visiblePercentage = c, r.maxVisiblePercentage = Math.max(r.maxVisiblePercentage, c);
|
|
1360
|
+
const d = Date.now(), l = c >= this.config.minVisiblePercentage;
|
|
1361
|
+
if (l && !r.enteredViewportAt && (r.enteredViewportAt = d, r.enterCount++, this.log(`[ViewabilityTracker] ${e} entered viewport at ${d}`), this.queueEvent(e, {
|
|
1354
1362
|
adId: e,
|
|
1355
1363
|
sessionId: i,
|
|
1356
1364
|
requestId: s,
|
|
1357
1365
|
viewToken: n,
|
|
1358
1366
|
eventType: "enter_viewport",
|
|
1359
1367
|
visiblePercentage: c,
|
|
1360
|
-
maxVisiblePercentage:
|
|
1361
|
-
totalVisibleTimeMs:
|
|
1368
|
+
maxVisiblePercentage: r.maxVisiblePercentage,
|
|
1369
|
+
totalVisibleTimeMs: r.totalVisibleTimeMs,
|
|
1362
1370
|
isViewable: !1,
|
|
1363
|
-
timestamp:
|
|
1364
|
-
})), !
|
|
1365
|
-
const u =
|
|
1366
|
-
|
|
1371
|
+
timestamp: d
|
|
1372
|
+
})), !l && r.enteredViewportAt) {
|
|
1373
|
+
const u = d - r.enteredViewportAt;
|
|
1374
|
+
r.totalVisibleTimeMs += u, r.enteredViewportAt = null, r.currentVisibleTimeMs = 0, this.log(`[ViewabilityTracker] ${e} exited viewport, total visible: ${r.totalVisibleTimeMs}ms`), this.queueEvent(e, {
|
|
1367
1375
|
adId: e,
|
|
1368
1376
|
sessionId: i,
|
|
1369
1377
|
requestId: s,
|
|
1370
1378
|
viewToken: n,
|
|
1371
1379
|
eventType: "exit_viewport",
|
|
1372
1380
|
visiblePercentage: c,
|
|
1373
|
-
maxVisiblePercentage:
|
|
1374
|
-
totalVisibleTimeMs:
|
|
1375
|
-
isViewable:
|
|
1376
|
-
timestamp:
|
|
1381
|
+
maxVisiblePercentage: r.maxVisiblePercentage,
|
|
1382
|
+
totalVisibleTimeMs: r.totalVisibleTimeMs,
|
|
1383
|
+
isViewable: r.isViewable,
|
|
1384
|
+
timestamp: d
|
|
1377
1385
|
});
|
|
1378
1386
|
}
|
|
1379
|
-
|
|
1387
|
+
r.isViewable !== a && r.isViewable && this.log(`[ViewabilityTracker] ${e} became VIEWABLE!`), this.metrics.set(e, r);
|
|
1380
1388
|
}
|
|
1381
1389
|
/**
|
|
1382
1390
|
* Start monitoring loop for tracking duration
|
|
1383
1391
|
* Runs every 100ms to track continuous visible time
|
|
1384
1392
|
*/
|
|
1385
1393
|
startMonitoring(e, t, i, s) {
|
|
1386
|
-
const
|
|
1394
|
+
const r = setInterval(() => {
|
|
1387
1395
|
const a = this.metrics.get(e);
|
|
1388
1396
|
if (!a || !this.isTracking.get(e)) {
|
|
1389
|
-
clearInterval(
|
|
1397
|
+
clearInterval(r);
|
|
1390
1398
|
return;
|
|
1391
1399
|
}
|
|
1392
|
-
const c = Date.now(),
|
|
1400
|
+
const c = Date.now(), d = a.isViewable;
|
|
1393
1401
|
if (a.enteredViewportAt) {
|
|
1394
|
-
const
|
|
1395
|
-
a.currentVisibleTimeMs =
|
|
1402
|
+
const l = c - a.enteredViewportAt;
|
|
1403
|
+
a.currentVisibleTimeMs = l, l >= this.config.minViewableDuration && a.visiblePercentage >= this.config.minVisiblePercentage && (a.isViewable = !0, d || (a.viewableAt = a.enteredViewportAt, this.log(`[ViewabilityTracker] ${e} BECAME VIEWABLE at ${a.viewableAt}`), this.queueEvent(e, {
|
|
1396
1404
|
adId: e,
|
|
1397
1405
|
sessionId: t,
|
|
1398
1406
|
requestId: i,
|
|
@@ -1407,13 +1415,13 @@ class F {
|
|
|
1407
1415
|
}
|
|
1408
1416
|
a.enteredViewportAt && (a.totalVisibleTimeMs += 100), this.metrics.set(e, a);
|
|
1409
1417
|
}, 100);
|
|
1410
|
-
this.timers.set(`${e}_monitoring`,
|
|
1418
|
+
this.timers.set(`${e}_monitoring`, r);
|
|
1411
1419
|
}
|
|
1412
1420
|
/**
|
|
1413
1421
|
* Queue an event to be sent (batched)
|
|
1414
1422
|
*/
|
|
1415
1423
|
queueEvent(e, t) {
|
|
1416
|
-
var n,
|
|
1424
|
+
var n, r;
|
|
1417
1425
|
const i = this.eventQueue.get(e);
|
|
1418
1426
|
if (!i) {
|
|
1419
1427
|
this.log(`[ViewabilityTracker] No queue found for ${e}, skipping event`);
|
|
@@ -1426,10 +1434,10 @@ class F {
|
|
|
1426
1434
|
else {
|
|
1427
1435
|
const a = this.batchTimers.get(e);
|
|
1428
1436
|
a && clearTimeout(a);
|
|
1429
|
-
const c = ((
|
|
1437
|
+
const c = ((r = this.config.batchConfig) == null ? void 0 : r.maxBatchWaitMs) ?? 1e4, d = setTimeout(() => {
|
|
1430
1438
|
this.flushQueue(e);
|
|
1431
1439
|
}, c);
|
|
1432
|
-
this.batchTimers.set(e,
|
|
1440
|
+
this.batchTimers.set(e, d);
|
|
1433
1441
|
}
|
|
1434
1442
|
}
|
|
1435
1443
|
/**
|
|
@@ -1460,7 +1468,7 @@ class F {
|
|
|
1460
1468
|
const n = this.metrics.get(e);
|
|
1461
1469
|
if (!n) return;
|
|
1462
1470
|
this.log(`[ViewabilityTracker] Ending tracking for ${e}`), this.flushQueue(e);
|
|
1463
|
-
const
|
|
1471
|
+
const r = Date.now();
|
|
1464
1472
|
this.queueEvent(e, {
|
|
1465
1473
|
adId: e,
|
|
1466
1474
|
sessionId: t,
|
|
@@ -1471,7 +1479,7 @@ class F {
|
|
|
1471
1479
|
maxVisiblePercentage: n.maxVisiblePercentage,
|
|
1472
1480
|
totalVisibleTimeMs: n.totalVisibleTimeMs,
|
|
1473
1481
|
isViewable: n.isViewable,
|
|
1474
|
-
timestamp:
|
|
1482
|
+
timestamp: r
|
|
1475
1483
|
}), this.flushQueue(e), this.cleanup(e);
|
|
1476
1484
|
}
|
|
1477
1485
|
/**
|
|
@@ -1530,38 +1538,38 @@ class F {
|
|
|
1530
1538
|
}
|
|
1531
1539
|
}
|
|
1532
1540
|
let k = null;
|
|
1533
|
-
function ne(
|
|
1534
|
-
return k || (k = new
|
|
1541
|
+
function ne(o, e) {
|
|
1542
|
+
return k || (k = new G(o, e), k.setupBeforeUnload()), k;
|
|
1535
1543
|
}
|
|
1536
1544
|
const re = "0.1.0";
|
|
1537
1545
|
export {
|
|
1538
1546
|
V as AdManager,
|
|
1539
1547
|
x as AnalyticsSender,
|
|
1540
1548
|
S as ClientInfoCollector,
|
|
1541
|
-
|
|
1549
|
+
y as DOMRenderer,
|
|
1542
1550
|
w as HTMLRenderer,
|
|
1543
1551
|
re as SDK_VERSION,
|
|
1544
1552
|
P as SessionManager,
|
|
1545
|
-
|
|
1553
|
+
G as ViewabilityTracker,
|
|
1546
1554
|
se as adaptAdToKoahAd,
|
|
1547
1555
|
ee as clearClientInfoCache,
|
|
1548
|
-
|
|
1549
|
-
|
|
1550
|
-
|
|
1551
|
-
|
|
1552
|
-
|
|
1553
|
-
|
|
1556
|
+
Q as createAnalytics,
|
|
1557
|
+
J as createSession,
|
|
1558
|
+
H as fetchAds,
|
|
1559
|
+
z as generateViewToken,
|
|
1560
|
+
Z as getAppInfo,
|
|
1561
|
+
b as getClientInfo,
|
|
1554
1562
|
$ as getClientInfoCollector,
|
|
1555
1563
|
te as getClientInfoJSON,
|
|
1556
1564
|
ie as getClientInfoSummary,
|
|
1557
|
-
|
|
1558
|
-
|
|
1559
|
-
|
|
1560
|
-
|
|
1565
|
+
X as getDeviceInfo,
|
|
1566
|
+
Y as getGeoInfo,
|
|
1567
|
+
m as getSessionId,
|
|
1568
|
+
D as getUserId,
|
|
1561
1569
|
N as getUserInfo,
|
|
1562
1570
|
ne as getViewabilityTracker,
|
|
1563
1571
|
T as trackAdClick,
|
|
1564
1572
|
I as trackAdImpression,
|
|
1565
|
-
|
|
1573
|
+
W as trackClicksBatch,
|
|
1566
1574
|
j as trackImpressionsBatch
|
|
1567
1575
|
};
|