hookified 1.5.1 → 1.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -123,6 +123,40 @@ if you are not using ESM modules, you can use the following:
123
123
 
124
124
  # API - Hooks
125
125
 
126
+ ## .throwHookErrors
127
+
128
+ If set to true, errors thrown in hooks will be thrown. If set to false, errors will be only emitted.
129
+
130
+ ```javascript
131
+ import { Hookified } from 'hookified';
132
+
133
+ class MyClass extends Hookified {
134
+ constructor() {
135
+ super({ throwHookErrors: true});
136
+ }
137
+ }
138
+
139
+ const myClass = new MyClass();
140
+
141
+ console.log(myClass.throwHookErrors); // true. because it is set in super
142
+
143
+ try {
144
+ myClass.onHook('error-event', async () => {
145
+ throw new Error('error');
146
+ });
147
+
148
+ await myClass.hook('error-event');
149
+ } catch (error) {
150
+ console.log(error.message); // error
151
+ }
152
+
153
+ myClass.throwHookErrors = false;
154
+ console.log(myClass.throwHookErrors); // false
155
+
156
+
157
+
158
+ ```
159
+
126
160
  ## .onHook(eventName, handler)
127
161
 
128
162
  Subscribe to a hook event.
@@ -182,6 +216,66 @@ myClass.myMethodWithHooks();
182
216
  console.log(myClass.hooks.length); // 0
