{"version":3,"sources":["../../src/use-timeout-fn/index.ts"],"sourcesContent":["import { useEffect, useRef } from 'react'\nimport { useLatest } from '../use-latest'\nimport { usePausable } from '../use-pausable'\nimport { useRender } from '../use-render'\nimport { unwrapGettable } from '../utils/unwrap'\n\nimport type { Pausable } from '../use-pausable'\nimport { type AnyFunc, type Gettable, type SetTimeoutReturn, noop } from '../utils/basic'\n\nexport interface UseTimeoutFnOptions {\n  /**\n   * Start the timer immediate after calling this function\n   *\n   * @defaultValue true\n   */\n  immediate?: boolean\n  /**\n   * Render the component immediately when the timer ends\n   *\n   * When you need `isActive` ref to be updated immediately after the timer ends, set this to `true`\n   *\n   * @defaultValue false\n   */\n  updateOnEnd?: boolean\n}\n\n/**\n * A React Hook that helps to create a timeout function.\n */\nexport function useTimeoutFn<Callback extends AnyFunc = AnyFunc>(\n  callback: Callback,\n  interval: Gettable<number>,\n  options: UseTimeoutFnOptions = {},\n): Pausable<[], Parameters<Callback>> {\n  const { immediate = true, updateOnEnd = false } = options\n  const render = useRender()\n  const timerRef = useRef<SetTimeoutReturn | null>(null)\n\n  function clearTimer() {\n    if (timerRef.current !== null) {\n      clearTimeout(timerRef.current)\n      timerRef.current = null\n    }\n  }\n\n  const pausable = usePausable(immediate, clearTimer, (ref, ...args: Parameters<Callback> | []) => {\n    const { interval, clearTimer } = latest.current\n\n    clearTimer()\n\n    timerRef.current = setTimeout(() => {\n      ref.current = false\n      timerRef.current = null\n\n      latest.current.callback(...args)\n\n      if (latest.current.updateOnEnd) {\n        render()\n      }\n    }, interval)\n  })\n\n  const intervalValue = unwrapGettable(interval)\n  const latest = useLatest({ clearTimer, callback, updateOnEnd, interval: intervalValue })\n\n  // biome-ignore lint/correctness/useExhaustiveDependencies: effect should re-run when intervalValue changes\n  useEffect(() => {\n    if (immediate) {\n      pausable.resume()\n    }\n    return immediate ? () => pausable.pause() : noop\n  }, [immediate, pausable, intervalValue])\n\n  return pausable\n}\n"],"names":["useTimeoutFn","callback","interval","options","immediate","updateOnEnd","render","useRender","timerRef","useRef","clearTimer","current","clearTimeout","pausable","usePausable","ref","args","latest","setTimeout","intervalValue","unwrapGettable","useLatest","useEffect","resume","pause","noop"],"mappings":";;;;+BA6BgBA;;;eAAAA;;;qBA7BkB;yBACR;2BACE;yBACF;sBACK;qBAG0C;;;;;;;;;;;;;;;;;;;;;;;;;;AAsBlE,SAASA,aACdC,QAAkB,EAClBC,QAA0B;QAC1BC,UAAAA,iEAA+B,CAAC;IAEhC,yBAAkDA,QAA1CC,WAAAA,4CAAY,kDAA8BD,QAAxBE,aAAAA,gDAAc;IACxC,IAAMC,SAASC,IAAAA,oBAAS;IACxB,IAAMC,WAAWC,IAAAA,aAAM,EAA0B;IAEjD,SAASC;QACP,IAAIF,SAASG,OAAO,KAAK,MAAM;YAC7BC,aAAaJ,SAASG,OAAO;YAC7BH,SAASG,OAAO,GAAG;QACrB;IACF;IAEA,IAAME,WAAWC,IAAAA,wBAAW,EAACV,WAAWM,YAAY,SAACK;yCAAQC;YAAAA;;QAC3D,IAAiCC,kBAAAA,OAAON,OAAO,EAAvCT,aAAyBe,gBAAzBf,UAAUQ,eAAeO,gBAAfP;QAElBA;QAEAF,SAASG,OAAO,GAAGO,WAAW;gBAI5BD;YAHAF,IAAIJ,OAAO,GAAG;YACdH,SAASG,OAAO,GAAG;YAEnBM,CAAAA,kBAAAA,OAAON,OAAO,EAACV,QAAQ,OAAvBgB,iBAAwB,qBAAGD;YAE3B,IAAIC,OAAON,OAAO,CAACN,WAAW,EAAE;gBAC9BC;YACF;QACF,GAAGJ;IACL;IAEA,IAAMiB,gBAAgBC,IAAAA,sBAAc,EAAClB;IACrC,IAAMe,SAASI,IAAAA,oBAAS,EAAC;QAAEX,YAAAA;QAAYT,UAAAA;QAAUI,aAAAA;QAAaH,UAAUiB;IAAc;IAEtF,2GAA2G;IAC3GG,IAAAA,gBAAS,EAAC;QACR,IAAIlB,WAAW;YACbS,SAASU,MAAM;QACjB;QACA,OAAOnB,YAAY;mBAAMS,SAASW,KAAK;YAAKC,WAAI;IAClD,GAAG;QAACrB;QAAWS;QAAUM;KAAc;IAEvC,OAAON;AACT"}