{"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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"}