@carter-rmn/cpix-js 1.0.6 → 1.0.7

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.
@@ -7,5 +7,5 @@ export default class Cookie {
7
7
  static exists(name: string): boolean;
8
8
  static setUtms(): void;
9
9
  static getUtms(): any;
10
- static createSession(): void;
10
+ static createSession(regenerate?: boolean): void;
11
11
  }
package/dist/cpix.cjs CHANGED
@@ -1 +1 @@
1
- "use strict";var y=Object.defineProperty;var S=(l,e,t)=>e in l?y(l,e,{enumerable:!0,configurable:!0,writable:!0,value:t}):l[e]=t;var o=(l,e,t)=>(S(l,typeof e!="symbol"?e+"":e,t),t);Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const v="@carter-rmn/cpix-js",P="1.0.5",_="module",x=["dist"],A="dist/cpix.umd.cjs",b="dist/cpix.js",T="dist/cpix.d.ts",R={".":{import:"./dist/cpix.js",require:"./dist/cpix.umd.cjs"}},I={dev:"vite",build:"tsc && vite build",preview:"vite preview"},U={picocolors:"^1.0.0","rollup-plugin-visualizer":"^5.12.0",typescript:"^5.2.2",vite:"^5.2.0","vite-plugin-progress":"^0.0.7"},C={"vite-plugin-dts":"^3.8.1"},m={name:v,version:P,type:_,files:x,main:A,module:b,types:T,exports:R,scripts:I,devDependencies:U,dependencies:C},n={DEBUG:!1,TRACKER_FUNC_NAME:"cpix",API_URL:"",QUEUE_MAX_RETRIES:3,QUEUE_INITIAL_DELAY:1e4,version:m.version,package:m.name,USER_PROPERTIES:{},SESSION_EXPIRY_DAYS:14,COMMON_PROPERTIES:{}},c={SESSION:"cpix_session",META_PARAMETERS:"cpix_meta_parameters",ACCESS_TOKEN:"cpix_access_token",UTM:"cpix_utm"},O=["utm_source","utm_medium","utm_term","utm_content","utm_campaign"],u=function(){const l=()=>n.DEBUG;return{info:function(...e){console.log(...e)},debug:function(...e){l()&&console.log(...e)},error:function(...e){console.error(...e)}}}();class D extends EventTarget{constructor(t={maxRetries:3,initialDelay:1e4,consumerHandler:i=>(u.debug("Consuming event:",i),Promise.resolve())}){super();o(this,"dataQueue");o(this,"retryQueue");o(this,"maxRetries");o(this,"initialDelay");o(this,"publishEvent");o(this,"retryEvent");o(this,"handler");this.dataQueue=[],this.retryQueue=[],this.maxRetries=t.maxRetries,this.initialDelay=t.initialDelay,this.handler=t.consumerHandler,this.publishEvent=new Event("eventPublished"),this.retryEvent=new Event("retryMessage"),this.consume(),this.retry()}publish(t){u.debug("publishing event");const i={data:t,id:`${Date.now()+Math.random()}`,retryCount:0,retryDelay:this.initialDelay};this.dataQueue.push(i),this.dispatchEvent(this.publishEvent)}consume(){u.debug("Started Consumer Queue"),this.addEventListener("eventPublished",async()=>{for(;this.dataQueue.length>0;){const t=this.dataQueue.shift(),{data:i={}}=t;try{await this.handler(i),this.acknowledge(t==null?void 0:t.id)}catch(r){u.error("Failed to publish event:",r),this.scheduleRetry(t)}}})}scheduleRetry(t){if(t.retryCount>=this.maxRetries){u.error("Max retries reached for message:",t);return}setTimeout(()=>{this.retryQueue.push({...t,retryCount:t.retryCount+1,retryDelay:t.retryDelay*2}),this.dispatchEvent(this.retryEvent)},t.retryDelay)}acknowledge(t){this.dataQueue=this.dataQueue.filter(i=>i.id!==t)}retry(){u.debug("Started Retry Queue"),this.addEventListener("retryMessage",async()=>{for(;this.retryQueue.length>0;){const t=this.retryQueue.shift(),{data:i={}}=t;try{await this.handler(i),this.acknowledge(t==null?void 0:t.id)}catch(r){u.error("Failed to publish event:",r),this.scheduleRetry(t)}}})}}class d{static getBrowserInfo(){var r,a,p,f,g;const e=navigator.userAgent||"";let t,i;return/chrome/i.test(e)?(t="Chrome",i=(r=e.match(/chrome\/(\d+)/i))==null?void 0:r[1]):/firefox/i.test(e)?(t="Firefox",i=(a=e.match(/firefox\/(\d+)/i))==null?void 0:a[1]):/safari/i.test(e)?(t="Safari",i=(p=e.match(/version\/(\d+)/i))==null?void 0:p[1]):/edge/i.test(e)?(t="Edge",i=(f=e.match(/edge\/(\d+)/i))==null?void 0:f[1]):/trident/i.test(e)?(t="Internet Explorer",i=(g=e.match(/rv:(\d+)/i))==null?void 0:g[1]):(t="Unknown",i="Unknown"),`${t} ${i}`}static getDeviceCategory(){const e=navigator.userAgent;return/mobile/i.test(e)?"Mobile":/tablet/i.test(e)?"Tablet":"Desktop"}static getDevicePlatform(){const e=navigator.userAgent;return/android/i.test(e)?"Android":/iphone|ipad|ipod/i.test(e)?"iOS":/windows phone/i.test(e)?"Windows Phone":/mac|Macintosh/i.test(e)?"Mac":/windows|Microsoft/i.test(e)?"Windows":/linux/i.test(e)?"Linux":"Unknown"}static getDeviceManufacturer(){const e=navigator.userAgent;let t;return/iphone|ipad|ipod|mac|Macintosh/i.test(e)?t="Apple":/samsung/i.test(e)?t="Samsung":/google/i.test(e)?t="Google":/huawei/i.test(e)?t="Huawei":/xiaomi/i.test(e)?t="Xiaomi":/oneplus/i.test(e)?t="OnePlus":/dell/i.test(e)?t="Dell":/lenovo/i.test(e)?t="Lenovo":/acer/i.test(e)?t="Acer":/asus/i.test(e)?t="Asus":/toshiba/i.test(e)?t="Toshiba":t="Unknown",t}static async getDeviceNetworkParameters(){try{const e=await fetch(`${n.API_URL}/api/geolocation`),{data:t}=await e.json();return{city:t.city||"Unknown",region:t.region||"Unknown",country:t.country||"Unknown",timezone:t.timezone||"Unknown",loc:t.loc||"Unknown",ip_address:t.ip_address||"Unknown"}}catch(e){return u.error("Error retrieving device network parameters:",e),{city:"Unknown",region:"Unknown",country:"Unknown",timezone:"Unknown",loc:"Unknown",ip_address:"Unknown"}}}static async aquireAccessToken(e){try{return(await(await fetch(`${n.API_URL}/api/authenticate`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({accountId:e,metadata:{sdk:n.package,version:n.version,hostname:window.location.hostname}})})).json()).accessToken}catch(t){throw u.error("Error acquiring access token:",t),new Error("[CPIX] Authentication error")}}}class h{static isPresent(e){return typeof e<"u"&&e!==null&&e!==""}static now(){return 1*new Date().getTime()}static guid(){return m.version+"-xxxxxxxx-".replace(/[x]/g,function(e){const t=Math.random()*36|0;return(e=="x"?t:t&3|8).toString(36)})+(1*new Date().getTime()).toString(36)}static optionalData(e){return h.isPresent(e)===!1?"":typeof e=="object"?h.optionalData(JSON.stringify(e)):typeof e=="function"?h.optionalData(e()):String(e)}static sleep(e){return new Promise(t=>setTimeout(t,e))}}class E{static getParametersByName(e,t){t||(t=window.location.href),e=e.replace(/[[\]]/g,"\\$&");const i=new RegExp("[?&]"+e+"(=([^&#]*)|&|#|$)","gi"),r=[];let a;for(;(a=i.exec(t))!==null;)a[2]&&r.push(decodeURIComponent(a[2].replace(/\+/g," ")));return r.length>0?r:null}static externalHost(e){var t;return e.hostname!=location.hostname&&((t=e==null?void 0:e.protocol)==null?void 0:t.indexOf("http"))===0}}class s{static prefix(){return`__${n.TRACKER_FUNC_NAME}__`}static get(e){const t=`${s.prefix()}${e}`,i=document.cookie.split("; ").find(r=>r.startsWith(`${t}=`));return i?i.split("=")[1]:void 0}static set(e,t,i){const r=`${s.prefix()}${e}`,a=new Date;a.setTime(a.getTime()+i*60*1e3),document.cookie=`${r}=${t}; expires=${a.toUTCString()}; path=/`}static delete(e){const t=`${s.prefix()}${e}`;document.cookie=`${t}=; expires=Thu, 01 Jan 1970 00:00:00 UTC; path=/`}static clear(){document.cookie.split("; ").filter(e=>e.startsWith(s.prefix())).forEach(e=>{const t=e.split("=")[0];document.cookie=`${t}=; expires=Thu, 01 Jan 1970 00:00:00 UTC; path=/`})}static exists(e){return!!s.get(e)}static setUtms(){const e=O;let t=!1;for(let i=0;i<e.length;i++){const r=e[i];if(h.isPresent(E.getParametersByName(r,window.location.href))){t=!0;break}}if(t){let i;const r=[];for(let a=0;a<e.length;a++){const p=e[a];i=E.getParametersByName(p,window.location.href),r.push({[p]:encodeURIComponent(i)})}s.set(c.UTM,JSON.stringify(r),n.SESSION_EXPIRY_DAYS*24*60)}}static getUtms(){const e=s.get(c.UTM);return h.isPresent(e)?JSON.parse(e):{}}static createSession(){s.exists(c.SESSION)||s.set(c.SESSION,h.guid(),n.SESSION_EXPIRY_DAYS*24*60),s.setUtms()}}class N{constructor(){o(this,"instances",[]);o(this,"initialized",!1);o(this,"sessionCreated",!1);o(this,"accessToken","");o(this,"metaParameters",{});o(this,"queue");if(!window)throw new Error("[CPIX] CarterAnalytics SDK can only be used in a browser environment");this.queue=new D({maxRetries:n.QUEUE_MAX_RETRIES,initialDelay:n.QUEUE_INITIAL_DELAY,consumerHandler:this.publishEventToServer.bind(this)})}async initialize(e){if(!e||e.length===0)throw new Error("[CPIX] At least one instance configuration is required for initialization");if(this.instances=e,n.DEBUG=this.instances[0].options.debug===!0,n.API_URL=this.instances[0].options.tracker_server_url,n.USER_PROPERTIES=this.instances[0].options.user_properties||{},n.SESSION_EXPIRY_DAYS=this.instances[0].options.session_expiry_days||14,n.COMMON_PROPERTIES=this.instances[0].options.common_properties||{},s.exists(c.SESSION)||(s.createSession(),this.sessionCreated=!0),s.exists(c.META_PARAMETERS)||await this.generateMetaParameters().then(t=>{this.metaParameters=t,s.set("metaParameters",JSON.stringify(t),60*24)}),s.setUtms(),this.metaParameters=JSON.parse(s.get("metaParameters")),this.initialized)throw new Error("[CPIX] CarterAnalytics SDK has already been initialized");if(!this.metaParameters)throw new Error("[CPIX] Meta parameters have not been generated");s.exists(c.ACCESS_TOKEN)||(this.accessToken=await d.aquireAccessToken(this.instances[0].client_id),s.set(c.ACCESS_TOKEN,this.accessToken,60*4)),this.initialized=!0,u.debug("CPIX Initialized"),u.debug("Carter Analytics SDK initialized with options:",this.instances),this.sessionCreated&&this.publishInit(),this.attachHistoryListener()}publishInit(){this.publish({event:"init",user_properties:n.USER_PROPERTIES,...this.metaParameters})}attachHistoryListener(){const e=history.pushState,t=history.replaceState,i=()=>{this.publish({event:"page_view",event_properties:{title:document.title,page:window.location.pathname,url:window.location.href},user_properties:n.USER_PROPERTIES,...this.metaParameters})};history.pushState=(...r)=>{e.apply(history,r),i()},history.replaceState=(...r)=>{t.apply(history,r),i()},window.addEventListener("popstate",i),i()}publish(e){if(!this.initialized)throw new Error("[CPIX] CarterAnalytics SDK has not been initialized. Please initialize before publishing events.");const t={...e,...this.metaParameters};t.utm_params=s.getUtms(),document.referrer&&(t.referrer=encodeURIComponent(document.referrer)),u.debug("Publishing event:",t),this.queue.publish(t),e.event==="logout"&&(s.delete(c.SESSION),s.delete(c.META_PARAMETERS),s.createSession(),this.generateMetaParameters().then(i=>{this.metaParameters=i,s.set(c.META_PARAMETERS,JSON.stringify(this.metaParameters),60*24),this.publishInit()}))}async generateMetaParameters(){if(!window)throw new Error("[CPIX] Meta parameters can only be generated in a browser environment");const e=await d.getDeviceNetworkParameters();return{client_id:this.instances[0].client_id,session:s.get(c.SESSION),location:{city:e.city,region:e.region,loc:e.loc,timezone:e.timezone,country:e.country},device:{category:d.getDeviceCategory(),brand:d.getDeviceManufacturer(),ip_address:e.ip_address,platform:d.getDevicePlatform(),cpix_sdk_version:n.version},referrer:encodeURIComponent(document.referrer)}}async publishEventToServer(e){try{e.timestamp=Date.now(),e.event_properties={url:window.location.href,...n.COMMON_PROPERTIES,...e.event_properties},e.device&&(e.device.cpix_sdk_version=n.version);const t=await fetch(`${n.API_URL}/api/event`,{method:"POST",body:JSON.stringify({event_data:e}),headers:{"Content-Type":"application/json",Authorization:`Bearer ${s.get(c.ACCESS_TOKEN)}`}});if(!t.ok)throw t.status===401&&(this.accessToken=await d.aquireAccessToken(this.instances[0].client_id),s.set(c.ACCESS_TOKEN,this.accessToken,60*4)),new Error("[CPIX] Failed to publish event");u.debug("Event published:",t.ok)}catch(t){throw u.error("Failed to publish event:",t),new Error("[CPIX] Failed to publish event")}}}const w=new N;typeof window<"u"&&(window.cpix=w);exports.CarterAnalytics=w;
1
+ "use strict";var w=Object.defineProperty;var y=(l,e,t)=>e in l?w(l,e,{enumerable:!0,configurable:!0,writable:!0,value:t}):l[e]=t;var u=(l,e,t)=>(y(l,typeof e!="symbol"?e+"":e,t),t);Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const v="@carter-rmn/cpix-js",P="1.0.7",_="module",A=["dist"],T="dist/cpix.umd.cjs",R="dist/cpix.js",I="dist/cpix.d.ts",b={".":{import:"./dist/cpix.js",require:"./dist/cpix.umd.cjs"}},x={dev:"vite",build:"tsc && vite build",preview:"vite preview"},M={picocolors:"^1.0.0","rollup-plugin-visualizer":"^5.12.0",typescript:"^5.2.2",vite:"^5.2.0","vite-plugin-progress":"^0.0.7"},U={"vite-plugin-dts":"^3.8.1"},m={name:v,version:P,type:_,files:A,main:T,module:R,types:I,exports:b,scripts:x,devDependencies:M,dependencies:U},a={DEBUG:!1,TRACKER_FUNC_NAME:"cpix",API_URL:"",QUEUE_MAX_RETRIES:3,QUEUE_INITIAL_DELAY:1e4,version:m.version,package:m.name,USER_PROPERTIES:{},SESSION_EXPIRY_DAYS:14,COMMON_PROPERTIES:{}},n={SESSION:"cpix_session",META_PARAMETERS:"cpix_meta_parameters",ACCESS_TOKEN:"cpix_access_token",UTM:"cpix_utm"},O=["utm_source","utm_medium","utm_term","utm_content","utm_campaign"],o=function(){const l=()=>a.DEBUG;return{info:function(...e){console.log(...e)},debug:function(...e){l()&&console.log(...e)},error:function(...e){console.error(...e)}}}();class C extends EventTarget{constructor(t={maxRetries:3,initialDelay:1e4,consumerHandler:i=>(o.debug("Consuming event:",i),Promise.resolve())}){super();u(this,"dataQueue");u(this,"retryQueue");u(this,"maxRetries");u(this,"initialDelay");u(this,"publishEvent");u(this,"retryEvent");u(this,"handler");this.dataQueue=[],this.retryQueue=[],this.maxRetries=t.maxRetries,this.initialDelay=t.initialDelay,this.handler=t.consumerHandler,this.publishEvent=new Event("eventPublished"),this.retryEvent=new Event("retryMessage"),this.consume(),this.retry()}publish(t){o.debug("publishing event");const i={data:t,id:`${Date.now()+Math.random()}`,retryCount:0,retryDelay:this.initialDelay};this.dataQueue.push(i),this.dispatchEvent(this.publishEvent)}consume(){o.debug("Started Consumer Queue"),this.addEventListener("eventPublished",async()=>{for(;this.dataQueue.length>0;){const t=this.dataQueue.shift(),{data:i={}}=t;try{await this.handler(i),this.acknowledge(t==null?void 0:t.id)}catch(s){o.error("Failed to publish event:",s),this.scheduleRetry(t)}}})}scheduleRetry(t){if(t.retryCount>=this.maxRetries){o.error("Max retries reached for message:",t);return}setTimeout(()=>{this.retryQueue.push({...t,retryCount:t.retryCount+1,retryDelay:t.retryDelay*2}),this.dispatchEvent(this.retryEvent)},t.retryDelay)}acknowledge(t){this.dataQueue=this.dataQueue.filter(i=>i.id!==t)}retry(){o.debug("Started Retry Queue"),this.addEventListener("retryMessage",async()=>{for(;this.retryQueue.length>0;){const t=this.retryQueue.shift(),{data:i={}}=t;try{await this.handler(i),this.acknowledge(t==null?void 0:t.id)}catch(s){o.error("Failed to publish event:",s),this.scheduleRetry(t)}}})}}class d{static getBrowserInfo(){var s,c,p,f,g;const e=navigator.userAgent||"";let t,i;return/chrome/i.test(e)?(t="Chrome",i=(s=e.match(/chrome\/(\d+)/i))==null?void 0:s[1]):/firefox/i.test(e)?(t="Firefox",i=(c=e.match(/firefox\/(\d+)/i))==null?void 0:c[1]):/safari/i.test(e)?(t="Safari",i=(p=e.match(/version\/(\d+)/i))==null?void 0:p[1]):/edge/i.test(e)?(t="Edge",i=(f=e.match(/edge\/(\d+)/i))==null?void 0:f[1]):/trident/i.test(e)?(t="Internet Explorer",i=(g=e.match(/rv:(\d+)/i))==null?void 0:g[1]):(t="Unknown",i="Unknown"),`${t} ${i}`}static getDeviceCategory(){const e=navigator.userAgent;return/mobile/i.test(e)?"Mobile":/tablet/i.test(e)?"Tablet":"Desktop"}static getDevicePlatform(){const e=navigator.userAgent;return/android/i.test(e)?"Android":/iphone|ipad|ipod/i.test(e)?"iOS":/windows phone/i.test(e)?"Windows Phone":/mac|Macintosh/i.test(e)?"Mac":/windows|Microsoft/i.test(e)?"Windows":/linux/i.test(e)?"Linux":"Unknown"}static getDeviceManufacturer(){const e=navigator.userAgent;let t;return/iphone|ipad|ipod|mac|Macintosh/i.test(e)?t="Apple":/samsung/i.test(e)?t="Samsung":/google/i.test(e)?t="Google":/huawei/i.test(e)?t="Huawei":/xiaomi/i.test(e)?t="Xiaomi":/oneplus/i.test(e)?t="OnePlus":/dell/i.test(e)?t="Dell":/lenovo/i.test(e)?t="Lenovo":/acer/i.test(e)?t="Acer":/asus/i.test(e)?t="Asus":/toshiba/i.test(e)?t="Toshiba":t="Unknown",t}static async getDeviceNetworkParameters(){try{const e=await fetch(`${a.API_URL}/api/geolocation`),{data:t}=await e.json();return{city:t.city||"Unknown",region:t.region||"Unknown",country:t.country||"Unknown",timezone:t.timezone||"Unknown",loc:t.loc||"Unknown",ip_address:t.ip_address||"Unknown"}}catch(e){return o.error("Error retrieving device network parameters:",e),{city:"Unknown",region:"Unknown",country:"Unknown",timezone:"Unknown",loc:"Unknown",ip_address:"Unknown"}}}static async aquireAccessToken(e){try{return(await(await fetch(`${a.API_URL}/api/authenticate`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({accountId:e,metadata:{sdk:a.package,version:a.version,hostname:window.location.hostname}})})).json()).accessToken}catch(t){throw o.error("Error acquiring access token:",t),new Error("[CPIX] Authentication error")}}}class h{static isPresent(e){return typeof e<"u"&&e!==null&&e!==""}static now(){return 1*new Date().getTime()}static guid(){return m.version+"-xxxxxxxx-".replace(/[x]/g,function(e){const t=Math.random()*36|0;return(e=="x"?t:t&3|8).toString(36)})+(1*new Date().getTime()).toString(36)}static optionalData(e){return h.isPresent(e)===!1?"":typeof e=="object"?h.optionalData(JSON.stringify(e)):typeof e=="function"?h.optionalData(e()):String(e)}static sleep(e){return new Promise(t=>setTimeout(t,e))}}class E{static getParametersByName(e,t){t||(t=window.location.href),e=e.replace(/[[\]]/g,"\\$&");const i=new RegExp("[?&]"+e+"(=([^&#]*)|&|#|$)","gi"),s=[];let c;for(;(c=i.exec(t))!==null;)c[2]&&s.push(decodeURIComponent(c[2].replace(/\+/g," ")));return s.length>0?s:null}static externalHost(e){var t;return e.hostname!=location.hostname&&((t=e==null?void 0:e.protocol)==null?void 0:t.indexOf("http"))===0}}class r{static prefix(){return`__${a.TRACKER_FUNC_NAME}__`}static get(e){const t=`${r.prefix()}${e}`,i=document.cookie.split("; ").find(s=>s.startsWith(`${t}=`));return i?i.split("=")[1]:void 0}static set(e,t,i){const s=`${r.prefix()}${e}`,c=new Date;c.setTime(c.getTime()+i*60*1e3),document.cookie=`${s}=${t}; expires=${c.toUTCString()}; path=/`}static delete(e){const t=`${r.prefix()}${e}`;document.cookie=`${t}=; expires=Thu, 01 Jan 1970 00:00:00 UTC; path=/`}static clear(){document.cookie.split("; ").filter(e=>e.startsWith(r.prefix())).forEach(e=>{const t=e.split("=")[0];document.cookie=`${t}=; expires=Thu, 01 Jan 1970 00:00:00 UTC; path=/`})}static exists(e){return!!r.get(e)}static setUtms(){const e=O;let t=!1;for(let i=0;i<e.length;i++){const s=e[i];if(h.isPresent(E.getParametersByName(s,window.location.href))){t=!0;break}}if(t){let i;const s=[];for(let c=0;c<e.length;c++){const p=e[c];i=E.getParametersByName(p,window.location.href),s.push({[p]:encodeURIComponent(i)})}r.set(n.UTM,JSON.stringify(s),a.SESSION_EXPIRY_DAYS*24*60)}}static getUtms(){const e=r.get(n.UTM);return h.isPresent(e)?JSON.parse(e):{}}static createSession(e=!1){(e||!r.exists(n.SESSION))&&r.set(n.SESSION,h.guid(),a.SESSION_EXPIRY_DAYS*24*60),r.setUtms()}}class N{constructor(){u(this,"instances",[]);u(this,"initialized",!1);u(this,"sessionCreated",!1);u(this,"accessToken","");u(this,"metaParameters",{});u(this,"queue");if(!window)throw new Error("[CPIX] CarterAnalytics SDK can only be used in a browser environment");this.queue=new C({maxRetries:a.QUEUE_MAX_RETRIES,initialDelay:a.QUEUE_INITIAL_DELAY,consumerHandler:this.publishEventToServer.bind(this)})}async initialize(e){if(!e||e.length===0)throw new Error("[CPIX] At least one instance configuration is required for initialization");this.instances=e,a.DEBUG=this.instances[0].options.debug===!0,a.API_URL=this.instances[0].options.tracker_server_url,a.USER_PROPERTIES=this.instances[0].options.user_properties||{},a.SESSION_EXPIRY_DAYS=this.instances[0].options.session_expiry_days||14,a.COMMON_PROPERTIES=this.instances[0].options.common_properties||{},r.exists(n.SESSION)||(r.createSession(),this.sessionCreated=!0);const t=r.get(n.SESSION);if(!r.exists(n.META_PARAMETERS))this.metaParameters=await this.generateMetaParameters(),r.set(n.META_PARAMETERS,JSON.stringify(this.metaParameters),60*24);else{const i=r.get(n.META_PARAMETERS);if(i)try{const s=JSON.parse(i);s.session!==t?(o.debug("Session ID mismatch detected, regenerating meta parameters"),this.metaParameters=await this.generateMetaParameters(),r.set(n.META_PARAMETERS,JSON.stringify(this.metaParameters),60*24)):this.metaParameters=s}catch(s){o.error("Failed to parse meta parameters, regenerating:",s),this.metaParameters=await this.generateMetaParameters(),r.set(n.META_PARAMETERS,JSON.stringify(this.metaParameters),60*24)}else this.metaParameters=await this.generateMetaParameters(),r.set(n.META_PARAMETERS,JSON.stringify(this.metaParameters),60*24)}if(r.setUtms(),this.initialized)throw new Error("[CPIX] CarterAnalytics SDK has already been initialized");if(!this.metaParameters)throw new Error("[CPIX] Meta parameters have not been generated");r.exists(n.ACCESS_TOKEN)||(this.accessToken=await d.aquireAccessToken(this.instances[0].client_id),r.set(n.ACCESS_TOKEN,this.accessToken,60*4)),this.initialized=!0,o.debug("CPIX Initialized"),o.debug("Carter Analytics SDK initialized with options:",this.instances),this.sessionCreated&&this.publishInit(),this.attachHistoryListener()}publishInit(){this.publish({event:"init",user_properties:a.USER_PROPERTIES,...this.metaParameters})}attachHistoryListener(){const e=history.pushState,t=history.replaceState,i=()=>{this.publish({event:"page_view",event_properties:{title:document.title,page:window.location.pathname,url:window.location.href},user_properties:a.USER_PROPERTIES,...this.metaParameters})};history.pushState=(...s)=>{e.apply(history,s),i()},history.replaceState=(...s)=>{t.apply(history,s),i()},window.addEventListener("popstate",i),i()}publish(e){if(!this.initialized)throw new Error("[CPIX] CarterAnalytics SDK has not been initialized. Please initialize before publishing events.");const t={...e,...this.metaParameters};if(t.utm_params=r.getUtms(),document.referrer&&(t.referrer=encodeURIComponent(document.referrer)),o.debug("Publishing event:",t),this.queue.publish(t),e.event==="logout"){r.delete(n.SESSION),r.delete(n.META_PARAMETERS),r.createSession(!0);const i=r.get(n.SESSION);if(!i){o.error("[CPIX] Failed to create new session on logout");return}this.generateMetaParameters().then(s=>{s.session!==i&&(o.error("[CPIX] Session ID mismatch after logout, updating meta parameters"),s.session=i),this.metaParameters=s,r.set(n.META_PARAMETERS,JSON.stringify(this.metaParameters),60*24),this.publishInit()})}}async generateMetaParameters(){if(!window)throw new Error("[CPIX] Meta parameters can only be generated in a browser environment");const e=await d.getDeviceNetworkParameters();return{client_id:this.instances[0].client_id,session:r.get(n.SESSION),location:{city:e.city,region:e.region,loc:e.loc,timezone:e.timezone,country:e.country},device:{category:d.getDeviceCategory(),brand:d.getDeviceManufacturer(),ip_address:e.ip_address,platform:d.getDevicePlatform(),cpix_sdk_version:a.version},referrer:encodeURIComponent(document.referrer)}}async publishEventToServer(e){try{e.timestamp=Date.now(),e.event_properties={url:window.location.href,...a.COMMON_PROPERTIES,...e.event_properties},e.device&&(e.device.cpix_sdk_version=a.version);const t=await fetch(`${a.API_URL}/api/event`,{method:"POST",body:JSON.stringify({event_data:e}),headers:{"Content-Type":"application/json",Authorization:`Bearer ${r.get(n.ACCESS_TOKEN)}`}});if(!t.ok)throw t.status===401&&(this.accessToken=await d.aquireAccessToken(this.instances[0].client_id),r.set(n.ACCESS_TOKEN,this.accessToken,60*4)),new Error("[CPIX] Failed to publish event");o.debug("Event published:",t.ok)}catch(t){throw o.error("Failed to publish event:",t),new Error("[CPIX] Failed to publish event")}}}const S=new N;typeof window<"u"&&(window.cpix=S);exports.CarterAnalytics=S;
package/dist/cpix.iife.js CHANGED
@@ -1 +1 @@
1
- var tracker=function(l){"use strict";var b=Object.defineProperty;var x=(l,d,p)=>d in l?b(l,d,{enumerable:!0,configurable:!0,writable:!0,value:p}):l[d]=p;var u=(l,d,p)=>(x(l,typeof d!="symbol"?d+"":d,p),p);const E={name:"@carter-rmn/cpix-js",version:"1.0.5",type:"module",files:["dist"],main:"dist/cpix.umd.cjs",module:"dist/cpix.js",types:"dist/cpix.d.ts",exports:{".":{import:"./dist/cpix.js",require:"./dist/cpix.umd.cjs"}},scripts:{dev:"vite",build:"tsc && vite build",preview:"vite preview"},devDependencies:{picocolors:"^1.0.0","rollup-plugin-visualizer":"^5.12.0",typescript:"^5.2.2",vite:"^5.2.0","vite-plugin-progress":"^0.0.7"},dependencies:{"vite-plugin-dts":"^3.8.1"}},n={DEBUG:!1,TRACKER_FUNC_NAME:"cpix",API_URL:"",QUEUE_MAX_RETRIES:3,QUEUE_INITIAL_DELAY:1e4,version:E.version,package:E.name,USER_PROPERTIES:{},SESSION_EXPIRY_DAYS:14,COMMON_PROPERTIES:{}},a={SESSION:"cpix_session",META_PARAMETERS:"cpix_meta_parameters",ACCESS_TOKEN:"cpix_access_token",UTM:"cpix_utm"},P=["utm_source","utm_medium","utm_term","utm_content","utm_campaign"],o=function(){const f=()=>n.DEBUG;return{info:function(...e){console.log(...e)},debug:function(...e){f()&&console.log(...e)},error:function(...e){console.error(...e)}}}();class _ extends EventTarget{constructor(t={maxRetries:3,initialDelay:1e4,consumerHandler:i=>(o.debug("Consuming event:",i),Promise.resolve())}){super();u(this,"dataQueue");u(this,"retryQueue");u(this,"maxRetries");u(this,"initialDelay");u(this,"publishEvent");u(this,"retryEvent");u(this,"handler");this.dataQueue=[],this.retryQueue=[],this.maxRetries=t.maxRetries,this.initialDelay=t.initialDelay,this.handler=t.consumerHandler,this.publishEvent=new Event("eventPublished"),this.retryEvent=new Event("retryMessage"),this.consume(),this.retry()}publish(t){o.debug("publishing event");const i={data:t,id:`${Date.now()+Math.random()}`,retryCount:0,retryDelay:this.initialDelay};this.dataQueue.push(i),this.dispatchEvent(this.publishEvent)}consume(){o.debug("Started Consumer Queue"),this.addEventListener("eventPublished",async()=>{for(;this.dataQueue.length>0;){const t=this.dataQueue.shift(),{data:i={}}=t;try{await this.handler(i),this.acknowledge(t==null?void 0:t.id)}catch(r){o.error("Failed to publish event:",r),this.scheduleRetry(t)}}})}scheduleRetry(t){if(t.retryCount>=this.maxRetries){o.error("Max retries reached for message:",t);return}setTimeout(()=>{this.retryQueue.push({...t,retryCount:t.retryCount+1,retryDelay:t.retryDelay*2}),this.dispatchEvent(this.retryEvent)},t.retryDelay)}acknowledge(t){this.dataQueue=this.dataQueue.filter(i=>i.id!==t)}retry(){o.debug("Started Retry Queue"),this.addEventListener("retryMessage",async()=>{for(;this.retryQueue.length>0;){const t=this.retryQueue.shift(),{data:i={}}=t;try{await this.handler(i),this.acknowledge(t==null?void 0:t.id)}catch(r){o.error("Failed to publish event:",r),this.scheduleRetry(t)}}})}}class m{static getBrowserInfo(){var r,c,g,S,v;const e=navigator.userAgent||"";let t,i;return/chrome/i.test(e)?(t="Chrome",i=(r=e.match(/chrome\/(\d+)/i))==null?void 0:r[1]):/firefox/i.test(e)?(t="Firefox",i=(c=e.match(/firefox\/(\d+)/i))==null?void 0:c[1]):/safari/i.test(e)?(t="Safari",i=(g=e.match(/version\/(\d+)/i))==null?void 0:g[1]):/edge/i.test(e)?(t="Edge",i=(S=e.match(/edge\/(\d+)/i))==null?void 0:S[1]):/trident/i.test(e)?(t="Internet Explorer",i=(v=e.match(/rv:(\d+)/i))==null?void 0:v[1]):(t="Unknown",i="Unknown"),`${t} ${i}`}static getDeviceCategory(){const e=navigator.userAgent;return/mobile/i.test(e)?"Mobile":/tablet/i.test(e)?"Tablet":"Desktop"}static getDevicePlatform(){const e=navigator.userAgent;return/android/i.test(e)?"Android":/iphone|ipad|ipod/i.test(e)?"iOS":/windows phone/i.test(e)?"Windows Phone":/mac|Macintosh/i.test(e)?"Mac":/windows|Microsoft/i.test(e)?"Windows":/linux/i.test(e)?"Linux":"Unknown"}static getDeviceManufacturer(){const e=navigator.userAgent;let t;return/iphone|ipad|ipod|mac|Macintosh/i.test(e)?t="Apple":/samsung/i.test(e)?t="Samsung":/google/i.test(e)?t="Google":/huawei/i.test(e)?t="Huawei":/xiaomi/i.test(e)?t="Xiaomi":/oneplus/i.test(e)?t="OnePlus":/dell/i.test(e)?t="Dell":/lenovo/i.test(e)?t="Lenovo":/acer/i.test(e)?t="Acer":/asus/i.test(e)?t="Asus":/toshiba/i.test(e)?t="Toshiba":t="Unknown",t}static async getDeviceNetworkParameters(){try{const e=await fetch(`${n.API_URL}/api/geolocation`),{data:t}=await e.json();return{city:t.city||"Unknown",region:t.region||"Unknown",country:t.country||"Unknown",timezone:t.timezone||"Unknown",loc:t.loc||"Unknown",ip_address:t.ip_address||"Unknown"}}catch(e){return o.error("Error retrieving device network parameters:",e),{city:"Unknown",region:"Unknown",country:"Unknown",timezone:"Unknown",loc:"Unknown",ip_address:"Unknown"}}}static async aquireAccessToken(e){try{return(await(await fetch(`${n.API_URL}/api/authenticate`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({accountId:e,metadata:{sdk:n.package,version:n.version,hostname:window.location.hostname}})})).json()).accessToken}catch(t){throw o.error("Error acquiring access token:",t),new Error("[CPIX] Authentication error")}}}class h{static isPresent(e){return typeof e<"u"&&e!==null&&e!==""}static now(){return 1*new Date().getTime()}static guid(){return E.version+"-xxxxxxxx-".replace(/[x]/g,function(e){const t=Math.random()*36|0;return(e=="x"?t:t&3|8).toString(36)})+(1*new Date().getTime()).toString(36)}static optionalData(e){return h.isPresent(e)===!1?"":typeof e=="object"?h.optionalData(JSON.stringify(e)):typeof e=="function"?h.optionalData(e()):String(e)}static sleep(e){return new Promise(t=>setTimeout(t,e))}}class w{static getParametersByName(e,t){t||(t=window.location.href),e=e.replace(/[[\]]/g,"\\$&");const i=new RegExp("[?&]"+e+"(=([^&#]*)|&|#|$)","gi"),r=[];let c;for(;(c=i.exec(t))!==null;)c[2]&&r.push(decodeURIComponent(c[2].replace(/\+/g," ")));return r.length>0?r:null}static externalHost(e){var t;return e.hostname!=location.hostname&&((t=e==null?void 0:e.protocol)==null?void 0:t.indexOf("http"))===0}}class s{static prefix(){return`__${n.TRACKER_FUNC_NAME}__`}static get(e){const t=`${s.prefix()}${e}`,i=document.cookie.split("; ").find(r=>r.startsWith(`${t}=`));return i?i.split("=")[1]:void 0}static set(e,t,i){const r=`${s.prefix()}${e}`,c=new Date;c.setTime(c.getTime()+i*60*1e3),document.cookie=`${r}=${t}; expires=${c.toUTCString()}; path=/`}static delete(e){const t=`${s.prefix()}${e}`;document.cookie=`${t}=; expires=Thu, 01 Jan 1970 00:00:00 UTC; path=/`}static clear(){document.cookie.split("; ").filter(e=>e.startsWith(s.prefix())).forEach(e=>{const t=e.split("=")[0];document.cookie=`${t}=; expires=Thu, 01 Jan 1970 00:00:00 UTC; path=/`})}static exists(e){return!!s.get(e)}static setUtms(){const e=P;let t=!1;for(let i=0;i<e.length;i++){const r=e[i];if(h.isPresent(w.getParametersByName(r,window.location.href))){t=!0;break}}if(t){let i;const r=[];for(let c=0;c<e.length;c++){const g=e[c];i=w.getParametersByName(g,window.location.href),r.push({[g]:encodeURIComponent(i)})}s.set(a.UTM,JSON.stringify(r),n.SESSION_EXPIRY_DAYS*24*60)}}static getUtms(){const e=s.get(a.UTM);return h.isPresent(e)?JSON.parse(e):{}}static createSession(){s.exists(a.SESSION)||s.set(a.SESSION,h.guid(),n.SESSION_EXPIRY_DAYS*24*60),s.setUtms()}}class A{constructor(){u(this,"instances",[]);u(this,"initialized",!1);u(this,"sessionCreated",!1);u(this,"accessToken","");u(this,"metaParameters",{});u(this,"queue");if(!window)throw new Error("[CPIX] CarterAnalytics SDK can only be used in a browser environment");this.queue=new _({maxRetries:n.QUEUE_MAX_RETRIES,initialDelay:n.QUEUE_INITIAL_DELAY,consumerHandler:this.publishEventToServer.bind(this)})}async initialize(e){if(!e||e.length===0)throw new Error("[CPIX] At least one instance configuration is required for initialization");if(this.instances=e,n.DEBUG=this.instances[0].options.debug===!0,n.API_URL=this.instances[0].options.tracker_server_url,n.USER_PROPERTIES=this.instances[0].options.user_properties||{},n.SESSION_EXPIRY_DAYS=this.instances[0].options.session_expiry_days||14,n.COMMON_PROPERTIES=this.instances[0].options.common_properties||{},s.exists(a.SESSION)||(s.createSession(),this.sessionCreated=!0),s.exists(a.META_PARAMETERS)||await this.generateMetaParameters().then(t=>{this.metaParameters=t,s.set("metaParameters",JSON.stringify(t),1440)}),s.setUtms(),this.metaParameters=JSON.parse(s.get("metaParameters")),this.initialized)throw new Error("[CPIX] CarterAnalytics SDK has already been initialized");if(!this.metaParameters)throw new Error("[CPIX] Meta parameters have not been generated");s.exists(a.ACCESS_TOKEN)||(this.accessToken=await m.aquireAccessToken(this.instances[0].client_id),s.set(a.ACCESS_TOKEN,this.accessToken,240)),this.initialized=!0,o.debug("CPIX Initialized"),o.debug("Carter Analytics SDK initialized with options:",this.instances),this.sessionCreated&&this.publishInit(),this.attachHistoryListener()}publishInit(){this.publish({event:"init",user_properties:n.USER_PROPERTIES,...this.metaParameters})}attachHistoryListener(){const e=history.pushState,t=history.replaceState,i=()=>{this.publish({event:"page_view",event_properties:{title:document.title,page:window.location.pathname,url:window.location.href},user_properties:n.USER_PROPERTIES,...this.metaParameters})};history.pushState=(...r)=>{e.apply(history,r),i()},history.replaceState=(...r)=>{t.apply(history,r),i()},window.addEventListener("popstate",i),i()}publish(e){if(!this.initialized)throw new Error("[CPIX] CarterAnalytics SDK has not been initialized. Please initialize before publishing events.");const t={...e,...this.metaParameters};t.utm_params=s.getUtms(),document.referrer&&(t.referrer=encodeURIComponent(document.referrer)),o.debug("Publishing event:",t),this.queue.publish(t),e.event==="logout"&&(s.delete(a.SESSION),s.delete(a.META_PARAMETERS),s.createSession(),this.generateMetaParameters().then(i=>{this.metaParameters=i,s.set(a.META_PARAMETERS,JSON.stringify(this.metaParameters),1440),this.publishInit()}))}async generateMetaParameters(){if(!window)throw new Error("[CPIX] Meta parameters can only be generated in a browser environment");const e=await m.getDeviceNetworkParameters();return{client_id:this.instances[0].client_id,session:s.get(a.SESSION),location:{city:e.city,region:e.region,loc:e.loc,timezone:e.timezone,country:e.country},device:{category:m.getDeviceCategory(),brand:m.getDeviceManufacturer(),ip_address:e.ip_address,platform:m.getDevicePlatform(),cpix_sdk_version:n.version},referrer:encodeURIComponent(document.referrer)}}async publishEventToServer(e){try{e.timestamp=Date.now(),e.event_properties={url:window.location.href,...n.COMMON_PROPERTIES,...e.event_properties},e.device&&(e.device.cpix_sdk_version=n.version);const t=await fetch(`${n.API_URL}/api/event`,{method:"POST",body:JSON.stringify({event_data:e}),headers:{"Content-Type":"application/json",Authorization:`Bearer ${s.get(a.ACCESS_TOKEN)}`}});if(!t.ok)throw t.status===401&&(this.accessToken=await m.aquireAccessToken(this.instances[0].client_id),s.set(a.ACCESS_TOKEN,this.accessToken,240)),new Error("[CPIX] Failed to publish event");o.debug("Event published:",t.ok)}catch(t){throw o.error("Failed to publish event:",t),new Error("[CPIX] Failed to publish event")}}}const y=new A;return typeof window<"u"&&(window.cpix=y),l.CarterAnalytics=y,Object.defineProperty(l,Symbol.toStringTag,{value:"Module"}),l}({});
1
+ var tracker=function(l){"use strict";var T=Object.defineProperty;var R=(l,h,p)=>h in l?T(l,h,{enumerable:!0,configurable:!0,writable:!0,value:p}):l[h]=p;var u=(l,h,p)=>(R(l,typeof h!="symbol"?h+"":h,p),p);const E={name:"@carter-rmn/cpix-js",version:"1.0.7",type:"module",files:["dist"],main:"dist/cpix.umd.cjs",module:"dist/cpix.js",types:"dist/cpix.d.ts",exports:{".":{import:"./dist/cpix.js",require:"./dist/cpix.umd.cjs"}},scripts:{dev:"vite",build:"tsc && vite build",preview:"vite preview"},devDependencies:{picocolors:"^1.0.0","rollup-plugin-visualizer":"^5.12.0",typescript:"^5.2.2",vite:"^5.2.0","vite-plugin-progress":"^0.0.7"},dependencies:{"vite-plugin-dts":"^3.8.1"}},n={DEBUG:!1,TRACKER_FUNC_NAME:"cpix",API_URL:"",QUEUE_MAX_RETRIES:3,QUEUE_INITIAL_DELAY:1e4,version:E.version,package:E.name,USER_PROPERTIES:{},SESSION_EXPIRY_DAYS:14,COMMON_PROPERTIES:{}},a={SESSION:"cpix_session",META_PARAMETERS:"cpix_meta_parameters",ACCESS_TOKEN:"cpix_access_token",UTM:"cpix_utm"},P=["utm_source","utm_medium","utm_term","utm_content","utm_campaign"],o=function(){const f=()=>n.DEBUG;return{info:function(...e){console.log(...e)},debug:function(...e){f()&&console.log(...e)},error:function(...e){console.error(...e)}}}();class _ extends EventTarget{constructor(t={maxRetries:3,initialDelay:1e4,consumerHandler:i=>(o.debug("Consuming event:",i),Promise.resolve())}){super();u(this,"dataQueue");u(this,"retryQueue");u(this,"maxRetries");u(this,"initialDelay");u(this,"publishEvent");u(this,"retryEvent");u(this,"handler");this.dataQueue=[],this.retryQueue=[],this.maxRetries=t.maxRetries,this.initialDelay=t.initialDelay,this.handler=t.consumerHandler,this.publishEvent=new Event("eventPublished"),this.retryEvent=new Event("retryMessage"),this.consume(),this.retry()}publish(t){o.debug("publishing event");const i={data:t,id:`${Date.now()+Math.random()}`,retryCount:0,retryDelay:this.initialDelay};this.dataQueue.push(i),this.dispatchEvent(this.publishEvent)}consume(){o.debug("Started Consumer Queue"),this.addEventListener("eventPublished",async()=>{for(;this.dataQueue.length>0;){const t=this.dataQueue.shift(),{data:i={}}=t;try{await this.handler(i),this.acknowledge(t==null?void 0:t.id)}catch(r){o.error("Failed to publish event:",r),this.scheduleRetry(t)}}})}scheduleRetry(t){if(t.retryCount>=this.maxRetries){o.error("Max retries reached for message:",t);return}setTimeout(()=>{this.retryQueue.push({...t,retryCount:t.retryCount+1,retryDelay:t.retryDelay*2}),this.dispatchEvent(this.retryEvent)},t.retryDelay)}acknowledge(t){this.dataQueue=this.dataQueue.filter(i=>i.id!==t)}retry(){o.debug("Started Retry Queue"),this.addEventListener("retryMessage",async()=>{for(;this.retryQueue.length>0;){const t=this.retryQueue.shift(),{data:i={}}=t;try{await this.handler(i),this.acknowledge(t==null?void 0:t.id)}catch(r){o.error("Failed to publish event:",r),this.scheduleRetry(t)}}})}}class m{static getBrowserInfo(){var r,c,g,y,v;const e=navigator.userAgent||"";let t,i;return/chrome/i.test(e)?(t="Chrome",i=(r=e.match(/chrome\/(\d+)/i))==null?void 0:r[1]):/firefox/i.test(e)?(t="Firefox",i=(c=e.match(/firefox\/(\d+)/i))==null?void 0:c[1]):/safari/i.test(e)?(t="Safari",i=(g=e.match(/version\/(\d+)/i))==null?void 0:g[1]):/edge/i.test(e)?(t="Edge",i=(y=e.match(/edge\/(\d+)/i))==null?void 0:y[1]):/trident/i.test(e)?(t="Internet Explorer",i=(v=e.match(/rv:(\d+)/i))==null?void 0:v[1]):(t="Unknown",i="Unknown"),`${t} ${i}`}static getDeviceCategory(){const e=navigator.userAgent;return/mobile/i.test(e)?"Mobile":/tablet/i.test(e)?"Tablet":"Desktop"}static getDevicePlatform(){const e=navigator.userAgent;return/android/i.test(e)?"Android":/iphone|ipad|ipod/i.test(e)?"iOS":/windows phone/i.test(e)?"Windows Phone":/mac|Macintosh/i.test(e)?"Mac":/windows|Microsoft/i.test(e)?"Windows":/linux/i.test(e)?"Linux":"Unknown"}static getDeviceManufacturer(){const e=navigator.userAgent;let t;return/iphone|ipad|ipod|mac|Macintosh/i.test(e)?t="Apple":/samsung/i.test(e)?t="Samsung":/google/i.test(e)?t="Google":/huawei/i.test(e)?t="Huawei":/xiaomi/i.test(e)?t="Xiaomi":/oneplus/i.test(e)?t="OnePlus":/dell/i.test(e)?t="Dell":/lenovo/i.test(e)?t="Lenovo":/acer/i.test(e)?t="Acer":/asus/i.test(e)?t="Asus":/toshiba/i.test(e)?t="Toshiba":t="Unknown",t}static async getDeviceNetworkParameters(){try{const e=await fetch(`${n.API_URL}/api/geolocation`),{data:t}=await e.json();return{city:t.city||"Unknown",region:t.region||"Unknown",country:t.country||"Unknown",timezone:t.timezone||"Unknown",loc:t.loc||"Unknown",ip_address:t.ip_address||"Unknown"}}catch(e){return o.error("Error retrieving device network parameters:",e),{city:"Unknown",region:"Unknown",country:"Unknown",timezone:"Unknown",loc:"Unknown",ip_address:"Unknown"}}}static async aquireAccessToken(e){try{return(await(await fetch(`${n.API_URL}/api/authenticate`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({accountId:e,metadata:{sdk:n.package,version:n.version,hostname:window.location.hostname}})})).json()).accessToken}catch(t){throw o.error("Error acquiring access token:",t),new Error("[CPIX] Authentication error")}}}class d{static isPresent(e){return typeof e<"u"&&e!==null&&e!==""}static now(){return 1*new Date().getTime()}static guid(){return E.version+"-xxxxxxxx-".replace(/[x]/g,function(e){const t=Math.random()*36|0;return(e=="x"?t:t&3|8).toString(36)})+(1*new Date().getTime()).toString(36)}static optionalData(e){return d.isPresent(e)===!1?"":typeof e=="object"?d.optionalData(JSON.stringify(e)):typeof e=="function"?d.optionalData(e()):String(e)}static sleep(e){return new Promise(t=>setTimeout(t,e))}}class S{static getParametersByName(e,t){t||(t=window.location.href),e=e.replace(/[[\]]/g,"\\$&");const i=new RegExp("[?&]"+e+"(=([^&#]*)|&|#|$)","gi"),r=[];let c;for(;(c=i.exec(t))!==null;)c[2]&&r.push(decodeURIComponent(c[2].replace(/\+/g," ")));return r.length>0?r:null}static externalHost(e){var t;return e.hostname!=location.hostname&&((t=e==null?void 0:e.protocol)==null?void 0:t.indexOf("http"))===0}}class s{static prefix(){return`__${n.TRACKER_FUNC_NAME}__`}static get(e){const t=`${s.prefix()}${e}`,i=document.cookie.split("; ").find(r=>r.startsWith(`${t}=`));return i?i.split("=")[1]:void 0}static set(e,t,i){const r=`${s.prefix()}${e}`,c=new Date;c.setTime(c.getTime()+i*60*1e3),document.cookie=`${r}=${t}; expires=${c.toUTCString()}; path=/`}static delete(e){const t=`${s.prefix()}${e}`;document.cookie=`${t}=; expires=Thu, 01 Jan 1970 00:00:00 UTC; path=/`}static clear(){document.cookie.split("; ").filter(e=>e.startsWith(s.prefix())).forEach(e=>{const t=e.split("=")[0];document.cookie=`${t}=; expires=Thu, 01 Jan 1970 00:00:00 UTC; path=/`})}static exists(e){return!!s.get(e)}static setUtms(){const e=P;let t=!1;for(let i=0;i<e.length;i++){const r=e[i];if(d.isPresent(S.getParametersByName(r,window.location.href))){t=!0;break}}if(t){let i;const r=[];for(let c=0;c<e.length;c++){const g=e[c];i=S.getParametersByName(g,window.location.href),r.push({[g]:encodeURIComponent(i)})}s.set(a.UTM,JSON.stringify(r),n.SESSION_EXPIRY_DAYS*24*60)}}static getUtms(){const e=s.get(a.UTM);return d.isPresent(e)?JSON.parse(e):{}}static createSession(e=!1){(e||!s.exists(a.SESSION))&&s.set(a.SESSION,d.guid(),n.SESSION_EXPIRY_DAYS*24*60),s.setUtms()}}class A{constructor(){u(this,"instances",[]);u(this,"initialized",!1);u(this,"sessionCreated",!1);u(this,"accessToken","");u(this,"metaParameters",{});u(this,"queue");if(!window)throw new Error("[CPIX] CarterAnalytics SDK can only be used in a browser environment");this.queue=new _({maxRetries:n.QUEUE_MAX_RETRIES,initialDelay:n.QUEUE_INITIAL_DELAY,consumerHandler:this.publishEventToServer.bind(this)})}async initialize(e){if(!e||e.length===0)throw new Error("[CPIX] At least one instance configuration is required for initialization");this.instances=e,n.DEBUG=this.instances[0].options.debug===!0,n.API_URL=this.instances[0].options.tracker_server_url,n.USER_PROPERTIES=this.instances[0].options.user_properties||{},n.SESSION_EXPIRY_DAYS=this.instances[0].options.session_expiry_days||14,n.COMMON_PROPERTIES=this.instances[0].options.common_properties||{},s.exists(a.SESSION)||(s.createSession(),this.sessionCreated=!0);const t=s.get(a.SESSION);if(!s.exists(a.META_PARAMETERS))this.metaParameters=await this.generateMetaParameters(),s.set(a.META_PARAMETERS,JSON.stringify(this.metaParameters),1440);else{const i=s.get(a.META_PARAMETERS);if(i)try{const r=JSON.parse(i);r.session!==t?(o.debug("Session ID mismatch detected, regenerating meta parameters"),this.metaParameters=await this.generateMetaParameters(),s.set(a.META_PARAMETERS,JSON.stringify(this.metaParameters),1440)):this.metaParameters=r}catch(r){o.error("Failed to parse meta parameters, regenerating:",r),this.metaParameters=await this.generateMetaParameters(),s.set(a.META_PARAMETERS,JSON.stringify(this.metaParameters),1440)}else this.metaParameters=await this.generateMetaParameters(),s.set(a.META_PARAMETERS,JSON.stringify(this.metaParameters),1440)}if(s.setUtms(),this.initialized)throw new Error("[CPIX] CarterAnalytics SDK has already been initialized");if(!this.metaParameters)throw new Error("[CPIX] Meta parameters have not been generated");s.exists(a.ACCESS_TOKEN)||(this.accessToken=await m.aquireAccessToken(this.instances[0].client_id),s.set(a.ACCESS_TOKEN,this.accessToken,240)),this.initialized=!0,o.debug("CPIX Initialized"),o.debug("Carter Analytics SDK initialized with options:",this.instances),this.sessionCreated&&this.publishInit(),this.attachHistoryListener()}publishInit(){this.publish({event:"init",user_properties:n.USER_PROPERTIES,...this.metaParameters})}attachHistoryListener(){const e=history.pushState,t=history.replaceState,i=()=>{this.publish({event:"page_view",event_properties:{title:document.title,page:window.location.pathname,url:window.location.href},user_properties:n.USER_PROPERTIES,...this.metaParameters})};history.pushState=(...r)=>{e.apply(history,r),i()},history.replaceState=(...r)=>{t.apply(history,r),i()},window.addEventListener("popstate",i),i()}publish(e){if(!this.initialized)throw new Error("[CPIX] CarterAnalytics SDK has not been initialized. Please initialize before publishing events.");const t={...e,...this.metaParameters};if(t.utm_params=s.getUtms(),document.referrer&&(t.referrer=encodeURIComponent(document.referrer)),o.debug("Publishing event:",t),this.queue.publish(t),e.event==="logout"){s.delete(a.SESSION),s.delete(a.META_PARAMETERS),s.createSession(!0);const i=s.get(a.SESSION);if(!i){o.error("[CPIX] Failed to create new session on logout");return}this.generateMetaParameters().then(r=>{r.session!==i&&(o.error("[CPIX] Session ID mismatch after logout, updating meta parameters"),r.session=i),this.metaParameters=r,s.set(a.META_PARAMETERS,JSON.stringify(this.metaParameters),1440),this.publishInit()})}}async generateMetaParameters(){if(!window)throw new Error("[CPIX] Meta parameters can only be generated in a browser environment");const e=await m.getDeviceNetworkParameters();return{client_id:this.instances[0].client_id,session:s.get(a.SESSION),location:{city:e.city,region:e.region,loc:e.loc,timezone:e.timezone,country:e.country},device:{category:m.getDeviceCategory(),brand:m.getDeviceManufacturer(),ip_address:e.ip_address,platform:m.getDevicePlatform(),cpix_sdk_version:n.version},referrer:encodeURIComponent(document.referrer)}}async publishEventToServer(e){try{e.timestamp=Date.now(),e.event_properties={url:window.location.href,...n.COMMON_PROPERTIES,...e.event_properties},e.device&&(e.device.cpix_sdk_version=n.version);const t=await fetch(`${n.API_URL}/api/event`,{method:"POST",body:JSON.stringify({event_data:e}),headers:{"Content-Type":"application/json",Authorization:`Bearer ${s.get(a.ACCESS_TOKEN)}`}});if(!t.ok)throw t.status===401&&(this.accessToken=await m.aquireAccessToken(this.instances[0].client_id),s.set(a.ACCESS_TOKEN,this.accessToken,240)),new Error("[CPIX] Failed to publish event");o.debug("Event published:",t.ok)}catch(t){throw o.error("Failed to publish event:",t),new Error("[CPIX] Failed to publish event")}}}const w=new A;return typeof window<"u"&&(window.cpix=w),l.CarterAnalytics=w,Object.defineProperty(l,Symbol.toStringTag,{value:"Module"}),l}({});
package/dist/cpix.js CHANGED
@@ -1,18 +1,18 @@
1
1
  var w = Object.defineProperty;
