@carter-rmn/cpix-js 1.0.2 → 1.0.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENCE +32 -0
- package/dist/common/constants.d.ts +3 -0
- package/dist/cpix.cjs +1 -1
- package/dist/cpix.iife.js +1 -1
- package/dist/cpix.js +123 -94
- package/dist/cpix.umd.cjs +1 -1
- package/dist/modules/carter-analytics.d.ts +5 -0
- package/dist/types/common.types.d.ts +9 -2
- package/package.json +7 -7
package/LICENCE
ADDED
|
@@ -0,0 +1,32 @@
|
|
|
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.
|
package/dist/cpix.cjs
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";var v=Object.defineProperty;var E=(u,e,t)=>e in u?v(u,e,{enumerable:!0,configurable:!0,writable:!0,value:t}):u[e]=t;var o=(u,e,t)=>(E(u,typeof e!="symbol"?e+"":e,t),t);Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const S="@carter-rmn/cpix-js",x="1.0.2",b="module",A=["dist"],P="dist/cpix.umd.cjs",T="dist/cpix.js",U="dist/cpix.d.ts",_={".":{import:"./dist/cpix.js",require:"./dist/cpix.umd.cjs"}},C={dev:"vite",build:"tsc && vite build",preview:"vite preview"},D={picocolors:"^1.0.0","rollup-plugin-visualizer":"^5.12.0",typescript:"^5.2.2",vite:"^5.2.0","vite-plugin-progress":"^0.0.7"},I={"vite-plugin-dts":"^3.8.1"},m={name:S,version:x,type:b,files:A,main:P,module:T,types:U,exports:_,scripts:C,devDependencies:D,dependencies:I},l={DEBUG:!1,TRACKER_FUNC_NAME:"cpix",API_URL:"",QUEUE_MAX_RETRIES:3,QUEUE_INITIAL_DELAY:1e4,version:m.version,package:m.name},c={SESSION:"cpix_session",META_PARAMETERS:"cpix_meta_parameters",ACCESS_TOKEN:"cpix_access_token",UTM:"cpix_utm"},k=["utm_source","utm_medium","utm_term","utm_content","utm_campaign"],a=function(){const u=()=>l.DEBUG;return{info:function(...e){console.log(...e)},debug:function(...e){u()&&console.log(...e)},error:function(...e){console.error(...e)}}}();class N extends EventTarget{constructor(t={maxRetries:3,initialDelay:1e4,consumerHandler:i=>(a.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){a.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(){a.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){a.error("Failed to publish event:",s),this.scheduleRetry(t)}}})}scheduleRetry(t){if(t.retryCount>=this.maxRetries){a.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(){a.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){a.error("Failed to publish event:",s),this.scheduleRetry(t)}}})}}class h{static getBrowserInfo(){var s,n,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=(n=e.match(/firefox\/(\d+)/i))==null?void 0:n[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(`${l.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 a.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(`${l.API_URL}/api/authenticate`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({accountId:e,metadata:{sdk:l.package,version:l.version,hostname:window.location.hostname}})})).json()).accessToken}catch(t){throw a.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 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 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 w{static getParametersByName(e,t){t||(t=window.location.href),e=e.replace(/[[\]]/g,"\\$&");const i=new RegExp("[?&]"+e+"(=([^&#]*)|&|#|$)","gi"),s=[];let n;for(;(n=i.exec(t))!==null;)n[2]&&s.push(decodeURIComponent(n[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`__${l.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}`,n=new Date;n.setTime(n.getTime()+i*60*1e3),document.cookie=`${s}=${t}; expires=${n.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=k;let t=!1;for(let i=0;i<e.length;i++){const s=e[i];if(d.isPresent(w.getParametersByName(s,window.location.href))){t=!0;break}}if(t){let i;const s=[];for(let n=0;n<e.length;n++){const p=e[n];i=w.getParametersByName(p,window.location.href),s.push({[p]:i})}r.set(c.UTM,JSON.stringify(s),14*24*60)}}static getUtms(){const e=r.get(c.UTM);return d.isPresent(e)?JSON.parse(e):{}}static createSession(){r.exists(c.SESSION)||r.set(c.SESSION,d.guid(),14*24*60),r.setUtms()}}class R{constructor(){o(this,"instances",[]);o(this,"initialized",!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 N({maxRetries:l.QUEUE_MAX_RETRIES,initialDelay:l.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,l.DEBUG=this.instances[0].options.debug===!0,l.API_URL=this.instances[0].options.tracker_server_url,r.exists(c.SESSION)||r.createSession(),r.exists(c.META_PARAMETERS)||await this.generateMetaParameters().then(t=>{this.metaParameters=t,r.set("metaParameters",JSON.stringify(t),60*24)}),r.setUtms(),this.metaParameters=JSON.parse(r.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");r.exists(c.ACCESS_TOKEN)||(this.accessToken=await h.aquireAccessToken(this.instances[0].client_id),r.set(c.ACCESS_TOKEN,this.accessToken,60*4)),this.initialized=!0,a.debug("CPIX Initialized"),a.debug("Carter Analytics SDK initialized with options:",this.instances),this.publish({event:"init",...this.metaParameters}),this.publish({event:"page_view",event_properties:{title:document.title,page:window.location.pathname,url:window.location.href},...this.metaParameters})}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=r.getUtms(),document.referrer&&(t.referrer=encodeURIComponent(document.referrer)),a.debug("Publishing event:",t),this.queue.publish(t),e.event==="logout"&&(r.delete(c.SESSION),r.createSession(),this.generateMetaParameters().then(i=>{this.metaParameters=i,r.set(c.META_PARAMETERS,JSON.stringify(this.metaParameters),60*24)}))}async generateMetaParameters(){if(!window)throw new Error("[CPIX] Meta parameters can only be generated in a browser environment");const e=await h.getDeviceNetworkParameters();return{client_id:this.instances[0].client_id,session:r.get(c.SESSION),location:{city:e.city,region:e.region,loc:e.loc,timezone:e.timezone,country:e.country},device:{category:h.getDeviceCategory(),brand:h.getDeviceManufacturer(),ip_address:e.ip_address,platform:h.getDevicePlatform()},referrer:encodeURIComponent(document.referrer)}}async publishEventToServer(e){try{e.timestamp=Date.now(),e.event_properties={url:window.location.href,...e.event_properties};const t=await fetch(`${l.API_URL}/api/event`,{method:"POST",body:JSON.stringify({event_data:e}),headers:{"Content-Type":"application/json",Authorization:`Bearer ${r.get(c.ACCESS_TOKEN)}`}});if(!t.ok)throw t.status===401&&(this.accessToken=await h.aquireAccessToken(this.instances[0].client_id),r.set(c.ACCESS_TOKEN,this.accessToken,60*4)),new Error("[CPIX] Failed to publish event");a.debug("Event published:",t.ok)}catch(t){throw a.error("Failed to publish event:",t),new Error("[CPIX] Failed to publish event")}}}const y=new R;typeof window<"u"&&(window.cpix=y);exports.CarterAnalytics=y;
|
|
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.4",_="module",x=["dist"],A="dist/cpix.umd.cjs",T="dist/cpix.js",b="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:T,types:b,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:{}},u={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"],c=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=>(c.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){c.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(){c.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){c.error("Failed to publish event:",r),this.scheduleRetry(t)}}})}scheduleRetry(t){if(t.retryCount>=this.maxRetries){c.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(){c.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){c.error("Failed to publish event:",r),this.scheduleRetry(t)}}})}}class h{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 c.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 c.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 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 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 w{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(d.isPresent(w.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=w.getParametersByName(p,window.location.href),r.push({[p]:encodeURIComponent(i)})}s.set(u.UTM,JSON.stringify(r),n.SESSION_EXPIRY_DAYS*24*60)}}static getUtms(){const e=s.get(u.UTM);return d.isPresent(e)?JSON.parse(e):{}}static createSession(){s.exists(u.SESSION)||s.set(u.SESSION,d.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(u.SESSION)||(s.createSession(),this.sessionCreated=!0),s.exists(u.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(u.ACCESS_TOKEN)||(this.accessToken=await h.aquireAccessToken(this.instances[0].client_id),s.set(u.ACCESS_TOKEN,this.accessToken,60*4)),this.initialized=!0,c.debug("CPIX Initialized"),c.debug("Carter Analytics SDK initialized with options:",this.instances),this.sessionCreated&&this.publish({event:"init",user_properties:n.USER_PROPERTIES,...this.metaParameters}),this.attachHistoryListener()}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)),c.debug("Publishing event:",t),this.queue.publish(t),e.event==="logout"&&(s.delete(u.SESSION),s.createSession(),this.generateMetaParameters().then(i=>{this.metaParameters=i,s.set(u.META_PARAMETERS,JSON.stringify(this.metaParameters),60*24)}))}async generateMetaParameters(){if(!window)throw new Error("[CPIX] Meta parameters can only be generated in a browser environment");const e=await h.getDeviceNetworkParameters();return{client_id:this.instances[0].client_id,session:s.get(u.SESSION),location:{city:e.city,region:e.region,loc:e.loc,timezone:e.timezone,country:e.country},device:{category:h.getDeviceCategory(),brand:h.getDeviceManufacturer(),ip_address:e.ip_address,platform:h.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(u.ACCESS_TOKEN)}`}});if(!t.ok)throw t.status===401&&(this.accessToken=await h.aquireAccessToken(this.instances[0].client_id),s.set(u.ACCESS_TOKEN,this.accessToken,60*4)),new Error("[CPIX] Failed to publish event");c.debug("Event published:",t.ok)}catch(t){throw c.error("Failed to publish event:",t),new Error("[CPIX] Failed to publish event")}}}const E=new N;typeof window<"u"&&(window.cpix=E);exports.CarterAnalytics=E;
|
package/dist/cpix.iife.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
var tracker=function(l){"use strict";var P=Object.defineProperty;var T=(l,d,p)=>d in l?P(l,d,{enumerable:!0,configurable:!0,writable:!0,value:p}):l[d]=p;var c=(l,d,p)=>(T(l,typeof d!="symbol"?d+"":d,p),p);const w={name:"@carter-rmn/cpix-js",version:"1.0.2",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"}},u={DEBUG:!1,TRACKER_FUNC_NAME:"cpix",API_URL:"",QUEUE_MAX_RETRIES:3,QUEUE_INITIAL_DELAY:1e4,version:w.version,package:w.name},o={SESSION:"cpix_session",META_PARAMETERS:"cpix_meta_parameters",ACCESS_TOKEN:"cpix_access_token",UTM:"cpix_utm"},x=["utm_source","utm_medium","utm_term","utm_content","utm_campaign"],s=function(){const f=()=>u.DEBUG;return{info:function(...e){console.log(...e)},debug:function(...e){f()&&console.log(...e)},error:function(...e){console.error(...e)}}}();class b extends EventTarget{constructor(t={maxRetries:3,initialDelay:1e4,consumerHandler:i=>(s.debug("Consuming event:",i),Promise.resolve())}){super();c(this,"dataQueue");c(this,"retryQueue");c(this,"maxRetries");c(this,"initialDelay");c(this,"publishEvent");c(this,"retryEvent");c(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){s.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(){s.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){s.error("Failed to publish event:",r),this.scheduleRetry(t)}}})}scheduleRetry(t){if(t.retryCount>=this.maxRetries){s.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(){s.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){s.error("Failed to publish event:",r),this.scheduleRetry(t)}}})}}class m{static getBrowserInfo(){var r,a,g,E,S;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=(g=e.match(/version\/(\d+)/i))==null?void 0:g[1]):/edge/i.test(e)?(t="Edge",i=(E=e.match(/edge\/(\d+)/i))==null?void 0:E[1]):/trident/i.test(e)?(t="Internet Explorer",i=(S=e.match(/rv:(\d+)/i))==null?void 0:S[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(`${u.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 s.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(`${u.API_URL}/api/authenticate`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({accountId:e,metadata:{sdk:u.package,version:u.version,hostname:window.location.hostname}})})).json()).accessToken}catch(t){throw s.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 w.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 y{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 n{static prefix(){return`__${u.TRACKER_FUNC_NAME}__`}static get(e){const t=`${n.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=`${n.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=`${n.prefix()}${e}`;document.cookie=`${t}=; expires=Thu, 01 Jan 1970 00:00:00 UTC; path=/`}static clear(){document.cookie.split("; ").filter(e=>e.startsWith(n.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!!n.get(e)}static setUtms(){const e=x;let t=!1;for(let i=0;i<e.length;i++){const r=e[i];if(h.isPresent(y.getParametersByName(r,window.location.href))){t=!0;break}}if(t){let i;const r=[];for(let a=0;a<e.length;a++){const g=e[a];i=y.getParametersByName(g,window.location.href),r.push({[g]:i})}n.set(o.UTM,JSON.stringify(r),20160)}}static getUtms(){const e=n.get(o.UTM);return h.isPresent(e)?JSON.parse(e):{}}static createSession(){n.exists(o.SESSION)||n.set(o.SESSION,h.guid(),20160),n.setUtms()}}class A{constructor(){c(this,"instances",[]);c(this,"initialized",!1);c(this,"accessToken","");c(this,"metaParameters",{});c(this,"queue");if(!window)throw new Error("[CPIX] CarterAnalytics SDK can only be used in a browser environment");this.queue=new b({maxRetries:u.QUEUE_MAX_RETRIES,initialDelay:u.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,u.DEBUG=this.instances[0].options.debug===!0,u.API_URL=this.instances[0].options.tracker_server_url,n.exists(o.SESSION)||n.createSession(),n.exists(o.META_PARAMETERS)||await this.generateMetaParameters().then(t=>{this.metaParameters=t,n.set("metaParameters",JSON.stringify(t),1440)}),n.setUtms(),this.metaParameters=JSON.parse(n.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");n.exists(o.ACCESS_TOKEN)||(this.accessToken=await m.aquireAccessToken(this.instances[0].client_id),n.set(o.ACCESS_TOKEN,this.accessToken,240)),this.initialized=!0,s.debug("CPIX Initialized"),s.debug("Carter Analytics SDK initialized with options:",this.instances),this.publish({event:"init",...this.metaParameters}),this.publish({event:"page_view",event_properties:{title:document.title,page:window.location.pathname,url:window.location.href},...this.metaParameters})}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=n.getUtms(),document.referrer&&(t.referrer=encodeURIComponent(document.referrer)),s.debug("Publishing event:",t),this.queue.publish(t),e.event==="logout"&&(n.delete(o.SESSION),n.createSession(),this.generateMetaParameters().then(i=>{this.metaParameters=i,n.set(o.META_PARAMETERS,JSON.stringify(this.metaParameters),1440)}))}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:n.get(o.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()},referrer:encodeURIComponent(document.referrer)}}async publishEventToServer(e){try{e.timestamp=Date.now(),e.event_properties={url:window.location.href,...e.event_properties};const t=await fetch(`${u.API_URL}/api/event`,{method:"POST",body:JSON.stringify({event_data:e}),headers:{"Content-Type":"application/json",Authorization:`Bearer ${n.get(o.ACCESS_TOKEN)}`}});if(!t.ok)throw t.status===401&&(this.accessToken=await m.aquireAccessToken(this.instances[0].client_id),n.set(o.ACCESS_TOKEN,this.accessToken,240)),new Error("[CPIX] Failed to publish event");s.debug("Event published:",t.ok)}catch(t){throw s.error("Failed to publish event:",t),new Error("[CPIX] Failed to publish event")}}}const v=new A;return typeof window<"u"&&(window.cpix=v),l.CarterAnalytics=v,Object.defineProperty(l,Symbol.toStringTag,{value:"Module"}),l}({});
|
|
1
|
+
var tracker=function(l){"use strict";var A=Object.defineProperty;var T=(l,d,p)=>d in l?A(l,d,{enumerable:!0,configurable:!0,writable:!0,value:p}):l[d]=p;var c=(l,d,p)=>(T(l,typeof d!="symbol"?d+"":d,p),p);const w={name:"@carter-rmn/cpix-js",version:"1.0.4",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:w.version,package:w.name,USER_PROPERTIES:{},SESSION_EXPIRY_DAYS:14,COMMON_PROPERTIES:{}},u={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"],a=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=>(a.debug("Consuming event:",i),Promise.resolve())}){super();c(this,"dataQueue");c(this,"retryQueue");c(this,"maxRetries");c(this,"initialDelay");c(this,"publishEvent");c(this,"retryEvent");c(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){a.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(){a.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){a.error("Failed to publish event:",r),this.scheduleRetry(t)}}})}scheduleRetry(t){if(t.retryCount>=this.maxRetries){a.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(){a.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){a.error("Failed to publish event:",r),this.scheduleRetry(t)}}})}}class m{static getBrowserInfo(){var r,o,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=(o=e.match(/firefox\/(\d+)/i))==null?void 0:o[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 a.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 a.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 w.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 o;for(;(o=i.exec(t))!==null;)o[2]&&r.push(decodeURIComponent(o[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}`,o=new Date;o.setTime(o.getTime()+i*60*1e3),document.cookie=`${r}=${t}; expires=${o.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(E.getParametersByName(r,window.location.href))){t=!0;break}}if(t){let i;const r=[];for(let o=0;o<e.length;o++){const g=e[o];i=E.getParametersByName(g,window.location.href),r.push({[g]:encodeURIComponent(i)})}s.set(u.UTM,JSON.stringify(r),n.SESSION_EXPIRY_DAYS*24*60)}}static getUtms(){const e=s.get(u.UTM);return h.isPresent(e)?JSON.parse(e):{}}static createSession(){s.exists(u.SESSION)||s.set(u.SESSION,h.guid(),n.SESSION_EXPIRY_DAYS*24*60),s.setUtms()}}class x{constructor(){c(this,"instances",[]);c(this,"initialized",!1);c(this,"sessionCreated",!1);c(this,"accessToken","");c(this,"metaParameters",{});c(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(u.SESSION)||(s.createSession(),this.sessionCreated=!0),s.exists(u.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(u.ACCESS_TOKEN)||(this.accessToken=await m.aquireAccessToken(this.instances[0].client_id),s.set(u.ACCESS_TOKEN,this.accessToken,240)),this.initialized=!0,a.debug("CPIX Initialized"),a.debug("Carter Analytics SDK initialized with options:",this.instances),this.sessionCreated&&this.publish({event:"init",user_properties:n.USER_PROPERTIES,...this.metaParameters}),this.attachHistoryListener()}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)),a.debug("Publishing event:",t),this.queue.publish(t),e.event==="logout"&&(s.delete(u.SESSION),s.createSession(),this.generateMetaParameters().then(i=>{this.metaParameters=i,s.set(u.META_PARAMETERS,JSON.stringify(this.metaParameters),1440)}))}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(u.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(u.ACCESS_TOKEN)}`}});if(!t.ok)throw t.status===401&&(this.accessToken=await m.aquireAccessToken(this.instances[0].client_id),s.set(u.ACCESS_TOKEN,this.accessToken,240)),new Error("[CPIX] Failed to publish event");a.debug("Event published:",t.ok)}catch(t){throw a.error("Failed to publish event:",t),new Error("[CPIX] Failed to publish event")}}}const y=new x;return typeof window<"u"&&(window.cpix=y),l.CarterAnalytics=y,Object.defineProperty(l,Symbol.toStringTag,{value:"Module"}),l}({});
|
package/dist/cpix.js
CHANGED
|
@@ -1,75 +1,78 @@
|
|
|
1
|
-
var
|
|
2
|
-
var
|
|
3
|
-
var o = (
|
|
4
|
-
const
|
|
1
|
+
var E = Object.defineProperty;
|
|
2
|
+
var y = (l, e, t) => e in l ? E(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.4", P = "module", _ = [
|
|
5
5
|
"dist"
|
|
6
|
-
],
|
|
6
|
+
], x = "dist/cpix.umd.cjs", A = "dist/cpix.js", R = "dist/cpix.d.ts", T = {
|
|
7
7
|
".": {
|
|
8
8
|
import: "./dist/cpix.js",
|
|
9
9
|
require: "./dist/cpix.umd.cjs"
|
|
10
10
|
}
|
|
11
|
-
},
|
|
11
|
+
}, b = {
|
|
12
12
|
dev: "vite",
|
|
13
13
|
build: "tsc && vite build",
|
|
14
14
|
preview: "vite preview"
|
|
15
|
-
},
|
|
15
|
+
}, I = {
|
|
16
16
|
picocolors: "^1.0.0",
|
|
17
17
|
"rollup-plugin-visualizer": "^5.12.0",
|
|
18
18
|
typescript: "^5.2.2",
|
|
19
19
|
vite: "^5.2.0",
|
|
20
20
|
"vite-plugin-progress": "^0.0.7"
|
|
21
|
-
},
|
|
21
|
+
}, U = {
|
|
22
22
|
"vite-plugin-dts": "^3.8.1"
|
|
23
23
|
}, m = {
|
|
24
|
-
name:
|
|
25
|
-
version:
|
|
26
|
-
type:
|
|
27
|
-
files:
|
|
28
|
-
main:
|
|
29
|
-
module:
|
|
30
|
-
types:
|
|
31
|
-
exports:
|
|
32
|
-
scripts:
|
|
33
|
-
devDependencies:
|
|
34
|
-
dependencies:
|
|
35
|
-
},
|
|
24
|
+
name: S,
|
|
25
|
+
version: v,
|
|
26
|
+
type: P,
|
|
27
|
+
files: _,
|
|
28
|
+
main: x,
|
|
29
|
+
module: A,
|
|
30
|
+
types: R,
|
|
31
|
+
exports: T,
|
|
32
|
+
scripts: b,
|
|
33
|
+
devDependencies: I,
|
|
34
|
+
dependencies: U
|
|
35
|
+
}, n = {
|
|
36
36
|
DEBUG: !1,
|
|
37
37
|
TRACKER_FUNC_NAME: "cpix",
|
|
38
38
|
API_URL: "",
|
|
39
39
|
QUEUE_MAX_RETRIES: 3,
|
|
40
40
|
QUEUE_INITIAL_DELAY: 1e4,
|
|
41
41
|
version: m.version,
|
|
42
|
-
package: m.name
|
|
43
|
-
},
|
|
42
|
+
package: m.name,
|
|
43
|
+
USER_PROPERTIES: {},
|
|
44
|
+
SESSION_EXPIRY_DAYS: 14,
|
|
45
|
+
COMMON_PROPERTIES: {}
|
|
46
|
+
}, u = {
|
|
44
47
|
SESSION: "cpix_session",
|
|
45
48
|
META_PARAMETERS: "cpix_meta_parameters",
|
|
46
49
|
ACCESS_TOKEN: "cpix_access_token",
|
|
47
50
|
UTM: "cpix_utm"
|
|
48
|
-
},
|
|
51
|
+
}, C = [
|
|
49
52
|
"utm_source",
|
|
50
53
|
"utm_medium",
|
|
51
54
|
"utm_term",
|
|
52
55
|
"utm_content",
|
|
53
56
|
"utm_campaign"
|
|
54
|
-
],
|
|
55
|
-
const
|
|
57
|
+
], c = /* @__PURE__ */ function() {
|
|
58
|
+
const l = () => n.DEBUG;
|
|
56
59
|
return {
|
|
57
60
|
info: function(...e) {
|
|
58
61
|
console.log(...e);
|
|
59
62
|
},
|
|
60
63
|
debug: function(...e) {
|
|
61
|
-
|
|
64
|
+
l() && console.log(...e);
|
|
62
65
|
},
|
|
63
66
|
error: function(...e) {
|
|
64
67
|
console.error(...e);
|
|
65
68
|
}
|
|
66
69
|
};
|
|
67
70
|
}();
|
|
68
|
-
class
|
|
71
|
+
class O extends EventTarget {
|
|
69
72
|
constructor(t = {
|
|
70
73
|
maxRetries: 3,
|
|
71
74
|
initialDelay: 1e4,
|
|
72
|
-
consumerHandler: (i) => (
|
|
75
|
+
consumerHandler: (i) => (c.debug("Consuming event:", i), Promise.resolve())
|
|
73
76
|
}) {
|
|
74
77
|
super();
|
|
75
78
|
o(this, "dataQueue");
|
|
@@ -82,7 +85,7 @@ class k extends EventTarget {
|
|
|
82
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();
|
|
83
86
|
}
|
|
84
87
|
publish(t) {
|
|
85
|
-
|
|
88
|
+
c.debug("publishing event");
|
|
86
89
|
const i = {
|
|
87
90
|
data: t,
|
|
88
91
|
id: `${Date.now() + Math.random()}`,
|
|
@@ -92,20 +95,20 @@ class k extends EventTarget {
|
|
|
92
95
|
this.dataQueue.push(i), this.dispatchEvent(this.publishEvent);
|
|
93
96
|
}
|
|
94
97
|
consume() {
|
|
95
|
-
|
|
98
|
+
c.debug("Started Consumer Queue"), this.addEventListener("eventPublished", async () => {
|
|
96
99
|
for (; this.dataQueue.length > 0; ) {
|
|
97
100
|
const t = this.dataQueue.shift(), { data: i = {} } = t;
|
|
98
101
|
try {
|
|
99
102
|
await this.handler(i), this.acknowledge(t == null ? void 0 : t.id);
|
|
100
103
|
} catch (r) {
|
|
101
|
-
|
|
104
|
+
c.error("Failed to publish event:", r), this.scheduleRetry(t);
|
|
102
105
|
}
|
|
103
106
|
}
|
|
104
107
|
});
|
|
105
108
|
}
|
|
106
109
|
scheduleRetry(t) {
|
|
107
110
|
if (t.retryCount >= this.maxRetries) {
|
|
108
|
-
|
|
111
|
+
c.error("Max retries reached for message:", t);
|
|
109
112
|
return;
|
|
110
113
|
}
|
|
111
114
|
setTimeout(() => {
|
|
@@ -120,24 +123,24 @@ class k extends EventTarget {
|
|
|
120
123
|
this.dataQueue = this.dataQueue.filter((i) => i.id !== t);
|
|
121
124
|
}
|
|
122
125
|
retry() {
|
|
123
|
-
|
|
126
|
+
c.debug("Started Retry Queue"), this.addEventListener("retryMessage", async () => {
|
|
124
127
|
for (; this.retryQueue.length > 0; ) {
|
|
125
128
|
const t = this.retryQueue.shift(), { data: i = {} } = t;
|
|
126
129
|
try {
|
|
127
130
|
await this.handler(i), this.acknowledge(t == null ? void 0 : t.id);
|
|
128
131
|
} catch (r) {
|
|
129
|
-
|
|
132
|
+
c.error("Failed to publish event:", r), this.scheduleRetry(t);
|
|
130
133
|
}
|
|
131
134
|
}
|
|
132
135
|
});
|
|
133
136
|
}
|
|
134
137
|
}
|
|
135
|
-
class
|
|
138
|
+
class d {
|
|
136
139
|
static getBrowserInfo() {
|
|
137
|
-
var r,
|
|
140
|
+
var r, a, p, f, g;
|
|
138
141
|
const e = navigator.userAgent || "";
|
|
139
142
|
let t, i;
|
|
140
|
-
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 = (
|
|
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 = (g = e.match(/rv:(\d+)/i)) == null ? void 0 : g[1]) : (t = "Unknown", i = "Unknown"), `${t} ${i}`;
|
|
141
144
|
}
|
|
142
145
|
static getDeviceCategory() {
|
|
143
146
|
const e = navigator.userAgent;
|
|
@@ -154,7 +157,7 @@ class h {
|
|
|
154
157
|
}
|
|
155
158
|
static async getDeviceNetworkParameters() {
|
|
156
159
|
try {
|
|
157
|
-
const e = await fetch(`${
|
|
160
|
+
const e = await fetch(`${n.API_URL}/api/geolocation`), { data: t } = await e.json();
|
|
158
161
|
return {
|
|
159
162
|
city: t.city || "Unknown",
|
|
160
163
|
region: t.region || "Unknown",
|
|
@@ -164,7 +167,7 @@ class h {
|
|
|
164
167
|
ip_address: t.ip_address || "Unknown"
|
|
165
168
|
};
|
|
166
169
|
} catch (e) {
|
|
167
|
-
return
|
|
170
|
+
return c.error("Error retrieving device network parameters:", e), {
|
|
168
171
|
city: "Unknown",
|
|
169
172
|
region: "Unknown",
|
|
170
173
|
country: "Unknown",
|
|
@@ -176,7 +179,7 @@ class h {
|
|
|
176
179
|
}
|
|
177
180
|
static async aquireAccessToken(e) {
|
|
178
181
|
try {
|
|
179
|
-
return (await (await fetch(`${
|
|
182
|
+
return (await (await fetch(`${n.API_URL}/api/authenticate`, {
|
|
180
183
|
method: "POST",
|
|
181
184
|
headers: {
|
|
182
185
|
"Content-Type": "application/json"
|
|
@@ -184,18 +187,18 @@ class h {
|
|
|
184
187
|
body: JSON.stringify({
|
|
185
188
|
accountId: e,
|
|
186
189
|
metadata: {
|
|
187
|
-
sdk:
|
|
188
|
-
version:
|
|
190
|
+
sdk: n.package,
|
|
191
|
+
version: n.version,
|
|
189
192
|
hostname: window.location.hostname
|
|
190
193
|
}
|
|
191
194
|
})
|
|
192
195
|
})).json()).accessToken;
|
|
193
196
|
} catch (t) {
|
|
194
|
-
throw
|
|
197
|
+
throw c.error("Error acquiring access token:", t), new Error("[CPIX] Authentication error");
|
|
195
198
|
}
|
|
196
199
|
}
|
|
197
200
|
}
|
|
198
|
-
class
|
|
201
|
+
class h {
|
|
199
202
|
static isPresent(e) {
|
|
200
203
|
return typeof e < "u" && e !== null && e !== "";
|
|
201
204
|
}
|
|
@@ -210,7 +213,7 @@ class d {
|
|
|
210
213
|
}
|
|
211
214
|
// reduces all optional data down to a string
|
|
212
215
|
static optionalData(e) {
|
|
213
|
-
return
|
|
216
|
+
return h.isPresent(e) === !1 ? "" : typeof e == "object" ? h.optionalData(JSON.stringify(e)) : typeof e == "function" ? h.optionalData(e()) : String(e);
|
|
214
217
|
}
|
|
215
218
|
static sleep(e) {
|
|
216
219
|
return new Promise((t) => setTimeout(t, e));
|
|
@@ -220,9 +223,9 @@ class w {
|
|
|
220
223
|
static getParametersByName(e, t) {
|
|
221
224
|
t || (t = window.location.href), e = e.replace(/[[\]]/g, "\\$&");
|
|
222
225
|
const i = new RegExp("[?&]" + e + "(=([^&#]*)|&|#|$)", "gi"), r = [];
|
|
223
|
-
let
|
|
224
|
-
for (; (
|
|
225
|
-
|
|
226
|
+
let a;
|
|
227
|
+
for (; (a = i.exec(t)) !== null; )
|
|
228
|
+
a[2] && r.push(decodeURIComponent(a[2].replace(/\+/g, " ")));
|
|
226
229
|
return r.length > 0 ? r : null;
|
|
227
230
|
}
|
|
228
231
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
@@ -233,15 +236,15 @@ class w {
|
|
|
233
236
|
}
|
|
234
237
|
class s {
|
|
235
238
|
static prefix() {
|
|
236
|
-
return `__${
|
|
239
|
+
return `__${n.TRACKER_FUNC_NAME}__`;
|
|
237
240
|
}
|
|
238
241
|
static get(e) {
|
|
239
242
|
const t = `${s.prefix()}${e}`, i = document.cookie.split("; ").find((r) => r.startsWith(`${t}=`));
|
|
240
243
|
return i ? i.split("=")[1] : void 0;
|
|
241
244
|
}
|
|
242
245
|
static set(e, t, i) {
|
|
243
|
-
const r = `${s.prefix()}${e}`,
|
|
244
|
-
|
|
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=/`;
|
|
245
248
|
}
|
|
246
249
|
static delete(e) {
|
|
247
250
|
const t = `${s.prefix()}${e}`;
|
|
@@ -257,11 +260,11 @@ class s {
|
|
|
257
260
|
return !!s.get(e);
|
|
258
261
|
}
|
|
259
262
|
static setUtms() {
|
|
260
|
-
const e =
|
|
263
|
+
const e = C;
|
|
261
264
|
let t = !1;
|
|
262
265
|
for (let i = 0; i < e.length; i++) {
|
|
263
266
|
const r = e[i];
|
|
264
|
-
if (
|
|
267
|
+
if (h.isPresent(w.getParametersByName(r, window.location.href))) {
|
|
265
268
|
t = !0;
|
|
266
269
|
break;
|
|
267
270
|
}
|
|
@@ -269,27 +272,36 @@ class s {
|
|
|
269
272
|
if (t) {
|
|
270
273
|
let i;
|
|
271
274
|
const r = [];
|
|
272
|
-
for (let
|
|
273
|
-
const p = e[
|
|
275
|
+
for (let a = 0; a < e.length; a++) {
|
|
276
|
+
const p = e[a];
|
|
274
277
|
i = w.getParametersByName(p, window.location.href), r.push({
|
|
275
|
-
[p]: i
|
|
278
|
+
[p]: encodeURIComponent(i)
|
|
276
279
|
});
|
|
277
280
|
}
|
|
278
|
-
s.set(
|
|
281
|
+
s.set(
|
|
282
|
+
u.UTM,
|
|
283
|
+
JSON.stringify(r),
|
|
284
|
+
n.SESSION_EXPIRY_DAYS * 24 * 60
|
|
285
|
+
);
|
|
279
286
|
}
|
|
280
287
|
}
|
|
281
288
|
static getUtms() {
|
|
282
|
-
const e = s.get(
|
|
283
|
-
return
|
|
289
|
+
const e = s.get(u.UTM);
|
|
290
|
+
return h.isPresent(e) ? JSON.parse(e) : {};
|
|
284
291
|
}
|
|
285
292
|
static createSession() {
|
|
286
|
-
s.exists(
|
|
293
|
+
s.exists(u.SESSION) || s.set(
|
|
294
|
+
u.SESSION,
|
|
295
|
+
h.guid(),
|
|
296
|
+
n.SESSION_EXPIRY_DAYS * 24 * 60
|
|
297
|
+
), s.setUtms();
|
|
287
298
|
}
|
|
288
299
|
}
|
|
289
|
-
class
|
|
300
|
+
class D {
|
|
290
301
|
constructor() {
|
|
291
302
|
o(this, "instances", []);
|
|
292
303
|
o(this, "initialized", !1);
|
|
304
|
+
o(this, "sessionCreated", !1);
|
|
293
305
|
o(this, "accessToken", "");
|
|
294
306
|
o(this, "metaParameters", {});
|
|
295
307
|
o(this, "queue");
|
|
@@ -297,9 +309,9 @@ class N {
|
|
|
297
309
|
throw new Error(
|
|
298
310
|
"[CPIX] CarterAnalytics SDK can only be used in a browser environment"
|
|
299
311
|
);
|
|
300
|
-
this.queue = new
|
|
301
|
-
maxRetries:
|
|
302
|
-
initialDelay:
|
|
312
|
+
this.queue = new O({
|
|
313
|
+
maxRetries: n.QUEUE_MAX_RETRIES,
|
|
314
|
+
initialDelay: n.QUEUE_INITIAL_DELAY,
|
|
303
315
|
consumerHandler: this.publishEventToServer.bind(this)
|
|
304
316
|
});
|
|
305
317
|
}
|
|
@@ -312,7 +324,7 @@ class N {
|
|
|
312
324
|
throw new Error(
|
|
313
325
|
"[CPIX] At least one instance configuration is required for initialization"
|
|
314
326
|
);
|
|
315
|
-
if (this.instances = e,
|
|
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(u.SESSION) || (s.createSession(), this.sessionCreated = !0), s.exists(u.META_PARAMETERS) || await this.generateMetaParameters().then((t) => {
|
|
316
328
|
this.metaParameters = t, s.set("metaParameters", JSON.stringify(t), 60 * 24);
|
|
317
329
|
}), s.setUtms(), this.metaParameters = JSON.parse(s.get("metaParameters")), this.initialized)
|
|
318
330
|
throw new Error(
|
|
@@ -320,23 +332,38 @@ class N {
|
|
|
320
332
|
);
|
|
321
333
|
if (!this.metaParameters)
|
|
322
334
|
throw new Error("[CPIX] Meta parameters have not been generated");
|
|
323
|
-
s.exists(
|
|
335
|
+
s.exists(u.ACCESS_TOKEN) || (this.accessToken = await d.aquireAccessToken(
|
|
324
336
|
this.instances[0].client_id
|
|
325
|
-
), s.set(
|
|
337
|
+
), s.set(u.ACCESS_TOKEN, this.accessToken, 60 * 4)), this.initialized = !0, c.debug("CPIX Initialized"), c.debug(
|
|
326
338
|
"Carter Analytics SDK initialized with options:",
|
|
327
339
|
this.instances
|
|
328
|
-
), this.publish({
|
|
340
|
+
), this.sessionCreated && this.publish({
|
|
329
341
|
event: "init",
|
|
342
|
+
user_properties: n.USER_PROPERTIES,
|
|
330
343
|
...this.metaParameters
|
|
331
|
-
}), this.
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
344
|
+
}), this.attachHistoryListener();
|
|
345
|
+
}
|
|
346
|
+
/**
|
|
347
|
+
* Attaches a history listener to publish a page_view event whenever the page changes.
|
|
348
|
+
*/
|
|
349
|
+
attachHistoryListener() {
|
|
350
|
+
const e = history.pushState, t = history.replaceState, i = () => {
|
|
351
|
+
this.publish({
|
|
352
|
+
event: "page_view",
|
|
353
|
+
event_properties: {
|
|
354
|
+
title: document.title,
|
|
355
|
+
page: window.location.pathname,
|
|
356
|
+
url: window.location.href
|
|
357
|
+
},
|
|
358
|
+
user_properties: n.USER_PROPERTIES,
|
|
359
|
+
...this.metaParameters
|
|
360
|
+
});
|
|
361
|
+
};
|
|
362
|
+
history.pushState = (...r) => {
|
|
363
|
+
e.apply(history, r), i();
|
|
364
|
+
}, history.replaceState = (...r) => {
|
|
365
|
+
t.apply(history, r), i();
|
|
366
|
+
}, window.addEventListener("popstate", i), i();
|
|
340
367
|
}
|
|
341
368
|
/**
|
|
342
369
|
* Publishes an event to the analytics queue.
|
|
@@ -351,9 +378,9 @@ class N {
|
|
|
351
378
|
...e,
|
|
352
379
|
...this.metaParameters
|
|
353
380
|
};
|
|
354
|
-
t.utm_params = s.getUtms(), document.referrer && (t.referrer = encodeURIComponent(document.referrer)),
|
|
381
|
+
t.utm_params = s.getUtms(), document.referrer && (t.referrer = encodeURIComponent(document.referrer)), c.debug("Publishing event:", t), this.queue.publish(t), e.event === "logout" && (s.delete(u.SESSION), s.createSession(), this.generateMetaParameters().then((i) => {
|
|
355
382
|
this.metaParameters = i, s.set(
|
|
356
|
-
|
|
383
|
+
u.META_PARAMETERS,
|
|
357
384
|
JSON.stringify(this.metaParameters),
|
|
358
385
|
60 * 24
|
|
359
386
|
);
|
|
@@ -367,10 +394,10 @@ class N {
|
|
|
367
394
|
throw new Error(
|
|
368
395
|
"[CPIX] Meta parameters can only be generated in a browser environment"
|
|
369
396
|
);
|
|
370
|
-
const e = await
|
|
397
|
+
const e = await d.getDeviceNetworkParameters();
|
|
371
398
|
return {
|
|
372
399
|
client_id: this.instances[0].client_id,
|
|
373
|
-
session: s.get(
|
|
400
|
+
session: s.get(u.SESSION),
|
|
374
401
|
location: {
|
|
375
402
|
city: e.city,
|
|
376
403
|
region: e.region,
|
|
@@ -379,10 +406,11 @@ class N {
|
|
|
379
406
|
country: e.country
|
|
380
407
|
},
|
|
381
408
|
device: {
|
|
382
|
-
category:
|
|
383
|
-
brand:
|
|
409
|
+
category: d.getDeviceCategory(),
|
|
410
|
+
brand: d.getDeviceManufacturer(),
|
|
384
411
|
ip_address: e.ip_address,
|
|
385
|
-
platform:
|
|
412
|
+
platform: d.getDevicePlatform(),
|
|
413
|
+
cpix_sdk_version: n.version
|
|
386
414
|
},
|
|
387
415
|
referrer: encodeURIComponent(document.referrer)
|
|
388
416
|
};
|
|
@@ -395,28 +423,29 @@ class N {
|
|
|
395
423
|
try {
|
|
396
424
|
e.timestamp = Date.now(), e.event_properties = {
|
|
397
425
|
url: window.location.href,
|
|
426
|
+
...n.COMMON_PROPERTIES,
|
|
398
427
|
...e.event_properties
|
|
399
|
-
};
|
|
400
|
-
const t = await fetch(`${
|
|
428
|
+
}, e.device && (e.device.cpix_sdk_version = n.version);
|
|
429
|
+
const t = await fetch(`${n.API_URL}/api/event`, {
|
|
401
430
|
method: "POST",
|
|
402
431
|
body: JSON.stringify({ event_data: e }),
|
|
403
432
|
headers: {
|
|
404
433
|
"Content-Type": "application/json",
|
|
405
|
-
Authorization: `Bearer ${s.get(
|
|
434
|
+
Authorization: `Bearer ${s.get(u.ACCESS_TOKEN)}`
|
|
406
435
|
}
|
|
407
436
|
});
|
|
408
437
|
if (!t.ok)
|
|
409
|
-
throw t.status === 401 && (this.accessToken = await
|
|
438
|
+
throw t.status === 401 && (this.accessToken = await d.aquireAccessToken(
|
|
410
439
|
this.instances[0].client_id
|
|
411
|
-
), s.set(
|
|
412
|
-
|
|
440
|
+
), s.set(u.ACCESS_TOKEN, this.accessToken, 60 * 4)), new Error("[CPIX] Failed to publish event");
|
|
441
|
+
c.debug("Event published:", t.ok);
|
|
413
442
|
} catch (t) {
|
|
414
|
-
throw
|
|
443
|
+
throw c.error("Failed to publish event:", t), new Error("[CPIX] Failed to publish event");
|
|
415
444
|
}
|
|
416
445
|
}
|
|
417
446
|
}
|
|
418
|
-
const
|
|
419
|
-
typeof window < "u" && (window.cpix =
|
|
447
|
+
const N = new D();
|
|
448
|
+
typeof window < "u" && (window.cpix = N);
|
|
420
449
|
export {
|
|
421
|
-
|
|
450
|
+
N as CarterAnalytics
|
|
422
451
|
};
|
package/dist/cpix.umd.cjs
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
(function(u,l){typeof exports=="object"&&typeof module<"u"?l(exports):typeof define=="function"&&define.amd?define(["exports"],l):(u=typeof globalThis<"u"?globalThis:u||self,l(u.tracker={}))})(this,function(u){"use strict";var P=Object.defineProperty;var T=(u,l,p)=>l in u?P(u,l,{enumerable:!0,configurable:!0,writable:!0,value:p}):u[l]=p;var c=(u,l,p)=>(T(u,typeof l!="symbol"?l+"":l,p),p);const w={name:"@carter-rmn/cpix-js",version:"1.0.2",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"}},d={DEBUG:!1,TRACKER_FUNC_NAME:"cpix",API_URL:"",QUEUE_MAX_RETRIES:3,QUEUE_INITIAL_DELAY:1e4,version:w.version,package:w.name},o={SESSION:"cpix_session",META_PARAMETERS:"cpix_meta_parameters",ACCESS_TOKEN:"cpix_access_token",UTM:"cpix_utm"},x=["utm_source","utm_medium","utm_term","utm_content","utm_campaign"],r=function(){const f=()=>d.DEBUG;return{info:function(...e){console.log(...e)},debug:function(...e){f()&&console.log(...e)},error:function(...e){console.error(...e)}}}();class b extends EventTarget{constructor(t={maxRetries:3,initialDelay:1e4,consumerHandler:i=>(r.debug("Consuming event:",i),Promise.resolve())}){super();c(this,"dataQueue");c(this,"retryQueue");c(this,"maxRetries");c(this,"initialDelay");c(this,"publishEvent");c(this,"retryEvent");c(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){r.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(){r.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){r.error("Failed to publish event:",s),this.scheduleRetry(t)}}})}scheduleRetry(t){if(t.retryCount>=this.maxRetries){r.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(){r.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){r.error("Failed to publish event:",s),this.scheduleRetry(t)}}})}}class m{static getBrowserInfo(){var s,a,g,E,S;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=(a=e.match(/firefox\/(\d+)/i))==null?void 0:a[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=(E=e.match(/edge\/(\d+)/i))==null?void 0:E[1]):/trident/i.test(e)?(t="Internet Explorer",i=(S=e.match(/rv:(\d+)/i))==null?void 0:S[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(`${d.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 r.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(`${d.API_URL}/api/authenticate`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({accountId:e,metadata:{sdk:d.package,version:d.version,hostname:window.location.hostname}})})).json()).accessToken}catch(t){throw r.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 w.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 y{static getParametersByName(e,t){t||(t=window.location.href),e=e.replace(/[[\]]/g,"\\$&");const i=new RegExp("[?&]"+e+"(=([^&#]*)|&|#|$)","gi"),s=[];let a;for(;(a=i.exec(t))!==null;)a[2]&&s.push(decodeURIComponent(a[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 n{static prefix(){return`__${d.TRACKER_FUNC_NAME}__`}static get(e){const t=`${n.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=`${n.prefix()}${e}`,a=new Date;a.setTime(a.getTime()+i*60*1e3),document.cookie=`${s}=${t}; expires=${a.toUTCString()}; path=/`}static delete(e){const t=`${n.prefix()}${e}`;document.cookie=`${t}=; expires=Thu, 01 Jan 1970 00:00:00 UTC; path=/`}static clear(){document.cookie.split("; ").filter(e=>e.startsWith(n.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!!n.get(e)}static setUtms(){const e=x;let t=!1;for(let i=0;i<e.length;i++){const s=e[i];if(h.isPresent(y.getParametersByName(s,window.location.href))){t=!0;break}}if(t){let i;const s=[];for(let a=0;a<e.length;a++){const g=e[a];i=y.getParametersByName(g,window.location.href),s.push({[g]:i})}n.set(o.UTM,JSON.stringify(s),14*24*60)}}static getUtms(){const e=n.get(o.UTM);return h.isPresent(e)?JSON.parse(e):{}}static createSession(){n.exists(o.SESSION)||n.set(o.SESSION,h.guid(),14*24*60),n.setUtms()}}class A{constructor(){c(this,"instances",[]);c(this,"initialized",!1);c(this,"accessToken","");c(this,"metaParameters",{});c(this,"queue");if(!window)throw new Error("[CPIX] CarterAnalytics SDK can only be used in a browser environment");this.queue=new b({maxRetries:d.QUEUE_MAX_RETRIES,initialDelay:d.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,d.DEBUG=this.instances[0].options.debug===!0,d.API_URL=this.instances[0].options.tracker_server_url,n.exists(o.SESSION)||n.createSession(),n.exists(o.META_PARAMETERS)||await this.generateMetaParameters().then(t=>{this.metaParameters=t,n.set("metaParameters",JSON.stringify(t),60*24)}),n.setUtms(),this.metaParameters=JSON.parse(n.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");n.exists(o.ACCESS_TOKEN)||(this.accessToken=await m.aquireAccessToken(this.instances[0].client_id),n.set(o.ACCESS_TOKEN,this.accessToken,60*4)),this.initialized=!0,r.debug("CPIX Initialized"),r.debug("Carter Analytics SDK initialized with options:",this.instances),this.publish({event:"init",...this.metaParameters}),this.publish({event:"page_view",event_properties:{title:document.title,page:window.location.pathname,url:window.location.href},...this.metaParameters})}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=n.getUtms(),document.referrer&&(t.referrer=encodeURIComponent(document.referrer)),r.debug("Publishing event:",t),this.queue.publish(t),e.event==="logout"&&(n.delete(o.SESSION),n.createSession(),this.generateMetaParameters().then(i=>{this.metaParameters=i,n.set(o.META_PARAMETERS,JSON.stringify(this.metaParameters),60*24)}))}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:n.get(o.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()},referrer:encodeURIComponent(document.referrer)}}async publishEventToServer(e){try{e.timestamp=Date.now(),e.event_properties={url:window.location.href,...e.event_properties};const t=await fetch(`${d.API_URL}/api/event`,{method:"POST",body:JSON.stringify({event_data:e}),headers:{"Content-Type":"application/json",Authorization:`Bearer ${n.get(o.ACCESS_TOKEN)}`}});if(!t.ok)throw t.status===401&&(this.accessToken=await m.aquireAccessToken(this.instances[0].client_id),n.set(o.ACCESS_TOKEN,this.accessToken,60*4)),new Error("[CPIX] Failed to publish event");r.debug("Event published:",t.ok)}catch(t){throw r.error("Failed to publish event:",t),new Error("[CPIX] Failed to publish event")}}}const v=new A;typeof window<"u"&&(window.cpix=v),u.CarterAnalytics=v,Object.defineProperty(u,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 b=(l,d,p)=>d in l?T(l,d,{enumerable:!0,configurable:!0,writable:!0,value:p}):l[d]=p;var c=(l,d,p)=>(b(l,typeof d!="symbol"?d+"":d,p),p);const w={name:"@carter-rmn/cpix-js",version:"1.0.4",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:w.version,package:w.name,USER_PROPERTIES:{},SESSION_EXPIRY_DAYS:14,COMMON_PROPERTIES:{}},u={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"],a=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=>(a.debug("Consuming event:",i),Promise.resolve())}){super();c(this,"dataQueue");c(this,"retryQueue");c(this,"maxRetries");c(this,"initialDelay");c(this,"publishEvent");c(this,"retryEvent");c(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){a.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(){a.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){a.error("Failed to publish event:",n),this.scheduleRetry(t)}}})}scheduleRetry(t){if(t.retryCount>=this.maxRetries){a.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(){a.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){a.error("Failed to publish event:",n),this.scheduleRetry(t)}}})}}class m{static getBrowserInfo(){var n,o,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=(o=e.match(/firefox\/(\d+)/i))==null?void 0:o[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 a.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 a.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 w.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 y{static getParametersByName(e,t){t||(t=window.location.href),e=e.replace(/[[\]]/g,"\\$&");const i=new RegExp("[?&]"+e+"(=([^&#]*)|&|#|$)","gi"),n=[];let o;for(;(o=i.exec(t))!==null;)o[2]&&n.push(decodeURIComponent(o[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}`,o=new Date;o.setTime(o.getTime()+i*60*1e3),document.cookie=`${n}=${t}; expires=${o.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(y.getParametersByName(n,window.location.href))){t=!0;break}}if(t){let i;const n=[];for(let o=0;o<e.length;o++){const g=e[o];i=y.getParametersByName(g,window.location.href),n.push({[g]:encodeURIComponent(i)})}s.set(u.UTM,JSON.stringify(n),r.SESSION_EXPIRY_DAYS*24*60)}}static getUtms(){const e=s.get(u.UTM);return h.isPresent(e)?JSON.parse(e):{}}static createSession(){s.exists(u.SESSION)||s.set(u.SESSION,h.guid(),r.SESSION_EXPIRY_DAYS*24*60),s.setUtms()}}class x{constructor(){c(this,"instances",[]);c(this,"initialized",!1);c(this,"sessionCreated",!1);c(this,"accessToken","");c(this,"metaParameters",{});c(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(u.SESSION)||(s.createSession(),this.sessionCreated=!0),s.exists(u.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(u.ACCESS_TOKEN)||(this.accessToken=await m.aquireAccessToken(this.instances[0].client_id),s.set(u.ACCESS_TOKEN,this.accessToken,60*4)),this.initialized=!0,a.debug("CPIX Initialized"),a.debug("Carter Analytics SDK initialized with options:",this.instances),this.sessionCreated&&this.publish({event:"init",user_properties:r.USER_PROPERTIES,...this.metaParameters}),this.attachHistoryListener()}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)),a.debug("Publishing event:",t),this.queue.publish(t),e.event==="logout"&&(s.delete(u.SESSION),s.createSession(),this.generateMetaParameters().then(i=>{this.metaParameters=i,s.set(u.META_PARAMETERS,JSON.stringify(this.metaParameters),60*24)}))}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(u.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(u.ACCESS_TOKEN)}`}});if(!t.ok)throw t.status===401&&(this.accessToken=await m.aquireAccessToken(this.instances[0].client_id),s.set(u.ACCESS_TOKEN,this.accessToken,60*4)),new Error("[CPIX] Failed to publish event");a.debug("Event published:",t.ok)}catch(t){throw a.error("Failed to publish event:",t),new Error("[CPIX] Failed to publish event")}}}const E=new x;typeof window<"u"&&(window.cpix=E),l.CarterAnalytics=E,Object.defineProperty(l,Symbol.toStringTag,{value:"Module"})});
|
|
@@ -6,6 +6,7 @@ import { Event, Init } from '../types/common.types';
|
|
|
6
6
|
declare class CarterAnalytics {
|
|
7
7
|
private instances;
|
|
8
8
|
private initialized;
|
|
9
|
+
private sessionCreated;
|
|
9
10
|
private accessToken;
|
|
10
11
|
private metaParameters;
|
|
11
12
|
private queue;
|
|
@@ -15,6 +16,10 @@ declare class CarterAnalytics {
|
|
|
15
16
|
* @param options - The configuration options for initializing the SDK.
|
|
16
17
|
*/
|
|
17
18
|
initialize(options: Init[]): Promise<void>;
|
|
19
|
+
/**
|
|
20
|
+
* Attaches a history listener to publish a page_view event whenever the page changes.
|
|
21
|
+
*/
|
|
22
|
+
private attachHistoryListener;
|
|
18
23
|
/**
|
|
19
24
|
* Publishes an event to the analytics queue.
|
|
20
25
|
* @param event - The event to be published.
|
|
@@ -4,6 +4,9 @@
|
|
|
4
4
|
export interface InitOptions {
|
|
5
5
|
debug?: boolean;
|
|
6
6
|
tracker_server_url: string;
|
|
7
|
+
session_expiry_days?: number;
|
|
8
|
+
user_properties?: UserProperties;
|
|
9
|
+
common_properties?: EventProperties;
|
|
7
10
|
}
|
|
8
11
|
/**
|
|
9
12
|
* Represents the initialization options for the application.
|
|
@@ -16,7 +19,7 @@ export interface Init {
|
|
|
16
19
|
/**
|
|
17
20
|
* Additional options for the application.
|
|
18
21
|
*/
|
|
19
|
-
options:
|
|
22
|
+
options: InitOptions;
|
|
20
23
|
}
|
|
21
24
|
/**
|
|
22
25
|
* Represents the event properties.
|
|
@@ -31,7 +34,7 @@ export interface UserProperties {
|
|
|
31
34
|
/**
|
|
32
35
|
* The user ID.
|
|
33
36
|
*/
|
|
34
|
-
user_id
|
|
37
|
+
user_id?: string;
|
|
35
38
|
[key: string]: unknown;
|
|
36
39
|
}
|
|
37
40
|
/**
|
|
@@ -79,6 +82,10 @@ export interface Device {
|
|
|
79
82
|
* The platform of the device.
|
|
80
83
|
*/
|
|
81
84
|
platform: string;
|
|
85
|
+
/**
|
|
86
|
+
* The SDK version.
|
|
87
|
+
*/
|
|
88
|
+
cpix_sdk_version?: string;
|
|
82
89
|
}
|
|
83
90
|
/**
|
|
84
91
|
* Represents the meta parameters for an event.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@carter-rmn/cpix-js",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.4",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"files": [
|
|
6
6
|
"dist"
|
|
@@ -14,11 +14,6 @@
|
|
|
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
|
-
},
|
|
22
17
|
"devDependencies": {
|
|
23
18
|
"picocolors": "^1.0.0",
|
|
24
19
|
"rollup-plugin-visualizer": "^5.12.0",
|
|
@@ -28,5 +23,10 @@
|
|
|
28
23
|
},
|
|
29
24
|
"dependencies": {
|
|
30
25
|
"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
|
+
}
|