Home Manual Reference Source Test Repository
public class | source

PluginManager

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 - PluginManager#add

plugins:add:all - PluginManager#addAll

plugins:create:event:proxy - PluginManager#createEventProxy

plugins:destroy:manager - PluginManager#destroy

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

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

plugins:get:method:names - PluginManager#getMethodNames

plugins:get:options - PluginManager#getOptions

plugins:get:plugin:data - PluginManager#getPluginData

plugins:get:plugin:enabled - PluginManager#getPluginEnabled

plugins:get:plugin:event:names - PluginManager#getPluginEventNames

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

plugins:get:plugin:names - PluginManager#getPluginNames

plugins:get:plugin:options - PluginManager#getPluginOptions

plugins:get:plugins:enabled - PluginManager#getPluginsEnabled

plugins:get:plugins:by:event:name - PluginManager#getPluginsByEventName

plugins:get:plugins:event:names - PluginManager#getPluginsEventNames

plugins:has:method - PluginManager#hasMethod

plugins:has:plugin - PluginManager#hasPlugin

plugins:has:plugin:method - PluginManager#hasPluginMethod

plugins:invoke - PluginManager#invoke

plugins:invoke:async - PluginManager#invokeAsync

plugins:invoke:sync - PluginManager#invokeSync

plugins:invoke:sync:event - PluginManager#invokeSyncEvent

plugins:is:valid:config - PluginManager#isValidConfig

plugins:remove - PluginManager#remove

plugins:remove:all - PluginManager#removeAll

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

plugins:set:plugin:enabled - PluginManager#setPluginEnabled

plugins:set:plugins:enabled - PluginManager#setPluginsEnabled

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.

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.

See:

Example:

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 will make a copy of the hash and the 4th defines a pass through object 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!

Constructor Summary

Public Constructor
public

constructor(options: object, extraEventData: object)

Instantiates PluginManager

Member Summary

Private Members
private

Stores the prepend string for eventbus registration.

private

Stores any associated eventbus.

private

Stores any extra options / data to add to PluginEvent callbacks.

private

Defines options for throwing exceptions.

private

Stores the plugins by name with an associated PluginEntry.

Method Summary

Public Methods
public

add(pluginConfig: PluginConfig): PluginData | undefined

Adds a plugin by the given configuration parameters.

public

Initializes multiple plugins in a single call.

public

If an eventbus is assigned to this plugin manager then a new EventProxy wrapping this eventbus is returned.

public

Destroys all managed plugins after unloading them.

public

Returns all plugin data or if a boolean is passed in will return plugin data by current enabled state.

public

Returns any associated eventbus.

public

Returns any extra event data associated with PluginEvents.

public

Returns all method names or if a boolean is passed in will return method names for plugins by current enabled state.

public

Returns a copy of the plugin manager options.

public

Gets the plugin data for a plugin by name.

public

Returns the enabled state of a plugin.

public

Returns the event binding names registered on any associated plugin EventProxy.

public

getPluginMethodNames(enabled: boolean | undefined): Array<{plugin: string, method: string}>

Returns all plugin names or if a boolean is passed in will return plugin names by current enabled state.

public

Returns all plugin names or if a boolean is passed in will return plugin names by current enabled state.

public

getPluginOptions(pluginName: string): *

Returns a copy of the given plugin options.

public

Returns the plugin names that registered the given event binding name.

public

getPluginsEnabled(pluginNames: Array<string>): Array<{pluginname: string, enabled: boolean}>

Returns the enabled state of a list of plugins.

public

getPluginsEventNames(nameOrList: string | string[]): Array<{pluginname: string, events: string[]}>

Returns the event binding names registered from each plugin.

public

hasMethod(methodName: string): boolean

Returns true if there is at least one plugin loaded with the given method name.

public

hasPlugin(pluginName: string): boolean

Returns true if there is a plugin loaded with the given plugin name.

public

hasPluginMethod(pluginName: string, methodName: string): boolean

Returns true if there is a plugin loaded with the given plugin name that also has a method with the given method name.

public

invoke(methodName: string, args: * | Array<*>, nameOrList: string | Array<string>)

This dispatch method simply invokes any plugin targets for the given methodName..

public

invokeAsync(methodName: string, args: * | Array<*>, nameOrList: string | Array<string>): * | Array<*>

This dispatch method uses ES6 Promises and adds any returned results to an array which is added to a Promise.all construction which passes back a Promise which waits until all Promises complete.

public

invokeSync(methodName: string, args: * | Array<*>, nameOrList: string | Array<string>): * | Array<*>

This dispatch method synchronously passes back a single value or an array with all results returned by any invoked targets.

