@@ -8,11 +8,19 @@ type UmamiTrack = {
88 ( ( data : AnalyticsProperties ) => void ) ;
99} ;
1010
11+ type PendingEvent = {
12+ eventName : string ;
13+ properties ?: AnalyticsProperties ;
14+ } ;
15+
1116const APP_NAME = 'competitiongroups' ;
1217const MAX_EVENT_NAME_LENGTH = 50 ;
18+ const MAX_PENDING_EVENTS = 50 ;
1319const UMAMI_SCRIPT_ID = 'umami-analytics-script' ;
1420
1521let currentUserId : string | undefined ;
22+ let pendingEvents : PendingEvent [ ] = [ ] ;
23+ let umamiConfigured = false ;
1624
1725const getEnvironment = ( ) => ( typeof __APP_ENV__ === 'undefined' ? 'test' : __APP_ENV__ ) ;
1826
@@ -67,14 +75,80 @@ const eventProperties = (properties: AnalyticsProperties = {}): AnalyticsPropert
6775export const isValidEventName = ( eventName : string ) =>
6876 eventName . length > 0 && eventName . length <= MAX_EVENT_NAME_LENGTH ;
6977
78+ export const configureUmamiAnalytics = ( {
79+ src,
80+ websiteId,
81+ } : {
82+ src ?: string ;
83+ websiteId ?: string ;
84+ } = { } ) => {
85+ umamiConfigured = Boolean ( src && websiteId ) ;
86+ } ;
87+
88+ const sendEvent = ( eventName : string , properties ?: AnalyticsProperties ) => {
89+ const umami = getUmami ( ) ;
90+ if ( ! umami ?. track ) {
91+ return false ;
92+ }
93+
94+ umami . track ( eventName , eventProperties ( properties ) ) ;
95+ return true ;
96+ } ;
97+
98+ const queueEvent = ( eventName : string , properties ?: AnalyticsProperties ) => {
99+ if ( ! umamiConfigured ) {
100+ return ;
101+ }
102+
103+ pendingEvents = [ ...pendingEvents . slice ( - ( MAX_PENDING_EVENTS - 1 ) ) , { eventName, properties } ] ;
104+ } ;
105+
106+ const identifyCurrentUser = ( ) => {
107+ const umami = getUmami ( ) ;
108+ if ( ! umami ?. identify || ! currentUserId ) {
109+ return false ;
110+ }
111+
112+ umami . identify ( currentUserId , {
113+ ...baseProperties ( ) ,
114+ auth_status : 'logged_in' ,
115+ } ) ;
116+ return true ;
117+ } ;
118+
119+ const flushPendingEvents = ( ) => {
120+ if ( ! pendingEvents . length ) {
121+ identifyCurrentUser ( ) ;
122+ return ;
123+ }
124+
125+ const events = pendingEvents ;
126+ pendingEvents = [ ] ;
127+
128+ events . forEach ( ( { eventName, properties } ) => {
129+ if ( ! sendEvent ( eventName , properties ) ) {
130+ queueEvent ( eventName , properties ) ;
131+ }
132+ } ) ;
133+
134+ identifyCurrentUser ( ) ;
135+ } ;
136+
70137export const loadUmamiScript = ( {
71138 src,
72139 websiteId,
73140} : {
74141 src ?: string ;
75142 websiteId ?: string ;
76143} = { } ) => {
77- if ( ! isBrowser ( ) || ! src || ! websiteId || document . getElementById ( UMAMI_SCRIPT_ID ) ) {
144+ if ( ! isBrowser ( ) || ! src || ! websiteId ) {
145+ return ;
146+ }
147+
148+ configureUmamiAnalytics ( { src, websiteId } ) ;
149+
150+ if ( document . getElementById ( UMAMI_SCRIPT_ID ) ) {
151+ flushPendingEvents ( ) ;
78152 return ;
79153 }
80154
@@ -83,21 +157,13 @@ export const loadUmamiScript = ({
83157 script . defer = true ;
84158 script . src = src ;
85159 script . dataset . websiteId = websiteId ;
160+ script . addEventListener ( 'load' , flushPendingEvents ) ;
86161 document . head . appendChild ( script ) ;
87162} ;
88163
89164export const identifyUser = ( userId ?: number | string | null ) => {
90165 currentUserId = userId ? String ( userId ) : undefined ;
91-
92- const umami = getUmami ( ) ;
93- if ( ! umami ?. identify || ! currentUserId ) {
94- return ;
95- }
96-
97- umami . identify ( currentUserId , {
98- ...baseProperties ( ) ,
99- auth_status : 'logged_in' ,
100- } ) ;
166+ identifyCurrentUser ( ) ;
101167} ;
102168
103169export const trackEvent = ( eventName : string , properties ?: AnalyticsProperties ) => {
@@ -108,12 +174,9 @@ export const trackEvent = (eventName: string, properties?: AnalyticsProperties)
108174 return ;
109175 }
110176
111- const umami = getUmami ( ) ;
112- if ( ! umami ?. track ) {
113- return ;
177+ if ( ! sendEvent ( eventName , properties ) ) {
178+ queueEvent ( eventName , properties ) ;
114179 }
115-
116- umami . track ( eventName , eventProperties ( properties ) ) ;
117180} ;
118181
119182export const trackCompetitionEvent = (
@@ -133,3 +196,9 @@ declare global {
133196 umami ?: UmamiTrack ;
134197 }
135198}
199+
200+ export const __resetAnalyticsForTests = ( ) => {
201+ currentUserId = undefined ;
202+ pendingEvents = [ ] ;
203+ umamiConfigured = false ;
204+ } ;
0 commit comments