export const TIMEOUT_ERROR = Symbol('timeout'); export async function timeout(thenable: Promise, ms?: number | undefined): Promise { let timer: NodeJS.Timeout | null = null; const timeout = new Promise((_, reject) => { timer = setTimeout(reject, ms, TIMEOUT_ERROR); }); return Promise.race([thenable, timeout]).finally(() => { timer && clearTimeout(timer); }); } export async function timeoutSafe(thenable: Promise): Promise; export async function timeoutSafe(thenable: Promise, ms: number | undefined, fallback: T): Promise; export async function timeoutSafe( thenable: Promise, ms?: number | undefined, fallback?: T, ): Promise { return timeout(thenable, ms).catch(error => { if (error === TIMEOUT_ERROR) return fallback; throw error; }); }