/** Default maximum duration for API dependency work. */ export const duration = 15_000 /** Returns a caller signal or a signal carrying the default deadline. */ export function signal(options: signal.Options = {}): AbortSignal { return options.signal ?? AbortSignal.timeout(options.timeout ?? duration) } export declare namespace signal { /** Options for {@link signal}. */ type Options = { /** Existing caller signal. */ signal?: AbortSignal | null | undefined /** Default maximum duration in milliseconds. */ timeout?: number | undefined } } /** Waits for a duration, rejecting immediately when `signal` aborts. */ export function wait(options: wait.Options): Promise { options.signal.throwIfAborted() return new Promise((resolve, reject) => { const abort = () => { clearTimeout(timer) reject(options.signal.reason) } const timer = setTimeout(() => { options.signal.removeEventListener('abort', abort) resolve() }, options.milliseconds) options.signal.addEventListener('abort', abort, { once: true }) }) } export declare namespace wait { /** Options for {@link wait}. */ type Options = { /** Duration to wait in milliseconds. */ milliseconds: number /** Signal that cancels the wait. */ signal: AbortSignal } } /** Runs asynchronous work under a hard deadline and aborts cooperative work. */ export function run( work: (signal: AbortSignal) => Promise, options: run.Options = {}, ): Promise { const timeout = options.timeout ?? duration const controller = new AbortController() const timeoutError = new DOMException(`Timed out after ${timeout}ms.`, 'TimeoutError') const error = options.error ?? timeoutError const timer = setTimeout(() => controller.abort(timeoutError), timeout) const operation = Promise.resolve().then(() => work(controller.signal)) return Promise.race([ operation, new Promise((_, reject) => { controller.signal.addEventListener('abort', () => reject(error), { once: true }) }), ]).finally(() => clearTimeout(timer)) } export declare namespace run { /** Options for {@link run}. */ type Options = { /** Error returned to the caller when the deadline expires. */ error?: Error | undefined /** Maximum duration in milliseconds. */ timeout?: number | undefined } }