@nicia-ai/typegraph 0.50.0 → 0.51.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 (326) hide show
  1. package/README.md +12 -0
  2. package/dist/backend/drizzle/indexes.cjs +10 -8
  3. package/dist/backend/drizzle/indexes.d.cts +1 -1
  4. package/dist/backend/drizzle/indexes.d.ts +1 -1
  5. package/dist/backend/drizzle/indexes.js +6 -4
  6. package/dist/backend/index.cjs +183 -50
  7. package/dist/backend/index.d.cts +90 -4
  8. package/dist/backend/index.d.ts +90 -4
  9. package/dist/backend/index.js +6 -9
  10. package/dist/backend/postgres/index.cjs +30 -28
  11. package/dist/backend/postgres/index.d.cts +7 -7
  12. package/dist/backend/postgres/index.d.ts +7 -7
  13. package/dist/backend/postgres/index.js +16 -14
  14. package/dist/backend/postgres/pglite-store.cjs +6 -62
  15. package/dist/backend/postgres/pglite-store.cjs.map +1 -1
  16. package/dist/backend/postgres/pglite-store.d.cts +8 -8
  17. package/dist/backend/postgres/pglite-store.d.ts +8 -8
  18. package/dist/backend/postgres/pglite-store.js +6 -62
  19. package/dist/backend/postgres/pglite-store.js.map +1 -1
  20. package/dist/backend/postgres/pglite.cjs +18 -16
  21. package/dist/backend/postgres/pglite.d.cts +3 -3
  22. package/dist/backend/postgres/pglite.d.ts +3 -3
  23. package/dist/backend/postgres/pglite.js +17 -15
  24. package/dist/backend/sqlite/index.cjs +27 -25
  25. package/dist/backend/sqlite/index.d.cts +7 -7
  26. package/dist/backend/sqlite/index.d.ts +7 -7
  27. package/dist/backend/sqlite/index.js +14 -12
  28. package/dist/backend/sqlite/libsql.cjs +21 -19
  29. package/dist/backend/sqlite/libsql.cjs.map +1 -1
  30. package/dist/backend/sqlite/libsql.d.cts +3 -3
  31. package/dist/backend/sqlite/libsql.d.ts +3 -3
  32. package/dist/backend/sqlite/libsql.js +16 -14
  33. package/dist/backend/sqlite/libsql.js.map +1 -1
  34. package/dist/backend/sqlite/local-store.cjs +8 -64
  35. package/dist/backend/sqlite/local-store.cjs.map +1 -1
  36. package/dist/backend/sqlite/local-store.d.cts +8 -8
  37. package/dist/backend/sqlite/local-store.d.ts +8 -8
  38. package/dist/backend/sqlite/local-store.js +7 -64
  39. package/dist/backend/sqlite/local-store.js.map +1 -1
  40. package/dist/backend/sqlite/local.cjs +22 -19
  41. package/dist/backend/sqlite/local.d.cts +3 -3
  42. package/dist/backend/sqlite/local.d.ts +3 -3
  43. package/dist/backend/sqlite/local.js +18 -15
  44. package/dist/{chunk-TUVD4DFR.cjs → chunk-2CVDZCXH.cjs} +122 -51
  45. package/dist/chunk-2CVDZCXH.cjs.map +1 -0
  46. package/dist/{chunk-I5C6OTKR.js → chunk-2DWTBNSH.js} +3 -3
  47. package/dist/{chunk-I5C6OTKR.js.map → chunk-2DWTBNSH.js.map} +1 -1
  48. package/dist/{chunk-C76WFIVZ.cjs → chunk-2KCTP3U2.cjs} +180 -127
  49. package/dist/chunk-2KCTP3U2.cjs.map +1 -0
  50. package/dist/{chunk-BYBDM423.cjs → chunk-322TBTOQ.cjs} +48 -48
  51. package/dist/{chunk-BYBDM423.cjs.map → chunk-322TBTOQ.cjs.map} +1 -1
  52. package/dist/chunk-36SX6QXP.cjs +186 -0
  53. package/dist/chunk-36SX6QXP.cjs.map +1 -0
  54. package/dist/{chunk-H3XP6BAV.js → chunk-36VYWVQU.js} +3 -3
  55. package/dist/{chunk-H3XP6BAV.js.map → chunk-36VYWVQU.js.map} +1 -1
  56. package/dist/{chunk-VTJVMP4I.js → chunk-4DKY6RIU.js} +102 -31
  57. package/dist/chunk-4DKY6RIU.js.map +1 -0
  58. package/dist/chunk-4QKOZYMV.js +9 -0
  59. package/dist/chunk-4QKOZYMV.js.map +1 -0
  60. package/dist/{chunk-U3Z7XKAG.js → chunk-57JM6NW3.js} +8 -18
  61. package/dist/chunk-57JM6NW3.js.map +1 -0
  62. package/dist/{chunk-XMY2SXOH.cjs → chunk-5WWEYV4H.cjs} +2208 -579
  63. package/dist/chunk-5WWEYV4H.cjs.map +1 -0
  64. package/dist/{chunk-WQBAQZHR.js → chunk-6NLYIMJO.js} +4 -4
  65. package/dist/{chunk-WQBAQZHR.js.map → chunk-6NLYIMJO.js.map} +1 -1
  66. package/dist/{chunk-G2TLHH6T.cjs → chunk-7B7I7YAW.cjs} +6 -6
  67. package/dist/{chunk-G2TLHH6T.cjs.map → chunk-7B7I7YAW.cjs.map} +1 -1
  68. package/dist/{chunk-EDLKIQRI.js → chunk-7G5IYROL.js} +6 -548
  69. package/dist/chunk-7G5IYROL.js.map +1 -0
  70. package/dist/{chunk-46UGOVRW.js → chunk-7QFRK6PU.js} +3 -7
  71. package/dist/chunk-7QFRK6PU.js.map +1 -0
  72. package/dist/chunk-A4C4NJ5U.cjs +12 -0
  73. package/dist/chunk-A4C4NJ5U.cjs.map +1 -0
  74. package/dist/{chunk-TYGGUWMS.cjs → chunk-B3MN7EJR.cjs} +177 -137
  75. package/dist/chunk-B3MN7EJR.cjs.map +1 -0
  76. package/dist/{chunk-K6VKTBST.cjs → chunk-BZ5MVITP.cjs} +4 -4
  77. package/dist/{chunk-K6VKTBST.cjs.map → chunk-BZ5MVITP.cjs.map} +1 -1
  78. package/dist/{chunk-R7MRFE5P.js → chunk-CAI6SMP6.js} +3 -3
  79. package/dist/{chunk-R7MRFE5P.js.map → chunk-CAI6SMP6.js.map} +1 -1
  80. package/dist/{chunk-ZAQUKCUC.js → chunk-CBOD7TXH.js} +5 -5
  81. package/dist/{chunk-ZAQUKCUC.js.map → chunk-CBOD7TXH.js.map} +1 -1
  82. package/dist/{chunk-LLVOQOWE.cjs → chunk-CRZ56SZU.cjs} +6 -5
  83. package/dist/chunk-CRZ56SZU.cjs.map +1 -0
  84. package/dist/{chunk-ON47CBE4.cjs → chunk-D3GWARN7.cjs} +47 -47
  85. package/dist/{chunk-ON47CBE4.cjs.map → chunk-D3GWARN7.cjs.map} +1 -1
  86. package/dist/{chunk-W5SOCUBL.js → chunk-D3OUDFU7.js} +5 -5
  87. package/dist/{chunk-W5SOCUBL.js.map → chunk-D3OUDFU7.js.map} +1 -1
  88. package/dist/chunk-EKG2UXNX.cjs +23 -0
  89. package/dist/chunk-EKG2UXNX.cjs.map +1 -0
  90. package/dist/{chunk-7PRMDZIA.cjs → chunk-FMMW3KX7.cjs} +21 -55
  91. package/dist/chunk-FMMW3KX7.cjs.map +1 -0
  92. package/dist/chunk-H2VWDQWC.cjs +571 -0
  93. package/dist/chunk-H2VWDQWC.cjs.map +1 -0
  94. package/dist/chunk-H4FY6OZK.js +13 -0
  95. package/dist/chunk-H4FY6OZK.js.map +1 -0
  96. package/dist/{chunk-OJHD3LXJ.cjs → chunk-H5IJSROF.cjs} +2 -8
  97. package/dist/chunk-H5IJSROF.cjs.map +1 -0
  98. package/dist/{chunk-U5EL6JUV.js → chunk-I5IOSA27.js} +101 -103
  99. package/dist/chunk-I5IOSA27.js.map +1 -0
  100. package/dist/{chunk-SHC7BCG5.cjs → chunk-I7YAY2VQ.cjs} +7 -7
  101. package/dist/{chunk-SHC7BCG5.cjs.map → chunk-I7YAY2VQ.cjs.map} +1 -1
  102. package/dist/chunk-IRCWIA3R.js +20 -0
  103. package/dist/chunk-IRCWIA3R.js.map +1 -0
  104. package/dist/chunk-IVQBLXBK.cjs +55 -0
  105. package/dist/chunk-IVQBLXBK.cjs.map +1 -0
  106. package/dist/{chunk-5PP4KRPV.js → chunk-IZD4HTCP.js} +5 -5
  107. package/dist/{chunk-5PP4KRPV.js.map → chunk-IZD4HTCP.js.map} +1 -1
  108. package/dist/{chunk-7CCMCMJO.cjs → chunk-JHRUZ73O.cjs} +75 -66
  109. package/dist/chunk-JHRUZ73O.cjs.map +1 -0
  110. package/dist/{chunk-RDP6ZRSM.cjs → chunk-JQKMEKKW.cjs} +261 -204
  111. package/dist/chunk-JQKMEKKW.cjs.map +1 -0
  112. package/dist/chunk-JVA3KDEA.cjs +691 -0
  113. package/dist/chunk-JVA3KDEA.cjs.map +1 -0
  114. package/dist/{chunk-JG5XIJDY.js → chunk-K67P5DLL.js} +62 -22
  115. package/dist/chunk-K67P5DLL.js.map +1 -0
  116. package/dist/{chunk-CS6JTQQ2.cjs → chunk-KACEYDYV.cjs} +94 -62
  117. package/dist/chunk-KACEYDYV.cjs.map +1 -0
  118. package/dist/{chunk-5OWHU7Z7.cjs → chunk-L6EVYIID.cjs} +248 -210
  119. package/dist/chunk-L6EVYIID.cjs.map +1 -0
  120. package/dist/{chunk-7OWE7WD6.js → chunk-LI4K2KEJ.js} +4 -4
  121. package/dist/{chunk-7OWE7WD6.js.map → chunk-LI4K2KEJ.js.map} +1 -1
  122. package/dist/chunk-LKZDQ2B4.js +1581 -0
  123. package/dist/chunk-LKZDQ2B4.js.map +1 -0
  124. package/dist/{chunk-45YZXI6X.cjs → chunk-LLFPQOBA.cjs} +27 -27
  125. package/dist/{chunk-45YZXI6X.cjs.map → chunk-LLFPQOBA.cjs.map} +1 -1
  126. package/dist/{chunk-ZRJTM7MT.js → chunk-LZMQ3SFK.js} +3 -3
  127. package/dist/{chunk-ZRJTM7MT.js.map → chunk-LZMQ3SFK.js.map} +1 -1
  128. package/dist/{chunk-DI6VC62F.js → chunk-M3VTS3F6.js} +3 -3
  129. package/dist/{chunk-DI6VC62F.js.map → chunk-M3VTS3F6.js.map} +1 -1
  130. package/dist/{chunk-MZ34E2GN.js → chunk-NBOS7BY3.js} +60 -21
  131. package/dist/chunk-NBOS7BY3.js.map +1 -0
  132. package/dist/{chunk-YA36ABIL.js → chunk-NGQDGL5X.js} +14 -48
  133. package/dist/chunk-NGQDGL5X.js.map +1 -0
  134. package/dist/{chunk-ZBFZGLZE.cjs → chunk-NLX5OWK7.cjs} +6 -2
  135. package/dist/chunk-NLX5OWK7.cjs.map +1 -0
  136. package/dist/chunk-NUQ2YFFH.cjs +1637 -0
  137. package/dist/chunk-NUQ2YFFH.cjs.map +1 -0
  138. package/dist/{chunk-TTCOPKUL.cjs → chunk-OGL4X4PH.cjs} +182 -184
  139. package/dist/chunk-OGL4X4PH.cjs.map +1 -0
  140. package/dist/{chunk-HY5BNOUN.cjs → chunk-OTNTGEXR.cjs} +4 -4
  141. package/dist/{chunk-HY5BNOUN.cjs.map → chunk-OTNTGEXR.cjs.map} +1 -1
  142. package/dist/chunk-OTWE63BW.js +53 -0
  143. package/dist/chunk-OTWE63BW.js.map +1 -0
  144. package/dist/chunk-PC5NGH5A.js +549 -0
  145. package/dist/chunk-PC5NGH5A.js.map +1 -0
  146. package/dist/{chunk-IPRP6TDL.cjs → chunk-PS3TUWJM.cjs} +7 -7
  147. package/dist/{chunk-IPRP6TDL.cjs.map → chunk-PS3TUWJM.cjs.map} +1 -1
  148. package/dist/{chunk-V76FGHY3.js → chunk-PVFFH7TL.js} +5 -5
  149. package/dist/{chunk-V76FGHY3.js.map → chunk-PVFFH7TL.js.map} +1 -1
  150. package/dist/chunk-QCD5JKU4.cjs +15 -0
  151. package/dist/chunk-QCD5JKU4.cjs.map +1 -0
  152. package/dist/{chunk-IRPYOHRC.js → chunk-QG5VEOKX.js} +6 -2
  153. package/dist/chunk-QG5VEOKX.js.map +1 -0
  154. package/dist/{chunk-MM3JHVKZ.cjs → chunk-QLLZM5I3.cjs} +4 -4
  155. package/dist/{chunk-MM3JHVKZ.cjs.map → chunk-QLLZM5I3.cjs.map} +1 -1
  156. package/dist/{chunk-MX7EKQPM.js → chunk-RCBG6YMT.js} +345 -97
  157. package/dist/chunk-RCBG6YMT.js.map +1 -0
  158. package/dist/{chunk-2CYI5HRH.js → chunk-RI7RJH4G.js} +49 -17
  159. package/dist/chunk-RI7RJH4G.js.map +1 -0
  160. package/dist/{chunk-5LKOVCPP.js → chunk-RVUL2HXY.js} +6 -5
  161. package/dist/chunk-RVUL2HXY.js.map +1 -0
  162. package/dist/{chunk-WK23PGTP.cjs → chunk-S5GU4LUN.cjs} +11 -11
  163. package/dist/{chunk-WK23PGTP.cjs.map → chunk-S5GU4LUN.cjs.map} +1 -1
  164. package/dist/{chunk-S33YQEL7.js → chunk-SDPWO2Z5.js} +6 -6
  165. package/dist/{chunk-S33YQEL7.js.map → chunk-SDPWO2Z5.js.map} +1 -1
  166. package/dist/{chunk-6S3PTHL4.js → chunk-SLGGT2XD.js} +3 -3
  167. package/dist/{chunk-6S3PTHL4.js.map → chunk-SLGGT2XD.js.map} +1 -1
  168. package/dist/{chunk-HSEZ7X6Y.cjs → chunk-TIJUA4I6.cjs} +45 -45
  169. package/dist/{chunk-HSEZ7X6Y.cjs.map → chunk-TIJUA4I6.cjs.map} +1 -1
  170. package/dist/{chunk-CSNOYIB4.cjs → chunk-TM54OBHX.cjs} +13 -13
  171. package/dist/{chunk-CSNOYIB4.cjs.map → chunk-TM54OBHX.cjs.map} +1 -1
  172. package/dist/{chunk-2GIV5X4P.js → chunk-TYEYRCXL.js} +86 -33
  173. package/dist/chunk-TYEYRCXL.js.map +1 -0
  174. package/dist/{chunk-MJPZNEJZ.js → chunk-UKOVGCRN.js} +2095 -496
  175. package/dist/chunk-UKOVGCRN.js.map +1 -0
  176. package/dist/chunk-UYKDYE5D.cjs +12 -0
  177. package/dist/{chunk-KWNWG4RC.cjs.map → chunk-UYKDYE5D.cjs.map} +1 -1
  178. package/dist/{chunk-FX5ZW6PN.js → chunk-VAAC7L57.js} +95 -40
  179. package/dist/chunk-VAAC7L57.js.map +1 -0
  180. package/dist/{chunk-ISKCIQF2.cjs → chunk-VKHXYVN7.cjs} +14 -25
  181. package/dist/chunk-VKHXYVN7.cjs.map +1 -0
  182. package/dist/chunk-VUQZNUHU.js +171 -0
  183. package/dist/chunk-VUQZNUHU.js.map +1 -0
  184. package/dist/{chunk-K2XYLVVB.cjs → chunk-WDM5WQK4.cjs} +175 -136
  185. package/dist/chunk-WDM5WQK4.cjs.map +1 -0
  186. package/dist/{chunk-GVYVGGPJ.js → chunk-WFSYYU4W.js} +66 -28
  187. package/dist/chunk-WFSYYU4W.js.map +1 -0
  188. package/dist/{chunk-WCLMKNQE.cjs → chunk-WRBV2FNH.cjs} +1356 -1108
  189. package/dist/chunk-WRBV2FNH.cjs.map +1 -0
  190. package/dist/chunk-XORONCV3.js +202 -0
  191. package/dist/chunk-XORONCV3.js.map +1 -0
  192. package/dist/{chunk-2Q45FAIE.js → chunk-YT2IVFAI.js} +26 -17
  193. package/dist/chunk-YT2IVFAI.js.map +1 -0
  194. package/dist/chunk-ZGVTNKTX.cjs +217 -0
  195. package/dist/chunk-ZGVTNKTX.cjs.map +1 -0
  196. package/dist/core/index.cjs +20 -20
  197. package/dist/core/index.d.cts +4 -4
  198. package/dist/core/index.d.ts +4 -4
  199. package/dist/core/index.js +4 -4
  200. package/dist/{ddl-B49O7dB_.d.ts → ddl-BvcbgzHo.d.ts} +3 -3
  201. package/dist/{ddl-DcZG660s.d.cts → ddl-Ufebz5q5.d.cts} +3 -3
  202. package/dist/graph-extension/index.d.cts +2 -4
  203. package/dist/graph-extension/index.d.ts +2 -4
  204. package/dist/graph-merge/index.cjs +140 -125
  205. package/dist/graph-merge/index.cjs.map +1 -1
  206. package/dist/graph-merge/index.d.cts +8 -9
  207. package/dist/graph-merge/index.d.ts +8 -9
  208. package/dist/graph-merge/index.js +42 -27
  209. package/dist/graph-merge/index.js.map +1 -1
  210. package/dist/index.cjs +144 -143
  211. package/dist/index.cjs.map +1 -1
  212. package/dist/index.d.cts +11 -12
  213. package/dist/index.d.ts +11 -12
  214. package/dist/index.js +30 -29
  215. package/dist/index.js.map +1 -1
  216. package/dist/indexes/index.cjs +14 -12
  217. package/dist/indexes/index.d.cts +4 -4
  218. package/dist/indexes/index.d.ts +4 -4
  219. package/dist/indexes/index.js +7 -5
  220. package/dist/{ingestion-import-target-CI8OWIkM.d.ts → ingestion-import-target-CAs1OX-l.d.cts} +1 -1
  221. package/dist/{ingestion-import-target-DCpfM1PX.d.cts → ingestion-import-target-DCQSPfNx.d.ts} +1 -1
  222. package/dist/interchange/index.cjs +41 -39
  223. package/dist/interchange/index.cjs.map +1 -1
  224. package/dist/interchange/index.d.cts +8 -8
  225. package/dist/interchange/index.d.ts +8 -8
  226. package/dist/interchange/index.js +16 -14
  227. package/dist/interchange/index.js.map +1 -1
  228. package/dist/local-store-impl-6DDTFM32.cjs +77 -0
  229. package/dist/local-store-impl-6DDTFM32.cjs.map +1 -0
  230. package/dist/local-store-impl-OXTOVU2J.js +75 -0
  231. package/dist/local-store-impl-OXTOVU2J.js.map +1 -0
  232. package/dist/{manager-Cfg1ENj1.d.ts → manager-B68OrPR2.d.ts} +1 -2
  233. package/dist/{manager-D348fa6W.d.cts → manager-D_t7oK69.d.cts} +1 -2
  234. package/dist/pglite-store-impl-6EMZGL7K.js +73 -0
  235. package/dist/pglite-store-impl-6EMZGL7K.js.map +1 -0
  236. package/dist/pglite-store-impl-GJG3Y7RP.cjs +75 -0
  237. package/dist/pglite-store-impl-GJG3Y7RP.cjs.map +1 -0
  238. package/dist/{postgres-UStOycLI.d.ts → postgres-BPLSVyHM.d.ts} +1 -1
  239. package/dist/{postgres-CH1kkM5J.d.cts → postgres-CqvtFC2y.d.cts} +1 -1
  240. package/dist/profiler/index.d.cts +9 -9
  241. package/dist/profiler/index.d.ts +9 -9
  242. package/dist/provenance/index.cjs +33 -20
  243. package/dist/provenance/index.cjs.map +1 -1
  244. package/dist/provenance/index.d.cts +7 -7
  245. package/dist/provenance/index.d.ts +7 -7
  246. package/dist/provenance/index.js +24 -11
  247. package/dist/provenance/index.js.map +1 -1
  248. package/dist/{repair-validity-windows-aWX7VNvv.d.cts → repair-validity-windows-DEzCKAdy.d.cts} +7 -3
  249. package/dist/{repair-validity-windows-BtOEe2pS.d.ts → repair-validity-windows-GMdaS2AH.d.ts} +7 -3
  250. package/dist/resolve-D_H8MHtq.d.ts +1805 -0
  251. package/dist/resolve-WEW8gWws.d.cts +1805 -0
  252. package/dist/schema/index.cjs +42 -40
  253. package/dist/schema/index.d.cts +4 -6
  254. package/dist/schema/index.d.ts +4 -6
  255. package/dist/schema/index.js +15 -13
  256. package/dist/{searchable-z4BiFfHI.d.ts → searchable-C_UREI9K.d.ts} +1 -1
  257. package/dist/{searchable-C8-RrL3l.d.cts → searchable-ClgET_i7.d.cts} +1 -1
  258. package/dist/{sqlite-axLw5Lo5.d.ts → sqlite-D1mXO9Kp.d.cts} +2 -1
  259. package/dist/{sqlite-Cyx9j9o6.d.cts → sqlite-MZA3oZNB.d.ts} +2 -1
  260. package/dist/{store-CTfQ9taw.d.ts → store-CuFX7fCx.d.cts} +38 -41
  261. package/dist/{store-DR9J7JVB.d.cts → store-D-ZjXQpW.d.ts} +38 -41
  262. package/dist/{temporal-CBOrERz5.d.ts → temporal-CpyEiRY8.d.cts} +1 -1
  263. package/dist/{temporal-B4Ky4wzh.d.cts → temporal-y0Aep9Su.d.ts} +1 -1
  264. package/dist/{types-CWg4dTjj.d.ts → types-6yf0Vv-_.d.cts} +1672 -1
  265. package/dist/{types-CWg4dTjj.d.cts → types-6yf0Vv-_.d.ts} +1672 -1
  266. package/dist/{types-BScHXVM7.d.ts → types-DzJ4dlzk.d.cts} +1 -1
  267. package/dist/{types-BE921wRl.d.cts → types-_vVSB9k-.d.ts} +1 -1
  268. package/dist/{where-BWXUPV3C.d.ts → where-DuG2LCLe.d.ts} +1 -1
  269. package/dist/{where-CNtx1aLc.d.cts → where-Mhf_yyKX.d.cts} +1 -1
  270. package/package.json +5 -1
  271. package/dist/chunk-2CYI5HRH.js.map +0 -1
  272. package/dist/chunk-2GIV5X4P.js.map +0 -1
  273. package/dist/chunk-2Q45FAIE.js.map +0 -1
  274. package/dist/chunk-46UGOVRW.js.map +0 -1
  275. package/dist/chunk-5LKOVCPP.js.map +0 -1
  276. package/dist/chunk-5OWHU7Z7.cjs.map +0 -1
  277. package/dist/chunk-6LEOAIIB.js +0 -1160
  278. package/dist/chunk-6LEOAIIB.js.map +0 -1
  279. package/dist/chunk-7CCMCMJO.cjs.map +0 -1
  280. package/dist/chunk-7PRMDZIA.cjs.map +0 -1
  281. package/dist/chunk-C76WFIVZ.cjs.map +0 -1
  282. package/dist/chunk-CS6JTQQ2.cjs.map +0 -1
  283. package/dist/chunk-EDLKIQRI.js.map +0 -1
  284. package/dist/chunk-EH3JZJUM.cjs +0 -567
  285. package/dist/chunk-EH3JZJUM.cjs.map +0 -1
  286. package/dist/chunk-FX5ZW6PN.js.map +0 -1
  287. package/dist/chunk-GHZPZNFC.cjs +0 -132
  288. package/dist/chunk-GHZPZNFC.cjs.map +0 -1
  289. package/dist/chunk-GVYVGGPJ.js.map +0 -1
  290. package/dist/chunk-IHK5KA2Q.cjs +0 -262
  291. package/dist/chunk-IHK5KA2Q.cjs.map +0 -1
  292. package/dist/chunk-IRPYOHRC.js.map +0 -1
  293. package/dist/chunk-ISKCIQF2.cjs.map +0 -1
  294. package/dist/chunk-JG5XIJDY.js.map +0 -1
  295. package/dist/chunk-K2XYLVVB.cjs.map +0 -1
  296. package/dist/chunk-KWNWG4RC.cjs +0 -12
  297. package/dist/chunk-LLVOQOWE.cjs.map +0 -1
  298. package/dist/chunk-MJPZNEJZ.js.map +0 -1
  299. package/dist/chunk-MX7EKQPM.js.map +0 -1
  300. package/dist/chunk-MZ34E2GN.js.map +0 -1
  301. package/dist/chunk-OJHD3LXJ.cjs.map +0 -1
  302. package/dist/chunk-PALYTHGM.js +0 -114
  303. package/dist/chunk-PALYTHGM.js.map +0 -1
  304. package/dist/chunk-RDP6ZRSM.cjs.map +0 -1
  305. package/dist/chunk-S3SDEQMC.js +0 -532
  306. package/dist/chunk-S3SDEQMC.js.map +0 -1
  307. package/dist/chunk-TEC24ZDA.cjs +0 -1254
  308. package/dist/chunk-TEC24ZDA.cjs.map +0 -1
  309. package/dist/chunk-TP4NJTI3.cjs +0 -1192
  310. package/dist/chunk-TP4NJTI3.cjs.map +0 -1
  311. package/dist/chunk-TTCOPKUL.cjs.map +0 -1
  312. package/dist/chunk-TUVD4DFR.cjs.map +0 -1
  313. package/dist/chunk-TYGGUWMS.cjs.map +0 -1
  314. package/dist/chunk-U3Z7XKAG.js.map +0 -1
  315. package/dist/chunk-U5EL6JUV.js.map +0 -1
  316. package/dist/chunk-VTJVMP4I.js.map +0 -1
  317. package/dist/chunk-WCLMKNQE.cjs.map +0 -1
  318. package/dist/chunk-XMY2SXOH.cjs.map +0 -1
  319. package/dist/chunk-Y55DLLEG.js +0 -247
  320. package/dist/chunk-Y55DLLEG.js.map +0 -1
  321. package/dist/chunk-YA36ABIL.js.map +0 -1
  322. package/dist/chunk-ZBFZGLZE.cjs.map +0 -1
  323. package/dist/index-B0PrmE3K.d.cts +0 -1146
  324. package/dist/index-CwcXsL5R.d.ts +0 -1146
  325. package/dist/materialize-indexes-C9GG3O3C.d.ts +0 -266
  326. package/dist/materialize-indexes-CrSiW_lT.d.cts +0 -266
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/query/dialect/vector/pgvector-strategy.ts"],"names":["assertFiniteEmbedding","sql","vectorPhysicalName","quoteIdentifier","VECTOR_CONTRIBUTION_PREFIX","vectorScoreExpression","vectorMinScoreCondition","vectorPageClause"],"mappings":";;;;;;;AA8CA,IAAM,YAAA,GAAe,QAAA;AACrB,IAAM,YAAA,GAAe,WAAA;AASd,IAAM,kBAAA,GAAqB,GAAA;AAM3B,SAAS,uBAAuB,QAAA,EAAyB;AAC9D,EAAA,IAAI,aAAa,MAAA,EAAW;AAC5B,EAAA,IAAI,CAAC,MAAA,CAAO,SAAA,CAAU,QAAQ,CAAA,IAAK,YAAY,CAAA,EAAG;AAChD,IAAA,MAAM,IAAI,KAAA,CAAM,CAAA,0CAAA,EAA6C,QAAQ,CAAA,CAAE,CAAA;AAAA,EACzE;AACA,EAAA,IAAI,WAAW,kBAAA,EAAoB;AACjC,IAAA,MAAM,IAAI,UAAA;AAAA,MACR,CAAA,wBAAA,EAAsB,kBAAkB,CAAA,8CAAA,EACjB,kBAAkB,WAAW,QAAQ,CAAA;AAAA,KAC9D;AAAA,EACF;AACF;AAQA,IAAM,uBAAA,GAA0B,IAAA;AAGhC,IAAM,cAAA,GAAiB,EAAA;AAEvB,IAAM,4BAAA,GAA+B,EAAA;AAErC,IAAM,qBAAA,GAAwB,GAAA;AAE9B,IAAM,qBAAA,GAA4C;AAAA,EAChD,SAAA,EAAW,IAAA;AAAA,EACX,OAAA,EAAS,CAAC,QAAA,EAAU,IAAA,EAAM,eAAe,CAAA;AAAA,EACzC,UAAA,EAAY,CAAC,MAAA,EAAQ,SAAA,EAAW,MAAM,CAAA;AAAA,EACtC,aAAA,EAAe,uBAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAUf,yBAAA,EAA2B;AAAA,IACzB,IAAA,EAAM,gBAAA;AAAA,IACN,kBAAA,EAAoB;AAAA,GACtB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,oBAAA,EAAsB;AAAA,IACpB,OAAA,EAAS,IAAA;AAAA,IACT,SAAA,EAAW,gBAAA;AAAA,IACX,SAAA,EAAW,MAAA;AAAA,IACX,wBAAA,EAA0B;AAAA;AAE9B,CAAA;AAGA,SAAS,aAAa,IAAA,EAA2B;AAC/C,EAAA,OAAO,IAAA,CAAK,SAAA,KAAc,MAAA,IAAU,IAAA,CAAK,SAAA,KAAc,SAAA;AACzD;AAOA,SAAS,cAAc,MAAA,EAA8B;AACnD,EAAA,QAAQ,MAAA;AAAQ,IACd,KAAK,QAAA,EAAU;AACb,MAAA,OAAO,mBAAA;AAAA,IACT;AAAA,IACA,KAAK,IAAA,EAAM;AACT,MAAA,OAAO,eAAA;AAAA,IACT;AAAA,IACA,KAAK,eAAA,EAAiB;AACpB,MAAA,OAAO,eAAA;AAAA,IACT;AAAA,IACA,SAAS;AACP,MAAA,MAAM,WAAA,GAAqB,MAAA;AAC3B,MAAA,MAAM,IAAI,KAAA,CAAM,CAAA,2BAAA,EAA8B,MAAA,CAAO,WAAW,CAAC,CAAA,CAAE,CAAA;AAAA,IACrE;AAAA;AAEJ;AAOA,SAAS,aAAA,CACP,WACA,IAAA,EACa;AACb,EAAAA,uCAAA,CAAsB,WAAW,IAAI,CAAA;AACrC,EAAA,OAAOC,wBAAM,CAAA,CAAA,EAAI,SAAA,CAAU,IAAA,CAAK,GAAG,CAAC,CAAA,CAAA,CAAG,CAAA,QAAA,CAAA;AACzC;AAEA,SAAS,kBAAA,CACP,eAAA,EACA,cAAA,EACA,MAAA,EACa;AACb,EAAA,MAAM,KAAA,GAAQ,aAAA,CAAc,cAAA,EAAgB,gBAAgB,CAAA;AAC5D,EAAA,QAAQ,MAAA;AAAQ,IACd,KAAK,QAAA,EAAU;AACb,MAAA,OAAOA,qBAAA,CAAA,CAAA,EAAO,eAAe,CAAA,KAAA,EAAQ,KAAK,CAAA,CAAA,CAAA;AAAA,IAC5C;AAAA,IACA,KAAK,IAAA,EAAM;AACT,MAAA,OAAOA,qBAAA,CAAA,CAAA,EAAO,eAAe,CAAA,KAAA,EAAQ,KAAK,CAAA,CAAA,CAAA;AAAA,IAC5C;AAAA,IACA,KAAK,eAAA,EAAiB;AACpB,MAAA,OAAOA,qBAAA,CAAA,CAAA,EAAO,eAAe,CAAA,KAAA,EAAQ,KAAK,CAAA,CAAA,CAAA;AAAA,IAC5C;AAAA,IACA,SAAS;AACP,MAAA,MAAM,WAAA,GAAqB,MAAA;AAC3B,MAAA,MAAM,IAAI,KAAA,CAAM,CAAA,2BAAA,EAA8B,MAAA,CAAO,WAAW,CAAC,CAAA,CAAE,CAAA;AAAA,IACrE;AAAA;AAEJ;AAEA,SAAS,SAAA,CACP,OAAA,EACA,QAAA,EACA,SAAA,EACQ;AACR,EAAA,OAAOC,oCAAA,CAAmB,YAAA,EAAc,OAAA,EAAS,QAAA,EAAU,SAAS,CAAA;AACtE;AAEO,IAAM,gBAAA,GAAmC;AAAA,EAC9C,IAAA,EAAM,UAAA;AAAA,EACN,YAAA,EAAc,qBAAA;AAAA,EAEd,SAAA;AAAA,EAEA,YAAY,IAAA,EAA4C;AACtD,IAAA,MAAM,QAAQ,SAAA,CAAU,IAAA,CAAK,SAAS,IAAA,CAAK,QAAA,EAAU,KAAK,SAAS,CAAA;AACnE,IAAA,MAAM,IAAA,GAAOC,kCAAgB,KAAK,CAAA;AAKlC,IAAA,MAAM,SAAA,GAAY;AAAA,MAChB,8BAA8B,IAAI,CAAA;AAAA;AAAA;AAAA,qBAAA,EAGjB,KAAK,UAAU,CAAA;AAAA;AAAA;AAAA;AAAA,EAAA;AAAA,KAKlC;AAWA,IAAA,OAAO;AAAA,MACL;AAAA,QACE,WAAA,EAAa,GAAGC,4CAA0B,CAAA,CAAA,EAAI,KAAK,QAAQ,CAAA,CAAA,EAAI,KAAK,SAAS,CAAA,CAAA;AAAA,QAC7E,KAAA,EAAO,UAAA;AAAA,QACP,SAAA,EAAW,KAAA;AAAA,QACX,SAAA;AAAA,QACA,aAAA,EAAe;AAAA;AACjB,KACF;AAAA,EACF,CAAA;AAAA,EAEA,WAAA,CACE,IAAA,EACA,MAAA,EACA,SAAA,EACwB;AACxB,IAAA,MAAM,QAAQH,qBAAA,CAAI,UAAA;AAAA,MAChB,UAAU,IAAA,CAAK,OAAA,EAAS,IAAA,CAAK,QAAA,EAAU,KAAK,SAAS;AAAA,KACvD;AACA,IAAA,MAAM,KAAA,GAAQ,aAAA,CAAc,MAAA,CAAO,SAAA,EAAW,WAAW,CAAA;AACzD,IAAA,OAAO;AAAA,MACLA,qBAAA;AAAA,oBAAA,EACgB,KAAK,CAAA;AAAA,gBAAA,EACT,MAAA,CAAO,OAAO,CAAA,EAAA,EAAK,MAAA,CAAO,MAAM,KAAK,KAAK,CAAA,EAAA,EAAK,SAAS,CAAA,EAAA,EAAK,SAAS,CAAA;AAAA;AAAA;AAAA,MAAA;AAAA,KAIpF;AAAA,EACF,CAAA;AAAA,EAEA,gBAAA,CACE,IAAA,EACA,MAAA,EACA,SAAA,EACwB;AACxB,IAAA,MAAM,QAAQA,qBAAA,CAAI,UAAA;AAAA,MAChB,UAAU,IAAA,CAAK,OAAA,EAAS,IAAA,CAAK,QAAA,EAAU,KAAK,SAAS;AAAA,KACvD;AACA,IAAA,MAAM,YAAYA,qBAAA,CAAI,IAAA;AAAA,MACpB,OAAO,IAAA,CAAK,GAAA;AAAA,QACV,CAAC,GAAA,KACCA,qBAAA,CAAA,CAAA,EAAO,MAAA,CAAO,OAAO,KAAK,GAAA,CAAI,MAAM,CAAA,EAAA,EAAK,aAAA,CAAc,IAAI,SAAA,EAAW,WAAW,CAAC,CAAA,EAAA,EAAK,SAAS,KAAK,SAAS,CAAA,CAAA;AAAA,OAClH;AAAA,MACAA,qBAAA,CAAA,EAAA;AAAA,KACF;AACA,IAAA,OAAO;AAAA,MACLA,qBAAA;AAAA,oBAAA,EACgB,KAAK,CAAA;AAAA,eAAA,EACV,SAAS;AAAA;AAAA;AAAA,MAAA;AAAA,KAItB;AAAA,EACF,CAAA;AAAA,EAEA,WAAA,CAAY,MAAM,MAAA,EAAuD;AACvE,IAAA,MAAM,QAAQA,qBAAA,CAAI,UAAA;AAAA,MAChB,UAAU,IAAA,CAAK,OAAA,EAAS,IAAA,CAAK,QAAA,EAAU,KAAK,SAAS;AAAA,KACvD;AACA,IAAA,OAAO;AAAA,MACLA,qBAAA;AAAA,oBAAA,EACgB,KAAK;AAAA,2BAAA,EACE,MAAA,CAAO,OAAO,CAAA,iBAAA,EAAoB,MAAA,CAAO,MAAM;AAAA,MAAA;AAAA,KAExE;AAAA,EACF,CAAA;AAAA,EAEA,gBAAA,CACE,MACA,MAAA,EAEwB;AACxB,IAAA,IAAI,MAAA,CAAO,OAAA,CAAQ,MAAA,KAAW,CAAA,SAAU,EAAC;AACzC,IAAA,MAAM,QAAQA,qBAAA,CAAI,UAAA;AAAA,MAChB,UAAU,IAAA,CAAK,OAAA,EAAS,IAAA,CAAK,QAAA,EAAU,KAAK,SAAS;AAAA,KACvD;AACA,IAAA,OAAO;AAAA,MACLA,oCAAkB,KAAK,CAAA,oBAAA,EAAuB,MAAA,CAAO,OAAO,sBAAsBA,qBAAA,CAAI,IAAA;AAAA,QACpF,OAAO,OAAA,CAAQ,GAAA,CAAI,CAAC,MAAA,KAAWA,qBAAA,CAAA,EAAM,MAAM,CAAA,CAAE,CAAA;AAAA,QAC7CA,qBAAA,CAAA,EAAA;AAAA,OACD,CAAA,CAAA;AAAA,KACH;AAAA,EACF,CAAA;AAAA,EAEA,WAAA,CACE,IAAA,EACA,MAAA,EACA,UAAA,EACa;AACb,IAAA,MAAM,QAAQA,qBAAA,CAAI,UAAA;AAAA,MAChB,UAAU,IAAA,CAAK,OAAA,EAAS,IAAA,CAAK,QAAA,EAAU,KAAK,SAAS;AAAA,KACvD;AACA,IAAA,MAAM,eAAA,GAAkBA,wBAAM,KAAK,CAAA,YAAA,CAAA;AACnC,IAAA,MAAM,QAAA,GAAW,kBAAA;AAAA,MACf,eAAA;AAAA,MACA,MAAA,CAAO,cAAA;AAAA,MACP,MAAA,CAAO;AAAA,KACT;AACA,IAAA,MAAM,KAAA,GAAQI,uCAAA,CAAsB,QAAA,EAAU,MAAA,CAAO,MAAM,CAAA;AAK3D,IAAA,MAAM,UAAA,GAA4B;AAAA,MAChCJ,qBAAA,CAAA,EAAM,KAAK,CAAA,cAAA,EAAiB,MAAA,CAAO,OAAO,CAAA;AAAA,KAC5C;AACA,IAAA,IAAI,MAAA,CAAO,aAAa,MAAA,EAAW;AACjC,MAAA,UAAA,CAAW,IAAA;AAAA,QACTK,yCAAA,CAAwB,QAAA,EAAU,MAAA,CAAO,MAAA,EAAQ,OAAO,QAAQ;AAAA,OAClE;AAAA,IACF;AAaA,IAAA,IAAI,eAAe,MAAA,EAAW;AAC5B,MAAA,UAAA,CAAW,IAAA,CAAKL,qBAAA,CAAA,EAAM,KAAK,CAAA,eAAA,EAAkB,UAAU,CAAA,CAAA,CAAG,CAAA;AAAA,IAC5D;AAGA,IAAA,MAAM,UAAA,GAAa,OAAO,MAAA,IAAU,CAAA;AACpC,IAAA,MAAM,UAAA,GAAaM,kCAAA,CAAiB,MAAA,CAAO,KAAA,EAAO,OAAO,MAAM,CAAA;AAU/D,IAAA,IAAI,IAAA,CAAK,cAAc,SAAA,EAAW;AAChC,MAAA,MAAM,SAAA,GACJ,MAAA,CAAO,MAAA,KAAW,QAAA,GAAWN,qBAAA,CAAI,IAAI,MAAM,CAAA,GAAIA,qBAAA,CAAI,GAAA,CAAI,KAAK,CAAA;AAC9D,MAAA,MAAM,WAAA,GAAcA,qBAAA;AAAA,eAAA,EACT,KAAK,0BAA0B,KAAK,CAAA;AAAA,aAAA,EACtC,KAAK;AAAA,cAAA,EACJA,qBAAA,CAAI,IAAA,CAAK,UAAA,EAAYA,qBAAA,CAAA,KAAA,CAAU,CAAC;AAAA,iBAAA,EAC7B,QAAQ,CAAA;AAAA,cAAA,EACX,MAAA,CAAO,QAAQ,UAAU;AAAA,MAAA,CAAA;AAEnC,MAAA,OAAOA,qBAAA;AAAA,6CAAA,EACkC,WAAW,CAAA;AAAA;AAAA,uBAAA,EAEjC,SAAS,CAAA;AAAA,QAAA,EACxB,UAAU;AAAA,MAAA,CAAA;AAAA,IAEhB;AACA,IAAA,OAAOA,qBAAA;AAAA,aAAA,EACI,KAAK,0BAA0B,KAAK,CAAA;AAAA,WAAA,EACtC,KAAK;AAAA,YAAA,EACJA,qBAAA,CAAI,IAAA,CAAK,UAAA,EAAYA,qBAAA,CAAA,KAAA,CAAU,CAAC;AAAA,eAAA,EAC7B,QAAQ,CAAA;AAAA,MAAA,EACjB,UAAU;AAAA,IAAA,CAAA;AAAA,EAEhB,CAAA;AAAA,EAEA,kBAAA,CAAmB,eAAA,EAAiB,cAAA,EAAgB,MAAA,EAAQ;AAC1D,IAAA,OAAO,kBAAA,CAAmB,eAAA,EAAiB,cAAA,EAAgB,MAAM,CAAA;AAAA,EACnE,CAAA;AAAA,EAEA,gBAAA,CAAiB,MAAM,OAAA,EAAkC;AACvD,IAAA,IAAI,CAAC,YAAA,CAAa,IAAI,CAAA,EAAG,OAAO,MAAA;AAChC,IAAA,OAAOA,qBAAA,CAAI,GAAA;AAAA,MACT,gBAAA;AAAA,QACE,UAAU,IAAA,CAAK,OAAA,EAAS,IAAA,CAAK,QAAA,EAAU,KAAK,SAAS,CAAA;AAAA,QACrD,IAAA;AAAA,QACA,SAAS,UAAA,KAAe;AAAA;AAC1B,KACF;AAAA,EACF,CAAA;AAAA,EAEA,eAAe,IAAA,EAA+B;AAC5C,IAAA,IAAI,CAAC,YAAA,CAAa,IAAI,CAAA,EAAG,OAAO,MAAA;AAChC,IAAA,MAAM,SAAA,GAAY,kBAAkB,IAAI,CAAA;AACxC,IAAA,OAAOA,sBAAI,GAAA,CAAI,CAAA,qBAAA,EAAwBE,iCAAA,CAAgB,SAAS,CAAC,CAAA,CAAE,CAAA;AAAA,EACrE,CAAA;AAAA,EAEA,iBAAiB,IAAA,EAAyB;AACxC,IAAA,MAAM,KAAA,GAAQA,iCAAA;AAAA,MACZ,UAAU,IAAA,CAAK,OAAA,EAAS,IAAA,CAAK,QAAA,EAAU,KAAK,SAAS;AAAA,KACvD;AAEA,IAAA,OAAO,CAAC,CAAA,qBAAA,EAAwB,KAAK,CAAA,QAAA,CAAU,CAAA;AAAA,EACjD;AACF;AAEA,SAAS,kBAAkB,IAAA,EAA0B;AACnD,EAAA,OAAOD,oCAAA;AAAA,IACL,YAAA;AAAA,IACA,IAAA,CAAK,OAAA;AAAA,IACL,IAAA,CAAK,QAAA;AAAA,IACL,IAAA,CAAK;AAAA,GACP;AACF;AAEA,SAAS,gBAAA,CACP,KAAA,EACA,IAAA,EACA,UAAA,EACQ;AACR,EAAA,MAAM,SAAA,GAAYC,iCAAA,CAAgB,iBAAA,CAAkB,IAAI,CAAC,CAAA;AACzD,EAAA,MAAM,WAAA,GAAcA,kCAAgB,KAAK,CAAA;AACzC,EAAA,MAAM,OAAA,GAAU,aAAA,CAAc,IAAA,CAAK,MAAM,CAAA;AAEzC,EAAA,MAAM,CAAA,GAAI,IAAA,CAAK,WAAA,EAAa,CAAA,IAAK,cAAA;AACjC,EAAA,MAAM,cAAA,GACJ,IAAA,CAAK,WAAA,EAAa,cAAA,IAAkB,4BAAA;AACtC,EAAA,MAAM,KAAA,GAAQ,IAAA,CAAK,WAAA,EAAa,KAAA,IAAS,qBAAA;AAGzC,EAAA,MAAM,MAAA,GAAS,CAAA,YAAA,EAAe,UAAA,GAAa,eAAA,GAAkB,EAAE,CAAA,cAAA,CAAA;AAE/D,EAAA,QAAQ,KAAK,SAAA;AAAW,IACtB,KAAK,MAAA,EAAQ;AACX,MAAA,OAAO,CAAA,EAAG,MAAM,CAAA,CAAA,EAAI,SAAS,CAAA,IAAA,EAAO,WAAW,CAAA,yBAAA,EAA4B,OAAO,CAAA,YAAA,EAAe,CAAC,CAAA,oBAAA,EAAuB,cAAc,CAAA,EAAA,CAAA;AAAA,IACzI;AAAA,IACA,KAAK,SAAA,EAAW;AACd,MAAA,OAAO,CAAA,EAAG,MAAM,CAAA,CAAA,EAAI,SAAS,OAAO,WAAW,CAAA,4BAAA,EAA+B,OAAO,CAAA,gBAAA,EAAmB,KAAK,CAAA,EAAA,CAAA;AAAA,IAC/G;AAAA,IACA,KAAK,MAAA,EAAQ;AACX,MAAA,MAAM,IAAI,KAAA;AAAA,QACR;AAAA,OACF;AAAA,IACF;AAAA,IACA,SAAS;AACP,MAAA,MAAM,cAAqB,IAAA,CAAK,SAAA;AAChC,MAAA,MAAM,IAAI,KAAA,CAAM,CAAA,+BAAA,EAAkC,MAAA,CAAO,WAAW,CAAC,CAAA,CAAE,CAAA;AAAA,IACzE;AAAA;AAEJ","file":"chunk-HSEZ7X6Y.cjs","sourcesContent":["/**\n * pgvector strategy.\n *\n * Postgres' pgvector extension is the one engine where the *same* SQL serves\n * brute-force and ANN: `ORDER BY embedding <=> q LIMIT k` scans sequentially\n * with no index and is rewritten to an HNSW/IVFFlat scan the moment a matching\n * index exists — the planner picks it up automatically. So `buildSearch` never\n * branches on `slot.indexType`; it emits one relevance scan and lets Postgres\n * decide. (Contrast libSQL/sqlite-vec, whose ANN needs distinct syntax.)\n *\n * Storage is per-`(nodeKind, fieldPath)`: a `vector(N)` column carrying the\n * field's fixed dimension `N`, with the operator-class-typed ANN index folded\n * into the same table contribution so materialization builds table + index\n * together. The typed column means the index does not need the legacy\n * `::vector(N)` cast-in-index escape hatch the old shared table relied on.\n *\n * Metric support is the full pgvector set — `cosine`, `l2`, `inner_product` —\n * advertised as data on `capabilities`, mirroring `vector_cosine_ops` /\n * `vector_l2_ops` / `vector_ip_ops` and the `<=>` / `<->` / `<#>` operators.\n *\n * Mirrors the `libsqlVectorStrategy` / `sqliteVecStrategy` structure while\n * letting Postgres' planner pick the ANN index when one exists.\n */\nimport { type StrategyTableContribution } from \"../../../backend/table-contribution\";\nimport {\n type DeleteEmbeddingParams,\n type UpsertEmbeddingBatchParams,\n type UpsertEmbeddingParams,\n type VectorCapabilities,\n type VectorMetric,\n type VectorSearchParams,\n} from \"../../../backend/types\";\nimport { sql, type SqlFragment } from \"../../sql-fragment\";\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\";\nimport { vectorPageClause } from \"./pagination\";\n\n/** Physical-name prefixes for the per-field table and its ANN index. */\nconst TABLE_PREFIX = \"tg_vec\";\nconst INDEX_PREFIX = \"tg_vecidx\";\n\n/**\n * pgvector defines `hnsw.ef_search` as an integer GUC with a valid range\n * of 1..1000; `SET hnsw.ef_search = 1001` errors at the server. The\n * backend validates a per-search `efSearch` against this ceiling before\n * inlining it into `SET LOCAL`, surfacing a clear message instead of a raw\n * pgvector error.\n */\nexport const MAX_HNSW_EF_SEARCH = 1000;\n\n/**\n * Validates a per-search `efSearch` override against pgvector's\n * `hnsw.ef_search` valid range. `undefined` (no override) is accepted.\n */\nexport function assertPgvectorEfSearch(efSearch?: number): void {\n if (efSearch === undefined) return;\n if (!Number.isInteger(efSearch) || efSearch <= 0) {\n throw new Error(`efSearch must be a positive integer, got: ${efSearch}`);\n }\n if (efSearch > MAX_HNSW_EF_SEARCH) {\n throw new RangeError(\n `efSearch must be ≤ ${MAX_HNSW_EF_SEARCH} (pgvector's hnsw.ef_search ` +\n `valid range is 1..${MAX_HNSW_EF_SEARCH}), got: ${efSearch}`,\n );\n }\n}\n\n/**\n * pgvector's `vector` type caps at 16,000 dimensions for a stored column\n * (2,000 for an indexed column, but the column-type ceiling is what governs\n * storage; recall degradation beyond 2,000 is a tuning concern, not a hard\n * limit advertised here).\n */\nconst PGVECTOR_MAX_DIMENSIONS = 16_000;\n\n/** Default HNSW `m` (max connections per layer) — pgvector's own default. */\nconst DEFAULT_HNSW_M = 16;\n/** Default HNSW `ef_construction` (build candidate list) — pgvector's own default. */\nconst DEFAULT_HNSW_EF_CONSTRUCTION = 64;\n/** Default IVFFlat `lists` (inverted lists) — pgvector's own default. */\nconst DEFAULT_IVFFLAT_LISTS = 100;\n\nconst PGVECTOR_CAPABILITIES: VectorCapabilities = {\n supported: true,\n metrics: [\"cosine\", \"l2\", \"inner_product\"],\n indexTypes: [\"hnsw\", \"ivfflat\", \"none\"],\n maxDimensions: PGVECTOR_MAX_DIMENSIONS,\n // The backend probes `pg_extension.extversion` once and turns on\n // `hnsw.iterative_scan` / `ivfflat.iterative_scan` when pgvector >= 0.8, so a\n // filtered scan re-enters the index for more candidates.\n //\n // NOT a full-page guarantee, on either axis. The iterative scan stops at\n // `hnsw.max_scan_tuples` / `ivfflat.max_probes`; and on pgvector < 0.8 there\n // is no iterative scan at all, so the search stays `ef_search`-bounded and\n // behaves like a post-filter. A statically-declared mode cannot express\n // either, which is why the guarantee is its own field.\n filteredApproximateSearch: {\n mode: \"iterative-scan\",\n guaranteesFullPage: false,\n },\n // The one bundled engine with a real per-search frontier: `hnsw.ef_search`\n // sizes the HNSW candidate list. IVFFlat has no equivalent (`ivfflat.probes`\n // is a different structure's knob and is not what `efSearch` means), and the\n // GUC is applied with `SET LOCAL` inside the search's own transaction so\n // concurrent searches cannot inherit each other's override.\n searchFrontierTuning: {\n tunable: true,\n parameter: \"hnsw.ef_search\",\n indexType: \"hnsw\",\n requiresTransactionScope: true,\n },\n};\n\n/** Whether a slot's declared index type materializes a real pgvector ANN index. */\nfunction usesAnnIndex(slot: VectorSlot): boolean {\n return slot.indexType === \"hnsw\" || slot.indexType === \"ivfflat\";\n}\n\n/**\n * pgvector operator class for a metric's ANN index — `vector_cosine_ops` /\n * `vector_l2_ops` / `vector_ip_ops`, mirroring the `<=>` / `<->` / `<#>`\n * distance operators this strategy emits.\n */\nfunction operatorClass(metric: VectorMetric): string {\n switch (metric) {\n case \"cosine\": {\n return \"vector_cosine_ops\";\n }\n case \"l2\": {\n return \"vector_l2_ops\";\n }\n case \"inner_product\": {\n return \"vector_ip_ops\";\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 a `::vector` literal. The value is bound as a\n * parameter (not interpolated) — Postgres parses the `[a,b,c]` text and the\n * cast types it. Finiteness is validated first so a NaN names its index.\n */\nfunction vectorLiteral(\n embedding: readonly number[],\n name: string,\n): SqlFragment {\n assertFiniteEmbedding(embedding, name);\n return sql`${`[${embedding.join(\",\")}]`}::vector`;\n}\n\nfunction distanceExpression(\n embeddingColumn: SqlFragment,\n queryEmbedding: readonly number[],\n metric: VectorMetric,\n): SqlFragment {\n const query = vectorLiteral(queryEmbedding, \"queryEmbedding\");\n switch (metric) {\n case \"cosine\": {\n return sql`(${embeddingColumn} <=> ${query})`;\n }\n case \"l2\": {\n return sql`(${embeddingColumn} <-> ${query})`;\n }\n case \"inner_product\": {\n return sql`(${embeddingColumn} <#> ${query})`;\n }\n default: {\n const _exhaustive: never = metric;\n throw new Error(`Unsupported vector metric: ${String(_exhaustive)}`);\n }\n }\n}\n\nfunction tableName(\n graphId: string,\n nodeKind: string,\n fieldPath: string,\n): string {\n return vectorPhysicalName(TABLE_PREFIX, graphId, nodeKind, fieldPath);\n}\n\nexport const pgvectorStrategy: VectorStrategy = {\n name: \"pgvector\",\n capabilities: PGVECTOR_CAPABILITIES,\n\n tableName,\n\n ownedTables(slot): readonly StrategyTableContribution[] {\n const table = tableName(slot.graphId, slot.nodeKind, slot.fieldPath);\n const name = quoteIdentifier(table);\n\n // No standalone graph_id index: the PRIMARY KEY (graph_id, node_id) already\n // covers `WHERE graph_id = ?` via its leading column, so a separate index\n // would be pure write amplification.\n const createDdl = [\n `CREATE TABLE IF NOT EXISTS ${name} (\n \"graph_id\" TEXT NOT NULL,\n \"node_id\" TEXT NOT NULL,\n \"embedding\" vector(${slot.dimensions}) NOT NULL,\n \"created_at\" TIMESTAMPTZ NOT NULL,\n \"updated_at\" TIMESTAMPTZ NOT NULL,\n PRIMARY KEY (\"graph_id\", \"node_id\")\n);`,\n ];\n\n // The HNSW/IVFFlat index is intentionally NOT created here. pgvector\n // similarity SQL is planner-driven (`ORDER BY embedding <=> q LIMIT k`\n // uses the index when present, sequential-scans when not), so the index\n // is a pure materialization concern: `buildCreateIndex` builds it through\n // `materializeIndexes()` with the field's declared `m`/`ef_construction`/\n // `lists`. Building it eagerly here would bake in default tuning (the\n // write-ensure slot has no `indexParams`) and `CREATE INDEX IF NOT EXISTS`\n // would then mask the tuned index materialization would emit.\n\n return [\n {\n logicalName: `${VECTOR_CONTRIBUTION_PREFIX}:${slot.nodeKind}.${slot.fieldPath}`,\n owner: \"pgvector\",\n tableName: table,\n createDdl,\n runtimeEnsure: true,\n },\n ];\n },\n\n buildUpsert(\n slot,\n params: UpsertEmbeddingParams,\n timestamp,\n ): readonly SqlFragment[] {\n const table = sql.identifier(\n tableName(slot.graphId, slot.nodeKind, slot.fieldPath),\n );\n const value = vectorLiteral(params.embedding, \"embedding\");\n return [\n sql`\n INSERT INTO ${table} (\"graph_id\", \"node_id\", \"embedding\", \"created_at\", \"updated_at\")\n VALUES (${params.graphId}, ${params.nodeId}, ${value}, ${timestamp}, ${timestamp})\n ON CONFLICT (\"graph_id\", \"node_id\")\n DO UPDATE SET \"embedding\" = EXCLUDED.\"embedding\", \"updated_at\" = EXCLUDED.\"updated_at\"\n `,\n ];\n },\n\n buildUpsertBatch(\n slot,\n params: UpsertEmbeddingBatchParams,\n timestamp,\n ): readonly SqlFragment[] {\n const table = sql.identifier(\n tableName(slot.graphId, slot.nodeKind, slot.fieldPath),\n );\n const valueRows = sql.join(\n params.rows.map(\n (row) =>\n sql`(${params.graphId}, ${row.nodeId}, ${vectorLiteral(row.embedding, \"embedding\")}, ${timestamp}, ${timestamp})`,\n ),\n sql`, `,\n );\n return [\n sql`\n INSERT INTO ${table} (\"graph_id\", \"node_id\", \"embedding\", \"created_at\", \"updated_at\")\n VALUES ${valueRows}\n ON CONFLICT (\"graph_id\", \"node_id\")\n DO UPDATE SET \"embedding\" = EXCLUDED.\"embedding\", \"updated_at\" = EXCLUDED.\"updated_at\"\n `,\n ];\n },\n\n buildDelete(slot, params: DeleteEmbeddingParams): readonly SqlFragment[] {\n const table = sql.identifier(\n tableName(slot.graphId, slot.nodeKind, slot.fieldPath),\n );\n return [\n sql`\n DELETE FROM ${table}\n WHERE \"graph_id\" = ${params.graphId} AND \"node_id\" = ${params.nodeId}\n `,\n ];\n },\n\n buildDeleteBatch(\n slot,\n params: Omit<DeleteEmbeddingParams, \"nodeId\"> &\n Readonly<{ nodeIds: readonly string[] }>,\n ): readonly SqlFragment[] {\n if (params.nodeIds.length === 0) return [];\n const table = sql.identifier(\n tableName(slot.graphId, slot.nodeKind, slot.fieldPath),\n );\n return [\n sql`DELETE FROM ${table} WHERE \"graph_id\" = ${params.graphId} AND \"node_id\" IN (${sql.join(\n params.nodeIds.map((nodeId) => sql`${nodeId}`),\n sql`, `,\n )})`,\n ];\n },\n\n buildSearch(\n slot,\n params: VectorSearchParams,\n candidates?: SqlFragment,\n ): SqlFragment {\n const table = sql.identifier(\n 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 // Same SQL for brute-force and ANN: with a matching HNSW/IVFFlat index the\n // Postgres planner rewrites this `ORDER BY distance LIMIT k` into an index\n // scan automatically, so the strategy never branches on `slot.indexType`.\n const conditions: SqlFragment[] = [\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 // Candidate pushdown keeps the HNSW scan (verified plan: HNSW Index Scan\n // -> Nested Loop probe of the nodes pkey -> Limit). Exact under\n // `hnsw.iterative_scan` (pgvector >= 0.8, applied by the backend);\n // bounded by `ef_search` on older pgvector — still strictly better than\n // ranking tombstones into top-k and dropping them post-hoc.\n //\n // Plain `IN (subquery)`: with fresh statistics the planner hashes it\n // (brute-force scans) or drives per-row probes of the nodes pkey\n // under the ordered HNSW scan — the plan-verified shape the liveness\n // pushdown was built on. Stale statistics degrade any membership\n // form; the answer is `store.refreshStatistics()` after bulk loads,\n // not a cleverer SQL shape.\n if (candidates !== undefined) {\n conditions.push(sql`${table}.\"node_id\" IN (${candidates})`);\n }\n // Pagination is rank-relative: the scan fetches `limit + offset`\n // ordered candidates and OFFSET discards the leading page.\n const pageOffset = params.offset ?? 0;\n const pageClause = vectorPageClause(params.limit, params.offset);\n // IVFFlat's iterative scan only offers `relaxed_order` (no\n // strict_order mode), so under the backend-applied\n // `ivfflat.iterative_scan` the index may emit the candidate set\n // slightly out of distance order. Re-sort the bounded set inside a\n // MATERIALIZED wrapper — the fence stops the planner from collapsing\n // the sort back into the index scan's claimed ordering — and page in\n // the wrapper: an OFFSET inside the relaxed scan could discard the\n // wrong rows. Score is monotone in distance, so ordering by score per\n // the metric's direction restores exact ranking.\n if (slot.indexType === \"ivfflat\") {\n const direction =\n params.metric === \"cosine\" ? sql.raw(\"DESC\") : sql.raw(\"ASC\");\n const relaxedBody = 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 + pageOffset}\n `;\n return sql`\n WITH tg_vec_relaxed AS MATERIALIZED (${relaxedBody})\n SELECT node_id, score FROM tg_vec_relaxed\n ORDER BY score ${direction}, node_id ASC\n ${pageClause}\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 ${pageClause}\n `;\n },\n\n distanceExpression(embeddingColumn, queryEmbedding, metric) {\n return distanceExpression(embeddingColumn, queryEmbedding, metric);\n },\n\n buildCreateIndex(slot, options): SqlFragment | undefined {\n if (!usesAnnIndex(slot)) return undefined;\n return sql.raw(\n pgvectorIndexDdl(\n tableName(slot.graphId, slot.nodeKind, slot.fieldPath),\n slot,\n options?.concurrent === true,\n ),\n );\n },\n\n buildDropIndex(slot): SqlFragment | undefined {\n if (!usesAnnIndex(slot)) return undefined;\n const indexName = pgvectorIndexName(slot);\n return sql.raw(`DROP INDEX IF EXISTS ${quoteIdentifier(indexName)}`);\n },\n\n buildDropStorage(slot): readonly string[] {\n const table = quoteIdentifier(\n tableName(slot.graphId, slot.nodeKind, slot.fieldPath),\n );\n // CASCADE drops the ANN index along with the table.\n return [`DROP TABLE IF EXISTS ${table} CASCADE`];\n },\n};\n\nfunction pgvectorIndexName(slot: VectorSlot): string {\n return vectorPhysicalName(\n INDEX_PREFIX,\n slot.graphId,\n slot.nodeKind,\n slot.fieldPath,\n );\n}\n\nfunction pgvectorIndexDdl(\n table: string,\n slot: VectorSlot,\n concurrent: boolean,\n): string {\n const indexName = quoteIdentifier(pgvectorIndexName(slot));\n const quotedTable = quoteIdentifier(table);\n const opClass = operatorClass(slot.metric);\n // Honor the field's declared tuning; fall back to pgvector defaults.\n const m = slot.indexParams?.m ?? DEFAULT_HNSW_M;\n const efConstruction =\n slot.indexParams?.efConstruction ?? DEFAULT_HNSW_EF_CONSTRUCTION;\n const lists = slot.indexParams?.lists ?? DEFAULT_IVFFLAT_LISTS;\n // CONCURRENTLY builds without taking a write-blocking lock on the live table\n // (materializeIndexes passes concurrent on Postgres). Run outside a tx.\n const create = `CREATE INDEX${concurrent ? \" CONCURRENTLY\" : \"\"} IF NOT EXISTS`;\n\n switch (slot.indexType) {\n case \"hnsw\": {\n return `${create} ${indexName} ON ${quotedTable} USING hnsw (\"embedding\" ${opClass}) WITH (m = ${m}, ef_construction = ${efConstruction});`;\n }\n case \"ivfflat\": {\n return `${create} ${indexName} ON ${quotedTable} USING ivfflat (\"embedding\" ${opClass}) WITH (lists = ${lists});`;\n }\n case \"none\": {\n throw new Error(\n \"pgvectorIndexDdl called for a brute-force-only slot (indexType 'none').\",\n );\n }\n default: {\n const _exhaustive: never = slot.indexType;\n throw new Error(`Unsupported vector index type: ${String(_exhaustive)}`);\n }\n }\n}\n"]}
1
+ {"version":3,"sources":["../src/query/dialect/vector/pgvector-strategy.ts"],"names":["assertFiniteEmbedding","sql","vectorPhysicalName","quoteIdentifier","VECTOR_CONTRIBUTION_PREFIX","vectorScoreExpression","vectorMinScoreCondition","vectorPageClause"],"mappings":"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","file":"chunk-TIJUA4I6.cjs","sourcesContent":["/**\n * pgvector strategy.\n *\n * Postgres' pgvector extension is the one engine where the *same* SQL serves\n * brute-force and ANN: `ORDER BY embedding <=> q LIMIT k` scans sequentially\n * with no index and is rewritten to an HNSW/IVFFlat scan the moment a matching\n * index exists — the planner picks it up automatically. So `buildSearch` never\n * branches on `slot.indexType`; it emits one relevance scan and lets Postgres\n * decide. (Contrast libSQL/sqlite-vec, whose ANN needs distinct syntax.)\n *\n * Storage is per-`(nodeKind, fieldPath)`: a `vector(N)` column carrying the\n * field's fixed dimension `N`, with the operator-class-typed ANN index folded\n * into the same table contribution so materialization builds table + index\n * together. The typed column means the index does not need the legacy\n * `::vector(N)` cast-in-index escape hatch the old shared table relied on.\n *\n * Metric support is the full pgvector set — `cosine`, `l2`, `inner_product` —\n * advertised as data on `capabilities`, mirroring `vector_cosine_ops` /\n * `vector_l2_ops` / `vector_ip_ops` and the `<=>` / `<->` / `<#>` operators.\n *\n * Mirrors the `libsqlVectorStrategy` / `sqliteVecStrategy` structure while\n * letting Postgres' planner pick the ANN index when one exists.\n */\nimport { type StrategyTableContribution } from \"../../../backend/table-contribution\";\nimport {\n type DeleteEmbeddingParams,\n type UpsertEmbeddingBatchParams,\n type UpsertEmbeddingParams,\n type VectorCapabilities,\n type VectorMetric,\n type VectorSearchParams,\n} from \"../../../backend/types\";\nimport { sql, type SqlFragment } from \"../../sql-fragment\";\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\";\nimport { vectorPageClause } from \"./pagination\";\n\n/** Physical-name prefixes for the per-field table and its ANN index. */\nconst TABLE_PREFIX = \"tg_vec\";\nconst INDEX_PREFIX = \"tg_vecidx\";\n\n/**\n * pgvector defines `hnsw.ef_search` as an integer GUC with a valid range\n * of 1..1000; `SET hnsw.ef_search = 1001` errors at the server. The\n * backend validates a per-search `efSearch` against this ceiling before\n * inlining it into `SET LOCAL`, surfacing a clear message instead of a raw\n * pgvector error.\n */\nexport const MAX_HNSW_EF_SEARCH = 1000;\n\n/**\n * Validates a per-search `efSearch` override against pgvector's\n * `hnsw.ef_search` valid range. `undefined` (no override) is accepted.\n */\nexport function assertPgvectorEfSearch(efSearch?: number): void {\n if (efSearch === undefined) return;\n if (!Number.isInteger(efSearch) || efSearch <= 0) {\n throw new Error(`efSearch must be a positive integer, got: ${efSearch}`);\n }\n if (efSearch > MAX_HNSW_EF_SEARCH) {\n throw new RangeError(\n `efSearch must be ≤ ${MAX_HNSW_EF_SEARCH} (pgvector's hnsw.ef_search ` +\n `valid range is 1..${MAX_HNSW_EF_SEARCH}), got: ${efSearch}`,\n );\n }\n}\n\n/**\n * pgvector's `vector` type caps at 16,000 dimensions for a stored column\n * (2,000 for an indexed column, but the column-type ceiling is what governs\n * storage; recall degradation beyond 2,000 is a tuning concern, not a hard\n * limit advertised here).\n */\nconst PGVECTOR_MAX_DIMENSIONS = 16_000;\n\n/** Default HNSW `m` (max connections per layer) — pgvector's own default. */\nconst DEFAULT_HNSW_M = 16;\n/** Default HNSW `ef_construction` (build candidate list) — pgvector's own default. */\nconst DEFAULT_HNSW_EF_CONSTRUCTION = 64;\n/** Default IVFFlat `lists` (inverted lists) — pgvector's own default. */\nconst DEFAULT_IVFFLAT_LISTS = 100;\n\nconst PGVECTOR_CAPABILITIES: VectorCapabilities = {\n supported: true,\n metrics: [\"cosine\", \"l2\", \"inner_product\"],\n indexTypes: [\"hnsw\", \"ivfflat\", \"none\"],\n maxDimensions: PGVECTOR_MAX_DIMENSIONS,\n // The backend probes `pg_extension.extversion` once and turns on\n // `hnsw.iterative_scan` / `ivfflat.iterative_scan` when pgvector >= 0.8, so a\n // filtered scan re-enters the index for more candidates.\n //\n // NOT a full-page guarantee, on either axis. The iterative scan stops at\n // `hnsw.max_scan_tuples` / `ivfflat.max_probes`; and on pgvector < 0.8 there\n // is no iterative scan at all, so the search stays `ef_search`-bounded and\n // behaves like a post-filter. A statically-declared mode cannot express\n // either, which is why the guarantee is its own field.\n filteredApproximateSearch: {\n mode: \"iterative-scan\",\n guaranteesFullPage: false,\n },\n // The one bundled engine with a real per-search frontier: `hnsw.ef_search`\n // sizes the HNSW candidate list. IVFFlat has no equivalent (`ivfflat.probes`\n // is a different structure's knob and is not what `efSearch` means), and the\n // GUC is applied with `SET LOCAL` inside the search's own transaction so\n // concurrent searches cannot inherit each other's override.\n searchFrontierTuning: {\n tunable: true,\n parameter: \"hnsw.ef_search\",\n indexType: \"hnsw\",\n requiresTransactionScope: true,\n },\n};\n\n/** Whether a slot's declared index type materializes a real pgvector ANN index. */\nfunction usesAnnIndex(slot: VectorSlot): boolean {\n return slot.indexType === \"hnsw\" || slot.indexType === \"ivfflat\";\n}\n\n/**\n * pgvector operator class for a metric's ANN index — `vector_cosine_ops` /\n * `vector_l2_ops` / `vector_ip_ops`, mirroring the `<=>` / `<->` / `<#>`\n * distance operators this strategy emits.\n */\nfunction operatorClass(metric: VectorMetric): string {\n switch (metric) {\n case \"cosine\": {\n return \"vector_cosine_ops\";\n }\n case \"l2\": {\n return \"vector_l2_ops\";\n }\n case \"inner_product\": {\n return \"vector_ip_ops\";\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 a `::vector` literal. The value is bound as a\n * parameter (not interpolated) — Postgres parses the `[a,b,c]` text and the\n * cast types it. Finiteness is validated first so a NaN names its index.\n */\nfunction vectorLiteral(\n embedding: readonly number[],\n name: string,\n): SqlFragment {\n assertFiniteEmbedding(embedding, name);\n return sql`${`[${embedding.join(\",\")}]`}::vector`;\n}\n\nfunction distanceExpression(\n embeddingColumn: SqlFragment,\n queryEmbedding: readonly number[],\n metric: VectorMetric,\n): SqlFragment {\n const query = vectorLiteral(queryEmbedding, \"queryEmbedding\");\n switch (metric) {\n case \"cosine\": {\n return sql`(${embeddingColumn} <=> ${query})`;\n }\n case \"l2\": {\n return sql`(${embeddingColumn} <-> ${query})`;\n }\n case \"inner_product\": {\n return sql`(${embeddingColumn} <#> ${query})`;\n }\n default: {\n const _exhaustive: never = metric;\n throw new Error(`Unsupported vector metric: ${String(_exhaustive)}`);\n }\n }\n}\n\nfunction tableName(\n graphId: string,\n nodeKind: string,\n fieldPath: string,\n): string {\n return vectorPhysicalName(TABLE_PREFIX, graphId, nodeKind, fieldPath);\n}\n\nexport const pgvectorStrategy: VectorStrategy = {\n name: \"pgvector\",\n capabilities: PGVECTOR_CAPABILITIES,\n\n tableName,\n\n ownedTables(slot): readonly StrategyTableContribution[] {\n const table = tableName(slot.graphId, slot.nodeKind, slot.fieldPath);\n const name = quoteIdentifier(table);\n\n // No standalone graph_id index: the PRIMARY KEY (graph_id, node_id) already\n // covers `WHERE graph_id = ?` via its leading column, so a separate index\n // would be pure write amplification.\n const createDdl = [\n `CREATE TABLE IF NOT EXISTS ${name} (\n \"graph_id\" TEXT NOT NULL,\n \"node_id\" TEXT NOT NULL,\n \"embedding\" vector(${slot.dimensions}) NOT NULL,\n \"created_at\" TIMESTAMPTZ NOT NULL,\n \"updated_at\" TIMESTAMPTZ NOT NULL,\n PRIMARY KEY (\"graph_id\", \"node_id\")\n);`,\n ];\n\n // The HNSW/IVFFlat index is intentionally NOT created here. pgvector\n // similarity SQL is planner-driven (`ORDER BY embedding <=> q LIMIT k`\n // uses the index when present, sequential-scans when not), so the index\n // is a pure materialization concern: `buildCreateIndex` builds it through\n // `materializeIndexes()` with the field's declared `m`/`ef_construction`/\n // `lists`. Building it eagerly here would bake in default tuning (the\n // write-ensure slot has no `indexParams`) and `CREATE INDEX IF NOT EXISTS`\n // would then mask the tuned index materialization would emit.\n\n return [\n {\n logicalName: `${VECTOR_CONTRIBUTION_PREFIX}:${slot.nodeKind}.${slot.fieldPath}`,\n owner: \"pgvector\",\n tableName: table,\n createDdl,\n runtimeEnsure: true,\n },\n ];\n },\n\n buildUpsert(\n slot,\n params: UpsertEmbeddingParams,\n timestamp,\n ): readonly SqlFragment[] {\n const table = sql.identifier(\n tableName(slot.graphId, slot.nodeKind, slot.fieldPath),\n );\n const value = vectorLiteral(params.embedding, \"embedding\");\n return [\n sql`\n INSERT INTO ${table} (\"graph_id\", \"node_id\", \"embedding\", \"created_at\", \"updated_at\")\n VALUES (${params.graphId}, ${params.nodeId}, ${value}, ${timestamp}, ${timestamp})\n ON CONFLICT (\"graph_id\", \"node_id\")\n DO UPDATE SET \"embedding\" = EXCLUDED.\"embedding\", \"updated_at\" = EXCLUDED.\"updated_at\"\n `,\n ];\n },\n\n buildUpsertBatch(\n slot,\n params: UpsertEmbeddingBatchParams,\n timestamp,\n ): readonly SqlFragment[] {\n const table = sql.identifier(\n tableName(slot.graphId, slot.nodeKind, slot.fieldPath),\n );\n const valueRows = sql.join(\n params.rows.map(\n (row) =>\n sql`(${params.graphId}, ${row.nodeId}, ${vectorLiteral(row.embedding, \"embedding\")}, ${timestamp}, ${timestamp})`,\n ),\n sql`, `,\n );\n return [\n sql`\n INSERT INTO ${table} (\"graph_id\", \"node_id\", \"embedding\", \"created_at\", \"updated_at\")\n VALUES ${valueRows}\n ON CONFLICT (\"graph_id\", \"node_id\")\n DO UPDATE SET \"embedding\" = EXCLUDED.\"embedding\", \"updated_at\" = EXCLUDED.\"updated_at\"\n `,\n ];\n },\n\n buildDelete(slot, params: DeleteEmbeddingParams): readonly SqlFragment[] {\n const table = sql.identifier(\n tableName(slot.graphId, slot.nodeKind, slot.fieldPath),\n );\n return [\n sql`\n DELETE FROM ${table}\n WHERE \"graph_id\" = ${params.graphId} AND \"node_id\" = ${params.nodeId}\n `,\n ];\n },\n\n buildDeleteBatch(\n slot,\n params: Omit<DeleteEmbeddingParams, \"nodeId\"> &\n Readonly<{ nodeIds: readonly string[] }>,\n ): readonly SqlFragment[] {\n if (params.nodeIds.length === 0) return [];\n const table = sql.identifier(\n tableName(slot.graphId, slot.nodeKind, slot.fieldPath),\n );\n return [\n sql`DELETE FROM ${table} WHERE \"graph_id\" = ${params.graphId} AND \"node_id\" IN (${sql.join(\n params.nodeIds.map((nodeId) => sql`${nodeId}`),\n sql`, `,\n )})`,\n ];\n },\n\n buildSearch(\n slot,\n params: VectorSearchParams,\n candidates?: SqlFragment,\n ): SqlFragment {\n const table = sql.identifier(\n 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 // Same SQL for brute-force and ANN: with a matching HNSW/IVFFlat index the\n // Postgres planner rewrites this `ORDER BY distance LIMIT k` into an index\n // scan automatically, so the strategy never branches on `slot.indexType`.\n const conditions: SqlFragment[] = [\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 // Candidate pushdown keeps the HNSW scan (verified plan: HNSW Index Scan\n // -> Nested Loop probe of the nodes pkey -> Limit). Exact under\n // `hnsw.iterative_scan` (pgvector >= 0.8, applied by the backend);\n // bounded by `ef_search` on older pgvector — still strictly better than\n // ranking tombstones into top-k and dropping them post-hoc.\n //\n // Plain `IN (subquery)`: with fresh statistics the planner hashes it\n // (brute-force scans) or drives per-row probes of the nodes pkey\n // under the ordered HNSW scan — the plan-verified shape the liveness\n // pushdown was built on. Stale statistics degrade any membership\n // form; the answer is `store.refreshStatistics()` after bulk loads,\n // not a cleverer SQL shape.\n if (candidates !== undefined) {\n conditions.push(sql`${table}.\"node_id\" IN (${candidates})`);\n }\n // Pagination is rank-relative: the scan fetches `limit + offset`\n // ordered candidates and OFFSET discards the leading page.\n const pageOffset = params.offset ?? 0;\n const pageClause = vectorPageClause(params.limit, params.offset);\n // IVFFlat's iterative scan only offers `relaxed_order` (no\n // strict_order mode), so under the backend-applied\n // `ivfflat.iterative_scan` the index may emit the candidate set\n // slightly out of distance order. Re-sort the bounded set inside a\n // MATERIALIZED wrapper — the fence stops the planner from collapsing\n // the sort back into the index scan's claimed ordering — and page in\n // the wrapper: an OFFSET inside the relaxed scan could discard the\n // wrong rows. Score is monotone in distance, so ordering by score per\n // the metric's direction restores exact ranking.\n if (slot.indexType === \"ivfflat\") {\n const direction =\n params.metric === \"cosine\" ? sql.raw(\"DESC\") : sql.raw(\"ASC\");\n const relaxedBody = 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 + pageOffset}\n `;\n return sql`\n WITH tg_vec_relaxed AS MATERIALIZED (${relaxedBody})\n SELECT node_id, score FROM tg_vec_relaxed\n ORDER BY score ${direction}, node_id ASC\n ${pageClause}\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 ${pageClause}\n `;\n },\n\n distanceExpression(embeddingColumn, queryEmbedding, metric) {\n return distanceExpression(embeddingColumn, queryEmbedding, metric);\n },\n\n buildCreateIndex(slot, options): SqlFragment | undefined {\n if (!usesAnnIndex(slot)) return undefined;\n return sql.raw(\n pgvectorIndexDdl(\n tableName(slot.graphId, slot.nodeKind, slot.fieldPath),\n slot,\n options?.concurrent === true,\n ),\n );\n },\n\n buildDropIndex(slot): SqlFragment | undefined {\n if (!usesAnnIndex(slot)) return undefined;\n const indexName = pgvectorIndexName(slot);\n return sql.raw(`DROP INDEX IF EXISTS ${quoteIdentifier(indexName)}`);\n },\n\n buildDropStorage(slot): readonly string[] {\n const table = quoteIdentifier(\n tableName(slot.graphId, slot.nodeKind, slot.fieldPath),\n );\n // CASCADE drops the ANN index along with the table.\n return [`DROP TABLE IF EXISTS ${table} CASCADE`];\n },\n};\n\nfunction pgvectorIndexName(slot: VectorSlot): string {\n return vectorPhysicalName(\n INDEX_PREFIX,\n slot.graphId,\n slot.nodeKind,\n slot.fieldPath,\n );\n}\n\nfunction pgvectorIndexDdl(\n table: string,\n slot: VectorSlot,\n concurrent: boolean,\n): string {\n const indexName = quoteIdentifier(pgvectorIndexName(slot));\n const quotedTable = quoteIdentifier(table);\n const opClass = operatorClass(slot.metric);\n // Honor the field's declared tuning; fall back to pgvector defaults.\n const m = slot.indexParams?.m ?? DEFAULT_HNSW_M;\n const efConstruction =\n slot.indexParams?.efConstruction ?? DEFAULT_HNSW_EF_CONSTRUCTION;\n const lists = slot.indexParams?.lists ?? DEFAULT_IVFFLAT_LISTS;\n // CONCURRENTLY builds without taking a write-blocking lock on the live table\n // (materializeIndexes passes concurrent on Postgres). Run outside a tx.\n const create = `CREATE INDEX${concurrent ? \" CONCURRENTLY\" : \"\"} IF NOT EXISTS`;\n\n switch (slot.indexType) {\n case \"hnsw\": {\n return `${create} ${indexName} ON ${quotedTable} USING hnsw (\"embedding\" ${opClass}) WITH (m = ${m}, ef_construction = ${efConstruction});`;\n }\n case \"ivfflat\": {\n return `${create} ${indexName} ON ${quotedTable} USING ivfflat (\"embedding\" ${opClass}) WITH (lists = ${lists});`;\n }\n case \"none\": {\n throw new Error(\n \"pgvectorIndexDdl called for a brute-force-only slot (indexType 'none').\",\n );\n }\n default: {\n const _exhaustive: never = slot.indexType;\n throw new Error(`Unsupported vector index type: ${String(_exhaustive)}`);\n }\n }\n}\n"]}
@@ -1,7 +1,7 @@
1
1
  'use strict';
