import { Event } from 'electron' ; import { EventEmitter } from 'events' ; import { Container as InversifyContainer } from 'inversify' ; import { Class } from 'type-fest' ; import ipcService from '../services/ipc' ; import Logger , { $ipcLogger , $mainLogger } from '../services/logger' ; import { IPC_EVENT_KEY } from '../utils/decorators' ; import { AppDependencies , ControllerMeta , AsyncServiceProvider } from './types' ; class Container extends InversifyContainer { controllers : Class [ ] ; constructor ( { controllers , services } ) { super ( { skipBaseClassChecks : true } ) ; this . controllers = controllers ; services . forEach ( ( { provide , useClass , useValue } ) => { if ( useClass ) { this . bind ( provide || useClass ) . to ( useClass ) . inSingletonScope ( ) ; } else if ( useValue ) { this . bind ( provide as any ) . toConstantValue ( useValue ) ; } } ) ; } async bindAsync ( { provide , usePromise } ) { const { default : service } = await usePromise ; const logger = this . get < Logger > ( $mainLogger ) ; logger . log ( `Async service loaded => ${ service . name }` ) ; this . bind ( provide ) . to ( service ) . inSingletonScope ( ) ; } listen ( ) { const ipc = this . get < EventEmitter > ( ipcService ) ; const logger = this . get < Logger > ( $ipcLogger ) ; this . controllers . forEach ( ( Controller ) => { try { this . bind ( Controller ) . to ( Controller ) . inSingletonScope ( ) ; const meta = Reflect . getMetadata ( IPC_EVENT_KEY , Controller . prototype ) ; const controller = this . get ( Controller ) ; meta . forEach ( ( { eventName , name , once } ) => { const on = once ? ipc . once : ipc . on ; on . bind ( ipc ) ( eventName , ( event , data ) => { logger . logEvent ( { once , direction : 'in' , event : eventName , data } ) ; const result = controller [ name ] ( event , data ) ; if ( result instanceof Promise ) { result . catch ( ( err ) => { logger . error ( `error in event ${ eventName } => ${ err . message }` ) ; logger . error ( err . stack ) ; } ) ; } } ) ; } ) ; } catch ( e ) { logger . error ( 'Service failed to initialize' ) ; logger . error ( e ) ; } } ) ; } } export default Container ;