import { InjectorContext } from '@deepkit/injector' ; import { rpcActionType , RpcConnectionWriter , RpcControllerAccess , RpcKernel , RpcKernelBaseConnection , RpcKernelConnection , RpcMessage , RpcMessageBuilder , RpcServerAction } from '@deepkit/rpc' ; import { FrameCategory , Stopwatch } from '@deepkit/stopwatch' ; import { ClassType } from '@deepkit/core' ; import { AppModule } from '@deepkit/app' ; export class RpcControllers { public readonly controllers = new Map < string , { controller : ClassType ; module : AppModule < any > ; } > ( ) ; } export class RpcInjectorContext extends InjectorContext { } export class RpcServerActionWithStopwatch extends RpcServerAction { stopwatch ? : Stopwatch ; protected async hasControllerAccess ( controllerAccess ) { const frame = this . stopwatch ? this . stopwatch . start ( 'RPC/controllerAccess' ) : undefined ; try { return await super . hasControllerAccess ( controllerAccess ) ; } finally { if ( frame ) frame . end ( ) ; } } async handleAction ( message , response ) { const body = message . parseBody ( rpcActionType ) ; const frame = this . stopwatch ? this . stopwatch . start ( body . method + '() [' + body . controller + ']' , FrameCategory . rpc , true ) : undefined ; if ( frame ) { const types = await this . loadTypes ( body . controller , body . method ) ; const value = message . parseBody ( types . parameterSchema ) ; frame . data ( { method : body . method , controller : body . controller , arguments : Object . values ( value . args ) } ) ; } try { if ( frame ) return await frame . run ( { } , ( ) => super . handleAction ( message , response ) ) ; return await super . handleAction ( message , response ) ; } finally { if ( frame ) frame . end ( ) ; } } } export class RpcKernelConnectionWithStopwatch extends RpcKernelConnection { protected actionHandler = new RpcServerActionWithStopwatch ( this . controllers , this . injector , this . security , this . sessionState ) ; stopwatch ? : Stopwatch ; setStopwatch ( stopwatch ) { this . stopwatch = stopwatch ; this . actionHandler . stopwatch = stopwatch ; } protected async authenticate ( message , response ) { const frame = this . stopwatch ? this . stopwatch . start ( 'RPC/authenticate' , FrameCategory . rpcAuthenticate , true ) : undefined ; try { return await super . authenticate ( message , response ) ; } finally { if ( frame ) frame . end ( ) ; } } } export class RpcKernelWithStopwatch extends RpcKernel { protected RpcKernelConnection = RpcKernelConnectionWithStopwatch ; stopwatch ? : Stopwatch ; createConnection ( writer , injector ? ) { const connection = super . createConnection ( writer , injector ) ; if ( this . stopwatch && connection instanceof RpcKernelConnectionWithStopwatch ) { connection . setStopwatch ( this . stopwatch ) ; } return connection ; } }