@nicia-ai/typegraph 0.43.0 → 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-KDRF3NR2.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-64LERBFM.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-JNXZQBN3.js → chunk-BCP7LLOY.js} +687 -456
  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-CTWZPYJW.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-BLBG2VZ5.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-L5AUCL5P.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-L2BYRYHC.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-NDQLPKBX.cjs → chunk-XR4YZFKW.cjs} +1740 -1509
  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-DHXw7QAl.d.cts → index-By89Sezh.d.ts} +37 -7
  212. package/dist/{index-DQzVJBHa.d.ts → 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-DpJqtbSX.d.cts → postgres-DaEWvN4x.d.cts} +1 -1
  232. package/dist/{postgres-C5-WMKFA.d.ts → 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-Ch5tSYQY.d.ts → sqlite-BrMoSsI7.d.cts} +1 -1
  248. package/dist/{sqlite-Da7jiYu9.d.cts → sqlite-CHhZUyO5.d.ts} +1 -1
  249. package/dist/{store-view-DdwBNjZQ.d.ts → store-view-Bvdku0Ht.d.ts} +181 -34
  250. package/dist/{store-view-D1F6KqsE.d.cts → store-view-w-md0nQ4.d.cts} +181 -34
  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.cts → types-Cjvkj0jA.d.cts} +351 -12
  256. package/dist/{types-Dh-EgT-w.d.ts → 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-42XYPKZU.js.map +0 -1
  261. package/dist/chunk-5Q3P6OIC.cjs.map +0 -1
  262. package/dist/chunk-5ZPRE4CV.cjs.map +0 -1
  263. package/dist/chunk-64LERBFM.cjs.map +0 -1
  264. package/dist/chunk-BLBG2VZ5.cjs.map +0 -1
  265. package/dist/chunk-CTWZPYJW.js.map +0 -1
  266. package/dist/chunk-ECU53PMN.cjs.map +0 -1
  267. package/dist/chunk-F2KVJ6FF.cjs.map +0 -1
  268. package/dist/chunk-FY4VY5EV.cjs.map +0 -1
  269. package/dist/chunk-HHBKGPEI.js.map +0 -1
  270. package/dist/chunk-JNXZQBN3.js.map +0 -1
  271. package/dist/chunk-KDRF3NR2.cjs.map +0 -1
  272. package/dist/chunk-KTBTSHU6.cjs.map +0 -1
  273. package/dist/chunk-L2BYRYHC.js.map +0 -1
  274. package/dist/chunk-L5AUCL5P.js.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-NDQLPKBX.cjs.map +0 -1
  278. package/dist/chunk-NXIZL7ZZ.js.map +0 -1
  279. package/dist/chunk-O7XVCLXW.cjs.map +0 -1
  280. package/dist/chunk-OYJSYDIH.js.map +0 -1
  281. package/dist/chunk-RAWG2FEU.js.map +0 -1
  282. package/dist/chunk-U3YRCZ5L.cjs +0 -12
  283. package/dist/chunk-UTTW2Q3M.cjs.map +0 -1
  284. package/dist/chunk-UZLEQFTV.js.map +0 -1
  285. package/dist/chunk-V2GZBPY2.cjs.map +0 -1
  286. package/dist/chunk-VGMNGWBR.cjs +0 -12
  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-L5AUCL5P.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-CTWZPYJW.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
  },
