import { injectable } from 'inversify' ; import { Class } from 'type-fest' ; import { ClassDecorator , MethodDecorator , ControllerMeta , MediaEventName } from './types' ; import { IpcEvents } from '@nuclear/core' ; /**
 * the key of the ipc metadata
 */ export const IPC_EVENT_KEY = Symbol ( '$$ipc-event-prefix' ) ; /**
 * the key of the system media metadata
 */ export const SYSTEM_MEDIA_EVENT_KEY = Symbol ( '$$system-media-event-prefix' ) ; const eventEmitterControllerFactory = ( metadataKey ) : ClassDecorator => ( prefix ? ) => { param target returns return ( target ) : Class => { const proto = target . prototype ; let events = Reflect . getMetadata ( metadataKey , proto ) || [ ] ; if ( ! events . length ) { throw new Error ( `The controller ${ proto . constructor . name } has no event registered, you must register at least one` ) ; } if ( prefix ) { events = events . map ( ( event ) => ( { eventName : prefix ? `${ prefix }-${ event . eventName }` : event . eventName , name : event . name } ) ) ; Reflect . defineMetadata ( metadataKey , events , proto ) ; } return injectable ( ) ( target ) ; } ; } ; interface IpcEventOptions { once : boolean ; } remark param eventName const eventListenerFactory = < T > ( metadataKey ) : MethodDecorator < T , IpcEventOptions > => ( eventName , options ) => { param target param name return ( target , name ) : void => { if ( ! eventName ) { throw new Error ( `You must specify an event name for method ${ name } of class ${ target . constructor . name }` ) ; } const meta = Reflect . getMetadata ( metadataKey , target ) || [ ] ; const eventMeta = { eventName , name } ; if ( options && options . once ) { eventMeta . once = options . once ; } meta . push ( eventMeta ) ; Reflect . defineMetadata ( metadataKey , meta , target ) ; } ; } ; export const ipcController = eventEmitterControllerFactory ( IPC_EVENT_KEY ) ; export const ipcEvent = eventListenerFactory < IpcEvents > ( IPC_EVENT_KEY ) ; export const systemMediaController = eventEmitterControllerFactory ( SYSTEM_MEDIA_EVENT_KEY ) ; export const systemMediaEvent = eventListenerFactory < MediaEventName > ( SYSTEM_MEDIA_EVENT_KEY ) ;