@@ -6,15 +6,47 @@ export type { ChunkEntity, Document, IndexConfig, IndexPhase, IndexProgress, Sea
66type RetrivInstance = Awaited < ReturnType < typeof getDb > >
77
88export class SearchDepsUnavailableError extends Error {
9- constructor ( cause : unknown ) {
10- super ( 'Search dependencies unavailable (sqlite-vec or retriv not installed). Search indexing skipped.' )
9+ constructor ( cause : unknown , message ?: string ) {
10+ super ( message ?? 'Search dependencies unavailable (sqlite-vec or retriv not installed). Search indexing skipped.' )
1111 this . name = 'SearchDepsUnavailableError'
1212 this . cause = cause
1313 }
1414}
1515
16+ let _fts5Available : boolean | null = null
17+
18+ /**
19+ * Probe whether SQLite FTS5 module is available.
20+ * Windows Node.js binaries often ship without FTS5 compiled in.
21+ */
22+ function checkFts5 ( ) : boolean {
23+ if ( _fts5Available !== null )
24+ return _fts5Available
25+ const nodeSqlite = globalThis . process ?. getBuiltinModule ?.( 'node:sqlite' ) as typeof import ( 'node:sqlite' ) | undefined
26+ if ( ! nodeSqlite ) {
27+ _fts5Available = false
28+ return false
29+ }
30+ const db = new nodeSqlite . DatabaseSync ( ':memory:' )
31+ try {
32+ db . exec ( 'CREATE VIRTUAL TABLE _fts5_probe USING fts5(content)' )
33+ db . exec ( 'DROP TABLE _fts5_probe' )
34+ _fts5Available = true
35+ }
36+ catch {
37+ _fts5Available = false
38+ }
39+ finally {
40+ db . close ( )
41+ }
42+ return _fts5Available
43+ }
44+
1645// Dynamic imports: retriv/chunkers/auto eagerly loads typescript which may not be installed (e.g. npx)
1746export async function getDb ( config : Pick < IndexConfig , 'dbPath' > ) {
47+ if ( ! checkFts5 ( ) )
48+ throw new SearchDepsUnavailableError ( new Error ( 'FTS5 module not available' ) , 'SQLite FTS5 module not available. Search indexing skipped. On Windows, run from WSL where FTS5 is included.' )
49+
1850 let createRetriv , autoChunker , sqliteMod , sqliteVec , transformersJs , cachedEmbeddings
1951 try {
2052 ; ( [
0 commit comments