You're Invited:Meet the Socket Team at RSAC and BSidesSF 2026, March 23–26.RSVP
Socket
Book a DemoSign in
Socket

@topsort/analytics.js

Package Overview
Dependencies
Maintainers
2
Versions
15
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@topsort/analytics.js - npm Package Compare versions

Comparing version
2.6.0
to
2.7.0
+1
dist/ts.iife.js
(function(){"use strict";var N="https://api.topsort.com",y={auctions:"v2/auctions",events:"v2/events"},_="0.3.8";class M{status;statusText;body;retry;constructor(t,s,n,r=!1){this.status=t,this.statusText=s,this.body=n,this.retry=r}}var d=M;class R{async handleResponse(t){let s;if(t.status!==204&&(s=await t.json()),!t.ok){let n=t.status===429||t.status>=500;throw new d(t.status,t.statusText,s,n)}return s}async request(t,s){try{let n=this.sanitizeUrl(t),r=await fetch(n,s);return this.handleResponse(r)}catch(n){let r=n instanceof Error?n.message:"Unknown error";throw new d(500,"Internal Server Error",r)}}setupTimeoutSignal(t){if(t.timeout!=null){let s=new AbortController;return setTimeout(()=>s.abort(),t.timeout),s.signal}}async post(t,s,n){let r=this.setupTimeoutSignal(n),o=n.fetchOptions??{keepalive:!0};return this.request(t,{method:"POST",headers:{"Content-Type":"application/json",Accept:"application/json","X-UA":n.userAgent?`@topsort/sdk ${_} ${n.userAgent}`:`@topsort/sdk ${_}`,Authorization:`Bearer ${n.apiKey}`},body:JSON.stringify(s),signal:r,...o})}sanitizeUrl(t){try{return new URL(t).href.replace(/\/+$/,"")}catch(s){throw new d(400,"Invalid URL",{error:`Invalid URL: ${s}`})}}}var m=new R;function L(e){if(!e?.apiKey?.length)throw new d(401,"API Key is required.",{})}function S(e){return async(...t)=>{let s=t[t.length-1];return L(s),e(...t)}}async function C(e,t){let s=`${t.host}/${y.auctions}`;return await m.post(s.toString(),e,t)}var $=S(C);async function q(e,t){try{let s=`${t.host}/${y.events}`;return await m.post(s,e,t),{ok:!0,retry:!1}}catch(s){if(s instanceof d&&s.retry)return{ok:!1,retry:!0};throw s}}var x=S(q);class H{config;constructor(t){this.config=t,this.config.host=this.config.host??N}async reportEvent(t){return x(t,this.config)}async createAuction(t){return $(t,this.config)}}var B=H;const D="2.7.0";class I{constructor(){this._data=[]}get(){return this._data}set(t){this._data=t}}class T{constructor(t){this._key=t,this._storage=window.localStorage}get(){const t=this._storage.getItem(this._key);return t?JSON.parse(t):[]}set(t){this._storage.setItem(this._key,JSON.stringify(t))}}class K{constructor(t){this._key=t,this._storage=window.sessionStorage,this._bid=void 0}get(){try{return this._storage.getItem(this._key)??void 0}catch{return this._bid}}set(t){this._bid=t;try{this._storage.setItem(this._key,t)}catch{}}}const j="ts-t",z="ts-q",J=3,X=25,Y=250,E=9,G=0;function W(e,t){return t>0?e+(Math.random()+2**t)*1e3:0}function Z(){const e=new T(j);try{if(e.set([{x:"3"}]),e.get()[0]?.x==="3")return new T(z)}catch{}return new I}class F{constructor(t){this._store=Z(),this._processing=new Set,this._scheduled=!1,this._processor=t}append(t,s){let n=this._store.get();n.push({e:t,r:0,p:s?.highPriority?E:G}),n=n.slice(-250),this._setEntries(n)}async _processNow(t){if(!t.length)return;const s=[];for(let i=t.length-1;i>=0&&s.length<X;i--){const a=t[i],l=a?.e;l&&!this._processing.has(l.id)&&W(l.t,a.r)<=Date.now()&&(s.push(l),this._processing.add(l.id))}if(!s.length){this._scheduleProcessing();return}let n={done:new Set,retry:new Set};try{n=await this._processor(s)}catch{for(const a of s)n.done.add(a.id)}const r=[];for(const i of this._processing)s.find(a=>a.id===i)||r.push(i);this._processing=new Set(r);const o=this._store.get(),c=[];for(const i of o)n.done.has(i.e.id)||(n.retry.has(i.e.id)?i.r<J&&(i.r+=1,c.push(i)):c.push(i));this._setEntries(c)}_setEntries(t){this._store.set(t),t.length&&(t.some(s=>s.p===E)||this._store instanceof I?this._processNow(t):this._scheduleProcessing())}_scheduleProcessing(){this._scheduled||(this._scheduled=!0,setTimeout(()=>{this._scheduled=!1,this._processNow(this._store.get())},Y))}}function Q(e,t){if(e.size<=t)return e;const s=e.values();for(let n=0;n<e.size-t;++n)s.next();return new Set(s)}const V=2500,tt=.5;let h=new Set;const b=new K("ts-b");function k(){return window.URL.createObjectURL?.(new Blob).split("/").pop()||`${Math.random()}`}let u;function g(){if(u)return u;const e=st();if(e)return u=e,e;const t=k();return v(t),t}function v(e){const t=window.TS.cookieName||"tsuid";u=e,document.cookie=`${t}=${e};max-age=31536000`}function et(){return u=void 0,document.cookie="tsuid=",g()}window.TS.setUserId=v,typeof window.TS.getUserId!="function"&&(window.TS.getUserId=g),window.TS.resetUserId=et;function st(){const e=window.TS.cookieName||"tsuid";return new RegExp(`(^|;)\\s*${e}\\s*=\\s*([^;]+)`).exec(document.cookie)?.pop()}function nt(e){const t=e.type,s={path:e.page};let n;e.product&&(n={type:"product",id:e.product});let r;e.additionalProduct&&(r={type:"product",id:e.additionalProduct});const o=new Date(e.t).toISOString();switch(t){case"Click":return{clicks:[{resolvedBidId:e.bid,entity:n,additionalAttribution:r,placement:s,occurredAt:o,opaqueUserId:e.uid,id:e.id}]};case"Impression":return{impressions:[{resolvedBidId:e.bid,entity:n,additionalAttribution:r,placement:s,occurredAt:o,opaqueUserId:e.uid,id:e.id}]};case"Purchase":return{purchases:[{occurredAt:o,opaqueUserId:e.uid,items:(e.items||[]).map(c=>({productId:c.product,quantity:c.quantity,unitPrice:c.price})),id:e.id}]}}}async function rt(e){const t={done:new Set,retry:new Set},s=[],n={apiKey:window.TS.token,host:window.TS.url,userAgent:`ts.js/${D}`},r=new B(n);for(const o of e)s.push(r.reportEvent(nt(o)).then(c=>{(c.retry?t.retry:t.done).add(o.id)}).catch(()=>{t.done.add(o.id)}));return await Promise.all(s),t}const ot=new F(rt);function f(e,t){const s=it(e);if(h.has(s))return;h.add(s),h=Q(h,V),ot.append(e);const n=new CustomEvent("topsort",{bubbles:!0,detail:e});t.dispatchEvent(n)}function it(e){const t=JSON.stringify(e.items||[]);return[e.page,e.type,e.product??e.additionalProduct,e.bid,t].join("-")}function ct(){const e=window.location,t=e.hash;return t[1]==="/"?t:`${e.pathname}${e.search}`}function p(e,t){let s=t.dataset.tsProduct,n=t.dataset.tsResolvedBid,r;n==="inherit"&&s&&(e==="Click"||e==="Impression")&&(n=b.get(),r=s,s=void 0);const o={type:e,product:s,additionalProduct:r,bid:n,t:Date.now(),page:ct(),id:k(),uid:typeof window.TS.getUserId=="function"?window.TS.getUserId():g()};return e==="Purchase"&&(o.items=JSON.parse(t.dataset.tsItems||"[]")),o}function at(e){if(!(e.currentTarget instanceof HTMLElement))return;const t=e.currentTarget.closest(O);if(t&&t instanceof HTMLElement){const s=p("Click",t);f(s,t),s.bid&&b.set(s.bid)}}const w=window.IntersectionObserver?new IntersectionObserver(e=>{for(const t of e)if(t.isIntersecting){const s=t.target;s instanceof HTMLElement&&(f(p("Impression",s),s),w&&w.unobserve(s))}},{threshold:tt}):void 0,O="[data-ts-product],[data-ts-action],[data-ts-items],[data-ts-resolved-bid]";function dt(e){const t=e.querySelectorAll("[data-ts-clickable]"),s=t.length===0?[e]:Array.from(t);for(const n of s)n.addEventListener("click",at)}function A(e){ut(e)?f(p("Purchase",e),e):(w?w.observe(e):f(p("Impression",e),e),dt(e))}function P(e){const t=e.querySelectorAll(O);for(let s=0;s<t.length;s++){const n=t[s];n instanceof HTMLElement&&A(n)}}function ut(e){return e.dataset.tsAction==="purchase"}function lt(e){for(const t of e)if(t.type==="childList"){const s=new Set;for(let n=0;n<t.addedNodes.length;n++){const r=t.addedNodes[n];if(r?.nodeType===Node.ELEMENT_NODE){const o=r.parentElement;o&&!s.has(o)&&s.add(o)}for(const o of s)P(o)}}else if(t.type==="attributes"){if(!(t.target instanceof HTMLElement))continue;A(t.target)}}function U(){if(window.TS?.loaded)return;if(window.TS.loaded=!0,!window.TS?.token){console.error("Missing TS token");return}P(document);const e=window.MutationObserver||window.WebKitMutationObserver||window.MozMutationObserver;new e(lt).observe(document,{attributes:!0,childList:!0,subtree:!0,attributeFilter:["data-ts-product","data-ts-action","data-ts-items","data-ts-resolved-bid"]})}/complete|interactive|loaded/.test(document.readyState)?U():window.addEventListener("DOMContentLoaded",U)})();
+8
-0

