Gathering detailed insights and metrics for @funnyecho/hamon
Gathering detailed insights and metrics for @funnyecho/hamon
Gathering detailed insights and metrics for @funnyecho/hamon
Gathering detailed insights and metrics for @funnyecho/hamon
npm install @funnyecho/hamon
Typescript
Module System
Node Version
NPM Version
TypeScript (97.84%)
JavaScript (1.8%)
Makefile (0.36%)
Total Downloads
0
Last Day
0
Last Week
0
Last Month
0
Last Year
0
MIT License
14 Stars
19 Commits
1 Forks
1 Watchers
1 Branches
1 Contributors
Updated on Dec 17, 2023
Latest Version
2.0.2
Package Id
@funnyecho/hamon@2.0.2
Unpacked Size
72.40 kB
Size
13.61 kB
File Count
12
NPM Version
6.13.4
Node Version
12.14.1
Cumulative downloads
Total Downloads
Last Day
0%
NaN
Compared to previous day
Last Week
0%
NaN
Compared to previous week
Last Month
0%
NaN
Compared to previous month
Last Year
0%
NaN
Compared to previous year
In traditional event-base repositories, event is just downstream flow which we can only emit data to listener but can not get any response from listener.
So once i came across from webpack/tapable, i'm sure tapable
is the better event-driven architecture then traditional event-emitter like.
The repo is almost a tapable-lite, referring to webpack/tapable.
There are some differences between tapable and hamon:
interception
, Context
, HookMap
and MultiHook
;TapOptions
;SyncLoopHook
;But:
unTap
function after tapping;exhaust
method to clean all listeners;bucketHashcode
function when creating hooks;npm install --save @funnyecho/hamon
1import { 2 SyncHook, 3 SyncBailHook, 4 SyncWaterfallHook, 5 6 AsyncParallelHook, 7 AsyncParallelBailHook, 8 9 AsyncSeriesHook, 10 AsyncSeriesBailHook, 11 AsyncSeriesWaterfallHook 12 } from "@funnyecho/hamon";
The hook listeners executed in different ways depending on the different hook types:
Bail
:Allows hook calling exited earily. if listener return with a non-undefined value, and skip remaining downstream listeners. The calling will return with that non-undefined bail value or first element of calling arguments;Waterfall
: Allows upstream listener to change the calling arguments of downstream listener by returning a non-undefined value;Besides, we can combine with Sync
, AsyncParallel
, or AsyncSeries
for more powerful function:
Sync
:
tap(listener)
to tapping;call(...args)
to invoke hook, all listeners were called in synchronous queue;AsyncParallel
:
tapAsync(listener)
or tapPromise(listener)
to tapping;callAsync(...args, cb)
or callPromise(...args)
to invoke hook, all listeners were called asynchronously in parallel;Bail
and basic type;AsyncSeries
:
tapAsync(listener)
or tapPromise(listener)
to tapping;callAsync(...args, cb)
or callPromise(...args)
to invoke hook, all listeners were called asynchronously in series;Bail
, Waterfall
and basic type;Sometimes, we are only intested in a certain clause of hook.
For example, message notification from webscoket was delivered by hook, and our app want to focus on the notification of current chatroom. So we use chatroom id
as hashcode. Code demo show below:
1import { SyncHook } from '@funnyecho/hamon'; 2 3// create hook with hashcode calculate function 4let messagHook = new SyncHook((messageEntity) => messageEntity.chatroomId); 5 6let currentChatroomId = 123; 7 8// listen to hook and only focus on currentChatroomId 9messageHook.tap(messageEntity => { 10 // do something with message received 11}, currentChatroomId); 12 13// chatroomId didn't equal to currentChatroomId, listener won't be called 14messageHook.call({chatroomId: 'not current'}); 15 16// chatroomId was equaled to currentChatroomId, listener was called 17messageHook.call({chatroomId: currentChatroomId});
refer to: docs
1import { SyncHook } from '@funnyecho/hamon'; 2 3// create SyncHook 4let hook = new SyncHook<[number, string]>(); 5 6// tapping to SyncHook 7// calling `unTap` can remove listener 8let unTap = hook.tap((a1: number, a2: string) => { 9 console.log('SyncHook', a1, a2); 10}) 11 12// invoke 13hook.call(1, 'foo'); 14 15// console: 16// SyncHook 1 'foo'
1import { SyncBailHook } from '@funnyecho/hamon'; 2 3// create SyncBailHook 4let hook = new SyncBailHook<[number, string], number>(); 5 6// tapping to SyncBailHook 7// calling `unTap` can remove listener 8let unTap1 = hook.tap((a1: number, a2: string): number => { 9 console.log('SyncBailHook_1', a1, a2); 10 11 return a1 * a1; 12}) 13 14let unTap2 = hook.tap((a1: number, a2: string): undefined => { 15 console.log('SyncBailHook_2', a1, a2); 16}) 17 18// invoke 19// listener1 was called and return `4`, listener2 won't be called 20// calling return `4` 21hook.call(2, 'foo'); 22 23// console: 24// SyncBailHook_1 2 'foo'
1import { SyncWaterfallHook } from '@funnyecho/hamon'; 2 3// create SyncHook 4let hook = new SyncWaterfallHook<[number, string], number>(); 5 6// tapping to SyncWaterfallHook 7// calling `unTap` can remove listener 8let unTap1 = hook.tap((a1: number, a2: string): number => { 9 console.log('SyncWaterfallHook_1', a1, a2); 10 11 return a1 * a1; 12}) 13 14let unTap2 = hook.tap((a1: number, a2: string): undefined => { 15 console.log('SyncWaterfallHook_2', a1, a2); 16}) 17 18let unTap3 = hook.tap((a1: number, a2: string): number => { 19 console.log('SyncWaterfallHook_3', a1, a2); 20 21 return a1 + 100; 22}) 23 24// invoke 25// listener1 was called with `[2, 'foo']` and return `4`, 26// listener2 was called with `[4, 'foo']`, 27// listener3 was called with `[4, 'foo']` and return `104` 28// calling return `104` 29hook.call(2, 'foo'); 30 31// console: 32// SyncBailHook_1 2 'foo' 33// SyncBailHook_2 4 'foo' 34// SyncBailHook_3 4 'foo'
1import { AsyncParallelHook } from '@funnyecho/hamon'; 2 3let hook = new AsyncParallelHook<[number]>(); 4 5let unTap1 = hook.tapAsync((a1, cb) => { 6 console.log('AsyncParallelHook_1', a1); 7 setTimeout(() => { 8 console.log('AsyncParallelHook_1', 'async', a1); 9 cb(); 10 }, 10); 11}) 12 13let unTap2 = hook.tapPromise(async (a1) => { 14 console.log('AsyncParallelHook_2', a1); 15 return new Promise(resolve => { 16 setTimeout(() => { 17 console.log('AsyncParallelHook_2', 'promise', a1); 18 resolve(); 19 }, 10); 20 }) 21}) 22 23// invoke with async callback, calling return undefined 24/* 25* console output: 26* AsyncParallelHook_1 2 27* AsyncParallelHook_2 2 28* AsyncParallelHook_1 async 2 29* AsyncParallelHook_2 promsie 2 30* AsyncParallelHook_async_done 31*/ 32hook.callAsync(2, () => { 33 console.log('AsyncParallelHook_async_done'); 34}); 35 36// invoke with async promise, calling return Promise 37/* 38* console output: 39* AsyncParallelHook_1 2 40* AsyncParallelHook_2 2 41* AsyncParallelHook_1 async 2 42* AsyncParallelHook_2 promsie 2 43* AsyncParallelHook_promise_done 44*/ 45hook.callPromise(2).then(() => console.log('AsyncParallelHook_promise_done'));
1import { AsyncParallelBailHook } from '@funnyecho/hamon'; 2 3let hook = new AsyncParallelBailHook<[number]>(); 4 5let unTap1 = hook.tapAsync((a1, cb) => { 6 setTimeout(() => { 7 // bailed 8 cb(a1 * 100); 9 }, 10); 10}) 11 12let unTap2 = hook.tapPromise(async (a1) => { 13 return new Promise(resolve => { 14 setTimeout(() => { 15 resolve(); 16 }, 10); 17 }) 18}) 19 20// invoke with async callback, calling return undefined 21/* 22* console output: 23* AsyncParallelHook_async_done 200 24*/ 25hook.callAsync(2, (v) => { 26 console.log('AsyncParallelBailHook_async_done', v); 27}); 28 29// invoke with async promise, calling return Promise 30/* 31* console output: 32* AsyncParallelBailHook_promise_done 200 33*/ 34hook.callPromise(2).then((v) => console.log('AsyncParallelBailHook_promise_done', v));
1import { AsyncSeriesHook } from '@funnyecho/hamon'; 2 3let hook = new AsyncSeriesHook<[number]>(); 4 5let unTap1 = hook.tapAsync((a1, cb) => { 6 console.log('AsyncSeriesHook_1', a1); 7 setTimeout(() => { 8 console.log('AsyncSeriesHook_1', 'async', a1); 9 cb(); 10 }, 10); 11}) 12 13let unTap2 = hook.tapPromise(async (a1) => { 14 console.log('AsyncSeriesHook_2', a1); 15 return new Promise(resolve => { 16 setTimeout(() => { 17 console.log('AsyncSeriesHook_2', 'promise', a1); 18 resolve(); 19 }, 10); 20 }) 21}) 22 23// invoke with async callback, calling return undefined 24/* 25* console output: 26* AsyncSeriesHook_1 2 27* AsyncSeriesHook_1 async 2 28* AsyncSeriesHook_2 2 29* AsyncSeriesHook_2 promsie 2 30* AsyncSeriesHook_async_done 31*/ 32hook.callAsync(2, () => { 33 console.log('AsyncSeriesHook_async_done'); 34}); 35 36// invoke with async promise, calling return Promise 37/* 38* console output: 39* AsyncSeriesHook_1 2 40* AsyncSeriesHook_1 async 2 41* AsyncSeriesHook_2 2 42* AsyncSeriesHook_2 promsie 2 43* AsyncSeriesHook_async_done 44*/ 45hook.callPromise(2).then(() => console.log('AsyncSeriesHook_promise_done'));
1import { AsyncSeriesBailHook } from '@funnyecho/hamon'; 2 3let hook = new AsyncSeriesBailHook<[number]>(); 4 5let unTap1 = hook.tapAsync((a1, cb) => { 6 setTimeout(() => { 7 // bailed 8 cb(a1 * 100); 9 }, 10); 10}) 11 12let unTap2 = hook.tapPromise(async (a1) => { 13 return new Promise(resolve => { 14 setTimeout(() => { 15 resolve(); 16 }, 10); 17 }) 18}) 19 20// invoke with async callback, calling return undefined 21/* 22* console output: 23* AsyncSeriesBailHook_async_done 200 24*/ 25hook.callAsync(2, (v) => { 26 console.log('AsyncSeriesBailHook_async_done', v); 27}); 28 29// invoke with async promise, calling return Promise 30/* 31* console output: 32* AsyncSeriesBailHook_promise_done 200 33*/ 34hook.callPromise(2).then((v) => console.log('AsyncSeriesBailHook_promise_done', v));
1import { AsyncSeriesWaterfallHook } from '@funnyecho/hamon'; 2 3let hook = new AsyncSeriesWaterfallHook<[number]>(); 4 5let unTap1 = hook.tapAsync((a1, cb) => { 6 console.log('AsyncSeriesWaterfallHook_1', a1); 7 setTimeout(() => { 8 // waterfall 9 cb(a1 * 100); 10 }, 10); 11}) 12 13let unTap2 = hook.tapPromise(async (a1) => { 14 console.log('AsyncSeriesWaterfallHook_2', a1); 15 return new Promise(resolve => { 16 setTimeout(() => { 17 resolve(); 18 }, 10); 19 }) 20}) 21 22// invoke with async callback, calling return undefined 23/* 24* console output: 25* AsyncSeriesWaterfallHook_1 1 26* AsyncSeriesWaterfallHook_2 200 27* AsyncSeriesWaterfallHook_async_done 200 28*/ 29hook.callAsync(2, (v) => { 30 console.log('AsyncSeriesWaterfallHook_async_done', v); 31}); 32 33// invoke with async promise, calling return Promise 34/* 35* console output: 36* AsyncSeriesWaterfallHook_1 1 37* AsyncSeriesWaterfallHook_2 200 38* AsyncSeriesWaterfallHook_promise_done 200 39*/ 40hook.callPromise(2).then((v) => console.log('AsyncSeriesWaterfallHook_promise_done', v));
Hook.prototype.exhaust()
can clean all listener of current hook.
Hook.prototype.destroy()
do the same thing.
No vulnerabilities found.
Reason
no binaries found in the repo
Reason
license file detected
Details
Reason
0 existing vulnerabilities detected
Reason
Found 0/19 approved changesets -- score normalized to 0
Reason
0 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 0
Reason
no SAST tool detected
Details
Reason
no effort to earn an OpenSSF best practices badge detected
Reason
security policy file not detected
Details
Reason
project is not fuzzed
Details
Reason
branch protection not enabled on development/release branches
Details
Score
Last Scanned on 2025-07-07
The Open Source Security Foundation is a cross-industry collaboration to improve the security of open source software (OSS). The Scorecard provides security health metrics for open source projects.
Learn More