@@ -10,18 +10,23 @@ import { getQuickInfoAtPosition } from './requests/getQuickInfoAtPosition';
1010import type { RequestContext } from './requests/types' ;
1111import { getServerPath } from './utils' ;
1212
13- export type RequestType = 'containsFile'
13+ export type RequestType =
14+ 'containsFile'
1415 | 'projectInfo'
1516 | 'collectExtractProps'
1617 | 'getImportPathForFile'
1718 | 'getPropertiesAtLocation'
1819 | 'getQuickInfoAtPosition'
1920 // Component Infos
20- | 'getComponentProps '
21+ | 'subscribeComponentProps '
2122 | 'getComponentEvents'
2223 | 'getTemplateContextProps'
2324 | 'getElementAttrs' ;
2425
26+ export type NotificationType =
27+ 'componentNamesUpdated'
28+ | 'componentPropsUpdated' ;
29+
2530export type RequestData = [
2631 seq : number ,
2732 type : RequestType ,
@@ -35,7 +40,7 @@ export type ResponseData = [
3540] ;
3641
3742export type NotificationData = [
38- type : 'componentAndPropsUpdated' ,
43+ type : NotificationType ,
3944 fileName : string ,
4045 data : any ,
4146] ;
@@ -63,7 +68,20 @@ export async function startNamedPipeServer(
6368 getFileId : ( fileName : string ) => fileName ,
6469 } ;
6570 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+ > ( ) ;
6785 const allConnections = new Set < net . Socket > ( ) ;
6886 const pendingRequests = new Set < number > ( ) ;
6987 const server = net . createServer ( connection => {
@@ -93,8 +111,12 @@ export async function startNamedPipeServer(
93111 } ) ;
94112 connection . on ( 'error' , err => console . error ( '[Vue Named Pipe Server]' , err . message ) ) ;
95113
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+ }
98120 }
99121 } ) ;
100122
@@ -137,37 +159,34 @@ export async function startNamedPipeServer(
137159 if ( token ?. isCancellationRequested ( ) ) {
138160 break ;
139161 }
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 ) ) {
149180 await sleep ( 10 ) ;
150181 if ( token ?. isCancellationRequested ( ) ) {
151- newData = undefined ;
152182 break ;
153183 }
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+ }
171190 }
172191 }
173192 }
@@ -200,7 +219,9 @@ export async function startNamedPipeServer(
200219 connection . write ( JSON . stringify ( [ seq , data ?? null ] ) + '\n\n' ) ;
201220 }
202221
203- function handleRequest ( requestType : RequestType , ...args : any [ ] ) {
222+ function handleRequest ( requestType : RequestType , ...args : [ fileName : string , ...any [ ] ] ) {
223+ const fileName = args [ 0 ] ;
224+
204225 if ( requestType === 'projectInfo' ) {
205226 return {
206227 name : info . project . getProjectName ( ) ,
@@ -209,7 +230,7 @@ export async function startNamedPipeServer(
209230 } satisfies ProjectInfo ;
210231 }
211232 else if ( requestType === 'containsFile' ) {
212- return info . project . containsFile ( ts . server . toNormalizedPath ( args [ 0 ] ) ) ;
233+ return info . project . containsFile ( ts . server . toNormalizedPath ( fileName ) ) ;
213234 }
214235 else if ( requestType === 'collectExtractProps' ) {
215236 return collectExtractProps . apply ( requestContext , args as any ) ;
@@ -223,8 +244,16 @@ export async function startNamedPipeServer(
223244 else if ( requestType === 'getQuickInfoAtPosition' ) {
224245 return getQuickInfoAtPosition . apply ( requestContext , args as any ) ;
225246 }
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 ;
228257 }
229258 else if ( requestType === 'getComponentEvents' ) {
230259 return getComponentEvents . apply ( requestContext , args as any ) ;
0 commit comments