@eventra_dev/eventra-cli 0.1.34 → 0.2.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/commands/check.js +14 -30
- package/dist/commands/sync.js +9 -27
- package/dist/commands/watch.js +38 -121
- package/dist/engine/engine.js +14 -9
- package/dist/engine/languageService.js +29 -24
- package/dist/engine/scanner.js +41 -28
- package/dist/utils/processFile.js +17 -0
- package/dist/utils/universal.js +1 -1
- package/package.json +1 -1
- package/src/commands/check.ts +17 -48
- package/src/commands/sync.ts +14 -44
- package/src/commands/watch.ts +48 -158
- package/src/engine/engine.ts +20 -12
- package/src/engine/languageService.ts +35 -32
- package/src/engine/scanner.ts +67 -27
- package/src/utils/processFile.ts +19 -0
- package/src/utils/universal.ts +1 -1
package/dist/commands/check.js
CHANGED
|
@@ -24,9 +24,9 @@ async function check({ fix = false }) {
|
|
|
24
24
|
absolute: true,
|
|
25
25
|
});
|
|
26
26
|
const engine = new engine_1.EventraEngine(process.cwd());
|
|
27
|
-
const toScan = new Set();
|
|
28
27
|
const cache = new Map();
|
|
29
|
-
|
|
28
|
+
const toScan = new Set();
|
|
29
|
+
// COLLECT
|
|
30
30
|
for (const file of files) {
|
|
31
31
|
try {
|
|
32
32
|
const raw = await promises_1.default.readFile(file, "utf-8");
|
|
@@ -35,23 +35,17 @@ async function check({ fix = false }) {
|
|
|
35
35
|
const parsed = (0, processFile_1.processFile)(file, raw);
|
|
36
36
|
cache.set(file, parsed);
|
|
37
37
|
toScan.add(file);
|
|
38
|
-
|
|
39
|
-
toScan.add(path_1.default.resolve(dep));
|
|
40
|
-
}
|
|
38
|
+
parsed.deps.forEach(dep => toScan.add(path_1.default.resolve(dep)));
|
|
41
39
|
}
|
|
42
40
|
catch { }
|
|
43
41
|
}
|
|
44
42
|
// PRELOAD
|
|
45
43
|
for (const file of toScan) {
|
|
46
44
|
try {
|
|
47
|
-
|
|
48
|
-
if (!parsed)
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
cache.set(file, parsed);
|
|
52
|
-
}
|
|
53
|
-
const virtual = (0, getVirtualFile_1.getVirtualFile)(file);
|
|
54
|
-
engine.preloadFile(virtual, parsed.content);
|
|
45
|
+
const parsed = cache.get(file);
|
|
46
|
+
if (!parsed)
|
|
47
|
+
continue;
|
|
48
|
+
engine.preloadFile((0, getVirtualFile_1.getVirtualFile)(file), parsed.content);
|
|
55
49
|
}
|
|
56
50
|
catch { }
|
|
57
51
|
}
|
|
@@ -61,34 +55,24 @@ async function check({ fix = false }) {
|
|
|
61
55
|
const parsed = cache.get(file);
|
|
62
56
|
if (!parsed)
|
|
63
57
|
continue;
|
|
64
|
-
|
|
65
|
-
engine.scanFile(virtual, parsed.content, config);
|
|
58
|
+
engine.scanFile((0, getVirtualFile_1.getVirtualFile)(file), parsed.content, config);
|
|
66
59
|
}
|
|
67
60
|
catch { }
|
|
68
61
|
}
|
|
69
|
-
// DIFF
|
|
70
62
|
const found = new Set(engine.getAllEvents());
|
|
71
63
|
const known = new Set(config.events ?? []);
|
|
72
|
-
const
|
|
64
|
+
const added = [...found].filter(e => !known.has(e));
|
|
73
65
|
const removed = [...known].filter(e => !found.has(e));
|
|
74
|
-
// FIX MODE
|
|
75
66
|
if (fix) {
|
|
76
67
|
config.events = [...found].sort();
|
|
77
68
|
await (0, config_1.saveConfig)(config);
|
|
78
|
-
console.log(chalk_1.default.green(
|
|
69
|
+
console.log(chalk_1.default.green("Synced"));
|
|
79
70
|
return;
|
|
80
71
|
}
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
console.log(chalk_1.default.red("\nNew events:"));
|
|
85
|
-
newEvents.forEach(e => console.log(chalk_1.default.red(`+ ${e}`)));
|
|
86
|
-
}
|
|
87
|
-
if (removed.length) {
|
|
88
|
-
console.log(chalk_1.default.yellow("\nRemoved events:"));
|
|
89
|
-
removed.forEach(e => console.log(chalk_1.default.yellow(`- ${e}`)));
|
|
90
|
-
}
|
|
72
|
+
if (added.length || removed.length) {
|
|
73
|
+
added.forEach(e => console.log(chalk_1.default.red(`+ ${e}`)));
|
|
74
|
+
removed.forEach(e => console.log(chalk_1.default.yellow(`- ${e}`)));
|
|
91
75
|
process.exit(1);
|
|
92
76
|
}
|
|
93
|
-
console.log(chalk_1.default.green("
|
|
77
|
+
console.log(chalk_1.default.green("All good"));
|
|
94
78
|
}
|
package/dist/commands/sync.js
CHANGED
|
@@ -21,14 +21,10 @@ async function sync() {
|
|
|
21
21
|
ignore: config.sync.exclude,
|
|
22
22
|
absolute: true,
|
|
23
23
|
});
|
|
24
|
-
if (!files.length) {
|
|
25
|
-
console.log(chalk_1.default.yellow("No files found"));
|
|
26
|
-
return;
|
|
27
|
-
}
|
|
28
24
|
const engine = new engine_1.EventraEngine(process.cwd());
|
|
29
|
-
const toScan = new Set();
|
|
30
25
|
const cache = new Map();
|
|
31
|
-
|
|
26
|
+
const toScan = new Set();
|
|
27
|
+
// COLLECT
|
|
32
28
|
for (const file of files) {
|
|
33
29
|
try {
|
|
34
30
|
const raw = await promises_1.default.readFile(file, "utf-8");
|
|
@@ -37,9 +33,7 @@ async function sync() {
|
|
|
37
33
|
const parsed = (0, processFile_1.processFile)(file, raw);
|
|
38
34
|
cache.set(file, parsed);
|
|
39
35
|
toScan.add(file);
|
|
40
|
-
|
|
41
|
-
toScan.add(path_1.default.resolve(dep));
|
|
42
|
-
}
|
|
36
|
+
parsed.deps.forEach(dep => toScan.add(path_1.default.resolve(dep)));
|
|
43
37
|
}
|
|
44
38
|
catch { }
|
|
45
39
|
}
|
|
@@ -52,8 +46,7 @@ async function sync() {
|
|
|
52
46
|
parsed = (0, processFile_1.processFile)(file, raw);
|
|
53
47
|
cache.set(file, parsed);
|
|
54
48
|
}
|
|
55
|
-
|
|
56
|
-
engine.preloadFile(virtual, parsed.content);
|
|
49
|
+
engine.preloadFile((0, getVirtualFile_1.getVirtualFile)(file), parsed.content);
|
|
57
50
|
}
|
|
58
51
|
catch { }
|
|
59
52
|
}
|
|
@@ -65,33 +58,22 @@ async function sync() {
|
|
|
65
58
|
const parsed = cache.get(file);
|
|
66
59
|
if (!parsed)
|
|
67
60
|
continue;
|
|
68
|
-
const
|
|
69
|
-
const res = engine.scanFile(virtual, parsed.content, config);
|
|
61
|
+
const res = engine.updateFile((0, getVirtualFile_1.getVirtualFile)(file), parsed.content, config);
|
|
70
62
|
res.detectedFunctionWrappers.forEach(w => detectedFn.add(w));
|
|
71
|
-
|
|
72
|
-
detectedCmp.set(k, v);
|
|
73
|
-
}
|
|
74
|
-
}
|
|
75
|
-
catch {
|
|
76
|
-
console.log(chalk_1.default.gray(`skip: ${file}`));
|
|
63
|
+
res.detectedComponentWrappers.forEach((v, k) => detectedCmp.set(k, v));
|
|
77
64
|
}
|
|
65
|
+
catch { }
|
|
78
66
|
}
|
|
79
67
|
// RESULT
|
|
80
68
|
const events = engine.getAllEvents().sort();
|
|
81
69
|
config.events = events;
|
|
82
70
|
config.functionWrappers = mergeUnique(config.functionWrappers ?? [], [...detectedFn].map(name => ({ name })), w => w.name);
|
|
83
|
-
config.wrappers = mergeUnique(config.wrappers ?? [], [...detectedCmp.entries()].map(([name, prop]) => ({
|
|
84
|
-
name,
|
|
85
|
-
prop,
|
|
86
|
-
})), w => `${w.name}:${w.prop}`);
|
|
71
|
+
config.wrappers = mergeUnique(config.wrappers ?? [], [...detectedCmp.entries()].map(([name, prop]) => ({ name, prop })), w => `${w.name}:${w.prop}`);
|
|
87
72
|
await (0, config_1.saveConfig)(config);
|
|
88
73
|
console.log(chalk_1.default.green(`Found ${events.length} events`));
|
|
89
74
|
}
|
|
90
|
-
// HELPERS
|
|
91
75
|
function mergeUnique(a, b, key) {
|
|
92
76
|
const map = new Map();
|
|
93
|
-
[...b, ...a].forEach(item =>
|
|
94
|
-
map.set(key(item), item);
|
|
95
|
-
});
|
|
77
|
+
[...b, ...a].forEach(item => map.set(key(item), item));
|
|
96
78
|
return [...map.values()];
|
|
97
79
|
}
|
package/dist/commands/watch.js
CHANGED
|
@@ -13,180 +13,97 @@ const config_1 = require("../utils/config");
|
|
|
13
13
|
const engine_1 = require("../engine/engine");
|
|
14
14
|
const processFile_1 = require("../utils/processFile");
|
|
15
15
|
const getVirtualFile_1 = require("../utils/getVirtualFile");
|
|
16
|
-
function normalize(file) {
|
|
17
|
-
return path_1.default.resolve(file).replace(/\\/g, "/");
|
|
18
|
-
}
|
|
19
16
|
async function watch() {
|
|
20
17
|
const config = await (0, config_1.loadConfig)();
|
|
21
18
|
if (!config)
|
|
22
19
|
return;
|
|
23
20
|
console.log(chalk_1.default.blue("Watching...\n"));
|
|
21
|
+
const engine = new engine_1.EventraEngine(process.cwd());
|
|
22
|
+
const fileDeps = new Map();
|
|
23
|
+
const cache = new Map();
|
|
24
|
+
const watchedDeps = new Set();
|
|
25
|
+
const normalize = (f) => path_1.default.resolve(f).replace(/\\/g, "/");
|
|
26
|
+
// INITIAL LOAD
|
|
24
27
|
const files = await (0, fast_glob_1.default)(config.sync.include, {
|
|
25
28
|
ignore: config.sync.exclude,
|
|
26
29
|
absolute: true,
|
|
27
30
|
});
|
|
28
|
-
const engine = new engine_1.EventraEngine(process.cwd());
|
|
29
|
-
const watchedDeps = new Set();
|
|
30
|
-
const cache = new Map();
|
|
31
|
-
const toScan = new Set();
|
|
32
|
-
// COLLECT + CACHE
|
|
33
31
|
for (const file of files) {
|
|
34
32
|
try {
|
|
35
33
|
const abs = normalize(file);
|
|
36
34
|
const raw = await promises_1.default.readFile(abs, "utf-8");
|
|
37
|
-
if (raw.length > 2_000_000)
|
|
38
|
-
continue;
|
|
39
35
|
const parsed = (0, processFile_1.processFile)(abs, raw);
|
|
40
36
|
cache.set(abs, parsed);
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
}
|
|
45
|
-
}
|
|
46
|
-
catch {
|
|
47
|
-
console.log(chalk_1.default.gray(`skip: ${file}`));
|
|
48
|
-
}
|
|
49
|
-
}
|
|
50
|
-
// PRELOAD
|
|
51
|
-
for (const file of toScan) {
|
|
52
|
-
try {
|
|
53
|
-
let parsed = cache.get(file);
|
|
54
|
-
if (!parsed) {
|
|
55
|
-
const raw = await promises_1.default.readFile(file, "utf-8");
|
|
56
|
-
parsed = (0, processFile_1.processFile)(file, raw);
|
|
57
|
-
cache.set(file, parsed);
|
|
58
|
-
}
|
|
59
|
-
const virtual = (0, getVirtualFile_1.getVirtualFile)(file);
|
|
60
|
-
engine.preloadFile?.(virtual, parsed.content);
|
|
61
|
-
}
|
|
62
|
-
catch { }
|
|
63
|
-
}
|
|
64
|
-
// INITIAL SCAN
|
|
65
|
-
for (const file of toScan) {
|
|
66
|
-
try {
|
|
67
|
-
let parsed = cache.get(file);
|
|
68
|
-
if (!parsed) {
|
|
69
|
-
const raw = await promises_1.default.readFile(file, "utf-8");
|
|
70
|
-
parsed = (0, processFile_1.processFile)(file, raw);
|
|
71
|
-
}
|
|
72
|
-
const virtual = (0, getVirtualFile_1.getVirtualFile)(file);
|
|
73
|
-
engine.scanFile(virtual, parsed.content, config);
|
|
74
|
-
for (const dep of parsed.deps) {
|
|
75
|
-
watchedDeps.add(normalize(dep));
|
|
76
|
-
}
|
|
37
|
+
engine.preloadFile((0, getVirtualFile_1.getVirtualFile)(abs), parsed.content);
|
|
38
|
+
engine.updateFile((0, getVirtualFile_1.getVirtualFile)(abs), parsed.content, config);
|
|
39
|
+
fileDeps.set(abs, new Set(parsed.deps.map(d => normalize(d))));
|
|
77
40
|
}
|
|
78
41
|
catch { }
|
|
79
42
|
}
|
|
80
43
|
config.events = engine.getAllEvents().sort();
|
|
81
44
|
await (0, config_1.saveConfig)(config);
|
|
82
|
-
console.log(chalk_1.default.gray(`Initial: ${config.events.length}
|
|
83
|
-
//
|
|
84
|
-
|
|
85
|
-
const
|
|
45
|
+
console.log(chalk_1.default.gray(`Initial: ${config.events.length}\n`));
|
|
46
|
+
// WATCHER
|
|
47
|
+
const watcher = chokidar_1.default.watch([...files.map(normalize), ...watchedDeps], { ignoreInitial: true });
|
|
48
|
+
const queue = new Map();
|
|
86
49
|
let timer = null;
|
|
87
50
|
const run = async () => {
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
const batch = [...queued.values()];
|
|
92
|
-
queued.clear();
|
|
93
|
-
for (const item of batch) {
|
|
51
|
+
const batch = [...queue.keys()];
|
|
52
|
+
queue.clear();
|
|
53
|
+
for (const file of batch) {
|
|
94
54
|
try {
|
|
95
|
-
const raw = await promises_1.default.readFile(
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
const nextDeps = new Set();
|
|
103
|
-
for (const dep of parsed.deps) {
|
|
104
|
-
nextDeps.add(normalize(dep));
|
|
105
|
-
}
|
|
55
|
+
const raw = await promises_1.default.readFile(file, "utf-8");
|
|
56
|
+
const parsed = (0, processFile_1.processFile)(file, raw);
|
|
57
|
+
cache.set(file, parsed);
|
|
58
|
+
engine.updateFile((0, getVirtualFile_1.getVirtualFile)(file), parsed.content, config);
|
|
59
|
+
//dependency diff
|
|
60
|
+
const abs = normalize(file);
|
|
61
|
+
const prevDeps = fileDeps.get(abs) ?? new Set();
|
|
62
|
+
const nextDeps = new Set(parsed.deps.map(d => normalize(d)));
|
|
106
63
|
// add new deps
|
|
107
64
|
for (const dep of nextDeps) {
|
|
108
|
-
if (!
|
|
65
|
+
if (!prevDeps.has(dep)) {
|
|
109
66
|
watcher.add(dep);
|
|
110
67
|
watchedDeps.add(dep);
|
|
111
68
|
}
|
|
112
69
|
}
|
|
113
70
|
// remove old deps
|
|
114
|
-
for (const dep of
|
|
71
|
+
for (const dep of prevDeps) {
|
|
115
72
|
if (!nextDeps.has(dep)) {
|
|
116
73
|
watcher.unwatch(dep);
|
|
117
74
|
watchedDeps.delete(dep);
|
|
118
75
|
}
|
|
119
76
|
}
|
|
120
|
-
|
|
121
|
-
for (const dep of nextDeps) {
|
|
122
|
-
try {
|
|
123
|
-
const raw = await promises_1.default.readFile(dep, "utf-8");
|
|
124
|
-
const parsedDep = (0, processFile_1.processFile)(dep, raw);
|
|
125
|
-
cache.set(dep, parsedDep);
|
|
126
|
-
const virtual = (0, getVirtualFile_1.getVirtualFile)(dep);
|
|
127
|
-
engine.updateFile(virtual, parsedDep.content, config);
|
|
128
|
-
}
|
|
129
|
-
catch { }
|
|
130
|
-
}
|
|
77
|
+
fileDeps.set(abs, nextDeps);
|
|
131
78
|
}
|
|
132
79
|
catch {
|
|
133
|
-
console.log(chalk_1.default.gray(`skip: ${
|
|
80
|
+
console.log(chalk_1.default.gray(`skip: ${file}`));
|
|
134
81
|
}
|
|
135
82
|
}
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
if (added.length || removed.length) {
|
|
141
|
-
added.forEach(e => console.log(chalk_1.default.green(`+ ${e}`)));
|
|
142
|
-
removed.forEach(e => console.log(chalk_1.default.red(`- ${e}`)));
|
|
143
|
-
config.events = next.sort();
|
|
144
|
-
await (0, config_1.saveConfig)(config);
|
|
145
|
-
console.log(chalk_1.default.gray(`Total: ${config.events.length} events\n`));
|
|
146
|
-
}
|
|
147
|
-
locked = false;
|
|
83
|
+
const next = engine.getAllEvents().sort();
|
|
84
|
+
config.events = next;
|
|
85
|
+
await (0, config_1.saveConfig)(config);
|
|
86
|
+
console.log(chalk_1.default.green(`Updated: ${next.length}`));
|
|
148
87
|
};
|
|
149
|
-
// SCHEDULER
|
|
150
88
|
const schedule = (file) => {
|
|
151
89
|
const abs = normalize(file);
|
|
152
|
-
|
|
153
|
-
console.log(chalk_1.default.gray(`change: ${file}`));
|
|
154
|
-
queued.set(abs, { real: abs, virtual });
|
|
90
|
+
queue.set(abs, true);
|
|
155
91
|
if (timer)
|
|
156
92
|
clearTimeout(timer);
|
|
157
93
|
timer = setTimeout(run, 200);
|
|
158
94
|
};
|
|
159
|
-
// WATCHER
|
|
160
|
-
const watcher = chokidar_1.default.watch(config.sync.include, {
|
|
161
|
-
ignored: config.sync.exclude,
|
|
162
|
-
ignoreInitial: true,
|
|
163
|
-
persistent: true,
|
|
164
|
-
});
|
|
165
95
|
watcher
|
|
166
|
-
.on("add", schedule)
|
|
167
96
|
.on("change", schedule)
|
|
97
|
+
.on("add", schedule)
|
|
168
98
|
.on("unlink", async (file) => {
|
|
169
99
|
const abs = normalize(file);
|
|
170
|
-
|
|
171
|
-
const
|
|
172
|
-
|
|
173
|
-
watcher.unwatch(abs);
|
|
174
|
-
watchedDeps.delete(abs);
|
|
175
|
-
const next = engine.getAllEvents();
|
|
176
|
-
config.events = next.sort();
|
|
100
|
+
engine.removeFile((0, getVirtualFile_1.getVirtualFile)(abs), config);
|
|
101
|
+
const next = engine.getAllEvents().sort();
|
|
102
|
+
config.events = next;
|
|
177
103
|
await (0, config_1.saveConfig)(config);
|
|
178
|
-
console.log(chalk_1.default.
|
|
179
|
-
})
|
|
180
|
-
.on("error", (err) => {
|
|
181
|
-
console.error(chalk_1.default.red("Watcher error:"), err);
|
|
104
|
+
console.log(chalk_1.default.red(`Removed → ${next.length}`));
|
|
182
105
|
});
|
|
183
|
-
// WATCH DEPS INIT
|
|
184
|
-
for (const dep of watchedDeps) {
|
|
185
|
-
watcher.add(dep);
|
|
186
|
-
}
|
|
187
|
-
// EXIT
|
|
188
106
|
process.on("SIGINT", async () => {
|
|
189
|
-
console.log(chalk_1.default.yellow("\nStopping watcher..."));
|
|
190
107
|
await watcher.close();
|
|
191
108
|
process.exit(0);
|
|
192
109
|
});
|
package/dist/engine/engine.js
CHANGED
|
@@ -41,7 +41,7 @@ class EventraEngine {
|
|
|
41
41
|
this.graph.update(file, source);
|
|
42
42
|
}
|
|
43
43
|
}
|
|
44
|
-
// SCAN FILE
|
|
44
|
+
// SCAN FILE (cached)
|
|
45
45
|
scanFile(file, content, config) {
|
|
46
46
|
file = this.normalize(file);
|
|
47
47
|
const h = (0, hash_1.hash)(content);
|
|
@@ -55,7 +55,6 @@ class EventraEngine {
|
|
|
55
55
|
if (!source || !checker) {
|
|
56
56
|
return this.empty();
|
|
57
57
|
}
|
|
58
|
-
// update graph
|
|
59
58
|
this.graph.update(file, source);
|
|
60
59
|
const res = (0, scanner_1.scanSource)(source, checker, config, new Set(), undefined, this.wrapperCache);
|
|
61
60
|
this.fileResults.set(file, res);
|
|
@@ -63,12 +62,19 @@ class EventraEngine {
|
|
|
63
62
|
}
|
|
64
63
|
// UPDATE FILE (incremental)
|
|
65
64
|
updateFile(file, content, config) {
|
|
66
|
-
this.wrapperCache.clear();
|
|
67
65
|
file = this.normalize(file);
|
|
66
|
+
// EARLY EXIT
|
|
67
|
+
if (this.fileHash.get(file) === (0, hash_1.hash)(content)) {
|
|
68
|
+
return this.fileResults.get(file) ?? this.empty();
|
|
69
|
+
}
|
|
70
|
+
// invalidate wrapper cache
|
|
71
|
+
this.wrapperCache.clear();
|
|
68
72
|
const res = this.scanFile(file, content, config);
|
|
69
73
|
const dependents = this.graph.getAllDependentsDeep(file);
|
|
70
74
|
for (const dep of dependents) {
|
|
71
75
|
const abs = this.normalize(dep);
|
|
76
|
+
if (abs === file)
|
|
77
|
+
continue; // self-skip
|
|
72
78
|
if ((0, boundary_1.isExternalFile)(abs))
|
|
73
79
|
continue;
|
|
74
80
|
let depContent = this.ts.getFileContent(abs);
|
|
@@ -106,15 +112,17 @@ class EventraEngine {
|
|
|
106
112
|
}
|
|
107
113
|
// REMOVE FILE
|
|
108
114
|
removeFile(file, config) {
|
|
109
|
-
this.wrapperCache.clear();
|
|
110
115
|
file = this.normalize(file);
|
|
116
|
+
this.wrapperCache.clear();
|
|
111
117
|
const dependents = this.graph.getAllDependentsDeep(file);
|
|
118
|
+
this.graph.remove(file);
|
|
112
119
|
this.ts.removeFile(file);
|
|
113
120
|
this.fileResults.delete(file);
|
|
114
121
|
this.fileHash.delete(file);
|
|
115
|
-
this.graph.remove(file);
|
|
116
122
|
for (const dep of dependents) {
|
|
117
123
|
const abs = this.normalize(dep);
|
|
124
|
+
if (abs === file)
|
|
125
|
+
continue;
|
|
118
126
|
if ((0, boundary_1.isExternalFile)(abs))
|
|
119
127
|
continue;
|
|
120
128
|
let content = this.ts.getFileContent(abs);
|
|
@@ -126,10 +134,7 @@ class EventraEngine {
|
|
|
126
134
|
continue;
|
|
127
135
|
}
|
|
128
136
|
}
|
|
129
|
-
|
|
130
|
-
if (this.fileHash.get(abs) === h)
|
|
131
|
-
continue;
|
|
132
|
-
this.fileHash.set(abs, h);
|
|
137
|
+
this.fileHash.delete(abs);
|
|
133
138
|
this.ts.updateFile(abs, content);
|
|
134
139
|
const source = this.ts.getSourceFile(abs);
|
|
135
140
|
const checker = this.ts.getChecker();
|
|
@@ -21,7 +21,7 @@ class TSService {
|
|
|
21
21
|
let compilerOptions = {
|
|
22
22
|
allowJs: true,
|
|
23
23
|
allowNonTsExtensions: true,
|
|
24
|
-
jsx: typescript_1.default.JsxEmit.
|
|
24
|
+
jsx: typescript_1.default.JsxEmit.Preserve,
|
|
25
25
|
jsxImportSource: "react",
|
|
26
26
|
moduleResolution: typescript_1.default.ModuleResolutionKind.Node16,
|
|
27
27
|
target: typescript_1.default.ScriptTarget.ESNext,
|
|
@@ -46,7 +46,15 @@ class TSService {
|
|
|
46
46
|
this.compilerOptions = compilerOptions;
|
|
47
47
|
this.baseUrl = baseUrl;
|
|
48
48
|
this.paths = paths;
|
|
49
|
-
const allFiles = typescript_1.default.sys.readDirectory(root, [
|
|
49
|
+
const allFiles = typescript_1.default.sys.readDirectory(root, [
|
|
50
|
+
".ts",
|
|
51
|
+
".tsx",
|
|
52
|
+
".js",
|
|
53
|
+
".jsx",
|
|
54
|
+
".vue",
|
|
55
|
+
".svelte",
|
|
56
|
+
".astro"
|
|
57
|
+
], undefined, undefined);
|
|
50
58
|
for (const f of allFiles) {
|
|
51
59
|
this.fileNames.add(this.normalize(f));
|
|
52
60
|
}
|
|
@@ -58,26 +66,31 @@ class TSService {
|
|
|
58
66
|
file = this.normalize(file);
|
|
59
67
|
return this.files.get(file)?.version.toString() ?? "0";
|
|
60
68
|
},
|
|
69
|
+
getScriptKind: (fileName) => {
|
|
70
|
+
fileName = this.normalize(fileName);
|
|
71
|
+
if (fileName.endsWith(".tsx") ||
|
|
72
|
+
fileName.endsWith(".vue") ||
|
|
73
|
+
fileName.endsWith(".svelte") ||
|
|
74
|
+
fileName.endsWith(".astro")) {
|
|
75
|
+
return typescript_1.default.ScriptKind.TSX;
|
|
76
|
+
}
|
|
77
|
+
if (fileName.endsWith(".ts")) {
|
|
78
|
+
return typescript_1.default.ScriptKind.TS;
|
|
79
|
+
}
|
|
80
|
+
if (fileName.endsWith(".jsx")) {
|
|
81
|
+
return typescript_1.default.ScriptKind.JSX;
|
|
82
|
+
}
|
|
83
|
+
if (fileName.endsWith(".js")) {
|
|
84
|
+
return typescript_1.default.ScriptKind.JS;
|
|
85
|
+
}
|
|
86
|
+
return typescript_1.default.ScriptKind.Unknown;
|
|
87
|
+
},
|
|
61
88
|
getScriptSnapshot: (file) => {
|
|
62
89
|
file = this.normalize(file);
|
|
63
|
-
// из памяти
|
|
64
90
|
const f = this.files.get(file);
|
|
65
91
|
if (f) {
|
|
66
92
|
return typescript_1.default.ScriptSnapshot.fromString(f.content);
|
|
67
93
|
}
|
|
68
|
-
// virtual TSX (vue/svelte/astro)
|
|
69
|
-
if (file.endsWith(".tsx")) {
|
|
70
|
-
const original = file.replace(/\.tsx$/, "");
|
|
71
|
-
if (fs_1.default.existsSync(original)) {
|
|
72
|
-
const content = fs_1.default.readFileSync(original, "utf-8");
|
|
73
|
-
this.files.set(file, {
|
|
74
|
-
content,
|
|
75
|
-
version: 1,
|
|
76
|
-
});
|
|
77
|
-
this.fileNames.add(file);
|
|
78
|
-
return typescript_1.default.ScriptSnapshot.fromString(content);
|
|
79
|
-
}
|
|
80
|
-
}
|
|
81
94
|
try {
|
|
82
95
|
if (fs_1.default.existsSync(file)) {
|
|
83
96
|
const content = fs_1.default.readFileSync(file, "utf-8");
|
|
@@ -110,12 +123,6 @@ class TSService {
|
|
|
110
123
|
normalize(file) {
|
|
111
124
|
return path_1.default.resolve(file).replace(/\\/g, "/");
|
|
112
125
|
}
|
|
113
|
-
ensureProgram() {
|
|
114
|
-
try {
|
|
115
|
-
this.service.getProgram();
|
|
116
|
-
}
|
|
117
|
-
catch { }
|
|
118
|
-
}
|
|
119
126
|
// PUBLIC API
|
|
120
127
|
updateFile(file, content) {
|
|
121
128
|
file = this.normalize(file);
|
|
@@ -125,13 +132,11 @@ class TSService {
|
|
|
125
132
|
version: prev ? prev.version + 1 : 1,
|
|
126
133
|
});
|
|
127
134
|
this.fileNames.add(file);
|
|
128
|
-
this.ensureProgram();
|
|
129
135
|
}
|
|
130
136
|
removeFile(file) {
|
|
131
137
|
file = this.normalize(file);
|
|
132
138
|
this.files.delete(file);
|
|
133
139
|
this.fileNames.delete(file);
|
|
134
|
-
this.ensureProgram();
|
|
135
140
|
}
|
|
136
141
|
getProgram() {
|
|
137
142
|
return this.service.getProgram();
|