{
  "version": 3,
  "sources": ["../src/main.ts", "../src/debounce.ts"],
  "sourcesContent": ["import {Debouncer} from './debounce.js';\n\nimport type {DebouncerConfig} from './type.js';\n\nexport * from './debounce.js';\nexport type * from './type.js';\n\n/**\n * Factory function for creating a Debouncer instance for better type inference.\n * @param config Configuration for the debouncer.\n *\n * @example\n * ```typescript\n * const debouncer = createDebouncer({\n *   func: (text: string) => console.log('Searching:', text),\n *   delay: 300,\n *   leading: false,\n *   trailing: true,\n * });\n *\n * // Debounce search input\n * debouncer.trigger('hello');\n * debouncer.trigger('hello world'); // Only 'hello world' will log after 300ms\n *\n * // With custom thisContext\n * const obj = { log: (msg: string) => console.log('Obj:', msg) };\n * const debouncerWithContext = createDebouncer({\n *   func: obj.log,\n *   thisContext: obj,\n *   delay: 200,\n * });\n * debouncerWithContext.trigger('test'); // Logs 'Obj: test'\n * ```\n */\nexport function createDebouncer<F extends AnyFunc>(config: DebouncerConfig<F>): Debouncer<F> {\n  return new Debouncer(config);\n}\n", "import type {DebouncerConfig} from './type.ts';\n\n/**\n * A powerful and type-safe Debouncer class.\n *\n * It encapsulates the debouncing logic, state, and provides a rich control API.\n * Debouncing delays function execution until after a specified delay has passed since the last invocation.\n * Useful for optimizing performance in scenarios like search inputs, resize events, or API calls.\n *\n * @example\n * ```typescript\n * const debouncer = new Debouncer({\n *   func: (text: string) => console.log('Searching:', text),\n *   delay: 300,\n *   leading: false,\n *   trailing: true,\n * });\n *\n * // Debounce search input\n * debouncer.trigger('hello');\n * debouncer.trigger('hello world'); // Only 'hello world' will log after 300ms\n *\n * // Advanced: With leading edge\n * const leadingDebouncer = new Debouncer({\n *   func: () => console.log('Immediate and delayed'),\n *   delay: 500,\n *   leading: true,\n *   trailing: true,\n * });\n * leadingDebouncer.trigger(); // Logs immediately, then again after 500ms if not cancelled\n * ```\n */\nexport class Debouncer<F extends AnyFunc> {\n  private timerId__?: number | NodeJS.Timeout;\n  private maxWaitTimerId__?: number | NodeJS.Timeout;\n  private lastArgs__?: Parameters<F>;\n\n  constructor(private readonly config__: DebouncerConfig<F>) {\n    this.config__.trailing ??= true;\n    this.flush = this.flush.bind(this);\n  }\n\n  /**\n   * Checks if there is a pending execution scheduled.\n   * Returns true if a timer is active, indicating a debounced call is waiting.\n   */\n  public get isPending(): boolean {\n    return this.timerId__ !== undefined;\n  }\n\n  /**\n   * Triggers the debounced function with the stored `thisContext`.\n   * @param args The arguments to pass to the `func`.\n   *\n   * @example\n   * ```typescript\n   * const debouncer = new Debouncer({\n   *   func: (value: number) => console.log('Value:', value),\n   *   delay: 500,\n   * });\n   * debouncer.trigger(42); // Logs after 500ms if not triggered again\n   *\n   * // Edge case: Rapid triggers only execute the last one\n   * debouncer.trigger(1);\n   * debouncer.trigger(2); // Only 2 will execute after delay\n   * ```\n   */\n  public trigger(...args: Parameters<F>): void {\n    this.lastArgs__ = args; // its an array even if triggered without any args\n    const firstTrigger = !this.isPending;\n\n    if (firstTrigger) {\n      if (this.config__.maxWait) {\n        this.maxWaitTimerId__ = setTimeout(this.flush, this.config__.maxWait);\n      }\n      if (this.config__.leading === true) {\n        this.invoke__();\n      }\n    }\n    else {\n      clearTimeout(this.timerId__!);\n    }\n\n    this.timerId__ = setTimeout(() => {\n      if (this.config__.trailing === true) {\n        this.invoke__();\n      }\n      this.cleanup__();\n    }, this.config__.delay);\n  }\n\n  /**\n   * Cancels any pending debounced execution and cleans up internal state.\n   * Useful for stopping execution when the operation is no longer needed (e.g., component unmount).\n   *\n   * @example\n   * ```typescript\n   * const debouncer = new Debouncer({\n   *   func: () => console.log('Executed'),\n   *   delay: 1000,\n   * });\n   * debouncer.trigger();\n   * debouncer.cancel(); // Prevents execution\n   *\n   * // Note: After cancel, isPending becomes false\n   * ```\n   */\n  public cancel(): void {\n    if (this.timerId__) {\n      clearTimeout(this.timerId__);\n    }\n    if (this.maxWaitTimerId__) {\n      clearTimeout(this.maxWaitTimerId__);\n    }\n    this.cleanup__();\n  }\n\n  /**\n   * Cleans up internal state by deleting timer and arguments.\n   */\n  private cleanup__(): void {\n    delete this.timerId__;\n    delete this.maxWaitTimerId__;\n    delete this.lastArgs__;\n  }\n\n  /**\n   * Immediately executes the pending function if one exists.\n   * Bypasses the delay and cleans up state. If no pending call, does nothing.\n   *\n   * @example\n   * ```typescript\n   * const debouncer = new Debouncer({\n   *   func: () => console.log('Flushed'),\n   *   delay: 1000,\n   * });\n   * debouncer.trigger();\n   * setTimeout(() => debouncer.flush(), 500); // Executes immediately\n   *\n   * // Edge case: Flush after cancel does nothing\n   * debouncer.cancel();\n   * debouncer.flush(); // No execution\n   * ```\n   */\n  public flush(): void {\n    if (this.isPending) {\n      this.invoke__();\n    }\n    this.cancel();\n  }\n\n  /**\n   * The core execution logic.\n   */\n  private invoke__(): void {\n    if (this.lastArgs__) {\n      // only call if we have new args (skip trailing call if leading already called)\n      this.config__.func.apply(this.config__.thisContext, this.lastArgs__);\n      this.lastArgs__ = undefined;\n    }\n  }\n}\n"],
  "mappings": ";;qqBAAA,mJCgCO,IAAM,UAAN,KAAmC,CAKxC,YAA6B,SAA8B,CAA9B,uBAC3B,KAAK,SAAS,WAAa,KAC3B,KAAK,MAAQ,KAAK,MAAM,KAAK,IAAI,CACnC,CAMA,IAAW,WAAqB,CAC9B,OAAO,KAAK,YAAc,MAC5B,CAmBO,WAAW,KAA2B,CAC3C,KAAK,WAAa,KAClB,MAAM,aAAe,CAAC,KAAK,UAE3B,GAAI,aAAc,CAChB,GAAI,KAAK,SAAS,QAAS,CACzB,KAAK,iBAAmB,WAAW,KAAK,MAAO,KAAK,SAAS,OAAO,CACtE,CACA,GAAI,KAAK,SAAS,UAAY,KAAM,CAClC,KAAK,SAAS,CAChB,CACF,KACK,CACH,aAAa,KAAK,SAAU,CAC9B,CAEA,KAAK,UAAY,WAAW,IAAM,CAChC,GAAI,KAAK,SAAS,WAAa,KAAM,CACnC,KAAK,SAAS,CAChB,CACA,KAAK,UAAU,CACjB,EAAG,KAAK,SAAS,KAAK,CACxB,CAkBO,QAAe,CACpB,GAAI,KAAK,UAAW,CAClB,aAAa,KAAK,SAAS,CAC7B,CACA,GAAI,KAAK,iBAAkB,CACzB,aAAa,KAAK,gBAAgB,CACpC,CACA,KAAK,UAAU,CACjB,CAKQ,WAAkB,CACxB,OAAO,KAAK,UACZ,OAAO,KAAK,iBACZ,OAAO,KAAK,UACd,CAoBO,OAAc,CACnB,GAAI,KAAK,UAAW,CAClB,KAAK,SAAS,CAChB,CACA,KAAK,OAAO,CACd,CAKQ,UAAiB,CACvB,GAAI,KAAK,WAAY,CAEnB,KAAK,SAAS,KAAK,MAAM,KAAK,SAAS,YAAa,KAAK,UAAU,EACnE,KAAK,WAAa,MACpB,CACF,CACF,ED/HO,SAAS,gBAAmC,OAA0C,CAC3F,OAAO,IAAI,UAAU,MAAM,CAC7B",
  "names": []
}
