All files timeout.ts

100% Statements 13/13
100% Branches 2/2
100% Functions 6/6
100% Lines 11/11

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 37 38 39 40 41 42 43 44 45 46 47 48 49 507x 7x                                             7x 2x           2x 2x   2x 1x             2x 1x   1x        
import { isError } from './index';
import { purry } from './purry';
 
/**
 * Prevents promise to execute longer than X ms
 * @param fn The function to invoke.
 * @param maxDuration - Duration in milliseconds
 * @throws If provided function executes longer than `maxDuration` milliseconds
 * @signature
 *    P.timeout(fn, milliseconds)
 * @signature
 *    P.timeout(milliseconds)(fn)
 * @example
 *    const req = P.timeout(request, 500)
 *    req({ ... }) // Will throw if function executes longer than 500ms
 * @category Utility, Pipe
 */
export function timeout<I extends any[], R>(
  fn: (...args: I) => Promise<R>,
  maxDuration: number
): (...args: I) => Promise<R>;
export function timeout<I extends any[], R>(
  maxDuration: number
): (fn: (...args: I) => Promise<R>) => (...args: I) => Promise<R>;
export function timeout() {
  return purry(_timeout, arguments);
}
function _timeout<I extends any[], R>(
  fn: (...args: I) => Promise<R>,
  maxDuration: number
): (...args: I) => Promise<R> {
  return (...args: I) => {
    return Promise.race([
      new Promise<Error>(resolve => {
        setTimeout(() => {
          resolve(
            new Error(`${fn.name} timeout after ${maxDuration}ms`.trim())
          );
        }, maxDuration);
      }),
      fn(...args),
    ]).then(q => {
      if (isError(q)) {
        throw q;
      }
      return q as R;
    });
  };
}