public

invokeSyncEvent(methodName: string, copyProps: object, passthruProps: object, nameOrList: string | Array<string>): PluginEvent | undefined

This dispatch method synchronously passes to and returns from any invoked targets a PluginEvent.

public

Performs validation of a PluginConfig.

public

remove(pluginName: string): boolean

Removes a plugin by name after unloading it and clearing any event bindings automatically.

public

Removes all plugins after unloading them and clearing any event bindings automatically.

public

setEventbus(targetEventbus: TyphonEvents, eventPrepend: string): PluginManager

Sets the eventbus associated with this plugin manager.

public

setExtraEventData(extraEventData: *)

Sets any extra event data attached to PluginEvent extra field.

public

Set optional parameters.

public

setPluginEnabled(pluginName: string, enabled: boolean): boolean

Enables or disables a single plugin.

public

setPluginsEnabled(pluginNames: Array<string>, enabled: boolean): boolean

Enables or disables a set of plugins given an array or iterabe of plugin names.

Private Methods
private

Provides the eventbus callback which may prevent addition if optional noEventAdd is enabled.

private

_addEventbus(pluginName: string): boolean

Provides the eventbus callback which may prevent addition if optional noEventAdd is enabled.

private

Provides the eventbus callback which may prevent plugin mananger destruction if optional noEventDestroy is enabled.

private

Provides the eventbus callback which may prevent removal if optional noEventRemoval is enabled.

private

Provides the eventbus callback which may prevent removal if optional noEventRemoval is enabled.

Public Constructors

public constructor(options: object, extraEventData: object) source

Instantiates PluginManager

Params:

NameTypeAttributeDescription
options object
  • optional

Provides various configuration options:

options.eventbus TyphonEvents
  • optional

An instance of 'backbone-esnext-events' used as the plugin eventbus.

options.eventPrepend string
  • optional
  • default: 'plugin'

A customized name to prepend PluginManager events on the eventbus.

options.throwNoMethod boolean
  • optional
  • default: false

If true then when a method fails to be invoked by any plugin an exception will be thrown.

options.throwNoPlugin boolean
  • optional
  • default: false

If true then when no plugin is matched to be invoked an exception will be thrown.

extraEventData object
  • optional

Provides additional optional data to attach to PluginEvent callbacks.

Private Members

private _eventPrepend: string source

Stores the prepend string for eventbus registration.

private _eventbus: TyphonEvents source

Stores any associated eventbus.

private _extraEventData: Object source

Stores any extra options / data to add to PluginEvent callbacks.

private _options: PluginManagerOptions source

Defines options for throwing exceptions. Turned off by default.

private _pluginMap: Map<string, PluginEntry> source

Stores the plugins by name with an associated PluginEntry.

Public Methods

public add(pluginConfig: PluginConfig): PluginData | undefined source

Adds a plugin by the given configuration parameters. A plugin name is always required. If no other options are provided then the name doubles as the NPM module / local file to load. The loading first checks for an existing instance to use as the plugin. Then the target is chosen as the NPM module / local file to load. By passing in options this will be stored and accessible to the plugin during all callbacks.

Params:

NameTypeAttributeDescription
pluginConfig PluginConfig

Defines the plugin to load.

Return:

PluginData | undefined

public addAll(pluginConfigs: Array<PluginConfig>): Array<PluginData> source

Initializes multiple plugins in a single call.

Params:

NameTypeAttributeDescription
pluginConfigs Array<PluginConfig>

An array of plugin config object hash entries.

Return:

Array<PluginData>

public createEventProxy(): EventProxy source

If an eventbus is assigned to this plugin manager then a new EventProxy wrapping this eventbus is returned.

Return:

EventProxy

public destroy() source

Destroys all managed plugins after unloading them.

public getAllPluginData(enabled: boolean | undefined): Array<PluginData> source

Returns all plugin data or if a boolean is passed in will return plugin data by current enabled state.

Params:

NameTypeAttributeDescription
enabled boolean | undefined

If enabled is a boolean it will return plugins given their enabled state.

Return:

Array<PluginData>

public getEventbus(): TyphonEvents | null source

Returns any associated eventbus.

Return:

TyphonEvents | null

public getExtraEventData(): * source

Returns any extra event data associated with PluginEvents.

Return:

*

public getMethodNames(enabled: boolean | undefined, pluginName: string | undefined): Array<string> source

Returns all method names or if a boolean is passed in will return method names for plugins by current enabled state.

Params:

NameTypeAttributeDescription
enabled boolean | undefined

If enabled is a boolean it will return plugin methods names given their enabled state.

pluginName string | undefined

