/** * State Sync for OpenCode Diff Plugin * * Provides file-based state persistence with atomic writes, file watching, * and debounced writes for performance. Manages state file format versioning * and handles concurrent access scenarios. */ import { PendingChange, ChangeQueue } from './state-manager.js'; /** * State file data structure */ export interface StateFileData { version: string; timestamp: number; sessionID: string; changes: unknown[]; } /** * Options for StateSync initialization */ export interface StateSyncOptions { /** Debounce interval in milliseconds (default: 100) */ debounceMs?: number; /** Enable debug logging */ debug?: boolean; } /** * Callback type for file change notifications */ export type StateChangeCallback = (changes: PendingChange[]) => void; /** * Error thrown when state sync operations fail */ export declare class StateSyncError extends Error { readonly operation: 'write' | 'read' | 'watch' | 'unwatch'; constructor(message: string, operation: 'write' | 'read' | 'watch' | 'unwatch'); } /** * StateSync class for file-based state persistence * * Features: * - Atomic writes using temp file + rename pattern * - File watching with fs.watch for external changes * - Debounced writes to prevent excessive I/O * - State file versioning for backward compatibility */ export declare class StateSync { private statePath; private sessionID; private debounceMs; private debug; private watcher; private watchTarget; private changeCallback; private debounceTimer; private watchDebounceTimer; private pendingChanges; private isWriting; private lastWriteTime; private readonly WRITE_IGNORE_WINDOW_MS; /** * Create a new StateSync instance * @param statePath - Path to the state file * @param sessionID - Unique session identifier * @param options - Optional configuration options */ constructor(statePath: string, sessionID: string, options?: StateSyncOptions); /** * Get the state file path * @returns The path to the state file */ getStatePath(): string; /** * Get the session ID * @returns The session identifier */ getSessionID(): string; /** * Write state to file atomically with comprehensive error handling * * Uses temp file + rename pattern for atomic writes: * 1. Write to temp file * 2. Sync to disk (optional, for durability) * 3. Rename temp file to target (atomic operation) * * @param changes - Array of pending changes to persist * @throws StateSyncError if write fails */ writeState(changes: PendingChange[]): Promise; /** * Validates state file data structure * @param data - Data to validate * @returns Validation result with error if invalid */ private validateStateData; /** * Creates a backup of the current state file * @returns Path to backup file or null if no state file */ private backupCorruptedState; /** * Attempts to recover from corrupted state file * @returns Recovered changes or empty array */ private attemptRecovery; /** * Read state from file with comprehensive corruption handling * * @returns Array of pending changes, or empty array if file doesn't exist * @throws StateSyncError if read fails and recovery is not possible */ readState(): Promise; /** * Write state with debouncing * * Multiple calls within the debounce interval will be coalesced into a single write. * This prevents excessive I/O when changes happen rapidly. * * @param changes - Array of pending changes to persist */ writeStateDebounced(changes: PendingChange[]): Promise; /** * Watch state file for external changes * * Sets up a file watcher that calls the provided callback when the state file * is modified externally. Automatically handles debouncing of watch events. * * @param callback - Function to call when state changes * @throws StateSyncError if watch fails */ watchState(callback: StateChangeCallback): void; /** * Stop watching state file * * Removes the file watcher and cleans up resources. */ unwatchState(): void; /** * Check if currently watching * @returns True if watcher is active */ isWatching(): boolean; /** * Handle file watch events * @param eventType - Type of file system event */ private handleWatchEvent; /** * Async wrapper for writeFile */ private writeFileAsync; /** * Async wrapper for readFile */ private readFileAsync; /** * Async wrapper for rename */ private renameAsync; /** * Async wrapper for unlink (cleanup) */ private unlinkAsync; /** * Debug logging helper */ private log; } /** * Create a ChangeQueue from persisted state * @param statePath - Path to the state file * @returns ChangeQueue populated with persisted changes, or empty queue */ export declare function loadChangeQueue(statePath: string): Promise; /** * Save a ChangeQueue to state file * @param queue - The ChangeQueue to save * @param statePath - Path to the state file * @param sessionID - Session identifier */ export declare function saveChangeQueue(queue: ChangeQueue, statePath: string, sessionID: string): Promise; export default StateSync; //# sourceMappingURL=state-sync.d.ts.map