/** * @file Reads what an append-only JSONL journal gained since a byte offset — * the incremental read a session-journal poller does (omp-usage.js). Only * complete lines are returned: one still being written * stays for the next pass. Every open goes through `openSafeAsync`, so a * member's journal (S3) is read only when it is a regular file they own, * never through a link. * @author Nguyễn Ngọc Trí Vĩ */ const CHUNK = 8 * 1024 * 1024; // read per file per pass; the rest waits for the next /** * The complete lines written between `offset` and `size`: `{lines, offset}`. * A chunk with no newline at all (one line over CHUNK) is skipped whole. */ async function readNew(file, offset, size, { chunk = CHUNK } = {}) { const fh = await require("./run-as").openSafeAsync(file); try { const len = Math.min(size - offset, chunk); if (len <= 0) return { lines: [], offset }; const buf = Buffer.alloc(len); let got = 0; for (let n; got < len; got += n) { ({ bytesRead: n } = await fh.read(buf, got, len - got, offset + got)); if (!n) break; } const end = got ? buf.lastIndexOf(0x0a, got - 1) : -1; if (end === -1) return { lines: [], offset: got === chunk ? offset + got : offset }; return { lines: buf.toString("utf8", 0, end).split("\n"), offset: offset + end + 1 }; } finally { await fh.close(); } } module.exports = { readNew };