Sign In

hookified

Package Overview
Dependencies
Maintainers
1
Versions
38
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

hookified - npm Package Compare versions

Comparing version
3.0.0
to
3.0.1
+34
-11
dist/browser/index.global.js
var Hookified = (function(exports) {
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
//#region \0@oxc-project+runtime@0.130.0/helpers/typeof.js
//#region \0@oxc-project+runtime@0.135.0/helpers/esm/typeof.js
function _typeof(o) {

@@ -13,3 +13,3 @@ "@babel/helpers - typeof";

//#endregion
//#region \0@oxc-project+runtime@0.130.0/helpers/toPrimitive.js
//#region \0@oxc-project+runtime@0.135.0/helpers/esm/toPrimitive.js
function toPrimitive(t, r) {

@@ -26,3 +26,3 @@ if ("object" != _typeof(t) || !t) return t;

//#endregion
//#region \0@oxc-project+runtime@0.130.0/helpers/toPropertyKey.js
//#region \0@oxc-project+runtime@0.135.0/helpers/esm/toPropertyKey.js
function toPropertyKey(t) {

@@ -33,3 +33,3 @@ var i = toPrimitive(t, "string");

//#endregion
//#region \0@oxc-project+runtime@0.130.0/helpers/defineProperty.js
//#region \0@oxc-project+runtime@0.135.0/helpers/esm/defineProperty.js
function _defineProperty(e, r, t) {

@@ -112,2 +112,3 @@ return (r = toPropertyKey(r)) in e ? Object.defineProperty(e, r, {

};
onceListener._originalListener = listener;
this.on(eventName, onceListener);

@@ -173,2 +174,3 @@ return this;

};
onceListener._originalListener = listener;
this.prependListener(eventName, onceListener);

@@ -227,2 +229,15 @@ return this;

/**
* Determines whether a stored listener matches the listener provided to off().
* A match occurs when the references are identical, or when the stored listener
* is a once-wrapper whose original listener equals the provided reference.
* @param {EventListener} stored - the listener currently stored
* @param {EventListener} target - the listener passed to off()
* @returns {boolean} true if the stored listener should be removed
*/
matchesListener(stored, target) {
if (stored === target) return true;
const original = stored._originalListener;
return original !== void 0 && original === target;
}
/**
* Removes a listener for a specific event

@@ -237,6 +252,7 @@ * @param {string | symbol} event

if (typeof entry === "function") {
if (entry === listener) this._eventListeners.delete(event);
if (this.matchesListener(entry, listener)) this._eventListeners.delete(event);
return this;
}
const index = entry.indexOf(listener);
let index = entry.indexOf(listener);
if (index === -1) index = entry.findIndex((stored) => this.matchesListener(stored, listener));
if (index !== -1) if (entry.length === 2) this._eventListeners.set(event, entry[1 - index]);

@@ -262,6 +278,7 @@ else if (entry.length === 1) this._eventListeners.delete(event);

else {
const len = entry.length;
for (let i = 0; i < len; i++) if (argumentLength === 1) entry[i](arguments_[0]);
else if (argumentLength === 2) entry[i](arguments_[0], arguments_[1]);
else entry[i](...arguments_);
const listeners = entry.slice();
const len = listeners.length;
for (let i = 0; i < len; i++) if (argumentLength === 1) listeners[i](arguments_[0]);
else if (argumentLength === 2) listeners[i](arguments_[0], arguments_[1]);
else listeners[i](...arguments_);
}

@@ -725,2 +742,3 @@ result = true;

};
wrappedHandler._originalHandler = hook.handler;
return this.onHook({

@@ -749,2 +767,3 @@ id: hook.id,

};
wrappedHandler._originalHandler = hook.handler;
this.onHook({

@@ -765,3 +784,7 @@ id: hook.id,

if (eventHandlers) {
const index = eventHandlers.findIndex((h) => h.handler === hook.handler);
let index = eventHandlers.findIndex((h) => h.handler === hook.handler);
if (index === -1) index = eventHandlers.findIndex((h) => {
const original = h.handler._originalHandler;
return original !== void 0 && original === hook.handler;
});
if (index !== -1) {

@@ -768,0 +791,0 @@ eventHandlers.splice(index, 1);

@@ -1,1 +0,1 @@

{"version":3,"file":"index.global.js","names":[],"sources":["../../src/eventified.ts","../../src/hooks/hook.ts","../../src/hooks/parallel-hook.ts","../../src/hooks/waterfall-hook.ts","../../src/index.ts"],"sourcesContent":["// biome-ignore-all lint/suspicious/noExplicitAny: this is for event emitter compatibility\nimport type {\n\tEventEmitterOptions,\n\tEventListener,\n\tIEventEmitter,\n\tLogger,\n} from \"./types.js\";\n\nexport type { EventEmitterOptions, EventListener, IEventEmitter };\n\nconst ERROR_EVENT = \"error\";\n\nexport class Eventified implements IEventEmitter {\n\tprivate readonly _eventListeners: Map<\n\t\tstring | symbol,\n\t\tEventListener | EventListener[]\n\t>;\n\tprivate _maxListeners: number;\n\tprivate _eventLogger?: Logger;\n\tprivate _throwOnEmitError = false;\n\tprivate _throwOnEmptyListeners = true;\n\n\tconstructor(options?: EventEmitterOptions) {\n\t\tthis._eventListeners = new Map<\n\t\t\tstring | symbol,\n\t\t\tEventListener | EventListener[]\n\t\t>();\n\t\tthis._maxListeners = 0; // Default is 0 (unlimited)\n\n\t\tthis._eventLogger = options?.eventLogger;\n\n\t\tif (options?.throwOnEmitError !== undefined) {\n\t\t\tthis._throwOnEmitError = options.throwOnEmitError;\n\t\t}\n\n\t\tif (options?.throwOnEmptyListeners !== undefined) {\n\t\t\tthis._throwOnEmptyListeners = options.throwOnEmptyListeners;\n\t\t}\n\t}\n\n\t/**\n\t * Gets the event logger\n\t * @returns {Logger}\n\t */\n\tpublic get eventLogger(): Logger | undefined {\n\t\treturn this._eventLogger;\n\t}\n\n\t/**\n\t * Sets the event logger\n\t * @param {Logger} eventLogger\n\t */\n\tpublic set eventLogger(eventLogger: Logger | undefined) {\n\t\tthis._eventLogger = eventLogger;\n\t}\n\n\t/**\n\t * Gets whether an error should be thrown when an emit throws an error. Default is false and only emits an error event.\n\t * @returns {boolean}\n\t */\n\tpublic get throwOnEmitError(): boolean {\n\t\treturn this._throwOnEmitError;\n\t}\n\n\t/**\n\t * Sets whether an error should be thrown when an emit throws an error. Default is false and only emits an error event.\n\t * @param {boolean} value\n\t */\n\tpublic set throwOnEmitError(value: boolean) {\n\t\tthis._throwOnEmitError = value;\n\t}\n\n\t/**\n\t * Gets whether an error should be thrown when emitting 'error' event with no listeners. Default is false.\n\t * @returns {boolean}\n\t */\n\tpublic get throwOnEmptyListeners(): boolean {\n\t\treturn this._throwOnEmptyListeners;\n\t}\n\n\t/**\n\t * Sets whether an error should be thrown when emitting 'error' event with no listeners. Default is false.\n\t * @param {boolean} value\n\t */\n\tpublic set throwOnEmptyListeners(value: boolean) {\n\t\tthis._throwOnEmptyListeners = value;\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\tpublic once(\n\t\teventName: string | symbol,\n\t\tlistener: EventListener,\n\t): IEventEmitter {\n\t\tconst onceListener: EventListener = (...arguments_: any[]) => {\n\t\t\tthis.off(eventName as string, onceListener);\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\tpublic listenerCount(eventName?: string | symbol): number {\n\t\tif (eventName === undefined) {\n\t\t\tlet count = 0;\n\t\t\tfor (const entry of this._eventListeners.values()) {\n\t\t\t\tcount += typeof entry === \"function\" ? 1 : entry.length;\n\t\t\t}\n\n\t\t\treturn count;\n\t\t}\n\n\t\tconst entry = this._eventListeners.get(eventName);\n\t\tif (entry === undefined) {\n\t\t\treturn 0;\n\t\t}\n\n\t\treturn typeof entry === \"function\" ? 1 : entry.length;\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\tpublic eventNames(): Array<string | symbol> {\n\t\treturn [...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\tpublic rawListeners(event?: string | symbol): EventListener[] {\n\t\tif (event === undefined) {\n\t\t\treturn this.getAllListeners();\n\t\t}\n\n\t\tconst entry = this._eventListeners.get(event);\n\t\tif (entry === undefined) {\n\t\t\treturn [];\n\t\t}\n\n\t\treturn typeof entry === \"function\" ? [entry] : entry;\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\tpublic prependListener(\n\t\teventName: string | symbol,\n\t\tlistener: EventListener,\n\t): IEventEmitter {\n\t\tconst existing = this._eventListeners.get(eventName);\n\n\t\tif (existing === undefined) {\n\t\t\tthis._eventListeners.set(eventName, listener);\n\t\t} else if (typeof existing === \"function\") {\n\t\t\tthis._eventListeners.set(eventName, [listener, existing]);\n\t\t} else {\n\t\t\texisting.unshift(listener);\n\t\t}\n\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\tpublic prependOnceListener(\n\t\teventName: string | symbol,\n\t\tlistener: EventListener,\n\t): IEventEmitter {\n\t\tconst onceListener: EventListener = (...arguments_: any[]) => {\n\t\t\tthis.off(eventName as string, onceListener);\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(\n\t\tevent: string | symbol,\n\t\tlistener: EventListener,\n\t): 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\tconst existing = this._eventListeners.get(event);\n\n\t\tif (existing === undefined) {\n\t\t\tthis._eventListeners.set(event, listener);\n\t\t\treturn this;\n\t\t}\n\n\t\tif (typeof existing === \"function\") {\n\t\t\tconst arr = [existing, listener];\n\t\t\tthis._eventListeners.set(event, arr);\n\t\t\tif (this._maxListeners > 0 && arr.length > this._maxListeners) {\n\t\t\t\tconsole.warn(\n\t\t\t\t\t`MaxListenersExceededWarning: Possible event memory leak detected. ${arr.length} ${event as string} listeners added. Use setMaxListeners() to increase limit.`,\n\t\t\t\t);\n\t\t\t}\n\t\t} else {\n\t\t\texisting.push(listener);\n\t\t\tif (this._maxListeners > 0 && existing.length > this._maxListeners) {\n\t\t\t\tconsole.warn(\n\t\t\t\t\t`MaxListenersExceededWarning: Possible event memory leak detected. ${existing.length} ${event as string} listeners added. Use setMaxListeners() to increase limit.`,\n\t\t\t\t);\n\t\t\t}\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 entry = this._eventListeners.get(event);\n\t\tif (entry === undefined) {\n\t\t\treturn this;\n\t\t}\n\n\t\tif (typeof entry === \"function\") {\n\t\t\tif (entry === listener) {\n\t\t\t\tthis._eventListeners.delete(event);\n\t\t\t}\n\n\t\t\treturn this;\n\t\t}\n\n\t\tconst index = entry.indexOf(listener);\n\t\tif (index !== -1) {\n\t\t\tif (entry.length === 2) {\n\t\t\t\tthis._eventListeners.set(event, entry[1 - index]);\n\t\t\t\t/* v8 ignore start -- @preserve: single-element arrays are stored as functions */\n\t\t\t} else if (entry.length === 1) {\n\t\t\t\tthis._eventListeners.delete(event);\n\t\t\t\t/* v8 ignore stop */\n\t\t\t} else {\n\t\t\t\tentry.splice(index, 1);\n\t\t\t}\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 entry = this._eventListeners.get(event);\n\t\tconst argumentLength = arguments_.length;\n\n\t\tif (entry !== undefined) {\n\t\t\tif (typeof entry === \"function\") {\n\t\t\t\tif (argumentLength === 1) {\n\t\t\t\t\tentry(arguments_[0]);\n\t\t\t\t} else if (argumentLength === 2) {\n\t\t\t\t\tentry(arguments_[0], arguments_[1]);\n\t\t\t\t} else {\n\t\t\t\t\tentry(...arguments_);\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tconst len = entry.length;\n\t\t\t\tfor (let i = 0; i < len; i++) {\n\t\t\t\t\tif (argumentLength === 1) {\n\t\t\t\t\t\tentry[i](arguments_[0]);\n\t\t\t\t\t} else if (argumentLength === 2) {\n\t\t\t\t\t\tentry[i](arguments_[0], arguments_[1]);\n\t\t\t\t\t} else {\n\t\t\t\t\t\tentry[i](...arguments_);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tresult = true;\n\t\t}\n\n\t\t// send it to the logger\n\t\tif (this._eventLogger) {\n\t\t\tthis.sendToEventLogger(event, arguments_);\n\t\t}\n\n\t\tif (!result && event === ERROR_EVENT) {\n\t\t\tconst error =\n\t\t\t\targuments_[0] instanceof Error\n\t\t\t\t\t? arguments_[0]\n\t\t\t\t\t: new Error(`${arguments_[0]}`);\n\n\t\t\tif (this._throwOnEmitError || this._throwOnEmptyListeners) {\n\t\t\t\tthrow error;\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 | symbol): EventListener[] {\n\t\tconst entry = this._eventListeners.get(event);\n\t\tif (entry === undefined) {\n\t\t\treturn [];\n\t\t}\n\n\t\treturn typeof entry === \"function\" ? [entry] : entry;\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 | symbol): IEventEmitter {\n\t\tif (event !== undefined) {\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 < 0 ? 0 : n;\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\tconst result: EventListener[] = [];\n\t\tfor (const entry of this._eventListeners.values()) {\n\t\t\tif (typeof entry === \"function\") {\n\t\t\t\tresult.push(entry);\n\t\t\t} else {\n\t\t\t\tfor (let i = 0; i < entry.length; i++) {\n\t\t\t\t\tresult.push(entry[i]);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn result;\n\t}\n\n\t/**\n\t * Sends a log message using the configured logger based on the event name\n\t * @param {string | symbol} eventName - The event name that determines the log level\n\t * @param {unknown} data - The data to log\n\t */\n\tprivate sendToEventLogger(eventName: string | symbol, data: any): void {\n\t\t/* v8 ignore next 3 -- @preserve: guarded by caller */\n\t\tif (!this._eventLogger) {\n\t\t\treturn;\n\t\t}\n\n\t\tlet message: string;\n\t\t/* v8 ignore next -- @preserve */\n\t\tif (typeof data === \"string\") {\n\t\t\tmessage = data;\n\t\t} else if (\n\t\t\tArray.isArray(data) &&\n\t\t\tdata.length > 0 &&\n\t\t\tdata[0] instanceof Error\n\t\t) {\n\t\t\tmessage = data[0].message;\n\t\t\t/* v8 ignore next -- @preserve */\n\t\t} else if (data instanceof Error) {\n\t\t\tmessage = data.message;\n\t\t} else if (\n\t\t\tArray.isArray(data) &&\n\t\t\tdata.length > 0 &&\n\t\t\ttypeof data[0]?.message === \"string\"\n\t\t) {\n\t\t\tmessage = data[0].message;\n\t\t} else {\n\t\t\tmessage = JSON.stringify(data);\n\t\t}\n\n\t\tswitch (eventName) {\n\t\t\tcase \"error\": {\n\t\t\t\tthis._eventLogger.error?.(message, { event: eventName, data });\n\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\tcase \"warn\": {\n\t\t\t\tthis._eventLogger.warn?.(message, { event: eventName, data });\n\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\tcase \"trace\": {\n\t\t\t\tthis._eventLogger.trace?.(message, { event: eventName, data });\n\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\tcase \"debug\": {\n\t\t\t\tthis._eventLogger.debug?.(message, { event: eventName, data });\n\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\tcase \"fatal\": {\n\t\t\t\tthis._eventLogger.fatal?.(message, { event: eventName, data });\n\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\tdefault: {\n\t\t\t\tthis._eventLogger.info?.(message, { event: eventName, data });\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t}\n}\n","import type { HookFn, IHook } from \"../types.js\";\n\n/**\n * Concrete implementation of the IHook interface.\n * Provides a convenient class-based way to create hook entries.\n */\nexport class Hook implements IHook {\n\tpublic id?: string;\n\tpublic event: string;\n\tpublic handler: HookFn;\n\n\t/**\n\t * Creates a new Hook instance\n\t * @param {string} event - The event name for the hook\n\t * @param {HookFn} handler - The handler function for the hook\n\t * @param {string} [id] - Optional unique identifier for the hook\n\t */\n\tconstructor(event: string, handler: HookFn, id?: string) {\n\t\tthis.id = id;\n\t\tthis.event = event;\n\t\tthis.handler = handler;\n\t}\n}\n","import type {\n\tHookFn,\n\tIParallelHook,\n\tParallelHookFinalFn,\n\tParallelHookFn,\n\tParallelHookResult,\n} from \"../types.js\";\n\n/**\n * A ParallelHook fans a single invocation out to many registered hook\n * functions concurrently via Promise.allSettled, then calls a final\n * handler with the aggregated results — including failures — keyed by\n * the hook function reference for direct lookup. Each hook receives only\n * the original arguments; hooks do not see each other's results.\n *\n * Implements IHook for compatibility with Hookified.onHook(); the final\n * handler is called regardless of whether the parallel hook is invoked\n * directly or through Hookified.hook().\n *\n * Generics tighten the per-hook signature when every hook in the set\n * accepts the same `initialArgs` and returns the same result type.\n * Both default to `any` for backwards compatibility.\n *\n * @template TArgs - The shape of `initialArgs` passed to every hook\n * @template TResult - The result type each hook returns\n */\n// biome-ignore lint/suspicious/noExplicitAny: defaults preserve untyped use\nexport class ParallelHook<TArgs = any, TResult = any>\n\timplements IParallelHook<TArgs, TResult>\n{\n\tpublic id?: string;\n\tpublic event: string;\n\tpublic handler: HookFn;\n\tpublic hooks: ParallelHookFn<TArgs, TResult>[];\n\n\tprivate readonly _finalHandler: ParallelHookFinalFn<TArgs, TResult>;\n\n\t/**\n\t * Creates a new ParallelHook instance\n\t * @param {string} event - The event name for the hook\n\t * @param {ParallelHookFinalFn<TArgs, TResult>} finalHandler - Called once with `{ initialArgs, results }` after all parallel hooks settle\n\t * @param {string} [id] - Optional unique identifier for the hook\n\t */\n\tconstructor(\n\t\tevent: string,\n\t\tfinalHandler: ParallelHookFinalFn<TArgs, TResult>,\n\t\tid?: string,\n\t) {\n\t\tthis.id = id;\n\t\tthis.event = event;\n\t\tthis.hooks = [];\n\t\tthis._finalHandler = finalHandler;\n\n\t\t// biome-ignore lint/suspicious/noExplicitAny: this is for any parameter compatibility\n\t\tthis.handler = async (...arguments_: any[]) => {\n\t\t\tconst initialArgs: TArgs = (\n\t\t\t\targuments_.length === 1 ? arguments_[0] : arguments_\n\t\t\t) as TArgs;\n\n\t\t\t// Snapshot hooks at invocation time so concurrent addHook/removeHook\n\t\t\t// calls during the awaited Promise.allSettled cannot desync the\n\t\t\t// settled-index → hook mapping below.\n\t\t\tconst snapshot = [...this.hooks];\n\n\t\t\tconst settled = await Promise.allSettled(\n\t\t\t\tsnapshot.map((hook) =>\n\t\t\t\t\tPromise.resolve().then(() => hook({ initialArgs })),\n\t\t\t\t),\n\t\t\t);\n\n\t\t\tconst results = new Map<\n\t\t\t\tParallelHookFn<TArgs, TResult>,\n\t\t\t\tParallelHookResult<TResult>\n\t\t\t>();\n\t\t\tsnapshot.forEach((hook, index) => {\n\t\t\t\tconst outcome = settled[index];\n\t\t\t\tresults.set(\n\t\t\t\t\thook,\n\t\t\t\t\toutcome.status === \"fulfilled\"\n\t\t\t\t\t\t? { status: \"fulfilled\", result: outcome.value }\n\t\t\t\t\t\t: { status: \"rejected\", reason: outcome.reason },\n\t\t\t\t);\n\t\t\t});\n\n\t\t\tawait this._finalHandler({ initialArgs, results });\n\t\t};\n\t}\n\n\t/**\n\t * Adds a hook function to the parallel set\n\t * @param {ParallelHookFn<TArgs, TResult>} hook - The hook function to add\n\t */\n\tpublic addHook(hook: ParallelHookFn<TArgs, TResult>): void {\n\t\tthis.hooks.push(hook);\n\t}\n\n\t/**\n\t * Removes a specific hook function from the parallel set\n\t * @param {ParallelHookFn<TArgs, TResult>} hook - The hook function to remove\n\t * @returns {boolean} true if the hook was found and removed\n\t */\n\tpublic removeHook(hook: ParallelHookFn<TArgs, TResult>): boolean {\n\t\tconst index = this.hooks.indexOf(hook);\n\t\tif (index !== -1) {\n\t\t\tthis.hooks.splice(index, 1);\n\t\t\treturn true;\n\t\t}\n\n\t\treturn false;\n\t}\n}\n","import type {\n\tHookFn,\n\tIWaterfallHook,\n\tWaterfallHookFn,\n\tWaterfallHookResult,\n} from \"../types.js\";\n\n/**\n * A WaterfallHook chains multiple hook functions sequentially,\n * where each hook receives a context with the previous result,\n * initial arguments, and accumulated results. After all hooks\n * have executed, the final handler receives the transformed result.\n * Implements IHook for compatibility with Hookified.onHook().\n */\nexport class WaterfallHook implements IWaterfallHook {\n\tpublic id?: string;\n\tpublic event: string;\n\tpublic handler: HookFn;\n\tpublic hooks: WaterfallHookFn[];\n\n\tprivate readonly _finalHandler: WaterfallHookFn;\n\n\t/**\n\t * Creates a new WaterfallHook instance\n\t * @param {string} event - The event name for the hook\n\t * @param {WaterfallHookFn} finalHandler - The final handler function that receives the transformed result\n\t * @param {string} [id] - Optional unique identifier for the hook\n\t */\n\tconstructor(event: string, finalHandler: WaterfallHookFn, id?: string) {\n\t\tthis.id = id;\n\t\tthis.event = event;\n\t\tthis.hooks = [];\n\t\tthis._finalHandler = finalHandler;\n\n\t\t// biome-ignore lint/suspicious/noExplicitAny: this is for any parameter compatibility\n\t\tthis.handler = async (...arguments_: any[]) => {\n\t\t\t// biome-ignore lint/suspicious/noExplicitAny: waterfall result type varies through the chain\n\t\t\tconst initialArgs: any =\n\t\t\t\targuments_.length === 1 ? arguments_[0] : arguments_;\n\t\t\tconst results: WaterfallHookResult[] = [];\n\n\t\t\tfor (const hook of this.hooks) {\n\t\t\t\tconst result = await hook({ initialArgs, results: [...results] });\n\t\t\t\tresults.push({ hook, result });\n\t\t\t}\n\n\t\t\tawait this._finalHandler({ initialArgs, results: [...results] });\n\t\t};\n\t}\n\n\t/**\n\t * Adds a hook function to the end of the waterfall chain\n\t * @param {WaterfallHookFn} hook - The hook function to add\n\t */\n\tpublic addHook(hook: WaterfallHookFn): void {\n\t\tthis.hooks.push(hook);\n\t}\n\n\t/**\n\t * Removes a specific hook function from the waterfall chain\n\t * @param {WaterfallHookFn} hook - The hook function to remove\n\t * @returns {boolean} true if the hook was found and removed\n\t */\n\tpublic removeHook(hook: WaterfallHookFn): boolean {\n\t\tconst index = this.hooks.indexOf(hook);\n\t\tif (index !== -1) {\n\t\t\tthis.hooks.splice(index, 1);\n\t\t\treturn true;\n\t\t}\n\n\t\treturn false;\n\t}\n}\n","import { Eventified } from \"./eventified.js\";\nimport type {\n\tHookFn,\n\tHookifiedOptions,\n\tIHook,\n\tIWaterfallHook,\n\tOnHookOptions,\n\tPrependHookOptions,\n\tWaterfallHookContext,\n\tWaterfallHookFn,\n\tWaterfallHookResult,\n} from \"./types.js\";\n\nexport type {\n\tHookFn,\n\tHookifiedOptions,\n\tIHook,\n\tIWaterfallHook,\n\tOnHookOptions,\n\tPrependHookOptions,\n\tWaterfallHookContext,\n\tWaterfallHookFn,\n\tWaterfallHookResult,\n};\n\nexport class Hookified extends Eventified {\n\tprivate readonly _hooks: Map<string, IHook[]>;\n\tprivate _throwOnHookError = false;\n\tprivate _enforceBeforeAfter = false;\n\tprivate _deprecatedHooks: Map<string, string>;\n\tprivate _allowDeprecated = true;\n\tprivate _useHookClone = true;\n\n\tconstructor(options?: HookifiedOptions) {\n\t\tsuper({\n\t\t\teventLogger: options?.eventLogger,\n\t\t\tthrowOnEmitError: options?.throwOnEmitError,\n\t\t\tthrowOnEmptyListeners: options?.throwOnEmptyListeners,\n\t\t});\n\t\tthis._hooks = new Map();\n\t\tthis._deprecatedHooks = options?.deprecatedHooks\n\t\t\t? new Map(options.deprecatedHooks)\n\t\t\t: new Map();\n\n\t\tif (options?.throwOnHookError !== undefined) {\n\t\t\tthis._throwOnHookError = options.throwOnHookError;\n\t\t}\n\n\t\tif (options?.enforceBeforeAfter !== undefined) {\n\t\t\tthis._enforceBeforeAfter = options.enforceBeforeAfter;\n\t\t}\n\n\t\tif (options?.allowDeprecated !== undefined) {\n\t\t\tthis._allowDeprecated = options.allowDeprecated;\n\t\t}\n\n\t\tif (options?.useHookClone !== undefined) {\n\t\t\tthis._useHookClone = options.useHookClone;\n\t\t}\n\t}\n\n\t/**\n\t * Gets all hooks\n\t * @returns {Map<string, IHook[]>}\n\t */\n\tpublic get 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\tpublic get throwOnHookError() {\n\t\treturn this._throwOnHookError;\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\tpublic set throwOnHookError(value) {\n\t\tthis._throwOnHookError = value;\n\t}\n\n\t/**\n\t * Gets whether to enforce that all hook names start with 'before' or 'after'. Default is false.\n\t * @returns {boolean}\n\t * @default false\n\t */\n\tpublic get enforceBeforeAfter() {\n\t\treturn this._enforceBeforeAfter;\n\t}\n\n\t/**\n\t * Sets whether to enforce that all hook names start with 'before' or 'after'. Default is false.\n\t * @param {boolean} value\n\t */\n\tpublic set enforceBeforeAfter(value) {\n\t\tthis._enforceBeforeAfter = value;\n\t}\n\n\t/**\n\t * Gets the map of deprecated hook names to deprecation messages.\n\t * @returns {Map<string, string>}\n\t */\n\tpublic get deprecatedHooks() {\n\t\treturn this._deprecatedHooks;\n\t}\n\n\t/**\n\t * Sets the map of deprecated hook names to deprecation messages.\n\t * @param {Map<string, string>} value\n\t */\n\tpublic set deprecatedHooks(value) {\n\t\tthis._deprecatedHooks = value;\n\t}\n\n\t/**\n\t * Gets whether deprecated hooks are allowed to be registered and executed. Default is true.\n\t * @returns {boolean}\n\t */\n\tpublic get allowDeprecated() {\n\t\treturn this._allowDeprecated;\n\t}\n\n\t/**\n\t * Sets whether deprecated hooks are allowed to be registered and executed. Default is true.\n\t * @param {boolean} value\n\t */\n\tpublic set allowDeprecated(value) {\n\t\tthis._allowDeprecated = value;\n\t}\n\n\t/**\n\t * Gets whether hook objects are cloned before storing. Default is true.\n\t * @returns {boolean}\n\t */\n\tpublic get useHookClone() {\n\t\treturn this._useHookClone;\n\t}\n\n\t/**\n\t * Sets whether hook objects are cloned before storing. Default is true.\n\t * When false, the original IHook reference is stored directly.\n\t * @param {boolean} value\n\t */\n\tpublic set useHookClone(value) {\n\t\tthis._useHookClone = value;\n\t}\n\n\t/**\n\t * Adds a handler function for a specific event.\n\t * Supports both object and legacy signatures:\n\t * onHook({ event, handler }, options?)\n\t * onHook(event, handler)\n\t * To register multiple hooks at once, use {@link onHooks}.\n\t * @param {IHook | string} hookOrEvent - the hook object or event name\n\t * @param {OnHookOptions | HookFn} [optionsOrHandler] - options (when using object form) or handler function (when using string form)\n\t * @returns {IHook | undefined} the stored hook, or undefined if blocked by deprecation\n\t */\n\tpublic onHook(hook: IHook, options?: OnHookOptions): IHook | undefined;\n\tpublic onHook(event: string, handler: HookFn): IHook | undefined;\n\tpublic onHook(\n\t\thookOrEvent: IHook | string,\n\t\toptionsOrHandler?: OnHookOptions | HookFn,\n\t): IHook | undefined {\n\t\tlet hook: IHook;\n\t\tlet options: OnHookOptions | undefined;\n\n\t\tif (typeof hookOrEvent === \"string\") {\n\t\t\tif (typeof optionsOrHandler !== \"function\") {\n\t\t\t\tthrow new TypeError(\n\t\t\t\t\t\"When calling onHook(event, handler), the second argument must be a function\",\n\t\t\t\t);\n\t\t\t}\n\n\t\t\thook = { event: hookOrEvent, handler: optionsOrHandler };\n\t\t\toptions = undefined;\n\t\t} else {\n\t\t\thook = hookOrEvent;\n\t\t\toptions = optionsOrHandler as OnHookOptions | undefined;\n\t\t}\n\t\tthis.validateHookName(hook.event);\n\t\tif (!this.checkDeprecatedHook(hook.event)) {\n\t\t\treturn undefined; // Skip registration if deprecated hooks are not allowed\n\t\t}\n\n\t\tconst shouldClone = options?.useHookClone ?? this._useHookClone;\n\t\tconst entry: IHook = shouldClone\n\t\t\t? { id: hook.id, event: hook.event, handler: hook.handler }\n\t\t\t: hook;\n\n\t\tentry.id = entry.id ?? crypto.randomUUID();\n\n\t\tconst eventHandlers = this._hooks.get(hook.event);\n\t\tif (eventHandlers) {\n\t\t\t// Check for duplicate id — replace in-place if found\n\t\t\tconst existingIndex = eventHandlers.findIndex((h) => h.id === entry.id);\n\t\t\tif (existingIndex !== -1) {\n\t\t\t\teventHandlers[existingIndex] = entry;\n\t\t\t} else {\n\t\t\t\tconst position = options?.position ?? \"Bottom\";\n\t\t\t\tif (position === \"Top\") {\n\t\t\t\t\teventHandlers.unshift(entry);\n\t\t\t\t} else if (position === \"Bottom\") {\n\t\t\t\t\teventHandlers.push(entry);\n\t\t\t\t} else {\n\t\t\t\t\tconst index = Math.max(0, Math.min(position, eventHandlers.length));\n\t\t\t\t\teventHandlers.splice(index, 0, entry);\n\t\t\t\t}\n\t\t\t}\n\t\t} else {\n\t\t\tthis._hooks.set(hook.event, [entry]);\n\t\t}\n\n\t\treturn entry;\n\t}\n\n\t/**\n\t * Alias for onHook. This is provided for compatibility with other libraries that use the `addHook` method.\n\t * @param {string} event - the event name\n\t * @param {HookFn} handler - the handler function\n\t * @returns {void}\n\t */\n\tpublic addHook(event: string, handler: HookFn) {\n\t\tthis.onHook({ event, handler });\n\t}\n\n\t/**\n\t * Adds handler functions for specific events\n\t * @param {Array<IHook>} hooks\n\t * @param {OnHookOptions} [options] - optional per-call options (e.g., useHookClone override, position)\n\t * @returns {void}\n\t */\n\tpublic onHooks(hooks: IHook[], options?: OnHookOptions) {\n\t\tfor (const hook of hooks) {\n\t\t\tthis.onHook(hook, options);\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 * Equivalent to calling `onHook(hook, { position: \"Top\" })`.\n\t * @param {IHook} hook - the hook containing event name and handler\n\t * @param {PrependHookOptions} [options] - optional per-call options (e.g., useHookClone override)\n\t * @returns {IHook | undefined} the stored hook, or undefined if blocked by deprecation\n\t */\n\tpublic prependHook(\n\t\thook: IHook,\n\t\toptions?: PrependHookOptions,\n\t): IHook | undefined {\n\t\treturn this.onHook(hook, { ...options, position: \"Top\" });\n\t}\n\n\t/**\n\t * Adds a handler that only executes once for a specific event before all other handlers.\n\t * Equivalent to calling `onHook` with a self-removing wrapper and `{ position: \"Top\" }`.\n\t * @param {IHook} hook - the hook containing event name and handler\n\t * @param {PrependHookOptions} [options] - optional per-call options (e.g., useHookClone override)\n\t * @returns {IHook | undefined} the stored hook, or undefined if blocked by deprecation\n\t */\n\tpublic prependOnceHook(\n\t\thook: IHook,\n\t\toptions?: PrependHookOptions,\n\t): IHook | undefined {\n\t\t// biome-ignore lint/suspicious/noExplicitAny: this is for any parameter compatibility\n\t\tconst wrappedHandler = async (...arguments_: any[]) => {\n\t\t\tthis.removeHook({ event: hook.event, handler: wrappedHandler });\n\t\t\treturn hook.handler(...arguments_);\n\t\t};\n\n\t\treturn this.onHook(\n\t\t\t{ id: hook.id, event: hook.event, handler: wrappedHandler },\n\t\t\t{ ...options, position: \"Top\" },\n\t\t);\n\t}\n\n\t/**\n\t * Adds a handler that only executes once for a specific event\n\t * @param {IHook} hook - the hook containing event name and handler\n\t */\n\tpublic onceHook(hook: IHook) {\n\t\tthis.validateHookName(hook.event);\n\t\tif (!this.checkDeprecatedHook(hook.event)) {\n\t\t\treturn; // Skip registration if deprecated hooks are not allowed\n\t\t}\n\t\t// biome-ignore lint/suspicious/noExplicitAny: this is for any parameter compatibility\n\t\tconst wrappedHandler = async (...arguments_: any[]) => {\n\t\t\tthis.removeHook({ event: hook.event, handler: wrappedHandler });\n\t\t\treturn hook.handler(...arguments_);\n\t\t};\n\n\t\tthis.onHook({ id: hook.id, event: hook.event, handler: wrappedHandler });\n\t}\n\n\t/**\n\t * Removes a handler function for a specific event\n\t * @param {IHook} hook - the hook containing event name and handler to remove\n\t * @returns {IHook | undefined} the removed hook, or undefined if not found\n\t */\n\tpublic removeHook(hook: IHook): IHook | undefined {\n\t\tthis.validateHookName(hook.event);\n\t\tconst eventHandlers = this._hooks.get(hook.event);\n\t\tif (eventHandlers) {\n\t\t\tconst index = eventHandlers.findIndex((h) => h.handler === hook.handler);\n\t\t\tif (index !== -1) {\n\t\t\t\teventHandlers.splice(index, 1);\n\t\t\t\tif (eventHandlers.length === 0) {\n\t\t\t\t\tthis._hooks.delete(hook.event);\n\t\t\t\t}\n\n\t\t\t\treturn { event: hook.event, handler: hook.handler };\n\t\t\t}\n\t\t}\n\n\t\treturn undefined;\n\t}\n\n\t/**\n\t * Removes multiple hook handlers\n\t * @param {Array<IHook>} hooks\n\t * @returns {IHook[]} the hooks that were successfully removed\n\t */\n\tpublic removeHooks(hooks: IHook[]): IHook[] {\n\t\tconst removed: IHook[] = [];\n\t\tfor (const hook of hooks) {\n\t\t\tconst result = this.removeHook(hook);\n\t\t\tif (result) {\n\t\t\t\tremoved.push(result);\n\t\t\t}\n\t\t}\n\n\t\treturn removed;\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\tpublic async hook<T>(event: string, ...arguments_: T[]) {\n\t\tthis.validateHookName(event);\n\t\tif (!this.checkDeprecatedHook(event)) {\n\t\t\treturn; // Skip execution if deprecated hooks are not allowed\n\t\t}\n\t\tconst eventHandlers = this._hooks.get(event);\n\t\tif (eventHandlers) {\n\t\t\tfor (const hook of [...eventHandlers]) {\n\t\t\t\ttry {\n\t\t\t\t\tawait hook.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\n\t\t\t\t\tif (this._throwOnHookError) {\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 * Calls all synchronous handlers for a specific event.\n\t * Async handlers (declared with `async` keyword) are silently skipped.\n\t *\n\t * Note: The `hook` method is preferred as it executes both sync and async functions.\n\t * Use `hookSync` only when you specifically need synchronous execution.\n\t * @param {string} event\n\t * @param {T[]} arguments_\n\t * @returns {void}\n\t */\n\tpublic hookSync<T>(event: string, ...arguments_: T[]): void {\n\t\tthis.validateHookName(event);\n\t\tif (!this.checkDeprecatedHook(event)) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst eventHandlers = this._hooks.get(event);\n\t\tif (eventHandlers) {\n\t\t\tfor (const hook of [...eventHandlers]) {\n\t\t\t\t// Skip async functions silently\n\t\t\t\tif (hook.handler.constructor.name === \"AsyncFunction\") {\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\n\t\t\t\ttry {\n\t\t\t\t\thook.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\n\t\t\t\t\tif (this._throwOnHookError) {\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 * Prepends the word `before` to your hook. Example is event is `test`, the before hook is `before:test`.\n\t * @param {string} event - The event name\n\t * @param {T[]} arguments_ - The arguments to pass to the hook\n\t */\n\tpublic async beforeHook<T>(event: string, ...arguments_: T[]) {\n\t\tawait this.hook(`before:${event}`, ...arguments_);\n\t}\n\n\t/**\n\t * Prepends the word `after` to your hook. Example is event is `test`, the after hook is `after:test`.\n\t * @param {string} event - The event name\n\t * @param {T[]} arguments_ - The arguments to pass to the hook\n\t */\n\tpublic async afterHook<T>(event: string, ...arguments_: T[]) {\n\t\tawait this.hook(`after:${event}`, ...arguments_);\n\t}\n\n\t/**\n\t * Calls all handlers for a specific event. This is an alias for `hook` and is provided for\n\t * compatibility with other libraries that use the `callHook` method.\n\t * @param {string} event\n\t * @param {T[]} arguments_\n\t * @returns {Promise<void>}\n\t */\n\tpublic async callHook<T>(event: string, ...arguments_: T[]) {\n\t\tawait this.hook(event, ...arguments_);\n\t}\n\n\t/**\n\t * Gets all hooks for a specific event\n\t * @param {string} event\n\t * @returns {IHook[]}\n\t */\n\tpublic getHooks(event: string) {\n\t\tthis.validateHookName(event);\n\t\treturn this._hooks.get(event);\n\t}\n\n\t/**\n\t * Gets a specific hook by id, searching across all events\n\t * @param {string} id - the hook id\n\t * @returns {IHook | undefined} the hook if found, or undefined\n\t */\n\tpublic getHook(id: string): IHook | undefined {\n\t\tfor (const eventHandlers of this._hooks.values()) {\n\t\t\tconst found = eventHandlers.find((h) => h.id === id);\n\t\t\tif (found) {\n\t\t\t\treturn found;\n\t\t\t}\n\t\t}\n\n\t\treturn undefined;\n\t}\n\n\t/**\n\t * Removes one or more hooks by id, searching across all events\n\t * @param {string | string[]} id - the hook id or array of hook ids to remove\n\t * @returns {IHook | IHook[] | undefined} the removed hook(s), or undefined/empty array if not found\n\t */\n\tpublic removeHookById(id: string | string[]): IHook | IHook[] | undefined {\n\t\tif (Array.isArray(id)) {\n\t\t\tconst removed: IHook[] = [];\n\t\t\tfor (const singleId of id) {\n\t\t\t\tconst result = this.removeHookById(singleId);\n\t\t\t\tif (result && !Array.isArray(result)) {\n\t\t\t\t\tremoved.push(result);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\treturn removed;\n\t\t}\n\n\t\tfor (const [event, eventHandlers] of this._hooks.entries()) {\n\t\t\tconst index = eventHandlers.findIndex((h) => h.id === id);\n\t\t\tif (index !== -1) {\n\t\t\t\tconst [removed] = eventHandlers.splice(index, 1);\n\t\t\t\tif (eventHandlers.length === 0) {\n\t\t\t\t\tthis._hooks.delete(event);\n\t\t\t\t}\n\n\t\t\t\treturn removed;\n\t\t\t}\n\t\t}\n\n\t\treturn undefined;\n\t}\n\n\t/**\n\t * Removes all hooks\n\t * @returns {void}\n\t */\n\tpublic clearHooks() {\n\t\tthis._hooks.clear();\n\t}\n\n\t/**\n\t * Removes all hooks for a specific event and returns the removed hooks.\n\t * @param {string} event - The event name to remove hooks for.\n\t * @returns {IHook[]} the hooks that were removed\n\t */\n\tpublic removeEventHooks(event: string): IHook[] {\n\t\tthis.validateHookName(event);\n\t\tconst eventHandlers = this._hooks.get(event);\n\t\tif (eventHandlers) {\n\t\t\tconst removed = [...eventHandlers];\n\t\t\tthis._hooks.delete(event);\n\t\t\treturn removed;\n\t\t}\n\n\t\treturn [];\n\t}\n\n\t/**\n\t * Validates hook event name if enforceBeforeAfter is enabled\n\t * @param {string} event - The event name to validate\n\t * @throws {Error} If enforceBeforeAfter is true and event doesn't start with 'before' or 'after'\n\t */\n\tprivate validateHookName(event: string): void {\n\t\tif (this._enforceBeforeAfter) {\n\t\t\tconst eventValue = event.trim().toLocaleLowerCase();\n\t\t\tif (!eventValue.startsWith(\"before\") && !eventValue.startsWith(\"after\")) {\n\t\t\t\tthrow new Error(\n\t\t\t\t\t`Hook event \"${event}\" must start with \"before\" or \"after\" when enforceBeforeAfter is enabled`,\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Checks if a hook is deprecated and emits a warning if it is\n\t * @param {string} event - The event name to check\n\t * @returns {boolean} - Returns true if the hook should proceed, false if it should be blocked\n\t */\n\tprivate checkDeprecatedHook(event: string): boolean {\n\t\tif (this._deprecatedHooks.has(event)) {\n\t\t\tconst message = this._deprecatedHooks.get(event);\n\t\t\tconst warningMessage = `Hook \"${event}\" is deprecated${message ? `: ${message}` : \"\"}`;\n\n\t\t\t// Emit deprecation warning event\n\t\t\tthis.emit(\"warn\", { hook: event, message: warningMessage });\n\n\t\t\t// Return false if deprecated hooks are not allowed\n\t\t\treturn this._allowDeprecated;\n\t\t}\n\t\treturn true;\n\t}\n}\n\nexport { Eventified } from \"./eventified.js\";\nexport { Hook } from \"./hooks/hook.js\";\nexport { ParallelHook } from \"./hooks/parallel-hook.js\";\nexport { WaterfallHook } from \"./hooks/waterfall-hook.js\";\nexport type {\n\tEventEmitterOptions,\n\tEventListener,\n\tIEventEmitter,\n\tIParallelHook,\n\tLogger,\n\tParallelHookContext,\n\tParallelHookFinalContext,\n\tParallelHookFinalFn,\n\tParallelHookFn,\n\tParallelHookResult,\n} from \"./types.js\";\n"],"mappings":"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"}
{"version":3,"file":"index.global.js","names":[],"sources":["../../src/eventified.ts","../../src/hooks/hook.ts","../../src/hooks/parallel-hook.ts","../../src/hooks/waterfall-hook.ts","../../src/index.ts"],"sourcesContent":["// biome-ignore-all lint/suspicious/noExplicitAny: this is for event emitter compatibility\nimport type {\n\tEventEmitterOptions,\n\tEventListener,\n\tIEventEmitter,\n\tLogger,\n} from \"./types.js\";\n\nexport type { EventEmitterOptions, EventListener, IEventEmitter };\n\nconst ERROR_EVENT = \"error\";\n\nexport class Eventified implements IEventEmitter {\n\tprivate readonly _eventListeners: Map<\n\t\tstring | symbol,\n\t\tEventListener | EventListener[]\n\t>;\n\tprivate _maxListeners: number;\n\tprivate _eventLogger?: Logger;\n\tprivate _throwOnEmitError = false;\n\tprivate _throwOnEmptyListeners = true;\n\n\tconstructor(options?: EventEmitterOptions) {\n\t\tthis._eventListeners = new Map<\n\t\t\tstring | symbol,\n\t\t\tEventListener | EventListener[]\n\t\t>();\n\t\tthis._maxListeners = 0; // Default is 0 (unlimited)\n\n\t\tthis._eventLogger = options?.eventLogger;\n\n\t\tif (options?.throwOnEmitError !== undefined) {\n\t\t\tthis._throwOnEmitError = options.throwOnEmitError;\n\t\t}\n\n\t\tif (options?.throwOnEmptyListeners !== undefined) {\n\t\t\tthis._throwOnEmptyListeners = options.throwOnEmptyListeners;\n\t\t}\n\t}\n\n\t/**\n\t * Gets the event logger\n\t * @returns {Logger}\n\t */\n\tpublic get eventLogger(): Logger | undefined {\n\t\treturn this._eventLogger;\n\t}\n\n\t/**\n\t * Sets the event logger\n\t * @param {Logger} eventLogger\n\t */\n\tpublic set eventLogger(eventLogger: Logger | undefined) {\n\t\tthis._eventLogger = eventLogger;\n\t}\n\n\t/**\n\t * Gets whether an error should be thrown when an emit throws an error. Default is false and only emits an error event.\n\t * @returns {boolean}\n\t */\n\tpublic get throwOnEmitError(): boolean {\n\t\treturn this._throwOnEmitError;\n\t}\n\n\t/**\n\t * Sets whether an error should be thrown when an emit throws an error. Default is false and only emits an error event.\n\t * @param {boolean} value\n\t */\n\tpublic set throwOnEmitError(value: boolean) {\n\t\tthis._throwOnEmitError = value;\n\t}\n\n\t/**\n\t * Gets whether an error should be thrown when emitting 'error' event with no listeners. Default is false.\n\t * @returns {boolean}\n\t */\n\tpublic get throwOnEmptyListeners(): boolean {\n\t\treturn this._throwOnEmptyListeners;\n\t}\n\n\t/**\n\t * Sets whether an error should be thrown when emitting 'error' event with no listeners. Default is false.\n\t * @param {boolean} value\n\t */\n\tpublic set throwOnEmptyListeners(value: boolean) {\n\t\tthis._throwOnEmptyListeners = value;\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\tpublic once(\n\t\teventName: string | symbol,\n\t\tlistener: EventListener,\n\t): IEventEmitter {\n\t\tconst onceListener: EventListener = (...arguments_: any[]) => {\n\t\t\tthis.off(eventName as string, onceListener);\n\t\t\tlistener(...arguments_);\n\t\t};\n\n\t\t// Keep a reference to the original listener so that off()/removeListener()\n\t\t// can remove the once wrapper when called with the original reference.\n\t\t(onceListener as any)._originalListener = listener;\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\tpublic listenerCount(eventName?: string | symbol): number {\n\t\tif (eventName === undefined) {\n\t\t\tlet count = 0;\n\t\t\tfor (const entry of this._eventListeners.values()) {\n\t\t\t\tcount += typeof entry === \"function\" ? 1 : entry.length;\n\t\t\t}\n\n\t\t\treturn count;\n\t\t}\n\n\t\tconst entry = this._eventListeners.get(eventName);\n\t\tif (entry === undefined) {\n\t\t\treturn 0;\n\t\t}\n\n\t\treturn typeof entry === \"function\" ? 1 : entry.length;\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\tpublic eventNames(): Array<string | symbol> {\n\t\treturn [...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\tpublic rawListeners(event?: string | symbol): EventListener[] {\n\t\tif (event === undefined) {\n\t\t\treturn this.getAllListeners();\n\t\t}\n\n\t\tconst entry = this._eventListeners.get(event);\n\t\tif (entry === undefined) {\n\t\t\treturn [];\n\t\t}\n\n\t\treturn typeof entry === \"function\" ? [entry] : entry;\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\tpublic prependListener(\n\t\teventName: string | symbol,\n\t\tlistener: EventListener,\n\t): IEventEmitter {\n\t\tconst existing = this._eventListeners.get(eventName);\n\n\t\tif (existing === undefined) {\n\t\t\tthis._eventListeners.set(eventName, listener);\n\t\t} else if (typeof existing === \"function\") {\n\t\t\tthis._eventListeners.set(eventName, [listener, existing]);\n\t\t} else {\n\t\t\texisting.unshift(listener);\n\t\t}\n\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\tpublic prependOnceListener(\n\t\teventName: string | symbol,\n\t\tlistener: EventListener,\n\t): IEventEmitter {\n\t\tconst onceListener: EventListener = (...arguments_: any[]) => {\n\t\t\tthis.off(eventName as string, onceListener);\n\t\t\tlistener(...arguments_);\n\t\t};\n\n\t\t// Keep a reference to the original listener so that off()/removeListener()\n\t\t// can remove the once wrapper when called with the original reference.\n\t\t(onceListener as any)._originalListener = listener;\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(\n\t\tevent: string | symbol,\n\t\tlistener: EventListener,\n\t): 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\tconst existing = this._eventListeners.get(event);\n\n\t\tif (existing === undefined) {\n\t\t\tthis._eventListeners.set(event, listener);\n\t\t\treturn this;\n\t\t}\n\n\t\tif (typeof existing === \"function\") {\n\t\t\tconst arr = [existing, listener];\n\t\t\tthis._eventListeners.set(event, arr);\n\t\t\tif (this._maxListeners > 0 && arr.length > this._maxListeners) {\n\t\t\t\tconsole.warn(\n\t\t\t\t\t`MaxListenersExceededWarning: Possible event memory leak detected. ${arr.length} ${event as string} listeners added. Use setMaxListeners() to increase limit.`,\n\t\t\t\t);\n\t\t\t}\n\t\t} else {\n\t\t\texisting.push(listener);\n\t\t\tif (this._maxListeners > 0 && existing.length > this._maxListeners) {\n\t\t\t\tconsole.warn(\n\t\t\t\t\t`MaxListenersExceededWarning: Possible event memory leak detected. ${existing.length} ${event as string} listeners added. Use setMaxListeners() to increase limit.`,\n\t\t\t\t);\n\t\t\t}\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 * Determines whether a stored listener matches the listener provided to off().\n\t * A match occurs when the references are identical, or when the stored listener\n\t * is a once-wrapper whose original listener equals the provided reference.\n\t * @param {EventListener} stored - the listener currently stored\n\t * @param {EventListener} target - the listener passed to off()\n\t * @returns {boolean} true if the stored listener should be removed\n\t */\n\tprivate matchesListener(\n\t\tstored: EventListener,\n\t\ttarget: EventListener,\n\t): boolean {\n\t\tif (stored === target) {\n\t\t\treturn true;\n\t\t}\n\n\t\t// Only treat this as a once-wrapper match when an original listener was\n\t\t// actually recorded. Without this guard, calling off() with an undefined\n\t\t// target would match any normal listener (whose _originalListener is also\n\t\t// undefined) and remove it.\n\t\tconst original = (stored as any)._originalListener;\n\t\treturn original !== undefined && original === target;\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 entry = this._eventListeners.get(event);\n\t\tif (entry === undefined) {\n\t\t\treturn this;\n\t\t}\n\n\t\tif (typeof entry === \"function\") {\n\t\t\tif (this.matchesListener(entry, listener)) {\n\t\t\t\tthis._eventListeners.delete(event);\n\t\t\t}\n\n\t\t\treturn this;\n\t\t}\n\n\t\t// Prefer an exact reference match before falling back to once-wrapper\n\t\t// matching, so a normal listener is never left behind when an identical\n\t\t// once-wrapper happens to precede it in the array.\n\t\tlet index = entry.indexOf(listener);\n\t\tif (index === -1) {\n\t\t\tindex = entry.findIndex((stored) =>\n\t\t\t\tthis.matchesListener(stored, listener),\n\t\t\t);\n\t\t}\n\n\t\tif (index !== -1) {\n\t\t\tif (entry.length === 2) {\n\t\t\t\tthis._eventListeners.set(event, entry[1 - index]);\n\t\t\t\t/* v8 ignore start -- @preserve: single-element arrays are stored as functions */\n\t\t\t} else if (entry.length === 1) {\n\t\t\t\tthis._eventListeners.delete(event);\n\t\t\t\t/* v8 ignore stop */\n\t\t\t} else {\n\t\t\t\tentry.splice(index, 1);\n\t\t\t}\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 entry = this._eventListeners.get(event);\n\t\tconst argumentLength = arguments_.length;\n\n\t\tif (entry !== undefined) {\n\t\t\tif (typeof entry === \"function\") {\n\t\t\t\tif (argumentLength === 1) {\n\t\t\t\t\tentry(arguments_[0]);\n\t\t\t\t} else if (argumentLength === 2) {\n\t\t\t\t\tentry(arguments_[0], arguments_[1]);\n\t\t\t\t} else {\n\t\t\t\t\tentry(...arguments_);\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\t// Iterate a snapshot so listeners removed (or added) during the\n\t\t\t\t// emit — e.g. a once wrapper removing itself, or a listener calling\n\t\t\t\t// off() — cannot corrupt the in-flight iteration. This matches\n\t\t\t\t// Node's EventEmitter behavior. The single-listener fast path above\n\t\t\t\t// needs no copy since it cannot be mid-iteration mutated.\n\t\t\t\tconst listeners = entry.slice();\n\t\t\t\tconst len = listeners.length;\n\t\t\t\tfor (let i = 0; i < len; i++) {\n\t\t\t\t\tif (argumentLength === 1) {\n\t\t\t\t\t\tlisteners[i](arguments_[0]);\n\t\t\t\t\t} else if (argumentLength === 2) {\n\t\t\t\t\t\tlisteners[i](arguments_[0], arguments_[1]);\n\t\t\t\t\t} else {\n\t\t\t\t\t\tlisteners[i](...arguments_);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tresult = true;\n\t\t}\n\n\t\t// send it to the logger\n\t\tif (this._eventLogger) {\n\t\t\tthis.sendToEventLogger(event, arguments_);\n\t\t}\n\n\t\tif (!result && event === ERROR_EVENT) {\n\t\t\tconst error =\n\t\t\t\targuments_[0] instanceof Error\n\t\t\t\t\t? arguments_[0]\n\t\t\t\t\t: new Error(`${arguments_[0]}`);\n\n\t\t\tif (this._throwOnEmitError || this._throwOnEmptyListeners) {\n\t\t\t\tthrow error;\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 | symbol): EventListener[] {\n\t\tconst entry = this._eventListeners.get(event);\n\t\tif (entry === undefined) {\n\t\t\treturn [];\n\t\t}\n\n\t\treturn typeof entry === \"function\" ? [entry] : entry;\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 | symbol): IEventEmitter {\n\t\tif (event !== undefined) {\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 < 0 ? 0 : n;\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\tconst result: EventListener[] = [];\n\t\tfor (const entry of this._eventListeners.values()) {\n\t\t\tif (typeof entry === \"function\") {\n\t\t\t\tresult.push(entry);\n\t\t\t} else {\n\t\t\t\tfor (let i = 0; i < entry.length; i++) {\n\t\t\t\t\tresult.push(entry[i]);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn result;\n\t}\n\n\t/**\n\t * Sends a log message using the configured logger based on the event name\n\t * @param {string | symbol} eventName - The event name that determines the log level\n\t * @param {unknown} data - The data to log\n\t */\n\tprivate sendToEventLogger(eventName: string | symbol, data: any): void {\n\t\t/* v8 ignore next 3 -- @preserve: guarded by caller */\n\t\tif (!this._eventLogger) {\n\t\t\treturn;\n\t\t}\n\n\t\tlet message: string;\n\t\t/* v8 ignore next -- @preserve */\n\t\tif (typeof data === \"string\") {\n\t\t\tmessage = data;\n\t\t} else if (\n\t\t\tArray.isArray(data) &&\n\t\t\tdata.length > 0 &&\n\t\t\tdata[0] instanceof Error\n\t\t) {\n\t\t\tmessage = data[0].message;\n\t\t\t/* v8 ignore next -- @preserve */\n\t\t} else if (data instanceof Error) {\n\t\t\tmessage = data.message;\n\t\t} else if (\n\t\t\tArray.isArray(data) &&\n\t\t\tdata.length > 0 &&\n\t\t\ttypeof data[0]?.message === \"string\"\n\t\t) {\n\t\t\tmessage = data[0].message;\n\t\t} else {\n\t\t\tmessage = JSON.stringify(data);\n\t\t}\n\n\t\tswitch (eventName) {\n\t\t\tcase \"error\": {\n\t\t\t\tthis._eventLogger.error?.(message, { event: eventName, data });\n\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\tcase \"warn\": {\n\t\t\t\tthis._eventLogger.warn?.(message, { event: eventName, data });\n\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\tcase \"trace\": {\n\t\t\t\tthis._eventLogger.trace?.(message, { event: eventName, data });\n\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\tcase \"debug\": {\n\t\t\t\tthis._eventLogger.debug?.(message, { event: eventName, data });\n\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\tcase \"fatal\": {\n\t\t\t\tthis._eventLogger.fatal?.(message, { event: eventName, data });\n\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\tdefault: {\n\t\t\t\tthis._eventLogger.info?.(message, { event: eventName, data });\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t}\n}\n","import type { HookFn, IHook } from \"../types.js\";\n\n/**\n * Concrete implementation of the IHook interface.\n * Provides a convenient class-based way to create hook entries.\n */\nexport class Hook implements IHook {\n\tpublic id?: string;\n\tpublic event: string;\n\tpublic handler: HookFn;\n\n\t/**\n\t * Creates a new Hook instance\n\t * @param {string} event - The event name for the hook\n\t * @param {HookFn} handler - The handler function for the hook\n\t * @param {string} [id] - Optional unique identifier for the hook\n\t */\n\tconstructor(event: string, handler: HookFn, id?: string) {\n\t\tthis.id = id;\n\t\tthis.event = event;\n\t\tthis.handler = handler;\n\t}\n}\n","import type {\n\tHookFn,\n\tIParallelHook,\n\tParallelHookFinalFn,\n\tParallelHookFn,\n\tParallelHookResult,\n} from \"../types.js\";\n\n/**\n * A ParallelHook fans a single invocation out to many registered hook\n * functions concurrently via Promise.allSettled, then calls a final\n * handler with the aggregated results — including failures — keyed by\n * the hook function reference for direct lookup. Each hook receives only\n * the original arguments; hooks do not see each other's results.\n *\n * Implements IHook for compatibility with Hookified.onHook(); the final\n * handler is called regardless of whether the parallel hook is invoked\n * directly or through Hookified.hook().\n *\n * Generics tighten the per-hook signature when every hook in the set\n * accepts the same `initialArgs` and returns the same result type.\n * Both default to `any` for backwards compatibility.\n *\n * @template TArgs - The shape of `initialArgs` passed to every hook\n * @template TResult - The result type each hook returns\n */\n// biome-ignore lint/suspicious/noExplicitAny: defaults preserve untyped use\nexport class ParallelHook<TArgs = any, TResult = any>\n\timplements IParallelHook<TArgs, TResult>\n{\n\tpublic id?: string;\n\tpublic event: string;\n\tpublic handler: HookFn;\n\tpublic hooks: ParallelHookFn<TArgs, TResult>[];\n\n\tprivate readonly _finalHandler: ParallelHookFinalFn<TArgs, TResult>;\n\n\t/**\n\t * Creates a new ParallelHook instance\n\t * @param {string} event - The event name for the hook\n\t * @param {ParallelHookFinalFn<TArgs, TResult>} finalHandler - Called once with `{ initialArgs, results }` after all parallel hooks settle\n\t * @param {string} [id] - Optional unique identifier for the hook\n\t */\n\tconstructor(\n\t\tevent: string,\n\t\tfinalHandler: ParallelHookFinalFn<TArgs, TResult>,\n\t\tid?: string,\n\t) {\n\t\tthis.id = id;\n\t\tthis.event = event;\n\t\tthis.hooks = [];\n\t\tthis._finalHandler = finalHandler;\n\n\t\t// biome-ignore lint/suspicious/noExplicitAny: this is for any parameter compatibility\n\t\tthis.handler = async (...arguments_: any[]) => {\n\t\t\tconst initialArgs: TArgs = (\n\t\t\t\targuments_.length === 1 ? arguments_[0] : arguments_\n\t\t\t) as TArgs;\n\n\t\t\t// Snapshot hooks at invocation time so concurrent addHook/removeHook\n\t\t\t// calls during the awaited Promise.allSettled cannot desync the\n\t\t\t// settled-index → hook mapping below.\n\t\t\tconst snapshot = [...this.hooks];\n\n\t\t\tconst settled = await Promise.allSettled(\n\t\t\t\tsnapshot.map((hook) =>\n\t\t\t\t\tPromise.resolve().then(() => hook({ initialArgs })),\n\t\t\t\t),\n\t\t\t);\n\n\t\t\tconst results = new Map<\n\t\t\t\tParallelHookFn<TArgs, TResult>,\n\t\t\t\tParallelHookResult<TResult>\n\t\t\t>();\n\t\t\tsnapshot.forEach((hook, index) => {\n\t\t\t\tconst outcome = settled[index];\n\t\t\t\tresults.set(\n\t\t\t\t\thook,\n\t\t\t\t\toutcome.status === \"fulfilled\"\n\t\t\t\t\t\t? { status: \"fulfilled\", result: outcome.value }\n\t\t\t\t\t\t: { status: \"rejected\", reason: outcome.reason },\n\t\t\t\t);\n\t\t\t});\n\n\t\t\tawait this._finalHandler({ initialArgs, results });\n\t\t};\n\t}\n\n\t/**\n\t * Adds a hook function to the parallel set\n\t * @param {ParallelHookFn<TArgs, TResult>} hook - The hook function to add\n\t */\n\tpublic addHook(hook: ParallelHookFn<TArgs, TResult>): void {\n\t\tthis.hooks.push(hook);\n\t}\n\n\t/**\n\t * Removes a specific hook function from the parallel set\n\t * @param {ParallelHookFn<TArgs, TResult>} hook - The hook function to remove\n\t * @returns {boolean} true if the hook was found and removed\n\t */\n\tpublic removeHook(hook: ParallelHookFn<TArgs, TResult>): boolean {\n\t\tconst index = this.hooks.indexOf(hook);\n\t\tif (index !== -1) {\n\t\t\tthis.hooks.splice(index, 1);\n\t\t\treturn true;\n\t\t}\n\n\t\treturn false;\n\t}\n}\n","import type {\n\tHookFn,\n\tIWaterfallHook,\n\tWaterfallHookFn,\n\tWaterfallHookResult,\n} from \"../types.js\";\n\n/**\n * A WaterfallHook chains multiple hook functions sequentially,\n * where each hook receives a context with the previous result,\n * initial arguments, and accumulated results. After all hooks\n * have executed, the final handler receives the transformed result.\n * Implements IHook for compatibility with Hookified.onHook().\n */\nexport class WaterfallHook implements IWaterfallHook {\n\tpublic id?: string;\n\tpublic event: string;\n\tpublic handler: HookFn;\n\tpublic hooks: WaterfallHookFn[];\n\n\tprivate readonly _finalHandler: WaterfallHookFn;\n\n\t/**\n\t * Creates a new WaterfallHook instance\n\t * @param {string} event - The event name for the hook\n\t * @param {WaterfallHookFn} finalHandler - The final handler function that receives the transformed result\n\t * @param {string} [id] - Optional unique identifier for the hook\n\t */\n\tconstructor(event: string, finalHandler: WaterfallHookFn, id?: string) {\n\t\tthis.id = id;\n\t\tthis.event = event;\n\t\tthis.hooks = [];\n\t\tthis._finalHandler = finalHandler;\n\n\t\t// biome-ignore lint/suspicious/noExplicitAny: this is for any parameter compatibility\n\t\tthis.handler = async (...arguments_: any[]) => {\n\t\t\t// biome-ignore lint/suspicious/noExplicitAny: waterfall result type varies through the chain\n\t\t\tconst initialArgs: any =\n\t\t\t\targuments_.length === 1 ? arguments_[0] : arguments_;\n\t\t\tconst results: WaterfallHookResult[] = [];\n\n\t\t\tfor (const hook of this.hooks) {\n\t\t\t\tconst result = await hook({ initialArgs, results: [...results] });\n\t\t\t\tresults.push({ hook, result });\n\t\t\t}\n\n\t\t\tawait this._finalHandler({ initialArgs, results: [...results] });\n\t\t};\n\t}\n\n\t/**\n\t * Adds a hook function to the end of the waterfall chain\n\t * @param {WaterfallHookFn} hook - The hook function to add\n\t */\n\tpublic addHook(hook: WaterfallHookFn): void {\n\t\tthis.hooks.push(hook);\n\t}\n\n\t/**\n\t * Removes a specific hook function from the waterfall chain\n\t * @param {WaterfallHookFn} hook - The hook function to remove\n\t * @returns {boolean} true if the hook was found and removed\n\t */\n\tpublic removeHook(hook: WaterfallHookFn): boolean {\n\t\tconst index = this.hooks.indexOf(hook);\n\t\tif (index !== -1) {\n\t\t\tthis.hooks.splice(index, 1);\n\t\t\treturn true;\n\t\t}\n\n\t\treturn false;\n\t}\n}\n","import { Eventified } from \"./eventified.js\";\nimport type {\n\tHookFn,\n\tHookifiedOptions,\n\tIHook,\n\tIWaterfallHook,\n\tOnHookOptions,\n\tPrependHookOptions,\n\tWaterfallHookContext,\n\tWaterfallHookFn,\n\tWaterfallHookResult,\n} from \"./types.js\";\n\nexport type {\n\tHookFn,\n\tHookifiedOptions,\n\tIHook,\n\tIWaterfallHook,\n\tOnHookOptions,\n\tPrependHookOptions,\n\tWaterfallHookContext,\n\tWaterfallHookFn,\n\tWaterfallHookResult,\n};\n\nexport class Hookified extends Eventified {\n\tprivate readonly _hooks: Map<string, IHook[]>;\n\tprivate _throwOnHookError = false;\n\tprivate _enforceBeforeAfter = false;\n\tprivate _deprecatedHooks: Map<string, string>;\n\tprivate _allowDeprecated = true;\n\tprivate _useHookClone = true;\n\n\tconstructor(options?: HookifiedOptions) {\n\t\tsuper({\n\t\t\teventLogger: options?.eventLogger,\n\t\t\tthrowOnEmitError: options?.throwOnEmitError,\n\t\t\tthrowOnEmptyListeners: options?.throwOnEmptyListeners,\n\t\t});\n\t\tthis._hooks = new Map();\n\t\tthis._deprecatedHooks = options?.deprecatedHooks\n\t\t\t? new Map(options.deprecatedHooks)\n\t\t\t: new Map();\n\n\t\tif (options?.throwOnHookError !== undefined) {\n\t\t\tthis._throwOnHookError = options.throwOnHookError;\n\t\t}\n\n\t\tif (options?.enforceBeforeAfter !== undefined) {\n\t\t\tthis._enforceBeforeAfter = options.enforceBeforeAfter;\n\t\t}\n\n\t\tif (options?.allowDeprecated !== undefined) {\n\t\t\tthis._allowDeprecated = options.allowDeprecated;\n\t\t}\n\n\t\tif (options?.useHookClone !== undefined) {\n\t\t\tthis._useHookClone = options.useHookClone;\n\t\t}\n\t}\n\n\t/**\n\t * Gets all hooks\n\t * @returns {Map<string, IHook[]>}\n\t */\n\tpublic get 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\tpublic get throwOnHookError() {\n\t\treturn this._throwOnHookError;\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\tpublic set throwOnHookError(value) {\n\t\tthis._throwOnHookError = value;\n\t}\n\n\t/**\n\t * Gets whether to enforce that all hook names start with 'before' or 'after'. Default is false.\n\t * @returns {boolean}\n\t * @default false\n\t */\n\tpublic get enforceBeforeAfter() {\n\t\treturn this._enforceBeforeAfter;\n\t}\n\n\t/**\n\t * Sets whether to enforce that all hook names start with 'before' or 'after'. Default is false.\n\t * @param {boolean} value\n\t */\n\tpublic set enforceBeforeAfter(value) {\n\t\tthis._enforceBeforeAfter = value;\n\t}\n\n\t/**\n\t * Gets the map of deprecated hook names to deprecation messages.\n\t * @returns {Map<string, string>}\n\t */\n\tpublic get deprecatedHooks() {\n\t\treturn this._deprecatedHooks;\n\t}\n\n\t/**\n\t * Sets the map of deprecated hook names to deprecation messages.\n\t * @param {Map<string, string>} value\n\t */\n\tpublic set deprecatedHooks(value) {\n\t\tthis._deprecatedHooks = value;\n\t}\n\n\t/**\n\t * Gets whether deprecated hooks are allowed to be registered and executed. Default is true.\n\t * @returns {boolean}\n\t */\n\tpublic get allowDeprecated() {\n\t\treturn this._allowDeprecated;\n\t}\n\n\t/**\n\t * Sets whether deprecated hooks are allowed to be registered and executed. Default is true.\n\t * @param {boolean} value\n\t */\n\tpublic set allowDeprecated(value) {\n\t\tthis._allowDeprecated = value;\n\t}\n\n\t/**\n\t * Gets whether hook objects are cloned before storing. Default is true.\n\t * @returns {boolean}\n\t */\n\tpublic get useHookClone() {\n\t\treturn this._useHookClone;\n\t}\n\n\t/**\n\t * Sets whether hook objects are cloned before storing. Default is true.\n\t * When false, the original IHook reference is stored directly.\n\t * @param {boolean} value\n\t */\n\tpublic set useHookClone(value) {\n\t\tthis._useHookClone = value;\n\t}\n\n\t/**\n\t * Adds a handler function for a specific event.\n\t * Supports both object and legacy signatures:\n\t * onHook({ event, handler }, options?)\n\t * onHook(event, handler)\n\t * To register multiple hooks at once, use {@link onHooks}.\n\t * @param {IHook | string} hookOrEvent - the hook object or event name\n\t * @param {OnHookOptions | HookFn} [optionsOrHandler] - options (when using object form) or handler function (when using string form)\n\t * @returns {IHook | undefined} the stored hook, or undefined if blocked by deprecation\n\t */\n\tpublic onHook(hook: IHook, options?: OnHookOptions): IHook | undefined;\n\tpublic onHook(event: string, handler: HookFn): IHook | undefined;\n\tpublic onHook(\n\t\thookOrEvent: IHook | string,\n\t\toptionsOrHandler?: OnHookOptions | HookFn,\n\t): IHook | undefined {\n\t\tlet hook: IHook;\n\t\tlet options: OnHookOptions | undefined;\n\n\t\tif (typeof hookOrEvent === \"string\") {\n\t\t\tif (typeof optionsOrHandler !== \"function\") {\n\t\t\t\tthrow new TypeError(\n\t\t\t\t\t\"When calling onHook(event, handler), the second argument must be a function\",\n\t\t\t\t);\n\t\t\t}\n\n\t\t\thook = { event: hookOrEvent, handler: optionsOrHandler };\n\t\t\toptions = undefined;\n\t\t} else {\n\t\t\thook = hookOrEvent;\n\t\t\toptions = optionsOrHandler as OnHookOptions | undefined;\n\t\t}\n\t\tthis.validateHookName(hook.event);\n\t\tif (!this.checkDeprecatedHook(hook.event)) {\n\t\t\treturn undefined; // Skip registration if deprecated hooks are not allowed\n\t\t}\n\n\t\tconst shouldClone = options?.useHookClone ?? this._useHookClone;\n\t\tconst entry: IHook = shouldClone\n\t\t\t? { id: hook.id, event: hook.event, handler: hook.handler }\n\t\t\t: hook;\n\n\t\tentry.id = entry.id ?? crypto.randomUUID();\n\n\t\tconst eventHandlers = this._hooks.get(hook.event);\n\t\tif (eventHandlers) {\n\t\t\t// Check for duplicate id — replace in-place if found\n\t\t\tconst existingIndex = eventHandlers.findIndex((h) => h.id === entry.id);\n\t\t\tif (existingIndex !== -1) {\n\t\t\t\teventHandlers[existingIndex] = entry;\n\t\t\t} else {\n\t\t\t\tconst position = options?.position ?? \"Bottom\";\n\t\t\t\tif (position === \"Top\") {\n\t\t\t\t\teventHandlers.unshift(entry);\n\t\t\t\t} else if (position === \"Bottom\") {\n\t\t\t\t\teventHandlers.push(entry);\n\t\t\t\t} else {\n\t\t\t\t\tconst index = Math.max(0, Math.min(position, eventHandlers.length));\n\t\t\t\t\teventHandlers.splice(index, 0, entry);\n\t\t\t\t}\n\t\t\t}\n\t\t} else {\n\t\t\tthis._hooks.set(hook.event, [entry]);\n\t\t}\n\n\t\treturn entry;\n\t}\n\n\t/**\n\t * Alias for onHook. This is provided for compatibility with other libraries that use the `addHook` method.\n\t * @param {string} event - the event name\n\t * @param {HookFn} handler - the handler function\n\t * @returns {void}\n\t */\n\tpublic addHook(event: string, handler: HookFn) {\n\t\tthis.onHook({ event, handler });\n\t}\n\n\t/**\n\t * Adds handler functions for specific events\n\t * @param {Array<IHook>} hooks\n\t * @param {OnHookOptions} [options] - optional per-call options (e.g., useHookClone override, position)\n\t * @returns {void}\n\t */\n\tpublic onHooks(hooks: IHook[], options?: OnHookOptions) {\n\t\tfor (const hook of hooks) {\n\t\t\tthis.onHook(hook, options);\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 * Equivalent to calling `onHook(hook, { position: \"Top\" })`.\n\t * @param {IHook} hook - the hook containing event name and handler\n\t * @param {PrependHookOptions} [options] - optional per-call options (e.g., useHookClone override)\n\t * @returns {IHook | undefined} the stored hook, or undefined if blocked by deprecation\n\t */\n\tpublic prependHook(\n\t\thook: IHook,\n\t\toptions?: PrependHookOptions,\n\t): IHook | undefined {\n\t\treturn this.onHook(hook, { ...options, position: \"Top\" });\n\t}\n\n\t/**\n\t * Adds a handler that only executes once for a specific event before all other handlers.\n\t * Equivalent to calling `onHook` with a self-removing wrapper and `{ position: \"Top\" }`.\n\t * @param {IHook} hook - the hook containing event name and handler\n\t * @param {PrependHookOptions} [options] - optional per-call options (e.g., useHookClone override)\n\t * @returns {IHook | undefined} the stored hook, or undefined if blocked by deprecation\n\t */\n\tpublic prependOnceHook(\n\t\thook: IHook,\n\t\toptions?: PrependHookOptions,\n\t): IHook | undefined {\n\t\t// biome-ignore lint/suspicious/noExplicitAny: this is for any parameter compatibility\n\t\tconst wrappedHandler = async (...arguments_: any[]) => {\n\t\t\tthis.removeHook({ event: hook.event, handler: wrappedHandler });\n\t\t\treturn hook.handler(...arguments_);\n\t\t};\n\n\t\t// Keep a reference to the original handler so removeHook() can remove the\n\t\t// once wrapper when called with the original handler reference.\n\t\t// biome-ignore lint/suspicious/noExplicitAny: attaching metadata to the wrapper\n\t\t(wrappedHandler as any)._originalHandler = hook.handler;\n\n\t\treturn this.onHook(\n\t\t\t{ id: hook.id, event: hook.event, handler: wrappedHandler },\n\t\t\t{ ...options, position: \"Top\" },\n\t\t);\n\t}\n\n\t/**\n\t * Adds a handler that only executes once for a specific event\n\t * @param {IHook} hook - the hook containing event name and handler\n\t */\n\tpublic onceHook(hook: IHook) {\n\t\tthis.validateHookName(hook.event);\n\t\tif (!this.checkDeprecatedHook(hook.event)) {\n\t\t\treturn; // Skip registration if deprecated hooks are not allowed\n\t\t}\n\t\t// biome-ignore lint/suspicious/noExplicitAny: this is for any parameter compatibility\n\t\tconst wrappedHandler = async (...arguments_: any[]) => {\n\t\t\tthis.removeHook({ event: hook.event, handler: wrappedHandler });\n\t\t\treturn hook.handler(...arguments_);\n\t\t};\n\n\t\t// Keep a reference to the original handler so removeHook() can remove the\n\t\t// once wrapper when called with the original handler reference.\n\t\t// biome-ignore lint/suspicious/noExplicitAny: attaching metadata to the wrapper\n\t\t(wrappedHandler as any)._originalHandler = hook.handler;\n\n\t\tthis.onHook({ id: hook.id, event: hook.event, handler: wrappedHandler });\n\t}\n\n\t/**\n\t * Removes a handler function for a specific event\n\t * @param {IHook} hook - the hook containing event name and handler to remove\n\t * @returns {IHook | undefined} the removed hook, or undefined if not found\n\t */\n\tpublic removeHook(hook: IHook): IHook | undefined {\n\t\tthis.validateHookName(hook.event);\n\t\tconst eventHandlers = this._hooks.get(hook.event);\n\t\tif (eventHandlers) {\n\t\t\t// Prefer an exact handler match before falling back to once-wrapper\n\t\t\t// matching, so a normal hook is never left behind when an identical\n\t\t\t// once-wrapper happens to precede it in the array.\n\t\t\tlet index = eventHandlers.findIndex((h) => h.handler === hook.handler);\n\t\t\tif (index === -1) {\n\t\t\t\tindex = eventHandlers.findIndex((h) => {\n\t\t\t\t\t// Match once-wrappers by their original handler reference. The\n\t\t\t\t\t// undefined guard prevents a normal hook (whose _originalHandler\n\t\t\t\t\t// is also undefined) from matching when hook.handler is undefined.\n\t\t\t\t\t// biome-ignore lint/suspicious/noExplicitAny: wrapper metadata lookup\n\t\t\t\t\tconst original = (h.handler as any)._originalHandler;\n\t\t\t\t\treturn original !== undefined && original === hook.handler;\n\t\t\t\t});\n\t\t\t}\n\t\t\tif (index !== -1) {\n\t\t\t\teventHandlers.splice(index, 1);\n\t\t\t\tif (eventHandlers.length === 0) {\n\t\t\t\t\tthis._hooks.delete(hook.event);\n\t\t\t\t}\n\n\t\t\t\treturn { event: hook.event, handler: hook.handler };\n\t\t\t}\n\t\t}\n\n\t\treturn undefined;\n\t}\n\n\t/**\n\t * Removes multiple hook handlers\n\t * @param {Array<IHook>} hooks\n\t * @returns {IHook[]} the hooks that were successfully removed\n\t */\n\tpublic removeHooks(hooks: IHook[]): IHook[] {\n\t\tconst removed: IHook[] = [];\n\t\tfor (const hook of hooks) {\n\t\t\tconst result = this.removeHook(hook);\n\t\t\tif (result) {\n\t\t\t\tremoved.push(result);\n\t\t\t}\n\t\t}\n\n\t\treturn removed;\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\tpublic async hook<T>(event: string, ...arguments_: T[]) {\n\t\tthis.validateHookName(event);\n\t\tif (!this.checkDeprecatedHook(event)) {\n\t\t\treturn; // Skip execution if deprecated hooks are not allowed\n\t\t}\n\t\tconst eventHandlers = this._hooks.get(event);\n\t\tif (eventHandlers) {\n\t\t\tfor (const hook of [...eventHandlers]) {\n\t\t\t\ttry {\n\t\t\t\t\tawait hook.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\n\t\t\t\t\tif (this._throwOnHookError) {\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 * Calls all synchronous handlers for a specific event.\n\t * Async handlers (declared with `async` keyword) are silently skipped.\n\t *\n\t * Note: The `hook` method is preferred as it executes both sync and async functions.\n\t * Use `hookSync` only when you specifically need synchronous execution.\n\t * @param {string} event\n\t * @param {T[]} arguments_\n\t * @returns {void}\n\t */\n\tpublic hookSync<T>(event: string, ...arguments_: T[]): void {\n\t\tthis.validateHookName(event);\n\t\tif (!this.checkDeprecatedHook(event)) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst eventHandlers = this._hooks.get(event);\n\t\tif (eventHandlers) {\n\t\t\tfor (const hook of [...eventHandlers]) {\n\t\t\t\t// Skip async functions silently\n\t\t\t\tif (hook.handler.constructor.name === \"AsyncFunction\") {\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\n\t\t\t\ttry {\n\t\t\t\t\thook.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\n\t\t\t\t\tif (this._throwOnHookError) {\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 * Prepends the word `before` to your hook. Example is event is `test`, the before hook is `before:test`.\n\t * @param {string} event - The event name\n\t * @param {T[]} arguments_ - The arguments to pass to the hook\n\t */\n\tpublic async beforeHook<T>(event: string, ...arguments_: T[]) {\n\t\tawait this.hook(`before:${event}`, ...arguments_);\n\t}\n\n\t/**\n\t * Prepends the word `after` to your hook. Example is event is `test`, the after hook is `after:test`.\n\t * @param {string} event - The event name\n\t * @param {T[]} arguments_ - The arguments to pass to the hook\n\t */\n\tpublic async afterHook<T>(event: string, ...arguments_: T[]) {\n\t\tawait this.hook(`after:${event}`, ...arguments_);\n\t}\n\n\t/**\n\t * Calls all handlers for a specific event. This is an alias for `hook` and is provided for\n\t * compatibility with other libraries that use the `callHook` method.\n\t * @param {string} event\n\t * @param {T[]} arguments_\n\t * @returns {Promise<void>}\n\t */\n\tpublic async callHook<T>(event: string, ...arguments_: T[]) {\n\t\tawait this.hook(event, ...arguments_);\n\t}\n\n\t/**\n\t * Gets all hooks for a specific event\n\t * @param {string} event\n\t * @returns {IHook[]}\n\t */\n\tpublic getHooks(event: string) {\n\t\tthis.validateHookName(event);\n\t\treturn this._hooks.get(event);\n\t}\n\n\t/**\n\t * Gets a specific hook by id, searching across all events\n\t * @param {string} id - the hook id\n\t * @returns {IHook | undefined} the hook if found, or undefined\n\t */\n\tpublic getHook(id: string): IHook | undefined {\n\t\tfor (const eventHandlers of this._hooks.values()) {\n\t\t\tconst found = eventHandlers.find((h) => h.id === id);\n\t\t\tif (found) {\n\t\t\t\treturn found;\n\t\t\t}\n\t\t}\n\n\t\treturn undefined;\n\t}\n\n\t/**\n\t * Removes one or more hooks by id, searching across all events\n\t * @param {string | string[]} id - the hook id or array of hook ids to remove\n\t * @returns {IHook | IHook[] | undefined} the removed hook(s), or undefined/empty array if not found\n\t */\n\tpublic removeHookById(id: string | string[]): IHook | IHook[] | undefined {\n\t\tif (Array.isArray(id)) {\n\t\t\tconst removed: IHook[] = [];\n\t\t\tfor (const singleId of id) {\n\t\t\t\tconst result = this.removeHookById(singleId);\n\t\t\t\tif (result && !Array.isArray(result)) {\n\t\t\t\t\tremoved.push(result);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\treturn removed;\n\t\t}\n\n\t\tfor (const [event, eventHandlers] of this._hooks.entries()) {\n\t\t\tconst index = eventHandlers.findIndex((h) => h.id === id);\n\t\t\tif (index !== -1) {\n\t\t\t\tconst [removed] = eventHandlers.splice(index, 1);\n\t\t\t\tif (eventHandlers.length === 0) {\n\t\t\t\t\tthis._hooks.delete(event);\n\t\t\t\t}\n\n\t\t\t\treturn removed;\n\t\t\t}\n\t\t}\n\n\t\treturn undefined;\n\t}\n\n\t/**\n\t * Removes all hooks\n\t * @returns {void}\n\t */\n\tpublic clearHooks() {\n\t\tthis._hooks.clear();\n\t}\n\n\t/**\n\t * Removes all hooks for a specific event and returns the removed hooks.\n\t * @param {string} event - The event name to remove hooks for.\n\t * @returns {IHook[]} the hooks that were removed\n\t */\n\tpublic removeEventHooks(event: string): IHook[] {\n\t\tthis.validateHookName(event);\n\t\tconst eventHandlers = this._hooks.get(event);\n\t\tif (eventHandlers) {\n\t\t\tconst removed = [...eventHandlers];\n\t\t\tthis._hooks.delete(event);\n\t\t\treturn removed;\n\t\t}\n\n\t\treturn [];\n\t}\n\n\t/**\n\t * Validates hook event name if enforceBeforeAfter is enabled\n\t * @param {string} event - The event name to validate\n\t * @throws {Error} If enforceBeforeAfter is true and event doesn't start with 'before' or 'after'\n\t */\n\tprivate validateHookName(event: string): void {\n\t\tif (this._enforceBeforeAfter) {\n\t\t\tconst eventValue = event.trim().toLocaleLowerCase();\n\t\t\tif (!eventValue.startsWith(\"before\") && !eventValue.startsWith(\"after\")) {\n\t\t\t\tthrow new Error(\n\t\t\t\t\t`Hook event \"${event}\" must start with \"before\" or \"after\" when enforceBeforeAfter is enabled`,\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Checks if a hook is deprecated and emits a warning if it is\n\t * @param {string} event - The event name to check\n\t * @returns {boolean} - Returns true if the hook should proceed, false if it should be blocked\n\t */\n\tprivate checkDeprecatedHook(event: string): boolean {\n\t\tif (this._deprecatedHooks.has(event)) {\n\t\t\tconst message = this._deprecatedHooks.get(event);\n\t\t\tconst warningMessage = `Hook \"${event}\" is deprecated${message ? `: ${message}` : \"\"}`;\n\n\t\t\t// Emit deprecation warning event\n\t\t\tthis.emit(\"warn\", { hook: event, message: warningMessage });\n\n\t\t\t// Return false if deprecated hooks are not allowed\n\t\t\treturn this._allowDeprecated;\n\t\t}\n\t\treturn true;\n\t}\n}\n\nexport { Eventified } from \"./eventified.js\";\nexport { Hook } from \"./hooks/hook.js\";\nexport { ParallelHook } from \"./hooks/parallel-hook.js\";\nexport { WaterfallHook } from \"./hooks/waterfall-hook.js\";\nexport type {\n\tEventEmitterOptions,\n\tEventListener,\n\tIEventEmitter,\n\tIParallelHook,\n\tLogger,\n\tParallelHookContext,\n\tParallelHookFinalContext,\n\tParallelHookFinalFn,\n\tParallelHookFn,\n\tParallelHookResult,\n} from \"./types.js\";\n"],"mappings":"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"}

@@ -1,2 +0,2 @@

//#region \0@oxc-project+runtime@0.130.0/helpers/typeof.js
//#region \0@oxc-project+runtime@0.135.0/helpers/esm/typeof.js
function _typeof(o) {

@@ -11,3 +11,3 @@ "@babel/helpers - typeof";

//#endregion
//#region \0@oxc-project+runtime@0.130.0/helpers/toPrimitive.js
//#region \0@oxc-project+runtime@0.135.0/helpers/esm/toPrimitive.js
function toPrimitive(t, r) {

@@ -24,3 +24,3 @@ if ("object" != _typeof(t) || !t) return t;

//#endregion
//#region \0@oxc-project+runtime@0.130.0/helpers/toPropertyKey.js
//#region \0@oxc-project+runtime@0.135.0/helpers/esm/toPropertyKey.js
function toPropertyKey(t) {

@@ -31,3 +31,3 @@ var i = toPrimitive(t, "string");

//#endregion
//#region \0@oxc-project+runtime@0.130.0/helpers/defineProperty.js
//#region \0@oxc-project+runtime@0.135.0/helpers/esm/defineProperty.js
function _defineProperty(e, r, t) {

@@ -110,2 +110,3 @@ return (r = toPropertyKey(r)) in e ? Object.defineProperty(e, r, {

};
onceListener._originalListener = listener;
this.on(eventName, onceListener);

@@ -171,2 +172,3 @@ return this;

};
onceListener._originalListener = listener;
this.prependListener(eventName, onceListener);

@@ -225,2 +227,15 @@ return this;

/**
* Determines whether a stored listener matches the listener provided to off().
* A match occurs when the references are identical, or when the stored listener
* is a once-wrapper whose original listener equals the provided reference.
* @param {EventListener} stored - the listener currently stored
* @param {EventListener} target - the listener passed to off()
* @returns {boolean} true if the stored listener should be removed
*/
matchesListener(stored, target) {
if (stored === target) return true;
const original = stored._originalListener;
return original !== void 0 && original === target;
}
/**
* Removes a listener for a specific event

@@ -235,6 +250,7 @@ * @param {string | symbol} event

if (typeof entry === "function") {
if (entry === listener) this._eventListeners.delete(event);
if (this.matchesListener(entry, listener)) this._eventListeners.delete(event);
return this;
}
const index = entry.indexOf(listener);
let index = entry.indexOf(listener);
if (index === -1) index = entry.findIndex((stored) => this.matchesListener(stored, listener));
if (index !== -1) if (entry.length === 2) this._eventListeners.set(event, entry[1 - index]);

@@ -260,6 +276,7 @@ else if (entry.length === 1) this._eventListeners.delete(event);

else {
const len = entry.length;
for (let i = 0; i < len; i++) if (argumentLength === 1) entry[i](arguments_[0]);
else if (argumentLength === 2) entry[i](arguments_[0], arguments_[1]);
else entry[i](...arguments_);
const listeners = entry.slice();
const len = listeners.length;
for (let i = 0; i < len; i++) if (argumentLength === 1) listeners[i](arguments_[0]);
else if (argumentLength === 2) listeners[i](arguments_[0], arguments_[1]);
else listeners[i](...arguments_);
}

@@ -723,2 +740,3 @@ result = true;

};
wrappedHandler._originalHandler = hook.handler;
return this.onHook({

@@ -747,2 +765,3 @@ id: hook.id,

};
wrappedHandler._originalHandler = hook.handler;
this.onHook({

@@ -763,3 +782,7 @@ id: hook.id,

if (eventHandlers) {
const index = eventHandlers.findIndex((h) => h.handler === hook.handler);
let index = eventHandlers.findIndex((h) => h.handler === hook.handler);
if (index === -1) index = eventHandlers.findIndex((h) => {
const original = h.handler._originalHandler;
return original !== void 0 && original === hook.handler;
});
if (index !== -1) {

@@ -766,0 +789,0 @@ eventHandlers.splice(index, 1);

@@ -1,1 +0,1 @@

{"version":3,"file":"index.js","names":[],"sources":["../../src/eventified.ts","../../src/hooks/hook.ts","../../src/hooks/parallel-hook.ts","../../src/hooks/waterfall-hook.ts","../../src/index.ts"],"sourcesContent":["// biome-ignore-all lint/suspicious/noExplicitAny: this is for event emitter compatibility\nimport type {\n\tEventEmitterOptions,\n\tEventListener,\n\tIEventEmitter,\n\tLogger,\n} from \"./types.js\";\n\nexport type { EventEmitterOptions, EventListener, IEventEmitter };\n\nconst ERROR_EVENT = \"error\";\n\nexport class Eventified implements IEventEmitter {\n\tprivate readonly _eventListeners: Map<\n\t\tstring | symbol,\n\t\tEventListener | EventListener[]\n\t>;\n\tprivate _maxListeners: number;\n\tprivate _eventLogger?: Logger;\n\tprivate _throwOnEmitError = false;\n\tprivate _throwOnEmptyListeners = true;\n\n\tconstructor(options?: EventEmitterOptions) {\n\t\tthis._eventListeners = new Map<\n\t\t\tstring | symbol,\n\t\t\tEventListener | EventListener[]\n\t\t>();\n\t\tthis._maxListeners = 0; // Default is 0 (unlimited)\n\n\t\tthis._eventLogger = options?.eventLogger;\n\n\t\tif (options?.throwOnEmitError !== undefined) {\n\t\t\tthis._throwOnEmitError = options.throwOnEmitError;\n\t\t}\n\n\t\tif (options?.throwOnEmptyListeners !== undefined) {\n\t\t\tthis._throwOnEmptyListeners = options.throwOnEmptyListeners;\n\t\t}\n\t}\n\n\t/**\n\t * Gets the event logger\n\t * @returns {Logger}\n\t */\n\tpublic get eventLogger(): Logger | undefined {\n\t\treturn this._eventLogger;\n\t}\n\n\t/**\n\t * Sets the event logger\n\t * @param {Logger} eventLogger\n\t */\n\tpublic set eventLogger(eventLogger: Logger | undefined) {\n\t\tthis._eventLogger = eventLogger;\n\t}\n\n\t/**\n\t * Gets whether an error should be thrown when an emit throws an error. Default is false and only emits an error event.\n\t * @returns {boolean}\n\t */\n\tpublic get throwOnEmitError(): boolean {\n\t\treturn this._throwOnEmitError;\n\t}\n\n\t/**\n\t * Sets whether an error should be thrown when an emit throws an error. Default is false and only emits an error event.\n\t * @param {boolean} value\n\t */\n\tpublic set throwOnEmitError(value: boolean) {\n\t\tthis._throwOnEmitError = value;\n\t}\n\n\t/**\n\t * Gets whether an error should be thrown when emitting 'error' event with no listeners. Default is false.\n\t * @returns {boolean}\n\t */\n\tpublic get throwOnEmptyListeners(): boolean {\n\t\treturn this._throwOnEmptyListeners;\n\t}\n\n\t/**\n\t * Sets whether an error should be thrown when emitting 'error' event with no listeners. Default is false.\n\t * @param {boolean} value\n\t */\n\tpublic set throwOnEmptyListeners(value: boolean) {\n\t\tthis._throwOnEmptyListeners = value;\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\tpublic once(\n\t\teventName: string | symbol,\n\t\tlistener: EventListener,\n\t): IEventEmitter {\n\t\tconst onceListener: EventListener = (...arguments_: any[]) => {\n\t\t\tthis.off(eventName as string, onceListener);\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\tpublic listenerCount(eventName?: string | symbol): number {\n\t\tif (eventName === undefined) {\n\t\t\tlet count = 0;\n\t\t\tfor (const entry of this._eventListeners.values()) {\n\t\t\t\tcount += typeof entry === \"function\" ? 1 : entry.length;\n\t\t\t}\n\n\t\t\treturn count;\n\t\t}\n\n\t\tconst entry = this._eventListeners.get(eventName);\n\t\tif (entry === undefined) {\n\t\t\treturn 0;\n\t\t}\n\n\t\treturn typeof entry === \"function\" ? 1 : entry.length;\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\tpublic eventNames(): Array<string | symbol> {\n\t\treturn [...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\tpublic rawListeners(event?: string | symbol): EventListener[] {\n\t\tif (event === undefined) {\n\t\t\treturn this.getAllListeners();\n\t\t}\n\n\t\tconst entry = this._eventListeners.get(event);\n\t\tif (entry === undefined) {\n\t\t\treturn [];\n\t\t}\n\n\t\treturn typeof entry === \"function\" ? [entry] : entry;\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\tpublic prependListener(\n\t\teventName: string | symbol,\n\t\tlistener: EventListener,\n\t): IEventEmitter {\n\t\tconst existing = this._eventListeners.get(eventName);\n\n\t\tif (existing === undefined) {\n\t\t\tthis._eventListeners.set(eventName, listener);\n\t\t} else if (typeof existing === \"function\") {\n\t\t\tthis._eventListeners.set(eventName, [listener, existing]);\n\t\t} else {\n\t\t\texisting.unshift(listener);\n\t\t}\n\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\tpublic prependOnceListener(\n\t\teventName: string | symbol,\n\t\tlistener: EventListener,\n\t): IEventEmitter {\n\t\tconst onceListener: EventListener = (...arguments_: any[]) => {\n\t\t\tthis.off(eventName as string, onceListener);\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(\n\t\tevent: string | symbol,\n\t\tlistener: EventListener,\n\t): 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\tconst existing = this._eventListeners.get(event);\n\n\t\tif (existing === undefined) {\n\t\t\tthis._eventListeners.set(event, listener);\n\t\t\treturn this;\n\t\t}\n\n\t\tif (typeof existing === \"function\") {\n\t\t\tconst arr = [existing, listener];\n\t\t\tthis._eventListeners.set(event, arr);\n\t\t\tif (this._maxListeners > 0 && arr.length > this._maxListeners) {\n\t\t\t\tconsole.warn(\n\t\t\t\t\t`MaxListenersExceededWarning: Possible event memory leak detected. ${arr.length} ${event as string} listeners added. Use setMaxListeners() to increase limit.`,\n\t\t\t\t);\n\t\t\t}\n\t\t} else {\n\t\t\texisting.push(listener);\n\t\t\tif (this._maxListeners > 0 && existing.length > this._maxListeners) {\n\t\t\t\tconsole.warn(\n\t\t\t\t\t`MaxListenersExceededWarning: Possible event memory leak detected. ${existing.length} ${event as string} listeners added. Use setMaxListeners() to increase limit.`,\n\t\t\t\t);\n\t\t\t}\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 entry = this._eventListeners.get(event);\n\t\tif (entry === undefined) {\n\t\t\treturn this;\n\t\t}\n\n\t\tif (typeof entry === \"function\") {\n\t\t\tif (entry === listener) {\n\t\t\t\tthis._eventListeners.delete(event);\n\t\t\t}\n\n\t\t\treturn this;\n\t\t}\n\n\t\tconst index = entry.indexOf(listener);\n\t\tif (index !== -1) {\n\t\t\tif (entry.length === 2) {\n\t\t\t\tthis._eventListeners.set(event, entry[1 - index]);\n\t\t\t\t/* v8 ignore start -- @preserve: single-element arrays are stored as functions */\n\t\t\t} else if (entry.length === 1) {\n\t\t\t\tthis._eventListeners.delete(event);\n\t\t\t\t/* v8 ignore stop */\n\t\t\t} else {\n\t\t\t\tentry.splice(index, 1);\n\t\t\t}\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 entry = this._eventListeners.get(event);\n\t\tconst argumentLength = arguments_.length;\n\n\t\tif (entry !== undefined) {\n\t\t\tif (typeof entry === \"function\") {\n\t\t\t\tif (argumentLength === 1) {\n\t\t\t\t\tentry(arguments_[0]);\n\t\t\t\t} else if (argumentLength === 2) {\n\t\t\t\t\tentry(arguments_[0], arguments_[1]);\n\t\t\t\t} else {\n\t\t\t\t\tentry(...arguments_);\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tconst len = entry.length;\n\t\t\t\tfor (let i = 0; i < len; i++) {\n\t\t\t\t\tif (argumentLength === 1) {\n\t\t\t\t\t\tentry[i](arguments_[0]);\n\t\t\t\t\t} else if (argumentLength === 2) {\n\t\t\t\t\t\tentry[i](arguments_[0], arguments_[1]);\n\t\t\t\t\t} else {\n\t\t\t\t\t\tentry[i](...arguments_);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tresult = true;\n\t\t}\n\n\t\t// send it to the logger\n\t\tif (this._eventLogger) {\n\t\t\tthis.sendToEventLogger(event, arguments_);\n\t\t}\n\n\t\tif (!result && event === ERROR_EVENT) {\n\t\t\tconst error =\n\t\t\t\targuments_[0] instanceof Error\n\t\t\t\t\t? arguments_[0]\n\t\t\t\t\t: new Error(`${arguments_[0]}`);\n\n\t\t\tif (this._throwOnEmitError || this._throwOnEmptyListeners) {\n\t\t\t\tthrow error;\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 | symbol): EventListener[] {\n\t\tconst entry = this._eventListeners.get(event);\n\t\tif (entry === undefined) {\n\t\t\treturn [];\n\t\t}\n\n\t\treturn typeof entry === \"function\" ? [entry] : entry;\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 | symbol): IEventEmitter {\n\t\tif (event !== undefined) {\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 < 0 ? 0 : n;\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\tconst result: EventListener[] = [];\n\t\tfor (const entry of this._eventListeners.values()) {\n\t\t\tif (typeof entry === \"function\") {\n\t\t\t\tresult.push(entry);\n\t\t\t} else {\n\t\t\t\tfor (let i = 0; i < entry.length; i++) {\n\t\t\t\t\tresult.push(entry[i]);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn result;\n\t}\n\n\t/**\n\t * Sends a log message using the configured logger based on the event name\n\t * @param {string | symbol} eventName - The event name that determines the log level\n\t * @param {unknown} data - The data to log\n\t */\n\tprivate sendToEventLogger(eventName: string | symbol, data: any): void {\n\t\t/* v8 ignore next 3 -- @preserve: guarded by caller */\n\t\tif (!this._eventLogger) {\n\t\t\treturn;\n\t\t}\n\n\t\tlet message: string;\n\t\t/* v8 ignore next -- @preserve */\n\t\tif (typeof data === \"string\") {\n\t\t\tmessage = data;\n\t\t} else if (\n\t\t\tArray.isArray(data) &&\n\t\t\tdata.length > 0 &&\n\t\t\tdata[0] instanceof Error\n\t\t) {\n\t\t\tmessage = data[0].message;\n\t\t\t/* v8 ignore next -- @preserve */\n\t\t} else if (data instanceof Error) {\n\t\t\tmessage = data.message;\n\t\t} else if (\n\t\t\tArray.isArray(data) &&\n\t\t\tdata.length > 0 &&\n\t\t\ttypeof data[0]?.message === \"string\"\n\t\t) {\n\t\t\tmessage = data[0].message;\n\t\t} else {\n\t\t\tmessage = JSON.stringify(data);\n\t\t}\n\n\t\tswitch (eventName) {\n\t\t\tcase \"error\": {\n\t\t\t\tthis._eventLogger.error?.(message, { event: eventName, data });\n\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\tcase \"warn\": {\n\t\t\t\tthis._eventLogger.warn?.(message, { event: eventName, data });\n\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\tcase \"trace\": {\n\t\t\t\tthis._eventLogger.trace?.(message, { event: eventName, data });\n\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\tcase \"debug\": {\n\t\t\t\tthis._eventLogger.debug?.(message, { event: eventName, data });\n\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\tcase \"fatal\": {\n\t\t\t\tthis._eventLogger.fatal?.(message, { event: eventName, data });\n\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\tdefault: {\n\t\t\t\tthis._eventLogger.info?.(message, { event: eventName, data });\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t}\n}\n","import type { HookFn, IHook } from \"../types.js\";\n\n/**\n * Concrete implementation of the IHook interface.\n * Provides a convenient class-based way to create hook entries.\n */\nexport class Hook implements IHook {\n\tpublic id?: string;\n\tpublic event: string;\n\tpublic handler: HookFn;\n\n\t/**\n\t * Creates a new Hook instance\n\t * @param {string} event - The event name for the hook\n\t * @param {HookFn} handler - The handler function for the hook\n\t * @param {string} [id] - Optional unique identifier for the hook\n\t */\n\tconstructor(event: string, handler: HookFn, id?: string) {\n\t\tthis.id = id;\n\t\tthis.event = event;\n\t\tthis.handler = handler;\n\t}\n}\n","import type {\n\tHookFn,\n\tIParallelHook,\n\tParallelHookFinalFn,\n\tParallelHookFn,\n\tParallelHookResult,\n} from \"../types.js\";\n\n/**\n * A ParallelHook fans a single invocation out to many registered hook\n * functions concurrently via Promise.allSettled, then calls a final\n * handler with the aggregated results — including failures — keyed by\n * the hook function reference for direct lookup. Each hook receives only\n * the original arguments; hooks do not see each other's results.\n *\n * Implements IHook for compatibility with Hookified.onHook(); the final\n * handler is called regardless of whether the parallel hook is invoked\n * directly or through Hookified.hook().\n *\n * Generics tighten the per-hook signature when every hook in the set\n * accepts the same `initialArgs` and returns the same result type.\n * Both default to `any` for backwards compatibility.\n *\n * @template TArgs - The shape of `initialArgs` passed to every hook\n * @template TResult - The result type each hook returns\n */\n// biome-ignore lint/suspicious/noExplicitAny: defaults preserve untyped use\nexport class ParallelHook<TArgs = any, TResult = any>\n\timplements IParallelHook<TArgs, TResult>\n{\n\tpublic id?: string;\n\tpublic event: string;\n\tpublic handler: HookFn;\n\tpublic hooks: ParallelHookFn<TArgs, TResult>[];\n\n\tprivate readonly _finalHandler: ParallelHookFinalFn<TArgs, TResult>;\n\n\t/**\n\t * Creates a new ParallelHook instance\n\t * @param {string} event - The event name for the hook\n\t * @param {ParallelHookFinalFn<TArgs, TResult>} finalHandler - Called once with `{ initialArgs, results }` after all parallel hooks settle\n\t * @param {string} [id] - Optional unique identifier for the hook\n\t */\n\tconstructor(\n\t\tevent: string,\n\t\tfinalHandler: ParallelHookFinalFn<TArgs, TResult>,\n\t\tid?: string,\n\t) {\n\t\tthis.id = id;\n\t\tthis.event = event;\n\t\tthis.hooks = [];\n\t\tthis._finalHandler = finalHandler;\n\n\t\t// biome-ignore lint/suspicious/noExplicitAny: this is for any parameter compatibility\n\t\tthis.handler = async (...arguments_: any[]) => {\n\t\t\tconst initialArgs: TArgs = (\n\t\t\t\targuments_.length === 1 ? arguments_[0] : arguments_\n\t\t\t) as TArgs;\n\n\t\t\t// Snapshot hooks at invocation time so concurrent addHook/removeHook\n\t\t\t// calls during the awaited Promise.allSettled cannot desync the\n\t\t\t// settled-index → hook mapping below.\n\t\t\tconst snapshot = [...this.hooks];\n\n\t\t\tconst settled = await Promise.allSettled(\n\t\t\t\tsnapshot.map((hook) =>\n\t\t\t\t\tPromise.resolve().then(() => hook({ initialArgs })),\n\t\t\t\t),\n\t\t\t);\n\n\t\t\tconst results = new Map<\n\t\t\t\tParallelHookFn<TArgs, TResult>,\n\t\t\t\tParallelHookResult<TResult>\n\t\t\t>();\n\t\t\tsnapshot.forEach((hook, index) => {\n\t\t\t\tconst outcome = settled[index];\n\t\t\t\tresults.set(\n\t\t\t\t\thook,\n\t\t\t\t\toutcome.status === \"fulfilled\"\n\t\t\t\t\t\t? { status: \"fulfilled\", result: outcome.value }\n\t\t\t\t\t\t: { status: \"rejected\", reason: outcome.reason },\n\t\t\t\t);\n\t\t\t});\n\n\t\t\tawait this._finalHandler({ initialArgs, results });\n\t\t};\n\t}\n\n\t/**\n\t * Adds a hook function to the parallel set\n\t * @param {ParallelHookFn<TArgs, TResult>} hook - The hook function to add\n\t */\n\tpublic addHook(hook: ParallelHookFn<TArgs, TResult>): void {\n\t\tthis.hooks.push(hook);\n\t}\n\n\t/**\n\t * Removes a specific hook function from the parallel set\n\t * @param {ParallelHookFn<TArgs, TResult>} hook - The hook function to remove\n\t * @returns {boolean} true if the hook was found and removed\n\t */\n\tpublic removeHook(hook: ParallelHookFn<TArgs, TResult>): boolean {\n\t\tconst index = this.hooks.indexOf(hook);\n\t\tif (index !== -1) {\n\t\t\tthis.hooks.splice(index, 1);\n\t\t\treturn true;\n\t\t}\n\n\t\treturn false;\n\t}\n}\n","import type {\n\tHookFn,\n\tIWaterfallHook,\n\tWaterfallHookFn,\n\tWaterfallHookResult,\n} from \"../types.js\";\n\n/**\n * A WaterfallHook chains multiple hook functions sequentially,\n * where each hook receives a context with the previous result,\n * initial arguments, and accumulated results. After all hooks\n * have executed, the final handler receives the transformed result.\n * Implements IHook for compatibility with Hookified.onHook().\n */\nexport class WaterfallHook implements IWaterfallHook {\n\tpublic id?: string;\n\tpublic event: string;\n\tpublic handler: HookFn;\n\tpublic hooks: WaterfallHookFn[];\n\n\tprivate readonly _finalHandler: WaterfallHookFn;\n\n\t/**\n\t * Creates a new WaterfallHook instance\n\t * @param {string} event - The event name for the hook\n\t * @param {WaterfallHookFn} finalHandler - The final handler function that receives the transformed result\n\t * @param {string} [id] - Optional unique identifier for the hook\n\t */\n\tconstructor(event: string, finalHandler: WaterfallHookFn, id?: string) {\n\t\tthis.id = id;\n\t\tthis.event = event;\n\t\tthis.hooks = [];\n\t\tthis._finalHandler = finalHandler;\n\n\t\t// biome-ignore lint/suspicious/noExplicitAny: this is for any parameter compatibility\n\t\tthis.handler = async (...arguments_: any[]) => {\n\t\t\t// biome-ignore lint/suspicious/noExplicitAny: waterfall result type varies through the chain\n\t\t\tconst initialArgs: any =\n\t\t\t\targuments_.length === 1 ? arguments_[0] : arguments_;\n\t\t\tconst results: WaterfallHookResult[] = [];\n\n\t\t\tfor (const hook of this.hooks) {\n\t\t\t\tconst result = await hook({ initialArgs, results: [...results] });\n\t\t\t\tresults.push({ hook, result });\n\t\t\t}\n\n\t\t\tawait this._finalHandler({ initialArgs, results: [...results] });\n\t\t};\n\t}\n\n\t/**\n\t * Adds a hook function to the end of the waterfall chain\n\t * @param {WaterfallHookFn} hook - The hook function to add\n\t */\n\tpublic addHook(hook: WaterfallHookFn): void {\n\t\tthis.hooks.push(hook);\n\t}\n\n\t/**\n\t * Removes a specific hook function from the waterfall chain\n\t * @param {WaterfallHookFn} hook - The hook function to remove\n\t * @returns {boolean} true if the hook was found and removed\n\t */\n\tpublic removeHook(hook: WaterfallHookFn): boolean {\n\t\tconst index = this.hooks.indexOf(hook);\n\t\tif (index !== -1) {\n\t\t\tthis.hooks.splice(index, 1);\n\t\t\treturn true;\n\t\t}\n\n\t\treturn false;\n\t}\n}\n","import { Eventified } from \"./eventified.js\";\nimport type {\n\tHookFn,\n\tHookifiedOptions,\n\tIHook,\n\tIWaterfallHook,\n\tOnHookOptions,\n\tPrependHookOptions,\n\tWaterfallHookContext,\n\tWaterfallHookFn,\n\tWaterfallHookResult,\n} from \"./types.js\";\n\nexport type {\n\tHookFn,\n\tHookifiedOptions,\n\tIHook,\n\tIWaterfallHook,\n\tOnHookOptions,\n\tPrependHookOptions,\n\tWaterfallHookContext,\n\tWaterfallHookFn,\n\tWaterfallHookResult,\n};\n\nexport class Hookified extends Eventified {\n\tprivate readonly _hooks: Map<string, IHook[]>;\n\tprivate _throwOnHookError = false;\n\tprivate _enforceBeforeAfter = false;\n\tprivate _deprecatedHooks: Map<string, string>;\n\tprivate _allowDeprecated = true;\n\tprivate _useHookClone = true;\n\n\tconstructor(options?: HookifiedOptions) {\n\t\tsuper({\n\t\t\teventLogger: options?.eventLogger,\n\t\t\tthrowOnEmitError: options?.throwOnEmitError,\n\t\t\tthrowOnEmptyListeners: options?.throwOnEmptyListeners,\n\t\t});\n\t\tthis._hooks = new Map();\n\t\tthis._deprecatedHooks = options?.deprecatedHooks\n\t\t\t? new Map(options.deprecatedHooks)\n\t\t\t: new Map();\n\n\t\tif (options?.throwOnHookError !== undefined) {\n\t\t\tthis._throwOnHookError = options.throwOnHookError;\n\t\t}\n\n\t\tif (options?.enforceBeforeAfter !== undefined) {\n\t\t\tthis._enforceBeforeAfter = options.enforceBeforeAfter;\n\t\t}\n\n\t\tif (options?.allowDeprecated !== undefined) {\n\t\t\tthis._allowDeprecated = options.allowDeprecated;\n\t\t}\n\n\t\tif (options?.useHookClone !== undefined) {\n\t\t\tthis._useHookClone = options.useHookClone;\n\t\t}\n\t}\n\n\t/**\n\t * Gets all hooks\n\t * @returns {Map<string, IHook[]>}\n\t */\n\tpublic get 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\tpublic get throwOnHookError() {\n\t\treturn this._throwOnHookError;\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\tpublic set throwOnHookError(value) {\n\t\tthis._throwOnHookError = value;\n\t}\n\n\t/**\n\t * Gets whether to enforce that all hook names start with 'before' or 'after'. Default is false.\n\t * @returns {boolean}\n\t * @default false\n\t */\n\tpublic get enforceBeforeAfter() {\n\t\treturn this._enforceBeforeAfter;\n\t}\n\n\t/**\n\t * Sets whether to enforce that all hook names start with 'before' or 'after'. Default is false.\n\t * @param {boolean} value\n\t */\n\tpublic set enforceBeforeAfter(value) {\n\t\tthis._enforceBeforeAfter = value;\n\t}\n\n\t/**\n\t * Gets the map of deprecated hook names to deprecation messages.\n\t * @returns {Map<string, string>}\n\t */\n\tpublic get deprecatedHooks() {\n\t\treturn this._deprecatedHooks;\n\t}\n\n\t/**\n\t * Sets the map of deprecated hook names to deprecation messages.\n\t * @param {Map<string, string>} value\n\t */\n\tpublic set deprecatedHooks(value) {\n\t\tthis._deprecatedHooks = value;\n\t}\n\n\t/**\n\t * Gets whether deprecated hooks are allowed to be registered and executed. Default is true.\n\t * @returns {boolean}\n\t */\n\tpublic get allowDeprecated() {\n\t\treturn this._allowDeprecated;\n\t}\n\n\t/**\n\t * Sets whether deprecated hooks are allowed to be registered and executed. Default is true.\n\t * @param {boolean} value\n\t */\n\tpublic set allowDeprecated(value) {\n\t\tthis._allowDeprecated = value;\n\t}\n\n\t/**\n\t * Gets whether hook objects are cloned before storing. Default is true.\n\t * @returns {boolean}\n\t */\n\tpublic get useHookClone() {\n\t\treturn this._useHookClone;\n\t}\n\n\t/**\n\t * Sets whether hook objects are cloned before storing. Default is true.\n\t * When false, the original IHook reference is stored directly.\n\t * @param {boolean} value\n\t */\n\tpublic set useHookClone(value) {\n\t\tthis._useHookClone = value;\n\t}\n\n\t/**\n\t * Adds a handler function for a specific event.\n\t * Supports both object and legacy signatures:\n\t * onHook({ event, handler }, options?)\n\t * onHook(event, handler)\n\t * To register multiple hooks at once, use {@link onHooks}.\n\t * @param {IHook | string} hookOrEvent - the hook object or event name\n\t * @param {OnHookOptions | HookFn} [optionsOrHandler] - options (when using object form) or handler function (when using string form)\n\t * @returns {IHook | undefined} the stored hook, or undefined if blocked by deprecation\n\t */\n\tpublic onHook(hook: IHook, options?: OnHookOptions): IHook | undefined;\n\tpublic onHook(event: string, handler: HookFn): IHook | undefined;\n\tpublic onHook(\n\t\thookOrEvent: IHook | string,\n\t\toptionsOrHandler?: OnHookOptions | HookFn,\n\t): IHook | undefined {\n\t\tlet hook: IHook;\n\t\tlet options: OnHookOptions | undefined;\n\n\t\tif (typeof hookOrEvent === \"string\") {\n\t\t\tif (typeof optionsOrHandler !== \"function\") {\n\t\t\t\tthrow new TypeError(\n\t\t\t\t\t\"When calling onHook(event, handler), the second argument must be a function\",\n\t\t\t\t);\n\t\t\t}\n\n\t\t\thook = { event: hookOrEvent, handler: optionsOrHandler };\n\t\t\toptions = undefined;\n\t\t} else {\n\t\t\thook = hookOrEvent;\n\t\t\toptions = optionsOrHandler as OnHookOptions | undefined;\n\t\t}\n\t\tthis.validateHookName(hook.event);\n\t\tif (!this.checkDeprecatedHook(hook.event)) {\n\t\t\treturn undefined; // Skip registration if deprecated hooks are not allowed\n\t\t}\n\n\t\tconst shouldClone = options?.useHookClone ?? this._useHookClone;\n\t\tconst entry: IHook = shouldClone\n\t\t\t? { id: hook.id, event: hook.event, handler: hook.handler }\n\t\t\t: hook;\n\n\t\tentry.id = entry.id ?? crypto.randomUUID();\n\n\t\tconst eventHandlers = this._hooks.get(hook.event);\n\t\tif (eventHandlers) {\n\t\t\t// Check for duplicate id — replace in-place if found\n\t\t\tconst existingIndex = eventHandlers.findIndex((h) => h.id === entry.id);\n\t\t\tif (existingIndex !== -1) {\n\t\t\t\teventHandlers[existingIndex] = entry;\n\t\t\t} else {\n\t\t\t\tconst position = options?.position ?? \"Bottom\";\n\t\t\t\tif (position === \"Top\") {\n\t\t\t\t\teventHandlers.unshift(entry);\n\t\t\t\t} else if (position === \"Bottom\") {\n\t\t\t\t\teventHandlers.push(entry);\n\t\t\t\t} else {\n\t\t\t\t\tconst index = Math.max(0, Math.min(position, eventHandlers.length));\n\t\t\t\t\teventHandlers.splice(index, 0, entry);\n\t\t\t\t}\n\t\t\t}\n\t\t} else {\n\t\t\tthis._hooks.set(hook.event, [entry]);\n\t\t}\n\n\t\treturn entry;\n\t}\n\n\t/**\n\t * Alias for onHook. This is provided for compatibility with other libraries that use the `addHook` method.\n\t * @param {string} event - the event name\n\t * @param {HookFn} handler - the handler function\n\t * @returns {void}\n\t */\n\tpublic addHook(event: string, handler: HookFn) {\n\t\tthis.onHook({ event, handler });\n\t}\n\n\t/**\n\t * Adds handler functions for specific events\n\t * @param {Array<IHook>} hooks\n\t * @param {OnHookOptions} [options] - optional per-call options (e.g., useHookClone override, position)\n\t * @returns {void}\n\t */\n\tpublic onHooks(hooks: IHook[], options?: OnHookOptions) {\n\t\tfor (const hook of hooks) {\n\t\t\tthis.onHook(hook, options);\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 * Equivalent to calling `onHook(hook, { position: \"Top\" })`.\n\t * @param {IHook} hook - the hook containing event name and handler\n\t * @param {PrependHookOptions} [options] - optional per-call options (e.g., useHookClone override)\n\t * @returns {IHook | undefined} the stored hook, or undefined if blocked by deprecation\n\t */\n\tpublic prependHook(\n\t\thook: IHook,\n\t\toptions?: PrependHookOptions,\n\t): IHook | undefined {\n\t\treturn this.onHook(hook, { ...options, position: \"Top\" });\n\t}\n\n\t/**\n\t * Adds a handler that only executes once for a specific event before all other handlers.\n\t * Equivalent to calling `onHook` with a self-removing wrapper and `{ position: \"Top\" }`.\n\t * @param {IHook} hook - the hook containing event name and handler\n\t * @param {PrependHookOptions} [options] - optional per-call options (e.g., useHookClone override)\n\t * @returns {IHook | undefined} the stored hook, or undefined if blocked by deprecation\n\t */\n\tpublic prependOnceHook(\n\t\thook: IHook,\n\t\toptions?: PrependHookOptions,\n\t): IHook | undefined {\n\t\t// biome-ignore lint/suspicious/noExplicitAny: this is for any parameter compatibility\n\t\tconst wrappedHandler = async (...arguments_: any[]) => {\n\t\t\tthis.removeHook({ event: hook.event, handler: wrappedHandler });\n\t\t\treturn hook.handler(...arguments_);\n\t\t};\n\n\t\treturn this.onHook(\n\t\t\t{ id: hook.id, event: hook.event, handler: wrappedHandler },\n\t\t\t{ ...options, position: \"Top\" },\n\t\t);\n\t}\n\n\t/**\n\t * Adds a handler that only executes once for a specific event\n\t * @param {IHook} hook - the hook containing event name and handler\n\t */\n\tpublic onceHook(hook: IHook) {\n\t\tthis.validateHookName(hook.event);\n\t\tif (!this.checkDeprecatedHook(hook.event)) {\n\t\t\treturn; // Skip registration if deprecated hooks are not allowed\n\t\t}\n\t\t// biome-ignore lint/suspicious/noExplicitAny: this is for any parameter compatibility\n\t\tconst wrappedHandler = async (...arguments_: any[]) => {\n\t\t\tthis.removeHook({ event: hook.event, handler: wrappedHandler });\n\t\t\treturn hook.handler(...arguments_);\n\t\t};\n\n\t\tthis.onHook({ id: hook.id, event: hook.event, handler: wrappedHandler });\n\t}\n\n\t/**\n\t * Removes a handler function for a specific event\n\t * @param {IHook} hook - the hook containing event name and handler to remove\n\t * @returns {IHook | undefined} the removed hook, or undefined if not found\n\t */\n\tpublic removeHook(hook: IHook): IHook | undefined {\n\t\tthis.validateHookName(hook.event);\n\t\tconst eventHandlers = this._hooks.get(hook.event);\n\t\tif (eventHandlers) {\n\t\t\tconst index = eventHandlers.findIndex((h) => h.handler === hook.handler);\n\t\t\tif (index !== -1) {\n\t\t\t\teventHandlers.splice(index, 1);\n\t\t\t\tif (eventHandlers.length === 0) {\n\t\t\t\t\tthis._hooks.delete(hook.event);\n\t\t\t\t}\n\n\t\t\t\treturn { event: hook.event, handler: hook.handler };\n\t\t\t}\n\t\t}\n\n\t\treturn undefined;\n\t}\n\n\t/**\n\t * Removes multiple hook handlers\n\t * @param {Array<IHook>} hooks\n\t * @returns {IHook[]} the hooks that were successfully removed\n\t */\n\tpublic removeHooks(hooks: IHook[]): IHook[] {\n\t\tconst removed: IHook[] = [];\n\t\tfor (const hook of hooks) {\n\t\t\tconst result = this.removeHook(hook);\n\t\t\tif (result) {\n\t\t\t\tremoved.push(result);\n\t\t\t}\n\t\t}\n\n\t\treturn removed;\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\tpublic async hook<T>(event: string, ...arguments_: T[]) {\n\t\tthis.validateHookName(event);\n\t\tif (!this.checkDeprecatedHook(event)) {\n\t\t\treturn; // Skip execution if deprecated hooks are not allowed\n\t\t}\n\t\tconst eventHandlers = this._hooks.get(event);\n\t\tif (eventHandlers) {\n\t\t\tfor (const hook of [...eventHandlers]) {\n\t\t\t\ttry {\n\t\t\t\t\tawait hook.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\n\t\t\t\t\tif (this._throwOnHookError) {\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 * Calls all synchronous handlers for a specific event.\n\t * Async handlers (declared with `async` keyword) are silently skipped.\n\t *\n\t * Note: The `hook` method is preferred as it executes both sync and async functions.\n\t * Use `hookSync` only when you specifically need synchronous execution.\n\t * @param {string} event\n\t * @param {T[]} arguments_\n\t * @returns {void}\n\t */\n\tpublic hookSync<T>(event: string, ...arguments_: T[]): void {\n\t\tthis.validateHookName(event);\n\t\tif (!this.checkDeprecatedHook(event)) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst eventHandlers = this._hooks.get(event);\n\t\tif (eventHandlers) {\n\t\t\tfor (const hook of [...eventHandlers]) {\n\t\t\t\t// Skip async functions silently\n\t\t\t\tif (hook.handler.constructor.name === \"AsyncFunction\") {\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\n\t\t\t\ttry {\n\t\t\t\t\thook.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\n\t\t\t\t\tif (this._throwOnHookError) {\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 * Prepends the word `before` to your hook. Example is event is `test`, the before hook is `before:test`.\n\t * @param {string} event - The event name\n\t * @param {T[]} arguments_ - The arguments to pass to the hook\n\t */\n\tpublic async beforeHook<T>(event: string, ...arguments_: T[]) {\n\t\tawait this.hook(`before:${event}`, ...arguments_);\n\t}\n\n\t/**\n\t * Prepends the word `after` to your hook. Example is event is `test`, the after hook is `after:test`.\n\t * @param {string} event - The event name\n\t * @param {T[]} arguments_ - The arguments to pass to the hook\n\t */\n\tpublic async afterHook<T>(event: string, ...arguments_: T[]) {\n\t\tawait this.hook(`after:${event}`, ...arguments_);\n\t}\n\n\t/**\n\t * Calls all handlers for a specific event. This is an alias for `hook` and is provided for\n\t * compatibility with other libraries that use the `callHook` method.\n\t * @param {string} event\n\t * @param {T[]} arguments_\n\t * @returns {Promise<void>}\n\t */\n\tpublic async callHook<T>(event: string, ...arguments_: T[]) {\n\t\tawait this.hook(event, ...arguments_);\n\t}\n\n\t/**\n\t * Gets all hooks for a specific event\n\t * @param {string} event\n\t * @returns {IHook[]}\n\t */\n\tpublic getHooks(event: string) {\n\t\tthis.validateHookName(event);\n\t\treturn this._hooks.get(event);\n\t}\n\n\t/**\n\t * Gets a specific hook by id, searching across all events\n\t * @param {string} id - the hook id\n\t * @returns {IHook | undefined} the hook if found, or undefined\n\t */\n\tpublic getHook(id: string): IHook | undefined {\n\t\tfor (const eventHandlers of this._hooks.values()) {\n\t\t\tconst found = eventHandlers.find((h) => h.id === id);\n\t\t\tif (found) {\n\t\t\t\treturn found;\n\t\t\t}\n\t\t}\n\n\t\treturn undefined;\n\t}\n\n\t/**\n\t * Removes one or more hooks by id, searching across all events\n\t * @param {string | string[]} id - the hook id or array of hook ids to remove\n\t * @returns {IHook | IHook[] | undefined} the removed hook(s), or undefined/empty array if not found\n\t */\n\tpublic removeHookById(id: string | string[]): IHook | IHook[] | undefined {\n\t\tif (Array.isArray(id)) {\n\t\t\tconst removed: IHook[] = [];\n\t\t\tfor (const singleId of id) {\n\t\t\t\tconst result = this.removeHookById(singleId);\n\t\t\t\tif (result && !Array.isArray(result)) {\n\t\t\t\t\tremoved.push(result);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\treturn removed;\n\t\t}\n\n\t\tfor (const [event, eventHandlers] of this._hooks.entries()) {\n\t\t\tconst index = eventHandlers.findIndex((h) => h.id === id);\n\t\t\tif (index !== -1) {\n\t\t\t\tconst [removed] = eventHandlers.splice(index, 1);\n\t\t\t\tif (eventHandlers.length === 0) {\n\t\t\t\t\tthis._hooks.delete(event);\n\t\t\t\t}\n\n\t\t\t\treturn removed;\n\t\t\t}\n\t\t}\n\n\t\treturn undefined;\n\t}\n\n\t/**\n\t * Removes all hooks\n\t * @returns {void}\n\t */\n\tpublic clearHooks() {\n\t\tthis._hooks.clear();\n\t}\n\n\t/**\n\t * Removes all hooks for a specific event and returns the removed hooks.\n\t * @param {string} event - The event name to remove hooks for.\n\t * @returns {IHook[]} the hooks that were removed\n\t */\n\tpublic removeEventHooks(event: string): IHook[] {\n\t\tthis.validateHookName(event);\n\t\tconst eventHandlers = this._hooks.get(event);\n\t\tif (eventHandlers) {\n\t\t\tconst removed = [...eventHandlers];\n\t\t\tthis._hooks.delete(event);\n\t\t\treturn removed;\n\t\t}\n\n\t\treturn [];\n\t}\n\n\t/**\n\t * Validates hook event name if enforceBeforeAfter is enabled\n\t * @param {string} event - The event name to validate\n\t * @throws {Error} If enforceBeforeAfter is true and event doesn't start with 'before' or 'after'\n\t */\n\tprivate validateHookName(event: string): void {\n\t\tif (this._enforceBeforeAfter) {\n\t\t\tconst eventValue = event.trim().toLocaleLowerCase();\n\t\t\tif (!eventValue.startsWith(\"before\") && !eventValue.startsWith(\"after\")) {\n\t\t\t\tthrow new Error(\n\t\t\t\t\t`Hook event \"${event}\" must start with \"before\" or \"after\" when enforceBeforeAfter is enabled`,\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Checks if a hook is deprecated and emits a warning if it is\n\t * @param {string} event - The event name to check\n\t * @returns {boolean} - Returns true if the hook should proceed, false if it should be blocked\n\t */\n\tprivate checkDeprecatedHook(event: string): boolean {\n\t\tif (this._deprecatedHooks.has(event)) {\n\t\t\tconst message = this._deprecatedHooks.get(event);\n\t\t\tconst warningMessage = `Hook \"${event}\" is deprecated${message ? `: ${message}` : \"\"}`;\n\n\t\t\t// Emit deprecation warning event\n\t\t\tthis.emit(\"warn\", { hook: event, message: warningMessage });\n\n\t\t\t// Return false if deprecated hooks are not allowed\n\t\t\treturn this._allowDeprecated;\n\t\t}\n\t\treturn true;\n\t}\n}\n\nexport { Eventified } from \"./eventified.js\";\nexport { Hook } from \"./hooks/hook.js\";\nexport { ParallelHook } from \"./hooks/parallel-hook.js\";\nexport { WaterfallHook } from \"./hooks/waterfall-hook.js\";\nexport type {\n\tEventEmitterOptions,\n\tEventListener,\n\tIEventEmitter,\n\tIParallelHook,\n\tLogger,\n\tParallelHookContext,\n\tParallelHookFinalContext,\n\tParallelHookFinalFn,\n\tParallelHookFn,\n\tParallelHookResult,\n} from \"./types.js\";\n"],"mappings":"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"}
{"version":3,"file":"index.js","names":[],"sources":["../../src/eventified.ts","../../src/hooks/hook.ts","../../src/hooks/parallel-hook.ts","../../src/hooks/waterfall-hook.ts","../../src/index.ts"],"sourcesContent":["// biome-ignore-all lint/suspicious/noExplicitAny: this is for event emitter compatibility\nimport type {\n\tEventEmitterOptions,\n\tEventListener,\n\tIEventEmitter,\n\tLogger,\n} from \"./types.js\";\n\nexport type { EventEmitterOptions, EventListener, IEventEmitter };\n\nconst ERROR_EVENT = \"error\";\n\nexport class Eventified implements IEventEmitter {\n\tprivate readonly _eventListeners: Map<\n\t\tstring | symbol,\n\t\tEventListener | EventListener[]\n\t>;\n\tprivate _maxListeners: number;\n\tprivate _eventLogger?: Logger;\n\tprivate _throwOnEmitError = false;\n\tprivate _throwOnEmptyListeners = true;\n\n\tconstructor(options?: EventEmitterOptions) {\n\t\tthis._eventListeners = new Map<\n\t\t\tstring | symbol,\n\t\t\tEventListener | EventListener[]\n\t\t>();\n\t\tthis._maxListeners = 0; // Default is 0 (unlimited)\n\n\t\tthis._eventLogger = options?.eventLogger;\n\n\t\tif (options?.throwOnEmitError !== undefined) {\n\t\t\tthis._throwOnEmitError = options.throwOnEmitError;\n\t\t}\n\n\t\tif (options?.throwOnEmptyListeners !== undefined) {\n\t\t\tthis._throwOnEmptyListeners = options.throwOnEmptyListeners;\n\t\t}\n\t}\n\n\t/**\n\t * Gets the event logger\n\t * @returns {Logger}\n\t */\n\tpublic get eventLogger(): Logger | undefined {\n\t\treturn this._eventLogger;\n\t}\n\n\t/**\n\t * Sets the event logger\n\t * @param {Logger} eventLogger\n\t */\n\tpublic set eventLogger(eventLogger: Logger | undefined) {\n\t\tthis._eventLogger = eventLogger;\n\t}\n\n\t/**\n\t * Gets whether an error should be thrown when an emit throws an error. Default is false and only emits an error event.\n\t * @returns {boolean}\n\t */\n\tpublic get throwOnEmitError(): boolean {\n\t\treturn this._throwOnEmitError;\n\t}\n\n\t/**\n\t * Sets whether an error should be thrown when an emit throws an error. Default is false and only emits an error event.\n\t * @param {boolean} value\n\t */\n\tpublic set throwOnEmitError(value: boolean) {\n\t\tthis._throwOnEmitError = value;\n\t}\n\n\t/**\n\t * Gets whether an error should be thrown when emitting 'error' event with no listeners. Default is false.\n\t * @returns {boolean}\n\t */\n\tpublic get throwOnEmptyListeners(): boolean {\n\t\treturn this._throwOnEmptyListeners;\n\t}\n\n\t/**\n\t * Sets whether an error should be thrown when emitting 'error' event with no listeners. Default is false.\n\t * @param {boolean} value\n\t */\n\tpublic set throwOnEmptyListeners(value: boolean) {\n\t\tthis._throwOnEmptyListeners = value;\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\tpublic once(\n\t\teventName: string | symbol,\n\t\tlistener: EventListener,\n\t): IEventEmitter {\n\t\tconst onceListener: EventListener = (...arguments_: any[]) => {\n\t\t\tthis.off(eventName as string, onceListener);\n\t\t\tlistener(...arguments_);\n\t\t};\n\n\t\t// Keep a reference to the original listener so that off()/removeListener()\n\t\t// can remove the once wrapper when called with the original reference.\n\t\t(onceListener as any)._originalListener = listener;\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\tpublic listenerCount(eventName?: string | symbol): number {\n\t\tif (eventName === undefined) {\n\t\t\tlet count = 0;\n\t\t\tfor (const entry of this._eventListeners.values()) {\n\t\t\t\tcount += typeof entry === \"function\" ? 1 : entry.length;\n\t\t\t}\n\n\t\t\treturn count;\n\t\t}\n\n\t\tconst entry = this._eventListeners.get(eventName);\n\t\tif (entry === undefined) {\n\t\t\treturn 0;\n\t\t}\n\n\t\treturn typeof entry === \"function\" ? 1 : entry.length;\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\tpublic eventNames(): Array<string | symbol> {\n\t\treturn [...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\tpublic rawListeners(event?: string | symbol): EventListener[] {\n\t\tif (event === undefined) {\n\t\t\treturn this.getAllListeners();\n\t\t}\n\n\t\tconst entry = this._eventListeners.get(event);\n\t\tif (entry === undefined) {\n\t\t\treturn [];\n\t\t}\n\n\t\treturn typeof entry === \"function\" ? [entry] : entry;\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\tpublic prependListener(\n\t\teventName: string | symbol,\n\t\tlistener: EventListener,\n\t): IEventEmitter {\n\t\tconst existing = this._eventListeners.get(eventName);\n\n\t\tif (existing === undefined) {\n\t\t\tthis._eventListeners.set(eventName, listener);\n\t\t} else if (typeof existing === \"function\") {\n\t\t\tthis._eventListeners.set(eventName, [listener, existing]);\n\t\t} else {\n\t\t\texisting.unshift(listener);\n\t\t}\n\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\tpublic prependOnceListener(\n\t\teventName: string | symbol,\n\t\tlistener: EventListener,\n\t): IEventEmitter {\n\t\tconst onceListener: EventListener = (...arguments_: any[]) => {\n\t\t\tthis.off(eventName as string, onceListener);\n\t\t\tlistener(...arguments_);\n\t\t};\n\n\t\t// Keep a reference to the original listener so that off()/removeListener()\n\t\t// can remove the once wrapper when called with the original reference.\n\t\t(onceListener as any)._originalListener = listener;\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(\n\t\tevent: string | symbol,\n\t\tlistener: EventListener,\n\t): 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\tconst existing = this._eventListeners.get(event);\n\n\t\tif (existing === undefined) {\n\t\t\tthis._eventListeners.set(event, listener);\n\t\t\treturn this;\n\t\t}\n\n\t\tif (typeof existing === \"function\") {\n\t\t\tconst arr = [existing, listener];\n\t\t\tthis._eventListeners.set(event, arr);\n\t\t\tif (this._maxListeners > 0 && arr.length > this._maxListeners) {\n\t\t\t\tconsole.warn(\n\t\t\t\t\t`MaxListenersExceededWarning: Possible event memory leak detected. ${arr.length} ${event as string} listeners added. Use setMaxListeners() to increase limit.`,\n\t\t\t\t);\n\t\t\t}\n\t\t} else {\n\t\t\texisting.push(listener);\n\t\t\tif (this._maxListeners > 0 && existing.length > this._maxListeners) {\n\t\t\t\tconsole.warn(\n\t\t\t\t\t`MaxListenersExceededWarning: Possible event memory leak detected. ${existing.length} ${event as string} listeners added. Use setMaxListeners() to increase limit.`,\n\t\t\t\t);\n\t\t\t}\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 * Determines whether a stored listener matches the listener provided to off().\n\t * A match occurs when the references are identical, or when the stored listener\n\t * is a once-wrapper whose original listener equals the provided reference.\n\t * @param {EventListener} stored - the listener currently stored\n\t * @param {EventListener} target - the listener passed to off()\n\t * @returns {boolean} true if the stored listener should be removed\n\t */\n\tprivate matchesListener(\n\t\tstored: EventListener,\n\t\ttarget: EventListener,\n\t): boolean {\n\t\tif (stored === target) {\n\t\t\treturn true;\n\t\t}\n\n\t\t// Only treat this as a once-wrapper match when an original listener was\n\t\t// actually recorded. Without this guard, calling off() with an undefined\n\t\t// target would match any normal listener (whose _originalListener is also\n\t\t// undefined) and remove it.\n\t\tconst original = (stored as any)._originalListener;\n\t\treturn original !== undefined && original === target;\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 entry = this._eventListeners.get(event);\n\t\tif (entry === undefined) {\n\t\t\treturn this;\n\t\t}\n\n\t\tif (typeof entry === \"function\") {\n\t\t\tif (this.matchesListener(entry, listener)) {\n\t\t\t\tthis._eventListeners.delete(event);\n\t\t\t}\n\n\t\t\treturn this;\n\t\t}\n\n\t\t// Prefer an exact reference match before falling back to once-wrapper\n\t\t// matching, so a normal listener is never left behind when an identical\n\t\t// once-wrapper happens to precede it in the array.\n\t\tlet index = entry.indexOf(listener);\n\t\tif (index === -1) {\n\t\t\tindex = entry.findIndex((stored) =>\n\t\t\t\tthis.matchesListener(stored, listener),\n\t\t\t);\n\t\t}\n\n\t\tif (index !== -1) {\n\t\t\tif (entry.length === 2) {\n\t\t\t\tthis._eventListeners.set(event, entry[1 - index]);\n\t\t\t\t/* v8 ignore start -- @preserve: single-element arrays are stored as functions */\n\t\t\t} else if (entry.length === 1) {\n\t\t\t\tthis._eventListeners.delete(event);\n\t\t\t\t/* v8 ignore stop */\n\t\t\t} else {\n\t\t\t\tentry.splice(index, 1);\n\t\t\t}\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 entry = this._eventListeners.get(event);\n\t\tconst argumentLength = arguments_.length;\n\n\t\tif (entry !== undefined) {\n\t\t\tif (typeof entry === \"function\") {\n\t\t\t\tif (argumentLength === 1) {\n\t\t\t\t\tentry(arguments_[0]);\n\t\t\t\t} else if (argumentLength === 2) {\n\t\t\t\t\tentry(arguments_[0], arguments_[1]);\n\t\t\t\t} else {\n\t\t\t\t\tentry(...arguments_);\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\t// Iterate a snapshot so listeners removed (or added) during the\n\t\t\t\t// emit — e.g. a once wrapper removing itself, or a listener calling\n\t\t\t\t// off() — cannot corrupt the in-flight iteration. This matches\n\t\t\t\t// Node's EventEmitter behavior. The single-listener fast path above\n\t\t\t\t// needs no copy since it cannot be mid-iteration mutated.\n\t\t\t\tconst listeners = entry.slice();\n\t\t\t\tconst len = listeners.length;\n\t\t\t\tfor (let i = 0; i < len; i++) {\n\t\t\t\t\tif (argumentLength === 1) {\n\t\t\t\t\t\tlisteners[i](arguments_[0]);\n\t\t\t\t\t} else if (argumentLength === 2) {\n\t\t\t\t\t\tlisteners[i](arguments_[0], arguments_[1]);\n\t\t\t\t\t} else {\n\t\t\t\t\t\tlisteners[i](...arguments_);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tresult = true;\n\t\t}\n\n\t\t// send it to the logger\n\t\tif (this._eventLogger) {\n\t\t\tthis.sendToEventLogger(event, arguments_);\n\t\t}\n\n\t\tif (!result && event === ERROR_EVENT) {\n\t\t\tconst error =\n\t\t\t\targuments_[0] instanceof Error\n\t\t\t\t\t? arguments_[0]\n\t\t\t\t\t: new Error(`${arguments_[0]}`);\n\n\t\t\tif (this._throwOnEmitError || this._throwOnEmptyListeners) {\n\t\t\t\tthrow error;\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 | symbol): EventListener[] {\n\t\tconst entry = this._eventListeners.get(event);\n\t\tif (entry === undefined) {\n\t\t\treturn [];\n\t\t}\n\n\t\treturn typeof entry === \"function\" ? [entry] : entry;\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 | symbol): IEventEmitter {\n\t\tif (event !== undefined) {\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 < 0 ? 0 : n;\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\tconst result: EventListener[] = [];\n\t\tfor (const entry of this._eventListeners.values()) {\n\t\t\tif (typeof entry === \"function\") {\n\t\t\t\tresult.push(entry);\n\t\t\t} else {\n\t\t\t\tfor (let i = 0; i < entry.length; i++) {\n\t\t\t\t\tresult.push(entry[i]);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn result;\n\t}\n\n\t/**\n\t * Sends a log message using the configured logger based on the event name\n\t * @param {string | symbol} eventName - The event name that determines the log level\n\t * @param {unknown} data - The data to log\n\t */\n\tprivate sendToEventLogger(eventName: string | symbol, data: any): void {\n\t\t/* v8 ignore next 3 -- @preserve: guarded by caller */\n\t\tif (!this._eventLogger) {\n\t\t\treturn;\n\t\t}\n\n\t\tlet message: string;\n\t\t/* v8 ignore next -- @preserve */\n\t\tif (typeof data === \"string\") {\n\t\t\tmessage = data;\n\t\t} else if (\n\t\t\tArray.isArray(data) &&\n\t\t\tdata.length > 0 &&\n\t\t\tdata[0] instanceof Error\n\t\t) {\n\t\t\tmessage = data[0].message;\n\t\t\t/* v8 ignore next -- @preserve */\n\t\t} else if (data instanceof Error) {\n\t\t\tmessage = data.message;\n\t\t} else if (\n\t\t\tArray.isArray(data) &&\n\t\t\tdata.length > 0 &&\n\t\t\ttypeof data[0]?.message === \"string\"\n\t\t) {\n\t\t\tmessage = data[0].message;\n\t\t} else {\n\t\t\tmessage = JSON.stringify(data);\n\t\t}\n\n\t\tswitch (eventName) {\n\t\t\tcase \"error\": {\n\t\t\t\tthis._eventLogger.error?.(message, { event: eventName, data });\n\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\tcase \"warn\": {\n\t\t\t\tthis._eventLogger.warn?.(message, { event: eventName, data });\n\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\tcase \"trace\": {\n\t\t\t\tthis._eventLogger.trace?.(message, { event: eventName, data });\n\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\tcase \"debug\": {\n\t\t\t\tthis._eventLogger.debug?.(message, { event: eventName, data });\n\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\tcase \"fatal\": {\n\t\t\t\tthis._eventLogger.fatal?.(message, { event: eventName, data });\n\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\tdefault: {\n\t\t\t\tthis._eventLogger.info?.(message, { event: eventName, data });\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t}\n}\n","import type { HookFn, IHook } from \"../types.js\";\n\n/**\n * Concrete implementation of the IHook interface.\n * Provides a convenient class-based way to create hook entries.\n */\nexport class Hook implements IHook {\n\tpublic id?: string;\n\tpublic event: string;\n\tpublic handler: HookFn;\n\n\t/**\n\t * Creates a new Hook instance\n\t * @param {string} event - The event name for the hook\n\t * @param {HookFn} handler - The handler function for the hook\n\t * @param {string} [id] - Optional unique identifier for the hook\n\t */\n\tconstructor(event: string, handler: HookFn, id?: string) {\n\t\tthis.id = id;\n\t\tthis.event = event;\n\t\tthis.handler = handler;\n\t}\n}\n","import type {\n\tHookFn,\n\tIParallelHook,\n\tParallelHookFinalFn,\n\tParallelHookFn,\n\tParallelHookResult,\n} from \"../types.js\";\n\n/**\n * A ParallelHook fans a single invocation out to many registered hook\n * functions concurrently via Promise.allSettled, then calls a final\n * handler with the aggregated results — including failures — keyed by\n * the hook function reference for direct lookup. Each hook receives only\n * the original arguments; hooks do not see each other's results.\n *\n * Implements IHook for compatibility with Hookified.onHook(); the final\n * handler is called regardless of whether the parallel hook is invoked\n * directly or through Hookified.hook().\n *\n * Generics tighten the per-hook signature when every hook in the set\n * accepts the same `initialArgs` and returns the same result type.\n * Both default to `any` for backwards compatibility.\n *\n * @template TArgs - The shape of `initialArgs` passed to every hook\n * @template TResult - The result type each hook returns\n */\n// biome-ignore lint/suspicious/noExplicitAny: defaults preserve untyped use\nexport class ParallelHook<TArgs = any, TResult = any>\n\timplements IParallelHook<TArgs, TResult>\n{\n\tpublic id?: string;\n\tpublic event: string;\n\tpublic handler: HookFn;\n\tpublic hooks: ParallelHookFn<TArgs, TResult>[];\n\n\tprivate readonly _finalHandler: ParallelHookFinalFn<TArgs, TResult>;\n\n\t/**\n\t * Creates a new ParallelHook instance\n\t * @param {string} event - The event name for the hook\n\t * @param {ParallelHookFinalFn<TArgs, TResult>} finalHandler - Called once with `{ initialArgs, results }` after all parallel hooks settle\n\t * @param {string} [id] - Optional unique identifier for the hook\n\t */\n\tconstructor(\n\t\tevent: string,\n\t\tfinalHandler: ParallelHookFinalFn<TArgs, TResult>,\n\t\tid?: string,\n\t) {\n\t\tthis.id = id;\n\t\tthis.event = event;\n\t\tthis.hooks = [];\n\t\tthis._finalHandler = finalHandler;\n\n\t\t// biome-ignore lint/suspicious/noExplicitAny: this is for any parameter compatibility\n\t\tthis.handler = async (...arguments_: any[]) => {\n\t\t\tconst initialArgs: TArgs = (\n\t\t\t\targuments_.length === 1 ? arguments_[0] : arguments_\n\t\t\t) as TArgs;\n\n\t\t\t// Snapshot hooks at invocation time so concurrent addHook/removeHook\n\t\t\t// calls during the awaited Promise.allSettled cannot desync the\n\t\t\t// settled-index → hook mapping below.\n\t\t\tconst snapshot = [...this.hooks];\n\n\t\t\tconst settled = await Promise.allSettled(\n\t\t\t\tsnapshot.map((hook) =>\n\t\t\t\t\tPromise.resolve().then(() => hook({ initialArgs })),\n\t\t\t\t),\n\t\t\t);\n\n\t\t\tconst results = new Map<\n\t\t\t\tParallelHookFn<TArgs, TResult>,\n\t\t\t\tParallelHookResult<TResult>\n\t\t\t>();\n\t\t\tsnapshot.forEach((hook, index) => {\n\t\t\t\tconst outcome = settled[index];\n\t\t\t\tresults.set(\n\t\t\t\t\thook,\n\t\t\t\t\toutcome.status === \"fulfilled\"\n\t\t\t\t\t\t? { status: \"fulfilled\", result: outcome.value }\n\t\t\t\t\t\t: { status: \"rejected\", reason: outcome.reason },\n\t\t\t\t);\n\t\t\t});\n\n\t\t\tawait this._finalHandler({ initialArgs, results });\n\t\t};\n\t}\n\n\t/**\n\t * Adds a hook function to the parallel set\n\t * @param {ParallelHookFn<TArgs, TResult>} hook - The hook function to add\n\t */\n\tpublic addHook(hook: ParallelHookFn<TArgs, TResult>): void {\n\t\tthis.hooks.push(hook);\n\t}\n\n\t/**\n\t * Removes a specific hook function from the parallel set\n\t * @param {ParallelHookFn<TArgs, TResult>} hook - The hook function to remove\n\t * @returns {boolean} true if the hook was found and removed\n\t */\n\tpublic removeHook(hook: ParallelHookFn<TArgs, TResult>): boolean {\n\t\tconst index = this.hooks.indexOf(hook);\n\t\tif (index !== -1) {\n\t\t\tthis.hooks.splice(index, 1);\n\t\t\treturn true;\n\t\t}\n\n\t\treturn false;\n\t}\n}\n","import type {\n\tHookFn,\n\tIWaterfallHook,\n\tWaterfallHookFn,\n\tWaterfallHookResult,\n} from \"../types.js\";\n\n/**\n * A WaterfallHook chains multiple hook functions sequentially,\n * where each hook receives a context with the previous result,\n * initial arguments, and accumulated results. After all hooks\n * have executed, the final handler receives the transformed result.\n * Implements IHook for compatibility with Hookified.onHook().\n */\nexport class WaterfallHook implements IWaterfallHook {\n\tpublic id?: string;\n\tpublic event: string;\n\tpublic handler: HookFn;\n\tpublic hooks: WaterfallHookFn[];\n\n\tprivate readonly _finalHandler: WaterfallHookFn;\n\n\t/**\n\t * Creates a new WaterfallHook instance\n\t * @param {string} event - The event name for the hook\n\t * @param {WaterfallHookFn} finalHandler - The final handler function that receives the transformed result\n\t * @param {string} [id] - Optional unique identifier for the hook\n\t */\n\tconstructor(event: string, finalHandler: WaterfallHookFn, id?: string) {\n\t\tthis.id = id;\n\t\tthis.event = event;\n\t\tthis.hooks = [];\n\t\tthis._finalHandler = finalHandler;\n\n\t\t// biome-ignore lint/suspicious/noExplicitAny: this is for any parameter compatibility\n\t\tthis.handler = async (...arguments_: any[]) => {\n\t\t\t// biome-ignore lint/suspicious/noExplicitAny: waterfall result type varies through the chain\n\t\t\tconst initialArgs: any =\n\t\t\t\targuments_.length === 1 ? arguments_[0] : arguments_;\n\t\t\tconst results: WaterfallHookResult[] = [];\n\n\t\t\tfor (const hook of this.hooks) {\n\t\t\t\tconst result = await hook({ initialArgs, results: [...results] });\n\t\t\t\tresults.push({ hook, result });\n\t\t\t}\n\n\t\t\tawait this._finalHandler({ initialArgs, results: [...results] });\n\t\t};\n\t}\n\n\t/**\n\t * Adds a hook function to the end of the waterfall chain\n\t * @param {WaterfallHookFn} hook - The hook function to add\n\t */\n\tpublic addHook(hook: WaterfallHookFn): void {\n\t\tthis.hooks.push(hook);\n\t}\n\n\t/**\n\t * Removes a specific hook function from the waterfall chain\n\t * @param {WaterfallHookFn} hook - The hook function to remove\n\t * @returns {boolean} true if the hook was found and removed\n\t */\n\tpublic removeHook(hook: WaterfallHookFn): boolean {\n\t\tconst index = this.hooks.indexOf(hook);\n\t\tif (index !== -1) {\n\t\t\tthis.hooks.splice(index, 1);\n\t\t\treturn true;\n\t\t}\n\n\t\treturn false;\n\t}\n}\n","import { Eventified } from \"./eventified.js\";\nimport type {\n\tHookFn,\n\tHookifiedOptions,\n\tIHook,\n\tIWaterfallHook,\n\tOnHookOptions,\n\tPrependHookOptions,\n\tWaterfallHookContext,\n\tWaterfallHookFn,\n\tWaterfallHookResult,\n} from \"./types.js\";\n\nexport type {\n\tHookFn,\n\tHookifiedOptions,\n\tIHook,\n\tIWaterfallHook,\n\tOnHookOptions,\n\tPrependHookOptions,\n\tWaterfallHookContext,\n\tWaterfallHookFn,\n\tWaterfallHookResult,\n};\n\nexport class Hookified extends Eventified {\n\tprivate readonly _hooks: Map<string, IHook[]>;\n\tprivate _throwOnHookError = false;\n\tprivate _enforceBeforeAfter = false;\n\tprivate _deprecatedHooks: Map<string, string>;\n\tprivate _allowDeprecated = true;\n\tprivate _useHookClone = true;\n\n\tconstructor(options?: HookifiedOptions) {\n\t\tsuper({\n\t\t\teventLogger: options?.eventLogger,\n\t\t\tthrowOnEmitError: options?.throwOnEmitError,\n\t\t\tthrowOnEmptyListeners: options?.throwOnEmptyListeners,\n\t\t});\n\t\tthis._hooks = new Map();\n\t\tthis._deprecatedHooks = options?.deprecatedHooks\n\t\t\t? new Map(options.deprecatedHooks)\n\t\t\t: new Map();\n\n\t\tif (options?.throwOnHookError !== undefined) {\n\t\t\tthis._throwOnHookError = options.throwOnHookError;\n\t\t}\n\n\t\tif (options?.enforceBeforeAfter !== undefined) {\n\t\t\tthis._enforceBeforeAfter = options.enforceBeforeAfter;\n\t\t}\n\n\t\tif (options?.allowDeprecated !== undefined) {\n\t\t\tthis._allowDeprecated = options.allowDeprecated;\n\t\t}\n\n\t\tif (options?.useHookClone !== undefined) {\n\t\t\tthis._useHookClone = options.useHookClone;\n\t\t}\n\t}\n\n\t/**\n\t * Gets all hooks\n\t * @returns {Map<string, IHook[]>}\n\t */\n\tpublic get 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\tpublic get throwOnHookError() {\n\t\treturn this._throwOnHookError;\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\tpublic set throwOnHookError(value) {\n\t\tthis._throwOnHookError = value;\n\t}\n\n\t/**\n\t * Gets whether to enforce that all hook names start with 'before' or 'after'. Default is false.\n\t * @returns {boolean}\n\t * @default false\n\t */\n\tpublic get enforceBeforeAfter() {\n\t\treturn this._enforceBeforeAfter;\n\t}\n\n\t/**\n\t * Sets whether to enforce that all hook names start with 'before' or 'after'. Default is false.\n\t * @param {boolean} value\n\t */\n\tpublic set enforceBeforeAfter(value) {\n\t\tthis._enforceBeforeAfter = value;\n\t}\n\n\t/**\n\t * Gets the map of deprecated hook names to deprecation messages.\n\t * @returns {Map<string, string>}\n\t */\n\tpublic get deprecatedHooks() {\n\t\treturn this._deprecatedHooks;\n\t}\n\n\t/**\n\t * Sets the map of deprecated hook names to deprecation messages.\n\t * @param {Map<string, string>} value\n\t */\n\tpublic set deprecatedHooks(value) {\n\t\tthis._deprecatedHooks = value;\n\t}\n\n\t/**\n\t * Gets whether deprecated hooks are allowed to be registered and executed. Default is true.\n\t * @returns {boolean}\n\t */\n\tpublic get allowDeprecated() {\n\t\treturn this._allowDeprecated;\n\t}\n\n\t/**\n\t * Sets whether deprecated hooks are allowed to be registered and executed. Default is true.\n\t * @param {boolean} value\n\t */\n\tpublic set allowDeprecated(value) {\n\t\tthis._allowDeprecated = value;\n\t}\n\n\t/**\n\t * Gets whether hook objects are cloned before storing. Default is true.\n\t * @returns {boolean}\n\t */\n\tpublic get useHookClone() {\n\t\treturn this._useHookClone;\n\t}\n\n\t/**\n\t * Sets whether hook objects are cloned before storing. Default is true.\n\t * When false, the original IHook reference is stored directly.\n\t * @param {boolean} value\n\t */\n\tpublic set useHookClone(value) {\n\t\tthis._useHookClone = value;\n\t}\n\n\t/**\n\t * Adds a handler function for a specific event.\n\t * Supports both object and legacy signatures:\n\t * onHook({ event, handler }, options?)\n\t * onHook(event, handler)\n\t * To register multiple hooks at once, use {@link onHooks}.\n\t * @param {IHook | string} hookOrEvent - the hook object or event name\n\t * @param {OnHookOptions | HookFn} [optionsOrHandler] - options (when using object form) or handler function (when using string form)\n\t * @returns {IHook | undefined} the stored hook, or undefined if blocked by deprecation\n\t */\n\tpublic onHook(hook: IHook, options?: OnHookOptions): IHook | undefined;\n\tpublic onHook(event: string, handler: HookFn): IHook | undefined;\n\tpublic onHook(\n\t\thookOrEvent: IHook | string,\n\t\toptionsOrHandler?: OnHookOptions | HookFn,\n\t): IHook | undefined {\n\t\tlet hook: IHook;\n\t\tlet options: OnHookOptions | undefined;\n\n\t\tif (typeof hookOrEvent === \"string\") {\n\t\t\tif (typeof optionsOrHandler !== \"function\") {\n\t\t\t\tthrow new TypeError(\n\t\t\t\t\t\"When calling onHook(event, handler), the second argument must be a function\",\n\t\t\t\t);\n\t\t\t}\n\n\t\t\thook = { event: hookOrEvent, handler: optionsOrHandler };\n\t\t\toptions = undefined;\n\t\t} else {\n\t\t\thook = hookOrEvent;\n\t\t\toptions = optionsOrHandler as OnHookOptions | undefined;\n\t\t}\n\t\tthis.validateHookName(hook.event);\n\t\tif (!this.checkDeprecatedHook(hook.event)) {\n\t\t\treturn undefined; // Skip registration if deprecated hooks are not allowed\n\t\t}\n\n\t\tconst shouldClone = options?.useHookClone ?? this._useHookClone;\n\t\tconst entry: IHook = shouldClone\n\t\t\t? { id: hook.id, event: hook.event, handler: hook.handler }\n\t\t\t: hook;\n\n\t\tentry.id = entry.id ?? crypto.randomUUID();\n\n\t\tconst eventHandlers = this._hooks.get(hook.event);\n\t\tif (eventHandlers) {\n\t\t\t// Check for duplicate id — replace in-place if found\n\t\t\tconst existingIndex = eventHandlers.findIndex((h) => h.id === entry.id);\n\t\t\tif (existingIndex !== -1) {\n\t\t\t\teventHandlers[existingIndex] = entry;\n\t\t\t} else {\n\t\t\t\tconst position = options?.position ?? \"Bottom\";\n\t\t\t\tif (position === \"Top\") {\n\t\t\t\t\teventHandlers.unshift(entry);\n\t\t\t\t} else if (position === \"Bottom\") {\n\t\t\t\t\teventHandlers.push(entry);\n\t\t\t\t} else {\n\t\t\t\t\tconst index = Math.max(0, Math.min(position, eventHandlers.length));\n\t\t\t\t\teventHandlers.splice(index, 0, entry);\n\t\t\t\t}\n\t\t\t}\n\t\t} else {\n\t\t\tthis._hooks.set(hook.event, [entry]);\n\t\t}\n\n\t\treturn entry;\n\t}\n\n\t/**\n\t * Alias for onHook. This is provided for compatibility with other libraries that use the `addHook` method.\n\t * @param {string} event - the event name\n\t * @param {HookFn} handler - the handler function\n\t * @returns {void}\n\t */\n\tpublic addHook(event: string, handler: HookFn) {\n\t\tthis.onHook({ event, handler });\n\t}\n\n\t/**\n\t * Adds handler functions for specific events\n\t * @param {Array<IHook>} hooks\n\t * @param {OnHookOptions} [options] - optional per-call options (e.g., useHookClone override, position)\n\t * @returns {void}\n\t */\n\tpublic onHooks(hooks: IHook[], options?: OnHookOptions) {\n\t\tfor (const hook of hooks) {\n\t\t\tthis.onHook(hook, options);\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 * Equivalent to calling `onHook(hook, { position: \"Top\" })`.\n\t * @param {IHook} hook - the hook containing event name and handler\n\t * @param {PrependHookOptions} [options] - optional per-call options (e.g., useHookClone override)\n\t * @returns {IHook | undefined} the stored hook, or undefined if blocked by deprecation\n\t */\n\tpublic prependHook(\n\t\thook: IHook,\n\t\toptions?: PrependHookOptions,\n\t): IHook | undefined {\n\t\treturn this.onHook(hook, { ...options, position: \"Top\" });\n\t}\n\n\t/**\n\t * Adds a handler that only executes once for a specific event before all other handlers.\n\t * Equivalent to calling `onHook` with a self-removing wrapper and `{ position: \"Top\" }`.\n\t * @param {IHook} hook - the hook containing event name and handler\n\t * @param {PrependHookOptions} [options] - optional per-call options (e.g., useHookClone override)\n\t * @returns {IHook | undefined} the stored hook, or undefined if blocked by deprecation\n\t */\n\tpublic prependOnceHook(\n\t\thook: IHook,\n\t\toptions?: PrependHookOptions,\n\t): IHook | undefined {\n\t\t// biome-ignore lint/suspicious/noExplicitAny: this is for any parameter compatibility\n\t\tconst wrappedHandler = async (...arguments_: any[]) => {\n\t\t\tthis.removeHook({ event: hook.event, handler: wrappedHandler });\n\t\t\treturn hook.handler(...arguments_);\n\t\t};\n\n\t\t// Keep a reference to the original handler so removeHook() can remove the\n\t\t// once wrapper when called with the original handler reference.\n\t\t// biome-ignore lint/suspicious/noExplicitAny: attaching metadata to the wrapper\n\t\t(wrappedHandler as any)._originalHandler = hook.handler;\n\n\t\treturn this.onHook(\n\t\t\t{ id: hook.id, event: hook.event, handler: wrappedHandler },\n\t\t\t{ ...options, position: \"Top\" },\n\t\t);\n\t}\n\n\t/**\n\t * Adds a handler that only executes once for a specific event\n\t * @param {IHook} hook - the hook containing event name and handler\n\t */\n\tpublic onceHook(hook: IHook) {\n\t\tthis.validateHookName(hook.event);\n\t\tif (!this.checkDeprecatedHook(hook.event)) {\n\t\t\treturn; // Skip registration if deprecated hooks are not allowed\n\t\t}\n\t\t// biome-ignore lint/suspicious/noExplicitAny: this is for any parameter compatibility\n\t\tconst wrappedHandler = async (...arguments_: any[]) => {\n\t\t\tthis.removeHook({ event: hook.event, handler: wrappedHandler });\n\t\t\treturn hook.handler(...arguments_);\n\t\t};\n\n\t\t// Keep a reference to the original handler so removeHook() can remove the\n\t\t// once wrapper when called with the original handler reference.\n\t\t// biome-ignore lint/suspicious/noExplicitAny: attaching metadata to the wrapper\n\t\t(wrappedHandler as any)._originalHandler = hook.handler;\n\n\t\tthis.onHook({ id: hook.id, event: hook.event, handler: wrappedHandler });\n\t}\n\n\t/**\n\t * Removes a handler function for a specific event\n\t * @param {IHook} hook - the hook containing event name and handler to remove\n\t * @returns {IHook | undefined} the removed hook, or undefined if not found\n\t */\n\tpublic removeHook(hook: IHook): IHook | undefined {\n\t\tthis.validateHookName(hook.event);\n\t\tconst eventHandlers = this._hooks.get(hook.event);\n\t\tif (eventHandlers) {\n\t\t\t// Prefer an exact handler match before falling back to once-wrapper\n\t\t\t// matching, so a normal hook is never left behind when an identical\n\t\t\t// once-wrapper happens to precede it in the array.\n\t\t\tlet index = eventHandlers.findIndex((h) => h.handler === hook.handler);\n\t\t\tif (index === -1) {\n\t\t\t\tindex = eventHandlers.findIndex((h) => {\n\t\t\t\t\t// Match once-wrappers by their original handler reference. The\n\t\t\t\t\t// undefined guard prevents a normal hook (whose _originalHandler\n\t\t\t\t\t// is also undefined) from matching when hook.handler is undefined.\n\t\t\t\t\t// biome-ignore lint/suspicious/noExplicitAny: wrapper metadata lookup\n\t\t\t\t\tconst original = (h.handler as any)._originalHandler;\n\t\t\t\t\treturn original !== undefined && original === hook.handler;\n\t\t\t\t});\n\t\t\t}\n\t\t\tif (index !== -1) {\n\t\t\t\teventHandlers.splice(index, 1);\n\t\t\t\tif (eventHandlers.length === 0) {\n\t\t\t\t\tthis._hooks.delete(hook.event);\n\t\t\t\t}\n\n\t\t\t\treturn { event: hook.event, handler: hook.handler };\n\t\t\t}\n\t\t}\n\n\t\treturn undefined;\n\t}\n\n\t/**\n\t * Removes multiple hook handlers\n\t * @param {Array<IHook>} hooks\n\t * @returns {IHook[]} the hooks that were successfully removed\n\t */\n\tpublic removeHooks(hooks: IHook[]): IHook[] {\n\t\tconst removed: IHook[] = [];\n\t\tfor (const hook of hooks) {\n\t\t\tconst result = this.removeHook(hook);\n\t\t\tif (result) {\n\t\t\t\tremoved.push(result);\n\t\t\t}\n\t\t}\n\n\t\treturn removed;\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\tpublic async hook<T>(event: string, ...arguments_: T[]) {\n\t\tthis.validateHookName(event);\n\t\tif (!this.checkDeprecatedHook(event)) {\n\t\t\treturn; // Skip execution if deprecated hooks are not allowed\n\t\t}\n\t\tconst eventHandlers = this._hooks.get(event);\n\t\tif (eventHandlers) {\n\t\t\tfor (const hook of [...eventHandlers]) {\n\t\t\t\ttry {\n\t\t\t\t\tawait hook.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\n\t\t\t\t\tif (this._throwOnHookError) {\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 * Calls all synchronous handlers for a specific event.\n\t * Async handlers (declared with `async` keyword) are silently skipped.\n\t *\n\t * Note: The `hook` method is preferred as it executes both sync and async functions.\n\t * Use `hookSync` only when you specifically need synchronous execution.\n\t * @param {string} event\n\t * @param {T[]} arguments_\n\t * @returns {void}\n\t */\n\tpublic hookSync<T>(event: string, ...arguments_: T[]): void {\n\t\tthis.validateHookName(event);\n\t\tif (!this.checkDeprecatedHook(event)) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst eventHandlers = this._hooks.get(event);\n\t\tif (eventHandlers) {\n\t\t\tfor (const hook of [...eventHandlers]) {\n\t\t\t\t// Skip async functions silently\n\t\t\t\tif (hook.handler.constructor.name === \"AsyncFunction\") {\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\n\t\t\t\ttry {\n\t\t\t\t\thook.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\n\t\t\t\t\tif (this._throwOnHookError) {\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 * Prepends the word `before` to your hook. Example is event is `test`, the before hook is `before:test`.\n\t * @param {string} event - The event name\n\t * @param {T[]} arguments_ - The arguments to pass to the hook\n\t */\n\tpublic async beforeHook<T>(event: string, ...arguments_: T[]) {\n\t\tawait this.hook(`before:${event}`, ...arguments_);\n\t}\n\n\t/**\n\t * Prepends the word `after` to your hook. Example is event is `test`, the after hook is `after:test`.\n\t * @param {string} event - The event name\n\t * @param {T[]} arguments_ - The arguments to pass to the hook\n\t */\n\tpublic async afterHook<T>(event: string, ...arguments_: T[]) {\n\t\tawait this.hook(`after:${event}`, ...arguments_);\n\t}\n\n\t/**\n\t * Calls all handlers for a specific event. This is an alias for `hook` and is provided for\n\t * compatibility with other libraries that use the `callHook` method.\n\t * @param {string} event\n\t * @param {T[]} arguments_\n\t * @returns {Promise<void>}\n\t */\n\tpublic async callHook<T>(event: string, ...arguments_: T[]) {\n\t\tawait this.hook(event, ...arguments_);\n\t}\n\n\t/**\n\t * Gets all hooks for a specific event\n\t * @param {string} event\n\t * @returns {IHook[]}\n\t */\n\tpublic getHooks(event: string) {\n\t\tthis.validateHookName(event);\n\t\treturn this._hooks.get(event);\n\t}\n\n\t/**\n\t * Gets a specific hook by id, searching across all events\n\t * @param {string} id - the hook id\n\t * @returns {IHook | undefined} the hook if found, or undefined\n\t */\n\tpublic getHook(id: string): IHook | undefined {\n\t\tfor (const eventHandlers of this._hooks.values()) {\n\t\t\tconst found = eventHandlers.find((h) => h.id === id);\n\t\t\tif (found) {\n\t\t\t\treturn found;\n\t\t\t}\n\t\t}\n\n\t\treturn undefined;\n\t}\n\n\t/**\n\t * Removes one or more hooks by id, searching across all events\n\t * @param {string | string[]} id - the hook id or array of hook ids to remove\n\t * @returns {IHook | IHook[] | undefined} the removed hook(s), or undefined/empty array if not found\n\t */\n\tpublic removeHookById(id: string | string[]): IHook | IHook[] | undefined {\n\t\tif (Array.isArray(id)) {\n\t\t\tconst removed: IHook[] = [];\n\t\t\tfor (const singleId of id) {\n\t\t\t\tconst result = this.removeHookById(singleId);\n\t\t\t\tif (result && !Array.isArray(result)) {\n\t\t\t\t\tremoved.push(result);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\treturn removed;\n\t\t}\n\n\t\tfor (const [event, eventHandlers] of this._hooks.entries()) {\n\t\t\tconst index = eventHandlers.findIndex((h) => h.id === id);\n\t\t\tif (index !== -1) {\n\t\t\t\tconst [removed] = eventHandlers.splice(index, 1);\n\t\t\t\tif (eventHandlers.length === 0) {\n\t\t\t\t\tthis._hooks.delete(event);\n\t\t\t\t}\n\n\t\t\t\treturn removed;\n\t\t\t}\n\t\t}\n\n\t\treturn undefined;\n\t}\n\n\t/**\n\t * Removes all hooks\n\t * @returns {void}\n\t */\n\tpublic clearHooks() {\n\t\tthis._hooks.clear();\n\t}\n\n\t/**\n\t * Removes all hooks for a specific event and returns the removed hooks.\n\t * @param {string} event - The event name to remove hooks for.\n\t * @returns {IHook[]} the hooks that were removed\n\t */\n\tpublic removeEventHooks(event: string): IHook[] {\n\t\tthis.validateHookName(event);\n\t\tconst eventHandlers = this._hooks.get(event);\n\t\tif (eventHandlers) {\n\t\t\tconst removed = [...eventHandlers];\n\t\t\tthis._hooks.delete(event);\n\t\t\treturn removed;\n\t\t}\n\n\t\treturn [];\n\t}\n\n\t/**\n\t * Validates hook event name if enforceBeforeAfter is enabled\n\t * @param {string} event - The event name to validate\n\t * @throws {Error} If enforceBeforeAfter is true and event doesn't start with 'before' or 'after'\n\t */\n\tprivate validateHookName(event: string): void {\n\t\tif (this._enforceBeforeAfter) {\n\t\t\tconst eventValue = event.trim().toLocaleLowerCase();\n\t\t\tif (!eventValue.startsWith(\"before\") && !eventValue.startsWith(\"after\")) {\n\t\t\t\tthrow new Error(\n\t\t\t\t\t`Hook event \"${event}\" must start with \"before\" or \"after\" when enforceBeforeAfter is enabled`,\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Checks if a hook is deprecated and emits a warning if it is\n\t * @param {string} event - The event name to check\n\t * @returns {boolean} - Returns true if the hook should proceed, false if it should be blocked\n\t */\n\tprivate checkDeprecatedHook(event: string): boolean {\n\t\tif (this._deprecatedHooks.has(event)) {\n\t\t\tconst message = this._deprecatedHooks.get(event);\n\t\t\tconst warningMessage = `Hook \"${event}\" is deprecated${message ? `: ${message}` : \"\"}`;\n\n\t\t\t// Emit deprecation warning event\n\t\t\tthis.emit(\"warn\", { hook: event, message: warningMessage });\n\n\t\t\t// Return false if deprecated hooks are not allowed\n\t\t\treturn this._allowDeprecated;\n\t\t}\n\t\treturn true;\n\t}\n}\n\nexport { Eventified } from \"./eventified.js\";\nexport { Hook } from \"./hooks/hook.js\";\nexport { ParallelHook } from \"./hooks/parallel-hook.js\";\nexport { WaterfallHook } from \"./hooks/waterfall-hook.js\";\nexport type {\n\tEventEmitterOptions,\n\tEventListener,\n\tIEventEmitter,\n\tIParallelHook,\n\tLogger,\n\tParallelHookContext,\n\tParallelHookFinalContext,\n\tParallelHookFinalFn,\n\tParallelHookFn,\n\tParallelHookResult,\n} from \"./types.js\";\n"],"mappings":"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"}

@@ -70,2 +70,3 @@ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });

};
onceListener._originalListener = listener;
this.on(eventName, onceListener);

@@ -131,2 +132,3 @@ return this;

};
onceListener._originalListener = listener;
this.prependListener(eventName, onceListener);

@@ -185,2 +187,15 @@ return this;

/**
* Determines whether a stored listener matches the listener provided to off().
* A match occurs when the references are identical, or when the stored listener
* is a once-wrapper whose original listener equals the provided reference.
* @param {EventListener} stored - the listener currently stored
* @param {EventListener} target - the listener passed to off()
* @returns {boolean} true if the stored listener should be removed
*/
matchesListener(stored, target) {
if (stored === target) return true;
const original = stored._originalListener;
return original !== void 0 && original === target;
}
/**
* Removes a listener for a specific event

@@ -195,6 +210,7 @@ * @param {string | symbol} event

if (typeof entry === "function") {
if (entry === listener) this._eventListeners.delete(event);
if (this.matchesListener(entry, listener)) this._eventListeners.delete(event);
return this;
}
const index = entry.indexOf(listener);
let index = entry.indexOf(listener);
if (index === -1) index = entry.findIndex((stored) => this.matchesListener(stored, listener));
if (index !== -1) if (entry.length === 2) this._eventListeners.set(event, entry[1 - index]);

@@ -220,6 +236,7 @@ else if (entry.length === 1) this._eventListeners.delete(event);

else {
const len = entry.length;
for (let i = 0; i < len; i++) if (argumentLength === 1) entry[i](arguments_[0]);
else if (argumentLength === 2) entry[i](arguments_[0], arguments_[1]);
else entry[i](...arguments_);
const listeners = entry.slice();
const len = listeners.length;
for (let i = 0; i < len; i++) if (argumentLength === 1) listeners[i](arguments_[0]);
else if (argumentLength === 2) listeners[i](arguments_[0], arguments_[1]);
else listeners[i](...arguments_);
}

@@ -683,2 +700,3 @@ result = true;

};
wrappedHandler._originalHandler = hook.handler;
return this.onHook({

@@ -707,2 +725,3 @@ id: hook.id,

};
wrappedHandler._originalHandler = hook.handler;
this.onHook({

@@ -723,3 +742,7 @@ id: hook.id,

if (eventHandlers) {
const index = eventHandlers.findIndex((h) => h.handler === hook.handler);
let index = eventHandlers.findIndex((h) => h.handler === hook.handler);
if (index === -1) index = eventHandlers.findIndex((h) => {
const original = h.handler._originalHandler;
return original !== void 0 && original === hook.handler;
});
if (index !== -1) {

@@ -726,0 +749,0 @@ eventHandlers.splice(index, 1);

@@ -424,2 +424,11 @@ //#region src/types.d.ts

/**
* Determines whether a stored listener matches the listener provided to off().
* A match occurs when the references are identical, or when the stored listener
* is a once-wrapper whose original listener equals the provided reference.
* @param {EventListener} stored - the listener currently stored
* @param {EventListener} target - the listener passed to off()
* @returns {boolean} true if the stored listener should be removed
*/
private matchesListener;
/**
* Removes a listener for a specific event

@@ -426,0 +435,0 @@ * @param {string | symbol} event

@@ -424,2 +424,11 @@ //#region src/types.d.ts

/**
* Determines whether a stored listener matches the listener provided to off().
* A match occurs when the references are identical, or when the stored listener
* is a once-wrapper whose original listener equals the provided reference.
* @param {EventListener} stored - the listener currently stored
* @param {EventListener} target - the listener passed to off()
* @returns {boolean} true if the stored listener should be removed
*/
private matchesListener;
/**
* Removes a listener for a specific event

@@ -426,0 +435,0 @@ * @param {string | symbol} event

@@ -69,2 +69,3 @@ //#region src/eventified.ts

};
onceListener._originalListener = listener;
this.on(eventName, onceListener);

@@ -130,2 +131,3 @@ return this;

};
onceListener._originalListener = listener;
this.prependListener(eventName, onceListener);

@@ -184,2 +186,15 @@ return this;

/**
* Determines whether a stored listener matches the listener provided to off().
* A match occurs when the references are identical, or when the stored listener
* is a once-wrapper whose original listener equals the provided reference.
* @param {EventListener} stored - the listener currently stored
* @param {EventListener} target - the listener passed to off()
* @returns {boolean} true if the stored listener should be removed
*/
matchesListener(stored, target) {
if (stored === target) return true;
const original = stored._originalListener;
return original !== void 0 && original === target;
}
/**
* Removes a listener for a specific event

@@ -194,6 +209,7 @@ * @param {string | symbol} event

if (typeof entry === "function") {
if (entry === listener) this._eventListeners.delete(event);
if (this.matchesListener(entry, listener)) this._eventListeners.delete(event);
return this;
}
const index = entry.indexOf(listener);
let index = entry.indexOf(listener);
if (index === -1) index = entry.findIndex((stored) => this.matchesListener(stored, listener));
if (index !== -1) if (entry.length === 2) this._eventListeners.set(event, entry[1 - index]);

@@ -219,6 +235,7 @@ else if (entry.length === 1) this._eventListeners.delete(event);

else {
const len = entry.length;
for (let i = 0; i < len; i++) if (argumentLength === 1) entry[i](arguments_[0]);
else if (argumentLength === 2) entry[i](arguments_[0], arguments_[1]);
else entry[i](...arguments_);
const listeners = entry.slice();
const len = listeners.length;
for (let i = 0; i < len; i++) if (argumentLength === 1) listeners[i](arguments_[0]);
else if (argumentLength === 2) listeners[i](arguments_[0], arguments_[1]);
else listeners[i](...arguments_);
}

@@ -682,2 +699,3 @@ result = true;

};
wrappedHandler._originalHandler = hook.handler;
return this.onHook({

@@ -706,2 +724,3 @@ id: hook.id,

};
wrappedHandler._originalHandler = hook.handler;
this.onHook({

@@ -722,3 +741,7 @@ id: hook.id,

if (eventHandlers) {
const index = eventHandlers.findIndex((h) => h.handler === hook.handler);
let index = eventHandlers.findIndex((h) => h.handler === hook.handler);
if (index === -1) index = eventHandlers.findIndex((h) => {
const original = h.handler._originalHandler;
return original !== void 0 && original === hook.handler;
});
if (index !== -1) {

@@ -725,0 +748,0 @@ eventHandlers.splice(index, 1);

{
"name": "hookified",
"version": "3.0.0",
"version": "3.0.1",
"description": "Event Emitting and Middleware Hooks",

@@ -62,6 +62,6 @@ "type": "module",

"devDependencies": {
"@biomejs/biome": "^2.4.15",
"@biomejs/biome": "^2.5.0",
"@monstermann/tinybench-pretty-printer": "^0.3.0",
"@types/node": "^24.12.2",
"@vitest/coverage-v8": "^4.1.0",
"@vitest/coverage-v8": "^4.1.8",
"docula": "^2.0.0",

@@ -74,6 +74,6 @@ "emittery": "^2.0.0",

"tinybench": "^6.0.2",
"tsdown": "^0.22.0",
"tsx": "^4.19.0",
"tsdown": "^0.22.2",
"tsx": "^4.22.4",
"typescript": "^6.0.3",
"vitest": "^4.1.0"
"vitest": "^4.1.8"
},

@@ -90,5 +90,6 @@ "files": [

"build": "tsdown",
"benchmark": "pnpm benchmark:hooks && pnpm benchmark:emit",
"benchmark": "pnpm benchmark:hooks && pnpm benchmark:emit && pnpm benchmark:emit-multi",
"benchmark:hooks": "pnpm tsx benchmark/hook.ts",
"benchmark:emit": "pnpm tsx benchmark/emit.ts",
"benchmark:emit-multi": "pnpm tsx benchmark/emit-multi.ts",
"benchmark:readme": "pnpm tsx scripts/benchmark-readme.ts",

@@ -95,0 +96,0 @@ "website:build": "docula build",