import { BasePlugin } from './index'; import { Error, getLogger } from '@playkit-js/playkit-js'; import { PluginClassType } from '../../types'; export const REGISTERED_PLUGINS_LIST_EVENT = 'registeredpluginslistevent'; /** * The logger of the PluginManager class. * @private * @const */ /** The PluginManager responsible for register plugins definitions and store plugins instances. * @classdesc */ export class PluginManager { private static _logger = getLogger('PluginManager'); /** * The registry of the plugins. * Maps plugin's name to his class. * @type {Map} * @static * @private */ private static _registry: Map = new Map(); /** * The active plugins in the player. * Maps plugin's name to his instance. * @type {Object} * @private */ private _plugins: { [name: string]: BasePlugin } = {}; /** * Is disabled plugin map. * Maps plugin's name to a boolean. * false means the plugin is disable. true or plugin name doesn't exist in the map means the plugin is not disable. * @type {Map} * @private */ private _isDisabledPluginMap: Map = new Map(); /** * Writes the plugin in the registry. * Maps: plugin name -> plugin class. * @param {string} name - The plugin name * @param PluginClass * @returns {boolean} - If the registration request succeeded * @static * @public */ public static register(name: string, PluginClass: PluginClassType): boolean { if (!(typeof PluginClass === 'function' && PluginClass.prototype instanceof BasePlugin)) { PluginManager._logger.error(`Plugin <${name}> registration failed, plugin is not an instance of BasePlugin`); return false; } if (!PluginManager._registry.has(name)) { PluginManager._registry.set(name, PluginClass); PluginManager._logger.debug(`Plugin <${name}> has been registered successfully`); return true; } PluginManager._logger.debug(`Plugin <${name}> is already registered, do not register again`); return false; } /** * Removes the plugin from the registry. * @param {string} name - The plugin name * @static * @public * @returns {void} */ public static unRegister(name: string): void { if (PluginManager._registry.has(name)) { PluginManager._registry.delete(name); PluginManager._logger.debug(`Unregistered <${name}> plugin.`); } } /** * Creates and store new instance of the plugin in case isValid() of the plugin returns true. * @param {string} name - The plugin name * @param {Object} player - The player reference * @param {Object} [config={}] - The plugin configuration * @returns {boolean} - Whether the plugin load was successful * @public */ public load(name: string, player: any, config: any = {}): boolean { if (!PluginManager._registry.has(name)) { PluginManager._logger.warn(`Plugin <${name}> loading failed, plugin is not registered`); throw new Error(Error.Severity.RECOVERABLE, Error.Category.PLAYER, Error.Code.RUNTIME_ERROR_NOT_REGISTERED_PLUGIN, name); } const PluginClass = PluginManager._registry.get(name)!; if (typeof config.disable === 'boolean') { this._isDisabledPluginMap.set(name, config.disable); } const isDisablePlugin = !!this._isDisabledPluginMap.get(name); const isValidPlugin = PluginClass ? PluginClass.isValid() : false; if (PluginClass && isValidPlugin && !isDisablePlugin) { try { this._plugins[name] = new PluginClass(name, player, config); } catch (e) { throw new Error(Error.Severity.RECOVERABLE, Error.Category.PLAYER, Error.Code.PLUGIN_LOAD_FAILED, e); } this._isDisabledPluginMap.set(name, false); PluginManager._logger.debug(`Plugin <${name}> has been loaded`); return true; } PluginManager._logger.debug(`Plugin <${name}> isn't loaded, isValid()=${isValidPlugin.toString()}, disabled=${isDisablePlugin.toString()}`); return false; } public getRegisterdPluginsList(): string[] { return Array.from(PluginManager._registry.keys()); } /** * Iterates over all the plugins and calls loadMedia(). * @public * @returns {void} */ public loadMedia(): void { Object.keys(this._plugins).forEach((k) => this._plugins[k].loadMedia()); } /** * Iterates over all the plugins and calls destroy(). * @public * @returns {void} */ public destroy(): void { Object.keys(this._plugins).forEach((k) => { this._plugins[k].destroy(); delete this._plugins[k]; }); } /** * Iterates over all the plugins and calls reset() method of the plugin's impl. * @public * @returns {void} */ public reset(): void { Object.keys(this._plugins).forEach((k) => this._plugins[k].reset()); } /** * Returns the plugin's instance. * @param {string} name - The plugin name. * @returns {BasePlugin} - The plugin instance. * @public */ public get(name: string): BasePlugin | undefined { return this._plugins[name]; } /** * Returns all plugins. * @returns {Object} - All plugins. * @public */ public getAll(): { [name: string]: BasePlugin } { return this._plugins; } } /** * Export the register method. * @type {function} * @constant */ // Extract the register method from PluginManager const { register: registerPlugin } = PluginManager; // Export the register method as registerPlugin export { registerPlugin };