Hāmo, from latin:
hooked
. ZERO overhead hooks.
Hamo
provides a handy interface for attaching before / after / once
hooks to any function without zero overhead.
Fully compatible with both Node and the browser.
The hooked function is dynamically builded during runtime. Only the pieces relative to the currently active hooks are added to the hooked function body. When no hooks are attached to the hooked function, the original function is used.
To invoke the after
hooks really after the hooked function has already returned,
a micro-task is scheduled by running the hooks inside an already resolved promise.
npm install hamo --save
If not using a bundler:
<script src="https://unpkg.com/hamo"></script>
The hamo
function accepts 2
arguments:
- function to be hooked.
- async flag (specify if the provided function is async or not).
It returns an array of 3
elements:
hooked
.on
, function used to attach hooks to hooked.off
, function used to detach hooks from hooked.
A suggested naming could be [function]
, on[function]
, off[function]
:
const [func, on, off] = hamo(function, async);
Basic example of hooking a function. The sum
function is exactly the function passed as argument to hamo
.
const hamo = require('hamo');
const [sum] = hamo((a, b) => a + b);
sum(1, 2); // 3
The existent hooks are:
before
oncebefore
after
onceafter
A hook can be defined passing to the on
function two arguments:
- Argument that define the timing of the hook (
hookString
). - Hook function (
hookFunction
).
on(hookString, hookFunction)
const [sum, onSum] = hamo((a, b) => a + b);
onSum('before', () => console.log('Called before!'));
sum(1, 2);
// Called before
// 3
before
and oncebefore
hooks gets called before the function execution.
Those functions are feeded with the same set of arguments that is passed to the hooked function.
NOTE: oncebefore
Is called only one time.
const [sum, onSum] = hamo((a, b) => a + b);
onSum('before', (a, b) => console.log(`Summing ${a} and ${b}`));
sum(1, 2);
// Summing 1 and 2
// 3
before
and onceafter
hooks gets called after the function execution.
Those functions are feeded with the result of the hooked function AND with the same set of arguments that is passed to the hooked function.
NOTE: onceafter
Is called only one time.
NOTE1: These functions are invoked after the function has returned.
const [sum, onSum] = hamo((a, b) => a + b);
onSum('after', (res, a, b) => console.log(`Sum is equal to ${res}`));
sum(1, 2);
// 3
// Sum is equal to 3
A previously defned hook is detachable by invoking the off
function with the hookString
argument
off(hookString);
NOTE: onceafter
Is called only one time.
NOTE1: These functions are invoked after the function has returned.
const [sum, onSum, offSum] = hamo((a, b) => a + b);
onSum('after', (res, a, b) => console.log(`Sum is equal to ${res}`));
offSum('after');
sum(1, 2);
// 3
It's possible to hook async functions.
Example of hoking fs
.
const { readFile } = require('fs');
const { promisify } = require('util');
// Specify the async flag
const [read, onRead] = hamo(promisify(readFile), true);
onRead('after', (file, path) => console.log(`Finished reading from ${path}`));
read('./test.txt', 'utf-8');
// ... test.txt ...
// Finished reading from ./test.txt
To run benchmarks:
- clone repo.
npm install
- run files inside
/benchmarks
.
To run tests:
- clone repo
npm install
npm test
MIT