Registry / web-framework / hookified

hookified

JSON →
library2.1.1jsnpmunverified

Hookified provides a robust solution for integrating event emitting and middleware-style hooks into JavaScript and TypeScript applications. Currently at version 2.1.1, the library maintains an active release cadence, with frequent updates addressing performance, type improvements, and feature enhancements. Key differentiators include its dual support for asynchronous and synchronous middleware hooks, serving as a simple yet powerful EventEmitter replacement. It offers comprehensive support for ESM and CJS module systems, along with TypeScript types and compatibility with Node.js 20+ environments, including browser support via CDN. The library boasts a lean footprint with no external package dependencies and a small size (around 250KB), focusing on fast and efficient execution, as evidenced by its benchmarks. Features like WaterfallHook for data transformation, robust error handling, options for enforcing hook naming conventions (enforceBeforeAfter), and built-in mechanisms for managing deprecated hooks (deprecatedHooks, allowDeprecated) further distinguish its capabilities.

npm install hookified
INSTALL
IMPORT
SIG · HOOKIFIED
H
hookified
web-frameworkjavascriptv2.1.1
Install
Import
Disk
Pass rate
0/ 6
Env Coverage0 / 6
glibc
1822
musl
1822
Install & Compatibility
Where this runs
tested against v? · npm install
Install × environment matrix
Each cell = how many times install + import succeeded across repeated harness runs. Partial = flaky.
glibc = Debian/Ubuntu slim · musl = Alpine Linux
musl
node 18226 runs
build_error
glibc
node 18226 runs
build_error
Code
Verified usage

Verified import paths — ran on the pinned version, not inferred.

Hookified
import { Hookified } from 'hookified';
const Hookified = require('hookified');
Hookified is an ESM-first package. While it supports CJS, direct `require` might lead to issues in some setups. Use `import` for best compatibility, especially in modern Node.js environments and TypeScript projects.
Hook
import { Hook } from 'hookified';
import { IHook } from 'hookified'; // IHook is an interface, not a class for direct instantiation
The `Hook` class is used to create structured hook entries. `IHook` is an interface describing the hook structure.
WaterfallHook
import { WaterfallHook } from 'hookified';
Used for creating sequential data transformation pipelines, it implements the `IHook` interface.

This quickstart demonstrates instantiating Hookified, registering standard and WaterfallHooks, emitting and listening to events, and processing data through the hook lifecycle.

