import type { AnyToAnyFnSignature } from '../misc/functions' ; returns export function promisifyTimeout < T > ( timeout , payload ? ) { return new Promise < T > ( ( resolve ) => setTimeout ( resolve . bind ( null , payload ) , timeout ) ) ; } /** Interface to describe abstract listenable target */ export type ListenableTarget = { addEventListener : ( event : string , callback : ( payload : any ) => void , options ? : boolean | AddEventListenerOptions | undefined ) => void ; removeEventListener : ( event : string , callback : ( payload : any ) => void , options ? : boolean | AddEventListenerOptions | undefined ) => void ; } ; returns export function promisifyEvent ( target , event , timeout ? , options ? ) { return new Promise ( ( resolve , reject ) => { function eventCallback ( e ) { target . removeEventListener ( event , eventCallback , options ) ; resolve ( e ) ; } target . addEventListener ( event , eventCallback , options ) ; if ( typeof timeout === 'number' && timeout >= 0 ) { setTimeout ( ( ) => reject ( new Error ( 'Rejected by timeout' ) ) , timeout ) ; } } ) ; } returns example export function promisifyMarker ( target , marker , event = marker ) { if ( ( target as any ) [ marker ] ) return Promise . resolve ( target ) ; return promisifyEvent ( target , event ) . then ( ( ) => target ) ; } returns export function tryUntil < T > ( callback , tryCount = 2 , timeout = 100 ) { return new Promise ( ( resolve , reject ) => { ( function check ( ) : void { let result ; try { result = callback ( ) ; } catch { result = undefined ; } if ( result || ( tryCount -- ) < 0 ) { result ? resolve ( result ) : reject ( new Error ( 'Rejected by limit of tries' ) ) ; } else { setTimeout ( check , timeout ) ; } } ) ( ) ; } ) ; } param callback param count returns export function repeatSequence < T > ( callback , count = 1 ) { if ( count < 1 ) return Promise . reject ( ) ; if ( count === 1 ) return Promise . resolve ( ) . then ( callback ) ; return repeatSequence ( callback , count - 1 ) . then ( callback ) ; } /** Deferred object represents promise with it's resolve/reject methods */ export type Deferred < T > = { /** Wrapped promise */ promise : Promise < T > ; /** Function that resolves wrapped promise */ resolve : ( arg : T ) => void ; /** Function that rejects wrapped promise */ reject : ( arg ? : any ) => void ; } ; /**
 * Create Deferred Object that wraps promise and its resolve and reject callbacks
 */ export function createDeferred < T > ( ) { let reject ; let resolve ; const promise = new Promise < T > ( ( res , rej ) => { resolve = res ; reject = rej ; } ) ; return { promise , resolve , reject } ; } /** Creates function type with the same signature but with the result type wrapped into promise */ export type PromisifyResultFn < F extends AnyToAnyFnSignature > = ( ( ... args : Parameters < F > ) => Promise < ReturnType < F > | void > ) ; example export function resolvePromise < T > ( arg ) { return Promise . resolve ( arg ) ; } example export function rejectPromise < T = never > ( arg ? ) { return Promise . reject ( arg ) ; } /**
 * Promise utils helper class
 * Note: use individual methods in case you need correct "tree shaking"
 */ export abstract class PromiseUtils { static fromTimeout = promisifyTimeout ; static fromEvent = promisifyEvent ; static fromMarker = promisifyMarker ; static repeat = repeatSequence ; static tryUntil = tryUntil ; static deferred = createDeferred ; static resolve = resolvePromise ; static reject = rejectPromise ; }