/** * SqliteFrameStore — SQLite implementation of FrameStore interface. * * Production-ready implementation that uses SQLite as the backing store. * Supports FTS5 for full-text search and proper connection management. */ import type Database from "better-sqlite3-multiple-ciphers"; import type { FrameStore, FrameSearchCriteria, FrameListOptions, FrameListResult, SaveResult, StoreStats, TurnCostMetrics } from "../frame-store.js"; import type { Frame } from "../../frames/types.js"; /** * SqliteFrameStore — SQLite-backed implementation of FrameStore. * * Provides Frame persistence using SQLite with FTS5 for full-text search. * Handles connection lifecycle management with proper cleanup. */ export declare class SqliteFrameStore implements FrameStore { private _db; private ownsConnection; private isClosed; /** * Access the underlying database connection. * Useful for operations not covered by the FrameStore interface (e.g., ImageManager). * * @throws Error if the store has been closed. */ get db(): Database.Database; /** * Create a new SqliteFrameStore. * * @param dbOrPath - Either an existing Database connection or a path to create/open a database. * If a path is provided (or undefined for default), the store owns the connection * and will close it on close(). If a Database is provided, the caller is * responsible for closing it. */ constructor(dbOrPath?: Database.Database | string); /** * Persist a Frame to storage. * Uses INSERT OR REPLACE for upsert behavior. */ saveFrame(frame: Frame): Promise; /** * Persist multiple Frames to storage with transactional semantics. * All-or-nothing: if any validation fails, no Frames are saved. * Uses a prepared statement within a transaction for optimal performance. */ saveFrames(frames: Frame[]): Promise; /** * Retrieve a Frame by its unique identifier. */ getFrameById(id: string): Promise; /** * Search for Frames matching the given criteria. * * Uses FTS5 for text search when query is provided. * Supports filtering by moduleScope, since, and until dates. * Fuzzy matching is enabled by default (can be disabled with exact=true). */ searchFrames(criteria: FrameSearchCriteria): Promise; /** * List Frames with optional pagination. * * Supports both cursor-based and offset-based pagination for backward compatibility. * Cursor-based pagination provides stable ordering by (timestamp DESC, id DESC). * When a cursor is provided, it takes precedence over offset. * * @param options - Pagination options (limit, cursor, or offset). * @returns FrameListResult with frames and pagination metadata. */ listFrames(options?: FrameListOptions): Promise; /** * Delete a Frame by its unique identifier. * Also removes associated FTS5 index entry. * @param id - The Frame ID to delete. * @returns true if a Frame was deleted, false if the ID was not found. */ deleteFrame(id: string): Promise; /** * Delete all Frames with timestamps before the given date. * FTS5 entries are removed automatically by SQLite triggers. * @param date - Delete Frames with timestamp < date (UTC). * @returns The number of Frames deleted. */ deleteFramesBefore(date: Date): Promise; /** * Delete all Frames matching a branch name. * FTS5 entries are removed automatically by SQLite triggers. * @param branch - The branch to match. * @returns The number of Frames deleted. */ deleteFramesByBranch(branch: string): Promise; /** * Delete all Frames that include the given module in their module_scope. * Uses json_each() to match within the JSON array column. * FTS5 entries are removed automatically by SQLite triggers. * @param moduleId - The module ID to match. * @returns The number of Frames deleted. */ deleteFramesByModule(moduleId: string): Promise; /** * Get the total number of Frames in the store. * @returns The total Frame count. */ getFrameCount(): Promise; /** * Get database statistics for diagnostics. * Queries frame counts, date ranges, and optional module distribution. */ getStats(detailed?: boolean): Promise; /** * Get turn cost metrics for a time period. * Aggregates token usage and prompt counts from Frame spend metadata. */ getTurnCostMetrics(since?: string): Promise; /** * Update specific fields of an existing Frame. * Only the provided fields are updated; all other fields remain unchanged. * Uses a targeted SQL UPDATE instead of INSERT OR REPLACE. * * @param id - The ID of the Frame to update. * @param updates - Partial Frame fields to update. 'id' and 'timestamp' cannot be changed. * @returns true if a Frame was found and updated, false if the ID was not found. */ updateFrame(id: string, updates: Partial>): Promise; /** * Delete all Frames that have been marked as superseded. * Removes frames where superseded_by IS NOT NULL. * FTS5 entries are removed automatically by SQLite triggers. * * @returns The number of Frames deleted. */ purgeSuperseded(): Promise; /** * Close the store and release any resources. * Idempotent - safe to call multiple times. */ close(): Promise; }