Files
learnharness/src/store/render-settings.ts
T
amosblomqvist eda5491010 schema stamps: lazy v1 for chats + the graph family, honest refusal
Chat records gain version (CURRENT_CHAT_VERSION), stamped by a single
writeChat choke point in the store; absence reads as v1 — existing files
migrate on their next write, no mass rewrite. The graph family (four JSONL
ledgers, sources.json, render-settings.json) shares one lazy sidecar,
graph/format.json; positions stays unstamped (rebuildable) and jobs stay
unstamped (transient).

Downgrade scenario ruled honest-refusal: records stamped newer than the
running build read as absent (chats, logged) or throw (graph family) — a
read-modify-write store never rewrites what it doesn't understand.

Golden fixtures stay the unstamped legacy shape on purpose (lazy v1 is
current-valid by design); the stamped write path is pinned by
tests/schema-stamps.test.ts. Reads never write — the golden byte-identical
pin holds.
2026-10-10 13:54:17 +03:00

44 lines
1.7 KiB
TypeScript

/**
* Server-side persistence for the graph render settings (the settings-panel
* controls): data/render-settings.json — read-modify-write, NOT a ledger.
*
* The shape, defaults, and sanitizer live in src/core/render-settings.ts
* (pure, shared with the client); this module only moves bytes. Whatever
* comes off disk is sanitized by the caller on load — and we sanitize on
* write too, so the file can never hold an out-of-range value that would
* silently shift a slider.
*/
import fs from "node:fs";
import path from "node:path";
import { RENDER_SETTINGS_FILE } from "../../config.ts";
import { DEFAULT_RENDER_SETTINGS, sanitizeRenderSettings, type GraphRenderSettings } from "../core/render-settings.ts";
import { assertGraphFormat, ensureGraphFormat } from "./graph-format.ts";
/** The persisted settings, or null when no file exists yet (first boot). */
export function readRenderSettings(): GraphRenderSettings | null {
assertGraphFormat(); // honest refusal on a newer-stamped data dir
let raw: string;
try {
raw = fs.readFileSync(RENDER_SETTINGS_FILE, "utf-8");
} catch {
return null; // never booted / unreadable → caller uses defaults
}
try {
return sanitizeRenderSettings(JSON.parse(raw));
} catch {
return null; // corrupt → defaults, never crash the view
}
}
/** Persist settings (sanitized). Returns what was written. */
export function writeRenderSettings(raw: unknown): GraphRenderSettings {
const settings = sanitizeRenderSettings(raw);
fs.mkdirSync(path.dirname(RENDER_SETTINGS_FILE), { recursive: true });
ensureGraphFormat(); // the lazy format stamp (graph-format.ts)
fs.writeFileSync(RENDER_SETTINGS_FILE, JSON.stringify(settings, null, "\t"), "utf-8");
return settings;
}
export { DEFAULT_RENDER_SETTINGS };