/** * In-memory structured initd journal (NDJSON lines) exposed under /run/bare-os/unit-journal/. */ const MAX_LINES_PER_UNIT = 400 const MAX_LINE_UTF8 = 4096 /** @type {Map} */ const linesByUnit = new Map() function journalMaxLinesPerUnit() { const raw = globalThis.process?.env?.BARE_OS_INITD_JOURNAL_MAX_LINES if (raw == null || raw === '') return MAX_LINES_PER_UNIT const n = Number.parseInt(String(raw), 10) return Number.isFinite(n) && n > 10 ? Math.min(n, 20000) : MAX_LINES_PER_UNIT } /** * @param {string} unit * @param {Record} rec */ export function appendBareInitdJournal(unit, rec) { if (!unit || !/^[a-zA-Z0-9._-]+$/.test(unit)) return const payload = { ts: Date.now(), unit, ...rec } let line try { line = JSON.stringify(payload) + '\n' } catch { return } if (line.length > MAX_LINE_UTF8) return let arr = linesByUnit.get(unit) if (!arr) { arr = [] linesByUnit.set(unit, arr) } arr.push(line) const cap = journalMaxLinesPerUnit() while (arr.length > cap) arr.shift() } /** * @param {string} unit * @returns {string} */ export function getBareInitdJournalNdjson(unit) { const arr = linesByUnit.get(unit) return arr ? arr.join('') : '' } /** @returns {string[]} */ export function listBareInitdJournalUnits() { return [...linesByUnit.keys()].sort() } export function clearBareInitdJournalForTests() { linesByUnit.clear() }