@nicia-ai/typegraph 0.28.0 → 0.29.0

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 (174) hide show
  1. package/dist/backend/postgres/index.cjs +23 -761
  2. package/dist/backend/postgres/index.cjs.map +1 -1
  3. package/dist/backend/postgres/index.d.cts +24 -5
  4. package/dist/backend/postgres/index.d.ts +24 -5
  5. package/dist/backend/postgres/index.js +10 -752
  6. package/dist/backend/postgres/index.js.map +1 -1
  7. package/dist/backend/postgres/pglite.cjs +52 -0
  8. package/dist/backend/postgres/pglite.cjs.map +1 -0
  9. package/dist/backend/postgres/pglite.d.cts +116 -0
  10. package/dist/backend/postgres/pglite.d.ts +116 -0
  11. package/dist/backend/postgres/pglite.js +50 -0
  12. package/dist/backend/postgres/pglite.js.map +1 -0
  13. package/dist/backend/sqlite/index.cjs +22 -26
  14. package/dist/backend/sqlite/index.d.cts +17 -15
  15. package/dist/backend/sqlite/index.d.ts +17 -15
  16. package/dist/backend/sqlite/index.js +9 -9
  17. package/dist/backend/sqlite/libsql.cjs +17 -13
  18. package/dist/backend/sqlite/libsql.cjs.map +1 -1
  19. package/dist/backend/sqlite/libsql.d.cts +3 -3
  20. package/dist/backend/sqlite/libsql.d.ts +3 -3
  21. package/dist/backend/sqlite/libsql.js +16 -12
  22. package/dist/backend/sqlite/libsql.js.map +1 -1
  23. package/dist/backend/sqlite/local.cjs +17 -16
  24. package/dist/backend/sqlite/local.cjs.map +1 -1
  25. package/dist/backend/sqlite/local.d.cts +3 -3
  26. package/dist/backend/sqlite/local.d.ts +3 -3
  27. package/dist/backend/sqlite/local.js +15 -14
  28. package/dist/backend/sqlite/local.js.map +1 -1
  29. package/dist/{chunk-DFHLG75V.js → chunk-3DTLDGIM.js} +386 -1093
  30. package/dist/chunk-3DTLDGIM.js.map +1 -0
  31. package/dist/{chunk-WVQXAFP3.js → chunk-454I6GDF.js} +46 -5
  32. package/dist/chunk-454I6GDF.js.map +1 -0
  33. package/dist/chunk-4K6IHUW6.cjs +183 -0
  34. package/dist/chunk-4K6IHUW6.cjs.map +1 -0
  35. package/dist/{chunk-ZTREJOGB.js → chunk-7KLVFWXR.js} +113 -68
  36. package/dist/chunk-7KLVFWXR.js.map +1 -0
  37. package/dist/{chunk-UKG7XHZ3.js → chunk-A4H6QMV4.js} +110 -102
  38. package/dist/chunk-A4H6QMV4.js.map +1 -0
  39. package/dist/{chunk-E5ROA3MN.js → chunk-BMDF2S7S.js} +3 -3
  40. package/dist/{chunk-E5ROA3MN.js.map → chunk-BMDF2S7S.js.map} +1 -1
  41. package/dist/{chunk-PN37HVAV.cjs → chunk-C2RWFIYP.cjs} +121 -67
  42. package/dist/chunk-C2RWFIYP.cjs.map +1 -0
  43. package/dist/chunk-CUZGBWFT.js +206 -0
  44. package/dist/chunk-CUZGBWFT.js.map +1 -0
  45. package/dist/chunk-F2Q76CQ4.cjs +266 -0
  46. package/dist/chunk-F2Q76CQ4.cjs.map +1 -0
  47. package/dist/{chunk-YEDQLNVE.cjs → chunk-G6P3OVDY.cjs} +14 -2
  48. package/dist/chunk-G6P3OVDY.cjs.map +1 -0
  49. package/dist/chunk-GPUNAJFH.js +181 -0
  50. package/dist/chunk-GPUNAJFH.js.map +1 -0
  51. package/dist/chunk-HKN622O4.js +254 -0
  52. package/dist/chunk-HKN622O4.js.map +1 -0
  53. package/dist/{chunk-PYJOBZR3.cjs → chunk-HM6XMR3E.cjs} +52 -52
  54. package/dist/chunk-HM6XMR3E.cjs.map +1 -0
  55. package/dist/chunk-IE2TPFBT.js +305 -0
  56. package/dist/chunk-IE2TPFBT.js.map +1 -0
  57. package/dist/chunk-KGAJ5HFO.cjs +319 -0
  58. package/dist/chunk-KGAJ5HFO.cjs.map +1 -0
  59. package/dist/chunk-M6OC455F.js +65 -0
  60. package/dist/chunk-M6OC455F.js.map +1 -0
  61. package/dist/{chunk-U5ROKVRF.js → chunk-MB363HT5.js} +14 -3
  62. package/dist/chunk-MB363HT5.js.map +1 -0
  63. package/dist/{chunk-X53YKGHR.js → chunk-MRMD7S7E.js} +9 -9
  64. package/dist/{chunk-X53YKGHR.js.map → chunk-MRMD7S7E.js.map} +1 -1
  65. package/dist/{chunk-OOS2RKRH.js → chunk-N3VVQDMA.js} +3 -3
  66. package/dist/{chunk-OOS2RKRH.js.map → chunk-N3VVQDMA.js.map} +1 -1
  67. package/dist/{chunk-EJCDOA37.js → chunk-OGUH56BB.js} +4 -4
  68. package/dist/{chunk-EJCDOA37.js.map → chunk-OGUH56BB.js.map} +1 -1
  69. package/dist/chunk-Q3ZZLU3O.cjs +12 -0
  70. package/dist/{chunk-4FJVSF3K.cjs.map → chunk-Q3ZZLU3O.cjs.map} +1 -1
  71. package/dist/chunk-Q5ASTPM4.cjs +208 -0
  72. package/dist/chunk-Q5ASTPM4.cjs.map +1 -0
  73. package/dist/{chunk-WFUN6DCM.cjs → chunk-R2LA6MKR.cjs} +11 -11
  74. package/dist/chunk-R2LA6MKR.cjs.map +1 -0
  75. package/dist/chunk-RP7YITHX.cjs +70 -0
  76. package/dist/chunk-RP7YITHX.cjs.map +1 -0
  77. package/dist/{chunk-33K3ZYFG.cjs → chunk-RU5BBUU2.cjs} +132 -124
  78. package/dist/chunk-RU5BBUU2.cjs.map +1 -0
  79. package/dist/{chunk-TSGBRPNE.js → chunk-SFNUHFON.js} +45 -45
  80. package/dist/chunk-SFNUHFON.js.map +1 -0
  81. package/dist/chunk-UP4QAJND.cjs +740 -0
  82. package/dist/chunk-UP4QAJND.cjs.map +1 -0
  83. package/dist/{chunk-CTHNVU6K.cjs → chunk-UPBXUOW7.cjs} +8 -8
  84. package/dist/{chunk-CTHNVU6K.cjs.map → chunk-UPBXUOW7.cjs.map} +1 -1
  85. package/dist/{chunk-EK6RJ373.cjs → chunk-VGU26WIU.cjs} +5 -5
  86. package/dist/{chunk-EK6RJ373.cjs.map → chunk-VGU26WIU.cjs.map} +1 -1
  87. package/dist/{chunk-ZGEMI7MJ.cjs → chunk-XTQHSOIC.cjs} +101 -101
  88. package/dist/{chunk-ZGEMI7MJ.cjs.map → chunk-XTQHSOIC.cjs.map} +1 -1
  89. package/dist/chunk-Y52UNT66.js +738 -0
  90. package/dist/chunk-Y52UNT66.js.map +1 -0
  91. package/dist/{chunk-OYLF3IC7.js → chunk-Z36W5WUM.js} +4 -4
  92. package/dist/chunk-Z36W5WUM.js.map +1 -0
  93. package/dist/{chunk-X3244EKP.cjs → chunk-ZFWNO3GE.cjs} +48 -4
  94. package/dist/chunk-ZFWNO3GE.cjs.map +1 -0
  95. package/dist/{chunk-2E4VTD2E.cjs → chunk-ZYQEXGYC.cjs} +423 -1139
  96. package/dist/chunk-ZYQEXGYC.cjs.map +1 -0
  97. package/dist/ddl-BwH00BB6.d.ts +38 -0
  98. package/dist/ddl-D3o-RmsV.d.cts +38 -0
  99. package/dist/{extension-types-B78CZfA5.d.ts → extension-types-CwHV-Uk4.d.cts} +4 -4
  100. package/dist/{extension-types-B78CZfA5.d.cts → extension-types-CwHV-Uk4.d.ts} +4 -4
  101. package/dist/graph-extension/index.cjs +18 -18
  102. package/dist/graph-extension/index.d.cts +4 -4
  103. package/dist/graph-extension/index.d.ts +4 -4
  104. package/dist/graph-extension/index.js +3 -3
  105. package/dist/{index-CWdBFWbI.d.ts → index-CapHwi1a.d.ts} +22 -3
  106. package/dist/{index-Bilw0pYm.d.cts → index-jPPexxM5.d.cts} +22 -3
  107. package/dist/index.cjs +1211 -945
  108. package/dist/index.cjs.map +1 -1
  109. package/dist/index.d.cts +142 -12
  110. package/dist/index.d.ts +142 -12
  111. package/dist/index.js +778 -544
  112. package/dist/index.js.map +1 -1
  113. package/dist/indexes/index.cjs +18 -18
  114. package/dist/indexes/index.d.cts +9 -9
  115. package/dist/indexes/index.d.ts +9 -9
  116. package/dist/indexes/index.js +4 -4
  117. package/dist/interchange/index.cjs +8 -14
  118. package/dist/interchange/index.cjs.map +1 -1
  119. package/dist/interchange/index.d.cts +5 -16
  120. package/dist/interchange/index.d.ts +5 -16
  121. package/dist/interchange/index.js +3 -9
  122. package/dist/interchange/index.js.map +1 -1
  123. package/dist/{manager-ehLTTNq0.d.ts → manager-BUugwCYz.d.ts} +2 -2
  124. package/dist/{manager-c1MGaVVR.d.cts → manager-DpIpn1HQ.d.cts} +2 -2
  125. package/dist/{materialize-indexes-DFavFQah.d.ts → materialize-indexes-lkawaDor.d.ts} +1 -1
  126. package/dist/{materialize-indexes-BQfaAZKA.d.cts → materialize-indexes-oanE3RU0.d.cts} +1 -1
  127. package/dist/{ddl-0Ooc2dpL.d.ts → postgres-CQL9UIn2.d.cts} +2 -471
  128. package/dist/{ddl-Dza3kDrI.d.cts → postgres-CcRLaxz0.d.ts} +2 -471
  129. package/dist/profiler/index.cjs +4 -4
  130. package/dist/profiler/index.d.cts +7 -7
  131. package/dist/profiler/index.d.ts +7 -7
  132. package/dist/profiler/index.js +2 -2
  133. package/dist/schema/index.cjs +32 -32
  134. package/dist/schema/index.d.cts +7 -7
  135. package/dist/schema/index.d.ts +7 -7
  136. package/dist/schema/index.js +9 -9
  137. package/dist/{sqlite-BxZUPbyD.d.ts → sqlite-CZDFUfHS.d.ts} +2 -468
  138. package/dist/{sqlite-mvpXjEeB.d.cts → sqlite-Rj3xu4It.d.cts} +2 -468
  139. package/dist/{store-Ufc1Eoey.d.ts → store-B43FpOVX.d.cts} +84 -5
  140. package/dist/{store-D7YEMg2v.d.cts → store-De0Y33wP.d.ts} +84 -5
  141. package/dist/{types-B-sJJ4GQ.d.ts → types-B5GSeE3t.d.ts} +2 -2
  142. package/dist/{types-CmUA9sal.d.cts → types-Bwlp_yvu.d.cts} +2 -2
  143. package/dist/{types-CMQymcwk.d.cts → types-CmAT-Z47.d.ts} +250 -46
  144. package/dist/{types-CQ7xXJMP.d.ts → types-DXCSyxac.d.cts} +250 -46
  145. package/dist/{where-5zf15aFZ.d.cts → where-2dsyYt3d.d.cts} +2 -2
  146. package/dist/{where-CtrLu1Zf.d.ts → where-CP4qGIHd.d.ts} +2 -2
  147. package/package.json +20 -5
  148. package/dist/chunk-2E4VTD2E.cjs.map +0 -1
  149. package/dist/chunk-33K3ZYFG.cjs.map +0 -1
  150. package/dist/chunk-3EUKJEQ3.js +0 -77
  151. package/dist/chunk-3EUKJEQ3.js.map +0 -1
  152. package/dist/chunk-4FJVSF3K.cjs +0 -12
  153. package/dist/chunk-5H3BAMTB.js +0 -32
  154. package/dist/chunk-5H3BAMTB.js.map +0 -1
  155. package/dist/chunk-DFHLG75V.js.map +0 -1
  156. package/dist/chunk-HTGDWIDE.cjs +0 -89
  157. package/dist/chunk-HTGDWIDE.cjs.map +0 -1
  158. package/dist/chunk-IUIWCFG3.cjs +0 -36
  159. package/dist/chunk-IUIWCFG3.cjs.map +0 -1
  160. package/dist/chunk-LYRUNG6E.cjs +0 -52
  161. package/dist/chunk-LYRUNG6E.cjs.map +0 -1
  162. package/dist/chunk-OYLF3IC7.js.map +0 -1
  163. package/dist/chunk-PCHTTG42.js +0 -47
  164. package/dist/chunk-PCHTTG42.js.map +0 -1
  165. package/dist/chunk-PN37HVAV.cjs.map +0 -1
  166. package/dist/chunk-PYJOBZR3.cjs.map +0 -1
  167. package/dist/chunk-TSGBRPNE.js.map +0 -1
  168. package/dist/chunk-U5ROKVRF.js.map +0 -1
  169. package/dist/chunk-UKG7XHZ3.js.map +0 -1
  170. package/dist/chunk-WFUN6DCM.cjs.map +0 -1
  171. package/dist/chunk-WVQXAFP3.js.map +0 -1
  172. package/dist/chunk-X3244EKP.cjs.map +0 -1
  173. package/dist/chunk-YEDQLNVE.cjs.map +0 -1
  174. package/dist/chunk-ZTREJOGB.js.map +0 -1
