包详细信息

typhonjs-plugin-manager

typhonjs-node-plugin83.4kMPL-2.00.2.0

Provides a plugin manager that dispatches events to loaded plugins.

typhonjs, plugin, manager

自述文件

typhonjs-plugin-manager

NPM Documentation Code Style License Gitter

Build Status Coverage Dependency Status

Provides a lightweight plugin manager for Node / NPM with optional backbone-esnext-events integration for plugins in a safe and protected manner across NPM modules, local files, and preloaded object instances. This pattern facilitates message passing between modules versus direct dependencies / method invocation.

It isn't necessary to use an eventbus associated with the plugin manager though invocation then relies on invoking methods directly with the plugin manager instance.

When passing in an eventbus from backbone-esnext-events the plugin manager will register by default under these event categories:

plugins:add - invokes PluginManager#add

plugins:add:all - invokes PluginManager#addAll

plugins:async:add - invokes PluginManager#addAsync

plugins:async:add:all - invokes PluginManager#addAllAsync

plugins:async:destroy:manager - invokes PluginManager#destroyAsync

plugins:async:invoke - invokes PluginManager#invokeAsync

plugins:async:invoke:event - invokes PluginManager#invokeAsyncEvent

plugins:async:remove - invokes PluginManager#removeAsync

plugins:async:remove:all - invokes PluginManager#removeAllAsync

plugins:create:event:proxy - invokes PluginManager#createEventProxy

plugins:destroy:manager - invokes PluginManager#destroy

plugins:get:all:plugin:data - invokes PluginManager#getAllPluginData

plugins:get:extra:event:data - invokes PluginManager#getExtraEventData

plugins:get:method:names - invokes PluginManager#getMethodNames

plugins:get:options - invokes PluginManager#getOptions

plugins:get:plugin:data - invokes PluginManager#getPluginData

plugins:get:plugin:enabled - invokes PluginManager#getPluginEnabled

plugins:get:plugin:method:names - invokes PluginManager#getPluginMethodNames

plugins:get:plugin:names - invokes PluginManager#getPluginNames

plugins:get:plugin:options - invokes PluginManager#getPluginOptions

plugins:get:plugins:enabled - invokes PluginManager#getPluginsEnabled

plugins:has:method - invokes PluginManager#hasMethod

plugins:has:plugin - invokes PluginManager#hasPlugin

plugins:has:plugin:method - invokes PluginManager#hasPluginMethod

plugins:invoke - invokes PluginManager#invoke

plugins:is:valid:config - invokes PluginManager#isValidConfig

plugins:remove - invokes PluginManager#remove

plugins:remove:all - invokes PluginManager#removeAll

plugins:set:extra:event:data - invokes PluginManager#setExtraEventData

plugins:set:plugin:enabled - invokes PluginManager#setPluginEnabled

plugins:set:plugins:enabled - invokes PluginManager#setPluginsEnabled

plugins:sync:invoke - invokes PluginManager#invokeSync

plugins:sync:invoke:event - invokes PluginManager#invokeSyncEvent

Automatically when a plugin is loaded and unloaded respective callbacks onPluginLoad and onPluginUnload will be attempted to be invoked on the plugin. This is an opportunity for the plugin to receive any associated eventbus and wire itself into it. It should be noted that a protected proxy around the eventbus is passed to the plugins such that when the plugin is removed automatically all events registered on the eventbus are cleaned up without a plugin author needing to do this manually in the onPluginUnload callback. This solves any dangling event binding issues.

The plugin manager also supports asynchronous operation with the methods ending in Async along with event bindings that include async. For asynchronous variations of add, destroy, and remove the lifecycle methods onPluginLoad and onPluginUnload will be awaited on such that if a plugin returns a Promise or is an async method then it must complete before execution continues. One can use Promises to interact with the plugin manager asynchronously, but usage via async / await is recommended.

If eventbus functionality is enabled it is important especially if using a process / global level eventbus such as backbone-esnext-eventbus to call PluginManager#destroy to clean up all plugin eventbus resources and the plugin manager event bindings.

