1
- import { spawn } from 'child_process' ;
1
+ import { spawn } from 'child_process' ;
2
2
import path from 'path' ;
3
- import { fileURLToPath } from 'url' ;
3
+ import { fileURLToPath } from 'url' ;
4
4
5
5
/**
6
6
* Creates a new instance of TypeScript Server.
@@ -24,6 +24,7 @@ function createTSServerInstance() {
24
24
25
25
tsserverProcess . stdout . on ( 'data' , ( data ) => {
26
26
const lines = data . split ( '\n' ) ;
27
+ console . log ( lines ) ;
27
28
for ( const line of lines ) {
28
29
if ( line . trim ( ) . startsWith ( '{' ) ) {
29
30
const message = JSON . parse ( line . trim ( ) ) ;
@@ -50,22 +51,18 @@ function createTSServerInstance() {
50
51
} , 10000 ) ; // 10 seconds timeout
51
52
} ) ;
52
53
}
54
+
53
55
/**
54
56
* Handles incoming data from the TypeScript Server.
55
57
* @param {string } line - A line of data received from tsserver.
56
58
*/
57
59
function onData ( line ) {
58
60
try {
59
- console . log ( line ) ;
60
61
const response = JSON . parse ( line ) ;
61
- // Check if it's a command response and has a matching sequence number
62
62
if ( response . request_seq !== undefined && pendingCommands . has ( response . request_seq ) ) {
63
- const { resolve } = pendingCommands . get ( response . request_seq ) ;
63
+ const { resolve} = pendingCommands . get ( response . request_seq ) ;
64
64
pendingCommands . delete ( response . request_seq ) ;
65
65
resolve ( response ) ;
66
- } else if ( response . type === 'event' ) {
67
- // Handle or log event messages from tsserver
68
- console . log ( 'Event from tsserver:' , response ) ;
69
66
}
70
67
} catch ( e ) {
71
68
console . error ( 'Error parsing line from tsserver:' , e ) ;
@@ -74,32 +71,36 @@ function createTSServerInstance() {
74
71
75
72
/**
76
73
* Sends a command to the TypeScript Server.
74
+ * Special handling for 'open' command as it does not receive a response.
77
75
* @param {Object } command - The command object to send.
78
76
* @param {number } [timeout=5000] - The timeout in milliseconds for the command.
79
77
* @returns {Promise<Object> } A promise that resolves with the response from tsserver.
80
78
*/
81
79
function sendCommand ( command , timeout = 5000 ) {
80
+ if ( command . command === "open" ) {
81
+ // For 'open' command, resolve immediately as no response is expected
82
+ tsserverProcess . stdin . write ( `${ JSON . stringify ( command ) } \n` ) ;
83
+ return Promise . resolve ( ) ;
84
+ }
82
85
return new Promise ( ( resolve , reject ) => {
83
86
if ( ! tsserverProcess ) {
84
87
reject ( new Error ( 'tsserver is not initialized' ) ) ;
85
88
return ;
86
89
}
87
90
88
- const seq = ++ seqNumber ;
89
- pendingCommands . set ( seq , { resolve, reject } ) ;
91
+ command . seq = ++ seqNumber ;
92
+ command . type = 'request' ;
93
+ pendingCommands . set ( command . seq , { resolve, reject} ) ;
90
94
91
95
const timeoutId = setTimeout ( ( ) => {
92
- if ( pendingCommands . has ( seq ) ) {
93
- pendingCommands . delete ( seq ) ;
96
+ if ( pendingCommands . has ( command . seq ) ) {
97
+ pendingCommands . delete ( command . seq ) ;
94
98
reject ( new Error ( 'tsserver response timeout' ) ) ;
95
99
}
96
100
} , timeout ) ;
97
101
98
- command . seq = seq ;
99
- command . type = 'request' ;
100
- console . log ( command ) ;
101
-
102
102
if ( tsserverProcess . stdin . writable ) {
103
+ console . log ( command ) ;
103
104
tsserverProcess . stdin . write ( `${ JSON . stringify ( command ) } \n` ) ;
104
105
} else {
105
106
clearTimeout ( timeoutId ) ;
@@ -114,14 +115,53 @@ function createTSServerInstance() {
114
115
* @param {number } timeout - The timeout in milliseconds for the command.
115
116
* @returns {Promise<Object> } A promise that resolves with the response from tsserver.
116
117
*/
117
- function openFile ( filePath , timeout ) {
118
+ function openFile ( filePath , timeout = 5000 ) {
118
119
const command = {
119
120
command : 'open' ,
120
- arguments : { file : filePath }
121
+ arguments : { file : filePath }
121
122
} ;
122
123
return sendCommand ( command , timeout ) ;
123
124
}
124
125
126
+ /**
127
+ * Sends a 'definition' request to the TypeScript Server.
128
+ * @param {string } filePath - The path to the file.
129
+ * @param {number } line - The line number of the position.
130
+ * @param {number } offset - The offset in the line of the position.
131
+ * @returns {Promise<Object> } A promise that resolves with the response from tsserver.
132
+ */
133
+ function getDefinition ( filePath , line , offset ) {
134
+ const command = {
135
+ command : "definition" ,
136
+ arguments : {
137
+ file : filePath ,
138
+ line : line ,
139
+ offset : offset
140
+ }
141
+ } ;
142
+ return sendCommand ( command ) ;
143
+ }
144
+
145
+
146
+ /**
147
+ * Sends a 'references' request to the TypeScript Server.
148
+ * @param {string } filePath - The path to the file.
149
+ * @param {number } line - The line number of the position.
150
+ * @param {number } offset - The offset in the line of the position.
151
+ * @returns {Promise<Object> } A promise that resolves with the response from tsserver.
152
+ */
153
+ function findReferences ( filePath , line , offset ) {
154
+ const command = {
155
+ command : "references" ,
156
+ arguments : {
157
+ file : filePath ,
158
+ line : line ,
159
+ offset : offset
160
+ }
161
+ } ;
162
+ return sendCommand ( command ) ;
163
+ }
164
+
125
165
/**
126
166
* Kills the TypeScript Server process.
127
167
*/
@@ -133,7 +173,13 @@ function createTSServerInstance() {
133
173
}
134
174
}
135
175
136
- return { init : initTSServer , openFile, killServer : killTSServer } ;
176
+ return {
177
+ init : initTSServer ,
178
+ openFile,
179
+ killServer : killTSServer ,
180
+ getDefinition : getDefinition ,
181
+ findReferences : findReferences
182
+ } ;
137
183
}
138
184
139
185
export default createTSServerInstance ;
0 commit comments