/** * @fileoverview Schema and row mapping for the local Gutendex catalog mirror. Holds * the SQLite column declaration, the FTS5 index over the fields * `gutenberg_search_books` matches on, and the two-way translation between a * normalized {@link Book} and one stored row. * * Structured fields (people, string lists, the formats map) are stored as JSON so a * hydrated row is byte-identical to the live record. The FTS index cannot search JSON * without indexing its keys and punctuation as terms, so each searchable list also * gets a flattened text column that carries only the values. * @module services/catalog-mirror/catalog-mirror-store */ import type { MirrorRow, SqliteMirrorStoreSpec } from '@cyanheads/mcp-ts-core/mirror'; import type { Book } from '../gutendex/types.js'; /** Primary table holding one row per Gutenberg book. */ export declare const CATALOG_TABLE = "books"; /** * Columns the FTS5 index covers. `gutenberg_search_books` matches its `query` against * title and author name and its `topic` against subject and bookshelf, mirroring * Gutendex's own filters; `languages_text` joins them so a language filter is served * by the same index instead of a table scan. */ export declare const CATALOG_FTS_COLUMNS: readonly ['title', 'authors_text', 'subjects_text', 'bookshelves_text', 'languages_text']; /** One stored catalog row. */ export interface CatalogBookRow extends MirrorRow { author_birth_max: number | null; author_birth_min: number | null; author_death_max: number | null; author_death_min: number | null; /** JSON `Person[]`. */ authors: string; /** Flattened author names, for FTS. */ authors_text: string; /** JSON `string[]`. */ bookshelves: string; bookshelves_text: string; /** 1 = copyrighted, 0 = public domain, null = unknown. */ copyright: number | null; download_count: number; /** JSON `Person[]`. */ editors: string; /** JSON `Record` of MIME type → URL. */ formats: string; /** 1 when `gutenberg_get_text` can serve this book, else 0. */ has_plain_text: number; id: number; /** JSON `string[]`. */ languages: string; languages_text: string; media_type: string; /** JSON `string[]`. */ subjects: string; subjects_text: string; /** JSON `string[]`. */ summaries: string; title: string; } /** * Store spec for the catalog mirror. * * The `download_count` index backs `gutenberg_browse_popular` and the default * `sort: 'popular'` ordering, which are the only ordered scans over the whole table. * The four `author_*` columns collapse Gutendex's author-lifespan filter — which is an * OR over every author of a book — into scalar comparisons a single row can answer. */ export declare function catalogStoreSpec(path: string): SqliteMirrorStoreSpec; /** Translate a normalized book into its stored row. */ export declare function rowFromBook(book: Book): CatalogBookRow; /** Translate a stored row back into the normalized book shape the live path returns. */ export declare function bookFromRow(row: MirrorRow): Book; //# sourceMappingURL=catalog-mirror-store.d.ts.map