@eventra_dev/eventra-cli 0.3.2 → 0.3.4
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/README.md +2 -2
- package/dist/analysis/cache/evaluationCache.js +1 -3
- package/dist/analysis/cache/resolvedCallCache.js +1 -3
- package/dist/analysis/cache/resolvedExportCache.js +1 -3
- package/dist/analysis/cache/returnPropagationCache.js +19 -0
- package/dist/analysis/cache/symbolInvalidation.js +8 -2
- package/dist/analysis/extractor/extractor.js +5 -13
- package/dist/analysis/extractor/propagationExtractor.js +55 -14
- package/dist/analysis/resolver/callResolver.js +10 -52
- package/dist/analysis/resolver/exportResolver.js +4 -19
- package/dist/analysis/resolver/resolver.js +148 -29
- package/dist/analysis/scanner/analyzer/propagationAnalyzer.js +19 -48
- package/dist/analysis/scanner/analyzer/returnPropagationAnalyzer.js +2 -13
- package/dist/analysis/scanner/scanner.js +16 -44
- package/dist/analysis/scanner/sinkDetector.js +10 -44
- package/dist/analysis/shared/evaluationContext.js +0 -1
- package/dist/analysis/symbols/symbolUtils.js +6 -29
- package/dist/analysis/symbols/wrapperRegistry.js +25 -25
- package/dist/cli/check.js +8 -10
- package/dist/cli/init.js +18 -82
- package/dist/cli/send.js +7 -5
- package/dist/cli/sync.js +4 -39
- package/dist/cli/watch.js +42 -40
- package/dist/compiler/compilerContext.js +18 -41
- package/dist/compiler/documentRegistry.js +5 -15
- package/dist/compiler/importGraph.js +4 -8
- package/dist/compiler/scheduler.js +1 -3
- package/dist/config/config.js +9 -19
- package/dist/core/EventraEngine.js +37 -101
- package/dist/core/projectScanner.js +7 -6
- package/dist/filesystem/processFile.js +1 -4
- package/dist/shared/buildSyntheticTsx.js +1 -2
- package/package.json +1 -1
- package/dist/analysis/cache/semanticDependencyGraph.js +0 -25
- package/dist/analysis/pipeline/semanticPass.js +0 -2
|
@@ -49,17 +49,13 @@ class CompilerContext {
|
|
|
49
49
|
this.rootNames.add(this.normalize(file));
|
|
50
50
|
}
|
|
51
51
|
}
|
|
52
|
-
this.compilerOptions =
|
|
53
|
-
|
|
54
|
-
this.host =
|
|
55
|
-
typescript_1.default.createCompilerHost(this.compilerOptions, true);
|
|
52
|
+
this.compilerOptions = compilerOptions;
|
|
53
|
+
this.host = typescript_1.default.createCompilerHost(this.compilerOptions, true);
|
|
56
54
|
this.patchCompilerHost();
|
|
57
|
-
this.builder =
|
|
58
|
-
typescript_1.default.createEmitAndSemanticDiagnosticsBuilderProgram([...this.rootNames], this.compilerOptions, this.host);
|
|
55
|
+
this.builder = typescript_1.default.createEmitAndSemanticDiagnosticsBuilderProgram([...this.rootNames], this.compilerOptions, this.host);
|
|
59
56
|
}
|
|
60
57
|
normalize(fileName) {
|
|
61
|
-
return this.registry
|
|
62
|
-
.normalize(fileName);
|
|
58
|
+
return this.registry.normalize(fileName);
|
|
63
59
|
}
|
|
64
60
|
patchCompilerHost() {
|
|
65
61
|
const originalGetSourceFile = this.host.getSourceFile;
|
|
@@ -75,22 +71,16 @@ class CompilerContext {
|
|
|
75
71
|
this.host.readFile = (fileName) => {
|
|
76
72
|
const normalized = this.normalize(fileName);
|
|
77
73
|
this.registry.ensure(normalized);
|
|
78
|
-
return (this.registry.getContent(normalized)
|
|
79
|
-
?? fs_1.default.readFileSync(normalized, "utf8"));
|
|
74
|
+
return (this.registry.getContent(normalized) ?? fs_1.default.readFileSync(normalized, "utf8"));
|
|
80
75
|
};
|
|
81
76
|
this.host.fileExists = (fileName) => {
|
|
82
77
|
const normalized = this.normalize(fileName);
|
|
83
|
-
return (this.registry.has(normalized)
|
|
84
|
-
|| fs_1.default.existsSync(normalized));
|
|
78
|
+
return (this.registry.has(normalized) || fs_1.default.existsSync(normalized));
|
|
85
79
|
};
|
|
86
|
-
this.host.getCanonicalFileName =
|
|
87
|
-
|
|
88
|
-
this.host.
|
|
89
|
-
|
|
90
|
-
this.host.getCurrentDirectory =
|
|
91
|
-
() => this.rootDir;
|
|
92
|
-
this.host.getNewLine =
|
|
93
|
-
() => "\n";
|
|
80
|
+
this.host.getCanonicalFileName = (f) => this.normalize(f);
|
|
81
|
+
this.host.useCaseSensitiveFileNames = () => true;
|
|
82
|
+
this.host.getCurrentDirectory = () => this.rootDir;
|
|
83
|
+
this.host.getNewLine = () => "\n";
|
|
94
84
|
}
|
|
95
85
|
getScriptKind(fileName) {
|
|
96
86
|
if (fileName.endsWith(".tsx")) {
|
|
@@ -111,8 +101,7 @@ class CompilerContext {
|
|
|
111
101
|
return typescript_1.default.ScriptKind.Unknown;
|
|
112
102
|
}
|
|
113
103
|
rebuild() {
|
|
114
|
-
this.builder =
|
|
115
|
-
typescript_1.default.createEmitAndSemanticDiagnosticsBuilderProgram([...this.rootNames], this.compilerOptions, this.host, this.builder);
|
|
104
|
+
this.builder = typescript_1.default.createEmitAndSemanticDiagnosticsBuilderProgram([...this.rootNames], this.compilerOptions, this.host, this.builder);
|
|
116
105
|
}
|
|
117
106
|
async updateFile(fileName, content) {
|
|
118
107
|
const normalized = this.normalize(fileName);
|
|
@@ -132,18 +121,13 @@ class CompilerContext {
|
|
|
132
121
|
this.rebuild();
|
|
133
122
|
}
|
|
134
123
|
getProgram() {
|
|
135
|
-
return this.builder
|
|
136
|
-
.getProgram();
|
|
124
|
+
return this.builder.getProgram();
|
|
137
125
|
}
|
|
138
126
|
getChecker() {
|
|
139
|
-
return this.builder
|
|
140
|
-
.getProgram()
|
|
141
|
-
.getTypeChecker();
|
|
127
|
+
return this.builder.getProgram().getTypeChecker();
|
|
142
128
|
}
|
|
143
129
|
getSourceFile(fileName) {
|
|
144
|
-
return this.builder
|
|
145
|
-
.getProgram()
|
|
146
|
-
.getSourceFile(this.normalize(fileName));
|
|
130
|
+
return this.builder.getProgram().getSourceFile(this.normalize(fileName));
|
|
147
131
|
}
|
|
148
132
|
getSemanticDiagnostics(fileName) {
|
|
149
133
|
const program = this.builder.getProgram();
|
|
@@ -161,9 +145,7 @@ class CompilerContext {
|
|
|
161
145
|
}
|
|
162
146
|
resolveModule(moduleName, fromFile) {
|
|
163
147
|
const resolved = typescript_1.default.resolveModuleName(moduleName, this.normalize(fromFile), this.compilerOptions, this.host);
|
|
164
|
-
return resolved
|
|
165
|
-
.resolvedModule
|
|
166
|
-
?.resolvedFileName;
|
|
148
|
+
return resolved.resolvedModule?.resolvedFileName;
|
|
167
149
|
}
|
|
168
150
|
getResolvedModules(fileName) {
|
|
169
151
|
const source = this.getSourceFile(fileName);
|
|
@@ -172,13 +154,11 @@ class CompilerContext {
|
|
|
172
154
|
}
|
|
173
155
|
const modules = new Set();
|
|
174
156
|
for (const statement of source.statements) {
|
|
175
|
-
if (!typescript_1.default.isImportDeclaration(statement)
|
|
176
|
-
&& !typescript_1.default.isExportDeclaration(statement)) {
|
|
157
|
+
if (!typescript_1.default.isImportDeclaration(statement) && !typescript_1.default.isExportDeclaration(statement)) {
|
|
177
158
|
continue;
|
|
178
159
|
}
|
|
179
160
|
const specifier = statement.moduleSpecifier;
|
|
180
|
-
if (!specifier
|
|
181
|
-
|| !typescript_1.default.isStringLiteral(specifier)) {
|
|
161
|
+
if (!specifier || !typescript_1.default.isStringLiteral(specifier)) {
|
|
182
162
|
continue;
|
|
183
163
|
}
|
|
184
164
|
const resolved = this.resolveModule(specifier.text, source.fileName);
|
|
@@ -192,10 +172,7 @@ class CompilerContext {
|
|
|
192
172
|
];
|
|
193
173
|
}
|
|
194
174
|
getAllSourceFiles() {
|
|
195
|
-
return this.builder
|
|
196
|
-
.getProgram()
|
|
197
|
-
.getSourceFiles()
|
|
198
|
-
.filter(sf => !sf.isDeclarationFile);
|
|
175
|
+
return this.builder.getProgram().getSourceFiles().filter(sf => !sf.isDeclarationFile);
|
|
199
176
|
}
|
|
200
177
|
getRealFileName(fileName) {
|
|
201
178
|
return fileName;
|
|
@@ -10,8 +10,7 @@ const typescript_1 = __importDefault(require("typescript"));
|
|
|
10
10
|
class DocumentRegistry {
|
|
11
11
|
documents = new Map();
|
|
12
12
|
normalize(fileName) {
|
|
13
|
-
return path_1.default.resolve(fileName)
|
|
14
|
-
.replace(/\\/g, "/");
|
|
13
|
+
return path_1.default.resolve(fileName).replace(/\\/g, "/");
|
|
15
14
|
}
|
|
16
15
|
has(fileName) {
|
|
17
16
|
return this.documents.has(this.normalize(fileName));
|
|
@@ -26,28 +25,19 @@ class DocumentRegistry {
|
|
|
26
25
|
return this.get(fileName)?.snapshot;
|
|
27
26
|
}
|
|
28
27
|
getVersion(fileName) {
|
|
29
|
-
return (this.get(fileName)
|
|
30
|
-
?.version
|
|
31
|
-
.toString()
|
|
32
|
-
?? "0");
|
|
28
|
+
return (this.get(fileName)?.version.toString() ?? "0");
|
|
33
29
|
}
|
|
34
30
|
update(fileName, content) {
|
|
35
31
|
const normalized = this.normalize(fileName);
|
|
36
32
|
const existing = this.documents.get(normalized);
|
|
37
|
-
|
|
38
|
-
// avoid snapshot churn
|
|
39
|
-
if (existing &&
|
|
40
|
-
existing.content === content) {
|
|
33
|
+
if (existing && existing.content === content) {
|
|
41
34
|
return;
|
|
42
35
|
}
|
|
43
36
|
this.documents.set(normalized, {
|
|
44
37
|
fileName: normalized,
|
|
45
38
|
content,
|
|
46
|
-
version: existing
|
|
47
|
-
|
|
48
|
-
: 1,
|
|
49
|
-
snapshot: typescript_1.default.ScriptSnapshot
|
|
50
|
-
.fromString(content),
|
|
39
|
+
version: existing ? existing.version + 1 : 1,
|
|
40
|
+
snapshot: typescript_1.default.ScriptSnapshot.fromString(content)
|
|
51
41
|
});
|
|
52
42
|
}
|
|
53
43
|
ensure(fileName) {
|
|
@@ -8,8 +8,7 @@ class ImportGraph {
|
|
|
8
8
|
// import -> importers
|
|
9
9
|
reverse = new Map();
|
|
10
10
|
updateFile(file, nextImports) {
|
|
11
|
-
const previous = this.imports.get(file)
|
|
12
|
-
?? new Set();
|
|
11
|
+
const previous = this.imports.get(file) ?? new Set();
|
|
13
12
|
const next = new Set(nextImports);
|
|
14
13
|
// remove old edges
|
|
15
14
|
for (const imported of previous) {
|
|
@@ -19,8 +18,7 @@ class ImportGraph {
|
|
|
19
18
|
const reverseImporters = this.reverse.get(imported);
|
|
20
19
|
if (reverseImporters) {
|
|
21
20
|
reverseImporters.delete(file);
|
|
22
|
-
if (reverseImporters.size
|
|
23
|
-
=== 0) {
|
|
21
|
+
if (reverseImporters.size === 0) {
|
|
24
22
|
this.reverse.delete(imported);
|
|
25
23
|
}
|
|
26
24
|
}
|
|
@@ -32,8 +30,7 @@ class ImportGraph {
|
|
|
32
30
|
}
|
|
33
31
|
let importers = this.reverse.get(imported);
|
|
34
32
|
if (!importers) {
|
|
35
|
-
importers =
|
|
36
|
-
new Set();
|
|
33
|
+
importers = new Set();
|
|
37
34
|
this.reverse.set(imported, importers);
|
|
38
35
|
}
|
|
39
36
|
importers.add(file);
|
|
@@ -47,8 +44,7 @@ class ImportGraph {
|
|
|
47
44
|
const importers = this.reverse.get(imported);
|
|
48
45
|
if (importers) {
|
|
49
46
|
importers.delete(file);
|
|
50
|
-
if (importers.size
|
|
51
|
-
=== 0) {
|
|
47
|
+
if (importers.size === 0) {
|
|
52
48
|
this.reverse.delete(imported);
|
|
53
49
|
}
|
|
54
50
|
}
|
|
@@ -13,9 +13,7 @@ class Scheduler {
|
|
|
13
13
|
this.pending.set(fileName, content);
|
|
14
14
|
if (!this.scheduled) {
|
|
15
15
|
this.scheduled = true;
|
|
16
|
-
this.currentFlush =
|
|
17
|
-
Promise.resolve()
|
|
18
|
-
.then(() => this.run());
|
|
16
|
+
this.currentFlush = Promise.resolve().then(() => this.run());
|
|
19
17
|
}
|
|
20
18
|
await this.currentFlush;
|
|
21
19
|
}
|
package/dist/config/config.js
CHANGED
|
@@ -10,29 +10,22 @@ exports.saveConfig = saveConfig;
|
|
|
10
10
|
const fs_extra_1 = __importDefault(require("fs-extra"));
|
|
11
11
|
const path_1 = __importDefault(require("path"));
|
|
12
12
|
exports.CONFIG_NAME = "eventra.json";
|
|
13
|
+
const DEFAULT_INCLUDE = ["**/*.{ts,tsx,js,jsx}"];
|
|
14
|
+
const DEFAULT_EXCLUDE = ["node_modules", "dist", ".next", ".git"];
|
|
13
15
|
function normalizeConfig(config) {
|
|
14
16
|
return {
|
|
15
17
|
apiKey: config.apiKey ?? "",
|
|
16
|
-
events: config.events ?? [],
|
|
17
18
|
endpoint: config.endpoint ?? "",
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
],
|
|
24
|
-
exclude: [
|
|
25
|
-
"node_modules",
|
|
26
|
-
"dist",
|
|
27
|
-
".next",
|
|
28
|
-
".git"
|
|
29
|
-
]
|
|
30
|
-
}
|
|
19
|
+
events: config.events ?? [],
|
|
20
|
+
sync: {
|
|
21
|
+
include: config.sync?.include ?? DEFAULT_INCLUDE,
|
|
22
|
+
exclude: config.sync?.exclude ?? DEFAULT_EXCLUDE,
|
|
23
|
+
},
|
|
31
24
|
};
|
|
32
25
|
}
|
|
33
26
|
async function loadConfig() {
|
|
34
27
|
const configPath = path_1.default.join(process.cwd(), exports.CONFIG_NAME);
|
|
35
|
-
if (!
|
|
28
|
+
if (!await fs_extra_1.default.pathExists(configPath)) {
|
|
36
29
|
return null;
|
|
37
30
|
}
|
|
38
31
|
try {
|
|
@@ -45,8 +38,5 @@ async function loadConfig() {
|
|
|
45
38
|
}
|
|
46
39
|
async function saveConfig(config) {
|
|
47
40
|
const configPath = path_1.default.join(process.cwd(), exports.CONFIG_NAME);
|
|
48
|
-
|
|
49
|
-
await fs_extra_1.default.writeJSON(configPath, normalized, {
|
|
50
|
-
spaces: 2
|
|
51
|
-
});
|
|
41
|
+
await fs_extra_1.default.writeJSON(configPath, normalizeConfig(config), { spaces: 2 });
|
|
52
42
|
}
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
// src/engine/engine.ts
|
|
3
2
|
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
4
3
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
5
4
|
};
|
|
@@ -13,6 +12,7 @@ const importGraph_1 = require("../compiler/importGraph");
|
|
|
13
12
|
const evaluationCache_1 = require("../analysis/cache/evaluationCache");
|
|
14
13
|
const resolvedCallCache_1 = require("../analysis/cache/resolvedCallCache");
|
|
15
14
|
const resolvedExportCache_1 = require("../analysis/cache/resolvedExportCache");
|
|
15
|
+
const returnPropagationCache_1 = require("../analysis/cache/returnPropagationCache");
|
|
16
16
|
const symbolInvalidation_1 = require("../analysis/cache/symbolInvalidation");
|
|
17
17
|
const scanner_1 = require("../analysis/scanner/scanner");
|
|
18
18
|
const extractor_1 = require("../analysis/extractor/extractor");
|
|
@@ -20,7 +20,6 @@ const wrapperRegistry_1 = require("../analysis/symbols/wrapperRegistry");
|
|
|
20
20
|
const EMPTY_RESULT = () => ({
|
|
21
21
|
events: new Set(),
|
|
22
22
|
detectedFunctionWrappers: new Set(),
|
|
23
|
-
detectedComponentWrappers: new Map(),
|
|
24
23
|
});
|
|
25
24
|
class EventraEngine {
|
|
26
25
|
compiler;
|
|
@@ -28,6 +27,7 @@ class EventraEngine {
|
|
|
28
27
|
importGraph = new importGraph_1.ImportGraph();
|
|
29
28
|
evaluationCache = new evaluationCache_1.EvaluationCache();
|
|
30
29
|
resolvedCallCache = new resolvedCallCache_1.ResolvedCallCache();
|
|
30
|
+
returnPropagationCache = new returnPropagationCache_1.ReturnPropagationCache();
|
|
31
31
|
resolvedExportCache = new resolvedExportCache_1.ResolvedExportCache();
|
|
32
32
|
wrapperRegistry;
|
|
33
33
|
fileResults = new Map();
|
|
@@ -35,83 +35,50 @@ class EventraEngine {
|
|
|
35
35
|
isPreloading = false;
|
|
36
36
|
lastConfig = {
|
|
37
37
|
events: [],
|
|
38
|
-
wrappers: [],
|
|
39
|
-
functionWrappers: [],
|
|
40
38
|
sync: {
|
|
41
39
|
include: [],
|
|
42
40
|
exclude: [],
|
|
43
41
|
},
|
|
44
42
|
};
|
|
45
43
|
constructor(rootDir) {
|
|
46
|
-
this.compiler =
|
|
47
|
-
|
|
48
|
-
this.
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
for (const [file, content] of updates) {
|
|
55
|
-
//
|
|
56
|
-
// SYMBOL INVALIDATION
|
|
57
|
-
//
|
|
58
|
-
const existing = this.compiler.getSourceFile(file);
|
|
59
|
-
if (existing) {
|
|
60
|
-
(0, symbolInvalidation_1.invalidateSourceFileSymbols)(existing, this.compiler.getChecker(), this.evaluationCache, this.resolvedCallCache, this.resolvedExportCache);
|
|
61
|
-
}
|
|
62
|
-
//
|
|
63
|
-
// UPDATE FILE
|
|
64
|
-
//
|
|
65
|
-
await this.compiler.updateFile(file, content);
|
|
66
|
-
//
|
|
67
|
-
// UPDATE IMPORT GRAPH
|
|
68
|
-
//
|
|
69
|
-
this.updateImportGraph(file);
|
|
44
|
+
this.compiler = new compilerContext_1.CompilerContext(rootDir);
|
|
45
|
+
this.wrapperRegistry = new wrapperRegistry_1.WrapperRegistry(this.compiler.getChecker(), this.resolvedExportCache);
|
|
46
|
+
this.scheduler = new scheduler_1.Scheduler(async (updates) => {
|
|
47
|
+
// APPLY UPDATES
|
|
48
|
+
for (const [file, content] of updates) {
|
|
49
|
+
const existing = this.compiler.getSourceFile(file);
|
|
50
|
+
if (existing) {
|
|
51
|
+
(0, symbolInvalidation_1.invalidateSourceFileSymbols)(existing, this.compiler.getChecker(), this.evaluationCache, this.resolvedCallCache, this.resolvedExportCache, this.returnPropagationCache, this.wrapperRegistry);
|
|
70
52
|
}
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
}
|
|
81
|
-
}
|
|
82
|
-
//
|
|
83
|
-
// RE-ANALYZE
|
|
84
|
-
//
|
|
85
|
-
for (const file of affected) {
|
|
86
|
-
this.analyzeFile(file, this.lastConfig);
|
|
53
|
+
await this.compiler.updateFile(file, content);
|
|
54
|
+
this.updateImportGraph(file);
|
|
55
|
+
}
|
|
56
|
+
// COLLECT AFFECTED FILES
|
|
57
|
+
const affected = new Set();
|
|
58
|
+
for (const file of updates.keys()) {
|
|
59
|
+
const dependents = this.importGraph.collectDependents(file);
|
|
60
|
+
for (const dependent of dependents) {
|
|
61
|
+
affected.add(dependent);
|
|
87
62
|
}
|
|
88
|
-
}
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
.clear();
|
|
95
|
-
this.resolvedExportCache
|
|
96
|
-
.clear();
|
|
97
|
-
this.wrapperRegistry
|
|
98
|
-
.clear();
|
|
63
|
+
}
|
|
64
|
+
// RE-ANALYZE
|
|
65
|
+
for (const file of affected) {
|
|
66
|
+
this.analyzeFile(file, this.lastConfig);
|
|
67
|
+
}
|
|
68
|
+
});
|
|
99
69
|
}
|
|
100
70
|
beginPreload() {
|
|
101
|
-
this.isPreloading =
|
|
102
|
-
true;
|
|
71
|
+
this.isPreloading = true;
|
|
103
72
|
}
|
|
104
73
|
endPreload() {
|
|
105
|
-
this.isPreloading =
|
|
106
|
-
false;
|
|
74
|
+
this.isPreloading = false;
|
|
107
75
|
}
|
|
108
76
|
normalize(fileName) {
|
|
109
77
|
const cached = this.normalizedPathCache.get(fileName);
|
|
110
78
|
if (cached) {
|
|
111
79
|
return cached;
|
|
112
80
|
}
|
|
113
|
-
const normalized = path_1.default.resolve(fileName)
|
|
114
|
-
.replace(/\\/g, "/");
|
|
81
|
+
const normalized = path_1.default.resolve(fileName).replace(/\\/g, "/");
|
|
115
82
|
this.normalizedPathCache.set(fileName, normalized);
|
|
116
83
|
return normalized;
|
|
117
84
|
}
|
|
@@ -127,16 +94,14 @@ class EventraEngine {
|
|
|
127
94
|
if (typescript_1.default.isExportAssignment(statement)) {
|
|
128
95
|
continue;
|
|
129
96
|
}
|
|
130
|
-
if (!typescript_1.default.isImportDeclaration(statement)
|
|
131
|
-
&& !typescript_1.default.isExportDeclaration(statement)) {
|
|
97
|
+
if (!typescript_1.default.isImportDeclaration(statement) && !typescript_1.default.isExportDeclaration(statement)) {
|
|
132
98
|
continue;
|
|
133
99
|
}
|
|
134
100
|
const specifier = statement.moduleSpecifier;
|
|
135
|
-
if (!specifier
|
|
136
|
-
|| !typescript_1.default.isStringLiteral(specifier)) {
|
|
101
|
+
if (!specifier || !typescript_1.default.isStringLiteral(specifier)) {
|
|
137
102
|
continue;
|
|
138
103
|
}
|
|
139
|
-
const resolved = this.compiler.resolveModule(specifier.text,
|
|
104
|
+
const resolved = this.compiler.resolveModule(specifier.text, source.fileName);
|
|
140
105
|
if (!resolved) {
|
|
141
106
|
continue;
|
|
142
107
|
}
|
|
@@ -152,8 +117,8 @@ class EventraEngine {
|
|
|
152
117
|
return EMPTY_RESULT();
|
|
153
118
|
}
|
|
154
119
|
const checker = this.compiler.getChecker();
|
|
155
|
-
const index = (0, scanner_1.scanSource)(source, checker,
|
|
156
|
-
const result = (0, extractor_1.extractEvents)(index, checker, config, this.evaluationCache, this.resolvedExportCache, this.resolvedCallCache, this.wrapperRegistry);
|
|
120
|
+
const index = (0, scanner_1.scanSource)(source, checker, this.wrapperRegistry);
|
|
121
|
+
const result = (0, extractor_1.extractEvents)(index, checker, config, this.evaluationCache, this.resolvedExportCache, this.resolvedCallCache, this.returnPropagationCache, this.wrapperRegistry);
|
|
157
122
|
this.fileResults.set(normalized, result);
|
|
158
123
|
return result;
|
|
159
124
|
}
|
|
@@ -166,40 +131,23 @@ class EventraEngine {
|
|
|
166
131
|
this.updateImportGraph(normalized);
|
|
167
132
|
}
|
|
168
133
|
async updateFile(fileName, content, config) {
|
|
169
|
-
this.lastConfig =
|
|
170
|
-
config;
|
|
134
|
+
this.lastConfig = config;
|
|
171
135
|
const normalized = this.normalize(fileName);
|
|
172
136
|
await this.scheduler.enqueue(normalized, content);
|
|
173
137
|
}
|
|
174
138
|
scanFile(fileName, config) {
|
|
175
|
-
this.lastConfig =
|
|
176
|
-
config;
|
|
139
|
+
this.lastConfig = config;
|
|
177
140
|
return this.analyzeFile(fileName, config);
|
|
178
141
|
}
|
|
179
|
-
async syncFile(fileName, content, config) {
|
|
180
|
-
this.lastConfig =
|
|
181
|
-
config;
|
|
182
|
-
const normalized = this.normalize(fileName);
|
|
183
|
-
const existing = this.compiler.getSourceFile(normalized);
|
|
184
|
-
if (existing) {
|
|
185
|
-
(0, symbolInvalidation_1.invalidateSourceFileSymbols)(existing, this.compiler.getChecker(), this.evaluationCache, this.resolvedCallCache, this.resolvedExportCache);
|
|
186
|
-
}
|
|
187
|
-
await this.compiler.updateFile(normalized, content);
|
|
188
|
-
this.updateImportGraph(normalized);
|
|
189
|
-
return this.analyzeFile(normalized, config);
|
|
190
|
-
}
|
|
191
142
|
async removeFile(fileName, config) {
|
|
192
143
|
const normalized = this.normalize(fileName);
|
|
193
|
-
this.
|
|
194
|
-
const affected = this.importGraph
|
|
195
|
-
.collectDependents(normalized);
|
|
144
|
+
const affected = this.importGraph.collectDependents(normalized);
|
|
196
145
|
this.importGraph.removeFile(normalized);
|
|
197
146
|
this.compiler.removeFile(normalized);
|
|
198
147
|
this.fileResults.delete(normalized);
|
|
199
148
|
this.normalizedPathCache.delete(fileName);
|
|
200
149
|
this.normalizedPathCache.delete(normalized);
|
|
201
|
-
const nextConfig = config
|
|
202
|
-
?? this.lastConfig;
|
|
150
|
+
const nextConfig = config ?? this.lastConfig;
|
|
203
151
|
for (const file of affected) {
|
|
204
152
|
if (file === normalized) {
|
|
205
153
|
continue;
|
|
@@ -207,10 +155,6 @@ class EventraEngine {
|
|
|
207
155
|
this.analyzeFile(file, nextConfig);
|
|
208
156
|
}
|
|
209
157
|
}
|
|
210
|
-
getResult(fileName) {
|
|
211
|
-
return (this.fileResults.get(this.normalize(fileName))
|
|
212
|
-
?? EMPTY_RESULT());
|
|
213
|
-
}
|
|
214
158
|
getAllEvents() {
|
|
215
159
|
const events = new Set();
|
|
216
160
|
for (const result of this.fileResults.values()) {
|
|
@@ -222,13 +166,5 @@ class EventraEngine {
|
|
|
222
166
|
...events,
|
|
223
167
|
].sort();
|
|
224
168
|
}
|
|
225
|
-
getDiagnostics(fileName) {
|
|
226
|
-
return this.compiler
|
|
227
|
-
.getSemanticDiagnostics(fileName);
|
|
228
|
-
}
|
|
229
|
-
invalidate() {
|
|
230
|
-
this.invalidateCaches();
|
|
231
|
-
this.fileResults.clear();
|
|
232
|
-
}
|
|
233
169
|
}
|
|
234
170
|
exports.EventraEngine = EventraEngine;
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
// src/core/projectScanner.ts
|
|
3
2
|
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
4
3
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
5
4
|
};
|
|
@@ -33,8 +32,7 @@ async function scanProject(config) {
|
|
|
33
32
|
for (const file of files) {
|
|
34
33
|
try {
|
|
35
34
|
const raw = await promises_1.default.readFile(file, "utf8");
|
|
36
|
-
if (raw.length
|
|
37
|
-
> 2_000_000) {
|
|
35
|
+
if (raw.length > 2_000_000) {
|
|
38
36
|
continue;
|
|
39
37
|
}
|
|
40
38
|
const parsed = await (0, processFile_1.processFile)(file, raw);
|
|
@@ -44,7 +42,8 @@ async function scanProject(config) {
|
|
|
44
42
|
toScan.add(path_1.default.resolve(path_1.default.dirname(file), dep));
|
|
45
43
|
}
|
|
46
44
|
}
|
|
47
|
-
catch {
|
|
45
|
+
catch {
|
|
46
|
+
}
|
|
48
47
|
}
|
|
49
48
|
// PRELOAD
|
|
50
49
|
engine.beginPreload();
|
|
@@ -53,7 +52,8 @@ async function scanProject(config) {
|
|
|
53
52
|
const parsed = await getParsedFile(file, cache);
|
|
54
53
|
await engine.preloadFile((0, getVirtualFile_1.getVirtualFile)(file), parsed.content);
|
|
55
54
|
}
|
|
56
|
-
catch {
|
|
55
|
+
catch {
|
|
56
|
+
}
|
|
57
57
|
}
|
|
58
58
|
engine.endPreload();
|
|
59
59
|
// SCAN
|
|
@@ -63,7 +63,8 @@ async function scanProject(config) {
|
|
|
63
63
|
const result = engine.scanFile((0, getVirtualFile_1.getVirtualFile)(file), config);
|
|
64
64
|
results.set(file, result);
|
|
65
65
|
}
|
|
66
|
-
catch {
|
|
66
|
+
catch {
|
|
67
|
+
}
|
|
67
68
|
}
|
|
68
69
|
return {
|
|
69
70
|
engine,
|
|
@@ -22,10 +22,7 @@ async function processFile(fileName, content) {
|
|
|
22
22
|
const source = typescript_1.default.createSourceFile(fileName, content, typescript_1.default.ScriptTarget.Latest, true, scriptKind);
|
|
23
23
|
const dependencies = [];
|
|
24
24
|
for (const statement of source.statements) {
|
|
25
|
-
if ((typescript_1.default.isImportDeclaration(statement)
|
|
26
|
-
|| typescript_1.default.isExportDeclaration(statement))
|
|
27
|
-
&& statement.moduleSpecifier
|
|
28
|
-
&& typescript_1.default.isStringLiteral(statement.moduleSpecifier)) {
|
|
25
|
+
if ((typescript_1.default.isImportDeclaration(statement) || typescript_1.default.isExportDeclaration(statement)) && statement.moduleSpecifier && typescript_1.default.isStringLiteral(statement.moduleSpecifier)) {
|
|
29
26
|
dependencies.push(statement.moduleSpecifier.text);
|
|
30
27
|
}
|
|
31
28
|
}
|
|
@@ -4,8 +4,7 @@ exports.buildSyntheticTsx = buildSyntheticTsx;
|
|
|
4
4
|
const templateExpressionExtractor_1 = require("./templateExpressionExtractor");
|
|
5
5
|
function buildSyntheticTsx(template) {
|
|
6
6
|
const expressions = (0, templateExpressionExtractor_1.extractTemplateExpressions)(template);
|
|
7
|
-
const body = expressions
|
|
8
|
-
.map((expression, index) => {
|
|
7
|
+
const body = expressions.map((expression, index) => {
|
|
9
8
|
return `
|
|
10
9
|
const __eventra_expr_${index} =
|
|
11
10
|
(() => (${expression}))();
|
package/package.json
CHANGED
|
@@ -1,25 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.SemanticDependencyGraph = void 0;
|
|
4
|
-
class SemanticDependencyGraph {
|
|
5
|
-
dependencies = new Map();
|
|
6
|
-
addDependency(from, to) {
|
|
7
|
-
let deps = this.dependencies.get(from);
|
|
8
|
-
if (!deps) {
|
|
9
|
-
deps =
|
|
10
|
-
new Set();
|
|
11
|
-
this.dependencies.set(from, deps);
|
|
12
|
-
}
|
|
13
|
-
deps.add(to);
|
|
14
|
-
}
|
|
15
|
-
getDependents(file) {
|
|
16
|
-
const result = new Set();
|
|
17
|
-
for (const [from, deps,] of this.dependencies) {
|
|
18
|
-
if (deps.has(file)) {
|
|
19
|
-
result.add(from);
|
|
20
|
-
}
|
|
21
|
-
}
|
|
22
|
-
return result;
|
|
23
|
-
}
|
|
24
|
-
}
|
|
25
|
-
exports.SemanticDependencyGraph = SemanticDependencyGraph;
|