@@ -72,7 +72,12 @@ export class Channel {
72
72
private overridedTitle = '' ;
73
73
74
74
private messageQueue : QueuedMessage [ ] = [ ] ;
75
- private isProcessingMessage = false ;
75
+
76
+ private processingMessageDeferred : {
77
+ promise : Promise < void > ;
78
+ resolve : ( ) => void ;
79
+ reject : ( reason ?: any ) => void ;
80
+ } | null = null ;
76
81
77
82
constructor (
78
83
private title : Title ,
@@ -137,14 +142,15 @@ export class Channel {
137
142
138
143
this . eventSource . addEventListener ( 'message' , ( e ) => {
139
144
// Looks like Angular has a bug where it's not intercepting EventSource onmessage.
140
- zone . run ( ( ) => {
145
+ zone . run ( async ( ) => {
141
146
const data = ( e as any ) . data ;
142
147
if ( data === STREAM_END ) {
143
148
this . eventSource . close ( ) ;
144
149
this . status = ChannelStatus . CLOSED ;
145
150
clearTimeout ( this . isWaitingTimeout ) ;
146
151
this . isWaiting = false ;
147
152
this . _isHotReloading = false ;
153
+ await this . processMessageQueue ( ) ;
148
154
this . dequeueEvent ( ) ;
149
155
return ;
150
156
}
@@ -185,7 +191,7 @@ export class Channel {
185
191
} ;
186
192
187
193
this . webSocket . onmessage = ( event ) => {
188
- zone . run ( ( ) => {
194
+ zone . run ( async ( ) => {
189
195
const prefix = 'data: ' ;
190
196
const payloadData = (
191
197
event . data . slice ( prefix . length ) as string
@@ -194,6 +200,7 @@ export class Channel {
194
200
if ( payloadData === STREAM_END ) {
195
201
this . _isHotReloading = false ;
196
202
this . status = ChannelStatus . CLOSED ;
203
+ await this . processMessageQueue ( ) ;
197
204
this . dequeueEvent ( ) ;
198
205
return ;
199
206
}
@@ -357,28 +364,32 @@ export class Channel {
357
364
request,
358
365
response,
359
366
} ) ;
360
- this . processNextMessage ( ) ;
367
+ this . processMessageQueue ( ) ;
361
368
}
362
369
363
- private async processNextMessage ( ) {
364
- if ( this . isProcessingMessage || this . messageQueue . length === 0 ) {
365
- return ;
370
+ private async processMessageQueue ( ) {
371
+ if ( this . processingMessageDeferred ) {
372
+ return this . processingMessageDeferred . promise ;
366
373
}
367
374
368
- this . isProcessingMessage = true ;
369
- try {
375
+ this . processingMessageDeferred = createDeferred ( ) ;
376
+
377
+ while ( this . messageQueue . length > 0 ) {
370
378
const queuedMessage = this . messageQueue . shift ( ) ! ;
371
- await this . handleUiResponse (
372
- queuedMessage . request ,
373
- queuedMessage . response ,
374
- this . initParams ,
375
- ) ;
376
- } finally {
377
- this . isProcessingMessage = false ;
378
- if ( this . messageQueue . length > 0 ) {
379
- await this . processNextMessage ( ) ;
379
+ try {
380
+ await this . handleUiResponse (
381
+ queuedMessage . request ,
382
+ queuedMessage . response ,
383
+ this . initParams ,
384
+ ) ;
385
+ } catch ( error ) {
386
+ console . error ( 'Error handling UI response:' , error ) ;
380
387
}
381
388
}
389
+
390
+ // All queued messages processed; resolve the promise and clear it.
391
+ this . processingMessageDeferred . resolve ( ) ;
392
+ this . processingMessageDeferred = null ;
382
393
}
383
394
384
395
dispatch ( userEvent : UserEvent ) {
@@ -506,6 +517,20 @@ export class Channel {
506
517
}
507
518
}
508
519
520
+ function createDeferred < T = void > ( ) : {
521
+ promise : Promise < T > ;
522
+ resolve : ( value : T | PromiseLike < T > ) => void ;
523
+ reject : ( reason ?: any ) => void ;
524
+ } {
525
+ let resolve : ( value : T | PromiseLike < T > ) => void = ( ) => { } ;
526
+ let reject : ( reason ?: any ) => void = ( ) => { } ;
527
+ const promise = new Promise < T > ( ( res , rej ) => {
528
+ resolve = res ;
529
+ reject = rej ;
530
+ } ) ;
531
+ return { promise, resolve, reject} ;
532
+ }
533
+
509
534
function generatePayloadString ( request : UiRequest ) : string {
510
535
request . setPath ( window . location . pathname ) ;
511
536
const array = request . serializeBinary ( ) ;
0 commit comments