@nicia-ai/typegraph 0.42.1 → 0.44.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 (289) hide show
  1. package/dist/backend/drizzle/indexes.cjs +9 -9
  2. package/dist/backend/drizzle/indexes.d.cts +1 -1
  3. package/dist/backend/drizzle/indexes.d.ts +1 -1
  4. package/dist/backend/drizzle/indexes.js +5 -5
  5. package/dist/backend/index.cjs +50 -50
  6. package/dist/backend/index.d.cts +3 -3
  7. package/dist/backend/index.d.ts +3 -3
  8. package/dist/backend/index.js +11 -11
  9. package/dist/backend/postgres/index.cjs +26 -26
  10. package/dist/backend/postgres/index.d.cts +6 -5
  11. package/dist/backend/postgres/index.d.ts +6 -5
  12. package/dist/backend/postgres/index.js +13 -13
  13. package/dist/backend/postgres/pglite-store.cjs +33 -33
  14. package/dist/backend/postgres/pglite-store.cjs.map +1 -1
  15. package/dist/backend/postgres/pglite-store.d.cts +7 -7
  16. package/dist/backend/postgres/pglite-store.d.ts +7 -7
  17. package/dist/backend/postgres/pglite-store.js +29 -29
  18. package/dist/backend/postgres/pglite-store.js.map +1 -1
  19. package/dist/backend/postgres/pglite.cjs +15 -15
  20. package/dist/backend/postgres/pglite.d.cts +3 -2
  21. package/dist/backend/postgres/pglite.d.ts +3 -2
  22. package/dist/backend/postgres/pglite.js +14 -14
  23. package/dist/backend/sqlite/index.cjs +23 -23
  24. package/dist/backend/sqlite/index.d.cts +7 -6
  25. package/dist/backend/sqlite/index.d.ts +7 -6
  26. package/dist/backend/sqlite/index.js +11 -11
  27. package/dist/backend/sqlite/libsql.cjs +17 -17
  28. package/dist/backend/sqlite/libsql.cjs.map +1 -1
  29. package/dist/backend/sqlite/libsql.d.cts +3 -2
  30. package/dist/backend/sqlite/libsql.d.ts +3 -2
  31. package/dist/backend/sqlite/libsql.js +13 -13
  32. package/dist/backend/sqlite/libsql.js.map +1 -1
  33. package/dist/backend/sqlite/local-store.cjs +34 -34
  34. package/dist/backend/sqlite/local-store.cjs.map +1 -1
  35. package/dist/backend/sqlite/local-store.d.cts +8 -7
  36. package/dist/backend/sqlite/local-store.d.ts +8 -7
  37. package/dist/backend/sqlite/local-store.js +30 -30
  38. package/dist/backend/sqlite/local-store.js.map +1 -1
  39. package/dist/backend/sqlite/local.cjs +16 -16
  40. package/dist/backend/sqlite/local.d.cts +3 -2
  41. package/dist/backend/sqlite/local.d.ts +3 -2
  42. package/dist/backend/sqlite/local.js +14 -14
  43. package/dist/{chunk-3RPQDGUE.cjs → chunk-2BIG7U6E.cjs} +5 -5
  44. package/dist/{chunk-3RPQDGUE.cjs.map → chunk-2BIG7U6E.cjs.map} +1 -1
  45. package/dist/{chunk-2OOY4OYT.js → chunk-2L54C2C2.js} +4 -4
  46. package/dist/{chunk-2OOY4OYT.js.map → chunk-2L54C2C2.js.map} +1 -1
  47. package/dist/{chunk-V2GZBPY2.cjs → chunk-2VLBGQBY.cjs} +310 -61
  48. package/dist/chunk-2VLBGQBY.cjs.map +1 -0
  49. package/dist/{chunk-RXOAXO3R.js → chunk-2WDD2NO3.js} +3 -3
  50. package/dist/{chunk-RXOAXO3R.js.map → chunk-2WDD2NO3.js.map} +1 -1
  51. package/dist/{chunk-2HKIID5K.js → chunk-2Y4IFKW7.js} +5 -5
  52. package/dist/{chunk-2HKIID5K.js.map → chunk-2Y4IFKW7.js.map} +1 -1
  53. package/dist/{chunk-ECU53PMN.cjs → chunk-3PRKZW6D.cjs} +5 -5
  54. package/dist/chunk-3PRKZW6D.cjs.map +1 -0
  55. package/dist/{chunk-2G6ZEGYO.js → chunk-46GDII45.js} +4 -4
  56. package/dist/{chunk-2G6ZEGYO.js.map → chunk-46GDII45.js.map} +1 -1
  57. package/dist/{chunk-OYJSYDIH.js → chunk-4MB3AQAQ.js} +13 -3
  58. package/dist/chunk-4MB3AQAQ.js.map +1 -0
  59. package/dist/chunk-4SZ6XPTG.cjs +12 -0
  60. package/dist/{chunk-VGMNGWBR.cjs.map → chunk-4SZ6XPTG.cjs.map} +1 -1
  61. package/dist/{chunk-FY4VY5EV.cjs → chunk-5MUSU4ZP.cjs} +20 -20
  62. package/dist/chunk-5MUSU4ZP.cjs.map +1 -0
  63. package/dist/{chunk-ZIRC2U6G.js → chunk-63KCKSSH.js} +78 -16
  64. package/dist/chunk-63KCKSSH.js.map +1 -0
  65. package/dist/{chunk-7Y6BV3TK.cjs → chunk-66UVLHQA.cjs} +100 -100
  66. package/dist/{chunk-7Y6BV3TK.cjs.map → chunk-66UVLHQA.cjs.map} +1 -1
  67. package/dist/{chunk-M4GYQF2H.js → chunk-6DCB664D.js} +7 -4
  68. package/dist/chunk-6DCB664D.js.map +1 -0
  69. package/dist/{chunk-OMQ2NBOR.cjs → chunk-6JZUSDY2.cjs} +27 -27
  70. package/dist/{chunk-OMQ2NBOR.cjs.map → chunk-6JZUSDY2.cjs.map} +1 -1
  71. package/dist/{chunk-Z3WIL6S3.js → chunk-7G32LIQM.js} +5 -5
  72. package/dist/{chunk-Z3WIL6S3.js.map → chunk-7G32LIQM.js.map} +1 -1
  73. package/dist/{chunk-2SO5I5AI.cjs → chunk-7V2FGGI2.cjs} +250 -198
  74. package/dist/chunk-7V2FGGI2.cjs.map +1 -0
  75. package/dist/{chunk-I73ATSAH.cjs → chunk-A2I2XO52.cjs} +4 -4
  76. package/dist/{chunk-I73ATSAH.cjs.map → chunk-A2I2XO52.cjs.map} +1 -1
  77. package/dist/{chunk-O2GZM7UK.cjs → chunk-A4PBRX4C.cjs} +7 -7
  78. package/dist/{chunk-O2GZM7UK.cjs.map → chunk-A4PBRX4C.cjs.map} +1 -1
  79. package/dist/{chunk-5P6IPIT6.cjs → chunk-ALFUGRYB.cjs} +75 -65
  80. package/dist/chunk-ALFUGRYB.cjs.map +1 -0
  81. package/dist/{chunk-NXIZL7ZZ.js → chunk-ATLN63JA.js} +6 -6
  82. package/dist/chunk-ATLN63JA.js.map +1 -0
  83. package/dist/{chunk-CUPJL6TS.js → chunk-B75XRV3O.js} +3 -3
  84. package/dist/{chunk-CUPJL6TS.js.map → chunk-B75XRV3O.js.map} +1 -1
  85. package/dist/{chunk-DP7KC6CL.js → chunk-BCP7LLOY.js} +754 -476
  86. package/dist/chunk-BCP7LLOY.js.map +1 -0
  87. package/dist/{chunk-RAWG2FEU.js → chunk-BEFM74L2.js} +264 -18
  88. package/dist/chunk-BEFM74L2.js.map +1 -0
  89. package/dist/{chunk-LQLVJWUH.js → chunk-BNUFUFAU.js} +7 -7
  90. package/dist/chunk-BNUFUFAU.js.map +1 -0
  91. package/dist/{chunk-KTBTSHU6.cjs → chunk-C4F7VJ5D.cjs} +13 -3
  92. package/dist/chunk-C4F7VJ5D.cjs.map +1 -0
  93. package/dist/{chunk-CVK4T34X.cjs → chunk-CPEL3YIR.cjs} +22 -22
  94. package/dist/{chunk-CVK4T34X.cjs.map → chunk-CPEL3YIR.cjs.map} +1 -1
  95. package/dist/{chunk-O3USVVWS.js → chunk-DK2S42XB.js} +3 -3
  96. package/dist/{chunk-O3USVVWS.js.map → chunk-DK2S42XB.js.map} +1 -1
  97. package/dist/{chunk-DMZEVJGL.cjs → chunk-EE7N5XXQ.cjs} +13 -13
  98. package/dist/{chunk-DMZEVJGL.cjs.map → chunk-EE7N5XXQ.cjs.map} +1 -1
  99. package/dist/{chunk-ZGOUVMVS.js → chunk-EFELJVLA.js} +5 -5
  100. package/dist/{chunk-ZGOUVMVS.js.map → chunk-EFELJVLA.js.map} +1 -1
  101. package/dist/chunk-EPTSMFH7.cjs +12 -0
  102. package/dist/{chunk-U3YRCZ5L.cjs.map → chunk-EPTSMFH7.cjs.map} +1 -1
  103. package/dist/{chunk-FSCJOTHF.cjs → chunk-EQ7JKLZO.cjs} +10 -10
  104. package/dist/{chunk-FSCJOTHF.cjs.map → chunk-EQ7JKLZO.cjs.map} +1 -1
  105. package/dist/{chunk-5Q3P6OIC.cjs → chunk-FGO5JFVJ.cjs} +12 -12
  106. package/dist/chunk-FGO5JFVJ.cjs.map +1 -0
  107. package/dist/{chunk-VC26BUNP.js → chunk-FMGEZBAQ.js} +5 -5
  108. package/dist/{chunk-VC26BUNP.js.map → chunk-FMGEZBAQ.js.map} +1 -1
  109. package/dist/{chunk-UZLEQFTV.js → chunk-FMMIX6N4.js} +4 -4
  110. package/dist/chunk-FMMIX6N4.js.map +1 -0
  111. package/dist/{chunk-5C75HQYQ.js → chunk-FRHHDHKH.js} +5 -5
  112. package/dist/{chunk-5C75HQYQ.js.map → chunk-FRHHDHKH.js.map} +1 -1
  113. package/dist/{chunk-EVFL2ZY5.js → chunk-FSXTPBRN.js} +63 -12
  114. package/dist/chunk-FSXTPBRN.js.map +1 -0
  115. package/dist/{chunk-TRC646QQ.cjs → chunk-GFRGG2US.cjs} +7 -7
  116. package/dist/{chunk-TRC646QQ.cjs.map → chunk-GFRGG2US.cjs.map} +1 -1
  117. package/dist/{chunk-UJRWOV5B.js → chunk-GWEDD3DH.js} +5 -5
  118. package/dist/{chunk-UJRWOV5B.js.map → chunk-GWEDD3DH.js.map} +1 -1
  119. package/dist/{chunk-AQR6BHB3.cjs → chunk-HJH3RMXG.cjs} +10 -10
  120. package/dist/{chunk-AQR6BHB3.cjs.map → chunk-HJH3RMXG.cjs.map} +1 -1
  121. package/dist/{chunk-F7TDKSVB.cjs → chunk-HOHAJ2NR.cjs} +4 -4
  122. package/dist/{chunk-F7TDKSVB.cjs.map → chunk-HOHAJ2NR.cjs.map} +1 -1
  123. package/dist/{chunk-YPVQYM3L.js → chunk-HOIFFY4M.js} +100 -20
  124. package/dist/chunk-HOIFFY4M.js.map +1 -0
  125. package/dist/{chunk-LDCWO5B6.js → chunk-IIMQJYAM.js} +3 -3
  126. package/dist/{chunk-LDCWO5B6.js.map → chunk-IIMQJYAM.js.map} +1 -1
  127. package/dist/{chunk-OM6RIOA5.cjs → chunk-IIT5K7SK.cjs} +13 -13
  128. package/dist/{chunk-OM6RIOA5.cjs.map → chunk-IIT5K7SK.cjs.map} +1 -1
  129. package/dist/{chunk-EQOQOT55.js → chunk-IJTLXNGJ.js} +5 -5
  130. package/dist/{chunk-EQOQOT55.js.map → chunk-IJTLXNGJ.js.map} +1 -1
  131. package/dist/{chunk-4XRP2N6B.js → chunk-JRP3VGHS.js} +3 -3
  132. package/dist/{chunk-4XRP2N6B.js.map → chunk-JRP3VGHS.js.map} +1 -1
  133. package/dist/{chunk-42XYPKZU.js → chunk-K3BUWSFR.js} +41 -3
  134. package/dist/chunk-K3BUWSFR.js.map +1 -0
  135. package/dist/{chunk-GT7NEXSU.js → chunk-KCO5EFJU.js} +3 -3
  136. package/dist/{chunk-GT7NEXSU.js.map → chunk-KCO5EFJU.js.map} +1 -1
  137. package/dist/{chunk-ARN3ZODS.cjs → chunk-KKYELPZ2.cjs} +6 -6
  138. package/dist/{chunk-ARN3ZODS.cjs.map → chunk-KKYELPZ2.cjs.map} +1 -1
  139. package/dist/{chunk-33PAKPED.cjs → chunk-MCHP7RHZ.cjs} +41 -41
  140. package/dist/{chunk-33PAKPED.cjs.map → chunk-MCHP7RHZ.cjs.map} +1 -1
  141. package/dist/{chunk-CDYRPI5U.js → chunk-MIJKEVV7.js} +4 -4
  142. package/dist/{chunk-CDYRPI5U.js.map → chunk-MIJKEVV7.js.map} +1 -1
  143. package/dist/{chunk-K2HHCWZO.cjs → chunk-NCX65HBY.cjs} +137 -108
  144. package/dist/chunk-NCX65HBY.cjs.map +1 -0
  145. package/dist/{chunk-6TJ6PKPS.cjs → chunk-NN3QSOVS.cjs} +27 -27
  146. package/dist/{chunk-6TJ6PKPS.cjs.map → chunk-NN3QSOVS.cjs.map} +1 -1
  147. package/dist/{chunk-F2KVJ6FF.cjs → chunk-OSZPLZIV.cjs} +179 -117
  148. package/dist/chunk-OSZPLZIV.cjs.map +1 -0
  149. package/dist/{chunk-UTTW2Q3M.cjs → chunk-OVUUTCPJ.cjs} +171 -133
  150. package/dist/chunk-OVUUTCPJ.cjs.map +1 -0
  151. package/dist/{chunk-FMPZPOUD.js → chunk-PAW2XUZN.js} +3 -3
  152. package/dist/{chunk-FMPZPOUD.js.map → chunk-PAW2XUZN.js.map} +1 -1
  153. package/dist/{chunk-5ZPRE4CV.cjs → chunk-PDGEXGS6.cjs} +204 -124
  154. package/dist/chunk-PDGEXGS6.cjs.map +1 -0
  155. package/dist/{chunk-CVNGKTHO.js → chunk-PHXITZE4.js} +4 -4
  156. package/dist/{chunk-CVNGKTHO.js.map → chunk-PHXITZE4.js.map} +1 -1
  157. package/dist/{chunk-ZPCKPLMX.cjs → chunk-QB6VMOJ2.cjs} +8 -8
  158. package/dist/{chunk-ZPCKPLMX.cjs.map → chunk-QB6VMOJ2.cjs.map} +1 -1
  159. package/dist/{chunk-5AERZSHC.cjs → chunk-QGKILWGZ.cjs} +4 -4
  160. package/dist/{chunk-5AERZSHC.cjs.map → chunk-QGKILWGZ.cjs.map} +1 -1
  161. package/dist/{chunk-ZOHCFYXE.js → chunk-QT6V3YRH.js} +3 -3
  162. package/dist/{chunk-ZOHCFYXE.js.map → chunk-QT6V3YRH.js.map} +1 -1
  163. package/dist/{chunk-XDMPDUKL.cjs → chunk-QYWINYEA.cjs} +9 -9
  164. package/dist/{chunk-XDMPDUKL.cjs.map → chunk-QYWINYEA.cjs.map} +1 -1
  165. package/dist/{chunk-3V6D5DEC.js → chunk-S4KQ5LV4.js} +3 -3
  166. package/dist/{chunk-3V6D5DEC.js.map → chunk-S4KQ5LV4.js.map} +1 -1
  167. package/dist/{chunk-6NB73BXV.js → chunk-SBPC5IP3.js} +40 -12
  168. package/dist/chunk-SBPC5IP3.js.map +1 -0
  169. package/dist/{chunk-HHBKGPEI.js → chunk-SQRD2CYF.js} +264 -21
  170. package/dist/chunk-SQRD2CYF.js.map +1 -0
  171. package/dist/{chunk-O7XVCLXW.cjs → chunk-ST3LPB2V.cjs} +324 -77
  172. package/dist/chunk-ST3LPB2V.cjs.map +1 -0
  173. package/dist/{chunk-FFQGI67R.cjs → chunk-STQ3BSED.cjs} +44 -44
  174. package/dist/{chunk-FFQGI67R.cjs.map → chunk-STQ3BSED.cjs.map} +1 -1
  175. package/dist/{chunk-JOYPNY33.js → chunk-TCRIQMBU.js} +9 -9
  176. package/dist/{chunk-JOYPNY33.js.map → chunk-TCRIQMBU.js.map} +1 -1
  177. package/dist/{chunk-ZP2KPDNN.js → chunk-TFMVL4QH.js} +3 -3
  178. package/dist/{chunk-ZP2KPDNN.js.map → chunk-TFMVL4QH.js.map} +1 -1
  179. package/dist/{chunk-4WYFRACU.js → chunk-TVLKA4AY.js} +3 -3
  180. package/dist/{chunk-4WYFRACU.js.map → chunk-TVLKA4AY.js.map} +1 -1
  181. package/dist/{chunk-X2XOQZT3.cjs → chunk-U5W4LKZV.cjs} +13 -9
  182. package/dist/chunk-U5W4LKZV.cjs.map +1 -0
  183. package/dist/{chunk-WYQILW5V.js → chunk-VITTKBWF.js} +43 -33
  184. package/dist/chunk-VITTKBWF.js.map +1 -0
  185. package/dist/{chunk-AO2WPYFZ.cjs → chunk-WBUFJ7BS.cjs} +4 -4
  186. package/dist/{chunk-AO2WPYFZ.cjs.map → chunk-WBUFJ7BS.cjs.map} +1 -1
  187. package/dist/{chunk-CI5NPLXX.js → chunk-XMYJY7NI.js} +3 -3
  188. package/dist/{chunk-CI5NPLXX.js.map → chunk-XMYJY7NI.js.map} +1 -1
  189. package/dist/{chunk-277UZV7X.cjs → chunk-XR4YZFKW.cjs} +1803 -1525
  190. package/dist/chunk-XR4YZFKW.cjs.map +1 -0
  191. package/dist/{chunk-5GV4JQNA.cjs → chunk-YNULOIR5.cjs} +43 -43
  192. package/dist/{chunk-5GV4JQNA.cjs.map → chunk-YNULOIR5.cjs.map} +1 -1
  193. package/dist/{chunk-ZBV4LQD2.cjs → chunk-ZTAJL4DT.cjs} +4 -4
  194. package/dist/{chunk-ZBV4LQD2.cjs.map → chunk-ZTAJL4DT.cjs.map} +1 -1
  195. package/dist/core/index.cjs +28 -28
  196. package/dist/core/index.d.cts +5 -5
  197. package/dist/core/index.d.ts +5 -5
  198. package/dist/core/index.js +8 -8
  199. package/dist/{ddl-Bc4Dl8fu.d.ts → ddl-D5369kOY.d.ts} +3 -3
  200. package/dist/{ddl-3unqC-kg.d.cts → ddl-eWg7hx6R.d.cts} +3 -3
  201. package/dist/{define-graph-Byslw2OO.d.cts → define-graph-DVF-oN1i.d.cts} +1 -1
  202. package/dist/{define-graph-DBFnc7u_.d.ts → define-graph-SvYXOl78.d.ts} +1 -1
  203. package/dist/graph-extension/index.cjs +20 -20
  204. package/dist/graph-extension/index.d.cts +4 -4
  205. package/dist/graph-extension/index.d.ts +4 -4
  206. package/dist/graph-extension/index.js +5 -5
  207. package/dist/graph-merge/index.cjs +104 -104
  208. package/dist/graph-merge/index.d.cts +9 -8
  209. package/dist/graph-merge/index.d.ts +9 -8
  210. package/dist/graph-merge/index.js +24 -24
  211. package/dist/{index-DQzVJBHa.d.ts → index-By89Sezh.d.ts} +37 -7
  212. package/dist/{index-DHXw7QAl.d.cts → index-DcQ3Sxs-.d.cts} +37 -7
  213. package/dist/index.cjs +210 -202
  214. package/dist/index.d.cts +13 -13
  215. package/dist/index.d.ts +13 -13
  216. package/dist/index.js +34 -34
  217. package/dist/indexes/index.cjs +13 -13
  218. package/dist/indexes/index.d.cts +4 -4
  219. package/dist/indexes/index.d.ts +4 -4
  220. package/dist/indexes/index.js +6 -6
  221. package/dist/interchange/index.cjs +49 -41
  222. package/dist/interchange/index.cjs.map +1 -1
  223. package/dist/interchange/index.d.cts +11 -11
  224. package/dist/interchange/index.d.ts +11 -11
  225. package/dist/interchange/index.js +23 -15
  226. package/dist/interchange/index.js.map +1 -1
  227. package/dist/{manager-Dl0-er1G.d.ts → manager-B0KjKE93.d.ts} +44 -6
  228. package/dist/{manager-U9_zopqr.d.cts → manager-Cn0NFIhN.d.cts} +44 -6
  229. package/dist/{materialize-indexes-BM3u0aXE.d.ts → materialize-indexes-BD4V3svD.d.ts} +1 -1
  230. package/dist/{materialize-indexes-DzMCetZe.d.cts → materialize-indexes-DVRhd5h4.d.cts} +1 -1
  231. package/dist/{postgres-C5-WMKFA.d.ts → postgres-DaEWvN4x.d.cts} +1 -1
  232. package/dist/{postgres-DpJqtbSX.d.cts → postgres-u0a0HN2D.d.ts} +1 -1
  233. package/dist/profiler/index.d.cts +10 -9
  234. package/dist/profiler/index.d.ts +10 -9
  235. package/dist/provenance/index.cjs +38 -38
  236. package/dist/provenance/index.cjs.map +1 -1
  237. package/dist/provenance/index.d.cts +7 -7
  238. package/dist/provenance/index.d.ts +7 -7
  239. package/dist/provenance/index.js +8 -8
  240. package/dist/provenance/index.js.map +1 -1
  241. package/dist/schema/index.cjs +41 -41
  242. package/dist/schema/index.d.cts +7 -7
  243. package/dist/schema/index.d.ts +7 -7
  244. package/dist/schema/index.js +14 -14
  245. package/dist/{searchable-B4mUXZT6.d.cts → searchable-BT7j9_IK.d.cts} +2 -2
  246. package/dist/{searchable-C7jmPNLT.d.ts → searchable-CnYEancP.d.ts} +2 -2
  247. package/dist/{sqlite-Da7jiYu9.d.cts → sqlite-BrMoSsI7.d.cts} +1 -1
  248. package/dist/{sqlite-Ch5tSYQY.d.ts → sqlite-CHhZUyO5.d.ts} +1 -1
  249. package/dist/{store-view-CNcOG8bQ.d.cts → store-view-Bvdku0Ht.d.ts} +199 -35
  250. package/dist/{store-view-6C2vTWqf.d.ts → store-view-w-md0nQ4.d.cts} +199 -35
  251. package/dist/{temporal-BtrTYTiB.d.ts → temporal--x9T8K4S.d.ts} +1 -1
  252. package/dist/{temporal-CMpigMCW.d.cts → temporal-BCORwUau.d.cts} +1 -1
  253. package/dist/{types-G4sVM-76.d.cts → types-6-WJmSD4.d.cts} +1 -1
  254. package/dist/{types-D2rU5Taq.d.ts → types-COODtTJU.d.ts} +1 -1
  255. package/dist/{types-Dh-EgT-w.d.ts → types-Cjvkj0jA.d.cts} +351 -12
  256. package/dist/{types-Dh-EgT-w.d.cts → types-Cjvkj0jA.d.ts} +351 -12
  257. package/dist/{where-B8Y21kig.d.ts → where-5xVawAwL.d.ts} +1 -1
  258. package/dist/{where-DbZ9XDOI.d.cts → where-CUQmCR6d.d.cts} +1 -1
  259. package/package.json +1 -1
  260. package/dist/chunk-277UZV7X.cjs.map +0 -1
  261. package/dist/chunk-2SO5I5AI.cjs.map +0 -1
  262. package/dist/chunk-42XYPKZU.js.map +0 -1
  263. package/dist/chunk-5P6IPIT6.cjs.map +0 -1
  264. package/dist/chunk-5Q3P6OIC.cjs.map +0 -1
  265. package/dist/chunk-5ZPRE4CV.cjs.map +0 -1
  266. package/dist/chunk-6NB73BXV.js.map +0 -1
  267. package/dist/chunk-DP7KC6CL.js.map +0 -1
  268. package/dist/chunk-ECU53PMN.cjs.map +0 -1
  269. package/dist/chunk-EVFL2ZY5.js.map +0 -1
  270. package/dist/chunk-F2KVJ6FF.cjs.map +0 -1
  271. package/dist/chunk-FY4VY5EV.cjs.map +0 -1
  272. package/dist/chunk-HHBKGPEI.js.map +0 -1
  273. package/dist/chunk-K2HHCWZO.cjs.map +0 -1
  274. package/dist/chunk-KTBTSHU6.cjs.map +0 -1
  275. package/dist/chunk-LQLVJWUH.js.map +0 -1
  276. package/dist/chunk-M4GYQF2H.js.map +0 -1
  277. package/dist/chunk-NXIZL7ZZ.js.map +0 -1
  278. package/dist/chunk-O7XVCLXW.cjs.map +0 -1
  279. package/dist/chunk-OYJSYDIH.js.map +0 -1
  280. package/dist/chunk-RAWG2FEU.js.map +0 -1
  281. package/dist/chunk-U3YRCZ5L.cjs +0 -12
  282. package/dist/chunk-UTTW2Q3M.cjs.map +0 -1
  283. package/dist/chunk-UZLEQFTV.js.map +0 -1
  284. package/dist/chunk-V2GZBPY2.cjs.map +0 -1
  285. package/dist/chunk-VGMNGWBR.cjs +0 -12
  286. package/dist/chunk-WYQILW5V.js.map +0 -1
  287. package/dist/chunk-X2XOQZT3.cjs.map +0 -1
  288. package/dist/chunk-YPVQYM3L.js.map +0 -1
  289. package/dist/chunk-ZIRC2U6G.js.map +0 -1
