import { Falsy } from 'justypes' import { SyncDestructor } from 'extra-defer' /** * @throws {AbortError} */ export async function withAbortSignal( signal: AbortSignal | Falsy , fn: () => PromiseLike ): Promise { return new Promise(async (resolve, reject) => { const destructor = new SyncDestructor() if (signal) { if (signal.aborted) { reject(signal.reason) return } const handler = () => reject(signal.reason) signal.addEventListener('abort', handler) destructor.defer(() => signal.removeEventListener('abort', handler)) } try { resolve(await fn()) } catch (e) { reject(e) } finally { destructor.execute() } }) }