evnty 3.0.31 → 3.0.33

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts"],"sourcesContent":["export type MaybePromise<T> = Promise<T> | PromiseLike<T> | T;\n\nexport interface Callback<R = void> {\n (): MaybePromise<R>;\n}\n\nexport interface Listener<T, R = unknown> {\n (event: T): MaybePromise<R | void>;\n}\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 * @param {Listener<T, R>[]} listeners - The array of listeners from which to remove the listener.\n * @param {Listener<T, R>} 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 * @example\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 */\nexport const removeListener = <T, R>(listeners: Listener<T, R>[], listener: Listener<T, R>): 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 * 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 FunctionExt is called as a function, it will\n * call the function passed to its constructor with the same arguments.\n * @internal\n */\nexport abstract class FunctionExt extends Function {\n constructor(func: Function) {\n super();\n return Object.setPrototypeOf(func, new.target.prototype);\n }\n}\n\nexport interface Unsubscribe {\n (): MaybePromise<void>;\n}\n\n/**\n * @internal\n */\nexport class Unsubscribe extends FunctionExt {\n constructor(callback: Callback) {\n super(callback);\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\nexport interface Event<T = any, R = any> {\n (event: T): Promise<(void | Awaited<R>)[]>;\n}\n\n/**\n * Represents a pair of events handling both successful outcomes and errors.\n * This interface is used to manage asynchronous operations where events can either\n * result in a successful output or an error.\n *\n * The `value` event is triggered when the operation succeeds and emits a result.\n * The `error` event is triggered when the operation encounters an error, allowing\n * error handling mechanisms to process or log the error accordingly.\n *\n * @template T The type of data emitted by the successful outcome of the event.\n * @template R The type of data (if any) emitted by the error event.\n * @template E The type of error information emitted by the error event, usually an Error object or string.\n *\n * @example\n * // Assume an asynchronous function that fetches user data\n * function fetchUserData(): ResultEvents<UserData, Error> {\n * const success = new Event<UserData>();\n * const failure = new Event<Error>();\n *\n * fetch('/api/user')\n * .then(response => response.json())\n * .then(data => success(data))\n * .catch(error => failure(error));\n *\n * return { value: success, error: failure };\n * }\n *\n * const userDataEvent = fetchUserData();\n * userDataEvent.value.on(data => console.log('User data received:', data));\n * userDataEvent.error.on(error => console.error('An error occurred:', error));\n */\nexport interface ResultEvents<T, R, E = unknown> {\n value: Event<T, R>; // Event triggered on a successful result.\n error: Event<E, void>; // Event triggered on an error occurrence.\n}\n\nexport interface Queue<T> {\n pop(): MaybePromise<T | undefined>;\n stop(): MaybePromise<void>;\n}\n\n/**\n * A class representing an anonymous event that can be listened to or triggered.\n *\n * @typeParam T - The tuple of arguments that the event takes.\n * @typeParam R - The return type of the event.\n */\nexport class Event<T, R> extends FunctionExt {\n /**\n * The array of listeners for the event.\n */\n private listeners: Listener<T, R>[];\n /**\n * The array of listeners for the event.\n */\n private addSpies: Array<(listener: Listener<T, R> | void) => void> = [];\n private removeSpies: Array<(listener: Listener<T, R> | void) => void> = [];\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 * @example\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 * @param dispose - A function to call on the event disposal.\n */\n constructor(dispose?: Callback) {\n const listeners: Listener<T, R>[] = [];\n // passes listeners exceptions to catch method\n super(async (value: T): Promise<(void | Awaited<R>)[]> => Promise.all(listeners.map(async (listener) => listener(await value))));\n this.listeners = listeners;\n\n this.dispose = async () => {\n this.clear();\n await dispose?.();\n };\n }\n\n /**\n * The number of listeners for the event.\n */\n get size(): number {\n return this.listeners.length;\n }\n\n /**\n * Checks if a specific listener is not registered for the event.\n * This method is typically used to verify whether an event listener has not been added to prevent duplicate registrations.\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 * @example\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 a specific listener is registered for the event.\n * This method is used to confirm the presence of a listener in the event's registration list.\n *\n * @param listener - The listener function to verify.\n * @returns `true` if the listener is currently registered; otherwise, `false`.\n *\n * @example\n * // Verify if a listener is registered\n * if (event.has(myListener)) {\n * console.log('Listener is already registered');\n * }\n */\n has(listener: Listener<T, R>): boolean {\n return this.listeners.indexOf(listener) !== -1;\n }\n\n /**\n * Removes a listener from the event's registration list.\n * This method is used when the listener is no longer needed, helping to prevent memory leaks and unnecessary executions.\n *\n * @param listener - The listener to remove.\n * @returns The event instance, allowing for method chaining.\n *\n * @example\n * // Remove a listener\n * event.off(myListener);\n */\n off(listener: Listener<T, R>): this {\n if (removeListener(this.listeners, listener)) {\n this.removeSpies.forEach((spy) => spy(listener));\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 * @example\n * // Add a listener to an event\n * const unsubscribe = event.on((data) => {\n * console.log('Event data:', data);\n * });\n */\n on(listener: Listener<T, R>): Unsubscribe {\n this.listeners.push(listener);\n if (this.addSpies.length > 0) {\n this.addSpies.forEach((spy) => spy(listener));\n }\n return new Unsubscribe(() => {\n 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 * @example\n * // Register a one-time listener\n * const onceUnsubscribe = event.once((data) => {\n * console.log('Received data once:', data);\n * });\n */\n once(listener: Listener<T, R>): Unsubscribe {\n const oneTimeListener = (event: T) => {\n this.off(oneTimeListener);\n return listener(event);\n };\n return this.on(oneTimeListener);\n }\n\n /**\n * Returns a Promise that resolves with the first event argument emitted.\n * This method is useful for scenarios where you need to wait for the first occurrence\n * of an event and then perform actions based on the event data.\n *\n * @returns {Promise<T>} A Promise that resolves with the first event argument emitted.\n * @example\n * const clickEvent = new Event<[number, number]>();\n * clickEvent.onceAsync().then(([x, y]) => {\n * console.log(`First click at (${x}, ${y})`);\n * });\n */\n onceAsync(): Promise<T> {\n return new Promise<T>((resolve) => this.once((event) => resolve(event)));\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 triggerings after certain conditions.\n *\n * @returns {this} The instance of the event, allowing for method chaining.\n * @example\n * const myEvent = new Event();\n * myEvent.on(data => console.log(data));\n * myEvent.clear(); // Clears all listeners\n */\n clear(): this {\n this.listeners.splice(0);\n this.removeSpies.forEach((spy) => spy());\n return this;\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>} filter 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 * @example\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 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 const unsubscribe = this.on(async (event: T) => {\n if (filteredEvent.size > 0 && (await filter(event))) {\n await filteredEvent(event as P);\n }\n });\n const filteredEvent = new Event<P, R>(unsubscribe);\n return filteredEvent;\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>} filter - 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 * @example\n * const sizeChangeEvent = new Event<number>();\n * const sizeReachedEvent = sizeChangeEvent.first(size => size > 1024);\n * sizeReachedEvent.on(() => console.log('Size threshold exceeded.'));\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 unsubscribe = this.on(async (event: T) => {\n if (filteredEvent.size > 0 && (await filter(event))) {\n await unsubscribe();\n await filteredEvent(event as P);\n }\n });\n const filteredEvent = new Event<P, R>(unsubscribe);\n return filteredEvent;\n }\n\n /**\n * Returns a Promise that resolves once an event occurs that meets the filter criteria.\n * This method is particularly useful for handling asynchronous flows where you need to wait for a specific condition.\n *\n * @param {Filter<T, P>} filter - The filter function or predicate.\n * @returns {Promise<P>} A Promise that resolves once the filter condition is met.\n * @example\n * const mouseEvent = new Event<{x: number, y: number}>();\n * const clickAtPosition = mouseEvent.firstAsync(pos => pos.x > 200 && pos.y > 200);\n * clickAtPosition.then(pos => console.log(`Clicked at (${pos.x}, ${pos.y})`));\n */\n firstAsync<P extends T>(predicate: Predicate<T, P>): Promise<P>;\n firstAsync<P extends T>(filter: FilterFunction<T>): Promise<P>;\n firstAsync<P extends T>(filter: Filter<T, P>): Promise<P> {\n return this.first<P>(filter).onceAsync();\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 * @example\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 * @param mapper A function that maps the values of this event to a new value.\n * @returns A new event that emits the mapped values.\n */\n map<M, MR = R>(mapper: Mapper<T, M>): Event<M, MR> {\n const unsubscribe = this.on(async (event) => {\n if (mappedEvent.size > 0) {\n const value = await mapper(event);\n await mappedEvent(value);\n }\n });\n const mappedEvent = new Event<M, MR>(unsubscribe);\n return mappedEvent;\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 * @example\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 * @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 */\n reduce<A, AR = R>(reducer: Reducer<T, A>, init: A): Event<A, AR> {\n let value = init;\n const unsubscribe = this.on(async (event) => {\n if (reducedEvent.size > 0) {\n value = await reducer(value, event);\n await reducedEvent(value);\n }\n });\n const reducedEvent = new Event<A, AR>(unsubscribe);\n return reducedEvent;\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 * @example\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 expand<ET, ER>(expander: Expander<T, ET[]>): Event<ET, ER> {\n const unsubscribe = this.on(async (event) => {\n if (expandedEvent.size > 0) {\n const values = await expander(event);\n for (const value of values) {\n await expandedEvent(value);\n }\n }\n });\n const expandedEvent = new Event<ET, ER>(unsubscribe);\n return expandedEvent;\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. This method is useful for synchronizing\n * events, where the emission of one event controls the timing of another.\n *\n * @example\n * const rightClickPositionEvent = mouseMoveEvent.orchestrate(mouseRightClickEvent);\n *\n * @example\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 * @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 An event that signals when the orchestrated event should emit.\n * @returns {Event<T, R>} An orchestrated event that emits values based on the conductor's trigger.\n *\n */\n orchestrate(conductor: Event<any, any>): 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 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 * @example\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 * @param {number} interval - The amount of time to wait (in milliseconds) before firing the debounced event.\n * @returns {ResultEvents<T, R, unknown>} An object containing two events: `value` for the debounced successful\n * outputs and `error` for catching errors during the debounce handling.\n */\n debounce(interval: number): ResultEvents<T, R, unknown> {\n let timer: ReturnType<typeof setTimeout>;\n const unsubscribe = this.on((event) => {\n clearTimeout(timer);\n timer = setTimeout(() => {\n value(event).catch(error);\n }, interval);\n });\n const value = new Event<T, R>(unsubscribe);\n const error = new Event<unknown, void>();\n return { value, error };\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 * @example\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.value.on((messages) => console.log('Batched Messages:', messages));\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 {ResultEvents<T[], R, unknown>} An object containing two events: `value` for the batched results\n * and `error` for errors that may occur during batching.\n */\n batch(interval: number, size?: number): ResultEvents<T[], R, unknown> {\n let timer: ReturnType<typeof setTimeout>;\n const batch: T[] = [];\n\n const emitBatch = () => {\n if (batch.length !== 0) {\n clearTimeout(timer);\n value(batch.splice(0)).catch(error);\n }\n };\n\n const unsubscribe = this.on((event) => {\n if (batch.length === 0) {\n timer = setTimeout(emitBatch, interval);\n }\n\n batch.push(event);\n if (size !== undefined && batch.length >= size) {\n emitBatch();\n }\n });\n const value = new Event<T[], R>(unsubscribe);\n const error = new Event<unknown, void>();\n return { value, error };\n }\n\n /**\n * Transforms an event into an AsyncIterable that yields values as they are emitted by the event. This allows for the consumption\n * of event data using async iteration mechanisms. The iterator generated will yield all emitted values until the event\n * signals it should no longer be active.\n *\n * @returns {AsyncIterable<T>} An async iterable that yields values emitted by the event.\n * @example\n * // Assuming an event that emits numbers\n * const numberEvent = new Event<number>();\n * const numberIterable = numberEvent.generator();\n * (async () => {\n * for await (const num of numberIterable) {\n * console.log('Number:', num);\n * }\n * })();\n * await numberEvent(1);\n * await numberEvent(2);\n * await numberEvent(3);\n */\n generator(): AsyncIterable<T> {\n const queue: T[] = [];\n const valueEvent = new Event<boolean>();\n const emitEvent = async (value: T) => {\n queue.push(value);\n await valueEvent(false);\n };\n const unsubscribe = this.on(emitEvent).pre(() => {\n removeListener(this.removeSpies, spy);\n });\n\n const spy: (typeof this.removeSpies)[number] = (target = emitEvent) => {\n if (target === emitEvent) {\n valueEvent(true);\n unsubscribe();\n }\n };\n this.removeSpies.push(spy);\n\n return {\n [Symbol.asyncIterator]() {\n return {\n async next() {\n if (queue.length) {\n return Promise.resolve({ value: queue.shift()!, done: false });\n }\n const result = await valueEvent.onceAsync();\n if (!result) {\n return Promise.resolve({ value: queue.shift()!, done: false });\n }\n return Promise.resolve({ value: undefined, done: true });\n },\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 * @example\n * // Queueing tasks for sequential execution\n * const taskEvent = new Event<string>();\n * const taskQueue = taskEvent.queue();\n * await taskEvent('Task 1');\n * await taskEvent('Task 2');\n * (async () => {\n * console.log('Processing:', await taskQueue.pop()); // Processing: Task 1\n * console.log('Processing:', await taskQueue.pop()); // Processing: Task 2\n * })();\n */\n queue(): Queue<T> {\n const queue: T[] = [];\n const valueEvent = new Event<void>();\n const unsubscribe = this.on(async (value) => {\n queue.push(value);\n await valueEvent();\n });\n\n return {\n async pop() {\n if (!queue.length) {\n await valueEvent.onceAsync();\n }\n return queue.shift();\n },\n async stop() {\n await unsubscribe();\n },\n };\n }\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 * @example\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 */\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 * @example\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 */\nexport const createInterval = <R = void>(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 * @example\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 */\nexport const createEvent = <T, R = void>(): 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":["Event","FunctionExt","Unsubscribe","createEvent","createInterval","merge","removeListener","listeners","listener","index","indexOf","wasRemoved","splice","Function","constructor","func","Object","setPrototypeOf","prototype","callback","pre","post","countdown","count","addSpies","removeSpies","dispose","value","Promise","all","map","clear","size","length","lacks","has","off","forEach","spy","on","push","once","oneTimeListener","event","onceAsync","resolve","filter","unsubscribe","filteredEvent","first","firstAsync","mapper","mappedEvent","reduce","reducer","init","reducedEvent","expand","expander","expandedEvent","values","orchestrate","conductor","initialized","lastValue","unsubscribeConductor","orchestratedEvent","debounce","interval","timer","clearTimeout","setTimeout","catch","error","batch","emitBatch","undefined","generator","queue","valueEvent","emitEvent","target","Symbol","asyncIterator","next","shift","done","result","pop","stop","events","mergedEvent","counter","intervalEvent","clearInterval","timerId","setInterval"],"rangeMappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;","mappings":"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"}
1
+ {"version":3,"sources":["../src/index.ts"],"sourcesContent":["export type MaybePromise<T> = Promise<T> | PromiseLike<T> | T;\n\nexport interface Callback<R = void> {\n (): MaybePromise<R>;\n}\n\nexport interface Listener<T, R = unknown> {\n (event: T): MaybePromise<R | void>;\n}\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 * @param {Listener<T, R>[]} listeners - The array of listeners from which to remove the listener.\n * @param {Listener<T, R>} 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 * @example\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 */\nexport const removeListener = <T, R>(listeners: Listener<T, R>[], listener: Listener<T, R>): 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 * 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 FunctionExt is called as a function, it will\n * call the function passed to its constructor with the same arguments.\n * @internal\n */\nexport abstract class FunctionExt extends Function {\n constructor(func: Function) {\n super();\n return Object.setPrototypeOf(func, new.target.prototype);\n }\n}\n\nexport interface Unsubscribe {\n (): MaybePromise<void>;\n}\n\n/**\n * @internal\n */\nexport class Unsubscribe extends FunctionExt {\n constructor(callback: Callback) {\n super(callback);\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\nexport interface Event<T = any, R = any> {\n (event: T): Promise<(void | Awaited<R>)[]>;\n}\n\n/**\n * Represents a pair of events handling both successful outcomes and errors.\n * This interface is used to manage asynchronous operations where events can either\n * result in a successful output or an error.\n *\n * The `value` event is triggered when the operation succeeds and emits a result.\n * The `error` event is triggered when the operation encounters an error, allowing\n * error handling mechanisms to process or log the error accordingly.\n *\n * @template T The type of data emitted by the successful outcome of the event.\n * @template R The type of data (if any) emitted by the error event.\n * @template E The type of error information emitted by the error event, usually an Error object or string.\n *\n * @example\n * // Assume an asynchronous function that fetches user data\n * function fetchUserData(): ResultEvents<UserData, Error> {\n * const success = new Event<UserData>();\n * const failure = new Event<Error>();\n *\n * fetch('/api/user')\n * .then(response => response.json())\n * .then(data => success(data))\n * .catch(error => failure(error));\n *\n * return { value: success, error: failure };\n * }\n *\n * const userDataEvent = fetchUserData();\n * userDataEvent.value.on(data => console.log('User data received:', data));\n * userDataEvent.error.on(error => console.error('An error occurred:', error));\n */\nexport interface ResultEvents<T, R, E = unknown> {\n value: Event<T, R>; // Event triggered on a successful result.\n error: Event<E, void>; // Event triggered on an error occurrence.\n}\n\nexport interface Queue<T> {\n pop(): MaybePromise<T | undefined>;\n stop(): MaybePromise<void>;\n}\n\n/**\n * A class representing an anonymous event that can be listened to or triggered.\n *\n * @typeParam T - The tuple of arguments that the event takes.\n * @typeParam R - The return type of the event.\n */\nexport class Event<T, R> extends FunctionExt {\n /**\n * The array of listeners for the event.\n */\n private listeners: Listener<T, R>[];\n /**\n * The array of listeners for the event.\n */\n private addSpies: Array<(listener: Listener<T, R> | void) => void> = [];\n private removeSpies: Array<(listener: Listener<T, R> | void) => void> = [];\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 * @example\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 * @param dispose - A function to call on the event disposal.\n */\n constructor(dispose?: Callback) {\n const listeners: Listener<T, R>[] = [];\n // passes listeners exceptions to catch method\n super(async (value: T): Promise<(void | Awaited<R>)[]> => Promise.all(listeners.map(async (listener) => listener(await value))));\n this.listeners = listeners;\n\n this.dispose = async () => {\n this.clear();\n await dispose?.();\n };\n }\n\n /**\n * The number of listeners for the event.\n */\n get size(): number {\n return this.listeners.length;\n }\n\n /**\n * Checks if a specific listener is not registered for the event.\n * This method is typically used to verify whether an event listener has not been added to prevent duplicate registrations.\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 * @example\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 a specific listener is registered for the event.\n * This method is used to confirm the presence of a listener in the event's registration list.\n *\n * @param listener - The listener function to verify.\n * @returns `true` if the listener is currently registered; otherwise, `false`.\n *\n * @example\n * // Verify if a listener is registered\n * if (event.has(myListener)) {\n * console.log('Listener is already registered');\n * }\n */\n has(listener: Listener<T, R>): boolean {\n return this.listeners.indexOf(listener) !== -1;\n }\n\n /**\n * Removes a listener from the event's registration list.\n * This method is used when the listener is no longer needed, helping to prevent memory leaks and unnecessary executions.\n *\n * @param listener - The listener to remove.\n * @returns The event instance, allowing for method chaining.\n *\n * @example\n * // Remove a listener\n * event.off(myListener);\n */\n off(listener: Listener<T, R>): this {\n if (removeListener(this.listeners, listener)) {\n this.removeSpies.forEach((spy) => spy(listener));\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 * @example\n * // Add a listener to an event\n * const unsubscribe = event.on((data) => {\n * console.log('Event data:', data);\n * });\n */\n on(listener: Listener<T, R>): Unsubscribe {\n this.listeners.push(listener);\n if (this.addSpies.length > 0) {\n this.addSpies.forEach((spy) => spy(listener));\n }\n return new Unsubscribe(() => {\n 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 * @example\n * // Register a one-time listener\n * const onceUnsubscribe = event.once((data) => {\n * console.log('Received data once:', data);\n * });\n */\n once(listener: Listener<T, R>): Unsubscribe {\n const oneTimeListener = (event: T) => {\n this.off(oneTimeListener);\n return listener(event);\n };\n return this.on(oneTimeListener);\n }\n\n /**\n * Returns a Promise that resolves with the first event argument emitted.\n * This method is useful for scenarios where you need to wait for the first occurrence\n * of an event and then perform actions based on the event data.\n *\n * @returns {Promise<T>} A Promise that resolves with the first event argument emitted.\n * @example\n * const clickEvent = new Event<[number, number]>();\n * clickEvent.onceAsync().then(([x, y]) => {\n * console.log(`First click at (${x}, ${y})`);\n * });\n */\n onceAsync(): Promise<T> {\n return new Promise<T>((resolve) => this.once((event) => resolve(event)));\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 triggerings after certain conditions.\n *\n * @returns {this} The instance of the event, allowing for method chaining.\n * @example\n * const myEvent = new Event();\n * myEvent.on(data => console.log(data));\n * myEvent.clear(); // Clears all listeners\n */\n clear(): this {\n this.listeners.splice(0);\n this.removeSpies.forEach((spy) => spy());\n return this;\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>} filter 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 * @example\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 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 const unsubscribe = this.on(async (event: T) => {\n if (filteredEvent.size > 0 && (await filter(event))) {\n await filteredEvent(event as P);\n }\n });\n const filteredEvent = new Event<P, R>(unsubscribe);\n return filteredEvent;\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>} filter - 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 * @example\n * const sizeChangeEvent = new Event<number>();\n * const sizeReachedEvent = sizeChangeEvent.first(size => size > 1024);\n * sizeReachedEvent.on(() => console.log('Size threshold exceeded.'));\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 unsubscribe = this.on(async (event: T) => {\n if (filteredEvent.size > 0 && (await filter(event))) {\n await unsubscribe();\n await filteredEvent(event as P);\n }\n });\n const filteredEvent = new Event<P, R>(unsubscribe);\n return filteredEvent;\n }\n\n /**\n * Returns a Promise that resolves once an event occurs that meets the filter criteria.\n * This method is particularly useful for handling asynchronous flows where you need to wait for a specific condition.\n *\n * @param {Filter<T, P>} filter - The filter function or predicate.\n * @returns {Promise<P>} A Promise that resolves once the filter condition is met.\n * @example\n * const mouseEvent = new Event<{x: number, y: number}>();\n * const clickAtPosition = mouseEvent.firstAsync(pos => pos.x > 200 && pos.y > 200);\n * clickAtPosition.then(pos => console.log(`Clicked at (${pos.x}, ${pos.y})`));\n */\n firstAsync<P extends T>(predicate: Predicate<T, P>): Promise<P>;\n firstAsync<P extends T>(filter: FilterFunction<T>): Promise<P>;\n firstAsync<P extends T>(filter: Filter<T, P>): Promise<P> {\n return this.first<P>(filter).onceAsync();\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 * @example\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 * @param mapper A function that maps the values of this event to a new value.\n * @returns A new event that emits the mapped values.\n */\n map<M, MR = R>(mapper: Mapper<T, M>): Event<M, MR> {\n const unsubscribe = this.on(async (event) => {\n if (mappedEvent.size > 0) {\n const value = await mapper(event);\n await mappedEvent(value);\n }\n });\n const mappedEvent = new Event<M, MR>(unsubscribe);\n return mappedEvent;\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 * @example\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 * @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 */\n reduce<A, AR = R>(reducer: Reducer<T, A>, init: A): Event<A, AR> {\n let value = init;\n const unsubscribe = this.on(async (event) => {\n if (reducedEvent.size > 0) {\n value = await reducer(value, event);\n await reducedEvent(value);\n }\n });\n const reducedEvent = new Event<A, AR>(unsubscribe);\n return reducedEvent;\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 * @example\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 expand<ET, ER>(expander: Expander<T, ET[]>): Event<ET, ER> {\n const unsubscribe = this.on(async (event) => {\n if (expandedEvent.size > 0) {\n const values = await expander(event);\n for (const value of values) {\n await expandedEvent(value);\n }\n }\n });\n const expandedEvent = new Event<ET, ER>(unsubscribe);\n return expandedEvent;\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. This method is useful for synchronizing\n * events, where the emission of one event controls the timing of another.\n *\n * @example\n * const rightClickPositionEvent = mouseMoveEvent.orchestrate(mouseRightClickEvent);\n *\n * @example\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 * @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 An event that signals when the orchestrated event should emit.\n * @returns {Event<T, R>} An orchestrated event that emits values based on the conductor's trigger.\n *\n */\n orchestrate(conductor: Event<any, any>): 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 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 * @example\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 * @param {number} interval - The amount of time to wait (in milliseconds) before firing the debounced event.\n * @returns {ResultEvents<T, R, unknown>} An object containing two events: `value` for the debounced successful\n * outputs and `error` for catching errors during the debounce handling.\n */\n debounce(interval: number): ResultEvents<T, R, unknown> {\n let timer: ReturnType<typeof setTimeout>;\n const unsubscribe = this.on((event) => {\n clearTimeout(timer);\n timer = setTimeout(() => {\n value(event).catch(error);\n }, interval);\n });\n const value = new Event<T, R>(unsubscribe);\n const error = new Event<unknown, void>();\n return { value, error };\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 * @example\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.value.on((messages) => console.log('Batched Messages:', messages));\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 {ResultEvents<T[], R, unknown>} An object containing two events: `value` for the batched results\n * and `error` for errors that may occur during batching.\n */\n batch(interval: number, size?: number): ResultEvents<T[], R, unknown> {\n let timer: ReturnType<typeof setTimeout>;\n const batch: T[] = [];\n\n const emitBatch = () => {\n if (batch.length !== 0) {\n clearTimeout(timer);\n value(batch.splice(0)).catch(error);\n }\n };\n\n const unsubscribe = this.on((event) => {\n if (batch.length === 0) {\n timer = setTimeout(emitBatch, interval);\n }\n\n batch.push(event);\n if (size !== undefined && batch.length >= size) {\n emitBatch();\n }\n });\n const value = new Event<T[], R>(unsubscribe);\n const error = new Event<unknown, void>();\n return { value, error };\n }\n\n /**\n * Transforms an event into an AsyncIterable that yields values as they are emitted by the event. This allows for the consumption\n * of event data using async iteration mechanisms. The iterator generated will yield all emitted values until the event\n * signals it should no longer be active.\n *\n * @returns {AsyncIterable<T>} An async iterable that yields values emitted by the event.\n * @example\n * // Assuming an event that emits numbers\n * const numberEvent = new Event<number>();\n * const numberIterable = numberEvent.generator();\n * (async () => {\n * for await (const num of numberIterable) {\n * console.log('Number:', num);\n * }\n * })();\n * await numberEvent(1);\n * await numberEvent(2);\n * await numberEvent(3);\n */\n generator(): AsyncIterable<T> {\n const queue: T[] = [];\n const valueEvent = new Event<boolean>();\n const emitEvent = async (value: T) => {\n queue.push(value);\n await valueEvent(false);\n };\n const unsubscribe = this.on(emitEvent).pre(() => {\n removeListener(this.removeSpies, spy);\n });\n\n const spy: (typeof this.removeSpies)[number] = (target = emitEvent) => {\n if (target === emitEvent) {\n valueEvent(true);\n unsubscribe();\n }\n };\n this.removeSpies.push(spy);\n\n return {\n [Symbol.asyncIterator]() {\n return {\n async next() {\n if (queue.length) {\n return Promise.resolve({ value: queue.shift()!, done: false });\n }\n const result = await valueEvent.onceAsync();\n if (!result) {\n return Promise.resolve({ value: queue.shift()!, done: false });\n }\n return Promise.resolve({ value: undefined, done: true });\n },\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 * @example\n * // Queueing tasks for sequential execution\n * const taskEvent = new Event<string>();\n * const taskQueue = taskEvent.queue();\n * await taskEvent('Task 1');\n * await taskEvent('Task 2');\n * (async () => {\n * console.log('Processing:', await taskQueue.pop()); // Processing: Task 1\n * console.log('Processing:', await taskQueue.pop()); // Processing: Task 2\n * })();\n */\n queue(): Queue<T> {\n const queue: T[] = [];\n const valueEvent = new Event<void>();\n const unsubscribe = this.on(async (value) => {\n queue.push(value);\n await valueEvent();\n });\n\n return {\n async pop() {\n if (!queue.length) {\n await valueEvent.onceAsync();\n }\n return queue.shift();\n },\n async stop() {\n await unsubscribe();\n },\n };\n }\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 * @example\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 */\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 * @example\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 */\nexport const createInterval = <R = void>(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 * @example\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 */\nexport const createEvent = <T, R = void>(): 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":["Event","FunctionExt","Unsubscribe","createEvent","createInterval","merge","removeListener","listeners","listener","index","indexOf","wasRemoved","splice","Function","constructor","func","Object","setPrototypeOf","prototype","callback","pre","post","countdown","count","addSpies","removeSpies","dispose","value","Promise","all","map","clear","size","length","lacks","has","off","forEach","spy","on","push","once","oneTimeListener","event","onceAsync","resolve","filter","unsubscribe","filteredEvent","first","firstAsync","mapper","mappedEvent","reduce","reducer","init","reducedEvent","expand","expander","expandedEvent","values","orchestrate","conductor","initialized","lastValue","unsubscribeConductor","orchestratedEvent","debounce","interval","timer","clearTimeout","setTimeout","catch","error","batch","emitBatch","undefined","generator","queue","valueEvent","emitEvent","target","Symbol","asyncIterator","next","shift","done","result","pop","stop","events","mergedEvent","counter","intervalEvent","clearInterval","timerId","setInterval"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts"],"sourcesContent":["export type MaybePromise<T> = Promise<T> | PromiseLike<T> | T;\n\nexport interface Callback<R = void> {\n (): MaybePromise<R>;\n}\n\nexport interface Listener<T, R = unknown> {\n (event: T): MaybePromise<R | void>;\n}\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 * @param {Listener<T, R>[]} listeners - The array of listeners from which to remove the listener.\n * @param {Listener<T, R>} 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 * @example\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 */\nexport const removeListener = <T, R>(listeners: Listener<T, R>[], listener: Listener<T, R>): 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 * 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 FunctionExt is called as a function, it will\n * call the function passed to its constructor with the same arguments.\n * @internal\n */\nexport abstract class FunctionExt extends Function {\n constructor(func: Function) {\n super();\n return Object.setPrototypeOf(func, new.target.prototype);\n }\n}\n\nexport interface Unsubscribe {\n (): MaybePromise<void>;\n}\n\n/**\n * @internal\n */\nexport class Unsubscribe extends FunctionExt {\n constructor(callback: Callback) {\n super(callback);\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\nexport interface Event<T = any, R = any> {\n (event: T): Promise<(void | Awaited<R>)[]>;\n}\n\n/**\n * Represents a pair of events handling both successful outcomes and errors.\n * This interface is used to manage asynchronous operations where events can either\n * result in a successful output or an error.\n *\n * The `value` event is triggered when the operation succeeds and emits a result.\n * The `error` event is triggered when the operation encounters an error, allowing\n * error handling mechanisms to process or log the error accordingly.\n *\n * @template T The type of data emitted by the successful outcome of the event.\n * @template R The type of data (if any) emitted by the error event.\n * @template E The type of error information emitted by the error event, usually an Error object or string.\n *\n * @example\n * // Assume an asynchronous function that fetches user data\n * function fetchUserData(): ResultEvents<UserData, Error> {\n * const success = new Event<UserData>();\n * const failure = new Event<Error>();\n *\n * fetch('/api/user')\n * .then(response => response.json())\n * .then(data => success(data))\n * .catch(error => failure(error));\n *\n * return { value: success, error: failure };\n * }\n *\n * const userDataEvent = fetchUserData();\n * userDataEvent.value.on(data => console.log('User data received:', data));\n * userDataEvent.error.on(error => console.error('An error occurred:', error));\n */\nexport interface ResultEvents<T, R, E = unknown> {\n value: Event<T, R>; // Event triggered on a successful result.\n error: Event<E, void>; // Event triggered on an error occurrence.\n}\n\nexport interface Queue<T> {\n pop(): MaybePromise<T | undefined>;\n stop(): MaybePromise<void>;\n}\n\n/**\n * A class representing an anonymous event that can be listened to or triggered.\n *\n * @typeParam T - The tuple of arguments that the event takes.\n * @typeParam R - The return type of the event.\n */\nexport class Event<T, R> extends FunctionExt {\n /**\n * The array of listeners for the event.\n */\n private listeners: Listener<T, R>[];\n /**\n * The array of listeners for the event.\n */\n private addSpies: Array<(listener: Listener<T, R> | void) => void> = [];\n private removeSpies: Array<(listener: Listener<T, R> | void) => void> = [];\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 * @example\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 * @param dispose - A function to call on the event disposal.\n */\n constructor(dispose?: Callback) {\n const listeners: Listener<T, R>[] = [];\n // passes listeners exceptions to catch method\n super(async (value: T): Promise<(void | Awaited<R>)[]> => Promise.all(listeners.map(async (listener) => listener(await value))));\n this.listeners = listeners;\n\n this.dispose = async () => {\n this.clear();\n await dispose?.();\n };\n }\n\n /**\n * The number of listeners for the event.\n */\n get size(): number {\n return this.listeners.length;\n }\n\n /**\n * Checks if a specific listener is not registered for the event.\n * This method is typically used to verify whether an event listener has not been added to prevent duplicate registrations.\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 * @example\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 a specific listener is registered for the event.\n * This method is used to confirm the presence of a listener in the event's registration list.\n *\n * @param listener - The listener function to verify.\n * @returns `true` if the listener is currently registered; otherwise, `false`.\n *\n * @example\n * // Verify if a listener is registered\n * if (event.has(myListener)) {\n * console.log('Listener is already registered');\n * }\n */\n has(listener: Listener<T, R>): boolean {\n return this.listeners.indexOf(listener) !== -1;\n }\n\n /**\n * Removes a listener from the event's registration list.\n * This method is used when the listener is no longer needed, helping to prevent memory leaks and unnecessary executions.\n *\n * @param listener - The listener to remove.\n * @returns The event instance, allowing for method chaining.\n *\n * @example\n * // Remove a listener\n * event.off(myListener);\n */\n off(listener: Listener<T, R>): this {\n if (removeListener(this.listeners, listener)) {\n this.removeSpies.forEach((spy) => spy(listener));\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 * @example\n * // Add a listener to an event\n * const unsubscribe = event.on((data) => {\n * console.log('Event data:', data);\n * });\n */\n on(listener: Listener<T, R>): Unsubscribe {\n this.listeners.push(listener);\n if (this.addSpies.length > 0) {\n this.addSpies.forEach((spy) => spy(listener));\n }\n return new Unsubscribe(() => {\n 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 * @example\n * // Register a one-time listener\n * const onceUnsubscribe = event.once((data) => {\n * console.log('Received data once:', data);\n * });\n */\n once(listener: Listener<T, R>): Unsubscribe {\n const oneTimeListener = (event: T) => {\n this.off(oneTimeListener);\n return listener(event);\n };\n return this.on(oneTimeListener);\n }\n\n /**\n * Returns a Promise that resolves with the first event argument emitted.\n * This method is useful for scenarios where you need to wait for the first occurrence\n * of an event and then perform actions based on the event data.\n *\n * @returns {Promise<T>} A Promise that resolves with the first event argument emitted.\n * @example\n * const clickEvent = new Event<[number, number]>();\n * clickEvent.onceAsync().then(([x, y]) => {\n * console.log(`First click at (${x}, ${y})`);\n * });\n */\n onceAsync(): Promise<T> {\n return new Promise<T>((resolve) => this.once((event) => resolve(event)));\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 triggerings after certain conditions.\n *\n * @returns {this} The instance of the event, allowing for method chaining.\n * @example\n * const myEvent = new Event();\n * myEvent.on(data => console.log(data));\n * myEvent.clear(); // Clears all listeners\n */\n clear(): this {\n this.listeners.splice(0);\n this.removeSpies.forEach((spy) => spy());\n return this;\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>} filter 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 * @example\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 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 const unsubscribe = this.on(async (event: T) => {\n if (filteredEvent.size > 0 && (await filter(event))) {\n await filteredEvent(event as P);\n }\n });\n const filteredEvent = new Event<P, R>(unsubscribe);\n return filteredEvent;\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>} filter - 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 * @example\n * const sizeChangeEvent = new Event<number>();\n * const sizeReachedEvent = sizeChangeEvent.first(size => size > 1024);\n * sizeReachedEvent.on(() => console.log('Size threshold exceeded.'));\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 unsubscribe = this.on(async (event: T) => {\n if (filteredEvent.size > 0 && (await filter(event))) {\n await unsubscribe();\n await filteredEvent(event as P);\n }\n });\n const filteredEvent = new Event<P, R>(unsubscribe);\n return filteredEvent;\n }\n\n /**\n * Returns a Promise that resolves once an event occurs that meets the filter criteria.\n * This method is particularly useful for handling asynchronous flows where you need to wait for a specific condition.\n *\n * @param {Filter<T, P>} filter - The filter function or predicate.\n * @returns {Promise<P>} A Promise that resolves once the filter condition is met.\n * @example\n * const mouseEvent = new Event<{x: number, y: number}>();\n * const clickAtPosition = mouseEvent.firstAsync(pos => pos.x > 200 && pos.y > 200);\n * clickAtPosition.then(pos => console.log(`Clicked at (${pos.x}, ${pos.y})`));\n */\n firstAsync<P extends T>(predicate: Predicate<T, P>): Promise<P>;\n firstAsync<P extends T>(filter: FilterFunction<T>): Promise<P>;\n firstAsync<P extends T>(filter: Filter<T, P>): Promise<P> {\n return this.first<P>(filter).onceAsync();\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 * @example\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 * @param mapper A function that maps the values of this event to a new value.\n * @returns A new event that emits the mapped values.\n */\n map<M, MR = R>(mapper: Mapper<T, M>): Event<M, MR> {\n const unsubscribe = this.on(async (event) => {\n if (mappedEvent.size > 0) {\n const value = await mapper(event);\n await mappedEvent(value);\n }\n });\n const mappedEvent = new Event<M, MR>(unsubscribe);\n return mappedEvent;\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 * @example\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 * @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 */\n reduce<A, AR = R>(reducer: Reducer<T, A>, init: A): Event<A, AR> {\n let value = init;\n const unsubscribe = this.on(async (event) => {\n if (reducedEvent.size > 0) {\n value = await reducer(value, event);\n await reducedEvent(value);\n }\n });\n const reducedEvent = new Event<A, AR>(unsubscribe);\n return reducedEvent;\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 * @example\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 expand<ET, ER>(expander: Expander<T, ET[]>): Event<ET, ER> {\n const unsubscribe = this.on(async (event) => {\n if (expandedEvent.size > 0) {\n const values = await expander(event);\n for (const value of values) {\n await expandedEvent(value);\n }\n }\n });\n const expandedEvent = new Event<ET, ER>(unsubscribe);\n return expandedEvent;\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. This method is useful for synchronizing\n * events, where the emission of one event controls the timing of another.\n *\n * @example\n * const rightClickPositionEvent = mouseMoveEvent.orchestrate(mouseRightClickEvent);\n *\n * @example\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 * @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 An event that signals when the orchestrated event should emit.\n * @returns {Event<T, R>} An orchestrated event that emits values based on the conductor's trigger.\n *\n */\n orchestrate(conductor: Event<any, any>): 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 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 * @example\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 * @param {number} interval - The amount of time to wait (in milliseconds) before firing the debounced event.\n * @returns {ResultEvents<T, R, unknown>} An object containing two events: `value` for the debounced successful\n * outputs and `error` for catching errors during the debounce handling.\n */\n debounce(interval: number): ResultEvents<T, R, unknown> {\n let timer: ReturnType<typeof setTimeout>;\n const unsubscribe = this.on((event) => {\n clearTimeout(timer);\n timer = setTimeout(() => {\n value(event).catch(error);\n }, interval);\n });\n const value = new Event<T, R>(unsubscribe);\n const error = new Event<unknown, void>();\n return { value, error };\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 * @example\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.value.on((messages) => console.log('Batched Messages:', messages));\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 {ResultEvents<T[], R, unknown>} An object containing two events: `value` for the batched results\n * and `error` for errors that may occur during batching.\n */\n batch(interval: number, size?: number): ResultEvents<T[], R, unknown> {\n let timer: ReturnType<typeof setTimeout>;\n const batch: T[] = [];\n\n const emitBatch = () => {\n if (batch.length !== 0) {\n clearTimeout(timer);\n value(batch.splice(0)).catch(error);\n }\n };\n\n const unsubscribe = this.on((event) => {\n if (batch.length === 0) {\n timer = setTimeout(emitBatch, interval);\n }\n\n batch.push(event);\n if (size !== undefined && batch.length >= size) {\n emitBatch();\n }\n });\n const value = new Event<T[], R>(unsubscribe);\n const error = new Event<unknown, void>();\n return { value, error };\n }\n\n /**\n * Transforms an event into an AsyncIterable that yields values as they are emitted by the event. This allows for the consumption\n * of event data using async iteration mechanisms. The iterator generated will yield all emitted values until the event\n * signals it should no longer be active.\n *\n * @returns {AsyncIterable<T>} An async iterable that yields values emitted by the event.\n * @example\n * // Assuming an event that emits numbers\n * const numberEvent = new Event<number>();\n * const numberIterable = numberEvent.generator();\n * (async () => {\n * for await (const num of numberIterable) {\n * console.log('Number:', num);\n * }\n * })();\n * await numberEvent(1);\n * await numberEvent(2);\n * await numberEvent(3);\n */\n generator(): AsyncIterable<T> {\n const queue: T[] = [];\n const valueEvent = new Event<boolean>();\n const emitEvent = async (value: T) => {\n queue.push(value);\n await valueEvent(false);\n };\n const unsubscribe = this.on(emitEvent).pre(() => {\n removeListener(this.removeSpies, spy);\n });\n\n const spy: (typeof this.removeSpies)[number] = (target = emitEvent) => {\n if (target === emitEvent) {\n valueEvent(true);\n unsubscribe();\n }\n };\n this.removeSpies.push(spy);\n\n return {\n [Symbol.asyncIterator]() {\n return {\n async next() {\n if (queue.length) {\n return Promise.resolve({ value: queue.shift()!, done: false });\n }\n const result = await valueEvent.onceAsync();\n if (!result) {\n return Promise.resolve({ value: queue.shift()!, done: false });\n }\n return Promise.resolve({ value: undefined, done: true });\n },\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 * @example\n * // Queueing tasks for sequential execution\n * const taskEvent = new Event<string>();\n * const taskQueue = taskEvent.queue();\n * await taskEvent('Task 1');\n * await taskEvent('Task 2');\n * (async () => {\n * console.log('Processing:', await taskQueue.pop()); // Processing: Task 1\n * console.log('Processing:', await taskQueue.pop()); // Processing: Task 2\n * })();\n */\n queue(): Queue<T> {\n const queue: T[] = [];\n const valueEvent = new Event<void>();\n const unsubscribe = this.on(async (value) => {\n queue.push(value);\n await valueEvent();\n });\n\n return {\n async pop() {\n if (!queue.length) {\n await valueEvent.onceAsync();\n }\n return queue.shift();\n },\n async stop() {\n await unsubscribe();\n },\n };\n }\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 * @example\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 */\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 * @example\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 */\nexport const createInterval = <R = void>(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 * @example\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 */\nexport const createEvent = <T, R = void>(): 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":["removeListener","listeners","listener","index","indexOf","wasRemoved","splice","FunctionExt","Function","constructor","func","Object","setPrototypeOf","prototype","Unsubscribe","callback","pre","post","countdown","count","Event","addSpies","removeSpies","dispose","value","Promise","all","map","clear","size","length","lacks","has","off","forEach","spy","on","push","once","oneTimeListener","event","onceAsync","resolve","filter","unsubscribe","filteredEvent","first","firstAsync","mapper","mappedEvent","reduce","reducer","init","reducedEvent","expand","expander","expandedEvent","values","orchestrate","conductor","initialized","lastValue","unsubscribeConductor","orchestratedEvent","debounce","interval","timer","clearTimeout","setTimeout","catch","error","batch","emitBatch","undefined","generator","queue","valueEvent","emitEvent","target","Symbol","asyncIterator","next","shift","done","result","pop","stop","merge","events","mergedEvent","createInterval","counter","intervalEvent","clearInterval","timerId","setInterval","createEvent"],"rangeMappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;","mappings":"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"}
1
+ {"version":3,"sources":["../src/index.ts"],"sourcesContent":["export type MaybePromise<T> = Promise<T> | PromiseLike<T> | T;\n\nexport interface Callback<R = void> {\n (): MaybePromise<R>;\n}\n\nexport interface Listener<T, R = unknown> {\n (event: T): MaybePromise<R | void>;\n}\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 * @param {Listener<T, R>[]} listeners - The array of listeners from which to remove the listener.\n * @param {Listener<T, R>} 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 * @example\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 */\nexport const removeListener = <T, R>(listeners: Listener<T, R>[], listener: Listener<T, R>): 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 * 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 FunctionExt is called as a function, it will\n * call the function passed to its constructor with the same arguments.\n * @internal\n */\nexport abstract class FunctionExt extends Function {\n constructor(func: Function) {\n super();\n return Object.setPrototypeOf(func, new.target.prototype);\n }\n}\n\nexport interface Unsubscribe {\n (): MaybePromise<void>;\n}\n\n/**\n * @internal\n */\nexport class Unsubscribe extends FunctionExt {\n constructor(callback: Callback) {\n super(callback);\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\nexport interface Event<T = any, R = any> {\n (event: T): Promise<(void | Awaited<R>)[]>;\n}\n\n/**\n * Represents a pair of events handling both successful outcomes and errors.\n * This interface is used to manage asynchronous operations where events can either\n * result in a successful output or an error.\n *\n * The `value` event is triggered when the operation succeeds and emits a result.\n * The `error` event is triggered when the operation encounters an error, allowing\n * error handling mechanisms to process or log the error accordingly.\n *\n * @template T The type of data emitted by the successful outcome of the event.\n * @template R The type of data (if any) emitted by the error event.\n * @template E The type of error information emitted by the error event, usually an Error object or string.\n *\n * @example\n * // Assume an asynchronous function that fetches user data\n * function fetchUserData(): ResultEvents<UserData, Error> {\n * const success = new Event<UserData>();\n * const failure = new Event<Error>();\n *\n * fetch('/api/user')\n * .then(response => response.json())\n * .then(data => success(data))\n * .catch(error => failure(error));\n *\n * return { value: success, error: failure };\n * }\n *\n * const userDataEvent = fetchUserData();\n * userDataEvent.value.on(data => console.log('User data received:', data));\n * userDataEvent.error.on(error => console.error('An error occurred:', error));\n */\nexport interface ResultEvents<T, R, E = unknown> {\n value: Event<T, R>; // Event triggered on a successful result.\n error: Event<E, void>; // Event triggered on an error occurrence.\n}\n\nexport interface Queue<T> {\n pop(): MaybePromise<T | undefined>;\n stop(): MaybePromise<void>;\n}\n\n/**\n * A class representing an anonymous event that can be listened to or triggered.\n *\n * @typeParam T - The tuple of arguments that the event takes.\n * @typeParam R - The return type of the event.\n */\nexport class Event<T, R> extends FunctionExt {\n /**\n * The array of listeners for the event.\n */\n private listeners: Listener<T, R>[];\n /**\n * The array of listeners for the event.\n */\n private addSpies: Array<(listener: Listener<T, R> | void) => void> = [];\n private removeSpies: Array<(listener: Listener<T, R> | void) => void> = [];\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 * @example\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 * @param dispose - A function to call on the event disposal.\n */\n constructor(dispose?: Callback) {\n const listeners: Listener<T, R>[] = [];\n // passes listeners exceptions to catch method\n super(async (value: T): Promise<(void | Awaited<R>)[]> => Promise.all(listeners.map(async (listener) => listener(await value))));\n this.listeners = listeners;\n\n this.dispose = async () => {\n this.clear();\n await dispose?.();\n };\n }\n\n /**\n * The number of listeners for the event.\n */\n get size(): number {\n return this.listeners.length;\n }\n\n /**\n * Checks if a specific listener is not registered for the event.\n * This method is typically used to verify whether an event listener has not been added to prevent duplicate registrations.\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 * @example\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 a specific listener is registered for the event.\n * This method is used to confirm the presence of a listener in the event's registration list.\n *\n * @param listener - The listener function to verify.\n * @returns `true` if the listener is currently registered; otherwise, `false`.\n *\n * @example\n * // Verify if a listener is registered\n * if (event.has(myListener)) {\n * console.log('Listener is already registered');\n * }\n */\n has(listener: Listener<T, R>): boolean {\n return this.listeners.indexOf(listener) !== -1;\n }\n\n /**\n * Removes a listener from the event's registration list.\n * This method is used when the listener is no longer needed, helping to prevent memory leaks and unnecessary executions.\n *\n * @param listener - The listener to remove.\n * @returns The event instance, allowing for method chaining.\n *\n * @example\n * // Remove a listener\n * event.off(myListener);\n */\n off(listener: Listener<T, R>): this {\n if (removeListener(this.listeners, listener)) {\n this.removeSpies.forEach((spy) => spy(listener));\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 * @example\n * // Add a listener to an event\n * const unsubscribe = event.on((data) => {\n * console.log('Event data:', data);\n * });\n */\n on(listener: Listener<T, R>): Unsubscribe {\n this.listeners.push(listener);\n if (this.addSpies.length > 0) {\n this.addSpies.forEach((spy) => spy(listener));\n }\n return new Unsubscribe(() => {\n 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 * @example\n * // Register a one-time listener\n * const onceUnsubscribe = event.once((data) => {\n * console.log('Received data once:', data);\n * });\n */\n once(listener: Listener<T, R>): Unsubscribe {\n const oneTimeListener = (event: T) => {\n this.off(oneTimeListener);\n return listener(event);\n };\n return this.on(oneTimeListener);\n }\n\n /**\n * Returns a Promise that resolves with the first event argument emitted.\n * This method is useful for scenarios where you need to wait for the first occurrence\n * of an event and then perform actions based on the event data.\n *\n * @returns {Promise<T>} A Promise that resolves with the first event argument emitted.\n * @example\n * const clickEvent = new Event<[number, number]>();\n * clickEvent.onceAsync().then(([x, y]) => {\n * console.log(`First click at (${x}, ${y})`);\n * });\n */\n onceAsync(): Promise<T> {\n return new Promise<T>((resolve) => this.once((event) => resolve(event)));\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 triggerings after certain conditions.\n *\n * @returns {this} The instance of the event, allowing for method chaining.\n * @example\n * const myEvent = new Event();\n * myEvent.on(data => console.log(data));\n * myEvent.clear(); // Clears all listeners\n */\n clear(): this {\n this.listeners.splice(0);\n this.removeSpies.forEach((spy) => spy());\n return this;\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>} filter 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 * @example\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 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 const unsubscribe = this.on(async (event: T) => {\n if (filteredEvent.size > 0 && (await filter(event))) {\n await filteredEvent(event as P);\n }\n });\n const filteredEvent = new Event<P, R>(unsubscribe);\n return filteredEvent;\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>} filter - 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 * @example\n * const sizeChangeEvent = new Event<number>();\n * const sizeReachedEvent = sizeChangeEvent.first(size => size > 1024);\n * sizeReachedEvent.on(() => console.log('Size threshold exceeded.'));\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 unsubscribe = this.on(async (event: T) => {\n if (filteredEvent.size > 0 && (await filter(event))) {\n await unsubscribe();\n await filteredEvent(event as P);\n }\n });\n const filteredEvent = new Event<P, R>(unsubscribe);\n return filteredEvent;\n }\n\n /**\n * Returns a Promise that resolves once an event occurs that meets the filter criteria.\n * This method is particularly useful for handling asynchronous flows where you need to wait for a specific condition.\n *\n * @param {Filter<T, P>} filter - The filter function or predicate.\n * @returns {Promise<P>} A Promise that resolves once the filter condition is met.\n * @example\n * const mouseEvent = new Event<{x: number, y: number}>();\n * const clickAtPosition = mouseEvent.firstAsync(pos => pos.x > 200 && pos.y > 200);\n * clickAtPosition.then(pos => console.log(`Clicked at (${pos.x}, ${pos.y})`));\n */\n firstAsync<P extends T>(predicate: Predicate<T, P>): Promise<P>;\n firstAsync<P extends T>(filter: FilterFunction<T>): Promise<P>;\n firstAsync<P extends T>(filter: Filter<T, P>): Promise<P> {\n return this.first<P>(filter).onceAsync();\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 * @example\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 * @param mapper A function that maps the values of this event to a new value.\n * @returns A new event that emits the mapped values.\n */\n map<M, MR = R>(mapper: Mapper<T, M>): Event<M, MR> {\n const unsubscribe = this.on(async (event) => {\n if (mappedEvent.size > 0) {\n const value = await mapper(event);\n await mappedEvent(value);\n }\n });\n const mappedEvent = new Event<M, MR>(unsubscribe);\n return mappedEvent;\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 * @example\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 * @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 */\n reduce<A, AR = R>(reducer: Reducer<T, A>, init: A): Event<A, AR> {\n let value = init;\n const unsubscribe = this.on(async (event) => {\n if (reducedEvent.size > 0) {\n value = await reducer(value, event);\n await reducedEvent(value);\n }\n });\n const reducedEvent = new Event<A, AR>(unsubscribe);\n return reducedEvent;\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 * @example\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 expand<ET, ER>(expander: Expander<T, ET[]>): Event<ET, ER> {\n const unsubscribe = this.on(async (event) => {\n if (expandedEvent.size > 0) {\n const values = await expander(event);\n for (const value of values) {\n await expandedEvent(value);\n }\n }\n });\n const expandedEvent = new Event<ET, ER>(unsubscribe);\n return expandedEvent;\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. This method is useful for synchronizing\n * events, where the emission of one event controls the timing of another.\n *\n * @example\n * const rightClickPositionEvent = mouseMoveEvent.orchestrate(mouseRightClickEvent);\n *\n * @example\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 * @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 An event that signals when the orchestrated event should emit.\n * @returns {Event<T, R>} An orchestrated event that emits values based on the conductor's trigger.\n *\n */\n orchestrate(conductor: Event<any, any>): 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 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 * @example\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 * @param {number} interval - The amount of time to wait (in milliseconds) before firing the debounced event.\n * @returns {ResultEvents<T, R, unknown>} An object containing two events: `value` for the debounced successful\n * outputs and `error` for catching errors during the debounce handling.\n */\n debounce(interval: number): ResultEvents<T, R, unknown> {\n let timer: ReturnType<typeof setTimeout>;\n const unsubscribe = this.on((event) => {\n clearTimeout(timer);\n timer = setTimeout(() => {\n value(event).catch(error);\n }, interval);\n });\n const value = new Event<T, R>(unsubscribe);\n const error = new Event<unknown, void>();\n return { value, error };\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 * @example\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.value.on((messages) => console.log('Batched Messages:', messages));\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 {ResultEvents<T[], R, unknown>} An object containing two events: `value` for the batched results\n * and `error` for errors that may occur during batching.\n */\n batch(interval: number, size?: number): ResultEvents<T[], R, unknown> {\n let timer: ReturnType<typeof setTimeout>;\n const batch: T[] = [];\n\n const emitBatch = () => {\n if (batch.length !== 0) {\n clearTimeout(timer);\n value(batch.splice(0)).catch(error);\n }\n };\n\n const unsubscribe = this.on((event) => {\n if (batch.length === 0) {\n timer = setTimeout(emitBatch, interval);\n }\n\n batch.push(event);\n if (size !== undefined && batch.length >= size) {\n emitBatch();\n }\n });\n const value = new Event<T[], R>(unsubscribe);\n const error = new Event<unknown, void>();\n return { value, error };\n }\n\n /**\n * Transforms an event into an AsyncIterable that yields values as they are emitted by the event. This allows for the consumption\n * of event data using async iteration mechanisms. The iterator generated will yield all emitted values until the event\n * signals it should no longer be active.\n *\n * @returns {AsyncIterable<T>} An async iterable that yields values emitted by the event.\n * @example\n * // Assuming an event that emits numbers\n * const numberEvent = new Event<number>();\n * const numberIterable = numberEvent.generator();\n * (async () => {\n * for await (const num of numberIterable) {\n * console.log('Number:', num);\n * }\n * })();\n * await numberEvent(1);\n * await numberEvent(2);\n * await numberEvent(3);\n */\n generator(): AsyncIterable<T> {\n const queue: T[] = [];\n const valueEvent = new Event<boolean>();\n const emitEvent = async (value: T) => {\n queue.push(value);\n await valueEvent(false);\n };\n const unsubscribe = this.on(emitEvent).pre(() => {\n removeListener(this.removeSpies, spy);\n });\n\n const spy: (typeof this.removeSpies)[number] = (target = emitEvent) => {\n if (target === emitEvent) {\n valueEvent(true);\n unsubscribe();\n }\n };\n this.removeSpies.push(spy);\n\n return {\n [Symbol.asyncIterator]() {\n return {\n async next() {\n if (queue.length) {\n return Promise.resolve({ value: queue.shift()!, done: false });\n }\n const result = await valueEvent.onceAsync();\n if (!result) {\n return Promise.resolve({ value: queue.shift()!, done: false });\n }\n return Promise.resolve({ value: undefined, done: true });\n },\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 * @example\n * // Queueing tasks for sequential execution\n * const taskEvent = new Event<string>();\n * const taskQueue = taskEvent.queue();\n * await taskEvent('Task 1');\n * await taskEvent('Task 2');\n * (async () => {\n * console.log('Processing:', await taskQueue.pop()); // Processing: Task 1\n * console.log('Processing:', await taskQueue.pop()); // Processing: Task 2\n * })();\n */\n queue(): Queue<T> {\n const queue: T[] = [];\n const valueEvent = new Event<void>();\n const unsubscribe = this.on(async (value) => {\n queue.push(value);\n await valueEvent();\n });\n\n return {\n async pop() {\n if (!queue.length) {\n await valueEvent.onceAsync();\n }\n return queue.shift();\n },\n async stop() {\n await unsubscribe();\n },\n };\n }\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 * @example\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 */\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 * @example\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 */\nexport const createInterval = <R = void>(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 * @example\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 */\nexport const createEvent = <T, R = void>(): 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":["removeListener","listeners","listener","index","indexOf","wasRemoved","splice","FunctionExt","Function","constructor","func","Object","setPrototypeOf","prototype","Unsubscribe","callback","pre","post","countdown","count","Event","addSpies","removeSpies","dispose","value","Promise","all","map","clear","size","length","lacks","has","off","forEach","spy","on","push","once","oneTimeListener","event","onceAsync","resolve","filter","unsubscribe","filteredEvent","first","firstAsync","mapper","mappedEvent","reduce","reducer","init","reducedEvent","expand","expander","expandedEvent","values","orchestrate","conductor","initialized","lastValue","unsubscribeConductor","orchestratedEvent","debounce","interval","timer","clearTimeout","setTimeout","catch","error","batch","emitBatch","undefined","generator","queue","valueEvent","emitEvent","target","Symbol","asyncIterator","next","shift","done","result","pop","stop","merge","events","mergedEvent","createInterval","counter","intervalEvent","clearInterval","timerId","setInterval","createEvent"],"mappings":"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"}
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "evnty",
3
3
  "description": "0-Deps, simple, fast, for browser and node js reactive anonymous event library",
4
- "version": "3.0.31",
4
+ "version": "3.0.33",
5
5
  "type": "module",
6
6
  "types": "build/index.d.ts",
7
7
  "main": "build/index.cjs",
@@ -60,24 +60,24 @@
60
60
  },
61
61
  "homepage": "https://github.com/3axap4eHko/evnty#readme",
62
62
  "devDependencies": {
63
- "@vuepress/bundler-vite": "2.0.0-rc.13",
64
- "@vuepress/theme-default": "2.0.0-rc.35",
65
- "vue": "^3.4.29",
66
- "vuepress": "2.0.0-rc.13",
63
+ "@vuepress/bundler-vite": "2.0.0-rc.14",
64
+ "@vuepress/theme-default": "2.0.0-rc.37",
65
+ "vue": "^3.4.30",
66
+ "vuepress": "2.0.0-rc.14",
67
67
  "@swc/jest": "^0.2.36",
68
68
  "@types/jest": "^29.5.12",
69
- "@types/node": "^20.14.2",
70
- "@typescript-eslint/eslint-plugin": "^7.13.0",
71
- "@typescript-eslint/parser": "^7.13.0",
69
+ "@types/node": "^20.14.8",
70
+ "@typescript-eslint/eslint-plugin": "^7.14.1",
71
+ "@typescript-eslint/parser": "^7.14.1",
72
72
  "eslint": "^8.57.0",
73
73
  "eslint-config-airbnb-base": "^15.0.0",
74
74
  "eslint-config-prettier": "^9.1.0",
75
75
  "eslint-plugin-import": "^2.29.1",
76
76
  "eslint-plugin-prettier": "^5.1.3",
77
77
  "husky": "^9.0.11",
78
- "inop": "^0.6.21",
78
+ "inop": "^0.7.0",
79
79
  "jest": "^29.7.0",
80
80
  "prettier": "^3.3.2",
81
- "typescript": "^5.4.5"
81
+ "typescript": "^5.5.2"
82
82
  }
83
83
  }