@@ -5,8 +5,8 @@ import { Emitter } from "@coder/events";
55import { logger , field } from "@coder/logger" ;
66import { ReadWriteConnection , InitData , SharedProcessData } from "../common/connection" ;
77import { Module , ServerProxy } from "../common/proxy" ;
8- import { stringify , parse , moduleToProto , protoToModule , protoToOperatingSystem } from "../common/util" ;
9- import { Ping , ServerMessage , ClientMessage , MethodMessage , NamedProxyMessage , NumberedProxyMessage , SuccessMessage , FailMessage , EventMessage , CallbackMessage } from "../proto" ;
8+ import { argumentToProto , protoToArgument , moduleToProto , protoToModule , protoToOperatingSystem } from "../common/util" ;
9+ import { Argument , Ping , ServerMessage , ClientMessage , Method , Event , Callback } from "../proto" ;
1010import { FsModule , ChildProcessModule , NetModule , NodePtyModule , SpdlogModule , TrashModule } from "./modules" ;
1111
1212// tslint:disable no-any
@@ -24,8 +24,8 @@ export class Client {
2424 private messageId = 0 ;
2525 private callbackId = 0 ;
2626 private readonly proxies = new Map < number | Module , ProxyData > ( ) ;
27- private readonly successEmitter = new Emitter < SuccessMessage > ( ) ;
28- private readonly failEmitter = new Emitter < FailMessage > ( ) ;
27+ private readonly successEmitter = new Emitter < Method . Success > ( ) ;
28+ private readonly failEmitter = new Emitter < Method . Fail > ( ) ;
2929 private readonly eventEmitter = new Emitter < { event : string ; args : any [ ] ; } > ( ) ;
3030
3131 private _initData : InitData | undefined ;
@@ -129,9 +129,9 @@ export class Client {
129129 field ( "event listeners" , this . eventEmitter . counts ) ,
130130 ] ) ;
131131
132- const message = new FailMessage ( ) ;
132+ const message = new Method . Fail ( ) ;
133133 const error = new Error ( "disconnected" ) ;
134- message . setResponse ( stringify ( error ) ) ;
134+ message . setResponse ( argumentToProto ( error ) ) ;
135135 this . failEmitter . emit ( message ) ;
136136
137137 this . eventEmitter . emit ( { event : "disconnected" , args : [ error ] } ) ;
@@ -182,20 +182,21 @@ export class Client {
182182 case "kill" :
183183 return Promise . resolve ( ) ;
184184 }
185+
185186 return Promise . reject (
186187 new Error ( `Unable to call "${ method } " on proxy ${ proxyId } : disconnected` ) ,
187188 ) ;
188189 }
189190
190- const message = new MethodMessage ( ) ;
191+ const message = new Method ( ) ;
191192 const id = this . messageId ++ ;
192- let proxyMessage : NamedProxyMessage | NumberedProxyMessage ;
193+ let proxyMessage : Method . Named | Method . Numbered ;
193194 if ( typeof proxyId === "string" ) {
194- proxyMessage = new NamedProxyMessage ( ) ;
195+ proxyMessage = new Method . Named ( ) ;
195196 proxyMessage . setModule ( moduleToProto ( proxyId ) ) ;
196197 message . setNamedProxy ( proxyMessage ) ;
197198 } else {
198- proxyMessage = new NumberedProxyMessage ( ) ;
199+ proxyMessage = new Method . Numbered ( ) ;
199200 proxyMessage . setProxyId ( proxyId ) ;
200201 message . setNumberedProxy ( proxyMessage ) ;
201202 }
@@ -215,16 +216,14 @@ export class Client {
215216 return callbackId ;
216217 } ;
217218
218- const stringifiedArgs = args . map ( ( a ) => stringify ( a , storeCallback ) ) ;
219219 logger . trace ( ( ) => [
220220 "sending" ,
221221 field ( "id" , id ) ,
222222 field ( "proxyId" , proxyId ) ,
223223 field ( "method" , method ) ,
224- field ( "args" , stringifiedArgs ) ,
225224 ] ) ;
226225
227- proxyMessage . setArgsList ( stringifiedArgs ) ;
226+ proxyMessage . setArgsList ( args . map ( ( a ) => argumentToProto ( a , storeCallback ) ) ) ;
228227
229228 const clientMessage = new ClientMessage ( ) ;
230229 clientMessage . setMethod ( message ) ;
@@ -246,12 +245,12 @@ export class Client {
246245
247246 const d1 = this . successEmitter . event ( id , ( message ) => {
248247 dispose ( ) ;
249- resolve ( this . parse ( message . getResponse ( ) , promise ) ) ;
248+ resolve ( this . protoToArgument ( message . getResponse ( ) , promise ) ) ;
250249 } ) ;
251250
252251 const d2 = this . failEmitter . event ( id , ( message ) => {
253252 dispose ( ) ;
254- reject ( parse ( message . getResponse ( ) ) ) ;
253+ reject ( protoToArgument ( message . getResponse ( ) ) ) ;
255254 } ) ;
256255 } ) ;
257256
@@ -262,42 +261,53 @@ export class Client {
262261 * Handle all messages from the server.
263262 */
264263 private async handleMessage ( message : ServerMessage ) : Promise < void > {
265- if ( message . hasInit ( ) ) {
266- const init = message . getInit ( ) ! ;
267- this . _initData = {
268- dataDirectory : init . getDataDirectory ( ) ,
269- homeDirectory : init . getHomeDirectory ( ) ,
270- tmpDirectory : init . getTmpDirectory ( ) ,
271- workingDirectory : init . getWorkingDirectory ( ) ,
272- os : protoToOperatingSystem ( init . getOperatingSystem ( ) ) ,
273- shell : init . getShell ( ) ,
274- builtInExtensionsDirectory : init . getBuiltinExtensionsDir ( ) ,
275- } ;
276- this . initDataEmitter . emit ( this . _initData ) ;
277- } else if ( message . hasSuccess ( ) ) {
278- this . emitSuccess ( message . getSuccess ( ) ! ) ;
279- } else if ( message . hasFail ( ) ) {
280- this . emitFail ( message . getFail ( ) ! ) ;
281- } else if ( message . hasEvent ( ) ) {
282- await this . emitEvent ( message . getEvent ( ) ! ) ;
283- } else if ( message . hasCallback ( ) ) {
284- await this . runCallback ( message . getCallback ( ) ! ) ;
285- } else if ( message . hasSharedProcessActive ( ) ) {
286- const sharedProcessActiveMessage = message . getSharedProcessActive ( ) ! ;
287- this . sharedProcessActiveEmitter . emit ( {
288- socketPath : sharedProcessActiveMessage . getSocketPath ( ) ,
289- logPath : sharedProcessActiveMessage . getLogPath ( ) ,
290- } ) ;
291- } else if ( message . hasPong ( ) ) {
292- // Nothing to do since pings are on a timer rather than waiting for the
293- // next pong in case a message from either the client or server is dropped
294- // which would break the ping cycle.
295- } else {
296- throw new Error ( "unknown message type" ) ;
264+ switch ( message . getMsgCase ( ) ) {
265+ case ServerMessage . MsgCase . INIT :
266+ const init = message . getInit ( ) ! ;
267+ this . _initData = {
268+ dataDirectory : init . getDataDirectory ( ) ,
269+ homeDirectory : init . getHomeDirectory ( ) ,
270+ tmpDirectory : init . getTmpDirectory ( ) ,
271+ workingDirectory : init . getWorkingDirectory ( ) ,
272+ os : protoToOperatingSystem ( init . getOperatingSystem ( ) ) ,
273+ shell : init . getShell ( ) ,
274+ builtInExtensionsDirectory : init . getBuiltinExtensionsDir ( ) ,
275+ } ;
276+ this . initDataEmitter . emit ( this . _initData ) ;
277+ break ;
278+ case ServerMessage . MsgCase . SUCCESS :
279+ this . emitSuccess ( message . getSuccess ( ) ! ) ;
280+ break ;
281+ case ServerMessage . MsgCase . FAIL :
282+ this . emitFail ( message . getFail ( ) ! ) ;
283+ break ;
284+ case ServerMessage . MsgCase . EVENT :
285+ await this . emitEvent ( message . getEvent ( ) ! ) ;
286+ break ;
287+ case ServerMessage . MsgCase . CALLBACK :
288+ await this . runCallback ( message . getCallback ( ) ! ) ;
289+ break ;
290+ case ServerMessage . MsgCase . SHARED_PROCESS_ACTIVE :
291+ const sharedProcessActiveMessage = message . getSharedProcessActive ( ) ! ;
292+ this . sharedProcessActiveEmitter . emit ( {
293+ socketPath : sharedProcessActiveMessage . getSocketPath ( ) ,
294+ logPath : sharedProcessActiveMessage . getLogPath ( ) ,
295+ } ) ;
296+ break ;
297+ case ServerMessage . MsgCase . PONG :
298+ // Nothing to do since pings are on a timer rather than waiting for the
299+ // next pong in case a message from either the client or server is dropped
300+ // which would break the ping cycle.
301+ break ;
302+ default :
303+ throw new Error ( "unknown message type" ) ;
297304 }
298305 }
299306
300- private emitSuccess ( message : SuccessMessage ) : void {
307+ /**
308+ * Convert message to a success event.
309+ */
310+ private emitSuccess ( message : Method . Success ) : void {
301311 logger . trace ( ( ) => [
302312 "received resolve" ,
303313 field ( "id" , message . getId ( ) ) ,
@@ -306,7 +316,10 @@ export class Client {
306316 this . successEmitter . emit ( message . getId ( ) , message ) ;
307317 }
308318
309- private emitFail ( message : FailMessage ) : void {
319+ /**
320+ * Convert message to a fail event.
321+ */
322+ private emitFail ( message : Method . Fail ) : void {
310323 logger . trace ( ( ) => [
311324 "received reject" ,
312325 field ( "id" , message . getId ( ) ) ,
@@ -322,7 +335,7 @@ export class Client {
322335 * request before it emits. Instead, emit all events from the server so all
323336 * events are always caught on the client.
324337 */
325- private async emitEvent ( message : EventMessage ) : Promise < void > {
338+ private async emitEvent ( message : Event ) : Promise < void > {
326339 const eventMessage = message . getNamedEvent ( ) ! || message . getNumberedEvent ( ) ! ;
327340 const proxyId = message . getNamedEvent ( )
328341 ? protoToModule ( message . getNamedEvent ( ) ! . getModule ( ) )
@@ -333,10 +346,9 @@ export class Client {
333346 "received event" ,
334347 field ( "proxyId" , proxyId ) ,
335348 field ( "event" , event ) ,
336- field ( "args" , eventMessage . getArgsList ( ) ) ,
337349 ] ) ;
338350
339- const args = eventMessage . getArgsList ( ) . map ( ( a ) => this . parse ( a ) ) ;
351+ const args = eventMessage . getArgsList ( ) . map ( ( a ) => this . protoToArgument ( a ) ) ;
340352 this . eventEmitter . emit ( proxyId , { event, args } ) ;
341353 }
342354
@@ -348,7 +360,7 @@ export class Client {
348360 * also only be used when passed together with the method. If they are sent
349361 * afterward, they may never be called due to timing issues.
350362 */
351- private async runCallback ( message : CallbackMessage ) : Promise < void > {
363+ private async runCallback ( message : Callback ) : Promise < void > {
352364 const callbackMessage = message . getNamedCallback ( ) ! || message . getNumberedCallback ( ) ! ;
353365 const proxyId = message . getNamedCallback ( )
354366 ? protoToModule ( message . getNamedCallback ( ) ! . getModule ( ) )
@@ -359,16 +371,15 @@ export class Client {
359371 "running callback" ,
360372 field ( "proxyId" , proxyId ) ,
361373 field ( "callbackId" , callbackId ) ,
362- field ( "args" , callbackMessage . getArgsList ( ) ) ,
363374 ] ) ;
364- const args = callbackMessage . getArgsList ( ) . map ( ( a ) => this . parse ( a ) ) ;
375+ const args = callbackMessage . getArgsList ( ) . map ( ( a ) => this . protoToArgument ( a ) ) ;
365376 this . getProxy ( proxyId ) . callbacks . get ( callbackId ) ! ( ...args ) ;
366377 }
367378
368379 /**
369380 * Start the ping loop. Does nothing if already pinging.
370381 */
371- private startPinging = ( ) : void => {
382+ private readonly startPinging = ( ) : void => {
372383 if ( typeof this . pingTimeout !== "undefined" ) {
373384 return ;
374385 }
@@ -505,10 +516,16 @@ export class Client {
505516 await this . getProxy ( proxyId ) . promise ;
506517 }
507518
508- private parse ( value ?: string , promise ?: Promise < any > ) : any {
509- return parse ( value , undefined , ( id ) => this . createProxy ( id , promise ) ) ;
519+ /**
520+ * Same as protoToArgument except provides createProxy.
521+ */
522+ private protoToArgument ( value ?: Argument , promise ?: Promise < any > ) : any {
523+ return protoToArgument ( value , undefined , ( id ) => this . createProxy ( id , promise ) ) ;
510524 }
511525
526+ /**
527+ * Get a proxy. Error if it doesn't exist.
528+ */
512529 private getProxy ( proxyId : number | Module ) : ProxyData {
513530 if ( ! this . proxies . has ( proxyId ) ) {
514531 throw new Error ( `proxy ${ proxyId } disposed too early` ) ;
0 commit comments