@nicia-ai/typegraph 0.44.0 → 0.46.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 (392) hide show
  1. package/dist/backend/drizzle/indexes.cjs +11 -11
  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 +7 -7
  5. package/dist/backend/index.cjs +53 -54
  6. package/dist/backend/index.d.cts +3 -3
  7. package/dist/backend/index.d.ts +3 -3
  8. package/dist/backend/index.js +13 -14
  9. package/dist/backend/postgres/index.cjs +29 -30
  10. package/dist/backend/postgres/index.d.cts +7 -7
  11. package/dist/backend/postgres/index.d.ts +7 -7
  12. package/dist/backend/postgres/index.js +16 -17
  13. package/dist/backend/postgres/pglite-store.cjs +48 -43
  14. package/dist/backend/postgres/pglite-store.cjs.map +1 -1
  15. package/dist/backend/postgres/pglite-store.d.cts +15 -9
  16. package/dist/backend/postgres/pglite-store.d.ts +15 -9
  17. package/dist/backend/postgres/pglite-store.js +44 -39
  18. package/dist/backend/postgres/pglite-store.js.map +1 -1
  19. package/dist/backend/postgres/pglite.cjs +18 -19
  20. package/dist/backend/postgres/pglite.d.cts +4 -4
  21. package/dist/backend/postgres/pglite.d.ts +4 -4
  22. package/dist/backend/postgres/pglite.js +17 -18
  23. package/dist/backend/sqlite/index.cjs +26 -27
  24. package/dist/backend/sqlite/index.d.cts +6 -6
  25. package/dist/backend/sqlite/index.d.ts +6 -6
  26. package/dist/backend/sqlite/index.js +14 -15
  27. package/dist/backend/sqlite/libsql.cjs +21 -22
  28. package/dist/backend/sqlite/libsql.cjs.map +1 -1
  29. package/dist/backend/sqlite/libsql.d.cts +15 -8
  30. package/dist/backend/sqlite/libsql.d.ts +15 -8
  31. package/dist/backend/sqlite/libsql.js +17 -18
  32. package/dist/backend/sqlite/libsql.js.map +1 -1
  33. package/dist/backend/sqlite/local-store.cjs +49 -44
  34. package/dist/backend/sqlite/local-store.cjs.map +1 -1
  35. package/dist/backend/sqlite/local-store.d.cts +15 -10
  36. package/dist/backend/sqlite/local-store.d.ts +15 -10
  37. package/dist/backend/sqlite/local-store.js +45 -40
  38. package/dist/backend/sqlite/local-store.js.map +1 -1
  39. package/dist/backend/sqlite/local.cjs +19 -20
  40. package/dist/backend/sqlite/local.d.cts +3 -3
  41. package/dist/backend/sqlite/local.d.ts +3 -3
  42. package/dist/backend/sqlite/local.js +17 -18
  43. package/dist/{chunk-XMYJY7NI.js → chunk-2LG2XB2M.js} +3 -3
  44. package/dist/{chunk-XMYJY7NI.js.map → chunk-2LG2XB2M.js.map} +1 -1
  45. package/dist/{chunk-QGKILWGZ.cjs → chunk-2NA5DYLO.cjs} +4 -4
  46. package/dist/{chunk-QGKILWGZ.cjs.map → chunk-2NA5DYLO.cjs.map} +1 -1
  47. package/dist/{chunk-5MUSU4ZP.cjs → chunk-3DHZCOT7.cjs} +20 -20
  48. package/dist/chunk-3DHZCOT7.cjs.map +1 -0
  49. package/dist/{chunk-OVUUTCPJ.cjs → chunk-4UGOKMI5.cjs} +268 -150
  50. package/dist/chunk-4UGOKMI5.cjs.map +1 -0
  51. package/dist/{chunk-FRHHDHKH.js → chunk-5262ZMTR.js} +26 -5
  52. package/dist/chunk-5262ZMTR.js.map +1 -0
  53. package/dist/{chunk-HOIFFY4M.js → chunk-5763DULU.js} +248 -76
  54. package/dist/chunk-5763DULU.js.map +1 -0
  55. package/dist/{chunk-7G32LIQM.js → chunk-5UVRGXD3.js} +277 -7
  56. package/dist/chunk-5UVRGXD3.js.map +1 -0
  57. package/dist/{chunk-IIT5K7SK.cjs → chunk-62ZP23AW.cjs} +15 -15
  58. package/dist/{chunk-IIT5K7SK.cjs.map → chunk-62ZP23AW.cjs.map} +1 -1
  59. package/dist/{chunk-S4KQ5LV4.js → chunk-775A4ZMN.js} +40 -6
  60. package/dist/chunk-775A4ZMN.js.map +1 -0
  61. package/dist/{chunk-QYWINYEA.cjs → chunk-7BQXPCGN.cjs} +830 -170
  62. package/dist/chunk-7BQXPCGN.cjs.map +1 -0
  63. package/dist/{chunk-FJMPR3OH.cjs → chunk-7EO3TCQB.cjs} +33 -7
  64. package/dist/chunk-7EO3TCQB.cjs.map +1 -0
  65. package/dist/chunk-7GT72YHH.cjs +1979 -0
  66. package/dist/chunk-7GT72YHH.cjs.map +1 -0
  67. package/dist/{chunk-SQRD2CYF.js → chunk-7VQXLT5O.js} +717 -76
  68. package/dist/chunk-7VQXLT5O.js.map +1 -0
  69. package/dist/{chunk-BCP7LLOY.js → chunk-7Z5OR7KO.js} +2706 -625
  70. package/dist/chunk-7Z5OR7KO.js.map +1 -0
  71. package/dist/chunk-A4OC4DVN.cjs +12 -0
  72. package/dist/{chunk-4SZ6XPTG.cjs.map → chunk-A4OC4DVN.cjs.map} +1 -1
  73. package/dist/{chunk-TDXIBCGY.cjs → chunk-A7J2YDDI.cjs} +5 -3
  74. package/dist/chunk-A7J2YDDI.cjs.map +1 -0
  75. package/dist/{chunk-FMMIX6N4.js → chunk-AKLS3BYZ.js} +56 -5
  76. package/dist/chunk-AKLS3BYZ.js.map +1 -0
  77. package/dist/{chunk-D7PG5D5K.js → chunk-AMKPPFUO.js} +32 -6
  78. package/dist/chunk-AMKPPFUO.js.map +1 -0
  79. package/dist/{chunk-PAW2XUZN.js → chunk-ASTI57H3.js} +3 -3
  80. package/dist/{chunk-PAW2XUZN.js.map → chunk-ASTI57H3.js.map} +1 -1
  81. package/dist/{chunk-FMGEZBAQ.js → chunk-BKCUOV7A.js} +27 -5
  82. package/dist/chunk-BKCUOV7A.js.map +1 -0
  83. package/dist/chunk-BSFJMMV3.cjs +268 -0
  84. package/dist/chunk-BSFJMMV3.cjs.map +1 -0
  85. package/dist/{chunk-63KCKSSH.js → chunk-C23WSN5E.js} +209 -24
  86. package/dist/chunk-C23WSN5E.js.map +1 -0
  87. package/dist/{chunk-JRP3VGHS.js → chunk-CBTIUB76.js} +3 -3
  88. package/dist/{chunk-JRP3VGHS.js.map → chunk-CBTIUB76.js.map} +1 -1
  89. package/dist/chunk-CNV4TXJG.js +58 -0
  90. package/dist/chunk-CNV4TXJG.js.map +1 -0
  91. package/dist/{chunk-QB6VMOJ2.cjs → chunk-CXBHOOIQ.cjs} +45 -10
  92. package/dist/chunk-CXBHOOIQ.cjs.map +1 -0
  93. package/dist/{chunk-46GDII45.js → chunk-DCQVHAYQ.js} +5 -5
  94. package/dist/{chunk-46GDII45.js.map → chunk-DCQVHAYQ.js.map} +1 -1
  95. package/dist/chunk-DLNROMQ7.js +306 -0
  96. package/dist/chunk-DLNROMQ7.js.map +1 -0
  97. package/dist/chunk-DYATYRY4.js +47 -0
  98. package/dist/chunk-DYATYRY4.js.map +1 -0
  99. package/dist/chunk-E4WNQBEF.cjs +217 -0
  100. package/dist/chunk-E4WNQBEF.cjs.map +1 -0
  101. package/dist/{chunk-G6Q5UM7U.js → chunk-FWJKWH6U.js} +5 -3
  102. package/dist/chunk-FWJKWH6U.js.map +1 -0
  103. package/dist/{chunk-BNUFUFAU.js → chunk-HFHTMECK.js} +7 -7
  104. package/dist/chunk-HFHTMECK.js.map +1 -0
  105. package/dist/{chunk-TFMVL4QH.js → chunk-I5MOXA4H.js} +20 -14
  106. package/dist/chunk-I5MOXA4H.js.map +1 -0
  107. package/dist/{chunk-4MB3AQAQ.js → chunk-J3WZ3FA2.js} +77 -3
  108. package/dist/chunk-J3WZ3FA2.js.map +1 -0
  109. package/dist/{chunk-UR7W5YQK.js → chunk-JBQQ7THH.js} +5 -3
  110. package/dist/chunk-JBQQ7THH.js.map +1 -0
  111. package/dist/chunk-JIVMTW7W.js +3393 -0
  112. package/dist/chunk-JIVMTW7W.js.map +1 -0
  113. package/dist/{chunk-2Y4IFKW7.js → chunk-JXA2ZP2Q.js} +6 -17
  114. package/dist/chunk-JXA2ZP2Q.js.map +1 -0
  115. package/dist/{chunk-GYA4JRP5.js → chunk-JXXDZTMN.js} +2 -2
  116. package/dist/chunk-JXXDZTMN.js.map +1 -0
  117. package/dist/chunk-JZUR7ZWE.js +254 -0
  118. package/dist/chunk-JZUR7ZWE.js.map +1 -0
  119. package/dist/chunk-K5ELX2GT.js +248 -0
  120. package/dist/chunk-K5ELX2GT.js.map +1 -0
  121. package/dist/chunk-LBJKZXDE.cjs +257 -0
  122. package/dist/chunk-LBJKZXDE.cjs.map +1 -0
  123. package/dist/{chunk-FGO5JFVJ.cjs → chunk-M4BDU5RX.cjs} +12 -12
  124. package/dist/{chunk-FGO5JFVJ.cjs.map → chunk-M4BDU5RX.cjs.map} +1 -1
  125. package/dist/{chunk-MIJKEVV7.js → chunk-MSY7FSX4.js} +37 -4
  126. package/dist/chunk-MSY7FSX4.js.map +1 -0
  127. package/dist/{chunk-ST3LPB2V.cjs → chunk-MUK4BU7K.cjs} +788 -146
  128. package/dist/chunk-MUK4BU7K.cjs.map +1 -0
  129. package/dist/{chunk-MCHP7RHZ.cjs → chunk-MXJDTH5B.cjs} +64 -41
  130. package/dist/chunk-MXJDTH5B.cjs.map +1 -0
  131. package/dist/{chunk-2VLBGQBY.cjs → chunk-N3257XE6.cjs} +724 -577
  132. package/dist/chunk-N3257XE6.cjs.map +1 -0
  133. package/dist/chunk-N66HCGCY.cjs +57 -0
  134. package/dist/chunk-N66HCGCY.cjs.map +1 -0
  135. package/dist/{chunk-CPEL3YIR.cjs → chunk-NFCVHQ5P.cjs} +55 -22
  136. package/dist/chunk-NFCVHQ5P.cjs.map +1 -0
  137. package/dist/{chunk-C4F7VJ5D.cjs → chunk-NI72YOJB.cjs} +84 -2
  138. package/dist/chunk-NI72YOJB.cjs.map +1 -0
  139. package/dist/{chunk-EE7N5XXQ.cjs → chunk-NK5Q7UNE.cjs} +10 -21
  140. package/dist/chunk-NK5Q7UNE.cjs.map +1 -0
  141. package/dist/{chunk-PHXITZE4.js → chunk-NMWDXFPH.js} +4 -4
  142. package/dist/{chunk-PHXITZE4.js.map → chunk-NMWDXFPH.js.map} +1 -1
  143. package/dist/{chunk-FSXTPBRN.js → chunk-NQ6BRJBE.js} +416 -850
  144. package/dist/chunk-NQ6BRJBE.js.map +1 -0
  145. package/dist/chunk-OH5E5KIO.js +2057 -0
  146. package/dist/chunk-OH5E5KIO.js.map +1 -0
  147. package/dist/chunk-ONU3HIED.cjs +2082 -0
  148. package/dist/chunk-ONU3HIED.cjs.map +1 -0
  149. package/dist/{chunk-STQ3BSED.cjs → chunk-PNN7RHVR.cjs} +66 -44
  150. package/dist/chunk-PNN7RHVR.cjs.map +1 -0
  151. package/dist/{chunk-6DCB664D.js → chunk-PQBQG7IM.js} +3 -3
  152. package/dist/{chunk-6DCB664D.js.map → chunk-PQBQG7IM.js.map} +1 -1
  153. package/dist/{chunk-ACSVZPK7.cjs → chunk-PWLJ77UV.cjs} +5 -3
  154. package/dist/chunk-PWLJ77UV.cjs.map +1 -0
  155. package/dist/chunk-Q7Q4WSLJ.cjs +328 -0
  156. package/dist/chunk-Q7Q4WSLJ.cjs.map +1 -0
  157. package/dist/{chunk-BEFM74L2.js → chunk-QLRESYPU.js} +637 -493
  158. package/dist/chunk-QLRESYPU.js.map +1 -0
  159. package/dist/{chunk-SBPC5IP3.js → chunk-QWX5YA3K.js} +784 -202
  160. package/dist/chunk-QWX5YA3K.js.map +1 -0
  161. package/dist/{chunk-TCRIQMBU.js → chunk-RJS7DECT.js} +8 -9
  162. package/dist/chunk-RJS7DECT.js.map +1 -0
  163. package/dist/{chunk-6JZUSDY2.cjs → chunk-RMQLSPA2.cjs} +297 -27
  164. package/dist/chunk-RMQLSPA2.cjs.map +1 -0
  165. package/dist/{chunk-SJDMVITW.cjs → chunk-RT5ZY4XA.cjs} +6 -5
  166. package/dist/chunk-RT5ZY4XA.cjs.map +1 -0
  167. package/dist/{chunk-IJTLXNGJ.js → chunk-T4XNKYXB.js} +780 -127
  168. package/dist/chunk-T4XNKYXB.js.map +1 -0
  169. package/dist/{chunk-PDGEXGS6.cjs → chunk-TQR4KBY2.cjs} +354 -182
  170. package/dist/chunk-TQR4KBY2.cjs.map +1 -0
  171. package/dist/chunk-TTAITEPJ.cjs +755 -0
  172. package/dist/chunk-TTAITEPJ.cjs.map +1 -0
  173. package/dist/{chunk-NN3QSOVS.cjs → chunk-U5SON7R2.cjs} +27 -27
  174. package/dist/{chunk-NN3QSOVS.cjs.map → chunk-U5SON7R2.cjs.map} +1 -1
  175. package/dist/{chunk-A2I2XO52.cjs → chunk-U63GDNRC.cjs} +32 -26
  176. package/dist/chunk-U63GDNRC.cjs.map +1 -0
  177. package/dist/{chunk-YNULOIR5.cjs → chunk-UDISNXDL.cjs} +64 -43
  178. package/dist/chunk-UDISNXDL.cjs.map +1 -0
  179. package/dist/{chunk-GWEDD3DH.js → chunk-UV3SN74I.js} +5 -5
  180. package/dist/{chunk-GWEDD3DH.js.map → chunk-UV3SN74I.js.map} +1 -1
  181. package/dist/{chunk-U5W4LKZV.cjs → chunk-VCRRKBLN.cjs} +9 -9
  182. package/dist/{chunk-U5W4LKZV.cjs.map → chunk-VCRRKBLN.cjs.map} +1 -1
  183. package/dist/{chunk-EFELJVLA.js → chunk-VGTJPTIC.js} +28 -5
  184. package/dist/chunk-VGTJPTIC.js.map +1 -0
  185. package/dist/chunk-VQH4VAWD.cjs +12 -0
  186. package/dist/{chunk-EPTSMFH7.cjs.map → chunk-VQH4VAWD.cjs.map} +1 -1
  187. package/dist/{chunk-SNXVDZAJ.js → chunk-W6OG3HDG.js} +5 -4
  188. package/dist/chunk-W6OG3HDG.js.map +1 -0
  189. package/dist/chunk-WDGA7IYB.js +207 -0
  190. package/dist/chunk-WDGA7IYB.js.map +1 -0
  191. package/dist/chunk-WEVQJ5LH.js +736 -0
  192. package/dist/chunk-WEVQJ5LH.js.map +1 -0
  193. package/dist/{chunk-3PRKZW6D.cjs → chunk-XBYVV3MP.cjs} +60 -5
  194. package/dist/chunk-XBYVV3MP.cjs.map +1 -0
  195. package/dist/{chunk-GFRGG2US.cjs → chunk-XCAGZAKP.cjs} +7 -7
  196. package/dist/{chunk-GFRGG2US.cjs.map → chunk-XCAGZAKP.cjs.map} +1 -1
  197. package/dist/{chunk-XR4YZFKW.cjs → chunk-XDF2UPEQ.cjs} +3864 -1783
  198. package/dist/chunk-XDF2UPEQ.cjs.map +1 -0
  199. package/dist/{chunk-7V2FGGI2.cjs → chunk-XMQSEJCF.cjs} +632 -1080
  200. package/dist/chunk-XMQSEJCF.cjs.map +1 -0
  201. package/dist/chunk-XNLIZYRZ.cjs +3432 -0
  202. package/dist/chunk-XNLIZYRZ.cjs.map +1 -0
  203. package/dist/{chunk-66UVLHQA.cjs → chunk-XNSI2FJO.cjs} +99 -100
  204. package/dist/chunk-XNSI2FJO.cjs.map +1 -0
  205. package/dist/chunk-XQSCL77R.cjs +60 -0
  206. package/dist/chunk-XQSCL77R.cjs.map +1 -0
  207. package/dist/{chunk-SVJ5GEXW.cjs → chunk-XUO3KQFO.cjs} +2 -2
  208. package/dist/chunk-XUO3KQFO.cjs.map +1 -0
  209. package/dist/{chunk-HJH3RMXG.cjs → chunk-YAAM3M2S.cjs} +10 -10
  210. package/dist/{chunk-HJH3RMXG.cjs.map → chunk-YAAM3M2S.cjs.map} +1 -1
  211. package/dist/{chunk-ATLN63JA.js → chunk-YBFHZUXX.js} +6 -6
  212. package/dist/{chunk-ATLN63JA.js.map → chunk-YBFHZUXX.js.map} +1 -1
  213. package/dist/{chunk-K3BUWSFR.js → chunk-YDFDBE6D.js} +119 -6
  214. package/dist/chunk-YDFDBE6D.js.map +1 -0
  215. package/dist/{chunk-OSZPLZIV.cjs → chunk-YVWGEQJE.cjs} +318 -132
  216. package/dist/chunk-YVWGEQJE.cjs.map +1 -0
  217. package/dist/{chunk-QT6V3YRH.js → chunk-YWGVVALJ.js} +3 -3
  218. package/dist/{chunk-QT6V3YRH.js.map → chunk-YWGVVALJ.js.map} +1 -1
  219. package/dist/core/index.cjs +40 -41
  220. package/dist/core/index.d.cts +4 -5
  221. package/dist/core/index.d.ts +4 -5
  222. package/dist/core/index.js +8 -9
  223. package/dist/{ddl-eWg7hx6R.d.cts → ddl-BJcOp4WZ.d.cts} +3 -3
  224. package/dist/{ddl-D5369kOY.d.ts → ddl-BXfGHbPN.d.ts} +3 -3
  225. package/dist/graph-extension/index.cjs +26 -23
  226. package/dist/graph-extension/index.d.cts +16 -6
  227. package/dist/graph-extension/index.d.ts +16 -6
  228. package/dist/graph-extension/index.js +7 -8
  229. package/dist/graph-merge/index.cjs +2459 -655
  230. package/dist/graph-merge/index.cjs.map +1 -1
  231. package/dist/graph-merge/index.d.cts +170 -33
  232. package/dist/graph-merge/index.d.ts +170 -33
  233. package/dist/graph-merge/index.js +2269 -468
  234. package/dist/graph-merge/index.js.map +1 -1
  235. package/dist/{index-By89Sezh.d.ts → index-BSHvKfok.d.ts} +221 -10
  236. package/dist/{index-DcQ3Sxs-.d.cts → index-DxaYCv8Y.d.cts} +221 -10
  237. package/dist/index.cjs +330 -269
  238. package/dist/index.cjs.map +1 -1
  239. package/dist/index.d.cts +590 -576
  240. package/dist/index.d.ts +590 -576
  241. package/dist/index.js +73 -50
  242. package/dist/index.js.map +1 -1
  243. package/dist/indexes/index.cjs +17 -17
  244. package/dist/indexes/index.d.cts +4 -4
  245. package/dist/indexes/index.d.ts +4 -4
  246. package/dist/indexes/index.js +10 -10
  247. package/dist/interchange/index.cjs +165 -50
  248. package/dist/interchange/index.cjs.map +1 -1
  249. package/dist/interchange/index.d.cts +261 -16
  250. package/dist/interchange/index.d.ts +261 -16
  251. package/dist/interchange/index.js +128 -24
  252. package/dist/interchange/index.js.map +1 -1
  253. package/dist/{manager-B0KjKE93.d.ts → manager-CfZAimti.d.ts} +36 -5
  254. package/dist/{manager-Cn0NFIhN.d.cts → manager-HGk6E_HW.d.cts} +36 -5
  255. package/dist/{materialize-indexes-BD4V3svD.d.ts → materialize-indexes-6A7dWGtb.d.cts} +10 -2
  256. package/dist/{materialize-indexes-DVRhd5h4.d.cts → materialize-indexes-BMJP6Tms.d.ts} +10 -2
  257. package/dist/{postgres-DaEWvN4x.d.cts → postgres-DFYWENdR.d.cts} +1961 -439
  258. package/dist/{postgres-u0a0HN2D.d.ts → postgres-e7a9TdvR.d.ts} +1961 -439
  259. package/dist/profiler/index.cjs +15 -15
  260. package/dist/profiler/index.d.cts +9 -10
  261. package/dist/profiler/index.d.ts +9 -10
  262. package/dist/profiler/index.js +4 -4
  263. package/dist/provenance/index.cjs +46 -48
  264. package/dist/provenance/index.cjs.map +1 -1
  265. package/dist/provenance/index.d.cts +7 -7
  266. package/dist/provenance/index.d.ts +7 -7
  267. package/dist/provenance/index.js +12 -14
  268. package/dist/provenance/index.js.map +1 -1
  269. package/dist/schema/index.cjs +50 -49
  270. package/dist/schema/index.d.cts +9 -16
  271. package/dist/schema/index.d.ts +9 -16
  272. package/dist/schema/index.js +23 -22
  273. package/dist/{searchable-CnYEancP.d.ts → searchable-9OQoPuRs.d.ts} +1 -2
  274. package/dist/{searchable-BT7j9_IK.d.cts → searchable-CIje5XYD.d.cts} +1 -2
  275. package/dist/{sqlite-BrMoSsI7.d.cts → sqlite-DerU5tc7.d.ts} +2029 -347
  276. package/dist/{sqlite-CHhZUyO5.d.ts → sqlite-DitnISa9.d.cts} +2029 -347
  277. package/dist/{store-view-Bvdku0Ht.d.ts → store-DawaWWjJ.d.ts} +3145 -2556
  278. package/dist/{store-view-w-md0nQ4.d.cts → store-RwTJx8LX.d.cts} +3145 -2556
  279. package/dist/{temporal-BCORwUau.d.cts → temporal-Bn-Fi8FJ.d.cts} +1 -1
  280. package/dist/{temporal--x9T8K4S.d.ts → temporal-BtM4UALv.d.ts} +1 -1
  281. package/dist/{types-6-WJmSD4.d.cts → types-CoIx8HX5.d.cts} +1 -1
  282. package/dist/{types-Cjvkj0jA.d.ts → types-HkveCCx0.d.cts} +866 -21
  283. package/dist/{types-Cjvkj0jA.d.cts → types-HkveCCx0.d.ts} +866 -21
  284. package/dist/{types-COODtTJU.d.ts → types-KFfk-8Ah.d.ts} +1 -1
  285. package/dist/{where-CUQmCR6d.d.cts → where--fk7_0kv.d.cts} +1 -1
  286. package/dist/{where-5xVawAwL.d.ts → where-ws5hf-Ov.d.ts} +1 -1
  287. package/package.json +1 -1
  288. package/dist/chunk-2BIG7U6E.cjs +0 -83
  289. package/dist/chunk-2BIG7U6E.cjs.map +0 -1
  290. package/dist/chunk-2L54C2C2.js +0 -144
  291. package/dist/chunk-2L54C2C2.js.map +0 -1
  292. package/dist/chunk-2VLBGQBY.cjs.map +0 -1
  293. package/dist/chunk-2WDD2NO3.js +0 -59
  294. package/dist/chunk-2WDD2NO3.js.map +0 -1
  295. package/dist/chunk-2Y4IFKW7.js.map +0 -1
  296. package/dist/chunk-35S6P5ZU.js +0 -27
  297. package/dist/chunk-35S6P5ZU.js.map +0 -1
  298. package/dist/chunk-3PRKZW6D.cjs.map +0 -1
  299. package/dist/chunk-4MB3AQAQ.js.map +0 -1
  300. package/dist/chunk-4SZ6XPTG.cjs +0 -12
  301. package/dist/chunk-5MUSU4ZP.cjs.map +0 -1
  302. package/dist/chunk-63KCKSSH.js.map +0 -1
  303. package/dist/chunk-66UVLHQA.cjs.map +0 -1
  304. package/dist/chunk-6JZUSDY2.cjs.map +0 -1
  305. package/dist/chunk-764JHTLT.cjs +0 -15
  306. package/dist/chunk-764JHTLT.cjs.map +0 -1
  307. package/dist/chunk-7G32LIQM.js.map +0 -1
  308. package/dist/chunk-7V2FGGI2.cjs.map +0 -1
  309. package/dist/chunk-A2I2XO52.cjs.map +0 -1
  310. package/dist/chunk-A4PBRX4C.cjs +0 -100
  311. package/dist/chunk-A4PBRX4C.cjs.map +0 -1
  312. package/dist/chunk-ACSVZPK7.cjs.map +0 -1
  313. package/dist/chunk-ALFUGRYB.cjs +0 -1282
  314. package/dist/chunk-ALFUGRYB.cjs.map +0 -1
  315. package/dist/chunk-B75XRV3O.js +0 -125
  316. package/dist/chunk-B75XRV3O.js.map +0 -1
  317. package/dist/chunk-BCP7LLOY.js.map +0 -1
  318. package/dist/chunk-BEFM74L2.js.map +0 -1
  319. package/dist/chunk-BNUFUFAU.js.map +0 -1
  320. package/dist/chunk-C4F7VJ5D.cjs.map +0 -1
  321. package/dist/chunk-CPEL3YIR.cjs.map +0 -1
  322. package/dist/chunk-D7PG5D5K.js.map +0 -1
  323. package/dist/chunk-DI74SMXS.cjs +0 -29
  324. package/dist/chunk-DI74SMXS.cjs.map +0 -1
  325. package/dist/chunk-DK2S42XB.js +0 -77
  326. package/dist/chunk-DK2S42XB.js.map +0 -1
  327. package/dist/chunk-DRACN6XG.js +0 -27
  328. package/dist/chunk-DRACN6XG.js.map +0 -1
  329. package/dist/chunk-EE7N5XXQ.cjs.map +0 -1
  330. package/dist/chunk-EFELJVLA.js.map +0 -1
  331. package/dist/chunk-EPTSMFH7.cjs +0 -12
  332. package/dist/chunk-EQ7JKLZO.cjs +0 -157
  333. package/dist/chunk-EQ7JKLZO.cjs.map +0 -1
  334. package/dist/chunk-FJMPR3OH.cjs.map +0 -1
  335. package/dist/chunk-FMGEZBAQ.js.map +0 -1
  336. package/dist/chunk-FMMIX6N4.js.map +0 -1
  337. package/dist/chunk-FRHHDHKH.js.map +0 -1
  338. package/dist/chunk-FSXTPBRN.js.map +0 -1
  339. package/dist/chunk-G6Q5UM7U.js.map +0 -1
  340. package/dist/chunk-GYA4JRP5.js.map +0 -1
  341. package/dist/chunk-HOHAJ2NR.cjs +0 -61
  342. package/dist/chunk-HOHAJ2NR.cjs.map +0 -1
  343. package/dist/chunk-HOIFFY4M.js.map +0 -1
  344. package/dist/chunk-IIMQJYAM.js +0 -81
  345. package/dist/chunk-IIMQJYAM.js.map +0 -1
  346. package/dist/chunk-IJTLXNGJ.js.map +0 -1
  347. package/dist/chunk-ITE4IXAK.js +0 -25
  348. package/dist/chunk-ITE4IXAK.js.map +0 -1
  349. package/dist/chunk-K3BUWSFR.js.map +0 -1
  350. package/dist/chunk-KCO5EFJU.js +0 -79
  351. package/dist/chunk-KCO5EFJU.js.map +0 -1
  352. package/dist/chunk-KKYELPZ2.cjs +0 -83
  353. package/dist/chunk-KKYELPZ2.cjs.map +0 -1
  354. package/dist/chunk-MCHP7RHZ.cjs.map +0 -1
  355. package/dist/chunk-MIJKEVV7.js.map +0 -1
  356. package/dist/chunk-NCX65HBY.cjs +0 -1396
  357. package/dist/chunk-NCX65HBY.cjs.map +0 -1
  358. package/dist/chunk-OSZPLZIV.cjs.map +0 -1
  359. package/dist/chunk-OVUUTCPJ.cjs.map +0 -1
  360. package/dist/chunk-PDGEXGS6.cjs.map +0 -1
  361. package/dist/chunk-QB6VMOJ2.cjs.map +0 -1
  362. package/dist/chunk-QMQLUA66.js +0 -12
  363. package/dist/chunk-QMQLUA66.js.map +0 -1
  364. package/dist/chunk-QYWINYEA.cjs.map +0 -1
  365. package/dist/chunk-S4KQ5LV4.js.map +0 -1
  366. package/dist/chunk-SBPC5IP3.js.map +0 -1
  367. package/dist/chunk-SJDMVITW.cjs.map +0 -1
  368. package/dist/chunk-SNXVDZAJ.js.map +0 -1
  369. package/dist/chunk-SQRD2CYF.js.map +0 -1
  370. package/dist/chunk-ST3LPB2V.cjs.map +0 -1
  371. package/dist/chunk-STQ3BSED.cjs.map +0 -1
  372. package/dist/chunk-SVJ5GEXW.cjs.map +0 -1
  373. package/dist/chunk-TCRIQMBU.js.map +0 -1
  374. package/dist/chunk-TDXIBCGY.cjs.map +0 -1
  375. package/dist/chunk-TFMVL4QH.js.map +0 -1
  376. package/dist/chunk-TRF4EBJT.cjs +0 -30
  377. package/dist/chunk-TRF4EBJT.cjs.map +0 -1
  378. package/dist/chunk-TVLKA4AY.js +0 -94
  379. package/dist/chunk-TVLKA4AY.js.map +0 -1
  380. package/dist/chunk-UR7W5YQK.js.map +0 -1
  381. package/dist/chunk-VITTKBWF.js +0 -1263
  382. package/dist/chunk-VITTKBWF.js.map +0 -1
  383. package/dist/chunk-WBUFJ7BS.cjs +0 -131
  384. package/dist/chunk-WBUFJ7BS.cjs.map +0 -1
  385. package/dist/chunk-XR4YZFKW.cjs.map +0 -1
  386. package/dist/chunk-YNULOIR5.cjs.map +0 -1
  387. package/dist/chunk-ZDH3DX3C.cjs +0 -30
  388. package/dist/chunk-ZDH3DX3C.cjs.map +0 -1
  389. package/dist/chunk-ZTAJL4DT.cjs +0 -85
  390. package/dist/chunk-ZTAJL4DT.cjs.map +0 -1
  391. package/dist/define-graph-DVF-oN1i.d.cts +0 -173
  392. package/dist/define-graph-SvYXOl78.d.ts +0 -173
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/store/types.ts","../src/store/runtime-port.ts","../src/store/embedding-sync.ts","../src/store/fulltext-sync.ts","../src/store/uniqueness.ts","../src/store/operations/node-write-pipeline.ts"],"names":[],"mappings":"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","file":"chunk-WEVQJ5LH.js","sourcesContent":["/**\n * Store types for TypeGraph operations.\n */\nimport { type z } from \"zod\";\n\nimport {\n type EdgeRow,\n type NodeRow,\n type TransactionBackend,\n type TransactionReadBackend,\n} from \"../backend/types\";\nimport {\n type EdgeKinds,\n type GraphDef,\n type GraphIdentityConfig,\n type NodeKinds,\n} from \"../core/define-graph\";\nimport { type RecordedInstant } from \"../core/temporal\";\nimport {\n type AnyEdgeType,\n type EdgeId,\n type EdgeRegistration,\n type EdgeType,\n type KindEntity,\n type NodeId,\n type NodeRegistration,\n type NodeType,\n type TemporalMode,\n} from \"../core/types\";\nimport type { IdentityFacade, IdentityWriteSummary } from \"../identity/types\";\nimport type { TraversalExpansion } from \"../query/ast\";\nimport type {\n DynamicEdgeAccessor,\n DynamicNodeAccessor,\n} from \"../query/builder\";\nimport type { BatchableQuery, NodeAccessor } from \"../query/builder/types\";\nimport {\n type ExternalRecordedReadSource,\n type SqlSchema,\n} from \"../query/compiler/schema\";\nimport type { Predicate } from \"../query/predicates\";\nimport { typeGraphGlobalSymbol } from \"../utils/global-symbol\";\nimport type {\n CURRENT_ONLY_READ_NAMES,\n EDGE_BATCH_READ_NAMES,\n EDGE_TEMPORAL_READ_NAMES,\n EDGE_WRITE_NAMES,\n NODE_TEMPORAL_READ_NAMES,\n NODE_WRITE_NAMES,\n RECORDED_POINT_READ_NAMES,\n} from \"./collection-surface\";\n\n// ============================================================\n// Row-to-Meta Field Mapping\n// ============================================================\n\n/**\n * Canonical mapping from snake_case row fields to camelCase meta fields.\n *\n * This is the single source of truth for which row columns become metadata.\n * Both the Meta types and the row-to-meta functions in row-mappers.ts must\n * stay in sync with this mapping. If you add a temporal/audit column to a\n * row type, add the mapping here — the compiler will then force you to\n * update the row mapper functions as well (since their return type is\n * NodeMeta/EdgeMeta, which is derived from this mapping).\n */\ntype TemporalMetaFieldMap = Readonly<{\n valid_from: \"validFrom\";\n valid_to: \"validTo\";\n created_at: \"createdAt\";\n updated_at: \"updatedAt\";\n deleted_at: \"deletedAt\";\n}>;\n\n/**\n * Maps row fields to their camelCase meta counterparts, preserving types.\n */\ntype MapRowToMeta<\n R extends Readonly<Record<string, unknown>>,\n M extends Readonly<Record<string, string>>,\n> = Readonly<{\n [SnakeKey in keyof M as M[SnakeKey] & string]: SnakeKey extends keyof R ?\n R[SnakeKey]\n : never;\n}>;\n\n// ============================================================\n// Node Instance Types\n// ============================================================\n\n/**\n * Metadata for a node instance.\n * Derived from NodeRow via TemporalMetaFieldMap + version.\n *\n * Adding a new metadata column requires:\n * 1. Add the column to NodeRow in backend/types.ts\n * 2. Add the mapping to TemporalMetaFieldMap above\n * 3. The compiler will error in rowToNodeMeta() until you add the field there\n */\nexport type NodeMeta = MapRowToMeta<NodeRow, TemporalMetaFieldMap> &\n Readonly<{ version: NodeRow[\"version\"] }>;\n\n/**\n * A node instance in the graph.\n *\n * Properties from the schema are spread at the top level for ergonomic access:\n * - `node.name` instead of `node.props.name`\n * - System metadata is under `node.meta.*`\n */\nexport type Node<N extends NodeType = NodeType> = Readonly<{\n kind: N[\"kind\"];\n id: NodeId<N>;\n meta: NodeMeta;\n}> &\n Readonly<z.infer<N[\"schema\"]>>;\n\n/**\n * Input for creating a node.\n */\nexport type CreateNodeInput<N extends NodeType = NodeType> = Readonly<{\n kind: N[\"kind\"];\n id?: string; // Optional - will generate ULID if not provided\n props: z.infer<N[\"schema\"]>;\n validFrom?: string;\n validTo?: string;\n}>;\n\n/**\n * Input for updating a node.\n */\nexport type UpdateNodeInput<N extends NodeType = NodeType> = Readonly<{\n kind: N[\"kind\"];\n id: NodeId<N>;\n props: Partial<z.infer<N[\"schema\"]>>;\n validTo?: string;\n}>;\n\n// ============================================================\n// Edge Instance Types\n// ============================================================\n\n/**\n * Metadata for an edge instance.\n * Derived from EdgeRow via TemporalMetaFieldMap (edges have no version).\n */\nexport type EdgeMeta = MapRowToMeta<EdgeRow, TemporalMetaFieldMap>;\n\n/**\n * An edge instance in the graph.\n *\n * Properties from the schema are spread at the top level for ergonomic access:\n * - `edge.role` instead of `edge.props.role`\n * - System metadata is under `edge.meta.*`\n */\nexport type Edge<\n E extends AnyEdgeType = EdgeType,\n From extends NodeType = NodeType,\n To extends NodeType = NodeType,\n> = Readonly<{\n id: EdgeId<E>;\n kind: E[\"kind\"];\n fromKind: From[\"kind\"];\n fromId: NodeId<From>;\n toKind: To[\"kind\"];\n toId: NodeId<To>;\n meta: EdgeMeta;\n}> &\n Readonly<z.infer<E[\"schema\"]>>;\n\n/**\n * Input for creating an edge.\n */\nexport type CreateEdgeInput<E extends AnyEdgeType = EdgeType> = Readonly<{\n kind: E[\"kind\"];\n id?: string; // Optional - will generate ULID if not provided\n fromKind: string;\n fromId: string;\n toKind: string;\n toId: string;\n props: z.infer<E[\"schema\"]>;\n validFrom?: string;\n validTo?: string;\n}>;\n\n/**\n * Input for updating an edge.\n */\nexport type UpdateEdgeInput<E extends AnyEdgeType = EdgeType> = Readonly<{\n id: EdgeId<E>;\n props: Partial<z.infer<E[\"schema\"]>>;\n validTo?: string;\n}>;\n\n// ============================================================\n// Query Options\n// ============================================================\n\n/**\n * Options for node and edge queries.\n */\nexport type NoRecordedCoordinate = Readonly<{\n /**\n * Recorded/system-time coordinates are internal-only and supplied by\n * RecordedStoreView. A public options object carrying this key is a type\n * error even when the object is pre-bound before the call site.\n */\n recordedAsOf?: never;\n}>;\n\nexport type QueryOptions = NoRecordedCoordinate &\n Readonly<{\n /** Temporal mode for the query */\n temporalMode?: TemporalMode;\n /** Specific timestamp for asOf queries */\n asOf?: string;\n }>;\n\n// ============================================================\n// Observability Hooks\n// ============================================================\n\n/**\n * Context passed to observability hooks.\n */\nexport type HookContext = Readonly<{\n /** Unique ID for this operation */\n operationId: string;\n /** Graph ID */\n graphId: string;\n /** Timestamp when operation started */\n startedAt: Date;\n}>;\n\n/**\n * Context for one SQL statement a query builder submits to the backend.\n *\n * A single logical query can emit more than one context, for example when a\n * selective projection falls back to a full-row fetch. Backend-internal setup\n * statements are not exposed as separate query-hook events.\n */\nexport type QueryHookContext = HookContext &\n Readonly<{\n /** The SQL statement being executed */\n sql: string;\n /** Query parameters */\n params: readonly unknown[];\n }>;\n\n/**\n * Operation hook context for CRUD operations.\n */\nexport type OperationHookContext = HookContext &\n Readonly<{\n /** Operation type */\n operation: \"create\" | \"update\" | \"delete\";\n /** Entity type */\n entity: KindEntity;\n /** Kind of node or edge */\n kind: string;\n /** Entity ID */\n id: string;\n }>;\n\n/**\n * Context for one set-based collection mutation. Node `updateWhere` is the only\n * mutation that reports one: the `operation` union is the exhaustive list of\n * what `onBulkOperationStart` / `onBulkOperationEnd` observe, so a batch method\n * absent from it (every `bulk*`, including `bulkDelete`) emits no bulk event.\n */\nexport type BulkOperationHookContext = HookContext &\n Readonly<{\n operation: \"updateWhere\";\n entity: \"node\";\n kind: string;\n }>;\n\n/**\n * Observability hooks for monitoring store operations.\n *\n * Note: Batch operations (`bulkCreate`, `bulkInsert`, `bulkUpsertById`,\n * `bulkDelete`) skip per-item operation hooks for throughput, and the bulk\n * hooks below do not stand in for them — those fire only for node\n * `updateWhere`, so a batch method emits no hook events at all, neither\n * per-item nor bulk. Query hooks still fire normally.\n *\n * @example\n * ```typescript\n * const hooks: StoreHooks = {\n * onQueryStart: (ctx) => {\n * console.log(`[${ctx.operationId}] Query: ${ctx.sql}`);\n * },\n * onQueryEnd: (ctx, result) => {\n * const duration = Date.now() - ctx.startedAt.getTime();\n * console.log(`[${ctx.operationId}] Completed in ${duration}ms`);\n * },\n * onError: (ctx, error) => {\n * console.error(`[${ctx.operationId}] Error:`, error);\n * },\n * };\n *\n * const store = createStore(graph, backend, { hooks });\n * ```\n */\nexport type StoreHooks = Readonly<{\n /** Called before each query-builder statement is submitted to the backend. */\n onQueryStart?: (ctx: QueryHookContext) => void;\n /** Called after each submitted query-builder statement succeeds. */\n onQueryEnd?: (\n ctx: QueryHookContext,\n result: Readonly<{ rowCount: number; durationMs: number }>,\n ) => void;\n /** Called before a CRUD operation starts */\n onOperationStart?: (ctx: OperationHookContext) => void;\n /** Called before a set-based collection mutation starts. */\n onBulkOperationStart?: (ctx: BulkOperationHookContext) => void;\n /**\n * Called after a CRUD operation completes AND is durably committed. For a\n * top-level operation that is when its own transaction commits; for an\n * operation inside `store.transaction`, emission is deferred until the\n * enclosing transaction commits — if that commit fails, the operation is\n * reported through `onError` instead. (Inside an adopted transaction —\n * `withTransaction` / `withRecordedTransaction` — the commit belongs to\n * the caller and cannot be observed, so this fires when the operation\n * completes within the still-open transaction.)\n */\n onOperationEnd?: (\n ctx: OperationHookContext,\n result: Readonly<{ durationMs: number }>,\n ) => void;\n /**\n * Called after a set-based mutation durably commits. Inside\n * `store.transaction`, emission is deferred until the enclosing commit.\n */\n onBulkOperationEnd?: (\n ctx: BulkOperationHookContext,\n result: Readonly<{ affectedCount: number; durationMs: number }>,\n ) => void;\n /**\n * Called when an operation fails — including an operation that completed\n * inside a `store.transaction` whose commit then failed and rolled it\n * back.\n */\n onError?: (ctx: HookContext, error: Error) => void;\n}>;\n\n// ============================================================\n// Store Configuration\n// ============================================================\n\n/**\n * Default row count at which an autocommit bulk write triggers an\n * automatic planner-statistics refresh. Below this, the refresh cost is\n * not worth paying per call and autovacuum/PRAGMA optimize cover it.\n */\nexport const AUTO_REFRESH_STATISTICS_ROW_THRESHOLD = 1000;\n\nexport type BaseStoreOptions = Readonly<{\n /** Observability hooks for monitoring */\n hooks?: StoreHooks;\n /**\n * Maintain a durable, graph-wide revision anchor for TypeGraph writes:\n * a random per-graph origin plus a monotonic revision clock. `branch()` uses\n * this anchor to validate that its base has not moved without\n * re-fingerprinting every live row, and cannot confuse a coincident clock in\n * a separately created store for its original base. `history: true` enables\n * the same tracking automatically through its recorded-time commit clock.\n *\n * This is intentionally opt-in for live stores: each successful graph write\n * advances the anchor inside its write transaction. On PostgreSQL, those\n * transactions take a graph-scoped advisory lock until commit; writes to the\n * same graph therefore serialize. Enable it for branchable graphs, but size\n * high-throughput multi-writer workloads for that trade-off.\n *\n * Writes performed directly through a backend — including raw graph-table\n * writes through `tx.sql` — bypass the anchor and are outside the\n * revision-tracking contract.\n */\n revisionTracking?: boolean;\n /**\n * Automatic planner-statistics refresh after large autocommit bulk\n * writes (bulkCreate and bulkInsert on nodes and edges). Stale statistics after a\n * bulk load are a whole class of planner cliffs: the planner keeps\n * pre-load row estimates until ANALYZE runs. When a single\n * autocommit bulk write reaches the threshold\n * ({@link AUTO_REFRESH_STATISTICS_ROW_THRESHOLD} rows by default),\n * the store runs `refreshStatistics()` after the write commits.\n * Pass a number to change the threshold, or `false` to disable.\n * Bulk writes inside a caller-provided transaction never\n * auto-refresh (statistics cannot see uncommitted rows); refresh\n * manually after commit. `importGraph` handles its own refresh.\n */\n autoRefreshStatistics?: false | number;\n /**\n * Skip the write for an `upsertById` (or `bulkUpsertById` item) whose\n * validated props are value-identical to the existing live row. Default\n * off.\n *\n * Enable this for at-least-once / replay materializers. An event log that\n * re-delivers a byte-identical change would otherwise rewrite the row anyway:\n * today an `upsertById` on an existing id calls `updateNode`\n * unconditionally, allocating a fresh recorded instant and a new history row\n * per re-delivery.\n *\n * The win is scoped to re-delivery of the **current** value. A full\n * replay-from-zero over the current state still writes wherever the stream\n * superseded a value in place: re-applying an older value over the live row\n * is a genuine change (and restoring the current value afterwards is\n * another), so only streams whose rows never supersede each other replay\n * without churn. A rebuild that should avoid that re-walk belongs in a fresh\n * store — replay into it and publish it, rather than re-applying the log\n * over current state.\n *\n * When enabled, an upsert that would not change the stored value performs\n * **no write at all**: no `updateNode`, no recorded-time capture, no history\n * row, no revision-anchor advance, and no `update` operation hooks (nothing\n * happened, so nothing is reported). It resolves with the **existing** node,\n * preserving its original `validFrom` / `updatedAt` / `version`.\n *\n * Receipt shape is unchanged and needs no new signal: a coalesced upsert\n * still counts as one write intent (`writes.total` includes it), but\n * captures nothing (`receipt.recorded` stays `undefined` when it is the only\n * write) — the same shape a no-op delete already produces, so a consumer\n * that carries the prior anchor forward on `recorded === undefined` handles\n * it unchanged.\n *\n * A write is coalesced only when **all** of the following hold; otherwise the\n * normal write happens:\n * 1. A value to compare against is known for the id: an existing row, or —\n * for a repeated id in one bulk batch — the value an earlier item in that\n * batch already queued (a create or an update).\n * 2. That row is not soft-deleted (a deleted row resurrects — a real\n * change — and is never coalesced).\n * 3. The caller passed no explicit `validFrom` / `validTo` (an explicit\n * temporal override is a deliberate request and is never coalesced;\n * applied per item in the bulk path).\n * 4. The new props, merged over the stored props and run through the\n * kind's Zod schema (defaults applied, values normalized), are deeply\n * value-identical to the stored props (key order aside).\n *\n * Default-off because some consumers *want* an audit row per re-delivery as\n * proof the event was reprocessed; coalescing removes that signal.\n */\n coalesceUnchangedUpserts?: boolean;\n /** SQL schema configuration from createSqlSchema(...) for custom table names */\n schema?: SqlSchema;\n /** Query default behaviors. */\n queryDefaults?: Readonly<{\n /** Default traversal ontology expansion mode (default: \"inverse\"). */\n traversalExpansion?: TraversalExpansion;\n }>;\n}>;\n\n/**\n * Store options without built-in recorded-time capture. A recorded read relation\n * can still be bound explicitly for hosts that populate history externally.\n */\nexport type LiveStoreOptions = BaseStoreOptions &\n Readonly<{\n history?: false | undefined;\n recordedRead?: ExternalRecordedReadSource | undefined;\n }>;\n\n/** Live-store options that do not bind a recorded-read relation. */\nexport type UnboundLiveStoreOptions = LiveStoreOptions &\n Readonly<{ recordedRead?: undefined }>;\n\n/** Live-store options with an explicitly bound recorded-read relation. */\nexport type RecordedReadStoreOptions = LiveStoreOptions &\n Readonly<{\n recordedRead: NonNullable<LiveStoreOptions[\"recordedRead\"]>;\n }>;\n\n/**\n * Store options with TypeGraph-managed recorded-time capture. `history: true`\n * captures TypeGraph writes and binds TypeGraph's built-in recorded relation\n * internally. Externally populated recorded read sources are read-only bindings\n * and are intentionally accepted only by {@link LiveStoreOptions}.\n */\nexport type HistoryStoreOptions = BaseStoreOptions &\n Readonly<{\n history: true;\n recordedRead?: never;\n }>;\n\n/**\n * Options for creating a store.\n */\nexport type StoreOptions = LiveStoreOptions | HistoryStoreOptions;\n\n/**\n * A mutable handle to the current `Store`, used by `store.evolve(...)`\n * so long-lived consumers can dereference through the ref and pick up\n * the new Store after each evolve call. When the ref is passed via\n * `evolve(extension, { ref })`, `current` is overwritten with the replacement\n * before a successful call resolves.\n *\n * **Request semantics.** Dereference once at request entry only when that\n * request will not change the schema. A schema-changing call such as\n * `evolve()` returns the Store for the resulting schema and updates\n * `ref.current`; a Store captured before that call remains pinned to the old\n * schema. Use the returned Store (or dereference `ref.current` again) for every\n * subsequent operation in the same request:\n *\n * ```ts\n * async function handleRequest(): Promise<void> {\n * const store = ref.current;\n * const evolved = await store.evolve(extension, { ref });\n * await evolved.materializeIndexes();\n * // ref.current === evolved\n * }\n * ```\n *\n * A `StoreRef` tracks only schema changes made by calls that receive that ref.\n * When another process or isolate can commit a schema version, compare\n * `getCommittedSchemaVersion()` with the cached version before reuse and call\n * `createVerifiedStore()` or `createVerifiedAdapterStore()` when it changes.\n *\n * Pure dereferenceable handle — no event/subscription machinery. If\n * consumers need eventing, they wrap the ref themselves.\n *\n * Generic over the held value (typically `Store<G>`) so the store\n * module can refer to it without importing the `Store` class into\n * `types.ts`. The type parameter is deliberately invariant: evolution writes\n * a replacement into `current`, so a ref for an adapter-only or history-only\n * Store must never be accepted by a Store that cannot preserve that surface.\n */\nexport interface StoreRef<in out T> {\n current: T;\n}\n\n// ============================================================\n// Transaction Receipt Types\n// ============================================================\n\n/**\n * Result plus write summary. Returned by `store.transactionWithReceipt(fn)`,\n * `store.withRecordedTransaction(externalTx, fn)` (the adopted-commit path), and\n * `tx.measure(fn)` (a scoped sub-receipt). See {@link TransactionReceipt}.\n */\nexport type TransactionOutcome<T> = Readonly<{\n result: T;\n receipt: TransactionReceipt;\n}>;\n\n/**\n * Transaction write summary.\n *\n * Receipt counts are completed write intents at the collection surface, not\n * rows affected:\n *\n * 1. Every successful completion of a write method on `tx.nodes.*` /\n * `tx.edges.*` counts. The authoritative method list is\n * {@link NodeWrites} / {@link EdgeWrites}.\n * 2. Bulk methods count by input length; an empty bulk call (`bulkCreate([])`)\n * counts 0.\n * 3. Single-row methods count 1 on resolve — including `delete` of an absent\n * id and `getOrCreate*` that found an existing row. Consumers that need\n * \"did anything actually change\" semantics apply their own per-operation\n * policy.\n * 4. A method that rejects counts 0 — even when the backend applied part of a\n * bulk input before failing. On SQLite a failed statement does not abort\n * the surrounding transaction, so a caller that catches the rejection and\n * commits can persist rows the receipt never counted. Do not read the\n * receipt as rows-affected in that scenario.\n * 5. A node `delete` under `cascade` / `disconnect` removes connected edges\n * through the backend, not the edge-collection surface; those removals do\n * not appear in `edges`.\n * 6. Rows-affected fidelity is intentionally out of scope for this first\n * version; a future extension could ask backends to return row counts.\n */\nexport type TransactionReceipt = Readonly<{\n writes: Readonly<{\n /** Completed node write intents by node kind. */\n nodes: Readonly<Record<string, number>>;\n /** Completed edge write intents by edge kind. */\n edges: Readonly<Record<string, number>>;\n /** Completed identity assertion and retraction write intents. */\n identity: IdentityWriteSummary;\n /** Sum of all node, edge, and identity write intents. */\n total: number;\n }>;\n /**\n * The recorded commit instant allocated for this store's graph by this\n * transaction. Undefined when history capture is off, the transaction is\n * read-only, or no captured writes were flushed. **Always undefined on a\n * scoped receipt from {@link ScopedMeasure}** (`tx.measure`) — the recorded\n * instant is a per-transaction flush concern allocated once when the whole\n * transaction's capture flushes, unknowable mid-transaction.\n */\n recorded?: RecordedInstant;\n}>;\n\n// ============================================================\n// Get-Or-Create Types\n// ============================================================\n\n/**\n * Behavior when a get-or-create operation matches an existing record.\n */\nexport type IfExistsMode = \"return\" | \"update\";\n\n/**\n * Action taken by a get-or-create operation.\n */\nexport type GetOrCreateAction = \"created\" | \"found\" | \"updated\" | \"resurrected\";\n\n/**\n * Result of a node getOrCreateByConstraint operation.\n */\nexport type NodeGetOrCreateByConstraintResult<N extends NodeType> = Readonly<{\n node: Node<N>;\n action: GetOrCreateAction;\n}>;\n\n/**\n * Options for node getOrCreateByConstraint operations.\n */\nexport type NodeGetOrCreateByConstraintOptions = Readonly<{\n /** Existing record behavior. Default: \"return\" */\n ifExists?: IfExistsMode;\n}>;\n\n/**\n * Options for node bulkFindByIndex operations.\n */\nexport type NodeBulkFindByIndexOptions = Readonly<{\n /**\n * Maximum number of candidate nodes returned per input item. When omitted,\n * each input's candidate set is unbounded. Must be a positive integer.\n *\n * Candidates are ordered deterministically by node id, so the cap is stable\n * across calls. Use this to bound fan-out on low-selectivity index keys.\n */\n limitPerInput?: number;\n}>;\n\n/**\n * Per-endpoint fan-out cap shared by the live and view forms of the edge\n * bulk endpoint reads.\n */\nexport type EdgeBulkFindOptions = Readonly<{\n /**\n * Maximum number of edges returned for each input endpoint. When omitted,\n * every input's edge set is unbounded. Must be a positive integer.\n *\n * The cap keeps each input's leading edges under the same ordering\n * `findFrom` / `findTo` return, so it bounds fan-out without reordering\n * anything.\n */\n limitPerInput?: number;\n}>;\n\n/**\n * Options for the edge bulk endpoint reads: the temporal coordinate every\n * edge read accepts, plus the per-endpoint fan-out cap.\n */\nexport type EdgeBulkFindEndpointOptions = QueryOptions & EdgeBulkFindOptions;\n\n/** A kind-grouped source list for a heterogeneous bulk edge read. */\nexport type BulkEdgeSourceGroup<G extends GraphDef> = {\n [K in NodeKinds<G>]: Readonly<{\n kind: K;\n ids: readonly NodeId<G[\"nodes\"][K][\"type\"]>[];\n }>;\n}[NodeKinds<G>];\n\n/** A node reference whose kind and branded id remain correlated. */\nexport type GraphNodeReference<G extends GraphDef> = {\n [K in NodeKinds<G>]: Readonly<{\n kind: K;\n id: NodeId<G[\"nodes\"][K][\"type\"]>;\n }>;\n}[NodeKinds<G>];\n\n/** Runtime edge union narrowed to the selected graph edge kinds. */\nexport type GraphEdgeForKinds<G extends GraphDef, K extends EdgeKinds<G>> = {\n [P in K]: Edge<\n G[\"edges\"][P][\"type\"],\n G[\"edges\"][P][\"from\"][number],\n G[\"edges\"][P][\"to\"][number]\n >;\n}[K];\n\n/** Input for {@link Store.bulkFindEdgesFrom}. */\nexport type BulkFindEdgesFromParams<\n G extends GraphDef,\n K extends EdgeKinds<G>,\n> = Readonly<{\n sources: readonly BulkEdgeSourceGroup<G>[];\n edgeKinds: readonly K[];\n}>;\n\n/** One source bucket returned by {@link Store.bulkFindEdgesFrom}. */\nexport type BulkFindEdgesFromResult<\n G extends GraphDef,\n K extends EdgeKinds<G>,\n> = Readonly<{\n source: GraphNodeReference<G>;\n edges: readonly GraphEdgeForKinds<G, K>[];\n}>;\n\n/**\n * Result of an edge getOrCreateByEndpoints operation.\n */\nexport type EdgeGetOrCreateByEndpointsResult<\n E extends AnyEdgeType,\n From extends NodeType = NodeType,\n To extends NodeType = NodeType,\n> = Readonly<{\n edge: Edge<E, From, To>;\n action: GetOrCreateAction;\n}>;\n\n/**\n * Options for edge findByEndpoints operations.\n */\nexport type EdgeFindByEndpointsOptions<E extends AnyEdgeType> = Readonly<{\n /**\n * Edge property fields to include in the match alongside the (from, to) endpoints.\n * When omitted, matches on endpoints only (returns the first edge at the read coordinate).\n */\n matchOn?: readonly (keyof z.input<E[\"schema\"]>)[];\n /** Property values to match against when matchOn is specified. */\n props?: Partial<z.input<E[\"schema\"]>>;\n}>;\n\n/**\n * Options for edge getOrCreateByEndpoints operations.\n */\nexport type EdgeGetOrCreateByEndpointsOptions<E extends AnyEdgeType> =\n Readonly<{\n /**\n * Edge property fields to include in the match key alongside the (from, to) endpoints.\n * Default: `[]` — match on endpoints only.\n */\n matchOn?: readonly (keyof z.input<E[\"schema\"]>)[];\n /** Existing record behavior. Default: \"return\" */\n ifExists?: IfExistsMode;\n /**\n * Valid-time start for a created or RESURRECTED edge — on a resurrection it\n * asserts the complete window, so an omitted `validTo` reopens the revived\n * row.\n *\n * A live edge's stored lower bound is history, so an in-place update\n * (`ifExists: \"update\"`) cannot store this: one naming a different instant is\n * REFUSED with `IMMUTABLE_VALIDITY_LOWER_BOUND_CODE`, and one restating the\n * bound the edge holds is accepted. Ignored when an existing edge is returned\n * (`ifExists: \"return\"`), which writes nothing at all — there the window\n * describes the edge to create if none is found.\n */\n validFrom?: string;\n /**\n * Valid-time end for a created, updated, or resurrected edge. Ignored when\n * the operation returns an existing edge without writing. May not precede\n * the row's effective start; see `INVERTED_VALIDITY_WINDOW_CODE`.\n */\n validTo?: string;\n }>;\n\n// ============================================================\n// Collection Interfaces\n// ============================================================\n\n/**\n * A collection of nodes of a specific type.\n *\n * Provides ergonomic CRUD operations for a single node type.\n */\nexport type NodeCollection<\n N extends NodeType,\n CN extends string = string,\n> = Readonly<{\n /**\n * Create a new node.\n *\n * `validFrom` defaults to the operation's creation timestamp when omitted.\n */\n create: (\n props: z.input<N[\"schema\"]>,\n options?: Readonly<{ id?: string; validFrom?: string; validTo?: string }>,\n ) => Promise<Node<N>>;\n\n /** Get a node by ID */\n getById: (\n id: NodeId<N>,\n options?: QueryOptions,\n ) => Promise<Node<N> | undefined>;\n\n /** Get multiple nodes by ID, preserving input order (undefined for missing) */\n getByIds: (\n ids: readonly NodeId<N>[],\n options?: QueryOptions,\n ) => Promise<readonly (Node<N> | undefined)[]>;\n\n /** Update a node */\n update: (\n id: NodeId<N>,\n props: Partial<z.input<N[\"schema\"]>>,\n options?: Readonly<{ validTo?: string }>,\n ) => Promise<Node<N>>;\n\n /**\n * Updates every current node selected by the supplied predicates in one\n * set-based write. Relationship clauses are independent EXISTS predicates\n * and are ANDed with each other and with `where`.\n */\n updateWhere: (\n params: Readonly<{\n patch: Partial<z.input<N[\"schema\"]>>;\n where?: (\n accessor: string extends N[\"kind\"] ? DynamicNodeAccessor\n : NodeAccessor<N>,\n ) => Predicate;\n exists?: readonly Readonly<{\n edgeKind: string;\n direction: \"out\" | \"in\";\n relatedKind: string;\n whereEdge?: (accessor: DynamicEdgeAccessor) => Predicate;\n whereRelated?: (accessor: DynamicNodeAccessor) => Predicate;\n }>[];\n all?: true;\n }>,\n ) => Promise<Readonly<{ affectedCount: number }>>;\n\n /** Delete a node (soft delete - sets deletedAt timestamp) */\n delete: (id: NodeId<N>) => Promise<void>;\n\n /**\n * Permanently delete a node from the database.\n *\n * Unlike `delete()` which performs a soft delete, this permanently\n * removes the node and its associated data (uniqueness entries, embeddings).\n *\n * **Warning:** This operation is irreversible and should be used carefully.\n * Consider using soft delete (`delete()`) for most use cases.\n *\n * @throws Error if edges are still connected to this node (delete edges first)\n */\n hardDelete: (id: NodeId<N>) => Promise<void>;\n\n /**\n * Find nodes matching criteria.\n *\n * Supports predicate filtering via the `where` option for SQL-level filtering.\n * For simple queries. Use store.query() for complex traversals.\n */\n find: (\n filter?: Readonly<{\n where?: (accessor: NodeAccessor<N>) => Predicate;\n limit?: number;\n offset?: number;\n }>,\n temporal?: QueryOptions,\n ) => Promise<Node<N>[]>;\n\n /** Count nodes matching criteria */\n count: (temporal?: QueryOptions) => Promise<number>;\n\n /**\n * Create a node from untyped data, relying on runtime Zod validation.\n *\n * Use this for dynamic dispatch (changesets, migrations, imports) where\n * the data shape is determined at runtime, not compile time.\n * The return type is fully typed — only the input gate is relaxed.\n *\n * `validFrom` defaults to the operation's creation timestamp when omitted.\n */\n createFromRecord: (\n data: Record<string, unknown>,\n options?: Readonly<{ id?: string; validFrom?: string; validTo?: string }>,\n ) => Promise<Node<N>>;\n\n /**\n * Create or update a node.\n *\n * If a node with the given ID exists, updates it with the provided props.\n * Otherwise, creates a new node with that ID.\n *\n * `validFrom` applies when the upsert CREATES the row and when it RESURRECTS\n * a tombstoned one — both write a fresh validity window — defaulting to the\n * operation's timestamp when omitted. An update to a LIVE row stores no lower\n * bound, because that row's is already history, so one naming a different\n * instant is REFUSED (`ValidationError` carrying\n * `IMMUTABLE_VALIDITY_LOWER_BOUND_CODE`) rather than ignored. Restating the\n * bound the row already holds is accepted and changes nothing.\n */\n upsertById: (\n id: string,\n props: z.input<N[\"schema\"]>,\n options?: Readonly<{ validFrom?: string; validTo?: string }>,\n ) => Promise<Node<N>>;\n\n /**\n * Upsert a node from untyped data, relying on runtime Zod validation.\n *\n * Use this for dynamic dispatch (changesets, migrations, imports) where\n * the data shape is determined at runtime, not compile time.\n * The return type is fully typed — only the input gate is relaxed.\n *\n * `validFrom` applies when the upsert CREATES the row and when it RESURRECTS\n * a tombstoned one — both write a fresh validity window — defaulting to the\n * operation's timestamp when omitted. An update to a LIVE row stores no lower\n * bound, because that row's is already history, so one naming a different\n * instant is REFUSED (`ValidationError` carrying\n * `IMMUTABLE_VALIDITY_LOWER_BOUND_CODE`) rather than ignored. Restating the\n * bound the row already holds is accepted and changes nothing.\n */\n upsertByIdFromRecord: (\n id: string,\n data: Record<string, unknown>,\n options?: Readonly<{ validFrom?: string; validTo?: string }>,\n ) => Promise<Node<N>>;\n\n /**\n * Create multiple nodes in a batch.\n *\n * More efficient than calling create() multiple times.\n * Use `bulkInsert` for the dedicated fast path that skips returning results.\n *\n * `validFrom` defaults to the operation's creation timestamp when omitted.\n */\n bulkCreate: (\n items: readonly Readonly<{\n props: z.input<N[\"schema\"]>;\n id?: string;\n validFrom?: string;\n validTo?: string;\n }>[],\n ) => Promise<Node<N>[]>;\n\n /**\n * Create or update multiple nodes in a batch.\n *\n * For each item, if a node with the given ID exists, updates it.\n * Otherwise, creates a new node with that ID.\n *\n * Items are applied in order, so a **repeated id** within one batch is\n * last-write-wins: the first item creates or updates the row, and every later\n * copy is an update over the value the earlier item wrote — the same final row\n * the equivalent sequence of `upsertById` calls produces. This holds whether\n * or not the row existed before the batch.\n *\n * `validFrom` applies when the upsert CREATES the row and when it RESURRECTS\n * a tombstoned one — both write a fresh validity window — defaulting to the\n * operation's timestamp when omitted. An update to a LIVE row stores no lower\n * bound, because that row's is already history, so one naming a different\n * instant is REFUSED (`ValidationError` carrying\n * `IMMUTABLE_VALIDITY_LOWER_BOUND_CODE`) rather than ignored. Restating the\n * bound the row already holds is accepted and changes nothing.\n *\n * **Limitation — a batch cannot hand a unique value from one row to\n * another.** Item order settles which value each id ends up with, but the\n * writes themselves are grouped: every create runs before every update. So a\n * batch where one item RELEASES a `unique` constraint value and a later item\n * CLAIMS it — `[{ id: \"a\", props: { email: \"moved@x\" } }, { id: \"b\", props:\n * { email: \"shared@x\" } }]` where `a` currently holds `\"shared@x\"` and `b` is\n * new — checks `b`'s create while `a` still reserves the value, and the whole\n * batch fails with a `UniquenessError`. The equivalent sequence of\n * single `upsertById` calls succeeds. A batch states the set of rows it wants,\n * not a script to reach them by; the failure is loud rather than silent, and\n * the workaround is to split the handoff across two batches (release, then\n * claim) or to apply those items as sequential `upsertById` calls.\n */\n bulkUpsertById: (\n items: readonly Readonly<{\n id: string;\n props: z.input<N[\"schema\"]>;\n validFrom?: string;\n validTo?: string;\n }>[],\n ) => Promise<Node<N>[]>;\n\n /**\n * Insert multiple nodes without returning results.\n *\n * This is the dedicated fast path for bulk inserts. Unlike `bulkCreate`\n * with `returnResults: false`, the intent is unambiguous: no results\n * are returned and the operation is wrapped in a transaction.\n *\n * `validFrom` defaults to the operation's creation timestamp when omitted.\n */\n bulkInsert: (\n items: readonly Readonly<{\n props: z.input<N[\"schema\"]>;\n id?: string;\n validFrom?: string;\n validTo?: string;\n }>[],\n ) => Promise<void>;\n\n /**\n * Delete multiple nodes by ID.\n *\n * Atomic when the backend supports transactions. Silently ignores IDs\n * that don't exist.\n */\n bulkDelete: (ids: readonly NodeId<N>[]) => Promise<void>;\n\n /**\n * Find a node by uniqueness constraint.\n *\n * Looks up a live node by the named constraint key computed from `props`.\n * Returns the node if found, or undefined. Soft-deleted nodes are excluded.\n *\n * @param constraintName - Name of the uniqueness constraint to match on\n * @param props - Properties to compute the constraint key from\n */\n findByConstraint: (\n constraintName: CN,\n props: z.input<N[\"schema\"]>,\n ) => Promise<Node<N> | undefined>;\n\n /**\n * Batch version of findByConstraint.\n *\n * Results are returned in the same order as the input items.\n * Returns undefined for entries that don't match.\n */\n bulkFindByConstraint: (\n constraintName: CN,\n items: readonly Readonly<{\n props: z.input<N[\"schema\"]>;\n }>[],\n ) => Promise<(Node<N> | undefined)[]>;\n\n /**\n * Batched candidate retrieval against a declared node index.\n *\n * For each input item, TypeGraph computes the index lookup key from\n * `index.fields` (JSON-pointer extraction, partial-`where` applied to\n * stored rows, null-safe matching) and returns the live, non-soft-deleted\n * nodes that share that key. Unlike {@link bulkFindByConstraint}, the index\n * may be non-unique, so each input yields a (possibly empty) array.\n *\n * Results preserve input order; each inner array is ordered by node id.\n * Empty input returns `[]`. An unknown index name throws\n * `NodeIndexNotFoundError`; a type-incompatible indexed field throws\n * `ValidationError`. This is candidate retrieval, not a uniqueness or\n * identity guarantee.\n *\n * @param indexName - Name of the declared node index to match on\n * @param items - Records whose `props` supply the indexed-field values\n * @param options - Optional `limitPerInput` to bound per-input fan-out\n */\n bulkFindByIndex: (\n indexName: string,\n items: readonly Readonly<{\n props: Partial<z.input<N[\"schema\"]>>;\n }>[],\n options?: NodeBulkFindByIndexOptions,\n ) => Promise<readonly Node<N>[][]>;\n\n /**\n * Get an existing node by uniqueness constraint, or create a new one.\n *\n * Looks up a node by the named constraint key computed from `props`.\n * If found, returns it (optionally updating with `ifExists: \"update\"`).\n * If not found, creates a new node. Soft-deleted matches are always resurrected.\n *\n * @param constraintName - Name of the uniqueness constraint to match on\n * @param props - Full properties for create, or merge source for update\n * @param options - Existing record behavior (default: \"return\")\n */\n getOrCreateByConstraint: (\n constraintName: CN,\n props: z.input<N[\"schema\"]>,\n options?: NodeGetOrCreateByConstraintOptions,\n ) => Promise<NodeGetOrCreateByConstraintResult<N>>;\n\n /**\n * Batch version of getOrCreateByConstraint.\n *\n * Results are returned in the same order as the input items.\n * Atomic when the backend supports transactions.\n */\n bulkGetOrCreateByConstraint: (\n constraintName: CN,\n items: readonly Readonly<{\n props: z.input<N[\"schema\"]>;\n }>[],\n options?: NodeGetOrCreateByConstraintOptions,\n ) => Promise<NodeGetOrCreateByConstraintResult<N>[]>;\n}>;\n\n/**\n * Reference to a node of a specific kind.\n *\n * Accepts either:\n * - A Node instance of the correct kind\n * - An explicit { kind, id } object with the correct kind name\n *\n * This provides compile-time checking that edge endpoints match the\n * allowed node kinds defined in the edge registration.\n */\nexport type NodeRef<N extends NodeType = NodeType> =\n Node<N> | Readonly<{ kind: N[\"kind\"]; id: string }>;\n\n/**\n * Options for creating an edge.\n */\ntype EdgeCreateOptions = Readonly<{\n id?: string;\n validFrom?: string;\n validTo?: string;\n}>;\n\n/**\n * Arguments for edge creation, with props optional when schema allows empty object.\n *\n * Uses `{}` to check if an empty object literal satisfies the schema input type.\n */\n/* eslint-disable @typescript-eslint/no-empty-object-type -- {} is intentional: checking if empty object satisfies schema */\ntype EdgeCreateArguments<E extends AnyEdgeType> =\n {} extends z.input<E[\"schema\"]> ?\n [props?: z.input<E[\"schema\"]>, options?: EdgeCreateOptions]\n : [props: z.input<E[\"schema\"]>, options?: EdgeCreateOptions];\n/* eslint-enable @typescript-eslint/no-empty-object-type */\n\n/**\n * A collection of edges of a specific type.\n *\n * Provides ergonomic CRUD operations for a single edge type.\n * The From and To type parameters enforce that edge endpoints\n * match the allowed node types at compile time.\n *\n * @example\n * ```typescript\n * // Create an edge - pass Node objects directly\n * const edge = await store.edges.worksAt.create(alice, acme, { role: \"Engineer\" });\n *\n * // TypeScript error: Company is not a valid 'from' type for worksAt\n * // store.edges.worksAt.create(acme, alice, { role: \"Engineer\" });\n *\n * // For edges with empty schemas, props is optional\n * await store.edges.wrote.create(author, book);\n *\n * // Find edges from a node\n * const edges = await store.edges.worksAt.findFrom(alice);\n * ```\n */\nexport type EdgeCollection<\n E extends AnyEdgeType,\n From extends NodeType = NodeType,\n To extends NodeType = NodeType,\n> = Readonly<{\n /**\n * Create a new edge.\n *\n * `validFrom` defaults to the operation's creation timestamp when omitted.\n *\n * @param from - Source node (must be one of the allowed 'from' types)\n * @param to - Target node (must be one of the allowed 'to' types)\n * @param args - Edge properties (optional if schema is empty) and creation options\n */\n create: (\n from: NodeRef<From>,\n to: NodeRef<To>,\n ...args: EdgeCreateArguments<E>\n ) => Promise<Edge<E, From, To>>;\n\n /** Get an edge by ID */\n getById: (\n id: EdgeId<E>,\n options?: QueryOptions,\n ) => Promise<Edge<E, From, To> | undefined>;\n\n /** Get multiple edges by ID, preserving input order (undefined for missing) */\n getByIds: (\n ids: readonly EdgeId<E>[],\n options?: QueryOptions,\n ) => Promise<readonly (Edge<E, From, To> | undefined)[]>;\n\n /** Update an edge's properties */\n update: (\n id: EdgeId<E>,\n props: Partial<z.input<E[\"schema\"]>>,\n options?: Readonly<{ validTo?: string }>,\n ) => Promise<Edge<E, From, To>>;\n\n /**\n * Find edges from a specific node.\n *\n * Honors the same temporal model as `getById` / `find`: with no\n * `options`, the graph's default `temporalMode` applies (excluding\n * soft-deleted edges and, in `current` / `asOf` modes, edges outside\n * their validity window). Pass `temporalMode` / `asOf` to read the\n * endpoint's edges at another temporal coordinate.\n */\n findFrom: (\n from: NodeRef<From>,\n options?: QueryOptions,\n ) => Promise<Edge<E, From, To>[]>;\n\n /**\n * Find edges to a specific node.\n *\n * Temporal semantics mirror {@link EdgeCollection.findFrom}.\n */\n findTo: (\n to: NodeRef<To>,\n options?: QueryOptions,\n ) => Promise<Edge<E, From, To>[]>;\n\n /**\n * Find the edges from a SET of source nodes in one read.\n *\n * `findFrom` with a widened endpoint predicate and nothing else: the same\n * temporal model, the same soft-delete filtering, and the same per-source\n * ordering — but `from_id IN (...)` instead of `from_id = ?`, so a page of\n * N sources costs one statement per distinct source kind and bind-budget\n * chunk rather than N singleton statements.\n *\n * Results are grouped per input: the outer array is parallel to `froms`\n * (index `i` holds the edges of `froms[i]`), and repeated inputs each get\n * their own copy of the same edge set. Empty input returns `[]`; a source\n * with no edges gets an empty array. Large inputs are split across\n * statements to respect the backend's bound-parameter budget, which is\n * invisible in the result.\n *\n * Requires a backend implementing `findEdgesByEndpointSet` — both bundled\n * Drizzle backends do. On one that does not, this **refuses** with a\n * `ConfigurationError` rather than looping `findFrom` per input: asking for\n * a bulk read is asking for set-oriented statements, and silently issuing N\n * singleton statements is the cost surprise the method exists to remove.\n *\n * @param froms - Source nodes to read the edges of\n * @param options - Temporal coordinate plus optional `limitPerInput`\n * @throws {ConfigurationError} when the backend cannot read an endpoint set\n */\n bulkFindFrom: (\n froms: readonly NodeRef<From>[],\n options?: EdgeBulkFindEndpointOptions,\n ) => Promise<readonly Edge<E, From, To>[][]>;\n\n /**\n * Find the edges into a SET of target nodes in one read.\n *\n * Mirrors {@link EdgeCollection.bulkFindFrom} on the `to` endpoint.\n */\n bulkFindTo: (\n tos: readonly NodeRef<To>[],\n options?: EdgeBulkFindEndpointOptions,\n ) => Promise<readonly Edge<E, From, To>[][]>;\n\n /**\n * Deferred variant of `findFrom` for use with `store.batch()`.\n *\n * Returns a `BatchableQuery` instead of executing immediately. Accepts\n * the same temporal `options` as {@link EdgeCollection.findFrom}.\n *\n * Batching these still issues one statement per call — it does not merge\n * the reads, and whether they share a connection is up to the adapter. It\n * is not a snapshot: PostgreSQL's default read-committed isolation lets a\n * later read observe a commit the earlier ones did not. To read edges for\n * many sources in one statement, traverse from them in a single query.\n */\n batchFindFrom: (\n from: NodeRef<From>,\n options?: QueryOptions,\n ) => BatchableQuery<Edge<E, From, To>>;\n\n /**\n * Deferred variant of `findTo` for use with `store.batch()`.\n *\n * Returns a `BatchableQuery` instead of executing immediately. Accepts\n * the same temporal `options` as {@link EdgeCollection.findTo}. Costs one\n * statement per call, like {@link EdgeCollection.batchFindFrom}.\n */\n batchFindTo: (\n to: NodeRef<To>,\n options?: QueryOptions,\n ) => BatchableQuery<Edge<E, From, To>>;\n\n /**\n * Deferred variant of `findByEndpoints` for use with `store.batch()`.\n *\n * Returns a `BatchableQuery` that yields a 0-or-1 element array\n * (matching `findByEndpoints`' at-most-one semantics). Costs one statement\n * per call, like {@link EdgeCollection.batchFindFrom}.\n */\n batchFindByEndpoints: (\n from: NodeRef<From>,\n to: NodeRef<To>,\n options?: EdgeFindByEndpointsOptions<E>,\n temporal?: QueryOptions,\n ) => BatchableQuery<Edge<E, From, To>>;\n\n /** Delete an edge (soft delete - sets deletedAt timestamp) */\n delete: (id: EdgeId<E>) => Promise<void>;\n\n /**\n * Permanently delete an edge from the database.\n *\n * Unlike `delete()` which performs a soft delete, this permanently\n * removes the edge record.\n *\n * **Warning:** This operation is irreversible and should be used carefully.\n * Consider using soft delete (`delete()`) for most use cases.\n */\n hardDelete: (id: EdgeId<E>) => Promise<void>;\n\n /** Find edges matching endpoint and pagination criteria */\n find: (\n filter?: Readonly<{\n from?: NodeRef<From>;\n to?: NodeRef<To>;\n limit?: number;\n offset?: number;\n }>,\n temporal?: QueryOptions,\n ) => Promise<Edge<E, From, To>[]>;\n\n /** Count edges matching criteria */\n count: (\n filter?: Readonly<{\n from?: NodeRef<From>;\n to?: NodeRef<To>;\n }>,\n temporal?: QueryOptions,\n ) => Promise<number>;\n\n /**\n * Create multiple edges in a batch.\n *\n * More efficient than calling create() multiple times.\n * Use `bulkInsert` for the dedicated fast path that skips returning results.\n *\n * `validFrom` defaults to the operation's creation timestamp when omitted.\n */\n bulkCreate: (\n items: readonly Readonly<{\n from: NodeRef<From>;\n to: NodeRef<To>;\n props?: z.input<E[\"schema\"]>;\n id?: string;\n validFrom?: string;\n validTo?: string;\n }>[],\n ) => Promise<Edge<E, From, To>[]>;\n\n /**\n * Create or update multiple edges in a batch.\n *\n * For each item, if an edge with the given ID exists, updates it.\n * Otherwise, creates a new edge with that ID.\n *\n * Items are applied in order, so a **repeated id** within one batch is\n * last-write-wins: the first item creates or updates the edge, and every later\n * copy is an update over the value the earlier item wrote. This holds whether\n * or not the edge existed before the batch. An update never repoints an edge,\n * so every item's `from` / `to` must exactly restate the endpoints already\n * owned by that id (including an earlier item in the same batch). A mismatch\n * is refused with `ValidationError` carrying\n * `EDGE_IDENTITY_MISMATCH_CODE`; it is never silently ignored.\n *\n * `validFrom` applies when the upsert CREATES the row and when it RESURRECTS\n * a tombstoned one — both write a fresh validity window — defaulting to the\n * operation's timestamp when omitted. An update to a LIVE row stores no lower\n * bound, because that row's is already history, so one naming a different\n * instant is REFUSED (`ValidationError` carrying\n * `IMMUTABLE_VALIDITY_LOWER_BOUND_CODE`) rather than ignored. Restating the\n * bound the row already holds is accepted and changes nothing.\n *\n * **Limitation — a batch cannot hand a constrained slot from one edge to\n * another.** Item order settles the final props, but the writes are grouped:\n * every create runs before every update. So a batch where one item frees the\n * slot a `cardinality` constraint allows and a later item claims it — ending\n * the lone `oneActive` edge from a source while creating its replacement —\n * checks the create while the old edge is still active, and the whole batch\n * fails with a `CardinalityError`. Applying the update first, as\n * separate `update` / `create` calls, succeeds. A batch states the set of\n * edges it wants, not a script to reach them by; the failure is loud rather\n * than silent, and the workaround is to split the handoff across two batches\n * (free the slot, then claim it) or to apply those items individually.\n */\n bulkUpsertById: (\n items: readonly Readonly<{\n id: EdgeId<E>;\n from: NodeRef<From>;\n to: NodeRef<To>;\n props?: z.input<E[\"schema\"]>;\n validFrom?: string;\n validTo?: string;\n }>[],\n ) => Promise<Edge<E, From, To>[]>;\n\n /**\n * Insert multiple edges without returning results.\n *\n * This is the dedicated fast path for bulk inserts. Unlike `bulkCreate`\n * with `returnResults: false`, the intent is unambiguous: no results\n * are returned and the operation is wrapped in a transaction.\n *\n * `validFrom` defaults to the operation's creation timestamp when omitted.\n */\n bulkInsert: (\n items: readonly Readonly<{\n from: NodeRef<From>;\n to: NodeRef<To>;\n props?: z.input<E[\"schema\"]>;\n id?: string;\n validFrom?: string;\n validTo?: string;\n }>[],\n ) => Promise<void>;\n\n /**\n * Delete multiple edges by ID.\n *\n * Atomic when the backend supports transactions. Silently ignores IDs\n * that don't exist.\n *\n * The batch runs as one transaction, checking each id's kind against the\n * authoritative row as it goes. An id owned by another edge kind is\n * refused with `ValidationError` carrying `EDGE_IDENTITY_MISMATCH_CODE`;\n * because the whole batch is one transaction, that refusal rolls back\n * every delete already applied for an earlier id in the same batch.\n */\n bulkDelete: (ids: readonly EdgeId<E>[]) => Promise<void>;\n\n /**\n * Find an edge by endpoints and optional property fields.\n *\n * Returns the first matching edge at the read coordinate, or undefined.\n * Honors the temporal model like `findFrom` / `findTo`: by default\n * (`current` mode) soft-deleted and out-of-window edges are excluded; under\n * `includeTombstones` a soft-deleted edge can be returned.\n *\n * @param from - Source node\n * @param to - Target node\n * @param options - Match criteria (matchOn fields and property values)\n * @param temporal - Temporal coordinate. With no `temporal`, the graph's\n * default `temporalMode` applies (so under the default `\"current\"` mode,\n * edges outside their validity window are excluded). Pass\n * `temporalMode` / `asOf` to read the edge as of another coordinate.\n */\n findByEndpoints: (\n from: NodeRef<From>,\n to: NodeRef<To>,\n options?: EdgeFindByEndpointsOptions<E>,\n temporal?: QueryOptions,\n ) => Promise<Edge<E, From, To> | undefined>;\n\n /**\n * Get an existing edge by endpoints and optional property fields, or create a new one.\n *\n * Matches edges of this kind between `(from, to)`. When `matchOn` specifies\n * property fields, only edges whose properties match on those fields are considered.\n * Soft-deleted matches are resurrected when cardinality allows.\n *\n * `validFrom` applies on the create and RESURRECT branches, defaulting to the\n * operation's creation timestamp when omitted. On the `ifExists: \"update\"`\n * branch a live edge's lower bound is history and cannot be stored, so a\n * `validFrom` naming a different instant is REFUSED (`ValidationError`\n * carrying `IMMUTABLE_VALIDITY_LOWER_BOUND_CODE`); restating the bound the\n * edge holds is accepted. A returned existing edge (`ifExists: \"return\"`)\n * writes nothing and judges nothing — the window options describe the row to\n * create if none is found. `validTo` applies on create, update, and\n * resurrection, but not when an existing edge is returned without a write.\n *\n * @param from - Source node\n * @param to - Target node\n * @param props - Full properties for create, or merge source for update\n * @param options - Match criteria and conflict resolution\n */\n getOrCreateByEndpoints: (\n from: NodeRef<From>,\n to: NodeRef<To>,\n props: z.input<E[\"schema\"]>,\n options?: EdgeGetOrCreateByEndpointsOptions<E>,\n ) => Promise<EdgeGetOrCreateByEndpointsResult<E, From, To>>;\n\n /**\n * Batch version of getOrCreateByEndpoints.\n *\n * Results are returned in the same order as the input items.\n * Atomic when the backend supports transactions.\n */\n bulkGetOrCreateByEndpoints: (\n items: readonly Readonly<{\n from: NodeRef<From>;\n to: NodeRef<To>;\n props: z.input<E[\"schema\"]>;\n validFrom?: string;\n validTo?: string;\n }>[],\n options?: Pick<\n EdgeGetOrCreateByEndpointsOptions<E>,\n \"matchOn\" | \"ifExists\"\n >,\n ) => Promise<EdgeGetOrCreateByEndpointsResult<E, From, To>[]>;\n}>;\n\n// ============================================================\n// Type Helpers\n// ============================================================\n\n/**\n * Extract uniqueness constraint names from a NodeRegistration.\n *\n * - Returns `never` when no uniqueness constraints are configured.\n * - Returns a literal union when names are inferred via `defineGraph` const params.\n * - Falls back to `string` when names are widened/dynamic.\n */\nexport type ConstraintNames<R extends NodeRegistration> =\n \"unique\" extends keyof R ?\n R[\"unique\"] extends readonly { readonly name: infer N }[] ?\n N & string\n : string\n : never;\n\n/**\n * Extract the union of 'from' node types from an EdgeRegistration.\n */\ntype EdgeFromTypes<R extends EdgeRegistration> =\n R[\"from\"] extends readonly (infer N)[] ? N : never;\n\n/**\n * Extract the union of 'to' node types from an EdgeRegistration.\n */\ntype EdgeToTypes<R extends EdgeRegistration> =\n R[\"to\"] extends readonly (infer N)[] ? N : never;\n\n/**\n * Create a type-safe EdgeCollection from an EdgeRegistration.\n * Extracts the edge type and from/to node types automatically.\n */\nexport type TypedEdgeCollection<R extends EdgeRegistration> = EdgeCollection<\n R[\"type\"],\n EdgeFromTypes<R> extends NodeType ? EdgeFromTypes<R> : NodeType,\n EdgeToTypes<R> extends NodeType ? EdgeToTypes<R> : NodeType\n>;\n\n// ============================================================\n// Transaction Types\n// ============================================================\n\n// ============================================================\n// Graph Collection Maps\n// ============================================================\n\n/** Mapped type of all node collections for a graph. */\nexport type GraphNodeCollections<G extends GraphDef> = {\n [K in keyof G[\"nodes\"] & string]-?: NodeCollection<\n G[\"nodes\"][K][\"type\"],\n ConstraintNames<G[\"nodes\"][K]>\n >;\n};\n\n/** Mapped type of all edge collections for a graph. */\nexport type GraphEdgeCollections<G extends GraphDef> = {\n [K in keyof G[\"edges\"] & string]-?: TypedEdgeCollection<G[\"edges\"][K]>;\n};\n\n// ============================================================\n// StoreView read-only collection surfaces\n// ============================================================\n\n/** Temporal-aware node reads — a {@link StoreView} pins these. */\nexport type NodeTemporalReads<\n N extends NodeType,\n CN extends string = string,\n> = Pick<NodeCollection<N, CN>, (typeof NODE_TEMPORAL_READ_NAMES)[number]>;\n\n/**\n * Current-state-only node reads (constraint / index lookups). No temporal\n * axis, so a {@link StoreView} delegates them on a `current` pin and refuses\n * them on a temporal pin.\n */\nexport type NodeCurrentReads<\n N extends NodeType,\n CN extends string = string,\n> = Pick<NodeCollection<N, CN>, (typeof CURRENT_ONLY_READ_NAMES)[number]>;\n\n/** Node writes — never available on a read-only {@link StoreView}. */\nexport type NodeWrites<N extends NodeType, CN extends string = string> = Pick<\n NodeCollection<N, CN>,\n (typeof NODE_WRITE_NAMES)[number]\n>;\n\n/** Temporal-aware edge reads — a {@link StoreView} pins these. */\nexport type EdgeTemporalReads<\n E extends AnyEdgeType,\n From extends NodeType = NodeType,\n To extends NodeType = NodeType,\n> = Pick<\n EdgeCollection<E, From, To>,\n (typeof EDGE_TEMPORAL_READ_NAMES)[number]\n>;\n\n/**\n * Deferred edge reads for `store.batch()` — absent from a {@link StoreView},\n * which has no batch context.\n */\nexport type EdgeBatchReads<\n E extends AnyEdgeType,\n From extends NodeType = NodeType,\n To extends NodeType = NodeType,\n> = Pick<EdgeCollection<E, From, To>, (typeof EDGE_BATCH_READ_NAMES)[number]>;\n\n/** Edge writes — never available on a read-only {@link StoreView}. */\nexport type EdgeWrites<\n E extends AnyEdgeType,\n From extends NodeType = NodeType,\n To extends NodeType = NodeType,\n> = Pick<EdgeCollection<E, From, To>, (typeof EDGE_WRITE_NAMES)[number]>;\n\n/**\n * The read-only node surface a {@link StoreView} exposes for one node kind.\n * The temporal reads drop the per-call temporal argument — the pin owns the\n * axis; the current reads ({@link NodeCurrentReads}) are exposed as-is\n * (delegated on a `current` view, refused on a temporal pin). Writes live on\n * the live `Store`. The conformance test asserts the temporal part equals the\n * pinned form of {@link NodeTemporalReads}.\n */\nexport type StoreViewNodeCollection<\n N extends NodeType,\n CN extends string = string,\n> = Readonly<{\n /** Get a node by ID at the view's pinned coordinate. */\n getById: (id: NodeId<N>) => Promise<Node<N> | undefined>;\n\n /** Get multiple nodes by ID, preserving input order (undefined for missing). */\n getByIds: (\n ids: readonly NodeId<N>[],\n ) => Promise<readonly (Node<N> | undefined)[]>;\n\n /** Find nodes matching criteria at the view's pinned coordinate. */\n find: (\n filter?: Readonly<{\n where?: (accessor: NodeAccessor<N>) => Predicate;\n limit?: number;\n offset?: number;\n }>,\n ) => Promise<Node<N>[]>;\n\n /** Count nodes at the view's pinned coordinate. */\n count: () => Promise<number>;\n}> &\n NodeCurrentReads<N, CN>;\n\n/**\n * The read-only edge surface a {@link StoreView} exposes for one edge\n * kind, mirroring {@link StoreViewNodeCollection}. Every edge read —\n * including `findByEndpoints` — honors the pin via the same temporal model,\n * so (unlike nodes) there are no current-state-only edge reads.\n */\nexport type StoreViewEdgeCollection<\n E extends AnyEdgeType,\n From extends NodeType = NodeType,\n To extends NodeType = NodeType,\n> = Readonly<{\n /** Get an edge by ID at the view's pinned coordinate. */\n getById: (id: EdgeId<E>) => Promise<Edge<E, From, To> | undefined>;\n\n /** Get multiple edges by ID, preserving input order (undefined for missing). */\n getByIds: (\n ids: readonly EdgeId<E>[],\n ) => Promise<readonly (Edge<E, From, To> | undefined)[]>;\n\n /** Find edges matching endpoint and pagination criteria. */\n find: (\n filter?: Readonly<{\n from?: NodeRef<From>;\n to?: NodeRef<To>;\n limit?: number;\n offset?: number;\n }>,\n ) => Promise<Edge<E, From, To>[]>;\n\n /** Count edges matching criteria at the view's pinned coordinate. */\n count: (\n filter?: Readonly<{ from?: NodeRef<From>; to?: NodeRef<To> }>,\n ) => Promise<number>;\n\n /** Find edges from a specific node at the view's pinned coordinate. */\n findFrom: (from: NodeRef<From>) => Promise<Edge<E, From, To>[]>;\n\n /** Find edges to a specific node at the view's pinned coordinate. */\n findTo: (to: NodeRef<To>) => Promise<Edge<E, From, To>[]>;\n\n /** Find the edges from a set of source nodes at the view's pinned coordinate. */\n bulkFindFrom: (\n froms: readonly NodeRef<From>[],\n options?: EdgeBulkFindOptions,\n ) => Promise<readonly Edge<E, From, To>[][]>;\n\n /** Find the edges into a set of target nodes at the view's pinned coordinate. */\n bulkFindTo: (\n tos: readonly NodeRef<To>[],\n options?: EdgeBulkFindOptions,\n ) => Promise<readonly Edge<E, From, To>[][]>;\n\n /** Find the edge between two endpoints at the view's pinned coordinate. */\n findByEndpoints: (\n from: NodeRef<From>,\n to: NodeRef<To>,\n options?: EdgeFindByEndpointsOptions<E>,\n ) => Promise<Edge<E, From, To> | undefined>;\n}>;\n\n/**\n * Read-only view edge collection derived from an `EdgeRegistration`,\n * extracting the edge type and from/to node types — the read-only\n * counterpart of {@link TypedEdgeCollection}.\n */\nexport type TypedStoreViewEdgeCollection<R extends EdgeRegistration> =\n StoreViewEdgeCollection<\n R[\"type\"],\n EdgeFromTypes<R> extends NodeType ? EdgeFromTypes<R> : NodeType,\n EdgeToTypes<R> extends NodeType ? EdgeToTypes<R> : NodeType\n >;\n\n/** Mapped type of all read-only view node collections for a graph. */\nexport type StoreViewNodeCollections<G extends GraphDef> = {\n [K in keyof G[\"nodes\"] & string]-?: StoreViewNodeCollection<\n G[\"nodes\"][K][\"type\"]\n >;\n};\n\n/** Mapped type of all read-only view edge collections for a graph. */\nexport type StoreViewEdgeCollections<G extends GraphDef> = {\n [K in keyof G[\"edges\"] & string]-?: TypedStoreViewEdgeCollection<\n G[\"edges\"][K]\n >;\n};\n\n/** Options for one bounded, forward-only recorded-time collection scan. */\nexport type RecordedScanOptions = Readonly<{\n /** Maximum entities to return. Defaults to 1,000 and cannot exceed 1,000. */\n limit?: number;\n /** Opaque cursor returned by the preceding page. */\n after?: string;\n}>;\n\n/** One page from a deterministic recorded-time collection scan. */\nexport type RecordedScanPage<T> = Readonly<{\n /** Entities ordered by canonical id ascending. */\n data: readonly T[];\n /** Cursor for the next page, or `undefined` when the scan is complete. */\n nextCursor: string | undefined;\n /** Whether another page exists after this one. */\n hasNextPage: boolean;\n}>;\n\n/** Recorded-time reconstructing reads for one node kind. */\nexport type RecordedStoreViewNodeCollection<N extends NodeType> = Pick<\n StoreViewNodeCollection<N>,\n (typeof RECORDED_POINT_READ_NAMES)[number]\n> &\n Readonly<{\n /** Scan one bounded page at the view's pinned coordinate. */\n scan: (options?: RecordedScanOptions) => Promise<RecordedScanPage<Node<N>>>;\n }>;\n\n/** Recorded-time reconstructing reads for one edge kind. */\nexport type RecordedStoreViewEdgeCollection<\n E extends AnyEdgeType,\n From extends NodeType = NodeType,\n To extends NodeType = NodeType,\n> = Pick<\n StoreViewEdgeCollection<E, From, To>,\n (typeof RECORDED_POINT_READ_NAMES)[number]\n> &\n Readonly<{\n /** Scan one bounded page at the view's pinned coordinate. */\n scan: (\n options?: RecordedScanOptions,\n ) => Promise<RecordedScanPage<Edge<E, From, To>>>;\n }>;\n\n/** Recorded-time edge collection derived from an `EdgeRegistration`. */\nexport type TypedRecordedStoreViewEdgeCollection<R extends EdgeRegistration> =\n RecordedStoreViewEdgeCollection<\n R[\"type\"],\n EdgeFromTypes<R> extends NodeType ? EdgeFromTypes<R> : NodeType,\n EdgeToTypes<R> extends NodeType ? EdgeToTypes<R> : NodeType\n >;\n\n/** Mapped type of all recorded-time node reconstructing-read collections. */\nexport type RecordedStoreViewNodeCollections<G extends GraphDef> = {\n [K in keyof G[\"nodes\"] & string]-?: RecordedStoreViewNodeCollection<\n G[\"nodes\"][K][\"type\"]\n >;\n};\n\n/** Mapped type of all recorded-time edge reconstructing-read collections. */\nexport type RecordedStoreViewEdgeCollections<G extends GraphDef> = {\n [K in keyof G[\"edges\"] & string]-?: TypedRecordedStoreViewEdgeCollection<\n G[\"edges\"][K]\n >;\n};\n\n// ============================================================\n// Transaction Context\n// ============================================================\n\n/**\n * Whether — and why — `tx.sql` can be used on a transaction context. A single\n * required discriminant covering exactly the four states raw-SQL access can be\n * in, so an adapter caller branches on capability instead of truthiness-testing\n * `tx.sql`. The non-available variants omit `sql` entirely, so even reading the\n * handle requires first narrowing `sqlAvailability` to `\"available\"`. The\n * runtime object keeps a fail-loud getter under history / revision tracking for\n * JavaScript and type-suppressed callers. See\n * {@link AdapterTransactionContext} for the per-value semantics.\n */\nexport type SqlAvailability =\n \"available\" | \"history\" | \"revisionTracking\" | \"unavailable\";\n\ntype AdapterTransactionSqlAccess<TNativeTransaction> =\n | Readonly<{\n sql: TNativeTransaction;\n sqlAvailability: \"available\";\n }>\n | Readonly<{\n sqlAvailability: \"history\" | \"revisionTracking\";\n }>\n | Readonly<{\n sqlAvailability: \"unavailable\";\n }>;\n\nexport const TRANSACTION_RUNTIME: unique symbol = typeGraphGlobalSymbol(\n \"transaction-runtime-v1\",\n);\n\ntype TransactionRuntime = Readonly<{\n backend: TransactionBackend;\n runNodeOperationHooks: <T>(\n operation: \"create\" | \"update\" | \"delete\",\n kind: string,\n id: string,\n fn: () => Promise<T>,\n ) => Promise<T>;\n}>;\n\n/**\n * The portable transaction context mirrors the Store's typed graph operations\n * while exposing only a read-only backend projection bound to the transaction.\n * Adapter-native handles are available only through\n * {@link AdapterTransactionContext}; arbitrary backend writes are absent from\n * every public transaction context. TypeGraph's non-enumerable symbol port is\n * an unsupported implementation detail, not a JavaScript security boundary:\n * reflective code can still discover symbol properties.\n *\n * @example\n * ```typescript\n * await store.transaction(async (tx) => {\n * const person = await tx.nodes.Person.create({ name: \"Alice\" });\n * const company = await tx.nodes.Company.create({ name: \"Acme\" });\n * await tx.edges.worksAt.create(person, company, { role: \"Engineer\" });\n * });\n * ```\n */\ntype TransactionCollections<G extends GraphDef> = Readonly<{\n [TRANSACTION_RUNTIME]: TransactionRuntime;\n nodes: GraphNodeCollections<G>;\n edges: GraphEdgeCollections<G>;\n /** Read-only backend projection bound to the same graph transaction. */\n backend: TransactionReadBackend;\n /**\n * Runtime string-keyed node collection access, mirroring\n * `Store.getNodeCollection`. Returns `undefined` when `kind` is not\n * registered in this graph.\n */\n getNodeCollection: (kind: string) => DynamicNodeCollection | undefined;\n}> &\n (G[\"identity\"] extends GraphIdentityConfig ?\n Readonly<{ identity: IdentityFacade<G> }>\n : Readonly<Record<never, never>>);\n\n/**\n * A portable transaction context containing only TypeGraph-owned graph\n * operations. Managed Stores use this surface so adapter-native handles never\n * enter their public contract.\n */\nexport type TransactionContext<G extends GraphDef> = TransactionCollections<G>;\n\n/**\n * A transaction context exposed by an {@link AdapterStore}. In addition to the\n * portable graph collections, it carries the adapter-native handle when that\n * capability is available. The TypeGraph backend remains the same runtime\n * read projection as the portable context; adapter-native writes intentionally\n * go through `sql`, making that escape hatch explicit.\n */\nexport type AdapterTransactionContext<\n G extends GraphDef,\n TNativeTransaction,\n> = TransactionCollections<G> & AdapterTransactionSqlAccess<TNativeTransaction>;\n\n/**\n * Scoped write measurement, available only on the receipt-enabled transaction\n * contexts (`transactionWithReceipt`, `withRecordedTransaction`). Runs `fn`,\n * passing it a **scoped context** — a second view over the same transaction — and\n * returns a {@link TransactionOutcome} whose receipt counts exactly the writes\n * made *through that scoped context* (`scoped.nodes` / `scoped.edges`).\n *\n * Attribution is by **which context you write through**, not by timing. A write\n * through the scoped context counts in both the scope and the outer receipt (it\n * happened in the transaction); a write through the outer `tx` during the scope\n * counts only in the outer receipt. This makes overlapping and concurrent\n * measures safe by construction — two scopes running under `Promise.all`, each\n * writing through its own scoped context, never cross-count. Nesting composes:\n * `scoped.measure(...)` opens a child scope that counts in itself, every\n * ancestor scope, and the outer receipt.\n *\n * Counts otherwise inherit {@link TransactionReceipt} (bulk by input length, a\n * rejected write counts 0). The returned receipt's `recorded` is **always\n * `undefined`**: the recorded commit instant is a per-transaction flush concern,\n * unknowable mid-transaction.\n */\nexport type ScopedMeasure<Context> = <T>(\n fn: (scoped: Context) => Promise<T>,\n) => Promise<TransactionOutcome<T>>;\n\n/**\n * A {@link TransactionContext} that also exposes {@link ScopedMeasure}. Only the\n * receipt-enabled entry points (`transactionWithReceipt`,\n * `withRecordedTransaction`) hand a callback this type; plain `transaction()`\n * contexts have no recorder and therefore no `measure`, keeping that path\n * zero-overhead. Assignable to {@link TransactionContext}, so a projector helper\n * typed `(tx: TransactionContext<G>) => ...` accepts a measurable context. The\n * scoped context handed to `measure` is itself measurable, so scopes nest.\n */\nexport type MeasurableTransactionContext<G extends GraphDef> =\n TransactionContext<G> &\n Readonly<{\n measure: ScopedMeasure<MeasurableTransactionContext<G>>;\n }>;\n\n/** Receipt-enabled transaction context for an {@link AdapterStore}. */\nexport type MeasurableAdapterTransactionContext<\n G extends GraphDef,\n TNativeTransaction,\n> = AdapterTransactionContext<G, TNativeTransaction> &\n Readonly<{\n measure: ScopedMeasure<\n MeasurableAdapterTransactionContext<G, TNativeTransaction>\n >;\n }>;\n\n// ============================================================\n// Dynamic Collection Types (widened for runtime dispatch)\n// ============================================================\n\n/**\n * Replace branded `NodeId` / `EdgeId` with plain `string` in each\n * method's parameter list. Return types are preserved unchanged.\n *\n * Handles three shapes:\n * 1. Direct branded ID parameter → `string`\n * 2. `readonly NodeId[]` / `readonly EdgeId[]` → `readonly string[]`\n * 3. Branded IDs nested one level inside bulk-item object arrays\n */\ntype WidenBrandedIds<T> = {\n readonly [K in keyof T]: T[K] extends (...args: infer A) => infer R ?\n (...args: { [P in keyof A]: UnbrandParam<A[P]> }) => R\n : T[K];\n};\n\n/** Replace a branded ID with `string`, recursing one level into arrays. */\ntype UnbrandParam<T> =\n T extends NodeId<NodeType> ? string\n : T extends EdgeId<AnyEdgeType> ? string\n : T extends readonly NodeId<NodeType>[] ? readonly string[]\n : T extends readonly EdgeId<AnyEdgeType>[] ? readonly string[]\n : T extends readonly (infer Item extends Record<string, unknown>)[] ?\n readonly UnbrandRecord<Item>[]\n : T;\n\n/** Replace branded ID values in object properties (does not recurse into nested structures). */\ntype UnbrandRecord<T extends Record<string, unknown>> = {\n readonly [K in keyof T]: T[K] extends NodeId<NodeType> ? string\n : T[K] extends EdgeId<AnyEdgeType> ? string\n : T[K];\n};\n\n/**\n * A node collection with widened generics for runtime string-keyed access.\n *\n * This is the return type of `store.getNodeCollection(kind)`. It exposes\n * the full `NodeCollection` API but with `NodeType` and `string` constraint\n * names instead of the specific generic parameters, since the concrete type\n * is not known at compile time.\n *\n * ID parameters accept plain `string` instead of branded `NodeId<N>`, since\n * the dynamic path typically receives IDs from edge metadata, snapshots,\n * or external input where the brand is not available.\n */\nexport type DynamicNodeCollection = WidenBrandedIds<\n NodeCollection<NodeType, string>\n>;\n\n/**\n * An edge collection with widened generics for runtime string-keyed access.\n *\n * This is the return type of `store.getEdgeCollection(kind)`. It exposes\n * the full `EdgeCollection` API but with `NodeType` endpoint types, since\n * the concrete from/to types are not known at compile time.\n *\n * ID parameters accept plain `string` instead of branded `EdgeId<E>`, since\n * the dynamic path typically receives IDs from edge metadata, snapshots,\n * or external input where the brand is not available.\n */\nexport type DynamicEdgeCollection = WidenBrandedIds<\n EdgeCollection<AnyEdgeType, NodeType, NodeType>\n>;\n\n// ============================================================\n// Store Projection\n// ============================================================\n\n/**\n * A type-level projection of a store's surface onto a subset of its\n * node and edge collections.\n *\n * Node collections are projected with constraint names erased (`never`),\n * so constraint-based methods like `findByConstraint` become uncallable.\n * This is intentional: unique constraints are graph-registration-level\n * details that differ between graphs sharing the same node types.\n *\n * @example\n * ```typescript\n * type CoreStore = StoreProjection<\n * typeof myGraph,\n * \"Document\" | \"Chunk\",\n * \"hasChunk\"\n * >;\n *\n * async function ingestChunk(\n * store: CoreStore,\n * document: Node<typeof Document>,\n * text: string,\n * ) {\n * const chunk = await store.nodes.Chunk.create({ text });\n * await store.edges.hasChunk.create(document, chunk);\n * return chunk;\n * }\n * ```\n *\n * Both `Store<G>` and `TransactionContext<G>` are structurally assignable\n * to a `StoreProjection` whose keys are a subset of `G`.\n */\nexport type StoreProjection<\n G extends GraphDef,\n N extends keyof G[\"nodes\"] & string = never,\n E extends keyof G[\"edges\"] & string = never,\n> = Readonly<{\n nodes: { [K in N]-?: NodeCollection<G[\"nodes\"][K][\"type\"], never> };\n edges: Pick<GraphEdgeCollections<G>, E>;\n}>;\n","import { type GraphBackend, type TransactionBackend } from \"../backend/types\";\nimport {\n type AllNodeTypes,\n type EdgeKinds,\n type GraphDef,\n type NodeKinds,\n} from \"../core/define-graph\";\nimport { type ReadCoordinate } from \"../core/temporal\";\nimport {\n type AnyEdgeType,\n type EdgeId,\n type NodeId,\n type NodeType,\n} from \"../core/types\";\nimport { type IdentityReadFacade } from \"../identity/types\";\nimport { type InitialQueryBuilder } from \"../query/builder\";\nimport { typeGraphGlobalSymbol } from \"../utils/global-symbol\";\nimport { type InternalGraphAlgorithms } from \"./algorithms\";\nimport {\n type InternalSubgraphOptions,\n type SubgraphProject,\n type SubgraphResult,\n} from \"./subgraph\";\nimport {\n type Edge,\n type Node,\n type RecordedScanOptions,\n type RecordedScanPage,\n TRANSACTION_RUNTIME,\n} from \"./types\";\n\nexport const STORE_RUNTIME: unique symbol =\n typeGraphGlobalSymbol(\"store-runtime-v1\");\n\n/**\n * @internal Operations used by Store-owned views. The port is absent from the\n * public Store contract and non-enumerable at runtime. JavaScript reflection\n * can still discover symbol properties, so this is an unsupported internal\n * surface rather than a security boundary.\n */\nexport type StoreRuntime<G extends GraphDef> = Readonly<{\n backend: GraphBackend;\n sealedQuery: (coordinate: ReadCoordinate) => InitialQueryBuilder<G, \"sealed\">;\n recordedNodeGetById: <N extends NodeType>(\n kind: string,\n id: NodeId<N>,\n coordinate: ReadCoordinate,\n ) => Promise<Node<N> | undefined>;\n recordedNodeGetByIds: <N extends NodeType>(\n kind: string,\n ids: readonly NodeId<N>[],\n coordinate: ReadCoordinate,\n ) => Promise<readonly (Node<N> | undefined)[]>;\n recordedNodeScan: <N extends NodeType>(\n kind: string,\n coordinate: ReadCoordinate,\n options?: RecordedScanOptions,\n ) => Promise<RecordedScanPage<Node<N>>>;\n recordedEdgeGetById: <E extends AnyEdgeType>(\n kind: string,\n id: EdgeId<E>,\n coordinate: ReadCoordinate,\n ) => Promise<Edge<E> | undefined>;\n recordedEdgeGetByIds: <E extends AnyEdgeType>(\n kind: string,\n ids: readonly EdgeId<E>[],\n coordinate: ReadCoordinate,\n ) => Promise<readonly (Edge<E> | undefined)[]>;\n recordedEdgeScan: <E extends AnyEdgeType>(\n kind: string,\n coordinate: ReadCoordinate,\n options?: RecordedScanOptions,\n ) => Promise<RecordedScanPage<Edge<E>>>;\n subgraphAtCoordinate: <\n const EK extends EdgeKinds<G>,\n const NK extends NodeKinds<G> = NodeKinds<G>,\n const P extends SubgraphProject<G, NK, EK> | undefined = undefined,\n >(\n rootId: NodeId<AllNodeTypes<G>>,\n options: InternalSubgraphOptions<G, EK, NK, P>,\n ) => Promise<SubgraphResult<G, NK, EK, P>>;\n algorithmsAtCoordinate: (\n coordinate: ReadCoordinate,\n ) => InternalGraphAlgorithms<G>;\n identityAtCoordinate: (coordinate: ReadCoordinate) => IdentityReadFacade<G>;\n rebuildIdentityClosure: () => Promise<void>;\n validateIdentity: () => Promise<void>;\n /**\n * @internal Reads the graph's identity assertions in transfer shape, honoring\n * this store's SQL binding. Used by interchange export, base-version\n * fingerprinting, and merge staging/diff.\n */\n readCurrentIdentityAssertions: (\n mode: \"state\" | \"archival\",\n options?: Readonly<{\n nodeKinds?: readonly string[];\n includeDeleted?: boolean;\n }>,\n ) => Promise<\n readonly Readonly<{\n id: string;\n relation: \"same\" | \"different\";\n a: Readonly<{ kind: string; id: string }>;\n b: Readonly<{ kind: string; id: string }>;\n validFrom: string;\n validTo?: string | undefined;\n endedBy?: Readonly<{ kind: string; id: string }> | undefined;\n }>[]\n >;\n /**\n * Live nodes (registry kinds only) sharing any of the given bare ids —\n * the cross-kind peer set same-id folding would join. Used by graph-merge's\n * plan-time contradiction simulation to seed its node universe.\n */\n liveNodesSharingIds: (\n ids: readonly string[],\n target?: GraphBackend | TransactionBackend,\n ) => Promise<readonly Readonly<{ kind: string; id: string }>[]>;\n /**\n * Every stored assertion row (ended rows included) for the given assertion\n * ids — the rows the import coordinator's id-conflict check compares\n * against. Used by graph-merge to validate the one-id-one-truth invariant\n * at plan time and inside the commit transaction.\n */\n identityAssertionRowsByIds: (\n ids: readonly string[],\n target?: GraphBackend | TransactionBackend,\n ) => Promise<\n ReadonlyMap<\n string,\n Readonly<{\n id: string;\n relation: \"same\" | \"different\";\n a: Readonly<{ kind: string; id: string }>;\n b: Readonly<{ kind: string; id: string }>;\n validFrom: string;\n validTo?: string | undefined;\n endedBy?: Readonly<{ kind: string; id: string }> | undefined;\n }>\n >\n >;\n /**\n * The CURRENT structural identity class (materialized closure: folds plus\n * asserted links) of each reference, keyed by `refKey` — the\n * `JSON.stringify([kind, id])` serialization exported from\n * `identity/service`, which callers must use to probe the returned map. A\n * missing node coalesces to its singleton. Used by graph-merge's fold-peer\n * window guard to detect class-transitive drift in the plan→commit window.\n */\n structuralIdentityClasses: (\n references: readonly Readonly<{ kind: string; id: string }>[],\n target?: GraphBackend | TransactionBackend,\n ) => Promise<\n ReadonlyMap<string, readonly Readonly<{ kind: string; id: string }>[]>\n >;\n identityAssertionsAtTarget: (\n target: GraphBackend | TransactionBackend,\n mode?: \"state\" | \"archival\",\n ) => Promise<\n readonly Readonly<{\n id: string;\n relation: \"same\" | \"different\";\n a: Readonly<{ kind: string; id: string }>;\n b: Readonly<{ kind: string; id: string }>;\n validFrom: string;\n validTo?: string | undefined;\n endedBy?: Readonly<{ kind: string; id: string }> | undefined;\n }>[]\n >;\n readIdentityAssertionPageAtTarget: (\n target: GraphBackend | TransactionBackend,\n mode: \"state\" | \"archival\",\n options: Readonly<{\n nodeKinds?: readonly string[];\n includeDeleted?: boolean;\n after?: string;\n limit: number;\n }>,\n ) => Promise<\n Readonly<{\n assertions: readonly Readonly<{\n id: string;\n relation: \"same\" | \"different\";\n a: Readonly<{ kind: string; id: string }>;\n b: Readonly<{ kind: string; id: string }>;\n validFrom: string;\n validTo?: string | undefined;\n endedBy?: Readonly<{ kind: string; id: string }> | undefined;\n }>[];\n nextAfter?: string;\n done: boolean;\n }>\n >;\n lockIdentityImportTarget: (\n target: GraphBackend | TransactionBackend,\n ) => Promise<void>;\n foldImportedIdentityNodes: (\n target: GraphBackend | TransactionBackend,\n references: readonly Readonly<{ kind: string; id: string }>[],\n ) => Promise<void>;\n importIdentityAssertionsAtTarget: (\n target: GraphBackend | TransactionBackend,\n assertions: readonly Readonly<{\n id: string;\n relation: \"same\" | \"different\";\n a: Readonly<{ kind: string; id: string }>;\n b: Readonly<{ kind: string; id: string }>;\n validFrom: string;\n validTo?: string | undefined;\n endedBy?: Readonly<{ kind: string; id: string }> | undefined;\n }>[],\n mode: \"state\" | \"archival\",\n ) => Promise<Readonly<{ created: number; skipped: number }>>;\n applyIdentityMergeAtTarget: (\n target: GraphBackend | TransactionBackend,\n retractionIds: readonly string[],\n assertions: readonly Readonly<{\n id: string;\n relation: \"same\" | \"different\";\n a: Readonly<{ kind: string; id: string }>;\n b: Readonly<{ kind: string; id: string }>;\n validFrom: string;\n validTo?: string | undefined;\n endedBy?: Readonly<{ kind: string; id: string }> | undefined;\n }>[],\n ) => Promise<Readonly<{ created: number; retracted: number }>>;\n /**\n * Proves the identity classes of `seeds` carry no contradiction in the state\n * the caller's transaction has just written — the post-write half of\n * graph-merge's identity correctness, scoped to the classes the merge\n * touched. A refusal aborts the caller's transaction; identity-disabled\n * graphs resolve immediately.\n */\n assertIdentityClassesConsistentAtTarget: (\n target: GraphBackend | TransactionBackend,\n seeds: readonly Readonly<{ kind: string; id: string }>[],\n ) => Promise<void>;\n}>;\n\nexport function storeRuntime<G extends GraphDef>(\n store: Readonly<{ [STORE_RUNTIME]?: StoreRuntime<G> }>,\n): StoreRuntime<G> {\n const runtime = store[STORE_RUNTIME];\n if (runtime === undefined) {\n throw new TypeError(\n \"Cannot access this Store's runtime port. The Store may come from an incompatible TypeGraph version.\",\n );\n }\n return runtime;\n}\n\nexport function storeBackend<G extends GraphDef>(\n store: Readonly<{ [STORE_RUNTIME]?: StoreRuntime<G> }>,\n): GraphBackend {\n return storeRuntime(store).backend;\n}\n\ntype TransactionRuntimePort = Readonly<{\n [TRANSACTION_RUNTIME]?: Readonly<{\n backend: TransactionBackend;\n runNodeOperationHooks: TransactionNodeOperationHookRunner;\n }>;\n}>;\n\ntype TransactionNodeOperationHookRunner = <T>(\n operation: \"create\" | \"update\" | \"delete\",\n kind: string,\n id: string,\n fn: () => Promise<T>,\n) => Promise<T>;\n\n/** Returns the full backend for privileged transaction-bound internals. */\nexport function transactionBackend(\n transaction: TransactionRuntimePort,\n): TransactionBackend {\n const runtime = transaction[TRANSACTION_RUNTIME];\n if (runtime === undefined) {\n throw new TypeError(\n \"Cannot access this transaction's runtime port. The transaction may come from an incompatible TypeGraph version.\",\n );\n }\n return runtime.backend;\n}\n\n/** Returns the hook runner paired with a transaction's internal backend. */\nexport function transactionNodeOperationHookRunner(\n transaction: TransactionRuntimePort,\n): TransactionNodeOperationHookRunner {\n const runtime = transaction[TRANSACTION_RUNTIME];\n if (runtime === undefined) {\n throw new TypeError(\n \"Cannot access this transaction's runtime port. The transaction may come from an incompatible TypeGraph version.\",\n );\n }\n return runtime.runNodeOperationHooks;\n}\n","/**\n * Embedding Sync Utilities\n *\n * Handles automatic synchronization of embedding fields with the embeddings table.\n * When nodes with embedding properties are created, updated, or deleted,\n * these utilities ensure the embeddings table stays in sync.\n */\nimport { type z } from \"zod\";\n\nimport { type GraphBackend, type TransactionBackend } from \"../backend/types\";\nimport {\n type ResolvedEmbeddingField,\n resolveEmbeddingFields,\n} from \"../core/embedding\";\nimport { readOwnProperty } from \"../utils/object\";\n\n// ============================================================\n// Types\n// ============================================================\n\n/**\n * Information about an embedding field in a node schema.\n *\n * Re-exports the canonical {@link ResolvedEmbeddingField} so the backend\n * gets `dimensions` plus the resolved index `(metric, indexType)` — all\n * three needed to address the field's typed per-`(kind, field)` storage\n * slot when upserting.\n */\ntype EmbeddingFieldInfo = ResolvedEmbeddingField;\n\n/**\n * Context for embedding sync operations.\n */\nexport type EmbeddingSyncContext = Readonly<{\n graphId: string;\n nodeKind: string;\n nodeId: string;\n backend: GraphBackend | TransactionBackend;\n}>;\n\n// ============================================================\n// Schema Introspection\n// ============================================================\n\n/**\n * Cache keyed by the Zod schema instance. Schemas are immutable at\n * runtime; the same reference recurs across every CRUD call.\n */\nconst embeddingFieldsCache = new WeakMap<\n z.ZodType,\n readonly EmbeddingFieldInfo[]\n>();\n\n/**\n * Extracts embedding field information from a Zod schema.\n * Returns all embedding fields found at the top level of an object schema.\n *\n * Thin per-schema-instance memoization over the canonical\n * {@link resolveEmbeddingFields}; the same schema reference recurs across\n * every CRUD call, so caching avoids re-walking the shape each time.\n */\nexport function getEmbeddingFields(\n schema: z.ZodType,\n): readonly EmbeddingFieldInfo[] {\n const cached = embeddingFieldsCache.get(schema);\n if (cached) return cached;\n const fields = resolveEmbeddingFields(schema);\n embeddingFieldsCache.set(schema, fields);\n return fields;\n}\n\n// ============================================================\n// Embedding Sync Operations\n// ============================================================\n\n/**\n * Syncs embeddings after a node create or update operation.\n *\n * For each embedding field in the schema:\n * - If the props contain an embedding value, upsert it to the embeddings table\n * - If the props don't contain an embedding value (undefined), delete any existing embedding\n */\nexport async function syncEmbeddings(\n ctx: EmbeddingSyncContext,\n schema: z.ZodType,\n props: Record<string, unknown>,\n): Promise<void> {\n const { backend } = ctx;\n\n // Check if backend supports embedding operations\n if (!backend.upsertEmbedding || !backend.deleteEmbedding) {\n return;\n }\n\n const embeddingFields = getEmbeddingFields(schema);\n if (embeddingFields.length === 0) {\n return;\n }\n\n for (const field of embeddingFields) {\n const value = readOwnProperty(props, field.fieldPath);\n\n if (isValidEmbeddingValue(value)) {\n // Upsert the embedding\n await backend.upsertEmbedding({\n graphId: ctx.graphId,\n nodeKind: ctx.nodeKind,\n nodeId: ctx.nodeId,\n fieldPath: field.fieldPath,\n embedding: value,\n dimensions: field.dimensions,\n metric: field.metric,\n indexType: field.indexType,\n });\n } else if (value === undefined) {\n // Delete any existing embedding for this field\n await backend.deleteEmbedding({\n graphId: ctx.graphId,\n nodeKind: ctx.nodeKind,\n nodeId: ctx.nodeId,\n fieldPath: field.fieldPath,\n dimensions: field.dimensions,\n metric: field.metric,\n indexType: field.indexType,\n });\n }\n // If value is null or invalid, skip (validation should have caught this)\n }\n}\n\n/**\n * Syncs embeddings for a batch of same-kind node creates through one\n * `upsertEmbeddingBatch` per field (falling back to per-row\n * `upsertEmbedding` when the backend lacks the batch primitive). Mirrors\n * `syncEmbeddings` per row: present values upsert, `undefined` values\n * delete any existing embedding for the field.\n */\nexport async function syncEmbeddingsBatchForKind(\n args: Readonly<{\n graphId: string;\n nodeKind: string;\n backend: GraphBackend | TransactionBackend;\n }>,\n schema: z.ZodType,\n items: readonly Readonly<{\n nodeId: string;\n props: Record<string, unknown>;\n }>[],\n): Promise<void> {\n const { graphId, nodeKind, backend } = args;\n if (!backend.upsertEmbedding || !backend.deleteEmbedding) {\n return;\n }\n\n const embeddingFields = getEmbeddingFields(schema);\n if (embeddingFields.length === 0) {\n return;\n }\n\n for (const field of embeddingFields) {\n const rows: { nodeId: string; embedding: readonly number[] }[] = [];\n const deletionIds: string[] = [];\n for (const item of items) {\n const value = readOwnProperty(item.props, field.fieldPath);\n if (isValidEmbeddingValue(value)) {\n rows.push({ nodeId: item.nodeId, embedding: value });\n } else if (value === undefined) {\n deletionIds.push(item.nodeId);\n }\n }\n\n if (rows.length > 0) {\n if (backend.upsertEmbeddingBatch === undefined) {\n for (const row of rows) {\n await backend.upsertEmbedding({\n graphId,\n nodeKind,\n nodeId: row.nodeId,\n fieldPath: field.fieldPath,\n embedding: row.embedding,\n dimensions: field.dimensions,\n metric: field.metric,\n indexType: field.indexType,\n });\n }\n } else {\n await backend.upsertEmbeddingBatch({\n graphId,\n nodeKind,\n fieldPath: field.fieldPath,\n dimensions: field.dimensions,\n metric: field.metric,\n indexType: field.indexType,\n rows,\n });\n }\n }\n\n if (deletionIds.length > 0 && backend.deleteEmbeddingBatch !== undefined) {\n await backend.deleteEmbeddingBatch({\n graphId,\n nodeKind,\n nodeIds: deletionIds,\n fieldPath: field.fieldPath,\n dimensions: field.dimensions,\n metric: field.metric,\n indexType: field.indexType,\n });\n } else {\n for (const nodeId of deletionIds) {\n await backend.deleteEmbedding({\n graphId,\n nodeKind,\n nodeId,\n fieldPath: field.fieldPath,\n dimensions: field.dimensions,\n metric: field.metric,\n indexType: field.indexType,\n });\n }\n }\n }\n}\n\n/**\n * Deletes a node's embeddings for the embedding fields its kind CURRENTLY\n * declares. A field dropped from the schema after the node was written is\n * intentionally NOT swept here — its entire per-field table is reclaimed\n * wholesale by `store.materializeRemovals()` (the deferred-cleanup verb), which\n * also covers live (never-deleted) nodes' rows. So a hard/soft delete can leave\n * a transient orphan row in a removed field's table until the next reclaim pass;\n * that is the deferred-cleanup design, not a leak.\n */\nexport async function deleteNodeEmbeddings(\n ctx: EmbeddingSyncContext,\n schema: z.ZodType,\n): Promise<void> {\n const { backend } = ctx;\n\n // Check if backend supports embedding operations\n if (!backend.deleteEmbedding) {\n return;\n }\n\n const embeddingFields = getEmbeddingFields(schema);\n if (embeddingFields.length === 0) {\n return;\n }\n\n for (const field of embeddingFields) {\n await backend.deleteEmbedding({\n graphId: ctx.graphId,\n nodeKind: ctx.nodeKind,\n nodeId: ctx.nodeId,\n fieldPath: field.fieldPath,\n dimensions: field.dimensions,\n metric: field.metric,\n indexType: field.indexType,\n });\n }\n}\n\n// ============================================================\n// Validation Helpers\n// ============================================================\n\n/**\n * Checks if a value is a valid embedding (array of numbers).\n */\nfunction isValidEmbeddingValue(value: unknown): value is readonly number[] {\n if (!Array.isArray(value)) {\n return false;\n }\n return value.every((n) => typeof n === \"number\" && Number.isFinite(n));\n}\n","/**\n * Keeps the fulltext index in sync with node data. One row per node:\n * the values of every `searchable()` field are concatenated (joined by\n * `\\n`) and stored as the indexed `content`, so a single FTS query can\n * match terms spanning multiple source fields — which a per-field\n * layout cannot, since FTS5 / Postgres MATCH require all terms in one\n * indexed document.\n *\n * Sync runs inline in the node-operation call path, so it inherits the\n * caller's transaction context.\n */\nimport { type z } from \"zod\";\n\nimport { type GraphBackend, type TransactionBackend } from \"../backend/types\";\nimport {\n DEFAULT_SEARCHABLE_LANGUAGE,\n getSearchableFields,\n type SearchableFieldInfo,\n} from \"../core/searchable\";\nimport { readOwnProperty } from \"../utils/object\";\n\nexport { getSearchableFields } from \"../core/searchable\";\n\nexport type FulltextSyncContext = Readonly<{\n graphId: string;\n nodeKind: string;\n nodeId: string;\n backend: GraphBackend | TransactionBackend;\n}>;\n\nconst FIELD_SEPARATOR = \"\\n\";\n\n/**\n * Picks a representative language when a node has searchable fields with\n * different language settings. Users who need true per-field\n * multilingual indexing should split the data across node kinds.\n */\nfunction resolveCombinedLanguage(\n fields: readonly SearchableFieldInfo[],\n): string {\n return fields[0]?.metadata.language ?? DEFAULT_SEARCHABLE_LANGUAGE;\n}\n\n/**\n * Computes the combined fulltext content for a node, or `undefined`\n * if the node has no non-empty searchable fields.\n *\n * Shared between `syncFulltext` (per-write) and `rebuildFulltextIndex`\n * (bulk) so the two never drift.\n */\nexport function computeFulltextContent(\n schema: z.ZodType,\n props: Record<string, unknown>,\n): { content: string; language: string } | undefined {\n const searchableFields = getSearchableFields(schema);\n if (searchableFields.length === 0) return undefined;\n\n const parts: string[] = [];\n for (const field of searchableFields) {\n const value = readOwnProperty(props, field.fieldPath);\n if (typeof value === \"string\" && value.length > 0) {\n parts.push(value);\n }\n }\n if (parts.length === 0) return undefined;\n\n return {\n content: parts.join(FIELD_SEPARATOR),\n language: resolveCombinedLanguage(searchableFields),\n };\n}\n\n/**\n * Syncs the fulltext index row after a node create or update.\n *\n * Concatenates the values of all searchable fields into a single content\n * string and upserts it. If every field is empty / undefined, deletes\n * any existing row for the node.\n */\nexport async function syncFulltext(\n ctx: FulltextSyncContext,\n schema: z.ZodType,\n props: Record<string, unknown>,\n): Promise<void> {\n const { backend } = ctx;\n\n if (!backend.upsertFulltext || !backend.deleteFulltext) {\n return;\n }\n\n // `computeFulltextContent` returns `undefined` both when the schema has\n // no `searchable()` fields and when every value is empty — either case\n // means the row should not exist. Delete any stale row only when the\n // schema declares searchable fields (nothing to clean up otherwise).\n const computed = computeFulltextContent(schema, props);\n if (computed !== undefined) {\n await backend.upsertFulltext({\n graphId: ctx.graphId,\n nodeKind: ctx.nodeKind,\n nodeId: ctx.nodeId,\n content: computed.content,\n language: computed.language,\n });\n return;\n }\n if (getSearchableFields(schema).length === 0) return;\n await backend.deleteFulltext({\n graphId: ctx.graphId,\n nodeKind: ctx.nodeKind,\n nodeId: ctx.nodeId,\n });\n}\n\n/**\n * Syncs the fulltext rows for a batch of same-kind node creates through\n * one `upsertFulltextBatch` call (falling back to per-row `upsertFulltext`\n * when the backend lacks the batch primitive). Mirrors `syncFulltext`\n * per row: computed content upserts, empty content deletes any stale row\n * when the schema declares searchable fields.\n */\nexport async function syncFulltextBatchForKind(\n args: Readonly<{\n graphId: string;\n nodeKind: string;\n backend: GraphBackend | TransactionBackend;\n }>,\n schema: z.ZodType,\n items: readonly Readonly<{\n nodeId: string;\n props: Record<string, unknown>;\n }>[],\n): Promise<void> {\n const { graphId, nodeKind, backend } = args;\n if (!backend.upsertFulltext || !backend.deleteFulltext) {\n return;\n }\n\n const rows: { nodeId: string; content: string; language: string }[] = [];\n const emptyContentIds: string[] = [];\n const hasSearchableFields = getSearchableFields(schema).length > 0;\n for (const item of items) {\n const computed = computeFulltextContent(schema, item.props);\n if (computed !== undefined) {\n rows.push({\n nodeId: item.nodeId,\n content: computed.content,\n language: computed.language,\n });\n } else if (hasSearchableFields) {\n emptyContentIds.push(item.nodeId);\n }\n }\n\n if (rows.length > 0) {\n if (backend.upsertFulltextBatch === undefined) {\n for (const row of rows) {\n await backend.upsertFulltext({\n graphId,\n nodeKind,\n nodeId: row.nodeId,\n content: row.content,\n language: row.language,\n });\n }\n } else {\n await backend.upsertFulltextBatch({ graphId, nodeKind, rows });\n }\n }\n\n if (emptyContentIds.length > 0) {\n if (backend.deleteFulltextBatch === undefined) {\n for (const nodeId of emptyContentIds) {\n await backend.deleteFulltext({ graphId, nodeKind, nodeId });\n }\n } else {\n await backend.deleteFulltextBatch({\n graphId,\n nodeKind,\n nodeIds: emptyContentIds,\n });\n }\n }\n}\n\n/**\n * Deletes the fulltext row for a node.\n * Called on soft-delete; hard-delete is handled by the backend cascade.\n */\nexport async function deleteNodeFulltext(\n ctx: FulltextSyncContext,\n schema: z.ZodType,\n): Promise<void> {\n const { backend } = ctx;\n\n if (!backend.deleteFulltext) {\n return;\n }\n\n if (getSearchableFields(schema).length === 0) {\n return;\n }\n\n await backend.deleteFulltext({\n graphId: ctx.graphId,\n nodeKind: ctx.nodeKind,\n nodeId: ctx.nodeId,\n });\n}\n","/**\n * Uniqueness Constraint Management\n *\n * Handles checking, inserting, updating, and deleting uniqueness constraint entries.\n */\nimport {\n type GraphBackend,\n type InsertUniqueParams,\n type TransactionBackend,\n} from \"../backend/types\";\nimport {\n checkWherePredicate,\n computeUniqueKey,\n getKindsForUniquenessCheck,\n} from \"../constraints\";\nimport { type UniqueConstraint } from \"../core/types\";\nimport { UniquenessError } from \"../errors\";\nimport { type KindRegistry } from \"../registry/kind-registry\";\n\n/**\n * Context for uniqueness operations.\n */\nexport type UniquenessContext = Readonly<{\n graphId: string;\n registry: KindRegistry;\n backend: GraphBackend | TransactionBackend;\n}>;\n\n/** Builds a {@link UniquenessContext} — the one constructor every call site shares. */\nexport function createUniquenessContext(\n graphId: string,\n registry: KindRegistry,\n backend: GraphBackend | TransactionBackend,\n): UniquenessContext {\n return { graphId, registry, backend };\n}\n\n/**\n * Probes ONE constraint's key across every kind its scope covers.\n *\n * THE SINGLE OWNER of \"is this key available to this node?\" — the conflict\n * verdict and the ownership reading are one read, so no caller can consult one\n * without the other. {@link checkUniquenessConstraints} is this probe run for\n * its refusal alone; the plan builders below additionally keep what it read.\n *\n * @returns whether THIS node already holds the key live under its OWN kind, in\n * which case a claim would be a no-op and a compensating release would strip\n * a reservation the node is entitled to.\n * @throws UniquenessError when a DIFFERENT node holds the key under any kind in\n * scope.\n */\nasync function probeUniqueKey(\n ctx: UniquenessContext,\n kind: string,\n id: string,\n constraint: UniqueConstraint,\n key: string,\n): Promise<boolean> {\n const kindsToCheck = getKindsForUniquenessCheck(\n kind,\n constraint.scope,\n ctx.registry,\n );\n\n // `let` earns its place: the loop must visit EVERY kind in scope to reach its\n // refusal, so the ownership reading cannot be an early return.\n let heldByThisNode = false;\n for (const kindToCheck of kindsToCheck) {\n const existing = await ctx.backend.checkUnique({\n graphId: ctx.graphId,\n nodeKind: kindToCheck,\n constraintName: constraint.name,\n key,\n });\n\n if (existing === undefined) continue;\n if (existing.node_id !== id) {\n throw new UniquenessError({\n constraintName: constraint.name,\n kind: kindToCheck,\n existingId: existing.node_id,\n newId: id,\n fields: constraint.fields,\n });\n }\n if (kindToCheck === kind) heldByThisNode = true;\n }\n return heldByThisNode;\n}\n\n/**\n * Checks uniqueness constraints for a new or existing node.\n *\n * @throws ValidationError if any constraint is violated\n */\nexport async function checkUniquenessConstraints(\n ctx: UniquenessContext,\n kind: string,\n id: string,\n props: Record<string, unknown>,\n constraints: readonly UniqueConstraint[],\n): Promise<void> {\n for (const constraint of constraints) {\n if (!checkWherePredicate(constraint, props)) {\n continue;\n }\n\n await probeUniqueKey(\n ctx,\n kind,\n id,\n constraint,\n computeUniqueKey(props, constraint.fields, constraint.collation),\n );\n }\n}\n\n/**\n * Inserts uniqueness entries for a newly created node.\n */\nexport async function insertUniquenessEntries(\n ctx: UniquenessContext,\n kind: string,\n id: string,\n props: Record<string, unknown>,\n constraints: readonly UniqueConstraint[],\n): Promise<void> {\n for (const constraint of constraints) {\n if (!checkWherePredicate(constraint, props)) {\n continue;\n }\n\n const key = computeUniqueKey(\n props,\n constraint.fields,\n constraint.collation,\n );\n\n await ctx.backend.insertUnique({\n graphId: ctx.graphId,\n nodeKind: kind,\n constraintName: constraint.name,\n key,\n nodeId: id,\n concreteKind: kind,\n });\n }\n}\n\n/**\n * Inserts uniqueness entries for a batch of newly created nodes through one\n * `insertUniqueBatch` call (falling back to per-entry `insertUnique` when\n * the backend lacks the batch primitive). Same conflict semantics as the\n * per-node path: the first entry whose key a different live node holds\n * throws `UniquenessError`.\n */\nexport async function insertUniquenessEntriesBatch(\n ctx: UniquenessContext,\n items: readonly Readonly<{\n kind: string;\n id: string;\n props: Record<string, unknown>;\n constraints: readonly UniqueConstraint[];\n }>[],\n): Promise<void> {\n const entries: InsertUniqueParams[] = [];\n for (const item of items) {\n for (const constraint of item.constraints) {\n if (!checkWherePredicate(constraint, item.props)) {\n continue;\n }\n entries.push({\n graphId: ctx.graphId,\n nodeKind: item.kind,\n constraintName: constraint.name,\n key: computeUniqueKey(\n item.props,\n constraint.fields,\n constraint.collation,\n ),\n nodeId: item.id,\n concreteKind: item.kind,\n });\n }\n }\n if (entries.length === 0) return;\n\n if (ctx.backend.insertUniqueBatch !== undefined) {\n await ctx.backend.insertUniqueBatch(entries);\n return;\n }\n for (const entry of entries) {\n await ctx.backend.insertUnique(entry);\n }\n}\n\n/**\n * Deletes uniqueness entries for a node being deleted.\n */\nexport async function deleteUniquenessEntries(\n ctx: UniquenessContext,\n kind: string,\n props: Record<string, unknown>,\n constraints: readonly UniqueConstraint[],\n): Promise<void> {\n for (const constraint of constraints) {\n if (!checkWherePredicate(constraint, props)) {\n continue;\n }\n\n const key = computeUniqueKey(\n props,\n constraint.fields,\n constraint.collation,\n );\n\n await ctx.backend.deleteUnique({\n graphId: ctx.graphId,\n nodeKind: kind,\n constraintName: constraint.name,\n key,\n });\n }\n}\n\n/**\n * A single constraint's sidecar transition, decided by a plan builder and\n * carried out by {@link withUniquenessTransition}.\n *\n * The two keys move at DIFFERENT times relative to the primary row write, so\n * they are named for when they move rather than for old/new:\n * `claim` is reserved BEFORE the write (it is the write's conflict gate),\n * `release` is given up AFTER it (it is history the write supersedes).\n */\ntype PendingUniqueMutation = Readonly<{\n constraintName: string;\n /** The key to give up once the primary write lands; undefined = none. */\n release: string | undefined;\n /**\n * The key to reserve before the primary write; undefined = none, either\n * because the constraint stopped applying or because {@link probeUniqueKey}\n * found this node already holding it live.\n */\n claim: string | undefined;\n}>;\n\n/**\n * The sidecar transition a node write owes, decided but not yet performed.\n *\n * Opaque to its holder on purpose: the only thing a caller does with a plan is\n * hand it to {@link withUniquenessTransition} together with the primary row\n * write it belongs to.\n */\nexport type UniquenessUpdatePlan = readonly PendingUniqueMutation[];\n\n/**\n * Decides the uniqueness-entry changes a node's new props require, WITHOUT\n * writing any of them.\n *\n * Preflights EVERY changed constraint before anything is written. A node can\n * carry several unique constraints; probing them one at a time as they are\n * applied would let a later constraint's conflict throw after earlier sidecars\n * already moved. Probing all of them first means a refusal here happens with\n * zero writes, and the probes are independent per `constraintName`, so one\n * constraint's verdict is unaffected by the others' still-unapplied changes.\n *\n * Handles the cases where a constraint starts applying, stops applying, or\n * keeps applying under a different key.\n *\n * @throws UniquenessError if an updated value is already held by another node\n */\nexport async function planUniquenessUpdate(\n ctx: UniquenessContext,\n kind: string,\n id: string,\n oldProps: Record<string, unknown>,\n newProps: Record<string, unknown>,\n constraints: readonly UniqueConstraint[],\n): Promise<UniquenessUpdatePlan> {\n const pending: PendingUniqueMutation[] = [];\n for (const constraint of constraints) {\n const oldApplies = checkWherePredicate(constraint, oldProps);\n const newApplies = checkWherePredicate(constraint, newProps);\n\n const oldKey =\n oldApplies ?\n computeUniqueKey(oldProps, constraint.fields, constraint.collation)\n : undefined;\n const newKey =\n newApplies ?\n computeUniqueKey(newProps, constraint.fields, constraint.collation)\n : undefined;\n\n // No change - constraint didn't apply and still doesn't\n if (!oldApplies && !newApplies) {\n continue;\n }\n\n // Keys are the same and constraint still applies - nothing to do\n if (oldApplies && newApplies && oldKey === newKey) {\n continue;\n }\n\n // Probe the new key: refuse a value another node holds, and note a value\n // this node somehow holds already so the transition neither re-claims nor\n // releases it.\n const alreadyHeld =\n newKey === undefined ? false : (\n await probeUniqueKey(ctx, kind, id, constraint, newKey)\n );\n\n pending.push({\n constraintName: constraint.name,\n release: oldKey,\n claim: alreadyHeld ? undefined : newKey,\n });\n }\n\n return pending;\n}\n\n/**\n * The plan a RESURRECTING write needs: every applying constraint re-reserved\n * from scratch.\n *\n * A tombstoned node holds no live reservations — {@link deleteUniquenessEntries}\n * released them at soft-delete time — so the diff-based\n * {@link planUniquenessUpdate} cannot be used here: it would skip an unchanged\n * key and leave the revived node holding NO reservation, letting a later create\n * silently duplicate the value.\n *\n * @throws UniquenessError if a key this node held was taken while it was\n * tombstoned\n */\nexport async function planUniquenessReinsert(\n ctx: UniquenessContext,\n kind: string,\n id: string,\n props: Record<string, unknown>,\n constraints: readonly UniqueConstraint[],\n): Promise<UniquenessUpdatePlan> {\n const pending: PendingUniqueMutation[] = [];\n for (const constraint of constraints) {\n if (!checkWherePredicate(constraint, props)) continue;\n\n const key = computeUniqueKey(\n props,\n constraint.fields,\n constraint.collation,\n );\n const alreadyHeld = await probeUniqueKey(ctx, kind, id, constraint, key);\n\n pending.push({\n constraintName: constraint.name,\n release: undefined,\n claim: alreadyHeld ? undefined : key,\n });\n }\n return pending;\n}\n\n/** Gives up the reservations named by `keys`, in plan order. */\nasync function releaseUniqueKeys(\n ctx: UniquenessContext,\n kind: string,\n keys: readonly Readonly<{ constraintName: string; key: string }>[],\n): Promise<void> {\n for (const entry of keys) {\n await ctx.backend.deleteUnique({\n graphId: ctx.graphId,\n nodeKind: kind,\n constraintName: entry.constraintName,\n key: entry.key,\n });\n }\n}\n\n/**\n * Reserves the plan's new keys, runs the primary row write they gate, and undoes\n * the reservations if that write does not land.\n */\nasync function claimUniqueKeysThen<T>(\n ctx: UniquenessContext,\n kind: string,\n id: string,\n plan: UniquenessUpdatePlan,\n gatedWrite: () => Promise<T>,\n): Promise<T> {\n const claimed: Readonly<{ constraintName: string; key: string }>[] = [];\n try {\n for (const mutation of plan) {\n if (mutation.claim === undefined) continue;\n await ctx.backend.insertUnique({\n graphId: ctx.graphId,\n nodeKind: kind,\n constraintName: mutation.constraintName,\n key: mutation.claim,\n nodeId: id,\n concreteKind: kind,\n });\n claimed.push({\n constraintName: mutation.constraintName,\n key: mutation.claim,\n });\n }\n return await gatedWrite();\n } catch (error) {\n // Compensate, not swallow: the reservations this transition took are given\n // back and the original failure is rethrown, so the caller sees the SAME\n // error it would have seen with no reservation attempted at all.\n //\n // The give-back is exact because of what a claim can be. `probeUniqueKey`\n // refuses a key another node holds and reports one THIS node already holds\n // (which the plan then does not claim), so every claimed key was free or\n // tombstoned beforehand and releasing it restores precisely that. And no\n // peer can have taken it in between: this transaction holds the row.\n //\n // One detail is restored in kind rather than exactly: a claim that took over\n // a TOMBSTONED reservation rewrites its recorded owner, and the give-back\n // re-tombstones it under THIS node's id instead of the previous holder's.\n // The key reads as free either way — `checkUnique` skips tombstoned rows —\n // and the one reader that looks at them, `getOrCreateByConstraint`'s\n // resurrect-by-key lookup, writes the props it was called with onto whatever\n // row it revives, so the reservation and the row holding the value stay\n // consistent. Which tombstone that lookup revives can differ. If the\n // compensation itself fails the row is genuinely half-written, and the\n // error that then surfaces is a raw backend failure no per-row consumer\n // catches — the enclosing transaction aborts, which is the only honest\n // outcome left.\n await releaseUniqueKeys(ctx, kind, claimed);\n throw error;\n }\n}\n\n/**\n * Runs one node's primary row write with its uniqueness transition wrapped\n * around it, so the pair commits or fails AS ONE UNIT.\n *\n * ## Why the sequence is claim, gate, release\n *\n * A node update is two independently fallible writes — the row itself and its\n * uniqueness entries — with no rollback between them: nothing here is\n * savepoint-protected (see `operations/write-transaction.ts`), and the backends\n * this supports do not all have savepoints to reach for. Sequencing is the only\n * atomicity available, and only ONE sequence makes both failures leave zero net\n * effect:\n *\n * - **Claim first.** `insertUnique` is an upsert that reports the key's final\n * owner, so claiming IS the conflict gate — and once this transaction holds\n * the row, no concurrent writer can take the key from under it. Probing and\n * then claiming later leaves a window (wide open under PostgreSQL READ\n * COMMITTED, where a peer commits between the two) in which the claim fails\n * AFTER the row was already updated.\n * - **Then the row write.** It can legitimately match nothing —\n * `expectedValidFrom`, `deleted_at` — and callers that catch that per row and\n * commit the rest (interchange import) must not be left with reservations for\n * a row that never changed. A refusal here compensates the claims away.\n * - **Release last.** Giving up the old key before the row write would free a\n * value for a write that may never land; giving it up after is safe because\n * nothing can fail on it.\n *\n * The predecessor of this helper ordered the whole sidecar transition after the\n * row write, which closed the second failure and left the first: a caught\n * `UniquenessError` then reported `updated: 0` for a row whose props HAD\n * changed, whose old reservation was gone, and whose new one belonged to someone\n * else.\n */\nexport async function withUniquenessTransition<T>(\n ctx: UniquenessContext,\n kind: string,\n id: string,\n plan: UniquenessUpdatePlan,\n gatedWrite: () => Promise<T>,\n): Promise<T> {\n const result = await claimUniqueKeysThen(ctx, kind, id, plan, gatedWrite);\n await releaseUniqueKeys(\n ctx,\n kind,\n plan.flatMap((mutation) =>\n mutation.release === undefined ?\n []\n : [{ constraintName: mutation.constraintName, key: mutation.release }],\n ),\n );\n return result;\n}\n","/**\n * Composable node write steps — the integrity side effects that every node\n * mutation must apply, extracted so there is a single implementation instead of\n * one hand-stitched copy per write path.\n *\n * A node mutation is the core row write plus a fixed set of side effects:\n * uniqueness entries, embedding sync, fulltext sync, and — for deletes —\n * delete-behavior enforcement over connected edges. These steps are shared by\n * the canonical collection operations (create / update / delete) and by\n * provenance retraction, which drives the same close/reopen of a fact node's\n * currency but skips delete-behavior enforcement so every connected edge\n * survives for a later reopen.\n *\n * The steps assume they run inside a write transaction (see\n * {@link runInWriteTransaction}); they perform no transaction management of\n * their own.\n */\nimport { type z } from \"zod\";\n\nimport {\n type GraphBackend,\n type LiveNodeRow,\n type NodeRow,\n rowPropsToObject,\n type TombstonedNodeRow,\n type TransactionBackend,\n} from \"../../backend/types\";\nimport { type DeleteBehavior, type UniqueConstraint } from \"../../core/types\";\nimport { RestrictedDeleteError } from \"../../errors\";\nimport { type KindRegistry } from \"../../registry/kind-registry\";\nimport {\n deleteNodeEmbeddings,\n syncEmbeddings,\n syncEmbeddingsBatchForKind,\n} from \"../embedding-sync\";\nimport {\n deleteNodeFulltext,\n syncFulltext,\n syncFulltextBatchForKind,\n} from \"../fulltext-sync\";\nimport { type GraphWriteLock } from \"../recorded-capture/clock\";\nimport {\n createUniquenessContext,\n deleteUniquenessEntries,\n insertUniquenessEntries,\n insertUniquenessEntriesBatch,\n planUniquenessReinsert,\n planUniquenessUpdate,\n type UniquenessUpdatePlan,\n withUniquenessTransition,\n} from \"../uniqueness\";\n\ntype Backend = GraphBackend | TransactionBackend;\n\n/**\n * The graph-scoped state the node write steps need. `lock` is compile-time\n * evidence that the per-graph write-lock discipline was satisfied BEFORE any\n * row work (see {@link GraphWriteLock}): the pipeline performs no locking of\n * its own, so requiring the token here makes \"sidecar write before lock\" a\n * type error at the call site instead of a lock-order inversion in review.\n */\nexport type NodeWriteContext = Readonly<{\n graphId: string;\n registry: KindRegistry;\n lock: GraphWriteLock;\n}>;\n\n/** Builds a {@link NodeWriteContext} — the one constructor every call site shares. */\nexport function createNodeWriteContext(\n graphId: string,\n registry: KindRegistry,\n lock: GraphWriteLock,\n): NodeWriteContext {\n return { graphId, registry, lock };\n}\n\n/** Whether a delete removes the node (`hard`) or tombstones it (`soft`). */\ntype NodeDeleteMode = \"soft\" | \"hard\";\n\n/**\n * Tunes how a delete treats the node's connected edges.\n *\n * By default delete behavior is enforced: connected edges block a `restrict`\n * node and are removed under `cascade` / `disconnect`. Provenance retraction\n * passes `enforceDeleteBehavior: false` — closing a fact's currency is a\n * belief-status change, not a domain delete, so its edges neither block the\n * close nor get removed; they survive untouched so a later reopen is an exact\n * inverse.\n */\nexport type NodeDeletePolicy = Readonly<{\n enforceDeleteBehavior: boolean;\n}>;\n\nfunction uniquenessContext(ctx: NodeWriteContext, backend: Backend) {\n return createUniquenessContext(ctx.graphId, ctx.registry, backend);\n}\n\n/**\n * The `(graphId, nodeKind, nodeId, backend)` context shared by the embedding and\n * fulltext sync helpers — `EmbeddingSyncContext` and `FulltextSyncContext` are\n * structurally identical, so one builder serves both.\n */\nfunction nodeSyncContext(\n ctx: NodeWriteContext,\n kind: string,\n id: string,\n backend: Backend,\n) {\n return { graphId: ctx.graphId, nodeKind: kind, nodeId: id, backend };\n}\n\n/**\n * Enforces a node's delete behavior against its connected edges: they block\n * the delete (`restrict`) or are removed alongside the node (`cascade` /\n * `disconnect`). Skipped entirely when the caller's {@link NodeDeletePolicy}\n * disables enforcement.\n */\nasync function enforceNodeDeleteBehavior(\n ctx: NodeWriteContext,\n args: Readonly<{\n kind: string;\n id: string;\n mode: NodeDeleteMode;\n onDelete: DeleteBehavior | undefined;\n }>,\n backend: Backend,\n policy?: NodeDeletePolicy,\n): Promise<void> {\n if (policy?.enforceDeleteBehavior === false) return;\n const behavior = args.onDelete ?? \"restrict\";\n const connectedEdges = await backend.findEdgesConnectedTo({\n graphId: ctx.graphId,\n nodeKind: args.kind,\n nodeId: args.id,\n });\n\n if (connectedEdges.length === 0) return;\n\n switch (behavior) {\n case \"restrict\": {\n throw new RestrictedDeleteError({\n nodeKind: args.kind,\n nodeId: args.id,\n edgeCount: connectedEdges.length,\n edgeKinds: [...new Set(connectedEdges.map((edge) => edge.kind))],\n });\n }\n\n case \"cascade\":\n case \"disconnect\": {\n // Both behaviors remove connected edges. \"cascade\" signals intent to\n // remove dependent data; \"disconnect\" signals intent to sever the\n // relationship. The effect is identical because edges cannot exist\n // without both endpoints. One batched statement per bind-budget\n // chunk instead of one statement per edge; the per-edge loop remains\n // for backends without the batch members.\n const batchDelete =\n args.mode === \"hard\" ?\n backend.hardDeleteEdgesBatch\n : backend.deleteEdgesBatch;\n if (batchDelete !== undefined) {\n await batchDelete({\n graphId: ctx.graphId,\n ids: connectedEdges.map((edge) => edge.id),\n });\n break;\n }\n for (const edge of connectedEdges) {\n await (args.mode === \"hard\" ?\n backend.hardDeleteEdge({ graphId: ctx.graphId, id: edge.id })\n : backend.deleteEdge({ graphId: ctx.graphId, id: edge.id }));\n }\n break;\n }\n }\n}\n\n/**\n * Applies the side effects that follow a node insert: uniqueness entries, then\n * embedding and fulltext sync. Uniqueness has already been *checked* during\n * create preparation; this writes the entries.\n */\nexport async function applyNodeInsertSideEffects(\n ctx: NodeWriteContext,\n args: Readonly<{\n kind: string;\n id: string;\n schema: z.ZodType;\n props: Record<string, unknown>;\n uniqueConstraints: readonly UniqueConstraint[];\n }>,\n backend: Backend,\n): Promise<void> {\n await insertUniquenessEntries(\n uniquenessContext(ctx, backend),\n args.kind,\n args.id,\n args.props,\n args.uniqueConstraints,\n );\n await Promise.all([\n syncEmbeddings(\n nodeSyncContext(ctx, args.kind, args.id, backend),\n args.schema,\n args.props,\n ),\n syncFulltext(\n nodeSyncContext(ctx, args.kind, args.id, backend),\n args.schema,\n args.props,\n ),\n ]);\n}\n\n/**\n * Batched {@link applyNodeInsertSideEffects}: one uniqueness batch across\n * every item, then one embedding batch per (kind, field) and one fulltext\n * batch per kind — instead of the per-row statement fan the single-op path\n * issues. Ordering matches the single-op path (uniqueness first, then the\n * sync fans).\n */\nexport async function applyNodeInsertSideEffectsBatch(\n ctx: NodeWriteContext,\n items: readonly Readonly<{\n kind: string;\n id: string;\n schema: z.ZodType;\n props: Record<string, unknown>;\n uniqueConstraints: readonly UniqueConstraint[];\n }>[],\n backend: Backend,\n): Promise<void> {\n if (items.length === 0) return;\n\n await insertUniquenessEntriesBatch(\n uniquenessContext(ctx, backend),\n items.map((item) => ({\n kind: item.kind,\n id: item.id,\n props: item.props,\n constraints: item.uniqueConstraints,\n })),\n );\n\n interface KindGroup {\n schema: z.ZodType;\n rows: { nodeId: string; props: Record<string, unknown> }[];\n }\n const byKind = new Map<string, KindGroup>();\n for (const item of items) {\n const group = byKind.get(item.kind) ?? { schema: item.schema, rows: [] };\n group.rows.push({ nodeId: item.id, props: item.props });\n byKind.set(item.kind, group);\n }\n\n await Promise.all(\n [...byKind.entries()].flatMap(([kind, group]) => {\n const syncArguments = { graphId: ctx.graphId, nodeKind: kind, backend };\n return [\n syncEmbeddingsBatchForKind(syncArguments, group.schema, group.rows),\n syncFulltextBatchForKind(syncArguments, group.schema, group.rows),\n ];\n }),\n );\n}\n\nfunction parseRowProps(row: NodeRow): Record<string, unknown> {\n return rowPropsToObject(row.props);\n}\n\n/**\n * The row a node update targets. A plain update runs live-row side effects\n * (uniqueness diff, embedding/fulltext sync), so it must be handed a\n * {@link LiveNodeRow}; only an explicit `clearDeleted: true` resurrecting\n * upsert may target a possibly-tombstoned row. Encoding the pairing as a\n * union makes \"live-row update pipeline on a tombstoned row\" a type error.\n */\nexport type NodeUpdateTarget =\n | Readonly<{ existing: LiveNodeRow; clearDeleted?: false }>\n | Readonly<{ existing: NodeRow; clearDeleted: true }>;\n\n/**\n * Decides a node update's uniqueness transition, writing nothing.\n *\n * Two shapes behind one seam. A live row diffs its old and new keys; a\n * resurrecting update (`clearDeleted` on a tombstoned row) cannot, because the\n * soft delete already removed its entries — the diff would skip an unchanged\n * key and leave the resurrected node holding NO reservation, so a later create\n * could silently duplicate the value. It re-reserves every applying key\n * instead. Both refuse a conflict before returning, and both hand the caller a\n * plan that only {@link withUniquenessTransition} may carry out.\n */\nasync function planNodeUpdateUniqueness(\n ctx: NodeWriteContext,\n args: Readonly<{\n existing: NodeRow;\n validatedProps: Record<string, unknown>;\n uniqueConstraints: readonly UniqueConstraint[];\n }>,\n backend: Backend,\n): Promise<UniquenessUpdatePlan> {\n const { kind, id } = args.existing;\n\n if (args.existing.deleted_at !== undefined) {\n return planUniquenessReinsert(\n uniquenessContext(ctx, backend),\n kind,\n id,\n args.validatedProps,\n args.uniqueConstraints,\n );\n }\n\n return planUniquenessUpdate(\n uniquenessContext(ctx, backend),\n kind,\n id,\n parseRowProps(args.existing),\n args.validatedProps,\n args.uniqueConstraints,\n );\n}\n\n/**\n * Applies a node update: uniqueness maintenance (diff-based for a live row;\n * check-and-reinsert for a resurrecting update, whose entries the soft delete\n * removed), the core row update, then embedding and fulltext sync. Returns\n * the updated row.\n *\n * ## The row write and its uniqueness transition are ONE unit\n *\n * Both can fail — the row write matches nothing when `expectedValidFrom` or the\n * `deleted_at` fence stopped holding, the uniqueness claim loses a race for a\n * key — and a caller that catches either PER ROW and commits the rest of the\n * transaction (interchange import) must never be left with half of the pair\n * applied. {@link withUniquenessTransition} owns that sequencing and documents\n * why claim/gate/release is the only order that works; this function just hands\n * it the plan and the write.\n *\n * The embedding and fulltext syncs stay AFTER the gate: they are derived data\n * with no claim to make, so a row write that lands on nothing must not rewrite\n * a fulltext row or re-embed props no row ever received.\n */\nexport async function applyNodeUpdate(\n ctx: NodeWriteContext,\n args: Readonly<{\n schema: z.ZodType;\n validatedProps: Record<string, unknown>;\n uniqueConstraints: readonly UniqueConstraint[];\n validFrom?: string | null;\n validTo?: string;\n /** See {@link UpdateNodeParams.expectedValidFrom}. */\n expectedValidFrom?: string | null;\n }> &\n NodeUpdateTarget,\n backend: Backend,\n): Promise<NodeRow> {\n const { kind, id } = args.existing;\n\n // Read-only phase: decide the sidecar changes, refuse a conflict, write\n // nothing.\n const plan = await planNodeUpdateUniqueness(\n ctx,\n {\n existing: args.existing,\n validatedProps: args.validatedProps,\n uniqueConstraints: args.uniqueConstraints,\n },\n backend,\n );\n\n const updateParams: {\n graphId: string;\n kind: string;\n id: string;\n props: Record<string, unknown>;\n validFrom?: string | null;\n validTo?: string;\n expectedValidFrom?: string | null;\n incrementVersion?: boolean;\n clearDeleted?: boolean;\n } = {\n graphId: ctx.graphId,\n kind,\n id,\n props: args.validatedProps,\n incrementVersion: true,\n };\n if (args.validFrom !== undefined) updateParams.validFrom = args.validFrom;\n if (args.validTo !== undefined) updateParams.validTo = args.validTo;\n if (args.expectedValidFrom !== undefined) {\n updateParams.expectedValidFrom = args.expectedValidFrom;\n }\n if (args.clearDeleted) updateParams.clearDeleted = true;\n\n const row = await withUniquenessTransition(\n uniquenessContext(ctx, backend),\n kind,\n id,\n plan,\n () => backend.updateNode(updateParams),\n );\n\n await Promise.all([\n syncEmbeddings(\n nodeSyncContext(ctx, kind, id, backend),\n args.schema,\n args.validatedProps,\n ),\n syncFulltext(\n nodeSyncContext(ctx, kind, id, backend),\n args.schema,\n args.validatedProps,\n ),\n ]);\n\n return row;\n}\n\n/**\n * Applies a node soft delete: delete-behavior enforcement, the tombstone\n * write, then removal of uniqueness entries, embeddings, and fulltext.\n * Requires a {@link LiveNodeRow}: deleting an already-tombstoned row would\n * re-run sidecar cleanup against entries the first delete already removed.\n */\nexport async function applyNodeSoftDelete(\n ctx: NodeWriteContext,\n args: Readonly<{\n existing: LiveNodeRow;\n schema: z.ZodType;\n uniqueConstraints: readonly UniqueConstraint[];\n onDelete: DeleteBehavior | undefined;\n }>,\n backend: Backend,\n policy?: NodeDeletePolicy,\n): Promise<void> {\n const { kind, id } = args.existing;\n await enforceNodeDeleteBehavior(\n ctx,\n { kind, id, mode: \"soft\", onDelete: args.onDelete },\n backend,\n policy,\n );\n await backend.deleteNode({\n graphId: ctx.graphId,\n kind,\n id,\n });\n await deleteUniquenessEntries(\n uniquenessContext(ctx, backend),\n kind,\n parseRowProps(args.existing),\n args.uniqueConstraints,\n );\n await deleteNodeEmbeddings(\n nodeSyncContext(ctx, kind, id, backend),\n args.schema,\n );\n await deleteNodeFulltext(\n nodeSyncContext(ctx, kind, id, backend),\n args.schema,\n );\n}\n\n/**\n * Applies a node hard delete: delete-behavior enforcement, permanent removal,\n * then embedding cleanup. Uniqueness and fulltext rows are removed by the\n * backend's `hardDeleteNode` cascade; embeddings live in strategy-owned\n * per-`(kind, field)` tables the graph-agnostic cascade cannot reach, so they\n * are cleaned here.\n */\nexport async function applyNodeHardDelete(\n ctx: NodeWriteContext,\n args: Readonly<{\n kind: string;\n id: string;\n schema: z.ZodType;\n onDelete: DeleteBehavior | undefined;\n }>,\n backend: Backend,\n): Promise<void> {\n await enforceNodeDeleteBehavior(\n ctx,\n { kind: args.kind, id: args.id, mode: \"hard\", onDelete: args.onDelete },\n backend,\n );\n await backend.hardDeleteNode({\n graphId: ctx.graphId,\n kind: args.kind,\n id: args.id,\n });\n await deleteNodeEmbeddings(\n nodeSyncContext(ctx, args.kind, args.id, backend),\n args.schema,\n );\n}\n\n/**\n * Reopens a soft-deleted node with its stored props (no merge, no\n * re-validation): re-checks and re-inserts uniqueness entries (the delete\n * removed them), clears the tombstone, then re-syncs embeddings and fulltext.\n * Used by provenance to reinstate a fact whose currency is restored. Returns\n * the reopened row.\n *\n * @throws {UniquenessError} when a unique key the node held was taken by\n * another node while it was tombstoned.\n */\nexport async function applyNodeResurrect(\n ctx: NodeWriteContext,\n args: Readonly<{\n existing: TombstonedNodeRow;\n schema: z.ZodType;\n uniqueConstraints: readonly UniqueConstraint[];\n }>,\n backend: Backend,\n): Promise<NodeRow> {\n const { kind, id } = args.existing;\n const props = parseRowProps(args.existing);\n // One unit, exactly as `applyNodeUpdate`, and for the same reason: the\n // resurrecting UPDATE carries `deleted_at IS NOT NULL`, so a peer that revived\n // this tombstone first makes it match zero rows — and the reservations that\n // revival is entitled to are the peer's, not this caller's.\n // `withUniquenessTransition` gives them back when the gate refuses.\n const plan = await planUniquenessReinsert(\n uniquenessContext(ctx, backend),\n kind,\n id,\n props,\n args.uniqueConstraints,\n );\n const row = await withUniquenessTransition(\n uniquenessContext(ctx, backend),\n kind,\n id,\n plan,\n () =>\n backend.updateNode({\n graphId: ctx.graphId,\n kind,\n id,\n props,\n incrementVersion: true,\n clearDeleted: true,\n }),\n );\n await Promise.all([\n syncEmbeddings(nodeSyncContext(ctx, kind, id, backend), args.schema, props),\n syncFulltext(nodeSyncContext(ctx, kind, id, backend), args.schema, props),\n ]);\n return row;\n}\n"]}
@@ -1,6 +1,55 @@
1
1
  'use strict';