@@ -9,2 +9,10 @@ # Changelog

## Unreleased
## Version 2.7.0 (2025-01-23)
### Added
- Add IIFE bundle for legacy systems that don't support ES modules
## Version 2.4.0 (2024-09-05)

@@ -11,0 +19,0 @@

+1
-1

@@ -1,1 +0,1 @@

(function(h){typeof define=="function"&&define.amd?define(h):h()})((function(){"use strict";var h="https://api.topsort.com",m={auctions:"v2/auctions",events:"v2/events"},_="0.3.8";class M{status;statusText;body;retry;constructor(t,s,n,o=!1){this.status=t,this.statusText=s,this.body=n,this.retry=o}}var d=M;class R{async handleResponse(t){let s;if(t.status!==204&&(s=await t.json()),!t.ok){let n=t.status===429||t.status>=500;throw new d(t.status,t.statusText,s,n)}return s}async request(t,s){try{let n=this.sanitizeUrl(t),o=await fetch(n,s);return this.handleResponse(o)}catch(n){let o=n instanceof Error?n.message:"Unknown error";throw new d(500,"Internal Server Error",o)}}setupTimeoutSignal(t){if(t.timeout!=null){let s=new AbortController;return setTimeout(()=>s.abort(),t.timeout),s.signal}}async post(t,s,n){let o=this.setupTimeoutSignal(n),r=n.fetchOptions??{keepalive:!0};return this.request(t,{method:"POST",headers:{"Content-Type":"application/json",Accept:"application/json","X-UA":n.userAgent?`@topsort/sdk ${_} ${n.userAgent}`:`@topsort/sdk ${_}`,Authorization:`Bearer ${n.apiKey}`},body:JSON.stringify(s),signal:o,...r})}sanitizeUrl(t){try{return new URL(t).href.replace(/\/+$/,"")}catch(s){throw new d(400,"Invalid URL",{error:`Invalid URL: ${s}`})}}}var S=new R;function L(e){if(!e?.apiKey?.length)throw new d(401,"API Key is required.",{})}function I(e){return async(...t)=>{let s=t[t.length-1];return L(s),e(...t)}}async function C(e,t){let s=`${t.host}/${m.auctions}`;return await S.post(s.toString(),e,t)}var $=I(C);async function q(e,t){try{let s=`${t.host}/${m.events}`;return await S.post(s,e,t),{ok:!0,retry:!1}}catch(s){if(s instanceof d&&s.retry)return{ok:!1,retry:!0};throw s}}var x=I(q);class H{config;constructor(t){this.config=t,this.config.host=this.config.host??h}async reportEvent(t){return x(t,this.config)}async createAuction(t){return $(t,this.config)}}var B=H;const D="2.6.0";class T{constructor(){this._data=[]}get(){return this._data}set(t){this._data=t}}class E{constructor(t){this._key=t,this._storage=window.localStorage}get(){const t=this._storage.getItem(this._key);return t?JSON.parse(t):[]}set(t){this._storage.setItem(this._key,JSON.stringify(t))}}class K{constructor(t){this._key=t,this._storage=window.sessionStorage,this._bid=void 0}get(){try{return this._storage.getItem(this._key)??void 0}catch{return this._bid}}set(t){this._bid=t;try{this._storage.setItem(this._key,t)}catch{}}}const j="ts-t",z="ts-q",J=3,X=25,Y=250,b=9,G=0;function W(e,t){return t>0?e+(Math.random()+2**t)*1e3:0}function Z(){const e=new E(j);try{if(e.set([{x:"3"}]),e.get()[0]?.x==="3")return new E(z)}catch{}return new T}class F{constructor(t){this._store=Z(),this._processing=new Set,this._scheduled=!1,this._processor=t}append(t,s){let n=this._store.get();n.push({e:t,r:0,p:s?.highPriority?b:G}),n=n.slice(-250),this._setEntries(n)}async _processNow(t){if(!t.length)return;const s=[];for(let i=t.length-1;i>=0&&s.length<X;i--){const a=t[i],l=a?.e;l&&!this._processing.has(l.id)&&W(l.t,a.r)<=Date.now()&&(s.push(l),this._processing.add(l.id))}if(!s.length){this._scheduleProcessing();return}let n={done:new Set,retry:new Set};try{n=await this._processor(s)}catch{for(const a of s)n.done.add(a.id)}const o=[];for(const i of this._processing)s.find(a=>a.id===i)||o.push(i);this._processing=new Set(o);const r=this._store.get(),c=[];for(const i of r)n.done.has(i.e.id)||(n.retry.has(i.e.id)?i.r<J&&(i.r+=1,c.push(i)):c.push(i));this._setEntries(c)}_setEntries(t){this._store.set(t),t.length&&(t.some(s=>s.p===b)||this._store instanceof T?this._processNow(t):this._scheduleProcessing())}_scheduleProcessing(){this._scheduled||(this._scheduled=!0,setTimeout(()=>{this._scheduled=!1,this._processNow(this._store.get())},Y))}}function Q(e,t){if(e.size<=t)return e;const s=e.values();for(let n=0;n<e.size-t;++n)s.next();return new Set(s)}const V=2500,tt=.5;let f=new Set;const k=new K("ts-b");function v(){return window.URL.createObjectURL?.(new Blob).split("/").pop()||`${Math.random()}`}let u;function y(){if(u)return u;const e=st();if(e)return u=e,e;const t=v();return O(t),t}function O(e){const t=window.TS.cookieName||"tsuid";u=e,document.cookie=`${t}=${e};max-age=31536000`}function et(){return u=void 0,document.cookie="tsuid=",y()}window.TS.setUserId=O,typeof window.TS.getUserId!="function"&&(window.TS.getUserId=y),window.TS.resetUserId=et;function st(){const e=window.TS.cookieName||"tsuid";return new RegExp(`(^|;)\\s*${e}\\s*=\\s*([^;]+)`).exec(document.cookie)?.pop()}function nt(e){const t=e.type,s={path:e.page};let n;e.product&&(n={type:"product",id:e.product});let o;e.additionalProduct&&(o={type:"product",id:e.additionalProduct});const r=new Date(e.t).toISOString();switch(t){case"Click":return{clicks:[{resolvedBidId:e.bid,entity:n,additionalAttribution:o,placement:s,occurredAt:r,opaqueUserId:e.uid,id:e.id}]};case"Impression":return{impressions:[{resolvedBidId:e.bid,entity:n,additionalAttribution:o,placement:s,occurredAt:r,opaqueUserId:e.uid,id:e.id}]};case"Purchase":return{purchases:[{occurredAt:r,opaqueUserId:e.uid,items:(e.items||[]).map(c=>({productId:c.product,quantity:c.quantity,unitPrice:c.price})),id:e.id}]}}}async function ot(e){const t={done:new Set,retry:new Set},s=[],n={apiKey:window.TS.token,host:window.TS.url,userAgent:`ts.js/${D}`},o=new B(n);for(const r of e)s.push(o.reportEvent(nt(r)).then(c=>{(c.retry?t.retry:t.done).add(r.id)}).catch(()=>{t.done.add(r.id)}));return await Promise.all(s),t}const rt=new F(ot);function p(e,t){const s=it(e);if(f.has(s))return;f.add(s),f=Q(f,V),rt.append(e);const n=new CustomEvent("topsort",{bubbles:!0,detail:e});t.dispatchEvent(n)}function it(e){const t=JSON.stringify(e.items||[]);return[e.page,e.type,e.product??e.additionalProduct,e.bid,t].join("-")}function ct(){const e=window.location,t=e.hash;return t[1]==="/"?t:`${e.pathname}${e.search}`}function w(e,t){let s=t.dataset.tsProduct,n=t.dataset.tsResolvedBid,o;n==="inherit"&&s&&(e==="Click"||e==="Impression")&&(n=k.get(),o=s,s=void 0);const r={type:e,product:s,additionalProduct:o,bid:n,t:Date.now(),page:ct(),id:v(),uid:typeof window.TS.getUserId=="function"?window.TS.getUserId():y()};return e==="Purchase"&&(r.items=JSON.parse(t.dataset.tsItems||"[]")),r}function at(e){if(!(e.currentTarget instanceof HTMLElement))return;const t=e.currentTarget.closest(A);if(t&&t instanceof HTMLElement){const s=w("Click",t);p(s,t),s.bid&&k.set(s.bid)}}const g=window.IntersectionObserver?new IntersectionObserver(e=>{for(const t of e)if(t.isIntersecting){const s=t.target;s instanceof HTMLElement&&(p(w("Impression",s),s),g&&g.unobserve(s))}},{threshold:tt}):void 0,A="[data-ts-product],[data-ts-action],[data-ts-items],[data-ts-resolved-bid]";function dt(e){const t=e.querySelectorAll("[data-ts-clickable]"),s=t.length===0?[e]:Array.from(t);for(const n of s)n.addEventListener("click",at)}function P(e){ut(e)?p(w("Purchase",e),e):(g?g.observe(e):p(w("Impression",e),e),dt(e))}function U(e){const t=e.querySelectorAll(A);for(let s=0;s<t.length;s++){const n=t[s];n instanceof HTMLElement&&P(n)}}function ut(e){return e.dataset.tsAction==="purchase"}function lt(e){for(const t of e)if(t.type==="childList"){const s=new Set;for(let n=0;n<t.addedNodes.length;n++){const o=t.addedNodes[n];if(o?.nodeType===Node.ELEMENT_NODE){const r=o.parentElement;r&&!s.has(r)&&s.add(r)}for(const r of s)U(r)}}else if(t.type==="attributes"){if(!(t.target instanceof HTMLElement))continue;P(t.target)}}function N(){if(window.TS?.loaded)return;if(window.TS.loaded=!0,!window.TS?.token){console.error("Missing TS token");return}U(document);const e=window.MutationObserver||window.WebKitMutationObserver||window.MozMutationObserver;new e(lt).observe(document,{attributes:!0,childList:!0,subtree:!0,attributeFilter:["data-ts-product","data-ts-action","data-ts-items","data-ts-resolved-bid"]})}/complete|interactive|loaded/.test(document.readyState)?N():window.addEventListener("DOMContentLoaded",N)}));
(function(a,u){typeof exports=="object"&&typeof module<"u"?u(require("@topsort/sdk")):typeof define=="function"&&define.amd?define(["@topsort/sdk"],u):(a=typeof globalThis<"u"?globalThis:a||self,u(a.sdk))})(this,(function(a){"use strict";const u="2.7.0";class m{constructor(){this._data=[]}get(){return this._data}set(e){this._data=e}}class S{constructor(e){this._key=e,this._storage=window.localStorage}get(){const e=this._storage.getItem(this._key);return e?JSON.parse(e):[]}set(e){this._storage.setItem(this._key,JSON.stringify(e))}}class N{constructor(e){this._key=e,this._storage=window.sessionStorage,this._bid=void 0}get(){try{return this._storage.getItem(this._key)??void 0}catch{return this._bid}}set(e){this._bid=e;try{this._storage.setItem(this._key,e)}catch{}}}const P="ts-t",U="ts-q",A=3,C=25,R=250,I=9,v=0;function L(t,e){return e>0?t+(Math.random()+2**e)*1e3:0}function q(){const t=new S(P);try{if(t.set([{x:"3"}]),t.get()[0]?.x==="3")return new S(U)}catch{}return new m}class x{constructor(e){this._store=q(),this._processing=new Set,this._scheduled=!1,this._processor=e}append(e,s){let o=this._store.get();o.push({e,r:0,p:s?.highPriority?I:v}),o=o.slice(-250),this._setEntries(o)}async _processNow(e){if(!e.length)return;const s=[];for(let r=e.length-1;r>=0&&s.length<C;r--){const d=e[r],f=d?.e;f&&!this._processing.has(f.id)&&L(f.t,d.r)<=Date.now()&&(s.push(f),this._processing.add(f.id))}if(!s.length){this._scheduleProcessing();return}let o={done:new Set,retry:new Set};try{o=await this._processor(s)}catch{for(const d of s)o.done.add(d.id)}const i=[];for(const r of this._processing)s.find(d=>d.id===r)||i.push(r);this._processing=new Set(i);const n=this._store.get(),c=[];for(const r of n)o.done.has(r.e.id)||(o.retry.has(r.e.id)?r.r<A&&(r.r+=1,c.push(r)):c.push(r));this._setEntries(c)}_setEntries(e){this._store.set(e),e.length&&(e.some(s=>s.p===I)||this._store instanceof m?this._processNow(e):this._scheduleProcessing())}_scheduleProcessing(){this._scheduled||(this._scheduled=!0,setTimeout(()=>{this._scheduled=!1,this._processNow(this._store.get())},R))}}function H(t,e){if(t.size<=e)return t;const s=t.values();for(let o=0;o<t.size-e;++o)s.next();return new Set(s)}const D=2500,$=.5;let h=new Set;const y=new N("ts-b");function E(){return window.URL.createObjectURL?.(new Blob).split("/").pop()||`${Math.random()}`}let l;function _(){if(l)return l;const t=j();if(t)return l=t,t;const e=E();return T(e),e}function T(t){const e=window.TS.cookieName||"tsuid";l=t,document.cookie=`${e}=${t};max-age=31536000`}function B(){return l=void 0,document.cookie="tsuid=",_()}window.TS.setUserId=T,typeof window.TS.getUserId!="function"&&(window.TS.getUserId=_),window.TS.resetUserId=B;function j(){const t=window.TS.cookieName||"tsuid";return new RegExp(`(^|;)\\s*${t}\\s*=\\s*([^;]+)`).exec(document.cookie)?.pop()}function J(t){const e=t.type,s={path:t.page};let o;t.product&&(o={type:"product",id:t.product});let i;t.additionalProduct&&(i={type:"product",id:t.additionalProduct});const n=new Date(t.t).toISOString();switch(e){case"Click":return{clicks:[{resolvedBidId:t.bid,entity:o,additionalAttribution:i,placement:s,occurredAt:n,opaqueUserId:t.uid,id:t.id}]};case"Impression":return{impressions:[{resolvedBidId:t.bid,entity:o,additionalAttribution:i,placement:s,occurredAt:n,opaqueUserId:t.uid,id:t.id}]};case"Purchase":return{purchases:[{occurredAt:n,opaqueUserId:t.uid,items:(t.items||[]).map(c=>({productId:c.product,quantity:c.quantity,unitPrice:c.price})),id:t.id}]}}}async function K(t){const e={done:new Set,retry:new Set},s=[],o={apiKey:window.TS.token,host:window.TS.url,userAgent:`ts.js/${u}`},i=new a.TopsortClient(o);for(const n of t)s.push(i.reportEvent(J(n)).then(c=>{(c.retry?e.retry:e.done).add(n.id)}).catch(()=>{e.done.add(n.id)}));return await Promise.all(s),e}const X=new x(K);function p(t,e){const s=Y(t);if(h.has(s))return;h.add(s),h=H(h,D),X.append(t);const o=new CustomEvent("topsort",{bubbles:!0,detail:t});e.dispatchEvent(o)}function Y(t){const e=JSON.stringify(t.items||[]);return[t.page,t.type,t.product??t.additionalProduct,t.bid,e].join("-")}function G(){const t=window.location,e=t.hash;return e[1]==="/"?e:`${t.pathname}${t.search}`}function w(t,e){let s=e.dataset.tsProduct,o=e.dataset.tsResolvedBid,i;o==="inherit"&&s&&(t==="Click"||t==="Impression")&&(o=y.get(),i=s,s=void 0);const n={type:t,product:s,additionalProduct:i,bid:o,t:Date.now(),page:G(),id:E(),uid:typeof window.TS.getUserId=="function"?window.TS.getUserId():_()};return t==="Purchase"&&(n.items=JSON.parse(e.dataset.tsItems||"[]")),n}function z(t){if(!(t.currentTarget instanceof HTMLElement))return;const e=t.currentTarget.closest(b);if(e&&e instanceof HTMLElement){const s=w("Click",e);p(s,e),s.bid&&y.set(s.bid)}}const g=window.IntersectionObserver?new IntersectionObserver(t=>{for(const e of t)if(e.isIntersecting){const s=e.target;s instanceof HTMLElement&&(p(w("Impression",s),s),g&&g.unobserve(s))}},{threshold:$}):void 0,b="[data-ts-product],[data-ts-action],[data-ts-items],[data-ts-resolved-bid]";function W(t){const e=t.querySelectorAll("[data-ts-clickable]"),s=e.length===0?[t]:Array.from(e);for(const o of s)o.addEventListener("click",z)}function k(t){Z(t)?p(w("Purchase",t),t):(g?g.observe(t):p(w("Impression",t),t),W(t))}function O(t){const e=t.querySelectorAll(b);for(let s=0;s<e.length;s++){const o=e[s];o instanceof HTMLElement&&k(o)}}function Z(t){return t.dataset.tsAction==="purchase"}function F(t){for(const e of t)if(e.type==="childList"){const s=new Set;for(let o=0;o<e.addedNodes.length;o++){const i=e.addedNodes[o];if(i?.nodeType===Node.ELEMENT_NODE){const n=i.parentElement;n&&!s.has(n)&&s.add(n)}for(const n of s)O(n)}}else if(e.type==="attributes"){if(!(e.target instanceof HTMLElement))continue;k(e.target)}}function M(){if(window.TS?.loaded)return;if(window.TS.loaded=!0,!window.TS?.token){console.error("Missing TS token");return}O(document);const t=window.MutationObserver||window.WebKitMutationObserver||window.MozMutationObserver;new t(F).observe(document,{attributes:!0,childList:!0,subtree:!0,attributeFilter:["data-ts-product","data-ts-action","data-ts-items","data-ts-resolved-bid"]})}/complete|interactive|loaded/.test(document.readyState)?M():window.addEventListener("DOMContentLoaded",M)}));
+189
-273

