@nicia-ai/typegraph 0.25.0 → 0.25.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/backend/postgres/index.cjs +92 -44
- package/dist/backend/postgres/index.cjs.map +1 -1
- package/dist/backend/postgres/index.d.cts +4 -4
- package/dist/backend/postgres/index.d.ts +4 -4
- package/dist/backend/postgres/index.js +47 -3
- package/dist/backend/postgres/index.js.map +1 -1
- package/dist/backend/sqlite/index.cjs +13 -13
- package/dist/backend/sqlite/index.d.cts +4 -4
- package/dist/backend/sqlite/index.d.ts +4 -4
- package/dist/backend/sqlite/index.js +3 -3
- package/dist/backend/sqlite/libsql.cjs +6 -6
- package/dist/backend/sqlite/libsql.d.cts +2 -2
- package/dist/backend/sqlite/libsql.d.ts +2 -2
- package/dist/backend/sqlite/libsql.js +3 -3
- package/dist/backend/sqlite/local.cjs +7 -7
- package/dist/backend/sqlite/local.d.cts +2 -2
- package/dist/backend/sqlite/local.d.ts +2 -2
- package/dist/backend/sqlite/local.js +3 -3
- package/dist/{chunk-LVCSL6A3.js → chunk-AAA2CR3P.js} +5 -3
- package/dist/chunk-AAA2CR3P.js.map +1 -0
- package/dist/{chunk-OJ6IQVZG.js → chunk-CLEUFN2K.js} +48 -4
- package/dist/chunk-CLEUFN2K.js.map +1 -0
- package/dist/{chunk-ZEMNF3QK.cjs → chunk-CLGC7AQ2.cjs} +78 -34
- package/dist/chunk-CLGC7AQ2.cjs.map +1 -0
- package/dist/{chunk-FPCOUJSL.js → chunk-CPFR3O7L.js} +2 -2
- package/dist/{chunk-FPCOUJSL.js.map → chunk-CPFR3O7L.js.map} +1 -1
- package/dist/{chunk-O2P3KAUT.cjs → chunk-CQVNGKU7.cjs} +39 -14
- package/dist/chunk-CQVNGKU7.cjs.map +1 -0
- package/dist/{chunk-7CDXX3QZ.cjs → chunk-OECDVACY.cjs} +2 -2
- package/dist/{chunk-7CDXX3QZ.cjs.map → chunk-OECDVACY.cjs.map} +1 -1
- package/dist/{chunk-WI5VRP3X.js → chunk-PSKUWVCB.js} +39 -15
- package/dist/chunk-PSKUWVCB.js.map +1 -0
- package/dist/{chunk-7W3KAMVQ.cjs → chunk-QMQYK3IF.cjs} +5 -3
- package/dist/chunk-QMQYK3IF.cjs.map +1 -0
- package/dist/{ddl-DpaeAKPp.d.ts → ddl-BqMmpNor.d.ts} +403 -21
- package/dist/{ddl-B2jjLjpR.d.cts → ddl-Bwjh8Hff.d.cts} +403 -21
- package/dist/index.cjs +65 -65
- package/dist/index.d.cts +7 -7
- package/dist/index.d.ts +7 -7
- package/dist/index.js +3 -3
- package/dist/indexes/index.d.cts +4 -4
- package/dist/indexes/index.d.ts +4 -4
- package/dist/interchange/index.d.cts +3 -3
- package/dist/interchange/index.d.ts +3 -3
- package/dist/{manager-BpjBW1JK.d.cts → manager-Cy3dhwYO.d.cts} +7 -2
- package/dist/{manager-BKaPQbns.d.ts → manager-sZkU2VPC.d.ts} +7 -2
- package/dist/profiler/index.d.cts +5 -5
- package/dist/profiler/index.d.ts +5 -5
- package/dist/schema/index.cjs +24 -24
- package/dist/schema/index.d.cts +4 -4
- package/dist/schema/index.d.ts +4 -4
- package/dist/schema/index.js +2 -2
- package/dist/{sqlite-Myo8e3Lr.d.cts → sqlite-BhFswiAR.d.cts} +1 -1
- package/dist/{sqlite-CU3j6rc7.d.ts → sqlite-h6dta1IJ.d.ts} +1 -1
- package/dist/{store-De98Lod4.d.ts → store-BS_hehiz.d.ts} +2 -2
- package/dist/{store-BAGuOHDh.d.cts → store-CkCvqRUf.d.cts} +2 -2
- package/dist/{types-CYga3lZp.d.cts → types-BpgACExN.d.cts} +1 -1
- package/dist/{types-BLmJq4wI.d.ts → types-Bz-Pi681.d.ts} +1 -1
- package/dist/{types-BNWYZ-0-.d.ts → types-DptZHe-l.d.ts} +9 -0
- package/dist/{types--0EslBx5.d.cts → types-WF5ItKQu.d.cts} +9 -0
- package/dist/{where-CluR73rs.d.ts → where-C40InMIp.d.ts} +1 -1
- package/dist/{where-m1uWsdua.d.cts → where-DZYMiXVq.d.cts} +1 -1
- package/package.json +1 -1
- package/dist/chunk-7W3KAMVQ.cjs.map +0 -1
- package/dist/chunk-LVCSL6A3.js.map +0 -1
- package/dist/chunk-O2P3KAUT.cjs.map +0 -1
- package/dist/chunk-OJ6IQVZG.js.map +0 -1
- package/dist/chunk-WI5VRP3X.js.map +0 -1
- package/dist/chunk-ZEMNF3QK.cjs.map +0 -1
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { createNodeRowMapper, SQLITE_ROW_MAPPER_CONFIG, createEdgeRowMapper, createUniqueRowMapper, createSchemaVersionRowMapper, tables2, createSqliteOperationStrategy, generateSqliteCreateTableSQL, buildKindRemovalInsertValues, SQLITE_KIND_REMOVAL_TIMESTAMPS, buildKindRemovalOnConflictSet, mapKindRemovalRow, buildMaterializationInsertValues, SQLITE_INDEX_MAT_TIMESTAMPS, buildMaterializationOnConflictSet, mapMaterializationRow, generateSqliteDDL, createCommonOperationBackend, nowIso, compileQueryWithDialect, dropSqliteVectorIndex, createSqliteVectorIndex, getOrCreateLru } from './chunk-
|
|
2
|
-
import { SQLITE_CAPABILITIES } from './chunk-
|
|
1
|
+
import { createNodeRowMapper, SQLITE_ROW_MAPPER_CONFIG, createEdgeRowMapper, createUniqueRowMapper, createSchemaVersionRowMapper, tables2, createSqliteOperationStrategy, generateSqliteCreateTableSQL, buildKindRemovalInsertValues, SQLITE_KIND_REMOVAL_TIMESTAMPS, buildKindRemovalOnConflictSet, mapKindRemovalRow, buildMaterializationInsertValues, SQLITE_INDEX_MAT_TIMESTAMPS, buildMaterializationOnConflictSet, mapMaterializationRow, generateSqliteDDL, createCommonOperationBackend, nowIso, compileQueryWithDialect, dropSqliteVectorIndex, createSqliteVectorIndex, getOrCreateLru } from './chunk-PSKUWVCB.js';
|
|
2
|
+
import { SQLITE_CAPABILITIES } from './chunk-CPFR3O7L.js';
|
|
3
3
|
import { fts5Strategy, buildFulltextCapabilities } from './chunk-YZZBDCLV.js';
|
|
4
4
|
import { ConfigurationError, BackendDisposedError } from './chunk-DOTEN2FG.js';
|
|
5
5
|
import { getTableName, sql, eq, and, isNull, inArray } from 'drizzle-orm';
|
|
@@ -489,6 +489,16 @@ function createSqliteBackend(db, options = {}) {
|
|
|
489
489
|
}, { behavior: "immediate" })
|
|
490
490
|
);
|
|
491
491
|
}
|
|
492
|
+
let fulltextEnsured = false;
|
|
493
|
+
async function ensureFulltextDdl() {
|
|
494
|
+
if (fulltextEnsured) return;
|
|
495
|
+
for (const statement of fulltextStrategy.generateDdl(
|
|
496
|
+
tables2$1.fulltextTableName
|
|
497
|
+
)) {
|
|
498
|
+
await db.run(sql.raw(statement));
|
|
499
|
+
}
|
|
500
|
+
fulltextEnsured = true;
|
|
501
|
+
}
|
|
492
502
|
const backend = {
|
|
493
503
|
...operations,
|
|
494
504
|
async bootstrapTables() {
|
|
@@ -496,6 +506,36 @@ function createSqliteBackend(db, options = {}) {
|
|
|
496
506
|
for (const statement of statements) {
|
|
497
507
|
await db.run(sql.raw(statement));
|
|
498
508
|
}
|
|
509
|
+
fulltextEnsured = true;
|
|
510
|
+
},
|
|
511
|
+
async upsertFulltext(params) {
|
|
512
|
+
await ensureFulltextDdl();
|
|
513
|
+
await operations.upsertFulltext(params);
|
|
514
|
+
},
|
|
515
|
+
async deleteFulltext(params) {
|
|
516
|
+
await ensureFulltextDdl();
|
|
517
|
+
await operations.deleteFulltext(params);
|
|
518
|
+
},
|
|
519
|
+
async upsertFulltextBatch(params) {
|
|
520
|
+
if (params.rows.length === 0) return;
|
|
521
|
+
await ensureFulltextDdl();
|
|
522
|
+
await operations.upsertFulltextBatch(params);
|
|
523
|
+
},
|
|
524
|
+
async deleteFulltextBatch(params) {
|
|
525
|
+
if (params.nodeIds.length === 0) return;
|
|
526
|
+
await ensureFulltextDdl();
|
|
527
|
+
await operations.deleteFulltextBatch(params);
|
|
528
|
+
},
|
|
529
|
+
async fulltextSearch(params) {
|
|
530
|
+
await ensureFulltextDdl();
|
|
531
|
+
return operations.fulltextSearch(params);
|
|
532
|
+
},
|
|
533
|
+
// hardDeleteNode is wrapped because the operation-backend-core
|
|
534
|
+
// cascade unconditionally deletes from the fulltext table — it
|
|
535
|
+
// would fail even on graphs that declare no searchable() fields.
|
|
536
|
+
async hardDeleteNode(params) {
|
|
537
|
+
await ensureFulltextDdl();
|
|
538
|
+
await operations.hardDeleteNode(params);
|
|
499
539
|
},
|
|
500
540
|
async executeDdl(ddl) {
|
|
501
541
|
await db.run(sql.raw(ddl));
|
|
@@ -569,6 +609,9 @@ function createSqliteBackend(db, options = {}) {
|
|
|
569
609
|
sql.raw(generateSqliteCreateTableSQL(tables2$1.reconciliationMarkers))
|
|
570
610
|
);
|
|
571
611
|
},
|
|
612
|
+
async ensureFulltextTable() {
|
|
613
|
+
await ensureFulltextDdl();
|
|
614
|
+
},
|
|
572
615
|
async getReconciliationMarker(graphId) {
|
|
573
616
|
const t = tables2$1.reconciliationMarkers;
|
|
574
617
|
const rows = await db.select().from(t).where(eq(t.graphId, graphId));
|
|
@@ -605,6 +648,7 @@ function createSqliteBackend(db, options = {}) {
|
|
|
605
648
|
}
|
|
606
649
|
);
|
|
607
650
|
}
|
|
651
|
+
await ensureFulltextDdl();
|
|
608
652
|
if (transactionMode === "sql") {
|
|
609
653
|
return runWithSerializedQueue(serializedQueue, async () => {
|
|
610
654
|
const txBackend = createTransactionBackend({
|
|
@@ -667,5 +711,5 @@ function createTransactionBackend(options) {
|
|
|
667
711
|
}
|
|
668
712
|
|
|
669
713
|
export { createSqliteBackend };
|
|
670
|
-
//# sourceMappingURL=chunk-
|
|
671
|
-
//# sourceMappingURL=chunk-
|
|
714
|
+
//# sourceMappingURL=chunk-CLEUFN2K.js.map
|
|
715
|
+
//# sourceMappingURL=chunk-CLEUFN2K.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/backend/drizzle/execution/sqlite-execution.ts","../src/backend/drizzle/sqlite.ts"],"names":["executeCompiled","tables","sql"],"mappings":"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","file":"chunk-CLEUFN2K.js","sourcesContent":["import { type SQL, sql } from \"drizzle-orm\";\nimport { type BaseSQLiteDatabase } from \"drizzle-orm/sqlite-core\";\n\nimport { getOrCreateLru } from \"./lru\";\nimport {\n type CompiledSqlQuery,\n compileQueryWithDialect,\n type PreparedSqlStatement,\n type SqlExecutionAdapter,\n} from \"./types\";\n\nconst DEFAULT_PREPARED_STATEMENT_CACHE_MAX = 256;\n\ntype PreparedAllStatement = Readonly<{\n all: (...params: readonly unknown[]) => readonly unknown[];\n}>;\n\ntype SqliteClientWithPrepare = Readonly<{\n prepare: (sqlText: string) => PreparedAllStatement;\n}>;\n\ntype SqliteClientCarrier = Readonly<{\n $client?: SqliteClientWithPrepare;\n}>;\n\ntype SessionLike = Readonly<{\n constructor?: Readonly<{\n name?: string;\n }>;\n}>;\n\ntype DatabaseWithSession = Readonly<{\n _?: Readonly<{\n session?: SessionLike;\n }>;\n session?: SessionLike;\n}>;\n\n/**\n * Controls how the backend manages SQLite transactions.\n *\n * - `\"sql\"`: TypeGraph issues BEGIN / COMMIT / ROLLBACK SQL directly.\n * Default for sync drivers (better-sqlite3, bun:sqlite).\n * - `\"drizzle\"`: Delegates to Drizzle's `db.transaction()` method.\n * Default for async drivers (libsql, sql.js).\n * - `\"none\"`: Transactions disabled.\n * Default for Cloudflare D1 and Durable Objects.\n */\nexport type SqliteTransactionMode = \"sql\" | \"drizzle\" | \"none\";\n\nexport type SqliteExecutionProfileHints = Readonly<{\n isSync?: boolean;\n transactionMode?: SqliteTransactionMode;\n}>;\n\ntype SqliteExecutionAdapterOptions = Readonly<{\n profileHints?: SqliteExecutionProfileHints;\n statementCacheMax?: number;\n}>;\n\nexport type AnySqliteDatabase = BaseSQLiteDatabase<\"sync\" | \"async\", unknown>;\n\nexport type SqliteExecutionProfile = Readonly<{\n isSync: boolean;\n supportsCompiledExecution: boolean;\n transactionMode: SqliteTransactionMode;\n}>;\n\nexport type SqliteExecutionAdapter = Readonly<\n SqlExecutionAdapter & {\n clearStatementCache: () => void;\n profile: SqliteExecutionProfile;\n }\n>;\n\nfunction getSessionName(db: AnySqliteDatabase): string | undefined {\n const databaseWithSession = db as DatabaseWithSession;\n const primarySessionName = databaseWithSession.session?.constructor?.name;\n if (primarySessionName !== undefined) {\n return primarySessionName;\n }\n\n return databaseWithSession._?.session?.constructor?.name;\n}\n\nfunction isD1DatabaseBySessionName(db: AnySqliteDatabase): boolean {\n return getSessionName(db) === \"SQLiteD1Session\";\n}\n\nfunction isDurableObjectBySessionName(db: AnySqliteDatabase): boolean {\n const sessionName = getSessionName(db);\n return sessionName === \"SQLiteDurableObjectSession\";\n}\n\nfunction isSyncDatabaseBySessionName(db: AnySqliteDatabase): boolean {\n const sessionName = getSessionName(db);\n return (\n sessionName === \"BetterSQLiteSession\" || sessionName === \"BunSQLiteSession\"\n );\n}\n\nfunction detectSyncProfile(\n db: AnySqliteDatabase,\n profileHints: SqliteExecutionProfileHints,\n): boolean {\n if (profileHints.isSync !== undefined) {\n return profileHints.isSync;\n }\n\n const sessionName = getSessionName(db);\n if (sessionName === \"BetterSQLiteSession\" || sessionName === \"BunSQLiteSession\") {\n return true;\n }\n if (sessionName === \"SQLiteD1Session\") {\n return false;\n }\n\n try {\n const probeResult = db.get(sql`SELECT 1 AS __typegraph_sync_probe__`);\n return !(probeResult instanceof Promise);\n } catch {\n return isSyncDatabaseBySessionName(db);\n }\n}\n\nfunction detectTransactionMode(\n db: AnySqliteDatabase,\n profileHints: SqliteExecutionProfileHints,\n isSync: boolean,\n): SqliteTransactionMode {\n if (profileHints.transactionMode !== undefined) {\n return profileHints.transactionMode;\n }\n // D1 and Durable Object SQLite do not support raw BEGIN/COMMIT SQL\n // through Drizzle's db.run(). Default to \"none\" because async\n // transaction callbacks are not reliably supported across sync\n // Drizzle drivers. Users can opt in to \"drizzle\" mode explicitly if\n // their runtime's db.transaction() handles async callbacks.\n if (isD1DatabaseBySessionName(db) || isDurableObjectBySessionName(db)) {\n return \"none\";\n }\n if (isSync) return \"sql\";\n return \"drizzle\";\n}\n\nfunction resolveSqliteClient(\n db: AnySqliteDatabase,\n): SqliteClientWithPrepare | undefined {\n const databaseWithClient = db as SqliteClientCarrier;\n const sqliteClient = databaseWithClient.$client;\n if (sqliteClient?.prepare === undefined) {\n return undefined;\n }\n return sqliteClient;\n}\n\nfunction getOrCreatePreparedStatement(\n cache: Map<string, PreparedAllStatement>,\n sqliteClient: SqliteClientWithPrepare,\n sqlText: string,\n cacheMax: number,\n): PreparedAllStatement {\n return getOrCreateLru(cache, sqlText, cacheMax, () =>\n sqliteClient.prepare(sqlText),\n );\n}\n\n// Uses unconditional `await` because Drizzle returns SQLiteRaw thenables\n// that fail `instanceof Promise` checks (drizzle-team/drizzle-orm#2275).\nasync function executeDrizzleQuery<TRow>(\n db: AnySqliteDatabase,\n query: SQL,\n): Promise<readonly TRow[]> {\n return (await db.all(query));\n}\n\nfunction createPreparedStatementExecutor(\n sqliteClient: SqliteClientWithPrepare,\n cache: Map<string, PreparedAllStatement>,\n sqlText: string,\n cacheMax: number,\n): PreparedSqlStatement {\n return {\n execute<TRow>(params: readonly unknown[]): Promise<readonly TRow[]> {\n const preparedStatement = getOrCreatePreparedStatement(\n cache,\n sqliteClient,\n sqlText,\n cacheMax,\n );\n const rows = preparedStatement.all(...params);\n return Promise.resolve(rows as readonly TRow[]);\n },\n };\n}\n\nexport function createSqliteExecutionAdapter(\n db: AnySqliteDatabase,\n statementCacheMaxOrOptions: number | SqliteExecutionAdapterOptions = {},\n): SqliteExecutionAdapter {\n const options: SqliteExecutionAdapterOptions =\n typeof statementCacheMaxOrOptions === \"number\"\n ? { statementCacheMax: statementCacheMaxOrOptions }\n : statementCacheMaxOrOptions;\n const statementCacheMax =\n options.statementCacheMax ?? DEFAULT_PREPARED_STATEMENT_CACHE_MAX;\n const profileHints = options.profileHints ?? {};\n\n const isSync = detectSyncProfile(db, profileHints);\n const sqliteClient = isSync ? resolveSqliteClient(db) : undefined;\n const transactionMode = detectTransactionMode(db, profileHints, isSync);\n\n const profile: SqliteExecutionProfile = {\n isSync,\n supportsCompiledExecution: sqliteClient !== undefined,\n transactionMode,\n };\n\n const compile = (query: SQL): CompiledSqlQuery =>\n compileQueryWithDialect(db, query, \"SQLite\");\n\n if (sqliteClient !== undefined) {\n const client = sqliteClient;\n const statementCache = new Map<string, PreparedAllStatement>();\n\n function executeCompiled<TRow>(\n compiledQuery: CompiledSqlQuery,\n ): Promise<readonly TRow[]> {\n const preparedStatement = getOrCreatePreparedStatement(\n statementCache,\n client,\n compiledQuery.sql,\n statementCacheMax,\n );\n const rows = preparedStatement.all(...compiledQuery.params);\n return Promise.resolve(rows as readonly TRow[]);\n }\n\n return {\n clearStatementCache() {\n statementCache.clear();\n },\n compile,\n execute<TRow>(query: SQL): Promise<readonly TRow[]> {\n const compiledQuery = compile(query);\n return executeCompiled<TRow>(compiledQuery);\n },\n executeCompiled,\n prepare(sqlText: string): PreparedSqlStatement {\n return createPreparedStatementExecutor(\n client,\n statementCache,\n sqlText,\n statementCacheMax,\n );\n },\n profile,\n };\n }\n\n return {\n clearStatementCache() {\n // No-op: no statement cache in async/D1 mode\n },\n compile,\n execute<TRow>(query: SQL): Promise<readonly TRow[]> {\n return executeDrizzleQuery<TRow>(db, query);\n },\n profile,\n };\n}\n","/**\n * SQLite backend adapter for TypeGraph.\n *\n * Works with any Drizzle SQLite database instance:\n * - better-sqlite3\n * - libsql / Turso\n * - Cloudflare D1\n * - bun:sqlite\n * - sql.js\n *\n * @example\n * ```typescript\n * import { drizzle } from \"drizzle-orm/better-sqlite3\";\n * import Database from \"better-sqlite3\";\n * import { createSqliteBackend, tables } from \"@nicia-ai/typegraph/sqlite\";\n *\n * const sqlite = new Database(\"app.db\");\n * const db = drizzle(sqlite);\n * const backend = createSqliteBackend(db, { tables });\n * ```\n */\nimport {\n and,\n eq,\n getTableName,\n inArray,\n isNull,\n type SQL,\n sql,\n} from \"drizzle-orm\";\n\nimport { BackendDisposedError, ConfigurationError } from \"../../errors\";\nimport type { SqlTableNames } from \"../../query/compiler/schema\";\nimport {\n buildFulltextCapabilities,\n fts5Strategy,\n type FulltextStrategy,\n} from \"../../query/dialect/fulltext-strategy\";\nimport {\n type BackendCapabilities,\n type CommitSchemaVersionParams,\n type CreateVectorIndexParams,\n type DeleteEmbeddingParams,\n type DeleteFulltextBatchParams,\n type DeleteFulltextParams,\n type DropVectorIndexParams,\n type FulltextSearchParams,\n type FulltextSearchResult,\n type GraphBackend,\n type IndexMaterializationRow,\n type KindRemovalRow,\n type RecordIndexMaterializationParams,\n type RecordKindRemovalParams,\n type SchemaVersionRow,\n type SetActiveVersionParams,\n SQLITE_CAPABILITIES,\n type TransactionBackend,\n type TransactionOptions,\n type UpsertEmbeddingParams,\n type UpsertFulltextBatchParams,\n type UpsertFulltextParams,\n type VectorSearchParams,\n type VectorSearchResult,\n} from \"../types\";\nimport {\n type AnySqliteDatabase,\n createSqliteExecutionAdapter,\n type SqliteExecutionAdapter,\n type SqliteExecutionProfileHints,\n} from \"./execution/sqlite-execution\";\nexport type { SqliteTransactionMode } from \"./execution/sqlite-execution\";\nimport { generateSqliteCreateTableSQL, generateSqliteDDL } from \"./ddl\";\nimport {\n buildMaterializationInsertValues,\n buildMaterializationOnConflictSet,\n mapMaterializationRow,\n SQLITE_INDEX_MAT_TIMESTAMPS,\n} from \"./index-materializations\";\nimport {\n buildKindRemovalInsertValues,\n buildKindRemovalOnConflictSet,\n mapKindRemovalRow,\n SQLITE_KIND_REMOVAL_TIMESTAMPS,\n} from \"./kind-removals\";\nimport {\n type CommonOperationBackend,\n createCommonOperationBackend,\n} from \"./operation-backend-core\";\nimport { createSqliteOperationStrategy } from \"./operations/strategy\";\nimport {\n createEdgeRowMapper,\n createNodeRowMapper,\n createSchemaVersionRowMapper,\n createUniqueRowMapper,\n nowIso,\n SQLITE_ROW_MAPPER_CONFIG,\n} from \"./row-mappers\";\nimport { type SqliteTables, tables as defaultTables } from \"./schema/sqlite\";\nimport {\n createSqliteVectorIndex,\n dropSqliteVectorIndex,\n type VectorIndexOptions,\n} from \"./vector-index\";\n\n// ============================================================\n// Types\n// ============================================================\n\n/**\n * Options for creating a SQLite backend.\n */\nexport type SqliteBackendOptions = Readonly<{\n /**\n * Custom table definitions. Use createSqliteTables() to customize table names.\n * Defaults to standard TypeGraph table names.\n */\n tables?: SqliteTables;\n /**\n * Optional execution profile hints used to avoid runtime driver reflection.\n * Set `transactionMode: \"none\"` for drivers that do not support transactions\n * (e.g. Cloudflare D1, Durable Objects).\n */\n executionProfile?: SqliteExecutionProfileHints;\n /**\n * Fulltext strategy override. Defaults to `fts5Strategy` (SQLite's\n * built-in FTS5 virtual table). Most users should leave this alone.\n */\n fulltext?: FulltextStrategy;\n /**\n * Set to `true` when sqlite-vec has been loaded on the connection.\n * Enables vector embedding persistence via `upsertEmbedding` /\n * `deleteEmbedding`, which the store's embedding-sync path relies on\n * whenever node schemas declare `embedding()` fields. When omitted the\n * backend does not expose those methods and embedding values pass\n * through writes without being indexed — matching existing behavior\n * for backends without sqlite-vec. `createLocalSqliteBackend` sets\n * this automatically when it loads the extension.\n */\n hasVectorEmbeddings?: boolean;\n}>;\n\nconst SQLITE_MAX_BIND_PARAMETERS = 999;\nconst NODE_INSERT_PARAM_COUNT = 9;\nconst EDGE_INSERT_PARAM_COUNT = 12;\nconst SQLITE_NODE_INSERT_BATCH_SIZE = Math.max(\n 1,\n Math.floor(SQLITE_MAX_BIND_PARAMETERS / NODE_INSERT_PARAM_COUNT),\n);\nconst SQLITE_EDGE_INSERT_BATCH_SIZE = Math.max(\n 1,\n Math.floor(SQLITE_MAX_BIND_PARAMETERS / EDGE_INSERT_PARAM_COUNT),\n);\nconst SQLITE_GET_NODES_ID_CHUNK_SIZE = Math.max(\n 1,\n SQLITE_MAX_BIND_PARAMETERS - 2,\n);\nconst SQLITE_GET_EDGES_ID_CHUNK_SIZE = Math.max(\n 1,\n SQLITE_MAX_BIND_PARAMETERS - 1,\n);\nconst CHECK_UNIQUE_BATCH_FIXED_PARAM_COUNT = 3;\nconst SQLITE_CHECK_UNIQUE_BATCH_CHUNK_SIZE = Math.max(\n 1,\n SQLITE_MAX_BIND_PARAMETERS - CHECK_UNIQUE_BATCH_FIXED_PARAM_COUNT,\n);\n\ntype SerializedExecutionQueue = Readonly<{\n dispose: () => void;\n runExclusive: <T>(task: () => Promise<T>) => Promise<T>;\n}>;\n\n// ============================================================\n// Utilities\n// ============================================================\n\nconst toNodeRow = createNodeRowMapper(SQLITE_ROW_MAPPER_CONFIG);\nconst toEdgeRow = createEdgeRowMapper(SQLITE_ROW_MAPPER_CONFIG);\nconst toUniqueRow = createUniqueRowMapper(SQLITE_ROW_MAPPER_CONFIG);\nconst toSchemaVersionRow = createSchemaVersionRowMapper(SQLITE_ROW_MAPPER_CONFIG);\n\n/** A shared promise that never settles — used to absorb post-dispose work. */\nconst PENDING_FOREVER: Promise<never> = new Promise<never>(noop);\n\nfunction pendingForever<T>(): Promise<T> {\n return PENDING_FOREVER;\n}\n\n// eslint-disable-next-line @typescript-eslint/no-empty-function\nfunction noop(): void {}\n\nfunction createSerializedExecutionQueue(): SerializedExecutionQueue {\n let tail: Promise<unknown> = Promise.resolve();\n let disposed = false;\n\n function isDisposed(): boolean {\n return disposed;\n }\n\n return {\n dispose() {\n disposed = true;\n },\n\n runExclusive<T>(task: () => Promise<T>): Promise<T> {\n if (isDisposed()) return Promise.reject(new BackendDisposedError());\n\n // When disposed, runTask returns a never-settling promise so that no\n // rejection propagates through the 7+ async wrappers between this\n // queue and the store-level caller. A rejection here would become an\n // unhandled rejection if the caller abandoned the promise during\n // teardown — and JavaScript offers no way to `.catch()` a rejection\n // at the bottom of a chain without every async wrapper above it also\n // creating an independently-unhandled rejected promise.\n //\n // The tradeoff: an active caller whose operation was queued before\n // dispose() will see a permanently-pending promise rather than a\n // BackendDisposedError. Post-dispose submissions (the check above)\n // still reject immediately since the caller actively holds that\n // promise.\n const runTask = async (): Promise<T> => {\n if (isDisposed()) return pendingForever<T>();\n try {\n return await task();\n } catch (error) {\n if (isDisposed()) return pendingForever<T>();\n throw error;\n }\n };\n const result = tail.then(runTask, runTask);\n tail = result.then(\n () => 0,\n () => 0,\n );\n return result;\n },\n };\n}\n\nfunction runWithSerializedQueue<T>(\n queue: SerializedExecutionQueue | undefined,\n task: () => Promise<T>,\n): Promise<T> {\n if (queue === undefined) return task();\n return queue.runExclusive(task);\n}\n\n// sqlite-vec exposes vec_distance_cosine and vec_distance_l2 but has no\n// vec_distance_ip — keep this list aligned with the SQLite dialect's\n// vectorMetrics so query compilation and capability advertising agree.\nconst SQLITE_VECTOR_METRICS = [\"cosine\", \"l2\"] as const;\n// sqlite-vec doesn't expose explicit index types (vec0 manages indexing\n// internally); createSqliteVectorIndex is a no-op. \"none\" matches that\n// reality without claiming HNSW/IVFFlat support we don't have.\nconst SQLITE_VECTOR_INDEX_TYPES = [\"none\"] as const;\n// sqlite-vec's vec_f32 has no documented hard cap, but practical ANN\n// performance degrades well before pgvector's 16k limit. 8000 is a\n// conservative ceiling consistent with the extension's typical use.\nconst SQLITE_VECTOR_MAX_DIMENSIONS = 8000;\n\nfunction buildSqliteCapabilities(\n options: Readonly<{\n fulltextStrategy: FulltextStrategy;\n hasVectorEmbeddings: boolean;\n transactionMode: SqliteExecutionAdapter[\"profile\"][\"transactionMode\"];\n }>,\n): BackendCapabilities {\n const base =\n options.transactionMode === \"none\"\n ? { ...SQLITE_CAPABILITIES, transactions: false }\n : SQLITE_CAPABILITIES;\n return {\n ...base,\n fulltext: buildFulltextCapabilities(options.fulltextStrategy),\n ...(options.hasVectorEmbeddings\n ? {\n vector: {\n supported: true,\n metrics: SQLITE_VECTOR_METRICS,\n indexTypes: SQLITE_VECTOR_INDEX_TYPES,\n maxDimensions: SQLITE_VECTOR_MAX_DIMENSIONS,\n },\n }\n : {}),\n };\n}\n\n// ============================================================\n// Backend Factory\n// ============================================================\n\n/**\n * Creates a TypeGraph backend for SQLite databases.\n *\n * Works with any Drizzle SQLite instance regardless of the underlying driver.\n *\n * @param db - A Drizzle SQLite database instance\n * @param options - Backend configuration\n * @returns A GraphBackend implementation\n */\ntype CreateSqliteOperationBackendOptions = Readonly<{\n capabilities: GraphBackend[\"capabilities\"];\n db: AnySqliteDatabase;\n executionAdapter: SqliteExecutionAdapter;\n operationStrategy: ReturnType<typeof createSqliteOperationStrategy>;\n serializedQueue?: SerializedExecutionQueue;\n tableNames: SqlTableNames;\n fulltextStrategy: FulltextStrategy;\n /** Wire up upsertEmbedding / deleteEmbedding. See transaction options for details. */\n hasVectorEmbeddings?: boolean;\n}>;\n\ntype CreateSqliteTransactionBackendOptions = Readonly<{\n capabilities: GraphBackend[\"capabilities\"];\n db: AnySqliteDatabase;\n executionAdapter?: SqliteExecutionAdapter;\n operationStrategy: ReturnType<typeof createSqliteOperationStrategy>;\n profileHints: SqliteExecutionProfileHints;\n tableNames: SqlTableNames;\n fulltextStrategy: FulltextStrategy;\n /**\n * When true, the backend exposes upsertEmbedding / deleteEmbedding —\n * detected by probing `vec_f32(...)` on the connection at boot so the\n * store's embedding-sync path persists vectors to the embeddings table.\n */\n hasVectorEmbeddings?: boolean;\n}>;\n\nfunction createSqliteOperationBackend(\n options: CreateSqliteOperationBackendOptions,\n): TransactionBackend {\n const {\n capabilities,\n db,\n executionAdapter,\n operationStrategy,\n serializedQueue,\n tableNames,\n fulltextStrategy,\n } = options;\n\n function execGet<T>(query: SQL): Promise<T | undefined> {\n // Workaround: drizzle-team/drizzle-orm#1049 — db.get() crashes with\n // the libsql driver when no rows match (normalizeRow receives undefined).\n // Using db.all()[0] avoids the crash for all drivers.\n //\n // All three exec helpers use `await` unconditionally rather than\n // `instanceof Promise` because Drizzle returns SQLiteRaw thenables\n // that are NOT Promise instances (drizzle-team/drizzle-orm#2275).\n return runWithSerializedQueue(serializedQueue, async () => {\n const rows = await db.all(query);\n return (rows as T[])[0];\n });\n }\n\n function execAll<T>(query: SQL): Promise<T[]> {\n return runWithSerializedQueue(serializedQueue, async () => {\n return await db.all(query);\n });\n }\n\n function execRun(query: SQL): Promise<void> {\n return runWithSerializedQueue(serializedQueue, async () => {\n await db.run(query);\n });\n }\n\n const commonBackend = createCommonOperationBackend({\n batchConfig: {\n checkUniqueBatchChunkSize: SQLITE_CHECK_UNIQUE_BATCH_CHUNK_SIZE,\n edgeInsertBatchSize: SQLITE_EDGE_INSERT_BATCH_SIZE,\n getEdgesChunkSize: SQLITE_GET_EDGES_ID_CHUNK_SIZE,\n getNodesChunkSize: SQLITE_GET_NODES_ID_CHUNK_SIZE,\n nodeInsertBatchSize: SQLITE_NODE_INSERT_BATCH_SIZE,\n },\n execution: {\n execAll,\n execGet,\n execRun,\n },\n nowIso,\n operationStrategy,\n rowMappers: {\n toEdgeRow,\n toNodeRow,\n toSchemaVersionRow,\n toUniqueRow,\n },\n });\n\n const executeCompiled = executionAdapter.executeCompiled;\n const executeRawMethod: Pick<TransactionBackend, \"executeRaw\"> =\n executeCompiled === undefined ?\n {}\n : {\n executeRaw<T>(\n sqlText: string,\n params: readonly unknown[],\n ): Promise<readonly T[]> {\n return runWithSerializedQueue(serializedQueue, async () =>\n executeCompiled<T>({ params, sql: sqlText }),\n );\n },\n };\n\n const vectorEmbeddingMethods =\n options.hasVectorEmbeddings\n ? {\n async upsertEmbedding(params: UpsertEmbeddingParams): Promise<void> {\n const query = operationStrategy.buildUpsertEmbedding(\n params,\n nowIso(),\n );\n await execRun(query);\n },\n async deleteEmbedding(params: DeleteEmbeddingParams): Promise<void> {\n const query = operationStrategy.buildDeleteEmbedding(params);\n await execRun(query);\n },\n async vectorSearch(\n params: VectorSearchParams,\n ): Promise<readonly VectorSearchResult[]> {\n const query = operationStrategy.buildVectorSearch(params);\n const rows = await execAll<{ node_id: string; score: number }>(\n query,\n );\n return rows.map((row) => ({\n nodeId: row.node_id,\n score: row.score,\n }));\n },\n }\n : {};\n\n const operationBackend: TransactionBackend = {\n ...commonBackend,\n ...executeRawMethod,\n ...vectorEmbeddingMethods,\n capabilities,\n dialect: \"sqlite\",\n tableNames,\n fulltextStrategy,\n\n createVectorIndex(params: CreateVectorIndexParams): Promise<void> {\n const indexOptions: VectorIndexOptions = {\n graphId: params.graphId,\n nodeKind: params.nodeKind,\n fieldPath: params.fieldPath,\n dimensions: params.dimensions,\n indexType: params.indexType,\n metric: params.metric,\n ...(params.indexParams?.m === undefined\n ? {}\n : { hnswM: params.indexParams.m }),\n ...(params.indexParams?.efConstruction === undefined\n ? {}\n : { hnswEfConstruction: params.indexParams.efConstruction }),\n ...(params.indexParams?.lists === undefined\n ? {}\n : { ivfflatLists: params.indexParams.lists }),\n };\n\n const result = createSqliteVectorIndex(indexOptions);\n\n if (!result.success) {\n throw new Error(result.message ?? \"Failed to create SQLite vector index\");\n }\n return Promise.resolve();\n },\n\n dropVectorIndex(params: DropVectorIndexParams): Promise<void> {\n const result = dropSqliteVectorIndex(\n params.graphId,\n params.nodeKind,\n params.fieldPath,\n );\n if (!result.success) {\n throw new Error(result.message ?? \"Failed to drop SQLite vector index\");\n }\n return Promise.resolve();\n },\n\n // === Fulltext Operations ===\n\n async upsertFulltext(params: UpsertFulltextParams): Promise<void> {\n const timestamp = nowIso();\n const statements = operationStrategy.buildUpsertFulltext(\n params,\n timestamp,\n );\n for (const stmt of statements) {\n await execRun(stmt);\n }\n },\n\n async deleteFulltext(params: DeleteFulltextParams): Promise<void> {\n const statements = operationStrategy.buildDeleteFulltext(params);\n for (const stmt of statements) {\n await execRun(stmt);\n }\n },\n\n async upsertFulltextBatch(\n params: UpsertFulltextBatchParams,\n ): Promise<void> {\n if (params.rows.length === 0) return;\n const timestamp = nowIso();\n const statements = operationStrategy.buildUpsertFulltextBatch(\n params,\n timestamp,\n );\n for (const stmt of statements) {\n await execRun(stmt);\n }\n },\n\n async deleteFulltextBatch(\n params: DeleteFulltextBatchParams,\n ): Promise<void> {\n if (params.nodeIds.length === 0) return;\n const statements = operationStrategy.buildDeleteFulltextBatch(params);\n for (const stmt of statements) {\n await execRun(stmt);\n }\n },\n\n async fulltextSearch(\n params: FulltextSearchParams,\n ): Promise<readonly FulltextSearchResult[]> {\n const query = operationStrategy.buildFulltextSearch(params);\n const rows = await execAll<{\n node_id: string;\n score: number;\n snippet: string | null;\n }>(query);\n return rows.map((row, index) => ({\n nodeId: row.node_id,\n score: row.score,\n rank: index + 1,\n ...(row.snippet === null ? {} : { snippet: row.snippet }),\n }));\n },\n\n // === Query Execution ===\n\n async execute<T>(query: SQL): Promise<readonly T[]> {\n return runWithSerializedQueue(serializedQueue, async () =>\n executionAdapter.execute<T>(query),\n );\n },\n\n compileSql(query: SQL): Readonly<{ sql: string; params: readonly unknown[] }> {\n return executionAdapter.compile(query);\n },\n };\n\n return operationBackend;\n}\n\nexport function createSqliteBackend(\n db: AnySqliteDatabase,\n options: SqliteBackendOptions = {},\n): GraphBackend {\n const tables = options.tables ?? defaultTables;\n const fulltextStrategy = options.fulltext ?? fts5Strategy;\n const profileHints = options.executionProfile ?? {};\n const executionAdapter = createSqliteExecutionAdapter(db, { profileHints });\n const { isSync, transactionMode } = executionAdapter.profile;\n // Explicit opt-in: wire upsertEmbedding / deleteEmbedding only when\n // the caller confirms sqlite-vec is loaded. Probing synchronously\n // isn't portable across drizzle SQLite drivers (sync vs async), so\n // the gate lives with the caller that loaded the extension.\n const hasVectorEmbeddings = options.hasVectorEmbeddings === true;\n const capabilities: BackendCapabilities = buildSqliteCapabilities({\n fulltextStrategy,\n hasVectorEmbeddings,\n transactionMode,\n });\n\n const tableNames: SqlTableNames = {\n nodes: getTableName(tables.nodes),\n edges: getTableName(tables.edges),\n embeddings: getTableName(tables.embeddings),\n fulltext: tables.fulltextTableName,\n uniques: getTableName(tables.uniques),\n };\n const operationStrategy = createSqliteOperationStrategy(\n tables,\n fulltextStrategy,\n );\n const serializedQueue = isSync ? createSerializedExecutionQueue() : undefined;\n const operations = createSqliteOperationBackend({\n capabilities,\n db,\n executionAdapter,\n operationStrategy,\n tableNames,\n fulltextStrategy,\n hasVectorEmbeddings,\n ...(serializedQueue === undefined ? {} : { serializedQueue }),\n });\n\n /**\n * Runs `fn` inside a SQLite write transaction (BEGIN IMMEDIATE) so that\n * the read-then-write inside `commitSchemaVersion` / `setActiveVersion`\n * is serialized against concurrent writers — a deferred BEGIN would let\n * two transactions race past the CAS read and one would later fail\n * with SQLITE_BUSY instead of producing a clean StaleVersionError.\n *\n * Refuses on `transactionMode: \"none\"`. The orphan-row crash window\n * cannot be eliminated without atomicity.\n */\n function runSchemaWriteTransaction<T>(\n fn: (tx: CommonOperationBackend) => Promise<T>,\n ): Promise<T> {\n if (transactionMode === \"none\") {\n throw new ConfigurationError(\n \"commitSchemaVersion and setActiveVersion require atomic transactions, \" +\n \"but this SQLite backend has transactions disabled. Configure a \" +\n \"driver that supports transactions (better-sqlite3, libsql, \" +\n \"bun:sqlite) to use schema commits.\",\n {\n backend: \"sqlite\",\n capability: \"transactions\",\n supportsTransactions: false,\n },\n );\n }\n\n if (transactionMode === \"sql\") {\n return runWithSerializedQueue(serializedQueue, async () => {\n // The runtime object returned by createTransactionBackend always\n // implements commitSchemaVersion / setActiveVersion (they live in\n // the operation-backend-core impl); the public TransactionBackend\n // type omits them so user-supplied transaction() callbacks can't\n // bypass the locking wrapper. Cast back to the wider internal\n // shape here, where the locking IS being applied.\n const txBackend = createTransactionBackend({\n capabilities,\n db,\n executionAdapter,\n operationStrategy,\n profileHints: { isSync: true },\n tableNames,\n fulltextStrategy,\n hasVectorEmbeddings,\n }) as unknown as CommonOperationBackend;\n db.run(sql`BEGIN IMMEDIATE`);\n try {\n const result = await fn(txBackend);\n db.run(sql`COMMIT`);\n return result;\n } catch (error) {\n db.run(sql`ROLLBACK`);\n throw error;\n }\n });\n }\n\n // transactionMode === \"drizzle\". Drizzle's sqlite-core transaction\n // accepts a `behavior` option that maps to BEGIN / BEGIN IMMEDIATE /\n // BEGIN EXCLUSIVE; \"immediate\" is what we need to acquire a reserved\n // write lock at the start of the transaction.\n return runWithSerializedQueue(serializedQueue, async () =>\n db.transaction(async (tx) => {\n const txBackend = createTransactionBackend({\n capabilities,\n db: tx,\n operationStrategy,\n profileHints: { isSync },\n tableNames,\n fulltextStrategy,\n hasVectorEmbeddings,\n }) as unknown as CommonOperationBackend;\n return fn(txBackend);\n }, { behavior: \"immediate\" }) as Promise<T>,\n );\n }\n\n // Per-backend latch for fulltext-table DDL. The wrappers below\n // guard every method that touches the fulltext table — fulltext\n // writes can fire from any code path (sync `createStore`, hard-\n // delete cascade, batched index sync), so the bootstrap-load\n // probe alone doesn't cover all surfaces.\n let fulltextEnsured = false;\n async function ensureFulltextDdl(): Promise<void> {\n if (fulltextEnsured) return;\n for (const statement of fulltextStrategy.generateDdl(\n tables.fulltextTableName,\n )) {\n await db.run(sql.raw(statement));\n }\n fulltextEnsured = true;\n }\n\n const backend: GraphBackend = {\n ...operations,\n\n async bootstrapTables(): Promise<void> {\n const statements = generateSqliteDDL(tables, fulltextStrategy);\n for (const statement of statements) {\n await db.run(sql.raw(statement));\n }\n fulltextEnsured = true;\n },\n\n async upsertFulltext(params): Promise<void> {\n await ensureFulltextDdl();\n await operations.upsertFulltext!(params);\n },\n async deleteFulltext(params): Promise<void> {\n await ensureFulltextDdl();\n await operations.deleteFulltext!(params);\n },\n async upsertFulltextBatch(params): Promise<void> {\n // Mirror the inner-method empty-input guard so a no-op call\n // on a cold backend doesn't materialize the table.\n if (params.rows.length === 0) return;\n await ensureFulltextDdl();\n await operations.upsertFulltextBatch!(params);\n },\n async deleteFulltextBatch(params): Promise<void> {\n if (params.nodeIds.length === 0) return;\n await ensureFulltextDdl();\n await operations.deleteFulltextBatch!(params);\n },\n async fulltextSearch(params) {\n await ensureFulltextDdl();\n return operations.fulltextSearch!(params);\n },\n // hardDeleteNode is wrapped because the operation-backend-core\n // cascade unconditionally deletes from the fulltext table — it\n // would fail even on graphs that declare no searchable() fields.\n async hardDeleteNode(params): Promise<void> {\n await ensureFulltextDdl();\n await operations.hardDeleteNode(params);\n },\n\n async executeDdl(ddl: string): Promise<void> {\n await db.run(sql.raw(ddl));\n },\n\n async ensureIndexMaterializationsTable(): Promise<void> {\n await db.run(\n sql.raw(generateSqliteCreateTableSQL(tables.indexMaterializations)),\n );\n },\n\n async getIndexMaterialization(\n indexName: string,\n ): Promise<IndexMaterializationRow | undefined> {\n const t = tables.indexMaterializations;\n const rows = await db.select().from(t).where(eq(t.indexName, indexName));\n const row = rows[0];\n if (row === undefined) return undefined;\n return mapMaterializationRow(row, SQLITE_INDEX_MAT_TIMESTAMPS.decode);\n },\n\n async getIndexMaterializations(\n statusKeys: readonly string[],\n ): Promise<readonly IndexMaterializationRow[]> {\n if (statusKeys.length === 0) return [];\n const t = tables.indexMaterializations;\n const rows = await db\n .select()\n .from(t)\n .where(inArray(t.indexName, [...statusKeys]));\n return rows.map((row) =>\n mapMaterializationRow(row, SQLITE_INDEX_MAT_TIMESTAMPS.decode),\n );\n },\n\n async recordIndexMaterialization(\n params: RecordIndexMaterializationParams,\n ): Promise<void> {\n const t = tables.indexMaterializations;\n await db\n .insert(t)\n .values(\n buildMaterializationInsertValues(\n params,\n SQLITE_INDEX_MAT_TIMESTAMPS.encode,\n ),\n )\n .onConflictDoUpdate({\n target: t.indexName,\n set: buildMaterializationOnConflictSet(\n t.materializedAt,\n params.materializedAt,\n ),\n });\n },\n\n async ensureKindRemovalsTable(): Promise<void> {\n await db.run(sql.raw(generateSqliteCreateTableSQL(tables.kindRemovals)));\n },\n\n async getPendingKindRemovals(\n graphId: string,\n ): Promise<readonly KindRemovalRow[]> {\n const t = tables.kindRemovals;\n const rows = await db\n .select()\n .from(t)\n .where(and(eq(t.graphId, graphId), isNull(t.removedAt)));\n return rows.map((row) =>\n mapKindRemovalRow(row, SQLITE_KIND_REMOVAL_TIMESTAMPS.decode),\n );\n },\n\n async getAllKindRemovals(\n graphId: string,\n ): Promise<readonly KindRemovalRow[]> {\n const t = tables.kindRemovals;\n const rows = await db.select().from(t).where(eq(t.graphId, graphId));\n return rows.map((row) =>\n mapKindRemovalRow(row, SQLITE_KIND_REMOVAL_TIMESTAMPS.decode),\n );\n },\n\n async recordKindRemoval(params: RecordKindRemovalParams): Promise<void> {\n const t = tables.kindRemovals;\n await db\n .insert(t)\n .values(\n buildKindRemovalInsertValues(\n params,\n SQLITE_KIND_REMOVAL_TIMESTAMPS.encode,\n ),\n )\n .onConflictDoUpdate({\n target: [t.graphId, t.kindName, t.entity, t.schemaVersion],\n set: buildKindRemovalOnConflictSet(t.removedAt, params.removedAt),\n });\n },\n\n async ensureReconciliationMarkersTable(): Promise<void> {\n await db.run(\n sql.raw(generateSqliteCreateTableSQL(tables.reconciliationMarkers)),\n );\n },\n\n async ensureFulltextTable(): Promise<void> {\n await ensureFulltextDdl();\n },\n\n async getReconciliationMarker(\n graphId: string,\n ): Promise<number | undefined> {\n const t = tables.reconciliationMarkers;\n const rows = await db.select().from(t).where(eq(t.graphId, graphId));\n return rows[0]?.reconciledToVersion;\n },\n\n async setReconciliationMarker(\n graphId: string,\n version: number,\n ): Promise<void> {\n const t = tables.reconciliationMarkers;\n await db\n .insert(t)\n .values({ graphId, reconciledToVersion: version })\n .onConflictDoUpdate({\n target: t.graphId,\n set: { reconciledToVersion: version },\n });\n },\n\n async refreshStatistics(): Promise<void> {\n // `ANALYZE` populates `sqlite_stat1`. With no stat table, the\n // planner falls back to heuristics that, at least for FTS5\n // virtual-table queries and multi-column index selection, can be\n // an order of magnitude slower. Running it explicitly makes the\n // planner data-driven.\n await db.run(sql`ANALYZE`);\n },\n\n async commitSchemaVersion(\n params: CommitSchemaVersionParams,\n ): Promise<SchemaVersionRow> {\n return runSchemaWriteTransaction((target) =>\n target.commitSchemaVersion(params),\n );\n },\n\n async setActiveVersion(params: SetActiveVersionParams): Promise<void> {\n await runSchemaWriteTransaction((target) =>\n target.setActiveVersion(params),\n );\n },\n\n async transaction<T>(\n fn: (tx: TransactionBackend) => Promise<T>,\n _options?: TransactionOptions,\n ): Promise<T> {\n if (transactionMode === \"none\") {\n throw new ConfigurationError(\n \"This SQLite backend does not support atomic transactions. \" +\n \"Operations within a transaction are not rolled back on failure. \" +\n \"Use backend.capabilities.transactions to check for transaction support, \" +\n \"or use individual operations with manual error handling.\",\n {\n backend: \"sqlite\",\n capability: \"transactions\",\n supportsTransactions: false,\n },\n );\n }\n\n // The tx-scoped backend exposes raw fulltext methods without\n // the outer self-ensure wrappers — so we do the ensure here,\n // before BEGIN runs. Outside-the-tx avoids\n // CREATE-INDEX-inside-tx lock contention and keeps the DDL\n // durable if the user's tx rolls back.\n await ensureFulltextDdl();\n\n if (transactionMode === \"sql\") {\n return runWithSerializedQueue(serializedQueue, async () => {\n const txBackend = createTransactionBackend({\n capabilities,\n db,\n executionAdapter,\n operationStrategy,\n profileHints: { isSync: true },\n tableNames,\n fulltextStrategy,\n hasVectorEmbeddings,\n });\n db.run(sql`BEGIN`);\n\n try {\n const result = await fn(txBackend);\n db.run(sql`COMMIT`);\n return result;\n } catch (error) {\n db.run(sql`ROLLBACK`);\n throw error;\n }\n });\n }\n\n // transactionMode === \"drizzle\"\n return runWithSerializedQueue(serializedQueue, async () =>\n db.transaction(async (tx) => {\n const txBackend = createTransactionBackend({\n capabilities,\n db: tx,\n operationStrategy,\n profileHints: { isSync },\n tableNames,\n fulltextStrategy,\n hasVectorEmbeddings,\n });\n return fn(txBackend);\n }) as Promise<T>,\n );\n },\n\n close(): Promise<void> {\n serializedQueue?.dispose();\n return Promise.resolve();\n },\n };\n\n return backend;\n}\n\nfunction createTransactionBackend(\n options: CreateSqliteTransactionBackendOptions,\n): TransactionBackend {\n const txExecutionAdapter =\n options.executionAdapter ??\n createSqliteExecutionAdapter(options.db, {\n profileHints: options.profileHints,\n });\n\n return createSqliteOperationBackend({\n capabilities: options.capabilities,\n db: options.db,\n executionAdapter: txExecutionAdapter,\n operationStrategy: options.operationStrategy,\n tableNames: options.tableNames,\n fulltextStrategy: options.fulltextStrategy,\n ...(options.hasVectorEmbeddings === undefined\n ? {}\n : { hasVectorEmbeddings: options.hasVectorEmbeddings }),\n });\n}\n\n// Re-export schema utilities\nexport type { SqliteTableNames,SqliteTables } from \"./schema/sqlite\";\nexport { createSqliteTables, tables } from \"./schema/sqlite\";\n"]}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
var
|
|
4
|
-
var
|
|
3
|
+
var chunkCQVNGKU7_cjs = require('./chunk-CQVNGKU7.cjs');
|
|
4
|
+
var chunkOECDVACY_cjs = require('./chunk-OECDVACY.cjs');
|
|
5
5
|
var chunkJTI5WT4P_cjs = require('./chunk-JTI5WT4P.cjs');
|
|
6
6
|
var chunkW5MTHMTE_cjs = require('./chunk-W5MTHMTE.cjs');
|
|
7
7
|
var drizzleOrm = require('drizzle-orm');
|
|
@@ -63,7 +63,7 @@ function resolveSqliteClient(db) {
|
|
|
63
63
|
return sqliteClient;
|
|
64
64
|
}
|
|
65
65
|
function getOrCreatePreparedStatement(cache, sqliteClient, sqlText, cacheMax) {
|
|
66
|
-
return
|
|
66
|
+
return chunkCQVNGKU7_cjs.getOrCreateLru(
|
|
67
67
|
cache,
|
|
68
68
|
sqlText,
|
|
69
69
|
cacheMax,
|
|
@@ -99,7 +99,7 @@ function createSqliteExecutionAdapter(db, statementCacheMaxOrOptions = {}) {
|
|
|
99
99
|
supportsCompiledExecution: sqliteClient !== void 0,
|
|
100
100
|
transactionMode
|
|
101
101
|
};
|
|
102
|
-
const compile = (query) =>
|
|
102
|
+
const compile = (query) => chunkCQVNGKU7_cjs.compileQueryWithDialect(db, query, "SQLite");
|
|
103
103
|
if (sqliteClient !== void 0) {
|
|
104
104
|
let executeCompiled2 = function(compiledQuery) {
|
|
105
105
|
const preparedStatement = getOrCreatePreparedStatement(
|
|
@@ -170,10 +170,10 @@ var SQLITE_CHECK_UNIQUE_BATCH_CHUNK_SIZE = Math.max(
|
|
|
170
170
|
1,
|
|
171
171
|
SQLITE_MAX_BIND_PARAMETERS - CHECK_UNIQUE_BATCH_FIXED_PARAM_COUNT
|
|
172
172
|
);
|
|
173
|
-
var toNodeRow =
|
|
174
|
-
var toEdgeRow =
|
|
175
|
-
var toUniqueRow =
|
|
176
|
-
var toSchemaVersionRow =
|
|
173
|
+
var toNodeRow = chunkCQVNGKU7_cjs.createNodeRowMapper(chunkCQVNGKU7_cjs.SQLITE_ROW_MAPPER_CONFIG);
|
|
174
|
+
var toEdgeRow = chunkCQVNGKU7_cjs.createEdgeRowMapper(chunkCQVNGKU7_cjs.SQLITE_ROW_MAPPER_CONFIG);
|
|
175
|
+
var toUniqueRow = chunkCQVNGKU7_cjs.createUniqueRowMapper(chunkCQVNGKU7_cjs.SQLITE_ROW_MAPPER_CONFIG);
|
|
176
|
+
var toSchemaVersionRow = chunkCQVNGKU7_cjs.createSchemaVersionRowMapper(chunkCQVNGKU7_cjs.SQLITE_ROW_MAPPER_CONFIG);
|
|
177
177
|
var PENDING_FOREVER = new Promise(noop);
|
|
178
178
|
function pendingForever() {
|
|
179
179
|
return PENDING_FOREVER;
|
|
@@ -218,7 +218,7 @@ var SQLITE_VECTOR_METRICS = ["cosine", "l2"];
|
|
|
218
218
|
var SQLITE_VECTOR_INDEX_TYPES = ["none"];
|
|
219
219
|
var SQLITE_VECTOR_MAX_DIMENSIONS = 8e3;
|
|
220
220
|
function buildSqliteCapabilities(options) {
|
|
221
|
-
const base = options.transactionMode === "none" ? { ...
|
|
221
|
+
const base = options.transactionMode === "none" ? { ...chunkOECDVACY_cjs.SQLITE_CAPABILITIES, transactions: false } : chunkOECDVACY_cjs.SQLITE_CAPABILITIES;
|
|
222
222
|
return {
|
|
223
223
|
...base,
|
|
224
224
|
fulltext: chunkJTI5WT4P_cjs.buildFulltextCapabilities(options.fulltextStrategy),
|
|
@@ -258,7 +258,7 @@ function createSqliteOperationBackend(options) {
|
|
|
258
258
|
await db.run(query);
|
|
259
259
|
});
|
|
260
260
|
}
|
|
261
|
-
const commonBackend =
|
|
261
|
+
const commonBackend = chunkCQVNGKU7_cjs.createCommonOperationBackend({
|
|
262
262
|
batchConfig: {
|
|
263
263
|
checkUniqueBatchChunkSize: SQLITE_CHECK_UNIQUE_BATCH_CHUNK_SIZE,
|
|
264
264
|
edgeInsertBatchSize: SQLITE_EDGE_INSERT_BATCH_SIZE,
|
|
@@ -271,7 +271,7 @@ function createSqliteOperationBackend(options) {
|
|
|
271
271
|
execGet,
|
|
272
272
|
execRun
|
|
273
273
|
},
|
|
274
|
-
nowIso:
|
|
274
|
+
nowIso: chunkCQVNGKU7_cjs.nowIso,
|
|
275
275
|
operationStrategy,
|
|
276
276
|
rowMappers: {
|
|
277
277
|
toEdgeRow,
|
|
@@ -293,7 +293,7 @@ function createSqliteOperationBackend(options) {
|
|
|
293
293
|
async upsertEmbedding(params) {
|
|
294
294
|
const query = operationStrategy.buildUpsertEmbedding(
|
|
295
295
|
params,
|
|
296
|
-
|
|
296
|
+
chunkCQVNGKU7_cjs.nowIso()
|
|
297
297
|
);
|
|
298
298
|
await execRun(query);
|
|
299
299
|
},
|
|
@@ -332,14 +332,14 @@ function createSqliteOperationBackend(options) {
|
|
|
332
332
|
...params.indexParams?.efConstruction === void 0 ? {} : { hnswEfConstruction: params.indexParams.efConstruction },
|
|
333
333
|
...params.indexParams?.lists === void 0 ? {} : { ivfflatLists: params.indexParams.lists }
|
|
334
334
|
};
|
|
335
|
-
const result =
|
|
335
|
+
const result = chunkCQVNGKU7_cjs.createSqliteVectorIndex(indexOptions);
|
|
336
336
|
if (!result.success) {
|
|
337
337
|
throw new Error(result.message ?? "Failed to create SQLite vector index");
|
|
338
338
|
}
|
|
339
339
|
return Promise.resolve();
|
|
340
340
|
},
|
|
341
341
|
dropVectorIndex(params) {
|
|
342
|
-
const result =
|
|
342
|
+
const result = chunkCQVNGKU7_cjs.dropSqliteVectorIndex(
|
|
343
343
|
params.graphId,
|
|
344
344
|
params.nodeKind,
|
|
345
345
|
params.fieldPath
|
|
@@ -351,7 +351,7 @@ function createSqliteOperationBackend(options) {
|
|
|
351
351
|
},
|
|
352
352
|
// === Fulltext Operations ===
|
|
353
353
|
async upsertFulltext(params) {
|
|
354
|
-
const timestamp =
|
|
354
|
+
const timestamp = chunkCQVNGKU7_cjs.nowIso();
|
|
355
355
|
const statements = operationStrategy.buildUpsertFulltext(
|
|
356
356
|
params,
|
|
357
357
|
timestamp
|
|
@@ -368,7 +368,7 @@ function createSqliteOperationBackend(options) {
|
|
|
368
368
|
},
|
|
369
369
|
async upsertFulltextBatch(params) {
|
|
370
370
|
if (params.rows.length === 0) return;
|
|
371
|
-
const timestamp =
|
|
371
|
+
const timestamp = chunkCQVNGKU7_cjs.nowIso();
|
|
372
372
|
const statements = operationStrategy.buildUpsertFulltextBatch(
|
|
373
373
|
params,
|
|
374
374
|
timestamp
|
|
@@ -408,7 +408,7 @@ function createSqliteOperationBackend(options) {
|
|
|
408
408
|
return operationBackend;
|
|
409
409
|
}
|
|
410
410
|
function createSqliteBackend(db, options = {}) {
|
|
411
|
-
const tables2 = options.tables ??
|
|
411
|
+
const tables2 = options.tables ?? chunkCQVNGKU7_cjs.tables2;
|
|
412
412
|
const fulltextStrategy = options.fulltext ?? chunkJTI5WT4P_cjs.fts5Strategy;
|
|
413
413
|
const profileHints = options.executionProfile ?? {};
|
|
414
414
|
const executionAdapter = createSqliteExecutionAdapter(db, { profileHints });
|
|
@@ -426,7 +426,7 @@ function createSqliteBackend(db, options = {}) {
|
|
|
426
426
|
fulltext: tables2.fulltextTableName,
|
|
427
427
|
uniques: drizzleOrm.getTableName(tables2.uniques)
|
|
428
428
|
};
|
|
429
|
-
const operationStrategy =
|
|
429
|
+
const operationStrategy = chunkCQVNGKU7_cjs.createSqliteOperationStrategy(
|
|
430
430
|
tables2,
|
|
431
431
|
fulltextStrategy
|
|
432
432
|
);
|
|
@@ -491,20 +491,60 @@ function createSqliteBackend(db, options = {}) {
|
|
|
491
491
|
}, { behavior: "immediate" })
|
|
492
492
|
);
|
|
493
493
|
}
|
|
494
|
+
let fulltextEnsured = false;
|
|
495
|
+
async function ensureFulltextDdl() {
|
|
496
|
+
if (fulltextEnsured) return;
|
|
497
|
+
for (const statement of fulltextStrategy.generateDdl(
|
|
498
|
+
tables2.fulltextTableName
|
|
499
|
+
)) {
|
|
500
|
+
await db.run(drizzleOrm.sql.raw(statement));
|
|
501
|
+
}
|
|
502
|
+
fulltextEnsured = true;
|
|
503
|
+
}
|
|
494
504
|
const backend = {
|
|
495
505
|
...operations,
|
|
496
506
|
async bootstrapTables() {
|
|
497
|
-
const statements =
|
|
507
|
+
const statements = chunkCQVNGKU7_cjs.generateSqliteDDL(tables2, fulltextStrategy);
|
|
498
508
|
for (const statement of statements) {
|
|
499
509
|
await db.run(drizzleOrm.sql.raw(statement));
|
|
500
510
|
}
|
|
511
|
+
fulltextEnsured = true;
|
|
512
|
+
},
|
|
513
|
+
async upsertFulltext(params) {
|
|
514
|
+
await ensureFulltextDdl();
|
|
515
|
+
await operations.upsertFulltext(params);
|
|
516
|
+
},
|
|
517
|
+
async deleteFulltext(params) {
|
|
518
|
+
await ensureFulltextDdl();
|
|
519
|
+
await operations.deleteFulltext(params);
|
|
520
|
+
},
|
|
521
|
+
async upsertFulltextBatch(params) {
|
|
522
|
+
if (params.rows.length === 0) return;
|
|
523
|
+
await ensureFulltextDdl();
|
|
524
|
+
await operations.upsertFulltextBatch(params);
|
|
525
|
+
},
|
|
526
|
+
async deleteFulltextBatch(params) {
|
|
527
|
+
if (params.nodeIds.length === 0) return;
|
|
528
|
+
await ensureFulltextDdl();
|
|
529
|
+
await operations.deleteFulltextBatch(params);
|
|
530
|
+
},
|
|
531
|
+
async fulltextSearch(params) {
|
|
532
|
+
await ensureFulltextDdl();
|
|
533
|
+
return operations.fulltextSearch(params);
|
|
534
|
+
},
|
|
535
|
+
// hardDeleteNode is wrapped because the operation-backend-core
|
|
536
|
+
// cascade unconditionally deletes from the fulltext table — it
|
|
537
|
+
// would fail even on graphs that declare no searchable() fields.
|
|
538
|
+
async hardDeleteNode(params) {
|
|
539
|
+
await ensureFulltextDdl();
|
|
540
|
+
await operations.hardDeleteNode(params);
|
|
501
541
|
},
|
|
502
542
|
async executeDdl(ddl) {
|
|
503
543
|
await db.run(drizzleOrm.sql.raw(ddl));
|
|
504
544
|
},
|
|
505
545
|
async ensureIndexMaterializationsTable() {
|
|
506
546
|
await db.run(
|
|
507
|
-
drizzleOrm.sql.raw(
|
|
547
|
+
drizzleOrm.sql.raw(chunkCQVNGKU7_cjs.generateSqliteCreateTableSQL(tables2.indexMaterializations))
|
|
508
548
|
);
|
|
509
549
|
},
|
|
510
550
|
async getIndexMaterialization(indexName) {
|
|
@@ -512,65 +552,68 @@ function createSqliteBackend(db, options = {}) {
|
|
|
512
552
|
const rows = await db.select().from(t).where(drizzleOrm.eq(t.indexName, indexName));
|
|
513
553
|
const row = rows[0];
|
|
514
554
|
if (row === void 0) return void 0;
|
|
515
|
-
return
|
|
555
|
+
return chunkCQVNGKU7_cjs.mapMaterializationRow(row, chunkCQVNGKU7_cjs.SQLITE_INDEX_MAT_TIMESTAMPS.decode);
|
|
516
556
|
},
|
|
517
557
|
async getIndexMaterializations(statusKeys) {
|
|
518
558
|
if (statusKeys.length === 0) return [];
|
|
519
559
|
const t = tables2.indexMaterializations;
|
|
520
560
|
const rows = await db.select().from(t).where(drizzleOrm.inArray(t.indexName, [...statusKeys]));
|
|
521
561
|
return rows.map(
|
|
522
|
-
(row) =>
|
|
562
|
+
(row) => chunkCQVNGKU7_cjs.mapMaterializationRow(row, chunkCQVNGKU7_cjs.SQLITE_INDEX_MAT_TIMESTAMPS.decode)
|
|
523
563
|
);
|
|
524
564
|
},
|
|
525
565
|
async recordIndexMaterialization(params) {
|
|
526
566
|
const t = tables2.indexMaterializations;
|
|
527
567
|
await db.insert(t).values(
|
|
528
|
-
|
|
568
|
+
chunkCQVNGKU7_cjs.buildMaterializationInsertValues(
|
|
529
569
|
params,
|
|
530
|
-
|
|
570
|
+
chunkCQVNGKU7_cjs.SQLITE_INDEX_MAT_TIMESTAMPS.encode
|
|
531
571
|
)
|
|
532
572
|
).onConflictDoUpdate({
|
|
533
573
|
target: t.indexName,
|
|
534
|
-
set:
|
|
574
|
+
set: chunkCQVNGKU7_cjs.buildMaterializationOnConflictSet(
|
|
535
575
|
t.materializedAt,
|
|
536
576
|
params.materializedAt
|
|
537
577
|
)
|
|
538
578
|
});
|
|
539
579
|
},
|
|
540
580
|
async ensureKindRemovalsTable() {
|
|
541
|
-
await db.run(drizzleOrm.sql.raw(
|
|
581
|
+
await db.run(drizzleOrm.sql.raw(chunkCQVNGKU7_cjs.generateSqliteCreateTableSQL(tables2.kindRemovals)));
|
|
542
582
|
},
|
|
543
583
|
async getPendingKindRemovals(graphId) {
|
|
544
584
|
const t = tables2.kindRemovals;
|
|
545
585
|
const rows = await db.select().from(t).where(drizzleOrm.and(drizzleOrm.eq(t.graphId, graphId), drizzleOrm.isNull(t.removedAt)));
|
|
546
586
|
return rows.map(
|
|
547
|
-
(row) =>
|
|
587
|
+
(row) => chunkCQVNGKU7_cjs.mapKindRemovalRow(row, chunkCQVNGKU7_cjs.SQLITE_KIND_REMOVAL_TIMESTAMPS.decode)
|
|
548
588
|
);
|
|
549
589
|
},
|
|
550
590
|
async getAllKindRemovals(graphId) {
|
|
551
591
|
const t = tables2.kindRemovals;
|
|
552
592
|
const rows = await db.select().from(t).where(drizzleOrm.eq(t.graphId, graphId));
|
|
553
593
|
return rows.map(
|
|
554
|
-
(row) =>
|
|
594
|
+
(row) => chunkCQVNGKU7_cjs.mapKindRemovalRow(row, chunkCQVNGKU7_cjs.SQLITE_KIND_REMOVAL_TIMESTAMPS.decode)
|
|
555
595
|
);
|
|
556
596
|
},
|
|
557
597
|
async recordKindRemoval(params) {
|
|
558
598
|
const t = tables2.kindRemovals;
|
|
559
599
|
await db.insert(t).values(
|
|
560
|
-
|
|
600
|
+
chunkCQVNGKU7_cjs.buildKindRemovalInsertValues(
|
|
561
601
|
params,
|
|
562
|
-
|
|
602
|
+
chunkCQVNGKU7_cjs.SQLITE_KIND_REMOVAL_TIMESTAMPS.encode
|
|
563
603
|
)
|
|
564
604
|
).onConflictDoUpdate({
|
|
565
605
|
target: [t.graphId, t.kindName, t.entity, t.schemaVersion],
|
|
566
|
-
set:
|
|
606
|
+
set: chunkCQVNGKU7_cjs.buildKindRemovalOnConflictSet(t.removedAt, params.removedAt)
|
|
567
607
|
});
|
|
568
608
|
},
|
|
569
609
|
async ensureReconciliationMarkersTable() {
|
|
570
610
|
await db.run(
|
|
571
|
-
drizzleOrm.sql.raw(
|
|
611
|
+
drizzleOrm.sql.raw(chunkCQVNGKU7_cjs.generateSqliteCreateTableSQL(tables2.reconciliationMarkers))
|
|
572
612
|
);
|
|
573
613
|
},
|
|
614
|
+
async ensureFulltextTable() {
|
|
615
|
+
await ensureFulltextDdl();
|
|
616
|
+
},
|
|
574
617
|
async getReconciliationMarker(graphId) {
|
|
575
618
|
const t = tables2.reconciliationMarkers;
|
|
576
619
|
const rows = await db.select().from(t).where(drizzleOrm.eq(t.graphId, graphId));
|
|
@@ -607,6 +650,7 @@ function createSqliteBackend(db, options = {}) {
|
|
|
607
650
|
}
|
|
608
651
|
);
|
|
609
652
|
}
|
|
653
|
+
await ensureFulltextDdl();
|
|
610
654
|
if (transactionMode === "sql") {
|
|
611
655
|
return runWithSerializedQueue(serializedQueue, async () => {
|
|
612
656
|
const txBackend = createTransactionBackend({
|
|
@@ -669,5 +713,5 @@ function createTransactionBackend(options) {
|
|
|
669
713
|
}
|
|
670
714
|
|
|
671
715
|
exports.createSqliteBackend = createSqliteBackend;
|
|
672
|
-
//# sourceMappingURL=chunk-
|
|
673
|
-
//# sourceMappingURL=chunk-
|
|
716
|
+
//# sourceMappingURL=chunk-CLGC7AQ2.cjs.map
|
|
717
|
+
//# sourceMappingURL=chunk-CLGC7AQ2.cjs.map
|