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