@eventra_dev/eventra-cli 0.1.34 → 0.2.1
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/scanner.js +41 -28
- 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/scanner.ts +67 -27
- package/src/utils/universal.ts +1 -1
package/src/commands/check.ts
CHANGED
|
@@ -25,28 +25,20 @@ export async function check({ fix = false }: { fix?: boolean }) {
|
|
|
25
25
|
|
|
26
26
|
const engine = new EventraEngine(process.cwd());
|
|
27
27
|
|
|
28
|
+
const cache = new Map<string, { content: string; deps: string[] }>();
|
|
28
29
|
const toScan = new Set<string>();
|
|
29
30
|
|
|
30
|
-
|
|
31
|
-
string,
|
|
32
|
-
{ content: string; deps: string[] }
|
|
33
|
-
>();
|
|
34
|
-
|
|
35
|
-
// COLLECT + CACHE
|
|
31
|
+
// COLLECT
|
|
36
32
|
for (const file of files) {
|
|
37
33
|
try {
|
|
38
34
|
const raw = await fs.readFile(file, "utf-8");
|
|
39
|
-
|
|
40
35
|
if (raw.length > 2_000_000) continue;
|
|
41
36
|
|
|
42
37
|
const parsed = processFile(file, raw);
|
|
43
38
|
|
|
44
39
|
cache.set(file, parsed);
|
|
45
40
|
toScan.add(file);
|
|
46
|
-
|
|
47
|
-
for (const dep of parsed.deps) {
|
|
48
|
-
toScan.add(path.resolve(dep));
|
|
49
|
-
}
|
|
41
|
+
parsed.deps.forEach(dep => toScan.add(path.resolve(dep)));
|
|
50
42
|
|
|
51
43
|
} catch {}
|
|
52
44
|
}
|
|
@@ -54,17 +46,9 @@ export async function check({ fix = false }: { fix?: boolean }) {
|
|
|
54
46
|
// PRELOAD
|
|
55
47
|
for (const file of toScan) {
|
|
56
48
|
try {
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
const raw = await fs.readFile(file, "utf-8");
|
|
61
|
-
parsed = processFile(file, raw);
|
|
62
|
-
cache.set(file, parsed);
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
const virtual = getVirtualFile(file);
|
|
66
|
-
engine.preloadFile(virtual, parsed.content);
|
|
67
|
-
|
|
49
|
+
const parsed = cache.get(file);
|
|
50
|
+
if (!parsed) continue;
|
|
51
|
+
engine.preloadFile(getVirtualFile(file), parsed.content);
|
|
68
52
|
} catch {}
|
|
69
53
|
}
|
|
70
54
|
|
|
@@ -74,49 +58,34 @@ export async function check({ fix = false }: { fix?: boolean }) {
|
|
|
74
58
|
const parsed = cache.get(file);
|
|
75
59
|
if (!parsed) continue;
|
|
76
60
|
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
61
|
+
engine.scanFile(
|
|
62
|
+
getVirtualFile(file),
|
|
63
|
+
parsed.content,
|
|
64
|
+
config
|
|
65
|
+
);
|
|
80
66
|
|
|
81
67
|
} catch {}
|
|
82
68
|
}
|
|
83
69
|
|
|
84
|
-
// DIFF
|
|
85
70
|
const found = new Set(engine.getAllEvents());
|
|
86
71
|
const known = new Set(config.events ?? []);
|
|
87
72
|
|
|
88
|
-
const
|
|
73
|
+
const added = [...found].filter(e => !known.has(e));
|
|
89
74
|
const removed = [...known].filter(e => !found.has(e));
|
|
90
75
|
|
|
91
|
-
// FIX MODE
|
|
92
76
|
if (fix) {
|
|
93
77
|
config.events = [...found].sort();
|
|
94
78
|
await saveConfig(config);
|
|
95
|
-
|
|
96
|
-
console.log(
|
|
97
|
-
chalk.green(`\nSynced (${config.events.length} events)`)
|
|
98
|
-
);
|
|
79
|
+
console.log(chalk.green("Synced"));
|
|
99
80
|
return;
|
|
100
81
|
}
|
|
101
82
|
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
console.log(chalk.red("\nNew events:"));
|
|
106
|
-
newEvents.forEach(e =>
|
|
107
|
-
console.log(chalk.red(`+ ${e}`))
|
|
108
|
-
);
|
|
109
|
-
}
|
|
110
|
-
|
|
111
|
-
if (removed.length) {
|
|
112
|
-
console.log(chalk.yellow("\nRemoved events:"));
|
|
113
|
-
removed.forEach(e =>
|
|
114
|
-
console.log(chalk.yellow(`- ${e}`))
|
|
115
|
-
);
|
|
116
|
-
}
|
|
83
|
+
if (added.length || removed.length) {
|
|
84
|
+
added.forEach(e => console.log(chalk.red(`+ ${e}`)));
|
|
85
|
+
removed.forEach(e => console.log(chalk.yellow(`- ${e}`)));
|
|
117
86
|
|
|
118
87
|
process.exit(1);
|
|
119
88
|
}
|
|
120
89
|
|
|
121
|
-
console.log(chalk.green("
|
|
90
|
+
console.log(chalk.green("All good"));
|
|
122
91
|
}
|
package/src/commands/sync.ts
CHANGED
|
@@ -19,25 +19,15 @@ export async function sync() {
|
|
|
19
19
|
absolute: true,
|
|
20
20
|
});
|
|
21
21
|
|
|
22
|
-
if (!files.length) {
|
|
23
|
-
console.log(chalk.yellow("No files found"));
|
|
24
|
-
return;
|
|
25
|
-
}
|
|
26
|
-
|
|
27
22
|
const engine = new EventraEngine(process.cwd());
|
|
28
23
|
|
|
24
|
+
const cache = new Map<string, { content: string; deps: string[] }>();
|
|
29
25
|
const toScan = new Set<string>();
|
|
30
26
|
|
|
31
|
-
|
|
32
|
-
string,
|
|
33
|
-
{ content: string; deps: string[] }
|
|
34
|
-
>();
|
|
35
|
-
|
|
36
|
-
// COLLECT + CACHE
|
|
27
|
+
// COLLECT
|
|
37
28
|
for (const file of files) {
|
|
38
29
|
try {
|
|
39
30
|
const raw = await fs.readFile(file, "utf-8");
|
|
40
|
-
|
|
41
31
|
if (raw.length > 2_000_000) continue;
|
|
42
32
|
|
|
43
33
|
const parsed = processFile(file, raw);
|
|
@@ -45,9 +35,7 @@ export async function sync() {
|
|
|
45
35
|
cache.set(file, parsed);
|
|
46
36
|
toScan.add(file);
|
|
47
37
|
|
|
48
|
-
|
|
49
|
-
toScan.add(path.resolve(dep));
|
|
50
|
-
}
|
|
38
|
+
parsed.deps.forEach(dep => toScan.add(path.resolve(dep)));
|
|
51
39
|
|
|
52
40
|
} catch {}
|
|
53
41
|
}
|
|
@@ -63,8 +51,7 @@ export async function sync() {
|
|
|
63
51
|
cache.set(file, parsed);
|
|
64
52
|
}
|
|
65
53
|
|
|
66
|
-
|
|
67
|
-
engine.preloadFile(virtual, parsed.content);
|
|
54
|
+
engine.preloadFile(getVirtualFile(file), parsed.content);
|
|
68
55
|
|
|
69
56
|
} catch {}
|
|
70
57
|
}
|
|
@@ -78,21 +65,16 @@ export async function sync() {
|
|
|
78
65
|
const parsed = cache.get(file);
|
|
79
66
|
if (!parsed) continue;
|
|
80
67
|
|
|
81
|
-
const
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
res.detectedFunctionWrappers.forEach(w =>
|
|
86
|
-
detectedFn.add(w)
|
|
68
|
+
const res = engine.updateFile(
|
|
69
|
+
getVirtualFile(file),
|
|
70
|
+
parsed.content,
|
|
71
|
+
config
|
|
87
72
|
);
|
|
88
73
|
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
}
|
|
74
|
+
res.detectedFunctionWrappers.forEach(w => detectedFn.add(w));
|
|
75
|
+
res.detectedComponentWrappers.forEach((v, k) => detectedCmp.set(k, v));
|
|
92
76
|
|
|
93
|
-
} catch {
|
|
94
|
-
console.log(chalk.gray(`skip: ${file}`));
|
|
95
|
-
}
|
|
77
|
+
} catch {}
|
|
96
78
|
}
|
|
97
79
|
|
|
98
80
|
// RESULT
|
|
@@ -108,10 +90,7 @@ export async function sync() {
|
|
|
108
90
|
|
|
109
91
|
config.wrappers = mergeUnique(
|
|
110
92
|
config.wrappers ?? [],
|
|
111
|
-
[...detectedCmp.entries()].map(([name, prop]) => ({
|
|
112
|
-
name,
|
|
113
|
-
prop,
|
|
114
|
-
})),
|
|
93
|
+
[...detectedCmp.entries()].map(([name, prop]) => ({ name, prop })),
|
|
115
94
|
w => `${w.name}:${w.prop}`
|
|
116
95
|
);
|
|
117
96
|
|
|
@@ -120,17 +99,8 @@ export async function sync() {
|
|
|
120
99
|
console.log(chalk.green(`Found ${events.length} events`));
|
|
121
100
|
}
|
|
122
101
|
|
|
123
|
-
|
|
124
|
-
function mergeUnique<T>(
|
|
125
|
-
a: T[],
|
|
126
|
-
b: T[],
|
|
127
|
-
key: (v: T) => string
|
|
128
|
-
): T[] {
|
|
102
|
+
function mergeUnique<T>(a: T[], b: T[], key: (v: T) => string): T[] {
|
|
129
103
|
const map = new Map<string, T>();
|
|
130
|
-
|
|
131
|
-
[...b, ...a].forEach(item => {
|
|
132
|
-
map.set(key(item), item);
|
|
133
|
-
});
|
|
134
|
-
|
|
104
|
+
[...b, ...a].forEach(item => map.set(key(item), item));
|
|
135
105
|
return [...map.values()];
|
|
136
106
|
}
|
package/src/commands/watch.ts
CHANGED
|
@@ -9,92 +9,39 @@ import { EventraEngine } from "../engine/engine";
|
|
|
9
9
|
import { processFile } from "../utils/processFile";
|
|
10
10
|
import { getVirtualFile } from "../utils/getVirtualFile";
|
|
11
11
|
|
|
12
|
-
type QueueItem = {
|
|
13
|
-
real: string;
|
|
14
|
-
virtual: string;
|
|
15
|
-
};
|
|
16
|
-
|
|
17
|
-
function normalize(file: string) {
|
|
18
|
-
return path.resolve(file).replace(/\\/g, "/");
|
|
19
|
-
}
|
|
20
|
-
|
|
21
12
|
export async function watch() {
|
|
22
13
|
const config = await loadConfig();
|
|
23
14
|
if (!config) return;
|
|
24
15
|
|
|
25
16
|
console.log(chalk.blue("Watching...\n"));
|
|
26
17
|
|
|
27
|
-
const files = await fg(config.sync.include, {
|
|
28
|
-
ignore: config.sync.exclude,
|
|
29
|
-
absolute: true,
|
|
30
|
-
});
|
|
31
|
-
|
|
32
18
|
const engine = new EventraEngine(process.cwd());
|
|
19
|
+
const fileDeps = new Map<string, Set<string>>();
|
|
20
|
+
const cache = new Map<string, { content: string; deps: string[] }>();
|
|
33
21
|
const watchedDeps = new Set<string>();
|
|
34
22
|
|
|
35
|
-
const
|
|
36
|
-
|
|
37
|
-
{ content: string; deps: string[] }
|
|
38
|
-
>();
|
|
23
|
+
const normalize = (f: string) =>
|
|
24
|
+
path.resolve(f).replace(/\\/g, "/");
|
|
39
25
|
|
|
40
|
-
|
|
26
|
+
// INITIAL LOAD
|
|
27
|
+
const files = await fg(config.sync.include, {
|
|
28
|
+
ignore: config.sync.exclude,
|
|
29
|
+
absolute: true,
|
|
30
|
+
});
|
|
41
31
|
|
|
42
|
-
// COLLECT + CACHE
|
|
43
32
|
for (const file of files) {
|
|
44
33
|
try {
|
|
45
34
|
const abs = normalize(file);
|
|
46
35
|
const raw = await fs.readFile(abs, "utf-8");
|
|
47
36
|
|
|
48
|
-
if (raw.length > 2_000_000) continue;
|
|
49
|
-
|
|
50
37
|
const parsed = processFile(abs, raw);
|
|
51
38
|
|
|
52
39
|
cache.set(abs, parsed);
|
|
53
|
-
toScan.add(abs);
|
|
54
40
|
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
}
|
|
41
|
+
engine.preloadFile(getVirtualFile(abs), parsed.content);
|
|
42
|
+
engine.updateFile(getVirtualFile(abs), parsed.content, config);
|
|
58
43
|
|
|
59
|
-
|
|
60
|
-
console.log(chalk.gray(`skip: ${file}`));
|
|
61
|
-
}
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
// PRELOAD
|
|
65
|
-
for (const file of toScan) {
|
|
66
|
-
try {
|
|
67
|
-
let parsed = cache.get(file);
|
|
68
|
-
|
|
69
|
-
if (!parsed) {
|
|
70
|
-
const raw = await fs.readFile(file, "utf-8");
|
|
71
|
-
parsed = processFile(file, raw);
|
|
72
|
-
cache.set(file, parsed);
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
const virtual = getVirtualFile(file);
|
|
76
|
-
engine.preloadFile?.(virtual, parsed.content);
|
|
77
|
-
|
|
78
|
-
} catch {}
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
// INITIAL SCAN
|
|
82
|
-
for (const file of toScan) {
|
|
83
|
-
try {
|
|
84
|
-
let parsed = cache.get(file);
|
|
85
|
-
|
|
86
|
-
if (!parsed) {
|
|
87
|
-
const raw = await fs.readFile(file, "utf-8");
|
|
88
|
-
parsed = processFile(file, raw);
|
|
89
|
-
}
|
|
90
|
-
|
|
91
|
-
const virtual = getVirtualFile(file);
|
|
92
|
-
|
|
93
|
-
engine.scanFile(virtual, parsed.content, config);
|
|
94
|
-
|
|
95
|
-
for (const dep of parsed.deps) {
|
|
96
|
-
watchedDeps.add(normalize(dep));
|
|
97
|
-
}
|
|
44
|
+
fileDeps.set(abs, new Set(parsed.deps.map(d => normalize(d))));
|
|
98
45
|
|
|
99
46
|
} catch {}
|
|
100
47
|
}
|
|
@@ -102,152 +49,95 @@ export async function watch() {
|
|
|
102
49
|
config.events = engine.getAllEvents().sort();
|
|
103
50
|
await saveConfig(config);
|
|
104
51
|
|
|
105
|
-
console.log(
|
|
106
|
-
|
|
52
|
+
console.log(chalk.gray(`Initial: ${config.events.length}\n`));
|
|
53
|
+
|
|
54
|
+
// WATCHER
|
|
55
|
+
const watcher = chokidar.watch(
|
|
56
|
+
[...files.map(normalize), ...watchedDeps],
|
|
57
|
+
{ ignoreInitial: true }
|
|
107
58
|
);
|
|
108
59
|
|
|
109
|
-
|
|
110
|
-
let locked = false;
|
|
111
|
-
const queued = new Map<string, QueueItem>();
|
|
60
|
+
const queue = new Map<string, boolean>();
|
|
112
61
|
let timer: NodeJS.Timeout | null = null;
|
|
113
62
|
|
|
114
63
|
const run = async () => {
|
|
115
|
-
|
|
116
|
-
|
|
64
|
+
const batch = [...queue.keys()];
|
|
65
|
+
queue.clear();
|
|
117
66
|
|
|
118
|
-
const
|
|
119
|
-
queued.clear();
|
|
120
|
-
|
|
121
|
-
for (const item of batch) {
|
|
67
|
+
for (const file of batch) {
|
|
122
68
|
try {
|
|
123
|
-
const raw = await fs.readFile(
|
|
124
|
-
|
|
125
|
-
if (raw.length > 2_000_000) continue;
|
|
69
|
+
const raw = await fs.readFile(file, "utf-8");
|
|
70
|
+
const parsed = processFile(file, raw);
|
|
126
71
|
|
|
127
|
-
|
|
128
|
-
cache.set(item.real, parsed);
|
|
72
|
+
cache.set(file, parsed);
|
|
129
73
|
|
|
130
|
-
engine.updateFile(
|
|
74
|
+
engine.updateFile(
|
|
75
|
+
getVirtualFile(file),
|
|
76
|
+
parsed.content,
|
|
77
|
+
config
|
|
78
|
+
);
|
|
131
79
|
|
|
132
|
-
//
|
|
133
|
-
const
|
|
80
|
+
//dependency diff
|
|
81
|
+
const abs = normalize(file);
|
|
134
82
|
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
}
|
|
83
|
+
const prevDeps = fileDeps.get(abs) ?? new Set();
|
|
84
|
+
const nextDeps = new Set(parsed.deps.map(d => normalize(d)));
|
|
138
85
|
|
|
139
86
|
// add new deps
|
|
140
87
|
for (const dep of nextDeps) {
|
|
141
|
-
if (!
|
|
88
|
+
if (!prevDeps.has(dep)) {
|
|
142
89
|
watcher.add(dep);
|
|
143
90
|
watchedDeps.add(dep);
|
|
144
91
|
}
|
|
145
92
|
}
|
|
146
93
|
|
|
147
94
|
// remove old deps
|
|
148
|
-
for (const dep of
|
|
95
|
+
for (const dep of prevDeps) {
|
|
149
96
|
if (!nextDeps.has(dep)) {
|
|
150
97
|
watcher.unwatch(dep);
|
|
151
98
|
watchedDeps.delete(dep);
|
|
152
99
|
}
|
|
153
100
|
}
|
|
154
101
|
|
|
155
|
-
|
|
156
|
-
for (const dep of nextDeps) {
|
|
157
|
-
try {
|
|
158
|
-
const raw = await fs.readFile(dep, "utf-8");
|
|
159
|
-
const parsedDep = processFile(dep, raw);
|
|
160
|
-
|
|
161
|
-
cache.set(dep, parsedDep);
|
|
162
|
-
|
|
163
|
-
const virtual = getVirtualFile(dep);
|
|
164
|
-
|
|
165
|
-
engine.updateFile(virtual, parsedDep.content, config);
|
|
166
|
-
} catch {}
|
|
167
|
-
}
|
|
102
|
+
fileDeps.set(abs, nextDeps);
|
|
168
103
|
|
|
169
104
|
} catch {
|
|
170
|
-
console.log(chalk.gray(`skip: ${
|
|
105
|
+
console.log(chalk.gray(`skip: ${file}`));
|
|
171
106
|
}
|
|
172
107
|
}
|
|
173
108
|
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
const added = next.filter(e => !config.events.includes(e));
|
|
178
|
-
const removed = config.events.filter(e => !next.includes(e));
|
|
179
|
-
|
|
180
|
-
if (added.length || removed.length) {
|
|
181
|
-
added.forEach(e => console.log(chalk.green(`+ ${e}`)));
|
|
182
|
-
removed.forEach(e => console.log(chalk.red(`- ${e}`)));
|
|
109
|
+
const next = engine.getAllEvents().sort();
|
|
110
|
+
config.events = next;
|
|
183
111
|
|
|
184
|
-
|
|
185
|
-
await saveConfig(config);
|
|
186
|
-
|
|
187
|
-
console.log(
|
|
188
|
-
chalk.gray(`Total: ${config.events.length} events\n`)
|
|
189
|
-
);
|
|
190
|
-
}
|
|
112
|
+
await saveConfig(config);
|
|
191
113
|
|
|
192
|
-
|
|
114
|
+
console.log(chalk.green(`Updated: ${next.length}`));
|
|
193
115
|
};
|
|
194
116
|
|
|
195
|
-
// SCHEDULER
|
|
196
117
|
const schedule = (file: string) => {
|
|
197
118
|
const abs = normalize(file);
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
console.log(chalk.gray(`change: ${file}`));
|
|
201
|
-
|
|
202
|
-
queued.set(abs, { real: abs, virtual });
|
|
119
|
+
queue.set(abs, true);
|
|
203
120
|
|
|
204
121
|
if (timer) clearTimeout(timer);
|
|
205
122
|
timer = setTimeout(run, 200);
|
|
206
123
|
};
|
|
207
124
|
|
|
208
|
-
// WATCHER
|
|
209
|
-
const watcher = chokidar.watch(config.sync.include, {
|
|
210
|
-
ignored: config.sync.exclude,
|
|
211
|
-
ignoreInitial: true,
|
|
212
|
-
persistent: true,
|
|
213
|
-
});
|
|
214
|
-
|
|
215
125
|
watcher
|
|
216
|
-
.on("add", schedule)
|
|
217
126
|
.on("change", schedule)
|
|
127
|
+
.on("add", schedule)
|
|
218
128
|
.on("unlink", async (file) => {
|
|
219
129
|
const abs = normalize(file);
|
|
220
130
|
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
const virtual = getVirtualFile(abs);
|
|
224
|
-
|
|
225
|
-
engine.removeFile(virtual, config);
|
|
131
|
+
engine.removeFile(getVirtualFile(abs), config);
|
|
226
132
|
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
const next = engine.getAllEvents();
|
|
231
|
-
|
|
232
|
-
config.events = next.sort();
|
|
133
|
+
const next = engine.getAllEvents().sort();
|
|
134
|
+
config.events = next;
|
|
233
135
|
await saveConfig(config);
|
|
234
136
|
|
|
235
|
-
console.log(
|
|
236
|
-
chalk.gray(`Total: ${config.events.length} events\n`)
|
|
237
|
-
);
|
|
238
|
-
})
|
|
239
|
-
.on("error", (err) => {
|
|
240
|
-
console.error(chalk.red("Watcher error:"), err);
|
|
137
|
+
console.log(chalk.red(`Removed → ${next.length}`));
|
|
241
138
|
});
|
|
242
139
|
|
|
243
|
-
// WATCH DEPS INIT
|
|
244
|
-
for (const dep of watchedDeps) {
|
|
245
|
-
watcher.add(dep);
|
|
246
|
-
}
|
|
247
|
-
|
|
248
|
-
// EXIT
|
|
249
140
|
process.on("SIGINT", async () => {
|
|
250
|
-
console.log(chalk.yellow("\nStopping watcher..."));
|
|
251
141
|
await watcher.close();
|
|
252
142
|
process.exit(0);
|
|
253
143
|
});
|
package/src/engine/engine.ts
CHANGED
|
@@ -5,7 +5,7 @@ import { TSService } from "./languageService";
|
|
|
5
5
|
import { scanSource } from "./scanner";
|
|
6
6
|
import { DependencyGraph } from "./graph";
|
|
7
7
|
import { hash } from "./hash";
|
|
8
|
-
import {EventraConfig, ScanResult} from "../types";
|
|
8
|
+
import { EventraConfig, ScanResult } from "../types";
|
|
9
9
|
import { isExternalFile } from "./boundary";
|
|
10
10
|
|
|
11
11
|
export class EventraEngine {
|
|
@@ -46,7 +46,7 @@ export class EventraEngine {
|
|
|
46
46
|
}
|
|
47
47
|
}
|
|
48
48
|
|
|
49
|
-
// SCAN FILE
|
|
49
|
+
// SCAN FILE (cached)
|
|
50
50
|
scanFile(
|
|
51
51
|
file: string,
|
|
52
52
|
content: string,
|
|
@@ -71,7 +71,6 @@ export class EventraEngine {
|
|
|
71
71
|
return this.empty();
|
|
72
72
|
}
|
|
73
73
|
|
|
74
|
-
// update graph
|
|
75
74
|
this.graph.update(file, source);
|
|
76
75
|
|
|
77
76
|
const res = scanSource(
|
|
@@ -82,6 +81,7 @@ export class EventraEngine {
|
|
|
82
81
|
undefined,
|
|
83
82
|
this.wrapperCache
|
|
84
83
|
);
|
|
84
|
+
|
|
85
85
|
this.fileResults.set(file, res);
|
|
86
86
|
|
|
87
87
|
return res;
|
|
@@ -92,10 +92,17 @@ export class EventraEngine {
|
|
|
92
92
|
file: string,
|
|
93
93
|
content: string,
|
|
94
94
|
config: EventraConfig
|
|
95
|
-
) {
|
|
96
|
-
this.wrapperCache.clear();
|
|
95
|
+
): ScanResult {
|
|
97
96
|
file = this.normalize(file);
|
|
98
97
|
|
|
98
|
+
// EARLY EXIT
|
|
99
|
+
if (this.fileHash.get(file) === hash(content)) {
|
|
100
|
+
return this.fileResults.get(file) ?? this.empty();
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
// invalidate wrapper cache
|
|
104
|
+
this.wrapperCache.clear();
|
|
105
|
+
|
|
99
106
|
const res = this.scanFile(file, content, config);
|
|
100
107
|
|
|
101
108
|
const dependents = this.graph.getAllDependentsDeep(file);
|
|
@@ -103,6 +110,7 @@ export class EventraEngine {
|
|
|
103
110
|
for (const dep of dependents) {
|
|
104
111
|
const abs = this.normalize(dep);
|
|
105
112
|
|
|
113
|
+
if (abs === file) continue; // self-skip
|
|
106
114
|
if (isExternalFile(abs)) continue;
|
|
107
115
|
|
|
108
116
|
let depContent = this.ts.getFileContent(abs);
|
|
@@ -140,6 +148,7 @@ export class EventraEngine {
|
|
|
140
148
|
undefined,
|
|
141
149
|
this.wrapperCache
|
|
142
150
|
);
|
|
151
|
+
|
|
143
152
|
this.fileResults.set(abs, r);
|
|
144
153
|
}
|
|
145
154
|
|
|
@@ -159,19 +168,22 @@ export class EventraEngine {
|
|
|
159
168
|
|
|
160
169
|
// REMOVE FILE
|
|
161
170
|
removeFile(file: string, config?: EventraConfig) {
|
|
162
|
-
this.wrapperCache.clear();
|
|
163
171
|
file = this.normalize(file);
|
|
164
172
|
|
|
173
|
+
this.wrapperCache.clear();
|
|
174
|
+
|
|
165
175
|
const dependents = this.graph.getAllDependentsDeep(file);
|
|
166
176
|
|
|
177
|
+
this.graph.remove(file);
|
|
178
|
+
|
|
167
179
|
this.ts.removeFile(file);
|
|
168
180
|
this.fileResults.delete(file);
|
|
169
181
|
this.fileHash.delete(file);
|
|
170
|
-
this.graph.remove(file);
|
|
171
182
|
|
|
172
183
|
for (const dep of dependents) {
|
|
173
184
|
const abs = this.normalize(dep);
|
|
174
185
|
|
|
186
|
+
if (abs === file) continue;
|
|
175
187
|
if (isExternalFile(abs)) continue;
|
|
176
188
|
|
|
177
189
|
let content = this.ts.getFileContent(abs);
|
|
@@ -184,11 +196,7 @@ export class EventraEngine {
|
|
|
184
196
|
}
|
|
185
197
|
}
|
|
186
198
|
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
if (this.fileHash.get(abs) === h) continue;
|
|
190
|
-
|
|
191
|
-
this.fileHash.set(abs, h);
|
|
199
|
+
this.fileHash.delete(abs);
|
|
192
200
|
|
|
193
201
|
this.ts.updateFile(abs, content);
|
|
194
202
|
|