@bidkernel/analytics 0.20.0 → 0.22.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/README.md +19 -1
- package/dist/analytics.global.js +1 -1
- package/dist/index.d.mts +38 -4
- package/dist/index.d.ts +38 -4
- package/dist/index.js +177 -23
- package/dist/index.mjs +175 -23
- package/package.json +1 -1
package/dist/index.mjs
CHANGED
|
@@ -317,6 +317,17 @@ var BidderOutcome = {
|
|
|
317
317
|
BIDDER_OUTCOME_NO_RESPONSE: 5,
|
|
318
318
|
UNRECOGNIZED: -1
|
|
319
319
|
};
|
|
320
|
+
var FloorSource = {
|
|
321
|
+
/** FLOOR_SOURCE_UNSPECIFIED - module off, no decision */
|
|
322
|
+
FLOOR_SOURCE_UNSPECIFIED: 0,
|
|
323
|
+
/** FLOOR_SOURCE_STATIC - the publisher's rule, scaled by the treatment */
|
|
324
|
+
FLOOR_SOURCE_STATIC: 1,
|
|
325
|
+
/** FLOOR_SOURCE_POOL - the bid pool's standing bid plus margin */
|
|
326
|
+
FLOOR_SOURCE_POOL: 2,
|
|
327
|
+
/** FLOOR_SOURCE_NONE - module on, but neither term applied */
|
|
328
|
+
FLOOR_SOURCE_NONE: 3,
|
|
329
|
+
UNRECOGNIZED: -1
|
|
330
|
+
};
|
|
320
331
|
function createBaseTraceEventBatch() {
|
|
321
332
|
return {
|
|
322
333
|
propertyId: new Uint8Array(0),
|
|
@@ -719,7 +730,15 @@ var TraceEvent_MetadataEntry = {
|
|
|
719
730
|
}
|
|
720
731
|
};
|
|
721
732
|
function createBaseBidderOutcomeEntry() {
|
|
722
|
-
return {
|
|
733
|
+
return {
|
|
734
|
+
adUnitCode: "",
|
|
735
|
+
outcome: 0,
|
|
736
|
+
bid: void 0,
|
|
737
|
+
refreshIndex: 0,
|
|
738
|
+
floorCents: void 0,
|
|
739
|
+
floorSource: 0,
|
|
740
|
+
floorTreatmentBp: void 0
|
|
741
|
+
};
|
|
723
742
|
}
|
|
724
743
|
var BidderOutcomeEntry = {
|
|
725
744
|
encode(message, writer = new BinaryWriter()) {
|
|
@@ -735,6 +754,15 @@ var BidderOutcomeEntry = {
|
|
|
735
754
|
if (message.refreshIndex !== void 0 && message.refreshIndex !== 0) {
|
|
736
755
|
writer.uint32(56).int32(message.refreshIndex);
|
|
737
756
|
}
|
|
757
|
+
if (message.floorCents !== void 0) {
|
|
758
|
+
writer.uint32(64).int32(message.floorCents);
|
|
759
|
+
}
|
|
760
|
+
if (message.floorSource !== void 0 && message.floorSource !== 0) {
|
|
761
|
+
writer.uint32(72).int32(message.floorSource);
|
|
762
|
+
}
|
|
763
|
+
if (message.floorTreatmentBp !== void 0) {
|
|
764
|
+
writer.uint32(80).int32(message.floorTreatmentBp);
|
|
765
|
+
}
|
|
738
766
|
return writer;
|
|
739
767
|
},
|
|
740
768
|
decode(input, length) {
|
|
@@ -772,6 +800,27 @@ var BidderOutcomeEntry = {
|
|
|
772
800
|
message.refreshIndex = reader.int32();
|
|
773
801
|
continue;
|
|
774
802
|
}
|
|
803
|
+
case 8: {
|
|
804
|
+
if (tag !== 64) {
|
|
805
|
+
break;
|
|
806
|
+
}
|
|
807
|
+
message.floorCents = reader.int32();
|
|
808
|
+
continue;
|
|
809
|
+
}
|
|
810
|
+
case 9: {
|
|
811
|
+
if (tag !== 72) {
|
|
812
|
+
break;
|
|
813
|
+
}
|
|
814
|
+
message.floorSource = reader.int32();
|
|
815
|
+
continue;
|
|
816
|
+
}
|
|
817
|
+
case 10: {
|
|
818
|
+
if (tag !== 80) {
|
|
819
|
+
break;
|
|
820
|
+
}
|
|
821
|
+
message.floorTreatmentBp = reader.int32();
|
|
822
|
+
continue;
|
|
823
|
+
}
|
|
775
824
|
}
|
|
776
825
|
if ((tag & 7) === 4 || tag === 0) {
|
|
777
826
|
break;
|
|
@@ -971,6 +1020,12 @@ var CACHED_BID_TTL_MS = 30 * 60 * 1e3;
|
|
|
971
1020
|
var MAX_CACHED_BID_KEYS = 200;
|
|
972
1021
|
var MAX_IMPRESSION_KEYS = 1e3;
|
|
973
1022
|
var MAX_TRACKED_AUCTIONS = 50;
|
|
1023
|
+
var MAX_FLOOR_DECISIONS = 200;
|
|
1024
|
+
var FLOOR_SOURCE_PROTO = {
|
|
1025
|
+
static: FloorSource.FLOOR_SOURCE_STATIC,
|
|
1026
|
+
pool: FloorSource.FLOOR_SOURCE_POOL,
|
|
1027
|
+
none: FloorSource.FLOOR_SOURCE_NONE
|
|
1028
|
+
};
|
|
974
1029
|
var CLICK_DEDUP_MS = 1e3;
|
|
975
1030
|
var SESSION_KEY = "_bidkernel_session";
|
|
976
1031
|
var SESSION_TS_KEY = "_bidkernel_session_ts";
|
|
@@ -1046,49 +1101,83 @@ function sameEndpointOrigin(a, b) {
|
|
|
1046
1101
|
}
|
|
1047
1102
|
var SESSION_PERSIST_INTERVAL_MS = 60 * 1e3;
|
|
1048
1103
|
var persistedSessionTs = 0;
|
|
1049
|
-
|
|
1104
|
+
var ACTIVITY_EVENTS = ["pointerdown", "pointermove", "keydown", "scroll", "wheel", "touchstart"];
|
|
1105
|
+
var activityListenersBound = false;
|
|
1106
|
+
var sessionResumeListeners = /* @__PURE__ */ new Set();
|
|
1107
|
+
function persistSessionTs(ts) {
|
|
1050
1108
|
try {
|
|
1051
1109
|
if (typeof localStorage !== "undefined") {
|
|
1052
|
-
localStorage.setItem(SESSION_TS_KEY,
|
|
1053
|
-
persistedSessionTs =
|
|
1110
|
+
localStorage.setItem(SESSION_TS_KEY, ts.toString());
|
|
1111
|
+
persistedSessionTs = ts;
|
|
1054
1112
|
}
|
|
1055
1113
|
} catch {
|
|
1056
1114
|
}
|
|
1057
1115
|
}
|
|
1058
|
-
function
|
|
1116
|
+
function isSessionActive(now = Date.now()) {
|
|
1117
|
+
return inMemorySessionTs > 0 && now - inMemorySessionTs <= THIRTY_MINUTES_MS;
|
|
1118
|
+
}
|
|
1119
|
+
function onSessionResume(listener) {
|
|
1120
|
+
bindActivityListeners();
|
|
1121
|
+
sessionResumeListeners.add(listener);
|
|
1122
|
+
return () => {
|
|
1123
|
+
sessionResumeListeners.delete(listener);
|
|
1124
|
+
};
|
|
1125
|
+
}
|
|
1126
|
+
function recordActivity() {
|
|
1059
1127
|
const now = Date.now();
|
|
1128
|
+
const lapsed = !!inMemorySessionId && !isSessionActive(now);
|
|
1060
1129
|
inMemorySessionTs = now;
|
|
1061
|
-
if (
|
|
1130
|
+
if (lapsed) {
|
|
1131
|
+
inMemorySessionId = null;
|
|
1132
|
+
for (const listener of sessionResumeListeners) listener();
|
|
1133
|
+
return;
|
|
1134
|
+
}
|
|
1135
|
+
if (!storageAllowed || !inMemorySessionId || persistedSessionTs === 0) return;
|
|
1062
1136
|
if (now - persistedSessionTs < SESSION_PERSIST_INTERVAL_MS) return;
|
|
1063
1137
|
persistSessionTs(now);
|
|
1064
1138
|
}
|
|
1139
|
+
function sessionNeedsSync() {
|
|
1140
|
+
return !inMemorySessionId || storageAllowed && persistedSessionTs === 0;
|
|
1141
|
+
}
|
|
1142
|
+
function bindActivityListeners() {
|
|
1143
|
+
if (activityListenersBound || typeof window === "undefined") return;
|
|
1144
|
+
activityListenersBound = true;
|
|
1145
|
+
const onActivity = () => recordActivity();
|
|
1146
|
+
for (const name of ACTIVITY_EVENTS) {
|
|
1147
|
+
window.addEventListener(name, onActivity, { passive: true, capture: true });
|
|
1148
|
+
}
|
|
1149
|
+
if (typeof document !== "undefined") {
|
|
1150
|
+
document.addEventListener("visibilitychange", () => {
|
|
1151
|
+
if (document.visibilityState === "visible") recordActivity();
|
|
1152
|
+
});
|
|
1153
|
+
}
|
|
1154
|
+
}
|
|
1065
1155
|
function getOrCreateSessionId() {
|
|
1066
1156
|
const now = Date.now();
|
|
1067
|
-
const memoryFresh = !!inMemorySessionId &&
|
|
1157
|
+
const memoryFresh = !!inMemorySessionId && isSessionActive(now);
|
|
1068
1158
|
try {
|
|
1069
1159
|
if (storageAllowed && typeof localStorage !== "undefined") {
|
|
1070
1160
|
const storedId = localStorage.getItem(SESSION_KEY);
|
|
1071
1161
|
const tsStr = localStorage.getItem(SESSION_TS_KEY);
|
|
1072
1162
|
const storedTs = tsStr ? parseInt(tsStr, 10) || 0 : 0;
|
|
1073
1163
|
if (storedId && storedTs && now - storedTs <= THIRTY_MINUTES_MS) {
|
|
1074
|
-
|
|
1075
|
-
|
|
1076
|
-
|
|
1164
|
+
if (inMemorySessionId !== storedId || inMemorySessionTs < storedTs) {
|
|
1165
|
+
inMemorySessionId = storedId;
|
|
1166
|
+
inMemorySessionTs = Math.max(inMemorySessionTs, storedTs);
|
|
1167
|
+
}
|
|
1168
|
+
if (persistedSessionTs === 0) persistedSessionTs = storedTs;
|
|
1077
1169
|
return storedId;
|
|
1078
1170
|
}
|
|
1079
1171
|
const newId = memoryFresh ? inMemorySessionId : generateUUID();
|
|
1172
|
+
if (!memoryFresh) inMemorySessionTs = now;
|
|
1080
1173
|
localStorage.setItem(SESSION_KEY, newId);
|
|
1081
|
-
persistSessionTs(
|
|
1174
|
+
persistSessionTs(inMemorySessionTs);
|
|
1082
1175
|
inMemorySessionId = newId;
|
|
1083
|
-
inMemorySessionTs = now;
|
|
1084
1176
|
return newId;
|
|
1085
1177
|
}
|
|
1086
1178
|
} catch {
|
|
1087
1179
|
}
|
|
1088
|
-
if (
|
|
1089
|
-
inMemorySessionTs = now;
|
|
1090
|
-
return inMemorySessionId;
|
|
1091
|
-
}
|
|
1180
|
+
if (memoryFresh) return inMemorySessionId;
|
|
1092
1181
|
inMemorySessionId = generateUUID();
|
|
1093
1182
|
inMemorySessionTs = now;
|
|
1094
1183
|
return inMemorySessionId;
|
|
@@ -1247,7 +1336,13 @@ var BidkernelPrebidAnalytics = class _BidkernelPrebidAnalytics {
|
|
|
1247
1336
|
videoDetachCleanups = /* @__PURE__ */ new Set();
|
|
1248
1337
|
// Compacted bidder participation map per auction: auctionId -> Map<`${bidder}:${adUnitCode}`, BidderOutcomeEntry>
|
|
1249
1338
|
auctionBidderOutcomes = /* @__PURE__ */ new Map();
|
|
1339
|
+
// Live Floors decisions: `${auctionId}:${adUnitCode}` -> decision (see recordFloorDecision)
|
|
1340
|
+
floorDecisions = /* @__PURE__ */ new Map();
|
|
1250
1341
|
logger;
|
|
1342
|
+
// True when this instance owns its session id (none was supplied), so the
|
|
1343
|
+
// id follows the page-wide session as it lapses and restarts. An id the
|
|
1344
|
+
// integration supplied is stamped as given.
|
|
1345
|
+
managesSessionId;
|
|
1251
1346
|
constructor(config) {
|
|
1252
1347
|
if (config.storageAllowed !== void 0) {
|
|
1253
1348
|
_BidkernelPrebidAnalytics.setStorageAllowed(config.storageAllowed);
|
|
@@ -1258,7 +1353,7 @@ var BidkernelPrebidAnalytics = class _BidkernelPrebidAnalytics {
|
|
|
1258
1353
|
endpoint,
|
|
1259
1354
|
propertyId: config.propertyId || "",
|
|
1260
1355
|
pageviewId: config.pageviewId || generateUUID(),
|
|
1261
|
-
sessionId: config.sessionId ||
|
|
1356
|
+
sessionId: config.sessionId || "",
|
|
1262
1357
|
userId: config.userId || "",
|
|
1263
1358
|
deviceType: config.deviceType || "desktop",
|
|
1264
1359
|
country: config.country || "",
|
|
@@ -1277,6 +1372,9 @@ var BidkernelPrebidAnalytics = class _BidkernelPrebidAnalytics {
|
|
|
1277
1372
|
prefix: "[bidkernel][prebid-analytics]",
|
|
1278
1373
|
logLevel: this.config.logLevel
|
|
1279
1374
|
});
|
|
1375
|
+
recordActivity();
|
|
1376
|
+
this.managesSessionId = !config.sessionId;
|
|
1377
|
+
if (this.managesSessionId) this.config.sessionId = getOrCreateSessionId();
|
|
1280
1378
|
if (requestedEndpoint && !endpoint) {
|
|
1281
1379
|
this.log(
|
|
1282
1380
|
"ERROR",
|
|
@@ -1325,6 +1423,7 @@ var BidkernelPrebidAnalytics = class _BidkernelPrebidAnalytics {
|
|
|
1325
1423
|
if (typeof document !== "undefined") {
|
|
1326
1424
|
document.addEventListener("visibilitychange", this.boundVisibilityChange);
|
|
1327
1425
|
}
|
|
1426
|
+
bindActivityListeners();
|
|
1328
1427
|
this.flushTimer = setInterval(() => this.flush(), FLUSH_INTERVAL_MS);
|
|
1329
1428
|
this.resendPersistedBatches();
|
|
1330
1429
|
}
|
|
@@ -1434,6 +1533,7 @@ var BidkernelPrebidAnalytics = class _BidkernelPrebidAnalytics {
|
|
|
1434
1533
|
this.slotEmittedImpressionKeys.clear();
|
|
1435
1534
|
this.slotLastAuctionIds.clear();
|
|
1436
1535
|
this.auctionBidderOutcomes.clear();
|
|
1536
|
+
this.floorDecisions.clear();
|
|
1437
1537
|
if (this.flushTimer) {
|
|
1438
1538
|
clearInterval(this.flushTimer);
|
|
1439
1539
|
this.flushTimer = null;
|
|
@@ -2193,15 +2293,44 @@ var BidkernelPrebidAnalytics = class _BidkernelPrebidAnalytics {
|
|
|
2193
2293
|
if (eventType === void 0) return;
|
|
2194
2294
|
this.enqueue(eventType, eventName, data, level);
|
|
2195
2295
|
}
|
|
2296
|
+
/**
|
|
2297
|
+
* Record the wrapper's Live Floors decision for an auction and ad unit,
|
|
2298
|
+
* before the auction runs. The decision is stamped on the auction's
|
|
2299
|
+
* outcome entries for the ad unit at auction end and on the win and
|
|
2300
|
+
* impression rows that follow, so every outcome can be split by floor,
|
|
2301
|
+
* source and treatment without a join. Integrations without the module
|
|
2302
|
+
* never call this and their rows carry no floor fields.
|
|
2303
|
+
*/
|
|
2304
|
+
recordFloorDecision(auctionId, adUnitCode, decision) {
|
|
2305
|
+
if (!auctionId || !adUnitCode) return;
|
|
2306
|
+
const key = `${auctionId}:${adUnitCode}`;
|
|
2307
|
+
this.floorDecisions.delete(key);
|
|
2308
|
+
this.floorDecisions.set(key, {
|
|
2309
|
+
floorCents: decision.floorCents !== void 0 && Number.isFinite(decision.floorCents) ? Math.round(decision.floorCents) : void 0,
|
|
2310
|
+
source: decision.source,
|
|
2311
|
+
treatment: Number.isFinite(decision.treatment) ? decision.treatment : 1
|
|
2312
|
+
});
|
|
2313
|
+
while (this.floorDecisions.size > MAX_FLOOR_DECISIONS) {
|
|
2314
|
+
const oldest = this.floorDecisions.keys().next();
|
|
2315
|
+
if (oldest.done) break;
|
|
2316
|
+
this.floorDecisions.delete(oldest.value);
|
|
2317
|
+
}
|
|
2318
|
+
}
|
|
2319
|
+
floorDecisionFor(auctionId, adUnitCode) {
|
|
2320
|
+
return auctionId && adUnitCode ? this.floorDecisions.get(`${auctionId}:${adUnitCode}`) : void 0;
|
|
2321
|
+
}
|
|
2196
2322
|
setUserId(userId) {
|
|
2197
2323
|
this.config.userId = userId;
|
|
2198
2324
|
}
|
|
2199
2325
|
setSessionId(sessionId) {
|
|
2200
2326
|
this.config.sessionId = sessionId;
|
|
2327
|
+
this.managesSessionId = !sessionId;
|
|
2328
|
+
if (this.managesSessionId) this.config.sessionId = getOrCreateSessionId();
|
|
2201
2329
|
}
|
|
2202
2330
|
navigate(pageviewId, pageUrl) {
|
|
2203
2331
|
this.disable();
|
|
2204
2332
|
this.slotRefreshIndices.clear();
|
|
2333
|
+
this.floorDecisions.clear();
|
|
2205
2334
|
this.pendingThresholdListeners.clear();
|
|
2206
2335
|
this.config.pageviewId = pageviewId || generateUUID();
|
|
2207
2336
|
if (pageUrl) {
|
|
@@ -2215,7 +2344,7 @@ var BidkernelPrebidAnalytics = class _BidkernelPrebidAnalytics {
|
|
|
2215
2344
|
this.pageUrl = "";
|
|
2216
2345
|
}
|
|
2217
2346
|
this.logger.resetTiming();
|
|
2218
|
-
|
|
2347
|
+
recordActivity();
|
|
2219
2348
|
this.enable();
|
|
2220
2349
|
}
|
|
2221
2350
|
handleAuctionInit(data) {
|
|
@@ -2554,7 +2683,9 @@ var BidkernelPrebidAnalytics = class _BidkernelPrebidAnalytics {
|
|
|
2554
2683
|
enqueue(type, eventName, data, level) {
|
|
2555
2684
|
if (!this.isEnabled) return;
|
|
2556
2685
|
if (!this.shouldSample(type, level)) return;
|
|
2557
|
-
|
|
2686
|
+
if (this.managesSessionId && sessionNeedsSync()) {
|
|
2687
|
+
this.config.sessionId = getOrCreateSessionId();
|
|
2688
|
+
}
|
|
2558
2689
|
const protoEvent = {
|
|
2559
2690
|
eventId: idToBytes(generateUUID()),
|
|
2560
2691
|
timestampMs: Date.now(),
|
|
@@ -2589,13 +2720,32 @@ var BidkernelPrebidAnalytics = class _BidkernelPrebidAnalytics {
|
|
|
2589
2720
|
}
|
|
2590
2721
|
if (data.bidderOutcomes && Array.isArray(data.bidderOutcomes)) {
|
|
2591
2722
|
protoEvent.bidderOutcomes = data.bidderOutcomes.map(
|
|
2592
|
-
(entry) =>
|
|
2593
|
-
|
|
2594
|
-
|
|
2595
|
-
|
|
2723
|
+
(entry) => {
|
|
2724
|
+
const floor = this.floorDecisionFor(String(data.auctionId || ""), entry.adUnitCode || "");
|
|
2725
|
+
return {
|
|
2726
|
+
...entry,
|
|
2727
|
+
refreshIndex: entry.refreshIndex ?? this.auctionCycleIndex(entry.adUnitCode || ""),
|
|
2728
|
+
...floor ? {
|
|
2729
|
+
floorCents: floor.floorCents,
|
|
2730
|
+
floorSource: FLOOR_SOURCE_PROTO[floor.source],
|
|
2731
|
+
floorTreatmentBp: Math.round(floor.treatment * 1e4)
|
|
2732
|
+
} : {}
|
|
2733
|
+
};
|
|
2734
|
+
}
|
|
2596
2735
|
);
|
|
2597
2736
|
}
|
|
2598
2737
|
const metadata = { ...data.metadata };
|
|
2738
|
+
if (type === TraceEventType.BID_WIN || type === TraceEventType.IMPRESSION) {
|
|
2739
|
+
const floor = this.floorDecisionFor(
|
|
2740
|
+
String(data.auctionId || ""),
|
|
2741
|
+
protoEvent.adUnitCode || ""
|
|
2742
|
+
);
|
|
2743
|
+
if (floor) {
|
|
2744
|
+
if (floor.floorCents !== void 0) metadata.floor_cents = String(floor.floorCents);
|
|
2745
|
+
metadata.floor_source = floor.source;
|
|
2746
|
+
metadata.floor_treatment = floor.treatment.toFixed(2);
|
|
2747
|
+
}
|
|
2748
|
+
}
|
|
2599
2749
|
if (data.error !== void 0 && data.error !== null) {
|
|
2600
2750
|
metadata.error = typeof data.error === "object" && data.error.message ? String(data.error.message) : String(data.error);
|
|
2601
2751
|
}
|
|
@@ -3803,6 +3953,8 @@ export {
|
|
|
3803
3953
|
getbidkernel,
|
|
3804
3954
|
hookImaPrototype,
|
|
3805
3955
|
initImaInterception,
|
|
3956
|
+
isSessionActive,
|
|
3806
3957
|
isTrustedEndpoint,
|
|
3958
|
+
onSessionResume,
|
|
3807
3959
|
registerPrebidAnalytics
|
|
3808
3960
|
};
|
package/package.json
CHANGED