If a string then just this plugins methods names are returned.

Return:

Array<string>

public getOptions(): PluginManagerOptions source

Returns a copy of the plugin manager options.

public getPluginData(pluginName: string): PluginData | undefined source

Gets the plugin data for a plugin by name.

Params:

NameTypeAttributeDescription
pluginName string

A plugin name.

Return:

PluginData | undefined

public getPluginEnabled(pluginName: string): boolean source

Returns the enabled state of a plugin.

Params:

NameTypeAttributeDescription
pluginName string

Plugin name to set state.

Return:

boolean

Operation success.

public getPluginEventNames(pluginName: string): string[] source

Returns the event binding names registered on any associated plugin EventProxy.

Params:

NameTypeAttributeDescription
pluginName string

Plugin name to set state.

Return:

string[]

Event binding names registered from the plugin.

public getPluginMethodNames(enabled: boolean | undefined): Array<{plugin: string, method: string}> source

Returns all plugin names or if a boolean is passed in will return plugin names by current enabled state.

Params:

NameTypeAttributeDescription
enabled boolean | undefined

If enabled is a boolean it will return plugins given their enabled state.

Return:

Array<{plugin: string, method: string}>

public getPluginNames(enabled: boolean | undefined): Array<string> source

Returns all plugin names or if a boolean is passed in will return plugin names by current enabled state.

Params:

NameTypeAttributeDescription
enabled boolean | undefined

If enabled is a boolean it will return plugins given their enabled state.

Return:

Array<string>

public getPluginOptions(pluginName: string): * source

Returns a copy of the given plugin options.

Params:

NameTypeAttributeDescription
pluginName string

Plugin name to retrieve.

Return:

*

public getPluginsByEventName(eventName: string): Array<string[]> source

Returns the plugin names that registered the given event binding name.

Params:

NameTypeAttributeDescription
eventName string

An event name that plugins may have registered.

Return:

Array<string[]>

A list of plugin names that has registered the given event name.

public getPluginsEnabled(pluginNames: Array<string>): Array<{pluginname: string, enabled: boolean}> source

Returns the enabled state of a list of plugins.

Params:

NameTypeAttributeDescription
pluginNames Array<string>

An array / iterable of plugin names.

Return:

Array<{pluginname: string, enabled: boolean}>

A list of objects with plugin name and enabled state.

public getPluginsEventNames(nameOrList: string | string[]): Array<{pluginname: string, events: string[]}> source

Returns the event binding names registered from each plugin.

Params:

NameTypeAttributeDescription
nameOrList string | string[]
  • optional

An array / iterable of plugin names.

Return:

Array<{pluginname: string, events: string[]}>

A list of objects with plugin name and event binding names registered from the plugin.

public hasMethod(methodName: string): boolean source

Returns true if there is at least one plugin loaded with the given method name.

Params:

NameTypeAttributeDescription
methodName string

Method name to test.

Return:

boolean

True method is found.

public hasPlugin(pluginName: string): boolean source

Returns true if there is a plugin loaded with the given plugin name.

Params:

NameTypeAttributeDescription
pluginName string

Plugin name to test.

Return:

boolean

True if a plugin exists.

public hasPluginMethod(pluginName: string, methodName: string): boolean source

Returns true if there is a plugin loaded with the given plugin name that also has a method with the given method name.

Params:

NameTypeAttributeDescription
pluginName string

Plugin name to test.

methodName string

Method name to test.

Return:

boolean

True if a plugin and method exists.

public invoke(methodName: string, args: * | Array<*>, nameOrList: string | Array<string>) source

This dispatch method simply invokes any plugin targets for the given methodName..

Params:

NameTypeAttributeDescription
methodName string

Method name to invoke.

args * | Array<*>
  • optional

Optional arguments. An array will be spread as multiple arguments.

nameOrList string | Array<string>
  • optional

An optional plugin name or array / iterable of plugin names to invoke.

public invokeAsync(methodName: string, args: * | Array<*>, nameOrList: string | Array<string>): * | Array<*> source

This dispatch method uses ES6 Promises and adds any returned results to an array which is added to a Promise.all construction which passes back a Promise which waits until all Promises complete. Any target invoked may return a Promise or any result. This is very useful to use for any asynchronous operations.

Params:

NameTypeAttributeDescription
methodName string

Method name to invoke.

args * | Array<*>
  • optional

Optional arguments. An array will be spread as multiple arguments.

nameOrList string | Array<string>
  • optional

An optional plugin name or array / iterable of plugin names to invoke.

Return:

* | Array<*>

public invokeSync(methodName: string, args: * | Array<*>, nameOrList: string | Array<string>): * | Array<*> source