@@ -1,31 +1,31 @@
1
- import { createEdgeRowMapper, createNodeRowMapper, SQLITE_ROW_MAPPER_CONFIG, POSTGRES_ROW_MAPPER_CONFIG } from './chunk-CVNGKTHO.js';
2
- import { rowToNode, executeNodeBulkFindByIndex, executeNodeBulkFindByConstraint, executeNodeFindByConstraint, executeNodeBulkGetOrCreateByConstraint, executeNodeGetOrCreateByConstraint, executeNodeHardDelete, executeNodeDelete, nodeUpsertDirtyCheck, executeNodeUpsertUpdate, executeNodeUpdate, executeNodeCreateNoReturnBatch, executeNodeCreateBatch, executeNodeCreate, rowToEdge, runInWriteTransaction, checkCardinalityConstraint, runHookedWriteOperation, rowToNodeMeta, rowToEdgeMeta } from './chunk-6NB73BXV.js';
3
- import { isParameterRef, fieldRef, buildFieldBuilderForTypeInfo, stringField, createFulltextAccessor, storeRuntime, CURRENT_READ_INSTANT_PLACEHOLDER, withPinnedReadInstant, STORE_RUNTIME, assertRevisionTrackableBackend, createRecordedBackend, readRecordedClock, ensureRevisionOrigin, TRANSACTION_RUNTIME, withRecordedFlushObserver, recordedCaptureRequiresCallbackTransactionError, assertRecordedCaptureTransactionIsolation, createRecordedTransactionScope, lockRecordedGraphWrite, generateId, createGraphBackendProjection, assertCurrentRecordedSchema, baseField, objectField, arrayField, dateField, numberField, computeFulltextContent, AUTO_REFRESH_STATISTICS_ROW_THRESHOLD, advanceRevisionClock, runInsertBatch, edgeInsertDispatch, runInsertBatchReturning, projectBackendMembers, sqlValueList, getEmbeddingFields, getNodeRowsByIds, getEdgeRowsByIds, compileKindFilter, currentReadInstant, compileTemporalFilter, validateEdgeEndpoints, buildPredicateIndex, compileFieldValue, recordedBindParamBudget, extractVectorSimilarityPredicates, extractFulltextMatchPredicates, currentReadInstantFor, extractTemporalOptions, compilePredicateExpression, getPredicatesForAlias, getFieldPointer, getNodeKindsForAlias, getHybridTargetAlias, closeRecordedHardDeletedKind, throwHistoryUnsafeSqlAccess, throwRevisionTrackingUnsafeSqlAccess, compilePredicateClauses } from './chunk-EVFL2ZY5.js';
4
- import { chunk } from './chunk-35S6P5ZU.js';
5
- import { DEFAULT_SQL_SCHEMA, requireSqlSchema, recordedReadSchemaFor, createSqlSchema, requireExternalRecordedReadSource, createRecordedReadBinding, vectorSlotKey, recordedReadSqlSchema, requireRecordedReadBinding, ALIAS_CTE_PREFIX, EMBEDDINGS_CTE_ALIAS, FULLTEXT_CTE_ALIAS, HYBRID_CANDIDATES_CTE_ALIAS } from './chunk-CDYRPI5U.js';
6
- import { runOptionallyInTransaction, createTransactionReadBackend, rowPropsToObject, createBackendOverlay, INTERNAL_TEMPORARY_WRITES } from './chunk-UZLEQFTV.js';
7
- import { resolveReadCoordinate, withRecordedCoordinate, describeCoordinate, coordinateContext, recordedInstantWallTime, asRecordedInstant, assertValidRecordedInstant } from './chunk-2OOY4OYT.js';
8
- import { loadAndMergeGraphExtensionDocument, ensureSchema, loadAndVerifyGraph, buildKindRegistry, getSchemaChanges, requiresMigration, mergeGraphExtension, commitNewSchemaVersion, applyDeprecatedKinds, loadActiveSchemaWithBootstrap, parseSerializedSchema, extensionKindNames, serializeSchemaProperties, buildGraphExtensionOntologyKeySet, compileTimeOntologyKey, serializeIndexDeclaration } from './chunk-RAWG2FEU.js';
1
+ import { createEdgeRowMapper, createNodeRowMapper, SQLITE_ROW_MAPPER_CONFIG, POSTGRES_ROW_MAPPER_CONFIG } from './chunk-PHXITZE4.js';
2
+ import { rowToNode, executeNodeBulkFindByIndex, executeNodeBulkFindByConstraint, executeNodeFindByConstraint, executeNodeBulkGetOrCreateByConstraint, executeNodeGetOrCreateByConstraint, executeNodeHardDelete, executeNodeDelete, nodeUpsertDirtyCheck, executeNodeUpsertUpdate, executeNodeUpdate, executeNodeCreateNoReturnBatch, executeNodeCreateBatch, executeNodeCreate, rowToEdge, lockSchemaVersionForStoreWrite, runInWriteTransaction, checkCardinalityConstraint, runHookedWriteOperation, rowToNodeMeta, rowToEdgeMeta } from './chunk-SBPC5IP3.js';
3
+ import { isParameterRef, resolveParameterValueType, fieldRef, buildFieldBuilderForTypeInfo, stringField, createFulltextAccessor, storeRuntime, CURRENT_READ_INSTANT_PLACEHOLDER, withPinnedReadInstant, STORE_RUNTIME, assertRevisionTrackableBackend, createRecordedBackend, readRecordedClock, ensureRevisionOrigin, TRANSACTION_RUNTIME, withRecordedFlushObserver, recordedCaptureRequiresCallbackTransactionError, assertRecordedCaptureTransactionIsolation, createRecordedTransactionScope, lockRecordedGraphWrite, createGraphBackendProjection, generateId, assertCurrentRecordedSchema, baseField, objectField, arrayField, dateField, numberField, computeFulltextContent, AUTO_REFRESH_STATISTICS_ROW_THRESHOLD, advanceRevisionClock, runInsertBatch, edgeInsertDispatch, runInsertBatchReturning, projectBackendMembers, sqlValueList, getEmbeddingFields, getNodeRowsByIds, getEdgeRowsByIds, compileKindFilter, currentReadInstant, compileTemporalFilter, validateEdgeEndpoints, closeRecordedHardDeletedKind, buildPredicateIndex, compileFieldValue, recordedBindParamBudget, extractVectorSimilarityPredicates, extractFulltextMatchPredicates, currentReadInstantFor, extractTemporalOptions, compilePredicateExpression, getPredicatesForAlias, getFieldPointer, getNodeKindsForAlias, getHybridTargetAlias, throwHistoryUnsafeSqlAccess, throwRevisionTrackingUnsafeSqlAccess, compilePredicateClauses } from './chunk-FSXTPBRN.js';
4
+ import { chunk, groupBy } from './chunk-35S6P5ZU.js';
5
+ import { DEFAULT_SQL_SCHEMA, requireSqlSchema, recordedReadSchemaFor, createSqlSchema, requireExternalRecordedReadSource, createRecordedReadBinding, vectorSlotKey, recordedReadSqlSchema, requireRecordedReadBinding, ALIAS_CTE_PREFIX, EMBEDDINGS_CTE_ALIAS, FULLTEXT_CTE_ALIAS, HYBRID_CANDIDATES_CTE_ALIAS } from './chunk-MIJKEVV7.js';
6
+ import { runOptionallyInTransaction, createTransactionReadBackend, rowPropsToObject, createBackendOverlay, INTERNAL_TEMPORARY_WRITES } from './chunk-FMMIX6N4.js';
7
+ import { resolveReadCoordinate, withRecordedCoordinate, describeCoordinate, coordinateContext, recordedInstantWallTime, asRecordedInstant, assertValidRecordedInstant } from './chunk-2L54C2C2.js';
8
+ import { loadAndMergeGraphExtensionDocument, ensureSchema, loadAndVerifyGraph, buildKindRegistry, getSchemaChanges, requiresMigration, mergeGraphExtension, commitNewSchemaVersion, planRemovals, stripGraphExtension, applyDeprecatedKinds, loadActiveSchemaWithBootstrap, parseSerializedSchema, extensionKindNames, serializeSchemaProperties, buildGraphExtensionOntologyKeySet, compileTimeOntologyKey, commitNewSchemaVersionIfKindsEmpty, serializeIndexDeclaration } from './chunk-BEFM74L2.js';
9
9
  import { compareStrings, compareCodePoints } from './chunk-DRACN6XG.js';
