@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
package/dist/index.js CHANGED
@@ -1,23 +1,26 @@
1
- import { quoteIdentifier, EMPTY_REQUIRED_COLUMNS, addRequiredColumn, markSelectiveFieldAsRequired, markFieldRefAsRequired, NODE_COLUMNS, shouldProjectColumn, mapSelectiveSystemFieldToColumn, isIdFieldRef, isAggregateExpr, EDGE_COLUMNS } from './chunk-3EUKJEQ3.js';
2
- import { META_EDGE_BRAND, loadAndMergeGraphExtensionDocument, ensureSchema, loadAndVerifyGraph, mergeGraphExtension, commitNewSchemaVersion, applyDeprecatedKinds, loadActiveSchemaWithBootstrap, parseSerializedSchema, computeClosuresFromOntology, createEmptyClosures, KindRegistry, extensionKindNames, serializeSchemaProperties, buildGraphExtensionOntologyKeySet, compileTimeOntologyKey, getTypeName, validateNodeProps, validateEdgeProps } from './chunk-5MTOKWDA.js';
3
- export { broader, core, defineEdge, defineNode, differentFrom, disjointWith, equivalentTo, hasPart, implies, inverseOf, isMetaEdge, narrower, partOf, relatedTo, sameAs, subClassOf } from './chunk-5MTOKWDA.js';
4
- import { nowIso, isKnownKind, validateOptionalIsoDate, getNodeKinds, getEdgeKinds } from './chunk-OYLF3IC7.js';
5
- export { defineGraph, getEdgeKinds, getNodeKinds, isEdgeType, isEdgeTypeWithEndpoints, isGraphDef, isNodeType } from './chunk-OYLF3IC7.js';
6
- export { defineGraphExtension } from './chunk-E5ROA3MN.js';
7
- import { IncompatibleChangeError, filterReservedKeys, RESERVED_NODE_KEYS, RESERVED_EDGE_KEYS, RemoveCompileTimeKindError, KindHasReferentsError, validateProjectionField } from './chunk-TSGBRPNE.js';
8
- export { CURRENT_GRAPH_EXTENSION_VERSION, GraphExtensionError, GraphExtensionUnresolvedEndpointError, GraphExtensionValidationError, GraphExtensionVersionUnsupportedError, IncompatibleChangeError, KindCollisionError, KindHasReferentsError, LEGACY_GRAPH_EXTENSION_VERSION, RemoveCompileTimeKindError, validateGraphExtension } from './chunk-TSGBRPNE.js';
9
- import { runOptionallyInTransaction } from './chunk-PCHTTG42.js';
10
- import { canonicalEqual, sortedReplacer } from './chunk-O57GYGYK.js';
11
- import { getDialect, generateIndexDDL } from './chunk-ZTREJOGB.js';
12
- export { andWhere, fts5Strategy, notWhere, orWhere, tsvectorStrategy } from './chunk-ZTREJOGB.js';
13
- import { MAX_PG_IDENTIFIER_LENGTH, DEFAULT_PAGINATION_LIMIT, DEFAULT_STREAM_BATCH_SIZE, NODE_META_KEYS, EDGE_META_KEYS, SQLITE_PATH_DELIMITER, PG_ARRAY_START, PG_ARRAY_END, PG_PATH_ELEMENT_SEPARATOR, fnv1aBase36, sha256Hex } from './chunk-EJCDOA37.js';
14
- export { defineEdgeIndex, defineNodeIndex } from './chunk-EJCDOA37.js';
15
- import { createSchemaIntrospector, resolveFieldTypeInfoAtJsonPointer, getSearchableMetadata, DEFAULT_SEARCHABLE_LANGUAGE } from './chunk-OOS2RKRH.js';
16
- export { DEFAULT_SEARCHABLE_LANGUAGE, getSearchableMetadata, isSearchableSchema, searchable } from './chunk-OOS2RKRH.js';
17
- import { getEmbeddingDimensions, isEmbeddingSchema } from './chunk-WVQXAFP3.js';
18
- export { embedding, getEmbeddingDimensions, isEmbeddingSchema } from './chunk-WVQXAFP3.js';
19
- import { ConfigurationError, UnsupportedPredicateError, ValidationError, KindNotFoundError, EndpointError, EagerMaterializationError, CompilerInvariantError, DatabaseOperationError, EdgeNotFoundError, NodeConstraintNotFoundError, RestrictedDeleteError, NodeNotFoundError, EndpointNotFoundError, UniquenessError, CardinalityError, DisjointError } from './chunk-U5ROKVRF.js';
20
- export { BackendDisposedError, CardinalityError, CompilerInvariantError, ConfigurationError, DatabaseOperationError, DisjointError, EagerMaterializationError, EdgeNotFoundError, EndpointError, EndpointNotFoundError, KindNotFoundError, MigrationError, NodeConstraintNotFoundError, NodeNotFoundError, RestrictedDeleteError, SchemaContentConflictError, SchemaMismatchError, StaleVersionError, StoreNotInitializedError, TypeGraphError, UniquenessError, UnsupportedPredicateError, ValidationError, VersionConflictError, getErrorSuggestion, isConstraintError, isSystemError, isTypeGraphError, isUserRecoverable } from './chunk-U5ROKVRF.js';
1
+ export { libsqlVectorStrategy } from './chunk-CUZGBWFT.js';
2
+ import { quoteIdentifier, EMPTY_REQUIRED_COLUMNS, addRequiredColumn, markSelectiveFieldAsRequired, markFieldRefAsRequired, NODE_COLUMNS, shouldProjectColumn, mapSelectiveSystemFieldToColumn, isIdFieldRef, isAggregateExpr, EDGE_COLUMNS } from './chunk-IE2TPFBT.js';
3
+ export { pgvectorStrategy } from './chunk-IE2TPFBT.js';
4
+ import { META_EDGE_BRAND, loadAndMergeGraphExtensionDocument, ensureSchema, loadAndVerifyGraph, mergeGraphExtension, commitNewSchemaVersion, applyDeprecatedKinds, loadActiveSchemaWithBootstrap, parseSerializedSchema, computeClosuresFromOntology, createEmptyClosures, KindRegistry, extensionKindNames, serializeSchemaProperties, buildGraphExtensionOntologyKeySet, compileTimeOntologyKey, getTypeName, validateNodeProps, validateEdgeProps } from './chunk-MRMD7S7E.js';
5
+ export { broader, core, defineEdge, defineNode, differentFrom, disjointWith, equivalentTo, hasPart, implies, inverseOf, isMetaEdge, narrower, partOf, relatedTo, sameAs, subClassOf } from './chunk-MRMD7S7E.js';
6
+ import { nowIso, isKnownKind, validateOptionalIsoDate, getNodeKinds, getEdgeKinds } from './chunk-Z36W5WUM.js';
7
+ export { defineGraph, getEdgeKinds, getNodeKinds, isEdgeType, isEdgeTypeWithEndpoints, isGraphDef, isNodeType } from './chunk-Z36W5WUM.js';
8
+ export { defineGraphExtension } from './chunk-BMDF2S7S.js';
9
+ import { IncompatibleChangeError, filterReservedKeys, RESERVED_NODE_KEYS, RESERVED_EDGE_KEYS, RemoveCompileTimeKindError, KindHasReferentsError, validateProjectionField } from './chunk-SFNUHFON.js';
10
+ export { CURRENT_GRAPH_EXTENSION_VERSION, GraphExtensionError, GraphExtensionUnresolvedEndpointError, GraphExtensionValidationError, GraphExtensionVersionUnsupportedError, IncompatibleChangeError, KindCollisionError, KindHasReferentsError, LEGACY_GRAPH_EXTENSION_VERSION, RemoveCompileTimeKindError, computeTransitiveClosure, invertClosure, isReachable, validateGraphExtension } from './chunk-SFNUHFON.js';
11
+ export { sqliteVecStrategy } from './chunk-GPUNAJFH.js';
12
+ import { LEGACY_EMBEDDINGS_TABLE_NAME, runOptionallyInTransaction } from './chunk-HKN622O4.js';
13
+ import { isMissingTableError, sortedReplacer, canonicalEqual } from './chunk-M6OC455F.js';
14
+ import { quotedTableName, getDialect, assertVectorMinScore, generateIndexDDL, vectorScoreExpression, vectorMinScoreCondition } from './chunk-7KLVFWXR.js';
15
+ export { andWhere, buildVectorCapabilities, fts5Strategy, notWhere, orWhere, tsvectorStrategy } from './chunk-7KLVFWXR.js';
16
+ import { MAX_PG_IDENTIFIER_LENGTH, DEFAULT_PAGINATION_LIMIT, DEFAULT_STREAM_BATCH_SIZE, NODE_META_KEYS, EDGE_META_KEYS, sha256Hex, SQLITE_PATH_DELIMITER, PG_ARRAY_START, PG_ARRAY_END, PG_PATH_ELEMENT_SEPARATOR, fnv1aBase36 } from './chunk-OGUH56BB.js';
17
+ export { defineEdgeIndex, defineNodeIndex } from './chunk-OGUH56BB.js';
18
+ import { createSchemaIntrospector, resolveFieldTypeInfoAtJsonPointer, getSearchableMetadata, DEFAULT_SEARCHABLE_LANGUAGE } from './chunk-N3VVQDMA.js';
19
+ export { DEFAULT_SEARCHABLE_LANGUAGE, getSearchableMetadata, isSearchableSchema, searchable } from './chunk-N3VVQDMA.js';
20
+ import { DEFAULT_EMBEDDING_INDEX_TYPE, DEFAULT_EMBEDDING_METRIC, resolveEmbeddingFields } from './chunk-454I6GDF.js';
21
+ export { embedding, getEmbeddingDimensions, isEmbeddingSchema } from './chunk-454I6GDF.js';
22
+ import { ConfigurationError, EmbeddingDimensionChangedError, UnsupportedPredicateError, ValidationError, KindNotFoundError, EndpointError, EagerMaterializationError, CompilerInvariantError, DatabaseOperationError, EdgeNotFoundError, NodeConstraintNotFoundError, RestrictedDeleteError, NodeNotFoundError, EndpointNotFoundError, UniquenessError, CardinalityError, DisjointError } from './chunk-MB363HT5.js';
23
+ export { BackendDisposedError, CardinalityError, CompilerInvariantError, ConfigurationError, DatabaseOperationError, DisjointError, EagerMaterializationError, EdgeNotFoundError, EmbeddingDimensionChangedError, EndpointError, EndpointNotFoundError, KindNotFoundError, MigrationError, NodeConstraintNotFoundError, NodeNotFoundError, RestrictedDeleteError, SchemaContentConflictError, SchemaMismatchError, StaleVersionError, StoreNotInitializedError, TypeGraphError, UniquenessError, UnsupportedPredicateError, ValidationError, VersionConflictError, getErrorSuggestion, isConstraintError, isSystemError, isTypeGraphError, isUserRecoverable } from './chunk-MB363HT5.js';
21
24
  import { jsonPointer, parseJsonPointer, normalizeJsonPointer, joinJsonPointers } from './chunk-NZ5PMBTG.js';
22
25
  export { MAX_JSON_POINTER_DEPTH, joinJsonPointers, jsonPointer, normalizeJsonPointer, parseJsonPointer } from './chunk-NZ5PMBTG.js';
23
26
  import { z } from 'zod';
