@nicia-ai/typegraph 0.43.0 → 0.45.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.
- package/dist/backend/drizzle/indexes.cjs +9 -9
- package/dist/backend/drizzle/indexes.d.cts +1 -1
- package/dist/backend/drizzle/indexes.d.ts +1 -1
- package/dist/backend/drizzle/indexes.js +5 -5
- package/dist/backend/index.cjs +50 -50
- package/dist/backend/index.d.cts +3 -3
- package/dist/backend/index.d.ts +3 -3
- package/dist/backend/index.js +11 -11
- package/dist/backend/postgres/index.cjs +26 -26
- package/dist/backend/postgres/index.d.cts +6 -5
- package/dist/backend/postgres/index.d.ts +6 -5
- package/dist/backend/postgres/index.js +13 -13
- package/dist/backend/postgres/pglite-store.cjs +32 -33
- package/dist/backend/postgres/pglite-store.cjs.map +1 -1
- package/dist/backend/postgres/pglite-store.d.cts +7 -7
- package/dist/backend/postgres/pglite-store.d.ts +7 -7
- package/dist/backend/postgres/pglite-store.js +28 -29
- package/dist/backend/postgres/pglite-store.js.map +1 -1
- package/dist/backend/postgres/pglite.cjs +15 -15
- package/dist/backend/postgres/pglite.d.cts +3 -2
- package/dist/backend/postgres/pglite.d.ts +3 -2
- package/dist/backend/postgres/pglite.js +14 -14
- package/dist/backend/sqlite/index.cjs +23 -23
- package/dist/backend/sqlite/index.d.cts +7 -6
- package/dist/backend/sqlite/index.d.ts +7 -6
- package/dist/backend/sqlite/index.js +11 -11
- package/dist/backend/sqlite/libsql.cjs +17 -17
- package/dist/backend/sqlite/libsql.cjs.map +1 -1
- package/dist/backend/sqlite/libsql.d.cts +3 -2
- package/dist/backend/sqlite/libsql.d.ts +3 -2
- package/dist/backend/sqlite/libsql.js +13 -13
- package/dist/backend/sqlite/libsql.js.map +1 -1
- package/dist/backend/sqlite/local-store.cjs +33 -34
- package/dist/backend/sqlite/local-store.cjs.map +1 -1
- package/dist/backend/sqlite/local-store.d.cts +8 -7
- package/dist/backend/sqlite/local-store.d.ts +8 -7
- package/dist/backend/sqlite/local-store.js +29 -30
- package/dist/backend/sqlite/local-store.js.map +1 -1
- package/dist/backend/sqlite/local.cjs +16 -16
- package/dist/backend/sqlite/local.d.cts +3 -2
- package/dist/backend/sqlite/local.d.ts +3 -2
- package/dist/backend/sqlite/local.js +14 -14
- package/dist/{chunk-2OOY4OYT.js → chunk-2L54C2C2.js} +4 -4
- package/dist/{chunk-2OOY4OYT.js.map → chunk-2L54C2C2.js.map} +1 -1
- package/dist/{chunk-4WYFRACU.js → chunk-42PYUGLS.js} +58 -4
- package/dist/chunk-42PYUGLS.js.map +1 -0
- package/dist/{chunk-EQOQOT55.js → chunk-4GUBTVPV.js} +4 -5
- package/dist/chunk-4GUBTVPV.js.map +1 -0
- package/dist/{chunk-ZIRC2U6G.js → chunk-4GUTQPVO.js} +102 -16
- package/dist/chunk-4GUTQPVO.js.map +1 -0
- package/dist/{chunk-OYJSYDIH.js → chunk-4MB3AQAQ.js} +13 -3
- package/dist/chunk-4MB3AQAQ.js.map +1 -0
- package/dist/{chunk-5Q3P6OIC.cjs → chunk-4MEWSUVM.cjs} +12 -12
- package/dist/chunk-4MEWSUVM.cjs.map +1 -0
- package/dist/{chunk-VC26BUNP.js → chunk-4QIKLIGG.js} +17 -5
- package/dist/chunk-4QIKLIGG.js.map +1 -0
- package/dist/chunk-4SZ6XPTG.cjs +12 -0
- package/dist/{chunk-VGMNGWBR.cjs.map → chunk-4SZ6XPTG.cjs.map} +1 -1
- package/dist/{chunk-UZLEQFTV.js → chunk-55ITBQJI.js} +4 -4
- package/dist/chunk-55ITBQJI.js.map +1 -0
- package/dist/{chunk-JOYPNY33.js → chunk-5EKPX6QU.js} +9 -9
- package/dist/{chunk-JOYPNY33.js.map → chunk-5EKPX6QU.js.map} +1 -1
- package/dist/{chunk-TRC646QQ.cjs → chunk-5GAONX5G.cjs} +7 -7
- package/dist/{chunk-TRC646QQ.cjs.map → chunk-5GAONX5G.cjs.map} +1 -1
- package/dist/{chunk-M4GYQF2H.js → chunk-6DCB664D.js} +7 -4
- package/dist/chunk-6DCB664D.js.map +1 -0
- package/dist/{chunk-64LERBFM.cjs → chunk-6RYPD3NJ.cjs} +75 -65
- package/dist/chunk-6RYPD3NJ.cjs.map +1 -0
- package/dist/{chunk-5AERZSHC.cjs → chunk-7PF2L3H6.cjs} +4 -4
- package/dist/{chunk-5AERZSHC.cjs.map → chunk-7PF2L3H6.cjs.map} +1 -1
- package/dist/chunk-B3F2D3SP.cjs +12 -0
- package/dist/{chunk-U3YRCZ5L.cjs.map → chunk-B3F2D3SP.cjs.map} +1 -1
- package/dist/{chunk-Z3WIL6S3.js → chunk-BGYJW37L.js} +5 -5
- package/dist/{chunk-Z3WIL6S3.js.map → chunk-BGYJW37L.js.map} +1 -1
- package/dist/{chunk-DMZEVJGL.cjs → chunk-BNS75YNF.cjs} +12 -13
- package/dist/chunk-BNS75YNF.cjs.map +1 -0
- package/dist/{chunk-KTBTSHU6.cjs → chunk-C4F7VJ5D.cjs} +13 -3
- package/dist/chunk-C4F7VJ5D.cjs.map +1 -0
- package/dist/{chunk-L2BYRYHC.js → chunk-CBKG6HEP.js} +43 -33
- package/dist/chunk-CBKG6HEP.js.map +1 -0
- package/dist/{chunk-CVK4T34X.cjs → chunk-CPEL3YIR.cjs} +22 -22
- package/dist/{chunk-CVK4T34X.cjs.map → chunk-CPEL3YIR.cjs.map} +1 -1
- package/dist/{chunk-O2GZM7UK.cjs → chunk-D54WH24V.cjs} +62 -7
- package/dist/chunk-D54WH24V.cjs.map +1 -0
- package/dist/{chunk-33PAKPED.cjs → chunk-D56XG4EI.cjs} +53 -41
- package/dist/chunk-D56XG4EI.cjs.map +1 -0
- package/dist/{chunk-O3USVVWS.js → chunk-DK2S42XB.js} +3 -3
- package/dist/{chunk-O3USVVWS.js.map → chunk-DK2S42XB.js.map} +1 -1
- package/dist/{chunk-HHBKGPEI.js → chunk-DXEEHSGN.js} +517 -26
- package/dist/chunk-DXEEHSGN.js.map +1 -0
- package/dist/{chunk-UJRWOV5B.js → chunk-EFEOOCJ3.js} +5 -5
- package/dist/{chunk-UJRWOV5B.js.map → chunk-EFEOOCJ3.js.map} +1 -1
- package/dist/{chunk-ECU53PMN.cjs → chunk-EKFUG4G7.cjs} +5 -5
- package/dist/chunk-EKFUG4G7.cjs.map +1 -0
- package/dist/{chunk-FSCJOTHF.cjs → chunk-EQ7JKLZO.cjs} +10 -10
- package/dist/{chunk-FSCJOTHF.cjs.map → chunk-EQ7JKLZO.cjs.map} +1 -1
- package/dist/{chunk-AQR6BHB3.cjs → chunk-F4NHQHEZ.cjs} +10 -10
- package/dist/{chunk-AQR6BHB3.cjs.map → chunk-F4NHQHEZ.cjs.map} +1 -1
- package/dist/{chunk-2G6ZEGYO.js → chunk-FL5UQRES.js} +4 -4
- package/dist/{chunk-2G6ZEGYO.js.map → chunk-FL5UQRES.js.map} +1 -1
- package/dist/{chunk-ZP2KPDNN.js → chunk-FLEQ2HBK.js} +3 -3
- package/dist/{chunk-ZP2KPDNN.js.map → chunk-FLEQ2HBK.js.map} +1 -1
- package/dist/{chunk-RAWG2FEU.js → chunk-FQ7ZPOTZ.js} +264 -18
- package/dist/chunk-FQ7ZPOTZ.js.map +1 -0
- package/dist/{chunk-O7XVCLXW.cjs → chunk-H7VE3FL4.cjs} +577 -82
- package/dist/chunk-H7VE3FL4.cjs.map +1 -0
- package/dist/{chunk-JNXZQBN3.js → chunk-ID4WXTKL.js} +1039 -482
- package/dist/chunk-ID4WXTKL.js.map +1 -0
- package/dist/{chunk-ZGOUVMVS.js → chunk-ISLPNELU.js} +17 -5
- package/dist/chunk-ISLPNELU.js.map +1 -0
- package/dist/{chunk-I73ATSAH.cjs → chunk-IX64T5OL.cjs} +4 -4
- package/dist/{chunk-I73ATSAH.cjs.map → chunk-IX64T5OL.cjs.map} +1 -1
- package/dist/{chunk-XDMPDUKL.cjs → chunk-J2ICGNHO.cjs} +8 -9
- package/dist/chunk-J2ICGNHO.cjs.map +1 -0
- package/dist/{chunk-KDRF3NR2.cjs → chunk-J7LXTUTP.cjs} +295 -201
- package/dist/chunk-J7LXTUTP.cjs.map +1 -0
- package/dist/{chunk-AO2WPYFZ.cjs → chunk-JQXSZHF2.cjs} +14 -4
- package/dist/chunk-JQXSZHF2.cjs.map +1 -0
- package/dist/{chunk-UTTW2Q3M.cjs → chunk-JXUTCSXX.cjs} +197 -133
- package/dist/chunk-JXUTCSXX.cjs.map +1 -0
- package/dist/{chunk-GT7NEXSU.js → chunk-KCO5EFJU.js} +3 -3
- package/dist/{chunk-GT7NEXSU.js.map → chunk-KCO5EFJU.js.map} +1 -1
- package/dist/{chunk-ARN3ZODS.cjs → chunk-KKYELPZ2.cjs} +6 -6
- package/dist/{chunk-ARN3ZODS.cjs.map → chunk-KKYELPZ2.cjs.map} +1 -1
- package/dist/{chunk-7Y6BV3TK.cjs → chunk-KMXWZLQX.cjs} +100 -100
- package/dist/{chunk-7Y6BV3TK.cjs.map → chunk-KMXWZLQX.cjs.map} +1 -1
- package/dist/{chunk-CDYRPI5U.js → chunk-MIJKEVV7.js} +4 -4
- package/dist/{chunk-CDYRPI5U.js.map → chunk-MIJKEVV7.js.map} +1 -1
- package/dist/{chunk-FFQGI67R.cjs → chunk-NAAMUYMS.cjs} +56 -44
- package/dist/chunk-NAAMUYMS.cjs.map +1 -0
- package/dist/{chunk-6TJ6PKPS.cjs → chunk-OOA273IJ.cjs} +27 -27
- package/dist/{chunk-6TJ6PKPS.cjs.map → chunk-OOA273IJ.cjs.map} +1 -1
- package/dist/{chunk-F2KVJ6FF.cjs → chunk-P7GTYOLB.cjs} +203 -117
- package/dist/chunk-P7GTYOLB.cjs.map +1 -0
- package/dist/{chunk-42XYPKZU.js → chunk-PVUI6KGR.js} +67 -3
- package/dist/chunk-PVUI6KGR.js.map +1 -0
- package/dist/{chunk-L5AUCL5P.js → chunk-Q6EDCUXV.js} +274 -14
- package/dist/chunk-Q6EDCUXV.js.map +1 -0
- package/dist/{chunk-ZPCKPLMX.cjs → chunk-QB6VMOJ2.cjs} +8 -8
- package/dist/{chunk-ZPCKPLMX.cjs.map → chunk-QB6VMOJ2.cjs.map} +1 -1
- package/dist/{chunk-3RPQDGUE.cjs → chunk-QC4MCOFV.cjs} +5 -5
- package/dist/{chunk-3RPQDGUE.cjs.map → chunk-QC4MCOFV.cjs.map} +1 -1
- package/dist/{chunk-4XRP2N6B.js → chunk-QLUXRWKL.js} +3 -3
- package/dist/{chunk-4XRP2N6B.js.map → chunk-QLUXRWKL.js.map} +1 -1
- package/dist/{chunk-OM6RIOA5.cjs → chunk-QR24DJDF.cjs} +13 -13
- package/dist/{chunk-OM6RIOA5.cjs.map → chunk-QR24DJDF.cjs.map} +1 -1
- package/dist/{chunk-YPVQYM3L.js → chunk-QRNYDV5Z.js} +138 -31
- package/dist/chunk-QRNYDV5Z.js.map +1 -0
- package/dist/{chunk-ZOHCFYXE.js → chunk-QT6V3YRH.js} +3 -3
- package/dist/{chunk-ZOHCFYXE.js.map → chunk-QT6V3YRH.js.map} +1 -1
- package/dist/{chunk-5C75HQYQ.js → chunk-RFRM3Q5K.js} +17 -5
- package/dist/chunk-RFRM3Q5K.js.map +1 -0
- package/dist/{chunk-NXIZL7ZZ.js → chunk-RUQS6M7G.js} +6 -6
- package/dist/chunk-RUQS6M7G.js.map +1 -0
- package/dist/{chunk-CI5NPLXX.js → chunk-S3ZRKJHY.js} +3 -3
- package/dist/{chunk-CI5NPLXX.js.map → chunk-S3ZRKJHY.js.map} +1 -1
- package/dist/{chunk-3V6D5DEC.js → chunk-S4KQ5LV4.js} +3 -3
- package/dist/{chunk-3V6D5DEC.js.map → chunk-S4KQ5LV4.js.map} +1 -1
- package/dist/{chunk-CTWZPYJW.js → chunk-TKORQCG4.js} +108 -15
- package/dist/chunk-TKORQCG4.js.map +1 -0
- package/dist/{chunk-2HKIID5K.js → chunk-TKP5T34P.js} +4 -5
- package/dist/chunk-TKP5T34P.js.map +1 -0
- package/dist/{chunk-X2XOQZT3.cjs → chunk-U5W4LKZV.cjs} +13 -9
- package/dist/chunk-U5W4LKZV.cjs.map +1 -0
- package/dist/{chunk-BLBG2VZ5.cjs → chunk-UCQ3BFSY.cjs} +372 -110
- package/dist/chunk-UCQ3BFSY.cjs.map +1 -0
- package/dist/{chunk-CUPJL6TS.js → chunk-V34A6R5V.js} +13 -4
- package/dist/chunk-V34A6R5V.js.map +1 -0
- package/dist/{chunk-LQLVJWUH.js → chunk-VTN3C3CH.js} +7 -7
- package/dist/chunk-VTN3C3CH.js.map +1 -0
- package/dist/{chunk-FY4VY5EV.cjs → chunk-VVQM4CZD.cjs} +20 -20
- package/dist/chunk-VVQM4CZD.cjs.map +1 -0
- package/dist/{chunk-LDCWO5B6.js → chunk-WDAVPX46.js} +3 -3
- package/dist/{chunk-LDCWO5B6.js.map → chunk-WDAVPX46.js.map} +1 -1
- package/dist/{chunk-5GV4JQNA.cjs → chunk-WDBXJOU5.cjs} +55 -43
- package/dist/chunk-WDBXJOU5.cjs.map +1 -0
- package/dist/{chunk-FMPZPOUD.js → chunk-WUFASQUO.js} +3 -3
- package/dist/{chunk-FMPZPOUD.js.map → chunk-WUFASQUO.js.map} +1 -1
- package/dist/{chunk-5ZPRE4CV.cjs → chunk-YDWLUT5V.cjs} +237 -130
- package/dist/chunk-YDWLUT5V.cjs.map +1 -0
- package/dist/{chunk-CVNGKTHO.js → chunk-YMTXMPV6.js} +4 -4
- package/dist/{chunk-CVNGKTHO.js.map → chunk-YMTXMPV6.js.map} +1 -1
- package/dist/{chunk-NDQLPKBX.cjs → chunk-YOALGKRE.cjs} +2092 -1535
- package/dist/chunk-YOALGKRE.cjs.map +1 -0
- package/dist/{chunk-OMQ2NBOR.cjs → chunk-Z3WO6MND.cjs} +27 -27
- package/dist/{chunk-OMQ2NBOR.cjs.map → chunk-Z3WO6MND.cjs.map} +1 -1
- package/dist/{chunk-V2GZBPY2.cjs → chunk-ZI6VQSZA.cjs} +310 -61
- package/dist/chunk-ZI6VQSZA.cjs.map +1 -0
- package/dist/{chunk-ZBV4LQD2.cjs → chunk-ZTAJL4DT.cjs} +4 -4
- package/dist/{chunk-ZBV4LQD2.cjs.map → chunk-ZTAJL4DT.cjs.map} +1 -1
- package/dist/core/index.cjs +27 -28
- package/dist/core/index.d.cts +5 -5
- package/dist/core/index.d.ts +5 -5
- package/dist/core/index.js +7 -8
- package/dist/{ddl-3unqC-kg.d.cts → ddl-BG4J805L.d.cts} +3 -3
- package/dist/{ddl-Bc4Dl8fu.d.ts → ddl-CgiS9QLj.d.ts} +3 -3
- package/dist/{define-graph-DBFnc7u_.d.ts → define-graph-BGrJahvp.d.ts} +1 -1
- package/dist/{define-graph-Byslw2OO.d.cts → define-graph-alREY2wj.d.cts} +1 -1
- package/dist/graph-extension/index.cjs +19 -20
- package/dist/graph-extension/index.d.cts +4 -4
- package/dist/graph-extension/index.d.ts +4 -4
- package/dist/graph-extension/index.js +4 -5
- package/dist/graph-merge/index.cjs +103 -104
- package/dist/graph-merge/index.cjs.map +1 -1
- package/dist/graph-merge/index.d.cts +9 -8
- package/dist/graph-merge/index.d.ts +9 -8
- package/dist/graph-merge/index.js +23 -24
- package/dist/graph-merge/index.js.map +1 -1
- package/dist/{index-DHXw7QAl.d.cts → index-BBxZCUdu.d.ts} +37 -7
- package/dist/{index-DQzVJBHa.d.ts → index-C3y_98iN.d.cts} +37 -7
- package/dist/index.cjs +209 -202
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +13 -13
- package/dist/index.d.ts +13 -13
- package/dist/index.js +33 -34
- package/dist/index.js.map +1 -1
- package/dist/indexes/index.cjs +13 -13
- package/dist/indexes/index.d.cts +4 -4
- package/dist/indexes/index.d.ts +4 -4
- package/dist/indexes/index.js +6 -6
- package/dist/interchange/index.cjs +50 -41
- package/dist/interchange/index.cjs.map +1 -1
- package/dist/interchange/index.d.cts +11 -11
- package/dist/interchange/index.d.ts +11 -11
- package/dist/interchange/index.js +24 -15
- package/dist/interchange/index.js.map +1 -1
- package/dist/{manager-U9_zopqr.d.cts → manager-KS7CGQQT.d.cts} +44 -6
- package/dist/{manager-Dl0-er1G.d.ts → manager-YoLEfcc1.d.ts} +44 -6
- package/dist/{materialize-indexes-BM3u0aXE.d.ts → materialize-indexes-Bhhyb1B3.d.ts} +1 -1
- package/dist/{materialize-indexes-DzMCetZe.d.cts → materialize-indexes-OHRWypW6.d.cts} +1 -1
- package/dist/{postgres-DpJqtbSX.d.cts → postgres-DpkW3R5Y.d.cts} +1 -1
- package/dist/{postgres-C5-WMKFA.d.ts → postgres-DwqyIniy.d.ts} +1 -1
- package/dist/profiler/index.d.cts +10 -9
- package/dist/profiler/index.d.ts +10 -9
- package/dist/provenance/index.cjs +38 -38
- package/dist/provenance/index.cjs.map +1 -1
- package/dist/provenance/index.d.cts +7 -7
- package/dist/provenance/index.d.ts +7 -7
- package/dist/provenance/index.js +8 -8
- package/dist/provenance/index.js.map +1 -1
- package/dist/schema/index.cjs +40 -41
- package/dist/schema/index.d.cts +7 -7
- package/dist/schema/index.d.ts +7 -7
- package/dist/schema/index.js +13 -14
- package/dist/{searchable-B4mUXZT6.d.cts → searchable-CIZL8Hyw.d.cts} +2 -2
- package/dist/{searchable-C7jmPNLT.d.ts → searchable-DLWEfC4a.d.ts} +2 -2
- package/dist/{sqlite-Ch5tSYQY.d.ts → sqlite-DY0WODUK.d.cts} +1 -1
- package/dist/{sqlite-Da7jiYu9.d.cts → sqlite-L-VIRzqA.d.ts} +1 -1
- package/dist/{store-view-DdwBNjZQ.d.ts → store-view-66p92IPi.d.ts} +1974 -1751
- package/dist/{store-view-D1F6KqsE.d.cts → store-view-A85FFRnk.d.cts} +1974 -1751
- package/dist/{temporal-CMpigMCW.d.cts → temporal-BNbjXqer.d.cts} +1 -1
- package/dist/{temporal-BtrTYTiB.d.ts → temporal-Bob6Nfbp.d.ts} +1 -1
- package/dist/{types-Dh-EgT-w.d.cts → types-Ch9a0Dx6.d.cts} +483 -20
- package/dist/{types-Dh-EgT-w.d.ts → types-Ch9a0Dx6.d.ts} +483 -20
- package/dist/{types-D2rU5Taq.d.ts → types-ClCzT-dT.d.ts} +1 -1
- package/dist/{types-G4sVM-76.d.cts → types-DeORZhxn.d.cts} +1 -1
- package/dist/{where-DbZ9XDOI.d.cts → where-DPw52ksb.d.cts} +1 -1
- package/dist/{where-B8Y21kig.d.ts → where-kWUZPvEA.d.ts} +1 -1
- package/package.json +1 -1
- package/dist/chunk-2HKIID5K.js.map +0 -1
- package/dist/chunk-33PAKPED.cjs.map +0 -1
- package/dist/chunk-42XYPKZU.js.map +0 -1
- package/dist/chunk-4WYFRACU.js.map +0 -1
- package/dist/chunk-5C75HQYQ.js.map +0 -1
- package/dist/chunk-5GV4JQNA.cjs.map +0 -1
- package/dist/chunk-5Q3P6OIC.cjs.map +0 -1
- package/dist/chunk-5ZPRE4CV.cjs.map +0 -1
- package/dist/chunk-64LERBFM.cjs.map +0 -1
- package/dist/chunk-AO2WPYFZ.cjs.map +0 -1
- package/dist/chunk-BLBG2VZ5.cjs.map +0 -1
- package/dist/chunk-CTWZPYJW.js.map +0 -1
- package/dist/chunk-CUPJL6TS.js.map +0 -1
- package/dist/chunk-DMZEVJGL.cjs.map +0 -1
- package/dist/chunk-ECU53PMN.cjs.map +0 -1
- package/dist/chunk-EQOQOT55.js.map +0 -1
- package/dist/chunk-F2KVJ6FF.cjs.map +0 -1
- package/dist/chunk-F7TDKSVB.cjs +0 -61
- package/dist/chunk-F7TDKSVB.cjs.map +0 -1
- package/dist/chunk-FFQGI67R.cjs.map +0 -1
- package/dist/chunk-FY4VY5EV.cjs.map +0 -1
- package/dist/chunk-HHBKGPEI.js.map +0 -1
- package/dist/chunk-JNXZQBN3.js.map +0 -1
- package/dist/chunk-KDRF3NR2.cjs.map +0 -1
- package/dist/chunk-KTBTSHU6.cjs.map +0 -1
- package/dist/chunk-L2BYRYHC.js.map +0 -1
- package/dist/chunk-L5AUCL5P.js.map +0 -1
- package/dist/chunk-LQLVJWUH.js.map +0 -1
- package/dist/chunk-M4GYQF2H.js.map +0 -1
- package/dist/chunk-NDQLPKBX.cjs.map +0 -1
- package/dist/chunk-NXIZL7ZZ.js.map +0 -1
- package/dist/chunk-O2GZM7UK.cjs.map +0 -1
- package/dist/chunk-O7XVCLXW.cjs.map +0 -1
- package/dist/chunk-OYJSYDIH.js.map +0 -1
- package/dist/chunk-RAWG2FEU.js.map +0 -1
- package/dist/chunk-RXOAXO3R.js +0 -59
- package/dist/chunk-RXOAXO3R.js.map +0 -1
- package/dist/chunk-U3YRCZ5L.cjs +0 -12
- package/dist/chunk-UTTW2Q3M.cjs.map +0 -1
- package/dist/chunk-UZLEQFTV.js.map +0 -1
- package/dist/chunk-V2GZBPY2.cjs.map +0 -1
- package/dist/chunk-VC26BUNP.js.map +0 -1
- package/dist/chunk-VGMNGWBR.cjs +0 -12
- package/dist/chunk-X2XOQZT3.cjs.map +0 -1
- package/dist/chunk-XDMPDUKL.cjs.map +0 -1
- package/dist/chunk-YPVQYM3L.js.map +0 -1
- package/dist/chunk-ZGOUVMVS.js.map +0 -1
- package/dist/chunk-ZIRC2U6G.js.map +0 -1
|
@@ -1,31 +1,31 @@
|
|
|
1
|
-
import { createEdgeRowMapper, createNodeRowMapper, SQLITE_ROW_MAPPER_CONFIG, POSTGRES_ROW_MAPPER_CONFIG } from './chunk-
|
|
2
|
-
import { rowToNode, executeNodeBulkFindByIndex, executeNodeBulkFindByConstraint, executeNodeFindByConstraint, executeNodeBulkGetOrCreateByConstraint, executeNodeGetOrCreateByConstraint, executeNodeHardDelete, executeNodeDelete, nodeUpsertDirtyCheck, executeNodeUpsertUpdate, executeNodeUpdate, executeNodeCreateNoReturnBatch, executeNodeCreateBatch, executeNodeCreate, rowToEdge, runInWriteTransaction, checkCardinalityConstraint, runHookedWriteOperation, rowToNodeMeta, rowToEdgeMeta } from './chunk-
|
|
3
|
-
import { isParameterRef, fieldRef, buildFieldBuilderForTypeInfo, stringField, createFulltextAccessor, storeRuntime, CURRENT_READ_INSTANT_PLACEHOLDER, withPinnedReadInstant, STORE_RUNTIME, assertRevisionTrackableBackend, createRecordedBackend, readRecordedClock, ensureRevisionOrigin, TRANSACTION_RUNTIME, withRecordedFlushObserver, recordedCaptureRequiresCallbackTransactionError, assertRecordedCaptureTransactionIsolation, createRecordedTransactionScope, lockRecordedGraphWrite,
|
|
4
|
-
import { chunk } from './chunk-35S6P5ZU.js';
|
|
5
|
-
import { DEFAULT_SQL_SCHEMA, requireSqlSchema, recordedReadSchemaFor, createSqlSchema, requireExternalRecordedReadSource, createRecordedReadBinding, vectorSlotKey, recordedReadSqlSchema, requireRecordedReadBinding, ALIAS_CTE_PREFIX, EMBEDDINGS_CTE_ALIAS, FULLTEXT_CTE_ALIAS, HYBRID_CANDIDATES_CTE_ALIAS } from './chunk-
|
|
6
|
-
import { runOptionallyInTransaction, createTransactionReadBackend, rowPropsToObject, createBackendOverlay, INTERNAL_TEMPORARY_WRITES } from './chunk-
|
|
7
|
-
import { resolveReadCoordinate, withRecordedCoordinate, describeCoordinate, coordinateContext, recordedInstantWallTime, asRecordedInstant, assertValidRecordedInstant } from './chunk-
|
|
8
|
-
import { loadAndMergeGraphExtensionDocument, ensureSchema, loadAndVerifyGraph, buildKindRegistry, getSchemaChanges, requiresMigration, mergeGraphExtension, commitNewSchemaVersion, applyDeprecatedKinds, loadActiveSchemaWithBootstrap, parseSerializedSchema, extensionKindNames, serializeSchemaProperties, buildGraphExtensionOntologyKeySet, compileTimeOntologyKey, serializeIndexDeclaration } from './chunk-
|
|
1
|
+
import { createEdgeRowMapper, createNodeRowMapper, SQLITE_ROW_MAPPER_CONFIG, POSTGRES_ROW_MAPPER_CONFIG } from './chunk-YMTXMPV6.js';
|
|
2
|
+
import { rowToNode, executeNodeBulkFindByIndex, executeNodeBulkFindByConstraint, executeNodeFindByConstraint, executeNodeBulkGetOrCreateByConstraint, executeNodeGetOrCreateByConstraint, executeNodeHardDelete, executeNodeDelete, nodeUpsertDirtyCheck, executeNodeUpsertUpdate, executeNodeUpdateWhere, executeNodeUpdate, executeNodeCreateNoReturnBatch, executeNodeCreateBatch, executeNodeCreate, rowToEdge, lockSchemaVersionForStoreWrite, runInWriteTransaction, checkCardinalityConstraint, runHookedWriteOperation, rowToNodeMeta, rowToEdgeMeta } from './chunk-Q6EDCUXV.js';
|
|
3
|
+
import { isParameterRef, resolveParameterValueType, fieldRef, buildFieldBuilderForTypeInfo, stringField, createFulltextAccessor, storeRuntime, CURRENT_READ_INSTANT_PLACEHOLDER, withPinnedReadInstant, STORE_RUNTIME, assertRevisionTrackableBackend, createRecordedBackend, readRecordedClock, ensureRevisionOrigin, TRANSACTION_RUNTIME, withRecordedFlushObserver, recordedCaptureRequiresCallbackTransactionError, assertRecordedCaptureTransactionIsolation, createRecordedTransactionScope, lockRecordedGraphWrite, createGraphBackendProjection, generateId, assertCurrentRecordedSchema, baseField, objectField, arrayField, dateField, numberField, computeFulltextContent, AUTO_REFRESH_STATISTICS_ROW_THRESHOLD, advanceRevisionClock, runInsertBatch, edgeInsertDispatch, runInsertBatchReturning, projectBackendMembers, sqlValueList, getEmbeddingFields, getNodeRowsByIds, getEdgeRowsByIds, compileKindFilter, currentReadInstant, compileTemporalFilter, validateEdgeEndpoints, closeRecordedHardDeletedKind, buildPredicateIndex, compileFieldValue, recordedBindParamBudget, extractVectorSimilarityPredicates, extractFulltextMatchPredicates, currentReadInstantFor, extractTemporalOptions, compilePredicateExpression, getPredicatesForAlias, getFieldPointer, getNodeKindsForAlias, getHybridTargetAlias, throwHistoryUnsafeSqlAccess, throwRevisionTrackingUnsafeSqlAccess, compilePredicateClauses } from './chunk-TKORQCG4.js';
|
|
4
|
+
import { chunk, groupBy } from './chunk-35S6P5ZU.js';
|
|
5
|
+
import { DEFAULT_SQL_SCHEMA, requireSqlSchema, recordedReadSchemaFor, createSqlSchema, requireExternalRecordedReadSource, createRecordedReadBinding, vectorSlotKey, recordedReadSqlSchema, requireRecordedReadBinding, ALIAS_CTE_PREFIX, EMBEDDINGS_CTE_ALIAS, FULLTEXT_CTE_ALIAS, HYBRID_CANDIDATES_CTE_ALIAS } from './chunk-MIJKEVV7.js';
|
|
6
|
+
import { runOptionallyInTransaction, createTransactionReadBackend, rowPropsToObject, createBackendOverlay, INTERNAL_TEMPORARY_WRITES } from './chunk-55ITBQJI.js';
|
|
7
|
+
import { resolveReadCoordinate, withRecordedCoordinate, describeCoordinate, coordinateContext, recordedInstantWallTime, asRecordedInstant, assertValidRecordedInstant } from './chunk-2L54C2C2.js';
|
|
8
|
+
import { loadAndMergeGraphExtensionDocument, ensureSchema, loadAndVerifyGraph, buildKindRegistry, getSchemaChanges, requiresMigration, mergeGraphExtension, commitNewSchemaVersion, planRemovals, stripGraphExtension, applyDeprecatedKinds, loadActiveSchemaWithBootstrap, parseSerializedSchema, extensionKindNames, serializeSchemaProperties, buildGraphExtensionOntologyKeySet, compileTimeOntologyKey, commitNewSchemaVersionIfKindsEmpty, serializeIndexDeclaration } from './chunk-FQ7ZPOTZ.js';
|
|
9
9
|
import { compareStrings, compareCodePoints } from './chunk-DRACN6XG.js';
|
|
10
|
-
import { getTypeName } from './chunk-
|
|
11
|
-
import { validateEdgeProps } from './chunk-
|
|
10
|
+
import { getTypeName } from './chunk-TKP5T34P.js';
|
|
11
|
+
import { validateEdgeProps } from './chunk-DK2S42XB.js';
|
|
12
12
|
import { canonicalEqual, sortedReplacer } from './chunk-UR7W5YQK.js';
|
|
13
|
-
import { withRecordedRelationsPrecondition, isMissingTableError } from './chunk-
|
|
14
|
-
import { isKnownKind } from './chunk-
|
|
15
|
-
import { nowIso, validateOptionalCanonicalIsoDate } from './chunk-
|
|
16
|
-
import { generateIndexDDL } from './chunk-
|
|
17
|
-
import { SYSTEM_INDEX_DECLARATIONS, resolveSystemIndexTableName, systemIndexName, resolveSystemIndexNames, generateSystemIndexDDL } from './chunk-
|
|
18
|
-
import { NODE_META_KEYS, EDGE_META_KEYS } from './chunk-
|
|
13
|
+
import { withRecordedRelationsPrecondition, isMissingTableError } from './chunk-V34A6R5V.js';
|
|
14
|
+
import { isKnownKind } from './chunk-S4KQ5LV4.js';
|
|
15
|
+
import { nowIso, validateOptionalCanonicalIsoDate } from './chunk-KCO5EFJU.js';
|
|
16
|
+
import { generateIndexDDL } from './chunk-FL5UQRES.js';
|
|
17
|
+
import { SYSTEM_INDEX_DECLARATIONS, resolveSystemIndexTableName, systemIndexName, resolveSystemIndexNames, generateSystemIndexDDL } from './chunk-QLUXRWKL.js';
|
|
18
|
+
import { NODE_META_KEYS, EDGE_META_KEYS } from './chunk-FLEQ2HBK.js';
|
|
19
19
|
import { sha256Hex, fnv1aBase36 } from './chunk-K34OPSJK.js';
|
|
20
20
|
import { DEFAULT_PAGINATION_LIMIT, DEFAULT_STREAM_BATCH_SIZE, SQLITE_PATH_DELIMITER, PG_ARRAY_START, PG_ARRAY_END, PG_PATH_ELEMENT_SEPARATOR, MAX_PG_IDENTIFIER_LENGTH } from './chunk-2EBMPJBO.js';
|
|
21
|
-
import { getDialect, assertVectorMinScore, vectorScoreExpression, vectorMinScoreCondition } from './chunk-
|
|
22
|
-
import { isSqlPlaceholder, bindSqlValue, markAnnIndexScan, asCompiledSelectSql, isRawExecutable, annIndexScanTypes, sql, asCompiledRowsSql, markForceCustomPlan, asCompiledTemporaryStatementSql, asCompiledStatementSql } from './chunk-
|
|
21
|
+
import { getDialect, assertVectorMinScore, vectorScoreExpression, vectorMinScoreCondition } from './chunk-PVUI6KGR.js';
|
|
22
|
+
import { isSqlPlaceholder, bindSqlValue, markAnnIndexScan, asCompiledSelectSql, isRawExecutable, renderSql, annIndexScanTypes, sql, asCompiledRowsSql, markForceCustomPlan, asCompiledTemporaryStatementSql, asCompiledStatementSql } from './chunk-6DCB664D.js';
|
|
23
23
|
import { createSchemaIntrospector } from './chunk-D7PG5D5K.js';
|
|
24
24
|
import { requireDefined, isPresent } from './chunk-QMQLUA66.js';
|
|
25
25
|
import { getSearchableFields, resolveEmbeddingFields, resolveGraphVectorSlots, resolveDeclaredFulltextLanguage } from './chunk-PC2UBAUB.js';
|
|
26
|
-
import { IncompatibleChangeError
|
|
27
|
-
import { validateProjectionField } from './chunk-
|
|
28
|
-
import { ConfigurationError, UnsupportedPredicateError, ValidationError, KindNotFoundError, EndpointError, EagerMaterializationError, CompilerInvariantError, CardinalityError, EdgeNotFoundError, DatabaseOperationError, UnsupportedBackendCapabilityError, GraphAlgorithmConvergenceError, EndpointNotFoundError, InvalidEdgeWeightError } from './chunk-
|
|
26
|
+
import { IncompatibleChangeError } from './chunk-4GUBTVPV.js';
|
|
27
|
+
import { validateProjectionField } from './chunk-42PYUGLS.js';
|
|
28
|
+
import { ConfigurationError, UnsupportedPredicateError, ValidationError, KindNotFoundError, EndpointError, EagerMaterializationError, CompilerInvariantError, CardinalityError, EdgeNotFoundError, DatabaseOperationError, UnsupportedBackendCapabilityError, GraphAlgorithmConvergenceError, EndpointNotFoundError, InvalidEdgeWeightError } from './chunk-4MB3AQAQ.js';
|
|
29
29
|
import { jsonPointer, parseJsonPointer, resolveJsonPointer } from './chunk-G6Q5UM7U.js';
|
|
30
30
|
|
|
31
31
|
// src/store/collection-surface.ts
|
|
@@ -38,6 +38,7 @@ var NODE_WRITE_NAMES = [
|
|
|
38
38
|
"create",
|
|
39
39
|
"createFromRecord",
|
|
40
40
|
"update",
|
|
41
|
+
"updateWhere",
|
|
41
42
|
"delete",
|
|
42
43
|
"hardDelete",
|
|
43
44
|
"upsertById",
|
|
@@ -170,7 +171,7 @@ function createCurrentOnlyRefusal(entity, method, coordinate) {
|
|
|
170
171
|
function createBatchReadRefusal(entity, method, coordinate) {
|
|
171
172
|
return () => {
|
|
172
173
|
throw new ConfigurationError(
|
|
173
|
-
`'${method}' is not available on a read-only StoreView (${describeCoordinate(coordinate)}). Batch endpoint reads resolve through store.batch(...), which a view does not expose \u2014 use the live Store's batch
|
|
174
|
+
`'${method}' is not available on a read-only StoreView (${describeCoordinate(coordinate)}). Batch endpoint reads resolve through store.batch(...), which a view does not expose \u2014 use the live Store's batch(...), or the view's findFrom / findTo / findByEndpoints for single reads.`,
|
|
174
175
|
{
|
|
175
176
|
code: "STORE_VIEW_BATCH_UNAVAILABLE",
|
|
176
177
|
entity,
|
|
@@ -264,6 +265,8 @@ function pinnedEdgeCollection(live, coordinate) {
|
|
|
264
265
|
count: (filter) => live.count(filter, temporal),
|
|
265
266
|
findFrom: (from) => live.findFrom(from, temporal),
|
|
266
267
|
findTo: (to) => live.findTo(to, temporal),
|
|
268
|
+
bulkFindFrom: (froms, options) => live.bulkFindFrom(froms, { ...options, ...temporal }),
|
|
269
|
+
bulkFindTo: (tos, options) => live.bulkFindTo(tos, { ...options, ...temporal }),
|
|
267
270
|
findByEndpoints: (from, to, options) => live.findByEndpoints(from, to, options, temporal)
|
|
268
271
|
};
|
|
269
272
|
return readOnlyCollectionProxy(reads, live, coordinate, "edge");
|
|
@@ -568,6 +571,13 @@ var StoreView = class extends CoordinatePinnedView {
|
|
|
568
571
|
);
|
|
569
572
|
return this.#edges;
|
|
570
573
|
}
|
|
574
|
+
/** Heterogeneous multi-kind edge read pinned to this view's coordinate. */
|
|
575
|
+
bulkFindEdgesFrom(params, options) {
|
|
576
|
+
return this.store.bulkFindEdgesFrom(params, {
|
|
577
|
+
...options,
|
|
578
|
+
...withValidCoordinate(this.coordinate)
|
|
579
|
+
});
|
|
580
|
+
}
|
|
571
581
|
/**
|
|
572
582
|
* Read-only search facade. On a `current` view the read methods
|
|
573
583
|
* (`fulltext` / `vector` / `hybrid`) delegate to the live `store.search`,
|
|
@@ -4910,7 +4920,7 @@ function compileStandardQueryWithCteStrategy(ast, graphId, ctx) {
|
|
|
4910
4920
|
...vectorPredicate === void 0 ? {} : { vectorPredicate },
|
|
4911
4921
|
...fulltextPredicate === void 0 ? {} : { fulltextPredicate }
|
|
4912
4922
|
});
|
|
4913
|
-
const
|
|
4923
|
+
const groupBy2 = buildStandardGroupBy({ ast, dialect });
|
|
4914
4924
|
const having2 = buildStandardHaving({ ast, ctx });
|
|
4915
4925
|
const orderBy = selectStandardOrderBy({
|
|
4916
4926
|
ast,
|
|
@@ -4927,7 +4937,7 @@ function compileStandardQueryWithCteStrategy(ast, graphId, ctx) {
|
|
|
4927
4937
|
return emitStandardQuerySql({
|
|
4928
4938
|
ctes,
|
|
4929
4939
|
fromClause,
|
|
4930
|
-
...
|
|
4940
|
+
...groupBy2 === void 0 ? {} : { groupBy: groupBy2 },
|
|
4931
4941
|
...having2 === void 0 ? {} : { having: having2 },
|
|
4932
4942
|
...orderBy === void 0 ? {} : { orderBy },
|
|
4933
4943
|
...limitOffset === void 0 ? {} : { limitOffset },
|
|
@@ -5859,7 +5869,8 @@ function buildQueryTemplate(ast, graphId, compileOptions, backend) {
|
|
|
5859
5869
|
needsReadInstant: queryAstNeedsCurrentReadInstant(ast)
|
|
5860
5870
|
});
|
|
5861
5871
|
}
|
|
5862
|
-
|
|
5872
|
+
var EMPTY_LIST_PARAMETERS = /* @__PURE__ */ new Map();
|
|
5873
|
+
function fillTemplateParams(params, bindings, dialect, listParameters = EMPTY_LIST_PARAMETERS) {
|
|
5863
5874
|
let readInstant;
|
|
5864
5875
|
return params.map((parameter) => {
|
|
5865
5876
|
if (!isSqlPlaceholder(parameter)) return parameter;
|
|
@@ -5874,9 +5885,20 @@ function fillTemplateParams(params, bindings, dialect) {
|
|
|
5874
5885
|
parameterName: name
|
|
5875
5886
|
});
|
|
5876
5887
|
}
|
|
5888
|
+
if (listParameters.has(name)) {
|
|
5889
|
+
assertListBinding(name, value);
|
|
5890
|
+
return getDialect(dialect).packListValue(value);
|
|
5891
|
+
}
|
|
5877
5892
|
return bindSqlValue(value, dialect);
|
|
5878
5893
|
});
|
|
5879
5894
|
}
|
|
5895
|
+
function assertListBinding(name, value) {
|
|
5896
|
+
if (Array.isArray(value)) return;
|
|
5897
|
+
throw new ConfigurationError(
|
|
5898
|
+
`Parameter "${name}" must be an array for in()/notIn()`,
|
|
5899
|
+
{ parameterName: name, actualType: typeof value }
|
|
5900
|
+
);
|
|
5901
|
+
}
|
|
5880
5902
|
|
|
5881
5903
|
// src/query/builder/prepared-query.ts
|
|
5882
5904
|
function toLiteral(value) {
|
|
@@ -5903,20 +5925,21 @@ function toLiteral(value) {
|
|
|
5903
5925
|
{ parameterName: "value", actualType: typeof value }
|
|
5904
5926
|
);
|
|
5905
5927
|
}
|
|
5928
|
+
function isListComparisonOp(op) {
|
|
5929
|
+
return op === "in" || op === "notIn";
|
|
5930
|
+
}
|
|
5931
|
+
function toLiteralList(parameterName, value) {
|
|
5932
|
+
assertListBinding(parameterName, value);
|
|
5933
|
+
return value.map((element) => toLiteral(element));
|
|
5934
|
+
}
|
|
5906
5935
|
function substitutePredicateExpression(expr, bindings) {
|
|
5907
5936
|
switch (expr.__type) {
|
|
5908
5937
|
case "comparison": {
|
|
5909
5938
|
if (isParameterRef(expr.right)) {
|
|
5910
|
-
const value = bindings
|
|
5911
|
-
if (value === void 0) {
|
|
5912
|
-
throw new ConfigurationError(
|
|
5913
|
-
`Missing binding for parameter "${expr.right.name}"`,
|
|
5914
|
-
{ parameterName: expr.right.name }
|
|
5915
|
-
);
|
|
5916
|
-
}
|
|
5939
|
+
const value = resolveBinding(bindings, expr.right.name);
|
|
5917
5940
|
return {
|
|
5918
5941
|
...expr,
|
|
5919
|
-
right: toLiteral(value)
|
|
5942
|
+
right: isListComparisonOp(expr.op) ? toLiteralList(expr.right.name, value) : toLiteral(value)
|
|
5920
5943
|
};
|
|
5921
5944
|
}
|
|
5922
5945
|
return expr;
|
|
@@ -6029,6 +6052,7 @@ var PreparedQuery = class {
|
|
|
6029
6052
|
#selectFn;
|
|
6030
6053
|
#schemaIntrospector;
|
|
6031
6054
|
#parameterMetadata;
|
|
6055
|
+
#selectiveExecutionDisabled = false;
|
|
6032
6056
|
/**
|
|
6033
6057
|
* Per-AST cached placeholder template, keyed by AST reference so the
|
|
6034
6058
|
* optimized (`#ast`) and unoptimized (`#unoptimizedAst`) variants cache
|
|
@@ -6049,6 +6073,7 @@ var PreparedQuery = class {
|
|
|
6049
6073
|
this.#selectFn = config.selectFn;
|
|
6050
6074
|
this.#schemaIntrospector = config.schemaIntrospector;
|
|
6051
6075
|
this.#parameterMetadata = collectParameterMetadata(this.#ast);
|
|
6076
|
+
assertDistinctParameterRoles(this.#parameterMetadata);
|
|
6052
6077
|
}
|
|
6053
6078
|
/**
|
|
6054
6079
|
* The cached placeholder template for `ast`, or `undefined` when no fast
|
|
@@ -6082,7 +6107,7 @@ var PreparedQuery = class {
|
|
|
6082
6107
|
*/
|
|
6083
6108
|
async execute(bindings = {}) {
|
|
6084
6109
|
validateBindings(bindings, this.#parameterMetadata);
|
|
6085
|
-
if (this.#selectiveFields !== void 0) {
|
|
6110
|
+
if (this.#selectiveFields !== void 0 && !this.#selectiveExecutionDisabled) {
|
|
6086
6111
|
try {
|
|
6087
6112
|
const rows = await this.#executeSelectiveRows(bindings);
|
|
6088
6113
|
return mapSelectiveResults(
|
|
@@ -6093,7 +6118,11 @@ var PreparedQuery = class {
|
|
|
6093
6118
|
this.#selectFn
|
|
6094
6119
|
);
|
|
6095
6120
|
} catch (error) {
|
|
6096
|
-
if (error instanceof MissingSelectiveFieldError
|
|
6121
|
+
if (error instanceof MissingSelectiveFieldError) {
|
|
6122
|
+
this.#selectiveExecutionDisabled = true;
|
|
6123
|
+
return this.#executeUnoptimized(bindings);
|
|
6124
|
+
}
|
|
6125
|
+
if (error instanceof UnsupportedPredicateError) {
|
|
6097
6126
|
return this.#executeUnoptimized(bindings);
|
|
6098
6127
|
}
|
|
6099
6128
|
throw error;
|
|
@@ -6128,7 +6157,8 @@ var PreparedQuery = class {
|
|
|
6128
6157
|
const params = fillTemplateParams(
|
|
6129
6158
|
template.params,
|
|
6130
6159
|
bindings,
|
|
6131
|
-
this.#dialect
|
|
6160
|
+
this.#dialect,
|
|
6161
|
+
this.#parameterMetadata.listParameters
|
|
6132
6162
|
);
|
|
6133
6163
|
const rawRows2 = await executeRaw(
|
|
6134
6164
|
template.sql,
|
|
@@ -6147,10 +6177,46 @@ var PreparedQuery = class {
|
|
|
6147
6177
|
}
|
|
6148
6178
|
};
|
|
6149
6179
|
function collectParameterMetadata(ast) {
|
|
6150
|
-
const
|
|
6151
|
-
|
|
6152
|
-
|
|
6153
|
-
|
|
6180
|
+
const accumulator = {
|
|
6181
|
+
names: /* @__PURE__ */ new Set(),
|
|
6182
|
+
stringOpParameters: /* @__PURE__ */ new Set(),
|
|
6183
|
+
listParameters: /* @__PURE__ */ new Map(),
|
|
6184
|
+
scalarParameters: /* @__PURE__ */ new Set(),
|
|
6185
|
+
conflictingElementTypes: /* @__PURE__ */ new Set()
|
|
6186
|
+
};
|
|
6187
|
+
collectParameterMetadataFromAst(ast, accumulator);
|
|
6188
|
+
return accumulator;
|
|
6189
|
+
}
|
|
6190
|
+
function assertDistinctParameterRoles(metadata) {
|
|
6191
|
+
if (metadata.conflictingElementTypes.size > 0) {
|
|
6192
|
+
const names = [...metadata.conflictingElementTypes];
|
|
6193
|
+
throw new ConfigurationError(
|
|
6194
|
+
`Parameter${names.length === 1 ? "" : "s"} ${names.map((name) => `"${name}"`).join(", ")} bound as an in()/notIn() list against fields of different types; one list cannot satisfy both`,
|
|
6195
|
+
{ conflictingParameters: names }
|
|
6196
|
+
);
|
|
6197
|
+
}
|
|
6198
|
+
const conflicting = [...metadata.listParameters.keys()].filter(
|
|
6199
|
+
(name) => metadata.scalarParameters.has(name)
|
|
6200
|
+
);
|
|
6201
|
+
if (conflicting.length === 0) return;
|
|
6202
|
+
throw new ConfigurationError(
|
|
6203
|
+
`Parameter${conflicting.length === 1 ? "" : "s"} ${conflicting.map((name) => `"${name}"`).join(", ")} used both as an in()/notIn() list and as a scalar value`,
|
|
6204
|
+
{ conflictingParameters: conflicting }
|
|
6205
|
+
);
|
|
6206
|
+
}
|
|
6207
|
+
function recordListElementType(accumulator, name, elementType) {
|
|
6208
|
+
if (!accumulator.listParameters.has(name)) {
|
|
6209
|
+
accumulator.listParameters.set(name, elementType);
|
|
6210
|
+
return;
|
|
6211
|
+
}
|
|
6212
|
+
const existing = accumulator.listParameters.get(name);
|
|
6213
|
+
if (existing === void 0) {
|
|
6214
|
+
accumulator.listParameters.set(name, elementType);
|
|
6215
|
+
return;
|
|
6216
|
+
}
|
|
6217
|
+
if (elementType !== void 0 && elementType !== existing) {
|
|
6218
|
+
accumulator.conflictingElementTypes.add(name);
|
|
6219
|
+
}
|
|
6154
6220
|
}
|
|
6155
6221
|
function hasParameterReferences(ast) {
|
|
6156
6222
|
return collectParameterMetadata(ast).names.size > 0;
|
|
@@ -6161,63 +6227,58 @@ function composableQueryHasParameterReferences(query) {
|
|
|
6161
6227
|
}
|
|
6162
6228
|
return hasParameterReferences(query);
|
|
6163
6229
|
}
|
|
6164
|
-
function collectParameterMetadataFromAst(ast,
|
|
6230
|
+
function collectParameterMetadataFromAst(ast, accumulator) {
|
|
6165
6231
|
for (const predicate of ast.predicates) {
|
|
6166
|
-
collectParameterMetadataFromExpression(
|
|
6167
|
-
predicate.expression,
|
|
6168
|
-
names,
|
|
6169
|
-
stringOpParameters
|
|
6170
|
-
);
|
|
6232
|
+
collectParameterMetadataFromExpression(predicate.expression, accumulator);
|
|
6171
6233
|
}
|
|
6172
6234
|
if (ast.having !== void 0) {
|
|
6173
|
-
collectParameterMetadataFromExpression(
|
|
6174
|
-
ast.having,
|
|
6175
|
-
names,
|
|
6176
|
-
stringOpParameters
|
|
6177
|
-
);
|
|
6235
|
+
collectParameterMetadataFromExpression(ast.having, accumulator);
|
|
6178
6236
|
}
|
|
6179
6237
|
}
|
|
6180
|
-
function collectParameterMetadataFromExpression(expression,
|
|
6238
|
+
function collectParameterMetadataFromExpression(expression, accumulator) {
|
|
6181
6239
|
switch (expression.__type) {
|
|
6182
6240
|
case "comparison": {
|
|
6183
6241
|
if (isParameterRef(expression.right)) {
|
|
6184
|
-
|
|
6242
|
+
const name = expression.right.name;
|
|
6243
|
+
accumulator.names.add(name);
|
|
6244
|
+
if (isListComparisonOp(expression.op)) {
|
|
6245
|
+
recordListElementType(
|
|
6246
|
+
accumulator,
|
|
6247
|
+
name,
|
|
6248
|
+
resolveParameterValueType(expression.left, expression.right)
|
|
6249
|
+
);
|
|
6250
|
+
} else {
|
|
6251
|
+
accumulator.scalarParameters.add(name);
|
|
6252
|
+
}
|
|
6185
6253
|
}
|
|
6186
6254
|
return;
|
|
6187
6255
|
}
|
|
6188
6256
|
case "string_op": {
|
|
6189
6257
|
if (isParameterRef(expression.pattern)) {
|
|
6190
|
-
names.add(expression.pattern.name);
|
|
6191
|
-
|
|
6258
|
+
accumulator.names.add(expression.pattern.name);
|
|
6259
|
+
accumulator.scalarParameters.add(expression.pattern.name);
|
|
6260
|
+
accumulator.stringOpParameters.add(expression.pattern.name);
|
|
6192
6261
|
}
|
|
6193
6262
|
return;
|
|
6194
6263
|
}
|
|
6195
6264
|
case "between": {
|
|
6196
|
-
|
|
6197
|
-
|
|
6198
|
-
|
|
6199
|
-
|
|
6200
|
-
|
|
6265
|
+
for (const bound of [expression.lower, expression.upper]) {
|
|
6266
|
+
if (isParameterRef(bound)) {
|
|
6267
|
+
accumulator.names.add(bound.name);
|
|
6268
|
+
accumulator.scalarParameters.add(bound.name);
|
|
6269
|
+
}
|
|
6201
6270
|
}
|
|
6202
6271
|
return;
|
|
6203
6272
|
}
|
|
6204
6273
|
case "and":
|
|
6205
6274
|
case "or": {
|
|
6206
6275
|
for (const predicate of expression.predicates) {
|
|
6207
|
-
collectParameterMetadataFromExpression(
|
|
6208
|
-
predicate,
|
|
6209
|
-
names,
|
|
6210
|
-
stringOpParameters
|
|
6211
|
-
);
|
|
6276
|
+
collectParameterMetadataFromExpression(predicate, accumulator);
|
|
6212
6277
|
}
|
|
6213
6278
|
return;
|
|
6214
6279
|
}
|
|
6215
6280
|
case "not": {
|
|
6216
|
-
collectParameterMetadataFromExpression(
|
|
6217
|
-
expression.predicate,
|
|
6218
|
-
names,
|
|
6219
|
-
stringOpParameters
|
|
6220
|
-
);
|
|
6281
|
+
collectParameterMetadataFromExpression(expression.predicate, accumulator);
|
|
6221
6282
|
return;
|
|
6222
6283
|
}
|
|
6223
6284
|
case "null_check":
|
|
@@ -6228,26 +6289,15 @@ function collectParameterMetadataFromExpression(expression, names, stringOpParam
|
|
|
6228
6289
|
case "fulltext_match": {
|
|
6229
6290
|
return;
|
|
6230
6291
|
}
|
|
6231
|
-
case "exists":
|
|
6232
|
-
collectParameterMetadataFromAst(
|
|
6233
|
-
expression.subquery,
|
|
6234
|
-
names,
|
|
6235
|
-
stringOpParameters
|
|
6236
|
-
);
|
|
6237
|
-
return;
|
|
6238
|
-
}
|
|
6292
|
+
case "exists":
|
|
6239
6293
|
case "in_subquery": {
|
|
6240
|
-
collectParameterMetadataFromAst(
|
|
6241
|
-
expression.subquery,
|
|
6242
|
-
names,
|
|
6243
|
-
stringOpParameters
|
|
6244
|
-
);
|
|
6294
|
+
collectParameterMetadataFromAst(expression.subquery, accumulator);
|
|
6245
6295
|
return;
|
|
6246
6296
|
}
|
|
6247
6297
|
}
|
|
6248
6298
|
}
|
|
6249
6299
|
function validateBindings(bindings, metadata) {
|
|
6250
|
-
const { names: expectedNames, stringOpParameters } = metadata;
|
|
6300
|
+
const { names: expectedNames, stringOpParameters, listParameters } = metadata;
|
|
6251
6301
|
const missing = [];
|
|
6252
6302
|
for (const name of expectedNames) {
|
|
6253
6303
|
if (bindings[name] === void 0) {
|
|
@@ -6271,9 +6321,53 @@ function validateBindings(bindings, metadata) {
|
|
|
6271
6321
|
}
|
|
6272
6322
|
for (const name of expectedNames) {
|
|
6273
6323
|
const value = bindings[name];
|
|
6324
|
+
if (listParameters.has(name)) {
|
|
6325
|
+
validateListBinding(name, value, listParameters.get(name));
|
|
6326
|
+
continue;
|
|
6327
|
+
}
|
|
6274
6328
|
validateBindingValue(name, value, stringOpParameters.has(name));
|
|
6275
6329
|
}
|
|
6276
6330
|
}
|
|
6331
|
+
function validateListBinding(name, value, elementType) {
|
|
6332
|
+
assertListBinding(name, value);
|
|
6333
|
+
for (const element of value) {
|
|
6334
|
+
validateBindingValue(name, element, false);
|
|
6335
|
+
if (elementType === void 0) continue;
|
|
6336
|
+
if (matchesElementType(element, elementType)) continue;
|
|
6337
|
+
throw new ConfigurationError(
|
|
6338
|
+
`Parameter "${name}" is bound against a ${elementType} field, so every element must be a ${elementType}; got ${describeBindingType(element)}`,
|
|
6339
|
+
{ parameterName: name, valueType: elementType }
|
|
6340
|
+
);
|
|
6341
|
+
}
|
|
6342
|
+
}
|
|
6343
|
+
function matchesElementType(value, elementType) {
|
|
6344
|
+
switch (elementType) {
|
|
6345
|
+
case "string": {
|
|
6346
|
+
return typeof value === "string";
|
|
6347
|
+
}
|
|
6348
|
+
case "number": {
|
|
6349
|
+
return typeof value === "number";
|
|
6350
|
+
}
|
|
6351
|
+
case "boolean": {
|
|
6352
|
+
return typeof value === "boolean";
|
|
6353
|
+
}
|
|
6354
|
+
case "date": {
|
|
6355
|
+
return value instanceof Date || typeof value === "string";
|
|
6356
|
+
}
|
|
6357
|
+
// No element cast is emitted for these, so there is no divergence to
|
|
6358
|
+
// prevent — `array`/`object` are rejected earlier, at compile time.
|
|
6359
|
+
case "array":
|
|
6360
|
+
case "object":
|
|
6361
|
+
case "embedding":
|
|
6362
|
+
case "unknown": {
|
|
6363
|
+
return true;
|
|
6364
|
+
}
|
|
6365
|
+
}
|
|
6366
|
+
}
|
|
6367
|
+
function describeBindingType(value) {
|
|
6368
|
+
if (value instanceof Date) return "date";
|
|
6369
|
+
return typeof value;
|
|
6370
|
+
}
|
|
6277
6371
|
function validateBindingValue(name, value, isStringOp) {
|
|
6278
6372
|
if (value === null) {
|
|
6279
6373
|
throw new ConfigurationError(
|
|
@@ -6290,7 +6384,16 @@ function validateBindingValue(name, value, isStringOp) {
|
|
|
6290
6384
|
}
|
|
6291
6385
|
return;
|
|
6292
6386
|
}
|
|
6293
|
-
if (
|
|
6387
|
+
if (typeof value === "number") {
|
|
6388
|
+
if (!Number.isFinite(value)) {
|
|
6389
|
+
throw new ConfigurationError(
|
|
6390
|
+
`Parameter "${name}" must be a finite number, got ${String(value)}`,
|
|
6391
|
+
{ parameterName: name, actualType: "number" }
|
|
6392
|
+
);
|
|
6393
|
+
}
|
|
6394
|
+
return;
|
|
6395
|
+
}
|
|
6396
|
+
if (value instanceof Date || typeof value === "string" || typeof value === "boolean") {
|
|
6294
6397
|
return;
|
|
6295
6398
|
}
|
|
6296
6399
|
throw new ConfigurationError(
|
|
@@ -6867,7 +6970,9 @@ var ExecutableQuery = class _ExecutableQuery {
|
|
|
6867
6970
|
* validates the AST once (a malformed query fails fast, here, instead of on
|
|
6868
6971
|
* first use); the prepared query then compiles once into a reusable template
|
|
6869
6972
|
* and fills a fresh read instant per execute() — see PreparedQuery's class
|
|
6870
|
-
* doc comment
|
|
6973
|
+
* doc comment, which also covers the two cases that recompile per call
|
|
6974
|
+
* instead (no `executeRaw`, or a statement whose semantics ride on the SQL
|
|
6975
|
+
* object rather than its text).
|
|
6871
6976
|
*
|
|
6872
6977
|
* Use `param("name")` in predicates to create parameterized slots,
|
|
6873
6978
|
* then pass values via `prepared.execute({ name: "value" })`.
|
|
@@ -7024,9 +7129,15 @@ var ExecutableQuery = class _ExecutableQuery {
|
|
|
7024
7129
|
/**
|
|
7025
7130
|
* Executes the query against a provided backend.
|
|
7026
7131
|
*
|
|
7027
|
-
* Used by `store.batch()` to run
|
|
7028
|
-
*
|
|
7029
|
-
*
|
|
7132
|
+
* Used by `store.batch()` to run several queries in sequence against one
|
|
7133
|
+
* target — a transaction on backends that have them, the backend itself
|
|
7134
|
+
* otherwise. The full compile → execute → transform pipeline runs
|
|
7135
|
+
* identically to `execute()`, but against the given backend.
|
|
7136
|
+
*
|
|
7137
|
+
* Costs one statement, or two when the selective-field path runs and its
|
|
7138
|
+
* mapping then falls back: `#tryOptimizedExecutionOn` detects that only
|
|
7139
|
+
* after its statement has executed, and the caller re-runs the full fetch.
|
|
7140
|
+
* The fallback clears the fast path for this instance.
|
|
7030
7141
|
*/
|
|
7031
7142
|
async executeOn(backend) {
|
|
7032
7143
|
const ast = this.toAst();
|
|
@@ -7133,29 +7244,15 @@ var ExecutableQuery = class _ExecutableQuery {
|
|
|
7133
7244
|
const hasOptionalTraversal = this.#state.traversals.some(
|
|
7134
7245
|
(traversal) => traversal.optional
|
|
7135
7246
|
);
|
|
7136
|
-
const
|
|
7137
|
-
{
|
|
7138
|
-
|
|
7139
|
-
|
|
7140
|
-
},
|
|
7141
|
-
{
|
|
7142
|
-
mode: "falsy",
|
|
7143
|
-
optionalTraversalAliases: "present"
|
|
7144
|
-
},
|
|
7145
|
-
{
|
|
7146
|
-
mode: "falsy",
|
|
7147
|
-
optionalTraversalAliases: "absent"
|
|
7148
|
-
}
|
|
7149
|
-
] : [
|
|
7150
|
-
{
|
|
7151
|
-
mode: "truthy",
|
|
7152
|
-
optionalTraversalAliases: "present"
|
|
7153
|
-
},
|
|
7154
|
-
{
|
|
7155
|
-
mode: "falsy",
|
|
7156
|
-
optionalTraversalAliases: "present"
|
|
7157
|
-
}
|
|
7247
|
+
const presentTrackingRuns = [
|
|
7248
|
+
{ mode: "truthy", optionalTraversalAliases: "present" },
|
|
7249
|
+
{ mode: "max", optionalTraversalAliases: "present" },
|
|
7250
|
+
{ mode: "falsy", optionalTraversalAliases: "present" }
|
|
7158
7251
|
];
|
|
7252
|
+
const trackingRuns = hasOptionalTraversal ? [
|
|
7253
|
+
...presentTrackingRuns,
|
|
7254
|
+
{ mode: "falsy", optionalTraversalAliases: "absent" }
|
|
7255
|
+
] : presentTrackingRuns;
|
|
7159
7256
|
for (const run of trackingRuns) {
|
|
7160
7257
|
const trackingContext = createTrackingContext(this.#state, tracker, {
|
|
7161
7258
|
schemaIntrospector: this.#config.schemaIntrospector,
|
|
@@ -9160,7 +9257,11 @@ var UnionableQuery = class _UnionableQuery {
|
|
|
9160
9257
|
/**
|
|
9161
9258
|
* Executes the combined query against a provided backend.
|
|
9162
9259
|
*
|
|
9163
|
-
* Used by `store.batch()` to run
|
|
9260
|
+
* Used by `store.batch()` to run several queries in sequence against one
|
|
9261
|
+
* target — a transaction on backends that have them, the backend itself
|
|
9262
|
+
* otherwise. A set operation compiles to one statement; whether that target
|
|
9263
|
+
* is a shared connection is the adapter's business, not a function of
|
|
9264
|
+
* transaction support.
|
|
9164
9265
|
*/
|
|
9165
9266
|
async executeOn(backend) {
|
|
9166
9267
|
const ast = this.toAst();
|
|
@@ -10701,183 +10802,6 @@ function classifyUnique(kind, existing, next, recorders) {
|
|
|
10701
10802
|
}
|
|
10702
10803
|
}
|
|
10703
10804
|
|
|
10704
|
-
// src/graph-extension/remove.ts
|
|
10705
|
-
function planRemovals(graph, names) {
|
|
10706
|
-
const document = graph.extension;
|
|
10707
|
-
const namesSet = new Set(names);
|
|
10708
|
-
if (namesSet.size === 0) {
|
|
10709
|
-
return { document, removedNodeKinds: [], removedEdgeKinds: [] };
|
|
10710
|
-
}
|
|
10711
|
-
const { nodes: runtimeNodeNames, edges: runtimeEdgeNames } = extensionKindNames(document);
|
|
10712
|
-
const compileTimeNodeNames = new Set(
|
|
10713
|
-
Object.keys(graph.nodes).filter((name) => !runtimeNodeNames.has(name))
|
|
10714
|
-
);
|
|
10715
|
-
const compileTimeEdgeNames = new Set(
|
|
10716
|
-
Object.keys(graph.edges).filter((name) => !runtimeEdgeNames.has(name))
|
|
10717
|
-
);
|
|
10718
|
-
for (const name of namesSet) {
|
|
10719
|
-
if (compileTimeNodeNames.has(name)) {
|
|
10720
|
-
throw new RemoveCompileTimeKindError(name, "node", graph.id);
|
|
10721
|
-
}
|
|
10722
|
-
if (compileTimeEdgeNames.has(name)) {
|
|
10723
|
-
throw new RemoveCompileTimeKindError(name, "edge", graph.id);
|
|
10724
|
-
}
|
|
10725
|
-
}
|
|
10726
|
-
const removedNodeKinds = [...namesSet].filter(
|
|
10727
|
-
(name) => runtimeNodeNames.has(name)
|
|
10728
|
-
);
|
|
10729
|
-
const explicitlyRemovedEdgeKinds = [...namesSet].filter(
|
|
10730
|
-
(name) => runtimeEdgeNames.has(name)
|
|
10731
|
-
);
|
|
10732
|
-
const referentsByKind = buildCompileTimeReferentIndex(
|
|
10733
|
-
graph,
|
|
10734
|
-
runtimeEdgeNames
|
|
10735
|
-
);
|
|
10736
|
-
for (const kindName of removedNodeKinds) {
|
|
10737
|
-
const referents = referentsByKind.get(kindName);
|
|
10738
|
-
if (referents !== void 0 && referents.length > 0) {
|
|
10739
|
-
throw new KindHasReferentsError(kindName, referents, graph.id);
|
|
10740
|
-
}
|
|
10741
|
-
}
|
|
10742
|
-
if (document === void 0) {
|
|
10743
|
-
return {
|
|
10744
|
-
document: void 0,
|
|
10745
|
-
removedNodeKinds: [],
|
|
10746
|
-
removedEdgeKinds: []
|
|
10747
|
-
};
|
|
10748
|
-
}
|
|
10749
|
-
const removedNodeKindsSet = new Set(removedNodeKinds);
|
|
10750
|
-
const explicitlyRemovedEdgeKindsSet = new Set(explicitlyRemovedEdgeKinds);
|
|
10751
|
-
const cascadeEdges = /* @__PURE__ */ new Set();
|
|
10752
|
-
const updatedEdges = {};
|
|
10753
|
-
for (const [edgeName, edgeDocument] of Object.entries(document.edges ?? {})) {
|
|
10754
|
-
if (explicitlyRemovedEdgeKindsSet.has(edgeName)) {
|
|
10755
|
-
cascadeEdges.add(edgeName);
|
|
10756
|
-
continue;
|
|
10757
|
-
}
|
|
10758
|
-
const newFrom = edgeDocument.from.filter(
|
|
10759
|
-
(kind) => !removedNodeKindsSet.has(kind)
|
|
10760
|
-
);
|
|
10761
|
-
const newTo = edgeDocument.to.filter(
|
|
10762
|
-
(kind) => !removedNodeKindsSet.has(kind)
|
|
10763
|
-
);
|
|
10764
|
-
if (newFrom.length === 0 || newTo.length === 0) {
|
|
10765
|
-
cascadeEdges.add(edgeName);
|
|
10766
|
-
continue;
|
|
10767
|
-
}
|
|
10768
|
-
updatedEdges[edgeName] = {
|
|
10769
|
-
...edgeDocument,
|
|
10770
|
-
from: newFrom,
|
|
10771
|
-
to: newTo
|
|
10772
|
-
};
|
|
10773
|
-
}
|
|
10774
|
-
const updatedNodes = {};
|
|
10775
|
-
for (const [nodeName, nodeDocument] of Object.entries(document.nodes ?? {})) {
|
|
10776
|
-
if (removedNodeKindsSet.has(nodeName)) continue;
|
|
10777
|
-
updatedNodes[nodeName] = nodeDocument;
|
|
10778
|
-
}
|
|
10779
|
-
const survivingOntology = (document.ontology ?? []).filter(
|
|
10780
|
-
(relation) => !removedNodeKindsSet.has(relation.from) && !removedNodeKindsSet.has(relation.to)
|
|
10781
|
-
);
|
|
10782
|
-
const allRemovedKinds = /* @__PURE__ */ new Set([
|
|
10783
|
-
...removedNodeKindsSet,
|
|
10784
|
-
...cascadeEdges,
|
|
10785
|
-
...explicitlyRemovedEdgeKindsSet
|
|
10786
|
-
]);
|
|
10787
|
-
const survivingIndexes = (document.indexes ?? []).filter(
|
|
10788
|
-
(index) => !allRemovedKinds.has(index.kind)
|
|
10789
|
-
);
|
|
10790
|
-
const newDocument = Object.freeze({
|
|
10791
|
-
...document.version === void 0 ? {} : { version: document.version },
|
|
10792
|
-
...Object.keys(updatedNodes).length === 0 ? {} : { nodes: updatedNodes },
|
|
10793
|
-
...Object.keys(updatedEdges).length === 0 ? {} : { edges: updatedEdges },
|
|
10794
|
-
...survivingOntology.length === 0 ? {} : { ontology: survivingOntology },
|
|
10795
|
-
...survivingIndexes.length === 0 ? {} : { indexes: survivingIndexes }
|
|
10796
|
-
});
|
|
10797
|
-
return {
|
|
10798
|
-
document: newDocument,
|
|
10799
|
-
removedNodeKinds,
|
|
10800
|
-
removedEdgeKinds: [
|
|
10801
|
-
...explicitlyRemovedEdgeKinds,
|
|
10802
|
-
...[...cascadeEdges].filter(
|
|
10803
|
-
(name) => !explicitlyRemovedEdgeKindsSet.has(name)
|
|
10804
|
-
)
|
|
10805
|
-
]
|
|
10806
|
-
};
|
|
10807
|
-
}
|
|
10808
|
-
function stripGraphExtension(graph) {
|
|
10809
|
-
const document = graph.extension;
|
|
10810
|
-
if (document === void 0) return graph;
|
|
10811
|
-
const { nodes: runtimeNodeNames, edges: runtimeEdgeNames } = extensionKindNames(document);
|
|
10812
|
-
const runtimeOntologyKeys = buildGraphExtensionOntologyKeySet(document);
|
|
10813
|
-
const compileNodes = {};
|
|
10814
|
-
for (const [name, registration] of Object.entries(graph.nodes)) {
|
|
10815
|
-
if (runtimeNodeNames.has(name)) continue;
|
|
10816
|
-
compileNodes[name] = registration;
|
|
10817
|
-
}
|
|
10818
|
-
const compileEdges = {};
|
|
10819
|
-
for (const [name, registration] of Object.entries(graph.edges)) {
|
|
10820
|
-
if (runtimeEdgeNames.has(name)) continue;
|
|
10821
|
-
compileEdges[name] = registration;
|
|
10822
|
-
}
|
|
10823
|
-
const compileOntology = graph.ontology.filter(
|
|
10824
|
-
(relation) => !runtimeOntologyKeys.has(compileTimeOntologyKey(relation))
|
|
10825
|
-
);
|
|
10826
|
-
const compileIndexes = (graph.indexes ?? []).filter(
|
|
10827
|
-
(index) => index.origin !== "runtime"
|
|
10828
|
-
);
|
|
10829
|
-
return Object.freeze({
|
|
10830
|
-
...graph,
|
|
10831
|
-
nodes: compileNodes,
|
|
10832
|
-
edges: compileEdges,
|
|
10833
|
-
ontology: compileOntology,
|
|
10834
|
-
indexes: compileIndexes.length === 0 ? void 0 : compileIndexes,
|
|
10835
|
-
extension: void 0
|
|
10836
|
-
});
|
|
10837
|
-
}
|
|
10838
|
-
function buildCompileTimeReferentIndex(graph, runtimeEdgeNames) {
|
|
10839
|
-
const index = /* @__PURE__ */ new Map();
|
|
10840
|
-
const append = (kindName, referent) => {
|
|
10841
|
-
const existing = index.get(kindName);
|
|
10842
|
-
if (existing === void 0) index.set(kindName, [referent]);
|
|
10843
|
-
else existing.push(referent);
|
|
10844
|
-
};
|
|
10845
|
-
for (const [edgeName, registration] of Object.entries(graph.edges)) {
|
|
10846
|
-
if (runtimeEdgeNames.has(edgeName)) continue;
|
|
10847
|
-
const reg = registration;
|
|
10848
|
-
const referent = {
|
|
10849
|
-
type: "compile-time-edge",
|
|
10850
|
-
name: edgeName
|
|
10851
|
-
};
|
|
10852
|
-
const seen = /* @__PURE__ */ new Set();
|
|
10853
|
-
for (const endpoint of reg.from ?? []) {
|
|
10854
|
-
if (seen.has(endpoint.kind)) continue;
|
|
10855
|
-
seen.add(endpoint.kind);
|
|
10856
|
-
append(endpoint.kind, referent);
|
|
10857
|
-
}
|
|
10858
|
-
for (const endpoint of reg.to ?? []) {
|
|
10859
|
-
if (seen.has(endpoint.kind)) continue;
|
|
10860
|
-
seen.add(endpoint.kind);
|
|
10861
|
-
append(endpoint.kind, referent);
|
|
10862
|
-
}
|
|
10863
|
-
}
|
|
10864
|
-
const runtimeOntologyKeys = buildGraphExtensionOntologyKeySet(
|
|
10865
|
-
graph.extension
|
|
10866
|
-
);
|
|
10867
|
-
for (const relation of graph.ontology) {
|
|
10868
|
-
if (runtimeOntologyKeys.has(compileTimeOntologyKey(relation))) continue;
|
|
10869
|
-
const fromName = getTypeName(relation.from);
|
|
10870
|
-
const toName = getTypeName(relation.to);
|
|
10871
|
-
const referent = {
|
|
10872
|
-
type: "compile-time-ontology",
|
|
10873
|
-
name: `${relation.metaEdge.name}(${fromName}, ${toName})`
|
|
10874
|
-
};
|
|
10875
|
-
append(fromName, referent);
|
|
10876
|
-
if (toName !== fromName) append(toName, referent);
|
|
10877
|
-
}
|
|
10878
|
-
return index;
|
|
10879
|
-
}
|
|
10880
|
-
|
|
10881
10805
|
// src/store/algorithms/context.ts
|
|
10882
10806
|
var DEFAULT_ALGORITHM_MAX_HOPS = 10;
|
|
10883
10807
|
var DEFAULT_NEIGHBOR_DEPTH = 1;
|
|
@@ -13530,6 +13454,36 @@ function buildUpdateEdgeInput(id, props, options) {
|
|
|
13530
13454
|
if (options?.validTo !== void 0) input.validTo = options.validTo;
|
|
13531
13455
|
return input;
|
|
13532
13456
|
}
|
|
13457
|
+
function endpointKey(endpointKind, id) {
|
|
13458
|
+
return `${endpointKind}\0${id}`;
|
|
13459
|
+
}
|
|
13460
|
+
function groupEndpointIdsByKind(references) {
|
|
13461
|
+
const referencesByKind = groupBy(references, (ref) => ref.kind);
|
|
13462
|
+
return new Map(
|
|
13463
|
+
[...referencesByKind].map(([endpointKind, group]) => [
|
|
13464
|
+
endpointKind,
|
|
13465
|
+
group.map((ref) => ref.id)
|
|
13466
|
+
])
|
|
13467
|
+
);
|
|
13468
|
+
}
|
|
13469
|
+
function assertLimitPerInput(kind, limitPerInput) {
|
|
13470
|
+
if (limitPerInput === void 0) return;
|
|
13471
|
+
if (Number.isInteger(limitPerInput) && limitPerInput > 0) return;
|
|
13472
|
+
throw new ValidationError(
|
|
13473
|
+
"bulk endpoint reads require limitPerInput to be a positive integer",
|
|
13474
|
+
{
|
|
13475
|
+
entityType: "edge",
|
|
13476
|
+
kind,
|
|
13477
|
+
issues: [
|
|
13478
|
+
{
|
|
13479
|
+
path: "limitPerInput",
|
|
13480
|
+
message: `Expected a positive integer, received ${String(limitPerInput)}`,
|
|
13481
|
+
code: "invalid_value"
|
|
13482
|
+
}
|
|
13483
|
+
]
|
|
13484
|
+
}
|
|
13485
|
+
);
|
|
13486
|
+
}
|
|
13533
13487
|
function mapBulkEdgeInputs(kind, items) {
|
|
13534
13488
|
return items.map(
|
|
13535
13489
|
(item) => buildCreateEdgeInput(kind, item.from, item.to, item.props ?? {}, item)
|
|
@@ -13552,29 +13506,74 @@ function createEdgeCollection(config) {
|
|
|
13552
13506
|
temporalRowMatcher
|
|
13553
13507
|
} = config;
|
|
13554
13508
|
const mapRows = (rows) => rows.map((row) => narrowEdge(rowToEdge2(row)));
|
|
13555
|
-
function buildEndpointFindParams(endpoint,
|
|
13556
|
-
return {
|
|
13557
|
-
graphId,
|
|
13558
|
-
kind,
|
|
13559
|
-
...endpoint,
|
|
13560
|
-
...resolveTemporalReadParams(options, defaultTemporalMode)
|
|
13561
|
-
};
|
|
13509
|
+
function buildEndpointFindParams(endpoint, temporal) {
|
|
13510
|
+
return { graphId, kind, ...endpoint, ...temporal };
|
|
13562
13511
|
}
|
|
13563
13512
|
async function findEdgesFrom(from, target, options) {
|
|
13564
13513
|
const rows = await target.findEdgesByKind(
|
|
13565
13514
|
buildEndpointFindParams(
|
|
13566
13515
|
{ fromKind: from.kind, fromId: from.id },
|
|
13567
|
-
options
|
|
13516
|
+
resolveTemporalReadParams(options, defaultTemporalMode)
|
|
13568
13517
|
)
|
|
13569
13518
|
);
|
|
13570
13519
|
return mapRows(rows);
|
|
13571
13520
|
}
|
|
13572
13521
|
async function findEdgesTo(to, target, options) {
|
|
13573
13522
|
const rows = await target.findEdgesByKind(
|
|
13574
|
-
buildEndpointFindParams(
|
|
13523
|
+
buildEndpointFindParams(
|
|
13524
|
+
{ toKind: to.kind, toId: to.id },
|
|
13525
|
+
resolveTemporalReadParams(options, defaultTemporalMode)
|
|
13526
|
+
)
|
|
13575
13527
|
);
|
|
13576
13528
|
return mapRows(rows);
|
|
13577
13529
|
}
|
|
13530
|
+
async function findEdgesByEndpointSet(side, references, options) {
|
|
13531
|
+
if (references.length === 0) return [];
|
|
13532
|
+
const method = side === "from" ? "bulkFindFrom" : "bulkFindTo";
|
|
13533
|
+
const readEndpointSet = backend.findEdgesByEndpointSet;
|
|
13534
|
+
if (readEndpointSet === void 0) {
|
|
13535
|
+
throw new ConfigurationError(
|
|
13536
|
+
`store.edges.${kind}.${method}() requires a backend that can read a set of endpoints with set-oriented statements, and this backend does not implement findEdgesByEndpointSet.`,
|
|
13537
|
+
{
|
|
13538
|
+
backend: backend.dialect,
|
|
13539
|
+
capability: "findEdgesByEndpointSet",
|
|
13540
|
+
kind,
|
|
13541
|
+
operation: method
|
|
13542
|
+
},
|
|
13543
|
+
{
|
|
13544
|
+
suggestion: `Falling back to one findFrom/findTo per endpoint is deliberately NOT done here: a caller reaching for a bulk endpoint read is asking for a set-oriented read, and silently issuing N singleton statements is the cost surprise this method exists to avoid. Loop over findFrom/findTo explicitly if that trade is acceptable.`
|
|
13545
|
+
}
|
|
13546
|
+
);
|
|
13547
|
+
}
|
|
13548
|
+
const limitPerInput = options?.limitPerInput;
|
|
13549
|
+
assertLimitPerInput(kind, limitPerInput);
|
|
13550
|
+
const temporal = resolveTemporalReadParams(options, defaultTemporalMode);
|
|
13551
|
+
const limitPerEndpoint = limitPerInput !== void 0 && backend.capabilities.windowFunctions ? { limitPerEndpoint: limitPerInput } : {};
|
|
13552
|
+
const edgesByEndpoint = /* @__PURE__ */ new Map();
|
|
13553
|
+
for (const [endpointKind, endpointIds] of groupEndpointIdsByKind(
|
|
13554
|
+
references
|
|
13555
|
+
)) {
|
|
13556
|
+
const rows = await readEndpointSet({
|
|
13557
|
+
graphId,
|
|
13558
|
+
kind,
|
|
13559
|
+
side,
|
|
13560
|
+
endpointKind,
|
|
13561
|
+
endpointIds,
|
|
13562
|
+
...limitPerEndpoint,
|
|
13563
|
+
...temporal
|
|
13564
|
+
});
|
|
13565
|
+
for (const edge of mapRows(rows)) {
|
|
13566
|
+
const key = side === "from" ? endpointKey(edge.fromKind, edge.fromId) : endpointKey(edge.toKind, edge.toId);
|
|
13567
|
+
const bucket = edgesByEndpoint.get(key);
|
|
13568
|
+
if (bucket === void 0) edgesByEndpoint.set(key, [edge]);
|
|
13569
|
+
else bucket.push(edge);
|
|
13570
|
+
}
|
|
13571
|
+
}
|
|
13572
|
+
return references.map((ref) => {
|
|
13573
|
+
const bucket = edgesByEndpoint.get(endpointKey(ref.kind, ref.id)) ?? [];
|
|
13574
|
+
return limitPerInput === void 0 ? [...bucket] : bucket.slice(0, limitPerInput);
|
|
13575
|
+
});
|
|
13576
|
+
}
|
|
13578
13577
|
function buildFindByEndpointsOptions(options, temporal) {
|
|
13579
13578
|
const result = { ...resolveTemporalReadParams(temporal, defaultTemporalMode) };
|
|
13580
13579
|
if (options?.matchOn !== void 0)
|
|
@@ -13622,6 +13621,12 @@ function createEdgeCollection(config) {
|
|
|
13622
13621
|
async findTo(to, options) {
|
|
13623
13622
|
return findEdgesTo(to, backend, options);
|
|
13624
13623
|
},
|
|
13624
|
+
async bulkFindFrom(froms, options) {
|
|
13625
|
+
return findEdgesByEndpointSet("from", froms, options);
|
|
13626
|
+
},
|
|
13627
|
+
async bulkFindTo(tos, options) {
|
|
13628
|
+
return findEdgesByEndpointSet("to", tos, options);
|
|
13629
|
+
},
|
|
13625
13630
|
batchFindFrom(from, options) {
|
|
13626
13631
|
return { executeOn: (target) => findEdgesFrom(from, target, options) };
|
|
13627
13632
|
},
|
|
@@ -13914,6 +13919,35 @@ function narrowNode(node) {
|
|
|
13914
13919
|
function narrowNodes(nodes) {
|
|
13915
13920
|
return nodes;
|
|
13916
13921
|
}
|
|
13922
|
+
function createFieldMember(accessor) {
|
|
13923
|
+
const selectField = (name) => accessor.field(name);
|
|
13924
|
+
return new Proxy(selectField, {
|
|
13925
|
+
get(target, property, receiver) {
|
|
13926
|
+
if (Reflect.has(target, property)) {
|
|
13927
|
+
const ownProperty = Reflect.get(target, property, receiver);
|
|
13928
|
+
return ownProperty;
|
|
13929
|
+
}
|
|
13930
|
+
return accessor.field("field")[property];
|
|
13931
|
+
}
|
|
13932
|
+
});
|
|
13933
|
+
}
|
|
13934
|
+
function evaluateNodePredicate(accessor, predicate) {
|
|
13935
|
+
const collectionAccessor = new Proxy(
|
|
13936
|
+
{},
|
|
13937
|
+
{
|
|
13938
|
+
get(_target, property) {
|
|
13939
|
+
if (typeof property === "symbol") return;
|
|
13940
|
+
if (property === "then" || property === "toJSON") return;
|
|
13941
|
+
if (property === "id" || property === "kind" || property === "$fulltext") {
|
|
13942
|
+
return accessor[property];
|
|
13943
|
+
}
|
|
13944
|
+
if (property === "field") return createFieldMember(accessor);
|
|
13945
|
+
return accessor.field(property);
|
|
13946
|
+
}
|
|
13947
|
+
}
|
|
13948
|
+
);
|
|
13949
|
+
return predicate(collectionAccessor);
|
|
13950
|
+
}
|
|
13917
13951
|
function buildCreateInput(kind, props, options) {
|
|
13918
13952
|
const input = { kind, props };
|
|
13919
13953
|
if (options?.id !== void 0) input.id = options.id;
|
|
@@ -13940,6 +13974,7 @@ function createNodeCollection(config) {
|
|
|
13940
13974
|
executeCreateNoReturnBatch: executeNodeCreateNoReturnBatch2,
|
|
13941
13975
|
executeCreateBatch: executeNodeCreateBatch2,
|
|
13942
13976
|
executeUpdate: executeNodeUpdate2,
|
|
13977
|
+
executeUpdateWhere: executeNodeUpdateWhere2,
|
|
13943
13978
|
executeUpsertUpdate: executeNodeUpsertUpdate2,
|
|
13944
13979
|
executeDelete: executeNodeDelete2,
|
|
13945
13980
|
executeHardDelete: executeNodeHardDelete2,
|
|
@@ -13986,6 +14021,85 @@ function createNodeCollection(config) {
|
|
|
13986
14021
|
);
|
|
13987
14022
|
return narrowNode(result);
|
|
13988
14023
|
},
|
|
14024
|
+
async updateWhere(params) {
|
|
14025
|
+
if (createQuery === void 0) {
|
|
14026
|
+
throw new ConfigurationError(
|
|
14027
|
+
`store.nodes.${kind}.updateWhere() requires a query-capable store`,
|
|
14028
|
+
{ kind, operation: "updateWhere" }
|
|
14029
|
+
);
|
|
14030
|
+
}
|
|
14031
|
+
const exists = params.exists ?? [];
|
|
14032
|
+
if (params.where === void 0 && exists.length === 0 && !params.all) {
|
|
14033
|
+
throw new ConfigurationError(
|
|
14034
|
+
`store.nodes.${kind}.updateWhere() requires where, exists, or explicit all: true`,
|
|
14035
|
+
{ kind, operation: "updateWhere" }
|
|
14036
|
+
);
|
|
14037
|
+
}
|
|
14038
|
+
const rootAlias = "update_candidate";
|
|
14039
|
+
const readInstant = nowIso();
|
|
14040
|
+
let base = createQuery().fromDynamic(kind, rootAlias).temporal("asOf", readInstant);
|
|
14041
|
+
const where = params.where;
|
|
14042
|
+
if (where !== void 0) {
|
|
14043
|
+
base = base.whereNode(
|
|
14044
|
+
rootAlias,
|
|
14045
|
+
(accessor) => evaluateNodePredicate(accessor, where)
|
|
14046
|
+
);
|
|
14047
|
+
}
|
|
14048
|
+
const candidateIdColumn = `${rootAlias}_id`;
|
|
14049
|
+
const compiledBranches = [];
|
|
14050
|
+
for (const [index, relation] of exists.entries()) {
|
|
14051
|
+
const edgeAlias = `update_edge_${index}`;
|
|
14052
|
+
const relatedAlias = `update_related_${index}`;
|
|
14053
|
+
const relationRoot = createQuery().fromDynamic(kind, rootAlias).temporal("asOf", readInstant);
|
|
14054
|
+
let traversal = relationRoot.traverseDynamic(
|
|
14055
|
+
relation.edgeKind,
|
|
14056
|
+
edgeAlias,
|
|
14057
|
+
{
|
|
14058
|
+
direction: relation.direction,
|
|
14059
|
+
expand: "none"
|
|
14060
|
+
}
|
|
14061
|
+
);
|
|
14062
|
+
if (relation.whereEdge !== void 0) {
|
|
14063
|
+
traversal = traversal.whereEdge(edgeAlias, relation.whereEdge);
|
|
14064
|
+
}
|
|
14065
|
+
let related = traversal.toDynamic(relation.relatedKind, relatedAlias);
|
|
14066
|
+
if (relation.whereRelated !== void 0) {
|
|
14067
|
+
related = related.whereNode(relatedAlias, relation.whereRelated);
|
|
14068
|
+
}
|
|
14069
|
+
compiledBranches.push(
|
|
14070
|
+
related.select(
|
|
14071
|
+
(ctx) => ctx[rootAlias]?.id
|
|
14072
|
+
).compile()
|
|
14073
|
+
);
|
|
14074
|
+
}
|
|
14075
|
+
compiledBranches.unshift(
|
|
14076
|
+
base.select((ctx) => ctx[rootAlias]?.id).compile()
|
|
14077
|
+
);
|
|
14078
|
+
const projectCandidateId = (branch, index) => sql`
|
|
14079
|
+
SELECT ${sql.identifier(candidateIdColumn)}
|
|
14080
|
+
FROM (${branch}) AS ${sql.identifier(`update_branch_${index}`)}
|
|
14081
|
+
`;
|
|
14082
|
+
let combinedCandidates = projectCandidateId(
|
|
14083
|
+
requireDefined(compiledBranches[0]),
|
|
14084
|
+
0
|
|
14085
|
+
);
|
|
14086
|
+
for (let index = 1; index < compiledBranches.length; index++) {
|
|
14087
|
+
combinedCandidates = sql`${combinedCandidates} INTERSECT ${projectCandidateId(
|
|
14088
|
+
requireDefined(compiledBranches[index]),
|
|
14089
|
+
index
|
|
14090
|
+
)}`;
|
|
14091
|
+
}
|
|
14092
|
+
const compiledCandidates = asCompiledSelectSql(combinedCandidates);
|
|
14093
|
+
const result = await executeNodeUpdateWhere2(
|
|
14094
|
+
kind,
|
|
14095
|
+
params.patch,
|
|
14096
|
+
compiledCandidates,
|
|
14097
|
+
candidateIdColumn,
|
|
14098
|
+
backend
|
|
14099
|
+
);
|
|
14100
|
+
await config.maybeRefreshStatisticsAfterBulk?.(result.affectedCount);
|
|
14101
|
+
return result;
|
|
14102
|
+
},
|
|
13989
14103
|
async delete(id) {
|
|
13990
14104
|
await executeNodeDelete2(kind, id, backend);
|
|
13991
14105
|
},
|
|
@@ -14326,6 +14440,8 @@ var HISTORY_STORE_BACKEND_KEYS = [
|
|
|
14326
14440
|
"claimIndexMaterialization",
|
|
14327
14441
|
"close",
|
|
14328
14442
|
"commitSchemaVersion",
|
|
14443
|
+
"commitSchemaVersionIfKindsEmpty",
|
|
14444
|
+
"lockSchemaVersionForWrite",
|
|
14329
14445
|
"compileSql",
|
|
14330
14446
|
"countEdgesByKind",
|
|
14331
14447
|
"countEdgesFrom",
|
|
@@ -14334,10 +14450,12 @@ var HISTORY_STORE_BACKEND_KEYS = [
|
|
|
14334
14450
|
"deleteEdge",
|
|
14335
14451
|
"deleteEdgesBatch",
|
|
14336
14452
|
"deleteEmbedding",
|
|
14453
|
+
"deleteEmbeddingBatch",
|
|
14337
14454
|
"deleteFulltext",
|
|
14338
14455
|
"deleteFulltextBatch",
|
|
14339
14456
|
"deleteNode",
|
|
14340
14457
|
"deleteUnique",
|
|
14458
|
+
"hardDeleteUniquesByNodeIds",
|
|
14341
14459
|
"deleteVectorSlotContribution",
|
|
14342
14460
|
"dialect",
|
|
14343
14461
|
"dropVectorIndex",
|
|
@@ -14354,6 +14472,8 @@ var HISTORY_STORE_BACKEND_KEYS = [
|
|
|
14354
14472
|
"execute",
|
|
14355
14473
|
"executeTemporaryStatement",
|
|
14356
14474
|
"findEdgesByKind",
|
|
14475
|
+
"findEdgesByEndpointSet",
|
|
14476
|
+
"findEdgesByHeterogeneousEndpointSet",
|
|
14357
14477
|
"findEdgesConnectedTo",
|
|
14358
14478
|
"findNodesByKind",
|
|
14359
14479
|
"fulltextSearch",
|
|
@@ -14373,6 +14493,7 @@ var HISTORY_STORE_BACKEND_KEYS = [
|
|
|
14373
14493
|
"hardDeleteEdge",
|
|
14374
14494
|
"hardDeleteEdgesBatch",
|
|
14375
14495
|
"hardDeleteNode",
|
|
14496
|
+
"hardDeleteUniquesByNodeIds",
|
|
14376
14497
|
"hybridSearch",
|
|
14377
14498
|
"insertEdge",
|
|
14378
14499
|
"insertEdgeNoReturn",
|
|
@@ -14394,12 +14515,14 @@ var HISTORY_STORE_BACKEND_KEYS = [
|
|
|
14394
14515
|
"tableNames",
|
|
14395
14516
|
"updateEdge",
|
|
14396
14517
|
"updateNode",
|
|
14518
|
+
"updateNodeSet",
|
|
14397
14519
|
"upsertEmbedding",
|
|
14398
14520
|
"upsertEmbeddingBatch",
|
|
14399
14521
|
"upsertFulltext",
|
|
14400
14522
|
"upsertFulltextBatch",
|
|
14401
14523
|
"vectorSearch",
|
|
14402
|
-
"vectorStrategy"
|
|
14524
|
+
"vectorStrategy",
|
|
14525
|
+
"verifyContributions"
|
|
14403
14526
|
];
|
|
14404
14527
|
function createHistoryStoreBackendProjection(backend) {
|
|
14405
14528
|
return Object.freeze(
|
|
@@ -14501,18 +14624,6 @@ async function runBucketedMaterialization(items, options, bucketKey, runOne) {
|
|
|
14501
14624
|
);
|
|
14502
14625
|
return results;
|
|
14503
14626
|
}
|
|
14504
|
-
async function runMaterialization(items, options, runOne) {
|
|
14505
|
-
if (options.stopOnError === true) {
|
|
14506
|
-
const results = [];
|
|
14507
|
-
for (const item of items) {
|
|
14508
|
-
const entry2 = await runOne(item);
|
|
14509
|
-
results.push(entry2);
|
|
14510
|
-
if (entry2.status === "failed") break;
|
|
14511
|
-
}
|
|
14512
|
-
return results;
|
|
14513
|
-
}
|
|
14514
|
-
return Promise.all(items.map((item) => runOne(item)));
|
|
14515
|
-
}
|
|
14516
14627
|
|
|
14517
14628
|
// src/store/materialize-indexes.ts
|
|
14518
14629
|
var CLAIM_LEASE_MS = 15 * 6e4;
|
|
@@ -15216,21 +15327,38 @@ function buildPendingKindRemoval(args) {
|
|
|
15216
15327
|
}
|
|
15217
15328
|
async function materializeRemovals(context, options = {}) {
|
|
15218
15329
|
const { backend, graphId } = context;
|
|
15219
|
-
if (backend.
|
|
15330
|
+
if (backend.recordKindRemoval === void 0 || backend.getPendingKindRemovals === void 0) {
|
|
15220
15331
|
throw new ConfigurationError(
|
|
15221
|
-
"store.materializeRemovals() requires a backend with kind-removal primitives (
|
|
15332
|
+
"store.materializeRemovals() requires a backend with kind-removal primitives (recordKindRemoval, getPendingKindRemovals). The bundled SQLite and Postgres backends provide them.",
|
|
15222
15333
|
{ code: "MATERIALIZE_REMOVALS_BACKEND_UNSUPPORTED" }
|
|
15223
15334
|
);
|
|
15224
15335
|
}
|
|
15225
15336
|
await ensureFocusedStatusTable(backend, backend.ensureKindRemovalsTable);
|
|
15226
15337
|
await reconcilePendingRemovals(context);
|
|
15227
|
-
const
|
|
15338
|
+
const activeRow = await backend.getActiveSchema(graphId);
|
|
15339
|
+
const activeSchema = activeRow === void 0 ? void 0 : parseSerializedSchema(activeRow.schema_doc);
|
|
15340
|
+
const reclaimedVectorFields = await reclaimRemovedVectorFieldTables(
|
|
15341
|
+
context,
|
|
15342
|
+
activeRow
|
|
15343
|
+
);
|
|
15228
15344
|
const pending = await backend.getPendingKindRemovals(graphId);
|
|
15345
|
+
const liveKinds = liveKindNamesFrom(activeSchema);
|
|
15229
15346
|
const kindFilter = options.kinds === void 0 ? void 0 : new Set(options.kinds);
|
|
15230
|
-
const
|
|
15231
|
-
(row) => kindFilter === void 0
|
|
15347
|
+
const selected = pending.filter(
|
|
15348
|
+
(row) => kindFilter === void 0 || kindFilter.has(row.kindName)
|
|
15349
|
+
);
|
|
15350
|
+
const candidates = selected.filter(
|
|
15351
|
+
(row) => !liveKinds[row.entity].has(row.kindName)
|
|
15232
15352
|
);
|
|
15233
|
-
|
|
15353
|
+
const skipped = selected.filter((row) => liveKinds[row.entity].has(row.kindName)).map((row) => ({
|
|
15354
|
+
kind: row.kindName,
|
|
15355
|
+
entity: row.entity,
|
|
15356
|
+
status: "skipped",
|
|
15357
|
+
reason: "kind-is-live"
|
|
15358
|
+
}));
|
|
15359
|
+
if (candidates.length === 0) {
|
|
15360
|
+
return { results: skipped, reclaimedVectorFields };
|
|
15361
|
+
}
|
|
15234
15362
|
const tableNames = backend.tableNames;
|
|
15235
15363
|
const nodesTable = tableNames?.nodes ?? "typegraph_nodes";
|
|
15236
15364
|
const edgesTable = tableNames?.edges ?? "typegraph_edges";
|
|
@@ -15247,14 +15375,13 @@ async function materializeRemovals(context, options = {}) {
|
|
|
15247
15375
|
captureRecordedRemovals,
|
|
15248
15376
|
recordedSchema: captureRecordedRemovals ? context.recordedSchema ?? createSqlSchema(backend.tableNames) : void 0
|
|
15249
15377
|
};
|
|
15250
|
-
|
|
15251
|
-
|
|
15252
|
-
|
|
15253
|
-
|
|
15254
|
-
|
|
15255
|
-
|
|
15256
|
-
|
|
15257
|
-
};
|
|
15378
|
+
const materialized = [];
|
|
15379
|
+
for (const candidate of candidates) {
|
|
15380
|
+
const entry2 = await materializeOne2(candidate, ctx);
|
|
15381
|
+
materialized.push(entry2);
|
|
15382
|
+
if (options.stopOnError === true && entry2.status === "failed") break;
|
|
15383
|
+
}
|
|
15384
|
+
return { results: [...materialized, ...skipped], reclaimedVectorFields };
|
|
15258
15385
|
}
|
|
15259
15386
|
async function reconcilePendingRemovals(context) {
|
|
15260
15387
|
const { backend, graphId } = context;
|
|
@@ -15322,14 +15449,49 @@ async function reconcilePendingRemovals(context) {
|
|
|
15322
15449
|
await backend.setReconciliationMarker(graphId, activeRow.version);
|
|
15323
15450
|
}
|
|
15324
15451
|
}
|
|
15452
|
+
function liveKindNamesFrom(schema) {
|
|
15453
|
+
if (schema === void 0) {
|
|
15454
|
+
return { node: /* @__PURE__ */ new Set(), edge: /* @__PURE__ */ new Set() };
|
|
15455
|
+
}
|
|
15456
|
+
return {
|
|
15457
|
+
node: new Set(Object.keys(schema.nodes)),
|
|
15458
|
+
edge: new Set(Object.keys(schema.edges))
|
|
15459
|
+
};
|
|
15460
|
+
}
|
|
15325
15461
|
function kindRemovalKey(entity, kindName, version) {
|
|
15326
15462
|
return `${entity}|${kindName}|${version}`;
|
|
15327
15463
|
}
|
|
15328
15464
|
async function materializeOne2(row, ctx) {
|
|
15329
15465
|
const recordKindRemoval = requireDefined(ctx.backend.recordKindRemoval);
|
|
15466
|
+
const schemaWriteTransaction = ctx.backend.schemaWriteTransaction;
|
|
15467
|
+
if (schemaWriteTransaction === void 0) {
|
|
15468
|
+
throw new ConfigurationError(
|
|
15469
|
+
"store.materializeRemovals() requires a backend that can hold the schema-write lock across the live-kind check and cleanup.",
|
|
15470
|
+
{ code: "MATERIALIZE_REMOVALS_SCHEMA_FENCE_UNSUPPORTED" }
|
|
15471
|
+
);
|
|
15472
|
+
}
|
|
15330
15473
|
try {
|
|
15331
|
-
await
|
|
15332
|
-
|
|
15474
|
+
const outcome = await schemaWriteTransaction(
|
|
15475
|
+
ctx.graphId,
|
|
15476
|
+
async (target) => {
|
|
15477
|
+
const activeRow = await target.getActiveSchema(ctx.graphId);
|
|
15478
|
+
const activeSchema = activeRow === void 0 ? void 0 : parseSerializedSchema(activeRow.schema_doc);
|
|
15479
|
+
if (liveKindNamesFrom(activeSchema)[row.entity].has(row.kindName)) {
|
|
15480
|
+
return "skipped";
|
|
15481
|
+
}
|
|
15482
|
+
await closeRecordedAndDeleteLiveRows(ctx, row, target);
|
|
15483
|
+
await dropEmbeddingTableStorage(ctx, row, target);
|
|
15484
|
+
return "removed";
|
|
15485
|
+
}
|
|
15486
|
+
);
|
|
15487
|
+
if (outcome === "skipped") {
|
|
15488
|
+
return {
|
|
15489
|
+
kind: row.kindName,
|
|
15490
|
+
entity: row.entity,
|
|
15491
|
+
status: "skipped",
|
|
15492
|
+
reason: "kind-is-live"
|
|
15493
|
+
};
|
|
15494
|
+
}
|
|
15333
15495
|
const removedAt = nowIso();
|
|
15334
15496
|
await recordKindRemoval({
|
|
15335
15497
|
graphId: ctx.graphId,
|
|
@@ -15364,28 +15526,33 @@ async function materializeOne2(row, ctx) {
|
|
|
15364
15526
|
};
|
|
15365
15527
|
}
|
|
15366
15528
|
}
|
|
15367
|
-
async function closeRecordedAndDeleteLiveRows(ctx, row) {
|
|
15529
|
+
async function closeRecordedAndDeleteLiveRows(ctx, row, target) {
|
|
15368
15530
|
const deleteStatements = buildRemovedKindLiveDeleteStatements(ctx, row);
|
|
15369
15531
|
if (!ctx.captureRecordedRemovals || ctx.recordedSchema === void 0) {
|
|
15370
|
-
await executeDeleteStatements(
|
|
15532
|
+
await executeDeleteStatements(target, deleteStatements);
|
|
15371
15533
|
return;
|
|
15372
15534
|
}
|
|
15373
15535
|
const recordedSchema = ctx.recordedSchema;
|
|
15374
|
-
|
|
15375
|
-
|
|
15376
|
-
|
|
15377
|
-
|
|
15378
|
-
|
|
15379
|
-
|
|
15380
|
-
|
|
15381
|
-
|
|
15382
|
-
|
|
15383
|
-
|
|
15384
|
-
|
|
15385
|
-
} catch (error) {
|
|
15386
|
-
if (!isMissingTableError(error)) throw error;
|
|
15387
|
-
await executeDeleteStatements(ctx.backend, deleteStatements);
|
|
15536
|
+
const requiredRecordedTables = [
|
|
15537
|
+
recordedSchema.tables.recordedClock,
|
|
15538
|
+
recordedSchema.tables.recordedEdges,
|
|
15539
|
+
...row.entity === "node" ? [recordedSchema.tables.recordedNodes] : []
|
|
15540
|
+
];
|
|
15541
|
+
const recordedTablesExist = await Promise.all(
|
|
15542
|
+
requiredRecordedTables.map((tableName) => target.tableExists(tableName))
|
|
15543
|
+
);
|
|
15544
|
+
if (recordedTablesExist.some((exists) => !exists)) {
|
|
15545
|
+
await executeDeleteStatements(target, deleteStatements);
|
|
15546
|
+
return;
|
|
15388
15547
|
}
|
|
15548
|
+
await closeRecordedHardDeletedKind(
|
|
15549
|
+
target,
|
|
15550
|
+
recordedSchema,
|
|
15551
|
+
ctx.graphId,
|
|
15552
|
+
{ entity: row.entity, kind: row.kindName },
|
|
15553
|
+
false
|
|
15554
|
+
);
|
|
15555
|
+
await executeDeleteStatements(target, deleteStatements);
|
|
15389
15556
|
}
|
|
15390
15557
|
function buildRemovedKindLiveDeleteStatements(ctx, row) {
|
|
15391
15558
|
const graphLit = literal(ctx.graphId);
|
|
@@ -15403,41 +15570,22 @@ function buildRemovedKindLiveDeleteStatements(ctx, row) {
|
|
|
15403
15570
|
];
|
|
15404
15571
|
}
|
|
15405
15572
|
async function executeDeleteStatements(target, statements) {
|
|
15406
|
-
|
|
15407
|
-
await
|
|
15408
|
-
statements.map(
|
|
15409
|
-
(statement) => requireDefined(target.executeStatement)(
|
|
15410
|
-
asCompiledStatementSql(sql.raw(statement))
|
|
15411
|
-
)
|
|
15412
|
-
)
|
|
15413
|
-
);
|
|
15414
|
-
return;
|
|
15415
|
-
}
|
|
15416
|
-
if (target.executeDdl === void 0) {
|
|
15417
|
-
throw new ConfigurationError(
|
|
15418
|
-
"store.materializeRemovals() requires a backend that can execute cleanup statements.",
|
|
15419
|
-
{ code: "MATERIALIZE_REMOVALS_BACKEND_UNSUPPORTED" }
|
|
15420
|
-
);
|
|
15573
|
+
for (const statement of statements) {
|
|
15574
|
+
await target.executeStatement(asCompiledStatementSql(sql.raw(statement)));
|
|
15421
15575
|
}
|
|
15422
|
-
await Promise.all(
|
|
15423
|
-
statements.map((statement) => requireDefined(target.executeDdl)(statement))
|
|
15424
|
-
);
|
|
15425
15576
|
}
|
|
15426
|
-
function
|
|
15577
|
+
async function dropEmbeddingTableStorage(ctx, row, target) {
|
|
15427
15578
|
const vectorStrategy = ctx.backend.vectorStrategy;
|
|
15428
|
-
if (vectorStrategy === void 0) return
|
|
15429
|
-
const executeDdl =
|
|
15430
|
-
const
|
|
15431
|
-
|
|
15432
|
-
|
|
15433
|
-
|
|
15434
|
-
|
|
15435
|
-
|
|
15436
|
-
);
|
|
15437
|
-
})();
|
|
15438
|
-
return [cleanup];
|
|
15579
|
+
if (vectorStrategy === void 0) return;
|
|
15580
|
+
const executeDdl = target.executeSchemaDdl;
|
|
15581
|
+
const deleteContribution = target.deleteSchemaVectorSlotContribution;
|
|
15582
|
+
const slots = await resolveRemovedKindEmbeddingSlots(target, row);
|
|
15583
|
+
for (const slot of slots) {
|
|
15584
|
+
await dropVectorSlotStorage(vectorStrategy, executeDdl, slot);
|
|
15585
|
+
await deleteContribution(slot);
|
|
15586
|
+
}
|
|
15439
15587
|
}
|
|
15440
|
-
async function dropVectorSlotStorage(
|
|
15588
|
+
async function dropVectorSlotStorage(strategy, executeDdl, slot) {
|
|
15441
15589
|
try {
|
|
15442
15590
|
for (const ddl of strategy.buildDropStorage(slot)) {
|
|
15443
15591
|
await executeDdl(ddl);
|
|
@@ -15445,7 +15593,6 @@ async function dropVectorSlotStorage(backend, strategy, executeDdl, slot) {
|
|
|
15445
15593
|
} catch (error) {
|
|
15446
15594
|
if (!isMissingTableError(error)) throw error;
|
|
15447
15595
|
}
|
|
15448
|
-
await backend.deleteVectorSlotContribution?.(slot);
|
|
15449
15596
|
}
|
|
15450
15597
|
async function resolveRemovedKindEmbeddingSlots(backend, row) {
|
|
15451
15598
|
const priorVersion = row.schemaVersion - 1;
|
|
@@ -15471,26 +15618,26 @@ async function resolveRemovedKindEmbeddingSlots(backend, row) {
|
|
|
15471
15618
|
function vectorFieldKey(kind, fieldPath) {
|
|
15472
15619
|
return `${kind}\0${fieldPath}`;
|
|
15473
15620
|
}
|
|
15474
|
-
|
|
15621
|
+
function vectorFieldKeysFrom(schema) {
|
|
15622
|
+
const keys = /* @__PURE__ */ new Set();
|
|
15623
|
+
for (const declaration of schema.indexes ?? []) {
|
|
15624
|
+
if (declaration.entity === "vector") {
|
|
15625
|
+
keys.add(vectorFieldKey(declaration.kind, declaration.fieldPath));
|
|
15626
|
+
}
|
|
15627
|
+
}
|
|
15628
|
+
return keys;
|
|
15629
|
+
}
|
|
15630
|
+
async function reclaimRemovedVectorFieldTables(context, activeRow) {
|
|
15475
15631
|
const { backend, graphId } = context;
|
|
15476
15632
|
const vectorStrategy = backend.vectorStrategy;
|
|
15477
|
-
|
|
15478
|
-
if (vectorStrategy === void 0 || executeDdl === void 0) return [];
|
|
15479
|
-
const activeRow = await backend.getActiveSchema(graphId);
|
|
15633
|
+
if (vectorStrategy === void 0) return [];
|
|
15480
15634
|
if (activeRow === void 0) return [];
|
|
15481
15635
|
const cacheKey = `${graphId}\0${activeRow.version}`;
|
|
15482
15636
|
let perBackend = reclaimCache.get(backend);
|
|
15483
15637
|
const cached = perBackend?.get(cacheKey);
|
|
15484
15638
|
if (cached !== void 0) return cached;
|
|
15485
15639
|
const activeSchema = parseSerializedSchema(activeRow.schema_doc);
|
|
15486
|
-
const activeVectorFields =
|
|
15487
|
-
for (const declaration of activeSchema.indexes ?? []) {
|
|
15488
|
-
if (declaration.entity === "vector") {
|
|
15489
|
-
activeVectorFields.add(
|
|
15490
|
-
vectorFieldKey(declaration.kind, declaration.fieldPath)
|
|
15491
|
-
);
|
|
15492
|
-
}
|
|
15493
|
-
}
|
|
15640
|
+
const activeVectorFields = vectorFieldKeysFrom(activeSchema);
|
|
15494
15641
|
const survivingKinds = new Set(Object.keys(activeSchema.nodes));
|
|
15495
15642
|
const historical = /* @__PURE__ */ new Map();
|
|
15496
15643
|
for (let version = activeRow.version - 1; version >= 1; version -= 1) {
|
|
@@ -15519,14 +15666,43 @@ async function reclaimRemovedVectorFieldTables(context) {
|
|
|
15519
15666
|
(field2) => !activeVectorFields.has(vectorFieldKey(field2.kind, field2.fieldPath)) && survivingKinds.has(field2.kind)
|
|
15520
15667
|
);
|
|
15521
15668
|
const results = [];
|
|
15669
|
+
let skippedAfterLockedRecheck = false;
|
|
15670
|
+
const schemaWriteTransaction = backend.schemaWriteTransaction;
|
|
15671
|
+
if (orphans.length > 0 && schemaWriteTransaction === void 0) {
|
|
15672
|
+
throw new ConfigurationError(
|
|
15673
|
+
"store.materializeRemovals() requires a backend that can hold the schema-write lock across the vector-field liveness check and cleanup.",
|
|
15674
|
+
{ code: "MATERIALIZE_REMOVALS_SCHEMA_FENCE_UNSUPPORTED" }
|
|
15675
|
+
);
|
|
15676
|
+
}
|
|
15522
15677
|
for (const field2 of orphans) {
|
|
15523
15678
|
try {
|
|
15524
|
-
await
|
|
15525
|
-
|
|
15526
|
-
|
|
15527
|
-
|
|
15528
|
-
|
|
15679
|
+
const reclaimed = await requireDefined(schemaWriteTransaction)(
|
|
15680
|
+
graphId,
|
|
15681
|
+
async (target) => {
|
|
15682
|
+
const lockedActiveRow = await target.getActiveSchema(graphId);
|
|
15683
|
+
if (lockedActiveRow === void 0) return false;
|
|
15684
|
+
const lockedActiveSchema = parseSerializedSchema(
|
|
15685
|
+
lockedActiveRow.schema_doc
|
|
15686
|
+
);
|
|
15687
|
+
const lockedVectorFields = vectorFieldKeysFrom(lockedActiveSchema);
|
|
15688
|
+
if (lockedVectorFields.has(
|
|
15689
|
+
vectorFieldKey(field2.kind, field2.fieldPath)
|
|
15690
|
+
) || !Object.hasOwn(lockedActiveSchema.nodes, field2.kind)) {
|
|
15691
|
+
return false;
|
|
15692
|
+
}
|
|
15693
|
+
await dropVectorSlotStorage(
|
|
15694
|
+
vectorStrategy,
|
|
15695
|
+
target.executeSchemaDdl,
|
|
15696
|
+
field2.slot
|
|
15697
|
+
);
|
|
15698
|
+
await target.deleteSchemaVectorSlotContribution(field2.slot);
|
|
15699
|
+
return true;
|
|
15700
|
+
}
|
|
15529
15701
|
);
|
|
15702
|
+
if (!reclaimed) {
|
|
15703
|
+
skippedAfterLockedRecheck = true;
|
|
15704
|
+
continue;
|
|
15705
|
+
}
|
|
15530
15706
|
results.push({
|
|
15531
15707
|
kind: field2.kind,
|
|
15532
15708
|
fieldPath: field2.fieldPath,
|
|
@@ -15541,7 +15717,7 @@ async function reclaimRemovedVectorFieldTables(context) {
|
|
|
15541
15717
|
});
|
|
15542
15718
|
}
|
|
15543
15719
|
}
|
|
15544
|
-
if (results.every((entry2) => entry2.status === "reclaimed")) {
|
|
15720
|
+
if (!skippedAfterLockedRecheck && results.every((entry2) => entry2.status === "reclaimed")) {
|
|
15545
15721
|
if (perBackend === void 0) {
|
|
15546
15722
|
perBackend = /* @__PURE__ */ new Map();
|
|
15547
15723
|
reclaimCache.set(backend, perBackend);
|
|
@@ -16211,7 +16387,7 @@ async function executeEdgeBulkGetOrCreateByEndpoints(ctx, kind, items, backend,
|
|
|
16211
16387
|
validatedProps,
|
|
16212
16388
|
matchOn
|
|
16213
16389
|
);
|
|
16214
|
-
const
|
|
16390
|
+
const endpointKey2 = buildEndpointPairKey(
|
|
16215
16391
|
item.fromKind,
|
|
16216
16392
|
item.fromId,
|
|
16217
16393
|
item.toKind,
|
|
@@ -16224,7 +16400,7 @@ async function executeEdgeBulkGetOrCreateByEndpoints(ctx, kind, items, backend,
|
|
|
16224
16400
|
toId: item.toId,
|
|
16225
16401
|
validatedProps,
|
|
16226
16402
|
compositeKey,
|
|
16227
|
-
endpointKey,
|
|
16403
|
+
endpointKey: endpointKey2,
|
|
16228
16404
|
...validFrom !== void 0 && { validFrom },
|
|
16229
16405
|
...validTo !== void 0 && { validTo }
|
|
16230
16406
|
});
|
|
@@ -16242,7 +16418,7 @@ async function executeEdgeBulkGetOrCreateByEndpoints(ctx, kind, items, backend,
|
|
|
16242
16418
|
}
|
|
16243
16419
|
async function fetchRowsByEndpoint(reader) {
|
|
16244
16420
|
const rowsByEndpoint = /* @__PURE__ */ new Map();
|
|
16245
|
-
for (const [
|
|
16421
|
+
for (const [endpointKey2, endpoint] of uniqueEndpoints) {
|
|
16246
16422
|
const rows = await reader.findEdgesByKind({
|
|
16247
16423
|
graphId: ctx.graphId,
|
|
16248
16424
|
kind,
|
|
@@ -16253,7 +16429,7 @@ async function executeEdgeBulkGetOrCreateByEndpoints(ctx, kind, items, backend,
|
|
|
16253
16429
|
excludeDeleted: false,
|
|
16254
16430
|
temporalMode: "includeTombstones"
|
|
16255
16431
|
});
|
|
16256
|
-
rowsByEndpoint.set(
|
|
16432
|
+
rowsByEndpoint.set(endpointKey2, rows);
|
|
16257
16433
|
}
|
|
16258
16434
|
return rowsByEndpoint;
|
|
16259
16435
|
}
|
|
@@ -16695,6 +16871,7 @@ var NODE_WRITE_INTENT_COUNTERS = {
|
|
|
16695
16871
|
create: countSingleWrite,
|
|
16696
16872
|
createFromRecord: countSingleWrite,
|
|
16697
16873
|
update: countSingleWrite,
|
|
16874
|
+
updateWhere: countSingleWrite,
|
|
16698
16875
|
delete: countSingleWrite,
|
|
16699
16876
|
hardDelete: countSingleWrite,
|
|
16700
16877
|
upsertById: countSingleWrite,
|
|
@@ -16875,6 +17052,10 @@ var CAUGHT_UP_VERB_DETAILS = {
|
|
|
16875
17052
|
reembed: {
|
|
16876
17053
|
phrase: "re-embed a vector field on",
|
|
16877
17054
|
code: "REEMBED_BEFORE_INITIALIZE"
|
|
17055
|
+
},
|
|
17056
|
+
repair: {
|
|
17057
|
+
phrase: "repair contributions for",
|
|
17058
|
+
code: "REPAIR_CONTRIBUTIONS_BEFORE_INITIALIZE"
|
|
16878
17059
|
}
|
|
16879
17060
|
};
|
|
16880
17061
|
var ROW_MAPPER_CONFIGS = {
|
|
@@ -16914,6 +17095,39 @@ function syncStoreReplacementRef(ref, replacement) {
|
|
|
16914
17095
|
if (ref === void 0) return;
|
|
16915
17096
|
ref.current = replacement;
|
|
16916
17097
|
}
|
|
17098
|
+
async function commitEvolvedSchemaWhenRequiredKindsAreEmpty(backend, graph, currentVersion, classification) {
|
|
17099
|
+
const result = await commitNewSchemaVersionIfKindsEmpty(
|
|
17100
|
+
backend,
|
|
17101
|
+
graph,
|
|
17102
|
+
currentVersion,
|
|
17103
|
+
classification.requireEmpty.map((entry2) => ({
|
|
17104
|
+
entity: entry2.entity,
|
|
17105
|
+
kind: entry2.kindName
|
|
17106
|
+
}))
|
|
17107
|
+
);
|
|
17108
|
+
if (result.status === "committed") return result.row;
|
|
17109
|
+
const populatedKeys = new Set(
|
|
17110
|
+
result.kinds.map((entry2) => `${entry2.entity}:${entry2.kind}`)
|
|
17111
|
+
);
|
|
17112
|
+
const nonEmpty = new Set(
|
|
17113
|
+
classification.requireEmpty.filter(
|
|
17114
|
+
(entry2) => populatedKeys.has(`${entry2.entity}:${entry2.kindName}`)
|
|
17115
|
+
)
|
|
17116
|
+
);
|
|
17117
|
+
const error = buildIncompatibleChangeError(
|
|
17118
|
+
classification,
|
|
17119
|
+
nonEmpty,
|
|
17120
|
+
graph.id
|
|
17121
|
+
);
|
|
17122
|
+
if (error !== void 0) throw error;
|
|
17123
|
+
throw new ConfigurationError(
|
|
17124
|
+
"Schema emptiness guard reported populated kinds that were not part of the compatibility classification.",
|
|
17125
|
+
{
|
|
17126
|
+
graphId: graph.id,
|
|
17127
|
+
populatedKinds: result.kinds.map((entry2) => entry2.kind)
|
|
17128
|
+
}
|
|
17129
|
+
);
|
|
17130
|
+
}
|
|
16917
17131
|
var StoreImplementation = class _StoreImplementation {
|
|
16918
17132
|
[STORE_RUNTIME];
|
|
16919
17133
|
#graph;
|
|
@@ -17206,8 +17420,9 @@ var StoreImplementation = class _StoreImplementation {
|
|
|
17206
17420
|
* `KindNotFoundError` when the kind is not registered.
|
|
17207
17421
|
*
|
|
17208
17422
|
* The dominant graph-extension-kind access pattern: `await store.evolve(...)`
|
|
17209
|
-
* returns
|
|
17210
|
-
* kind, and the null-check the optional variant requires
|
|
17423
|
+
* returns the Store for the resulting schema, the caller immediately
|
|
17424
|
+
* operates on the new kind, and the null-check the optional variant requires
|
|
17425
|
+
* is busywork.
|
|
17211
17426
|
*/
|
|
17212
17427
|
getNodeCollectionOrThrow(kind) {
|
|
17213
17428
|
const collection = this.getNodeCollection(kind);
|
|
@@ -17370,6 +17585,14 @@ var StoreImplementation = class _StoreImplementation {
|
|
|
17370
17585
|
executeCreateBatch: (inputs, backend) => executeNodeCreateBatch(ctx, inputs, backend),
|
|
17371
17586
|
executeCreateNoReturnBatch: (inputs, backend) => executeNodeCreateNoReturnBatch(ctx, inputs, backend),
|
|
17372
17587
|
executeUpdate: (input, backend, options) => executeNodeUpdate(ctx, { ...input, id: input.id }, backend, options),
|
|
17588
|
+
executeUpdateWhere: (kind, patch, candidateIds, candidateIdColumn, backend) => executeNodeUpdateWhere(
|
|
17589
|
+
ctx,
|
|
17590
|
+
kind,
|
|
17591
|
+
patch,
|
|
17592
|
+
candidateIds,
|
|
17593
|
+
candidateIdColumn,
|
|
17594
|
+
backend
|
|
17595
|
+
),
|
|
17373
17596
|
executeUpsertUpdate: (input, backend, options) => executeNodeUpsertUpdate(
|
|
17374
17597
|
ctx,
|
|
17375
17598
|
{ ...input, id: input.id },
|
|
@@ -17759,19 +17982,54 @@ var StoreImplementation = class _StoreImplementation {
|
|
|
17759
17982
|
}
|
|
17760
17983
|
// === Batch Query Execution ===
|
|
17761
17984
|
/**
|
|
17762
|
-
*
|
|
17985
|
+
* Runs several queries in sequence, returning a typed tuple. The portable
|
|
17986
|
+
* guarantee is N serialized query executions — never one round trip.
|
|
17987
|
+
*
|
|
17988
|
+
* **Cost.** At least one statement per query, sometimes two: a query whose
|
|
17989
|
+
* selective-field mapping falls back re-runs as a full fetch, and that
|
|
17990
|
+
* fallback is detected *after* the selective statement has already
|
|
17991
|
+
* executed. It clears the fast path, so a reused query instance pays the
|
|
17992
|
+
* double only once — but the builder is immutable, so a query rebuilt per
|
|
17993
|
+
* request pays it every request.
|
|
17994
|
+
*
|
|
17995
|
+
* With `backend.capabilities.transactions` the queries share one
|
|
17996
|
+
* transaction; how that reaches the wire is the adapter's business. A SQL
|
|
17997
|
+
* backend frames them with `begin`/`commit`, putting a networked one at
|
|
17998
|
+
* N+2 round trips *at best*, while Durable Objects use an ambient storage
|
|
17999
|
+
* transaction with no framing statements. Without transactions there is no
|
|
18000
|
+
* framing. Connection reuse is a separate question from transaction
|
|
18001
|
+
* support: the no-transaction path passes the same backend object, so an
|
|
18002
|
+
* adapter may reuse one client there too. The portable guarantee is only
|
|
18003
|
+
* that at most one query is in flight at a time.
|
|
17763
18004
|
*
|
|
17764
|
-
*
|
|
17765
|
-
*
|
|
18005
|
+
* **Not a snapshot — and there is no way to make it one.** PostgreSQL
|
|
18006
|
+
* defaults to read-committed isolation, so a later query can observe a
|
|
18007
|
+
* commit the earlier ones did not. `store.transaction()` takes an
|
|
18008
|
+
* `isolationLevel`, but its context exposes only `nodes` / `edges`: there is
|
|
18009
|
+
* no public way to run a fluent query or a batch inside a transaction, so a
|
|
18010
|
+
* snapshot across fluent queries is not available today. Collection reads
|
|
18011
|
+
* can have one — `store.transaction(fn, { isolationLevel: "repeatable_read" })`
|
|
18012
|
+
* reading through `tx.nodes` / `tx.edges` — but only where the backend has
|
|
18013
|
+
* transactions (others ignore the option entirely), and a history-enabled
|
|
18014
|
+
* store on PostgreSQL additionally requires `accessMode: "read_only"` or the
|
|
18015
|
+
* call throws.
|
|
17766
18016
|
*
|
|
17767
|
-
* **
|
|
17768
|
-
*
|
|
17769
|
-
*
|
|
17770
|
-
*
|
|
17771
|
-
*
|
|
17772
|
-
*
|
|
17773
|
-
*
|
|
17774
|
-
*
|
|
18017
|
+
* **Will not fix an N+1.** Serializing N queries does not reduce their
|
|
18018
|
+
* number. The alternatives are set-oriented or chunked rather than
|
|
18019
|
+
* fixed-cost: `.traverse()` compiles a whole chain to one statement;
|
|
18020
|
+
* `store.subgraph()` costs 2 statements on SQLite and 3 on PostgreSQL
|
|
18021
|
+
* however large the result; `getByIds()` issues one statement per
|
|
18022
|
+
* bind-limit chunk, falling back to one per distinct id where the backend
|
|
18023
|
+
* exposes no batch read; `bulkFindByIndex()` costs one probe plus that same
|
|
18024
|
+
* chunked hydration.
|
|
18025
|
+
*
|
|
18026
|
+
* **Versus `Promise.all`.** Workload- and adapter-dependent in both
|
|
18027
|
+
* directions. `Promise.all` overlaps its queries against a pool with idle
|
|
18028
|
+
* capacity, but it does not necessarily hold N connections, and against a
|
|
18029
|
+
* single client or a saturated pool it queues. `batch()` keeps at most one
|
|
18030
|
+
* query in flight, so it pays the sum of their latencies — but it can still
|
|
18031
|
+
* come out ahead where connection acquisition dominates. Measure rather
|
|
18032
|
+
* than assume.
|
|
17775
18033
|
*
|
|
17776
18034
|
* Read-only — use `bulkCreate`, `bulkInsert`, etc. for write batching.
|
|
17777
18035
|
*
|
|
@@ -17796,14 +18054,105 @@ var StoreImplementation = class _StoreImplementation {
|
|
|
17796
18054
|
*/
|
|
17797
18055
|
async batch(...queries) {
|
|
17798
18056
|
return runOptionallyInTransaction(this.#baseBackend, async (target) => {
|
|
18057
|
+
const queryBackend = this.#createHookedQueryBackend(target);
|
|
17799
18058
|
const results = [];
|
|
17800
18059
|
for (const query of queries) {
|
|
17801
|
-
const result = await query.executeOn(
|
|
18060
|
+
const result = await query.executeOn(queryBackend);
|
|
17802
18061
|
results.push(result);
|
|
17803
18062
|
}
|
|
17804
18063
|
return results;
|
|
17805
18064
|
});
|
|
17806
18065
|
}
|
|
18066
|
+
/**
|
|
18067
|
+
* Reads several edge kinds from heterogeneous source nodes with round trips
|
|
18068
|
+
* independent of the number of licensed edge/source-kind combinations.
|
|
18069
|
+
*
|
|
18070
|
+
* Results are flattened in source-group/id order. Repeated sources receive
|
|
18071
|
+
* independent edge arrays, and sources with no matching edges remain present
|
|
18072
|
+
* with an empty array. Inputs that exceed the backend bind budget are split
|
|
18073
|
+
* into source chunks without splitting one source across statements.
|
|
18074
|
+
*/
|
|
18075
|
+
async bulkFindEdgesFrom(params, options) {
|
|
18076
|
+
const sources = params.sources.flatMap(
|
|
18077
|
+
(group) => {
|
|
18078
|
+
if (!Object.hasOwn(this.#graph.nodes, group.kind)) {
|
|
18079
|
+
throw new KindNotFoundError(group.kind, "node", {
|
|
18080
|
+
graphId: this.graphId
|
|
18081
|
+
});
|
|
18082
|
+
}
|
|
18083
|
+
return group.ids.map((id) => ({ kind: group.kind, id }));
|
|
18084
|
+
}
|
|
18085
|
+
);
|
|
18086
|
+
for (const edgeKind of params.edgeKinds) {
|
|
18087
|
+
if (!Object.hasOwn(this.#graph.edges, edgeKind)) {
|
|
18088
|
+
throw new KindNotFoundError(edgeKind, "edge", {
|
|
18089
|
+
graphId: this.graphId
|
|
18090
|
+
});
|
|
18091
|
+
}
|
|
18092
|
+
}
|
|
18093
|
+
if (sources.length === 0 || params.edgeKinds.length === 0) {
|
|
18094
|
+
return sources.map((source) => ({ source, edges: [] }));
|
|
18095
|
+
}
|
|
18096
|
+
const readEndpointSet = this.#baseBackend.findEdgesByHeterogeneousEndpointSet;
|
|
18097
|
+
if (readEndpointSet === void 0) {
|
|
18098
|
+
throw new ConfigurationError(
|
|
18099
|
+
"store.bulkFindEdgesFrom() requires a backend that can read heterogeneous endpoint and edge-kind sets in set-oriented statements.",
|
|
18100
|
+
{
|
|
18101
|
+
backend: this.#baseBackend.dialect,
|
|
18102
|
+
capability: "findEdgesByHeterogeneousEndpointSet",
|
|
18103
|
+
operation: "bulkFindEdgesFrom"
|
|
18104
|
+
},
|
|
18105
|
+
{
|
|
18106
|
+
suggestion: "Use per-edge-kind bulkFindFrom calls explicitly if that round-trip tradeoff is acceptable."
|
|
18107
|
+
}
|
|
18108
|
+
);
|
|
18109
|
+
}
|
|
18110
|
+
const limitPerInput = options?.limitPerInput;
|
|
18111
|
+
if (limitPerInput !== void 0 && (!Number.isInteger(limitPerInput) || limitPerInput <= 0)) {
|
|
18112
|
+
throw new ValidationError(
|
|
18113
|
+
"bulk endpoint reads require limitPerInput to be a positive integer",
|
|
18114
|
+
{
|
|
18115
|
+
entityType: "edge",
|
|
18116
|
+
kind: params.edgeKinds.join(","),
|
|
18117
|
+
issues: [
|
|
18118
|
+
{
|
|
18119
|
+
path: "limitPerInput",
|
|
18120
|
+
message: `Expected a positive integer, received ${String(limitPerInput)}`,
|
|
18121
|
+
code: "invalid_value"
|
|
18122
|
+
}
|
|
18123
|
+
]
|
|
18124
|
+
}
|
|
18125
|
+
);
|
|
18126
|
+
}
|
|
18127
|
+
const temporal = resolveTemporalReadParams(
|
|
18128
|
+
options,
|
|
18129
|
+
this.#graph.defaults.temporalMode
|
|
18130
|
+
);
|
|
18131
|
+
const endpoints = sources;
|
|
18132
|
+
const rows = await readEndpointSet({
|
|
18133
|
+
graphId: this.graphId,
|
|
18134
|
+
side: "from",
|
|
18135
|
+
endpoints,
|
|
18136
|
+
edgeKinds: params.edgeKinds,
|
|
18137
|
+
...limitPerInput !== void 0 && this.#baseBackend.capabilities.windowFunctions && {
|
|
18138
|
+
limitPerEndpoint: limitPerInput
|
|
18139
|
+
},
|
|
18140
|
+
...temporal
|
|
18141
|
+
});
|
|
18142
|
+
const edgesBySource = /* @__PURE__ */ new Map();
|
|
18143
|
+
for (const row of rows) {
|
|
18144
|
+
const edge = rowToEdge(row);
|
|
18145
|
+
const key = `${edge.fromKind}\0${edge.fromId}`;
|
|
18146
|
+
const bucket = edgesBySource.get(key);
|
|
18147
|
+
if (bucket === void 0) edgesBySource.set(key, [edge]);
|
|
18148
|
+
else bucket.push(edge);
|
|
18149
|
+
}
|
|
18150
|
+
return sources.map((source) => {
|
|
18151
|
+
const bucket = edgesBySource.get(`${source.kind}\0${source.id}`) ?? [];
|
|
18152
|
+
const edges = limitPerInput === void 0 ? [...bucket] : bucket.slice(0, limitPerInput);
|
|
18153
|
+
return { source, edges };
|
|
18154
|
+
});
|
|
18155
|
+
}
|
|
17807
18156
|
// === Subgraph Extraction ===
|
|
17808
18157
|
/**
|
|
17809
18158
|
* Extracts a typed subgraph by traversing from a root node.
|
|
@@ -17945,6 +18294,7 @@ var StoreImplementation = class _StoreImplementation {
|
|
|
17945
18294
|
}
|
|
17946
18295
|
const pending = [];
|
|
17947
18296
|
const runHooks = this.#createBufferedHookRunner(pending);
|
|
18297
|
+
const runBulkHooks = this.#createBufferedBulkHookRunner(pending);
|
|
17948
18298
|
let recordedByGraph;
|
|
17949
18299
|
const transactionOptions = receiptRecorder !== void 0 && this.#captureEnabled ? withRecordedFlushObserver(backendOptions, (instants) => {
|
|
17950
18300
|
recordedByGraph = instants;
|
|
@@ -17955,7 +18305,8 @@ var StoreImplementation = class _StoreImplementation {
|
|
|
17955
18305
|
txBackend,
|
|
17956
18306
|
nativeTransaction,
|
|
17957
18307
|
runHooks,
|
|
17958
|
-
receiptRecorder
|
|
18308
|
+
receiptRecorder,
|
|
18309
|
+
runBulkHooks
|
|
17959
18310
|
)
|
|
17960
18311
|
);
|
|
17961
18312
|
const result = this.#captureEnabled || this.#adapterBackend === void 0 ? await this.#backend.transaction(
|
|
@@ -17966,9 +18317,16 @@ var StoreImplementation = class _StoreImplementation {
|
|
|
17966
18317
|
transactionOptions
|
|
17967
18318
|
);
|
|
17968
18319
|
for (const outcome of pending) {
|
|
17969
|
-
|
|
17970
|
-
|
|
17971
|
-
|
|
18320
|
+
if (outcome.type === "bulkOperation") {
|
|
18321
|
+
this.#hooks.onBulkOperationEnd?.(outcome.ctx, {
|
|
18322
|
+
affectedCount: outcome.affectedCount,
|
|
18323
|
+
durationMs: outcome.durationMs
|
|
18324
|
+
});
|
|
18325
|
+
} else {
|
|
18326
|
+
this.#hooks.onOperationEnd?.(outcome.ctx, {
|
|
18327
|
+
durationMs: outcome.durationMs
|
|
18328
|
+
});
|
|
18329
|
+
}
|
|
17972
18330
|
}
|
|
17973
18331
|
return { result, recordedByGraph };
|
|
17974
18332
|
} catch (error) {
|
|
@@ -18080,6 +18438,13 @@ var StoreImplementation = class _StoreImplementation {
|
|
|
18080
18438
|
const txBackend = adopt(externalTx);
|
|
18081
18439
|
if (this.#captureEnabled) {
|
|
18082
18440
|
await assertRecordedCaptureTransactionIsolation(txBackend);
|
|
18441
|
+
await lockSchemaVersionForStoreWrite(
|
|
18442
|
+
{
|
|
18443
|
+
graphId: this.graphId,
|
|
18444
|
+
schemaVersion: this.#schemaMetadata.schemaVersion
|
|
18445
|
+
},
|
|
18446
|
+
txBackend
|
|
18447
|
+
);
|
|
18083
18448
|
}
|
|
18084
18449
|
const scope = this.#captureEnabled ? createRecordedTransactionScope(txBackend, this.#sqlSchema()) : {
|
|
18085
18450
|
backend: txBackend,
|
|
@@ -18151,9 +18516,11 @@ var StoreImplementation = class _StoreImplementation {
|
|
|
18151
18516
|
* (#140); when history capture is enabled it is replaced with a fail-loud
|
|
18152
18517
|
* guard because raw graph writes would bypass recorded-time capture.
|
|
18153
18518
|
*/
|
|
18154
|
-
#buildTransactionContext(txBackend, sql2, runHooks = this.#immediateHookRunner(), receiptRecorder) {
|
|
18519
|
+
#buildTransactionContext(txBackend, sql2, runHooks = this.#immediateHookRunner(), receiptRecorder, runBulkHooks = this.#immediateBulkHookRunner()) {
|
|
18155
18520
|
const txNodeOperations = {
|
|
18156
|
-
...this.#buildNodeOperations(
|
|
18521
|
+
...this.#buildNodeOperations(
|
|
18522
|
+
this.#createNodeOperationContext(runHooks, runBulkHooks)
|
|
18523
|
+
),
|
|
18157
18524
|
createQuery: () => this.#createQueryForBackend(txBackend),
|
|
18158
18525
|
maybeRefreshStatisticsAfterBulk: void 0
|
|
18159
18526
|
};
|
|
@@ -18249,6 +18616,7 @@ var StoreImplementation = class _StoreImplementation {
|
|
|
18249
18616
|
};
|
|
18250
18617
|
await (this.#baseBackend.capabilities.transactions ? this.#baseBackend.transaction(async (tx) => doClear(tx)) : doClear(this.#baseBackend));
|
|
18251
18618
|
await this.#clearVectorStorage();
|
|
18619
|
+
this.#schemaMetadata = UNKNOWN_SCHEMA_METADATA;
|
|
18252
18620
|
this.#nodeCollections = void 0;
|
|
18253
18621
|
this.#edgeCollections = void 0;
|
|
18254
18622
|
this.#algorithms = void 0;
|
|
@@ -18320,12 +18688,14 @@ var StoreImplementation = class _StoreImplementation {
|
|
|
18320
18688
|
/**
|
|
18321
18689
|
* Evolves the graph at runtime by merging a graph extension into the
|
|
18322
18690
|
* current schema, atomically committing a new schema version, and
|
|
18323
|
-
* returning
|
|
18691
|
+
* returning the `Store` for the merged graph.
|
|
18324
18692
|
*
|
|
18325
18693
|
* The `Store` is immutable — its registry, collections, and operation
|
|
18326
|
-
* contexts close over the graph at construction time
|
|
18327
|
-
* must use the returned
|
|
18328
|
-
*
|
|
18694
|
+
* contexts close over the graph at construction time. After `evolve()`
|
|
18695
|
+
* resolves, callers must use the returned Store (or the re-pointed
|
|
18696
|
+
* `ref.current`) for every subsequent operation in the same request. A
|
|
18697
|
+
* Store captured before the schema commit remains pinned to the old version,
|
|
18698
|
+
* and its next managed write is rejected by the schema fence.
|
|
18329
18699
|
*
|
|
18330
18700
|
* **Cost for purely additive extensions is proportional to schema
|
|
18331
18701
|
* document size, not row count.** The commit is a single CAS write.
|
|
@@ -18343,10 +18713,10 @@ var StoreImplementation = class _StoreImplementation {
|
|
|
18343
18713
|
*
|
|
18344
18714
|
* @param extension - Graph extension produced by
|
|
18345
18715
|
* `defineGraphExtension(...)`.
|
|
18346
|
-
* @param options.ref - Optional handle whose `current` is overwritten
|
|
18347
|
-
*
|
|
18348
|
-
*
|
|
18349
|
-
*
|
|
18716
|
+
* @param options.ref - Optional handle whose `current` is overwritten with
|
|
18717
|
+
* the replacement before a successful call resolves. Code awaiting this
|
|
18718
|
+
* call can use the returned Store or `ref.current` immediately. A
|
|
18719
|
+
* previously captured Store is not mutated.
|
|
18350
18720
|
*
|
|
18351
18721
|
* @throws {GraphExtensionValidationError} when the extension is
|
|
18352
18722
|
* structurally invalid.
|
|
@@ -18385,6 +18755,7 @@ var StoreImplementation = class _StoreImplementation {
|
|
|
18385
18755
|
}
|
|
18386
18756
|
return caughtUp;
|
|
18387
18757
|
}
|
|
18758
|
+
await this.#assertNoPendingRemovalFor(merged, baseline);
|
|
18388
18759
|
const baselineDocument = baseline.extension ?? Object.freeze({});
|
|
18389
18760
|
const classification = classifyModifications(baselineDocument, extension);
|
|
18390
18761
|
if (classification.incompatible.length > 0) {
|
|
@@ -18393,20 +18764,12 @@ var StoreImplementation = class _StoreImplementation {
|
|
|
18393
18764
|
this.graphId
|
|
18394
18765
|
);
|
|
18395
18766
|
}
|
|
18396
|
-
|
|
18397
|
-
const nonEmpty = await this.#probeEmptyKinds(classification.requireEmpty);
|
|
18398
|
-
const error = buildIncompatibleChangeError(
|
|
18399
|
-
classification,
|
|
18400
|
-
nonEmpty,
|
|
18401
|
-
this.graphId
|
|
18402
|
-
);
|
|
18403
|
-
if (error !== void 0) throw error;
|
|
18404
|
-
}
|
|
18405
|
-
const committed = await commitNewSchemaVersion(
|
|
18767
|
+
const committed = classification.requireEmpty.length > 0 ? await commitEvolvedSchemaWhenRequiredKindsAreEmpty(
|
|
18406
18768
|
this.#backend,
|
|
18407
18769
|
merged,
|
|
18408
|
-
activeRow.version
|
|
18409
|
-
|
|
18770
|
+
activeRow.version,
|
|
18771
|
+
classification
|
|
18772
|
+
) : await commitNewSchemaVersion(this.#backend, merged, activeRow.version);
|
|
18410
18773
|
await materializeVectorContributions(this.#backend, merged);
|
|
18411
18774
|
const evolved = this.#cloneWithGraph(
|
|
18412
18775
|
merged,
|
|
@@ -18437,8 +18800,8 @@ var StoreImplementation = class _StoreImplementation {
|
|
|
18437
18800
|
* kind that's already marked is a no-op (no version bump).
|
|
18438
18801
|
*
|
|
18439
18802
|
* @param names - Node or edge kind names to mark as deprecated.
|
|
18440
|
-
* @param options.ref - Optional handle to be re-pointed
|
|
18441
|
-
*
|
|
18803
|
+
* @param options.ref - Optional handle to be re-pointed to the replacement
|
|
18804
|
+
* Store before a successful call resolves, mirroring `evolve()`.
|
|
18442
18805
|
*
|
|
18443
18806
|
* @throws {ConfigurationError} on `DEPRECATE_BEFORE_INITIALIZE` (no
|
|
18444
18807
|
* schema yet) or `DEPRECATE_UNKNOWN_KIND` (name not on the graph).
|
|
@@ -18459,8 +18822,8 @@ var StoreImplementation = class _StoreImplementation {
|
|
|
18459
18822
|
*
|
|
18460
18823
|
* @param names - Node or edge kind names to remove from the
|
|
18461
18824
|
* deprecated set.
|
|
18462
|
-
* @param options.ref - Optional handle to be re-pointed
|
|
18463
|
-
*
|
|
18825
|
+
* @param options.ref - Optional handle to be re-pointed to the replacement
|
|
18826
|
+
* Store before a successful call resolves.
|
|
18464
18827
|
*
|
|
18465
18828
|
* @throws {ConfigurationError} on `DEPRECATE_BEFORE_INITIALIZE`.
|
|
18466
18829
|
* @throws {StaleVersionError} on a CAS race with another writer.
|
|
@@ -18681,6 +19044,98 @@ var StoreImplementation = class _StoreImplementation {
|
|
|
18681
19044
|
}
|
|
18682
19045
|
return { recreated: true, reembedded };
|
|
18683
19046
|
}
|
|
19047
|
+
/**
|
|
19048
|
+
* Diagnostic: compare each contribution currently expected by this graph
|
|
19049
|
+
* and the backend strategies with its durable marker and the physical
|
|
19050
|
+
* catalog. Reports detected unusable contributions, including a recorded
|
|
19051
|
+
* failed materialization whose absent table agrees with the marker.
|
|
19052
|
+
* Contributions with neither marker nor table and retired marker rows are
|
|
19053
|
+
* omitted, so an empty array is not proof that storage was initialized.
|
|
19054
|
+
*
|
|
19055
|
+
* Opening a store never probes the catalog — `ensureRuntimeContributions`
|
|
19056
|
+
* and the runtime asserts short-circuit on a per-instance signature cache
|
|
19057
|
+
* and then on the marker row alone, which is the right default for a hot
|
|
19058
|
+
* path. The cost is that a database whose contribution tables were dropped
|
|
19059
|
+
* out of band (a partial restore, a hand-run `DROP`, a schema-scoped
|
|
19060
|
+
* restore that missed them) opens completely clean and then fails at the
|
|
19061
|
+
* first read of the affected slot. This is the explicit, operator-invoked
|
|
19062
|
+
* check for that state; it is not, and should not become, a boot step.
|
|
19063
|
+
*
|
|
19064
|
+
* Purely read-only: one existence query per distinct contribution table
|
|
19065
|
+
* plus one marker read per graph, no DDL and no writes, so it is safe to
|
|
19066
|
+
* run under a least-privilege runtime role and safe to run on a live
|
|
19067
|
+
* store. Each entry carries identity resolved from the active contribution
|
|
19068
|
+
* declaration and matching the marker contract, so callers can route to a
|
|
19069
|
+
* repair without reconstructing any internal naming contract.
|
|
19070
|
+
*
|
|
19071
|
+
* Route on `state`, NOT on whether the entry is a vector slot: the
|
|
19072
|
+
* repairs differ per state and the wrong one destroys data.
|
|
19073
|
+
* {@link Store.reembedVectorField} drops and recreates storage, so
|
|
19074
|
+
* applying it to a `missing-marker` — table intact, only the marker
|
|
19075
|
+
* wrong — discards every embedding to fix bookkeeping. See
|
|
19076
|
+
* {@link ContributionDiagnostic} and the per-state repair tables in the
|
|
19077
|
+
* troubleshooting guide.
|
|
19078
|
+
*
|
|
19079
|
+
* Vector slots are enumerated from the graph's declared embedding fields
|
|
19080
|
+
* and are considered only when the backend advertises vector support; a
|
|
19081
|
+
* backend without it never materialized them, so there is nothing to
|
|
19082
|
+
* compare. Current fulltext contributions are always considered. For a
|
|
19083
|
+
* readiness check, first construct the Store through a verified attach so
|
|
19084
|
+
* initialization is established independently.
|
|
19085
|
+
*
|
|
19086
|
+
* @throws {ConfigurationError} when the backend cannot probe its own
|
|
19087
|
+
* catalog. Reporting "no problems found" on a backend that never
|
|
19088
|
+
* looked would be the one answer this diagnostic must never give.
|
|
19089
|
+
*/
|
|
19090
|
+
async verifyContributions() {
|
|
19091
|
+
const backend = this.#baseBackend;
|
|
19092
|
+
const verify = backend.verifyContributions;
|
|
19093
|
+
if (verify === void 0) {
|
|
19094
|
+
throw new ConfigurationError(
|
|
19095
|
+
"verifyContributions requires a backend that can probe its catalog for contribution tables.",
|
|
19096
|
+
{
|
|
19097
|
+
backend: backend.dialect,
|
|
19098
|
+
capability: "contributions",
|
|
19099
|
+
operation: "verify"
|
|
19100
|
+
}
|
|
19101
|
+
);
|
|
19102
|
+
}
|
|
19103
|
+
const vectorSlots = backend.capabilities.vector?.supported === true ? resolveGraphVectorSlots(this.#graph) : [];
|
|
19104
|
+
return verify(this.graphId, vectorSlots);
|
|
19105
|
+
}
|
|
19106
|
+
/**
|
|
19107
|
+
* Non-destructively repairs contribution states whose physical storage can
|
|
19108
|
+
* be preserved: `missing-marker` and `failed-materialization`.
|
|
19109
|
+
* `orphaned-marker` and `stale` findings are returned as
|
|
19110
|
+
* `requires-rebuild`; this method never drops contribution tables or
|
|
19111
|
+
* fabricates the data needed to rebuild them.
|
|
19112
|
+
*
|
|
19113
|
+
* The repair re-audits inside the backend and resolves every declaration
|
|
19114
|
+
* from the committed schema. Callers do not supply diagnostics, physical
|
|
19115
|
+
* names, or DDL. A stale Store is caught up to the active persisted graph
|
|
19116
|
+
* before its vector slots are enumerated, so repair does not use declarations
|
|
19117
|
+
* from the Store's stale in-memory graph snapshot.
|
|
19118
|
+
*
|
|
19119
|
+
* @throws {ConfigurationError} when no schema has been initialized or the
|
|
19120
|
+
* backend cannot probe and repair strategy-owned contributions.
|
|
19121
|
+
*/
|
|
19122
|
+
async repairContributions() {
|
|
19123
|
+
const backend = this.#baseBackend;
|
|
19124
|
+
const repair = backend.repairContributions;
|
|
19125
|
+
if (repair === void 0) {
|
|
19126
|
+
throw new ConfigurationError(
|
|
19127
|
+
"repairContributions requires a backend that can probe and repair strategy-owned contribution tables.",
|
|
19128
|
+
{
|
|
19129
|
+
backend: backend.dialect,
|
|
19130
|
+
capability: "contributions",
|
|
19131
|
+
operation: "repair"
|
|
19132
|
+
}
|
|
19133
|
+
);
|
|
19134
|
+
}
|
|
19135
|
+
const { baseline } = await this.#loadCaughtUp("repair");
|
|
19136
|
+
const vectorSlots = backend.capabilities.vector?.supported === true ? resolveGraphVectorSlots(baseline) : [];
|
|
19137
|
+
return repair(this.graphId, vectorSlots);
|
|
19138
|
+
}
|
|
18684
19139
|
/**
|
|
18685
19140
|
* Removes extension kinds from the schema with cascading edge and
|
|
18686
19141
|
* ontology cleanup. Two-phase by design:
|
|
@@ -18735,9 +19190,10 @@ var StoreImplementation = class _StoreImplementation {
|
|
|
18735
19190
|
);
|
|
18736
19191
|
const recordKindRemoval = this.#backend.recordKindRemoval;
|
|
18737
19192
|
if (recordKindRemoval !== void 0) {
|
|
18738
|
-
|
|
18739
|
-
|
|
18740
|
-
|
|
19193
|
+
await ensureFocusedStatusTable(
|
|
19194
|
+
this.#backend,
|
|
19195
|
+
this.#backend.ensureKindRemovalsTable
|
|
19196
|
+
);
|
|
18741
19197
|
const attemptedAt = nowIso();
|
|
18742
19198
|
const newSchemaVersion = committedRow.version;
|
|
18743
19199
|
const queue = (kindName, entity) => recordKindRemoval(
|
|
@@ -18861,42 +19317,40 @@ var StoreImplementation = class _StoreImplementation {
|
|
|
18861
19317
|
return { activeRow, storedSchema, baseline };
|
|
18862
19318
|
}
|
|
18863
19319
|
/**
|
|
18864
|
-
*
|
|
18865
|
-
* composite keys (`${entity}:${kindName}`) that have at least one
|
|
18866
|
-
* row — those entries need to be promoted from "allowed-on-empty"
|
|
18867
|
-
* to incompatible. Dispatches to `countNodesByKind` for `node`
|
|
18868
|
-
* entries and `countEdgesByKind` for `edge` entries (a single-
|
|
18869
|
-
* primitive probe would always return 0 for the wrong-entity case
|
|
18870
|
-
* and silently bypass the gate).
|
|
19320
|
+
* Refuses an evolve that re-adds a kind whose data cleanup is still pending.
|
|
18871
19321
|
*
|
|
18872
|
-
*
|
|
18873
|
-
*
|
|
18874
|
-
* previously-empty kind. The schema commit still succeeds (CAS
|
|
18875
|
-
* guards on schema version, not row count); the new schema rejects
|
|
18876
|
-
* the inserted row at next read, which the operator inspects and
|
|
18877
|
-
* either deletes or reverts. Rare in practice; tighter elimination
|
|
18878
|
-
* would require `SELECT FOR UPDATE` on the rows table, too
|
|
18879
|
-
* heavyweight for a millisecond-budget operation.
|
|
19322
|
+
* Returns silently on backends without the removal queue: they cannot have
|
|
19323
|
+
* a pending row, so there is nothing to conflict with.
|
|
18880
19324
|
*/
|
|
18881
|
-
async #
|
|
18882
|
-
const
|
|
18883
|
-
|
|
18884
|
-
|
|
18885
|
-
|
|
18886
|
-
|
|
18887
|
-
|
|
18888
|
-
|
|
18889
|
-
|
|
18890
|
-
|
|
18891
|
-
|
|
19325
|
+
async #assertNoPendingRemovalFor(merged, baseline) {
|
|
19326
|
+
const getPendingKindRemovals = this.#backend.getPendingKindRemovals;
|
|
19327
|
+
if (getPendingKindRemovals === void 0) return;
|
|
19328
|
+
const addedNodes = Object.keys(merged.nodes).filter(
|
|
19329
|
+
(kind) => !(kind in baseline.nodes)
|
|
19330
|
+
);
|
|
19331
|
+
const addedEdges = Object.keys(merged.edges).filter(
|
|
19332
|
+
(kind) => !(kind in baseline.edges)
|
|
19333
|
+
);
|
|
19334
|
+
if (addedNodes.length === 0 && addedEdges.length === 0) return;
|
|
19335
|
+
await ensureFocusedStatusTable(
|
|
19336
|
+
this.#backend,
|
|
19337
|
+
this.#backend.ensureKindRemovalsTable
|
|
19338
|
+
);
|
|
19339
|
+
const pending = await getPendingKindRemovals(this.graphId);
|
|
19340
|
+
if (pending.length === 0) return;
|
|
19341
|
+
const blocked = pending.filter(
|
|
19342
|
+
(row) => row.entity === "node" ? addedNodes.includes(row.kindName) : addedEdges.includes(row.kindName)
|
|
19343
|
+
);
|
|
19344
|
+
if (blocked.length === 0) return;
|
|
19345
|
+
const named = blocked.map((row) => `${row.entity} "${row.kindName}"`).join(", ");
|
|
19346
|
+
throw new ConfigurationError(
|
|
19347
|
+
`Cannot re-add ${named} for graph "${this.graphId}": the previous removal's data cleanup has not run, so the old rows are still in the database and would become visible again alongside the new ones. Run store.materializeRemovals() first, then evolve.`,
|
|
19348
|
+
{
|
|
19349
|
+
code: "KIND_READD_BLOCKED_BY_PENDING_REMOVAL",
|
|
19350
|
+
graphId: this.graphId,
|
|
19351
|
+
kinds: blocked.map((row) => row.kindName)
|
|
18892
19352
|
}
|
|
18893
19353
|
);
|
|
18894
|
-
const results = await Promise.all(probes);
|
|
18895
|
-
const nonEmpty = /* @__PURE__ */ new Set();
|
|
18896
|
-
for (const [entry2, count2] of results) {
|
|
18897
|
-
if (count2 > 0) nonEmpty.add(entry2);
|
|
18898
|
-
}
|
|
18899
|
-
return nonEmpty;
|
|
18900
19354
|
}
|
|
18901
19355
|
#cloneWithGraph(graph, ref, schemaMetadata = this.#schemaMetadata) {
|
|
18902
19356
|
const next = this.#adapterBackend === void 0 ? new _StoreImplementation(
|
|
@@ -18928,22 +19382,34 @@ var StoreImplementation = class _StoreImplementation {
|
|
|
18928
19382
|
#immediateHookRunner() {
|
|
18929
19383
|
return (ctx, fn) => this.#withOperationHooks(ctx, fn);
|
|
18930
19384
|
}
|
|
18931
|
-
#
|
|
19385
|
+
#immediateBulkHookRunner() {
|
|
19386
|
+
return (ctx, fn) => this.#withBulkOperationHooks(ctx, fn);
|
|
19387
|
+
}
|
|
19388
|
+
#createNodeOperationContext(runHooks = this.#immediateHookRunner(), runBulkHooks = this.#immediateBulkHookRunner()) {
|
|
18932
19389
|
return {
|
|
18933
19390
|
graph: this.#graph,
|
|
18934
19391
|
graphId: this.graphId,
|
|
19392
|
+
schemaVersion: this.#schemaMetadata.schemaVersion,
|
|
18935
19393
|
historyEnabled: this.#captureEnabled,
|
|
18936
19394
|
revisionTrackingEnabled: this.#revisionTrackingEnabled,
|
|
18937
19395
|
revisionSchema: this.#sqlSchema(),
|
|
18938
19396
|
registry: this.#registry,
|
|
18939
19397
|
createOperationContext: (operation, entity, kind, id) => this.#createOperationContext(operation, entity, kind, id),
|
|
18940
|
-
withOperationHooks: runHooks
|
|
19398
|
+
withOperationHooks: runHooks,
|
|
19399
|
+
createBulkOperationContext: (operation, kind) => ({
|
|
19400
|
+
...this.#createHookContext(),
|
|
19401
|
+
operation,
|
|
19402
|
+
entity: "node",
|
|
19403
|
+
kind
|
|
19404
|
+
}),
|
|
19405
|
+
withBulkOperationHooks: runBulkHooks
|
|
18941
19406
|
};
|
|
18942
19407
|
}
|
|
18943
19408
|
#createEdgeOperationContext(runHooks = this.#immediateHookRunner()) {
|
|
18944
19409
|
return {
|
|
18945
19410
|
graph: this.#graph,
|
|
18946
19411
|
graphId: this.graphId,
|
|
19412
|
+
schemaVersion: this.#schemaMetadata.schemaVersion,
|
|
18947
19413
|
historyEnabled: this.#captureEnabled,
|
|
18948
19414
|
revisionTrackingEnabled: this.#revisionTrackingEnabled,
|
|
18949
19415
|
revisionSchema: this.#sqlSchema(),
|
|
@@ -18953,6 +19419,57 @@ var StoreImplementation = class _StoreImplementation {
|
|
|
18953
19419
|
};
|
|
18954
19420
|
}
|
|
18955
19421
|
// === Internal: Hook Helpers ===
|
|
19422
|
+
/**
|
|
19423
|
+
* Decorates the query execution port so hooks observe each statement the
|
|
19424
|
+
* query builder submits to the backend. A selective-projection retry
|
|
19425
|
+
* therefore emits two independent start/end pairs with their actual SQL.
|
|
19426
|
+
*/
|
|
19427
|
+
#createHookedQueryBackend(backend) {
|
|
19428
|
+
if (this.#hooks.onQueryStart === void 0 && this.#hooks.onQueryEnd === void 0 && this.#hooks.onError === void 0) {
|
|
19429
|
+
return backend;
|
|
19430
|
+
}
|
|
19431
|
+
const executeRaw = backend.executeRaw;
|
|
19432
|
+
const compileSql = backend.compileSql;
|
|
19433
|
+
const projected = createGraphBackendProjection(backend);
|
|
19434
|
+
return {
|
|
19435
|
+
...projected,
|
|
19436
|
+
execute: (query) => {
|
|
19437
|
+
const compiled = compileSql === void 0 ? renderSql(query, backend.dialect) : compileSql(query);
|
|
19438
|
+
return this.#withQueryHooks(
|
|
19439
|
+
compiled.sql,
|
|
19440
|
+
compiled.params,
|
|
19441
|
+
() => backend.execute(query)
|
|
19442
|
+
);
|
|
19443
|
+
},
|
|
19444
|
+
...executeRaw === void 0 ? {} : {
|
|
19445
|
+
executeRaw: (sqlText, params) => this.#withQueryHooks(
|
|
19446
|
+
sqlText,
|
|
19447
|
+
params,
|
|
19448
|
+
() => executeRaw(sqlText, params)
|
|
19449
|
+
)
|
|
19450
|
+
}
|
|
19451
|
+
};
|
|
19452
|
+
}
|
|
19453
|
+
async #withQueryHooks(sql2, params, execute) {
|
|
19454
|
+
const ctx = {
|
|
19455
|
+
...this.#createHookContext(),
|
|
19456
|
+
sql: sql2,
|
|
19457
|
+
params
|
|
19458
|
+
};
|
|
19459
|
+
this.#hooks.onQueryStart?.(ctx);
|
|
19460
|
+
const startTime = Date.now();
|
|
19461
|
+
try {
|
|
19462
|
+
const rows = await execute();
|
|
19463
|
+
this.#hooks.onQueryEnd?.(ctx, {
|
|
19464
|
+
rowCount: rows.length,
|
|
19465
|
+
durationMs: Date.now() - startTime
|
|
19466
|
+
});
|
|
19467
|
+
return rows;
|
|
19468
|
+
} catch (error) {
|
|
19469
|
+
this.#hooks.onError?.(ctx, asError(error));
|
|
19470
|
+
throw error;
|
|
19471
|
+
}
|
|
19472
|
+
}
|
|
18956
19473
|
#createHookContext() {
|
|
18957
19474
|
return {
|
|
18958
19475
|
operationId: generateId(),
|
|
@@ -18983,6 +19500,21 @@ var StoreImplementation = class _StoreImplementation {
|
|
|
18983
19500
|
throw error;
|
|
18984
19501
|
}
|
|
18985
19502
|
}
|
|
19503
|
+
async #withBulkOperationHooks(ctx, fn) {
|
|
19504
|
+
this.#hooks.onBulkOperationStart?.(ctx);
|
|
19505
|
+
const startTime = Date.now();
|
|
19506
|
+
try {
|
|
19507
|
+
const result = await fn();
|
|
19508
|
+
this.#hooks.onBulkOperationEnd?.(ctx, {
|
|
19509
|
+
affectedCount: result.affectedCount,
|
|
19510
|
+
durationMs: Date.now() - startTime
|
|
19511
|
+
});
|
|
19512
|
+
return result;
|
|
19513
|
+
} catch (error) {
|
|
19514
|
+
this.#hooks.onError?.(ctx, asError(error));
|
|
19515
|
+
throw error;
|
|
19516
|
+
}
|
|
19517
|
+
}
|
|
18986
19518
|
/**
|
|
18987
19519
|
* A hook runner for operations that execute INSIDE an explicit
|
|
18988
19520
|
* `store.transaction`: `onOperationStart` (and a failed operation's
|
|
@@ -18999,7 +19531,31 @@ var StoreImplementation = class _StoreImplementation {
|
|
|
18999
19531
|
const startTime = Date.now();
|
|
19000
19532
|
try {
|
|
19001
19533
|
const result = await fn();
|
|
19002
|
-
pending.push({
|
|
19534
|
+
pending.push({
|
|
19535
|
+
type: "operation",
|
|
19536
|
+
ctx,
|
|
19537
|
+
durationMs: Date.now() - startTime
|
|
19538
|
+
});
|
|
19539
|
+
return result;
|
|
19540
|
+
} catch (error) {
|
|
19541
|
+
this.#hooks.onError?.(ctx, asError(error));
|
|
19542
|
+
throw error;
|
|
19543
|
+
}
|
|
19544
|
+
};
|
|
19545
|
+
}
|
|
19546
|
+
/** Buffered counterpart for set-based operations inside `transaction()`. */
|
|
19547
|
+
#createBufferedBulkHookRunner(pending) {
|
|
19548
|
+
return async (ctx, fn) => {
|
|
19549
|
+
this.#hooks.onBulkOperationStart?.(ctx);
|
|
19550
|
+
const startTime = Date.now();
|
|
19551
|
+
try {
|
|
19552
|
+
const result = await fn();
|
|
19553
|
+
pending.push({
|
|
19554
|
+
type: "bulkOperation",
|
|
19555
|
+
ctx,
|
|
19556
|
+
affectedCount: result.affectedCount,
|
|
19557
|
+
durationMs: Date.now() - startTime
|
|
19558
|
+
});
|
|
19003
19559
|
return result;
|
|
19004
19560
|
} catch (error) {
|
|
19005
19561
|
this.#hooks.onError?.(ctx, asError(error));
|
|
@@ -19034,13 +19590,14 @@ var StoreImplementation = class _StoreImplementation {
|
|
|
19034
19590
|
};
|
|
19035
19591
|
}
|
|
19036
19592
|
#createQueryForBackend(backend, sealedCoordinate) {
|
|
19593
|
+
const queryBackend = this.#createHookedQueryBackend(backend);
|
|
19037
19594
|
return createInternalQueryBuilder(
|
|
19038
19595
|
this.graphId,
|
|
19039
19596
|
this.#registry,
|
|
19040
19597
|
{
|
|
19041
19598
|
// TransactionBackend omits transaction/close, but query execution only needs
|
|
19042
19599
|
// the read-path/query capabilities shared with GraphBackend.
|
|
19043
|
-
backend,
|
|
19600
|
+
backend: queryBackend,
|
|
19044
19601
|
dialect: backend.dialect,
|
|
19045
19602
|
defaultTraversalExpansion: this.#defaultTraversalExpansion,
|
|
19046
19603
|
...this.#schema !== void 0 && { schema: this.#schema },
|
|
@@ -19353,5 +19910,5 @@ async function createVerifiedAdapterStore(graph, backend, options) {
|
|
|
19353
19910
|
}
|
|
19354
19911
|
|
|
19355
19912
|
export { ExecutableAggregateQuery, ExecutableQuery, MAX_EXPLICIT_RECURSIVE_DEPTH, MAX_RECURSIVE_DEPTH, PreparedQuery, QueryBuilder, RecordedStoreView, StoreSearch, StoreView, UnionableQuery, avg, composeFragments, count, countDistinct, countDistinctEdges, countEdges, createAdapterStore, createAdapterStoreWithSchema, createFragment, createQueryBuilder, createStore, createStoreWithSchema, createVerifiedAdapterStore, createVerifiedStore, defineSubgraphProject, field, having, havingEq, havingGt, havingGte, havingLt, havingLte, limitFragment, max, min, offsetFragment, orderByFragment, sum };
|
|
19356
|
-
//# sourceMappingURL=chunk-
|
|
19357
|
-
//# sourceMappingURL=chunk-
|
|
19913
|
+
//# sourceMappingURL=chunk-ID4WXTKL.js.map
|
|
19914
|
+
//# sourceMappingURL=chunk-ID4WXTKL.js.map
|