All files / utils/async with-timeout.ts

100% Statements 5/5
100% Branches 0/0
100% Functions 2/2
100% Lines 3/3

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 3713x                                                             13x       8x  
import { delay } from './delay.ts';
 
/**
 * Wraps a given promise and resolves with its value if it completes within the specified timeout. If the timeout
 * elapses, the returned promise resolves with a provided fallback value or undefined if no `timeoutValue` is provided.
 *
 * Note: The original promise continues to run in the background even if the timeout occurs. If caching promises,
 * consider caching the original promise instead of the timed one, since it may resolve successfully on a subsequent
 * access.
 *
 * @example
 *
 * ```ts
 * const promise: Promise<string | undefined> = withTimeout(fetchContent(uri), 5000);
 * const content: string = await promise.then((value) => value ?? '');
 * ```
 *
 * @example
 *
 * ```ts
 * const promise: Promise<string | -1> = withTimeout(fetchContent(uri), 5000, -1);
 * const content: string | undefined = await promise.then((value) => (value === -1 ? undefined : value));
 * ```
 *
 * @param promise The promise to be wrapped with a timeout.
 * @param timeout The maximum duration (in milliseconds) to wait before resolving with `timeoutValue`. (0 if negatived,
 *   and ceil if decimal).
 * @param timeoutValue The value to resolve with if the timeout is reached before the promise completes.
 * @returns A promise that resolves with the original promise's value if completed within the timeout, or with
 *   `timeoutValue` otherwise.
 */
export const withTimeout = <T, const R = undefined>(
  promise: Promise<T>,
  timeout: number,
  timeoutValue?: R,
): Promise<T | R> => Promise.race<T | R>([promise, delay(timeout).then(() => timeoutValue as R)]);