@travetto/compiler 3.0.0-rc.8 → 3.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.
@@ -0,0 +1,210 @@
1
+ import path from 'path';
2
+ import fs from 'fs/promises';
3
+ import os from 'os';
4
+ import cp from 'child_process';
5
+ import { createRequire } from 'module';
6
+
7
+ import { DeltaEvent, ManifestContext, ManifestRoot, Package } from '@travetto/manifest';
8
+
9
+ import { LogUtil } from './log';
10
+
11
+ type ModFile = { input: string, output: string, stale: boolean };
12
+ export type CompileResult = 'restart' | 'complete' | 'skipped';
13
+
14
+ const OPT_CACHE: Record<string, import('typescript').CompilerOptions> = {};
15
+ const SRC_REQ = createRequire(path.resolve('node_modules'));
16
+ const RECENT_STAT = (stat: { ctimeMs: number, mtimeMs: number }): number => Math.max(stat.ctimeMs, stat.mtimeMs);
17
+
18
+ /**
19
+ * Transpile utilities for launching
20
+ */
21
+ export class TranspileUtil {
22
+ /**
23
+ * Write text file, and ensure folder exists
24
+ */
25
+ static writeTextFile = (file: string, content: string): Promise<void> =>
26
+ fs.mkdir(path.dirname(file), { recursive: true }).then(() => fs.writeFile(file, content, 'utf8'));
27
+
28
+ /**
29
+ * Returns the compiler options
30
+ */
31
+ static async getCompilerOptions(ctx: ManifestContext): Promise<{}> {
32
+ if (!(ctx.workspacePath in OPT_CACHE)) {
33
+ let tsconfig = path.resolve(ctx.workspacePath, 'tsconfig.json');
34
+
35
+ if (!await fs.stat(tsconfig).then(_ => true, _ => false)) {
36
+ tsconfig = SRC_REQ.resolve('@travetto/compiler/tsconfig.trv.json');
37
+ }
38
+
39
+ const ts = (await import('typescript')).default;
40
+
41
+ const { options } = ts.parseJsonSourceFileConfigFileContent(
42
+ ts.readJsonConfigFile(tsconfig, ts.sys.readFile), ts.sys, ctx.workspacePath
43
+ );
44
+
45
+ OPT_CACHE[ctx.workspacePath] = {
46
+ ...options,
47
+ allowJs: true,
48
+ sourceMap: false,
49
+ inlineSourceMap: true,
50
+ resolveJsonModule: true,
51
+ sourceRoot: ctx.workspacePath,
52
+ rootDir: ctx.workspacePath,
53
+ outDir: path.resolve(ctx.workspacePath),
54
+ module: ctx.moduleType === 'commonjs' ? ts.ModuleKind.CommonJS : ts.ModuleKind.ESNext,
55
+ };
56
+ }
57
+ return OPT_CACHE[ctx.workspacePath];
58
+ }
59
+
60
+ /**
61
+ * Output a file, support for ts, js, and package.json
62
+ */
63
+ static async transpileFile(ctx: ManifestContext, inputFile: string, outputFile: string): Promise<void> {
64
+ if (inputFile.endsWith('.ts') || inputFile.endsWith('.js')) {
65
+ const compilerOut = path.resolve(ctx.workspacePath, ctx.compilerFolder, 'node_modules');
66
+
67
+ const text = (await fs.readFile(inputFile, 'utf8'))
68
+ .replace(/from '([.][^']+)'/g, (_, i) => `from '${i.replace(/[.]js$/, '')}.js'`)
69
+ .replace(/from '(@travetto\/(.*?))'/g, (_, i, s) => `from '${path.resolve(compilerOut, `${i}${s.includes('/') ? '.js' : '/__index__.js'}`)}'`);
70
+
71
+ const ts = (await import('typescript')).default;
72
+ const content = ts.transpile(text, await this.getCompilerOptions(ctx), inputFile);
73
+ await this.writeTextFile(outputFile, content);
74
+ } else if (inputFile.endsWith('package.json')) {
75
+ const pkg: Package = JSON.parse(await fs.readFile(inputFile, 'utf8'));
76
+ const main = pkg.main?.replace(/[.]ts$/, '.js');
77
+ const files = pkg.files?.map(x => x.replace('.ts', '.js'));
78
+
79
+ const content = JSON.stringify({ ...pkg, main, type: ctx.moduleType, files }, null, 2);
80
+ await this.writeTextFile(outputFile, content);
81
+ }
82
+ }
83
+
84
+ /**
85
+ * Scan directory to find all project sources for comparison
86
+ */
87
+ static async getModuleSources(ctx: ManifestContext, module: string, seed: string[]): Promise<ModFile[]> {
88
+ const inputFolder = (ctx.mainModule === module) ?
89
+ process.cwd() :
90
+ path.dirname(SRC_REQ.resolve(`${module}/package.json`));
91
+
92
+ const folders = seed.filter(x => !/[.]/.test(x)).map(x => path.resolve(inputFolder, x));
93
+ const files = seed.filter(x => /[.]/.test(x)).map(x => path.resolve(inputFolder, x));
94
+
95
+ while (folders.length) {
96
+ const sub = folders.pop();
97
+ if (!sub) {
98
+ continue;
99
+ }
100
+
101
+ for (const file of await fs.readdir(sub).catch(() => [])) {
102
+ if (file.startsWith('.')) {
103
+ continue;
104
+ }
105
+ const resolvedInput = path.resolve(sub, file);
106
+ const stat = await fs.stat(resolvedInput);
107
+
108
+ if (stat.isDirectory()) {
109
+ folders.push(resolvedInput);
110
+ } else if (file.endsWith('.d.ts')) {
111
+ // Do nothing
112
+ } else if (file.endsWith('.ts') || file.endsWith('.js')) {
113
+ files.push(resolvedInput);
114
+ }
115
+ }
116
+ }
117
+
118
+ const outputFolder = path.resolve(ctx.workspacePath, ctx.compilerFolder, 'node_modules', module);
119
+ const out: ModFile[] = [];
120
+ for (const input of files) {
121
+ const output = input.replace(inputFolder, outputFolder).replace(/[.]ts$/, '.js');
122
+ const inputTs = await fs.stat(input).then(RECENT_STAT, () => 0);
123
+ if (inputTs) {
124
+ const outputTs = await fs.stat(output).then(RECENT_STAT, () => 0);
125
+ await fs.mkdir(path.dirname(output), { recursive: true, });
126
+ out.push({ input, output, stale: inputTs > outputTs });
127
+ }
128
+ }
129
+
130
+ return out;
131
+ }
132
+
133
+ /**
134
+ * Recompile folder if stale
135
+ */
136
+ static async compileIfStale(ctx: ManifestContext, scope: string, mod: string, seed: string[]): Promise<string[]> {
137
+ const files = await this.getModuleSources(ctx, mod, seed);
138
+ const changes = files.filter(x => x.stale).map(x => x.input);
139
+ const out: string[] = [];
140
+
141
+ try {
142
+ await LogUtil.withLogger(scope, async log => {
143
+ if (files.some(f => f.stale)) {
144
+ log('debug', 'Starting');
145
+ for (const file of files.filter(x => x.stale)) {
146
+ await this.transpileFile(ctx, file.input, file.output);
147
+ }
148
+ if (changes.length) {
149
+ out.push(...changes.map(x => `${mod}/${x}`));
150
+ log('debug', `Source changed: ${changes.join(', ')}`);
151
+ }
152
+ log('debug', 'Completed');
153
+ } else {
154
+ log('debug', 'Skipped');
155
+ }
156
+ }, false, [mod]);
157
+ } catch (err) {
158
+ console.error(err);
159
+ }
160
+ return out;
161
+ }
162
+
163
+ /**
164
+ * Run compiler
165
+ */
166
+ static async runCompiler(ctx: ManifestContext, manifest: ManifestRoot, changed: DeltaEvent[], watch: boolean, onMessage: (msg: unknown) => void): Promise<CompileResult> {
167
+ const compiler = path.resolve(ctx.workspacePath, ctx.compilerFolder);
168
+ const main = path.resolve(compiler, 'node_modules', '@travetto/compiler/support/compiler-entry.js');
169
+ const deltaFile = path.resolve(os.tmpdir(), `manifest-delta.${process.pid}.${process.ppid}.${Date.now()}.json`);
170
+
171
+ const changedFiles = changed[0]?.file === '*' ? ['*'] : changed.map(ev =>
172
+ path.resolve(manifest.workspacePath, manifest.modules[ev.module].sourceFolder, ev.file)
173
+ );
174
+
175
+ let proc: cp.ChildProcess | undefined;
176
+ let kill: (() => void) | undefined;
177
+
178
+ try {
179
+ await this.writeTextFile(deltaFile, changedFiles.join('\n'));
180
+
181
+ return await LogUtil.withLogger('compiler-exec', log => new Promise<CompileResult>((res, rej) => {
182
+ proc = cp.spawn(process.argv0, [main, deltaFile, `${watch}`], {
183
+ env: {
184
+ ...process.env,
185
+ TRV_MANIFEST: path.resolve(ctx.workspacePath, ctx.outputFolder, 'node_modules', ctx.mainModule),
186
+ },
187
+ stdio: [0, 1, 2, 'ipc'],
188
+ })
189
+ .on('message', msg => {
190
+ if (LogUtil.isLogEvent(msg)) {
191
+ log(...msg);
192
+ } else if (msg === 'restart') {
193
+ res(msg);
194
+ } else {
195
+ onMessage(msg);
196
+ }
197
+ })
198
+ .on('exit', code => (code !== null && code > 0) ? rej(new Error('Failed during compilation')) : res('complete'));
199
+ kill = (): void => { proc?.kill('SIGKILL'); };
200
+ process.on('exit', kill);
201
+ }));
202
+ } finally {
203
+ if (proc?.killed === false) { proc.kill('SIGKILL'); }
204
+ if (kill) {
205
+ process.removeListener('exit', kill);
206
+ }
207
+ await fs.rm(deltaFile, { force: true });
208
+ }
209
+ }
210
+ }
package/tsconfig.trv.json CHANGED
@@ -17,6 +17,7 @@
17
17
  "inlineSourceMap": false,
