@bacnet-js/device
Version:
A TypeScript library for implementing BACnet IP devices in Node.js.
88 lines • 2.95 kB
JavaScript
import { events as debug } from './debug.js';
/**
* Implements an event emitter, conceptually similar to Node.js' native
* EventEmitter, that supports asynchronous event handlers/listeners.
*
* This class provides a foundation for event-based communication between
* BACnet components. It allows objects to register listeners for specific events
* and trigger those events asynchronously.
*
* @typeParam T - An interface mapping event names to their argument arrays
*/
export class AsyncEventEmitter {
/**
* Internal mapping of event names to their registered listeners
* @private
*/
#callbacks;
/**
* Creates a new Evented instance with no registered listeners
*/
constructor() {
this.#callbacks = Object.create(null);
}
/**
* Adds a new listener for the specified event.
*
* @param event - The event name to subscribe to
* @param cb - The callback function to execute when the event is triggered
* @returns The callback function for chaining
*/
on(event, cb) {
let callbacks = this.#callbacks[event];
if (!callbacks) {
callbacks = (this.#callbacks[event] = []);
}
callbacks.push(cb);
return this;
}
/**
* Alias for `on`
*/
addListener(event, cb) {
this.on(event, cb);
}
/**
* Fires an event. All subscribed listeners will be called synchronously.
* Promises will be ignored.
*
* @param event - The event name to trigger
* @param args - The arguments to pass to each listener
* @internal
*/
___emit(event, ...args) {
const callbacks = this.#callbacks[event];
if (callbacks) {
for (let i = 0; i < callbacks.length; i += 1) {
callbacks[i].apply(this, args);
}
}
}
/**
* Fires an event. All subscribed listeners will be called in series.
* Promises will be awaited for before continuing to the next listener.
*
* @param rethrow - Whether to rethrow errors thrown by listeners or ignore them
* @param event - The event name to trigger
* @param args - The arguments to pass to each listener
* @returns A promise that resolves when all listeners have completed
* @internal
*/
async ___asyncEmitSeries(rethrow, event, ...args) {
const callbacks = this.#callbacks[event];
if (callbacks) {
for (let i = 0; i < callbacks.length; i += 1) {
try {
await callbacks[i].apply(this, args);
}
catch (err) {
debug('error while calling listener #%s for event %s: %s', i, event, err instanceof Error ? err.stack : String(err));
if (rethrow) {
throw err;
}
}
}
}
}
}
//# sourceMappingURL=events.js.map