class Emitter { #listeners; constructor() { this.#listeners = {}; } /** * Registers a callback function for the specified event. * * @param {string} event - The name of the event. * @param {Function} callback - The callback function to be executed when the event is triggered. */ on(event, callback) { if (!this.#listeners[event]) { this.#listeners[event] = []; } this.#listeners[event].push(callback); } /** * Removes an event listener callback for the specified event. * If no callback is provided, removes all callbacks for the event. * * @param {string} event - The name of the event. * @param {Function} [callback] - The callback function to be removed. */ off(event, callback = undefined) { if (typeof event != 'string') { throw new TypeError('event must be a string'); return; } if ( !Array.isArray(this.#listeners[event]) || this.#listeners[event].length === 0 ) { throw new TypeError( `listener for \`${event}\` is not an array or empty` ); } if (!callback) { this.#listeners[event] = undefined; return; } this.#listeners[event] = this.#listeners[event].filter( (listener) => listener !== callback ); } /** * Emits an event and invokes all registered listeners for that event. * * @param {string} event - The name of the event to emit. * @param {...any} args - The arguments to pass to the event listeners. */ emit(event, ...args) { if (!this.#listeners[event]) { return; } for (const callback of this.#listeners[event]) { callback(this, ...args); } } } export default Emitter;