userpath-js 0.0.10 → 0.0.12

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -607,3 +607,12 @@ And re-enable it later if needed:
607
607
  ```ts
608
608
  up.installErrorHandler();
609
609
  ```
610
+
611
+ ### Geo location for first-party server integration
612
+
613
+ Connect your domain with CloudFlare, and then enable the managed transform for location headers:
614
+
615
+ Rules > Settings > Add visitor location headers
616
+ Adds HTTP request headers with location information for the visitor's IP address, including city, country, continent, longitude, and latitude.
617
+
618
+ UserPath will use this information when saving events.
package/dist/index.js CHANGED
@@ -1 +1 @@
1
- var q={name:"userpath-js",version:"0.0.9",private:!1,main:"dist/index.js",types:"dist/types/client/src/index.d.ts",exports:{".":{types:"./dist/types/client/src/index.d.ts",default:"./dist/index.js"},"./server":{types:"./dist/types/client/src/server/index.d.ts",default:"./dist/server/index.js"}},files:["dist/index.js","dist/types","dist/server"],scripts:{dev:"bun build src/index.ts --outdir ./dist --watch",types:"tsc",build:"bun run build.client && bun run build.pixel && bun run build.server","build.prod":"bun run build.client.prod && bun run build.pixel.prod && bun run build.server.prod","build.client":"bun run types && bun build src/index.ts --outdir ./dist --no-cache","build.client.prod":"bun run types && bun build src/index.ts --outdir ./dist --minify","build.pixel":"bun build src/pixel.ts --outdir ./dist","build.pixel.prod":"bun build src/pixel.ts --outdir ./dist --minify","build.server":"bun run types && bun build src/server/index.ts --outdir ./dist/server","build.server.prod":"bun run types && bun build src/server/index.ts --outdir ./dist/server --minify"},devDependencies:{"bun-types":"latest",typescript:"^5.0.0"}};class z{namespace;constructor({namespace:x}){this.namespace=x}getItem(x){let $=localStorage.getItem(`${this.namespace}.${x}`)||"";try{return JSON.parse($)}catch(R){return null}}setItem(x,$){localStorage.setItem(`${this.namespace}.${x}`,JSON.stringify($))}removeItem(x){localStorage.removeItem(`${this.namespace}.${x}`)}}var F=new z({namespace:"userpath"});function K(x,$,R={}){let{days:J=7,path:j="/",domain:X,secure:Q,sameSite:Z="strict"}=R,_=J?new Date(Date.now()+J*86400000).toUTCString():"",Y=`${encodeURIComponent(x)}=${encodeURIComponent($)}`;if(_)Y+=`; expires=${_}`;if(j)Y+=`; path=${j}`;if(X)Y+=`; domain=${X}`;if(Q)Y+="; secure";if(Z)Y+=`; samesite=${Z}`;document.cookie=Y}function A(x){let $=encodeURIComponent(x)+"=",R=document.cookie.split(";");for(let J=0;J<R.length;J++){let j=R[J];while(j.charAt(0)===" ")j=j.substring(1,j.length);if(j.indexOf($)===0)return decodeURIComponent(j.substring($.length,j.length))}return null}var W={appId:"",serverUrl:"https://api.userpath.co",version:1,flushIntervalMs:5000,secure:!0,autoTrack:{errors:!0,clicks:!0,scrolling:!0,forms:!0,videos:!0,pageVisibility:!0,pageInactivity:!0}};function M(x){let R=new URL(x).hostname,J=R.split(".");return`.${J.length>2?J.slice(-2).join("."):R}`}class B{serverUrl;appId;version;secure;constructor(x){this.secure=typeof x.secure==="boolean"?x.secure:W.secure,this.serverUrl=x.serverUrl||W.serverUrl,this.appId=x.appId,this.version=x.version||W.version,K("_up.app",this.appId,{days:365,sameSite:"lax",secure:this.secure,domain:M(this.serverUrl)})}buildUrl(x){return`${this.serverUrl}/v${this.version}/${x}`}}var E=typeof window==="undefined",L={pushState:()=>{},replaceState:()=>{},go:()=>{},back:()=>{},forward:()=>{}};if(E)global.history=L;var V={location:{href:""},addEventListener:()=>{},removeEventListener:()=>{},scrollTo:()=>{},scrollBy:()=>{},setTimeout:()=>{},clearTimeout:()=>{},setInterval:()=>{},clearInterval:()=>{}};if(E)global.window=V;var D={hidden:!1,addEventListener:()=>{},removeEventListener:()=>{},querySelector:()=>null,closest:()=>null,getAttribute:()=>null,tagName:"",textContent:"",classList:{contains:()=>!1},scrollHeight:0,offsetHeight:0,clientHeight:0,pageYOffset:0,referrer:"",title:""};if(E)global.document=D;class O{#R;#x;#$;#j;#W;#X;#Y;#J;#Z;#_;#P;#L;#V;#D;#g;#K;#y;#z;#q;#M;#A;#B;#w;#E;#b;#Q;#O;#C;#U=60000;#N;#G=!1;#F;#I;#u;constructor(x,$=W){this.#R=x,this.#u=$,this.#x=new Set,this.#$=0,this.#K=null,this.#y=window.location.href,this.#z=new Map,this.#q=new WeakMap,this.#M=new WeakMap,this.#A=Date.now(),this.#B=0,this.#w=this.#A,this.#E=document.hidden,this.#b=Date.now(),this.#Q=null,this.#O=!1,this.#N=null,this.#j=this.handleClick.bind(this),this.#W=this.handleScroll.bind(this),this.#X=this.handleScroll.bind(this),this.#Y=this.handleInputFocus.bind(this),this.#J=this.handleInputBlur.bind(this),this.#Z=this.handleFormChange.bind(this),this.#_=this.handleFormSubmit.bind(this),this.#P=this.handleVideoPlay.bind(this),this.#L=this.handleVideoPause.bind(this),this.#V=this.handleVideoEnd.bind(this),this.#D=this.handleVisibilityChange.bind(this),this.#g=this.handleBeforeUnload.bind(this),this.#C=this.handleUserActivity.bind(this),this.#F=this.handleError.bind(this),this.#I=this.handleRejection.bind(this);let R=this.#u.autoTrack||W.autoTrack;if(R.clicks!==!1)this.setupClickTracking();if(R.scrolling!==!1)this.setupScrollTracking();if(R.forms!==!1)this.setupFormTracking();if(R.videos!==!1)this.setupVideoTracking();if(R.pageVisibility!==!1)this.setupPageTimeTracking();if(R.pageInactivity!==!1)this.setupInactivityTracking()}destroy(){if(document.removeEventListener("click",this.#j),window.removeEventListener("scroll",this.#W),window.removeEventListener("resize",this.#X),document.removeEventListener("focus",this.#Y,!0),document.removeEventListener("blur",this.#J,!0),document.removeEventListener("change",this.#Z,!0),document.removeEventListener("submit",this.#_,!0),document.removeEventListener("play",this.#P,!0),document.removeEventListener("pause",this.#L,!0),document.removeEventListener("ended",this.#V,!0),document.removeEventListener("visibilitychange",this.#D),window.removeEventListener("beforeunload",this.#g),this.#K)window.clearTimeout(this.#K);if(["mousemove","mousedown","keydown","touchstart","scroll"].forEach((x)=>{document.removeEventListener(x,this.#C,!0)}),this.#Q)window.clearTimeout(this.#Q);this.uninstallErrorHandler()}setupClickTracking(){document.addEventListener("click",this.#j)}handleClick(x){let $=x.target;if(!$)return;let R=this.extractClickLabel($);if(!R)return;this.trackCustomEvent("click",{label:R,element:$.tagName.toLowerCase(),id:$.id||void 0})}handleScroll(){let x=window.location.href;if(x!==this.#y)this.#y=x,this.#$=0,this.#x.clear();if(this.#K)window.clearTimeout(this.#K);this.#K=window.setTimeout(()=>{let $=this.calculateScrollDepth();if($>this.#$)this.#$=$,this.checkAndTrackScrollDepth($)},100)}setupScrollTracking(){window.addEventListener("scroll",this.#W),window.addEventListener("resize",this.#X)}calculateScrollDepth(){let x=window.innerHeight,$=Math.max(document.documentElement.scrollHeight,document.documentElement.offsetHeight,document.documentElement.clientHeight),R=window.pageYOffset||document.documentElement.scrollTop;return Math.round((R+x)/$*100)}checkAndTrackScrollDepth(x){let $=window.location.href;if(x>50&&!this.#x.has($))this.#x.add($),this.trackCustomEvent("scroll")}extractClickLabel(x){let $=x.getAttribute("aria-label");if($)return`${$}`;if(x instanceof HTMLButtonElement||x instanceof HTMLAnchorElement){let J=x.textContent?.trim();if(J)return`${J}`}if(x instanceof HTMLInputElement){if(x.type==="submit"&&x.value)return`${x.value}`;if(x.type==="checkbox"){let J=this.findInputLabel(x),j=x.checked?"Checked":"Unchecked";return J?`${j} ${J}`:null}}let R=x.closest("label");if(R){let J=R.textContent?.trim();if(J)return`${J}`}return null}findInputLabel(x){let $=x.getAttribute("aria-label");if($)return $;if(x.id){let J=document.querySelector(`label[for="${x.id}"]`);if(J&&J.textContent)return J.textContent.trim()}let R=x.closest("label");if(R&&R.textContent)return R.textContent.trim().replace(x.value,"").trim();return null}trackPageView(){let x={name:"page_view",url:window.location.href,referrer:document.referrer,title:document.title,timestamp:new Date().toISOString()};this.#R.track(x)}trackCustomEvent(x,$={},R={immediate:!1}){let J={name:x,url:window.location.href,referrer:document.referrer,title:document.title,properties:$,timestamp:new Date().toISOString()};if(R.immediate)this.#R.publish([J]);else this.#R.track(J)}trackPurchase(x){let $={name:"purchase",url:window.location.href,referrer:document.referrer,title:document.title,productId:x.productId,price:x.price,currency:x.currency,properties:{...x.properties},timestamp:new Date().toISOString()};this.#R.track($)}setupFormTracking(){document.addEventListener("focus",this.#Y,!0),document.addEventListener("blur",this.#J,!0),document.addEventListener("change",this.#Z,!0),document.addEventListener("submit",this.#_,!0)}handleInputFocus(x){let $=x.target;if(!$||!($ instanceof HTMLInputElement||$ instanceof HTMLTextAreaElement||$ instanceof HTMLSelectElement))return;if($ instanceof HTMLInputElement&&$.type==="password")return;this.#q.set($,this.getElementValue($));let R=$.closest("form");if(R&&!this.#z.has(R))this.#z.set(R,Date.now())}getElementValue(x){if(x instanceof HTMLSelectElement)return x.value;if(x instanceof HTMLInputElement||x instanceof HTMLTextAreaElement)return x.value;return""}handleInputBlur(x){let $=x.target;if(!$||!($ instanceof HTMLInputElement||$ instanceof HTMLTextAreaElement||$ instanceof HTMLSelectElement))return;if($ instanceof HTMLInputElement&&$.type==="password")return;let R=this.#q.get($)||"",J=this.getElementValue($);if(J!==R&&J.trim()!==""){let j=$ instanceof HTMLSelectElement?"select":$.type,X=this.findFormElementLabel($)||this.getInputIdentifier($);if(!X)return;this.trackCustomEvent("input_fill",{input_type:j,label:X,form_name:this.getFormName($)})}this.#q.delete($)}getFormName(x){let $=x.closest("form");if(!$)return;return $.getAttribute("name")||$.getAttribute("id")||$.getAttribute("aria-label")||void 0}getInputIdentifier(x){return x.getAttribute("name")||x.getAttribute("id")||x.getAttribute("placeholder")||null}findFormElementLabel(x){let $=x.getAttribute("aria-label");if($)return $;if(x.id){let J=document.querySelector(`label[for="${x.id}"]`);if(J&&J.textContent)return J.textContent.trim()}let R=x.closest("label");if(R&&R.textContent){let J=R.textContent.trim(),j=x instanceof HTMLSelectElement?x.selectedOptions[0]?.text:x.value;return j?J.replace(j,"").trim():J}return null}handleFormChange(x){let $=x.target;if(!$||!($ instanceof HTMLSelectElement||$ instanceof HTMLInputElement))return;if($ instanceof HTMLSelectElement)this.trackSelectChange($);else if($ instanceof HTMLInputElement){if($.type==="radio")this.trackRadioChange($);else if($.type==="checkbox")this.trackCheckboxChange($);else if($.type==="range")this.trackRangeChange($)}}trackSelectChange(x){let $=this.findFormElementLabel(x)||this.getInputIdentifier(x);if(!$)return;let R=x.selectedOptions[0];this.trackCustomEvent("input_select",{input_type:"select",label:$,option_label:R?.text||"",form_name:this.getFormName(x)})}trackRadioChange(x){let $=this.findFormElementLabel(x)||this.getInputIdentifier(x);if(!$)return;let R=x.name||$;this.trackCustomEvent("input_radio",{input_type:"radio",group:R,label:$,form_name:this.getFormName(x)})}trackCheckboxChange(x){let $=this.findFormElementLabel(x)||this.getInputIdentifier(x);if(!$)return;this.trackCustomEvent("input_checkbox",{input_type:"checkbox",label:$,checked:x.checked,form_name:this.getFormName(x)})}trackRangeChange(x){let $=this.findFormElementLabel(x)||this.getInputIdentifier(x);if(!$)return;this.trackCustomEvent("input_range",{input_type:"range",label:$,form_name:this.getFormName(x)})}handleFormSubmit(x){let $=x.target;if(!$||!($ instanceof HTMLFormElement))return;let R=this.#z.get($)||Date.now(),J=Date.now()-R,j=this.getFormName($)||"unknown";this.trackCustomEvent("form_submit",{form_name:j,time_to_complete:J}),this.#z.delete($)}setupVideoTracking(){document.addEventListener("play",this.#P,!0),document.addEventListener("pause",this.#L,!0),document.addEventListener("ended",this.#V,!0)}getVideoMetadata(x){return{duration:Math.round(x.duration),current_time:Math.round(x.currentTime),src:x.currentSrc||x.src||void 0,title:x.title||void 0,video_id:x.id||void 0}}handleVideoPlay(x){let $=x.target;if(!$||!($ instanceof HTMLVideoElement))return;this.#M.set($,Date.now()),this.trackCustomEvent("video_play",this.getVideoMetadata($))}handleVideoPause(x){let $=x.target;if(!$||!($ instanceof HTMLVideoElement))return;let R=this.#M.get($),J=this.getVideoMetadata($);if(R)J.watch_time=Math.round((Date.now()-R)/1000),this.#M.delete($);this.trackCustomEvent("video_pause",J)}handleVideoEnd(x){let $=x.target;if(!$||!($ instanceof HTMLVideoElement))return;let R=this.#M.get($),J=this.getVideoMetadata($);if(R)J.watch_time=Math.round((Date.now()-R)/1000),this.#M.delete($);this.trackCustomEvent("video_complete",J)}setupPageTimeTracking(){document.addEventListener("visibilitychange",this.#D),window.addEventListener("beforeunload",this.#g)}handleVisibilityChange(){let x=Date.now(),$=this.#E;if(this.#E=!document.hidden,$)this.#B+=x-this.#w;this.#w=x,this.trackCustomEvent("page_visibility",{visible:this.#E,total_time:Math.round((x-this.#A)/1000),visible_time:Math.round(this.#B/1000)})}handleBeforeUnload(){let x=Date.now();if(this.#E)this.#B+=x-this.#w;this.trackCustomEvent("page_exit",{total_time:Math.round((x-this.#A)/1000),visible_time:Math.round(this.#B/1000)},{immediate:!0})}setupInactivityTracking(){["mousemove","mousedown","keydown","touchstart","scroll"].forEach((x)=>{document.addEventListener(x,this.#C,!0)}),this.checkInactivity()}handleUserActivity(){if(this.#b=Date.now(),this.#O&&this.#N)this.#O=!1,this.trackCustomEvent("user_active",{inactive_duration:Math.round((Date.now()-this.#N)/1000),url:window.location.href,title:document.title}),this.#N=null;this.checkInactivity()}checkInactivity(){if(this.#Q)window.clearTimeout(this.#Q);this.#Q=window.setTimeout(()=>{let x=Date.now();if(x-this.#b>=this.#U&&!this.#O)this.#O=!0,this.#N=x,this.trackCustomEvent("user_inactive")},this.#U)}installErrorHandler(){if(this.#G||typeof window==="undefined")return;window.addEventListener("error",this.#F),window.addEventListener("unhandledrejection",this.#I),this.#G=!0}uninstallErrorHandler(){if(!this.#G||typeof window==="undefined")return;window.removeEventListener("error",this.#F),window.removeEventListener("unhandledrejection",this.#I),this.#G=!1}isErrorHandlerInstalled(){return this.#G}handleError(x){if(x instanceof ErrorEvent)this.trackError(new Error(x.message),{filename:x.filename,lineno:x.lineno,colno:x.colno,source:"window.onerror"})}handleRejection(x){let $=x.reason instanceof Error?x.reason:new Error(String(x.reason||"Unhandled Promise rejection"));this.trackError($,{source:"unhandledrejection"})}trackError(x,$={},R={immediate:!1}){let{filename:J,lineno:j,colno:X,source:Q,url:Z,referrer:_,userAgent:Y,...w}=$,G={name:"error",message:x.message,stack:x.stack,source:Q||"client",lineno:j,colno:X,filename:J,properties:w,timestamp:new Date().toISOString(),url:Z||window.location.href,referrer:_||document.referrer,title:document.title};if(R.immediate)this.#R.publish([G]);else this.#R.track(G)}}class N{#R;#x=[];#$=null;#j;#W;#X="";#Y=null;#J=null;#Z=5000;#_=!0;constructor(x,$){this.#R=x,this.#j=$?.userId,this.#W=$?.appId||"",this.#_=typeof $?.secure==="boolean"?$.secure:W.secure,this.#Z=$?.flushIntervalMs||W.flushIntervalMs||5000}init(x){this.#$=x,this.setup()}destroy(){if(this.#Y)window.clearInterval(this.#Y);if(this.#J)window.clearTimeout(this.#J);if(this.#x.length>0)this.flush()}setup(){if(typeof window==="undefined")return;this.getSessionId(),this.#X=window.location.href,this.#$.trackPageView(),this.setupHistoryChange(),this.#Y=window.setInterval(()=>this.flush(),this.#Z)}setupHistoryChange(){if(!this.#$)return;let{pushState:x,replaceState:$}=history;history.pushState=(...R)=>{x.apply(history,R),this.trackPageViewIfUrlChanged()},history.replaceState=(...R)=>{$.apply(history,R),this.trackPageViewIfUrlChanged()},window.addEventListener("popstate",()=>{this.trackPageViewIfUrlChanged()})}trackPageViewIfUrlChanged(){let x=window.location.href;if(x!==this.#X)this.#X=x,this.#$.trackPageView()}getUserId(){return this.#j}setUserId(x){this.#j=x}getAppId(){return this.#W}setAppId(x){this.#W=x}track(x){if(this.#x.push(x),this.#x.length>=20){this.flush();return}if(!this.#J)this.#J=window.setTimeout(()=>{this.flush(),this.#J=null},this.#Z)}async identify(x){this.setUserId(x.id),await fetch(this.#R.buildUrl("identify"),{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(x),keepalive:!0,credentials:"include"})}deduplicateEvents(x){let $=new Set;return x.filter((R)=>{let J=`${R.name}-${R.timestamp}`;if($.has(J))return!1;return $.add(J),!0})}flush(){if(this.#x.length===0)return;if(this.#J)window.clearTimeout(this.#J),this.#J=null;let x=[...this.#x];this.#x=[];let $=this.deduplicateEvents(x);this.publish($).catch((R)=>{this.#x=[...$,...this.#x].slice(0,100),console.error("Error sending analytics data:",R)})}async publish(x){return fetch(this.#R.buildUrl("log"),{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({userAgent:navigator.userAgent,screenWidth:window.screen.width,screenHeight:window.screen.height,language:navigator.language,timezone:Intl.DateTimeFormat().resolvedOptions().timeZone,events:x.map(($)=>{if(!$.timestamp)$.timestamp=new Date().toISOString();return{...$,name:$.name||$.type,properties:$.properties||{}}})}),credentials:"include",keepalive:!0})}getSessionId(){let x=A("_up.sid");if(!x)x=this.generateId(),K("_up.sid",x,{days:365,sameSite:"lax",secure:this.#_,domain:M(this.#R.serverUrl)});return x}generateId(){return"xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g,function(x){let $=Math.random()*16|0;return(x==="x"?$:$&3|8).toString(16)})}}class g{#R;#x;#$;#j=W.version;constructor(x){if(this.#R=new B(x),this.#x=new N(this.#R,x),this.#$=new O(this.#x,x),this.#j=x.version||this.#j,this.#x.init(this.#$),this.#x.setAppId(x.appId),x.autoTrack?.errors!==void 0?x.autoTrack.errors:!0)this.installErrorHandler();console.debug(`UserPath v${q.version} initialized`)}getAppId(){return this.#x.getAppId()}setAppId(x){this.#x.setAppId(x)}installErrorHandler(){this.#$.installErrorHandler()}uninstallErrorHandler(){this.#$.uninstallErrorHandler()}trackError(x,$={}){if(!this.#$.isErrorHandlerInstalled()&&$.source!=="manual")return;this.#$.trackError(x,$)}setUserId(x){this.#x.setUserId(x)}getUserId(){return this.#x.getUserId()}async identify(x){await this.#x.identify(x)}track(x,$){if(x==="page_view")this.#$.trackPageView();else if(x==="event")this.#$.trackCustomEvent($.name,$.properties||{});else if(x==="purchase")this.#$.trackPurchase({productId:$.properties?.product_id||"",price:$.price,currency:$.currency,properties:$.properties})}}export{g as UserPath,W as DEFAULT_CONFIG};
1
+ var q={name:"userpath-js",version:"0.0.11",private:!1,main:"dist/index.js",types:"dist/types/client/src/index.d.ts",exports:{".":{types:"./dist/types/client/src/index.d.ts",default:"./dist/index.js"},"./server":{types:"./dist/types/client/src/server/index.d.ts",default:"./dist/server/index.js"}},files:["dist/index.js","dist/types","dist/server"],scripts:{dev:"bun build src/index.ts --outdir ./dist --watch",types:"tsc",build:"bun run build.client && bun run build.pixel && bun run build.server","build.prod":"bun run build.client.prod && bun run build.pixel.prod && bun run build.server.prod","build.client":"bun run types && bun build src/index.ts --outdir ./dist --no-cache","build.client.prod":"bun run types && bun build src/index.ts --outdir ./dist --minify","build.pixel":"bun build src/pixel.ts --outdir ./dist","build.pixel.prod":"bun build src/pixel.ts --outdir ./dist --minify","build.server":"bun run types && bun build src/server/index.ts --outdir ./dist/server","build.server.prod":"bun run types && bun build src/server/index.ts --outdir ./dist/server --minify"},devDependencies:{"bun-types":"latest",typescript:"^5.0.0"},dependencies:{"iconv-lite":"^0.6.3"}};class z{namespace;constructor({namespace:x}){this.namespace=x}getItem(x){let $=localStorage.getItem(`${this.namespace}.${x}`)||"";try{return JSON.parse($)}catch(R){return null}}setItem(x,$){localStorage.setItem(`${this.namespace}.${x}`,JSON.stringify($))}removeItem(x){localStorage.removeItem(`${this.namespace}.${x}`)}}var F=new z({namespace:"userpath"});function K(x,$,R={}){let{days:J=7,path:j="/",domain:X,secure:Q,sameSite:Z="strict"}=R,_=J?new Date(Date.now()+J*86400000).toUTCString():"",Y=`${encodeURIComponent(x)}=${encodeURIComponent($)}`;if(_)Y+=`; expires=${_}`;if(j)Y+=`; path=${j}`;if(X)Y+=`; domain=${X}`;if(Q)Y+="; secure";if(Z)Y+=`; samesite=${Z}`;document.cookie=Y}function A(x){let $=encodeURIComponent(x)+"=",R=document.cookie.split(";");for(let J=0;J<R.length;J++){let j=R[J];while(j.charAt(0)===" ")j=j.substring(1,j.length);if(j.indexOf($)===0)return decodeURIComponent(j.substring($.length,j.length))}return null}var W={appId:"",serverUrl:"https://api.userpath.co",version:1,flushIntervalMs:5000,secure:!0,autoTrack:{errors:!0,clicks:!0,scrolling:!0,forms:!0,videos:!0,pageVisibility:!0,pageInactivity:!0}};function M(x){let R=new URL(x).hostname,J=R.split(".");return`.${J.length>2?J.slice(-2).join("."):R}`}class B{serverUrl;appId;version;secure;constructor(x){this.secure=typeof x.secure==="boolean"?x.secure:W.secure,this.serverUrl=x.serverUrl||W.serverUrl,this.appId=x.appId,this.version=x.version||W.version,K("_up.app",this.appId,{days:365,sameSite:"lax",secure:this.secure,domain:M(this.serverUrl)})}buildUrl(x){return`${this.serverUrl}/v${this.version}/${x}`}}var E=typeof window==="undefined",L={pushState:()=>{},replaceState:()=>{},go:()=>{},back:()=>{},forward:()=>{}};if(E)global.history=L;var V={location:{href:""},addEventListener:()=>{},removeEventListener:()=>{},scrollTo:()=>{},scrollBy:()=>{},setTimeout:()=>{},clearTimeout:()=>{},setInterval:()=>{},clearInterval:()=>{}};if(E)global.window=V;var D={hidden:!1,addEventListener:()=>{},removeEventListener:()=>{},querySelector:()=>null,closest:()=>null,getAttribute:()=>null,tagName:"",textContent:"",classList:{contains:()=>!1},scrollHeight:0,offsetHeight:0,clientHeight:0,pageYOffset:0,referrer:"",title:""};if(E)global.document=D;class O{#R;#x;#$;#j;#W;#X;#Y;#J;#Z;#_;#P;#L;#V;#D;#g;#K;#y;#z;#q;#M;#A;#B;#w;#E;#b;#Q;#O;#C;#U=60000;#N;#G=!1;#F;#I;#u;constructor(x,$=W){this.#R=x,this.#u=$,this.#x=new Set,this.#$=0,this.#K=null,this.#y=window.location.href,this.#z=new Map,this.#q=new WeakMap,this.#M=new WeakMap,this.#A=Date.now(),this.#B=0,this.#w=this.#A,this.#E=document.hidden,this.#b=Date.now(),this.#Q=null,this.#O=!1,this.#N=null,this.#j=this.handleClick.bind(this),this.#W=this.handleScroll.bind(this),this.#X=this.handleScroll.bind(this),this.#Y=this.handleInputFocus.bind(this),this.#J=this.handleInputBlur.bind(this),this.#Z=this.handleFormChange.bind(this),this.#_=this.handleFormSubmit.bind(this),this.#P=this.handleVideoPlay.bind(this),this.#L=this.handleVideoPause.bind(this),this.#V=this.handleVideoEnd.bind(this),this.#D=this.handleVisibilityChange.bind(this),this.#g=this.handleBeforeUnload.bind(this),this.#C=this.handleUserActivity.bind(this),this.#F=this.handleError.bind(this),this.#I=this.handleRejection.bind(this);let R=this.#u.autoTrack||W.autoTrack;if(R.clicks!==!1)this.setupClickTracking();if(R.scrolling!==!1)this.setupScrollTracking();if(R.forms!==!1)this.setupFormTracking();if(R.videos!==!1)this.setupVideoTracking();if(R.pageVisibility!==!1)this.setupPageTimeTracking();if(R.pageInactivity!==!1)this.setupInactivityTracking()}destroy(){if(document.removeEventListener("click",this.#j),window.removeEventListener("scroll",this.#W),window.removeEventListener("resize",this.#X),document.removeEventListener("focus",this.#Y,!0),document.removeEventListener("blur",this.#J,!0),document.removeEventListener("change",this.#Z,!0),document.removeEventListener("submit",this.#_,!0),document.removeEventListener("play",this.#P,!0),document.removeEventListener("pause",this.#L,!0),document.removeEventListener("ended",this.#V,!0),document.removeEventListener("visibilitychange",this.#D),window.removeEventListener("beforeunload",this.#g),this.#K)window.clearTimeout(this.#K);if(["mousemove","mousedown","keydown","touchstart","scroll"].forEach((x)=>{document.removeEventListener(x,this.#C,!0)}),this.#Q)window.clearTimeout(this.#Q);this.uninstallErrorHandler()}setupClickTracking(){document.addEventListener("click",this.#j)}handleClick(x){let $=x.target;if(!$)return;let R=this.extractClickLabel($);if(!R)return;this.trackCustomEvent("click",{label:R,element:$.tagName.toLowerCase(),id:$.id||void 0})}handleScroll(){let x=window.location.href;if(x!==this.#y)this.#y=x,this.#$=0,this.#x.clear();if(this.#K)window.clearTimeout(this.#K);this.#K=window.setTimeout(()=>{let $=this.calculateScrollDepth();if($>this.#$)this.#$=$,this.checkAndTrackScrollDepth($)},100)}setupScrollTracking(){window.addEventListener("scroll",this.#W),window.addEventListener("resize",this.#X)}calculateScrollDepth(){let x=window.innerHeight,$=Math.max(document.documentElement.scrollHeight,document.documentElement.offsetHeight,document.documentElement.clientHeight),R=window.pageYOffset||document.documentElement.scrollTop;return Math.round((R+x)/$*100)}checkAndTrackScrollDepth(x){let $=window.location.href;if(x>50&&!this.#x.has($))this.#x.add($),this.trackCustomEvent("scroll")}extractClickLabel(x){let $=x.getAttribute("aria-label");if($)return`${$}`;if(x instanceof HTMLButtonElement||x instanceof HTMLAnchorElement){let J=x.textContent?.trim();if(J)return`${J}`}if(x instanceof HTMLInputElement){if(x.type==="submit"&&x.value)return`${x.value}`;if(x.type==="checkbox"){let J=this.findInputLabel(x),j=x.checked?"Checked":"Unchecked";return J?`${j} ${J}`:null}}let R=x.closest("label");if(R){let J=R.textContent?.trim();if(J)return`${J}`}return null}findInputLabel(x){let $=x.getAttribute("aria-label");if($)return $;if(x.id){let J=document.querySelector(`label[for="${x.id}"]`);if(J&&J.textContent)return J.textContent.trim()}let R=x.closest("label");if(R&&R.textContent)return R.textContent.trim().replace(x.value,"").trim();return null}trackPageView(){let x={name:"page_view",url:window.location.href,referrer:document.referrer,title:document.title,timestamp:new Date().toISOString()};this.#R.track(x)}trackCustomEvent(x,$={},R={immediate:!1}){let J={name:x,url:window.location.href,referrer:document.referrer,title:document.title,properties:$,timestamp:new Date().toISOString()};if(R.immediate)this.#R.publish([J]);else this.#R.track(J)}trackPurchase(x){let $={name:"purchase",url:window.location.href,referrer:document.referrer,title:document.title,productId:x.productId,price:x.price,currency:x.currency,properties:{...x.properties},timestamp:new Date().toISOString()};this.#R.track($)}setupFormTracking(){document.addEventListener("focus",this.#Y,!0),document.addEventListener("blur",this.#J,!0),document.addEventListener("change",this.#Z,!0),document.addEventListener("submit",this.#_,!0)}handleInputFocus(x){let $=x.target;if(!$||!($ instanceof HTMLInputElement||$ instanceof HTMLTextAreaElement||$ instanceof HTMLSelectElement))return;if($ instanceof HTMLInputElement&&$.type==="password")return;this.#q.set($,this.getElementValue($));let R=$.closest("form");if(R&&!this.#z.has(R))this.#z.set(R,Date.now())}getElementValue(x){if(x instanceof HTMLSelectElement)return x.value;if(x instanceof HTMLInputElement||x instanceof HTMLTextAreaElement)return x.value;return""}handleInputBlur(x){let $=x.target;if(!$||!($ instanceof HTMLInputElement||$ instanceof HTMLTextAreaElement||$ instanceof HTMLSelectElement))return;if($ instanceof HTMLInputElement&&$.type==="password")return;let R=this.#q.get($)||"",J=this.getElementValue($);if(J!==R&&J.trim()!==""){let j=$ instanceof HTMLSelectElement?"select":$.type,X=this.findFormElementLabel($)||this.getInputIdentifier($);if(!X)return;this.trackCustomEvent("input_fill",{input_type:j,label:X,form_name:this.getFormName($)})}this.#q.delete($)}getFormName(x){let $=x.closest("form");if(!$)return;return $.getAttribute("name")||$.getAttribute("id")||$.getAttribute("aria-label")||void 0}getInputIdentifier(x){return x.getAttribute("name")||x.getAttribute("id")||x.getAttribute("placeholder")||null}findFormElementLabel(x){let $=x.getAttribute("aria-label");if($)return $;if(x.id){let J=document.querySelector(`label[for="${x.id}"]`);if(J&&J.textContent)return J.textContent.trim()}let R=x.closest("label");if(R&&R.textContent){let J=R.textContent.trim(),j=x instanceof HTMLSelectElement?x.selectedOptions[0]?.text:x.value;return j?J.replace(j,"").trim():J}return null}handleFormChange(x){let $=x.target;if(!$||!($ instanceof HTMLSelectElement||$ instanceof HTMLInputElement))return;if($ instanceof HTMLSelectElement)this.trackSelectChange($);else if($ instanceof HTMLInputElement){if($.type==="radio")this.trackRadioChange($);else if($.type==="checkbox")this.trackCheckboxChange($);else if($.type==="range")this.trackRangeChange($)}}trackSelectChange(x){let $=this.findFormElementLabel(x)||this.getInputIdentifier(x);if(!$)return;let R=x.selectedOptions[0];this.trackCustomEvent("input_select",{input_type:"select",label:$,option_label:R?.text||"",form_name:this.getFormName(x)})}trackRadioChange(x){let $=this.findFormElementLabel(x)||this.getInputIdentifier(x);if(!$)return;let R=x.name||$;this.trackCustomEvent("input_radio",{input_type:"radio",group:R,label:$,form_name:this.getFormName(x)})}trackCheckboxChange(x){let $=this.findFormElementLabel(x)||this.getInputIdentifier(x);if(!$)return;this.trackCustomEvent("input_checkbox",{input_type:"checkbox",label:$,checked:x.checked,form_name:this.getFormName(x)})}trackRangeChange(x){let $=this.findFormElementLabel(x)||this.getInputIdentifier(x);if(!$)return;this.trackCustomEvent("input_range",{input_type:"range",label:$,form_name:this.getFormName(x)})}handleFormSubmit(x){let $=x.target;if(!$||!($ instanceof HTMLFormElement))return;let R=this.#z.get($)||Date.now(),J=Date.now()-R,j=this.getFormName($)||"unknown";this.trackCustomEvent("form_submit",{form_name:j,time_to_complete:J}),this.#z.delete($)}setupVideoTracking(){document.addEventListener("play",this.#P,!0),document.addEventListener("pause",this.#L,!0),document.addEventListener("ended",this.#V,!0)}getVideoMetadata(x){return{duration:Math.round(x.duration),current_time:Math.round(x.currentTime),src:x.currentSrc||x.src||void 0,title:x.title||void 0,video_id:x.id||void 0}}handleVideoPlay(x){let $=x.target;if(!$||!($ instanceof HTMLVideoElement))return;this.#M.set($,Date.now()),this.trackCustomEvent("video_play",this.getVideoMetadata($))}handleVideoPause(x){let $=x.target;if(!$||!($ instanceof HTMLVideoElement))return;let R=this.#M.get($),J=this.getVideoMetadata($);if(R)J.watch_time=Math.round((Date.now()-R)/1000),this.#M.delete($);this.trackCustomEvent("video_pause",J)}handleVideoEnd(x){let $=x.target;if(!$||!($ instanceof HTMLVideoElement))return;let R=this.#M.get($),J=this.getVideoMetadata($);if(R)J.watch_time=Math.round((Date.now()-R)/1000),this.#M.delete($);this.trackCustomEvent("video_complete",J)}setupPageTimeTracking(){document.addEventListener("visibilitychange",this.#D),window.addEventListener("beforeunload",this.#g)}handleVisibilityChange(){let x=Date.now(),$=this.#E;if(this.#E=!document.hidden,$)this.#B+=x-this.#w;this.#w=x,this.trackCustomEvent("page_visibility",{visible:this.#E,total_time:Math.round((x-this.#A)/1000),visible_time:Math.round(this.#B/1000)})}handleBeforeUnload(){let x=Date.now();if(this.#E)this.#B+=x-this.#w;this.trackCustomEvent("page_exit",{total_time:Math.round((x-this.#A)/1000),visible_time:Math.round(this.#B/1000)},{immediate:!0})}setupInactivityTracking(){["mousemove","mousedown","keydown","touchstart","scroll"].forEach((x)=>{document.addEventListener(x,this.#C,!0)}),this.checkInactivity()}handleUserActivity(){if(this.#b=Date.now(),this.#O&&this.#N)this.#O=!1,this.trackCustomEvent("user_active",{inactive_duration:Math.round((Date.now()-this.#N)/1000),url:window.location.href,title:document.title}),this.#N=null;this.checkInactivity()}checkInactivity(){if(this.#Q)window.clearTimeout(this.#Q);this.#Q=window.setTimeout(()=>{let x=Date.now();if(x-this.#b>=this.#U&&!this.#O)this.#O=!0,this.#N=x,this.trackCustomEvent("user_inactive")},this.#U)}installErrorHandler(){if(this.#G||typeof window==="undefined")return;window.addEventListener("error",this.#F),window.addEventListener("unhandledrejection",this.#I),this.#G=!0}uninstallErrorHandler(){if(!this.#G||typeof window==="undefined")return;window.removeEventListener("error",this.#F),window.removeEventListener("unhandledrejection",this.#I),this.#G=!1}isErrorHandlerInstalled(){return this.#G}handleError(x){if(x instanceof ErrorEvent)this.trackError(new Error(x.message),{filename:x.filename,lineno:x.lineno,colno:x.colno,source:"window.onerror"})}handleRejection(x){let $=x.reason instanceof Error?x.reason:new Error(String(x.reason||"Unhandled Promise rejection"));this.trackError($,{source:"unhandledrejection"})}trackError(x,$={},R={immediate:!1}){let{filename:J,lineno:j,colno:X,source:Q,url:Z,referrer:_,userAgent:Y,...w}=$,G={name:"error",message:x.message,stack:x.stack,source:Q||"client",lineno:j,colno:X,filename:J,properties:w,timestamp:new Date().toISOString(),url:Z||window.location.href,referrer:_||document.referrer,title:document.title};if(R.immediate)this.#R.publish([G]);else this.#R.track(G)}}class N{#R;#x=[];#$=null;#j;#W;#X="";#Y=null;#J=null;#Z=5000;#_=!0;constructor(x,$){this.#R=x,this.#j=$?.userId,this.#W=$?.appId||"",this.#_=typeof $?.secure==="boolean"?$.secure:W.secure,this.#Z=$?.flushIntervalMs||W.flushIntervalMs||5000}init(x){this.#$=x,this.setup()}destroy(){if(this.#Y)window.clearInterval(this.#Y);if(this.#J)window.clearTimeout(this.#J);if(this.#x.length>0)this.flush()}setup(){if(typeof window==="undefined")return;this.getSessionId(),this.#X=window.location.href,this.#$.trackPageView(),this.setupHistoryChange(),this.#Y=window.setInterval(()=>this.flush(),this.#Z)}setupHistoryChange(){if(!this.#$)return;let{pushState:x,replaceState:$}=history;history.pushState=(...R)=>{x.apply(history,R),this.trackPageViewIfUrlChanged()},history.replaceState=(...R)=>{$.apply(history,R),this.trackPageViewIfUrlChanged()},window.addEventListener("popstate",()=>{this.trackPageViewIfUrlChanged()})}trackPageViewIfUrlChanged(){let x=window.location.href;if(x!==this.#X)this.#X=x,this.#$.trackPageView()}getUserId(){return this.#j}setUserId(x){this.#j=x}getAppId(){return this.#W}setAppId(x){this.#W=x}track(x){if(this.#x.push(x),this.#x.length>=20){this.flush();return}if(!this.#J)this.#J=window.setTimeout(()=>{this.flush(),this.#J=null},this.#Z)}async identify(x){this.setUserId(x.id),await fetch(this.#R.buildUrl("identify"),{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(x),keepalive:!0,credentials:"include"})}deduplicateEvents(x){let $=new Set;return x.filter((R)=>{let J=`${R.name}-${R.timestamp}`;if($.has(J))return!1;return $.add(J),!0})}flush(){if(this.#x.length===0)return;if(this.#J)window.clearTimeout(this.#J),this.#J=null;let x=[...this.#x];this.#x=[];let $=this.deduplicateEvents(x);this.publish($).catch((R)=>{this.#x=[...$,...this.#x].slice(0,100),console.error("Error sending analytics data:",R)})}async publish(x){return fetch(this.#R.buildUrl("log"),{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({userAgent:navigator.userAgent,screenWidth:window.screen.width,screenHeight:window.screen.height,language:navigator.language,timezone:Intl.DateTimeFormat().resolvedOptions().timeZone,events:x.map(($)=>{if(!$.timestamp)$.timestamp=new Date().toISOString();return{...$,name:$.name||$.type,properties:$.properties||{}}})}),credentials:"include",keepalive:!0})}getSessionId(){let x=A("_up.sid");if(!x)x=this.generateId(),K("_up.sid",x,{days:365,sameSite:"lax",secure:this.#_,domain:M(this.#R.serverUrl)});return x}generateId(){return"xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g,function(x){let $=Math.random()*16|0;return(x==="x"?$:$&3|8).toString(16)})}}class g{#R;#x;#$;#j=W.version;constructor(x){if(this.#R=new B(x),this.#x=new N(this.#R,x),this.#$=new O(this.#x,x),this.#j=x.version||this.#j,this.#x.init(this.#$),this.#x.setAppId(x.appId),x.autoTrack?.errors!==void 0?x.autoTrack.errors:!0)this.installErrorHandler();console.debug(`UserPath v${q.version} initialized`)}getAppId(){return this.#x.getAppId()}setAppId(x){this.#x.setAppId(x)}installErrorHandler(){this.#$.installErrorHandler()}uninstallErrorHandler(){this.#$.uninstallErrorHandler()}trackError(x,$={}){if(!this.#$.isErrorHandlerInstalled()&&$.source!=="manual")return;this.#$.trackError(x,$)}setUserId(x){this.#x.setUserId(x)}getUserId(){return this.#x.getUserId()}async identify(x){await this.#x.identify(x)}track(x,$){if(x==="page_view")this.#$.trackPageView();else if(x==="event")this.#$.trackCustomEvent($.name,$.properties||{});else if(x==="purchase")this.#$.trackPurchase({productId:$.properties?.product_id||"",price:$.price,currency:$.currency,properties:$.properties})}}export{g as UserPath,W as DEFAULT_CONFIG};