@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.
Files changed (69) hide show
  1. package/dist/backend/postgres/index.cjs +92 -44
  2. package/dist/backend/postgres/index.cjs.map +1 -1
  3. package/dist/backend/postgres/index.d.cts +4 -4
  4. package/dist/backend/postgres/index.d.ts +4 -4
  5. package/dist/backend/postgres/index.js +47 -3
  6. package/dist/backend/postgres/index.js.map +1 -1
  7. package/dist/backend/sqlite/index.cjs +13 -13
  8. package/dist/backend/sqlite/index.d.cts +4 -4
  9. package/dist/backend/sqlite/index.d.ts +4 -4
  10. package/dist/backend/sqlite/index.js +3 -3
  11. package/dist/backend/sqlite/libsql.cjs +6 -6
  12. package/dist/backend/sqlite/libsql.d.cts +2 -2
  13. package/dist/backend/sqlite/libsql.d.ts +2 -2
  14. package/dist/backend/sqlite/libsql.js +3 -3
  15. package/dist/backend/sqlite/local.cjs +7 -7
  16. package/dist/backend/sqlite/local.d.cts +2 -2
  17. package/dist/backend/sqlite/local.d.ts +2 -2
  18. package/dist/backend/sqlite/local.js +3 -3
  19. package/dist/{chunk-LVCSL6A3.js → chunk-AAA2CR3P.js} +5 -3
  20. package/dist/chunk-AAA2CR3P.js.map +1 -0
  21. package/dist/{chunk-OJ6IQVZG.js → chunk-CLEUFN2K.js} +48 -4
  22. package/dist/chunk-CLEUFN2K.js.map +1 -0
  23. package/dist/{chunk-ZEMNF3QK.cjs → chunk-CLGC7AQ2.cjs} +78 -34
  24. package/dist/chunk-CLGC7AQ2.cjs.map +1 -0
  25. package/dist/{chunk-FPCOUJSL.js → chunk-CPFR3O7L.js} +2 -2
  26. package/dist/{chunk-FPCOUJSL.js.map → chunk-CPFR3O7L.js.map} +1 -1
  27. package/dist/{chunk-O2P3KAUT.cjs → chunk-CQVNGKU7.cjs} +39 -14
  28. package/dist/chunk-CQVNGKU7.cjs.map +1 -0
  29. package/dist/{chunk-7CDXX3QZ.cjs → chunk-OECDVACY.cjs} +2 -2
  30. package/dist/{chunk-7CDXX3QZ.cjs.map → chunk-OECDVACY.cjs.map} +1 -1
  31. package/dist/{chunk-WI5VRP3X.js → chunk-PSKUWVCB.js} +39 -15
  32. package/dist/chunk-PSKUWVCB.js.map +1 -0
  33. package/dist/{chunk-7W3KAMVQ.cjs → chunk-QMQYK3IF.cjs} +5 -3
  34. package/dist/chunk-QMQYK3IF.cjs.map +1 -0
  35. package/dist/{ddl-DpaeAKPp.d.ts → ddl-BqMmpNor.d.ts} +403 -21
  36. package/dist/{ddl-B2jjLjpR.d.cts → ddl-Bwjh8Hff.d.cts} +403 -21
  37. package/dist/index.cjs +65 -65
  38. package/dist/index.d.cts +7 -7
  39. package/dist/index.d.ts +7 -7
  40. package/dist/index.js +3 -3
  41. package/dist/indexes/index.d.cts +4 -4
  42. package/dist/indexes/index.d.ts +4 -4
  43. package/dist/interchange/index.d.cts +3 -3
  44. package/dist/interchange/index.d.ts +3 -3
  45. package/dist/{manager-BpjBW1JK.d.cts → manager-Cy3dhwYO.d.cts} +7 -2
  46. package/dist/{manager-BKaPQbns.d.ts → manager-sZkU2VPC.d.ts} +7 -2
  47. package/dist/profiler/index.d.cts +5 -5
  48. package/dist/profiler/index.d.ts +5 -5
  49. package/dist/schema/index.cjs +24 -24
  50. package/dist/schema/index.d.cts +4 -4
  51. package/dist/schema/index.d.ts +4 -4
  52. package/dist/schema/index.js +2 -2
  53. package/dist/{sqlite-Myo8e3Lr.d.cts → sqlite-BhFswiAR.d.cts} +1 -1
  54. package/dist/{sqlite-CU3j6rc7.d.ts → sqlite-h6dta1IJ.d.ts} +1 -1
  55. package/dist/{store-De98Lod4.d.ts → store-BS_hehiz.d.ts} +2 -2
  56. package/dist/{store-BAGuOHDh.d.cts → store-CkCvqRUf.d.cts} +2 -2
  57. package/dist/{types-CYga3lZp.d.cts → types-BpgACExN.d.cts} +1 -1
  58. package/dist/{types-BLmJq4wI.d.ts → types-Bz-Pi681.d.ts} +1 -1
  59. package/dist/{types-BNWYZ-0-.d.ts → types-DptZHe-l.d.ts} +9 -0
  60. package/dist/{types--0EslBx5.d.cts → types-WF5ItKQu.d.cts} +9 -0
  61. package/dist/{where-CluR73rs.d.ts → where-C40InMIp.d.ts} +1 -1
  62. package/dist/{where-m1uWsdua.d.cts → where-DZYMiXVq.d.cts} +1 -1
  63. package/package.json +1 -1
  64. package/dist/chunk-7W3KAMVQ.cjs.map +0 -1
  65. package/dist/chunk-LVCSL6A3.js.map +0 -1
  66. package/dist/chunk-O2P3KAUT.cjs.map +0 -1
  67. package/dist/chunk-OJ6IQVZG.js.map +0 -1
  68. package/dist/chunk-WI5VRP3X.js.map +0 -1
  69. 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-WI5VRP3X.js';
