{"version":3,"file":"retry-DqRIhHV5.mjs","names":[],"sources":["../../src/retry.ts"],"sourcesContent":["type Milliseconds = number;\n\ntype RetryOptions = Partial<{\n  /**\n   * The initial delay before the first retry.\n   *\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   *\n   * @default 0\n   */\n  maxDelayBetweenRetries: Milliseconds;\n  /**\n   * The multiplier for the exponential backoff.\n   *\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   *\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   *\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   *\n   * @default true\n   */\n  jitter: boolean;\n\n  /**\n   * A callback that is invoked before each retry attempt.\n   * The callback receives the iteration number (starting from 1 for the first retry).\n   * This can be used to modify request parameters, add headers, etc.\n   */\n  onBeforeRetry?: (iteration: number) => void | Promise<void>;\n}>;\n\nconst defaultOptions = {\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, onBeforeRetry } = {\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\n      if (onBeforeRetry) {\n        await onBeforeRetry(iterations);\n      }\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":";AAsDA,MAAM,iBAAiB;CACrB,cAAc;CACd,wBAAwB;CACxB,QAAQ;CACR,cAAc,GAAY,cAAsB,YAAY;CAC5D,kBAAkB;CAClB,QAAQ;CACT;AAED,MAAM,0BAA0B;AAEhC,MAAM,QAAQ,OAAO,OAAqB,IAAI,SAAQ,MAAK,WAAW,GAAG,GAAG,CAAC;AAE7E,MAAM,eAAe,OAAqB,WAAoB;AAC5D,QAAO,SAAS,SAAS,IAAI,KAAK,QAAQ,IAAI;;AAGhD,MAAM,iCACJ,SACG;CACH,IAAI,cAAc;CAElB,MAAM,2BAA2B;EAC/B,MAAM,WAAW,KAAK;EACtB,MAAM,OAAO,KAAK;EAClB,IAAI,QAAQ,WAAW,KAAK,IAAI,MAAM,YAAY;AAClD,UAAQ,YAAY,OAAO,KAAK,OAAO;AACvC,SAAO,KAAK,IAAI,KAAK,0BAA0B,OAAO,MAAM;;AAG9D,QAAO,YAA2B;AAChC,QAAM,MAAM,oBAAoB,CAAC;AACjC;;;;;;;AAQJ,MAAa,QAAQ,OAAU,UAAgC,UAAwB,EAAE,KAAiB;CACxG,IAAI,aAAa;CACjB,MAAM,EAAE,aAAa,cAAc,wBAAwB,QAAQ,kBAAkB,QAAQ,kBAAkB;EAC7G,GAAG;EACH,GAAG;EACJ;CAED,MAAM,QAAQ,8BAA8B;EAC1C;EACA;EACA;EACA;EACD,CAAC;AAEF,QAAO,KACL,KAAI;AACF,SAAO,MAAM,UAAU;UAChB,GAAG;AACV;AACA,MAAI,CAAC,YAAY,GAAG,WAAW,CAC7B,OAAM;AAGR,MAAI,cACF,OAAM,cAAc,WAAW;AAGjC,MAAI,oBAAoB,eAAe,EACrC,OAAM,MAAM,YAAY,yBAAyB,OAAO,CAAC;MAEzD,OAAM,OAAO"}