@li2/analytics 0.3.3 → 0.4.0-beta.1

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.
Files changed (46) hide show
  1. package/dist/auto-events.global.js +1 -1
  2. package/dist/auto-events.js +1 -1
  3. package/dist/auto-events.mjs +1 -1
  4. package/dist/chunk-4EC35KD3.mjs +1 -0
  5. package/dist/chunk-5TDT656N.mjs +0 -0
  6. package/dist/chunk-772JYJV2.mjs +1 -0
  7. package/dist/chunk-EO7Y3K6L.mjs +1 -0
  8. package/dist/chunk-FF6VDEL5.mjs +1 -1
  9. package/dist/chunk-GS2LGTLM.mjs +1 -0
  10. package/dist/chunk-HWKYLC4Q.mjs +1 -0
  11. package/dist/chunk-KZDID5T3.mjs +1 -0
  12. package/dist/chunk-LZDMBCUK.mjs +1 -1
  13. package/dist/chunk-MURA7RU5.mjs +0 -1
  14. package/dist/chunk-PGNNL26O.mjs +1 -0
  15. package/dist/chunk-PSKG2XOE.mjs +1 -0
  16. package/dist/click-tracker/index.d.mts +13 -0
  17. package/dist/click-tracker/index.d.ts +13 -0
  18. package/dist/click-tracker/index.global.js +1 -1
  19. package/dist/click-tracker/index.js +1 -1
  20. package/dist/click-tracker/index.mjs +1 -1
  21. package/dist/{index-B3dzYzIM.d.mts → index-BlPDBYpZ.d.mts} +9 -2
  22. package/dist/{index-B3dzYzIM.d.ts → index-BlPDBYpZ.d.ts} +9 -2
  23. package/dist/index.d.mts +28 -2
  24. package/dist/index.d.ts +28 -2
  25. package/dist/index.global.js +1 -1
  26. package/dist/index.js +1 -1
  27. package/dist/index.mjs +1 -1
  28. package/dist/interaction-batch-sender-E3M77C4U.mjs +1 -0
  29. package/dist/interaction-batch-sender-GVPPBMES.mjs +1 -0
  30. package/dist/interaction-batch-sender-PLC6EBSJ.mjs +1 -0
  31. package/dist/interaction-batch-sender-S4752CBB.mjs +0 -0
  32. package/dist/outbound.global.js +1 -1
  33. package/dist/outbound.js +1 -1
  34. package/dist/outbound.mjs +1 -1
  35. package/dist/pageview/index.d.mts +1 -1
  36. package/dist/pageview/index.d.ts +1 -1
  37. package/dist/pageview/index.global.js +1 -1
  38. package/dist/pageview/index.js +1 -1
  39. package/dist/pageview/index.mjs +1 -1
  40. package/dist/scroll-tracker-YQKUW7A7.mjs +1 -0
  41. package/dist/toolbar/index.d.mts +4 -3
  42. package/dist/toolbar/index.d.ts +4 -3
  43. package/dist/toolbar/index.global.js +51 -2
  44. package/dist/toolbar/index.js +51 -2
  45. package/dist/toolbar/index.mjs +51 -2
  46. package/package.json +13 -12
