@nicia-ai/typegraph 0.28.1 → 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 (172) 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-TKM2WDT4.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-PGU2XKMA.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-O57GYGYK.js → chunk-M6OC455F.js} +32 -18
  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-5MTOKWDA.js → chunk-MRMD7S7E.js} +9 -9
  64. package/dist/{chunk-5MTOKWDA.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-FFHW2JEK.cjs → chunk-RP7YITHX.cjs} +32 -17
  76. package/dist/chunk-RP7YITHX.cjs.map +1 -0
  77. package/dist/{chunk-NMOE2ZEU.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-WZH2MKHW.cjs → chunk-XTQHSOIC.cjs} +101 -101
  88. package/dist/{chunk-WZH2MKHW.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-NYQFPGYP.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.cts → extension-types-CwHV-Uk4.d.cts} +4 -4
  100. package/dist/{extension-types-B78CZfA5.d.ts → 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-D7YEMg2v.d.cts → store-B43FpOVX.d.cts} +84 -5
  140. package/dist/{store-Ufc1Eoey.d.ts → 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-3EUKJEQ3.js +0 -77
  149. package/dist/chunk-3EUKJEQ3.js.map +0 -1
  150. package/dist/chunk-4FJVSF3K.cjs +0 -12
  151. package/dist/chunk-FFHW2JEK.cjs.map +0 -1
  152. package/dist/chunk-HTGDWIDE.cjs +0 -89
  153. package/dist/chunk-HTGDWIDE.cjs.map +0 -1
  154. package/dist/chunk-LYRUNG6E.cjs +0 -52
  155. package/dist/chunk-LYRUNG6E.cjs.map +0 -1
  156. package/dist/chunk-NMOE2ZEU.cjs.map +0 -1
  157. package/dist/chunk-NYQFPGYP.cjs.map +0 -1
  158. package/dist/chunk-O57GYGYK.js.map +0 -1
  159. package/dist/chunk-OYLF3IC7.js.map +0 -1
  160. package/dist/chunk-PCHTTG42.js +0 -47
  161. package/dist/chunk-PCHTTG42.js.map +0 -1
  162. package/dist/chunk-PGU2XKMA.js.map +0 -1
  163. package/dist/chunk-PN37HVAV.cjs.map +0 -1
  164. package/dist/chunk-PYJOBZR3.cjs.map +0 -1
  165. package/dist/chunk-TKM2WDT4.js.map +0 -1
  166. package/dist/chunk-TSGBRPNE.js.map +0 -1
  167. package/dist/chunk-U5ROKVRF.js.map +0 -1
  168. package/dist/chunk-WFUN6DCM.cjs.map +0 -1
  169. package/dist/chunk-WVQXAFP3.js.map +0 -1
  170. package/dist/chunk-X3244EKP.cjs.map +0 -1
  171. package/dist/chunk-YEDQLNVE.cjs.map +0 -1
  172. package/dist/chunk-ZTREJOGB.js.map +0 -1
@@ -32,7 +32,7 @@ function embedding(dimensions, options = {}) {
32
32
  });
33
33
  }
