UNPKG

@deriv-com/analytics

Version:

Comprehensive analytics package for Deriv applications. Provides unified event tracking, A/B testing, and user analytics through RudderStack, PostHog and GrowthBook integrations with built-in caching and offline support.

3 lines 10.9 kB
/* @deriv-com/analytics - Browser ESM Bundle (RudderStack + PostHog) - Built with tsup */ import{a as G}from"../chunk-MWNJTXSL.mjs";import{c as z,g as E,h as U,i as b,j as D,k as P,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=E("[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,d=["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,x=>x.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=${d}; 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:z});try{this.setCookieIfNotExists(),this.analytics.load(i,z,{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 d={...r&&{user_id:r},...c};this.log("pageView | tracking page view",{platform:e,current_page:i,properties:d}),this.analytics.page(e,i,d),this.current_page=i}catch(d){console.error("RudderStack: Failed to track page view",d)}};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 F=v;var R="cached_analytics_events",C="cached_analytics_page_views",$=(l,i)=>{try{let e=localStorage.getItem(R),r=e?JSON.parse(e):[];r.push({name:l,properties:i,timestamp:Date.now()}),localStorage.setItem(R,JSON.stringify(r))}catch(e){console.warn("Analytics: Failed to cache event",e)}},L=(l,i)=>{try{let e=localStorage.getItem(C),r=e?JSON.parse(e):[];r.push({name:l,properties:i,timestamp:Date.now()}),localStorage.setItem(C,JSON.stringify(r))}catch(e){console.warn("Analytics: Failed to cache page view",e)}},N=()=>{try{let l=localStorage.getItem(R);if(l){let i=JSON.parse(l);return Array.isArray(i)?i:[]}}catch(l){console.warn("Analytics: Failed to get cached events",l)}return[]},H=()=>{try{let l=localStorage.getItem(C);if(l){let i=JSON.parse(l);return Array.isArray(i)?i:[]}}catch(l){console.warn("Analytics: Failed to get cached pages",l)}return[]},j=()=>{try{localStorage.removeItem(R)}catch(l){console.warn("Analytics: Failed to clear cached events",l)}},J=()=>{try{localStorage.removeItem(C)}catch(l){console.warn("Analytics: Failed to clear cached page views",l)}};function Y(l){let i=l?.debug??!1,e=E("",()=>i),r,c,d,p={},I={},m=[],g=[],_=!1,x=()=>{if(!_&&c?.has_initialized){_=!0;try{let t=N();t.length>0&&(e(`processStorageCache | replaying ${t.length} cached event(s)`,t),t.forEach(o=>{let a=P(o.properties);c?.track(o.name,a)}),j());let n=H();n.length>0&&(e(`processStorageCache | replaying ${n.length} cached page view(s)`,n),n.forEach(o=>{c?.pageView(o.name,"Deriv App",w(),o.properties)}),J())}catch(t){console.warn("Analytics: Failed to process storage cache",t)}}},B=()=>{e("onSdkLoaded | RudderStack SDK loaded"),x(),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:o,growthbookOptions:a,posthogOptions:u,debug:f})=>{var h,y;f!==void 0&&(i=f),e("initialise | starting analytics initialization",{rudderstack:!!o,growthbook:!!t,posthog:!!u});try{let k=a?.attributes?.country||(t?await D():void 0);if(o&&(e("initialise | initializing RudderStack"),c=F.getRudderStackInstance(o,B,i)),a?.attributes&&Object.keys(a.attributes).length>0){let s=a.attributes,A=c?.getAnonymousId();p={...p,country:k,...s.user_language&&{user_language:s.user_language},...s.account_type&&{account_type:s.account_type},...s.app_id&&{app_id:s.app_id},...s.residence_country&&{residence_country:s.residence_country},...s.device_type&&{device_type:s.device_type},...s.url&&{url:s.url},...s.email_hash&&{email_hash:s.email_hash},...s.network_type&&{network_type:s.network_type},...s.network_rtt&&{network_rtt:s.network_rtt},...s.network_downlink&&{network_downlink:s.network_downlink},...s.account_currency&&{account_currency:s.account_currency},...s.account_mode&&{account_mode:s.account_mode},loggedIn:!!s.loggedIn,...s.user_id&&!b(s.user_id)&&{user_id:s.user_id},...A&&{anonymous_id:A}}}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:s}=await import("../growthbook-TBZXPHJZ.mjs");r=s.getGrowthBookInstance(t,n,a,i),e("initialise | GrowthBook initialized");let A=setInterval(()=>{Object.keys(I).length>0?clearInterval(A):I=V("tracking-buttons-config",{})},1e3)}if(u){e("initialise | initializing PostHog");let{Posthog:s}=await import("../posthog-QH4OCJ4V.mjs");d=s.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,...o}=t,a=n??w();if(r){let u={...o};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(o).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,V=(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:""},T={initialise:K,setAttributes:W,identifyEvent:(t,n)=>{let o=t||w();if(!o){e("identifyEvent | skipped \u2014 no user_id available");return}e("identifyEvent | called",{user_id:o,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:o,traits:f}),c.identifyEvent(o,f)):g.some(y=>y.userId===o)||(e("identifyEvent | RudderStack not initialized \u2014 queuing identify call",{user_id:o}),g.push({userId:o,traits:f}))),d?.has_initialized&&(e("identifyEvent | calling PostHog identify",{user_id:o,traits:h}),d.identifyEvent(o,h))},backfillPersonProperties:({user_id:t,email:n,language:o,country_of_residence:a})=>{e("backfillPersonProperties | called",{user_id:t}),d?.has_initialized?(e("backfillPersonProperties | backfilling person properties in PostHog",{user_id:t}),d.backfillPersonProperties({user_id:t,email:n,language:o,country_of_residence:a})):e("backfillPersonProperties | skipped \u2014 PostHog not initialized")},getFeatureState:q,getFeatureValue:V,getGrowthbookStatus:M,isFeatureOn:X,setUrl:Q,getId:w,getAnonymousId:()=>c?.getAnonymousId()||"",trackEvent:(t,n)=>{let o=w();e("trackEvent | called",{event:t,analytics_data:n,userId:o,core_data:p});let a={...p,...n,...o&&!p.user_id&&{user_id:o}};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=P(y.payload);c?.track(y.event,k)}),m=[]);let h=P(a);e("trackEvent | sending event to RudderStack",{event:t,payload:h}),c?.track(t,h)}if(d?.has_initialized){let h=P(O(a));e("trackEvent | sending event to PostHog",{event:t,payload:h}),d.capture(t,h)}},getInstances:()=>({ab:r,tracking:c,posthog:d}),pageView:(t,n="Deriv App",o)=>{let a=w();e("pageView | called",{current_page:t,platform:n,properties:o,userId:a}),c?.has_initialized?(e("pageView | sending page view to RudderStack",{current_page:t,platform:n}),c.pageView(t,n,a,o)):(e("pageView | RudderStack not initialized \u2014 caching page view to localStorage",{current_page:t}),L(t,{platform:n,...o}))},reset:()=>{e("reset | resetting all providers"),c?.has_initialized&&(e("reset | resetting RudderStack"),c.reset()),d?.has_initialized&&(e("reset | resetting PostHog"),d.reset())},isPosthogFeatureEnabled:t=>d?.isFeatureEnabled(t),getPosthogFeatureFlag:t=>d?.getFeatureFlag(t),getPosthogFeatureFlagPayload:t=>d?.getFeatureFlagPayload(t),getPosthogAllFlags:()=>d?.getAllFlags()??{},onPosthogFeatureFlags:t=>d?.onFeatureFlags(t)??(()=>{}),reloadPosthogFeatureFlags:()=>d?.reloadFeatureFlags()};return typeof window<"u"&&(window.AnalyticsInstance=T),T}var ee=Y();export{ee as Analytics}; //# sourceMappingURL=analytics.esm.mjs.map