/** * Base interface representing a timeout subscriber. */ export interface TimeoutSubscriber { on_time: (handler: (arg: T) => any) => TimeoutSubscriber, late: (handler: (arg: T) => any) => TimeoutSubscriber, timeout: (handler: () => any) => TimeoutSubscriber, run: () => Promise, } /** * Subscribe to a promise with a timeout. * @param {number} timeout - timeout in milliseconds * @param {Promise} promise - the promise to subscribe to */ export function withTimeout(timeout: number, promise: Promise) { let on_time_handler: (arg: T) => any = (arg) => {} let late_handler: (arg: T) => any = (arg) => {} let timeout_handler: () => any = () => {} const sub = { on_time: handler => { on_time_handler = handler return sub }, late: handler => { late_handler = handler return sub }, timeout: handler => { timeout_handler = handler return sub }, run: async () => { let expired = false let resolved = false setTimeout(() => { expired = true if ( !resolved ) timeout_handler() }, timeout) const result: T = await promise resolved = true if ( !expired ) { await on_time_handler(result) } else { await late_handler(result) } return result } } as TimeoutSubscriber return sub }