Please see the following NPM modules for eventbus info:

Examples follow:

import Events        from 'backbone-esnext-events';   // Imports the TyphonEvents class for local usage.
::or alternatively::
import eventbus      from 'backbone-esnext-eventbus'; // Imports a global / process level eventbus.

import PluginManager from 'typhonjs-plugin-manager';

const pluginManager = new PluginManager({ eventbus });

pluginManager.add({ name: 'an-npm-plugin-enabled-module' });
pluginManager.add({ name: 'my-local-module', target: './myModule.js' });

// Let's say an-npm-plugin-enabled-module responds to 'cool:event' which returns 'true'.
// Let's say my-local-module responds to 'hot:event' which returns 'false'.
// Both of the plugin / modules will have 'onPluginLoaded' invoked with a proxy to the eventbus and any plugin
// options defined.

// One can then use the eventbus functionality to invoke associated module / plugin methods even retrieving results.
assert(eventbus.triggerSync('cool:event') === true);
assert(eventbus.triggerSync('hot:event') === false);

// One can also indirectly invoke any method of the plugin via:
eventbus.triggerSync('plugins:invoke:sync:event', 'aCoolMethod'); // Any plugin with a method named `aCoolMethod` is invoked.
eventbus.triggerSync('plugins:invoke:sync:event', 'aCoolMethod', {}, {}, 'an-npm-plugin-enabled-module'); // specific invocation.

// The 3rd parameter defines a pass through object hash and the 4th will make a copy of the hash sending a single
// event / object hash to the invoked method.

// -----------------------

// Given that `backbone-esnext-eventbus` defines a global / process level eventbus you can import it in an entirely
// different file or even NPM module and invoke methods of loaded plugins like this:

import eventbus from 'backbone-esnext-eventbus';

eventbus.triggerSync('plugins:invoke', 'aCoolMethod'); // Any plugin with a method named `aCoolMethod` is invoked.

assert(eventbus.triggerSync('cool:event') === true);

eventbus.trigger('plugins:remove', 'an-npm-plugin-enabled-module'); // Removes the plugin and unregisters events.

assert(eventbus.triggerSync('cool:event') === true); // Will now fail!

// In this case though when using the global eventbus be mindful to always call `pluginManager.destroy()` in the main
// thread of execution scope to remove all plugins and the plugin manager event bindings!

更新日志

0.2.0 (2017-08-25)

  • Fine tuned internal plugin entry data.
  • Added optional module data to be associated with plugin data when added.
  • Added deep freeze of plugin data / typhonjs-object-util.
  • Breaking change (minor impact): Updated data passed to global event bindings when plugins are added, removed, enabled.

0.1.11 (2017-07-14)

  • Breaking change (minor impact): updated event bindings for async / sync methods

0.1.10 (2017-07-12)

  • added support for asynchronous usage: please see addAsync, addAllAsync, destroyAsync, setEventbusAsync, removeAsync, removeAllAsync and related event bindings. These methods that invoke plugin lifecycle methods onPluginLoad / onPluginUnload will asynchronously invoke them such that if a plugin returns a Promise or is async then execution awaits until completed.

  • It is recommended that you use async / await to integrate asynchronous usage.

0.1.9 (2017-05-30)

  • added basic plugin invoke method and event binding that does not return results.
  • reorganized method signature for invokeAsync / invokeSync to take a method name and then optional arguments / plugin names

0.1.7 (2017-03-10)

  • updated event bindings.

0.1.6 (2017-03-09)

  • added getPluginEventNames / plugins:get:plugin:event:names event.
  • added getPluginsByEventName / plugins:get:plugins:by:event:name event.
  • added getPluginsEventNames / plugins:get:plugins:event:names event.

0.1.5 (2017-03-07)

added plugins:destroy:manager event.

0.1.2 (2017-02-20)

Added createEventProxy returning an EventProxy instance of any assigned eventbus to PluginManager.

0.1.0 (2017-02-11)

Initial feature complete implementation; pending full testsuite for coverage & more docs.