@deriv-com/analytics 1.40.1 → 1.40.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/browser/analytics.bundle.global.js +5 -5
- package/dist/browser/analytics.bundle.global.js.map +1 -1
- package/dist/browser/analytics.esm.mjs +1 -1
- package/dist/browser/analytics.esm.mjs.map +1 -1
- package/dist/index.d.mts +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +1 -1
- package/dist/index.mjs.map +1 -1
- package/dist/metafile-cjs.json +1 -1
- package/dist/metafile-esm.json +1 -1
- package/dist/metafile-iife.json +1 -1
- package/dist/{posthog-BqcxWQRm.d.mts → posthog-C-VllHa3.d.mts} +1 -1
- package/dist/{posthog-BqcxWQRm.d.ts → posthog-C-VllHa3.d.ts} +1 -1
- package/dist/posthog-VJQDUIWQ.mjs +4 -0
- package/dist/posthog-VJQDUIWQ.mjs.map +1 -0
- package/dist/providers/posthog/index.d.mts +1 -1
- package/dist/providers/posthog/index.d.ts +1 -1
- package/dist/providers/posthog/index.js +1 -1
- package/dist/providers/posthog/index.js.map +1 -1
- package/dist/providers/posthog/index.mjs +1 -1
- package/dist/providers/posthog/index.mjs.map +1 -1
- package/package.json +8 -1
- package/dist/posthog-ZVEV7JVD.mjs +0 -4
- package/dist/posthog-ZVEV7JVD.mjs.map +0 -1
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
/* @deriv-com/analytics - Browser ESM Bundle (RudderStack + PostHog) - Built with tsup */
|
|
2
|
-
import{a as G}from"../chunk-YVBRA3QD.mjs";import{c as V,g as R,h as U,i as b,j as O,k as E,l as D}from"../chunk-F3U33XPR.mjs";var Z=4320*60*60,w=class w{constructor(i,e,r=!1){this.analytics=new G;this.has_identified=!1;this.has_initialized=!1;this.current_page="";this.rudderstack_anonymous_cookie_key="rudder_anonymous_id";this.debug=!1;this.log=R("[RudderStack]",()=>this.debug);this.getAnonymousId=()=>document.cookie.match("(^|;)\\s*"+this.rudderstack_anonymous_cookie_key+"\\s*=\\s*([^;]+)")?.pop();this.setCookieIfNotExists=()=>{if(!this.getAnonymousId())try{let e=window.location.hostname,l=["webflow.io"].some(g=>e.endsWith(g))?e:e.split(".").slice(-2).join("."),f;if(crypto?.randomUUID)f=crypto.randomUUID();else if(crypto?.getRandomValues){let g=new Uint8Array(16);crypto.getRandomValues(g),g[6]=g[6]&15|64,g[8]=g[8]&63|128;let k=Array.from(g,z=>z.toString(16).padStart(2,"0")).join("");f=`${k.slice(0,8)}-${k.slice(8,12)}-${k.slice(12,16)}-${k.slice(16,20)}-${k.slice(20)}`}else throw new Error("Crypto API not available for secure random UUID generation");let v=window.location.protocol==="https:"?"; Secure":"";document.cookie=`${this.rudderstack_anonymous_cookie_key}=${f}; path=/; Domain=${l}; max-age=${Z}; SameSite=Lax${v}`}catch(e){console.warn("RudderStack: Failed to set anonymous ID cookie",e)}};this.getUserId=()=>this.analytics.getUserId();this.init=i=>{if(!i){console.warn("RudderStack: Initialization skipped - no key provided");return}this.log("init | loading SDK",{dataplane:V});try{this.setCookieIfNotExists(),this.analytics.load(i,V,{externalAnonymousIdCookieName:this.rudderstack_anonymous_cookie_key,storage:{type:"localStorage"},lockIntegrationsVersion:!0,onLoaded:()=>{this.has_initialized=!0,this.has_identified=!!this.getUserId(),this.log("init | SDK loaded successfully",{userId:this.getUserId(),anonymousId:this.getAnonymousId()}),this.onLoadedCallback?.()}})}catch(e){console.error("RudderStack: Failed to initialize",e)}};this.identifyEvent=(i,e)=>{if(!this.has_initialized){console.warn("RudderStack: Cannot identify - not initialized");return}let r=this.getUserId();if(!r||r!==i)try{this.log("identifyEvent | identifying user",{user_id:i,traits:e}),this.analytics.identify(i,e||{}),this.has_identified=!0}catch(c){console.error("RudderStack: Failed to identify user",c)}else this.log("identifyEvent | user already identified",{user_id:i}),this.has_identified=!0};this.pageView=(i,e="Deriv App",r,c)=>{if(!(!this.has_initialized||i===this.current_page))try{let l={...r&&{user_id:r},...c};this.log("pageView | tracking page view",{platform:e,current_page:i,properties:l}),this.analytics.page(e,i,l),this.current_page=i}catch(l){console.error("RudderStack: Failed to track page view",l)}};this.reset=()=>{if(this.has_initialized)try{this.log("reset | resetting RudderStack session"),this.analytics.reset(),this.has_identified=!1}catch(i){console.error("RudderStack: Failed to reset",i)}};this.track=(i,e)=>{if(this.has_initialized)try{this.log("track | sending event to RudderStack",{event:i,payload:e}),this.analytics.track(i,e)}catch(r){console.warn("RudderStack: Failed to track event",r)}};this.onLoadedCallback=e,this.debug=r,this.init(i)}};w.getRudderStackInstance=(i,e,r=!1)=>(w._instance||(w._instance=new w(i,e,r)),w._instance);var P=w;var C="cached_analytics_events",x="cached_analytics_page_views",$=(d,i)=>{try{let e=localStorage.getItem(C),r=e?JSON.parse(e):[];r.push({name:d,properties:i,timestamp:Date.now()}),localStorage.setItem(C,JSON.stringify(r))}catch(e){console.warn("Analytics: Failed to cache event",e)}},L=(d,i)=>{try{let e=localStorage.getItem(x),r=e?JSON.parse(e):[];r.push({name:d,properties:i,timestamp:Date.now()}),localStorage.setItem(x,JSON.stringify(r))}catch(e){console.warn("Analytics: Failed to cache page view",e)}},N=()=>{try{let d=localStorage.getItem(C);if(d){let i=JSON.parse(d);return Array.isArray(i)?i:[]}}catch(d){console.warn("Analytics: Failed to get cached events",d)}return[]},j=()=>{try{let d=localStorage.getItem(x);if(d){let i=JSON.parse(d);return Array.isArray(i)?i:[]}}catch(d){console.warn("Analytics: Failed to get cached pages",d)}return[]},H=()=>{try{localStorage.removeItem(C)}catch(d){console.warn("Analytics: Failed to clear cached events",d)}},J=()=>{try{localStorage.removeItem(x)}catch(d){console.warn("Analytics: Failed to clear cached page views",d)}};function Y(d){let i=d?.debug??!1,e=R("",()=>i),r,c,l,f={},I={},v=[],g=[],k=!1,z=()=>{if(!k&&c?.has_initialized){k=!0;try{let t=N();t.length>0&&(e(`processStorageCache | replaying ${t.length} cached event(s)`,t),t.forEach(s=>{let a=E(s.properties);c?.track(s.name,a)}),H());let n=j();n.length>0&&(e(`processStorageCache | replaying ${n.length} cached page view(s)`,n),n.forEach(s=>{c?.pageView(s.name,"Deriv App",S(),s.properties)}),J())}catch(t){console.warn("Analytics: Failed to process storage cache",t)}}},B=()=>{e("onSdkLoaded | RudderStack SDK loaded"),z(),g.length>0&&e(`onSdkLoaded | flushing ${g.length} pending identify call(s)`),g.forEach(({userId:t,traits:n})=>{t&&c?.identifyEvent(t,n)}),g=[]},K=async({growthbookKey:t,growthbookDecryptionKey:n,rudderstackKey:s,growthbookOptions:a,posthogOptions:h,debug:_})=>{var p,u;_!==void 0&&(i=_),e("initialise | starting analytics initialization",{rudderstack:!!s,growthbook:!!t,posthog:!!h});try{let y=a?.attributes?.country||(t?await O():void 0);if(s&&(e("initialise | initializing RudderStack"),c=P.getRudderStackInstance(s,B,i)),a?.attributes&&Object.keys(a.attributes).length>0){let o=a.attributes,A=c?.getAnonymousId();f={...f,country:y,...o.user_language&&{user_language:o.user_language},...o.account_type&&{account_type:o.account_type},...o.app_id&&{app_id:o.app_id},...o.residence_country&&{residence_country:o.residence_country},...o.device_type&&{device_type:o.device_type},...o.url&&{url:o.url},...o.email_hash&&{email_hash:o.email_hash},...o.network_type&&{network_type:o.network_type},...o.network_rtt&&{network_rtt:o.network_rtt},...o.network_downlink&&{network_downlink:o.network_downlink},...o.account_currency&&{account_currency:o.account_currency},...o.account_mode&&{account_mode:o.account_mode},loggedIn:!!o.loggedIn,...o.user_id&&!b(o.user_id)&&{user_id:o.user_id},...A&&{anonymous_id:A}}}a??(a={}),a.attributes??(a.attributes={});let m=c?.getAnonymousId();if((p=a.attributes).id??(p.id=m),(u=a.attributes).country??(u.country=y),t){e("initialise | initializing GrowthBook");let{Growthbook:o}=await import("../growthbook-T47IBUAJ.mjs");r=o.getGrowthBookInstance(t,n,a,i),e("initialise | GrowthBook initialized");let A=setInterval(()=>{Object.keys(I).length>0?clearInterval(A):I=T("tracking-buttons-config",{})},1e3)}if(h){e("initialise | initializing PostHog");let{Posthog:o}=await import("../posthog-ZVEV7JVD.mjs");l=o.getPosthogInstance(h,i),e("initialise | PostHog initialized")}e("initialise | analytics initialization complete")}catch(y){console.warn("Analytics: Failed to initialize",y)}},W=t=>{e("setAttributes | received attributes",t);let{user_id:n,...s}=t,a=n??S();if(r){let h={...s};n&&!b(n)&&(h.user_id=n),a&&(h.id=a,h.user_id=a),e("setAttributes | called GrowthBook setAttributes",h),r.setAttributes(h)}f={...f,...Object.fromEntries(Object.entries(s).filter(([,h])=>h!==void 0)),...n!==void 0&&!b(n)&&{user_id:n}},e("setAttributes | updated core_data",f)},q=t=>r?.getFeatureState(t)?.experimentResult?.name,T=(t,n)=>r?.getFeatureValue(t,n),M=async()=>await r?.getStatus(),X=t=>r?.isOn(t),Q=t=>r?.setUrl(t),S=()=>{let t=c?.getUserId()||"";return t&&!b(t)?t:""},F={initialise:K,setAttributes:W,identifyEvent:(t,n)=>{let s=t||S();if(!s){e("identifyEvent | skipped \u2014 no user_id available");return}e("identifyEvent | called",{user_id:s,traits:n});let a=u=>{if(!u)return u;let{email:y,...m}=u;return{...m,...y&&{is_internal:U(y)}}},h=n?.rudderstack!==void 0||n?.posthog!==void 0,_,p;if(h){let{rudderstack:u,posthog:y,...m}=n;_=a({...m,...u}),p=a({...m,...y})}else _=a(n),p=a(n);c&&(c.has_initialized?(e("identifyEvent | calling RudderStack identify",{user_id:s,traits:_}),c.identifyEvent(s,_)):g.some(u=>u.userId===s)||(e("identifyEvent | RudderStack not initialized \u2014 queuing identify call",{user_id:s}),g.push({userId:s,traits:_}))),l?.has_initialized&&p&&(e("identifyEvent | calling PostHog identify",{user_id:s,traits:p}),l.identifyEvent(s,p))},backfillPersonProperties:({user_id:t,email:n,language:s,country_of_residence:a})=>{e("backfillPersonProperties | called",{user_id:t}),l?.has_initialized?(e("backfillPersonProperties | backfilling person properties in PostHog",{user_id:t}),l.backfillPersonProperties({user_id:t,email:n,language:s,country_of_residence:a})):e("backfillPersonProperties | skipped \u2014 PostHog not initialized")},getFeatureState:q,getFeatureValue:T,getGrowthbookStatus:M,isFeatureOn:X,setUrl:Q,getId:S,getAnonymousId:()=>c?.getAnonymousId()||"",trackEvent:(t,n)=>{let s=S();e("trackEvent | called",{event:t,analytics_data:n,userId:s,core_data:f});let a={...f,...n,...s&&!f.user_id&&{user_id:s}};if(e("trackEvent | built payload",{event:t,final_payload:a}),!(!(t in I)||I[t])){e("trackEvent | skipped \u2014 event disabled by tracking_config",{event:t});return}let _=c?.has_initialized;if(!navigator.onLine||!_)_?(e("trackEvent | offline \u2014 caching event to memory",{event:t}),v.push({event:t,payload:a})):(e("trackEvent | RudderStack not initialized \u2014 caching event to localStorage",{event:t}),$(t,a));else{v.length>0&&(e(`trackEvent | flushing ${v.length} offline cached event(s) to RudderStack`),v.forEach(u=>{let y=E(u.payload);c?.track(u.event,y)}),v=[]);let p=E(a);e("trackEvent | sending event to RudderStack",{event:t,payload:p}),c?.track(t,p)}if(l?.has_initialized){let p=["page_name","user_language","form_name","version","email_hash"],u=D(a),y=E(Object.fromEntries(Object.entries(u).filter(([m])=>!p.includes(m))));e("trackEvent | sending event to PostHog",{event:t,payload:y}),l.capture(t,y)}},getInstances:()=>({ab:r,tracking:c,posthog:l}),pageView:(t,n="Deriv App",s)=>{let a=S();e("pageView | called",{current_page:t,platform:n,properties:s,userId:a}),c?.has_initialized?(e("pageView | sending page view to RudderStack",{current_page:t,platform:n}),c.pageView(t,n,a,s)):(e("pageView | RudderStack not initialized \u2014 caching page view to localStorage",{current_page:t}),L(t,{platform:n,...s}))},reset:()=>{e("reset | resetting all providers"),c?.has_initialized&&(e("reset | resetting RudderStack"),c.reset()),l?.has_initialized&&(e("reset | resetting PostHog"),l.reset())}};return typeof window<"u"&&(window.AnalyticsInstance=F),F}var ee=Y();export{ee as Analytics};
|
|
2
|
+
import{a as G}from"../chunk-YVBRA3QD.mjs";import{c as V,g as R,h as U,i as b,j as D,k as A,l as O}from"../chunk-F3U33XPR.mjs";var Z=4320*60*60,v=class v{constructor(i,e,r=!1){this.analytics=new G;this.has_identified=!1;this.has_initialized=!1;this.current_page="";this.rudderstack_anonymous_cookie_key="rudder_anonymous_id";this.debug=!1;this.log=R("[RudderStack]",()=>this.debug);this.getAnonymousId=()=>document.cookie.match("(^|;)\\s*"+this.rudderstack_anonymous_cookie_key+"\\s*=\\s*([^;]+)")?.pop();this.setCookieIfNotExists=()=>{if(!this.getAnonymousId())try{let e=window.location.hostname,l=["webflow.io"].some(g=>e.endsWith(g))?e:e.split(".").slice(-2).join("."),p;if(crypto?.randomUUID)p=crypto.randomUUID();else if(crypto?.getRandomValues){let g=new Uint8Array(16);crypto.getRandomValues(g),g[6]=g[6]&15|64,g[8]=g[8]&63|128;let _=Array.from(g,z=>z.toString(16).padStart(2,"0")).join("");p=`${_.slice(0,8)}-${_.slice(8,12)}-${_.slice(12,16)}-${_.slice(16,20)}-${_.slice(20)}`}else throw new Error("Crypto API not available for secure random UUID generation");let m=window.location.protocol==="https:"?"; Secure":"";document.cookie=`${this.rudderstack_anonymous_cookie_key}=${p}; path=/; Domain=${l}; max-age=${Z}; SameSite=Lax${m}`}catch(e){console.warn("RudderStack: Failed to set anonymous ID cookie",e)}};this.getUserId=()=>this.analytics.getUserId();this.init=i=>{if(!i){console.warn("RudderStack: Initialization skipped - no key provided");return}this.log("init | loading SDK",{dataplane:V});try{this.setCookieIfNotExists(),this.analytics.load(i,V,{externalAnonymousIdCookieName:this.rudderstack_anonymous_cookie_key,storage:{type:"localStorage"},lockIntegrationsVersion:!0,onLoaded:()=>{this.has_initialized=!0,this.has_identified=!!this.getUserId(),this.log("init | SDK loaded successfully",{userId:this.getUserId(),anonymousId:this.getAnonymousId()}),this.onLoadedCallback?.()}})}catch(e){console.error("RudderStack: Failed to initialize",e)}};this.identifyEvent=(i,e)=>{if(!this.has_initialized){console.warn("RudderStack: Cannot identify - not initialized");return}let r=this.getUserId();if(!r||r!==i)try{this.log("identifyEvent | identifying user",{user_id:i,traits:e}),this.analytics.identify(i,e||{}),this.has_identified=!0}catch(c){console.error("RudderStack: Failed to identify user",c)}else this.log("identifyEvent | user already identified",{user_id:i}),this.has_identified=!0};this.pageView=(i,e="Deriv App",r,c)=>{if(!(!this.has_initialized||i===this.current_page))try{let l={...r&&{user_id:r},...c};this.log("pageView | tracking page view",{platform:e,current_page:i,properties:l}),this.analytics.page(e,i,l),this.current_page=i}catch(l){console.error("RudderStack: Failed to track page view",l)}};this.reset=()=>{if(this.has_initialized)try{this.log("reset | resetting RudderStack session"),this.analytics.reset(),this.has_identified=!1}catch(i){console.error("RudderStack: Failed to reset",i)}};this.track=(i,e)=>{if(this.has_initialized)try{this.log("track | sending event to RudderStack",{event:i,payload:e}),this.analytics.track(i,e)}catch(r){console.warn("RudderStack: Failed to track event",r)}};this.onLoadedCallback=e,this.debug=r,this.init(i)}};v.getRudderStackInstance=(i,e,r=!1)=>(v._instance||(v._instance=new v(i,e,r)),v._instance);var P=v;var C="cached_analytics_events",x="cached_analytics_page_views",$=(d,i)=>{try{let e=localStorage.getItem(C),r=e?JSON.parse(e):[];r.push({name:d,properties:i,timestamp:Date.now()}),localStorage.setItem(C,JSON.stringify(r))}catch(e){console.warn("Analytics: Failed to cache event",e)}},L=(d,i)=>{try{let e=localStorage.getItem(x),r=e?JSON.parse(e):[];r.push({name:d,properties:i,timestamp:Date.now()}),localStorage.setItem(x,JSON.stringify(r))}catch(e){console.warn("Analytics: Failed to cache page view",e)}},N=()=>{try{let d=localStorage.getItem(C);if(d){let i=JSON.parse(d);return Array.isArray(i)?i:[]}}catch(d){console.warn("Analytics: Failed to get cached events",d)}return[]},H=()=>{try{let d=localStorage.getItem(x);if(d){let i=JSON.parse(d);return Array.isArray(i)?i:[]}}catch(d){console.warn("Analytics: Failed to get cached pages",d)}return[]},j=()=>{try{localStorage.removeItem(C)}catch(d){console.warn("Analytics: Failed to clear cached events",d)}},J=()=>{try{localStorage.removeItem(x)}catch(d){console.warn("Analytics: Failed to clear cached page views",d)}};function Y(d){let i=d?.debug??!1,e=R("",()=>i),r,c,l,p={},I={},m=[],g=[],_=!1,z=()=>{if(!_&&c?.has_initialized){_=!0;try{let t=N();t.length>0&&(e(`processStorageCache | replaying ${t.length} cached event(s)`,t),t.forEach(s=>{let a=A(s.properties);c?.track(s.name,a)}),j());let n=H();n.length>0&&(e(`processStorageCache | replaying ${n.length} cached page view(s)`,n),n.forEach(s=>{c?.pageView(s.name,"Deriv App",w(),s.properties)}),J())}catch(t){console.warn("Analytics: Failed to process storage cache",t)}}},B=()=>{e("onSdkLoaded | RudderStack SDK loaded"),z(),g.length>0&&e(`onSdkLoaded | flushing ${g.length} pending identify call(s)`),g.forEach(({userId:t,traits:n})=>{t&&c?.identifyEvent(t,n)}),g=[]},K=async({growthbookKey:t,growthbookDecryptionKey:n,rudderstackKey:s,growthbookOptions:a,posthogOptions:u,debug:f})=>{var h,y;f!==void 0&&(i=f),e("initialise | starting analytics initialization",{rudderstack:!!s,growthbook:!!t,posthog:!!u});try{let k=a?.attributes?.country||(t?await D():void 0);if(s&&(e("initialise | initializing RudderStack"),c=P.getRudderStackInstance(s,B,i)),a?.attributes&&Object.keys(a.attributes).length>0){let o=a.attributes,E=c?.getAnonymousId();p={...p,country:k,...o.user_language&&{user_language:o.user_language},...o.account_type&&{account_type:o.account_type},...o.app_id&&{app_id:o.app_id},...o.residence_country&&{residence_country:o.residence_country},...o.device_type&&{device_type:o.device_type},...o.url&&{url:o.url},...o.email_hash&&{email_hash:o.email_hash},...o.network_type&&{network_type:o.network_type},...o.network_rtt&&{network_rtt:o.network_rtt},...o.network_downlink&&{network_downlink:o.network_downlink},...o.account_currency&&{account_currency:o.account_currency},...o.account_mode&&{account_mode:o.account_mode},loggedIn:!!o.loggedIn,...o.user_id&&!b(o.user_id)&&{user_id:o.user_id},...E&&{anonymous_id:E}}}a??(a={}),a.attributes??(a.attributes={});let S=c?.getAnonymousId();if((h=a.attributes).id??(h.id=S),(y=a.attributes).country??(y.country=k),t){e("initialise | initializing GrowthBook");let{Growthbook:o}=await import("../growthbook-T47IBUAJ.mjs");r=o.getGrowthBookInstance(t,n,a,i),e("initialise | GrowthBook initialized");let E=setInterval(()=>{Object.keys(I).length>0?clearInterval(E):I=T("tracking-buttons-config",{})},1e3)}if(u){e("initialise | initializing PostHog");let{Posthog:o}=await import("../posthog-VJQDUIWQ.mjs");l=o.getPosthogInstance(u,i),e("initialise | PostHog initialized")}e("initialise | analytics initialization complete")}catch(k){console.warn("Analytics: Failed to initialize",k)}},W=t=>{e("setAttributes | received attributes",t);let{user_id:n,...s}=t,a=n??w();if(r){let u={...s};n&&!b(n)&&(u.user_id=n),a&&(u.id=a,u.user_id=a),e("setAttributes | called GrowthBook setAttributes",u),r.setAttributes(u)}p={...p,...Object.fromEntries(Object.entries(s).filter(([,u])=>u!==void 0)),...n!==void 0&&!b(n)&&{user_id:n}},e("setAttributes | updated core_data",p)},q=t=>r?.getFeatureState(t)?.experimentResult?.name,T=(t,n)=>r?.getFeatureValue(t,n),M=async()=>await r?.getStatus(),X=t=>r?.isOn(t),Q=t=>r?.setUrl(t),w=()=>{let t=c?.getUserId()||"";return t&&!b(t)?t:""},F={initialise:K,setAttributes:W,identifyEvent:(t,n)=>{let s=t||w();if(!s){e("identifyEvent | skipped \u2014 no user_id available");return}e("identifyEvent | called",{user_id:s,traits:n});let a=y=>{if(!y)return y;let{email:k,...S}=y;return{...S,...k&&{is_internal:U(k)}}},u=n?.rudderstack!==void 0||n?.posthog!==void 0,f,h;if(u){let{rudderstack:y,posthog:k,...S}=n;f=a({...S,...y}),h=a({...S,...k})}else f=a(n),h=a(n);c&&(c.has_initialized?(e("identifyEvent | calling RudderStack identify",{user_id:s,traits:f}),c.identifyEvent(s,f)):g.some(y=>y.userId===s)||(e("identifyEvent | RudderStack not initialized \u2014 queuing identify call",{user_id:s}),g.push({userId:s,traits:f}))),l?.has_initialized&&(e("identifyEvent | calling PostHog identify",{user_id:s,traits:h}),l.identifyEvent(s,h))},backfillPersonProperties:({user_id:t,email:n,language:s,country_of_residence:a})=>{e("backfillPersonProperties | called",{user_id:t}),l?.has_initialized?(e("backfillPersonProperties | backfilling person properties in PostHog",{user_id:t}),l.backfillPersonProperties({user_id:t,email:n,language:s,country_of_residence:a})):e("backfillPersonProperties | skipped \u2014 PostHog not initialized")},getFeatureState:q,getFeatureValue:T,getGrowthbookStatus:M,isFeatureOn:X,setUrl:Q,getId:w,getAnonymousId:()=>c?.getAnonymousId()||"",trackEvent:(t,n)=>{let s=w();e("trackEvent | called",{event:t,analytics_data:n,userId:s,core_data:p});let a={...p,...n,...s&&!p.user_id&&{user_id:s}};if(e("trackEvent | built payload",{event:t,final_payload:a}),!(!(t in I)||I[t])){e("trackEvent | skipped \u2014 event disabled by tracking_config",{event:t});return}let f=c?.has_initialized;if(!navigator.onLine||!f)f?(e("trackEvent | offline \u2014 caching event to memory",{event:t}),m.push({event:t,payload:a})):(e("trackEvent | RudderStack not initialized \u2014 caching event to localStorage",{event:t}),$(t,a));else{m.length>0&&(e(`trackEvent | flushing ${m.length} offline cached event(s) to RudderStack`),m.forEach(y=>{let k=A(y.payload);c?.track(y.event,k)}),m=[]);let h=A(a);e("trackEvent | sending event to RudderStack",{event:t,payload:h}),c?.track(t,h)}if(l?.has_initialized){let h=A(O(a));e("trackEvent | sending event to PostHog",{event:t,payload:h}),l.capture(t,h)}},getInstances:()=>({ab:r,tracking:c,posthog:l}),pageView:(t,n="Deriv App",s)=>{let a=w();e("pageView | called",{current_page:t,platform:n,properties:s,userId:a}),c?.has_initialized?(e("pageView | sending page view to RudderStack",{current_page:t,platform:n}),c.pageView(t,n,a,s)):(e("pageView | RudderStack not initialized \u2014 caching page view to localStorage",{current_page:t}),L(t,{platform:n,...s}))},reset:()=>{e("reset | resetting all providers"),c?.has_initialized&&(e("reset | resetting RudderStack"),c.reset()),l?.has_initialized&&(e("reset | resetting PostHog"),l.reset())}};return typeof window<"u"&&(window.AnalyticsInstance=F),F}var ee=Y();export{ee as Analytics};
|
|
3
3
|
//# sourceMappingURL=analytics.esm.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/providers/rudderstack.ts","../../src/utils/storage.ts","../../src/analytics.ts"],"sourcesContent":["import { RudderAnalytics } from '@rudderstack/analytics-js'\nimport { rudderstackDataplane } from '../utils/urls'\nimport { createLogger } from '../utils/helpers'\n\n// Constants\nconst COOKIE_MAX_AGE_SECONDS = 180 * 24 * 60 * 60 // 180 days (~6 months)\n\n/**\n * RudderStack analytics wrapper with singleton pattern.\n * Handles user tracking, page views, and event analytics.\n */\nexport class RudderStack {\n analytics = new RudderAnalytics()\n has_identified = false\n has_initialized = false\n current_page = ''\n rudderstack_anonymous_cookie_key = 'rudder_anonymous_id'\n private static _instance: RudderStack\n private onLoadedCallback?: () => void\n private debug = false\n private log = createLogger('[RudderStack]', () => this.debug)\n\n constructor(RUDDERSTACK_KEY: string, onLoaded?: () => void, debug = false) {\n this.onLoadedCallback = onLoaded\n this.debug = debug\n this.init(RUDDERSTACK_KEY)\n }\n\n /**\n * Get or create the singleton instance of RudderStack\n * @param RUDDERSTACK_KEY - RudderStack write key\n * @param onLoaded - Optional callback when RudderStack is loaded\n * @param debug - Enable debug logging\n * @returns The RudderStack singleton instance\n */\n public static getRudderStackInstance = (\n RUDDERSTACK_KEY: string,\n onLoaded?: () => void,\n debug = false\n ): RudderStack => {\n if (!RudderStack._instance) {\n RudderStack._instance = new RudderStack(RUDDERSTACK_KEY, onLoaded, debug)\n }\n return RudderStack._instance\n }\n\n /**\n * Get the anonymous ID from cookies\n * @returns The anonymous ID or undefined if not found\n */\n getAnonymousId = (): string | undefined => {\n return document.cookie.match('(^|;)\\\\s*' + this.rudderstack_anonymous_cookie_key + '\\\\s*=\\\\s*([^;]+)')?.pop()\n }\n\n /**\n * Set anonymous ID cookie if it doesn't exist\n * Creates a secure cookie with proper domain and security attributes\n */\n setCookieIfNotExists = (): void => {\n const anonymous_id = this.getAnonymousId()\n\n if (!anonymous_id) {\n try {\n const hostname = window.location.hostname\n const external_domains = ['webflow.io']\n const is_external_domain = external_domains.some(domain => hostname.endsWith(domain))\n const domain_name = is_external_domain ? hostname : hostname.split('.').slice(-2).join('.')\n\n // Generate cryptographically secure UUID\n let uuid: string\n if (crypto?.randomUUID) {\n uuid = crypto.randomUUID()\n } else if (crypto?.getRandomValues) {\n // Fallback: Generate UUID v4 using crypto.getRandomValues\n const bytes = new Uint8Array(16)\n crypto.getRandomValues(bytes)\n // Set version (4) and variant bits\n bytes[6] = (bytes[6]! & 0x0f) | 0x40\n bytes[8] = (bytes[8]! & 0x3f) | 0x80\n // Convert to UUID string format\n const hex = Array.from(bytes, byte => byte.toString(16).padStart(2, '0')).join('')\n uuid = `${hex.slice(0, 8)}-${hex.slice(8, 12)}-${hex.slice(12, 16)}-${hex.slice(16, 20)}-${hex.slice(20)}`\n } else {\n // Crypto API not available - this should not happen in modern browsers\n throw new Error('Crypto API not available for secure random UUID generation')\n }\n\n const isSecure = window.location.protocol === 'https:'\n const secureFlag = isSecure ? '; Secure' : ''\n\n document.cookie = `${this.rudderstack_anonymous_cookie_key}=${uuid}; path=/; Domain=${domain_name}; max-age=${COOKIE_MAX_AGE_SECONDS}; SameSite=Lax${secureFlag}`\n } catch (error) {\n console.warn('RudderStack: Failed to set anonymous ID cookie', error)\n }\n }\n }\n\n /**\n * Get the current user ID\n * @returns The user ID, null, or undefined if not identified\n */\n getUserId = () => this.analytics.getUserId()\n\n /**\n * Initialize RudderStack with the provided key\n * @param RUDDERSTACK_KEY - RudderStack write key\n */\n init = (RUDDERSTACK_KEY: string): void => {\n if (!RUDDERSTACK_KEY) {\n console.warn('RudderStack: Initialization skipped - no key provided')\n return\n }\n\n this.log('init | loading SDK', { dataplane: rudderstackDataplane })\n\n try {\n this.setCookieIfNotExists()\n\n this.analytics.load(RUDDERSTACK_KEY, rudderstackDataplane, {\n externalAnonymousIdCookieName: this.rudderstack_anonymous_cookie_key,\n storage: { type: 'localStorage' },\n // Performance optimizations\n lockIntegrationsVersion: true,\n onLoaded: () => {\n this.has_initialized = true\n this.has_identified = !!this.getUserId()\n this.log('init | SDK loaded successfully', {\n userId: this.getUserId(),\n anonymousId: this.getAnonymousId(),\n })\n this.onLoadedCallback?.()\n },\n })\n } catch (error) {\n console.error('RudderStack: Failed to initialize', error)\n }\n }\n\n /**\n * Identify a user with RudderStack\n * Only identifies if user hasn't been identified yet\n * @param user_id - The user ID to identify\n * @param payload - Optional user traits (e.g., language, custom properties)\n */\n identifyEvent = (user_id: string, payload?: Record<string, any>): void => {\n if (!this.has_initialized) {\n console.warn('RudderStack: Cannot identify - not initialized')\n return\n }\n\n const currentUserId = this.getUserId()\n if (!currentUserId || currentUserId !== user_id) {\n try {\n this.log('identifyEvent | identifying user', { user_id, traits: payload })\n this.analytics.identify(user_id, payload || {})\n this.has_identified = true\n } catch (error) {\n console.error('RudderStack: Failed to identify user', error)\n }\n } else {\n this.log('identifyEvent | user already identified', { user_id })\n this.has_identified = true\n }\n }\n\n /**\n * Track a page view event\n * @param current_page - The page name/path\n * @param platform - The platform name (default: 'Deriv App')\n * @param user_id - The user ID\n * @param properties - Additional page properties\n */\n pageView = (\n current_page: string,\n platform = 'Deriv App',\n user_id: string,\n properties?: Record<string, unknown>\n ): void => {\n if (!this.has_initialized || current_page === this.current_page) return\n\n try {\n const pageProperties = {\n ...(user_id && { user_id }),\n ...properties,\n }\n\n this.log('pageView | tracking page view', { platform, current_page, properties: pageProperties })\n // Type assertion needed due to RudderStack's type definitions\n this.analytics.page(platform, current_page, pageProperties as any)\n this.current_page = current_page\n } catch (error) {\n console.error('RudderStack: Failed to track page view', error)\n }\n }\n\n /**\n * Reset the RudderStack instance\n * Clears user identification and resets tracking state\n */\n reset = (): void => {\n if (!this.has_initialized) return\n\n try {\n this.log('reset | resetting RudderStack session')\n this.analytics.reset()\n this.has_identified = false\n } catch (error) {\n console.error('RudderStack: Failed to reset', error)\n }\n }\n\n /**\n * Track a custom event with payload\n * Payload is pre-cleaned by analytics.ts using cleanObject before being passed here\n * @param event - The event name\n * @param payload - The event payload with core attributes\n */\n track = (event: string, payload: Record<string, any>): void => {\n if (!this.has_initialized) return\n\n try {\n this.log('track | sending event to RudderStack', { event, payload })\n // Type assertion needed to match RudderStack's ApiObject type\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n this.analytics.track(event as string, payload as any)\n } catch (err) {\n console.warn('RudderStack: Failed to track event', err)\n }\n }\n}\n","export const CACHE_STORAGE_EVENTS = 'cached_analytics_events'\nexport const CACHE_STORAGE_PAGES = 'cached_analytics_page_views'\n\nexport type CachedEvent = {\n name: string\n properties: Record<string, unknown>\n timestamp: number\n}\n\nexport type CachedPageView = {\n name: string\n properties?: Record<string, unknown>\n timestamp: number\n}\n\nexport const cacheEventToStorage = (eventName: string, properties: Record<string, unknown>): void => {\n try {\n const existingCache = localStorage.getItem(CACHE_STORAGE_EVENTS)\n const events: CachedEvent[] = existingCache ? JSON.parse(existingCache) : []\n events.push({ name: eventName, properties, timestamp: Date.now() })\n localStorage.setItem(CACHE_STORAGE_EVENTS, JSON.stringify(events))\n } catch (err) {\n console.warn('Analytics: Failed to cache event', err)\n }\n}\n\nexport const cachePageViewToStorage = (pageName: string, properties?: Record<string, unknown>): void => {\n try {\n const existingCache = localStorage.getItem(CACHE_STORAGE_PAGES)\n const pages: CachedPageView[] = existingCache ? JSON.parse(existingCache) : []\n pages.push({ name: pageName, properties, timestamp: Date.now() })\n localStorage.setItem(CACHE_STORAGE_PAGES, JSON.stringify(pages))\n } catch (err) {\n console.warn('Analytics: Failed to cache page view', err)\n }\n}\n\nexport const getCachedEvents = (): CachedEvent[] => {\n try {\n const storedEventsString = localStorage.getItem(CACHE_STORAGE_EVENTS)\n if (storedEventsString) {\n const events = JSON.parse(storedEventsString)\n return Array.isArray(events) ? events : []\n }\n } catch (err) {\n console.warn('Analytics: Failed to get cached events', err)\n }\n return []\n}\n\nexport const getCachedPageViews = (): CachedPageView[] => {\n try {\n const storedPagesString = localStorage.getItem(CACHE_STORAGE_PAGES)\n if (storedPagesString) {\n const pages = JSON.parse(storedPagesString)\n return Array.isArray(pages) ? pages : []\n }\n } catch (err) {\n console.warn('Analytics: Failed to get cached pages', err)\n }\n return []\n}\n\nexport const clearCachedEvents = (): void => {\n try {\n localStorage.removeItem(CACHE_STORAGE_EVENTS)\n } catch (err) {\n console.warn('Analytics: Failed to clear cached events', err)\n }\n}\n\nexport const clearCachedPageViews = (): void => {\n try {\n localStorage.removeItem(CACHE_STORAGE_PAGES)\n } catch (err) {\n console.warn('Analytics: Failed to clear cached page views', err)\n }\n}\n","import { RudderStack } from './providers/rudderstack'\nimport {\n cacheEventToStorage,\n cachePageViewToStorage,\n getCachedEvents,\n getCachedPageViews,\n clearCachedEvents,\n clearCachedPageViews,\n} from './utils/storage'\nimport { isUUID, getCountry, cleanObject, flattenObject, createLogger, isInternalEmail } from './utils/helpers'\n// Optional Growthbook types - only import if using Growthbook\nimport type { Growthbook, GrowthbookConfigs } from './providers/growthbook'\nimport type { TGrowthbookAttributes, TGrowthbookOptions } from './providers/growthbookTypes'\n\n// Optional Posthog types - only import if using Posthog\nimport type { Posthog } from './providers/posthog'\nimport type { TPosthogIdentifyTraits, TPosthogOptions } from './providers/posthogTypes'\n\ndeclare global {\n interface Window {\n AnalyticsInstance: ReturnType<typeof createAnalyticsInstance>\n }\n}\n\n/**\n * Configuration options for initializing the analytics instance\n */\ntype Options = {\n /** GrowthBook client API key for A/B testing and feature flags */\n growthbookKey?: string\n /** GrowthBook decryption key for encrypted feature payloads */\n growthbookDecryptionKey?: string\n /** RudderStack write key for event tracking */\n rudderstackKey?: string\n /** Additional configuration options for GrowthBook */\n growthbookOptions?: TGrowthbookOptions\n /** PostHog configuration options including API keys and settings */\n posthogOptions?: TPosthogOptions\n /** Enable debug logging — logs all analytics calls prefixed with [ANALYTIC] */\n debug?: boolean\n}\n\n/**\n * Creates a unified analytics instance that integrates RudderStack and GrowthBook.\n *\n * This function provides a centralized interface for:\n * - Event tracking across multiple analytics platforms\n * - A/B testing and feature flag management via GrowthBook\n * - Offline event caching with automatic replay\n *\n * @param {Options} _options - Optional initialization configuration\n * @returns {Object} Analytics instance with methods for tracking, identification, and feature management\n *\n * @example\n * ```typescript\n * const analytics = createAnalyticsInstance();\n *\n * // Initialize with providers\n * await analytics.initialise({\n * rudderstackKey: 'YOUR_RS_KEY',\n * growthbookKey: 'YOUR_GB_KEY',\n * growthbookDecryptionKey: 'YOUR_GB_DECRYPT_KEY'\n * });\n *\n * // Set user attributes\n * analytics.setAttributes({\n * user_id: 'user123',\n * country: 'US',\n * user_language: 'en'\n * });\n *\n * // Track events\n * analytics.trackEvent('button_clicked', { button_name: 'signup' });\n *\n * // Track page views\n * analytics.pageView('/dashboard', 'Deriv App');\n * ```\n */\nexport function createAnalyticsInstance(_options?: Options) {\n let _debug = _options?.debug ?? false\n\n const log = createLogger('', () => _debug)\n\n let _growthbook: Growthbook | undefined,\n _rudderstack: RudderStack,\n _posthog: Posthog | undefined,\n core_data: Record<string, any> = {},\n tracking_config: { [key: string]: boolean } = {},\n offline_event_cache: Array<{ event: string; payload: Record<string, any> }> = [],\n _pending_identify_calls: Array<{ userId: string; traits?: Record<string, any> }> = [],\n _storage_cache_processed = false\n\n const processStorageCache = () => {\n if (_storage_cache_processed) return\n if (!_rudderstack?.has_initialized) return\n\n _storage_cache_processed = true\n\n try {\n const storedEvents = getCachedEvents()\n if (storedEvents.length > 0) {\n log(`processStorageCache | replaying ${storedEvents.length} cached event(s)`, storedEvents)\n storedEvents.forEach(event => {\n const cleaned_properties = cleanObject(event.properties)\n _rudderstack?.track(event.name, cleaned_properties)\n })\n clearCachedEvents()\n }\n\n const storedPages = getCachedPageViews()\n if (storedPages.length > 0) {\n log(`processStorageCache | replaying ${storedPages.length} cached page view(s)`, storedPages)\n storedPages.forEach(page => {\n _rudderstack?.pageView(page.name, 'Deriv App', getId(), page.properties)\n })\n clearCachedPageViews()\n }\n } catch (err) {\n console.warn('Analytics: Failed to process storage cache', err)\n }\n }\n\n const onSdkLoaded = () => {\n log('onSdkLoaded | RudderStack SDK loaded')\n processStorageCache()\n\n if (_pending_identify_calls.length > 0) {\n log(`onSdkLoaded | flushing ${_pending_identify_calls.length} pending identify call(s)`)\n }\n _pending_identify_calls.forEach(({ userId, traits }) => {\n if (userId) {\n _rudderstack?.identifyEvent(userId, traits)\n }\n })\n _pending_identify_calls = []\n }\n\n /**\n * Initializes the analytics instance with specified provider configurations.\n * This method should be called before tracking any events.\n *\n * Features:\n * - Lazy-loads providers (GrowthBook, PostHog) only when configured\n * - Automatically fetches user's country for GrowthBook targeting\n * - Processes any cached events from previous sessions\n * - Sets up event tracking callback for GrowthBook experiments\n *\n * @param {Options} options - Configuration options for analytics providers\n * @returns {Promise<void>} Resolves when initialization is complete\n *\n * @example\n * ```typescript\n * await analytics.initialise({\n * rudderstackKey: 'YOUR_RS_KEY',\n * growthbookKey: 'YOUR_GB_KEY',\n * growthbookDecryptionKey: 'YOUR_GB_DECRYPT_KEY',\n * posthogOptions: {\n * apiKey: 'YOUR_POSTHOG_API_KEY',\n * config: {\n * session_recording: {\n * recordCrossOriginIframes: true,\n * minimumDurationMilliseconds: 30000\n * }\n * }\n * }\n * });\n * ```\n */\n const initialise = async ({\n growthbookKey,\n growthbookDecryptionKey,\n rudderstackKey,\n growthbookOptions,\n posthogOptions,\n debug,\n }: Options) => {\n if (debug !== undefined) _debug = debug\n\n log('initialise | starting analytics initialization', {\n rudderstack: !!rudderstackKey,\n growthbook: !!growthbookKey,\n posthog: !!posthogOptions,\n })\n\n try {\n // Only fetch country if GrowthBook is enabled and country not provided\n const country = growthbookOptions?.attributes?.country || (growthbookKey ? await getCountry() : undefined)\n\n if (rudderstackKey) {\n log('initialise | initializing RudderStack')\n _rudderstack = RudderStack.getRudderStackInstance(rudderstackKey, onSdkLoaded, _debug)\n }\n\n if (growthbookOptions?.attributes && Object.keys(growthbookOptions.attributes).length > 0) {\n const attrs = growthbookOptions.attributes\n const anonymousId = _rudderstack?.getAnonymousId()\n\n core_data = {\n ...core_data,\n country,\n ...(attrs.user_language && { user_language: attrs.user_language }),\n ...(attrs.account_type && { account_type: attrs.account_type }),\n ...(attrs.app_id && { app_id: attrs.app_id }),\n ...(attrs.residence_country && { residence_country: attrs.residence_country }),\n ...(attrs.device_type && { device_type: attrs.device_type }),\n ...(attrs.url && { url: attrs.url }),\n ...(attrs.email_hash && { email_hash: attrs.email_hash }),\n ...(attrs.network_type && { network_type: attrs.network_type }),\n ...(attrs.network_rtt && { network_rtt: attrs.network_rtt }),\n ...(attrs.network_downlink && { network_downlink: attrs.network_downlink }),\n ...(attrs.account_currency && { account_currency: attrs.account_currency }),\n ...(attrs.account_mode && { account_mode: attrs.account_mode }),\n loggedIn: !!attrs.loggedIn,\n ...(attrs.user_id && !isUUID(attrs.user_id) && { user_id: attrs.user_id }),\n ...(anonymousId && { anonymous_id: anonymousId }),\n }\n }\n\n growthbookOptions ??= {}\n growthbookOptions.attributes ??= {}\n const anonId = _rudderstack?.getAnonymousId()\n growthbookOptions.attributes.id ??= anonId\n growthbookOptions.attributes.country ??= country\n\n if (growthbookKey) {\n log('initialise | initializing GrowthBook')\n // Dynamically import Growthbook only when needed\n const { Growthbook } = await import('./providers/growthbook')\n _growthbook = Growthbook.getGrowthBookInstance(\n growthbookKey,\n growthbookDecryptionKey,\n growthbookOptions,\n _debug\n )\n log('initialise | GrowthBook initialized')\n\n const interval = setInterval(() => {\n if (Object.keys(tracking_config).length > 0) clearInterval(interval)\n else tracking_config = getFeatureValue('tracking-buttons-config', {}) as { [key: string]: boolean }\n }, 1000)\n }\n\n if (posthogOptions) {\n log('initialise | initializing PostHog')\n // Dynamically import Posthog only when needed\n const { Posthog } = await import('./providers/posthog')\n _posthog = Posthog.getPosthogInstance(posthogOptions, _debug)\n log('initialise | PostHog initialized')\n }\n\n log('initialise | analytics initialization complete')\n } catch (err) {\n console.warn('Analytics: Failed to initialize', err)\n }\n }\n\n /**\n * Sets user and context attributes for analytics tracking and targeting.\n * These attributes are automatically included in all subsequent events.\n *\n * Attributes are used for:\n * - Event enrichment (added to all tracked events)\n * - GrowthBook targeting (feature flags and A/B tests)\n * - User segmentation across analytics platforms\n *\n * @param {TCoreAttributes} attributes - User and context attributes\n *\n * @example\n * ```typescript\n * analytics.setAttributes({\n * user_id: 'CR123456',\n * country: 'US',\n * user_language: 'en',\n * device_type: 'desktop',\n * account_type: 'real',\n * loggedIn: true\n * });\n * ```\n */\n const setAttributes = (attributes: Record<string, any>) => {\n log('setAttributes | received attributes', attributes)\n\n const { user_id, ...rest } = attributes\n const user_identity = user_id ?? getId()\n\n if (_growthbook) {\n const config: TGrowthbookAttributes = { ...rest }\n if (user_id && !isUUID(user_id)) config.user_id = user_id\n if (user_identity) {\n config.id = user_identity\n config.user_id = user_identity\n }\n log('setAttributes | called GrowthBook setAttributes', config)\n _growthbook.setAttributes(config)\n }\n\n core_data = {\n ...core_data,\n ...Object.fromEntries(Object.entries(rest).filter(([, v]) => v !== undefined)),\n ...(user_id !== undefined && !isUUID(user_id) && { user_id }),\n }\n\n log('setAttributes | updated core_data', core_data)\n }\n\n const getFeatureState = (id: string) => _growthbook?.getFeatureState(id)?.experimentResult?.name\n\n const getFeatureValue = <K extends keyof GrowthbookConfigs, V extends GrowthbookConfigs[K]>(\n id: K,\n defaultValue: V\n ) => _growthbook?.getFeatureValue(id as string, defaultValue)\n\n const getGrowthbookStatus = async () => await _growthbook?.getStatus()\n const isFeatureOn = (key: string) => _growthbook?.isOn(key)\n const setUrl = (href: string) => _growthbook?.setUrl(href)\n\n const getId = () => {\n const userId = _rudderstack?.getUserId() || ''\n return userId && !isUUID(userId) ? userId : ''\n }\n\n const getAnonymousId = () => _rudderstack?.getAnonymousId() || ''\n\n /**\n * Tracks a page view event.\n *\n * Features:\n * - Automatically includes user ID if available\n * - Caches page views when offline or provider not initialized\n *\n * @param {string} current_page - The current page URL or path\n * @param {string} [platform='Deriv App'] - The platform name\n * @param {Record<string, unknown>} [properties] - Additional page properties\n *\n * @example\n * ```typescript\n * analytics.pageView('/dashboard');\n * analytics.pageView('/trade', 'Deriv Trader', { section: 'multipliers' });\n * ```\n */\n const pageView = (current_page: string, platform = 'Deriv App', properties?: Record<string, unknown>) => {\n const userId = getId()\n\n log('pageView | called', { current_page, platform, properties, userId })\n\n // Handle RudderStack pageView independently\n if (_rudderstack?.has_initialized) {\n log('pageView | sending page view to RudderStack', { current_page, platform })\n _rudderstack.pageView(current_page, platform, userId, properties)\n } else {\n log('pageView | RudderStack not initialized — caching page view to localStorage', { current_page })\n cachePageViewToStorage(current_page, { platform, ...properties })\n }\n\n // PostHog handles page views automatically via autocapture\n // No need to manually send page views to PostHog\n }\n\n /**\n * Identifies a user across analytics platforms.\n * This method should be called after user login or when user identity is known.\n *\n * Features:\n * - Queues identify calls if provider not yet initialized\n * - Allows custom traits for each provider or shared traits for both\n * - Identifies user in PostHog if configured\n *\n * @param {string} [user_id] - The user ID to identify. If not provided, uses stored user ID\n * @param {Record<string, any>} [traits] - Optional traits to send to both providers, or provider-specific traits\n *\n * @example\n * ```typescript\n * // Simple identify\n * analytics.identifyEvent('CR123456');\n *\n * // Identify with same traits for both providers\n * analytics.identifyEvent('CR123456', {\n * language: 'en',\n * country_of_residence: 'US'\n * });\n *\n * // Identify with provider-specific traits\n * analytics.identifyEvent('CR123456', {\n * rudderstack: { language: 'en', custom_field: 'value' },\n * posthog: { language: 'en', country_of_residence: 'US' }\n * });\n * ```\n */\n const identifyEvent = (user_id?: string, traits?: Record<string, any>) => {\n const stored_user_id = user_id || getId()\n if (!stored_user_id) {\n log('identifyEvent | skipped — no user_id available')\n return\n }\n\n log('identifyEvent | called', { user_id: stored_user_id, traits })\n\n // Strip PII: replace raw email with is_internal flag\n const sanitizePII = (t?: Record<string, any>) => {\n if (!t) return t\n const { email, ...safe } = t\n return { ...safe, ...(email && { is_internal: isInternalEmail(email) }) }\n }\n\n // Check if traits has provider-specific structure\n const hasProviderStructure = traits?.rudderstack !== undefined || traits?.posthog !== undefined\n let rudderstackTraits, posthogTraits\n if (hasProviderStructure) {\n // Merge shared top-level props with provider-specific ones (provider-specific wins on conflict)\n const { rudderstack, posthog, ...sharedTraits } = traits as any\n rudderstackTraits = sanitizePII({ ...sharedTraits, ...rudderstack })\n posthogTraits = sanitizePII({ ...sharedTraits, ...posthog })\n } else {\n rudderstackTraits = sanitizePII(traits)\n posthogTraits = sanitizePII(traits)\n }\n\n // Handle RudderStack identification independently\n if (_rudderstack) {\n if (_rudderstack.has_initialized) {\n log('identifyEvent | calling RudderStack identify', {\n user_id: stored_user_id,\n traits: rudderstackTraits,\n })\n _rudderstack.identifyEvent(stored_user_id, rudderstackTraits)\n } else {\n if (!_pending_identify_calls.some(call => call.userId === stored_user_id)) {\n log('identifyEvent | RudderStack not initialized — queuing identify call', {\n user_id: stored_user_id,\n })\n _pending_identify_calls.push({ userId: stored_user_id, traits: rudderstackTraits })\n }\n }\n }\n\n // Handle PostHog identification independently\n if (_posthog?.has_initialized && posthogTraits) {\n log('identifyEvent | calling PostHog identify', { user_id: stored_user_id, traits: posthogTraits })\n _posthog.identifyEvent(stored_user_id, posthogTraits as TPosthogIdentifyTraits)\n }\n }\n\n const reset = () => {\n log('reset | resetting all providers')\n // Reset each provider independently\n if (_rudderstack?.has_initialized) {\n log('reset | resetting RudderStack')\n _rudderstack.reset()\n }\n if (_posthog?.has_initialized) {\n log('reset | resetting PostHog')\n _posthog.reset()\n }\n }\n\n /**\n * Tracks a custom event with associated data.\n *\n * Features:\n * - Automatically enriches events with core attributes\n * - RudderStack: Caches events when offline or not initialized\n * - PostHog: Sends immediately if initialized (has built-in caching)\n * - Respects feature flag configurations\n * - Each provider works independently - one failing won't affect the other\n *\n * @param {string} event - The event name to track\n * @param {Record<string, any>} analytics_data - The event data payload\n */\n const trackEvent = (event: string, analytics_data: Record<string, any>) => {\n const userId = getId()\n\n log('trackEvent | called', { event, analytics_data, userId, core_data })\n\n const final_payload = {\n ...core_data,\n ...analytics_data,\n ...(userId && !core_data.user_id && { user_id: userId }),\n }\n\n log('trackEvent | built payload', { event, final_payload })\n\n const shouldTrack = !(event in tracking_config) || tracking_config[event as string]\n if (!shouldTrack) {\n log('trackEvent | skipped — event disabled by tracking_config', { event })\n return\n }\n\n // Handle RudderStack independently\n const hasRudderstackInitialized = _rudderstack?.has_initialized\n if (!navigator.onLine || !hasRudderstackInitialized) {\n if (!hasRudderstackInitialized) {\n log('trackEvent | RudderStack not initialized — caching event to localStorage', { event })\n cacheEventToStorage(event as string, final_payload)\n } else {\n log('trackEvent | offline — caching event to memory', { event })\n offline_event_cache.push({ event, payload: final_payload })\n }\n } else {\n // Send cached events to RudderStack\n if (offline_event_cache.length > 0) {\n log(`trackEvent | flushing ${offline_event_cache.length} offline cached event(s) to RudderStack`)\n offline_event_cache.forEach(cache => {\n const cleaned_cache_payload = cleanObject(cache.payload)\n _rudderstack?.track(cache.event, cleaned_cache_payload)\n })\n offline_event_cache = []\n }\n\n // Send current event to RudderStack\n const cleaned_payload = cleanObject(final_payload)\n log('trackEvent | sending event to RudderStack', { event, payload: cleaned_payload })\n _rudderstack?.track(event, cleaned_payload)\n }\n\n // Handle PostHog independently - send immediately if initialized\n if (_posthog?.has_initialized) {\n const posthog_excluded_keys = ['page_name', 'user_language', 'form_name', 'version', 'email_hash'] as const\n const flattened_payload = flattenObject(final_payload)\n const posthog_payload = cleanObject(\n Object.fromEntries(\n Object.entries(flattened_payload).filter(([key]) => !posthog_excluded_keys.includes(key as any))\n )\n )\n log('trackEvent | sending event to PostHog', { event, payload: posthog_payload })\n _posthog.capture(event as string, posthog_payload)\n }\n }\n\n /**\n * Ensures client_id is set in PostHog stored person properties.\n * Call this when the user ID is available and PostHog is loaded.\n * Useful for backfilling client_id for users identified in previous sessions.\n * No-op if client_id is already present or PostHog is not initialized.\n *\n * @param params.user_id - The user ID to use as client_id\n * @param params.email - The user's email, used to determine is_internal\n * @param params.language - The user's language (BCP 47 tag, e.g. \"en-GB\")\n * @param params.country_of_residence - The user's country of residence\n *\n * @example\n * ```typescript\n * if (window.posthog?.__loaded && userId) {\n * analytics.backfillPersonProperties({ user_id: userId, email, language, country_of_residence })\n * }\n * ```\n */\n const backfillPersonProperties = ({\n user_id,\n email,\n language,\n country_of_residence,\n }: {\n user_id: string\n email?: string\n language?: string\n country_of_residence?: string\n }): void => {\n log('backfillPersonProperties | called', { user_id })\n if (_posthog?.has_initialized) {\n log('backfillPersonProperties | backfilling person properties in PostHog', { user_id })\n _posthog.backfillPersonProperties({ user_id, email, language, country_of_residence })\n } else {\n log('backfillPersonProperties | skipped — PostHog not initialized')\n }\n }\n\n const getInstances = () => ({ ab: _growthbook, tracking: _rudderstack, posthog: _posthog })\n\n const AnalyticsInstance = {\n initialise,\n setAttributes,\n identifyEvent,\n backfillPersonProperties,\n getFeatureState,\n getFeatureValue,\n getGrowthbookStatus,\n isFeatureOn,\n setUrl,\n getId,\n getAnonymousId,\n trackEvent,\n getInstances,\n pageView,\n reset,\n }\n\n if (typeof window !== 'undefined') {\n window.AnalyticsInstance = AnalyticsInstance\n }\n\n return AnalyticsInstance\n}\n\nexport const Analytics = createAnalyticsInstance()\n"],"mappings":"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","names":["COOKIE_MAX_AGE_SECONDS","_RudderStack","RUDDERSTACK_KEY","onLoaded","debug","RudderAnalytics","createLogger","hostname","domain_name","domain","uuid","bytes","hex","byte","secureFlag","error","rudderstackDataplane","user_id","payload","currentUserId","current_page","platform","properties","pageProperties","event","err","RudderStack","CACHE_STORAGE_EVENTS","CACHE_STORAGE_PAGES","cacheEventToStorage","eventName","properties","existingCache","events","err","cachePageViewToStorage","pageName","pages","getCachedEvents","storedEventsString","getCachedPageViews","storedPagesString","clearCachedEvents","clearCachedPageViews","createAnalyticsInstance","_options","_debug","log","createLogger","_growthbook","_rudderstack","_posthog","core_data","tracking_config","offline_event_cache","_pending_identify_calls","_storage_cache_processed","processStorageCache","storedEvents","getCachedEvents","event","cleaned_properties","cleanObject","clearCachedEvents","storedPages","getCachedPageViews","page","getId","clearCachedPageViews","err","onSdkLoaded","userId","traits","initialise","growthbookKey","growthbookDecryptionKey","rudderstackKey","growthbookOptions","posthogOptions","debug","_a","_b","country","getCountry","RudderStack","attrs","anonymousId","isUUID","anonId","Growthbook","interval","getFeatureValue","Posthog","setAttributes","attributes","user_id","rest","user_identity","config","v","getFeatureState","id","defaultValue","getGrowthbookStatus","isFeatureOn","key","setUrl","href","AnalyticsInstance","stored_user_id","sanitizePII","t","email","safe","isInternalEmail","hasProviderStructure","rudderstackTraits","posthogTraits","rudderstack","posthog","sharedTraits","call","language","country_of_residence","analytics_data","final_payload","hasRudderstackInitialized","cacheEventToStorage","cache","cleaned_cache_payload","cleaned_payload","posthog_excluded_keys","flattened_payload","flattenObject","posthog_payload","current_page","platform","properties","cachePageViewToStorage","Analytics"]}
|
|
1
|
+
{"version":3,"sources":["../../src/providers/rudderstack.ts","../../src/utils/storage.ts","../../src/analytics.ts"],"sourcesContent":["import { RudderAnalytics } from '@rudderstack/analytics-js'\nimport { rudderstackDataplane } from '../utils/urls'\nimport { createLogger } from '../utils/helpers'\n\n// Constants\nconst COOKIE_MAX_AGE_SECONDS = 180 * 24 * 60 * 60 // 180 days (~6 months)\n\n/**\n * RudderStack analytics wrapper with singleton pattern.\n * Handles user tracking, page views, and event analytics.\n */\nexport class RudderStack {\n analytics = new RudderAnalytics()\n has_identified = false\n has_initialized = false\n current_page = ''\n rudderstack_anonymous_cookie_key = 'rudder_anonymous_id'\n private static _instance: RudderStack\n private onLoadedCallback?: () => void\n private debug = false\n private log = createLogger('[RudderStack]', () => this.debug)\n\n constructor(RUDDERSTACK_KEY: string, onLoaded?: () => void, debug = false) {\n this.onLoadedCallback = onLoaded\n this.debug = debug\n this.init(RUDDERSTACK_KEY)\n }\n\n /**\n * Get or create the singleton instance of RudderStack\n * @param RUDDERSTACK_KEY - RudderStack write key\n * @param onLoaded - Optional callback when RudderStack is loaded\n * @param debug - Enable debug logging\n * @returns The RudderStack singleton instance\n */\n public static getRudderStackInstance = (\n RUDDERSTACK_KEY: string,\n onLoaded?: () => void,\n debug = false\n ): RudderStack => {\n if (!RudderStack._instance) {\n RudderStack._instance = new RudderStack(RUDDERSTACK_KEY, onLoaded, debug)\n }\n return RudderStack._instance\n }\n\n /**\n * Get the anonymous ID from cookies\n * @returns The anonymous ID or undefined if not found\n */\n getAnonymousId = (): string | undefined => {\n return document.cookie.match('(^|;)\\\\s*' + this.rudderstack_anonymous_cookie_key + '\\\\s*=\\\\s*([^;]+)')?.pop()\n }\n\n /**\n * Set anonymous ID cookie if it doesn't exist\n * Creates a secure cookie with proper domain and security attributes\n */\n setCookieIfNotExists = (): void => {\n const anonymous_id = this.getAnonymousId()\n\n if (!anonymous_id) {\n try {\n const hostname = window.location.hostname\n const external_domains = ['webflow.io']\n const is_external_domain = external_domains.some(domain => hostname.endsWith(domain))\n const domain_name = is_external_domain ? hostname : hostname.split('.').slice(-2).join('.')\n\n // Generate cryptographically secure UUID\n let uuid: string\n if (crypto?.randomUUID) {\n uuid = crypto.randomUUID()\n } else if (crypto?.getRandomValues) {\n // Fallback: Generate UUID v4 using crypto.getRandomValues\n const bytes = new Uint8Array(16)\n crypto.getRandomValues(bytes)\n // Set version (4) and variant bits\n bytes[6] = (bytes[6]! & 0x0f) | 0x40\n bytes[8] = (bytes[8]! & 0x3f) | 0x80\n // Convert to UUID string format\n const hex = Array.from(bytes, byte => byte.toString(16).padStart(2, '0')).join('')\n uuid = `${hex.slice(0, 8)}-${hex.slice(8, 12)}-${hex.slice(12, 16)}-${hex.slice(16, 20)}-${hex.slice(20)}`\n } else {\n // Crypto API not available - this should not happen in modern browsers\n throw new Error('Crypto API not available for secure random UUID generation')\n }\n\n const isSecure = window.location.protocol === 'https:'\n const secureFlag = isSecure ? '; Secure' : ''\n\n document.cookie = `${this.rudderstack_anonymous_cookie_key}=${uuid}; path=/; Domain=${domain_name}; max-age=${COOKIE_MAX_AGE_SECONDS}; SameSite=Lax${secureFlag}`\n } catch (error) {\n console.warn('RudderStack: Failed to set anonymous ID cookie', error)\n }\n }\n }\n\n /**\n * Get the current user ID\n * @returns The user ID, null, or undefined if not identified\n */\n getUserId = () => this.analytics.getUserId()\n\n /**\n * Initialize RudderStack with the provided key\n * @param RUDDERSTACK_KEY - RudderStack write key\n */\n init = (RUDDERSTACK_KEY: string): void => {\n if (!RUDDERSTACK_KEY) {\n console.warn('RudderStack: Initialization skipped - no key provided')\n return\n }\n\n this.log('init | loading SDK', { dataplane: rudderstackDataplane })\n\n try {\n this.setCookieIfNotExists()\n\n this.analytics.load(RUDDERSTACK_KEY, rudderstackDataplane, {\n externalAnonymousIdCookieName: this.rudderstack_anonymous_cookie_key,\n storage: { type: 'localStorage' },\n // Performance optimizations\n lockIntegrationsVersion: true,\n onLoaded: () => {\n this.has_initialized = true\n this.has_identified = !!this.getUserId()\n this.log('init | SDK loaded successfully', {\n userId: this.getUserId(),\n anonymousId: this.getAnonymousId(),\n })\n this.onLoadedCallback?.()\n },\n })\n } catch (error) {\n console.error('RudderStack: Failed to initialize', error)\n }\n }\n\n /**\n * Identify a user with RudderStack\n * Only identifies if user hasn't been identified yet\n * @param user_id - The user ID to identify\n * @param payload - Optional user traits (e.g., language, custom properties)\n */\n identifyEvent = (user_id: string, payload?: Record<string, any>): void => {\n if (!this.has_initialized) {\n console.warn('RudderStack: Cannot identify - not initialized')\n return\n }\n\n const currentUserId = this.getUserId()\n if (!currentUserId || currentUserId !== user_id) {\n try {\n this.log('identifyEvent | identifying user', { user_id, traits: payload })\n this.analytics.identify(user_id, payload || {})\n this.has_identified = true\n } catch (error) {\n console.error('RudderStack: Failed to identify user', error)\n }\n } else {\n this.log('identifyEvent | user already identified', { user_id })\n this.has_identified = true\n }\n }\n\n /**\n * Track a page view event\n * @param current_page - The page name/path\n * @param platform - The platform name (default: 'Deriv App')\n * @param user_id - The user ID\n * @param properties - Additional page properties\n */\n pageView = (\n current_page: string,\n platform = 'Deriv App',\n user_id: string,\n properties?: Record<string, unknown>\n ): void => {\n if (!this.has_initialized || current_page === this.current_page) return\n\n try {\n const pageProperties = {\n ...(user_id && { user_id }),\n ...properties,\n }\n\n this.log('pageView | tracking page view', { platform, current_page, properties: pageProperties })\n // Type assertion needed due to RudderStack's type definitions\n this.analytics.page(platform, current_page, pageProperties as any)\n this.current_page = current_page\n } catch (error) {\n console.error('RudderStack: Failed to track page view', error)\n }\n }\n\n /**\n * Reset the RudderStack instance\n * Clears user identification and resets tracking state\n */\n reset = (): void => {\n if (!this.has_initialized) return\n\n try {\n this.log('reset | resetting RudderStack session')\n this.analytics.reset()\n this.has_identified = false\n } catch (error) {\n console.error('RudderStack: Failed to reset', error)\n }\n }\n\n /**\n * Track a custom event with payload\n * Payload is pre-cleaned by analytics.ts using cleanObject before being passed here\n * @param event - The event name\n * @param payload - The event payload with core attributes\n */\n track = (event: string, payload: Record<string, any>): void => {\n if (!this.has_initialized) return\n\n try {\n this.log('track | sending event to RudderStack', { event, payload })\n // Type assertion needed to match RudderStack's ApiObject type\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n this.analytics.track(event as string, payload as any)\n } catch (err) {\n console.warn('RudderStack: Failed to track event', err)\n }\n }\n}\n","export const CACHE_STORAGE_EVENTS = 'cached_analytics_events'\nexport const CACHE_STORAGE_PAGES = 'cached_analytics_page_views'\n\nexport type CachedEvent = {\n name: string\n properties: Record<string, unknown>\n timestamp: number\n}\n\nexport type CachedPageView = {\n name: string\n properties?: Record<string, unknown>\n timestamp: number\n}\n\nexport const cacheEventToStorage = (eventName: string, properties: Record<string, unknown>): void => {\n try {\n const existingCache = localStorage.getItem(CACHE_STORAGE_EVENTS)\n const events: CachedEvent[] = existingCache ? JSON.parse(existingCache) : []\n events.push({ name: eventName, properties, timestamp: Date.now() })\n localStorage.setItem(CACHE_STORAGE_EVENTS, JSON.stringify(events))\n } catch (err) {\n console.warn('Analytics: Failed to cache event', err)\n }\n}\n\nexport const cachePageViewToStorage = (pageName: string, properties?: Record<string, unknown>): void => {\n try {\n const existingCache = localStorage.getItem(CACHE_STORAGE_PAGES)\n const pages: CachedPageView[] = existingCache ? JSON.parse(existingCache) : []\n pages.push({ name: pageName, properties, timestamp: Date.now() })\n localStorage.setItem(CACHE_STORAGE_PAGES, JSON.stringify(pages))\n } catch (err) {\n console.warn('Analytics: Failed to cache page view', err)\n }\n}\n\nexport const getCachedEvents = (): CachedEvent[] => {\n try {\n const storedEventsString = localStorage.getItem(CACHE_STORAGE_EVENTS)\n if (storedEventsString) {\n const events = JSON.parse(storedEventsString)\n return Array.isArray(events) ? events : []\n }\n } catch (err) {\n console.warn('Analytics: Failed to get cached events', err)\n }\n return []\n}\n\nexport const getCachedPageViews = (): CachedPageView[] => {\n try {\n const storedPagesString = localStorage.getItem(CACHE_STORAGE_PAGES)\n if (storedPagesString) {\n const pages = JSON.parse(storedPagesString)\n return Array.isArray(pages) ? pages : []\n }\n } catch (err) {\n console.warn('Analytics: Failed to get cached pages', err)\n }\n return []\n}\n\nexport const clearCachedEvents = (): void => {\n try {\n localStorage.removeItem(CACHE_STORAGE_EVENTS)\n } catch (err) {\n console.warn('Analytics: Failed to clear cached events', err)\n }\n}\n\nexport const clearCachedPageViews = (): void => {\n try {\n localStorage.removeItem(CACHE_STORAGE_PAGES)\n } catch (err) {\n console.warn('Analytics: Failed to clear cached page views', err)\n }\n}\n","import { RudderStack } from './providers/rudderstack'\nimport {\n cacheEventToStorage,\n cachePageViewToStorage,\n getCachedEvents,\n getCachedPageViews,\n clearCachedEvents,\n clearCachedPageViews,\n} from './utils/storage'\nimport { isUUID, getCountry, cleanObject, flattenObject, createLogger, isInternalEmail } from './utils/helpers'\n// Optional Growthbook types - only import if using Growthbook\nimport type { Growthbook, GrowthbookConfigs } from './providers/growthbook'\nimport type { TGrowthbookAttributes, TGrowthbookOptions } from './providers/growthbookTypes'\n\n// Optional Posthog types - only import if using Posthog\nimport type { Posthog } from './providers/posthog'\nimport type { TPosthogIdentifyTraits, TPosthogOptions } from './providers/posthogTypes'\n\ndeclare global {\n interface Window {\n AnalyticsInstance: ReturnType<typeof createAnalyticsInstance>\n }\n}\n\n/**\n * Configuration options for initializing the analytics instance\n */\ntype Options = {\n /** GrowthBook client API key for A/B testing and feature flags */\n growthbookKey?: string\n /** GrowthBook decryption key for encrypted feature payloads */\n growthbookDecryptionKey?: string\n /** RudderStack write key for event tracking */\n rudderstackKey?: string\n /** Additional configuration options for GrowthBook */\n growthbookOptions?: TGrowthbookOptions\n /** PostHog configuration options including API keys and settings */\n posthogOptions?: TPosthogOptions\n /** Enable debug logging — logs all analytics calls prefixed with [ANALYTIC] */\n debug?: boolean\n}\n\n/**\n * Creates a unified analytics instance that integrates RudderStack and GrowthBook.\n *\n * This function provides a centralized interface for:\n * - Event tracking across multiple analytics platforms\n * - A/B testing and feature flag management via GrowthBook\n * - Offline event caching with automatic replay\n *\n * @param {Options} _options - Optional initialization configuration\n * @returns {Object} Analytics instance with methods for tracking, identification, and feature management\n *\n * @example\n * ```typescript\n * const analytics = createAnalyticsInstance();\n *\n * // Initialize with providers\n * await analytics.initialise({\n * rudderstackKey: 'YOUR_RS_KEY',\n * growthbookKey: 'YOUR_GB_KEY',\n * growthbookDecryptionKey: 'YOUR_GB_DECRYPT_KEY'\n * });\n *\n * // Set user attributes\n * analytics.setAttributes({\n * user_id: 'user123',\n * country: 'US',\n * user_language: 'en'\n * });\n *\n * // Track events\n * analytics.trackEvent('button_clicked', { button_name: 'signup' });\n *\n * // Track page views\n * analytics.pageView('/dashboard', 'Deriv App');\n * ```\n */\nexport function createAnalyticsInstance(_options?: Options) {\n let _debug = _options?.debug ?? false\n\n const log = createLogger('', () => _debug)\n\n let _growthbook: Growthbook | undefined,\n _rudderstack: RudderStack,\n _posthog: Posthog | undefined,\n core_data: Record<string, any> = {},\n tracking_config: { [key: string]: boolean } = {},\n offline_event_cache: Array<{ event: string; payload: Record<string, any> }> = [],\n _pending_identify_calls: Array<{ userId: string; traits?: Record<string, any> }> = [],\n _storage_cache_processed = false\n\n const processStorageCache = () => {\n if (_storage_cache_processed) return\n if (!_rudderstack?.has_initialized) return\n\n _storage_cache_processed = true\n\n try {\n const storedEvents = getCachedEvents()\n if (storedEvents.length > 0) {\n log(`processStorageCache | replaying ${storedEvents.length} cached event(s)`, storedEvents)\n storedEvents.forEach(event => {\n const cleaned_properties = cleanObject(event.properties)\n _rudderstack?.track(event.name, cleaned_properties)\n })\n clearCachedEvents()\n }\n\n const storedPages = getCachedPageViews()\n if (storedPages.length > 0) {\n log(`processStorageCache | replaying ${storedPages.length} cached page view(s)`, storedPages)\n storedPages.forEach(page => {\n _rudderstack?.pageView(page.name, 'Deriv App', getId(), page.properties)\n })\n clearCachedPageViews()\n }\n } catch (err) {\n console.warn('Analytics: Failed to process storage cache', err)\n }\n }\n\n const onSdkLoaded = () => {\n log('onSdkLoaded | RudderStack SDK loaded')\n processStorageCache()\n\n if (_pending_identify_calls.length > 0) {\n log(`onSdkLoaded | flushing ${_pending_identify_calls.length} pending identify call(s)`)\n }\n _pending_identify_calls.forEach(({ userId, traits }) => {\n if (userId) {\n _rudderstack?.identifyEvent(userId, traits)\n }\n })\n _pending_identify_calls = []\n }\n\n /**\n * Initializes the analytics instance with specified provider configurations.\n * This method should be called before tracking any events.\n *\n * Features:\n * - Lazy-loads providers (GrowthBook, PostHog) only when configured\n * - Automatically fetches user's country for GrowthBook targeting\n * - Processes any cached events from previous sessions\n * - Sets up event tracking callback for GrowthBook experiments\n *\n * @param {Options} options - Configuration options for analytics providers\n * @returns {Promise<void>} Resolves when initialization is complete\n *\n * @example\n * ```typescript\n * await analytics.initialise({\n * rudderstackKey: 'YOUR_RS_KEY',\n * growthbookKey: 'YOUR_GB_KEY',\n * growthbookDecryptionKey: 'YOUR_GB_DECRYPT_KEY',\n * posthogOptions: {\n * apiKey: 'YOUR_POSTHOG_API_KEY',\n * config: {\n * session_recording: {\n * recordCrossOriginIframes: true,\n * minimumDurationMilliseconds: 30000\n * }\n * }\n * }\n * });\n * ```\n */\n const initialise = async ({\n growthbookKey,\n growthbookDecryptionKey,\n rudderstackKey,\n growthbookOptions,\n posthogOptions,\n debug,\n }: Options) => {\n if (debug !== undefined) _debug = debug\n\n log('initialise | starting analytics initialization', {\n rudderstack: !!rudderstackKey,\n growthbook: !!growthbookKey,\n posthog: !!posthogOptions,\n })\n\n try {\n // Only fetch country if GrowthBook is enabled and country not provided\n const country = growthbookOptions?.attributes?.country || (growthbookKey ? await getCountry() : undefined)\n\n if (rudderstackKey) {\n log('initialise | initializing RudderStack')\n _rudderstack = RudderStack.getRudderStackInstance(rudderstackKey, onSdkLoaded, _debug)\n }\n\n if (growthbookOptions?.attributes && Object.keys(growthbookOptions.attributes).length > 0) {\n const attrs = growthbookOptions.attributes\n const anonymousId = _rudderstack?.getAnonymousId()\n\n core_data = {\n ...core_data,\n country,\n ...(attrs.user_language && { user_language: attrs.user_language }),\n ...(attrs.account_type && { account_type: attrs.account_type }),\n ...(attrs.app_id && { app_id: attrs.app_id }),\n ...(attrs.residence_country && { residence_country: attrs.residence_country }),\n ...(attrs.device_type && { device_type: attrs.device_type }),\n ...(attrs.url && { url: attrs.url }),\n ...(attrs.email_hash && { email_hash: attrs.email_hash }),\n ...(attrs.network_type && { network_type: attrs.network_type }),\n ...(attrs.network_rtt && { network_rtt: attrs.network_rtt }),\n ...(attrs.network_downlink && { network_downlink: attrs.network_downlink }),\n ...(attrs.account_currency && { account_currency: attrs.account_currency }),\n ...(attrs.account_mode && { account_mode: attrs.account_mode }),\n loggedIn: !!attrs.loggedIn,\n ...(attrs.user_id && !isUUID(attrs.user_id) && { user_id: attrs.user_id }),\n ...(anonymousId && { anonymous_id: anonymousId }),\n }\n }\n\n growthbookOptions ??= {}\n growthbookOptions.attributes ??= {}\n const anonId = _rudderstack?.getAnonymousId()\n growthbookOptions.attributes.id ??= anonId\n growthbookOptions.attributes.country ??= country\n\n if (growthbookKey) {\n log('initialise | initializing GrowthBook')\n // Dynamically import Growthbook only when needed\n const { Growthbook } = await import('./providers/growthbook')\n _growthbook = Growthbook.getGrowthBookInstance(\n growthbookKey,\n growthbookDecryptionKey,\n growthbookOptions,\n _debug\n )\n log('initialise | GrowthBook initialized')\n\n const interval = setInterval(() => {\n if (Object.keys(tracking_config).length > 0) clearInterval(interval)\n else tracking_config = getFeatureValue('tracking-buttons-config', {}) as { [key: string]: boolean }\n }, 1000)\n }\n\n if (posthogOptions) {\n log('initialise | initializing PostHog')\n // Dynamically import Posthog only when needed\n const { Posthog } = await import('./providers/posthog')\n _posthog = Posthog.getPosthogInstance(posthogOptions, _debug)\n log('initialise | PostHog initialized')\n }\n\n log('initialise | analytics initialization complete')\n } catch (err) {\n console.warn('Analytics: Failed to initialize', err)\n }\n }\n\n /**\n * Sets user and context attributes for analytics tracking and targeting.\n * These attributes are automatically included in all subsequent events.\n *\n * Attributes are used for:\n * - Event enrichment (added to all tracked events)\n * - GrowthBook targeting (feature flags and A/B tests)\n * - User segmentation across analytics platforms\n *\n * @param {TCoreAttributes} attributes - User and context attributes\n *\n * @example\n * ```typescript\n * analytics.setAttributes({\n * user_id: 'CR123456',\n * country: 'US',\n * user_language: 'en',\n * device_type: 'desktop',\n * account_type: 'real',\n * loggedIn: true\n * });\n * ```\n */\n const setAttributes = (attributes: Record<string, any>) => {\n log('setAttributes | received attributes', attributes)\n\n const { user_id, ...rest } = attributes\n const user_identity = user_id ?? getId()\n\n if (_growthbook) {\n const config: TGrowthbookAttributes = { ...rest }\n if (user_id && !isUUID(user_id)) config.user_id = user_id\n if (user_identity) {\n config.id = user_identity\n config.user_id = user_identity\n }\n log('setAttributes | called GrowthBook setAttributes', config)\n _growthbook.setAttributes(config)\n }\n\n core_data = {\n ...core_data,\n ...Object.fromEntries(Object.entries(rest).filter(([, v]) => v !== undefined)),\n ...(user_id !== undefined && !isUUID(user_id) && { user_id }),\n }\n\n log('setAttributes | updated core_data', core_data)\n }\n\n const getFeatureState = (id: string) => _growthbook?.getFeatureState(id)?.experimentResult?.name\n\n const getFeatureValue = <K extends keyof GrowthbookConfigs, V extends GrowthbookConfigs[K]>(\n id: K,\n defaultValue: V\n ) => _growthbook?.getFeatureValue(id as string, defaultValue)\n\n const getGrowthbookStatus = async () => await _growthbook?.getStatus()\n const isFeatureOn = (key: string) => _growthbook?.isOn(key)\n const setUrl = (href: string) => _growthbook?.setUrl(href)\n\n const getId = () => {\n const userId = _rudderstack?.getUserId() || ''\n return userId && !isUUID(userId) ? userId : ''\n }\n\n const getAnonymousId = () => _rudderstack?.getAnonymousId() || ''\n\n /**\n * Tracks a page view event.\n *\n * Features:\n * - Automatically includes user ID if available\n * - Caches page views when offline or provider not initialized\n *\n * @param {string} current_page - The current page URL or path\n * @param {string} [platform='Deriv App'] - The platform name\n * @param {Record<string, unknown>} [properties] - Additional page properties\n *\n * @example\n * ```typescript\n * analytics.pageView('/dashboard');\n * analytics.pageView('/trade', 'Deriv Trader', { section: 'multipliers' });\n * ```\n */\n const pageView = (current_page: string, platform = 'Deriv App', properties?: Record<string, unknown>) => {\n const userId = getId()\n\n log('pageView | called', { current_page, platform, properties, userId })\n\n // Handle RudderStack pageView independently\n if (_rudderstack?.has_initialized) {\n log('pageView | sending page view to RudderStack', { current_page, platform })\n _rudderstack.pageView(current_page, platform, userId, properties)\n } else {\n log('pageView | RudderStack not initialized — caching page view to localStorage', { current_page })\n cachePageViewToStorage(current_page, { platform, ...properties })\n }\n\n // PostHog handles page views automatically via autocapture\n // No need to manually send page views to PostHog\n }\n\n /**\n * Identifies a user across analytics platforms.\n * This method should be called after user login or when user identity is known.\n *\n * Features:\n * - Queues identify calls if provider not yet initialized\n * - Allows custom traits for each provider or shared traits for both\n * - Identifies user in PostHog if configured\n *\n * @param {string} [user_id] - The user ID to identify. If not provided, uses stored user ID\n * @param {Record<string, any>} [traits] - Optional traits to send to both providers, or provider-specific traits\n *\n * @example\n * ```typescript\n * // Simple identify\n * analytics.identifyEvent('CR123456');\n *\n * // Identify with same traits for both providers\n * analytics.identifyEvent('CR123456', {\n * language: 'en',\n * country_of_residence: 'US'\n * });\n *\n * // Identify with provider-specific traits\n * analytics.identifyEvent('CR123456', {\n * rudderstack: { language: 'en', custom_field: 'value' },\n * posthog: { language: 'en', country_of_residence: 'US' }\n * });\n * ```\n */\n const identifyEvent = (user_id?: string, traits?: Record<string, any>) => {\n const stored_user_id = user_id || getId()\n if (!stored_user_id) {\n log('identifyEvent | skipped — no user_id available')\n return\n }\n\n log('identifyEvent | called', { user_id: stored_user_id, traits })\n\n // Strip PII: replace raw email with is_internal flag\n const sanitizePII = (t?: Record<string, any>) => {\n if (!t) return t\n const { email, ...safe } = t\n return { ...safe, ...(email && { is_internal: isInternalEmail(email) }) }\n }\n\n // Check if traits has provider-specific structure\n const hasProviderStructure = traits?.rudderstack !== undefined || traits?.posthog !== undefined\n let rudderstackTraits, posthogTraits\n if (hasProviderStructure) {\n // Merge shared top-level props with provider-specific ones (provider-specific wins on conflict)\n const { rudderstack, posthog, ...sharedTraits } = traits as any\n rudderstackTraits = sanitizePII({ ...sharedTraits, ...rudderstack })\n posthogTraits = sanitizePII({ ...sharedTraits, ...posthog })\n } else {\n rudderstackTraits = sanitizePII(traits)\n posthogTraits = sanitizePII(traits)\n }\n\n // Handle RudderStack identification independently\n if (_rudderstack) {\n if (_rudderstack.has_initialized) {\n log('identifyEvent | calling RudderStack identify', {\n user_id: stored_user_id,\n traits: rudderstackTraits,\n })\n _rudderstack.identifyEvent(stored_user_id, rudderstackTraits)\n } else {\n if (!_pending_identify_calls.some(call => call.userId === stored_user_id)) {\n log('identifyEvent | RudderStack not initialized — queuing identify call', {\n user_id: stored_user_id,\n })\n _pending_identify_calls.push({ userId: stored_user_id, traits: rudderstackTraits })\n }\n }\n }\n\n // Handle PostHog identification independently\n if (_posthog?.has_initialized) {\n log('identifyEvent | calling PostHog identify', { user_id: stored_user_id, traits: posthogTraits })\n _posthog.identifyEvent(stored_user_id, posthogTraits as TPosthogIdentifyTraits)\n }\n }\n\n const reset = () => {\n log('reset | resetting all providers')\n // Reset each provider independently\n if (_rudderstack?.has_initialized) {\n log('reset | resetting RudderStack')\n _rudderstack.reset()\n }\n if (_posthog?.has_initialized) {\n log('reset | resetting PostHog')\n _posthog.reset()\n }\n }\n\n /**\n * Tracks a custom event with associated data.\n *\n * Features:\n * - Automatically enriches events with core attributes\n * - RudderStack: Caches events when offline or not initialized\n * - PostHog: Sends immediately if initialized (has built-in caching)\n * - Respects feature flag configurations\n * - Each provider works independently - one failing won't affect the other\n *\n * @param {string} event - The event name to track\n * @param {Record<string, any>} analytics_data - The event data payload\n */\n const trackEvent = (event: string, analytics_data: Record<string, any>) => {\n const userId = getId()\n\n log('trackEvent | called', { event, analytics_data, userId, core_data })\n\n const final_payload = {\n ...core_data,\n ...analytics_data,\n ...(userId && !core_data.user_id && { user_id: userId }),\n }\n\n log('trackEvent | built payload', { event, final_payload })\n\n const shouldTrack = !(event in tracking_config) || tracking_config[event as string]\n if (!shouldTrack) {\n log('trackEvent | skipped — event disabled by tracking_config', { event })\n return\n }\n\n // Handle RudderStack independently\n const hasRudderstackInitialized = _rudderstack?.has_initialized\n if (!navigator.onLine || !hasRudderstackInitialized) {\n if (!hasRudderstackInitialized) {\n log('trackEvent | RudderStack not initialized — caching event to localStorage', { event })\n cacheEventToStorage(event as string, final_payload)\n } else {\n log('trackEvent | offline — caching event to memory', { event })\n offline_event_cache.push({ event, payload: final_payload })\n }\n } else {\n // Send cached events to RudderStack\n if (offline_event_cache.length > 0) {\n log(`trackEvent | flushing ${offline_event_cache.length} offline cached event(s) to RudderStack`)\n offline_event_cache.forEach(cache => {\n const cleaned_cache_payload = cleanObject(cache.payload)\n _rudderstack?.track(cache.event, cleaned_cache_payload)\n })\n offline_event_cache = []\n }\n\n // Send current event to RudderStack\n const cleaned_payload = cleanObject(final_payload)\n log('trackEvent | sending event to RudderStack', { event, payload: cleaned_payload })\n _rudderstack?.track(event, cleaned_payload)\n }\n\n // Handle PostHog independently - send immediately if initialized\n if (_posthog?.has_initialized) {\n const posthog_payload = cleanObject(flattenObject(final_payload))\n log('trackEvent | sending event to PostHog', { event, payload: posthog_payload })\n _posthog.capture(event as string, posthog_payload)\n }\n }\n\n /**\n * Ensures client_id is set in PostHog stored person properties.\n * Call this when the user ID is available and PostHog is loaded.\n * Useful for backfilling client_id for users identified in previous sessions.\n * No-op if client_id is already present or PostHog is not initialized.\n *\n * @param params.user_id - The user ID to use as client_id\n * @param params.email - The user's email, used to determine is_internal\n * @param params.language - The user's language (BCP 47 tag, e.g. \"en-GB\")\n * @param params.country_of_residence - The user's country of residence\n *\n * @example\n * ```typescript\n * if (window.posthog?.__loaded && userId) {\n * analytics.backfillPersonProperties({ user_id: userId, email, language, country_of_residence })\n * }\n * ```\n */\n const backfillPersonProperties = ({\n user_id,\n email,\n language,\n country_of_residence,\n }: {\n user_id: string\n email?: string\n language?: string\n country_of_residence?: string\n }): void => {\n log('backfillPersonProperties | called', { user_id })\n if (_posthog?.has_initialized) {\n log('backfillPersonProperties | backfilling person properties in PostHog', { user_id })\n _posthog.backfillPersonProperties({ user_id, email, language, country_of_residence })\n } else {\n log('backfillPersonProperties | skipped — PostHog not initialized')\n }\n }\n\n const getInstances = () => ({ ab: _growthbook, tracking: _rudderstack, posthog: _posthog })\n\n const AnalyticsInstance = {\n initialise,\n setAttributes,\n identifyEvent,\n backfillPersonProperties,\n getFeatureState,\n getFeatureValue,\n getGrowthbookStatus,\n isFeatureOn,\n setUrl,\n getId,\n getAnonymousId,\n trackEvent,\n getInstances,\n pageView,\n reset,\n }\n\n if (typeof window !== 'undefined') {\n window.AnalyticsInstance = AnalyticsInstance\n }\n\n return AnalyticsInstance\n}\n\nexport const Analytics = createAnalyticsInstance()\n"],"mappings":"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","names":["COOKIE_MAX_AGE_SECONDS","_RudderStack","RUDDERSTACK_KEY","onLoaded","debug","RudderAnalytics","createLogger","hostname","domain_name","domain","uuid","bytes","hex","byte","secureFlag","error","rudderstackDataplane","user_id","payload","currentUserId","current_page","platform","properties","pageProperties","event","err","RudderStack","CACHE_STORAGE_EVENTS","CACHE_STORAGE_PAGES","cacheEventToStorage","eventName","properties","existingCache","events","err","cachePageViewToStorage","pageName","pages","getCachedEvents","storedEventsString","getCachedPageViews","storedPagesString","clearCachedEvents","clearCachedPageViews","createAnalyticsInstance","_options","_debug","log","createLogger","_growthbook","_rudderstack","_posthog","core_data","tracking_config","offline_event_cache","_pending_identify_calls","_storage_cache_processed","processStorageCache","storedEvents","getCachedEvents","event","cleaned_properties","cleanObject","clearCachedEvents","storedPages","getCachedPageViews","page","getId","clearCachedPageViews","err","onSdkLoaded","userId","traits","initialise","growthbookKey","growthbookDecryptionKey","rudderstackKey","growthbookOptions","posthogOptions","debug","_a","_b","country","getCountry","RudderStack","attrs","anonymousId","isUUID","anonId","Growthbook","interval","getFeatureValue","Posthog","setAttributes","attributes","user_id","rest","user_identity","config","v","getFeatureState","id","defaultValue","getGrowthbookStatus","isFeatureOn","key","setUrl","href","AnalyticsInstance","stored_user_id","sanitizePII","t","email","safe","isInternalEmail","hasProviderStructure","rudderstackTraits","posthogTraits","rudderstack","posthog","sharedTraits","call","language","country_of_residence","analytics_data","final_payload","hasRudderstackInitialized","cacheEventToStorage","cache","cleaned_cache_payload","cleaned_payload","posthog_payload","flattenObject","current_page","platform","properties","cachePageViewToStorage","Analytics"]}
|
package/dist/index.d.mts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import * as _growthbook_growthbook from '@growthbook/growthbook';
|
|
2
2
|
import { RudderStack } from './providers/rudderstack/index.mjs';
|
|
3
3
|
import { TGrowthbookOptions, GrowthbookConfigs, Growthbook } from './providers/growthbook/index.mjs';
|
|
4
|
-
import { T as TPosthogOptions, P as Posthog } from './posthog-
|
|
4
|
+
import { T as TPosthogOptions, P as Posthog } from './posthog-C-VllHa3.mjs';
|
|
5
5
|
import '@rudderstack/analytics-js';
|
|
6
6
|
import 'posthog-js';
|
|
7
7
|
|
package/dist/index.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import * as _growthbook_growthbook from '@growthbook/growthbook';
|
|
2
2
|
import { RudderStack } from './providers/rudderstack/index.js';
|
|
3
3
|
import { TGrowthbookOptions, GrowthbookConfigs, Growthbook } from './providers/growthbook/index.js';
|
|
4
|
-
import { T as TPosthogOptions, P as Posthog } from './posthog-
|
|
4
|
+
import { T as TPosthogOptions, P as Posthog } from './posthog-C-VllHa3.js';
|
|
5
5
|
import '@rudderstack/analytics-js';
|
|
6
6
|
import 'posthog-js';
|
|
7
7
|
|
package/dist/index.js
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
'use strict';var chunk6BHMKTVG_js=require('./chunk-6BHMKTVG.js'),chunkT4BXL6JM_js=require('./chunk-T4BXL6JM.js');/* @deriv-com/analytics - NPM Package - Built with tsup */
|
|
2
|
-
var I="cached_analytics_events",A="cached_analytics_page_views",O=(o,c)=>{try{let t=localStorage.getItem(I),d=t?JSON.parse(t):[];d.push({name:o,properties:c,timestamp:Date.now()}),localStorage.setItem(I,JSON.stringify(d));}catch(t){console.warn("Analytics: Failed to cache event",t);}},H=(o,c)=>{try{let t=localStorage.getItem(A),d=t?JSON.parse(t):[];d.push({name:o,properties:c,timestamp:Date.now()}),localStorage.setItem(A,JSON.stringify(d));}catch(t){console.warn("Analytics: Failed to cache page view",t);}},
|
|
2
|
+
var I="cached_analytics_events",A="cached_analytics_page_views",O=(o,c)=>{try{let t=localStorage.getItem(I),d=t?JSON.parse(t):[];d.push({name:o,properties:c,timestamp:Date.now()}),localStorage.setItem(I,JSON.stringify(d));}catch(t){console.warn("Analytics: Failed to cache event",t);}},H=(o,c)=>{try{let t=localStorage.getItem(A),d=t?JSON.parse(t):[];d.push({name:o,properties:c,timestamp:Date.now()}),localStorage.setItem(A,JSON.stringify(d));}catch(t){console.warn("Analytics: Failed to cache page view",t);}},D=()=>{try{let o=localStorage.getItem(I);if(o){let c=JSON.parse(o);return Array.isArray(c)?c:[]}}catch(o){console.warn("Analytics: Failed to get cached events",o);}return []},N=()=>{try{let o=localStorage.getItem(A);if(o){let c=JSON.parse(o);return Array.isArray(c)?c:[]}}catch(o){console.warn("Analytics: Failed to get cached pages",o);}return []},j=()=>{try{localStorage.removeItem(I);}catch(o){console.warn("Analytics: Failed to clear cached events",o);}},J=()=>{try{localStorage.removeItem(A);}catch(o){console.warn("Analytics: Failed to clear cached page views",o);}};function Q(o){let c=false,t=chunkT4BXL6JM_js.f("",()=>c),d,s,h,f={},b={},v=[],_=[],P=false,L=()=>{if(!P&&s?.has_initialized){P=true;try{let e=D();e.length>0&&(t(`processStorageCache | replaying ${e.length} cached event(s)`,e),e.forEach(a=>{let i=chunkT4BXL6JM_js.j(a.properties);s?.track(a.name,i);}),j());let n=N();n.length>0&&(t(`processStorageCache | replaying ${n.length} cached page view(s)`,n),n.forEach(a=>{s?.pageView(a.name,"Deriv App",k(),a.properties);}),J());}catch(e){console.warn("Analytics: Failed to process storage cache",e);}}},U=()=>{t("onSdkLoaded | RudderStack SDK loaded"),L(),_.length>0&&t(`onSdkLoaded | flushing ${_.length} pending identify call(s)`),_.forEach(({userId:e,traits:n})=>{e&&s?.identifyEvent(e,n);}),_=[];},B=async({growthbookKey:e,growthbookDecryptionKey:n,rudderstackKey:a,growthbookOptions:i,posthogOptions:l,debug:p})=>{var g,u;p!==void 0&&(c=p),t("initialise | starting analytics initialization",{rudderstack:!!a,growthbook:!!e,posthog:!!l});try{let y=i?.attributes?.country||(e?await chunkT4BXL6JM_js.i():void 0);if(a&&(t("initialise | initializing RudderStack"),s=chunk6BHMKTVG_js.a.getRudderStackInstance(a,U,c)),i?.attributes&&Object.keys(i.attributes).length>0){let r=i.attributes,E=s?.getAnonymousId();f={...f,country:y,...r.user_language&&{user_language:r.user_language},...r.account_type&&{account_type:r.account_type},...r.app_id&&{app_id:r.app_id},...r.residence_country&&{residence_country:r.residence_country},...r.device_type&&{device_type:r.device_type},...r.url&&{url:r.url},...r.email_hash&&{email_hash:r.email_hash},...r.network_type&&{network_type:r.network_type},...r.network_rtt&&{network_rtt:r.network_rtt},...r.network_downlink&&{network_downlink:r.network_downlink},...r.account_currency&&{account_currency:r.account_currency},...r.account_mode&&{account_mode:r.account_mode},loggedIn:!!r.loggedIn,...r.user_id&&!chunkT4BXL6JM_js.h(r.user_id)&&{user_id:r.user_id},...E&&{anonymous_id:E}};}i??(i={}),i.attributes??(i.attributes={});let w=s?.getAnonymousId();if((g=i.attributes).id??(g.id=w),(u=i.attributes).country??(u.country=y),e){t("initialise | initializing GrowthBook");let{Growthbook:r}=await import('./providers/growthbook/index.js');d=r.getGrowthBookInstance(e,n,i,c),t("initialise | GrowthBook initialized");let E=setInterval(()=>{Object.keys(b).length>0?clearInterval(E):b=R("tracking-buttons-config",{});},1e3);}if(l){t("initialise | initializing PostHog");let{Posthog:r}=await import('./providers/posthog/index.js');h=r.getPosthogInstance(l,c),t("initialise | PostHog initialized");}t("initialise | analytics initialization complete");}catch(y){console.warn("Analytics: Failed to initialize",y);}},$=e=>{t("setAttributes | received attributes",e);let{user_id:n,...a}=e,i=n??k();if(d){let l={...a};n&&!chunkT4BXL6JM_js.h(n)&&(l.user_id=n),i&&(l.id=i,l.user_id=i),t("setAttributes | called GrowthBook setAttributes",l),d.setAttributes(l);}f={...f,...Object.fromEntries(Object.entries(a).filter(([,l])=>l!==void 0)),...n!==void 0&&!chunkT4BXL6JM_js.h(n)&&{user_id:n}},t("setAttributes | updated core_data",f);},K=e=>d?.getFeatureState(e)?.experimentResult?.name,R=(e,n)=>d?.getFeatureValue(e,n),q=async()=>await d?.getStatus(),W=e=>d?.isOn(e),M=e=>d?.setUrl(e),k=()=>{let e=s?.getUserId()||"";return e&&!chunkT4BXL6JM_js.h(e)?e:""},C={initialise:B,setAttributes:$,identifyEvent:(e,n)=>{let a=e||k();if(!a){t("identifyEvent | skipped \u2014 no user_id available");return}t("identifyEvent | called",{user_id:a,traits:n});let i=u=>{if(!u)return u;let{email:y,...w}=u;return {...w,...y&&{is_internal:chunkT4BXL6JM_js.g(y)}}},l=n?.rudderstack!==void 0||n?.posthog!==void 0,p,g;if(l){let{rudderstack:u,posthog:y,...w}=n;p=i({...w,...u}),g=i({...w,...y});}else p=i(n),g=i(n);s&&(s.has_initialized?(t("identifyEvent | calling RudderStack identify",{user_id:a,traits:p}),s.identifyEvent(a,p)):_.some(u=>u.userId===a)||(t("identifyEvent | RudderStack not initialized \u2014 queuing identify call",{user_id:a}),_.push({userId:a,traits:p}))),h?.has_initialized&&(t("identifyEvent | calling PostHog identify",{user_id:a,traits:g}),h.identifyEvent(a,g));},backfillPersonProperties:({user_id:e,email:n,language:a,country_of_residence:i})=>{t("backfillPersonProperties | called",{user_id:e}),h?.has_initialized?(t("backfillPersonProperties | backfilling person properties in PostHog",{user_id:e}),h.backfillPersonProperties({user_id:e,email:n,language:a,country_of_residence:i})):t("backfillPersonProperties | skipped \u2014 PostHog not initialized");},getFeatureState:K,getFeatureValue:R,getGrowthbookStatus:q,isFeatureOn:W,setUrl:M,getId:k,getAnonymousId:()=>s?.getAnonymousId()||"",trackEvent:(e,n)=>{let a=k();t("trackEvent | called",{event:e,analytics_data:n,userId:a,core_data:f});let i={...f,...n,...a&&!f.user_id&&{user_id:a}};if(t("trackEvent | built payload",{event:e,final_payload:i}),!(!(e in b)||b[e])){t("trackEvent | skipped \u2014 event disabled by tracking_config",{event:e});return}let p=s?.has_initialized;if(!navigator.onLine||!p)p?(t("trackEvent | offline \u2014 caching event to memory",{event:e}),v.push({event:e,payload:i})):(t("trackEvent | RudderStack not initialized \u2014 caching event to localStorage",{event:e}),O(e,i));else {v.length>0&&(t(`trackEvent | flushing ${v.length} offline cached event(s) to RudderStack`),v.forEach(u=>{let y=chunkT4BXL6JM_js.j(u.payload);s?.track(u.event,y);}),v=[]);let g=chunkT4BXL6JM_js.j(i);t("trackEvent | sending event to RudderStack",{event:e,payload:g}),s?.track(e,g);}if(h?.has_initialized){let g=chunkT4BXL6JM_js.j(chunkT4BXL6JM_js.k(i));t("trackEvent | sending event to PostHog",{event:e,payload:g}),h.capture(e,g);}},getInstances:()=>({ab:d,tracking:s,posthog:h}),pageView:(e,n="Deriv App",a)=>{let i=k();t("pageView | called",{current_page:e,platform:n,properties:a,userId:i}),s?.has_initialized?(t("pageView | sending page view to RudderStack",{current_page:e,platform:n}),s.pageView(e,n,i,a)):(t("pageView | RudderStack not initialized \u2014 caching page view to localStorage",{current_page:e}),H(e,{platform:n,...a}));},reset:()=>{t("reset | resetting all providers"),s?.has_initialized&&(t("reset | resetting RudderStack"),s.reset()),h?.has_initialized&&(t("reset | resetting PostHog"),h.reset());}};return typeof window<"u"&&(window.AnalyticsInstance=C),C}var X=Q();exports.Analytics=X;//# sourceMappingURL=index.js.map
|
|
3
3
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/utils/storage.ts","../src/analytics.ts"],"names":["CACHE_STORAGE_EVENTS","CACHE_STORAGE_PAGES","cacheEventToStorage","eventName","properties","existingCache","events","err","cachePageViewToStorage","pageName","pages","getCachedEvents","storedEventsString","getCachedPageViews","storedPagesString","clearCachedEvents","clearCachedPageViews","createAnalyticsInstance","_options","_debug","log","createLogger","_growthbook","_rudderstack","_posthog","core_data","tracking_config","offline_event_cache","_pending_identify_calls","_storage_cache_processed","processStorageCache","storedEvents","event","cleaned_properties","cleanObject","storedPages","page","getId","onSdkLoaded","userId","traits","initialise","growthbookKey","growthbookDecryptionKey","rudderstackKey","growthbookOptions","posthogOptions","debug","_a","_b","country","getCountry","RudderStack","attrs","anonymousId","isUUID","anonId","Growthbook","interval","getFeatureValue","Posthog","setAttributes","attributes","user_id","rest","user_identity","config","v","getFeatureState","id","defaultValue","getGrowthbookStatus","isFeatureOn","key","setUrl","href","AnalyticsInstance","stored_user_id","sanitizePII","t","email","safe","isInternalEmail","hasProviderStructure","rudderstackTraits","posthogTraits","rudderstack","posthog","sharedTraits","call","language","country_of_residence","analytics_data","final_payload","hasRudderstackInitialized","cache","cleaned_cache_payload","cleaned_payload","posthog_excluded_keys","flattened_payload","flattenObject","posthog_payload","current_page","platform","Analytics"],"mappings":";AAAO,IAAMA,EAAuB,yBAAA,CACvBC,CAAAA,CAAsB,8BActBC,CAAAA,CAAsB,CAACC,EAAmBC,CAAAA,GAA8C,CACjG,GAAI,CACA,IAAMC,CAAAA,CAAgB,YAAA,CAAa,QAAQL,CAAoB,CAAA,CACzDM,EAAwBD,CAAAA,CAAgB,IAAA,CAAK,KAAA,CAAMA,CAAa,EAAI,EAAC,CAC3EC,EAAO,IAAA,CAAK,CAAE,KAAMH,CAAAA,CAAW,UAAA,CAAAC,CAAAA,CAAY,SAAA,CAAW,KAAK,GAAA,EAAM,CAAC,CAAA,CAClE,YAAA,CAAa,QAAQJ,CAAAA,CAAsB,IAAA,CAAK,SAAA,CAAUM,CAAM,CAAC,EACrE,CAAA,MAASC,EAAK,CACV,OAAA,CAAQ,KAAK,kCAAA,CAAoCA,CAAG,EACxD,CACJ,EAEaC,CAAAA,CAAyB,CAACC,EAAkBL,CAAAA,GAA+C,CACpG,GAAI,CACA,IAAMC,CAAAA,CAAgB,YAAA,CAAa,QAAQJ,CAAmB,CAAA,CACxDS,EAA0BL,CAAAA,CAAgB,IAAA,CAAK,MAAMA,CAAa,CAAA,CAAI,EAAC,CAC7EK,EAAM,IAAA,CAAK,CAAE,KAAMD,CAAAA,CAAU,UAAA,CAAAL,EAAY,SAAA,CAAW,IAAA,CAAK,GAAA,EAAM,CAAC,CAAA,CAChE,YAAA,CAAa,QAAQH,CAAAA,CAAqB,IAAA,CAAK,UAAUS,CAAK,CAAC,EACnE,CAAA,MAASH,EAAK,CACV,OAAA,CAAQ,KAAK,sCAAA,CAAwCA,CAAG,EAC5D,CACJ,CAAA,CAEaI,CAAAA,CAAkB,IAAqB,CAChD,GAAI,CACA,IAAMC,CAAAA,CAAqB,YAAA,CAAa,QAAQZ,CAAoB,CAAA,CACpE,GAAIY,CAAAA,CAAoB,CACpB,IAAMN,CAAAA,CAAS,KAAK,KAAA,CAAMM,CAAkB,EAC5C,OAAO,KAAA,CAAM,OAAA,CAAQN,CAAM,EAAIA,CAAAA,CAAS,EAC5C,CACJ,CAAA,MAASC,EAAK,CACV,OAAA,CAAQ,IAAA,CAAK,wCAAA,CAA0CA,CAAG,EAC9D,CACA,OAAO,EACX,EAEaM,CAAAA,CAAqB,IAAwB,CACtD,GAAI,CACA,IAAMC,CAAAA,CAAoB,aAAa,OAAA,CAAQb,CAAmB,EAClE,GAAIa,CAAAA,CAAmB,CACnB,IAAMJ,EAAQ,IAAA,CAAK,KAAA,CAAMI,CAAiB,CAAA,CAC1C,OAAO,MAAM,OAAA,CAAQJ,CAAK,CAAA,CAAIA,CAAAA,CAAQ,EAC1C,CACJ,OAASH,CAAAA,CAAK,CACV,QAAQ,IAAA,CAAK,uCAAA,CAAyCA,CAAG,EAC7D,CACA,OAAO,EACX,CAAA,CAEaQ,CAAAA,CAAoB,IAAY,CACzC,GAAI,CACA,YAAA,CAAa,WAAWf,CAAoB,EAChD,OAASO,CAAAA,CAAK,CACV,QAAQ,IAAA,CAAK,0CAAA,CAA4CA,CAAG,EAChE,CACJ,CAAA,CAEaS,CAAAA,CAAuB,IAAY,CAC5C,GAAI,CACA,YAAA,CAAa,UAAA,CAAWf,CAAmB,EAC/C,OAASM,CAAAA,CAAK,CACV,QAAQ,IAAA,CAAK,8CAAA,CAAgDA,CAAG,EACpE,CACJ,CAAA,CCCO,SAASU,EAAwBC,CAAAA,CAAoB,CACxD,IAAIC,CAAAA,CAA4B,KAAA,CAE1BC,CAAAA,CAAMC,kBAAAA,CAAa,EAAA,CAAI,IAAMF,CAAM,CAAA,CAErCG,EACAC,CAAAA,CACAC,CAAAA,CACAC,EAAiC,EAAC,CAClCC,CAAAA,CAA8C,GAC9CC,CAAAA,CAA8E,GAC9EC,CAAAA,CAAmF,GACnFC,CAAAA,CAA2B,KAAA,CAEzBC,CAAAA,CAAsB,IAAM,CAC9B,GAAI,CAAAD,GACCN,CAAAA,EAAc,eAAA,CAEnB,CAAAM,CAAAA,CAA2B,IAAA,CAE3B,GAAI,CACA,IAAME,CAAAA,CAAepB,CAAAA,GACjBoB,CAAAA,CAAa,MAAA,CAAS,IACtBX,CAAAA,CAAI,CAAA,gCAAA,EAAmCW,CAAAA,CAAa,MAAM,mBAAoBA,CAAY,CAAA,CAC1FA,EAAa,OAAA,CAAQC,CAAAA,EAAS,CAC1B,IAAMC,CAAAA,CAAqBC,kBAAAA,CAAYF,CAAAA,CAAM,UAAU,CAAA,CACvDT,CAAAA,EAAc,MAAMS,CAAAA,CAAM,IAAA,CAAMC,CAAkB,EACtD,CAAC,CAAA,CACDlB,CAAAA,IAGJ,IAAMoB,CAAAA,CAActB,GAAmB,CACnCsB,CAAAA,CAAY,OAAS,CAAA,GACrBf,CAAAA,CAAI,CAAA,gCAAA,EAAmCe,CAAAA,CAAY,MAAM,CAAA,oBAAA,CAAA,CAAwBA,CAAW,EAC5FA,CAAAA,CAAY,OAAA,CAAQC,GAAQ,CACxBb,CAAAA,EAAc,QAAA,CAASa,CAAAA,CAAK,KAAM,WAAA,CAAaC,CAAAA,GAASD,CAAAA,CAAK,UAAU,EAC3E,CAAC,CAAA,CACDpB,GAAqB,EAE7B,CAAA,MAAST,EAAK,CACV,OAAA,CAAQ,KAAK,4CAAA,CAA8CA,CAAG,EAClE,CAAA,CACJ,CAAA,CAEM+B,CAAAA,CAAc,IAAM,CACtBlB,CAAAA,CAAI,sCAAsC,EAC1CU,CAAAA,EAAoB,CAEhBF,EAAwB,MAAA,CAAS,CAAA,EACjCR,CAAAA,CAAI,CAAA,uBAAA,EAA0BQ,EAAwB,MAAM,CAAA,yBAAA,CAA2B,EAE3FA,CAAAA,CAAwB,OAAA,CAAQ,CAAC,CAAE,MAAA,CAAAW,CAAAA,CAAQ,MAAA,CAAAC,CAAO,CAAA,GAAM,CAChDD,GACAhB,CAAAA,EAAc,aAAA,CAAcgB,EAAQC,CAAM,EAElD,CAAC,CAAA,CACDZ,EAA0B,GAC9B,EAiCMa,CAAAA,CAAa,MAAO,CACtB,aAAA,CAAAC,CAAAA,CACA,uBAAA,CAAAC,CAAAA,CACA,eAAAC,CAAAA,CACA,iBAAA,CAAAC,EACA,cAAA,CAAAC,CAAAA,CACA,MAAAC,CACJ,CAAA,GAAe,CA/KnB,IAAAC,EAAAC,CAAAA,CAgLYF,CAAAA,GAAU,SAAW5B,CAAAA,CAAS4B,CAAAA,CAAAA,CAElC3B,EAAI,gDAAA,CAAkD,CAClD,WAAA,CAAa,CAAC,CAACwB,CAAAA,CACf,UAAA,CAAY,CAAC,CAACF,CAAAA,CACd,QAAS,CAAC,CAACI,CACf,CAAC,EAED,GAAI,CAEA,IAAMI,CAAAA,CAAUL,CAAAA,EAAmB,YAAY,OAAA,GAAYH,CAAAA,CAAgB,MAAMS,kBAAAA,GAAe,KAAA,CAAA,CAAA,CAOhG,GALIP,IACAxB,CAAAA,CAAI,uCAAuC,EAC3CG,CAAAA,CAAe6B,kBAAAA,CAAY,sBAAA,CAAuBR,CAAAA,CAAgBN,EAAanB,CAAM,CAAA,CAAA,CAGrF0B,GAAmB,UAAA,EAAc,MAAA,CAAO,KAAKA,CAAAA,CAAkB,UAAU,CAAA,CAAE,MAAA,CAAS,EAAG,CACvF,IAAMQ,EAAQR,CAAAA,CAAkB,UAAA,CAC1BS,EAAc/B,CAAAA,EAAc,cAAA,EAAe,CAEjDE,CAAAA,CAAY,CACR,GAAGA,CAAAA,CACH,QAAAyB,CAAAA,CACA,GAAIG,EAAM,aAAA,EAAiB,CAAE,aAAA,CAAeA,CAAAA,CAAM,aAAc,CAAA,CAChE,GAAIA,EAAM,YAAA,EAAgB,CAAE,aAAcA,CAAAA,CAAM,YAAa,CAAA,CAC7D,GAAIA,EAAM,MAAA,EAAU,CAAE,OAAQA,CAAAA,CAAM,MAAO,EAC3C,GAAIA,CAAAA,CAAM,iBAAA,EAAqB,CAAE,kBAAmBA,CAAAA,CAAM,iBAAkB,EAC5E,GAAIA,CAAAA,CAAM,aAAe,CAAE,WAAA,CAAaA,CAAAA,CAAM,WAAY,EAC1D,GAAIA,CAAAA,CAAM,KAAO,CAAE,GAAA,CAAKA,EAAM,GAAI,CAAA,CAClC,GAAIA,CAAAA,CAAM,YAAc,CAAE,UAAA,CAAYA,EAAM,UAAW,CAAA,CACvD,GAAIA,CAAAA,CAAM,YAAA,EAAgB,CAAE,YAAA,CAAcA,EAAM,YAAa,CAAA,CAC7D,GAAIA,CAAAA,CAAM,WAAA,EAAe,CAAE,WAAA,CAAaA,CAAAA,CAAM,WAAY,CAAA,CAC1D,GAAIA,CAAAA,CAAM,gBAAA,EAAoB,CAAE,gBAAA,CAAkBA,CAAAA,CAAM,gBAAiB,CAAA,CACzE,GAAIA,CAAAA,CAAM,gBAAA,EAAoB,CAAE,gBAAA,CAAkBA,CAAAA,CAAM,gBAAiB,CAAA,CACzE,GAAIA,EAAM,YAAA,EAAgB,CAAE,YAAA,CAAcA,CAAAA,CAAM,YAAa,CAAA,CAC7D,QAAA,CAAU,CAAC,CAACA,CAAAA,CAAM,SAClB,GAAIA,CAAAA,CAAM,OAAA,EAAW,CAACE,mBAAOF,CAAAA,CAAM,OAAO,GAAK,CAAE,OAAA,CAASA,EAAM,OAAQ,CAAA,CACxE,GAAIC,CAAAA,EAAe,CAAE,YAAA,CAAcA,CAAY,CACnD,EACJ,CAEAT,MAAsB,EAAC,CAAA,CACvBA,CAAAA,CAAkB,UAAA,GAAlBA,EAAkB,UAAA,CAAe,IACjC,IAAMW,CAAAA,CAASjC,GAAc,cAAA,EAAe,CAI5C,GAAA,CAHAyB,CAAAA,CAAAH,EAAkB,UAAA,EAAW,EAAA,GAA7BG,EAA6B,EAAA,CAAOQ,CAAAA,CAAAA,CAAAA,CACpCP,EAAAJ,CAAAA,CAAkB,UAAA,EAAW,OAAA,GAA7BI,CAAAA,CAA6B,QAAYC,CAAAA,CAAAA,CAErCR,CAAAA,CAAe,CACftB,CAAAA,CAAI,sCAAsC,EAE1C,GAAM,CAAE,UAAA,CAAAqC,CAAW,EAAI,MAAM,OAAO,iCAAwB,CAAA,CAC5DnC,CAAAA,CAAcmC,EAAW,qBAAA,CACrBf,CAAAA,CACAC,CAAAA,CACAE,CAAAA,CACA1B,CACJ,CAAA,CACAC,CAAAA,CAAI,qCAAqC,CAAA,CAEzC,IAAMsC,EAAW,WAAA,CAAY,IAAM,CAC3B,MAAA,CAAO,KAAKhC,CAAe,CAAA,CAAE,OAAS,CAAA,CAAG,aAAA,CAAcgC,CAAQ,CAAA,CAC9DhC,CAAAA,CAAkBiC,CAAAA,CAAgB,yBAAA,CAA2B,EAAE,EACxE,EAAG,GAAI,EACX,CAEA,GAAIb,CAAAA,CAAgB,CAChB1B,CAAAA,CAAI,mCAAmC,CAAA,CAEvC,GAAM,CAAE,OAAA,CAAAwC,CAAQ,EAAI,MAAM,OAAO,8BAAqB,CAAA,CACtDpC,CAAAA,CAAWoC,EAAQ,kBAAA,CAAmBd,CAAAA,CAAgB3B,CAAM,CAAA,CAC5DC,CAAAA,CAAI,kCAAkC,EAC1C,CAEAA,CAAAA,CAAI,gDAAgD,EACxD,CAAA,MAASb,CAAAA,CAAK,CACV,OAAA,CAAQ,IAAA,CAAK,kCAAmCA,CAAG,EACvD,CACJ,CAAA,CAyBMsD,EAAiBC,CAAAA,EAAoC,CACvD1C,EAAI,qCAAA,CAAuC0C,CAAU,EAErD,GAAM,CAAE,OAAA,CAAAC,CAAAA,CAAS,GAAGC,CAAK,CAAA,CAAIF,EACvBG,CAAAA,CAAgBF,CAAAA,EAAW1B,GAAM,CAEvC,GAAIf,CAAAA,CAAa,CACb,IAAM4C,CAAAA,CAAgC,CAAE,GAAGF,CAAK,CAAA,CAC5CD,GAAW,CAACR,kBAAAA,CAAOQ,CAAO,CAAA,GAAGG,EAAO,OAAA,CAAUH,CAAAA,CAAAA,CAC9CE,IACAC,CAAAA,CAAO,EAAA,CAAKD,EACZC,CAAAA,CAAO,OAAA,CAAUD,CAAAA,CAAAA,CAErB7C,CAAAA,CAAI,kDAAmD8C,CAAM,CAAA,CAC7D5C,EAAY,aAAA,CAAc4C,CAAM,EACpC,CAEAzC,CAAAA,CAAY,CACR,GAAGA,EACH,GAAG,MAAA,CAAO,YAAY,MAAA,CAAO,OAAA,CAAQuC,CAAI,CAAA,CAAE,MAAA,CAAO,CAAC,EAAGG,CAAC,CAAA,GAAMA,IAAM,MAAS,CAAC,EAC7E,GAAIJ,CAAAA,GAAY,MAAA,EAAa,CAACR,mBAAOQ,CAAO,CAAA,EAAK,CAAE,OAAA,CAAAA,CAAQ,CAC/D,CAAA,CAEA3C,CAAAA,CAAI,mCAAA,CAAqCK,CAAS,EACtD,CAAA,CAEM2C,CAAAA,CAAmBC,GAAe/C,CAAAA,EAAa,eAAA,CAAgB+C,CAAE,CAAA,EAAG,gBAAA,EAAkB,IAAA,CAEtFV,CAAAA,CAAkB,CACpBU,CAAAA,CACAC,CAAAA,GACChD,GAAa,eAAA,CAAgB+C,CAAAA,CAAcC,CAAY,CAAA,CAEtDC,CAAAA,CAAsB,SAAY,MAAMjD,GAAa,SAAA,EAAU,CAC/DkD,EAAeC,CAAAA,EAAgBnD,CAAAA,EAAa,KAAKmD,CAAG,CAAA,CACpDC,CAAAA,CAAUC,CAAAA,EAAiBrD,GAAa,MAAA,CAAOqD,CAAI,EAEnDtC,CAAAA,CAAQ,IAAM,CAChB,IAAME,CAAAA,CAAShB,CAAAA,EAAc,SAAA,IAAe,EAAA,CAC5C,OAAOgB,GAAU,CAACgB,kBAAAA,CAAOhB,CAAM,CAAA,CAAIA,CAAAA,CAAS,EAChD,CAAA,CAyPMqC,EAAoB,CACtB,UAAA,CAAAnC,EACA,aAAA,CAAAoB,CAAAA,CACA,cAvLkB,CAACE,CAAAA,CAAkBvB,CAAAA,GAAiC,CACtE,IAAMqC,CAAAA,CAAiBd,CAAAA,EAAW1B,GAAM,CACxC,GAAI,CAACwC,CAAAA,CAAgB,CACjBzD,CAAAA,CAAI,qDAAgD,EACpD,MACJ,CAEAA,EAAI,wBAAA,CAA0B,CAAE,QAASyD,CAAAA,CAAgB,MAAA,CAAArC,CAAO,CAAC,EAGjE,IAAMsC,CAAAA,CAAeC,GAA4B,CAC7C,GAAI,CAACA,CAAAA,CAAG,OAAOA,CAAAA,CACf,GAAM,CAAE,KAAA,CAAAC,CAAAA,CAAO,GAAGC,CAAK,CAAA,CAAIF,EAC3B,OAAO,CAAE,GAAGE,CAAAA,CAAM,GAAID,CAAAA,EAAS,CAAE,YAAaE,kBAAAA,CAAgBF,CAAK,CAAE,CAAG,CAC5E,CAAA,CAGMG,CAAAA,CAAuB3C,GAAQ,WAAA,GAAgB,MAAA,EAAaA,GAAQ,OAAA,GAAY,MAAA,CAClF4C,EAAmBC,CAAAA,CACvB,GAAIF,CAAAA,CAAsB,CAEtB,GAAM,CAAE,WAAA,CAAAG,EAAa,OAAA,CAAAC,CAAAA,CAAS,GAAGC,CAAa,CAAA,CAAIhD,CAAAA,CAClD4C,CAAAA,CAAoBN,EAAY,CAAE,GAAGU,EAAc,GAAGF,CAAY,CAAC,CAAA,CACnED,CAAAA,CAAgBP,CAAAA,CAAY,CAAE,GAAGU,CAAAA,CAAc,GAAGD,CAAQ,CAAC,EAC/D,MACIH,CAAAA,CAAoBN,CAAAA,CAAYtC,CAAM,CAAA,CACtC6C,EAAgBP,CAAAA,CAAYtC,CAAM,EAIlCjB,CAAAA,GACIA,CAAAA,CAAa,iBACbH,CAAAA,CAAI,8CAAA,CAAgD,CAChD,OAAA,CAASyD,EACT,MAAA,CAAQO,CACZ,CAAC,CAAA,CACD7D,CAAAA,CAAa,cAAcsD,CAAAA,CAAgBO,CAAiB,CAAA,EAEvDxD,CAAAA,CAAwB,KAAK6D,CAAAA,EAAQA,CAAAA,CAAK,SAAWZ,CAAc,CAAA,GACpEzD,EAAI,0EAAA,CAAuE,CACvE,OAAA,CAASyD,CACb,CAAC,CAAA,CACDjD,CAAAA,CAAwB,KAAK,CAAE,MAAA,CAAQiD,EAAgB,MAAA,CAAQO,CAAkB,CAAC,CAAA,CAAA,CAAA,CAM1F5D,GAAU,eAAA,EAAmB6D,CAAAA,GAC7BjE,EAAI,0CAAA,CAA4C,CAAE,QAASyD,CAAAA,CAAgB,MAAA,CAAQQ,CAAc,CAAC,EAClG7D,CAAAA,CAAS,aAAA,CAAcqD,EAAgBQ,CAAuC,CAAA,EAEtF,EAoII,wBAAA,CA1B6B,CAAC,CAC9B,OAAA,CAAAtB,EACA,KAAA,CAAAiB,CAAAA,CACA,SAAAU,CAAAA,CACA,oBAAA,CAAAC,CACJ,CAAA,GAKY,CACRvE,EAAI,mCAAA,CAAqC,CAAE,QAAA2C,CAAQ,CAAC,EAChDvC,CAAAA,EAAU,eAAA,EACVJ,EAAI,qEAAA,CAAuE,CAAE,OAAA,CAAA2C,CAAQ,CAAC,CAAA,CACtFvC,CAAAA,CAAS,yBAAyB,CAAE,OAAA,CAAAuC,EAAS,KAAA,CAAAiB,CAAAA,CAAO,QAAA,CAAAU,CAAAA,CAAU,qBAAAC,CAAqB,CAAC,GAEpFvE,CAAAA,CAAI,mEAA8D,EAE1E,CAAA,CASI,eAAA,CAAAgD,CAAAA,CACA,eAAA,CAAAT,EACA,mBAAA,CAAAY,CAAAA,CACA,YAAAC,CAAAA,CACA,MAAA,CAAAE,EACA,KAAA,CAAArC,CAAAA,CACA,cAAA,CAlQmB,IAAMd,GAAc,cAAA,EAAe,EAAK,GAmQ3D,UAAA,CAhHe,CAACS,EAAe4D,CAAAA,GAAwC,CACvE,IAAMrD,CAAAA,CAASF,GAAM,CAErBjB,CAAAA,CAAI,sBAAuB,CAAE,KAAA,CAAAY,EAAO,cAAA,CAAA4D,CAAAA,CAAgB,MAAA,CAAArD,CAAAA,CAAQ,UAAAd,CAAU,CAAC,EAEvE,IAAMoE,CAAAA,CAAgB,CAClB,GAAGpE,CAAAA,CACH,GAAGmE,CAAAA,CACH,GAAIrD,CAAAA,EAAU,CAACd,EAAU,OAAA,EAAW,CAAE,QAASc,CAAO,CAC1D,CAAA,CAKA,GAHAnB,EAAI,4BAAA,CAA8B,CAAE,MAAAY,CAAAA,CAAO,aAAA,CAAA6D,CAAc,CAAC,CAAA,CAGtD,EADgB,EAAE7D,KAASN,CAAAA,CAAAA,EAAoBA,CAAAA,CAAgBM,CAAe,CAAA,CAAA,CAChE,CACdZ,EAAI,+DAAA,CAA4D,CAAE,KAAA,CAAAY,CAAM,CAAC,CAAA,CACzE,MACJ,CAGA,IAAM8D,CAAAA,CAA4BvE,GAAc,eAAA,CAChD,GAAI,CAAC,SAAA,CAAU,QAAU,CAACuE,CAAAA,CACjBA,GAID1E,CAAAA,CAAI,qDAAA,CAAkD,CAAE,KAAA,CAAAY,CAAM,CAAC,CAAA,CAC/DL,EAAoB,IAAA,CAAK,CAAE,MAAAK,CAAAA,CAAO,OAAA,CAAS6D,CAAc,CAAC,CAAA,GAJ1DzE,CAAAA,CAAI,+EAAA,CAA4E,CAAE,KAAA,CAAAY,CAAM,CAAC,CAAA,CACzF9B,CAAAA,CAAoB8B,EAAiB6D,CAAa,CAAA,CAAA,CAAA,KAKnD,CAEClE,CAAAA,CAAoB,OAAS,CAAA,GAC7BP,CAAAA,CAAI,yBAAyBO,CAAAA,CAAoB,MAAM,yCAAyC,CAAA,CAChGA,CAAAA,CAAoB,OAAA,CAAQoE,CAAAA,EAAS,CACjC,IAAMC,CAAAA,CAAwB9D,mBAAY6D,CAAAA,CAAM,OAAO,EACvDxE,CAAAA,EAAc,KAAA,CAAMwE,EAAM,KAAA,CAAOC,CAAqB,EAC1D,CAAC,CAAA,CACDrE,EAAsB,EAAC,CAAA,CAI3B,IAAMsE,CAAAA,CAAkB/D,kBAAAA,CAAY2D,CAAa,CAAA,CACjDzE,EAAI,2CAAA,CAA6C,CAAE,MAAAY,CAAAA,CAAO,OAAA,CAASiE,CAAgB,CAAC,CAAA,CACpF1E,CAAAA,EAAc,KAAA,CAAMS,EAAOiE,CAAe,EAC9C,CAGA,GAAIzE,CAAAA,EAAU,gBAAiB,CAC3B,IAAM0E,CAAAA,CAAwB,CAAC,YAAa,eAAA,CAAiB,WAAA,CAAa,UAAW,YAAY,CAAA,CAC3FC,EAAoBC,kBAAAA,CAAcP,CAAa,CAAA,CAC/CQ,CAAAA,CAAkBnE,mBACpB,MAAA,CAAO,WAAA,CACH,OAAO,OAAA,CAAQiE,CAAiB,EAAE,MAAA,CAAO,CAAC,CAAC1B,CAAG,IAAM,CAACyB,CAAAA,CAAsB,SAASzB,CAAU,CAAC,CACnG,CACJ,CAAA,CACArD,CAAAA,CAAI,uCAAA,CAAyC,CAAE,KAAA,CAAAY,CAAAA,CAAO,QAASqE,CAAgB,CAAC,EAChF7E,CAAAA,CAAS,OAAA,CAAQQ,CAAAA,CAAiBqE,CAAe,EACrD,CACJ,CAAA,CAuDI,aAfiB,KAAO,CAAE,GAAI/E,CAAAA,CAAa,QAAA,CAAUC,CAAAA,CAAc,OAAA,CAASC,CAAS,CAAA,CAAA,CAgBrF,QAAA,CAlPa,CAAC8E,CAAAA,CAAsBC,CAAAA,CAAW,YAAanG,CAAAA,GAAyC,CACrG,IAAMmC,CAAAA,CAASF,GAAM,CAErBjB,CAAAA,CAAI,oBAAqB,CAAE,YAAA,CAAAkF,EAAc,QAAA,CAAAC,CAAAA,CAAU,UAAA,CAAAnG,CAAAA,CAAY,OAAAmC,CAAO,CAAC,EAGnEhB,CAAAA,EAAc,eAAA,EACdH,EAAI,6CAAA,CAA+C,CAAE,YAAA,CAAAkF,CAAAA,CAAc,SAAAC,CAAS,CAAC,EAC7EhF,CAAAA,CAAa,QAAA,CAAS+E,EAAcC,CAAAA,CAAUhE,CAAAA,CAAQnC,CAAU,CAAA,GAEhEgB,EAAI,iFAAA,CAA8E,CAAE,aAAAkF,CAAa,CAAC,EAClG9F,CAAAA,CAAuB8F,CAAAA,CAAc,CAAE,QAAA,CAAAC,EAAU,GAAGnG,CAAW,CAAC,CAAA,EAKxE,CAAA,CAmOI,MA7IU,IAAM,CAChBgB,CAAAA,CAAI,iCAAiC,EAEjCG,CAAAA,EAAc,eAAA,GACdH,EAAI,+BAA+B,CAAA,CACnCG,EAAa,KAAA,EAAM,CAAA,CAEnBC,CAAAA,EAAU,eAAA,GACVJ,EAAI,2BAA2B,CAAA,CAC/BI,EAAS,KAAA,EAAM,EAEvB,CAmIA,CAAA,CAEA,OAAI,OAAO,MAAA,CAAW,GAAA,GAClB,OAAO,iBAAA,CAAoBoD,CAAAA,CAAAA,CAGxBA,CACX,CAEO,IAAM4B,EAAYvF,CAAAA","file":"index.js","sourcesContent":["export const CACHE_STORAGE_EVENTS = 'cached_analytics_events'\nexport const CACHE_STORAGE_PAGES = 'cached_analytics_page_views'\n\nexport type CachedEvent = {\n name: string\n properties: Record<string, unknown>\n timestamp: number\n}\n\nexport type CachedPageView = {\n name: string\n properties?: Record<string, unknown>\n timestamp: number\n}\n\nexport const cacheEventToStorage = (eventName: string, properties: Record<string, unknown>): void => {\n try {\n const existingCache = localStorage.getItem(CACHE_STORAGE_EVENTS)\n const events: CachedEvent[] = existingCache ? JSON.parse(existingCache) : []\n events.push({ name: eventName, properties, timestamp: Date.now() })\n localStorage.setItem(CACHE_STORAGE_EVENTS, JSON.stringify(events))\n } catch (err) {\n console.warn('Analytics: Failed to cache event', err)\n }\n}\n\nexport const cachePageViewToStorage = (pageName: string, properties?: Record<string, unknown>): void => {\n try {\n const existingCache = localStorage.getItem(CACHE_STORAGE_PAGES)\n const pages: CachedPageView[] = existingCache ? JSON.parse(existingCache) : []\n pages.push({ name: pageName, properties, timestamp: Date.now() })\n localStorage.setItem(CACHE_STORAGE_PAGES, JSON.stringify(pages))\n } catch (err) {\n console.warn('Analytics: Failed to cache page view', err)\n }\n}\n\nexport const getCachedEvents = (): CachedEvent[] => {\n try {\n const storedEventsString = localStorage.getItem(CACHE_STORAGE_EVENTS)\n if (storedEventsString) {\n const events = JSON.parse(storedEventsString)\n return Array.isArray(events) ? events : []\n }\n } catch (err) {\n console.warn('Analytics: Failed to get cached events', err)\n }\n return []\n}\n\nexport const getCachedPageViews = (): CachedPageView[] => {\n try {\n const storedPagesString = localStorage.getItem(CACHE_STORAGE_PAGES)\n if (storedPagesString) {\n const pages = JSON.parse(storedPagesString)\n return Array.isArray(pages) ? pages : []\n }\n } catch (err) {\n console.warn('Analytics: Failed to get cached pages', err)\n }\n return []\n}\n\nexport const clearCachedEvents = (): void => {\n try {\n localStorage.removeItem(CACHE_STORAGE_EVENTS)\n } catch (err) {\n console.warn('Analytics: Failed to clear cached events', err)\n }\n}\n\nexport const clearCachedPageViews = (): void => {\n try {\n localStorage.removeItem(CACHE_STORAGE_PAGES)\n } catch (err) {\n console.warn('Analytics: Failed to clear cached page views', err)\n }\n}\n","import { RudderStack } from './providers/rudderstack'\nimport {\n cacheEventToStorage,\n cachePageViewToStorage,\n getCachedEvents,\n getCachedPageViews,\n clearCachedEvents,\n clearCachedPageViews,\n} from './utils/storage'\nimport { isUUID, getCountry, cleanObject, flattenObject, createLogger, isInternalEmail } from './utils/helpers'\n// Optional Growthbook types - only import if using Growthbook\nimport type { Growthbook, GrowthbookConfigs } from './providers/growthbook'\nimport type { TGrowthbookAttributes, TGrowthbookOptions } from './providers/growthbookTypes'\n\n// Optional Posthog types - only import if using Posthog\nimport type { Posthog } from './providers/posthog'\nimport type { TPosthogIdentifyTraits, TPosthogOptions } from './providers/posthogTypes'\n\ndeclare global {\n interface Window {\n AnalyticsInstance: ReturnType<typeof createAnalyticsInstance>\n }\n}\n\n/**\n * Configuration options for initializing the analytics instance\n */\ntype Options = {\n /** GrowthBook client API key for A/B testing and feature flags */\n growthbookKey?: string\n /** GrowthBook decryption key for encrypted feature payloads */\n growthbookDecryptionKey?: string\n /** RudderStack write key for event tracking */\n rudderstackKey?: string\n /** Additional configuration options for GrowthBook */\n growthbookOptions?: TGrowthbookOptions\n /** PostHog configuration options including API keys and settings */\n posthogOptions?: TPosthogOptions\n /** Enable debug logging — logs all analytics calls prefixed with [ANALYTIC] */\n debug?: boolean\n}\n\n/**\n * Creates a unified analytics instance that integrates RudderStack and GrowthBook.\n *\n * This function provides a centralized interface for:\n * - Event tracking across multiple analytics platforms\n * - A/B testing and feature flag management via GrowthBook\n * - Offline event caching with automatic replay\n *\n * @param {Options} _options - Optional initialization configuration\n * @returns {Object} Analytics instance with methods for tracking, identification, and feature management\n *\n * @example\n * ```typescript\n * const analytics = createAnalyticsInstance();\n *\n * // Initialize with providers\n * await analytics.initialise({\n * rudderstackKey: 'YOUR_RS_KEY',\n * growthbookKey: 'YOUR_GB_KEY',\n * growthbookDecryptionKey: 'YOUR_GB_DECRYPT_KEY'\n * });\n *\n * // Set user attributes\n * analytics.setAttributes({\n * user_id: 'user123',\n * country: 'US',\n * user_language: 'en'\n * });\n *\n * // Track events\n * analytics.trackEvent('button_clicked', { button_name: 'signup' });\n *\n * // Track page views\n * analytics.pageView('/dashboard', 'Deriv App');\n * ```\n */\nexport function createAnalyticsInstance(_options?: Options) {\n let _debug = _options?.debug ?? false\n\n const log = createLogger('', () => _debug)\n\n let _growthbook: Growthbook | undefined,\n _rudderstack: RudderStack,\n _posthog: Posthog | undefined,\n core_data: Record<string, any> = {},\n tracking_config: { [key: string]: boolean } = {},\n offline_event_cache: Array<{ event: string; payload: Record<string, any> }> = [],\n _pending_identify_calls: Array<{ userId: string; traits?: Record<string, any> }> = [],\n _storage_cache_processed = false\n\n const processStorageCache = () => {\n if (_storage_cache_processed) return\n if (!_rudderstack?.has_initialized) return\n\n _storage_cache_processed = true\n\n try {\n const storedEvents = getCachedEvents()\n if (storedEvents.length > 0) {\n log(`processStorageCache | replaying ${storedEvents.length} cached event(s)`, storedEvents)\n storedEvents.forEach(event => {\n const cleaned_properties = cleanObject(event.properties)\n _rudderstack?.track(event.name, cleaned_properties)\n })\n clearCachedEvents()\n }\n\n const storedPages = getCachedPageViews()\n if (storedPages.length > 0) {\n log(`processStorageCache | replaying ${storedPages.length} cached page view(s)`, storedPages)\n storedPages.forEach(page => {\n _rudderstack?.pageView(page.name, 'Deriv App', getId(), page.properties)\n })\n clearCachedPageViews()\n }\n } catch (err) {\n console.warn('Analytics: Failed to process storage cache', err)\n }\n }\n\n const onSdkLoaded = () => {\n log('onSdkLoaded | RudderStack SDK loaded')\n processStorageCache()\n\n if (_pending_identify_calls.length > 0) {\n log(`onSdkLoaded | flushing ${_pending_identify_calls.length} pending identify call(s)`)\n }\n _pending_identify_calls.forEach(({ userId, traits }) => {\n if (userId) {\n _rudderstack?.identifyEvent(userId, traits)\n }\n })\n _pending_identify_calls = []\n }\n\n /**\n * Initializes the analytics instance with specified provider configurations.\n * This method should be called before tracking any events.\n *\n * Features:\n * - Lazy-loads providers (GrowthBook, PostHog) only when configured\n * - Automatically fetches user's country for GrowthBook targeting\n * - Processes any cached events from previous sessions\n * - Sets up event tracking callback for GrowthBook experiments\n *\n * @param {Options} options - Configuration options for analytics providers\n * @returns {Promise<void>} Resolves when initialization is complete\n *\n * @example\n * ```typescript\n * await analytics.initialise({\n * rudderstackKey: 'YOUR_RS_KEY',\n * growthbookKey: 'YOUR_GB_KEY',\n * growthbookDecryptionKey: 'YOUR_GB_DECRYPT_KEY',\n * posthogOptions: {\n * apiKey: 'YOUR_POSTHOG_API_KEY',\n * config: {\n * session_recording: {\n * recordCrossOriginIframes: true,\n * minimumDurationMilliseconds: 30000\n * }\n * }\n * }\n * });\n * ```\n */\n const initialise = async ({\n growthbookKey,\n growthbookDecryptionKey,\n rudderstackKey,\n growthbookOptions,\n posthogOptions,\n debug,\n }: Options) => {\n if (debug !== undefined) _debug = debug\n\n log('initialise | starting analytics initialization', {\n rudderstack: !!rudderstackKey,\n growthbook: !!growthbookKey,\n posthog: !!posthogOptions,\n })\n\n try {\n // Only fetch country if GrowthBook is enabled and country not provided\n const country = growthbookOptions?.attributes?.country || (growthbookKey ? await getCountry() : undefined)\n\n if (rudderstackKey) {\n log('initialise | initializing RudderStack')\n _rudderstack = RudderStack.getRudderStackInstance(rudderstackKey, onSdkLoaded, _debug)\n }\n\n if (growthbookOptions?.attributes && Object.keys(growthbookOptions.attributes).length > 0) {\n const attrs = growthbookOptions.attributes\n const anonymousId = _rudderstack?.getAnonymousId()\n\n core_data = {\n ...core_data,\n country,\n ...(attrs.user_language && { user_language: attrs.user_language }),\n ...(attrs.account_type && { account_type: attrs.account_type }),\n ...(attrs.app_id && { app_id: attrs.app_id }),\n ...(attrs.residence_country && { residence_country: attrs.residence_country }),\n ...(attrs.device_type && { device_type: attrs.device_type }),\n ...(attrs.url && { url: attrs.url }),\n ...(attrs.email_hash && { email_hash: attrs.email_hash }),\n ...(attrs.network_type && { network_type: attrs.network_type }),\n ...(attrs.network_rtt && { network_rtt: attrs.network_rtt }),\n ...(attrs.network_downlink && { network_downlink: attrs.network_downlink }),\n ...(attrs.account_currency && { account_currency: attrs.account_currency }),\n ...(attrs.account_mode && { account_mode: attrs.account_mode }),\n loggedIn: !!attrs.loggedIn,\n ...(attrs.user_id && !isUUID(attrs.user_id) && { user_id: attrs.user_id }),\n ...(anonymousId && { anonymous_id: anonymousId }),\n }\n }\n\n growthbookOptions ??= {}\n growthbookOptions.attributes ??= {}\n const anonId = _rudderstack?.getAnonymousId()\n growthbookOptions.attributes.id ??= anonId\n growthbookOptions.attributes.country ??= country\n\n if (growthbookKey) {\n log('initialise | initializing GrowthBook')\n // Dynamically import Growthbook only when needed\n const { Growthbook } = await import('./providers/growthbook')\n _growthbook = Growthbook.getGrowthBookInstance(\n growthbookKey,\n growthbookDecryptionKey,\n growthbookOptions,\n _debug\n )\n log('initialise | GrowthBook initialized')\n\n const interval = setInterval(() => {\n if (Object.keys(tracking_config).length > 0) clearInterval(interval)\n else tracking_config = getFeatureValue('tracking-buttons-config', {}) as { [key: string]: boolean }\n }, 1000)\n }\n\n if (posthogOptions) {\n log('initialise | initializing PostHog')\n // Dynamically import Posthog only when needed\n const { Posthog } = await import('./providers/posthog')\n _posthog = Posthog.getPosthogInstance(posthogOptions, _debug)\n log('initialise | PostHog initialized')\n }\n\n log('initialise | analytics initialization complete')\n } catch (err) {\n console.warn('Analytics: Failed to initialize', err)\n }\n }\n\n /**\n * Sets user and context attributes for analytics tracking and targeting.\n * These attributes are automatically included in all subsequent events.\n *\n * Attributes are used for:\n * - Event enrichment (added to all tracked events)\n * - GrowthBook targeting (feature flags and A/B tests)\n * - User segmentation across analytics platforms\n *\n * @param {TCoreAttributes} attributes - User and context attributes\n *\n * @example\n * ```typescript\n * analytics.setAttributes({\n * user_id: 'CR123456',\n * country: 'US',\n * user_language: 'en',\n * device_type: 'desktop',\n * account_type: 'real',\n * loggedIn: true\n * });\n * ```\n */\n const setAttributes = (attributes: Record<string, any>) => {\n log('setAttributes | received attributes', attributes)\n\n const { user_id, ...rest } = attributes\n const user_identity = user_id ?? getId()\n\n if (_growthbook) {\n const config: TGrowthbookAttributes = { ...rest }\n if (user_id && !isUUID(user_id)) config.user_id = user_id\n if (user_identity) {\n config.id = user_identity\n config.user_id = user_identity\n }\n log('setAttributes | called GrowthBook setAttributes', config)\n _growthbook.setAttributes(config)\n }\n\n core_data = {\n ...core_data,\n ...Object.fromEntries(Object.entries(rest).filter(([, v]) => v !== undefined)),\n ...(user_id !== undefined && !isUUID(user_id) && { user_id }),\n }\n\n log('setAttributes | updated core_data', core_data)\n }\n\n const getFeatureState = (id: string) => _growthbook?.getFeatureState(id)?.experimentResult?.name\n\n const getFeatureValue = <K extends keyof GrowthbookConfigs, V extends GrowthbookConfigs[K]>(\n id: K,\n defaultValue: V\n ) => _growthbook?.getFeatureValue(id as string, defaultValue)\n\n const getGrowthbookStatus = async () => await _growthbook?.getStatus()\n const isFeatureOn = (key: string) => _growthbook?.isOn(key)\n const setUrl = (href: string) => _growthbook?.setUrl(href)\n\n const getId = () => {\n const userId = _rudderstack?.getUserId() || ''\n return userId && !isUUID(userId) ? userId : ''\n }\n\n const getAnonymousId = () => _rudderstack?.getAnonymousId() || ''\n\n /**\n * Tracks a page view event.\n *\n * Features:\n * - Automatically includes user ID if available\n * - Caches page views when offline or provider not initialized\n *\n * @param {string} current_page - The current page URL or path\n * @param {string} [platform='Deriv App'] - The platform name\n * @param {Record<string, unknown>} [properties] - Additional page properties\n *\n * @example\n * ```typescript\n * analytics.pageView('/dashboard');\n * analytics.pageView('/trade', 'Deriv Trader', { section: 'multipliers' });\n * ```\n */\n const pageView = (current_page: string, platform = 'Deriv App', properties?: Record<string, unknown>) => {\n const userId = getId()\n\n log('pageView | called', { current_page, platform, properties, userId })\n\n // Handle RudderStack pageView independently\n if (_rudderstack?.has_initialized) {\n log('pageView | sending page view to RudderStack', { current_page, platform })\n _rudderstack.pageView(current_page, platform, userId, properties)\n } else {\n log('pageView | RudderStack not initialized — caching page view to localStorage', { current_page })\n cachePageViewToStorage(current_page, { platform, ...properties })\n }\n\n // PostHog handles page views automatically via autocapture\n // No need to manually send page views to PostHog\n }\n\n /**\n * Identifies a user across analytics platforms.\n * This method should be called after user login or when user identity is known.\n *\n * Features:\n * - Queues identify calls if provider not yet initialized\n * - Allows custom traits for each provider or shared traits for both\n * - Identifies user in PostHog if configured\n *\n * @param {string} [user_id] - The user ID to identify. If not provided, uses stored user ID\n * @param {Record<string, any>} [traits] - Optional traits to send to both providers, or provider-specific traits\n *\n * @example\n * ```typescript\n * // Simple identify\n * analytics.identifyEvent('CR123456');\n *\n * // Identify with same traits for both providers\n * analytics.identifyEvent('CR123456', {\n * language: 'en',\n * country_of_residence: 'US'\n * });\n *\n * // Identify with provider-specific traits\n * analytics.identifyEvent('CR123456', {\n * rudderstack: { language: 'en', custom_field: 'value' },\n * posthog: { language: 'en', country_of_residence: 'US' }\n * });\n * ```\n */\n const identifyEvent = (user_id?: string, traits?: Record<string, any>) => {\n const stored_user_id = user_id || getId()\n if (!stored_user_id) {\n log('identifyEvent | skipped — no user_id available')\n return\n }\n\n log('identifyEvent | called', { user_id: stored_user_id, traits })\n\n // Strip PII: replace raw email with is_internal flag\n const sanitizePII = (t?: Record<string, any>) => {\n if (!t) return t\n const { email, ...safe } = t\n return { ...safe, ...(email && { is_internal: isInternalEmail(email) }) }\n }\n\n // Check if traits has provider-specific structure\n const hasProviderStructure = traits?.rudderstack !== undefined || traits?.posthog !== undefined\n let rudderstackTraits, posthogTraits\n if (hasProviderStructure) {\n // Merge shared top-level props with provider-specific ones (provider-specific wins on conflict)\n const { rudderstack, posthog, ...sharedTraits } = traits as any\n rudderstackTraits = sanitizePII({ ...sharedTraits, ...rudderstack })\n posthogTraits = sanitizePII({ ...sharedTraits, ...posthog })\n } else {\n rudderstackTraits = sanitizePII(traits)\n posthogTraits = sanitizePII(traits)\n }\n\n // Handle RudderStack identification independently\n if (_rudderstack) {\n if (_rudderstack.has_initialized) {\n log('identifyEvent | calling RudderStack identify', {\n user_id: stored_user_id,\n traits: rudderstackTraits,\n })\n _rudderstack.identifyEvent(stored_user_id, rudderstackTraits)\n } else {\n if (!_pending_identify_calls.some(call => call.userId === stored_user_id)) {\n log('identifyEvent | RudderStack not initialized — queuing identify call', {\n user_id: stored_user_id,\n })\n _pending_identify_calls.push({ userId: stored_user_id, traits: rudderstackTraits })\n }\n }\n }\n\n // Handle PostHog identification independently\n if (_posthog?.has_initialized && posthogTraits) {\n log('identifyEvent | calling PostHog identify', { user_id: stored_user_id, traits: posthogTraits })\n _posthog.identifyEvent(stored_user_id, posthogTraits as TPosthogIdentifyTraits)\n }\n }\n\n const reset = () => {\n log('reset | resetting all providers')\n // Reset each provider independently\n if (_rudderstack?.has_initialized) {\n log('reset | resetting RudderStack')\n _rudderstack.reset()\n }\n if (_posthog?.has_initialized) {\n log('reset | resetting PostHog')\n _posthog.reset()\n }\n }\n\n /**\n * Tracks a custom event with associated data.\n *\n * Features:\n * - Automatically enriches events with core attributes\n * - RudderStack: Caches events when offline or not initialized\n * - PostHog: Sends immediately if initialized (has built-in caching)\n * - Respects feature flag configurations\n * - Each provider works independently - one failing won't affect the other\n *\n * @param {string} event - The event name to track\n * @param {Record<string, any>} analytics_data - The event data payload\n */\n const trackEvent = (event: string, analytics_data: Record<string, any>) => {\n const userId = getId()\n\n log('trackEvent | called', { event, analytics_data, userId, core_data })\n\n const final_payload = {\n ...core_data,\n ...analytics_data,\n ...(userId && !core_data.user_id && { user_id: userId }),\n }\n\n log('trackEvent | built payload', { event, final_payload })\n\n const shouldTrack = !(event in tracking_config) || tracking_config[event as string]\n if (!shouldTrack) {\n log('trackEvent | skipped — event disabled by tracking_config', { event })\n return\n }\n\n // Handle RudderStack independently\n const hasRudderstackInitialized = _rudderstack?.has_initialized\n if (!navigator.onLine || !hasRudderstackInitialized) {\n if (!hasRudderstackInitialized) {\n log('trackEvent | RudderStack not initialized — caching event to localStorage', { event })\n cacheEventToStorage(event as string, final_payload)\n } else {\n log('trackEvent | offline — caching event to memory', { event })\n offline_event_cache.push({ event, payload: final_payload })\n }\n } else {\n // Send cached events to RudderStack\n if (offline_event_cache.length > 0) {\n log(`trackEvent | flushing ${offline_event_cache.length} offline cached event(s) to RudderStack`)\n offline_event_cache.forEach(cache => {\n const cleaned_cache_payload = cleanObject(cache.payload)\n _rudderstack?.track(cache.event, cleaned_cache_payload)\n })\n offline_event_cache = []\n }\n\n // Send current event to RudderStack\n const cleaned_payload = cleanObject(final_payload)\n log('trackEvent | sending event to RudderStack', { event, payload: cleaned_payload })\n _rudderstack?.track(event, cleaned_payload)\n }\n\n // Handle PostHog independently - send immediately if initialized\n if (_posthog?.has_initialized) {\n const posthog_excluded_keys = ['page_name', 'user_language', 'form_name', 'version', 'email_hash'] as const\n const flattened_payload = flattenObject(final_payload)\n const posthog_payload = cleanObject(\n Object.fromEntries(\n Object.entries(flattened_payload).filter(([key]) => !posthog_excluded_keys.includes(key as any))\n )\n )\n log('trackEvent | sending event to PostHog', { event, payload: posthog_payload })\n _posthog.capture(event as string, posthog_payload)\n }\n }\n\n /**\n * Ensures client_id is set in PostHog stored person properties.\n * Call this when the user ID is available and PostHog is loaded.\n * Useful for backfilling client_id for users identified in previous sessions.\n * No-op if client_id is already present or PostHog is not initialized.\n *\n * @param params.user_id - The user ID to use as client_id\n * @param params.email - The user's email, used to determine is_internal\n * @param params.language - The user's language (BCP 47 tag, e.g. \"en-GB\")\n * @param params.country_of_residence - The user's country of residence\n *\n * @example\n * ```typescript\n * if (window.posthog?.__loaded && userId) {\n * analytics.backfillPersonProperties({ user_id: userId, email, language, country_of_residence })\n * }\n * ```\n */\n const backfillPersonProperties = ({\n user_id,\n email,\n language,\n country_of_residence,\n }: {\n user_id: string\n email?: string\n language?: string\n country_of_residence?: string\n }): void => {\n log('backfillPersonProperties | called', { user_id })\n if (_posthog?.has_initialized) {\n log('backfillPersonProperties | backfilling person properties in PostHog', { user_id })\n _posthog.backfillPersonProperties({ user_id, email, language, country_of_residence })\n } else {\n log('backfillPersonProperties | skipped — PostHog not initialized')\n }\n }\n\n const getInstances = () => ({ ab: _growthbook, tracking: _rudderstack, posthog: _posthog })\n\n const AnalyticsInstance = {\n initialise,\n setAttributes,\n identifyEvent,\n backfillPersonProperties,\n getFeatureState,\n getFeatureValue,\n getGrowthbookStatus,\n isFeatureOn,\n setUrl,\n getId,\n getAnonymousId,\n trackEvent,\n getInstances,\n pageView,\n reset,\n }\n\n if (typeof window !== 'undefined') {\n window.AnalyticsInstance = AnalyticsInstance\n }\n\n return AnalyticsInstance\n}\n\nexport const Analytics = createAnalyticsInstance()\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/utils/storage.ts","../src/analytics.ts"],"names":["CACHE_STORAGE_EVENTS","CACHE_STORAGE_PAGES","cacheEventToStorage","eventName","properties","existingCache","events","err","cachePageViewToStorage","pageName","pages","getCachedEvents","storedEventsString","getCachedPageViews","storedPagesString","clearCachedEvents","clearCachedPageViews","createAnalyticsInstance","_options","_debug","log","createLogger","_growthbook","_rudderstack","_posthog","core_data","tracking_config","offline_event_cache","_pending_identify_calls","_storage_cache_processed","processStorageCache","storedEvents","event","cleaned_properties","cleanObject","storedPages","page","getId","onSdkLoaded","userId","traits","initialise","growthbookKey","growthbookDecryptionKey","rudderstackKey","growthbookOptions","posthogOptions","debug","_a","_b","country","getCountry","RudderStack","attrs","anonymousId","isUUID","anonId","Growthbook","interval","getFeatureValue","Posthog","setAttributes","attributes","user_id","rest","user_identity","config","v","getFeatureState","id","defaultValue","getGrowthbookStatus","isFeatureOn","key","setUrl","href","AnalyticsInstance","stored_user_id","sanitizePII","t","email","safe","isInternalEmail","hasProviderStructure","rudderstackTraits","posthogTraits","rudderstack","posthog","sharedTraits","call","language","country_of_residence","analytics_data","final_payload","hasRudderstackInitialized","cache","cleaned_cache_payload","cleaned_payload","posthog_payload","flattenObject","current_page","platform","Analytics"],"mappings":"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","file":"index.js","sourcesContent":["export const CACHE_STORAGE_EVENTS = 'cached_analytics_events'\nexport const CACHE_STORAGE_PAGES = 'cached_analytics_page_views'\n\nexport type CachedEvent = {\n name: string\n properties: Record<string, unknown>\n timestamp: number\n}\n\nexport type CachedPageView = {\n name: string\n properties?: Record<string, unknown>\n timestamp: number\n}\n\nexport const cacheEventToStorage = (eventName: string, properties: Record<string, unknown>): void => {\n try {\n const existingCache = localStorage.getItem(CACHE_STORAGE_EVENTS)\n const events: CachedEvent[] = existingCache ? JSON.parse(existingCache) : []\n events.push({ name: eventName, properties, timestamp: Date.now() })\n localStorage.setItem(CACHE_STORAGE_EVENTS, JSON.stringify(events))\n } catch (err) {\n console.warn('Analytics: Failed to cache event', err)\n }\n}\n\nexport const cachePageViewToStorage = (pageName: string, properties?: Record<string, unknown>): void => {\n try {\n const existingCache = localStorage.getItem(CACHE_STORAGE_PAGES)\n const pages: CachedPageView[] = existingCache ? JSON.parse(existingCache) : []\n pages.push({ name: pageName, properties, timestamp: Date.now() })\n localStorage.setItem(CACHE_STORAGE_PAGES, JSON.stringify(pages))\n } catch (err) {\n console.warn('Analytics: Failed to cache page view', err)\n }\n}\n\nexport const getCachedEvents = (): CachedEvent[] => {\n try {\n const storedEventsString = localStorage.getItem(CACHE_STORAGE_EVENTS)\n if (storedEventsString) {\n const events = JSON.parse(storedEventsString)\n return Array.isArray(events) ? events : []\n }\n } catch (err) {\n console.warn('Analytics: Failed to get cached events', err)\n }\n return []\n}\n\nexport const getCachedPageViews = (): CachedPageView[] => {\n try {\n const storedPagesString = localStorage.getItem(CACHE_STORAGE_PAGES)\n if (storedPagesString) {\n const pages = JSON.parse(storedPagesString)\n return Array.isArray(pages) ? pages : []\n }\n } catch (err) {\n console.warn('Analytics: Failed to get cached pages', err)\n }\n return []\n}\n\nexport const clearCachedEvents = (): void => {\n try {\n localStorage.removeItem(CACHE_STORAGE_EVENTS)\n } catch (err) {\n console.warn('Analytics: Failed to clear cached events', err)\n }\n}\n\nexport const clearCachedPageViews = (): void => {\n try {\n localStorage.removeItem(CACHE_STORAGE_PAGES)\n } catch (err) {\n console.warn('Analytics: Failed to clear cached page views', err)\n }\n}\n","import { RudderStack } from './providers/rudderstack'\nimport {\n cacheEventToStorage,\n cachePageViewToStorage,\n getCachedEvents,\n getCachedPageViews,\n clearCachedEvents,\n clearCachedPageViews,\n} from './utils/storage'\nimport { isUUID, getCountry, cleanObject, flattenObject, createLogger, isInternalEmail } from './utils/helpers'\n// Optional Growthbook types - only import if using Growthbook\nimport type { Growthbook, GrowthbookConfigs } from './providers/growthbook'\nimport type { TGrowthbookAttributes, TGrowthbookOptions } from './providers/growthbookTypes'\n\n// Optional Posthog types - only import if using Posthog\nimport type { Posthog } from './providers/posthog'\nimport type { TPosthogIdentifyTraits, TPosthogOptions } from './providers/posthogTypes'\n\ndeclare global {\n interface Window {\n AnalyticsInstance: ReturnType<typeof createAnalyticsInstance>\n }\n}\n\n/**\n * Configuration options for initializing the analytics instance\n */\ntype Options = {\n /** GrowthBook client API key for A/B testing and feature flags */\n growthbookKey?: string\n /** GrowthBook decryption key for encrypted feature payloads */\n growthbookDecryptionKey?: string\n /** RudderStack write key for event tracking */\n rudderstackKey?: string\n /** Additional configuration options for GrowthBook */\n growthbookOptions?: TGrowthbookOptions\n /** PostHog configuration options including API keys and settings */\n posthogOptions?: TPosthogOptions\n /** Enable debug logging — logs all analytics calls prefixed with [ANALYTIC] */\n debug?: boolean\n}\n\n/**\n * Creates a unified analytics instance that integrates RudderStack and GrowthBook.\n *\n * This function provides a centralized interface for:\n * - Event tracking across multiple analytics platforms\n * - A/B testing and feature flag management via GrowthBook\n * - Offline event caching with automatic replay\n *\n * @param {Options} _options - Optional initialization configuration\n * @returns {Object} Analytics instance with methods for tracking, identification, and feature management\n *\n * @example\n * ```typescript\n * const analytics = createAnalyticsInstance();\n *\n * // Initialize with providers\n * await analytics.initialise({\n * rudderstackKey: 'YOUR_RS_KEY',\n * growthbookKey: 'YOUR_GB_KEY',\n * growthbookDecryptionKey: 'YOUR_GB_DECRYPT_KEY'\n * });\n *\n * // Set user attributes\n * analytics.setAttributes({\n * user_id: 'user123',\n * country: 'US',\n * user_language: 'en'\n * });\n *\n * // Track events\n * analytics.trackEvent('button_clicked', { button_name: 'signup' });\n *\n * // Track page views\n * analytics.pageView('/dashboard', 'Deriv App');\n * ```\n */\nexport function createAnalyticsInstance(_options?: Options) {\n let _debug = _options?.debug ?? false\n\n const log = createLogger('', () => _debug)\n\n let _growthbook: Growthbook | undefined,\n _rudderstack: RudderStack,\n _posthog: Posthog | undefined,\n core_data: Record<string, any> = {},\n tracking_config: { [key: string]: boolean } = {},\n offline_event_cache: Array<{ event: string; payload: Record<string, any> }> = [],\n _pending_identify_calls: Array<{ userId: string; traits?: Record<string, any> }> = [],\n _storage_cache_processed = false\n\n const processStorageCache = () => {\n if (_storage_cache_processed) return\n if (!_rudderstack?.has_initialized) return\n\n _storage_cache_processed = true\n\n try {\n const storedEvents = getCachedEvents()\n if (storedEvents.length > 0) {\n log(`processStorageCache | replaying ${storedEvents.length} cached event(s)`, storedEvents)\n storedEvents.forEach(event => {\n const cleaned_properties = cleanObject(event.properties)\n _rudderstack?.track(event.name, cleaned_properties)\n })\n clearCachedEvents()\n }\n\n const storedPages = getCachedPageViews()\n if (storedPages.length > 0) {\n log(`processStorageCache | replaying ${storedPages.length} cached page view(s)`, storedPages)\n storedPages.forEach(page => {\n _rudderstack?.pageView(page.name, 'Deriv App', getId(), page.properties)\n })\n clearCachedPageViews()\n }\n } catch (err) {\n console.warn('Analytics: Failed to process storage cache', err)\n }\n }\n\n const onSdkLoaded = () => {\n log('onSdkLoaded | RudderStack SDK loaded')\n processStorageCache()\n\n if (_pending_identify_calls.length > 0) {\n log(`onSdkLoaded | flushing ${_pending_identify_calls.length} pending identify call(s)`)\n }\n _pending_identify_calls.forEach(({ userId, traits }) => {\n if (userId) {\n _rudderstack?.identifyEvent(userId, traits)\n }\n })\n _pending_identify_calls = []\n }\n\n /**\n * Initializes the analytics instance with specified provider configurations.\n * This method should be called before tracking any events.\n *\n * Features:\n * - Lazy-loads providers (GrowthBook, PostHog) only when configured\n * - Automatically fetches user's country for GrowthBook targeting\n * - Processes any cached events from previous sessions\n * - Sets up event tracking callback for GrowthBook experiments\n *\n * @param {Options} options - Configuration options for analytics providers\n * @returns {Promise<void>} Resolves when initialization is complete\n *\n * @example\n * ```typescript\n * await analytics.initialise({\n * rudderstackKey: 'YOUR_RS_KEY',\n * growthbookKey: 'YOUR_GB_KEY',\n * growthbookDecryptionKey: 'YOUR_GB_DECRYPT_KEY',\n * posthogOptions: {\n * apiKey: 'YOUR_POSTHOG_API_KEY',\n * config: {\n * session_recording: {\n * recordCrossOriginIframes: true,\n * minimumDurationMilliseconds: 30000\n * }\n * }\n * }\n * });\n * ```\n */\n const initialise = async ({\n growthbookKey,\n growthbookDecryptionKey,\n rudderstackKey,\n growthbookOptions,\n posthogOptions,\n debug,\n }: Options) => {\n if (debug !== undefined) _debug = debug\n\n log('initialise | starting analytics initialization', {\n rudderstack: !!rudderstackKey,\n growthbook: !!growthbookKey,\n posthog: !!posthogOptions,\n })\n\n try {\n // Only fetch country if GrowthBook is enabled and country not provided\n const country = growthbookOptions?.attributes?.country || (growthbookKey ? await getCountry() : undefined)\n\n if (rudderstackKey) {\n log('initialise | initializing RudderStack')\n _rudderstack = RudderStack.getRudderStackInstance(rudderstackKey, onSdkLoaded, _debug)\n }\n\n if (growthbookOptions?.attributes && Object.keys(growthbookOptions.attributes).length > 0) {\n const attrs = growthbookOptions.attributes\n const anonymousId = _rudderstack?.getAnonymousId()\n\n core_data = {\n ...core_data,\n country,\n ...(attrs.user_language && { user_language: attrs.user_language }),\n ...(attrs.account_type && { account_type: attrs.account_type }),\n ...(attrs.app_id && { app_id: attrs.app_id }),\n ...(attrs.residence_country && { residence_country: attrs.residence_country }),\n ...(attrs.device_type && { device_type: attrs.device_type }),\n ...(attrs.url && { url: attrs.url }),\n ...(attrs.email_hash && { email_hash: attrs.email_hash }),\n ...(attrs.network_type && { network_type: attrs.network_type }),\n ...(attrs.network_rtt && { network_rtt: attrs.network_rtt }),\n ...(attrs.network_downlink && { network_downlink: attrs.network_downlink }),\n ...(attrs.account_currency && { account_currency: attrs.account_currency }),\n ...(attrs.account_mode && { account_mode: attrs.account_mode }),\n loggedIn: !!attrs.loggedIn,\n ...(attrs.user_id && !isUUID(attrs.user_id) && { user_id: attrs.user_id }),\n ...(anonymousId && { anonymous_id: anonymousId }),\n }\n }\n\n growthbookOptions ??= {}\n growthbookOptions.attributes ??= {}\n const anonId = _rudderstack?.getAnonymousId()\n growthbookOptions.attributes.id ??= anonId\n growthbookOptions.attributes.country ??= country\n\n if (growthbookKey) {\n log('initialise | initializing GrowthBook')\n // Dynamically import Growthbook only when needed\n const { Growthbook } = await import('./providers/growthbook')\n _growthbook = Growthbook.getGrowthBookInstance(\n growthbookKey,\n growthbookDecryptionKey,\n growthbookOptions,\n _debug\n )\n log('initialise | GrowthBook initialized')\n\n const interval = setInterval(() => {\n if (Object.keys(tracking_config).length > 0) clearInterval(interval)\n else tracking_config = getFeatureValue('tracking-buttons-config', {}) as { [key: string]: boolean }\n }, 1000)\n }\n\n if (posthogOptions) {\n log('initialise | initializing PostHog')\n // Dynamically import Posthog only when needed\n const { Posthog } = await import('./providers/posthog')\n _posthog = Posthog.getPosthogInstance(posthogOptions, _debug)\n log('initialise | PostHog initialized')\n }\n\n log('initialise | analytics initialization complete')\n } catch (err) {\n console.warn('Analytics: Failed to initialize', err)\n }\n }\n\n /**\n * Sets user and context attributes for analytics tracking and targeting.\n * These attributes are automatically included in all subsequent events.\n *\n * Attributes are used for:\n * - Event enrichment (added to all tracked events)\n * - GrowthBook targeting (feature flags and A/B tests)\n * - User segmentation across analytics platforms\n *\n * @param {TCoreAttributes} attributes - User and context attributes\n *\n * @example\n * ```typescript\n * analytics.setAttributes({\n * user_id: 'CR123456',\n * country: 'US',\n * user_language: 'en',\n * device_type: 'desktop',\n * account_type: 'real',\n * loggedIn: true\n * });\n * ```\n */\n const setAttributes = (attributes: Record<string, any>) => {\n log('setAttributes | received attributes', attributes)\n\n const { user_id, ...rest } = attributes\n const user_identity = user_id ?? getId()\n\n if (_growthbook) {\n const config: TGrowthbookAttributes = { ...rest }\n if (user_id && !isUUID(user_id)) config.user_id = user_id\n if (user_identity) {\n config.id = user_identity\n config.user_id = user_identity\n }\n log('setAttributes | called GrowthBook setAttributes', config)\n _growthbook.setAttributes(config)\n }\n\n core_data = {\n ...core_data,\n ...Object.fromEntries(Object.entries(rest).filter(([, v]) => v !== undefined)),\n ...(user_id !== undefined && !isUUID(user_id) && { user_id }),\n }\n\n log('setAttributes | updated core_data', core_data)\n }\n\n const getFeatureState = (id: string) => _growthbook?.getFeatureState(id)?.experimentResult?.name\n\n const getFeatureValue = <K extends keyof GrowthbookConfigs, V extends GrowthbookConfigs[K]>(\n id: K,\n defaultValue: V\n ) => _growthbook?.getFeatureValue(id as string, defaultValue)\n\n const getGrowthbookStatus = async () => await _growthbook?.getStatus()\n const isFeatureOn = (key: string) => _growthbook?.isOn(key)\n const setUrl = (href: string) => _growthbook?.setUrl(href)\n\n const getId = () => {\n const userId = _rudderstack?.getUserId() || ''\n return userId && !isUUID(userId) ? userId : ''\n }\n\n const getAnonymousId = () => _rudderstack?.getAnonymousId() || ''\n\n /**\n * Tracks a page view event.\n *\n * Features:\n * - Automatically includes user ID if available\n * - Caches page views when offline or provider not initialized\n *\n * @param {string} current_page - The current page URL or path\n * @param {string} [platform='Deriv App'] - The platform name\n * @param {Record<string, unknown>} [properties] - Additional page properties\n *\n * @example\n * ```typescript\n * analytics.pageView('/dashboard');\n * analytics.pageView('/trade', 'Deriv Trader', { section: 'multipliers' });\n * ```\n */\n const pageView = (current_page: string, platform = 'Deriv App', properties?: Record<string, unknown>) => {\n const userId = getId()\n\n log('pageView | called', { current_page, platform, properties, userId })\n\n // Handle RudderStack pageView independently\n if (_rudderstack?.has_initialized) {\n log('pageView | sending page view to RudderStack', { current_page, platform })\n _rudderstack.pageView(current_page, platform, userId, properties)\n } else {\n log('pageView | RudderStack not initialized — caching page view to localStorage', { current_page })\n cachePageViewToStorage(current_page, { platform, ...properties })\n }\n\n // PostHog handles page views automatically via autocapture\n // No need to manually send page views to PostHog\n }\n\n /**\n * Identifies a user across analytics platforms.\n * This method should be called after user login or when user identity is known.\n *\n * Features:\n * - Queues identify calls if provider not yet initialized\n * - Allows custom traits for each provider or shared traits for both\n * - Identifies user in PostHog if configured\n *\n * @param {string} [user_id] - The user ID to identify. If not provided, uses stored user ID\n * @param {Record<string, any>} [traits] - Optional traits to send to both providers, or provider-specific traits\n *\n * @example\n * ```typescript\n * // Simple identify\n * analytics.identifyEvent('CR123456');\n *\n * // Identify with same traits for both providers\n * analytics.identifyEvent('CR123456', {\n * language: 'en',\n * country_of_residence: 'US'\n * });\n *\n * // Identify with provider-specific traits\n * analytics.identifyEvent('CR123456', {\n * rudderstack: { language: 'en', custom_field: 'value' },\n * posthog: { language: 'en', country_of_residence: 'US' }\n * });\n * ```\n */\n const identifyEvent = (user_id?: string, traits?: Record<string, any>) => {\n const stored_user_id = user_id || getId()\n if (!stored_user_id) {\n log('identifyEvent | skipped — no user_id available')\n return\n }\n\n log('identifyEvent | called', { user_id: stored_user_id, traits })\n\n // Strip PII: replace raw email with is_internal flag\n const sanitizePII = (t?: Record<string, any>) => {\n if (!t) return t\n const { email, ...safe } = t\n return { ...safe, ...(email && { is_internal: isInternalEmail(email) }) }\n }\n\n // Check if traits has provider-specific structure\n const hasProviderStructure = traits?.rudderstack !== undefined || traits?.posthog !== undefined\n let rudderstackTraits, posthogTraits\n if (hasProviderStructure) {\n // Merge shared top-level props with provider-specific ones (provider-specific wins on conflict)\n const { rudderstack, posthog, ...sharedTraits } = traits as any\n rudderstackTraits = sanitizePII({ ...sharedTraits, ...rudderstack })\n posthogTraits = sanitizePII({ ...sharedTraits, ...posthog })\n } else {\n rudderstackTraits = sanitizePII(traits)\n posthogTraits = sanitizePII(traits)\n }\n\n // Handle RudderStack identification independently\n if (_rudderstack) {\n if (_rudderstack.has_initialized) {\n log('identifyEvent | calling RudderStack identify', {\n user_id: stored_user_id,\n traits: rudderstackTraits,\n })\n _rudderstack.identifyEvent(stored_user_id, rudderstackTraits)\n } else {\n if (!_pending_identify_calls.some(call => call.userId === stored_user_id)) {\n log('identifyEvent | RudderStack not initialized — queuing identify call', {\n user_id: stored_user_id,\n })\n _pending_identify_calls.push({ userId: stored_user_id, traits: rudderstackTraits })\n }\n }\n }\n\n // Handle PostHog identification independently\n if (_posthog?.has_initialized) {\n log('identifyEvent | calling PostHog identify', { user_id: stored_user_id, traits: posthogTraits })\n _posthog.identifyEvent(stored_user_id, posthogTraits as TPosthogIdentifyTraits)\n }\n }\n\n const reset = () => {\n log('reset | resetting all providers')\n // Reset each provider independently\n if (_rudderstack?.has_initialized) {\n log('reset | resetting RudderStack')\n _rudderstack.reset()\n }\n if (_posthog?.has_initialized) {\n log('reset | resetting PostHog')\n _posthog.reset()\n }\n }\n\n /**\n * Tracks a custom event with associated data.\n *\n * Features:\n * - Automatically enriches events with core attributes\n * - RudderStack: Caches events when offline or not initialized\n * - PostHog: Sends immediately if initialized (has built-in caching)\n * - Respects feature flag configurations\n * - Each provider works independently - one failing won't affect the other\n *\n * @param {string} event - The event name to track\n * @param {Record<string, any>} analytics_data - The event data payload\n */\n const trackEvent = (event: string, analytics_data: Record<string, any>) => {\n const userId = getId()\n\n log('trackEvent | called', { event, analytics_data, userId, core_data })\n\n const final_payload = {\n ...core_data,\n ...analytics_data,\n ...(userId && !core_data.user_id && { user_id: userId }),\n }\n\n log('trackEvent | built payload', { event, final_payload })\n\n const shouldTrack = !(event in tracking_config) || tracking_config[event as string]\n if (!shouldTrack) {\n log('trackEvent | skipped — event disabled by tracking_config', { event })\n return\n }\n\n // Handle RudderStack independently\n const hasRudderstackInitialized = _rudderstack?.has_initialized\n if (!navigator.onLine || !hasRudderstackInitialized) {\n if (!hasRudderstackInitialized) {\n log('trackEvent | RudderStack not initialized — caching event to localStorage', { event })\n cacheEventToStorage(event as string, final_payload)\n } else {\n log('trackEvent | offline — caching event to memory', { event })\n offline_event_cache.push({ event, payload: final_payload })\n }\n } else {\n // Send cached events to RudderStack\n if (offline_event_cache.length > 0) {\n log(`trackEvent | flushing ${offline_event_cache.length} offline cached event(s) to RudderStack`)\n offline_event_cache.forEach(cache => {\n const cleaned_cache_payload = cleanObject(cache.payload)\n _rudderstack?.track(cache.event, cleaned_cache_payload)\n })\n offline_event_cache = []\n }\n\n // Send current event to RudderStack\n const cleaned_payload = cleanObject(final_payload)\n log('trackEvent | sending event to RudderStack', { event, payload: cleaned_payload })\n _rudderstack?.track(event, cleaned_payload)\n }\n\n // Handle PostHog independently - send immediately if initialized\n if (_posthog?.has_initialized) {\n const posthog_payload = cleanObject(flattenObject(final_payload))\n log('trackEvent | sending event to PostHog', { event, payload: posthog_payload })\n _posthog.capture(event as string, posthog_payload)\n }\n }\n\n /**\n * Ensures client_id is set in PostHog stored person properties.\n * Call this when the user ID is available and PostHog is loaded.\n * Useful for backfilling client_id for users identified in previous sessions.\n * No-op if client_id is already present or PostHog is not initialized.\n *\n * @param params.user_id - The user ID to use as client_id\n * @param params.email - The user's email, used to determine is_internal\n * @param params.language - The user's language (BCP 47 tag, e.g. \"en-GB\")\n * @param params.country_of_residence - The user's country of residence\n *\n * @example\n * ```typescript\n * if (window.posthog?.__loaded && userId) {\n * analytics.backfillPersonProperties({ user_id: userId, email, language, country_of_residence })\n * }\n * ```\n */\n const backfillPersonProperties = ({\n user_id,\n email,\n language,\n country_of_residence,\n }: {\n user_id: string\n email?: string\n language?: string\n country_of_residence?: string\n }): void => {\n log('backfillPersonProperties | called', { user_id })\n if (_posthog?.has_initialized) {\n log('backfillPersonProperties | backfilling person properties in PostHog', { user_id })\n _posthog.backfillPersonProperties({ user_id, email, language, country_of_residence })\n } else {\n log('backfillPersonProperties | skipped — PostHog not initialized')\n }\n }\n\n const getInstances = () => ({ ab: _growthbook, tracking: _rudderstack, posthog: _posthog })\n\n const AnalyticsInstance = {\n initialise,\n setAttributes,\n identifyEvent,\n backfillPersonProperties,\n getFeatureState,\n getFeatureValue,\n getGrowthbookStatus,\n isFeatureOn,\n setUrl,\n getId,\n getAnonymousId,\n trackEvent,\n getInstances,\n pageView,\n reset,\n }\n\n if (typeof window !== 'undefined') {\n window.AnalyticsInstance = AnalyticsInstance\n }\n\n return AnalyticsInstance\n}\n\nexport const Analytics = createAnalyticsInstance()\n"]}
|