@travetto/compiler 6.0.0 → 6.0.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/package.json +4 -4
- package/src/compiler.ts +41 -3
- package/src/types.ts +1 -1
- package/src/watch.ts +2 -1
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@travetto/compiler",
|
|
3
|
-
"version": "6.0.
|
|
3
|
+
"version": "6.0.2",
|
|
4
4
|
"description": "The compiler infrastructure for the Travetto framework",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"compiler",
|
|
@@ -30,11 +30,11 @@
|
|
|
30
30
|
},
|
|
31
31
|
"dependencies": {
|
|
32
32
|
"@parcel/watcher": "^2.5.1",
|
|
33
|
-
"@travetto/manifest": "^6.0.
|
|
34
|
-
"@travetto/transformer": "^6.0.
|
|
33
|
+
"@travetto/manifest": "^6.0.1",
|
|
34
|
+
"@travetto/transformer": "^6.0.1"
|
|
35
35
|
},
|
|
36
36
|
"peerDependencies": {
|
|
37
|
-
"@travetto/cli": "^6.0.
|
|
37
|
+
"@travetto/cli": "^6.0.1"
|
|
38
38
|
},
|
|
39
39
|
"peerDependenciesMeta": {
|
|
40
40
|
"@travetto/cli": {
|
package/src/compiler.ts
CHANGED
|
@@ -87,6 +87,32 @@ export class Compiler {
|
|
|
87
87
|
CommonUtil.nonBlockingTimeout(1000).then(() => process.exit()); // Allow upto 1s to shutdown gracefully
|
|
88
88
|
}
|
|
89
89
|
|
|
90
|
+
/**
|
|
91
|
+
* Log compilation statistics
|
|
92
|
+
*/
|
|
93
|
+
logStatistics(metrics: CompileEmitEvent[]): void {
|
|
94
|
+
// Simple metrics
|
|
95
|
+
const durations = metrics.map(x => x.duration);
|
|
96
|
+
const total = durations.reduce((a, b) => a + b, 0);
|
|
97
|
+
const avg = total / durations.length;
|
|
98
|
+
const sorted = [...durations].sort((a, b) => a - b);
|
|
99
|
+
const median = sorted[Math.trunc(sorted.length / 2)];
|
|
100
|
+
|
|
101
|
+
// Find the 5 slowest files
|
|
102
|
+
const slowest = [...metrics]
|
|
103
|
+
.sort((a, b) => b.duration - a.duration)
|
|
104
|
+
.slice(0, 5)
|
|
105
|
+
.map(x => ({ file: x.file, duration: x.duration }));
|
|
106
|
+
|
|
107
|
+
log.debug('Compilation Statistics', {
|
|
108
|
+
files: metrics.length,
|
|
109
|
+
totalTime: total,
|
|
110
|
+
averageTime: Math.round(avg),
|
|
111
|
+
medianTime: median,
|
|
112
|
+
slowest
|
|
113
|
+
});
|
|
114
|
+
}
|
|
115
|
+
|
|
90
116
|
/**
|
|
91
117
|
* Compile in a single pass, only emitting dirty files
|
|
92
118
|
*/
|
|
@@ -101,10 +127,16 @@ export class Compiler {
|
|
|
101
127
|
let i = 0;
|
|
102
128
|
let lastSent = Date.now();
|
|
103
129
|
|
|
130
|
+
await emitter(files[0]); // Prime
|
|
131
|
+
|
|
104
132
|
for (const file of files) {
|
|
133
|
+
const start = Date.now();
|
|
105
134
|
const err = await emitter(file);
|
|
106
|
-
const
|
|
107
|
-
|
|
135
|
+
const duration = Date.now() - start;
|
|
136
|
+
const nodeModSep = 'node_modules/';
|
|
137
|
+
const nodeModIdx = file.lastIndexOf(nodeModSep);
|
|
138
|
+
const imp = nodeModIdx >= 0 ? file.substring(nodeModIdx + nodeModSep.length) : file;
|
|
139
|
+
yield { file: imp, i: i += 1, err, total: files.length, duration };
|
|
108
140
|
if ((Date.now() - lastSent) > 50) { // Limit to 1 every 50ms
|
|
109
141
|
lastSent = Date.now();
|
|
110
142
|
EventUtil.sendEvent('progress', { total: files.length, idx: i, message: imp, operation: 'compile' });
|
|
@@ -135,6 +167,8 @@ export class Compiler {
|
|
|
135
167
|
|
|
136
168
|
EventUtil.sendEvent('state', { state: 'compile-start' });
|
|
137
169
|
|
|
170
|
+
const metrics: CompileEmitEvent[] = [];
|
|
171
|
+
|
|
138
172
|
if (this.#dirtyFiles.length) {
|
|
139
173
|
for await (const ev of this.emit(this.#dirtyFiles, emitter)) {
|
|
140
174
|
if (ev.err) {
|
|
@@ -142,6 +176,7 @@ export class Compiler {
|
|
|
142
176
|
failure ??= compileError;
|
|
143
177
|
EventUtil.sendEvent('log', { level: 'error', message: compileError.toString(), time: Date.now() });
|
|
144
178
|
}
|
|
179
|
+
metrics.push(ev);
|
|
145
180
|
}
|
|
146
181
|
if (this.#signal.aborted) {
|
|
147
182
|
log.debug('Compilation aborted');
|
|
@@ -159,6 +194,10 @@ export class Compiler {
|
|
|
159
194
|
|
|
160
195
|
EventUtil.sendEvent('state', { state: 'compile-end' });
|
|
161
196
|
|
|
197
|
+
if (process.env.TRV_BUILD === 'debug' && metrics.length) {
|
|
198
|
+
this.logStatistics(metrics);
|
|
199
|
+
}
|
|
200
|
+
|
|
162
201
|
if (this.#watch && !this.#signal.aborted) {
|
|
163
202
|
log.info('Watch is ready');
|
|
164
203
|
|
|
@@ -190,7 +229,6 @@ export class Compiler {
|
|
|
190
229
|
});
|
|
191
230
|
}
|
|
192
231
|
EventUtil.sendEvent('state', { state: 'watch-end' });
|
|
193
|
-
|
|
194
232
|
} catch (err) {
|
|
195
233
|
if (err instanceof Error) {
|
|
196
234
|
this.#shutdown(err instanceof CompilerReset ? 'reset' : 'error', err);
|
package/src/types.ts
CHANGED
|
@@ -4,7 +4,7 @@ import type { ManifestModule } from '@travetto/manifest';
|
|
|
4
4
|
|
|
5
5
|
export type CompileEmitError = Error | readonly ts.Diagnostic[];
|
|
6
6
|
export type CompileEmitter = (file: string, newProgram?: boolean) => Promise<CompileEmitError | undefined>;
|
|
7
|
-
export type CompileEmitEvent = { file: string, i: number, total: number, err?: CompileEmitError };
|
|
7
|
+
export type CompileEmitEvent = { file: string, i: number, total: number, err?: CompileEmitError, duration: number };
|
|
8
8
|
export type CompileStateEntry = { sourceFile: string, tscOutputFile: string, outputFile?: string, module: ManifestModule };
|
|
9
9
|
export type CompilerWatchEvent = { action: 'create' | 'update' | 'delete', file: string, entry: CompileStateEntry };
|
|
10
10
|
export class CompilerReset extends Error { }
|
package/src/watch.ts
CHANGED
|
@@ -117,13 +117,14 @@ export class CompilerWatcher {
|
|
|
117
117
|
const relativeFile = file.includes(moduleRoot) ? file.split(`${moduleRoot}/`)[1] : file;
|
|
118
118
|
const folderKey = ManifestModuleUtil.getFolderKey(relativeFile);
|
|
119
119
|
const fileType = ManifestModuleUtil.getFileType(relativeFile);
|
|
120
|
+
const roleType = ManifestModuleUtil.getFileRole(relativeFile)!;
|
|
120
121
|
|
|
121
122
|
const manifestModuleFiles = manifest.modules[moduleName].files[folderKey] ??= [];
|
|
122
123
|
const idx = manifestModuleFiles.findIndex(x => x[0] === relativeFile);
|
|
123
124
|
const wrappedIdx = idx < 0 ? manifestModuleFiles.length : idx;
|
|
124
125
|
|
|
125
126
|
switch (action) {
|
|
126
|
-
case 'create': manifestModuleFiles[wrappedIdx] = [relativeFile, fileType, Date.now()]; break;
|
|
127
|
+
case 'create': manifestModuleFiles[wrappedIdx] = [relativeFile, fileType, Date.now(), roleType]; break;
|
|
127
128
|
case 'delete': idx >= 0 && manifestModuleFiles.splice(idx, 1); break;
|
|
128
129
|
}
|
|
129
130
|
}
|