183
217
  ```
184
218
 
219
+ ## .prependHook(eventName, handler)
220
+
221
+ Subscribe to a hook event before all other hooks.
222
+
223
+ ```javascript
224
+ import { Hookified } from 'hookified';
225
+
226
+ class MyClass extends Hookified {
227
+ constructor() {
228
+ super();
229
+ }
230
+
231
+ async myMethodWithHooks() Promise<any> {
232
+ let data = { some: 'data' };
233
+ // do something
234
+ await this.hook('before:myMethod2', data);
235
+
236
+ return data;
237
+ }
238
+ }
239
+
240
+ const myClass = new MyClass();
241
+ myClass.onHook('before:myMethod2', async (data) => {
242
+ data.some = 'new data';
243
+ });
244
+ myClass.preHook('before:myMethod2', async (data) => {
245
+ data.some = 'will run before new data';
246
+ });
247
+ ```
248
+
249
+ ## .prependOnceHook(eventName, handler)
250
+
251
+ Subscribe to a hook event before all other hooks. After it is used once it will be removed.
252
+
253
+ ```javascript
254
+ import { Hookified } from 'hookified';
255
+
256
+ class MyClass extends Hookified {
257
+ constructor() {
258
+ super();
259
+ }
260
+
261
+ async myMethodWithHooks() Promise<any> {
262
+ let data = { some: 'data' };
263
+ // do something
264
+ await this.hook('before:myMethod2', data);
265
+
266
+ return data;
267
+ }
268
+ }
269
+
270
+ const myClass = new MyClass();
271
+ myClass.onHook('before:myMethod2', async (data) => {
272
+ data.some = 'new data';
273
+ });
274
+ myClass.preHook('before:myMethod2', async (data) => {
275
+ data.some = 'will run before new data';
276
+ });
277
+ ```
278
+
185
279
  ## .removeHook(eventName)
186
280
 
187
281
  Unsubscribe from a hook event.
@@ -1,2 +1,2 @@
1
- "use strict";(()=>{var v=Object.defineProperty;var g=(i,e,t)=>e in i?v(i,e,{enumerable:!0,configurable:!0,writable:!0,value:t}):i[e]=t;var o=(i,e,t)=>g(i,typeof e!="symbol"?e+"":e,t);var l=class{constructor(){o(this,"_eventListeners");o(this,"_maxListeners");this._eventListeners=new Map,this._maxListeners=100}once(e,t){let s=(...n)=>{this.off(e,s),t(...n)};return this.on(e,s),this}listenerCount(e){if(!e)return this.getAllListeners().length;let t=this._eventListeners.get(e);return t?t.length:0}eventNames(){return Array.from(this._eventListeners.keys())}rawListeners(e){return e?this._eventListeners.get(e)??[]:this.getAllListeners()}prependListener(e,t){let s=this._eventListeners.get(e)??[];return s.unshift(t),this._eventListeners.set(e,s),this}prependOnceListener(e,t){let s=(...n)=>{this.off(e,s),t(...n)};return this.prependListener(e,s),this}maxListeners(){return this._maxListeners}addListener(e,t){return this.on(e,t),this}on(e,t){this._eventListeners.has(e)||this._eventListeners.set(e,[]);let s=this._eventListeners.get(e);return s&&(s.length>=this._maxListeners&&console.warn(`MaxListenersExceededWarning: Possible event memory leak detected. ${s.length+1} ${e} listeners added. Use setMaxListeners() to increase limit.`),s.push(t)),this}removeListener(e,t){return this.off(e,t),this}off(e,t){let s=this._eventListeners.get(e)??[],n=s.indexOf(t);return n>-1&&s.splice(n,1),s.length===0&&this._eventListeners.delete(e),this}emit(e,...t){let s=!1,n=this._eventListeners.get(e);if(n&&n.length>0)for(let r of n)r(...t),s=!0;return s}listeners(e){return this._eventListeners.get(e)??[]}removeAllListeners(e){return e?this._eventListeners.delete(e):this._eventListeners.clear(),this}setMaxListeners(e){this._maxListeners=e;for(let t of this._eventListeners.values())t.length>e&&t.splice(e)}getAllListeners(){let e=new Array;for(let t of this._eventListeners.values())e=e.concat(t);return e}};var m=class extends l{constructor(){super();o(this,"_hooks");this._hooks=new Map}onHook(t,s){let n=this._hooks.get(t);n?n.push(s):this._hooks.set(t,[s])}onceHook(t,s){let n=async(...r)=>(this.removeHook(t,n),s(...r));this.onHook(t,n)}removeHook(t,s){let n=this._hooks.get(t);if(n){let r=n.indexOf(s);r!==-1&&n.splice(r,1)}}async hook(t,...s){let n=this._hooks.get(t);if(n)for(let r of n)try{await r(...s)}catch(a){this.emit("error",new Error(`Error in hook handler for event "${t}": ${a.message}`))}}get hooks(){return this._hooks}getHooks(t){return this._hooks.get(t)}clearHooks(){this._hooks.clear()}};})();
1
+ "use strict";(()=>{var g=Object.defineProperty;var v=(i,t,e)=>t in i?g(i,t,{enumerable:!0,configurable:!0,writable:!0,value:e}):i[t]=e;var o=(i,t,e)=>v(i,typeof t!="symbol"?t+"":t,e);var l=class{constructor(){o(this,"_eventListeners");o(this,"_maxListeners");this._eventListeners=new Map,this._maxListeners=100}once(t,e){let s=(...r)=>{this.off(t,s),e(...r)};return this.on(t,s),this}listenerCount(t){if(!t)return this.getAllListeners().length;let e=this._eventListeners.get(t);return e?e.length:0}eventNames(){return Array.from(this._eventListeners.keys())}rawListeners(t){return t?this._eventListeners.get(t)??[]:this.getAllListeners()}prependListener(t,e){let s=this._eventListeners.get(t)??[];return s.unshift(e),this._eventListeners.set(t,s),this}prependOnceListener(t,e){let s=(...r)=>{this.off(t,s),e(...r)};return this.prependListener(t,s),this}maxListeners(){return this._maxListeners}addListener(t,e){return this.on(t,e),this}on(t,e){this._eventListeners.has(t)||this._eventListeners.set(t,[]);let s=this._eventListeners.get(t);return s&&(s.length>=this._maxListeners&&console.warn(`MaxListenersExceededWarning: Possible event memory leak detected. ${s.length+1} ${t} listeners added. Use setMaxListeners() to increase limit.`),s.push(e)),this}removeListener(t,e){return this.off(t,e),this}off(t,e){let s=this._eventListeners.get(t)??[],r=s.indexOf(e);return r!==-1&&s.splice(r,1),s.length===0&&this._eventListeners.delete(t),this}emit(t,...e){let s=!1,r=this._eventListeners.get(t);if(r&&r.length>0)for(let n of r)n(...e),s=!0;return s}listeners(t){return this._eventListeners.get(t)??[]}removeAllListeners(t){return t?this._eventListeners.delete(t):this._eventListeners.clear(),this}setMaxListeners(t){this._maxListeners=t;for(let e of this._eventListeners.values())e.length>t&&e.splice(t)}getAllListeners(){let t=new Array;for(let e of this._eventListeners.values())t=t.concat(e);return t}};var m=class extends l{constructor(e){super();o(this,"_hooks");o(this,"_throwHookErrors",!1);this._hooks=new Map,e?.throwHookErrors!==void 0&&(this._throwHookErrors=e.throwHookErrors)}get hooks(){return this._hooks}get throwHookErrors(){return this._throwHookErrors}set throwHookErrors(e){this._throwHookErrors=e}onHook(e,s){let r=this._hooks.get(e);r?r.push(s):this._hooks.set(e,[s])}prependHook(e,s){let r=this._hooks.get(e);r?r.unshift(s):this._hooks.set(e,[s])}prependOnceHook(e,s){let r=async(...n)=>(this.removeHook(e,r),s(...n));this.prependHook(e,r)}onceHook(e,s){let r=async(...n)=>(this.removeHook(e,r),s(...n));this.onHook(e,r)}removeHook(e,s){let r=this._hooks.get(e);if(r){let n=r.indexOf(s);n!==-1&&r.splice(n,1)}}async hook(e,...s){let r=this._hooks.get(e);if(r)for(let n of r)try{await n(...s)}catch(h){let a=`${e}: ${h.message}`;if(this.emit("error",new Error(a)),this._throwHookErrors)throw new Error(a)}}getHooks(e){return this._hooks.get(e)}clearHooks(){this._hooks.clear()}};})();
2
2
  //# sourceMappingURL=index.global.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/eventified.ts","../../src/index.ts"],"sourcesContent":["// eslint-disable-next-line @typescript-eslint/naming-convention\nexport type IEventEmitter = {\n\t/**\n\t * Registers a listener for the specified event.\n\t *\n\t * @param eventName - The name (or symbol) of the event to listen for.\n\t * @param listener - A callback function that will be invoked when the event is emitted.\n\t * @returns The current instance of EventEmitter for method chaining.\n\t *\n\t * @example\n\t * emitter.on('data', (message) => {\n\t * console.log(message);\n\t * });\n\t */\n\ton(eventName: string | symbol, listener: (...arguments_: any[]) => void): IEventEmitter;\n\n\t/**\n\t * Alias for `on`. Registers a listener for the specified event.\n\t *\n\t * @param eventName - The name (or symbol) of the event to listen for.\n\t * @param listener - A callback function that will be invoked when the event is emitted.\n\t * @returns The current instance of EventEmitter for method chaining.\n\t */\n\taddListener(eventName: string | symbol, listener: (...arguments_: any[]) => void): IEventEmitter;\n\n\t/**\n\t * Registers a one-time listener for the specified event. The listener is removed after it is called once.\n\t *\n\t * @param eventName - The name (or symbol) of the event to listen for.\n\t * @param listener - A callback function that will be invoked once when the event is emitted.\n\t * @returns The current instance of EventEmitter for method chaining.\n\t *\n\t * @example\n\t * emitter.once('close', () => {\n\t * console.log('The connection was closed.');\n\t * });\n\t */\n\tonce(eventName: string | symbol, listener: (...arguments_: any[]) => void): IEventEmitter;\n\n\t/**\n\t * Removes a previously registered listener for the specified event.\n\t *\n\t * @param eventName - The name (or symbol) of the event to stop listening for.\n\t * @param listener - The specific callback function to remove.\n\t * @returns The current instance of EventEmitter for method chaining.\n\t *\n\t * @example\n\t * emitter.off('data', myListener);\n\t */\n\toff(eventName: string | symbol, listener: (...arguments_: any[]) => void): IEventEmitter;\n\n\t/**\n\t * Alias for `off`. Removes a previously registered listener for the specified event.\n\t *\n\t * @param eventName - The name (or symbol) of the event to stop listening for.\n\t * @param listener - The specific callback function to remove.\n\t * @returns The current instance of EventEmitter for method chaining.\n\t */\n\tremoveListener(eventName: string | symbol, listener: (...arguments_: any[]) => void): IEventEmitter;\n\n\t/**\n\t * Emits the specified event, invoking all registered listeners with the provided arguments.\n\t *\n\t * @param eventName - The name (or symbol) of the event to emit.\n\t * @param args - Arguments passed to each listener.\n\t * @returns `true` if the event had listeners, `false` otherwise.\n\t *\n\t * @example\n\t * emitter.emit('data', 'Hello World');\n\t */\n\temit(eventName: string | symbol, ...arguments_: any[]): boolean;\n\n\t/**\n\t * Returns the number of listeners registered for the specified event.\n\t *\n\t * @param eventName - The name (or symbol) of the event.\n\t * @returns The number of registered listeners.\n\t *\n\t * @example\n\t * const count = emitter.listenerCount('data');\n\t * console.log(count); // e.g., 2\n\t */\n\tlistenerCount(eventName: string | symbol): number;\n\n\t/**\n\t * Removes all listeners for the specified event. If no event is specified, it removes all listeners for all events.\n\t *\n\t * @param eventName - (Optional) The name (or symbol) of the event.\n\t * @returns The current instance of EventEmitter for method chaining.\n\t *\n\t * @example\n\t * emitter.removeAllListeners('data');\n\t */\n\tremoveAllListeners(eventName?: string | symbol): IEventEmitter;\n\n\t/**\n\t * Returns an array of event names for which listeners have been registered.\n\t *\n\t * @returns An array of event names (or symbols).\n\t *\n\t * @example\n\t * const events = emitter.eventNames();\n\t * console.log(events); // e.g., ['data', 'close']\n\t */\n\teventNames(): Array<string | symbol>;\n\n\t/**\n\t * Returns an array of listeners registered for the specified event.\n\t *\n\t * @param eventName - The name (or symbol) of the event.\n\t * @returns An array of listener functions.\n\t *\n\t * @example\n\t * const listeners = emitter.listeners('data');\n\t * console.log(listeners.length); // e.g., 2\n\t */\n\tlisteners(eventName: string | symbol): Array<(...arguments_: any[]) => void>;\n\n\t/**\n\t * Returns an array of raw listeners for the specified event. This includes listeners wrapped by internal mechanisms (e.g., once-only listeners).\n\t *\n\t * @param eventName - The name (or symbol) of the event.\n\t * @returns An array of raw listener functions.\n\t *\n\t * @example\n\t * const rawListeners = emitter.rawListeners('data');\n\t */\n\trawListeners(eventName: string | symbol): Array<(...arguments_: any[]) => void>;\n\n\t/**\n\t * Adds a listener to the beginning of the listeners array for the specified event.\n\t *\n\t * @param eventName - The name (or symbol) of the event to listen for.\n\t * @param listener - A callback function that will be invoked when the event is emitted.\n\t * @returns The current instance of EventEmitter for method chaining.\n\t *\n\t * @example\n\t * emitter.prependListener('data', (message) => {\n\t * console.log('This will run first.');\n\t * });\n\t */\n\tprependListener(eventName: string | symbol, listener: (...arguments_: any[]) => void): IEventEmitter;\n\n\t/**\n\t * Adds a one-time listener to the beginning of the listeners array for the specified event.\n\t *\n\t * @param eventName - The name (or symbol) of the event to listen for.\n\t * @param listener - A callback function that will be invoked once when the event is emitted.\n\t * @returns The current instance of EventEmitter for method chaining.\n\t *\n\t * @example\n\t * emitter.prependOnceListener('data', (message) => {\n\t * console.log('This will run first and only once.');\n\t * });\n\t */\n\tprependOnceListener(eventName: string | symbol, listener: (...arguments_: any[]) => void): IEventEmitter;\n};\n\nexport type EventListener = (...arguments_: any[]) => void;\n\nexport class Eventified implements IEventEmitter {\n\t_eventListeners: Map<string | symbol, EventListener[]>;\n\t_maxListeners: number;\n\n\tconstructor() {\n\t\tthis._eventListeners = new Map<string | symbol, EventListener[]>();\n\t\tthis._maxListeners = 100; // Default maximum number of listeners\n\t}\n\n\t/**\n\t * Adds a handler function for a specific event that will run only once\n\t * @param {string | symbol} eventName\n\t * @param {EventListener} listener\n\t * @returns {IEventEmitter} returns the instance of the class for chaining\n\t */\n\tonce(eventName: string | symbol, listener: EventListener): IEventEmitter {\n\t\tconst onceListener: EventListener = (...arguments_: any[]) => {\n\t\t\tthis.off(eventName as string, onceListener);\n\t\t\t// eslint-disable-next-line @typescript-eslint/no-unsafe-argument\n\t\t\tlistener(...arguments_);\n\t\t};\n\n\t\tthis.on(eventName as string, onceListener);\n\t\treturn this;\n\t}\n\n\t/**\n\t * Gets the number of listeners for a specific event. If no event is provided, it returns the total number of listeners\n\t * @param {string} eventName The event name. Not required\n\t * @returns {number} The number of listeners\n\t */\n\tlistenerCount(eventName?: string | symbol): number {\n\t\tif (!eventName) {\n\t\t\treturn this.getAllListeners().length;\n\t\t}\n\n\t\tconst listeners = this._eventListeners.get(eventName as string);\n\t\treturn listeners ? listeners.length : 0;\n\t}\n\n\t/**\n\t * Gets an array of event names\n\t * @returns {Array<string | symbol>} An array of event names\n\t */\n\teventNames(): Array<string | symbol> {\n\t\treturn Array.from(this._eventListeners.keys());\n\t}\n\n\t/**\n\t * Gets an array of listeners for a specific event. If no event is provided, it returns all listeners\n\t * @param {string} [event] (Optional) The event name\n\t * @returns {EventListener[]} An array of listeners\n\t */\n\trawListeners(event?: string | symbol): EventListener[] {\n\t\tif (!event) {\n\t\t\treturn this.getAllListeners();\n\t\t}\n\n\t\treturn this._eventListeners.get(event) ?? [];\n\t}\n\n\t/**\n\t * Prepends a listener to the beginning of the listeners array for the specified event\n\t * @param {string | symbol} eventName\n\t * @param {EventListener} listener\n\t * @returns {IEventEmitter} returns the instance of the class for chaining\n\t */\n\tprependListener(eventName: string | symbol, listener: EventListener): IEventEmitter {\n\t\tconst listeners = this._eventListeners.get(eventName) ?? [];\n\t\tlisteners.unshift(listener);\n\t\tthis._eventListeners.set(eventName, listeners);\n\t\treturn this;\n\t}\n\n\t/**\n\t * Prepends a one-time listener to the beginning of the listeners array for the specified event\n\t * @param {string | symbol} eventName\n\t * @param {EventListener} listener\n\t * @returns {IEventEmitter} returns the instance of the class for chaining\n\t */\n\tprependOnceListener(eventName: string | symbol, listener: EventListener): IEventEmitter {\n\t\tconst onceListener: EventListener = (...arguments_: any[]) => {\n\t\t\tthis.off(eventName as string, onceListener);\n\t\t\t// eslint-disable-next-line @typescript-eslint/no-unsafe-argument\n\t\t\tlistener(...arguments_);\n\t\t};\n\n\t\tthis.prependListener(eventName as string, onceListener);\n\t\treturn this;\n\t}\n\n\t/**\n\t * Gets the maximum number of listeners that can be added for a single event\n\t * @returns {number} The maximum number of listeners\n\t */\n\tpublic maxListeners(): number {\n\t\treturn this._maxListeners;\n\t}\n\n\t/**\n\t * Adds a listener for a specific event. It is an alias for the on() method\n\t * @param {string | symbol} event\n\t * @param {EventListener} listener\n\t * @returns {IEventEmitter} returns the instance of the class for chaining\n\t */\n\tpublic addListener(event: string | symbol, listener: EventListener): IEventEmitter {\n\t\tthis.on(event, listener);\n\t\treturn this;\n\t}\n\n\t/**\n\t * Adds a listener for a specific event\n\t * @param {string | symbol} event\n\t * @param {EventListener} listener\n\t * @returns {IEventEmitter} returns the instance of the class for chaining\n\t */\n\tpublic on(event: string | symbol, listener: EventListener): IEventEmitter {\n\t\tif (!this._eventListeners.has(event)) {\n\t\t\tthis._eventListeners.set(event, []);\n\t\t}\n\n\t\tconst listeners = this._eventListeners.get(event);\n\n\t\tif (listeners) {\n\t\t\tif (listeners.length >= this._maxListeners) {\n\t\t\t\tconsole.warn(`MaxListenersExceededWarning: Possible event memory leak detected. ${listeners.length + 1} ${event as string} listeners added. Use setMaxListeners() to increase limit.`);\n\t\t\t}\n\n\t\t\tlisteners.push(listener);\n\t\t}\n\n\t\treturn this;\n\t}\n\n\t/**\n\t * Removes a listener for a specific event. It is an alias for the off() method\n\t * @param {string | symbol} event\n\t * @param {EventListener} listener\n\t * @returns {IEventEmitter} returns the instance of the class for chaining\n\t */\n\tpublic removeListener(event: string, listener: EventListener): IEventEmitter {\n\t\tthis.off(event, listener);\n\t\treturn this;\n\t}\n\n\t/**\n\t * Removes a listener for a specific event\n\t * @param {string | symbol} event\n\t * @param {EventListener} listener\n\t * @returns {IEventEmitter} returns the instance of the class for chaining\n\t */\n\tpublic off(event: string | symbol, listener: EventListener): IEventEmitter {\n\t\tconst listeners = this._eventListeners.get(event) ?? [];\n\t\tconst index = listeners.indexOf(listener);\n\t\tif (index > -1) {\n\t\t\tlisteners.splice(index, 1);\n\t\t}\n\n\t\tif (listeners.length === 0) {\n\t\t\tthis._eventListeners.delete(event);\n\t\t}\n\n\t\treturn this;\n\t}\n\n\t/**\n\t * Calls all listeners for a specific event\n\t * @param {string | symbol} event\n\t * @param arguments_ The arguments to pass to the listeners\n\t * @returns {boolean} Returns true if the event had listeners, false otherwise\n\t */\n\tpublic emit(event: string | symbol, ...arguments_: any[]): boolean {\n\t\tlet result = false;\n\t\tconst listeners = this._eventListeners.get(event);\n\n\t\tif (listeners && listeners.length > 0) {\n\t\t\tfor (const listener of listeners) {\n\t\t\t\t// eslint-disable-next-line @typescript-eslint/no-unsafe-argument\n\t\t\t\tlistener(...arguments_);\n\t\t\t\tresult = true;\n\t\t\t}\n\t\t}\n\n\t\treturn result;\n\t}\n\n\t/**\n\t * Gets all listeners for a specific event. If no event is provided, it returns all listeners\n\t * @param {string} [event] (Optional) The event name\n\t * @returns {EventListener[]} An array of listeners\n\t */\n\tpublic listeners(event: string): EventListener[] {\n\t\treturn this._eventListeners.get(event) ?? [];\n\t}\n\n\t/**\n\t * Removes all listeners for a specific event. If no event is provided, it removes all listeners\n\t * @param {string} [event] (Optional) The event name\n\t * @returns {IEventEmitter} returns the instance of the class for chaining\n\t */\n\tpublic removeAllListeners(event?: string): IEventEmitter {\n\t\tif (event) {\n\t\t\tthis._eventListeners.delete(event);\n\t\t} else {\n\t\t\tthis._eventListeners.clear();\n\t\t}\n\n\t\treturn this;\n\t}\n\n\t/**\n\t * Sets the maximum number of listeners that can be added for a single event\n\t * @param {number} n The maximum number of listeners\n\t * @returns {void}\n\t */\n\tpublic setMaxListeners(n: number): void {\n\t\tthis._maxListeners = n;\n\t\tfor (const listeners of this._eventListeners.values()) {\n\t\t\tif (listeners.length > n) {\n\t\t\t\tlisteners.splice(n);\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Gets all listeners\n\t * @returns {EventListener[]} An array of listeners\n\t */\n\tpublic getAllListeners(): EventListener[] {\n\t\tlet result = new Array<EventListener>();\n\t\tfor (const listeners of this._eventListeners.values()) {\n\t\t\tresult = result.concat(listeners);\n\t\t}\n\n\t\treturn result;\n\t}\n}\n","import {Eventified} from './eventified.js';\n\nexport type Hook = (...arguments_: any[]) => Promise<void> | void;\n\nexport class Hookified extends Eventified {\n\t_hooks: Map<string, Hook[]>;\n\n\tconstructor() {\n\t\tsuper();\n\t\tthis._hooks = new Map();\n\t}\n\n\t/**\n\t * Adds a handler function for a specific event\n\t * @param {string} event\n\t * @param {Hook} handler - this can be async or sync\n\t * @returns {void}\n\t */\n\tonHook(event: string, handler: Hook) {\n\t\tconst eventHandlers = this._hooks.get(event);\n\t\tif (eventHandlers) {\n\t\t\teventHandlers.push(handler);\n\t\t} else {\n\t\t\tthis._hooks.set(event, [handler]);\n\t\t}\n\t}\n\n\t/**\n\t * Adds a handler that only executes once for a specific event\n\t * @param event\n\t * @param handler\n\t */\n\tonceHook(event: string, handler: Hook) {\n\t\tconst hook = async (...arguments_: any[]) => {\n\t\t\tthis.removeHook(event, hook);\n\t\t\t// eslint-disable-next-line @typescript-eslint/no-unsafe-argument\n\t\t\treturn handler(...arguments_);\n\t\t};\n\n\t\tthis.onHook(event, hook);\n\t}\n\n\t/**\n\t * Removes a handler function for a specific event\n\t * @param {string} event\n\t * @param {Hook} handler\n\t * @returns {void}\n\t */\n\tremoveHook(event: string, handler: Hook) {\n\t\tconst eventHandlers = this._hooks.get(event);\n\t\tif (eventHandlers) {\n\t\t\tconst index = eventHandlers.indexOf(handler);\n\t\t\tif (index !== -1) {\n\t\t\t\teventHandlers.splice(index, 1);\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Calls all handlers for a specific event\n\t * @param {string} event\n\t * @param {T[]} arguments_\n\t * @returns {Promise<void>}\n\t */\n\tasync hook<T>(event: string, ...arguments_: T[]) {\n\t\tconst eventHandlers = this._hooks.get(event);\n\t\tif (eventHandlers) {\n\t\t\tfor (const handler of eventHandlers) {\n\t\t\t\ttry {\n\t\t\t\t\t// eslint-disable-next-line no-await-in-loop\n\t\t\t\t\tawait handler(...arguments_);\n\t\t\t\t} catch (error) {\n\t\t\t\t\tthis.emit('error', new Error(`Error in hook handler for event \"${event}\": ${(error as Error).message}`));\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Gets all hooks\n\t * @returns {Map<string, Hook[]>}\n\t */\n\tget hooks() {\n\t\treturn this._hooks;\n\t}\n\n\t/**\n\t * Gets all hooks for a specific event\n\t * @param {string} event\n\t * @returns {Hook[]}\n\t */\n\tgetHooks(event: string) {\n\t\treturn this._hooks.get(event);\n\t}\n\n\t/**\n\t * Removes all hooks\n\t * @returns {void}\n\t */\n\tclearHooks() {\n\t\tthis._hooks.clear();\n\t}\n}\n\nexport {Eventified, type EventListener} from './eventified.js';\n"],"mappings":"uLAgKO,IAAMA,EAAN,KAA0C,CAIhD,aAAc,CAHdC,EAAA,wBACAA,EAAA,sBAGC,KAAK,gBAAkB,IAAI,IAC3B,KAAK,cAAgB,GACtB,CAQA,KAAKC,EAA4BC,EAAwC,CACxE,IAAMC,EAA8B,IAAIC,IAAsB,CAC7D,KAAK,IAAIH,EAAqBE,CAAY,EAE1CD,EAAS,GAAGE,CAAU,CACvB,EAEA,YAAK,GAAGH,EAAqBE,CAAY,EAClC,IACR,CAOA,cAAcF,EAAqC,CAClD,GAAI,CAACA,EACJ,OAAO,KAAK,gBAAgB,EAAE,OAG/B,IAAMI,EAAY,KAAK,gBAAgB,IAAIJ,CAAmB,EAC9D,OAAOI,EAAYA,EAAU,OAAS,CACvC,CAMA,YAAqC,CACpC,OAAO,MAAM,KAAK,KAAK,gBAAgB,KAAK,CAAC,CAC9C,CAOA,aAAaC,EAA0C,CACtD,OAAKA,EAIE,KAAK,gBAAgB,IAAIA,CAAK,GAAK,CAAC,EAHnC,KAAK,gBAAgB,CAI9B,CAQA,gBAAgBL,EAA4BC,EAAwC,CACnF,IAAMG,EAAY,KAAK,gBAAgB,IAAIJ,CAAS,GAAK,CAAC,EAC1D,OAAAI,EAAU,QAAQH,CAAQ,EAC1B,KAAK,gBAAgB,IAAID,EAAWI,CAAS,EACtC,IACR,CAQA,oBAAoBJ,EAA4BC,EAAwC,CACvF,IAAMC,EAA8B,IAAIC,IAAsB,CAC7D,KAAK,IAAIH,EAAqBE,CAAY,EAE1CD,EAAS,GAAGE,CAAU,CACvB,EAEA,YAAK,gBAAgBH,EAAqBE,CAAY,EAC/C,IACR,CAMO,cAAuB,CAC7B,OAAO,KAAK,aACb,CAQO,YAAYG,EAAwBJ,EAAwC,CAClF,YAAK,GAAGI,EAAOJ,CAAQ,EAChB,IACR,CAQO,GAAGI,EAAwBJ,EAAwC,CACpE,KAAK,gBAAgB,IAAII,CAAK,GAClC,KAAK,gBAAgB,IAAIA,EAAO,CAAC,CAAC,EAGnC,IAAMD,EAAY,KAAK,gBAAgB,IAAIC,CAAK,EAEhD,OAAID,IACCA,EAAU,QAAU,KAAK,eAC5B,QAAQ,KAAK,qEAAqEA,EAAU,OAAS,CAAC,IAAIC,CAAe,4DAA4D,EAGtLD,EAAU,KAAKH,CAAQ,GAGjB,IACR,CAQO,eAAeI,EAAeJ,EAAwC,CAC5E,YAAK,IAAII,EAAOJ,CAAQ,EACjB,IACR,CAQO,IAAII,EAAwBJ,EAAwC,CAC1E,IAAMG,EAAY,KAAK,gBAAgB,IAAIC,CAAK,GAAK,CAAC,EAChDC,EAAQF,EAAU,QAAQH,CAAQ,EACxC,OAAIK,EAAQ,IACXF,EAAU,OAAOE,EAAO,CAAC,EAGtBF,EAAU,SAAW,GACxB,KAAK,gBAAgB,OAAOC,CAAK,EAG3B,IACR,CAQO,KAAKA,KAA2BF,EAA4B,CAClE,IAAII,EAAS,GACPH,EAAY,KAAK,gBAAgB,IAAIC,CAAK,EAEhD,GAAID,GAAaA,EAAU,OAAS,EACnC,QAAWH,KAAYG,EAEtBH,EAAS,GAAGE,CAAU,EACtBI,EAAS,GAIX,OAAOA,CACR,CAOO,UAAUF,EAAgC,CAChD,OAAO,KAAK,gBAAgB,IAAIA,CAAK,GAAK,CAAC,CAC5C,CAOO,mBAAmBA,EAA+B,CACxD,OAAIA,EACH,KAAK,gBAAgB,OAAOA,CAAK,EAEjC,KAAK,gBAAgB,MAAM,EAGrB,IACR,CAOO,gBAAgBG,EAAiB,CACvC,KAAK,cAAgBA,EACrB,QAAWJ,KAAa,KAAK,gBAAgB,OAAO,EAC/CA,EAAU,OAASI,GACtBJ,EAAU,OAAOI,CAAC,CAGrB,CAMO,iBAAmC,CACzC,IAAID,EAAS,IAAI,MACjB,QAAWH,KAAa,KAAK,gBAAgB,OAAO,EACnDG,EAASA,EAAO,OAAOH,CAAS,EAGjC,OAAOG,CACR,CACD,ECxYO,IAAME,EAAN,cAAwBC,CAAW,CAGzC,aAAc,CACb,MAAM,EAHPC,EAAA,eAIC,KAAK,OAAS,IAAI,GACnB,CAQA,OAAOC,EAAeC,EAAe,CACpC,IAAMC,EAAgB,KAAK,OAAO,IAAIF,CAAK,EACvCE,EACHA,EAAc,KAAKD,CAAO,EAE1B,KAAK,OAAO,IAAID,EAAO,CAACC,CAAO,CAAC,CAElC,CAOA,SAASD,EAAeC,EAAe,CACtC,IAAME,EAAO,SAAUC,KACtB,KAAK,WAAWJ,EAAOG,CAAI,EAEpBF,EAAQ,GAAGG,CAAU,GAG7B,KAAK,OAAOJ,EAAOG,CAAI,CACxB,CAQA,WAAWH,EAAeC,EAAe,CACxC,IAAMC,EAAgB,KAAK,OAAO,IAAIF,CAAK,EAC3C,GAAIE,EAAe,CAClB,IAAMG,EAAQH,EAAc,QAAQD,CAAO,EACvCI,IAAU,IACbH,EAAc,OAAOG,EAAO,CAAC,CAE/B,CACD,CAQA,MAAM,KAAQL,KAAkBI,EAAiB,CAChD,IAAMF,EAAgB,KAAK,OAAO,IAAIF,CAAK,EAC3C,GAAIE,EACH,QAAWD,KAAWC,EACrB,GAAI,CAEH,MAAMD,EAAQ,GAAGG,CAAU,CAC5B,OAASE,EAAO,CACf,KAAK,KAAK,QAAS,IAAI,MAAM,oCAAoCN,CAAK,MAAOM,EAAgB,OAAO,EAAE,CAAC,CACxG,CAGH,CAMA,IAAI,OAAQ,CACX,OAAO,KAAK,MACb,CAOA,SAASN,EAAe,CACvB,OAAO,KAAK,OAAO,IAAIA,CAAK,CAC7B,CAMA,YAAa,CACZ,KAAK,OAAO,MAAM,CACnB,CACD","names":["Eventified","__publicField","eventName","listener","onceListener","arguments_","listeners","event","index","result","n","Hookified","Eventified","__publicField","event","handler","eventHandlers","hook","arguments_","index","error"]}
