@@ -15,51 +15,56 @@ export class Client {
15
15
listen ( ) {
16
16
this . server . stdout . on ( 'data' , ( data : Buffer ) => {
17
17
this . data = this . data ? Buffer . concat ( [ this . data , data ] ) : data ;
18
+ // tsserver could batch multiple responses together so we have to go
19
+ // through the entire buffer to keep looking for messages.
18
20
const CONTENT_LENGTH = 'Content-Length: '
19
- const index = this . data . indexOf ( CONTENT_LENGTH ) ;
20
- if ( index < 0 ) {
21
- return ;
22
- }
23
- let start = index + CONTENT_LENGTH . length ;
24
- let end = this . data . indexOf ( '\r\n' , start ) ;
25
- if ( end < start ) {
26
- return ;
27
- }
28
- const contentLengthStr = this . data . slice ( start , end ) . toString ( ) ;
29
- const contentLength = Number ( contentLengthStr ) ;
30
- if ( isNaN ( contentLength ) || contentLength < 0 ) {
31
- return ;
32
- }
33
- start = end + 4 ;
34
- end = start + contentLength ;
35
- if ( end > this . data . length ) {
36
- return ;
37
- }
38
- const content = this . data . slice ( start , end ) . toString ( ) ;
39
- this . data = this . data . slice ( end ) ;
40
- try {
41
- const payload = JSON . parse ( content ) ;
42
- if ( payload . type === "event" ) {
21
+ do {
22
+ const index = this . data . indexOf ( CONTENT_LENGTH ) ;
23
+ if ( index < 0 ) {
43
24
return ;
44
25
}
45
- this . responseEmitter . emit ( 'response' , payload ) ;
46
- }
47
- catch ( error ) {
48
- this . responseEmitter . emit ( 'error' , error ) ;
49
- }
26
+ let start = index + CONTENT_LENGTH . length ;
27
+ let end = this . data . indexOf ( '\r\n' , start ) ;
28
+ if ( end < start ) {
29
+ return ;
30
+ }
31
+ const contentLengthStr = this . data . slice ( start , end ) . toString ( ) ;
32
+ const contentLength = Number ( contentLengthStr ) ;
33
+ if ( isNaN ( contentLength ) || contentLength < 0 ) {
34
+ return ;
35
+ }
36
+ start = end + 4 ;
37
+ end = start + contentLength ;
38
+ if ( end > this . data . length ) {
39
+ return ;
40
+ }
41
+ const content = this . data . slice ( start , end ) . toString ( ) ;
42
+ this . data = this . data . slice ( end ) ;
43
+ try {
44
+ const payload = JSON . parse ( content ) ;
45
+ if ( payload . type === "response" ) {
46
+ const seq = `${ payload . request_seq } ` ;
47
+ this . responseEmitter . emit ( seq , payload ) ;
48
+ }
49
+ }
50
+ catch ( error ) {
51
+ this . responseEmitter . emit ( 'error' , error ) ;
52
+ }
53
+ } while ( this . data . length > 0 )
50
54
} ) ;
51
55
}
52
56
53
57
async send ( type : string , command : string , params : { } ) {
58
+ const seq = this . id ++ ;
54
59
const request = {
55
- seq : this . id ++ ,
60
+ seq,
56
61
type,
57
62
command,
58
63
arguments : params
59
64
} ;
60
65
this . server . stdin . write ( JSON . stringify ( request ) + '\r\n' ) ;
61
66
return new Promise ( ( resolve , reject ) => {
62
- this . responseEmitter . once ( 'response' , resolve ) ;
67
+ this . responseEmitter . once ( ` ${ seq } ` , resolve ) ;
63
68
this . responseEmitter . once ( 'error' , reject ) ;
64
69
} ) ;
65
70
}
0 commit comments