"use strict"; var __defProp = Object.defineProperty; var __getOwnPropDesc = Object.getOwnPropertyDescriptor; var __getOwnPropNames = Object.getOwnPropertyNames; var __hasOwnProp = Object.prototype.hasOwnProperty; var __export = (target, all) => { for (var name in all) __defProp(target, name, { get: all[name], enumerable: true }); }; var __copyProps = (to, from, except, desc) => { if (from && typeof from === "object" || typeof from === "function") { for (let key of __getOwnPropNames(from)) if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); } return to; }; var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); // src/index.ts var src_exports = {}; __export(src_exports, { Eventified: () => Eventified, Hookified: () => Hookified }); module.exports = __toCommonJS(src_exports); // src/eventified.ts var Eventified = class { _eventListeners; _maxListeners; constructor() { this._eventListeners = /* @__PURE__ */ new Map(); this._maxListeners = 100; } /** * Adds a handler function for a specific event that will run only once * @param {string | symbol} eventName * @param {EventListener} listener * @returns {IEventEmitter} returns the instance of the class for chaining */ once(eventName, listener) { const onceListener = (...arguments_) => { this.off(eventName, onceListener); listener(...arguments_); }; this.on(eventName, onceListener); return this; } /** * Gets the number of listeners for a specific event. If no event is provided, it returns the total number of listeners * @param {string} eventName The event name. Not required * @returns {number} The number of listeners */ listenerCount(eventName) { if (!eventName) { return this.getAllListeners().length; } const listeners = this._eventListeners.get(eventName); return listeners ? listeners.length : 0; } /** * Gets an array of event names * @returns {Array} An array of event names */ eventNames() { return Array.from(this._eventListeners.keys()); } /** * Gets an array of listeners for a specific event. If no event is provided, it returns all listeners * @param {string} [event] (Optional) The event name * @returns {EventListener[]} An array of listeners */ rawListeners(event) { if (!event) { return this.getAllListeners(); } return this._eventListeners.get(event) ?? []; } /** * Prepends a listener to the beginning of the listeners array for the specified event * @param {string | symbol} eventName * @param {EventListener} listener * @returns {IEventEmitter} returns the instance of the class for chaining */ prependListener(eventName, listener) { const listeners = this._eventListeners.get(eventName) ?? []; listeners.unshift(listener); this._eventListeners.set(eventName, listeners); return this; } /** * Prepends a one-time listener to the beginning of the listeners array for the specified event * @param {string | symbol} eventName * @param {EventListener} listener * @returns {IEventEmitter} returns the instance of the class for chaining */ prependOnceListener(eventName, listener) { const onceListener = (...arguments_) => { this.off(eventName, onceListener); listener(...arguments_); }; this.prependListener(eventName, onceListener); return this; } /** * Gets the maximum number of listeners that can be added for a single event * @returns {number} The maximum number of listeners */ maxListeners() { return this._maxListeners; } /** * Adds a listener for a specific event. It is an alias for the on() method * @param {string | symbol} event * @param {EventListener} listener * @returns {IEventEmitter} returns the instance of the class for chaining */ addListener(event, listener) { this.on(event, listener); return this; } /** * Adds a listener for a specific event * @param {string | symbol} event * @param {EventListener} listener * @returns {IEventEmitter} returns the instance of the class for chaining */ on(event, listener) { if (!this._eventListeners.has(event)) { this._eventListeners.set(event, []); } const listeners = this._eventListeners.get(event); if (listeners) { if (listeners.length >= this._maxListeners) { console.warn(`MaxListenersExceededWarning: Possible event memory leak detected. ${listeners.length + 1} ${event} listeners added. Use setMaxListeners() to increase limit.`); } listeners.push(listener); } return this; } /** * Removes a listener for a specific event. It is an alias for the off() method * @param {string | symbol} event * @param {EventListener} listener * @returns {IEventEmitter} returns the instance of the class for chaining */ removeListener(event, listener) { this.off(event, listener); return this; } /** * Removes a listener for a specific event * @param {string | symbol} event * @param {EventListener} listener * @returns {IEventEmitter} returns the instance of the class for chaining */ off(event, listener) { const listeners = this._eventListeners.get(event) ?? []; const index = listeners.indexOf(listener); if (index > -1) { listeners.splice(index, 1); } if (listeners.length === 0) { this._eventListeners.delete(event); } return this; } /** * Calls all listeners for a specific event * @param {string | symbol} event * @param arguments_ The arguments to pass to the listeners * @returns {boolean} Returns true if the event had listeners, false otherwise */ emit(event, ...arguments_) { let result = false; const listeners = this._eventListeners.get(event); if (listeners && listeners.length > 0) { for (const listener of listeners) { listener(...arguments_); result = true; } } return result; } /** * Gets all listeners for a specific event. If no event is provided, it returns all listeners * @param {string} [event] (Optional) The event name * @returns {EventListener[]} An array of listeners */ listeners(event) { return this._eventListeners.get(event) ?? []; } /** * Removes all listeners for a specific event. If no event is provided, it removes all listeners * @param {string} [event] (Optional) The event name * @returns {IEventEmitter} returns the instance of the class for chaining */ removeAllListeners(event) { if (event) { this._eventListeners.delete(event); } else { this._eventListeners.clear(); } return this; } /** * Sets the maximum number of listeners that can be added for a single event * @param {number} n The maximum number of listeners * @returns {void} */ setMaxListeners(n) { this._maxListeners = n; for (const listeners of this._eventListeners.values()) { if (listeners.length > n) { listeners.splice(n); } } } /** * Gets all listeners * @returns {EventListener[]} An array of listeners */ getAllListeners() { let result = new Array(); for (const listeners of this._eventListeners.values()) { result = result.concat(listeners); } return result; } }; // src/index.ts var Hookified = class extends Eventified { _hooks; constructor() { super(); this._hooks = /* @__PURE__ */ new Map(); } /** * Adds a handler function for a specific event * @param {string} event * @param {Hook} handler - this can be async or sync * @returns {void} */ onHook(event, handler) { const eventHandlers = this._hooks.get(event); if (eventHandlers) { eventHandlers.push(handler); } else { this._hooks.set(event, [handler]); } } /** * Adds a handler that only executes once for a specific event * @param event * @param handler */ onceHook(event, handler) { const hook = async (...arguments_) => { this.removeHook(event, hook); return handler(...arguments_); }; this.onHook(event, hook); } /** * Removes a handler function for a specific event * @param {string} event * @param {Hook} handler * @returns {void} */ removeHook(event, handler) { const eventHandlers = this._hooks.get(event); if (eventHandlers) { const index = eventHandlers.indexOf(handler); if (index !== -1) { eventHandlers.splice(index, 1); } } } /** * Calls all handlers for a specific event * @param {string} event * @param {T[]} arguments_ * @returns {Promise} */ async hook(event, ...arguments_) { const eventHandlers = this._hooks.get(event); if (eventHandlers) { for (const handler of eventHandlers) { try { await handler(...arguments_); } catch (error) { this.emit("error", new Error(`Error in hook handler for event "${event}": ${error.message}`)); } } } } /** * Gets all hooks * @returns {Map} */ get hooks() { return this._hooks; } /** * Gets all hooks for a specific event * @param {string} event * @returns {Hook[]} */ getHooks(event) { return this._hooks.get(event); } /** * Removes all hooks * @returns {void} */ clearHooks() { this._hooks.clear(); } }; // Annotate the CommonJS export names for ESM import in node: 0 && (module.exports = { Eventified, Hookified });