UNPKG

rich-domain

Version:

This package provide utils file and interfaces to assistant build a complex application with domain driving design

115 lines 5.47 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); const events_1 = require("events"); const validate_context_event_name_util_1 = require("../utils/validate-context-event-name.util"); /** * @class ServerEventManager * @description A singleton class to manage server-side events. This class ensures that event listeners are properly managed and provides utilities for subscribing, dispatching, and removing events. * @implements {EventManager} */ class ServerEventManager { events; // Stores the list of registered events and their handlers. static _instance; // Singleton instance of the ServerEventManager. emitter; // Node.js EventEmitter instance for event handling. /** * @private * @constructor * @throws {Error} If the runtime environment does not support EventEmitter or Node.js process. */ constructor() { this.events = []; if (typeof global?.process === 'undefined' || typeof events_1.EventEmitter === 'undefined') { throw new Error('ServerEventManager is not supported'); } this.emitter = new events_1.EventEmitter({ captureRejections: true }); // Enable rejection capture for promise-based event handlers. } /** * @static * @method instance * @description Returns the singleton instance of the ServerEventManager. If it doesn't exist, it initializes a new instance. * @returns {ServerEventManager} The singleton instance. */ static instance() { if (ServerEventManager._instance) return ServerEventManager._instance; ServerEventManager._instance = new ServerEventManager(); return ServerEventManager._instance; } /** * @private * @method getEvent * @description Retrieves the event handler associated with a given event name. * @param {string} eventName The name of the event. * @returns {EventType | null} The event type if found, otherwise null. */ getEvent(eventName) { const event = this.events.find((event) => event.eventName === eventName); return event || null; } /** * @method subscribe * @description Subscribes a callback function to a specific event. If the event already exists, it won't be added again. * @param {string} eventName The name of the event. * @param {(event: Event) => void | Promise<void>} fn The callback function to handle the event. * @throws {Error} If the event name does not follow the context:event pattern. */ subscribe(eventName, fn) { (0, validate_context_event_name_util_1.default)(eventName); // Validate event name format. if (this.exists(eventName)) return; // Avoid duplicate subscriptions. this.events.push({ eventName, callback: fn }); // Register the event. this.emitter.addListener(eventName, fn); // Add the listener to the EventEmitter. } /** * @method exists * @description Checks if an event with the given name is already registered. * @param {string} eventName The name of the event to check. * @returns {boolean} True if the event exists, false otherwise. */ exists(eventName) { const count = this.emitter.listenerCount(eventName); // Check if there are listeners for the event. const hasListener = count > 0; const hasLocal = !!this.events.find((evt) => evt.eventName === eventName); // Check if it exists in the local list. return hasListener || hasLocal; } /** * @method removerEvent * @description Removes an event and its associated callback from the manager and EventEmitter. * @param {string} eventName The name of the event to remove. * @returns {boolean} True if the event was successfully removed, false otherwise. */ removerEvent(eventName) { const event = this.getEvent(eventName); if (!event) return false; // Event not found. this.events = this.events.filter((event) => event.eventName !== eventName); // Remove from local list. this.emitter.removeListener(eventName, event.callback); // Remove the listener from EventEmitter. return true; } /** * @method dispatchEvent * @description Dispatches an event, optionally supporting wildcard patterns to emit multiple events. * @param {string} eventName The name of the event to dispatch. Supports wildcard patterns using `*`. * @param {...any[]} args Arguments to pass to the event handler. */ dispatchEvent(eventName, ...args) { (0, validate_context_event_name_util_1.default)(eventName); // Validate event name format. if (eventName.includes('*')) { // Handle wildcard patterns in event names. const regex = new RegExp(eventName.replace('*', '.*')); let i = 0; while (this.events[i]) { const localEventName = this.events[i].eventName; const match = regex.test(localEventName); // Match event names using regex. if (match) { this.emitter.emit(localEventName, { detail: args || [] }); // Emit matching events. } i++; } return; } this.emitter.emit(eventName, { detail: args || [] }); // Emit the event directly if no wildcard. } } exports.default = ServerEventManager; //# sourceMappingURL=server-event-manager.js.map