{"version":3,"file":"debounce.cjs","names":[],"sources":["../../src/function/debounce.ts"],"sourcesContent":["import type { ThrottleOptions } from '../types';\n\n/**\n * Creates a debounced function that delays invoking func until after wait milliseconds\n * have elapsed since the last time the debounced function was invoked.\n *\n * @template T - The type of the function to debounce\n * @param func - The function to debounce\n * @param wait - The number of milliseconds to delay (default: 0)\n * @param options - The options object\n * @param options.leading - Specify invoking on the leading edge of the timeout (default: false)\n * @param options.trailing - Specify invoking on the trailing edge of the timeout (default: true)\n * @param options.maxWait - The maximum time func is allowed to be delayed before it's invoked\n * @returns Returns the new debounced function\n *\n * @example\n * const debounced = debounce(() => console.log('Hello'), 1000);\n * debounced(); // Will log 'Hello' after 1 second\n * debounced(); // Resets the timer\n *\n * @example\n * // With leading option\n * const debounced = debounce(() => console.log('Hello'), 1000, { leading: true });\n * debounced(); // Logs 'Hello' immediately, then waits 1 second before allowing next call\n */\nexport function debounce<T extends (...args: never[]) => unknown>(\n  func: T,\n  wait = 0,\n  options: ThrottleOptions = {},\n): T & { cancel(): void; flush(): ReturnType<T> } {\n  const { leading = false, trailing = true, maxWait } = options;\n\n  type DebouncedFn = T & { cancel(): void; flush(): ReturnType<T> };\n\n  const invoke = (thisArg: unknown, args: Parameters<T>): ReturnType<T> =>\n    (func as (this: unknown, ...args: Parameters<T>) => ReturnType<T>).apply(thisArg, args);\n\n  let timerId: ReturnType<typeof setTimeout> | undefined;\n  let lastCallTime: number | undefined;\n  let lastInvokeTime = 0;\n  let lastArgs: Parameters<T> | undefined;\n  let lastThis: unknown;\n  let result: ReturnType<T> | undefined;\n\n  function invokeFunc(time: number) {\n    const args = lastArgs!;\n    const thisArg = lastThis;\n\n    lastArgs = undefined;\n    lastThis = undefined;\n    lastInvokeTime = time;\n    result = invoke(thisArg, args);\n    return result;\n  }\n\n  function leadingEdge(time: number) {\n    // Reset maxWait timer.\n    lastInvokeTime = time;\n    // Start the timer for the trailing edge.\n    timerId = setTimeout(timerExpired, wait);\n    // Invoke the leading edge.\n    return leading ? invokeFunc(time) : result;\n  }\n\n  function remainingWait(time: number) {\n    const timeSinceLastCall = time - lastCallTime!;\n    const timeSinceLastInvoke = time - lastInvokeTime;\n    const timeWaiting = wait - timeSinceLastCall;\n\n    return maxWait !== undefined ? 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      (maxWait !== undefined && timeSinceLastInvoke >= maxWait)\n    );\n  }\n\n  function timerExpired() {\n    const time = Date.now();\n    if (shouldInvoke(time)) {\n      return trailingEdge(time);\n    }\n    // Restart the timer.\n    timerId = setTimeout(timerExpired, remainingWait(time));\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 = undefined;\n    lastThis = undefined;\n    return result;\n  }\n\n  function cancel() {\n    if (timerId !== undefined) {\n      clearTimeout(timerId);\n    }\n    lastInvokeTime = 0;\n    lastArgs = undefined;\n    lastCallTime = undefined;\n    lastThis = undefined;\n    timerId = undefined;\n  }\n\n  function flush() {\n    return timerId === undefined ? result : trailingEdge(Date.now());\n  }\n\n  function debounced(this: unknown, ...args: Parameters<T>): ReturnType<T> {\n    const time = Date.now();\n    const isInvoking = shouldInvoke(time);\n\n    lastArgs = args;\n    lastThis = this;\n    lastCallTime = time;\n\n    if (isInvoking) {\n      if (timerId === undefined) {\n        return leadingEdge(lastCallTime) as ReturnType<T>;\n      }\n      if (maxWait !== undefined) {\n        // Handle invocations in a tight loop.\n        timerId = setTimeout(timerExpired, wait);\n        return invokeFunc(lastCallTime);\n      }\n    }\n    if (timerId === undefined) {\n      timerId = setTimeout(timerExpired, wait);\n    }\n    return result as ReturnType<T>;\n  }\n\n  (debounced as DebouncedFn).cancel = cancel;\n  (debounced as DebouncedFn).flush = flush as () => ReturnType<T>;\n\n  return debounced as DebouncedFn;\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;AAyBA,SAAgB,SACd,MACA,OAAO,GACP,UAA2B,CAAC,GACoB;CAChD,MAAM,EAAE,UAAU,OAAO,WAAW,MAAM,YAAY;CAItD,MAAM,UAAU,SAAkB,SAC/B,KAAkE,MAAM,SAAS,IAAI;CAExF,IAAI;CACJ,IAAI;CACJ,IAAI,iBAAiB;CACrB,IAAI;CACJ,IAAI;CACJ,IAAI;CAEJ,SAAS,WAAW,MAAc;EAChC,MAAM,OAAO;EACb,MAAM,UAAU;EAEhB,WAAW,KAAA;EACX,WAAW,KAAA;EACX,iBAAiB;EACjB,SAAS,OAAO,SAAS,IAAI;EAC7B,OAAO;CACT;CAEA,SAAS,YAAY,MAAc;EAEjC,iBAAiB;EAEjB,UAAU,WAAW,cAAc,IAAI;EAEvC,OAAO,UAAU,WAAW,IAAI,IAAI;CACtC;CAEA,SAAS,cAAc,MAAc;EACnC,MAAM,oBAAoB,OAAO;EACjC,MAAM,sBAAsB,OAAO;EACnC,MAAM,cAAc,OAAO;EAE3B,OAAO,YAAY,KAAA,IAAY,KAAK,IAAI,aAAa,UAAU,mBAAmB,IAAI;CACxF;CAEA,SAAS,aAAa,MAAc;EAClC,MAAM,oBAAoB,QAAQ,gBAAgB;EAClD,MAAM,sBAAsB,OAAO;EAKnC,OACE,iBAAiB,KAAA,KACjB,qBAAqB,QACrB,oBAAoB,KACnB,YAAY,KAAA,KAAa,uBAAuB;CAErD;CAEA,SAAS,eAAe;EACtB,MAAM,OAAO,KAAK,IAAI;EACtB,IAAI,aAAa,IAAI,GACnB,OAAO,aAAa,IAAI;EAG1B,UAAU,WAAW,cAAc,cAAc,IAAI,CAAC;CACxD;CAEA,SAAS,aAAa,MAAc;EAClC,UAAU,KAAA;EAIV,IAAI,YAAY,UACd,OAAO,WAAW,IAAI;EAExB,WAAW,KAAA;EACX,WAAW,KAAA;EACX,OAAO;CACT;CAEA,SAAS,SAAS;EAChB,IAAI,YAAY,KAAA,GACd,aAAa,OAAO;EAEtB,iBAAiB;EACjB,WAAW,KAAA;EACX,eAAe,KAAA;EACf,WAAW,KAAA;EACX,UAAU,KAAA;CACZ;CAEA,SAAS,QAAQ;EACf,OAAO,YAAY,KAAA,IAAY,SAAS,aAAa,KAAK,IAAI,CAAC;CACjE;CAEA,SAAS,UAAyB,GAAG,MAAoC;EACvE,MAAM,OAAO,KAAK,IAAI;EACtB,MAAM,aAAa,aAAa,IAAI;EAEpC,WAAW;EACX,WAAW;EACX,eAAe;EAEf,IAAI,YAAY;GACd,IAAI,YAAY,KAAA,GACd,OAAO,YAAY,YAAY;GAEjC,IAAI,YAAY,KAAA,GAAW;IAEzB,UAAU,WAAW,cAAc,IAAI;IACvC,OAAO,WAAW,YAAY;GAChC;EACF;EACA,IAAI,YAAY,KAAA,GACd,UAAU,WAAW,cAAc,IAAI;EAEzC,OAAO;CACT;CAEA,UAA2B,SAAS;CACpC,UAA2B,QAAQ;CAEnC,OAAO;AACT"}