@@ -32,6 +32,8 @@ class EventRepository implements IEventRepository {
3232 dataplaneEventsQueue : any ;
3333 destinationsEventsQueue : any ;
3434 dmtEventsQueue : any ;
35+ eventsBuffer : RudderEvent [ ] ;
36+ isEventBufferingActive : boolean ;
3537
3638 /**
3739 *
@@ -52,6 +54,8 @@ class EventRepository implements IEventRepository {
5254 this . httpClient = httpClient ;
5355 this . logger = logger ;
5456 this . storeManager = storeManager ;
57+ this . eventsBuffer = [ ] ;
58+ this . isEventBufferingActive = true ;
5559 }
5660
5761 /**
@@ -96,50 +100,66 @@ class EventRepository implements IEventRepository {
96100 } ) ;
97101
98102 const bufferEventsBeforeConsent = shouldBufferEventsForPreConsent ( state ) ;
103+ if ( ! bufferEventsBeforeConsent ) {
104+ this . startDpEventsQueue ( ) ;
105+ }
106+ }
99107
100- // Start the queue processing only when the destinations are ready or hybrid mode destinations exist
101- // However, events will be enqueued for now.
102- // At the time of processing the events, the integrations config data from destinations
103- // is merged into the event object
104- let timeoutId : number ;
105- effect ( ( ) => {
106- const shouldBufferDpEvents =
107- state . loadOptions . value . bufferDataPlaneEventsUntilReady === true &&
108- state . nativeDestinations . clientDestinationsReady . value === false ;
108+ private startDpEventsQueue ( ) {
109+ const bufferEventsUntilReady = state . loadOptions . value
110+ . bufferDataPlaneEventsUntilReady as boolean ;
109111
110- const hybridDestExist = state . nativeDestinations . activeDestinations . value . some (
111- ( dest : Destination ) => isHybridModeDestination ( dest ) ,
112- ) ;
112+ const hybridDestExist = state . nativeDestinations . activeDestinations . value . some (
113+ ( dest : Destination ) => isHybridModeDestination ( dest ) ,
114+ ) ;
115+ const shouldBufferEvents = bufferEventsUntilReady && hybridDestExist ;
116+
117+ // Start the data plane events queue and replay the events from the buffer
118+ // This function is called when the client destinations are ready
119+ // or when the timeout expires
120+ // or when no buffering is required
121+ const startDpQueueAndReplayEvents = ( ) => {
122+ this . isEventBufferingActive = false ;
123+ this . eventsBuffer . forEach ( event => {
124+ this . enqueue ( event ) ;
125+ } ) ;
126+
127+ if ( this . dataplaneEventsQueue ?. scheduleTimeoutActive !== true ) {
128+ this . dataplaneEventsQueue ?. start ( ) ;
129+ }
130+
131+ this . eventsBuffer = [ ] ;
132+ } ;
113133
114- if (
115- ( hybridDestExist === false || shouldBufferDpEvents === false ) &&
116- ! bufferEventsBeforeConsent &&
117- this . dataplaneEventsQueue ?. scheduleTimeoutActive !== true
118- ) {
134+ let timeoutId : number ;
135+ // Start the queue when no event buffering is required
136+ // or when buffering is required and the client destinations are ready
137+ effect ( ( ) => {
138+ if ( ! shouldBufferEvents || state . nativeDestinations . clientDestinationsReady . value ) {
119139 ( globalThis as typeof window ) . clearTimeout ( timeoutId ) ;
120- this . dataplaneEventsQueue ?. start ( ) ;
140+ startDpQueueAndReplayEvents ( ) ;
121141 }
122142 } ) ;
123143
124144 // Force start the data plane events queue processing after a timeout
125- if ( state . loadOptions . value . bufferDataPlaneEventsUntilReady === true ) {
145+ if ( shouldBufferEvents ) {
146+ this . isEventBufferingActive = true ;
126147 timeoutId = ( globalThis as typeof window ) . setTimeout ( ( ) => {
127- if ( this . dataplaneEventsQueue ?. scheduleTimeoutActive !== true ) {
128- this . dataplaneEventsQueue ?. start ( ) ;
129- }
148+ startDpQueueAndReplayEvents ( ) ;
130149 } , state . loadOptions . value . dataPlaneEventsBufferTimeout ) ;
131150 }
132151 }
133152
134153 resume ( ) {
135- if ( this . dataplaneEventsQueue ?. scheduleTimeoutActive !== true ) {
136- if ( state . consents . postConsent . value . discardPreConsentEvents ) {
137- this . dataplaneEventsQueue ?. clear ( ) ;
138- this . destinationsEventsQueue ?. clear ( ) ;
139- }
140-
141- this . dataplaneEventsQueue ?. start ( ) ;
154+ if (
155+ this . dataplaneEventsQueue ?. scheduleTimeoutActive !== true &&
156+ state . consents . postConsent . value . discardPreConsentEvents
157+ ) {
158+ this . dataplaneEventsQueue ?. clear ( ) ;
159+ this . destinationsEventsQueue ?. clear ( ) ;
142160 }
161+
162+ this . startDpEventsQueue ( ) ;
143163 }
144164
145165 /**
@@ -149,24 +169,29 @@ class EventRepository implements IEventRepository {
149169 */
150170 enqueue ( event : RudderEvent , callback ?: ApiCallback ) : void {
151171 const dpQEvent = getFinalEvent ( event , state ) ;
152- this . pluginsManager . invokeSingle (
153- `${ DATA_PLANE_QUEUE_EXT_POINT_PREFIX } .enqueue` ,
154- state ,
155- this . dataplaneEventsQueue ,
156- dpQEvent ,
157- this . errorHandler ,
158- this . logger ,
159- ) ;
160172
161- const dQEvent = clone ( event ) ;
162- this . pluginsManager . invokeSingle (
163- `${ DESTINATIONS_QUEUE_EXT_POINT_PREFIX } .enqueue` ,
164- state ,
165- this . destinationsEventsQueue ,
166- dQEvent ,
167- this . errorHandler ,
168- this . logger ,
169- ) ;
173+ if ( this . isEventBufferingActive ) {
174+ this . eventsBuffer . push ( dpQEvent ) ;
175+ } else {
176+ this . pluginsManager . invokeSingle (
177+ `${ DATA_PLANE_QUEUE_EXT_POINT_PREFIX } .enqueue` ,
178+ state ,
179+ this . dataplaneEventsQueue ,
180+ dpQEvent ,
181+ this . errorHandler ,
182+ this . logger ,
183+ ) ;
184+
185+ const dQEvent = clone ( event ) ;
186+ this . pluginsManager . invokeSingle (
187+ `${ DESTINATIONS_QUEUE_EXT_POINT_PREFIX } .enqueue` ,
188+ state ,
189+ this . destinationsEventsQueue ,
190+ dQEvent ,
191+ this . errorHandler ,
192+ this . logger ,
193+ ) ;
194+ }
170195
171196 // Invoke the callback if it exists
172197 const apiName = `${ event . type . charAt ( 0 ) . toUpperCase ( ) } ${ event . type . slice ( 1 ) } ${ API_SUFFIX } ` ;
0 commit comments