2
2
 
3
- var chunkU5W4LKZV_cjs = require('./chunk-U5W4LKZV.cjs');
3
+ var chunkVCRRKBLN_cjs = require('./chunk-VCRRKBLN.cjs');
4
+
5
+ // src/backend/transaction-resource.ts
6
+ var SERIALIZED_TRANSACTION_RESOURCES = /* @__PURE__ */ new WeakMap();
7
+ var ACTIVE_SERIALIZED_STREAMS = /* @__PURE__ */ new Map();
8
+ function markSerializedTransactionResource(backend, resource) {
9
+ SERIALIZED_TRANSACTION_RESOURCES.set(backend, resource);
10
+ }
11
+ function inheritSerializedTransactionResource(target, source) {
12
+ const resource = SERIALIZED_TRANSACTION_RESOURCES.get(source);
13
+ if (resource !== void 0) {
14
+ SERIALIZED_TRANSACTION_RESOURCES.set(target, resource);
15
+ }
16
+ }
17
+ function sharesSerializedTransactionResource(left, right) {
18
+ const leftResource = SERIALIZED_TRANSACTION_RESOURCES.get(left);
19
+ return leftResource !== void 0 && leftResource === SERIALIZED_TRANSACTION_RESOURCES.get(right);
20
+ }
21
+ function snapshotExportContention(source, target) {
22
+ if (!source.capabilities.transactions) return void 0;
23
+ if (source === target && source.dialect === "sqlite") {
24
+ return "same-sqlite-backend";
25
+ }
26
+ if (sharesSerializedTransactionResource(source, target)) {
27
+ return "shared-resource";
28
+ }
29
+ return void 0;
30
+ }
31
+ function acquireSerializedStreamLease(backend, kind) {
32
+ const resource = SERIALIZED_TRANSACTION_RESOURCES.get(backend);
33
+ if (resource === void 0) {
34
+ return {
35
+ acquired: true,
36
+ release: () => {
37
+ }
38
+ };
39
+ }
40
+ const holder = ACTIVE_SERIALIZED_STREAMS.get(resource);
41
+ if (holder !== void 0) return { acquired: false, heldBy: holder };
42
+ ACTIVE_SERIALIZED_STREAMS.set(resource, kind);
43
+ let released = false;
44
+ return {
45
+ acquired: true,
46
+ release: () => {
47
+ if (released) return;
48
+ released = true;
49
+ ACTIVE_SERIALIZED_STREAMS.delete(resource);
50
+ }
51
+ };
52
+ }
4
53
 