34
34
  function resolveEmbeddingIndex(options) {
35
- const indexType = options.indexType ?? "hnsw";
35
+ const indexType = options.indexType ?? DEFAULT_EMBEDDING_INDEX_TYPE;
36
36
  const m = options.m ?? DEFAULT_HNSW_M;
37
37
  const efConstruction = options.efConstruction ?? DEFAULT_HNSW_EF_CONSTRUCTION;
38
38
  if (m <= 0 || !Number.isInteger(m)) {
@@ -51,7 +51,7 @@ function resolveEmbeddingIndex(options) {
51
51
  );
52
52
  }
53
53
  return Object.freeze({
54
- metric: options.metric ?? "cosine",
54
+ metric: options.metric ?? DEFAULT_EMBEDDING_METRIC,
55
55
  indexType,
56
56
  m,
57
57
  efConstruction,
@@ -73,7 +73,48 @@ function getEmbeddingIndex(schema) {
73
73
  if (candidate === void 0) return void 0;
74
74
  return candidate;
75
75
  }
76
+ var DEFAULT_EMBEDDING_METRIC = "cosine";
77
+ var DEFAULT_EMBEDDING_INDEX_TYPE = "hnsw";
78
+ function resolveEmbeddingFields(schema) {
79
+ if (schema.type !== "object") return [];
80
+ const shape = schema.def.shape;
81
+ if (!shape) return [];
82
+ const fields = [];
83
+ for (const [fieldPath, fieldSchema] of Object.entries(shape)) {
84
+ const dimensions = resolveEmbeddingDimensions(fieldSchema);
85
+ if (dimensions === void 0) continue;
86
+ const index = resolveEmbeddingIndexConfig(fieldSchema);
87
+ fields.push({
88
+ fieldPath,
89
+ dimensions,
90
+ metric: index?.metric ?? DEFAULT_EMBEDDING_METRIC,
91
+ indexType: index?.indexType ?? DEFAULT_EMBEDDING_INDEX_TYPE
92
+ });
93
+ }
94
+ return fields;
95
+ }
96
+ function resolveEmbeddingDimensions(schema) {
97
+ const direct = getEmbeddingDimensions(schema);
98
+ if (direct !== void 0) return direct;
99
+ const unwrapped = unwrapToEmbedding(schema);
100
+ return unwrapped === void 0 ? void 0 : getEmbeddingDimensions(unwrapped);
101
+ }
102
+ function resolveEmbeddingIndexConfig(schema) {
103
+ const direct = getEmbeddingIndex(schema);
104
+ if (direct !== void 0) return direct;
105
+ const unwrapped = unwrapToEmbedding(schema);
106
+ return unwrapped === void 0 ? void 0 : getEmbeddingIndex(unwrapped);
107
+ }
108
+ function unwrapToEmbedding(schema) {
109
+ const type = schema.type;
110
+ const innerType = schema.def.innerType;
111
+ if ((type === "optional" || type === "nullable" || type === "default" || type === "readonly") && innerType) {
112
+ if (isEmbeddingSchema(innerType)) return innerType;
113
+ return unwrapToEmbedding(innerType);
114
+ }
115
+ return void 0;
116
+ }
76
117
 
77
- export { embedding, getEmbeddingDimensions, getEmbeddingIndex, isEmbeddingSchema };
78
- //# sourceMappingURL=chunk-WVQXAFP3.js.map
79
- //# sourceMappingURL=chunk-WVQXAFP3.js.map
118
+ export { DEFAULT_EMBEDDING_INDEX_TYPE, DEFAULT_EMBEDDING_METRIC, embedding, getEmbeddingDimensions, getEmbeddingIndex, isEmbeddingSchema, resolveEmbeddingFields };
119
+ //# sourceMappingURL=chunk-454I6GDF.js.map
120
+ //# sourceMappingURL=chunk-454I6GDF.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/core/embedding.ts"],"names":[],"mappings":"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","file":"chunk-454I6GDF.js","sourcesContent":["/**\n * Embedding type for vector search.\n *\n * Creates a Zod-compatible schema for vector embeddings with\n * dimension validation and metadata for query compilation.\n */\nimport { z } from \"zod\";\n\n// ============================================================\n// Embedding Brand Symbol\n// ============================================================\n\n/**\n * Symbol used to brand embedding values at the type level.\n * This allows TypeScript to distinguish embedding arrays from regular\n * number arrays in the query builder type system.\n */\ndeclare const EMBEDDING_BRAND: unique symbol;\n\n/**\n * Branded embedding type for type-level distinction.\n * At runtime this is just `readonly number[]`, but TypeScript can\n * distinguish it from regular arrays for query builder typing.\n */\nexport type EmbeddingValue = readonly number[] & {\n readonly [EMBEDDING_BRAND]: true;\n};\n\n// ============================================================\n// Embedding Metadata Symbol\n// ============================================================\n\n/**\n * Symbol key for storing embedding dimensions on the schema.\n * This allows the schema introspector to detect embedding types\n * and extract dimension information.\n */\nexport const EMBEDDING_DIMENSIONS_KEY = \"_embeddingDimensions\" as const;\n\n/**\n * Symbol key for storing the embedding's preferred index configuration\n * on the schema. The schema introspector reads this when auto-deriving\n * `VectorIndexDeclaration` entries at `defineGraph()` time.\n */\nexport const EMBEDDING_INDEX_KEY = \"_embeddingIndex\" as const;\n\n/**\n * Distance metric used for vector similarity. Pinned at the embedding\n * brand because changing the metric usually means generating different\n * model output (e.g. cosine-normalized vs. raw inner-product), and the\n * stored index needs the same metric to score correctly.\n *\n * - `cosine`: cosine similarity. The default — works for most\n * sentence-transformer / OpenAI-style embeddings that are already\n * length-normalized.\n * - `l2`: Euclidean distance. Use when your model outputs vectors\n * trained for L2 (e.g. some image embedding models).\n * - `inner_product`: dot-product distance. Use when your model outputs\n * pre-normalized vectors AND you want to skip the cosine\n * normalization step at query time.\n */\nexport type EmbeddingMetric = \"cosine\" | \"l2\" | \"inner_product\";\n\n/**\n * Vector index implementation. `hnsw` is the default and what pgvector\n * recommends for most workloads. `ivfflat` is the alternative for\n * larger datasets where memory is the bottleneck. `none` disables\n * automatic index creation for this embedding (the operator can still\n * call `backend.createVectorIndex` manually).\n */\nexport type EmbeddingIndexType = \"hnsw\" | \"ivfflat\" | \"none\";\n\n/**\n * Per-embedding configuration for the auto-derived\n * `VectorIndexDeclaration`. All fields are optional with sensible\n * defaults (`cosine` / `hnsw` / pgvector defaults: `m=16`,\n * `ef_construction=64`). Override only when your model or dataset has\n * a known reason to.\n */\nexport type EmbeddingIndexOptions = Readonly<{\n /** Distance metric. Default `\"cosine\"`. */\n metric?: EmbeddingMetric;\n /** Vector index implementation. Default `\"hnsw\"`. */\n indexType?: EmbeddingIndexType;\n /** HNSW `m` parameter — max connections per layer. Default `16`. */\n m?: number;\n /** HNSW `ef_construction` parameter — build-time search depth. Default `64`. */\n efConstruction?: number;\n /** IVFFlat `lists` parameter — number of inverted-list partitions. */\n lists?: number;\n}>;\n\n/**\n * Resolved embedding index configuration with all defaults applied.\n * What gets attached to the brand and read by the auto-derivation pass.\n */\nexport type ResolvedEmbeddingIndex = Readonly<{\n metric: EmbeddingMetric;\n indexType: EmbeddingIndexType;\n m: number;\n efConstruction: number;\n lists: number | undefined;\n}>;\n\nconst DEFAULT_HNSW_M = 16;\nconst DEFAULT_HNSW_EF_CONSTRUCTION = 64;\n\n// ============================================================\n// Embedding Schema Type\n// ============================================================\n\n/**\n * A Zod schema for vector embeddings with attached dimension metadata.\n * Uses the branded EmbeddingValue type for type-level distinction.\n */\nexport type EmbeddingSchema<D extends number = number> =\n z.ZodType<EmbeddingValue> &\n Readonly<{\n [EMBEDDING_DIMENSIONS_KEY]: D;\n [EMBEDDING_INDEX_KEY]: ResolvedEmbeddingIndex;\n }>;\n\n// ============================================================\n// Embedding Factory\n// ============================================================\n\n/**\n * Creates a Zod schema for vector embeddings.\n *\n * The dimension is validated at runtime and attached as metadata\n * for the schema introspector and query compiler.\n *\n * @param dimensions - The number of dimensions (e.g., 384, 512, 768, 1536, 3072)\n * @returns A Zod schema that validates embedding arrays\n *\n * @example\n * ```typescript\n * // OpenAI ada-002 embeddings\n * const Document = defineNode(\"Document\", {\n * schema: z.object({\n * title: z.string(),\n * embedding: embedding(1536),\n * }),\n * });\n *\n * // Sentence transformers\n * const Sentence = defineNode(\"Sentence\", {\n * schema: z.object({\n * text: z.string(),\n * embedding: embedding(384), // all-MiniLM-L6-v2\n * }),\n * });\n *\n * // Optional embeddings are supported\n * const Article = defineNode(\"Article\", {\n * schema: z.object({\n * content: z.string(),\n * embedding: embedding(1536).optional(),\n * }),\n * });\n * ```\n */\nexport function embedding<D extends number>(\n dimensions: D,\n options: EmbeddingIndexOptions = {},\n): EmbeddingSchema<D> {\n if (!Number.isInteger(dimensions) || dimensions <= 0) {\n throw new Error(\n `Embedding dimensions must be a positive integer, got: ${dimensions}`,\n );\n }\n\n const indexConfig = resolveEmbeddingIndex(options);\n\n // Use EmbeddingValue as the output type for proper type branding.\n // At runtime, validation accepts any number array with correct dimensions.\n const schema = z.custom<EmbeddingValue>(\n (value): value is EmbeddingValue => {\n if (!Array.isArray(value)) {\n return false;\n }\n if (value.length !== dimensions) {\n return false;\n }\n return value.every((n) => typeof n === \"number\" && Number.isFinite(n));\n },\n {\n message: `Expected an array of ${dimensions} finite numbers`,\n },\n );\n\n return Object.assign(schema, {\n [EMBEDDING_DIMENSIONS_KEY]: dimensions,\n [EMBEDDING_INDEX_KEY]: indexConfig,\n });\n}\n\nfunction resolveEmbeddingIndex(\n options: EmbeddingIndexOptions,\n): ResolvedEmbeddingIndex {\n const indexType = options.indexType ?? DEFAULT_EMBEDDING_INDEX_TYPE;\n const m = options.m ?? DEFAULT_HNSW_M;\n const efConstruction = options.efConstruction ?? DEFAULT_HNSW_EF_CONSTRUCTION;\n\n if (m <= 0 || !Number.isInteger(m)) {\n throw new Error(\n `embedding() index option 'm' must be a positive integer, got: ${m}`,\n );\n }\n if (efConstruction <= 0 || !Number.isInteger(efConstruction)) {\n throw new Error(\n `embedding() index option 'efConstruction' must be a positive integer, got: ${efConstruction}`,\n );\n }\n if (\n options.lists !== undefined &&\n (options.lists <= 0 || !Number.isInteger(options.lists))\n ) {\n throw new Error(\n `embedding() index option 'lists' must be a positive integer, got: ${options.lists}`,\n );\n }\n\n return Object.freeze({\n metric: options.metric ?? DEFAULT_EMBEDDING_METRIC,\n indexType,\n m,\n efConstruction,\n lists: options.lists,\n });\n}\n\n// ============================================================\n// Type Guards\n// ============================================================\n\n/**\n * Checks if a value is an embedding schema.\n */\nexport function isEmbeddingSchema(value: unknown): value is EmbeddingSchema {\n return (\n typeof value === \"object\" &&\n value !== null &&\n EMBEDDING_DIMENSIONS_KEY in value &&\n typeof (value as Record<string, unknown>)[EMBEDDING_DIMENSIONS_KEY] ===\n \"number\"\n );\n}\n\n/**\n * Gets the dimensions from an embedding schema.\n * Returns undefined if the schema is not an embedding schema.\n */\nexport function getEmbeddingDimensions(schema: z.ZodType): number | undefined {\n if (isEmbeddingSchema(schema)) {\n return schema[EMBEDDING_DIMENSIONS_KEY];\n }\n return undefined;\n}\n\n/**\n * Gets the resolved index configuration from an embedding schema.\n * Returns undefined if the schema is not an embedding schema. Used by\n * the auto-derivation pass at `defineGraph()` time to build vector\n * `IndexDeclaration` entries.\n */\nexport function getEmbeddingIndex(\n schema: z.ZodType,\n): ResolvedEmbeddingIndex | undefined {\n if (!isEmbeddingSchema(schema)) return undefined;\n const candidate = (schema as unknown as Record<string, unknown>)[\n EMBEDDING_INDEX_KEY\n ];\n if (candidate === undefined) return undefined;\n return candidate as ResolvedEmbeddingIndex;\n}\n\n// ============================================================\n// Embedding Field Resolution\n// ============================================================\n\n/**\n * One resolved embedding field on a node schema — its dot-path plus the\n * fixed `dimensions` and the resolved index `(metric, indexType)`.\n * Sourced from the field's `embedding()` brand, unwrapping `.optional()`\n * / `.nullable()` / `.default()` / `.readonly()` wrappers. The single\n * source of truth shared by embedding sync (write path), the query\n * compiler's `field.similarTo(...)` slot resolution, and search.\n */\nexport type ResolvedEmbeddingField = Readonly<{\n fieldPath: string;\n dimensions: number;\n metric: EmbeddingMetric;\n indexType: EmbeddingIndexType;\n}>;\n\n/**\n * The single source of truth for an embedding field's default metric / index\n * type when unspecified — used by `embedding()` declaration resolution, the\n * field-fallback below, and the legacy-migration slot defaults\n * (`migrate-vectors.ts`) so the three never drift.\n */\nexport const DEFAULT_EMBEDDING_METRIC: EmbeddingMetric = \"cosine\";\nexport const DEFAULT_EMBEDDING_INDEX_TYPE: EmbeddingIndexType = \"hnsw\";\n\n/**\n * Extracts every top-level embedding field from a node's object schema.\n * Returns `[]` for non-object schemas or schemas with no embedding\n * fields. Embeddings nested inside object properties are out of scope by\n * design (storage keys at the top-level `(kind, fieldPath)` grain).\n */\nexport function resolveEmbeddingFields(\n schema: z.ZodType,\n): readonly ResolvedEmbeddingField[] {\n if (schema.type !== \"object\") return [];\n const shape = (schema.def as { shape?: Record<string, z.ZodType> }).shape;\n if (!shape) return [];\n\n const fields: ResolvedEmbeddingField[] = [];\n for (const [fieldPath, fieldSchema] of Object.entries(shape)) {\n const dimensions = resolveEmbeddingDimensions(fieldSchema);\n if (dimensions === undefined) continue;\n const index = resolveEmbeddingIndexConfig(fieldSchema);\n fields.push({\n fieldPath,\n dimensions,\n metric: index?.metric ?? DEFAULT_EMBEDDING_METRIC,\n indexType: index?.indexType ?? DEFAULT_EMBEDDING_INDEX_TYPE,\n });\n }\n return fields;\n}\n\nfunction resolveEmbeddingDimensions(schema: z.ZodType): number | undefined {\n const direct = getEmbeddingDimensions(schema);\n if (direct !== undefined) return direct;\n const unwrapped = unwrapToEmbedding(schema);\n return unwrapped === undefined ? undefined : (\n getEmbeddingDimensions(unwrapped)\n );\n}\n\nfunction resolveEmbeddingIndexConfig(\n schema: z.ZodType,\n): ResolvedEmbeddingIndex | undefined {\n const direct = getEmbeddingIndex(schema);\n if (direct !== undefined) return direct;\n const unwrapped = unwrapToEmbedding(schema);\n return unwrapped === undefined ? undefined : getEmbeddingIndex(unwrapped);\n}\n\n/**\n * Unwraps optional / nullable / default / readonly wrappers to find the\n * inner embedding schema, recursing through chained wrappers. Returns\n * `undefined` when no embedding schema is reachable.\n */\nfunction unwrapToEmbedding(schema: z.ZodType): z.ZodType | undefined {\n const type = schema.type;\n const innerType = (schema.def as { innerType?: z.ZodType }).innerType;\n if (\n (type === \"optional\" ||\n type === \"nullable\" ||\n type === \"default\" ||\n type === \"readonly\") &&\n innerType\n ) {\n if (isEmbeddingSchema(innerType)) return innerType;\n return unwrapToEmbedding(innerType);\n }\n return undefined;\n}\n"]}
@@ -0,0 +1,183 @@
1
+ 'use strict';
2
+
3
+ var chunkC2RWFIYP_cjs = require('./chunk-C2RWFIYP.cjs');
4
+ var drizzleOrm = require('drizzle-orm');
5
+
6
+ var TABLE_PREFIX = "tg_vec";
7
+ var SQLITE_VEC_MAX_DIMENSIONS = 8e3;
8
+ var SQLITE_VEC_CAPABILITIES = {
9
+ supported: true,
10
+ metrics: ["cosine", "l2"],
11
+ // vec0 always indexes inline, so the portable ANN intent ("hnsw", the
12
+ // `embedding()` default) is honored by real KNN; "none" stays brute-force.
13
+ // Both map to the same vec0 table — only `buildSearch` differs.
14
+ indexTypes: ["hnsw", "none"],
15
+ maxDimensions: SQLITE_VEC_MAX_DIMENSIONS
16
+ };
17
+ function usesAnnIndex(slot) {
18
+ return slot.indexType === "hnsw";
19
+ }
20
+ function sqliteVecMetricToken(metric) {
21
+ switch (metric) {
22
+ case "cosine": {
23
+ return "cosine";
24
+ }
25
+ case "l2": {
26
+ return "l2";
27
+ }
28
+ case "inner_product": {
29
+ throw new Error(
30
+ "sqlite-vec does not support inner_product. Use 'cosine' or 'l2'."
31
+ );
32
+ }
33
+ default: {
34
+ const _exhaustive = metric;
35
+ throw new Error(`Unsupported vector metric: ${String(_exhaustive)}`);
36
+ }
37
+ }
38
+ }
39
+ function vecF32Literal(embedding, name) {
40
+ chunkC2RWFIYP_cjs.assertFiniteEmbedding(embedding, name);
41
+ return drizzleOrm.sql`vec_f32(${JSON.stringify(embedding)})`;
42
+ }
43
+ function distanceExpression(embeddingColumn, queryEmbedding, metric) {
44
+ const query = vecF32Literal(queryEmbedding, "queryEmbedding");
45
+ switch (metric) {
46
+ case "cosine": {
47
+ return drizzleOrm.sql`vec_distance_cosine(${embeddingColumn}, ${query})`;
48
+ }
49
+ case "l2": {
50
+ return drizzleOrm.sql`vec_distance_l2(${embeddingColumn}, ${query})`;
51
+ }
52
+ case "inner_product": {
53
+ throw new Error(
54
+ "sqlite-vec does not support inner_product. Use 'cosine' or 'l2'."
55
+ );
56
+ }
57
+ default: {
58
+ const _exhaustive = metric;
59
+ throw new Error(`Unsupported vector metric: ${String(_exhaustive)}`);
60
+ }
61
+ }
62
+ }
63
+ var sqliteVecStrategy = {
64
+ name: "sqlite-vec",
65
+ capabilities: SQLITE_VEC_CAPABILITIES,
66
+ tableName(graphId, nodeKind, fieldPath) {
67
+ return chunkC2RWFIYP_cjs.vectorPhysicalName(TABLE_PREFIX, graphId, nodeKind, fieldPath);
68
+ },
69
+ ownedTables(slot) {
70
+ const table = this.tableName(slot.graphId, slot.nodeKind, slot.fieldPath);
71
+ const name = chunkC2RWFIYP_cjs.quoteIdentifier(table);
72
+ const metric = sqliteVecMetricToken(slot.metric);
73
+ return [
74
+ {
75
+ logicalName: `${chunkC2RWFIYP_cjs.VECTOR_CONTRIBUTION_PREFIX}:${slot.nodeKind}.${slot.fieldPath}`,
76
+ owner: "sqlite-vec",
77
+ tableName: table,
78
+ createDdl: [
79
+ `CREATE VIRTUAL TABLE IF NOT EXISTS ${name} USING vec0(
80
+ node_id TEXT PRIMARY KEY,
81
+ graph_id TEXT PARTITION KEY,
82
+ +created_at TEXT,
83
+ +updated_at TEXT,
84
+ embedding float[${slot.dimensions}] distance_metric=${metric}
85
+ );`
86
+ ],
87
+ runtimeEnsure: true
88
+ }
89
+ ];
90
+ },
91
+ buildUpsert(slot, params, timestamp) {
92
+ const table = chunkC2RWFIYP_cjs.quotedTableName(
93
+ this.tableName(slot.graphId, slot.nodeKind, slot.fieldPath)
94
+ );
95
+ const value = vecF32Literal(params.embedding, "embedding");
96
+ return [
97
+ drizzleOrm.sql`
98
+ DELETE FROM ${table}
99
+ WHERE "node_id" = ${params.nodeId} AND "graph_id" = ${params.graphId}
100
+ `,
101
+ drizzleOrm.sql`
102
+ INSERT INTO ${table} ("node_id", "graph_id", "created_at", "updated_at", "embedding")
103
+ VALUES (${params.nodeId}, ${params.graphId}, ${timestamp}, ${timestamp}, ${value})
104
+ `
105
+ ];
106
+ },
107
+ buildDelete(slot, params) {
108
+ const table = chunkC2RWFIYP_cjs.quotedTableName(
109
+ this.tableName(slot.graphId, slot.nodeKind, slot.fieldPath)
110
+ );
111
+ return [
112
+ drizzleOrm.sql`
113
+ DELETE FROM ${table}
114
+ WHERE "node_id" = ${params.nodeId} AND "graph_id" = ${params.graphId}
115
+ `
116
+ ];
117
+ },
118
+ buildSearch(slot, params) {
119
+ const table = chunkC2RWFIYP_cjs.quotedTableName(
120
+ this.tableName(slot.graphId, slot.nodeKind, slot.fieldPath)
121
+ );
122
+ const embeddingColumn = drizzleOrm.sql`${table}."embedding"`;
123
+ const distance = distanceExpression(
124
+ embeddingColumn,
125
+ params.queryEmbedding,
126
+ params.metric
127
+ );
128
+ const score = chunkC2RWFIYP_cjs.vectorScoreExpression(distance, params.metric);
129
+ if (usesAnnIndex(slot)) {
130
+ const query = vecF32Literal(params.queryEmbedding, "queryEmbedding");
131
+ const conditions2 = [
132
+ drizzleOrm.sql`${table}."embedding" MATCH ${query}`,
133
+ drizzleOrm.sql`k = ${params.limit}`,
134
+ drizzleOrm.sql`${table}."graph_id" = ${params.graphId}`
135
+ ];
136
+ if (params.minScore !== void 0) {
137
+ conditions2.push(
138
+ chunkC2RWFIYP_cjs.vectorMinScoreCondition(distance, params.metric, params.minScore)
139
+ );
140
+ }
141
+ return drizzleOrm.sql`
142
+ SELECT ${table}."node_id" AS node_id, ${score} AS score
143
+ FROM ${table}
144
+ WHERE ${drizzleOrm.sql.join(conditions2, drizzleOrm.sql` AND `)}
145
+ ORDER BY distance ASC
146
+ `;
147
+ }
148
+ const conditions = [drizzleOrm.sql`${table}."graph_id" = ${params.graphId}`];
149
+ if (params.minScore !== void 0) {
150
+ conditions.push(
151
+ chunkC2RWFIYP_cjs.vectorMinScoreCondition(distance, params.metric, params.minScore)
152
+ );
153
+ }
154
+ return drizzleOrm.sql`
155
+ SELECT ${table}."node_id" AS node_id, ${score} AS score
156
+ FROM ${table}
157
+ WHERE ${drizzleOrm.sql.join(conditions, drizzleOrm.sql` AND `)}
158
+ ORDER BY ${distance} ASC
159
+ LIMIT ${params.limit}
160
+ `;
161
+ },
162
+ distanceExpression(embeddingColumn, queryEmbedding, metric) {
163
+ return distanceExpression(embeddingColumn, queryEmbedding, metric);
164
+ },
165
+ // vec0 indexes inline (the virtual table is the index), so there is no
166
+ // standalone ANN index to create or drop — both return undefined.
167
+ buildCreateIndex() {
168
+ return void 0;
169
+ },
170
+ buildDropIndex() {
171
+ return void 0;
172
+ },
173
+ buildDropStorage(slot) {
174
+ const table = chunkC2RWFIYP_cjs.quoteIdentifier(
175
+ this.tableName(slot.graphId, slot.nodeKind, slot.fieldPath)
176
+ );
177
+ return [`DROP TABLE IF EXISTS ${table}`];
178
+ }
179
+ };
180
+
181
+ exports.sqliteVecStrategy = sqliteVecStrategy;
182
+ //# sourceMappingURL=chunk-4K6IHUW6.cjs.map
183
+ //# sourceMappingURL=chunk-4K6IHUW6.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/query/dialect/vector/sqlite-vec-strategy.ts"],"names":["assertFiniteEmbedding","sql","vectorPhysicalName","quoteIdentifier","VECTOR_CONTRIBUTION_PREFIX","quotedTableName","vectorScoreExpression","conditions","vectorMinScoreCondition"],"mappings":"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","file":"chunk-4K6IHUW6.cjs","sourcesContent":["/**\n * sqlite-vec strategy — real `vec0` KNN for local SQLite.\n *\n * This upgrades `createLocalSqliteBackend` (better-sqlite3 + the sqlite-vec\n * extension) from the legacy brute-force-on-a-shared-table model to genuine\n * approximate-nearest-neighbor search on per-`(nodeKind, fieldPath)` storage.\n *\n * ## Storage choice: a `vec0` virtual table per field\n *\n * Each slot is backed by its own `vec0` virtual table:\n *\n * ```sql\n * CREATE VIRTUAL TABLE tg_vec_<kind>_<field> USING vec0(\n * node_id TEXT PRIMARY KEY,\n * graph_id TEXT PARTITION KEY,\n * +created_at TEXT,\n * +updated_at TEXT,\n * embedding float[<N>] distance_metric=<cosine|l2>\n * );\n * ```\n *\n * Verified against the installed `sqlite-vec` `v0.1.9`:\n *\n * - **vec0 over a plain `vec_f32` BLOB column.** The shipped option (a) — a\n * `vec0` virtual table — is chosen over option (b) — a regular table whose\n * `vec_f32` BLOB column is brute-forced — because vec0 is the *only* form\n * that gives local SQLite a real ANN index (today's code only ever\n * brute-forces). vec0 indexes inline (the virtual table *is* the index), so\n * there is no separate `CREATE INDEX` step.\n * - **KNN with partition-correct filtering.** `WHERE embedding MATCH vec_f32(q)\n * AND k = ? AND graph_id = ?` returns the nearest `k`, ordered by `distance`,\n * scoped to one graph — a near vector in another `graph_id` partition does\n * not leak. This is strictly better than libSQL's table-global `vector_top_k`\n * (which over-fetches for multi-graph correctness): vec0's `PARTITION KEY`\n * makes the per-graph KNN exact.\n * - **One table serves both read paths.** The same `embedding` column answers\n * the compiler's brute-force `distanceExpression` (`vec_distance_cosine` /\n * `vec_distance_l2` over the column, `ORDER BY … LIMIT`, no `MATCH`), so the\n * `.where(field.similarTo(...))` CTE path needs no second structure.\n * - **`k` and `LIMIT` are mutually exclusive** in a vec0 `MATCH` query, so the\n * ANN path uses `k = <limit>` with no `LIMIT`, and the brute-force path uses\n * `LIMIT <limit>` with no `MATCH`.\n * - **No `ON CONFLICT` / `INSERT OR REPLACE`** on a vec0 primary key, so upsert\n * is `DELETE` + `INSERT` (atomic under the caller's outer transaction),\n * mirroring the FTS5 strategy.\n *\n * Metric support is `cosine` + `l2` (no `inner_product` — sqlite-vec has no\n * `vec_distance_ip`), advertised as data on `capabilities`. The table's\n * `distance_metric` is fixed at creation from the slot's metric, alongside its\n * fixed dimension `N`.\n *\n * The libSQL and pgvector siblings implement the same `VectorStrategy`\n * contract for their engines.\n */\nimport { type SQL, sql } from \"drizzle-orm\";\n\nimport { quotedTableName } from \"../../../backend/drizzle/operations/shared\";\nimport { type StrategyTableContribution } from \"../../../backend/table-contribution\";\nimport {\n type DeleteEmbeddingParams,\n type UpsertEmbeddingParams,\n type VectorCapabilities,\n type VectorMetric,\n type VectorSearchParams,\n} from \"../../../backend/types\";\nimport {\n assertFiniteEmbedding,\n quoteIdentifier,\n VECTOR_CONTRIBUTION_PREFIX,\n vectorMinScoreCondition,\n vectorPhysicalName,\n vectorScoreExpression,\n type VectorSlot,\n type VectorStrategy,\n} from \"../vector-strategy\";\n\n/** Physical-name prefix for the per-field `vec0` virtual table. */\nconst TABLE_PREFIX = \"tg_vec\";\n\n/**\n * sqlite-vec stores each dimension as a 32-bit float; `float[N]` accepts\n * large `N`, but we advertise the same conservative ceiling the legacy\n * SQLite path used so capability discovery is stable across the swap.\n */\nconst SQLITE_VEC_MAX_DIMENSIONS = 8000;\n\nconst SQLITE_VEC_CAPABILITIES: VectorCapabilities = {\n supported: true,\n metrics: [\"cosine\", \"l2\"],\n // vec0 always indexes inline, so the portable ANN intent (\"hnsw\", the\n // `embedding()` default) is honored by real KNN; \"none\" stays brute-force.\n // Both map to the same vec0 table — only `buildSearch` differs.\n indexTypes: [\"hnsw\", \"none\"],\n maxDimensions: SQLITE_VEC_MAX_DIMENSIONS,\n};\n\n/** Whether a slot's declared index type maps to vec0's `MATCH … k =` KNN. */\nfunction usesAnnIndex(slot: VectorSlot): boolean {\n return slot.indexType === \"hnsw\";\n}\n\n/** vec0 `distance_metric` token accepted in the virtual-table definition. */\nfunction sqliteVecMetricToken(metric: VectorMetric): string {\n switch (metric) {\n case \"cosine\": {\n return \"cosine\";\n }\n case \"l2\": {\n return \"l2\";\n }\n case \"inner_product\": {\n throw new Error(\n \"sqlite-vec does not support inner_product. Use 'cosine' or 'l2'.\",\n );\n }\n default: {\n const _exhaustive: never = metric;\n throw new Error(`Unsupported vector metric: ${String(_exhaustive)}`);\n }\n }\n}\n\n/**\n * Formats an embedding as the bound JSON argument to `vec_f32(...)`. The\n * value rides as a parameter (not interpolated) — `vec_f32` parses the JSON\n * array into the packed float blob. Finiteness is validated first so a\n * NaN/Infinity names its index before JSON.stringify masks it as `null`.\n */\nfunction vecF32Literal(embedding: readonly number[], name: string): SQL {\n assertFiniteEmbedding(embedding, name);\n return sql`vec_f32(${JSON.stringify(embedding)})`;\n}\n\nfunction distanceExpression(\n embeddingColumn: SQL,\n queryEmbedding: readonly number[],\n metric: VectorMetric,\n): SQL {\n const query = vecF32Literal(queryEmbedding, \"queryEmbedding\");\n switch (metric) {\n case \"cosine\": {\n return sql`vec_distance_cosine(${embeddingColumn}, ${query})`;\n }\n case \"l2\": {\n return sql`vec_distance_l2(${embeddingColumn}, ${query})`;\n }\n case \"inner_product\": {\n throw new Error(\n \"sqlite-vec does not support inner_product. Use 'cosine' or 'l2'.\",\n );\n }\n default: {\n const _exhaustive: never = metric;\n throw new Error(`Unsupported vector metric: ${String(_exhaustive)}`);\n }\n }\n}\n\nexport const sqliteVecStrategy: VectorStrategy = {\n name: \"sqlite-vec\",\n capabilities: SQLITE_VEC_CAPABILITIES,\n\n tableName(graphId, nodeKind, fieldPath) {\n return vectorPhysicalName(TABLE_PREFIX, graphId, nodeKind, fieldPath);\n },\n\n ownedTables(slot): readonly StrategyTableContribution[] {\n const table = this.tableName(slot.graphId, slot.nodeKind, slot.fieldPath);\n const name = quoteIdentifier(table);\n const metric = sqliteVecMetricToken(slot.metric);\n\n // vec0 virtual tables cannot be modeled as a Drizzle table, so this is a\n // raw-ddl contribution — emitted verbatim and invisible to drizzle-kit.\n // `graph_id` is a PARTITION KEY so per-graph KNN is exact; `created_at` /\n // `updated_at` are auxiliary (`+`) columns (stored, not filtered on). The\n // virtual table *is* the index — no separate CREATE INDEX is emitted.\n return [\n {\n logicalName: `${VECTOR_CONTRIBUTION_PREFIX}:${slot.nodeKind}.${slot.fieldPath}`,\n owner: \"sqlite-vec\",\n tableName: table,\n createDdl: [\n `CREATE VIRTUAL TABLE IF NOT EXISTS ${name} USING vec0(\n node_id TEXT PRIMARY KEY,\n graph_id TEXT PARTITION KEY,\n +created_at TEXT,\n +updated_at TEXT,\n embedding float[${slot.dimensions}] distance_metric=${metric}\n);`,\n ],\n runtimeEnsure: true,\n },\n ];\n },\n\n buildUpsert(slot, params: UpsertEmbeddingParams, timestamp): readonly SQL[] {\n const table = quotedTableName(\n this.tableName(slot.graphId, slot.nodeKind, slot.fieldPath),\n );\n const value = vecF32Literal(params.embedding, \"embedding\");\n // vec0 rejects ON CONFLICT / INSERT OR REPLACE on its primary key —\n // emulate upsert with DELETE + INSERT, atomic under the caller's\n // outer transaction (mirrors the FTS5 fulltext strategy).\n return [\n sql`\n DELETE FROM ${table}\n WHERE \"node_id\" = ${params.nodeId} AND \"graph_id\" = ${params.graphId}\n `,\n sql`\n INSERT INTO ${table} (\"node_id\", \"graph_id\", \"created_at\", \"updated_at\", \"embedding\")\n VALUES (${params.nodeId}, ${params.graphId}, ${timestamp}, ${timestamp}, ${value})\n `,\n ];\n },\n\n buildDelete(slot, params: DeleteEmbeddingParams): readonly SQL[] {\n const table = quotedTableName(\n this.tableName(slot.graphId, slot.nodeKind, slot.fieldPath),\n );\n return [\n sql`\n DELETE FROM ${table}\n WHERE \"node_id\" = ${params.nodeId} AND \"graph_id\" = ${params.graphId}\n `,\n ];\n },\n\n buildSearch(slot, params: VectorSearchParams): SQL {\n const table = quotedTableName(\n this.tableName(slot.graphId, slot.nodeKind, slot.fieldPath),\n );\n const embeddingColumn = sql`${table}.\"embedding\"`;\n const distance = distanceExpression(\n embeddingColumn,\n params.queryEmbedding,\n params.metric,\n );\n const score = vectorScoreExpression(distance, params.metric);\n\n if (usesAnnIndex(slot)) {\n // vec0 KNN. `k` and `LIMIT` are mutually exclusive in a MATCH query, so\n // bound `k = limit` and omit LIMIT. `graph_id` filters by the partition\n // key (exact, no recall loss). Order by vec0's own `distance` column —\n // the recomputed `distance` expression is reused only for score/minScore\n // so the math matches the brute-force path and the shared helpers.\n const query = vecF32Literal(params.queryEmbedding, \"queryEmbedding\");\n const conditions: SQL[] = [\n sql`${table}.\"embedding\" MATCH ${query}`,\n sql`k = ${params.limit}`,\n sql`${table}.\"graph_id\" = ${params.graphId}`,\n ];\n if (params.minScore !== undefined) {\n conditions.push(\n vectorMinScoreCondition(distance, params.metric, params.minScore),\n );\n }\n return sql`\n SELECT ${table}.\"node_id\" AS node_id, ${score} AS score\n FROM ${table}\n WHERE ${sql.join(conditions, sql` AND `)}\n ORDER BY distance ASC\n `;\n }\n\n // Brute-force scan: no MATCH, so LIMIT is allowed (and required).\n const conditions: SQL[] = [sql`${table}.\"graph_id\" = ${params.graphId}`];\n if (params.minScore !== undefined) {\n conditions.push(\n vectorMinScoreCondition(distance, params.metric, params.minScore),\n );\n }\n return sql`\n SELECT ${table}.\"node_id\" AS node_id, ${score} AS score\n FROM ${table}\n WHERE ${sql.join(conditions, sql` AND `)}\n ORDER BY ${distance} ASC\n LIMIT ${params.limit}\n `;\n },\n\n distanceExpression(embeddingColumn, queryEmbedding, metric) {\n return distanceExpression(embeddingColumn, queryEmbedding, metric);\n },\n\n // vec0 indexes inline (the virtual table is the index), so there is no\n // standalone ANN index to create or drop — both return undefined.\n buildCreateIndex(): SQL | undefined {\n return undefined;\n },\n\n buildDropIndex(): SQL | undefined {\n return undefined;\n },\n\n buildDropStorage(slot): readonly string[] {\n const table = quoteIdentifier(\n this.tableName(slot.graphId, slot.nodeKind, slot.fieldPath),\n );\n // Dropping the vec0 virtual table removes its backing shadow tables too.\n return [`DROP TABLE IF EXISTS ${table}`];\n },\n};\n"]}
@@ -401,7 +401,6 @@ var postgresDialect = {
401
401
  capabilities: {
402
402
  standardQueryStrategy: "cte_project",
403
403
  recursiveQueryStrategy: "recursive_cte",
404
- setOperationStrategy: "standard_parenthesized",
405
404
  materializeIntermediateTraversalCtes: false,
406
405
  emitNotMaterializedHint: true,
407
406
  forceRecursiveWorktableOuterJoinOrder: false,
@@ -484,6 +483,12 @@ var postgresDialect = {
484
483
  return sql`${column} ILIKE ${pattern}`;
485
484
  },
486
485
  // ============================================================
486
+ // Set Operations
487
+ // ============================================================
488
+ wrapSetOperationOperand(inner) {
489
+ return sql`(${inner})`;
490
+ },
491
+ // ============================================================
487
492
  // Recursive CTE Path Operations
488
493
  // ============================================================
489
494
  initializePath(nodeId) {
@@ -519,36 +524,9 @@ var postgresDialect = {
519
524
  // ============================================================
520
525
  // Vector Operations
521
526
  // ============================================================
527
+ // Compile-time gate for `field.similarTo(...)`; the active
528
+ // `VectorStrategy` (pgvector) owns the distance SQL.
522
529
  supportsVectors: true,
523
- vectorDistance(column, embedding, metric) {
524
- const formatted = this.formatEmbedding(embedding);
525
- switch (metric) {
526
- case "cosine": {
527
- return sql`(${column} <=> ${formatted})`;
528
- }
529
- case "l2": {
530
- return sql`(${column} <-> ${formatted})`;
531
- }
532
- case "inner_product": {
533
- return sql`(${column} <#> ${formatted})`;
534
- }
535
- default: {
536
- const _exhaustive = metric;
537
- throw new Error("Unsupported vector metric: " + String(_exhaustive));
538
- }
539
- }
540
- },
541
- formatEmbedding(embedding) {
542
- for (const [index, value] of embedding.entries()) {
543
- if (typeof value !== "number" || !Number.isFinite(value)) {
544
- throw new TypeError(
545
- `embedding[${index}] must be a finite number, got: ${value}`
546
- );
547
- }
548
- }
549
- const asString = `[${embedding.join(",")}]`;
550
- return sql`${asString}::vector`;
551
- },
552
530
  // ============================================================
553
531
  // Fulltext Operations
554
532
  // ============================================================
@@ -580,7 +558,6 @@ var sqliteDialect = {
580
558
  capabilities: {
581
559
  standardQueryStrategy: "cte_project",
582
560
  recursiveQueryStrategy: "recursive_cte",
583
- setOperationStrategy: "sqlite_compound",
584
561
  materializeIntermediateTraversalCtes: true,
585
562
  emitNotMaterializedHint: false,
586
563
  forceRecursiveWorktableOuterJoinOrder: true,
@@ -665,6 +642,12 @@ var sqliteDialect = {
665
642
  return sql`LOWER(${column}) LIKE LOWER(${pattern})`;
666
643
  },
667
644
  // ============================================================
645
+ // Set Operations
646
+ // ============================================================
647
+ wrapSetOperationOperand(inner) {
648
+ return sql`SELECT * FROM (${inner})`;
649
+ },
650
+ // ============================================================
668
651
  // Recursive CTE Path Operations
669
652
  // ============================================================
670
653
  initializePath(nodeId) {
@@ -703,43 +686,105 @@ var sqliteDialect = {
703
686
  // ============================================================
704
687
  // Vector Operations
705
688
  // ============================================================
689
+ // Compile-time gate for `field.similarTo(...)`; the active
690
+ // `VectorStrategy` (sqlite-vec / libSQL-native) owns the distance SQL.
706
691
  supportsVectors: true,
707
- vectorDistance(column, embedding, metric) {
708
- const formatted = this.formatEmbedding(embedding);
709
- switch (metric) {
710
- case "cosine": {
711
- return sql`vec_distance_cosine(${column}, ${formatted})`;
712
- }
713
- case "l2": {
714
- return sql`vec_distance_l2(${column}, ${formatted})`;
715
- }
716
- case "inner_product": {
717
- throw new Error(
718
- "Inner product distance is not supported by sqlite-vec. Use 'cosine' or 'l2' metrics instead."
719
- );
720
- }
721
- default: {
722
- const _exhaustive = metric;
723
- throw new Error("Unsupported vector metric: " + String(_exhaustive));
724
- }
725
- }
726
- },
727
- formatEmbedding(embedding) {
728
- for (const [index, value] of embedding.entries()) {
729
- if (typeof value !== "number" || !Number.isFinite(value)) {
730
- throw new TypeError(
731
- `embedding[${index}] must be a finite number, got: ${value}`
732
- );
733
- }
734
- }
735
- const asJson = JSON.stringify(embedding);
736
- return sql`vec_f32(${asJson})`;
737
- },
738
692
  // ============================================================
739
693
  // Fulltext Operations
740
694
  // ============================================================
741
695
  fulltext: fts5Strategy
742
696
  };
697
+ var VECTOR_CONTRIBUTION_PREFIX = "vector";
698
+ function buildVectorCapabilities(strategy) {
699
+ return strategy.capabilities;
700
+ }
701
+ function vectorScoreExpression(distanceExpression, metric) {
702
+ switch (metric) {
703
+ case "cosine": {
704
+ return sql`(1 - (${distanceExpression}))`;
705
+ }
706
+ case "l2":
707
+ case "inner_product": {
708
+ return distanceExpression;
709
+ }
710
+ default: {
711
+ const _exhaustive = metric;
712
+ throw new Error(`Unsupported vector metric: ${String(_exhaustive)}`);
713
+ }
714
+ }
715
+ }
716
+ function vectorMinScoreCondition(distanceExpression, metric, minScore) {
717
+ assertVectorMinScore(minScore, metric);
718
+ switch (metric) {
719
+ case "cosine": {
720
+ return sql`${distanceExpression} <= ${1 - minScore}`;
721
+ }
722
+ case "l2": {
723
+ return sql`${distanceExpression} <= ${minScore}`;
724
+ }
725
+ case "inner_product": {
726
+ return sql`${distanceExpression} <= ${-minScore}`;
727
+ }
728
+ default: {
729
+ const _exhaustive = metric;
730
+ throw new Error(`Unsupported vector metric: ${String(_exhaustive)}`);
731
+ }
732
+ }
733
+ }
734
+ function assertFiniteEmbedding(embedding, name) {
735
+ for (const [index, value] of embedding.entries()) {
736
+ if (typeof value !== "number" || !Number.isFinite(value)) {
737
+ throw new TypeError(
738
+ `${name}[${index}] must be a finite number, got: ${value}`
739
+ );
740
+ }
741
+ }
742
+ }
743
+ function assertVectorSearchLimit(limit) {
744
+ if (!Number.isInteger(limit) || limit <= 0) {
745
+ throw new RangeError(
746
+ `vectorSearch limit must be a positive integer, got: ${limit}`
747
+ );
748
+ }
749
+ }
750
+ function assertVectorMinScore(minScore, metric, label = "minScore") {
751
+ if (!Number.isFinite(minScore)) {
752
+ throw new RangeError(`${label} must be a finite number, got: ${minScore}`);
753
+ }
754
+ if (metric === "cosine" && (minScore < -1 || minScore > 1)) {
755
+ throw new RangeError(
756
+ `${label} for the cosine metric must be between -1 and 1, got: ${minScore}`
757
+ );
758
+ }
759
+ }
760
+ var MAX_VECTOR_IDENTIFIER_LENGTH = 63;
761
+ function sanitizeIdentifierPart(value) {
762
+ return value.toLowerCase().replaceAll(/[^a-z0-9_]/g, "_");
763
+ }
764
+ function shortHash(input) {
765
+ let h1 = 3735928559;
766
+ let h2 = 1103547991;
767
+ for (let index = 0; index < input.length; index++) {
768
+ const ch = input.codePointAt(index);
769
+ h1 = Math.imul(h1 ^ ch, 2654435761);
770
+ h2 = Math.imul(h2 ^ ch, 1597334677);
771
+ }
772
+ h1 = Math.imul(h1 ^ h1 >>> 16, 2246822507) ^ Math.imul(h2 ^ h2 >>> 13, 3266489909);
773
+ h2 = Math.imul(h2 ^ h2 >>> 16, 2246822507) ^ Math.imul(h1 ^ h1 >>> 13, 3266489909);
774
+ const hi = (h2 >>> 0).toString(16).padStart(8, "0");
775
+ const lo = (h1 >>> 0).toString(16).padStart(8, "0");
776
+ return `${hi}${lo}`.slice(0, 8);
777
+ }
778
+ function vectorPhysicalName(prefix, graphId, nodeKind, fieldPath) {
779
+ const readable = `${prefix}_${sanitizeIdentifierPart(graphId)}_${sanitizeIdentifierPart(nodeKind)}_${sanitizeIdentifierPart(fieldPath)}`;
780
+ const hash = shortHash(JSON.stringify([graphId, nodeKind, fieldPath]));
781
+ const full = `${readable}_${hash}`;
782
+ if (full.length <= MAX_VECTOR_IDENTIFIER_LENGTH) return full;
783
+ return `${readable.slice(0, MAX_VECTOR_IDENTIFIER_LENGTH - 1 - hash.length)}_${hash}`;
784
+ }
785
+ function quoteIdentifier2(name) {
786
+ return `"${name.replaceAll('"', '""')}"`;
787
+ }
743
788
 
744
789
  // src/query/dialect/index.ts
745
790
  var DIALECT_ADAPTERS = {
@@ -983,7 +1028,7 @@ function generateEdgeIndexDDL(index, dialect, options = {}) {
983
1028
  function generateTableIndexDDL(index, dialect, tableName, options) {
984
1029
  const ifNotExists = options.ifNotExists ?? true;
985
1030
  const propsColumn = sql.raw('"props"');
986
- const systemColumn = (column) => sql.raw(quoteIdentifier2(column));
1031
+ const systemColumn = (column) => sql.raw(quoteIdentifier3(column));
987
1032
  const keys = index.entity === "node" ? compileNodeIndexKeys(index, dialect, propsColumn, systemColumn).keys : compileEdgeIndexKeys(index, dialect, propsColumn, systemColumn).keys;
988
1033
  const whereSql = index.where ? sqlToInlineString(
989
1034
  compileIndexWhere(
@@ -1001,9 +1046,9 @@ function generateTableIndexDDL(index, dialect, tableName, options) {
1001
1046
  const concurrent = options.concurrent === true && dialect === "postgres" ? "CONCURRENTLY " : "";
1002
1047
  const ifNotExistsSql = ifNotExists ? "IF NOT EXISTS " : "";
1003
1048
  const whereClause = whereSql ? ` WHERE ${whereSql}` : "";
1004
- return `CREATE ${unique}INDEX ${concurrent}${ifNotExistsSql}${quoteIdentifier2(index.name)} ON ${quoteIdentifier2(tableName)} (${keySql})${whereClause};`;
1049
+ return `CREATE ${unique}INDEX ${concurrent}${ifNotExistsSql}${quoteIdentifier3(index.name)} ON ${quoteIdentifier3(tableName)} (${keySql})${whereClause};`;
1005
1050
  }
1006
- function quoteIdentifier2(identifier) {
1051
+ function quoteIdentifier3(identifier) {
1007
1052
  return `"${identifier.replaceAll('"', '""')}"`;
1008
1053
  }
1009
1054
  function sqlToInlineString(object, dialect) {
@@ -1364,6 +1409,6 @@ function notWhere(predicate) {
1364
1409
  };
1365
1410
  }
1366
1411
 
1367
- export { BASE_CONTRIBUTION_OWNER, andWhere, buildFulltextCapabilities, buildPostgresEdgeIndexBuilders, buildPostgresNodeIndexBuilders, buildSqliteEdgeIndexBuilders, buildSqliteNodeIndexBuilders, edgeColumnList, fts5Strategy, generateEdgeIndexDDL, generateIndexDDL, generateNodeIndexDDL, getDialect, nodeColumnList, notWhere, orWhere, quotedColumn, quotedTableName, sqlNull, toDeclaredIndex, toDeclaredIndexes, tsvectorStrategy };
1368
- //# sourceMappingURL=chunk-ZTREJOGB.js.map
1369
- //# sourceMappingURL=chunk-ZTREJOGB.js.map
1412
+ export { BASE_CONTRIBUTION_OWNER, VECTOR_CONTRIBUTION_PREFIX, andWhere, assertFiniteEmbedding, assertVectorMinScore, assertVectorSearchLimit, buildFulltextCapabilities, buildPostgresEdgeIndexBuilders, buildPostgresNodeIndexBuilders, buildSqliteEdgeIndexBuilders, buildSqliteNodeIndexBuilders, buildVectorCapabilities, edgeColumnList, fts5Strategy, generateEdgeIndexDDL, generateIndexDDL, generateNodeIndexDDL, getDialect, nodeColumnList, notWhere, orWhere, quoteIdentifier2 as quoteIdentifier, quotedColumn, quotedTableName, sqlNull, toDeclaredIndex, toDeclaredIndexes, tsvectorStrategy, vectorMinScoreCondition, vectorPhysicalName, vectorScoreExpression };
1413
+ //# sourceMappingURL=chunk-7KLVFWXR.js.map
1414
+ //# sourceMappingURL=chunk-7KLVFWXR.js.map