@travetto/compiler
Advanced tools
Comparing version 4.1.2 to 5.0.0-rc.0
@@ -13,4 +13,9 @@ // @ts-check | ||
const modPath = (/** @type {Ctx} */ ctx, mod, file) => { | ||
const base = path.resolve(ctx.workspace.path, ctx.build.compilerFolder, 'node_modules', mod, file); | ||
return `${base}${file.includes('.') ? '' : file.includes('/') ? '.ts' : '/__index__.ts'}`.replace(TS_EXT, '.js'); | ||
}; | ||
const getTarget = (/** @type {Ctx} */ ctx, file = '') => ({ | ||
dest: path.resolve(ctx.workspace.path, ctx.build.compilerFolder, 'node_modules', '@travetto/compiler', file).replace(TS_EXT, '.js'), | ||
dest: modPath(ctx, '@travetto/compiler', file), | ||
src: path.resolve(ctx.workspace.path, ctx.build.compilerModuleFolder, file), | ||
@@ -32,4 +37,3 @@ async writeIfStale(/** @type {(text:string)=>(string|Promise<string>)}*/ transform) { | ||
.replace(/from '([.][^']+)'/g, (_, i) => `from '${i.replace(/[.]js$/, '')}.js'`) | ||
.replace(/from '(@travetto\/(.*?))'/g, (_, i, s) => | ||
`from '${path.resolve(ctx.workspace.path, ctx.build.compilerFolder, `${i}${s.includes('/') ? '.js' : '/__index__.js'}`)}'`); | ||
.replace(/from '(@travetto\/[^/']+)([/][^']+)?'/g, (_, mod, file) => `from '${modPath(ctx, mod, file)}'`); | ||
}; | ||
@@ -49,10 +53,17 @@ | ||
const tsconfig = path.resolve(ctx.workspace.path, 'tsconfig.json'); | ||
existsSync(tsconfig) || writeFileSync(tsconfig, JSON.stringify({ extends: '@travetto/compiler/tsconfig.trv.json' }), 'utf8'); | ||
existsSync(tsconfig) || writeFileSync(tsconfig, | ||
JSON.stringify({ extends: '@travetto/compiler/tsconfig.trv.json' }), 'utf8'); | ||
// Compile support folder | ||
await target('package.json').writeIfStale(text => JSON.stringify(Object.assign(JSON.parse(text), { type: ctx.workspace.type }), null, 2)); | ||
await target('package.json').writeIfStale(text => | ||
JSON.stringify(Object.assign(JSON.parse(text), { type: ctx.workspace.type }), null, 2) | ||
); | ||
let transpile; | ||
for (const file of readdirSync(target('support').src, { recursive: true, encoding: 'utf8' })) { | ||
if (TS_EXT.test(file)) { await target(`support/${file}`).writeIfStale(async (text) => (transpile ??= await getTranspiler(ctx))(text)); } | ||
if (TS_EXT.test(file)) { | ||
await target(`support/${file}`).writeIfStale(async (text) => | ||
(transpile ??= await getTranspiler(ctx))(text) | ||
); | ||
} | ||
} | ||
@@ -59,0 +70,0 @@ |
{ | ||
"name": "@travetto/compiler", | ||
"version": "4.1.2", | ||
"version": "5.0.0-rc.0", | ||
"description": "The compiler infrastructure for the Travetto framework", | ||
@@ -34,8 +34,8 @@ "keywords": [ | ||
"@parcel/watcher": "^2.4.1", | ||
"@travetto/manifest": "^4.1.0", | ||
"@travetto/transformer": "^4.1.2", | ||
"@types/node": "^20.14.8" | ||
"@travetto/manifest": "^5.0.0-rc.0", | ||
"@travetto/transformer": "^5.0.0-rc.0", | ||
"@types/node": "^20.14.10" | ||
}, | ||
"peerDependencies": { | ||
"@travetto/cli": "^4.1.2" | ||
"@travetto/cli": "^5.0.0-rc.0" | ||
}, | ||
@@ -42,0 +42,0 @@ "peerDependenciesMeta": { |
@@ -5,4 +5,4 @@ import type { CompilerEvent, CompilerEventType } from '../support/types'; | ||
static sendEvent<K extends CompilerEventType, T extends CompilerEvent & { type: K }>(type: K, payload: T['payload']): void { | ||
process.connected && process.send!({ type, payload }, undefined, { swallowErrors: true }); | ||
process.connected && process.send!({ type, payload }, undefined, undefined, () => { }); | ||
} | ||
} |
import ts from 'typescript'; | ||
import { ManifestContext, ManifestModuleFileType, ManifestModuleUtil, ManifestRoot, Package, path } from '@travetto/manifest'; | ||
import { path, ManifestContext, ManifestModuleFileType, ManifestModuleUtil, ManifestRoot, Package } from '@travetto/manifest'; | ||
@@ -5,0 +5,0 @@ type OutputToSource = (outputFile: string) => ({ sourceFile: string } | undefined); |
@@ -22,3 +22,2 @@ import os from 'node:os'; | ||
/** | ||
@@ -48,3 +47,3 @@ * Watch support, based on compiler state and manifest details | ||
// Disable exclusions until parcel watcher fixes itself | ||
// TODO: Fix once node/parcel sort this out | ||
return os.platform() === 'linux' ? [] : [ | ||
@@ -51,0 +50,0 @@ ...ignores, |
// @trv-no-transform | ||
import fs from 'node:fs/promises'; | ||
import path from 'node:path'; | ||
@@ -13,3 +12,5 @@ import type { ManifestContext } from '@travetto/manifest'; | ||
import { CompilerClient } from './server/client'; | ||
import { CommonUtil } from './util'; | ||
// eslint-disable-next-line @typescript-eslint/explicit-function-return-type | ||
@@ -67,3 +68,3 @@ export const main = (ctx: ManifestContext) => { | ||
} else { | ||
await Promise.all(buildFolders.map(f => fs.rm(path.resolve(ctx.workspace.path, f), { force: true, recursive: true }))); | ||
await Promise.all(buildFolders.map(f => fs.rm(CommonUtil.resolveWorkspace(ctx, f), { force: true, recursive: true }))); | ||
return console.log(`Cleaned ${ctx.workspace.path}:`, buildFolders); | ||
@@ -77,2 +78,4 @@ } | ||
for await (const ev of client.fetchEvents(type)) { await handler(ev); } | ||
} else if (type === 'all') { | ||
for await (const ev of client.fetchEvents(type)) { await handler(ev); } | ||
} else { | ||
@@ -104,8 +107,7 @@ throw new Error(`Unknown event type: ${type}`); | ||
return (mod, args) => { | ||
const outputRoot = path.resolve(ctx.workspace.path, ctx.build.outputFolder); | ||
process.env.TRV_MANIFEST = path.resolve(outputRoot, 'node_modules', ctx.main.name); // Setup for running | ||
process.env.TRV_MANIFEST = CommonUtil.resolveWorkspace(ctx, ctx.build.outputFolder, 'node_modules', ctx.main.name); // Setup for running | ||
if (args) { | ||
process.argv = [process.argv0, mod, ...args]; | ||
} | ||
return import(path.join(outputRoot, 'node_modules', mod)); // Return function to run import on a module | ||
return import(CommonUtil.resolveWorkspace(ctx, ctx.build.outputFolder, 'node_modules', mod)); // Return function to run import on a module | ||
}; | ||
@@ -112,0 +114,0 @@ }, |
@@ -96,6 +96,9 @@ import rl from 'node:readline/promises'; | ||
/** Fetch compiler events */ | ||
async * fetchEvents< | ||
/** Fetch compiler events */ | ||
fetchEvents< | ||
V extends CompilerEventType, | ||
T extends (CompilerEvent & { type: V })['payload'] | ||
>(type: V, cfg: FetchEventsConfig<T> = {}): AsyncIterable<T> { | ||
>(type: V, cfg?: FetchEventsConfig<T>): AsyncIterable<T>; | ||
fetchEvents(type: 'all', cfg?: FetchEventsConfig<CompilerEvent>): AsyncIterable<CompilerEvent>; | ||
async * fetchEvents<T = unknown>(type: string, cfg: FetchEventsConfig<T> = {}): AsyncIterable<T> { | ||
let info = await this.info(); | ||
@@ -102,0 +105,0 @@ if (!info) { |
@@ -14,3 +14,3 @@ import fs from 'node:fs/promises'; | ||
constructor(ctx: ManifestContext, name: string) { | ||
this.#file = path.resolve(ctx.workspace.path, ctx.build.toolFolder, `${name}.pid`); | ||
this.#file = CommonUtil.resolveWorkspace(ctx, ctx.build.toolFolder, `${name}.pid`); | ||
this.#log = Log.scoped(`process-handle.${name}`); | ||
@@ -55,4 +55,8 @@ } | ||
const pid = await this.getPid(); | ||
if (!pid) { | ||
return false; | ||
} | ||
this.#log.debug('Ensuring Killed', pid); | ||
while (pid && (Date.now() - start) < gracePeriod) { // Ensure its done | ||
while ((Date.now() - start) < gracePeriod) { // Ensure its done | ||
if (!await this.isRunning()) { | ||
@@ -65,7 +69,7 @@ return true; | ||
this.#log.debug('Force Killing', pid); | ||
pid && process.kill(pid); // Force kill | ||
process.kill(pid); // Force kill | ||
} catch { } | ||
this.#log.debug('Did Kill', this.#file, !!pid); | ||
return pid !== undefined; | ||
return true; | ||
} | ||
} |
import cp from 'node:child_process'; | ||
import path from 'node:path'; | ||
import { rmSync } from 'node:fs'; | ||
@@ -38,4 +37,4 @@ | ||
const main = path.resolve(ctx.workspace.path, ctx.build.compilerFolder, 'node_modules', '@travetto/compiler/support/entry.compiler.js'); | ||
const deltaFile = path.resolve(ctx.workspace.path, ctx.build.compilerFolder, `manifest-delta-${Date.now()}.json`); | ||
const main = CommonUtil.resolveWorkspace(ctx, ctx.build.compilerFolder, 'node_modules', '@travetto/compiler/support/entry.compiler.js'); | ||
const deltaFile = CommonUtil.resolveWorkspace(ctx, ctx.build.compilerFolder, `manifest-delta-${Date.now()}.json`); | ||
@@ -53,3 +52,3 @@ const changedFiles = changed[0]?.file === '*' ? ['*'] : changed.map(ev => ev.sourceFile); | ||
...process.env, | ||
TRV_MANIFEST: path.resolve(ctx.workspace.path, ctx.build.outputFolder, 'node_modules', ctx.workspace.name), | ||
TRV_MANIFEST: CommonUtil.resolveWorkspace(ctx, ctx.build.outputFolder, 'node_modules', ctx.workspace.name), | ||
}, | ||
@@ -56,0 +55,0 @@ detached: true, |
import http from 'node:http'; | ||
import fs from 'node:fs/promises'; | ||
import path from 'node:path'; | ||
import { setMaxListeners } from 'node:events'; | ||
@@ -23,3 +22,4 @@ | ||
#server: http.Server; | ||
#listeners: Record<string, { res: http.ServerResponse, type: CompilerEventType }> = {}; | ||
#listenersAll = new Set<http.ServerResponse>(); | ||
#listeners: Partial<Record<CompilerEventType | 'all', Record<string, http.ServerResponse>>> = {}; | ||
#shutdown = new AbortController(); | ||
@@ -99,23 +99,41 @@ signal = this.#shutdown.signal; | ||
async #addListener(type: string, res: http.ServerResponse): Promise<void> { | ||
#addListener(type: CompilerEventType | 'all', res: http.ServerResponse): void { | ||
res.writeHead(200); | ||
const id = `id_${Date.now()}_${Math.random()}`.replace('.', '1'); | ||
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions | ||
this.#listeners[id] = { res, type: type as 'change' }; | ||
if (type === 'state') { // Send on initial connect | ||
res.write(JSON.stringify({ state: this.info.state })); | ||
(this.#listeners[type] ??= {})[id] = res; | ||
this.#listenersAll.add(res); | ||
if (type === 'state' || type === 'all') { // Send on initial connect | ||
this.#emitEvent({ type: 'state', payload: { state: this.info.state } }, id); | ||
} else { | ||
res.write('\n'); // Send at least one byte on listen | ||
} | ||
res.write('\n'); // Send at least one byte on listen | ||
// Do not wait on it | ||
res.on('close', () => { delete this.#listeners[id]; }); | ||
res.on('close', () => { | ||
delete this.#listeners[type]?.[id]; | ||
this.#listenersAll.delete(res); | ||
}); | ||
} | ||
#emitEvent(ev: CompilerEvent): void { | ||
const msg = `${JSON.stringify(ev.payload)}\n`; | ||
for (const el of Object.values(this.#listeners)) { | ||
if (!el.res.closed && el.type === ev.type) { | ||
el.res.write(msg); | ||
#emitEvent(ev: CompilerEvent, to?: string): void { | ||
if (this.#listeners.all) { | ||
const msg = JSON.stringify(ev); | ||
for (const [id, item] of Object.entries(this.#listeners.all)) { | ||
if (item.closed || (to && id !== to)) { | ||
continue; | ||
} | ||
item.write(msg); | ||
item.write('\n'); | ||
} | ||
} | ||
if (this.#listeners[ev.type]) { | ||
const msg = JSON.stringify(ev.payload); | ||
for (const [id, item] of Object.entries(this.#listeners[ev.type]!)) { | ||
if (item.closed || (to && id !== to)) { | ||
continue; | ||
} | ||
item.write(msg); | ||
item.write('\n'); | ||
} | ||
} | ||
} | ||
@@ -127,6 +145,7 @@ | ||
await CommonUtil.blockingTimeout(20); | ||
for (const el of Object.values(this.#listeners)) { | ||
try { el.res.end(); } catch { } | ||
for (const el of this.#listenersAll) { | ||
try { el.end(); } catch { } | ||
} | ||
this.#listeners = {}; // Ensure its empty | ||
this.#listenersAll.clear(); | ||
} | ||
@@ -136,3 +155,3 @@ | ||
await Promise.all([this.#ctx.build.compilerFolder, this.#ctx.build.outputFolder] | ||
.map(f => fs.rm(path.resolve(this.#ctx.workspace.path, f), { recursive: true, force: true }))); | ||
.map(f => fs.rm(CommonUtil.resolveWorkspace(this.#ctx, f), { recursive: true, force: true }))); | ||
return { clean: true }; | ||
@@ -152,3 +171,4 @@ } | ||
switch (action) { | ||
case 'event': return await this.#addListener(subAction, res); | ||
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions | ||
case 'event': return this.#addListener(subAction as 'change', res); | ||
case 'clean': out = await this.#clean(); break; | ||
@@ -155,0 +175,0 @@ case 'stop': out = JSON.stringify({ closing: true }); close = true; break; |
@@ -1,4 +0,4 @@ | ||
import path from 'node:path'; | ||
import { createRequire } from 'node:module'; | ||
import fs from 'node:fs/promises'; | ||
import path from 'node:path'; | ||
@@ -30,3 +30,3 @@ import { type DeltaEvent, type ManifestContext, type Package } from '@travetto/manifest'; | ||
const all = ['util', 'delta'].map(f => | ||
import(path.resolve(ctx.workspace.path, ctx.build.compilerFolder, 'node_modules', `@travetto/manifest/src/${f}.js`)) | ||
import(CommonUtil.resolveWorkspace(ctx, ctx.build.compilerFolder, 'node_modules', `@travetto/manifest/src/${f}.js`)) | ||
); | ||
@@ -54,7 +54,7 @@ return Promise.all(all).then(props => Object.assign({}, ...props)); | ||
if (type === 'js' || type === 'ts') { | ||
const compilerOut = path.resolve(ctx.workspace.path, ctx.build.compilerFolder, 'node_modules'); | ||
const compilerOut = CommonUtil.resolveWorkspace(ctx, ctx.build.compilerFolder, 'node_modules'); | ||
const text = (await fs.readFile(inputFile, 'utf8')) | ||
.replace(/from '([.][^']+)'/g, (_, i) => `from '${i.replace(/[.]js$/, '')}.js'`) | ||
.replace(/from '(@travetto\/(.*?))'/g, (_, i, s) => `from '${path.resolve(compilerOut, `${i}${s.includes('/') ? '.js' : '/__index__.js'}`)}'`); | ||
.replace(/from '(@travetto\/(.*?))'/g, (_, i, s) => `from '${compilerOut}/${i}${s.includes('/') ? '.js' : '/__index__.js'}'`); | ||
@@ -97,3 +97,3 @@ const ts = (await import('typescript')).default; | ||
} | ||
const resolvedInput = path.resolve(sub, file); | ||
const resolvedInput = path.resolve(sub, file).replaceAll('\\', '/'); // To posix | ||
const stat = await fs.stat(resolvedInput); | ||
@@ -111,3 +111,3 @@ | ||
const outputFolder = path.resolve(ctx.workspace.path, ctx.build.compilerFolder, 'node_modules', module); | ||
const outputFolder = CommonUtil.resolveWorkspace(ctx, ctx.build.compilerFolder, 'node_modules', module); | ||
const out: ModFile[] = []; | ||
@@ -119,3 +119,3 @@ for (const input of files) { | ||
const outputTs = await fs.stat(output).then(RECENT_STAT, () => 0); | ||
await fs.mkdir(path.dirname(output), { recursive: true, }); | ||
await fs.mkdir(path.dirname(output), { recursive: true }); | ||
out.push({ input, output, stale: inputTs > outputTs }); | ||
@@ -210,3 +210,3 @@ } | ||
await Log.wrap('reset', async log => { | ||
await fs.rm(path.resolve(ctx.workspace.path, ctx.build.outputFolder), { recursive: true, force: true }); | ||
await fs.rm(CommonUtil.resolveWorkspace(ctx, ctx.build.outputFolder), { recursive: true, force: true }); | ||
log.info('Clearing output due to compiler changes'); | ||
@@ -213,0 +213,0 @@ }, false); |
import fs from 'node:fs/promises'; | ||
import path from 'node:path'; | ||
import { ManifestContext } from '@travetto/manifest'; | ||
import { type ManifestContext } from '@travetto/manifest'; | ||
import { CommonUtil } from './util'; | ||
@@ -14,6 +14,6 @@ const OPT_CACHE: Record<string, import('typescript').CompilerOptions> = {}; | ||
if (!(ctx.workspace.path in OPT_CACHE)) { | ||
let tsconfig = path.resolve(ctx.workspace.path, 'tsconfig.json'); | ||
let tsconfig = CommonUtil.resolveWorkspace(ctx, 'tsconfig.json'); | ||
if (!await fs.stat(tsconfig).then(_ => true, _ => false)) { | ||
tsconfig = path.resolve(ctx.workspace.path, ctx.build.compilerModuleFolder, 'tsconfig.trv.json'); | ||
tsconfig = CommonUtil.resolveWorkspace(ctx, ctx.build.compilerModuleFolder, 'tsconfig.trv.json'); | ||
} | ||
@@ -33,3 +33,3 @@ | ||
rootDir: ctx.workspace.path, | ||
outDir: path.resolve(ctx.workspace.path), | ||
outDir: CommonUtil.resolveWorkspace(ctx), | ||
module: ctx.workspace.type === 'commonjs' ? ts.ModuleKind.CommonJS : ts.ModuleKind.ESNext, | ||
@@ -36,0 +36,0 @@ }; |
import fs from 'node:fs/promises'; | ||
import path from 'node:path'; | ||
import { setMaxListeners } from 'node:events'; | ||
import timers from 'node:timers/promises'; | ||
import posix from 'node:path/posix'; | ||
import native from 'node:path'; | ||
import { type ManifestContext } from '@travetto/manifest'; | ||
import { Log } from './log'; | ||
const toPosix = (file: string): string => file.replaceAll('\\', '/'); | ||
export class CommonUtil { | ||
@@ -22,3 +27,3 @@ /** | ||
static writeTextFile = (file: string, content: string): Promise<void> => | ||
fs.mkdir(path.dirname(file), { recursive: true }).then(() => fs.writeFile(file, content, 'utf8')); | ||
fs.mkdir(native.dirname(file), { recursive: true }).then(() => fs.writeFile(file, content, 'utf8')); | ||
@@ -96,2 +101,10 @@ /** | ||
} | ||
/** | ||
* Resolve path for workspace, ensuring posix compliant slashes | ||
*/ | ||
static resolveWorkspace(ctx: ManifestContext, ...args: string[]): string { | ||
const all = [process.cwd(), ctx.workspace.path, ...args].map(toPosix); | ||
return process.platform === 'win32' ? toPosix(native.resolve(...all)) : posix.resolve(...all); | ||
} | ||
} |
@@ -7,3 +7,3 @@ { | ||
"lib": [ | ||
"es2022" | ||
"ES2023" | ||
], | ||
@@ -10,0 +10,0 @@ "jsx": "react-jsx", |
No v1
QualityPackage is not semver >=1. This means it is not stable and does not support ^ ranges.
Found 1 instance in 1 package
85612
1891
1
+ Added@travetto/cli@5.1.0(transitive)
+ Added@travetto/manifest@5.1.0(transitive)
+ Added@travetto/registry@5.1.0(transitive)
+ Added@travetto/runtime@5.1.0(transitive)
+ Added@travetto/schema@5.1.0(transitive)
+ Added@travetto/terminal@5.1.0(transitive)
+ Added@travetto/transformer@5.1.0(transitive)
+ Added@types/node@22.13.8(transitive)
+ Addedundici-types@6.20.0(transitive)
- Removed@travetto/base@4.1.2(transitive)
- Removed@travetto/cli@4.1.2(transitive)
- Removed@travetto/manifest@4.1.0(transitive)
- Removed@travetto/registry@4.1.2(transitive)
- Removed@travetto/schema@4.1.1(transitive)
- Removed@travetto/terminal@4.1.1(transitive)
- Removed@travetto/transformer@4.1.2(transitive)
Updated@types/node@^20.14.10