'use strict';

Object.defineProperty(exports, '__esModule', { value: true });

var React = require('react');

/**
 * Debounce updates to a provided value
 *
 * @param value New value to set as
 * @param delay Number of milliseconds to delay updating value
 * @returns Debounced value
 */
function useDebouncedValue(value, delay) {
    const [debouncedValue, setDebouncedValue] = React.useState(value);
    React.useEffect(() => {
        const handler = setTimeout(() => {
            setDebouncedValue(value);
        }, delay);
        return () => {
            clearTimeout(handler);
        };
    }, [value]);
    return debouncedValue;
}
/**
 * @deprecated Prefer using `useDebouncedValue` instead
 */
const useDebounce = useDebouncedValue;
/**
 * Debounce dispatching a function.
 *
 * By default the function will wait [timeout] amount of time before
 * dispatching the function. If the [leading] arg is set to `true`, then
 * this logic will change to dispatching on the first request and ignoring
 * all subsequent requests in the [timeout] period proceeding.
 *
 * @param fn Function to be called
 * @param timeout Number of milliseconds
 * @param leading If the dispatch should fire on the leading request. Default is last recieved request.
 * @returns Dispatch function
 * @see https://www.freecodecamp.org/news/javascript-debounce-example/
 * @example
 *  const fn = useDebouncedFn(() => {}, 1000);
 *  fn();
 *  fn();
 *  fn(); <-- only this one will run
 * @example
 *  const fn = useDebouncedFn(() => {}, 1000, true);
 *  fn(); <-- only this one will run
 *  fn();
 *  fn();
 */
function useDebouncedFn(fn, timeout, leading) {
    let timer;
    function debounceLast(...args) {
        if (timer) {
            clearTimeout(timer);
        }
        timer = setTimeout(() => fn(...args), timeout);
    }
    function debounceLeading(...args) {
        if (!timer) {
            fn(...args);
        }
        else {
            clearTimeout(timer);
        }
        timer = setTimeout(() => {
            timer = undefined;
        }, timeout);
    }
    return leading ? debounceLeading : debounceLast;
}

exports.useDebounce = useDebounce;
exports.useDebouncedFn = useDebouncedFn;
exports.useDebouncedValue = useDebouncedValue;