2
2
 
3
- var chunkTEC24ZDA_cjs = require('./chunk-TEC24ZDA.cjs');
4
- var chunkOJHD3LXJ_cjs = require('./chunk-OJHD3LXJ.cjs');
3
+ var chunkJVA3KDEA_cjs = require('./chunk-JVA3KDEA.cjs');
4
+ var chunkH5IJSROF_cjs = require('./chunk-H5IJSROF.cjs');
5
5
  var chunkN66HCGCY_cjs = require('./chunk-N66HCGCY.cjs');
6
6
 
7
7
  // src/indexes/ddl.ts
@@ -28,11 +28,11 @@ function generateTableIndexDDL(index, dialect, tableName, options) {
28
28
  return generateGinFamilyIndexDDL(index, dialect, tableName, options);
29
29
  }
30
30
  const ifNotExists = options.ifNotExists ?? true;
31
- const propsColumn = chunkOJHD3LXJ_cjs.sql.identifier("props");
32
- const systemColumn = (column) => chunkOJHD3LXJ_cjs.sql.identifier(column);
33
- const keys = index.entity === "node" ? chunkTEC24ZDA_cjs.compileNodeIndexKeys(index, dialect, propsColumn, systemColumn).keys : chunkTEC24ZDA_cjs.compileEdgeIndexKeys(index, dialect, propsColumn, systemColumn).keys;
34
- const whereSql = index.where ? chunkOJHD3LXJ_cjs.renderSqlInline(
35
- chunkTEC24ZDA_cjs.compileIndexWhere(
31
+ const propsColumn = chunkH5IJSROF_cjs.sql.identifier("props");
32
+ const systemColumn = (column) => chunkH5IJSROF_cjs.sql.identifier(column);
33
+ const keys = index.entity === "node" ? chunkJVA3KDEA_cjs.compileNodeIndexKeys(index, dialect, propsColumn, systemColumn).keys : chunkJVA3KDEA_cjs.compileEdgeIndexKeys(index, dialect, propsColumn, systemColumn).keys;
34
+ const whereSql = index.where ? chunkH5IJSROF_cjs.renderSqlInline(
35
+ chunkJVA3KDEA_cjs.compileIndexWhere(
36
36
  {
37
37
  dialect,
38
38
  propsColumn,
@@ -42,7 +42,7 @@ function generateTableIndexDDL(index, dialect, tableName, options) {
42
42
  ),
43
43
  dialect
44
44
  ) : void 0;
45
- const keySql = keys.map((key) => chunkOJHD3LXJ_cjs.renderSqlInline(key, dialect)).join(", ");
45
+ const keySql = keys.map((key) => chunkH5IJSROF_cjs.renderSqlInline(key, dialect)).join(", ");
46
46
  const unique = index.unique ? "UNIQUE " : "";
47
47
  const concurrent = options.concurrent === true && INDEX_DDL_BEHAVIOR[dialect].concurrentBuilds ? "CONCURRENTLY " : "";
48
48
  const ifNotExistsSql = ifNotExists ? "IF NOT EXISTS " : "";
@@ -55,14 +55,14 @@ function generateGinFamilyIndexDDL(index, dialect, tableName, options) {
55
55
  `Index "${index.name}" declares method "${index.method}", which requires PostgreSQL. materializeIndexes() reports such declarations as skipped on SQLite instead of calling this.`
56
56
  );
57
57
  }
58
- const adapter = chunkTEC24ZDA_cjs.getDialect(dialect);
59
- const propsColumn = chunkOJHD3LXJ_cjs.sql.identifier("props");
58
+ const adapter = chunkJVA3KDEA_cjs.getDialect(dialect);
59
+ const propsColumn = chunkH5IJSROF_cjs.sql.identifier("props");
60
60
  const pointer = chunkN66HCGCY_cjs.requireDefined(index.fields[0]);
61
61
  const expression = index.method === "gin" ? adapter.jsonExtract(propsColumn, pointer) : adapter.jsonExtractText(propsColumn, pointer);
62
62
  const operatorClass = index.method === "gin" ? "jsonb_path_ops" : "gin_trgm_ops";
63
63
  const concurrent = options.concurrent === true ? "CONCURRENTLY " : "";
64
64
  const ifNotExistsSql = options.ifNotExists ?? true ? "IF NOT EXISTS " : "";
65
- return `CREATE INDEX ${concurrent}${ifNotExistsSql}${quoteIdentifier(index.name)} ON ${quoteIdentifier(tableName)} USING GIN ((${chunkOJHD3LXJ_cjs.renderSqlInline(expression, dialect)}) ${operatorClass});`;
65
+ return `CREATE INDEX ${concurrent}${ifNotExistsSql}${quoteIdentifier(index.name)} ON ${quoteIdentifier(tableName)} USING GIN ((${chunkH5IJSROF_cjs.renderSqlInline(expression, dialect)}) ${operatorClass});`;
66
66
  }
67
67
  function quoteIdentifier(identifier) {
68
68
  return `"${identifier.replaceAll('"', '""')}"`;
@@ -71,5 +71,5 @@ function quoteIdentifier(identifier) {
71
71
  exports.generateEdgeIndexDDL = generateEdgeIndexDDL;
72
72
  exports.generateIndexDDL = generateIndexDDL;
73
73
  exports.generateNodeIndexDDL = generateNodeIndexDDL;
74
- //# sourceMappingURL=chunk-CSNOYIB4.cjs.map
75
- //# sourceMappingURL=chunk-CSNOYIB4.cjs.map
74
+ //# sourceMappingURL=chunk-TM54OBHX.cjs.map
75
+ //# sourceMappingURL=chunk-TM54OBHX.cjs.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/indexes/ddl.ts"],"names":["sql","compileNodeIndexKeys","compileEdgeIndexKeys","renderSqlInline","compileIndexWhere","getDialect","requireDefined"],"mappings":"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","file":"chunk-CSNOYIB4.cjs","sourcesContent":["import { getDialect } from \"../query/dialect\";\nimport { type SqlDialect } from \"../query/dialect/types\";\nimport { renderSqlInline, sql, type SqlFragment } from \"../query/sql-fragment\";\nimport { requireDefined } from \"../utils/presence\";\nimport {\n compileEdgeIndexKeys,\n compileIndexWhere,\n compileNodeIndexKeys,\n type IndexCompilationContext,\n} from \"./compiler\";\nimport {\n type EdgeIndexDeclaration,\n type NodeIndexDeclaration,\n type RelationalIndexDeclaration,\n type SystemColumnName,\n} from \"./types\";\n\nexport type GenerateIndexDdlOptions = Readonly<{\n nodesTableName?: string | undefined;\n edgesTableName?: string | undefined;\n ifNotExists?: boolean | undefined;\n /**\n * Emit `CREATE INDEX CONCURRENTLY` (Postgres only). Required for\n * `store.materializeIndexes()` so live tables don't take an\n * `AccessExclusiveLock`. Ignored on SQLite (no equivalent; SQLite is\n * single-writer regardless). When true on Postgres, the resulting\n * statement cannot be executed inside a transaction.\n */\n concurrent?: boolean | undefined;\n}>;\n\nconst INDEX_DDL_BEHAVIOR = {\n postgres: { concurrentBuilds: true, supportsGinFamily: true },\n sqlite: { concurrentBuilds: false, supportsGinFamily: false },\n} as const satisfies Record<\n SqlDialect,\n Readonly<{ concurrentBuilds: boolean; supportsGinFamily: boolean }>\n>;\n\n/**\n * Generate `CREATE INDEX` DDL for a single relational index declaration.\n *\n * Vector index declarations (`entity: \"vector\"`) are NOT handled here —\n * they go through `backend.createVectorIndex` instead because the DDL\n * is dialect-specific (`USING hnsw (...) WITH (m=..., ef_construction=...)`\n * on Postgres) and operates on the strategy's per-`(kind, field)` embedding\n * tables, not `typegraph_nodes` / `typegraph_edges`. Callers narrow to the\n * relational subset before calling this function.\n */\nexport function generateIndexDDL(\n index: RelationalIndexDeclaration,\n dialect: SqlDialect,\n options: GenerateIndexDdlOptions = {},\n): string {\n if (index.entity === \"node\") {\n return generateNodeIndexDDL(index, dialect, options);\n }\n return generateEdgeIndexDDL(index, dialect, options);\n}\n\nexport function generateNodeIndexDDL(\n index: NodeIndexDeclaration,\n dialect: SqlDialect,\n options: GenerateIndexDdlOptions = {},\n): string {\n const tableName = options.nodesTableName ?? \"typegraph_nodes\";\n return generateTableIndexDDL(index, dialect, tableName, options);\n}\n\nexport function generateEdgeIndexDDL(\n index: EdgeIndexDeclaration,\n dialect: SqlDialect,\n options: GenerateIndexDdlOptions = {},\n): string {\n const tableName = options.edgesTableName ?? \"typegraph_edges\";\n return generateTableIndexDDL(index, dialect, tableName, options);\n}\n\nfunction generateTableIndexDDL(\n index: RelationalIndexDeclaration,\n dialect: SqlDialect,\n tableName: string,\n options: GenerateIndexDdlOptions,\n): string {\n if (index.method !== undefined) {\n return generateGinFamilyIndexDDL(index, dialect, tableName, options);\n }\n const ifNotExists = options.ifNotExists ?? true;\n const propsColumn = sql.identifier(\"props\");\n const systemColumn = (column: SystemColumnName): SqlFragment =>\n sql.identifier(column);\n\n const keys =\n index.entity === \"node\" ?\n compileNodeIndexKeys(index, dialect, propsColumn, systemColumn).keys\n : compileEdgeIndexKeys(index, dialect, propsColumn, systemColumn).keys;\n\n const whereSql =\n index.where ?\n renderSqlInline(\n compileIndexWhere(\n {\n dialect,\n propsColumn,\n systemColumn,\n } satisfies IndexCompilationContext,\n index.where,\n ),\n dialect,\n )\n : undefined;\n\n const keySql = keys.map((key) => renderSqlInline(key, dialect)).join(\", \");\n const unique = index.unique ? \"UNIQUE \" : \"\";\n const concurrent =\n (\n options.concurrent === true &&\n INDEX_DDL_BEHAVIOR[dialect].concurrentBuilds\n ) ?\n \"CONCURRENTLY \"\n : \"\";\n const ifNotExistsSql = ifNotExists ? \"IF NOT EXISTS \" : \"\";\n\n const whereClause = whereSql ? ` WHERE ${whereSql}` : \"\";\n\n return `CREATE ${unique}INDEX ${concurrent}${ifNotExistsSql}${quoteIdentifier(index.name)} ON ${quoteIdentifier(tableName)} (${keySql})${whereClause};`;\n}\n\n/**\n * DDL for the GIN-family methods (`\"gin\"` / `\"trigram\"`) — a PostgreSQL\n * expression GIN over the declaration's single field.\n *\n * The indexed expression is built from the SAME dialect extraction the\n * query compiler emits for the field (`jsonExtract` → `\"props\" #> ARRAY[…]`\n * for containment, `jsonExtractText` → `#>>` for text), because Postgres\n * matches expression indexes structurally: `(props #> ARRAY['tags']) @> $1`\n * and `(props #>> ARRAY['name']) ILIKE $1 ESCAPE '\\'` both hit their GIN\n * (verified against parameterized prepared statements). No scope prefix\n * columns, uniqueness, or partial clause: a GIN indexes one expression, and\n * the query's `graph_id` / `kind` equality filters apply as residual\n * conditions over the candidate rows.\n */\nfunction generateGinFamilyIndexDDL(\n index: RelationalIndexDeclaration,\n dialect: SqlDialect,\n tableName: string,\n options: GenerateIndexDdlOptions,\n): string {\n if (!INDEX_DDL_BEHAVIOR[dialect].supportsGinFamily) {\n throw new Error(\n `Index \"${index.name}\" declares method \"${index.method}\", which ` +\n \"requires PostgreSQL. materializeIndexes() reports such \" +\n \"declarations as skipped on SQLite instead of calling this.\",\n );\n }\n const adapter = getDialect(dialect);\n const propsColumn = sql.identifier(\"props\");\n const pointer = requireDefined(index.fields[0]);\n const expression =\n index.method === \"gin\" ?\n adapter.jsonExtract(propsColumn, pointer)\n : adapter.jsonExtractText(propsColumn, pointer);\n const operatorClass =\n index.method === \"gin\" ? \"jsonb_path_ops\" : \"gin_trgm_ops\";\n const concurrent = options.concurrent === true ? \"CONCURRENTLY \" : \"\";\n const ifNotExistsSql = (options.ifNotExists ?? true) ? \"IF NOT EXISTS \" : \"\";\n return `CREATE INDEX ${concurrent}${ifNotExistsSql}${quoteIdentifier(index.name)} ON ${quoteIdentifier(tableName)} USING GIN ((${renderSqlInline(expression, dialect)}) ${operatorClass});`;\n}\n\nfunction quoteIdentifier(identifier: string): string {\n return `\"${identifier.replaceAll('\"', '\"\"')}\"`;\n}\n"]}
1
+ {"version":3,"sources":["../src/indexes/ddl.ts"],"names":["sql","compileNodeIndexKeys","compileEdgeIndexKeys","renderSqlInline","compileIndexWhere","getDialect","requireDefined"],"mappings":"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","file":"chunk-TM54OBHX.cjs","sourcesContent":["import { getDialect } from \"../query/dialect\";\nimport { type SqlDialect } from \"../query/dialect/types\";\nimport { renderSqlInline, sql, type SqlFragment } from \"../query/sql-fragment\";\nimport { requireDefined } from \"../utils/presence\";\nimport {\n compileEdgeIndexKeys,\n compileIndexWhere,\n compileNodeIndexKeys,\n type IndexCompilationContext,\n} from \"./compiler\";\nimport {\n type EdgeIndexDeclaration,\n type NodeIndexDeclaration,\n type RelationalIndexDeclaration,\n type SystemColumnName,\n} from \"./types\";\n\nexport type GenerateIndexDdlOptions = Readonly<{\n nodesTableName?: string | undefined;\n edgesTableName?: string | undefined;\n ifNotExists?: boolean | undefined;\n /**\n * Emit `CREATE INDEX CONCURRENTLY` (Postgres only). Required for\n * `store.materializeIndexes()` so live tables don't take an\n * `AccessExclusiveLock`. Ignored on SQLite (no equivalent; SQLite is\n * single-writer regardless). When true on Postgres, the resulting\n * statement cannot be executed inside a transaction.\n */\n concurrent?: boolean | undefined;\n}>;\n\nconst INDEX_DDL_BEHAVIOR = {\n postgres: { concurrentBuilds: true, supportsGinFamily: true },\n sqlite: { concurrentBuilds: false, supportsGinFamily: false },\n} as const satisfies Record<\n SqlDialect,\n Readonly<{ concurrentBuilds: boolean; supportsGinFamily: boolean }>\n>;\n\n/**\n * Generate `CREATE INDEX` DDL for a single relational index declaration.\n *\n * Vector index declarations (`entity: \"vector\"`) are NOT handled here —\n * they go through `backend.createVectorIndex` instead because the DDL\n * is dialect-specific (`USING hnsw (...) WITH (m=..., ef_construction=...)`\n * on Postgres) and operates on the strategy's per-`(kind, field)` embedding\n * tables, not `typegraph_nodes` / `typegraph_edges`. Callers narrow to the\n * relational subset before calling this function.\n */\nexport function generateIndexDDL(\n index: RelationalIndexDeclaration,\n dialect: SqlDialect,\n options: GenerateIndexDdlOptions = {},\n): string {\n if (index.entity === \"node\") {\n return generateNodeIndexDDL(index, dialect, options);\n }\n return generateEdgeIndexDDL(index, dialect, options);\n}\n\nexport function generateNodeIndexDDL(\n index: NodeIndexDeclaration,\n dialect: SqlDialect,\n options: GenerateIndexDdlOptions = {},\n): string {\n const tableName = options.nodesTableName ?? \"typegraph_nodes\";\n return generateTableIndexDDL(index, dialect, tableName, options);\n}\n\nexport function generateEdgeIndexDDL(\n index: EdgeIndexDeclaration,\n dialect: SqlDialect,\n options: GenerateIndexDdlOptions = {},\n): string {\n const tableName = options.edgesTableName ?? \"typegraph_edges\";\n return generateTableIndexDDL(index, dialect, tableName, options);\n}\n\nfunction generateTableIndexDDL(\n index: RelationalIndexDeclaration,\n dialect: SqlDialect,\n tableName: string,\n options: GenerateIndexDdlOptions,\n): string {\n if (index.method !== undefined) {\n return generateGinFamilyIndexDDL(index, dialect, tableName, options);\n }\n const ifNotExists = options.ifNotExists ?? true;\n const propsColumn = sql.identifier(\"props\");\n const systemColumn = (column: SystemColumnName): SqlFragment =>\n sql.identifier(column);\n\n const keys =\n index.entity === \"node\" ?\n compileNodeIndexKeys(index, dialect, propsColumn, systemColumn).keys\n : compileEdgeIndexKeys(index, dialect, propsColumn, systemColumn).keys;\n\n const whereSql =\n index.where ?\n renderSqlInline(\n compileIndexWhere(\n {\n dialect,\n propsColumn,\n systemColumn,\n } satisfies IndexCompilationContext,\n index.where,\n ),\n dialect,\n )\n : undefined;\n\n const keySql = keys.map((key) => renderSqlInline(key, dialect)).join(\", \");\n const unique = index.unique ? \"UNIQUE \" : \"\";\n const concurrent =\n (\n options.concurrent === true &&\n INDEX_DDL_BEHAVIOR[dialect].concurrentBuilds\n ) ?\n \"CONCURRENTLY \"\n : \"\";\n const ifNotExistsSql = ifNotExists ? \"IF NOT EXISTS \" : \"\";\n\n const whereClause = whereSql ? ` WHERE ${whereSql}` : \"\";\n\n return `CREATE ${unique}INDEX ${concurrent}${ifNotExistsSql}${quoteIdentifier(index.name)} ON ${quoteIdentifier(tableName)} (${keySql})${whereClause};`;\n}\n\n/**\n * DDL for the GIN-family methods (`\"gin\"` / `\"trigram\"`) — a PostgreSQL\n * expression GIN over the declaration's single field.\n *\n * The indexed expression is built from the SAME dialect extraction the\n * query compiler emits for the field (`jsonExtract` → `\"props\" #> ARRAY[…]`\n * for containment, `jsonExtractText` → `#>>` for text), because Postgres\n * matches expression indexes structurally: `(props #> ARRAY['tags']) @> $1`\n * and `(props #>> ARRAY['name']) ILIKE $1 ESCAPE '\\'` both hit their GIN\n * (verified against parameterized prepared statements). No scope prefix\n * columns, uniqueness, or partial clause: a GIN indexes one expression, and\n * the query's `graph_id` / `kind` equality filters apply as residual\n * conditions over the candidate rows.\n */\nfunction generateGinFamilyIndexDDL(\n index: RelationalIndexDeclaration,\n dialect: SqlDialect,\n tableName: string,\n options: GenerateIndexDdlOptions,\n): string {\n if (!INDEX_DDL_BEHAVIOR[dialect].supportsGinFamily) {\n throw new Error(\n `Index \"${index.name}\" declares method \"${index.method}\", which ` +\n \"requires PostgreSQL. materializeIndexes() reports such \" +\n \"declarations as skipped on SQLite instead of calling this.\",\n );\n }\n const adapter = getDialect(dialect);\n const propsColumn = sql.identifier(\"props\");\n const pointer = requireDefined(index.fields[0]);\n const expression =\n index.method === \"gin\" ?\n adapter.jsonExtract(propsColumn, pointer)\n : adapter.jsonExtractText(propsColumn, pointer);\n const operatorClass =\n index.method === \"gin\" ? \"jsonb_path_ops\" : \"gin_trgm_ops\";\n const concurrent = options.concurrent === true ? \"CONCURRENTLY \" : \"\";\n const ifNotExistsSql = (options.ifNotExists ?? true) ? \"IF NOT EXISTS \" : \"\";\n return `CREATE INDEX ${concurrent}${ifNotExistsSql}${quoteIdentifier(index.name)} ON ${quoteIdentifier(tableName)} USING GIN ((${renderSqlInline(expression, dialect)}) ${operatorClass});`;\n}\n\nfunction quoteIdentifier(identifier: string): string {\n return `\"${identifier.replaceAll('\"', '\"\"')}\"`;\n}\n"]}
@@ -1,14 +1,14 @@
1
- import { nodeClaimSites, nodeClaimEntries, getEmbeddingFields, createNodeWriteContext, applyNodeSetUpdate, applyNodeResurrect, applyNodeHardDelete, applyNodeSoftDelete, applyNodeUpdate, withNodeCreateClaimsBatch, applyNodeInsertSyncFansBatch, withNodeCreateClaims, applyNodeInsertSyncFans, checkUniquenessConstraints, createUniquenessContext } from './chunk-VTJVMP4I.js';
2
- import { EDGE_CARDINALITY_SPECS, claimEdgeCardinalityBatch, claimEdgeCardinality, purgeEdgeClaims } from './chunk-YA36ABIL.js';
3
- import { refKey } from './chunk-GVYVGGPJ.js';
4
- import { runInWriteTransaction, runHookedWriteOperation, validateNodeProps, getNodeRowsByIds, generateId, nodeInsertDispatch, edgeInsertDispatch, runInsertBatch, runInsertBatchReturning, runInsertNoReturn } from './chunk-FX5ZW6PN.js';
5
- import { deriveBackend, canonicalEqual } from './chunk-IRPYOHRC.js';
6
- import { createSqlSchema, DEFAULT_SQL_SCHEMA } from './chunk-Y55DLLEG.js';
7
- import { rowPropsToObject, isLiveNodeRow } from './chunk-PALYTHGM.js';
8
- import { checkDisjointness, checkUniqueEdge, checkCardinality, uniquenessProbeKinds, encodeTupleKey, checkWherePredicate, computeUniqueKey } from './chunk-5LKOVCPP.js';
1
+ import { nodeClaimSites, nodeClaimEntries, getEmbeddingFields, createNodeWriteContext, applyNodeSetUpdate, applyNodeResurrect, applyNodeHardDelete, applyNodeSoftDelete, applyNodeUpdate, withNodeCreateClaimsBatch, applyNodeInsertSyncFansBatch, withNodeCreateClaims, applyNodeInsertSyncFans, checkUniquenessConstraints, createUniquenessContext } from './chunk-4DKY6RIU.js';
2
+ import { EDGE_CARDINALITY_SPECS, claimEdgeCardinalityBatch, claimEdgeCardinality, purgeEdgeClaims } from './chunk-NGQDGL5X.js';
3
+ import { refKey } from './chunk-WFSYYU4W.js';
4
+ import { runInWriteTransaction, runHookedWriteOperation, validateNodeProps, getNodeRowsByIds, generateId, nodeInsertDispatch, edgeInsertDispatch, runInsertBatch, runInsertBatchReturning, runInsertNoReturn } from './chunk-VAAC7L57.js';
5
+ import { deriveBackend, canonicalEqual } from './chunk-QG5VEOKX.js';
6
+ import { missingRequiredExtras } from './chunk-XORONCV3.js';
7
+ import { rowPropsToObject, bindExtraIfReachable, BATCH_POINT_READ, UNIQUE_SIDECAR_BATCH, createSqlSchema, DEFAULT_SQL_SCHEMA, isLiveNodeRow } from './chunk-LKZDQ2B4.js';
8
+ import { checkDisjointness, checkUniqueEdge, checkCardinality, uniquenessProbeKinds, encodeTupleKey, checkWherePredicate, computeUniqueKey } from './chunk-RVUL2HXY.js';
9
9
  import { assertsStoredLowerBound, assertsStoredUpperBound, validateOptionalCanonicalIsoDate, nowIso, resolveStampedValidityLowerBound, assertOrderedValidityWindow, preservesImmutableLowerBound, assertWritableValidityWindow } from './chunk-K46SDNQD.js';
10
- import { getDialect, compileNodeIndexFieldKeys, compileIndexWhere } from './chunk-EDLKIQRI.js';
11
- import { sql, asCompiledRowsSql } from './chunk-46UGOVRW.js';
10
+ import { getDialect, compileNodeIndexFieldKeys, compileIndexWhere } from './chunk-7G5IYROL.js';
11
+ import { sql, asCompiledRowsSql } from './chunk-7QFRK6PU.js';
12
12
  import { getSearchableFields } from './chunk-PC2UBAUB.js';
13
13
  import { filterReservedKeys, RESERVED_NODE_KEYS, RESERVED_EDGE_KEYS, assertJsonValue } from './chunk-FZHF5UWR.js';
14
14
  import { ValidationError, ConfigurationError, DatabaseOperationError, UniquenessError, KindNotFoundError, NodeConstraintNotFoundError, NodeIndexNotFoundError, ENTITY_ALREADY_EXISTS_CODE, NodeNotFoundError } from './chunk-YDEJQWOL.js';
@@ -266,12 +266,14 @@ function createEdgeBatchValidationBackend(backend) {
266
266
  }
267
267
 
268
268
  // src/store/operations/edge-write-pipeline.ts
269
- function createEdgeWriteContext(graphId, lock) {
270
- return { graphId, lock };
269
+ function createEdgeWriteContext(graphId, lock, claimsVerdict) {
270
+ return { graphId, lock, claimsVerdict };
271
271
  }
272
272
  async function applyEdgeUpdate(ctx, args, backend) {
273
273
  const { claim, ...rowWork } = args;
274
- if (claim !== void 0) await claimEdgeCardinality(backend, claim);
274
+ if (claim !== void 0) {
275
+ await claimEdgeCardinality(backend, ctx.claimsVerdict(), claim);
276
+ }
275
277
  const updateParams = { graphId: ctx.graphId, ...rowWork };
276
278
  return backend.updateEdge(updateParams);
277
279
  }
@@ -289,7 +291,7 @@ async function applyEdgeHardDelete(ctx, work, backend) {
289
291
  kind: work.kind
290
292
  });
291
293
  if (work.holdsCardinalityClaim) {
292
- await purgeEdgeClaims(backend, ctx.graphId, [work.id]);
294
+ await purgeEdgeClaims(backend, ctx.claimsVerdict(), ctx.graphId, [work.id]);
293
295
  }
294
296
  }
295
297
 
@@ -356,9 +358,19 @@ function edgeBatchClaims(work) {
356
358
  return work.flatMap((item) => item.claim === void 0 ? [] : [item.claim]);
357
359
  }
358
360
  function createWriteSession(ctx, target, lock) {
359
- const writeContext = createNodeWriteContext(ctx.graphId, ctx.registry, lock);
361
+ const writeContext = createNodeWriteContext(
362
+ ctx.graphId,
363
+ ctx.registry,
364
+ lock,
365
+ ctx.claimsVerdict,
366
+ ctx.uniqueSidecarBatch
367
+ );
360
368
  const dispatch = nodeInsertDispatch(target);
361
- const edgeContext = createEdgeWriteContext(ctx.graphId, lock);
369
+ const edgeContext = createEdgeWriteContext(
370
+ ctx.graphId,
371
+ lock,
372
+ ctx.claimsVerdict
373
+ );
362
374
  const edgeDispatch = edgeInsertDispatch(target);
363
375
  return {
364
376
  // The pinned coordination order, spelled once per insert shape:
@@ -442,25 +454,33 @@ function createWriteSession(ctx, target, lock) {
442
454
  // in the same order.
443
455
  createEdge: async (work) => {
444
456
  if (work.claim !== void 0) {
445
- await claimEdgeCardinality(target, work.claim);
457
+ await claimEdgeCardinality(target, ctx.claimsVerdict(), work.claim);
446
458
  }
447
459
  return edgeDispatch.one(work.params);
448
460
  },
449
461
  createEdgeNoReturn: async (work) => {
450
462
  if (work.claim !== void 0) {
451
- await claimEdgeCardinality(target, work.claim);
463
+ await claimEdgeCardinality(target, ctx.claimsVerdict(), work.claim);
452
464
  }
453
465
  await runInsertNoReturn(edgeDispatch, work.params);
454
466
  },
455
467
  createEdges: async (work) => {
456
- await claimEdgeCardinalityBatch(target, edgeBatchClaims(work));
468
+ await claimEdgeCardinalityBatch(
469
+ target,
470
+ ctx.claimsVerdict(),
471
+ edgeBatchClaims(work)
472
+ );
457
473
  return runInsertBatchReturning(
458
474
  edgeDispatch,
459
475
  work.map((item) => item.params)
460
476
  );
461
477
  },
462
478
  createEdgesNoReturn: async (work) => {
463
- await claimEdgeCardinalityBatch(target, edgeBatchClaims(work));
479
+ await claimEdgeCardinalityBatch(
480
+ target,
481
+ ctx.claimsVerdict(),
482
+ edgeBatchClaims(work)
483
+ );
464
484
  await runInsertBatch(
465
485
  edgeDispatch,
466
486
  work.map((item) => item.params)
@@ -886,7 +906,12 @@ async function finishNodeCreatePreparation(ctx, draft, backend) {
886
906
  };
887
907
  await checkDisjointnessConstraint(constraintContext, kind, id);
888
908
  await checkUniquenessConstraints(
889
- createUniquenessContext(ctx.graphId, ctx.registry, backend),
909
+ createUniquenessContext(
910
+ ctx.graphId,
911
+ ctx.registry,
912
+ backend,
913
+ ctx.uniqueSidecarBatch
914
+ ),
890
915
  kind,
891
916
  id,
892
917
  validatedProps,
@@ -1077,7 +1102,12 @@ function nodeUpdateRaceError(input, error) {
1077
1102
  );
1078
1103
  }
1079
1104
  async function primeBatchValidationCaches(ctx, drafts, backend, seams) {
1080
- if (backend.getNodes !== void 0) {
1105
+ const boundGetNodes = bindExtraIfReachable(
1106
+ backend,
1107
+ ctx.batchPointRead.extras.getNodes,
1108
+ BATCH_POINT_READ.id
1109
+ );
1110
+ if (boundGetNodes !== void 0) {
1081
1111
  const idsByKind = /* @__PURE__ */ new Map();
1082
1112
  for (const draft of drafts) {
1083
1113
  const ids = idsByKind.get(draft.kind) ?? /* @__PURE__ */ new Set();
@@ -1086,14 +1116,19 @@ async function primeBatchValidationCaches(ctx, drafts, backend, seams) {
1086
1116
  }
1087
1117
  for (const [kind, ids] of idsByKind) {
1088
1118
  const orderedIds = [...ids];
1089
- const rows = await backend.getNodes(ctx.graphId, kind, orderedIds);
1119
+ const rows = await boundGetNodes.getNodes(ctx.graphId, kind, orderedIds);
1090
1120
  const rowsById = new Map(rows.map((row) => [row.id, row]));
1091
1121
  for (const id of orderedIds) {
1092
1122
  seams.seedNodeRow(kind, id, rowsById.get(id));
1093
1123
  }
1094
1124
  }
1095
1125
  }
1096
- if (backend.checkUniqueBatch !== void 0) {
1126
+ const boundCheckUniqueBatch = bindExtraIfReachable(
1127
+ backend,
1128
+ ctx.uniqueSidecarBatch.extras.checkUniqueBatch,
1129
+ UNIQUE_SIDECAR_BATCH.id
1130
+ );
1131
+ if (boundCheckUniqueBatch !== void 0) {
1097
1132
  const groups = /* @__PURE__ */ new Map();
1098
1133
  for (const draft of drafts) {
1099
1134
  for (const entry of nodeClaimEntries(
@@ -1126,7 +1161,7 @@ async function primeBatchValidationCaches(ctx, drafts, backend, seams) {
1126
1161
  }
1127
1162
  for (const group of groups.values()) {
1128
1163
  const orderedKeys = [...group.keys];
1129
- const rows = await backend.checkUniqueBatch({
1164
+ const rows = await boundCheckUniqueBatch.checkUniqueBatch({
1130
1165
  graphId: ctx.graphId,
1131
1166
  nodeKind: group.nodeKind,
1132
1167
  constraintName: group.constraintName,
@@ -1263,10 +1298,15 @@ async function findUniqueRowAcrossKinds(backend, graphId, constraintName, key, k
1263
1298
  }
1264
1299
  return preferred;
1265
1300
  }
1266
- async function batchCheckUniqueAcrossKinds(backend, graphId, constraintName, uniqueKeys, kindsToCheck, includeDeleted) {
1301
+ async function batchCheckUniqueAcrossKinds(backend, uniqueSidecarBatch, graphId, constraintName, uniqueKeys, kindsToCheck, includeDeleted) {
1267
1302
  const existingByKey = /* @__PURE__ */ new Map();
1303
+ const boundCheckUniqueBatch = bindExtraIfReachable(
1304
+ backend,
1305
+ uniqueSidecarBatch.extras.checkUniqueBatch,
1306
+ UNIQUE_SIDECAR_BATCH.id
1307
+ );
1268
1308
  for (const kindToCheck of kindsToCheck) {
1269
- if (backend.checkUniqueBatch === void 0) {
1309
+ if (boundCheckUniqueBatch === void 0) {
1270
1310
  for (const key of uniqueKeys) {
1271
1311
  const incumbent = existingByKey.get(key);
1272
1312
  if (incumbent !== void 0 && incumbent.deleted_at === void 0) {
@@ -1284,7 +1324,7 @@ async function batchCheckUniqueAcrossKinds(backend, graphId, constraintName, uni
1284
1324
  }
1285
1325
  }
1286
1326
  } else {
1287
- const rows = await backend.checkUniqueBatch({
1327
+ const rows = await boundCheckUniqueBatch.checkUniqueBatch({
1288
1328
  graphId,
1289
1329
  nodeKind: kindToCheck,
1290
1330
  constraintName,
@@ -1559,7 +1599,11 @@ async function executeNodeUpdateWhere(ctx, kind, inputPatch, candidateIds, candi
1559
1599
  }
1560
1600
  );
1561
1601
  }
1562
- if (uniqueConstraints.length > 0 && (backend.hardDeleteUniquesByNodeIds === void 0 || backend.insertUniqueBatch === void 0 || backend.checkUniqueBatch === void 0)) {
1602
+ if (uniqueConstraints.length > 0 && missingRequiredExtras(
1603
+ UNIQUE_SIDECAR_BATCH,
1604
+ ctx.uniqueSidecarBatch,
1605
+ "set-based node update"
1606
+ ).length > 0) {
1563
1607
  throw new ConfigurationError(
1564
1608
  "updateWhere() requires batched uniqueness sidecar operations for constrained nodes",
1565
1609
  { code: "SET_UPDATE_UNIQUENESS_UNSUPPORTED", kind }
@@ -1889,6 +1933,7 @@ async function executeNodeBulkFindByConstraint(ctx, kind, constraintName, items,
1889
1933
  );
1890
1934
  const existingByKey = uniqueKeys.length > 0 ? await batchCheckUniqueAcrossKinds(
1891
1935
  backend,
1936
+ ctx.uniqueSidecarBatch,
1892
1937
  ctx.graphId,
1893
1938
  constraint.name,
1894
1939
  uniqueKeys,
@@ -2113,6 +2158,7 @@ async function executeNodeBulkFindByIndex(ctx, kind, indexName, items, backend,
2113
2158
  const matches = limitPerInput !== void 0 && !capInSql ? capMatchesPerGroup(rawMatches, limitPerInput) : rawMatches;
2114
2159
  const nodesById = await hydrateNodesById(
2115
2160
  backend,
2161
+ ctx.batchPointRead,
2116
2162
  ctx.graphId,
2117
2163
  kind,
2118
2164
  matches.map((match) => match.id)
@@ -2140,8 +2186,14 @@ function capMatchesPerGroup(matches, limitPerInput) {
2140
2186
  }
2141
2187
  return capped;
2142
2188
  }
2143
- async function hydrateNodesById(backend, graphId, kind, ids) {
2144
- const rowsById = await getNodeRowsByIds(backend, graphId, kind, ids);
2189
+ async function hydrateNodesById(backend, batchPointRead, graphId, kind, ids) {
2190
+ const rowsById = await getNodeRowsByIds(
2191
+ backend,
2192
+ batchPointRead,
2193
+ graphId,
2194
+ kind,
2195
+ ids
2196
+ );
2145
2197
  const nodesById = /* @__PURE__ */ new Map();
2146
2198
  for (const [id, row] of rowsById) {
2147
2199
  if (row.deleted_at !== void 0) continue;
@@ -2165,6 +2217,7 @@ async function executeNodeBulkGetOrCreateByConstraint(ctx, kind, constraintName,
2165
2217
  async function attempt() {
2166
2218
  const existingByKey = uniqueKeys.length > 0 ? await batchCheckUniqueAcrossKinds(
2167
2219
  backend,
2220
+ ctx.uniqueSidecarBatch,
2168
2221
  ctx.graphId,
2169
2222
  constraint.name,
2170
2223
  uniqueKeys,
@@ -2266,5 +2319,5 @@ async function executeNodeBulkGetOrCreateByConstraint(ctx, kind, constraintName,
2266
2319
  }
2267
2320
 
2268
2321
  export { assertClearValidToSupported, assertValidityEndMutation, assertsStoredWindowState, checkCardinalityConstraint, checkDisjointnessConstraint, createEdgeBatchValidationBackend, createNodeBatchValidationSeams, edgeWriteNeedsConstraintFence, edgeWritePlan, executeNodeBulkFindByConstraint, executeNodeBulkFindByIndex, executeNodeBulkGetOrCreateByConstraint, executeNodeCreate, executeNodeCreateBatch, executeNodeCreateNoReturnBatch, executeNodeDelete, executeNodeDeleteBatch, executeNodeFindByConstraint, executeNodeGetOrCreateByConstraint, executeNodeHardDelete, executeNodeUpdate, executeNodeUpdateWhere, executeNodeUpsertUpdate, graphOwesClaims, mixedWritePlan, nodeUpsertDirtyCheck, primeBatchValidationCaches, rowToEdge, rowToEdgeMeta, rowToNode, rowToNodeMeta, runHookedWritePlan, runWritePlan, unfencedTarget, validityEndAfterMutation, withAlreadyExistsTranslation };
2269
- //# sourceMappingURL=chunk-2GIV5X4P.js.map
2270
- //# sourceMappingURL=chunk-2GIV5X4P.js.map
2322
+ //# sourceMappingURL=chunk-TYEYRCXL.js.map
2323
+ //# sourceMappingURL=chunk-TYEYRCXL.js.map