export class Semaphore { queue : ( ( v : boolean ) => void ) [ ] = [ ] ; available = 1 ; async acquire ( ) { if ( this . available > 0 ) { this . available -= 1 ; return Promise . resolve ( true ) ; } return new Promise ( resolver => this . queue . push ( resolver ) ) ; } release ( ) { this . available += 1 ; if ( this . available > 1 && this . queue . length > 0 ) { throw new Error ( 'this.available should never be > 0 when there is someone waiting.' ) ; } else if ( this . available === 1 && this . queue . length > 0 ) { this . available -= 1 ; const nextResolver = this . queue . shift ( ) ; if ( nextResolver ) { nextResolver ( true ) ; } } } }