diff --git a/src/server/server.ts b/src/server/server.ts index 2fa84e04dcb..68909227ac8 100644 --- a/src/server/server.ts +++ b/src/server/server.ts @@ -6,6 +6,10 @@ namespace ts.server { host: ServerHost; cancellationToken: ServerCancellationToken; canUseEvents: boolean; + /** + * If defined, specifies the socket used to send events to the client. + * Otherwise, events are sent through the host. + */ eventPort?: number; useSingleInferredProject: boolean; useInferredProjectPerProjectRoot: boolean; @@ -31,6 +35,14 @@ namespace ts.server { tmpdir(): string; } = require("os"); + interface NodeSocket { + write(data: string, encoding: string): boolean; + } + + const net: { + connect(options: { port: number }, onConnect?: () => void): NodeSocket + } = require("net"); + function getGlobalTypingsCacheLocation() { switch (process.platform) { case "win32": { @@ -507,6 +519,49 @@ namespace ts.server { } } + class SocketEventSender implements EventSender { + private host: ServerHost; + private logger: Logger; + private eventPort: number; + private eventSocket: NodeSocket | undefined; + private socketEventQueue: { body: any, eventName: string }[] | undefined; + + constructor(host: ServerHost, logger: Logger, eventPort: number) { + this.host = host; + this.logger = logger; + this.eventPort = eventPort; + + const s = net.connect({ port: this.eventPort }, () => { + this.eventSocket = s; + if (this.socketEventQueue) { + // flush queue. + for (const event of this.socketEventQueue) { + this.writeToEventSocket(event.body, event.eventName); + } + this.socketEventQueue = undefined; + } + }); + } + + public event = (body: T, eventName: string) => { + if (!this.eventSocket) { + if (this.logger.hasLevel(LogLevel.verbose)) { + this.logger.info(`eventPort: event "${eventName}" queued, but socket not yet initialized`); + } + (this.socketEventQueue || (this.socketEventQueue = [])).push({ body, eventName }); + return; + } + else { + Debug.assert(this.socketEventQueue === undefined); + this.writeToEventSocket(body, eventName); + } + } + + private writeToEventSocket(body: any, eventName: string): void { + this.eventSocket.write(formatMessage({ seq: 0, type: "event", event: eventName, body }, this.logger, Buffer.byteLength, this.host.newLine), "utf8"); + } + } + class IOSession extends Session { constructor(options: IoSessionOptions) { const { host, eventPort, globalTypingsCacheLocation, typingSafeListLocation, typesMapLocation, npmLocation, canUseEvents } = options; @@ -531,7 +586,6 @@ namespace ts.server { hrtime: process.hrtime, logger, canUseEvents, - eventPort, event, globalPlugins: options.globalPlugins, pluginProbeLocations: options.pluginProbeLocations, diff --git a/src/server/session.ts b/src/server/session.ts index 5912536f4f3..73575672bec 100644 --- a/src/server/session.ts +++ b/src/server/session.ts @@ -1,19 +1,9 @@ -/// /// /// /// /// namespace ts.server { - - interface NodeSocket { - write(data: string, encoding: string): boolean; - } - - const net: { - connect(options: { port: number }, onConnect?: () => void): NodeSocket - } = require("net"); - interface StackTraceError extends Error { stack?: string; } @@ -255,50 +245,6 @@ namespace ts.server { event: Event; } - /** @internal */ - export class SocketEventSender implements EventSender { - private host: ServerHost; - private logger: Logger; - private eventPort: number; - private eventSocket: NodeSocket | undefined; - private socketEventQueue: { body: any, eventName: string }[] | undefined; - - constructor(host: ServerHost, logger: Logger, eventPort: number) { - this.host = host; - this.logger = logger; - this.eventPort = eventPort; - - const s = net.connect({ port: this.eventPort }, () => { - this.eventSocket = s; - if (this.socketEventQueue) { - // flush queue. - for (const event of this.socketEventQueue) { - this.writeToEventSocket(event.body, event.eventName); - } - this.socketEventQueue = undefined; - } - }); - } - - public event = (body: T, eventName: string) => { - if (!this.eventSocket) { - if (this.logger.hasLevel(LogLevel.verbose)) { - this.logger.info(`eventPort: event "${eventName}" queued, but socket not yet initialized`); - } - (this.socketEventQueue || (this.socketEventQueue = [])).push({ body, eventName }); - return; - } - else { - Debug.assert(this.socketEventQueue === undefined); - this.writeToEventSocket(body, eventName); - } - } - - private writeToEventSocket(body: any, eventName: string): void { - this.eventSocket.write(formatMessage({ seq: 0, type: "event", event: eventName, body }, this.logger, Buffer.byteLength, this.host.newLine), "utf8"); - } - } - export interface SessionOptions { host: ServerHost; cancellationToken: ServerCancellationToken; @@ -312,11 +258,6 @@ namespace ts.server { * If falsy, all events are suppressed. */ canUseEvents: boolean; - /** - * If defined, specifies the socket to send events to the client. - * Otherwise, events are sent through the host. - */ - eventPort?: number; /** * An optional callback overriding the default behavior for sending events. * if set, `canUseEvents` and `eventPort` are ignored. @@ -348,7 +289,6 @@ namespace ts.server { protected logger: Logger; private canUseEvents: boolean; - private eventPort: number | undefined; private eventHandler: ProjectServiceEventHandler; constructor(opts: SessionOptions) { @@ -358,7 +298,6 @@ namespace ts.server { this.byteLength = opts.byteLength; this.hrtime = opts.hrtime; this.logger = opts.logger; - this.eventPort = opts.eventPort; this.canUseEvents = opts.canUseEvents || !!opts.event; const { throttleWaitMilliseconds } = opts; @@ -366,10 +305,6 @@ namespace ts.server { if (opts.event) { this.event = opts.event; } - else if (this.eventPort && this.canUseEvents) { - const eventSender = new SocketEventSender(this.host, this.logger, this.eventPort); - this.event = eventSender.event; - } else { this.event = function (body: T, eventName: string): void { const ev: protocol.Event = {