@@ -1,5 +1,5 @@
1
1
  import { z } from 'zod';
2
- import { N as NodeType, e as EdgeType, o as UniquenessScope, g as Collation, D as DeleteBehavior, d as KindAnnotations, f as Cardinality, k as EndpointExistence, T as TemporalMode, G as GraphExtension, I as IndexEntity, K as KindEntity, a as NullCheckOp, A as AnyEdgeType } from './extension-types-B78CZfA5.js';
2
+ import { N as NodeType, d as EdgeType, U as UniquenessScope, C as Collation, D as DeleteBehavior, e as KindAnnotations, f as Cardinality, g as EndpointExistence, T as TemporalMode, G as GraphExtension, I as IndexEntity, K as KindEntity, a as NullCheckOp, A as AnyEdgeType } from './extension-types-CwHV-Uk4.cjs';
3
3
  import { SQL } from 'drizzle-orm';
4
4
  import { PgDatabase, PgQueryResultHKT } from 'drizzle-orm/pg-core';
5
5
  import { BaseSQLiteDatabase } from 'drizzle-orm/sqlite-core';
@@ -120,8 +120,6 @@ type SqlTableNames = Readonly<{
120
120
  nodes: string;
121
121
  /** Edges table name (default: "typegraph_edges") */
122
122
  edges: string;
123
- /** Node embeddings table name (default: "typegraph_node_embeddings") */
124
- embeddings: string;
125
123
  /** Node fulltext table name (default: "typegraph_node_fulltext") */
126
124
  fulltext: string;
127
125
  /** Node uniques table name (default: "typegraph_node_uniques") */
@@ -138,8 +136,6 @@ type SqlSchema = Readonly<{
138
136
  nodesTable: SQL;
139
137
  /** Get a SQL reference to the edges table */
140
138
  edgesTable: SQL;
141
- /** Get a SQL reference to the embeddings table */
142
- embeddingsTable: SQL;
143
139
  /** Get a SQL reference to the fulltext table */
144
140
  fulltextTable: SQL;
145
141
  }>;
@@ -162,7 +158,7 @@ type SqlSchema = Readonly<{
162
158
  * const schema = createSqlSchema({
163
159
  * nodes: "myapp_nodes",
164
160
  * edges: "myapp_edges",
165
- * embeddings: "myapp_embeddings",
161
+ * fulltext: "myapp_fulltext",
166
162
  * });
167
163
  * ```
168
164
  */
@@ -171,6 +167,27 @@ declare function createSqlSchema(names?: Partial<SqlTableNames>): SqlSchema;
171
167
  * Default SqlSchema using standard TypeGraph table names.
172
168
  */
173
169
  declare const DEFAULT_SQL_SCHEMA: SqlSchema;
170
+ /**
171
+ * The compiler's resolved view of one declared embedding field — the
172
+ * `(dimensions, metric, indexType)` a {@link VectorStrategy} needs to
173
+ * name and scan the field's typed per-`(kind, field)` storage. Sourced
174
+ * from the registered node schema's `embedding()` declaration when the
175
+ * store builds its compile options.
176
+ */
177
+ type VectorSlotDescriptor = Readonly<{
178
+ dimensions: number;
179
+ metric: VectorMetric;
180
+ indexType: VectorIndexType;
181
+ }>;
182
+ /**
183
+ * Map of declared embedding slots keyed by {@link vectorSlotKey} -
184
+ * `"<nodeKind>\0<fieldPath>"` (NUL-separated). Carries every `(concrete kind,
185
+ * fieldPath)` that declares an embedding field, so the compiler's
186
+ * `field.similarTo(...)` CTE can UNION ALL the per-field tables for the
187
+ * kinds in an alias that actually declare the field (only
188
+ * `includeSubClasses` yields more than one).
189
+ */
190
+ type VectorSlotMap = ReadonlyMap<string, VectorSlotDescriptor>;
174
191
 
175
192
  /**
176
193
  * A single table TypeGraph owns.
@@ -348,6 +365,181 @@ interface FulltextStrategy {
348
365
  declare const tsvectorStrategy: FulltextStrategy;
349
366
  declare const fts5Strategy: FulltextStrategy;
350
367
 
368
+ /**
369
+ * Vector Strategy — pluggable storage + SQL generation for a backend's
370
+ * vector stack. The sibling of {@link FulltextStrategy}: a strategy owns
371
+ * every statement that touches its embedding storage — the per-field DDL,
372
+ * upsert, delete, similarity search, and (optional) ANN index lifecycle —
373
+ * plus the capability advertisement and the distance/score expressions the
374
+ * query compiler splices into its relevance CTE.
375
+ *
376
+ * ## Why a strategy, and why per-(kind, field) storage
377
+ *
378
+ * The spike behind #157 established that "real" ANN on every engine we
379
+ * support converges on a
380
+ * **typed, fixed-dimension structure per `(nodeKind, fieldPath)`**:
381
+ *
382
+ * - pgvector: a `vector(N)` column + HNSW/IVFFlat;
383
+ * - libSQL native: an `F32_BLOB(N)` column + `libsql_vector_idx` +
384
+ * `vector_top_k` (a plain `BLOB` or dimensionless `F32_BLOB` is rejected
385
+ * by the index — the dimension must live in the column type);
386
+ * - sqlite-vec: a `vec0(embedding float[N])` virtual table.
387
+ *
388
+ * The legacy single shared `typegraph_node_embeddings` table (one generic
389
+ * column holding mixed-dimension vectors) can only ever be brute-forced;
390
+ * pgvector was the sole engine that hid this, because its index supplies the
391
+ * dimension via a `::vector(N)` cast expression. So storage is the
392
+ * strategy's to own, slot by slot, rather than a fixed global table.
393
+ *
394
+ * Brute force remains a legitimate, capability-advertised mode (libSQL's
395
+ * `vector_distance_cos` over a column with no index, sqlite-vec's
396
+ * `vec_distance_cosine`): a strategy whose `capabilities.indexTypes` is
397
+ * `["none"]` simply never emits an ANN index and `buildSearch` always scans.
398
+ */
399
+
400
+ /**
401
+ * The resolved identity of one embedding field's storage in a graph —
402
+ * everything a strategy needs to DDL, address, and index it.
403
+ *
404
+ * Graph-scoped: each `(graphId, nodeKind, fieldPath)` gets its own physical
405
+ * table. TypeGraph supports many graphs per physical database, and the same
406
+ * `(kind, field)` can carry different embedding dimensions across graphs — a
407
+ * shared per-`(kind, field)` table would collide on the fixed column type
408
+ * (`vector(N)` / `F32_BLOB(N)`). Graph-scoping also makes libSQL's
409
+ * table-global `vector_top_k` per-graph-exact (no cross-graph recall bleed).
410
+ */
411
+ type VectorSlot = Readonly<{
412
+ /** Graph the embedding belongs to — scopes the physical table. */
413
+ graphId: string;
414
+ /** Node kind owning the embedding field (e.g. `"Document"`). */
415
+ nodeKind: string;
416
+ /** Dot-path of the embedding field within the node props (e.g. `"embedding"`). */
417
+ fieldPath: string;
418
+ /** Fixed vector dimension `N` for this field — carried into the column type. */
419
+ dimensions: number;
420
+ /** Distance metric the field's index is built for. */
421
+ metric: VectorMetric;
422
+ /**
423
+ * Index type to materialize. `"none"` means brute-force only (no ANN
424
+ * index emitted); the strategy still stores and searches the field.
425
+ */
426
+ indexType: VectorIndexType;
427
+ /**
428
+ * Optional ANN index tuning carried into the index DDL (pgvector
429
+ * `m`/`ef_construction`/`lists`). Present on the create-index / re-embed
430
+ * paths (resolved from the field's `embedding()` declaration); omitted on
431
+ * the write/search ensure paths, where the strategy falls back to defaults.
432
+ */
433
+ indexParams?: Readonly<{
434
+ m?: number;
435
+ efConstruction?: number;
436
+ lists?: number;
437
+ }>;
438
+ }>;
439
+ /**
440
+ * Derives the `VectorCapabilities` a backend advertises from its active
441
+ * strategy, so the two never drift (mirrors `buildFulltextCapabilities`).
442
+ * The strategy is the single source of truth; there are no per-call-site
443
+ * `SQLITE_VECTOR_*` constants.
444
+ */
445
+ declare function buildVectorCapabilities(strategy: VectorStrategy): VectorCapabilities;
446
+ /**
447
+ * A pluggable vector implementation. Each strategy is self-contained:
448
+ * given a {@link VectorSlot}, it emits every statement the backend and
449
+ * compiler need — per-field storage DDL, writes, similarity search, ANN
450
+ * index lifecycle — and advertises exactly the metrics and index types it
451
+ * can honor. Adding the Nth backend is one of these objects; no core edits.
452
+ */
453
+ interface VectorStrategy {
454
+ /** Human-readable identifier used in error messages and telemetry. */
455
+ readonly name: string;
456
+ /**
457
+ * The metrics, index types, and dimension ceiling this strategy honors —
458
+ * advertised verbatim as `backend.capabilities.vector`. Asymmetry across
459
+ * engines is legitimate and explicit here (pgvector has `inner_product`;
460
+ * libSQL/sqlite-vec do not), never a silent runtime failure.
461
+ */
462
+ readonly capabilities: VectorCapabilities;
463
+ /**
464
+ * Deterministic physical table (or virtual-table) name backing a field in
465
+ * a graph. The compiler references this to scan the right per-field storage,
466
+ * and the backend uses it to route upserts/deletes. Must be a stable,
467
+ * collision-safe SQL identifier derived from `(graphId, nodeKind, fieldPath)`.
468
+ */
469
+ tableName(graphId: string, nodeKind: string, fieldPath: string): string;
470
+ /**
471
+ * The per-field storage this strategy owns for `slot`, as Drizzle-free
472
+ * `StrategyTableContribution`s (resolved `tableName`, deterministic
473
+ * idempotent `createDdl` for the table **and** its ANN index when the
474
+ * slot's `indexType` warrants one, `runtimeEnsure`). Rides the #129/#135
475
+ * table-contribution + durable-materialization machinery exactly as the
476
+ * FTS5 / tsvector virtual tables do — these are materialized per graph by
477
+ * `materializeIndexes()`, not by global `bootstrapTables`.
478
+ */
479
+ ownedTables(slot: VectorSlot): readonly StrategyTableContribution[];
480
+ /**
481
+ * Emits the statement(s) that upsert a single embedding into the slot's
482
+ * storage. Multiple statements are allowed for engines that cannot upsert
483
+ * a vector in one statement (e.g. a `vec0` virtual table → DELETE+INSERT).
484
+ */
485
+ buildUpsert(slot: VectorSlot, params: UpsertEmbeddingParams, timestamp: string): readonly SQL[];
486
+ /** Emits the statement(s) that delete a single embedding from the slot. */
487
+ buildDelete(slot: VectorSlot, params: DeleteEmbeddingParams): readonly SQL[];
488
+ /**
489
+ * Raw DDL statement(s) that drop the slot's entire physical storage
490
+ * (table + ANN index, and any engine-managed shadow tables). Used by the
491
+ * destructive `store.reembedVectorField()` path to recreate a field's
492
+ * storage at a new dimension. Returned as raw strings (like
493
+ * `ownedTables(...).createDdl`) for `backend.executeDdl`; must be idempotent
494
+ * (`IF EXISTS`).
495
+ */
496
+ buildDropStorage(slot: VectorSlot): readonly string[];
497
+ /**
498
+ * Emits the similarity-search query for the `backend.vectorSearch` path,
499
+ * returning rows shaped `{ node_id, score }` ordered best-first. The
500
+ * strategy picks brute-force vs ANN based on whether `slot.indexType`
501
+ * materialized an index — the caller never branches. `score` follows the
502
+ * shared convention (cosine → similarity `1 - distance`; l2 /
503
+ * inner_product → raw distance), so `coerceVectorScore` / fusion stay
504
+ * dialect-neutral.
505
+ */
506
+ buildSearch(slot: VectorSlot, params: VectorSearchParams): SQL;
507
+ /**
508
+ * The distance expression over the slot's embedding column, used by the
509
+ * **query compiler** to splice vector relevance into its CTE. This is the
510
+ * one genuinely engine-specific fragment (`vec_distance_cosine` vs
511
+ * `<=>` vs `vector_distance_cos`); the surrounding score / minScore /
512
+ * ORDER BY math is shared (see {@link vectorScoreExpression} etc.).
513
+ *
514
+ * `embeddingColumn` is the already-qualified column SQL; `queryEmbedding`
515
+ * is formatted by the strategy into its engine's literal form.
516
+ */
517
+ distanceExpression(embeddingColumn: SQL, queryEmbedding: readonly number[], metric: VectorMetric): SQL;
518
+ /**
519
+ * Emits the ANN index creation statement for a slot, or `undefined` when
520
+ * indexing is inline (vec0) or unsupported (brute-force-only strategies).
521
+ * Invoked through `backend.createVectorIndex` during `materializeIndexes`.
522
+ */
523
+ buildCreateIndex?(slot: VectorSlot, options?: Readonly<{
524
+ concurrent?: boolean;
525
+ }>): SQL | undefined;
526
+ /** Emits the ANN index drop statement, or `undefined` when not applicable. */
527
+ buildDropIndex?(slot: VectorSlot): SQL | undefined;
528
+ }
529
+
530
+ /**
531
+ * SQL Dialect Abstraction Layer
532
+ *
533
+ * Provides a unified interface for dialect-specific SQL generation.
534
+ * Implementing a new dialect (MySQL, SQL Server, etc.) requires
535
+ * implementing this interface.
536
+ */
537
+
538
+ /**
539
+ * Supported SQL dialects.
540
+ */
541
+ type SqlDialect = "sqlite" | "postgres";
542
+
351
543
  /**
352
544
  * JSON Schema type (subset used by Zod toJSONSchema).
353
545
  *
@@ -541,19 +733,6 @@ type SqliteExecutionProfileHints = Readonly<{
541
733
  }>;
542
734
  type AnySqliteDatabase = BaseSQLiteDatabase<"sync" | "async", unknown>;
543
735
 
544
- /**
545
- * SQL Dialect Abstraction Layer
546
- *
547
- * Provides a unified interface for dialect-specific SQL generation.
548
- * Implementing a new dialect (MySQL, SQL Server, etc.) requires
549
- * implementing this interface.
550
- */
551
-
552
- /**
553
- * Supported SQL dialects.
554
- */
555
- type SqlDialect = "sqlite" | "postgres";
556
-
557
736
  /**
558
737
  * Backend interface types for TypeGraph storage.
559
738
  *
@@ -618,16 +797,6 @@ type FulltextCapabilities = Readonly<{
618
797
  * Backend capabilities that vary by dialect.
619
798
  */
620
799
  type BackendCapabilities = Readonly<{
621
- /** Whether the backend supports JSONB type (vs TEXT for JSON) */
622
- jsonb: boolean;
623
- /** Whether the backend supports partial indexes */
624
- partialIndexes: boolean;
625
- /** Whether the backend supports GIN indexes for JSON */
626
- ginIndexes: boolean;
627
- /** Whether the backend supports CTE (WITH) queries */
628
- cte: boolean;
629
- /** Whether the backend supports RETURNING clause */
630
- returning: boolean;
631
800
  /** Whether the backend supports atomic transactions (D1 does not) */
632
801
  transactions: boolean;
633
802
  /** Vector search capabilities (undefined if not configured) */
@@ -691,19 +860,6 @@ type SchemaVersionRow = Readonly<{
691
860
  created_at: string;
692
861
  is_active: boolean;
693
862
  }>;
694
- /**
695
- * A row from the typegraph_node_embeddings table.
696
- */
697
- type EmbeddingRow = Readonly<{
698
- graph_id: string;
699
- node_kind: string;
700
- node_id: string;
701
- field_path: string;
702
- embedding: readonly number[];
703
- dimensions: number;
704
- created_at: string;
705
- updated_at: string;
706
- }>;
707
863
  /**
708
864
  * Parameters for inserting a node.
709
865
  */
@@ -785,6 +941,14 @@ type HardDeleteEdgeParams = Readonly<{
785
941
  }>;
786
942
  /**
787
943
  * Parameters for inserting or updating an embedding.
944
+ *
945
+ * `dimensions`, `metric`, and `indexType` together resolve the slot's
946
+ * typed per-`(nodeKind, fieldPath)` storage (the strategy needs the fixed
947
+ * dimension for the column type, and the metric/index type to address the
948
+ * right ANN structure). The store populates them from the schema's
949
+ * `embedding()` declaration via `getEmbeddingDimensions()` /
950
+ * `getEmbeddingIndex()`; the backend constructs a `VectorSlot` from them
951
+ * and stays graph-agnostic.
788
952
  */
789
953
  type UpsertEmbeddingParams = Readonly<{
790
954
  graphId: string;
@@ -793,15 +957,29 @@ type UpsertEmbeddingParams = Readonly<{
793
957
  fieldPath: string;
794
958
  embedding: readonly number[];
795
959
  dimensions: number;
960
+ metric: VectorMetric;
961
+ indexType: VectorIndexType;
796
962
  }>;
797
963
  /**
798
964
  * Parameters for deleting an embedding.
965
+ *
966
+ * `dimensions` / `metric` / `indexType` mirror {@link UpsertEmbeddingParams}
967
+ * so the backend can resolve the slot's typed per-`(nodeKind, fieldPath)`
968
+ * storage and idempotently ensure it exists before the DELETE. That
969
+ * matters because a delete can run before any embedding was ever written
970
+ * (e.g. a node hard-deleted having never carried one), and on Postgres a
971
+ * DELETE against a missing relation inside a transaction aborts the whole
972
+ * transaction. The store populates them from the schema's `embedding()`
973
+ * declaration, exactly as for upserts.
799
974
  */
800
975
  type DeleteEmbeddingParams = Readonly<{
801
976
  graphId: string;
802
977
  nodeKind: string;
803
978
  nodeId: string;
804
979
  fieldPath: string;
980
+ dimensions: number;
981
+ metric: VectorMetric;
982
+ indexType: VectorIndexType;
805
983
  }>;
806
984
  /**
807
985
  * Parameters for vector similarity search.
@@ -812,6 +990,19 @@ type VectorSearchParams = Readonly<{
812
990
  fieldPath: string;
813
991
  queryEmbedding: readonly number[];
814
992
  metric: VectorMetric;
993
+ /**
994
+ * Fixed vector dimension `N` for the searched `(nodeKind, fieldPath)`
995
+ * slot. The store populates it from the schema's `embedding()`
996
+ * declaration via `getEmbeddingDimensions()`; the backend uses it to
997
+ * construct the `VectorSlot` whose typed storage the strategy scans.
998
+ */
999
+ dimensions: number;
1000
+ /**
1001
+ * Index type materialized for this slot. `"none"` means brute-force
1002
+ * only; otherwise the strategy may route through its ANN structure.
1003
+ * The store populates it from `getEmbeddingIndex()`.
1004
+ */
1005
+ indexType: VectorIndexType;
815
1006
  limit: number;
816
1007
  minScore?: number;
817
1008
  /**
@@ -1170,6 +1361,16 @@ type GraphBackend = Readonly<{
1170
1361
  * When absent, the dialect's default strategy is used.
1171
1362
  */
1172
1363
  fulltextStrategy?: FulltextStrategy | undefined;
1364
+ /**
1365
+ * Optional vector strategy this backend is wired with. The query
1366
+ * compiler reads it (via `compileQuery` options) to emit per-`(kind,
1367
+ * field)` relevance scans for `field.similarTo(...)` predicates, and
1368
+ * the index-materialization / removal paths read its deterministic
1369
+ * `tableName(...)` to address the right physical per-field storage.
1370
+ * `undefined` when the backend has no vector support (e.g. a generic
1371
+ * SQLite backend without sqlite-vec).
1372
+ */
1373
+ vectorStrategy?: VectorStrategy | undefined;
1173
1374
  insertNode: (params: InsertNodeParams) => Promise<NodeRow>;
1174
1375
  insertNodeNoReturn?: (params: InsertNodeParams) => Promise<void>;
1175
1376
  insertNodesBatch?: (params: readonly InsertNodeParams[]) => Promise<void>;
@@ -1234,7 +1435,6 @@ type GraphBackend = Readonly<{
1234
1435
  setActiveVersion: (params: SetActiveVersionParams) => Promise<void>;
1235
1436
  upsertEmbedding?: (params: UpsertEmbeddingParams) => Promise<void>;
1236
1437
  deleteEmbedding?: (params: DeleteEmbeddingParams) => Promise<void>;
1237
- getEmbedding?: (graphId: string, nodeKind: string, nodeId: string, fieldPath: string) => Promise<EmbeddingRow | undefined>;
1238
1438
  vectorSearch?: (params: VectorSearchParams) => Promise<readonly VectorSearchResult[]>;
1239
1439
  createVectorIndex?: (params: CreateVectorIndexParams) => Promise<void>;
1240
1440
  dropVectorIndex?: (params: DropVectorIndexParams) => Promise<void>;
@@ -1879,8 +2079,12 @@ type VectorSimilarityPredicate = Readonly<{
1879
2079
  field: FieldRef;
1880
2080
  /** The query embedding to compare against */
1881
2081
  queryEmbedding: readonly number[];
1882
- /** Similarity metric to use */
1883
- metric: VectorMetricType;
2082
+ /**
2083
+ * Similarity metric. Omitted when the caller didn't pass one — the compiler
2084
+ * then uses the field's DECLARED `embedding()` metric (resolved per kind),
2085
+ * falling back to "cosine" only when no declaration is available.
2086
+ */
2087
+ metric?: VectorMetricType;
1884
2088
  /** Maximum number of results to return */
1885
2089
  limit: number;
1886
2090
  /** Optional minimum similarity score (0-1 for cosine) */
@@ -2398,4 +2602,4 @@ type RelationalIndexDeclaration = NodeIndexDeclaration | EdgeIndexDeclaration;
2398
2602
  type IndexDeclaration = RelationalIndexDeclaration | VectorIndexDeclaration;
2399
2603
  type SystemColumnName = "graph_id" | "kind" | "id" | "from_kind" | "from_id" | "to_kind" | "to_id" | "deleted_at" | "valid_from" | "valid_to" | "created_at" | "updated_at" | "version";
2400
2604
 
2401
- export { type FulltextCapabilities as $, type AnySqliteDatabase as A, type BackendCapabilities as B, type VectorIndexParams as C, type SchemaVersionRow as D, type EdgeIndexConfig as E, type FulltextStrategy as F, type GraphBackend as G, type InferenceType as H, type IndexDeclaration as I, type JsonPointer as J, type AggregateExpr as K, type FieldRef as L, type MetaEdge as M, type NodeIndexConfig as N, type OntologyRelation as O, type ComparisonOp as P, type QueryAst as Q, type RelationalIndexDeclaration as R, type SqliteExecutionProfileHints as S, type AggregateComparisonPredicate as T, type AdoptedTransaction as U, type VectorIndexDeclaration as V, type CommitSchemaVersionExpected as W, type CommitSchemaVersionParams as X, DEFAULT_SQL_SCHEMA as Y, type DeleteFulltextBatchParams as Z, type FulltextBatchRow as _, type SqliteTransactionMode as a, type FulltextQueryMode as a0, type FulltextSearchParams as a1, type FulltextSearchResult as a2, type HybridFusionOptions as a3, type JsonPointerFor as a4, type JsonPointerInput as a5, type JsonPointerSegment as a6, type JsonPointerSegments as a7, type JsonPointerSegmentsFor as a8, MAX_JSON_POINTER_DEPTH as a9, type Traversal as aA, type NodePredicate as aB, type ProjectedField as aC, type GroupBySpec as aD, type RecursiveCyclePolicy as aE, type TraversalDirection as aF, type EdgeRow as aG, type NodeRow as aH, type SelectiveField as aI, type ComposableQuery as aJ, type SetOperationType as aK, type SetOperation as aL, type VectorMetric as aM, type MetaEdgeProperties as aa, type OrderSpec as ab, type ParameterRef as ac, type ResolveJsonPointer as ad, type ResolveJsonPointerSegments as ae, type SetActiveVersionParams as af, type SortDirection as ag, type SqlSchema as ah, type SqlTableNames as ai, type StrategyTableContribution as aj, type TableContribution as ak, type TransactionBackend as al, type TraversalExpansion as am, type UpsertFulltextBatchParams as an, type VectorCapabilities as ao, createSqlSchema as ap, fts5Strategy as aq, isMetaEdge as ar, joinJsonPointers as as, jsonPointer as at, normalizeJsonPointer as au, parseJsonPointer as av, tsvectorStrategy as aw, type ValueType as ax, type PredicateExpression as ay, type VectorMetricType as az, type AnyPgDatabase as b, type EdgeIndexDeclaration as c, type NodeIndexDeclaration as d, type IndexWhereExpression as e, type SerializedNodeDef as f, type SerializedEdgeDef as g, type SerializedMetaEdge as h, type SerializedOntologyRelation as i, type SerializedClosures as j, type SerializedSchema as k, type SchemaHash as l, type JsonSchema as m, type SerializedOntology as n, type SerializedUniqueConstraint as o, type SqlDialect as p, type EdgeIndexDirection as q, type EdgeIndexWhereBuilder as r, type IndexOrigin as s, type IndexScope as t, type IndexWhereFieldBuilder as u, type IndexWhereInput as v, type NodeIndexWhereBuilder as w, type SystemColumnName as x, type VectorIndexImplementation as y, type VectorIndexMetric as z };
2605
+ export { type FulltextBatchRow as $, type AnySqliteDatabase as A, type BackendCapabilities as B, type VectorIndexMetric as C, type VectorIndexParams as D, type EdgeIndexConfig as E, type FulltextStrategy as F, type GraphBackend as G, type SchemaVersionRow as H, type IndexDeclaration as I, type JsonPointer as J, type InferenceType as K, type AggregateExpr as L, type MetaEdge as M, type NodeIndexConfig as N, type OntologyRelation as O, type FieldRef as P, type QueryAst as Q, type RelationalIndexDeclaration as R, type SqliteExecutionProfileHints as S, type ComparisonOp as T, type AggregateComparisonPredicate as U, type VectorStrategy as V, type AdoptedTransaction as W, type CommitSchemaVersionExpected as X, type CommitSchemaVersionParams as Y, DEFAULT_SQL_SCHEMA as Z, type DeleteFulltextBatchParams as _, type SqliteTransactionMode as a, type FulltextCapabilities as a0, type FulltextQueryMode as a1, type FulltextSearchParams as a2, type FulltextSearchResult as a3, type HybridFusionOptions as a4, type JsonPointerFor as a5, type JsonPointerInput as a6, type JsonPointerSegment as a7, type JsonPointerSegments as a8, type JsonPointerSegmentsFor as a9, type VectorSlotMap as aA, type ValueType as aB, type PredicateExpression as aC, type VectorMetricType as aD, type Traversal as aE, type NodePredicate as aF, type ProjectedField as aG, type GroupBySpec as aH, type RecursiveCyclePolicy as aI, type TraversalDirection as aJ, type EdgeRow as aK, type NodeRow as aL, type SelectiveField as aM, type ComposableQuery as aN, type SetOperationType as aO, type SetOperation as aP, type VectorMetric as aQ, MAX_JSON_POINTER_DEPTH as aa, type MetaEdgeProperties as ab, type OrderSpec as ac, type ParameterRef as ad, type ResolveJsonPointer as ae, type ResolveJsonPointerSegments as af, type SetActiveVersionParams as ag, type SortDirection as ah, type SqlSchema as ai, type SqlTableNames as aj, type StrategyTableContribution as ak, type TableContribution as al, type TransactionBackend as am, type TraversalExpansion as an, type UpsertFulltextBatchParams as ao, type VectorCapabilities as ap, type VectorSlot as aq, buildVectorCapabilities as ar, createSqlSchema as as, fts5Strategy as at, isMetaEdge as au, joinJsonPointers as av, jsonPointer as aw, normalizeJsonPointer as ax, parseJsonPointer as ay, tsvectorStrategy as az, type AnyPgDatabase as b, type EdgeIndexDeclaration as c, type NodeIndexDeclaration as d, type IndexWhereExpression as e, type SerializedNodeDef as f, type SerializedEdgeDef as g, type SerializedMetaEdge as h, type SerializedOntologyRelation as i, type SerializedClosures as j, type SerializedSchema as k, type SchemaHash as l, type JsonSchema as m, type SerializedOntology as n, type SerializedUniqueConstraint as o, type SqlDialect as p, type EdgeIndexDirection as q, type EdgeIndexWhereBuilder as r, type IndexOrigin as s, type IndexScope as t, type IndexWhereFieldBuilder as u, type IndexWhereInput as v, type NodeIndexWhereBuilder as w, type SystemColumnName as x, type VectorIndexDeclaration as y, type VectorIndexImplementation as z };
@@ -1,5 +1,5 @@
1
- import { A as AnyEdgeType, N as NodeType } from './extension-types-B78CZfA5.cjs';
2
- import { E as EdgeIndexConfig, c as EdgeIndexDeclaration, N as NodeIndexConfig, d as NodeIndexDeclaration, e as IndexWhereExpression } from './types-CMQymcwk.cjs';
1
+ import { A as AnyEdgeType, N as NodeType } from './extension-types-CwHV-Uk4.cjs';
2
+ import { E as EdgeIndexConfig, c as EdgeIndexDeclaration, N as NodeIndexConfig, d as NodeIndexDeclaration, e as IndexWhereExpression } from './types-DXCSyxac.cjs';
3
3
 
4
4
  declare function defineNodeIndex<N extends NodeType>(node: N, config: NodeIndexConfig<N>): NodeIndexDeclaration;
5
5
  declare function defineEdgeIndex<E extends AnyEdgeType>(edge: E, config: EdgeIndexConfig<E>): EdgeIndexDeclaration;
@@ -1,5 +1,5 @@
1
- import { A as AnyEdgeType, N as NodeType } from './extension-types-B78CZfA5.js';
2
- import { E as EdgeIndexConfig, c as EdgeIndexDeclaration, N as NodeIndexConfig, d as NodeIndexDeclaration, e as IndexWhereExpression } from './types-CQ7xXJMP.js';
1
+ import { A as AnyEdgeType, N as NodeType } from './extension-types-CwHV-Uk4.js';
2
+ import { E as EdgeIndexConfig, c as EdgeIndexDeclaration, N as NodeIndexConfig, d as NodeIndexDeclaration, e as IndexWhereExpression } from './types-CmAT-Z47.js';
3
3
 
4
4
  declare function defineNodeIndex<N extends NodeType>(node: N, config: NodeIndexConfig<N>): NodeIndexDeclaration;
5
5
  declare function defineEdgeIndex<E extends AnyEdgeType>(edge: E, config: EdgeIndexConfig<E>): EdgeIndexDeclaration;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nicia-ai/typegraph",
3
- "version": "0.28.0",
3
+ "version": "0.29.0",
4
4
  "description": "TypeScript-first embedded knowledge graph library with ontological reasoning",
5
5
  "type": "module",
6
6
  "main": "./dist/index.cjs",
@@ -47,6 +47,11 @@
47
47
  "import": "./dist/backend/postgres/index.js",
48
48
  "require": "./dist/backend/postgres/index.cjs"
49
49
  },
50
+ "./postgres/pglite": {
51
+ "types": "./dist/backend/postgres/pglite.d.ts",
52
+ "import": "./dist/backend/postgres/pglite.js",
53
+ "require": "./dist/backend/postgres/pglite.cjs"
54
+ },
50
55
  "./sqlite/local": {
51
56
  "types": "./dist/backend/sqlite/local.d.ts",
52
57
  "import": "./dist/backend/sqlite/local.js",
@@ -92,6 +97,8 @@
92
97
  "node": ">=22"
93
98
  },
94
99
  "peerDependencies": {
100
+ "@electric-sql/pglite": ">=0.5.0 <0.6.0",
101
+ "@electric-sql/pglite-pgvector": ">=0.0.2 <1.0.0",
95
102
  "@libsql/client": ">=0.6.0",
96
103
  "@neondatabase/serverless": ">=0.9.0 <2.0.0",
97
104
  "better-sqlite3": ">=9.0.0 <13.0.0",
@@ -101,6 +108,12 @@
101
108
  "zod": "^4.0.0"
102
109
  },
103
110
  "peerDependenciesMeta": {
111
+ "@electric-sql/pglite": {
112
+ "optional": true
113
+ },
114
+ "@electric-sql/pglite-pgvector": {
115
+ "optional": true
116
+ },
104
117
  "@libsql/client": {
105
118
  "optional": true
106
119
  },
@@ -121,7 +134,9 @@
121
134
  "nanoid": "^5.1.11"
122
135
  },
123
136
  "devDependencies": {
124
- "@cloudflare/vitest-pool-workers": "^0.16.7",
137
+ "@cloudflare/vitest-pool-workers": "^0.16.12",
138
+ "@electric-sql/pglite": "^0.5.1",
139
+ "@electric-sql/pglite-pgvector": "^0.0.2",
125
140
  "@libsql/client": "^0.17.3",
126
141
  "@neondatabase/serverless": "^1.1.0",
127
142
  "@stryker-mutator/core": "^9.6.1",
@@ -129,10 +144,10 @@
129
144
  "@types/better-sqlite3": "^7.6.13",
130
145
  "@types/node": "^24.12.0",
131
146
  "@types/pg": "^8.20.0",
132
- "@vitest/coverage-v8": "^4.1.7",
147
+ "@vitest/coverage-v8": "^4.1.8",
133
148
  "better-sqlite3": "^12.10.0",
134
149
  "drizzle-orm": "^0.45.2",
135
- "eslint": "^10.4.0",
150
+ "eslint": "^10.4.1",
136
151
  "fast-check": "^4.8.0",
137
152
  "pg": "^8.21.0",
138
153
  "postgres": "^3.4.9",
@@ -140,7 +155,7 @@
140
155
  "tsd": "^0.33.0",
141
156
  "tsup": "^8.5.1",
142
157
  "typescript": "^5.9.3",
143
- "vitest": "^4.1.7",
158
+ "vitest": "^4.1.8",
144
159
  "zod": "^4.4.3",
145
160
  "@typegraph/eslint-config": "0.1.0"
146
161
  },