1
- import { field , logger } from "@coder/logger"
1
+ import { logger } from "@coder/logger"
2
2
import * as cp from "child_process"
3
3
import * as net from "net"
4
4
import * as path from "path"
@@ -8,19 +8,18 @@ import { rootPath } from "./constants"
8
8
import { settings } from "./settings"
9
9
import { SocketProxyProvider } from "./socket"
10
10
import { isFile } from "./util"
11
- import { ipcMain } from "./wrapper"
11
+ import { onMessage , wrapper } from "./wrapper"
12
12
13
13
export class VscodeProvider {
14
14
public readonly serverRootPath : string
15
15
public readonly vsRootPath : string
16
16
private _vscode ?: Promise < cp . ChildProcess >
17
- private timeoutInterval = 10000 // 10s, matches VS Code's timeouts.
18
17
private readonly socketProvider = new SocketProxyProvider ( )
19
18
20
19
public constructor ( ) {
21
20
this . vsRootPath = path . resolve ( rootPath , "lib/vscode" )
22
21
this . serverRootPath = path . join ( this . vsRootPath , "out/vs/server" )
23
- ipcMain . onDispose ( ( ) => this . dispose ( ) )
22
+ wrapper . onDispose ( ( ) => this . dispose ( ) )
24
23
}
25
24
26
25
public async dispose ( ) : Promise < void > {
@@ -69,10 +68,13 @@ export class VscodeProvider {
69
68
vscode ,
70
69
)
71
70
72
- const message = await this . onMessage ( vscode , ( message ) : message is ipc . OptionsMessage => {
73
- // There can be parallel initializations so wait for the right ID.
74
- return message . type === "options" && message . id === id
75
- } )
71
+ const message = await onMessage < ipc . VscodeMessage , ipc . OptionsMessage > (
72
+ vscode ,
73
+ ( message ) : message is ipc . OptionsMessage => {
74
+ // There can be parallel initializations so wait for the right ID.
75
+ return message . type === "options" && message . id === id
76
+ } ,
77
+ )
76
78
77
79
return message . options
78
80
}
@@ -104,61 +106,13 @@ export class VscodeProvider {
104
106
dispose ( )
105
107
} )
106
108
107
- this . _vscode = this . onMessage ( vscode , ( message ) : message is ipc . ReadyMessage => {
109
+ this . _vscode = onMessage < ipc . VscodeMessage , ipc . ReadyMessage > ( vscode , ( message ) : message is ipc . ReadyMessage => {
108
110
return message . type === "ready"
109
111
} ) . then ( ( ) => vscode )
110
112
111
113
return this . _vscode
112
114
}
113
115
114
- /**
115
- * Listen to a single message from a process. Reject if the process errors,
116
- * exits, or times out.
117
- *
118
- * `fn` is a function that determines whether the message is the one we're
119
- * waiting for.
120
- */
121
- private onMessage < T extends ipc . VscodeMessage > (
122
- proc : cp . ChildProcess ,
123
- fn : ( message : ipc . VscodeMessage ) => message is T ,
124
- ) : Promise < T > {
125
- return new Promise ( ( resolve , reject ) => {
126
- const cleanup = ( ) => {
127
- proc . off ( "error" , onError )
128
- proc . off ( "exit" , onExit )
129
- proc . off ( "message" , onMessage )
130
- clearTimeout ( timeout )
131
- }
132
-
133
- const timeout = setTimeout ( ( ) => {
134
- cleanup ( )
135
- reject ( new Error ( "timed out" ) )
136
- } , this . timeoutInterval )
137
-
138
- const onError = ( error : Error ) => {
139
- cleanup ( )
140
- reject ( error )
141
- }
142
-
143
- const onExit = ( code : number | null ) => {
144
- cleanup ( )
145
- reject ( new Error ( `VS Code exited unexpectedly with code ${ code } ` ) )
146
- }
147
-
148
- const onMessage = ( message : ipc . VscodeMessage ) => {
149
- logger . trace ( "got message from vscode" , field ( "message" , message ) )
150
- if ( fn ( message ) ) {
151
- cleanup ( )
152
- resolve ( message )
153
- }
154
- }
155
-
156
- proc . on ( "message" , onMessage )
157
- proc . on ( "error" , onError )
158
- proc . on ( "exit" , onExit )
159
- } )
160
- }
161
-
162
116
/**
163
117
* VS Code expects a raw socket. It will handle all the web socket frames.
164
118
*/
0 commit comments