/**
 * A deferred creates a promise and the ability to resolve or reject it
 */ export class Deferred < T > { private readonly p : Promise < T > ; private res : ( ( value : T | PromiseLike < T > ) => void ) | undefined ; private rej : ( ( reason ? : any ) => void ) | undefined ; private completed : boolean = false ; constructor ( ) { this . p = new Promise < T > ( ( resolve , reject ) => { this . res = resolve ; this . rej = reject ; } ) ; } /**
     * Returns whether the underlying promise has been completed
     */ public get isCompleted ( ) { return this . completed ; } returns public get promise ( ) : Promise < T > { return this . p ; } param value public resolve ( value ) { if ( this . res !== undefined ) { this . completed = true ; this . res ( value ) ; } } param value public reject ( error ) { if ( this . rej !== undefined ) { this . completed = true ; this . rej ( error ) ; } } } /**
 * A lazy evaluated promise. The execute function is delayed until
 * the promise is used, e.g. await, then, catch ...
 * The execute function is only called once.
 * All calls are then proxied to the promise returned by the execute method.
 */ export class LazyPromise < T > implements Promise < T > { public get [ Symbol . toStringTag ] ( ) : string { return this . getPromise ( ) [ Symbol . toStringTag ] ; } private result : Promise < T > | undefined ; constructor ( private readonly execute ) { } public async then < TResult1 = T , TResult2 = never > ( onfulfilled ? , onrejected ? ) { return this . getPromise ( ) . then < TResult1 , TResult2 > ( ... arguments ) ; } public async catch < TResult = never > ( onrejected ? ) { return this . getPromise ( ) . catch < TResult > ( ... arguments ) ; } public async finally ( onfinally ? ) { return this . getPromise ( ) . finally ( ... arguments ) ; } private async getPromise ( ) { if ( this . result === undefined ) { this . result = this . execute ( ) ; } return this . result ; } }