@travetto/compiler 3.4.4 → 4.0.0-rc.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/README.md +29 -27
- package/bin/common.js +51 -46
- package/bin/trvc.js +21 -14
- package/package.json +6 -7
- package/src/compiler.ts +96 -43
- package/src/event.ts +3 -3
- package/src/log.ts +1 -1
- package/src/state.ts +43 -25
- package/src/types.ts +1 -1
- package/src/util.ts +6 -6
- package/src/watch.ts +107 -117
- package/support/entry.trvc.ts +67 -37
- package/support/log.ts +55 -24
- package/support/queue.ts +11 -6
- package/support/server/client.ts +122 -81
- package/support/server/process-handle.ts +57 -0
- package/support/server/runner.ts +37 -64
- package/support/server/server.ts +86 -58
- package/support/setup.ts +38 -36
- package/support/types.ts +3 -4
- package/support/util.ts +20 -25
- package/src/internal/watch-core.ts +0 -104
package/README.md
CHANGED
|
@@ -30,7 +30,8 @@ The compiler cli supports the following operations:
|
|
|
30
30
|
* `build` - Ensure the project is built and upto date
|
|
31
31
|
* `clean` - Clean out the output and compiler caches
|
|
32
32
|
* `info` - Retrieve the compiler information, if running
|
|
33
|
-
* `
|
|
33
|
+
* `event <log|progress|state>` - Watch events in realtime as newline delimited JSON
|
|
34
|
+
* `manifest --prod [output]` - Generate the project manifest
|
|
34
35
|
In addition to the normal output, the compiler supports an environment variable `TRV_BUILD` that supports the following values: `debug`, `info`, `warn` or `none`. This provides different level of logging during the build process which is helpful to diagnose any odd behaviors. When invoking an unknown command (e.g. `<other>` from above), the default level is `warn`. Otherwise the default logging level is `info`.
|
|
35
36
|
|
|
36
37
|
**Terminal: Sample trv output with debug logging**
|
|
@@ -38,34 +39,35 @@ In addition to the normal output, the compiler supports an environment variable
|
|
|
38
39
|
$ TRV_BUILD=debug trvc build
|
|
39
40
|
|
|
40
41
|
2029-03-14T04:00:00.618Z info [compiler-server] Starting server http://127.0.0.1:25539
|
|
41
|
-
2029-03-14T04:00:00.837Z debug [
|
|
42
|
+
2029-03-14T04:00:00.837Z debug [client.main ] Start Server
|
|
42
43
|
2029-03-14T04:00:01.510Z debug [event-stream ] Started event stream
|
|
43
44
|
2029-03-14T04:00:02.450Z debug [precompile ] Started
|
|
44
|
-
2029-03-14T04:00:02.762Z debug [
|
|
45
|
-
2029-03-14T04:00:02.947Z debug [precompile ] Skipped @travetto/
|
|
46
|
-
2029-03-14T04:00:03.093Z debug [precompile ] Skipped @travetto/
|
|
47
|
-
2029-03-14T04:00:04.003Z debug [precompile ]
|
|
48
|
-
2029-03-14T04:00:04.495Z debug [
|
|
49
|
-
2029-03-14T04:00:05.066Z debug [
|
|
50
|
-
2029-03-14T04:00:05.307Z debug [
|
|
51
|
-
2029-03-14T04:00:05.952Z debug [
|
|
52
|
-
2029-03-14T04:00:06.859Z debug [transformers ]
|
|
53
|
-
2029-03-14T04:00:07.720Z debug [transformers ] Skipped @travetto/
|
|
54
|
-
2029-03-14T04:00:08.179Z debug [transformers ] Skipped @travetto/
|
|
55
|
-
2029-03-14T04:00:08.588Z debug [transformers ] Skipped @travetto/
|
|
56
|
-
2029-03-14T04:00:09.493Z debug [transformers ]
|
|
57
|
-
2029-03-14T04:00:10.395Z debug [
|
|
58
|
-
2029-03-14T04:00:10.407Z debug [
|
|
59
|
-
2029-03-14T04:00:10.799Z debug [
|
|
60
|
-
2029-03-14T04:00:11.013Z debug [
|
|
61
|
-
2029-03-14T04:00:11.827Z debug [manifest ]
|
|
62
|
-
2029-03-14T04:00:11.894Z
|
|
63
|
-
2029-03-14T04:00:12.133Z debug [
|
|
64
|
-
2029-03-14T04:00:13.123Z
|
|
65
|
-
2029-03-14T04:00:14.014Z
|
|
66
|
-
2029-03-14T04:00:14.924Z debug [
|
|
67
|
-
2029-03-14T04:00:15.690Z info [compiler-server]
|
|
68
|
-
2029-03-14T04:00:15.865Z debug [compiler-
|
|
45
|
+
2029-03-14T04:00:02.762Z debug [precompile ] Skipped @travetto/manifest
|
|
46
|
+
2029-03-14T04:00:02.947Z debug [precompile ] Skipped @travetto/transformer
|
|
47
|
+
2029-03-14T04:00:03.093Z debug [precompile ] Skipped @travetto/compiler
|
|
48
|
+
2029-03-14T04:00:04.003Z debug [precompile ] Completed
|
|
49
|
+
2029-03-14T04:00:04.495Z debug [manifest ] Started
|
|
50
|
+
2029-03-14T04:00:05.066Z debug [manifest ] Completed
|
|
51
|
+
2029-03-14T04:00:05.307Z debug [transformers ] Started
|
|
52
|
+
2029-03-14T04:00:05.952Z debug [transformers ] Skipped @travetto/base
|
|
53
|
+
2029-03-14T04:00:06.859Z debug [transformers ] Skipped @travetto/cli
|
|
54
|
+
2029-03-14T04:00:07.720Z debug [transformers ] Skipped @travetto/manifest
|
|
55
|
+
2029-03-14T04:00:08.179Z debug [transformers ] Skipped @travetto/registry
|
|
56
|
+
2029-03-14T04:00:08.588Z debug [transformers ] Skipped @travetto/schema
|
|
57
|
+
2029-03-14T04:00:09.493Z debug [transformers ] Completed
|
|
58
|
+
2029-03-14T04:00:10.395Z debug [delta ] Started
|
|
59
|
+
2029-03-14T04:00:10.407Z debug [delta ] Completed
|
|
60
|
+
2029-03-14T04:00:10.799Z debug [manifest ] Started
|
|
61
|
+
2029-03-14T04:00:11.013Z debug [manifest ] Wrote manifest @travetto-doc/compiler
|
|
62
|
+
2029-03-14T04:00:11.827Z debug [manifest ] Completed
|
|
63
|
+
2029-03-14T04:00:11.894Z info [compiler-server] State changed: compile-end
|
|
64
|
+
2029-03-14T04:00:12.133Z debug [compiler-exec ] Skipped
|
|
65
|
+
2029-03-14T04:00:13.123Z debug [event-stream ] Finished event stream
|
|
66
|
+
2029-03-14T04:00:14.014Z info [compiler-server] Closing down server
|
|
67
|
+
2029-03-14T04:00:14.924Z debug [compiler-server] Server close event
|
|
68
|
+
2029-03-14T04:00:15.690Z info [compiler-server] Closed down server
|
|
69
|
+
2029-03-14T04:00:15.865Z debug [compiler-server] Finished processing events
|
|
70
|
+
2029-03-14T04:00:16.757Z debug [client.main ] End Server
|
|
69
71
|
```
|
|
70
72
|
|
|
71
73
|
**Terminal: Sample trv output with default log level**
|
package/bin/common.js
CHANGED
|
@@ -1,55 +1,60 @@
|
|
|
1
1
|
// @ts-check
|
|
2
|
-
|
|
3
|
-
import
|
|
4
|
-
import path from 'path';
|
|
5
|
-
import { createRequire } from 'module';
|
|
2
|
+
import { statSync, readFileSync, writeFileSync, mkdirSync, readdirSync, existsSync, rmSync } from 'node:fs';
|
|
3
|
+
import path from 'node:path';
|
|
6
4
|
|
|
7
5
|
import { getManifestContext } from '@travetto/manifest/bin/context.js';
|
|
8
6
|
|
|
9
|
-
|
|
7
|
+
/** @typedef {import('@travetto/manifest').ManifestContext} Ctx */
|
|
10
8
|
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
const src = path.resolve(compMod, file);
|
|
24
|
-
|
|
25
|
-
const targetTime = await fs.stat(target).then(s => Math.max(s.mtimeMs, s.ctimeMs)).catch(() => 0);
|
|
26
|
-
const srcTime = await fs.stat(src).then(s => Math.max(s.mtimeMs, s.ctimeMs));
|
|
27
|
-
// If stale
|
|
28
|
-
if (srcTime > targetTime) {
|
|
29
|
-
const ts = (await import('typescript')).default;
|
|
30
|
-
const module = ctx.moduleType === 'module' ? ts.ModuleKind.ESNext : ts.ModuleKind.CommonJS;
|
|
31
|
-
await fs.mkdir(path.dirname(target), { recursive: true });
|
|
32
|
-
const text = await fs.readFile(src, 'utf8');
|
|
33
|
-
if (/[.]tsx?$/.test(file)) {
|
|
34
|
-
const content = ts.transpile(
|
|
35
|
-
text,
|
|
36
|
-
{ target: ts.ScriptTarget.ES2022, module, esModuleInterop: true, allowSyntheticDefaultImports: true }
|
|
37
|
-
)
|
|
38
|
-
.replace(/^((?:im|ex)port .*from '[.][^']+)(')/mg, (_, a, b) => `${a}.js${b}`)
|
|
39
|
-
.replace(/^(import [^\n]*from '[^.][^\n/]+[/][^\n/]+[/][^\n']+)(')/mg, (_, a, b) => `${a}.js${b}`);
|
|
40
|
-
await fs.writeFile(target, content, 'utf8');
|
|
41
|
-
} else {
|
|
42
|
-
const pkg = JSON.parse(text);
|
|
43
|
-
pkg.type = ctx.moduleType;
|
|
44
|
-
await fs.writeFile(target, JSON.stringify(pkg, null, 2), 'utf8');
|
|
45
|
-
}
|
|
46
|
-
// Compile
|
|
9
|
+
const TS_EXT = /[.]tsx?$/;
|
|
10
|
+
|
|
11
|
+
const getAge = (/** @type {{mtimeMs:number, ctimeMs:number}} */ st) => Math.max(st.mtimeMs, st.ctimeMs);
|
|
12
|
+
|
|
13
|
+
const getTarget = (/** @type {Ctx} */ ctx, file = '') => ({
|
|
14
|
+
dest: path.resolve(ctx.workspace.path, ctx.build.compilerFolder, 'node_modules', '@travetto/compiler', file).replace(TS_EXT, '.js'),
|
|
15
|
+
src: path.resolve(ctx.workspace.path, ctx.build.compilerModuleFolder, file),
|
|
16
|
+
async writeIfStale(/** @type {(text:string)=>(string|Promise<string>)}*/ transform) {
|
|
17
|
+
if (!existsSync(this.dest) || getAge(statSync(this.dest)) < getAge(statSync(this.src))) {
|
|
18
|
+
const text = readFileSync(this.src, 'utf8');
|
|
19
|
+
mkdirSync(path.dirname(this.dest), { recursive: true });
|
|
20
|
+
writeFileSync(this.dest, await transform(text), 'utf8');
|
|
47
21
|
}
|
|
48
|
-
files.push(target);
|
|
49
22
|
}
|
|
23
|
+
});
|
|
24
|
+
|
|
25
|
+
const getTranspiler = async (/** @type {Ctx} */ ctx) => {
|
|
26
|
+
const ts = (await import('typescript')).default;
|
|
27
|
+
const module = ctx.workspace.type === 'module' ? ts.ModuleKind.ESNext : ts.ModuleKind.CommonJS;
|
|
28
|
+
return (content = '') => ts.transpile(content, { target: ts.ScriptTarget.ES2022, module, esModuleInterop: true, allowSyntheticDefaultImports: true });
|
|
29
|
+
};
|
|
30
|
+
|
|
31
|
+
/** @returns {Promise<import('@travetto/compiler/support/entry.trvc')>} */
|
|
32
|
+
async function imp(f = '') { try { return require(f); } catch (err) { return import(f); } }
|
|
50
33
|
|
|
51
|
-
|
|
34
|
+
export async function getEntry() {
|
|
35
|
+
process.setSourceMapsEnabled(true); // Ensure source map during compilation/development
|
|
36
|
+
process.env.NODE_OPTIONS = `${process.env.NODE_OPTIONS ?? ''} --enable-source-maps`; // Ensure it passes to children
|
|
52
37
|
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
38
|
+
const ctx = getManifestContext();
|
|
39
|
+
const target = getTarget.bind(null, ctx);
|
|
40
|
+
|
|
41
|
+
// Setup Tsconfig
|
|
42
|
+
const tsconfig = path.resolve(ctx.workspace.path, 'tsconfig.json');
|
|
43
|
+
existsSync(tsconfig) || writeFileSync(tsconfig, JSON.stringify({ extends: '@travetto/compiler/tsconfig.trv.json' }), 'utf8');
|
|
44
|
+
|
|
45
|
+
// Compile support folder
|
|
46
|
+
await target('package.json').writeIfStale(text => JSON.stringify(Object.assign(JSON.parse(text), { type: ctx.workspace.type }), null, 2));
|
|
47
|
+
|
|
48
|
+
let transpile;
|
|
49
|
+
for (const file of readdirSync(target('support').src, { recursive: true, encoding: 'utf8' })) {
|
|
50
|
+
if (TS_EXT.test(file)) { await target(`support/${file}`).writeIfStale(async (text) => (transpile ??= await getTranspiler(ctx))(text)); }
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
// Load
|
|
54
|
+
try {
|
|
55
|
+
return await imp(target('support/entry.trvc.ts').dest).then(v => v.main(ctx));
|
|
56
|
+
} catch (err) {
|
|
57
|
+
rmSync(target('.').dest, { recursive: true, force: true });
|
|
58
|
+
throw err;
|
|
59
|
+
}
|
|
60
|
+
}
|
package/bin/trvc.js
CHANGED
|
@@ -7,30 +7,37 @@ const help = () => [
|
|
|
7
7
|
'npx trvc [command]',
|
|
8
8
|
'',
|
|
9
9
|
'Available Commands:',
|
|
10
|
-
' * start|watch
|
|
11
|
-
' * stop
|
|
12
|
-
' * restart
|
|
13
|
-
' * build
|
|
14
|
-
' * clean
|
|
15
|
-
' * info
|
|
16
|
-
' *
|
|
10
|
+
' * start|watch - Run the compiler in watch mode',
|
|
11
|
+
' * stop - Stop the compiler if running',
|
|
12
|
+
' * restart - Restart the compiler in watch mode',
|
|
13
|
+
' * build - Ensure the project is built and upto date',
|
|
14
|
+
' * clean - Clean out the output and compiler caches',
|
|
15
|
+
' * info - Retrieve the compiler information, if running',
|
|
16
|
+
' * event <log|progress|state> - Watch events in realtime as newline delimited JSON',
|
|
17
|
+
' * manifest --prod [output] - Generate the project manifest',
|
|
17
18
|
].join('\n');
|
|
18
19
|
|
|
19
20
|
getEntry().then(async (ops) => {
|
|
20
|
-
const [op, ...
|
|
21
|
-
const
|
|
21
|
+
const [op, ...all] = process.argv.slice(2);
|
|
22
|
+
const args = all.filter(x => !x.startsWith('-'));
|
|
23
|
+
const flags = all.filter(x => x.startsWith('-'));
|
|
22
24
|
|
|
23
25
|
switch (op) {
|
|
24
26
|
case undefined:
|
|
25
27
|
case 'help': return console.log(`\n${help()}\n`);
|
|
26
|
-
case 'restart': return ops.
|
|
28
|
+
case 'restart': return ops.restart();
|
|
27
29
|
case 'stop': return ops.stop();
|
|
28
30
|
case 'info': return ops.info().then(v => console.log(JSON.stringify(v, null, 2)));
|
|
31
|
+
case 'event': return ops.events(args[0], v => {
|
|
32
|
+
if (!process.stdout.write(`${JSON.stringify(v)}\n`)) {
|
|
33
|
+
return new Promise(r => process.stdout.once('drain', r));
|
|
34
|
+
}
|
|
35
|
+
});
|
|
29
36
|
case 'clean': return ops.clean();
|
|
30
|
-
case 'manifest': return ops.manifest(
|
|
31
|
-
case 'start':
|
|
32
|
-
case 'watch':
|
|
33
|
-
case 'build': return ops.
|
|
37
|
+
case 'manifest': return ops.manifest(args[0], flags.some(x => x === '--prod'));
|
|
38
|
+
case 'start':
|
|
39
|
+
case 'watch': return ops.watch();
|
|
40
|
+
case 'build': return ops.build();
|
|
34
41
|
default: console.error(`Unknown trvc operation: ${op}\n`); return console.error(help());
|
|
35
42
|
}
|
|
36
43
|
});
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@travetto/compiler",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "4.0.0-rc.1",
|
|
4
4
|
"description": "The compiler infrastructure for the Travetto framework",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"compiler",
|
|
@@ -30,14 +30,13 @@
|
|
|
30
30
|
"directory": "module/compiler"
|
|
31
31
|
},
|
|
32
32
|
"dependencies": {
|
|
33
|
-
"@parcel/watcher": "^2.
|
|
34
|
-
"@travetto/manifest": "^
|
|
35
|
-
"@travetto/
|
|
36
|
-
"@
|
|
37
|
-
"@types/node": "^20.9.2"
|
|
33
|
+
"@parcel/watcher": "^2.4.0",
|
|
34
|
+
"@travetto/manifest": "^4.0.0-rc.1",
|
|
35
|
+
"@travetto/transformer": "^4.0.0-rc.1",
|
|
36
|
+
"@types/node": "^20.11.16"
|
|
38
37
|
},
|
|
39
38
|
"peerDependencies": {
|
|
40
|
-
"@travetto/cli": "^
|
|
39
|
+
"@travetto/cli": "^4.0.0-rc.1"
|
|
41
40
|
},
|
|
42
41
|
"peerDependenciesMeta": {
|
|
43
42
|
"@travetto/cli": {
|
package/src/compiler.ts
CHANGED
|
@@ -1,8 +1,9 @@
|
|
|
1
|
-
import { install } from 'source-map-support';
|
|
2
1
|
import ts from 'typescript';
|
|
3
|
-
import
|
|
2
|
+
import timers from 'node:timers/promises';
|
|
3
|
+
import fs from 'node:fs/promises';
|
|
4
|
+
import { setMaxListeners } from 'node:events';
|
|
4
5
|
|
|
5
|
-
import { ManifestModuleUtil,
|
|
6
|
+
import { ManifestModuleUtil, RuntimeIndex } from '@travetto/manifest';
|
|
6
7
|
|
|
7
8
|
import { CompilerUtil } from './util';
|
|
8
9
|
import { CompilerState } from './state';
|
|
@@ -21,22 +22,65 @@ export class Compiler {
|
|
|
21
22
|
*/
|
|
22
23
|
static async main(): Promise<void> {
|
|
23
24
|
const [dirty, watch] = process.argv.slice(2);
|
|
24
|
-
const state = await CompilerState.get(
|
|
25
|
+
const state = await CompilerState.get(RuntimeIndex);
|
|
26
|
+
Log.debug('Running compiler with dirty file', dirty);
|
|
25
27
|
const dirtyFiles = ManifestModuleUtil.getFileType(dirty) === 'ts' ? [dirty] : (await fs.readFile(dirty, 'utf8')).split(/\n/).filter(x => !!x);
|
|
26
28
|
await new Compiler(state, dirtyFiles, watch === 'true').run();
|
|
27
|
-
process.exit();
|
|
28
29
|
}
|
|
29
30
|
|
|
30
31
|
#state: CompilerState;
|
|
31
32
|
#dirtyFiles: string[];
|
|
32
33
|
#watch?: boolean;
|
|
34
|
+
#ctrl: AbortController;
|
|
35
|
+
#signal: AbortSignal;
|
|
36
|
+
#shuttingDown = false;
|
|
33
37
|
|
|
34
38
|
constructor(state: CompilerState, dirtyFiles: string[], watch?: boolean) {
|
|
35
39
|
this.#state = state;
|
|
36
40
|
this.#dirtyFiles = dirtyFiles[0] === '*' ?
|
|
37
41
|
this.#state.getAllFiles() :
|
|
38
|
-
dirtyFiles.map(f => this.#state.getBySource(f)!.
|
|
42
|
+
dirtyFiles.map(f => this.#state.getBySource(f)!.inputFile);
|
|
39
43
|
this.#watch = watch;
|
|
44
|
+
|
|
45
|
+
this.#ctrl = new AbortController();
|
|
46
|
+
this.#signal = this.#ctrl.signal;
|
|
47
|
+
setMaxListeners(1000, this.#signal);
|
|
48
|
+
process
|
|
49
|
+
.once('disconnect', () => this.#shutdown('manual'))
|
|
50
|
+
.on('message', ev => (ev === 'shutdown') && this.#shutdown('manual'));
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
#shutdown(mode: 'error' | 'manual' | 'complete' | 'reset', err?: Error): void {
|
|
54
|
+
if (this.#shuttingDown) {
|
|
55
|
+
return;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
this.#shuttingDown = true;
|
|
59
|
+
switch (mode) {
|
|
60
|
+
case 'manual': {
|
|
61
|
+
Log.error('Shutting down manually');
|
|
62
|
+
process.exitCode = 2;
|
|
63
|
+
break;
|
|
64
|
+
}
|
|
65
|
+
case 'error': {
|
|
66
|
+
process.exitCode = 1;
|
|
67
|
+
if (err) {
|
|
68
|
+
Log.error('Shutting down due to failure', err.message);
|
|
69
|
+
}
|
|
70
|
+
break;
|
|
71
|
+
}
|
|
72
|
+
case 'reset': {
|
|
73
|
+
Log.info('Triggering reset due to change in core files');
|
|
74
|
+
EventUtil.sendEvent('state', { state: 'reset' });
|
|
75
|
+
process.exitCode = 0;
|
|
76
|
+
break;
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
// No longer listen to disconnect
|
|
80
|
+
process.removeAllListeners('disconnect');
|
|
81
|
+
process.removeAllListeners('message');
|
|
82
|
+
this.#ctrl.abort();
|
|
83
|
+
setTimeout(() => process.exit(), 1000).unref(); // Allow upto 1s to shutdown gracefully
|
|
40
84
|
}
|
|
41
85
|
|
|
42
86
|
/**
|
|
@@ -50,6 +94,7 @@ export class Compiler {
|
|
|
50
94
|
if (needsNewProgram) {
|
|
51
95
|
program = this.#state.createProgram(program);
|
|
52
96
|
}
|
|
97
|
+
await timers.setImmediate();
|
|
53
98
|
const result = this.#state.writeInputFile(program, inputFile);
|
|
54
99
|
if (result?.diagnostics?.length) {
|
|
55
100
|
return result.diagnostics;
|
|
@@ -72,6 +117,7 @@ export class Compiler {
|
|
|
72
117
|
async * emit(files: string[], emitter: CompileEmitter): AsyncIterable<CompileEmitEvent> {
|
|
73
118
|
let i = 0;
|
|
74
119
|
let lastSent = Date.now();
|
|
120
|
+
|
|
75
121
|
for (const file of files) {
|
|
76
122
|
const err = await emitter(file);
|
|
77
123
|
const imp = file.replace(/.*node_modules\//, '');
|
|
@@ -80,8 +126,14 @@ export class Compiler {
|
|
|
80
126
|
lastSent = Date.now();
|
|
81
127
|
EventUtil.sendEvent('progress', { total: files.length, idx: i, message: imp, operation: 'compile' });
|
|
82
128
|
}
|
|
129
|
+
if (this.#signal.aborted) {
|
|
130
|
+
break;
|
|
131
|
+
}
|
|
83
132
|
}
|
|
84
133
|
EventUtil.sendEvent('progress', { total: files.length, idx: files.length, message: 'Complete', operation: 'compile', complete: true });
|
|
134
|
+
|
|
135
|
+
await timers.setTimeout(1);
|
|
136
|
+
|
|
85
137
|
Log.debug(`Compiled ${i} files`);
|
|
86
138
|
}
|
|
87
139
|
|
|
@@ -89,16 +141,10 @@ export class Compiler {
|
|
|
89
141
|
* Run the compiler
|
|
90
142
|
*/
|
|
91
143
|
async run(): Promise<void> {
|
|
92
|
-
install();
|
|
93
|
-
|
|
94
144
|
Log.debug('Compilation started');
|
|
95
145
|
|
|
96
146
|
EventUtil.sendEvent('state', { state: 'init', extra: { pid: process.pid } });
|
|
97
147
|
|
|
98
|
-
if (process.send) {
|
|
99
|
-
process.on('disconnect', () => process.exit(0));
|
|
100
|
-
}
|
|
101
|
-
|
|
102
148
|
const emitter = await this.getCompiler();
|
|
103
149
|
let failed = false;
|
|
104
150
|
|
|
@@ -114,9 +160,12 @@ export class Compiler {
|
|
|
114
160
|
EventUtil.sendEvent('log', { level: 'error', message: compileError.toString(), time: Date.now() });
|
|
115
161
|
}
|
|
116
162
|
}
|
|
117
|
-
if (
|
|
163
|
+
if (this.#signal.aborted) {
|
|
164
|
+
Log.debug('Compilation aborted');
|
|
165
|
+
} else if (failed) {
|
|
118
166
|
Log.debug('Compilation failed');
|
|
119
|
-
process.
|
|
167
|
+
process.exitCode = 1;
|
|
168
|
+
return;
|
|
120
169
|
} else {
|
|
121
170
|
Log.debug('Compilation succeeded');
|
|
122
171
|
}
|
|
@@ -128,43 +177,47 @@ export class Compiler {
|
|
|
128
177
|
|
|
129
178
|
EventUtil.sendEvent('state', { state: 'compile-end' });
|
|
130
179
|
|
|
131
|
-
if (this.#watch) {
|
|
180
|
+
if (this.#watch && !this.#signal.aborted) {
|
|
132
181
|
Log.info('Watch is ready');
|
|
133
182
|
|
|
134
183
|
EventUtil.sendEvent('state', { state: 'watch-start' });
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
const err = await emitter(entry.input, true);
|
|
145
|
-
if (err) {
|
|
146
|
-
Log.info('Compilation Error', CompilerUtil.buildTranspileError(entry.input, err));
|
|
184
|
+
try {
|
|
185
|
+
for await (const ev of new CompilerWatcher(this.#state, this.#signal).watchChanges()) {
|
|
186
|
+
if (ev.action !== 'delete') {
|
|
187
|
+
const err = await emitter(ev.entry.inputFile, true);
|
|
188
|
+
if (err) {
|
|
189
|
+
Log.info('Compilation Error', CompilerUtil.buildTranspileError(ev.entry.inputFile, err));
|
|
190
|
+
} else {
|
|
191
|
+
Log.info(`Compiled ${ev.entry.sourceFile} on ${ev.action}`);
|
|
192
|
+
}
|
|
147
193
|
} else {
|
|
148
|
-
|
|
194
|
+
if (ev.entry.outputFile) {
|
|
195
|
+
// Remove output
|
|
196
|
+
Log.info(`Removed ${ev.entry.sourceFile}, ${ev.entry.outputFile}`);
|
|
197
|
+
await fs.rm(ev.entry.outputFile, { force: true }); // Ensure output is deleted
|
|
198
|
+
}
|
|
149
199
|
}
|
|
150
|
-
|
|
151
|
-
//
|
|
152
|
-
|
|
153
|
-
|
|
200
|
+
|
|
201
|
+
// Send change events
|
|
202
|
+
EventUtil.sendEvent('change', {
|
|
203
|
+
action: ev.action,
|
|
204
|
+
time: Date.now(),
|
|
205
|
+
file: ev.file,
|
|
206
|
+
output: ev.entry.outputFile!,
|
|
207
|
+
module: ev.entry.module.name
|
|
208
|
+
});
|
|
154
209
|
}
|
|
210
|
+
EventUtil.sendEvent('state', { state: 'watch-end' });
|
|
155
211
|
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
file: ev.file,
|
|
161
|
-
folder: ev.folder,
|
|
162
|
-
output: ev.entry.output!,
|
|
163
|
-
module: ev.entry.module.name
|
|
164
|
-
});
|
|
212
|
+
} catch (err) {
|
|
213
|
+
if (err instanceof Error) {
|
|
214
|
+
this.#shutdown(err.message === 'RESET' ? 'reset' : 'error', err);
|
|
215
|
+
}
|
|
165
216
|
}
|
|
166
|
-
|
|
167
|
-
EventUtil.sendEvent('state', { state: 'watch-end' });
|
|
168
217
|
}
|
|
218
|
+
|
|
219
|
+
Log.debug('Compiler process shutdown');
|
|
220
|
+
|
|
221
|
+
this.#shutdown('complete');
|
|
169
222
|
}
|
|
170
223
|
}
|
package/src/event.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { CompilerEvent, CompilerEventType } from '../support/types';
|
|
2
2
|
|
|
3
3
|
export class EventUtil {
|
|
4
|
-
static sendEvent<K extends
|
|
5
|
-
process.send
|
|
4
|
+
static sendEvent<K extends CompilerEventType, T extends CompilerEvent & { type: K }>(type: K, payload: T['payload']): void {
|
|
5
|
+
process.connected && process.send!({ type, payload }, undefined, { swallowErrors: true });
|
|
6
6
|
}
|
|
7
7
|
}
|
package/src/log.ts
CHANGED
|
@@ -3,7 +3,7 @@ import { EventUtil } from './event';
|
|
|
3
3
|
|
|
4
4
|
function log(level: CompilerLogLevel, message: string, ...args: unknown[]): void {
|
|
5
5
|
EventUtil.sendEvent('log', { level, message, args, time: Date.now(), scope: 'compiler-exec' });
|
|
6
|
-
if (!process.
|
|
6
|
+
if (!process.connected) {
|
|
7
7
|
// eslint-disable-next-line no-console
|
|
8
8
|
console[level](message, ...args);
|
|
9
9
|
}
|