node-comfortv2.0.0

Emitter

A small typed event emitter. Declare your events once, and your editor checks every event name and listener argument. on() returns a function that removes the listener, and you can await an event or loop over events with for await.

const { Emitter } = require("@ix-xs/node-comfort");
import Emitter from "@ix-xs/node-comfort/emitter";
const chat = new nc.Emitter<{ message: [text: string, from: string]; close: [] }>();
const off = chat.on("message", (text, from) => console.log(`${from}: ${text}`));
chat.emit("message", "hello", "ada");
off();
const [text] = await chat.waitFor("message", { timeout: "5s" });
GuideExplanations and examples for Emitter.
Read the guide →

Constructor and methods

new Emitter()

new Emitter<Events extends EventMap = EventMap>(): Emitter<Events>

events.on()method

on<K extends keyof Events & string>(event: K, listener: (...args: Events[K]) => unknown): () => void

Listens to an event.

Parameters

NameType
eventK
listener(...args: Events[K]) => unknown

Returns () => void: Removes the listener.

Example

const off = emitter.on("data", (chunk) => chunks.push(chunk));
off(); // stop listening

events.once()method

once<K extends keyof Events & string>(event: K, listener: (...args: Events[K]) => unknown): () => void

Listens to an event once.

Parameters

NameType
eventK
listener(...args: Events[K]) => unknown

Returns () => void: Removes the listener if it hasn't run yet.

events.onAny()method

onAny(listener: (event: keyof Events & string, ...args: any[]) => unknown): () => void

Listens to every event; the listener gets the event name first. Handy for logging.

Parameters

NameType
listener(event: keyof Events & string, ...args: any[]) => unknown

Returns () => void: Removes the listener.

Example

emitter.onAny((event, ...args) => nc.debug(event, args));

events.off()method

off<K extends keyof Events & string>(event: K, listener?: ((...args: Events[K]) => unknown) | undefined): Emitter<Events>

Removes a listener, or all listeners of the event if you don't pass one.

Parameters

NameType
eventK
listeneroptional(...args: Events[K]) => unknown

Returns this

events.emit()method

emit<K extends keyof Events & string>(event: K, ...args: Events[K]): boolean

Calls the event's listeners right away, in the order they were added. If one throws, the error propagates, as with Node's EventEmitter.

Parameters

NameType
eventK
...argsEvents[K]

Returns boolean: true if anyone was listening.

Example

emitter.emit("message", "hello", "ada");

events.emitAsync()method

emitAsync<K extends keyof Events & string>(event: K, ...args: Events[K]): Promise<unknown[]>

Calls the listeners one at a time, waiting for each, and resolves with what they returned. Good for hooks that may be async.

Parameters

NameType
eventK
...argsEvents[K]

Returns Promise<unknown[]>

Example

await hooks.emitAsync("beforeSave", record);

events.waitFor()method

waitFor<K extends keyof Events & string>(event: K, options?: WaitForOptions<Events[K]>): Promise<Events[K]>

Waits for the next time the event fires and resolves with its arguments.

Parameters

NameType
eventK
optionsoptionalWaitForOptions<Events[K]>

Returns Promise<Events[K]>

Throws TimeoutError; AbortError

Example

const [code] = await child.waitFor("exit", { timeout: "30s" });
const [text] = await chat.waitFor("message", { filter: (text, from) => from === "ada" });

events.iterate()method

iterate<K extends keyof Events & string>(event: K, options?: { signal?: AbortSignal; } | undefined): AsyncIterableIterator<Events[K]>

Loops over an event with for await. Events that fire while your loop body runs are queued, and leaving the loop removes the listener.

Parameters

NameTypeDescription
eventK
optionsoptional{ signal?: AbortSignal }Ends the loop when aborted.

Returns AsyncIterableIterator<Events[K]>

Example

for await (const [job] of queue.iterate("job")) {
  await process(job);
}

events.listenerCount()method

listenerCount(event?: (keyof Events & string) | undefined): number

How many listeners an event has, or all events together. onAny listeners aren't counted.

Parameters

NameType
eventoptionalkeyof Events & string

Returns number

events.eventNames()method

eventNames(): (keyof Events & string)[]

The events that have listeners.

Returns Array<keyof Events & string>

events.clear()method

clear(event?: (keyof Events & string) | undefined): Emitter<Events>

Removes all listeners of an event, or everything if you don't name one.

Parameters

NameType
eventoptionalkeyof Events & string

Returns this

Types

Import any of them in TypeScript with import type { EventMap } from "@ix-xs/node-comfort", or in JavaScript with import("@ix-xs/node-comfort").EventMap.

EventMap

Event names mapped to their arguments, like { ready: [], data: [chunk: Buffer], error: [error: Error] }.

type EventMap = Record<string, any[]>

WaitForOptions

Options for waitFor().

PropertyTypeDescription
timeoutoptionalstring | numberReject with a TimeoutError after this long.
signaloptionalAbortSignalReject with an AbortError when aborted.
filteroptional((...args: A) => boolean)Only resolve for events that pass this test.
node-comfort v2.0.0View the source