@@ -17,6 +17,7 @@ export type VueLanguagePlugin = (ctx: {
17
17
} ) => {
18
18
order ?: number ;
19
19
parseSFC ?( fileName : string , content : string ) : SFCParseResult | undefined ;
20
+ updateSFC ?( oldResult : SFCParseResult , textChange : { start : number , end : number , newText : string ; } ) : SFCParseResult | undefined ;
20
21
compileSFCTemplate ?( lang : string , template : string , options ?: CompilerDom . CompilerOptions ) : CompilerDom . CodegenResult | undefined ;
21
22
getEmbeddedFileNames ?( fileName : string , sfc : Sfc ) : string [ ] ;
22
23
resolveEmbeddedFile ?( fileName : string , sfc : Sfc , embeddedFile : EmbeddedFile ) : void ;
@@ -109,6 +110,13 @@ export function createSourceFile(
109
110
} ) as unknown as Sfc [ 'scriptSetupAst' ] ,
110
111
} ) as Sfc /* avoid Sfc unwrap in .d.ts by reactive */ ;
111
112
113
+ // cache
114
+ let parsedSfcCache : {
115
+ snapshot : ts . IScriptSnapshot ,
116
+ sfc : SFCParseResult ,
117
+ plugin : ReturnType < VueLanguagePlugin > ,
118
+ } | undefined ;
119
+
112
120
// use
113
121
const scriptAst = computed ( ( ) => {
114
122
if ( sfc . script ) {
@@ -121,9 +129,28 @@ export function createSourceFile(
121
129
}
122
130
} ) ;
123
131
const parsedSfc = computed ( ( ) => {
132
+
133
+ // incremental update
134
+ if ( parsedSfcCache ?. plugin . updateSFC ) {
135
+ const change = snapshot . value . getChangeRange ( parsedSfcCache . snapshot ) ;
136
+ if ( change ) {
137
+ const newSfc = parsedSfcCache . plugin . updateSFC ( parsedSfcCache . sfc , {
138
+ start : change . span . start ,
139
+ end : change . span . start + change . span . length ,
140
+ newText : snapshot . value . getText ( change . span . start , change . span . start + change . newLength ) ,
141
+ } ) ;
142
+ if ( newSfc ) {
143
+ parsedSfcCache . snapshot = snapshot . value ;
144
+ parsedSfcCache . sfc = newSfc ;
145
+ return newSfc ;
146
+ }
147
+ }
148
+ }
149
+
124
150
for ( const plugin of plugins ) {
125
151
const sfc = plugin . parseSFC ?.( fileName , fileContent . value ) ;
126
152
if ( sfc ) {
153
+ parsedSfcCache = { snapshot : snapshot . value , sfc, plugin } ;
127
154
return sfc ;
128
155
}
129
156
}
@@ -404,13 +431,8 @@ export function createSourceFile(
404
431
return ;
405
432
}
406
433
407
- const change = newScriptSnapshot . getChangeRange ( snapshot . value ) ;
408
434
snapshot . value = newScriptSnapshot ;
409
435
410
- if ( change ) {
411
- // TODO
412
- }
413
-
414
436
// TODO: wait for https://github.com/vuejs/core/pull/5912
415
437
if ( parsedSfc . value ) {
416
438
updateTemplate ( parsedSfc . value . descriptor . template ) ;
@@ -419,6 +441,13 @@ export function createSourceFile(
419
441
updateStyles ( parsedSfc . value . descriptor . styles ) ;
420
442
updateCustomBlocks ( parsedSfc . value . descriptor . customBlocks ) ;
421
443
}
444
+ else {
445
+ updateTemplate ( null ) ;
446
+ updateScript ( null ) ;
447
+ updateScriptSetup ( null ) ;
448
+ updateStyles ( [ ] ) ;
449
+ updateCustomBlocks ( [ ] ) ;
450
+ }
422
451
423
452
function updateTemplate ( block : SFCTemplateBlock | null ) {
424
453
0 commit comments