1
+ {"version":3,"sources":["../../src/eventified.ts","../../src/index.ts"],"sourcesContent":["// eslint-disable-next-line @typescript-eslint/naming-convention\nexport type IEventEmitter = {\n\t/**\n\t * Registers a listener for the specified event.\n\t *\n\t * @param eventName - The name (or symbol) of the event to listen for.\n\t * @param listener - A callback function that will be invoked when the event is emitted.\n\t * @returns The current instance of EventEmitter for method chaining.\n\t *\n\t * @example\n\t * emitter.on('data', (message) => {\n\t * console.log(message);\n\t * });\n\t */\n\ton(eventName: string | symbol, listener: (...arguments_: any[]) => void): IEventEmitter;\n\n\t/**\n\t * Alias for `on`. Registers a listener for the specified event.\n\t *\n\t * @param eventName - The name (or symbol) of the event to listen for.\n\t * @param listener - A callback function that will be invoked when the event is emitted.\n\t * @returns The current instance of EventEmitter for method chaining.\n\t */\n\taddListener(eventName: string | symbol, listener: (...arguments_: any[]) => void): IEventEmitter;\n\n\t/**\n\t * Registers a one-time listener for the specified event. The listener is removed after it is called once.\n\t *\n\t * @param eventName - The name (or symbol) of the event to listen for.\n\t * @param listener - A callback function that will be invoked once when the event is emitted.\n\t * @returns The current instance of EventEmitter for method chaining.\n\t *\n\t * @example\n\t * emitter.once('close', () => {\n\t * console.log('The connection was closed.');\n\t * });\n\t */\n\tonce(eventName: string | symbol, listener: (...arguments_: any[]) => void): IEventEmitter;\n\n\t/**\n\t * Removes a previously registered listener for the specified event.\n\t *\n\t * @param eventName - The name (or symbol) of the event to stop listening for.\n\t * @param listener - The specific callback function to remove.\n\t * @returns The current instance of EventEmitter for method chaining.\n\t *\n\t * @example\n\t * emitter.off('data', myListener);\n\t */\n\toff(eventName: string | symbol, listener: (...arguments_: any[]) => void): IEventEmitter;\n\n\t/**\n\t * Alias for `off`. Removes a previously registered listener for the specified event.\n\t *\n\t * @param eventName - The name (or symbol) of the event to stop listening for.\n\t * @param listener - The specific callback function to remove.\n\t * @returns The current instance of EventEmitter for method chaining.\n\t */\n\tremoveListener(eventName: string | symbol, listener: (...arguments_: any[]) => void): IEventEmitter;\n\n\t/**\n\t * Emits the specified event, invoking all registered listeners with the provided arguments.\n\t *\n\t * @param eventName - The name (or symbol) of the event to emit.\n\t * @param args - Arguments passed to each listener.\n\t * @returns `true` if the event had listeners, `false` otherwise.\n\t *\n\t * @example\n\t * emitter.emit('data', 'Hello World');\n\t */\n\temit(eventName: string | symbol, ...arguments_: any[]): boolean;\n\n\t/**\n\t * Returns the number of listeners registered for the specified event.\n\t *\n\t * @param eventName - The name (or symbol) of the event.\n\t * @returns The number of registered listeners.\n\t *\n\t * @example\n\t * const count = emitter.listenerCount('data');\n\t * console.log(count); // e.g., 2\n\t */\n\tlistenerCount(eventName: string | symbol): number;\n\n\t/**\n\t * Removes all listeners for the specified event. If no event is specified, it removes all listeners for all events.\n\t *\n\t * @param eventName - (Optional) The name (or symbol) of the event.\n\t * @returns The current instance of EventEmitter for method chaining.\n\t *\n\t * @example\n\t * emitter.removeAllListeners('data');\n\t */\n\tremoveAllListeners(eventName?: string | symbol): IEventEmitter;\n\n\t/**\n\t * Returns an array of event names for which listeners have been registered.\n\t *\n\t * @returns An array of event names (or symbols).\n\t *\n\t * @example\n\t * const events = emitter.eventNames();\n\t * console.log(events); // e.g., ['data', 'close']\n\t */\n\teventNames(): Array<string | symbol>;\n\n\t/**\n\t * Returns an array of listeners registered for the specified event.\n\t *\n\t * @param eventName - The name (or symbol) of the event.\n\t * @returns An array of listener functions.\n\t *\n\t * @example\n\t * const listeners = emitter.listeners('data');\n\t * console.log(listeners.length); // e.g., 2\n\t */\n\tlisteners(eventName: string | symbol): Array<(...arguments_: any[]) => void>;\n\n\t/**\n\t * Returns an array of raw listeners for the specified event. This includes listeners wrapped by internal mechanisms (e.g., once-only listeners).\n\t *\n\t * @param eventName - The name (or symbol) of the event.\n\t * @returns An array of raw listener functions.\n\t *\n\t * @example\n\t * const rawListeners = emitter.rawListeners('data');\n\t */\n\trawListeners(eventName: string | symbol): Array<(...arguments_: any[]) => void>;\n\n\t/**\n\t * Adds a listener to the beginning of the listeners array for the specified event.\n\t *\n\t * @param eventName - The name (or symbol) of the event to listen for.\n\t * @param listener - A callback function that will be invoked when the event is emitted.\n\t * @returns The current instance of EventEmitter for method chaining.\n\t *\n\t * @example\n\t * emitter.prependListener('data', (message) => {\n\t * console.log('This will run first.');\n\t * });\n\t */\n\tprependListener(eventName: string | symbol, listener: (...arguments_: any[]) => void): IEventEmitter;\n\n\t/**\n\t * Adds a one-time listener to the beginning of the listeners array for the specified event.\n\t *\n\t * @param eventName - The name (or symbol) of the event to listen for.\n\t * @param listener - A callback function that will be invoked once when the event is emitted.\n\t * @returns The current instance of EventEmitter for method chaining.\n\t *\n\t * @example\n\t * emitter.prependOnceListener('data', (message) => {\n\t * console.log('This will run first and only once.');\n\t * });\n\t */\n\tprependOnceListener(eventName: string | symbol, listener: (...arguments_: any[]) => void): IEventEmitter;\n};\n\nexport type EventListener = (...arguments_: any[]) => void;\n\nexport class Eventified implements IEventEmitter {\n\t_eventListeners: Map<string | symbol, EventListener[]>;\n\t_maxListeners: number;\n\n\tconstructor() {\n\t\tthis._eventListeners = new Map<string | symbol, EventListener[]>();\n\t\tthis._maxListeners = 100; // Default maximum number of listeners\n\t}\n\n\t/**\n\t * Adds a handler function for a specific event that will run only once\n\t * @param {string | symbol} eventName\n\t * @param {EventListener} listener\n\t * @returns {IEventEmitter} returns the instance of the class for chaining\n\t */\n\tonce(eventName: string | symbol, listener: EventListener): IEventEmitter {\n\t\tconst onceListener: EventListener = (...arguments_: any[]) => {\n\t\t\tthis.off(eventName as string, onceListener);\n\t\t\t// eslint-disable-next-line @typescript-eslint/no-unsafe-argument\n\t\t\tlistener(...arguments_);\n\t\t};\n\n\t\tthis.on(eventName as string, onceListener);\n\t\treturn this;\n\t}\n\n\t/**\n\t * Gets the number of listeners for a specific event. If no event is provided, it returns the total number of listeners\n\t * @param {string} eventName The event name. Not required\n\t * @returns {number} The number of listeners\n\t */\n\tlistenerCount(eventName?: string | symbol): number {\n\t\tif (!eventName) {\n\t\t\treturn this.getAllListeners().length;\n\t\t}\n\n\t\tconst listeners = this._eventListeners.get(eventName as string);\n\t\treturn listeners ? listeners.length : 0;\n\t}\n\n\t/**\n\t * Gets an array of event names\n\t * @returns {Array<string | symbol>} An array of event names\n\t */\n\teventNames(): Array<string | symbol> {\n\t\treturn Array.from(this._eventListeners.keys());\n\t}\n\n\t/**\n\t * Gets an array of listeners for a specific event. If no event is provided, it returns all listeners\n\t * @param {string} [event] (Optional) The event name\n\t * @returns {EventListener[]} An array of listeners\n\t */\n\trawListeners(event?: string | symbol): EventListener[] {\n\t\tif (!event) {\n\t\t\treturn this.getAllListeners();\n\t\t}\n\n\t\treturn this._eventListeners.get(event) ?? [];\n\t}\n\n\t/**\n\t * Prepends a listener to the beginning of the listeners array for the specified event\n\t * @param {string | symbol} eventName\n\t * @param {EventListener} listener\n\t * @returns {IEventEmitter} returns the instance of the class for chaining\n\t */\n\tprependListener(eventName: string | symbol, listener: EventListener): IEventEmitter {\n\t\tconst listeners = this._eventListeners.get(eventName) ?? [];\n\t\tlisteners.unshift(listener);\n\t\tthis._eventListeners.set(eventName, listeners);\n\t\treturn this;\n\t}\n\n\t/**\n\t * Prepends a one-time listener to the beginning of the listeners array for the specified event\n\t * @param {string | symbol} eventName\n\t * @param {EventListener} listener\n\t * @returns {IEventEmitter} returns the instance of the class for chaining\n\t */\n\tprependOnceListener(eventName: string | symbol, listener: EventListener): IEventEmitter {\n\t\tconst onceListener: EventListener = (...arguments_: any[]) => {\n\t\t\tthis.off(eventName as string, onceListener);\n\t\t\t// eslint-disable-next-line @typescript-eslint/no-unsafe-argument\n\t\t\tlistener(...arguments_);\n\t\t};\n\n\t\tthis.prependListener(eventName as string, onceListener);\n\t\treturn this;\n\t}\n\n\t/**\n\t * Gets the maximum number of listeners that can be added for a single event\n\t * @returns {number} The maximum number of listeners\n\t */\n\tpublic maxListeners(): number {\n\t\treturn this._maxListeners;\n\t}\n\n\t/**\n\t * Adds a listener for a specific event. It is an alias for the on() method\n\t * @param {string | symbol} event\n\t * @param {EventListener} listener\n\t * @returns {IEventEmitter} returns the instance of the class for chaining\n\t */\n\tpublic addListener(event: string | symbol, listener: EventListener): IEventEmitter {\n\t\tthis.on(event, listener);\n\t\treturn this;\n\t}\n\n\t/**\n\t * Adds a listener for a specific event\n\t * @param {string | symbol} event\n\t * @param {EventListener} listener\n\t * @returns {IEventEmitter} returns the instance of the class for chaining\n\t */\n\tpublic on(event: string | symbol, listener: EventListener): IEventEmitter {\n\t\tif (!this._eventListeners.has(event)) {\n\t\t\tthis._eventListeners.set(event, []);\n\t\t}\n\n\t\tconst listeners = this._eventListeners.get(event);\n\n\t\tif (listeners) {\n\t\t\tif (listeners.length >= this._maxListeners) {\n\t\t\t\tconsole.warn(`MaxListenersExceededWarning: Possible event memory leak detected. ${listeners.length + 1} ${event as string} listeners added. Use setMaxListeners() to increase limit.`);\n\t\t\t}\n\n\t\t\tlisteners.push(listener);\n\t\t}\n\n\t\treturn this;\n\t}\n\n\t/**\n\t * Removes a listener for a specific event. It is an alias for the off() method\n\t * @param {string | symbol} event\n\t * @param {EventListener} listener\n\t * @returns {IEventEmitter} returns the instance of the class for chaining\n\t */\n\tpublic removeListener(event: string, listener: EventListener): IEventEmitter {\n\t\tthis.off(event, listener);\n\t\treturn this;\n\t}\n\n\t/**\n\t * Removes a listener for a specific event\n\t * @param {string | symbol} event\n\t * @param {EventListener} listener\n\t * @returns {IEventEmitter} returns the instance of the class for chaining\n\t */\n\tpublic off(event: string | symbol, listener: EventListener): IEventEmitter {\n\t\tconst listeners = this._eventListeners.get(event) ?? [];\n\t\tconst index = listeners.indexOf(listener);\n\t\tif (index !== -1) {\n\t\t\tlisteners.splice(index, 1);\n\t\t}\n\n\t\tif (listeners.length === 0) {\n\t\t\tthis._eventListeners.delete(event);\n\t\t}\n\n\t\treturn this;\n\t}\n\n\t/**\n\t * Calls all listeners for a specific event\n\t * @param {string | symbol} event\n\t * @param arguments_ The arguments to pass to the listeners\n\t * @returns {boolean} Returns true if the event had listeners, false otherwise\n\t */\n\tpublic emit(event: string | symbol, ...arguments_: any[]): boolean {\n\t\tlet result = false;\n\t\tconst listeners = this._eventListeners.get(event);\n\n\t\tif (listeners && listeners.length > 0) {\n\t\t\tfor (const listener of listeners) {\n\t\t\t\t// eslint-disable-next-line @typescript-eslint/no-unsafe-argument\n\t\t\t\tlistener(...arguments_);\n\t\t\t\tresult = true;\n\t\t\t}\n\t\t}\n\n\t\treturn result;\n\t}\n\n\t/**\n\t * Gets all listeners for a specific event. If no event is provided, it returns all listeners\n\t * @param {string} [event] (Optional) The event name\n\t * @returns {EventListener[]} An array of listeners\n\t */\n\tpublic listeners(event: string): EventListener[] {\n\t\treturn this._eventListeners.get(event) ?? [];\n\t}\n\n\t/**\n\t * Removes all listeners for a specific event. If no event is provided, it removes all listeners\n\t * @param {string} [event] (Optional) The event name\n\t * @returns {IEventEmitter} returns the instance of the class for chaining\n\t */\n\tpublic removeAllListeners(event?: string): IEventEmitter {\n\t\tif (event) {\n\t\t\tthis._eventListeners.delete(event);\n\t\t} else {\n\t\t\tthis._eventListeners.clear();\n\t\t}\n\n\t\treturn this;\n\t}\n\n\t/**\n\t * Sets the maximum number of listeners that can be added for a single event\n\t * @param {number} n The maximum number of listeners\n\t * @returns {void}\n\t */\n\tpublic setMaxListeners(n: number): void {\n\t\tthis._maxListeners = n;\n\t\tfor (const listeners of this._eventListeners.values()) {\n\t\t\tif (listeners.length > n) {\n\t\t\t\tlisteners.splice(n);\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Gets all listeners\n\t * @returns {EventListener[]} An array of listeners\n\t */\n\tpublic getAllListeners(): EventListener[] {\n\t\tlet result = new Array<EventListener>();\n\t\tfor (const listeners of this._eventListeners.values()) {\n\t\t\tresult = result.concat(listeners);\n\t\t}\n\n\t\treturn result;\n\t}\n}\n","import {Eventified} from './eventified.js';\n\nexport type Hook = (...arguments_: any[]) => Promise<void> | void;\n\nexport type HookifiedOptions = {\n\tthrowHookErrors?: boolean;\n};\n\nexport class Hookified extends Eventified {\n\t_hooks: Map<string, Hook[]>;\n\t_throwHookErrors = false;\n\n\tconstructor(options?: HookifiedOptions) {\n\t\tsuper();\n\t\tthis._hooks = new Map();\n\n\t\tif (options?.throwHookErrors !== undefined) {\n\t\t\tthis._throwHookErrors = options.throwHookErrors;\n\t\t}\n\t}\n\n\t/**\n\t * Gets all hooks\n\t * @returns {Map<string, Hook[]>}\n\t */\n\tget hooks() {\n\t\treturn this._hooks;\n\t}\n\n\t/**\n\t * Gets whether an error should be thrown when a hook throws an error. Default is false and only emits an error event.\n\t * @returns {boolean}\n\t */\n\tget throwHookErrors() {\n\t\treturn this._throwHookErrors;\n\t}\n\n\t/**\n\t * Sets whether an error should be thrown when a hook throws an error. Default is false and only emits an error event.\n\t * @param {boolean} value\n\t */\n\tset throwHookErrors(value) {\n\t\tthis._throwHookErrors = value;\n\t}\n\n\t/**\n\t * Adds a handler function for a specific event\n\t * @param {string} event\n\t * @param {Hook} handler - this can be async or sync\n\t * @returns {void}\n\t */\n\tonHook(event: string, handler: Hook) {\n\t\tconst eventHandlers = this._hooks.get(event);\n\t\tif (eventHandlers) {\n\t\t\teventHandlers.push(handler);\n\t\t} else {\n\t\t\tthis._hooks.set(event, [handler]);\n\t\t}\n\t}\n\n\t/**\n\t * Adds a handler function for a specific event that runs before all other handlers\n\t * @param {string} event\n\t * @param {Hook} handler - this can be async or sync\n\t * @returns {void}\n\t */\n\tprependHook(event: string, handler: Hook) {\n\t\tconst eventHandlers = this._hooks.get(event);\n\t\tif (eventHandlers) {\n\t\t\teventHandlers.unshift(handler);\n\t\t} else {\n\t\t\tthis._hooks.set(event, [handler]);\n\t\t}\n\t}\n\n\t/**\n\t * Adds a handler that only executes once for a specific event before all other handlers\n\t * @param event\n\t * @param handler\n\t */\n\tprependOnceHook(event: string, handler: Hook) {\n\t\tconst hook = async (...arguments_: any[]) => {\n\t\t\tthis.removeHook(event, hook);\n\t\t\t// eslint-disable-next-line @typescript-eslint/no-unsafe-argument\n\t\t\treturn handler(...arguments_);\n\t\t};\n\n\t\tthis.prependHook(event, hook);\n\t}\n\n\t/**\n\t * Adds a handler that only executes once for a specific event\n\t * @param event\n\t * @param handler\n\t */\n\tonceHook(event: string, handler: Hook) {\n\t\tconst hook = async (...arguments_: any[]) => {\n\t\t\tthis.removeHook(event, hook);\n\t\t\t// eslint-disable-next-line @typescript-eslint/no-unsafe-argument\n\t\t\treturn handler(...arguments_);\n\t\t};\n\n\t\tthis.onHook(event, hook);\n\t}\n\n\t/**\n\t * Removes a handler function for a specific event\n\t * @param {string} event\n\t * @param {Hook} handler\n\t * @returns {void}\n\t */\n\tremoveHook(event: string, handler: Hook) {\n\t\tconst eventHandlers = this._hooks.get(event);\n\t\tif (eventHandlers) {\n\t\t\tconst index = eventHandlers.indexOf(handler);\n\t\t\tif (index !== -1) {\n\t\t\t\teventHandlers.splice(index, 1);\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Calls all handlers for a specific event\n\t * @param {string} event\n\t * @param {T[]} arguments_\n\t * @returns {Promise<void>}\n\t */\n\tasync hook<T>(event: string, ...arguments_: T[]) {\n\t\tconst eventHandlers = this._hooks.get(event);\n\t\tif (eventHandlers) {\n\t\t\tfor (const handler of eventHandlers) {\n\t\t\t\ttry {\n\t\t\t\t\t// eslint-disable-next-line no-await-in-loop\n\t\t\t\t\tawait handler(...arguments_);\n\t\t\t\t} catch (error) {\n\t\t\t\t\tconst message = `${event}: ${(error as Error).message}`;\n\t\t\t\t\tthis.emit('error', new Error(message));\n\t\t\t\t\tif (this._throwHookErrors) {\n\t\t\t\t\t\tthrow new Error(message);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Gets all hooks for a specific event\n\t * @param {string} event\n\t * @returns {Hook[]}\n\t */\n\tgetHooks(event: string) {\n\t\treturn this._hooks.get(event);\n\t}\n\n\t/**\n\t * Removes all hooks\n\t * @returns {void}\n\t */\n\tclearHooks() {\n\t\tthis._hooks.clear();\n\t}\n}\n\nexport {Eventified, type EventListener} from './eventified.js';\n"],"mappings":"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","names":["Eventified","__publicField","eventName","listener","onceListener","arguments_","listeners","event","index","result","n","Hookified","Eventified","options","__publicField","value","event","handler","eventHandlers","hook","arguments_","index","error","message"]}
@@ -1,2 +1,2 @@
1
- var v=Object.defineProperty;var g=(i,e,t)=>e in i?v(i,e,{enumerable:!0,configurable:!0,writable:!0,value:t}):i[e]=t;var o=(i,e,t)=>g(i,typeof e!="symbol"?e+"":e,t);var l=class{constructor(){o(this,"_eventListeners");o(this,"_maxListeners");this._eventListeners=new Map,this._maxListeners=100}once(e,t){let s=(...n)=>{this.off(e,s),t(...n)};return this.on(e,s),this}listenerCount(e){if(!e)return this.getAllListeners().length;let t=this._eventListeners.get(e);return t?t.length:0}eventNames(){return Array.from(this._eventListeners.keys())}rawListeners(e){return e?this._eventListeners.get(e)??[]:this.getAllListeners()}prependListener(e,t){let s=this._eventListeners.get(e)??[];return s.unshift(t),this._eventListeners.set(e,s),this}prependOnceListener(e,t){let s=(...n)=>{this.off(e,s),t(...n)};return this.prependListener(e,s),this}maxListeners(){return this._maxListeners}addListener(e,t){return this.on(e,t),this}on(e,t){this._eventListeners.has(e)||this._eventListeners.set(e,[]);let s=this._eventListeners.get(e);return s&&(s.length>=this._maxListeners&&console.warn(`MaxListenersExceededWarning: Possible event memory leak detected. ${s.length+1} ${e} listeners added. Use setMaxListeners() to increase limit.`),s.push(t)),this}removeListener(e,t){return this.off(e,t),this}off(e,t){let s=this._eventListeners.get(e)??[],n=s.indexOf(t);return n>-1&&s.splice(n,1),s.length===0&&this._eventListeners.delete(e),this}emit(e,...t){let s=!1,n=this._eventListeners.get(e);if(n&&n.length>0)for(let r of n)r(...t),s=!0;return s}listeners(e){return this._eventListeners.get(e)??[]}removeAllListeners(e){return e?this._eventListeners.delete(e):this._eventListeners.clear(),this}setMaxListeners(e){this._maxListeners=e;for(let t of this._eventListeners.values())t.length>e&&t.splice(e)}getAllListeners(){let e=new Array;for(let t of this._eventListeners.values())e=e.concat(t);return e}};var m=class extends l{constructor(){super();o(this,"_hooks");this._hooks=new Map}onHook(t,s){let n=this._hooks.get(t);n?n.push(s):this._hooks.set(t,[s])}onceHook(t,s){let n=async(...r)=>(this.removeHook(t,n),s(...r));this.onHook(t,n)}removeHook(t,s){let n=this._hooks.get(t);if(n){let r=n.indexOf(s);r!==-1&&n.splice(r,1)}}async hook(t,...s){let n=this._hooks.get(t);if(n)for(let r of n)try{await r(...s)}catch(a){this.emit("error",new Error(`Error in hook handler for event "${t}": ${a.message}`))}}get hooks(){return this._hooks}getHooks(t){return this._hooks.get(t)}clearHooks(){this._hooks.clear()}};export{l as Eventified,m as Hookified};
1
+ var g=Object.defineProperty;var v=(i,t,e)=>t in i?g(i,t,{enumerable:!0,configurable:!0,writable:!0,value:e}):i[t]=e;var o=(i,t,e)=>v(i,typeof t!="symbol"?t+"":t,e);var l=class{constructor(){o(this,"_eventListeners");o(this,"_maxListeners");this._eventListeners=new Map,this._maxListeners=100}once(t,e){let s=(...r)=>{this.off(t,s),e(...r)};return this.on(t,s),this}listenerCount(t){if(!t)return this.getAllListeners().length;let e=this._eventListeners.get(t);return e?e.length:0}eventNames(){return Array.from(this._eventListeners.keys())}rawListeners(t){return t?this._eventListeners.get(t)??[]:this.getAllListeners()}prependListener(t,e){let s=this._eventListeners.get(t)??[];return s.unshift(e),this._eventListeners.set(t,s),this}prependOnceListener(t,e){let s=(...r)=>{this.off(t,s),e(...r)};return this.prependListener(t,s),this}maxListeners(){return this._maxListeners}addListener(t,e){return this.on(t,e),this}on(t,e){this._eventListeners.has(t)||this._eventListeners.set(t,[]);let s=this._eventListeners.get(t);return s&&(s.length>=this._maxListeners&&console.warn(`MaxListenersExceededWarning: Possible event memory leak detected. ${s.length+1} ${t} listeners added. Use setMaxListeners() to increase limit.`),s.push(e)),this}removeListener(t,e){return this.off(t,e),this}off(t,e){let s=this._eventListeners.get(t)??[],r=s.indexOf(e);return r!==-1&&s.splice(r,1),s.length===0&&this._eventListeners.delete(t),this}emit(t,...e){let s=!1,r=this._eventListeners.get(t);if(r&&r.length>0)for(let n of r)n(...e),s=!0;return s}listeners(t){return this._eventListeners.get(t)??[]}removeAllListeners(t){return t?this._eventListeners.delete(t):this._eventListeners.clear(),this}setMaxListeners(t){this._maxListeners=t;for(let e of this._eventListeners.values())e.length>t&&e.splice(t)}getAllListeners(){let t=new Array;for(let e of this._eventListeners.values())t=t.concat(e);return t}};var m=class extends l{constructor(e){super();o(this,"_hooks");o(this,"_throwHookErrors",!1);this._hooks=new Map,e?.throwHookErrors!==void 0&&(this._throwHookErrors=e.throwHookErrors)}get hooks(){return this._hooks}get throwHookErrors(){return this._throwHookErrors}set throwHookErrors(e){this._throwHookErrors=e}onHook(e,s){let r=this._hooks.get(e);r?r.push(s):this._hooks.set(e,[s])}prependHook(e,s){let r=this._hooks.get(e);r?r.unshift(s):this._hooks.set(e,[s])}prependOnceHook(e,s){let r=async(...n)=>(this.removeHook(e,r),s(...n));this.prependHook(e,r)}onceHook(e,s){let r=async(...n)=>(this.removeHook(e,r),s(...n));this.onHook(e,r)}removeHook(e,s){let r=this._hooks.get(e);if(r){let n=r.indexOf(s);n!==-1&&r.splice(n,1)}}async hook(e,...s){let r=this._hooks.get(e);if(r)for(let n of r)try{await n(...s)}catch(h){let a=`${e}: ${h.message}`;if(this.emit("error",new Error(a)),this._throwHookErrors)throw new Error(a)}}getHooks(e){return this._hooks.get(e)}clearHooks(){this._hooks.clear()}};export{l as Eventified,m as Hookified};
2
2
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/eventified.ts","../../src/index.ts"],"sourcesContent":["// eslint-disable-next-line @typescript-eslint/naming-convention\nexport type IEventEmitter = {\n\t/**\n\t * Registers a listener for the specified event.\n\t *\n\t * @param eventName - The name (or symbol) of the event to listen for.\n\t * @param listener - A callback function that will be invoked when the event is emitted.\n\t * @returns The current instance of EventEmitter for method chaining.\n\t *\n\t * @example\n\t * emitter.on('data', (message) => {\n\t * console.log(message);\n\t * });\n\t */\n\ton(eventName: string | symbol, listener: (...arguments_: any[]) => void): IEventEmitter;\n\n\t/**\n\t * Alias for `on`. Registers a listener for the specified event.\n\t *\n\t * @param eventName - The name (or symbol) of the event to listen for.\n\t * @param listener - A callback function that will be invoked when the event is emitted.\n\t * @returns The current instance of EventEmitter for method chaining.\n\t */\n\taddListener(eventName: string | symbol, listener: (...arguments_: any[]) => void): IEventEmitter;\n\n\t/**\n\t * Registers a one-time listener for the specified event. The listener is removed after it is called once.\n\t *\n\t * @param eventName - The name (or symbol) of the event to listen for.\n\t * @param listener - A callback function that will be invoked once when the event is emitted.\n\t * @returns The current instance of EventEmitter for method chaining.\n\t *\n\t * @example\n\t * emitter.once('close', () => {\n\t * console.log('The connection was closed.');\n\t * });\n\t */\n\tonce(eventName: string | symbol, listener: (...arguments_: any[]) => void): IEventEmitter;\n\n\t/**\n\t * Removes a previously registered listener for the specified event.\n\t *\n\t * @param eventName - The name (or symbol) of the event to stop listening for.\n\t * @param listener - The specific callback function to remove.\n\t * @returns The current instance of EventEmitter for method chaining.\n\t *\n\t * @example\n\t * emitter.off('data', myListener);\n\t */\n\toff(eventName: string | symbol, listener: (...arguments_: any[]) => void): IEventEmitter;\n\n\t/**\n\t * Alias for `off`. Removes a previously registered listener for the specified event.\n\t *\n\t * @param eventName - The name (or symbol) of the event to stop listening for.\n\t * @param listener - The specific callback function to remove.\n\t * @returns The current instance of EventEmitter for method chaining.\n\t */\n\tremoveListener(eventName: string | symbol, listener: (...arguments_: any[]) => void): IEventEmitter;\n\n\t/**\n\t * Emits the specified event, invoking all registered listeners with the provided arguments.\n\t *\n\t * @param eventName - The name (or symbol) of the event to emit.\n\t * @param args - Arguments passed to each listener.\n\t * @returns `true` if the event had listeners, `false` otherwise.\n\t *\n\t * @example\n\t * emitter.emit('data', 'Hello World');\n\t */\n\temit(eventName: string | symbol, ...arguments_: any[]): boolean;\n\n\t/**\n\t * Returns the number of listeners registered for the specified event.\n\t *\n\t * @param eventName - The name (or symbol) of the event.\n\t * @returns The number of registered listeners.\n\t *\n\t * @example\n\t * const count = emitter.listenerCount('data');\n\t * console.log(count); // e.g., 2\n\t */\n\tlistenerCount(eventName: string | symbol): number;\n\n\t/**\n\t * Removes all listeners for the specified event. If no event is specified, it removes all listeners for all events.\n\t *\n\t * @param eventName - (Optional) The name (or symbol) of the event.\n\t * @returns The current instance of EventEmitter for method chaining.\n\t *\n\t * @example\n\t * emitter.removeAllListeners('data');\n\t */\n\tremoveAllListeners(eventName?: string | symbol): IEventEmitter;\n\n\t/**\n\t * Returns an array of event names for which listeners have been registered.\n\t *\n\t * @returns An array of event names (or symbols).\n\t *\n\t * @example\n\t * const events = emitter.eventNames();\n\t * console.log(events); // e.g., ['data', 'close']\n\t */\n\teventNames(): Array<string | symbol>;\n\n\t/**\n\t * Returns an array of listeners registered for the specified event.\n\t *\n\t * @param eventName - The name (or symbol) of the event.\n\t * @returns An array of listener functions.\n\t *\n\t * @example\n\t * const listeners = emitter.listeners('data');\n\t * console.log(listeners.length); // e.g., 2\n\t */\n\tlisteners(eventName: string | symbol): Array<(...arguments_: any[]) => void>;\n\n\t/**\n\t * Returns an array of raw listeners for the specified event. This includes listeners wrapped by internal mechanisms (e.g., once-only listeners).\n\t *\n\t * @param eventName - The name (or symbol) of the event.\n\t * @returns An array of raw listener functions.\n\t *\n\t * @example\n\t * const rawListeners = emitter.rawListeners('data');\n\t */\n\trawListeners(eventName: string | symbol): Array<(...arguments_: any[]) => void>;\n\n\t/**\n\t * Adds a listener to the beginning of the listeners array for the specified event.\n\t *\n\t * @param eventName - The name (or symbol) of the event to listen for.\n\t * @param listener - A callback function that will be invoked when the event is emitted.\n\t * @returns The current instance of EventEmitter for method chaining.\n\t *\n\t * @example\n\t * emitter.prependListener('data', (message) => {\n\t * console.log('This will run first.');\n\t * });\n\t */\n\tprependListener(eventName: string | symbol, listener: (...arguments_: any[]) => void): IEventEmitter;\n\n\t/**\n\t * Adds a one-time listener to the beginning of the listeners array for the specified event.\n\t *\n\t * @param eventName - The name (or symbol) of the event to listen for.\n\t * @param listener - A callback function that will be invoked once when the event is emitted.\n\t * @returns The current instance of EventEmitter for method chaining.\n\t *\n\t * @example\n\t * emitter.prependOnceListener('data', (message) => {\n\t * console.log('This will run first and only once.');\n\t * });\n\t */\n\tprependOnceListener(eventName: string | symbol, listener: (...arguments_: any[]) => void): IEventEmitter;\n};\n\nexport type EventListener = (...arguments_: any[]) => void;\n\nexport class Eventified implements IEventEmitter {\n\t_eventListeners: Map<string | symbol, EventListener[]>;\n\t_maxListeners: number;\n\n\tconstructor() {\n\t\tthis._eventListeners = new Map<string | symbol, EventListener[]>();\n\t\tthis._maxListeners = 100; // Default maximum number of listeners\n\t}\n\n\t/**\n\t * Adds a handler function for a specific event that will run only once\n\t * @param {string | symbol} eventName\n\t * @param {EventListener} listener\n\t * @returns {IEventEmitter} returns the instance of the class for chaining\n\t */\n\tonce(eventName: string | symbol, listener: EventListener): IEventEmitter {\n\t\tconst onceListener: EventListener = (...arguments_: any[]) => {\n\t\t\tthis.off(eventName as string, onceListener);\n\t\t\t// eslint-disable-next-line @typescript-eslint/no-unsafe-argument\n\t\t\tlistener(...arguments_);\n\t\t};\n\n\t\tthis.on(eventName as string, onceListener);\n\t\treturn this;\n\t}\n\n\t/**\n\t * Gets the number of listeners for a specific event. If no event is provided, it returns the total number of listeners\n\t * @param {string} eventName The event name. Not required\n\t * @returns {number} The number of listeners\n\t */\n\tlistenerCount(eventName?: string | symbol): number {\n\t\tif (!eventName) {\n\t\t\treturn this.getAllListeners().length;\n\t\t}\n\n\t\tconst listeners = this._eventListeners.get(eventName as string);\n\t\treturn listeners ? listeners.length : 0;\n\t}\n\n\t/**\n\t * Gets an array of event names\n\t * @returns {Array<string | symbol>} An array of event names\n\t */\n\teventNames(): Array<string | symbol> {\n\t\treturn Array.from(this._eventListeners.keys());\n\t}\n\n\t/**\n\t * Gets an array of listeners for a specific event. If no event is provided, it returns all listeners\n\t * @param {string} [event] (Optional) The event name\n\t * @returns {EventListener[]} An array of listeners\n\t */\n\trawListeners(event?: string | symbol): EventListener[] {\n\t\tif (!event) {\n\t\t\treturn this.getAllListeners();\n\t\t}\n\n\t\treturn this._eventListeners.get(event) ?? [];\n\t}\n\n\t/**\n\t * Prepends a listener to the beginning of the listeners array for the specified event\n\t * @param {string | symbol} eventName\n\t * @param {EventListener} listener\n\t * @returns {IEventEmitter} returns the instance of the class for chaining\n\t */\n\tprependListener(eventName: string | symbol, listener: EventListener): IEventEmitter {\n\t\tconst listeners = this._eventListeners.get(eventName) ?? [];\n\t\tlisteners.unshift(listener);\n\t\tthis._eventListeners.set(eventName, listeners);\n\t\treturn this;\n\t}\n\n\t/**\n\t * Prepends a one-time listener to the beginning of the listeners array for the specified event\n\t * @param {string | symbol} eventName\n\t * @param {EventListener} listener\n\t * @returns {IEventEmitter} returns the instance of the class for chaining\n\t */\n\tprependOnceListener(eventName: string | symbol, listener: EventListener): IEventEmitter {\n\t\tconst onceListener: EventListener = (...arguments_: any[]) => {\n\t\t\tthis.off(eventName as string, onceListener);\n\t\t\t// eslint-disable-next-line @typescript-eslint/no-unsafe-argument\n\t\t\tlistener(...arguments_);\n\t\t};\n\n\t\tthis.prependListener(eventName as string, onceListener);\n\t\treturn this;\n\t}\n\n\t/**\n\t * Gets the maximum number of listeners that can be added for a single event\n\t * @returns {number} The maximum number of listeners\n\t */\n\tpublic maxListeners(): number {\n\t\treturn this._maxListeners;\n\t}\n\n\t/**\n\t * Adds a listener for a specific event. It is an alias for the on() method\n\t * @param {string | symbol} event\n\t * @param {EventListener} listener\n\t * @returns {IEventEmitter} returns the instance of the class for chaining\n\t */\n\tpublic addListener(event: string | symbol, listener: EventListener): IEventEmitter {\n\t\tthis.on(event, listener);\n\t\treturn this;\n\t}\n\n\t/**\n\t * Adds a listener for a specific event\n\t * @param {string | symbol} event\n\t * @param {EventListener} listener\n\t * @returns {IEventEmitter} returns the instance of the class for chaining\n\t */\n\tpublic on(event: string | symbol, listener: EventListener): IEventEmitter {\n\t\tif (!this._eventListeners.has(event)) {\n\t\t\tthis._eventListeners.set(event, []);\n\t\t}\n\n\t\tconst listeners = this._eventListeners.get(event);\n\n\t\tif (listeners) {\n\t\t\tif (listeners.length >= this._maxListeners) {\n\t\t\t\tconsole.warn(`MaxListenersExceededWarning: Possible event memory leak detected. ${listeners.length + 1} ${event as string} listeners added. Use setMaxListeners() to increase limit.`);\n\t\t\t}\n\n\t\t\tlisteners.push(listener);\n\t\t}\n\n\t\treturn this;\n\t}\n\n\t/**\n\t * Removes a listener for a specific event. It is an alias for the off() method\n\t * @param {string | symbol} event\n\t * @param {EventListener} listener\n\t * @returns {IEventEmitter} returns the instance of the class for chaining\n\t */\n\tpublic removeListener(event: string, listener: EventListener): IEventEmitter {\n\t\tthis.off(event, listener);\n\t\treturn this;\n\t}\n\n\t/**\n\t * Removes a listener for a specific event\n\t * @param {string | symbol} event\n\t * @param {EventListener} listener\n\t * @returns {IEventEmitter} returns the instance of the class for chaining\n\t */\n\tpublic off(event: string | symbol, listener: EventListener): IEventEmitter {\n\t\tconst listeners = this._eventListeners.get(event) ?? [];\n\t\tconst index = listeners.indexOf(listener);\n\t\tif (index > -1) {\n\t\t\tlisteners.splice(index, 1);\n\t\t}\n\n\t\tif (listeners.length === 0) {\n\t\t\tthis._eventListeners.delete(event);\n\t\t}\n\n\t\treturn this;\n\t}\n\n\t/**\n\t * Calls all listeners for a specific event\n\t * @param {string | symbol} event\n\t * @param arguments_ The arguments to pass to the listeners\n\t * @returns {boolean} Returns true if the event had listeners, false otherwise\n\t */\n\tpublic emit(event: string | symbol, ...arguments_: any[]): boolean {\n\t\tlet result = false;\n\t\tconst listeners = this._eventListeners.get(event);\n\n\t\tif (listeners && listeners.length > 0) {\n\t\t\tfor (const listener of listeners) {\n\t\t\t\t// eslint-disable-next-line @typescript-eslint/no-unsafe-argument\n\t\t\t\tlistener(...arguments_);\n\t\t\t\tresult = true;\n\t\t\t}\n\t\t}\n\n\t\treturn result;\n\t}\n\n\t/**\n\t * Gets all listeners for a specific event. If no event is provided, it returns all listeners\n\t * @param {string} [event] (Optional) The event name\n\t * @returns {EventListener[]} An array of listeners\n\t */\n\tpublic listeners(event: string): EventListener[] {\n\t\treturn this._eventListeners.get(event) ?? [];\n\t}\n\n\t/**\n\t * Removes all listeners for a specific event. If no event is provided, it removes all listeners\n\t * @param {string} [event] (Optional) The event name\n\t * @returns {IEventEmitter} returns the instance of the class for chaining\n\t */\n\tpublic removeAllListeners(event?: string): IEventEmitter {\n\t\tif (event) {\n\t\t\tthis._eventListeners.delete(event);\n\t\t} else {\n\t\t\tthis._eventListeners.clear();\n\t\t}\n\n\t\treturn this;\n\t}\n\n\t/**\n\t * Sets the maximum number of listeners that can be added for a single event\n\t * @param {number} n The maximum number of listeners\n\t * @returns {void}\n\t */\n\tpublic setMaxListeners(n: number): void {\n\t\tthis._maxListeners = n;\n\t\tfor (const listeners of this._eventListeners.values()) {\n\t\t\tif (listeners.length > n) {\n\t\t\t\tlisteners.splice(n);\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Gets all listeners\n\t * @returns {EventListener[]} An array of listeners\n\t */\n\tpublic getAllListeners(): EventListener[] {\n\t\tlet result = new Array<EventListener>();\n\t\tfor (const listeners of this._eventListeners.values()) {\n\t\t\tresult = result.concat(listeners);\n\t\t}\n\n\t\treturn result;\n\t}\n}\n","import {Eventified} from './eventified.js';\n\nexport type Hook = (...arguments_: any[]) => Promise<void> | void;\n\nexport class Hookified extends Eventified {\n\t_hooks: Map<string, Hook[]>;\n\n\tconstructor() {\n\t\tsuper();\n\t\tthis._hooks = new Map();\n\t}\n\n\t/**\n\t * Adds a handler function for a specific event\n\t * @param {string} event\n\t * @param {Hook} handler - this can be async or sync\n\t * @returns {void}\n\t */\n\tonHook(event: string, handler: Hook) {\n\t\tconst eventHandlers = this._hooks.get(event);\n\t\tif (eventHandlers) {\n\t\t\teventHandlers.push(handler);\n\t\t} else {\n\t\t\tthis._hooks.set(event, [handler]);\n\t\t}\n\t}\n\n\t/**\n\t * Adds a handler that only executes once for a specific event\n\t * @param event\n\t * @param handler\n\t */\n\tonceHook(event: string, handler: Hook) {\n\t\tconst hook = async (...arguments_: any[]) => {\n\t\t\tthis.removeHook(event, hook);\n\t\t\t// eslint-disable-next-line @typescript-eslint/no-unsafe-argument\n\t\t\treturn handler(...arguments_);\n\t\t};\n\n\t\tthis.onHook(event, hook);\n\t}\n\n\t/**\n\t * Removes a handler function for a specific event\n\t * @param {string} event\n\t * @param {Hook} handler\n\t * @returns {void}\n\t */\n\tremoveHook(event: string, handler: Hook) {\n\t\tconst eventHandlers = this._hooks.get(event);\n\t\tif (eventHandlers) {\n\t\t\tconst index = eventHandlers.indexOf(handler);\n\t\t\tif (index !== -1) {\n\t\t\t\teventHandlers.splice(index, 1);\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Calls all handlers for a specific event\n\t * @param {string} event\n\t * @param {T[]} arguments_\n\t * @returns {Promise<void>}\n\t */\n\tasync hook<T>(event: string, ...arguments_: T[]) {\n\t\tconst eventHandlers = this._hooks.get(event);\n\t\tif (eventHandlers) {\n\t\t\tfor (const handler of eventHandlers) {\n\t\t\t\ttry {\n\t\t\t\t\t// eslint-disable-next-line no-await-in-loop\n\t\t\t\t\tawait handler(...arguments_);\n\t\t\t\t} catch (error) {\n\t\t\t\t\tthis.emit('error', new Error(`Error in hook handler for event \"${event}\": ${(error as Error).message}`));\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Gets all hooks\n\t * @returns {Map<string, Hook[]>}\n\t */\n\tget hooks() {\n\t\treturn this._hooks;\n\t}\n\n\t/**\n\t * Gets all hooks for a specific event\n\t * @param {string} event\n\t * @returns {Hook[]}\n\t */\n\tgetHooks(event: string) {\n\t\treturn this._hooks.get(event);\n\t}\n\n\t/**\n\t * Removes all hooks\n\t * @returns {void}\n\t */\n\tclearHooks() {\n\t\tthis._hooks.clear();\n\t}\n}\n\nexport {Eventified, type EventListener} from './eventified.js';\n"],"mappings":"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","names":["Eventified","__publicField","eventName","listener","onceListener","arguments_","listeners","event","index","result","n","Hookified","Eventified","__publicField","event","handler","eventHandlers","hook","arguments_","index","error"]}
1
+ {"version":3,"sources":["../../src/eventified.ts","../../src/index.ts"],"sourcesContent":["// eslint-disable-next-line @typescript-eslint/naming-convention\nexport type IEventEmitter = {\n\t/**\n\t * Registers a listener for the specified event.\n\t *\n\t * @param eventName - The name (or symbol) of the event to listen for.\n\t * @param listener - A callback function that will be invoked when the event is emitted.\n\t * @returns The current instance of EventEmitter for method chaining.\n\t *\n\t * @example\n\t * emitter.on('data', (message) => {\n\t * console.log(message);\n\t * });\n\t */\n\ton(eventName: string | symbol, listener: (...arguments_: any[]) => void): IEventEmitter;\n\n\t/**\n\t * Alias for `on`. Registers a listener for the specified event.\n\t *\n\t * @param eventName - The name (or symbol) of the event to listen for.\n\t * @param listener - A callback function that will be invoked when the event is emitted.\n\t * @returns The current instance of EventEmitter for method chaining.\n\t */\n\taddListener(eventName: string | symbol, listener: (...arguments_: any[]) => void): IEventEmitter;\n\n\t/**\n\t * Registers a one-time listener for the specified event. The listener is removed after it is called once.\n\t *\n\t * @param eventName - The name (or symbol) of the event to listen for.\n\t * @param listener - A callback function that will be invoked once when the event is emitted.\n\t * @returns The current instance of EventEmitter for method chaining.\n\t *\n\t * @example\n\t * emitter.once('close', () => {\n\t * console.log('The connection was closed.');\n\t * });\n\t */\n\tonce(eventName: string | symbol, listener: (...arguments_: any[]) => void): IEventEmitter;\n\n\t/**\n\t * Removes a previously registered listener for the specified event.\n\t *\n\t * @param eventName - The name (or symbol) of the event to stop listening for.\n\t * @param listener - The specific callback function to remove.\n\t * @returns The current instance of EventEmitter for method chaining.\n\t *\n\t * @example\n\t * emitter.off('data', myListener);\n\t */\n\toff(eventName: string | symbol, listener: (...arguments_: any[]) => void): IEventEmitter;\n\n\t/**\n\t * Alias for `off`. Removes a previously registered listener for the specified event.\n\t *\n\t * @param eventName - The name (or symbol) of the event to stop listening for.\n\t * @param listener - The specific callback function to remove.\n\t * @returns The current instance of EventEmitter for method chaining.\n\t */\n\tremoveListener(eventName: string | symbol, listener: (...arguments_: any[]) => void): IEventEmitter;\n\n\t/**\n\t * Emits the specified event, invoking all registered listeners with the provided arguments.\n\t *\n\t * @param eventName - The name (or symbol) of the event to emit.\n\t * @param args - Arguments passed to each listener.\n\t * @returns `true` if the event had listeners, `false` otherwise.\n\t *\n\t * @example\n\t * emitter.emit('data', 'Hello World');\n\t */\n\temit(eventName: string | symbol, ...arguments_: any[]): boolean;\n\n\t/**\n\t * Returns the number of listeners registered for the specified event.\n\t *\n\t * @param eventName - The name (or symbol) of the event.\n\t * @returns The number of registered listeners.\n\t *\n\t * @example\n\t * const count = emitter.listenerCount('data');\n\t * console.log(count); // e.g., 2\n\t */\n\tlistenerCount(eventName: string | symbol): number;\n\n\t/**\n\t * Removes all listeners for the specified event. If no event is specified, it removes all listeners for all events.\n\t *\n\t * @param eventName - (Optional) The name (or symbol) of the event.\n\t * @returns The current instance of EventEmitter for method chaining.\n\t *\n\t * @example\n\t * emitter.removeAllListeners('data');\n\t */\n\tremoveAllListeners(eventName?: string | symbol): IEventEmitter;\n\n\t/**\n\t * Returns an array of event names for which listeners have been registered.\n\t *\n\t * @returns An array of event names (or symbols).\n\t *\n\t * @example\n\t * const events = emitter.eventNames();\n\t * console.log(events); // e.g., ['data', 'close']\n\t */\n\teventNames(): Array<string | symbol>;\n\n\t/**\n\t * Returns an array of listeners registered for the specified event.\n\t *\n\t * @param eventName - The name (or symbol) of the event.\n\t * @returns An array of listener functions.\n\t *\n\t * @example\n\t * const listeners = emitter.listeners('data');\n\t * console.log(listeners.length); // e.g., 2\n\t */\n\tlisteners(eventName: string | symbol): Array<(...arguments_: any[]) => void>;\n\n\t/**\n\t * Returns an array of raw listeners for the specified event. This includes listeners wrapped by internal mechanisms (e.g., once-only listeners).\n\t *\n\t * @param eventName - The name (or symbol) of the event.\n\t * @returns An array of raw listener functions.\n\t *\n\t * @example\n\t * const rawListeners = emitter.rawListeners('data');\n\t */\n\trawListeners(eventName: string | symbol): Array<(...arguments_: any[]) => void>;\n\n\t/**\n\t * Adds a listener to the beginning of the listeners array for the specified event.\n\t *\n\t * @param eventName - The name (or symbol) of the event to listen for.\n\t * @param listener - A callback function that will be invoked when the event is emitted.\n\t * @returns The current instance of EventEmitter for method chaining.\n\t *\n\t * @example\n\t * emitter.prependListener('data', (message) => {\n\t * console.log('This will run first.');\n\t * });\n\t */\n\tprependListener(eventName: string | symbol, listener: (...arguments_: any[]) => void): IEventEmitter;\n\n\t/**\n\t * Adds a one-time listener to the beginning of the listeners array for the specified event.\n\t *\n\t * @param eventName - The name (or symbol) of the event to listen for.\n\t * @param listener - A callback function that will be invoked once when the event is emitted.\n\t * @returns The current instance of EventEmitter for method chaining.\n\t *\n\t * @example\n\t * emitter.prependOnceListener('data', (message) => {\n\t * console.log('This will run first and only once.');\n\t * });\n\t */\n\tprependOnceListener(eventName: string | symbol, listener: (...arguments_: any[]) => void): IEventEmitter;\n};\n\nexport type EventListener = (...arguments_: any[]) => void;\n\nexport class Eventified implements IEventEmitter {\n\t_eventListeners: Map<string | symbol, EventListener[]>;\n\t_maxListeners: number;\n\n\tconstructor() {\n\t\tthis._eventListeners = new Map<string | symbol, EventListener[]>();\n\t\tthis._maxListeners = 100; // Default maximum number of listeners\n\t}\n\n\t/**\n\t * Adds a handler function for a specific event that will run only once\n\t * @param {string | symbol} eventName\n\t * @param {EventListener} listener\n\t * @returns {IEventEmitter} returns the instance of the class for chaining\n\t */\n\tonce(eventName: string | symbol, listener: EventListener): IEventEmitter {\n\t\tconst onceListener: EventListener = (...arguments_: any[]) => {\n\t\t\tthis.off(eventName as string, onceListener);\n\t\t\t// eslint-disable-next-line @typescript-eslint/no-unsafe-argument\n\t\t\tlistener(...arguments_);\n\t\t};\n\n\t\tthis.on(eventName as string, onceListener);\n\t\treturn this;\n\t}\n\n\t/**\n\t * Gets the number of listeners for a specific event. If no event is provided, it returns the total number of listeners\n\t * @param {string} eventName The event name. Not required\n\t * @returns {number} The number of listeners\n\t */\n\tlistenerCount(eventName?: string | symbol): number {\n\t\tif (!eventName) {\n\t\t\treturn this.getAllListeners().length;\n\t\t}\n\n\t\tconst listeners = this._eventListeners.get(eventName as string);\n\t\treturn listeners ? listeners.length : 0;\n\t}\n\n\t/**\n\t * Gets an array of event names\n\t * @returns {Array<string | symbol>} An array of event names\n\t */\n\teventNames(): Array<string | symbol> {\n\t\treturn Array.from(this._eventListeners.keys());\n\t}\n\n\t/**\n\t * Gets an array of listeners for a specific event. If no event is provided, it returns all listeners\n\t * @param {string} [event] (Optional) The event name\n\t * @returns {EventListener[]} An array of listeners\n\t */\n\trawListeners(event?: string | symbol): EventListener[] {\n\t\tif (!event) {\n\t\t\treturn this.getAllListeners();\n\t\t}\n\n\t\treturn this._eventListeners.get(event) ?? [];\n\t}\n\n\t/**\n\t * Prepends a listener to the beginning of the listeners array for the specified event\n\t * @param {string | symbol} eventName\n\t * @param {EventListener} listener\n\t * @returns {IEventEmitter} returns the instance of the class for chaining\n\t */\n\tprependListener(eventName: string | symbol, listener: EventListener): IEventEmitter {\n\t\tconst listeners = this._eventListeners.get(eventName) ?? [];\n\t\tlisteners.unshift(listener);\n\t\tthis._eventListeners.set(eventName, listeners);\n\t\treturn this;\n\t}\n\n\t/**\n\t * Prepends a one-time listener to the beginning of the listeners array for the specified event\n\t * @param {string | symbol} eventName\n\t * @param {EventListener} listener\n\t * @returns {IEventEmitter} returns the instance of the class for chaining\n\t */\n\tprependOnceListener(eventName: string | symbol, listener: EventListener): IEventEmitter {\n\t\tconst onceListener: EventListener = (...arguments_: any[]) => {\n\t\t\tthis.off(eventName as string, onceListener);\n\t\t\t// eslint-disable-next-line @typescript-eslint/no-unsafe-argument\n\t\t\tlistener(...arguments_);\n\t\t};\n\n\t\tthis.prependListener(eventName as string, onceListener);\n\t\treturn this;\n\t}\n\n\t/**\n\t * Gets the maximum number of listeners that can be added for a single event\n\t * @returns {number} The maximum number of listeners\n\t */\n\tpublic maxListeners(): number {\n\t\treturn this._maxListeners;\n\t}\n\n\t/**\n\t * Adds a listener for a specific event. It is an alias for the on() method\n\t * @param {string | symbol} event\n\t * @param {EventListener} listener\n\t * @returns {IEventEmitter} returns the instance of the class for chaining\n\t */\n\tpublic addListener(event: string | symbol, listener: EventListener): IEventEmitter {\n\t\tthis.on(event, listener);\n\t\treturn this;\n\t}\n\n\t/**\n\t * Adds a listener for a specific event\n\t * @param {string | symbol} event\n\t * @param {EventListener} listener\n\t * @returns {IEventEmitter} returns the instance of the class for chaining\n\t */\n\tpublic on(event: string | symbol, listener: EventListener): IEventEmitter {\n\t\tif (!this._eventListeners.has(event)) {\n\t\t\tthis._eventListeners.set(event, []);\n\t\t}\n\n\t\tconst listeners = this._eventListeners.get(event);\n\n\t\tif (listeners) {\n\t\t\tif (listeners.length >= this._maxListeners) {\n\t\t\t\tconsole.warn(`MaxListenersExceededWarning: Possible event memory leak detected. ${listeners.length + 1} ${event as string} listeners added. Use setMaxListeners() to increase limit.`);\n\t\t\t}\n\n\t\t\tlisteners.push(listener);\n\t\t}\n\n\t\treturn this;\n\t}\n\n\t/**\n\t * Removes a listener for a specific event. It is an alias for the off() method\n\t * @param {string | symbol} event\n\t * @param {EventListener} listener\n\t * @returns {IEventEmitter} returns the instance of the class for chaining\n\t */\n\tpublic removeListener(event: string, listener: EventListener): IEventEmitter {\n\t\tthis.off(event, listener);\n\t\treturn this;\n\t}\n\n\t/**\n\t * Removes a listener for a specific event\n\t * @param {string | symbol} event\n\t * @param {EventListener} listener\n\t * @returns {IEventEmitter} returns the instance of the class for chaining\n\t */\n\tpublic off(event: string | symbol, listener: EventListener): IEventEmitter {\n\t\tconst listeners = this._eventListeners.get(event) ?? [];\n\t\tconst index = listeners.indexOf(listener);\n\t\tif (index !== -1) {\n\t\t\tlisteners.splice(index, 1);\n\t\t}\n\n\t\tif (listeners.length === 0) {\n\t\t\tthis._eventListeners.delete(event);\n\t\t}\n\n\t\treturn this;\n\t}\n\n\t/**\n\t * Calls all listeners for a specific event\n\t * @param {string | symbol} event\n\t * @param arguments_ The arguments to pass to the listeners\n\t * @returns {boolean} Returns true if the event had listeners, false otherwise\n\t */\n\tpublic emit(event: string | symbol, ...arguments_: any[]): boolean {\n\t\tlet result = false;\n\t\tconst listeners = this._eventListeners.get(event);\n\n\t\tif (listeners && listeners.length > 0) {\n\t\t\tfor (const listener of listeners) {\n\t\t\t\t// eslint-disable-next-line @typescript-eslint/no-unsafe-argument\n\t\t\t\tlistener(...arguments_);\n\t\t\t\tresult = true;\n\t\t\t}\n\t\t}\n\n\t\treturn result;\n\t}\n\n\t/**\n\t * Gets all listeners for a specific event. If no event is provided, it returns all listeners\n\t * @param {string} [event] (Optional) The event name\n\t * @returns {EventListener[]} An array of listeners\n\t */\n\tpublic listeners(event: string): EventListener[] {\n\t\treturn this._eventListeners.get(event) ?? [];\n\t}\n\n\t/**\n\t * Removes all listeners for a specific event. If no event is provided, it removes all listeners\n\t * @param {string} [event] (Optional) The event name\n\t * @returns {IEventEmitter} returns the instance of the class for chaining\n\t */\n\tpublic removeAllListeners(event?: string): IEventEmitter {\n\t\tif (event) {\n\t\t\tthis._eventListeners.delete(event);\n\t\t} else {\n\t\t\tthis._eventListeners.clear();\n\t\t}\n\n\t\treturn this;\n\t}\n\n\t/**\n\t * Sets the maximum number of listeners that can be added for a single event\n\t * @param {number} n The maximum number of listeners\n\t * @returns {void}\n\t */\n\tpublic setMaxListeners(n: number): void {\n\t\tthis._maxListeners = n;\n\t\tfor (const listeners of this._eventListeners.values()) {\n\t\t\tif (listeners.length > n) {\n\t\t\t\tlisteners.splice(n);\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Gets all listeners\n\t * @returns {EventListener[]} An array of listeners\n\t */\n\tpublic getAllListeners(): EventListener[] {\n\t\tlet result = new Array<EventListener>();\n\t\tfor (const listeners of this._eventListeners.values()) {\n\t\t\tresult = result.concat(listeners);\n\t\t}\n\n\t\treturn result;\n\t}\n}\n","import {Eventified} from './eventified.js';\n\nexport type Hook = (...arguments_: any[]) => Promise<void> | void;\n\nexport type HookifiedOptions = {\n\tthrowHookErrors?: boolean;\n};\n\nexport class Hookified extends Eventified {\n\t_hooks: Map<string, Hook[]>;\n\t_throwHookErrors = false;\n\n\tconstructor(options?: HookifiedOptions) {\n\t\tsuper();\n\t\tthis._hooks = new Map();\n\n\t\tif (options?.throwHookErrors !== undefined) {\n\t\t\tthis._throwHookErrors = options.throwHookErrors;\n\t\t}\n\t}\n\n\t/**\n\t * Gets all hooks\n\t * @returns {Map<string, Hook[]>}\n\t */\n\tget hooks() {\n\t\treturn this._hooks;\n\t}\n\n\t/**\n\t * Gets whether an error should be thrown when a hook throws an error. Default is false and only emits an error event.\n\t * @returns {boolean}\n\t */\n\tget throwHookErrors() {\n\t\treturn this._throwHookErrors;\n\t}\n\n\t/**\n\t * Sets whether an error should be thrown when a hook throws an error. Default is false and only emits an error event.\n\t * @param {boolean} value\n\t */\n\tset throwHookErrors(value) {\n\t\tthis._throwHookErrors = value;\n\t}\n\n\t/**\n\t * Adds a handler function for a specific event\n\t * @param {string} event\n\t * @param {Hook} handler - this can be async or sync\n\t * @returns {void}\n\t */\n\tonHook(event: string, handler: Hook) {\n\t\tconst eventHandlers = this._hooks.get(event);\n\t\tif (eventHandlers) {\n\t\t\teventHandlers.push(handler);\n\t\t} else {\n\t\t\tthis._hooks.set(event, [handler]);\n\t\t}\n\t}\n\n\t/**\n\t * Adds a handler function for a specific event that runs before all other handlers\n\t * @param {string} event\n\t * @param {Hook} handler - this can be async or sync\n\t * @returns {void}\n\t */\n\tprependHook(event: string, handler: Hook) {\n\t\tconst eventHandlers = this._hooks.get(event);\n\t\tif (eventHandlers) {\n\t\t\teventHandlers.unshift(handler);\n\t\t} else {\n\t\t\tthis._hooks.set(event, [handler]);\n\t\t}\n\t}\n\n\t/**\n\t * Adds a handler that only executes once for a specific event before all other handlers\n\t * @param event\n\t * @param handler\n\t */\n\tprependOnceHook(event: string, handler: Hook) {\n\t\tconst hook = async (...arguments_: any[]) => {\n\t\t\tthis.removeHook(event, hook);\n\t\t\t// eslint-disable-next-line @typescript-eslint/no-unsafe-argument\n\t\t\treturn handler(...arguments_);\n\t\t};\n\n\t\tthis.prependHook(event, hook);\n\t}\n\n\t/**\n\t * Adds a handler that only executes once for a specific event\n\t * @param event\n\t * @param handler\n\t */\n\tonceHook(event: string, handler: Hook) {\n\t\tconst hook = async (...arguments_: any[]) => {\n\t\t\tthis.removeHook(event, hook);\n\t\t\t// eslint-disable-next-line @typescript-eslint/no-unsafe-argument\n\t\t\treturn handler(...arguments_);\n\t\t};\n\n\t\tthis.onHook(event, hook);\n\t}\n\n\t/**\n\t * Removes a handler function for a specific event\n\t * @param {string} event\n\t * @param {Hook} handler\n\t * @returns {void}\n\t */\n\tremoveHook(event: string, handler: Hook) {\n\t\tconst eventHandlers = this._hooks.get(event);\n\t\tif (eventHandlers) {\n\t\t\tconst index = eventHandlers.indexOf(handler);\n\t\t\tif (index !== -1) {\n\t\t\t\teventHandlers.splice(index, 1);\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Calls all handlers for a specific event\n\t * @param {string} event\n\t * @param {T[]} arguments_\n\t * @returns {Promise<void>}\n\t */\n\tasync hook<T>(event: string, ...arguments_: T[]) {\n\t\tconst eventHandlers = this._hooks.get(event);\n\t\tif (eventHandlers) {\n\t\t\tfor (const handler of eventHandlers) {\n\t\t\t\ttry {\n\t\t\t\t\t// eslint-disable-next-line no-await-in-loop\n\t\t\t\t\tawait handler(...arguments_);\n\t\t\t\t} catch (error) {\n\t\t\t\t\tconst message = `${event}: ${(error as Error).message}`;\n\t\t\t\t\tthis.emit('error', new Error(message));\n\t\t\t\t\tif (this._throwHookErrors) {\n\t\t\t\t\t\tthrow new Error(message);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Gets all hooks for a specific event\n\t * @param {string} event\n\t * @returns {Hook[]}\n\t */\n\tgetHooks(event: string) {\n\t\treturn this._hooks.get(event);\n\t}\n\n\t/**\n\t * Removes all hooks\n\t * @returns {void}\n\t */\n\tclearHooks() {\n\t\tthis._hooks.clear();\n\t}\n}\n\nexport {Eventified, type EventListener} from './eventified.js';\n"],"mappings":"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","names":["Eventified","__publicField","eventName","listener","onceListener","arguments_","listeners","event","index","result","n","Hookified","Eventified","options","__publicField","value","event","handler","eventHandlers","hook","arguments_","index","error","message"]}
@@ -18,12 +18,12 @@ var __copyProps = (to, from, except, desc) => {
18
18
  var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
19
 
20
20
  // src/index.ts
21
- var src_exports = {};
22
- __export(src_exports, {
21
+ var index_exports = {};
22
+ __export(index_exports, {
23
23
  Eventified: () => Eventified,
24
24
  Hookified: () => Hookified
25
25
  });
26
- module.exports = __toCommonJS(src_exports);
26
+ module.exports = __toCommonJS(index_exports);
27
27
 
28
28
  // src/eventified.ts
29
29
  var Eventified = class {
@@ -158,7 +158,7 @@ var Eventified = class {
158
158
  off(event, listener) {
159
159
  const listeners = this._eventListeners.get(event) ?? [];
160
160
  const index = listeners.indexOf(listener);
161
- if (index > -1) {
161
+ if (index !== -1) {
162
162
  listeners.splice(index, 1);
163
163
  }
164
164
  if (listeners.length === 0) {
@@ -233,9 +233,34 @@ var Eventified = class {
233
233
  // src/index.ts
234
234
  var Hookified = class extends Eventified {
235
235
  _hooks;
236
- constructor() {
236
+ _throwHookErrors = false;
237
+ constructor(options) {
237
238
  super();
238
239
  this._hooks = /* @__PURE__ */ new Map();
240
+ if (options?.throwHookErrors !== void 0) {
241
+ this._throwHookErrors = options.throwHookErrors;
242
+ }
243
+ }
244
+ /**
245
+ * Gets all hooks
246
+ * @returns {Map<string, Hook[]>}
247
+ */
248
+ get hooks() {
249
+ return this._hooks;
250
+ }
251
+ /**
252
+ * Gets whether an error should be thrown when a hook throws an error. Default is false and only emits an error event.
253
+ * @returns {boolean}
254
+ */
255
+ get throwHookErrors() {
256
+ return this._throwHookErrors;
257
+ }
258
+ /**
259
+ * Sets whether an error should be thrown when a hook throws an error. Default is false and only emits an error event.
260
+ * @param {boolean} value
261
+ */
262
+ set throwHookErrors(value) {
263
+ this._throwHookErrors = value;
239
264
  }
240
265
  /**
241
266
  * Adds a handler function for a specific event
@@ -251,6 +276,32 @@ var Hookified = class extends Eventified {
251
276
  this._hooks.set(event, [handler]);
252
277
  }
253
278
  }
279
+ /**
280
+ * Adds a handler function for a specific event that runs before all other handlers
281
+ * @param {string} event
282
+ * @param {Hook} handler - this can be async or sync
283
+ * @returns {void}
284
+ */
285
+ prependHook(event, handler) {
286
+ const eventHandlers = this._hooks.get(event);
287
+ if (eventHandlers) {
288
+ eventHandlers.unshift(handler);
289
+ } else {
290
+ this._hooks.set(event, [handler]);
291
+ }
292
+ }
293
+ /**
294
+ * Adds a handler that only executes once for a specific event before all other handlers
295
+ * @param event
296
+ * @param handler
297
+ */
298
+ prependOnceHook(event, handler) {
299
+ const hook = async (...arguments_) => {
300
+ this.removeHook(event, hook);
301
+ return handler(...arguments_);
302
+ };
303
+ this.prependHook(event, hook);
304
+ }
254
305
  /**
255
306
  * Adds a handler that only executes once for a specific event
256
307
  * @param event
@@ -291,18 +342,15 @@ var Hookified = class extends Eventified {
291
342
  try {
292
343
  await handler(...arguments_);
293
344
  } catch (error) {
294
- this.emit("error", new Error(`Error in hook handler for event "${event}": ${error.message}`));
345
+ const message = `${event}: ${error.message}`;
346
+ this.emit("error", new Error(message));
347
+ if (this._throwHookErrors) {
348
+ throw new Error(message);
349
+ }
295
350
  }
296
351
  }
297
352
  }
298
353
  }
299
- /**
300
- * Gets all hooks
301
- * @returns {Map<string, Hook[]>}
302
- */
303
- get hooks() {
304
- return this._hooks;
305
- }
306
354
  /**
307
355
  * Gets all hooks for a specific event
308
356
  * @param {string} event
@@ -251,9 +251,28 @@ declare class Eventified implements IEventEmitter {
251
251
  }
252
252
 
253
253
  type Hook = (...arguments_: any[]) => Promise<void> | void;
254
+ type HookifiedOptions = {
255
+ throwHookErrors?: boolean;
256
+ };
254
257
  declare class Hookified extends Eventified {
255
258
  _hooks: Map<string, Hook[]>;
256
- constructor();
259
+ _throwHookErrors: boolean;
260
+ constructor(options?: HookifiedOptions);
261
+ /**
262
+ * Gets all hooks
263
+ * @returns {Map<string, Hook[]>}
264
+ */
265
+ get hooks(): Map<string, Hook[]>;
266
+ /**
267
+ * Gets whether an error should be thrown when a hook throws an error. Default is false and only emits an error event.
268
+ * @returns {boolean}
269
+ */
270
+ get throwHookErrors(): boolean;
271
+ /**
272
+ * Sets whether an error should be thrown when a hook throws an error. Default is false and only emits an error event.
273
+ * @param {boolean} value
274
+ */
275
+ set throwHookErrors(value: boolean);
257
276
  /**
258
277
  * Adds a handler function for a specific event
259
278
  * @param {string} event
@@ -261,6 +280,19 @@ declare class Hookified extends Eventified {
261
280
  * @returns {void}
262
281
  */
263
282
  onHook(event: string, handler: Hook): void;
283
+ /**
284
+ * Adds a handler function for a specific event that runs before all other handlers
285
+ * @param {string} event
286
+ * @param {Hook} handler - this can be async or sync
287
+ * @returns {void}
288
+ */
289
+ prependHook(event: string, handler: Hook): void;
290
+ /**
291
+ * Adds a handler that only executes once for a specific event before all other handlers
292
+ * @param event
293
+ * @param handler
294
+ */
295
+ prependOnceHook(event: string, handler: Hook): void;
264
296
  /**
265
297
  * Adds a handler that only executes once for a specific event
266
298
  * @param event
@@ -281,11 +313,6 @@ declare class Hookified extends Eventified {
281
313
  * @returns {Promise<void>}
282
314
  */
283
315
  hook<T>(event: string, ...arguments_: T[]): Promise<void>;
284
- /**
285
- * Gets all hooks
286
- * @returns {Map<string, Hook[]>}
287
- */
288
- get hooks(): Map<string, Hook[]>;
289
316
  /**
290
317
  * Gets all hooks for a specific event
291
318
  * @param {string} event
@@ -299,4 +326,4 @@ declare class Hookified extends Eventified {
299
326
  clearHooks(): void;
300
327
  }
301
328
 
302
- export { type EventListener, Eventified, type Hook, Hookified };
329
+ export { type EventListener, Eventified, type Hook, Hookified, type HookifiedOptions };
@@ -251,9 +251,28 @@ declare class Eventified implements IEventEmitter {
251
251
  }
252
252
 
253
253
  type Hook = (...arguments_: any[]) => Promise<void> | void;
254
+ type HookifiedOptions = {
255
+ throwHookErrors?: boolean;
256
+ };
254
257
  declare class Hookified extends Eventified {
255
258
  _hooks: Map<string, Hook[]>;
256
- constructor();
259
+ _throwHookErrors: boolean;
260
+ constructor(options?: HookifiedOptions);
261
+ /**
262
+ * Gets all hooks
263
+ * @returns {Map<string, Hook[]>}
264
+ */
265
+ get hooks(): Map<string, Hook[]>;
266
+ /**
267
+ * Gets whether an error should be thrown when a hook throws an error. Default is false and only emits an error event.
268
+ * @returns {boolean}
269
+ */
270
+ get throwHookErrors(): boolean;
271
+ /**
272
+ * Sets whether an error should be thrown when a hook throws an error. Default is false and only emits an error event.
273
+ * @param {boolean} value
274
+ */
275
+ set throwHookErrors(value: boolean);
257
276
  /**
258
277
  * Adds a handler function for a specific event
259
278
  * @param {string} event
@@ -261,6 +280,19 @@ declare class Hookified extends Eventified {
261
280
  * @returns {void}
262
281
  */
263
282
  onHook(event: string, handler: Hook): void;
283
+ /**
284
+ * Adds a handler function for a specific event that runs before all other handlers
285
+ * @param {string} event
286
+ * @param {Hook} handler - this can be async or sync
287
+ * @returns {void}
288
+ */
289
+ prependHook(event: string, handler: Hook): void;
290
+ /**
291
+ * Adds a handler that only executes once for a specific event before all other handlers
292
+ * @param event
293
+ * @param handler
294
+ */
295
+ prependOnceHook(event: string, handler: Hook): void;
264
296
  /**
265
297
  * Adds a handler that only executes once for a specific event
266
298
  * @param event
@@ -281,11 +313,6 @@ declare class Hookified extends Eventified {
281
313
  * @returns {Promise<void>}
282
314
  */
283
315
  hook<T>(event: string, ...arguments_: T[]): Promise<void>;
284
- /**
285
- * Gets all hooks
286
- * @returns {Map<string, Hook[]>}
287
- */
288
- get hooks(): Map<string, Hook[]>;
289
316
  /**
290
317
  * Gets all hooks for a specific event
291
318
  * @param {string} event
@@ -299,4 +326,4 @@ declare class Hookified extends Eventified {
299
326
  clearHooks(): void;
300
327
  }
301
328
 
302
- export { type EventListener, Eventified, type Hook, Hookified };
329
+ export { type EventListener, Eventified, type Hook, Hookified, type HookifiedOptions };
@@ -131,7 +131,7 @@ var Eventified = class {
131
131
  off(event, listener) {
132
132
  const listeners = this._eventListeners.get(event) ?? [];
133
133
  const index = listeners.indexOf(listener);
134
- if (index > -1) {
134
+ if (index !== -1) {
135
135
  listeners.splice(index, 1);
136
136
  }
137
137
  if (listeners.length === 0) {
@@ -206,9 +206,34 @@ var Eventified = class {
206
206
  // src/index.ts
207
207
  var Hookified = class extends Eventified {
208
208
  _hooks;
209
- constructor() {
209
+ _throwHookErrors = false;
210
+ constructor(options) {
210
211
  super();
211
212
  this._hooks = /* @__PURE__ */ new Map();
213
+ if (options?.throwHookErrors !== void 0) {
214
+ this._throwHookErrors = options.throwHookErrors;
215
+ }
216
+ }
217
+ /**
218
+ * Gets all hooks
219
+ * @returns {Map<string, Hook[]>}
220
+ */
221
+ get hooks() {
222
+ return this._hooks;
223
+ }
224
+ /**
225
+ * Gets whether an error should be thrown when a hook throws an error. Default is false and only emits an error event.
226
+ * @returns {boolean}
227
+ */
228
+ get throwHookErrors() {
229
+ return this._throwHookErrors;
230
+ }
231
+ /**
232
+ * Sets whether an error should be thrown when a hook throws an error. Default is false and only emits an error event.
233
+ * @param {boolean} value
234
+ */
235
+ set throwHookErrors(value) {
236
+ this._throwHookErrors = value;
212
237
  }
213
238
  /**
214
239
  * Adds a handler function for a specific event
@@ -224,6 +249,32 @@ var Hookified = class extends Eventified {
224
249
  this._hooks.set(event, [handler]);
225
250
  }
226
251
  }
252
+ /**
253
+ * Adds a handler function for a specific event that runs before all other handlers
254
+ * @param {string} event
255
+ * @param {Hook} handler - this can be async or sync
256
+ * @returns {void}
257
+ */
258
+ prependHook(event, handler) {
259
+ const eventHandlers = this._hooks.get(event);
260
+ if (eventHandlers) {
261
+ eventHandlers.unshift(handler);
262
+ } else {
263
+ this._hooks.set(event, [handler]);
264
+ }
265
+ }
266
+ /**
267
+ * Adds a handler that only executes once for a specific event before all other handlers
268
+ * @param event
269
+ * @param handler
270
+ */
271
+ prependOnceHook(event, handler) {
272
+ const hook = async (...arguments_) => {
273
+ this.removeHook(event, hook);
274
+ return handler(...arguments_);
275
+ };
276
+ this.prependHook(event, hook);
277
+ }
227
278
  /**
228
279
  * Adds a handler that only executes once for a specific event
229
280
  * @param event
@@ -264,18 +315,15 @@ var Hookified = class extends Eventified {
264
315
  try {
265
316
  await handler(...arguments_);
266
317
  } catch (error) {
267
- this.emit("error", new Error(`Error in hook handler for event "${event}": ${error.message}`));
318
+ const message = `${event}: ${error.message}`;
319
+ this.emit("error", new Error(message));
320
+ if (this._throwHookErrors) {
321
+ throw new Error(message);
322
+ }
268
323
  }
269
324
  }
270
325
  }
271
326
  }
272
- /**
273
- * Gets all hooks
274
- * @returns {Map<string, Hook[]>}
275
- */
276
- get hooks() {
277
- return this._hooks;
278
- }
279
327
  /**
280
328
  * Gets all hooks for a specific event
281
329
  * @param {string} event
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "hookified",
3
- "version": "1.5.1",
3
+ "version": "1.7.0",
4
4
  "description": "Event and Middleware Hooks",
5
5
  "type": "module",
6
6
  "main": "dist/node/index.cjs",
@@ -57,13 +57,13 @@
57
57
  },
58
58
  "homepage": "https://github.com/jaredwray/hookified#readme",
59
59
  "devDependencies": {
60
- "@vitest/coverage-v8": "^2.1.5",
61
- "docula": "^0.9.5",
60
+ "@vitest/coverage-v8": "^3.0.2",
61
+ "docula": "^0.9.6",
62
62
  "rimraf": "^6.0.1",
63
63
  "tsup": "^8.3.5",
64
- "typescript": "^5.7.2",
65
- "vitest": "^2.1.5",
66
- "xo": "^0.59.3"
64
+ "typescript": "^5.7.3",
65
+ "vitest": "^3.0.2",
66
+ "xo": "^0.60.0"
67
67
  },
68
68
  "files": [
69
69
  "dist",