10
- import { getTypeName } from './chunk-2HKIID5K.js';
11
- import { validateEdgeProps } from './chunk-O3USVVWS.js';
10
+ import { getTypeName } from './chunk-2Y4IFKW7.js';
11
+ import { validateEdgeProps } from './chunk-DK2S42XB.js';
12
12
  import { canonicalEqual, sortedReplacer } from './chunk-UR7W5YQK.js';
13
- import { withRecordedRelationsPrecondition, isMissingTableError } from './chunk-CUPJL6TS.js';
14
- import { isKnownKind } from './chunk-3V6D5DEC.js';
15
- import { nowIso, validateOptionalCanonicalIsoDate } from './chunk-GT7NEXSU.js';
16
- import { generateIndexDDL } from './chunk-2G6ZEGYO.js';
17
- import { SYSTEM_INDEX_DECLARATIONS, resolveSystemIndexTableName, systemIndexName, resolveSystemIndexNames, generateSystemIndexDDL } from './chunk-4XRP2N6B.js';
18
- import { NODE_META_KEYS, EDGE_META_KEYS } from './chunk-ZP2KPDNN.js';
13
+ import { withRecordedRelationsPrecondition, isMissingTableError } from './chunk-B75XRV3O.js';
14
+ import { isKnownKind } from './chunk-S4KQ5LV4.js';
15
+ import { nowIso, validateOptionalCanonicalIsoDate } from './chunk-KCO5EFJU.js';
16
+ import { generateIndexDDL } from './chunk-46GDII45.js';
17
+ import { SYSTEM_INDEX_DECLARATIONS, resolveSystemIndexTableName, systemIndexName, resolveSystemIndexNames, generateSystemIndexDDL } from './chunk-JRP3VGHS.js';
18
+ import { NODE_META_KEYS, EDGE_META_KEYS } from './chunk-TFMVL4QH.js';
19
19
  import { sha256Hex, fnv1aBase36 } from './chunk-K34OPSJK.js';
20
20
  import { DEFAULT_PAGINATION_LIMIT, DEFAULT_STREAM_BATCH_SIZE, SQLITE_PATH_DELIMITER, PG_ARRAY_START, PG_ARRAY_END, PG_PATH_ELEMENT_SEPARATOR, MAX_PG_IDENTIFIER_LENGTH } from './chunk-2EBMPJBO.js';
21
- import { getDialect, assertVectorMinScore, vectorScoreExpression, vectorMinScoreCondition } from './chunk-42XYPKZU.js';
22
- import { isSqlPlaceholder, bindSqlValue, markAnnIndexScan, asCompiledSelectSql, isRawExecutable, annIndexScanTypes, sql, asCompiledRowsSql, markForceCustomPlan, asCompiledTemporaryStatementSql, asCompiledStatementSql } from './chunk-M4GYQF2H.js';
21
+ import { getDialect, assertVectorMinScore, vectorScoreExpression, vectorMinScoreCondition } from './chunk-K3BUWSFR.js';
22
+ import { isSqlPlaceholder, bindSqlValue, markAnnIndexScan, asCompiledSelectSql, isRawExecutable, renderSql, annIndexScanTypes, sql, asCompiledRowsSql, markForceCustomPlan, asCompiledTemporaryStatementSql, asCompiledStatementSql } from './chunk-6DCB664D.js';
23
23
  import { createSchemaIntrospector } from './chunk-D7PG5D5K.js';
24
24
  import { requireDefined, isPresent } from './chunk-QMQLUA66.js';
25
25
  import { getSearchableFields, resolveEmbeddingFields, resolveGraphVectorSlots, resolveDeclaredFulltextLanguage } from './chunk-PC2UBAUB.js';
26
- import { IncompatibleChangeError, RemoveCompileTimeKindError, KindHasReferentsError } from './chunk-EQOQOT55.js';
27
- import { validateProjectionField } from './chunk-4WYFRACU.js';
28
- import { ConfigurationError, UnsupportedPredicateError, ValidationError, KindNotFoundError, EndpointError, EagerMaterializationError, CompilerInvariantError, CardinalityError, EdgeNotFoundError, DatabaseOperationError, UnsupportedBackendCapabilityError, GraphAlgorithmConvergenceError, EndpointNotFoundError, InvalidEdgeWeightError } from './chunk-OYJSYDIH.js';
26
+ import { IncompatibleChangeError } from './chunk-IJTLXNGJ.js';
27
+ import { validateProjectionField } from './chunk-TVLKA4AY.js';
28
+ import { ConfigurationError, UnsupportedPredicateError, ValidationError, KindNotFoundError, EndpointError, EagerMaterializationError, CompilerInvariantError, CardinalityError, EdgeNotFoundError, DatabaseOperationError, UnsupportedBackendCapabilityError, GraphAlgorithmConvergenceError, EndpointNotFoundError, InvalidEdgeWeightError } from './chunk-4MB3AQAQ.js';
29
29
  import { jsonPointer, parseJsonPointer, resolveJsonPointer } from './chunk-G6Q5UM7U.js';
30
30
 
31
31
  // src/store/collection-surface.ts