@@ -14326,6 +14323,8 @@ var HISTORY_STORE_BACKEND_KEYS = [
14326
14323
  "claimIndexMaterialization",
14327
14324
  "close",
14328
14325
  "commitSchemaVersion",
14326
+ "commitSchemaVersionIfKindsEmpty",
14327
+ "lockSchemaVersionForWrite",
14329
14328
  "compileSql",
14330
14329
  "countEdgesByKind",
14331
14330
  "countEdgesFrom",
@@ -14354,6 +14353,7 @@ var HISTORY_STORE_BACKEND_KEYS = [
14354
14353
  "execute",
14355
14354
  "executeTemporaryStatement",
14356
14355
  "findEdgesByKind",
14356
+ "findEdgesByEndpointSet",
14357
14357
  "findEdgesConnectedTo",
14358
14358
  "findNodesByKind",
14359
14359
  "fulltextSearch",
@@ -14399,7 +14399,8 @@ var HISTORY_STORE_BACKEND_KEYS = [
14399
14399
  "upsertFulltext",
14400
14400
  "upsertFulltextBatch",
14401
14401
  "vectorSearch",
14402
- "vectorStrategy"
14402
+ "vectorStrategy",
14403
+ "verifyContributions"
14403
14404
  ];
14404
14405
  function createHistoryStoreBackendProjection(backend) {
14405
14406
  return Object.freeze(
@@ -14501,18 +14502,6 @@ async function runBucketedMaterialization(items, options, bucketKey, runOne) {
14501
14502
  );
14502
14503
  return results;
14503
14504
  }
14504
- async function runMaterialization(items, options, runOne) {
14505
- if (options.stopOnError === true) {
14506
- const results = [];
14507
- for (const item of items) {
14508
- const entry2 = await runOne(item);
14509
- results.push(entry2);
14510
- if (entry2.status === "failed") break;
14511
- }
14512
- return results;
14513
- }
14514
- return Promise.all(items.map((item) => runOne(item)));
14515
- }
14516
14505
 
14517
14506
  // src/store/materialize-indexes.ts
14518
14507
  var CLAIM_LEASE_MS = 15 * 6e4;
@@ -15216,21 +15205,38 @@ function buildPendingKindRemoval(args) {
15216
15205
  }
15217
15206
  async function materializeRemovals(context, options = {}) {
15218
15207
  const { backend, graphId } = context;
15219
- if (backend.executeDdl === void 0 || backend.recordKindRemoval === void 0 || backend.getPendingKindRemovals === void 0) {
15208
+ if (backend.recordKindRemoval === void 0 || backend.getPendingKindRemovals === void 0) {
15220
15209
  throw new ConfigurationError(
15221
- "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.",
15222
15211
  { code: "MATERIALIZE_REMOVALS_BACKEND_UNSUPPORTED" }
15223
15212
  );
15224
15213
  }
15225
15214
  await ensureFocusedStatusTable(backend, backend.ensureKindRemovalsTable);
15226
15215
  await reconcilePendingRemovals(context);
15227
- 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
+ );
15228
15222
  const pending = await backend.getPendingKindRemovals(graphId);
15223
+ const liveKinds = liveKindNamesFrom(activeSchema);
15229
15224
  const kindFilter = options.kinds === void 0 ? void 0 : new Set(options.kinds);
15230
- const candidates = pending.filter(
15231
- (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)
15232
15230
  );
15233
- 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
+ }
15234
15240
  const tableNames = backend.tableNames;
15235
15241
  const nodesTable = tableNames?.nodes ?? "typegraph_nodes";
15236
15242
  const edgesTable = tableNames?.edges ?? "typegraph_edges";
@@ -15247,14 +15253,13 @@ async function materializeRemovals(context, options = {}) {
15247
15253
  captureRecordedRemovals,
15248
15254
  recordedSchema: captureRecordedRemovals ? context.recordedSchema ?? createSqlSchema(backend.tableNames) : void 0
15249
15255
  };
15250
- return {
15251
- results: await runMaterialization(
15252
- candidates,
15253
- options,
15254
- (removal) => materializeOne2(removal, ctx)
15255
- ),
15256
- reclaimedVectorFields
15257
- };
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 };
15258
15263
  }
15259
15264
  async function reconcilePendingRemovals(context) {
15260
15265
  const { backend, graphId } = context;
@@ -15322,14 +15327,49 @@ async function reconcilePendingRemovals(context) {
15322
15327
  await backend.setReconciliationMarker(graphId, activeRow.version);
15323
15328
  }
15324
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
+ }
15325
15339
  function kindRemovalKey(entity, kindName, version) {
15326
15340
  return `${entity}|${kindName}|${version}`;
15327
15341
  }
15328
15342
  async function materializeOne2(row, ctx) {
15329
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
+ }
15330
15351
  try {
15331
- await closeRecordedAndDeleteLiveRows(ctx, row);
15332
- 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
+ }
15333
15373
  const removedAt = nowIso();
15334
15374
  await recordKindRemoval({
15335
15375
  graphId: ctx.graphId,
@@ -15364,28 +15404,33 @@ async function materializeOne2(row, ctx) {
15364
15404
  };
15365
15405
  }
15366
15406
  }
15367
- async function closeRecordedAndDeleteLiveRows(ctx, row) {
15407
+ async function closeRecordedAndDeleteLiveRows(ctx, row, target) {
15368
15408
  const deleteStatements = buildRemovedKindLiveDeleteStatements(ctx, row);
15369
15409
  if (!ctx.captureRecordedRemovals || ctx.recordedSchema === void 0) {
15370
- await executeDeleteStatements(ctx.backend, deleteStatements);
15410
+ await executeDeleteStatements(target, deleteStatements);
15371
15411
  return;
15372
15412
  }
15373
15413
  const recordedSchema = ctx.recordedSchema;
15374
- try {
15375
- await ctx.backend.transaction(async (target) => {
15376
- await closeRecordedHardDeletedKind(
15377
- target,
15378
- recordedSchema,
15379
- ctx.graphId,
15380
- { entity: row.entity, kind: row.kindName },
15381
- false
15382
- );
15383
- await executeDeleteStatements(target, deleteStatements);
15384
- });
15385
- } catch (error) {
15386
- if (!isMissingTableError(error)) throw error;
15387
- 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;
15388
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);
15389
15434
  }
15390
15435
  function buildRemovedKindLiveDeleteStatements(ctx, row) {
15391
15436
  const graphLit = literal(ctx.graphId);
@@ -15403,41 +15448,22 @@ function buildRemovedKindLiveDeleteStatements(ctx, row) {
15403
15448
  ];
15404
15449
  }
15405
15450
  async function executeDeleteStatements(target, statements) {
15406
- if (target.executeStatement !== void 0) {
15407
- await Promise.all(
15408
- statements.map(
15409
- (statement) => requireDefined(target.executeStatement)(
15410
- asCompiledStatementSql(sql.raw(statement))
15411
- )
15412
- )
15413
- );
15414
- return;
15451
+ for (const statement of statements) {
15452
+ await target.executeStatement(asCompiledStatementSql(sql.raw(statement)));
15415
15453
  }
15416
- if (target.executeDdl === void 0) {
15417
- throw new ConfigurationError(
15418
- "store.materializeRemovals() requires a backend that can execute cleanup statements.",
15419
- { code: "MATERIALIZE_REMOVALS_BACKEND_UNSUPPORTED" }
15420
- );
15421
- }
15422
- await Promise.all(
15423
- statements.map((statement) => requireDefined(target.executeDdl)(statement))
15424
- );
15425
15454
  }
15426
- function buildEmbeddingTableCleanup(ctx, row) {
15455
+ async function dropEmbeddingTableStorage(ctx, row, target) {
15427
15456
  const vectorStrategy = ctx.backend.vectorStrategy;
15428
- if (vectorStrategy === void 0) return [];
15429
- const executeDdl = requireDefined(ctx.backend.executeDdl);
15430
- const cleanup = (async () => {
15431
- const slots = await resolveRemovedKindEmbeddingSlots(ctx.backend, row);
15432
- await Promise.all(
15433
- slots.map(
15434
- (slot) => dropVectorSlotStorage(ctx.backend, vectorStrategy, executeDdl, slot)
15435
- )
15436
- );
15437
- })();
15438
- 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
+ }
15439
15465
  }
15440
- async function dropVectorSlotStorage(backend, strategy, executeDdl, slot) {
15466
+ async function dropVectorSlotStorage(strategy, executeDdl, slot) {
15441
15467
  try {
15442
15468
  for (const ddl of strategy.buildDropStorage(slot)) {
15443
15469
  await executeDdl(ddl);
@@ -15445,7 +15471,6 @@ async function dropVectorSlotStorage(backend, strategy, executeDdl, slot) {
15445
15471
  } catch (error) {
15446
15472
  if (!isMissingTableError(error)) throw error;
15447
15473
  }
15448
- await backend.deleteVectorSlotContribution?.(slot);
15449
15474
  }
15450
15475
  async function resolveRemovedKindEmbeddingSlots(backend, row) {
15451
15476
  const priorVersion = row.schemaVersion - 1;
@@ -15471,26 +15496,26 @@ async function resolveRemovedKindEmbeddingSlots(backend, row) {
15471
15496
  function vectorFieldKey(kind, fieldPath) {
15472
15497
  return `${kind}\0${fieldPath}`;
15473
15498
  }
15474
- 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) {
15475
15509
  const { backend, graphId } = context;
15476
15510
  const vectorStrategy = backend.vectorStrategy;
15477
- const executeDdl = backend.executeDdl;
15478
- if (vectorStrategy === void 0 || executeDdl === void 0) return [];
15479
- const activeRow = await backend.getActiveSchema(graphId);
15511
+ if (vectorStrategy === void 0) return [];
15480
15512
  if (activeRow === void 0) return [];
15481
15513
  const cacheKey = `${graphId}\0${activeRow.version}`;
15482
15514
  let perBackend = reclaimCache.get(backend);
15483
15515
  const cached = perBackend?.get(cacheKey);
15484
15516
  if (cached !== void 0) return cached;
15485
15517
  const activeSchema = parseSerializedSchema(activeRow.schema_doc);
15486
- const activeVectorFields = /* @__PURE__ */ new Set();
15487
- for (const declaration of activeSchema.indexes ?? []) {
15488
- if (declaration.entity === "vector") {
15489
- activeVectorFields.add(
15490
- vectorFieldKey(declaration.kind, declaration.fieldPath)
15491
- );
15492
- }
15493
- }
15518
+ const activeVectorFields = vectorFieldKeysFrom(activeSchema);
15494
15519
  const survivingKinds = new Set(Object.keys(activeSchema.nodes));
15495
15520
  const historical = /* @__PURE__ */ new Map();
15496
15521
  for (let version = activeRow.version - 1; version >= 1; version -= 1) {
@@ -15519,14 +15544,43 @@ async function reclaimRemovedVectorFieldTables(context) {
15519
15544
  (field2) => !activeVectorFields.has(vectorFieldKey(field2.kind, field2.fieldPath)) && survivingKinds.has(field2.kind)
15520
15545
  );
15521
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
+ }
15522
15555
  for (const field2 of orphans) {
15523
15556
  try {
15524
- await dropVectorSlotStorage(
15525
- backend,
15526
- vectorStrategy,
15527
- executeDdl,
15528
- 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
+ }
15529
15579
  );
15580
+ if (!reclaimed) {
15581
+ skippedAfterLockedRecheck = true;
15582
+ continue;
15583
+ }
15530
15584
  results.push({
15531
15585
  kind: field2.kind,
15532
15586
  fieldPath: field2.fieldPath,
@@ -15541,7 +15595,7 @@ async function reclaimRemovedVectorFieldTables(context) {
15541
15595
  });
15542
15596
  }
15543
15597
  }
15544
- if (results.every((entry2) => entry2.status === "reclaimed")) {
15598
+ if (!skippedAfterLockedRecheck && results.every((entry2) => entry2.status === "reclaimed")) {
15545
15599
  if (perBackend === void 0) {
15546
15600
  perBackend = /* @__PURE__ */ new Map();
15547
15601
  reclaimCache.set(backend, perBackend);
@@ -16211,7 +16265,7 @@ async function executeEdgeBulkGetOrCreateByEndpoints(ctx, kind, items, backend,
16211
16265
  validatedProps,
16212
16266
  matchOn
16213
16267
  );
16214
- const endpointKey = buildEndpointPairKey(
16268
+ const endpointKey2 = buildEndpointPairKey(
16215
16269
  item.fromKind,
16216
16270
  item.fromId,
16217
16271
  item.toKind,
@@ -16224,7 +16278,7 @@ async function executeEdgeBulkGetOrCreateByEndpoints(ctx, kind, items, backend,
16224
16278
  toId: item.toId,
16225
16279
  validatedProps,
16226
16280
  compositeKey,
16227
- endpointKey,
16281
+ endpointKey: endpointKey2,
16228
16282
  ...validFrom !== void 0 && { validFrom },
16229
16283
  ...validTo !== void 0 && { validTo }
16230
16284
  });
@@ -16242,7 +16296,7 @@ async function executeEdgeBulkGetOrCreateByEndpoints(ctx, kind, items, backend,
16242
16296
  }
16243
16297
  async function fetchRowsByEndpoint(reader) {
16244
16298
  const rowsByEndpoint = /* @__PURE__ */ new Map();
16245
- for (const [endpointKey, endpoint] of uniqueEndpoints) {
16299
+ for (const [endpointKey2, endpoint] of uniqueEndpoints) {
16246
16300
  const rows = await reader.findEdgesByKind({
16247
16301
  graphId: ctx.graphId,
16248
16302
  kind,
@@ -16253,7 +16307,7 @@ async function executeEdgeBulkGetOrCreateByEndpoints(ctx, kind, items, backend,
16253
16307
  excludeDeleted: false,
16254
16308
  temporalMode: "includeTombstones"
16255
16309
  });
16256
- rowsByEndpoint.set(endpointKey, rows);
16310
+ rowsByEndpoint.set(endpointKey2, rows);
16257
16311
  }
16258
16312
  return rowsByEndpoint;
16259
16313
  }
@@ -16914,6 +16968,39 @@ function syncStoreReplacementRef(ref, replacement) {
16914
16968
  if (ref === void 0) return;
16915
16969
  ref.current = replacement;
16916
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
+ }
16917
17004
  var StoreImplementation = class _StoreImplementation {
16918
17005
  [STORE_RUNTIME];
16919
17006
  #graph;
@@ -17759,19 +17846,54 @@ var StoreImplementation = class _StoreImplementation {
17759
17846
  }
17760
17847
  // === Batch Query Execution ===
17761
17848
  /**
17762
- * 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.
17763
17858
  *
17764
- * Each query preserves its own result type, projection, filtering, sorting,
17765
- * and pagination.
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.
17766
17868
  *
17767
- * **Snapshot consistency is conditional.** When
17768
- * `backend.capabilities.transactions` is `true`, queries run sequentially
17769
- * on a single connection inside an implicit transaction and observe the
17770
- * same database snapshot. When transactions are unavailable
17771
- * (Cloudflare D1, `drizzle-orm/neon-http`), queries run sequentially over
17772
- * independent connections and may observe writes that landed between them.
17773
- * Branch on `backend.capabilities.transactions` if you need a guaranteed
17774
- * snapshot.
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.
17880
+ *
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.
17889
+ *
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.
17775
17897
  *
17776
17898
  * Read-only — use `bulkCreate`, `bulkInsert`, etc. for write batching.
17777
17899
  *
@@ -17796,9 +17918,10 @@ var StoreImplementation = class _StoreImplementation {
17796
17918
  */
17797
17919
  async batch(...queries) {
17798
17920
  return runOptionallyInTransaction(this.#baseBackend, async (target) => {
17921
+ const queryBackend = this.#createHookedQueryBackend(target);
17799
17922
  const results = [];
17800
17923
  for (const query of queries) {
17801
- const result = await query.executeOn(target);
17924
+ const result = await query.executeOn(queryBackend);
17802
17925
  results.push(result);
17803
17926
  }
17804
17927
  return results;
@@ -18080,6 +18203,13 @@ var StoreImplementation = class _StoreImplementation {
18080
18203
  const txBackend = adopt(externalTx);
18081
18204
  if (this.#captureEnabled) {
18082
18205
  await assertRecordedCaptureTransactionIsolation(txBackend);
18206
+ await lockSchemaVersionForStoreWrite(
18207
+ {
18208
+ graphId: this.graphId,
18209
+ schemaVersion: this.#schemaMetadata.schemaVersion
18210
+ },
18211
+ txBackend
18212
+ );
18083
18213
  }
18084
18214
  const scope = this.#captureEnabled ? createRecordedTransactionScope(txBackend, this.#sqlSchema()) : {
18085
18215
  backend: txBackend,
@@ -18249,6 +18379,7 @@ var StoreImplementation = class _StoreImplementation {
18249
18379
  };
18250
18380
  await (this.#baseBackend.capabilities.transactions ? this.#baseBackend.transaction(async (tx) => doClear(tx)) : doClear(this.#baseBackend));
18251
18381
  await this.#clearVectorStorage();
18382
+ this.#schemaMetadata = UNKNOWN_SCHEMA_METADATA;
18252
18383
  this.#nodeCollections = void 0;
18253
18384
  this.#edgeCollections = void 0;
18254
18385
  this.#algorithms = void 0;
@@ -18385,6 +18516,7 @@ var StoreImplementation = class _StoreImplementation {
18385
18516
  }
18386
18517
  return caughtUp;
18387
18518
  }
18519
+ await this.#assertNoPendingRemovalFor(merged, baseline);
18388
18520
  const baselineDocument = baseline.extension ?? Object.freeze({});
18389
18521
  const classification = classifyModifications(baselineDocument, extension);
18390
18522
  if (classification.incompatible.length > 0) {
@@ -18393,20 +18525,12 @@ var StoreImplementation = class _StoreImplementation {
18393
18525
  this.graphId
18394
18526
  );
18395
18527
  }
18396
- if (classification.requireEmpty.length > 0) {
18397
- const nonEmpty = await this.#probeEmptyKinds(classification.requireEmpty);
18398
- const error = buildIncompatibleChangeError(
18399
- classification,
18400
- nonEmpty,
18401
- this.graphId
18402
- );
18403
- if (error !== void 0) throw error;
18404
- }
18405
- const committed = await commitNewSchemaVersion(
18528
+ const committed = classification.requireEmpty.length > 0 ? await commitEvolvedSchemaWhenRequiredKindsAreEmpty(
18406
18529
  this.#backend,
18407
18530
  merged,
18408
- activeRow.version
18409
- );
18531
+ activeRow.version,
18532
+ classification
18533
+ ) : await commitNewSchemaVersion(this.#backend, merged, activeRow.version);
18410
18534
  await materializeVectorContributions(this.#backend, merged);
18411
18535
  const evolved = this.#cloneWithGraph(
18412
18536
  merged,
@@ -18681,6 +18805,65 @@ var StoreImplementation = class _StoreImplementation {
18681
18805
  }
18682
18806
  return { recreated: true, reembedded };
18683
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
+ }
18684
18867
  /**
18685
18868
  * Removes extension kinds from the schema with cascading edge and
18686
18869
  * ontology cleanup. Two-phase by design:
@@ -18861,42 +19044,36 @@ var StoreImplementation = class _StoreImplementation {
18861
19044
  return { activeRow, storedSchema, baseline };
18862
19045
  }
18863
19046
  /**
18864
- * Probes each `requireEmpty` entry for any rows. Returns the set of
18865
- * composite keys (`${entity}:${kindName}`) that have at least one
18866
- * row — those entries need to be promoted from "allowed-on-empty"
18867
- * to incompatible. Dispatches to `countNodesByKind` for `node`
18868
- * entries and `countEdgesByKind` for `edge` entries (a single-
18869
- * primitive probe would always return 0 for the wrong-entity case
18870
- * and silently bypass the gate).
19047
+ * Refuses an evolve that re-adds a kind whose data cleanup is still pending.
18871
19048
  *
18872
- * Probes run in parallel; each entry is independent. Race window
18873
- * (probe → CAS commit): another writer can insert a row into a
18874
- * previously-empty kind. The schema commit still succeeds (CAS
18875
- * guards on schema version, not row count); the new schema rejects
18876
- * the inserted row at next read, which the operator inspects and
18877
- * either deletes or reverts. Rare in practice; tighter elimination
18878
- * would require `SELECT FOR UPDATE` on the rows table, too
18879
- * 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.
18880
19051
  */
18881
- async #probeEmptyKinds(requireEmpty) {
18882
- const probes = requireEmpty.map(
18883
- async (entry2) => {
18884
- const count2 = entry2.entity === "node" ? await this.#backend.countNodesByKind({
18885
- graphId: this.graphId,
18886
- kind: entry2.kindName
18887
- }) : await this.#backend.countEdgesByKind({
18888
- graphId: this.graphId,
18889
- kind: entry2.kindName
18890
- });
18891
- 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)
18892
19075
  }
18893
19076
  );
18894
- const results = await Promise.all(probes);
18895
- const nonEmpty = /* @__PURE__ */ new Set();
18896
- for (const [entry2, count2] of results) {
18897
- if (count2 > 0) nonEmpty.add(entry2);
18898
- }
18899
- return nonEmpty;
18900
19077
  }
18901
19078
  #cloneWithGraph(graph, ref, schemaMetadata = this.#schemaMetadata) {
18902
19079
  const next = this.#adapterBackend === void 0 ? new _StoreImplementation(
@@ -18932,6 +19109,7 @@ var StoreImplementation = class _StoreImplementation {
18932
19109
  return {
18933
19110
  graph: this.#graph,
18934
19111
  graphId: this.graphId,
19112
+ schemaVersion: this.#schemaMetadata.schemaVersion,
18935
19113
  historyEnabled: this.#captureEnabled,
18936
19114
  revisionTrackingEnabled: this.#revisionTrackingEnabled,
18937
19115
  revisionSchema: this.#sqlSchema(),
@@ -18944,6 +19122,7 @@ var StoreImplementation = class _StoreImplementation {
18944
19122
  return {
18945
19123
  graph: this.#graph,
18946
19124
  graphId: this.graphId,
19125
+ schemaVersion: this.#schemaMetadata.schemaVersion,
18947
19126
  historyEnabled: this.#captureEnabled,
18948
19127
  revisionTrackingEnabled: this.#revisionTrackingEnabled,
18949
19128
  revisionSchema: this.#sqlSchema(),
@@ -18953,6 +19132,57 @@ var StoreImplementation = class _StoreImplementation {
18953
19132
  };
18954
19133
  }
18955
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
+ }
18956
19186
  #createHookContext() {
18957
19187
  return {
18958
19188
  operationId: generateId(),
@@ -19034,13 +19264,14 @@ var StoreImplementation = class _StoreImplementation {
19034
19264
  };
19035
19265
  }
19036
19266
  #createQueryForBackend(backend, sealedCoordinate) {
19267
+ const queryBackend = this.#createHookedQueryBackend(backend);
19037
19268
  return createInternalQueryBuilder(
19038
19269
  this.graphId,
19039
19270
  this.#registry,
19040
19271
  {
19041
19272
  // TransactionBackend omits transaction/close, but query execution only needs
19042
19273
  // the read-path/query capabilities shared with GraphBackend.
19043
- backend,
19274
+ backend: queryBackend,
19044
19275
  dialect: backend.dialect,
19045
19276
  defaultTraversalExpansion: this.#defaultTraversalExpansion,
19046
19277
  ...this.#schema !== void 0 && { schema: this.#schema },
@@ -19353,5 +19584,5 @@ async function createVerifiedAdapterStore(graph, backend, options) {
19353
19584
  }
19354
19585
 
19355
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 };
19356
- //# sourceMappingURL=chunk-JNXZQBN3.js.map
19357
- //# sourceMappingURL=chunk-JNXZQBN3.js.map
19587
+ //# sourceMappingURL=chunk-BCP7LLOY.js.map
19588
+ //# sourceMappingURL=chunk-BCP7LLOY.js.map