5
54
  // src/backend/types.ts
6
55
  function normalizeGraphAnalyticsCapabilities(capabilities) {
@@ -24,7 +73,7 @@ function isLiveNodeRow(row) {
24
73
  function isTombstonedNodeRow(row) {
25
74
  return row.deleted_at !== void 0;
26
75
  }
27
- var INTERNAL_TEMPORARY_WRITES = chunkU5W4LKZV_cjs.typeGraphGlobalSymbol(
76
+ var INTERNAL_TEMPORARY_WRITES = chunkVCRRKBLN_cjs.typeGraphGlobalSymbol(
28
77
  "internal-temporary-writes-v1"
29
78
  );
30
79
  function createTransactionReadBackend(backend) {
@@ -62,7 +111,7 @@ function createBackendOverlay(target, overlay) {
62
111
  function hasOverlayProperty(property) {
63
112
  return Object.hasOwn(overlay, property);
64
113
  }
65
- return new Proxy(target, {
114
+ const decoratedBackend = new Proxy(target, {
66
115
  get(targetObject, property) {
67
116
  if (hasOverlayProperty(property)) {
68
117
  return Reflect.get(overlay, property, overlay);
@@ -107,6 +156,8 @@ function createBackendOverlay(target, overlay) {
107
156
  return Reflect.deleteProperty(targetObject, property);
108
157
  }
109
158
  });
159
+ inheritSerializedTransactionResource(decoratedBackend, target);
160
+ return decoratedBackend;
110
161
  }
111
162
  function wrapWithManagedClose(backend, teardown) {
112
163
  let backendClosed = false;
@@ -198,15 +249,19 @@ exports.POSTGRES_CAPABILITIES = POSTGRES_CAPABILITIES;
198
249
  exports.POSTGRES_MAX_BIND_PARAMETERS = POSTGRES_MAX_BIND_PARAMETERS;
199
250
  exports.SQLITE_CAPABILITIES = SQLITE_CAPABILITIES;
200
251
  exports.SQLITE_MAX_BIND_PARAMETERS = SQLITE_MAX_BIND_PARAMETERS;
252
+ exports.acquireSerializedStreamLease = acquireSerializedStreamLease;
201
253
  exports.closeAfterFailure = closeAfterFailure;
202
254
  exports.createBackendOverlay = createBackendOverlay;
203
255
  exports.createTransactionReadBackend = createTransactionReadBackend;
256
+ exports.inheritSerializedTransactionResource = inheritSerializedTransactionResource;
204
257
  exports.isLiveNodeRow = isLiveNodeRow;
205
258
  exports.isTombstonedNodeRow = isTombstonedNodeRow;
259
+ exports.markSerializedTransactionResource = markSerializedTransactionResource;
206
260
  exports.normalizeGraphAnalyticsCapabilities = normalizeGraphAnalyticsCapabilities;
207
261
  exports.rowPropsToJsonText = rowPropsToJsonText;
208
262
  exports.rowPropsToObject = rowPropsToObject;
209
263
  exports.runOptionallyInTransaction = runOptionallyInTransaction;
264
+ exports.snapshotExportContention = snapshotExportContention;
210
265
  exports.wrapWithManagedClose = wrapWithManagedClose;
211
- //# sourceMappingURL=chunk-3PRKZW6D.cjs.map
212
- //# sourceMappingURL=chunk-3PRKZW6D.cjs.map
266
+ //# sourceMappingURL=chunk-XBYVV3MP.cjs.map
267
+ //# sourceMappingURL=chunk-XBYVV3MP.cjs.map