export type Deferred<T = any, R = Error> = { promise: Promise<T>; resolve: (t?: T) => void; reject: (r?: R) => void; readonly handled: boolean;};
export function defer<T = void>(): Deferred<T> { let handled = false; let resolve; let reject; const promise = new Promise<T>((res, rej) => { resolve = r => { handled = true; res(r); }; reject = r => { handled = true; rej(r); }; }); return { promise, resolve, reject, get handled() { return handled; } };}
export class TimeoutError extends Error {}
export function promiseInterrupter({ timeout = -1, cancel}: { timeout?: number; cancel?: Promise<void>;}): <T>(p: Promise<T>) => Promise<T> { timeout = Number.isInteger(timeout) ? timeout : -1; return <T>(p) => new Promise<T>((resolve, reject) => { if (timeout < 0) { p.then(resolve).catch(reject); if (cancel) { cancel.then(reject).catch(reject); } } else { const i = setTimeout(() => { reject(new TimeoutError()); }, timeout); const clear = () => clearTimeout(i); p.then(resolve) .catch(reject) .finally(clear); if (cancel) { cancel .then(reject) .catch(reject) .finally(clear); } } });}