import { BetterSqlite3Constructor, BetterSqlite3Database, BetterSqlite3Statement } from "./driver-types.js"; import { EncryptionConfig } from "./encryption/index.js"; //#region src/connection.d.ts /** * The runtime contract every higher-level store interacts with. The * concrete adapter is built by {@link openConnection} and wraps either * `better-sqlite3` (default) or `better-sqlite3-multiple-ciphers` * (encryption-at-rest opt-in). * * @stable */ interface SqliteConnection { /** Path to the underlying database file (`':memory:'` for in-memory). */ readonly path: string; /** Whether the connection is encryption-enabled. */ readonly encrypted: boolean; /** Whether the connection wraps a `:memory:` database. */ readonly inMemory: boolean; /** * How vector sidecars are served: `'vec0'` (sqlite-vec * loaded), `'linear-fallback'` (plain tables + in-process cosine * scan), or `'disabled'` (`skipSqliteVec`). Optional so existing * structural stubs keep compiling; absent reads as `'vec0'`. */ readonly vectorSearchMode?: 'vec0' | 'linear-fallback' | 'disabled'; pragma(query: string, options?: { simple?: boolean; }): unknown; exec(query: string): void; execMany(sql: string): void; run(query: string, params?: ReadonlyArray): { changes: number; }; get(query: string, params?: ReadonlyArray): T | undefined; all(query: string, params?: ReadonlyArray): T[]; prepare(query: string): BetterSqlite3Statement; transaction(fn: () => T): T; close(): void; /** Returns the underlying `better-sqlite3` handle. Escape hatch only. */ raw(): BetterSqlite3Database; } /** * Mandatory WAL hardening pragmas applied at connection open. Any * deviation must be documented in the calling site's TSDoc per the * Phase 05 acceptance criteria. * * @stable */ declare const WAL_HARDENING_PRAGMAS: readonly ["journal_mode = WAL", "synchronous = NORMAL", "busy_timeout = 5000", "mmap_size = 134217728", "temp_store = MEMORY", "cache_size = -64000", "foreign_keys = ON"]; /** * Options for {@link openConnection}. * * @stable */ interface OpenConnectionOptions { readonly path: string; /** Optional encryption-at-rest configuration. Default: disabled. */ readonly encryption?: EncryptionConfig; /** * If `true`, skip loading the `sqlite-vec` extension. Used by tests * that exercise the migration runner without the vector adapter. */ readonly skipSqliteVec?: boolean; /** * Policy when the `sqlite-vec` peer is missing or fails to load. * `'fail'` (default) rethrows * {@link SqliteVecMissingError} - the historical behaviour. * `'linear-fallback'` degrades instead of dying: vector sidecars are * kept in PLAIN tables (same names/columns) and KNN runs as an * in-process batched cosine scan with `setImmediate` yields. Suits * environments where the native build is unavailable and degraded * vector recall beats a crash. A database must stay in ONE mode: the * table manager refuses to open vec0 tables in fallback mode (and * plain fallback tables in vec0 mode) with an actionable error. */ readonly onMissingSqliteVec?: 'fail' | 'linear-fallback'; /** * Override the constructor used to open the underlying database. * Used by the test suite to inject a stub. When unset the connection * lazily loads `better-sqlite3` (or the cipher peer when encryption * is enabled) at first call. */ readonly driver?: BetterSqlite3Constructor; /** * Override the `sqlite-vec` `load(db)` helper. Used by the test * suite to verify the loader is invoked without a native build. */ readonly loadVecExtension?: (db: BetterSqlite3Database) => void; /** * If `true`, do not apply the WAL hardening pragmas. The runner * still applies `foreign_keys=ON` and `busy_timeout` so the * migration step works against `:memory:` databases. Off by default. */ readonly disableWalHardening?: boolean; /** * Optional cipher-driver loader override. When `encryption.enabled` * is `true` and the operator does not pass `driver`, this loader is * consulted instead of the canonical * `loadCipherDriver`. Used by * the test suite to simulate a missing cipher peer without * uninstalling the package from the workspace. * * @internal */ readonly cipherLoader?: () => Promise; /** * How long the driver's busy handler waits for a contended * write lock before the operation fails with {@link SqliteBusyError}. * Applied AFTER the hardening pragmas so the exported * {@link WAL_HARDENING_PRAGMAS} constant keeps its documented bytes; * also honoured on the `disableWalHardening` / `:memory:` branch. * @default 5000 */ readonly busyTimeoutMs?: number; } /** * Test-only helper. Drops cached driver / loader handles so the next * `openConnection(...)` call resolves them again. * * @internal */ declare function _resetDriverCacheForTesting(): void; /** * Opens a connection. Side effects (in this order): * 1. Resolve the encryption passphrase if `encryption.enabled === true`. * 2. Load the cipher driver or the default `better-sqlite3` peer. * 3. Create the parent directory if absent (`recursive: true`). * 4. Open the database file. * 5. Apply WAL hardening pragmas. * 6. Apply the cipher passphrase (`PRAGMA key = ...`). * 7. Load `sqlite-vec` (unless `skipSqliteVec` is set). * * @stable */ declare function openConnection(options: OpenConnectionOptions): Promise; /** * Pragma helper that surfaces the runtime value of a single setting as * a typed scalar. Used by the integration tests to verify the WAL * hardening defaults landed correctly. * * @stable */ declare function readPragma(conn: SqliteConnection, name: string): unknown; /** * Returns the byte size of the WAL file, or `0` when the file is * absent / empty. Surfaced as `graphorin.storage.wal.size_bytes`. * * @stable */ declare function readWalSize(conn: SqliteConnection): number; /** * Periodic `wal_checkpoint(RESTART)` runner. Invoked by the worker * pool every `intervalMs` to bound WAL growth on long-running servers. * * @stable */ declare class WalCheckpointManager { #private; constructor(conn: SqliteConnection, intervalMs: number); start(): void; stop(): void; } /** @stable */ declare class SqliteVecMissingError extends Error { readonly name = "SqliteVecMissingError"; } /** * Typed wrapper for the driver's raw `SQLITE_BUSY` / * `SQLITE_BUSY_SNAPSHOT` errors: the write lock stayed * contended past `busy_timeout`. Carries `code = 'SQLITE_BUSY'` for * compatibility with callers that already branch on the driver's * `err.code`, plus the driver error as `cause`. No auto-retry by * design (deterministic policies; the busy handler already waited the * full `busy_timeout`). * * @stable */ declare class SqliteBusyError extends Error { readonly name = "SqliteBusyError"; /** Stable machine discriminator, mirroring the driver's code. */ readonly code = "SQLITE_BUSY"; /** Package-level error kind, matching the repo's `kind` convention. */ readonly kind = "sqlite-busy"; constructor(operation: string, cause: unknown); } //#endregion export { type BetterSqlite3Constructor, type BetterSqlite3Database, type BetterSqlite3Statement, OpenConnectionOptions, SqliteBusyError, SqliteConnection, SqliteVecMissingError, WAL_HARDENING_PRAGMAS, WalCheckpointManager, _resetDriverCacheForTesting, openConnection, readPragma, readWalSize }; //# sourceMappingURL=connection.d.ts.map