fix(session): repaired torn JSONL appends
Rolled partial file appends back to their pre-write size and marked malformed resumed sessions for an atomic rewrite. Retried transient persistence failures from in-memory state and surfaced the first failure in the interactive TUI. Fixes #8596
This commit is contained in:
@@ -446,12 +446,13 @@ export async function* readSseEvents(
|
||||
* Uses `Bun.JSONL.parseChunk` internally. On parse errors, the malformed
|
||||
* region is skipped up to the next newline and parsing continues.
|
||||
*
|
||||
* @param options.onMalformedRecord Called once for every skipped JSONL record.
|
||||
* @example
|
||||
* ```ts
|
||||
* const entries = parseJsonlLenient<MyType>(fileContents);
|
||||
* ```
|
||||
*/
|
||||
export function parseJsonlLenient<T>(buffer: string): T[] {
|
||||
export function parseJsonlLenient<T>(buffer: string, options: { onMalformedRecord?: () => void } = {}): T[] {
|
||||
let entries: T[] | undefined;
|
||||
|
||||
while (buffer.length > 0) {
|
||||
@@ -466,11 +467,16 @@ export function parseJsonlLenient<T>(buffer: string): T[] {
|
||||
}
|
||||
if (error) {
|
||||
const nextNewline = buffer.indexOf("\n", read);
|
||||
const malformedEnd = nextNewline === -1 ? buffer.length : nextNewline;
|
||||
if (buffer.substring(read, malformedEnd).trim().length > 0) options.onMalformedRecord?.();
|
||||
if (nextNewline === -1) break;
|
||||
buffer = buffer.substring(nextNewline + 1);
|
||||
continue;
|
||||
}
|
||||
if (read === 0) break;
|
||||
if (read === 0) {
|
||||
if (buffer.trim().length > 0) options.onMalformedRecord?.();
|
||||
break;
|
||||
}
|
||||
buffer = buffer.substring(read);
|
||||
if (done) break;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user