@bidkernel/analytics 0.3.0 → 0.4.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 CHANGED
@@ -52,21 +52,54 @@ analytics.enable();
52
52
 
53
53
  ## Configuration
54
54
 
55
- | Option | Default | Description |
56
- | ------------------------------------- | -------------- | -------------------------------------------------------------------- |
57
- | `endpoint` | — | Ingest base URL; events POST to `{endpoint}/{propertyId}`. The standalone bundle defaults it to `https://by.bidkernel.io/t`. |
58
- | `propertyId` | — | Your Bidkernel property ID. |
59
- | `pbjsGlobalName` | `"pbjs"` | Window global holding the Prebid instance (for renamed installs). |
60
- | `attachPbjsListeners` | `true` | Set `false` when events are fed via `trackRawEvent` (full SDK mode). |
61
- | `auctionEnabled` | `true` | Collect auction lifecycle events. |
62
- | `warningsEnabled` | `true` | Collect warning events. |
63
- | `errorsEnabled` | `true` | Collect error events (capped per session). |
64
- | `userId` / `sessionId` / `pageviewId` | generated | Override identity; a 30-minute rolling session is managed otherwise. |
65
- | `deviceType` / `country` / `region` | server-derived | Optional client hints; ingest resolves these server-side. |
66
- | `logLevel` | `"INFO"` | Console log verbosity. |
55
+ | Option | Default | Description |
56
+ | ----------------------------------- | -------------- | ---------------------------------------------------------------------------------------------------------------------------- |
57
+ | `endpoint` | — | Ingest base URL; events POST to `{endpoint}/{propertyId}`. The standalone bundle defaults it to `https://by.bidkernel.io/t`. |
58
+ | `propertyId` | — | Your Bidkernel property ID. |
59
+ | `pbjsGlobalName` | `"pbjs"` | Window global holding the Prebid instance (for renamed installs). |
60
+ | `attachPbjsListeners` | `true` | Set `false` when events are fed via `trackRawEvent` (full SDK mode). |
61
+ | `auctionEnabled` | `true` | Collect auction lifecycle events. |
62
+ | `warningsEnabled` | `true` | Collect warning events. |
63
+ | `errorsEnabled` | `true` | Collect error events (capped per session). |
64
+ | `userId` | `""` (empty) | **Not generated you must pass it.** See [User identity](#user-identity). |
65
+ | `sessionId` / `pageviewId` | generated | Override identity; a 30-minute rolling session is managed otherwise. |
66
+ | `deviceType` / `country` / `region` | server-derived | Optional client hints; ingest resolves these server-side. |
67
+ | `logLevel` | `"INFO"` | Console log verbosity. |
67
68
 
68
69
  SPA navigations: call `analytics.navigate(newPageviewId, newUrl)` to flush the old pageview and continue under the new one.
69
70
 
71
+ ## User identity
72
+
73
+ Unlike `sessionId` and `pageviewId`, the adapter never generates a `userId`.
74
+ The full edge-served Bidkernel SDK receives a persistent first-party user id
75
+ in its server-injected config; the npm adapter has no such source, so unless
76
+ you supply one, every event lands in the warehouse with a NULL `user_id` and
77
+ unique-user metrics are empty.
78
+
79
+ Pass your own stable identifier (a first-party cookie or your login user id —
80
+ never PII) when enabling analytics:
81
+
82
+ ```js
83
+ pbjs.enableAnalytics([
84
+ {
85
+ provider: "bidkernel",
86
+ options: {
87
+ propertyId: "YOUR_PROPERTY_ID",
88
+ userId: getOrCreateFirstPartyUserId(), // e.g. a cookie-backed UUID
89
+ },
90
+ },
91
+ ]);
92
+ ```
93
+
94
+ Or set it later (e.g. once consent resolves) on a direct instance:
95
+
96
+ ```js
97
+ analytics.setUserId(userId);
98
+ ```
99
+
100
+ Only events flushed after `setUserId` carry the id — batches are stamped at
101
+ send time, so set it as early as possible.
102
+
70
103
  ## Releasing
71
104
 
72
105
  Publishing is automated by
@@ -1 +1 @@
1
- "use strict";var bidkernelPrebidAnalyticsBundle=(()=>{var l=(t,e)=>()=>(t&&(e=t(t=0)),e);var le=(t,e)=>()=>(e||t((e={exports:{}}).exports,e),e.exports);function q(){let t=0,e=0;for(let i=0;i<28;i+=7){let r=this.buf[this.pos++];if(t|=(r&127)<<i,(r&128)==0)return this.assertBounds(),[t,e]}let n=this.buf[this.pos++];if(t|=(n&15)<<28,e=(n&112)>>4,(n&128)==0)return this.assertBounds(),[t,e];for(let i=3;i<=31;i+=7){let r=this.buf[this.pos++];if(e|=(r&127)<<i,(r&128)==0)return this.assertBounds(),[t,e]}throw new Error("invalid varint")}function E(t,e,n){for(let s=0;s<28;s=s+7){let o=t>>>s,d=!(!(o>>>7)&&e==0),a=(d?o|128:o)&255;if(n.push(a),!d)return}let i=t>>>28&15|(e&7)<<4,r=e>>3!=0;if(n.push((r?i|128:i)&255),!!r){for(let s=3;s<31;s=s+7){let o=e>>>s,d=!!(o>>>7),a=(d?o|128:o)&255;if(n.push(a),!d)return}n.push(e>>>31&1)}}function B(t){let e=t[0]==="-";e&&(t=t.slice(1));let n=1e6,i=0,r=0;function s(o,d){let a=Number(t.slice(o,d));r*=n,i=i*n+a,i>=T&&(r=r+(i/T|0),i=i%T)}return s(-24,-18),s(-18,-12),s(-12,-6),s(-6),e?W(i,r):k(i,r)}function V(t,e){let n=k(t,e),i=n.hi&2147483648;i&&(n=W(n.lo,n.hi));let r=A(n.lo,n.hi);return i?"-"+r:r}function A(t,e){if({lo:t,hi:e}=he(t,e),e<=2097151)return String(T*e+t);let n=t&16777215,i=(t>>>24|e<<8)&16777215,r=e>>16&65535,s=n+i*6777216+r*6710656,o=i+r*8147497,d=r*2,a=1e7;return s>=a&&(o+=Math.floor(s/a),s%=a),o>=a&&(d+=Math.floor(o/a),o%=a),d.toString()+$(o)+$(s)}function he(t,e){return{lo:t>>>0,hi:e>>>0}}function k(t,e){return{lo:t|0,hi:e|0}}function W(t,e){return e=~e,t?t=~t+1:e+=1,k(t,e)}function R(t,e){if(t>=0){for(;t>127;)e.push(t&127|128),t=t>>>7;e.push(t)}else{for(let n=0;n<9;n++)e.push(t&127|128),t=t>>7;e.push(1)}}function G(){let t=this.buf[this.pos++],e=t&127;if((t&128)==0)return this.assertBounds(),e;if(t=this.buf[this.pos++],e|=(t&127)<<7,(t&128)==0)return this.assertBounds(),e;if(t=this.buf[this.pos++],e|=(t&127)<<14,(t&128)==0)return this.assertBounds(),e;if(t=this.buf[this.pos++],e|=(t&127)<<21,(t&128)==0)return this.assertBounds(),e;t=this.buf[this.pos++],e|=(t&15)<<28;for(let n=5;(t&128)!==0&&n<10;n++)t=this.buf[this.pos++];if((t&128)!=0)throw new Error("invalid varint");return this.assertBounds(),e>>>0}var T,$,U=l(()=>{"use strict";T=4294967296;$=t=>{let e=String(t);return"0000000".slice(e.length)+e}});function pe(){let t=new DataView(new ArrayBuffer(8));if(typeof BigInt=="function"&&typeof t.getBigInt64=="function"&&typeof t.getBigUint64=="function"&&typeof t.setBigInt64=="function"&&typeof t.setBigUint64=="function"&&(!!globalThis.Deno||typeof process!="object"||typeof process.env!="object"||process.env.BUF_BIGINT_DISABLE!=="1")){let n=BigInt("-9223372036854775808"),i=BigInt("9223372036854775807"),r=BigInt("0"),s=BigInt("18446744073709551615");return{zero:BigInt(0),supported:!0,parse(o){let d=typeof o=="bigint"?o:BigInt(o);if(d>i||d<n)throw new Error(`invalid int64: ${o}`);return d},uParse(o){let d=typeof o=="bigint"?o:BigInt(o);if(d>s||d<r)throw new Error(`invalid uint64: ${o}`);return d},enc(o){return t.setBigInt64(0,this.parse(o),!0),{lo:t.getInt32(0,!0),hi:t.getInt32(4,!0)}},uEnc(o){return t.setBigInt64(0,this.uParse(o),!0),{lo:t.getInt32(0,!0),hi:t.getInt32(4,!0)}},dec(o,d){return t.setInt32(0,o,!0),t.setInt32(4,d,!0),t.getBigInt64(0,!0)},uDec(o,d){return t.setInt32(0,o,!0),t.setInt32(4,d,!0),t.getBigUint64(0,!0)}}}return{zero:"0",supported:!1,parse(n){return typeof n!="string"&&(n=n.toString()),z(n),n},uParse(n){return typeof n!="string"&&(n=n.toString()),K(n),n},enc(n){return typeof n!="string"&&(n=n.toString()),z(n),B(n)},uEnc(n){return typeof n!="string"&&(n=n.toString()),K(n),B(n)},dec(n,i){return V(n,i)},uDec(n,i){return A(n,i)}}}function z(t){if(!/^-?[0-9]+$/.test(t))throw new Error("invalid int64: "+t)}function K(t){if(!/^[0-9]+$/.test(t))throw new Error("invalid uint64: "+t)}var u,j=l(()=>{"use strict";U();u=pe()});function S(){if(globalThis[N]==null){let t=new globalThis.TextEncoder,e=new globalThis.TextDecoder;globalThis[N]={encodeUtf8(n){return t.encode(n)},decodeUtf8(n){return e.decode(n)},checkUtf8(n){try{return encodeURIComponent(n),!0}catch{return!1}}}}return globalThis[N]}var N,_=l(()=>{"use strict";N=Symbol.for("@bufbuild/protobuf/text-encoding")});function P(t){if(typeof t=="string")t=Number(t);else if(typeof t!="number")throw new Error("invalid int32: "+typeof t);if(!Number.isInteger(t)||t>Te||t<Ee)throw new Error("invalid int32: "+t)}function Y(t){if(typeof t=="string")t=Number(t);else if(typeof t!="number")throw new Error("invalid uint32: "+typeof t);if(!Number.isInteger(t)||t>Ie||t<0)throw new Error("invalid uint32: "+t)}function ge(t){if(typeof t=="string"){let e=t;if(t=Number(t),Number.isNaN(t)&&e!=="NaN")throw new Error("invalid float32: "+e)}else if(typeof t!="number")throw new Error("invalid float32: "+typeof t);if(Number.isFinite(t)&&(t>ye||t<be))throw new Error("invalid float32: "+t)}var h,ye,be,Ie,Te,Ee,p,f,H=l(()=>{"use strict";U();j();_();(function(t){t[t.Varint=0]="Varint",t[t.Bit64=1]="Bit64",t[t.LengthDelimited=2]="LengthDelimited",t[t.StartGroup=3]="StartGroup",t[t.EndGroup=4]="EndGroup",t[t.Bit32=5]="Bit32"})(h||(h={}));ye=34028234663852886e22,be=-34028234663852886e22,Ie=4294967295,Te=2147483647,Ee=-2147483648,p=class{constructor(e=S().encodeUtf8){this.encodeUtf8=e,this.stack=[],this.chunks=[],this.buf=[]}finish(){this.buf.length&&(this.chunks.push(new Uint8Array(this.buf)),this.buf=[]);let e=0;for(let r=0;r<this.chunks.length;r++)e+=this.chunks[r].length;let n=new Uint8Array(e),i=0;for(let r=0;r<this.chunks.length;r++)n.set(this.chunks[r],i),i+=this.chunks[r].length;return this.chunks=[],n}fork(){return this.stack.push({chunks:this.chunks,buf:this.buf}),this.chunks=[],this.buf=[],this}join(){let e=this.finish(),n=this.stack.pop();if(!n)throw new Error("invalid state, fork stack empty");return this.chunks=n.chunks,this.buf=n.buf,this.uint32(e.byteLength),this.raw(e)}tag(e,n){return this.uint32((e<<3|n)>>>0)}raw(e){return this.buf.length&&(this.chunks.push(new Uint8Array(this.buf)),this.buf=[]),this.chunks.push(e),this}uint32(e){for(Y(e);e>127;)this.buf.push(e&127|128),e=e>>>7;return this.buf.push(e),this}int32(e){return P(e),R(e,this.buf),this}bool(e){return this.buf.push(e?1:0),this}bytes(e){return this.uint32(e.byteLength),this.raw(e)}string(e){let n=this.encodeUtf8(e);return this.uint32(n.byteLength),this.raw(n)}float(e){ge(e);let n=new Uint8Array(4);return new DataView(n.buffer).setFloat32(0,e,!0),this.raw(n)}double(e){let n=new Uint8Array(8);return new DataView(n.buffer).setFloat64(0,e,!0),this.raw(n)}fixed32(e){Y(e);let n=new Uint8Array(4);return new DataView(n.buffer).setUint32(0,e,!0),this.raw(n)}sfixed32(e){P(e);let n=new Uint8Array(4);return new DataView(n.buffer).setInt32(0,e,!0),this.raw(n)}sint32(e){return P(e),e=(e<<1^e>>31)>>>0,R(e,this.buf),this}sfixed64(e){let n=new Uint8Array(8),i=new DataView(n.buffer),r=u.enc(e);return i.setInt32(0,r.lo,!0),i.setInt32(4,r.hi,!0),this.raw(n)}fixed64(e){let n=new Uint8Array(8),i=new DataView(n.buffer),r=u.uEnc(e);return i.setInt32(0,r.lo,!0),i.setInt32(4,r.hi,!0),this.raw(n)}int64(e){let n=u.enc(e);return E(n.lo,n.hi,this.buf),this}sint64(e){let n=u.enc(e),i=n.hi>>31,r=n.lo<<1^i,s=(n.hi<<1|n.lo>>>31)^i;return E(r,s,this.buf),this}uint64(e){let n=u.uEnc(e);return E(n.lo,n.hi,this.buf),this}},f=class{constructor(e,n=S().decodeUtf8){this.decodeUtf8=n,this.varint64=q,this.uint32=G,this.buf=e,this.len=e.length,this.pos=0,this.view=new DataView(e.buffer,e.byteOffset,e.byteLength)}tag(){let e=this.uint32(),n=e>>>3,i=e&7;if(n<=0||i<0||i>5)throw new Error("illegal tag: field no "+n+" wire type "+i);return[n,i]}skip(e,n){let i=this.pos;switch(e){case h.Varint:for(;this.buf[this.pos++]&128;);break;case h.Bit64:this.pos+=4;case h.Bit32:this.pos+=4;break;case h.LengthDelimited:let r=this.uint32();this.pos+=r;break;case h.StartGroup:for(;;){let[s,o]=this.tag();if(o===h.EndGroup){if(n!==void 0&&s!==n)throw new Error("invalid end group tag");break}this.skip(o,s)}break;default:throw new Error("cant skip wire type "+e)}return this.assertBounds(),this.buf.subarray(i,this.pos)}assertBounds(){if(this.pos>this.len)throw new RangeError("premature EOF")}int32(){return this.uint32()|0}sint32(){let e=this.uint32();return e>>>1^-(e&1)}int64(){return u.dec(...this.varint64())}uint64(){return u.uDec(...this.varint64())}sint64(){let[e,n]=this.varint64(),i=-(e&1);return e=(e>>>1|(n&1)<<31)^i,n=n>>>1^i,u.dec(e,n)}bool(){let[e,n]=this.varint64();return e!==0||n!==0}fixed32(){return this.view.getUint32((this.pos+=4)-4,!0)}sfixed32(){return this.view.getInt32((this.pos+=4)-4,!0)}fixed64(){return u.uDec(this.sfixed32(),this.sfixed32())}sfixed64(){return u.dec(this.sfixed32(),this.sfixed32())}float(){return this.view.getFloat32((this.pos+=4)-4,!0)}double(){return this.view.getFloat64((this.pos+=8)-8,!0)}bytes(){let e=this.uint32(),n=this.pos;return this.pos+=e,this.assertBounds(),this.buf.subarray(n,n+e)}string(){return this.decodeUtf8(this.bytes())}}});var X=l(()=>{"use strict"});var Q=l(()=>{"use strict"});var Z=l(()=>{"use strict"});var J=l(()=>{"use strict";H();X();_();Q();Z()});function ee(){return{propertyId:"",pageviewId:"",sessionId:"",pageUrl:"",country:"",region:"",deviceType:"",userId:"",domain:"",events:[],browser:"",deviceManufacturer:"",deviceModel:"",city:"",postalCode:""}}function te(){return{timestampMs:0,type:0,eventName:"",auctionId:"",transactionId:"",adUnitCode:"",bid:void 0,namespace:"",eventId:"",metadata:{},viewableDurationMs:void 0}}function ne(){return{key:"",value:""}}function ie(){return{bidder:"",cpm:0,currency:"",width:0,height:0,dealId:"",mediaType:"",latencyMs:0,advertiserDomain:"",creativeId:""}}var c,M,g,C,v,re=l(()=>{"use strict";J();c={TRACE_EVENT_TYPE_UNSPECIFIED:0,AUCTION_START:1,AUCTION_END:2,BID_REQUEST:3,BID_RESPONSE:4,BID_WIN:5,BID_TIMEOUT:6,IMPRESSION:7,VIEWABLE:8,TIME_IN_VIEW:14,REFRESH:9,ERROR:10,SLOT_DEFINED:11,SLOT_DESTROYED:12,CLICK:13,NO_BID:15,AD_RENDER_FAILED:16,UNRECOGNIZED:-1};M={encode(t,e=new p){if(t.propertyId!==void 0&&t.propertyId!==""&&e.uint32(10).string(t.propertyId),t.pageviewId!==void 0&&t.pageviewId!==""&&e.uint32(18).string(t.pageviewId),t.sessionId!==void 0&&t.sessionId!==""&&e.uint32(26).string(t.sessionId),t.pageUrl!==void 0&&t.pageUrl!==""&&e.uint32(34).string(t.pageUrl),t.country!==void 0&&t.country!==""&&e.uint32(42).string(t.country),t.region!==void 0&&t.region!==""&&e.uint32(50).string(t.region),t.deviceType!==void 0&&t.deviceType!==""&&e.uint32(58).string(t.deviceType),t.userId!==void 0&&t.userId!==""&&e.uint32(66).string(t.userId),t.domain!==void 0&&t.domain!==""&&e.uint32(74).string(t.domain),t.events!==void 0&&t.events.length!==0)for(let n of t.events)g.encode(n,e.uint32(82).fork()).join();return t.browser!==void 0&&t.browser!==""&&e.uint32(90).string(t.browser),t.deviceManufacturer!==void 0&&t.deviceManufacturer!==""&&e.uint32(98).string(t.deviceManufacturer),t.deviceModel!==void 0&&t.deviceModel!==""&&e.uint32(106).string(t.deviceModel),t.city!==void 0&&t.city!==""&&e.uint32(114).string(t.city),t.postalCode!==void 0&&t.postalCode!==""&&e.uint32(122).string(t.postalCode),e},decode(t,e){let n=t instanceof f?t:new f(t),i=e===void 0?n.len:n.pos+e,r=ee();for(;n.pos<i;){let s=n.uint32();switch(s>>>3){case 1:{if(s!==10)break;r.propertyId=n.string();continue}case 2:{if(s!==18)break;r.pageviewId=n.string();continue}case 3:{if(s!==26)break;r.sessionId=n.string();continue}case 4:{if(s!==34)break;r.pageUrl=n.string();continue}case 5:{if(s!==42)break;r.country=n.string();continue}case 6:{if(s!==50)break;r.region=n.string();continue}case 7:{if(s!==58)break;r.deviceType=n.string();continue}case 8:{if(s!==66)break;r.userId=n.string();continue}case 9:{if(s!==74)break;r.domain=n.string();continue}case 10:{if(s!==82)break;let o=g.decode(n,n.uint32());o!==void 0&&r.events.push(o);continue}case 11:{if(s!==90)break;r.browser=n.string();continue}case 12:{if(s!==98)break;r.deviceManufacturer=n.string();continue}case 13:{if(s!==106)break;r.deviceModel=n.string();continue}case 14:{if(s!==114)break;r.city=n.string();continue}case 15:{if(s!==122)break;r.postalCode=n.string();continue}}if((s&7)===4||s===0)break;n.skip(s&7)}return r},create(t){return M.fromPartial(t??{})},fromPartial(t){let e=ee();return e.propertyId=t.propertyId??"",e.pageviewId=t.pageviewId??"",e.sessionId=t.sessionId??"",e.pageUrl=t.pageUrl??"",e.country=t.country??"",e.region=t.region??"",e.deviceType=t.deviceType??"",e.userId=t.userId??"",e.domain=t.domain??"",e.events=t.events?.map(n=>g.fromPartial(n))||[],e.browser=t.browser??"",e.deviceManufacturer=t.deviceManufacturer??"",e.deviceModel=t.deviceModel??"",e.city=t.city??"",e.postalCode=t.postalCode??"",e}};g={encode(t,e=new p){return t.timestampMs!==void 0&&t.timestampMs!==0&&e.uint32(9).double(t.timestampMs),t.type!==void 0&&t.type!==0&&e.uint32(16).int32(t.type),t.eventName!==void 0&&t.eventName!==""&&e.uint32(26).string(t.eventName),t.auctionId!==void 0&&t.auctionId!==""&&e.uint32(34).string(t.auctionId),t.transactionId!==void 0&&t.transactionId!==""&&e.uint32(42).string(t.transactionId),t.adUnitCode!==void 0&&t.adUnitCode!==""&&e.uint32(50).string(t.adUnitCode),t.bid!==void 0&&v.encode(t.bid,e.uint32(58).fork()).join(),t.namespace!==void 0&&t.namespace!==""&&e.uint32(66).string(t.namespace),t.eventId!==void 0&&t.eventId!==""&&e.uint32(74).string(t.eventId),globalThis.Object.entries(t.metadata||{}).forEach(([n,i])=>{C.encode({key:n,value:i},e.uint32(82).fork()).join()}),t.viewableDurationMs!==void 0&&e.uint32(89).double(t.viewableDurationMs),e},decode(t,e){let n=t instanceof f?t:new f(t),i=e===void 0?n.len:n.pos+e,r=te();for(;n.pos<i;){let s=n.uint32();switch(s>>>3){case 1:{if(s!==9)break;r.timestampMs=n.double();continue}case 2:{if(s!==16)break;r.type=n.int32();continue}case 3:{if(s!==26)break;r.eventName=n.string();continue}case 4:{if(s!==34)break;r.auctionId=n.string();continue}case 5:{if(s!==42)break;r.transactionId=n.string();continue}case 6:{if(s!==50)break;r.adUnitCode=n.string();continue}case 7:{if(s!==58)break;r.bid=v.decode(n,n.uint32());continue}case 8:{if(s!==66)break;r.namespace=n.string();continue}case 9:{if(s!==74)break;r.eventId=n.string();continue}case 10:{if(s!==82)break;let o=C.decode(n,n.uint32());o.value!==void 0&&(r.metadata[o.key]=o.value);continue}case 11:{if(s!==89)break;r.viewableDurationMs=n.double();continue}}if((s&7)===4||s===0)break;n.skip(s&7)}return r},create(t){return g.fromPartial(t??{})},fromPartial(t){let e=te();return e.timestampMs=t.timestampMs??0,e.type=t.type??0,e.eventName=t.eventName??"",e.auctionId=t.auctionId??"",e.transactionId=t.transactionId??"",e.adUnitCode=t.adUnitCode??"",e.bid=t.bid!==void 0&&t.bid!==null?v.fromPartial(t.bid):void 0,e.namespace=t.namespace??"",e.eventId=t.eventId??"",e.metadata=globalThis.Object.entries(t.metadata??{}).reduce((n,[i,r])=>(r!==void 0&&(n[i]=globalThis.String(r)),n),{}),e.viewableDurationMs=t.viewableDurationMs??void 0,e}};C={encode(t,e=new p){return t.key!==""&&e.uint32(10).string(t.key),t.value!==""&&e.uint32(18).string(t.value),e},decode(t,e){let n=t instanceof f?t:new f(t),i=e===void 0?n.len:n.pos+e,r=ne();for(;n.pos<i;){let s=n.uint32();switch(s>>>3){case 1:{if(s!==10)break;r.key=n.string();continue}case 2:{if(s!==18)break;r.value=n.string();continue}}if((s&7)===4||s===0)break;n.skip(s&7)}return r},create(t){return C.fromPartial(t??{})},fromPartial(t){let e=ne();return e.key=t.key??"",e.value=t.value??"",e}};v={encode(t,e=new p){return t.bidder!==void 0&&t.bidder!==""&&e.uint32(10).string(t.bidder),t.cpm!==void 0&&t.cpm!==0&&e.uint32(17).double(t.cpm),t.currency!==void 0&&t.currency!==""&&e.uint32(26).string(t.currency),t.width!==void 0&&t.width!==0&&e.uint32(32).int32(t.width),t.height!==void 0&&t.height!==0&&e.uint32(40).int32(t.height),t.dealId!==void 0&&t.dealId!==""&&e.uint32(50).string(t.dealId),t.mediaType!==void 0&&t.mediaType!==""&&e.uint32(58).string(t.mediaType),t.latencyMs!==void 0&&t.latencyMs!==0&&e.uint32(65).double(t.latencyMs),t.advertiserDomain!==void 0&&t.advertiserDomain!==""&&e.uint32(74).string(t.advertiserDomain),t.creativeId!==void 0&&t.creativeId!==""&&e.uint32(82).string(t.creativeId),e},decode(t,e){let n=t instanceof f?t:new f(t),i=e===void 0?n.len:n.pos+e,r=ie();for(;n.pos<i;){let s=n.uint32();switch(s>>>3){case 1:{if(s!==10)break;r.bidder=n.string();continue}case 2:{if(s!==17)break;r.cpm=n.double();continue}case 3:{if(s!==26)break;r.currency=n.string();continue}case 4:{if(s!==32)break;r.width=n.int32();continue}case 5:{if(s!==40)break;r.height=n.int32();continue}case 6:{if(s!==50)break;r.dealId=n.string();continue}case 7:{if(s!==58)break;r.mediaType=n.string();continue}case 8:{if(s!==65)break;r.latencyMs=n.double();continue}case 9:{if(s!==74)break;r.advertiserDomain=n.string();continue}case 10:{if(s!==82)break;r.creativeId=n.string();continue}}if((s&7)===4||s===0)break;n.skip(s&7)}return r},create(t){return v.fromPartial(t??{})},fromPartial(t){let e=ie();return e.bidder=t.bidder??"",e.cpm=t.cpm??0,e.currency=t.currency??"",e.width=t.width??0,e.height=t.height??0,e.dealId=t.dealId??"",e.mediaType=t.mediaType??"",e.latencyMs=t.latencyMs??0,e.advertiserDomain=t.advertiserDomain??"",e.creativeId=t.creativeId??"",e}}});function I(){return typeof crypto<"u"&&typeof crypto.randomUUID=="function"?crypto.randomUUID():"xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g,t=>{let e=Math.random()*16|0;return(t==="x"?e:e&3|8).toString(16)})}function Ae(){let t=Date.now();b=t;try{typeof localStorage<"u"&&localStorage.setItem(x,t.toString())}catch{}}function ke(){let t=Date.now();try{if(typeof localStorage<"u"){let e=localStorage.getItem(oe),n=localStorage.getItem(x),i=n&&parseInt(n,10)||0;if(e&&i&&t-i<=de)return localStorage.setItem(x,t.toString()),e;let r=I();return localStorage.setItem(oe,r),localStorage.setItem(x,t.toString()),r}}catch{}return m&&b&&t-b<=de?(b=t,m):(m=I(),b=t,m)}function Re(t,e){switch(t){case"auctionInit":return`auctionInit:${e?.auctionId||""}`;case"auctionEnd":return`auctionEnd:${e?.auctionId||""}`;case"bidRequested":return`bidRequested:${e?.auctionId||""}:${e?.bidderCode||""}:${Array.isArray(e?.bids)?e.bids.map(n=>n?.bidId||n?.adUnitCode||"").join(","):""}`;case"bidResponse":return`bidResponse:${e?.auctionId||""}:${e?.adUnitCode||""}:${e?.bidderCode||e?.bidder||""}:${e?.creativeId||e?.adId||e?.requestId||""}:${e?.originalCpm??e?.cpm??""}`;case"bidTimeout":return Array.isArray(e)?"bidTimeout:"+e.map(n=>`${n?.auctionId||""}:${n?.bidder||n?.bidderCode||""}:${n?.bidId||n?.adUnitCode||""}`).join(","):`bidTimeout:${e?.auctionId||""}:${e?.bidder||e?.bidderCode||""}:${e?.bidId||e?.adUnitCode||""}`;case"bidWon":return`bidWon:${e?.auctionId||""}:${e?.adUnitCode||""}:${e?.bidderCode||e?.bidder||""}:${e?.creativeId||e?.adId||e?.requestId||""}:${e?.originalCpm??e?.cpm??""}`;case"noBid":return`noBid:${e?.auctionId||""}:${e?.adUnitCode||""}:${e?.bidderCode||e?.bidder||""}:${e?.bidId||""}`;case"adRenderFailed":return`adRenderFailed:${e?.bid?.auctionId||e?.auctionId||""}:${e?.bid?.adUnitCode||e?.adUnitCode||""}:${e?.bid?.bidderCode||e?.bid?.bidder||""}:${e?.reason||""}:${e?.message||""}`;case"adRenderSucceeded":return`adRenderSucceeded:${e?.bid?.auctionId||e?.auctionId||""}:${e?.bid?.adUnitCode||e?.adUnitCode||""}:${e?.bid?.bidderCode||e?.bid?.bidder||""}`;case"setTargeting":return`setTargeting:${Object.keys(e||{}).sort().join(",")}`;case"auctionDebug":return`auctionDebug:${e?.type||""}:${String(e?.arguments?.[0]??"").slice(0,50)}`;default:return""}}function ae(t){if(!t)return{width:0,height:0};let e=t;for(;Array.isArray(e)&&e.length>0&&Array.isArray(e[0]);)e=e[0];if(Array.isArray(e)&&e.length>=2){let n=Number(e[0]),i=Number(e[1]);return{width:Number.isFinite(n)?n:0,height:Number.isFinite(i)?i:0}}return{width:0,height:0}}function y(t){if(!t)return null;if(Array.isArray(t)){let e=t.find(n=>n?.provider==="bidkernel")??t.find(n=>n&&typeof n=="object"&&n.provider===void 0);return e?y(e):null}if(typeof t=="object"){if(t.options&&typeof t.options=="object")return t.options;if(t.config&&typeof t.config=="object")return t.config;if(t.propertyId||t.endpoint)return t}return null}function Ue(t){if(!t)return null;if(t._bidkernelAnalyticsConfig){let e=y(t._bidkernelAnalyticsConfig);if(e)return e}if(t.bidkernelPrebidAnalytics){let e=t.bidkernelPrebidAnalytics;if(e.options){let n=y(e.options);if(n)return n}if(e.config){let n=y(e.config);if(n)return n}if(e.propertyId)return y(e)}return null}function L(t="pbjs",e){let n=typeof window<"u"?window:{};n[t]=n[t]||{};let i=n[t],r=o=>{if(n._bidkernelPrebidAnalytics)try{n._bidkernelPrebidAnalytics.disable()}catch(a){console.warn("[bidkernel] Failed to disable previous analytics instance:",a)}let d=new O({pbjsGlobalName:t,...e,...o});return d.enable(),n._bidkernelPrebidAnalytics=d,d},s=()=>{try{i.adapterManager&&typeof i.adapterManager.registerAnalyticsAdapter=="function"&&i.adapterManager.registerAnalyticsAdapter({adapter:{enableAnalytics:d=>{let a=y(d);a&&r(a)},disableAnalytics:()=>{n._bidkernelPrebidAnalytics&&n._bidkernelPrebidAnalytics.disable()}},code:"bidkernel"});let o=Ue(n);o&&(o.propertyId||e?.propertyId)&&r(o)}catch(o){console.warn("[bidkernel] Failed to register standard Prebid analytics adapter:",o)}};i.adapterManager&&typeof i.adapterManager.registerAnalyticsAdapter=="function"?s():(i.que=i.que||[],i.que.push(s))}var we,se,me,w,xe,De,Be,oe,x,de,m,b,F,O,ce=l(()=>{"use strict";re();we=20,se=1e4,me=50,w=200,xe=300*1e3,De=10,Be={auctionStart:c.AUCTION_START,auctionEnd:c.AUCTION_END,bidRequest:c.BID_REQUEST,bidResponse:c.BID_RESPONSE,bidTimeout:c.BID_TIMEOUT,bidWin:c.BID_WIN,noBid:c.NO_BID,adRenderFailed:c.AD_RENDER_FAILED,click:c.CLICK,impression:c.IMPRESSION,refresh:c.REFRESH,timeInView:c.TIME_IN_VIEW,viewable:c.VIEWABLE},oe="_bidkernel_session",x="_bidkernel_session_ts",de=1800*1e3,m=null,b=0;F=class{seenObjects=new WeakSet;seenKeys=new Set;isDuplicate(e,n){if(!n)return!1;if(typeof n=="object"){if(this.seenObjects.has(n))return!0;this.seenObjects.add(n)}let i=Re(e,n);if(i){if(this.seenKeys.has(i))return!0;if(this.seenKeys.size>=1e3){let r=this.seenKeys.values().next().value;r!==void 0&&this.seenKeys.delete(r)}this.seenKeys.add(i)}return!1}};O=class{config;queue=[];errorCount=0;flushTimer=null;boundFlushBeacon;boundVisibilityChange;isEnabled=!1;boundPbjsHandlers=[];pageUrl="";deduper=new F;consecutiveSendFailures=0;nextSendAllowedAt=0;constructor(e){this.config={endpoint:e.endpoint||"",propertyId:e.propertyId||"",pageviewId:e.pageviewId||I(),sessionId:e.sessionId||ke(),userId:e.userId||"",deviceType:e.deviceType||"desktop",country:e.country||"",region:e.region||"",auctionEnabled:e.auctionEnabled??!0,warningsEnabled:e.warningsEnabled??!0,errorsEnabled:e.errorsEnabled??!0,logLevel:e.logLevel||"INFO",pbjsGlobalName:e.pbjsGlobalName||"pbjs",attachPbjsListeners:e.attachPbjsListeners??!0},this.boundFlushBeacon=()=>this.flushBeacon(),this.boundVisibilityChange=()=>this.handleVisibilityChange()}enable(){if(!this.isEnabled){if(this.isEnabled=!0,this.config.endpoint||this.log("WARN","Endpoint is empty. Analytics events will not be transmitted."),this.config.attachPbjsListeners){let n=(typeof window<"u"?window:{})[this.config.pbjsGlobalName]||{};if(typeof n.onEvent=="function"){this.log("DEBUG","Attaching event listeners to pbjs");let i=[["auctionInit",this.handleAuctionInit.bind(this)],["auctionEnd",this.handleAuctionEnd.bind(this)],["bidRequested",this.handleBidRequested.bind(this)],["bidResponse",this.handleBidResponse.bind(this)],["bidTimeout",this.handleBidTimeout.bind(this)],["bidWon",this.handleBidWon.bind(this)],["noBid",this.handleNoBid.bind(this)],["adRenderFailed",this.handleAdRenderFailed.bind(this)],["adRenderSucceeded",this.handleAdRenderSucceeded.bind(this)]];for(let[r,s]of i)n.onEvent(r,s),this.boundPbjsHandlers.push({event:r,handler:s})}else this.log("WARN","pbjs.onEvent is not defined. Prebid analytics will not function.");if(typeof n.getEvents=="function")try{let i=n.getEvents();if(Array.isArray(i)){this.log("DEBUG",`Replaying ${i.length} historical events from pbjs.getEvents()`);let r={auctionInit:this.handleAuctionInit.bind(this),auctionEnd:this.handleAuctionEnd.bind(this),bidRequested:this.handleBidRequested.bind(this),bidResponse:this.handleBidResponse.bind(this),bidTimeout:this.handleBidTimeout.bind(this),bidWon:this.handleBidWon.bind(this),noBid:this.handleNoBid.bind(this),adRenderFailed:this.handleAdRenderFailed.bind(this),adRenderSucceeded:this.handleAdRenderSucceeded.bind(this)};for(let s of i){if(!s)continue;let o=s.eventType||s.event||s.name,d=s.args!==void 0?s.args:s.data!==void 0?s.data:s,a=r[o];a&&a(d)}}}catch(i){this.log("WARN","Failed to replay historical events from pbjs.getEvents()",i)}}if(typeof window<"u"){if(!this.pageUrl)try{let e=new URL(window.location.href);this.pageUrl=e.origin+e.pathname}catch{this.pageUrl=window.location.href}window.addEventListener("pagehide",this.boundFlushBeacon),typeof document<"u"&&document.addEventListener("visibilitychange",this.boundVisibilityChange),this.flushTimer=setInterval(()=>this.flush(),se)}}}disable(){if(this.isEnabled){if(this.isEnabled=!1,this.flushTimer&&(clearInterval(this.flushTimer),this.flushTimer=null),typeof window<"u"&&(window.removeEventListener("pagehide",this.boundFlushBeacon),typeof document<"u"&&document.removeEventListener("visibilitychange",this.boundVisibilityChange)),this.boundPbjsHandlers.length>0){let n=(typeof window<"u"?window:{})[this.config.pbjsGlobalName]||{};if(typeof n.offEvent=="function")for(let{event:i,handler:r}of this.boundPbjsHandlers)n.offEvent(i,r);this.boundPbjsHandlers=[]}this.flush()}}handleVisibilityChange(){typeof document<"u"&&document.visibilityState==="hidden"&&this.flushBeacon()}trackRawEvent(e,n,i){let r=Be[n]??(e==="ERROR"?c.ERROR:c.TRACE_EVENT_TYPE_UNSPECIFIED);this.enqueue(r,n,i,e)}setUserId(e){this.config.userId=e}setSessionId(e){this.config.sessionId=e}navigate(e,n){if(this.disable(),this.config.pageviewId=e||I(),n)try{let i=new URL(n);this.pageUrl=i.origin+i.pathname}catch{this.pageUrl=n}else this.pageUrl="";Ae(),this.enable()}handleAuctionInit(e){this.isDuplicate("auctionInit",e)||(this.log("DEBUG","auctionInit",e),this.enqueue(c.AUCTION_START,"auctionStart",{auctionId:e.auctionId||""}))}handleAuctionEnd(e){this.isDuplicate("auctionEnd",e)||(this.log("DEBUG","auctionEnd",e),this.enqueue(c.AUCTION_END,"auctionEnd",{auctionId:e.auctionId||""}))}handleBidRequested(e){if(this.isDuplicate("bidRequested",e))return;this.log("DEBUG","bidRequested",e);let n=e.auctionId||"",i=e.bidderCode||"";Array.isArray(e.bids)&&e.bids.forEach(r=>{let s=Object.keys(r.mediaTypes||{}),o=r.ortb2Imp?.ext?.gpid||r.gpid||e.gpid||"";if(s.length===0){let d=r.mediaType||"banner",{width:a,height:D}=ae(r.sizes||r.playerSize);this.enqueue(c.BID_REQUEST,"bidRequest",{auctionId:n,adUnitCode:r.adUnitCode||"",gpid:o,bid:{bidder:i,mediaType:d,width:a,height:D}});return}s.forEach(d=>{let a=null;d==="banner"?a=r.mediaTypes?.banner?.sizes||r.sizes:d==="video"?a=r.mediaTypes?.video?.playerSize||r.mediaTypes?.video?.sizes||r.playerSize:a=r.mediaTypes?.[d]?.sizes;let{width:D,height:fe}=ae(a);this.enqueue(c.BID_REQUEST,"bidRequest",{auctionId:n,adUnitCode:r.adUnitCode||"",gpid:o,bid:{bidder:i,mediaType:d,width:D,height:fe}})})})}handleBidResponse(e){this.isDuplicate("bidResponse",e)||(this.log("DEBUG","bidResponse",e),this.enqueue(c.BID_RESPONSE,"bidResponse",{auctionId:e.auctionId||"",adUnitCode:e.adUnitCode||"",bid:{bidder:e.bidderCode||e.bidder||"",cpm:Number.isFinite(e.originalCpm)?e.originalCpm:Number.isFinite(e.cpm)?e.cpm:0,currency:e.originalCurrency??e.currency??"USD",width:Number.isFinite(e.width)?e.width:0,height:Number.isFinite(e.height)?e.height:0,dealId:e.dealId||"",mediaType:e.mediaType||"banner",latencyMs:Number.isFinite(e.timeToRespond)?e.timeToRespond:0,advertiserDomain:e.meta?.advertiserDomains?.[0]||"",creativeId:e.creativeId||""}}))}handleBidTimeout(e){this.isDuplicate("bidTimeout",e)||(this.log("DEBUG","bidTimeout",e),Array.isArray(e)&&e.forEach(n=>{this.enqueue(c.BID_TIMEOUT,"bidTimeout",{auctionId:n.auctionId||"",adUnitCode:n.adUnitCode||"",bid:{bidder:n.bidder||""}})}))}handleBidWon(e){this.isDuplicate("bidWon",e)||(this.log("DEBUG","bidWon",e),this.enqueue(c.BID_WIN,"bidWon",{auctionId:e.auctionId||"",adUnitCode:e.adUnitCode||"",bid:{bidder:e.bidderCode||e.bidder||"",cpm:Number.isFinite(e.originalCpm)?e.originalCpm:Number.isFinite(e.cpm)?e.cpm:0,currency:e.originalCurrency??e.currency??"USD",width:Number.isFinite(e.width)?e.width:0,height:Number.isFinite(e.height)?e.height:0,dealId:e.dealId||"",mediaType:e.mediaType||"banner",latencyMs:Number.isFinite(e.timeToRespond)?e.timeToRespond:0,advertiserDomain:e.meta?.advertiserDomains?.[0]||"",creativeId:e.creativeId||""}}))}handleNoBid(e){this.isDuplicate("noBid",e)||(this.log("DEBUG","noBid",e),this.enqueue(c.NO_BID,"noBid",{auctionId:e.auctionId||"",adUnitCode:e.adUnitCode||"",bid:{bidder:e.bidderCode||e.bidder||""}}))}handleAdRenderFailed(e){this.isDuplicate("adRenderFailed",e)||(this.log("DEBUG","adRenderFailed",e),this.enqueue(c.AD_RENDER_FAILED,"adRenderFailed",{auctionId:e.bid?.auctionId||"",adUnitCode:e.bid?.adUnitCode||"",bid:{bidder:e.bid?.bidderCode||e.bid?.bidder||""},metadata:{reason:String(e.reason||""),message:String(e.message||"")}}))}handleAdRenderSucceeded(e){if(this.isDuplicate("adRenderSucceeded",e))return;this.log("DEBUG","adRenderSucceeded",e);let n=e.bid||{};this.enqueue(c.IMPRESSION,"impression",{auctionId:n.auctionId||"",adUnitCode:e.adUnitCode||n.adUnitCode||"",bid:{bidder:n.bidderCode||n.bidder||"",cpm:Number.isFinite(n.originalCpm)?n.originalCpm:Number.isFinite(n.cpm)?n.cpm:0,currency:n.originalCurrency??n.currency??"USD",width:Number.isFinite(n.width)?n.width:0,height:Number.isFinite(n.height)?n.height:0,dealId:n.dealId||"",mediaType:n.mediaType||"banner",latencyMs:Number.isFinite(n.timeToRespond)?n.timeToRespond:0,advertiserDomain:n.meta?.advertiserDomains?.[0]||"",creativeId:n.creativeId||""}})}isDuplicate(e,n){return this.deduper.isDuplicate(e,n)}enqueue(e,n,i,r){if(!this.isEnabled||!this.shouldSample(e,r))return;let s={eventId:I(),timestampMs:Date.now(),type:e,eventName:n,auctionId:i.auctionId||"",transactionId:i.transactionId||"",adUnitCode:i.adUnitCode||i.elementId||"",namespace:i.ns||i.namespace||""};i.bid&&(s.bid={bidder:i.bid.bidder||"",cpm:Number.isFinite(i.bid.cpm)?i.bid.cpm:0,currency:i.bid.currency||"USD",width:Number.isFinite(i.bid.width)?i.bid.width:0,height:Number.isFinite(i.bid.height)?i.bid.height:0,dealId:i.bid.dealId||"",mediaType:i.bid.mediaType||"banner",latencyMs:Number.isFinite(i.bid.latencyMs)?i.bid.latencyMs:0,advertiserDomain:i.bid.advertiserDomain||"",creativeId:i.bid.creativeId||""}),i.viewableDurationMs!==void 0&&(s.viewableDurationMs=Number.isFinite(i.viewableDurationMs)?i.viewableDurationMs:0);let o={...i.metadata};i.error!==void 0&&i.error!==null&&(o.error=typeof i.error=="object"&&i.error.message?String(i.error.message):String(i.error)),i.gpid&&(o.gpid=String(i.gpid)),Object.keys(o).length>0&&(s.metadata=o),this.queue.push(s),this.queue.length>w&&this.queue.splice(0,this.queue.length-w),this.queue.length>=we&&this.flush()}shouldSample(e,n){return e===c.ERROR?(this.errorCount++,this.errorCount>me?!1:this.config.errorsEnabled):n==="WARN"?this.config.warningsEnabled:this.config.auctionEnabled}requeue(e){e.length&&(this.queue=e.concat(this.queue),this.queue.length>w&&this.queue.splice(0,this.queue.length-w))}drainBatch(){if(this.queue.length===0||!this.config.endpoint)return null;let e=this.queue;this.queue=[];let n=typeof window<"u"?window.location.hostname:"",i={propertyId:this.config.propertyId,pageviewId:this.config.pageviewId,sessionId:this.config.sessionId,pageUrl:this.pageUrl,country:this.config.country,region:this.config.region,deviceType:this.config.deviceType,userId:this.config.userId,domain:n,events:e};return{url:`${this.config.endpoint}/${this.config.propertyId}`,encoded:M.encode(i).finish(),events:e}}sendFetch(e){fetch(e.url,{method:"POST",headers:{"Content-Type":"application/x-protobuf"},body:e.encoded,keepalive:!0}).then(n=>{n.ok?(this.consecutiveSendFailures=0,this.nextSendAllowedAt=0):(this.log("WARN",`Failed to send batch: HTTP ${n.status}`),this.handleSendFailure(e.events))}).catch(n=>{this.log("ERROR","Failed to send batch",n),this.handleSendFailure(e.events)})}handleSendFailure(e){this.consecutiveSendFailures++;let n=Math.min(se*2**(this.consecutiveSendFailures-1),xe);this.nextSendAllowedAt=Date.now()+n,this.consecutiveSendFailures<=De?this.requeue(e):this.log("WARN",`Dropping ${e.length} events after ${this.consecutiveSendFailures} consecutive send failures`)}flush(){if(Date.now()<this.nextSendAllowedAt)return;let e=this.drainBatch();e&&this.sendFetch(e)}flushBeacon(){let e=this.drainBatch();if(!e)return;let n=!1;if(typeof navigator<"u"&&typeof navigator.sendBeacon=="function")try{let i=new Blob([e.encoded],{type:"application/x-protobuf"});n=navigator.sendBeacon(e.url,i)}catch{n=!1}n||this.sendFetch(e)}log(e,n,...i){let r={DEBUG:10,INFO:20,WARN:30,ERROR:40};if(r[e]<r[this.config.logLevel])return;let s=`[bidkernel][prebid-analytics][${e}]`;switch(e){case"DEBUG":console.debug(s,n,...i);break;case"INFO":console.info(s,n,...i);break;case"WARN":console.warn(s,n,...i);break;case"ERROR":console.error(s,n,...i);break}}}});var Se=le(()=>{ce();var ue="https://by.bidkernel.io/t",Ne=window._bidkernelPbjsGlobal||"pbjs";L(Ne,{endpoint:ue});window.bidkernelPrebidAnalytics={...window.bidkernelPrebidAnalytics,register:(t,e)=>L(t,{endpoint:ue,...e})}});return Se();})();
1
+ "use strict";var bidkernelPrebidAnalyticsBundle=(()=>{var h=(t,e)=>()=>(t&&(e=t(t=0)),e);var be=(t,e)=>()=>(e||t((e={exports:{}}).exports,e),e.exports);function G(){let t=0,e=0;for(let i=0;i<28;i+=7){let r=this.buf[this.pos++];if(t|=(r&127)<<i,(r&128)==0)return this.assertBounds(),[t,e]}let n=this.buf[this.pos++];if(t|=(n&15)<<28,e=(n&112)>>4,(n&128)==0)return this.assertBounds(),[t,e];for(let i=3;i<=31;i+=7){let r=this.buf[this.pos++];if(e|=(r&127)<<i,(r&128)==0)return this.assertBounds(),[t,e]}throw new Error("invalid varint")}function v(t,e,n){for(let s=0;s<28;s=s+7){let o=t>>>s,d=!(!(o>>>7)&&e==0),u=(d?o|128:o)&255;if(n.push(u),!d)return}let i=t>>>28&15|(e&7)<<4,r=e>>3!=0;if(n.push((r?i|128:i)&255),!!r){for(let s=3;s<31;s=s+7){let o=e>>>s,d=!!(o>>>7),u=(d?o|128:o)&255;if(n.push(u),!d)return}n.push(e>>>31&1)}}function R(t){let e=t[0]==="-";e&&(t=t.slice(1));let n=1e6,i=0,r=0;function s(o,d){let u=Number(t.slice(o,d));r*=n,i=i*n+u,i>=g&&(r=r+(i/g|0),i=i%g)}return s(-24,-18),s(-18,-12),s(-12,-6),s(-6),e?K(i,r):U(i,r)}function z(t,e){let n=U(t,e),i=n.hi&2147483648;i&&(n=K(n.lo,n.hi));let r=S(n.lo,n.hi);return i?"-"+r:r}function S(t,e){if({lo:t,hi:e}=Ie(t,e),e<=2097151)return String(g*e+t);let n=t&16777215,i=(t>>>24|e<<8)&16777215,r=e>>16&65535,s=n+i*6777216+r*6710656,o=i+r*8147497,d=r*2,u=1e7;return s>=u&&(o+=Math.floor(s/u),s%=u),o>=u&&(d+=Math.floor(o/u),o%=u),d.toString()+W(o)+W(s)}function Ie(t,e){return{lo:t>>>0,hi:e>>>0}}function U(t,e){return{lo:t|0,hi:e|0}}function K(t,e){return e=~e,t?t=~t+1:e+=1,U(t,e)}function N(t,e){if(t>=0){for(;t>127;)e.push(t&127|128),t=t>>>7;e.push(t)}else{for(let n=0;n<9;n++)e.push(t&127|128),t=t>>7;e.push(1)}}function Y(){let t=this.buf[this.pos++],e=t&127;if((t&128)==0)return this.assertBounds(),e;if(t=this.buf[this.pos++],e|=(t&127)<<7,(t&128)==0)return this.assertBounds(),e;if(t=this.buf[this.pos++],e|=(t&127)<<14,(t&128)==0)return this.assertBounds(),e;if(t=this.buf[this.pos++],e|=(t&127)<<21,(t&128)==0)return this.assertBounds(),e;t=this.buf[this.pos++],e|=(t&15)<<28;for(let n=5;(t&128)!==0&&n<10;n++)t=this.buf[this.pos++];if((t&128)!=0)throw new Error("invalid varint");return this.assertBounds(),e>>>0}var g,W,_=h(()=>{"use strict";g=4294967296;W=t=>{let e=String(t);return"0000000".slice(e.length)+e}});function Te(){let t=new DataView(new ArrayBuffer(8));if(typeof BigInt=="function"&&typeof t.getBigInt64=="function"&&typeof t.getBigUint64=="function"&&typeof t.setBigInt64=="function"&&typeof t.setBigUint64=="function"&&(!!globalThis.Deno||typeof process!="object"||typeof process.env!="object"||process.env.BUF_BIGINT_DISABLE!=="1")){let n=BigInt("-9223372036854775808"),i=BigInt("9223372036854775807"),r=BigInt("0"),s=BigInt("18446744073709551615");return{zero:BigInt(0),supported:!0,parse(o){let d=typeof o=="bigint"?o:BigInt(o);if(d>i||d<n)throw new Error(`invalid int64: ${o}`);return d},uParse(o){let d=typeof o=="bigint"?o:BigInt(o);if(d>s||d<r)throw new Error(`invalid uint64: ${o}`);return d},enc(o){return t.setBigInt64(0,this.parse(o),!0),{lo:t.getInt32(0,!0),hi:t.getInt32(4,!0)}},uEnc(o){return t.setBigInt64(0,this.uParse(o),!0),{lo:t.getInt32(0,!0),hi:t.getInt32(4,!0)}},dec(o,d){return t.setInt32(0,o,!0),t.setInt32(4,d,!0),t.getBigInt64(0,!0)},uDec(o,d){return t.setInt32(0,o,!0),t.setInt32(4,d,!0),t.getBigUint64(0,!0)}}}return{zero:"0",supported:!1,parse(n){return typeof n!="string"&&(n=n.toString()),j(n),n},uParse(n){return typeof n!="string"&&(n=n.toString()),H(n),n},enc(n){return typeof n!="string"&&(n=n.toString()),j(n),R(n)},uEnc(n){return typeof n!="string"&&(n=n.toString()),H(n),R(n)},dec(n,i){return z(n,i)},uDec(n,i){return S(n,i)}}}function j(t){if(!/^-?[0-9]+$/.test(t))throw new Error("invalid int64: "+t)}function H(t){if(!/^[0-9]+$/.test(t))throw new Error("invalid uint64: "+t)}var f,X=h(()=>{"use strict";_();f=Te()});function C(){if(globalThis[P]==null){let t=new globalThis.TextEncoder,e=new globalThis.TextDecoder;globalThis[P]={encodeUtf8(n){return t.encode(n)},decodeUtf8(n){return e.decode(n)},checkUtf8(n){try{return encodeURIComponent(n),!0}catch{return!1}}}}return globalThis[P]}var P,M=h(()=>{"use strict";P=Symbol.for("@bufbuild/protobuf/text-encoding")});function F(t){if(typeof t=="string")t=Number(t);else if(typeof t!="number")throw new Error("invalid int32: "+typeof t);if(!Number.isInteger(t)||t>we||t<me)throw new Error("invalid int32: "+t)}function Q(t){if(typeof t=="string")t=Number(t);else if(typeof t!="number")throw new Error("invalid uint32: "+typeof t);if(!Number.isInteger(t)||t>ve||t<0)throw new Error("invalid uint32: "+t)}function xe(t){if(typeof t=="string"){let e=t;if(t=Number(t),Number.isNaN(t)&&e!=="NaN")throw new Error("invalid float32: "+e)}else if(typeof t!="number")throw new Error("invalid float32: "+typeof t);if(Number.isFinite(t)&&(t>Ee||t<ge))throw new Error("invalid float32: "+t)}var y,Ee,ge,ve,we,me,b,l,Z=h(()=>{"use strict";_();X();M();(function(t){t[t.Varint=0]="Varint",t[t.Bit64=1]="Bit64",t[t.LengthDelimited=2]="LengthDelimited",t[t.StartGroup=3]="StartGroup",t[t.EndGroup=4]="EndGroup",t[t.Bit32=5]="Bit32"})(y||(y={}));Ee=34028234663852886e22,ge=-34028234663852886e22,ve=4294967295,we=2147483647,me=-2147483648,b=class{constructor(e=C().encodeUtf8){this.encodeUtf8=e,this.stack=[],this.chunks=[],this.buf=[]}finish(){this.buf.length&&(this.chunks.push(new Uint8Array(this.buf)),this.buf=[]);let e=0;for(let r=0;r<this.chunks.length;r++)e+=this.chunks[r].length;let n=new Uint8Array(e),i=0;for(let r=0;r<this.chunks.length;r++)n.set(this.chunks[r],i),i+=this.chunks[r].length;return this.chunks=[],n}fork(){return this.stack.push({chunks:this.chunks,buf:this.buf}),this.chunks=[],this.buf=[],this}join(){let e=this.finish(),n=this.stack.pop();if(!n)throw new Error("invalid state, fork stack empty");return this.chunks=n.chunks,this.buf=n.buf,this.uint32(e.byteLength),this.raw(e)}tag(e,n){return this.uint32((e<<3|n)>>>0)}raw(e){return this.buf.length&&(this.chunks.push(new Uint8Array(this.buf)),this.buf=[]),this.chunks.push(e),this}uint32(e){for(Q(e);e>127;)this.buf.push(e&127|128),e=e>>>7;return this.buf.push(e),this}int32(e){return F(e),N(e,this.buf),this}bool(e){return this.buf.push(e?1:0),this}bytes(e){return this.uint32(e.byteLength),this.raw(e)}string(e){let n=this.encodeUtf8(e);return this.uint32(n.byteLength),this.raw(n)}float(e){xe(e);let n=new Uint8Array(4);return new DataView(n.buffer).setFloat32(0,e,!0),this.raw(n)}double(e){let n=new Uint8Array(8);return new DataView(n.buffer).setFloat64(0,e,!0),this.raw(n)}fixed32(e){Q(e);let n=new Uint8Array(4);return new DataView(n.buffer).setUint32(0,e,!0),this.raw(n)}sfixed32(e){F(e);let n=new Uint8Array(4);return new DataView(n.buffer).setInt32(0,e,!0),this.raw(n)}sint32(e){return F(e),e=(e<<1^e>>31)>>>0,N(e,this.buf),this}sfixed64(e){let n=new Uint8Array(8),i=new DataView(n.buffer),r=f.enc(e);return i.setInt32(0,r.lo,!0),i.setInt32(4,r.hi,!0),this.raw(n)}fixed64(e){let n=new Uint8Array(8),i=new DataView(n.buffer),r=f.uEnc(e);return i.setInt32(0,r.lo,!0),i.setInt32(4,r.hi,!0),this.raw(n)}int64(e){let n=f.enc(e);return v(n.lo,n.hi,this.buf),this}sint64(e){let n=f.enc(e),i=n.hi>>31,r=n.lo<<1^i,s=(n.hi<<1|n.lo>>>31)^i;return v(r,s,this.buf),this}uint64(e){let n=f.uEnc(e);return v(n.lo,n.hi,this.buf),this}},l=class{constructor(e,n=C().decodeUtf8){this.decodeUtf8=n,this.varint64=G,this.uint32=Y,this.buf=e,this.len=e.length,this.pos=0,this.view=new DataView(e.buffer,e.byteOffset,e.byteLength)}tag(){let e=this.uint32(),n=e>>>3,i=e&7;if(n<=0||i<0||i>5)throw new Error("illegal tag: field no "+n+" wire type "+i);return[n,i]}skip(e,n){let i=this.pos;switch(e){case y.Varint:for(;this.buf[this.pos++]&128;);break;case y.Bit64:this.pos+=4;case y.Bit32:this.pos+=4;break;case y.LengthDelimited:let r=this.uint32();this.pos+=r;break;case y.StartGroup:for(;;){let[s,o]=this.tag();if(o===y.EndGroup){if(n!==void 0&&s!==n)throw new Error("invalid end group tag");break}this.skip(o,s)}break;default:throw new Error("cant skip wire type "+e)}return this.assertBounds(),this.buf.subarray(i,this.pos)}assertBounds(){if(this.pos>this.len)throw new RangeError("premature EOF")}int32(){return this.uint32()|0}sint32(){let e=this.uint32();return e>>>1^-(e&1)}int64(){return f.dec(...this.varint64())}uint64(){return f.uDec(...this.varint64())}sint64(){let[e,n]=this.varint64(),i=-(e&1);return e=(e>>>1|(n&1)<<31)^i,n=n>>>1^i,f.dec(e,n)}bool(){let[e,n]=this.varint64();return e!==0||n!==0}fixed32(){return this.view.getUint32((this.pos+=4)-4,!0)}sfixed32(){return this.view.getInt32((this.pos+=4)-4,!0)}fixed64(){return f.uDec(this.sfixed32(),this.sfixed32())}sfixed64(){return f.dec(this.sfixed32(),this.sfixed32())}float(){return this.view.getFloat32((this.pos+=4)-4,!0)}double(){return this.view.getFloat64((this.pos+=8)-8,!0)}bytes(){let e=this.uint32(),n=this.pos;return this.pos+=e,this.assertBounds(),this.buf.subarray(n,n+e)}string(){return this.decodeUtf8(this.bytes())}}});var J=h(()=>{"use strict"});var ee=h(()=>{"use strict"});var te=h(()=>{"use strict"});var ne=h(()=>{"use strict";Z();J();M();ee();te()});function ie(){return{propertyId:"",pageviewId:"",sessionId:"",pageUrl:"",country:"",region:"",deviceType:"",userId:"",domain:"",events:[],browser:"",deviceManufacturer:"",deviceModel:"",city:"",postalCode:""}}function re(){return{timestampMs:0,type:0,eventName:"",auctionId:"",transactionId:"",adUnitCode:"",bid:void 0,namespace:"",eventId:"",metadata:{},viewableDurationMs:void 0}}function se(){return{key:"",value:""}}function oe(){return{bidder:"",cpm:0,currency:"",width:0,height:0,dealId:"",mediaType:"",latencyMs:0,advertiserDomain:"",creativeId:""}}var c,x,w,O,m,ae=h(()=>{"use strict";ne();c={TRACE_EVENT_TYPE_UNSPECIFIED:0,AUCTION_START:1,AUCTION_END:2,BID_REQUEST:3,BID_RESPONSE:4,BID_WIN:5,BID_TIMEOUT:6,IMPRESSION:7,VIEWABLE:8,TIME_IN_VIEW:14,REFRESH:9,ERROR:10,SLOT_DEFINED:11,SLOT_DESTROYED:12,CLICK:13,NO_BID:15,AD_RENDER_FAILED:16,UNRECOGNIZED:-1};x={encode(t,e=new b){if(t.propertyId!==void 0&&t.propertyId!==""&&e.uint32(10).string(t.propertyId),t.pageviewId!==void 0&&t.pageviewId!==""&&e.uint32(18).string(t.pageviewId),t.sessionId!==void 0&&t.sessionId!==""&&e.uint32(26).string(t.sessionId),t.pageUrl!==void 0&&t.pageUrl!==""&&e.uint32(34).string(t.pageUrl),t.country!==void 0&&t.country!==""&&e.uint32(42).string(t.country),t.region!==void 0&&t.region!==""&&e.uint32(50).string(t.region),t.deviceType!==void 0&&t.deviceType!==""&&e.uint32(58).string(t.deviceType),t.userId!==void 0&&t.userId!==""&&e.uint32(66).string(t.userId),t.domain!==void 0&&t.domain!==""&&e.uint32(74).string(t.domain),t.events!==void 0&&t.events.length!==0)for(let n of t.events)w.encode(n,e.uint32(82).fork()).join();return t.browser!==void 0&&t.browser!==""&&e.uint32(90).string(t.browser),t.deviceManufacturer!==void 0&&t.deviceManufacturer!==""&&e.uint32(98).string(t.deviceManufacturer),t.deviceModel!==void 0&&t.deviceModel!==""&&e.uint32(106).string(t.deviceModel),t.city!==void 0&&t.city!==""&&e.uint32(114).string(t.city),t.postalCode!==void 0&&t.postalCode!==""&&e.uint32(122).string(t.postalCode),e},decode(t,e){let n=t instanceof l?t:new l(t),i=e===void 0?n.len:n.pos+e,r=ie();for(;n.pos<i;){let s=n.uint32();switch(s>>>3){case 1:{if(s!==10)break;r.propertyId=n.string();continue}case 2:{if(s!==18)break;r.pageviewId=n.string();continue}case 3:{if(s!==26)break;r.sessionId=n.string();continue}case 4:{if(s!==34)break;r.pageUrl=n.string();continue}case 5:{if(s!==42)break;r.country=n.string();continue}case 6:{if(s!==50)break;r.region=n.string();continue}case 7:{if(s!==58)break;r.deviceType=n.string();continue}case 8:{if(s!==66)break;r.userId=n.string();continue}case 9:{if(s!==74)break;r.domain=n.string();continue}case 10:{if(s!==82)break;let o=w.decode(n,n.uint32());o!==void 0&&r.events.push(o);continue}case 11:{if(s!==90)break;r.browser=n.string();continue}case 12:{if(s!==98)break;r.deviceManufacturer=n.string();continue}case 13:{if(s!==106)break;r.deviceModel=n.string();continue}case 14:{if(s!==114)break;r.city=n.string();continue}case 15:{if(s!==122)break;r.postalCode=n.string();continue}}if((s&7)===4||s===0)break;n.skip(s&7)}return r},create(t){return x.fromPartial(t??{})},fromPartial(t){let e=ie();return e.propertyId=t.propertyId??"",e.pageviewId=t.pageviewId??"",e.sessionId=t.sessionId??"",e.pageUrl=t.pageUrl??"",e.country=t.country??"",e.region=t.region??"",e.deviceType=t.deviceType??"",e.userId=t.userId??"",e.domain=t.domain??"",e.events=t.events?.map(n=>w.fromPartial(n))||[],e.browser=t.browser??"",e.deviceManufacturer=t.deviceManufacturer??"",e.deviceModel=t.deviceModel??"",e.city=t.city??"",e.postalCode=t.postalCode??"",e}};w={encode(t,e=new b){return t.timestampMs!==void 0&&t.timestampMs!==0&&e.uint32(9).double(t.timestampMs),t.type!==void 0&&t.type!==0&&e.uint32(16).int32(t.type),t.eventName!==void 0&&t.eventName!==""&&e.uint32(26).string(t.eventName),t.auctionId!==void 0&&t.auctionId!==""&&e.uint32(34).string(t.auctionId),t.transactionId!==void 0&&t.transactionId!==""&&e.uint32(42).string(t.transactionId),t.adUnitCode!==void 0&&t.adUnitCode!==""&&e.uint32(50).string(t.adUnitCode),t.bid!==void 0&&m.encode(t.bid,e.uint32(58).fork()).join(),t.namespace!==void 0&&t.namespace!==""&&e.uint32(66).string(t.namespace),t.eventId!==void 0&&t.eventId!==""&&e.uint32(74).string(t.eventId),globalThis.Object.entries(t.metadata||{}).forEach(([n,i])=>{O.encode({key:n,value:i},e.uint32(82).fork()).join()}),t.viewableDurationMs!==void 0&&e.uint32(89).double(t.viewableDurationMs),e},decode(t,e){let n=t instanceof l?t:new l(t),i=e===void 0?n.len:n.pos+e,r=re();for(;n.pos<i;){let s=n.uint32();switch(s>>>3){case 1:{if(s!==9)break;r.timestampMs=n.double();continue}case 2:{if(s!==16)break;r.type=n.int32();continue}case 3:{if(s!==26)break;r.eventName=n.string();continue}case 4:{if(s!==34)break;r.auctionId=n.string();continue}case 5:{if(s!==42)break;r.transactionId=n.string();continue}case 6:{if(s!==50)break;r.adUnitCode=n.string();continue}case 7:{if(s!==58)break;r.bid=m.decode(n,n.uint32());continue}case 8:{if(s!==66)break;r.namespace=n.string();continue}case 9:{if(s!==74)break;r.eventId=n.string();continue}case 10:{if(s!==82)break;let o=O.decode(n,n.uint32());o.value!==void 0&&(r.metadata[o.key]=o.value);continue}case 11:{if(s!==89)break;r.viewableDurationMs=n.double();continue}}if((s&7)===4||s===0)break;n.skip(s&7)}return r},create(t){return w.fromPartial(t??{})},fromPartial(t){let e=re();return e.timestampMs=t.timestampMs??0,e.type=t.type??0,e.eventName=t.eventName??"",e.auctionId=t.auctionId??"",e.transactionId=t.transactionId??"",e.adUnitCode=t.adUnitCode??"",e.bid=t.bid!==void 0&&t.bid!==null?m.fromPartial(t.bid):void 0,e.namespace=t.namespace??"",e.eventId=t.eventId??"",e.metadata=globalThis.Object.entries(t.metadata??{}).reduce((n,[i,r])=>(r!==void 0&&(n[i]=globalThis.String(r)),n),{}),e.viewableDurationMs=t.viewableDurationMs??void 0,e}};O={encode(t,e=new b){return t.key!==""&&e.uint32(10).string(t.key),t.value!==""&&e.uint32(18).string(t.value),e},decode(t,e){let n=t instanceof l?t:new l(t),i=e===void 0?n.len:n.pos+e,r=se();for(;n.pos<i;){let s=n.uint32();switch(s>>>3){case 1:{if(s!==10)break;r.key=n.string();continue}case 2:{if(s!==18)break;r.value=n.string();continue}}if((s&7)===4||s===0)break;n.skip(s&7)}return r},create(t){return O.fromPartial(t??{})},fromPartial(t){let e=se();return e.key=t.key??"",e.value=t.value??"",e}};m={encode(t,e=new b){return t.bidder!==void 0&&t.bidder!==""&&e.uint32(10).string(t.bidder),t.cpm!==void 0&&t.cpm!==0&&e.uint32(17).double(t.cpm),t.currency!==void 0&&t.currency!==""&&e.uint32(26).string(t.currency),t.width!==void 0&&t.width!==0&&e.uint32(32).int32(t.width),t.height!==void 0&&t.height!==0&&e.uint32(40).int32(t.height),t.dealId!==void 0&&t.dealId!==""&&e.uint32(50).string(t.dealId),t.mediaType!==void 0&&t.mediaType!==""&&e.uint32(58).string(t.mediaType),t.latencyMs!==void 0&&t.latencyMs!==0&&e.uint32(65).double(t.latencyMs),t.advertiserDomain!==void 0&&t.advertiserDomain!==""&&e.uint32(74).string(t.advertiserDomain),t.creativeId!==void 0&&t.creativeId!==""&&e.uint32(82).string(t.creativeId),e},decode(t,e){let n=t instanceof l?t:new l(t),i=e===void 0?n.len:n.pos+e,r=oe();for(;n.pos<i;){let s=n.uint32();switch(s>>>3){case 1:{if(s!==10)break;r.bidder=n.string();continue}case 2:{if(s!==17)break;r.cpm=n.double();continue}case 3:{if(s!==26)break;r.currency=n.string();continue}case 4:{if(s!==32)break;r.width=n.int32();continue}case 5:{if(s!==40)break;r.height=n.int32();continue}case 6:{if(s!==50)break;r.dealId=n.string();continue}case 7:{if(s!==58)break;r.mediaType=n.string();continue}case 8:{if(s!==65)break;r.latencyMs=n.double();continue}case 9:{if(s!==74)break;r.advertiserDomain=n.string();continue}case 10:{if(s!==82)break;r.creativeId=n.string();continue}}if((s&7)===4||s===0)break;n.skip(s&7)}return r},create(t){return m.fromPartial(t??{})},fromPartial(t){let e=oe();return e.bidder=t.bidder??"",e.cpm=t.cpm??0,e.currency=t.currency??"",e.width=t.width??0,e.height=t.height??0,e.dealId=t.dealId??"",e.mediaType=t.mediaType??"",e.latencyMs=t.latencyMs??0,e.advertiserDomain=t.advertiserDomain??"",e.creativeId=t.creativeId??"",e}}});function E(){return typeof crypto<"u"&&typeof crypto.randomUUID=="function"?crypto.randomUUID():"xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g,t=>{let e=Math.random()*16|0;return(t==="x"?e:e&3|8).toString(16)})}function fe(){let t=Date.now();T=t;try{typeof localStorage<"u"&&localStorage.setItem(A,t.toString())}catch{}}function Ne(){let t=Date.now();try{if(typeof localStorage<"u"){let e=localStorage.getItem(ce),n=localStorage.getItem(A),i=n&&parseInt(n,10)||0;if(e&&i&&t-i<=ue)return localStorage.setItem(A,t.toString()),e;let r=E();return localStorage.setItem(ce,r),localStorage.setItem(A,t.toString()),r}}catch{}return D&&T&&t-T<=ue?(T=t,D):(D=E(),T=t,D)}function a(t){return String(t??"").replace(/%/g,"%25").replace(/:/g,"%3A")}function _e(t,e){switch(t){case"auctionInit":return`auctionInit:${a(e?.auctionId)}`;case"auctionEnd":return`auctionEnd:${a(e?.auctionId)}`;case"bidRequested":{let n=Array.isArray(e?.bids)?e.bids.map(i=>a(i?.bidId||i?.transactionId||i?.adUnitCode)).join(","):"";return`bidRequested:${a(e?.auctionId)}:${a(e?.bidderCode||e?.bidder)}:${n}`}case"bidResponse":{let n=e||{},i=n.creativeId||n.adId||n.requestId||n.bidId||"",r=n.originalCpm??n.cpm??"";return`bidResponse:${a(n.auctionId)}:${a(n.adUnitCode)}:${a(n.bidderCode||n.bidder)}:${a(i)}:${a(r)}`}case"bidTimeout":return"bidTimeout:"+(Array.isArray(e)?e:e?[e]:[]).map(i=>`${a(i?.auctionId)}:${a(i?.bidderCode||i?.bidder)}:${a(i?.bidId||i?.transactionId||i?.adUnitCode)}`).join(",");case"bidWon":{let n=e||{},i=n.creativeId||n.adId||n.requestId||n.bidId||"",r=n.originalCpm??n.cpm??"";return`bidWon:${a(n.auctionId)}:${a(n.adUnitCode)}:${a(n.bidderCode||n.bidder)}:${a(i)}:${a(r)}`}case"noBid":return`noBid:${a(e?.auctionId)}:${a(e?.adUnitCode)}:${a(e?.bidderCode||e?.bidder)}:${a(e?.bidId||e?.transactionId)}`;case"adRenderFailed":{let n=e?.bid||{};return`adRenderFailed:${a(n.auctionId||e?.auctionId)}:${a(n.adUnitCode||e?.adUnitCode)}:${a(n.bidderCode||n.bidder||e?.bidderCode||e?.bidder)}:${a(e?.reason)}:${a(e?.message)}`}case"adRenderSucceeded":{let n=e?.bid||e||{},i=n.creativeId||n.adId||e?.adId||"",r=n.originalCpm??n.cpm??"";return`adRenderSucceeded:${a(n.auctionId||e?.auctionId)}:${a(n.adUnitCode||e?.adUnitCode)}:${a(n.bidderCode||n.bidder)}:${a(i)}:${a(r)}`}case"setTargeting":return`setTargeting:${Object.keys(e||{}).sort().map(a).join(",")}`;case"auctionDebug":return`auctionDebug:${a(e?.type)}:${a(String(e?.arguments?.[0]??"").slice(0,50))}`;default:return""}}function le(t){if(!t)return{width:0,height:0};let e=t;for(;Array.isArray(e)&&e.length>0&&Array.isArray(e[0]);)e=e[0];if(Array.isArray(e)&&e.length>=2){let n=Number(e[0]),i=Number(e[1]);return{width:Number.isFinite(n)?n:0,height:Number.isFinite(i)?i:0}}return{width:0,height:0}}function L(t){if(Number.isFinite(t?.width)&&Number.isFinite(t?.height))return{width:t.width,height:t.height};if(typeof t?.size=="string"){let e=t.size.match(/^(\d+)x(\d+)$/);if(e)return{width:Number(e[1]),height:Number(e[2])}}return{width:Number.isFinite(t?.width)?t.width:0,height:Number.isFinite(t?.height)?t.height:0}}function I(t){if(!t)return null;if(Array.isArray(t)){let e=t.find(n=>n?.provider==="bidkernel")??t.find(n=>n&&typeof n=="object"&&n.provider===void 0);return e?I(e):null}if(typeof t=="object"){if(t.options&&typeof t.options=="object")return t.options;if(t.config&&typeof t.config=="object")return t.config;if(t.propertyId||t.endpoint)return t}return null}function Pe(t){if(!t)return null;if(t._bidkernelAnalyticsConfig){let e=I(t._bidkernelAnalyticsConfig);if(e)return e}if(t.bidkernelPrebidAnalytics){let e=t.bidkernelPrebidAnalytics;if(e.options){let n=I(e.options);if(n)return n}if(e.config){let n=I(e.config);if(n)return n}if(e.propertyId)return I(e)}return null}function V(t="pbjs",e){let n=typeof window<"u"?window:{};n[t]=n[t]||{};let i=n[t],r=o=>{if(n._bidkernelPrebidAnalytics)try{n._bidkernelPrebidAnalytics.disable()}catch(u){console.warn("[bidkernel] Failed to disable previous analytics instance:",u)}let d=new $({pbjsGlobalName:t,...e,...o});return d.enable(),n._bidkernelPrebidAnalytics=d,d},s=()=>{try{i.adapterManager&&typeof i.adapterManager.registerAnalyticsAdapter=="function"&&i.adapterManager.registerAnalyticsAdapter({adapter:{enableAnalytics:d=>{let u=I(d);u&&r(u)},disableAnalytics:()=>{n._bidkernelPrebidAnalytics&&n._bidkernelPrebidAnalytics.disable()}},code:"bidkernel"});let o=Pe(n);o&&(o.propertyId||e?.propertyId)&&r(o)}catch(o){console.warn("[bidkernel] Failed to register standard Prebid analytics adapter:",o)}};i.adapterManager&&typeof i.adapterManager.registerAnalyticsAdapter=="function"?s():(i.que=i.que||[],i.que.push(s))}var De,de,Ae,B,ke,Re,Se,Ue,ce,A,ue,D,T,q,$,he=h(()=>{"use strict";ae();De=20,de=1e4,Ae=50,B=200,ke=300*1e3,Re=10,Se=32*1024,Ue={auctionStart:c.AUCTION_START,auctionEnd:c.AUCTION_END,bidRequest:c.BID_REQUEST,bidResponse:c.BID_RESPONSE,bidTimeout:c.BID_TIMEOUT,bidWin:c.BID_WIN,noBid:c.NO_BID,adRenderFailed:c.AD_RENDER_FAILED,click:c.CLICK,impression:c.IMPRESSION,refresh:c.REFRESH,timeInView:c.TIME_IN_VIEW,viewable:c.VIEWABLE},ce="_bidkernel_session",A="_bidkernel_session_ts",ue=1800*1e3,D=null,T=0;q=class{seenObjects=new WeakMap;seenKeys=new Set;isDuplicate(e,n){if(!n)return!1;if(typeof n=="object"){let r=this.seenObjects.get(n);if(r){if(r.has(e))return!0;r.add(e)}else this.seenObjects.set(n,new Set([e]))}let i=_e(e,n);if(i){if(this.seenKeys.has(i))return!0;if(this.seenKeys.size>=1e3){let r=this.seenKeys.values().next().value;r!==void 0&&this.seenKeys.delete(r)}this.seenKeys.add(i)}return!1}};$=class{config;queue=[];errorCount=0;flushTimer=null;boundFlushBeacon;boundVisibilityChange;isEnabled=!1;boundPbjsHandlers=[];pageUrl="";deduper=new q;consecutiveSendFailures=0;nextSendAllowedAt=0;replayedEventCount=0;constructor(e){this.config={endpoint:e.endpoint||"",propertyId:e.propertyId||"",pageviewId:e.pageviewId||E(),sessionId:e.sessionId||Ne(),userId:e.userId||"",deviceType:e.deviceType||"desktop",country:e.country||"",region:e.region||"",auctionEnabled:e.auctionEnabled??!0,warningsEnabled:e.warningsEnabled??!0,errorsEnabled:e.errorsEnabled??!0,logLevel:e.logLevel||"INFO",pbjsGlobalName:e.pbjsGlobalName||"pbjs",attachPbjsListeners:e.attachPbjsListeners??!0},this.boundFlushBeacon=()=>this.flushBeacon(),this.boundVisibilityChange=()=>this.handleVisibilityChange()}enable(){if(!this.isEnabled){if(this.isEnabled=!0,this.config.endpoint||this.log("WARN","Endpoint is empty. Analytics events will not be transmitted."),this.config.attachPbjsListeners){let n=(typeof window<"u"?window:{})[this.config.pbjsGlobalName]||{};if(typeof n.onEvent=="function"){this.log("DEBUG","Attaching event listeners to pbjs");let i=[["auctionInit",this.handleAuctionInit.bind(this)],["auctionEnd",this.handleAuctionEnd.bind(this)],["bidRequested",this.handleBidRequested.bind(this)],["bidResponse",this.handleBidResponse.bind(this)],["bidTimeout",this.handleBidTimeout.bind(this)],["bidWon",this.handleBidWon.bind(this)],["noBid",this.handleNoBid.bind(this)],["adRenderFailed",this.handleAdRenderFailed.bind(this)],["adRenderSucceeded",this.handleAdRenderSucceeded.bind(this)]];for(let[r,s]of i)n.onEvent(r,s),this.boundPbjsHandlers.push({event:r,handler:s})}else this.log("WARN","pbjs.onEvent is not defined. Prebid analytics will not function.");if(typeof n.getEvents=="function")try{let i=n.getEvents();if(Array.isArray(i)){let r=i.slice(this.replayedEventCount);if(this.replayedEventCount=i.length,r.length>0){this.log("DEBUG",`Replaying ${r.length} historical events from pbjs.getEvents()`);let s={auctionInit:this.handleAuctionInit.bind(this),auctionEnd:this.handleAuctionEnd.bind(this),bidRequested:this.handleBidRequested.bind(this),bidResponse:this.handleBidResponse.bind(this),bidTimeout:this.handleBidTimeout.bind(this),bidWon:this.handleBidWon.bind(this),noBid:this.handleNoBid.bind(this),adRenderFailed:this.handleAdRenderFailed.bind(this),adRenderSucceeded:this.handleAdRenderSucceeded.bind(this)};for(let o of r){if(!o)continue;let d=o.eventType||o.event||o.name,u=o.args!==void 0?o.args:o.data!==void 0?o.data:o,p=s[d];p&&p(u)}}}}catch(i){this.log("WARN","Failed to replay historical events from pbjs.getEvents()",i)}}if(typeof window<"u"){if(!this.pageUrl)try{let e=new URL(window.location.href);this.pageUrl=e.origin+e.pathname}catch{this.pageUrl=window.location.href}window.addEventListener("pagehide",this.boundFlushBeacon),typeof document<"u"&&document.addEventListener("visibilitychange",this.boundVisibilityChange),this.flushTimer=setInterval(()=>this.flush(),de)}}}disable(){if(this.isEnabled){if(this.isEnabled=!1,this.flushTimer&&(clearInterval(this.flushTimer),this.flushTimer=null),typeof window<"u"&&(window.removeEventListener("pagehide",this.boundFlushBeacon),typeof document<"u"&&document.removeEventListener("visibilitychange",this.boundVisibilityChange)),this.boundPbjsHandlers.length>0){let n=(typeof window<"u"?window:{})[this.config.pbjsGlobalName]||{};if(typeof n.offEvent=="function")for(let{event:i,handler:r}of this.boundPbjsHandlers)n.offEvent(i,r);this.boundPbjsHandlers=[]}this.flush()}}handleVisibilityChange(){typeof document<"u"&&document.visibilityState==="hidden"&&this.flushBeacon()}trackRawEvent(e,n,i){let r=Ue[n]??(e==="ERROR"?c.ERROR:c.TRACE_EVENT_TYPE_UNSPECIFIED);this.enqueue(r,n,i,e)}setUserId(e){this.config.userId=e}setSessionId(e){this.config.sessionId=e}navigate(e,n){if(this.disable(),this.config.pageviewId=e||E(),n)try{let i=new URL(n);this.pageUrl=i.origin+i.pathname}catch{this.pageUrl=n}else this.pageUrl="";fe(),this.enable()}handleAuctionInit(e){this.isDuplicate("auctionInit",e)||(this.log("DEBUG","auctionInit",e),this.enqueue(c.AUCTION_START,"auctionStart",{auctionId:e.auctionId||"",transactionId:e.transactionId||""}))}handleAuctionEnd(e){this.isDuplicate("auctionEnd",e)||(this.log("DEBUG","auctionEnd",e),this.enqueue(c.AUCTION_END,"auctionEnd",{auctionId:e.auctionId||"",transactionId:e.transactionId||""}))}handleBidRequested(e){if(this.isDuplicate("bidRequested",e))return;this.log("DEBUG","bidRequested",e);let n=e.auctionId||"",i=e.bidderCode||e.bidder||"";Array.isArray(e.bids)&&e.bids.forEach(r=>{let s=Object.keys(r.mediaTypes||{}),o=r.ortb2Imp?.ext?.gpid||r.gpid||e.gpid||"",d=r.transactionId||r.ortb2Imp?.id||e.transactionId||"";if(s.length===0){let u=r.mediaType||"banner",{width:p,height:k}=le(r.sizes||r.playerSize);this.enqueue(c.BID_REQUEST,"bidRequest",{auctionId:n,transactionId:d,adUnitCode:r.adUnitCode||"",gpid:o,bid:{bidder:i,mediaType:u,width:p,height:k}});return}s.forEach(u=>{let p=null;u==="banner"?p=r.mediaTypes?.banner?.sizes||r.sizes:u==="video"?p=r.mediaTypes?.video?.playerSize||r.mediaTypes?.video?.sizes||r.playerSize:p=r.mediaTypes?.[u]?.sizes;let{width:k,height:ye}=le(p);this.enqueue(c.BID_REQUEST,"bidRequest",{auctionId:n,transactionId:d,adUnitCode:r.adUnitCode||"",gpid:o,bid:{bidder:i,mediaType:u,width:k,height:ye}})})})}handleBidResponse(e){this.isDuplicate("bidResponse",e)||(this.log("DEBUG","bidResponse",e),this.enqueue(c.BID_RESPONSE,"bidResponse",{auctionId:e.auctionId||"",transactionId:e.transactionId||"",adUnitCode:e.adUnitCode||"",bid:{bidder:e.bidderCode||e.bidder||"",cpm:Number.isFinite(e.originalCpm)?e.originalCpm:Number.isFinite(e.cpm)?e.cpm:0,currency:e.originalCurrency??e.currency??"USD",...L(e),dealId:e.dealId||"",mediaType:e.mediaType||"banner",latencyMs:Number.isFinite(e.timeToRespond)?e.timeToRespond:0,advertiserDomain:e.meta?.advertiserDomains?.[0]||"",creativeId:e.creativeId||""}}))}handleBidTimeout(e){if(this.isDuplicate("bidTimeout",e))return;this.log("DEBUG","bidTimeout",e);let n=Array.isArray(e)?e:e?[e]:[];for(let i of n)this.enqueue(c.BID_TIMEOUT,"bidTimeout",{auctionId:i.auctionId||"",transactionId:i.transactionId||"",adUnitCode:i.adUnitCode||"",bid:{bidder:i.bidderCode||i.bidder||"",latencyMs:Number.isFinite(i.timeout)?i.timeout:0}})}handleBidWon(e){this.isDuplicate("bidWon",e)||(this.log("DEBUG","bidWon",e),this.enqueue(c.BID_WIN,"bidWon",{auctionId:e.auctionId||"",transactionId:e.transactionId||"",adUnitCode:e.adUnitCode||"",bid:{bidder:e.bidderCode||e.bidder||"",cpm:Number.isFinite(e.originalCpm)?e.originalCpm:Number.isFinite(e.cpm)?e.cpm:0,currency:e.originalCurrency??e.currency??"USD",...L(e),dealId:e.dealId||"",mediaType:e.mediaType||"banner",latencyMs:Number.isFinite(e.timeToRespond)?e.timeToRespond:0,advertiserDomain:e.meta?.advertiserDomains?.[0]||"",creativeId:e.creativeId||""}}))}handleNoBid(e){this.isDuplicate("noBid",e)||(this.log("DEBUG","noBid",e),this.enqueue(c.NO_BID,"noBid",{auctionId:e.auctionId||"",transactionId:e.transactionId||"",adUnitCode:e.adUnitCode||"",bid:{bidder:e.bidderCode||e.bidder||""}}))}handleAdRenderFailed(e){if(this.isDuplicate("adRenderFailed",e))return;this.log("DEBUG","adRenderFailed",e);let n=e.bid||{};this.enqueue(c.AD_RENDER_FAILED,"adRenderFailed",{auctionId:n.auctionId||e.auctionId||"",transactionId:n.transactionId||e.transactionId||"",adUnitCode:n.adUnitCode||e.adUnitCode||"",bid:{bidder:n.bidderCode||n.bidder||e.bidderCode||e.bidder||""},metadata:{reason:String(e.reason||""),message:String(e.message||e.error?.message||"")},error:e.error||(e.message?new Error(String(e.message)):void 0)})}handleAdRenderSucceeded(e){if(this.isDuplicate("adRenderSucceeded",e))return;this.log("DEBUG","adRenderSucceeded",e);let n=e.bid||{};this.enqueue(c.IMPRESSION,"impression",{auctionId:n.auctionId||e.auctionId||"",transactionId:n.transactionId||e.transactionId||"",adUnitCode:e.adUnitCode||n.adUnitCode||"",bid:{bidder:n.bidderCode||n.bidder||"",cpm:Number.isFinite(n.originalCpm)?n.originalCpm:Number.isFinite(n.cpm)?n.cpm:0,currency:n.originalCurrency??n.currency??"USD",...L(n),dealId:n.dealId||"",mediaType:n.mediaType||"banner",latencyMs:Number.isFinite(n.timeToRespond)?n.timeToRespond:0,advertiserDomain:n.meta?.advertiserDomains?.[0]||"",creativeId:n.creativeId||""}})}isDuplicate(e,n){return this.deduper.isDuplicate(e,n)}enqueue(e,n,i,r){if(!this.isEnabled||!this.shouldSample(e,r))return;fe();let s={eventId:E(),timestampMs:Date.now(),type:e,eventName:n,auctionId:i.auctionId||"",transactionId:i.transactionId||"",adUnitCode:i.adUnitCode||i.elementId||"",namespace:i.ns||i.namespace||""};i.bid&&(s.bid={bidder:i.bid.bidder||"",cpm:Number.isFinite(i.bid.cpm)?i.bid.cpm:0,currency:i.bid.currency||"",width:Number.isFinite(i.bid.width)?i.bid.width:0,height:Number.isFinite(i.bid.height)?i.bid.height:0,dealId:i.bid.dealId||"",mediaType:i.bid.mediaType||"",latencyMs:Number.isFinite(i.bid.latencyMs)?i.bid.latencyMs:0,advertiserDomain:i.bid.advertiserDomain||"",creativeId:i.bid.creativeId||""}),i.viewableDurationMs!==void 0&&(s.viewableDurationMs=Number.isFinite(i.viewableDurationMs)?i.viewableDurationMs:0);let o={...i.metadata};i.error!==void 0&&i.error!==null&&(o.error=typeof i.error=="object"&&i.error.message?String(i.error.message):String(i.error)),i.gpid&&(o.gpid=String(i.gpid)),Object.keys(o).length>0&&(s.metadata=o),this.queue.push(s),this.queue.length>B&&this.queue.splice(0,this.queue.length-B),this.queue.length>=De&&this.flush()}shouldSample(e,n){return e===c.ERROR?(this.errorCount++,this.errorCount>Ae?!1:this.config.errorsEnabled):n==="WARN"?this.config.warningsEnabled:this.config.auctionEnabled}requeue(e){e.length&&(this.queue=e.concat(this.queue),this.queue.length>B&&this.queue.splice(0,this.queue.length-B))}drainBatch(){if(this.queue.length===0||!this.config.endpoint)return null;let e=this.queue,n=typeof window<"u"?window.location.hostname:"",i=s=>({propertyId:this.config.propertyId,pageviewId:this.config.pageviewId,sessionId:this.config.sessionId,pageUrl:this.pageUrl,country:this.config.country,region:this.config.region,deviceType:this.config.deviceType,userId:this.config.userId,domain:n,events:s}),r=x.encode(i(e)).finish();for(;e.length>1&&r.byteLength>Se;)e=e.slice(0,Math.floor(e.length/2)),r=x.encode(i(e)).finish();return this.queue=this.queue.slice(e.length),{url:`${this.config.endpoint}/${this.config.propertyId}`,encoded:r,events:e}}sendFetch(e,n=!1){let i={method:"POST",headers:{"Content-Type":"application/x-protobuf"},body:e.encoded};n&&(i.keepalive=!0),fetch(e.url,i).then(r=>{if(r.ok)this.consecutiveSendFailures=0,this.nextSendAllowedAt=0;else{if(this.log("WARN",`Failed to send batch: HTTP ${r.status}`),r.status>=400&&r.status<500){this.log("WARN",`Dropping batch due to non-retryable client error HTTP ${r.status}`);return}this.handleSendFailure(e.events)}}).catch(r=>{this.log("ERROR","Failed to send batch",r),this.handleSendFailure(e.events)})}handleSendFailure(e){this.consecutiveSendFailures++;let n=Math.min(de*2**(this.consecutiveSendFailures-1),ke);this.nextSendAllowedAt=Date.now()+n,this.consecutiveSendFailures<=Re?this.requeue(e):this.log("WARN",`Dropping ${e.length} events after ${this.consecutiveSendFailures} consecutive send failures`)}flush(){if(Date.now()<this.nextSendAllowedAt)return;let e=this.drainBatch();for(;e&&(this.sendFetch(e,!1),!(Date.now()<this.nextSendAllowedAt));)e=this.drainBatch()}flushBeacon(){let e=this.drainBatch();for(;e;){let n=!1;if(typeof navigator<"u"&&typeof navigator.sendBeacon=="function")try{let i=new Blob([e.encoded],{type:"application/x-protobuf"});n=navigator.sendBeacon(e.url,i)}catch{n=!1}n||this.sendFetch(e,!0),e=this.drainBatch()}}log(e,n,...i){let r={DEBUG:10,INFO:20,WARN:30,ERROR:40};if(r[e]<r[this.config.logLevel])return;let s=`[bidkernel][prebid-analytics][${e}]`;switch(e){case"DEBUG":console.debug(s,n,...i);break;case"INFO":console.info(s,n,...i);break;case"WARN":console.warn(s,n,...i);break;case"ERROR":console.error(s,n,...i);break}}}});var Me=be(()=>{he();var pe="https://by.bidkernel.io/t",Ce=window._bidkernelPbjsGlobal||"pbjs";V(Ce,{endpoint:pe});window.bidkernelPrebidAnalytics={...window.bidkernelPrebidAnalytics,register:(t,e)=>V(t,{endpoint:pe,...e})}});return Me();})();
package/dist/index.d.mts CHANGED
@@ -44,6 +44,7 @@ declare class BidkernelPrebidAnalytics {
44
44
  private deduper;
45
45
  private consecutiveSendFailures;
46
46
  private nextSendAllowedAt;
47
+ private replayedEventCount;
47
48
  constructor(config: AnalyticsConfig);
48
49
  enable(): void;
49
50
  disable(): void;
package/dist/index.d.ts CHANGED
@@ -44,6 +44,7 @@ declare class BidkernelPrebidAnalytics {
44
44
  private deduper;
45
45
  private consecutiveSendFailures;
46
46
  private nextSendAllowedAt;
47
+ private replayedEventCount;
47
48
  constructor(config: AnalyticsConfig);
48
49
  enable(): void;
49
50
  disable(): void;
package/dist/index.js CHANGED
@@ -657,6 +657,7 @@ var MAX_ERRORS_PER_SESSION = 50;
657
657
  var MAX_QUEUE_SIZE = 200;
658
658
  var MAX_SEND_BACKOFF_MS = 5 * 60 * 1e3;
659
659
  var MAX_CONSECUTIVE_SEND_FAILURES = 10;
660
+ var MAX_PAYLOAD_BYTES = 32 * 1024;
660
661
  var EVENT_NAME_TO_TYPE = {
661
662
  auctionStart: TraceEventType.AUCTION_START,
662
663
  auctionEnd: TraceEventType.AUCTION_END,
@@ -723,47 +724,73 @@ function getOrCreateSessionId() {
723
724
  inMemorySessionTs = now;
724
725
  return inMemorySessionId;
725
726
  }
727
+ function escapeKeyPart(str) {
728
+ return String(str ?? "").replace(/%/g, "%25").replace(/:/g, "%3A");
729
+ }
726
730
  function getPrebidEventKey(eventName, data) {
727
731
  switch (eventName) {
728
732
  case "auctionInit":
729
- return `auctionInit:${data?.auctionId || ""}`;
733
+ return `auctionInit:${escapeKeyPart(data?.auctionId)}`;
730
734
  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 ?? ""}`;
735
+ return `auctionEnd:${escapeKeyPart(data?.auctionId)}`;
736
+ case "bidRequested": {
737
+ const bids = Array.isArray(data?.bids) ? data.bids.map((b) => escapeKeyPart(b?.bidId || b?.transactionId || b?.adUnitCode)).join(",") : "";
738
+ return `bidRequested:${escapeKeyPart(data?.auctionId)}:${escapeKeyPart(data?.bidderCode || data?.bidder)}:${bids}`;
739
+ }
740
+ case "bidResponse": {
741
+ const bid = data || {};
742
+ const uniqueBidId = bid.creativeId || bid.adId || bid.requestId || bid.bidId || "";
743
+ const price = bid.originalCpm ?? bid.cpm ?? "";
744
+ return `bidResponse:${escapeKeyPart(bid.auctionId)}:${escapeKeyPart(bid.adUnitCode)}:${escapeKeyPart(bid.bidderCode || bid.bidder)}:${escapeKeyPart(uniqueBidId)}:${escapeKeyPart(price)}`;
745
+ }
746
+ case "bidTimeout": {
747
+ const items = Array.isArray(data) ? data : data ? [data] : [];
748
+ return "bidTimeout:" + items.map(
749
+ (t) => `${escapeKeyPart(t?.auctionId)}:${escapeKeyPart(t?.bidderCode || t?.bidder)}:${escapeKeyPart(t?.bidId || t?.transactionId || t?.adUnitCode)}`
750
+ ).join(",");
751
+ }
752
+ case "bidWon": {
753
+ const bid = data || {};
754
+ const uniqueBidId = bid.creativeId || bid.adId || bid.requestId || bid.bidId || "";
755
+ const price = bid.originalCpm ?? bid.cpm ?? "";
756
+ return `bidWon:${escapeKeyPart(bid.auctionId)}:${escapeKeyPart(bid.adUnitCode)}:${escapeKeyPart(bid.bidderCode || bid.bidder)}:${escapeKeyPart(uniqueBidId)}:${escapeKeyPart(price)}`;
757
+ }
745
758
  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 || ""}`;
759
+ return `noBid:${escapeKeyPart(data?.auctionId)}:${escapeKeyPart(data?.adUnitCode)}:${escapeKeyPart(data?.bidderCode || data?.bidder)}:${escapeKeyPart(data?.bidId || data?.transactionId)}`;
760
+ case "adRenderFailed": {
761
+ const bid = data?.bid || {};
762
+ return `adRenderFailed:${escapeKeyPart(bid.auctionId || data?.auctionId)}:${escapeKeyPart(bid.adUnitCode || data?.adUnitCode)}:${escapeKeyPart(bid.bidderCode || bid.bidder || data?.bidderCode || data?.bidder)}:${escapeKeyPart(data?.reason)}:${escapeKeyPart(data?.message)}`;
763
+ }
764
+ case "adRenderSucceeded": {
765
+ const bid = data?.bid || data || {};
766
+ const uniqueId = bid.creativeId || bid.adId || data?.adId || "";
767
+ const price = bid.originalCpm ?? bid.cpm ?? "";
768
+ return `adRenderSucceeded:${escapeKeyPart(bid.auctionId || data?.auctionId)}:${escapeKeyPart(bid.adUnitCode || data?.adUnitCode)}:${escapeKeyPart(bid.bidderCode || bid.bidder)}:${escapeKeyPart(uniqueId)}:${escapeKeyPart(price)}`;
769
+ }
751
770
  case "setTargeting":
752
- return `setTargeting:${Object.keys(data || {}).sort().join(",")}`;
771
+ return `setTargeting:${Object.keys(data || {}).sort().map(escapeKeyPart).join(",")}`;
753
772
  case "auctionDebug":
754
- return `auctionDebug:${data?.type || ""}:${String(data?.arguments?.[0] ?? "").slice(0, 50)}`;
773
+ return `auctionDebug:${escapeKeyPart(data?.type)}:${escapeKeyPart(String(data?.arguments?.[0] ?? "").slice(0, 50))}`;
755
774
  default:
756
775
  return "";
757
776
  }
758
777
  }
759
778
  var PrebidEventDeduper = class {
760
- seenObjects = /* @__PURE__ */ new WeakSet();
779
+ // Object identity is tracked per event name: Prebid passes the SAME bid
780
+ // object to bidResponse and later to bidWon, so a bare WeakSet would drop
781
+ // every bidWon as a duplicate of its own bidResponse.
782
+ seenObjects = /* @__PURE__ */ new WeakMap();
761
783
  seenKeys = /* @__PURE__ */ new Set();
762
784
  isDuplicate(eventName, data) {
763
785
  if (!data) return false;
764
786
  if (typeof data === "object") {
765
- if (this.seenObjects.has(data)) return true;
766
- this.seenObjects.add(data);
787
+ const seenEvents = this.seenObjects.get(data);
788
+ if (seenEvents) {
789
+ if (seenEvents.has(eventName)) return true;
790
+ seenEvents.add(eventName);
791
+ } else {
792
+ this.seenObjects.set(data, /* @__PURE__ */ new Set([eventName]));
793
+ }
767
794
  }
768
795
  const key = getPrebidEventKey(eventName, data);
769
796
  if (key) {
@@ -793,6 +820,21 @@ function parseSize(raw) {
793
820
  }
794
821
  return { width: 0, height: 0 };
795
822
  }
823
+ function parseBidDimensions(bid) {
824
+ if (Number.isFinite(bid?.width) && Number.isFinite(bid?.height)) {
825
+ return { width: bid.width, height: bid.height };
826
+ }
827
+ if (typeof bid?.size === "string") {
828
+ const match = bid.size.match(/^(\d+)x(\d+)$/);
829
+ if (match) {
830
+ return { width: Number(match[1]), height: Number(match[2]) };
831
+ }
832
+ }
833
+ return {
834
+ width: Number.isFinite(bid?.width) ? bid.width : 0,
835
+ height: Number.isFinite(bid?.height) ? bid.height : 0
836
+ };
837
+ }
796
838
  var BidkernelPrebidAnalytics = class {
797
839
  config;
798
840
  queue = [];
@@ -808,6 +850,7 @@ var BidkernelPrebidAnalytics = class {
808
850
  deduper = new PrebidEventDeduper();
809
851
  consecutiveSendFailures = 0;
810
852
  nextSendAllowedAt = 0;
853
+ replayedEventCount = 0;
811
854
  constructor(config) {
812
855
  this.config = {
813
856
  endpoint: config.endpoint || "",
@@ -861,28 +904,32 @@ var BidkernelPrebidAnalytics = class {
861
904
  try {
862
905
  const pastEvents = pbjs.getEvents();
863
906
  if (Array.isArray(pastEvents)) {
864
- this.log(
865
- "DEBUG",
866
- `Replaying ${pastEvents.length} historical events from pbjs.getEvents()`
867
- );
868
- const handlerMap = {
869
- auctionInit: this.handleAuctionInit.bind(this),
870
- auctionEnd: this.handleAuctionEnd.bind(this),
871
- bidRequested: this.handleBidRequested.bind(this),
872
- bidResponse: this.handleBidResponse.bind(this),
873
- bidTimeout: this.handleBidTimeout.bind(this),
874
- bidWon: this.handleBidWon.bind(this),
875
- noBid: this.handleNoBid.bind(this),
876
- adRenderFailed: this.handleAdRenderFailed.bind(this),
877
- adRenderSucceeded: this.handleAdRenderSucceeded.bind(this)
878
- };
879
- for (const ev of pastEvents) {
880
- if (!ev) continue;
881
- const eventType = ev.eventType || ev.event || ev.name;
882
- const args = ev.args !== void 0 ? ev.args : ev.data !== void 0 ? ev.data : ev;
883
- const handler = handlerMap[eventType];
884
- if (handler) {
885
- handler(args);
907
+ const newPastEvents = pastEvents.slice(this.replayedEventCount);
908
+ this.replayedEventCount = pastEvents.length;
909
+ if (newPastEvents.length > 0) {
910
+ this.log(
911
+ "DEBUG",
912
+ `Replaying ${newPastEvents.length} historical events from pbjs.getEvents()`
913
+ );
914
+ const handlerMap = {
915
+ auctionInit: this.handleAuctionInit.bind(this),
916
+ auctionEnd: this.handleAuctionEnd.bind(this),
917
+ bidRequested: this.handleBidRequested.bind(this),
918
+ bidResponse: this.handleBidResponse.bind(this),
919
+ bidTimeout: this.handleBidTimeout.bind(this),
920
+ bidWon: this.handleBidWon.bind(this),
921
+ noBid: this.handleNoBid.bind(this),
922
+ adRenderFailed: this.handleAdRenderFailed.bind(this),
923
+ adRenderSucceeded: this.handleAdRenderSucceeded.bind(this)
924
+ };
925
+ for (const ev of newPastEvents) {
926
+ if (!ev) continue;
927
+ const eventType = ev.eventType || ev.event || ev.name;
928
+ const args = ev.args !== void 0 ? ev.args : ev.data !== void 0 ? ev.data : ev;
929
+ const handler = handlerMap[eventType];
930
+ if (handler) {
931
+ handler(args);
932
+ }
886
933
  }
887
934
  }
888
935
  }
@@ -967,30 +1014,34 @@ var BidkernelPrebidAnalytics = class {
967
1014
  if (this.isDuplicate("auctionInit", data)) return;
968
1015
  this.log("DEBUG", "auctionInit", data);
969
1016
  this.enqueue(TraceEventType.AUCTION_START, "auctionStart", {
970
- auctionId: data.auctionId || ""
1017
+ auctionId: data.auctionId || "",
1018
+ transactionId: data.transactionId || ""
971
1019
  });
972
1020
  }
973
1021
  handleAuctionEnd(data) {
974
1022
  if (this.isDuplicate("auctionEnd", data)) return;
975
1023
  this.log("DEBUG", "auctionEnd", data);
976
1024
  this.enqueue(TraceEventType.AUCTION_END, "auctionEnd", {
977
- auctionId: data.auctionId || ""
1025
+ auctionId: data.auctionId || "",
1026
+ transactionId: data.transactionId || ""
978
1027
  });
979
1028
  }
980
1029
  handleBidRequested(data) {
981
1030
  if (this.isDuplicate("bidRequested", data)) return;
982
1031
  this.log("DEBUG", "bidRequested", data);
983
1032
  const auctionId = data.auctionId || "";
984
- const bidder = data.bidderCode || "";
1033
+ const bidder = data.bidderCode || data.bidder || "";
985
1034
  if (Array.isArray(data.bids)) {
986
1035
  data.bids.forEach((bid) => {
987
1036
  const mediaTypes = Object.keys(bid.mediaTypes || {});
988
1037
  const gpid = bid.ortb2Imp?.ext?.gpid || bid.gpid || data.gpid || "";
1038
+ const transactionId = bid.transactionId || bid.ortb2Imp?.id || data.transactionId || "";
989
1039
  if (mediaTypes.length === 0) {
990
1040
  const mediaType = bid.mediaType || "banner";
991
1041
  const { width, height } = parseSize(bid.sizes || bid.playerSize);
992
1042
  this.enqueue(TraceEventType.BID_REQUEST, "bidRequest", {
993
1043
  auctionId,
1044
+ transactionId,
994
1045
  adUnitCode: bid.adUnitCode || "",
995
1046
  gpid,
996
1047
  bid: {
@@ -1014,6 +1065,7 @@ var BidkernelPrebidAnalytics = class {
1014
1065
  const { width, height } = parseSize(rawSize);
1015
1066
  this.enqueue(TraceEventType.BID_REQUEST, "bidRequest", {
1016
1067
  auctionId,
1068
+ transactionId,
1017
1069
  adUnitCode: bid.adUnitCode || "",
1018
1070
  gpid,
1019
1071
  bid: {
@@ -1032,13 +1084,13 @@ var BidkernelPrebidAnalytics = class {
1032
1084
  this.log("DEBUG", "bidResponse", data);
1033
1085
  this.enqueue(TraceEventType.BID_RESPONSE, "bidResponse", {
1034
1086
  auctionId: data.auctionId || "",
1087
+ transactionId: data.transactionId || "",
1035
1088
  adUnitCode: data.adUnitCode || "",
1036
1089
  bid: {
1037
1090
  bidder: data.bidderCode || data.bidder || "",
1038
1091
  cpm: Number.isFinite(data.originalCpm) ? data.originalCpm : Number.isFinite(data.cpm) ? data.cpm : 0,
1039
1092
  currency: data.originalCurrency ?? data.currency ?? "USD",
1040
- width: Number.isFinite(data.width) ? data.width : 0,
1041
- height: Number.isFinite(data.height) ? data.height : 0,
1093
+ ...parseBidDimensions(data),
1042
1094
  dealId: data.dealId || "",
1043
1095
  mediaType: data.mediaType || "banner",
1044
1096
  latencyMs: Number.isFinite(data.timeToRespond) ? data.timeToRespond : 0,
@@ -1050,15 +1102,16 @@ var BidkernelPrebidAnalytics = class {
1050
1102
  handleBidTimeout(data) {
1051
1103
  if (this.isDuplicate("bidTimeout", data)) return;
1052
1104
  this.log("DEBUG", "bidTimeout", data);
1053
- if (Array.isArray(data)) {
1054
- data.forEach((t) => {
1055
- this.enqueue(TraceEventType.BID_TIMEOUT, "bidTimeout", {
1056
- auctionId: t.auctionId || "",
1057
- adUnitCode: t.adUnitCode || "",
1058
- bid: {
1059
- bidder: t.bidder || ""
1060
- }
1061
- });
1105
+ const items = Array.isArray(data) ? data : data ? [data] : [];
1106
+ for (const t of items) {
1107
+ this.enqueue(TraceEventType.BID_TIMEOUT, "bidTimeout", {
1108
+ auctionId: t.auctionId || "",
1109
+ transactionId: t.transactionId || "",
1110
+ adUnitCode: t.adUnitCode || "",
1111
+ bid: {
1112
+ bidder: t.bidderCode || t.bidder || "",
1113
+ latencyMs: Number.isFinite(t.timeout) ? t.timeout : 0
1114
+ }
1062
1115
  });
1063
1116
  }
1064
1117
  }
@@ -1067,13 +1120,13 @@ var BidkernelPrebidAnalytics = class {
1067
1120
  this.log("DEBUG", "bidWon", data);
1068
1121
  this.enqueue(TraceEventType.BID_WIN, "bidWon", {
1069
1122
  auctionId: data.auctionId || "",
1123
+ transactionId: data.transactionId || "",
1070
1124
  adUnitCode: data.adUnitCode || "",
1071
1125
  bid: {
1072
1126
  bidder: data.bidderCode || data.bidder || "",
1073
1127
  cpm: Number.isFinite(data.originalCpm) ? data.originalCpm : Number.isFinite(data.cpm) ? data.cpm : 0,
1074
1128
  currency: data.originalCurrency ?? data.currency ?? "USD",
1075
- width: Number.isFinite(data.width) ? data.width : 0,
1076
- height: Number.isFinite(data.height) ? data.height : 0,
1129
+ ...parseBidDimensions(data),
1077
1130
  dealId: data.dealId || "",
1078
1131
  mediaType: data.mediaType || "banner",
1079
1132
  latencyMs: Number.isFinite(data.timeToRespond) ? data.timeToRespond : 0,
@@ -1087,6 +1140,7 @@ var BidkernelPrebidAnalytics = class {
1087
1140
  this.log("DEBUG", "noBid", data);
1088
1141
  this.enqueue(TraceEventType.NO_BID, "noBid", {
1089
1142
  auctionId: data.auctionId || "",
1143
+ transactionId: data.transactionId || "",
1090
1144
  adUnitCode: data.adUnitCode || "",
1091
1145
  bid: {
1092
1146
  bidder: data.bidderCode || data.bidder || ""
@@ -1096,16 +1150,19 @@ var BidkernelPrebidAnalytics = class {
1096
1150
  handleAdRenderFailed(data) {
1097
1151
  if (this.isDuplicate("adRenderFailed", data)) return;
1098
1152
  this.log("DEBUG", "adRenderFailed", data);
1153
+ const bid = data.bid || {};
1099
1154
  this.enqueue(TraceEventType.AD_RENDER_FAILED, "adRenderFailed", {
1100
- auctionId: data.bid?.auctionId || "",
1101
- adUnitCode: data.bid?.adUnitCode || "",
1155
+ auctionId: bid.auctionId || data.auctionId || "",
1156
+ transactionId: bid.transactionId || data.transactionId || "",
1157
+ adUnitCode: bid.adUnitCode || data.adUnitCode || "",
1102
1158
  bid: {
1103
- bidder: data.bid?.bidderCode || data.bid?.bidder || ""
1159
+ bidder: bid.bidderCode || bid.bidder || data.bidderCode || data.bidder || ""
1104
1160
  },
1105
1161
  metadata: {
1106
1162
  reason: String(data.reason || ""),
1107
- message: String(data.message || "")
1108
- }
1163
+ message: String(data.message || data.error?.message || "")
1164
+ },
1165
+ error: data.error || (data.message ? new Error(String(data.message)) : void 0)
1109
1166
  });
1110
1167
  }
1111
1168
  // Prebid's adRenderSucceeded payload is { doc, bid, adId }: the winning bid
@@ -1115,14 +1172,14 @@ var BidkernelPrebidAnalytics = class {
1115
1172
  this.log("DEBUG", "adRenderSucceeded", data);
1116
1173
  const bid = data.bid || {};
1117
1174
  this.enqueue(TraceEventType.IMPRESSION, "impression", {
1118
- auctionId: bid.auctionId || "",
1175
+ auctionId: bid.auctionId || data.auctionId || "",
1176
+ transactionId: bid.transactionId || data.transactionId || "",
1119
1177
  adUnitCode: data.adUnitCode || bid.adUnitCode || "",
1120
1178
  bid: {
1121
1179
  bidder: bid.bidderCode || bid.bidder || "",
1122
1180
  cpm: Number.isFinite(bid.originalCpm) ? bid.originalCpm : Number.isFinite(bid.cpm) ? bid.cpm : 0,
1123
1181
  currency: bid.originalCurrency ?? bid.currency ?? "USD",
1124
- width: Number.isFinite(bid.width) ? bid.width : 0,
1125
- height: Number.isFinite(bid.height) ? bid.height : 0,
1182
+ ...parseBidDimensions(bid),
1126
1183
  dealId: bid.dealId || "",
1127
1184
  mediaType: bid.mediaType || "banner",
1128
1185
  latencyMs: Number.isFinite(bid.timeToRespond) ? bid.timeToRespond : 0,
@@ -1137,6 +1194,7 @@ var BidkernelPrebidAnalytics = class {
1137
1194
  enqueue(type, eventName, data, level) {
1138
1195
  if (!this.isEnabled) return;
1139
1196
  if (!this.shouldSample(type, level)) return;
1197
+ extendSession();
1140
1198
  const protoEvent = {
1141
1199
  eventId: generateUUID(),
1142
1200
  timestampMs: Date.now(),
@@ -1151,11 +1209,14 @@ var BidkernelPrebidAnalytics = class {
1151
1209
  protoEvent.bid = {
1152
1210
  bidder: data.bid.bidder || "",
1153
1211
  cpm: Number.isFinite(data.bid.cpm) ? data.bid.cpm : 0,
1154
- currency: data.bid.currency || "USD",
1212
+ // No defaults here: handlers with a priced bid (bidResponse, bidWon,
1213
+ // impression) set currency/mediaType themselves. Defaulting for the
1214
+ // rest would stamp fake "USD"/"banner" on noBid and bidRequest rows.
1215
+ currency: data.bid.currency || "",
1155
1216
  width: Number.isFinite(data.bid.width) ? data.bid.width : 0,
1156
1217
  height: Number.isFinite(data.bid.height) ? data.bid.height : 0,
1157
1218
  dealId: data.bid.dealId || "",
1158
- mediaType: data.bid.mediaType || "banner",
1219
+ mediaType: data.bid.mediaType || "",
1159
1220
  latencyMs: Number.isFinite(data.bid.latencyMs) ? data.bid.latencyMs : 0,
1160
1221
  advertiserDomain: data.bid.advertiserDomain || "",
1161
1222
  creativeId: data.bid.creativeId || ""
@@ -1200,14 +1261,13 @@ var BidkernelPrebidAnalytics = class {
1200
1261
  this.queue.splice(0, this.queue.length - MAX_QUEUE_SIZE);
1201
1262
  }
1202
1263
  }
1203
- // Drains the queue and returns the encoded batch plus target URL and event list,
1204
- // or null if there is nothing to send. Shared by flush() and flushBeacon().
1264
+ // Drains a batch (up to MAX_PAYLOAD_BYTES) from the queue.
1265
+ // Shared by flush() and flushBeacon().
1205
1266
  drainBatch() {
1206
1267
  if (this.queue.length === 0 || !this.config.endpoint) return null;
1207
- const events = this.queue;
1208
- this.queue = [];
1268
+ let events = this.queue;
1209
1269
  const domain = typeof window !== "undefined" ? window.location.hostname : "";
1210
- const batch = {
1270
+ const buildBatch = (evts) => ({
1211
1271
  propertyId: this.config.propertyId,
1212
1272
  pageviewId: this.config.pageviewId,
1213
1273
  sessionId: this.config.sessionId,
@@ -1217,25 +1277,42 @@ var BidkernelPrebidAnalytics = class {
1217
1277
  deviceType: this.config.deviceType,
1218
1278
  userId: this.config.userId,
1219
1279
  domain,
1220
- events
1221
- };
1280
+ events: evts
1281
+ });
1282
+ let encoded = TraceEventBatch.encode(
1283
+ buildBatch(events)
1284
+ ).finish();
1285
+ while (events.length > 1 && encoded.byteLength > MAX_PAYLOAD_BYTES) {
1286
+ events = events.slice(0, Math.floor(events.length / 2));
1287
+ encoded = TraceEventBatch.encode(
1288
+ buildBatch(events)
1289
+ ).finish();
1290
+ }
1291
+ this.queue = this.queue.slice(events.length);
1222
1292
  return {
1223
1293
  url: `${this.config.endpoint}/${this.config.propertyId}`,
1224
1294
  // protobufjs types finish() as Uint8Array<ArrayBufferLike>; the buffer is
1225
1295
  // always a plain ArrayBuffer, so narrow for fetch/Blob compatibility.
1226
- encoded: TraceEventBatch.encode(batch).finish(),
1296
+ encoded,
1227
1297
  events
1228
1298
  };
1229
1299
  }
1230
- sendFetch(payload) {
1231
- fetch(payload.url, {
1300
+ sendFetch(payload, useKeepalive = false) {
1301
+ const fetchOpts = {
1232
1302
  method: "POST",
1233
1303
  headers: { "Content-Type": "application/x-protobuf" },
1234
- body: payload.encoded,
1235
- keepalive: true
1236
- }).then((res) => {
1304
+ body: payload.encoded
1305
+ };
1306
+ if (useKeepalive) {
1307
+ fetchOpts.keepalive = true;
1308
+ }
1309
+ fetch(payload.url, fetchOpts).then((res) => {
1237
1310
  if (!res.ok) {
1238
1311
  this.log("WARN", `Failed to send batch: HTTP ${res.status}`);
1312
+ if (res.status >= 400 && res.status < 500) {
1313
+ this.log("WARN", `Dropping batch due to non-retryable client error HTTP ${res.status}`);
1314
+ return;
1315
+ }
1239
1316
  this.handleSendFailure(payload.events);
1240
1317
  } else {
1241
1318
  this.consecutiveSendFailures = 0;
@@ -1264,24 +1341,31 @@ var BidkernelPrebidAnalytics = class {
1264
1341
  }
1265
1342
  flush() {
1266
1343
  if (Date.now() < this.nextSendAllowedAt) return;
1267
- const payload = this.drainBatch();
1268
- if (!payload) return;
1269
- this.sendFetch(payload);
1344
+ let payload = this.drainBatch();
1345
+ while (payload) {
1346
+ this.sendFetch(payload, false);
1347
+ if (Date.now() < this.nextSendAllowedAt) break;
1348
+ payload = this.drainBatch();
1349
+ }
1270
1350
  }
1271
1351
  flushBeacon() {
1272
- const payload = this.drainBatch();
1273
- if (!payload) return;
1274
- let sent = false;
1275
- if (typeof navigator !== "undefined" && typeof navigator.sendBeacon === "function") {
1276
- try {
1277
- const blob = new Blob([payload.encoded], { type: "application/x-protobuf" });
1278
- sent = navigator.sendBeacon(payload.url, blob);
1279
- } catch {
1280
- sent = false;
1352
+ let payload = this.drainBatch();
1353
+ while (payload) {
1354
+ let sent = false;
1355
+ if (typeof navigator !== "undefined" && typeof navigator.sendBeacon === "function") {
1356
+ try {
1357
+ const blob = new Blob([payload.encoded], {
1358
+ type: "application/x-protobuf"
1359
+ });
1360
+ sent = navigator.sendBeacon(payload.url, blob);
1361
+ } catch {
1362
+ sent = false;
1363
+ }
1281
1364
  }
1282
- }
1283
- if (!sent) {
1284
- this.sendFetch(payload);
1365
+ if (!sent) {
1366
+ this.sendFetch(payload, true);
1367
+ }
1368
+ payload = this.drainBatch();
1285
1369
  }
1286
1370
  }
1287
1371
  log(level, msg, ...args) {
package/dist/index.mjs CHANGED
@@ -627,6 +627,7 @@ var MAX_ERRORS_PER_SESSION = 50;
627
627
  var MAX_QUEUE_SIZE = 200;
628
628
  var MAX_SEND_BACKOFF_MS = 5 * 60 * 1e3;
629
629
  var MAX_CONSECUTIVE_SEND_FAILURES = 10;
630
+ var MAX_PAYLOAD_BYTES = 32 * 1024;
630
631
  var EVENT_NAME_TO_TYPE = {
631
632
  auctionStart: TraceEventType.AUCTION_START,
632
633
  auctionEnd: TraceEventType.AUCTION_END,
@@ -693,47 +694,73 @@ function getOrCreateSessionId() {
693
694
  inMemorySessionTs = now;
694
695
  return inMemorySessionId;
695
696
  }
697
+ function escapeKeyPart(str) {
698
+ return String(str ?? "").replace(/%/g, "%25").replace(/:/g, "%3A");
699
+ }
696
700
  function getPrebidEventKey(eventName, data) {
697
701
  switch (eventName) {
698
702
  case "auctionInit":
699
- return `auctionInit:${data?.auctionId || ""}`;
703
+ return `auctionInit:${escapeKeyPart(data?.auctionId)}`;
700
704
  case "auctionEnd":
701
- return `auctionEnd:${data?.auctionId || ""}`;
702
- case "bidRequested":
703
- return `bidRequested:${data?.auctionId || ""}:${data?.bidderCode || ""}:${Array.isArray(data?.bids) ? data.bids.map((b) => b?.bidId || b?.adUnitCode || "").join(",") : ""}`;
704
- case "bidResponse":
705
- return `bidResponse:${data?.auctionId || ""}:${data?.adUnitCode || ""}:${data?.bidderCode || data?.bidder || ""}:${data?.creativeId || data?.adId || data?.requestId || ""}:${data?.originalCpm ?? data?.cpm ?? ""}`;
706
- case "bidTimeout":
707
- if (Array.isArray(data)) {
708
- return "bidTimeout:" + data.map(
709
- (t) => `${t?.auctionId || ""}:${t?.bidder || t?.bidderCode || ""}:${t?.bidId || t?.adUnitCode || ""}`
710
- ).join(",");
711
- }
712
- return `bidTimeout:${data?.auctionId || ""}:${data?.bidder || data?.bidderCode || ""}:${data?.bidId || data?.adUnitCode || ""}`;
713
- case "bidWon":
714
- return `bidWon:${data?.auctionId || ""}:${data?.adUnitCode || ""}:${data?.bidderCode || data?.bidder || ""}:${data?.creativeId || data?.adId || data?.requestId || ""}:${data?.originalCpm ?? data?.cpm ?? ""}`;
705
+ return `auctionEnd:${escapeKeyPart(data?.auctionId)}`;
706
+ case "bidRequested": {
707
+ const bids = Array.isArray(data?.bids) ? data.bids.map((b) => escapeKeyPart(b?.bidId || b?.transactionId || b?.adUnitCode)).join(",") : "";
708
+ return `bidRequested:${escapeKeyPart(data?.auctionId)}:${escapeKeyPart(data?.bidderCode || data?.bidder)}:${bids}`;
709
+ }
710
+ case "bidResponse": {
711
+ const bid = data || {};
712
+ const uniqueBidId = bid.creativeId || bid.adId || bid.requestId || bid.bidId || "";
713
+ const price = bid.originalCpm ?? bid.cpm ?? "";
714
+ return `bidResponse:${escapeKeyPart(bid.auctionId)}:${escapeKeyPart(bid.adUnitCode)}:${escapeKeyPart(bid.bidderCode || bid.bidder)}:${escapeKeyPart(uniqueBidId)}:${escapeKeyPart(price)}`;
715
+ }
716
+ case "bidTimeout": {
717
+ const items = Array.isArray(data) ? data : data ? [data] : [];
718
+ return "bidTimeout:" + items.map(
719
+ (t) => `${escapeKeyPart(t?.auctionId)}:${escapeKeyPart(t?.bidderCode || t?.bidder)}:${escapeKeyPart(t?.bidId || t?.transactionId || t?.adUnitCode)}`
720
+ ).join(",");
721
+ }
722
+ case "bidWon": {
723
+ const bid = data || {};
724
+ const uniqueBidId = bid.creativeId || bid.adId || bid.requestId || bid.bidId || "";
725
+ const price = bid.originalCpm ?? bid.cpm ?? "";
726
+ return `bidWon:${escapeKeyPart(bid.auctionId)}:${escapeKeyPart(bid.adUnitCode)}:${escapeKeyPart(bid.bidderCode || bid.bidder)}:${escapeKeyPart(uniqueBidId)}:${escapeKeyPart(price)}`;
727
+ }
715
728
  case "noBid":
716
- return `noBid:${data?.auctionId || ""}:${data?.adUnitCode || ""}:${data?.bidderCode || data?.bidder || ""}:${data?.bidId || ""}`;
717
- case "adRenderFailed":
718
- return `adRenderFailed:${data?.bid?.auctionId || data?.auctionId || ""}:${data?.bid?.adUnitCode || data?.adUnitCode || ""}:${data?.bid?.bidderCode || data?.bid?.bidder || ""}:${data?.reason || ""}:${data?.message || ""}`;
719
- case "adRenderSucceeded":
720
- return `adRenderSucceeded:${data?.bid?.auctionId || data?.auctionId || ""}:${data?.bid?.adUnitCode || data?.adUnitCode || ""}:${data?.bid?.bidderCode || data?.bid?.bidder || ""}`;
729
+ return `noBid:${escapeKeyPart(data?.auctionId)}:${escapeKeyPart(data?.adUnitCode)}:${escapeKeyPart(data?.bidderCode || data?.bidder)}:${escapeKeyPart(data?.bidId || data?.transactionId)}`;
730
+ case "adRenderFailed": {
731
+ const bid = data?.bid || {};
732
+ return `adRenderFailed:${escapeKeyPart(bid.auctionId || data?.auctionId)}:${escapeKeyPart(bid.adUnitCode || data?.adUnitCode)}:${escapeKeyPart(bid.bidderCode || bid.bidder || data?.bidderCode || data?.bidder)}:${escapeKeyPart(data?.reason)}:${escapeKeyPart(data?.message)}`;
733
+ }
734
+ case "adRenderSucceeded": {
735
+ const bid = data?.bid || data || {};
736
+ const uniqueId = bid.creativeId || bid.adId || data?.adId || "";
737
+ const price = bid.originalCpm ?? bid.cpm ?? "";
738
+ return `adRenderSucceeded:${escapeKeyPart(bid.auctionId || data?.auctionId)}:${escapeKeyPart(bid.adUnitCode || data?.adUnitCode)}:${escapeKeyPart(bid.bidderCode || bid.bidder)}:${escapeKeyPart(uniqueId)}:${escapeKeyPart(price)}`;
739
+ }
721
740
  case "setTargeting":
722
- return `setTargeting:${Object.keys(data || {}).sort().join(",")}`;
741
+ return `setTargeting:${Object.keys(data || {}).sort().map(escapeKeyPart).join(",")}`;
723
742
  case "auctionDebug":
724
- return `auctionDebug:${data?.type || ""}:${String(data?.arguments?.[0] ?? "").slice(0, 50)}`;
743
+ return `auctionDebug:${escapeKeyPart(data?.type)}:${escapeKeyPart(String(data?.arguments?.[0] ?? "").slice(0, 50))}`;
725
744
  default:
726
745
  return "";
727
746
  }
728
747
  }
729
748
  var PrebidEventDeduper = class {
730
- seenObjects = /* @__PURE__ */ new WeakSet();
749
+ // Object identity is tracked per event name: Prebid passes the SAME bid
750
+ // object to bidResponse and later to bidWon, so a bare WeakSet would drop
751
+ // every bidWon as a duplicate of its own bidResponse.
752
+ seenObjects = /* @__PURE__ */ new WeakMap();
731
753
  seenKeys = /* @__PURE__ */ new Set();
732
754
  isDuplicate(eventName, data) {
733
755
  if (!data) return false;
734
756
  if (typeof data === "object") {
735
- if (this.seenObjects.has(data)) return true;
736
- this.seenObjects.add(data);
757
+ const seenEvents = this.seenObjects.get(data);
758
+ if (seenEvents) {
759
+ if (seenEvents.has(eventName)) return true;
760
+ seenEvents.add(eventName);
761
+ } else {
762
+ this.seenObjects.set(data, /* @__PURE__ */ new Set([eventName]));
763
+ }
737
764
  }
738
765
  const key = getPrebidEventKey(eventName, data);
739
766
  if (key) {
@@ -763,6 +790,21 @@ function parseSize(raw) {
763
790
  }
764
791
  return { width: 0, height: 0 };
765
792
  }
793
+ function parseBidDimensions(bid) {
794
+ if (Number.isFinite(bid?.width) && Number.isFinite(bid?.height)) {
795
+ return { width: bid.width, height: bid.height };
796
+ }
797
+ if (typeof bid?.size === "string") {
798
+ const match = bid.size.match(/^(\d+)x(\d+)$/);
799
+ if (match) {
800
+ return { width: Number(match[1]), height: Number(match[2]) };
801
+ }
802
+ }
803
+ return {
804
+ width: Number.isFinite(bid?.width) ? bid.width : 0,
805
+ height: Number.isFinite(bid?.height) ? bid.height : 0
806
+ };
807
+ }
766
808
  var BidkernelPrebidAnalytics = class {
767
809
  config;
768
810
  queue = [];
@@ -778,6 +820,7 @@ var BidkernelPrebidAnalytics = class {
778
820
  deduper = new PrebidEventDeduper();
779
821
  consecutiveSendFailures = 0;
780
822
  nextSendAllowedAt = 0;
823
+ replayedEventCount = 0;
781
824
  constructor(config) {
782
825
  this.config = {
783
826
  endpoint: config.endpoint || "",
@@ -831,28 +874,32 @@ var BidkernelPrebidAnalytics = class {
831
874
  try {
832
875
  const pastEvents = pbjs.getEvents();
833
876
  if (Array.isArray(pastEvents)) {
834
- this.log(
835
- "DEBUG",
836
- `Replaying ${pastEvents.length} historical events from pbjs.getEvents()`
837
- );
838
- const handlerMap = {
839
- auctionInit: this.handleAuctionInit.bind(this),
840
- auctionEnd: this.handleAuctionEnd.bind(this),
841
- bidRequested: this.handleBidRequested.bind(this),
842
- bidResponse: this.handleBidResponse.bind(this),
843
- bidTimeout: this.handleBidTimeout.bind(this),
844
- bidWon: this.handleBidWon.bind(this),
845
- noBid: this.handleNoBid.bind(this),
846
- adRenderFailed: this.handleAdRenderFailed.bind(this),
847
- adRenderSucceeded: this.handleAdRenderSucceeded.bind(this)
848
- };
849
- for (const ev of pastEvents) {
850
- if (!ev) continue;
851
- const eventType = ev.eventType || ev.event || ev.name;
852
- const args = ev.args !== void 0 ? ev.args : ev.data !== void 0 ? ev.data : ev;
853
- const handler = handlerMap[eventType];
854
- if (handler) {
855
- handler(args);
877
+ const newPastEvents = pastEvents.slice(this.replayedEventCount);
878
+ this.replayedEventCount = pastEvents.length;
879
+ if (newPastEvents.length > 0) {
880
+ this.log(
881
+ "DEBUG",
882
+ `Replaying ${newPastEvents.length} historical events from pbjs.getEvents()`
883
+ );
884
+ const handlerMap = {
885
+ auctionInit: this.handleAuctionInit.bind(this),
886
+ auctionEnd: this.handleAuctionEnd.bind(this),
887
+ bidRequested: this.handleBidRequested.bind(this),
888
+ bidResponse: this.handleBidResponse.bind(this),
889
+ bidTimeout: this.handleBidTimeout.bind(this),
890
+ bidWon: this.handleBidWon.bind(this),
891
+ noBid: this.handleNoBid.bind(this),
892
+ adRenderFailed: this.handleAdRenderFailed.bind(this),
893
+ adRenderSucceeded: this.handleAdRenderSucceeded.bind(this)
894
+ };
895
+ for (const ev of newPastEvents) {
896
+ if (!ev) continue;
897
+ const eventType = ev.eventType || ev.event || ev.name;
898
+ const args = ev.args !== void 0 ? ev.args : ev.data !== void 0 ? ev.data : ev;
899
+ const handler = handlerMap[eventType];
900
+ if (handler) {
901
+ handler(args);
902
+ }
856
903
  }
857
904
  }
858
905
  }
@@ -937,30 +984,34 @@ var BidkernelPrebidAnalytics = class {
937
984
  if (this.isDuplicate("auctionInit", data)) return;
938
985
  this.log("DEBUG", "auctionInit", data);
939
986
  this.enqueue(TraceEventType.AUCTION_START, "auctionStart", {
940
- auctionId: data.auctionId || ""
987
+ auctionId: data.auctionId || "",
988
+ transactionId: data.transactionId || ""
941
989
  });
942
990
  }
943
991
  handleAuctionEnd(data) {
944
992
  if (this.isDuplicate("auctionEnd", data)) return;
945
993
  this.log("DEBUG", "auctionEnd", data);
946
994
  this.enqueue(TraceEventType.AUCTION_END, "auctionEnd", {
947
- auctionId: data.auctionId || ""
995
+ auctionId: data.auctionId || "",
996
+ transactionId: data.transactionId || ""
948
997
  });
949
998
  }
950
999
  handleBidRequested(data) {
951
1000
  if (this.isDuplicate("bidRequested", data)) return;
952
1001
  this.log("DEBUG", "bidRequested", data);
953
1002
  const auctionId = data.auctionId || "";
954
- const bidder = data.bidderCode || "";
1003
+ const bidder = data.bidderCode || data.bidder || "";
955
1004
  if (Array.isArray(data.bids)) {
956
1005
  data.bids.forEach((bid) => {
957
1006
  const mediaTypes = Object.keys(bid.mediaTypes || {});
958
1007
  const gpid = bid.ortb2Imp?.ext?.gpid || bid.gpid || data.gpid || "";
1008
+ const transactionId = bid.transactionId || bid.ortb2Imp?.id || data.transactionId || "";
959
1009
  if (mediaTypes.length === 0) {
960
1010
  const mediaType = bid.mediaType || "banner";
961
1011
  const { width, height } = parseSize(bid.sizes || bid.playerSize);
962
1012
  this.enqueue(TraceEventType.BID_REQUEST, "bidRequest", {
963
1013
  auctionId,
1014
+ transactionId,
964
1015
  adUnitCode: bid.adUnitCode || "",
965
1016
  gpid,
966
1017
  bid: {
@@ -984,6 +1035,7 @@ var BidkernelPrebidAnalytics = class {
984
1035
  const { width, height } = parseSize(rawSize);
985
1036
  this.enqueue(TraceEventType.BID_REQUEST, "bidRequest", {
986
1037
  auctionId,
1038
+ transactionId,
987
1039
  adUnitCode: bid.adUnitCode || "",
988
1040
  gpid,
989
1041
  bid: {
@@ -1002,13 +1054,13 @@ var BidkernelPrebidAnalytics = class {
1002
1054
  this.log("DEBUG", "bidResponse", data);
1003
1055
  this.enqueue(TraceEventType.BID_RESPONSE, "bidResponse", {
1004
1056
  auctionId: data.auctionId || "",
1057
+ transactionId: data.transactionId || "",
1005
1058
  adUnitCode: data.adUnitCode || "",
1006
1059
  bid: {
1007
1060
  bidder: data.bidderCode || data.bidder || "",
1008
1061
  cpm: Number.isFinite(data.originalCpm) ? data.originalCpm : Number.isFinite(data.cpm) ? data.cpm : 0,
1009
1062
  currency: data.originalCurrency ?? data.currency ?? "USD",
1010
- width: Number.isFinite(data.width) ? data.width : 0,
1011
- height: Number.isFinite(data.height) ? data.height : 0,
1063
+ ...parseBidDimensions(data),
1012
1064
  dealId: data.dealId || "",
1013
1065
  mediaType: data.mediaType || "banner",
1014
1066
  latencyMs: Number.isFinite(data.timeToRespond) ? data.timeToRespond : 0,
@@ -1020,15 +1072,16 @@ var BidkernelPrebidAnalytics = class {
1020
1072
  handleBidTimeout(data) {
1021
1073
  if (this.isDuplicate("bidTimeout", data)) return;
1022
1074
  this.log("DEBUG", "bidTimeout", data);
1023
- if (Array.isArray(data)) {
1024
- data.forEach((t) => {
1025
- this.enqueue(TraceEventType.BID_TIMEOUT, "bidTimeout", {
1026
- auctionId: t.auctionId || "",
1027
- adUnitCode: t.adUnitCode || "",
1028
- bid: {
1029
- bidder: t.bidder || ""
1030
- }
1031
- });
1075
+ const items = Array.isArray(data) ? data : data ? [data] : [];
1076
+ for (const t of items) {
1077
+ this.enqueue(TraceEventType.BID_TIMEOUT, "bidTimeout", {
1078
+ auctionId: t.auctionId || "",
1079
+ transactionId: t.transactionId || "",
1080
+ adUnitCode: t.adUnitCode || "",
1081
+ bid: {
1082
+ bidder: t.bidderCode || t.bidder || "",
1083
+ latencyMs: Number.isFinite(t.timeout) ? t.timeout : 0
1084
+ }
1032
1085
  });
1033
1086
  }
1034
1087
  }
@@ -1037,13 +1090,13 @@ var BidkernelPrebidAnalytics = class {
1037
1090
  this.log("DEBUG", "bidWon", data);
1038
1091
  this.enqueue(TraceEventType.BID_WIN, "bidWon", {
1039
1092
  auctionId: data.auctionId || "",
1093
+ transactionId: data.transactionId || "",
1040
1094
  adUnitCode: data.adUnitCode || "",
1041
1095
  bid: {
1042
1096
  bidder: data.bidderCode || data.bidder || "",
1043
1097
  cpm: Number.isFinite(data.originalCpm) ? data.originalCpm : Number.isFinite(data.cpm) ? data.cpm : 0,
1044
1098
  currency: data.originalCurrency ?? data.currency ?? "USD",
1045
- width: Number.isFinite(data.width) ? data.width : 0,
1046
- height: Number.isFinite(data.height) ? data.height : 0,
1099
+ ...parseBidDimensions(data),
1047
1100
  dealId: data.dealId || "",
1048
1101
  mediaType: data.mediaType || "banner",
1049
1102
  latencyMs: Number.isFinite(data.timeToRespond) ? data.timeToRespond : 0,
@@ -1057,6 +1110,7 @@ var BidkernelPrebidAnalytics = class {
1057
1110
  this.log("DEBUG", "noBid", data);
1058
1111
  this.enqueue(TraceEventType.NO_BID, "noBid", {
1059
1112
  auctionId: data.auctionId || "",
1113
+ transactionId: data.transactionId || "",
1060
1114
  adUnitCode: data.adUnitCode || "",
1061
1115
  bid: {
1062
1116
  bidder: data.bidderCode || data.bidder || ""
@@ -1066,16 +1120,19 @@ var BidkernelPrebidAnalytics = class {
1066
1120
  handleAdRenderFailed(data) {
1067
1121
  if (this.isDuplicate("adRenderFailed", data)) return;
1068
1122
  this.log("DEBUG", "adRenderFailed", data);
1123
+ const bid = data.bid || {};
1069
1124
  this.enqueue(TraceEventType.AD_RENDER_FAILED, "adRenderFailed", {
1070
- auctionId: data.bid?.auctionId || "",
1071
- adUnitCode: data.bid?.adUnitCode || "",
1125
+ auctionId: bid.auctionId || data.auctionId || "",
1126
+ transactionId: bid.transactionId || data.transactionId || "",
1127
+ adUnitCode: bid.adUnitCode || data.adUnitCode || "",
1072
1128
  bid: {
1073
- bidder: data.bid?.bidderCode || data.bid?.bidder || ""
1129
+ bidder: bid.bidderCode || bid.bidder || data.bidderCode || data.bidder || ""
1074
1130
  },
1075
1131
  metadata: {
1076
1132
  reason: String(data.reason || ""),
1077
- message: String(data.message || "")
1078
- }
1133
+ message: String(data.message || data.error?.message || "")
1134
+ },
1135
+ error: data.error || (data.message ? new Error(String(data.message)) : void 0)
1079
1136
  });
1080
1137
  }
1081
1138
  // Prebid's adRenderSucceeded payload is { doc, bid, adId }: the winning bid
@@ -1085,14 +1142,14 @@ var BidkernelPrebidAnalytics = class {
1085
1142
  this.log("DEBUG", "adRenderSucceeded", data);
1086
1143
  const bid = data.bid || {};
1087
1144
  this.enqueue(TraceEventType.IMPRESSION, "impression", {
1088
- auctionId: bid.auctionId || "",
1145
+ auctionId: bid.auctionId || data.auctionId || "",
1146
+ transactionId: bid.transactionId || data.transactionId || "",
1089
1147
  adUnitCode: data.adUnitCode || bid.adUnitCode || "",
1090
1148
  bid: {
1091
1149
  bidder: bid.bidderCode || bid.bidder || "",
1092
1150
  cpm: Number.isFinite(bid.originalCpm) ? bid.originalCpm : Number.isFinite(bid.cpm) ? bid.cpm : 0,
1093
1151
  currency: bid.originalCurrency ?? bid.currency ?? "USD",
1094
- width: Number.isFinite(bid.width) ? bid.width : 0,
1095
- height: Number.isFinite(bid.height) ? bid.height : 0,
1152
+ ...parseBidDimensions(bid),
1096
1153
  dealId: bid.dealId || "",
1097
1154
  mediaType: bid.mediaType || "banner",
1098
1155
  latencyMs: Number.isFinite(bid.timeToRespond) ? bid.timeToRespond : 0,
@@ -1107,6 +1164,7 @@ var BidkernelPrebidAnalytics = class {
1107
1164
  enqueue(type, eventName, data, level) {
1108
1165
  if (!this.isEnabled) return;
1109
1166
  if (!this.shouldSample(type, level)) return;
1167
+ extendSession();
1110
1168
  const protoEvent = {
1111
1169
  eventId: generateUUID(),
1112
1170
  timestampMs: Date.now(),
@@ -1121,11 +1179,14 @@ var BidkernelPrebidAnalytics = class {
1121
1179
  protoEvent.bid = {
1122
1180
  bidder: data.bid.bidder || "",
1123
1181
  cpm: Number.isFinite(data.bid.cpm) ? data.bid.cpm : 0,
1124
- currency: data.bid.currency || "USD",
1182
+ // No defaults here: handlers with a priced bid (bidResponse, bidWon,
1183
+ // impression) set currency/mediaType themselves. Defaulting for the
1184
+ // rest would stamp fake "USD"/"banner" on noBid and bidRequest rows.
1185
+ currency: data.bid.currency || "",
1125
1186
  width: Number.isFinite(data.bid.width) ? data.bid.width : 0,
1126
1187
  height: Number.isFinite(data.bid.height) ? data.bid.height : 0,
1127
1188
  dealId: data.bid.dealId || "",
1128
- mediaType: data.bid.mediaType || "banner",
1189
+ mediaType: data.bid.mediaType || "",
1129
1190
  latencyMs: Number.isFinite(data.bid.latencyMs) ? data.bid.latencyMs : 0,
1130
1191
  advertiserDomain: data.bid.advertiserDomain || "",
1131
1192
  creativeId: data.bid.creativeId || ""
@@ -1170,14 +1231,13 @@ var BidkernelPrebidAnalytics = class {
1170
1231
  this.queue.splice(0, this.queue.length - MAX_QUEUE_SIZE);
1171
1232
  }
1172
1233
  }
1173
- // Drains the queue and returns the encoded batch plus target URL and event list,
1174
- // or null if there is nothing to send. Shared by flush() and flushBeacon().
1234
+ // Drains a batch (up to MAX_PAYLOAD_BYTES) from the queue.
1235
+ // Shared by flush() and flushBeacon().
1175
1236
  drainBatch() {
1176
1237
  if (this.queue.length === 0 || !this.config.endpoint) return null;
1177
- const events = this.queue;
1178
- this.queue = [];
1238
+ let events = this.queue;
1179
1239
  const domain = typeof window !== "undefined" ? window.location.hostname : "";
1180
- const batch = {
1240
+ const buildBatch = (evts) => ({
1181
1241
  propertyId: this.config.propertyId,
1182
1242
  pageviewId: this.config.pageviewId,
1183
1243
  sessionId: this.config.sessionId,
@@ -1187,25 +1247,42 @@ var BidkernelPrebidAnalytics = class {
1187
1247
  deviceType: this.config.deviceType,
1188
1248
  userId: this.config.userId,
1189
1249
  domain,
1190
- events
1191
- };
1250
+ events: evts
1251
+ });
1252
+ let encoded = TraceEventBatch.encode(
1253
+ buildBatch(events)
1254
+ ).finish();
1255
+ while (events.length > 1 && encoded.byteLength > MAX_PAYLOAD_BYTES) {
1256
+ events = events.slice(0, Math.floor(events.length / 2));
1257
+ encoded = TraceEventBatch.encode(
1258
+ buildBatch(events)
1259
+ ).finish();
1260
+ }
1261
+ this.queue = this.queue.slice(events.length);
1192
1262
  return {
1193
1263
  url: `${this.config.endpoint}/${this.config.propertyId}`,
1194
1264
  // protobufjs types finish() as Uint8Array<ArrayBufferLike>; the buffer is
1195
1265
  // always a plain ArrayBuffer, so narrow for fetch/Blob compatibility.
1196
- encoded: TraceEventBatch.encode(batch).finish(),
1266
+ encoded,
1197
1267
  events
1198
1268
  };
1199
1269
  }
1200
- sendFetch(payload) {
1201
- fetch(payload.url, {
1270
+ sendFetch(payload, useKeepalive = false) {
1271
+ const fetchOpts = {
1202
1272
  method: "POST",
1203
1273
  headers: { "Content-Type": "application/x-protobuf" },
1204
- body: payload.encoded,
1205
- keepalive: true
1206
- }).then((res) => {
1274
+ body: payload.encoded
1275
+ };
1276
+ if (useKeepalive) {
1277
+ fetchOpts.keepalive = true;
1278
+ }
1279
+ fetch(payload.url, fetchOpts).then((res) => {
1207
1280
  if (!res.ok) {
1208
1281
  this.log("WARN", `Failed to send batch: HTTP ${res.status}`);
1282
+ if (res.status >= 400 && res.status < 500) {
1283
+ this.log("WARN", `Dropping batch due to non-retryable client error HTTP ${res.status}`);
1284
+ return;
1285
+ }
1209
1286
  this.handleSendFailure(payload.events);
1210
1287
  } else {
1211
1288
  this.consecutiveSendFailures = 0;
@@ -1234,24 +1311,31 @@ var BidkernelPrebidAnalytics = class {
1234
1311
  }
1235
1312
  flush() {
1236
1313
  if (Date.now() < this.nextSendAllowedAt) return;
1237
- const payload = this.drainBatch();
1238
- if (!payload) return;
1239
- this.sendFetch(payload);
1314
+ let payload = this.drainBatch();
1315
+ while (payload) {
1316
+ this.sendFetch(payload, false);
1317
+ if (Date.now() < this.nextSendAllowedAt) break;
1318
+ payload = this.drainBatch();
1319
+ }
1240
1320
  }
1241
1321
  flushBeacon() {
1242
- const payload = this.drainBatch();
1243
- if (!payload) return;
1244
- let sent = false;
1245
- if (typeof navigator !== "undefined" && typeof navigator.sendBeacon === "function") {
1246
- try {
1247
- const blob = new Blob([payload.encoded], { type: "application/x-protobuf" });
1248
- sent = navigator.sendBeacon(payload.url, blob);
1249
- } catch {
1250
- sent = false;
1322
+ let payload = this.drainBatch();
1323
+ while (payload) {
1324
+ let sent = false;
1325
+ if (typeof navigator !== "undefined" && typeof navigator.sendBeacon === "function") {
1326
+ try {
1327
+ const blob = new Blob([payload.encoded], {
1328
+ type: "application/x-protobuf"
1329
+ });
1330
+ sent = navigator.sendBeacon(payload.url, blob);
1331
+ } catch {
1332
+ sent = false;
1333
+ }
1251
1334
  }
1252
- }
1253
- if (!sent) {
1254
- this.sendFetch(payload);
1335
+ if (!sent) {
1336
+ this.sendFetch(payload, true);
1337
+ }
1338
+ payload = this.drainBatch();
1255
1339
  }
1256
1340
  }
1257
1341
  log(level, msg, ...args) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@bidkernel/analytics",
3
- "version": "0.3.0",
3
+ "version": "0.4.0",
4
4
  "description": "Bidkernel auction analytics: a standalone Prebid.js analytics adapter, plus TypeScript bindings for the Bidkernel ad SDK.",
5
5
  "keywords": [
6
6
  "advertising",