@hirosystems/api-toolkit
Version:
API development toolkit
53 lines (52 loc) • 1.98 kB
TypeScript
import { EventEmitter } from 'node:events';
/**
* Creates a Promise that resolves when the specified `eventName` is emitted by the `EventEmitter`
* and the provided predicate returns `true` for the emitted arguments.
*
* Similar to [`events.once`](https://nodejs.org/api/events.html#eventsonceemitter-name-options),
* but includes support for a predicate function to filter events. Only events for which
* the predicate returns `true` will cause the Promise to resolve.
*
* The resolved value is an array of the arguments emitted with the event.
*
* Supports typed `EventEmitter`s and optional cancellation via `AbortSignal`.
*
* @example
* ```ts
* import { EventEmitter } from 'node:events';
*
* const emitter = new EventEmitter<{
* myEvent: [id: number, msg: string];
* }>();
*
* setTimeout(() => {
* for (let i = 0; i <= 5; i++) {
* emitter.emit('myEvent', i, `Message ${i}`);
* }
* }, 100);
*
* const [id, msg] = await onceWhen(emitter, 'myEvent', (id, msg) => id === 3);
*
* // outputs: "Received event with id: 3, message: Message 3"
* console.log(`Received event with id: ${id}, message: ${msg}`);
* ```
*
* @example
* ```ts
* import { EventEmitter } from 'node:events';
*
* const emitter = new EventEmitter<{ myEvent: [id: number, msg: string] }>();
*
* const signal = AbortSignal.timeout(10);
*
* setTimeout(() => emitter.emit('myEvent', 1, 'Hello'), 1000);
*
* const whenPromise = onceWhen(emitter, 'myEvent', id => id === 1, { signal });
*
* // This rejects because the signal is aborted before the event is emitted
* await expect(whenPromise).rejects.toThrow(signal.reason);
* ```
*/
export declare function onceWhen<EventMap extends Record<string, any[]> = Record<string, any[]>, K extends Extract<keyof EventMap, string> = Extract<keyof EventMap, string>>(emitter: EventEmitter<EventMap>, eventName: K, predicate: (...args: EventMap[K]) => boolean, options?: {
signal?: AbortSignal;
}): Promise<EventMap[K]>;