@@ -1 +1 @@
1
- "use strict";var li2Analytics=(()=>{var u=Object.defineProperty;var v=Object.getOwnPropertyDescriptor;var S=Object.getOwnPropertyNames;var E=Object.prototype.hasOwnProperty;var I=(n,e)=>{for(var t in e)u(n,t,{get:e[t],enumerable:!0})},k=(n,e,t,i)=>{if(e&&typeof e=="object"||typeof e=="function")for(let s of S(e))!E.call(n,s)&&s!==t&&u(n,s,{get:()=>e[s],enumerable:!(i=v(e,s))||i.enumerable});return n};var C=n=>k(u({},"__esModule",{value:!0}),n);var N={};I(N,{ClickTracker:()=>g,DEFAULT_CLICK_TRACKER_CONFIG:()=>U});var a="li2_vid",d="li2_sid",f="li2_la",c=class{constructor(e){this.config=e,this.visitorId=this.resolveVisitorId(),this.sessionId=this.resolveSessionId()}getVisitorId(){return this.visitorId}getSessionId(){return this.isSessionExpired()&&this.createNewSession(),this.sessionId}touch(){let e=Date.now();this.setStorage(f,e.toString(),"session")}createNewSession(){this.sessionId=this.generateId("sess"),this.setStorage(d,this.sessionId,"session"),this.touch()}resolveVisitorId(){let e=this.getStorage(a,"local");return!e&&!this.config.cookieLessMode&&(e=this.getCookie(a)),e||(e=this.generateId("vis")),this.setStorage(a,e,"local"),this.config.cookieLessMode||this.setCookie(a,e,365),e}resolveSessionId(){let e=this.getStorage(d,"session");return(!e||this.isSessionExpired())&&(e=this.generateId("sess"),this.setStorage(d,e,"session"),this.touch()),e}isSessionExpired(){let e=this.getStorage(f,"session");if(!e)return!0;let t=Date.now()-parseInt(e,10),i=this.config.timeout*60*1e3;return t>i}generateId(e){if(typeof crypto<"u"&&crypto.randomUUID)return`${e}_${crypto.randomUUID().replace(/-/g,"").slice(0,16)}`;let t=Array.from({length:16},()=>Math.floor(Math.random()*16).toString(16)).join("");return`${e}_${t}`}getStorage(e,t){try{return(t==="local"?localStorage:sessionStorage).getItem(e)}catch{return null}}setStorage(e,t,i){try{(i==="local"?localStorage:sessionStorage).setItem(e,t)}catch{}}getCookie(e){let t=document.cookie.match(new RegExp(`(?:^|;\\s*)${e}=([^;]*)`));return t?decodeURIComponent(t[1]):null}setCookie(e,t,i){let s=[`${e}=${encodeURIComponent(t)}`,`path=${this.config.cookiePath}`,`max-age=${i*86400}`,"SameSite=Lax"];this.config.cookieDomain&&s.push(`domain=${this.config.cookieDomain}`),window.location.protocol==="https:"&&s.push("Secure"),document.cookie=s.join("; ")}};var y=new Set(["a","button","input","select","textarea","form","label"]),_=new Set(["button","link","tab","menuitem"]);function p(n){let e=n;for(;e&&!(e instanceof HTMLElement);)e=e.parentElement;if(!e)return null;let i=w(e),s=x(i);return{tag:i.tagName.toLowerCase(),text:m(L(i),256),href:M(i),className:m(i.className||"",512),id:i.id||null,selectorPath:T(i),isFixed:s}}function w(n){let e=n,t=0;for(;e&&t<5&&e.tagName!=="BODY";){let i=e.tagName.toLowerCase(),s=e.getAttribute("role");if(y.has(i)||s&&_.has(s))return e;e=e.parentElement,t++}return n}function x(n){let e=n;for(;e&&e!==document.body;){try{let i=window.getComputedStyle(e).getPropertyValue("position");if(i==="fixed"||i==="sticky")return!0}catch{break}e=e.parentElement}return!1}function T(n){let e=[],t=n,i=0;for(;t&&t!==document.body&&i<5;){let s=t.tagName.toLowerCase();t.id&&(s+=`#${t.id}`);let o=t.parentElement;if(o){let l=Array.from(o.children).filter(r=>r.tagName===t.tagName);if(l.length>1){let r=l.indexOf(t)+1;s+=`:nth-of-type(${r})`}}e.unshift(s),t=t.parentElement,i++}return e.join(" > ")}function L(n){return n instanceof HTMLInputElement?n.value||n.placeholder||"":(n.innerText||n.textContent||"").trim()}function M(n){return n instanceof HTMLAnchorElement?n.href||null:n.getAttribute("href")||null}function m(n,e){return n.length<=e?n:n.slice(0,e)}function b(n,e){let t=window.scrollX||document.documentElement.scrollLeft,i=window.scrollY||document.documentElement.scrollTop;return{x:n.clientX+(e?0:t),y:n.clientY+(e?0:i),scrollY:i,pageHeight:document.documentElement.scrollHeight}}var h=class{constructor(e){this.buffer=[];this.timer=null;this.started=!1;this.handleBeforeUnload=null;this.handleVisibilityChange=null;this.config=e}start(){this.started||(this.started=!0,this.timer=setInterval(()=>this.flush(),this.config.batchInterval),this.handleBeforeUnload=()=>this.flush(!0),window.addEventListener("beforeunload",this.handleBeforeUnload),this.handleVisibilityChange=()=>{document.visibilityState==="hidden"&&this.flush(!0)},document.addEventListener("visibilitychange",this.handleVisibilityChange))}stop(){this.started&&(this.started=!1,this.flush(!0),this.timer&&(clearInterval(this.timer),this.timer=null),this.handleBeforeUnload&&(window.removeEventListener("beforeunload",this.handleBeforeUnload),this.handleBeforeUnload=null),this.handleVisibilityChange&&(document.removeEventListener("visibilitychange",this.handleVisibilityChange),this.handleVisibilityChange=null))}add(e){this.buffer.push(e),this.buffer.length>=this.config.batchSize&&this.flush()}getBufferSize(){return this.buffer.length}flush(e=!1){if(this.buffer.length===0)return;let t=this.buffer.splice(0,this.config.batchSize),i={interactions:t},s=`${this.config.apiUrl}/api/v1/track/interaction`,o=JSON.stringify(i);if(e&&navigator.sendBeacon){let l=`${s}?li2_key=${encodeURIComponent(this.config.publishableKey)}`,r=new Blob([o],{type:"application/json"});navigator.sendBeacon(l,r)?this.log(`Beacon sent: ${t.length} interactions`):this.sendViaFetch(s,o,t)}else this.sendViaFetch(s,o,t);this.buffer.length>0&&this.flush(e)}sendViaFetch(e,t,i){fetch(e,{method:"POST",headers:{"Content-Type":"application/json","X-Li2-Key":this.config.publishableKey},body:t,keepalive:!0}).then(s=>{s.ok?this.log(`Sent: ${i.length} interactions`):(this.log(`Send failed: ${s.status}, re-queuing ${i.length} events`),this.buffer.unshift(...i))}).catch(()=>{this.log(`Network error, re-queuing ${i.length} events`),this.buffer.unshift(...i)})}log(...e){this.config.debug&&console.log("[Li2 InteractionBatchSender]",...e)}};var U={batchInterval:5e3,batchSize:50,excludeSelector:null,debug:!1,sessionTimeout:30,cookieLessMode:!1,cookiePath:"/"},H=50,g=class{constructor(e){this.started=!1;this.handleClick=null;this.lastClickTarget=null;this.lastClickTime=0;this.config=e,this.sessionManager=new c({timeout:e.sessionTimeout,cookieLessMode:e.cookieLessMode,cookieDomain:e.cookieDomain,cookiePath:e.cookiePath}),this.batchSender=new h({apiUrl:e.apiUrl,publishableKey:e.publishableKey,batchInterval:e.batchInterval,batchSize:e.batchSize,debug:e.debug})}start(){this.started||(this.started=!0,this.handleClick=e=>this.onDocumentClick(e),document.addEventListener("click",this.handleClick,!0),this.batchSender.start(),this.log("ClickTracker started"))}stop(){this.started&&(this.started=!1,this.handleClick&&(document.removeEventListener("click",this.handleClick,!0),this.handleClick=null),this.batchSender.stop(),this.log("ClickTracker stopped"))}onDocumentClick(e){if(e.button!==0)return;let t=Date.now();if(e.target===this.lastClickTarget&&t-this.lastClickTime<H||(this.lastClickTarget=e.target,this.lastClickTime=t,this.shouldExclude(e.target)))return;let i=p(e.target);if(!i)return;let s=b(e,i.isFixed),o={session_id:this.sessionManager.getSessionId(),visitor_id:this.sessionManager.getVisitorId(),li2_cid:this.config.clickId,page_url:window.location.href,page_path:window.location.pathname,x:s.x,y:s.y,target_fixed:i.isFixed,viewport_width:window.innerWidth,viewport_height:window.innerHeight,page_height:s.pageHeight,scroll_y:s.scrollY,element_tag:i.tag,element_text:i.text,element_href:i.href,element_class:i.className,element_id:i.id,selector_path:i.selectorPath,interaction_type:"click",timestamp:t};this.sessionManager.touch(),this.batchSender.add(o)}shouldExclude(e){if(!this.config.excludeSelector||!e)return!1;let t=e;for(;t&&t!==document.body;){try{if(t.matches(this.config.excludeSelector))return!0}catch{return this.log(`Invalid excludeSelector: ${this.config.excludeSelector}`),this.config.excludeSelector=null,!1}t=t.parentElement}return!1}log(...e){this.config.debug&&console.log("[Li2 ClickTracker]",...e)}};return C(N);})();
1
+ "use strict";var li2Analytics=(()=>{var h=Object.defineProperty;var w=Object.getOwnPropertyDescriptor;var C=Object.getOwnPropertyNames;var _=Object.prototype.hasOwnProperty;var T=(i,e)=>{for(var t in e)h(i,t,{get:e[t],enumerable:!0})},L=(i,e,t,n)=>{if(e&&typeof e=="object"||typeof e=="function")for(let s of C(e))!_.call(i,s)&&s!==t&&h(i,s,{get:()=>e[s],enumerable:!(n=w(e,s))||n.enumerable});return i};var M=i=>L(h({},"__esModule",{value:!0}),i);var A={};T(A,{ClickTracker:()=>m,DEFAULT_CLICK_TRACKER_CONFIG:()=>F});var a="li2_vid",g="li2_sid",b="li2_la",c=class{constructor(e){this.config=e,this.visitorId=this.resolveVisitorId(),this.sessionId=this.resolveSessionId()}getVisitorId(){return this.visitorId}getSessionId(){return this.isSessionExpired()&&this.createNewSession(),this.sessionId}touch(){let e=Date.now();this.setStorage(b,e.toString(),"session")}createNewSession(){this.sessionId=this.generateId("sess"),this.setStorage(g,this.sessionId,"session"),this.touch()}resolveVisitorId(){let e=this.getStorage(a,"local");return!e&&!this.config.cookieLessMode&&(e=this.getCookie(a)),e||(e=this.generateId("vis")),this.setStorage(a,e,"local"),this.config.cookieLessMode||this.setCookie(a,e,365),e}resolveSessionId(){let e=this.getStorage(g,"session");return(!e||this.isSessionExpired())&&(e=this.generateId("sess"),this.setStorage(g,e,"session"),this.touch()),e}isSessionExpired(){let e=this.getStorage(b,"session");if(!e)return!0;let t=Date.now()-parseInt(e,10),n=this.config.timeout*60*1e3;return t>n}generateId(e){if(typeof crypto<"u"&&crypto.randomUUID)return`${e}_${crypto.randomUUID().replace(/-/g,"").slice(0,16)}`;let t=Array.from({length:16},()=>Math.floor(Math.random()*16).toString(16)).join("");return`${e}_${t}`}getStorage(e,t){try{return(t==="local"?localStorage:sessionStorage).getItem(e)}catch{return null}}setStorage(e,t,n){try{(n==="local"?localStorage:sessionStorage).setItem(e,t)}catch{}}getCookie(e){let t=document.cookie.match(new RegExp(`(?:^|;\\s*)${e}=([^;]*)`));return t?decodeURIComponent(t[1]):null}setCookie(e,t,n){let s=[`${e}=${encodeURIComponent(t)}`,`path=${this.config.cookiePath}`,`max-age=${n*86400}`,"SameSite=Lax"];this.config.cookieDomain&&s.push(`domain=${this.config.cookieDomain}`),window.location.protocol==="https:"&&s.push("Secure"),document.cookie=s.join("; ")}};var P=new Set(["a","button","input","select","textarea","form","label"]),$=new Set(["button","link","tab","menuitem"]);function k(i){let e=i;for(;e&&!(e instanceof HTMLElement);)e=e.parentElement;if(!e)return null;let n=D(e),s=N(n);return{tag:n.tagName.toLowerCase(),text:v(j(n),256),href:H(n),className:v(n.className||"",512),id:n.id||null,selectorPath:U(n),isFixed:s}}function D(i){let e=i,t=0;for(;e&&t<5&&e.tagName!=="BODY";){let n=e.tagName.toLowerCase(),s=e.getAttribute("role");if(P.has(n)||s&&$.has(s))return e;e=e.parentElement,t++}return i}function N(i){let e=i;for(;e&&e!==document.body;){try{let n=window.getComputedStyle(e).getPropertyValue("position");if(n==="fixed"||n==="sticky")return!0}catch{break}e=e.parentElement}return!1}function U(i){let e=[],t=i,n=0;for(;t&&t!==document.body&&n<5;){let s=t.tagName.toLowerCase();t.id&&(s+=`#${t.id}`);let o=t.parentElement;if(o){let r=Array.from(o.children).filter(l=>l.tagName===t.tagName);if(r.length>1){let l=r.indexOf(t)+1;s+=`:nth-of-type(${l})`}}e.unshift(s),t=t.parentElement,n++}return e.join(" > ")}function j(i){return i instanceof HTMLInputElement?i.value||i.placeholder||"":(i.innerText||i.textContent||"").trim()}function H(i){return i instanceof HTMLAnchorElement?i.href||null:i.getAttribute("href")||null}function v(i,e){return i.length<=e?i:i.slice(0,e)}function x(i,e){let t=window.scrollX||document.documentElement.scrollLeft,n=window.scrollY||document.documentElement.scrollTop;return{x:i.clientX+(e?0:t),y:i.clientY+(e?0:n),scrollY:n,pageHeight:document.documentElement.scrollHeight}}var S={name:"@li2/analytics",version:"0.4.0-beta.1",description:"Li2 Analytics SDK for conversion tracking",main:"dist/index.js",module:"dist/index.mjs",types:"dist/index.d.ts",exports:{".":{types:"./dist/index.d.ts",import:"./dist/index.mjs",require:"./dist/index.js"},"./pageview":{types:"./dist/pageview/index.d.ts",import:"./dist/pageview/index.mjs",require:"./dist/pageview/index.js"},"./click-tracker":{types:"./dist/click-tracker/index.d.ts",import:"./dist/click-tracker/index.mjs",require:"./dist/click-tracker/index.js"},"./toolbar":{types:"./dist/toolbar/index.d.ts",import:"./dist/toolbar/index.mjs",require:"./dist/toolbar/index.js"}},files:["dist"],scripts:{build:"tsup src/index.ts src/outbound.ts src/auto-events.ts src/pageview/index.ts src/click-tracker/index.ts src/toolbar/index.ts --format cjs,esm,iife --dts --minify --global-name li2Analytics","build:obfuscate":"tsup src/index.ts src/outbound.ts src/auto-events.ts src/pageview/index.ts src/click-tracker/index.ts src/toolbar/index.ts --format cjs,esm,iife --dts --minify --global-name li2Analytics && node scripts/obfuscate.js",dev:"tsup src/index.ts src/outbound.ts src/auto-events.ts src/pageview/index.ts src/click-tracker/index.ts src/toolbar/index.ts --format cjs,esm,iife --dts --watch --global-name li2Analytics",demo:"pnpm run build && node demo/server.js","demo:serve":"node demo/server.js",test:"vitest run","test:watch":"vitest","test:coverage":"vitest run --coverage",prepublishOnly:"NODE_OPTIONS=--max-old-space-size=4096 pnpm run build:obfuscate"},keywords:["li2","analytics","conversion","tracking"],author:"Li2",license:"MIT",devDependencies:{"@vitest/coverage-v8":"^4.0.18","happy-dom":"^20.6.1","javascript-obfuscator":"^4.1.0",tsup:"^8.0.0",typescript:"^5.0.0",vitest:"^4.0.18"}};var f=S.version;var d=class{constructor(e){this.buffer=[];this.timer=null;this.started=!1;this.handleBeforeUnload=null;this.handleVisibilityChange=null;this.config=e}start(){this.started||(this.started=!0,this.timer=setInterval(()=>this.flush(),this.config.batchInterval),this.handleBeforeUnload=()=>this.flush(!0),window.addEventListener("beforeunload",this.handleBeforeUnload),this.handleVisibilityChange=()=>{document.visibilityState==="hidden"&&this.flush(!0)},document.addEventListener("visibilitychange",this.handleVisibilityChange))}stop(){this.started&&(this.started=!1,this.flush(!0),this.timer&&(clearInterval(this.timer),this.timer=null),this.handleBeforeUnload&&(window.removeEventListener("beforeunload",this.handleBeforeUnload),this.handleBeforeUnload=null),this.handleVisibilityChange&&(document.removeEventListener("visibilitychange",this.handleVisibilityChange),this.handleVisibilityChange=null))}add(e){this.buffer.push(e),this.buffer.length>=this.config.batchSize&&this.flush()}getBufferSize(){return this.buffer.length}flush(e=!1){if(this.buffer.length===0)return;let t=this.buffer.splice(0,this.config.batchSize),n={interactions:t},s=`${this.config.apiUrl}/api/v1/track/interaction`;if(e&&navigator.sendBeacon){let o={...n,sdk_version:f},r=`${s}?li2_key=${encodeURIComponent(this.config.publishableKey)}`,l=new Blob([JSON.stringify(o)],{type:"application/json"});navigator.sendBeacon(r,l)?this.log(`Beacon sent: ${t.length} interactions`):this.sendViaFetch(s,JSON.stringify(n),t)}else{let o=JSON.stringify(n);this.sendViaFetch(s,o,t)}this.buffer.length>0&&this.flush(e)}sendViaFetch(e,t,n){fetch(e,{method:"POST",headers:{"Content-Type":"application/json","X-Li2-Key":this.config.publishableKey,"X-Li2-SDK-Version":f},body:t,keepalive:!0}).then(s=>{s.ok?this.log(`Sent: ${n.length} interactions`):(this.log(`Send failed: ${s.status}, re-queuing ${n.length} events`),this.buffer.unshift(...n))}).catch(()=>{this.log(`Network error, re-queuing ${n.length} events`),this.buffer.unshift(...n)})}log(...e){this.config.debug&&console.log("[Li2 InteractionBatchSender]",...e)}};function y(i,e,t){if(!e)return!0;let{mode:n,includePaths:s,excludePaths:o}=e;if(n==="include"){if(!(s&&s.length>0))return t&&console.log(`[PathFilter] mode=include but no includePaths, blocking "${i}"`),!1;let p=s.some(I=>E(i,I));return t&&(p?console.log(`[PathFilter] mode=include: "${i}" matched includePath`):console.log(`[PathFilter] mode=include: "${i}" not in includePaths:`,s)),p}return o&&o.length>0?o.some(u=>E(i,u))?(t&&console.log(`[PathFilter] mode=exclude: "${i}" matched excludePath:`,o),!1):(t&&console.log(`[PathFilter] Path "${i}" allowed by rules`),!0):(t&&console.log(`[PathFilter] No excludePaths, path "${i}" allowed`),!0)}function E(i,e){let n=e.replace(/[.+?^${}()|[\]\\]/g,"\\$&").replace(/\*\*|\*/g,s=>s==="**"?".*":"[^/]*");return new RegExp(`^${n}$`).test(i)}var F={batchInterval:5e3,batchSize:50,excludeSelector:null,debug:!1,sessionTimeout:30,cookieLessMode:!1,cookiePath:"/"},V=50,m=class{constructor(e){this.started=!1;this.handleClick=null;this.lastClickTarget=null;this.lastClickTime=0;this.config=e,this.sessionManager=new c({timeout:e.sessionTimeout,cookieLessMode:e.cookieLessMode,cookieDomain:e.cookieDomain,cookiePath:e.cookiePath}),this.batchSender=new d({apiUrl:e.apiUrl,publishableKey:e.publishableKey,batchInterval:e.batchInterval,batchSize:e.batchSize,debug:e.debug})}start(){this.started||(this.started=!0,this.handleClick=e=>this.onDocumentClick(e),document.addEventListener("click",this.handleClick,!0),this.batchSender.start(),this.log("ClickTracker started"))}stop(){this.started&&(this.started=!1,this.handleClick&&(document.removeEventListener("click",this.handleClick,!0),this.handleClick=null),this.batchSender.stop(),this.log("ClickTracker stopped"))}onDocumentClick(e){if(e.button!==0)return;let t=window.location.pathname;if(!y(t,this.config.dataCollectionRules,this.config.debug)){this.log(`Path excluded from tracking: ${t}`);return}let n=Date.now();if(e.target===this.lastClickTarget&&n-this.lastClickTime<V||(this.lastClickTarget=e.target,this.lastClickTime=n,this.shouldExclude(e.target)))return;let s=k(e.target);if(!s)return;let o=x(e,s.isFixed),r={session_id:this.sessionManager.getSessionId(),visitor_id:this.sessionManager.getVisitorId(),li2_cid:this.config.clickId,page_url:window.location.href,page_path:window.location.pathname,x:o.x,y:o.y,target_fixed:s.isFixed,viewport_width:window.innerWidth,viewport_height:window.innerHeight,page_height:o.pageHeight,scroll_y:o.scrollY,element_tag:s.tag,element_text:s.text,element_href:s.href,element_class:s.className,element_id:s.id,selector_path:s.selectorPath,interaction_type:"click",timestamp:n};this.sessionManager.touch(),this.batchSender.add(r)}shouldExclude(e){if(!this.config.excludeSelector||!e)return!1;let t=e;for(;t&&t!==document.body;){try{if(t.matches(this.config.excludeSelector))return!0}catch{return this.log(`Invalid excludeSelector: ${this.config.excludeSelector}`),this.config.excludeSelector=null,!1}t=t.parentElement}return!1}log(...e){this.config.debug&&console.log("[Li2 ClickTracker]",...e)}};return M(A);})();
@@ -1 +1 @@
1
- "use strict";var u=Object.defineProperty;var v=Object.getOwnPropertyDescriptor;var S=Object.getOwnPropertyNames;var E=Object.prototype.hasOwnProperty;var I=(n,e)=>{for(var t in e)u(n,t,{get:e[t],enumerable:!0})},k=(n,e,t,i)=>{if(e&&typeof e=="object"||typeof e=="function")for(let s of S(e))!E.call(n,s)&&s!==t&&u(n,s,{get:()=>e[s],enumerable:!(i=v(e,s))||i.enumerable});return n};var C=n=>k(u({},"__esModule",{value:!0}),n);var N={};I(N,{ClickTracker:()=>g,DEFAULT_CLICK_TRACKER_CONFIG:()=>U});module.exports=C(N);var a="li2_vid",d="li2_sid",f="li2_la",c=class{constructor(e){this.config=e,this.visitorId=this.resolveVisitorId(),this.sessionId=this.resolveSessionId()}getVisitorId(){return this.visitorId}getSessionId(){return this.isSessionExpired()&&this.createNewSession(),this.sessionId}touch(){let e=Date.now();this.setStorage(f,e.toString(),"session")}createNewSession(){this.sessionId=this.generateId("sess"),this.setStorage(d,this.sessionId,"session"),this.touch()}resolveVisitorId(){let e=this.getStorage(a,"local");return!e&&!this.config.cookieLessMode&&(e=this.getCookie(a)),e||(e=this.generateId("vis")),this.setStorage(a,e,"local"),this.config.cookieLessMode||this.setCookie(a,e,365),e}resolveSessionId(){let e=this.getStorage(d,"session");return(!e||this.isSessionExpired())&&(e=this.generateId("sess"),this.setStorage(d,e,"session"),this.touch()),e}isSessionExpired(){let e=this.getStorage(f,"session");if(!e)return!0;let t=Date.now()-parseInt(e,10),i=this.config.timeout*60*1e3;return t>i}generateId(e){if(typeof crypto<"u"&&crypto.randomUUID)return`${e}_${crypto.randomUUID().replace(/-/g,"").slice(0,16)}`;let t=Array.from({length:16},()=>Math.floor(Math.random()*16).toString(16)).join("");return`${e}_${t}`}getStorage(e,t){try{return(t==="local"?localStorage:sessionStorage).getItem(e)}catch{return null}}setStorage(e,t,i){try{(i==="local"?localStorage:sessionStorage).setItem(e,t)}catch{}}getCookie(e){let t=document.cookie.match(new RegExp(`(?:^|;\\s*)${e}=([^;]*)`));return t?decodeURIComponent(t[1]):null}setCookie(e,t,i){let s=[`${e}=${encodeURIComponent(t)}`,`path=${this.config.cookiePath}`,`max-age=${i*86400}`,"SameSite=Lax"];this.config.cookieDomain&&s.push(`domain=${this.config.cookieDomain}`),window.location.protocol==="https:"&&s.push("Secure"),document.cookie=s.join("; ")}};var y=new Set(["a","button","input","select","textarea","form","label"]),_=new Set(["button","link","tab","menuitem"]);function p(n){let e=n;for(;e&&!(e instanceof HTMLElement);)e=e.parentElement;if(!e)return null;let i=w(e),s=x(i);return{tag:i.tagName.toLowerCase(),text:m(L(i),256),href:M(i),className:m(i.className||"",512),id:i.id||null,selectorPath:T(i),isFixed:s}}function w(n){let e=n,t=0;for(;e&&t<5&&e.tagName!=="BODY";){let i=e.tagName.toLowerCase(),s=e.getAttribute("role");if(y.has(i)||s&&_.has(s))return e;e=e.parentElement,t++}return n}function x(n){let e=n;for(;e&&e!==document.body;){try{let i=window.getComputedStyle(e).getPropertyValue("position");if(i==="fixed"||i==="sticky")return!0}catch{break}e=e.parentElement}return!1}function T(n){let e=[],t=n,i=0;for(;t&&t!==document.body&&i<5;){let s=t.tagName.toLowerCase();t.id&&(s+=`#${t.id}`);let o=t.parentElement;if(o){let l=Array.from(o.children).filter(r=>r.tagName===t.tagName);if(l.length>1){let r=l.indexOf(t)+1;s+=`:nth-of-type(${r})`}}e.unshift(s),t=t.parentElement,i++}return e.join(" > ")}function L(n){return n instanceof HTMLInputElement?n.value||n.placeholder||"":(n.innerText||n.textContent||"").trim()}function M(n){return n instanceof HTMLAnchorElement?n.href||null:n.getAttribute("href")||null}function m(n,e){return n.length<=e?n:n.slice(0,e)}function b(n,e){let t=window.scrollX||document.documentElement.scrollLeft,i=window.scrollY||document.documentElement.scrollTop;return{x:n.clientX+(e?0:t),y:n.clientY+(e?0:i),scrollY:i,pageHeight:document.documentElement.scrollHeight}}var h=class{constructor(e){this.buffer=[];this.timer=null;this.started=!1;this.handleBeforeUnload=null;this.handleVisibilityChange=null;this.config=e}start(){this.started||(this.started=!0,this.timer=setInterval(()=>this.flush(),this.config.batchInterval),this.handleBeforeUnload=()=>this.flush(!0),window.addEventListener("beforeunload",this.handleBeforeUnload),this.handleVisibilityChange=()=>{document.visibilityState==="hidden"&&this.flush(!0)},document.addEventListener("visibilitychange",this.handleVisibilityChange))}stop(){this.started&&(this.started=!1,this.flush(!0),this.timer&&(clearInterval(this.timer),this.timer=null),this.handleBeforeUnload&&(window.removeEventListener("beforeunload",this.handleBeforeUnload),this.handleBeforeUnload=null),this.handleVisibilityChange&&(document.removeEventListener("visibilitychange",this.handleVisibilityChange),this.handleVisibilityChange=null))}add(e){this.buffer.push(e),this.buffer.length>=this.config.batchSize&&this.flush()}getBufferSize(){return this.buffer.length}flush(e=!1){if(this.buffer.length===0)return;let t=this.buffer.splice(0,this.config.batchSize),i={interactions:t},s=`${this.config.apiUrl}/api/v1/track/interaction`,o=JSON.stringify(i);if(e&&navigator.sendBeacon){let l=`${s}?li2_key=${encodeURIComponent(this.config.publishableKey)}`,r=new Blob([o],{type:"application/json"});navigator.sendBeacon(l,r)?this.log(`Beacon sent: ${t.length} interactions`):this.sendViaFetch(s,o,t)}else this.sendViaFetch(s,o,t);this.buffer.length>0&&this.flush(e)}sendViaFetch(e,t,i){fetch(e,{method:"POST",headers:{"Content-Type":"application/json","X-Li2-Key":this.config.publishableKey},body:t,keepalive:!0}).then(s=>{s.ok?this.log(`Sent: ${i.length} interactions`):(this.log(`Send failed: ${s.status}, re-queuing ${i.length} events`),this.buffer.unshift(...i))}).catch(()=>{this.log(`Network error, re-queuing ${i.length} events`),this.buffer.unshift(...i)})}log(...e){this.config.debug&&console.log("[Li2 InteractionBatchSender]",...e)}};var U={batchInterval:5e3,batchSize:50,excludeSelector:null,debug:!1,sessionTimeout:30,cookieLessMode:!1,cookiePath:"/"},H=50,g=class{constructor(e){this.started=!1;this.handleClick=null;this.lastClickTarget=null;this.lastClickTime=0;this.config=e,this.sessionManager=new c({timeout:e.sessionTimeout,cookieLessMode:e.cookieLessMode,cookieDomain:e.cookieDomain,cookiePath:e.cookiePath}),this.batchSender=new h({apiUrl:e.apiUrl,publishableKey:e.publishableKey,batchInterval:e.batchInterval,batchSize:e.batchSize,debug:e.debug})}start(){this.started||(this.started=!0,this.handleClick=e=>this.onDocumentClick(e),document.addEventListener("click",this.handleClick,!0),this.batchSender.start(),this.log("ClickTracker started"))}stop(){this.started&&(this.started=!1,this.handleClick&&(document.removeEventListener("click",this.handleClick,!0),this.handleClick=null),this.batchSender.stop(),this.log("ClickTracker stopped"))}onDocumentClick(e){if(e.button!==0)return;let t=Date.now();if(e.target===this.lastClickTarget&&t-this.lastClickTime<H||(this.lastClickTarget=e.target,this.lastClickTime=t,this.shouldExclude(e.target)))return;let i=p(e.target);if(!i)return;let s=b(e,i.isFixed),o={session_id:this.sessionManager.getSessionId(),visitor_id:this.sessionManager.getVisitorId(),li2_cid:this.config.clickId,page_url:window.location.href,page_path:window.location.pathname,x:s.x,y:s.y,target_fixed:i.isFixed,viewport_width:window.innerWidth,viewport_height:window.innerHeight,page_height:s.pageHeight,scroll_y:s.scrollY,element_tag:i.tag,element_text:i.text,element_href:i.href,element_class:i.className,element_id:i.id,selector_path:i.selectorPath,interaction_type:"click",timestamp:t};this.sessionManager.touch(),this.batchSender.add(o)}shouldExclude(e){if(!this.config.excludeSelector||!e)return!1;let t=e;for(;t&&t!==document.body;){try{if(t.matches(this.config.excludeSelector))return!0}catch{return this.log(`Invalid excludeSelector: ${this.config.excludeSelector}`),this.config.excludeSelector=null,!1}t=t.parentElement}return!1}log(...e){this.config.debug&&console.log("[Li2 ClickTracker]",...e)}};0&&(module.exports={ClickTracker,DEFAULT_CLICK_TRACKER_CONFIG});
1
+ "use strict";var h=Object.defineProperty;var w=Object.getOwnPropertyDescriptor;var C=Object.getOwnPropertyNames;var _=Object.prototype.hasOwnProperty;var T=(i,e)=>{for(var t in e)h(i,t,{get:e[t],enumerable:!0})},L=(i,e,t,n)=>{if(e&&typeof e=="object"||typeof e=="function")for(let s of C(e))!_.call(i,s)&&s!==t&&h(i,s,{get:()=>e[s],enumerable:!(n=w(e,s))||n.enumerable});return i};var M=i=>L(h({},"__esModule",{value:!0}),i);var A={};T(A,{ClickTracker:()=>m,DEFAULT_CLICK_TRACKER_CONFIG:()=>F});module.exports=M(A);var a="li2_vid",g="li2_sid",b="li2_la",c=class{constructor(e){this.config=e,this.visitorId=this.resolveVisitorId(),this.sessionId=this.resolveSessionId()}getVisitorId(){return this.visitorId}getSessionId(){return this.isSessionExpired()&&this.createNewSession(),this.sessionId}touch(){let e=Date.now();this.setStorage(b,e.toString(),"session")}createNewSession(){this.sessionId=this.generateId("sess"),this.setStorage(g,this.sessionId,"session"),this.touch()}resolveVisitorId(){let e=this.getStorage(a,"local");return!e&&!this.config.cookieLessMode&&(e=this.getCookie(a)),e||(e=this.generateId("vis")),this.setStorage(a,e,"local"),this.config.cookieLessMode||this.setCookie(a,e,365),e}resolveSessionId(){let e=this.getStorage(g,"session");return(!e||this.isSessionExpired())&&(e=this.generateId("sess"),this.setStorage(g,e,"session"),this.touch()),e}isSessionExpired(){let e=this.getStorage(b,"session");if(!e)return!0;let t=Date.now()-parseInt(e,10),n=this.config.timeout*60*1e3;return t>n}generateId(e){if(typeof crypto<"u"&&crypto.randomUUID)return`${e}_${crypto.randomUUID().replace(/-/g,"").slice(0,16)}`;let t=Array.from({length:16},()=>Math.floor(Math.random()*16).toString(16)).join("");return`${e}_${t}`}getStorage(e,t){try{return(t==="local"?localStorage:sessionStorage).getItem(e)}catch{return null}}setStorage(e,t,n){try{(n==="local"?localStorage:sessionStorage).setItem(e,t)}catch{}}getCookie(e){let t=document.cookie.match(new RegExp(`(?:^|;\\s*)${e}=([^;]*)`));return t?decodeURIComponent(t[1]):null}setCookie(e,t,n){let s=[`${e}=${encodeURIComponent(t)}`,`path=${this.config.cookiePath}`,`max-age=${n*86400}`,"SameSite=Lax"];this.config.cookieDomain&&s.push(`domain=${this.config.cookieDomain}`),window.location.protocol==="https:"&&s.push("Secure"),document.cookie=s.join("; ")}};var P=new Set(["a","button","input","select","textarea","form","label"]),$=new Set(["button","link","tab","menuitem"]);function k(i){let e=i;for(;e&&!(e instanceof HTMLElement);)e=e.parentElement;if(!e)return null;let n=D(e),s=N(n);return{tag:n.tagName.toLowerCase(),text:v(j(n),256),href:H(n),className:v(n.className||"",512),id:n.id||null,selectorPath:U(n),isFixed:s}}function D(i){let e=i,t=0;for(;e&&t<5&&e.tagName!=="BODY";){let n=e.tagName.toLowerCase(),s=e.getAttribute("role");if(P.has(n)||s&&$.has(s))return e;e=e.parentElement,t++}return i}function N(i){let e=i;for(;e&&e!==document.body;){try{let n=window.getComputedStyle(e).getPropertyValue("position");if(n==="fixed"||n==="sticky")return!0}catch{break}e=e.parentElement}return!1}function U(i){let e=[],t=i,n=0;for(;t&&t!==document.body&&n<5;){let s=t.tagName.toLowerCase();t.id&&(s+=`#${t.id}`);let o=t.parentElement;if(o){let r=Array.from(o.children).filter(l=>l.tagName===t.tagName);if(r.length>1){let l=r.indexOf(t)+1;s+=`:nth-of-type(${l})`}}e.unshift(s),t=t.parentElement,n++}return e.join(" > ")}function j(i){return i instanceof HTMLInputElement?i.value||i.placeholder||"":(i.innerText||i.textContent||"").trim()}function H(i){return i instanceof HTMLAnchorElement?i.href||null:i.getAttribute("href")||null}function v(i,e){return i.length<=e?i:i.slice(0,e)}function x(i,e){let t=window.scrollX||document.documentElement.scrollLeft,n=window.scrollY||document.documentElement.scrollTop;return{x:i.clientX+(e?0:t),y:i.clientY+(e?0:n),scrollY:n,pageHeight:document.documentElement.scrollHeight}}var S={name:"@li2/analytics",version:"0.4.0-beta.1",description:"Li2 Analytics SDK for conversion tracking",main:"dist/index.js",module:"dist/index.mjs",types:"dist/index.d.ts",exports:{".":{types:"./dist/index.d.ts",import:"./dist/index.mjs",require:"./dist/index.js"},"./pageview":{types:"./dist/pageview/index.d.ts",import:"./dist/pageview/index.mjs",require:"./dist/pageview/index.js"},"./click-tracker":{types:"./dist/click-tracker/index.d.ts",import:"./dist/click-tracker/index.mjs",require:"./dist/click-tracker/index.js"},"./toolbar":{types:"./dist/toolbar/index.d.ts",import:"./dist/toolbar/index.mjs",require:"./dist/toolbar/index.js"}},files:["dist"],scripts:{build:"tsup src/index.ts src/outbound.ts src/auto-events.ts src/pageview/index.ts src/click-tracker/index.ts src/toolbar/index.ts --format cjs,esm,iife --dts --minify --global-name li2Analytics","build:obfuscate":"tsup src/index.ts src/outbound.ts src/auto-events.ts src/pageview/index.ts src/click-tracker/index.ts src/toolbar/index.ts --format cjs,esm,iife --dts --minify --global-name li2Analytics && node scripts/obfuscate.js",dev:"tsup src/index.ts src/outbound.ts src/auto-events.ts src/pageview/index.ts src/click-tracker/index.ts src/toolbar/index.ts --format cjs,esm,iife --dts --watch --global-name li2Analytics",demo:"pnpm run build && node demo/server.js","demo:serve":"node demo/server.js",test:"vitest run","test:watch":"vitest","test:coverage":"vitest run --coverage",prepublishOnly:"NODE_OPTIONS=--max-old-space-size=4096 pnpm run build:obfuscate"},keywords:["li2","analytics","conversion","tracking"],author:"Li2",license:"MIT",devDependencies:{"@vitest/coverage-v8":"^4.0.18","happy-dom":"^20.6.1","javascript-obfuscator":"^4.1.0",tsup:"^8.0.0",typescript:"^5.0.0",vitest:"^4.0.18"}};var f=S.version;var d=class{constructor(e){this.buffer=[];this.timer=null;this.started=!1;this.handleBeforeUnload=null;this.handleVisibilityChange=null;this.config=e}start(){this.started||(this.started=!0,this.timer=setInterval(()=>this.flush(),this.config.batchInterval),this.handleBeforeUnload=()=>this.flush(!0),window.addEventListener("beforeunload",this.handleBeforeUnload),this.handleVisibilityChange=()=>{document.visibilityState==="hidden"&&this.flush(!0)},document.addEventListener("visibilitychange",this.handleVisibilityChange))}stop(){this.started&&(this.started=!1,this.flush(!0),this.timer&&(clearInterval(this.timer),this.timer=null),this.handleBeforeUnload&&(window.removeEventListener("beforeunload",this.handleBeforeUnload),this.handleBeforeUnload=null),this.handleVisibilityChange&&(document.removeEventListener("visibilitychange",this.handleVisibilityChange),this.handleVisibilityChange=null))}add(e){this.buffer.push(e),this.buffer.length>=this.config.batchSize&&this.flush()}getBufferSize(){return this.buffer.length}flush(e=!1){if(this.buffer.length===0)return;let t=this.buffer.splice(0,this.config.batchSize),n={interactions:t},s=`${this.config.apiUrl}/api/v1/track/interaction`;if(e&&navigator.sendBeacon){let o={...n,sdk_version:f},r=`${s}?li2_key=${encodeURIComponent(this.config.publishableKey)}`,l=new Blob([JSON.stringify(o)],{type:"application/json"});navigator.sendBeacon(r,l)?this.log(`Beacon sent: ${t.length} interactions`):this.sendViaFetch(s,JSON.stringify(n),t)}else{let o=JSON.stringify(n);this.sendViaFetch(s,o,t)}this.buffer.length>0&&this.flush(e)}sendViaFetch(e,t,n){fetch(e,{method:"POST",headers:{"Content-Type":"application/json","X-Li2-Key":this.config.publishableKey,"X-Li2-SDK-Version":f},body:t,keepalive:!0}).then(s=>{s.ok?this.log(`Sent: ${n.length} interactions`):(this.log(`Send failed: ${s.status}, re-queuing ${n.length} events`),this.buffer.unshift(...n))}).catch(()=>{this.log(`Network error, re-queuing ${n.length} events`),this.buffer.unshift(...n)})}log(...e){this.config.debug&&console.log("[Li2 InteractionBatchSender]",...e)}};function y(i,e,t){if(!e)return!0;let{mode:n,includePaths:s,excludePaths:o}=e;if(n==="include"){if(!(s&&s.length>0))return t&&console.log(`[PathFilter] mode=include but no includePaths, blocking "${i}"`),!1;let p=s.some(I=>E(i,I));return t&&(p?console.log(`[PathFilter] mode=include: "${i}" matched includePath`):console.log(`[PathFilter] mode=include: "${i}" not in includePaths:`,s)),p}return o&&o.length>0?o.some(u=>E(i,u))?(t&&console.log(`[PathFilter] mode=exclude: "${i}" matched excludePath:`,o),!1):(t&&console.log(`[PathFilter] Path "${i}" allowed by rules`),!0):(t&&console.log(`[PathFilter] No excludePaths, path "${i}" allowed`),!0)}function E(i,e){let n=e.replace(/[.+?^${}()|[\]\\]/g,"\\$&").replace(/\*\*|\*/g,s=>s==="**"?".*":"[^/]*");return new RegExp(`^${n}$`).test(i)}var F={batchInterval:5e3,batchSize:50,excludeSelector:null,debug:!1,sessionTimeout:30,cookieLessMode:!1,cookiePath:"/"},V=50,m=class{constructor(e){this.started=!1;this.handleClick=null;this.lastClickTarget=null;this.lastClickTime=0;this.config=e,this.sessionManager=new c({timeout:e.sessionTimeout,cookieLessMode:e.cookieLessMode,cookieDomain:e.cookieDomain,cookiePath:e.cookiePath}),this.batchSender=new d({apiUrl:e.apiUrl,publishableKey:e.publishableKey,batchInterval:e.batchInterval,batchSize:e.batchSize,debug:e.debug})}start(){this.started||(this.started=!0,this.handleClick=e=>this.onDocumentClick(e),document.addEventListener("click",this.handleClick,!0),this.batchSender.start(),this.log("ClickTracker started"))}stop(){this.started&&(this.started=!1,this.handleClick&&(document.removeEventListener("click",this.handleClick,!0),this.handleClick=null),this.batchSender.stop(),this.log("ClickTracker stopped"))}onDocumentClick(e){if(e.button!==0)return;let t=window.location.pathname;if(!y(t,this.config.dataCollectionRules,this.config.debug)){this.log(`Path excluded from tracking: ${t}`);return}let n=Date.now();if(e.target===this.lastClickTarget&&n-this.lastClickTime<V||(this.lastClickTarget=e.target,this.lastClickTime=n,this.shouldExclude(e.target)))return;let s=k(e.target);if(!s)return;let o=x(e,s.isFixed),r={session_id:this.sessionManager.getSessionId(),visitor_id:this.sessionManager.getVisitorId(),li2_cid:this.config.clickId,page_url:window.location.href,page_path:window.location.pathname,x:o.x,y:o.y,target_fixed:s.isFixed,viewport_width:window.innerWidth,viewport_height:window.innerHeight,page_height:o.pageHeight,scroll_y:o.scrollY,element_tag:s.tag,element_text:s.text,element_href:s.href,element_class:s.className,element_id:s.id,selector_path:s.selectorPath,interaction_type:"click",timestamp:n};this.sessionManager.touch(),this.batchSender.add(r)}shouldExclude(e){if(!this.config.excludeSelector||!e)return!1;let t=e;for(;t&&t!==document.body;){try{if(t.matches(this.config.excludeSelector))return!0}catch{return this.log(`Invalid excludeSelector: ${this.config.excludeSelector}`),this.config.excludeSelector=null,!1}t=t.parentElement}return!1}log(...e){this.config.debug&&console.log("[Li2 ClickTracker]",...e)}};0&&(module.exports={ClickTracker,DEFAULT_CLICK_TRACKER_CONFIG});
@@ -1 +1 @@
1
- import{a as l}from"../chunk-LZDMBCUK.mjs";import{a}from"../chunk-FF6VDEL5.mjs";function c(s,e){let i=window.scrollX||document.documentElement.scrollLeft,t=window.scrollY||document.documentElement.scrollTop;return{x:s.clientX+(e?0:i),y:s.clientY+(e?0:t),scrollY:t,pageHeight:document.documentElement.scrollHeight}}var o=class{constructor(e){this.buffer=[];this.timer=null;this.started=!1;this.handleBeforeUnload=null;this.handleVisibilityChange=null;this.config=e}start(){this.started||(this.started=!0,this.timer=setInterval(()=>this.flush(),this.config.batchInterval),this.handleBeforeUnload=()=>this.flush(!0),window.addEventListener("beforeunload",this.handleBeforeUnload),this.handleVisibilityChange=()=>{document.visibilityState==="hidden"&&this.flush(!0)},document.addEventListener("visibilitychange",this.handleVisibilityChange))}stop(){this.started&&(this.started=!1,this.flush(!0),this.timer&&(clearInterval(this.timer),this.timer=null),this.handleBeforeUnload&&(window.removeEventListener("beforeunload",this.handleBeforeUnload),this.handleBeforeUnload=null),this.handleVisibilityChange&&(document.removeEventListener("visibilitychange",this.handleVisibilityChange),this.handleVisibilityChange=null))}add(e){this.buffer.push(e),this.buffer.length>=this.config.batchSize&&this.flush()}getBufferSize(){return this.buffer.length}flush(e=!1){if(this.buffer.length===0)return;let i=this.buffer.splice(0,this.config.batchSize),t={interactions:i},n=`${this.config.apiUrl}/api/v1/track/interaction`,r=JSON.stringify(t);if(e&&navigator.sendBeacon){let d=`${n}?li2_key=${encodeURIComponent(this.config.publishableKey)}`,u=new Blob([r],{type:"application/json"});navigator.sendBeacon(d,u)?this.log(`Beacon sent: ${i.length} interactions`):this.sendViaFetch(n,r,i)}else this.sendViaFetch(n,r,i);this.buffer.length>0&&this.flush(e)}sendViaFetch(e,i,t){fetch(e,{method:"POST",headers:{"Content-Type":"application/json","X-Li2-Key":this.config.publishableKey},body:i,keepalive:!0}).then(n=>{n.ok?this.log(`Sent: ${t.length} interactions`):(this.log(`Send failed: ${n.status}, re-queuing ${t.length} events`),this.buffer.unshift(...t))}).catch(()=>{this.log(`Network error, re-queuing ${t.length} events`),this.buffer.unshift(...t)})}log(...e){this.config.debug&&console.log("[Li2 InteractionBatchSender]",...e)}};var y={batchInterval:5e3,batchSize:50,excludeSelector:null,debug:!1,sessionTimeout:30,cookieLessMode:!1,cookiePath:"/"},g=50,h=class{constructor(e){this.started=!1;this.handleClick=null;this.lastClickTarget=null;this.lastClickTime=0;this.config=e,this.sessionManager=new l({timeout:e.sessionTimeout,cookieLessMode:e.cookieLessMode,cookieDomain:e.cookieDomain,cookiePath:e.cookiePath}),this.batchSender=new o({apiUrl:e.apiUrl,publishableKey:e.publishableKey,batchInterval:e.batchInterval,batchSize:e.batchSize,debug:e.debug})}start(){this.started||(this.started=!0,this.handleClick=e=>this.onDocumentClick(e),document.addEventListener("click",this.handleClick,!0),this.batchSender.start(),this.log("ClickTracker started"))}stop(){this.started&&(this.started=!1,this.handleClick&&(document.removeEventListener("click",this.handleClick,!0),this.handleClick=null),this.batchSender.stop(),this.log("ClickTracker stopped"))}onDocumentClick(e){if(e.button!==0)return;let i=Date.now();if(e.target===this.lastClickTarget&&i-this.lastClickTime<g||(this.lastClickTarget=e.target,this.lastClickTime=i,this.shouldExclude(e.target)))return;let t=a(e.target);if(!t)return;let n=c(e,t.isFixed),r={session_id:this.sessionManager.getSessionId(),visitor_id:this.sessionManager.getVisitorId(),li2_cid:this.config.clickId,page_url:window.location.href,page_path:window.location.pathname,x:n.x,y:n.y,target_fixed:t.isFixed,viewport_width:window.innerWidth,viewport_height:window.innerHeight,page_height:n.pageHeight,scroll_y:n.scrollY,element_tag:t.tag,element_text:t.text,element_href:t.href,element_class:t.className,element_id:t.id,selector_path:t.selectorPath,interaction_type:"click",timestamp:i};this.sessionManager.touch(),this.batchSender.add(r)}shouldExclude(e){if(!this.config.excludeSelector||!e)return!1;let i=e;for(;i&&i!==document.body;){try{if(i.matches(this.config.excludeSelector))return!0}catch{return this.log(`Invalid excludeSelector: ${this.config.excludeSelector}`),this.config.excludeSelector=null,!1}i=i.parentElement}return!1}log(...e){this.config.debug&&console.log("[Li2 ClickTracker]",...e)}};export{h as ClickTracker,y as DEFAULT_CLICK_TRACKER_CONFIG};
1
+ import{a as s}from"../chunk-772JYJV2.mjs";import{a}from"../chunk-FF6VDEL5.mjs";import{a as c}from"../chunk-GS2LGTLM.mjs";import"../chunk-EO7Y3K6L.mjs";import{a as r}from"../chunk-LZDMBCUK.mjs";function h(l,e){let t=window.scrollX||document.documentElement.scrollLeft,o=window.scrollY||document.documentElement.scrollTop;return{x:l.clientX+(e?0:t),y:l.clientY+(e?0:o),scrollY:o,pageHeight:document.documentElement.scrollHeight}}var x={batchInterval:5e3,batchSize:50,excludeSelector:null,debug:!1,sessionTimeout:30,cookieLessMode:!1,cookiePath:"/"},m=50,d=class{constructor(e){this.started=!1;this.handleClick=null;this.lastClickTarget=null;this.lastClickTime=0;this.config=e,this.sessionManager=new r({timeout:e.sessionTimeout,cookieLessMode:e.cookieLessMode,cookieDomain:e.cookieDomain,cookiePath:e.cookiePath}),this.batchSender=new c({apiUrl:e.apiUrl,publishableKey:e.publishableKey,batchInterval:e.batchInterval,batchSize:e.batchSize,debug:e.debug})}start(){this.started||(this.started=!0,this.handleClick=e=>this.onDocumentClick(e),document.addEventListener("click",this.handleClick,!0),this.batchSender.start(),this.log("ClickTracker started"))}stop(){this.started&&(this.started=!1,this.handleClick&&(document.removeEventListener("click",this.handleClick,!0),this.handleClick=null),this.batchSender.stop(),this.log("ClickTracker stopped"))}onDocumentClick(e){if(e.button!==0)return;let t=window.location.pathname;if(!s(t,this.config.dataCollectionRules,this.config.debug)){this.log(`Path excluded from tracking: ${t}`);return}let o=Date.now();if(e.target===this.lastClickTarget&&o-this.lastClickTime<m||(this.lastClickTarget=e.target,this.lastClickTime=o,this.shouldExclude(e.target)))return;let i=a(e.target);if(!i)return;let n=h(e,i.isFixed),u={session_id:this.sessionManager.getSessionId(),visitor_id:this.sessionManager.getVisitorId(),li2_cid:this.config.clickId,page_url:window.location.href,page_path:window.location.pathname,x:n.x,y:n.y,target_fixed:i.isFixed,viewport_width:window.innerWidth,viewport_height:window.innerHeight,page_height:n.pageHeight,scroll_y:n.scrollY,element_tag:i.tag,element_text:i.text,element_href:i.href,element_class:i.className,element_id:i.id,selector_path:i.selectorPath,interaction_type:"click",timestamp:o};this.sessionManager.touch(),this.batchSender.add(u)}shouldExclude(e){if(!this.config.excludeSelector||!e)return!1;let t=e;for(;t&&t!==document.body;){try{if(t.matches(this.config.excludeSelector))return!0}catch{return this.log(`Invalid excludeSelector: ${this.config.excludeSelector}`),this.config.excludeSelector=null,!1}t=t.parentElement}return!1}log(...e){this.config.debug&&console.log("[Li2 ClickTracker]",...e)}};export{d as ClickTracker,x as DEFAULT_CLICK_TRACKER_CONFIG};
@@ -7,13 +7,18 @@ interface PageviewConfig {
7
7
  /** Enable/disable pageview tracking */
8
8
  enabled: boolean;
9
9
  /** SPA detection mode: 'auto' | 'manual' | 'disabled' */
10
- spaMode: 'auto' | 'manual' | 'disabled';
10
+ spaMode: "auto" | "manual" | "disabled";
11
11
  /** Batch send interval in milliseconds (default: 5000) */
12
12
  batchInterval: number;
13
13
  /** Max pageviews per batch (default: 50) */
14
14
  batchSize: number;
15
15
  /** URL patterns to exclude from tracking (glob-like) */
16
16
  excludePatterns: string[];
17
+ /** Path filtering rules from config (takes precedence over excludePatterns) */
18
+ dataCollectionRules?: {
19
+ excludePaths?: string[];
20
+ includePaths?: string[];
21
+ };
17
22
  /** Track hash changes as separate pageviews (default: false) */
18
23
  trackHashChanges: boolean;
19
24
  /** Session timeout in minutes (default: 30) */
@@ -30,6 +35,8 @@ interface PageviewConfig {
30
35
  cookiePath: string;
31
36
  /** Search query URL parameters to detect (default: ['q', 'query', 'search', 's']) */
32
37
  searchParams: string[];
38
+ /** Optional callback fired on every SPA route change (e.g. to reset scroll tracker) */
39
+ onRouteChange?: () => void;
33
40
  }
34
41
  /** A single pageview event to be sent to the server */
35
42
  interface PageviewEvent {
@@ -78,7 +85,7 @@ declare class PageviewTracker {
78
85
  private enabled;
79
86
  private lastPageUrl;
80
87
  private lastPageTimestamp;
81
- constructor(config: Partial<PageviewConfig> & Pick<PageviewConfig, 'apiUrl' | 'publishableKey'>);
88
+ constructor(config: Partial<PageviewConfig> & Pick<PageviewConfig, "apiUrl" | "publishableKey">);
82
89
  /** Start tracking pageviews */
83
90
  start(): void;
84
91
  /** Stop tracking pageviews */
@@ -7,13 +7,18 @@ interface PageviewConfig {
7
7
  /** Enable/disable pageview tracking */
8
8
  enabled: boolean;
9
9
  /** SPA detection mode: 'auto' | 'manual' | 'disabled' */
10
- spaMode: 'auto' | 'manual' | 'disabled';
10
+ spaMode: "auto" | "manual" | "disabled";
11
11
  /** Batch send interval in milliseconds (default: 5000) */
12
12
  batchInterval: number;
13
13
  /** Max pageviews per batch (default: 50) */
14
14
  batchSize: number;
15
15
  /** URL patterns to exclude from tracking (glob-like) */
16
16
  excludePatterns: string[];
17
+ /** Path filtering rules from config (takes precedence over excludePatterns) */
18
+ dataCollectionRules?: {
19
+ excludePaths?: string[];
20
+ includePaths?: string[];
21
+ };
17
22
  /** Track hash changes as separate pageviews (default: false) */
18
23
  trackHashChanges: boolean;
19
24
  /** Session timeout in minutes (default: 30) */
@@ -30,6 +35,8 @@ interface PageviewConfig {
30
35
  cookiePath: string;
31
36
  /** Search query URL parameters to detect (default: ['q', 'query', 'search', 's']) */
32
37
  searchParams: string[];
38
+ /** Optional callback fired on every SPA route change (e.g. to reset scroll tracker) */
39
+ onRouteChange?: () => void;
33
40
  }
34
41
  /** A single pageview event to be sent to the server */
35
42
  interface PageviewEvent {
@@ -78,7 +85,7 @@ declare class PageviewTracker {
78
85
  private enabled;
79
86
  private lastPageUrl;
80
87
  private lastPageTimestamp;
81
- constructor(config: Partial<PageviewConfig> & Pick<PageviewConfig, 'apiUrl' | 'publishableKey'>);
88
+ constructor(config: Partial<PageviewConfig> & Pick<PageviewConfig, "apiUrl" | "publishableKey">);
82
89
  /** Start tracking pageviews */
83
90
  start(): void;
84
91
  /** Stop tracking pageviews */
package/dist/index.d.mts CHANGED
@@ -1,5 +1,5 @@
1
- import { P as PageviewTracker } from './index-B3dzYzIM.mjs';
2
- export { c as PageviewBatchPayload, a as PageviewConfig, b as PageviewEvent } from './index-B3dzYzIM.mjs';
1
+ import { P as PageviewTracker } from './index-BlPDBYpZ.mjs';
2
+ export { c as PageviewBatchPayload, a as PageviewConfig, b as PageviewEvent } from './index-BlPDBYpZ.mjs';
3
3
  export { AnalyticsSettings, AutoEvent, ConditionOperator, ConditionType, EventAction, EventActionType, EventTrigger, TriggerCondition, TriggerType } from './auto-events.mjs';
4
4
  export { ClickTrackerConfig } from './click-tracker/index.mjs';
5
5
  export { E as ElementInfo } from './element-resolver-BnZ_ItHT.mjs';
@@ -46,6 +46,10 @@ interface InteractionEvent {
46
46
  selector_path: string;
47
47
  /** Interaction type (click, scroll, etc.) */
48
48
  interaction_type: string;
49
+ /** Scroll-specific fields (only set when interaction_type = "scroll") */
50
+ scroll_depth_percent?: number;
51
+ scroll_direction?: string;
52
+ time_at_depth?: number;
49
53
  /** Unix timestamp in milliseconds */
50
54
  timestamp: number;
51
55
  }
@@ -212,6 +216,7 @@ declare class Li2Analytics {
212
216
  private cookieOptions;
213
217
  private autoEventTracker;
214
218
  private clickTracker;
219
+ private scrollTracker;
215
220
  pageview: PageviewTracker | null;
216
221
  constructor(config?: Li2Config);
217
222
  private log;
@@ -219,6 +224,10 @@ declare class Li2Analytics {
219
224
  * Initialize auto-event tracking
220
225
  */
221
226
  private initAutoEventTracking;
227
+ /**
228
+ * Get data collection rules from config
229
+ */
230
+ private getDataCollectionRules;
222
231
  /**
223
232
  * Initialize pageview tracking from data-attributes or config.
224
233
  * Uses dynamic import to lazy-load the pageview module only when enabled.
@@ -256,6 +265,23 @@ declare class Li2Analytics {
256
265
  cookieDomain?: string;
257
266
  cookiePath?: string;
258
267
  }): Promise<void>;
268
+ /**
269
+ * Initialize scroll tracking from data-attributes.
270
+ * @internal Called from auto-init block
271
+ */
272
+ initScrollTracking(scrollConfig: Record<string, string>): Promise<void>;
273
+ /**
274
+ * Enable scroll tracking programmatically (for users not using data-attributes)
275
+ */
276
+ enableScrollTracking(options?: {
277
+ milestones?: number[];
278
+ sessionTimeout?: number;
279
+ cookieLessMode?: boolean;
280
+ cookieDomain?: string;
281
+ cookiePath?: string;
282
+ }): Promise<void>;
283
+ /** Reset scroll tracker on SPA navigation (called by PageviewTracker) */
284
+ resetScrollTracker(): void;
259
285
  /**
260
286
  * Manually track a pageview (convenience method)
261
287
  */
package/dist/index.d.ts CHANGED
@@ -1,5 +1,5 @@
1
- import { P as PageviewTracker } from './index-B3dzYzIM.js';
2
- export { c as PageviewBatchPayload, a as PageviewConfig, b as PageviewEvent } from './index-B3dzYzIM.js';
1
+ import { P as PageviewTracker } from './index-BlPDBYpZ.js';
2
+ export { c as PageviewBatchPayload, a as PageviewConfig, b as PageviewEvent } from './index-BlPDBYpZ.js';
3
3
  export { AnalyticsSettings, AutoEvent, ConditionOperator, ConditionType, EventAction, EventActionType, EventTrigger, TriggerCondition, TriggerType } from './auto-events.js';
4
4
  export { ClickTrackerConfig } from './click-tracker/index.js';
5
5
  export { E as ElementInfo } from './element-resolver-BnZ_ItHT.js';
@@ -46,6 +46,10 @@ interface InteractionEvent {
46
46
  selector_path: string;
47
47
  /** Interaction type (click, scroll, etc.) */
48
48
  interaction_type: string;
49
+ /** Scroll-specific fields (only set when interaction_type = "scroll") */
50
+ scroll_depth_percent?: number;
51
+ scroll_direction?: string;
52
+ time_at_depth?: number;
49
53
  /** Unix timestamp in milliseconds */
50
54
  timestamp: number;
51
55
  }
@@ -212,6 +216,7 @@ declare class Li2Analytics {
212
216
  private cookieOptions;
213
217
  private autoEventTracker;
214
218
  private clickTracker;
219
+ private scrollTracker;
215
220
  pageview: PageviewTracker | null;
216
221
  constructor(config?: Li2Config);
217
222
  private log;
@@ -219,6 +224,10 @@ declare class Li2Analytics {
219
224
  * Initialize auto-event tracking
220
225
  */
221
226
  private initAutoEventTracking;
227
+ /**
228
+ * Get data collection rules from config
229
+ */
230
+ private getDataCollectionRules;
222
231
  /**
223
232
  * Initialize pageview tracking from data-attributes or config.
224
233
  * Uses dynamic import to lazy-load the pageview module only when enabled.
@@ -256,6 +265,23 @@ declare class Li2Analytics {
256
265
  cookieDomain?: string;
257
266
  cookiePath?: string;
258
267
  }): Promise<void>;
268
+ /**
269
+ * Initialize scroll tracking from data-attributes.
270
+ * @internal Called from auto-init block
271
+ */
272
+ initScrollTracking(scrollConfig: Record<string, string>): Promise<void>;
273
+ /**
274
+ * Enable scroll tracking programmatically (for users not using data-attributes)
275
+ */
276
+ enableScrollTracking(options?: {
277
+ milestones?: number[];
278
+ sessionTimeout?: number;
279
+ cookieLessMode?: boolean;
280
+ cookieDomain?: string;
281
+ cookiePath?: string;
282
+ }): Promise<void>;
283
+ /** Reset scroll tracker on SPA navigation (called by PageviewTracker) */
284
+ resetScrollTracker(): void;
259
285
  /**
260
286
  * Manually track a pageview (convenience method)
261
287
  */