import Emittery from "emittery" ; import Entry from "./src/entry" ; const emitteryMethods = [ "emit" , "once" ] as const ; example @ Emittery . mixin ( Symbol . for ( "emittery" ) , emitteryMethods ) class PromiseQueue < T > { /**
     * Returns true if there are promises pending in the queue
     */ public isBusy ( ) { return this . #queue . length !== 0 ; } readonly #queue : Entry < T > [ ] = [ ] ; #tryResolve = ( queue , entry ) => { if ( entry === queue [ 0 ] ) { queue . shift ( ) ; entry . resolve ( entry . value ) ; this . #tryResolveChain ( queue ) ; } else { entry . resolved = true ; } } ; param promise returns add ( promise ) { const queue = this . #queue ; const entry = new Entry ( promise , queue , this . #tryResolve ) ; queue . push ( entry ) ; return entry . promise ; } /**
     * Clears all promises from the queue and sets their resolved values to the
     * given value.
     */ clear ( value ) { const cancelledQueue = this . #queue . splice ( 0 ) ; cancelledQueue . forEach ( entry => { entry . queue = cancelledQueue ; entry . value = value ; } ) ; } /**
     * Removes all _resolved_ promises from the front of the chain of promises.
     */ #tryResolveChain = ( queue ) => { let first = queue [ 0 ] ; while ( first && first . resolved ) { queue . shift ( ) ; first . resolve ( first . value ) ; first = queue [ 0 ] ; } if ( queue . length === 0 ) { this . emit ( "idle" ) ; } } ; } interface PromiseQueue < T > extends Pick < Emittery , typeof emitteryMethods [ number ] > { emittery : Emittery ; } export default PromiseQueue ;