99const {
1010 ArrayIsArray,
1111 ArrayPrototypePush,
12+ ArrayPrototypeShift,
1213 MathMax,
1314 PromisePrototypeThen,
1415 PromiseReject,
@@ -146,6 +147,7 @@ class BroadcastImpl {
146147 cursor : this . #bufferStart,
147148 resolve : null ,
148149 reject : null ,
150+ pending : [ ] ,
149151 detached : false ,
150152 } ;
151153
@@ -165,9 +167,10 @@ class BroadcastImpl {
165167
166168 function detach ( ) {
167169 state . detached = true ;
168- state . resolve ?. ( { __proto__ : null , done : true , value : undefined } ) ;
169- state . resolve = null ;
170- state . reject = null ;
170+ if ( state . resolve ) {
171+ state . resolve ( { __proto__ : null , done : true , value : undefined } ) ;
172+ }
173+ self . #resolvePendingDone( state ) ;
171174 if ( self . #deleteConsumer( state ) ) {
172175 self . #tryTrimBuffer( ) ;
173176 }
@@ -208,6 +211,13 @@ class BroadcastImpl {
208211 return kDone ;
209212 }
210213
214+ if ( state . resolve ) {
215+ const { promise, resolve, reject } = PromiseWithResolvers ( ) ;
216+ ArrayPrototypePush ( state . pending ,
217+ { __proto__ : null , resolve, reject } ) ;
218+ return promise ;
219+ }
220+
211221 const { promise, resolve, reject } = PromiseWithResolvers ( ) ;
212222 state . resolve = resolve ;
213223 state . reject = reject ;
@@ -251,6 +261,11 @@ class BroadcastImpl {
251261 consumer . resolve = null ;
252262 consumer . reject = null ;
253263 }
264+ if ( reason !== undefined ) {
265+ this . #rejectPending( consumer , reason ) ;
266+ } else {
267+ this . #resolvePendingDone( consumer ) ;
268+ }
254269 consumer . detached = true ;
255270 }
256271 this . #consumers. clear ( ) ;
@@ -297,7 +312,7 @@ class BroadcastImpl {
297312 this . #ended = true ;
298313
299314 for ( const consumer of this . #consumers) {
300- if ( consumer . resolve ) {
315+ while ( consumer . resolve ) {
301316 const bufferIndex = consumer . cursor - this . #bufferStart;
302317 if ( bufferIndex < this . #buffer. length ) {
303318 const chunk = this . #buffer. get ( bufferIndex ) ;
@@ -310,9 +325,15 @@ class BroadcastImpl {
310325 consumer . resolve ( { __proto__ : null , done : false , value : chunk } ) ;
311326 } else {
312327 consumer . resolve ( { __proto__ : null , done : true , value : undefined } ) ;
328+ this . #resolvePendingDone( consumer ) ;
329+ consumer . detached = true ;
313330 }
314331 consumer . resolve = null ;
315332 consumer . reject = null ;
333+ if ( consumer . detached && this . #deleteConsumer( consumer ) ) {
334+ this . #tryTrimBuffer( ) ;
335+ break ;
336+ }
316337 }
317338 }
318339 }
@@ -329,6 +350,7 @@ class BroadcastImpl {
329350 consumer . resolve = null ;
330351 consumer . reject = null ;
331352 }
353+ this . #rejectPending( consumer , reason ) ;
332354 consumer . detached = true ;
333355 }
334356 this . #consumers. clear ( ) ;
@@ -397,6 +419,11 @@ class BroadcastImpl {
397419 consumer . resolve = null ;
398420 consumer . reject = null ;
399421 resolve ( { __proto__ : null , done : false , value : chunk } ) ;
422+ if ( consumer . detached && this . #deleteConsumer( consumer ) ) {
423+ this . #tryTrimBuffer( ) ;
424+ } else if ( this . #promotePending( consumer ) ) {
425+ ArrayPrototypePush ( this . #waiters, consumer ) ;
426+ }
400427 } else {
401428 // Still waiting -- put back
402429 ArrayPrototypePush ( this . #waiters, consumer ) ;
@@ -419,6 +446,31 @@ class BroadcastImpl {
419446 }
420447 return false ;
421448 }
449+
450+ #promotePending( consumer ) {
451+ const next = ArrayPrototypeShift ( consumer . pending ) ;
452+ if ( next === undefined ) return false ;
453+ consumer . resolve = next . resolve ;
454+ consumer . reject = next . reject ;
455+ return true ;
456+ }
457+
458+ #resolvePendingDone( consumer ) {
459+ if ( consumer . resolve ) {
460+ consumer . resolve = null ;
461+ consumer . reject = null ;
462+ }
463+ while ( consumer . pending . length > 0 ) {
464+ ArrayPrototypeShift ( consumer . pending ) . resolve (
465+ { __proto__ : null , done : true , value : undefined } ) ;
466+ }
467+ }
468+
469+ #rejectPending( consumer , reason ) {
470+ while ( consumer . pending . length > 0 ) {
471+ ArrayPrototypeShift ( consumer . pending ) . reject ( reason ) ;
472+ }
473+ }
422474}
423475
424476// =============================================================================
0 commit comments