{"version":3,"sources":["../../src/use-retry-fn/index.ts"],"sourcesContent":["import { useCreation } from '../use-creation'\nimport { useLatest } from '../use-latest'\nimport { useStableFn } from '../use-stable-fn'\nimport { useVersionedAction } from '../use-versioned-action'\nimport { isFunction, wait } from '../utils/basic'\n\nimport type { AnyFunc } from '../utils/basic'\n\nexport interface UseRetryFnOptions<E = unknown> {\n  /**\n   * Number of retries.\n   *\n   * @defaultValue 3\n   */\n  count?: number\n  /**\n   * Retry interval. ms\n   *\n   * @defaultValue defaultRetryInterval\n   */\n  interval?: number | ((currentCount: number) => number)\n  /**\n   * Error callback.\n   *\n   * @defaultValue undefined\n   */\n  onError?: (error: E | undefined) => void\n  /**\n   * Error retry callback.\n   *\n   * @defaultValue undefined\n   */\n  onErrorRetry?: (error: E | undefined, state: UseRetryFnRetryState) => void\n  /**\n   * All retries failed callback.\n   *\n   * @defaultValue undefined\n   */\n  onRetryFailed?: (error: E | undefined, state: UseRetryFnRetryState) => void\n}\n\nexport interface UseRetryFnRetryState {\n  /**\n   * Current retry count.\n   */\n  currentCount: number\n  /**\n   * Number of retries.\n   */\n  retryCount: number\n  /**\n   * Internal unique version to track the latest retry state in multiple concurrent calls conditions.\n   */\n  version: object\n}\n\nexport function defaultRetryInterval(currentCount: number): number {\n  const nextInterval = 1000 * 2 ** (currentCount - 1)\n  return nextInterval >= 30_000 ? 30_000 : nextInterval\n}\n\n/**\n * A hook to retry the function when it fails.\n *\n * @since 1.4.0\n */\nexport function useRetryFn<T extends AnyFunc, E = any>(\n  fn: T,\n  options: UseRetryFnOptions<E> = {},\n): T & { cancel: () => void } {\n  const { count = 3, interval = defaultRetryInterval, onError, onErrorRetry, onRetryFailed } = options\n\n  const [incVersion, runVersionedAction] = useVersionedAction()\n\n  const latest = useLatest({\n    fn,\n    count,\n    interval,\n    onError,\n    onErrorRetry,\n    onRetryFailed,\n  })\n\n  const runFnWithRetry = useCreation(\n    () =>\n      async (retryState: UseRetryFnRetryState, ...args: Parameters<T>): Promise<Awaited<ReturnType<T>> | undefined> => {\n        try {\n          const result = await latest.current.fn(...args)\n\n          runVersionedAction(retryState.version, () => {\n            retryState.currentCount = 0\n          })\n\n          return result\n        } catch (error) {\n          return runVersionedAction(retryState.version, async () => {\n            retryState.currentCount++\n\n            const { onError, onErrorRetry, onRetryFailed, interval } = latest.current\n\n            onError?.(error as E | undefined)\n\n            if (retryState.currentCount > retryState.retryCount) {\n              onRetryFailed?.(error as E | undefined, { ...retryState })\n              retryState.currentCount = 0\n              return\n            }\n\n            const nextInterval = isFunction(interval) ? interval(retryState.currentCount) : interval\n\n            await wait(nextInterval)\n\n            onErrorRetry?.(error as E | undefined, { ...retryState })\n\n            return runFnWithRetry({ ...retryState }, ...args)\n          })\n        }\n      },\n  )\n\n  const fnWithRetry = (...args: Parameters<T>) => {\n    const retryState = {\n      currentCount: 0,\n      retryCount: latest.current.count,\n      version: incVersion(),\n    }\n\n    return runFnWithRetry(retryState, ...args)\n  }\n\n  const stableFnWithRetry = useStableFn(fnWithRetry as T & { cancel: () => void })\n\n  stableFnWithRetry.cancel = useStableFn(() => void incVersion())\n\n  return stableFnWithRetry\n}\n"],"names":["defaultRetryInterval","useRetryFn","currentCount","nextInterval","fn","options","count","interval","onError","onErrorRetry","onRetryFailed","useVersionedAction","incVersion","runVersionedAction","latest","useLatest","runFnWithRetry","useCreation","retryState","args","result","error","current","version","retryCount","isFunction","wait","fnWithRetry","stableFnWithRetry","useStableFn","cancel"],"mappings":";;;;;;;;;;;QAwDgBA;eAAAA;;QAUAC;eAAAA;;;2BAlEY;yBACF;2BACE;kCACO;qBACF;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAoD1B,SAASD,qBAAqBE,YAAoB;IACvD,IAAMC,eAAe,gBAAO,GAAMD,eAAe;IACjD,OAAOC,gBAAgB,QAAS,QAASA;AAC3C;AAOO,SAASF,WACdG,EAAK;QACLC,UAAAA,iEAAgC,CAAC;IAEjC,qBAA6FA,QAArFC,OAAAA,oCAAQ,wCAA6ED,QAA1EE,UAAAA,0CAAWP,0CAAsBQ,UAAyCH,QAAzCG,SAASC,eAAgCJ,QAAhCI,cAAcC,gBAAkBL,QAAlBK;IAE3E,IAAyCC,uCAAAA,IAAAA,sCAAkB,SAApDC,aAAkCD,wBAAtBE,qBAAsBF;IAEzC,IAAMG,SAASC,IAAAA,oBAAS,EAAC;QACvBX,IAAAA;QACAE,OAAAA;QACAC,UAAAA;QACAC,SAAAA;QACAC,cAAAA;QACAC,eAAAA;IACF;IAEA,IAAMM,iBAAiBC,IAAAA,wBAAW,EAChC;eACE,SAAOC;6CAAqCC;gBAAAA;;;oBAEnBL,iBAAfM,QAOCC;;;;;;;;;;4BAPQ;;gCAAMP,CAAAA,kBAAAA,OAAOQ,OAAO,EAAClB,EAAE,OAAjBU,iBAAkB,qBAAGK;;;4BAApCC,SAAS;4BAEfP,mBAAmBK,WAAWK,OAAO,EAAE;gCACrCL,WAAWhB,YAAY,GAAG;4BAC5B;4BAEA;;gCAAOkB;;;4BACAC;4BACP;;gCAAOR,mBAAmBK,WAAWK,OAAO,EAAE;;4CAGeT,iBAAnDN,SAASC,cAAcC,eAAeH,UAUxCJ;;;;oDAZNe,WAAWhB,YAAY;oDAEoCY,kBAAAA,OAAOQ,OAAO,EAAjEd,UAAmDM,gBAAnDN,SAASC,eAA0CK,gBAA1CL,cAAcC,gBAA4BI,gBAA5BJ,eAAeH,WAAaO,gBAAbP;oDAE9CC,oBAAAA,8BAAAA,QAAUa;oDAEV,IAAIH,WAAWhB,YAAY,GAAGgB,WAAWM,UAAU,EAAE;wDACnDd,0BAAAA,oCAAAA,cAAgBW,OAAwB,mBAAKH;wDAC7CA,WAAWhB,YAAY,GAAG;wDAC1B;;;oDACF;oDAEMC,eAAesB,IAAAA,iBAAU,EAAClB,YAAYA,SAASW,WAAWhB,YAAY,IAAIK;oDAEhF;;wDAAMmB,IAAAA,WAAI,EAACvB;;;oDAAX;oDAEAM,yBAAAA,mCAAAA,aAAeY,OAAwB,mBAAKH;oDAE5C;;wDAAOF,qBAAAA,KAAAA,GAAAA;4DAAe,mBAAKE;0DAApBF,OAAkC,qBAAGG;;;;oCAC9C;;;;;;;;;YAEJ;;;IAGJ,IAAMQ,cAAc;yCAAIR;YAAAA;;QACtB,IAAMD,aAAa;YACjBhB,cAAc;YACdsB,YAAYV,OAAOQ,OAAO,CAAChB,KAAK;YAChCiB,SAASX;QACX;QAEA,OAAOI,qBAAAA,KAAAA,GAAAA;YAAeE;SAAoB,CAAnCF,OAA2B,qBAAGG;IACvC;IAEA,IAAMS,oBAAoBC,IAAAA,wBAAW,EAACF;IAEtCC,kBAAkBE,MAAM,GAAGD,IAAAA,wBAAW,EAAC;eAAM,KAAKjB;;IAElD,OAAOgB;AACT"}