@@ -170,7 +170,7 @@ function createCurrentOnlyRefusal(entity, method, coordinate) {
170
170
  function createBatchReadRefusal(entity, method, coordinate) {
171
171
  return () => {
172
172
  throw new ConfigurationError(
173
- `'${method}' is not available on a read-only StoreView (${describeCoordinate(coordinate)}). Batch endpoint reads resolve through store.batch(...), which a view does not expose \u2014 use the live Store's batch loader, or the view's findFrom / findTo / findByEndpoints for single reads.`,
173
+ `'${method}' is not available on a read-only StoreView (${describeCoordinate(coordinate)}). Batch endpoint reads resolve through store.batch(...), which a view does not expose \u2014 use the live Store's batch(...), or the view's findFrom / findTo / findByEndpoints for single reads.`,
174
174
  {
175
175
  code: "STORE_VIEW_BATCH_UNAVAILABLE",
176
176
  entity,
@@ -264,6 +264,8 @@ function pinnedEdgeCollection(live, coordinate) {
264
264
  count: (filter) => live.count(filter, temporal),
265
265
  findFrom: (from) => live.findFrom(from, temporal),
266
266
  findTo: (to) => live.findTo(to, temporal),
267
+ bulkFindFrom: (froms, options) => live.bulkFindFrom(froms, { ...options, ...temporal }),
268
+ bulkFindTo: (tos, options) => live.bulkFindTo(tos, { ...options, ...temporal }),
267
269
  findByEndpoints: (from, to, options) => live.findByEndpoints(from, to, options, temporal)
268
270
  };
269
271
  return readOnlyCollectionProxy(reads, live, coordinate, "edge");
@@ -4910,7 +4912,7 @@ function compileStandardQueryWithCteStrategy(ast, graphId, ctx) {
4910
4912
  ...vectorPredicate === void 0 ? {} : { vectorPredicate },
4911
4913
  ...fulltextPredicate === void 0 ? {} : { fulltextPredicate }
4912
4914
  });
4913
- const groupBy = buildStandardGroupBy({ ast, dialect });
4915
+ const groupBy2 = buildStandardGroupBy({ ast, dialect });
4914
4916
  const having2 = buildStandardHaving({ ast, ctx });
4915
4917
  const orderBy = selectStandardOrderBy({
4916
4918
  ast,
@@ -4927,7 +4929,7 @@ function compileStandardQueryWithCteStrategy(ast, graphId, ctx) {
4927
4929
  return emitStandardQuerySql({
4928
4930
  ctes,
4929
4931
  fromClause,
4930
- ...groupBy === void 0 ? {} : { groupBy },
4932
+ ...groupBy2 === void 0 ? {} : { groupBy: groupBy2 },
4931
4933
  ...having2 === void 0 ? {} : { having: having2 },
4932
4934
  ...orderBy === void 0 ? {} : { orderBy },
4933
4935
  ...limitOffset === void 0 ? {} : { limitOffset },
@@ -5859,7 +5861,8 @@ function buildQueryTemplate(ast, graphId, compileOptions, backend) {
5859
5861
  needsReadInstant: queryAstNeedsCurrentReadInstant(ast)
5860
5862
  });
5861
5863
  }
5862
- function fillTemplateParams(params, bindings, dialect) {
5864
+ var EMPTY_LIST_PARAMETERS = /* @__PURE__ */ new Map();
5865
+ function fillTemplateParams(params, bindings, dialect, listParameters = EMPTY_LIST_PARAMETERS) {
5863
5866
  let readInstant;
5864
5867
  return params.map((parameter) => {
5865
5868
  if (!isSqlPlaceholder(parameter)) return parameter;
@@ -5874,9 +5877,20 @@ function fillTemplateParams(params, bindings, dialect) {
5874
5877
  parameterName: name
5875
5878
  });
5876
5879
  }
5880
+ if (listParameters.has(name)) {
5881
+ assertListBinding(name, value);
5882
+ return getDialect(dialect).packListValue(value);
5883
+ }
5877
5884
  return bindSqlValue(value, dialect);
5878
5885
  });
5879
5886
  }
5887
+ function assertListBinding(name, value) {
5888
+ if (Array.isArray(value)) return;
5889
+ throw new ConfigurationError(
5890
+ `Parameter "${name}" must be an array for in()/notIn()`,
5891
+ { parameterName: name, actualType: typeof value }
5892
+ );
5893
+ }
5880
5894
 
5881
5895
  // src/query/builder/prepared-query.ts
5882
5896
  function toLiteral(value) {
@@ -5903,20 +5917,21 @@ function toLiteral(value) {
5903
5917
  { parameterName: "value", actualType: typeof value }
5904
5918
  );
5905
5919
  }
5920
+ function isListComparisonOp(op) {
5921
+ return op === "in" || op === "notIn";
5922
+ }
5923
+ function toLiteralList(parameterName, value) {
5924
+ assertListBinding(parameterName, value);
5925
+ return value.map((element) => toLiteral(element));
5926
+ }
5906
5927
  function substitutePredicateExpression(expr, bindings) {
5907
5928
  switch (expr.__type) {
5908
5929
  case "comparison": {
5909
5930
  if (isParameterRef(expr.right)) {
5910
- const value = bindings[expr.right.name];
5911
- if (value === void 0) {
5912
- throw new ConfigurationError(
5913
- `Missing binding for parameter "${expr.right.name}"`,
5914
- { parameterName: expr.right.name }
5915
- );
5916
- }
5931
+ const value = resolveBinding(bindings, expr.right.name);
5917
5932
  return {
5918
5933
  ...expr,
5919
- right: toLiteral(value)
5934
+ right: isListComparisonOp(expr.op) ? toLiteralList(expr.right.name, value) : toLiteral(value)
5920
5935
  };
5921
5936
  }
5922
5937
  return expr;
@@ -6029,6 +6044,7 @@ var PreparedQuery = class {
6029
6044
  #selectFn;
6030
6045
  #schemaIntrospector;
6031
6046
  #parameterMetadata;
6047
+ #selectiveExecutionDisabled = false;
6032
6048
  /**
6033
6049
  * Per-AST cached placeholder template, keyed by AST reference so the
6034
6050
  * optimized (`#ast`) and unoptimized (`#unoptimizedAst`) variants cache
@@ -6049,6 +6065,7 @@ var PreparedQuery = class {
6049
6065
  this.#selectFn = config.selectFn;
6050
6066
  this.#schemaIntrospector = config.schemaIntrospector;
6051
6067
  this.#parameterMetadata = collectParameterMetadata(this.#ast);
6068
+ assertDistinctParameterRoles(this.#parameterMetadata);
6052
6069
  }
6053
6070
  /**
6054
6071
  * The cached placeholder template for `ast`, or `undefined` when no fast
@@ -6082,7 +6099,7 @@ var PreparedQuery = class {
6082
6099
  */
6083
6100
  async execute(bindings = {}) {
6084
6101
  validateBindings(bindings, this.#parameterMetadata);
6085
- if (this.#selectiveFields !== void 0) {
6102
+ if (this.#selectiveFields !== void 0 && !this.#selectiveExecutionDisabled) {
6086
6103
  try {
6087
6104
  const rows = await this.#executeSelectiveRows(bindings);
6088
6105
  return mapSelectiveResults(
@@ -6093,7 +6110,11 @@ var PreparedQuery = class {
6093
6110
  this.#selectFn
6094
6111
  );
6095
6112
  } catch (error) {
6096
- if (error instanceof MissingSelectiveFieldError || error instanceof UnsupportedPredicateError) {
6113
+ if (error instanceof MissingSelectiveFieldError) {
6114
+ this.#selectiveExecutionDisabled = true;
6115
+ return this.#executeUnoptimized(bindings);
6116
+ }
6117
+ if (error instanceof UnsupportedPredicateError) {
6097
6118
  return this.#executeUnoptimized(bindings);
6098
6119
  }
6099
6120
  throw error;
@@ -6128,7 +6149,8 @@ var PreparedQuery = class {
6128
6149
  const params = fillTemplateParams(
6129
6150
  template.params,
6130
6151
  bindings,
6131
- this.#dialect
6152
+ this.#dialect,
6153
+ this.#parameterMetadata.listParameters
6132
6154
  );
6133
6155
  const rawRows2 = await executeRaw(
6134
6156
  template.sql,
@@ -6147,10 +6169,46 @@ var PreparedQuery = class {
6147
6169
  }
6148
6170
  };
6149
6171
  function collectParameterMetadata(ast) {
6150
- const names = /* @__PURE__ */ new Set();
6151
- const stringOpParameters = /* @__PURE__ */ new Set();
6152
- collectParameterMetadataFromAst(ast, names, stringOpParameters);
6153
- return { names, stringOpParameters };
6172
+ const accumulator = {
6173
+ names: /* @__PURE__ */ new Set(),
6174
+ stringOpParameters: /* @__PURE__ */ new Set(),
6175
+ listParameters: /* @__PURE__ */ new Map(),
6176
+ scalarParameters: /* @__PURE__ */ new Set(),
6177
+ conflictingElementTypes: /* @__PURE__ */ new Set()
6178
+ };
6179
+ collectParameterMetadataFromAst(ast, accumulator);
6180
+ return accumulator;
6181
+ }
6182
+ function assertDistinctParameterRoles(metadata) {
6183
+ if (metadata.conflictingElementTypes.size > 0) {
6184
+ const names = [...metadata.conflictingElementTypes];
6185
+ throw new ConfigurationError(
6186
+ `Parameter${names.length === 1 ? "" : "s"} ${names.map((name) => `"${name}"`).join(", ")} bound as an in()/notIn() list against fields of different types; one list cannot satisfy both`,
6187
+ { conflictingParameters: names }
6188
+ );
6189
+ }
6190
+ const conflicting = [...metadata.listParameters.keys()].filter(
6191
+ (name) => metadata.scalarParameters.has(name)
6192
+ );
6193
+ if (conflicting.length === 0) return;
6194
+ throw new ConfigurationError(
6195
+ `Parameter${conflicting.length === 1 ? "" : "s"} ${conflicting.map((name) => `"${name}"`).join(", ")} used both as an in()/notIn() list and as a scalar value`,
6196
+ { conflictingParameters: conflicting }
6197
+ );
6198
+ }
6199
+ function recordListElementType(accumulator, name, elementType) {
6200
+ if (!accumulator.listParameters.has(name)) {
6201
+ accumulator.listParameters.set(name, elementType);
6202
+ return;
6203
+ }
6204
+ const existing = accumulator.listParameters.get(name);
6205
+ if (existing === void 0) {
6206
+ accumulator.listParameters.set(name, elementType);
6207
+ return;
6208
+ }
6209
+ if (elementType !== void 0 && elementType !== existing) {
6210
+ accumulator.conflictingElementTypes.add(name);
6211
+ }
6154
6212
  }
6155
6213
  function hasParameterReferences(ast) {
6156
6214
  return collectParameterMetadata(ast).names.size > 0;
@@ -6161,63 +6219,58 @@ function composableQueryHasParameterReferences(query) {
6161
6219
  }
6162
6220
  return hasParameterReferences(query);
6163
6221
  }
6164
- function collectParameterMetadataFromAst(ast, names, stringOpParameters) {
6222
+ function collectParameterMetadataFromAst(ast, accumulator) {
6165
6223
  for (const predicate of ast.predicates) {
6166
- collectParameterMetadataFromExpression(
6167
- predicate.expression,
6168
- names,
6169
- stringOpParameters
6170
- );
6224
+ collectParameterMetadataFromExpression(predicate.expression, accumulator);
6171
6225
  }
6172
6226
  if (ast.having !== void 0) {
6173
- collectParameterMetadataFromExpression(
6174
- ast.having,
6175
- names,
6176
- stringOpParameters
6177
- );
6227
+ collectParameterMetadataFromExpression(ast.having, accumulator);
6178
6228
  }
6179
6229
  }
6180
- function collectParameterMetadataFromExpression(expression, names, stringOpParameters) {
6230
+ function collectParameterMetadataFromExpression(expression, accumulator) {
6181
6231
  switch (expression.__type) {
6182
6232
  case "comparison": {
6183
6233
  if (isParameterRef(expression.right)) {
6184
- names.add(expression.right.name);
6234
+ const name = expression.right.name;
6235
+ accumulator.names.add(name);
6236
+ if (isListComparisonOp(expression.op)) {
6237
+ recordListElementType(
6238
+ accumulator,
6239
+ name,
6240
+ resolveParameterValueType(expression.left, expression.right)
6241
+ );
6242
+ } else {
6243
+ accumulator.scalarParameters.add(name);
6244
+ }
6185
6245
  }
6186
6246
  return;
6187
6247
  }
6188
6248
  case "string_op": {
6189
6249
  if (isParameterRef(expression.pattern)) {
6190
- names.add(expression.pattern.name);
6191
- stringOpParameters.add(expression.pattern.name);
6250
+ accumulator.names.add(expression.pattern.name);
6251
+ accumulator.scalarParameters.add(expression.pattern.name);
6252
+ accumulator.stringOpParameters.add(expression.pattern.name);
6192
6253
  }
6193
6254
  return;
6194
6255
  }
6195
6256
  case "between": {
6196
- if (isParameterRef(expression.lower)) {
6197
- names.add(expression.lower.name);
6198
- }
6199
- if (isParameterRef(expression.upper)) {
6200
- names.add(expression.upper.name);
6257
+ for (const bound of [expression.lower, expression.upper]) {
6258
+ if (isParameterRef(bound)) {
6259
+ accumulator.names.add(bound.name);
6260
+ accumulator.scalarParameters.add(bound.name);
6261
+ }
6201
6262
  }
6202
6263
  return;
6203
6264
  }
6204
6265
  case "and":
6205
6266
  case "or": {
6206
6267
  for (const predicate of expression.predicates) {
6207
- collectParameterMetadataFromExpression(
6208
- predicate,
6209
- names,
6210
- stringOpParameters
6211
- );
6268
+ collectParameterMetadataFromExpression(predicate, accumulator);
6212
6269
  }
6213
6270
  return;
6214
6271
  }
6215
6272
  case "not": {
6216
- collectParameterMetadataFromExpression(
6217
- expression.predicate,
6218
- names,
6219
- stringOpParameters
6220
- );
6273
+ collectParameterMetadataFromExpression(expression.predicate, accumulator);
6221
6274
  return;
6222
6275
  }
6223
6276
  case "null_check":
@@ -6228,26 +6281,15 @@ function collectParameterMetadataFromExpression(expression, names, stringOpParam
6228
6281
  case "fulltext_match": {
6229
6282
  return;
6230
6283
  }
6231
- case "exists": {
6232
- collectParameterMetadataFromAst(
6233
- expression.subquery,
6234
- names,
6235
- stringOpParameters
6236
- );
6237
- return;
6238
- }
6284
+ case "exists":
6239
6285
  case "in_subquery": {
6240
- collectParameterMetadataFromAst(
6241
- expression.subquery,
6242
- names,
6243
- stringOpParameters
6244
- );
6286
+ collectParameterMetadataFromAst(expression.subquery, accumulator);
6245
6287
  return;
6246
6288
  }
6247
6289
  }
6248
6290
  }
6249
6291
  function validateBindings(bindings, metadata) {
6250
- const { names: expectedNames, stringOpParameters } = metadata;
6292
+ const { names: expectedNames, stringOpParameters, listParameters } = metadata;
6251
6293
  const missing = [];
6252
6294
  for (const name of expectedNames) {
6253
6295
  if (bindings[name] === void 0) {
@@ -6271,9 +6313,53 @@ function validateBindings(bindings, metadata) {
6271
6313
  }
6272
6314
  for (const name of expectedNames) {
6273
6315
  const value = bindings[name];
6316
+ if (listParameters.has(name)) {
6317
+ validateListBinding(name, value, listParameters.get(name));
6318
+ continue;
6319
+ }
6274
6320
  validateBindingValue(name, value, stringOpParameters.has(name));
6275
6321
  }
6276
6322
  }
6323
+ function validateListBinding(name, value, elementType) {
6324
+ assertListBinding(name, value);
6325
+ for (const element of value) {
6326
+ validateBindingValue(name, element, false);
6327
+ if (elementType === void 0) continue;
6328
+ if (matchesElementType(element, elementType)) continue;
6329
+ throw new ConfigurationError(
6330
+ `Parameter "${name}" is bound against a ${elementType} field, so every element must be a ${elementType}; got ${describeBindingType(element)}`,
6331
+ { parameterName: name, valueType: elementType }
6332
+ );
6333
+ }
6334
+ }
6335
+ function matchesElementType(value, elementType) {
6336
+ switch (elementType) {
6337
+ case "string": {
6338
+ return typeof value === "string";
6339
+ }
6340
+ case "number": {
6341
+ return typeof value === "number";
6342
+ }
6343
+ case "boolean": {
6344
+ return typeof value === "boolean";
6345
+ }
6346
+ case "date": {
6347
+ return value instanceof Date || typeof value === "string";
6348
+ }
6349
+ // No element cast is emitted for these, so there is no divergence to
6350
+ // prevent — `array`/`object` are rejected earlier, at compile time.
6351
+ case "array":
6352
+ case "object":
6353
+ case "embedding":
6354
+ case "unknown": {
6355
+ return true;
6356
+ }
6357
+ }
6358
+ }
6359
+ function describeBindingType(value) {
6360
+ if (value instanceof Date) return "date";
6361
+ return typeof value;
6362
+ }
6277
6363
  function validateBindingValue(name, value, isStringOp) {
6278
6364
  if (value === null) {
6279
6365
  throw new ConfigurationError(
@@ -6290,7 +6376,16 @@ function validateBindingValue(name, value, isStringOp) {
6290
6376
  }
6291
6377
  return;
6292
6378
  }
6293
- if (value instanceof Date || typeof value === "string" || typeof value === "number" || typeof value === "boolean") {
6379
+ if (typeof value === "number") {
6380
+ if (!Number.isFinite(value)) {
6381
+ throw new ConfigurationError(
6382
+ `Parameter "${name}" must be a finite number, got ${String(value)}`,
6383
+ { parameterName: name, actualType: "number" }
6384
+ );
6385
+ }
6386
+ return;
6387
+ }
6388
+ if (value instanceof Date || typeof value === "string" || typeof value === "boolean") {
6294
6389
  return;
6295
6390
  }
6296
6391
  throw new ConfigurationError(
@@ -6867,7 +6962,9 @@ var ExecutableQuery = class _ExecutableQuery {
6867
6962
  * validates the AST once (a malformed query fails fast, here, instead of on
6868
6963
  * first use); the prepared query then compiles once into a reusable template
6869
6964
  * and fills a fresh read instant per execute() — see PreparedQuery's class
6870
- * doc comment.
6965
+ * doc comment, which also covers the two cases that recompile per call
6966
+ * instead (no `executeRaw`, or a statement whose semantics ride on the SQL
6967
+ * object rather than its text).
6871
6968
  *
6872
6969
  * Use `param("name")` in predicates to create parameterized slots,
6873
6970
  * then pass values via `prepared.execute({ name: "value" })`.
@@ -7024,9 +7121,15 @@ var ExecutableQuery = class _ExecutableQuery {
7024
7121
  /**
7025
7122
  * Executes the query against a provided backend.
7026
7123
  *
7027
- * Used by `store.batch()` to run multiple queries over a single connection
7028
- * (e.g., within a transaction). The full compile → execute → transform
7029
- * pipeline runs identically to `execute()`, but against the given backend.
7124
+ * Used by `store.batch()` to run several queries in sequence against one
7125
+ * target — a transaction on backends that have them, the backend itself
7126
+ * otherwise. The full compile → execute → transform pipeline runs
7127
+ * identically to `execute()`, but against the given backend.
7128
+ *
7129
+ * Costs one statement, or two when the selective-field path runs and its
7130
+ * mapping then falls back: `#tryOptimizedExecutionOn` detects that only
7131
+ * after its statement has executed, and the caller re-runs the full fetch.
7132
+ * The fallback clears the fast path for this instance.
7030
7133
  */
7031
7134
  async executeOn(backend) {
7032
7135
  const ast = this.toAst();
@@ -7133,29 +7236,15 @@ var ExecutableQuery = class _ExecutableQuery {
7133
7236
  const hasOptionalTraversal = this.#state.traversals.some(
7134
7237
  (traversal) => traversal.optional
7135
7238
  );
7136
- const trackingRuns = hasOptionalTraversal ? [
7137
- {
7138
- mode: "truthy",
7139
- optionalTraversalAliases: "present"
7140
- },
7141
- {
7142
- mode: "falsy",
7143
- optionalTraversalAliases: "present"
7144
- },
7145
- {
7146
- mode: "falsy",
7147
- optionalTraversalAliases: "absent"
7148
- }
7149
- ] : [
7150
- {
7151
- mode: "truthy",
7152
- optionalTraversalAliases: "present"
7153
- },
7154
- {
7155
- mode: "falsy",
7156
- optionalTraversalAliases: "present"
7157
- }
7239
+ const presentTrackingRuns = [
7240
+ { mode: "truthy", optionalTraversalAliases: "present" },
7241
+ { mode: "max", optionalTraversalAliases: "present" },
7242
+ { mode: "falsy", optionalTraversalAliases: "present" }
7158
7243
  ];
7244
+ const trackingRuns = hasOptionalTraversal ? [
7245
+ ...presentTrackingRuns,
7246
+ { mode: "falsy", optionalTraversalAliases: "absent" }
7247
+ ] : presentTrackingRuns;
7159
7248
  for (const run of trackingRuns) {
7160
7249
  const trackingContext = createTrackingContext(this.#state, tracker, {
7161
7250
  schemaIntrospector: this.#config.schemaIntrospector,
@@ -9160,7 +9249,11 @@ var UnionableQuery = class _UnionableQuery {
9160
9249
  /**
9161
9250
  * Executes the combined query against a provided backend.
9162
9251
  *
9163
- * Used by `store.batch()` to run multiple queries over a single connection.
9252
+ * Used by `store.batch()` to run several queries in sequence against one
9253
+ * target — a transaction on backends that have them, the backend itself
9254
+ * otherwise. A set operation compiles to one statement; whether that target
9255
+ * is a shared connection is the adapter's business, not a function of
9256
+ * transaction support.
9164
9257
  */
9165
9258
  async executeOn(backend) {
9166
9259
  const ast = this.toAst();
@@ -10701,183 +10794,6 @@ function classifyUnique(kind, existing, next, recorders) {
10701
10794
  }
10702
10795
  }
10703
10796
 
10704
- // src/graph-extension/remove.ts
10705
- function planRemovals(graph, names) {
10706
- const document = graph.extension;
10707
- const namesSet = new Set(names);
10708
- if (namesSet.size === 0) {
10709
- return { document, removedNodeKinds: [], removedEdgeKinds: [] };
10710
- }
10711
- const { nodes: runtimeNodeNames, edges: runtimeEdgeNames } = extensionKindNames(document);
10712
- const compileTimeNodeNames = new Set(
10713
- Object.keys(graph.nodes).filter((name) => !runtimeNodeNames.has(name))
10714
- );
10715
- const compileTimeEdgeNames = new Set(
10716
- Object.keys(graph.edges).filter((name) => !runtimeEdgeNames.has(name))
10717
- );
10718
- for (const name of namesSet) {
10719
- if (compileTimeNodeNames.has(name)) {
10720
- throw new RemoveCompileTimeKindError(name, "node", graph.id);
10721
- }
10722
- if (compileTimeEdgeNames.has(name)) {
10723
- throw new RemoveCompileTimeKindError(name, "edge", graph.id);
10724
- }
10725
- }
10726
- const removedNodeKinds = [...namesSet].filter(
10727
- (name) => runtimeNodeNames.has(name)
10728
- );
10729
- const explicitlyRemovedEdgeKinds = [...namesSet].filter(
10730
- (name) => runtimeEdgeNames.has(name)
10731
- );
10732
- const referentsByKind = buildCompileTimeReferentIndex(
10733
- graph,
10734
- runtimeEdgeNames
10735
- );
10736
- for (const kindName of removedNodeKinds) {
10737
- const referents = referentsByKind.get(kindName);
10738
- if (referents !== void 0 && referents.length > 0) {
10739
- throw new KindHasReferentsError(kindName, referents, graph.id);
10740
- }
10741
- }
10742
- if (document === void 0) {
10743
- return {
10744
- document: void 0,
10745
- removedNodeKinds: [],
10746
- removedEdgeKinds: []
10747
- };
10748
- }
10749
- const removedNodeKindsSet = new Set(removedNodeKinds);
10750
- const explicitlyRemovedEdgeKindsSet = new Set(explicitlyRemovedEdgeKinds);
10751
- const cascadeEdges = /* @__PURE__ */ new Set();
10752
- const updatedEdges = {};
10753
- for (const [edgeName, edgeDocument] of Object.entries(document.edges ?? {})) {
10754
- if (explicitlyRemovedEdgeKindsSet.has(edgeName)) {
10755
- cascadeEdges.add(edgeName);
10756
- continue;
10757
- }
10758
- const newFrom = edgeDocument.from.filter(
10759
- (kind) => !removedNodeKindsSet.has(kind)
10760
- );
10761
- const newTo = edgeDocument.to.filter(
10762
- (kind) => !removedNodeKindsSet.has(kind)
10763
- );
10764
- if (newFrom.length === 0 || newTo.length === 0) {
10765
- cascadeEdges.add(edgeName);
10766
- continue;
10767
- }
10768
- updatedEdges[edgeName] = {
10769
- ...edgeDocument,
10770
- from: newFrom,
10771
- to: newTo
10772
- };
10773
- }
10774
- const updatedNodes = {};
10775
- for (const [nodeName, nodeDocument] of Object.entries(document.nodes ?? {})) {
10776
- if (removedNodeKindsSet.has(nodeName)) continue;
10777
- updatedNodes[nodeName] = nodeDocument;
10778
- }
10779
- const survivingOntology = (document.ontology ?? []).filter(
10780
- (relation) => !removedNodeKindsSet.has(relation.from) && !removedNodeKindsSet.has(relation.to)
10781
- );
10782
- const allRemovedKinds = /* @__PURE__ */ new Set([
10783
- ...removedNodeKindsSet,
10784
- ...cascadeEdges,
10785
- ...explicitlyRemovedEdgeKindsSet
10786
- ]);
10787
- const survivingIndexes = (document.indexes ?? []).filter(
10788
- (index) => !allRemovedKinds.has(index.kind)
10789
- );
10790
- const newDocument = Object.freeze({
10791
- ...document.version === void 0 ? {} : { version: document.version },
10792
- ...Object.keys(updatedNodes).length === 0 ? {} : { nodes: updatedNodes },
10793
- ...Object.keys(updatedEdges).length === 0 ? {} : { edges: updatedEdges },
10794
- ...survivingOntology.length === 0 ? {} : { ontology: survivingOntology },
10795
- ...survivingIndexes.length === 0 ? {} : { indexes: survivingIndexes }
10796
- });
10797
- return {
10798
- document: newDocument,
10799
- removedNodeKinds,
10800
- removedEdgeKinds: [
10801
- ...explicitlyRemovedEdgeKinds,
10802
- ...[...cascadeEdges].filter(
10803
- (name) => !explicitlyRemovedEdgeKindsSet.has(name)
10804
- )
10805
- ]
10806
- };
10807
- }
10808
- function stripGraphExtension(graph) {
10809
- const document = graph.extension;
10810
- if (document === void 0) return graph;
10811
- const { nodes: runtimeNodeNames, edges: runtimeEdgeNames } = extensionKindNames(document);
10812
- const runtimeOntologyKeys = buildGraphExtensionOntologyKeySet(document);
10813
- const compileNodes = {};
10814
- for (const [name, registration] of Object.entries(graph.nodes)) {
10815
- if (runtimeNodeNames.has(name)) continue;
10816
- compileNodes[name] = registration;
10817
- }
10818
- const compileEdges = {};
10819
- for (const [name, registration] of Object.entries(graph.edges)) {
10820
- if (runtimeEdgeNames.has(name)) continue;
10821
- compileEdges[name] = registration;
10822
- }
10823
- const compileOntology = graph.ontology.filter(
10824
- (relation) => !runtimeOntologyKeys.has(compileTimeOntologyKey(relation))
10825
- );
10826
- const compileIndexes = (graph.indexes ?? []).filter(
10827
- (index) => index.origin !== "runtime"
10828
- );
10829
- return Object.freeze({
10830
- ...graph,
10831
- nodes: compileNodes,
10832
- edges: compileEdges,
10833
- ontology: compileOntology,
10834
- indexes: compileIndexes.length === 0 ? void 0 : compileIndexes,
10835
- extension: void 0
10836
- });
10837
- }
10838
- function buildCompileTimeReferentIndex(graph, runtimeEdgeNames) {
10839
- const index = /* @__PURE__ */ new Map();
10840
- const append = (kindName, referent) => {
10841
- const existing = index.get(kindName);
10842
- if (existing === void 0) index.set(kindName, [referent]);
10843
- else existing.push(referent);
10844
- };
10845
- for (const [edgeName, registration] of Object.entries(graph.edges)) {
10846
- if (runtimeEdgeNames.has(edgeName)) continue;
10847
- const reg = registration;
10848
- const referent = {
10849
- type: "compile-time-edge",
10850
- name: edgeName
10851
- };
10852
- const seen = /* @__PURE__ */ new Set();
10853
- for (const endpoint of reg.from ?? []) {
10854
- if (seen.has(endpoint.kind)) continue;
10855
- seen.add(endpoint.kind);
10856
- append(endpoint.kind, referent);
10857
- }
10858
- for (const endpoint of reg.to ?? []) {
10859
- if (seen.has(endpoint.kind)) continue;
10860
- seen.add(endpoint.kind);
10861
- append(endpoint.kind, referent);
10862
- }
10863
- }
10864
- const runtimeOntologyKeys = buildGraphExtensionOntologyKeySet(
10865
- graph.extension
10866
- );
10867
- for (const relation of graph.ontology) {
10868
- if (runtimeOntologyKeys.has(compileTimeOntologyKey(relation))) continue;
10869
- const fromName = getTypeName(relation.from);
10870
- const toName = getTypeName(relation.to);
10871
- const referent = {
10872
- type: "compile-time-ontology",
10873
- name: `${relation.metaEdge.name}(${fromName}, ${toName})`
10874
- };
10875
- append(fromName, referent);
10876
- if (toName !== fromName) append(toName, referent);
10877
- }
10878
- return index;
10879
- }
10880
-
10881
10797
  // src/store/algorithms/context.ts
10882
10798
  var DEFAULT_ALGORITHM_MAX_HOPS = 10;
10883
10799
  var DEFAULT_NEIGHBOR_DEPTH = 1;
@@ -13530,6 +13446,36 @@ function buildUpdateEdgeInput(id, props, options) {
13530
13446
  if (options?.validTo !== void 0) input.validTo = options.validTo;
13531
13447
  return input;
13532
13448
  }
13449
+ function endpointKey(endpointKind, id) {
13450
+ return `${endpointKind}\0${id}`;
13451
+ }
13452
+ function groupEndpointIdsByKind(references) {
13453
+ const referencesByKind = groupBy(references, (ref) => ref.kind);
13454
+ return new Map(
13455
+ [...referencesByKind].map(([endpointKind, group]) => [
13456
+ endpointKind,
13457
+ group.map((ref) => ref.id)
13458
+ ])
13459
+ );
13460
+ }
13461
+ function assertLimitPerInput(kind, limitPerInput) {
13462
+ if (limitPerInput === void 0) return;
13463
+ if (Number.isInteger(limitPerInput) && limitPerInput > 0) return;
13464
+ throw new ValidationError(
13465
+ "bulk endpoint reads require limitPerInput to be a positive integer",
13466
+ {
13467
+ entityType: "edge",
13468
+ kind,
13469
+ issues: [
13470
+ {
13471
+ path: "limitPerInput",
13472
+ message: `Expected a positive integer, received ${String(limitPerInput)}`,
13473
+ code: "invalid_value"
13474
+ }
13475
+ ]
13476
+ }
13477
+ );
13478
+ }
13533
13479
  function mapBulkEdgeInputs(kind, items) {
13534
13480
  return items.map(
13535
13481
  (item) => buildCreateEdgeInput(kind, item.from, item.to, item.props ?? {}, item)
@@ -13552,29 +13498,74 @@ function createEdgeCollection(config) {
13552
13498
  temporalRowMatcher
13553
13499
  } = config;
13554
13500
  const mapRows = (rows) => rows.map((row) => narrowEdge(rowToEdge2(row)));
13555
- function buildEndpointFindParams(endpoint, options) {
13556
- return {
13557
- graphId,
13558
- kind,
13559
- ...endpoint,
13560
- ...resolveTemporalReadParams(options, defaultTemporalMode)
13561
- };
13501
+ function buildEndpointFindParams(endpoint, temporal) {
13502
+ return { graphId, kind, ...endpoint, ...temporal };
13562
13503
  }
13563
13504
  async function findEdgesFrom(from, target, options) {
13564
13505
  const rows = await target.findEdgesByKind(
13565
13506
  buildEndpointFindParams(
13566
13507
  { fromKind: from.kind, fromId: from.id },
13567
- options
13508
+ resolveTemporalReadParams(options, defaultTemporalMode)
13568
13509
  )
13569
13510
  );
13570
13511
  return mapRows(rows);
13571
13512
  }
13572
13513
  async function findEdgesTo(to, target, options) {
13573
13514
  const rows = await target.findEdgesByKind(
13574
- buildEndpointFindParams({ toKind: to.kind, toId: to.id }, options)
13515
+ buildEndpointFindParams(
13516
+ { toKind: to.kind, toId: to.id },
13517
+ resolveTemporalReadParams(options, defaultTemporalMode)
13518
+ )
13575
13519
  );
13576
13520
  return mapRows(rows);
13577
13521
  }
13522
+ async function findEdgesByEndpointSet(side, references, options) {
13523
+ if (references.length === 0) return [];
13524
+ const method = side === "from" ? "bulkFindFrom" : "bulkFindTo";
13525
+ const readEndpointSet = backend.findEdgesByEndpointSet;
13526
+ if (readEndpointSet === void 0) {
13527
+ throw new ConfigurationError(
13528
+ `store.edges.${kind}.${method}() requires a backend that can read a set of endpoints with set-oriented statements, and this backend does not implement findEdgesByEndpointSet.`,
13529
+ {
13530
+ backend: backend.dialect,
13531
+ capability: "findEdgesByEndpointSet",
13532
+ kind,
13533
+ operation: method
13534
+ },
13535
+ {
13536
+ suggestion: `Falling back to one findFrom/findTo per endpoint is deliberately NOT done here: a caller reaching for a bulk endpoint read is asking for a set-oriented read, and silently issuing N singleton statements is the cost surprise this method exists to avoid. Loop over findFrom/findTo explicitly if that trade is acceptable.`
13537
+ }
13538
+ );
13539
+ }
13540
+ const limitPerInput = options?.limitPerInput;
13541
+ assertLimitPerInput(kind, limitPerInput);
13542
+ const temporal = resolveTemporalReadParams(options, defaultTemporalMode);
13543
+ const limitPerEndpoint = limitPerInput !== void 0 && backend.capabilities.windowFunctions ? { limitPerEndpoint: limitPerInput } : {};
13544
+ const edgesByEndpoint = /* @__PURE__ */ new Map();
13545
+ for (const [endpointKind, endpointIds] of groupEndpointIdsByKind(
13546
+ references
13547
+ )) {
13548
+ const rows = await readEndpointSet({
13549
+ graphId,
13550
+ kind,
13551
+ side,
13552
+ endpointKind,
13553
+ endpointIds,
13554
+ ...limitPerEndpoint,
13555
+ ...temporal
13556
+ });
13557
+ for (const edge of mapRows(rows)) {
13558
+ const key = side === "from" ? endpointKey(edge.fromKind, edge.fromId) : endpointKey(edge.toKind, edge.toId);
13559
+ const bucket = edgesByEndpoint.get(key);
13560
+ if (bucket === void 0) edgesByEndpoint.set(key, [edge]);
13561
+ else bucket.push(edge);
13562
+ }
13563
+ }
13564
+ return references.map((ref) => {
13565
+ const bucket = edgesByEndpoint.get(endpointKey(ref.kind, ref.id)) ?? [];
13566
+ return limitPerInput === void 0 ? [...bucket] : bucket.slice(0, limitPerInput);
13567
+ });
13568
+ }
13578
13569
  function buildFindByEndpointsOptions(options, temporal) {
13579
13570
  const result = { ...resolveTemporalReadParams(temporal, defaultTemporalMode) };
13580
13571
  if (options?.matchOn !== void 0)
@@ -13622,6 +13613,12 @@ function createEdgeCollection(config) {
13622
13613
  async findTo(to, options) {
13623
13614
  return findEdgesTo(to, backend, options);
13624
13615
  },
13616
+ async bulkFindFrom(froms, options) {
13617
+ return findEdgesByEndpointSet("from", froms, options);
13618
+ },
13619
+ async bulkFindTo(tos, options) {
13620
+ return findEdgesByEndpointSet("to", tos, options);
13621
+ },
13625
13622
  batchFindFrom(from, options) {
13626
13623
  return { executeOn: (target) => findEdgesFrom(from, target, options) };
13627
13624
  },
@@ -13830,11 +13827,18 @@ function createEdgeCollection(config) {
13830
13827
  return result === void 0 ? void 0 : narrowEdge(result);
13831
13828
  },
13832
13829
  async getOrCreateByEndpoints(from, to, props, options) {
13833
- const getOrCreateOptions = {};
13834
- if (options?.matchOn !== void 0)
13835
- getOrCreateOptions.matchOn = options.matchOn;
13836
- if (options?.ifExists !== void 0)
13837
- getOrCreateOptions.ifExists = options.ifExists;
13830
+ const getOrCreateOptions = {
13831
+ ...options?.matchOn !== void 0 && {
13832
+ matchOn: options.matchOn
13833
+ },
13834
+ ...options?.ifExists !== void 0 && {
13835
+ ifExists: options.ifExists
13836
+ },
13837
+ ...options?.validFrom !== void 0 && {
13838
+ validFrom: options.validFrom
13839
+ },
13840
+ ...options?.validTo !== void 0 && { validTo: options.validTo }
13841
+ };
13838
13842
  const result = await config.executeGetOrCreateByEndpoints(
13839
13843
  kind,
13840
13844
  from.kind,
@@ -13854,13 +13858,18 @@ function createEdgeCollection(config) {
13854
13858
  fromId: item.from.id,
13855
13859
  toKind: item.to.kind,
13856
13860
  toId: item.to.id,
13857
- props: item.props
13861
+ props: item.props,
13862
+ ...item.validFrom !== void 0 && { validFrom: item.validFrom },
13863
+ ...item.validTo !== void 0 && { validTo: item.validTo }
13858
13864
  }));
13859
- const getOrCreateOptions = {};
13860
- if (options?.matchOn !== void 0)
13861
- getOrCreateOptions.matchOn = options.matchOn;
13862
- if (options?.ifExists !== void 0)
13863
- getOrCreateOptions.ifExists = options.ifExists;
13865
+ const getOrCreateOptions = {
13866
+ ...options?.matchOn !== void 0 && {
13867
+ matchOn: options.matchOn
13868
+ },
13869
+ ...options?.ifExists !== void 0 && {
13870
+ ifExists: options.ifExists
13871
+ }
13872
+ };
13864
13873
  const getOrCreateAll = async (target) => {
13865
13874
  const results = await config.executeBulkGetOrCreateByEndpoints(
13866
13875
  kind,
@@ -14314,6 +14323,8 @@ var HISTORY_STORE_BACKEND_KEYS = [
14314
14323
  "claimIndexMaterialization",
14315
14324
  "close",
14316
14325
  "commitSchemaVersion",
14326
+ "commitSchemaVersionIfKindsEmpty",
14327
+ "lockSchemaVersionForWrite",
14317
14328
  "compileSql",
14318
14329
  "countEdgesByKind",
14319
14330
  "countEdgesFrom",
@@ -14342,6 +14353,7 @@ var HISTORY_STORE_BACKEND_KEYS = [
14342
14353
  "execute",
14343
14354
  "executeTemporaryStatement",
14344
14355
  "findEdgesByKind",
14356
+ "findEdgesByEndpointSet",
14345
14357
  "findEdgesConnectedTo",
14346
14358
  "findNodesByKind",
14347
14359
  "fulltextSearch",
@@ -14387,7 +14399,8 @@ var HISTORY_STORE_BACKEND_KEYS = [
14387
14399
  "upsertFulltext",
14388
14400
  "upsertFulltextBatch",
14389
14401
  "vectorSearch",
14390
- "vectorStrategy"
14402
+ "vectorStrategy",
14403
+ "verifyContributions"
14391
14404
  ];
14392
14405
  function createHistoryStoreBackendProjection(backend) {
14393
14406
  return Object.freeze(
@@ -14489,18 +14502,6 @@ async function runBucketedMaterialization(items, options, bucketKey, runOne) {
14489
14502
  );
14490
14503
  return results;
14491
14504
  }
14492
- async function runMaterialization(items, options, runOne) {
14493
- if (options.stopOnError === true) {
14494
- const results = [];
14495
- for (const item of items) {
14496
- const entry2 = await runOne(item);
14497
- results.push(entry2);
14498
- if (entry2.status === "failed") break;
14499
- }
14500
- return results;
14501
- }
14502
- return Promise.all(items.map((item) => runOne(item)));
14503
- }
14504
14505
 
14505
14506
  // src/store/materialize-indexes.ts
14506
14507
  var CLAIM_LEASE_MS = 15 * 6e4;
@@ -15204,21 +15205,38 @@ function buildPendingKindRemoval(args) {
15204
15205
  }
15205
15206
  async function materializeRemovals(context, options = {}) {
15206
15207
  const { backend, graphId } = context;
15207
- if (backend.executeDdl === void 0 || backend.recordKindRemoval === void 0 || backend.getPendingKindRemovals === void 0) {
15208
+ if (backend.recordKindRemoval === void 0 || backend.getPendingKindRemovals === void 0) {
15208
15209
  throw new ConfigurationError(
15209
- "store.materializeRemovals() requires a backend with kind-removal primitives (executeDdl, recordKindRemoval, getPendingKindRemovals). The bundled SQLite and Postgres backends provide them.",
15210
+ "store.materializeRemovals() requires a backend with kind-removal primitives (recordKindRemoval, getPendingKindRemovals). The bundled SQLite and Postgres backends provide them.",
15210
15211
  { code: "MATERIALIZE_REMOVALS_BACKEND_UNSUPPORTED" }
15211
15212
  );
15212
15213
  }
15213
15214
  await ensureFocusedStatusTable(backend, backend.ensureKindRemovalsTable);
15214
15215
  await reconcilePendingRemovals(context);
15215
- const reclaimedVectorFields = await reclaimRemovedVectorFieldTables(context);
15216
+ const activeRow = await backend.getActiveSchema(graphId);
15217
+ const activeSchema = activeRow === void 0 ? void 0 : parseSerializedSchema(activeRow.schema_doc);
15218
+ const reclaimedVectorFields = await reclaimRemovedVectorFieldTables(
15219
+ context,
15220
+ activeRow
15221
+ );
15216
15222
  const pending = await backend.getPendingKindRemovals(graphId);
15223
+ const liveKinds = liveKindNamesFrom(activeSchema);
15217
15224
  const kindFilter = options.kinds === void 0 ? void 0 : new Set(options.kinds);
15218
- const candidates = pending.filter(
15219
- (row) => kindFilter === void 0 ? true : kindFilter.has(row.kindName)
15225
+ const selected = pending.filter(
15226
+ (row) => kindFilter === void 0 || kindFilter.has(row.kindName)
15227
+ );
15228
+ const candidates = selected.filter(
15229
+ (row) => !liveKinds[row.entity].has(row.kindName)
15220
15230
  );
15221
- if (candidates.length === 0) return { results: [], reclaimedVectorFields };
15231
+ const skipped = selected.filter((row) => liveKinds[row.entity].has(row.kindName)).map((row) => ({
15232
+ kind: row.kindName,
15233
+ entity: row.entity,
15234
+ status: "skipped",
15235
+ reason: "kind-is-live"
15236
+ }));
15237
+ if (candidates.length === 0) {
15238
+ return { results: skipped, reclaimedVectorFields };
15239
+ }
15222
15240
  const tableNames = backend.tableNames;
15223
15241
  const nodesTable = tableNames?.nodes ?? "typegraph_nodes";
15224
15242
  const edgesTable = tableNames?.edges ?? "typegraph_edges";
@@ -15235,14 +15253,13 @@ async function materializeRemovals(context, options = {}) {
15235
15253
  captureRecordedRemovals,
15236
15254
  recordedSchema: captureRecordedRemovals ? context.recordedSchema ?? createSqlSchema(backend.tableNames) : void 0
15237
15255
  };
15238
- return {
15239
- results: await runMaterialization(
15240
- candidates,
15241
- options,
15242
- (removal) => materializeOne2(removal, ctx)
15243
- ),
15244
- reclaimedVectorFields
15245
- };
15256
+ const materialized = [];
15257
+ for (const candidate of candidates) {
15258
+ const entry2 = await materializeOne2(candidate, ctx);
15259
+ materialized.push(entry2);
15260
+ if (options.stopOnError === true && entry2.status === "failed") break;
15261
+ }
15262
+ return { results: [...materialized, ...skipped], reclaimedVectorFields };
15246
15263
  }
15247
15264
  async function reconcilePendingRemovals(context) {
15248
15265
  const { backend, graphId } = context;
@@ -15310,14 +15327,49 @@ async function reconcilePendingRemovals(context) {
15310
15327
  await backend.setReconciliationMarker(graphId, activeRow.version);
15311
15328
  }
15312
15329
  }
15330
+ function liveKindNamesFrom(schema) {
15331
+ if (schema === void 0) {
15332
+ return { node: /* @__PURE__ */ new Set(), edge: /* @__PURE__ */ new Set() };
15333
+ }
15334
+ return {
15335
+ node: new Set(Object.keys(schema.nodes)),
15336
+ edge: new Set(Object.keys(schema.edges))
15337
+ };
15338
+ }
15313
15339
  function kindRemovalKey(entity, kindName, version) {
15314
15340
  return `${entity}|${kindName}|${version}`;
15315
15341
  }
15316
15342
  async function materializeOne2(row, ctx) {
15317
15343
  const recordKindRemoval = requireDefined(ctx.backend.recordKindRemoval);
15344
+ const schemaWriteTransaction = ctx.backend.schemaWriteTransaction;
15345
+ if (schemaWriteTransaction === void 0) {
15346
+ throw new ConfigurationError(
15347
+ "store.materializeRemovals() requires a backend that can hold the schema-write lock across the live-kind check and cleanup.",
15348
+ { code: "MATERIALIZE_REMOVALS_SCHEMA_FENCE_UNSUPPORTED" }
15349
+ );
15350
+ }
15318
15351
  try {
15319
- await closeRecordedAndDeleteLiveRows(ctx, row);
15320
- await Promise.all(buildEmbeddingTableCleanup(ctx, row));
15352
+ const outcome = await schemaWriteTransaction(
15353
+ ctx.graphId,
15354
+ async (target) => {
15355
+ const activeRow = await target.getActiveSchema(ctx.graphId);
15356
+ const activeSchema = activeRow === void 0 ? void 0 : parseSerializedSchema(activeRow.schema_doc);
15357
+ if (liveKindNamesFrom(activeSchema)[row.entity].has(row.kindName)) {
15358
+ return "skipped";
15359
+ }
15360
+ await closeRecordedAndDeleteLiveRows(ctx, row, target);
15361
+ await dropEmbeddingTableStorage(ctx, row, target);
15362
+ return "removed";
15363
+ }
15364
+ );
15365
+ if (outcome === "skipped") {
15366
+ return {
15367
+ kind: row.kindName,
15368
+ entity: row.entity,
15369
+ status: "skipped",
15370
+ reason: "kind-is-live"
15371
+ };
15372
+ }
15321
15373
  const removedAt = nowIso();
15322
15374
  await recordKindRemoval({
15323
15375
  graphId: ctx.graphId,
@@ -15352,28 +15404,33 @@ async function materializeOne2(row, ctx) {
15352
15404
  };
15353
15405
  }
15354
15406
  }
15355
- async function closeRecordedAndDeleteLiveRows(ctx, row) {
15407
+ async function closeRecordedAndDeleteLiveRows(ctx, row, target) {
15356
15408
  const deleteStatements = buildRemovedKindLiveDeleteStatements(ctx, row);
15357
15409
  if (!ctx.captureRecordedRemovals || ctx.recordedSchema === void 0) {
15358
- await executeDeleteStatements(ctx.backend, deleteStatements);
15410
+ await executeDeleteStatements(target, deleteStatements);
15359
15411
  return;
15360
15412
  }
15361
15413
  const recordedSchema = ctx.recordedSchema;
15362
- try {
15363
- await ctx.backend.transaction(async (target) => {
15364
- await closeRecordedHardDeletedKind(
15365
- target,
15366
- recordedSchema,
15367
- ctx.graphId,
15368
- { entity: row.entity, kind: row.kindName },
15369
- false
15370
- );
15371
- await executeDeleteStatements(target, deleteStatements);
15372
- });
15373
- } catch (error) {
15374
- if (!isMissingTableError(error)) throw error;
15375
- await executeDeleteStatements(ctx.backend, deleteStatements);
15414
+ const requiredRecordedTables = [
15415
+ recordedSchema.tables.recordedClock,
15416
+ recordedSchema.tables.recordedEdges,
15417
+ ...row.entity === "node" ? [recordedSchema.tables.recordedNodes] : []
15418
+ ];
15419
+ const recordedTablesExist = await Promise.all(
15420
+ requiredRecordedTables.map((tableName) => target.tableExists(tableName))
15421
+ );
15422
+ if (recordedTablesExist.some((exists) => !exists)) {
15423
+ await executeDeleteStatements(target, deleteStatements);
15424
+ return;
15376
15425
  }
15426
+ await closeRecordedHardDeletedKind(
15427
+ target,
15428
+ recordedSchema,
15429
+ ctx.graphId,
15430
+ { entity: row.entity, kind: row.kindName },
15431
+ false
15432
+ );
15433
+ await executeDeleteStatements(target, deleteStatements);
15377
15434
  }
15378
15435
  function buildRemovedKindLiveDeleteStatements(ctx, row) {
15379
15436
  const graphLit = literal(ctx.graphId);
@@ -15391,41 +15448,22 @@ function buildRemovedKindLiveDeleteStatements(ctx, row) {
15391
15448
  ];
15392
15449
  }
15393
15450
  async function executeDeleteStatements(target, statements) {
15394
- if (target.executeStatement !== void 0) {
15395
- await Promise.all(
15396
- statements.map(
15397
- (statement) => requireDefined(target.executeStatement)(
15398
- asCompiledStatementSql(sql.raw(statement))
15399
- )
15400
- )
15401
- );
15402
- return;
15451
+ for (const statement of statements) {
15452
+ await target.executeStatement(asCompiledStatementSql(sql.raw(statement)));
15403
15453
  }
15404
- if (target.executeDdl === void 0) {
15405
- throw new ConfigurationError(
15406
- "store.materializeRemovals() requires a backend that can execute cleanup statements.",
15407
- { code: "MATERIALIZE_REMOVALS_BACKEND_UNSUPPORTED" }
15408
- );
15409
- }
15410
- await Promise.all(
15411
- statements.map((statement) => requireDefined(target.executeDdl)(statement))
15412
- );
15413
15454
  }
15414
- function buildEmbeddingTableCleanup(ctx, row) {
15455
+ async function dropEmbeddingTableStorage(ctx, row, target) {
15415
15456
  const vectorStrategy = ctx.backend.vectorStrategy;
15416
- if (vectorStrategy === void 0) return [];
15417
- const executeDdl = requireDefined(ctx.backend.executeDdl);
15418
- const cleanup = (async () => {
15419
- const slots = await resolveRemovedKindEmbeddingSlots(ctx.backend, row);
15420
- await Promise.all(
15421
- slots.map(
15422
- (slot) => dropVectorSlotStorage(ctx.backend, vectorStrategy, executeDdl, slot)
15423
- )
15424
- );
15425
- })();
15426
- return [cleanup];
15457
+ if (vectorStrategy === void 0) return;
15458
+ const executeDdl = target.executeSchemaDdl;
15459
+ const deleteContribution = target.deleteSchemaVectorSlotContribution;
15460
+ const slots = await resolveRemovedKindEmbeddingSlots(target, row);
15461
+ for (const slot of slots) {
15462
+ await dropVectorSlotStorage(vectorStrategy, executeDdl, slot);
15463
+ await deleteContribution(slot);
15464
+ }
15427
15465
  }
15428
- async function dropVectorSlotStorage(backend, strategy, executeDdl, slot) {
15466
+ async function dropVectorSlotStorage(strategy, executeDdl, slot) {
15429
15467
  try {
15430
15468
  for (const ddl of strategy.buildDropStorage(slot)) {
15431
15469
  await executeDdl(ddl);
@@ -15433,7 +15471,6 @@ async function dropVectorSlotStorage(backend, strategy, executeDdl, slot) {
15433
15471
  } catch (error) {
15434
15472
  if (!isMissingTableError(error)) throw error;
15435
15473
  }
15436
- await backend.deleteVectorSlotContribution?.(slot);
15437
15474
  }
15438
15475
  async function resolveRemovedKindEmbeddingSlots(backend, row) {
15439
15476
  const priorVersion = row.schemaVersion - 1;
@@ -15459,26 +15496,26 @@ async function resolveRemovedKindEmbeddingSlots(backend, row) {
15459
15496
  function vectorFieldKey(kind, fieldPath) {
15460
15497
  return `${kind}\0${fieldPath}`;
15461
15498
  }
15462
- async function reclaimRemovedVectorFieldTables(context) {
15499
+ function vectorFieldKeysFrom(schema) {
15500
+ const keys = /* @__PURE__ */ new Set();
15501
+ for (const declaration of schema.indexes ?? []) {
15502
+ if (declaration.entity === "vector") {
15503
+ keys.add(vectorFieldKey(declaration.kind, declaration.fieldPath));
15504
+ }
15505
+ }
15506
+ return keys;
15507
+ }
15508
+ async function reclaimRemovedVectorFieldTables(context, activeRow) {
15463
15509
  const { backend, graphId } = context;
15464
15510
  const vectorStrategy = backend.vectorStrategy;
15465
- const executeDdl = backend.executeDdl;
15466
- if (vectorStrategy === void 0 || executeDdl === void 0) return [];
15467
- const activeRow = await backend.getActiveSchema(graphId);
15511
+ if (vectorStrategy === void 0) return [];
15468
15512
  if (activeRow === void 0) return [];
15469
15513
  const cacheKey = `${graphId}\0${activeRow.version}`;
15470
15514
  let perBackend = reclaimCache.get(backend);
15471
15515
  const cached = perBackend?.get(cacheKey);
15472
15516
  if (cached !== void 0) return cached;
15473
15517
  const activeSchema = parseSerializedSchema(activeRow.schema_doc);
15474
- const activeVectorFields = /* @__PURE__ */ new Set();
15475
- for (const declaration of activeSchema.indexes ?? []) {
15476
- if (declaration.entity === "vector") {
15477
- activeVectorFields.add(
15478
- vectorFieldKey(declaration.kind, declaration.fieldPath)
15479
- );
15480
- }
15481
- }
15518
+ const activeVectorFields = vectorFieldKeysFrom(activeSchema);
15482
15519
  const survivingKinds = new Set(Object.keys(activeSchema.nodes));
15483
15520
  const historical = /* @__PURE__ */ new Map();
15484
15521
  for (let version = activeRow.version - 1; version >= 1; version -= 1) {
@@ -15507,14 +15544,43 @@ async function reclaimRemovedVectorFieldTables(context) {
15507
15544
  (field2) => !activeVectorFields.has(vectorFieldKey(field2.kind, field2.fieldPath)) && survivingKinds.has(field2.kind)
15508
15545
  );
15509
15546
  const results = [];
15547
+ let skippedAfterLockedRecheck = false;
15548
+ const schemaWriteTransaction = backend.schemaWriteTransaction;
15549
+ if (orphans.length > 0 && schemaWriteTransaction === void 0) {
15550
+ throw new ConfigurationError(
15551
+ "store.materializeRemovals() requires a backend that can hold the schema-write lock across the vector-field liveness check and cleanup.",
15552
+ { code: "MATERIALIZE_REMOVALS_SCHEMA_FENCE_UNSUPPORTED" }
15553
+ );
15554
+ }
15510
15555
  for (const field2 of orphans) {
15511
15556
  try {
15512
- await dropVectorSlotStorage(
15513
- backend,
15514
- vectorStrategy,
15515
- executeDdl,
15516
- field2.slot
15557
+ const reclaimed = await requireDefined(schemaWriteTransaction)(
15558
+ graphId,
15559
+ async (target) => {
15560
+ const lockedActiveRow = await target.getActiveSchema(graphId);
15561
+ if (lockedActiveRow === void 0) return false;
15562
+ const lockedActiveSchema = parseSerializedSchema(
15563
+ lockedActiveRow.schema_doc
15564
+ );
15565
+ const lockedVectorFields = vectorFieldKeysFrom(lockedActiveSchema);
15566
+ if (lockedVectorFields.has(
15567
+ vectorFieldKey(field2.kind, field2.fieldPath)
15568
+ ) || !Object.hasOwn(lockedActiveSchema.nodes, field2.kind)) {
15569
+ return false;
15570
+ }
15571
+ await dropVectorSlotStorage(
15572
+ vectorStrategy,
15573
+ target.executeSchemaDdl,
15574
+ field2.slot
15575
+ );
15576
+ await target.deleteSchemaVectorSlotContribution(field2.slot);
15577
+ return true;
15578
+ }
15517
15579
  );
15580
+ if (!reclaimed) {
15581
+ skippedAfterLockedRecheck = true;
15582
+ continue;
15583
+ }
15518
15584
  results.push({
15519
15585
  kind: field2.kind,
15520
15586
  fieldPath: field2.fieldPath,
@@ -15529,7 +15595,7 @@ async function reclaimRemovedVectorFieldTables(context) {
15529
15595
  });
15530
15596
  }
15531
15597
  }
15532
- if (results.every((entry2) => entry2.status === "reclaimed")) {
15598
+ if (!skippedAfterLockedRecheck && results.every((entry2) => entry2.status === "reclaimed")) {
15533
15599
  if (perBackend === void 0) {
15534
15600
  perBackend = /* @__PURE__ */ new Map();
15535
15601
  reclaimCache.set(backend, perBackend);
@@ -16062,6 +16128,11 @@ async function executeEdgeGetOrCreateByEndpoints(ctx, kind, fromKind, fromId, to
16062
16128
  operation: "create"
16063
16129
  });
16064
16130
  validateMatchOnFields(edgeKind.schema, matchOn, kind);
16131
+ const validFrom = validateOptionalCanonicalIsoDate(
16132
+ options?.validFrom,
16133
+ "validFrom"
16134
+ );
16135
+ const validTo = validateOptionalCanonicalIsoDate(options?.validTo, "validTo");
16065
16136
  if (ifExists === "return") {
16066
16137
  const probeRows = await backend.findEdgesByKind({
16067
16138
  graphId: ctx.graphId,
@@ -16105,7 +16176,9 @@ async function executeEdgeGetOrCreateByEndpoints(ctx, kind, fromKind, fromId, to
16105
16176
  fromId,
16106
16177
  toKind,
16107
16178
  toId,
16108
- props: validatedProps
16179
+ props: validatedProps,
16180
+ ...validFrom !== void 0 && { validFrom },
16181
+ ...validTo !== void 0 && { validTo }
16109
16182
  };
16110
16183
  const edge2 = await executeEdgeCreate(ctx, input, backend);
16111
16184
  return { edge: edge2, action: "created" };
@@ -16116,7 +16189,11 @@ async function executeEdgeGetOrCreateByEndpoints(ctx, kind, fromKind, fromId, to
16116
16189
  }
16117
16190
  const edge2 = await executeEdgeUpsertUpdate(
16118
16191
  ctx,
16119
- { id: liveRow.id, props: validatedProps },
16192
+ {
16193
+ id: liveRow.id,
16194
+ props: validatedProps,
16195
+ ...validTo !== void 0 && { validTo }
16196
+ },
16120
16197
  backend
16121
16198
  );
16122
16199
  return { edge: edge2, action: "updated" };
@@ -16126,7 +16203,7 @@ async function executeEdgeGetOrCreateByEndpoints(ctx, kind, fromKind, fromId, to
16126
16203
  throw new Error("Expected deletedRow to be defined");
16127
16204
  }
16128
16205
  const matchedDeletedRow = deletedRow;
16129
- const effectiveValidTo = matchedDeletedRow.valid_to;
16206
+ const effectiveValidTo = validTo ?? matchedDeletedRow.valid_to;
16130
16207
  const constraintContext = {
16131
16208
  graphId: ctx.graphId,
16132
16209
  registry: ctx.registry,
@@ -16144,7 +16221,11 @@ async function executeEdgeGetOrCreateByEndpoints(ctx, kind, fromKind, fromId, to
16144
16221
  );
16145
16222
  const edge = await executeEdgeUpsertUpdate(
16146
16223
  ctx,
16147
- { id: matchedDeletedRow.id, props: validatedProps },
16224
+ {
16225
+ id: matchedDeletedRow.id,
16226
+ props: validatedProps,
16227
+ ...validTo !== void 0 && { validTo }
16228
+ },
16148
16229
  backend,
16149
16230
  { clearDeleted: true }
16150
16231
  );
@@ -16171,6 +16252,11 @@ async function executeEdgeBulkGetOrCreateByEndpoints(ctx, kind, items, backend,
16171
16252
  kind,
16172
16253
  operation: "create"
16173
16254
  });
16255
+ const validFrom = validateOptionalCanonicalIsoDate(
16256
+ item.validFrom,
16257
+ "validFrom"
16258
+ );
16259
+ const validTo = validateOptionalCanonicalIsoDate(item.validTo, "validTo");
16174
16260
  const compositeKey = buildEdgeCompositeKey(
16175
16261
  item.fromKind,
16176
16262
  item.fromId,
@@ -16179,7 +16265,7 @@ async function executeEdgeBulkGetOrCreateByEndpoints(ctx, kind, items, backend,
16179
16265
  validatedProps,
16180
16266
  matchOn
16181
16267
  );
16182
- const endpointKey = buildEndpointPairKey(
16268
+ const endpointKey2 = buildEndpointPairKey(
16183
16269
  item.fromKind,
16184
16270
  item.fromId,
16185
16271
  item.toKind,
@@ -16192,7 +16278,9 @@ async function executeEdgeBulkGetOrCreateByEndpoints(ctx, kind, items, backend,
16192
16278
  toId: item.toId,
16193
16279
  validatedProps,
16194
16280
  compositeKey,
16195
- endpointKey
16281
+ endpointKey: endpointKey2,
16282
+ ...validFrom !== void 0 && { validFrom },
16283
+ ...validTo !== void 0 && { validTo }
16196
16284
  });
16197
16285
  }
16198
16286
  const uniqueEndpoints = /* @__PURE__ */ new Map();
@@ -16208,7 +16296,7 @@ async function executeEdgeBulkGetOrCreateByEndpoints(ctx, kind, items, backend,
16208
16296
  }
16209
16297
  async function fetchRowsByEndpoint(reader) {
16210
16298
  const rowsByEndpoint = /* @__PURE__ */ new Map();
16211
- for (const [endpointKey, endpoint] of uniqueEndpoints) {
16299
+ for (const [endpointKey2, endpoint] of uniqueEndpoints) {
16212
16300
  const rows = await reader.findEdgesByKind({
16213
16301
  graphId: ctx.graphId,
16214
16302
  kind,
@@ -16219,7 +16307,7 @@ async function executeEdgeBulkGetOrCreateByEndpoints(ctx, kind, items, backend,
16219
16307
  excludeDeleted: false,
16220
16308
  temporalMode: "includeTombstones"
16221
16309
  });
16222
- rowsByEndpoint.set(endpointKey, rows);
16310
+ rowsByEndpoint.set(endpointKey2, rows);
16223
16311
  }
16224
16312
  return rowsByEndpoint;
16225
16313
  }
@@ -16250,7 +16338,11 @@ async function executeEdgeBulkGetOrCreateByEndpoints(ctx, kind, items, backend,
16250
16338
  fromId: entry2.fromId,
16251
16339
  toKind: entry2.toKind,
16252
16340
  toId: entry2.toId,
16253
- props: entry2.validatedProps
16341
+ props: entry2.validatedProps,
16342
+ ...entry2.validFrom !== void 0 && {
16343
+ validFrom: entry2.validFrom
16344
+ },
16345
+ ...entry2.validTo !== void 0 && { validTo: entry2.validTo }
16254
16346
  }
16255
16347
  });
16256
16348
  } else {
@@ -16266,7 +16358,8 @@ async function executeEdgeBulkGetOrCreateByEndpoints(ctx, kind, items, backend,
16266
16358
  fromKind: entry2.fromKind,
16267
16359
  fromId: entry2.fromId,
16268
16360
  toKind: entry2.toKind,
16269
- toId: entry2.toId
16361
+ toId: entry2.toId,
16362
+ ...entry2.validTo !== void 0 && { validTo: entry2.validTo }
16270
16363
  });
16271
16364
  }
16272
16365
  }
@@ -16310,7 +16403,7 @@ async function executeEdgeBulkGetOrCreateByEndpoints(ctx, kind, items, backend,
16310
16403
  }
16311
16404
  for (const entry2 of toFetch) {
16312
16405
  if (entry2.isDeleted) {
16313
- const effectiveValidTo = entry2.row.valid_to;
16406
+ const effectiveValidTo = entry2.validTo ?? entry2.row.valid_to;
16314
16407
  const constraintContext = {
16315
16408
  graphId: ctx.graphId,
16316
16409
  registry: ctx.registry,
@@ -16328,7 +16421,11 @@ async function executeEdgeBulkGetOrCreateByEndpoints(ctx, kind, items, backend,
16328
16421
  );
16329
16422
  const edge = await executeEdgeUpsertUpdate(
16330
16423
  ctx,
16331
- { id: entry2.row.id, props: entry2.validatedProps },
16424
+ {
16425
+ id: entry2.row.id,
16426
+ props: entry2.validatedProps,
16427
+ ...entry2.validTo !== void 0 && { validTo: entry2.validTo }
16428
+ },
16332
16429
  target,
16333
16430
  { clearDeleted: true }
16334
16431
  );
@@ -16336,7 +16433,11 @@ async function executeEdgeBulkGetOrCreateByEndpoints(ctx, kind, items, backend,
16336
16433
  } else if (ifExists === "update") {
16337
16434
  const edge = await executeEdgeUpsertUpdate(
16338
16435
  ctx,
16339
- { id: entry2.row.id, props: entry2.validatedProps },
16436
+ {
16437
+ id: entry2.row.id,
16438
+ props: entry2.validatedProps,
16439
+ ...entry2.validTo !== void 0 && { validTo: entry2.validTo }
16440
+ },
16340
16441
  target
16341
16442
  );
16342
16443
  results[entry2.index] = { edge, action: "updated" };
@@ -16867,6 +16968,39 @@ function syncStoreReplacementRef(ref, replacement) {
16867
16968
  if (ref === void 0) return;
16868
16969
  ref.current = replacement;
16869
16970
  }
16971
+ async function commitEvolvedSchemaWhenRequiredKindsAreEmpty(backend, graph, currentVersion, classification) {
16972
+ const result = await commitNewSchemaVersionIfKindsEmpty(
16973
+ backend,
16974
+ graph,
16975
+ currentVersion,
16976
+ classification.requireEmpty.map((entry2) => ({
16977
+ entity: entry2.entity,
16978
+ kind: entry2.kindName
16979
+ }))
16980
+ );
16981
+ if (result.status === "committed") return result.row;
16982
+ const populatedKeys = new Set(
16983
+ result.kinds.map((entry2) => `${entry2.entity}:${entry2.kind}`)
16984
+ );
16985
+ const nonEmpty = new Set(
16986
+ classification.requireEmpty.filter(
16987
+ (entry2) => populatedKeys.has(`${entry2.entity}:${entry2.kindName}`)
16988
+ )
16989
+ );
16990
+ const error = buildIncompatibleChangeError(
16991
+ classification,
16992
+ nonEmpty,
16993
+ graph.id
16994
+ );
16995
+ if (error !== void 0) throw error;
16996
+ throw new ConfigurationError(
16997
+ "Schema emptiness guard reported populated kinds that were not part of the compatibility classification.",
16998
+ {
16999
+ graphId: graph.id,
17000
+ populatedKinds: result.kinds.map((entry2) => entry2.kind)
17001
+ }
17002
+ );
17003
+ }
16870
17004
  var StoreImplementation = class _StoreImplementation {
16871
17005
  [STORE_RUNTIME];
16872
17006
  #graph;
@@ -17712,19 +17846,54 @@ var StoreImplementation = class _StoreImplementation {
17712
17846
  }
17713
17847
  // === Batch Query Execution ===
17714
17848
  /**
17715
- * Executes multiple queries and returns a typed tuple of results.
17849
+ * Runs several queries in sequence, returning a typed tuple. The portable
17850
+ * guarantee is N serialized query executions — never one round trip.
17851
+ *
17852
+ * **Cost.** At least one statement per query, sometimes two: a query whose
17853
+ * selective-field mapping falls back re-runs as a full fetch, and that
17854
+ * fallback is detected *after* the selective statement has already
17855
+ * executed. It clears the fast path, so a reused query instance pays the
17856
+ * double only once — but the builder is immutable, so a query rebuilt per
17857
+ * request pays it every request.
17858
+ *
17859
+ * With `backend.capabilities.transactions` the queries share one
17860
+ * transaction; how that reaches the wire is the adapter's business. A SQL
17861
+ * backend frames them with `begin`/`commit`, putting a networked one at
17862
+ * N+2 round trips *at best*, while Durable Objects use an ambient storage
17863
+ * transaction with no framing statements. Without transactions there is no
17864
+ * framing. Connection reuse is a separate question from transaction
17865
+ * support: the no-transaction path passes the same backend object, so an
17866
+ * adapter may reuse one client there too. The portable guarantee is only
17867
+ * that at most one query is in flight at a time.
17868
+ *
17869
+ * **Not a snapshot — and there is no way to make it one.** PostgreSQL
17870
+ * defaults to read-committed isolation, so a later query can observe a
17871
+ * commit the earlier ones did not. `store.transaction()` takes an
17872
+ * `isolationLevel`, but its context exposes only `nodes` / `edges`: there is
17873
+ * no public way to run a fluent query or a batch inside a transaction, so a
17874
+ * snapshot across fluent queries is not available today. Collection reads
17875
+ * can have one — `store.transaction(fn, { isolationLevel: "repeatable_read" })`
17876
+ * reading through `tx.nodes` / `tx.edges` — but only where the backend has
17877
+ * transactions (others ignore the option entirely), and a history-enabled
17878
+ * store on PostgreSQL additionally requires `accessMode: "read_only"` or the
17879
+ * call throws.
17716
17880
  *
17717
- * Each query preserves its own result type, projection, filtering, sorting,
17718
- * and pagination.
17881
+ * **Will not fix an N+1.** Serializing N queries does not reduce their
17882
+ * number. The alternatives are set-oriented or chunked rather than
17883
+ * fixed-cost: `.traverse()` compiles a whole chain to one statement;
17884
+ * `store.subgraph()` costs 2 statements on SQLite and 3 on PostgreSQL
17885
+ * however large the result; `getByIds()` issues one statement per
17886
+ * bind-limit chunk, falling back to one per distinct id where the backend
17887
+ * exposes no batch read; `bulkFindByIndex()` costs one probe plus that same
17888
+ * chunked hydration.
17719
17889
  *
17720
- * **Snapshot consistency is conditional.** When
17721
- * `backend.capabilities.transactions` is `true`, queries run sequentially
17722
- * on a single connection inside an implicit transaction and observe the
17723
- * same database snapshot. When transactions are unavailable
17724
- * (Cloudflare D1, `drizzle-orm/neon-http`), queries run sequentially over
17725
- * independent connections and may observe writes that landed between them.
17726
- * Branch on `backend.capabilities.transactions` if you need a guaranteed
17727
- * snapshot.
17890
+ * **Versus `Promise.all`.** Workload- and adapter-dependent in both
17891
+ * directions. `Promise.all` overlaps its queries against a pool with idle
17892
+ * capacity, but it does not necessarily hold N connections, and against a
17893
+ * single client or a saturated pool it queues. `batch()` keeps at most one
17894
+ * query in flight, so it pays the sum of their latencies — but it can still
17895
+ * come out ahead where connection acquisition dominates. Measure rather
17896
+ * than assume.
17728
17897
  *
17729
17898
  * Read-only — use `bulkCreate`, `bulkInsert`, etc. for write batching.
17730
17899
  *
@@ -17749,9 +17918,10 @@ var StoreImplementation = class _StoreImplementation {
17749
17918
  */
17750
17919
  async batch(...queries) {
17751
17920
  return runOptionallyInTransaction(this.#baseBackend, async (target) => {
17921
+ const queryBackend = this.#createHookedQueryBackend(target);
17752
17922
  const results = [];
17753
17923
  for (const query of queries) {
17754
- const result = await query.executeOn(target);
17924
+ const result = await query.executeOn(queryBackend);
17755
17925
  results.push(result);
17756
17926
  }
17757
17927
  return results;
@@ -18033,6 +18203,13 @@ var StoreImplementation = class _StoreImplementation {
18033
18203
  const txBackend = adopt(externalTx);
18034
18204
  if (this.#captureEnabled) {
18035
18205
  await assertRecordedCaptureTransactionIsolation(txBackend);
18206
+ await lockSchemaVersionForStoreWrite(
18207
+ {
18208
+ graphId: this.graphId,
18209
+ schemaVersion: this.#schemaMetadata.schemaVersion
18210
+ },
18211
+ txBackend
18212
+ );
18036
18213
  }
18037
18214
  const scope = this.#captureEnabled ? createRecordedTransactionScope(txBackend, this.#sqlSchema()) : {
18038
18215
  backend: txBackend,
@@ -18202,6 +18379,7 @@ var StoreImplementation = class _StoreImplementation {
18202
18379
  };
18203
18380
  await (this.#baseBackend.capabilities.transactions ? this.#baseBackend.transaction(async (tx) => doClear(tx)) : doClear(this.#baseBackend));
18204
18381
  await this.#clearVectorStorage();
18382
+ this.#schemaMetadata = UNKNOWN_SCHEMA_METADATA;
18205
18383
  this.#nodeCollections = void 0;
18206
18384
  this.#edgeCollections = void 0;
18207
18385
  this.#algorithms = void 0;
@@ -18338,6 +18516,7 @@ var StoreImplementation = class _StoreImplementation {
18338
18516
  }
18339
18517
  return caughtUp;
18340
18518
  }
18519
+ await this.#assertNoPendingRemovalFor(merged, baseline);
18341
18520
  const baselineDocument = baseline.extension ?? Object.freeze({});
18342
18521
  const classification = classifyModifications(baselineDocument, extension);
18343
18522
  if (classification.incompatible.length > 0) {
@@ -18346,20 +18525,12 @@ var StoreImplementation = class _StoreImplementation {
18346
18525
  this.graphId
18347
18526
  );
18348
18527
  }
18349
- if (classification.requireEmpty.length > 0) {
18350
- const nonEmpty = await this.#probeEmptyKinds(classification.requireEmpty);
18351
- const error = buildIncompatibleChangeError(
18352
- classification,
18353
- nonEmpty,
18354
- this.graphId
18355
- );
18356
- if (error !== void 0) throw error;
18357
- }
18358
- const committed = await commitNewSchemaVersion(
18528
+ const committed = classification.requireEmpty.length > 0 ? await commitEvolvedSchemaWhenRequiredKindsAreEmpty(
18359
18529
  this.#backend,
18360
18530
  merged,
18361
- activeRow.version
18362
- );
18531
+ activeRow.version,
18532
+ classification
18533
+ ) : await commitNewSchemaVersion(this.#backend, merged, activeRow.version);
18363
18534
  await materializeVectorContributions(this.#backend, merged);
18364
18535
  const evolved = this.#cloneWithGraph(
18365
18536
  merged,
@@ -18634,6 +18805,65 @@ var StoreImplementation = class _StoreImplementation {
18634
18805
  }
18635
18806
  return { recreated: true, reembedded };
18636
18807
  }
18808
+ /**
18809
+ * Diagnostic: compare each contribution currently expected by this graph
18810
+ * and the backend strategies with its durable marker and the physical
18811
+ * catalog. Reports detected unusable contributions, including a recorded
18812
+ * failed materialization whose absent table agrees with the marker.
18813
+ * Contributions with neither marker nor table and retired marker rows are
18814
+ * omitted, so an empty array is not proof that storage was initialized.
18815
+ *
18816
+ * Opening a store never probes the catalog — `ensureRuntimeContributions`
18817
+ * and the runtime asserts short-circuit on a per-instance signature cache
18818
+ * and then on the marker row alone, which is the right default for a hot
18819
+ * path. The cost is that a database whose contribution tables were dropped
18820
+ * out of band (a partial restore, a hand-run `DROP`, a schema-scoped
18821
+ * restore that missed them) opens completely clean and then fails at the
18822
+ * first read of the affected slot. This is the explicit, operator-invoked
18823
+ * check for that state; it is not, and should not become, a boot step.
18824
+ *
18825
+ * Purely read-only: one existence query per distinct contribution table
18826
+ * plus one marker read per graph, no DDL and no writes, so it is safe to
18827
+ * run under a least-privilege runtime role and safe to run on a live
18828
+ * store. Each entry carries identity resolved from the active contribution
18829
+ * declaration and matching the marker contract, so callers can route to a
18830
+ * repair without reconstructing any internal naming contract.
18831
+ *
18832
+ * Route on `state`, NOT on whether the entry is a vector slot: the
18833
+ * repairs differ per state and the wrong one destroys data.
18834
+ * {@link Store.reembedVectorField} drops and recreates storage, so
18835
+ * applying it to a `missing-marker` — table intact, only the marker
18836
+ * wrong — discards every embedding to fix bookkeeping. See
18837
+ * {@link ContributionDiagnostic} and the per-state repair tables in the
18838
+ * troubleshooting guide.
18839
+ *
18840
+ * Vector slots are enumerated from the graph's declared embedding fields
18841
+ * and are considered only when the backend advertises vector support; a
18842
+ * backend without it never materialized them, so there is nothing to
18843
+ * compare. Current fulltext contributions are always considered. For a
18844
+ * readiness check, first construct the Store through a verified attach so
18845
+ * initialization is established independently.
18846
+ *
18847
+ * @throws {ConfigurationError} when the backend cannot probe its own
18848
+ * catalog. Reporting "no problems found" on a backend that never
18849
+ * looked would be the one answer this diagnostic must never give.
18850
+ */
18851
+ async verifyContributions() {
18852
+ const backend = this.#baseBackend;
18853
+ const verify = backend.verifyContributions;
18854
+ if (verify === void 0) {
18855
+ throw new ConfigurationError(
18856
+ "verifyContributions requires a backend that can probe its catalog for contribution tables.",
18857
+ {
18858
+ backend: backend.dialect,
18859
+ capability: "contributions",
18860
+ operation: "verify"
18861
+ }
18862
+ );
18863
+ }
18864
+ const vectorSlots = backend.capabilities.vector?.supported === true ? resolveGraphVectorSlots(this.#graph) : [];
18865
+ return verify(this.graphId, vectorSlots);
18866
+ }
18637
18867
  /**
18638
18868
  * Removes extension kinds from the schema with cascading edge and
18639
18869
  * ontology cleanup. Two-phase by design:
@@ -18814,42 +19044,36 @@ var StoreImplementation = class _StoreImplementation {
18814
19044
  return { activeRow, storedSchema, baseline };
18815
19045
  }
18816
19046
  /**
18817
- * Probes each `requireEmpty` entry for any rows. Returns the set of
18818
- * composite keys (`${entity}:${kindName}`) that have at least one
18819
- * row — those entries need to be promoted from "allowed-on-empty"
18820
- * to incompatible. Dispatches to `countNodesByKind` for `node`
18821
- * entries and `countEdgesByKind` for `edge` entries (a single-
18822
- * primitive probe would always return 0 for the wrong-entity case
18823
- * and silently bypass the gate).
19047
+ * Refuses an evolve that re-adds a kind whose data cleanup is still pending.
18824
19048
  *
18825
- * Probes run in parallel; each entry is independent. Race window
18826
- * (probe → CAS commit): another writer can insert a row into a
18827
- * previously-empty kind. The schema commit still succeeds (CAS
18828
- * guards on schema version, not row count); the new schema rejects
18829
- * the inserted row at next read, which the operator inspects and
18830
- * either deletes or reverts. Rare in practice; tighter elimination
18831
- * would require `SELECT FOR UPDATE` on the rows table, too
18832
- * heavyweight for a millisecond-budget operation.
19049
+ * Returns silently on backends without the removal queue: they cannot have
19050
+ * a pending row, so there is nothing to conflict with.
18833
19051
  */
18834
- async #probeEmptyKinds(requireEmpty) {
18835
- const probes = requireEmpty.map(
18836
- async (entry2) => {
18837
- const count2 = entry2.entity === "node" ? await this.#backend.countNodesByKind({
18838
- graphId: this.graphId,
18839
- kind: entry2.kindName
18840
- }) : await this.#backend.countEdgesByKind({
18841
- graphId: this.graphId,
18842
- kind: entry2.kindName
18843
- });
18844
- return [entry2, count2];
19052
+ async #assertNoPendingRemovalFor(merged, baseline) {
19053
+ const getPendingKindRemovals = this.#backend.getPendingKindRemovals;
19054
+ if (getPendingKindRemovals === void 0) return;
19055
+ const addedNodes = Object.keys(merged.nodes).filter(
19056
+ (kind) => !(kind in baseline.nodes)
19057
+ );
19058
+ const addedEdges = Object.keys(merged.edges).filter(
19059
+ (kind) => !(kind in baseline.edges)
19060
+ );
19061
+ if (addedNodes.length === 0 && addedEdges.length === 0) return;
19062
+ const pending = await getPendingKindRemovals(this.graphId);
19063
+ if (pending.length === 0) return;
19064
+ const blocked = pending.filter(
19065
+ (row) => row.entity === "node" ? addedNodes.includes(row.kindName) : addedEdges.includes(row.kindName)
19066
+ );
19067
+ if (blocked.length === 0) return;
19068
+ const named = blocked.map((row) => `${row.entity} "${row.kindName}"`).join(", ");
19069
+ throw new ConfigurationError(
19070
+ `Cannot re-add ${named} for graph "${this.graphId}": the previous removal's data cleanup has not run, so the old rows are still in the database and would become visible again alongside the new ones. Run store.materializeRemovals() first, then evolve.`,
19071
+ {
19072
+ code: "KIND_READD_BLOCKED_BY_PENDING_REMOVAL",
19073
+ graphId: this.graphId,
19074
+ kinds: blocked.map((row) => row.kindName)
18845
19075
  }
18846
19076
  );
18847
- const results = await Promise.all(probes);
18848
- const nonEmpty = /* @__PURE__ */ new Set();
18849
- for (const [entry2, count2] of results) {
18850
- if (count2 > 0) nonEmpty.add(entry2);
18851
- }
18852
- return nonEmpty;
18853
19077
  }
18854
19078
  #cloneWithGraph(graph, ref, schemaMetadata = this.#schemaMetadata) {
18855
19079
  const next = this.#adapterBackend === void 0 ? new _StoreImplementation(
@@ -18885,6 +19109,7 @@ var StoreImplementation = class _StoreImplementation {
18885
19109
  return {
18886
19110
  graph: this.#graph,
18887
19111
  graphId: this.graphId,
19112
+ schemaVersion: this.#schemaMetadata.schemaVersion,
18888
19113
  historyEnabled: this.#captureEnabled,
18889
19114
  revisionTrackingEnabled: this.#revisionTrackingEnabled,
18890
19115
  revisionSchema: this.#sqlSchema(),
@@ -18897,6 +19122,7 @@ var StoreImplementation = class _StoreImplementation {
18897
19122
  return {
18898
19123
  graph: this.#graph,
18899
19124
  graphId: this.graphId,
19125
+ schemaVersion: this.#schemaMetadata.schemaVersion,
18900
19126
  historyEnabled: this.#captureEnabled,
18901
19127
  revisionTrackingEnabled: this.#revisionTrackingEnabled,
18902
19128
  revisionSchema: this.#sqlSchema(),
@@ -18906,6 +19132,57 @@ var StoreImplementation = class _StoreImplementation {
18906
19132
  };
18907
19133
  }
18908
19134
  // === Internal: Hook Helpers ===
19135
+ /**
19136
+ * Decorates the query execution port so hooks observe each statement the
19137
+ * query builder submits to the backend. A selective-projection retry
19138
+ * therefore emits two independent start/end pairs with their actual SQL.
19139
+ */
19140
+ #createHookedQueryBackend(backend) {
19141
+ if (this.#hooks.onQueryStart === void 0 && this.#hooks.onQueryEnd === void 0 && this.#hooks.onError === void 0) {
19142
+ return backend;
19143
+ }
19144
+ const executeRaw = backend.executeRaw;
19145
+ const compileSql = backend.compileSql;
19146
+ const projected = createGraphBackendProjection(backend);
19147
+ return {
19148
+ ...projected,
19149
+ execute: (query) => {
19150
+ const compiled = compileSql === void 0 ? renderSql(query, backend.dialect) : compileSql(query);
19151
+ return this.#withQueryHooks(
19152
+ compiled.sql,
19153
+ compiled.params,
19154
+ () => backend.execute(query)
19155
+ );
19156
+ },
19157
+ ...executeRaw === void 0 ? {} : {
19158
+ executeRaw: (sqlText, params) => this.#withQueryHooks(
19159
+ sqlText,
19160
+ params,
19161
+ () => executeRaw(sqlText, params)
19162
+ )
19163
+ }
19164
+ };
19165
+ }
19166
+ async #withQueryHooks(sql2, params, execute) {
19167
+ const ctx = {
19168
+ ...this.#createHookContext(),
19169
+ sql: sql2,
19170
+ params
19171
+ };
19172
+ this.#hooks.onQueryStart?.(ctx);
19173
+ const startTime = Date.now();
19174
+ try {
19175
+ const rows = await execute();
19176
+ this.#hooks.onQueryEnd?.(ctx, {
19177
+ rowCount: rows.length,
19178
+ durationMs: Date.now() - startTime
19179
+ });
19180
+ return rows;
19181
+ } catch (error) {
19182
+ this.#hooks.onError?.(ctx, asError(error));
19183
+ throw error;
19184
+ }
19185
+ }
18909
19186
  #createHookContext() {
18910
19187
  return {
18911
19188
  operationId: generateId(),
@@ -18987,13 +19264,14 @@ var StoreImplementation = class _StoreImplementation {
18987
19264
  };
18988
19265
  }
18989
19266
  #createQueryForBackend(backend, sealedCoordinate) {
19267
+ const queryBackend = this.#createHookedQueryBackend(backend);
18990
19268
  return createInternalQueryBuilder(
18991
19269
  this.graphId,
18992
19270
  this.#registry,
18993
19271
  {
18994
19272
  // TransactionBackend omits transaction/close, but query execution only needs
18995
19273
  // the read-path/query capabilities shared with GraphBackend.
18996
- backend,
19274
+ backend: queryBackend,
18997
19275
  dialect: backend.dialect,
18998
19276
  defaultTraversalExpansion: this.#defaultTraversalExpansion,
18999
19277
  ...this.#schema !== void 0 && { schema: this.#schema },
@@ -19306,5 +19584,5 @@ async function createVerifiedAdapterStore(graph, backend, options) {
19306
19584
  }
19307
19585
 
19308
19586
  export { ExecutableAggregateQuery, ExecutableQuery, MAX_EXPLICIT_RECURSIVE_DEPTH, MAX_RECURSIVE_DEPTH, PreparedQuery, QueryBuilder, RecordedStoreView, StoreSearch, StoreView, UnionableQuery, avg, composeFragments, count, countDistinct, countDistinctEdges, countEdges, createAdapterStore, createAdapterStoreWithSchema, createFragment, createQueryBuilder, createStore, createStoreWithSchema, createVerifiedAdapterStore, createVerifiedStore, defineSubgraphProject, field, having, havingEq, havingGt, havingGte, havingLt, havingLte, limitFragment, max, min, offsetFragment, orderByFragment, sum };
19309
- //# sourceMappingURL=chunk-DP7KC6CL.js.map
19310
- //# sourceMappingURL=chunk-DP7KC6CL.js.map
19587
+ //# sourceMappingURL=chunk-BCP7LLOY.js.map
19588
+ //# sourceMappingURL=chunk-BCP7LLOY.js.map