@travetto/compiler 7.0.0 → 7.0.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/package.json +3 -3
- package/src/event.ts +2 -2
- package/src/watch.ts +25 -8
- package/support/entry.main.ts +3 -4
- package/support/server/client.ts +2 -7
- package/support/server/server.ts +9 -8
- package/support/types.ts +9 -1
- package/support/util.ts +2 -2
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@travetto/compiler",
|
|
3
|
-
"version": "7.0.
|
|
3
|
+
"version": "7.0.1",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "The compiler infrastructure for the Travetto framework",
|
|
6
6
|
"keywords": [
|
|
@@ -32,10 +32,10 @@
|
|
|
32
32
|
"dependencies": {
|
|
33
33
|
"@parcel/watcher": "^2.5.1",
|
|
34
34
|
"@travetto/manifest": "^7.0.0",
|
|
35
|
-
"@travetto/transformer": "^7.0.
|
|
35
|
+
"@travetto/transformer": "^7.0.1"
|
|
36
36
|
},
|
|
37
37
|
"peerDependencies": {
|
|
38
|
-
"@travetto/cli": "^7.0.
|
|
38
|
+
"@travetto/cli": "^7.0.1"
|
|
39
39
|
},
|
|
40
40
|
"peerDependenciesMeta": {
|
|
41
41
|
"@travetto/cli": {
|
package/src/event.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { CompilerEventPayload, CompilerEventType } from '../support/types.ts';
|
|
2
2
|
|
|
3
3
|
export class EventUtil {
|
|
4
|
-
static sendEvent<K extends CompilerEventType, T extends
|
|
4
|
+
static sendEvent<K extends CompilerEventType, T extends CompilerEventPayload<K>>(type: K, payload: T): void {
|
|
5
5
|
process.connected && process.send!({ type, payload }, undefined, undefined, () => { });
|
|
6
6
|
}
|
|
7
7
|
}
|
package/src/watch.ts
CHANGED
|
@@ -9,6 +9,7 @@ import { CompilerUtil } from './util.ts';
|
|
|
9
9
|
|
|
10
10
|
import { AsyncQueue } from '../support/queue.ts';
|
|
11
11
|
import { IpcLogger } from '../support/log.ts';
|
|
12
|
+
import { EventUtil } from './event.ts';
|
|
12
13
|
|
|
13
14
|
const log = new IpcLogger({ level: 'debug' });
|
|
14
15
|
|
|
@@ -56,7 +57,7 @@ export class CompilerWatcher {
|
|
|
56
57
|
return [...ignores].toSorted().map(ignore => ignore.endsWith('/') ? ignore : `${ignore}/`);
|
|
57
58
|
}
|
|
58
59
|
|
|
59
|
-
#toCandidateEvent(action: CompilerWatchEvent
|
|
60
|
+
#toCandidateEvent({ action, file }: Pick<CompilerWatchEvent, 'action' | 'file'>): CompilerWatchEventCandidate {
|
|
60
61
|
let entry = this.#state.getBySource(file);
|
|
61
62
|
const mod = entry?.module ?? this.#state.manifestIndex.findModuleForArbitraryFile(file);
|
|
62
63
|
if (mod && action === 'create' && !entry) {
|
|
@@ -69,19 +70,25 @@ export class CompilerWatcher {
|
|
|
69
70
|
return { entry, file: entry?.sourceFile ?? file, action };
|
|
70
71
|
}
|
|
71
72
|
|
|
72
|
-
#
|
|
73
|
-
const relativeFile =
|
|
73
|
+
#isValidFile(file: string): boolean {
|
|
74
|
+
const relativeFile = file.replace(`${this.#root}/`, '');
|
|
74
75
|
if (relativeFile === this.#watchCanary) {
|
|
75
76
|
return false;
|
|
76
77
|
} else if (relativeFile.startsWith('.')) {
|
|
77
78
|
return false;
|
|
78
|
-
}
|
|
79
|
-
|
|
79
|
+
}
|
|
80
|
+
return true;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
#isValidEvent(event: CompilerWatchEventCandidate): event is CompilerWatchEvent {
|
|
84
|
+
if (!event.entry) {
|
|
85
|
+
log.debug(`Skipping unknown file ${event.file}`);
|
|
80
86
|
return false;
|
|
81
87
|
} else if (event.action === 'update' && !this.#state.checkIfSourceChanged(event.entry.sourceFile)) {
|
|
88
|
+
const relativeFile = event.file.replace(`${this.#root}/`, '');
|
|
82
89
|
log.debug(`Skipping update, as contents unchanged ${relativeFile}`);
|
|
83
90
|
return false;
|
|
84
|
-
} else if (!CompilerUtil.validFile(ManifestModuleUtil.getFileType(
|
|
91
|
+
} else if (!CompilerUtil.validFile(ManifestModuleUtil.getFileType(event.file))) {
|
|
85
92
|
return false;
|
|
86
93
|
}
|
|
87
94
|
return true;
|
|
@@ -168,10 +175,20 @@ export class CompilerWatcher {
|
|
|
168
175
|
throw new CompilerReset('Package information changed');
|
|
169
176
|
}
|
|
170
177
|
|
|
171
|
-
|
|
172
|
-
|
|
178
|
+
// One event per file set
|
|
179
|
+
const filesChanged = events.map(e => ({ file: path.toPosix(e.path), action: e.type })).filter(e => this.#isValidFile(e.file));
|
|
180
|
+
if (filesChanged.length) {
|
|
181
|
+
EventUtil.sendEvent('file', { time: Date.now(), files: filesChanged });
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
const items = filesChanged
|
|
185
|
+
.map(event => this.#toCandidateEvent(event))
|
|
173
186
|
.filter(event => this.#isValidEvent(event));
|
|
174
187
|
|
|
188
|
+
if (items.length === 0) {
|
|
189
|
+
return;
|
|
190
|
+
}
|
|
191
|
+
|
|
175
192
|
try {
|
|
176
193
|
await this.#reconcileManifestUpdates(items);
|
|
177
194
|
} catch (manifestError) {
|
package/support/entry.main.ts
CHANGED
|
@@ -3,7 +3,7 @@ import fs from 'node:fs/promises';
|
|
|
3
3
|
|
|
4
4
|
import type { ManifestContext } from '@travetto/manifest';
|
|
5
5
|
|
|
6
|
-
import type
|
|
6
|
+
import { isComplilerEventType, type CompilerMode, type CompilerServerInfo } from './types.ts';
|
|
7
7
|
import { Log } from './log.ts';
|
|
8
8
|
import { CompilerSetup } from './setup.ts';
|
|
9
9
|
import { CompilerServer } from './server/server.ts';
|
|
@@ -72,9 +72,8 @@ export const main = (ctx: ManifestContext) => {
|
|
|
72
72
|
|
|
73
73
|
/** Stream events */
|
|
74
74
|
events: async (type: string, handler: (event: unknown) => unknown): Promise<void> => {
|
|
75
|
-
if (type
|
|
76
|
-
|
|
77
|
-
for await (const event of client.fetchEvents(type as 'change')) { await handler(event); }
|
|
75
|
+
if (isComplilerEventType(type)) {
|
|
76
|
+
for await (const event of client.fetchEvents(type)) { await handler(event); }
|
|
78
77
|
} else {
|
|
79
78
|
throw new Error(`Unknown event type: ${type}`);
|
|
80
79
|
}
|
package/support/server/client.ts
CHANGED
|
@@ -4,7 +4,7 @@ import http, { Agent } from 'node:http';
|
|
|
4
4
|
|
|
5
5
|
import { ManifestContext } from '@travetto/manifest';
|
|
6
6
|
|
|
7
|
-
import type {
|
|
7
|
+
import type { CompilerEventPayload, CompilerEventType, CompilerServerInfo, CompilerStateType } from '../types.ts';
|
|
8
8
|
import type { LogShape } from '../log.ts';
|
|
9
9
|
import { CommonUtil } from '../util.ts';
|
|
10
10
|
import { ProcessHandle } from './process-handle.ts';
|
|
@@ -91,12 +91,7 @@ export class CompilerClient {
|
|
|
91
91
|
}
|
|
92
92
|
|
|
93
93
|
/** Fetch compiler events */
|
|
94
|
-
fetchEvents<
|
|
95
|
-
V extends CompilerEventType,
|
|
96
|
-
T extends (CompilerEvent & { type: V })['payload']
|
|
97
|
-
>(type: V, config?: FetchEventsConfig<T>): AsyncIterable<T>;
|
|
98
|
-
fetchEvents(type: 'all', config?: FetchEventsConfig<CompilerEvent>): AsyncIterable<CompilerEvent>;
|
|
99
|
-
async * fetchEvents<T = unknown>(type: string, config: FetchEventsConfig<T> = {}): AsyncIterable<T> {
|
|
94
|
+
async * fetchEvents<V extends CompilerEventType, T extends CompilerEventPayload<V>>(type: V, config: FetchEventsConfig<T> = {}): AsyncIterable<T> {
|
|
100
95
|
let info = await this.info();
|
|
101
96
|
if (!info) {
|
|
102
97
|
return;
|
package/support/server/server.ts
CHANGED
|
@@ -4,7 +4,10 @@ import { setMaxListeners } from 'node:events';
|
|
|
4
4
|
|
|
5
5
|
import type { ManifestContext } from '@travetto/manifest';
|
|
6
6
|
|
|
7
|
-
import
|
|
7
|
+
import {
|
|
8
|
+
type CompilerMode, type CompilerProgressEvent, type CompilerEvent,
|
|
9
|
+
type CompilerEventType, type CompilerServerInfo, isComplilerEventType
|
|
10
|
+
} from '../types.ts';
|
|
8
11
|
import { Log } from '../log.ts';
|
|
9
12
|
import { CommonUtil } from '../util.ts';
|
|
10
13
|
import { CompilerClient } from './client.ts';
|
|
@@ -20,7 +23,7 @@ export class CompilerServer {
|
|
|
20
23
|
#ctx: ManifestContext;
|
|
21
24
|
#server: http.Server;
|
|
22
25
|
#listenersAll = new Set<http.ServerResponse>();
|
|
23
|
-
#listeners: Partial<Record<CompilerEventType
|
|
26
|
+
#listeners: Partial<Record<CompilerEventType, Record<string, http.ServerResponse>>> = {};
|
|
24
27
|
#shutdown = new AbortController();
|
|
25
28
|
info: CompilerServerInfo;
|
|
26
29
|
#client: CompilerClient;
|
|
@@ -98,7 +101,7 @@ export class CompilerServer {
|
|
|
98
101
|
return output;
|
|
99
102
|
}
|
|
100
103
|
|
|
101
|
-
#addListener(type: CompilerEventType
|
|
104
|
+
#addListener(type: CompilerEventType, response: http.ServerResponse): void {
|
|
102
105
|
response.writeHead(200);
|
|
103
106
|
const id = `id_${Date.now()}_${Math.random()}`.replace('.', '1');
|
|
104
107
|
(this.#listeners[type] ??= {})[id] = response;
|
|
@@ -109,7 +112,6 @@ export class CompilerServer {
|
|
|
109
112
|
response.write('\n'); // Send at least one byte on listen
|
|
110
113
|
}
|
|
111
114
|
|
|
112
|
-
// Do not wait on it
|
|
113
115
|
response.on('close', () => {
|
|
114
116
|
delete this.#listeners[type]?.[id];
|
|
115
117
|
this.#listenersAll.delete(response);
|
|
@@ -168,11 +170,10 @@ export class CompilerServer {
|
|
|
168
170
|
let close = false;
|
|
169
171
|
switch (action) {
|
|
170
172
|
case 'event': {
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
return this.#addListener(subAction, response);
|
|
174
|
-
default: return;
|
|
173
|
+
if (isComplilerEventType(subAction)) {
|
|
174
|
+
this.#addListener(subAction, response);
|
|
175
175
|
}
|
|
176
|
+
return;
|
|
176
177
|
}
|
|
177
178
|
case 'clean': out = await this.#clean(); break;
|
|
178
179
|
case 'stop': out = JSON.stringify({ closing: true }); close = true; break;
|
package/support/types.ts
CHANGED
|
@@ -8,14 +8,18 @@ export type CompilerLogLevel = 'info' | 'debug' | 'warn' | 'error';
|
|
|
8
8
|
export type CompilerLogEvent = { level: CompilerLogLevel, message: string, time?: number, args?: unknown[], scope?: string };
|
|
9
9
|
export type CompilerProgressEvent = { idx: number, total: number, message: string, operation: 'compile', complete?: boolean };
|
|
10
10
|
export type CompilerStateEvent = { state: CompilerStateType, extra?: Record<string, unknown> };
|
|
11
|
+
export type FileChangeEvent = { files: { file: string, action: ChangeEventType }[], time: number };
|
|
11
12
|
|
|
12
13
|
export type CompilerEvent =
|
|
14
|
+
{ type: 'file', payload: FileChangeEvent } |
|
|
13
15
|
{ type: 'change', payload: CompilerChangeEvent } |
|
|
14
16
|
{ type: 'log', payload: CompilerLogEvent } |
|
|
15
17
|
{ type: 'progress', payload: CompilerProgressEvent } |
|
|
16
|
-
{ type: 'state', payload: CompilerStateEvent }
|
|
18
|
+
{ type: 'state', payload: CompilerStateEvent } |
|
|
19
|
+
{ type: 'all', payload: unknown };
|
|
17
20
|
|
|
18
21
|
export type CompilerEventType = CompilerEvent['type'];
|
|
22
|
+
export type CompilerEventPayload<V> = (CompilerEvent & { type: V })['payload'];
|
|
19
23
|
|
|
20
24
|
export type CompilerServerInfo = {
|
|
21
25
|
path: string;
|
|
@@ -27,3 +31,7 @@ export type CompilerServerInfo = {
|
|
|
27
31
|
url: string;
|
|
28
32
|
env?: Record<string, string>;
|
|
29
33
|
};
|
|
34
|
+
|
|
35
|
+
const VALID_EVENT_TYPES = new Set<CompilerEventType>(['change', 'log', 'progress', 'state', 'all', 'file']);
|
|
36
|
+
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions
|
|
37
|
+
export const isComplilerEventType = (value: string): value is CompilerEventType => VALID_EVENT_TYPES.has(value as CompilerEventType);
|
package/support/util.ts
CHANGED
|
@@ -38,12 +38,12 @@ export class CommonUtil {
|
|
|
38
38
|
const kill = (): void => controller.abort();
|
|
39
39
|
parent.addEventListener('abort', kill);
|
|
40
40
|
|
|
41
|
-
const
|
|
41
|
+
const stream = input(controller.signal);
|
|
42
42
|
|
|
43
43
|
log.debug('Started event stream');
|
|
44
44
|
|
|
45
45
|
// Wait for all events, close at the end
|
|
46
|
-
for await (const event of
|
|
46
|
+
for await (const event of stream) {
|
|
47
47
|
yield event;
|
|
48
48
|
if (shouldRestart(event)) {
|
|
49
49
|
log.debug('Restarting stream');
|