@travetto/compiler 6.0.0-rc.2 → 6.0.0

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
@@ -18,6 +18,7 @@ This module expands upon the [Typescript](https://typescriptlang.org) compiler,
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
20
  * Automatic addition of `.js` extension to imports to also support [Ecmascript Module](https://nodejs.org/api/esm.html)-style output
21
+
21
22
  Beyond the [Typescript](https://typescriptlang.org) compiler functionality, the module provides the primary entry point into the development process.
22
23
 
23
24
  ## CLI
@@ -33,6 +34,7 @@ The compiler cli supports the following operations:
33
34
  * `event <log|progress|state>` - Watch events in realtime as newline delimited JSON
34
35
  * `exec <file> [...args]` - Allow for compiling and executing an entrypoint file
35
36
  * `manifest --prod [output]` - Generate the project manifest
37
+
36
38
  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`.
37
39
 
38
40
  **Terminal: Sample trv output with debug logging**
package/__index__.ts CHANGED
@@ -1,5 +1,5 @@
1
- export * from './src/compiler';
2
- export * from './src/state';
3
- export * from './src/util';
4
- export * from './src/watch';
5
- export * from './src/types';
1
+ export * from './src/compiler.ts';
2
+ export * from './src/state.ts';
3
+ export * from './src/util.ts';
4
+ export * from './src/watch.ts';
5
+ export * from './src/types.ts';
@@ -4,6 +4,9 @@ const { stat, readFile, writeFile, mkdir, rm, readdir } = require('node:fs/promi
4
4
  const path = require('node:path');
5
5
 
6
6
  const COMP_MOD = '@travetto/compiler';
7
+ const SOURCE_EXT_RE = /[.][cm]?[tj]sx?$/;
8
+ const BARE_IMPORT_RE = /^(@[^/]+[/])?[^.][^@/]+$/;
9
+ const OUTPUT_EXT = '.js';
7
10
 
8
11
  async function writeIfStale(src = '', dest = '', transform = async (x = '') => x) {
9
12
  const [srcStat, destStat] = await Promise.all([src, dest].map(x => stat(`${x}`).then(z => z.mtimeMs, () => 0)));
@@ -20,6 +23,10 @@ async function transpile(content = '', esm = true, full = true) {
20
23
  return ts.transpile(content, {
21
24
  target: ts.ScriptTarget.ES2022,
22
25
  module: esm ? ts.ModuleKind.ESNext : ts.ModuleKind.CommonJS,
26
+ importHelpers: true,
27
+ sourceMap: false,
28
+ inlineSourceMap: true,
29
+ allowImportingTsExtensions: true,
23
30
  ...(full ? { esModuleInterop: true, allowSyntheticDefaultImports: true } : {})
24
31
  });
25
32
  }
@@ -28,13 +35,11 @@ async function getContext() {
28
35
  const ctxSrc = require.resolve('@travetto/manifest/src/context.ts');
29
36
  const ctxDest = path.resolve(__dirname, 'gen.context.mjs');
30
37
  await writeIfStale(ctxSrc, ctxDest, content => transpile(content, true, false));
31
- const ctx = await import(ctxDest).then((/** @type {import('@travetto/manifest/src/context')} */ v) => v.getManifestContext());
38
+ const ctx = await import(ctxDest).then((/** @type {import('@travetto/manifest')} */ v) => v.getManifestContext());
32
39
 
33
40
  const srcPath = path.resolve.bind(path, ctx.workspace.path, ctx.build.compilerModuleFolder);
34
- const destPath = (file = '', mod = COMP_MOD) => {
35
- const base = path.resolve(ctx.workspace.path, ctx.build.compilerFolder, mod, file);
36
- return `${base}${file.includes('.') ? '' : file.includes('/') ? '.ts' : '/__index__.ts'}`.replace('.ts', '.js');
37
- };
41
+ const destPath = (file = '') =>
42
+ path.resolve(ctx.workspace.path, ctx.build.compilerFolder, 'node_modules', file).replace(SOURCE_EXT_RE, OUTPUT_EXT);
38
43
 
39
44
  return {
40
45
  packageType: ctx.workspace.type,
@@ -42,29 +47,32 @@ async function getContext() {
42
47
  destPath,
43
48
  tsconfig: path.resolve(ctx.workspace.path, 'tsconfig.json'),
44
49
  cleanImports: (t = '') => t
45
- .replace(/from '([.][^']+)'/g, (_, i) => `from '${i.replace(/[.]js$/, '')}.js'`)
46
- .replace(/from '(@travetto\/[^/']+)([/][^']+)?'/g, (_, mod, modFile) => `from '${destPath(modFile, mod)}'`),
47
- loadMain: () => import(destPath('support/entry.main.ts'))
48
- .then((/** @type {import('../support/entry.main')} */ v) => v.main(ctx)),
50
+ .replace(/from ['"]((@travetto|[.]+)[^'"]+)['"]/g, (_, v, m) => {
51
+ const s = (m === '@travetto' ? destPath(v) : v).replace(SOURCE_EXT_RE, OUTPUT_EXT);
52
+ const suf = s.endsWith(OUTPUT_EXT) ? '' : (BARE_IMPORT_RE.test(v) ? `/__index__${OUTPUT_EXT}` : OUTPUT_EXT);
53
+ return `from '${s}${suf}'`;
54
+ }),
55
+ loadMain: () => import(destPath(`${COMP_MOD}/support/entry.main.ts`))
56
+ .then((/** @type {import('../support/entry.main.ts')} */ v) => v.main(ctx)),
49
57
  supportFiles: () => readdir(srcPath('support'), { recursive: true, encoding: 'utf8' })
50
58
  .then(v => v.filter(f => f.endsWith('.ts')).map(j => `support/${j}`))
51
59
  };
52
60
  }
53
61
 
54
62
  /** @template T */
55
- async function load(/** @type {(ops: import('../support/entry.main').Operations) => T} */ cb) {
63
+ async function load(/** @type {(ops: import('../support/entry.main.ts').Operations) => T} */ cb) {
56
64
  const ctx = await getContext();
57
65
 
58
66
  try {
59
67
  await writeIfStale('', ctx.tsconfig,
60
68
  async () => JSON.stringify({ extends: `${COMP_MOD}/tsconfig.trv.json` }, null, 2));
61
69
 
62
- await writeIfStale(ctx.srcPath('package.json'), ctx.destPath('package.json'),
70
+ await writeIfStale(ctx.srcPath('package.json'), ctx.destPath(`${COMP_MOD}/package.json`),
63
71
  async text => JSON.stringify({ ...JSON.parse(text || '{}'), type: ctx.packageType }, null, 2));
64
72
 
65
73
  await Promise.all((await ctx.supportFiles()).map(f =>
66
- writeIfStale(ctx.srcPath(f), ctx.destPath(f),
67
- t => transpile(t, ctx.packageType === 'module').then(ctx.cleanImports))));
74
+ writeIfStale(ctx.srcPath(f), ctx.destPath(`${COMP_MOD}/${f}`),
75
+ t => transpile(ctx.cleanImports(t), ctx.packageType === 'module'))));
68
76
 
69
77
  process.setSourceMapsEnabled(true); // Ensure source map during compilation/development
70
78
  process.env.NODE_OPTIONS = `${process.env.NODE_OPTIONS ?? ''} --enable-source-maps`; // Ensure it passes to children
@@ -73,7 +81,7 @@ async function load(/** @type {(ops: import('../support/entry.main').Operations)
73
81
  try { module.enableCompileCache(); } catch { }
74
82
  return cb(res);
75
83
  } catch (err) {
76
- await rm(ctx.destPath('.'), { recursive: true, force: true });
84
+ await rm(ctx.destPath(COMP_MOD), { recursive: true, force: true });
77
85
  throw err;
78
86
  }
79
87
  }
@@ -66,3 +66,4 @@ export function getManifestContext(root = process.cwd()) {
66
66
  }
67
67
  };
68
68
  }
69
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibW9kdWxlLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsibW9kdWxlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxVQUFVLEVBQUUsWUFBWSxFQUFFLE1BQU0sU0FBUyxDQUFDO0FBQ25ELE9BQU8sSUFBSSxNQUFNLFdBQVcsQ0FBQztBQUM3QixPQUFPLEVBQUUsYUFBYSxFQUFFLE1BQU0sYUFBYSxDQUFDO0FBTzVDLHNDQUFzQztBQUN0QyxNQUFNLE1BQU0sR0FBRyxDQUFDLEdBQVcsRUFBVSxFQUFFLENBQUMsQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFDLENBQUMsR0FBRyxHQUFHLENBQUMsQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxDQUFDLENBQUMsR0FBRyxFQUFFLENBQUMsR0FBRyxDQUFDLENBQUMsVUFBVSxDQUFDLENBQUMsQ0FBQyxFQUFFLElBQUksQ0FBQyxDQUFDLEdBQUcsS0FBSyxDQUFDLEdBQUcsS0FBSyxDQUFDO0FBQ2hJLE1BQU0sT0FBTyxHQUFHLENBQUMsR0FBVyxFQUFVLEVBQUUsQ0FBQyxHQUFHLENBQUMsVUFBVSxDQUFDLElBQUksRUFBRSxHQUFHLENBQUMsQ0FBQztBQUNuRSxNQUFNLFdBQVcsR0FBRyxDQUFDLElBQVksRUFBTyxFQUFFLENBQUMsQ0FBQyxFQUFFLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQyxZQUFZLENBQUMsSUFBSSxFQUFFLE1BQU0sQ0FBQyxDQUFDLEVBQUUsSUFBSSxFQUFFLE9BQU8sQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFDLElBQUksQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDO0FBRTlILG1CQUFtQjtBQUNuQixTQUFTLFdBQVcsQ0FBQyxJQUFZLEVBQUUsSUFBMkI7SUFDNUQsSUFBSSxNQUFNLEdBQUcsR0FBRyxJQUFJLElBQUksQ0FBQztJQUN6QixJQUFJLElBQVksQ0FBQztJQUNqQixJQUFJLEdBQW9CLENBQUM7SUFD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
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@travetto/compiler",
3
- "version": "6.0.0-rc.2",
3
+ "version": "6.0.0",
4
4
  "description": "The compiler infrastructure for the Travetto framework",
5
5
  "keywords": [
6
6
  "compiler",
@@ -30,11 +30,11 @@
30
30
  },
31
31
  "dependencies": {
32
32
  "@parcel/watcher": "^2.5.1",
33
- "@travetto/manifest": "^6.0.0-rc.1",
34
- "@travetto/transformer": "^6.0.0-rc.2"
33
+ "@travetto/manifest": "^6.0.0",
34
+ "@travetto/transformer": "^6.0.0"
35
35
  },
36
36
  "peerDependencies": {
37
- "@travetto/cli": "^6.0.0-rc.1"
37
+ "@travetto/cli": "^6.0.0"
38
38
  },
39
39
  "peerDependenciesMeta": {
40
40
  "@travetto/cli": {
package/src/compiler.ts CHANGED
@@ -3,14 +3,14 @@ import { setMaxListeners } from 'node:events';
3
3
 
4
4
  import { ManifestIndex, ManifestModuleUtil } from '@travetto/manifest';
5
5
 
6
- import { CompilerUtil } from './util';
7
- import { CompilerState } from './state';
8
- import { CompilerWatcher } from './watch';
9
- import { CompileEmitEvent, CompileEmitter, CompilerReset } from './types';
10
- import { EventUtil } from './event';
11
-
12
- import { IpcLogger } from '../support/log';
13
- import { CommonUtil } from '../support/util';
6
+ import { CompilerUtil } from './util.ts';
7
+ import { CompilerState } from './state.ts';
8
+ import { CompilerWatcher } from './watch.ts';
9
+ import { CompileEmitEvent, CompileEmitter, CompilerReset } from './types.ts';
10
+ import { EventUtil } from './event.ts';
11
+
12
+ import { IpcLogger } from '../support/log.ts';
13
+ import { CommonUtil } from '../support/util.ts';
14
14
 
15
15
  const log = new IpcLogger({ level: 'debug' });
16
16
 
package/src/event.ts CHANGED
@@ -1,4 +1,4 @@
1
- import type { CompilerEvent, CompilerEventType } from '../support/types';
1
+ import type { CompilerEvent, CompilerEventType } from '../support/types.ts';
2
2
 
3
3
  export class EventUtil {
4
4
  static sendEvent<K extends CompilerEventType, T extends CompilerEvent & { type: K }>(type: K, payload: T['payload']): void {
package/src/state.ts CHANGED
@@ -3,14 +3,13 @@ import ts from 'typescript';
3
3
  import { path, ManifestModuleUtil, type ManifestModule, type ManifestRoot, ManifestIndex, ManifestModuleFolderType } from '@travetto/manifest';
4
4
  import { TransformerManager } from '@travetto/transformer';
5
5
 
6
- import { TypescriptUtil } from '../support/ts-util';
6
+ import { TypescriptUtil } from '../support/ts-util.ts';
7
7
 
8
- import { CompilerUtil } from './util';
9
- import { CompileEmitError, CompileStateEntry } from './types';
10
- import { CommonUtil } from '../support/util';
8
+ import { CompilerUtil } from './util.ts';
9
+ import { CompileEmitError, CompileStateEntry } from './types.ts';
10
+ import { CommonUtil } from '../support/util.ts';
11
11
 
12
12
  const TYPINGS_FOLDER_KEYS = new Set<ManifestModuleFolderType>(['$index', 'support', 'src', '$package']);
13
- const TYPINGS_EXT_RE = /[.]d[.][cm]?ts([.]map)?$/;
14
13
 
15
14
  export class CompilerState implements ts.CompilerHost {
16
15
 
@@ -47,7 +46,7 @@ export class CompilerState implements ts.CompilerHost {
47
46
  #writeExternalTypings(location: string, text: string, bom: boolean): void {
48
47
  let core = location.replace('.map', '');
49
48
  if (!this.#outputToEntry.has(core)) {
50
- core = core.replace('.d.ts', '.js');
49
+ core = core.replace(ManifestModuleUtil.TYPINGS_EXT_RE, ManifestModuleUtil.OUTPUT_EXT);
51
50
  }
52
51
  const entry = this.#outputToEntry.get(core);
53
52
  if (entry) {
@@ -144,7 +143,7 @@ export class CompilerState implements ts.CompilerHost {
144
143
  case 'ts': {
145
144
  const result = program.emit(
146
145
  program.getSourceFile(sourceFile)!,
147
- (...args) => this.writeFile(...args), undefined, false,
146
+ (...args) => this.writeFile(args[0], args[1], args[2]), undefined, false,
148
147
  this.#transformerManager.get()
149
148
  );
150
149
  return result?.diagnostics?.length ? result.diagnostics : undefined;
@@ -185,8 +184,8 @@ export class CompilerState implements ts.CompilerHost {
185
184
  this.#tscOutputFileToOuptut.set(`${tscOutputFile}.map`, `${outputFile}.map`);
186
185
 
187
186
  if (!isTypings) {
188
- const srcBase = `${ManifestModuleUtil.withoutSourceExtension(tscOutputFile)}.d.ts`;
189
- const outBase = `${ManifestModuleUtil.withoutSourceExtension(outputFile)}.d.ts`;
187
+ const srcBase = `${ManifestModuleUtil.withoutSourceExtension(tscOutputFile)}${ManifestModuleUtil.TYPINGS_EXT}`;
188
+ const outBase = `${ManifestModuleUtil.withoutSourceExtension(outputFile)}${ManifestModuleUtil.TYPINGS_EXT}`;
190
189
  this.#tscOutputFileToOuptut.set(`${srcBase}.map`, `${outBase}.map`);
191
190
  this.#tscOutputFileToOuptut.set(srcBase, outBase);
192
191
  }
@@ -222,7 +221,7 @@ export class CompilerState implements ts.CompilerHost {
222
221
  this.#sourceToEntry.delete(sourceFile);
223
222
  this.#sourceFiles.delete(sourceFile);
224
223
 
225
- const tscOutputDts = `${ManifestModuleUtil.withoutSourceExtension(entry.tscOutputFile)}.d.ts`;
224
+ const tscOutputDts = `${ManifestModuleUtil.withoutSourceExtension(entry.tscOutputFile)}${ManifestModuleUtil.TYPINGS_EXT}`;
226
225
  this.#tscOutputFileToOuptut.delete(entry.tscOutputFile);
227
226
  this.#tscOutputFileToOuptut.delete(`${entry.tscOutputFile}.map`);
228
227
  this.#tscOutputFileToOuptut.delete(tscOutputDts);
@@ -252,17 +251,14 @@ export class CompilerState implements ts.CompilerHost {
252
251
  writeFile(
253
252
  outputFile: string,
254
253
  text: string,
255
- bom: boolean,
256
- onError?: (message: string) => void,
257
- sourceFiles?: readonly ts.SourceFile[],
258
- data?: ts.WriteFileCallbackData
254
+ bom: boolean
259
255
  ): void {
260
256
  if (outputFile.endsWith('package.json')) {
261
257
  text = CompilerUtil.rewritePackageJSON(this.#manifest, text);
262
258
  }
263
259
  const location = this.#tscOutputFileToOuptut.get(outputFile) ?? outputFile;
264
260
 
265
- if (TYPINGS_EXT_RE.test(outputFile) || outputFile.endsWith('package.json')) {
261
+ if (ManifestModuleUtil.TYPINGS_WITH_MAP_EXT_RE.test(outputFile) || outputFile.endsWith('package.json')) {
266
262
  this.#writeExternalTypings(location, text, bom);
267
263
  }
268
264
 
package/src/watch.ts CHANGED
@@ -1,14 +1,14 @@
1
1
  import fs from 'node:fs/promises';
2
2
  import { watch } from 'node:fs';
3
3
 
4
- import { ManifestFileUtil, ManifestModuleUtil, ManifestUtil, PackageUtil, path } from '@travetto/manifest';
4
+ import { ManifestFileUtil, ManifestModuleUtil, ManifestRoot, ManifestUtil, PackageUtil, path } from '@travetto/manifest';
5
5
 
6
- import { CompilerReset, type CompilerWatchEvent, type CompileStateEntry } from './types';
7
- import { CompilerState } from './state';
8
- import { CompilerUtil } from './util';
6
+ import { CompilerReset, type CompilerWatchEvent, type CompileStateEntry } from './types.ts';
7
+ import { CompilerState } from './state.ts';
8
+ import { CompilerUtil } from './util.ts';
9
9
 
10
- import { AsyncQueue } from '../support/queue';
11
- import { IpcLogger } from '../support/log';
10
+ import { AsyncQueue } from '../support/queue.ts';
11
+ import { IpcLogger } from '../support/log.ts';
12
12
 
13
13
  const log = new IpcLogger({ level: 'debug' });
14
14
 
@@ -53,7 +53,7 @@ export class CompilerWatcher {
53
53
  ignores.add(item);
54
54
  }
55
55
  }
56
- return [...ignores].sort().map(x => x.endsWith('/') ? x : `${x}/`);
56
+ return [...ignores].toSorted().map(x => x.endsWith('/') ? x : `${x}/`);
57
57
  }
58
58
 
59
59
  #toCandidateEvent(action: CompilerWatchEvent['action'], file: string): CompilerWatchEventCandidate {
@@ -63,6 +63,8 @@ export class CompilerWatcher {
63
63
  const modRoot = mod.sourceFolder || this.#root;
64
64
  const moduleFile = file.includes(`${modRoot}/`) ? file.split(`${modRoot}/`)[1] : file;
65
65
  entry = this.#state.registerInput(mod, moduleFile);
66
+ } else if (action === 'delete' && entry) {
67
+ this.#state.removeSource(entry.sourceFile); // Ensure we remove it
66
68
  }
67
69
  return { entry, file: entry?.sourceFile ?? file, action };
68
70
  }
@@ -85,54 +87,62 @@ export class CompilerWatcher {
85
87
  return true;
86
88
  }
87
89
 
88
- async #reconcileAddRemove(compilerEvents: CompilerWatchEvent[]): Promise<void> {
89
- const nonUpdates = compilerEvents.filter(x => x.entry.outputFile && x.action !== 'update');
90
- if (!nonUpdates.length) {
90
+ #getManifestUpdateEventsByParents(events: CompilerWatchEvent[]): Map<string, CompilerWatchEvent[]> {
91
+ const eventsByMod = new Map<string, CompilerWatchEvent[]>();
92
+ for (const ev of events) {
93
+ if (ev.action === 'update') {
94
+ continue;
95
+ }
96
+
97
+ const mod = ev.entry.module;
98
+ const moduleSet = new Set(this.#state.manifestIndex.getDependentModules(mod.name, 'parents').map(x => x.name));
99
+ moduleSet.add(this.#state.manifest.workspace.name);
100
+ for (const m of moduleSet) {
101
+ if (!eventsByMod.has(m)) {
102
+ eventsByMod.set(m, []);
103
+ }
104
+ eventsByMod.get(m)!.push(ev);
105
+ }
106
+ }
107
+ return eventsByMod;
108
+ }
109
+
110
+ #updateManifestForEvent({ action, file, entry }: CompilerWatchEvent, manifest: ManifestRoot): void {
111
+ if (action === 'update') {
91
112
  return;
92
113
  }
93
114
 
94
- try {
95
- const eventsByMod = new Map<string, CompilerWatchEvent[]>();
115
+ const moduleName = entry.module.name;
116
+ const moduleRoot = entry.module.sourceFolder || this.#root;
117
+ const relativeFile = file.includes(moduleRoot) ? file.split(`${moduleRoot}/`)[1] : file;
118
+ const folderKey = ManifestModuleUtil.getFolderKey(relativeFile);
119
+ const fileType = ManifestModuleUtil.getFileType(relativeFile);
96
120
 
97
- for (const ev of nonUpdates) {
98
- const mod = ev.entry.module;
99
- if (ev.action === 'delete') {
100
- this.#state.removeSource(ev.entry.sourceFile);
101
- }
102
- for (const m of [mod, ...this.#state.manifestIndex.getDependentModules(mod.name, 'parents')]) {
103
- if (!eventsByMod.has(m.name)) {
104
- eventsByMod.set(m.name, []);
105
- }
106
- eventsByMod.get(m.name)!.push(ev);
107
- }
108
- }
121
+ const manifestModuleFiles = manifest.modules[moduleName].files[folderKey] ??= [];
122
+ const idx = manifestModuleFiles.findIndex(x => x[0] === relativeFile);
123
+ const wrappedIdx = idx < 0 ? manifestModuleFiles.length : idx;
109
124
 
110
- for (const [mod, events] of eventsByMod.entries()) {
111
- const modRoot = this.#state.manifestIndex.getManifestModule(mod)!.sourceFolder;
112
- const context = ManifestUtil.getModuleContext(this.#state.manifest, modRoot);
113
- const newManifest = ManifestUtil.readManifestSync(ManifestUtil.getManifestLocation(context));
114
- log.debug('Updating manifest', { module: mod });
115
- for (const { action, file } of events) {
116
- const resolvedRoot = modRoot || this.#root;
117
- const moduleFile = file.includes(resolvedRoot) ? file.split(`${resolvedRoot}/`)[1] : file;
118
- const folderKey = ManifestModuleUtil.getFolderKey(moduleFile);
119
- const fileType = ManifestModuleUtil.getFileType(moduleFile);
120
-
121
- const modFiles = newManifest.modules[mod].files[folderKey] ??= [];
122
- const idx = modFiles.findIndex(x => x[0] === moduleFile);
123
- switch (action) {
124
- case 'create': modFiles[idx < 0 ? modFiles.length : idx] = [moduleFile, fileType, Date.now()]; break;
125
- case 'delete': modFiles.splice(idx, 1); break;
126
- }
127
- }
128
- await ManifestUtil.writeManifest(newManifest);
129
- }
125
+ switch (action) {
126
+ case 'create': manifestModuleFiles[wrappedIdx] = [relativeFile, fileType, Date.now()]; break;
127
+ case 'delete': idx >= 0 && manifestModuleFiles.splice(idx, 1); break;
128
+ }
129
+ }
130
+
131
+ async #reconcileManifestUpdates(compilerEvents: CompilerWatchEvent[]): Promise<void> {
132
+ for (const [mod, events] of this.#getManifestUpdateEventsByParents(compilerEvents).entries()) {
133
+ const moduleRoot = this.#state.manifestIndex.getManifestModule(mod)!.sourceFolder;
134
+ const moduleContext = ManifestUtil.getModuleContext(this.#state.manifest, moduleRoot);
135
+ const manifestLocation = ManifestUtil.getManifestLocation(moduleContext, mod);
136
+ const moduleManifest = ManifestUtil.readManifestSync(manifestLocation);
130
137
 
131
- this.#state.manifestIndex.init(ManifestUtil.getManifestLocation(this.#state.manifest));
132
- } catch (mErr) {
133
- log.info('Restarting due to manifest rebuild failure', mErr);
134
- throw new CompilerReset(`Manifest rebuild failure: ${mErr}`);
138
+ log.debug('Updating manifest', { module: mod, events: events.length });
139
+ for (const ev of events) {
140
+ this.#updateManifestForEvent(ev, moduleManifest);
141
+ }
142
+ await ManifestUtil.writeManifest(moduleManifest);
135
143
  }
144
+
145
+ this.#state.manifestIndex.init(ManifestUtil.getManifestLocation(this.#state.manifest));
136
146
  }
137
147
 
138
148
  async #listenWorkspace(): Promise<void> {
@@ -161,7 +171,12 @@ export class CompilerWatcher {
161
171
  .map(x => this.#toCandidateEvent(x.type, path.toPosix(x.path)))
162
172
  .filter(x => this.#isValidEvent(x));
163
173
 
164
- await this.#reconcileAddRemove(items);
174
+ try {
175
+ await this.#reconcileManifestUpdates(items);
176
+ } catch (mErr) {
177
+ log.info('Restarting due to manifest rebuild failure', mErr);
178
+ throw new CompilerReset(`Manifest rebuild failure: ${mErr}`);
179
+ }
165
180
 
166
181
  for (const item of items) {
167
182
  this.#q.add(item);
@@ -1,3 +1,3 @@
1
1
  // @trv-no-transform
2
- import { Compiler } from '../src/compiler';
2
+ import { Compiler } from '../src/compiler.ts';
3
3
  Compiler.main();
@@ -3,13 +3,13 @@ import fs from 'node:fs/promises';
3
3
 
4
4
  import type { ManifestContext } from '@travetto/manifest';
5
5
 
6
- import type { CompilerMode, CompilerServerInfo } from './types';
7
- import { Log } from './log';
8
- import { CompilerSetup } from './setup';
9
- import { CompilerServer } from './server/server';
10
- import { CompilerRunner } from './server/runner';
11
- import { CompilerClient } from './server/client';
12
- import { CommonUtil } from './util';
6
+ import type { CompilerMode, CompilerServerInfo } from './types.ts';
7
+ import { Log } from './log.ts';
8
+ import { CompilerSetup } from './setup.ts';
9
+ import { CompilerServer } from './server/server.ts';
10
+ import { CompilerRunner } from './server/runner.ts';
11
+ import { CompilerClient } from './server/client.ts';
12
+ import { CommonUtil } from './util.ts';
13
13
 
14
14
  // eslint-disable-next-line @typescript-eslint/explicit-function-return-type
15
15
  export const main = (ctx: ManifestContext) => {
package/support/log.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { CompilerLogEvent, CompilerLogLevel, CompilerProgressEvent } from './types';
1
+ import { CompilerLogEvent, CompilerLogLevel, CompilerProgressEvent } from './types.ts';
2
2
 
3
3
  const LEVEL_TO_PRI: Record<CompilerLogLevel | 'none', number> = { debug: 1, info: 2, warn: 3, error: 4, none: 5 };
4
4
  const SCOPE_MAX = 15;
@@ -4,10 +4,10 @@ import http, { Agent } from 'node:http';
4
4
 
5
5
  import { ManifestContext } from '@travetto/manifest';
6
6
 
7
- import type { CompilerEvent, CompilerEventType, CompilerServerInfo, CompilerStateType } from '../types';
8
- import type { LogShape } from '../log';
9
- import { CommonUtil } from '../util';
10
- import { ProcessHandle } from './process-handle';
7
+ import type { CompilerEvent, CompilerEventType, CompilerServerInfo, CompilerStateType } from '../types.ts';
8
+ import type { LogShape } from '../log.ts';
9
+ import { CommonUtil } from '../util.ts';
10
+ import { ProcessHandle } from './process-handle.ts';
11
11
 
12
12
  type FetchEventsConfig<T> = {
13
13
  signal?: AbortSignal;
@@ -55,8 +55,8 @@ export class CompilerClient {
55
55
  ctrl.abort('TIMEOUT');
56
56
  })
57
57
  .catch(() => { });
58
- const res = await fetch(`${this.#url}${rel}`, { ...opts, signal: ctrl.signal });
59
- const out = { ok: res.ok, text: await res.text() };
58
+ const response = await fetch(`${this.#url}${rel}`, { ...opts, signal: ctrl.signal });
59
+ const out = { ok: response.ok, text: await response.text() };
60
60
  timeoutCtrl.abort();
61
61
  return out;
62
62
  }
@@ -127,7 +127,7 @@ export class CompilerClient {
127
127
 
128
128
  for await (const line of rl.createInterface(response)) {
129
129
  if (line.trim().charAt(0) === '{') {
130
- const val = JSON.parse(line);
130
+ const val: T = JSON.parse(line);
131
131
  if (cfg.until?.(val)) {
132
132
  await CommonUtil.queueMacroTask();
133
133
  ctrl.abort();
@@ -136,7 +136,8 @@ export class CompilerClient {
136
136
  }
137
137
  }
138
138
  } catch (err) {
139
- if (!ctrl.signal.aborted) { throw err; }
139
+ const aborted = ctrl.signal.aborted || (typeof err === 'object' && err && 'code' in err && err.code === 'ECONNRESET');
140
+ if (!aborted) { throw err; }
140
141
  }
141
142
  signal.removeEventListener('abort', quit);
142
143
 
@@ -3,8 +3,8 @@ import path from 'node:path';
3
3
 
4
4
  import type { ManifestContext } from '@travetto/manifest';
5
5
 
6
- import { Log, Logger } from '../log';
7
- import { CommonUtil } from '../util';
6
+ import { Log, Logger } from '../log.ts';
7
+ import { CommonUtil } from '../util.ts';
8
8
 
9
9
  export class ProcessHandle {
10
10
 
@@ -3,10 +3,10 @@ import { rmSync } from 'node:fs';
3
3
 
4
4
  import type { ManifestContext, DeltaEvent } from '@travetto/manifest';
5
5
 
6
- import type { CompilerEvent, CompilerMode } from '../types';
7
- import { AsyncQueue } from '../queue';
8
- import { Log } from '../log';
9
- import { CommonUtil } from '../util';
6
+ import type { CompilerEvent, CompilerMode } from '../types.ts';
7
+ import { AsyncQueue } from '../queue.ts';
8
+ import { Log } from '../log.ts';
9
+ import { CommonUtil } from '../util.ts';
10
10
 
11
11
  const log = Log.scoped('compiler-exec');
12
12
  const isEvent = (msg: unknown): msg is CompilerEvent => !!msg && typeof msg === 'object' && 'type' in msg;
@@ -58,7 +58,7 @@ export class CompilerRunner {
58
58
 
59
59
  const kill = (): unknown => {
60
60
  log.debug('Shutting down process');
61
- return (proc.connected ? proc.send('shutdown', (err) => proc.kill()) : proc.kill());
61
+ return (proc.connected ? proc.send('shutdown', () => proc.kill()) : proc.kill());
62
62
  };
63
63
 
64
64
  process.once('SIGINT', kill);
@@ -4,11 +4,11 @@ import { setMaxListeners } from 'node:events';
4
4
 
5
5
  import type { ManifestContext } from '@travetto/manifest';
6
6
 
7
- import type { CompilerMode, CompilerProgressEvent, CompilerEvent, CompilerEventType, CompilerServerInfo } from '../types';
8
- import { Log } from '../log';
9
- import { CommonUtil } from '../util';
10
- import { CompilerClient } from './client';
11
- import { ProcessHandle } from './process-handle';
7
+ import type { CompilerMode, CompilerProgressEvent, CompilerEvent, CompilerEventType, CompilerServerInfo } from '../types.ts';
8
+ import { Log } from '../log.ts';
9
+ import { CommonUtil } from '../util.ts';
10
+ import { CompilerClient } from './client.ts';
11
+ import { ProcessHandle } from './process-handle.ts';
12
12
 
13
13
  const log = Log.scoped('server');
14
14
 
package/support/setup.ts CHANGED
@@ -4,9 +4,9 @@ import path from 'node:path';
4
4
 
5
5
  import type { DeltaEvent, ManifestContext, Package } from '@travetto/manifest';
6
6
 
7
- import { Log } from './log';
8
- import { CommonUtil } from './util';
9
- import { TypescriptUtil } from './ts-util';
7
+ import { Log } from './log.ts';
8
+ import { CommonUtil } from './util.ts';
9
+ import { TypescriptUtil } from './ts-util.ts';
10
10
 
11
11
  type ModFile = { input: string, output: string, stale: boolean };
12
12
 
@@ -15,6 +15,10 @@ const PRECOMPILE_MODS = ['@travetto/manifest', '@travetto/transformer', '@travet
15
15
  const RECENT_STAT = (stat: { ctimeMs: number, mtimeMs: number }): number => Math.max(stat.ctimeMs, stat.mtimeMs);
16
16
  const REQ = createRequire(path.resolve('node_modules')).resolve.bind(null);
17
17
 
18
+ const SOURCE_EXT_RE = /[.][cm]?[tj]s$/;
19
+ const BARE_IMPORT_RE = /^(@[^/]+[/])?[^.][^@/]+$/;
20
+ const OUTPUT_EXT = '.js';
21
+
18
22
  /**
19
23
  * Compiler Setup Utilities
20
24
  */
@@ -27,21 +31,21 @@ export class CompilerSetup {
27
31
  Pick<typeof import('@travetto/manifest'), 'ManifestDeltaUtil' | 'ManifestUtil'>
28
32
  > => {
29
33
  const all = ['util', 'delta'].map(f =>
30
- import(CommonUtil.resolveWorkspace(ctx, ctx.build.compilerFolder, 'node_modules', `@travetto/manifest/src/${f}.js`))
34
+ import(CommonUtil.resolveWorkspace(ctx, ctx.build.compilerFolder, 'node_modules', `@travetto/manifest/src/${f}${OUTPUT_EXT}`))
31
35
  );
32
36
  return Promise.all(all).then(props => Object.assign({}, ...props));
33
37
  };
34
38
 
35
39
  /** Convert a file to a given ext */
36
40
  static #sourceToExtension(sourceFile: string, ext: string): string {
37
- return sourceFile.replace(/[.][tj]sx?$/, ext);
41
+ return sourceFile.replace(SOURCE_EXT_RE, ext);
38
42
  }
39
43
 
40
44
  /**
41
45
  * Get the output file name for a given input
42
46
  */
43
47
  static #sourceToOutputExt(sourceFile: string): string {
44
- return this.#sourceToExtension(sourceFile, '.js');
48
+ return this.#sourceToExtension(sourceFile, OUTPUT_EXT);
45
49
  }
46
50
 
47
51
  /**
@@ -53,14 +57,19 @@ export class CompilerSetup {
53
57
  const compilerOut = CommonUtil.resolveWorkspace(ctx, ctx.build.compilerFolder, 'node_modules');
54
58
 
55
59
  const text = (await fs.readFile(sourceFile, 'utf8'))
56
- .replace(/from '([.][^']+)'/g, (_, i) => `from '${i.replace(/[.]js$/, '')}.js'`)
57
- .replace(/from '(@travetto\/(.*?))'/g, (_, i, s) => `from '${compilerOut}/${i}${s.includes('/') ? '.js' : '/__index__.js'}'`);
60
+ .replace(/from ['"](([.]+|@travetto)[/][^']+)['"]/g, (_, clause, m) => {
61
+ const s = this.#sourceToOutputExt(clause);
62
+ const suf = s.endsWith(OUTPUT_EXT) ? '' : (BARE_IMPORT_RE.test(clause) ? `/__index__${OUTPUT_EXT}` : OUTPUT_EXT);
63
+ const pre = m === '@travetto' ? `${compilerOut}/` : '';
64
+ return `from '${pre}${s}${suf}'`;
65
+ });
58
66
 
59
67
  const ts = (await import('typescript')).default;
60
68
  const content = ts.transpile(text, {
61
69
  ...await TypescriptUtil.getCompilerOptions(ctx),
62
70
  sourceMap: false,
63
71
  inlineSourceMap: true,
72
+ importHelpers: true,
64
73
  }, sourceFile);
65
74
  await CommonUtil.writeTextFile(outputFile, content);
66
75
  } else if (type === 'package-json') {
@@ -2,7 +2,7 @@ import fs from 'node:fs/promises';
2
2
  import type { CompilerOptions } from 'typescript';
3
3
 
4
4
  import type { ManifestContext } from '@travetto/manifest';
5
- import { CommonUtil } from './util';
5
+ import { CommonUtil } from './util.ts';
6
6
 
7
7
  const OPT_CACHE: Record<string, CompilerOptions> = {};
8
8
 
@@ -14,7 +14,7 @@ export class TypescriptUtil {
14
14
  if (!(ctx.workspace.path in OPT_CACHE)) {
15
15
  let tsconfig = CommonUtil.resolveWorkspace(ctx, 'tsconfig.json');
16
16
 
17
- if (!await fs.stat(tsconfig).then(_ => true, _ => false)) {
17
+ if (!await fs.stat(tsconfig).then(() => true, () => false)) {
18
18
  tsconfig = CommonUtil.resolveWorkspace(ctx, ctx.build.compilerModuleFolder, 'tsconfig.trv.json');
19
19
  }
20
20
 
@@ -26,6 +26,8 @@ export class TypescriptUtil {
26
26
 
27
27
  OPT_CACHE[ctx.workspace.path] = {
28
28
  ...options,
29
+ noEmit: false,
30
+ emitDeclarationOnly: false,
29
31
  allowJs: true,
30
32
  resolveJsonModule: true,
31
33
  sourceRoot: ctx.workspace.path,
package/support/util.ts CHANGED
@@ -6,7 +6,7 @@ import native from 'node:path';
6
6
 
7
7
  import type { ManifestContext } from '@travetto/manifest';
8
8
 
9
- import { Log } from './log';
9
+ import { Log } from './log.ts';
10
10
 
11
11
  const toPosix = (file: string): string => file.replaceAll('\\', '/');
12
12
 
@@ -17,7 +17,7 @@ export class CommonUtil {
17
17
  static getFileType(file: string): 'ts' | 'js' | 'package-json' | 'typings' | undefined {
18
18
  return file.endsWith('package.json') ? 'package-json' :
19
19
  (file.endsWith('.js') ? 'js' :
20
- (file.endsWith('.d.ts') ? 'typings' : (/[.]tsx?$/.test(file) ? 'ts' : undefined)));
20
+ (file.endsWith('.d.ts') ? 'typings' : (/[.][cm]?tsx?$/.test(file) ? 'ts' : undefined)));
21
21
  }
22
22
 
23
23
  /**
package/tsconfig.trv.json CHANGED
@@ -3,8 +3,9 @@
3
3
  "module": "ES2022",
4
4
  "target": "esnext",
5
5
  "moduleResolution": "Bundler",
6
+ "allowImportingTsExtensions": true,
6
7
  "lib": [
7
- "ES2023"
8
+ "ES2024"
8
9
  ],
9
10
  "jsx": "react-jsx",
10
11
  "strict": true,
@@ -12,6 +13,7 @@
12
13
  "declarationMap": true,
13
14
  "esModuleInterop": true,
14
15
  "strictPropertyInitialization": false,
16
+ "erasableSyntaxOnly": true,
15
17
  "experimentalDecorators": true,
16
18
  "noEmitOnError": false,
17
19
  "noErrorTruncation": true,
@@ -22,6 +24,7 @@
22
24
  "importHelpers": true,
23
25
  "noEmitHelpers": true,
24
26
  "outDir": "build/",
27
+ "noEmit": true
25
28
  },
26
29
  "watchOptions": {
27
30
  "excludeDirectories": [