{"version":3,"file":"index.mjs","sources":["../src/useDebouncedCallback.ts","../src/useDebounce.ts","../src/useThrottledCallback.ts"],"sourcesContent":["import {\n  useRef,\n  useEffect,\n  useMemo,\n  type Dispatch,\n  type SetStateAction,\n} from 'react';\n\nexport interface CallOptions {\n  /**\n   * Controls if the function should be invoked on the leading edge of the timeout.\n   */\n  leading?: boolean;\n  /**\n   * Controls if the function should be invoked on the trailing edge of the timeout.\n   */\n  trailing?: boolean;\n  /**\n   * Controls if the function should be invoked when the React component unmounts or\n   * the page is closed. This is usually desirable whenever `func` has persistent side-effects\n   * such as persists data.\n   *\n   * NOTE: If the callback calls `fetch()`, you usually also want to specify the `keepalive=true`\n   * option for `fetch()` so it can finish in the background after the page is closed.\n   *\n   * This option has no effect if `trailing == false`.\n   */\n  flushOnExit?: boolean;\n}\n\nexport interface Options extends CallOptions {\n  /**\n   * The maximum time the given function is allowed to be delayed before it's invoked.\n   */\n  maxWait?: number;\n  /**\n   * If the setting is set to true, all debouncing and timers will happen on the server side as well\n   */\n  debounceOnServer?: boolean;\n}\n\nexport interface ControlFunctions<ReturnT> {\n  /**\n   * Cancel pending function invocations\n   */\n  cancel: () => void;\n  /**\n   * Immediately invoke pending function invocations\n   */\n  flush: () => ReturnT | undefined;\n  /**\n   * Returns `true` if there are any pending function invocations\n   */\n  isPending: () => boolean;\n}\n\n/**\n * Subsequent calls to the debounced function return the result of the last func invocation.\n * Note, that if there are no previous invocations you will get undefined. You should check it in your code properly.\n */\nexport interface DebouncedState<T extends (...args: any) => ReturnType<T>>\n  extends ControlFunctions<ReturnType<T>> {\n  (...args: Parameters<T>): ReturnType<T> | undefined;\n}\n\n/**\n * Creates a debounced function that delays invoking `func` until after `wait`\n * milliseconds have elapsed since the last time the debounced function was\n * invoked, or until the next browser frame is drawn.\n *\n * The debounced function comes with a `cancel` method to cancel delayed `func`\n * invocations and a `flush` method to immediately invoke them.\n *\n * Provide `options` to indicate whether `func` should be invoked on the leading\n * and/or trailing edge of the `wait` timeout. The `func` is invoked with the\n * last arguments provided to the debounced function.\n *\n * Subsequent calls to the debounced function return the result of the last\n * `func` invocation.\n *\n * **Note:** If `leading` and `trailing` options are `true`, `func` is\n * invoked on the trailing edge of the timeout only if the debounced function\n * is invoked more than once during the `wait` timeout.\n *\n * If `wait` is `0` and `leading` is `false`, `func` invocation is deferred\n * until the next tick, similar to `setTimeout` with a timeout of `0`.\n *\n * If `wait` is omitted in an environment with `requestAnimationFrame`, `func`\n * invocation will be deferred until the next frame is drawn (typically about\n * 16ms).\n *\n * See [David Corbacho's article](https://css-tricks.com/debouncing-throttling-explained-examples/)\n * for details over the differences between `debounce` and `throttle`.\n *\n * @category Function\n * @param {Function} func The function to debounce.\n * @param {number} [wait=0]\n *  The number of milliseconds to delay; if omitted, `requestAnimationFrame` is\n *  used (if available, otherwise it will be setTimeout(...,0)).\n * @param {Object} [options={}] The options object.\n *  Controls if `func` should be invoked on the leading edge of the timeout.\n * @param {boolean} [options.leading=false]\n *  The maximum time `func` is allowed to be delayed before it's invoked.\n * @param {number} [options.maxWait]\n *  Controls if `func` should be invoked the trailing edge of the timeout.\n * @param {boolean} [options.trailing=true]\n * @returns {Function} Returns the new debounced function.\n * @example\n *\n * // Avoid costly calculations while the window size is in flux.\n * const resizeHandler = useDebouncedCallback(calculateLayout, 150);\n * window.addEventListener('resize', resizeHandler)\n *\n * // Invoke `sendMail` when clicked, debouncing subsequent calls.\n * const clickHandler = useDebouncedCallback(sendMail, 300, {\n *   leading: true,\n *   trailing: false,\n * })\n * <button onClick={clickHandler}>click me</button>\n *\n * // Ensure `batchLog` is invoked once after 1 second of debounced calls.\n * const debounced = useDebouncedCallback(batchLog, 250, { 'maxWait': 1000 })\n * const source = new EventSource('/stream')\n * source.addEventListener('message', debounced)\n *\n * // Cancel the trailing debounced invocation.\n * window.addEventListener('popstate', debounced.cancel)\n *\n * // Check for pending invocations.\n * const status = debounced.isPending() ? \"Pending...\" : \"Ready\"\n */\nexport default function useDebouncedCallback<\n  T extends (...args: any) => ReturnType<T>,\n>(\n  func: T,\n  wait?: number,\n  options?: Options,\n  forceUpdate?: Dispatch<SetStateAction<object>>\n): DebouncedState<T> {\n  const lastCallTime = useRef(null);\n  const lastInvokeTime = useRef(0);\n  const firstInvokeTime = useRef(0);\n  const timerId = useRef(null);\n  const lastArgs = useRef<unknown[]>([]);\n  const lastThis = useRef<unknown>();\n  const result = useRef<ReturnType<T>>();\n  const funcRef = useRef(func);\n  const mounted = useRef(true);\n  const visibilityListener = useRef<VoidFunction>();\n  const debouncedRef = useRef<DebouncedState<T>>();\n  // Always keep the latest version of debounce callback, with no wait time.\n  funcRef.current = func;\n\n  const isClientSide = typeof window !== 'undefined';\n  // Bypass `requestAnimationFrame` by explicitly setting `wait=0`.\n  const useRAF = !wait && wait !== 0 && isClientSide;\n\n  if (typeof func !== 'function') {\n    throw new TypeError('Expected a function');\n  }\n\n  wait = +wait || 0;\n  options = options || {};\n\n  const leading = !!options.leading;\n  const trailing = 'trailing' in options ? !!options.trailing : true; // `true` by default\n  const flushOnExit = !!options.flushOnExit && trailing;\n  const maxing = 'maxWait' in options;\n  const debounceOnServer =\n    'debounceOnServer' in options ? !!options.debounceOnServer : false; // `false` by default\n  const maxWait = maxing ? Math.max(+options.maxWait || 0, wait) : null;\n\n  // You may have a question, why we have so many code under the useMemo definition.\n  //\n  // This was made as we want to escape from useCallback hell and\n  // not to initialize a number of functions each time useDebouncedCallback is called.\n  //\n  // It means that we have less garbage for our GC calls which improves performance.\n  // Also, it makes this library smaller.\n  //\n  // And the last reason, that the code without lots of useCallback with deps is easier to read.\n  // You have only one place for that.\n  const debounced = useMemo(() => {\n    const invokeFunc = (time: number) => {\n      const args = lastArgs.current;\n      const thisArg = lastThis.current;\n      lastArgs.current = lastThis.current = null;\n      lastInvokeTime.current = time;\n      firstInvokeTime.current = firstInvokeTime.current || time;\n\n      return (result.current = funcRef.current.apply(thisArg, args));\n    };\n\n    const startTimer = (pendingFunc: () => void, wait: number) => {\n      if (useRAF) cancelAnimationFrame(timerId.current);\n      timerId.current = useRAF\n        ? requestAnimationFrame(pendingFunc)\n        : setTimeout(pendingFunc, wait);\n    };\n\n    const shouldInvoke = (time: number) => {\n      if (!mounted.current) return false;\n\n      const timeSinceLastCall = time - lastCallTime.current;\n      const timeSinceLastInvoke = time - lastInvokeTime.current;\n\n      // Either this is the first call, activity has stopped and we're at the\n      // trailing edge, the system time has gone backwards and we're treating\n      // it as the trailing edge, or we've hit the `maxWait` limit.\n      return (\n        !lastCallTime.current ||\n        timeSinceLastCall >= wait ||\n        timeSinceLastCall < 0 ||\n        (maxing && timeSinceLastInvoke >= maxWait)\n      );\n    };\n\n    const trailingEdge = (time: number) => {\n      timerId.current = null;\n\n      // Only invoke if we have `lastArgs` which means `func` has been\n      // debounced at least once.\n      if (trailing && lastArgs.current) {\n        return invokeFunc(time);\n      }\n\n      lastArgs.current = lastThis.current = null;\n      return result.current;\n    };\n\n    const timerExpired = () => {\n      const time = Date.now();\n\n      if (leading && firstInvokeTime.current === lastInvokeTime.current) {\n        notifyManuallyTimerExpired();\n      }\n\n      if (shouldInvoke(time)) {\n        return trailingEdge(time);\n      }\n      // https://github.com/xnimorz/use-debounce/issues/97\n      if (!mounted.current) {\n        return;\n      }\n      // Remaining wait calculation\n      const timeSinceLastCall = time - lastCallTime.current;\n      const timeSinceLastInvoke = time - lastInvokeTime.current;\n      const timeWaiting = wait - timeSinceLastCall;\n      const remainingWait = maxing\n        ? Math.min(timeWaiting, maxWait - timeSinceLastInvoke)\n        : timeWaiting;\n\n      // Restart the timer\n      startTimer(timerExpired, remainingWait);\n    };\n\n    const notifyManuallyTimerExpired = () => {\n      if (forceUpdate) {\n        forceUpdate({});\n      }\n    };\n\n    const func: DebouncedState<T> = (...args: Parameters<T>): ReturnType<T> => {\n      if (!isClientSide && !debounceOnServer) {\n        return;\n      }\n      const time = Date.now();\n      const isInvoking = shouldInvoke(time);\n\n      lastArgs.current = args;\n      lastThis.current = this;\n      lastCallTime.current = time;\n\n      if (flushOnExit && !visibilityListener.current) {\n        visibilityListener.current = () => {\n          if (globalThis.document?.visibilityState === 'hidden') {\n            debouncedRef.current.flush();\n          }\n        };\n        globalThis.document?.addEventListener?.(\n          'visibilitychange',\n          visibilityListener.current\n        );\n      }\n      if (isInvoking) {\n        if (!timerId.current && mounted.current) {\n          // Reset any `maxWait` timer.\n          lastInvokeTime.current = lastCallTime.current;\n          // Start the timer for the trailing edge.\n          startTimer(timerExpired, wait);\n          // Invoke the leading edge.\n          return leading ? invokeFunc(lastCallTime.current) : result.current;\n        }\n        if (maxing) {\n          // Handle invocations in a tight loop.\n          startTimer(timerExpired, wait);\n          return invokeFunc(lastCallTime.current);\n        }\n      }\n      if (!timerId.current) {\n        startTimer(timerExpired, wait);\n      }\n      return result.current;\n    };\n\n    func.cancel = () => {\n      const hadTimer = timerId.current;\n      if (hadTimer) {\n        useRAF\n          ? cancelAnimationFrame(timerId.current)\n          : clearTimeout(timerId.current);\n      }\n      lastInvokeTime.current = 0;\n      lastArgs.current =\n        lastCallTime.current =\n        lastThis.current =\n        timerId.current =\n          null;\n\n      // Notify React to re-render when cancel is called and there was an active timer\n      if (hadTimer && forceUpdate) {\n        forceUpdate({});\n      }\n    };\n\n    func.isPending = () => {\n      return !!timerId.current;\n    };\n\n    func.flush = () => {\n      return !timerId.current ? result.current : trailingEdge(Date.now());\n    };\n\n    return func;\n  }, [\n    leading,\n    maxing,\n    wait,\n    maxWait,\n    trailing,\n    flushOnExit,\n    useRAF,\n    isClientSide,\n    debounceOnServer,\n    forceUpdate,\n  ]);\n\n  // Store reference to debounced function for cleanup\n  debouncedRef.current = debounced;\n\n  useEffect(() => {\n    mounted.current = true;\n    return () => {\n      if (flushOnExit) {\n        debouncedRef.current.flush();\n      }\n      if (visibilityListener.current) {\n        globalThis.document?.removeEventListener?.(\n          'visibilitychange',\n          visibilityListener.current\n        );\n        visibilityListener.current = null;\n      }\n      mounted.current = false;\n    };\n  }, [flushOnExit]);\n\n  return debounced;\n}\n","import { useCallback, useRef, useState } from 'react';\nimport useDebouncedCallback, { DebouncedState } from './useDebouncedCallback';\n\nfunction valueEquality<T>(left: T, right: T): boolean {\n  return left === right;\n}\n\nexport default function useDebounce<T>(\n  value: T,\n  delay: number,\n  options?: {\n    maxWait?: number;\n    leading?: boolean;\n    trailing?: boolean;\n    equalityFn?: (left: T, right: T) => boolean;\n  }\n): [T, DebouncedState<(value: T) => void>] {\n  const eq = (options && options.equalityFn) || valueEquality;\n\n  const activeValue = useRef(value);\n  const [, forceUpdate] = useState({});\n  const debounced = useDebouncedCallback(\n    useCallback(\n      (value: T) => {\n        activeValue.current = value;\n        forceUpdate({});\n      },\n      [forceUpdate]\n    ),\n    delay,\n    options,\n    forceUpdate\n  );\n  const previousValue = useRef(value);\n\n  if (!eq(previousValue.current, value)) {\n    debounced(value);\n    previousValue.current = value;\n  }\n\n  return [activeValue.current as T, debounced];\n}\n","import useDebouncedCallback, {\n  CallOptions,\n  DebouncedState,\n} from './useDebouncedCallback';\n\n/**\n * Creates a throttled function that only invokes `func` at most once per\n * every `wait` milliseconds (or once per browser frame).\n *\n * The throttled function comes with a `cancel` method to cancel delayed `func`\n * invocations and a `flush` method to immediately invoke them.\n *\n * Provide `options` to indicate whether `func` should be invoked on the leading\n * and/or trailing edge of the `wait` timeout. The `func` is invoked with the\n * last arguments provided to the throttled function.\n *\n * Subsequent calls to the throttled function return the result of the last\n * `func` invocation.\n *\n * **Note:** If `leading` and `trailing` options are `true`, `func` is\n * invoked on the trailing edge of the timeout only if the throttled function\n * is invoked more than once during the `wait` timeout.\n *\n * If `wait` is `0` and `leading` is `false`, `func` invocation is deferred\n * until the next tick, similar to `setTimeout` with a timeout of `0`.\n *\n * If `wait` is omitted in an environment with `requestAnimationFrame`, `func`\n * invocation will be deferred until the next frame is drawn (typically about\n * 16ms).\n *\n * See [David Corbacho's article](https://css-tricks.com/debouncing-throttling-explained-examples/)\n * for details over the differences between `throttle` and `debounce`.\n *\n * @category Function\n * @param {Function} func The function to throttle.\n * @param {number} [wait=0]\n *  The number of milliseconds to throttle invocations to; if omitted,\n *  `requestAnimationFrame` is used (if available, otherwise it will be setTimeout(...,0)).\n * @param {Object} [options={}] The options object.\n * @param {boolean} [options.leading=true]\n *  Specify invoking on the leading edge of the timeout.\n * @param {boolean} [options.trailing=true]\n *  Specify invoking on the trailing edge of the timeout.\n * @returns {Function} Returns the new throttled function.\n * @example\n *\n * // Avoid excessively updating the position while scrolling.\n * const scrollHandler = useThrottledCallback(updatePosition, 100)\n * window.addEventListener('scroll', scrollHandler)\n *\n * // Invoke `renewToken` when the click event is fired, but not more than once every 5 minutes.\n * const throttled = useThrottledCallback(renewToken, 300000, { 'trailing': false })\n * <button onClick={throttled}>click</button>\n *\n * // Cancel the trailing throttled invocation.\n * window.addEventListener('popstate', throttled.cancel);\n */\nexport default function useThrottledCallback<\n  T extends (...args: any) => ReturnType<T>,\n>(\n  func: T,\n  wait: number,\n  { leading = true, trailing = true, flushOnExit = false }: CallOptions = {}\n): DebouncedState<T> {\n  return useDebouncedCallback(func, wait, {\n    maxWait: wait,\n    leading,\n    trailing,\n    flushOnExit,\n  });\n}\n"],"names":["useDebouncedCallback","func","wait","options","forceUpdate","lastCallTime","useRef","lastInvokeTime","firstInvokeTime","timerId","lastArgs","lastThis","result","funcRef","mounted","visibilityListener","debouncedRef","current","isClientSide","window","useRAF","TypeError","leading","trailing","flushOnExit","maxing","debounceOnServer","maxWait","Math","max","debounced","useMemo","invokeFunc","time","args","thisArg","apply","startTimer","pendingFunc","cancelAnimationFrame","requestAnimationFrame","setTimeout","shouldInvoke","timeSinceLastCall","trailingEdge","timerExpired","Date","now","notifyManuallyTimerExpired","timeWaiting","remainingWait","min","isInvoking","_globalThis$document2","this","_globalThis$document","globalThis","document","visibilityState","flush","addEventListener","cancel","hadTimer","clearTimeout","isPending","useEffect","_globalThis$document3","removeEventListener","valueEquality","left","right","useDebounce","value","delay","eq","equalityFn","activeValue","useState","useCallback","previousValue","useThrottledCallback"],"mappings":"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"}