@bidkernel/analytics 0.1.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/index.js ADDED
@@ -0,0 +1,1396 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+
20
+ // src/index.ts
21
+ var src_exports = {};
22
+ __export(src_exports, {
23
+ BidkernelPrebidAnalytics: () => BidkernelPrebidAnalytics,
24
+ PrebidEventDeduper: () => PrebidEventDeduper,
25
+ getPrebidEventKey: () => getPrebidEventKey,
26
+ getbidkernel: () => getbidkernel,
27
+ registerPrebidAnalytics: () => registerPrebidAnalytics
28
+ });
29
+ module.exports = __toCommonJS(src_exports);
30
+
31
+ // ../../protogen/trace_event.ts
32
+ var import_wire = require("@bufbuild/protobuf/wire");
33
+ var TraceEventType = {
34
+ TRACE_EVENT_TYPE_UNSPECIFIED: 0,
35
+ AUCTION_START: 1,
36
+ AUCTION_END: 2,
37
+ BID_REQUEST: 3,
38
+ BID_RESPONSE: 4,
39
+ BID_WIN: 5,
40
+ BID_TIMEOUT: 6,
41
+ /** IMPRESSION - ad rendered into DOM */
42
+ IMPRESSION: 7,
43
+ /** VIEWABLE - IAB viewability threshold met (boolean, once per render cycle) */
44
+ VIEWABLE: 8,
45
+ /** TIME_IN_VIEW - accumulated in-viewport duration (once per render cycle end) */
46
+ TIME_IN_VIEW: 14,
47
+ REFRESH: 9,
48
+ ERROR: 10,
49
+ SLOT_DEFINED: 11,
50
+ SLOT_DESTROYED: 12,
51
+ /** CLICK - ad click-through */
52
+ CLICK: 13,
53
+ /** NO_BID - bidder responded with no bid */
54
+ NO_BID: 15,
55
+ /** AD_RENDER_FAILED - Prebid failed to render the winning ad */
56
+ AD_RENDER_FAILED: 16,
57
+ UNRECOGNIZED: -1
58
+ };
59
+ function createBaseTraceEventBatch() {
60
+ return {
61
+ propertyId: "",
62
+ pageviewId: "",
63
+ sessionId: "",
64
+ pageUrl: "",
65
+ country: "",
66
+ region: "",
67
+ deviceType: "",
68
+ userId: "",
69
+ domain: "",
70
+ events: [],
71
+ browser: "",
72
+ deviceManufacturer: "",
73
+ deviceModel: "",
74
+ city: "",
75
+ postalCode: ""
76
+ };
77
+ }
78
+ var TraceEventBatch = {
79
+ encode(message, writer = new import_wire.BinaryWriter()) {
80
+ if (message.propertyId !== void 0 && message.propertyId !== "") {
81
+ writer.uint32(10).string(message.propertyId);
82
+ }
83
+ if (message.pageviewId !== void 0 && message.pageviewId !== "") {
84
+ writer.uint32(18).string(message.pageviewId);
85
+ }
86
+ if (message.sessionId !== void 0 && message.sessionId !== "") {
87
+ writer.uint32(26).string(message.sessionId);
88
+ }
89
+ if (message.pageUrl !== void 0 && message.pageUrl !== "") {
90
+ writer.uint32(34).string(message.pageUrl);
91
+ }
92
+ if (message.country !== void 0 && message.country !== "") {
93
+ writer.uint32(42).string(message.country);
94
+ }
95
+ if (message.region !== void 0 && message.region !== "") {
96
+ writer.uint32(50).string(message.region);
97
+ }
98
+ if (message.deviceType !== void 0 && message.deviceType !== "") {
99
+ writer.uint32(58).string(message.deviceType);
100
+ }
101
+ if (message.userId !== void 0 && message.userId !== "") {
102
+ writer.uint32(66).string(message.userId);
103
+ }
104
+ if (message.domain !== void 0 && message.domain !== "") {
105
+ writer.uint32(74).string(message.domain);
106
+ }
107
+ if (message.events !== void 0 && message.events.length !== 0) {
108
+ for (const v of message.events) {
109
+ TraceEvent.encode(v, writer.uint32(82).fork()).join();
110
+ }
111
+ }
112
+ if (message.browser !== void 0 && message.browser !== "") {
113
+ writer.uint32(90).string(message.browser);
114
+ }
115
+ if (message.deviceManufacturer !== void 0 && message.deviceManufacturer !== "") {
116
+ writer.uint32(98).string(message.deviceManufacturer);
117
+ }
118
+ if (message.deviceModel !== void 0 && message.deviceModel !== "") {
119
+ writer.uint32(106).string(message.deviceModel);
120
+ }
121
+ if (message.city !== void 0 && message.city !== "") {
122
+ writer.uint32(114).string(message.city);
123
+ }
124
+ if (message.postalCode !== void 0 && message.postalCode !== "") {
125
+ writer.uint32(122).string(message.postalCode);
126
+ }
127
+ return writer;
128
+ },
129
+ decode(input, length) {
130
+ const reader = input instanceof import_wire.BinaryReader ? input : new import_wire.BinaryReader(input);
131
+ const end = length === void 0 ? reader.len : reader.pos + length;
132
+ const message = createBaseTraceEventBatch();
133
+ while (reader.pos < end) {
134
+ const tag = reader.uint32();
135
+ switch (tag >>> 3) {
136
+ case 1: {
137
+ if (tag !== 10) {
138
+ break;
139
+ }
140
+ message.propertyId = reader.string();
141
+ continue;
142
+ }
143
+ case 2: {
144
+ if (tag !== 18) {
145
+ break;
146
+ }
147
+ message.pageviewId = reader.string();
148
+ continue;
149
+ }
150
+ case 3: {
151
+ if (tag !== 26) {
152
+ break;
153
+ }
154
+ message.sessionId = reader.string();
155
+ continue;
156
+ }
157
+ case 4: {
158
+ if (tag !== 34) {
159
+ break;
160
+ }
161
+ message.pageUrl = reader.string();
162
+ continue;
163
+ }
164
+ case 5: {
165
+ if (tag !== 42) {
166
+ break;
167
+ }
168
+ message.country = reader.string();
169
+ continue;
170
+ }
171
+ case 6: {
172
+ if (tag !== 50) {
173
+ break;
174
+ }
175
+ message.region = reader.string();
176
+ continue;
177
+ }
178
+ case 7: {
179
+ if (tag !== 58) {
180
+ break;
181
+ }
182
+ message.deviceType = reader.string();
183
+ continue;
184
+ }
185
+ case 8: {
186
+ if (tag !== 66) {
187
+ break;
188
+ }
189
+ message.userId = reader.string();
190
+ continue;
191
+ }
192
+ case 9: {
193
+ if (tag !== 74) {
194
+ break;
195
+ }
196
+ message.domain = reader.string();
197
+ continue;
198
+ }
199
+ case 10: {
200
+ if (tag !== 82) {
201
+ break;
202
+ }
203
+ const el = TraceEvent.decode(reader, reader.uint32());
204
+ if (el !== void 0) {
205
+ message.events.push(el);
206
+ }
207
+ continue;
208
+ }
209
+ case 11: {
210
+ if (tag !== 90) {
211
+ break;
212
+ }
213
+ message.browser = reader.string();
214
+ continue;
215
+ }
216
+ case 12: {
217
+ if (tag !== 98) {
218
+ break;
219
+ }
220
+ message.deviceManufacturer = reader.string();
221
+ continue;
222
+ }
223
+ case 13: {
224
+ if (tag !== 106) {
225
+ break;
226
+ }
227
+ message.deviceModel = reader.string();
228
+ continue;
229
+ }
230
+ case 14: {
231
+ if (tag !== 114) {
232
+ break;
233
+ }
234
+ message.city = reader.string();
235
+ continue;
236
+ }
237
+ case 15: {
238
+ if (tag !== 122) {
239
+ break;
240
+ }
241
+ message.postalCode = reader.string();
242
+ continue;
243
+ }
244
+ }
245
+ if ((tag & 7) === 4 || tag === 0) {
246
+ break;
247
+ }
248
+ reader.skip(tag & 7);
249
+ }
250
+ return message;
251
+ },
252
+ create(base) {
253
+ return TraceEventBatch.fromPartial(base ?? {});
254
+ },
255
+ fromPartial(object) {
256
+ const message = createBaseTraceEventBatch();
257
+ message.propertyId = object.propertyId ?? "";
258
+ message.pageviewId = object.pageviewId ?? "";
259
+ message.sessionId = object.sessionId ?? "";
260
+ message.pageUrl = object.pageUrl ?? "";
261
+ message.country = object.country ?? "";
262
+ message.region = object.region ?? "";
263
+ message.deviceType = object.deviceType ?? "";
264
+ message.userId = object.userId ?? "";
265
+ message.domain = object.domain ?? "";
266
+ message.events = object.events?.map((e) => TraceEvent.fromPartial(e)) || [];
267
+ message.browser = object.browser ?? "";
268
+ message.deviceManufacturer = object.deviceManufacturer ?? "";
269
+ message.deviceModel = object.deviceModel ?? "";
270
+ message.city = object.city ?? "";
271
+ message.postalCode = object.postalCode ?? "";
272
+ return message;
273
+ }
274
+ };
275
+ function createBaseTraceEvent() {
276
+ return {
277
+ timestampMs: 0,
278
+ type: 0,
279
+ eventName: "",
280
+ auctionId: "",
281
+ transactionId: "",
282
+ adUnitCode: "",
283
+ bid: void 0,
284
+ namespace: "",
285
+ eventId: "",
286
+ metadata: {},
287
+ viewableDurationMs: void 0
288
+ };
289
+ }
290
+ var TraceEvent = {
291
+ encode(message, writer = new import_wire.BinaryWriter()) {
292
+ if (message.timestampMs !== void 0 && message.timestampMs !== 0) {
293
+ writer.uint32(9).double(message.timestampMs);
294
+ }
295
+ if (message.type !== void 0 && message.type !== 0) {
296
+ writer.uint32(16).int32(message.type);
297
+ }
298
+ if (message.eventName !== void 0 && message.eventName !== "") {
299
+ writer.uint32(26).string(message.eventName);
300
+ }
301
+ if (message.auctionId !== void 0 && message.auctionId !== "") {
302
+ writer.uint32(34).string(message.auctionId);
303
+ }
304
+ if (message.transactionId !== void 0 && message.transactionId !== "") {
305
+ writer.uint32(42).string(message.transactionId);
306
+ }
307
+ if (message.adUnitCode !== void 0 && message.adUnitCode !== "") {
308
+ writer.uint32(50).string(message.adUnitCode);
309
+ }
310
+ if (message.bid !== void 0) {
311
+ BidTrace.encode(message.bid, writer.uint32(58).fork()).join();
312
+ }
313
+ if (message.namespace !== void 0 && message.namespace !== "") {
314
+ writer.uint32(66).string(message.namespace);
315
+ }
316
+ if (message.eventId !== void 0 && message.eventId !== "") {
317
+ writer.uint32(74).string(message.eventId);
318
+ }
319
+ globalThis.Object.entries(message.metadata || {}).forEach(([key, value]) => {
320
+ TraceEvent_MetadataEntry.encode({ key, value }, writer.uint32(82).fork()).join();
321
+ });
322
+ if (message.viewableDurationMs !== void 0) {
323
+ writer.uint32(89).double(message.viewableDurationMs);
324
+ }
325
+ return writer;
326
+ },
327
+ decode(input, length) {
328
+ const reader = input instanceof import_wire.BinaryReader ? input : new import_wire.BinaryReader(input);
329
+ const end = length === void 0 ? reader.len : reader.pos + length;
330
+ const message = createBaseTraceEvent();
331
+ while (reader.pos < end) {
332
+ const tag = reader.uint32();
333
+ switch (tag >>> 3) {
334
+ case 1: {
335
+ if (tag !== 9) {
336
+ break;
337
+ }
338
+ message.timestampMs = reader.double();
339
+ continue;
340
+ }
341
+ case 2: {
342
+ if (tag !== 16) {
343
+ break;
344
+ }
345
+ message.type = reader.int32();
346
+ continue;
347
+ }
348
+ case 3: {
349
+ if (tag !== 26) {
350
+ break;
351
+ }
352
+ message.eventName = reader.string();
353
+ continue;
354
+ }
355
+ case 4: {
356
+ if (tag !== 34) {
357
+ break;
358
+ }
359
+ message.auctionId = reader.string();
360
+ continue;
361
+ }
362
+ case 5: {
363
+ if (tag !== 42) {
364
+ break;
365
+ }
366
+ message.transactionId = reader.string();
367
+ continue;
368
+ }
369
+ case 6: {
370
+ if (tag !== 50) {
371
+ break;
372
+ }
373
+ message.adUnitCode = reader.string();
374
+ continue;
375
+ }
376
+ case 7: {
377
+ if (tag !== 58) {
378
+ break;
379
+ }
380
+ message.bid = BidTrace.decode(reader, reader.uint32());
381
+ continue;
382
+ }
383
+ case 8: {
384
+ if (tag !== 66) {
385
+ break;
386
+ }
387
+ message.namespace = reader.string();
388
+ continue;
389
+ }
390
+ case 9: {
391
+ if (tag !== 74) {
392
+ break;
393
+ }
394
+ message.eventId = reader.string();
395
+ continue;
396
+ }
397
+ case 10: {
398
+ if (tag !== 82) {
399
+ break;
400
+ }
401
+ const entry10 = TraceEvent_MetadataEntry.decode(reader, reader.uint32());
402
+ if (entry10.value !== void 0) {
403
+ message.metadata[entry10.key] = entry10.value;
404
+ }
405
+ continue;
406
+ }
407
+ case 11: {
408
+ if (tag !== 89) {
409
+ break;
410
+ }
411
+ message.viewableDurationMs = reader.double();
412
+ continue;
413
+ }
414
+ }
415
+ if ((tag & 7) === 4 || tag === 0) {
416
+ break;
417
+ }
418
+ reader.skip(tag & 7);
419
+ }
420
+ return message;
421
+ },
422
+ create(base) {
423
+ return TraceEvent.fromPartial(base ?? {});
424
+ },
425
+ fromPartial(object) {
426
+ const message = createBaseTraceEvent();
427
+ message.timestampMs = object.timestampMs ?? 0;
428
+ message.type = object.type ?? 0;
429
+ message.eventName = object.eventName ?? "";
430
+ message.auctionId = object.auctionId ?? "";
431
+ message.transactionId = object.transactionId ?? "";
432
+ message.adUnitCode = object.adUnitCode ?? "";
433
+ message.bid = object.bid !== void 0 && object.bid !== null ? BidTrace.fromPartial(object.bid) : void 0;
434
+ message.namespace = object.namespace ?? "";
435
+ message.eventId = object.eventId ?? "";
436
+ message.metadata = globalThis.Object.entries(object.metadata ?? {}).reduce(
437
+ (acc, [key, value]) => {
438
+ if (value !== void 0) {
439
+ acc[key] = globalThis.String(value);
440
+ }
441
+ return acc;
442
+ },
443
+ {}
444
+ );
445
+ message.viewableDurationMs = object.viewableDurationMs ?? void 0;
446
+ return message;
447
+ }
448
+ };
449
+ function createBaseTraceEvent_MetadataEntry() {
450
+ return { key: "", value: "" };
451
+ }
452
+ var TraceEvent_MetadataEntry = {
453
+ encode(message, writer = new import_wire.BinaryWriter()) {
454
+ if (message.key !== "") {
455
+ writer.uint32(10).string(message.key);
456
+ }
457
+ if (message.value !== "") {
458
+ writer.uint32(18).string(message.value);
459
+ }
460
+ return writer;
461
+ },
462
+ decode(input, length) {
463
+ const reader = input instanceof import_wire.BinaryReader ? input : new import_wire.BinaryReader(input);
464
+ const end = length === void 0 ? reader.len : reader.pos + length;
465
+ const message = createBaseTraceEvent_MetadataEntry();
466
+ while (reader.pos < end) {
467
+ const tag = reader.uint32();
468
+ switch (tag >>> 3) {
469
+ case 1: {
470
+ if (tag !== 10) {
471
+ break;
472
+ }
473
+ message.key = reader.string();
474
+ continue;
475
+ }
476
+ case 2: {
477
+ if (tag !== 18) {
478
+ break;
479
+ }
480
+ message.value = reader.string();
481
+ continue;
482
+ }
483
+ }
484
+ if ((tag & 7) === 4 || tag === 0) {
485
+ break;
486
+ }
487
+ reader.skip(tag & 7);
488
+ }
489
+ return message;
490
+ },
491
+ create(base) {
492
+ return TraceEvent_MetadataEntry.fromPartial(base ?? {});
493
+ },
494
+ fromPartial(object) {
495
+ const message = createBaseTraceEvent_MetadataEntry();
496
+ message.key = object.key ?? "";
497
+ message.value = object.value ?? "";
498
+ return message;
499
+ }
500
+ };
501
+ function createBaseBidTrace() {
502
+ return {
503
+ bidder: "",
504
+ cpm: 0,
505
+ currency: "",
506
+ width: 0,
507
+ height: 0,
508
+ dealId: "",
509
+ mediaType: "",
510
+ latencyMs: 0,
511
+ advertiserDomain: "",
512
+ creativeId: ""
513
+ };
514
+ }
515
+ var BidTrace = {
516
+ encode(message, writer = new import_wire.BinaryWriter()) {
517
+ if (message.bidder !== void 0 && message.bidder !== "") {
518
+ writer.uint32(10).string(message.bidder);
519
+ }
520
+ if (message.cpm !== void 0 && message.cpm !== 0) {
521
+ writer.uint32(17).double(message.cpm);
522
+ }
523
+ if (message.currency !== void 0 && message.currency !== "") {
524
+ writer.uint32(26).string(message.currency);
525
+ }
526
+ if (message.width !== void 0 && message.width !== 0) {
527
+ writer.uint32(32).int32(message.width);
528
+ }
529
+ if (message.height !== void 0 && message.height !== 0) {
530
+ writer.uint32(40).int32(message.height);
531
+ }
532
+ if (message.dealId !== void 0 && message.dealId !== "") {
533
+ writer.uint32(50).string(message.dealId);
534
+ }
535
+ if (message.mediaType !== void 0 && message.mediaType !== "") {
536
+ writer.uint32(58).string(message.mediaType);
537
+ }
538
+ if (message.latencyMs !== void 0 && message.latencyMs !== 0) {
539
+ writer.uint32(65).double(message.latencyMs);
540
+ }
541
+ if (message.advertiserDomain !== void 0 && message.advertiserDomain !== "") {
542
+ writer.uint32(74).string(message.advertiserDomain);
543
+ }
544
+ if (message.creativeId !== void 0 && message.creativeId !== "") {
545
+ writer.uint32(82).string(message.creativeId);
546
+ }
547
+ return writer;
548
+ },
549
+ decode(input, length) {
550
+ const reader = input instanceof import_wire.BinaryReader ? input : new import_wire.BinaryReader(input);
551
+ const end = length === void 0 ? reader.len : reader.pos + length;
552
+ const message = createBaseBidTrace();
553
+ while (reader.pos < end) {
554
+ const tag = reader.uint32();
555
+ switch (tag >>> 3) {
556
+ case 1: {
557
+ if (tag !== 10) {
558
+ break;
559
+ }
560
+ message.bidder = reader.string();
561
+ continue;
562
+ }
563
+ case 2: {
564
+ if (tag !== 17) {
565
+ break;
566
+ }
567
+ message.cpm = reader.double();
568
+ continue;
569
+ }
570
+ case 3: {
571
+ if (tag !== 26) {
572
+ break;
573
+ }
574
+ message.currency = reader.string();
575
+ continue;
576
+ }
577
+ case 4: {
578
+ if (tag !== 32) {
579
+ break;
580
+ }
581
+ message.width = reader.int32();
582
+ continue;
583
+ }
584
+ case 5: {
585
+ if (tag !== 40) {
586
+ break;
587
+ }
588
+ message.height = reader.int32();
589
+ continue;
590
+ }
591
+ case 6: {
592
+ if (tag !== 50) {
593
+ break;
594
+ }
595
+ message.dealId = reader.string();
596
+ continue;
597
+ }
598
+ case 7: {
599
+ if (tag !== 58) {
600
+ break;
601
+ }
602
+ message.mediaType = reader.string();
603
+ continue;
604
+ }
605
+ case 8: {
606
+ if (tag !== 65) {
607
+ break;
608
+ }
609
+ message.latencyMs = reader.double();
610
+ continue;
611
+ }
612
+ case 9: {
613
+ if (tag !== 74) {
614
+ break;
615
+ }
616
+ message.advertiserDomain = reader.string();
617
+ continue;
618
+ }
619
+ case 10: {
620
+ if (tag !== 82) {
621
+ break;
622
+ }
623
+ message.creativeId = reader.string();
624
+ continue;
625
+ }
626
+ }
627
+ if ((tag & 7) === 4 || tag === 0) {
628
+ break;
629
+ }
630
+ reader.skip(tag & 7);
631
+ }
632
+ return message;
633
+ },
634
+ create(base) {
635
+ return BidTrace.fromPartial(base ?? {});
636
+ },
637
+ fromPartial(object) {
638
+ const message = createBaseBidTrace();
639
+ message.bidder = object.bidder ?? "";
640
+ message.cpm = object.cpm ?? 0;
641
+ message.currency = object.currency ?? "";
642
+ message.width = object.width ?? 0;
643
+ message.height = object.height ?? 0;
644
+ message.dealId = object.dealId ?? "";
645
+ message.mediaType = object.mediaType ?? "";
646
+ message.latencyMs = object.latencyMs ?? 0;
647
+ message.advertiserDomain = object.advertiserDomain ?? "";
648
+ message.creativeId = object.creativeId ?? "";
649
+ return message;
650
+ }
651
+ };
652
+
653
+ // src/prebid-analytics.ts
654
+ var BATCH_SIZE = 20;
655
+ var FLUSH_INTERVAL_MS = 1e4;
656
+ var MAX_ERRORS_PER_SESSION = 50;
657
+ var MAX_QUEUE_SIZE = 200;
658
+ var MAX_SEND_BACKOFF_MS = 5 * 60 * 1e3;
659
+ var MAX_CONSECUTIVE_SEND_FAILURES = 10;
660
+ var EVENT_NAME_TO_TYPE = {
661
+ auctionStart: TraceEventType.AUCTION_START,
662
+ auctionEnd: TraceEventType.AUCTION_END,
663
+ bidRequest: TraceEventType.BID_REQUEST,
664
+ bidResponse: TraceEventType.BID_RESPONSE,
665
+ bidTimeout: TraceEventType.BID_TIMEOUT,
666
+ bidWin: TraceEventType.BID_WIN,
667
+ noBid: TraceEventType.NO_BID,
668
+ adRenderFailed: TraceEventType.AD_RENDER_FAILED,
669
+ click: TraceEventType.CLICK,
670
+ impression: TraceEventType.IMPRESSION,
671
+ refresh: TraceEventType.REFRESH,
672
+ timeInView: TraceEventType.TIME_IN_VIEW,
673
+ viewable: TraceEventType.VIEWABLE
674
+ };
675
+ var SESSION_KEY = "_bidkernel_session";
676
+ var SESSION_TS_KEY = "_bidkernel_session_ts";
677
+ var THIRTY_MINUTES_MS = 30 * 60 * 1e3;
678
+ var inMemorySessionId = null;
679
+ var inMemorySessionTs = 0;
680
+ function generateUUID() {
681
+ if (typeof crypto !== "undefined" && typeof crypto.randomUUID === "function") {
682
+ return crypto.randomUUID();
683
+ }
684
+ return "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g, (c) => {
685
+ const r = Math.random() * 16 | 0;
686
+ const v = c === "x" ? r : r & 3 | 8;
687
+ return v.toString(16);
688
+ });
689
+ }
690
+ function extendSession() {
691
+ const now = Date.now();
692
+ inMemorySessionTs = now;
693
+ try {
694
+ if (typeof localStorage !== "undefined") {
695
+ localStorage.setItem(SESSION_TS_KEY, now.toString());
696
+ }
697
+ } catch {
698
+ }
699
+ }
700
+ function getOrCreateSessionId() {
701
+ const now = Date.now();
702
+ try {
703
+ if (typeof localStorage !== "undefined") {
704
+ const storedId = localStorage.getItem(SESSION_KEY);
705
+ const tsStr = localStorage.getItem(SESSION_TS_KEY);
706
+ const storedTs = tsStr ? parseInt(tsStr, 10) || 0 : 0;
707
+ if (storedId && storedTs && now - storedTs <= THIRTY_MINUTES_MS) {
708
+ localStorage.setItem(SESSION_TS_KEY, now.toString());
709
+ return storedId;
710
+ }
711
+ const newId = generateUUID();
712
+ localStorage.setItem(SESSION_KEY, newId);
713
+ localStorage.setItem(SESSION_TS_KEY, now.toString());
714
+ return newId;
715
+ }
716
+ } catch {
717
+ }
718
+ if (inMemorySessionId && inMemorySessionTs && now - inMemorySessionTs <= THIRTY_MINUTES_MS) {
719
+ inMemorySessionTs = now;
720
+ return inMemorySessionId;
721
+ }
722
+ inMemorySessionId = generateUUID();
723
+ inMemorySessionTs = now;
724
+ return inMemorySessionId;
725
+ }
726
+ function getPrebidEventKey(eventName, data) {
727
+ switch (eventName) {
728
+ case "auctionInit":
729
+ return `auctionInit:${data?.auctionId || ""}`;
730
+ case "auctionEnd":
731
+ return `auctionEnd:${data?.auctionId || ""}`;
732
+ case "bidRequested":
733
+ return `bidRequested:${data?.auctionId || ""}:${data?.bidderCode || ""}:${Array.isArray(data?.bids) ? data.bids.map((b) => b?.bidId || b?.adUnitCode || "").join(",") : ""}`;
734
+ case "bidResponse":
735
+ return `bidResponse:${data?.auctionId || ""}:${data?.adUnitCode || ""}:${data?.bidderCode || data?.bidder || ""}:${data?.creativeId || data?.adId || data?.requestId || ""}:${data?.originalCpm ?? data?.cpm ?? ""}`;
736
+ case "bidTimeout":
737
+ if (Array.isArray(data)) {
738
+ return "bidTimeout:" + data.map(
739
+ (t) => `${t?.auctionId || ""}:${t?.bidder || t?.bidderCode || ""}:${t?.bidId || t?.adUnitCode || ""}`
740
+ ).join(",");
741
+ }
742
+ return `bidTimeout:${data?.auctionId || ""}:${data?.bidder || data?.bidderCode || ""}:${data?.bidId || data?.adUnitCode || ""}`;
743
+ case "bidWon":
744
+ return `bidWon:${data?.auctionId || ""}:${data?.adUnitCode || ""}:${data?.bidderCode || data?.bidder || ""}:${data?.creativeId || data?.adId || data?.requestId || ""}:${data?.originalCpm ?? data?.cpm ?? ""}`;
745
+ case "noBid":
746
+ return `noBid:${data?.auctionId || ""}:${data?.adUnitCode || ""}:${data?.bidderCode || data?.bidder || ""}:${data?.bidId || ""}`;
747
+ case "adRenderFailed":
748
+ return `adRenderFailed:${data?.bid?.auctionId || data?.auctionId || ""}:${data?.bid?.adUnitCode || data?.adUnitCode || ""}:${data?.bid?.bidderCode || data?.bid?.bidder || ""}:${data?.reason || ""}:${data?.message || ""}`;
749
+ case "adRenderSucceeded":
750
+ return `adRenderSucceeded:${data?.bid?.auctionId || data?.auctionId || ""}:${data?.bid?.adUnitCode || data?.adUnitCode || ""}:${data?.bid?.bidderCode || data?.bid?.bidder || ""}`;
751
+ case "setTargeting":
752
+ return `setTargeting:${Object.keys(data || {}).sort().join(",")}`;
753
+ case "auctionDebug":
754
+ return `auctionDebug:${data?.type || ""}:${String(data?.arguments?.[0] ?? "").slice(0, 50)}`;
755
+ default:
756
+ return "";
757
+ }
758
+ }
759
+ var PrebidEventDeduper = class {
760
+ seenObjects = /* @__PURE__ */ new WeakSet();
761
+ seenKeys = /* @__PURE__ */ new Set();
762
+ isDuplicate(eventName, data) {
763
+ if (!data) return false;
764
+ if (typeof data === "object") {
765
+ if (this.seenObjects.has(data)) return true;
766
+ this.seenObjects.add(data);
767
+ }
768
+ const key = getPrebidEventKey(eventName, data);
769
+ if (key) {
770
+ if (this.seenKeys.has(key)) return true;
771
+ if (this.seenKeys.size >= 1e3) {
772
+ const first = this.seenKeys.values().next().value;
773
+ if (first !== void 0) this.seenKeys.delete(first);
774
+ }
775
+ this.seenKeys.add(key);
776
+ }
777
+ return false;
778
+ }
779
+ };
780
+ function parseSize(raw) {
781
+ if (!raw) return { width: 0, height: 0 };
782
+ let cur = raw;
783
+ while (Array.isArray(cur) && cur.length > 0 && Array.isArray(cur[0])) {
784
+ cur = cur[0];
785
+ }
786
+ if (Array.isArray(cur) && cur.length >= 2) {
787
+ const w = Number(cur[0]);
788
+ const h = Number(cur[1]);
789
+ return {
790
+ width: Number.isFinite(w) ? w : 0,
791
+ height: Number.isFinite(h) ? h : 0
792
+ };
793
+ }
794
+ return { width: 0, height: 0 };
795
+ }
796
+ var BidkernelPrebidAnalytics = class {
797
+ config;
798
+ queue = [];
799
+ errorCount = 0;
800
+ flushTimer = null;
801
+ boundFlushBeacon;
802
+ boundVisibilityChange;
803
+ isEnabled = false;
804
+ boundPbjsHandlers = [];
805
+ // Captured at enable()/navigate() so events queued before an SPA route
806
+ // change flush with the page they occurred on, not the new URL.
807
+ pageUrl = "";
808
+ deduper = new PrebidEventDeduper();
809
+ consecutiveSendFailures = 0;
810
+ nextSendAllowedAt = 0;
811
+ constructor(config) {
812
+ this.config = {
813
+ endpoint: config.endpoint || "",
814
+ propertyId: config.propertyId || "",
815
+ pageviewId: config.pageviewId || generateUUID(),
816
+ sessionId: config.sessionId || getOrCreateSessionId(),
817
+ userId: config.userId || "",
818
+ deviceType: config.deviceType || "desktop",
819
+ country: config.country || "",
820
+ region: config.region || "",
821
+ auctionEnabled: config.auctionEnabled ?? true,
822
+ warningsEnabled: config.warningsEnabled ?? true,
823
+ errorsEnabled: config.errorsEnabled ?? true,
824
+ logLevel: config.logLevel || "INFO",
825
+ pbjsGlobalName: config.pbjsGlobalName || "pbjs",
826
+ attachPbjsListeners: config.attachPbjsListeners ?? true
827
+ };
828
+ this.boundFlushBeacon = () => this.flushBeacon();
829
+ this.boundVisibilityChange = () => this.handleVisibilityChange();
830
+ }
831
+ enable() {
832
+ if (this.isEnabled) return;
833
+ this.isEnabled = true;
834
+ if (!this.config.endpoint) {
835
+ this.log("WARN", "Endpoint is empty. Analytics events will not be transmitted.");
836
+ }
837
+ if (this.config.attachPbjsListeners) {
838
+ const win = typeof window !== "undefined" ? window : {};
839
+ const pbjs = win[this.config.pbjsGlobalName] || {};
840
+ if (typeof pbjs.onEvent === "function") {
841
+ this.log("DEBUG", "Attaching event listeners to pbjs");
842
+ const events = [
843
+ ["auctionInit", this.handleAuctionInit.bind(this)],
844
+ ["auctionEnd", this.handleAuctionEnd.bind(this)],
845
+ ["bidRequested", this.handleBidRequested.bind(this)],
846
+ ["bidResponse", this.handleBidResponse.bind(this)],
847
+ ["bidTimeout", this.handleBidTimeout.bind(this)],
848
+ ["bidWon", this.handleBidWon.bind(this)],
849
+ ["noBid", this.handleNoBid.bind(this)],
850
+ ["adRenderFailed", this.handleAdRenderFailed.bind(this)]
851
+ ];
852
+ for (const [name, fn] of events) {
853
+ pbjs.onEvent(name, fn);
854
+ this.boundPbjsHandlers.push({ event: name, handler: fn });
855
+ }
856
+ } else {
857
+ this.log("WARN", "pbjs.onEvent is not defined. Prebid analytics will not function.");
858
+ }
859
+ if (typeof pbjs.getEvents === "function") {
860
+ try {
861
+ const pastEvents = pbjs.getEvents();
862
+ if (Array.isArray(pastEvents)) {
863
+ this.log(
864
+ "DEBUG",
865
+ `Replaying ${pastEvents.length} historical events from pbjs.getEvents()`
866
+ );
867
+ const handlerMap = {
868
+ auctionInit: this.handleAuctionInit.bind(this),
869
+ auctionEnd: this.handleAuctionEnd.bind(this),
870
+ bidRequested: this.handleBidRequested.bind(this),
871
+ bidResponse: this.handleBidResponse.bind(this),
872
+ bidTimeout: this.handleBidTimeout.bind(this),
873
+ bidWon: this.handleBidWon.bind(this),
874
+ noBid: this.handleNoBid.bind(this),
875
+ adRenderFailed: this.handleAdRenderFailed.bind(this)
876
+ };
877
+ for (const ev of pastEvents) {
878
+ if (!ev) continue;
879
+ const eventType = ev.eventType || ev.event || ev.name;
880
+ const args = ev.args !== void 0 ? ev.args : ev.data !== void 0 ? ev.data : ev;
881
+ const handler = handlerMap[eventType];
882
+ if (handler) {
883
+ handler(args);
884
+ }
885
+ }
886
+ }
887
+ } catch (e) {
888
+ this.log("WARN", "Failed to replay historical events from pbjs.getEvents()", e);
889
+ }
890
+ }
891
+ }
892
+ if (typeof window !== "undefined") {
893
+ if (!this.pageUrl) {
894
+ try {
895
+ const u = new URL(window.location.href);
896
+ this.pageUrl = u.origin + u.pathname;
897
+ } catch {
898
+ this.pageUrl = window.location.href;
899
+ }
900
+ }
901
+ window.addEventListener("pagehide", this.boundFlushBeacon);
902
+ if (typeof document !== "undefined") {
903
+ document.addEventListener("visibilitychange", this.boundVisibilityChange);
904
+ }
905
+ this.flushTimer = setInterval(() => this.flush(), FLUSH_INTERVAL_MS);
906
+ }
907
+ }
908
+ disable() {
909
+ if (!this.isEnabled) return;
910
+ this.isEnabled = false;
911
+ if (this.flushTimer) {
912
+ clearInterval(this.flushTimer);
913
+ this.flushTimer = null;
914
+ }
915
+ if (typeof window !== "undefined") {
916
+ window.removeEventListener("pagehide", this.boundFlushBeacon);
917
+ if (typeof document !== "undefined") {
918
+ document.removeEventListener("visibilitychange", this.boundVisibilityChange);
919
+ }
920
+ }
921
+ if (this.boundPbjsHandlers.length > 0) {
922
+ const win = typeof window !== "undefined" ? window : {};
923
+ const pbjs = win[this.config.pbjsGlobalName] || {};
924
+ if (typeof pbjs.offEvent === "function") {
925
+ for (const { event, handler } of this.boundPbjsHandlers) {
926
+ pbjs.offEvent(event, handler);
927
+ }
928
+ }
929
+ this.boundPbjsHandlers = [];
930
+ }
931
+ this.flush();
932
+ }
933
+ handleVisibilityChange() {
934
+ if (typeof document !== "undefined" && document.visibilityState === "hidden") {
935
+ this.flushBeacon();
936
+ }
937
+ }
938
+ trackRawEvent(level, eventName, data) {
939
+ const eventType = EVENT_NAME_TO_TYPE[eventName] ?? (level === "ERROR" ? TraceEventType.ERROR : TraceEventType.TRACE_EVENT_TYPE_UNSPECIFIED);
940
+ this.enqueue(eventType, eventName, data, level);
941
+ }
942
+ setUserId(userId) {
943
+ this.config.userId = userId;
944
+ }
945
+ setSessionId(sessionId) {
946
+ this.config.sessionId = sessionId;
947
+ }
948
+ navigate(pageviewId, pageUrl) {
949
+ this.disable();
950
+ this.config.pageviewId = pageviewId || generateUUID();
951
+ if (pageUrl) {
952
+ try {
953
+ const u = new URL(pageUrl);
954
+ this.pageUrl = u.origin + u.pathname;
955
+ } catch {
956
+ this.pageUrl = pageUrl;
957
+ }
958
+ } else {
959
+ this.pageUrl = "";
960
+ }
961
+ extendSession();
962
+ this.enable();
963
+ }
964
+ handleAuctionInit(data) {
965
+ if (this.isDuplicate("auctionInit", data)) return;
966
+ this.log("DEBUG", "auctionInit", data);
967
+ this.enqueue(TraceEventType.AUCTION_START, "auctionStart", {
968
+ auctionId: data.auctionId || ""
969
+ });
970
+ }
971
+ handleAuctionEnd(data) {
972
+ if (this.isDuplicate("auctionEnd", data)) return;
973
+ this.log("DEBUG", "auctionEnd", data);
974
+ this.enqueue(TraceEventType.AUCTION_END, "auctionEnd", {
975
+ auctionId: data.auctionId || ""
976
+ });
977
+ }
978
+ handleBidRequested(data) {
979
+ if (this.isDuplicate("bidRequested", data)) return;
980
+ this.log("DEBUG", "bidRequested", data);
981
+ const auctionId = data.auctionId || "";
982
+ const bidder = data.bidderCode || "";
983
+ if (Array.isArray(data.bids)) {
984
+ data.bids.forEach((bid) => {
985
+ const mediaTypes = Object.keys(bid.mediaTypes || {});
986
+ const gpid = bid.ortb2Imp?.ext?.gpid || bid.gpid || data.gpid || "";
987
+ if (mediaTypes.length === 0) {
988
+ const mediaType = bid.mediaType || "banner";
989
+ const { width, height } = parseSize(bid.sizes || bid.playerSize);
990
+ this.enqueue(TraceEventType.BID_REQUEST, "bidRequest", {
991
+ auctionId,
992
+ adUnitCode: bid.adUnitCode || "",
993
+ gpid,
994
+ bid: {
995
+ bidder,
996
+ mediaType,
997
+ width,
998
+ height
999
+ }
1000
+ });
1001
+ return;
1002
+ }
1003
+ mediaTypes.forEach((mediaType) => {
1004
+ let rawSize = null;
1005
+ if (mediaType === "banner") {
1006
+ rawSize = bid.mediaTypes?.banner?.sizes || bid.sizes;
1007
+ } else if (mediaType === "video") {
1008
+ rawSize = bid.mediaTypes?.video?.playerSize || bid.mediaTypes?.video?.sizes || bid.playerSize;
1009
+ } else {
1010
+ rawSize = bid.mediaTypes?.[mediaType]?.sizes;
1011
+ }
1012
+ const { width, height } = parseSize(rawSize);
1013
+ this.enqueue(TraceEventType.BID_REQUEST, "bidRequest", {
1014
+ auctionId,
1015
+ adUnitCode: bid.adUnitCode || "",
1016
+ gpid,
1017
+ bid: {
1018
+ bidder,
1019
+ mediaType,
1020
+ width,
1021
+ height
1022
+ }
1023
+ });
1024
+ });
1025
+ });
1026
+ }
1027
+ }
1028
+ handleBidResponse(data) {
1029
+ if (this.isDuplicate("bidResponse", data)) return;
1030
+ this.log("DEBUG", "bidResponse", data);
1031
+ this.enqueue(TraceEventType.BID_RESPONSE, "bidResponse", {
1032
+ auctionId: data.auctionId || "",
1033
+ adUnitCode: data.adUnitCode || "",
1034
+ bid: {
1035
+ bidder: data.bidderCode || data.bidder || "",
1036
+ cpm: Number.isFinite(data.originalCpm) ? data.originalCpm : Number.isFinite(data.cpm) ? data.cpm : 0,
1037
+ currency: data.originalCurrency ?? data.currency ?? "USD",
1038
+ width: Number.isFinite(data.width) ? data.width : 0,
1039
+ height: Number.isFinite(data.height) ? data.height : 0,
1040
+ dealId: data.dealId || "",
1041
+ mediaType: data.mediaType || "banner",
1042
+ latencyMs: Number.isFinite(data.timeToRespond) ? data.timeToRespond : 0,
1043
+ advertiserDomain: data.meta?.advertiserDomains?.[0] || "",
1044
+ creativeId: data.creativeId || ""
1045
+ }
1046
+ });
1047
+ }
1048
+ handleBidTimeout(data) {
1049
+ if (this.isDuplicate("bidTimeout", data)) return;
1050
+ this.log("DEBUG", "bidTimeout", data);
1051
+ if (Array.isArray(data)) {
1052
+ data.forEach((t) => {
1053
+ this.enqueue(TraceEventType.BID_TIMEOUT, "bidTimeout", {
1054
+ auctionId: t.auctionId || "",
1055
+ adUnitCode: t.adUnitCode || "",
1056
+ bid: {
1057
+ bidder: t.bidder || ""
1058
+ }
1059
+ });
1060
+ });
1061
+ }
1062
+ }
1063
+ handleBidWon(data) {
1064
+ if (this.isDuplicate("bidWon", data)) return;
1065
+ this.log("DEBUG", "bidWon", data);
1066
+ this.enqueue(TraceEventType.BID_WIN, "bidWon", {
1067
+ auctionId: data.auctionId || "",
1068
+ adUnitCode: data.adUnitCode || "",
1069
+ bid: {
1070
+ bidder: data.bidderCode || data.bidder || "",
1071
+ cpm: Number.isFinite(data.originalCpm) ? data.originalCpm : Number.isFinite(data.cpm) ? data.cpm : 0,
1072
+ currency: data.originalCurrency ?? data.currency ?? "USD",
1073
+ width: Number.isFinite(data.width) ? data.width : 0,
1074
+ height: Number.isFinite(data.height) ? data.height : 0,
1075
+ dealId: data.dealId || "",
1076
+ mediaType: data.mediaType || "banner",
1077
+ latencyMs: Number.isFinite(data.timeToRespond) ? data.timeToRespond : 0,
1078
+ advertiserDomain: data.meta?.advertiserDomains?.[0] || "",
1079
+ creativeId: data.creativeId || ""
1080
+ }
1081
+ });
1082
+ }
1083
+ handleNoBid(data) {
1084
+ if (this.isDuplicate("noBid", data)) return;
1085
+ this.log("DEBUG", "noBid", data);
1086
+ this.enqueue(TraceEventType.NO_BID, "noBid", {
1087
+ auctionId: data.auctionId || "",
1088
+ adUnitCode: data.adUnitCode || "",
1089
+ bid: {
1090
+ bidder: data.bidderCode || data.bidder || ""
1091
+ }
1092
+ });
1093
+ }
1094
+ handleAdRenderFailed(data) {
1095
+ if (this.isDuplicate("adRenderFailed", data)) return;
1096
+ this.log("DEBUG", "adRenderFailed", data);
1097
+ this.enqueue(TraceEventType.AD_RENDER_FAILED, "adRenderFailed", {
1098
+ auctionId: data.bid?.auctionId || "",
1099
+ adUnitCode: data.bid?.adUnitCode || "",
1100
+ bid: {
1101
+ bidder: data.bid?.bidderCode || data.bid?.bidder || ""
1102
+ },
1103
+ metadata: {
1104
+ reason: String(data.reason || ""),
1105
+ message: String(data.message || "")
1106
+ }
1107
+ });
1108
+ }
1109
+ isDuplicate(eventName, data) {
1110
+ return this.deduper.isDuplicate(eventName, data);
1111
+ }
1112
+ enqueue(type, eventName, data, level) {
1113
+ if (!this.isEnabled) return;
1114
+ if (!this.shouldSample(type, level)) return;
1115
+ const protoEvent = {
1116
+ eventId: generateUUID(),
1117
+ timestampMs: Date.now(),
1118
+ type,
1119
+ eventName,
1120
+ auctionId: data.auctionId || "",
1121
+ transactionId: data.transactionId || "",
1122
+ adUnitCode: data.adUnitCode || data.elementId || "",
1123
+ namespace: data.ns || data.namespace || ""
1124
+ };
1125
+ if (data.bid) {
1126
+ protoEvent.bid = {
1127
+ bidder: data.bid.bidder || "",
1128
+ cpm: Number.isFinite(data.bid.cpm) ? data.bid.cpm : 0,
1129
+ currency: data.bid.currency || "USD",
1130
+ width: Number.isFinite(data.bid.width) ? data.bid.width : 0,
1131
+ height: Number.isFinite(data.bid.height) ? data.bid.height : 0,
1132
+ dealId: data.bid.dealId || "",
1133
+ mediaType: data.bid.mediaType || "banner",
1134
+ latencyMs: Number.isFinite(data.bid.latencyMs) ? data.bid.latencyMs : 0,
1135
+ advertiserDomain: data.bid.advertiserDomain || "",
1136
+ creativeId: data.bid.creativeId || ""
1137
+ };
1138
+ }
1139
+ if (data.viewableDurationMs !== void 0) {
1140
+ protoEvent.viewableDurationMs = Number.isFinite(data.viewableDurationMs) ? data.viewableDurationMs : 0;
1141
+ }
1142
+ const metadata = { ...data.metadata };
1143
+ if (data.error !== void 0 && data.error !== null) {
1144
+ metadata.error = typeof data.error === "object" && data.error.message ? String(data.error.message) : String(data.error);
1145
+ }
1146
+ if (data.gpid) {
1147
+ metadata.gpid = String(data.gpid);
1148
+ }
1149
+ if (Object.keys(metadata).length > 0) {
1150
+ protoEvent.metadata = metadata;
1151
+ }
1152
+ this.queue.push(protoEvent);
1153
+ if (this.queue.length > MAX_QUEUE_SIZE) {
1154
+ this.queue.splice(0, this.queue.length - MAX_QUEUE_SIZE);
1155
+ }
1156
+ if (this.queue.length >= BATCH_SIZE) {
1157
+ this.flush();
1158
+ }
1159
+ }
1160
+ shouldSample(type, level) {
1161
+ if (type === TraceEventType.ERROR) {
1162
+ this.errorCount++;
1163
+ if (this.errorCount > MAX_ERRORS_PER_SESSION) return false;
1164
+ return this.config.errorsEnabled;
1165
+ }
1166
+ if (level === "WARN") {
1167
+ return this.config.warningsEnabled;
1168
+ }
1169
+ return this.config.auctionEnabled;
1170
+ }
1171
+ requeue(events) {
1172
+ if (!events.length) return;
1173
+ this.queue = events.concat(this.queue);
1174
+ if (this.queue.length > MAX_QUEUE_SIZE) {
1175
+ this.queue.splice(0, this.queue.length - MAX_QUEUE_SIZE);
1176
+ }
1177
+ }
1178
+ // Drains the queue and returns the encoded batch plus target URL and event list,
1179
+ // or null if there is nothing to send. Shared by flush() and flushBeacon().
1180
+ drainBatch() {
1181
+ if (this.queue.length === 0 || !this.config.endpoint) return null;
1182
+ const events = this.queue;
1183
+ this.queue = [];
1184
+ const domain = typeof window !== "undefined" ? window.location.hostname : "";
1185
+ const batch = {
1186
+ propertyId: this.config.propertyId,
1187
+ pageviewId: this.config.pageviewId,
1188
+ sessionId: this.config.sessionId,
1189
+ pageUrl: this.pageUrl,
1190
+ country: this.config.country,
1191
+ region: this.config.region,
1192
+ deviceType: this.config.deviceType,
1193
+ userId: this.config.userId,
1194
+ domain,
1195
+ events
1196
+ };
1197
+ return {
1198
+ url: `${this.config.endpoint}/${this.config.propertyId}`,
1199
+ // protobufjs types finish() as Uint8Array<ArrayBufferLike>; the buffer is
1200
+ // always a plain ArrayBuffer, so narrow for fetch/Blob compatibility.
1201
+ encoded: TraceEventBatch.encode(batch).finish(),
1202
+ events
1203
+ };
1204
+ }
1205
+ sendFetch(payload) {
1206
+ fetch(payload.url, {
1207
+ method: "POST",
1208
+ headers: { "Content-Type": "application/x-protobuf" },
1209
+ body: payload.encoded,
1210
+ keepalive: true
1211
+ }).then((res) => {
1212
+ if (!res.ok) {
1213
+ this.log("WARN", `Failed to send batch: HTTP ${res.status}`);
1214
+ this.handleSendFailure(payload.events);
1215
+ } else {
1216
+ this.consecutiveSendFailures = 0;
1217
+ this.nextSendAllowedAt = 0;
1218
+ }
1219
+ }).catch((err) => {
1220
+ this.log("ERROR", "Failed to send batch", err);
1221
+ this.handleSendFailure(payload.events);
1222
+ });
1223
+ }
1224
+ handleSendFailure(events) {
1225
+ this.consecutiveSendFailures++;
1226
+ const backoff = Math.min(
1227
+ FLUSH_INTERVAL_MS * 2 ** (this.consecutiveSendFailures - 1),
1228
+ MAX_SEND_BACKOFF_MS
1229
+ );
1230
+ this.nextSendAllowedAt = Date.now() + backoff;
1231
+ if (this.consecutiveSendFailures <= MAX_CONSECUTIVE_SEND_FAILURES) {
1232
+ this.requeue(events);
1233
+ } else {
1234
+ this.log(
1235
+ "WARN",
1236
+ `Dropping ${events.length} events after ${this.consecutiveSendFailures} consecutive send failures`
1237
+ );
1238
+ }
1239
+ }
1240
+ flush() {
1241
+ if (Date.now() < this.nextSendAllowedAt) return;
1242
+ const payload = this.drainBatch();
1243
+ if (!payload) return;
1244
+ this.sendFetch(payload);
1245
+ }
1246
+ flushBeacon() {
1247
+ const payload = this.drainBatch();
1248
+ if (!payload) return;
1249
+ let sent = false;
1250
+ if (typeof navigator !== "undefined" && typeof navigator.sendBeacon === "function") {
1251
+ try {
1252
+ const blob = new Blob([payload.encoded], { type: "application/x-protobuf" });
1253
+ sent = navigator.sendBeacon(payload.url, blob);
1254
+ } catch {
1255
+ sent = false;
1256
+ }
1257
+ }
1258
+ if (!sent) {
1259
+ this.sendFetch(payload);
1260
+ }
1261
+ }
1262
+ log(level, msg, ...args) {
1263
+ const levels = { DEBUG: 10, INFO: 20, WARN: 30, ERROR: 40 };
1264
+ if (levels[level] < levels[this.config.logLevel]) return;
1265
+ const prefix = `[bidkernel][prebid-analytics][${level}]`;
1266
+ switch (level) {
1267
+ case "DEBUG":
1268
+ console.debug(prefix, msg, ...args);
1269
+ break;
1270
+ case "INFO":
1271
+ console.info(prefix, msg, ...args);
1272
+ break;
1273
+ case "WARN":
1274
+ console.warn(prefix, msg, ...args);
1275
+ break;
1276
+ case "ERROR":
1277
+ console.error(prefix, msg, ...args);
1278
+ break;
1279
+ }
1280
+ }
1281
+ };
1282
+ function extractAnalyticsOptions(config) {
1283
+ if (!config) return null;
1284
+ if (Array.isArray(config)) {
1285
+ const matched = config.find((item) => item?.provider === "bidkernel") ?? config.find((item) => item && typeof item === "object" && item.provider === void 0);
1286
+ return matched ? extractAnalyticsOptions(matched) : null;
1287
+ }
1288
+ if (typeof config === "object") {
1289
+ if (config.options && typeof config.options === "object") {
1290
+ return config.options;
1291
+ }
1292
+ if (config.config && typeof config.config === "object") {
1293
+ return config.config;
1294
+ }
1295
+ if (config.propertyId || config.endpoint) {
1296
+ return config;
1297
+ }
1298
+ }
1299
+ return null;
1300
+ }
1301
+ function getStashedConfig(win) {
1302
+ if (!win) return null;
1303
+ if (win._bidkernelAnalyticsConfig) {
1304
+ const extracted = extractAnalyticsOptions(win._bidkernelAnalyticsConfig);
1305
+ if (extracted) return extracted;
1306
+ }
1307
+ if (win.bidkernelPrebidAnalytics) {
1308
+ const bpa = win.bidkernelPrebidAnalytics;
1309
+ if (bpa.options) {
1310
+ const extracted = extractAnalyticsOptions(bpa.options);
1311
+ if (extracted) return extracted;
1312
+ }
1313
+ if (bpa.config) {
1314
+ const extracted = extractAnalyticsOptions(bpa.config);
1315
+ if (extracted) return extracted;
1316
+ }
1317
+ if (bpa.propertyId) {
1318
+ return extractAnalyticsOptions(bpa);
1319
+ }
1320
+ }
1321
+ return null;
1322
+ }
1323
+ function registerPrebidAnalytics(pbjsGlobalName = "pbjs", defaults) {
1324
+ const win = typeof window !== "undefined" ? window : {};
1325
+ win[pbjsGlobalName] = win[pbjsGlobalName] || {};
1326
+ const pbjs = win[pbjsGlobalName];
1327
+ const enableInstance = (options) => {
1328
+ if (win._bidkernelPrebidAnalytics) {
1329
+ try {
1330
+ win._bidkernelPrebidAnalytics.disable();
1331
+ } catch (e) {
1332
+ console.warn("[bidkernel] Failed to disable previous analytics instance:", e);
1333
+ }
1334
+ }
1335
+ const analytics = new BidkernelPrebidAnalytics({
1336
+ pbjsGlobalName,
1337
+ ...defaults,
1338
+ ...options
1339
+ });
1340
+ analytics.enable();
1341
+ win._bidkernelPrebidAnalytics = analytics;
1342
+ return analytics;
1343
+ };
1344
+ const doRegister = () => {
1345
+ try {
1346
+ if (pbjs.adapterManager && typeof pbjs.adapterManager.registerAnalyticsAdapter === "function") {
1347
+ pbjs.adapterManager.registerAnalyticsAdapter({
1348
+ adapter: {
1349
+ enableAnalytics: (config) => {
1350
+ const options = extractAnalyticsOptions(config);
1351
+ if (options) {
1352
+ enableInstance(options);
1353
+ }
1354
+ },
1355
+ disableAnalytics: () => {
1356
+ if (win._bidkernelPrebidAnalytics) {
1357
+ win._bidkernelPrebidAnalytics.disable();
1358
+ }
1359
+ }
1360
+ },
1361
+ code: "bidkernel"
1362
+ });
1363
+ }
1364
+ const stashed = getStashedConfig(win);
1365
+ if (stashed && (stashed.propertyId || defaults?.propertyId)) {
1366
+ enableInstance(stashed);
1367
+ }
1368
+ } catch (e) {
1369
+ console.warn("[bidkernel] Failed to register standard Prebid analytics adapter:", e);
1370
+ }
1371
+ };
1372
+ if (pbjs.adapterManager && typeof pbjs.adapterManager.registerAnalyticsAdapter === "function") {
1373
+ doRegister();
1374
+ } else {
1375
+ pbjs.que = pbjs.que || [];
1376
+ pbjs.que.push(doRegister);
1377
+ }
1378
+ }
1379
+
1380
+ // src/index.ts
1381
+ function getbidkernel(alias = "bidkernel") {
1382
+ if (typeof window === "undefined") {
1383
+ return { q: [] };
1384
+ }
1385
+ const win = window;
1386
+ win[alias] = win[alias] || { q: [] };
1387
+ return win[alias];
1388
+ }
1389
+ // Annotate the CommonJS export names for ESM import in node:
1390
+ 0 && (module.exports = {
1391
+ BidkernelPrebidAnalytics,
1392
+ PrebidEventDeduper,
1393
+ getPrebidEventKey,
1394
+ getbidkernel,
1395
+ registerPrebidAnalytics
1396
+ });