@travetto/compiler 8.0.0-alpha.20 → 8.0.0-alpha.21

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 CHANGED
@@ -17,12 +17,12 @@ This module expands upon the [Typescript](https://typescriptlang.org) compiler,
17
17
  * Integration with the [Transformation](https://github.com/travetto/travetto/tree/main/module/transformer#readme "Functionality for AST transformations, with transformer registration, and general utils") module, allowing for rich, type-aware transformations
18
18
  * Automatic conversion to either [Ecmascript Module](https://nodejs.org/api/esm.html) or [CommonJS](https://nodejs.org/api/modules.html) based on the [Package JSON](https://docs.npmjs.com/cli/v9/configuring-npm/package-json) `type` value
19
19
  * Removal of type only imports which can break [Ecmascript Module](https://nodejs.org/api/esm.html)-style output
20
- * Automatic addition of `.js` extension to imports to also support [Ecmascript Module](https://nodejs.org/api/esm.html)-style output
20
+ * Automatic addition of `.js` extension to imports to also support [Ecmascript Module](https://nodejs.org/api/esm.html)-style output
21
21
 
22
22
  Beyond the [Typescript](https://typescriptlang.org) compiler functionality, the module provides the primary entry point into the development process.
23
23
 
24
24
  ## CLI
25
- The compiler cli, [trvc](https://github.com/travetto/travetto/tree/main/module/compiler/bin/trvc.js) is the entry point for compilation-related operations. It has the ability to check for active builds, and ongoing watch operations to ensure only one process is building at a time. Within the framework, regardless of mono-repo or not, the compilation always targets the entire project. With the efficient caching behavior, this leads to generally a minimal overhead but allows for centralization of all operations.
25
+ The compiler cli, [trvc](https://github.com/travetto/travetto/tree/main/module/compiler/bin/trvc.js) is the entry point for compilation-related operations. It has the ability to check for active builds, and ongoing watch operations to ensure only one process is building at a time. Within the framework, regardless of mono-repo or not, the compilation always targets the entire project. With the efficient caching behavior, this leads to generally a minimal overhead but allows for centralization of all operations.
26
26
 
27
27
  The compiler cli supports the following operations:
28
28
  * `start` - Run the compiler in watch mode
@@ -36,7 +36,7 @@ The compiler cli supports the following operations:
36
36
  * `manifest [output]` - Generate the project manifest
37
37
  * `manifest:production [output]` - Generate the production project manifest
38
38
 
39
- 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`.
39
+ 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`.
40
40
 
41
41
  **Terminal: Sample trv output with debug logging**
42
42
  ```bash
package/__index__.ts CHANGED
@@ -2,11 +2,11 @@ export * from './src/common.ts';
2
2
  export * from './src/compiler.ts';
3
3
  export * from './src/event.ts';
4
4
  export * from './src/log.ts';
5
+ export * from './src/server/client.ts';
6
+ export * from './src/server/manager.ts';
7
+ export * from './src/server/process-handle.ts';
8
+ export * from './src/server/server.ts';
5
9
  export * from './src/state.ts';
6
10
  export * from './src/types.ts';
7
11
  export * from './src/util.ts';
8
12
  export * from './src/watch.ts';
9
- export * from './src/server/client.ts';
10
- export * from './src/server/server.ts';
11
- export * from './src/server/manager.ts';
12
- export * from './src/server/process-handle.ts';
package/bin/hook.js CHANGED
@@ -1,6 +1,7 @@
1
1
  // @ts-check
2
- import module from 'node:module';
2
+
3
3
  import { readFileSync } from 'node:fs';
4
+ import module from 'node:module';
4
5
  import { fileURLToPath } from 'node:url';
5
6
 
6
7
  const ogEmitWarning = process.emitWarning.bind(process);
@@ -10,7 +11,7 @@ module.registerHooks({
10
11
  if (/[.]tsx?$/.test(url)) {
11
12
  const source = readFileSync(fileURLToPath(url), 'utf8');
12
13
  try {
13
- process.emitWarning = () => { };
14
+ process.emitWarning = () => {};
14
15
  return { format: 'module', source: module.stripTypeScriptTypes(source), shortCircuit: true };
15
16
  } finally {
16
17
  process.emitWarning = ogEmitWarning;
@@ -19,4 +20,4 @@ module.registerHooks({
19
20
  return nextLoad(url, context);
20
21
  }
21
22
  }
22
- });
23
+ });
@@ -1,5 +1,6 @@
1
1
  // @ts-check
2
2
  import '@travetto/runtime/support/patch.js';
3
3
  import './hook.js';
4
+
4
5
  const { Compiler } = await import('../src/compiler.ts');
5
- await Compiler.main();
6
+ await Compiler.main();
package/bin/trvc.js CHANGED
@@ -2,5 +2,6 @@
2
2
  // @ts-check
3
3
  import '@travetto/runtime/support/patch.js';
4
4
  import './hook.js';
5
+
5
6
  const { invoke } = await import('@travetto/compiler/support/invoke.ts');
6
- await invoke(...process.argv.slice(2));
7
+ await invoke(...process.argv.slice(2));
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@travetto/compiler",
3
- "version": "8.0.0-alpha.20",
3
+ "version": "8.0.0-alpha.21",
4
4
  "type": "module",
5
5
  "description": "The compiler infrastructure for the Travetto framework",
6
6
  "keywords": [
@@ -31,11 +31,11 @@
31
31
  },
32
32
  "dependencies": {
33
33
  "@parcel/watcher": "^2.5.6",
34
- "@travetto/manifest": "^8.0.0-alpha.10",
35
- "@travetto/transformer": "^8.0.0-alpha.13"
34
+ "@travetto/manifest": "^8.0.0-alpha.11",
35
+ "@travetto/transformer": "^8.0.0-alpha.14"
36
36
  },
37
37
  "peerDependencies": {
38
- "@travetto/cli": "^8.0.0-alpha.26"
38
+ "@travetto/cli": "^8.0.0-alpha.28"
39
39
  },
40
40
  "peerDependenciesMeta": {
41
41
  "@travetto/cli": {
package/src/common.ts CHANGED
@@ -6,11 +6,14 @@ import { type ManifestContext, path } from '@travetto/manifest';
6
6
  import { Log } from './log.ts';
7
7
 
8
8
  export class CommonUtil {
9
-
10
9
  /**
11
10
  * Restartable Event Stream
12
11
  */
13
- static async * restartableEvents<T>(input: (signal: AbortSignal) => AsyncIterable<T>, parent: AbortSignal, shouldRestart: (item: T) => boolean): AsyncIterable<T> {
12
+ static async *restartableEvents<T>(
13
+ input: (signal: AbortSignal) => AsyncIterable<T>,
14
+ parent: AbortSignal,
15
+ shouldRestart: (item: T) => boolean
16
+ ): AsyncIterable<T> {
14
17
  const log = Log.scoped('event-stream');
15
18
  outer: while (!parent.aborted) {
16
19
  const controller = new AbortController();
@@ -37,7 +40,8 @@ export class CommonUtil {
37
40
  log.debug('Finished event stream');
38
41
 
39
42
  // Natural exit, we done
40
- if (!controller.signal.aborted) { // Shutdown source if still running
43
+ if (!controller.signal.aborted) {
44
+ // Shutdown source if still running
41
45
  controller.abort();
42
46
  }
43
47
  return;
@@ -48,14 +52,14 @@ export class CommonUtil {
48
52
  * Non-blocking timeout
49
53
  */
50
54
  static nonBlockingTimeout(time: number): Promise<void> {
51
- return timers.setTimeout(time, undefined, { ref: false }).catch(() => { });
55
+ return timers.setTimeout(time, undefined, { ref: false }).catch(() => {});
52
56
  }
53
57
 
54
58
  /**
55
59
  * Blocking timeout
56
60
  */
57
61
  static blockingTimeout(time: number): Promise<void> {
58
- return timers.setTimeout(time, undefined, { ref: true }).catch(() => { });
62
+ return timers.setTimeout(time, undefined, { ref: true }).catch(() => {});
59
63
  }
60
64
 
61
65
  /**
@@ -76,8 +80,10 @@ export class CommonUtil {
76
80
  * Write to stdout with backpressure handling
77
81
  */
78
82
  static async writeStdout(level: number, data: unknown): Promise<void> {
79
- if (data === undefined) { return; }
83
+ if (data === undefined) {
84
+ return;
85
+ }
80
86
  process.stdout.write(`${JSON.stringify(data, undefined, level)}\n`) ||
81
- await new Promise(resolve => process.stdout.once('drain', resolve));
82
- };
83
- }
87
+ (await new Promise(resolve => process.stdout.once('drain', resolve)));
88
+ }
89
+ }
package/src/compiler.ts CHANGED
@@ -1,15 +1,14 @@
1
- import fs from 'node:fs/promises';
2
1
  import { setMaxListeners } from 'node:events';
2
+ import fs from 'node:fs/promises';
3
3
 
4
- import { getManifestContext, ManifestDeltaUtil, ManifestIndex, ManifestUtil, type DeltaEvent } from '@travetto/manifest';
4
+ import { type DeltaEvent, getManifestContext, ManifestDeltaUtil, ManifestIndex, ManifestUtil } from '@travetto/manifest';
5
5
 
6
- import { CompilerState } from './state.ts';
7
- import { CompilerWatcher } from './watch.ts';
8
- import { type CompileEmitEvent, CompilerReset } from './types.ts';
6
+ import { CommonUtil } from './common.ts';
9
7
  import { EventUtil } from './event.ts';
10
-
11
8
  import { IpcLogger } from './log.ts';
12
- import { CommonUtil } from './common.ts';
9
+ import { CompilerState } from './state.ts';
10
+ import { type CompileEmitEvent, CompilerReset } from './types.ts';
11
+ import { CompilerWatcher } from './watch.ts';
13
12
 
14
13
  const log = new IpcLogger({ level: 'debug' });
15
14
 
@@ -17,7 +16,6 @@ const log = new IpcLogger({ level: 'debug' });
17
16
  * Compilation support
18
17
  */
19
18
  export class Compiler {
20
-
21
19
  /**
22
20
  * Run compiler as a main entry point
23
21
  */
@@ -44,9 +42,7 @@ export class Compiler {
44
42
  this.#shutdownController = new AbortController();
45
43
  this.#shutdownSignal = this.#shutdownController.signal;
46
44
  setMaxListeners(1000, this.#shutdownSignal);
47
- process
48
- .once('disconnect', () => this.#shutdown('manual'))
49
- .on('message', event => (event === 'shutdown') && this.#shutdown('manual'));
45
+ process.once('disconnect', () => this.#shutdown('manual')).on('message', event => event === 'shutdown' && this.#shutdown('manual'));
50
46
  }
51
47
 
52
48
  #shutdown(mode: 'error' | 'manual' | 'complete' | 'reset', errorMessage?: string): void {
@@ -111,7 +107,7 @@ export class Compiler {
111
107
  /**
112
108
  * Emit all files as a stream
113
109
  */
114
- async * emit(files: string[]): AsyncIterable<CompileEmitEvent> {
110
+ async *emit(files: string[]): AsyncIterable<CompileEmitEvent> {
115
111
  let i = 0;
116
112
  let lastSent = Date.now();
117
113
 
@@ -122,8 +118,9 @@ export class Compiler {
122
118
  const nodeModSeparator = 'node_modules/';
123
119
  const nodeModIdx = file.lastIndexOf(nodeModSeparator);
124
120
  const imp = nodeModIdx >= 0 ? file.substring(nodeModIdx + nodeModSeparator.length) : file;
125
- yield { file: imp, i: i += 1, errors, total: files.length, duration };
126
- if ((Date.now() - lastSent) > 50) { // Limit to 1 every 50ms
121
+ yield { file: imp, i: (i += 1), errors, total: files.length, duration };
122
+ if (Date.now() - lastSent > 50) {
123
+ // Limit to 1 every 50ms
127
124
  lastSent = Date.now();
128
125
  EventUtil.sendEvent('progress', { total: files.length, idx: i, message: imp, operation: 'compile' });
129
126
  }
@@ -154,7 +151,7 @@ export class Compiler {
154
151
 
155
152
  const metrics: CompileEmitEvent[] = [];
156
153
  const isCompilerChanged = this.#deltaEvents.some(event => this.#state.isCompilerFile(event.sourceFile));
157
- const changedFiles = (isCompilerChanged ? this.#state.getAllFiles() : this.#deltaEvents.map(event => event.sourceFile));
154
+ const changedFiles = isCompilerChanged ? this.#state.getAllFiles() : this.#deltaEvents.map(event => event.sourceFile);
158
155
 
159
156
  if (changedFiles.length) {
160
157
  for await (const event of this.emit(changedFiles)) {
@@ -174,9 +171,9 @@ export class Compiler {
174
171
  log.debug('Compilation aborted');
175
172
  } else if (failures.size) {
176
173
  const sortedFailures = [...failures.entries()].sort((a, b) => a[0].localeCompare(b[0]));
177
- log.error('Compilation failed',
178
- ['', sortedFailures.flatMap(([file, count]) => `- ${file}: ${count} errors found`)]
179
- .flat(3).join('\n')
174
+ log.error(
175
+ 'Compilation failed',
176
+ ['', sortedFailures.flatMap(([file, count]) => `- ${file}: ${count} errors found`)].flat(3).join('\n')
180
177
  );
181
178
  } else {
182
179
  log.debug('Compilation succeeded');
@@ -249,4 +246,4 @@ export class Compiler {
249
246
 
250
247
  this.#shutdown('complete');
251
248
  }
252
- }
249
+ }
package/src/event.ts CHANGED
@@ -3,14 +3,16 @@ import type { CompilerEvent, CompilerEventPayload, CompilerEventType } from './t
3
3
  const VALID_EVENT_TYPES = new Set<CompilerEventType>(['change', 'log', 'progress', 'state', 'all', 'file']);
4
4
 
5
5
  export class EventUtil {
6
-
7
- // eslint-disable-next-line @typescript-eslint/consistent-type-assertions
8
6
  static isComplilerEventType = (value: string): value is CompilerEventType => VALID_EVENT_TYPES.has(value as CompilerEventType);
9
7
 
10
8
  static isCompilerEvent = (value: unknown): value is CompilerEvent =>
11
- typeof value === 'object' && value !== null && 'type' in value && typeof value.type === 'string' && EventUtil.isComplilerEventType(value.type);
9
+ typeof value === 'object' &&
10
+ value !== null &&
11
+ 'type' in value &&
12
+ typeof value.type === 'string' &&
13
+ EventUtil.isComplilerEventType(value.type);
12
14
 
13
15
  static sendEvent<K extends CompilerEventType, T extends CompilerEventPayload<K>>(type: K, payload: T): void {
14
- process.connected && process.send!({ type, payload }, undefined, undefined, () => { });
16
+ process.connected && process.send!({ type, payload }, undefined, undefined, () => {});
15
17
  }
16
- }
18
+ }
package/src/log.ts CHANGED
@@ -15,7 +15,6 @@ export type LogShape = Record<'info' | 'debug' | 'warn' | 'error', (message: str
15
15
  const ESC = '\x1b[';
16
16
 
17
17
  export class Logger implements LogConfig, LogShape {
18
-
19
18
  static #linePartial: boolean | undefined;
20
19
 
21
20
  /** Rewrite text line, tracking cleanup as necessary */
@@ -23,7 +22,8 @@ export class Logger implements LogConfig, LogShape {
23
22
  if ((!text && !this.#linePartial) || !process.stdout.isTTY) {
24
23
  return;
25
24
  }
26
- if (this.#linePartial === undefined) { // First time
25
+ if (this.#linePartial === undefined) {
26
+ // First time
27
27
  process.stdout.write(`${ESC}?25l`); // Hide cursor
28
28
  process.on('exit', () => this.reset());
29
29
  }
@@ -35,7 +35,9 @@ export class Logger implements LogConfig, LogShape {
35
35
  }
36
36
  }
37
37
 
38
- static reset(): void { process.stdout.write(`${ESC}!p${ESC}?25h`); }
38
+ static reset(): void {
39
+ process.stdout.write(`${ESC}!p${ESC}?25h`);
40
+ }
39
41
 
40
42
  level?: CompilerLogLevel | 'none';
41
43
  root: string = process.cwd();
@@ -47,28 +49,38 @@ export class Logger implements LogConfig, LogShape {
47
49
  }
48
50
 
49
51
  valid(event: CompilerLogEvent): boolean {
50
- return LEVEL_TO_PRIORITY[this.level ?? this.parent?.level!] <= LEVEL_TO_PRIORITY[event.level];
52
+ return LEVEL_TO_PRIORITY[this.level ?? this.parent?.level ?? 'none'] <= LEVEL_TO_PRIORITY[event.level];
51
53
  }
52
54
 
53
55
  /** Log event with filtering by level */
54
56
  render(event: CompilerLogEvent): void {
55
- if (!this.valid(event)) { return; }
56
- const params = [event.message, ...event.args ?? []]
57
- .map(arg => typeof arg === 'string' ? arg.replaceAll(this.root ?? this.parent?.root!, '.') : arg);
57
+ if (!this.valid(event)) {
58
+ return;
59
+ }
60
+ const params = [event.message, ...(event.args ?? [])].map(arg =>
61
+ typeof arg === 'string' ? arg.replaceAll(this.root ?? this.parent?.root, '.') : arg
62
+ );
58
63
 
59
64
  if (event.scope ?? this.scope) {
60
65
  params.unshift(`[${(event.scope ?? this.scope!).padEnd(SCOPE_MAX, ' ')}]`);
61
66
  }
62
67
  params.unshift(new Date().toISOString(), `${event.level.padEnd(5)}`);
63
68
  Logger.rewriteLine(''); // Clear out progress line, if active
64
- // eslint-disable-next-line no-console
65
69
  console[event.level]!(...params);
66
70
  }
67
71
 
68
- info(message: string, ...args: unknown[]): void { return this.render({ level: 'info', message, args }); }
69
- debug(message: string, ...args: unknown[]): void { return this.render({ level: 'debug', message, args }); }
70
- warn(message: string, ...args: unknown[]): void { return this.render({ level: 'warn', message, args }); }
71
- error(message: string, ...args: unknown[]): void { return this.render({ level: 'error', message, args }); }
72
+ info(message: string, ...args: unknown[]): void {
73
+ this.render({ level: 'info', message, args });
74
+ }
75
+ debug(message: string, ...args: unknown[]): void {
76
+ this.render({ level: 'debug', message, args });
77
+ }
78
+ warn(message: string, ...args: unknown[]): void {
79
+ this.render({ level: 'warn', message, args });
80
+ }
81
+ error(message: string, ...args: unknown[]): void {
82
+ this.render({ level: 'error', message, args });
83
+ }
72
84
  }
73
85
 
74
86
  class $RootLogger extends Logger {
@@ -86,9 +98,17 @@ class $RootLogger extends Logger {
86
98
  initLevel(defaultLevel: CompilerLogLevel | 'none'): void {
87
99
  const value = process.env.TRV_QUIET !== 'true' ? process.env.TRV_BUILD : 'none';
88
100
  switch (value) {
89
- case 'debug': case 'warn': case 'error': case 'info': this.level = value; break;
90
- case undefined: this.level = defaultLevel; break;
91
- case 'none': default: this.level = 'none';
101
+ case 'debug':
102
+ case 'warn':
103
+ case 'error':
104
+ case 'info':
105
+ this.level = value;
106
+ break;
107
+ case undefined:
108
+ this.level = defaultLevel;
109
+ break;
110
+ default:
111
+ this.level = 'none';
92
112
  }
93
113
  }
94
114
 
@@ -100,21 +120,34 @@ class $RootLogger extends Logger {
100
120
  /** Scope and provide a callback pattern for access to a logger */
101
121
  wrap<T = unknown>(scope: string, operation: (log: Logger) => Promise<T>, basic = true): Promise<T> {
102
122
  const logger = this.scoped(scope);
103
- return basic ? (logger.debug('Started'), operation(logger).finally(() => logger.debug('Completed'))) : operation(logger);
123
+ if (basic) {
124
+ logger.debug('Started');
125
+ return operation(logger).finally(() => logger.debug('Completed'));
126
+ } else {
127
+ return operation(logger);
128
+ }
104
129
  }
105
130
 
106
131
  /** Write progress event, if active */
107
132
  onProgressEvent(event: CompilerProgressEvent): void | Promise<void> {
108
- if (!(this.logProgress)) { return; }
109
- const progress = Math.trunc(event.idx * 100 / event.total);
110
- const text = event.complete ? '' : `Compiling [${'#'.repeat(Math.trunc(progress / 10)).padEnd(10, ' ')}] [${event.idx}/${event.total}] ${event.message}`;
133
+ if (!this.logProgress) {
134
+ return;
135
+ }
136
+ const progress = Math.trunc((event.idx * 100) / event.total);
137
+ const text = event.complete
138
+ ? ''
139
+ : `Compiling [${'#'.repeat(Math.trunc(progress / 10)).padEnd(10, ' ')}] [${event.idx}/${event.total}] ${event.message}`;
111
140
  return Logger.rewriteLine(text);
112
141
  }
113
142
 
114
143
  /** Write all progress events if active */
115
144
  async consumeProgressEvents(input: () => AsyncIterable<CompilerProgressEvent>): Promise<void> {
116
- if (!(this.logProgress)) { return; }
117
- for await (const event of input()) { this.onProgressEvent(event); }
145
+ if (!this.logProgress) {
146
+ return;
147
+ }
148
+ for await (const event of input()) {
149
+ this.onProgressEvent(event);
150
+ }
118
151
  Logger.reset();
119
152
  }
120
153
  }
@@ -123,7 +156,9 @@ export const Log = new $RootLogger();
123
156
 
124
157
  export class IpcLogger extends Logger {
125
158
  render(event: CompilerLogEvent): void {
126
- if (!this.valid(event)) { return; }
159
+ if (!this.valid(event)) {
160
+ return;
161
+ }
127
162
  if (process.connected && process.send) {
128
163
  process.send({ type: 'log', payload: event });
129
164
  }
package/src/queue.ts CHANGED
@@ -10,7 +10,9 @@ export class AsyncQueue<X> implements AsyncIterator<X>, AsyncIterable<X> {
10
10
  }
11
11
  }
12
12
 
13
- [Symbol.asyncIterator](): AsyncIterator<X> { return this; }
13
+ [Symbol.asyncIterator](): AsyncIterator<X> {
14
+ return this;
15
+ }
14
16
 
15
17
  async next(): Promise<IteratorResult<X>> {
16
18
  while (!this.#done && !this.#queue.length) {
@@ -35,4 +37,4 @@ export class AsyncQueue<X> implements AsyncIterator<X>, AsyncIterable<X> {
35
37
  this.#done = true;
36
38
  this.#ready.resolve();
37
39
  }
38
- }
40
+ }
@@ -1,13 +1,13 @@
1
- import rl from 'node:readline/promises';
2
- import timers from 'node:timers/promises';
3
1
  import fs from 'node:fs/promises';
4
2
  import http, { Agent } from 'node:http';
3
+ import rl from 'node:readline/promises';
4
+ import timers from 'node:timers/promises';
5
5
 
6
6
  import type { ManifestContext } from '@travetto/manifest';
7
7
 
8
- import type { CompilerEventPayload, CompilerEventType, CompilerServerInfo, CompilerStateType } from '../types.ts';
9
- import type { LogShape } from '../log.ts';
10
8
  import { CommonUtil } from '../common.ts';
9
+ import type { LogShape } from '../log.ts';
10
+ import type { CompilerEventPayload, CompilerEventType, CompilerServerInfo, CompilerStateType } from '../types.ts';
11
11
  import { ProcessHandle } from './process-handle.ts';
12
12
 
13
13
  type FetchEventsConfig<T> = {
@@ -26,7 +26,6 @@ const streamAgent = new Agent({
26
26
  * Compiler Client Operations
27
27
  */
28
28
  export class CompilerClient {
29
-
30
29
  #url: string;
31
30
  #log: LogShape;
32
31
  #handle: Record<'compiler' | 'server', ProcessHandle>;
@@ -47,17 +46,18 @@ export class CompilerClient {
47
46
  return this.#url;
48
47
  }
49
48
 
50
- async #fetch(urlPath: string, options?: RequestInit & { timeout?: number }, logTimeout = true): Promise<{ ok: boolean, text: string }> {
49
+ async #fetch(urlPath: string, options?: RequestInit & { timeout?: number }, logTimeout = true): Promise<{ ok: boolean; text: string }> {
51
50
  const controller = new AbortController();
52
51
  const timeoutController = new AbortController();
53
52
 
54
53
  options?.signal?.addEventListener('abort', () => controller.abort());
55
- timers.setTimeout(options?.timeout ?? 100, undefined, { ref: false, signal: timeoutController.signal })
54
+ timers
55
+ .setTimeout(options?.timeout ?? 100, undefined, { ref: false, signal: timeoutController.signal })
56
56
  .then(() => {
57
57
  logTimeout && this.#log.error(`Timeout on request to ${this.#url}${urlPath}`);
58
58
  controller.abort('TIMEOUT');
59
59
  })
60
- .catch(() => { });
60
+ .catch(() => {});
61
61
  const response = await fetch(`${this.#url}${urlPath}`, { ...options, signal: controller.signal });
62
62
  const out = { ok: response.ok, text: await response.text() };
63
63
  timeoutController.abort();
@@ -66,7 +66,10 @@ export class CompilerClient {
66
66
 
67
67
  /** Get server information, if server is running */
68
68
  info(): Promise<CompilerServerInfo | undefined> {
69
- return this.#fetch('/info', { timeout: 200 }, false).then(response => JSON.parse(response.text), () => undefined);
69
+ return this.#fetch('/info', { timeout: 200 }, false).then(
70
+ response => JSON.parse(response.text),
71
+ () => undefined
72
+ );
70
73
  }
71
74
 
72
75
  async isWatching(): Promise<boolean> {
@@ -75,13 +78,19 @@ export class CompilerClient {
75
78
 
76
79
  /** Clean the server */
77
80
  async clean(forceOnFailure?: boolean): Promise<boolean> {
78
- const result = await this.#fetch('/clean', { timeout: 300 }).then(response => response.ok, () => false);
81
+ const result = await this.#fetch('/clean', { timeout: 300 }).then(
82
+ response => response.ok,
83
+ () => false
84
+ );
79
85
  if (!result && forceOnFailure) {
80
86
  this.#log.warn('Clean request failed, forcing cleanup');
81
87
  try {
82
- await Promise.all([this.#ctx.build.outputFolder, this.#ctx.build.typesFolder]
83
- .map(file => fs.rm(CommonUtil.resolveWorkspace(this.#ctx, file), { force: true, recursive: true })));
84
- } catch { }
88
+ await Promise.all(
89
+ [this.#ctx.build.outputFolder, this.#ctx.build.typesFolder].map(file =>
90
+ fs.rm(CommonUtil.resolveWorkspace(this.#ctx, file), { force: true, recursive: true })
91
+ )
92
+ );
93
+ } catch {}
85
94
  }
86
95
  return result;
87
96
  }
@@ -91,18 +100,20 @@ export class CompilerClient {
91
100
  const info = await this.info();
92
101
  if (!info) {
93
102
  this.#log.debug('Stopping server, info not found, manual killing');
94
- return Promise.all([this.#handle.server.kill(), this.#handle.compiler.kill()])
95
- .then(results => results.some(result => result));
103
+ return Promise.all([this.#handle.server.kill(), this.#handle.compiler.kill()]).then(results => results.some(result => result));
96
104
  }
97
105
 
98
- await this.#fetch('/stop').catch(() => { }); // Trigger
106
+ await this.#fetch('/stop').catch(() => {}); // Trigger
99
107
  this.#log.debug('Waiting for compiler to exit');
100
108
  await this.#handle.compiler.ensureKilled();
101
109
  return true;
102
110
  }
103
111
 
104
112
  /** Fetch compiler events */
105
- async * fetchEvents<V extends CompilerEventType, T extends CompilerEventPayload<V>>(type: V, config: FetchEventsConfig<T> = {}): AsyncIterable<T> {
113
+ async *fetchEvents<V extends CompilerEventType, T extends CompilerEventPayload<V>>(
114
+ type: V,
115
+ config: FetchEventsConfig<T> = {}
116
+ ): AsyncIterable<T> {
106
117
  let info = await this.info();
107
118
  if (!info) {
108
119
  return;
@@ -121,14 +132,13 @@ export class CompilerClient {
121
132
 
122
133
  const { iteration } = info;
123
134
 
124
- for (; ;) {
135
+ for (;;) {
125
136
  const controller = new AbortController();
126
137
  const quit = (): void => controller.abort();
127
138
  try {
128
139
  signal.addEventListener('abort', quit);
129
140
  const response = await new Promise<http.IncomingMessage>((resolve, reject) =>
130
- http.get(`${this.#url}/event/${type}`, { agent: streamAgent, signal: controller.signal }, resolve)
131
- .on('error', reject)
141
+ http.get(`${this.#url}/event/${type}`, { agent: streamAgent, signal: controller.signal }, resolve).on('error', reject)
132
142
  );
133
143
 
134
144
  for await (const line of rl.createInterface(response)) {
@@ -143,7 +153,9 @@ export class CompilerClient {
143
153
  }
144
154
  } catch (error) {
145
155
  const aborted = controller.signal.aborted || (typeof error === 'object' && error && 'code' in error && error.code === 'ECONNRESET');
146
- if (!aborted) { throw error; }
156
+ if (!aborted) {
157
+ throw error;
158
+ }
147
159
  }
148
160
  signal.removeEventListener('abort', quit);
149
161
 
@@ -156,7 +168,8 @@ export class CompilerClient {
156
168
  return;
157
169
  }
158
170
 
159
- if (controller.signal.aborted || !info || (config.enforceIteration && info.iteration !== iteration)) { // If health check fails, or aborted
171
+ if (controller.signal.aborted || !info || (config.enforceIteration && info.iteration !== iteration)) {
172
+ // If health check fails, or aborted
160
173
  this.#log.debug(`Stopping watch for events of type "${type}"`);
161
174
  return;
162
175
  } else {
@@ -170,10 +183,11 @@ export class CompilerClient {
170
183
  const set = new Set(states);
171
184
  // Loop until
172
185
  this.#log.debug(`Waiting for states, ${states.join(', ')}`);
173
- for await (const _ of this.fetchEvents('state', { signal, until: event => set.has(event.state) })) { }
186
+ for await (const _ of this.fetchEvents('state', { signal, until: event => set.has(event.state) })) {
187
+ }
174
188
  this.#log.debug(`Found state, one of ${states.join(', ')} `);
175
189
  if (message) {
176
190
  this.#log.info(message);
177
191
  }
178
192
  }
179
- }
193
+ }