@@ -72,6 +72,7 @@ import {
7272 translateHTTPError ,
7373} from './errors' ;
7474import { QueueFlushingPlugin } from './plugins/QueueFlushingPlugin' ;
75+ import { WaitingPlugin } from './plugins/Waiting' ;
7576
7677type OnPluginAddedCallback = ( plugin : Plugin ) => void ;
7778
@@ -97,6 +98,11 @@ export class SegmentClient {
9798 private isAddingPlugins = false ;
9899
99100 private timeline : Timeline ;
101+ // running state (matches Kotlin's running flag)
102+ private isRunning = true ;
103+
104+ // Waiting plugin instance (buffers events while paused)
105+ private waitingPlugin ?: WaitingPlugin ;
100106
101107 private pluginsToAdd : Plugin [ ] = [ ] ;
102108
@@ -200,6 +206,18 @@ export class SegmentClient {
200206 this . store = store ;
201207 this . timeline = new Timeline ( ) ;
202208
209+ // create and add waiting plugin immediately so early events get buffered.
210+ try {
211+ this . waitingPlugin = new WaitingPlugin ( ) ;
212+ // add directly to timeline via addPlugin to ensure configure() is called immediately
213+ this . addPlugin ( this . waitingPlugin ) ;
214+ // initial running state false until init completes (mirrors Kotlin semantics)
215+ this . isRunning = false ;
216+ } catch ( e ) {
217+ // if WaitingPlugin instantiation or add fails, fallback to running=true
218+ this . isRunning = true ;
219+ }
220+
203221 // Initialize the watchables
204222 this . context = {
205223 get : this . store . context . get ,
@@ -296,6 +314,9 @@ export class SegmentClient {
296314 await this . storageReady ( ) ;
297315 }
298316
317+ // Pause pipeline at init start (buffer events until init completes)
318+ this . pauseEventProcessing ( ) ;
319+
299320 // Get new settings from segment
300321 // It's important to run this before checkInstalledVersion and trackDeeplinks to give time for destination plugins
301322 // which make use of the settings object to initialize
@@ -309,7 +330,8 @@ export class SegmentClient {
309330 ] ) ;
310331 await this . onReady ( ) ;
311332 this . isReady . value = true ;
312-
333+ // Resume pipeline before processing pending events so WaitingPlugin flushes
334+ await this . resumeEventProcessing ( ) ;
313335 // Process all pending events
314336 await this . processPendingEvents ( ) ;
315337 // Trigger manual flush
@@ -1027,4 +1049,45 @@ export class SegmentClient {
10271049
10281050 return totalEventsCount ;
10291051 }
1052+ /*
1053+ * Running / pause/resume helpers (Kotlin parity)
1054+ */
1055+
1056+ public running ( ) {
1057+ return this . isRunning ;
1058+ }
1059+ /**
1060+ * Pause event processing globally. Events will be buffered into pendingEvents and WaitingPlugin.
1061+ * An auto-resume will be scheduled after `timeout` ms.
1062+ */
1063+ public pauseEventProcessing ( timeout = 30000 ) {
1064+ if ( ! this . isRunning ) {
1065+ return ;
1066+ }
1067+
1068+ this . isRunning = false ;
1069+ try {
1070+ this . waitingPlugin ?. pause ( ) ;
1071+ } catch {
1072+ // ignore if plugin not present
1073+ }
1074+
1075+ // auto-resume after timeout to avoid permanent blocking
1076+ setTimeout ( ( ) => {
1077+ void this . resumeEventProcessing ( ) ;
1078+ } , timeout ) ;
1079+ }
1080+ public async resumeEventProcessing ( ) {
1081+ if ( this . isRunning ) {
1082+ return ;
1083+ }
1084+
1085+ this . isRunning = true ;
1086+
1087+ try {
1088+ await this . waitingPlugin ?. resume ( ) ;
1089+ } catch {
1090+ // ignore plugin errors during resume
1091+ }
1092+ }
10301093}
0 commit comments