@product-intelligence-hub/sdk-web 0.1.2 → 0.1.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.cjs CHANGED
@@ -1,3 +1,3 @@
1
- 'use strict';Object.defineProperty(exports,'__esModule',{value:true});var O=Object.defineProperty;var C=(n,t,e)=>t in n?O(n,t,{enumerable:true,configurable:true,writable:true,value:e}):n[t]=e;var s=(n,t,e)=>C(n,typeof t!="symbol"?t+"":t,e);var a=class n extends Error{constructor(e,i,r){super(e);s(this,"code");s(this,"details");this.name="PIHError",this.code=i,this.details=r,Error.captureStackTrace&&Error.captureStackTrace(this,n);}static networkError(e,i){return new n(e,"NETWORK_ERROR",i)}static invalidConfig(e,i){return new n(e,"INVALID_CONFIG",i)}static queueFull(e,i){return new n(e,"QUEUE_FULL",i)}static rateLimited(e,i){return new n(e,"RATE_LIMITED",i)}static invalidPayload(e,i){return new n(e,"INVALID_PAYLOAD",i)}static storageError(e,i){return new n(e,"STORAGE_ERROR",i)}static sessionError(e,i){return new n(e,"SESSION_ERROR",i)}static fromUnknown(e){return e instanceof n?e:e instanceof Error?new n(e.message,"UNKNOWN_ERROR",e):new n(String(e),"UNKNOWN_ERROR",e)}};function d(){if(typeof crypto<"u"&&typeof crypto.randomUUID=="function")return crypto.randomUUID();if(typeof crypto<"u"&&typeof crypto.getRandomValues=="function"){let n=new Uint8Array(16);crypto.getRandomValues(n),n[6]=n[6]&15|64,n[8]=n[8]&63|128;let t=Array.from(n,e=>e.toString(16).padStart(2,"0")).join("");return `${t.slice(0,8)}-${t.slice(8,12)}-${t.slice(12,16)}-${t.slice(16,20)}-${t.slice(20)}`}return "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g,n=>{let t=Math.random()*16|0;return (n==="x"?t:t&3|8).toString(16)})}function T(){return new Date().toISOString()}function A(n){return n.toISOString()}function U(n,t=1e3,e=16e3){let i=t*Math.pow(2,n);return Math.min(i,e)}var g="pih_",l={QUEUE:`${g}queue`,ANONYMOUS_ID:`${g}anonymous_id`,USER_ID:`${g}user_id`,USER_TRAITS:`${g}user_traits`,SESSION_ID:`${g}session_id`,SESSION_LAST_ACTIVITY:`${g}session_last_activity`},h={API_URL:"https://repoingest-production.up.railway.app",FLUSH_INTERVAL:1e4,FLUSH_AT:25,MAX_QUEUE_SIZE:5e3,SESSION_TIMEOUT:18e5,MAX_BATCH_SIZE:100,MAX_RETRIES:5,BASE_BACKOFF_DELAY:1e3,MAX_BACKOFF_DELAY:16e3};var m=class{constructor(t,e=false){s(this,"anonymousId");s(this,"userId",null);s(this,"userTraits",{});s(this,"storage");s(this,"debug");this.storage=t,this.debug=e,this.anonymousId=d();}async initialize(){if(!this.storage){this.log("No storage adapter, using in-memory identity only");return}try{let t=await this.storage.get(l.ANONYMOUS_ID);t?(this.anonymousId=t,this.log("Loaded anonymous ID from storage:",this.anonymousId)):(await this.storage.set(l.ANONYMOUS_ID,this.anonymousId),this.log("Generated new anonymous ID:",this.anonymousId));let e=await this.storage.get(l.USER_ID);e&&(this.userId=e,this.log("Loaded user ID from storage:",this.userId));let i=await this.storage.get(l.USER_TRAITS);if(i)try{this.userTraits=JSON.parse(i),this.log("Loaded user traits from storage:",this.userTraits);}catch{this.log("Failed to parse stored user traits");}}catch(t){this.log("Error loading identity from storage:",t);}}getAnonymousId(){return this.anonymousId}getUserId(){return this.userId}getUserTraits(){return {...this.userTraits}}async setUserId(t){if(this.userId=t,this.log("Set user ID:",t),this.storage)try{await this.storage.set(l.USER_ID,t);}catch(e){this.log("Error persisting user ID:",e);}}async setUserTraits(t){if(this.userTraits={...this.userTraits,...t},this.log("Set user traits:",this.userTraits),this.storage)try{await this.storage.set(l.USER_TRAITS,JSON.stringify(this.userTraits));}catch(e){this.log("Error persisting user traits:",e);}}async reset(){if(this.anonymousId=d(),this.userId=null,this.userTraits={},this.log("Identity reset, new anonymous ID:",this.anonymousId),this.storage)try{await Promise.all([this.storage.set(l.ANONYMOUS_ID,this.anonymousId),this.storage.remove(l.USER_ID),this.storage.remove(l.USER_TRAITS)]);}catch(t){this.log("Error resetting identity in storage:",t);}}setDebug(t){this.debug=t;}log(...t){this.debug&&[...t];}};var y=class{constructor(t,e=h.SESSION_TIMEOUT,i={},r=false){s(this,"sessionId",null);s(this,"sessionStartTime",0);s(this,"lastActivity",0);s(this,"timeout");s(this,"storage");s(this,"callbacks");s(this,"debug");this.storage=t,this.timeout=e,this.callbacks=i,this.debug=r;}async initialize(){if(!this.storage){this.log("No storage adapter, using in-memory session only");return}try{let t=await this.storage.get(l.SESSION_ID),e=await this.storage.get(l.SESSION_LAST_ACTIVITY);if(t&&e){let i=parseInt(e,10);Date.now()-i<this.timeout?(this.sessionId=t,this.lastActivity=i,this.sessionStartTime=i,this.log("Restored session from storage:",this.sessionId)):(this.log("Stored session expired, will start new session"),await this.clearStoredSession());}}catch(t){this.log("Error loading session from storage:",t);}}getSessionId(){let t=Date.now();return this.sessionId&&t-this.lastActivity>this.timeout&&this.endSession(),this.sessionId||this.startSession(),this.lastActivity=t,this.persistLastActivity(),this.sessionId}touch(){this.sessionId&&(this.lastActivity=Date.now(),this.persistLastActivity());}hasActiveSession(){return this.sessionId?Date.now()-this.lastActivity<this.timeout:false}getCurrentSessionId(){return this.sessionId}getSessionDuration(){return this.sessionId?Date.now()-this.sessionStartTime:0}startSession(){let t=Date.now();this.sessionId=d(),this.sessionStartTime=t,this.lastActivity=t,this.log("Started new session:",this.sessionId),this.persistSession(),this.callbacks.onSessionStart?.(this.sessionId);}endSession(){if(!this.sessionId)return;let t=this.getSessionDuration(),e=this.sessionId;this.log("Ended session:",e,"duration:",t),this.sessionId=null,this.sessionStartTime=0,this.lastActivity=0,this.clearStoredSession(),this.callbacks.onSessionEnd?.(e,t);}forceEndSession(){this.sessionId&&this.endSession();}setDebug(t){this.debug=t;}setTimeout(t){this.timeout=t;}async persistSession(){if(!(!this.storage||!this.sessionId))try{await Promise.all([this.storage.set(l.SESSION_ID,this.sessionId),this.storage.set(l.SESSION_LAST_ACTIVITY,String(this.lastActivity))]);}catch(t){this.log("Error persisting session:",t);}}async persistLastActivity(){if(this.storage)try{await this.storage.set(l.SESSION_LAST_ACTIVITY,String(this.lastActivity));}catch(t){this.log("Error persisting last activity:",t);}}async clearStoredSession(){if(this.storage)try{await Promise.all([this.storage.remove(l.SESSION_ID),this.storage.remove(l.SESSION_LAST_ACTIVITY)]);}catch(t){this.log("Error clearing stored session:",t);}}log(...t){this.debug&&[...t];}};var S=class{constructor(t){s(this,"apiUrl");s(this,"apiKey");s(this,"tenantId");s(this,"debug");this.apiUrl=t.apiUrl.replace(/\/$/,""),this.apiKey=t.apiKey,this.tenantId=t.tenantId,this.debug=t.debug??false;}async sendEvents(t,e){let i=`${this.apiUrl}/v1/track`,r=JSON.stringify({events:t});if(this.log("Sending",t.length,"events to",i),e?.useBeacon&&typeof navigator<"u"&&typeof navigator.sendBeacon=="function"&&this.sendViaBeacon(i,r))return this.log("Events sent via sendBeacon"),{accepted:t.map(u=>({event_id:u.event_id,timestamp:u.timestamp})),rejected:[],stats:{received:t.length,accepted:t.length,rejected:0,processing_time_ms:0}};try{let o=await this.fetch(i,{method:"POST",headers:this.getHeaders(),body:r,keepalive:e?.useBeacon});if(!o.ok)throw o.status===429?a.rateLimited(`Rate limited: ${o.statusText}`,{status:o.status}):a.networkError(`HTTP ${o.status}: ${o.statusText}`,{status:o.status});let u=await o.json();return this.log("Track response:",u),u}catch(o){throw o instanceof a?o:a.networkError(`Failed to send events: ${o instanceof Error?o.message:String(o)}`,o)}}async sendIdentify(t){let e=`${this.apiUrl}/v1/identify`,i=JSON.stringify(t);this.log("Sending identify to",e,t);try{let r=await this.fetch(e,{method:"POST",headers:this.getHeaders(),body:i});if(!r.ok)throw r.status===429?a.rateLimited(`Rate limited: ${r.statusText}`,{status:r.status}):a.networkError(`HTTP ${r.status}: ${r.statusText}`,{status:r.status});let o=await r.json();return this.log("Identify response:",o),o}catch(r){throw r instanceof a?r:a.networkError(`Failed to send identify: ${r instanceof Error?r.message:String(r)}`,r)}}setTenantId(t){this.tenantId=t;}setDebug(t){this.debug=t;}getHeaders(){let t={"Content-Type":"application/json",Authorization:`Bearer ${this.apiKey}`};return this.tenantId&&(t["X-Tenant-Id"]=this.tenantId),t}sendViaBeacon(t,e){try{let i=new Blob([e],{type:"application/json"});return navigator.sendBeacon(t,i)}catch(i){return this.log("sendBeacon failed:",i),false}}async fetch(t,e){if(typeof fetch<"u")return fetch(t,e);throw a.networkError("fetch is not available in this environment")}log(...t){this.debug&&[...t];}};var I=class{constructor(t){s(this,"queue",[]);s(this,"isFlushing",false);s(this,"flushTimer",null);s(this,"retryTimer",null);s(this,"config");s(this,"initialized",false);this.config={flushAt:t.flushAt??h.FLUSH_AT,flushInterval:t.flushInterval??h.FLUSH_INTERVAL,maxQueueSize:t.maxQueueSize??h.MAX_QUEUE_SIZE,storage:t.storage,transport:t.transport,onError:t.onError,debug:t.debug??false};}async initialize(){this.initialized||(await this.loadPersistedQueue(),this.startFlushTimer(),this.initialized=true,this.log("Queue initialized with",this.queue.length,"persisted events"));}async enqueue(t){for(;this.queue.length>=this.config.maxQueueSize;){let i=this.queue.shift();i&&(this.log("Queue full, dropping oldest event:",i.event.event_id),this.config.onError?.(a.queueFull("Queue full, dropped oldest event",{dropped_event_id:i.event.event_id}),[i.event]));}let e={event:t,attempts:0,firstAttempt:Date.now()};this.queue.push(e),this.log("Enqueued event:",t.event_id,"Queue size:",this.queue.length),await this.persistQueue(),this.queue.length>=this.config.flushAt&&(this.log("Queue reached flushAt threshold, flushing"),this.flush());}async flush(t){if(!(this.isFlushing||this.queue.length===0)){this.isFlushing=true,this.log("Flushing",this.queue.length,"events");try{let e=this.queue.splice(0,h.MAX_BATCH_SIZE),i=e.map(r=>r.event);try{let r=await this.config.transport.sendEvents(i,t);for(let o of r.rejected)if(o.reason==="rate_limited"){let u=e.find(f=>f.event.event_id===o.event_id);u&&u.attempts<h.MAX_RETRIES&&(u.attempts++,this.queue.unshift(u),this.log("Rate limited event re-queued:",o.event_id,"attempt:",u.attempts));}else this.log("Event permanently rejected:",o.event_id,o.reason,o.details);this.log("Flush complete. Accepted:",r.stats.accepted,"Rejected:",r.stats.rejected);}catch(r){let o=a.fromUnknown(r);for(let p of e)p.attempts<h.MAX_RETRIES?(p.attempts++,this.queue.unshift(p)):this.log("Event dropped after max retries:",p.event.event_id);let u=e[0]?.attempts??1,f=U(u);this.log("Network error, scheduling retry in",f,"ms"),this.retryTimer=setTimeout(()=>{this.retryTimer=null,this.flush(t);},f),this.config.onError?.(o,i);}await this.persistQueue(),this.queue.length>=this.config.flushAt&&setTimeout(()=>this.flush(t),0);}finally{this.isFlushing=false;}}}getQueueLength(){return this.queue.length}isEmpty(){return this.queue.length===0}isBusy(){return this.isFlushing}async clear(){this.queue=[],await this.persistQueue(),this.log("Queue cleared");}destroy(){this.flushTimer&&(clearInterval(this.flushTimer),this.flushTimer=null),this.retryTimer&&(clearTimeout(this.retryTimer),this.retryTimer=null),this.log("Queue destroyed");}setDebug(t){this.config.debug=t;}async persistQueue(){if(this.config.storage)try{await this.config.storage.set(l.QUEUE,JSON.stringify(this.queue));}catch(t){this.log("Error persisting queue:",t);}}async loadPersistedQueue(){if(this.config.storage)try{let t=await this.config.storage.get(l.QUEUE);if(t){let e=JSON.parse(t);Array.isArray(e)&&(this.queue=e.filter(i=>i&&typeof i=="object"&&"event"in i&&"attempts"in i));}}catch(t){this.log("Error loading persisted queue:",t),this.queue=[];}}startFlushTimer(){this.flushTimer||(this.flushTimer=setInterval(()=>{this.queue.length>0&&(this.log("Flush timer triggered"),this.flush());},this.config.flushInterval));}log(...t){this.config.debug&&[...t];}};var v=class{constructor(t,e=null){s(this,"config");s(this,"storage",null);s(this,"identity");s(this,"session");s(this,"transport");s(this,"queue");s(this,"initialized",false);s(this,"tenantId");this.validateConfig(t),this.config={apiUrl:h.API_URL,debug:false,flushInterval:h.FLUSH_INTERVAL,flushAt:h.FLUSH_AT,maxQueueSize:h.MAX_QUEUE_SIZE,sessionTimeout:h.SESSION_TIMEOUT,...t},this.storage=e,this.tenantId=t.tenantId??"",this.identity=new m(e,this.config.debug),this.session=new y(e,this.config.sessionTimeout,{onSessionStart:i=>{this.log("Session started:",i),this.trackInternal("session_started",{session_id:i});},onSessionEnd:(i,r)=>{this.log("Session ended:",i,"duration:",r),this.trackInternal("session_ended",{session_id:i,duration_ms:r});}},this.config.debug),this.transport=new S({apiUrl:this.config.apiUrl,apiKey:this.config.apiKey,tenantId:this.tenantId,debug:this.config.debug}),this.queue=new I({flushAt:this.config.flushAt,flushInterval:this.config.flushInterval,maxQueueSize:this.config.maxQueueSize,storage:e,transport:this.transport,onError:(i,r)=>{this.config.onError?.(i),this.log("Queue error:",i.message,"events:",r.length);},debug:this.config.debug});}async initialize(){this.initialized||(await Promise.all([this.identity.initialize(),this.session.initialize(),this.queue.initialize()]),this.initialized=true,this.log("Client initialized"));}setTenant(t){this.tenantId=t,this.transport.setTenantId(t),this.log("Tenant set:",t);}async identify(t,e){await this.ensureInitialized(),await this.identity.setUserId(t),e&&await this.identity.setUserTraits(e);try{await this.transport.sendIdentify({project_id:this.config.projectId,environment:this.config.environment,tenant_id:this.tenantId,anonymous_id:this.identity.getAnonymousId(),user_id:t,traits:e,timestamp:T()});}catch(i){let r=a.fromUnknown(i);this.config.onError?.(r),this.log("Identify error:",r.message);}}async setUserTraits(t){await this.ensureInitialized(),await this.identity.setUserTraits(t);}async track(t,e,i){await this.ensureInitialized();let r=this.createEvent(t,e,i);if(this.session.touch(),i?.immediate)try{await this.transport.sendEvents([r]);}catch(o){let u=a.fromUnknown(o);this.config.onError?.(u),this.log("Immediate track error:",u.message);}else await this.queue.enqueue(r);}async flush(t){await this.ensureInitialized(),await this.queue.flush(t);}async reset(){await this.ensureInitialized(),this.session.forceEndSession(),await this.identity.reset(),this.log("Client reset");}setDebug(t){this.config.debug=t,this.identity.setDebug(t),this.session.setDebug(t),this.transport.setDebug(t),this.queue.setDebug(t);}getAnonymousId(){return this.identity.getAnonymousId()}getUserId(){return this.identity.getUserId()}getSessionId(){return this.session.getCurrentSessionId()}getQueueLength(){return this.queue.getQueueLength()}destroy(){this.queue.destroy(),this.log("Client destroyed");}trackInternal(t,e){let i=this.createEvent(t,e);this.queue.enqueue(i).catch(r=>{this.log("Internal track error:",r);});}createEvent(t,e,i){let r=i?.timestamp?A(i.timestamp):T();return {event_id:d(),timestamp:r,project_id:this.config.projectId,environment:this.config.environment,tenant_id:this.tenantId,event_name:t,anonymous_id:this.identity.getAnonymousId(),user_id:this.identity.getUserId(),session_id:this.session.getSessionId(),platform:this.config.platform,app_version:this.config.appVersion??null,properties:e??{},user_traits:this.identity.getUserTraits()}}async ensureInitialized(){this.initialized||await this.initialize();}validateConfig(t){if(!t.apiKey)throw a.invalidConfig("apiKey is required");if(!t.projectId)throw a.invalidConfig("projectId is required");if(!t.environment)throw a.invalidConfig("environment is required");if(!t.platform)throw a.invalidConfig("platform is required")}log(...t){this.config.debug&&[...t];}};var w=class{constructor(){s(this,"data",new Map);}async get(t){return this.data.get(t)??null}async set(t,e){this.data.set(t,e);}async remove(t){this.data.delete(t);}};function H(){try{let n="__pih_test__";return localStorage.setItem(n,n),localStorage.removeItem(n),!0}catch{return false}}var P=class{constructor(){s(this,"fallback",null);s(this,"useLocalStorage");this.useLocalStorage=H(),this.useLocalStorage||(this.fallback=new w,console.warn("[PIH] localStorage unavailable, using in-memory storage. Data will not persist across page loads."));}async get(t){if(this.fallback)return this.fallback.get(t);try{return localStorage.getItem(t)}catch{return this.fallback||(this.fallback=new w),this.fallback.get(t)}}async set(t,e){if(this.fallback)return this.fallback.set(t,e);try{localStorage.setItem(t,e);}catch(i){return this.fallback||(this.fallback=new w,console.warn("[PIH] localStorage write failed, falling back to in-memory storage:",i)),this.fallback.set(t,e)}}async remove(t){if(this.fallback)return this.fallback.remove(t);try{localStorage.removeItem(t);}catch{}}};function x(){return new P}x();var k="pih_utm_params",L=["utm_source","utm_medium","utm_campaign","utm_term","utm_content"],E=class{constructor(t,e={}){s(this,"client");s(this,"config");s(this,"cachedUtmParams",null);s(this,"originalPushState",null);s(this,"originalReplaceState",null);s(this,"boundHandleClick");s(this,"boundHandlePopState");this.client=t,this.config={pageViews:e.pageViews!==false,clicks:e.clicks??false,clickSelector:e.clickSelector??"[data-track]",forms:e.forms??false},this.boundHandleClick=this.handleClick.bind(this),this.boundHandlePopState=this.handlePopState.bind(this);}start(){typeof window>"u"||typeof document>"u"||(this.loadCachedUtmParams(),this.config.pageViews&&(this.setupPageViews(),this.trackPageView()),this.config.clicks&&this.setupClickTracking());}stop(){this.originalPushState&&(history.pushState=this.originalPushState,this.originalPushState=null),this.originalReplaceState&&(history.replaceState=this.originalReplaceState,this.originalReplaceState=null),typeof window<"u"&&window.removeEventListener("popstate",this.boundHandlePopState),typeof document<"u"&&document.removeEventListener("click",this.boundHandleClick,true);}trackPageView(){let t=new URL(window.location.href),e=this.extractUtmParams(t);Object.keys(e).length>0&&!this.cachedUtmParams&&(this.cachedUtmParams=e,this.persistUtmParams(e)),this.client.track("page_viewed",{path:t.pathname,search:t.search,hash:t.hash,referrer:document.referrer||null,title:document.title,url:window.location.href,...this.getUtmParams(t)});}setupPageViews(){this.originalPushState=history.pushState,this.originalReplaceState=history.replaceState;let t=this;history.pushState=function(...e){t.originalPushState.apply(history,e),setTimeout(()=>t.trackPageView(),0);},history.replaceState=function(...e){t.originalReplaceState.apply(history,e),setTimeout(()=>t.trackPageView(),0);},window.addEventListener("popstate",this.boundHandlePopState);}handlePopState(){this.trackPageView();}setupClickTracking(){document.addEventListener("click",this.boundHandleClick,true);}handleClick(t){let e=t.target;if(!e)return;let i=e.closest(this.config.clickSelector);if(!i)return;let r=i.tagName.toLowerCase(),o=(i.textContent||"").trim().slice(0,100),u=i.id||null,f=i.className||null,p=i.getAttribute("data-track"),R=i instanceof HTMLAnchorElement?i.href:null;this.client.track("element_clicked",{element_tag:r,element_text:o,element_id:u,element_classes:f,data_track:p,href:R,path:window.location.pathname});}extractUtmParams(t){let e={};for(let i of L){let r=t.searchParams.get(i);r&&(e[i]=r);}return e}getUtmParams(t){let e=this.extractUtmParams(t);return Object.keys(e).length>0?e:this.cachedUtmParams??{}}loadCachedUtmParams(){try{let t=localStorage.getItem(k);t&&(this.cachedUtmParams=JSON.parse(t));}catch{}}persistUtmParams(t){try{localStorage.setItem(k,JSON.stringify(t));}catch{}}};var b=class{constructor(t){s(this,"client");s(this,"boundHandleVisibilityChange");s(this,"boundHandleBeforeUnload");this.client=t,this.boundHandleVisibilityChange=this.handleVisibilityChange.bind(this),this.boundHandleBeforeUnload=this.handleBeforeUnload.bind(this);}start(){typeof document<"u"&&document.addEventListener("visibilitychange",this.boundHandleVisibilityChange),typeof window<"u"&&(window.addEventListener("beforeunload",this.boundHandleBeforeUnload),window.addEventListener("pagehide",this.boundHandleBeforeUnload));}stop(){typeof document<"u"&&document.removeEventListener("visibilitychange",this.boundHandleVisibilityChange),typeof window<"u"&&(window.removeEventListener("beforeunload",this.boundHandleBeforeUnload),window.removeEventListener("pagehide",this.boundHandleBeforeUnload));}handleVisibilityChange(){document.visibilityState==="hidden"&&this.flushWithBeacon();}handleBeforeUnload(){this.flushWithBeacon();}flushWithBeacon(){this.client.flush({useBeacon:true}).catch(()=>{});}};var _=class extends v{constructor(e,i){let r={...e,platform:"web"};super(r,i??x());s(this,"autocapture",null);s(this,"beacon");this.beacon=new b(this);}async initialize(){await super.initialize(),this.beacon.start(),this.config.autocapture&&(this.autocapture=new E(this,this.config.autocapture),this.autocapture.start()),this.log("Web client initialized");}enableAutocapture(e){this.autocapture&&this.autocapture.stop(),this.autocapture=new E(this,e),this.autocapture.start();}disableAutocapture(){this.autocapture&&(this.autocapture.stop(),this.autocapture=null);}trackPageView(){if(this.autocapture)this.autocapture.trackPageView();else {let e=new URL(window.location.href);this.track("page_viewed",{path:e.pathname,search:e.search,hash:e.hash,referrer:document.referrer||null,title:document.title,url:window.location.href});}}destroy(){this.beacon.stop(),this.autocapture&&this.autocapture.stop(),super.destroy();}log(...e){this.config.debug&&[...e];}},c=null;function D(n){return c?(console.warn("[PIH] SDK already initialized. Returning existing instance."),c):(c=new _(n),c.initialize().catch(t=>{console.error("[PIH] Failed to initialize:",t);}),c)}function N(){return c}function q(){c&&(c.destroy(),c=null);}var z={init:D,getInstance:N,resetInstance:q,WebPIHClient:_},Ht=z;
1
+ 'use strict';Object.defineProperty(exports,'__esModule',{value:true});var O=Object.defineProperty;var C=(n,t,e)=>t in n?O(n,t,{enumerable:true,configurable:true,writable:true,value:e}):n[t]=e;var s=(n,t,e)=>C(n,typeof t!="symbol"?t+"":t,e);var a=class n extends Error{constructor(e,i,r){super(e);s(this,"code");s(this,"details");this.name="PIHError",this.code=i,this.details=r,Error.captureStackTrace&&Error.captureStackTrace(this,n);}static networkError(e,i){return new n(e,"NETWORK_ERROR",i)}static invalidConfig(e,i){return new n(e,"INVALID_CONFIG",i)}static queueFull(e,i){return new n(e,"QUEUE_FULL",i)}static rateLimited(e,i){return new n(e,"RATE_LIMITED",i)}static invalidPayload(e,i){return new n(e,"INVALID_PAYLOAD",i)}static storageError(e,i){return new n(e,"STORAGE_ERROR",i)}static sessionError(e,i){return new n(e,"SESSION_ERROR",i)}static fromUnknown(e){return e instanceof n?e:e instanceof Error?new n(e.message,"UNKNOWN_ERROR",e):new n(String(e),"UNKNOWN_ERROR",e)}};function g(){if(typeof crypto<"u"&&typeof crypto.randomUUID=="function")return crypto.randomUUID();if(typeof crypto<"u"&&typeof crypto.getRandomValues=="function"){let n=new Uint8Array(16);crypto.getRandomValues(n),n[6]=n[6]&15|64,n[8]=n[8]&63|128;let t=Array.from(n,e=>e.toString(16).padStart(2,"0")).join("");return `${t.slice(0,8)}-${t.slice(8,12)}-${t.slice(12,16)}-${t.slice(16,20)}-${t.slice(20)}`}return "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g,n=>{let t=Math.random()*16|0;return (n==="x"?t:t&3|8).toString(16)})}function T(){return new Date().toISOString()}function A(n){return n.toISOString()}function U(n,t=1e3,e=16e3){let i=t*Math.pow(2,n);return Math.min(i,e)}var f="pih_",u={QUEUE:`${f}queue`,ANONYMOUS_ID:`${f}anonymous_id`,USER_ID:`${f}user_id`,USER_TRAITS:`${f}user_traits`,SESSION_ID:`${f}session_id`,SESSION_LAST_ACTIVITY:`${f}session_last_activity`},h={API_URL:"https://repoingest-production.up.railway.app",FLUSH_INTERVAL:1e4,FLUSH_AT:25,MAX_QUEUE_SIZE:5e3,SESSION_TIMEOUT:18e5,MAX_BATCH_SIZE:100,MAX_RETRIES:5,BASE_BACKOFF_DELAY:1e3,MAX_BACKOFF_DELAY:16e3};var m=class{constructor(t,e=false){s(this,"anonymousId");s(this,"userId",null);s(this,"userTraits",{});s(this,"storage");s(this,"debug");this.storage=t,this.debug=e,this.anonymousId=g();}async initialize(){if(!this.storage){this.log("No storage adapter, using in-memory identity only");return}try{let t=await this.storage.get(u.ANONYMOUS_ID);t?(this.anonymousId=t,this.log("Loaded anonymous ID from storage:",this.anonymousId)):(await this.storage.set(u.ANONYMOUS_ID,this.anonymousId),this.log("Generated new anonymous ID:",this.anonymousId));let e=await this.storage.get(u.USER_ID);e&&(this.userId=e,this.log("Loaded user ID from storage:",this.userId));let i=await this.storage.get(u.USER_TRAITS);if(i)try{this.userTraits=JSON.parse(i),this.log("Loaded user traits from storage:",this.userTraits);}catch{this.log("Failed to parse stored user traits");}}catch(t){this.log("Error loading identity from storage:",t);}}getAnonymousId(){return this.anonymousId}getUserId(){return this.userId}getUserTraits(){return {...this.userTraits}}async setUserId(t){if(this.userId=t,this.log("Set user ID:",t),this.storage)try{await this.storage.set(u.USER_ID,t);}catch(e){this.log("Error persisting user ID:",e);}}async setUserTraits(t){if(this.userTraits={...this.userTraits,...t},this.log("Set user traits:",this.userTraits),this.storage)try{await this.storage.set(u.USER_TRAITS,JSON.stringify(this.userTraits));}catch(e){this.log("Error persisting user traits:",e);}}async reset(){if(this.anonymousId=g(),this.userId=null,this.userTraits={},this.log("Identity reset, new anonymous ID:",this.anonymousId),this.storage)try{await Promise.all([this.storage.set(u.ANONYMOUS_ID,this.anonymousId),this.storage.remove(u.USER_ID),this.storage.remove(u.USER_TRAITS)]);}catch(t){this.log("Error resetting identity in storage:",t);}}setDebug(t){this.debug=t;}log(...t){this.debug&&[...t];}};var y=class{constructor(t,e=h.SESSION_TIMEOUT,i={},r=false){s(this,"sessionId",null);s(this,"sessionStartTime",0);s(this,"lastActivity",0);s(this,"timeout");s(this,"storage");s(this,"callbacks");s(this,"debug");this.storage=t,this.timeout=e,this.callbacks=i,this.debug=r;}async initialize(){if(!this.storage){this.log("No storage adapter, using in-memory session only");return}try{let t=await this.storage.get(u.SESSION_ID),e=await this.storage.get(u.SESSION_LAST_ACTIVITY);if(t&&e){let i=parseInt(e,10);Date.now()-i<this.timeout?(this.sessionId=t,this.lastActivity=i,this.sessionStartTime=i,this.log("Restored session from storage:",this.sessionId)):(this.log("Stored session expired, will start new session"),await this.clearStoredSession());}}catch(t){this.log("Error loading session from storage:",t);}}getSessionId(){let t=Date.now();return this.sessionId&&t-this.lastActivity>this.timeout&&this.endSession(),this.sessionId||this.startSession(),this.lastActivity=t,this.persistLastActivity(),this.sessionId}touch(){this.sessionId&&(this.lastActivity=Date.now(),this.persistLastActivity());}hasActiveSession(){return this.sessionId?Date.now()-this.lastActivity<this.timeout:false}getCurrentSessionId(){return this.sessionId}getSessionDuration(){return this.sessionId?Date.now()-this.sessionStartTime:0}startSession(){let t=Date.now();this.sessionId=g(),this.sessionStartTime=t,this.lastActivity=t,this.log("Started new session:",this.sessionId),this.persistSession(),this.callbacks.onSessionStart?.(this.sessionId);}endSession(){if(!this.sessionId)return;let t=this.getSessionDuration(),e=this.sessionId;this.log("Ended session:",e,"duration:",t),this.sessionId=null,this.sessionStartTime=0,this.lastActivity=0,this.clearStoredSession(),this.callbacks.onSessionEnd?.(e,t);}forceEndSession(){this.sessionId&&this.endSession();}setDebug(t){this.debug=t;}setTimeout(t){this.timeout=t;}async persistSession(){if(!(!this.storage||!this.sessionId))try{await Promise.all([this.storage.set(u.SESSION_ID,this.sessionId),this.storage.set(u.SESSION_LAST_ACTIVITY,String(this.lastActivity))]);}catch(t){this.log("Error persisting session:",t);}}async persistLastActivity(){if(this.storage)try{await this.storage.set(u.SESSION_LAST_ACTIVITY,String(this.lastActivity));}catch(t){this.log("Error persisting last activity:",t);}}async clearStoredSession(){if(this.storage)try{await Promise.all([this.storage.remove(u.SESSION_ID),this.storage.remove(u.SESSION_LAST_ACTIVITY)]);}catch(t){this.log("Error clearing stored session:",t);}}log(...t){this.debug&&[...t];}};var I=class{constructor(t){s(this,"apiUrl");s(this,"apiKey");s(this,"tenantId");s(this,"debug");this.apiUrl=t.apiUrl.replace(/\/$/,""),this.apiKey=t.apiKey,this.tenantId=t.tenantId,this.debug=t.debug??false;}async sendEvents(t,e){let i=`${this.apiUrl}/v1/track`,r=t.map(o=>this.toTrackApiPayload(o)),l=JSON.stringify({events:r});if(this.log("Sending",t.length,"events to",i),e?.useBeacon&&typeof navigator<"u"&&typeof navigator.sendBeacon=="function"&&this.sendViaBeacon(i,l))return this.log("Events sent via sendBeacon"),{accepted:t.map(c=>({event_id:c.event_id,timestamp:c.timestamp})),rejected:[],stats:{received:t.length,accepted:t.length,rejected:0,processing_time_ms:0}};try{let o=await this.fetch(i,{method:"POST",headers:this.getHeaders(),body:l,keepalive:e?.useBeacon});if(!o.ok)throw o.status===429?a.rateLimited(`Rate limited: ${o.statusText}`,{status:o.status}):a.networkError(`HTTP ${o.status}: ${o.statusText}`,{status:o.status});let c=await o.json();return this.log("Track response:",c),c}catch(o){throw o instanceof a?o:a.networkError(`Failed to send events: ${o instanceof Error?o.message:String(o)}`,o)}}async sendIdentify(t){let e=`${this.apiUrl}/v1/identify`,i=JSON.stringify(this.toIdentifyApiPayload(t));this.log("Sending identify to",e,t);try{let r=await this.fetch(e,{method:"POST",headers:this.getHeaders(),body:i});if(!r.ok)throw r.status===429?a.rateLimited(`Rate limited: ${r.statusText}`,{status:r.status}):a.networkError(`HTTP ${r.status}: ${r.statusText}`,{status:r.status});let l=await r.json();return this.log("Identify response:",l),l}catch(r){throw r instanceof a?r:a.networkError(`Failed to send identify: ${r instanceof Error?r.message:String(r)}`,r)}}setTenantId(t){this.tenantId=t;}setDebug(t){this.debug=t;}getHeaders(){let t={"Content-Type":"application/json",Authorization:`Bearer ${this.apiKey}`};return this.tenantId&&(t["X-Tenant-Id"]=this.tenantId),t}toTrackApiPayload(t){return {eventId:t.event_id,eventName:t.event_name,timestamp:t.timestamp,anonymousId:t.anonymous_id,userId:t.user_id??void 0,sessionId:t.session_id??void 0,properties:t.properties,userTraits:t.user_traits,context:{platform:t.platform,appVersion:t.app_version??void 0}}}toIdentifyApiPayload(t){return {userId:t.user_id,anonymousId:t.anonymous_id,traits:t.traits,timestamp:t.timestamp}}sendViaBeacon(t,e){try{let i=new Blob([e],{type:"application/json"});return navigator.sendBeacon(t,i)}catch(i){return this.log("sendBeacon failed:",i),false}}async fetch(t,e){if(typeof fetch<"u")return fetch(t,e);throw a.networkError("fetch is not available in this environment")}log(...t){this.debug&&[...t];}};var S=class{constructor(t){s(this,"queue",[]);s(this,"isFlushing",false);s(this,"flushTimer",null);s(this,"retryTimer",null);s(this,"config");s(this,"initialized",false);this.config={flushAt:t.flushAt??h.FLUSH_AT,flushInterval:t.flushInterval??h.FLUSH_INTERVAL,maxQueueSize:t.maxQueueSize??h.MAX_QUEUE_SIZE,storage:t.storage,transport:t.transport,onError:t.onError,debug:t.debug??false};}async initialize(){this.initialized||(await this.loadPersistedQueue(),this.startFlushTimer(),this.initialized=true,this.log("Queue initialized with",this.queue.length,"persisted events"));}async enqueue(t){for(;this.queue.length>=this.config.maxQueueSize;){let i=this.queue.shift();i&&(this.log("Queue full, dropping oldest event:",i.event.event_id),this.config.onError?.(a.queueFull("Queue full, dropped oldest event",{dropped_event_id:i.event.event_id}),[i.event]));}let e={event:t,attempts:0,firstAttempt:Date.now()};this.queue.push(e),this.log("Enqueued event:",t.event_id,"Queue size:",this.queue.length),await this.persistQueue(),this.queue.length>=this.config.flushAt&&(this.log("Queue reached flushAt threshold, flushing"),this.flush());}async flush(t){if(!(this.isFlushing||this.queue.length===0)){this.isFlushing=true,this.log("Flushing",this.queue.length,"events");try{let e=this.queue.splice(0,h.MAX_BATCH_SIZE),i=e.map(r=>r.event);try{let r=await this.config.transport.sendEvents(i,t);for(let l of r.rejected)if(l.reason==="rate_limited"){let o=e.find(c=>c.event.event_id===l.event_id);o&&o.attempts<h.MAX_RETRIES&&(o.attempts++,this.queue.unshift(o),this.log("Rate limited event re-queued:",l.event_id,"attempt:",o.attempts));}else this.log("Event permanently rejected:",l.event_id,l.reason,l.details);this.log("Flush complete. Accepted:",r.stats.accepted,"Rejected:",r.stats.rejected);}catch(r){let l=a.fromUnknown(r);for(let p of e)p.attempts<h.MAX_RETRIES?(p.attempts++,this.queue.unshift(p)):this.log("Event dropped after max retries:",p.event.event_id);let o=e[0]?.attempts??1,c=U(o);this.log("Network error, scheduling retry in",c,"ms"),this.retryTimer=setTimeout(()=>{this.retryTimer=null,this.flush(t);},c),this.config.onError?.(l,i);}await this.persistQueue(),this.queue.length>=this.config.flushAt&&setTimeout(()=>this.flush(t),0);}finally{this.isFlushing=false;}}}getQueueLength(){return this.queue.length}isEmpty(){return this.queue.length===0}isBusy(){return this.isFlushing}async clear(){this.queue=[],await this.persistQueue(),this.log("Queue cleared");}destroy(){this.flushTimer&&(clearInterval(this.flushTimer),this.flushTimer=null),this.retryTimer&&(clearTimeout(this.retryTimer),this.retryTimer=null),this.log("Queue destroyed");}setDebug(t){this.config.debug=t;}async persistQueue(){if(this.config.storage)try{await this.config.storage.set(u.QUEUE,JSON.stringify(this.queue));}catch(t){this.log("Error persisting queue:",t);}}async loadPersistedQueue(){if(this.config.storage)try{let t=await this.config.storage.get(u.QUEUE);if(t){let e=JSON.parse(t);Array.isArray(e)&&(this.queue=e.filter(i=>i&&typeof i=="object"&&"event"in i&&"attempts"in i));}}catch(t){this.log("Error loading persisted queue:",t),this.queue=[];}}startFlushTimer(){this.flushTimer||(this.flushTimer=setInterval(()=>{this.queue.length>0&&(this.log("Flush timer triggered"),this.flush());},this.config.flushInterval));}log(...t){this.config.debug&&[...t];}};var v=class{constructor(t,e=null){s(this,"config");s(this,"storage",null);s(this,"identity");s(this,"session");s(this,"transport");s(this,"queue");s(this,"initialized",false);s(this,"tenantId");this.validateConfig(t),this.config={apiUrl:h.API_URL,debug:false,flushInterval:h.FLUSH_INTERVAL,flushAt:h.FLUSH_AT,maxQueueSize:h.MAX_QUEUE_SIZE,sessionTimeout:h.SESSION_TIMEOUT,...t},this.storage=e,this.tenantId=t.tenantId??"",this.identity=new m(e,this.config.debug),this.session=new y(e,this.config.sessionTimeout,{onSessionStart:i=>{this.log("Session started:",i),this.trackInternal("session_started",{session_id:i});},onSessionEnd:(i,r)=>{this.log("Session ended:",i,"duration:",r),this.trackInternal("session_ended",{session_id:i,duration_ms:r});}},this.config.debug),this.transport=new I({apiUrl:this.config.apiUrl,apiKey:this.config.apiKey,tenantId:this.tenantId,debug:this.config.debug}),this.queue=new S({flushAt:this.config.flushAt,flushInterval:this.config.flushInterval,maxQueueSize:this.config.maxQueueSize,storage:e,transport:this.transport,onError:(i,r)=>{this.config.onError?.(i),this.log("Queue error:",i.message,"events:",r.length);},debug:this.config.debug});}async initialize(){this.initialized||(await Promise.all([this.identity.initialize(),this.session.initialize(),this.queue.initialize()]),this.initialized=true,this.log("Client initialized"));}setTenant(t){this.tenantId=t,this.transport.setTenantId(t),this.log("Tenant set:",t);}async identify(t,e){await this.ensureInitialized(),await this.identity.setUserId(t),e&&await this.identity.setUserTraits(e);try{await this.transport.sendIdentify({project_id:this.config.projectId,environment:this.config.environment,tenant_id:this.tenantId,anonymous_id:this.identity.getAnonymousId(),user_id:t,traits:e,timestamp:T()});}catch(i){let r=a.fromUnknown(i);this.config.onError?.(r),this.log("Identify error:",r.message);}}async setUserTraits(t){await this.ensureInitialized(),await this.identity.setUserTraits(t);}async track(t,e,i){await this.ensureInitialized();let r=this.createEvent(t,e,i);if(this.session.touch(),i?.immediate)try{await this.transport.sendEvents([r]);}catch(l){let o=a.fromUnknown(l);this.config.onError?.(o),this.log("Immediate track error:",o.message);}else await this.queue.enqueue(r);}async flush(t){await this.ensureInitialized(),await this.queue.flush(t);}async reset(){await this.ensureInitialized(),this.session.forceEndSession(),await this.identity.reset(),this.log("Client reset");}setDebug(t){this.config.debug=t,this.identity.setDebug(t),this.session.setDebug(t),this.transport.setDebug(t),this.queue.setDebug(t);}getAnonymousId(){return this.identity.getAnonymousId()}getUserId(){return this.identity.getUserId()}getSessionId(){return this.session.getCurrentSessionId()}getQueueLength(){return this.queue.getQueueLength()}destroy(){this.queue.destroy(),this.log("Client destroyed");}trackInternal(t,e){let i=this.createEvent(t,e);this.queue.enqueue(i).catch(r=>{this.log("Internal track error:",r);});}createEvent(t,e,i){let r=i?.timestamp?A(i.timestamp):T();return {event_id:g(),timestamp:r,project_id:this.config.projectId,environment:this.config.environment,tenant_id:this.tenantId,event_name:t,anonymous_id:this.identity.getAnonymousId(),user_id:this.identity.getUserId(),session_id:this.session.getSessionId(),platform:this.config.platform,app_version:this.config.appVersion??null,properties:e??{},user_traits:this.identity.getUserTraits()}}async ensureInitialized(){this.initialized||await this.initialize();}validateConfig(t){if(!t.apiKey)throw a.invalidConfig("apiKey is required");if(!t.projectId)throw a.invalidConfig("projectId is required");if(!t.environment)throw a.invalidConfig("environment is required");if(!t.platform)throw a.invalidConfig("platform is required")}log(...t){this.config.debug&&[...t];}};var w=class{constructor(){s(this,"data",new Map);}async get(t){return this.data.get(t)??null}async set(t,e){this.data.set(t,e);}async remove(t){this.data.delete(t);}};function H(){try{let n="__pih_test__";return localStorage.setItem(n,n),localStorage.removeItem(n),!0}catch{return false}}var P=class{constructor(){s(this,"fallback",null);s(this,"useLocalStorage");this.useLocalStorage=H(),this.useLocalStorage||(this.fallback=new w,console.warn("[PIH] localStorage unavailable, using in-memory storage. Data will not persist across page loads."));}async get(t){if(this.fallback)return this.fallback.get(t);try{return localStorage.getItem(t)}catch{return this.fallback||(this.fallback=new w),this.fallback.get(t)}}async set(t,e){if(this.fallback)return this.fallback.set(t,e);try{localStorage.setItem(t,e);}catch(i){return this.fallback||(this.fallback=new w,console.warn("[PIH] localStorage write failed, falling back to in-memory storage:",i)),this.fallback.set(t,e)}}async remove(t){if(this.fallback)return this.fallback.remove(t);try{localStorage.removeItem(t);}catch{}}};function x(){return new P}x();var k="pih_utm_params",L=["utm_source","utm_medium","utm_campaign","utm_term","utm_content"],E=class{constructor(t,e={}){s(this,"client");s(this,"config");s(this,"cachedUtmParams",null);s(this,"originalPushState",null);s(this,"originalReplaceState",null);s(this,"boundHandleClick");s(this,"boundHandlePopState");this.client=t,this.config={pageViews:e.pageViews!==false,clicks:e.clicks??false,clickSelector:e.clickSelector??"[data-track]",forms:e.forms??false},this.boundHandleClick=this.handleClick.bind(this),this.boundHandlePopState=this.handlePopState.bind(this);}start(){typeof window>"u"||typeof document>"u"||(this.loadCachedUtmParams(),this.config.pageViews&&(this.setupPageViews(),this.trackPageView()),this.config.clicks&&this.setupClickTracking());}stop(){this.originalPushState&&(history.pushState=this.originalPushState,this.originalPushState=null),this.originalReplaceState&&(history.replaceState=this.originalReplaceState,this.originalReplaceState=null),typeof window<"u"&&window.removeEventListener("popstate",this.boundHandlePopState),typeof document<"u"&&document.removeEventListener("click",this.boundHandleClick,true);}trackPageView(){let t=new URL(window.location.href),e=this.extractUtmParams(t);Object.keys(e).length>0&&!this.cachedUtmParams&&(this.cachedUtmParams=e,this.persistUtmParams(e)),this.client.track("page_viewed",{path:t.pathname,search:t.search,hash:t.hash,referrer:document.referrer||null,title:document.title,url:window.location.href,...this.getUtmParams(t)});}setupPageViews(){this.originalPushState=history.pushState,this.originalReplaceState=history.replaceState;let t=this;history.pushState=function(...e){t.originalPushState.apply(history,e),setTimeout(()=>t.trackPageView(),0);},history.replaceState=function(...e){t.originalReplaceState.apply(history,e),setTimeout(()=>t.trackPageView(),0);},window.addEventListener("popstate",this.boundHandlePopState);}handlePopState(){this.trackPageView();}setupClickTracking(){document.addEventListener("click",this.boundHandleClick,true);}handleClick(t){let e=t.target;if(!e)return;let i=e.closest(this.config.clickSelector);if(!i)return;let r=i.tagName.toLowerCase(),l=(i.textContent||"").trim().slice(0,100),o=i.id||null,c=i.className||null,p=i.getAttribute("data-track"),R=i instanceof HTMLAnchorElement?i.href:null;this.client.track("element_clicked",{element_tag:r,element_text:l,element_id:o,element_classes:c,data_track:p,href:R,path:window.location.pathname});}extractUtmParams(t){let e={};for(let i of L){let r=t.searchParams.get(i);r&&(e[i]=r);}return e}getUtmParams(t){let e=this.extractUtmParams(t);return Object.keys(e).length>0?e:this.cachedUtmParams??{}}loadCachedUtmParams(){try{let t=localStorage.getItem(k);t&&(this.cachedUtmParams=JSON.parse(t));}catch{}}persistUtmParams(t){try{localStorage.setItem(k,JSON.stringify(t));}catch{}}};var b=class{constructor(t){s(this,"client");s(this,"boundHandleVisibilityChange");s(this,"boundHandleBeforeUnload");this.client=t,this.boundHandleVisibilityChange=this.handleVisibilityChange.bind(this),this.boundHandleBeforeUnload=this.handleBeforeUnload.bind(this);}start(){typeof document<"u"&&document.addEventListener("visibilitychange",this.boundHandleVisibilityChange),typeof window<"u"&&(window.addEventListener("beforeunload",this.boundHandleBeforeUnload),window.addEventListener("pagehide",this.boundHandleBeforeUnload));}stop(){typeof document<"u"&&document.removeEventListener("visibilitychange",this.boundHandleVisibilityChange),typeof window<"u"&&(window.removeEventListener("beforeunload",this.boundHandleBeforeUnload),window.removeEventListener("pagehide",this.boundHandleBeforeUnload));}handleVisibilityChange(){document.visibilityState==="hidden"&&this.flushWithBeacon();}handleBeforeUnload(){this.flushWithBeacon();}flushWithBeacon(){this.client.flush({useBeacon:true}).catch(()=>{});}};var _=class extends v{constructor(e,i){let r={...e,platform:"web"};super(r,i??x());s(this,"autocapture",null);s(this,"beacon");this.beacon=new b(this);}async initialize(){await super.initialize(),this.beacon.start(),this.config.autocapture&&(this.autocapture=new E(this,this.config.autocapture),this.autocapture.start()),this.log("Web client initialized");}enableAutocapture(e){this.autocapture&&this.autocapture.stop(),this.autocapture=new E(this,e),this.autocapture.start();}disableAutocapture(){this.autocapture&&(this.autocapture.stop(),this.autocapture=null);}trackPageView(){if(this.autocapture)this.autocapture.trackPageView();else {let e=new URL(window.location.href);this.track("page_viewed",{path:e.pathname,search:e.search,hash:e.hash,referrer:document.referrer||null,title:document.title,url:window.location.href});}}destroy(){this.beacon.stop(),this.autocapture&&this.autocapture.stop(),super.destroy();}log(...e){this.config.debug&&[...e];}},d=null;function D(n){return d?(console.warn("[PIH] SDK already initialized. Returning existing instance."),d):(d=new _(n),d.initialize().catch(t=>{console.error("[PIH] Failed to initialize:",t);}),d)}function N(){return d}function q(){d&&(d.destroy(),d=null);}var z={init:D,getInstance:N,resetInstance:q,WebPIHClient:_},Ht=z;
2
2
  exports.WebPIHClient=_;exports.default=Ht;exports.getInstance=N;exports.init=D;exports.resetInstance=q;//# sourceMappingURL=index.cjs.map
3
3
  //# sourceMappingURL=index.cjs.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../../sdk-core/src/errors.ts","../../sdk-core/src/utils.ts","../../sdk-core/src/identity.ts","../../sdk-core/src/session.ts","../../sdk-core/src/transport.ts","../../sdk-core/src/queue.ts","../../sdk-core/src/client.ts","../src/storage.ts","../src/autocapture.ts","../src/beacon.ts","../src/index.ts"],"names":["PIHError","_PIHError","message","code","details","__publicField","error","generateUUID","bytes","hex","b","c","r","getTimestamp","dateToTimestamp","date","getBackoffDelay","attempt","baseDelay","maxDelay","delay","STORAGE_PREFIX","STORAGE_KEYS","DEFAULTS","IdentityManager","storage","debug","storedAnonymousId","storedUserId","storedTraits","userId","traits","enabled","args","SessionManager","timeout","callbacks","storedSessionId","storedLastActivity","lastActivity","now","duration","endedSessionId","Transport","config","events","options","url","body","e","response","data","payload","tenantId","headers","blob","EventQueue","event","dropped","queuedEvent","batch","q","rejection","pihError","item","nextAttempt","backoff","stored","parsed","PIHClient","sessionId","eventName","properties","timestamp","MemoryStorage","key","value","isLocalStorageAvailable","testKey","LocalStorageAdapter","createWebStorage","UTM_STORAGE_KEY","UTM_PARAMS","Autocapture","client","utmParams","self","target","trackElement","elementTag","elementText","elementId","elementClasses","dataTrack","href","params","currentParams","BeaconManager","WebPIHClient","webConfig","instance","init","getInstance","resetInstance","PIH","index_default"],"mappings":"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","file":"index.cjs","sourcesContent":["/**\n * Error codes for PIH SDK errors\n */\nexport type PIHErrorCode =\n | \"NETWORK_ERROR\"\n | \"INVALID_CONFIG\"\n | \"QUEUE_FULL\"\n | \"RATE_LIMITED\"\n | \"INVALID_PAYLOAD\"\n | \"STORAGE_ERROR\"\n | \"SESSION_ERROR\"\n | \"UNKNOWN_ERROR\";\n\n/**\n * Custom error class for PIH SDK\n */\nexport class PIHError extends Error {\n /** Error code for programmatic handling */\n public readonly code: PIHErrorCode;\n /** Additional error details */\n public readonly details?: unknown;\n\n constructor(message: string, code: PIHErrorCode, details?: unknown) {\n super(message);\n this.name = \"PIHError\";\n this.code = code;\n this.details = details;\n\n // Maintains proper stack trace for where error was thrown (V8 only)\n if (Error.captureStackTrace) {\n Error.captureStackTrace(this, PIHError);\n }\n }\n\n /**\n * Create a network error\n */\n static networkError(message: string, details?: unknown): PIHError {\n return new PIHError(message, \"NETWORK_ERROR\", details);\n }\n\n /**\n * Create an invalid config error\n */\n static invalidConfig(message: string, details?: unknown): PIHError {\n return new PIHError(message, \"INVALID_CONFIG\", details);\n }\n\n /**\n * Create a queue full error\n */\n static queueFull(message: string, details?: unknown): PIHError {\n return new PIHError(message, \"QUEUE_FULL\", details);\n }\n\n /**\n * Create a rate limited error\n */\n static rateLimited(message: string, details?: unknown): PIHError {\n return new PIHError(message, \"RATE_LIMITED\", details);\n }\n\n /**\n * Create an invalid payload error\n */\n static invalidPayload(message: string, details?: unknown): PIHError {\n return new PIHError(message, \"INVALID_PAYLOAD\", details);\n }\n\n /**\n * Create a storage error\n */\n static storageError(message: string, details?: unknown): PIHError {\n return new PIHError(message, \"STORAGE_ERROR\", details);\n }\n\n /**\n * Create a session error\n */\n static sessionError(message: string, details?: unknown): PIHError {\n return new PIHError(message, \"SESSION_ERROR\", details);\n }\n\n /**\n * Convert unknown error to PIHError\n */\n static fromUnknown(error: unknown): PIHError {\n if (error instanceof PIHError) {\n return error;\n }\n if (error instanceof Error) {\n return new PIHError(error.message, \"UNKNOWN_ERROR\", error);\n }\n return new PIHError(String(error), \"UNKNOWN_ERROR\", error);\n }\n}\n","/**\n * Generate a UUID v4\n * Uses crypto.randomUUID if available, otherwise falls back to manual generation\n */\nexport function generateUUID(): string {\n // Use native crypto.randomUUID if available (modern browsers, Node.js 19+)\n if (\n typeof crypto !== \"undefined\" &&\n typeof crypto.randomUUID === \"function\"\n ) {\n return crypto.randomUUID();\n }\n\n // Fallback implementation using crypto.getRandomValues\n if (\n typeof crypto !== \"undefined\" &&\n typeof crypto.getRandomValues === \"function\"\n ) {\n const bytes = new Uint8Array(16);\n crypto.getRandomValues(bytes);\n\n // Set version (4) and variant (8, 9, A, or B)\n bytes[6] = (bytes[6]! & 0x0f) | 0x40;\n bytes[8] = (bytes[8]! & 0x3f) | 0x80;\n\n const hex = Array.from(bytes, (b) => b.toString(16).padStart(2, \"0\")).join(\n \"\"\n );\n\n return `${hex.slice(0, 8)}-${hex.slice(8, 12)}-${hex.slice(12, 16)}-${hex.slice(16, 20)}-${hex.slice(20)}`;\n }\n\n // Last resort fallback using Math.random (less secure but works everywhere)\n return \"xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx\".replace(/[xy]/g, (c) => {\n const r = (Math.random() * 16) | 0;\n const v = c === \"x\" ? r : (r & 0x3) | 0x8;\n return v.toString(16);\n });\n}\n\n/**\n * Get current timestamp in ISO 8601 UTC format\n */\nexport function getTimestamp(): string {\n return new Date().toISOString();\n}\n\n/**\n * Get timestamp from Date in ISO 8601 UTC format\n */\nexport function dateToTimestamp(date: Date): string {\n return date.toISOString();\n}\n\n/**\n * Calculate exponential backoff delay\n * @param attempt - Current attempt number (0-indexed)\n * @param baseDelay - Base delay in milliseconds (default: 1000)\n * @param maxDelay - Maximum delay in milliseconds (default: 16000)\n */\nexport function getBackoffDelay(\n attempt: number,\n baseDelay = 1000,\n maxDelay = 16000\n): number {\n const delay = baseDelay * Math.pow(2, attempt);\n return Math.min(delay, maxDelay);\n}\n\n/**\n * Check if a value is a plain object\n */\nexport function isPlainObject(value: unknown): value is Record<string, unknown> {\n if (value === null || typeof value !== \"object\") {\n return false;\n }\n const proto = Object.getPrototypeOf(value);\n return proto === Object.prototype || proto === null;\n}\n\n/**\n * Deep clone a value using JSON serialization\n * Note: Does not preserve functions, undefined, or special objects\n */\nexport function deepClone<T>(value: T): T {\n return JSON.parse(JSON.stringify(value));\n}\n\n/**\n * Merge two objects, with the second object's values taking precedence\n */\nexport function mergeObjects<T extends Record<string, unknown>>(\n target: T,\n source: Partial<T>\n): T {\n return { ...target, ...source };\n}\n\n/**\n * Create a debounced function\n */\nexport function debounce<T extends (...args: unknown[]) => void>(\n fn: T,\n delay: number\n): T {\n let timeoutId: ReturnType<typeof setTimeout> | null = null;\n\n return ((...args: unknown[]) => {\n if (timeoutId) {\n clearTimeout(timeoutId);\n }\n timeoutId = setTimeout(() => {\n fn(...args);\n timeoutId = null;\n }, delay);\n }) as T;\n}\n\n/**\n * Storage key prefix for all PIH SDK data\n */\nexport const STORAGE_PREFIX = \"pih_\";\n\n/**\n * Storage keys used by the SDK\n */\nexport const STORAGE_KEYS = {\n QUEUE: `${STORAGE_PREFIX}queue`,\n ANONYMOUS_ID: `${STORAGE_PREFIX}anonymous_id`,\n USER_ID: `${STORAGE_PREFIX}user_id`,\n USER_TRAITS: `${STORAGE_PREFIX}user_traits`,\n SESSION_ID: `${STORAGE_PREFIX}session_id`,\n SESSION_LAST_ACTIVITY: `${STORAGE_PREFIX}session_last_activity`,\n} as const;\n\n/**\n * Default configuration values\n */\nexport const DEFAULTS = {\n API_URL: \"https://repoingest-production.up.railway.app\",\n FLUSH_INTERVAL: 10000, // 10 seconds\n FLUSH_AT: 25, // events\n MAX_QUEUE_SIZE: 5000, // events\n SESSION_TIMEOUT: 1800000, // 30 minutes\n MAX_BATCH_SIZE: 100, // events per request\n MAX_RETRIES: 5,\n BASE_BACKOFF_DELAY: 1000, // 1 second\n MAX_BACKOFF_DELAY: 16000, // 16 seconds\n} as const;\n","import type { StorageAdapter } from \"./types.js\";\nimport { generateUUID, STORAGE_KEYS } from \"./utils.js\";\n\n/**\n * Identity manager for handling anonymous and user IDs\n */\nexport class IdentityManager {\n private anonymousId: string;\n private userId: string | null = null;\n private userTraits: Record<string, unknown> = {};\n private storage: StorageAdapter | null;\n private debug: boolean;\n\n constructor(storage: StorageAdapter | null, debug = false) {\n this.storage = storage;\n this.debug = debug;\n this.anonymousId = generateUUID();\n }\n\n /**\n * Initialize identity from storage\n */\n async initialize(): Promise<void> {\n if (!this.storage) {\n this.log(\"No storage adapter, using in-memory identity only\");\n return;\n }\n\n try {\n // Load anonymous ID\n const storedAnonymousId = await this.storage.get(\n STORAGE_KEYS.ANONYMOUS_ID\n );\n if (storedAnonymousId) {\n this.anonymousId = storedAnonymousId;\n this.log(\"Loaded anonymous ID from storage:\", this.anonymousId);\n } else {\n // Persist the generated anonymous ID\n await this.storage.set(STORAGE_KEYS.ANONYMOUS_ID, this.anonymousId);\n this.log(\"Generated new anonymous ID:\", this.anonymousId);\n }\n\n // Load user ID\n const storedUserId = await this.storage.get(STORAGE_KEYS.USER_ID);\n if (storedUserId) {\n this.userId = storedUserId;\n this.log(\"Loaded user ID from storage:\", this.userId);\n }\n\n // Load user traits\n const storedTraits = await this.storage.get(STORAGE_KEYS.USER_TRAITS);\n if (storedTraits) {\n try {\n this.userTraits = JSON.parse(storedTraits);\n this.log(\"Loaded user traits from storage:\", this.userTraits);\n } catch {\n this.log(\"Failed to parse stored user traits\");\n }\n }\n } catch (error) {\n this.log(\"Error loading identity from storage:\", error);\n }\n }\n\n /**\n * Get the anonymous ID\n */\n getAnonymousId(): string {\n return this.anonymousId;\n }\n\n /**\n * Get the user ID\n */\n getUserId(): string | null {\n return this.userId;\n }\n\n /**\n * Get user traits\n */\n getUserTraits(): Record<string, unknown> {\n return { ...this.userTraits };\n }\n\n /**\n * Set the user ID (identify the user)\n */\n async setUserId(userId: string): Promise<void> {\n this.userId = userId;\n this.log(\"Set user ID:\", userId);\n\n if (this.storage) {\n try {\n await this.storage.set(STORAGE_KEYS.USER_ID, userId);\n } catch (error) {\n this.log(\"Error persisting user ID:\", error);\n }\n }\n }\n\n /**\n * Set user traits\n */\n async setUserTraits(traits: Record<string, unknown>): Promise<void> {\n this.userTraits = { ...this.userTraits, ...traits };\n this.log(\"Set user traits:\", this.userTraits);\n\n if (this.storage) {\n try {\n await this.storage.set(\n STORAGE_KEYS.USER_TRAITS,\n JSON.stringify(this.userTraits)\n );\n } catch (error) {\n this.log(\"Error persisting user traits:\", error);\n }\n }\n }\n\n /**\n * Reset identity (logout)\n * Generates a new anonymous ID and clears user data\n */\n async reset(): Promise<void> {\n this.anonymousId = generateUUID();\n this.userId = null;\n this.userTraits = {};\n this.log(\"Identity reset, new anonymous ID:\", this.anonymousId);\n\n if (this.storage) {\n try {\n await Promise.all([\n this.storage.set(STORAGE_KEYS.ANONYMOUS_ID, this.anonymousId),\n this.storage.remove(STORAGE_KEYS.USER_ID),\n this.storage.remove(STORAGE_KEYS.USER_TRAITS),\n ]);\n } catch (error) {\n this.log(\"Error resetting identity in storage:\", error);\n }\n }\n }\n\n /**\n * Set debug mode\n */\n setDebug(enabled: boolean): void {\n this.debug = enabled;\n }\n\n private log(...args: unknown[]): void {\n if (this.debug) {\n console.log(\"[PIH Identity]\", ...args);\n }\n }\n}\n","import type { StorageAdapter } from \"./types.js\";\nimport { generateUUID, STORAGE_KEYS, DEFAULTS } from \"./utils.js\";\n\n/**\n * Callback for session events\n */\nexport interface SessionCallbacks {\n onSessionStart?: (sessionId: string) => void;\n onSessionEnd?: (sessionId: string, duration: number) => void;\n}\n\n/**\n * Session manager for handling session tracking\n */\nexport class SessionManager {\n private sessionId: string | null = null;\n private sessionStartTime: number = 0;\n private lastActivity: number = 0;\n private timeout: number;\n private storage: StorageAdapter | null;\n private callbacks: SessionCallbacks;\n private debug: boolean;\n\n constructor(\n storage: StorageAdapter | null,\n timeout: number = DEFAULTS.SESSION_TIMEOUT,\n callbacks: SessionCallbacks = {},\n debug = false\n ) {\n this.storage = storage;\n this.timeout = timeout;\n this.callbacks = callbacks;\n this.debug = debug;\n }\n\n /**\n * Initialize session from storage\n */\n async initialize(): Promise<void> {\n if (!this.storage) {\n this.log(\"No storage adapter, using in-memory session only\");\n return;\n }\n\n try {\n const storedSessionId = await this.storage.get(STORAGE_KEYS.SESSION_ID);\n const storedLastActivity = await this.storage.get(\n STORAGE_KEYS.SESSION_LAST_ACTIVITY\n );\n\n if (storedSessionId && storedLastActivity) {\n const lastActivity = parseInt(storedLastActivity, 10);\n const now = Date.now();\n\n // Check if session is still valid\n if (now - lastActivity < this.timeout) {\n this.sessionId = storedSessionId;\n this.lastActivity = lastActivity;\n this.sessionStartTime = lastActivity; // Approximate\n this.log(\"Restored session from storage:\", this.sessionId);\n } else {\n // Session expired, clear it\n this.log(\"Stored session expired, will start new session\");\n await this.clearStoredSession();\n }\n }\n } catch (error) {\n this.log(\"Error loading session from storage:\", error);\n }\n }\n\n /**\n * Get the current session ID\n * Creates a new session if needed or if the current one expired\n */\n getSessionId(): string {\n const now = Date.now();\n\n // Check if session expired\n if (this.sessionId && now - this.lastActivity > this.timeout) {\n this.endSession();\n }\n\n // Start new session if needed\n if (!this.sessionId) {\n this.startSession();\n }\n\n // Update last activity\n this.lastActivity = now;\n this.persistLastActivity();\n\n return this.sessionId!;\n }\n\n /**\n * Touch the session to update last activity\n * Call this on each track event\n */\n touch(): void {\n if (this.sessionId) {\n this.lastActivity = Date.now();\n this.persistLastActivity();\n }\n }\n\n /**\n * Check if there's an active session\n */\n hasActiveSession(): boolean {\n if (!this.sessionId) return false;\n return Date.now() - this.lastActivity < this.timeout;\n }\n\n /**\n * Get the current session ID without creating a new one\n */\n getCurrentSessionId(): string | null {\n return this.sessionId;\n }\n\n /**\n * Get session duration in milliseconds\n */\n getSessionDuration(): number {\n if (!this.sessionId) return 0;\n return Date.now() - this.sessionStartTime;\n }\n\n /**\n * Start a new session\n */\n startSession(): void {\n const now = Date.now();\n this.sessionId = generateUUID();\n this.sessionStartTime = now;\n this.lastActivity = now;\n\n this.log(\"Started new session:\", this.sessionId);\n this.persistSession();\n\n // Notify callback\n this.callbacks.onSessionStart?.(this.sessionId);\n }\n\n /**\n * End the current session\n */\n endSession(): void {\n if (!this.sessionId) return;\n\n const duration = this.getSessionDuration();\n const endedSessionId = this.sessionId;\n\n this.log(\"Ended session:\", endedSessionId, \"duration:\", duration);\n\n // Clear session\n this.sessionId = null;\n this.sessionStartTime = 0;\n this.lastActivity = 0;\n this.clearStoredSession();\n\n // Notify callback\n this.callbacks.onSessionEnd?.(endedSessionId, duration);\n }\n\n /**\n * Force end the session (for app background, page hide, etc.)\n */\n forceEndSession(): void {\n if (this.sessionId) {\n this.endSession();\n }\n }\n\n /**\n * Set debug mode\n */\n setDebug(enabled: boolean): void {\n this.debug = enabled;\n }\n\n /**\n * Set session timeout\n */\n setTimeout(timeout: number): void {\n this.timeout = timeout;\n }\n\n private async persistSession(): Promise<void> {\n if (!this.storage || !this.sessionId) return;\n\n try {\n await Promise.all([\n this.storage.set(STORAGE_KEYS.SESSION_ID, this.sessionId),\n this.storage.set(\n STORAGE_KEYS.SESSION_LAST_ACTIVITY,\n String(this.lastActivity)\n ),\n ]);\n } catch (error) {\n this.log(\"Error persisting session:\", error);\n }\n }\n\n private async persistLastActivity(): Promise<void> {\n if (!this.storage) return;\n\n try {\n await this.storage.set(\n STORAGE_KEYS.SESSION_LAST_ACTIVITY,\n String(this.lastActivity)\n );\n } catch (error) {\n this.log(\"Error persisting last activity:\", error);\n }\n }\n\n private async clearStoredSession(): Promise<void> {\n if (!this.storage) return;\n\n try {\n await Promise.all([\n this.storage.remove(STORAGE_KEYS.SESSION_ID),\n this.storage.remove(STORAGE_KEYS.SESSION_LAST_ACTIVITY),\n ]);\n } catch (error) {\n this.log(\"Error clearing stored session:\", error);\n }\n }\n\n private log(...args: unknown[]): void {\n if (this.debug) {\n console.log(\"[PIH Session]\", ...args);\n }\n }\n}\n","import type {\n TrackEvent,\n TrackResponse,\n IdentifyPayload,\n IdentifyResponse,\n TransportOptions,\n} from \"./types.js\";\nimport { PIHError } from \"./errors.js\";\n\n/**\n * Transport configuration\n */\nexport interface TransportConfig {\n /** API base URL */\n apiUrl: string;\n /** API key for authentication */\n apiKey: string;\n /** Tenant ID for multi-tenancy */\n tenantId?: string;\n /** Debug mode */\n debug?: boolean;\n}\n\n/**\n * HTTP transport for sending events to the ingest API\n */\nexport class Transport {\n private apiUrl: string;\n private apiKey: string;\n private tenantId?: string;\n private debug: boolean;\n\n constructor(config: TransportConfig) {\n this.apiUrl = config.apiUrl.replace(/\\/$/, \"\"); // Remove trailing slash\n this.apiKey = config.apiKey;\n this.tenantId = config.tenantId;\n this.debug = config.debug ?? false;\n }\n\n /**\n * Send a batch of events to the track endpoint\n */\n async sendEvents(\n events: TrackEvent[],\n options?: TransportOptions\n ): Promise<TrackResponse> {\n const url = `${this.apiUrl}/v1/track`;\n const body = JSON.stringify({ events });\n\n this.log(\"Sending\", events.length, \"events to\", url);\n\n // Try sendBeacon first if requested (for page hide scenarios)\n if (options?.useBeacon && typeof navigator !== \"undefined\" && typeof navigator.sendBeacon === \"function\") {\n const sent = this.sendViaBeacon(url, body);\n if (sent) {\n this.log(\"Events sent via sendBeacon\");\n // sendBeacon doesn't return response, assume success\n return {\n accepted: events.map((e) => ({\n event_id: e.event_id,\n timestamp: e.timestamp,\n })),\n rejected: [],\n stats: {\n received: events.length,\n accepted: events.length,\n rejected: 0,\n processing_time_ms: 0,\n },\n };\n }\n }\n\n // Standard fetch request\n try {\n const response = await this.fetch(url, {\n method: \"POST\",\n headers: this.getHeaders(),\n body,\n keepalive: options?.useBeacon, // Keep connection alive for page hide\n });\n\n if (!response.ok) {\n if (response.status === 429) {\n throw PIHError.rateLimited(\n `Rate limited: ${response.statusText}`,\n { status: response.status }\n );\n }\n throw PIHError.networkError(\n `HTTP ${response.status}: ${response.statusText}`,\n { status: response.status }\n );\n }\n\n const data = (await response.json()) as TrackResponse;\n this.log(\"Track response:\", data);\n return data;\n } catch (error) {\n if (error instanceof PIHError) {\n throw error;\n }\n throw PIHError.networkError(\n `Failed to send events: ${error instanceof Error ? error.message : String(error)}`,\n error\n );\n }\n }\n\n /**\n * Send an identify call\n */\n async sendIdentify(payload: IdentifyPayload): Promise<IdentifyResponse> {\n const url = `${this.apiUrl}/v1/identify`;\n const body = JSON.stringify(payload);\n\n this.log(\"Sending identify to\", url, payload);\n\n try {\n const response = await this.fetch(url, {\n method: \"POST\",\n headers: this.getHeaders(),\n body,\n });\n\n if (!response.ok) {\n if (response.status === 429) {\n throw PIHError.rateLimited(\n `Rate limited: ${response.statusText}`,\n { status: response.status }\n );\n }\n throw PIHError.networkError(\n `HTTP ${response.status}: ${response.statusText}`,\n { status: response.status }\n );\n }\n\n const data = (await response.json()) as IdentifyResponse;\n this.log(\"Identify response:\", data);\n return data;\n } catch (error) {\n if (error instanceof PIHError) {\n throw error;\n }\n throw PIHError.networkError(\n `Failed to send identify: ${error instanceof Error ? error.message : String(error)}`,\n error\n );\n }\n }\n\n /**\n * Set tenant ID\n */\n setTenantId(tenantId: string): void {\n this.tenantId = tenantId;\n }\n\n /**\n * Set debug mode\n */\n setDebug(enabled: boolean): void {\n this.debug = enabled;\n }\n\n private getHeaders(): Record<string, string> {\n const headers: Record<string, string> = {\n \"Content-Type\": \"application/json\",\n Authorization: `Bearer ${this.apiKey}`,\n };\n\n if (this.tenantId) {\n headers[\"X-Tenant-Id\"] = this.tenantId;\n }\n\n return headers;\n }\n\n private sendViaBeacon(url: string, body: string): boolean {\n try {\n // Create blob with proper content type\n const blob = new Blob([body], { type: \"application/json\" });\n return navigator.sendBeacon(url, blob);\n } catch (error) {\n this.log(\"sendBeacon failed:\", error);\n return false;\n }\n }\n\n private async fetch(\n url: string,\n options: RequestInit\n ): Promise<Response> {\n // Use native fetch\n if (typeof fetch !== \"undefined\") {\n return fetch(url, options);\n }\n\n // This shouldn't happen in modern environments, but throw a clear error\n throw PIHError.networkError(\n \"fetch is not available in this environment\"\n );\n }\n\n private log(...args: unknown[]): void {\n if (this.debug) {\n console.log(\"[PIH Transport]\", ...args);\n }\n }\n}\n","import type {\n TrackEvent,\n QueuedEvent,\n StorageAdapter,\n TransportOptions,\n} from \"./types.js\";\nimport type { Transport } from \"./transport.js\";\nimport { PIHError } from \"./errors.js\";\nimport { STORAGE_KEYS, DEFAULTS, getBackoffDelay } from \"./utils.js\";\n\n/**\n * Event queue configuration\n */\nexport interface EventQueueConfig {\n /** Events before auto-flush (default: 25) */\n flushAt: number;\n /** Milliseconds between auto-flushes (default: 10000) */\n flushInterval: number;\n /** Max queued events (default: 5000) */\n maxQueueSize: number;\n /** Storage adapter for persistence */\n storage: StorageAdapter | null;\n /** Transport for sending events */\n transport: Transport;\n /** Error callback */\n onError?: (error: PIHError, events: TrackEvent[]) => void;\n /** Debug mode */\n debug?: boolean;\n}\n\n/**\n * Event queue with persistence and retry logic\n */\nexport class EventQueue {\n private queue: QueuedEvent[] = [];\n private isFlushing = false;\n private flushTimer: ReturnType<typeof setInterval> | null = null;\n private retryTimer: ReturnType<typeof setTimeout> | null = null;\n private config: EventQueueConfig;\n private initialized = false;\n\n constructor(config: EventQueueConfig) {\n this.config = {\n flushAt: config.flushAt ?? DEFAULTS.FLUSH_AT,\n flushInterval: config.flushInterval ?? DEFAULTS.FLUSH_INTERVAL,\n maxQueueSize: config.maxQueueSize ?? DEFAULTS.MAX_QUEUE_SIZE,\n storage: config.storage,\n transport: config.transport,\n onError: config.onError,\n debug: config.debug ?? false,\n };\n }\n\n /**\n * Initialize the queue (load persisted events)\n */\n async initialize(): Promise<void> {\n if (this.initialized) return;\n\n await this.loadPersistedQueue();\n this.startFlushTimer();\n this.initialized = true;\n\n this.log(\"Queue initialized with\", this.queue.length, \"persisted events\");\n }\n\n /**\n * Add an event to the queue\n */\n async enqueue(event: TrackEvent): Promise<void> {\n // Enforce max queue size (drop oldest when full)\n while (this.queue.length >= this.config.maxQueueSize) {\n const dropped = this.queue.shift();\n if (dropped) {\n this.log(\"Queue full, dropping oldest event:\", dropped.event.event_id);\n this.config.onError?.(\n PIHError.queueFull(\"Queue full, dropped oldest event\", {\n dropped_event_id: dropped.event.event_id,\n }),\n [dropped.event]\n );\n }\n }\n\n // Add event to queue\n const queuedEvent: QueuedEvent = {\n event,\n attempts: 0,\n firstAttempt: Date.now(),\n };\n this.queue.push(queuedEvent);\n\n this.log(\"Enqueued event:\", event.event_id, \"Queue size:\", this.queue.length);\n\n // Persist queue\n await this.persistQueue();\n\n // Check if we should flush\n if (this.queue.length >= this.config.flushAt) {\n this.log(\"Queue reached flushAt threshold, flushing\");\n this.flush();\n }\n }\n\n /**\n * Flush the queue (send all events)\n */\n async flush(options?: TransportOptions): Promise<void> {\n if (this.isFlushing || this.queue.length === 0) {\n return;\n }\n\n this.isFlushing = true;\n this.log(\"Flushing\", this.queue.length, \"events\");\n\n try {\n // Take batch from queue (max 100 per request)\n const batch = this.queue.splice(0, DEFAULTS.MAX_BATCH_SIZE);\n const events = batch.map((q) => q.event);\n\n try {\n const response = await this.config.transport.sendEvents(events, options);\n\n // Handle rejections\n for (const rejection of response.rejected) {\n if (rejection.reason === \"rate_limited\") {\n // Re-queue rate limited events\n const queuedEvent = batch.find(\n (q) => q.event.event_id === rejection.event_id\n );\n if (queuedEvent && queuedEvent.attempts < DEFAULTS.MAX_RETRIES) {\n queuedEvent.attempts++;\n this.queue.unshift(queuedEvent);\n this.log(\n \"Rate limited event re-queued:\",\n rejection.event_id,\n \"attempt:\",\n queuedEvent.attempts\n );\n }\n } else {\n // Other rejections are permanent failures\n this.log(\n \"Event permanently rejected:\",\n rejection.event_id,\n rejection.reason,\n rejection.details\n );\n }\n }\n\n this.log(\n \"Flush complete. Accepted:\",\n response.stats.accepted,\n \"Rejected:\",\n response.stats.rejected\n );\n } catch (error) {\n const pihError = PIHError.fromUnknown(error);\n\n // Network error - re-queue all with backoff\n for (const item of batch) {\n if (item.attempts < DEFAULTS.MAX_RETRIES) {\n item.attempts++;\n this.queue.unshift(item);\n } else {\n this.log(\n \"Event dropped after max retries:\",\n item.event.event_id\n );\n }\n }\n\n // Schedule retry with backoff\n const nextAttempt = batch[0]?.attempts ?? 1;\n const backoff = getBackoffDelay(nextAttempt);\n this.log(\"Network error, scheduling retry in\", backoff, \"ms\");\n\n this.retryTimer = setTimeout(() => {\n this.retryTimer = null;\n this.flush(options);\n }, backoff);\n\n this.config.onError?.(pihError, events);\n }\n\n // Persist updated queue\n await this.persistQueue();\n\n // Continue flushing if there are more events\n if (this.queue.length >= this.config.flushAt) {\n // Use setImmediate/setTimeout to avoid blocking\n setTimeout(() => this.flush(options), 0);\n }\n } finally {\n this.isFlushing = false;\n }\n }\n\n /**\n * Get the current queue length\n */\n getQueueLength(): number {\n return this.queue.length;\n }\n\n /**\n * Check if the queue is empty\n */\n isEmpty(): boolean {\n return this.queue.length === 0;\n }\n\n /**\n * Check if queue is currently flushing\n */\n isBusy(): boolean {\n return this.isFlushing;\n }\n\n /**\n * Clear the queue\n */\n async clear(): Promise<void> {\n this.queue = [];\n await this.persistQueue();\n this.log(\"Queue cleared\");\n }\n\n /**\n * Stop the queue (cancel timers)\n */\n destroy(): void {\n if (this.flushTimer) {\n clearInterval(this.flushTimer);\n this.flushTimer = null;\n }\n if (this.retryTimer) {\n clearTimeout(this.retryTimer);\n this.retryTimer = null;\n }\n this.log(\"Queue destroyed\");\n }\n\n /**\n * Set debug mode\n */\n setDebug(enabled: boolean): void {\n this.config.debug = enabled;\n }\n\n private async persistQueue(): Promise<void> {\n if (!this.config.storage) return;\n\n try {\n await this.config.storage.set(\n STORAGE_KEYS.QUEUE,\n JSON.stringify(this.queue)\n );\n } catch (error) {\n this.log(\"Error persisting queue:\", error);\n }\n }\n\n private async loadPersistedQueue(): Promise<void> {\n if (!this.config.storage) return;\n\n try {\n const stored = await this.config.storage.get(STORAGE_KEYS.QUEUE);\n if (stored) {\n const parsed = JSON.parse(stored) as QueuedEvent[];\n // Validate parsed data\n if (Array.isArray(parsed)) {\n this.queue = parsed.filter(\n (item) =>\n item &&\n typeof item === \"object\" &&\n \"event\" in item &&\n \"attempts\" in item\n );\n }\n }\n } catch (error) {\n this.log(\"Error loading persisted queue:\", error);\n this.queue = [];\n }\n }\n\n private startFlushTimer(): void {\n if (this.flushTimer) return;\n\n this.flushTimer = setInterval(() => {\n if (this.queue.length > 0) {\n this.log(\"Flush timer triggered\");\n this.flush();\n }\n }, this.config.flushInterval);\n }\n\n private log(...args: unknown[]): void {\n if (this.config.debug) {\n console.log(\"[PIH Queue]\", ...args);\n }\n }\n}\n","import type {\n PIHConfig,\n TrackEvent,\n TrackOptions,\n StorageAdapter,\n TransportOptions,\n} from \"./types.js\";\nimport { PIHError } from \"./errors.js\";\nimport { IdentityManager } from \"./identity.js\";\nimport { SessionManager } from \"./session.js\";\nimport { Transport } from \"./transport.js\";\nimport { EventQueue } from \"./queue.js\";\nimport { generateUUID, getTimestamp, dateToTimestamp, DEFAULTS } from \"./utils.js\";\n\n/**\n * Base PIH client class\n * Platform-specific SDKs extend this class\n */\nexport class PIHClient {\n protected config: PIHConfig;\n protected storage: StorageAdapter | null = null;\n protected identity: IdentityManager;\n protected session: SessionManager;\n protected transport: Transport;\n protected queue: EventQueue;\n protected initialized = false;\n protected tenantId: string;\n\n constructor(config: PIHConfig, storage: StorageAdapter | null = null) {\n this.validateConfig(config);\n\n this.config = {\n apiUrl: DEFAULTS.API_URL,\n debug: false,\n flushInterval: DEFAULTS.FLUSH_INTERVAL,\n flushAt: DEFAULTS.FLUSH_AT,\n maxQueueSize: DEFAULTS.MAX_QUEUE_SIZE,\n sessionTimeout: DEFAULTS.SESSION_TIMEOUT,\n ...config,\n };\n\n this.storage = storage;\n this.tenantId = config.tenantId ?? \"\";\n\n // Initialize identity manager\n this.identity = new IdentityManager(storage, this.config.debug);\n\n // Initialize session manager\n this.session = new SessionManager(\n storage,\n this.config.sessionTimeout,\n {\n onSessionStart: (sessionId) => {\n this.log(\"Session started:\", sessionId);\n // Track session_started event\n this.trackInternal(\"session_started\", { session_id: sessionId });\n },\n onSessionEnd: (sessionId, duration) => {\n this.log(\"Session ended:\", sessionId, \"duration:\", duration);\n // Track session_ended event\n this.trackInternal(\"session_ended\", {\n session_id: sessionId,\n duration_ms: duration,\n });\n },\n },\n this.config.debug\n );\n\n // Initialize transport\n this.transport = new Transport({\n apiUrl: this.config.apiUrl!,\n apiKey: this.config.apiKey,\n tenantId: this.tenantId,\n debug: this.config.debug,\n });\n\n // Initialize queue\n this.queue = new EventQueue({\n flushAt: this.config.flushAt!,\n flushInterval: this.config.flushInterval!,\n maxQueueSize: this.config.maxQueueSize!,\n storage,\n transport: this.transport,\n onError: (error, events) => {\n this.config.onError?.(error);\n this.log(\"Queue error:\", error.message, \"events:\", events.length);\n },\n debug: this.config.debug,\n });\n }\n\n /**\n * Initialize the client (load persisted state)\n */\n async initialize(): Promise<void> {\n if (this.initialized) return;\n\n await Promise.all([\n this.identity.initialize(),\n this.session.initialize(),\n this.queue.initialize(),\n ]);\n\n this.initialized = true;\n this.log(\"Client initialized\");\n }\n\n /**\n * Set the tenant ID\n */\n setTenant(tenantId: string): void {\n this.tenantId = tenantId;\n this.transport.setTenantId(tenantId);\n this.log(\"Tenant set:\", tenantId);\n }\n\n /**\n * Identify the user\n */\n async identify(\n userId: string,\n traits?: Record<string, unknown>\n ): Promise<void> {\n await this.ensureInitialized();\n\n await this.identity.setUserId(userId);\n if (traits) {\n await this.identity.setUserTraits(traits);\n }\n\n // Send identify call to server\n try {\n await this.transport.sendIdentify({\n project_id: this.config.projectId,\n environment: this.config.environment,\n tenant_id: this.tenantId,\n anonymous_id: this.identity.getAnonymousId(),\n user_id: userId,\n traits,\n timestamp: getTimestamp(),\n });\n } catch (error) {\n const pihError = PIHError.fromUnknown(error);\n this.config.onError?.(pihError);\n this.log(\"Identify error:\", pihError.message);\n }\n }\n\n /**\n * Set user traits without identifying\n */\n async setUserTraits(traits: Record<string, unknown>): Promise<void> {\n await this.ensureInitialized();\n await this.identity.setUserTraits(traits);\n }\n\n /**\n * Track an event\n */\n async track(\n eventName: string,\n properties?: Record<string, unknown>,\n options?: TrackOptions\n ): Promise<void> {\n await this.ensureInitialized();\n\n const event = this.createEvent(eventName, properties, options);\n\n // Touch session to update last activity\n this.session.touch();\n\n if (options?.immediate) {\n // Send immediately, bypassing queue\n try {\n await this.transport.sendEvents([event]);\n } catch (error) {\n const pihError = PIHError.fromUnknown(error);\n this.config.onError?.(pihError);\n this.log(\"Immediate track error:\", pihError.message);\n }\n } else {\n // Add to queue\n await this.queue.enqueue(event);\n }\n }\n\n /**\n * Flush the event queue\n */\n async flush(options?: TransportOptions): Promise<void> {\n await this.ensureInitialized();\n await this.queue.flush(options);\n }\n\n /**\n * Reset identity (logout)\n */\n async reset(): Promise<void> {\n await this.ensureInitialized();\n\n // End current session\n this.session.forceEndSession();\n\n // Reset identity\n await this.identity.reset();\n\n this.log(\"Client reset\");\n }\n\n /**\n * Enable/disable debug mode\n */\n setDebug(enabled: boolean): void {\n this.config.debug = enabled;\n this.identity.setDebug(enabled);\n this.session.setDebug(enabled);\n this.transport.setDebug(enabled);\n this.queue.setDebug(enabled);\n }\n\n /**\n * Get the anonymous ID\n */\n getAnonymousId(): string {\n return this.identity.getAnonymousId();\n }\n\n /**\n * Get the user ID\n */\n getUserId(): string | null {\n return this.identity.getUserId();\n }\n\n /**\n * Get the session ID\n */\n getSessionId(): string | null {\n return this.session.getCurrentSessionId();\n }\n\n /**\n * Get the queue length\n */\n getQueueLength(): number {\n return this.queue.getQueueLength();\n }\n\n /**\n * Destroy the client (cleanup)\n */\n destroy(): void {\n this.queue.destroy();\n this.log(\"Client destroyed\");\n }\n\n /**\n * Internal track method that doesn't require initialization\n * Used for session events during initialization\n */\n protected trackInternal(\n eventName: string,\n properties?: Record<string, unknown>\n ): void {\n const event = this.createEvent(eventName, properties);\n // Fire and forget - don't await\n this.queue.enqueue(event).catch((error) => {\n this.log(\"Internal track error:\", error);\n });\n }\n\n /**\n * Create a track event\n */\n protected createEvent(\n eventName: string,\n properties?: Record<string, unknown>,\n options?: TrackOptions\n ): TrackEvent {\n const timestamp = options?.timestamp\n ? dateToTimestamp(options.timestamp)\n : getTimestamp();\n\n return {\n event_id: generateUUID(),\n timestamp,\n project_id: this.config.projectId,\n environment: this.config.environment,\n tenant_id: this.tenantId,\n event_name: eventName,\n anonymous_id: this.identity.getAnonymousId(),\n user_id: this.identity.getUserId(),\n session_id: this.session.getSessionId(),\n platform: this.config.platform,\n app_version: this.config.appVersion ?? null,\n properties: properties ?? {},\n user_traits: this.identity.getUserTraits(),\n };\n }\n\n /**\n * Ensure client is initialized\n */\n protected async ensureInitialized(): Promise<void> {\n if (!this.initialized) {\n await this.initialize();\n }\n }\n\n /**\n * Validate configuration\n */\n protected validateConfig(config: PIHConfig): void {\n if (!config.apiKey) {\n throw PIHError.invalidConfig(\"apiKey is required\");\n }\n if (!config.projectId) {\n throw PIHError.invalidConfig(\"projectId is required\");\n }\n if (!config.environment) {\n throw PIHError.invalidConfig(\"environment is required\");\n }\n if (!config.platform) {\n throw PIHError.invalidConfig(\"platform is required\");\n }\n }\n\n protected log(...args: unknown[]): void {\n if (this.config.debug) {\n console.log(\"[PIH Client]\", ...args);\n }\n }\n}\n","import type { StorageAdapter } from \"@product-intelligence-hub/sdk-core\";\n\n/**\n * In-memory storage fallback when localStorage is unavailable\n */\nclass MemoryStorage implements StorageAdapter {\n private data = new Map<string, string>();\n\n async get(key: string): Promise<string | null> {\n return this.data.get(key) ?? null;\n }\n\n async set(key: string, value: string): Promise<void> {\n this.data.set(key, value);\n }\n\n async remove(key: string): Promise<void> {\n this.data.delete(key);\n }\n}\n\n/**\n * Check if localStorage is available\n */\nfunction isLocalStorageAvailable(): boolean {\n try {\n const testKey = \"__pih_test__\";\n localStorage.setItem(testKey, testKey);\n localStorage.removeItem(testKey);\n return true;\n } catch {\n return false;\n }\n}\n\n/**\n * localStorage adapter with fallback to in-memory storage\n */\nclass LocalStorageAdapter implements StorageAdapter {\n private fallback: MemoryStorage | null = null;\n private useLocalStorage: boolean;\n\n constructor() {\n this.useLocalStorage = isLocalStorageAvailable();\n if (!this.useLocalStorage) {\n this.fallback = new MemoryStorage();\n console.warn(\n \"[PIH] localStorage unavailable, using in-memory storage. Data will not persist across page loads.\"\n );\n }\n }\n\n async get(key: string): Promise<string | null> {\n if (this.fallback) {\n return this.fallback.get(key);\n }\n\n try {\n return localStorage.getItem(key);\n } catch {\n // localStorage access might fail in some contexts\n if (!this.fallback) {\n this.fallback = new MemoryStorage();\n }\n return this.fallback.get(key);\n }\n }\n\n async set(key: string, value: string): Promise<void> {\n if (this.fallback) {\n return this.fallback.set(key, value);\n }\n\n try {\n localStorage.setItem(key, value);\n } catch (error) {\n // Handle quota exceeded or other errors\n if (!this.fallback) {\n this.fallback = new MemoryStorage();\n console.warn(\n \"[PIH] localStorage write failed, falling back to in-memory storage:\",\n error\n );\n }\n return this.fallback.set(key, value);\n }\n }\n\n async remove(key: string): Promise<void> {\n if (this.fallback) {\n return this.fallback.remove(key);\n }\n\n try {\n localStorage.removeItem(key);\n } catch {\n // Ignore removal errors\n }\n }\n}\n\n/**\n * Create the web storage adapter\n */\nexport function createWebStorage(): StorageAdapter {\n return new LocalStorageAdapter();\n}\n\n/**\n * Export the storage adapter singleton\n */\nexport const webStorage = createWebStorage();\n","import type { PIHClient, AutocaptureConfig } from \"@product-intelligence-hub/sdk-core\";\n\n/**\n * UTM parameter storage key\n */\nconst UTM_STORAGE_KEY = \"pih_utm_params\";\n\n/**\n * UTM parameter names\n */\nconst UTM_PARAMS = [\n \"utm_source\",\n \"utm_medium\",\n \"utm_campaign\",\n \"utm_term\",\n \"utm_content\",\n] as const;\n\n/**\n * Autocapture manager for web SDK\n */\nexport class Autocapture {\n private client: PIHClient;\n private config: AutocaptureConfig;\n private cachedUtmParams: Record<string, string> | null = null;\n private originalPushState: typeof history.pushState | null = null;\n private originalReplaceState: typeof history.replaceState | null = null;\n private boundHandleClick: (e: MouseEvent) => void;\n private boundHandlePopState: () => void;\n\n constructor(client: PIHClient, config: AutocaptureConfig = {}) {\n this.client = client;\n this.config = {\n pageViews: config.pageViews !== false, // default: true\n clicks: config.clicks ?? false, // default: false\n clickSelector: config.clickSelector ?? \"[data-track]\",\n forms: config.forms ?? false, // default: false\n };\n\n this.boundHandleClick = this.handleClick.bind(this);\n this.boundHandlePopState = this.handlePopState.bind(this);\n }\n\n /**\n * Start autocapture\n */\n start(): void {\n if (typeof window === \"undefined\" || typeof document === \"undefined\") {\n return;\n }\n\n // Load cached UTM params\n this.loadCachedUtmParams();\n\n // Setup page view tracking\n if (this.config.pageViews) {\n this.setupPageViews();\n // Track initial page view\n this.trackPageView();\n }\n\n // Setup click tracking\n if (this.config.clicks) {\n this.setupClickTracking();\n }\n }\n\n /**\n * Stop autocapture\n */\n stop(): void {\n // Restore original history methods\n if (this.originalPushState) {\n history.pushState = this.originalPushState;\n this.originalPushState = null;\n }\n if (this.originalReplaceState) {\n history.replaceState = this.originalReplaceState;\n this.originalReplaceState = null;\n }\n\n // Remove event listeners\n if (typeof window !== \"undefined\") {\n window.removeEventListener(\"popstate\", this.boundHandlePopState);\n }\n if (typeof document !== \"undefined\") {\n document.removeEventListener(\"click\", this.boundHandleClick, true);\n }\n }\n\n /**\n * Manually track a page view\n */\n trackPageView(): void {\n const url = new URL(window.location.href);\n const utmParams = this.extractUtmParams(url);\n\n // Cache UTM params on first page view with UTM\n if (Object.keys(utmParams).length > 0 && !this.cachedUtmParams) {\n this.cachedUtmParams = utmParams;\n this.persistUtmParams(utmParams);\n }\n\n this.client.track(\"page_viewed\", {\n path: url.pathname,\n search: url.search,\n hash: url.hash,\n referrer: document.referrer || null,\n title: document.title,\n url: window.location.href,\n // Include UTM params (from current URL or cached)\n ...this.getUtmParams(url),\n });\n }\n\n /**\n * Setup page view tracking\n */\n private setupPageViews(): void {\n // Monkey-patch History API for SPA navigation\n this.originalPushState = history.pushState;\n this.originalReplaceState = history.replaceState;\n\n const self = this;\n\n history.pushState = function (...args) {\n self.originalPushState!.apply(history, args);\n // Use setTimeout to ensure URL has been updated\n setTimeout(() => self.trackPageView(), 0);\n };\n\n history.replaceState = function (...args) {\n self.originalReplaceState!.apply(history, args);\n // Use setTimeout to ensure URL has been updated\n setTimeout(() => self.trackPageView(), 0);\n };\n\n // Listen for popstate (back/forward navigation)\n window.addEventListener(\"popstate\", this.boundHandlePopState);\n }\n\n /**\n * Handle popstate event\n */\n private handlePopState(): void {\n this.trackPageView();\n }\n\n /**\n * Setup click tracking\n */\n private setupClickTracking(): void {\n document.addEventListener(\"click\", this.boundHandleClick, true);\n }\n\n /**\n * Handle click event\n */\n private handleClick(event: MouseEvent): void {\n const target = event.target as Element | null;\n if (!target) return;\n\n // Find the closest element matching the selector\n const trackElement = target.closest(this.config.clickSelector!);\n if (!trackElement) return;\n\n // Get element properties\n const elementTag = trackElement.tagName.toLowerCase();\n const elementText = (trackElement.textContent || \"\").trim().slice(0, 100);\n const elementId = trackElement.id || null;\n const elementClasses = trackElement.className || null;\n const dataTrack = trackElement.getAttribute(\"data-track\");\n const href =\n trackElement instanceof HTMLAnchorElement ? trackElement.href : null;\n\n this.client.track(\"element_clicked\", {\n element_tag: elementTag,\n element_text: elementText,\n element_id: elementId,\n element_classes: elementClasses,\n data_track: dataTrack,\n href,\n path: window.location.pathname,\n });\n }\n\n /**\n * Extract UTM parameters from URL\n */\n private extractUtmParams(url: URL): Record<string, string> {\n const params: Record<string, string> = {};\n for (const key of UTM_PARAMS) {\n const value = url.searchParams.get(key);\n if (value) {\n params[key] = value;\n }\n }\n return params;\n }\n\n /**\n * Get UTM parameters (current URL or cached)\n */\n private getUtmParams(url: URL): Record<string, string> {\n // First check current URL\n const currentParams = this.extractUtmParams(url);\n if (Object.keys(currentParams).length > 0) {\n return currentParams;\n }\n\n // Fall back to cached params\n return this.cachedUtmParams ?? {};\n }\n\n /**\n * Load cached UTM params from storage\n */\n private loadCachedUtmParams(): void {\n try {\n const stored = localStorage.getItem(UTM_STORAGE_KEY);\n if (stored) {\n this.cachedUtmParams = JSON.parse(stored);\n }\n } catch {\n // Ignore storage errors\n }\n }\n\n /**\n * Persist UTM params to storage\n */\n private persistUtmParams(params: Record<string, string>): void {\n try {\n localStorage.setItem(UTM_STORAGE_KEY, JSON.stringify(params));\n } catch {\n // Ignore storage errors\n }\n }\n}\n","import type { PIHClient } from \"@product-intelligence-hub/sdk-core\";\n\n/**\n * Beacon manager for flushing events on page hide\n */\nexport class BeaconManager {\n private client: PIHClient;\n private boundHandleVisibilityChange: () => void;\n private boundHandleBeforeUnload: () => void;\n\n constructor(client: PIHClient) {\n this.client = client;\n this.boundHandleVisibilityChange = this.handleVisibilityChange.bind(this);\n this.boundHandleBeforeUnload = this.handleBeforeUnload.bind(this);\n }\n\n /**\n * Start listening for visibility and unload events\n */\n start(): void {\n if (typeof document !== \"undefined\") {\n document.addEventListener(\n \"visibilitychange\",\n this.boundHandleVisibilityChange\n );\n }\n\n if (typeof window !== \"undefined\") {\n window.addEventListener(\"beforeunload\", this.boundHandleBeforeUnload);\n // Also listen for pagehide which is more reliable on mobile\n window.addEventListener(\"pagehide\", this.boundHandleBeforeUnload);\n }\n }\n\n /**\n * Stop listening for events\n */\n stop(): void {\n if (typeof document !== \"undefined\") {\n document.removeEventListener(\n \"visibilitychange\",\n this.boundHandleVisibilityChange\n );\n }\n\n if (typeof window !== \"undefined\") {\n window.removeEventListener(\"beforeunload\", this.boundHandleBeforeUnload);\n window.removeEventListener(\"pagehide\", this.boundHandleBeforeUnload);\n }\n }\n\n /**\n * Handle visibility change\n */\n private handleVisibilityChange(): void {\n if (document.visibilityState === \"hidden\") {\n this.flushWithBeacon();\n }\n }\n\n /**\n * Handle before unload\n */\n private handleBeforeUnload(): void {\n this.flushWithBeacon();\n }\n\n /**\n * Flush events using sendBeacon\n */\n private flushWithBeacon(): void {\n // Use sendBeacon for reliability when page is closing\n this.client.flush({ useBeacon: true }).catch(() => {\n // Ignore errors during page unload\n });\n }\n}\n\n/**\n * Check if sendBeacon is available\n */\nexport function isSendBeaconAvailable(): boolean {\n return (\n typeof navigator !== \"undefined\" &&\n typeof navigator.sendBeacon === \"function\"\n );\n}\n","import {\n PIHClient,\n type PIHConfig,\n type TrackOptions,\n type TransportOptions,\n type StorageAdapter,\n} from \"@product-intelligence-hub/sdk-core\";\nimport { createWebStorage } from \"./storage.js\";\nimport { Autocapture } from \"./autocapture.js\";\nimport { BeaconManager } from \"./beacon.js\";\n\n/**\n * Web-specific PIH configuration\n */\nexport interface WebPIHConfig extends Omit<PIHConfig, \"platform\"> {\n /** Platform is always \"web\" for web SDK */\n platform?: \"web\";\n}\n\n/**\n * Web PIH Client\n * Extends the base client with web-specific features\n */\nexport class WebPIHClient extends PIHClient {\n private autocapture: Autocapture | null = null;\n private beacon: BeaconManager;\n\n constructor(config: WebPIHConfig, storage?: StorageAdapter) {\n // Ensure platform is set to \"web\"\n const webConfig: PIHConfig = {\n ...config,\n platform: \"web\",\n };\n\n // Use provided storage or create web storage\n super(webConfig, storage ?? createWebStorage());\n\n // Setup beacon manager for flush on page hide\n this.beacon = new BeaconManager(this);\n }\n\n /**\n * Initialize the web client\n */\n override async initialize(): Promise<void> {\n await super.initialize();\n\n // Start beacon manager\n this.beacon.start();\n\n // Setup autocapture if configured\n if (this.config.autocapture) {\n this.autocapture = new Autocapture(this, this.config.autocapture);\n this.autocapture.start();\n }\n\n this.log(\"Web client initialized\");\n }\n\n /**\n * Enable autocapture after initialization\n */\n enableAutocapture(config?: PIHConfig[\"autocapture\"]): void {\n if (this.autocapture) {\n this.autocapture.stop();\n }\n this.autocapture = new Autocapture(this, config);\n this.autocapture.start();\n }\n\n /**\n * Disable autocapture\n */\n disableAutocapture(): void {\n if (this.autocapture) {\n this.autocapture.stop();\n this.autocapture = null;\n }\n }\n\n /**\n * Manually track a page view\n */\n trackPageView(): void {\n if (this.autocapture) {\n this.autocapture.trackPageView();\n } else {\n // Track page view without autocapture\n const url = new URL(window.location.href);\n this.track(\"page_viewed\", {\n path: url.pathname,\n search: url.search,\n hash: url.hash,\n referrer: document.referrer || null,\n title: document.title,\n url: window.location.href,\n });\n }\n }\n\n /**\n * Destroy the client\n */\n override destroy(): void {\n this.beacon.stop();\n if (this.autocapture) {\n this.autocapture.stop();\n }\n super.destroy();\n }\n\n protected override log(...args: unknown[]): void {\n if (this.config.debug) {\n console.log(\"[PIH Web]\", ...args);\n }\n }\n}\n\n/**\n * Singleton instance\n */\nlet instance: WebPIHClient | null = null;\n\n/**\n * Initialize the PIH Web SDK\n */\nfunction init(config: WebPIHConfig): WebPIHClient {\n if (instance) {\n console.warn(\"[PIH] SDK already initialized. Returning existing instance.\");\n return instance;\n }\n\n instance = new WebPIHClient(config);\n\n // Auto-initialize\n instance.initialize().catch((error) => {\n console.error(\"[PIH] Failed to initialize:\", error);\n });\n\n return instance;\n}\n\n/**\n * Get the current instance\n */\nfunction getInstance(): WebPIHClient | null {\n return instance;\n}\n\n/**\n * Reset the singleton (for testing)\n */\nfunction resetInstance(): void {\n if (instance) {\n instance.destroy();\n instance = null;\n }\n}\n\n// Default export for UMD/IIFE\nconst PIH = {\n init,\n getInstance,\n resetInstance,\n WebPIHClient,\n};\n\nexport default PIH;\nexport { init, getInstance, resetInstance };\n\n// Re-export types from core\nexport type {\n PIHConfig,\n TrackEvent,\n TrackOptions,\n TransportOptions,\n AutocaptureConfig,\n PIHError,\n PIHErrorCode,\n} from \"@product-intelligence-hub/sdk-core\";\n"]}
1
+ {"version":3,"sources":["../../sdk-core/src/errors.ts","../../sdk-core/src/utils.ts","../../sdk-core/src/identity.ts","../../sdk-core/src/session.ts","../../sdk-core/src/transport.ts","../../sdk-core/src/queue.ts","../../sdk-core/src/client.ts","../src/storage.ts","../src/autocapture.ts","../src/beacon.ts","../src/index.ts"],"names":["PIHError","_PIHError","message","code","details","__publicField","error","generateUUID","bytes","hex","b","c","r","getTimestamp","dateToTimestamp","date","getBackoffDelay","attempt","baseDelay","maxDelay","delay","STORAGE_PREFIX","STORAGE_KEYS","DEFAULTS","IdentityManager","storage","debug","storedAnonymousId","storedUserId","storedTraits","userId","traits","enabled","args","SessionManager","timeout","callbacks","storedSessionId","storedLastActivity","lastActivity","now","duration","endedSessionId","Transport","config","events","options","url","apiEvents","e","body","response","data","payload","tenantId","headers","event","blob","EventQueue","dropped","queuedEvent","batch","q","rejection","pihError","item","nextAttempt","backoff","stored","parsed","PIHClient","sessionId","eventName","properties","timestamp","MemoryStorage","key","value","isLocalStorageAvailable","testKey","LocalStorageAdapter","createWebStorage","UTM_STORAGE_KEY","UTM_PARAMS","Autocapture","client","utmParams","self","target","trackElement","elementTag","elementText","elementId","elementClasses","dataTrack","href","params","currentParams","BeaconManager","WebPIHClient","webConfig","instance","init","getInstance","resetInstance","PIH","index_default"],"mappings":"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","file":"index.cjs","sourcesContent":["/**\n * Error codes for PIH SDK errors\n */\nexport type PIHErrorCode =\n | \"NETWORK_ERROR\"\n | \"INVALID_CONFIG\"\n | \"QUEUE_FULL\"\n | \"RATE_LIMITED\"\n | \"INVALID_PAYLOAD\"\n | \"STORAGE_ERROR\"\n | \"SESSION_ERROR\"\n | \"UNKNOWN_ERROR\";\n\n/**\n * Custom error class for PIH SDK\n */\nexport class PIHError extends Error {\n /** Error code for programmatic handling */\n public readonly code: PIHErrorCode;\n /** Additional error details */\n public readonly details?: unknown;\n\n constructor(message: string, code: PIHErrorCode, details?: unknown) {\n super(message);\n this.name = \"PIHError\";\n this.code = code;\n this.details = details;\n\n // Maintains proper stack trace for where error was thrown (V8 only)\n if (Error.captureStackTrace) {\n Error.captureStackTrace(this, PIHError);\n }\n }\n\n /**\n * Create a network error\n */\n static networkError(message: string, details?: unknown): PIHError {\n return new PIHError(message, \"NETWORK_ERROR\", details);\n }\n\n /**\n * Create an invalid config error\n */\n static invalidConfig(message: string, details?: unknown): PIHError {\n return new PIHError(message, \"INVALID_CONFIG\", details);\n }\n\n /**\n * Create a queue full error\n */\n static queueFull(message: string, details?: unknown): PIHError {\n return new PIHError(message, \"QUEUE_FULL\", details);\n }\n\n /**\n * Create a rate limited error\n */\n static rateLimited(message: string, details?: unknown): PIHError {\n return new PIHError(message, \"RATE_LIMITED\", details);\n }\n\n /**\n * Create an invalid payload error\n */\n static invalidPayload(message: string, details?: unknown): PIHError {\n return new PIHError(message, \"INVALID_PAYLOAD\", details);\n }\n\n /**\n * Create a storage error\n */\n static storageError(message: string, details?: unknown): PIHError {\n return new PIHError(message, \"STORAGE_ERROR\", details);\n }\n\n /**\n * Create a session error\n */\n static sessionError(message: string, details?: unknown): PIHError {\n return new PIHError(message, \"SESSION_ERROR\", details);\n }\n\n /**\n * Convert unknown error to PIHError\n */\n static fromUnknown(error: unknown): PIHError {\n if (error instanceof PIHError) {\n return error;\n }\n if (error instanceof Error) {\n return new PIHError(error.message, \"UNKNOWN_ERROR\", error);\n }\n return new PIHError(String(error), \"UNKNOWN_ERROR\", error);\n }\n}\n","/**\n * Generate a UUID v4\n * Uses crypto.randomUUID if available, otherwise falls back to manual generation\n */\nexport function generateUUID(): string {\n // Use native crypto.randomUUID if available (modern browsers, Node.js 19+)\n if (\n typeof crypto !== \"undefined\" &&\n typeof crypto.randomUUID === \"function\"\n ) {\n return crypto.randomUUID();\n }\n\n // Fallback implementation using crypto.getRandomValues\n if (\n typeof crypto !== \"undefined\" &&\n typeof crypto.getRandomValues === \"function\"\n ) {\n const bytes = new Uint8Array(16);\n crypto.getRandomValues(bytes);\n\n // Set version (4) and variant (8, 9, A, or B)\n bytes[6] = (bytes[6]! & 0x0f) | 0x40;\n bytes[8] = (bytes[8]! & 0x3f) | 0x80;\n\n const hex = Array.from(bytes, (b) => b.toString(16).padStart(2, \"0\")).join(\n \"\"\n );\n\n return `${hex.slice(0, 8)}-${hex.slice(8, 12)}-${hex.slice(12, 16)}-${hex.slice(16, 20)}-${hex.slice(20)}`;\n }\n\n // Last resort fallback using Math.random (less secure but works everywhere)\n return \"xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx\".replace(/[xy]/g, (c) => {\n const r = (Math.random() * 16) | 0;\n const v = c === \"x\" ? r : (r & 0x3) | 0x8;\n return v.toString(16);\n });\n}\n\n/**\n * Get current timestamp in ISO 8601 UTC format\n */\nexport function getTimestamp(): string {\n return new Date().toISOString();\n}\n\n/**\n * Get timestamp from Date in ISO 8601 UTC format\n */\nexport function dateToTimestamp(date: Date): string {\n return date.toISOString();\n}\n\n/**\n * Calculate exponential backoff delay\n * @param attempt - Current attempt number (0-indexed)\n * @param baseDelay - Base delay in milliseconds (default: 1000)\n * @param maxDelay - Maximum delay in milliseconds (default: 16000)\n */\nexport function getBackoffDelay(\n attempt: number,\n baseDelay = 1000,\n maxDelay = 16000\n): number {\n const delay = baseDelay * Math.pow(2, attempt);\n return Math.min(delay, maxDelay);\n}\n\n/**\n * Check if a value is a plain object\n */\nexport function isPlainObject(value: unknown): value is Record<string, unknown> {\n if (value === null || typeof value !== \"object\") {\n return false;\n }\n const proto = Object.getPrototypeOf(value);\n return proto === Object.prototype || proto === null;\n}\n\n/**\n * Deep clone a value using JSON serialization\n * Note: Does not preserve functions, undefined, or special objects\n */\nexport function deepClone<T>(value: T): T {\n return JSON.parse(JSON.stringify(value));\n}\n\n/**\n * Merge two objects, with the second object's values taking precedence\n */\nexport function mergeObjects<T extends Record<string, unknown>>(\n target: T,\n source: Partial<T>\n): T {\n return { ...target, ...source };\n}\n\n/**\n * Create a debounced function\n */\nexport function debounce<T extends (...args: unknown[]) => void>(\n fn: T,\n delay: number\n): T {\n let timeoutId: ReturnType<typeof setTimeout> | null = null;\n\n return ((...args: unknown[]) => {\n if (timeoutId) {\n clearTimeout(timeoutId);\n }\n timeoutId = setTimeout(() => {\n fn(...args);\n timeoutId = null;\n }, delay);\n }) as T;\n}\n\n/**\n * Storage key prefix for all PIH SDK data\n */\nexport const STORAGE_PREFIX = \"pih_\";\n\n/**\n * Storage keys used by the SDK\n */\nexport const STORAGE_KEYS = {\n QUEUE: `${STORAGE_PREFIX}queue`,\n ANONYMOUS_ID: `${STORAGE_PREFIX}anonymous_id`,\n USER_ID: `${STORAGE_PREFIX}user_id`,\n USER_TRAITS: `${STORAGE_PREFIX}user_traits`,\n SESSION_ID: `${STORAGE_PREFIX}session_id`,\n SESSION_LAST_ACTIVITY: `${STORAGE_PREFIX}session_last_activity`,\n} as const;\n\n/**\n * Default configuration values\n */\nexport const DEFAULTS = {\n API_URL: \"https://repoingest-production.up.railway.app\",\n FLUSH_INTERVAL: 10000, // 10 seconds\n FLUSH_AT: 25, // events\n MAX_QUEUE_SIZE: 5000, // events\n SESSION_TIMEOUT: 1800000, // 30 minutes\n MAX_BATCH_SIZE: 100, // events per request\n MAX_RETRIES: 5,\n BASE_BACKOFF_DELAY: 1000, // 1 second\n MAX_BACKOFF_DELAY: 16000, // 16 seconds\n} as const;\n","import type { StorageAdapter } from \"./types.js\";\nimport { generateUUID, STORAGE_KEYS } from \"./utils.js\";\n\n/**\n * Identity manager for handling anonymous and user IDs\n */\nexport class IdentityManager {\n private anonymousId: string;\n private userId: string | null = null;\n private userTraits: Record<string, unknown> = {};\n private storage: StorageAdapter | null;\n private debug: boolean;\n\n constructor(storage: StorageAdapter | null, debug = false) {\n this.storage = storage;\n this.debug = debug;\n this.anonymousId = generateUUID();\n }\n\n /**\n * Initialize identity from storage\n */\n async initialize(): Promise<void> {\n if (!this.storage) {\n this.log(\"No storage adapter, using in-memory identity only\");\n return;\n }\n\n try {\n // Load anonymous ID\n const storedAnonymousId = await this.storage.get(\n STORAGE_KEYS.ANONYMOUS_ID\n );\n if (storedAnonymousId) {\n this.anonymousId = storedAnonymousId;\n this.log(\"Loaded anonymous ID from storage:\", this.anonymousId);\n } else {\n // Persist the generated anonymous ID\n await this.storage.set(STORAGE_KEYS.ANONYMOUS_ID, this.anonymousId);\n this.log(\"Generated new anonymous ID:\", this.anonymousId);\n }\n\n // Load user ID\n const storedUserId = await this.storage.get(STORAGE_KEYS.USER_ID);\n if (storedUserId) {\n this.userId = storedUserId;\n this.log(\"Loaded user ID from storage:\", this.userId);\n }\n\n // Load user traits\n const storedTraits = await this.storage.get(STORAGE_KEYS.USER_TRAITS);\n if (storedTraits) {\n try {\n this.userTraits = JSON.parse(storedTraits);\n this.log(\"Loaded user traits from storage:\", this.userTraits);\n } catch {\n this.log(\"Failed to parse stored user traits\");\n }\n }\n } catch (error) {\n this.log(\"Error loading identity from storage:\", error);\n }\n }\n\n /**\n * Get the anonymous ID\n */\n getAnonymousId(): string {\n return this.anonymousId;\n }\n\n /**\n * Get the user ID\n */\n getUserId(): string | null {\n return this.userId;\n }\n\n /**\n * Get user traits\n */\n getUserTraits(): Record<string, unknown> {\n return { ...this.userTraits };\n }\n\n /**\n * Set the user ID (identify the user)\n */\n async setUserId(userId: string): Promise<void> {\n this.userId = userId;\n this.log(\"Set user ID:\", userId);\n\n if (this.storage) {\n try {\n await this.storage.set(STORAGE_KEYS.USER_ID, userId);\n } catch (error) {\n this.log(\"Error persisting user ID:\", error);\n }\n }\n }\n\n /**\n * Set user traits\n */\n async setUserTraits(traits: Record<string, unknown>): Promise<void> {\n this.userTraits = { ...this.userTraits, ...traits };\n this.log(\"Set user traits:\", this.userTraits);\n\n if (this.storage) {\n try {\n await this.storage.set(\n STORAGE_KEYS.USER_TRAITS,\n JSON.stringify(this.userTraits)\n );\n } catch (error) {\n this.log(\"Error persisting user traits:\", error);\n }\n }\n }\n\n /**\n * Reset identity (logout)\n * Generates a new anonymous ID and clears user data\n */\n async reset(): Promise<void> {\n this.anonymousId = generateUUID();\n this.userId = null;\n this.userTraits = {};\n this.log(\"Identity reset, new anonymous ID:\", this.anonymousId);\n\n if (this.storage) {\n try {\n await Promise.all([\n this.storage.set(STORAGE_KEYS.ANONYMOUS_ID, this.anonymousId),\n this.storage.remove(STORAGE_KEYS.USER_ID),\n this.storage.remove(STORAGE_KEYS.USER_TRAITS),\n ]);\n } catch (error) {\n this.log(\"Error resetting identity in storage:\", error);\n }\n }\n }\n\n /**\n * Set debug mode\n */\n setDebug(enabled: boolean): void {\n this.debug = enabled;\n }\n\n private log(...args: unknown[]): void {\n if (this.debug) {\n console.log(\"[PIH Identity]\", ...args);\n }\n }\n}\n","import type { StorageAdapter } from \"./types.js\";\nimport { generateUUID, STORAGE_KEYS, DEFAULTS } from \"./utils.js\";\n\n/**\n * Callback for session events\n */\nexport interface SessionCallbacks {\n onSessionStart?: (sessionId: string) => void;\n onSessionEnd?: (sessionId: string, duration: number) => void;\n}\n\n/**\n * Session manager for handling session tracking\n */\nexport class SessionManager {\n private sessionId: string | null = null;\n private sessionStartTime: number = 0;\n private lastActivity: number = 0;\n private timeout: number;\n private storage: StorageAdapter | null;\n private callbacks: SessionCallbacks;\n private debug: boolean;\n\n constructor(\n storage: StorageAdapter | null,\n timeout: number = DEFAULTS.SESSION_TIMEOUT,\n callbacks: SessionCallbacks = {},\n debug = false\n ) {\n this.storage = storage;\n this.timeout = timeout;\n this.callbacks = callbacks;\n this.debug = debug;\n }\n\n /**\n * Initialize session from storage\n */\n async initialize(): Promise<void> {\n if (!this.storage) {\n this.log(\"No storage adapter, using in-memory session only\");\n return;\n }\n\n try {\n const storedSessionId = await this.storage.get(STORAGE_KEYS.SESSION_ID);\n const storedLastActivity = await this.storage.get(\n STORAGE_KEYS.SESSION_LAST_ACTIVITY\n );\n\n if (storedSessionId && storedLastActivity) {\n const lastActivity = parseInt(storedLastActivity, 10);\n const now = Date.now();\n\n // Check if session is still valid\n if (now - lastActivity < this.timeout) {\n this.sessionId = storedSessionId;\n this.lastActivity = lastActivity;\n this.sessionStartTime = lastActivity; // Approximate\n this.log(\"Restored session from storage:\", this.sessionId);\n } else {\n // Session expired, clear it\n this.log(\"Stored session expired, will start new session\");\n await this.clearStoredSession();\n }\n }\n } catch (error) {\n this.log(\"Error loading session from storage:\", error);\n }\n }\n\n /**\n * Get the current session ID\n * Creates a new session if needed or if the current one expired\n */\n getSessionId(): string {\n const now = Date.now();\n\n // Check if session expired\n if (this.sessionId && now - this.lastActivity > this.timeout) {\n this.endSession();\n }\n\n // Start new session if needed\n if (!this.sessionId) {\n this.startSession();\n }\n\n // Update last activity\n this.lastActivity = now;\n this.persistLastActivity();\n\n return this.sessionId!;\n }\n\n /**\n * Touch the session to update last activity\n * Call this on each track event\n */\n touch(): void {\n if (this.sessionId) {\n this.lastActivity = Date.now();\n this.persistLastActivity();\n }\n }\n\n /**\n * Check if there's an active session\n */\n hasActiveSession(): boolean {\n if (!this.sessionId) return false;\n return Date.now() - this.lastActivity < this.timeout;\n }\n\n /**\n * Get the current session ID without creating a new one\n */\n getCurrentSessionId(): string | null {\n return this.sessionId;\n }\n\n /**\n * Get session duration in milliseconds\n */\n getSessionDuration(): number {\n if (!this.sessionId) return 0;\n return Date.now() - this.sessionStartTime;\n }\n\n /**\n * Start a new session\n */\n startSession(): void {\n const now = Date.now();\n this.sessionId = generateUUID();\n this.sessionStartTime = now;\n this.lastActivity = now;\n\n this.log(\"Started new session:\", this.sessionId);\n this.persistSession();\n\n // Notify callback\n this.callbacks.onSessionStart?.(this.sessionId);\n }\n\n /**\n * End the current session\n */\n endSession(): void {\n if (!this.sessionId) return;\n\n const duration = this.getSessionDuration();\n const endedSessionId = this.sessionId;\n\n this.log(\"Ended session:\", endedSessionId, \"duration:\", duration);\n\n // Clear session\n this.sessionId = null;\n this.sessionStartTime = 0;\n this.lastActivity = 0;\n this.clearStoredSession();\n\n // Notify callback\n this.callbacks.onSessionEnd?.(endedSessionId, duration);\n }\n\n /**\n * Force end the session (for app background, page hide, etc.)\n */\n forceEndSession(): void {\n if (this.sessionId) {\n this.endSession();\n }\n }\n\n /**\n * Set debug mode\n */\n setDebug(enabled: boolean): void {\n this.debug = enabled;\n }\n\n /**\n * Set session timeout\n */\n setTimeout(timeout: number): void {\n this.timeout = timeout;\n }\n\n private async persistSession(): Promise<void> {\n if (!this.storage || !this.sessionId) return;\n\n try {\n await Promise.all([\n this.storage.set(STORAGE_KEYS.SESSION_ID, this.sessionId),\n this.storage.set(\n STORAGE_KEYS.SESSION_LAST_ACTIVITY,\n String(this.lastActivity)\n ),\n ]);\n } catch (error) {\n this.log(\"Error persisting session:\", error);\n }\n }\n\n private async persistLastActivity(): Promise<void> {\n if (!this.storage) return;\n\n try {\n await this.storage.set(\n STORAGE_KEYS.SESSION_LAST_ACTIVITY,\n String(this.lastActivity)\n );\n } catch (error) {\n this.log(\"Error persisting last activity:\", error);\n }\n }\n\n private async clearStoredSession(): Promise<void> {\n if (!this.storage) return;\n\n try {\n await Promise.all([\n this.storage.remove(STORAGE_KEYS.SESSION_ID),\n this.storage.remove(STORAGE_KEYS.SESSION_LAST_ACTIVITY),\n ]);\n } catch (error) {\n this.log(\"Error clearing stored session:\", error);\n }\n }\n\n private log(...args: unknown[]): void {\n if (this.debug) {\n console.log(\"[PIH Session]\", ...args);\n }\n }\n}\n","import type {\n TrackEvent,\n TrackResponse,\n IdentifyPayload,\n IdentifyResponse,\n TransportOptions,\n} from \"./types.js\";\nimport { PIHError } from \"./errors.js\";\n\n/**\n * Transport configuration\n */\nexport interface TransportConfig {\n /** API base URL */\n apiUrl: string;\n /** API key for authentication */\n apiKey: string;\n /** Tenant ID for multi-tenancy */\n tenantId?: string;\n /** Debug mode */\n debug?: boolean;\n}\n\n/**\n * HTTP transport for sending events to the ingest API\n */\nexport class Transport {\n private apiUrl: string;\n private apiKey: string;\n private tenantId?: string;\n private debug: boolean;\n\n constructor(config: TransportConfig) {\n this.apiUrl = config.apiUrl.replace(/\\/$/, \"\"); // Remove trailing slash\n this.apiKey = config.apiKey;\n this.tenantId = config.tenantId;\n this.debug = config.debug ?? false;\n }\n\n /**\n * Send a batch of events to the track endpoint\n */\n async sendEvents(\n events: TrackEvent[],\n options?: TransportOptions\n ): Promise<TrackResponse> {\n const url = `${this.apiUrl}/v1/track`;\n const apiEvents = events.map((e) => this.toTrackApiPayload(e));\n const body = JSON.stringify({ events: apiEvents });\n\n this.log(\"Sending\", events.length, \"events to\", url);\n\n // Try sendBeacon first if requested (for page hide scenarios)\n if (options?.useBeacon && typeof navigator !== \"undefined\" && typeof navigator.sendBeacon === \"function\") {\n const sent = this.sendViaBeacon(url, body);\n if (sent) {\n this.log(\"Events sent via sendBeacon\");\n // sendBeacon doesn't return response, assume success\n return {\n accepted: events.map((e) => ({\n event_id: e.event_id,\n timestamp: e.timestamp,\n })),\n rejected: [],\n stats: {\n received: events.length,\n accepted: events.length,\n rejected: 0,\n processing_time_ms: 0,\n },\n };\n }\n }\n\n // Standard fetch request\n try {\n const response = await this.fetch(url, {\n method: \"POST\",\n headers: this.getHeaders(),\n body,\n keepalive: options?.useBeacon, // Keep connection alive for page hide\n });\n\n if (!response.ok) {\n if (response.status === 429) {\n throw PIHError.rateLimited(\n `Rate limited: ${response.statusText}`,\n { status: response.status }\n );\n }\n throw PIHError.networkError(\n `HTTP ${response.status}: ${response.statusText}`,\n { status: response.status }\n );\n }\n\n const data = (await response.json()) as TrackResponse;\n this.log(\"Track response:\", data);\n return data;\n } catch (error) {\n if (error instanceof PIHError) {\n throw error;\n }\n throw PIHError.networkError(\n `Failed to send events: ${error instanceof Error ? error.message : String(error)}`,\n error\n );\n }\n }\n\n /**\n * Send an identify call\n */\n async sendIdentify(payload: IdentifyPayload): Promise<IdentifyResponse> {\n const url = `${this.apiUrl}/v1/identify`;\n const body = JSON.stringify(this.toIdentifyApiPayload(payload));\n\n this.log(\"Sending identify to\", url, payload);\n\n try {\n const response = await this.fetch(url, {\n method: \"POST\",\n headers: this.getHeaders(),\n body,\n });\n\n if (!response.ok) {\n if (response.status === 429) {\n throw PIHError.rateLimited(\n `Rate limited: ${response.statusText}`,\n { status: response.status }\n );\n }\n throw PIHError.networkError(\n `HTTP ${response.status}: ${response.statusText}`,\n { status: response.status }\n );\n }\n\n const data = (await response.json()) as IdentifyResponse;\n this.log(\"Identify response:\", data);\n return data;\n } catch (error) {\n if (error instanceof PIHError) {\n throw error;\n }\n throw PIHError.networkError(\n `Failed to send identify: ${error instanceof Error ? error.message : String(error)}`,\n error\n );\n }\n }\n\n /**\n * Set tenant ID\n */\n setTenantId(tenantId: string): void {\n this.tenantId = tenantId;\n }\n\n /**\n * Set debug mode\n */\n setDebug(enabled: boolean): void {\n this.debug = enabled;\n }\n\n private getHeaders(): Record<string, string> {\n const headers: Record<string, string> = {\n \"Content-Type\": \"application/json\",\n Authorization: `Bearer ${this.apiKey}`,\n };\n\n if (this.tenantId) {\n headers[\"X-Tenant-Id\"] = this.tenantId;\n }\n\n return headers;\n }\n\n /**\n * Map internal TrackEvent (snake_case) to API payload (camelCase)\n */\n private toTrackApiPayload(event: TrackEvent): Record<string, unknown> {\n return {\n eventId: event.event_id,\n eventName: event.event_name,\n timestamp: event.timestamp,\n anonymousId: event.anonymous_id,\n userId: event.user_id ?? undefined,\n sessionId: event.session_id ?? undefined,\n properties: event.properties,\n userTraits: event.user_traits,\n context: {\n platform: event.platform,\n appVersion: event.app_version ?? undefined,\n },\n };\n }\n\n /**\n * Map internal IdentifyPayload (snake_case) to API payload (camelCase)\n */\n private toIdentifyApiPayload(payload: IdentifyPayload): Record<string, unknown> {\n return {\n userId: payload.user_id,\n anonymousId: payload.anonymous_id,\n traits: payload.traits,\n timestamp: payload.timestamp,\n };\n }\n\n private sendViaBeacon(url: string, body: string): boolean {\n try {\n // Create blob with proper content type\n const blob = new Blob([body], { type: \"application/json\" });\n return navigator.sendBeacon(url, blob);\n } catch (error) {\n this.log(\"sendBeacon failed:\", error);\n return false;\n }\n }\n\n private async fetch(\n url: string,\n options: RequestInit\n ): Promise<Response> {\n // Use native fetch\n if (typeof fetch !== \"undefined\") {\n return fetch(url, options);\n }\n\n // This shouldn't happen in modern environments, but throw a clear error\n throw PIHError.networkError(\n \"fetch is not available in this environment\"\n );\n }\n\n private log(...args: unknown[]): void {\n if (this.debug) {\n console.log(\"[PIH Transport]\", ...args);\n }\n }\n}\n","import type {\n TrackEvent,\n QueuedEvent,\n StorageAdapter,\n TransportOptions,\n} from \"./types.js\";\nimport type { Transport } from \"./transport.js\";\nimport { PIHError } from \"./errors.js\";\nimport { STORAGE_KEYS, DEFAULTS, getBackoffDelay } from \"./utils.js\";\n\n/**\n * Event queue configuration\n */\nexport interface EventQueueConfig {\n /** Events before auto-flush (default: 25) */\n flushAt: number;\n /** Milliseconds between auto-flushes (default: 10000) */\n flushInterval: number;\n /** Max queued events (default: 5000) */\n maxQueueSize: number;\n /** Storage adapter for persistence */\n storage: StorageAdapter | null;\n /** Transport for sending events */\n transport: Transport;\n /** Error callback */\n onError?: (error: PIHError, events: TrackEvent[]) => void;\n /** Debug mode */\n debug?: boolean;\n}\n\n/**\n * Event queue with persistence and retry logic\n */\nexport class EventQueue {\n private queue: QueuedEvent[] = [];\n private isFlushing = false;\n private flushTimer: ReturnType<typeof setInterval> | null = null;\n private retryTimer: ReturnType<typeof setTimeout> | null = null;\n private config: EventQueueConfig;\n private initialized = false;\n\n constructor(config: EventQueueConfig) {\n this.config = {\n flushAt: config.flushAt ?? DEFAULTS.FLUSH_AT,\n flushInterval: config.flushInterval ?? DEFAULTS.FLUSH_INTERVAL,\n maxQueueSize: config.maxQueueSize ?? DEFAULTS.MAX_QUEUE_SIZE,\n storage: config.storage,\n transport: config.transport,\n onError: config.onError,\n debug: config.debug ?? false,\n };\n }\n\n /**\n * Initialize the queue (load persisted events)\n */\n async initialize(): Promise<void> {\n if (this.initialized) return;\n\n await this.loadPersistedQueue();\n this.startFlushTimer();\n this.initialized = true;\n\n this.log(\"Queue initialized with\", this.queue.length, \"persisted events\");\n }\n\n /**\n * Add an event to the queue\n */\n async enqueue(event: TrackEvent): Promise<void> {\n // Enforce max queue size (drop oldest when full)\n while (this.queue.length >= this.config.maxQueueSize) {\n const dropped = this.queue.shift();\n if (dropped) {\n this.log(\"Queue full, dropping oldest event:\", dropped.event.event_id);\n this.config.onError?.(\n PIHError.queueFull(\"Queue full, dropped oldest event\", {\n dropped_event_id: dropped.event.event_id,\n }),\n [dropped.event]\n );\n }\n }\n\n // Add event to queue\n const queuedEvent: QueuedEvent = {\n event,\n attempts: 0,\n firstAttempt: Date.now(),\n };\n this.queue.push(queuedEvent);\n\n this.log(\"Enqueued event:\", event.event_id, \"Queue size:\", this.queue.length);\n\n // Persist queue\n await this.persistQueue();\n\n // Check if we should flush\n if (this.queue.length >= this.config.flushAt) {\n this.log(\"Queue reached flushAt threshold, flushing\");\n this.flush();\n }\n }\n\n /**\n * Flush the queue (send all events)\n */\n async flush(options?: TransportOptions): Promise<void> {\n if (this.isFlushing || this.queue.length === 0) {\n return;\n }\n\n this.isFlushing = true;\n this.log(\"Flushing\", this.queue.length, \"events\");\n\n try {\n // Take batch from queue (max 100 per request)\n const batch = this.queue.splice(0, DEFAULTS.MAX_BATCH_SIZE);\n const events = batch.map((q) => q.event);\n\n try {\n const response = await this.config.transport.sendEvents(events, options);\n\n // Handle rejections\n for (const rejection of response.rejected) {\n if (rejection.reason === \"rate_limited\") {\n // Re-queue rate limited events\n const queuedEvent = batch.find(\n (q) => q.event.event_id === rejection.event_id\n );\n if (queuedEvent && queuedEvent.attempts < DEFAULTS.MAX_RETRIES) {\n queuedEvent.attempts++;\n this.queue.unshift(queuedEvent);\n this.log(\n \"Rate limited event re-queued:\",\n rejection.event_id,\n \"attempt:\",\n queuedEvent.attempts\n );\n }\n } else {\n // Other rejections are permanent failures\n this.log(\n \"Event permanently rejected:\",\n rejection.event_id,\n rejection.reason,\n rejection.details\n );\n }\n }\n\n this.log(\n \"Flush complete. Accepted:\",\n response.stats.accepted,\n \"Rejected:\",\n response.stats.rejected\n );\n } catch (error) {\n const pihError = PIHError.fromUnknown(error);\n\n // Network error - re-queue all with backoff\n for (const item of batch) {\n if (item.attempts < DEFAULTS.MAX_RETRIES) {\n item.attempts++;\n this.queue.unshift(item);\n } else {\n this.log(\n \"Event dropped after max retries:\",\n item.event.event_id\n );\n }\n }\n\n // Schedule retry with backoff\n const nextAttempt = batch[0]?.attempts ?? 1;\n const backoff = getBackoffDelay(nextAttempt);\n this.log(\"Network error, scheduling retry in\", backoff, \"ms\");\n\n this.retryTimer = setTimeout(() => {\n this.retryTimer = null;\n this.flush(options);\n }, backoff);\n\n this.config.onError?.(pihError, events);\n }\n\n // Persist updated queue\n await this.persistQueue();\n\n // Continue flushing if there are more events\n if (this.queue.length >= this.config.flushAt) {\n // Use setImmediate/setTimeout to avoid blocking\n setTimeout(() => this.flush(options), 0);\n }\n } finally {\n this.isFlushing = false;\n }\n }\n\n /**\n * Get the current queue length\n */\n getQueueLength(): number {\n return this.queue.length;\n }\n\n /**\n * Check if the queue is empty\n */\n isEmpty(): boolean {\n return this.queue.length === 0;\n }\n\n /**\n * Check if queue is currently flushing\n */\n isBusy(): boolean {\n return this.isFlushing;\n }\n\n /**\n * Clear the queue\n */\n async clear(): Promise<void> {\n this.queue = [];\n await this.persistQueue();\n this.log(\"Queue cleared\");\n }\n\n /**\n * Stop the queue (cancel timers)\n */\n destroy(): void {\n if (this.flushTimer) {\n clearInterval(this.flushTimer);\n this.flushTimer = null;\n }\n if (this.retryTimer) {\n clearTimeout(this.retryTimer);\n this.retryTimer = null;\n }\n this.log(\"Queue destroyed\");\n }\n\n /**\n * Set debug mode\n */\n setDebug(enabled: boolean): void {\n this.config.debug = enabled;\n }\n\n private async persistQueue(): Promise<void> {\n if (!this.config.storage) return;\n\n try {\n await this.config.storage.set(\n STORAGE_KEYS.QUEUE,\n JSON.stringify(this.queue)\n );\n } catch (error) {\n this.log(\"Error persisting queue:\", error);\n }\n }\n\n private async loadPersistedQueue(): Promise<void> {\n if (!this.config.storage) return;\n\n try {\n const stored = await this.config.storage.get(STORAGE_KEYS.QUEUE);\n if (stored) {\n const parsed = JSON.parse(stored) as QueuedEvent[];\n // Validate parsed data\n if (Array.isArray(parsed)) {\n this.queue = parsed.filter(\n (item) =>\n item &&\n typeof item === \"object\" &&\n \"event\" in item &&\n \"attempts\" in item\n );\n }\n }\n } catch (error) {\n this.log(\"Error loading persisted queue:\", error);\n this.queue = [];\n }\n }\n\n private startFlushTimer(): void {\n if (this.flushTimer) return;\n\n this.flushTimer = setInterval(() => {\n if (this.queue.length > 0) {\n this.log(\"Flush timer triggered\");\n this.flush();\n }\n }, this.config.flushInterval);\n }\n\n private log(...args: unknown[]): void {\n if (this.config.debug) {\n console.log(\"[PIH Queue]\", ...args);\n }\n }\n}\n","import type {\n PIHConfig,\n TrackEvent,\n TrackOptions,\n StorageAdapter,\n TransportOptions,\n} from \"./types.js\";\nimport { PIHError } from \"./errors.js\";\nimport { IdentityManager } from \"./identity.js\";\nimport { SessionManager } from \"./session.js\";\nimport { Transport } from \"./transport.js\";\nimport { EventQueue } from \"./queue.js\";\nimport { generateUUID, getTimestamp, dateToTimestamp, DEFAULTS } from \"./utils.js\";\n\n/**\n * Base PIH client class\n * Platform-specific SDKs extend this class\n */\nexport class PIHClient {\n protected config: PIHConfig;\n protected storage: StorageAdapter | null = null;\n protected identity: IdentityManager;\n protected session: SessionManager;\n protected transport: Transport;\n protected queue: EventQueue;\n protected initialized = false;\n protected tenantId: string;\n\n constructor(config: PIHConfig, storage: StorageAdapter | null = null) {\n this.validateConfig(config);\n\n this.config = {\n apiUrl: DEFAULTS.API_URL,\n debug: false,\n flushInterval: DEFAULTS.FLUSH_INTERVAL,\n flushAt: DEFAULTS.FLUSH_AT,\n maxQueueSize: DEFAULTS.MAX_QUEUE_SIZE,\n sessionTimeout: DEFAULTS.SESSION_TIMEOUT,\n ...config,\n };\n\n this.storage = storage;\n this.tenantId = config.tenantId ?? \"\";\n\n // Initialize identity manager\n this.identity = new IdentityManager(storage, this.config.debug);\n\n // Initialize session manager\n this.session = new SessionManager(\n storage,\n this.config.sessionTimeout,\n {\n onSessionStart: (sessionId) => {\n this.log(\"Session started:\", sessionId);\n // Track session_started event\n this.trackInternal(\"session_started\", { session_id: sessionId });\n },\n onSessionEnd: (sessionId, duration) => {\n this.log(\"Session ended:\", sessionId, \"duration:\", duration);\n // Track session_ended event\n this.trackInternal(\"session_ended\", {\n session_id: sessionId,\n duration_ms: duration,\n });\n },\n },\n this.config.debug\n );\n\n // Initialize transport\n this.transport = new Transport({\n apiUrl: this.config.apiUrl!,\n apiKey: this.config.apiKey,\n tenantId: this.tenantId,\n debug: this.config.debug,\n });\n\n // Initialize queue\n this.queue = new EventQueue({\n flushAt: this.config.flushAt!,\n flushInterval: this.config.flushInterval!,\n maxQueueSize: this.config.maxQueueSize!,\n storage,\n transport: this.transport,\n onError: (error, events) => {\n this.config.onError?.(error);\n this.log(\"Queue error:\", error.message, \"events:\", events.length);\n },\n debug: this.config.debug,\n });\n }\n\n /**\n * Initialize the client (load persisted state)\n */\n async initialize(): Promise<void> {\n if (this.initialized) return;\n\n await Promise.all([\n this.identity.initialize(),\n this.session.initialize(),\n this.queue.initialize(),\n ]);\n\n this.initialized = true;\n this.log(\"Client initialized\");\n }\n\n /**\n * Set the tenant ID\n */\n setTenant(tenantId: string): void {\n this.tenantId = tenantId;\n this.transport.setTenantId(tenantId);\n this.log(\"Tenant set:\", tenantId);\n }\n\n /**\n * Identify the user\n */\n async identify(\n userId: string,\n traits?: Record<string, unknown>\n ): Promise<void> {\n await this.ensureInitialized();\n\n await this.identity.setUserId(userId);\n if (traits) {\n await this.identity.setUserTraits(traits);\n }\n\n // Send identify call to server\n try {\n await this.transport.sendIdentify({\n project_id: this.config.projectId,\n environment: this.config.environment,\n tenant_id: this.tenantId,\n anonymous_id: this.identity.getAnonymousId(),\n user_id: userId,\n traits,\n timestamp: getTimestamp(),\n });\n } catch (error) {\n const pihError = PIHError.fromUnknown(error);\n this.config.onError?.(pihError);\n this.log(\"Identify error:\", pihError.message);\n }\n }\n\n /**\n * Set user traits without identifying\n */\n async setUserTraits(traits: Record<string, unknown>): Promise<void> {\n await this.ensureInitialized();\n await this.identity.setUserTraits(traits);\n }\n\n /**\n * Track an event\n */\n async track(\n eventName: string,\n properties?: Record<string, unknown>,\n options?: TrackOptions\n ): Promise<void> {\n await this.ensureInitialized();\n\n const event = this.createEvent(eventName, properties, options);\n\n // Touch session to update last activity\n this.session.touch();\n\n if (options?.immediate) {\n // Send immediately, bypassing queue\n try {\n await this.transport.sendEvents([event]);\n } catch (error) {\n const pihError = PIHError.fromUnknown(error);\n this.config.onError?.(pihError);\n this.log(\"Immediate track error:\", pihError.message);\n }\n } else {\n // Add to queue\n await this.queue.enqueue(event);\n }\n }\n\n /**\n * Flush the event queue\n */\n async flush(options?: TransportOptions): Promise<void> {\n await this.ensureInitialized();\n await this.queue.flush(options);\n }\n\n /**\n * Reset identity (logout)\n */\n async reset(): Promise<void> {\n await this.ensureInitialized();\n\n // End current session\n this.session.forceEndSession();\n\n // Reset identity\n await this.identity.reset();\n\n this.log(\"Client reset\");\n }\n\n /**\n * Enable/disable debug mode\n */\n setDebug(enabled: boolean): void {\n this.config.debug = enabled;\n this.identity.setDebug(enabled);\n this.session.setDebug(enabled);\n this.transport.setDebug(enabled);\n this.queue.setDebug(enabled);\n }\n\n /**\n * Get the anonymous ID\n */\n getAnonymousId(): string {\n return this.identity.getAnonymousId();\n }\n\n /**\n * Get the user ID\n */\n getUserId(): string | null {\n return this.identity.getUserId();\n }\n\n /**\n * Get the session ID\n */\n getSessionId(): string | null {\n return this.session.getCurrentSessionId();\n }\n\n /**\n * Get the queue length\n */\n getQueueLength(): number {\n return this.queue.getQueueLength();\n }\n\n /**\n * Destroy the client (cleanup)\n */\n destroy(): void {\n this.queue.destroy();\n this.log(\"Client destroyed\");\n }\n\n /**\n * Internal track method that doesn't require initialization\n * Used for session events during initialization\n */\n protected trackInternal(\n eventName: string,\n properties?: Record<string, unknown>\n ): void {\n const event = this.createEvent(eventName, properties);\n // Fire and forget - don't await\n this.queue.enqueue(event).catch((error) => {\n this.log(\"Internal track error:\", error);\n });\n }\n\n /**\n * Create a track event\n */\n protected createEvent(\n eventName: string,\n properties?: Record<string, unknown>,\n options?: TrackOptions\n ): TrackEvent {\n const timestamp = options?.timestamp\n ? dateToTimestamp(options.timestamp)\n : getTimestamp();\n\n return {\n event_id: generateUUID(),\n timestamp,\n project_id: this.config.projectId,\n environment: this.config.environment,\n tenant_id: this.tenantId,\n event_name: eventName,\n anonymous_id: this.identity.getAnonymousId(),\n user_id: this.identity.getUserId(),\n session_id: this.session.getSessionId(),\n platform: this.config.platform,\n app_version: this.config.appVersion ?? null,\n properties: properties ?? {},\n user_traits: this.identity.getUserTraits(),\n };\n }\n\n /**\n * Ensure client is initialized\n */\n protected async ensureInitialized(): Promise<void> {\n if (!this.initialized) {\n await this.initialize();\n }\n }\n\n /**\n * Validate configuration\n */\n protected validateConfig(config: PIHConfig): void {\n if (!config.apiKey) {\n throw PIHError.invalidConfig(\"apiKey is required\");\n }\n if (!config.projectId) {\n throw PIHError.invalidConfig(\"projectId is required\");\n }\n if (!config.environment) {\n throw PIHError.invalidConfig(\"environment is required\");\n }\n if (!config.platform) {\n throw PIHError.invalidConfig(\"platform is required\");\n }\n }\n\n protected log(...args: unknown[]): void {\n if (this.config.debug) {\n console.log(\"[PIH Client]\", ...args);\n }\n }\n}\n","import type { StorageAdapter } from \"@product-intelligence-hub/sdk-core\";\n\n/**\n * In-memory storage fallback when localStorage is unavailable\n */\nclass MemoryStorage implements StorageAdapter {\n private data = new Map<string, string>();\n\n async get(key: string): Promise<string | null> {\n return this.data.get(key) ?? null;\n }\n\n async set(key: string, value: string): Promise<void> {\n this.data.set(key, value);\n }\n\n async remove(key: string): Promise<void> {\n this.data.delete(key);\n }\n}\n\n/**\n * Check if localStorage is available\n */\nfunction isLocalStorageAvailable(): boolean {\n try {\n const testKey = \"__pih_test__\";\n localStorage.setItem(testKey, testKey);\n localStorage.removeItem(testKey);\n return true;\n } catch {\n return false;\n }\n}\n\n/**\n * localStorage adapter with fallback to in-memory storage\n */\nclass LocalStorageAdapter implements StorageAdapter {\n private fallback: MemoryStorage | null = null;\n private useLocalStorage: boolean;\n\n constructor() {\n this.useLocalStorage = isLocalStorageAvailable();\n if (!this.useLocalStorage) {\n this.fallback = new MemoryStorage();\n console.warn(\n \"[PIH] localStorage unavailable, using in-memory storage. Data will not persist across page loads.\"\n );\n }\n }\n\n async get(key: string): Promise<string | null> {\n if (this.fallback) {\n return this.fallback.get(key);\n }\n\n try {\n return localStorage.getItem(key);\n } catch {\n // localStorage access might fail in some contexts\n if (!this.fallback) {\n this.fallback = new MemoryStorage();\n }\n return this.fallback.get(key);\n }\n }\n\n async set(key: string, value: string): Promise<void> {\n if (this.fallback) {\n return this.fallback.set(key, value);\n }\n\n try {\n localStorage.setItem(key, value);\n } catch (error) {\n // Handle quota exceeded or other errors\n if (!this.fallback) {\n this.fallback = new MemoryStorage();\n console.warn(\n \"[PIH] localStorage write failed, falling back to in-memory storage:\",\n error\n );\n }\n return this.fallback.set(key, value);\n }\n }\n\n async remove(key: string): Promise<void> {\n if (this.fallback) {\n return this.fallback.remove(key);\n }\n\n try {\n localStorage.removeItem(key);\n } catch {\n // Ignore removal errors\n }\n }\n}\n\n/**\n * Create the web storage adapter\n */\nexport function createWebStorage(): StorageAdapter {\n return new LocalStorageAdapter();\n}\n\n/**\n * Export the storage adapter singleton\n */\nexport const webStorage = createWebStorage();\n","import type { PIHClient, AutocaptureConfig } from \"@product-intelligence-hub/sdk-core\";\n\n/**\n * UTM parameter storage key\n */\nconst UTM_STORAGE_KEY = \"pih_utm_params\";\n\n/**\n * UTM parameter names\n */\nconst UTM_PARAMS = [\n \"utm_source\",\n \"utm_medium\",\n \"utm_campaign\",\n \"utm_term\",\n \"utm_content\",\n] as const;\n\n/**\n * Autocapture manager for web SDK\n */\nexport class Autocapture {\n private client: PIHClient;\n private config: AutocaptureConfig;\n private cachedUtmParams: Record<string, string> | null = null;\n private originalPushState: typeof history.pushState | null = null;\n private originalReplaceState: typeof history.replaceState | null = null;\n private boundHandleClick: (e: MouseEvent) => void;\n private boundHandlePopState: () => void;\n\n constructor(client: PIHClient, config: AutocaptureConfig = {}) {\n this.client = client;\n this.config = {\n pageViews: config.pageViews !== false, // default: true\n clicks: config.clicks ?? false, // default: false\n clickSelector: config.clickSelector ?? \"[data-track]\",\n forms: config.forms ?? false, // default: false\n };\n\n this.boundHandleClick = this.handleClick.bind(this);\n this.boundHandlePopState = this.handlePopState.bind(this);\n }\n\n /**\n * Start autocapture\n */\n start(): void {\n if (typeof window === \"undefined\" || typeof document === \"undefined\") {\n return;\n }\n\n // Load cached UTM params\n this.loadCachedUtmParams();\n\n // Setup page view tracking\n if (this.config.pageViews) {\n this.setupPageViews();\n // Track initial page view\n this.trackPageView();\n }\n\n // Setup click tracking\n if (this.config.clicks) {\n this.setupClickTracking();\n }\n }\n\n /**\n * Stop autocapture\n */\n stop(): void {\n // Restore original history methods\n if (this.originalPushState) {\n history.pushState = this.originalPushState;\n this.originalPushState = null;\n }\n if (this.originalReplaceState) {\n history.replaceState = this.originalReplaceState;\n this.originalReplaceState = null;\n }\n\n // Remove event listeners\n if (typeof window !== \"undefined\") {\n window.removeEventListener(\"popstate\", this.boundHandlePopState);\n }\n if (typeof document !== \"undefined\") {\n document.removeEventListener(\"click\", this.boundHandleClick, true);\n }\n }\n\n /**\n * Manually track a page view\n */\n trackPageView(): void {\n const url = new URL(window.location.href);\n const utmParams = this.extractUtmParams(url);\n\n // Cache UTM params on first page view with UTM\n if (Object.keys(utmParams).length > 0 && !this.cachedUtmParams) {\n this.cachedUtmParams = utmParams;\n this.persistUtmParams(utmParams);\n }\n\n this.client.track(\"page_viewed\", {\n path: url.pathname,\n search: url.search,\n hash: url.hash,\n referrer: document.referrer || null,\n title: document.title,\n url: window.location.href,\n // Include UTM params (from current URL or cached)\n ...this.getUtmParams(url),\n });\n }\n\n /**\n * Setup page view tracking\n */\n private setupPageViews(): void {\n // Monkey-patch History API for SPA navigation\n this.originalPushState = history.pushState;\n this.originalReplaceState = history.replaceState;\n\n const self = this;\n\n history.pushState = function (...args) {\n self.originalPushState!.apply(history, args);\n // Use setTimeout to ensure URL has been updated\n setTimeout(() => self.trackPageView(), 0);\n };\n\n history.replaceState = function (...args) {\n self.originalReplaceState!.apply(history, args);\n // Use setTimeout to ensure URL has been updated\n setTimeout(() => self.trackPageView(), 0);\n };\n\n // Listen for popstate (back/forward navigation)\n window.addEventListener(\"popstate\", this.boundHandlePopState);\n }\n\n /**\n * Handle popstate event\n */\n private handlePopState(): void {\n this.trackPageView();\n }\n\n /**\n * Setup click tracking\n */\n private setupClickTracking(): void {\n document.addEventListener(\"click\", this.boundHandleClick, true);\n }\n\n /**\n * Handle click event\n */\n private handleClick(event: MouseEvent): void {\n const target = event.target as Element | null;\n if (!target) return;\n\n // Find the closest element matching the selector\n const trackElement = target.closest(this.config.clickSelector!);\n if (!trackElement) return;\n\n // Get element properties\n const elementTag = trackElement.tagName.toLowerCase();\n const elementText = (trackElement.textContent || \"\").trim().slice(0, 100);\n const elementId = trackElement.id || null;\n const elementClasses = trackElement.className || null;\n const dataTrack = trackElement.getAttribute(\"data-track\");\n const href =\n trackElement instanceof HTMLAnchorElement ? trackElement.href : null;\n\n this.client.track(\"element_clicked\", {\n element_tag: elementTag,\n element_text: elementText,\n element_id: elementId,\n element_classes: elementClasses,\n data_track: dataTrack,\n href,\n path: window.location.pathname,\n });\n }\n\n /**\n * Extract UTM parameters from URL\n */\n private extractUtmParams(url: URL): Record<string, string> {\n const params: Record<string, string> = {};\n for (const key of UTM_PARAMS) {\n const value = url.searchParams.get(key);\n if (value) {\n params[key] = value;\n }\n }\n return params;\n }\n\n /**\n * Get UTM parameters (current URL or cached)\n */\n private getUtmParams(url: URL): Record<string, string> {\n // First check current URL\n const currentParams = this.extractUtmParams(url);\n if (Object.keys(currentParams).length > 0) {\n return currentParams;\n }\n\n // Fall back to cached params\n return this.cachedUtmParams ?? {};\n }\n\n /**\n * Load cached UTM params from storage\n */\n private loadCachedUtmParams(): void {\n try {\n const stored = localStorage.getItem(UTM_STORAGE_KEY);\n if (stored) {\n this.cachedUtmParams = JSON.parse(stored);\n }\n } catch {\n // Ignore storage errors\n }\n }\n\n /**\n * Persist UTM params to storage\n */\n private persistUtmParams(params: Record<string, string>): void {\n try {\n localStorage.setItem(UTM_STORAGE_KEY, JSON.stringify(params));\n } catch {\n // Ignore storage errors\n }\n }\n}\n","import type { PIHClient } from \"@product-intelligence-hub/sdk-core\";\n\n/**\n * Beacon manager for flushing events on page hide\n */\nexport class BeaconManager {\n private client: PIHClient;\n private boundHandleVisibilityChange: () => void;\n private boundHandleBeforeUnload: () => void;\n\n constructor(client: PIHClient) {\n this.client = client;\n this.boundHandleVisibilityChange = this.handleVisibilityChange.bind(this);\n this.boundHandleBeforeUnload = this.handleBeforeUnload.bind(this);\n }\n\n /**\n * Start listening for visibility and unload events\n */\n start(): void {\n if (typeof document !== \"undefined\") {\n document.addEventListener(\n \"visibilitychange\",\n this.boundHandleVisibilityChange\n );\n }\n\n if (typeof window !== \"undefined\") {\n window.addEventListener(\"beforeunload\", this.boundHandleBeforeUnload);\n // Also listen for pagehide which is more reliable on mobile\n window.addEventListener(\"pagehide\", this.boundHandleBeforeUnload);\n }\n }\n\n /**\n * Stop listening for events\n */\n stop(): void {\n if (typeof document !== \"undefined\") {\n document.removeEventListener(\n \"visibilitychange\",\n this.boundHandleVisibilityChange\n );\n }\n\n if (typeof window !== \"undefined\") {\n window.removeEventListener(\"beforeunload\", this.boundHandleBeforeUnload);\n window.removeEventListener(\"pagehide\", this.boundHandleBeforeUnload);\n }\n }\n\n /**\n * Handle visibility change\n */\n private handleVisibilityChange(): void {\n if (document.visibilityState === \"hidden\") {\n this.flushWithBeacon();\n }\n }\n\n /**\n * Handle before unload\n */\n private handleBeforeUnload(): void {\n this.flushWithBeacon();\n }\n\n /**\n * Flush events using sendBeacon\n */\n private flushWithBeacon(): void {\n // Use sendBeacon for reliability when page is closing\n this.client.flush({ useBeacon: true }).catch(() => {\n // Ignore errors during page unload\n });\n }\n}\n\n/**\n * Check if sendBeacon is available\n */\nexport function isSendBeaconAvailable(): boolean {\n return (\n typeof navigator !== \"undefined\" &&\n typeof navigator.sendBeacon === \"function\"\n );\n}\n","import {\n PIHClient,\n type PIHConfig,\n type TrackOptions,\n type TransportOptions,\n type StorageAdapter,\n} from \"@product-intelligence-hub/sdk-core\";\nimport { createWebStorage } from \"./storage.js\";\nimport { Autocapture } from \"./autocapture.js\";\nimport { BeaconManager } from \"./beacon.js\";\n\n/**\n * Web-specific PIH configuration\n */\nexport interface WebPIHConfig extends Omit<PIHConfig, \"platform\"> {\n /** Platform is always \"web\" for web SDK */\n platform?: \"web\";\n}\n\n/**\n * Web PIH Client\n * Extends the base client with web-specific features\n */\nexport class WebPIHClient extends PIHClient {\n private autocapture: Autocapture | null = null;\n private beacon: BeaconManager;\n\n constructor(config: WebPIHConfig, storage?: StorageAdapter) {\n // Ensure platform is set to \"web\"\n const webConfig: PIHConfig = {\n ...config,\n platform: \"web\",\n };\n\n // Use provided storage or create web storage\n super(webConfig, storage ?? createWebStorage());\n\n // Setup beacon manager for flush on page hide\n this.beacon = new BeaconManager(this);\n }\n\n /**\n * Initialize the web client\n */\n override async initialize(): Promise<void> {\n await super.initialize();\n\n // Start beacon manager\n this.beacon.start();\n\n // Setup autocapture if configured\n if (this.config.autocapture) {\n this.autocapture = new Autocapture(this, this.config.autocapture);\n this.autocapture.start();\n }\n\n this.log(\"Web client initialized\");\n }\n\n /**\n * Enable autocapture after initialization\n */\n enableAutocapture(config?: PIHConfig[\"autocapture\"]): void {\n if (this.autocapture) {\n this.autocapture.stop();\n }\n this.autocapture = new Autocapture(this, config);\n this.autocapture.start();\n }\n\n /**\n * Disable autocapture\n */\n disableAutocapture(): void {\n if (this.autocapture) {\n this.autocapture.stop();\n this.autocapture = null;\n }\n }\n\n /**\n * Manually track a page view\n */\n trackPageView(): void {\n if (this.autocapture) {\n this.autocapture.trackPageView();\n } else {\n // Track page view without autocapture\n const url = new URL(window.location.href);\n this.track(\"page_viewed\", {\n path: url.pathname,\n search: url.search,\n hash: url.hash,\n referrer: document.referrer || null,\n title: document.title,\n url: window.location.href,\n });\n }\n }\n\n /**\n * Destroy the client\n */\n override destroy(): void {\n this.beacon.stop();\n if (this.autocapture) {\n this.autocapture.stop();\n }\n super.destroy();\n }\n\n protected override log(...args: unknown[]): void {\n if (this.config.debug) {\n console.log(\"[PIH Web]\", ...args);\n }\n }\n}\n\n/**\n * Singleton instance\n */\nlet instance: WebPIHClient | null = null;\n\n/**\n * Initialize the PIH Web SDK\n */\nfunction init(config: WebPIHConfig): WebPIHClient {\n if (instance) {\n console.warn(\"[PIH] SDK already initialized. Returning existing instance.\");\n return instance;\n }\n\n instance = new WebPIHClient(config);\n\n // Auto-initialize\n instance.initialize().catch((error) => {\n console.error(\"[PIH] Failed to initialize:\", error);\n });\n\n return instance;\n}\n\n/**\n * Get the current instance\n */\nfunction getInstance(): WebPIHClient | null {\n return instance;\n}\n\n/**\n * Reset the singleton (for testing)\n */\nfunction resetInstance(): void {\n if (instance) {\n instance.destroy();\n instance = null;\n }\n}\n\n// Default export for UMD/IIFE\nconst PIH = {\n init,\n getInstance,\n resetInstance,\n WebPIHClient,\n};\n\nexport default PIH;\nexport { init, getInstance, resetInstance };\n\n// Re-export types from core\nexport type {\n PIHConfig,\n TrackEvent,\n TrackOptions,\n TransportOptions,\n AutocaptureConfig,\n PIHError,\n PIHErrorCode,\n} from \"@product-intelligence-hub/sdk-core\";\n"]}