{"version":3,"sources":["../src/retry.ts"],"sourcesContent":["type Milliseconds = number;\n\ntype RetryOptions = Partial<{\n  /**\n   * The initial delay before the first retry.\n   * @default 125\n   */\n  initialDelay: Milliseconds;\n  /**\n   * The maximum delay between retries.\n   * The delay between retries will never exceed this value.\n   * If set to 0, the delay will increase indefinitely.\n   * @default 0\n   */\n  maxDelayBetweenRetries: Milliseconds;\n  /**\n   * The multiplier for the exponential backoff.\n   * @default 2\n   */\n  factor: number;\n  /**\n   * A function to determine if the operation should be retried.\n   * The callback accepts the error that was thrown and the number of iterations.\n   * The iterations variable references the number of retries AFTER attempt\n   * that caused the error and starts at 1 (as in, this is the 1st, 2nd, nth retry).\n   * @default (error, iterations) => iterations < 5\n   */\n  shouldRetry: (error: unknown, iterations: number) => boolean;\n  /**\n   * Controls whether the helper should retry the operation immediately once before applying exponential backoff.\n   * The delay for the immediate retry is 100ms.\n   * @default false\n   */\n  retryImmediately: boolean;\n  /**\n   * If true, the intervals will be multiplied by a factor in the range of [1,2].\n   * @default true\n   */\n  jitter: boolean;\n}>;\n\nconst defaultOptions: Required<RetryOptions> = {\n  initialDelay: 125,\n  maxDelayBetweenRetries: 0,\n  factor: 2,\n  shouldRetry: (_: unknown, iteration: number) => iteration < 5,\n  retryImmediately: false,\n  jitter: true,\n};\n\nconst RETRY_IMMEDIATELY_DELAY = 100;\n\nconst sleep = async (ms: Milliseconds) => new Promise(s => setTimeout(s, ms));\n\nconst applyJitter = (delay: Milliseconds, jitter: boolean) => {\n  return jitter ? delay * (1 + Math.random()) : delay;\n};\n\nconst createExponentialDelayAsyncFn = (\n  opts: Required<Pick<RetryOptions, 'initialDelay' | 'maxDelayBetweenRetries' | 'factor' | 'jitter'>>,\n) => {\n  let timesCalled = 0;\n\n  const calculateDelayInMs = () => {\n    const constant = opts.initialDelay;\n    const base = opts.factor;\n    let delay = constant * Math.pow(base, timesCalled);\n    delay = applyJitter(delay, opts.jitter);\n    return Math.min(opts.maxDelayBetweenRetries || delay, delay);\n  };\n\n  return async (): Promise<void> => {\n    await sleep(calculateDelayInMs());\n    timesCalled++;\n  };\n};\n\n/**\n * Retries a callback until it succeeds or the shouldRetry function returns false.\n * See {@link RetryOptions} for the available options.\n */\nexport const retry = async <T>(callback: () => T | Promise<T>, options: RetryOptions = {}): Promise<T> => {\n  let iterations = 0;\n  const { shouldRetry, initialDelay, maxDelayBetweenRetries, factor, retryImmediately, jitter } = {\n    ...defaultOptions,\n    ...options,\n  };\n\n  const delay = createExponentialDelayAsyncFn({\n    initialDelay,\n    maxDelayBetweenRetries,\n    factor,\n    jitter,\n  });\n\n  while (true) {\n    try {\n      return await callback();\n    } catch (e) {\n      iterations++;\n      if (!shouldRetry(e, iterations)) {\n        throw e;\n      }\n      if (retryImmediately && iterations === 1) {\n        await sleep(applyJitter(RETRY_IMMEDIATELY_DELAY, jitter));\n      } else {\n        await delay();\n      }\n    }\n  }\n};\n"],"mappings":";AAyCA,IAAM,iBAAyC;AAAA,EAC7C,cAAc;AAAA,EACd,wBAAwB;AAAA,EACxB,QAAQ;AAAA,EACR,aAAa,CAAC,GAAY,cAAsB,YAAY;AAAA,EAC5D,kBAAkB;AAAA,EAClB,QAAQ;AACV;AAEA,IAAM,0BAA0B;AAEhC,IAAM,QAAQ,OAAO,OAAqB,IAAI,QAAQ,OAAK,WAAW,GAAG,EAAE,CAAC;AAE5E,IAAM,cAAc,CAAC,OAAqB,WAAoB;AAC5D,SAAO,SAAS,SAAS,IAAI,KAAK,OAAO,KAAK;AAChD;AAEA,IAAM,gCAAgC,CACpC,SACG;AACH,MAAI,cAAc;AAElB,QAAM,qBAAqB,MAAM;AAC/B,UAAM,WAAW,KAAK;AACtB,UAAM,OAAO,KAAK;AAClB,QAAI,QAAQ,WAAW,KAAK,IAAI,MAAM,WAAW;AACjD,YAAQ,YAAY,OAAO,KAAK,MAAM;AACtC,WAAO,KAAK,IAAI,KAAK,0BAA0B,OAAO,KAAK;AAAA,EAC7D;AAEA,SAAO,YAA2B;AAChC,UAAM,MAAM,mBAAmB,CAAC;AAChC;AAAA,EACF;AACF;AAMO,IAAM,QAAQ,OAAU,UAAgC,UAAwB,CAAC,MAAkB;AACxG,MAAI,aAAa;AACjB,QAAM,EAAE,aAAa,cAAc,wBAAwB,QAAQ,kBAAkB,OAAO,IAAI;AAAA,IAC9F,GAAG;AAAA,IACH,GAAG;AAAA,EACL;AAEA,QAAM,QAAQ,8BAA8B;AAAA,IAC1C;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF,CAAC;AAED,SAAO,MAAM;AACX,QAAI;AACF,aAAO,MAAM,SAAS;AAAA,IACxB,SAAS,GAAG;AACV;AACA,UAAI,CAAC,YAAY,GAAG,UAAU,GAAG;AAC/B,cAAM;AAAA,MACR;AACA,UAAI,oBAAoB,eAAe,GAAG;AACxC,cAAM,MAAM,YAAY,yBAAyB,MAAM,CAAC;AAAA,MAC1D,OAAO;AACL,cAAM,MAAM;AAAA,MACd;AAAA,IACF;AAAA,EACF;AACF;","names":[]}