@@ -1,88 +0,4 @@

var N = "https://api.topsort.com", I = { auctions: "v2/auctions", events: "v2/events" }, y = "0.3.8";
class M {
status;
statusText;
body;
retry;
constructor(t, s, r, n = !1) {
this.status = t, this.statusText = s, this.body = r, this.retry = n;
}
}
var u = M;
class R {
async handleResponse(t) {
let s;
if (t.status !== 204 && (s = await t.json()), !t.ok) {
let r = t.status === 429 || t.status >= 500;
throw new u(t.status, t.statusText, s, r);
}
return s;
}
async request(t, s) {
try {
let r = this.sanitizeUrl(t), n = await fetch(r, s);
return this.handleResponse(n);
} catch (r) {
let n = r instanceof Error ? r.message : "Unknown error";
throw new u(500, "Internal Server Error", n);
}
}
setupTimeoutSignal(t) {
if (t.timeout != null) {
let s = new AbortController();
return setTimeout(() => s.abort(), t.timeout), s.signal;
}
}
async post(t, s, r) {
let n = this.setupTimeoutSignal(r), o = r.fetchOptions ?? { keepalive: !0 };
return this.request(t, { method: "POST", headers: { "Content-Type": "application/json", Accept: "application/json", "X-UA": r.userAgent ? `@topsort/sdk ${y} ${r.userAgent}` : `@topsort/sdk ${y}`, Authorization: `Bearer ${r.apiKey}` }, body: JSON.stringify(s), signal: n, ...o });
}
sanitizeUrl(t) {
try {
return new URL(t).href.replace(/\/+$/, "");
} catch (s) {
throw new u(400, "Invalid URL", { error: `Invalid URL: ${s}` });
}
}
}
var T = new R();
function L(e) {
if (!e?.apiKey?.length) throw new u(401, "API Key is required.", {});
}
function E(e) {
return async (...t) => {
let s = t[t.length - 1];
return L(s), e(...t);
};
}
async function C(e, t) {
let s = `${t.host}/${I.auctions}`;
return await T.post(s.toString(), e, t);
}
var $ = E(C);
async function q(e, t) {
try {
let s = `${t.host}/${I.events}`;
return await T.post(s, e, t), { ok: !0, retry: !1 };
} catch (s) {
if (s instanceof u && s.retry) return { ok: !1, retry: !0 };
throw s;
}
}
var x = E(q);
class H {
config;
constructor(t) {
this.config = t, this.config.host = this.config.host ?? N;
}
async reportEvent(t) {
return x(t, this.config);
}
async createAuction(t) {
return $(t, this.config);
}
}
var B = H;
const D = "2.6.0";
class b {
import { TopsortClient as O } from "@topsort/sdk";
const M = "2.7.0";
class S {
constructor() {

@@ -94,21 +10,21 @@ this._data = [];

}
set(t) {
this._data = t;
set(e) {
this._data = e;
}
}
class _ {
constructor(t) {
this._key = t, this._storage = window.localStorage;
class g {
constructor(e) {
this._key = e, this._storage = window.localStorage;
}
get() {
const t = this._storage.getItem(this._key);
return t ? JSON.parse(t) : [];
const e = this._storage.getItem(this._key);
return e ? JSON.parse(e) : [];
}
set(t) {
this._storage.setItem(this._key, JSON.stringify(t));
set(e) {
this._storage.setItem(this._key, JSON.stringify(e));
}
}
class K {
constructor(t) {
this._key = t, this._storage = window.sessionStorage, this._bid = void 0;
class N {
constructor(e) {
this._key = e, this._storage = window.sessionStorage, this._bid = void 0;
}

@@ -122,6 +38,6 @@ get() {

}
set(t) {
this._bid = t;
set(e) {
this._bid = e;
try {
this._storage.setItem(this._key, t);
this._storage.setItem(this._key, e);
} catch {

@@ -131,34 +47,34 @@ }

}
const j = "ts-t", z = "ts-q", J = 3, X = 25, Y = 250, m = 9, G = 0;
function W(e, t) {
return t > 0 ? e + (Math.random() + 2 ** t) * 1e3 : 0;
const P = "ts-t", U = "ts-q", A = 3, C = 25, R = 250, _ = 9, v = 0;
function L(t, e) {
return e > 0 ? t + (Math.random() + 2 ** e) * 1e3 : 0;
}
function Z() {
const e = new _(j);
function q() {
const t = new g(P);
try {
if (e.set([{ x: "3" }]), e.get()[0]?.x === "3")
return new _(z);
if (t.set([{ x: "3" }]), t.get()[0]?.x === "3")
return new g(U);
} catch {
}
return new b();
return new S();
}
class F {
constructor(t) {
this._store = Z(), this._processing = /* @__PURE__ */ new Set(), this._scheduled = !1, this._processor = t;
class H {
constructor(e) {
this._store = q(), this._processing = /* @__PURE__ */ new Set(), this._scheduled = !1, this._processor = e;
}
append(t, s) {
let r = this._store.get();
r.push({
e: t,
append(e, s) {
let o = this._store.get();
o.push({
e,
r: 0,
p: s?.highPriority ? m : G
}), r = r.slice(-250), this._setEntries(r);
p: s?.highPriority ? _ : v
}), o = o.slice(-250), this._setEntries(o);
}
async _processNow(t) {
if (!t.length)
async _processNow(e) {
if (!e.length)
return;
const s = [];
for (let i = t.length - 1; i >= 0 && s.length < X; i--) {
const a = t[i], d = a?.e;
d && !this._processing.has(d.id) && W(d.t, a.r) <= Date.now() && (s.push(d), this._processing.add(d.id));
for (let r = e.length - 1; r >= 0 && s.length < C; r--) {
const d = e[r], a = d?.e;
a && !this._processing.has(a.id) && L(a.t, d.r) <= Date.now() && (s.push(a), this._processing.add(a.id));
}

@@ -169,20 +85,20 @@ if (!s.length) {

}
let r = { done: /* @__PURE__ */ new Set(), retry: /* @__PURE__ */ new Set() };
let o = { done: /* @__PURE__ */ new Set(), retry: /* @__PURE__ */ new Set() };
try {
r = await this._processor(s);
o = await this._processor(s);
} catch {
for (const a of s)
r.done.add(a.id);
for (const d of s)
o.done.add(d.id);
}
const n = [];
for (const i of this._processing)
s.find((a) => a.id === i) || n.push(i);
this._processing = new Set(n);
const o = this._store.get(), c = [];
for (const i of o)
r.done.has(i.e.id) || (r.retry.has(i.e.id) ? i.r < J && (i.r += 1, c.push(i)) : c.push(i));
const i = [];
for (const r of this._processing)
s.find((d) => d.id === r) || i.push(r);
this._processing = new Set(i);
const n = this._store.get(), c = [];
for (const r of n)
o.done.has(r.e.id) || (o.retry.has(r.e.id) ? r.r < A && (r.r += 1, c.push(r)) : c.push(r));
this._setEntries(c);
}
_setEntries(t) {
this._store.set(t), t.length && (t.some((s) => s.p === m) || this._store instanceof b ? this._processNow(t) : this._scheduleProcessing());
_setEntries(e) {
this._store.set(e), e.length && (e.some((s) => s.p === _) || this._store instanceof S ? this._processNow(e) : this._scheduleProcessing());
}

@@ -192,59 +108,59 @@ _scheduleProcessing() {

this._scheduled = !1, this._processNow(this._store.get());
}, Y));
}, R));
}
}
function Q(e, t) {
if (e.size <= t)
return e;
const s = e.values();
for (let r = 0; r < e.size - t; ++r)
function x(t, e) {
if (t.size <= e)
return t;
const s = t.values();
for (let o = 0; o < t.size - e; ++o)
s.next();
return new Set(s);
}
const V = 2500, tt = 0.5;
let h = /* @__PURE__ */ new Set();
const k = new K("ts-b");
function v() {
const D = 2500, $ = 0.5;
let l = /* @__PURE__ */ new Set();
const I = new N("ts-b");
function y() {
return window.URL.createObjectURL?.(new Blob()).split("/").pop() || `${Math.random()}`;
}
let l;
function g() {
if (l)
return l;
const e = st();
if (e)
return l = e, e;
const t = v();
return O(t), t;
let u;
function w() {
if (u)
return u;
const t = J();
if (t)
return u = t, t;
const e = y();
return E(e), e;
}
function O(e) {
const t = window.TS.cookieName || "tsuid";
l = e, document.cookie = `${t}=${e};max-age=31536000`;
function E(t) {
const e = window.TS.cookieName || "tsuid";
u = t, document.cookie = `${e}=${t};max-age=31536000`;
}
function et() {
return l = void 0, document.cookie = "tsuid=", g();
function B() {
return u = void 0, document.cookie = "tsuid=", w();
}
window.TS.setUserId = O;
typeof window.TS.getUserId != "function" && (window.TS.getUserId = g);
window.TS.resetUserId = et;
function st() {
const e = window.TS.cookieName || "tsuid";
return new RegExp(`(^|;)\\s*${e}\\s*=\\s*([^;]+)`).exec(document.cookie)?.pop();
window.TS.setUserId = E;
typeof window.TS.getUserId != "function" && (window.TS.getUserId = w);
window.TS.resetUserId = B;
function J() {
const t = window.TS.cookieName || "tsuid";
return new RegExp(`(^|;)\\s*${t}\\s*=\\s*([^;]+)`).exec(document.cookie)?.pop();
}
function rt(e) {
const t = e.type, s = {
path: e.page
function K(t) {
const e = t.type, s = {
path: t.page
};
let r;
e.product && (r = {
let o;
t.product && (o = {
type: "product",
id: e.product
id: t.product
});
let n;
e.additionalProduct && (n = {
let i;
t.additionalProduct && (i = {
type: "product",
id: e.additionalProduct
id: t.additionalProduct
});
const o = new Date(e.t).toISOString();
switch (t) {
const n = new Date(t.t).toISOString();
switch (e) {
case "Click":

@@ -254,9 +170,9 @@ return {

{
resolvedBidId: e.bid,
entity: r,
additionalAttribution: n,
resolvedBidId: t.bid,
entity: o,
additionalAttribution: i,
placement: s,
occurredAt: o,
opaqueUserId: e.uid,
id: e.id
occurredAt: n,
opaqueUserId: t.uid,
id: t.id
}

@@ -269,9 +185,9 @@ ]

{
resolvedBidId: e.bid,
entity: r,
additionalAttribution: n,
resolvedBidId: t.bid,
entity: o,
additionalAttribution: i,
placement: s,
occurredAt: o,
opaqueUserId: e.uid,
id: e.id
occurredAt: n,
opaqueUserId: t.uid,
id: t.id
}

@@ -284,5 +200,5 @@ ]

{
occurredAt: o,
opaqueUserId: e.uid,
items: (e.items || []).map((c) => ({
occurredAt: n,
opaqueUserId: t.uid,
items: (t.items || []).map((c) => ({
productId: c.product,

@@ -292,3 +208,3 @@ quantity: c.quantity,

})),
id: e.id
id: t.id
}

@@ -299,114 +215,114 @@ ]

}
async function nt(e) {
const t = {
async function X(t) {
const e = {
done: /* @__PURE__ */ new Set(),
retry: /* @__PURE__ */ new Set()
}, s = [], r = {
}, s = [], o = {
apiKey: window.TS.token,
host: window.TS.url,
userAgent: `ts.js/${D}`
}, n = new B(r);
for (const o of e)
userAgent: `ts.js/${M}`
}, i = new O(o);
for (const n of t)
s.push(
n.reportEvent(rt(o)).then((c) => {
(c.retry ? t.retry : t.done).add(o.id);
i.reportEvent(K(n)).then((c) => {
(c.retry ? e.retry : e.done).add(n.id);
}).catch(() => {
t.done.add(o.id);
e.done.add(n.id);
})
);
return await Promise.all(s), t;
return await Promise.all(s), e;
}
const ot = new F(nt);
function f(e, t) {
const s = it(e);
if (h.has(s))
const Y = new H(X);
function h(t, e) {
const s = j(t);
if (l.has(s))
return;
h.add(s), h = Q(h, V), ot.append(e);
const r = new CustomEvent("topsort", { bubbles: !0, detail: e });
t.dispatchEvent(r);
l.add(s), l = x(l, D), Y.append(t);
const o = new CustomEvent("topsort", { bubbles: !0, detail: t });
e.dispatchEvent(o);
}
function it(e) {
const t = JSON.stringify(e.items || []);
return [e.page, e.type, e.product ?? e.additionalProduct, e.bid, t].join(
function j(t) {
const e = JSON.stringify(t.items || []);
return [t.page, t.type, t.product ?? t.additionalProduct, t.bid, e].join(
"-"
);
}
function ct() {
const e = window.location, t = e.hash;
return t[1] === "/" ? t : `${e.pathname}${e.search}`;
function G() {
const t = window.location, e = t.hash;
return e[1] === "/" ? e : `${t.pathname}${t.search}`;
}
function p(e, t) {
let s = t.dataset.tsProduct, r = t.dataset.tsResolvedBid, n;
r === "inherit" && s && (e === "Click" || e === "Impression") && (r = k.get(), n = s, s = void 0);
const o = {
type: e,
function f(t, e) {
let s = e.dataset.tsProduct, o = e.dataset.tsResolvedBid, i;
o === "inherit" && s && (t === "Click" || t === "Impression") && (o = I.get(), i = s, s = void 0);
const n = {
type: t,
product: s,
additionalProduct: n,
bid: r,
additionalProduct: i,
bid: o,
t: Date.now(),
page: ct(),
id: v(),
uid: typeof window.TS.getUserId == "function" ? window.TS.getUserId() : g()
page: G(),
id: y(),
uid: typeof window.TS.getUserId == "function" ? window.TS.getUserId() : w()
};
return e === "Purchase" && (o.items = JSON.parse(t.dataset.tsItems || "[]")), o;
return t === "Purchase" && (n.items = JSON.parse(e.dataset.tsItems || "[]")), n;
}
function at(e) {
if (!(e.currentTarget instanceof HTMLElement))
function z(t) {
if (!(t.currentTarget instanceof HTMLElement))
return;
const t = e.currentTarget.closest(A);
if (t && t instanceof HTMLElement) {
const s = p("Click", t);
f(s, t), s.bid && k.set(s.bid);
const e = t.currentTarget.closest(T);
if (e && e instanceof HTMLElement) {
const s = f("Click", e);
h(s, e), s.bid && I.set(s.bid);
}
}
const w = window.IntersectionObserver ? new IntersectionObserver(
(e) => {
for (const t of e)
if (t.isIntersecting) {
const s = t.target;
s instanceof HTMLElement && (f(p("Impression", s), s), w && w.unobserve(s));
const p = window.IntersectionObserver ? new IntersectionObserver(
(t) => {
for (const e of t)
if (e.isIntersecting) {
const s = e.target;
s instanceof HTMLElement && (h(f("Impression", s), s), p && p.unobserve(s));
}
},
{
threshold: tt
threshold: $
}
) : void 0, A = "[data-ts-product],[data-ts-action],[data-ts-items],[data-ts-resolved-bid]";
function dt(e) {
const t = e.querySelectorAll("[data-ts-clickable]"), s = t.length === 0 ? [e] : Array.from(t);
for (const r of s)
r.addEventListener("click", at);
) : void 0, T = "[data-ts-product],[data-ts-action],[data-ts-items],[data-ts-resolved-bid]";
function W(t) {
const e = t.querySelectorAll("[data-ts-clickable]"), s = e.length === 0 ? [t] : Array.from(e);
for (const o of s)
o.addEventListener("click", z);
}
function P(e) {
ut(e) ? f(p("Purchase", e), e) : (w ? w.observe(e) : f(p("Impression", e), e), dt(e));
function b(t) {
Z(t) ? h(f("Purchase", t), t) : (p ? p.observe(t) : h(f("Impression", t), t), W(t));
}
function U(e) {
const t = e.querySelectorAll(A);
for (let s = 0; s < t.length; s++) {
const r = t[s];
r instanceof HTMLElement && P(r);
function k(t) {
const e = t.querySelectorAll(T);
for (let s = 0; s < e.length; s++) {
const o = e[s];
o instanceof HTMLElement && b(o);
}
}
function ut(e) {
return e.dataset.tsAction === "purchase";
function Z(t) {
return t.dataset.tsAction === "purchase";
}
function lt(e) {
for (const t of e)
if (t.type === "childList") {
function F(t) {
for (const e of t)
if (e.type === "childList") {
const s = /* @__PURE__ */ new Set();
for (let r = 0; r < t.addedNodes.length; r++) {
const n = t.addedNodes[r];
if (n?.nodeType === Node.ELEMENT_NODE) {
const o = n.parentElement;
o && !s.has(o) && s.add(o);
for (let o = 0; o < e.addedNodes.length; o++) {
const i = e.addedNodes[o];
if (i?.nodeType === Node.ELEMENT_NODE) {
const n = i.parentElement;
n && !s.has(n) && s.add(n);
}
for (const o of s)
U(o);
for (const n of s)
k(n);
}
} else if (t.type === "attributes") {
if (!(t.target instanceof HTMLElement))
} else if (e.type === "attributes") {
if (!(e.target instanceof HTMLElement))
continue;
P(t.target);
b(e.target);
}
}
function S() {
function m() {
if (window.TS?.loaded)

@@ -418,5 +334,5 @@ return;

}
U(document);
const e = window.MutationObserver || window.WebKitMutationObserver || window.MozMutationObserver;
new e(lt).observe(document, {
k(document);
const t = window.MutationObserver || window.WebKitMutationObserver || window.MozMutationObserver;
new t(F).observe(document, {
attributes: !0,

@@ -428,2 +344,2 @@ childList: !0,

}
/complete|interactive|loaded/.test(document.readyState) ? S() : window.addEventListener("DOMContentLoaded", S);
/complete|interactive|loaded/.test(document.readyState) ? m() : window.addEventListener("DOMContentLoaded", m);
{
"name": "@topsort/analytics.js",
"version": "2.6.0",
"version": "2.7.0",
"description": "JS library to automatically report events to Topsort's Analytics",

@@ -26,2 +26,5 @@ "main": "dist/ts.js",

"require": "./dist/ts.js"
},
"./iife": {
"default": "./dist/ts.iife.js"
}

@@ -34,2 +37,3 @@ },

"dist/ts.mjs",
"dist/ts.iife.js",
"dist/src/*.d.ts",

@@ -42,3 +46,3 @@ "package.json",

"scripts": {
"build": "vite build",
"build": "vite build && vite build --mode iife",
"format": "biome format",

@@ -64,3 +68,3 @@ "format:fix": "biome format --write",

"jsdom": "27.2.0",
"msw": "2.12.1",
"msw": "2.12.4",
"react": "19.2.0",

@@ -67,0 +71,0 @@ "react-dom": "19.2.0",