import { Hookified, Hook, WaterfallHook } from 'hookified'; class MyService extends Hookified { constructor() { super(); this.data = { count: 0, items: [] }; } async processData(input: string) { await this.hook('beforeProcess', input); this.data.count++; this.data.items.push(input.toUpperCase()); await this.hook('afterProcess', this.data); return this.data; } async saveData(initialData: any) { const processedData = await this.hook('saveData', initialData); console.log('Final data saved:', processedData); this.emit('dataSaved', processedData); } } const service = new MyService(); // Register a standard hook handler for 'beforeProcess' service.onHook({ event: 'beforeProcess', handler: async (input: string) => { console.log(`[Hook: beforeProcess] Input received: ${input}`); } }); // Register another hook for 'afterProcess' service.onHook('afterProcess', (data: { count: number }) => { console.log(`[Hook: afterProcess] Current count: ${data.count}`); }); // Register a WaterfallHook for 'saveData' to transform data sequentially const transformHook = new WaterfallHook('saveData', ({ args, results }) => { const currentResult = results.length > 0 ? results[results.length - 1].result : args[0]; const transformed = { ...currentResult, timestamp: Date.now(), processedBy: 'transformHook' }; console.log('[WaterfallHook: saveData] Data transformed.'); return transformed; }); service.onHook(transformHook); // Register an event listener service.on('dataSaved', (data) => { console.log(`[Event: dataSaved] Event emitted with data: ${JSON.stringify(data)}`); }); // Run the service (async () => { console.log('--- Starting processData ---'); await service.processData('hello world'); await service.processData('hookified'); console.log('--- Finished processData ---\n'); console.log('--- Starting saveData ---'); await service.saveData({ id: 1, value: 'initial' }); console.log('--- Finished saveData ---'); // Example of using a hook programmatically (equivalent to onHook but for single use) await service.onceHook(new Hook('afterProcess', (data) => { console.log(`[Hook: onceHook] Special one-time afterProcess hook triggered with count: ${data.count}`); })); await service.processData('one-time-hook-test'); })();
Debug
Known issues
breakingThe `logger` property was renamed to `eventLogger` in v2.0.0 to prevent naming conflicts. Code accessing `this.logger` directly will fail.
fix
Update all instances of `this.logger` to `this.eventLogger`.
affects: >=2.0.0
breakingThe `throwHookErrors` option was removed in v2.0.0. Its functionality is now integrated into `throwOnHookError`.
fix
Migrate usage to `throwOnHookError` in the constructor options or instance property.
affects: >=2.0.0
breakingThe default value for `throwOnEmptyListeners` changed to `true` in v2.0.0. This means emitting an 'error' event without any registered listeners will now throw an exception, aligning with Node.js EventEmitter behavior.
fix
Ensure an 'error' event listener is always registered, or explicitly set `throwOnEmptyListeners: false` in the `Hookified` constructor options if you want to suppress this behavior.
affects: >=2.0.0
breakingVersion 2.0.0 introduced significant changes to internal types and interfaces, including `Hook` type becoming `HookFn`, `onHook` accepting `IHook` objects, and `hooks` being stored as an array of `IHook`. While direct usage of `Hookified` should mostly be compatible, custom hook implementations or deep integrations might require adjustments.
fix
Review the migration guide from v1 to v2 on the project's GitHub page for details on adapting custom hook implementations or extending `Hookified`.
affects: >=2.0.0
gotchaEnabling `enforceBeforeAfter` in constructor options (e.g., `new Hookified({ enforceBeforeAfter: true })`) requires all hook names to explicitly start with 'before' or 'after'. Not adhering to this convention will result in runtime errors.
fix
Prefix all custom hook names (e.g., `beforeSave`, `afterValidation`) or set `enforceBeforeAfter: false` if this naming convention is not desired.
affects: >=1.12.1
gotchaThe `.hookSync()` method explicitly skips asynchronous (async/await) handler functions. If you need to execute both synchronous and asynchronous handlers, use the `.hook()` method, which is the preferred and more comprehensive approach.
fix
Use `.hook()` for general hook execution. Only use `.hookSync()` when strictly needing to process only synchronous handlers.
affects: >=1.15.0
Errors
Common errors & fixes
TypeError: 'logger' is not a function
Attempting to call or access the `logger` property which was renamed to `eventLogger` in Hookified v2.0.0.
fix
Change references from `myInstance.logger` to `myInstance.eventLogger` or `this.eventLogger`.
Error: Hook event "myCustomHook" must start with "before" or "after" when enforceBeforeAfter is enabled
The `enforceBeforeAfter` option is set to `true`, requiring all hook names to follow a 'before:' or 'after:' prefix convention, and the provided hook name does not.
fix
Rename your hook to `beforeMyCustomHook` or `afterMyCustomHook`, or disable the enforcement by passing `{ enforceBeforeAfter: false }` to the `Hookified` constructor.
TypeError: Hookified is not a constructor (in CommonJS context)
Using `const Hookified = require('hookified');` in a CommonJS module when the library is primarily designed for ESM, leading to module interoperability issues.
fix
Refactor your module to use ESM `import { Hookified } from 'hookified';` or use dynamic imports `import('hookified').then(module => new module.Hookified());` if you must remain in CJS.
UnhandledPromiseRejectionWarning: Error: No listeners for event: error
An 'error' event was `emit`ted, and the `throwOnEmptyListeners` option (which defaults to `true` in v2+) is enabled, but no listener was registered for the 'error' event.
fix
Add an 'error' event listener: `myInstance.on('error', (err) => { console.error('Caught error:', err); });` or set `new Hookified({ throwOnEmptyListeners: false })` to suppress this behavior.
Upgrade
Version history
2.1.1latest on npm
Audit
Dependencies

No dependency data recorded yet.

Agent activity
6 hits · last 30 days
node
6
Resources
hookified — npm install hookified · libregistry