{"version":3,"sources":["../src/index.ts"],"sourcesContent":["export interface Fn<A extends unknown[], R> {\n  (...args: A): R;\n}\n\nexport type MaybePromise<T> = Promise<T> | PromiseLike<T> | T;\n\nexport interface Callback<R = void> extends Fn<[], MaybePromise<R>> {}\n\nexport interface Listener<T, R = unknown> extends Fn<[T], MaybePromise<R | void>> {}\n\nexport interface FilterFunction<T> {\n  (event: T): MaybePromise<boolean>;\n}\n\nexport interface Predicate<T, P extends T> {\n  (event: T): event is P;\n}\n\nexport type Filter<T, P extends T> = Predicate<T, P> | FilterFunction<T>;\n\nexport interface Mapper<T, R> {\n  (event: T): MaybePromise<R>;\n}\n\nexport interface Reducer<T, R> {\n  (result: R, event: T): MaybePromise<R>;\n}\n\nexport interface Expander<T, R> {\n  (event: T): MaybePromise<R>;\n}\n\n/**\n * Removes a listener from the provided array of listeners. It searches for the listener and removes all instances of it from the array.\n * This method ensures that the listener is fully unregistered, preventing any residual calls to a potentially deprecated handler.\n *\n * @internal\n * @param {unknown[]} listeners - The array of listeners from which to remove the listener.\n * @param {unknown} listener - The listener function to remove from the list of listeners.\n * @returns {boolean} - Returns `true` if the listener was found and removed, `false` otherwise.\n *\n * @template T - The type of the event that listeners are associated with.\n * @template R - The type of the return value that listeners are expected to return.\n *\n * ```typescript\n * // Assuming an array of listeners for click events\n * const listeners = [onClickHandler1, onClickHandler2];\n * const wasRemoved = removeListener(listeners, onClickHandler1);\n * console.log(wasRemoved); // Output: true\n * ```\n */\nexport const removeListener = (listeners: unknown[], listener: unknown): boolean => {\n  let index = listeners.indexOf(listener);\n  const wasRemoved = index !== -1;\n  while (~index) {\n    listeners.splice(index, 1);\n    index = listeners.indexOf(listener);\n  }\n  return wasRemoved;\n};\n\n/**\n * @internal\n * Creates a promise that resolves after a specified timeout. If an `AbortSignal` is provided and triggered,\n * the timeout is cleared, and the promise resolves to `false`.\n *\n * @param {number} timeout - The time in milliseconds to wait before resolving the promise.\n * @param {AbortSignal} [signal] - An optional `AbortSignal` that can abort the timeout.\n * @returns {Promise<boolean>} A promise that resolves to `true` if the timeout completed, or `false` if it was aborted.\n *\n * @example\n * ```typescript\n * const controller = new AbortController();\n * setTimeout(() => controller.abort(), 500);\n * const result = await setTimeoutAsync(1000, controller.signal);\n * console.log(result); // false\n * ```\n */\nexport const setTimeoutAsync = (timeout: number, signal?: AbortSignal): Promise<boolean> =>\n  new Promise<boolean>((resolve) => {\n    const timerId = setTimeout(resolve, timeout, true);\n    signal?.addEventListener('abort', () => {\n      clearTimeout(timerId);\n      resolve(false);\n    });\n  });\n\n/**\n * @internal\n */\nexport interface Callable<T extends unknown[], R> {\n  (...args: T): R;\n}\n\n/**\n * An abstract class that extends the built-in Function class. It allows instances of the class\n * to be called as functions. When an instance of Callable is called as a function, it will\n * call the function passed to its constructor with the same arguments.\n * @internal\n */\n// eslint-disable-next-line @typescript-eslint/no-unused-vars\nexport abstract class Callable<T, R> {\n  // eslint-disable-next-line @typescript-eslint/no-unsafe-function-type\n  constructor(func: Function) {\n    return Object.setPrototypeOf(func, new.target.prototype);\n  }\n}\n\n/**\n * @internal\n */\nexport class Unsubscribe extends Callable<[], MaybePromise<void>> {\n  private _done = false;\n\n  constructor(callback: Callback) {\n    super(async () => {\n      this._done = true;\n      await callback();\n    });\n  }\n\n  get done() {\n    return this._done;\n  }\n\n  pre(callback: Callback): Unsubscribe {\n    return new Unsubscribe(async () => {\n      await callback();\n      await this();\n    });\n  }\n\n  post(callback: Callback): Unsubscribe {\n    return new Unsubscribe(async () => {\n      await this();\n      await callback();\n    });\n  }\n\n  countdown(count: number): Unsubscribe {\n    return new Unsubscribe(async () => {\n      if (!--count) {\n        await this();\n      }\n    });\n  }\n}\n\nenum HookType {\n  Add,\n  Remove,\n}\n\n/**\n * A class representing an anonymous event that can be listened to or triggered.\n *\n * @template T - The event type.\n * @template R - The return type of the event.\n */\nexport class Event<T = unknown, R = unknown> extends Callable<[T], Promise<(void | Awaited<R>)[]>> implements AsyncIterable<T>, PromiseLike<T> {\n  /**\n   * The array of listeners for the event.\n   */\n  private listeners: Listener<T, R>[];\n\n  private hooks: Array<(listener: Listener<T, R> | void, type: HookType) => void> = [];\n\n  private _disposed = false;\n\n  /**\n   * A function that disposes of the event and its listeners.\n   */\n  readonly dispose: Callback;\n\n  /**\n   * Creates a new event.\n   *\n   * @param dispose - A function to call on the event disposal.\n   *\n   * ```typescript\n   * // Create a click event.\n   * const clickEvent = new Event<[x: number, y: number], void>();\n   * clickEvent.on(([x, y]) => console.log(`Clicked at ${x}, ${y}`));\n   * ```\n   */\n  constructor(dispose?: Callback) {\n    const listeners: Listener<T, R>[] = [];\n    // passes listeners exceptions to catch method\n    super((value: T): Promise<(void | Awaited<R>)[]> => Promise.all(listeners.map(async (listener) => listener(await value))));\n\n    this.listeners = listeners;\n\n    this.dispose = () => {\n      this._disposed = true;\n      void this.clear();\n      void this._error?.dispose();\n      void dispose?.();\n    };\n  }\n\n  private _error?: Event<unknown>;\n\n  /**\n   * Error event that emits errors.\n   *\n   * @returns {Event<unknown>} The error event.\n   */\n  get error(): Event<unknown> {\n    return (this._error ??= new Event<unknown>());\n  }\n\n  /**\n   * The number of listeners for the event.\n   *\n   * @readonly\n   * @type {number}\n   */\n  get size(): number {\n    return this.listeners.length;\n  }\n\n  /**\n   * Checks if the event has been disposed.\n   * @returns {boolean} `true` if the event has been disposed; otherwise, `false`.\n   */\n  get disposed(): boolean {\n    return this._disposed;\n  }\n\n  /**\n   * Checks if the given listener is NOT registered for this event.\n   *\n   * @param listener - The listener function to check against the registered listeners.\n   * @returns `true` if the listener is not already registered; otherwise, `false`.\n   *\n   * ```typescript\n   * // Check if a listener is not already added\n   * if (event.lacks(myListener)) {\n   *   event.on(myListener);\n   * }\n   * ```\n   */\n  lacks(listener: Listener<T, R>): boolean {\n    return this.listeners.indexOf(listener) === -1;\n  }\n\n  /**\n   * Checks if the given listener is registered for this event.\n   *\n   * @param listener - The listener function to check.\n   * @returns `true` if the listener is currently registered; otherwise, `false`.\n   *\n   * ```typescript\n   * // Verify if a listener is registered\n   * if (event.has(myListener)) {\n   *   console.log('Listener is already registered');\n   * }\n   * ```\n   */\n  has(listener: Listener<T, R>): boolean {\n    return this.listeners.indexOf(listener) !== -1;\n  }\n\n  /**\n   * Removes a specific listener from this event.\n   *\n   * @param listener - The listener to remove.\n   * @returns The event instance, allowing for method chaining.\n   *\n   * ```typescript\n   * // Remove a listener\n   * event.off(myListener);\n   * ```\n   */\n  off(listener: Listener<T, R>): this {\n    if (removeListener(this.listeners, listener) && this.hooks.length) {\n      [...this.hooks].forEach((spy) => spy(listener, HookType.Remove));\n    }\n    return this;\n  }\n\n  /**\n   * Registers a listener that gets triggered whenever the event is emitted.\n   * This is the primary method for adding event handlers that will react to the event being triggered.\n   *\n   * @param listener - The function to call when the event occurs.\n   * @returns An object that can be used to unsubscribe the listener, ensuring easy cleanup.\n   *\n   * ```typescript\n   * // Add a listener to an event\n   * const unsubscribe = event.on((data) => {\n   *   console.log('Event data:', data);\n   * });\n   * ```\n   */\n  on(listener: Listener<T, R>): Unsubscribe {\n    this.listeners.push(listener);\n    if (this.hooks.length) {\n      [...this.hooks].forEach((spy) => spy(listener, HookType.Add));\n    }\n    return new Unsubscribe(() => {\n      void this.off(listener);\n    });\n  }\n\n  /**\n   * Adds a listener that will be called only once the next time the event is emitted.\n   * This method is useful for one-time notifications or single-trigger scenarios.\n   *\n   * @param listener - The listener to trigger once.\n   * @returns An object that can be used to remove the listener if the event has not yet occurred.\n   *\n   * ```typescript\n   * // Register a one-time listener\n   * const onceUnsubscribe = event.once((data) => {\n   *   console.log('Received data once:', data);\n   * });\n   * ```\n   */\n  once(listener: Listener<T, R>): Unsubscribe {\n    const oneTimeListener = (event: T) => {\n      void this.off(oneTimeListener);\n      return listener(event);\n    };\n    return this.on(oneTimeListener);\n  }\n\n  /**\n   * Removes all listeners from the event, effectively resetting it. This is useful when you need to\n   * cleanly dispose of all event handlers to prevent memory leaks or unwanted triggers after certain conditions.\n   *\n   * @returns {this} The instance of the event, allowing for method chaining.\n   *\n   * ```typescript\n   * const myEvent = new Event();\n   * myEvent.on(data => console.log(data));\n   * myEvent.clear(); // Clears all listeners\n   * ```\n   */\n  clear(): this {\n    this.listeners.splice(0);\n    if (this.hooks.length) {\n      [...this.hooks].forEach((spy) => spy(undefined, HookType.Remove));\n    }\n    return this;\n  }\n\n  /**\n   * Enables the `Event` to be used in a Promise chain, resolving with the first emitted value.\n   *\n   * @template OK - The type of the fulfilled value returned by `onfulfilled` (defaults to the event's type).\n   * @template ERR - The type of the rejected value returned by `onrejected` (defaults to `never`).\n   * @param onfulfilled - A function called when the event emits its first value.\n   * @param onrejected - A function called if an error occurs before the event emits.\n   * @returns A Promise that resolves with the result of `onfulfilled` or `onrejected`.\n   *\n   * ```typescript\n   * const clickEvent = new Event<[number, number]>();\n   * await clickEvent;\n   * ```\n   */\n  then<OK = T, ERR = never>(\n    onfulfilled?: ((value: T) => OK | PromiseLike<OK>) | null | undefined,\n    onrejected?: ((reason: unknown) => ERR | PromiseLike<ERR>) | null | undefined,\n  ): Promise<OK | ERR> {\n    const unsubscribe: Unsubscribe[] = [];\n    const promise = new Promise<T>((resolve, reject) => {\n      unsubscribe.push(this.once(resolve));\n      unsubscribe.push(this.error.once(reject));\n    });\n\n    return promise.then(onfulfilled, onrejected).finally(async () => {\n      await Promise.all(unsubscribe.map((u) => u()));\n    });\n  }\n\n  /**\n   * Waits for the event to settle, returning a `PromiseSettledResult`.\n   *\n   * @returns {Promise<PromiseSettledResult<T>>} A promise that resolves with the settled result.\n   *\n   * @example\n   * ```typescript\n   * const result = await event.settle();\n   * if (result.status === 'fulfilled') {\n   *   console.log('Event fulfilled with value:', result.value);\n   * } else {\n   *   console.error('Event rejected with reason:', result.reason);\n   * }\n   * ```\n   */\n  async settle(): Promise<PromiseSettledResult<T>> {\n    return await Promise.allSettled([this.promise]).then(([settled]) => settled);\n  }\n\n  /**\n   * A promise that resolves with the first emitted value from this event.\n   *\n   * @returns {Promise<T>} The promise value.\n   */\n  get promise(): Promise<T> {\n    return this.then();\n  }\n\n  /**\n   * Makes this event iterable using `for await...of` loops.\n   *\n   * @returns An async iterator that yields values as they are emitted by this event.\n   *\n   * ```typescript\n   * // Assuming an event that emits numbers\n   * const numberEvent = new Event<number>();\n   * (async () => {\n   *   for await (const num of numberEvent) {\n   *     console.log('Number:', num);\n   *   }\n   * })();\n   * await numberEvent(1);\n   * await numberEvent(2);\n   * await numberEvent(3);\n   * ```\n   */\n  [Symbol.asyncIterator](): AsyncIterator<T> {\n    const queue: T[] = [];\n    const hasNextEvent = new Event<boolean>();\n    const emitEvent = async (value: T) => {\n      queue.push(value);\n      await hasNextEvent(true);\n    };\n    const unsubscribe = this.on(emitEvent).pre(async () => {\n      await hasNextEvent.dispose();\n      removeListener(this.hooks, spy);\n      queue.splice(0);\n    });\n\n    const spy: (typeof this.hooks)[number] = (target = emitEvent, action) => {\n      if (target === emitEvent && action === HookType.Remove) {\n        void hasNextEvent(false);\n        void unsubscribe();\n      }\n    };\n\n    this.hooks.push(spy);\n    return {\n      async next() {\n        if (!hasNextEvent.disposed) {\n          const next = queue.length || (await hasNextEvent);\n          if (next) {\n            return { value: queue.shift()!, done: false };\n          }\n        }\n        return { value: undefined, done: true };\n      },\n      async return(value: unknown) {\n        await unsubscribe();\n        return { value, done: true };\n      },\n    };\n  }\n\n  /**\n   * Transforms the event's values using a generator function, creating a new `Event` that emits the transformed values.\n   *\n   * @template PT - The type of values emitted by the transformed `Event`.\n   * @template PR - The return type of the listeners of the transformed `Event`.\n   * @param generator - A function that takes the original event's value and returns a generator (sync or async) that yields the transformed values.\n   * @returns A new `Event` instance that emits the transformed values.\n   *\n   * ```typescript\n   * const numbersEvent = new Event<number>();\n   * const evenNumbersEvent = numbersEvent.pipe(function*(value) {\n   *    if (value % 2 === 0) {\n   *      yield value;\n   *    }\n   * });\n   * evenNumbersEvent.on((evenNumber) => console.log(evenNumber));\n   * await numbersEvent(1);\n   * await numbersEvent(2);\n   * await numbersEvent(3);\n   * ```\n   */\n  pipe<PT, R>(generator: (event: T) => AsyncGenerator<PT, void, unknown> | Generator<PT, void, unknown>): Event<PT, R> {\n    const emitEvent = async (value: T) => {\n      try {\n        for await (const generatedValue of generator(value)) {\n          await result(generatedValue).catch(result.error);\n        }\n      } catch (e) {\n        await result.error(e);\n      }\n    };\n\n    const unsubscribe = this.on(emitEvent).pre(() => {\n      removeListener(this.hooks, spy);\n    });\n\n    const spy: (typeof this.hooks)[number] = (target = emitEvent, action) => {\n      if (target === emitEvent && action === HookType.Remove) {\n        void unsubscribe();\n      }\n    };\n    this.hooks.push(spy);\n\n    const result = new Event<PT, R>(unsubscribe);\n    return result;\n  }\n\n  /**\n   * Creates an async generator that yields values as they are emitted by this event.\n   *\n   * @template PT - The type of values yielded by the async generator.\n   * @param generator - An optional function that takes the original event's value and returns a generator (sync or async)\n   *                  that yields values to include in the async generator.\n   * @returns An async generator that yields values from this event as they occur.\n   *\n   * ```typescript\n   * const numbersEvent = new Event<number>();\n   * const evenNumbersEvent = numbersEvent.pipe(function*(value) {\n   *    if (value % 2 === 0) {\n   *      yield value;\n   *    }\n   * });\n   * evenNumbersEvent.on((evenNumber) => console.log(evenNumber));\n   * await numbersEvent(1);\n   * await numbersEvent(2);\n   * await numbersEvent(3);\n   * ```\n   */\n  async *generator<PT>(generator: (event: T) => AsyncGenerator<PT, void, unknown> | Generator<PT, void, unknown>): AsyncGenerator<Awaited<PT>, void, unknown> {\n    for await (const value of this.pipe(generator)) {\n      yield value;\n    }\n  }\n\n  /**\n   * Filters events, creating a new event that only triggers when the provided filter function returns `true`.\n   * This method can be used to selectively process events that meet certain criteria.\n   *\n   * @param {Filter<T, P>} predicate The filter function or predicate to apply to each event.\n   * @returns {Event<P, R>} A new event that only triggers for filtered events.\n   *\n   * ```typescript\n   * const keyPressedEvent = new Event<string>();\n   * const enterPressedEvent = keyPressedEvent.filter(key => key === 'Enter');\n   * enterPressedEvent.on(() => console.log('Enter key was pressed.'));\n   * ```\n   */\n  filter<P extends T>(predicate: Predicate<T, P>): Event<P, R>;\n  filter<P extends T>(filter: FilterFunction<T>): Event<P, R>;\n  filter<P extends T>(filter: Filter<T, P>): Event<P, R> {\n    return this.pipe<P, R>(async function* (value: T) {\n      if (await filter(value)) {\n        yield value as P;\n      }\n    });\n  }\n\n  /**\n   * Creates a new event that will only be triggered once when the provided filter function returns `true`.\n   * This method is useful for handling one-time conditions in a stream of events.\n   *\n   * @param {Filter<T, P>} predicate - The filter function or predicate.\n   * @returns {Event<P, R>} A new event that will be triggered only once when the filter condition is met.\n   *\n   * ```typescript\n   * const sizeChangeEvent = new Event<number>();\n   * const sizeReachedEvent = sizeChangeEvent.first(size => size > 1024);\n   * sizeReachedEvent.on(() => console.log('Size threshold exceeded.'));\n   * ```\n   */\n  first<P extends T>(predicate: Predicate<T, P>): Event<P, R>;\n  first<P extends T>(filter: FilterFunction<T>): Event<P, R>;\n  first<P extends T>(filter: Filter<T, P>): Event<P, R> {\n    const filteredEvent = this.pipe<P, R>(async function* (value: T) {\n      if (await filter(value)) {\n        yield value as P;\n        await filteredEvent.dispose();\n      }\n    });\n    return filteredEvent;\n  }\n\n  /**\n   * Transforms the data emitted by this event using a mapping function. Each emitted event is processed by the `mapper`\n   * function, which returns a new value that is then emitted by the returned `Event` instance. This is useful for data transformation\n   * or adapting the event's data structure.\n   *\n   * @template M The type of data that the mapper function will produce.\n   * @template MR The type of data emitted by the mapped event, usually related to or the same as `M`.\n   * @param {Mapper<T, M>} mapper A function that takes the original event data and returns the transformed data.\n   * @returns {Event<M, MR>} A new `Event` instance that emits the mapped values.\n   *\n   * ```typescript\n   * // Assuming an event that emits numbers, create a new event that emits their squares.\n   * const numberEvent = new Event<number>();\n   * const squaredEvent = numberEvent.map(num => num * num);\n   * squaredEvent.on(squared => console.log('Squared number:', squared));\n   * await numberEvent(5); // Logs: \"Squared number: 25\"\n   * ```\n   */\n  map<M, MR = R>(mapper: Mapper<T, M>): Event<Awaited<M>, MR> {\n    return this.pipe(async function* (value) {\n      yield await mapper(value);\n    });\n  }\n\n  /**\n   * Accumulates the values emitted by this event using a reducer function, starting from an initial value. The reducer\n   * function takes the accumulated value and the latest emitted event data, then returns a new accumulated value. This\n   * new value is then emitted by the returned `Event` instance. This is particularly useful for accumulating state over time.\n   *\n   * @template A The type of the accumulator value.\n   * @template AR The type of data emitted by the reduced event, usually the same as `A`.\n   * @param {Reducer<T, A>} reducer A function that takes the current accumulated value and the new event data, returning the new accumulated value.\n   * @param {A} init The initial value of the accumulator.\n   * @returns {Event<A, AR>} A new `Event` instance that emits the reduced value.\n   *\n   * ```typescript\n   * const sumEvent = numberEvent.reduce((a, b) => a + b, 0);\n   * sumEvent.on((sum) => console.log(sum)); // 1, 3, 6\n   * await sumEvent(1);\n   * await sumEvent(2);\n   * await sumEvent(3);\n   * ```\n   */\n  reduce<A, AR = R>(reducer: Reducer<T, A>, init?: A): Event<Awaited<A>, AR>;\n  reduce<A, AR = R>(reducer: Reducer<T, A>, ...init: unknown[]): Event<Awaited<A>, AR> {\n    let hasInit = init.length === 1;\n    let result = init[0] as A | undefined;\n\n    return this.pipe(async function* (value) {\n      if (hasInit) {\n        result = await reducer(result!, value);\n        yield result;\n      } else {\n        result = value as unknown as A;\n        hasInit = true;\n      }\n    });\n  }\n\n  /**\n   * Transforms each event's data into multiple events using an expander function. The expander function takes\n   * the original event's data and returns an array of new data elements, each of which will be emitted individually\n   * by the returned `Event` instance. This method is useful for scenarios where an event's data can naturally\n   * be expanded into multiple, separate pieces of data which should each trigger further processing independently.\n   *\n   * @template ET - The type of data elements in the array returned by the expander function.\n   * @template ER - The type of responses emitted by the expanded event, usually related to or the same as `ET`.\n   * @param {Expander<T, ET[]>} expander - A function that takes the original event data and returns an array of new data elements.\n   * @returns {Event<ET, ER>} - A new `Event` instance that emits each value from the array returned by the expander function.\n   *\n   * ```typescript\n   * // Assuming an event that emits a sentence, create a new event that emits each word from the sentence separately.\n   * const sentenceEvent = new Event<string>();\n   * const wordEvent = sentenceEvent.expand(sentence => sentence.split(' '));\n   * wordEvent.on(word => console.log('Word:', word));\n   * await sentenceEvent('Hello world'); // Logs: \"Word: Hello\", \"Word: world\"\n   * ```\n   */\n  expand<ET, ER>(expander: Expander<T, ET[]>): Event<Awaited<ET>, ER> {\n    return this.pipe(async function* (value) {\n      const values = await expander(value);\n      for (const value of values) {\n        yield value;\n      }\n    });\n  }\n\n  /**\n   * Creates a new event that emits values based on a conductor event. The orchestrated event will emit the last value\n   * captured from the original event each time the conductor event is triggered.\n   *\n   * @template T The type of data emitted by the original event.\n   * @template R The type of data emitted by the orchestrated event, usually the same as `T`.\n   * @param {Event<unknown, unknown>} conductor The event that triggers the emission of the last captured value.\n   * @returns {Event<T, R>} A new event that emits values based on the conductor's triggers.\n   *\n   * ```typescript\n   * const rightClickPositionEvent = mouseMoveEvent.orchestrate(mouseRightClickEvent);\n   * ```\n   *\n   * ```typescript\n   * // An event that emits whenever a \"tick\" event occurs.\n   * const tickEvent = new Event<void>();\n   * const dataEvent = new Event<string>();\n   * const synchronizedEvent = dataEvent.orchestrate(tickEvent);\n   * synchronizedEvent.on(data => console.log('Data on tick:', data));\n   * await dataEvent('Hello');\n   * await dataEvent('World!');\n   * await tickEvent(); // Logs: \"Data on tick: World!\"\n   * ```\n   */\n  orchestrate<CT, CR>(conductor: Event<CT, CR>): Event<T, R> {\n    let initialized = false;\n    let lastValue: T;\n    const unsubscribe = this.on(async (event) => {\n      initialized = true;\n      lastValue = event;\n    });\n    const unsubscribeConductor = conductor.on(async () => {\n      if (initialized) {\n        await orchestratedEvent(lastValue);\n        initialized = false;\n      }\n    });\n\n    const orchestratedEvent = new Event<T, R>(unsubscribe.post(unsubscribeConductor));\n\n    return orchestratedEvent;\n  }\n  /**\n   * Creates a debounced event that delays triggering until after a specified interval has elapsed\n   * following the last time it was invoked. This method is particularly useful for limiting the rate\n   * at which a function is executed. Common use cases include handling rapid user inputs, window resizing,\n   * or scroll events.\n   *\n   * @param {number} interval - The amount of time to wait (in milliseconds) before firing the debounced event.\n   * @returns {Event<T, R>} An event of debounced events.\n   *\n   * ```typescript\n   * const debouncedEvent = textInputEvent.debounce(100);\n   * debouncedEvent.on((str) => console.log(str)); // only 'text' is emitted\n   * await event('t');\n   * await event('te');\n   * await event('tex');\n   * await event('text');\n   * ```\n   */\n  debounce(interval: number): Event<Awaited<T>, unknown> {\n    let controller = new AbortController();\n\n    return this.pipe(async function* (value) {\n      controller.abort();\n      controller = new AbortController();\n      const complete = await setTimeoutAsync(interval, controller.signal);\n      if (complete) {\n        yield value;\n      }\n    });\n  }\n\n  /**\n   * Creates a throttled event that emits values at most once per specified interval.\n   *\n   * This is useful for controlling the rate of event emissions, especially for high-frequency events.\n   * The throttled event will immediately emit the first value, and then only emit subsequent values\n   * if the specified interval has passed since the last emission.\n   *\n   * @param interval - The time interval (in milliseconds) between allowed emissions.\n   * @returns A new Event that emits throttled values.\n   *\n   * ```typescript\n   * const scrollEvent = new Event();\n   * const throttledScroll = scrollEvent.throttle(100); // Emit at most every 100ms\n   * throttledScroll.on(() => console.log(\"Throttled scroll event\"));\n   * ```\n   */\n  throttle(interval: number): Event<Awaited<T>, unknown> {\n    let timeout = 0;\n    let pendingValue: T;\n    let hasPendingValue = false;\n\n    return this.pipe(async function* (value) {\n      const now = Date.now();\n      if (timeout <= now) {\n        timeout = now + interval;\n        yield value;\n      } else {\n        pendingValue = value;\n        if (!hasPendingValue) {\n          hasPendingValue = true;\n          await setTimeoutAsync(timeout - now);\n          timeout = now + interval;\n          hasPendingValue = false;\n          yield pendingValue;\n        }\n      }\n    });\n  }\n\n  /**\n   * Aggregates multiple event emissions into batches and emits the batched events either at specified\n   * time intervals or when the batch reaches a predefined size. This method is useful for grouping\n   * a high volume of events into manageable chunks, such as logging or processing data in bulk.\n   *\n   * @param {number} interval - The time in milliseconds between batch emissions.\n   * @param {number} [size] - Optional. The maximum size of each batch. If specified, triggers a batch emission\n   * once the batch reaches this size, regardless of the interval.\n   * @returns {Event<T[], R>} An event of the batched results.\n   *\n   * ```typescript\n   * // Batch messages for bulk processing every 1 second or when 10 messages are collected\n   * const messageEvent = createEvent<string, void>();\n   * const batchedMessageEvent = messageEvent.batch(1000, 10);\n   * batchedMessageEvent.on((messages) => console.log('Batched Messages:', messages));\n   * ```\n   */\n  batch(interval: number, size?: number): Event<T[], R> {\n    let controller = new AbortController();\n    const batch: T[] = [];\n\n    return this.pipe(async function* (value) {\n      batch.push(value);\n      if (size !== undefined && batch.length >= size) {\n        controller.abort();\n        yield batch.splice(0);\n      }\n      if (batch.length === 1) {\n        controller = new AbortController();\n        const complete = await setTimeoutAsync(interval, controller.signal);\n        if (complete) {\n          yield batch.splice(0);\n        }\n      }\n    });\n  }\n\n  /**\n   * Creates a queue from the event, where each emitted value is sequentially processed. The returned object allows popping elements\n   * from the queue, ensuring that elements are handled one at a time. This method is ideal for scenarios where order and sequential processing are critical.\n   *\n   * @returns {Queue<T>} An object representing the queue. The 'pop' method retrieves the next element from the queue, while 'stop' halts further processing.\n   *\n   * ```typescript\n   * // Queueing tasks for sequential execution\n   * const taskEvent = new Event<string>();\n   * const taskQueue = taskEvent.queue();\n   * (async () => {\n   *   console.log('Processing:', await taskQueue.pop()); // Processing: Task 1\n   *   // Queue also can be used as a Promise\n   *   console.log('Processing:', await taskQueue); // Processing: Task 2\n   * })();\n   * await taskEvent('Task 1');\n   * await taskEvent('Task 2');\n   *```\n   *\n   *```typescript\n   * // Additionally, the queue can be used as an async iterator\n   * const taskEvent = new Event<string>();\n   * const taskQueue = taskEvent.queue();\n   * (async () => {\n   *   for await (const task of taskQueue) {\n   *     console.log('Processing:', task);\n   *   }\n   * })();\n   * await taskEvent('Task 1');\n   * await taskEvent('Task 2');\n   * ```\n   *\n   */\n  queue(): Queue<T> {\n    const queue: T[] = [];\n    let done = false;\n    const valueEvent = new Event<void>();\n\n    const unsubscribe = this.on(async (value) => {\n      queue.push(value);\n      await valueEvent();\n    });\n\n    const pop = async () => {\n      if (!queue.length) {\n        await valueEvent;\n      }\n      return queue.shift()!;\n    };\n    const stop = async () => {\n      await unsubscribe();\n      done = true;\n      await valueEvent();\n    };\n\n    return {\n      pop,\n      stop,\n      get stopped() {\n        return done;\n      },\n      then<TResult1 = T, TResult2 = never>(\n        onfulfilled?: ((value: T) => TResult1 | PromiseLike<TResult1>) | null | undefined,\n        onrejected?: ((reason: unknown) => TResult2 | PromiseLike<TResult2>) | null | undefined,\n      ): Promise<TResult1 | TResult2> {\n        return this.pop().then(onfulfilled, onrejected);\n      },\n      [Symbol.asyncIterator]() {\n        return {\n          next: async () => {\n            return { value: await pop(), done };\n          },\n        };\n      },\n    };\n  }\n}\n\nexport interface Queue<T> extends AsyncIterable<T>, PromiseLike<T> {\n  pop(): Promise<T>;\n  stop(): Promise<void>;\n  stopped: boolean;\n}\n\nexport type EventParameters<T> = T extends Event<infer P, any> ? P : never;\n\nexport type EventResult<T> = T extends Event<any, infer R> ? R : never;\n\nexport type AllEventsParameters<T extends Event<any, any>[]> = { [K in keyof T]: EventParameters<T[K]> }[number];\n\nexport type AllEventsResults<T extends Event<any, any>[]> = { [K in keyof T]: EventResult<T[K]> }[number];\n\n/**\n * Merges multiple events into a single event. This function takes any number of `Event` instances\n * and returns a new `Event` that triggers whenever any of the input events trigger. The parameters\n * and results of the merged event are derived from the input events, providing a flexible way to\n * handle multiple sources of events in a unified manner.\n *\n * @template Events - An array of `Event` instances.\n * @param {...Events} events - A rest parameter that takes multiple events to be merged.\n * @returns {Event<AllEventsParameters<Events>, AllEventsResults<Events>>} - Returns a new `Event` instance\n *           that triggers with the parameters and results of any of the merged input events.\n *\n * ```typescript\n * // Merging mouse and keyboard events into a single event\n * const mouseEvent = createEvent<MouseEvent>();\n * const keyboardEvent = createEvent<KeyboardEvent>();\n * const inputEvent = merge(mouseEvent, keyboardEvent);\n * inputEvent.on(event => console.log('Input event:', event));\n * ```\n */\nexport const merge = <Events extends Event<any, any>[]>(...events: Events): Event<AllEventsParameters<Events>, AllEventsResults<Events>> => {\n  const mergedEvent = new Event<AllEventsParameters<Events>, AllEventsResults<Events>>();\n  events.forEach((event) => event.on(mergedEvent));\n  return mergedEvent;\n};\n\n/**\n * Creates a periodic event that triggers at a specified interval. The event will automatically emit\n * an incrementing counter value each time it triggers, starting from zero. This function is useful\n * for creating time-based triggers within an application, such as updating UI elements, polling,\n * or any other timed operation.\n *\n * @template R - The return type of the event handler function, defaulting to `void`.\n * @param {number} interval - The interval in milliseconds at which the event should trigger.\n * @returns {Event<number, R>} - An `Event` instance that triggers at the specified interval,\n *           emitting an incrementing counter value.\n *\n * ```typescript\n * // Creating an interval event that logs a message every second\n * const tickEvent = createInterval(1000);\n * tickEvent.on(tickNumber => console.log('Tick:', tickNumber));\n * ```\n */\nexport const createInterval = <R = unknown>(interval: number): Event<number, R> => {\n  let counter = 0;\n  const intervalEvent = new Event<number, R>(() => clearInterval(timerId));\n  const timerId: ReturnType<typeof setInterval> = setInterval(() => intervalEvent(counter++), interval);\n  return intervalEvent;\n};\n\n/**\n * Creates a new instance of the `Event` class, which allows for the registration of event handlers that get called when the event is emitted.\n * This factory function simplifies the creation of events by encapsulating the instantiation logic, providing a clean and simple API for event creation.\n *\n * @typeParam T - The tuple of argument types that the event will accept.\n * @typeParam R - The return type of the event handler function, which is emitted after processing the event data.\n * @returns {Event<T, R>} - A new instance of the `Event` class, ready to have listeners added to it.\n *\n * ```typescript\n * // Create a new event that accepts a string and returns the string length\n * const myEvent = createEvent<string, number>();\n * myEvent.on((str: string) => str.length);\n * myEvent('hello').then(results => console.log(results)); // Logs: [5]\n * ```\n */\nexport const createEvent = <T = unknown, R = unknown>(): Event<T, R> => new Event<T, R>();\n\nexport default createEvent;\n\n/**\n * A type helper that extracts the event listener type\n *\n * @typeParam E - The event type.\n */\nexport type EventHandler<E> = E extends Event<infer T, infer R> ? Listener<T, R> : never;\n\n/**\n * A type helper that extracts the event filter type\n *\n * @typeParam E The event type to filter.\n */\nexport type EventFilter<E> = FilterFunction<EventParameters<E>>;\n\n/**\n * A type helper that extracts the event predicate type\n *\n * @typeParam E The event type to predicate.\n */\nexport type EventPredicate<E, P extends EventParameters<E>> = Predicate<EventParameters<E>, P>;\n\n/**\n * A type helper that extracts the event mapper type\n *\n * @typeParam E The event type to map.\n * @typeParam M The new type to map `E` to.\n */\nexport type EventMapper<E, M> = Mapper<EventParameters<E>, M>;\n\n/**\n * A type helper that extracts the event mapper type\n *\n * @typeParam E The type of event to reduce.\n * @typeParam M The type of reduced event.\n */\nexport type EventReducer<E, R> = Reducer<EventParameters<E>, R>;\n"],"names":["Callable","Event","Unsubscribe","createEvent","createInterval","merge","removeListener","setTimeoutAsync","listeners","listener","index","indexOf","wasRemoved","splice","timeout","signal","Promise","resolve","timerId","setTimeout","addEventListener","clearTimeout","constructor","func","Object","setPrototypeOf","prototype","_done","callback","done","pre","post","countdown","count","HookType","hooks","_disposed","dispose","value","all","map","clear","_error","error","size","length","disposed","lacks","has","off","forEach","spy","on","push","once","oneTimeListener","event","undefined","then","onfulfilled","onrejected","unsubscribe","promise","reject","finally","u","settle","allSettled","settled","Symbol","asyncIterator","queue","hasNextEvent","emitEvent","target","action","next","shift","return","pipe","generator","generatedValue","result","catch","e","filter","first","filteredEvent","mapper","reduce","reducer","init","hasInit","expand","expander","values","orchestrate","conductor","initialized","lastValue","unsubscribeConductor","orchestratedEvent","debounce","interval","controller","AbortController","abort","complete","throttle","pendingValue","hasPendingValue","now","Date","batch","valueEvent","pop","stop","stopped","events","mergedEvent","counter","intervalEvent","clearInterval","setInterval"],"mappings":"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"}