@travetto/compiler 5.0.15 → 5.0.17
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/bin/entry.common.js +81 -0
- package/bin/{manifest-context.mjs → gen.context.mjs} +9 -3
- package/bin/trvc.js +25 -31
- package/package.json +5 -9
- package/src/compiler.ts +1 -1
- package/support/{entry.trvc.ts → entry.main.ts} +10 -11
- package/bin/common.js +0 -101
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
// @ts-check
|
|
2
|
+
/* eslint-disable no-undef */
|
|
3
|
+
const { stat, readFile, writeFile, mkdir, rm, readdir } = require('node:fs/promises');
|
|
4
|
+
const path = require('node:path');
|
|
5
|
+
|
|
6
|
+
const COMP_MOD = '@travetto/compiler';
|
|
7
|
+
|
|
8
|
+
async function writeIfStale(src = '', dest = '', transform = async (x = '') => x) {
|
|
9
|
+
const [srcStat, destStat] = await Promise.all([src, dest].map(x => stat(`${x}`).then(z => z.mtimeMs, () => 0)));
|
|
10
|
+
|
|
11
|
+
if (!destStat || destStat < srcStat) {
|
|
12
|
+
const text = src ? await readFile(src, 'utf8') : '';
|
|
13
|
+
await mkdir(path.dirname(dest), { recursive: true });
|
|
14
|
+
await writeFile(dest, await transform(text), 'utf8');
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
async function transpile(content = '', esm = true, full = true) {
|
|
19
|
+
const ts = (await import('typescript')).default;
|
|
20
|
+
return ts.transpile(content, {
|
|
21
|
+
target: ts.ScriptTarget.ES2022,
|
|
22
|
+
module: esm ? ts.ModuleKind.ESNext : ts.ModuleKind.CommonJS,
|
|
23
|
+
...(full ? { esModuleInterop: true, allowSyntheticDefaultImports: true } : {})
|
|
24
|
+
});
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
async function getContext() {
|
|
28
|
+
const ctxSrc = require.resolve('@travetto/manifest/src/context.ts');
|
|
29
|
+
const ctxDest = path.resolve(__dirname, 'gen.context.mjs');
|
|
30
|
+
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());
|
|
32
|
+
|
|
33
|
+
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
|
+
};
|
|
38
|
+
|
|
39
|
+
return {
|
|
40
|
+
packageType: ctx.workspace.type,
|
|
41
|
+
srcPath,
|
|
42
|
+
destPath,
|
|
43
|
+
tsconfig: path.resolve(ctx.workspace.path, 'tsconfig.json'),
|
|
44
|
+
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)),
|
|
49
|
+
supportFiles: () => readdir(srcPath('support'), { recursive: true, encoding: 'utf8' })
|
|
50
|
+
.then(v => v.filter(f => f.endsWith('.ts')).map(j => `support/${j}`))
|
|
51
|
+
};
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
/** @template T */
|
|
55
|
+
async function load(/** @type {(ops: import('../support/entry.main').Operations) => T} */ cb) {
|
|
56
|
+
const ctx = await getContext();
|
|
57
|
+
|
|
58
|
+
try {
|
|
59
|
+
await writeIfStale('', ctx.tsconfig,
|
|
60
|
+
async () => JSON.stringify({ extends: `${COMP_MOD}/tsconfig.trv.json` }, null, 2));
|
|
61
|
+
|
|
62
|
+
await writeIfStale(ctx.srcPath('package.json'), ctx.destPath('package.json'),
|
|
63
|
+
async text => JSON.stringify({ ...JSON.parse(text || '{}'), type: ctx.packageType }, null, 2));
|
|
64
|
+
|
|
65
|
+
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))));
|
|
68
|
+
|
|
69
|
+
process.setSourceMapsEnabled(true); // Ensure source map during compilation/development
|
|
70
|
+
process.env.NODE_OPTIONS = `${process.env.NODE_OPTIONS ?? ''} --enable-source-maps`; // Ensure it passes to children
|
|
71
|
+
const res = await ctx.loadMain();
|
|
72
|
+
// @ts-ignore
|
|
73
|
+
try { module.enableCompileCache(); } catch { }
|
|
74
|
+
return cb(res);
|
|
75
|
+
} catch (err) {
|
|
76
|
+
await rm(ctx.srcPath('.'), { recursive: true, force: true });
|
|
77
|
+
throw err;
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
module.exports = { load };
|
|
@@ -1,9 +1,11 @@
|
|
|
1
1
|
import { existsSync, readFileSync } from 'node:fs';
|
|
2
2
|
import path from 'node:path';
|
|
3
3
|
import { createRequire } from 'node:module';
|
|
4
|
+
// eslint-disable-next-line no-bitwise
|
|
4
5
|
const toPort = (pth) => (Math.abs([...pth].reduce((a, b) => (a * 33) ^ b.charCodeAt(0), 5381)) % 29000) + 20000;
|
|
5
6
|
const toPosix = (pth) => pth.replaceAll('\\', '/');
|
|
6
7
|
const readPackage = (file) => ({ ...JSON.parse(readFileSync(file, 'utf8')), path: toPosix(path.dirname(file)) });
|
|
8
|
+
/** Find package */
|
|
7
9
|
function findPackage(base, pred) {
|
|
8
10
|
let folder = `${base}/.`;
|
|
9
11
|
let prev;
|
|
@@ -13,14 +15,18 @@ function findPackage(base, pred) {
|
|
|
13
15
|
folder = path.dirname(folder);
|
|
14
16
|
const folderPkg = path.resolve(folder, 'package.json');
|
|
15
17
|
pkg = existsSync(folderPkg) ? readPackage(folderPkg) : pkg;
|
|
16
|
-
} while (prev !== folder &&
|
|
17
|
-
!pred(pkg) &&
|
|
18
|
-
!existsSync(path.resolve(folder, '.git'))
|
|
18
|
+
} while (prev !== folder && // Not at root
|
|
19
|
+
!pred(pkg) && // Matches criteria
|
|
20
|
+
!existsSync(path.resolve(folder, '.git')) // Not at source root
|
|
21
|
+
);
|
|
19
22
|
if (!pkg) {
|
|
20
23
|
throw new Error('Could not find a package.json');
|
|
21
24
|
}
|
|
22
25
|
return pkg;
|
|
23
26
|
}
|
|
27
|
+
/**
|
|
28
|
+
* Gets build context
|
|
29
|
+
*/
|
|
24
30
|
export function getManifestContext(root = process.cwd()) {
|
|
25
31
|
const workspace = findPackage(root, pkg => !!pkg?.workspaces || !!pkg?.travetto?.build?.isolated);
|
|
26
32
|
const build = workspace.travetto?.build ?? {};
|
package/bin/trvc.js
CHANGED
|
@@ -1,45 +1,39 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
+
const help = `
|
|
3
|
+
npx trvc [command]
|
|
2
4
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
+
Available Commands:
|
|
6
|
+
* start|watch - Run the compiler in watch mode
|
|
7
|
+
* stop - Stop the compiler if running
|
|
8
|
+
* restart - Restart the compiler in watch mode
|
|
9
|
+
* build - Ensure the project is built and upto date
|
|
10
|
+
* clean - Clean out the output and compiler caches
|
|
11
|
+
* info - Retrieve the compiler information, if running
|
|
12
|
+
* event <log|progress|state> - Watch events in realtime as newline delimited JSON
|
|
13
|
+
* exec <file> [...args] - Allow for compiling and executing an entrypoint file
|
|
14
|
+
* manifest --prod [output] - Generate the project manifest
|
|
15
|
+
`;
|
|
5
16
|
|
|
6
|
-
const
|
|
7
|
-
|
|
8
|
-
'',
|
|
9
|
-
'Available Commands:',
|
|
10
|
-
' * start|watch - Run the compiler in watch mode',
|
|
11
|
-
' * stop - Stop the compiler if running',
|
|
12
|
-
' * restart - Restart the compiler in watch mode',
|
|
13
|
-
' * build - Ensure the project is built and upto date',
|
|
14
|
-
' * clean - Clean out the output and compiler caches',
|
|
15
|
-
' * info - Retrieve the compiler information, if running',
|
|
16
|
-
' * event <log|progress|state> - Watch events in realtime as newline delimited JSON',
|
|
17
|
-
' * exec <file> [...args] - Allow for compiling and executing an entrypoint file',
|
|
18
|
-
' * manifest --prod [output] - Generate the project manifest',
|
|
19
|
-
].join('\n');
|
|
17
|
+
const toJson = (/** @type {number} */ depth) => v => process.stdout.write(`${JSON.stringify(v, undefined, depth)}\n`) ||
|
|
18
|
+
new Promise(r => process.stdout.once('drain', r));
|
|
20
19
|
|
|
21
|
-
|
|
20
|
+
require('./entry.common.js').load(ops => {
|
|
22
21
|
const [op, ...all] = process.argv.slice(2);
|
|
23
22
|
const args = all.filter(x => !x.startsWith('-'));
|
|
24
|
-
const flags = all.filter(x => x.startsWith('-'));
|
|
25
23
|
|
|
26
24
|
switch (op) {
|
|
27
25
|
case undefined:
|
|
28
|
-
case 'help': return console.log(
|
|
29
|
-
case '
|
|
30
|
-
case '
|
|
31
|
-
case '
|
|
32
|
-
case '
|
|
33
|
-
|
|
34
|
-
return new Promise(r => process.stdout.once('drain', r));
|
|
35
|
-
}
|
|
36
|
-
});
|
|
26
|
+
case 'help': return console.log(help);
|
|
27
|
+
case 'info': return ops.info().then(toJson(2));
|
|
28
|
+
case 'event': return ops.events(args[0], toJson(0));
|
|
29
|
+
case 'manifest': return ops.manifest(args[0], all.some(x => x === '--prod'));
|
|
30
|
+
case 'exec': return ops.exec(args[0], all.slice(1));
|
|
31
|
+
case 'build': return ops.build();
|
|
37
32
|
case 'clean': return ops.clean();
|
|
38
|
-
case 'manifest': return ops.manifest(args[0], flags.some(x => x === '--prod'));
|
|
39
|
-
case 'exec': return ops.getLoader().then(v => v(args[0], all.slice(1)));
|
|
40
33
|
case 'start':
|
|
41
34
|
case 'watch': return ops.watch();
|
|
42
|
-
case '
|
|
43
|
-
|
|
35
|
+
case 'stop': return ops.stop();
|
|
36
|
+
case 'restart': return ops.restart();
|
|
37
|
+
default: console.error(`\nUnknown trvc operation: ${op}\n${help}`);
|
|
44
38
|
}
|
|
45
39
|
});
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@travetto/compiler",
|
|
3
|
-
"version": "5.0.
|
|
3
|
+
"version": "5.0.17",
|
|
4
4
|
"description": "The compiler infrastructure for the Travetto framework",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"compiler",
|
|
@@ -28,17 +28,13 @@
|
|
|
28
28
|
"url": "https://github.com/travetto/travetto.git",
|
|
29
29
|
"directory": "module/compiler"
|
|
30
30
|
},
|
|
31
|
-
"engines": {
|
|
32
|
-
"node": ">=22.0.0"
|
|
33
|
-
},
|
|
34
31
|
"dependencies": {
|
|
35
|
-
"@parcel/watcher": "^2.
|
|
36
|
-
"@travetto/manifest": "^5.0.
|
|
37
|
-
"@travetto/transformer": "^5.0.
|
|
38
|
-
"@types/node": "^22.7.7"
|
|
32
|
+
"@parcel/watcher": "^2.5.0",
|
|
33
|
+
"@travetto/manifest": "^5.0.10",
|
|
34
|
+
"@travetto/transformer": "^5.0.11"
|
|
39
35
|
},
|
|
40
36
|
"peerDependencies": {
|
|
41
|
-
"@travetto/cli": "^5.0.
|
|
37
|
+
"@travetto/cli": "^5.0.17"
|
|
42
38
|
},
|
|
43
39
|
"peerDependenciesMeta": {
|
|
44
40
|
"@travetto/cli": {
|
package/src/compiler.ts
CHANGED
|
@@ -103,7 +103,7 @@ export class Compiler {
|
|
|
103
103
|
|
|
104
104
|
for (const file of files) {
|
|
105
105
|
const err = await emitter(file);
|
|
106
|
-
const imp = file.
|
|
106
|
+
const imp = file.includes('node_modules/') ? file.split('node_modules/')[1] : file;
|
|
107
107
|
yield { file: imp, i: i += 1, err, total: files.length };
|
|
108
108
|
if ((Date.now() - lastSent) > 50) { // Limit to 1 every 50ms
|
|
109
109
|
lastSent = Date.now();
|
|
@@ -11,7 +11,6 @@ import { CompilerRunner } from './server/runner';
|
|
|
11
11
|
import { CompilerClient } from './server/client';
|
|
12
12
|
import { CommonUtil } from './util';
|
|
13
13
|
|
|
14
|
-
|
|
15
14
|
// eslint-disable-next-line @typescript-eslint/explicit-function-return-type
|
|
16
15
|
export const main = (ctx: ManifestContext) => {
|
|
17
16
|
const client = new CompilerClient(ctx, Log.scoped('client'));
|
|
@@ -91,21 +90,19 @@ export const main = (ctx: ManifestContext) => {
|
|
|
91
90
|
await compile('watch');
|
|
92
91
|
},
|
|
93
92
|
|
|
94
|
-
/**
|
|
95
|
-
async
|
|
93
|
+
/** Set arguments and import module */
|
|
94
|
+
async exec(mod: string, args?: string[]): Promise<unknown> {
|
|
96
95
|
Log.initLevel('none');
|
|
97
96
|
if (!(await client.isWatching())) { // Short circuit if we can
|
|
98
97
|
Log.initLevel('error');
|
|
99
98
|
await compile('build');
|
|
100
99
|
}
|
|
101
100
|
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
return import(CommonUtil.resolveWorkspace(ctx, ctx.build.outputFolder, 'node_modules', mod)); // Return function to run import on a module
|
|
108
|
-
};
|
|
101
|
+
process.env.TRV_MANIFEST = CommonUtil.resolveWorkspace(ctx, ctx.build.outputFolder, 'node_modules', ctx.main.name); // Setup for running
|
|
102
|
+
if (args) {
|
|
103
|
+
process.argv = [process.argv0, mod, ...args];
|
|
104
|
+
}
|
|
105
|
+
return import(CommonUtil.resolveWorkspace(ctx, ctx.build.outputFolder, 'node_modules', mod)); // Return function to run import on a module
|
|
109
106
|
},
|
|
110
107
|
|
|
111
108
|
/** Manifest entry point */
|
|
@@ -115,4 +112,6 @@ export const main = (ctx: ManifestContext) => {
|
|
|
115
112
|
}
|
|
116
113
|
};
|
|
117
114
|
return ops;
|
|
118
|
-
};
|
|
115
|
+
};
|
|
116
|
+
|
|
117
|
+
export type Operations = ReturnType<typeof main>;
|
package/bin/common.js
DELETED
|
@@ -1,101 +0,0 @@
|
|
|
1
|
-
// @ts-check
|
|
2
|
-
const { statSync, readFileSync, writeFileSync, mkdirSync, readdirSync, existsSync, rmSync } = require('node:fs');
|
|
3
|
-
const path = require('node:path');
|
|
4
|
-
|
|
5
|
-
/** @typedef {import('@travetto/manifest').ManifestContext} Ctx */
|
|
6
|
-
|
|
7
|
-
const TS_EXT = /[.]tsx?$/;
|
|
8
|
-
|
|
9
|
-
const getAge = (/** @type {{mtimeMs:number, ctimeMs:number}} */ st) => Math.max(st.mtimeMs, st.ctimeMs);
|
|
10
|
-
|
|
11
|
-
const modPath = (/** @type {Ctx} */ ctx, mod, file) => {
|
|
12
|
-
const base = path.resolve(ctx.workspace.path, ctx.build.compilerFolder, 'node_modules', mod, file);
|
|
13
|
-
return `${base}${file.includes('.') ? '' : file.includes('/') ? '.ts' : '/__index__.ts'}`.replace(TS_EXT, '.js');
|
|
14
|
-
};
|
|
15
|
-
|
|
16
|
-
const needsWriting = (/** @type {string} */ src, /** @type {string} */ dest) =>
|
|
17
|
-
!existsSync(dest) || getAge(statSync(dest)) < getAge(statSync(src));
|
|
18
|
-
|
|
19
|
-
const getTarget = (/** @type {Ctx} */ ctx, file = '') => ({
|
|
20
|
-
dest: modPath(ctx, '@travetto/compiler', file),
|
|
21
|
-
src: path.resolve(ctx.workspace.path, ctx.build.compilerModuleFolder, file),
|
|
22
|
-
async writeIfStale(/** @type {(text:string)=>(string|Promise<string>)}*/ transform) {
|
|
23
|
-
if (needsWriting(this.src, this.dest)) {
|
|
24
|
-
const text = readFileSync(this.src, 'utf8');
|
|
25
|
-
mkdirSync(path.dirname(this.dest), { recursive: true });
|
|
26
|
-
writeFileSync(this.dest, await transform(text), 'utf8');
|
|
27
|
-
}
|
|
28
|
-
}
|
|
29
|
-
});
|
|
30
|
-
|
|
31
|
-
const getTranspiler = async (/** @type {Ctx} */ ctx) => {
|
|
32
|
-
const ts = (await import('typescript')).default;
|
|
33
|
-
const module = ctx.workspace.type === 'module' ? ts.ModuleKind.ESNext : ts.ModuleKind.CommonJS;
|
|
34
|
-
return (content = '') =>
|
|
35
|
-
ts.transpile(content, { target: ts.ScriptTarget.ES2022, module, esModuleInterop: true, allowSyntheticDefaultImports: true })
|
|
36
|
-
.replace(/from '([.][^']+)'/g, (_, i) => `from '${i.replace(/[.]js$/, '')}.js'`)
|
|
37
|
-
.replace(/from '(@travetto\/[^/']+)([/][^']+)?'/g, (_, mod, file) => `from '${modPath(ctx, mod, file)}'`);
|
|
38
|
-
};
|
|
39
|
-
|
|
40
|
-
async function getEntry() {
|
|
41
|
-
process.setSourceMapsEnabled(true); // Ensure source map during compilation/development
|
|
42
|
-
process.env.NODE_OPTIONS = `${process.env.NODE_OPTIONS ?? ''} --enable-source-maps`; // Ensure it passes to children
|
|
43
|
-
|
|
44
|
-
// eslint-disable-next-line no-undef
|
|
45
|
-
const manifestJs = path.resolve(__dirname, 'manifest-context.mjs');
|
|
46
|
-
const loc = require.resolve('@travetto/manifest').replace(/__index__.*/, 'src/context.ts');
|
|
47
|
-
|
|
48
|
-
// Compile if needed
|
|
49
|
-
if (needsWriting(loc, manifestJs)) {
|
|
50
|
-
const ts = (await import('typescript')).default;
|
|
51
|
-
const text = ts.transpile(readFileSync(loc, 'utf8'), {
|
|
52
|
-
target: ts.ScriptTarget.ES2022,
|
|
53
|
-
module: ts.ModuleKind.ESNext,
|
|
54
|
-
removeComments: true
|
|
55
|
-
}, manifestJs);
|
|
56
|
-
writeFileSync(manifestJs, text, 'utf8');
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
// Load module on demand
|
|
60
|
-
/** @type {import('@travetto/manifest/src/context')} */
|
|
61
|
-
const { getManifestContext } = await import(manifestJs);
|
|
62
|
-
|
|
63
|
-
/** @type {Ctx} */
|
|
64
|
-
const ctx = getManifestContext();
|
|
65
|
-
const target = getTarget.bind(null, ctx);
|
|
66
|
-
|
|
67
|
-
// Setup Tsconfig
|
|
68
|
-
const tsconfig = path.resolve(ctx.workspace.path, 'tsconfig.json');
|
|
69
|
-
existsSync(tsconfig) || writeFileSync(tsconfig,
|
|
70
|
-
JSON.stringify({ extends: '@travetto/compiler/tsconfig.trv.json' }), 'utf8');
|
|
71
|
-
|
|
72
|
-
// Compile support folder
|
|
73
|
-
await target('package.json').writeIfStale(text =>
|
|
74
|
-
JSON.stringify(Object.assign(JSON.parse(text), { type: ctx.workspace.type }), null, 2)
|
|
75
|
-
);
|
|
76
|
-
|
|
77
|
-
let transpile;
|
|
78
|
-
for (const file of readdirSync(target('support').src, { recursive: true, encoding: 'utf8' })) {
|
|
79
|
-
if (TS_EXT.test(file)) {
|
|
80
|
-
await target(`support/${file}`).writeIfStale(async (text) =>
|
|
81
|
-
(transpile ??= await getTranspiler(ctx))(text)
|
|
82
|
-
);
|
|
83
|
-
}
|
|
84
|
-
}
|
|
85
|
-
|
|
86
|
-
// Load
|
|
87
|
-
try {
|
|
88
|
-
// @ts-ignore
|
|
89
|
-
try { await import('node:module').then(v => v.enableCompileCache()); } catch { }
|
|
90
|
-
|
|
91
|
-
/** @type {import('../support/entry.trvc')} */
|
|
92
|
-
const res = await import(target('support/entry.trvc.ts').dest);
|
|
93
|
-
return await res.main(ctx);
|
|
94
|
-
} catch (err) {
|
|
95
|
-
rmSync(target('.').dest, { recursive: true, force: true });
|
|
96
|
-
throw err;
|
|
97
|
-
}
|
|
98
|
-
}
|
|
99
|
-
|
|
100
|
-
// eslint-disable-next-line no-undef
|
|
101
|
-
module.exports = { getEntry };
|