{"version":3,"file":"throttle.mjs","sources":["../../../src/core/utils/throttle.ts"],"sourcesContent":["interface DebounceSettings {\n    /** Specify invoking on the leading edge of the timeout. */\n    leading?: boolean | undefined;\n    /** The maximum time func is allowed to be delayed before it's invoked. */\n    maxWait?: number | undefined;\n    /** Specify invoking on the trailing edge of the timeout. */\n    trailing?: boolean | undefined;\n}\ninterface DebounceSettingsLeading extends DebounceSettings {\n    leading: true;\n}\ninterface DebouncedFunc<T extends (...args: any[]) => any> {\n    /**\n     * Call the original function, but applying the debounce rules.\n     *\n     * If the debounced function can be run immediately, this calls it and returns\n     * its return value.\n     *\n     * Otherwise, it returns the return value of the last invocation, or undefined\n     * if the debounced function was not invoked yet.\n     */\n    (...args: Parameters<T>): ReturnType<T> | undefined;\n\n    /** Throw away any pending invocation of the debounced function. */\n    cancel(): void;\n\n    /**\n     * If there is a pending invocation of the debounced function, invoke it\n     * immediately and return its return value.\n     *\n     * Otherwise, return the value from the last invocation, or undefined if the\n     * debounced function was never invoked.\n     */\n    flush(): ReturnType<T> | undefined;\n}\ninterface DebouncedFuncLeading<T extends (...args: any[]) => any> extends DebouncedFunc<T> {\n    (...args: Parameters<T>): ReturnType<T>;\n    flush(): ReturnType<T>;\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. The debounced function\n * comes with a `cancel` method to cancel delayed `func` invocations and a\n * `flush` method to immediately invoke them. Provide `options` to indicate\n * whether `func` should be invoked on the leading and/or trailing edge of the\n * `wait` timeout. The `func` is invoked with the last arguments provided to the\n * debounced function. Subsequent calls to the debounced function return the\n * result of the last `func` invocation.\n *\n * **Note:** If `leading` and `trailing` options are `true`, `func` is invoked\n * on the trailing edge of the timeout only if the debounced function is invoked\n * 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\n * article](https://css-tricks.com/debouncing-throttling-explained-examples/)\n * for details over the differences between `debounce` and `throttle`.\n *\n * @category Function\n * @example\n *   // Avoid costly calculations while the window size is in flux.\n *   jQuery(window).on('resize', debounce(calculateLayout, 150))\n *\n *   // Invoke `sendMail` when clicked, debouncing subsequent calls.\n *   jQuery(element).on(\n *     'click',\n *     debounce(sendMail, 300, {\n *       leading: true,\n *       trailing: false,\n *     })\n *   )\n *\n *   // Ensure `batchLog` is invoked once after 1 second of debounced calls.\n *   const debounced = debounce(batchLog, 250, { maxWait: 1000 })\n *   const source = new EventSource('/stream')\n *   jQuery(source).on('message', debounced)\n *\n *   // Cancel the trailing debounced invocation.\n *   jQuery(window).on('popstate', debounced.cancel)\n *\n *   // Check for pending invocations.\n *   const status = debounced.pending() ? 'Pending...' : 'Ready'\n *\n * @param func The function to debounce.\n * @param [wait] The number of milliseconds to delay; if omitted,\n *   `requestAnimationFrame` is used (if available). Default is `0`\n * @param [options] The options object. Default is `{}`\n * @param options.leading Specify invoking on the leading edge\n *   of the timeout. Default is `false`\n * @param options.maxWait The maximum time `func` is allowed to be\n *   delayed before it's invoked.\n * @param options.trailing Specify invoking on the trailing\n *   edge of the timeout. Default is `true`\n * @returns Returns the new debounced function.\n */\nexport function debounce<T extends (...args: any) => any>(\n    func: T,\n    wait: number | undefined,\n    options: DebounceSettingsLeading,\n): DebouncedFuncLeading<T>;\nexport function debounce<T extends (...args: any) => any>(\n    func: T,\n    wait?: number,\n    options?: DebounceSettings,\n): DebouncedFunc<T>;\nexport function debounce<T extends (...args: any) => any>(\n    func: T,\n    wait = 0,\n    options: DebounceSettingsLeading | DebounceSettings = {},\n): DebouncedFunc<T> | DebouncedFuncLeading<T> {\n    let lastArgs: Parameters<T> | undefined;\n    let lastThis: any;\n    const maxWait = options.maxWait ? options.maxWait : wait;\n    let result: ReturnType<T> | undefined;\n    let timerId: ReturnType<typeof setTimeout> | ReturnType<typeof globalThis.requestAnimationFrame> | undefined;\n    let lastCallTime: number | undefined;\n    let lastInvokeTime = 0;\n    const leading = !!options.leading;\n    const maxing = 'maxWait' in options;\n    const trailing = options.trailing ?? true;\n\n    // Bypass `requestAnimationFrame` by explicitly setting `wait=0`.\n    const useRAF = wait !== 0 && typeof globalThis.requestAnimationFrame === 'function';\n\n    if (typeof func !== 'function') {\n        throw new TypeError('Expected a function');\n    }\n\n    function invokeFunc(time: number) {\n        const args = lastArgs;\n        const thisArg = lastThis;\n\n        lastArgs = lastThis = undefined;\n        lastInvokeTime = time;\n        result = func.apply(thisArg, args!);\n\n        return result;\n    }\n\n    function startTimer(pendingFunc: () => ReturnType<T> | undefined, milliseconds: number) {\n        if (useRAF) {\n            if (typeof timerId === 'number') {\n                globalThis.cancelAnimationFrame(timerId);\n            }\n\n            return globalThis.requestAnimationFrame(pendingFunc);\n        }\n\n        return setTimeout(pendingFunc, milliseconds);\n    }\n\n    function cancelTimer(id: number | ReturnType<typeof setTimeout>) {\n        if (useRAF) {\n            globalThis.cancelAnimationFrame(id as number);\n\n            return;\n        }\n        clearTimeout(id);\n    }\n\n    function leadingEdge(time: number) {\n        // Reset any `maxWait` timer.\n        lastInvokeTime = time;\n        // Start the timer for the trailing edge.\n        timerId = startTimer(timerExpired, wait);\n\n        // Invoke the leading edge.\n        return leading ? invokeFunc(time) : result;\n    }\n\n    function remainingWait(time: number) {\n        const timeSinceLastCall = time - (lastCallTime || 0);\n        const timeSinceLastInvoke = time - lastInvokeTime;\n        const timeWaiting = wait - timeSinceLastCall;\n\n        return maxing ? Math.min(timeWaiting, maxWait - timeSinceLastInvoke) : timeWaiting;\n    }\n\n    function shouldInvoke(time: number) {\n        const timeSinceLastCall = time - (lastCallTime || 0);\n        const timeSinceLastInvoke = time - lastInvokeTime;\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 === undefined ||\n            timeSinceLastCall >= wait ||\n            timeSinceLastCall < 0 ||\n            (maxing && timeSinceLastInvoke >= maxWait)\n        );\n    }\n\n    function timerExpired() {\n        const time = Date.now();\n\n        if (shouldInvoke(time)) {\n            return trailingEdge(time);\n        }\n        // Restart the timer.\n        timerId = startTimer(timerExpired, remainingWait(time));\n\n        return undefined;\n    }\n\n    function trailingEdge(time: number) {\n        timerId = undefined;\n\n        // Only invoke if we have `lastArgs` which means `func` has been\n        // debounced at least once.\n        if (trailing && lastArgs) {\n            return invokeFunc(time);\n        }\n        lastArgs = lastThis = undefined;\n\n        return result;\n    }\n\n    function cancel() {\n        if (timerId !== undefined) {\n            cancelTimer(timerId);\n        }\n        lastInvokeTime = 0;\n        lastArgs = lastCallTime = lastThis = timerId = undefined;\n    }\n\n    function flush() {\n        return timerId === undefined ? result : trailingEdge(Date.now());\n    }\n\n    function pending() {\n        return timerId !== undefined;\n    }\n\n    function debounced(this: any, ...args: Parameters<T>) {\n        const time = Date.now();\n        const isInvoking = shouldInvoke(time);\n\n        lastArgs = args;\n        // eslint-disable-next-line @typescript-eslint/no-this-alias\n        lastThis = this;\n        lastCallTime = time;\n\n        if (isInvoking) {\n            if (timerId === undefined) {\n                return leadingEdge(lastCallTime);\n            }\n            if (maxing) {\n                // Handle invocations in a tight loop.\n                timerId = startTimer(timerExpired, wait);\n\n                return invokeFunc(lastCallTime);\n            }\n        }\n        if (timerId === undefined) {\n            timerId = startTimer(timerExpired, wait);\n        }\n\n        return result;\n    }\n    debounced.cancel = cancel;\n    debounced.flush = flush;\n    debounced.pending = pending;\n\n    return debounced;\n}\n\ninterface ThrottleSettings {\n    /** Specify invoking on the leading edge of the timeout. */\n    leading?: boolean | undefined;\n    /** Specify invoking on the trailing edge of the timeout. */\n    trailing?: boolean | undefined;\n}\n\ninterface DebouncedFunc<T extends (...args: any[]) => any> {\n    /**\n     * Call the original function, but applying the debounce rules.\n     *\n     * If the debounced function can be run immediately, this calls it and returns\n     * its return value.\n     *\n     * Otherwise, it returns the return value of the last invocation, or undefined\n     * if the debounced function was not invoked yet.\n     */\n    (...args: Parameters<T>): ReturnType<T> | undefined;\n\n    /** Throw away any pending invocation of the debounced function. */\n    cancel(): void;\n\n    /**\n     * If there is a pending invocation of the debounced function, invoke it\n     * immediately and return its return value.\n     *\n     * Otherwise, return the value from the last invocation, or undefined if the\n     * debounced function was never invoked.\n     */\n    flush(): ReturnType<T> | undefined;\n}\n\n/**\n * Creates a throttled function that only invokes `func` at most once per every\n * `wait` milliseconds (or once per browser frame). The throttled function comes\n * with a `cancel` method to cancel delayed `func` invocations and a `flush`\n * method to immediately invoke them. Provide `options` to indicate whether\n * `func` should be invoked on the leading and/or trailing edge of the `wait`\n * timeout. The `func` is invoked with the last arguments provided to the\n * throttled function. Subsequent calls to the throttled function return the\n * result of the last `func` invocation.\n *\n * **Note:** If `leading` and `trailing` options are `true`, `func` is invoked\n * on the trailing edge of the timeout only if the throttled function is invoked\n * 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\n * article](https://css-tricks.com/debouncing-throttling-explained-examples/)\n * for details over the differences between `throttle` and `debounce`.\n *\n * @category Function\n * @example\n *   // Avoid excessively updating the position while scrolling.\n *   jQuery(window).on('scroll', throttle(updatePosition, 100))\n *\n *   // Invoke `renewToken` when the click event is fired, but not more than once every 5 minutes.\n *   const throttled = throttle(renewToken, 300000, { trailing: false })\n *   jQuery(element).on('click', throttled)\n *\n *   // Cancel the trailing throttled invocation.\n *   jQuery(window).on('popstate', throttled.cancel)\n *\n * @param func The function to throttle.\n * @param wait The number of milliseconds to throttle invocations\n *   to; if omitted, `requestAnimationFrame` is used (if available). Default is\n *   `0`\n * @param options The options object. Default is `{}`\n * @param options.leading Specify invoking on the leading edge\n *   of the timeout. Default is `true`\n * @param options.trailing Specify invoking on the trailing\n *   edge of the timeout. Default is `true`\n * @returns Returns the new throttled function.\n */\nexport function throttle<T extends (...args: any) => any>(\n    func: T,\n    wait?: number,\n    options: ThrottleSettings = {},\n): DebouncedFunc<T> {\n    const leading = options.leading ?? true;\n    const trailing = options.trailing ?? true;\n\n    if (typeof func !== 'function') {\n        throw new TypeError('Expected a function');\n    }\n\n    return debounce(func, wait, {\n        leading,\n        trailing,\n        maxWait: wait,\n    });\n}\n"],"names":[],"mappings":"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"}