Inroduction
Make pluginable applications.
Demo
const { PluginAnything } = require('plugin-anything');
class MyPlugin__A {
constructor(options) {
console.log('my plugin A options', options);
}
apply(pa) {
const { hooks, utils } = pa;
hooks.done.tap('my plugin A', async (data) => {
console.log('my plugin A hook run', data);
return 'a';
});
}
}
class MyPlugin__B {
constructor(options) {
console.log('my plugin B options', options);
}
apply(pa) {
const { hooks, utils } = pa;
hooks.done.tap('my plugin B', async (data) => {
console.log('my plugin B hook run', data);
});
}
}
class MyPlugin__C {
constructor(options) {
console.log('my plugin C options', options);
}
apply(pa) {
const { hooks, utils } = pa;
hooks.done.tap('my plugin C', async (data) => {
console.log('my plugin C hook run', data);
});
}
}
function initHooks() {
const pa = new PluginAnything();
// init anything into pa
Object.assign(pa, {
utils: {
aaa: 1
},
hooks: {
start: pa.createHook(),
done: pa.createHook(),
}
});
// install plugins
pa.installPlugins({
// Array< string | FunctionContructor | Array<string | FunctionContructor, object> >
plugins: [
MyPlugin__A,
[ MyPlugin__B, { name: 'bbb' } ],
new MyPlugin__C({ name: 'ccc' }),
],
// search plugins when plugin name is string
// Array< string >; Array item should be absolute folder path
searchList: [],
});
return pa;
}
// run events defined in plugins
(async () => {
const pa = initHooks();
await pa.hooks.done.flush();
})();
# because of `new MyPlugin__C({ name: 'ccc' })` runs first
my plugin C options { name: 'ccc' }
my plugin A options {}
my plugin B options { name: 'bbb' }
# event 'done' callbacks
my plugin A hook run undefined
my plugin B hook run a
my plugin C hook run undefined
APIs
-
searchList
: Array< string >Absolute folder path list that will be used in searching plugins.
examples:
[ '/path_a/node_modules', '/path_b/node_modules' ]
-
plugins: Array< string | FunctionContructor | { apply(data?: any): any; [ name: string ]: any } | Array<string | FunctionContructor, object> >
class MyPlugin { constructor(options) { this.options = options; }; options: {}; apply(pa) { } } // config demo { plugins: { 'my-plugin-0', [ 'my-plugin-1', { params: 1 } ], [ MyPlugin, { params: 2 } ], new MyPlugin({ params: 2 }) } }
-
createHook()
const hook = createHook();
-
hook.tap(name: string, callback: Function | Promise<any>)
Add callback at current hook event.
name
could be any string for event description. -
hook.untap(name?: string)
Remove callback list whose name equals
name
.When
name
is blank, clear callback list. -
hook.flush(type?: sync | waterfall | paralle, initData?: any, paralleLimit = 3)
Run all callbacks.
-
sync
(default)run callbacks one next one.
-
waterfall
run callbacks one next none.
and previous returned value will be parameter of next callback.
-
paralle
run all callbacks at the same time.
-
paralle-sync
run callbacks by sync sequences:
[ callback1, callback2, cakkback3 ] [ callback4, ... ] ...
-
-
hook.beforeFlush(callback)
andhook.afterFlush(callback)
regist callback before and after
flush
.callback should be a
Function
with return typeany | Promise<any>
.example:
(async () => { hook.beforeFlush(async () => { console.log('before flush'); }); hook.afterFlush(async () => { console.log('after flush'); }); await hook.flush(); })(); // result log: before flush flushing... log: after flush
-
LICENSE
MIT