import Logger from '../../tools/env.logger' ; import ControllerPluginRender from './plugin.controller.render' ; import InstalledPlugin , { TConnectionFactory } from './plugin.installed' ; import { IPCMessages } from '../../services/service.electron' ; import { CommonInterfaces } from '../../interfaces/interface.common' ; export { InstalledPlugin , TConnectionFactory } ; class description export default class ControllerPluginsStorage { private _logger : Logger = new Logger ( 'ControllerPluginsStorage' ) ; private _plugins : Map < string , InstalledPlugin > = new Map ( ) ; public destroy ( ) { return new Promise ( ( resolve ) => { Promise . all ( Array . from ( this . _plugins . values ( ) ) . map ( ( plugin ) => { return plugin . destroy ( ) ; } ) ) . catch ( ( error ) => { this . _logger . warn ( `Error on destroy of plugin's storage: ${ error . message }` ) ; } ) . finally ( ( ) => { this . _plugins . clear ( ) ; resolve ( ) ; } ) ; } ) ; } public shutdown ( ) { return new Promise ( ( resolve ) => { Promise . all ( Array . from ( this . _plugins . values ( ) ) . map ( ( plugin ) => { return plugin . shutdown ( ) ; } ) ) . catch ( ( error ) => { this . _logger . warn ( `Error on shutdown of plugin's storage: ${ error . message }` ) ; } ) . finally ( ( ) => { resolve ( ) ; } ) ; } ) ; } public getPluginByName ( name ) { return Array . from ( this . _plugins . values ( ) ) . find ( ( plugin ) => { return plugin . getName ( ) === name ; } ) ; } public getPluginById ( id ) { return Array . from ( this . _plugins . values ( ) ) . find ( ( plugin ) => { return plugin . getId ( ) === id ; } ) ; } public getPluginByToken ( token ) { return Array . from ( this . _plugins . values ( ) ) . find ( ( plugin ) => { return plugin . getToken ( ) === token ; } ) ; } public bindWithSession ( session , connectionFactory ) { return new Promise ( ( resolve , reject ) => { return Promise . all ( Array . from ( this . _plugins . values ( ) ) . map ( ( plugin ) => { return plugin . bindWithSession ( session , connectionFactory ) . then ( ( error ) => { if ( error instanceof Error ) { this . _logger . debug ( `Plugin "${ plugin . getName ( ) }" wouldn't be attached because: ${ error . message }` ) ; } return Promise . resolve ( ) ; } ) . catch ( ( bindErr ) => { this . _logger . warn ( `Fail bind plugin ${ plugin . getName ( ) } with session "${ session }" due error: ${ bindErr . message }` ) ; this . _logger . warn ( `Plugin ${ plugin . getName ( ) } will be excluded.` ) ; this . exclude ( plugin . getName ( ) ) . catch ( ( exclErr ) => { this . _logger . warn ( `Fail exclude plugin ${ plugin . getName ( ) } due error: ${ exclErr . message }` ) ; } ) ; return Promise . resolve ( ) ; } ) ; } ) ) . then ( ( ) => { resolve ( ) ; } ) . catch ( ( error ) => { reject ( error ) ; } ) ; } ) ; } public unbindWithSession ( session ) { return new Promise ( ( resolve , reject ) => { return Promise . all ( Array . from ( this . _plugins . values ( ) ) . map ( ( plugin ) => { return plugin . unbindWithSession ( session ) . catch ( ( bindErr ) => { this . _logger . warn ( `Fail unbind plugin ${ plugin . getName ( ) } with session "${ session }" due error: ${ bindErr . message }` ) ; return Promise . resolve ( ) ; } ) ; } ) ) . then ( ( ) => { resolve ( ) ; } ) . catch ( ( error ) => { reject ( error ) ; } ) ; } ) ; } public getNamesOfInstalled ( ) { return Array . from ( this . _plugins . values ( ) ) . map ( ( plugin ) => { return plugin . getName ( ) ; } ) ; } public getPluginRendersInfo ( ) { const plugins = [ ] ; this . _plugins . forEach ( ( plugin ) => { const controller = plugin . getRenderController ( ) ; if ( controller === undefined || controller . getEntrypoint ( ) === undefined ) { return ; } plugins . push ( { name : plugin . getName ( ) , location : controller . getEntrypoint ( ) as string , token : plugin . getToken ( ) , id : plugin . getId ( ) , displayName : plugin . getDisplayName ( ) , } ) ; } ) ; return plugins ; } public runAllSingleProcess ( ) { return new Promise ( ( resolve , reject ) => { Promise . all ( Array . from ( this . _plugins . values ( ) ) . filter ( ( plugin ) => { return plugin . isSingleProcess ( ) ; } ) . map ( ( plugin ) => { return ( plugin . runAsSingle ( ) as Promise < void > ) . catch ( ( error ) => { this . _logger . warn ( `Fail to run as single plugin ${ plugin . getName ( ) } due error: ${ error }.` ) ; this . exclude ( plugin . getName ( ) ) . catch ( ( exclErr ) => { this . _logger . warn ( `Fail exclude plugin ${ plugin . getName ( ) } due error: ${ exclErr . message }` ) ; } ) ; return Promise . resolve ( ) ; } ) ; } ) ) . then ( ( ) => { this . _logger . debug ( `Single process plugins running is done` ) ; resolve ( ) ; } ) . catch ( ( error ) => { reject ( error ) ; } ) ; } ) ; } public getInstalled ( ) { return Array . from ( this . _plugins . values ( ) ) . map ( ( plugin ) => { return plugin ; } ) ; } public include ( plugin ) { this . _plugins . set ( plugin . getName ( ) , plugin ) ; } public exclude ( name ) { return new Promise ( ( resolve , reject ) => { const plugin = this . _plugins . get ( name ) ; if ( plugin === undefined ) { return reject ( new Error ( this . _logger . warn ( `Cannot exclude plugin "${ name }" because it isn't found` ) ) ) ; } plugin . destroy ( ) . then ( ( ) => { this . _logger . debug ( `Plugin "${ plugin . getName ( ) }" was excluded.` ) ; resolve ( ) ; } ) . catch ( ( error ) => { this . _logger . debug ( `Fail to correctly exclude plugin "${ plugin . getName ( ) }" due error: ${ error . message }` ) ; } ) ; this . _plugins . delete ( name ) ; } ) ; } public logState ( ) { this . _logger . debug ( `Next plugins are initialized:\n${ Array . from ( this . _plugins . values ( ) ) . map ( ( plugin ) => { return `\t - ${ plugin . getName ( ) }` ; } ) . join ( '\n' ) }` ) ; } }