@@ -67,6 +70,184 @@ function getExternalRefTable(schema) {
67
70
  function createExternalRef(table) {
68
71
  return (id) => ({ table, id });
69
72
  }
73
+ var DEFAULT_BATCH_SIZE = 500;
74
+ var DEFAULT_SLOT_METRIC = DEFAULT_EMBEDDING_METRIC;
75
+ var DEFAULT_SLOT_INDEX_TYPE = DEFAULT_EMBEDDING_INDEX_TYPE;
76
+ async function migrateLegacyEmbeddings(options) {
77
+ const {
78
+ backend,
79
+ graphId,
80
+ resolveSlotConfig,
81
+ batchSize = DEFAULT_BATCH_SIZE,
82
+ legacyTableName = LEGACY_EMBEDDINGS_TABLE_NAME
83
+ } = options;
84
+ if (backend.vectorStrategy === void 0 || backend.upsertEmbedding === void 0) {
85
+ throw new Error(
86
+ "migrateLegacyEmbeddings requires a backend wired with a vectorStrategy (the destination per-field storage). Pass the post-cutover backend."
87
+ );
88
+ }
89
+ if (!Number.isInteger(batchSize) || batchSize <= 0) {
90
+ throw new RangeError(
91
+ `batchSize must be a positive integer, got: ${batchSize}`
92
+ );
93
+ }
94
+ const upsertEmbedding = backend.upsertEmbedding;
95
+ const perField = {};
96
+ const skippedDimensionMismatch = {};
97
+ const skippedDecodeError = {};
98
+ let migrated = 0;
99
+ let cursor;
100
+ for (; ; ) {
101
+ let batch;
102
+ try {
103
+ batch = await readLegacyBatch(backend, {
104
+ legacyTableName,
105
+ graphId,
106
+ batchSize,
107
+ after: cursor
108
+ });
109
+ } catch (error) {
110
+ if (cursor === void 0 && isMissingTableError(error)) {
111
+ return {
112
+ migrated: 0,
113
+ perField: {},
114
+ skippedDimensionMismatch: {},
115
+ skippedDecodeError: {},
116
+ legacyTablePresent: false
117
+ };
118
+ }
119
+ throw error;
120
+ }
121
+ if (batch.length === 0) break;
122
+ for (const row of batch) {
123
+ const slotKey = `${row.node_kind}.${row.field_path}`;
124
+ let embedding2;
125
+ try {
126
+ embedding2 = decodeEmbeddingJson(row);
127
+ } catch {
128
+ skippedDecodeError[slotKey] = (skippedDecodeError[slotKey] ?? 0) + 1;
129
+ continue;
130
+ }
131
+ const config = resolveSlotConfig?.(row.node_kind, row.field_path);
132
+ try {
133
+ await upsertEmbedding({
134
+ graphId: row.graph_id,
135
+ nodeKind: row.node_kind,
136
+ nodeId: row.node_id,
137
+ fieldPath: row.field_path,
138
+ embedding: embedding2,
139
+ // The decoded length is the authoritative fixed dimension — the
140
+ // strategy provisions its column type (e.g. `F32_BLOB(N)`) from it.
141
+ dimensions: embedding2.length,
142
+ metric: config?.metric ?? DEFAULT_SLOT_METRIC,
143
+ indexType: config?.indexType ?? DEFAULT_SLOT_INDEX_TYPE
144
+ });
145
+ } catch (error) {
146
+ if (error instanceof EmbeddingDimensionChangedError) {
147
+ skippedDimensionMismatch[slotKey] = (skippedDimensionMismatch[slotKey] ?? 0) + 1;
148
+ continue;
149
+ }
150
+ throw error;
151
+ }
152
+ migrated += 1;
153
+ perField[slotKey] = (perField[slotKey] ?? 0) + 1;
154
+ }
155
+ if (batch.length < batchSize) break;
156
+ const last = batch.at(-1);
157
+ cursor = {
158
+ graphId: last.graph_id,
159
+ nodeKind: last.node_kind,
160
+ nodeId: last.node_id,
161
+ fieldPath: last.field_path
162
+ };
163
+ }
164
+ return {
165
+ migrated,
166
+ perField,
167
+ skippedDimensionMismatch,
168
+ skippedDecodeError,
169
+ legacyTablePresent: true
170
+ };
171
+ }
172
+ async function readLegacyBatch(backend, params) {
173
+ const table = quotedTableName(params.legacyTableName);
174
+ const embeddingJson = legacyEmbeddingDecodeExpression(backend);
175
+ const conditions = [];
176
+ if (params.graphId !== void 0) {
177
+ conditions.push(sql`"graph_id" = ${params.graphId}`);
178
+ }
179
+ if (params.after !== void 0) {
180
+ conditions.push(keysetAfterCondition(params.after));
181
+ }
182
+ const whereClause = conditions.length === 0 ? sql`` : sql` WHERE ${sql.join(conditions, sql` AND `)}`;
183
+ const query = sql`
184
+ SELECT
185
+ "graph_id" AS graph_id,
186
+ "node_kind" AS node_kind,
187
+ "node_id" AS node_id,
188
+ "field_path" AS field_path,
189
+ ${embeddingJson} AS embedding_json
190
+ FROM ${table}${whereClause}
191
+ ORDER BY "graph_id" ASC, "node_kind" ASC, "node_id" ASC, "field_path" ASC
192
+ LIMIT ${params.batchSize}
193
+ `;
194
+ return backend.execute(query);
195
+ }
196
+ function keysetAfterCondition(after) {
197
+ return sql`
198
+ (
199
+ "graph_id" > ${after.graphId}
200
+ OR ("graph_id" = ${after.graphId} AND "node_kind" > ${after.nodeKind})
201
+ OR ("graph_id" = ${after.graphId} AND "node_kind" = ${after.nodeKind} AND "node_id" > ${after.nodeId})
202
+ OR (
203
+ "graph_id" = ${after.graphId}
204
+ AND "node_kind" = ${after.nodeKind}
205
+ AND "node_id" = ${after.nodeId}
206
+ AND "field_path" > ${after.fieldPath}
207
+ )
208
+ )
209
+ `;
210
+ }
211
+ function legacyEmbeddingDecodeExpression(backend) {
212
+ switch (backend.dialect) {
213
+ case "sqlite": {
214
+ return sql`vec_to_json("embedding")`;
215
+ }
216
+ case "postgres": {
217
+ return sql`"embedding"::text`;
218
+ }
219
+ default: {
220
+ const _exhaustive = backend.dialect;
221
+ throw new Error(
222
+ `migrateLegacyEmbeddings does not support dialect: ${String(_exhaustive)}`
223
+ );
224
+ }
225
+ }
226
+ }
227
+ function decodeEmbeddingJson(row) {
228
+ let parsed;
229
+ try {
230
+ parsed = JSON.parse(row.embedding_json);
231
+ } catch (error) {
232
+ throw new Error(
233
+ `Failed to decode legacy embedding for ${row.node_kind}.${row.field_path} (graph ${row.graph_id}, node ${row.node_id}): not valid JSON.`,
234
+ { cause: error }
235
+ );
236
+ }
237
+ if (!Array.isArray(parsed) || parsed.length === 0) {
238
+ throw new Error(
239
+ `Legacy embedding for ${row.node_kind}.${row.field_path} (graph ${row.graph_id}, node ${row.node_id}) decoded to a non-array or empty value.`
240
+ );
241
+ }
242
+ for (const [index, value] of parsed.entries()) {
243
+ if (typeof value !== "number" || !Number.isFinite(value)) {
244
+ throw new TypeError(
245
+ `Legacy embedding for ${row.node_kind}.${row.field_path} (graph ${row.graph_id}, node ${row.node_id}) has a non-finite value at index ${index}: ${String(value)}.`
246
+ );
247
+ }
248
+ }
249
+ return parsed;
250
+ }
70
251
 
71
252
  // src/query/subquery-utils.ts
72
253
  function normalizeValueType(valueType) {
@@ -371,7 +552,10 @@ function vectorSimilarity(field2, queryEmbedding, limit, options) {
371
552
  __type: "vector_similarity",
372
553
  field: field2,
373
554
  queryEmbedding,
374
- metric: options?.metric ?? "cosine",
555
+ // Leave metric unset when the caller didn't specify one, so the compiler
556
+ // resolves the field's declared metric per kind. Defaulting to "cosine"
557
+ // here would mis-rank l2/inner_product fields and bypass their ANN index.
558
+ ...options?.metric !== void 0 && { metric: options.metric },
375
559
  limit,
376
560
  ...options?.minScore !== void 0 && { minScore: options.minScore }
377
561
  };
@@ -1614,7 +1798,6 @@ function mergeEdgeKinds(traversal) {
1614
1798
  var DEFAULT_TABLE_NAMES = {
1615
1799
  nodes: "typegraph_nodes",
1616
1800
  edges: "typegraph_edges",
1617
- embeddings: "typegraph_node_embeddings",
1618
1801
  fulltext: "typegraph_node_fulltext",
1619
1802
  uniques: "typegraph_node_uniques"
1620
1803
  };
@@ -1641,18 +1824,19 @@ function createSqlSchema(names = {}) {
1641
1824
  const tables = { ...DEFAULT_TABLE_NAMES, ...names };
1642
1825
  validateTableName(tables.nodes, "nodes");
1643
1826
  validateTableName(tables.edges, "edges");
1644
- validateTableName(tables.embeddings, "embeddings");
1645
1827
  validateTableName(tables.fulltext, "fulltext");
1646
1828
  validateTableName(tables.uniques, "uniques");
1647
1829
  return {
1648
1830
  tables,
1649
1831
  nodesTable: sql.raw(quoteIdentifier2(tables.nodes)),
1650
1832
  edgesTable: sql.raw(quoteIdentifier2(tables.edges)),
1651
- embeddingsTable: sql.raw(quoteIdentifier2(tables.embeddings)),
1652
1833
  fulltextTable: sql.raw(quoteIdentifier2(tables.fulltext))
1653
1834
  };
1654
1835
  }
1655
1836
  var DEFAULT_SQL_SCHEMA = createSqlSchema();
1837
+ function vectorSlotKey(nodeKind, fieldPath) {
1838
+ return `${nodeKind}\0${fieldPath}`;
1839
+ }
1656
1840
  var ALIAS_CTE_PREFIX = "cte_";
1657
1841
  var EMBEDDINGS_CTE_ALIAS = "cte_embeddings";
1658
1842
  var FULLTEXT_CTE_ALIAS = "cte_fulltext";
@@ -2159,35 +2343,61 @@ function buildStandardHaving(input) {
2159
2343
  }
2160
2344
  function buildStandardEmbeddingsCte(input) {
2161
2345
  const { ctx, graphId, nodeKinds, vectorPredicate } = input;
2162
- const { dialect } = ctx;
2163
2346
  const { field: field2, metric, minScore, queryEmbedding } = vectorPredicate;
2164
- const embeddingsTableName = ctx.schema.tables.embeddings;
2165
2347
  if (nodeKinds.length === 0) {
2166
2348
  throw new UnsupportedPredicateError(
2167
2349
  "Vector predicate must resolve to at least one node kind"
2168
2350
  );
2169
2351
  }
2170
- const fieldPath = resolveEmbeddingFieldPath(field2);
2171
- const distanceExpr = dialect.vectorDistance(
2172
- qualifyColumn(embeddingsTableName, "embedding"),
2173
- queryEmbedding,
2174
- metric
2175
- );
2176
- const scopedNodes = buildScopedNodeIdsSubquery(field2.alias);
2177
- const conditions = [
2178
- sql`${qualifyColumn(embeddingsTableName, "graph_id")} = ${graphId}`,
2179
- compileKindFilter(
2180
- qualifyColumn(embeddingsTableName, "node_kind"),
2181
- nodeKinds
2182
- ),
2183
- sql`${qualifyColumn(embeddingsTableName, "field_path")} = ${fieldPath}`
2184
- ];
2185
- if (minScore !== void 0) {
2186
- conditions.push(
2187
- compileVectorMinScoreCondition(distanceExpr, metric, minScore)
2352
+ const { vectorStrategy } = ctx;
2353
+ if (vectorStrategy === void 0) {
2354
+ throw new UnsupportedPredicateError(
2355
+ "Vector similarity predicate requires a backend with a vector strategy"
2188
2356
  );
2189
2357
  }
2190
- const scoreExpr = compileVectorScoreExpression(distanceExpr, metric);
2358
+ const fieldPath = resolveEmbeddingFieldPath(field2);
2359
+ const vectorSlots = ctx.vectorSlots;
2360
+ const scopedNodes = buildScopedNodeIdsSubquery(field2.alias);
2361
+ const declaringKinds = nodeKinds.filter(
2362
+ (kind) => vectorSlots?.has(vectorSlotKey(kind, fieldPath))
2363
+ );
2364
+ const branches = declaringKinds.map((kind) => {
2365
+ const tableName = vectorStrategy.tableName(graphId, kind, fieldPath);
2366
+ const branchMetric = metric ?? vectorSlots?.get(vectorSlotKey(kind, fieldPath))?.metric ?? "cosine";
2367
+ const distanceExpr = vectorStrategy.distanceExpression(
2368
+ qualifyColumn(tableName, "embedding"),
2369
+ queryEmbedding,
2370
+ branchMetric
2371
+ );
2372
+ const scoreExpr = vectorScoreExpression(distanceExpr, branchMetric);
2373
+ const conditions = [
2374
+ sql`${qualifyColumn(tableName, "graph_id")} = ${graphId}`
2375
+ ];
2376
+ if (minScore !== void 0) {
2377
+ conditions.push(
2378
+ vectorMinScoreCondition(distanceExpr, branchMetric, minScore)
2379
+ );
2380
+ }
2381
+ return sql`
2382
+ SELECT
2383
+ ${qualifyColumn(tableName, "node_id")} AS node_id,
2384
+ ${kind} AS node_kind,
2385
+ ${distanceExpr} AS distance,
2386
+ ${scoreExpr} AS score
2387
+ FROM ${quoteIdentifier(tableName)}
2388
+ INNER JOIN ${scopedNodes}
2389
+ ON ${sql.raw(`${SCOPED_RELEVANCE_NODES_ALIAS}.node_id`)} =
2390
+ ${qualifyColumn(tableName, "node_id")}
2391
+ AND ${sql.raw(`${SCOPED_RELEVANCE_NODES_ALIAS}.node_kind`)} = ${kind}
2392
+ WHERE ${sql.join(conditions, sql` AND `)}
2393
+ `;
2394
+ });
2395
+ const unionBody = branches.length === 0 ? emptyEmbeddingsBody() : sql.join(
2396
+ branches,
2397
+ sql`
2398
+ UNION ALL
2399
+ `
2400
+ );
2191
2401
  return sql`
2192
2402
  ${sql.raw(EMBEDDINGS_CTE_ALIAS)} AS (
2193
2403
  SELECT
@@ -2197,49 +2407,22 @@ function buildStandardEmbeddingsCte(input) {
2197
2407
  score,
2198
2408
  ROW_NUMBER() OVER (ORDER BY distance ASC) AS ord
2199
2409
  FROM (
2200
- SELECT
2201
- ${qualifyColumn(embeddingsTableName, "node_id")} AS node_id,
2202
- ${qualifyColumn(embeddingsTableName, "node_kind")} AS node_kind,
2203
- ${distanceExpr} AS distance,
2204
- ${scoreExpr} AS score
2205
- FROM ${ctx.schema.embeddingsTable}
2206
- INNER JOIN ${scopedNodes}
2207
- ON ${sql.raw(`${SCOPED_RELEVANCE_NODES_ALIAS}.node_id`)} =
2208
- ${qualifyColumn(embeddingsTableName, "node_id")}
2209
- AND ${sql.raw(`${SCOPED_RELEVANCE_NODES_ALIAS}.node_kind`)} =
2210
- ${qualifyColumn(embeddingsTableName, "node_kind")}
2211
- WHERE ${sql.join(conditions, sql` AND `)}
2410
+ ${unionBody}
2212
2411
  ORDER BY distance ASC
2213
2412
  LIMIT ${vectorPredicate.limit}
2214
2413
  ) AS vec_inner
2215
2414
  )
2216
2415
  `;
2217
2416
  }
2218
- function compileVectorScoreExpression(distanceExpr, metric) {
2219
- switch (metric) {
2220
- case "cosine": {
2221
- return sql`(1.0 - ${distanceExpr})`;
2222
- }
2223
- case "l2":
2224
- case "inner_product": {
2225
- return distanceExpr;
2226
- }
2227
- }
2228
- }
2229
- function compileVectorMinScoreCondition(distanceExpr, metric, minScore) {
2230
- switch (metric) {
2231
- case "cosine": {
2232
- const threshold = 1 - minScore;
2233
- return sql`${distanceExpr} <= ${threshold}`;
2234
- }
2235
- case "l2": {
2236
- return sql`${distanceExpr} <= ${minScore}`;
2237
- }
2238
- case "inner_product": {
2239
- const negativeThreshold = -minScore;
2240
- return sql`${distanceExpr} <= ${negativeThreshold}`;
2241
- }
2242
- }
2417
+ function emptyEmbeddingsBody() {
2418
+ return sql`
2419
+ SELECT
2420
+ CAST(NULL AS TEXT) AS node_id,
2421
+ CAST(NULL AS TEXT) AS node_kind,
2422
+ CAST(NULL AS REAL) AS distance,
2423
+ CAST(NULL AS REAL) AS score
2424
+ WHERE 1 = 0
2425
+ `;
2243
2426
  }
2244
2427
  function buildStandardFulltextCte(input) {
2245
2428
  const { ctx, fulltextPredicate, graphId, nodeKinds } = input;
@@ -2406,6 +2589,11 @@ function runFulltextPredicatePass(ast, dialect) {
2406
2589
  `Fulltext query mode "${fulltextPredicate.mode}" is not supported by the "${strategy.name}" strategy. Supported modes: ${strategy.supportedModes.join(", ")}.`
2407
2590
  );
2408
2591
  }
2592
+ if (fulltextPredicate.language !== void 0 && !strategy.supportsLanguageOverride) {
2593
+ throw new UnsupportedPredicateError(
2594
+ `Fulltext strategy "${strategy.name}" does not honor a per-query \`language\` override (its tokenizer is fixed at table-create time). Drop the option, or use a strategy that advertises \`supportsLanguageOverride: true\`.`
2595
+ );
2596
+ }
2409
2597
  if (!Number.isFinite(fulltextPredicate.limit) || fulltextPredicate.limit <= 0) {
2410
2598
  throw new UnsupportedPredicateError(
2411
2599
  `Fulltext match limit must be a positive finite number, got ${String(fulltextPredicate.limit)}`
@@ -2516,7 +2704,7 @@ function createTemporalFilterPass(ast, currentTimestamp) {
2516
2704
  }
2517
2705
 
2518
2706
  // src/query/compiler/passes/vector.ts
2519
- function runVectorPredicatePass(ast, dialect) {
2707
+ function runVectorPredicatePass(ast, dialect, vectorStrategy) {
2520
2708
  const vectorPredicates = extractVectorSimilarityPredicates(ast.predicates);
2521
2709
  if (vectorPredicates.length > 1) {
2522
2710
  throw new UnsupportedPredicateError(
@@ -2527,16 +2715,19 @@ function runVectorPredicatePass(ast, dialect) {
2527
2715
  if (vectorPredicate === void 0) {
2528
2716
  return { vectorPredicate: void 0 };
2529
2717
  }
2530
- const vectorStrategy = dialect.capabilities.vectorPredicateStrategy;
2531
- if (vectorStrategy === "unsupported" || !dialect.supportsVectors) {
2718
+ const predicateStrategy = dialect.capabilities.vectorPredicateStrategy;
2719
+ if (predicateStrategy === "unsupported" || !dialect.supportsVectors) {
2532
2720
  throw new UnsupportedPredicateError(
2533
2721
  `Vector similarity predicates are not supported for dialect "${dialect.name}"`
2534
2722
  );
2535
2723
  }
2536
- if (!dialect.capabilities.vectorMetrics.includes(vectorPredicate.metric)) {
2537
- throw new UnsupportedPredicateError(
2538
- `Vector metric "${vectorPredicate.metric}" is not supported for dialect "${dialect.name}"`
2539
- );
2724
+ if (vectorPredicate.metric !== void 0) {
2725
+ const supportedMetrics = vectorStrategy?.capabilities.metrics ?? dialect.capabilities.vectorMetrics;
2726
+ if (!supportedMetrics.includes(vectorPredicate.metric)) {
2727
+ throw new UnsupportedPredicateError(
2728
+ vectorStrategy === void 0 ? `Vector metric "${vectorPredicate.metric}" is not supported for dialect "${dialect.name}"` : `Vector metric "${vectorPredicate.metric}" is not supported by vector strategy "${vectorStrategy.name}" (supported: ${supportedMetrics.join(", ")})`
2729
+ );
2730
+ }
2540
2731
  }
2541
2732
  if (!Number.isFinite(vectorPredicate.limit) || vectorPredicate.limit <= 0) {
2542
2733
  throw new UnsupportedPredicateError(
@@ -2781,13 +2972,14 @@ function lowerRecursiveQueryToLogicalPlanNode(input) {
2781
2972
  ast.limit
2782
2973
  );
2783
2974
  }
2784
- function lowerComposableQueryToLogicalPlanNode(query, dialect, graphId, nextPlanNodeId) {
2975
+ function lowerComposableQueryToLogicalPlanNode(query, dialect, graphId, nextPlanNodeId, vectorStrategy) {
2785
2976
  if ("__type" in query) {
2786
2977
  return lowerSetOperationToLogicalPlanNode(
2787
2978
  query,
2788
2979
  graphId,
2789
2980
  dialect,
2790
- nextPlanNodeId
2981
+ nextPlanNodeId,
2982
+ vectorStrategy
2791
2983
  );
2792
2984
  }
2793
2985
  const hasVariableLengthTraversal2 = query.traversals.some(
@@ -2803,7 +2995,8 @@ function lowerComposableQueryToLogicalPlanNode(query, dialect, graphId, nextPlan
2803
2995
  const dialectAdapter = getDialect(dialect);
2804
2996
  const vectorPredicate = runVectorPredicatePass(
2805
2997
  query,
2806
- dialectAdapter
2998
+ dialectAdapter,
2999
+ vectorStrategy
2807
3000
  ).vectorPredicate;
2808
3001
  const fulltextPredicate = runFulltextPredicatePass(
2809
3002
  query,
@@ -2827,14 +3020,15 @@ function lowerComposableQueryToLogicalPlanNode(query, dialect, graphId, nextPlan
2827
3020
  };
2828
3021
  return lowerStandardQueryToLogicalPlanNode(loweringInput);
2829
3022
  }
2830
- function lowerSetOperationToLogicalPlanNode(op, graphId, dialect, nextPlanNodeId) {
3023
+ function lowerSetOperationToLogicalPlanNode(op, graphId, dialect, nextPlanNodeId, vectorStrategy) {
2831
3024
  let currentNode = {
2832
3025
  id: nextPlanNodeId(),
2833
3026
  left: lowerComposableQueryToLogicalPlanNode(
2834
3027
  op.left,
2835
3028
  dialect,
2836
3029
  graphId,
2837
- nextPlanNodeId
3030
+ nextPlanNodeId,
3031
+ vectorStrategy
2838
3032
  ),
2839
3033
  op: "set_op",
2840
3034
  operator: op.operator,
@@ -2842,7 +3036,8 @@ function lowerSetOperationToLogicalPlanNode(op, graphId, dialect, nextPlanNodeId
2842
3036
  op.right,
2843
3037
  dialect,
2844
3038
  graphId,
2845
- nextPlanNodeId
3039
+ nextPlanNodeId,
3040
+ vectorStrategy
2846
3041
  )
2847
3042
  };
2848
3043
  if (op.orderBy !== void 0 && op.orderBy.length > 0) {
@@ -2906,7 +3101,8 @@ function lowerSetOperationToLogicalPlan(input) {
2906
3101
  input.op,
2907
3102
  input.graphId,
2908
3103
  input.dialect,
2909
- nextPlanNodeId
3104
+ nextPlanNodeId,
3105
+ input.vectorStrategy
2910
3106
  )
2911
3107
  };
2912
3108
  }
@@ -4480,29 +4676,7 @@ var OPERATOR_MAP = {
4480
4676
  intersect: "INTERSECT",
4481
4677
  except: "EXCEPT"
4482
4678
  };
4483
- function compileSetOperationWithStandardParenthesizedStrategy(op, graphId, dialect, logicalPlan, _schema, compileQuery2) {
4484
- return compileSetOperationStandard(
4485
- op,
4486
- graphId,
4487
- dialect,
4488
- logicalPlan,
4489
- compileQuery2
4490
- );
4491
- }
4492
- function compileSetOperationWithSqliteCompoundStrategy(op, graphId, dialect, logicalPlan, schema, _compileQuery) {
4493
- return compileSetOperationForSqlite(
4494
- op,
4495
- graphId,
4496
- dialect,
4497
- logicalPlan,
4498
- schema
4499
- );
4500
- }
4501
- var SET_OPERATION_STRATEGY_HANDLERS = {
4502
- standard_parenthesized: compileSetOperationWithStandardParenthesizedStrategy,
4503
- sqlite_compound: compileSetOperationWithSqliteCompoundStrategy
4504
- };
4505
- function runSetOperationPassPipeline(op, graphId, dialect) {
4679
+ function runSetOperationPassPipeline(op, graphId, dialect, vectorStrategy) {
4506
4680
  let state = {
4507
4681
  dialect,
4508
4682
  graphId,
@@ -4515,7 +4689,8 @@ function runSetOperationPassPipeline(op, graphId, dialect) {
4515
4689
  return lowerSetOperationToLogicalPlan({
4516
4690
  dialect: currentState.dialect.name,
4517
4691
  graphId: currentState.graphId,
4518
- op: currentState.op
4692
+ op: currentState.op,
4693
+ ...vectorStrategy === void 0 ? {} : { vectorStrategy }
4519
4694
  });
4520
4695
  },
4521
4696
  update(currentState, logicalPlan) {
@@ -4528,25 +4703,20 @@ function runSetOperationPassPipeline(op, graphId, dialect) {
4528
4703
  state = logicalPlanPass.state;
4529
4704
  return state;
4530
4705
  }
4531
- function compileSetOperation(op, graphId, dialect, schema, compileQuery2) {
4532
- const passState = runSetOperationPassPipeline(op, graphId, dialect);
4706
+ function compileSetOperation(op, graphId, dialect, compileQuery2, vectorStrategy) {
4707
+ const passState = runSetOperationPassPipeline(
4708
+ op,
4709
+ graphId,
4710
+ dialect,
4711
+ vectorStrategy
4712
+ );
4533
4713
  const { logicalPlan } = passState;
4534
4714
  if (logicalPlan === void 0) {
4535
4715
  throw new CompilerInvariantError(
4536
4716
  "Logical plan pass did not initialize plan state"
4537
4717
  );
4538
4718
  }
4539
- const strategy = dialect.capabilities.setOperationStrategy;
4540
- const handler = SET_OPERATION_STRATEGY_HANDLERS[strategy];
4541
- return handler(op, graphId, dialect, logicalPlan, schema, compileQuery2);
4542
- }
4543
- function compileSetOperationStandard(op, graphId, dialect, logicalPlan, compileQuery2) {
4544
- const coreSql = compileSetOperationCoreStandard(
4545
- op,
4546
- graphId,
4547
- dialect,
4548
- compileQuery2
4549
- );
4719
+ const coreSql = compileSetOperationCore(op, graphId, compileQuery2, dialect);
4550
4720
  const suffixClauses = buildSetOperationSuffixClauses(op, dialect);
4551
4721
  return emitSetOperationQuerySql({
4552
4722
  baseQuery: coreSql,
@@ -4554,361 +4724,28 @@ function compileSetOperationStandard(op, graphId, dialect, logicalPlan, compileQ
4554
4724
  ...suffixClauses.length === 0 ? {} : { suffixClauses }
4555
4725
  });
4556
4726
  }
4557
- function compileSetOperationCoreStandard(op, graphId, dialect, compileQuery2) {
4558
- const left = compileComposableQueryStandard(
4559
- op.left,
4560
- graphId,
4561
- dialect,
4562
- compileQuery2
4563
- );
4564
- const right = compileComposableQueryStandard(
4727
+ function compileSetOperationCore(op, graphId, compileQuery2, dialect) {
4728
+ const left = compileComposableQuery(op.left, graphId, compileQuery2, dialect);
4729
+ const right = compileComposableQuery(
4565
4730
  op.right,
4566
4731
  graphId,
4567
- dialect,
4568
- compileQuery2
4732
+ compileQuery2,
4733
+ dialect
4569
4734
  );
4570
4735
  const opSql = sql.raw(OPERATOR_MAP[op.operator]);
4571
- return sql`(${left}) ${opSql} (${right})`;
4736
+ return sql`${dialect.wrapSetOperationOperand(left)} ${opSql} ${dialect.wrapSetOperationOperand(right)}`;
4572
4737
  }
4573
- function compileComposableQueryStandard(query, graphId, dialect, compileQuery2) {
4738
+ function compileComposableQuery(query, graphId, compileQuery2, dialect) {
4574
4739
  if ("__type" in query) {
4575
- return compileSetOperationCoreStandard(
4576
- query,
4577
- graphId,
4578
- dialect,
4579
- compileQuery2
4580
- );
4740
+ return compileSetOperationCompound(query, graphId, compileQuery2, dialect);
4581
4741
  }
4582
4742
  return compileQuery2(query, graphId);
4583
4743
  }
4584
- function runSqliteSetOperationValidationPass(op) {
4585
- const leaves = [];
4586
- collectLeafQueries(op, leaves, "q");
4587
- for (const leaf of leaves) {
4588
- validateSqliteSetOpLeaf(leaf.ast);
4589
- }
4590
- return { leaves };
4591
- }
4592
- function compileSetOperationForSqlite(op, graphId, dialect, logicalPlan, schema) {
4593
- const { leaves } = runSqliteSetOperationValidationPass(op);
4594
- const allCtes = [];
4595
- const ctx = {
4596
- dialect,
4597
- schema,
4598
- compileQuery: () => {
4599
- throw new CompilerInvariantError(
4600
- "compileQuery is not available in set-operation CTE compilation"
4601
- );
4602
- }
4603
- };
4604
- for (const leaf of leaves) {
4605
- const cte = compilePrefixedStartCte(leaf.ast, leaf.prefix, graphId, ctx);
4606
- allCtes.push(cte);
4607
- }
4608
- const selectStatements = [];
4609
- for (const leaf of leaves) {
4610
- const select = compilePrefixedSelect(leaf.ast, leaf.prefix, dialect);
4611
- selectStatements.push(select);
4612
- }
4613
- const compoundSelect = buildCompoundSelect(op, leaves, selectStatements);
4744
+ function compileSetOperationCompound(op, graphId, compileQuery2, dialect) {
4745
+ const core2 = compileSetOperationCore(op, graphId, compileQuery2, dialect);
4614
4746
  const suffixClauses = buildSetOperationSuffixClauses(op, dialect);
4615
- return emitSetOperationQuerySql({
4616
- baseQuery: compoundSelect,
4617
- ...allCtes.length === 0 ? {} : { ctes: allCtes },
4618
- logicalPlan,
4619
- ...suffixClauses.length === 0 ? {} : { suffixClauses }
4620
- });
4621
- }
4622
- function validateSqliteSetOpLeaf(ast) {
4623
- const unsupported = [];
4624
- if (ast.traversals.length > 0) {
4625
- unsupported.push("traversals");
4626
- }
4627
- if (hasSubqueryPredicates(ast)) {
4628
- unsupported.push("EXISTS/IN subqueries");
4629
- }
4630
- if (hasVectorSimilarityPredicates(ast)) {
4631
- unsupported.push("vector similarity predicates");
4632
- }
4633
- if (hasFulltextMatchPredicates(ast)) {
4634
- unsupported.push("fulltext match predicates");
4635
- }
4636
- if (ast.groupBy !== void 0) {
4637
- unsupported.push("GROUP BY");
4638
- }
4639
- if (ast.having !== void 0) {
4640
- unsupported.push("HAVING");
4641
- }
4642
- if (ast.orderBy !== void 0 && ast.orderBy.length > 0) {
4643
- unsupported.push(
4644
- "per-query ORDER BY (use set operation's orderBy instead)"
4645
- );
4646
- }
4647
- if (ast.limit !== void 0) {
4648
- unsupported.push("per-query LIMIT (use set operation's limit instead)");
4649
- }
4650
- if (ast.offset !== void 0) {
4651
- unsupported.push("per-query OFFSET (use set operation's offset instead)");
4652
- }
4653
- if (unsupported.length > 0) {
4654
- throw new UnsupportedPredicateError(
4655
- `SQLite set operations (UNION/INTERSECT/EXCEPT) do not support: ${unsupported.join(", ")}. Use PostgreSQL for complex set operations, or refactor to separate queries.`
4656
- );
4657
- }
4658
- }
4659
- function hasVectorSimilarityPredicates(ast) {
4660
- return ast.predicates.some(
4661
- (predicate2) => hasVectorSimilarityInExpression(predicate2.expression)
4662
- );
4663
- }
4664
- function hasVectorSimilarityInExpression(expr) {
4665
- if ("__type" in expr) {
4666
- switch (expr.__type) {
4667
- case "and":
4668
- case "or": {
4669
- return expr.predicates.some((p) => hasVectorSimilarityInExpression(p));
4670
- }
4671
- case "not": {
4672
- return hasVectorSimilarityInExpression(expr.predicate);
4673
- }
4674
- case "vector_similarity": {
4675
- return true;
4676
- }
4677
- case "exists":
4678
- case "in_subquery":
4679
- case "comparison":
4680
- case "string_op":
4681
- case "null_check":
4682
- case "between":
4683
- case "array_op":
4684
- case "object_op":
4685
- case "aggregate_comparison":
4686
- case "fulltext_match": {
4687
- return false;
4688
- }
4689
- }
4690
- }
4691
- return false;
4692
- }
4693
- function hasFulltextMatchPredicates(ast) {
4694
- return ast.predicates.some(
4695
- (predicate2) => hasFulltextMatchInExpression(predicate2.expression)
4696
- );
4697
- }
4698
- function hasFulltextMatchInExpression(expr) {
4699
- if ("__type" in expr) {
4700
- switch (expr.__type) {
4701
- case "and":
4702
- case "or": {
4703
- return expr.predicates.some((p) => hasFulltextMatchInExpression(p));
4704
- }
4705
- case "not": {
4706
- return hasFulltextMatchInExpression(expr.predicate);
4707
- }
4708
- case "fulltext_match": {
4709
- return true;
4710
- }
4711
- case "exists":
4712
- case "in_subquery":
4713
- case "comparison":
4714
- case "string_op":
4715
- case "null_check":
4716
- case "between":
4717
- case "array_op":
4718
- case "object_op":
4719
- case "aggregate_comparison":
4720
- case "vector_similarity": {
4721
- return false;
4722
- }
4723
- }
4724
- }
4725
- return false;
4726
- }
4727
- function hasSubqueryPredicates(ast) {
4728
- return ast.predicates.some(
4729
- (predicate2) => hasSubqueryInExpression(predicate2.expression)
4730
- );
4731
- }
4732
- function hasSubqueryInExpression(expr) {
4733
- if ("__type" in expr) {
4734
- switch (expr.__type) {
4735
- case "and":
4736
- case "or": {
4737
- return expr.predicates.some((p) => hasSubqueryInExpression(p));
4738
- }
4739
- case "not": {
4740
- return hasSubqueryInExpression(expr.predicate);
4741
- }
4742
- case "exists": {
4743
- return true;
4744
- }
4745
- case "in_subquery": {
4746
- return true;
4747
- }
4748
- // These expression types don't contain subqueries
4749
- case "comparison":
4750
- case "string_op":
4751
- case "null_check":
4752
- case "between":
4753
- case "array_op":
4754
- case "object_op":
4755
- case "aggregate_comparison":
4756
- case "vector_similarity":
4757
- case "fulltext_match": {
4758
- return false;
4759
- }
4760
- }
4761
- }
4762
- return false;
4763
- }
4764
- function collectLeafQueries(query, leaves, basePrefix) {
4765
- if ("__type" in query) {
4766
- collectLeafQueries(query.left, leaves, basePrefix);
4767
- collectLeafQueries(query.right, leaves, basePrefix);
4768
- } else {
4769
- const index = leaves.length;
4770
- leaves.push({ ast: query, prefix: `${basePrefix}${index}` });
4771
- }
4772
- }
4773
- function compilePrefixedStartCte(ast, prefix, graphId, ctx) {
4774
- const temporalFilterPass = createTemporalFilterPass(
4775
- ast,
4776
- ctx.dialect.currentTimestamp()
4777
- );
4778
- const alias = ast.start.alias;
4779
- const kinds = ast.start.kinds;
4780
- const kindFilter = kinds.length === 1 ? sql`kind = ${kinds[0]}` : sql`kind IN (${sql.join(
4781
- kinds.map((k) => sql`${k}`),
4782
- sql`, `
4783
- )})`;
4784
- const temporalFilter = temporalFilterPass.forAlias();
4785
- const cteContext = { ...ctx, cteColumnPrefix: "" };
4786
- const predicateClauses = ast.predicates.filter((p) => p.targetAlias === alias).map((p) => compilePredicateExpression(p.expression, cteContext));
4787
- const whereClauses = [
4788
- sql`graph_id = ${graphId}`,
4789
- kindFilter,
4790
- temporalFilter,
4791
- ...predicateClauses
4792
- ];
4793
- const cteName = `cte_${prefix}_${alias}`;
4794
- return sql`
4795
- ${sql.raw(cteName)} AS (
4796
- SELECT
4797
- id AS ${sql.raw(alias)}_id,
4798
- kind AS ${sql.raw(alias)}_kind,
4799
- props AS ${sql.raw(alias)}_props,
4800
- version AS ${sql.raw(alias)}_version,
4801
- valid_from AS ${sql.raw(alias)}_valid_from,
4802
- valid_to AS ${sql.raw(alias)}_valid_to,
4803
- created_at AS ${sql.raw(alias)}_created_at,
4804
- updated_at AS ${sql.raw(alias)}_updated_at,
4805
- deleted_at AS ${sql.raw(alias)}_deleted_at
4806
- FROM ${ctx.schema.nodesTable}
4807
- WHERE ${sql.join(whereClauses, sql` AND `)}
4808
- )
4809
- `;
4810
- }
4811
- function compilePrefixedSelect(ast, prefix, dialect) {
4812
- const alias = ast.start.alias;
4813
- const cteName = `cte_${prefix}_${alias}`;
4814
- const fields = ast.projection.fields;
4815
- const projection = fields.length === 0 ? sql.raw("*") : sql.join(
4816
- fields.map((f) => {
4817
- const source = compileFieldValueForSetOp(
4818
- f.source,
4819
- prefix,
4820
- alias,
4821
- dialect
4822
- );
4823
- return sql`${source} AS ${sql.raw(dialect.quoteIdentifier(f.outputName))}`;
4824
- }),
4825
- sql`, `
4826
- );
4827
- return sql`SELECT ${projection} FROM ${sql.raw(cteName)}`;
4828
- }
4829
- function compileFieldValueForSetOp(source, prefix, alias, dialect) {
4830
- if ("__type" in source && source.__type === "aggregate") {
4831
- const { field: field2, function: fn } = source;
4832
- switch (fn) {
4833
- case "count":
4834
- case "countDistinct":
4835
- case "sum":
4836
- case "avg":
4837
- case "min":
4838
- case "max": {
4839
- const column = compileFieldColumnForSetOp(field2, prefix, dialect);
4840
- if (fn === "countDistinct") {
4841
- return sql`COUNT(DISTINCT ${column})`;
4842
- }
4843
- return sql`${sql.raw(fn.toUpperCase())}(${column})`;
4844
- }
4845
- default: {
4846
- throw new CompilerInvariantError(
4847
- `Unknown aggregate function: ${String(fn)}`
4848
- );
4849
- }
4850
- }
4851
- }
4852
- return compileFieldColumnForSetOp(source, prefix, dialect);
4853
- }
4854
- function compileFieldColumnForSetOp(field2, prefix, dialect) {
4855
- const cteName = `cte_${prefix}_${field2.alias}`;
4856
- const alias = field2.alias;
4857
- if (field2.path.length === 1) {
4858
- const columnName = field2.path[0];
4859
- const columnMap = {
4860
- id: "_id",
4861
- kind: "_kind",
4862
- props: "_props",
4863
- version: "_version",
4864
- valid_from: "_valid_from",
4865
- valid_to: "_valid_to",
4866
- created_at: "_created_at",
4867
- updated_at: "_updated_at",
4868
- deleted_at: "_deleted_at"
4869
- };
4870
- if (columnName === void 0) return sql.raw(`${cteName}.${alias}_props`);
4871
- const suffix = columnMap[columnName];
4872
- if (suffix) {
4873
- return sql.raw(`${cteName}.${alias}${suffix}`);
4874
- }
4875
- }
4876
- const column = sql.raw(`${cteName}.${alias}_props`);
4877
- const pointer = field2.jsonPointer;
4878
- if (!pointer) {
4879
- return column;
4880
- }
4881
- return compileTypedJsonExtract({
4882
- column,
4883
- dialect,
4884
- fallback: "text",
4885
- pointer,
4886
- valueType: field2.valueType
4887
- });
4888
- }
4889
- function buildCompoundSelect(op, leaves, selectStatements) {
4890
- const prefixToSelect = /* @__PURE__ */ new Map();
4891
- for (const [index, leaf] of leaves.entries()) {
4892
- prefixToSelect.set(leaf.prefix, selectStatements[index]);
4893
- }
4894
- return buildCompoundSelectRecursive(op, leaves, prefixToSelect);
4895
- }
4896
- function buildCompoundSelectRecursive(query, leaves, prefixToSelect) {
4897
- if (!("__type" in query)) {
4898
- const leaf = leaves.find((l) => l.ast === query);
4899
- if (!leaf) {
4900
- throw new CompilerInvariantError("Leaf query not found in leaves array");
4901
- }
4902
- return prefixToSelect.get(leaf.prefix);
4903
- }
4904
- const left = buildCompoundSelectRecursive(query.left, leaves, prefixToSelect);
4905
- const right = buildCompoundSelectRecursive(
4906
- query.right,
4907
- leaves,
4908
- prefixToSelect
4909
- );
4910
- const opSql = sql.raw(OPERATOR_MAP[query.operator]);
4911
- return sql`${left} ${opSql} ${right}`;
4747
+ if (suffixClauses.length === 0) return core2;
4748
+ return sql.join([core2, ...suffixClauses], sql` `);
4912
4749
  }
4913
4750
  function getLeftmostProjection(op) {
4914
4751
  let current = op.left;
@@ -5201,7 +5038,11 @@ function runStandardQueryPassPipeline(ast, graphId, ctx) {
5201
5038
  const vectorPass = runCompilerPass(state, {
5202
5039
  name: "vector_predicate",
5203
5040
  execute(currentState) {
5204
- return runVectorPredicatePass(currentState.ast, currentState.ctx.dialect).vectorPredicate;
5041
+ return runVectorPredicatePass(
5042
+ currentState.ast,
5043
+ currentState.ctx.dialect,
5044
+ currentState.ctx.vectorStrategy
5045
+ ).vectorPredicate;
5205
5046
  },
5206
5047
  update(currentState, vectorPredicate) {
5207
5048
  return {
@@ -5358,7 +5199,9 @@ function compileQuery(ast, graphId, options = "sqlite") {
5358
5199
  const ctx = {
5359
5200
  dialect: adapter,
5360
5201
  schema,
5361
- compileQuery: (subAst, subGraphId) => compileQuery(subAst, subGraphId, propagateOptions(options_))
5202
+ compileQuery: (subAst, subGraphId) => compileQuery(subAst, subGraphId, propagateOptions(options_)),
5203
+ ...options_.vectorStrategy === void 0 ? {} : { vectorStrategy: options_.vectorStrategy },
5204
+ ...options_.vectorSlots === void 0 ? {} : { vectorSlots: options_.vectorSlots }
5362
5205
  };
5363
5206
  if (hasVariableLengthTraversal(ast)) {
5364
5207
  const lowered = tryLowerSingleHopRecursiveTraversal(ast);
@@ -5393,14 +5236,13 @@ function tryLowerSingleHopRecursiveTraversal(ast) {
5393
5236
  function compileSetOperation2(op, graphId, options = "sqlite") {
5394
5237
  const options_ = typeof options === "string" ? { dialect: options } : options;
5395
5238
  const dialect = options_.dialect ?? "sqlite";
5396
- const schema = options_.schema ?? DEFAULT_SQL_SCHEMA;
5397
5239
  const adapter = resolveDialectAdapter(dialect, options_.fulltextStrategy);
5398
5240
  return compileSetOperation(
5399
5241
  op,
5400
5242
  graphId,
5401
5243
  adapter,
5402
- schema,
5403
- (ast, gid) => compileQuery(ast, gid, propagateOptions(options_))
5244
+ (ast, gid) => compileQuery(ast, gid, propagateOptions(options_)),
5245
+ options_.vectorStrategy
5404
5246
  );
5405
5247
  }
5406
5248
  function resolveDialectAdapter(dialect, fulltextStrategy) {
@@ -5414,7 +5256,9 @@ function propagateOptions(options_) {
5414
5256
  return {
5415
5257
  dialect: options_.dialect ?? "sqlite",
5416
5258
  ...options_.schema === void 0 ? {} : { schema: options_.schema },
5417
- ...options_.fulltextStrategy === void 0 ? {} : { fulltextStrategy: options_.fulltextStrategy }
5259
+ ...options_.fulltextStrategy === void 0 ? {} : { fulltextStrategy: options_.fulltextStrategy },
5260
+ ...options_.vectorStrategy === void 0 ? {} : { vectorStrategy: options_.vectorStrategy },
5261
+ ...options_.vectorSlots === void 0 ? {} : { vectorSlots: options_.vectorSlots }
5418
5262
  };
5419
5263
  }
5420
5264
  function resolveCountAggregateFastPath(ast) {
@@ -7005,12 +6849,31 @@ function buildQueryAst(config, state) {
7005
6849
  // src/query/builder/compile-options.ts
7006
6850
  function buildCompileOptions(config) {
7007
6851
  const fulltextStrategy = config.backend?.fulltextStrategy;
6852
+ const vectorStrategy = config.backend?.vectorStrategy;
7008
6853
  return {
7009
6854
  dialect: config.dialect ?? "sqlite",
7010
6855
  schema: config.schema,
7011
- ...fulltextStrategy === void 0 ? {} : { fulltextStrategy }
6856
+ ...fulltextStrategy === void 0 ? {} : { fulltextStrategy },
6857
+ ...vectorStrategy === void 0 ? {} : { vectorStrategy, vectorSlots: buildVectorSlots(config.registry) }
7012
6858
  };
7013
6859
  }
6860
+ var vectorSlotsCache = /* @__PURE__ */ new WeakMap();
6861
+ function buildVectorSlots(registry) {
6862
+ const cached = vectorSlotsCache.get(registry);
6863
+ if (cached !== void 0) return cached;
6864
+ const slots = /* @__PURE__ */ new Map();
6865
+ for (const [nodeKind, nodeType] of registry.nodeKinds) {
6866
+ for (const field2 of resolveEmbeddingFields(nodeType.schema)) {
6867
+ slots.set(vectorSlotKey(nodeKind, field2.fieldPath), {
6868
+ dimensions: field2.dimensions,
6869
+ metric: field2.metric,
6870
+ indexType: field2.indexType
6871
+ });
6872
+ }
6873
+ }
6874
+ vectorSlotsCache.set(registry, slots);
6875
+ return slots;
6876
+ }
7014
6877
  function toLiteral(value) {
7015
6878
  if (value === null) {
7016
6879
  throw new ConfigurationError(
@@ -11212,7 +11075,7 @@ async function materializeVectorIndex(declaration, backend, graphId, schemaVersi
11212
11075
  );
11213
11076
  }
11214
11077
  const vectorCapability = backend.capabilities.vector;
11215
- if (vectorCapability?.supported !== true || backend.createVectorIndex === void 0) {
11078
+ if (vectorCapability?.supported !== true || backend.createVectorIndex === void 0 || backend.vectorStrategy === void 0) {
11216
11079
  return skippedEntry(
11217
11080
  declaration,
11218
11081
  `Backend (${backend.dialect}) does not support vector indexes in its current configuration`
@@ -11224,7 +11087,11 @@ async function materializeVectorIndex(declaration, backend, graphId, schemaVersi
11224
11087
  `Backend (${backend.dialect}) does not support index type "${declaration.indexType}" for vector indexes; supported: ${vectorCapability.indexTypes.join(", ") || "(none)"}`
11225
11088
  );
11226
11089
  }
11227
- const embeddingsTable = backend.tableNames?.embeddings ?? "typegraph_node_embeddings";
11090
+ const embeddingsTable = backend.vectorStrategy.tableName(
11091
+ graphId,
11092
+ declaration.kind,
11093
+ declaration.fieldPath
11094
+ );
11228
11095
  const signature = await computeIndexSignature(
11229
11096
  backend.dialect,
11230
11097
  embeddingsTable,
@@ -11387,16 +11254,16 @@ async function materializeRemovals(context, options = {}) {
11387
11254
  }
11388
11255
  await ensureFocusedStatusTable(backend, backend.ensureKindRemovalsTable);
11389
11256
  await reconcilePendingRemovals(context);
11257
+ const reclaimedVectorFields = await reclaimRemovedVectorFieldTables(context);
11390
11258
  const pending = await backend.getPendingKindRemovals(graphId);
11391
11259
  const kindFilter = options.kinds === void 0 ? void 0 : new Set(options.kinds);
11392
11260
  const candidates = pending.filter(
11393
11261
  (row) => kindFilter === void 0 ? true : kindFilter.has(row.kindName)
11394
11262
  );
11395
- if (candidates.length === 0) return { results: [] };
11263
+ if (candidates.length === 0) return { results: [], reclaimedVectorFields };
11396
11264
  const tableNames = backend.tableNames;
11397
11265
  const nodesTable = tableNames?.nodes ?? "typegraph_nodes";
11398
11266
  const edgesTable = tableNames?.edges ?? "typegraph_edges";
11399
- const embeddingsTable = tableNames?.embeddings ?? "typegraph_node_embeddings";
11400
11267
  const fulltextTable = tableNames?.fulltext ?? "typegraph_node_fulltext";
11401
11268
  const uniquesTable = tableNames?.uniques ?? "typegraph_node_uniques";
11402
11269
  const ctx = {
@@ -11404,7 +11271,6 @@ async function materializeRemovals(context, options = {}) {
11404
11271
  graphId,
11405
11272
  nodesTable,
11406
11273
  edgesTable,
11407
- embeddingsTable,
11408
11274
  fulltextTable,
11409
11275
  uniquesTable
11410
11276
  };
@@ -11413,7 +11279,8 @@ async function materializeRemovals(context, options = {}) {
11413
11279
  candidates,
11414
11280
  options,
11415
11281
  (removal) => materializeOne2(removal, ctx)
11416
- )
11282
+ ),
11283
+ reclaimedVectorFields
11417
11284
  };
11418
11285
  }
11419
11286
  async function reconcilePendingRemovals(context) {
@@ -11500,15 +11367,13 @@ async function materializeOne2(row, ctx) {
11500
11367
  executeDdl(
11501
11368
  `DELETE FROM ${quote(ctx.edgesTable)} WHERE graph_id = ${graphLit} AND (from_kind = ${kindLit} OR to_kind = ${kindLit})`
11502
11369
  ),
11503
- executeDdl(
11504
- `DELETE FROM ${quote(ctx.embeddingsTable)} WHERE graph_id = ${graphLit} AND node_kind = ${kindLit}`
11505
- ),
11506
11370
  executeDdl(
11507
11371
  `DELETE FROM ${quote(ctx.fulltextTable)} WHERE graph_id = ${graphLit} AND node_kind = ${kindLit}`
11508
11372
  ),
11509
11373
  executeDdl(
11510
11374
  `DELETE FROM ${quote(ctx.uniquesTable)} WHERE graph_id = ${graphLit} AND node_kind = ${kindLit}`
11511
- )
11375
+ ),
11376
+ ...buildEmbeddingTableCleanup(ctx, row)
11512
11377
  );
11513
11378
  } else {
11514
11379
  deletes.push(
@@ -11552,6 +11417,128 @@ async function materializeOne2(row, ctx) {
11552
11417
  };
11553
11418
  }
11554
11419
  }
11420
+ function buildEmbeddingTableCleanup(ctx, row) {
11421
+ const vectorStrategy = ctx.backend.vectorStrategy;
11422
+ if (vectorStrategy === void 0) return [];
11423
+ const executeDdl = ctx.backend.executeDdl;
11424
+ const cleanup = (async () => {
11425
+ const slots = await resolveRemovedKindEmbeddingSlots(ctx.backend, row);
11426
+ await Promise.all(
11427
+ slots.map(
11428
+ (slot) => dropVectorSlotStorage(vectorStrategy, executeDdl, slot)
11429
+ )
11430
+ );
11431
+ })();
11432
+ return [cleanup];
11433
+ }
11434
+ async function dropVectorSlotStorage(strategy, executeDdl, slot) {
11435
+ try {
11436
+ for (const ddl of strategy.buildDropStorage(slot)) {
11437
+ await executeDdl(ddl);
11438
+ }
11439
+ } catch (error) {
11440
+ if (!isMissingTableError(error)) throw error;
11441
+ }
11442
+ }
11443
+ async function resolveRemovedKindEmbeddingSlots(backend, row) {
11444
+ const priorVersion = row.schemaVersion - 1;
11445
+ if (priorVersion < 1) return [];
11446
+ const priorRow = await backend.getSchemaVersion(row.graphId, priorVersion);
11447
+ if (priorRow === void 0) return [];
11448
+ const priorSchema = parseSerializedSchema(priorRow.schema_doc);
11449
+ const slots = /* @__PURE__ */ new Map();
11450
+ for (const declaration of priorSchema.indexes ?? []) {
11451
+ if (declaration.entity === "vector" && declaration.kind === row.kindName) {
11452
+ slots.set(declaration.fieldPath, {
11453
+ graphId: row.graphId,
11454
+ nodeKind: row.kindName,
11455
+ fieldPath: declaration.fieldPath,
11456
+ dimensions: declaration.dimensions,
11457
+ metric: declaration.metric,
11458
+ indexType: declaration.indexType
11459
+ });
11460
+ }
11461
+ }
11462
+ return [...slots.values()];
11463
+ }
11464
+ function vectorFieldKey(kind, fieldPath) {
11465
+ return `${kind}\0${fieldPath}`;
11466
+ }
11467
+ async function reclaimRemovedVectorFieldTables(context) {
11468
+ const { backend, graphId } = context;
11469
+ const vectorStrategy = backend.vectorStrategy;
11470
+ const executeDdl = backend.executeDdl;
11471
+ if (vectorStrategy === void 0 || executeDdl === void 0) return [];
11472
+ const activeRow = await backend.getActiveSchema(graphId);
11473
+ if (activeRow === void 0) return [];
11474
+ const cacheKey = `${graphId}\0${activeRow.version}`;
11475
+ let perBackend = reclaimCache.get(backend);
11476
+ const cached = perBackend?.get(cacheKey);
11477
+ if (cached !== void 0) return cached;
11478
+ const activeSchema = parseSerializedSchema(activeRow.schema_doc);
11479
+ const activeVectorFields = /* @__PURE__ */ new Set();
11480
+ for (const declaration of activeSchema.indexes ?? []) {
11481
+ if (declaration.entity === "vector") {
11482
+ activeVectorFields.add(
11483
+ vectorFieldKey(declaration.kind, declaration.fieldPath)
11484
+ );
11485
+ }
11486
+ }
11487
+ const survivingKinds = new Set(Object.keys(activeSchema.nodes));
11488
+ const historical = /* @__PURE__ */ new Map();
11489
+ for (let version = activeRow.version - 1; version >= 1; version -= 1) {
11490
+ const priorRow = await backend.getSchemaVersion(graphId, version);
11491
+ if (priorRow === void 0) continue;
11492
+ const priorSchema = parseSerializedSchema(priorRow.schema_doc);
11493
+ for (const declaration of priorSchema.indexes ?? []) {
11494
+ if (declaration.entity !== "vector") continue;
11495
+ const key = vectorFieldKey(declaration.kind, declaration.fieldPath);
11496
+ if (historical.has(key)) continue;
11497
+ historical.set(key, {
11498
+ kind: declaration.kind,
11499
+ fieldPath: declaration.fieldPath,
11500
+ slot: {
11501
+ graphId,
11502
+ nodeKind: declaration.kind,
11503
+ fieldPath: declaration.fieldPath,
11504
+ dimensions: declaration.dimensions,
11505
+ metric: declaration.metric,
11506
+ indexType: declaration.indexType
11507
+ }
11508
+ });
11509
+ }
11510
+ }
11511
+ const orphans = [...historical.values()].filter(
11512
+ (field2) => !activeVectorFields.has(vectorFieldKey(field2.kind, field2.fieldPath)) && survivingKinds.has(field2.kind)
11513
+ );
11514
+ const results = [];
11515
+ for (const field2 of orphans) {
11516
+ try {
11517
+ await dropVectorSlotStorage(vectorStrategy, executeDdl, field2.slot);
11518
+ results.push({
11519
+ kind: field2.kind,
11520
+ fieldPath: field2.fieldPath,
11521
+ status: "reclaimed"
11522
+ });
11523
+ } catch (error) {
11524
+ results.push({
11525
+ kind: field2.kind,
11526
+ fieldPath: field2.fieldPath,
11527
+ status: "failed",
11528
+ error: error instanceof Error ? error : new Error(String(error))
11529
+ });
11530
+ }
11531
+ }
11532
+ if (results.every((entry2) => entry2.status === "reclaimed")) {
11533
+ if (perBackend === void 0) {
11534
+ perBackend = /* @__PURE__ */ new Map();
11535
+ reclaimCache.set(backend, perBackend);
11536
+ }
11537
+ perBackend.set(cacheKey, results);
11538
+ }
11539
+ return results;
11540
+ }
11541
+ var reclaimCache = /* @__PURE__ */ new WeakMap();
11555
11542
  function quote(identifier) {
11556
11543
  return `"${identifier.replaceAll('"', '""')}"`;
11557
11544
  }
@@ -12536,46 +12523,10 @@ var embeddingFieldsCache = /* @__PURE__ */ new WeakMap();
12536
12523
  function getEmbeddingFields(schema) {
12537
12524
  const cached = embeddingFieldsCache.get(schema);
12538
12525
  if (cached) return cached;
12539
- const fields = computeEmbeddingFields(schema);
12526
+ const fields = resolveEmbeddingFields(schema);
12540
12527
  embeddingFieldsCache.set(schema, fields);
12541
12528
  return fields;
12542
12529
  }
12543
- function computeEmbeddingFields(schema) {
12544
- if (schema.type !== "object") return [];
12545
- const def = schema.def;
12546
- const shape = def.shape;
12547
- if (!shape) return [];
12548
- const fields = [];
12549
- for (const [fieldPath, fieldSchema] of Object.entries(shape)) {
12550
- const dimensions = getEmbeddingDimensionsFromField(fieldSchema);
12551
- if (dimensions !== void 0) {
12552
- fields.push({ fieldPath, dimensions });
12553
- }
12554
- }
12555
- return fields;
12556
- }
12557
- function getEmbeddingDimensionsFromField(schema) {
12558
- const directDimensions = getEmbeddingDimensions(schema);
12559
- if (directDimensions !== void 0) {
12560
- return directDimensions;
12561
- }
12562
- const unwrapped = unwrapToEmbedding(schema);
12563
- if (unwrapped) {
12564
- return getEmbeddingDimensions(unwrapped);
12565
- }
12566
- return void 0;
12567
- }
12568
- function unwrapToEmbedding(schema) {
12569
- const type = schema.type;
12570
- const def = schema.def;
12571
- if ((type === "optional" || type === "nullable" || type === "default" || type === "readonly") && def.innerType) {
12572
- if (isEmbeddingSchema(def.innerType)) {
12573
- return def.innerType;
12574
- }
12575
- return unwrapToEmbedding(def.innerType);
12576
- }
12577
- return void 0;
12578
- }
12579
12530
  async function syncEmbeddings(ctx, schema, props) {
12580
12531
  const { backend } = ctx;
12581
12532
  if (!backend.upsertEmbedding || !backend.deleteEmbedding) {
@@ -12594,14 +12545,19 @@ async function syncEmbeddings(ctx, schema, props) {
12594
12545
  nodeId: ctx.nodeId,
12595
12546
  fieldPath: field2.fieldPath,
12596
12547
  embedding: value,
12597
- dimensions: field2.dimensions
12548
+ dimensions: field2.dimensions,
12549
+ metric: field2.metric,
12550
+ indexType: field2.indexType
12598
12551
  });
12599
12552
  } else if (value === void 0) {
12600
12553
  await backend.deleteEmbedding({
12601
12554
  graphId: ctx.graphId,
12602
12555
  nodeKind: ctx.nodeKind,
12603
12556
  nodeId: ctx.nodeId,
12604
- fieldPath: field2.fieldPath
12557
+ fieldPath: field2.fieldPath,
12558
+ dimensions: field2.dimensions,
12559
+ metric: field2.metric,
12560
+ indexType: field2.indexType
12605
12561
  });
12606
12562
  }
12607
12563
  }
@@ -12620,7 +12576,10 @@ async function deleteNodeEmbeddings(ctx, schema) {
12620
12576
  graphId: ctx.graphId,
12621
12577
  nodeKind: ctx.nodeKind,
12622
12578
  nodeId: ctx.nodeId,
12623
- fieldPath: field2.fieldPath
12579
+ fieldPath: field2.fieldPath,
12580
+ dimensions: field2.dimensions,
12581
+ metric: field2.metric,
12582
+ indexType: field2.indexType
12624
12583
  });
12625
12584
  }
12626
12585
  }
@@ -13360,6 +13319,10 @@ async function executeNodeHardDelete(ctx, kind, id, backend) {
13360
13319
  await enforceDeleteBehavior(ctx, kind, id, "hard", backend, registration);
13361
13320
  const hardDelete = async (target) => {
13362
13321
  await target.hardDeleteNode({ graphId: ctx.graphId, kind, id });
13322
+ await deleteNodeEmbeddings(
13323
+ createEmbeddingSyncContext(ctx.graphId, kind, id, target),
13324
+ registration.type.schema
13325
+ );
13363
13326
  };
13364
13327
  await ("transaction" in backend && backend.capabilities.transactions ? backend.transaction(async (tx) => hardDelete(tx)) : hardDelete(backend));
13365
13328
  });
@@ -13829,6 +13792,24 @@ function processPage(schema, rows) {
13829
13792
  }
13830
13793
 
13831
13794
  // src/store/search.ts
13795
+ function resolveSearchSlot(ctx, nodeKind, fieldPath) {
13796
+ const nodeType = ctx.registry.getNodeType(nodeKind);
13797
+ if (nodeType !== void 0) {
13798
+ const fields = getEmbeddingFields(nodeType.schema);
13799
+ const field2 = fields.find((entry2) => entry2.fieldPath === fieldPath);
13800
+ if (field2 !== void 0) {
13801
+ return {
13802
+ dimensions: field2.dimensions,
13803
+ metric: field2.metric,
13804
+ indexType: field2.indexType
13805
+ };
13806
+ }
13807
+ }
13808
+ throw new ConfigurationError(
13809
+ `Node kind "${nodeKind}" has no embedding field "${fieldPath}". Declare it with embedding(dimensions) on the node schema.`,
13810
+ { capability: "vector", graphId: ctx.graphId }
13811
+ );
13812
+ }
13832
13813
  async function executeFulltextSearch(ctx, nodeKind, options) {
13833
13814
  const { backend, graphId } = ctx;
13834
13815
  if (!backend.fulltextSearch) {
@@ -13890,12 +13871,29 @@ async function executeVectorSearch(ctx, nodeKind, options) {
13890
13871
  );
13891
13872
  }
13892
13873
  assertEfSearch(options.efSearch, "vectorSearch.efSearch");
13874
+ const slot = resolveSearchSlot(ctx, nodeKind, options.fieldPath);
13875
+ assertVectorQueryCompatible(
13876
+ backend,
13877
+ slot,
13878
+ { metric: options.metric, queryEmbedding: options.queryEmbedding },
13879
+ "vectorSearch"
13880
+ );
13881
+ assertMinScore(
13882
+ options.minScore,
13883
+ options.metric ?? slot.metric,
13884
+ "vectorSearch.minScore"
13885
+ );
13893
13886
  const rows = await backend.vectorSearch({
13894
13887
  graphId,
13895
13888
  nodeKind,
13896
13889
  fieldPath: options.fieldPath,
13897
13890
  queryEmbedding: options.queryEmbedding,
13898
- metric: options.metric ?? "cosine",
13891
+ // Default to the field's DECLARED metric (the metric its index was built
13892
+ // for); only an explicit caller override changes it. Defaulting to cosine
13893
+ // here would mis-rank l2 / inner_product fields and bypass their ANN index.
13894
+ metric: options.metric ?? slot.metric,
13895
+ dimensions: slot.dimensions,
13896
+ indexType: slot.indexType,
13899
13897
  limit: options.limit,
13900
13898
  ...options.minScore === void 0 ? {} : { minScore: options.minScore },
13901
13899
  ...options.efSearch === void 0 ? {} : { efSearch: options.efSearch }
@@ -13947,12 +13945,30 @@ async function executeHybridSearch(ctx, nodeKind, options) {
13947
13945
  const overFetchMultiplier = 4;
13948
13946
  const vectorK = options.vector.k ?? options.limit * overFetchMultiplier;
13949
13947
  const fulltextK = options.fulltext.k ?? options.limit * overFetchMultiplier;
13948
+ const vectorSlot = resolveSearchSlot(ctx, nodeKind, options.vector.fieldPath);
13949
+ assertVectorQueryCompatible(
13950
+ backend,
13951
+ vectorSlot,
13952
+ {
13953
+ metric: options.vector.metric,
13954
+ queryEmbedding: options.vector.queryEmbedding
13955
+ },
13956
+ "hybridSearch.vector"
13957
+ );
13958
+ assertMinScore(
13959
+ options.vector.minScore,
13960
+ options.vector.metric ?? vectorSlot.metric,
13961
+ "hybridSearch.vector.minScore"
13962
+ );
13950
13963
  const vectorPromise = backend.vectorSearch({
13951
13964
  graphId,
13952
13965
  nodeKind,
13953
13966
  fieldPath: options.vector.fieldPath,
13954
13967
  queryEmbedding: options.vector.queryEmbedding,
13955
- metric: options.vector.metric ?? "cosine",
13968
+ // Default to the field's declared metric (see executeVectorSearch).
13969
+ metric: options.vector.metric ?? vectorSlot.metric,
13970
+ dimensions: vectorSlot.dimensions,
13971
+ indexType: vectorSlot.indexType,
13956
13972
  limit: vectorK,
13957
13973
  ...options.vector.minScore === void 0 ? {} : { minScore: options.vector.minScore },
13958
13974
  ...options.vector.efSearch === void 0 ? {} : { efSearch: options.vector.efSearch }
@@ -14043,6 +14059,30 @@ function assertEfSearch(efSearch, label) {
14043
14059
  );
14044
14060
  }
14045
14061
  }
14062
+ function assertMinScore(minScore, metric, label) {
14063
+ if (minScore === void 0) return;
14064
+ assertVectorMinScore(minScore, metric, label);
14065
+ }
14066
+ function assertVectorQueryCompatible(backend, slot, options, label) {
14067
+ if (options.metric !== void 0 && options.metric !== slot.metric) {
14068
+ throw new ConfigurationError(
14069
+ `${label}: metric "${options.metric}" does not match the field's declared metric "${slot.metric}". Vector storage is built for the declared metric \u2014 omit metric or pass "${slot.metric}".`,
14070
+ { backend: backend.dialect, capability: "vector" }
14071
+ );
14072
+ }
14073
+ const supported = backend.capabilities.vector?.metrics;
14074
+ if (supported !== void 0 && !supported.includes(slot.metric)) {
14075
+ throw new ConfigurationError(
14076
+ `${label}: backend "${backend.dialect}" does not support the "${slot.metric}" metric (supported: ${supported.join(", ")}).`,
14077
+ { backend: backend.dialect, capability: "vector" }
14078
+ );
14079
+ }
14080
+ if (options.queryEmbedding.length !== slot.dimensions) {
14081
+ throw new RangeError(
14082
+ `${label}: queryEmbedding has ${options.queryEmbedding.length} dimensions, but "${slot.dimensions}" are declared for this field.`
14083
+ );
14084
+ }
14085
+ }
14046
14086
  function validateFulltextCallOptions(backend, options) {
14047
14087
  const strategy = backend.fulltextStrategy;
14048
14088
  const capabilities = backend.capabilities.fulltext;
@@ -14149,7 +14189,11 @@ var StoreSearch = class {
14149
14189
  async fulltext(nodeKind, options) {
14150
14190
  this.#assertKindRegistered(nodeKind);
14151
14191
  return executeFulltextSearch(
14152
- { graphId: this.#context.graphId, backend: this.#context.backend },
14192
+ {
14193
+ graphId: this.#context.graphId,
14194
+ backend: this.#context.backend,
14195
+ registry: this.#context.registry
14196
+ },
14153
14197
  nodeKind,
14154
14198
  options
14155
14199
  );
@@ -14168,7 +14212,11 @@ var StoreSearch = class {
14168
14212
  async vector(nodeKind, options) {
14169
14213
  this.#assertKindRegistered(nodeKind);
14170
14214
  return executeVectorSearch(
14171
- { graphId: this.#context.graphId, backend: this.#context.backend },
14215
+ {
14216
+ graphId: this.#context.graphId,
14217
+ backend: this.#context.backend,
14218
+ registry: this.#context.registry
14219
+ },
14172
14220
  nodeKind,
14173
14221
  options
14174
14222
  );
@@ -14185,7 +14233,11 @@ var StoreSearch = class {
14185
14233
  async hybrid(nodeKind, options) {
14186
14234
  this.#assertKindRegistered(nodeKind);
14187
14235
  return executeHybridSearch(
14188
- { graphId: this.#context.graphId, backend: this.#context.backend },
14236
+ {
14237
+ graphId: this.#context.graphId,
14238
+ backend: this.#context.backend,
14239
+ registry: this.#context.registry
14240
+ },
14189
14241
  nodeKind,
14190
14242
  options
14191
14243
  );
@@ -14234,6 +14286,7 @@ var UNKNOWN_SCHEMA_METADATA = Object.freeze({
14234
14286
  schemaVersion: void 0,
14235
14287
  schemaHash: void 0
14236
14288
  });
14289
+ var DEFAULT_REEMBED_BATCH_SIZE = 200;
14237
14290
  var CAUGHT_UP_VERB_DETAILS = {
14238
14291
  evolve: { phrase: "evolve", code: "EVOLVE_BEFORE_INITIALIZE" },
14239
14292
  materialize: {
@@ -14248,6 +14301,10 @@ var CAUGHT_UP_VERB_DETAILS = {
14248
14301
  undeprecate: {
14249
14302
  phrase: "undeprecate kinds on",
14250
14303
  code: "DEPRECATE_BEFORE_INITIALIZE"
14304
+ },
14305
+ reembed: {
14306
+ phrase: "re-embed a vector field on",
14307
+ code: "REEMBED_BEFORE_INITIALIZE"
14251
14308
  }
14252
14309
  };
14253
14310
  var Store = class _Store {
@@ -14799,7 +14856,7 @@ var Store = class _Store {
14799
14856
  return fn({ nodes: this.nodes, edges: this.edges });
14800
14857
  }
14801
14858
  return this.#backend.transaction(
14802
- async (txBackend, sql17) => fn(this.#buildTransactionContext(txBackend, sql17))
14859
+ async (txBackend, sql18) => fn(this.#buildTransactionContext(txBackend, sql18))
14803
14860
  );
14804
14861
  }
14805
14862
  /**
@@ -14876,7 +14933,7 @@ var Store = class _Store {
14876
14933
  * raw Drizzle handle bound to the same transaction (#140);
14877
14934
  * `undefined` only on the non-transactional fallback.
14878
14935
  */
14879
- #buildTransactionContext(txBackend, sql17) {
14936
+ #buildTransactionContext(txBackend, sql18) {
14880
14937
  const txNodeOperations = {
14881
14938
  ...this.#nodeOperations,
14882
14939
  createQuery: () => this.#createQueryForBackend(txBackend)
@@ -14899,7 +14956,7 @@ var Store = class _Store {
14899
14956
  txBackend,
14900
14957
  txEdgeOperations
14901
14958
  );
14902
- return sql17 === void 0 ? { nodes, edges } : { nodes, edges, sql: sql17 };
14959
+ return sql18 === void 0 ? { nodes, edges } : { nodes, edges, sql: sql18 };
14903
14960
  }
14904
14961
  // === Graph Lifecycle ===
14905
14962
  /**
@@ -14916,11 +14973,44 @@ var Store = class _Store {
14916
14973
  await target.clearGraph(this.graphId);
14917
14974
  };
14918
14975
  await (this.#backend.capabilities.transactions ? this.#backend.transaction(async (tx) => doClear(tx)) : doClear(this.#backend));
14976
+ await this.#clearVectorStorage();
14919
14977
  this.#nodeCollections = void 0;
14920
14978
  this.#edgeCollections = void 0;
14921
14979
  this.#algorithms = void 0;
14922
14980
  this.#search = void 0;
14923
14981
  }
14982
+ /**
14983
+ * Resets every declared embedding field's per-field storage for this graph by
14984
+ * dropping and recreating it empty. Drop+recreate (rather than DELETE) mirrors
14985
+ * `reembedVectorField` and keeps the backend's storage-ensure latch valid: the
14986
+ * table still exists after clear, so a later write finds it. Enumerated from
14987
+ * the in-memory registry (not the DB schema, which `clearGraph` just wiped).
14988
+ */
14989
+ async #clearVectorStorage() {
14990
+ const backend = this.#backend;
14991
+ const strategy = backend.vectorStrategy;
14992
+ if (strategy === void 0 || backend.executeDdl === void 0) return;
14993
+ for (const [nodeKind, nodeType] of this.#registry.nodeKinds) {
14994
+ for (const field2 of resolveEmbeddingFields(nodeType.schema)) {
14995
+ const slot = {
14996
+ graphId: this.graphId,
14997
+ nodeKind,
14998
+ fieldPath: field2.fieldPath,
14999
+ dimensions: field2.dimensions,
15000
+ metric: field2.metric,
15001
+ indexType: field2.indexType
15002
+ };
15003
+ for (const ddl of strategy.buildDropStorage(slot)) {
15004
+ await backend.executeDdl(ddl);
15005
+ }
15006
+ for (const contribution of strategy.ownedTables(slot)) {
15007
+ for (const ddl of contribution.createDdl) {
15008
+ await backend.executeDdl(ddl);
15009
+ }
15010
+ }
15011
+ }
15012
+ }
15013
+ }
14924
15014
  // === Lifecycle ===
14925
15015
  /**
14926
15016
  * Refreshes the backend's query-planner statistics.
@@ -15144,6 +15234,150 @@ var Store = class _Store {
15144
15234
  options ?? {}
15145
15235
  );
15146
15236
  }
15237
+ /**
15238
+ * Recreate a vector field's per-field storage at its current declared
15239
+ * dimension, then optionally re-embed existing rows.
15240
+ *
15241
+ * Use this after changing a field's `embedding(N)` to `embedding(M)` (e.g. a
15242
+ * new embedding model): the stored N-dim vectors are invalid under the new
15243
+ * dimension and must be recomputed, not converted. This drops and recreates
15244
+ * the per-`(graphId, kind, field)` table at the new dimension — a brief
15245
+ * window where the field returns no vector hits — resets its materialization
15246
+ * marker, then, when `options.embed` is supplied, pages the kind's nodes,
15247
+ * calls `embed(batch)`, and upserts the returned vectors. Without `embed`,
15248
+ * storage is recreated empty and the caller re-embeds via normal
15249
+ * `update()` / `upsertEmbedding` writes.
15250
+ *
15251
+ * @throws {ConfigurationError} when the backend has no vector strategy or
15252
+ * cannot execute DDL, or `(kind, fieldPath)` is not a declared embedding.
15253
+ */
15254
+ async reembedVectorField(kind, fieldPath, options) {
15255
+ if (options?.batchSize !== void 0 && (!Number.isInteger(options.batchSize) || options.batchSize <= 0)) {
15256
+ throw new RangeError(
15257
+ `reembedVectorField batchSize must be a positive integer, got: ${options.batchSize}`
15258
+ );
15259
+ }
15260
+ const { activeRow, baseline } = await this.#loadCaughtUp("reembed");
15261
+ const backend = this.#backend;
15262
+ const strategy = backend.vectorStrategy;
15263
+ if (strategy === void 0 || backend.executeDdl === void 0) {
15264
+ throw new ConfigurationError(
15265
+ "reembedVectorField requires a backend with a vector strategy and executeDdl.",
15266
+ {
15267
+ backend: backend.dialect,
15268
+ capability: "vector",
15269
+ operation: "reembed"
15270
+ }
15271
+ );
15272
+ }
15273
+ const declaration = (baseline.indexes ?? []).find(
15274
+ (candidate) => candidate.entity === "vector" && candidate.kind === kind && candidate.fieldPath === fieldPath
15275
+ );
15276
+ if (declaration === void 0) {
15277
+ throw new ConfigurationError(
15278
+ `No embedding field "${kind}.${fieldPath}" is declared in the active schema.`,
15279
+ { kind, fieldPath, operation: "reembed" }
15280
+ );
15281
+ }
15282
+ const slot = {
15283
+ graphId: this.graphId,
15284
+ nodeKind: kind,
15285
+ fieldPath,
15286
+ dimensions: declaration.dimensions,
15287
+ metric: declaration.metric,
15288
+ indexType: declaration.indexType
15289
+ };
15290
+ for (const ddl of strategy.buildDropStorage(slot)) {
15291
+ await backend.executeDdl(ddl);
15292
+ }
15293
+ for (const contribution of strategy.ownedTables(slot)) {
15294
+ for (const ddl of contribution.createDdl) {
15295
+ await backend.executeDdl(ddl);
15296
+ }
15297
+ }
15298
+ const declaredIndexMaterializes = declaration.indexType !== "none" && backend.capabilities.vector?.indexTypes.includes(
15299
+ declaration.indexType
15300
+ ) === true;
15301
+ if (declaredIndexMaterializes && backend.createVectorIndex !== void 0) {
15302
+ await backend.createVectorIndex({
15303
+ graphId: this.graphId,
15304
+ nodeKind: kind,
15305
+ fieldPath,
15306
+ dimensions: declaration.dimensions,
15307
+ metric: declaration.metric,
15308
+ indexType: declaration.indexType,
15309
+ indexParams: {
15310
+ m: declaration.indexParams.m,
15311
+ efConstruction: declaration.indexParams.efConstruction,
15312
+ ...declaration.indexParams.lists === void 0 ? {} : { lists: declaration.indexParams.lists }
15313
+ }
15314
+ });
15315
+ }
15316
+ if (declaredIndexMaterializes && backend.recordIndexMaterialization !== void 0) {
15317
+ const tableName = strategy.tableName(this.graphId, kind, fieldPath);
15318
+ const signature = await computeIndexSignature(
15319
+ backend.dialect,
15320
+ tableName,
15321
+ declaration
15322
+ );
15323
+ const now = nowIso();
15324
+ await backend.recordIndexMaterialization({
15325
+ indexName: vectorStatusKey(this.graphId, declaration.name),
15326
+ graphId: this.graphId,
15327
+ entity: "vector",
15328
+ kind,
15329
+ signature,
15330
+ schemaVersion: activeRow.version,
15331
+ attemptedAt: now,
15332
+ materializedAt: now,
15333
+ error: void 0
15334
+ });
15335
+ }
15336
+ if (options?.embed === void 0) {
15337
+ return { recreated: true, reembedded: 0 };
15338
+ }
15339
+ if (backend.upsertEmbedding === void 0) {
15340
+ throw new ConfigurationError(
15341
+ "reembedVectorField with an `embed` callback requires a backend that supports upsertEmbedding.",
15342
+ {
15343
+ backend: backend.dialect,
15344
+ capability: "vector",
15345
+ operation: "reembed"
15346
+ }
15347
+ );
15348
+ }
15349
+ const upsertEmbedding = backend.upsertEmbedding;
15350
+ const batchSize = options.batchSize ?? DEFAULT_REEMBED_BATCH_SIZE;
15351
+ const collection = this.getNodeCollectionOrThrow(kind);
15352
+ let reembedded = 0;
15353
+ let offset = 0;
15354
+ for (; ; ) {
15355
+ const batch = await collection.find({
15356
+ limit: batchSize,
15357
+ offset
15358
+ });
15359
+ if (batch.length === 0) break;
15360
+ const vectors = await options.embed(batch);
15361
+ for (const node of batch) {
15362
+ const embedding2 = vectors.get(node.id);
15363
+ if (embedding2 === void 0) continue;
15364
+ await upsertEmbedding({
15365
+ graphId: this.graphId,
15366
+ nodeKind: kind,
15367
+ nodeId: node.id,
15368
+ fieldPath,
15369
+ embedding: embedding2,
15370
+ dimensions: declaration.dimensions,
15371
+ metric: declaration.metric,
15372
+ indexType: declaration.indexType
15373
+ });
15374
+ reembedded += 1;
15375
+ }
15376
+ offset += batch.length;
15377
+ if (batch.length < batchSize) break;
15378
+ }
15379
+ return { recreated: true, reembedded };
15380
+ }
15147
15381
  /**
15148
15382
  * Removes extension kinds from the schema with cascading edge and
15149
15383
  * ontology cleanup. Two-phase by design:
@@ -15521,6 +15755,6 @@ async function createVerifiedStore(graph, backend, options) {
15521
15755
  return [store, result];
15522
15756
  }
15523
15757
 
15524
- export { DEFAULT_SQL_SCHEMA, ExecutableAggregateQuery, ExecutableQuery, MAX_EXPLICIT_RECURSIVE_DEPTH, MAX_RECURSIVE_DEPTH, PreparedQuery, QueryBuilder, StoreSearch, UnionableQuery, avg, composeFragments, count, countDistinct, countDistinctEdges, countEdges, createExternalRef, createFragment, createQueryBuilder, createSqlSchema, createStore, createStoreWithSchema, createVerifiedStore, defineSubgraphProject, exists, externalRef, field, fieldRef, generateId, getExternalRefTable, having, havingEq, havingGt, havingGte, havingLt, havingLte, inSubquery, isExternalRefSchema, isParameterRef, limitFragment, max, metaEdge, min, notExists, notInSubquery, offsetFragment, orderByFragment, param, sum };
15758
+ export { DEFAULT_SQL_SCHEMA, ExecutableAggregateQuery, ExecutableQuery, MAX_EXPLICIT_RECURSIVE_DEPTH, MAX_RECURSIVE_DEPTH, PreparedQuery, QueryBuilder, StoreSearch, UnionableQuery, avg, composeFragments, count, countDistinct, countDistinctEdges, countEdges, createExternalRef, createFragment, createQueryBuilder, createSqlSchema, createStore, createStoreWithSchema, createVerifiedStore, defineSubgraphProject, exists, externalRef, field, fieldRef, generateId, getExternalRefTable, having, havingEq, havingGt, havingGte, havingLt, havingLte, inSubquery, isExternalRefSchema, isParameterRef, limitFragment, max, metaEdge, migrateLegacyEmbeddings, min, notExists, notInSubquery, offsetFragment, orderByFragment, param, sum };
15525
15759
  //# sourceMappingURL=index.js.map
15526
15760
  //# sourceMappingURL=index.js.map