2
- import { SQLITE_CAPABILITIES } from './chunk-FPCOUJSL.js';
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-OJ6IQVZG.js.map
671
- //# sourceMappingURL=chunk-OJ6IQVZG.js.map
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 chunkO2P3KAUT_cjs = require('./chunk-O2P3KAUT.cjs');
4
- var chunk7CDXX3QZ_cjs = require('./chunk-7CDXX3QZ.cjs');
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 chunkO2P3KAUT_cjs.getOrCreateLru(
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) => chunkO2P3KAUT_cjs.compileQueryWithDialect(db, query, "SQLite");
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 = chunkO2P3KAUT_cjs.createNodeRowMapper(chunkO2P3KAUT_cjs.SQLITE_ROW_MAPPER_CONFIG);
174
- var toEdgeRow = chunkO2P3KAUT_cjs.createEdgeRowMapper(chunkO2P3KAUT_cjs.SQLITE_ROW_MAPPER_CONFIG);
175
- var toUniqueRow = chunkO2P3KAUT_cjs.createUniqueRowMapper(chunkO2P3KAUT_cjs.SQLITE_ROW_MAPPER_CONFIG);
176
- var toSchemaVersionRow = chunkO2P3KAUT_cjs.createSchemaVersionRowMapper(chunkO2P3KAUT_cjs.SQLITE_ROW_MAPPER_CONFIG);
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" ? { ...chunk7CDXX3QZ_cjs.SQLITE_CAPABILITIES, transactions: false } : chunk7CDXX3QZ_cjs.SQLITE_CAPABILITIES;
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 = chunkO2P3KAUT_cjs.createCommonOperationBackend({
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: chunkO2P3KAUT_cjs.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
- chunkO2P3KAUT_cjs.nowIso()
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 = chunkO2P3KAUT_cjs.createSqliteVectorIndex(indexOptions);
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 = chunkO2P3KAUT_cjs.dropSqliteVectorIndex(
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 = chunkO2P3KAUT_cjs.nowIso();
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 = chunkO2P3KAUT_cjs.nowIso();
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 ?? chunkO2P3KAUT_cjs.tables2;
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 = chunkO2P3KAUT_cjs.createSqliteOperationStrategy(
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 = chunkO2P3KAUT_cjs.generateSqliteDDL(tables2, fulltextStrategy);
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(chunkO2P3KAUT_cjs.generateSqliteCreateTableSQL(tables2.indexMaterializations))
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 chunkO2P3KAUT_cjs.mapMaterializationRow(row, chunkO2P3KAUT_cjs.SQLITE_INDEX_MAT_TIMESTAMPS.decode);
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) => chunkO2P3KAUT_cjs.mapMaterializationRow(row, chunkO2P3KAUT_cjs.SQLITE_INDEX_MAT_TIMESTAMPS.decode)
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
- chunkO2P3KAUT_cjs.buildMaterializationInsertValues(
568
+ chunkCQVNGKU7_cjs.buildMaterializationInsertValues(
529
569
  params,
530
- chunkO2P3KAUT_cjs.SQLITE_INDEX_MAT_TIMESTAMPS.encode
570
+ chunkCQVNGKU7_cjs.SQLITE_INDEX_MAT_TIMESTAMPS.encode
531
571
  )
532
572
  ).onConflictDoUpdate({
533
573
  target: t.indexName,
534
- set: chunkO2P3KAUT_cjs.buildMaterializationOnConflictSet(
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(chunkO2P3KAUT_cjs.generateSqliteCreateTableSQL(tables2.kindRemovals)));
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) => chunkO2P3KAUT_cjs.mapKindRemovalRow(row, chunkO2P3KAUT_cjs.SQLITE_KIND_REMOVAL_TIMESTAMPS.decode)
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) => chunkO2P3KAUT_cjs.mapKindRemovalRow(row, chunkO2P3KAUT_cjs.SQLITE_KIND_REMOVAL_TIMESTAMPS.decode)
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
- chunkO2P3KAUT_cjs.buildKindRemovalInsertValues(
600
+ chunkCQVNGKU7_cjs.buildKindRemovalInsertValues(
561
601
  params,
562
- chunkO2P3KAUT_cjs.SQLITE_KIND_REMOVAL_TIMESTAMPS.encode
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: chunkO2P3KAUT_cjs.buildKindRemovalOnConflictSet(t.removedAt, params.removedAt)
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(chunkO2P3KAUT_cjs.generateSqliteCreateTableSQL(tables2.reconciliationMarkers))
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-ZEMNF3QK.cjs.map
673
- //# sourceMappingURL=chunk-ZEMNF3QK.cjs.map
716
+ //# sourceMappingURL=chunk-CLGC7AQ2.cjs.map
717
+ //# sourceMappingURL=chunk-CLGC7AQ2.cjs.map