@bidkernel/analytics 0.12.0 → 0.16.0
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/analytics.global.js +1 -1
- package/dist/index.d.mts +66 -1
- package/dist/index.d.ts +66 -1
- package/dist/index.js +221 -70
- package/dist/index.mjs +220 -70
- package/package.json +1 -1
package/dist/index.mjs
CHANGED
|
@@ -1052,11 +1052,13 @@ var CACHED_BID_TTL_MS = 30 * 60 * 1e3;
|
|
|
1052
1052
|
var MAX_CACHED_BID_KEYS = 200;
|
|
1053
1053
|
var MAX_IMPRESSION_KEYS = 1e3;
|
|
1054
1054
|
var MAX_TRACKED_AUCTIONS = 50;
|
|
1055
|
+
var CLICK_DEDUP_MS = 1e3;
|
|
1055
1056
|
var SESSION_KEY = "_bidkernel_session";
|
|
1056
1057
|
var SESSION_TS_KEY = "_bidkernel_session_ts";
|
|
1057
1058
|
var THIRTY_MINUTES_MS = 30 * 60 * 1e3;
|
|
1058
1059
|
var inMemorySessionId = null;
|
|
1059
1060
|
var inMemorySessionTs = 0;
|
|
1061
|
+
var storageAllowed = true;
|
|
1060
1062
|
function generateUUID() {
|
|
1061
1063
|
if (typeof crypto !== "undefined" && typeof crypto.randomUUID === "function") {
|
|
1062
1064
|
return crypto.randomUUID();
|
|
@@ -1126,6 +1128,7 @@ function sameEndpointOrigin(a, b) {
|
|
|
1126
1128
|
function extendSession() {
|
|
1127
1129
|
const now = Date.now();
|
|
1128
1130
|
inMemorySessionTs = now;
|
|
1131
|
+
if (!storageAllowed) return;
|
|
1129
1132
|
try {
|
|
1130
1133
|
if (typeof localStorage !== "undefined") {
|
|
1131
1134
|
localStorage.setItem(SESSION_TS_KEY, now.toString());
|
|
@@ -1135,18 +1138,23 @@ function extendSession() {
|
|
|
1135
1138
|
}
|
|
1136
1139
|
function getOrCreateSessionId() {
|
|
1137
1140
|
const now = Date.now();
|
|
1141
|
+
const memoryFresh = !!inMemorySessionId && !!inMemorySessionTs && now - inMemorySessionTs <= THIRTY_MINUTES_MS;
|
|
1138
1142
|
try {
|
|
1139
|
-
if (typeof localStorage !== "undefined") {
|
|
1143
|
+
if (storageAllowed && typeof localStorage !== "undefined") {
|
|
1140
1144
|
const storedId = localStorage.getItem(SESSION_KEY);
|
|
1141
1145
|
const tsStr = localStorage.getItem(SESSION_TS_KEY);
|
|
1142
1146
|
const storedTs = tsStr ? parseInt(tsStr, 10) || 0 : 0;
|
|
1143
1147
|
if (storedId && storedTs && now - storedTs <= THIRTY_MINUTES_MS) {
|
|
1144
1148
|
localStorage.setItem(SESSION_TS_KEY, now.toString());
|
|
1149
|
+
inMemorySessionId = storedId;
|
|
1150
|
+
inMemorySessionTs = now;
|
|
1145
1151
|
return storedId;
|
|
1146
1152
|
}
|
|
1147
|
-
const newId = generateUUID();
|
|
1153
|
+
const newId = memoryFresh ? inMemorySessionId : generateUUID();
|
|
1148
1154
|
localStorage.setItem(SESSION_KEY, newId);
|
|
1149
1155
|
localStorage.setItem(SESSION_TS_KEY, now.toString());
|
|
1156
|
+
inMemorySessionId = newId;
|
|
1157
|
+
inMemorySessionTs = now;
|
|
1150
1158
|
return newId;
|
|
1151
1159
|
}
|
|
1152
1160
|
} catch {
|
|
@@ -1512,6 +1520,17 @@ var BidkernelPrebidAnalytics = class _BidkernelPrebidAnalytics {
|
|
|
1512
1520
|
static initImaInterception() {
|
|
1513
1521
|
initImaInterception();
|
|
1514
1522
|
}
|
|
1523
|
+
/**
|
|
1524
|
+
* Allows or forbids localStorage writes for every instance on the page.
|
|
1525
|
+
* Collection and delivery are unaffected: only the persisted session id,
|
|
1526
|
+
* its timestamp and exit batches are gated.
|
|
1527
|
+
*/
|
|
1528
|
+
static setStorageAllowed(allowed) {
|
|
1529
|
+
storageAllowed = allowed;
|
|
1530
|
+
}
|
|
1531
|
+
static isStorageAllowed() {
|
|
1532
|
+
return storageAllowed;
|
|
1533
|
+
}
|
|
1515
1534
|
config;
|
|
1516
1535
|
queue = [];
|
|
1517
1536
|
errorCount = 0;
|
|
@@ -1540,6 +1559,12 @@ var BidkernelPrebidAnalytics = class _BidkernelPrebidAnalytics {
|
|
|
1540
1559
|
slotRefreshIndices = /* @__PURE__ */ new Map();
|
|
1541
1560
|
slotLastAuctionIds = /* @__PURE__ */ new Map();
|
|
1542
1561
|
pendingThresholdListeners = /* @__PURE__ */ new Map();
|
|
1562
|
+
pendingViewableListeners = /* @__PURE__ */ new Map();
|
|
1563
|
+
// Element a subscriber named for a slot (a sticky bar or interstitial that
|
|
1564
|
+
// renders outside the slot element); wins over document.getElementById.
|
|
1565
|
+
slotElements = /* @__PURE__ */ new Map();
|
|
1566
|
+
clickDetachCleanups = /* @__PURE__ */ new Set();
|
|
1567
|
+
lastClickAt = /* @__PURE__ */ new Map();
|
|
1543
1568
|
// Impression deduplication per slot and refresh cycle (strictly 1 impression per cycle)
|
|
1544
1569
|
slotEmittedImpressionKeys = /* @__PURE__ */ new Set();
|
|
1545
1570
|
// Winning bid cache from bidWon to marry with subsequent render triggers (adRenderSucceeded, video, etc.)
|
|
@@ -1550,6 +1575,9 @@ var BidkernelPrebidAnalytics = class _BidkernelPrebidAnalytics {
|
|
|
1550
1575
|
auctionBidderOutcomes = /* @__PURE__ */ new Map();
|
|
1551
1576
|
logger;
|
|
1552
1577
|
constructor(config) {
|
|
1578
|
+
if (config.storageAllowed !== void 0) {
|
|
1579
|
+
_BidkernelPrebidAnalytics.setStorageAllowed(config.storageAllowed);
|
|
1580
|
+
}
|
|
1553
1581
|
const requestedEndpoint = config.endpoint || "";
|
|
1554
1582
|
const endpoint = !requestedEndpoint || isTrustedEndpoint(requestedEndpoint) ? requestedEndpoint : "";
|
|
1555
1583
|
this.config = {
|
|
@@ -1565,6 +1593,7 @@ var BidkernelPrebidAnalytics = class _BidkernelPrebidAnalytics {
|
|
|
1565
1593
|
warningsEnabled: config.warningsEnabled ?? true,
|
|
1566
1594
|
errorsEnabled: config.errorsEnabled ?? true,
|
|
1567
1595
|
viewabilityEnabled: config.viewabilityEnabled ?? true,
|
|
1596
|
+
storageAllowed: config.storageAllowed ?? true,
|
|
1568
1597
|
logLevel: config.logLevel || "INFO",
|
|
1569
1598
|
pbjsGlobalName: config.pbjsGlobalName || "pbjs",
|
|
1570
1599
|
attachPbjsListeners: config.attachPbjsListeners ?? true,
|
|
@@ -1607,65 +1636,7 @@ var BidkernelPrebidAnalytics = class _BidkernelPrebidAnalytics {
|
|
|
1607
1636
|
}
|
|
1608
1637
|
}
|
|
1609
1638
|
if (this.config.attachPbjsListeners) {
|
|
1610
|
-
|
|
1611
|
-
const pbjs = win[this.config.pbjsGlobalName] || {};
|
|
1612
|
-
if (typeof pbjs.onEvent === "function") {
|
|
1613
|
-
this.log("DEBUG", "Attaching event listeners to pbjs");
|
|
1614
|
-
const events = [
|
|
1615
|
-
["auctionInit", this.handleAuctionInit.bind(this)],
|
|
1616
|
-
["auctionEnd", this.handleAuctionEnd.bind(this)],
|
|
1617
|
-
["bidRequested", this.handleBidRequested.bind(this)],
|
|
1618
|
-
["bidResponse", this.handleBidResponse.bind(this)],
|
|
1619
|
-
["bidTimeout", this.handleBidTimeout.bind(this)],
|
|
1620
|
-
["bidWon", this.handleBidWon.bind(this)],
|
|
1621
|
-
["noBid", this.handleNoBid.bind(this)],
|
|
1622
|
-
["adRenderFailed", this.handleAdRenderFailed.bind(this)],
|
|
1623
|
-
["adRenderSucceeded", this.handleAdRenderSucceeded.bind(this)]
|
|
1624
|
-
];
|
|
1625
|
-
for (const [name, fn] of events) {
|
|
1626
|
-
pbjs.onEvent(name, fn);
|
|
1627
|
-
this.boundPbjsHandlers.push({ event: name, handler: fn });
|
|
1628
|
-
}
|
|
1629
|
-
} else {
|
|
1630
|
-
this.log("WARN", "pbjs.onEvent is not defined. Prebid analytics will not function.");
|
|
1631
|
-
}
|
|
1632
|
-
if (typeof pbjs.getEvents === "function") {
|
|
1633
|
-
try {
|
|
1634
|
-
const pastEvents = pbjs.getEvents();
|
|
1635
|
-
if (Array.isArray(pastEvents)) {
|
|
1636
|
-
const newPastEvents = pastEvents.slice(this.replayedEventCount);
|
|
1637
|
-
this.replayedEventCount = pastEvents.length;
|
|
1638
|
-
if (newPastEvents.length > 0) {
|
|
1639
|
-
this.log(
|
|
1640
|
-
"DEBUG",
|
|
1641
|
-
`Replaying ${newPastEvents.length} historical events from pbjs.getEvents()`
|
|
1642
|
-
);
|
|
1643
|
-
const handlerMap = {
|
|
1644
|
-
auctionInit: this.handleAuctionInit.bind(this),
|
|
1645
|
-
auctionEnd: this.handleAuctionEnd.bind(this),
|
|
1646
|
-
bidRequested: this.handleBidRequested.bind(this),
|
|
1647
|
-
bidResponse: this.handleBidResponse.bind(this),
|
|
1648
|
-
bidTimeout: this.handleBidTimeout.bind(this),
|
|
1649
|
-
bidWon: this.handleBidWon.bind(this),
|
|
1650
|
-
noBid: this.handleNoBid.bind(this),
|
|
1651
|
-
adRenderFailed: this.handleAdRenderFailed.bind(this),
|
|
1652
|
-
adRenderSucceeded: this.handleAdRenderSucceeded.bind(this)
|
|
1653
|
-
};
|
|
1654
|
-
for (const ev of newPastEvents) {
|
|
1655
|
-
if (!ev) continue;
|
|
1656
|
-
const eventType = ev.eventType || ev.event || ev.name;
|
|
1657
|
-
const args = ev.args !== void 0 ? ev.args : ev.data !== void 0 ? ev.data : ev;
|
|
1658
|
-
const handler = handlerMap[eventType];
|
|
1659
|
-
if (handler) {
|
|
1660
|
-
handler(args);
|
|
1661
|
-
}
|
|
1662
|
-
}
|
|
1663
|
-
}
|
|
1664
|
-
}
|
|
1665
|
-
} catch (e) {
|
|
1666
|
-
this.log("WARN", "Failed to replay historical events from pbjs.getEvents()", e);
|
|
1667
|
-
}
|
|
1668
|
-
}
|
|
1639
|
+
this.attachPbjs();
|
|
1669
1640
|
}
|
|
1670
1641
|
if (typeof window !== "undefined") {
|
|
1671
1642
|
if (!this.pageUrl) {
|
|
@@ -1688,6 +1659,68 @@ var BidkernelPrebidAnalytics = class _BidkernelPrebidAnalytics {
|
|
|
1688
1659
|
}
|
|
1689
1660
|
}
|
|
1690
1661
|
}
|
|
1662
|
+
/**
|
|
1663
|
+
* Binds the Prebid event handlers on the configured global and replays
|
|
1664
|
+
* pbjs.getEvents() history. enable() calls this when attachPbjsListeners is
|
|
1665
|
+
* true. An integration that loads Prebid lazily constructs the instance with
|
|
1666
|
+
* attachPbjsListeners=false and calls this once pbjs exists; disable() (and
|
|
1667
|
+
* therefore navigate()) drops the handlers, so call it again after either.
|
|
1668
|
+
* Idempotent. Returns true when handlers are bound after the call, false
|
|
1669
|
+
* when the instance is disabled or pbjs.onEvent is not available yet.
|
|
1670
|
+
*/
|
|
1671
|
+
attachPbjs() {
|
|
1672
|
+
if (!this.isEnabled) return false;
|
|
1673
|
+
if (this.boundPbjsHandlers.length > 0) return true;
|
|
1674
|
+
const win = typeof window !== "undefined" ? window : {};
|
|
1675
|
+
const pbjs = win[this.config.pbjsGlobalName] || {};
|
|
1676
|
+
if (typeof pbjs.onEvent !== "function") {
|
|
1677
|
+
this.log("WARN", "pbjs.onEvent is not defined. Prebid analytics will not function.");
|
|
1678
|
+
return false;
|
|
1679
|
+
}
|
|
1680
|
+
this.log("DEBUG", "Attaching event listeners to pbjs");
|
|
1681
|
+
const handlerMap = {
|
|
1682
|
+
auctionInit: this.handleAuctionInit.bind(this),
|
|
1683
|
+
auctionEnd: this.handleAuctionEnd.bind(this),
|
|
1684
|
+
bidRequested: this.handleBidRequested.bind(this),
|
|
1685
|
+
bidResponse: this.handleBidResponse.bind(this),
|
|
1686
|
+
bidTimeout: this.handleBidTimeout.bind(this),
|
|
1687
|
+
bidWon: this.handleBidWon.bind(this),
|
|
1688
|
+
noBid: this.handleNoBid.bind(this),
|
|
1689
|
+
adRenderFailed: this.handleAdRenderFailed.bind(this),
|
|
1690
|
+
adRenderSucceeded: this.handleAdRenderSucceeded.bind(this)
|
|
1691
|
+
};
|
|
1692
|
+
for (const [name, fn] of Object.entries(handlerMap)) {
|
|
1693
|
+
pbjs.onEvent(name, fn);
|
|
1694
|
+
this.boundPbjsHandlers.push({ event: name, handler: fn });
|
|
1695
|
+
}
|
|
1696
|
+
if (typeof pbjs.getEvents === "function") {
|
|
1697
|
+
try {
|
|
1698
|
+
const pastEvents = pbjs.getEvents();
|
|
1699
|
+
if (Array.isArray(pastEvents)) {
|
|
1700
|
+
const newPastEvents = pastEvents.slice(this.replayedEventCount);
|
|
1701
|
+
this.replayedEventCount = pastEvents.length;
|
|
1702
|
+
if (newPastEvents.length > 0) {
|
|
1703
|
+
this.log(
|
|
1704
|
+
"DEBUG",
|
|
1705
|
+
`Replaying ${newPastEvents.length} historical events from pbjs.getEvents()`
|
|
1706
|
+
);
|
|
1707
|
+
for (const ev of newPastEvents) {
|
|
1708
|
+
if (!ev) continue;
|
|
1709
|
+
const eventType = ev.eventType || ev.event || ev.name;
|
|
1710
|
+
const args = ev.args !== void 0 ? ev.args : ev.data !== void 0 ? ev.data : ev;
|
|
1711
|
+
const handler = handlerMap[eventType];
|
|
1712
|
+
if (handler) {
|
|
1713
|
+
handler(args);
|
|
1714
|
+
}
|
|
1715
|
+
}
|
|
1716
|
+
}
|
|
1717
|
+
}
|
|
1718
|
+
} catch (e) {
|
|
1719
|
+
this.log("WARN", "Failed to replay historical events from pbjs.getEvents()", e);
|
|
1720
|
+
}
|
|
1721
|
+
}
|
|
1722
|
+
return true;
|
|
1723
|
+
}
|
|
1691
1724
|
disable() {
|
|
1692
1725
|
if (!this.isEnabled) return;
|
|
1693
1726
|
this.flushAllSlotsTimeInView();
|
|
@@ -1719,6 +1752,14 @@ var BidkernelPrebidAnalytics = class _BidkernelPrebidAnalytics {
|
|
|
1719
1752
|
}
|
|
1720
1753
|
}
|
|
1721
1754
|
this.videoDetachCleanups.clear();
|
|
1755
|
+
for (const cleanup of Array.from(this.clickDetachCleanups)) {
|
|
1756
|
+
try {
|
|
1757
|
+
cleanup();
|
|
1758
|
+
} catch {
|
|
1759
|
+
}
|
|
1760
|
+
}
|
|
1761
|
+
this.clickDetachCleanups.clear();
|
|
1762
|
+
this.slotElements.clear();
|
|
1722
1763
|
this.cachedWinningBids.clear();
|
|
1723
1764
|
this.slotEmittedImpressionKeys.clear();
|
|
1724
1765
|
this.slotLastAuctionIds.clear();
|
|
@@ -1880,6 +1921,105 @@ var BidkernelPrebidAnalytics = class _BidkernelPrebidAnalytics {
|
|
|
1880
1921
|
}
|
|
1881
1922
|
});
|
|
1882
1923
|
}
|
|
1924
|
+
this.notifyViewable(record);
|
|
1925
|
+
}
|
|
1926
|
+
notifyViewable(record) {
|
|
1927
|
+
if (!record.viewableFired) return;
|
|
1928
|
+
for (const listener of record.viewableListeners) {
|
|
1929
|
+
if (listener.firedForIndex === record.refreshIndex) continue;
|
|
1930
|
+
listener.firedForIndex = record.refreshIndex;
|
|
1931
|
+
try {
|
|
1932
|
+
listener.callback(record.slotId);
|
|
1933
|
+
} catch (e) {
|
|
1934
|
+
this.log("ERROR", "Error in viewable listener callback", e);
|
|
1935
|
+
}
|
|
1936
|
+
}
|
|
1937
|
+
}
|
|
1938
|
+
/**
|
|
1939
|
+
* Calls back once per render cycle when the slot has met the IAB viewable
|
|
1940
|
+
* standard this adapter measures (immediately if it already has). Works
|
|
1941
|
+
* before the slot is observed: the listener waits for observeSlot. Returns
|
|
1942
|
+
* an unsubscribe function.
|
|
1943
|
+
*/
|
|
1944
|
+
/**
|
|
1945
|
+
* Names the element to measure for a slot when the creative renders
|
|
1946
|
+
* somewhere other than the slot element (a sticky bar, an interstitial).
|
|
1947
|
+
* Applies to the current cycle at once and to every later render.
|
|
1948
|
+
*/
|
|
1949
|
+
setSlotElement(slotId, element) {
|
|
1950
|
+
this.slotElements.set(slotId, element);
|
|
1951
|
+
const record = this.slotViewabilityRecords.get(slotId);
|
|
1952
|
+
if (record && record.element !== element) {
|
|
1953
|
+
this.observeSlot(element, slotId, {
|
|
1954
|
+
refreshIndex: record.refreshIndex,
|
|
1955
|
+
emitRefreshEvent: false
|
|
1956
|
+
});
|
|
1957
|
+
}
|
|
1958
|
+
}
|
|
1959
|
+
/**
|
|
1960
|
+
* Records a click on the slot's current creative, attributed to the cached
|
|
1961
|
+
* winning bid. Repeats within one second are one click. Returns whether a
|
|
1962
|
+
* CLICK was recorded.
|
|
1963
|
+
*/
|
|
1964
|
+
recordClick(slotId, options) {
|
|
1965
|
+
if (!this.isEnabled || !slotId) return false;
|
|
1966
|
+
const now = Date.now();
|
|
1967
|
+
if (now - (this.lastClickAt.get(slotId) || 0) < CLICK_DEDUP_MS) return false;
|
|
1968
|
+
this.lastClickAt.set(slotId, now);
|
|
1969
|
+
const cached = this.getCachedBid(slotId);
|
|
1970
|
+
this.enqueue(TraceEventType.CLICK, "click", {
|
|
1971
|
+
auctionId: cached?.auctionId || "",
|
|
1972
|
+
transactionId: cached?.transactionId || "",
|
|
1973
|
+
adUnitCode: slotId,
|
|
1974
|
+
bid: cached?.bidTrace,
|
|
1975
|
+
metadata: {
|
|
1976
|
+
...options?.metadata,
|
|
1977
|
+
refresh_index: String(this.getRefreshIndex(slotId))
|
|
1978
|
+
}
|
|
1979
|
+
});
|
|
1980
|
+
return true;
|
|
1981
|
+
}
|
|
1982
|
+
/**
|
|
1983
|
+
* Detects clicks into a cross-origin creative frame: a click inside an
|
|
1984
|
+
* iframe moves focus into it and blurs the window. Returns a detach
|
|
1985
|
+
* function; every tracker is detached on disable().
|
|
1986
|
+
*/
|
|
1987
|
+
attachClickTracker(element, slotId) {
|
|
1988
|
+
if (typeof window === "undefined") return () => {
|
|
1989
|
+
};
|
|
1990
|
+
const onBlur = () => {
|
|
1991
|
+
setTimeout(() => {
|
|
1992
|
+
const active = document.activeElement;
|
|
1993
|
+
if (active && (active === element || element.contains(active))) {
|
|
1994
|
+
this.recordClick(slotId, { metadata: { source: "blur" } });
|
|
1995
|
+
window.focus();
|
|
1996
|
+
}
|
|
1997
|
+
}, 0);
|
|
1998
|
+
};
|
|
1999
|
+
window.addEventListener("blur", onBlur);
|
|
2000
|
+
const cleanup = () => {
|
|
2001
|
+
window.removeEventListener("blur", onBlur);
|
|
2002
|
+
this.clickDetachCleanups.delete(cleanup);
|
|
2003
|
+
};
|
|
2004
|
+
this.clickDetachCleanups.add(cleanup);
|
|
2005
|
+
return cleanup;
|
|
2006
|
+
}
|
|
2007
|
+
onViewable(slotId, callback) {
|
|
2008
|
+
const listener = { callback, firedForIndex: -1 };
|
|
2009
|
+
const record = this.slotViewabilityRecords.get(slotId);
|
|
2010
|
+
if (record) {
|
|
2011
|
+
record.viewableListeners.add(listener);
|
|
2012
|
+
this.notifyViewable(record);
|
|
2013
|
+
} else {
|
|
2014
|
+
if (!this.pendingViewableListeners.has(slotId)) {
|
|
2015
|
+
this.pendingViewableListeners.set(slotId, /* @__PURE__ */ new Set());
|
|
2016
|
+
}
|
|
2017
|
+
this.pendingViewableListeners.get(slotId).add(listener);
|
|
2018
|
+
}
|
|
2019
|
+
return () => {
|
|
2020
|
+
this.slotViewabilityRecords.get(slotId)?.viewableListeners.delete(listener);
|
|
2021
|
+
this.pendingViewableListeners.get(slotId)?.delete(listener);
|
|
2022
|
+
};
|
|
1883
2023
|
}
|
|
1884
2024
|
scheduleThresholdTimers(record) {
|
|
1885
2025
|
if (!record.inView || typeof document !== "undefined" && document.visibilityState === "hidden") {
|
|
@@ -2069,6 +2209,8 @@ var BidkernelPrebidAnalytics = class _BidkernelPrebidAnalytics {
|
|
|
2069
2209
|
}
|
|
2070
2210
|
const listeners = this.pendingThresholdListeners.get(resolvedSlotId) || /* @__PURE__ */ new Set();
|
|
2071
2211
|
this.pendingThresholdListeners.delete(resolvedSlotId);
|
|
2212
|
+
const viewableListeners = this.pendingViewableListeners.get(resolvedSlotId) || /* @__PURE__ */ new Set();
|
|
2213
|
+
this.pendingViewableListeners.delete(resolvedSlotId);
|
|
2072
2214
|
const record = {
|
|
2073
2215
|
slotId: resolvedSlotId,
|
|
2074
2216
|
element: el,
|
|
@@ -2085,7 +2227,8 @@ var BidkernelPrebidAnalytics = class _BidkernelPrebidAnalytics {
|
|
|
2085
2227
|
viewableFired: false,
|
|
2086
2228
|
dwellTimer: null,
|
|
2087
2229
|
dwellStartedAt: null,
|
|
2088
|
-
thresholdListeners: listeners
|
|
2230
|
+
thresholdListeners: listeners,
|
|
2231
|
+
viewableListeners
|
|
2089
2232
|
};
|
|
2090
2233
|
this.slotViewabilityRecords.set(resolvedSlotId, record);
|
|
2091
2234
|
if (el) {
|
|
@@ -2110,6 +2253,7 @@ var BidkernelPrebidAnalytics = class _BidkernelPrebidAnalytics {
|
|
|
2110
2253
|
}
|
|
2111
2254
|
}
|
|
2112
2255
|
record.thresholdListeners = /* @__PURE__ */ new Set();
|
|
2256
|
+
record.viewableListeners = /* @__PURE__ */ new Set();
|
|
2113
2257
|
if (record.element && this.intersectionObserver) {
|
|
2114
2258
|
this.intersectionObserver.unobserve(record.element);
|
|
2115
2259
|
this.elementToSlotId.delete(record.element);
|
|
@@ -2124,6 +2268,7 @@ var BidkernelPrebidAnalytics = class _BidkernelPrebidAnalytics {
|
|
|
2124
2268
|
this.slotRefreshIndices.delete(slotId);
|
|
2125
2269
|
this.slotLastAuctionIds.delete(slotId);
|
|
2126
2270
|
this.pendingThresholdListeners.delete(slotId);
|
|
2271
|
+
this.pendingViewableListeners.delete(slotId);
|
|
2127
2272
|
const prefix = `${escapeKeyPart(slotId)}:`;
|
|
2128
2273
|
for (const key of Array.from(this.slotEmittedImpressionKeys)) {
|
|
2129
2274
|
if (key === slotId || key.startsWith(prefix)) {
|
|
@@ -2398,19 +2543,21 @@ var BidkernelPrebidAnalytics = class _BidkernelPrebidAnalytics {
|
|
|
2398
2543
|
if (!adsManager.__bidkernelAttachedInstances) {
|
|
2399
2544
|
try {
|
|
2400
2545
|
Object.defineProperty(adsManager, "__bidkernelAttachedInstances", {
|
|
2401
|
-
value: /* @__PURE__ */ new
|
|
2546
|
+
value: /* @__PURE__ */ new Map(),
|
|
2402
2547
|
configurable: true,
|
|
2403
2548
|
writable: true
|
|
2404
2549
|
});
|
|
2405
2550
|
} catch {
|
|
2406
|
-
adsManager.__bidkernelAttachedInstances = /* @__PURE__ */ new
|
|
2551
|
+
adsManager.__bidkernelAttachedInstances = /* @__PURE__ */ new Map();
|
|
2407
2552
|
}
|
|
2408
2553
|
}
|
|
2409
|
-
|
|
2410
|
-
|
|
2554
|
+
const attached = adsManager.__bidkernelAttachedInstances;
|
|
2555
|
+
const previous = attached.get(this);
|
|
2556
|
+
if (previous) {
|
|
2557
|
+
if (!options) return () => {
|
|
2411
2558
|
};
|
|
2559
|
+
previous();
|
|
2412
2560
|
}
|
|
2413
|
-
adsManager.__bidkernelAttachedInstances.add(this);
|
|
2414
2561
|
const slotId = options?.slotId || options?.adUnitCode || "video";
|
|
2415
2562
|
const adUnitCode = options?.adUnitCode || slotId;
|
|
2416
2563
|
const auctionId = options?.auctionId || "";
|
|
@@ -2558,7 +2705,7 @@ var BidkernelPrebidAnalytics = class _BidkernelPrebidAnalytics {
|
|
|
2558
2705
|
}
|
|
2559
2706
|
}
|
|
2560
2707
|
const cleanup = () => {
|
|
2561
|
-
|
|
2708
|
+
attached.delete(this);
|
|
2562
2709
|
for (const { type, handler } of listeners) {
|
|
2563
2710
|
try {
|
|
2564
2711
|
adsManager.removeEventListener(type, handler);
|
|
@@ -2567,6 +2714,7 @@ var BidkernelPrebidAnalytics = class _BidkernelPrebidAnalytics {
|
|
|
2567
2714
|
}
|
|
2568
2715
|
this.videoDetachCleanups.delete(cleanup);
|
|
2569
2716
|
};
|
|
2717
|
+
attached.set(this, cleanup);
|
|
2570
2718
|
this.videoDetachCleanups.add(cleanup);
|
|
2571
2719
|
return cleanup;
|
|
2572
2720
|
}
|
|
@@ -3194,9 +3342,9 @@ var BidkernelPrebidAnalytics = class _BidkernelPrebidAnalytics {
|
|
|
3194
3342
|
);
|
|
3195
3343
|
}
|
|
3196
3344
|
if (this.config.viewabilityEnabled && typeof document !== "undefined") {
|
|
3197
|
-
let el = null;
|
|
3345
|
+
let el = adUnitCode && this.slotElements.get(adUnitCode) || null;
|
|
3198
3346
|
const targetId = adUnitCode || data.adId || bid.adId;
|
|
3199
|
-
if (targetId) {
|
|
3347
|
+
if (!el && targetId) {
|
|
3200
3348
|
el = document.getElementById(targetId);
|
|
3201
3349
|
}
|
|
3202
3350
|
if (!el && typeof window !== "undefined" && window.googletag?.pubads) {
|
|
@@ -3457,6 +3605,7 @@ var BidkernelPrebidAnalytics = class _BidkernelPrebidAnalytics {
|
|
|
3457
3605
|
return `${PENDING_BATCH_KEY_PREFIX}${encodeURIComponent(this.config.propertyId)}_`;
|
|
3458
3606
|
}
|
|
3459
3607
|
persistBatch(encoded) {
|
|
3608
|
+
if (!storageAllowed) return null;
|
|
3460
3609
|
try {
|
|
3461
3610
|
if (typeof localStorage === "undefined") return null;
|
|
3462
3611
|
if (!this.config.propertyId) return null;
|
|
@@ -3708,6 +3857,7 @@ function getbidkernel(alias = "bidkernel") {
|
|
|
3708
3857
|
export {
|
|
3709
3858
|
BidkernelPrebidAnalytics,
|
|
3710
3859
|
PrebidEventDeduper,
|
|
3860
|
+
getOrCreateSessionId,
|
|
3711
3861
|
getPrebidEventKey,
|
|
3712
3862
|
getbidkernel,
|
|
3713
3863
|
hookImaPrototype,
|
package/package.json
CHANGED