import type { SearchSourceKind } from '../../shared/types' import { stripHtml } from './word-count' import type { SqliteDb } from '../db/types' export class FtsSyncService { upsert(db: SqliteDb, kind: SearchSourceKind, id: string, title: string, body: string): void { const plainBody = stripHtml(body) db.prepare('DELETE FROM search_fts WHERE source_kind = ? AND source_id = ?').run(kind, id) db.prepare( 'INSERT INTO search_fts (source_kind, source_id, title, body) VALUES (?, ?, ?, ?)' ).run(kind, id, title, plainBody) } remove(db: SqliteDb, kind: SearchSourceKind, id: string): void { db.prepare('DELETE FROM search_fts WHERE source_kind = ? AND source_id = ?').run(kind, id) } rebuildAll(db: SqliteDb): void { db.exec('DELETE FROM search_fts') const chapters = db.prepare('SELECT id, title, content FROM chapters').all() as { id: string title: string content: string }[] for (const ch of chapters) { this.upsert(db, 'chapter', ch.id, ch.title, ch.content) } const outlines = db.prepare('SELECT id, title, description FROM outline_items').all() as { id: string title: string description: string }[] for (const o of outlines) { this.upsert(db, 'outline', o.id, o.title, o.description) } const settings = db.prepare('SELECT id, name, description FROM settings').all() as { id: string name: string description: string }[] for (const s of settings) { this.upsert(db, 'setting', s.id, s.name, s.description) } const inspirations = db.prepare('SELECT id, title, content FROM inspiration').all() as { id: string title: string content: string }[] for (const i of inspirations) { this.upsert(db, 'inspiration', i.id, i.title, i.content) } const bookmarks = db.prepare('SELECT id, label, chapter_id FROM bookmarks').all() as { id: string label: string chapter_id: string }[] for (const b of bookmarks) { this.upsert(db, 'bookmark', b.id, b.label, b.label) } } } export const ftsSync = new FtsSyncService()