@travetto/compiler
Advanced tools
Comparing version 4.0.0-rc.5 to 4.0.0-rc.6
{ | ||
"name": "@travetto/compiler", | ||
"version": "4.0.0-rc.5", | ||
"version": "4.0.0-rc.6", | ||
"description": "The compiler infrastructure for the Travetto framework", | ||
@@ -34,8 +34,8 @@ "keywords": [ | ||
"@parcel/watcher": "^2.4.0", | ||
"@travetto/manifest": "^4.0.0-rc.5", | ||
"@travetto/transformer": "^4.0.0-rc.5", | ||
"@travetto/manifest": "^4.0.0-rc.6", | ||
"@travetto/transformer": "^4.0.0-rc.6", | ||
"@types/node": "^20.11.16" | ||
}, | ||
"peerDependencies": { | ||
"@travetto/cli": "^4.0.0-rc.6" | ||
"@travetto/cli": "^4.0.0-rc.7" | ||
}, | ||
@@ -42,0 +42,0 @@ "peerDependenciesMeta": { |
@@ -1,2 +0,1 @@ | ||
import ts from 'typescript'; | ||
import timers from 'node:timers/promises'; | ||
@@ -12,3 +11,3 @@ import fs from 'node:fs/promises'; | ||
import { Log } from './log'; | ||
import { CompileEmitError, CompileEmitEvent, CompileEmitter } from './types'; | ||
import { CompileEmitEvent, CompileEmitter } from './types'; | ||
import { EventUtil } from './event'; | ||
@@ -90,25 +89,4 @@ | ||
*/ | ||
async getCompiler(): Promise<CompileEmitter> { | ||
let program: ts.Program; | ||
const emit = async (inputFile: string, needsNewProgram = program === undefined): Promise<CompileEmitError | undefined> => { | ||
try { | ||
if (needsNewProgram) { | ||
program = this.#state.createProgram(program); | ||
} | ||
await timers.setImmediate(); | ||
const result = this.#state.writeInputFile(program, inputFile); | ||
if (result?.diagnostics?.length) { | ||
return result.diagnostics; | ||
} | ||
} catch (err) { | ||
if (err instanceof Error) { | ||
return err; | ||
} else { | ||
throw err; | ||
} | ||
} | ||
}; | ||
return emit; | ||
getCompiler(): CompileEmitter { | ||
return (inputFile: string, needsNewProgram?: boolean) => this.#state.writeInputFile(inputFile, needsNewProgram); | ||
} | ||
@@ -115,0 +93,0 @@ |
import ts from 'typescript'; | ||
import timers from 'node:timers/promises'; | ||
@@ -9,3 +10,3 @@ import { path, ManifestModuleUtil, ManifestModule, ManifestRoot, ManifestIndex } from '@travetto/manifest'; | ||
import { CompilerUtil } from './util'; | ||
import { CompileStateEntry } from './types'; | ||
import { CompileEmitError, CompileStateEntry } from './types'; | ||
@@ -48,2 +49,3 @@ function folderMapper(root: string, prefix: string): { dir: string, translate: (val: string) => string } { | ||
#compilerOptions: ts.CompilerOptions; | ||
#program: ts.Program; | ||
@@ -109,20 +111,36 @@ #readFile(inputFile: string): string | undefined { | ||
createProgram(oldProgram?: ts.Program): ts.Program { | ||
const prog = ts.createProgram({ rootNames: this.getAllFiles(), host: this, options: this.#compilerOptions, oldProgram }); | ||
this.#transformerManager.init(prog.getTypeChecker()); | ||
return prog; | ||
async createProgram(force = false): Promise<ts.Program> { | ||
if (force || !this.#program) { | ||
this.#program = ts.createProgram({ rootNames: this.getAllFiles(), host: this, options: this.#compilerOptions, oldProgram: this.#program }); | ||
this.#transformerManager.init(this.#program.getTypeChecker()); | ||
await timers.setImmediate(); | ||
} | ||
return this.#program; | ||
} | ||
writeInputFile(program: ts.Program, inputFile: string): ts.EmitResult | undefined | void { | ||
switch (ManifestModuleUtil.getFileType(inputFile)) { | ||
case 'package-json': | ||
return this.writeFile(this.#inputToEntry.get(inputFile)!.outputFile!, this.readFile(inputFile)!, false); | ||
case 'js': | ||
return this.writeFile(this.#inputToEntry.get(inputFile)!.outputFile!, ts.transpile(this.readFile(inputFile)!, this.#compilerOptions), false); | ||
case 'ts': | ||
return program.emit( | ||
program.getSourceFile(inputFile)!, | ||
(...args) => this.writeFile(...args), undefined, false, | ||
this.#transformerManager.get() | ||
); | ||
async writeInputFile(inputFile: string, needsNewProgram = false): Promise<CompileEmitError | undefined> { | ||
const program = await this.createProgram(needsNewProgram); | ||
try { | ||
switch (ManifestModuleUtil.getFileType(inputFile)) { | ||
case 'package-json': | ||
this.writeFile(this.#inputToEntry.get(inputFile)!.outputFile!, this.readFile(inputFile)!, false), undefined; | ||
break; | ||
case 'js': | ||
this.writeFile(this.#inputToEntry.get(inputFile)!.outputFile!, ts.transpile(this.readFile(inputFile)!, this.#compilerOptions), false); | ||
break; | ||
case 'ts': { | ||
const result = program.emit( | ||
program.getSourceFile(inputFile)!, | ||
(...args) => this.writeFile(...args), undefined, false, | ||
this.#transformerManager.get() | ||
); | ||
return result?.diagnostics?.length ? result.diagnostics : undefined; | ||
} | ||
} | ||
} catch (err) { | ||
if (err instanceof Error) { | ||
return err; | ||
} else { | ||
throw err; | ||
} | ||
} | ||
@@ -129,0 +147,0 @@ } |
@@ -8,3 +8,3 @@ // @trv-no-transform | ||
import type { CompilerLogLevel, CompilerMode, CompilerServerInfo } from './types'; | ||
import { LogUtil } from './log'; | ||
import { CompilerLogger } from './log'; | ||
import { CommonUtil } from './util'; | ||
@@ -18,4 +18,3 @@ import { CompilerSetup } from './setup'; | ||
export const main = (ctx: ManifestContext) => { | ||
const log = LogUtil.logger('client.main'); | ||
const client = new CompilerClient(ctx, log); | ||
const client = new CompilerClient(ctx, new CompilerLogger('client')); | ||
const buildFolders = [ctx.build.outputFolder, ctx.build.compilerFolder]; | ||
@@ -25,9 +24,10 @@ | ||
const compile = async (op: CompilerMode, logLevel: CompilerLogLevel, setupOnly = false): Promise<void> => { | ||
LogUtil.initLogs(ctx, logLevel ?? 'info'); | ||
CompilerLogger.init(ctx, logLevel ?? 'info'); | ||
const server = await new CompilerServer(ctx, op).listen(); | ||
const log = new CompilerLogger('main'); | ||
// Wait for build to be ready | ||
if (server) { | ||
log('debug', 'Start Server'); | ||
log.debug('Start Server'); | ||
await server.processEvents(async function* (signal) { | ||
@@ -39,11 +39,10 @@ const changed = await CompilerSetup.setup(ctx); | ||
}); | ||
log('debug', 'End Server'); | ||
log.debug('End Server'); | ||
} else { | ||
log('info', 'Server already running, waiting for initial compile to complete'); | ||
log.info('Server already running, waiting for initial compile to complete'); | ||
const ctrl = new AbortController(); | ||
LogUtil.consumeProgressEvents(() => client.fetchEvents('progress', { until: ev => !!ev.complete, signal: ctrl.signal })); | ||
log.consumeProgressEvents(() => client.fetchEvents('progress', { until: ev => !!ev.complete, signal: ctrl.signal })); | ||
await client.waitForState(['compile-end', 'watch-start'], 'Successfully built'); | ||
ctrl.abort(); | ||
} | ||
LogUtil.cleanup(); | ||
}; | ||
@@ -54,3 +53,3 @@ | ||
async stop(): Promise<void> { | ||
LogUtil.initLogs(ctx); | ||
CompilerLogger.init(ctx); | ||
if (await client.stop()) { | ||
@@ -71,3 +70,3 @@ console.log(`Stopped server ${ctx.workspace.path}: ${client}`); | ||
async clean(): Promise<void> { | ||
LogUtil.initLogs(ctx); | ||
CompilerLogger.init(ctx); | ||
if (await client.clean()) { | ||
@@ -83,3 +82,3 @@ return console.log(`Clean triggered ${ctx.workspace.path}:`, buildFolders); | ||
events: async (type: string, handler: (ev: unknown) => unknown): Promise<void> => { | ||
LogUtil.initLogs(ctx, 'error'); | ||
CompilerLogger.init(ctx, 'error'); | ||
if (type === 'change' || type === 'log' || type === 'progress' || type === 'state') { | ||
@@ -102,3 +101,3 @@ for await (const ev of client.fetchEvents(type)) { await handler(ev); } | ||
if (!(await client.isWatching())) { | ||
await compile('build', LogUtil.isInteractiveShell ? 'info' : 'error'); | ||
await compile('build', 'error'); | ||
} | ||
@@ -105,0 +104,0 @@ return CommonUtil.moduleLoader(ctx); |
import type { ManifestContext } from '@travetto/manifest'; | ||
import type { CompilerLogEvent, CompilerLogLevel, CompilerProgressEvent } from './types'; | ||
export type CompilerLogger = (level: CompilerLogLevel, message: string, ...args: unknown[]) => void; | ||
export type WithLogger<T> = (log: CompilerLogger) => Promise<T>; | ||
type ProgressWriter = (ev: CompilerProgressEvent) => (unknown | Promise<unknown>); | ||
const LEVEL_TO_PRI: Record<CompilerLogLevel, number> = { debug: 1, info: 2, warn: 3, error: 4 }; | ||
const SCOPE_MAX = 15; | ||
const ESC = '\x1b['; | ||
export class LogUtil { | ||
export class CompilerLogger { | ||
static root = process.cwd(); | ||
static #root = process.cwd(); | ||
static #logLevel: CompilerLogLevel = 'error'; | ||
static #linePartial: boolean | undefined; | ||
static logLevel: CompilerLogLevel = 'error'; | ||
static logProgress = false; | ||
static logProgress?: ProgressWriter; | ||
static linePartial = false; | ||
static #rewriteLine(text: string): Promise<void> | void { | ||
/** Rewrite text line, tracking cleanup as necessary */ | ||
static rewriteLine(text: string): Promise<void> | void { | ||
if ((!text && !this.#linePartial) || !process.stdout.isTTY) { | ||
return; | ||
} | ||
if (this.#linePartial === undefined) { // First time | ||
process.stdout.write(`${ESC}?25l`); // Hide cursor | ||
process.on('exit', () => this.reset()); | ||
} | ||
// Move to 1st position, and clear after text | ||
const done = process.stdout.write(`${ESC}1G${text}${ESC}0K`); | ||
this.linePartial = !!text; | ||
this.#linePartial = !!text; | ||
if (!done) { | ||
@@ -42,77 +41,68 @@ return new Promise<void>(r => process.stdout.once('drain', r)); | ||
*/ | ||
static initLogs(ctx: ManifestContext, defaultLevel?: CompilerLogLevel): void { | ||
static init(ctx: ManifestContext, defaultLevel?: CompilerLogLevel): void { | ||
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions | ||
const build = process.env.TRV_BUILD as CompilerLogLevel | 'none'; | ||
if (build !== 'none' && process.env.TRV_QUIET !== 'true') { | ||
this.logLevel = build || defaultLevel; | ||
this.#logLevel = build || defaultLevel; | ||
this.logProgress = this.isInteractiveShell; | ||
} | ||
this.root = ctx.workspace.path; | ||
// If we are in info or a terminal and also in a tty | ||
this.logProgress = (this.isLevelActive('info') && process.stdout.isTTY) ? this.#logProgressEvent : undefined; | ||
if (this.logProgress) { | ||
process.stdout.write(`${ESC}?25l`); // Hide cursor | ||
} | ||
process.on('exit', () => this.cleanup()); | ||
this.#root = ctx.workspace.path; | ||
} | ||
static cleanup(): void { | ||
if (this.logProgress) { | ||
process.stdout.write(`${ESC}!p`); // Reset | ||
/** Cleanup to restore behavior */ | ||
static reset(): void { | ||
if (process.stdout.isTTY) { | ||
process.stdout.write(`${ESC}!p${ESC}?25h`); | ||
} | ||
} | ||
static #logProgressEvent(ev: CompilerProgressEvent): Promise<void> | void { | ||
const pct = Math.trunc(ev.idx * 100 / ev.total); | ||
const text = ev.complete ? '' : `Compiling [${'#'.repeat(Math.trunc(pct / 10)).padEnd(10, ' ')}] [${ev.idx}/${ev.total}] ${ev.message}`; | ||
return this.#rewriteLine(text); | ||
} | ||
constructor( | ||
private scope: string, | ||
private level?: CompilerLogLevel, | ||
private logProgress?: boolean, | ||
private root = CompilerLogger.#root, | ||
) { } | ||
/** | ||
* Is the log level active? | ||
*/ | ||
static isLevelActive(lvl: CompilerLogLevel): boolean { | ||
return LEVEL_TO_PRI[this.logLevel] <= LEVEL_TO_PRI[lvl]; | ||
isActive(level: CompilerLogLevel): boolean { | ||
return LEVEL_TO_PRI[this.level ?? CompilerLogger.#logLevel] <= LEVEL_TO_PRI[level]; | ||
} | ||
/** | ||
* Log event with filtering by level | ||
*/ | ||
static logEvent(ev: CompilerLogEvent): void { | ||
if (this.isLevelActive(ev.level)) { | ||
const params = [ev.message, ...ev.args ?? []].map(x => typeof x === 'string' ? x.replaceAll(this.root, '.') : x); | ||
if (ev.scope) { | ||
params.unshift(`[${ev.scope.padEnd(SCOPE_MAX, ' ')}]`); | ||
} | ||
params.unshift(new Date().toISOString(), `${ev.level.padEnd(5)}`); | ||
if (this.linePartial) { | ||
this.#rewriteLine(''); // Clear out progress line | ||
} | ||
// eslint-disable-next-line no-console | ||
console[ev.level]!(...params); | ||
/** Log event with filtering by level */ | ||
onLogEvent(ev: CompilerLogEvent): void { | ||
if (!this.isActive(ev.level)) { return; } | ||
const params = [ev.message, ...ev.args ?? []].map(x => typeof x === 'string' ? x.replaceAll(this.root, '.') : x); | ||
if (ev.scope) { | ||
params.unshift(`[${ev.scope.padEnd(SCOPE_MAX, ' ')}]`); | ||
} | ||
params.unshift(new Date().toISOString(), `${ev.level.padEnd(5)}`); | ||
CompilerLogger.rewriteLine(''); // Clear out progress line, if active | ||
// eslint-disable-next-line no-console | ||
console[ev.level]!(...params); | ||
} | ||
/** | ||
* With logger | ||
*/ | ||
static withLogger<T>(scope: string, op: WithLogger<T>, basic = true): Promise<T> { | ||
const log = this.logger(scope); | ||
basic && log('debug', 'Started'); | ||
return op(log).finally(() => basic && log('debug', 'Completed')); | ||
/** Write progress event, if active */ | ||
onProgressEvent(ev: CompilerProgressEvent): void | Promise<void> { | ||
if (!(this.logProgress ?? CompilerLogger.logProgress)) { return; } | ||
const pct = Math.trunc(ev.idx * 100 / ev.total); | ||
const text = ev.complete ? '' : `Compiling [${'#'.repeat(Math.trunc(pct / 10)).padEnd(10, ' ')}] [${ev.idx}/${ev.total}] ${ev.message}`; | ||
return CompilerLogger.rewriteLine(text); | ||
} | ||
/** | ||
* With scope | ||
*/ | ||
static logger(scope: string): CompilerLogger { | ||
return (level, message, ...args) => this.logEvent({ scope, message, level, args, time: Date.now() }); | ||
/** Write all progress events if active */ | ||
async consumeProgressEvents(src: () => AsyncIterable<CompilerProgressEvent>): Promise<void> { | ||
if (!(this.logProgress ?? CompilerLogger.logProgress)) { return; } | ||
for await (const ev of src()) { this.onProgressEvent(ev); } | ||
await CompilerLogger.reset(); | ||
} | ||
/** | ||
* Write all progress events if active | ||
*/ | ||
static async consumeProgressEvents(src: () => AsyncIterable<CompilerProgressEvent>): Promise<void> { | ||
if (!this.logProgress) { return; } | ||
for await (const item of src()) { await this.logProgress?.(item); } | ||
log(level: CompilerLogLevel, message: string, args: unknown[]): void { | ||
this.onLogEvent({ scope: this.scope, message, level, args, time: Date.now() }); | ||
} | ||
info(message: string, ...args: unknown[]): void { return this.log('info', message, args); } | ||
debug(message: string, ...args: unknown[]): void { return this.log('debug', message, args); } | ||
warn(message: string, ...args: unknown[]): void { return this.log('warn', message, args); } | ||
error(message: string, ...args: unknown[]): void { return this.log('error', message, args); } | ||
wrap<T = unknown>(op: (log: typeof this) => Promise<T>, basic = false): Promise<T> { | ||
return basic ? (this.debug('Started'), op(this).finally(() => this.debug('Completed'))) : op(this); | ||
} | ||
} |
@@ -17,2 +17,4 @@ import rl from 'node:readline/promises'; | ||
type SimpleLogger = Pick<CompilerLogger, 'error' | 'info' | 'debug'>; | ||
/** | ||
@@ -24,6 +26,6 @@ * Compiler Client Operations | ||
#url: string; | ||
#log: CompilerLogger; | ||
#log: SimpleLogger; | ||
#handle: Record<'compiler' | 'server', ProcessHandle>; | ||
constructor(ctx: ManifestContext, log: CompilerLogger) { | ||
constructor(ctx: ManifestContext, log: SimpleLogger) { | ||
this.#url = ctx.build.compilerUrl.replace('localhost', '127.0.0.1'); | ||
@@ -46,3 +48,3 @@ this.#log = log; | ||
const timeoutId = setTimeout(() => { | ||
logTimeout && this.#log('error', `Timeout on request to ${this.#url}${rel}`); | ||
logTimeout && this.#log.error(`Timeout on request to ${this.#url}${rel}`); | ||
ctrl.abort('TIMEOUT'); | ||
@@ -77,3 +79,3 @@ }, opts?.timeout ?? 100).unref(); | ||
if (!info) { | ||
this.#log('debug', 'Stopping server, info not found, manual killing'); | ||
this.#log.debug('Stopping server, info not found, manual killing'); | ||
return Promise.all([this.#handle.server.kill(), this.#handle.compiler.kill()]) | ||
@@ -84,3 +86,3 @@ .then(v => v.some(x => x)); | ||
await this.#fetch('/stop').catch(() => { }); // Trigger | ||
this.#log('debug', 'Waiting for compiler to exit'); | ||
this.#log.debug('Waiting for compiler to exit'); | ||
await this.#handle.compiler.ensureKilled(); | ||
@@ -100,3 +102,3 @@ return true; | ||
this.#log('debug', `Starting watch for events of type "${type}"`); | ||
this.#log.debug(`Starting watch for events of type "${type}"`); | ||
@@ -141,3 +143,3 @@ let signal = cfg.signal; | ||
if (ctrl.signal.reason === 'TIMEOUT') { | ||
this.#log('debug', 'Failed due to timeout'); | ||
this.#log.debug('Failed due to timeout'); | ||
return; | ||
@@ -147,6 +149,6 @@ } | ||
if (ctrl.signal.aborted || !info || (cfg.enforceIteration && info.iteration !== iteration)) { // If health check fails, or aborted | ||
this.#log('debug', `Stopping watch for events of type "${type}"`); | ||
this.#log.debug(`Stopping watch for events of type "${type}"`); | ||
return; | ||
} else { | ||
this.#log('debug', `Restarting watch for events of type "${type}"`); | ||
this.#log.debug(`Restarting watch for events of type "${type}"`); | ||
} | ||
@@ -160,9 +162,9 @@ } | ||
// Loop until | ||
this.#log('debug', `Waiting for states, ${states.join(', ')}`); | ||
this.#log.debug(`Waiting for states, ${states.join(', ')}`); | ||
for await (const _ of this.fetchEvents('state', { signal, until: s => set.has(s.state) })) { } | ||
this.#log('debug', `Found state, one of ${states.join(', ')} `); | ||
this.#log.debug(`Found state, one of ${states.join(', ')} `); | ||
if (message) { | ||
this.#log('info', message); | ||
this.#log.info(message); | ||
} | ||
} | ||
} |
@@ -6,3 +6,3 @@ import fs from 'node:fs/promises'; | ||
import type { ManifestContext } from '@travetto/manifest'; | ||
import { CompilerLogger, LogUtil } from '../log'; | ||
import { CompilerLogger } from '../log'; | ||
@@ -16,3 +16,3 @@ export class ProcessHandle { | ||
this.#file = path.resolve(ctx.workspace.path, ctx.build.toolFolder, `${name}.pid`); | ||
this.#log = LogUtil.logger(`process-handle.${name}`); | ||
this.#log = new CompilerLogger(`process-handle.${name}`); | ||
} | ||
@@ -34,6 +34,6 @@ | ||
process.kill(pid, 0); // See if process is still running | ||
this.#log('debug', 'Is running', pid); | ||
this.#log.debug('Is running', pid); | ||
return true; | ||
} catch { | ||
this.#log('debug', 'Is not running', pid); | ||
this.#log.debug('Is not running', pid); | ||
} | ||
@@ -47,3 +47,3 @@ return false; // Not running | ||
try { | ||
this.#log('debug', 'Killing', pid); | ||
this.#log.debug('Killing', pid); | ||
return process.kill(pid); | ||
@@ -58,3 +58,3 @@ } catch { } | ||
const pid = await this.getPid(); | ||
this.#log('debug', 'Ensuring Killed', pid); | ||
this.#log.debug('Ensuring Killed', pid); | ||
while (pid && (Date.now() - start) < gracePeriod) { // Ensure its done | ||
@@ -67,8 +67,8 @@ if (!await this.isRunning()) { | ||
try { | ||
this.#log('debug', 'Force Killing', pid); | ||
this.#log.debug('Force Killing', pid); | ||
pid && process.kill(pid); // Force kill | ||
} catch { } | ||
this.#log('debug', 'Did Kill', this.#file, !!pid); | ||
this.#log.debug('Did Kill', this.#file, !!pid); | ||
return pid !== undefined; | ||
} | ||
} |
@@ -9,6 +9,6 @@ import cp from 'node:child_process'; | ||
import { AsyncQueue } from '../queue'; | ||
import { LogUtil } from '../log'; | ||
import { CompilerLogger } from '../log'; | ||
import { CommonUtil } from '../util'; | ||
const log = LogUtil.logger('compiler-exec'); | ||
const log = new CompilerLogger('compiler-exec'); | ||
const isEvent = (msg: unknown): msg is CompilerEvent => !!msg && typeof msg === 'object' && 'type' in msg; | ||
@@ -26,3 +26,3 @@ | ||
if (signal.aborted) { | ||
log('debug', 'Skipping, shutting down'); | ||
log.debug('Skipping, shutting down'); | ||
return; | ||
@@ -34,6 +34,6 @@ } | ||
yield { type: 'state', payload: { state: 'compile-end' } }; | ||
log('debug', 'Skipped'); | ||
log.debug('Skipped'); | ||
return; | ||
} else { | ||
log('debug', `Started watch=${watch} changed=${changed.slice(0, 10).map(x => `${x.module}/${x.file}`)}`); | ||
log.debug(`Started watch=${watch} changed=${changed.slice(0, 10).map(x => `${x.module}/${x.file}`)}`); | ||
} | ||
@@ -51,3 +51,3 @@ | ||
log('info', 'Launching compiler'); | ||
log.info('Launching compiler'); | ||
const proc = cp.spawn(process.argv0, [main, deltaFile, `${watch}`], { | ||
@@ -65,3 +65,3 @@ env: { | ||
const kill = (): unknown => { | ||
log('debug', 'Shutting down process'); | ||
log.debug('Shutting down process'); | ||
return (proc.connected ? proc.send('shutdown', (err) => proc.kill()) : proc.kill()); | ||
@@ -76,7 +76,7 @@ }; | ||
if (proc.exitCode !== 0) { | ||
log('error', `Terminated during compilation, code=${proc.exitCode}, killed=${proc.killed}`); | ||
log.error(`Terminated during compilation, code=${proc.exitCode}, killed=${proc.killed}`); | ||
} | ||
process.off('SIGINT', kill); | ||
log('debug', 'Finished'); | ||
log.debug('Finished'); | ||
} finally { | ||
@@ -83,0 +83,0 @@ rmSync(deltaFile, { force: true }); |
@@ -9,3 +9,3 @@ import http from 'node:http'; | ||
import type { CompilerMode, CompilerProgressEvent, CompilerEvent, CompilerEventType, CompilerServerInfo } from '../types'; | ||
import { LogUtil } from '../log'; | ||
import { CompilerLogger } from '../log'; | ||
import { CommonUtil } from '../util'; | ||
@@ -15,3 +15,3 @@ import { CompilerClient } from './client'; | ||
const log = LogUtil.logger('compiler-server'); | ||
const log = new CompilerLogger('compiler-server'); | ||
@@ -35,3 +35,3 @@ /** | ||
this.#ctx = ctx; | ||
this.#client = new CompilerClient(ctx, LogUtil.logger('client.server')); | ||
this.#client = new CompilerClient(ctx, new CompilerLogger('client.server')); | ||
this.#url = this.#client.url; | ||
@@ -76,7 +76,7 @@ this.#handle = { server: new ProcessHandle(ctx, 'server'), compiler: new ProcessHandle(ctx, 'compiler') }; | ||
} else { | ||
log('warn', 'Failed in running server', err); | ||
log.warn('Failed in running server', err); | ||
reject(err); | ||
} | ||
}) | ||
.on('close', () => log('debug', 'Server close event')); | ||
.on('close', () => log.debug('Server close event')); | ||
@@ -91,3 +91,3 @@ const url = new URL(this.#url); | ||
} | ||
log('info', 'Waiting for build to finish, before retrying'); | ||
log.info('Waiting for build to finish, before retrying'); | ||
// Let the server finish | ||
@@ -127,3 +127,3 @@ await this.#client.waitForState(['close'], 'Server closed', this.signal); | ||
async #disconnectActive(): Promise<void> { | ||
log('info', 'Server disconnect requested'); | ||
log.info('Server disconnect requested'); | ||
this.info.iteration = Date.now(); | ||
@@ -151,4 +151,2 @@ await new Promise(r => setTimeout(r, 20)); | ||
log('debug', 'Receive request', { action, subAction }); | ||
let out: unknown; | ||
@@ -175,3 +173,3 @@ let close = false; | ||
if (ev.type === 'progress') { | ||
await LogUtil.logProgress?.(ev.payload); | ||
await log.onProgressEvent(ev.payload); | ||
} | ||
@@ -187,5 +185,5 @@ | ||
} | ||
log('info', `State changed: ${this.info.state}`); | ||
log.info(`State changed: ${this.info.state}`); | ||
} else if (ev.type === 'log') { | ||
LogUtil.logEvent(ev.payload); | ||
log.onLogEvent(ev.payload); | ||
} | ||
@@ -200,3 +198,3 @@ if (this.isResetEvent(ev)) { | ||
log('debug', 'Finished processing events'); | ||
log.debug('Finished processing events'); | ||
} | ||
@@ -208,3 +206,3 @@ | ||
async close(): Promise<void> { | ||
log('info', 'Closing down server'); | ||
log.info('Closing down server'); | ||
@@ -214,3 +212,3 @@ // If we are in a place where progress exists | ||
const cancel: CompilerProgressEvent = { complete: true, idx: 0, total: 0, message: 'Complete', operation: 'compile' }; | ||
LogUtil.logProgress?.(cancel); | ||
await log.onProgressEvent(cancel); | ||
this.#emitEvent({ type: 'progress', payload: cancel }); | ||
@@ -235,3 +233,3 @@ } | ||
log('info', 'Closed down server'); | ||
log.info('Closed down server'); | ||
} | ||
@@ -244,5 +242,5 @@ | ||
const running = await this.#tryListen() === 'ok'; | ||
log('info', running ? 'Starting server' : 'Server already running under a different process', this.#url); | ||
log.info(running ? 'Starting server' : 'Server already running under a different process', this.#url); | ||
return running ? this : undefined; | ||
} | ||
} |
@@ -7,3 +7,3 @@ import path from 'node:path'; | ||
import { LogUtil } from './log'; | ||
import { CompilerLogger } from './log'; | ||
import { CommonUtil } from './util'; | ||
@@ -132,5 +132,5 @@ | ||
try { | ||
await LogUtil.withLogger(scope, async log => { | ||
await new CompilerLogger(scope).wrap(async log => { | ||
if (files.some(f => f.stale)) { | ||
log('debug', 'Starting', mod); | ||
log.debug('Starting', mod); | ||
for (const file of files.filter(x => x.stale)) { | ||
@@ -141,7 +141,7 @@ await this.#transpileFile(ctx, file.input, file.output); | ||
out.push(...changes.map(x => `${mod}/${x}`)); | ||
log('debug', `Source changed: ${changes.join(', ')}`, mod); | ||
log.debug(`Source changed: ${changes.join(', ')}`, mod); | ||
} | ||
log('debug', 'Completed', mod); | ||
log.debug('Completed', mod); | ||
} else { | ||
log('debug', 'Skipped', mod); | ||
log.debug('Skipped', mod); | ||
} | ||
@@ -179,3 +179,3 @@ }, false); | ||
await LogUtil.withLogger('precompile', async () => { | ||
await new CompilerLogger('precompile').wrap(async () => { | ||
for (const mod of PRECOMPILE_MODS) { | ||
@@ -188,6 +188,6 @@ changes += (await this.#compileIfStale(ctx, 'precompile', mod, SOURCE_SEED)).length; | ||
const manifest = await LogUtil.withLogger('manifest', () => | ||
const manifest = await new CompilerLogger('manifest').wrap(() => | ||
ManifestUtil.buildManifest(ManifestUtil.getWorkspaceContext(ctx))); | ||
await LogUtil.withLogger('transformers', async () => { | ||
await new CompilerLogger('transformers').wrap(async () => { | ||
for (const mod of Object.values(manifest.modules).filter(m => m.files.$transformer?.length)) { | ||
@@ -198,5 +198,5 @@ changes += (await this.#compileIfStale(ctx, 'transformers', mod.name, ['package.json', ...mod.files.$transformer!.map(x => x[0])])).length; | ||
const delta = await LogUtil.withLogger('delta', async log => { | ||
const delta = await new CompilerLogger('delta').wrap(async log => { | ||
if (changes) { | ||
log('debug', 'Skipping, everything changed'); | ||
log.debug('Skipping, everything changed'); | ||
return [{ type: 'changed', file: '*', module: ctx.workspace.name, sourceFile: '' } as const]; | ||
@@ -209,5 +209,5 @@ } else { | ||
if (changes) { | ||
await LogUtil.withLogger('reset', async log => { | ||
await new CompilerLogger('reset').wrap(async log => { | ||
await fs.rm(path.resolve(ctx.workspace.path, ctx.build.outputFolder), { recursive: true, force: true }); | ||
log('info', 'Clearing output due to compiler changes'); | ||
log.info('Clearing output due to compiler changes'); | ||
}, false); | ||
@@ -217,5 +217,5 @@ } | ||
// Write manifest | ||
await LogUtil.withLogger('manifest', async log => { | ||
await new CompilerLogger('manifest').wrap(async log => { | ||
await ManifestUtil.writeManifest(manifest); | ||
log('debug', `Wrote manifest ${ctx.workspace.name}`); | ||
log.debug(`Wrote manifest ${ctx.workspace.name}`); | ||
@@ -232,4 +232,4 @@ // Update all manifests when in mono repo | ||
} | ||
log('debug', `Changes triggered ${delta.slice(0, 10).map(x => `${x.type}:${x.module}:${x.file}`)}`); | ||
log('debug', `Rewrote monorepo manifests [changes=${delta.length}] ${names.slice(0, 10).join(', ')}`); | ||
log.debug(`Changes triggered ${delta.slice(0, 10).map(x => `${x.type}:${x.module}:${x.file}`)}`); | ||
log.debug(`Rewrote monorepo manifests [changes=${delta.length}] ${names.slice(0, 10).join(', ')}`); | ||
} | ||
@@ -236,0 +236,0 @@ }); |
@@ -7,3 +7,3 @@ import fs from 'node:fs/promises'; | ||
import { LogUtil } from './log'; | ||
import { CompilerLogger } from './log'; | ||
@@ -62,3 +62,3 @@ const OPT_CACHE: Record<string, import('typescript').CompilerOptions> = {}; | ||
static async * restartableEvents<T>(src: (signal: AbortSignal) => AsyncIterable<T>, parent: AbortSignal, shouldRestart: (item: T) => boolean): AsyncIterable<T> { | ||
const log = LogUtil.logger('event-stream'); | ||
const log = new CompilerLogger('event-stream'); | ||
outer: while (!parent.aborted) { | ||
@@ -73,3 +73,3 @@ const controller = new AbortController(); | ||
log('debug', 'Started event stream'); | ||
log.debug('Started event stream'); | ||
@@ -80,3 +80,3 @@ // Wait for all events, close at the end | ||
if (shouldRestart(ev)) { | ||
log('debug', 'Restarting stream'); | ||
log.debug('Restarting stream'); | ||
controller.abort(); // Ensure terminated of process | ||
@@ -88,3 +88,3 @@ parent.removeEventListener('abort', kill); | ||
log('debug', 'Finished event stream'); | ||
log.debug('Finished event stream'); | ||
@@ -91,0 +91,0 @@ // Natural exit, we done |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
81508
1773