New:Socket for Asana Is Now Available.Learn more
Sign In

hookified

Package Overview
Dependencies
Maintainers
1
Versions
39
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
2.2.0
to
3.0.0
+4
-4
dist/browser/index.global.js
var Hookified = (function(exports) {
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
//#region \0@oxc-project+runtime@0.127.0/helpers/typeof.js
//#region \0@oxc-project+runtime@0.130.0/helpers/typeof.js
function _typeof(o) {

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

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

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

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

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

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

@@ -36,0 +36,0 @@ return (r = toPropertyKey(r)) in e ? Object.defineProperty(e, r, {

@@ -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\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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"}

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

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

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

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

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

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

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

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

@@ -34,0 +34,0 @@ return (r = toPropertyKey(r)) in e ? Object.defineProperty(e, r, {

@@ -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":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAUA,MAAM,cAAc;AAEpB,IAAa,aAAb,MAAiD;CAUhD,YAAY,SAA+B;wBAT1B,mBAAA,KAAA,EAGf;wBACM,iBAAA,KAAA,EAAsB;wBACtB,gBAAA,KAAA,EAAsB;wBACtB,qBAAoB,MAAM;wBAC1B,0BAAyB,KAAK;AAGrC,OAAK,kCAAkB,IAAI,KAGxB;AACH,OAAK,gBAAgB;AAErB,OAAK,eAAe,SAAS;AAE7B,MAAI,SAAS,qBAAqB,KAAA,EACjC,MAAK,oBAAoB,QAAQ;AAGlC,MAAI,SAAS,0BAA0B,KAAA,EACtC,MAAK,yBAAyB,QAAQ;;;;;;CAQxC,IAAW,cAAkC;AAC5C,SAAO,KAAK;;;;;;CAOb,IAAW,YAAY,aAAiC;AACvD,OAAK,eAAe;;;;;;CAOrB,IAAW,mBAA4B;AACtC,SAAO,KAAK;;;;;;CAOb,IAAW,iBAAiB,OAAgB;AAC3C,OAAK,oBAAoB;;;;;;CAO1B,IAAW,wBAAiC;AAC3C,SAAO,KAAK;;;;;;CAOb,IAAW,sBAAsB,OAAgB;AAChD,OAAK,yBAAyB;;;;;;;;CAS/B,KACC,WACA,UACgB;EAChB,MAAM,gBAA+B,GAAG,eAAsB;AAC7D,QAAK,IAAI,WAAqB,aAAa;AAC3C,YAAS,GAAG,WAAW;;AAGxB,OAAK,GAAG,WAAqB,aAAa;AAC1C,SAAO;;;;;;;CAQR,cAAqB,WAAqC;AACzD,MAAI,cAAc,KAAA,GAAW;GAC5B,IAAI,QAAQ;AACZ,QAAK,MAAM,SAAS,KAAK,gBAAgB,QAAQ,CAChD,UAAS,OAAO,UAAU,aAAa,IAAI,MAAM;AAGlD,UAAO;;EAGR,MAAM,QAAQ,KAAK,gBAAgB,IAAI,UAAU;AACjD,MAAI,UAAU,KAAA,EACb,QAAO;AAGR,SAAO,OAAO,UAAU,aAAa,IAAI,MAAM;;;;;;CAOhD,aAA4C;AAC3C,SAAO,CAAC,GAAG,KAAK,gBAAgB,MAAM,CAAC;;;;;;;CAQxC,aAAoB,OAA0C;AAC7D,MAAI,UAAU,KAAA,EACb,QAAO,KAAK,iBAAiB;EAG9B,MAAM,QAAQ,KAAK,gBAAgB,IAAI,MAAM;AAC7C,MAAI,UAAU,KAAA,EACb,QAAO,EAAE;AAGV,SAAO,OAAO,UAAU,aAAa,CAAC,MAAM,GAAG;;;;;;;;CAShD,gBACC,WACA,UACgB;EAChB,MAAM,WAAW,KAAK,gBAAgB,IAAI,UAAU;AAEpD,MAAI,aAAa,KAAA,EAChB,MAAK,gBAAgB,IAAI,WAAW,SAAS;WACnC,OAAO,aAAa,WAC9B,MAAK,gBAAgB,IAAI,WAAW,CAAC,UAAU,SAAS,CAAC;MAEzD,UAAS,QAAQ,SAAS;AAG3B,SAAO;;;;;;;;CASR,oBACC,WACA,UACgB;EAChB,MAAM,gBAA+B,GAAG,eAAsB;AAC7D,QAAK,IAAI,WAAqB,aAAa;AAC3C,YAAS,GAAG,WAAW;;AAGxB,OAAK,gBAAgB,WAAqB,aAAa;AACvD,SAAO;;;;;;CAOR,eAA8B;AAC7B,SAAO,KAAK;;;;;;;;CASb,YACC,OACA,UACgB;AAChB,OAAK,GAAG,OAAO,SAAS;AACxB,SAAO;;;;;;;;CASR,GAAU,OAAwB,UAAwC;EACzE,MAAM,WAAW,KAAK,gBAAgB,IAAI,MAAM;AAEhD,MAAI,aAAa,KAAA,GAAW;AAC3B,QAAK,gBAAgB,IAAI,OAAO,SAAS;AACzC,UAAO;;AAGR,MAAI,OAAO,aAAa,YAAY;GACnC,MAAM,MAAM,CAAC,UAAU,SAAS;AAChC,QAAK,gBAAgB,IAAI,OAAO,IAAI;AACpC,OAAI,KAAK,gBAAgB,KAAK,IAAI,SAAS,KAAK,cAC/C,SAAQ,KACP,qEAAqE,IAAI,OAAO,GAAG,MAAgB,4DACnG;SAEI;AACN,YAAS,KAAK,SAAS;AACvB,OAAI,KAAK,gBAAgB,KAAK,SAAS,SAAS,KAAK,cACpD,SAAQ,KACP,qEAAqE,SAAS,OAAO,GAAG,MAAgB,4DACxG;;AAIH,SAAO;;;;;;;;CASR,eAAsB,OAAe,UAAwC;AAC5E,OAAK,IAAI,OAAO,SAAS;AACzB,SAAO;;;;;;;;CASR,IAAW,OAAwB,UAAwC;EAC1E,MAAM,QAAQ,KAAK,gBAAgB,IAAI,MAAM;AAC7C,MAAI,UAAU,KAAA,EACb,QAAO;AAGR,MAAI,OAAO,UAAU,YAAY;AAChC,OAAI,UAAU,SACb,MAAK,gBAAgB,OAAO,MAAM;AAGnC,UAAO;;EAGR,MAAM,QAAQ,MAAM,QAAQ,SAAS;AACrC,MAAI,UAAU,GACb,KAAI,MAAM,WAAW,EACpB,MAAK,gBAAgB,IAAI,OAAO,MAAM,IAAI,OAAO;WAEvC,MAAM,WAAW,EAC3B,MAAK,gBAAgB,OAAO,MAAM;MAGlC,OAAM,OAAO,OAAO,EAAE;AAIxB,SAAO;;;;;;;;CASR,KAAY,OAAwB,GAAG,YAA4B;EAClE,IAAI,SAAS;EACb,MAAM,QAAQ,KAAK,gBAAgB,IAAI,MAAM;EAC7C,MAAM,iBAAiB,WAAW;AAElC,MAAI,UAAU,KAAA,GAAW;AACxB,OAAI,OAAO,UAAU,WACpB,KAAI,mBAAmB,EACtB,OAAM,WAAW,GAAG;YACV,mBAAmB,EAC7B,OAAM,WAAW,IAAI,WAAW,GAAG;OAEnC,OAAM,GAAG,WAAW;QAEf;IACN,MAAM,MAAM,MAAM;AAClB,SAAK,IAAI,IAAI,GAAG,IAAI,KAAK,IACxB,KAAI,mBAAmB,EACtB,OAAM,GAAG,WAAW,GAAG;aACb,mBAAmB,EAC7B,OAAM,GAAG,WAAW,IAAI,WAAW,GAAG;QAEtC,OAAM,GAAG,GAAG,WAAW;;AAK1B,YAAS;;AAIV,MAAI,KAAK,aACR,MAAK,kBAAkB,OAAO,WAAW;AAG1C,MAAI,CAAC,UAAU,UAAU,aAAa;GACrC,MAAM,QACL,WAAW,cAAc,QACtB,WAAW,qBACX,IAAI,MAAM,GAAG,WAAW,KAAK;AAEjC,OAAI,KAAK,qBAAqB,KAAK,uBAClC,OAAM;;AAIR,SAAO;;;;;;;CAQR,UAAiB,OAAyC;EACzD,MAAM,QAAQ,KAAK,gBAAgB,IAAI,MAAM;AAC7C,MAAI,UAAU,KAAA,EACb,QAAO,EAAE;AAGV,SAAO,OAAO,UAAU,aAAa,CAAC,MAAM,GAAG;;;;;;;CAQhD,mBAA0B,OAAwC;AACjE,MAAI,UAAU,KAAA,EACb,MAAK,gBAAgB,OAAO,MAAM;MAElC,MAAK,gBAAgB,OAAO;AAG7B,SAAO;;;;;;;CAQR,gBAAuB,GAAiB;AACvC,OAAK,gBAAgB,IAAI,IAAI,IAAI;;;;;;CAOlC,kBAA0C;EACzC,MAAM,SAA0B,EAAE;AAClC,OAAK,MAAM,SAAS,KAAK,gBAAgB,QAAQ,CAChD,KAAI,OAAO,UAAU,WACpB,QAAO,KAAK,MAAM;MAElB,MAAK,IAAI,IAAI,GAAG,IAAI,MAAM,QAAQ,IACjC,QAAO,KAAK,MAAM,GAAG;AAKxB,SAAO;;;;;;;CAQR,kBAA0B,WAA4B,MAAiB;;AAEtE,MAAI,CAAC,KAAK,aACT;EAGD,IAAI;;AAEJ,MAAI,OAAO,SAAS,SACnB,WAAU;WAEV,MAAM,QAAQ,KAAK,IACnB,KAAK,SAAS,KACd,KAAK,cAAc,MAEnB,WAAU,KAAK,GAAG;WAER,gBAAgB,MAC1B,WAAU,KAAK;WAEf,MAAM,QAAQ,KAAK,IACnB,KAAK,SAAS,KACd,OAAO,KAAK,IAAI,YAAY,SAE5B,WAAU,KAAK,GAAG;MAElB,WAAU,KAAK,UAAU,KAAK;AAG/B,UAAQ,WAAR;GACC,KAAK;AACJ,SAAK,aAAa,QAAQ,SAAS;KAAE,OAAO;KAAW;KAAM,CAAC;AAC9D;GAGD,KAAK;AACJ,SAAK,aAAa,OAAO,SAAS;KAAE,OAAO;KAAW;KAAM,CAAC;AAC7D;GAGD,KAAK;AACJ,SAAK,aAAa,QAAQ,SAAS;KAAE,OAAO;KAAW;KAAM,CAAC;AAC9D;GAGD,KAAK;AACJ,SAAK,aAAa,QAAQ,SAAS;KAAE,OAAO;KAAW;KAAM,CAAC;AAC9D;GAGD,KAAK;AACJ,SAAK,aAAa,QAAQ,SAAS;KAAE,OAAO;KAAW;KAAM,CAAC;AAC9D;GAGD;AACC,SAAK,aAAa,OAAO,SAAS;KAAE,OAAO;KAAW;KAAM,CAAC;AAC7D;;;;;;;;;;ACrdJ,IAAa,OAAb,MAAmC;;;;;;;CAWlC,YAAY,OAAe,SAAiB,IAAa;wBAVlD,MAAA,KAAA,EAAY;wBACZ,SAAA,KAAA,EAAc;wBACd,WAAA,KAAA,EAAgB;AAStB,OAAK,KAAK;AACV,OAAK,QAAQ;AACb,OAAK,UAAU;;;;;;;;;;;;;;;;;;;;;;;ACOjB,IAAa,eAAb,MAEA;;;;;;;CAcC,YACC,OACA,cACA,IACC;wBAjBK,MAAA,KAAA,EAAY;wBACZ,SAAA,KAAA,EAAc;wBACd,WAAA,KAAA,EAAgB;wBAChB,SAAA,KAAA,EAAwC;wBAE9B,iBAAA,KAAA,EAAmD;AAanE,OAAK,KAAK;AACV,OAAK,QAAQ;AACb,OAAK,QAAQ,EAAE;AACf,OAAK,gBAAgB;AAGrB,OAAK,UAAU,OAAO,GAAG,eAAsB;GAC9C,MAAM,cACL,WAAW,WAAW,IAAI,WAAW,KAAK;GAM3C,MAAM,WAAW,CAAC,GAAG,KAAK,MAAM;GAEhC,MAAM,UAAU,MAAM,QAAQ,WAC7B,SAAS,KAAK,SACb,QAAQ,SAAS,CAAC,WAAW,KAAK,EAAE,aAAa,CAAC,CAAC,CACnD,CACD;GAED,MAAM,0BAAU,IAAI,KAGjB;AACH,YAAS,SAAS,MAAM,UAAU;IACjC,MAAM,UAAU,QAAQ;AACxB,YAAQ,IACP,MACA,QAAQ,WAAW,cAChB;KAAE,QAAQ;KAAa,QAAQ,QAAQ;KAAO,GAC9C;KAAE,QAAQ;KAAY,QAAQ,QAAQ;KAAQ,CACjD;KACA;AAEF,SAAM,KAAK,cAAc;IAAE;IAAa;IAAS,CAAC;;;;;;;CAQpD,QAAe,MAA4C;AAC1D,OAAK,MAAM,KAAK,KAAK;;;;;;;CAQtB,WAAkB,MAA+C;EAChE,MAAM,QAAQ,KAAK,MAAM,QAAQ,KAAK;AACtC,MAAI,UAAU,IAAI;AACjB,QAAK,MAAM,OAAO,OAAO,EAAE;AAC3B,UAAO;;AAGR,SAAO;;;;;;;;;;;;AC9FT,IAAa,gBAAb,MAAqD;;;;;;;CAcpD,YAAY,OAAe,cAA+B,IAAa;wBAbhE,MAAA,KAAA,EAAY;wBACZ,SAAA,KAAA,EAAc;wBACd,WAAA,KAAA,EAAgB;wBAChB,SAAA,KAAA,EAAyB;wBAEf,iBAAA,KAAA,EAA+B;AAS/C,OAAK,KAAK;AACV,OAAK,QAAQ;AACb,OAAK,QAAQ,EAAE;AACf,OAAK,gBAAgB;AAGrB,OAAK,UAAU,OAAO,GAAG,eAAsB;GAE9C,MAAM,cACL,WAAW,WAAW,IAAI,WAAW,KAAK;GAC3C,MAAM,UAAiC,EAAE;AAEzC,QAAK,MAAM,QAAQ,KAAK,OAAO;IAC9B,MAAM,SAAS,MAAM,KAAK;KAAE;KAAa,SAAS,CAAC,GAAG,QAAQ;KAAE,CAAC;AACjE,YAAQ,KAAK;KAAE;KAAM;KAAQ,CAAC;;AAG/B,SAAM,KAAK,cAAc;IAAE;IAAa,SAAS,CAAC,GAAG,QAAQ;IAAE,CAAC;;;;;;;CAQlE,QAAe,MAA6B;AAC3C,OAAK,MAAM,KAAK,KAAK;;;;;;;CAQtB,WAAkB,MAAgC;EACjD,MAAM,QAAQ,KAAK,MAAM,QAAQ,KAAK;AACtC,MAAI,UAAU,IAAI;AACjB,QAAK,MAAM,OAAO,OAAO,EAAE;AAC3B,UAAO;;AAGR,SAAO;;;;;AC7CT,IAAa,YAAb,cAA+B,WAAW;CAQzC,YAAY,SAA4B;AACvC,QAAM;GACL,aAAa,SAAS;GACtB,kBAAkB,SAAS;GAC3B,uBAAuB,SAAS;GAChC,CAAC;wBAZc,UAAA,KAAA,EAA6B;wBACtC,qBAAoB,MAAM;wBAC1B,uBAAsB,MAAM;wBAC5B,oBAAA,KAAA,EAAsC;wBACtC,oBAAmB,KAAK;wBACxB,iBAAgB,KAAK;AAQ5B,OAAK,yBAAS,IAAI,KAAK;AACvB,OAAK,mBAAmB,SAAS,kBAC9B,IAAI,IAAI,QAAQ,gBAAgB,mBAChC,IAAI,KAAK;AAEZ,MAAI,SAAS,qBAAqB,KAAA,EACjC,MAAK,oBAAoB,QAAQ;AAGlC,MAAI,SAAS,uBAAuB,KAAA,EACnC,MAAK,sBAAsB,QAAQ;AAGpC,MAAI,SAAS,oBAAoB,KAAA,EAChC,MAAK,mBAAmB,QAAQ;AAGjC,MAAI,SAAS,iBAAiB,KAAA,EAC7B,MAAK,gBAAgB,QAAQ;;;;;;CAQ/B,IAAW,QAAQ;AAClB,SAAO,KAAK;;;;;;CAOb,IAAW,mBAAmB;AAC7B,SAAO,KAAK;;;;;;CAOb,IAAW,iBAAiB,OAAO;AAClC,OAAK,oBAAoB;;;;;;;CAQ1B,IAAW,qBAAqB;AAC/B,SAAO,KAAK;;;;;;CAOb,IAAW,mBAAmB,OAAO;AACpC,OAAK,sBAAsB;;;;;;CAO5B,IAAW,kBAAkB;AAC5B,SAAO,KAAK;;;;;;CAOb,IAAW,gBAAgB,OAAO;AACjC,OAAK,mBAAmB;;;;;;CAOzB,IAAW,kBAAkB;AAC5B,SAAO,KAAK;;;;;;CAOb,IAAW,gBAAgB,OAAO;AACjC,OAAK,mBAAmB;;;;;;CAOzB,IAAW,eAAe;AACzB,SAAO,KAAK;;;;;;;CAQb,IAAW,aAAa,OAAO;AAC9B,OAAK,gBAAgB;;CAetB,OACC,aACA,kBACoB;EACpB,IAAI;EACJ,IAAI;AAEJ,MAAI,OAAO,gBAAgB,UAAU;AACpC,OAAI,OAAO,qBAAqB,WAC/B,OAAM,IAAI,UACT,8EACA;AAGF,UAAO;IAAE,OAAO;IAAa,SAAS;IAAkB;AACxD,aAAU,KAAA;SACJ;AACN,UAAO;AACP,aAAU;;AAEX,OAAK,iBAAiB,KAAK,MAAM;AACjC,MAAI,CAAC,KAAK,oBAAoB,KAAK,MAAM,CACxC;EAID,MAAM,QADc,SAAS,gBAAgB,KAAK,gBAE/C;GAAE,IAAI,KAAK;GAAI,OAAO,KAAK;GAAO,SAAS,KAAK;GAAS,GACzD;AAEH,QAAM,KAAK,MAAM,MAAM,OAAO,YAAY;EAE1C,MAAM,gBAAgB,KAAK,OAAO,IAAI,KAAK,MAAM;AACjD,MAAI,eAAe;GAElB,MAAM,gBAAgB,cAAc,WAAW,MAAM,EAAE,OAAO,MAAM,GAAG;AACvE,OAAI,kBAAkB,GACrB,eAAc,iBAAiB;QACzB;IACN,MAAM,WAAW,SAAS,YAAY;AACtC,QAAI,aAAa,MAChB,eAAc,QAAQ,MAAM;aAClB,aAAa,SACvB,eAAc,KAAK,MAAM;SACnB;KACN,MAAM,QAAQ,KAAK,IAAI,GAAG,KAAK,IAAI,UAAU,cAAc,OAAO,CAAC;AACnE,mBAAc,OAAO,OAAO,GAAG,MAAM;;;QAIvC,MAAK,OAAO,IAAI,KAAK,OAAO,CAAC,MAAM,CAAC;AAGrC,SAAO;;;;;;;;CASR,QAAe,OAAe,SAAiB;AAC9C,OAAK,OAAO;GAAE;GAAO;GAAS,CAAC;;;;;;;;CAShC,QAAe,OAAgB,SAAyB;AACvD,OAAK,MAAM,QAAQ,MAClB,MAAK,OAAO,MAAM,QAAQ;;;;;;;;;CAW5B,YACC,MACA,SACoB;AACpB,SAAO,KAAK,OAAO,MAAM;GAAE,GAAG;GAAS,UAAU;GAAO,CAAC;;;;;;;;;CAU1D,gBACC,MACA,SACoB;EAEpB,MAAM,iBAAiB,OAAO,GAAG,eAAsB;AACtD,QAAK,WAAW;IAAE,OAAO,KAAK;IAAO,SAAS;IAAgB,CAAC;AAC/D,UAAO,KAAK,QAAQ,GAAG,WAAW;;AAGnC,SAAO,KAAK,OACX;GAAE,IAAI,KAAK;GAAI,OAAO,KAAK;GAAO,SAAS;GAAgB,EAC3D;GAAE,GAAG;GAAS,UAAU;GAAO,CAC/B;;;;;;CAOF,SAAgB,MAAa;AAC5B,OAAK,iBAAiB,KAAK,MAAM;AACjC,MAAI,CAAC,KAAK,oBAAoB,KAAK,MAAM,CACxC;EAGD,MAAM,iBAAiB,OAAO,GAAG,eAAsB;AACtD,QAAK,WAAW;IAAE,OAAO,KAAK;IAAO,SAAS;IAAgB,CAAC;AAC/D,UAAO,KAAK,QAAQ,GAAG,WAAW;;AAGnC,OAAK,OAAO;GAAE,IAAI,KAAK;GAAI,OAAO,KAAK;GAAO,SAAS;GAAgB,CAAC;;;;;;;CAQzE,WAAkB,MAAgC;AACjD,OAAK,iBAAiB,KAAK,MAAM;EACjC,MAAM,gBAAgB,KAAK,OAAO,IAAI,KAAK,MAAM;AACjD,MAAI,eAAe;GAClB,MAAM,QAAQ,cAAc,WAAW,MAAM,EAAE,YAAY,KAAK,QAAQ;AACxE,OAAI,UAAU,IAAI;AACjB,kBAAc,OAAO,OAAO,EAAE;AAC9B,QAAI,cAAc,WAAW,EAC5B,MAAK,OAAO,OAAO,KAAK,MAAM;AAG/B,WAAO;KAAE,OAAO,KAAK;KAAO,SAAS,KAAK;KAAS;;;;;;;;;CAYtD,YAAmB,OAAyB;EAC3C,MAAM,UAAmB,EAAE;AAC3B,OAAK,MAAM,QAAQ,OAAO;GACzB,MAAM,SAAS,KAAK,WAAW,KAAK;AACpC,OAAI,OACH,SAAQ,KAAK,OAAO;;AAItB,SAAO;;;;;;;;CASR,MAAa,KAAQ,OAAe,GAAG,YAAiB;AACvD,OAAK,iBAAiB,MAAM;AAC5B,MAAI,CAAC,KAAK,oBAAoB,MAAM,CACnC;EAED,MAAM,gBAAgB,KAAK,OAAO,IAAI,MAAM;AAC5C,MAAI,cACH,MAAK,MAAM,QAAQ,CAAC,GAAG,cAAc,CACpC,KAAI;AACH,SAAM,KAAK,QAAQ,GAAG,WAAW;WACzB,OAAO;GACf,MAAM,UAAU,GAAG,MAAM,IAAK,MAAgB;AAC9C,QAAK,KAAK,SAAS,IAAI,MAAM,QAAQ,CAAC;AAEtC,OAAI,KAAK,kBACR,OAAM,IAAI,MAAM,QAAQ;;;;;;;;;;;;;CAiB7B,SAAmB,OAAe,GAAG,YAAuB;AAC3D,OAAK,iBAAiB,MAAM;AAC5B,MAAI,CAAC,KAAK,oBAAoB,MAAM,CACnC;EAGD,MAAM,gBAAgB,KAAK,OAAO,IAAI,MAAM;AAC5C,MAAI,cACH,MAAK,MAAM,QAAQ,CAAC,GAAG,cAAc,EAAE;AAEtC,OAAI,KAAK,QAAQ,YAAY,SAAS,gBACrC;AAGD,OAAI;AACH,SAAK,QAAQ,GAAG,WAAW;YACnB,OAAO;IACf,MAAM,UAAU,GAAG,MAAM,IAAK,MAAgB;AAC9C,SAAK,KAAK,SAAS,IAAI,MAAM,QAAQ,CAAC;AAEtC,QAAI,KAAK,kBACR,OAAM,IAAI,MAAM,QAAQ;;;;;;;;;CAY7B,MAAa,WAAc,OAAe,GAAG,YAAiB;AAC7D,QAAM,KAAK,KAAK,UAAU,SAAS,GAAG,WAAW;;;;;;;CAQlD,MAAa,UAAa,OAAe,GAAG,YAAiB;AAC5D,QAAM,KAAK,KAAK,SAAS,SAAS,GAAG,WAAW;;;;;;;;;CAUjD,MAAa,SAAY,OAAe,GAAG,YAAiB;AAC3D,QAAM,KAAK,KAAK,OAAO,GAAG,WAAW;;;;;;;CAQtC,SAAgB,OAAe;AAC9B,OAAK,iBAAiB,MAAM;AAC5B,SAAO,KAAK,OAAO,IAAI,MAAM;;;;;;;CAQ9B,QAAe,IAA+B;AAC7C,OAAK,MAAM,iBAAiB,KAAK,OAAO,QAAQ,EAAE;GACjD,MAAM,QAAQ,cAAc,MAAM,MAAM,EAAE,OAAO,GAAG;AACpD,OAAI,MACH,QAAO;;;;;;;;CAYV,eAAsB,IAAoD;AACzE,MAAI,MAAM,QAAQ,GAAG,EAAE;GACtB,MAAM,UAAmB,EAAE;AAC3B,QAAK,MAAM,YAAY,IAAI;IAC1B,MAAM,SAAS,KAAK,eAAe,SAAS;AAC5C,QAAI,UAAU,CAAC,MAAM,QAAQ,OAAO,CACnC,SAAQ,KAAK,OAAO;;AAItB,UAAO;;AAGR,OAAK,MAAM,CAAC,OAAO,kBAAkB,KAAK,OAAO,SAAS,EAAE;GAC3D,MAAM,QAAQ,cAAc,WAAW,MAAM,EAAE,OAAO,GAAG;AACzD,OAAI,UAAU,IAAI;IACjB,MAAM,CAAC,WAAW,cAAc,OAAO,OAAO,EAAE;AAChD,QAAI,cAAc,WAAW,EAC5B,MAAK,OAAO,OAAO,MAAM;AAG1B,WAAO;;;;;;;;CAWV,aAAoB;AACnB,OAAK,OAAO,OAAO;;;;;;;CAQpB,iBAAwB,OAAwB;AAC/C,OAAK,iBAAiB,MAAM;EAC5B,MAAM,gBAAgB,KAAK,OAAO,IAAI,MAAM;AAC5C,MAAI,eAAe;GAClB,MAAM,UAAU,CAAC,GAAG,cAAc;AAClC,QAAK,OAAO,OAAO,MAAM;AACzB,UAAO;;AAGR,SAAO,EAAE;;;;;;;CAQV,iBAAyB,OAAqB;AAC7C,MAAI,KAAK,qBAAqB;GAC7B,MAAM,aAAa,MAAM,MAAM,CAAC,mBAAmB;AACnD,OAAI,CAAC,WAAW,WAAW,SAAS,IAAI,CAAC,WAAW,WAAW,QAAQ,CACtE,OAAM,IAAI,MACT,eAAe,MAAM,0EACrB;;;;;;;;CAUJ,oBAA4B,OAAwB;AACnD,MAAI,KAAK,iBAAiB,IAAI,MAAM,EAAE;GACrC,MAAM,UAAU,KAAK,iBAAiB,IAAI,MAAM;GAChD,MAAM,iBAAiB,SAAS,MAAM,iBAAiB,UAAU,KAAK,YAAY;AAGlF,QAAK,KAAK,QAAQ;IAAE,MAAM;IAAO,SAAS;IAAgB,CAAC;AAG3D,UAAO,KAAK;;AAEb,SAAO"}
{"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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"}
{
"name": "hookified",
"version": "2.2.0",
"version": "3.0.0",
"description": "Event Emitting and Middleware Hooks",

@@ -27,17 +27,2 @@ "type": "module",

},
"scripts": {
"lint": "biome check --write --error-on-warnings",
"test": "pnpm lint && vitest run --coverage",
"test:ci": "biome check --error-on-warnings && vitest run --coverage",
"clean": "rimraf ./dist ./coverage ./site/dist",
"build": "tsdown",
"benchmark": "pnpm benchmark:hooks && pnpm benchmark:emit",
"benchmark:hooks": "pnpm tsx benchmark/hook.ts",
"benchmark:emit": "pnpm tsx benchmark/emit.ts",
"benchmark:readme": "pnpm tsx scripts/benchmark-readme.ts",
"website:build": "docula build",
"website:serve": "docula serve",
"website:dev": "docula dev",
"prepublishOnly": "pnpm build"
},
"keywords": [

@@ -74,8 +59,11 @@ "hooks",

"homepage": "https://github.com/jaredwray/hookified#readme",
"engines": {
"node": ">=22.18.0"
},
"devDependencies": {
"@biomejs/biome": "^2.4.13",
"@biomejs/biome": "^2.4.15",
"@monstermann/tinybench-pretty-printer": "^0.3.0",
"@types/node": "^24.12.2",
"@vitest/coverage-v8": "^4.1.5",
"docula": "^1.14.0",
"@vitest/coverage-v8": "^4.1.0",
"docula": "^2.0.0",
"emittery": "^2.0.0",

@@ -86,7 +74,7 @@ "eventemitter3": "^5.0.4",

"rimraf": "^6.1.3",
"tinybench": "^6.0.0",
"tsdown": "^0.21.10",
"tsx": "^4.21.0",
"tinybench": "^6.0.2",
"tsdown": "^0.22.0",
"tsx": "^4.19.0",
"typescript": "^6.0.3",
"vitest": "^4.1.5"
"vitest": "^4.1.0"
},

@@ -96,3 +84,17 @@ "files": [

"LICENSE"
]
}
],
"scripts": {
"lint": "biome check --write --error-on-warnings",
"test": "pnpm lint && vitest run --coverage",
"test:ci": "biome check --error-on-warnings && vitest run --coverage",
"clean": "rimraf ./dist ./coverage ./site/dist",
"build": "tsdown",
"benchmark": "pnpm benchmark:hooks && pnpm benchmark:emit",
"benchmark:hooks": "pnpm tsx benchmark/hook.ts",
"benchmark:emit": "pnpm tsx benchmark/emit.ts",
"benchmark:readme": "pnpm tsx scripts/benchmark-readme.ts",
"website:build": "docula build",
"website:serve": "docula serve",
"website:dev": "docula dev"
}
}

@@ -15,3 +15,3 @@ ![Hookified](site/logo.svg)

- Async / Sync Middleware Hooks for Your Methods
- ESM / CJS with Types and Nodejs 20+
- ESM / CJS with Types
- Browser Support and Delivered via CDN

@@ -32,2 +32,3 @@ - Ability to throw errors in hooks

- [Usage](#usage)
- [Migrating from v2 to v3](#migrating-from-v2-to-v3)
- [Migrating from v1 to v2](#migrating-from-v1-to-v2)

@@ -1368,2 +1369,18 @@ - [Using it in the Browser](#using-it-in-the-browser)

# Migrating from v2 to v3
v3 has no API changes. The only breaking change is the minimum Node.js version requirement.
## Breaking Changes
| Change | Summary |
|---|---|
| Node.js version | Minimum required version is now `>=22.18.0` (previously no `engines` constraint) |
### Node.js >=22.18.0 required
The `engines` field in `package.json` now requires Node.js 22.18.0 or later. Node.js 20 reached end-of-life in April 2026.
**Migration:** Upgrade to Node.js 22 LTS or Node.js 24+. No code changes are required — the library API is identical to v2.
# Migrating from v1 to v2

@@ -1370,0 +1387,0 @@