@@ -54,9 +54,6 @@ export class SegmentClient {
5454 // internal time to know when to flush, ticks every second
5555 private flushInterval : ReturnType < typeof setInterval > | null = null ;
5656
57- // Watcher for isReady updates to the storage
58- private readinessWatcher ?: Unsubscribe = undefined ;
59-
6057 // unsubscribe watchers for the store
6158 private watchers : Unsubscribe [ ] = [ ] ;
6259
@@ -70,8 +67,8 @@ export class SegmentClient {
7067
7168 private timeline : Timeline ;
7269
73- // mechanism to prevent adding plugins before we are fully initalised
74- private isStorageReady = false ;
70+ private pendingEvents : SegmentEvent [ ] = [ ] ;
71+
7572 private pluginsToAdd : Plugin [ ] = [ ] ;
7673
7774 private isInitialized = false ;
@@ -167,9 +164,6 @@ export class SegmentClient {
167164 this . add ( { plugin : segmentDestination } ) ;
168165 }
169166
170- // Setup platform specific plugins
171- this . platformPlugins . forEach ( ( plugin ) => this . add ( { plugin : plugin } ) ) ;
172-
173167 // Initialize the watchables
174168 this . context = {
175169 get : this . store . context . get ,
@@ -199,6 +193,13 @@ export class SegmentClient {
199193 get : this . store . events . get ,
200194 onChange : this . store . events . onChange ,
201195 } ;
196+
197+ // Watch for isReady so that we can handle any pending events
198+ // Delays events processing in the timeline until the store is ready to prevent missing data injected from the plugins
199+ this . store . isReady . onChange ( ( value ) => this . onStorageReady ( value ) ) ;
200+
201+ // Setup platform specific plugins
202+ this . platformPlugins . forEach ( ( plugin ) => this . add ( { plugin : plugin } ) ) ;
202203 }
203204
204205 /**
@@ -211,12 +212,6 @@ export class SegmentClient {
211212 return ;
212213 }
213214
214- // Plugin interval check
215- if ( this . store . isReady . get ( ) ) {
216- this . onStorageReady ( true ) ;
217- } else {
218- this . store . isReady . onChange ( ( value ) => this . onStorageReady ( value ) ) ;
219- }
220215 await this . fetchSettings ( ) ;
221216
222217 // flush any stored events
@@ -290,7 +285,6 @@ export class SegmentClient {
290285 clearInterval ( this . flushInterval ) ;
291286 }
292287
293- this . unsubscribeReadinessWatcher ( ) ;
294288 this . unsubscribeStorageWatchers ( ) ;
295289
296290 this . appStateSubscription ?. remove ( ) ;
@@ -358,7 +352,7 @@ export class SegmentClient {
358352 this . store . settings . add ( ( plugin as DestinationPlugin ) . key , settings ) ;
359353 }
360354
361- if ( ! this . isStorageReady ) {
355+ if ( ! this . store . isReady . get ( ) ) {
362356 this . pluginsToAdd . push ( plugin ) ;
363357 } else {
364358 this . addPlugin ( plugin ) ;
@@ -381,7 +375,11 @@ export class SegmentClient {
381375
382376 process ( incomingEvent : SegmentEvent ) {
383377 const event = applyRawEventData ( incomingEvent , this . store . userInfo . get ( ) ) ;
384- this . timeline . process ( event ) ;
378+ if ( this . store . isReady . get ( ) === true ) {
379+ this . timeline . process ( event ) ;
380+ } else {
381+ this . pendingEvents . push ( event ) ;
382+ }
385383 }
386384
387385 private async trackDeepLinks ( ) {
@@ -399,29 +397,34 @@ export class SegmentClient {
399397 }
400398 }
401399
402- private unsubscribeReadinessWatcher ( ) {
403- this . readinessWatcher ?. ( ) ;
404- }
405-
400+ /**
401+ * Executes when the state store is initialized.
402+ * @param isReady
403+ */
406404 private onStorageReady ( isReady : boolean ) {
407- if ( isReady && this . pluginsToAdd . length > 0 && ! this . isAddingPlugins ) {
408- this . isAddingPlugins = true ;
409- try {
410- // start by adding the plugins
411- this . pluginsToAdd . forEach ( ( plugin ) => {
412- this . addPlugin ( plugin ) ;
413- } ) ;
414-
415- // now that they're all added, clear the cache
416- // this prevents this block running for every update
417- this . pluginsToAdd = [ ] ;
405+ if ( isReady ) {
406+ // Add all plugins awaiting store
407+ if ( this . pluginsToAdd . length > 0 && ! this . isAddingPlugins ) {
408+ this . isAddingPlugins = true ;
409+ try {
410+ // start by adding the plugins
411+ this . pluginsToAdd . forEach ( ( plugin ) => {
412+ this . addPlugin ( plugin ) ;
413+ } ) ;
414+
415+ // now that they're all added, clear the cache
416+ // this prevents this block running for every update
417+ this . pluginsToAdd = [ ] ;
418+ } finally {
419+ this . isAddingPlugins = false ;
420+ }
421+ }
418422
419- // finally set the flag which means plugins will be added + registered immediately in future
420- this . isStorageReady = true ;
421- this . unsubscribeReadinessWatcher ( ) ;
422- } finally {
423- this . isAddingPlugins = false ;
423+ // Send all events in the queue
424+ for ( const e of this . pendingEvents ) {
425+ this . timeline . process ( e ) ;
424426 }
427+ this . pendingEvents = [ ] ;
425428 }
426429 }
427430
0 commit comments