everything-dev
Version:
A consolidated product package for building Module Federation apps with oRPC APIs.
89 lines (87 loc) • 3.84 kB
JavaScript
const require_dev_log_pipeline = require('./dev-log-pipeline.cjs');
let node_fs = require("node:fs");
let node_path = require("node:path");
let node_fs_promises = require("node:fs/promises");
//#region src/dev-logs.ts
function getBosDir(configDir) {
return (0, node_path.join)(configDir, ".bos");
}
function getLogsDir(configDir) {
return (0, node_path.join)(getBosDir(configDir), "logs");
}
function formatLogLine(entry) {
const ts = new Date(entry.timestamp).toISOString();
const prefix = entry.isError ? "ERR" : "OUT";
const clean = require_dev_log_pipeline.stripAnsi(entry.line);
const head = `[${ts}] [${entry.source}] [${prefix}] `;
const pad = " ".repeat(head.length);
const [first, ...rest] = clean.split("\n");
return [`${head}${first}`, ...rest.map((line) => `${pad}${line}`)].join("\n");
}
async function createDevLogger(configDir, description) {
const dir = getLogsDir(configDir);
if (!(0, node_fs.existsSync)(dir)) await (0, node_fs_promises.mkdir)(dir, { recursive: true });
const now = /* @__PURE__ */ new Date();
const ts = now.toISOString().replace(/[:.]/g, "-").slice(0, 19);
const logFile = (0, node_path.join)(dir, `dev-${ts}-${process.pid}.log`);
const latestFile = (0, node_path.join)(dir, `dev-latest-${process.pid}.log`);
const header = `# everything-dev dev session: ${description}\n# Started: ${now.toISOString()}\n\n`;
await (0, node_fs_promises.writeFile)(logFile, header, "utf8");
await (0, node_fs_promises.writeFile)(latestFile, header, "utf8");
let chain = Promise.resolve();
const enqueue = (fn) => {
chain = chain.then(fn, fn);
return chain;
};
return {
logFile,
latestFile,
write: (entry) => enqueue(async () => {
const line = `${formatLogLine(entry)}\n`;
await (0, node_fs_promises.appendFile)(logFile, line);
await (0, node_fs_promises.appendFile)(latestFile, line);
}),
readLatest: async (opts) => {
const text = await (0, node_fs_promises.readFile)(latestFile, "utf8").catch(() => "");
const tail = opts?.tail;
if (!tail || tail <= 0) return text;
const lines = text.split("\n");
return lines.slice(Math.max(0, lines.length - tail)).join("\n");
}
};
}
function resolveDevLatestFile(configDir) {
const dir = getLogsDir(configDir);
const latestFile = (0, node_path.join)(dir, "dev-latest.log");
if ((0, node_fs.existsSync)(latestFile)) return latestFile;
const STARTED_RE = /^# Started: (.+)$/m;
const startedMsOf = (name) => {
const header = (0, node_fs.readFileSync)((0, node_path.join)(dir, name), "utf8").slice(0, 256);
const started = STARTED_RE.exec(header)?.[1];
const parsed = started ? Date.parse(started) : NaN;
return Number.isNaN(parsed) ? (0, node_fs.statSync)((0, node_path.join)(dir, name)).mtimeMs : parsed;
};
const pidOf = (name) => Number(/^dev-latest-(\d+)\.log$/.exec(name)?.[1] ?? 0);
const candidates = (0, node_fs.readdirSync)(dir).filter((name) => /^dev-latest-\d+\.log$/.test(name)).map((name) => ({
name,
startedMs: startedMsOf(name),
pid: pidOf(name)
})).sort((a, b) => b.startedMs - a.startedMs || b.pid - a.pid || a.name.localeCompare(b.name));
return candidates.length > 0 ? (0, node_path.join)(dir, candidates[0].name) : latestFile;
}
async function readDevLatestLog(configDir, opts) {
const latestFile = resolveDevLatestFile(configDir);
const text = await (0, node_fs_promises.readFile)(latestFile, "utf8").catch(() => "");
const tail = opts?.tail;
if (!tail || tail <= 0) return text;
const lines = text.split("\n");
return lines.slice(Math.max(0, lines.length - tail)).join("\n");
}
//#endregion
exports.createDevLogger = createDevLogger;
exports.formatLogLine = formatLogLine;
exports.getBosDir = getBosDir;
exports.getLogsDir = getLogsDir;
exports.readDevLatestLog = readDevLatestLog;
exports.resolveDevLatestFile = resolveDevLatestFile;
//# sourceMappingURL=dev-logs.cjs.map