Hookall is a lightweight, flexible, and type-safe hooking system for Node.js and the browser. Enhance your application's extensibility by seamlessly injecting logic into any operation.
import { useHookall } from 'hookall'
const hook = useHookall(yourObject)
// 1. Register hooks
hook.onBefore('run', async (val) => {
return [...val, 2]
})
hook.onAfter('run', async (val) => {
return [...val, 4]
})
// 2. Trigger operation
const result = await hook.trigger('run', [1], async (val) => {
return [...val, 3]
})
console.log(result) // [1, 2, 3, 4]Full TypeScript support for commands, parameters, and return types. Gain full IDE autocompletion and compile-time checks.
Native support for async/await. Hooks are executed sequentially, ensuring data integrity across asynchronous operations.
Easily manage complex workflows using predefined onBefore and onAfter lifecycles. Perfect for middleware, plugins, or validation logic.
Use hooks locally for specific objects or globally to share logic across different modules and files.
npm install hookallimport { useHookall, useHookallSync } from 'hookall'<script type="module">
import { useHookall } from 'https://cdn.jsdelivr.net/npm/hookall@2/+esm'
</script>Creates an asynchronous hook system.
- target: Optional. If provided, the hook system is scoped to this object. If omitted, it operates in a global scope.
Creates a synchronous hook system. Use this if your operations do not require async/await.
Registers a preprocessing function called before the main trigger callback.
- The return value of one hook is passed as the
initialValueto the next. onceBeforeruns only once and is then automatically removed.
Registers a post-processing function called after the main trigger callback finishes.
- Receives the result of the
triggercallback (or previousonAfterhook) as its first argument. onceAfterruns only once.
Removes registered hooks.
- If
callbackis omitted, all hooks for the specifiedcommandare removed.
Executes the hook lifecycle:
- All
onBeforehooks (sequentially). - The main
callback. - All
onAfterhooks (sequentially).
Returns the final processed value.
Define a hook interface to get the most out of TypeScript:
import { useHookall } from 'hookall'
interface MyHooks {
save: (content: string, filename: string) => Promise<string>
}
const obj = { name: 'MyProcessor' }
const hook = useHookall<MyHooks>(obj)
hook.onBefore('save', async (content, filename) => {
console.log(`Preparing to save ${filename}...`)
return content.trim()
})
const result = await hook.trigger('save', ' Hello World ', async (content, filename) => {
// Save logic here
return content
}, 'memo.txt')
console.log(result) // "Hello World"You can pass extra arguments to trigger which will be available in all lifecycle hooks:
hook.onBefore('process', async (data, options) => {
if (options.verbose) console.log('Processing...')
return data
})
await hook.trigger('process', data, async (data, options) => {
return transform(data, options)
}, { verbose: true })MIT License. See LICENSE for details.