import * as grpc from '@grpc/grpc-js' ; import { injectable , interfaces } from 'inversify' ; import { SchemaService , loadProtoService } from '@centsideas/schemas' ; import { Logger } from '@centsideas/utils' ; @ injectable ( ) export class RpcClient < T = any > { client : T = { } as any ; private readonly defaultPort = 40000 ; private internalRpcClient ! : grpc . Client ; constructor ( private logger ) { } initialize ( host , service , port = this . defaultPort ) { const serviceDefinition = loadProtoService ( service ) ; this . internalRpcClient = new serviceDefinition ( `${ host }:${ port }` , grpc . credentials . createInsecure ( ) ) ; this . registerMethods ( Object . keys ( serviceDefinition . service ) ) ; } /**
     * Creates wrappers for grpc unary calls that allows to use
     * promises instead of the default callback
     */ private registerMethods ( methodNames ) { methodNames . forEach ( methodName => { ( this . client as any ) [ methodName ] = ( payload ) => { return new Promise ( ( resolve , reject ) => { this . logger . info ( 'rpc:client' , methodName , payload ) ; const method = ( this . internalRpcClient as any ) [ methodName ] ( payload , ( err , response ) => { if ( err ) reject ( err ) ; resolve ( response ) ; } ) ; ( this . internalRpcClient as any ) [ methodName ] . bind ( method ) ; } ) ; } ; } ) ; } } export type RpcClientFactory = ( options : { host : string ; service : SchemaService ; port ? : number ; } ) => RpcClient < any > ; export const rpcClientFactory = ( context ) : RpcClientFactory => { return ( { host , service , port } ) => { const rpcClient = context . container . get ( RpcClient ) ; rpcClient . initialize ( host , service , port ) ; return rpcClient ; } ; } ;