This dispatch method synchronously passes back a single value or an array with all results returned by any invoked targets.

Params:

NameTypeAttributeDescription
methodName string

Method name to invoke.

args * | Array<*>
  • optional

Optional arguments. An array will be spread as multiple arguments.

nameOrList string | Array<string>
  • optional

An optional plugin name or array / iterable of plugin names to invoke.

Return:

* | Array<*>

public invokeSyncEvent(methodName: string, copyProps: object, passthruProps: object, nameOrList: string | Array<string>): PluginEvent | undefined source

This dispatch method synchronously passes to and returns from any invoked targets a PluginEvent.

Params:

NameTypeAttributeDescription
methodName string

Method name to invoke.

copyProps object
  • optional
  • default: {}

plugin event object.

passthruProps object
  • optional
  • default: {}

if true, event has plugin option.

nameOrList string | Array<string>
  • optional

An optional plugin name or array / iterable of plugin names to invoke.

public isValidConfig(pluginConfig: PluginConfig): boolean source

Performs validation of a PluginConfig.

Params:

NameTypeAttributeDescription
pluginConfig PluginConfig

A PluginConfig to validate.

Return:

boolean

True if the given PluginConfig is valid.

public remove(pluginName: string): boolean source

Removes a plugin by name after unloading it and clearing any event bindings automatically.

Params:

NameTypeAttributeDescription
pluginName string

The plugin name to remove.

Return:

boolean

Operation success.

public removeAll() source

Removes all plugins after unloading them and clearing any event bindings automatically.

public setEventbus(targetEventbus: TyphonEvents, eventPrepend: string): PluginManager source

Sets the eventbus associated with this plugin manager. If any previous eventbus was associated all plugin manager events will be removed then added to the new eventbus. If there are any existing plugins being managed their events will be removed from the old eventbus and then onPluginLoad will be called with the new eventbus.

Params:

NameTypeAttributeDescription
targetEventbus TyphonEvents

The target eventbus to associate.

eventPrepend string
  • optional
  • default: 'plugins'

An optional string to prepend to all of the event binding targets.

Return:

PluginManager

public setExtraEventData(extraEventData: *) source

Sets any extra event data attached to PluginEvent extra field.

Params:

NameTypeAttributeDescription
extraEventData *

Adds extra data to PluginEvent extra field.

public setOptions(options: PluginManagerOptions) source

Set optional parameters. All parameters are off by default.

Params:

NameTypeAttributeDescription
options PluginManagerOptions

Defines optional parameters to set.

public setPluginEnabled(pluginName: string, enabled: boolean): boolean source

Enables or disables a single plugin.

Params:

NameTypeAttributeDescription
pluginName string

Plugin name to set state.

enabled boolean

The new enabled state.

Return:

boolean

Operation success.

public setPluginsEnabled(pluginNames: Array<string>, enabled: boolean): boolean source

Enables or disables a set of plugins given an array or iterabe of plugin names.

Params:

NameTypeAttributeDescription
pluginNames Array<string>

An array / iterable of plugin names.

enabled boolean

The new enabled state.

Return:

boolean

Operation success.

Private Methods

private _addAllEventbus(pluginConfigs: Array<PluginConfig>): Array<PluginData> source

Provides the eventbus callback which may prevent addition if optional noEventAdd is enabled. This disables the ability for plugins to be added via events preventing any external code adding plugins in this manner.

Params:

NameTypeAttributeDescription
pluginConfigs Array<PluginConfig>

An array of plugin config object hash entries.

Return:

Array<PluginData>

private _addEventbus(pluginName: string): boolean source

Provides the eventbus callback which may prevent addition if optional noEventAdd is enabled. This disables the ability for plugins to be added via events preventing any external code adding plugins in this manner.

Params:

NameTypeAttributeDescription
pluginName string

The plugin name to remove.

Return:

boolean

Operation success.

private _destroyEventbus() source

Provides the eventbus callback which may prevent plugin mananger destruction if optional noEventDestroy is enabled. This disables the ability for the plugin mananger to be destroyed via events preventing any external code removing plugins in this manner.

private _removeAllEventbus() source

Provides the eventbus callback which may prevent removal if optional noEventRemoval is enabled. This disables the ability for plugins to be removed via events preventing any external code removing plugins in this manner.

private _removeEventbus(pluginName: string): boolean source

Provides the eventbus callback which may prevent removal if optional noEventRemoval is enabled. This disables the ability for plugins to be removed via events preventing any external code removing plugins in this manner.

Params:

NameTypeAttributeDescription
pluginName string

The plugin name to remove.

Return:

boolean

Operation success.