@travetto/compiler 3.4.0-rc.0 → 3.4.0-rc.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/README.md CHANGED
@@ -21,7 +21,7 @@ This module expands upon the [Typescript](https://typescriptlang.org) compiler,
21
21
  Beyond the [Typescript](https://typescriptlang.org) compiler functionality, the module provides the primary entry point into the development process.
22
22
 
23
23
  ## CLI
24
- The compiler cli, [trvc](https://github.com/travetto/travetto/tree/main/module/compiler/bin/trvc.js#L7) is a compilation aware entry point, that 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, always builds the entire project. With the efficient caching behavior, this leads to generally a minimal overhead but allows for centralization of all operations.
24
+ The compiler cli, [trvc](https://github.com/travetto/travetto/tree/main/module/compiler/bin/trvc.js#L4) 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
25
 
26
26
  The compiler cli supports the following operations:
27
27
  * `start|watch` - Run the compiler in watch mode
@@ -37,7 +37,7 @@ In addition to the normal output, the compiler supports an environment variable
37
37
  ```bash
38
38
  $ TRV_BUILD=debug trvc build
39
39
 
40
- 2029-03-14T04:00:00.618Z info [compiler-server] Starting server http://127.0.0.1:29222
40
+ 2029-03-14T04:00:00.618Z info [compiler-server] Starting server http://127.0.0.1:25539
41
41
  2029-03-14T04:00:00.837Z debug [compiler-client] Starting watch for events of type "log"
42
42
  2029-03-14T04:00:01.510Z debug [event-stream ] Started event stream
43
43
  2029-03-14T04:00:02.450Z debug [precompile ] Started
@@ -86,4 +86,4 @@ The compiler will move through the following phases on a given compilation execu
86
86
  * `Invoke Compiler` - Run [Typescript](https://typescriptlang.org) compiler with the aforementioned enhancements
87
87
 
88
88
  ### Bootstrapping
89
- Given that the framework is distributed as [Typescript](https://typescriptlang.org) only files, there is a bootstrapping problem that needs to be mitigated. The [trvc](https://github.com/travetto/travetto/tree/main/module/compiler/bin/trvc.js#L7) entrypoint, along with a small context utility in [Manifest](https://github.com/travetto/travetto/tree/main/module/manifest#readme "Support for project indexing, manifesting, along with file watching") are the only [Javascript](https://developer.mozilla.org/en-US/docs/Web/JavaScript) files needed to run the project. The [trvc](https://github.com/travetto/travetto/tree/main/module/compiler/bin/trvc.js#L7) entry point will compile `@travetto/compiler/support/*` files as the set that is used at startup. These files are also accessible to the compiler as they get re-compiled after the fact.
89
+ Given that the framework is distributed as [Typescript](https://typescriptlang.org) only files, there is a bootstrapping problem that needs to be mitigated. The [trvc](https://github.com/travetto/travetto/tree/main/module/compiler/bin/trvc.js#L4) entrypoint, along with a small context utility in [Manifest](https://github.com/travetto/travetto/tree/main/module/manifest#readme "Support for project indexing, manifesting, along with file watching") are the only [Javascript](https://developer.mozilla.org/en-US/docs/Web/JavaScript) files needed to run the project. The [trvc](https://github.com/travetto/travetto/tree/main/module/compiler/bin/trvc.js#L4) entry point will compile `@travetto/compiler/support/*` files as the set that is used at startup. These files are also accessible to the compiler as they get re-compiled after the fact.
package/bin/common.js CHANGED
@@ -8,11 +8,9 @@ import { getManifestContext } from '@travetto/manifest/bin/context.js';
8
8
 
9
9
  const COMPILER_FILES = [...['entry.trvc', 'log', 'queue', 'server/client', 'server/runner', 'server/server', 'setup', 'util'].map(x => `support/${x}.ts`), 'package.json'];
10
10
 
11
- /** @typedef {import('@travetto/manifest/src/types').ManifestContext} Ctx */
12
- /** @typedef {import('@travetto/compiler/support/types').EntryOp} EntryOp */
13
-
14
- /** @return {Promise<import('@travetto/compiler/support/entry.trvc').main>} */
15
- const $getEntry = async (/** @type {Ctx} */ ctx) => {
11
+ /** @return {Promise<ReturnType<import('@travetto/compiler/support/entry.trvc').main>>} */
12
+ export const getEntry = async () => {
13
+ const ctx = await getManifestContext();
16
14
  const tsconfigFile = path.resolve(ctx.workspacePath, 'tsconfig.json');
17
15
  if (!(await fs.stat(tsconfigFile).catch(() => undefined))) {
18
16
  await fs.writeFile(tsconfigFile, JSON.stringify({ extends: '@travetto/compiler/tsconfig.trv.json' }), 'utf8');
@@ -50,21 +48,8 @@ const $getEntry = async (/** @type {Ctx} */ ctx) => {
50
48
  files.push(target);
51
49
  }
52
50
 
53
- try { return require(files[0]).main; }
54
- catch { return import(files[0]).then(x => x.main); }
55
- };
56
-
57
- async function $compile(/** @type {Ctx} ctx*/ ctx, /** @type {EntryOp} op */ op) {
58
51
  const rootCtx = await (ctx.monoRepo ? getManifestContext(ctx.workspacePath) : ctx);
59
- return (await $getEntry(ctx))(ctx, rootCtx, op, process.argv.slice(3));
60
- }
61
52
 
62
- /**
63
- * @template T
64
- * @param {(ctx: Ctx, compile: typeof $compile) => Promise<T>} fn
65
- * @returns {Promise<T>}
66
- */
67
- export async function withContext(fn) {
68
- const ctx = await getManifestContext();
69
- return fn(ctx, $compile);
70
- }
53
+ try { return require(files[0]).main(rootCtx, ctx); }
54
+ catch { return import(files[0]).then(v => v.main(rootCtx, ctx)); }
55
+ };
package/bin/trvc.js CHANGED
@@ -1,34 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
 
3
3
  // @ts-check
4
- import fs from 'fs/promises';
5
- import path from 'path';
6
-
7
- import { withContext } from './common.js';
8
-
9
- /** @typedef {import('@travetto/manifest/src/types').ManifestContext} Ctx */
10
-
11
- const stop = async (/** @typedef {Ctx} */ ctx) => {
12
- if (await fetch(`${ctx.compilerUrl}/stop`).then(v => v.ok, () => false)) {
13
- console.log(`Stopped server ${ctx.workspacePath}: [${ctx.compilerUrl}]`);
14
- } else {
15
- console.log(`Server not running ${ctx.workspacePath}: [${ctx.compilerUrl}]`);
16
- }
17
- };
18
-
19
- const info = async (/** @typedef {Ctx} */ctx) => console.log(
20
- JSON.stringify(await fetch(ctx.compilerUrl).then(v => v.json(), () => undefined) ?? { state: 'Server not running' }, null, 2)
21
- );
22
-
23
- const clean = async (/** @typedef {Ctx} */ctx) => {
24
- const folders = [ctx.outputFolder, ctx.compilerFolder];
25
- if (await fetch(`${ctx.compilerUrl}/clean`).then(v => v.ok, () => false)) {
26
- return console.log(`Clean triggered ${ctx.workspacePath}:`, folders);
27
- } else {
28
- await Promise.all(folders.map(f => fs.rm(path.resolve(ctx.workspacePath, f), { force: true, recursive: true })));
29
- return console.log(`Cleaned ${ctx.workspacePath}:`, folders);
30
- }
31
- };
4
+ import { getEntry } from './common.js';
32
5
 
33
6
  const help = () => [
34
7
  'npx trvc [command]',
@@ -43,20 +16,20 @@ const help = () => [
43
16
  ' * manifest - Generate the project manifest',
44
17
  ].join('\n');
45
18
 
46
- withContext(async (ctx, compile) => {
47
- const op = process.argv[2];
19
+ getEntry().then(async (ops) => {
20
+ const [op, ...args] = process.argv.slice(2);
48
21
 
49
22
  switch (op) {
50
- case 'restart': return stop(ctx).then(() => compile(ctx, 'watch'));
51
- case 'stop': return stop(ctx);
52
- case 'info': return info(ctx);
53
- case 'clean': return clean(ctx);
54
- case 'watch':
55
- case 'start': return compile(ctx, 'watch');
56
- case 'build':
57
- case 'manifest': return compile(ctx, op);
58
23
  case undefined:
59
24
  case 'help': return console.log(`\n${help()}\n`);
25
+ case 'restart': return ops.stop().then(() => ops.compile('watch'));
26
+ case 'stop': return ops.stop();
27
+ case 'info': return ops.info().then(v => console.log(JSON.stringify(v, null, 2)));
28
+ case 'clean': return ops.clean();
29
+ case 'manifest': return ops.manifest(args);
30
+ case 'start': return ops.compile('watch');
31
+ case 'watch':
32
+ case 'build': return ops.compile(op);
60
33
  default: console.error(`Unknown trvc operation: ${op}\n`); return console.error(help());
61
34
  }
62
35
  });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@travetto/compiler",
3
- "version": "3.4.0-rc.0",
3
+ "version": "3.4.0-rc.2",
4
4
  "description": "The compiler infrastructure for the Travetto framework",
5
5
  "keywords": [
6
6
  "compiler",
@@ -31,13 +31,13 @@
31
31
  },
32
32
  "dependencies": {
33
33
  "@parcel/watcher": "^2.3.0",
34
- "@travetto/manifest": "^3.4.0-rc.0",
34
+ "@travetto/manifest": "^3.4.0-rc.3",
35
35
  "@travetto/terminal": "^3.4.0-rc.0",
36
- "@travetto/transformer": "^3.4.0-rc.0",
37
- "@types/node": "^20.8.9"
36
+ "@travetto/transformer": "^3.4.0-rc.2",
37
+ "@types/node": "^20.8.10"
38
38
  },
39
39
  "peerDependencies": {
40
- "@travetto/cli": "^3.4.0-rc.0"
40
+ "@travetto/cli": "^3.4.0-rc.3"
41
41
  },
42
42
  "peerDependenciesMeta": {
43
43
  "@travetto/cli": {
@@ -46,7 +46,7 @@
46
46
  },
47
47
  "travetto": {
48
48
  "displayName": "Compiler",
49
- "profiles": [
49
+ "roles": [
50
50
  "compile"
51
51
  ]
52
52
  },
@@ -1,39 +1,73 @@
1
+ import fs from 'fs/promises';
2
+ import path from 'path';
3
+
1
4
  import type { ManifestContext } from '@travetto/manifest';
2
5
 
3
6
  import { LogUtil } from './log';
4
7
  import { CompilerSetup } from './setup';
5
8
  import { CompilerServer } from './server/server';
6
9
  import { CompilerRunner } from './server/runner';
7
- import type { BuildOp, EntryOp } from './types';
10
+ import type { CompilerOp, CompilerServerInfo } from './types';
8
11
  import { CompilerClientUtil } from './server/client';
9
12
  import { CommonUtil } from './util';
10
13
 
11
- async function build(root: ManifestContext, op: BuildOp): Promise<void> {
12
- const server = await new CompilerServer(root, op).listen();
13
-
14
- // Wait for build to be ready
15
- if (server) {
16
- await server.processEvents(async function* (signal) {
17
- const { changed, manifest } = await CompilerSetup.setup(root);
18
- yield* CompilerRunner.runProcess(root, manifest, changed, op === 'watch', signal);
19
- });
20
- } else {
21
- await CompilerClientUtil.waitForBuild(root);
22
- }
23
- }
24
-
25
- /**
26
- * Main entry point for trv.js
27
- */
28
- export async function main(ctx: ManifestContext, root: ManifestContext, op: EntryOp, args: (string | undefined)[] = []): Promise<((mod: string) => Promise<unknown>) | undefined> {
29
- LogUtil.initLogs(ctx, op);
30
- switch (op) {
31
- case 'manifest': await CompilerSetup.exportManifest(ctx, ...args.filter(x => !x?.startsWith('-'))); return;
32
- case 'watch':
33
- case 'build': await build(root, op); return;
34
- case 'run': {
35
- await build(root, 'build');
14
+ // eslint-disable-next-line @typescript-eslint/explicit-function-return-type
15
+ export const main = (root: ManifestContext, ctx: ManifestContext) => {
16
+ const ops = {
17
+ /** Stop the server */
18
+ async stop(): Promise<void> {
19
+ if (await fetch(`${ctx.compilerUrl}/stop`).then(v => v.ok, () => false)) {
20
+ console.log(`Stopped server ${ctx.workspacePath}: [${ctx.compilerUrl}]`);
21
+ } else {
22
+ console.log(`Server not running ${ctx.workspacePath}: [${ctx.compilerUrl}]`);
23
+ }
24
+ },
25
+
26
+ /** Get server info */
27
+ info(): Promise<CompilerServerInfo> {
28
+ // eslint-disable-next-line @typescript-eslint/consistent-type-assertions
29
+ return fetch(ctx.compilerUrl).then(v => v.json(), () => ({ state: 'Server not running' })) as Promise<CompilerServerInfo>;
30
+ },
31
+
32
+ /** Clean the server */
33
+ async clean(): Promise<void> {
34
+ const folders = [ctx.outputFolder, ctx.compilerFolder];
35
+ if (await fetch(`${ctx.compilerUrl}/clean`).then(v => v.ok, () => false)) {
36
+ return console.log(`Clean triggered ${ctx.workspacePath}:`, folders);
37
+ } else {
38
+ await Promise.all(folders.map(f => fs.rm(path.resolve(ctx.workspacePath, f), { force: true, recursive: true })));
39
+ return console.log(`Cleaned ${ctx.workspacePath}:`, folders);
40
+ }
41
+ },
42
+
43
+ /** Main entry point for compilation */
44
+ async compile(op: CompilerOp, setupOnly = false): Promise<(mod: string) => Promise<unknown>> {
45
+ LogUtil.initLogs(ctx, op === 'run' ? 'error' : 'info');
46
+
47
+ const server = await new CompilerServer(root, op).listen();
48
+
49
+ // Wait for build to be ready
50
+ if (server) {
51
+ await server.processEvents(async function* (signal) {
52
+ const { changed, manifest } = await CompilerSetup.setup(root);
53
+ if (!setupOnly) {
54
+ yield* CompilerRunner.runProcess(root, manifest, changed, op, signal);
55
+ } else {
56
+ yield* [];
57
+ }
58
+ });
59
+ } else {
60
+ await CompilerClientUtil.waitForBuild(root);
61
+ }
36
62
  return CommonUtil.moduleLoader(ctx);
63
+ },
64
+
65
+ /** Manifest entry point */
66
+ async manifest(args: (string | undefined)[] = []): Promise<void> {
67
+ await ops.compile('run', true);
68
+ await CompilerSetup.exportManifest(ctx, ...args.filter(x => !x?.startsWith('-'))); return;
37
69
  }
38
- }
39
- }
70
+ };
71
+ return ops;
72
+ };
73
+
package/support/log.ts CHANGED
@@ -1,10 +1,10 @@
1
1
  import type { ManifestContext } from '@travetto/manifest';
2
- import type { CompilerLogEvent, CompilerLogLevel, EntryOp } from './types';
2
+ import type { CompilerLogEvent, CompilerLogLevel } from './types';
3
3
 
4
4
  export type CompilerLogger = (level: CompilerLogLevel, message: string, ...args: unknown[]) => void;
5
5
  export type WithLogger<T> = (log: CompilerLogger) => Promise<T>;
6
6
 
7
- const LEVEL_TO_PRI = Object.fromEntries((['debug', 'info', 'warn', 'error'] as const).map((x, i) => [x, i + 1]));
7
+ const LEVEL_TO_PRI: Record<CompilerLogLevel, number> = { debug: 1, info: 2, warn: 3, error: 4 };
8
8
 
9
9
  const SCOPE_MAX = 15;
10
10
 
@@ -12,20 +12,27 @@ export class LogUtil {
12
12
 
13
13
  static root = process.cwd();
14
14
 
15
- static logLevel?: CompilerLogLevel;
15
+ static logLevel: CompilerLogLevel = 'error';
16
16
 
17
17
  /**
18
18
  * Set level for operation
19
19
  */
20
- static initLogs(ctx: ManifestContext, op: EntryOp): void {
20
+ static initLogs(ctx: ManifestContext, defaultLevel: CompilerLogLevel): void {
21
21
  // Listen only if we aren't in quiet
22
- if ((process.env.TRV_BUILD || !process.env.TRV_QUIET) && op !== 'manifest') {
22
+ if ((process.env.TRV_BUILD || !process.env.TRV_QUIET)) {
23
23
  // eslint-disable-next-line @typescript-eslint/consistent-type-assertions
24
- this.logLevel = (process.env.TRV_BUILD as 'debug') ?? (op === 'run' ? 'warn' : 'info');
24
+ this.logLevel = (process.env.TRV_BUILD as 'debug') || defaultLevel;
25
25
  }
26
26
  this.root = ctx.workspacePath;
27
27
  }
28
28
 
29
+ /**
30
+ * Is the log level active?
31
+ */
32
+ static isLevelActive(lvl: CompilerLogLevel): boolean {
33
+ return LEVEL_TO_PRI[this.logLevel] <= LEVEL_TO_PRI[lvl];
34
+ }
35
+
29
36
  /**
30
37
  * Log message with filtering by level
31
38
  */
@@ -46,7 +53,7 @@ export class LogUtil {
46
53
  * Compiler log event to console
47
54
  */
48
55
  static sendLogEventToConsole(ev: CompilerLogEvent): void {
49
- if (this.logLevel && LEVEL_TO_PRI[this.logLevel] <= LEVEL_TO_PRI[ev.level]) {
56
+ if (this.isLevelActive(ev.level)) {
50
57
  const params = [ev.message, ...ev.args ?? []].map(x => typeof x === 'string' ? x.replaceAll(LogUtil.root, '.') : x);
51
58
  if (ev.scope) {
52
59
  params.unshift(`[${ev.scope.padEnd(SCOPE_MAX, ' ')}]`);
@@ -3,7 +3,7 @@ import path from 'path';
3
3
 
4
4
  import type { ManifestContext, ManifestRoot, DeltaEvent } from '@travetto/manifest';
5
5
 
6
- import type { CompilerProgressEvent, CompilerServerEvent } from '../types';
6
+ import type { CompilerOp, CompilerProgressEvent, CompilerServerEvent } from '../types';
7
7
  import { AsyncQueue } from '../queue';
8
8
  import { LogUtil } from '../log';
9
9
  import { CommonUtil } from '../util';
@@ -35,7 +35,8 @@ export class CompilerRunner {
35
35
  /**
36
36
  * Run compile process
37
37
  */
38
- static async* runProcess(ctx: ManifestContext, manifest: ManifestRoot, changed: DeltaEvent[], watch: boolean, signal: AbortSignal): AsyncIterable<CompilerServerEvent> {
38
+ static async* runProcess(ctx: ManifestContext, manifest: ManifestRoot, changed: DeltaEvent[], op: CompilerOp, signal: AbortSignal): AsyncIterable<CompilerServerEvent> {
39
+ const watch = op === 'watch';
39
40
  if (!changed.length && !watch) {
40
41
  yield { type: 'state', payload: { state: 'compile-end' } };
41
42
  log('debug', 'Skipped');
@@ -44,8 +45,10 @@ export class CompilerRunner {
44
45
  log('debug', `Started watch=${watch} changed=${changed.slice(0, 10).map(x => `${x.module}/${x.file}`)}`);
45
46
  }
46
47
 
47
- // Track progress
48
- this.trackProgress(ctx, CompilerClientUtil.fetchEvents(ctx, 'progress', signal, ev => !!ev.complete));
48
+ // Track progress if not in run mode
49
+ if (op !== 'run') {
50
+ this.trackProgress(ctx, CompilerClientUtil.fetchEvents(ctx, 'progress', signal, ev => !!ev.complete));
51
+ }
49
52
 
50
53
  const compiler = path.resolve(ctx.workspacePath, ctx.compilerFolder);
51
54
  const main = path.resolve(compiler, 'node_modules', '@travetto/compiler/support/entry.compiler.js');
@@ -4,7 +4,7 @@ import path from 'path';
4
4
 
5
5
  import type { ManifestContext } from '@travetto/manifest';
6
6
 
7
- import type { BuildOp, CompilerServerEvent, CompilerServerEventType, CompilerServerInfo } from '../types';
7
+ import type { CompilerMode, CompilerOp, CompilerServerEvent, CompilerServerEventType, CompilerServerInfo } from '../types';
8
8
  import { LogUtil } from '../log';
9
9
  import { CompilerClientUtil } from './client';
10
10
  import { CommonUtil } from '../util';
@@ -23,12 +23,12 @@ export class CompilerServer {
23
23
  signal = this.#shutdown.signal;
24
24
  info: CompilerServerInfo;
25
25
 
26
- constructor(ctx: ManifestContext, op: BuildOp) {
26
+ constructor(ctx: ManifestContext, op: CompilerOp) {
27
27
  this.#ctx = ctx;
28
28
  this.info = {
29
29
  state: 'startup',
30
30
  iteration: Date.now(),
31
- type: op,
31
+ mode: op === 'run' ? 'build' : op,
32
32
  serverPid: process.pid,
33
33
  compilerPid: -1,
34
34
  path: ctx.workspacePath,
@@ -45,8 +45,8 @@ export class CompilerServer {
45
45
  process.on('SIGINT', () => this.#shutdown.abort());
46
46
  }
47
47
 
48
- get op(): BuildOp {
49
- return this.info.type;
48
+ get mode(): CompilerMode {
49
+ return this.info.mode;
50
50
  }
51
51
 
52
52
  isResetEvent(ev: CompilerServerEvent): boolean {
@@ -60,7 +60,7 @@ export class CompilerServer {
60
60
  .on('error', async err => {
61
61
  if ('code' in err && err.code === 'EADDRINUSE') {
62
62
  const info = await CompilerClientUtil.getServerInfo(this.#ctx);
63
- resolve((info && info.type === 'build' && this.op === 'watch') ? 'retry' : 'running');
63
+ resolve((info && info.mode === 'build' && this.mode === 'watch') ? 'retry' : 'running');
64
64
  } else {
65
65
  reject(err);
66
66
  }
package/support/types.ts CHANGED
@@ -1,6 +1,5 @@
1
- export type BuildOp = 'build' | 'watch';
2
- export type EntryOp = BuildOp | 'manifest' | 'run';
3
- export type TotalOp = EntryOp | 'stop' | 'clean' | 'info';
1
+ export type CompilerMode = 'build' | 'watch';
2
+ export type CompilerOp = CompilerMode | 'run';
4
3
 
5
4
  export type CompilerStateType = 'startup' | 'init' | 'compile-start' | 'compile-end' | 'watch-start' | 'watch-end' | 'reset' | 'close';
6
5
  export type CompilerChangeEvent = { file: string, action: 'create' | 'update' | 'delete', folder: string, output: string, module: string, time: number };
@@ -22,7 +21,7 @@ export type CompilerServerInfo = {
22
21
  serverPid: number;
23
22
  compilerPid: number;
24
23
  state: CompilerStateType;
25
- type: BuildOp;
24
+ mode: CompilerMode,
26
25
  iteration: number;
27
26
  url: string;
28
27
  };