@@ -10,18 +10,23 @@ import { getQuickInfoAtPosition } from './requests/getQuickInfoAtPosition';
10
10
import type { RequestContext } from './requests/types' ;
11
11
import { getServerPath } from './utils' ;
12
12
13
- export type RequestType = 'containsFile'
13
+ export type RequestType =
14
+ 'containsFile'
14
15
| 'projectInfo'
15
16
| 'collectExtractProps'
16
17
| 'getImportPathForFile'
17
18
| 'getPropertiesAtLocation'
18
19
| 'getQuickInfoAtPosition'
19
20
// Component Infos
20
- | 'getComponentProps '
21
+ | 'subscribeComponentProps '
21
22
| 'getComponentEvents'
22
23
| 'getTemplateContextProps'
23
24
| 'getElementAttrs' ;
24
25
26
+ export type NotificationType =
27
+ 'componentNamesUpdated'
28
+ | 'componentPropsUpdated' ;
29
+
25
30
export type RequestData = [
26
31
seq : number ,
27
32
type : RequestType ,
@@ -35,7 +40,7 @@ export type ResponseData = [
35
40
] ;
36
41
37
42
export type NotificationData = [
38
- type : 'componentAndPropsUpdated' ,
43
+ type : NotificationType ,
39
44
fileName : string ,
40
45
data : any ,
41
46
] ;
@@ -63,7 +68,20 @@ export async function startNamedPipeServer(
63
68
getFileId : ( fileName : string ) => fileName ,
64
69
} ;
65
70
const dataChunks : Buffer [ ] = [ ] ;
66
- const componentNamesAndProps = new Map < string , string > ( ) ;
71
+ const currentData = new Map <
72
+ string ,
73
+ [
74
+ componentNames : string [ ] ,
75
+ Record <
76
+ string ,
77
+ {
78
+ name : string ;
79
+ required ?: true ;
80
+ commentMarkdown ?: string ;
81
+ } [ ]
82
+ > ,
83
+ ]
84
+ > ( ) ;
67
85
const allConnections = new Set < net . Socket > ( ) ;
68
86
const pendingRequests = new Set < number > ( ) ;
69
87
const server = net . createServer ( connection => {
@@ -93,8 +111,12 @@ export async function startNamedPipeServer(
93
111
} ) ;
94
112
connection . on ( 'error' , err => console . error ( '[Vue Named Pipe Server]' , err . message ) ) ;
95
113
96
- for ( const [ fileName , data ] of componentNamesAndProps ) {
97
- notify ( connection , 'componentAndPropsUpdated' , fileName , data ) ;
114
+ for ( const [ fileName , [ componentNames , componentProps ] ] of currentData ) {
115
+ notify ( connection , 'componentNamesUpdated' , fileName , Object . keys ( componentNames ) ) ;
116
+
117
+ for ( const [ name , props ] of Object . entries ( componentProps ) ) {
118
+ notify ( connection , 'componentPropsUpdated' , fileName , [ name , props ] ) ;
119
+ }
98
120
}
99
121
} ) ;
100
122
@@ -137,37 +159,34 @@ export async function startNamedPipeServer(
137
159
if ( token ?. isCancellationRequested ( ) ) {
138
160
break ;
139
161
}
140
- let newData : Record < string , {
141
- name : string ;
142
- required ?: true ;
143
- commentMarkdown ?: string ;
144
- } [ ] > | undefined = { } ;
145
- const componentNames = getComponentNames . apply ( requestContext , [ scriptInfo . fileName ] ) ;
146
- // const testProps = getComponentProps.apply(requestContext, [scriptInfo.fileName, 'HelloWorld']);
147
- // debugger;
148
- for ( const component of componentNames ?? [ ] ) {
162
+
163
+ let data = currentData . get ( scriptInfo . fileName ) ;
164
+ if ( ! data ) {
165
+ data = [ [ ] , { } ] ;
166
+ currentData . set ( scriptInfo . fileName , data ) ;
167
+ }
168
+
169
+ const [ oldComponentNames , componentProps ] = data ;
170
+ const newComponentNames = getComponentNames . apply ( requestContext , [ scriptInfo . fileName ] ) ?? [ ] ;
171
+
172
+ if ( JSON . stringify ( oldComponentNames ) !== JSON . stringify ( newComponentNames ) ) {
173
+ data [ 0 ] = newComponentNames ;
174
+ for ( const connection of connections ) {
175
+ notify ( connection , 'componentNamesUpdated' , scriptInfo . fileName , newComponentNames ) ;
176
+ }
177
+ }
178
+
179
+ for ( const [ name , props ] of Object . entries ( componentProps ) ) {
149
180
await sleep ( 10 ) ;
150
181
if ( token ?. isCancellationRequested ( ) ) {
151
- newData = undefined ;
152
182
break ;
153
183
}
154
- const props = getComponentProps . apply ( requestContext , [ scriptInfo . fileName , component ] ) ;
155
- if ( props ) {
156
- newData [ component ] = props ;
157
- }
158
- }
159
- if ( ! newData ) {
160
- // Canceled
161
- break ;
162
- }
163
- const oldDataJson = componentNamesAndProps . get ( scriptInfo . fileName ) ;
164
- const newDataJson = JSON . stringify ( newData ) ;
165
- if ( oldDataJson !== newDataJson ) {
166
- // Update cache
167
- componentNamesAndProps . set ( scriptInfo . fileName , newDataJson ) ;
168
- // Notify
169
- for ( const connection of connections ) {
170
- notify ( connection , 'componentAndPropsUpdated' , scriptInfo . fileName , newData ) ;
184
+ const newProps = getComponentProps . apply ( requestContext , [ scriptInfo . fileName , name ] ) ?? [ ] ;
185
+ if ( JSON . stringify ( props ) !== JSON . stringify ( newProps ) ) {
186
+ componentProps [ name ] = newProps ;
187
+ for ( const connection of connections ) {
188
+ notify ( connection , 'componentPropsUpdated' , scriptInfo . fileName , [ name , newProps ] ) ;
189
+ }
171
190
}
172
191
}
173
192
}
@@ -200,7 +219,9 @@ export async function startNamedPipeServer(
200
219
connection . write ( JSON . stringify ( [ seq , data ?? null ] ) + '\n\n' ) ;
201
220
}
202
221
203
- function handleRequest ( requestType : RequestType , ...args : any [ ] ) {
222
+ function handleRequest ( requestType : RequestType , ...args : [ fileName : string , ...any [ ] ] ) {
223
+ const fileName = args [ 0 ] ;
224
+
204
225
if ( requestType === 'projectInfo' ) {
205
226
return {
206
227
name : info . project . getProjectName ( ) ,
@@ -209,7 +230,7 @@ export async function startNamedPipeServer(
209
230
} satisfies ProjectInfo ;
210
231
}
211
232
else if ( requestType === 'containsFile' ) {
212
- return info . project . containsFile ( ts . server . toNormalizedPath ( args [ 0 ] ) ) ;
233
+ return info . project . containsFile ( ts . server . toNormalizedPath ( fileName ) ) ;
213
234
}
214
235
else if ( requestType === 'collectExtractProps' ) {
215
236
return collectExtractProps . apply ( requestContext , args as any ) ;
@@ -223,8 +244,16 @@ export async function startNamedPipeServer(
223
244
else if ( requestType === 'getQuickInfoAtPosition' ) {
224
245
return getQuickInfoAtPosition . apply ( requestContext , args as any ) ;
225
246
}
226
- else if ( requestType === 'getComponentProps' ) {
227
- return getComponentProps . apply ( requestContext , args as any ) ;
247
+ else if ( requestType === 'subscribeComponentProps' ) {
248
+ const tag = args [ 1 ] ;
249
+ const props = getComponentProps . apply ( requestContext , [ fileName , tag ] ) ?? [ ] ;
250
+ let data = currentData . get ( fileName ) ;
251
+ if ( ! data ) {
252
+ data = [ [ ] , { } ] ;
253
+ currentData . set ( fileName , data ) ;
254
+ }
255
+ data [ 1 ] [ tag ] = props ;
256
+ return props ;
228
257
}
229
258
else if ( requestType === 'getComponentEvents' ) {
230
259
return getComponentEvents . apply ( requestContext , args as any ) ;
0 commit comments