18
18
  "removeComments": true,
19
19
  "importHelpers": true,
20
+ "noEmitHelpers": true,
20
21
  "outDir": "build/"
21
22
  },
22
23
  }
@@ -1,32 +0,0 @@
1
- import type { ManifestContext, Package } from '@travetto/manifest';
2
-
3
- declare namespace Transpile {
4
- type CompileCommand = 'build' | 'watch' | 'clean' | 'manifest';
5
-
6
- /**
7
- * Writes a package json file
8
- */
9
- function writePackageJson(ctx: ManifestContext, inputFile: string, outputFile: string, transform?: (pkg: Package) => Package): Promise<void>;
10
-
11
- /**
12
- * Transpiles a file
13
- */
14
- function transpileFile(ctx: ManifestContext, inputFile: string, outputFile: string): Promise<void>;
15
-
16
- /**
17
- * Write js file
18
- */
19
- function writeJsFile(ctx: ManifestContext, inputFile: string, outputFile: string): Promise<void>;
20
-
21
- /**
22
- * Build an entire package
23
- */
24
- function buildPackage(ctx: ManifestContext, name: string, sourcePath: string, mainSource: string, extraSource: string[]): Promise<string>;
25
-
26
- /**
27
- * Get Context for building
28
- */
29
- function getContext(folder?: string): Promise<ManifestContext>;
30
- }
31
-
32
- export = Transpile;
package/bin/transpile.js DELETED
@@ -1,227 +0,0 @@
1
- // @ts-check
2
-
3
- const _opts = {};
4
-
5
- /**
6
- * @typedef {import('@travetto/manifest').Package} Pkg
7
- * @typedef {import('@travetto/manifest').ManifestContext} ManifestContext
8
- */
9
-
10
- function $imp(mod) {
11
- try { return require(mod); } catch { return import(mod).then(x => x.default); }
12
- }
13
-
14
- /** @type {() => import('typescript')} */
15
- const $getTs = $imp.bind(null, 'typescript');
16
- /** @type {() => import('fs/promises')} */
17
- const $getFs = $imp.bind(null, 'fs/promises');
18
- /** @type {() => import('path')} */
19
- const $getPath = $imp.bind(null, 'path');
20
- /** @type {() => ({createRequire:(folder:string) => ({ resolve: (file:string)=>string})})} */
21
- const $getModule = $imp.bind(null, 'module');
22
- /** @param {string} x */
23
- const toPosix = x => x.replace(/\\/g, '/');
24
-
25
- /**
26
- * Returns the package.json
27
- * @param {string} inputFolder
28
- * @returns {Promise<Pkg>}
29
- */
30
- async function $getPkg(inputFolder) {
31
- const fs = await $getFs();
32
- const path = await $getPath();
33
- if (!inputFolder.endsWith('.json')) {
34
- inputFolder = path.resolve(inputFolder, 'package.json');
35
- }
36
- return JSON.parse(await fs.readFile(inputFolder, 'utf8'));
37
- }
38
-
39
- /**
40
- * Get workspace root
41
- * @return {Promise<string>}
42
- */
43
- async function $getWorkspaceRoot() {
44
- const path = await $getPath();
45
- const fs = await $getFs();
46
- let folder = process.cwd();
47
- let prevFolder = '';
48
- while (folder !== prevFolder) {
49
- try {
50
- const pkg = await $getPkg(folder);
51
- if (!!pkg.workspaces || !!pkg.travetto?.isolated) {
52
- return folder;
53
- }
54
- } catch { }
55
- if (await fs.stat(path.resolve(folder, '.git')).catch(() => { })) {
56
- break;
57
- }
58
- prevFolder = folder;
59
- folder = path.dirname(folder);
60
- }
61
- return process.cwd();
62
- }
63
-
64
- /**
65
- * Returns the compiler options
66
- * @param {ManifestContext} ctx
67
- * @returns
68
- */
69
- async function $getOpts(ctx) {
70
- if (!(ctx.workspacePath in _opts)) {
71
- const path = await $getPath();
72
- const fs = await $getFs();
73
- const ts = await $getTs();
74
- const mod = await $getModule();
75
- const req = mod.createRequire(`${ctx.workspacePath}/node_modules`);
76
-
77
- const framework = req.resolve('@travetto/compiler/tsconfig.trv.json');
78
- const self = path.resolve(ctx.workspacePath, 'tsconfig.json');
79
- const loc = (await fs.stat(self).catch(() => false)) ? self : framework;
80
- const { options } = ts.parseJsonSourceFileConfigFileContent(
81
- ts.readJsonConfigFile(loc, ts.sys.readFile), ts.sys, ctx.workspacePath
82
- );
83
- options.inlineSourceMap = true;
84
- options.sourceMap = false;
85
- try {
86
- const { type } = await $getPkg(ctx.workspacePath);
87
- if (type) {
88
- options.module = type.toLowerCase() === 'commonjs' ? ts.ModuleKind.CommonJS : ts.ModuleKind.ESNext;
89
- }
90
- } catch { }
91
-
92
- _opts[ctx.workspacePath] = options;
93
- }
94
- return _opts[ctx.workspacePath];
95
- }
96
-
97
- /**
98
- * Writes a package json file
99
- * @param {ManifestContext} ctx
100
- * @param {string} inputFile
101
- * @param {string} outputFile
102
- * @param {(pkg:Pkg) => Pkg} transform
103
- */
104
- async function writePackageJson(ctx, inputFile, outputFile, transform) {
105
- const opts = await $getOpts(ctx);
106
- const ts = await $getTs();
107
- const isEsm = opts.module !== ts.ModuleKind.CommonJS;
108
- let pkg = await $getPkg(inputFile);
109
- pkg = transform?.(pkg) ?? pkg;
110
- pkg.main = pkg.main?.replace(/[.]ts$/, '.js');
111
- pkg.type = isEsm ? 'module' : 'commonjs';
112
- pkg.files = pkg.files?.map(x => x.replace('.ts', '.js'));
113
-
114
- ts.sys.writeFile(outputFile, JSON.stringify(pkg, null, 2));
115
- }
116
-
117
- /**
118
- * Transpiles a file
119
- * @param {ManifestContext} ctx
120
- * @param {string} inputFile
121
- * @param {string} outputFile
122
- */
123
- async function transpileFile(ctx, inputFile, outputFile) {
124
- const ts = await $getTs();
125
- const fs = await $getFs();
126
-
127
- const opts = await $getOpts(ctx);
128
- const content = ts.transpile(await fs.readFile(inputFile, 'utf8'), opts, inputFile)
129
- .replace(/^((?:im|ex)port .*from '[.][^']+)(')/mg, (_, a, b) => `${a}.js${b}`)
130
- .replace(/^(import [^\n]*from '[^.][^\n/]+[/][^\n/]+[/][^\n']+)(')/mg, (_, a, b) => `${a}.js${b}`);
131
-
132
- ts.sys.writeFile(outputFile, content);
133
- }
134
-
135
- /**
136
- * Writes a js file
137
- * @param {ManifestContext} ctx
138
- * @param {string} inputFile
139
- * @param {string} outputFile
140
- */
141
- async function writeJsFile(ctx, inputFile, outputFile) {
142
- const ts = await $getTs();
143
- const fs = await $getFs();
144
-
145
- const opts = await $getOpts(ctx);
146
- const isEsm = opts.module !== ts.ModuleKind.CommonJS;
147
-
148
- let content = await fs.readFile(inputFile, 'utf8');
149
- if (isEsm) {
150
- content = content
151
- .replace(/^(?:async )?function [^$]/mg, a => `export ${a}`)
152
- .replace(/^module.exports.*/mg, '');
153
- }
154
-
155
- await fs.writeFile(outputFile, content, 'utf8');
156
- }
157
-
158
- /**
159
- * Write an entire package
160
- * @param {ManifestContext} ctx
161
- * @param {string} name
162
- * @param {string} sourcePath
163
- * @param {string} mainSource
164
- * @param {string[]} extraSources
165
- */
166
- async function buildPackage(ctx, name, sourcePath, mainSource, extraSources) {
167
- const path = await $getPath();
168
- const fs = await $getFs();
169
-
170
- const files = [mainSource, ...extraSources].map(x => ({ src: x, out: x.replace(/[.]ts$/, '.js') }));
171
- const main = files[0].out;
172
- const outputPath = path.resolve(ctx.workspacePath, ctx.compilerFolder, 'node_modules', name);
173
-
174
- for (const { src, out } of files) {
175
- const inputFile = path.resolve(sourcePath, src);
176
- const outputFile = path.resolve(outputPath, out);
177
-
178
- const [outStat, inStat] = await Promise.all([
179
- fs.stat(outputFile).catch(() => undefined),
180
- fs.stat(inputFile)
181
- ]);
182
-
183
- if (!outStat || (outStat.mtimeMs < inStat.mtimeMs)) {
184
- await fs.mkdir(path.dirname(outputFile), { recursive: true });
185
-
186
- if (inputFile.endsWith('.ts')) {
187
- await transpileFile(ctx, inputFile, outputFile);
188
- } else if (inputFile.endsWith('.js')) {
189
- await writeJsFile(ctx, inputFile, outputFile);
190
- } else if (inputFile.endsWith('.json')) {
191
- await writePackageJson(ctx, inputFile, outputFile,
192
- (pkg) => ({ ...pkg, files: files.map(x => x.out), name, main }));
193
- }
194
- }
195
- }
196
-
197
- return path.resolve(outputPath, main);
198
- }
199
-
200
- /**
201
- * Gets build context
202
- * @return {Promise<ManifestContext>}
203
- */
204
- async function getContext(folder = process.cwd()) {
205
- const path = await $getPath();
206
-
207
- const workspacePath = path.resolve(await $getWorkspaceRoot());
208
- const mainPath = toPosix(folder);
209
-
210
- const { name: mainModule, workspaces, travetto } = (await $getPkg(mainPath));
211
- const monoRepo = workspacePath !== mainPath || !!workspaces;
212
-
213
- // All relative to workspacePath
214
- const manifestFile = `node_modules/${mainModule}/manifest.json`;
215
-
216
- return {
217
- mainModule,
218
- mainPath,
219
- workspacePath,
220
- monoRepo,
221
- manifestFile,
222
- outputFolder: travetto?.outputFolder ?? '.trv_output',
223
- compilerFolder: '.trv_compiler'
224
- };
225
- }
226
-
227
- module.exports = { transpileFile, writePackageJson, writeJsFile, buildPackage, getContext };
@@ -1,151 +0,0 @@
1
- import path from 'path';
2
- import fs from 'fs/promises';
3
- import cp from 'child_process';
4
-
5
- import type { ManifestState, ManifestContext, ManifestRoot } from '@travetto/manifest';
6
-
7
- import { log, compileIfStale, getProjectSources, addNodePath, importManifest } from './utils';
8
-
9
- const PRECOMPILE_MODS = [
10
- '@travetto/terminal',
11
- '@travetto/manifest',
12
- '@travetto/transformer',
13
- '@travetto/compiler'
14
- ];
15
-
16
- let manifestTemp;
17
-
18
- /**
19
- * Step 0
20
- */
21
- export async function precompile(ctx: ManifestContext): Promise<void> {
22
- for (const mod of PRECOMPILE_MODS) {
23
- await compileIfStale(ctx, `[0] Compiling ${mod}`, await getProjectSources(ctx, mod),);
24
- }
25
- }
26
-
27
- export async function writeManifest(ctx: ManifestContext, manifest: ManifestRoot): Promise<void> {
28
- const { ManifestUtil } = await importManifest(ctx);
29
- return ManifestUtil.writeManifest(ctx, manifest);
30
- }
31
-
32
- async function rewriteManifests(ctx: ManifestContext, state: ManifestState): Promise<void> {
33
- const { ManifestUtil } = await importManifest(ctx);
34
-
35
- // Write out all changed manifests
36
- const { getContext } = await import('../../bin/transpile');
37
-
38
- const dirtyModules = [...Object.entries(state.delta)].filter(x => x[1].length > 0).map(([mod]) => mod);
39
- for (const module of dirtyModules) {
40
- const subCtx = await getContext(state.manifest.modules[module].source);
41
- await ManifestUtil.createAndWriteManifest(subCtx);
42
- }
43
- }
44
-
45
- /**
46
- * Step 1
47
- */
48
- export async function buildManifest(ctx: ManifestContext): Promise<ManifestState> {
49
- log('[1] Manifest Generation');
50
- const { ManifestUtil } = await importManifest(ctx);
51
- return ManifestUtil.produceState(ctx);
52
- }
53
-
54
- function shouldRebuildCompiler({ delta }: ManifestState): { total: boolean, transformers: [string, string][] } {
55
- // Did enough things change to re-stage and build the compiler
56
- const transformersChanged = Object.entries(delta)
57
- .flatMap(([mod, files]) => files.map(x => [mod, x.file]))
58
- .filter((ev): ev is [string, string] => ev[1].startsWith('support/transform'));
59
- const transformerChanged = (delta['@travetto/transformer'] ?? []);
60
- const compilerChanged = delta['@travetto/compiler'] ?? [];
61
-
62
- const changed = transformerChanged.length || transformersChanged.length || compilerChanged.length;
63
- if (changed) {
64
- if (compilerChanged.length) {
65
- log('[2] Compiler source changed @travetto/compiler', compilerChanged);
66
- }
67
- if (transformerChanged.length) {
68
- log('[2] Compiler source changed @travetto/transformer', transformerChanged);
69
- }
70
- if (transformersChanged.length) {
71
- log('[2] Compiler source changed */support/transform', transformersChanged);
72
- }
73
- }
74
- return { total: changed > 0, transformers: transformersChanged };
75
- }
76
-
77
- /**
78
- * Step 2
79
- */
80
- async function buildCompiler(state: ManifestState, ctx: ManifestContext): Promise<void> {
81
- const changed = shouldRebuildCompiler(state);
82
-
83
- if (changed.transformers.length) {
84
- state = await buildManifest(ctx);
85
- let x = 0;
86
- for (const [mod, file] of changed.transformers) {
87
- await compileIfStale(
88
- ctx,
89
- `[2.${x += 1}] ${file} Bootstrapping`,
90
- await getProjectSources(ctx, mod, ['package.json', file])
91
- );
92
- }
93
- }
94
-
95
- log('[2] Compiler Ready');
96
- }
97
-
98
- /**
99
- * Step 4
100
- */
101
- async function compileOutput(state: ManifestState, ctx: ManifestContext, watch?: boolean): Promise<void> {
102
- let changes = Object.values(state.delta).flat();
103
-
104
- // Remove files that should go away
105
- await Promise.all(changes.filter(x => x.type === 'removed')
106
- .map(x => fs.unlink(path.resolve(ctx.workspacePath, ctx.outputFolder, x.file)).catch(() => { })));
107
-
108
- changes = changes.filter(x => x.type !== 'removed');
109
-
110
- const { ManifestUtil } = await importManifest(ctx);
111
- const resolve = ManifestUtil.resolveFile.bind(null, ctx, state.manifest, '@travetto/compiler');
112
-
113
- manifestTemp ??= await ManifestUtil.writeState(state);
114
- const cwd = path.resolve(ctx.workspacePath, ctx.compilerFolder);
115
-
116
- if (changes.length) {
117
- log('[3] Changed Sources', changes);
118
-
119
- // Blocking call, compile only
120
- const res = cp.spawnSync(process.argv0,
121
- [resolve('support/main.output'), manifestTemp],
122
- { cwd, stdio: 'inherit', encoding: 'utf8' }
123
- );
124
-
125
- if (res.status) {
126
- throw new Error(res.stderr);
127
- }
128
-
129
- await rewriteManifests(ctx, state);
130
- }
131
-
132
- if (watch) {
133
- // Rewrite state with updated manifest
134
- const newState = await ManifestUtil.produceState(ctx);
135
- manifestTemp = await ManifestUtil.writeState(newState);
136
-
137
- // Run with watching
138
- cp.spawnSync(process.argv0,
139
- [resolve('support/main.output'), manifestTemp, 'true'], { cwd, stdio: 'inherit' }
140
- );
141
- }
142
- }
143
-
144
- export async function compile(ctx: ManifestContext, watch?: boolean): Promise<ManifestState> {
145
- await precompile(ctx); // Step 0
146
- const state = await buildManifest(ctx); // Step 1
147
- await buildCompiler(state, ctx); // Step 2
148
- await compileOutput(state, ctx, watch); // Step 3
149
- await addNodePath(path.resolve(ctx.workspacePath, ctx.outputFolder));
150
- return state;
151
- }