-
-
Notifications
You must be signed in to change notification settings - Fork 371
/
computedVueSfc.ts
52 lines (47 loc) · 1.26 KB
/
computedVueSfc.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
import type { SFCParseResult } from '@vue/compiler-sfc';
import { computed } from 'computeds';
import type * as ts from 'typescript';
import type { VueLanguagePlugin } from '../types';
export function computedVueSfc(
plugins: ReturnType<VueLanguagePlugin>[],
fileName: string,
snapshot: () => ts.IScriptSnapshot
) {
let cache: {
snapshot: ts.IScriptSnapshot,
sfc: SFCParseResult,
plugin: ReturnType<VueLanguagePlugin>,
} | undefined;
return computed(() => {
// incremental update
if (cache?.plugin.updateSFC) {
const change = snapshot().getChangeRange(cache.snapshot);
if (change) {
const newSfc = cache.plugin.updateSFC(cache.sfc, {
start: change.span.start,
end: change.span.start + change.span.length,
newText: snapshot().getText(change.span.start, change.span.start + change.newLength),
});
if (newSfc) {
cache.snapshot = snapshot();
// force dirty
cache.sfc = JSON.parse(JSON.stringify(newSfc));
return cache.sfc;
}
}
}
for (const plugin of plugins) {
const sfc = plugin.parseSFC?.(fileName, snapshot().getText(0, snapshot().getLength()));
if (sfc) {
if (!sfc.errors.length) {
cache = {
snapshot: snapshot(),
sfc,
plugin,
};
}
return sfc;
}
}
});
}