@@ -115,10 +115,6 @@ namespace ts.server {
115115 project : Project ;
116116 }
117117
118- export interface EventSender {
119- event < T > ( payload : T , eventName : string ) : void ;
120- }
121-
122118 function allEditsBeforePos ( edits : ts . TextChange [ ] , pos : number ) {
123119 for ( const edit of edits ) {
124120 if ( textSpanEnd ( edit . span ) >= pos ) {
@@ -253,6 +249,55 @@ namespace ts.server {
253249 }
254250 }
255251
252+ export type Event = < T > ( body : T , eventName : string ) => void ;
253+
254+ export interface EventSender {
255+ event : Event ;
256+ }
257+
258+ class SocketEventSender implements EventSender {
259+ private host : ServerHost ;
260+ private logger : Logger ;
261+ private eventPort : number ;
262+ private eventSocket : NodeSocket ;
263+ private socketEventQueue : { body : any , eventName : string } [ ] | undefined ;
264+
265+ constructor ( host : ServerHost , logger : Logger , eventPort : number ) {
266+ this . host = host ;
267+ this . logger = logger ;
268+ this . eventPort = eventPort ;
269+
270+ const s = net . connect ( { port : this . eventPort } , ( ) => {
271+ this . eventSocket = s ;
272+ if ( this . socketEventQueue ) {
273+ // flush queue.
274+ for ( const event of this . socketEventQueue ) {
275+ this . writeToEventSocket ( event . body , event . eventName ) ;
276+ }
277+ this . socketEventQueue = undefined ;
278+ }
279+ } ) ;
280+ }
281+
282+ public event < T > ( body : T , eventName : string ) : void {
283+ if ( ! this . eventSocket ) {
284+ if ( this . logger . hasLevel ( LogLevel . verbose ) ) {
285+ this . logger . info ( `eventPort: event "${ eventName } " queued, but socket not yet initialized` ) ;
286+ }
287+ ( this . socketEventQueue || ( this . socketEventQueue = [ ] ) ) . push ( { body, eventName } ) ;
288+ return ;
289+ }
290+ else {
291+ Debug . assert ( this . socketEventQueue === undefined ) ;
292+ this . writeToEventSocket ( body , eventName ) ;
293+ }
294+ }
295+
296+ private writeToEventSocket ( body : any , eventName : string ) : void {
297+ this . eventSocket . write ( formatMessage ( { seq : 0 , type : "event" , event : eventName , body : body } , this . logger , Buffer . byteLength , this . host . newLine ) , "utf8" ) ;
298+ }
299+ }
300+
256301 export interface SessionOptions {
257302 host : ServerHost ;
258303 cancellationToken : ServerCancellationToken ;
@@ -262,9 +307,13 @@ namespace ts.server {
262307 byteLength : ( buf : string , encoding ?: string ) => number ;
263308 hrtime : ( start ?: number [ ] ) => number [ ] ;
264309 logger : Logger ;
310+ /**
311+ * If falsy, all events are suppressed.
312+ */
265313 canUseEvents : boolean ;
266314 /**
267- * If defined, the Session will send events through `eventPort` instead of stdout.
315+ * If defined, specifies the socket to send events to the client.
316+ * Otherwise, events are sent through the host.
268317 */
269318 eventPort ?: number ;
270319 eventHandler ?: ProjectServiceEventHandler ;
@@ -276,6 +325,8 @@ namespace ts.server {
276325 }
277326
278327 export class Session implements EventSender {
328+ public readonly event : Event ;
329+
279330 private readonly gcTimer : GcTimer ;
280331 protected projectService : ProjectService ;
281332 private changeSeq = 0 ;
@@ -292,10 +343,7 @@ namespace ts.server {
292343
293344 private canUseEvents : boolean ;
294345 private eventPort : number | undefined ;
295- private eventSocket : NodeSocket ;
296346 private eventHandler : ProjectServiceEventHandler ;
297- public readonly event : EventSender [ "event" ] ;
298- private socketEventQueue : { info : any , eventName : string } [ ] | undefined ;
299347
300348 constructor ( opts : SessionOptions ) {
301349 this . host = opts . host ;
@@ -308,43 +356,18 @@ namespace ts.server {
308356 this . canUseEvents = opts . canUseEvents ;
309357
310358 const { throttleWaitMilliseconds } = opts ;
311-
312- if ( ! this . canUseEvents ) {
313- this . event = noop ;
314- }
315- else if ( this . eventPort ) {
316- const s = net . connect ( { port : this . eventPort } , ( ) => {
317- this . eventSocket = s ;
318- if ( this . socketEventQueue ) {
319- // flush queue.
320- for ( const event of this . socketEventQueue ) {
321- this . writeToEventSocket ( event . info , event . eventName ) ;
322- }
323- this . socketEventQueue = undefined ;
324- }
325- } ) ;
326-
327- this . event = function < T > ( info : T , eventName : string ) {
328- if ( ! this . eventSocket ) {
329- if ( this . logger . hasLevel ( LogLevel . verbose ) ) {
330- this . logger . info ( `eventPort: event queued, but socket not yet initialized` ) ;
331- }
332- ( this . socketEventQueue || ( this . socketEventQueue = [ ] ) ) . push ( { info, eventName } ) ;
333- return ;
334- }
335- else {
336- Debug . assert ( this . socketEventQueue === undefined ) ;
337- this . writeToEventSocket ( info , eventName ) ;
338- }
339- } ;
359+
360+ if ( this . eventPort && this . canUseEvents ) {
361+ const eventSender = new SocketEventSender ( this . host , this . logger , this . eventPort ) ;
362+ this . event = eventSender . event ;
340363 }
341364 else {
342- this . event = function < T > ( info : T , eventName : string ) {
365+ this . event = function < T > ( body : T , eventName : string ) : void {
343366 const ev : protocol . Event = {
344367 seq : 0 ,
345368 type : "event" ,
346369 event : eventName ,
347- body : info
370+ body
348371 } ;
349372 this . send ( ev ) ;
350373 } ;
@@ -380,10 +403,6 @@ namespace ts.server {
380403 this . gcTimer = new GcTimer ( this . host , /*delay*/ 7000 , this . logger ) ;
381404 }
382405
383- private writeToEventSocket ( info : any , eventName : string ) : void {
384- this . eventSocket . write ( formatMessage ( { seq : 0 , type : "event" , event : eventName , body : info } , this . logger , Buffer . byteLength , this . host . newLine ) , "utf8" ) ;
385- }
386-
387406 private sendRequestCompletedEvent ( requestId : number ) : void {
388407 this . event < protocol . RequestCompletedEventBody > ( { request_seq : requestId } , "requestCompleted" ) ;
389408 }
0 commit comments