2
- var y = (l, e, t) => e in l ? w(l, e, { enumerable: !0, configurable: !0, writable: !0, value: t }) : l[e] = t;
3
- var o = (l, e, t) => (y(l, typeof e != "symbol" ? e + "" : e, t), t);
4
- const S = "@carter-rmn/cpix-js", v = "1.0.5", P = "module", _ = [
2
+ var S = (l, e, t) => e in l ? w(l, e, { enumerable: !0, configurable: !0, writable: !0, value: t }) : l[e] = t;
3
+ var u = (l, e, t) => (S(l, typeof e != "symbol" ? e + "" : e, t), t);
4
+ const y = "@carter-rmn/cpix-js", v = "1.0.7", P = "module", _ = [
5
5
  "dist"
6
- ], x = "dist/cpix.umd.cjs", A = "dist/cpix.js", R = "dist/cpix.d.ts", T = {
6
+ ], A = "dist/cpix.umd.cjs", R = "dist/cpix.js", T = "dist/cpix.d.ts", I = {
7
7
  ".": {
8
8
  import: "./dist/cpix.js",
9
9
  require: "./dist/cpix.umd.cjs"
10
10
  }
11
- }, b = {
11
+ }, x = {
12
12
  dev: "vite",
13
13
  build: "tsc && vite build",
14
14
  preview: "vite preview"
15
- }, I = {
15
+ }, b = {
16
16
  picocolors: "^1.0.0",
17
17
  "rollup-plugin-visualizer": "^5.12.0",
18
18
  typescript: "^5.2.2",
@@ -21,18 +21,18 @@ const S = "@carter-rmn/cpix-js", v = "1.0.5", P = "module", _ = [
21
21
  }, U = {
22
22
  "vite-plugin-dts": "^3.8.1"
23
23
  }, m = {
24
- name: S,
24
+ name: y,
25
25
  version: v,
26
26
  type: P,
27
27
  files: _,
28
- main: x,
29
- module: A,
30
- types: R,
31
- exports: T,
32
- scripts: b,
33
- devDependencies: I,
28
+ main: A,
29
+ module: R,
30
+ types: T,
31
+ exports: I,
32
+ scripts: x,
33
+ devDependencies: b,
34
34
  dependencies: U
35
- }, n = {
35
+ }, a = {
36
36
  DEBUG: !1,
37
37
  TRACKER_FUNC_NAME: "cpix",
38
38
  API_URL: "",
@@ -43,19 +43,19 @@ const S = "@carter-rmn/cpix-js", v = "1.0.5", P = "module", _ = [
43
43
  USER_PROPERTIES: {},
44
44
  SESSION_EXPIRY_DAYS: 14,
45
45
  COMMON_PROPERTIES: {}
46
- }, c = {
46
+ }, n = {
47
47
  SESSION: "cpix_session",
48
48
  META_PARAMETERS: "cpix_meta_parameters",
49
49
  ACCESS_TOKEN: "cpix_access_token",
50
50
  UTM: "cpix_utm"
51
- }, C = [
51
+ }, M = [
52
52
  "utm_source",
53
53
  "utm_medium",
54
54
  "utm_term",
55
55
  "utm_content",
56
56
  "utm_campaign"
57
- ], u = /* @__PURE__ */ function() {
58
- const l = () => n.DEBUG;
57
+ ], o = /* @__PURE__ */ function() {
58
+ const l = () => a.DEBUG;
59
59
  return {
60
60
  info: function(...e) {
61
61
  console.log(...e);
@@ -72,20 +72,20 @@ class O extends EventTarget {
72
72
  constructor(t = {
73
73
  maxRetries: 3,
74
74
  initialDelay: 1e4,
75
- consumerHandler: (i) => (u.debug("Consuming event:", i), Promise.resolve())
75
+ consumerHandler: (i) => (o.debug("Consuming event:", i), Promise.resolve())
76
76
  }) {
77
77
  super();
78
- o(this, "dataQueue");
79
- o(this, "retryQueue");
80
- o(this, "maxRetries");
81
- o(this, "initialDelay");
82
- o(this, "publishEvent");
83
- o(this, "retryEvent");
84
- o(this, "handler");
78
+ u(this, "dataQueue");
79
+ u(this, "retryQueue");
80
+ u(this, "maxRetries");
81
+ u(this, "initialDelay");
82
+ u(this, "publishEvent");
83
+ u(this, "retryEvent");
84
+ u(this, "handler");
85
85
  this.dataQueue = [], this.retryQueue = [], this.maxRetries = t.maxRetries, this.initialDelay = t.initialDelay, this.handler = t.consumerHandler, this.publishEvent = new Event("eventPublished"), this.retryEvent = new Event("retryMessage"), this.consume(), this.retry();
86
86
  }
87
87
  publish(t) {
88
- u.debug("publishing event");
88
+ o.debug("publishing event");
89
89
  const i = {
90
90
  data: t,
91
91
  id: `${Date.now() + Math.random()}`,
@@ -95,20 +95,20 @@ class O extends EventTarget {
95
95
  this.dataQueue.push(i), this.dispatchEvent(this.publishEvent);
96
96
  }
97
97
  consume() {
98
- u.debug("Started Consumer Queue"), this.addEventListener("eventPublished", async () => {
98
+ o.debug("Started Consumer Queue"), this.addEventListener("eventPublished", async () => {
99
99
  for (; this.dataQueue.length > 0; ) {
100
100
  const t = this.dataQueue.shift(), { data: i = {} } = t;
101
101
  try {
102
102
  await this.handler(i), this.acknowledge(t == null ? void 0 : t.id);
103
- } catch (r) {
104
- u.error("Failed to publish event:", r), this.scheduleRetry(t);
103
+ } catch (s) {
104
+ o.error("Failed to publish event:", s), this.scheduleRetry(t);
105
105
  }
106
106
  }
107
107
  });
108
108
  }
109
109
  scheduleRetry(t) {
110
110
  if (t.retryCount >= this.maxRetries) {
111
- u.error("Max retries reached for message:", t);
111
+ o.error("Max retries reached for message:", t);
112
112
  return;
113
113
  }
114
114
  setTimeout(() => {
@@ -123,13 +123,13 @@ class O extends EventTarget {
123
123
  this.dataQueue = this.dataQueue.filter((i) => i.id !== t);
124
124
  }
125
125
  retry() {
126
- u.debug("Started Retry Queue"), this.addEventListener("retryMessage", async () => {
126
+ o.debug("Started Retry Queue"), this.addEventListener("retryMessage", async () => {
127
127
  for (; this.retryQueue.length > 0; ) {
128
128
  const t = this.retryQueue.shift(), { data: i = {} } = t;
129
129
  try {
130
130
  await this.handler(i), this.acknowledge(t == null ? void 0 : t.id);
131
- } catch (r) {
132
- u.error("Failed to publish event:", r), this.scheduleRetry(t);
131
+ } catch (s) {
132
+ o.error("Failed to publish event:", s), this.scheduleRetry(t);
133
133
  }
134
134
  }
135
135
  });
@@ -137,10 +137,10 @@ class O extends EventTarget {
137
137
  }
138
138
  class d {
139
139
  static getBrowserInfo() {
140
- var r, a, p, f, E;
140
+ var s, c, p, f, E;
141
141
  const e = navigator.userAgent || "";
142
142
  let t, i;
143
- return /chrome/i.test(e) ? (t = "Chrome", i = (r = e.match(/chrome\/(\d+)/i)) == null ? void 0 : r[1]) : /firefox/i.test(e) ? (t = "Firefox", i = (a = e.match(/firefox\/(\d+)/i)) == null ? void 0 : a[1]) : /safari/i.test(e) ? (t = "Safari", i = (p = e.match(/version\/(\d+)/i)) == null ? void 0 : p[1]) : /edge/i.test(e) ? (t = "Edge", i = (f = e.match(/edge\/(\d+)/i)) == null ? void 0 : f[1]) : /trident/i.test(e) ? (t = "Internet Explorer", i = (E = e.match(/rv:(\d+)/i)) == null ? void 0 : E[1]) : (t = "Unknown", i = "Unknown"), `${t} ${i}`;
143
+ return /chrome/i.test(e) ? (t = "Chrome", i = (s = e.match(/chrome\/(\d+)/i)) == null ? void 0 : s[1]) : /firefox/i.test(e) ? (t = "Firefox", i = (c = e.match(/firefox\/(\d+)/i)) == null ? void 0 : c[1]) : /safari/i.test(e) ? (t = "Safari", i = (p = e.match(/version\/(\d+)/i)) == null ? void 0 : p[1]) : /edge/i.test(e) ? (t = "Edge", i = (f = e.match(/edge\/(\d+)/i)) == null ? void 0 : f[1]) : /trident/i.test(e) ? (t = "Internet Explorer", i = (E = e.match(/rv:(\d+)/i)) == null ? void 0 : E[1]) : (t = "Unknown", i = "Unknown"), `${t} ${i}`;
144
144
  }
145
145
  static getDeviceCategory() {
146
146
  const e = navigator.userAgent;
@@ -157,7 +157,7 @@ class d {
157
157
  }
158
158
  static async getDeviceNetworkParameters() {
159
159
  try {
160
- const e = await fetch(`${n.API_URL}/api/geolocation`), { data: t } = await e.json();
160
+ const e = await fetch(`${a.API_URL}/api/geolocation`), { data: t } = await e.json();
161
161
  return {
162
162
  city: t.city || "Unknown",
163
163
  region: t.region || "Unknown",
@@ -167,7 +167,7 @@ class d {
167
167
  ip_address: t.ip_address || "Unknown"
168
168
  };
169
169
  } catch (e) {
170
- return u.error("Error retrieving device network parameters:", e), {
170
+ return o.error("Error retrieving device network parameters:", e), {
171
171
  city: "Unknown",
172
172
  region: "Unknown",
173
173
  country: "Unknown",
@@ -179,7 +179,7 @@ class d {
179
179
  }
180
180
  static async aquireAccessToken(e) {
181
181
  try {
182
- return (await (await fetch(`${n.API_URL}/api/authenticate`, {
182
+ return (await (await fetch(`${a.API_URL}/api/authenticate`, {
183
183
  method: "POST",
184
184
  headers: {
185
185
  "Content-Type": "application/json"
@@ -187,14 +187,14 @@ class d {
187
187
  body: JSON.stringify({
188
188
  accountId: e,
189
189
  metadata: {
190
- sdk: n.package,
191
- version: n.version,
190
+ sdk: a.package,
191
+ version: a.version,
192
192
  hostname: window.location.hostname
193
193
  }
194
194
  })
195
195
  })).json()).accessToken;
196
196
  } catch (t) {
197
- throw u.error("Error acquiring access token:", t), new Error("[CPIX] Authentication error");
197
+ throw o.error("Error acquiring access token:", t), new Error("[CPIX] Authentication error");
198
198
  }
199
199
  }
200
200
  }
@@ -222,11 +222,11 @@ class h {
222
222
  class g {
223
223
  static getParametersByName(e, t) {
224
224
  t || (t = window.location.href), e = e.replace(/[[\]]/g, "\\$&");
225
- const i = new RegExp("[?&]" + e + "(=([^&#]*)|&|#|$)", "gi"), r = [];
226
- let a;
227
- for (; (a = i.exec(t)) !== null; )
228
- a[2] && r.push(decodeURIComponent(a[2].replace(/\+/g, " ")));
229
- return r.length > 0 ? r : null;
225
+ const i = new RegExp("[?&]" + e + "(=([^&#]*)|&|#|$)", "gi"), s = [];
226
+ let c;
227
+ for (; (c = i.exec(t)) !== null; )
228
+ c[2] && s.push(decodeURIComponent(c[2].replace(/\+/g, " ")));
229
+ return s.length > 0 ? s : null;
230
230
  }
231
231
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
232
232
  static externalHost(e) {
@@ -234,84 +234,84 @@ class g {
234
234
  return e.hostname != location.hostname && ((t = e == null ? void 0 : e.protocol) == null ? void 0 : t.indexOf("http")) === 0;
235
235
  }
236
236
  }
237
- class s {
237
+ class r {
238
238
  static prefix() {
239
- return `__${n.TRACKER_FUNC_NAME}__`;
239
+ return `__${a.TRACKER_FUNC_NAME}__`;
240
240
  }
241
241
  static get(e) {
242
- const t = `${s.prefix()}${e}`, i = document.cookie.split("; ").find((r) => r.startsWith(`${t}=`));
242
+ const t = `${r.prefix()}${e}`, i = document.cookie.split("; ").find((s) => s.startsWith(`${t}=`));
243
243
  return i ? i.split("=")[1] : void 0;
244
244
  }
245
245
  static set(e, t, i) {
246
- const r = `${s.prefix()}${e}`, a = /* @__PURE__ */ new Date();
247
- a.setTime(a.getTime() + i * 60 * 1e3), document.cookie = `${r}=${t}; expires=${a.toUTCString()}; path=/`;
246
+ const s = `${r.prefix()}${e}`, c = /* @__PURE__ */ new Date();
247
+ c.setTime(c.getTime() + i * 60 * 1e3), document.cookie = `${s}=${t}; expires=${c.toUTCString()}; path=/`;
248
248
  }
249
249
  static delete(e) {
250
- const t = `${s.prefix()}${e}`;
250
+ const t = `${r.prefix()}${e}`;
251
251
  document.cookie = `${t}=; expires=Thu, 01 Jan 1970 00:00:00 UTC; path=/`;
252
252
  }
253
253
  static clear() {
254
- document.cookie.split("; ").filter((e) => e.startsWith(s.prefix())).forEach((e) => {
254
+ document.cookie.split("; ").filter((e) => e.startsWith(r.prefix())).forEach((e) => {
255
255
  const t = e.split("=")[0];
256
256
  document.cookie = `${t}=; expires=Thu, 01 Jan 1970 00:00:00 UTC; path=/`;
257
257
  });
258
258
  }
259
259
  static exists(e) {
260
- return !!s.get(e);
260
+ return !!r.get(e);
261
261
  }
262
262
  static setUtms() {
263
- const e = C;
263
+ const e = M;
264
264
  let t = !1;
265
265
  for (let i = 0; i < e.length; i++) {
266
- const r = e[i];
267
- if (h.isPresent(g.getParametersByName(r, window.location.href))) {
266
+ const s = e[i];
267
+ if (h.isPresent(g.getParametersByName(s, window.location.href))) {
268
268
  t = !0;
269
269
  break;
270
270
  }
271
271
  }
272
272
  if (t) {
273
273
  let i;
274
- const r = [];
275
- for (let a = 0; a < e.length; a++) {
276
- const p = e[a];
277
- i = g.getParametersByName(p, window.location.href), r.push({
274
+ const s = [];
275
+ for (let c = 0; c < e.length; c++) {
276
+ const p = e[c];
277
+ i = g.getParametersByName(p, window.location.href), s.push({
278
278
  [p]: encodeURIComponent(i)
279
279
  });
280
280
  }
281
- s.set(
282
- c.UTM,
283
- JSON.stringify(r),
284
- n.SESSION_EXPIRY_DAYS * 24 * 60
281
+ r.set(
282
+ n.UTM,
283
+ JSON.stringify(s),
284
+ a.SESSION_EXPIRY_DAYS * 24 * 60
285
285
  );
286
286
  }
287
287
  }
288
288
  static getUtms() {
289
- const e = s.get(c.UTM);
289
+ const e = r.get(n.UTM);
290
290
  return h.isPresent(e) ? JSON.parse(e) : {};
291
291
  }
292
- static createSession() {
293
- s.exists(c.SESSION) || s.set(
294
- c.SESSION,
292
+ static createSession(e = !1) {
293
+ (e || !r.exists(n.SESSION)) && r.set(
294
+ n.SESSION,
295
295
  h.guid(),
296
- n.SESSION_EXPIRY_DAYS * 24 * 60
297
- ), s.setUtms();
296
+ a.SESSION_EXPIRY_DAYS * 24 * 60
297
+ ), r.setUtms();
298
298
  }
299
299
  }
300
- class D {
300
+ class C {
301
301
  constructor() {
302
- o(this, "instances", []);
303
- o(this, "initialized", !1);
304
- o(this, "sessionCreated", !1);
305
- o(this, "accessToken", "");
306
- o(this, "metaParameters", {});
307
- o(this, "queue");
302
+ u(this, "instances", []);
303
+ u(this, "initialized", !1);
304
+ u(this, "sessionCreated", !1);
305
+ u(this, "accessToken", "");
306
+ u(this, "metaParameters", {});
307
+ u(this, "queue");
308
308
  if (!window)
309
309
  throw new Error(
310
310
  "[CPIX] CarterAnalytics SDK can only be used in a browser environment"
311
311
  );
312
312
  this.queue = new O({
313
- maxRetries: n.QUEUE_MAX_RETRIES,
314
- initialDelay: n.QUEUE_INITIAL_DELAY,
313
+ maxRetries: a.QUEUE_MAX_RETRIES,
314
+ initialDelay: a.QUEUE_INITIAL_DELAY,
315
315
  consumerHandler: this.publishEventToServer.bind(this)
316
316
  });
317
317
  }
@@ -324,17 +324,49 @@ class D {
324
324
  throw new Error(
325
325
  "[CPIX] At least one instance configuration is required for initialization"
326
326
  );
327
- if (this.instances = e, n.DEBUG = this.instances[0].options.debug === !0, n.API_URL = this.instances[0].options.tracker_server_url, n.USER_PROPERTIES = this.instances[0].options.user_properties || {}, n.SESSION_EXPIRY_DAYS = this.instances[0].options.session_expiry_days || 14, n.COMMON_PROPERTIES = this.instances[0].options.common_properties || {}, s.exists(c.SESSION) || (s.createSession(), this.sessionCreated = !0), s.exists(c.META_PARAMETERS) || await this.generateMetaParameters().then((t) => {
328
- this.metaParameters = t, s.set("metaParameters", JSON.stringify(t), 60 * 24);
329
- }), s.setUtms(), this.metaParameters = JSON.parse(s.get("metaParameters")), this.initialized)
327
+ this.instances = e, a.DEBUG = this.instances[0].options.debug === !0, a.API_URL = this.instances[0].options.tracker_server_url, a.USER_PROPERTIES = this.instances[0].options.user_properties || {}, a.SESSION_EXPIRY_DAYS = this.instances[0].options.session_expiry_days || 14, a.COMMON_PROPERTIES = this.instances[0].options.common_properties || {}, r.exists(n.SESSION) || (r.createSession(), this.sessionCreated = !0);
328
+ const t = r.get(n.SESSION);
329
+ if (!r.exists(n.META_PARAMETERS))
330
+ this.metaParameters = await this.generateMetaParameters(), r.set(
331
+ n.META_PARAMETERS,
332
+ JSON.stringify(this.metaParameters),
333
+ 60 * 24
334
+ );
335
+ else {
336
+ const i = r.get(n.META_PARAMETERS);
337
+ if (i)
338
+ try {
339
+ const s = JSON.parse(i);
340
+ s.session !== t ? (o.debug(
341
+ "Session ID mismatch detected, regenerating meta parameters"
342
+ ), this.metaParameters = await this.generateMetaParameters(), r.set(
343
+ n.META_PARAMETERS,
344
+ JSON.stringify(this.metaParameters),
345
+ 60 * 24
346
+ )) : this.metaParameters = s;
347
+ } catch (s) {
348
+ o.error("Failed to parse meta parameters, regenerating:", s), this.metaParameters = await this.generateMetaParameters(), r.set(
349
+ n.META_PARAMETERS,
350
+ JSON.stringify(this.metaParameters),
351
+ 60 * 24
352
+ );
353
+ }
354
+ else
355
+ this.metaParameters = await this.generateMetaParameters(), r.set(
356
+ n.META_PARAMETERS,
357
+ JSON.stringify(this.metaParameters),
358
+ 60 * 24
359
+ );
360
+ }
361
+ if (r.setUtms(), this.initialized)
330
362
  throw new Error(
331
363
  "[CPIX] CarterAnalytics SDK has already been initialized"
332
364
  );
333
365
  if (!this.metaParameters)
334
366
  throw new Error("[CPIX] Meta parameters have not been generated");
335
- s.exists(c.ACCESS_TOKEN) || (this.accessToken = await d.aquireAccessToken(
367
+ r.exists(n.ACCESS_TOKEN) || (this.accessToken = await d.aquireAccessToken(
336
368
  this.instances[0].client_id
337
- ), s.set(c.ACCESS_TOKEN, this.accessToken, 60 * 4)), this.initialized = !0, u.debug("CPIX Initialized"), u.debug(
369
+ ), r.set(n.ACCESS_TOKEN, this.accessToken, 60 * 4)), this.initialized = !0, o.debug("CPIX Initialized"), o.debug(
338
370
  "Carter Analytics SDK initialized with options:",
339
371
  this.instances
340
372
  ), this.sessionCreated && this.publishInit(), this.attachHistoryListener();
@@ -342,7 +374,7 @@ class D {
342
374
  publishInit() {
343
375
  this.publish({
344
376
  event: "init",
345
- user_properties: n.USER_PROPERTIES,
377
+ user_properties: a.USER_PROPERTIES,
346
378
  ...this.metaParameters
347
379
  });
348
380
  }
@@ -358,14 +390,14 @@ class D {
358
390
  page: window.location.pathname,
359
391
  url: window.location.href
360
392
  },
361
- user_properties: n.USER_PROPERTIES,
393
+ user_properties: a.USER_PROPERTIES,
362
394
  ...this.metaParameters
363
395
  });
364
396
  };
365
- history.pushState = (...r) => {
366
- e.apply(history, r), i();
367
- }, history.replaceState = (...r) => {
368
- t.apply(history, r), i();
397
+ history.pushState = (...s) => {
398
+ e.apply(history, s), i();
399
+ }, history.replaceState = (...s) => {
400
+ t.apply(history, s), i();
369
401
  }, window.addEventListener("popstate", i), i();
370
402
  }
371
403
  /**
@@ -381,13 +413,23 @@ class D {
381
413
  ...e,
382
414
  ...this.metaParameters
383
415
  };
384
- t.utm_params = s.getUtms(), document.referrer && (t.referrer = encodeURIComponent(document.referrer)), u.debug("Publishing event:", t), this.queue.publish(t), e.event === "logout" && (s.delete(c.SESSION), s.delete(c.META_PARAMETERS), s.createSession(), this.generateMetaParameters().then((i) => {
385
- this.metaParameters = i, s.set(
386
- c.META_PARAMETERS,
387
- JSON.stringify(this.metaParameters),
388
- 60 * 24
389
- ), this.publishInit();
390
- }));
416
+ if (t.utm_params = r.getUtms(), document.referrer && (t.referrer = encodeURIComponent(document.referrer)), o.debug("Publishing event:", t), this.queue.publish(t), e.event === "logout") {
417
+ r.delete(n.SESSION), r.delete(n.META_PARAMETERS), r.createSession(!0);
418
+ const i = r.get(n.SESSION);
419
+ if (!i) {
420
+ o.error("[CPIX] Failed to create new session on logout");
421
+ return;
422
+ }
423
+ this.generateMetaParameters().then((s) => {
424
+ s.session !== i && (o.error(
425
+ "[CPIX] Session ID mismatch after logout, updating meta parameters"
426
+ ), s.session = i), this.metaParameters = s, r.set(
427
+ n.META_PARAMETERS,
428
+ JSON.stringify(this.metaParameters),
429
+ 60 * 24
430
+ ), this.publishInit();
431
+ });
432
+ }
391
433
  }
392
434
  /**
393
435
  * Generates meta parameters that is attached to every event before publishing.
@@ -400,7 +442,7 @@ class D {
400
442
  const e = await d.getDeviceNetworkParameters();
401
443
  return {
402
444
  client_id: this.instances[0].client_id,
403
- session: s.get(c.SESSION),
445
+ session: r.get(n.SESSION),
404
446
  location: {
405
447
  city: e.city,
406
448
  region: e.region,
@@ -413,7 +455,7 @@ class D {
413
455
  brand: d.getDeviceManufacturer(),
414
456
  ip_address: e.ip_address,
415
457
  platform: d.getDevicePlatform(),
416
- cpix_sdk_version: n.version
458
+ cpix_sdk_version: a.version
417
459
  },
418
460
  referrer: encodeURIComponent(document.referrer)
419
461
  };
@@ -426,28 +468,28 @@ class D {
426
468
  try {
427
469
  e.timestamp = Date.now(), e.event_properties = {
428
470
  url: window.location.href,
429
- ...n.COMMON_PROPERTIES,
471
+ ...a.COMMON_PROPERTIES,
430
472
  ...e.event_properties
431
- }, e.device && (e.device.cpix_sdk_version = n.version);
432
- const t = await fetch(`${n.API_URL}/api/event`, {
473
+ }, e.device && (e.device.cpix_sdk_version = a.version);
474
+ const t = await fetch(`${a.API_URL}/api/event`, {
433
475
  method: "POST",
434
476
  body: JSON.stringify({ event_data: e }),
435
477
  headers: {
436
478
  "Content-Type": "application/json",
437
- Authorization: `Bearer ${s.get(c.ACCESS_TOKEN)}`
479
+ Authorization: `Bearer ${r.get(n.ACCESS_TOKEN)}`
438
480
  }
439
481
  });
440
482
  if (!t.ok)
441
483
  throw t.status === 401 && (this.accessToken = await d.aquireAccessToken(
442
484
  this.instances[0].client_id
443
- ), s.set(c.ACCESS_TOKEN, this.accessToken, 60 * 4)), new Error("[CPIX] Failed to publish event");
444
- u.debug("Event published:", t.ok);
485
+ ), r.set(n.ACCESS_TOKEN, this.accessToken, 60 * 4)), new Error("[CPIX] Failed to publish event");
486
+ o.debug("Event published:", t.ok);
445
487
  } catch (t) {
446
- throw u.error("Failed to publish event:", t), new Error("[CPIX] Failed to publish event");
488
+ throw o.error("Failed to publish event:", t), new Error("[CPIX] Failed to publish event");
447
489
  }
448
490
  }
449
491
  }
450
- const N = new D();
492
+ const N = new C();
451
493
  typeof window < "u" && (window.cpix = N);
452
494
  export {
453
495
  N as CarterAnalytics
package/dist/cpix.umd.cjs CHANGED
@@ -1 +1 @@
1
- (function(l,d){typeof exports=="object"&&typeof module<"u"?d(exports):typeof define=="function"&&define.amd?define(["exports"],d):(l=typeof globalThis<"u"?globalThis:l||self,d(l.tracker={}))})(this,function(l){"use strict";var T=Object.defineProperty;var b=(l,d,p)=>d in l?T(l,d,{enumerable:!0,configurable:!0,writable:!0,value:p}):l[d]=p;var u=(l,d,p)=>(b(l,typeof d!="symbol"?d+"":d,p),p);const E={name:"@carter-rmn/cpix-js",version:"1.0.5",type:"module",files:["dist"],main:"dist/cpix.umd.cjs",module:"dist/cpix.js",types:"dist/cpix.d.ts",exports:{".":{import:"./dist/cpix.js",require:"./dist/cpix.umd.cjs"}},scripts:{dev:"vite",build:"tsc && vite build",preview:"vite preview"},devDependencies:{picocolors:"^1.0.0","rollup-plugin-visualizer":"^5.12.0",typescript:"^5.2.2",vite:"^5.2.0","vite-plugin-progress":"^0.0.7"},dependencies:{"vite-plugin-dts":"^3.8.1"}},r={DEBUG:!1,TRACKER_FUNC_NAME:"cpix",API_URL:"",QUEUE_MAX_RETRIES:3,QUEUE_INITIAL_DELAY:1e4,version:E.version,package:E.name,USER_PROPERTIES:{},SESSION_EXPIRY_DAYS:14,COMMON_PROPERTIES:{}},a={SESSION:"cpix_session",META_PARAMETERS:"cpix_meta_parameters",ACCESS_TOKEN:"cpix_access_token",UTM:"cpix_utm"},P=["utm_source","utm_medium","utm_term","utm_content","utm_campaign"],o=function(){const f=()=>r.DEBUG;return{info:function(...e){console.log(...e)},debug:function(...e){f()&&console.log(...e)},error:function(...e){console.error(...e)}}}();class _ extends EventTarget{constructor(t={maxRetries:3,initialDelay:1e4,consumerHandler:i=>(o.debug("Consuming event:",i),Promise.resolve())}){super();u(this,"dataQueue");u(this,"retryQueue");u(this,"maxRetries");u(this,"initialDelay");u(this,"publishEvent");u(this,"retryEvent");u(this,"handler");this.dataQueue=[],this.retryQueue=[],this.maxRetries=t.maxRetries,this.initialDelay=t.initialDelay,this.handler=t.consumerHandler,this.publishEvent=new Event("eventPublished"),this.retryEvent=new Event("retryMessage"),this.consume(),this.retry()}publish(t){o.debug("publishing event");const i={data:t,id:`${Date.now()+Math.random()}`,retryCount:0,retryDelay:this.initialDelay};this.dataQueue.push(i),this.dispatchEvent(this.publishEvent)}consume(){o.debug("Started Consumer Queue"),this.addEventListener("eventPublished",async()=>{for(;this.dataQueue.length>0;){const t=this.dataQueue.shift(),{data:i={}}=t;try{await this.handler(i),this.acknowledge(t==null?void 0:t.id)}catch(n){o.error("Failed to publish event:",n),this.scheduleRetry(t)}}})}scheduleRetry(t){if(t.retryCount>=this.maxRetries){o.error("Max retries reached for message:",t);return}setTimeout(()=>{this.retryQueue.push({...t,retryCount:t.retryCount+1,retryDelay:t.retryDelay*2}),this.dispatchEvent(this.retryEvent)},t.retryDelay)}acknowledge(t){this.dataQueue=this.dataQueue.filter(i=>i.id!==t)}retry(){o.debug("Started Retry Queue"),this.addEventListener("retryMessage",async()=>{for(;this.retryQueue.length>0;){const t=this.retryQueue.shift(),{data:i={}}=t;try{await this.handler(i),this.acknowledge(t==null?void 0:t.id)}catch(n){o.error("Failed to publish event:",n),this.scheduleRetry(t)}}})}}class m{static getBrowserInfo(){var n,c,g,S,v;const e=navigator.userAgent||"";let t,i;return/chrome/i.test(e)?(t="Chrome",i=(n=e.match(/chrome\/(\d+)/i))==null?void 0:n[1]):/firefox/i.test(e)?(t="Firefox",i=(c=e.match(/firefox\/(\d+)/i))==null?void 0:c[1]):/safari/i.test(e)?(t="Safari",i=(g=e.match(/version\/(\d+)/i))==null?void 0:g[1]):/edge/i.test(e)?(t="Edge",i=(S=e.match(/edge\/(\d+)/i))==null?void 0:S[1]):/trident/i.test(e)?(t="Internet Explorer",i=(v=e.match(/rv:(\d+)/i))==null?void 0:v[1]):(t="Unknown",i="Unknown"),`${t} ${i}`}static getDeviceCategory(){const e=navigator.userAgent;return/mobile/i.test(e)?"Mobile":/tablet/i.test(e)?"Tablet":"Desktop"}static getDevicePlatform(){const e=navigator.userAgent;return/android/i.test(e)?"Android":/iphone|ipad|ipod/i.test(e)?"iOS":/windows phone/i.test(e)?"Windows Phone":/mac|Macintosh/i.test(e)?"Mac":/windows|Microsoft/i.test(e)?"Windows":/linux/i.test(e)?"Linux":"Unknown"}static getDeviceManufacturer(){const e=navigator.userAgent;let t;return/iphone|ipad|ipod|mac|Macintosh/i.test(e)?t="Apple":/samsung/i.test(e)?t="Samsung":/google/i.test(e)?t="Google":/huawei/i.test(e)?t="Huawei":/xiaomi/i.test(e)?t="Xiaomi":/oneplus/i.test(e)?t="OnePlus":/dell/i.test(e)?t="Dell":/lenovo/i.test(e)?t="Lenovo":/acer/i.test(e)?t="Acer":/asus/i.test(e)?t="Asus":/toshiba/i.test(e)?t="Toshiba":t="Unknown",t}static async getDeviceNetworkParameters(){try{const e=await fetch(`${r.API_URL}/api/geolocation`),{data:t}=await e.json();return{city:t.city||"Unknown",region:t.region||"Unknown",country:t.country||"Unknown",timezone:t.timezone||"Unknown",loc:t.loc||"Unknown",ip_address:t.ip_address||"Unknown"}}catch(e){return o.error("Error retrieving device network parameters:",e),{city:"Unknown",region:"Unknown",country:"Unknown",timezone:"Unknown",loc:"Unknown",ip_address:"Unknown"}}}static async aquireAccessToken(e){try{return(await(await fetch(`${r.API_URL}/api/authenticate`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({accountId:e,metadata:{sdk:r.package,version:r.version,hostname:window.location.hostname}})})).json()).accessToken}catch(t){throw o.error("Error acquiring access token:",t),new Error("[CPIX] Authentication error")}}}class h{static isPresent(e){return typeof e<"u"&&e!==null&&e!==""}static now(){return 1*new Date().getTime()}static guid(){return E.version+"-xxxxxxxx-".replace(/[x]/g,function(e){const t=Math.random()*36|0;return(e=="x"?t:t&3|8).toString(36)})+(1*new Date().getTime()).toString(36)}static optionalData(e){return h.isPresent(e)===!1?"":typeof e=="object"?h.optionalData(JSON.stringify(e)):typeof e=="function"?h.optionalData(e()):String(e)}static sleep(e){return new Promise(t=>setTimeout(t,e))}}class w{static getParametersByName(e,t){t||(t=window.location.href),e=e.replace(/[[\]]/g,"\\$&");const i=new RegExp("[?&]"+e+"(=([^&#]*)|&|#|$)","gi"),n=[];let c;for(;(c=i.exec(t))!==null;)c[2]&&n.push(decodeURIComponent(c[2].replace(/\+/g," ")));return n.length>0?n:null}static externalHost(e){var t;return e.hostname!=location.hostname&&((t=e==null?void 0:e.protocol)==null?void 0:t.indexOf("http"))===0}}class s{static prefix(){return`__${r.TRACKER_FUNC_NAME}__`}static get(e){const t=`${s.prefix()}${e}`,i=document.cookie.split("; ").find(n=>n.startsWith(`${t}=`));return i?i.split("=")[1]:void 0}static set(e,t,i){const n=`${s.prefix()}${e}`,c=new Date;c.setTime(c.getTime()+i*60*1e3),document.cookie=`${n}=${t}; expires=${c.toUTCString()}; path=/`}static delete(e){const t=`${s.prefix()}${e}`;document.cookie=`${t}=; expires=Thu, 01 Jan 1970 00:00:00 UTC; path=/`}static clear(){document.cookie.split("; ").filter(e=>e.startsWith(s.prefix())).forEach(e=>{const t=e.split("=")[0];document.cookie=`${t}=; expires=Thu, 01 Jan 1970 00:00:00 UTC; path=/`})}static exists(e){return!!s.get(e)}static setUtms(){const e=P;let t=!1;for(let i=0;i<e.length;i++){const n=e[i];if(h.isPresent(w.getParametersByName(n,window.location.href))){t=!0;break}}if(t){let i;const n=[];for(let c=0;c<e.length;c++){const g=e[c];i=w.getParametersByName(g,window.location.href),n.push({[g]:encodeURIComponent(i)})}s.set(a.UTM,JSON.stringify(n),r.SESSION_EXPIRY_DAYS*24*60)}}static getUtms(){const e=s.get(a.UTM);return h.isPresent(e)?JSON.parse(e):{}}static createSession(){s.exists(a.SESSION)||s.set(a.SESSION,h.guid(),r.SESSION_EXPIRY_DAYS*24*60),s.setUtms()}}class x{constructor(){u(this,"instances",[]);u(this,"initialized",!1);u(this,"sessionCreated",!1);u(this,"accessToken","");u(this,"metaParameters",{});u(this,"queue");if(!window)throw new Error("[CPIX] CarterAnalytics SDK can only be used in a browser environment");this.queue=new _({maxRetries:r.QUEUE_MAX_RETRIES,initialDelay:r.QUEUE_INITIAL_DELAY,consumerHandler:this.publishEventToServer.bind(this)})}async initialize(e){if(!e||e.length===0)throw new Error("[CPIX] At least one instance configuration is required for initialization");if(this.instances=e,r.DEBUG=this.instances[0].options.debug===!0,r.API_URL=this.instances[0].options.tracker_server_url,r.USER_PROPERTIES=this.instances[0].options.user_properties||{},r.SESSION_EXPIRY_DAYS=this.instances[0].options.session_expiry_days||14,r.COMMON_PROPERTIES=this.instances[0].options.common_properties||{},s.exists(a.SESSION)||(s.createSession(),this.sessionCreated=!0),s.exists(a.META_PARAMETERS)||await this.generateMetaParameters().then(t=>{this.metaParameters=t,s.set("metaParameters",JSON.stringify(t),60*24)}),s.setUtms(),this.metaParameters=JSON.parse(s.get("metaParameters")),this.initialized)throw new Error("[CPIX] CarterAnalytics SDK has already been initialized");if(!this.metaParameters)throw new Error("[CPIX] Meta parameters have not been generated");s.exists(a.ACCESS_TOKEN)||(this.accessToken=await m.aquireAccessToken(this.instances[0].client_id),s.set(a.ACCESS_TOKEN,this.accessToken,60*4)),this.initialized=!0,o.debug("CPIX Initialized"),o.debug("Carter Analytics SDK initialized with options:",this.instances),this.sessionCreated&&this.publishInit(),this.attachHistoryListener()}publishInit(){this.publish({event:"init",user_properties:r.USER_PROPERTIES,...this.metaParameters})}attachHistoryListener(){const e=history.pushState,t=history.replaceState,i=()=>{this.publish({event:"page_view",event_properties:{title:document.title,page:window.location.pathname,url:window.location.href},user_properties:r.USER_PROPERTIES,...this.metaParameters})};history.pushState=(...n)=>{e.apply(history,n),i()},history.replaceState=(...n)=>{t.apply(history,n),i()},window.addEventListener("popstate",i),i()}publish(e){if(!this.initialized)throw new Error("[CPIX] CarterAnalytics SDK has not been initialized. Please initialize before publishing events.");const t={...e,...this.metaParameters};t.utm_params=s.getUtms(),document.referrer&&(t.referrer=encodeURIComponent(document.referrer)),o.debug("Publishing event:",t),this.queue.publish(t),e.event==="logout"&&(s.delete(a.SESSION),s.delete(a.META_PARAMETERS),s.createSession(),this.generateMetaParameters().then(i=>{this.metaParameters=i,s.set(a.META_PARAMETERS,JSON.stringify(this.metaParameters),60*24),this.publishInit()}))}async generateMetaParameters(){if(!window)throw new Error("[CPIX] Meta parameters can only be generated in a browser environment");const e=await m.getDeviceNetworkParameters();return{client_id:this.instances[0].client_id,session:s.get(a.SESSION),location:{city:e.city,region:e.region,loc:e.loc,timezone:e.timezone,country:e.country},device:{category:m.getDeviceCategory(),brand:m.getDeviceManufacturer(),ip_address:e.ip_address,platform:m.getDevicePlatform(),cpix_sdk_version:r.version},referrer:encodeURIComponent(document.referrer)}}async publishEventToServer(e){try{e.timestamp=Date.now(),e.event_properties={url:window.location.href,...r.COMMON_PROPERTIES,...e.event_properties},e.device&&(e.device.cpix_sdk_version=r.version);const t=await fetch(`${r.API_URL}/api/event`,{method:"POST",body:JSON.stringify({event_data:e}),headers:{"Content-Type":"application/json",Authorization:`Bearer ${s.get(a.ACCESS_TOKEN)}`}});if(!t.ok)throw t.status===401&&(this.accessToken=await m.aquireAccessToken(this.instances[0].client_id),s.set(a.ACCESS_TOKEN,this.accessToken,60*4)),new Error("[CPIX] Failed to publish event");o.debug("Event published:",t.ok)}catch(t){throw o.error("Failed to publish event:",t),new Error("[CPIX] Failed to publish event")}}}const y=new x;typeof window<"u"&&(window.cpix=y),l.CarterAnalytics=y,Object.defineProperty(l,Symbol.toStringTag,{value:"Module"})});
1
+ (function(l,d){typeof exports=="object"&&typeof module<"u"?d(exports):typeof define=="function"&&define.amd?define(["exports"],d):(l=typeof globalThis<"u"?globalThis:l||self,d(l.tracker={}))})(this,function(l){"use strict";var T=Object.defineProperty;var R=(l,d,p)=>d in l?T(l,d,{enumerable:!0,configurable:!0,writable:!0,value:p}):l[d]=p;var u=(l,d,p)=>(R(l,typeof d!="symbol"?d+"":d,p),p);const E={name:"@carter-rmn/cpix-js",version:"1.0.7",type:"module",files:["dist"],main:"dist/cpix.umd.cjs",module:"dist/cpix.js",types:"dist/cpix.d.ts",exports:{".":{import:"./dist/cpix.js",require:"./dist/cpix.umd.cjs"}},scripts:{dev:"vite",build:"tsc && vite build",preview:"vite preview"},devDependencies:{picocolors:"^1.0.0","rollup-plugin-visualizer":"^5.12.0",typescript:"^5.2.2",vite:"^5.2.0","vite-plugin-progress":"^0.0.7"},dependencies:{"vite-plugin-dts":"^3.8.1"}},n={DEBUG:!1,TRACKER_FUNC_NAME:"cpix",API_URL:"",QUEUE_MAX_RETRIES:3,QUEUE_INITIAL_DELAY:1e4,version:E.version,package:E.name,USER_PROPERTIES:{},SESSION_EXPIRY_DAYS:14,COMMON_PROPERTIES:{}},a={SESSION:"cpix_session",META_PARAMETERS:"cpix_meta_parameters",ACCESS_TOKEN:"cpix_access_token",UTM:"cpix_utm"},P=["utm_source","utm_medium","utm_term","utm_content","utm_campaign"],o=function(){const f=()=>n.DEBUG;return{info:function(...e){console.log(...e)},debug:function(...e){f()&&console.log(...e)},error:function(...e){console.error(...e)}}}();class _ extends EventTarget{constructor(t={maxRetries:3,initialDelay:1e4,consumerHandler:i=>(o.debug("Consuming event:",i),Promise.resolve())}){super();u(this,"dataQueue");u(this,"retryQueue");u(this,"maxRetries");u(this,"initialDelay");u(this,"publishEvent");u(this,"retryEvent");u(this,"handler");this.dataQueue=[],this.retryQueue=[],this.maxRetries=t.maxRetries,this.initialDelay=t.initialDelay,this.handler=t.consumerHandler,this.publishEvent=new Event("eventPublished"),this.retryEvent=new Event("retryMessage"),this.consume(),this.retry()}publish(t){o.debug("publishing event");const i={data:t,id:`${Date.now()+Math.random()}`,retryCount:0,retryDelay:this.initialDelay};this.dataQueue.push(i),this.dispatchEvent(this.publishEvent)}consume(){o.debug("Started Consumer Queue"),this.addEventListener("eventPublished",async()=>{for(;this.dataQueue.length>0;){const t=this.dataQueue.shift(),{data:i={}}=t;try{await this.handler(i),this.acknowledge(t==null?void 0:t.id)}catch(r){o.error("Failed to publish event:",r),this.scheduleRetry(t)}}})}scheduleRetry(t){if(t.retryCount>=this.maxRetries){o.error("Max retries reached for message:",t);return}setTimeout(()=>{this.retryQueue.push({...t,retryCount:t.retryCount+1,retryDelay:t.retryDelay*2}),this.dispatchEvent(this.retryEvent)},t.retryDelay)}acknowledge(t){this.dataQueue=this.dataQueue.filter(i=>i.id!==t)}retry(){o.debug("Started Retry Queue"),this.addEventListener("retryMessage",async()=>{for(;this.retryQueue.length>0;){const t=this.retryQueue.shift(),{data:i={}}=t;try{await this.handler(i),this.acknowledge(t==null?void 0:t.id)}catch(r){o.error("Failed to publish event:",r),this.scheduleRetry(t)}}})}}class m{static getBrowserInfo(){var r,c,g,y,v;const e=navigator.userAgent||"";let t,i;return/chrome/i.test(e)?(t="Chrome",i=(r=e.match(/chrome\/(\d+)/i))==null?void 0:r[1]):/firefox/i.test(e)?(t="Firefox",i=(c=e.match(/firefox\/(\d+)/i))==null?void 0:c[1]):/safari/i.test(e)?(t="Safari",i=(g=e.match(/version\/(\d+)/i))==null?void 0:g[1]):/edge/i.test(e)?(t="Edge",i=(y=e.match(/edge\/(\d+)/i))==null?void 0:y[1]):/trident/i.test(e)?(t="Internet Explorer",i=(v=e.match(/rv:(\d+)/i))==null?void 0:v[1]):(t="Unknown",i="Unknown"),`${t} ${i}`}static getDeviceCategory(){const e=navigator.userAgent;return/mobile/i.test(e)?"Mobile":/tablet/i.test(e)?"Tablet":"Desktop"}static getDevicePlatform(){const e=navigator.userAgent;return/android/i.test(e)?"Android":/iphone|ipad|ipod/i.test(e)?"iOS":/windows phone/i.test(e)?"Windows Phone":/mac|Macintosh/i.test(e)?"Mac":/windows|Microsoft/i.test(e)?"Windows":/linux/i.test(e)?"Linux":"Unknown"}static getDeviceManufacturer(){const e=navigator.userAgent;let t;return/iphone|ipad|ipod|mac|Macintosh/i.test(e)?t="Apple":/samsung/i.test(e)?t="Samsung":/google/i.test(e)?t="Google":/huawei/i.test(e)?t="Huawei":/xiaomi/i.test(e)?t="Xiaomi":/oneplus/i.test(e)?t="OnePlus":/dell/i.test(e)?t="Dell":/lenovo/i.test(e)?t="Lenovo":/acer/i.test(e)?t="Acer":/asus/i.test(e)?t="Asus":/toshiba/i.test(e)?t="Toshiba":t="Unknown",t}static async getDeviceNetworkParameters(){try{const e=await fetch(`${n.API_URL}/api/geolocation`),{data:t}=await e.json();return{city:t.city||"Unknown",region:t.region||"Unknown",country:t.country||"Unknown",timezone:t.timezone||"Unknown",loc:t.loc||"Unknown",ip_address:t.ip_address||"Unknown"}}catch(e){return o.error("Error retrieving device network parameters:",e),{city:"Unknown",region:"Unknown",country:"Unknown",timezone:"Unknown",loc:"Unknown",ip_address:"Unknown"}}}static async aquireAccessToken(e){try{return(await(await fetch(`${n.API_URL}/api/authenticate`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({accountId:e,metadata:{sdk:n.package,version:n.version,hostname:window.location.hostname}})})).json()).accessToken}catch(t){throw o.error("Error acquiring access token:",t),new Error("[CPIX] Authentication error")}}}class h{static isPresent(e){return typeof e<"u"&&e!==null&&e!==""}static now(){return 1*new Date().getTime()}static guid(){return E.version+"-xxxxxxxx-".replace(/[x]/g,function(e){const t=Math.random()*36|0;return(e=="x"?t:t&3|8).toString(36)})+(1*new Date().getTime()).toString(36)}static optionalData(e){return h.isPresent(e)===!1?"":typeof e=="object"?h.optionalData(JSON.stringify(e)):typeof e=="function"?h.optionalData(e()):String(e)}static sleep(e){return new Promise(t=>setTimeout(t,e))}}class S{static getParametersByName(e,t){t||(t=window.location.href),e=e.replace(/[[\]]/g,"\\$&");const i=new RegExp("[?&]"+e+"(=([^&#]*)|&|#|$)","gi"),r=[];let c;for(;(c=i.exec(t))!==null;)c[2]&&r.push(decodeURIComponent(c[2].replace(/\+/g," ")));return r.length>0?r:null}static externalHost(e){var t;return e.hostname!=location.hostname&&((t=e==null?void 0:e.protocol)==null?void 0:t.indexOf("http"))===0}}class s{static prefix(){return`__${n.TRACKER_FUNC_NAME}__`}static get(e){const t=`${s.prefix()}${e}`,i=document.cookie.split("; ").find(r=>r.startsWith(`${t}=`));return i?i.split("=")[1]:void 0}static set(e,t,i){const r=`${s.prefix()}${e}`,c=new Date;c.setTime(c.getTime()+i*60*1e3),document.cookie=`${r}=${t}; expires=${c.toUTCString()}; path=/`}static delete(e){const t=`${s.prefix()}${e}`;document.cookie=`${t}=; expires=Thu, 01 Jan 1970 00:00:00 UTC; path=/`}static clear(){document.cookie.split("; ").filter(e=>e.startsWith(s.prefix())).forEach(e=>{const t=e.split("=")[0];document.cookie=`${t}=; expires=Thu, 01 Jan 1970 00:00:00 UTC; path=/`})}static exists(e){return!!s.get(e)}static setUtms(){const e=P;let t=!1;for(let i=0;i<e.length;i++){const r=e[i];if(h.isPresent(S.getParametersByName(r,window.location.href))){t=!0;break}}if(t){let i;const r=[];for(let c=0;c<e.length;c++){const g=e[c];i=S.getParametersByName(g,window.location.href),r.push({[g]:encodeURIComponent(i)})}s.set(a.UTM,JSON.stringify(r),n.SESSION_EXPIRY_DAYS*24*60)}}static getUtms(){const e=s.get(a.UTM);return h.isPresent(e)?JSON.parse(e):{}}static createSession(e=!1){(e||!s.exists(a.SESSION))&&s.set(a.SESSION,h.guid(),n.SESSION_EXPIRY_DAYS*24*60),s.setUtms()}}class A{constructor(){u(this,"instances",[]);u(this,"initialized",!1);u(this,"sessionCreated",!1);u(this,"accessToken","");u(this,"metaParameters",{});u(this,"queue");if(!window)throw new Error("[CPIX] CarterAnalytics SDK can only be used in a browser environment");this.queue=new _({maxRetries:n.QUEUE_MAX_RETRIES,initialDelay:n.QUEUE_INITIAL_DELAY,consumerHandler:this.publishEventToServer.bind(this)})}async initialize(e){if(!e||e.length===0)throw new Error("[CPIX] At least one instance configuration is required for initialization");this.instances=e,n.DEBUG=this.instances[0].options.debug===!0,n.API_URL=this.instances[0].options.tracker_server_url,n.USER_PROPERTIES=this.instances[0].options.user_properties||{},n.SESSION_EXPIRY_DAYS=this.instances[0].options.session_expiry_days||14,n.COMMON_PROPERTIES=this.instances[0].options.common_properties||{},s.exists(a.SESSION)||(s.createSession(),this.sessionCreated=!0);const t=s.get(a.SESSION);if(!s.exists(a.META_PARAMETERS))this.metaParameters=await this.generateMetaParameters(),s.set(a.META_PARAMETERS,JSON.stringify(this.metaParameters),60*24);else{const i=s.get(a.META_PARAMETERS);if(i)try{const r=JSON.parse(i);r.session!==t?(o.debug("Session ID mismatch detected, regenerating meta parameters"),this.metaParameters=await this.generateMetaParameters(),s.set(a.META_PARAMETERS,JSON.stringify(this.metaParameters),60*24)):this.metaParameters=r}catch(r){o.error("Failed to parse meta parameters, regenerating:",r),this.metaParameters=await this.generateMetaParameters(),s.set(a.META_PARAMETERS,JSON.stringify(this.metaParameters),60*24)}else this.metaParameters=await this.generateMetaParameters(),s.set(a.META_PARAMETERS,JSON.stringify(this.metaParameters),60*24)}if(s.setUtms(),this.initialized)throw new Error("[CPIX] CarterAnalytics SDK has already been initialized");if(!this.metaParameters)throw new Error("[CPIX] Meta parameters have not been generated");s.exists(a.ACCESS_TOKEN)||(this.accessToken=await m.aquireAccessToken(this.instances[0].client_id),s.set(a.ACCESS_TOKEN,this.accessToken,60*4)),this.initialized=!0,o.debug("CPIX Initialized"),o.debug("Carter Analytics SDK initialized with options:",this.instances),this.sessionCreated&&this.publishInit(),this.attachHistoryListener()}publishInit(){this.publish({event:"init",user_properties:n.USER_PROPERTIES,...this.metaParameters})}attachHistoryListener(){const e=history.pushState,t=history.replaceState,i=()=>{this.publish({event:"page_view",event_properties:{title:document.title,page:window.location.pathname,url:window.location.href},user_properties:n.USER_PROPERTIES,...this.metaParameters})};history.pushState=(...r)=>{e.apply(history,r),i()},history.replaceState=(...r)=>{t.apply(history,r),i()},window.addEventListener("popstate",i),i()}publish(e){if(!this.initialized)throw new Error("[CPIX] CarterAnalytics SDK has not been initialized. Please initialize before publishing events.");const t={...e,...this.metaParameters};if(t.utm_params=s.getUtms(),document.referrer&&(t.referrer=encodeURIComponent(document.referrer)),o.debug("Publishing event:",t),this.queue.publish(t),e.event==="logout"){s.delete(a.SESSION),s.delete(a.META_PARAMETERS),s.createSession(!0);const i=s.get(a.SESSION);if(!i){o.error("[CPIX] Failed to create new session on logout");return}this.generateMetaParameters().then(r=>{r.session!==i&&(o.error("[CPIX] Session ID mismatch after logout, updating meta parameters"),r.session=i),this.metaParameters=r,s.set(a.META_PARAMETERS,JSON.stringify(this.metaParameters),60*24),this.publishInit()})}}async generateMetaParameters(){if(!window)throw new Error("[CPIX] Meta parameters can only be generated in a browser environment");const e=await m.getDeviceNetworkParameters();return{client_id:this.instances[0].client_id,session:s.get(a.SESSION),location:{city:e.city,region:e.region,loc:e.loc,timezone:e.timezone,country:e.country},device:{category:m.getDeviceCategory(),brand:m.getDeviceManufacturer(),ip_address:e.ip_address,platform:m.getDevicePlatform(),cpix_sdk_version:n.version},referrer:encodeURIComponent(document.referrer)}}async publishEventToServer(e){try{e.timestamp=Date.now(),e.event_properties={url:window.location.href,...n.COMMON_PROPERTIES,...e.event_properties},e.device&&(e.device.cpix_sdk_version=n.version);const t=await fetch(`${n.API_URL}/api/event`,{method:"POST",body:JSON.stringify({event_data:e}),headers:{"Content-Type":"application/json",Authorization:`Bearer ${s.get(a.ACCESS_TOKEN)}`}});if(!t.ok)throw t.status===401&&(this.accessToken=await m.aquireAccessToken(this.instances[0].client_id),s.set(a.ACCESS_TOKEN,this.accessToken,60*4)),new Error("[CPIX] Failed to publish event");o.debug("Event published:",t.ok)}catch(t){throw o.error("Failed to publish event:",t),new Error("[CPIX] Failed to publish event")}}}const w=new A;typeof window<"u"&&(window.cpix=w),l.CarterAnalytics=w,Object.defineProperty(l,Symbol.toStringTag,{value:"Module"})});
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@carter-rmn/cpix-js",
3
- "version": "1.0.6",
3
+ "version": "1.0.7",
4
4
  "type": "module",
5
5
  "files": [
6
6
  "dist"
@@ -14,6 +14,11 @@
14
14
  "require": "./dist/cpix.umd.cjs"
15
15
  }
16
16
  },
17
+ "scripts": {
18
+ "dev": "vite",
19
+ "build": "tsc && vite build",
20
+ "preview": "vite preview"
21
+ },
17
22
  "devDependencies": {
18
23
  "picocolors": "^1.0.0",
19
24
  "rollup-plugin-visualizer": "^5.12.0",
@@ -23,10 +28,5 @@
23
28
  },
24
29
  "dependencies": {
25
30
  "vite-plugin-dts": "^3.8.1"
26
- },
27
- "scripts": {
28
- "dev": "vite",
29
- "build": "tsc && vite build",
30
- "preview": "vite preview"
31
31
  }
32
- }
32
+ }
package/LICENCE DELETED
@@ -1,32 +0,0 @@
1
- Proprietary License
2
-
3
- This software is licensed under the terms of this Proprietary License (the "License"). By using this software, you agree to comply with the terms of this License.
4
-
5
- 1. Grant of License
6
- This software is licensed, not sold, to you by Carter Analytics for use only under the terms of this License. Carter Analytics retains ownership of the software itself and reserves all rights not expressly granted to you.
7
-
8
- 2. Permitted Use
9
- You are granted a non-exclusive, non-transferable, limited license to use the software solely for your personal or internal business purposes, provided you have an active subscription to Carter Analytics's paid supporting service.
10
-
11
- 3. Restrictions
12
- You may not:
13
- a. Redistribute, sell, lease, sublicense, or otherwise transfer the software or any portion thereof.
14
- b. Modify, adapt, translate, reverse engineer, decompile, or disassemble the software.
15
- c. Remove or alter any proprietary notices or labels on the software.
16
-
17
- 4. Intellectual Property
18
- All intellectual property rights in and to the software are and shall remain the exclusive property of Carter Analytics.
19
-
20
- 5. Disclaimer of Warranties
21
- The software is provided "as is" without warranty of any kind, either express or implied, including but not limited to the implied warranties of merchantability and fitness for a particular purpose.
22
-
23
- 6. Limitation of Liability
24
- In no event shall Carter Analytics be liable for any damages whatsoever (including, without limitation, damages for loss of business profits, business interruption, loss of business information, or any other pecuniary loss) arising out of the use of or inability to use this software, even if Carter Analytics has been advised of the possibility of such damages.
25
-
26
- 7. Termination
27
- This License is effective until terminated. Your rights under this License will terminate automatically without notice from Carter Analytics if you fail to comply with any term(s) of this License. Upon termination, you shall cease all use of the software and destroy all copies, full or partial, of the software.
28
-
29
- 8. Governing Law
30
- This License shall be governed by and construed in accordance with the laws of [Your Jurisdiction].
31
-
32
- By using this software, you acknowledge that you have read this License, understand it, and agree to be bound by its terms and conditions.