/** * Layout store — per-session persistence of entry layout data. * * Stores a layout snapshot (entry id → row height / char count / term width) * in memory during the session and persists it to disk alongside the session * data so a resumed session can reconstruct the virtual scroll viewport * without mounting every entry just to discover its height. * * Threading: designed for single-threaded use in the TUI's React render * cycle. Disk writes use atomic-write (temp-file + rename) for crash safety. * Calls should be batched; writes are debounced (500ms idle after last set). */ import type { EntryLayout } from './layout-engine.js'; export interface LayoutStoreOptions { /** Directory where the session's layout snapshot is stored. */ sessionDataDir: string | undefined; /** When true, skip all disk I/O (for testing / no-session mode). */ ephemeral?: boolean; } export declare class LayoutStore { /** In-memory map: entry id → layout data. */ private readonly layouts; /** Current terminal width used for layout computations. */ private currentTermWidth; /** Session data directory path, or undefined for ephemeral mode. */ private readonly sessionDataDir; /** When true, skip all disk I/O. */ private readonly ephemeral; /** Debounce timer handle for pending disk writes. */ private debounceTimer; /** Pending dirty flag — set when in-memory state diverges from disk. */ private dirty; constructor(options: LayoutStoreOptions); /** Set the terminal width used for layout computation. */ setTermWidth(width: number): void; /** Get the current terminal width. */ get termWidth(): number; /** Number of entries tracked. */ get size(): number; /** Get the cached layout for an entry id, or undefined. */ get(id: number): EntryLayout | undefined; /** Get the cached row height for an entry id. Returns fallback if unknown. */ getRows(id: number): number; /** * True when every entry id in the set has a measured (non-estimated) layout. */ allMeasured(ids: Iterable): boolean; /** * Record or update the layout for an entry. Idempotent when both the * terminal width and row count are unchanged. Marks the store dirty and * schedules a debounced disk write. */ set(id: number, layout: EntryLayout): void; /** * Batch-set multiple layouts at once. More efficient than calling `set()` * in a loop because it only triggers one debounced flush. */ setMany(entries: Iterable): void; /** * Promote a layout from 'estimated' to 'measured' once the real component * has been mounted and its actual height is known. * * Also updates the stored `termWidth` to the current terminal width: after a * resize, entries are re-seeded with the new width as estimates, and the * post-render measurement pass needs to stamp the actual width so the store * is consistent. Without this, a subsequent render sees `stored.termWidth` * mismatch the current width and re-seeds estimates, discarding the * measurement and corrupting the virtual scroll viewport. */ markMeasured(id: number, actualRows: number, termWidth?: number): void; /** * Remove entries no longer in the active set (after history retention). */ retain(entryIds: Set): void; /** Reset all in-memory state (on /clear). */ clear(): void; /** * Load layout data from disk. Returns the number of entries restored, or 0 * when no data exists or the version has changed (caller should regenerate). * * Call once at session start, before the first render cycle, so the entry * height cache can be seeded with accurate (measured) layouts instead of * fallback estimates. */ load(): Promise; /** * Force an immediate disk write. Normally writes are debounced; call this * before session end to ensure the latest layout data is persisted. */ flushNow(): Promise; /** Schedule a debounced flush to disk. */ private scheduleFlush; /** Cancel any pending flush. */ private cancelFlush; } //# sourceMappingURL=layout-store.d.ts.map