@travetto/compiler 4.0.0-rc.2 → 4.0.0-rc.3
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/bin/common.js +5 -1
- package/package.json +4 -4
- package/src/watch.ts +20 -10
- package/support/entry.compiler.ts +1 -0
- package/support/entry.trvc.ts +2 -0
- package/support/log.ts +15 -3
- package/support/server/client.ts +3 -3
- package/support/server/process-handle.ts +2 -1
- package/support/server/server.ts +9 -8
package/bin/common.js
CHANGED
|
@@ -25,7 +25,11 @@ const getTarget = (/** @type {Ctx} */ ctx, file = '') => ({
|
|
|
25
25
|
const getTranspiler = async (/** @type {Ctx} */ ctx) => {
|
|
26
26
|
const ts = (await import('typescript')).default;
|
|
27
27
|
const module = ctx.workspace.type === 'module' ? ts.ModuleKind.ESNext : ts.ModuleKind.CommonJS;
|
|
28
|
-
return (content = '') =>
|
|
28
|
+
return (content = '') =>
|
|
29
|
+
ts.transpile(content, { target: ts.ScriptTarget.ES2022, module, esModuleInterop: true, allowSyntheticDefaultImports: true })
|
|
30
|
+
.replace(/from '([.][^']+)'/g, (_, i) => `from '${i.replace(/[.]js$/, '')}.js'`)
|
|
31
|
+
.replace(/from '(@travetto\/(.*?))'/g, (_, i, s) =>
|
|
32
|
+
`from '${path.resolve(ctx.workspace.path, ctx.build.compilerFolder, `${i}${s.includes('/') ? '.js' : '/__index__.js'}`)}'`);
|
|
29
33
|
};
|
|
30
34
|
|
|
31
35
|
/** @returns {Promise<import('@travetto/compiler/support/entry.trvc')>} */
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@travetto/compiler",
|
|
3
|
-
"version": "4.0.0-rc.
|
|
3
|
+
"version": "4.0.0-rc.3",
|
|
4
4
|
"description": "The compiler infrastructure for the Travetto framework",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"compiler",
|
|
@@ -31,12 +31,12 @@
|
|
|
31
31
|
},
|
|
32
32
|
"dependencies": {
|
|
33
33
|
"@parcel/watcher": "^2.4.0",
|
|
34
|
-
"@travetto/manifest": "^4.0.0-rc.
|
|
35
|
-
"@travetto/transformer": "^4.0.0-rc.
|
|
34
|
+
"@travetto/manifest": "^4.0.0-rc.3",
|
|
35
|
+
"@travetto/transformer": "^4.0.0-rc.3",
|
|
36
36
|
"@types/node": "^20.11.16"
|
|
37
37
|
},
|
|
38
38
|
"peerDependencies": {
|
|
39
|
-
"@travetto/cli": "^4.0.0-rc.
|
|
39
|
+
"@travetto/cli": "^4.0.0-rc.4"
|
|
40
40
|
},
|
|
41
41
|
"peerDependenciesMeta": {
|
|
42
42
|
"@travetto/cli": {
|
package/src/watch.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { ManifestContext, ManifestModuleUtil, ManifestUtil, RuntimeIndex, path } from '@travetto/manifest';
|
|
1
|
+
import { ManifestContext, ManifestModuleUtil, ManifestUtil, PackageUtil, RuntimeIndex, path } from '@travetto/manifest';
|
|
2
2
|
|
|
3
3
|
import type { CompileStateEntry } from './types';
|
|
4
4
|
import { CompilerState } from './state';
|
|
@@ -22,10 +22,28 @@ export class CompilerWatcher {
|
|
|
22
22
|
this.#signal = signal;
|
|
23
23
|
}
|
|
24
24
|
|
|
25
|
+
#getIgnores(): string[] {
|
|
26
|
+
// TODO: Read .gitignore?
|
|
27
|
+
let ignores = PackageUtil.readPackage(this.#state.manifest.workspace.path)?.travetto?.build?.watchIgnores;
|
|
28
|
+
|
|
29
|
+
if (!ignores) {
|
|
30
|
+
ignores = ['node_modules/**'];
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
return [
|
|
34
|
+
...ignores,
|
|
35
|
+
'.git', '**/.git',
|
|
36
|
+
`${this.#state.manifest.build.outputFolder}/node_modules/**`,
|
|
37
|
+
`${this.#state.manifest.build.compilerFolder}/node_modules/**`,
|
|
38
|
+
`${this.#state.manifest.build.toolFolder}/**`
|
|
39
|
+
];
|
|
40
|
+
}
|
|
41
|
+
|
|
25
42
|
/** Watch files */
|
|
26
43
|
async * #watchFolder(rootPath: string): AsyncIterable<WatchEvent> {
|
|
27
44
|
const q = new AsyncQueue<WatchEvent>(this.#signal);
|
|
28
45
|
const lib = await import('@parcel/watcher');
|
|
46
|
+
const ignore = this.#getIgnores();
|
|
29
47
|
|
|
30
48
|
const cleanup = await lib.subscribe(rootPath, (err, events) => {
|
|
31
49
|
if (err) {
|
|
@@ -36,15 +54,7 @@ export class CompilerWatcher {
|
|
|
36
54
|
for (const ev of events) {
|
|
37
55
|
q.add({ action: ev.type, file: path.toPosix(ev.path) });
|
|
38
56
|
}
|
|
39
|
-
}, {
|
|
40
|
-
// TODO: Read .gitignore?
|
|
41
|
-
ignore: [
|
|
42
|
-
'node_modules', '**/node_modules', '.git', '**/.git',
|
|
43
|
-
`${this.#state.manifest.build.outputFolder}/node_modules/**`,
|
|
44
|
-
`${this.#state.manifest.build.compilerFolder}/node_modules/**`,
|
|
45
|
-
`${this.#state.manifest.build.toolFolder}/**`
|
|
46
|
-
]
|
|
47
|
-
});
|
|
57
|
+
}, { ignore });
|
|
48
58
|
|
|
49
59
|
if (this.#signal.aborted) { // If already aborted, can happen async
|
|
50
60
|
cleanup.unsubscribe();
|
package/support/entry.trvc.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
// @trv-no-transform
|
|
1
2
|
import fs from 'node:fs/promises';
|
|
2
3
|
import path from 'node:path';
|
|
3
4
|
|
|
@@ -40,6 +41,7 @@ export const main = (ctx: ManifestContext) => {
|
|
|
40
41
|
await client.waitForState(['compile-end', 'watch-start'], 'Successfully built');
|
|
41
42
|
ctrl.abort();
|
|
42
43
|
}
|
|
44
|
+
LogUtil.cleanup();
|
|
43
45
|
};
|
|
44
46
|
|
|
45
47
|
const ops = {
|
package/support/log.ts
CHANGED
|
@@ -10,6 +10,8 @@ const LEVEL_TO_PRI: Record<CompilerLogLevel, number> = { debug: 1, info: 2, warn
|
|
|
10
10
|
|
|
11
11
|
const SCOPE_MAX = 15;
|
|
12
12
|
|
|
13
|
+
const ESC = '\x1b[';
|
|
14
|
+
|
|
13
15
|
export class LogUtil {
|
|
14
16
|
|
|
15
17
|
static root = process.cwd();
|
|
@@ -22,14 +24,13 @@ export class LogUtil {
|
|
|
22
24
|
|
|
23
25
|
static #rewriteLine(text: string): Promise<void> | void {
|
|
24
26
|
// Move to 1st position, and clear after text
|
|
25
|
-
const done = process.stdout.write(
|
|
27
|
+
const done = process.stdout.write(`${ESC}1G${text}${ESC}0K`);
|
|
26
28
|
this.linePartial = !!text;
|
|
27
29
|
if (!done) {
|
|
28
30
|
return new Promise<void>(r => process.stdout.once('drain', r));
|
|
29
31
|
}
|
|
30
32
|
}
|
|
31
33
|
|
|
32
|
-
|
|
33
34
|
/**
|
|
34
35
|
* Set level for operation
|
|
35
36
|
*/
|
|
@@ -40,7 +41,18 @@ export class LogUtil {
|
|
|
40
41
|
this.logLevel = build || defaultLevel;
|
|
41
42
|
}
|
|
42
43
|
this.root = ctx.workspace.path;
|
|
43
|
-
|
|
44
|
+
// If we are in info or a terminal and also in a tty
|
|
45
|
+
this.logProgress = ((this.isLevelActive('info') || process.env.PS1) && process.stdout.isTTY) ? this.#logProgressEvent : undefined;
|
|
46
|
+
if (this.logProgress) {
|
|
47
|
+
process.stdout.write(`${ESC}?25l`); // Hide cursor
|
|
48
|
+
}
|
|
49
|
+
process.on('exit', () => this.cleanup());
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
static cleanup(): void {
|
|
53
|
+
if (this.logProgress) {
|
|
54
|
+
process.stdout.write(`${ESC}!p`); // Reset
|
|
55
|
+
}
|
|
44
56
|
}
|
|
45
57
|
|
|
46
58
|
static #logProgressEvent(ev: CompilerProgressEvent): Promise<void> | void {
|
package/support/server/client.ts
CHANGED
|
@@ -37,11 +37,11 @@ export class CompilerClient {
|
|
|
37
37
|
return this.#url;
|
|
38
38
|
}
|
|
39
39
|
|
|
40
|
-
async #fetch(rel: string, opts?: RequestInit & { timeout?: number }): Promise<Response> {
|
|
40
|
+
async #fetch(rel: string, opts?: RequestInit & { timeout?: number }, logTimeout = true): Promise<Response> {
|
|
41
41
|
const ctrl = new AbortController();
|
|
42
42
|
opts?.signal?.addEventListener('abort', () => ctrl.abort());
|
|
43
43
|
const timeoutId = setTimeout(() => {
|
|
44
|
-
this.#log('error', `Timeout on request to ${this.#url}${rel}`);
|
|
44
|
+
logTimeout && this.#log('error', `Timeout on request to ${this.#url}${rel}`);
|
|
45
45
|
ctrl.abort('TIMEOUT');
|
|
46
46
|
}, 100).unref();
|
|
47
47
|
try {
|
|
@@ -53,7 +53,7 @@ export class CompilerClient {
|
|
|
53
53
|
|
|
54
54
|
/** Get server information, if server is running */
|
|
55
55
|
info(): Promise<CompilerServerInfo | undefined> {
|
|
56
|
-
return this.#fetch('/info').then(v => v.json(), () => undefined)
|
|
56
|
+
return this.#fetch('/info', {}, false).then(v => v.json(), () => undefined)
|
|
57
57
|
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions
|
|
58
58
|
.then(v => v as CompilerServerInfo);
|
|
59
59
|
}
|
|
@@ -12,7 +12,8 @@ export class ProcessHandle {
|
|
|
12
12
|
this.#file = path.resolve(ctx.workspace.path, ctx.build.toolFolder, `${name}.pid`);
|
|
13
13
|
}
|
|
14
14
|
|
|
15
|
-
writePid(pid: number): Promise<void> {
|
|
15
|
+
async writePid(pid: number): Promise<void> {
|
|
16
|
+
await fs.mkdir(path.dirname(this.#file), { recursive: true });
|
|
16
17
|
return fs.writeFile(this.#file, JSON.stringify(pid), 'utf8');
|
|
17
18
|
}
|
|
18
19
|
|
package/support/server/server.ts
CHANGED
|
@@ -20,7 +20,7 @@ export class CompilerServer {
|
|
|
20
20
|
|
|
21
21
|
#ctx: ManifestContext;
|
|
22
22
|
#server: http.Server;
|
|
23
|
-
#listeners: { res: http.ServerResponse, type: CompilerEventType }
|
|
23
|
+
#listeners: Record<string, { res: http.ServerResponse, type: CompilerEventType }> = {};
|
|
24
24
|
#shutdown = new AbortController();
|
|
25
25
|
signal = this.#shutdown.signal;
|
|
26
26
|
info: CompilerServerInfo;
|
|
@@ -97,20 +97,21 @@ export class CompilerServer {
|
|
|
97
97
|
|
|
98
98
|
async #addListener(type: string, res: http.ServerResponse): Promise<void> {
|
|
99
99
|
res.writeHead(200);
|
|
100
|
+
const id = `id_${Date.now()}_${Math.random()}`.replace('.', '1');
|
|
100
101
|
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions
|
|
101
|
-
this.#listeners
|
|
102
|
+
this.#listeners[id] = { res, type: type as 'change' };
|
|
102
103
|
if (type === 'state') { // Send on initial connect
|
|
103
104
|
res.write(JSON.stringify({ state: this.info.state }));
|
|
104
105
|
}
|
|
105
106
|
res.write('\n'); // Send at least one byte on listen
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
res.
|
|
107
|
+
|
|
108
|
+
// Do not wait on it
|
|
109
|
+
res.on('close', () => { delete this.#listeners[id]; });
|
|
109
110
|
}
|
|
110
111
|
|
|
111
112
|
#emitEvent(ev: CompilerEvent): void {
|
|
112
113
|
const msg = `${JSON.stringify(ev.payload)}\n`;
|
|
113
|
-
for (const el of this.#listeners) {
|
|
114
|
+
for (const el of Object.values(this.#listeners)) {
|
|
114
115
|
if (!el.res.closed && el.type === ev.type) {
|
|
115
116
|
el.res.write(msg);
|
|
116
117
|
}
|
|
@@ -121,8 +122,8 @@ export class CompilerServer {
|
|
|
121
122
|
log('info', 'Server disconnect requested');
|
|
122
123
|
this.info.iteration = Date.now();
|
|
123
124
|
await new Promise(r => setTimeout(r, 20));
|
|
124
|
-
for (const el of this.#listeners) {
|
|
125
|
-
el.res.
|
|
125
|
+
for (const el of Object.values(this.#listeners)) {
|
|
126
|
+
el.res.end();
|
|
126
127
|
}
|
|
127
128
|
}
|
|
128
129
|
|