@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,10 +1,10 @@
|
|
|
1
|
-
import { G as GraphDef, E as EdgeKinds, N as NodeKinds, a as AllNodeTypes } from './define-graph-
|
|
2
|
-
import { R as RecordedInstant, d as ReadCoordinate } from './temporal-
|
|
3
|
-
import {
|
|
4
|
-
import { K as KindRegistry, S as SchemaManagerOptions,
|
|
1
|
+
import { G as GraphDef, E as EdgeKinds, N as NodeKinds, a as AllNodeTypes } from './define-graph-BGrJahvp.js';
|
|
2
|
+
import { R as RecordedInstant, d as ReadCoordinate } from './temporal-Bob6Nfbp.js';
|
|
3
|
+
import { cb as ValueType, cc as PredicateExpression, aC as FulltextQueryMode, cd as VectorMetricType, Q as QueryAst, J as JsonPointer, a4 as FieldRef, b3 as ParameterRef, d as NodeType, e as AnyEdgeType, a2 as EdgeType, bB as TraversalExpansion, z as GraphBackend, S as SqlDialect, bs as SqlSchema, ce as Traversal, cf as NodePredicate, cg as ProjectedField, b2 as OrderSpec, ch as AggregateOrderSpec, T as TemporalMode, ci as GroupBySpec, aL as HybridFusionOptions, aP as JsonPointerInput, cj as RecursiveCyclePolicy, a7 as TraversalDirection$1, E as EdgeRegistration, b0 as NodeId, by as TransactionBackend, a3 as AggregateExpr, bl as SortDirection, ak as CompiledSelectSql, F as FulltextStrategy, V as VectorStrategy, ck as VectorSlotMap, cl as RecordedReadBinding, cm as SelectiveField, cn as ComposableQuery, co as SetOperationType, cp as SetOperation, K as KindEntity, av as ExternalRecordedReadSource, cq as NodeRow, ar as EdgeId, cr as EdgeRow, N as NodeRegistration, bA as TransactionReadBackend, cs as VectorMetric, aU as KindAnnotations, _ as JsonSchema, bG as UniquenessScope, af as Collation, ae as Cardinality, au as EndpointExistence, G as GraphExtension, B as BackendCapabilities, C as ContributionDiagnostic, c as ContributionRepairResult, bz as TransactionOptions, A as AdapterBackend } from './types-Ch9a0Dx6.js';
|
|
4
|
+
import { K as KindRegistry, S as SchemaManagerOptions, b as SchemaValidationResult } from './manager-YoLEfcc1.js';
|
|
5
5
|
import { z } from 'zod';
|
|
6
|
-
import { S as SearchableMetadata, c as EmbeddingValue } from './searchable-
|
|
7
|
-
import { S as SchemaDiff, h as MaterializeIndexesOptions, M as MaterializeIndexesResult, j as MaterializeSystemIndexesOptions } from './materialize-indexes-
|
|
6
|
+
import { S as SearchableMetadata, c as EmbeddingValue } from './searchable-DLWEfC4a.js';
|
|
7
|
+
import { S as SchemaDiff, h as MaterializeIndexesOptions, M as MaterializeIndexesResult, j as MaterializeSystemIndexesOptions } from './materialize-indexes-Bhhyb1B3.js';
|
|
8
8
|
|
|
9
9
|
type FieldTypeInfo = Readonly<{
|
|
10
10
|
valueType: ValueType;
|
|
@@ -50,8 +50,10 @@ type Predicate = Readonly<{
|
|
|
50
50
|
* Creates a named parameter reference for prepared queries.
|
|
51
51
|
*
|
|
52
52
|
* Use with `query.prepare()` to create reusable parameterized queries.
|
|
53
|
-
*
|
|
54
|
-
*
|
|
53
|
+
* Supported in scalar comparison positions (eq, neq, gt, etc.), string
|
|
54
|
+
* operations, between bounds, and as the WHOLE list of `in()`/`notIn()` —
|
|
55
|
+
* `field.in(param("ids"))` bound to an array at execute time. A `param()`
|
|
56
|
+
* among the individual elements of a literal list is rejected.
|
|
55
57
|
*
|
|
56
58
|
* @example
|
|
57
59
|
* ```typescript
|
|
@@ -63,6 +65,18 @@ type Predicate = Readonly<{
|
|
|
63
65
|
*
|
|
64
66
|
* const results = await prepared.execute({ name: "Alice" });
|
|
65
67
|
* ```
|
|
68
|
+
*
|
|
69
|
+
* @example List-valued parameter — one compiled statement, any list length.
|
|
70
|
+
* ```typescript
|
|
71
|
+
* const byIds = store.query()
|
|
72
|
+
* .from("Person", "p")
|
|
73
|
+
* .whereNode("p", (p) => p.id.in(param("ids")))
|
|
74
|
+
* .select((ctx) => ctx.p)
|
|
75
|
+
* .prepare();
|
|
76
|
+
*
|
|
77
|
+
* await byIds.execute({ ids: ["a", "b"] });
|
|
78
|
+
* await byIds.execute({ ids: ["c"] });
|
|
79
|
+
* ```
|
|
66
80
|
*/
|
|
67
81
|
declare function param(name: string): ParameterRef;
|
|
68
82
|
/**
|
|
@@ -305,10 +319,17 @@ type DynamicSelectableEdge = Readonly<{
|
|
|
305
319
|
|
|
306
320
|
type QueryCoordinateState = "open" | "sealed";
|
|
307
321
|
/**
|
|
308
|
-
* A query
|
|
322
|
+
* A query deferred for execution inside a `store.batch()` call.
|
|
309
323
|
*
|
|
310
324
|
* Both `ExecutableQuery` and `UnionableQuery` satisfy this interface.
|
|
311
325
|
* The result type `R` is preserved per-query in the batch return tuple.
|
|
326
|
+
*
|
|
327
|
+
* Deferring costs nothing and saves nothing on its own: `store.batch()` runs
|
|
328
|
+
* each query as its own statement (sometimes two — see `ExecutableQuery`'s
|
|
329
|
+
* `executeOn`), so it does not fold these into a single round trip. Whether
|
|
330
|
+
* they share one connection is up to the adapter, not to
|
|
331
|
+
* `backend.capabilities.transactions` — see `store.batch()` for the full cost
|
|
332
|
+
* model.
|
|
312
333
|
*/
|
|
313
334
|
type BatchableQuery<R = unknown> = Readonly<{
|
|
314
335
|
executeOn: (backend: GraphBackend | TransactionBackend) => Promise<readonly R[]>;
|
|
@@ -417,8 +438,8 @@ type BaseFieldAccessor = Readonly<{
|
|
|
417
438
|
neq: (value: unknown) => Predicate;
|
|
418
439
|
isNull: () => Predicate;
|
|
419
440
|
isNotNull: () => Predicate;
|
|
420
|
-
in: (values: readonly unknown[]) => Predicate;
|
|
421
|
-
notIn: (values: readonly unknown[]) => Predicate;
|
|
441
|
+
in: (values: readonly unknown[] | ParameterRef) => Predicate;
|
|
442
|
+
notIn: (values: readonly unknown[] | ParameterRef) => Predicate;
|
|
422
443
|
}>;
|
|
423
444
|
type StringFieldAccessor = BaseFieldAccessor & Readonly<{
|
|
424
445
|
gt: (value: string | ParameterRef) => Predicate;
|
|
@@ -744,2075 +765,2234 @@ type CreateQueryBuilderOptions = Readonly<{
|
|
|
744
765
|
}>;
|
|
745
766
|
|
|
746
767
|
/**
|
|
747
|
-
*
|
|
748
|
-
*
|
|
749
|
-
* The live NodeCollection / EdgeCollection partition into buckets a StoreView
|
|
750
|
-
* treats differently:
|
|
751
|
-
*
|
|
752
|
-
* - temporal reads honor the pinned coordinate;
|
|
753
|
-
* - current reads have no temporal axis and are refused on temporal pins;
|
|
754
|
-
* - writes are never available on a read-only view; and
|
|
755
|
-
* - batch reads require store.batch() and are absent from a view.
|
|
756
|
-
*
|
|
757
|
-
* These arrays are the single runtime source of truth for the proxy routing and
|
|
758
|
-
* the type-level source for the derived StoreView collection types. The
|
|
759
|
-
* StoreView surface-classification test asserts they exactly partition the live
|
|
760
|
-
* collection methods so new collection methods cannot be silently omitted.
|
|
761
|
-
*/
|
|
762
|
-
/** Temporal-aware node read method names. */
|
|
763
|
-
declare const NODE_TEMPORAL_READ_NAMES: readonly ["getById", "getByIds", "find", "count"];
|
|
764
|
-
/** Current-state-only node reads (constraint / index lookups). */
|
|
765
|
-
declare const CURRENT_ONLY_READ_NAMES: readonly ["findByConstraint", "bulkFindByConstraint", "bulkFindByIndex"];
|
|
766
|
-
/** Node write method names: never available on a read-only StoreView. */
|
|
767
|
-
declare const NODE_WRITE_NAMES: readonly ["create", "createFromRecord", "update", "delete", "hardDelete", "upsertById", "upsertByIdFromRecord", "bulkCreate", "bulkUpsertById", "bulkInsert", "bulkDelete", "getOrCreateByConstraint", "bulkGetOrCreateByConstraint"];
|
|
768
|
-
/** Temporal-aware edge read method names. */
|
|
769
|
-
declare const EDGE_TEMPORAL_READ_NAMES: readonly ["getById", "getByIds", "find", "count", "findFrom", "findTo", "findByEndpoints"];
|
|
770
|
-
/** Deferred edge batch-read method names. */
|
|
771
|
-
declare const EDGE_BATCH_READ_NAMES: readonly ["batchFindFrom", "batchFindTo", "batchFindByEndpoints"];
|
|
772
|
-
/** Edge write method names: never available on a read-only StoreView. */
|
|
773
|
-
declare const EDGE_WRITE_NAMES: readonly ["create", "update", "delete", "hardDelete", "bulkCreate", "bulkUpsertById", "bulkInsert", "bulkDelete", "getOrCreateByEndpoints", "bulkGetOrCreateByEndpoints"];
|
|
774
|
-
/** Recorded-time collection point reads that reconstruct safely by id. */
|
|
775
|
-
declare const RECORDED_POINT_READ_NAMES: readonly ["getById", "getByIds"];
|
|
776
|
-
|
|
777
|
-
/**
|
|
778
|
-
* Store types for TypeGraph operations.
|
|
768
|
+
* ExecutableAggregateQuery - A query with aggregate functions that can be executed.
|
|
779
769
|
*/
|
|
780
770
|
|
|
781
771
|
/**
|
|
782
|
-
*
|
|
783
|
-
*
|
|
784
|
-
* This is the single source of truth for which row columns become metadata.
|
|
785
|
-
* Both the Meta types and the row-to-meta functions in row-mappers.ts must
|
|
786
|
-
* stay in sync with this mapping. If you add a temporal/audit column to a
|
|
787
|
-
* row type, add the mapping here — the compiler will then force you to
|
|
788
|
-
* update the row mapper functions as well (since their return type is
|
|
789
|
-
* NodeMeta/EdgeMeta, which is derived from this mapping).
|
|
772
|
+
* Result type for aggregate queries.
|
|
773
|
+
* Maps field refs to their value types and aggregates to numbers.
|
|
790
774
|
*/
|
|
791
|
-
type
|
|
792
|
-
|
|
793
|
-
|
|
794
|
-
created_at: "createdAt";
|
|
795
|
-
updated_at: "updatedAt";
|
|
796
|
-
deleted_at: "deletedAt";
|
|
797
|
-
}>;
|
|
775
|
+
type AggregateResult<R extends Record<string, FieldRef | AggregateExpr>> = {
|
|
776
|
+
[K in keyof R]: R[K] extends AggregateExpr ? number : R[K] extends FieldRef ? unknown : never;
|
|
777
|
+
};
|
|
798
778
|
/**
|
|
799
|
-
*
|
|
779
|
+
* An aggregate query that can be executed.
|
|
800
780
|
*/
|
|
801
|
-
|
|
802
|
-
|
|
803
|
-
|
|
781
|
+
declare class ExecutableAggregateQuery<G extends GraphDef, Aliases extends AliasMap, R extends Record<string, FieldRef | AggregateExpr>> {
|
|
782
|
+
#private;
|
|
783
|
+
constructor(config: QueryBuilderConfig, state: QueryBuilderState, fields: R);
|
|
784
|
+
/**
|
|
785
|
+
* Builds the query AST.
|
|
786
|
+
*/
|
|
787
|
+
toAst(): QueryAst;
|
|
788
|
+
/**
|
|
789
|
+
* Orders results by a grouped field or aggregate alias.
|
|
790
|
+
*
|
|
791
|
+
* `key` is one of the output names passed to `.aggregate({...})` — either
|
|
792
|
+
* a grouped field (e.g. `genre`) or an aggregate alias (e.g. `bookCount`).
|
|
793
|
+
* Both are ordered the same way: by referencing the SELECT-list output
|
|
794
|
+
* column, since every `.aggregate()` field is projected with an alias.
|
|
795
|
+
*
|
|
796
|
+
* Chain multiple calls to sort by more than one key, in call order:
|
|
797
|
+
* `.orderBy("genre").orderBy("bookCount", "desc")` sorts by genre first,
|
|
798
|
+
* then by book count within each genre.
|
|
799
|
+
*
|
|
800
|
+
* @example
|
|
801
|
+
* ```typescript
|
|
802
|
+
* // Top 2 authors by book count
|
|
803
|
+
* store.query()
|
|
804
|
+
* .from("Author", "a")
|
|
805
|
+
* .traverse("wrote", "e")
|
|
806
|
+
* .to("Book", "b")
|
|
807
|
+
* .groupByNode("a")
|
|
808
|
+
* .aggregate({ author: field("a", "name"), bookCount: count("b") })
|
|
809
|
+
* .orderBy("bookCount", "desc")
|
|
810
|
+
* .limit(2)
|
|
811
|
+
* .execute();
|
|
812
|
+
* ```
|
|
813
|
+
*/
|
|
814
|
+
orderBy<K extends keyof R & string>(key: K, direction?: SortDirection): ExecutableAggregateQuery<G, Aliases, R>;
|
|
815
|
+
/**
|
|
816
|
+
* Limits the number of results.
|
|
817
|
+
*/
|
|
818
|
+
limit(n: number): ExecutableAggregateQuery<G, Aliases, R>;
|
|
819
|
+
/**
|
|
820
|
+
* Offsets the results.
|
|
821
|
+
*/
|
|
822
|
+
offset(n: number): ExecutableAggregateQuery<G, Aliases, R>;
|
|
823
|
+
/**
|
|
824
|
+
* Compiles the query and returns the SQL text and parameters.
|
|
825
|
+
*
|
|
826
|
+
* Requires a backend to be configured (the backend determines the SQL dialect).
|
|
827
|
+
* Use this for debugging, logging, or running the query with a custom executor.
|
|
828
|
+
*/
|
|
829
|
+
toSQL(): Readonly<{
|
|
830
|
+
sql: string;
|
|
831
|
+
params: readonly unknown[];
|
|
832
|
+
}>;
|
|
833
|
+
/**
|
|
834
|
+
* Compiles the query to TypeGraph's database-independent SQL fragment.
|
|
835
|
+
*/
|
|
836
|
+
compile(): CompiledSelectSql;
|
|
837
|
+
/**
|
|
838
|
+
* Executes the query and returns typed results.
|
|
839
|
+
*
|
|
840
|
+
* @throws Error if no backend is configured
|
|
841
|
+
*/
|
|
842
|
+
execute(): Promise<readonly AggregateResult<R>[]>;
|
|
843
|
+
}
|
|
844
|
+
|
|
804
845
|
/**
|
|
805
|
-
*
|
|
806
|
-
* Derived from NodeRow via TemporalMetaFieldMap + version.
|
|
846
|
+
* How a "current" valid-time read instant is emitted into compiled SQL:
|
|
807
847
|
*
|
|
808
|
-
*
|
|
809
|
-
*
|
|
810
|
-
*
|
|
811
|
-
*
|
|
848
|
+
* - `"literal"` — bound as a concrete value at compile time
|
|
849
|
+
* ({@link currentReadInstant}). The instant is frozen into the compiled
|
|
850
|
+
* statement, so the statement must be recompiled to observe a newer "now".
|
|
851
|
+
* - `"placeholder"` — bound as a reserved execution-time placeholder
|
|
852
|
+
* ({@link currentReadInstantPlaceholder}). The statement can be compiled
|
|
853
|
+
* once and reused across executions, filling a fresh instant each call.
|
|
854
|
+
*
|
|
855
|
+
* Defaults to `"literal"` everywhere except the query builder's compiled
|
|
856
|
+
* template cache, which opts into `"placeholder"` so a reused/prepared query
|
|
857
|
+
* never freezes "now" the way a cached literal would (the #246 regression).
|
|
812
858
|
*/
|
|
813
|
-
type
|
|
814
|
-
|
|
815
|
-
}>;
|
|
859
|
+
type ReadInstantMode = "literal" | "placeholder";
|
|
860
|
+
|
|
816
861
|
/**
|
|
817
|
-
*
|
|
862
|
+
* Query Compiler Module
|
|
818
863
|
*
|
|
819
|
-
*
|
|
820
|
-
* -
|
|
821
|
-
* - System metadata is under `node.meta.*`
|
|
864
|
+
* Main entry point for compiling query ASTs to SQL.
|
|
865
|
+
* Re-exports individual compiler modules and provides the main compile functions.
|
|
822
866
|
*/
|
|
823
|
-
|
|
824
|
-
kind: N["kind"];
|
|
825
|
-
id: NodeId<N>;
|
|
826
|
-
meta: NodeMeta;
|
|
827
|
-
}> & Readonly<z.infer<N["schema"]>>;
|
|
867
|
+
|
|
828
868
|
/**
|
|
829
|
-
*
|
|
869
|
+
* Options for query compilation.
|
|
830
870
|
*/
|
|
831
|
-
type
|
|
832
|
-
|
|
833
|
-
|
|
834
|
-
|
|
835
|
-
|
|
836
|
-
|
|
871
|
+
type CompileQueryOptions = Readonly<{
|
|
872
|
+
/** SQL dialect ("sqlite" or "postgres"). Defaults to "sqlite". */
|
|
873
|
+
dialect?: SqlDialect | undefined;
|
|
874
|
+
/** SQL schema configuration from createSqlSchema(...). Defaults to standard names. */
|
|
875
|
+
schema?: SqlSchema | undefined;
|
|
876
|
+
/**
|
|
877
|
+
* Fulltext strategy override. When set, overrides the dialect's
|
|
878
|
+
* default fulltext strategy for `$fulltext.matches()` compilation.
|
|
879
|
+
* Callers typically read this from `backend.fulltextStrategy` so a
|
|
880
|
+
* backend-declared strategy (e.g. ParadeDB) wins over the dialect
|
|
881
|
+
* default (tsvector).
|
|
882
|
+
*/
|
|
883
|
+
fulltextStrategy?: FulltextStrategy | undefined;
|
|
884
|
+
/**
|
|
885
|
+
* Vector strategy override. When set, `field.similarTo(...)`
|
|
886
|
+
* predicates compile against the strategy's per-`(kind, field)`
|
|
887
|
+
* tables and distance expression. Callers read it from
|
|
888
|
+
* `backend.vectorStrategy` so a backend-declared strategy (pgvector,
|
|
889
|
+
* libsql-native, sqlite-vec) drives the per-field relevance scan.
|
|
890
|
+
*/
|
|
891
|
+
vectorStrategy?: VectorStrategy | undefined;
|
|
892
|
+
/**
|
|
893
|
+
* Whether the active backend supports SQL window functions such as
|
|
894
|
+
* `ROW_NUMBER()`. Defaults to true for direct compiler callers.
|
|
895
|
+
*/
|
|
896
|
+
windowFunctions?: boolean | undefined;
|
|
897
|
+
/**
|
|
898
|
+
* Declared embedding slots `(kind, fieldPath) -> descriptor` used by
|
|
899
|
+
* the `field.similarTo(...)` CTE to know which kinds in an alias
|
|
900
|
+
* declare the field. Callers build it from the graph's node schemas.
|
|
901
|
+
*/
|
|
902
|
+
vectorSlots?: VectorSlotMap | undefined;
|
|
903
|
+
/** Per-kind declared fulltext language (see buildFulltextLanguages). */
|
|
904
|
+
fulltextLanguages?: ReadonlyMap<string, string> | undefined;
|
|
905
|
+
/**
|
|
906
|
+
* Recorded read relation to use when the AST carries `recordedAsOf`.
|
|
907
|
+
* Supplying a recorded timestamp without this binding is rejected so the
|
|
908
|
+
* compiler never silently swaps to TypeGraph's built-in history tables when
|
|
909
|
+
* the store was only configured for live/valid-time reads.
|
|
910
|
+
*/
|
|
911
|
+
recordedReadBinding?: RecordedReadBinding | undefined;
|
|
912
|
+
/**
|
|
913
|
+
* How the "current" valid-time read instant is emitted. Defaults to
|
|
914
|
+
* `"literal"` (a value frozen at compile time). The query builder's
|
|
915
|
+
* compiled template cache passes `"placeholder"` so the instant is a
|
|
916
|
+
* reserved execution-time slot, letting one compiled statement be reused
|
|
917
|
+
* across executions with a fresh "now" each call. See {@link ReadInstantMode}.
|
|
918
|
+
*/
|
|
919
|
+
readInstant?: ReadInstantMode | undefined;
|
|
837
920
|
}>;
|
|
921
|
+
|
|
838
922
|
/**
|
|
839
|
-
*
|
|
923
|
+
* PreparedQuery — a pre-validated, parameterized query.
|
|
924
|
+
*
|
|
925
|
+
* Created via `ExecutableQuery.prepare()`. Builds and structurally validates
|
|
926
|
+
* the query AST once at prepare time (so a malformed query fails fast, before
|
|
927
|
+
* the first `execute()`).
|
|
928
|
+
*
|
|
929
|
+
* Fast path: when the backend can compile and run raw SQL (`compileSql` +
|
|
930
|
+
* `executeRaw`) AND the statement is raw-executable, it is compiled ONCE
|
|
931
|
+
* into a cached template whose
|
|
932
|
+
* "current" read instant and user `param()` refs are reserved placeholders
|
|
933
|
+
* (see {@link buildReadInstantTemplate}). Every `execute()` fills those
|
|
934
|
+
* placeholders — a fresh instant plus the call's bindings — and runs the
|
|
935
|
+
* cached SQL text directly, so a reused prepared query never recompiles and
|
|
936
|
+
* never freezes "now" the way a cached literal instant would (the #246
|
|
937
|
+
* regression).
|
|
938
|
+
*
|
|
939
|
+
* Fallback: substitutes parameter refs into the AST, compiles fresh per call,
|
|
940
|
+
* and executes via the standard `backend.execute` path. Taken in two cases —
|
|
941
|
+
* a backend without raw execution (custom/async), and a statement that is not
|
|
942
|
+
* raw-executable because its execution semantics ride on the compiled SQL
|
|
943
|
+
* OBJECT rather than its text (approximate vector search's iterative-scan
|
|
944
|
+
* wrapper, `subgraph()`'s force-custom-plan fetches). The second applies even
|
|
945
|
+
* on PostgreSQL with `executeRaw` available; `isRawExecutable` in
|
|
946
|
+
* `sql-intent.ts` is the predicate that decides it.
|
|
840
947
|
*/
|
|
841
|
-
|
|
842
|
-
|
|
843
|
-
|
|
844
|
-
|
|
845
|
-
|
|
948
|
+
|
|
949
|
+
type PreparedQueryConfig<R> = Readonly<{
|
|
950
|
+
ast: QueryAst;
|
|
951
|
+
unoptimizedAst: QueryAst;
|
|
952
|
+
backend: GraphBackend;
|
|
953
|
+
dialect: SqlDialect;
|
|
954
|
+
graphId: string;
|
|
955
|
+
compileOptions: CompileQueryOptions;
|
|
956
|
+
state: QueryBuilderState;
|
|
957
|
+
selectiveFields: readonly SelectiveField[] | undefined;
|
|
958
|
+
selectFn: (context: SelectContext<AliasMap, EdgeAliasMap>) => R;
|
|
959
|
+
schemaIntrospector: SchemaIntrospector;
|
|
846
960
|
}>;
|
|
847
961
|
/**
|
|
848
|
-
*
|
|
849
|
-
*
|
|
850
|
-
|
|
851
|
-
type EdgeMeta = MapRowToMeta<EdgeRow, TemporalMetaFieldMap>;
|
|
852
|
-
/**
|
|
853
|
-
* An edge instance in the graph.
|
|
962
|
+
* A pre-validated, parameterized query — see the module doc comment above for
|
|
963
|
+
* how a reused prepared query runs a cached SQL template with a fresh read
|
|
964
|
+
* instant filled per call.
|
|
854
965
|
*
|
|
855
|
-
*
|
|
856
|
-
*
|
|
857
|
-
*
|
|
858
|
-
|
|
859
|
-
|
|
860
|
-
|
|
861
|
-
|
|
862
|
-
|
|
863
|
-
|
|
864
|
-
|
|
865
|
-
|
|
866
|
-
|
|
867
|
-
}> & Readonly<z.infer<E["schema"]>>;
|
|
868
|
-
/**
|
|
869
|
-
* Input for creating an edge.
|
|
870
|
-
*/
|
|
871
|
-
type CreateEdgeInput<E extends AnyEdgeType = EdgeType> = Readonly<{
|
|
872
|
-
kind: E["kind"];
|
|
873
|
-
id?: string;
|
|
874
|
-
fromKind: string;
|
|
875
|
-
fromId: string;
|
|
876
|
-
toKind: string;
|
|
877
|
-
toId: string;
|
|
878
|
-
props: z.infer<E["schema"]>;
|
|
879
|
-
validFrom?: string;
|
|
880
|
-
validTo?: string;
|
|
881
|
-
}>;
|
|
882
|
-
/**
|
|
883
|
-
* Input for updating an edge.
|
|
884
|
-
*/
|
|
885
|
-
type UpdateEdgeInput<E extends AnyEdgeType = EdgeType> = Readonly<{
|
|
886
|
-
id: EdgeId<E>;
|
|
887
|
-
props: Partial<z.infer<E["schema"]>>;
|
|
888
|
-
validTo?: string;
|
|
889
|
-
}>;
|
|
890
|
-
/**
|
|
891
|
-
* Options for node and edge queries.
|
|
966
|
+
* @example
|
|
967
|
+
* ```typescript
|
|
968
|
+
* const prepared = store.query()
|
|
969
|
+
* .from("Person", "p")
|
|
970
|
+
* .whereNode("p", (p) => p.name.eq(param("name")))
|
|
971
|
+
* .select((ctx) => ctx.p)
|
|
972
|
+
* .prepare();
|
|
973
|
+
*
|
|
974
|
+
* // Execute with different bindings
|
|
975
|
+
* const alice = await prepared.execute({ name: "Alice" });
|
|
976
|
+
* const bob = await prepared.execute({ name: "Bob" });
|
|
977
|
+
* ```
|
|
892
978
|
*/
|
|
893
|
-
|
|
979
|
+
declare class PreparedQuery<R> {
|
|
980
|
+
#private;
|
|
981
|
+
constructor(config: PreparedQueryConfig<R>);
|
|
982
|
+
/** The set of parameter names required by this prepared query. */
|
|
983
|
+
get parameterNames(): ReadonlySet<string>;
|
|
894
984
|
/**
|
|
895
|
-
*
|
|
896
|
-
*
|
|
897
|
-
*
|
|
985
|
+
* Executes the prepared query with the given parameter bindings.
|
|
986
|
+
*
|
|
987
|
+
* @param bindings - A record mapping parameter names to their values
|
|
988
|
+
* @returns The query results
|
|
898
989
|
*/
|
|
899
|
-
|
|
900
|
-
}
|
|
901
|
-
|
|
902
|
-
/** Temporal mode for the query */
|
|
903
|
-
temporalMode?: TemporalMode;
|
|
904
|
-
/** Specific timestamp for asOf queries */
|
|
905
|
-
asOf?: string;
|
|
906
|
-
}>;
|
|
907
|
-
/**
|
|
908
|
-
* Context passed to observability hooks.
|
|
909
|
-
*/
|
|
910
|
-
type HookContext = Readonly<{
|
|
911
|
-
/** Unique ID for this operation */
|
|
912
|
-
operationId: string;
|
|
913
|
-
/** Graph ID */
|
|
914
|
-
graphId: string;
|
|
915
|
-
/** Timestamp when operation started */
|
|
916
|
-
startedAt: Date;
|
|
917
|
-
}>;
|
|
990
|
+
execute(bindings?: Readonly<Record<string, unknown>>): Promise<readonly R[]>;
|
|
991
|
+
}
|
|
992
|
+
|
|
918
993
|
/**
|
|
919
|
-
*
|
|
994
|
+
* UnionableQuery - A query formed by combining multiple queries with set operations.
|
|
920
995
|
*/
|
|
921
|
-
|
|
922
|
-
|
|
923
|
-
|
|
924
|
-
|
|
925
|
-
params: readonly unknown[];
|
|
926
|
-
}>;
|
|
996
|
+
|
|
997
|
+
interface ExecutableQueryLike<G extends GraphDef, R> {
|
|
998
|
+
toAst(): QueryAst;
|
|
999
|
+
}
|
|
927
1000
|
/**
|
|
928
|
-
*
|
|
1001
|
+
* Internal state for unionable query.
|
|
929
1002
|
*/
|
|
930
|
-
type
|
|
931
|
-
|
|
932
|
-
|
|
933
|
-
|
|
934
|
-
|
|
935
|
-
|
|
936
|
-
|
|
937
|
-
|
|
938
|
-
|
|
1003
|
+
type UnionableQueryState = Readonly<{
|
|
1004
|
+
left: ComposableQuery;
|
|
1005
|
+
operator: SetOperationType;
|
|
1006
|
+
right: ComposableQuery;
|
|
1007
|
+
limit?: number;
|
|
1008
|
+
offset?: number;
|
|
1009
|
+
startAlias?: string;
|
|
1010
|
+
traversals?: readonly Traversal[];
|
|
1011
|
+
selectFn?: (context: SelectContext<AliasMap, EdgeAliasMap>) => unknown;
|
|
939
1012
|
}>;
|
|
940
|
-
|
|
941
|
-
|
|
942
|
-
|
|
943
|
-
* Note: Batch operations (`bulkCreate`, `bulkInsert`, `bulkUpsertById`) skip
|
|
944
|
-
* per-item operation hooks for throughput. Query hooks still fire normally.
|
|
945
|
-
*
|
|
946
|
-
* @example
|
|
947
|
-
* ```typescript
|
|
948
|
-
* const hooks: StoreHooks = {
|
|
949
|
-
* onQueryStart: (ctx) => {
|
|
950
|
-
* console.log(`[${ctx.operationId}] Query: ${ctx.sql}`);
|
|
951
|
-
* },
|
|
952
|
-
* onQueryEnd: (ctx, result) => {
|
|
953
|
-
* const duration = Date.now() - ctx.startedAt.getTime();
|
|
954
|
-
* console.log(`[${ctx.operationId}] Completed in ${duration}ms`);
|
|
955
|
-
* },
|
|
956
|
-
* onError: (ctx, error) => {
|
|
957
|
-
* console.error(`[${ctx.operationId}] Error:`, error);
|
|
958
|
-
* },
|
|
959
|
-
* };
|
|
960
|
-
*
|
|
961
|
-
* const store = createStore(graph, backend, { hooks });
|
|
962
|
-
* ```
|
|
963
|
-
*/
|
|
964
|
-
type StoreHooks = Readonly<{
|
|
965
|
-
/** Called before a query is executed */
|
|
966
|
-
onQueryStart?: (ctx: QueryHookContext) => void;
|
|
967
|
-
/** Called after a query completes successfully */
|
|
968
|
-
onQueryEnd?: (ctx: QueryHookContext, result: Readonly<{
|
|
969
|
-
rowCount: number;
|
|
970
|
-
durationMs: number;
|
|
971
|
-
}>) => void;
|
|
972
|
-
/** Called before a CRUD operation starts */
|
|
973
|
-
onOperationStart?: (ctx: OperationHookContext) => void;
|
|
1013
|
+
declare class UnionableQuery<G extends GraphDef, R> {
|
|
1014
|
+
#private;
|
|
1015
|
+
constructor(config: QueryBuilderConfig, state: UnionableQueryState);
|
|
974
1016
|
/**
|
|
975
|
-
*
|
|
976
|
-
* top-level operation that is when its own transaction commits; for an
|
|
977
|
-
* operation inside `store.transaction`, emission is deferred until the
|
|
978
|
-
* enclosing transaction commits — if that commit fails, the operation is
|
|
979
|
-
* reported through `onError` instead. (Inside an adopted transaction —
|
|
980
|
-
* `withTransaction` / `withRecordedTransaction` — the commit belongs to
|
|
981
|
-
* the caller and cannot be observed, so this fires when the operation
|
|
982
|
-
* completes within the still-open transaction.)
|
|
1017
|
+
* Combines with another query using UNION.
|
|
983
1018
|
*/
|
|
984
|
-
|
|
985
|
-
durationMs: number;
|
|
986
|
-
}>) => void;
|
|
1019
|
+
union(other: ExecutableQueryLike<G, R>): UnionableQuery<G, R>;
|
|
987
1020
|
/**
|
|
988
|
-
*
|
|
989
|
-
* inside a `store.transaction` whose commit then failed and rolled it
|
|
990
|
-
* back.
|
|
1021
|
+
* Combines with another query using UNION ALL.
|
|
991
1022
|
*/
|
|
992
|
-
|
|
993
|
-
}>;
|
|
994
|
-
type BaseStoreOptions = Readonly<{
|
|
995
|
-
/** Observability hooks for monitoring */
|
|
996
|
-
hooks?: StoreHooks;
|
|
1023
|
+
unionAll(other: ExecutableQueryLike<G, R>): UnionableQuery<G, R>;
|
|
997
1024
|
/**
|
|
998
|
-
*
|
|
999
|
-
* a random per-graph origin plus a monotonic revision clock. `branch()` uses
|
|
1000
|
-
* this anchor to validate that its base has not moved without
|
|
1001
|
-
* re-fingerprinting every live row, and cannot confuse a coincident clock in
|
|
1002
|
-
* a separately created store for its original base. `history: true` enables
|
|
1003
|
-
* the same tracking automatically through its recorded-time commit clock.
|
|
1004
|
-
*
|
|
1005
|
-
* This is intentionally opt-in for live stores: each successful graph write
|
|
1006
|
-
* advances the anchor inside its write transaction. On PostgreSQL, those
|
|
1007
|
-
* transactions take a graph-scoped advisory lock until commit; writes to the
|
|
1008
|
-
* same graph therefore serialize. Enable it for branchable graphs, but size
|
|
1009
|
-
* high-throughput multi-writer workloads for that trade-off.
|
|
1010
|
-
*
|
|
1011
|
-
* Writes performed directly through a backend — including raw graph-table
|
|
1012
|
-
* writes through `tx.sql` — bypass the anchor and are outside the
|
|
1013
|
-
* revision-tracking contract.
|
|
1025
|
+
* Combines with another query using INTERSECT.
|
|
1014
1026
|
*/
|
|
1015
|
-
|
|
1027
|
+
intersect(other: ExecutableQueryLike<G, R>): UnionableQuery<G, R>;
|
|
1016
1028
|
/**
|
|
1017
|
-
*
|
|
1018
|
-
* writes (bulkCreate and bulkInsert on nodes and edges). Stale statistics after a
|
|
1019
|
-
* bulk load are a whole class of planner cliffs: the planner keeps
|
|
1020
|
-
* pre-load row estimates until ANALYZE runs. When a single
|
|
1021
|
-
* autocommit bulk write reaches the threshold
|
|
1022
|
-
* ({@link AUTO_REFRESH_STATISTICS_ROW_THRESHOLD} rows by default),
|
|
1023
|
-
* the store runs `refreshStatistics()` after the write commits.
|
|
1024
|
-
* Pass a number to change the threshold, or `false` to disable.
|
|
1025
|
-
* Bulk writes inside a caller-provided transaction never
|
|
1026
|
-
* auto-refresh (statistics cannot see uncommitted rows); refresh
|
|
1027
|
-
* manually after commit. `importGraph` handles its own refresh.
|
|
1029
|
+
* Combines with another query using EXCEPT.
|
|
1028
1030
|
*/
|
|
1029
|
-
|
|
1031
|
+
except(other: ExecutableQueryLike<G, R>): UnionableQuery<G, R>;
|
|
1030
1032
|
/**
|
|
1031
|
-
*
|
|
1032
|
-
|
|
1033
|
-
|
|
1033
|
+
* Limits the number of results from the combined query.
|
|
1034
|
+
*/
|
|
1035
|
+
limit(n: number): UnionableQuery<G, R>;
|
|
1036
|
+
/**
|
|
1037
|
+
* Offsets the results from the combined query.
|
|
1038
|
+
*/
|
|
1039
|
+
offset(n: number): UnionableQuery<G, R>;
|
|
1040
|
+
/**
|
|
1041
|
+
* Builds the set operation AST.
|
|
1042
|
+
*/
|
|
1043
|
+
toAst(): SetOperation;
|
|
1044
|
+
/**
|
|
1045
|
+
* Compiles the query and returns the SQL text and parameters.
|
|
1034
1046
|
*
|
|
1035
|
-
*
|
|
1036
|
-
*
|
|
1037
|
-
|
|
1038
|
-
|
|
1039
|
-
|
|
1047
|
+
* Requires a backend to be configured (the backend determines the SQL dialect).
|
|
1048
|
+
* Use this for debugging, logging, or running the query with a custom executor.
|
|
1049
|
+
*/
|
|
1050
|
+
toSQL(): Readonly<{
|
|
1051
|
+
sql: string;
|
|
1052
|
+
params: readonly unknown[];
|
|
1053
|
+
}>;
|
|
1054
|
+
/**
|
|
1055
|
+
* Compiles the set operation to SQL.
|
|
1056
|
+
*/
|
|
1057
|
+
compile(): CompiledSelectSql;
|
|
1058
|
+
/**
|
|
1059
|
+
* Executes the combined query.
|
|
1060
|
+
*/
|
|
1061
|
+
execute(): Promise<readonly R[]>;
|
|
1062
|
+
/**
|
|
1063
|
+
* Executes the combined query against a provided backend.
|
|
1040
1064
|
*
|
|
1041
|
-
*
|
|
1042
|
-
*
|
|
1043
|
-
*
|
|
1044
|
-
* is a
|
|
1045
|
-
*
|
|
1046
|
-
* without churn. A rebuild that should avoid that re-walk belongs in a fresh
|
|
1047
|
-
* store — replay into it and publish it, rather than re-applying the log
|
|
1048
|
-
* over current state.
|
|
1049
|
-
*
|
|
1050
|
-
* When enabled, an upsert that would not change the stored value performs
|
|
1051
|
-
* **no write at all**: no `updateNode`, no recorded-time capture, no history
|
|
1052
|
-
* row, no revision-anchor advance, and no `update` operation hooks (nothing
|
|
1053
|
-
* happened, so nothing is reported). It resolves with the **existing** node,
|
|
1054
|
-
* preserving its original `validFrom` / `updatedAt` / `version`.
|
|
1055
|
-
*
|
|
1056
|
-
* Receipt shape is unchanged and needs no new signal: a coalesced upsert
|
|
1057
|
-
* still counts as one write intent (`writes.total` includes it), but
|
|
1058
|
-
* captures nothing (`receipt.recorded` stays `undefined` when it is the only
|
|
1059
|
-
* write) — the same shape a no-op delete already produces, so a consumer
|
|
1060
|
-
* that carries the prior anchor forward on `recorded === undefined` handles
|
|
1061
|
-
* it unchanged.
|
|
1062
|
-
*
|
|
1063
|
-
* A write is coalesced only when **all** of the following hold; otherwise the
|
|
1064
|
-
* normal write happens:
|
|
1065
|
-
* 1. An existing row is found for the id (else it is a create).
|
|
1066
|
-
* 2. That row is not soft-deleted (a deleted row resurrects — a real
|
|
1067
|
-
* change — and is never coalesced).
|
|
1068
|
-
* 3. The caller passed no explicit `validFrom` / `validTo` (an explicit
|
|
1069
|
-
* temporal override is a deliberate request and is never coalesced;
|
|
1070
|
-
* applied per item in the bulk path).
|
|
1071
|
-
* 4. The new props, merged over the stored props and run through the
|
|
1072
|
-
* kind's Zod schema (defaults applied, values normalized), are deeply
|
|
1073
|
-
* value-identical to the stored props (key order aside).
|
|
1074
|
-
*
|
|
1075
|
-
* Default-off because some consumers *want* an audit row per re-delivery as
|
|
1076
|
-
* proof the event was reprocessed; coalescing removes that signal.
|
|
1065
|
+
* Used by `store.batch()` to run several queries in sequence against one
|
|
1066
|
+
* target — a transaction on backends that have them, the backend itself
|
|
1067
|
+
* otherwise. A set operation compiles to one statement; whether that target
|
|
1068
|
+
* is a shared connection is the adapter's business, not a function of
|
|
1069
|
+
* transaction support.
|
|
1077
1070
|
*/
|
|
1078
|
-
|
|
1079
|
-
/** SQL schema configuration from createSqlSchema(...) for custom table names */
|
|
1080
|
-
schema?: SqlSchema;
|
|
1081
|
-
/** Query default behaviors. */
|
|
1082
|
-
queryDefaults?: Readonly<{
|
|
1083
|
-
/** Default traversal ontology expansion mode (default: "inverse"). */
|
|
1084
|
-
traversalExpansion?: TraversalExpansion;
|
|
1085
|
-
}>;
|
|
1086
|
-
}>;
|
|
1087
|
-
/**
|
|
1088
|
-
* Store options without built-in recorded-time capture. A recorded read relation
|
|
1089
|
-
* can still be bound explicitly for hosts that populate history externally.
|
|
1090
|
-
*/
|
|
1091
|
-
type LiveStoreOptions = BaseStoreOptions & Readonly<{
|
|
1092
|
-
history?: false | undefined;
|
|
1093
|
-
recordedRead?: ExternalRecordedReadSource | undefined;
|
|
1094
|
-
}>;
|
|
1095
|
-
/** Live-store options that do not bind a recorded-read relation. */
|
|
1096
|
-
type UnboundLiveStoreOptions = LiveStoreOptions & Readonly<{
|
|
1097
|
-
recordedRead?: undefined;
|
|
1098
|
-
}>;
|
|
1099
|
-
/** Live-store options with an explicitly bound recorded-read relation. */
|
|
1100
|
-
type RecordedReadStoreOptions = LiveStoreOptions & Readonly<{
|
|
1101
|
-
recordedRead: NonNullable<LiveStoreOptions["recordedRead"]>;
|
|
1102
|
-
}>;
|
|
1103
|
-
/**
|
|
1104
|
-
* Store options with TypeGraph-managed recorded-time capture. `history: true`
|
|
1105
|
-
* captures TypeGraph writes and binds TypeGraph's built-in recorded relation
|
|
1106
|
-
* internally. Externally populated recorded read sources are read-only bindings
|
|
1107
|
-
* and are intentionally accepted only by {@link LiveStoreOptions}.
|
|
1108
|
-
*/
|
|
1109
|
-
type HistoryStoreOptions = BaseStoreOptions & Readonly<{
|
|
1110
|
-
history: true;
|
|
1111
|
-
recordedRead?: never;
|
|
1112
|
-
}>;
|
|
1113
|
-
/**
|
|
1114
|
-
* Options for creating a store.
|
|
1115
|
-
*/
|
|
1116
|
-
type StoreOptions = LiveStoreOptions | HistoryStoreOptions;
|
|
1117
|
-
/**
|
|
1118
|
-
* A mutable handle to the current `Store`, used by `store.evolve(...)`
|
|
1119
|
-
* so long-lived consumers can dereference through the ref and pick up
|
|
1120
|
-
* the new store after each evolve call. `current` is overwritten by
|
|
1121
|
-
* `evolve()` atomically with the schema commit when the ref is passed
|
|
1122
|
-
* via `evolve(extension, { ref })`.
|
|
1123
|
-
*
|
|
1124
|
-
* **Mid-request semantics.** `ref.current` flips on the *next* call
|
|
1125
|
-
* after evolve, not mid-handler. Dereference once at request entry and
|
|
1126
|
-
* reuse the captured `Store` for the duration:
|
|
1127
|
-
*
|
|
1128
|
-
* ```ts
|
|
1129
|
-
* async function handleRequest(): Promise<void> {
|
|
1130
|
-
* const store = ref.current; // capture once
|
|
1131
|
-
* const tag = await store.nodes.Tag?.create({ label: "..." });
|
|
1132
|
-
* // ...further work on the same `store`...
|
|
1133
|
-
* }
|
|
1134
|
-
* ```
|
|
1135
|
-
*
|
|
1136
|
-
* Pure dereferenceable handle — no event/subscription machinery. If
|
|
1137
|
-
* consumers need eventing, they wrap the ref themselves.
|
|
1138
|
-
*
|
|
1139
|
-
* Generic over the held value (typically `Store<G>`) so the store
|
|
1140
|
-
* module can refer to it without importing the `Store` class into
|
|
1141
|
-
* `types.ts`. The type parameter is deliberately invariant: evolution writes
|
|
1142
|
-
* a replacement into `current`, so a ref for an adapter-only or history-only
|
|
1143
|
-
* Store must never be accepted by a Store that cannot preserve that surface.
|
|
1144
|
-
*/
|
|
1145
|
-
interface StoreRef<in out T> {
|
|
1146
|
-
current: T;
|
|
1071
|
+
executeOn(backend: GraphBackend | TransactionBackend): Promise<readonly R[]>;
|
|
1147
1072
|
}
|
|
1073
|
+
|
|
1148
1074
|
/**
|
|
1149
|
-
*
|
|
1150
|
-
* `store.withRecordedTransaction(externalTx, fn)` (the adopted-commit path), and
|
|
1151
|
-
* `tx.measure(fn)` (a scoped sub-receipt). See {@link TransactionReceipt}.
|
|
1075
|
+
* ExecutableQuery - A query that can be executed, paginated, or streamed.
|
|
1152
1076
|
*/
|
|
1153
|
-
|
|
1154
|
-
result: T;
|
|
1155
|
-
receipt: TransactionReceipt;
|
|
1156
|
-
}>;
|
|
1077
|
+
|
|
1157
1078
|
/**
|
|
1158
|
-
*
|
|
1159
|
-
*
|
|
1160
|
-
* Receipt counts are completed write intents at the collection surface, not
|
|
1161
|
-
* rows affected:
|
|
1162
|
-
*
|
|
1163
|
-
* 1. Every successful completion of a write method on `tx.nodes.*` /
|
|
1164
|
-
* `tx.edges.*` counts. The authoritative method list is
|
|
1165
|
-
* {@link NodeWrites} / {@link EdgeWrites}.
|
|
1166
|
-
* 2. Bulk methods count by input length; an empty bulk call (`bulkCreate([])`)
|
|
1167
|
-
* counts 0.
|
|
1168
|
-
* 3. Single-row methods count 1 on resolve — including `delete` of an absent
|
|
1169
|
-
* id and `getOrCreate*` that found an existing row. Consumers that need
|
|
1170
|
-
* "did anything actually change" semantics apply their own per-operation
|
|
1171
|
-
* policy.
|
|
1172
|
-
* 4. A method that rejects counts 0 — even when the backend applied part of a
|
|
1173
|
-
* bulk input before failing. On SQLite a failed statement does not abort
|
|
1174
|
-
* the surrounding transaction, so a caller that catches the rejection and
|
|
1175
|
-
* commits can persist rows the receipt never counted. Do not read the
|
|
1176
|
-
* receipt as rows-affected in that scenario.
|
|
1177
|
-
* 5. A node `delete` under `cascade` / `disconnect` removes connected edges
|
|
1178
|
-
* through the backend, not the edge-collection surface; those removals do
|
|
1179
|
-
* not appear in `edges`.
|
|
1180
|
-
* 6. Rows-affected fidelity is intentionally out of scope for this first
|
|
1181
|
-
* version; a future extension could ask backends to return row counts.
|
|
1079
|
+
* A query that can be executed.
|
|
1182
1080
|
*/
|
|
1183
|
-
|
|
1184
|
-
|
|
1185
|
-
|
|
1186
|
-
nodes: Readonly<Record<string, number>>;
|
|
1187
|
-
/** Completed edge write intents by edge kind. */
|
|
1188
|
-
edges: Readonly<Record<string, number>>;
|
|
1189
|
-
/** Sum of all node and edge write intents. */
|
|
1190
|
-
total: number;
|
|
1191
|
-
}>;
|
|
1081
|
+
declare class ExecutableQuery<G extends GraphDef, Aliases extends AliasMap, EdgeAliases extends EdgeAliasMap = {}, RecursiveAliases extends RecursiveAliasMap = {}, R = unknown> {
|
|
1082
|
+
#private;
|
|
1083
|
+
constructor(config: QueryBuilderConfig, state: QueryBuilderState, selectFunction: (context: SelectContext<Aliases, EdgeAliases, RecursiveAliases>) => R);
|
|
1192
1084
|
/**
|
|
1193
|
-
*
|
|
1194
|
-
* transaction. Undefined when history capture is off, the transaction is
|
|
1195
|
-
* read-only, or no captured writes were flushed. **Always undefined on a
|
|
1196
|
-
* scoped receipt from {@link ScopedMeasure}** (`tx.measure`) — the recorded
|
|
1197
|
-
* instant is a per-transaction flush concern allocated once when the whole
|
|
1198
|
-
* transaction's capture flushes, unknowable mid-transaction.
|
|
1085
|
+
* Builds the query AST (memoized — the instance is immutable).
|
|
1199
1086
|
*/
|
|
1200
|
-
|
|
1201
|
-
}>;
|
|
1202
|
-
/**
|
|
1203
|
-
* Behavior when a get-or-create operation matches an existing record.
|
|
1204
|
-
*/
|
|
1205
|
-
type IfExistsMode = "return" | "update";
|
|
1206
|
-
/**
|
|
1207
|
-
* Action taken by a get-or-create operation.
|
|
1208
|
-
*/
|
|
1209
|
-
type GetOrCreateAction = "created" | "found" | "updated" | "resurrected";
|
|
1210
|
-
/**
|
|
1211
|
-
* Result of a node getOrCreateByConstraint operation.
|
|
1212
|
-
*/
|
|
1213
|
-
type NodeGetOrCreateByConstraintResult<N extends NodeType> = Readonly<{
|
|
1214
|
-
node: Node<N>;
|
|
1215
|
-
action: GetOrCreateAction;
|
|
1216
|
-
}>;
|
|
1217
|
-
/**
|
|
1218
|
-
* Options for node getOrCreateByConstraint operations.
|
|
1219
|
-
*/
|
|
1220
|
-
type NodeGetOrCreateByConstraintOptions = Readonly<{
|
|
1221
|
-
/** Existing record behavior. Default: "return" */
|
|
1222
|
-
ifExists?: IfExistsMode;
|
|
1223
|
-
}>;
|
|
1224
|
-
/**
|
|
1225
|
-
* Options for node bulkFindByIndex operations.
|
|
1226
|
-
*/
|
|
1227
|
-
type NodeBulkFindByIndexOptions = Readonly<{
|
|
1087
|
+
toAst(): QueryAst;
|
|
1228
1088
|
/**
|
|
1229
|
-
*
|
|
1230
|
-
* each input's candidate set is unbounded. Must be a positive integer.
|
|
1231
|
-
*
|
|
1232
|
-
* Candidates are ordered deterministically by node id, so the cap is stable
|
|
1233
|
-
* across calls. Use this to bound fan-out on low-selectivity index keys.
|
|
1089
|
+
* Orders results.
|
|
1234
1090
|
*/
|
|
1235
|
-
|
|
1236
|
-
}>;
|
|
1237
|
-
/**
|
|
1238
|
-
* Result of an edge getOrCreateByEndpoints operation.
|
|
1239
|
-
*/
|
|
1240
|
-
type EdgeGetOrCreateByEndpointsResult<E extends AnyEdgeType, From extends NodeType = NodeType, To extends NodeType = NodeType> = Readonly<{
|
|
1241
|
-
edge: Edge<E, From, To>;
|
|
1242
|
-
action: GetOrCreateAction;
|
|
1243
|
-
}>;
|
|
1244
|
-
/**
|
|
1245
|
-
* Options for edge findByEndpoints operations.
|
|
1246
|
-
*/
|
|
1247
|
-
type EdgeFindByEndpointsOptions<E extends AnyEdgeType> = Readonly<{
|
|
1091
|
+
orderBy<A extends (keyof Aliases | keyof EdgeAliases) & string>(alias: A, field: string, direction?: SortDirection): ExecutableQuery<G, Aliases, EdgeAliases, RecursiveAliases, R>;
|
|
1248
1092
|
/**
|
|
1249
|
-
*
|
|
1250
|
-
* When omitted, matches on endpoints only (returns the first edge at the read coordinate).
|
|
1093
|
+
* Limits the number of results.
|
|
1251
1094
|
*/
|
|
1252
|
-
|
|
1253
|
-
/** Property values to match against when matchOn is specified. */
|
|
1254
|
-
props?: Partial<z.input<E["schema"]>>;
|
|
1255
|
-
}>;
|
|
1256
|
-
/**
|
|
1257
|
-
* Options for edge getOrCreateByEndpoints operations.
|
|
1258
|
-
*/
|
|
1259
|
-
type EdgeGetOrCreateByEndpointsOptions<E extends AnyEdgeType> = Readonly<{
|
|
1095
|
+
limit(n: number): ExecutableQuery<G, Aliases, EdgeAliases, RecursiveAliases, R>;
|
|
1260
1096
|
/**
|
|
1261
|
-
*
|
|
1262
|
-
* Default: `[]` — match on endpoints only.
|
|
1097
|
+
* Offsets the results.
|
|
1263
1098
|
*/
|
|
1264
|
-
|
|
1265
|
-
/** Existing record behavior. Default: "return" */
|
|
1266
|
-
ifExists?: IfExistsMode;
|
|
1099
|
+
offset(n: number): ExecutableQuery<G, Aliases, EdgeAliases, RecursiveAliases, R>;
|
|
1267
1100
|
/**
|
|
1268
|
-
*
|
|
1269
|
-
*
|
|
1101
|
+
* Applies a query fragment to transform this executable query.
|
|
1102
|
+
*
|
|
1103
|
+
* Useful for applying post-select transformations like ordering,
|
|
1104
|
+
* limits, and offsets from reusable fragments.
|
|
1105
|
+
*
|
|
1106
|
+
* @example
|
|
1107
|
+
* ```typescript
|
|
1108
|
+
* const paginated = (q) => q.orderBy("u", "createdAt", "desc").limit(10);
|
|
1109
|
+
*
|
|
1110
|
+
* const results = await query()
|
|
1111
|
+
* .from("User", "u")
|
|
1112
|
+
* .select((ctx) => ctx.u)
|
|
1113
|
+
* .pipe(paginated)
|
|
1114
|
+
* .execute();
|
|
1115
|
+
* ```
|
|
1116
|
+
*
|
|
1117
|
+
* @param fragment - A function that transforms the executable query
|
|
1118
|
+
* @returns The transformed executable query
|
|
1270
1119
|
*/
|
|
1271
|
-
|
|
1120
|
+
pipe<NewR = R>(fragment: (query: ExecutableQuery<G, Aliases, EdgeAliases, RecursiveAliases, R>) => ExecutableQuery<G, Aliases, EdgeAliases, RecursiveAliases, NewR>): ExecutableQuery<G, Aliases, EdgeAliases, RecursiveAliases, NewR>;
|
|
1272
1121
|
/**
|
|
1273
|
-
*
|
|
1274
|
-
* the operation returns an existing edge without writing.
|
|
1122
|
+
* Combines this query with another using UNION (removes duplicates).
|
|
1275
1123
|
*/
|
|
1276
|
-
|
|
1277
|
-
}>;
|
|
1278
|
-
/**
|
|
1279
|
-
* A collection of nodes of a specific type.
|
|
1280
|
-
*
|
|
1281
|
-
* Provides ergonomic CRUD operations for a single node type.
|
|
1282
|
-
*/
|
|
1283
|
-
type NodeCollection<N extends NodeType, CN extends string = string> = Readonly<{
|
|
1124
|
+
union(other: ExecutableQuery<G, any, any, any, R>): UnionableQuery<G, R>;
|
|
1284
1125
|
/**
|
|
1285
|
-
*
|
|
1286
|
-
*
|
|
1287
|
-
* `validFrom` defaults to the operation's creation timestamp when omitted.
|
|
1126
|
+
* Combines this query with another using UNION ALL (keeps duplicates).
|
|
1288
1127
|
*/
|
|
1289
|
-
|
|
1290
|
-
id?: string;
|
|
1291
|
-
validFrom?: string;
|
|
1292
|
-
validTo?: string;
|
|
1293
|
-
}>) => Promise<Node<N>>;
|
|
1294
|
-
/** Get a node by ID */
|
|
1295
|
-
getById: (id: NodeId<N>, options?: QueryOptions) => Promise<Node<N> | undefined>;
|
|
1296
|
-
/** Get multiple nodes by ID, preserving input order (undefined for missing) */
|
|
1297
|
-
getByIds: (ids: readonly NodeId<N>[], options?: QueryOptions) => Promise<readonly (Node<N> | undefined)[]>;
|
|
1298
|
-
/** Update a node */
|
|
1299
|
-
update: (id: NodeId<N>, props: Partial<z.input<N["schema"]>>, options?: Readonly<{
|
|
1300
|
-
validTo?: string;
|
|
1301
|
-
}>) => Promise<Node<N>>;
|
|
1302
|
-
/** Delete a node (soft delete - sets deletedAt timestamp) */
|
|
1303
|
-
delete: (id: NodeId<N>) => Promise<void>;
|
|
1128
|
+
unionAll(other: ExecutableQuery<G, any, any, any, R>): UnionableQuery<G, R>;
|
|
1304
1129
|
/**
|
|
1305
|
-
*
|
|
1306
|
-
*
|
|
1307
|
-
* Unlike `delete()` which performs a soft delete, this permanently
|
|
1308
|
-
* removes the node and its associated data (uniqueness entries, embeddings).
|
|
1309
|
-
*
|
|
1310
|
-
* **Warning:** This operation is irreversible and should be used carefully.
|
|
1311
|
-
* Consider using soft delete (`delete()`) for most use cases.
|
|
1312
|
-
*
|
|
1313
|
-
* @throws Error if edges are still connected to this node (delete edges first)
|
|
1130
|
+
* Combines this query with another using INTERSECT.
|
|
1314
1131
|
*/
|
|
1315
|
-
|
|
1132
|
+
intersect(other: ExecutableQuery<G, any, any, any, R>): UnionableQuery<G, R>;
|
|
1316
1133
|
/**
|
|
1317
|
-
*
|
|
1318
|
-
*
|
|
1319
|
-
* Supports predicate filtering via the `where` option for SQL-level filtering.
|
|
1320
|
-
* For simple queries. Use store.query() for complex traversals.
|
|
1134
|
+
* Combines this query with another using EXCEPT.
|
|
1321
1135
|
*/
|
|
1322
|
-
|
|
1323
|
-
where?: (accessor: NodeAccessor<N>) => Predicate;
|
|
1324
|
-
limit?: number;
|
|
1325
|
-
offset?: number;
|
|
1326
|
-
}>, temporal?: QueryOptions) => Promise<Node<N>[]>;
|
|
1327
|
-
/** Count nodes matching criteria */
|
|
1328
|
-
count: (temporal?: QueryOptions) => Promise<number>;
|
|
1136
|
+
except(other: ExecutableQuery<G, any, any, any, R>): UnionableQuery<G, R>;
|
|
1329
1137
|
/**
|
|
1330
|
-
*
|
|
1331
|
-
*
|
|
1332
|
-
* Use this for dynamic dispatch (changesets, migrations, imports) where
|
|
1333
|
-
* the data shape is determined at runtime, not compile time.
|
|
1334
|
-
* The return type is fully typed — only the input gate is relaxed.
|
|
1138
|
+
* Compiles the query and returns the SQL text and parameters.
|
|
1335
1139
|
*
|
|
1336
|
-
*
|
|
1140
|
+
* Requires a backend to be configured (the backend determines the SQL dialect).
|
|
1141
|
+
* Use this for debugging, logging, or running the query with a custom executor.
|
|
1337
1142
|
*/
|
|
1338
|
-
|
|
1339
|
-
|
|
1340
|
-
|
|
1341
|
-
|
|
1342
|
-
}>) => Promise<Node<N>>;
|
|
1143
|
+
toSQL(): Readonly<{
|
|
1144
|
+
sql: string;
|
|
1145
|
+
params: readonly unknown[];
|
|
1146
|
+
}>;
|
|
1343
1147
|
/**
|
|
1344
|
-
*
|
|
1345
|
-
*
|
|
1346
|
-
* If a node with the given ID exists, updates it with the provided props.
|
|
1347
|
-
* Otherwise, creates a new node with that ID.
|
|
1148
|
+
* Compiles the query to TypeGraph's database-independent SQL fragment.
|
|
1348
1149
|
*
|
|
1349
|
-
*
|
|
1350
|
-
*
|
|
1150
|
+
* Pass the result to a GraphBackend, or use toSQL() to render SQL text and
|
|
1151
|
+
* parameters for the configured dialect.
|
|
1351
1152
|
*/
|
|
1352
|
-
|
|
1353
|
-
validFrom?: string;
|
|
1354
|
-
validTo?: string;
|
|
1355
|
-
}>) => Promise<Node<N>>;
|
|
1153
|
+
compile(): CompiledSelectSql;
|
|
1356
1154
|
/**
|
|
1357
|
-
*
|
|
1358
|
-
*
|
|
1359
|
-
*
|
|
1360
|
-
* the
|
|
1361
|
-
*
|
|
1155
|
+
* Creates a prepared (pre-validated) query that can be executed multiple
|
|
1156
|
+
* times with different parameter bindings. Builds and structurally
|
|
1157
|
+
* validates the AST once (a malformed query fails fast, here, instead of on
|
|
1158
|
+
* first use); the prepared query then compiles once into a reusable template
|
|
1159
|
+
* and fills a fresh read instant per execute() — see PreparedQuery's class
|
|
1160
|
+
* doc comment, which also covers the two cases that recompile per call
|
|
1161
|
+
* instead (no `executeRaw`, or a statement whose semantics ride on the SQL
|
|
1162
|
+
* object rather than its text).
|
|
1362
1163
|
*
|
|
1363
|
-
* `
|
|
1364
|
-
*
|
|
1365
|
-
*/
|
|
1366
|
-
upsertByIdFromRecord: (id: string, data: Record<string, unknown>, options?: Readonly<{
|
|
1367
|
-
validFrom?: string;
|
|
1368
|
-
validTo?: string;
|
|
1369
|
-
}>) => Promise<Node<N>>;
|
|
1370
|
-
/**
|
|
1371
|
-
* Create multiple nodes in a batch.
|
|
1164
|
+
* Use `param("name")` in predicates to create parameterized slots,
|
|
1165
|
+
* then pass values via `prepared.execute({ name: "value" })`.
|
|
1372
1166
|
*
|
|
1373
|
-
*
|
|
1374
|
-
*
|
|
1167
|
+
* @example
|
|
1168
|
+
* ```typescript
|
|
1169
|
+
* import { param } from "@nicia-ai/typegraph";
|
|
1375
1170
|
*
|
|
1376
|
-
*
|
|
1377
|
-
|
|
1378
|
-
|
|
1379
|
-
|
|
1380
|
-
|
|
1381
|
-
validFrom?: string;
|
|
1382
|
-
validTo?: string;
|
|
1383
|
-
}>[]) => Promise<Node<N>[]>;
|
|
1384
|
-
/**
|
|
1385
|
-
* Create or update multiple nodes in a batch.
|
|
1171
|
+
* const prepared = store.query()
|
|
1172
|
+
* .from("Person", "p")
|
|
1173
|
+
* .whereNode("p", (p) => p.name.eq(param("name")))
|
|
1174
|
+
* .select((ctx) => ctx.p)
|
|
1175
|
+
* .prepare();
|
|
1386
1176
|
*
|
|
1387
|
-
*
|
|
1388
|
-
*
|
|
1177
|
+
* const alice = await prepared.execute({ name: "Alice" });
|
|
1178
|
+
* const bob = await prepared.execute({ name: "Bob" });
|
|
1179
|
+
* ```
|
|
1389
1180
|
*
|
|
1390
|
-
*
|
|
1391
|
-
* operation's creation timestamp when omitted; it has no effect on update.
|
|
1181
|
+
* @throws Error if no backend is configured
|
|
1392
1182
|
*/
|
|
1393
|
-
|
|
1394
|
-
id: string;
|
|
1395
|
-
props: z.input<N["schema"]>;
|
|
1396
|
-
validFrom?: string;
|
|
1397
|
-
validTo?: string;
|
|
1398
|
-
}>[]) => Promise<Node<N>[]>;
|
|
1183
|
+
prepare(): PreparedQuery<R>;
|
|
1399
1184
|
/**
|
|
1400
|
-
*
|
|
1401
|
-
*
|
|
1402
|
-
* This is the dedicated fast path for bulk inserts. Unlike `bulkCreate`
|
|
1403
|
-
* with `returnResults: false`, the intent is unambiguous: no results
|
|
1404
|
-
* are returned and the operation is wrapped in a transaction.
|
|
1185
|
+
* Executes the query and returns typed results.
|
|
1405
1186
|
*
|
|
1406
|
-
*
|
|
1407
|
-
|
|
1408
|
-
|
|
1409
|
-
|
|
1410
|
-
id?: string;
|
|
1411
|
-
validFrom?: string;
|
|
1412
|
-
validTo?: string;
|
|
1413
|
-
}>[]) => Promise<void>;
|
|
1414
|
-
/**
|
|
1415
|
-
* Delete multiple nodes by ID.
|
|
1187
|
+
* Uses smart optimization to detect when only specific fields are accessed
|
|
1188
|
+
* in the select callback. If the callback only accesses simple field
|
|
1189
|
+
* references (no method calls or computations), generates optimized SQL
|
|
1190
|
+
* that only extracts those fields instead of the full props blob.
|
|
1416
1191
|
*
|
|
1417
|
-
*
|
|
1418
|
-
* that don't exist.
|
|
1192
|
+
* @throws Error if no backend is configured
|
|
1419
1193
|
*/
|
|
1420
|
-
|
|
1194
|
+
execute(): Promise<readonly R[]>;
|
|
1421
1195
|
/**
|
|
1422
|
-
*
|
|
1423
|
-
*
|
|
1424
|
-
* Looks up a live node by the named constraint key computed from `props`.
|
|
1425
|
-
* Returns the node if found, or undefined. Soft-deleted nodes are excluded.
|
|
1196
|
+
* Executes the query against a provided backend.
|
|
1426
1197
|
*
|
|
1427
|
-
*
|
|
1428
|
-
*
|
|
1429
|
-
|
|
1430
|
-
|
|
1431
|
-
/**
|
|
1432
|
-
* Batch version of findByConstraint.
|
|
1198
|
+
* Used by `store.batch()` to run several queries in sequence against one
|
|
1199
|
+
* target — a transaction on backends that have them, the backend itself
|
|
1200
|
+
* otherwise. The full compile → execute → transform pipeline runs
|
|
1201
|
+
* identically to `execute()`, but against the given backend.
|
|
1433
1202
|
*
|
|
1434
|
-
*
|
|
1435
|
-
*
|
|
1203
|
+
* Costs one statement, or two when the selective-field path runs and its
|
|
1204
|
+
* mapping then falls back: `#tryOptimizedExecutionOn` detects that only
|
|
1205
|
+
* after its statement has executed, and the caller re-runs the full fetch.
|
|
1206
|
+
* The fallback clears the fast path for this instance.
|
|
1436
1207
|
*/
|
|
1437
|
-
|
|
1438
|
-
props: z.input<N["schema"]>;
|
|
1439
|
-
}>[]) => Promise<(Node<N> | undefined)[]>;
|
|
1208
|
+
executeOn(backend: GraphBackend | TransactionBackend): Promise<readonly R[]>;
|
|
1440
1209
|
/**
|
|
1441
|
-
*
|
|
1442
|
-
*
|
|
1443
|
-
* For each input item, TypeGraph computes the index lookup key from
|
|
1444
|
-
* `index.fields` (JSON-pointer extraction, partial-`where` applied to
|
|
1445
|
-
* stored rows, null-safe matching) and returns the live, non-soft-deleted
|
|
1446
|
-
* nodes that share that key. Unlike {@link bulkFindByConstraint}, the index
|
|
1447
|
-
* may be non-unique, so each input yields a (possibly empty) array.
|
|
1210
|
+
* Executes a paginated query using cursor-based keyset pagination.
|
|
1448
1211
|
*
|
|
1449
|
-
*
|
|
1450
|
-
*
|
|
1451
|
-
* `NodeIndexNotFoundError`; a type-incompatible indexed field throws
|
|
1452
|
-
* `ValidationError`. This is candidate retrieval, not a uniqueness or
|
|
1453
|
-
* identity guarantee.
|
|
1212
|
+
* Cursor pagination is efficient for large datasets as it avoids OFFSET.
|
|
1213
|
+
* Requires ORDER BY to be specified for deterministic results.
|
|
1454
1214
|
*
|
|
1455
|
-
* @param
|
|
1456
|
-
* @
|
|
1457
|
-
* @
|
|
1215
|
+
* @param options - Pagination options (first/after for forward, last/before for backward)
|
|
1216
|
+
* @throws ValidationError if ORDER BY is not specified
|
|
1217
|
+
* @throws ValidationError if cursor columns don't match query ORDER BY columns
|
|
1458
1218
|
*/
|
|
1459
|
-
|
|
1460
|
-
props: Partial<z.input<N["schema"]>>;
|
|
1461
|
-
}>[], options?: NodeBulkFindByIndexOptions) => Promise<readonly Node<N>[][]>;
|
|
1219
|
+
paginate(options: PaginateOptions): Promise<PaginatedResult<R>>;
|
|
1462
1220
|
/**
|
|
1463
|
-
*
|
|
1464
|
-
*
|
|
1465
|
-
* Looks up a node by the named constraint key computed from `props`.
|
|
1466
|
-
* If found, returns it (optionally updating with `ifExists: "update"`).
|
|
1467
|
-
* If not found, creates a new node. Soft-deleted matches are always resurrected.
|
|
1221
|
+
* Returns an async iterator that streams results in batches.
|
|
1468
1222
|
*
|
|
1469
|
-
*
|
|
1470
|
-
*
|
|
1471
|
-
* @param options - Existing record behavior (default: "return")
|
|
1472
|
-
*/
|
|
1473
|
-
getOrCreateByConstraint: (constraintName: CN, props: z.input<N["schema"]>, options?: NodeGetOrCreateByConstraintOptions) => Promise<NodeGetOrCreateByConstraintResult<N>>;
|
|
1474
|
-
/**
|
|
1475
|
-
* Batch version of getOrCreateByConstraint.
|
|
1223
|
+
* Uses cursor pagination internally for efficient memory usage.
|
|
1224
|
+
* Requires ORDER BY to be specified for deterministic results.
|
|
1476
1225
|
*
|
|
1477
|
-
*
|
|
1478
|
-
*
|
|
1226
|
+
* @param options - Stream options (batchSize defaults to 1000)
|
|
1227
|
+
* @throws ValidationError if ORDER BY is not specified
|
|
1479
1228
|
*/
|
|
1480
|
-
|
|
1481
|
-
|
|
1482
|
-
|
|
1483
|
-
}>;
|
|
1229
|
+
stream(options?: StreamOptions): AsyncIterable<R>;
|
|
1230
|
+
}
|
|
1231
|
+
|
|
1484
1232
|
/**
|
|
1485
|
-
*
|
|
1486
|
-
|
|
1487
|
-
|
|
1488
|
-
|
|
1489
|
-
*
|
|
1233
|
+
* TraversalBuilder - Intermediate builder for edge traversals.
|
|
1234
|
+
*/
|
|
1235
|
+
|
|
1236
|
+
/**
|
|
1237
|
+
* Resolves the edge type for an edge alias based on its kind type parameter.
|
|
1490
1238
|
*
|
|
1491
|
-
*
|
|
1492
|
-
*
|
|
1239
|
+
* For `traverse(...)`, `EK` is a literal like `"authoredBy"` and the
|
|
1240
|
+
* type comes from the typed graph. For `traverseDynamic(...)`, `EK` is
|
|
1241
|
+
* widened to `string` — `string extends EK` distinguishes that case and
|
|
1242
|
+
* resolves to `DynamicEdgeType`, so the conditional accessor types fire.
|
|
1493
1243
|
*/
|
|
1494
|
-
type
|
|
1495
|
-
kind: N["kind"];
|
|
1496
|
-
id: string;
|
|
1497
|
-
}>;
|
|
1244
|
+
type EdgeTypeForKey<G extends GraphDef, EK> = string extends EK ? DynamicEdgeType : EK extends keyof G["edges"] & string ? G["edges"][EK]["type"] : DynamicEdgeType;
|
|
1498
1245
|
/**
|
|
1499
|
-
*
|
|
1246
|
+
* State for variable-length traversal configuration.
|
|
1500
1247
|
*/
|
|
1501
|
-
|
|
1502
|
-
|
|
1503
|
-
|
|
1504
|
-
|
|
1505
|
-
|
|
1248
|
+
interface VariableLengthState {
|
|
1249
|
+
enabled: boolean;
|
|
1250
|
+
minDepth: number;
|
|
1251
|
+
maxDepth: number;
|
|
1252
|
+
cyclePolicy: RecursiveCyclePolicy;
|
|
1253
|
+
pathEnabled: boolean;
|
|
1254
|
+
pathAlias?: string;
|
|
1255
|
+
depthEnabled: boolean;
|
|
1256
|
+
depthAlias?: string;
|
|
1257
|
+
}
|
|
1506
1258
|
/**
|
|
1507
|
-
*
|
|
1259
|
+
* Intermediate builder for traversal operations.
|
|
1508
1260
|
*
|
|
1509
|
-
*
|
|
1510
|
-
|
|
1511
|
-
type EdgeCreateArguments<E extends AnyEdgeType> = {} extends z.input<E["schema"]> ? [
|
|
1512
|
-
props?: z.input<E["schema"]>,
|
|
1513
|
-
options?: EdgeCreateOptions
|
|
1514
|
-
] : [props: z.input<E["schema"]>, options?: EdgeCreateOptions];
|
|
1515
|
-
/**
|
|
1516
|
-
* A collection of edges of a specific type.
|
|
1517
|
-
*
|
|
1518
|
-
* Provides ergonomic CRUD operations for a single edge type.
|
|
1519
|
-
* The From and To type parameters enforce that edge endpoints
|
|
1520
|
-
* match the allowed node types at compile time.
|
|
1521
|
-
*
|
|
1522
|
-
* @example
|
|
1523
|
-
* ```typescript
|
|
1524
|
-
* // Create an edge - pass Node objects directly
|
|
1525
|
-
* const edge = await store.edges.worksAt.create(alice, acme, { role: "Engineer" });
|
|
1526
|
-
*
|
|
1527
|
-
* // TypeScript error: Company is not a valid 'from' type for worksAt
|
|
1528
|
-
* // store.edges.worksAt.create(acme, alice, { role: "Engineer" });
|
|
1529
|
-
*
|
|
1530
|
-
* // For edges with empty schemas, props is optional
|
|
1531
|
-
* await store.edges.wrote.create(author, book);
|
|
1532
|
-
*
|
|
1533
|
-
* // Find edges from a node
|
|
1534
|
-
* const edges = await store.edges.worksAt.findFrom(alice);
|
|
1535
|
-
* ```
|
|
1261
|
+
* Type parameters track the edge kind and direction to constrain
|
|
1262
|
+
* which node kinds are valid targets in the `to()` method.
|
|
1536
1263
|
*/
|
|
1537
|
-
|
|
1264
|
+
declare class TraversalBuilder<G extends GraphDef, Aliases extends AliasMap, EdgeAliases extends EdgeAliasMap = EmptyEdgeAliasMap, EK extends keyof G["edges"] & string = keyof G["edges"] & string, EA extends string = string, Dir extends TraversalDirection$1 = "out", Optional extends boolean = false, DC extends boolean | string = false, PC extends boolean | string = false, RecAliases extends RecursiveAliasMap = EmptyRecursiveAliasMap, CoordinateState extends QueryCoordinateState = "open"> {
|
|
1265
|
+
#private;
|
|
1266
|
+
constructor(config: QueryBuilderConfig, state: QueryBuilderState, edgeKinds: readonly string[], edgeAlias: EA, direction: Dir, fromAlias: string, inverseEdgeKinds?: readonly string[], optional?: Optional, variableLength?: VariableLengthState, pendingEdgePredicates?: readonly NodePredicate[]);
|
|
1538
1267
|
/**
|
|
1539
|
-
*
|
|
1540
|
-
*
|
|
1541
|
-
* `
|
|
1542
|
-
*
|
|
1543
|
-
* @param from - Source node (must be one of the allowed 'from' types)
|
|
1544
|
-
* @param to - Target node (must be one of the allowed 'to' types)
|
|
1545
|
-
* @param args - Edge properties (optional if schema is empty) and creation options
|
|
1268
|
+
* Enables variable-length (recursive) traversal.
|
|
1269
|
+
* Defaults to MAX_RECURSIVE_DEPTH (10) hops with cycle prevention.
|
|
1270
|
+
* Use `maxHops` to override (up to MAX_EXPLICIT_RECURSIVE_DEPTH).
|
|
1546
1271
|
*/
|
|
1547
|
-
|
|
1548
|
-
|
|
1549
|
-
|
|
1550
|
-
|
|
1551
|
-
|
|
1552
|
-
/** Update an edge's properties */
|
|
1553
|
-
update: (id: EdgeId<E>, props: Partial<z.input<E["schema"]>>, options?: Readonly<{
|
|
1554
|
-
validTo?: string;
|
|
1555
|
-
}>) => Promise<Edge<E, From, To>>;
|
|
1272
|
+
recursive<const O extends RecursiveTraversalOptions = Record<string, never>>(options?: O): TraversalBuilder<G, Aliases, EdgeAliases, EK, EA, Dir, Optional, O extends {
|
|
1273
|
+
depth: infer D extends boolean | string;
|
|
1274
|
+
} ? D : DC, O extends {
|
|
1275
|
+
path: infer P extends boolean | string;
|
|
1276
|
+
} ? P : PC, RecAliases, CoordinateState>;
|
|
1556
1277
|
/**
|
|
1557
|
-
*
|
|
1278
|
+
* Adds a WHERE clause for the edge being traversed.
|
|
1558
1279
|
*
|
|
1559
|
-
*
|
|
1560
|
-
*
|
|
1561
|
-
* soft-deleted edges and, in `current` / `asOf` modes, edges outside
|
|
1562
|
-
* their validity window). Pass `temporalMode` / `asOf` to read the
|
|
1563
|
-
* endpoint's edges at another temporal coordinate.
|
|
1280
|
+
* @param alias - The edge alias to filter on (must be the current edge alias)
|
|
1281
|
+
* @param predicateFunction - A function that builds predicates using the edge accessor
|
|
1564
1282
|
*/
|
|
1565
|
-
|
|
1283
|
+
whereEdge(alias: EA, predicateFunction: (edge: EdgeAccessor<EdgeTypeForKey<G, EK>>) => Predicate): TraversalBuilder<G, Aliases, EdgeAliases, EK, EA, Dir, Optional, DC, PC, RecAliases, CoordinateState>;
|
|
1566
1284
|
/**
|
|
1567
|
-
*
|
|
1285
|
+
* Specifies the target node kind.
|
|
1568
1286
|
*
|
|
1569
|
-
*
|
|
1287
|
+
* The kind must be a valid target for this edge based on the traversal direction:
|
|
1288
|
+
* - "out" direction: kind must be in the edge's "to" array
|
|
1289
|
+
* - "in" direction: kind must be in the edge's "from" array
|
|
1290
|
+
*
|
|
1291
|
+
* @param kind - The target node kind
|
|
1292
|
+
* @param alias - A unique alias for this node (compile-time error if duplicate)
|
|
1570
1293
|
*/
|
|
1571
|
-
|
|
1294
|
+
to<K extends ValidEdgeTargets<G, EK, Dir>, A extends string>(kind: K, alias: UniqueAlias<A, Aliases>, options?: {
|
|
1295
|
+
includeSubClasses?: false;
|
|
1296
|
+
}): QueryBuilder<G, Aliases & Record<A, NodeAlias<G["nodes"][K]["type"], Optional>>, EdgeAliases & Record<EA, EdgeAlias<G["edges"][EK]["type"], Optional>>, RecAliases & BuildRecursiveAliases<DC, PC, A>, CoordinateState>;
|
|
1297
|
+
to<K extends ValidEdgeTargets<G, EK, Dir>, A extends string>(kind: K, alias: UniqueAlias<A, Aliases>, options: {
|
|
1298
|
+
includeSubClasses: true;
|
|
1299
|
+
}): QueryBuilder<G, Aliases & Record<A, NodeAlias<NodeType, Optional>>, EdgeAliases & Record<EA, EdgeAlias<G["edges"][EK]["type"], Optional>>, RecAliases & BuildRecursiveAliases<DC, PC, A>, CoordinateState>;
|
|
1572
1300
|
/**
|
|
1573
|
-
*
|
|
1574
|
-
*
|
|
1575
|
-
* Returns a `BatchableQuery` instead of executing immediately. Accepts
|
|
1576
|
-
* the same temporal `options` as {@link EdgeCollection.findFrom}.
|
|
1301
|
+
* String-keyed sibling of `to` for runtime-declared target kinds.
|
|
1302
|
+
* Throws `KindNotFoundError` if the kind is not registered.
|
|
1577
1303
|
*/
|
|
1578
|
-
|
|
1304
|
+
toDynamic<A extends string>(kind: string, alias: UniqueAlias<A, Aliases>, options?: {
|
|
1305
|
+
includeSubClasses?: boolean;
|
|
1306
|
+
}): QueryBuilder<G, Aliases & Record<A, NodeAlias<DynamicNodeType, Optional>>, EdgeAliases & Record<EA, EdgeAlias<EdgeTypeForKey<G, EK>, Optional>>, RecAliases & BuildRecursiveAliases<DC, PC, A>, CoordinateState>;
|
|
1307
|
+
}
|
|
1308
|
+
|
|
1309
|
+
/**
|
|
1310
|
+
* QueryBuilder - The fluent query builder.
|
|
1311
|
+
*/
|
|
1312
|
+
|
|
1313
|
+
type TemporalMethod<G extends GraphDef, Aliases extends AliasMap, EdgeAliases extends EdgeAliasMap, RecursiveAliases extends RecursiveAliasMap, CoordinateState extends QueryCoordinateState> = CoordinateState extends "open" ? (mode: TemporalMode, asOf?: string) => QueryBuilder<G, Aliases, EdgeAliases, RecursiveAliases, "open"> : never;
|
|
1314
|
+
/**
|
|
1315
|
+
* The fluent query builder.
|
|
1316
|
+
*
|
|
1317
|
+
* Type parameters accumulate as methods are chained:
|
|
1318
|
+
* - G: The graph definition
|
|
1319
|
+
* - Aliases: Map of alias names to their node kinds
|
|
1320
|
+
* - EdgeAliases: Map of alias names to their edge kinds (accumulated during traversals)
|
|
1321
|
+
*/
|
|
1322
|
+
declare class QueryBuilder<G extends GraphDef, Aliases extends AliasMap = EmptyAliasMap, EdgeAliases extends EdgeAliasMap = EmptyEdgeAliasMap, RecursiveAliases extends RecursiveAliasMap = EmptyRecursiveAliasMap, CoordinateState extends QueryCoordinateState = "open"> {
|
|
1323
|
+
#private;
|
|
1324
|
+
readonly temporal: TemporalMethod<G, Aliases, EdgeAliases, RecursiveAliases, CoordinateState>;
|
|
1325
|
+
constructor(config: QueryBuilderConfig, state: QueryBuilderState);
|
|
1579
1326
|
/**
|
|
1580
|
-
*
|
|
1327
|
+
* Starts a query from a node kind.
|
|
1581
1328
|
*
|
|
1582
|
-
*
|
|
1583
|
-
*
|
|
1329
|
+
* @param kind - The node kind to start from
|
|
1330
|
+
* @param alias - A unique alias for this node (compile-time error if duplicate)
|
|
1584
1331
|
*/
|
|
1585
|
-
|
|
1332
|
+
from<K extends keyof G["nodes"] & string, A extends string>(kind: K, alias: UniqueAlias<A, Aliases>, options?: {
|
|
1333
|
+
includeSubClasses?: false;
|
|
1334
|
+
}): QueryBuilder<G, Aliases & Record<A, NodeAlias<G["nodes"][K]["type"]>>, EdgeAliases, RecursiveAliases, CoordinateState>;
|
|
1335
|
+
from<K extends keyof G["nodes"] & string, A extends string>(kind: K, alias: UniqueAlias<A, Aliases>, options: {
|
|
1336
|
+
includeSubClasses: true;
|
|
1337
|
+
}): QueryBuilder<G, Aliases & Record<A, NodeAlias>, EdgeAliases, RecursiveAliases, CoordinateState>;
|
|
1586
1338
|
/**
|
|
1587
|
-
*
|
|
1588
|
-
*
|
|
1589
|
-
*
|
|
1590
|
-
* (matching `findByEndpoints`' at-most-one semantics).
|
|
1339
|
+
* String-keyed sibling of `from` for runtime-declared kinds. Throws
|
|
1340
|
+
* `KindNotFoundError` if the kind is not registered. Predicates use
|
|
1341
|
+
* the `n.field("name").number().gte(...)` discriminator.
|
|
1591
1342
|
*/
|
|
1592
|
-
|
|
1593
|
-
|
|
1594
|
-
|
|
1343
|
+
fromDynamic<A extends string>(kind: string, alias: UniqueAlias<A, Aliases>, options?: {
|
|
1344
|
+
includeSubClasses?: boolean;
|
|
1345
|
+
}): QueryBuilder<G, Aliases & Record<A, NodeAlias<DynamicNodeType>>, EdgeAliases, RecursiveAliases, CoordinateState>;
|
|
1595
1346
|
/**
|
|
1596
|
-
*
|
|
1597
|
-
*
|
|
1598
|
-
* Unlike `delete()` which performs a soft delete, this permanently
|
|
1599
|
-
* removes the edge record.
|
|
1600
|
-
*
|
|
1601
|
-
* **Warning:** This operation is irreversible and should be used carefully.
|
|
1602
|
-
* Consider using soft delete (`delete()`) for most use cases.
|
|
1347
|
+
* Adds a WHERE clause for a node.
|
|
1603
1348
|
*/
|
|
1604
|
-
|
|
1605
|
-
/** Find edges matching endpoint and pagination criteria */
|
|
1606
|
-
find: (filter?: Readonly<{
|
|
1607
|
-
from?: NodeRef<From>;
|
|
1608
|
-
to?: NodeRef<To>;
|
|
1609
|
-
limit?: number;
|
|
1610
|
-
offset?: number;
|
|
1611
|
-
}>, temporal?: QueryOptions) => Promise<Edge<E, From, To>[]>;
|
|
1612
|
-
/** Count edges matching criteria */
|
|
1613
|
-
count: (filter?: Readonly<{
|
|
1614
|
-
from?: NodeRef<From>;
|
|
1615
|
-
to?: NodeRef<To>;
|
|
1616
|
-
}>, temporal?: QueryOptions) => Promise<number>;
|
|
1349
|
+
whereNode<A extends keyof Aliases & string>(alias: A, predicateFunction: (n: NodeAccessor<Aliases[A]["type"]>) => Predicate): QueryBuilder<G, Aliases, EdgeAliases, RecursiveAliases, CoordinateState>;
|
|
1617
1350
|
/**
|
|
1618
|
-
*
|
|
1619
|
-
*
|
|
1620
|
-
* More efficient than calling create() multiple times.
|
|
1621
|
-
* Use `bulkInsert` for the dedicated fast path that skips returning results.
|
|
1351
|
+
* Adds a WHERE clause for an edge.
|
|
1622
1352
|
*
|
|
1623
|
-
*
|
|
1353
|
+
* @param alias - The edge alias to filter on
|
|
1354
|
+
* @param predicateFunction - A function that builds predicates using the edge accessor
|
|
1624
1355
|
*/
|
|
1625
|
-
|
|
1626
|
-
from: NodeRef<From>;
|
|
1627
|
-
to: NodeRef<To>;
|
|
1628
|
-
props?: z.input<E["schema"]>;
|
|
1629
|
-
id?: string;
|
|
1630
|
-
validFrom?: string;
|
|
1631
|
-
validTo?: string;
|
|
1632
|
-
}>[]) => Promise<Edge<E, From, To>[]>;
|
|
1356
|
+
whereEdge<EA extends keyof EdgeAliases & string>(alias: EA, predicateFunction: (edge: EdgeAccessor<EdgeAliases[EA]["type"]>) => Predicate): QueryBuilder<G, Aliases, EdgeAliases, RecursiveAliases, CoordinateState>;
|
|
1633
1357
|
/**
|
|
1634
|
-
*
|
|
1358
|
+
* Traverses an edge to another node (outgoing direction).
|
|
1635
1359
|
*
|
|
1636
|
-
*
|
|
1637
|
-
*
|
|
1360
|
+
* By default, traverses from the current node (last traversal target, or start node).
|
|
1361
|
+
* Use the `from` option to traverse from a different alias (fan-out pattern).
|
|
1638
1362
|
*
|
|
1639
|
-
*
|
|
1640
|
-
*
|
|
1363
|
+
* @param options.expand - Ontology expansion mode for implying/inverse edges
|
|
1364
|
+
* @param options.from - Alias to traverse from (defaults to current/last traversal target)
|
|
1641
1365
|
*/
|
|
1642
|
-
|
|
1643
|
-
|
|
1644
|
-
|
|
1645
|
-
|
|
1646
|
-
|
|
1647
|
-
validFrom?: string;
|
|
1648
|
-
validTo?: string;
|
|
1649
|
-
}>[]) => Promise<Edge<E, From, To>[]>;
|
|
1366
|
+
traverse<EK extends keyof G["edges"] & string, EA extends string>(edgeKind: EK, edgeAlias: EA, options?: {
|
|
1367
|
+
direction?: "out";
|
|
1368
|
+
expand?: TraversalExpansion;
|
|
1369
|
+
from?: keyof Aliases & string;
|
|
1370
|
+
}): TraversalBuilder<G, Aliases, EdgeAliases, EK, EA, "out", false, false, false, RecursiveAliases, CoordinateState>;
|
|
1650
1371
|
/**
|
|
1651
|
-
*
|
|
1372
|
+
* Traverses an edge to another node (incoming direction).
|
|
1652
1373
|
*
|
|
1653
|
-
*
|
|
1654
|
-
*
|
|
1655
|
-
* are returned and the operation is wrapped in a transaction.
|
|
1374
|
+
* By default, traverses from the current node (last traversal target, or start node).
|
|
1375
|
+
* Use the `from` option to traverse from a different alias (fan-out pattern).
|
|
1656
1376
|
*
|
|
1657
|
-
*
|
|
1377
|
+
* @param options.direction - Set to "in" for incoming edge traversal
|
|
1378
|
+
* @param options.expand - Ontology expansion mode for implying/inverse edges
|
|
1379
|
+
* @param options.from - Alias to traverse from (defaults to current/last traversal target)
|
|
1658
1380
|
*/
|
|
1659
|
-
|
|
1660
|
-
|
|
1661
|
-
|
|
1662
|
-
|
|
1663
|
-
|
|
1664
|
-
validFrom?: string;
|
|
1665
|
-
validTo?: string;
|
|
1666
|
-
}>[]) => Promise<void>;
|
|
1381
|
+
traverse<EK extends keyof G["edges"] & string, EA extends string>(edgeKind: EK, edgeAlias: EA, options: {
|
|
1382
|
+
direction: "in";
|
|
1383
|
+
expand?: TraversalExpansion;
|
|
1384
|
+
from?: keyof Aliases & string;
|
|
1385
|
+
}): TraversalBuilder<G, Aliases, EdgeAliases, EK, EA, "in", false, false, false, RecursiveAliases, CoordinateState>;
|
|
1667
1386
|
/**
|
|
1668
|
-
*
|
|
1669
|
-
*
|
|
1670
|
-
* Atomic when the backend supports transactions. Silently ignores IDs
|
|
1671
|
-
* that don't exist.
|
|
1387
|
+
* String-keyed sibling of `traverse` for runtime-declared edge kinds.
|
|
1388
|
+
* Throws `KindNotFoundError` if the edge kind is not registered.
|
|
1672
1389
|
*/
|
|
1673
|
-
|
|
1390
|
+
traverseDynamic<EA extends string>(edgeKind: string, edgeAlias: EA, options?: {
|
|
1391
|
+
direction?: TraversalDirection$1;
|
|
1392
|
+
expand?: TraversalExpansion;
|
|
1393
|
+
from?: keyof Aliases & string;
|
|
1394
|
+
}): TraversalBuilder<G, Aliases, EdgeAliases & Record<EA, EdgeAlias<DynamicEdgeType>>, string, EA, TraversalDirection$1, false, false, false, RecursiveAliases, CoordinateState>;
|
|
1674
1395
|
/**
|
|
1675
|
-
*
|
|
1396
|
+
* Optionally traverses an edge to another node (LEFT JOIN semantics).
|
|
1397
|
+
* If no matching edge/node exists, the result will include null values.
|
|
1676
1398
|
*
|
|
1677
|
-
*
|
|
1678
|
-
*
|
|
1679
|
-
* (`current` mode) soft-deleted and out-of-window edges are excluded; under
|
|
1680
|
-
* `includeTombstones` a soft-deleted edge can be returned.
|
|
1399
|
+
* By default, traverses from the current node (last traversal target, or start node).
|
|
1400
|
+
* Use the `from` option to traverse from a different alias (fan-out pattern).
|
|
1681
1401
|
*
|
|
1682
|
-
* @param
|
|
1683
|
-
* @param
|
|
1684
|
-
* @param options -
|
|
1685
|
-
* @param temporal - Temporal coordinate. With no `temporal`, the graph's
|
|
1686
|
-
* default `temporalMode` applies (so under the default `"current"` mode,
|
|
1687
|
-
* edges outside their validity window are excluded). Pass
|
|
1688
|
-
* `temporalMode` / `asOf` to read the edge as of another coordinate.
|
|
1402
|
+
* @param options.direction - Direction of traversal: "out" (default) or "in"
|
|
1403
|
+
* @param options.expand - Ontology expansion mode for implying/inverse edges
|
|
1404
|
+
* @param options.from - Alias to traverse from (defaults to current/last traversal target)
|
|
1689
1405
|
*/
|
|
1690
|
-
|
|
1691
|
-
|
|
1692
|
-
|
|
1406
|
+
optionalTraverse<EK extends keyof G["edges"] & string, EA extends string>(edgeKind: EK, edgeAlias: EA, options?: {
|
|
1407
|
+
direction?: "out";
|
|
1408
|
+
expand?: TraversalExpansion;
|
|
1409
|
+
from?: keyof Aliases & string;
|
|
1410
|
+
}): TraversalBuilder<G, Aliases, EdgeAliases, EK, EA, "out", true, false, false, RecursiveAliases, CoordinateState>;
|
|
1411
|
+
optionalTraverse<EK extends keyof G["edges"] & string, EA extends string>(edgeKind: EK, edgeAlias: EA, options: {
|
|
1412
|
+
direction: "in";
|
|
1413
|
+
expand?: TraversalExpansion;
|
|
1414
|
+
from?: keyof Aliases & string;
|
|
1415
|
+
}): TraversalBuilder<G, Aliases, EdgeAliases, EK, EA, "in", true, false, false, RecursiveAliases, CoordinateState>;
|
|
1416
|
+
/**
|
|
1417
|
+
* String-keyed sibling of `optionalTraverse` for runtime-declared edge
|
|
1418
|
+
* kinds. LEFT JOIN semantics — non-matching rows produce a null edge
|
|
1419
|
+
* alias instead of dropping. Throws `KindNotFoundError` if the edge
|
|
1420
|
+
* kind is not registered.
|
|
1421
|
+
*/
|
|
1422
|
+
optionalTraverseDynamic<EA extends string>(edgeKind: string, edgeAlias: EA, options?: {
|
|
1423
|
+
direction?: TraversalDirection$1;
|
|
1424
|
+
expand?: TraversalExpansion;
|
|
1425
|
+
from?: keyof Aliases & string;
|
|
1426
|
+
}): TraversalBuilder<G, Aliases, EdgeAliases & Record<EA, EdgeAlias<DynamicEdgeType, true>>, string, EA, TraversalDirection$1, true, false, false, RecursiveAliases, CoordinateState>;
|
|
1427
|
+
/**
|
|
1428
|
+
* Selects fields to return.
|
|
1429
|
+
*/
|
|
1430
|
+
select<R>(selectFunction: (context: SelectContext<Aliases, EdgeAliases, RecursiveAliases>) => R): ExecutableQuery<G, Aliases, EdgeAliases, RecursiveAliases, R>;
|
|
1431
|
+
/**
|
|
1432
|
+
* Selects fields including aggregates.
|
|
1433
|
+
* Use with groupBy() for aggregate queries.
|
|
1693
1434
|
*
|
|
1694
|
-
*
|
|
1695
|
-
|
|
1696
|
-
|
|
1435
|
+
* @param fields - Object mapping output names to field refs or aggregate expressions
|
|
1436
|
+
*/
|
|
1437
|
+
aggregate<R extends Record<string, FieldRef | AggregateExpr>>(fields: R): ExecutableAggregateQuery<G, Aliases, R>;
|
|
1438
|
+
/**
|
|
1439
|
+
* Orders results.
|
|
1440
|
+
*/
|
|
1441
|
+
orderBy<A extends (keyof Aliases | keyof EdgeAliases) & string>(alias: A, field: string, direction?: SortDirection): QueryBuilder<G, Aliases, EdgeAliases, RecursiveAliases, CoordinateState>;
|
|
1442
|
+
/**
|
|
1443
|
+
* Limits the number of results.
|
|
1444
|
+
*/
|
|
1445
|
+
limit(n: number): QueryBuilder<G, Aliases, EdgeAliases, RecursiveAliases, CoordinateState>;
|
|
1446
|
+
/**
|
|
1447
|
+
* Offsets the results.
|
|
1448
|
+
*/
|
|
1449
|
+
offset(n: number): QueryBuilder<G, Aliases, EdgeAliases, RecursiveAliases, CoordinateState>;
|
|
1450
|
+
/**
|
|
1451
|
+
* Groups results by the specified field.
|
|
1452
|
+
* Use with aggregate functions like COUNT, SUM, AVG in select().
|
|
1697
1453
|
*
|
|
1698
|
-
*
|
|
1699
|
-
*
|
|
1700
|
-
|
|
1701
|
-
|
|
1454
|
+
* @param alias - The node alias to group by
|
|
1455
|
+
* @param field - The field name to group by
|
|
1456
|
+
*/
|
|
1457
|
+
groupBy<A extends keyof Aliases & string>(alias: A, field: string): QueryBuilder<G, Aliases, EdgeAliases, RecursiveAliases, CoordinateState>;
|
|
1458
|
+
/**
|
|
1459
|
+
* Groups results by the node ID.
|
|
1460
|
+
* Use when you want to group by a complete node rather than a specific field.
|
|
1702
1461
|
*
|
|
1703
|
-
* @param
|
|
1704
|
-
* @param to - Target node
|
|
1705
|
-
* @param props - Full properties for create, or merge source for update
|
|
1706
|
-
* @param options - Match criteria and conflict resolution
|
|
1462
|
+
* @param alias - The node alias to group by (uses the node's ID)
|
|
1707
1463
|
*/
|
|
1708
|
-
|
|
1464
|
+
groupByNode<A extends keyof Aliases & string>(alias: A): QueryBuilder<G, Aliases, EdgeAliases, RecursiveAliases, CoordinateState>;
|
|
1709
1465
|
/**
|
|
1710
|
-
*
|
|
1466
|
+
* Filters grouped results using aggregate conditions (HAVING clause).
|
|
1467
|
+
* Use after groupBy() to filter based on aggregate values.
|
|
1711
1468
|
*
|
|
1712
|
-
*
|
|
1713
|
-
* Atomic when the backend supports transactions.
|
|
1469
|
+
* @param predicate - A predicate expression to filter groups
|
|
1714
1470
|
*/
|
|
1715
|
-
|
|
1716
|
-
|
|
1717
|
-
|
|
1718
|
-
|
|
1719
|
-
|
|
1720
|
-
|
|
1721
|
-
|
|
1722
|
-
|
|
1471
|
+
having(predicate: PredicateExpression): QueryBuilder<G, Aliases, EdgeAliases, RecursiveAliases, CoordinateState>;
|
|
1472
|
+
/**
|
|
1473
|
+
* Sets fusion parameters for hybrid (vector + fulltext) queries.
|
|
1474
|
+
*
|
|
1475
|
+
* Applies only when the query contains both a `.similarTo()` and a
|
|
1476
|
+
* `.$fulltext.matches()` predicate. Without this call, the default is
|
|
1477
|
+
* RRF with k=60 and equal weights. A mismatch between `.fuseWith()`
|
|
1478
|
+
* configuration and the predicates on the query is caught during
|
|
1479
|
+
* compilation, not here.
|
|
1480
|
+
*
|
|
1481
|
+
* @example
|
|
1482
|
+
* ```typescript
|
|
1483
|
+
* store.query()
|
|
1484
|
+
* .from("Document", "d")
|
|
1485
|
+
* .whereNode("d", d =>
|
|
1486
|
+
* d.$fulltext.matches("renewable energy", 50)
|
|
1487
|
+
* .and(d.embedding.similarTo(vec, 50))
|
|
1488
|
+
* .and(d.tenantId.eq(tenant))
|
|
1489
|
+
* )
|
|
1490
|
+
* .fuseWith({ k: 60, weights: { fulltext: 1.5 } })
|
|
1491
|
+
* .limit(10)
|
|
1492
|
+
* .execute();
|
|
1493
|
+
* ```
|
|
1494
|
+
*/
|
|
1495
|
+
fuseWith(options: HybridFusionOptions): QueryBuilder<G, Aliases, EdgeAliases, RecursiveAliases, CoordinateState>;
|
|
1496
|
+
/**
|
|
1497
|
+
* Applies a query fragment to transform this builder.
|
|
1498
|
+
*
|
|
1499
|
+
* Fragments are reusable query transformations that can add predicates,
|
|
1500
|
+
* traversals, ordering, and other query operations. Use this for
|
|
1501
|
+
* composing complex queries from simpler, reusable parts.
|
|
1502
|
+
*
|
|
1503
|
+
* @example
|
|
1504
|
+
* ```typescript
|
|
1505
|
+
* // Define a reusable fragment
|
|
1506
|
+
* const activeUsers = createFragment<MyGraph>()((q) =>
|
|
1507
|
+
* q.whereNode("u", ({ status }) => status.eq("active"))
|
|
1508
|
+
* );
|
|
1509
|
+
*
|
|
1510
|
+
* // Apply the fragment
|
|
1511
|
+
* const results = await query()
|
|
1512
|
+
* .from("User", "u")
|
|
1513
|
+
* .pipe(activeUsers)
|
|
1514
|
+
* .select((ctx) => ctx.u)
|
|
1515
|
+
* .execute();
|
|
1516
|
+
* ```
|
|
1517
|
+
*
|
|
1518
|
+
* @param fragment - A function that transforms the builder
|
|
1519
|
+
* @returns The transformed builder
|
|
1520
|
+
*/
|
|
1521
|
+
pipe<OutAliases extends AliasMap, OutEdgeAliases extends EdgeAliasMap = EdgeAliases, OutRecAliases extends RecursiveAliasMap = RecursiveAliases>(fragment: (builder: QueryBuilder<G, Aliases, EdgeAliases, RecursiveAliases, CoordinateState>) => QueryBuilder<G, OutAliases, OutEdgeAliases, OutRecAliases, CoordinateState>): QueryBuilder<G, OutAliases, OutEdgeAliases, OutRecAliases, CoordinateState>;
|
|
1522
|
+
}
|
|
1523
|
+
|
|
1723
1524
|
/**
|
|
1724
|
-
*
|
|
1525
|
+
* Fluent query builder for TypeGraph.
|
|
1725
1526
|
*
|
|
1726
|
-
*
|
|
1727
|
-
*
|
|
1728
|
-
*
|
|
1527
|
+
* Provides a type-safe, chainable API for building queries.
|
|
1528
|
+
* Each method returns a new builder instance with expanded type information.
|
|
1529
|
+
*
|
|
1530
|
+
* This module re-exports from the builder submodules and provides the
|
|
1531
|
+
* createQueryBuilder factory function.
|
|
1729
1532
|
*/
|
|
1730
|
-
|
|
1731
|
-
|
|
1732
|
-
|
|
1533
|
+
|
|
1534
|
+
type InitialQueryBuilder<G extends GraphDef, CoordinateState extends QueryCoordinateState = "open"> = QueryBuilder<G, EmptyAliasMap, EmptyEdgeAliasMap, EmptyRecursiveAliasMap, CoordinateState>;
|
|
1535
|
+
declare function createQueryBuilder<G extends GraphDef>(graphId: string, registry: KindRegistry, options?: CreateQueryBuilderOptions): InitialQueryBuilder<G>;
|
|
1536
|
+
|
|
1733
1537
|
/**
|
|
1734
|
-
*
|
|
1538
|
+
* StoreView collection surface buckets.
|
|
1539
|
+
*
|
|
1540
|
+
* The live NodeCollection / EdgeCollection partition into buckets a StoreView
|
|
1541
|
+
* treats differently:
|
|
1542
|
+
*
|
|
1543
|
+
* - temporal reads honor the pinned coordinate;
|
|
1544
|
+
* - current reads have no temporal axis and are refused on temporal pins;
|
|
1545
|
+
* - writes are never available on a read-only view; and
|
|
1546
|
+
* - batch reads require store.batch() and are absent from a view.
|
|
1547
|
+
*
|
|
1548
|
+
* These arrays are the single runtime source of truth for the proxy routing and
|
|
1549
|
+
* the type-level source for the derived StoreView collection types. The
|
|
1550
|
+
* StoreView surface-classification test asserts they exactly partition the live
|
|
1551
|
+
* collection methods so new collection methods cannot be silently omitted.
|
|
1735
1552
|
*/
|
|
1736
|
-
|
|
1553
|
+
/** Temporal-aware node read method names. */
|
|
1554
|
+
declare const NODE_TEMPORAL_READ_NAMES: readonly ["getById", "getByIds", "find", "count"];
|
|
1555
|
+
/** Current-state-only node reads (constraint / index lookups). */
|
|
1556
|
+
declare const CURRENT_ONLY_READ_NAMES: readonly ["findByConstraint", "bulkFindByConstraint", "bulkFindByIndex"];
|
|
1557
|
+
/** Node write method names: never available on a read-only StoreView. */
|
|
1558
|
+
declare const NODE_WRITE_NAMES: readonly ["create", "createFromRecord", "update", "updateWhere", "delete", "hardDelete", "upsertById", "upsertByIdFromRecord", "bulkCreate", "bulkUpsertById", "bulkInsert", "bulkDelete", "getOrCreateByConstraint", "bulkGetOrCreateByConstraint"];
|
|
1559
|
+
/** Temporal-aware edge read method names. */
|
|
1560
|
+
declare const EDGE_TEMPORAL_READ_NAMES: readonly ["getById", "getByIds", "find", "count", "findFrom", "findTo", "bulkFindFrom", "bulkFindTo", "findByEndpoints"];
|
|
1561
|
+
/** Deferred edge batch-read method names. */
|
|
1562
|
+
declare const EDGE_BATCH_READ_NAMES: readonly ["batchFindFrom", "batchFindTo", "batchFindByEndpoints"];
|
|
1563
|
+
/** Edge write method names: never available on a read-only StoreView. */
|
|
1564
|
+
declare const EDGE_WRITE_NAMES: readonly ["create", "update", "delete", "hardDelete", "bulkCreate", "bulkUpsertById", "bulkInsert", "bulkDelete", "getOrCreateByEndpoints", "bulkGetOrCreateByEndpoints"];
|
|
1565
|
+
/** Recorded-time collection point reads that reconstruct safely by id. */
|
|
1566
|
+
declare const RECORDED_POINT_READ_NAMES: readonly ["getById", "getByIds"];
|
|
1567
|
+
|
|
1737
1568
|
/**
|
|
1738
|
-
*
|
|
1569
|
+
* Store types for TypeGraph operations.
|
|
1739
1570
|
*/
|
|
1740
|
-
|
|
1571
|
+
|
|
1741
1572
|
/**
|
|
1742
|
-
*
|
|
1743
|
-
*
|
|
1573
|
+
* Canonical mapping from snake_case row fields to camelCase meta fields.
|
|
1574
|
+
*
|
|
1575
|
+
* This is the single source of truth for which row columns become metadata.
|
|
1576
|
+
* Both the Meta types and the row-to-meta functions in row-mappers.ts must
|
|
1577
|
+
* stay in sync with this mapping. If you add a temporal/audit column to a
|
|
1578
|
+
* row type, add the mapping here — the compiler will then force you to
|
|
1579
|
+
* update the row mapper functions as well (since their return type is
|
|
1580
|
+
* NodeMeta/EdgeMeta, which is derived from this mapping).
|
|
1744
1581
|
*/
|
|
1745
|
-
type
|
|
1746
|
-
|
|
1747
|
-
|
|
1748
|
-
|
|
1749
|
-
|
|
1750
|
-
|
|
1751
|
-
|
|
1752
|
-
[K in keyof G["edges"] & string]-?: TypedEdgeCollection<G["edges"][K]>;
|
|
1753
|
-
};
|
|
1754
|
-
/** Temporal-aware node reads — a {@link StoreView} pins these. */
|
|
1755
|
-
type NodeTemporalReads<N extends NodeType, CN extends string = string> = Pick<NodeCollection<N, CN>, (typeof NODE_TEMPORAL_READ_NAMES)[number]>;
|
|
1582
|
+
type TemporalMetaFieldMap = Readonly<{
|
|
1583
|
+
valid_from: "validFrom";
|
|
1584
|
+
valid_to: "validTo";
|
|
1585
|
+
created_at: "createdAt";
|
|
1586
|
+
updated_at: "updatedAt";
|
|
1587
|
+
deleted_at: "deletedAt";
|
|
1588
|
+
}>;
|
|
1756
1589
|
/**
|
|
1757
|
-
*
|
|
1758
|
-
* axis, so a {@link StoreView} delegates them on a `current` pin and refuses
|
|
1759
|
-
* them on a temporal pin.
|
|
1590
|
+
* Maps row fields to their camelCase meta counterparts, preserving types.
|
|
1760
1591
|
*/
|
|
1761
|
-
type
|
|
1762
|
-
|
|
1763
|
-
|
|
1764
|
-
/** Temporal-aware edge reads — a {@link StoreView} pins these. */
|
|
1765
|
-
type EdgeTemporalReads<E extends AnyEdgeType, From extends NodeType = NodeType, To extends NodeType = NodeType> = Pick<EdgeCollection<E, From, To>, (typeof EDGE_TEMPORAL_READ_NAMES)[number]>;
|
|
1592
|
+
type MapRowToMeta<R extends Readonly<Record<string, unknown>>, M extends Readonly<Record<string, string>>> = Readonly<{
|
|
1593
|
+
[SnakeKey in keyof M as M[SnakeKey] & string]: SnakeKey extends keyof R ? R[SnakeKey] : never;
|
|
1594
|
+
}>;
|
|
1766
1595
|
/**
|
|
1767
|
-
*
|
|
1768
|
-
*
|
|
1596
|
+
* Metadata for a node instance.
|
|
1597
|
+
* Derived from NodeRow via TemporalMetaFieldMap + version.
|
|
1598
|
+
*
|
|
1599
|
+
* Adding a new metadata column requires:
|
|
1600
|
+
* 1. Add the column to NodeRow in backend/types.ts
|
|
1601
|
+
* 2. Add the mapping to TemporalMetaFieldMap above
|
|
1602
|
+
* 3. The compiler will error in rowToNodeMeta() until you add the field there
|
|
1769
1603
|
*/
|
|
1770
|
-
type
|
|
1771
|
-
|
|
1772
|
-
|
|
1604
|
+
type NodeMeta = MapRowToMeta<NodeRow, TemporalMetaFieldMap> & Readonly<{
|
|
1605
|
+
version: NodeRow["version"];
|
|
1606
|
+
}>;
|
|
1773
1607
|
/**
|
|
1774
|
-
*
|
|
1775
|
-
*
|
|
1776
|
-
*
|
|
1777
|
-
*
|
|
1778
|
-
*
|
|
1779
|
-
* pinned form of {@link NodeTemporalReads}.
|
|
1608
|
+
* A node instance in the graph.
|
|
1609
|
+
*
|
|
1610
|
+
* Properties from the schema are spread at the top level for ergonomic access:
|
|
1611
|
+
* - `node.name` instead of `node.props.name`
|
|
1612
|
+
* - System metadata is under `node.meta.*`
|
|
1780
1613
|
*/
|
|
1781
|
-
type
|
|
1782
|
-
|
|
1783
|
-
|
|
1784
|
-
|
|
1785
|
-
|
|
1786
|
-
/** Find nodes matching criteria at the view's pinned coordinate. */
|
|
1787
|
-
find: (filter?: Readonly<{
|
|
1788
|
-
where?: (accessor: NodeAccessor<N>) => Predicate;
|
|
1789
|
-
limit?: number;
|
|
1790
|
-
offset?: number;
|
|
1791
|
-
}>) => Promise<Node<N>[]>;
|
|
1792
|
-
/** Count nodes at the view's pinned coordinate. */
|
|
1793
|
-
count: () => Promise<number>;
|
|
1794
|
-
}> & NodeCurrentReads<N, CN>;
|
|
1614
|
+
type Node<N extends NodeType = NodeType> = Readonly<{
|
|
1615
|
+
kind: N["kind"];
|
|
1616
|
+
id: NodeId<N>;
|
|
1617
|
+
meta: NodeMeta;
|
|
1618
|
+
}> & Readonly<z.infer<N["schema"]>>;
|
|
1795
1619
|
/**
|
|
1796
|
-
*
|
|
1797
|
-
* kind, mirroring {@link StoreViewNodeCollection}. Every edge read —
|
|
1798
|
-
* including `findByEndpoints` — honors the pin via the same temporal model,
|
|
1799
|
-
* so (unlike nodes) there are no current-state-only edge reads.
|
|
1620
|
+
* Input for creating a node.
|
|
1800
1621
|
*/
|
|
1801
|
-
type
|
|
1802
|
-
|
|
1803
|
-
|
|
1804
|
-
|
|
1805
|
-
|
|
1806
|
-
|
|
1807
|
-
find: (filter?: Readonly<{
|
|
1808
|
-
from?: NodeRef<From>;
|
|
1809
|
-
to?: NodeRef<To>;
|
|
1810
|
-
limit?: number;
|
|
1811
|
-
offset?: number;
|
|
1812
|
-
}>) => Promise<Edge<E, From, To>[]>;
|
|
1813
|
-
/** Count edges matching criteria at the view's pinned coordinate. */
|
|
1814
|
-
count: (filter?: Readonly<{
|
|
1815
|
-
from?: NodeRef<From>;
|
|
1816
|
-
to?: NodeRef<To>;
|
|
1817
|
-
}>) => Promise<number>;
|
|
1818
|
-
/** Find edges from a specific node at the view's pinned coordinate. */
|
|
1819
|
-
findFrom: (from: NodeRef<From>) => Promise<Edge<E, From, To>[]>;
|
|
1820
|
-
/** Find edges to a specific node at the view's pinned coordinate. */
|
|
1821
|
-
findTo: (to: NodeRef<To>) => Promise<Edge<E, From, To>[]>;
|
|
1822
|
-
/** Find the edge between two endpoints at the view's pinned coordinate. */
|
|
1823
|
-
findByEndpoints: (from: NodeRef<From>, to: NodeRef<To>, options?: EdgeFindByEndpointsOptions<E>) => Promise<Edge<E, From, To> | undefined>;
|
|
1622
|
+
type CreateNodeInput<N extends NodeType = NodeType> = Readonly<{
|
|
1623
|
+
kind: N["kind"];
|
|
1624
|
+
id?: string;
|
|
1625
|
+
props: z.infer<N["schema"]>;
|
|
1626
|
+
validFrom?: string;
|
|
1627
|
+
validTo?: string;
|
|
1824
1628
|
}>;
|
|
1825
1629
|
/**
|
|
1826
|
-
*
|
|
1827
|
-
* extracting the edge type and from/to node types — the read-only
|
|
1828
|
-
* counterpart of {@link TypedEdgeCollection}.
|
|
1630
|
+
* Input for updating a node.
|
|
1829
1631
|
*/
|
|
1830
|
-
type
|
|
1831
|
-
|
|
1832
|
-
|
|
1833
|
-
|
|
1834
|
-
|
|
1835
|
-
/** Mapped type of all read-only view edge collections for a graph. */
|
|
1836
|
-
type StoreViewEdgeCollections<G extends GraphDef> = {
|
|
1837
|
-
[K in keyof G["edges"] & string]-?: TypedStoreViewEdgeCollection<G["edges"][K]>;
|
|
1838
|
-
};
|
|
1839
|
-
/** Options for one bounded, forward-only recorded-time collection scan. */
|
|
1840
|
-
type RecordedScanOptions = Readonly<{
|
|
1841
|
-
/** Maximum entities to return. Defaults to 1,000 and cannot exceed 1,000. */
|
|
1842
|
-
limit?: number;
|
|
1843
|
-
/** Opaque cursor returned by the preceding page. */
|
|
1844
|
-
after?: string;
|
|
1845
|
-
}>;
|
|
1846
|
-
/** One page from a deterministic recorded-time collection scan. */
|
|
1847
|
-
type RecordedScanPage<T> = Readonly<{
|
|
1848
|
-
/** Entities ordered by canonical id ascending. */
|
|
1849
|
-
data: readonly T[];
|
|
1850
|
-
/** Cursor for the next page, or `undefined` when the scan is complete. */
|
|
1851
|
-
nextCursor: string | undefined;
|
|
1852
|
-
/** Whether another page exists after this one. */
|
|
1853
|
-
hasNextPage: boolean;
|
|
1854
|
-
}>;
|
|
1855
|
-
/** Recorded-time reconstructing reads for one node kind. */
|
|
1856
|
-
type RecordedStoreViewNodeCollection<N extends NodeType> = Pick<StoreViewNodeCollection<N>, (typeof RECORDED_POINT_READ_NAMES)[number]> & Readonly<{
|
|
1857
|
-
/** Scan one bounded page at the view's pinned coordinate. */
|
|
1858
|
-
scan: (options?: RecordedScanOptions) => Promise<RecordedScanPage<Node<N>>>;
|
|
1859
|
-
}>;
|
|
1860
|
-
/** Recorded-time reconstructing reads for one edge kind. */
|
|
1861
|
-
type RecordedStoreViewEdgeCollection<E extends AnyEdgeType, From extends NodeType = NodeType, To extends NodeType = NodeType> = Pick<StoreViewEdgeCollection<E, From, To>, (typeof RECORDED_POINT_READ_NAMES)[number]> & Readonly<{
|
|
1862
|
-
/** Scan one bounded page at the view's pinned coordinate. */
|
|
1863
|
-
scan: (options?: RecordedScanOptions) => Promise<RecordedScanPage<Edge<E, From, To>>>;
|
|
1632
|
+
type UpdateNodeInput<N extends NodeType = NodeType> = Readonly<{
|
|
1633
|
+
kind: N["kind"];
|
|
1634
|
+
id: NodeId<N>;
|
|
1635
|
+
props: Partial<z.infer<N["schema"]>>;
|
|
1636
|
+
validTo?: string;
|
|
1864
1637
|
}>;
|
|
1865
|
-
/** Recorded-time edge collection derived from an `EdgeRegistration`. */
|
|
1866
|
-
type TypedRecordedStoreViewEdgeCollection<R extends EdgeRegistration> = RecordedStoreViewEdgeCollection<R["type"], EdgeFromTypes<R> extends NodeType ? EdgeFromTypes<R> : NodeType, EdgeToTypes<R> extends NodeType ? EdgeToTypes<R> : NodeType>;
|
|
1867
|
-
/** Mapped type of all recorded-time node reconstructing-read collections. */
|
|
1868
|
-
type RecordedStoreViewNodeCollections<G extends GraphDef> = {
|
|
1869
|
-
[K in keyof G["nodes"] & string]-?: RecordedStoreViewNodeCollection<G["nodes"][K]["type"]>;
|
|
1870
|
-
};
|
|
1871
|
-
/** Mapped type of all recorded-time edge reconstructing-read collections. */
|
|
1872
|
-
type RecordedStoreViewEdgeCollections<G extends GraphDef> = {
|
|
1873
|
-
[K in keyof G["edges"] & string]-?: TypedRecordedStoreViewEdgeCollection<G["edges"][K]>;
|
|
1874
|
-
};
|
|
1875
1638
|
/**
|
|
1876
|
-
*
|
|
1877
|
-
*
|
|
1878
|
-
* in, so an adapter caller branches on capability instead of truthiness-testing
|
|
1879
|
-
* `tx.sql`. The non-available variants omit `sql` entirely, so even reading the
|
|
1880
|
-
* handle requires first narrowing `sqlAvailability` to `"available"`. The
|
|
1881
|
-
* runtime object keeps a fail-loud getter under history / revision tracking for
|
|
1882
|
-
* JavaScript and type-suppressed callers. See
|
|
1883
|
-
* {@link AdapterTransactionContext} for the per-value semantics.
|
|
1639
|
+
* Metadata for an edge instance.
|
|
1640
|
+
* Derived from EdgeRow via TemporalMetaFieldMap (edges have no version).
|
|
1884
1641
|
*/
|
|
1885
|
-
type
|
|
1886
|
-
type AdapterTransactionSqlAccess<TNativeTransaction> = Readonly<{
|
|
1887
|
-
sql: TNativeTransaction;
|
|
1888
|
-
sqlAvailability: "available";
|
|
1889
|
-
}> | Readonly<{
|
|
1890
|
-
sqlAvailability: "history" | "revisionTracking";
|
|
1891
|
-
}> | Readonly<{
|
|
1892
|
-
sqlAvailability: "unavailable";
|
|
1893
|
-
}>;
|
|
1894
|
-
declare const TRANSACTION_RUNTIME: unique symbol;
|
|
1895
|
-
type TransactionRuntime = Readonly<{
|
|
1896
|
-
backend: TransactionBackend;
|
|
1897
|
-
runNodeOperationHooks: <T>(operation: "create" | "update" | "delete", kind: string, id: string, fn: () => Promise<T>) => Promise<T>;
|
|
1898
|
-
}>;
|
|
1642
|
+
type EdgeMeta = MapRowToMeta<EdgeRow, TemporalMetaFieldMap>;
|
|
1899
1643
|
/**
|
|
1900
|
-
*
|
|
1901
|
-
* while exposing only a read-only backend projection bound to the transaction.
|
|
1902
|
-
* Adapter-native handles are available only through
|
|
1903
|
-
* {@link AdapterTransactionContext}; arbitrary backend writes are absent from
|
|
1904
|
-
* every public transaction context. TypeGraph's non-enumerable symbol port is
|
|
1905
|
-
* an unsupported implementation detail, not a JavaScript security boundary:
|
|
1906
|
-
* reflective code can still discover symbol properties.
|
|
1644
|
+
* An edge instance in the graph.
|
|
1907
1645
|
*
|
|
1908
|
-
*
|
|
1909
|
-
*
|
|
1910
|
-
*
|
|
1911
|
-
* const person = await tx.nodes.Person.create({ name: "Alice" });
|
|
1912
|
-
* const company = await tx.nodes.Company.create({ name: "Acme" });
|
|
1913
|
-
* await tx.edges.worksAt.create(person, company, { role: "Engineer" });
|
|
1914
|
-
* });
|
|
1915
|
-
* ```
|
|
1646
|
+
* Properties from the schema are spread at the top level for ergonomic access:
|
|
1647
|
+
* - `edge.role` instead of `edge.props.role`
|
|
1648
|
+
* - System metadata is under `edge.meta.*`
|
|
1916
1649
|
*/
|
|
1917
|
-
type
|
|
1918
|
-
|
|
1919
|
-
|
|
1920
|
-
|
|
1921
|
-
|
|
1922
|
-
|
|
1923
|
-
|
|
1924
|
-
|
|
1925
|
-
|
|
1926
|
-
* registered in this graph.
|
|
1927
|
-
*/
|
|
1928
|
-
getNodeCollection: (kind: string) => DynamicNodeCollection | undefined;
|
|
1929
|
-
}>;
|
|
1650
|
+
type Edge<E extends AnyEdgeType = EdgeType, From extends NodeType = NodeType, To extends NodeType = NodeType> = Readonly<{
|
|
1651
|
+
id: EdgeId<E>;
|
|
1652
|
+
kind: E["kind"];
|
|
1653
|
+
fromKind: From["kind"];
|
|
1654
|
+
fromId: NodeId<From>;
|
|
1655
|
+
toKind: To["kind"];
|
|
1656
|
+
toId: NodeId<To>;
|
|
1657
|
+
meta: EdgeMeta;
|
|
1658
|
+
}> & Readonly<z.infer<E["schema"]>>;
|
|
1930
1659
|
/**
|
|
1931
|
-
*
|
|
1932
|
-
* operations. Managed Stores use this surface so adapter-native handles never
|
|
1933
|
-
* enter their public contract.
|
|
1660
|
+
* Input for creating an edge.
|
|
1934
1661
|
*/
|
|
1935
|
-
type
|
|
1662
|
+
type CreateEdgeInput<E extends AnyEdgeType = EdgeType> = Readonly<{
|
|
1663
|
+
kind: E["kind"];
|
|
1664
|
+
id?: string;
|
|
1665
|
+
fromKind: string;
|
|
1666
|
+
fromId: string;
|
|
1667
|
+
toKind: string;
|
|
1668
|
+
toId: string;
|
|
1669
|
+
props: z.infer<E["schema"]>;
|
|
1670
|
+
validFrom?: string;
|
|
1671
|
+
validTo?: string;
|
|
1672
|
+
}>;
|
|
1936
1673
|
/**
|
|
1937
|
-
*
|
|
1938
|
-
* portable graph collections, it carries the adapter-native handle when that
|
|
1939
|
-
* capability is available. The TypeGraph backend remains the same runtime
|
|
1940
|
-
* read projection as the portable context; adapter-native writes intentionally
|
|
1941
|
-
* go through `sql`, making that escape hatch explicit.
|
|
1674
|
+
* Input for updating an edge.
|
|
1942
1675
|
*/
|
|
1943
|
-
type
|
|
1676
|
+
type UpdateEdgeInput<E extends AnyEdgeType = EdgeType> = Readonly<{
|
|
1677
|
+
id: EdgeId<E>;
|
|
1678
|
+
props: Partial<z.infer<E["schema"]>>;
|
|
1679
|
+
validTo?: string;
|
|
1680
|
+
}>;
|
|
1944
1681
|
/**
|
|
1945
|
-
*
|
|
1946
|
-
* contexts (`transactionWithReceipt`, `withRecordedTransaction`). Runs `fn`,
|
|
1947
|
-
* passing it a **scoped context** — a second view over the same transaction — and
|
|
1948
|
-
* returns a {@link TransactionOutcome} whose receipt counts exactly the writes
|
|
1949
|
-
* made *through that scoped context* (`scoped.nodes` / `scoped.edges`).
|
|
1950
|
-
*
|
|
1951
|
-
* Attribution is by **which context you write through**, not by timing. A write
|
|
1952
|
-
* through the scoped context counts in both the scope and the outer receipt (it
|
|
1953
|
-
* happened in the transaction); a write through the outer `tx` during the scope
|
|
1954
|
-
* counts only in the outer receipt. This makes overlapping and concurrent
|
|
1955
|
-
* measures safe by construction — two scopes running under `Promise.all`, each
|
|
1956
|
-
* writing through its own scoped context, never cross-count. Nesting composes:
|
|
1957
|
-
* `scoped.measure(...)` opens a child scope that counts in itself, every
|
|
1958
|
-
* ancestor scope, and the outer receipt.
|
|
1959
|
-
*
|
|
1960
|
-
* Counts otherwise inherit {@link TransactionReceipt} (bulk by input length, a
|
|
1961
|
-
* rejected write counts 0). The returned receipt's `recorded` is **always
|
|
1962
|
-
* `undefined`**: the recorded commit instant is a per-transaction flush concern,
|
|
1963
|
-
* unknowable mid-transaction.
|
|
1682
|
+
* Options for node and edge queries.
|
|
1964
1683
|
*/
|
|
1965
|
-
type
|
|
1684
|
+
type NoRecordedCoordinate = Readonly<{
|
|
1685
|
+
/**
|
|
1686
|
+
* Recorded/system-time coordinates are internal-only and supplied by
|
|
1687
|
+
* RecordedStoreView. A public options object carrying this key is a type
|
|
1688
|
+
* error even when the object is pre-bound before the call site.
|
|
1689
|
+
*/
|
|
1690
|
+
recordedAsOf?: never;
|
|
1691
|
+
}>;
|
|
1692
|
+
type QueryOptions = NoRecordedCoordinate & Readonly<{
|
|
1693
|
+
/** Temporal mode for the query */
|
|
1694
|
+
temporalMode?: TemporalMode;
|
|
1695
|
+
/** Specific timestamp for asOf queries */
|
|
1696
|
+
asOf?: string;
|
|
1697
|
+
}>;
|
|
1966
1698
|
/**
|
|
1967
|
-
*
|
|
1968
|
-
* receipt-enabled entry points (`transactionWithReceipt`,
|
|
1969
|
-
* `withRecordedTransaction`) hand a callback this type; plain `transaction()`
|
|
1970
|
-
* contexts have no recorder and therefore no `measure`, keeping that path
|
|
1971
|
-
* zero-overhead. Assignable to {@link TransactionContext}, so a projector helper
|
|
1972
|
-
* typed `(tx: TransactionContext<G>) => ...` accepts a measurable context. The
|
|
1973
|
-
* scoped context handed to `measure` is itself measurable, so scopes nest.
|
|
1699
|
+
* Context passed to observability hooks.
|
|
1974
1700
|
*/
|
|
1975
|
-
type
|
|
1976
|
-
|
|
1977
|
-
|
|
1978
|
-
/**
|
|
1979
|
-
|
|
1980
|
-
|
|
1701
|
+
type HookContext = Readonly<{
|
|
1702
|
+
/** Unique ID for this operation */
|
|
1703
|
+
operationId: string;
|
|
1704
|
+
/** Graph ID */
|
|
1705
|
+
graphId: string;
|
|
1706
|
+
/** Timestamp when operation started */
|
|
1707
|
+
startedAt: Date;
|
|
1981
1708
|
}>;
|
|
1982
1709
|
/**
|
|
1983
|
-
*
|
|
1984
|
-
* method's parameter list. Return types are preserved unchanged.
|
|
1710
|
+
* Context for one SQL statement a query builder submits to the backend.
|
|
1985
1711
|
*
|
|
1986
|
-
*
|
|
1987
|
-
*
|
|
1988
|
-
*
|
|
1989
|
-
* 3. Branded IDs nested one level inside bulk-item object arrays
|
|
1990
|
-
*/
|
|
1991
|
-
type WidenBrandedIds<T> = {
|
|
1992
|
-
readonly [K in keyof T]: T[K] extends (...args: infer A) => infer R ? (...args: {
|
|
1993
|
-
[P in keyof A]: UnbrandParam<A[P]>;
|
|
1994
|
-
}) => R : T[K];
|
|
1995
|
-
};
|
|
1996
|
-
/** Replace a branded ID with `string`, recursing one level into arrays. */
|
|
1997
|
-
type UnbrandParam<T> = T extends NodeId<NodeType> ? string : T extends EdgeId<AnyEdgeType> ? string : T extends readonly NodeId<NodeType>[] ? readonly string[] : T extends readonly EdgeId<AnyEdgeType>[] ? readonly string[] : T extends readonly (infer Item extends Record<string, unknown>)[] ? readonly UnbrandRecord<Item>[] : T;
|
|
1998
|
-
/** Replace branded ID values in object properties (does not recurse into nested structures). */
|
|
1999
|
-
type UnbrandRecord<T extends Record<string, unknown>> = {
|
|
2000
|
-
readonly [K in keyof T]: T[K] extends NodeId<NodeType> ? string : T[K] extends EdgeId<AnyEdgeType> ? string : T[K];
|
|
2001
|
-
};
|
|
2002
|
-
/**
|
|
2003
|
-
* A node collection with widened generics for runtime string-keyed access.
|
|
2004
|
-
*
|
|
2005
|
-
* This is the return type of `store.getNodeCollection(kind)`. It exposes
|
|
2006
|
-
* the full `NodeCollection` API but with `NodeType` and `string` constraint
|
|
2007
|
-
* names instead of the specific generic parameters, since the concrete type
|
|
2008
|
-
* is not known at compile time.
|
|
2009
|
-
*
|
|
2010
|
-
* ID parameters accept plain `string` instead of branded `NodeId<N>`, since
|
|
2011
|
-
* the dynamic path typically receives IDs from edge metadata, snapshots,
|
|
2012
|
-
* or external input where the brand is not available.
|
|
1712
|
+
* A single logical query can emit more than one context, for example when a
|
|
1713
|
+
* selective projection falls back to a full-row fetch. Backend-internal setup
|
|
1714
|
+
* statements are not exposed as separate query-hook events.
|
|
2013
1715
|
*/
|
|
2014
|
-
type
|
|
1716
|
+
type QueryHookContext = HookContext & Readonly<{
|
|
1717
|
+
/** The SQL statement being executed */
|
|
1718
|
+
sql: string;
|
|
1719
|
+
/** Query parameters */
|
|
1720
|
+
params: readonly unknown[];
|
|
1721
|
+
}>;
|
|
2015
1722
|
/**
|
|
2016
|
-
*
|
|
2017
|
-
*
|
|
2018
|
-
* This is the return type of `store.getEdgeCollection(kind)`. It exposes
|
|
2019
|
-
* the full `EdgeCollection` API but with `NodeType` endpoint types, since
|
|
2020
|
-
* the concrete from/to types are not known at compile time.
|
|
2021
|
-
*
|
|
2022
|
-
* ID parameters accept plain `string` instead of branded `EdgeId<E>`, since
|
|
2023
|
-
* the dynamic path typically receives IDs from edge metadata, snapshots,
|
|
2024
|
-
* or external input where the brand is not available.
|
|
1723
|
+
* Operation hook context for CRUD operations.
|
|
2025
1724
|
*/
|
|
2026
|
-
type
|
|
1725
|
+
type OperationHookContext = HookContext & Readonly<{
|
|
1726
|
+
/** Operation type */
|
|
1727
|
+
operation: "create" | "update" | "delete";
|
|
1728
|
+
/** Entity type */
|
|
1729
|
+
entity: KindEntity;
|
|
1730
|
+
/** Kind of node or edge */
|
|
1731
|
+
kind: string;
|
|
1732
|
+
/** Entity ID */
|
|
1733
|
+
id: string;
|
|
1734
|
+
}>;
|
|
1735
|
+
/** Context for one set-based collection mutation. */
|
|
1736
|
+
type BulkOperationHookContext = HookContext & Readonly<{
|
|
1737
|
+
operation: "updateWhere";
|
|
1738
|
+
entity: "node";
|
|
1739
|
+
kind: string;
|
|
1740
|
+
}>;
|
|
2027
1741
|
/**
|
|
2028
|
-
*
|
|
2029
|
-
* node and edge collections.
|
|
1742
|
+
* Observability hooks for monitoring store operations.
|
|
2030
1743
|
*
|
|
2031
|
-
*
|
|
2032
|
-
*
|
|
2033
|
-
* This is intentional: unique constraints are graph-registration-level
|
|
2034
|
-
* details that differ between graphs sharing the same node types.
|
|
1744
|
+
* Note: Batch operations (`bulkCreate`, `bulkInsert`, `bulkUpsertById`) skip
|
|
1745
|
+
* per-item operation hooks for throughput. Query hooks still fire normally.
|
|
2035
1746
|
*
|
|
2036
1747
|
* @example
|
|
2037
1748
|
* ```typescript
|
|
2038
|
-
*
|
|
2039
|
-
*
|
|
2040
|
-
*
|
|
2041
|
-
*
|
|
2042
|
-
*
|
|
1749
|
+
* const hooks: StoreHooks = {
|
|
1750
|
+
* onQueryStart: (ctx) => {
|
|
1751
|
+
* console.log(`[${ctx.operationId}] Query: ${ctx.sql}`);
|
|
1752
|
+
* },
|
|
1753
|
+
* onQueryEnd: (ctx, result) => {
|
|
1754
|
+
* const duration = Date.now() - ctx.startedAt.getTime();
|
|
1755
|
+
* console.log(`[${ctx.operationId}] Completed in ${duration}ms`);
|
|
1756
|
+
* },
|
|
1757
|
+
* onError: (ctx, error) => {
|
|
1758
|
+
* console.error(`[${ctx.operationId}] Error:`, error);
|
|
1759
|
+
* },
|
|
1760
|
+
* };
|
|
2043
1761
|
*
|
|
2044
|
-
*
|
|
2045
|
-
* store: CoreStore,
|
|
2046
|
-
* document: Node<typeof Document>,
|
|
2047
|
-
* text: string,
|
|
2048
|
-
* ) {
|
|
2049
|
-
* const chunk = await store.nodes.Chunk.create({ text });
|
|
2050
|
-
* await store.edges.hasChunk.create(document, chunk);
|
|
2051
|
-
* return chunk;
|
|
2052
|
-
* }
|
|
1762
|
+
* const store = createStore(graph, backend, { hooks });
|
|
2053
1763
|
* ```
|
|
2054
|
-
*
|
|
2055
|
-
* Both `Store<G>` and `TransactionContext<G>` are structurally assignable
|
|
2056
|
-
* to a `StoreProjection` whose keys are a subset of `G`.
|
|
2057
|
-
*/
|
|
2058
|
-
type StoreProjection<G extends GraphDef, N extends keyof G["nodes"] & string = never, E extends keyof G["edges"] & string = never> = Readonly<{
|
|
2059
|
-
nodes: {
|
|
2060
|
-
[K in N]-?: NodeCollection<G["nodes"][K]["type"], never>;
|
|
2061
|
-
};
|
|
2062
|
-
edges: Pick<GraphEdgeCollections<G>, E>;
|
|
2063
|
-
}>;
|
|
2064
|
-
|
|
2065
|
-
/**
|
|
2066
|
-
* ExecutableAggregateQuery - A query with aggregate functions that can be executed.
|
|
2067
|
-
*/
|
|
2068
|
-
|
|
2069
|
-
/**
|
|
2070
|
-
* Result type for aggregate queries.
|
|
2071
|
-
* Maps field refs to their value types and aggregates to numbers.
|
|
2072
|
-
*/
|
|
2073
|
-
type AggregateResult<R extends Record<string, FieldRef | AggregateExpr>> = {
|
|
2074
|
-
[K in keyof R]: R[K] extends AggregateExpr ? number : R[K] extends FieldRef ? unknown : never;
|
|
2075
|
-
};
|
|
2076
|
-
/**
|
|
2077
|
-
* An aggregate query that can be executed.
|
|
2078
1764
|
*/
|
|
2079
|
-
|
|
2080
|
-
|
|
2081
|
-
|
|
2082
|
-
/**
|
|
2083
|
-
|
|
2084
|
-
|
|
2085
|
-
|
|
1765
|
+
type StoreHooks = Readonly<{
|
|
1766
|
+
/** Called before each query-builder statement is submitted to the backend. */
|
|
1767
|
+
onQueryStart?: (ctx: QueryHookContext) => void;
|
|
1768
|
+
/** Called after each submitted query-builder statement succeeds. */
|
|
1769
|
+
onQueryEnd?: (ctx: QueryHookContext, result: Readonly<{
|
|
1770
|
+
rowCount: number;
|
|
1771
|
+
durationMs: number;
|
|
1772
|
+
}>) => void;
|
|
1773
|
+
/** Called before a CRUD operation starts */
|
|
1774
|
+
onOperationStart?: (ctx: OperationHookContext) => void;
|
|
1775
|
+
/** Called before a set-based collection mutation starts. */
|
|
1776
|
+
onBulkOperationStart?: (ctx: BulkOperationHookContext) => void;
|
|
2086
1777
|
/**
|
|
2087
|
-
*
|
|
2088
|
-
*
|
|
2089
|
-
* `
|
|
2090
|
-
*
|
|
2091
|
-
*
|
|
2092
|
-
*
|
|
2093
|
-
*
|
|
2094
|
-
*
|
|
2095
|
-
* `.orderBy("genre").orderBy("bookCount", "desc")` sorts by genre first,
|
|
2096
|
-
* then by book count within each genre.
|
|
2097
|
-
*
|
|
2098
|
-
* @example
|
|
2099
|
-
* ```typescript
|
|
2100
|
-
* // Top 2 authors by book count
|
|
2101
|
-
* store.query()
|
|
2102
|
-
* .from("Author", "a")
|
|
2103
|
-
* .traverse("wrote", "e")
|
|
2104
|
-
* .to("Book", "b")
|
|
2105
|
-
* .groupByNode("a")
|
|
2106
|
-
* .aggregate({ author: field("a", "name"), bookCount: count("b") })
|
|
2107
|
-
* .orderBy("bookCount", "desc")
|
|
2108
|
-
* .limit(2)
|
|
2109
|
-
* .execute();
|
|
2110
|
-
* ```
|
|
1778
|
+
* Called after a CRUD operation completes AND is durably committed. For a
|
|
1779
|
+
* top-level operation that is when its own transaction commits; for an
|
|
1780
|
+
* operation inside `store.transaction`, emission is deferred until the
|
|
1781
|
+
* enclosing transaction commits — if that commit fails, the operation is
|
|
1782
|
+
* reported through `onError` instead. (Inside an adopted transaction —
|
|
1783
|
+
* `withTransaction` / `withRecordedTransaction` — the commit belongs to
|
|
1784
|
+
* the caller and cannot be observed, so this fires when the operation
|
|
1785
|
+
* completes within the still-open transaction.)
|
|
2111
1786
|
*/
|
|
2112
|
-
|
|
1787
|
+
onOperationEnd?: (ctx: OperationHookContext, result: Readonly<{
|
|
1788
|
+
durationMs: number;
|
|
1789
|
+
}>) => void;
|
|
2113
1790
|
/**
|
|
2114
|
-
*
|
|
1791
|
+
* Called after a set-based mutation durably commits. Inside
|
|
1792
|
+
* `store.transaction`, emission is deferred until the enclosing commit.
|
|
2115
1793
|
*/
|
|
2116
|
-
|
|
1794
|
+
onBulkOperationEnd?: (ctx: BulkOperationHookContext, result: Readonly<{
|
|
1795
|
+
affectedCount: number;
|
|
1796
|
+
durationMs: number;
|
|
1797
|
+
}>) => void;
|
|
2117
1798
|
/**
|
|
2118
|
-
*
|
|
1799
|
+
* Called when an operation fails — including an operation that completed
|
|
1800
|
+
* inside a `store.transaction` whose commit then failed and rolled it
|
|
1801
|
+
* back.
|
|
2119
1802
|
*/
|
|
2120
|
-
|
|
1803
|
+
onError?: (ctx: HookContext, error: Error) => void;
|
|
1804
|
+
}>;
|
|
1805
|
+
type BaseStoreOptions = Readonly<{
|
|
1806
|
+
/** Observability hooks for monitoring */
|
|
1807
|
+
hooks?: StoreHooks;
|
|
2121
1808
|
/**
|
|
2122
|
-
*
|
|
1809
|
+
* Maintain a durable, graph-wide revision anchor for TypeGraph writes:
|
|
1810
|
+
* a random per-graph origin plus a monotonic revision clock. `branch()` uses
|
|
1811
|
+
* this anchor to validate that its base has not moved without
|
|
1812
|
+
* re-fingerprinting every live row, and cannot confuse a coincident clock in
|
|
1813
|
+
* a separately created store for its original base. `history: true` enables
|
|
1814
|
+
* the same tracking automatically through its recorded-time commit clock.
|
|
2123
1815
|
*
|
|
2124
|
-
*
|
|
2125
|
-
*
|
|
1816
|
+
* This is intentionally opt-in for live stores: each successful graph write
|
|
1817
|
+
* advances the anchor inside its write transaction. On PostgreSQL, those
|
|
1818
|
+
* transactions take a graph-scoped advisory lock until commit; writes to the
|
|
1819
|
+
* same graph therefore serialize. Enable it for branchable graphs, but size
|
|
1820
|
+
* high-throughput multi-writer workloads for that trade-off.
|
|
1821
|
+
*
|
|
1822
|
+
* Writes performed directly through a backend — including raw graph-table
|
|
1823
|
+
* writes through `tx.sql` — bypass the anchor and are outside the
|
|
1824
|
+
* revision-tracking contract.
|
|
2126
1825
|
*/
|
|
2127
|
-
|
|
2128
|
-
sql: string;
|
|
2129
|
-
params: readonly unknown[];
|
|
2130
|
-
}>;
|
|
1826
|
+
revisionTracking?: boolean;
|
|
2131
1827
|
/**
|
|
2132
|
-
*
|
|
1828
|
+
* Automatic planner-statistics refresh after large autocommit bulk
|
|
1829
|
+
* writes (bulkCreate and bulkInsert on nodes and edges). Stale statistics after a
|
|
1830
|
+
* bulk load are a whole class of planner cliffs: the planner keeps
|
|
1831
|
+
* pre-load row estimates until ANALYZE runs. When a single
|
|
1832
|
+
* autocommit bulk write reaches the threshold
|
|
1833
|
+
* ({@link AUTO_REFRESH_STATISTICS_ROW_THRESHOLD} rows by default),
|
|
1834
|
+
* the store runs `refreshStatistics()` after the write commits.
|
|
1835
|
+
* Pass a number to change the threshold, or `false` to disable.
|
|
1836
|
+
* Bulk writes inside a caller-provided transaction never
|
|
1837
|
+
* auto-refresh (statistics cannot see uncommitted rows); refresh
|
|
1838
|
+
* manually after commit. `importGraph` handles its own refresh.
|
|
2133
1839
|
*/
|
|
2134
|
-
|
|
1840
|
+
autoRefreshStatistics?: false | number;
|
|
2135
1841
|
/**
|
|
2136
|
-
*
|
|
1842
|
+
* Skip the write for an `upsertById` (or `bulkUpsertById` item) whose
|
|
1843
|
+
* validated props are value-identical to the existing live row. Default
|
|
1844
|
+
* off.
|
|
2137
1845
|
*
|
|
2138
|
-
*
|
|
2139
|
-
|
|
2140
|
-
|
|
2141
|
-
|
|
2142
|
-
|
|
2143
|
-
|
|
2144
|
-
|
|
2145
|
-
|
|
2146
|
-
|
|
2147
|
-
|
|
2148
|
-
|
|
2149
|
-
|
|
2150
|
-
|
|
2151
|
-
|
|
2152
|
-
|
|
2153
|
-
|
|
2154
|
-
|
|
2155
|
-
|
|
2156
|
-
|
|
2157
|
-
|
|
2158
|
-
|
|
2159
|
-
|
|
2160
|
-
|
|
2161
|
-
|
|
2162
|
-
|
|
2163
|
-
|
|
2164
|
-
|
|
2165
|
-
|
|
2166
|
-
|
|
2167
|
-
|
|
2168
|
-
|
|
2169
|
-
|
|
2170
|
-
|
|
2171
|
-
|
|
2172
|
-
|
|
2173
|
-
|
|
2174
|
-
|
|
2175
|
-
*
|
|
2176
|
-
*
|
|
2177
|
-
*
|
|
2178
|
-
*
|
|
2179
|
-
*
|
|
2180
|
-
*/
|
|
2181
|
-
fulltextStrategy?: FulltextStrategy | undefined;
|
|
2182
|
-
/**
|
|
2183
|
-
* Vector strategy override. When set, `field.similarTo(...)`
|
|
2184
|
-
* predicates compile against the strategy's per-`(kind, field)`
|
|
2185
|
-
* tables and distance expression. Callers read it from
|
|
2186
|
-
* `backend.vectorStrategy` so a backend-declared strategy (pgvector,
|
|
2187
|
-
* libsql-native, sqlite-vec) drives the per-field relevance scan.
|
|
2188
|
-
*/
|
|
2189
|
-
vectorStrategy?: VectorStrategy | undefined;
|
|
2190
|
-
/**
|
|
2191
|
-
* Whether the active backend supports SQL window functions such as
|
|
2192
|
-
* `ROW_NUMBER()`. Defaults to true for direct compiler callers.
|
|
2193
|
-
*/
|
|
2194
|
-
windowFunctions?: boolean | undefined;
|
|
2195
|
-
/**
|
|
2196
|
-
* Declared embedding slots `(kind, fieldPath) -> descriptor` used by
|
|
2197
|
-
* the `field.similarTo(...)` CTE to know which kinds in an alias
|
|
2198
|
-
* declare the field. Callers build it from the graph's node schemas.
|
|
2199
|
-
*/
|
|
2200
|
-
vectorSlots?: VectorSlotMap | undefined;
|
|
2201
|
-
/** Per-kind declared fulltext language (see buildFulltextLanguages). */
|
|
2202
|
-
fulltextLanguages?: ReadonlyMap<string, string> | undefined;
|
|
2203
|
-
/**
|
|
2204
|
-
* Recorded read relation to use when the AST carries `recordedAsOf`.
|
|
2205
|
-
* Supplying a recorded timestamp without this binding is rejected so the
|
|
2206
|
-
* compiler never silently swaps to TypeGraph's built-in history tables when
|
|
2207
|
-
* the store was only configured for live/valid-time reads.
|
|
2208
|
-
*/
|
|
2209
|
-
recordedReadBinding?: RecordedReadBinding | undefined;
|
|
2210
|
-
/**
|
|
2211
|
-
* How the "current" valid-time read instant is emitted. Defaults to
|
|
2212
|
-
* `"literal"` (a value frozen at compile time). The query builder's
|
|
2213
|
-
* compiled template cache passes `"placeholder"` so the instant is a
|
|
2214
|
-
* reserved execution-time slot, letting one compiled statement be reused
|
|
2215
|
-
* across executions with a fresh "now" each call. See {@link ReadInstantMode}.
|
|
1846
|
+
* Enable this for at-least-once / replay materializers. An event log that
|
|
1847
|
+
* re-delivers a byte-identical change would otherwise rewrite the row anyway:
|
|
1848
|
+
* today an `upsertById` on an existing id calls `updateNode`
|
|
1849
|
+
* unconditionally, allocating a fresh recorded instant and a new history row
|
|
1850
|
+
* per re-delivery.
|
|
1851
|
+
*
|
|
1852
|
+
* The win is scoped to re-delivery of the **current** value. A full
|
|
1853
|
+
* replay-from-zero over the current state still writes wherever the stream
|
|
1854
|
+
* superseded a value in place: re-applying an older value over the live row
|
|
1855
|
+
* is a genuine change (and restoring the current value afterwards is
|
|
1856
|
+
* another), so only streams whose rows never supersede each other replay
|
|
1857
|
+
* without churn. A rebuild that should avoid that re-walk belongs in a fresh
|
|
1858
|
+
* store — replay into it and publish it, rather than re-applying the log
|
|
1859
|
+
* over current state.
|
|
1860
|
+
*
|
|
1861
|
+
* When enabled, an upsert that would not change the stored value performs
|
|
1862
|
+
* **no write at all**: no `updateNode`, no recorded-time capture, no history
|
|
1863
|
+
* row, no revision-anchor advance, and no `update` operation hooks (nothing
|
|
1864
|
+
* happened, so nothing is reported). It resolves with the **existing** node,
|
|
1865
|
+
* preserving its original `validFrom` / `updatedAt` / `version`.
|
|
1866
|
+
*
|
|
1867
|
+
* Receipt shape is unchanged and needs no new signal: a coalesced upsert
|
|
1868
|
+
* still counts as one write intent (`writes.total` includes it), but
|
|
1869
|
+
* captures nothing (`receipt.recorded` stays `undefined` when it is the only
|
|
1870
|
+
* write) — the same shape a no-op delete already produces, so a consumer
|
|
1871
|
+
* that carries the prior anchor forward on `recorded === undefined` handles
|
|
1872
|
+
* it unchanged.
|
|
1873
|
+
*
|
|
1874
|
+
* A write is coalesced only when **all** of the following hold; otherwise the
|
|
1875
|
+
* normal write happens:
|
|
1876
|
+
* 1. An existing row is found for the id (else it is a create).
|
|
1877
|
+
* 2. That row is not soft-deleted (a deleted row resurrects — a real
|
|
1878
|
+
* change — and is never coalesced).
|
|
1879
|
+
* 3. The caller passed no explicit `validFrom` / `validTo` (an explicit
|
|
1880
|
+
* temporal override is a deliberate request and is never coalesced;
|
|
1881
|
+
* applied per item in the bulk path).
|
|
1882
|
+
* 4. The new props, merged over the stored props and run through the
|
|
1883
|
+
* kind's Zod schema (defaults applied, values normalized), are deeply
|
|
1884
|
+
* value-identical to the stored props (key order aside).
|
|
1885
|
+
*
|
|
1886
|
+
* Default-off because some consumers *want* an audit row per re-delivery as
|
|
1887
|
+
* proof the event was reprocessed; coalescing removes that signal.
|
|
2216
1888
|
*/
|
|
2217
|
-
|
|
1889
|
+
coalesceUnchangedUpserts?: boolean;
|
|
1890
|
+
/** SQL schema configuration from createSqlSchema(...) for custom table names */
|
|
1891
|
+
schema?: SqlSchema;
|
|
1892
|
+
/** Query default behaviors. */
|
|
1893
|
+
queryDefaults?: Readonly<{
|
|
1894
|
+
/** Default traversal ontology expansion mode (default: "inverse"). */
|
|
1895
|
+
traversalExpansion?: TraversalExpansion;
|
|
1896
|
+
}>;
|
|
2218
1897
|
}>;
|
|
2219
|
-
|
|
2220
1898
|
/**
|
|
2221
|
-
*
|
|
1899
|
+
* Store options without built-in recorded-time capture. A recorded read relation
|
|
1900
|
+
* can still be bound explicitly for hosts that populate history externally.
|
|
1901
|
+
*/
|
|
1902
|
+
type LiveStoreOptions = BaseStoreOptions & Readonly<{
|
|
1903
|
+
history?: false | undefined;
|
|
1904
|
+
recordedRead?: ExternalRecordedReadSource | undefined;
|
|
1905
|
+
}>;
|
|
1906
|
+
/** Live-store options that do not bind a recorded-read relation. */
|
|
1907
|
+
type UnboundLiveStoreOptions = LiveStoreOptions & Readonly<{
|
|
1908
|
+
recordedRead?: undefined;
|
|
1909
|
+
}>;
|
|
1910
|
+
/** Live-store options with an explicitly bound recorded-read relation. */
|
|
1911
|
+
type RecordedReadStoreOptions = LiveStoreOptions & Readonly<{
|
|
1912
|
+
recordedRead: NonNullable<LiveStoreOptions["recordedRead"]>;
|
|
1913
|
+
}>;
|
|
1914
|
+
/**
|
|
1915
|
+
* Store options with TypeGraph-managed recorded-time capture. `history: true`
|
|
1916
|
+
* captures TypeGraph writes and binds TypeGraph's built-in recorded relation
|
|
1917
|
+
* internally. Externally populated recorded read sources are read-only bindings
|
|
1918
|
+
* and are intentionally accepted only by {@link LiveStoreOptions}.
|
|
1919
|
+
*/
|
|
1920
|
+
type HistoryStoreOptions = BaseStoreOptions & Readonly<{
|
|
1921
|
+
history: true;
|
|
1922
|
+
recordedRead?: never;
|
|
1923
|
+
}>;
|
|
1924
|
+
/**
|
|
1925
|
+
* Options for creating a store.
|
|
1926
|
+
*/
|
|
1927
|
+
type StoreOptions = LiveStoreOptions | HistoryStoreOptions;
|
|
1928
|
+
/**
|
|
1929
|
+
* A mutable handle to the current `Store`, used by `store.evolve(...)`
|
|
1930
|
+
* so long-lived consumers can dereference through the ref and pick up
|
|
1931
|
+
* the new Store after each evolve call. When the ref is passed via
|
|
1932
|
+
* `evolve(extension, { ref })`, `current` is overwritten with the replacement
|
|
1933
|
+
* before a successful call resolves.
|
|
2222
1934
|
*
|
|
2223
|
-
*
|
|
2224
|
-
*
|
|
2225
|
-
*
|
|
1935
|
+
* **Request semantics.** Dereference once at request entry only when that
|
|
1936
|
+
* request will not change the schema. A schema-changing call such as
|
|
1937
|
+
* `evolve()` returns the Store for the resulting schema and updates
|
|
1938
|
+
* `ref.current`; a Store captured before that call remains pinned to the old
|
|
1939
|
+
* schema. Use the returned Store (or dereference `ref.current` again) for every
|
|
1940
|
+
* subsequent operation in the same request:
|
|
2226
1941
|
*
|
|
2227
|
-
*
|
|
2228
|
-
*
|
|
2229
|
-
*
|
|
2230
|
-
* (
|
|
2231
|
-
*
|
|
2232
|
-
*
|
|
2233
|
-
*
|
|
2234
|
-
*
|
|
1942
|
+
* ```ts
|
|
1943
|
+
* async function handleRequest(): Promise<void> {
|
|
1944
|
+
* const store = ref.current;
|
|
1945
|
+
* const evolved = await store.evolve(extension, { ref });
|
|
1946
|
+
* await evolved.materializeIndexes();
|
|
1947
|
+
* // ref.current === evolved
|
|
1948
|
+
* }
|
|
1949
|
+
* ```
|
|
1950
|
+
*
|
|
1951
|
+
* A `StoreRef` tracks only schema changes made by calls that receive that ref.
|
|
1952
|
+
* When another process or isolate can commit a schema version, compare
|
|
1953
|
+
* `getCommittedSchemaVersion()` with the cached version before reuse and call
|
|
1954
|
+
* `createVerifiedStore()` or `createVerifiedAdapterStore()` when it changes.
|
|
1955
|
+
*
|
|
1956
|
+
* Pure dereferenceable handle — no event/subscription machinery. If
|
|
1957
|
+
* consumers need eventing, they wrap the ref themselves.
|
|
2235
1958
|
*
|
|
2236
|
-
*
|
|
2237
|
-
*
|
|
2238
|
-
*
|
|
1959
|
+
* Generic over the held value (typically `Store<G>`) so the store
|
|
1960
|
+
* module can refer to it without importing the `Store` class into
|
|
1961
|
+
* `types.ts`. The type parameter is deliberately invariant: evolution writes
|
|
1962
|
+
* a replacement into `current`, so a ref for an adapter-only or history-only
|
|
1963
|
+
* Store must never be accepted by a Store that cannot preserve that surface.
|
|
2239
1964
|
*/
|
|
2240
|
-
|
|
2241
|
-
|
|
2242
|
-
|
|
2243
|
-
|
|
2244
|
-
|
|
2245
|
-
|
|
2246
|
-
|
|
2247
|
-
|
|
2248
|
-
|
|
2249
|
-
|
|
2250
|
-
|
|
2251
|
-
schemaIntrospector: SchemaIntrospector;
|
|
1965
|
+
interface StoreRef<in out T> {
|
|
1966
|
+
current: T;
|
|
1967
|
+
}
|
|
1968
|
+
/**
|
|
1969
|
+
* Result plus write summary. Returned by `store.transactionWithReceipt(fn)`,
|
|
1970
|
+
* `store.withRecordedTransaction(externalTx, fn)` (the adopted-commit path), and
|
|
1971
|
+
* `tx.measure(fn)` (a scoped sub-receipt). See {@link TransactionReceipt}.
|
|
1972
|
+
*/
|
|
1973
|
+
type TransactionOutcome<T> = Readonly<{
|
|
1974
|
+
result: T;
|
|
1975
|
+
receipt: TransactionReceipt;
|
|
2252
1976
|
}>;
|
|
2253
1977
|
/**
|
|
2254
|
-
*
|
|
2255
|
-
* how a reused prepared query runs a cached SQL template with a fresh read
|
|
2256
|
-
* instant filled per call.
|
|
1978
|
+
* Transaction write summary.
|
|
2257
1979
|
*
|
|
2258
|
-
*
|
|
2259
|
-
*
|
|
2260
|
-
* const prepared = store.query()
|
|
2261
|
-
* .from("Person", "p")
|
|
2262
|
-
* .whereNode("p", (p) => p.name.eq(param("name")))
|
|
2263
|
-
* .select((ctx) => ctx.p)
|
|
2264
|
-
* .prepare();
|
|
1980
|
+
* Receipt counts are completed write intents at the collection surface, not
|
|
1981
|
+
* rows affected:
|
|
2265
1982
|
*
|
|
2266
|
-
*
|
|
2267
|
-
*
|
|
2268
|
-
*
|
|
2269
|
-
*
|
|
1983
|
+
* 1. Every successful completion of a write method on `tx.nodes.*` /
|
|
1984
|
+
* `tx.edges.*` counts. The authoritative method list is
|
|
1985
|
+
* {@link NodeWrites} / {@link EdgeWrites}.
|
|
1986
|
+
* 2. Bulk methods count by input length; an empty bulk call (`bulkCreate([])`)
|
|
1987
|
+
* counts 0.
|
|
1988
|
+
* 3. Single-row methods count 1 on resolve — including `delete` of an absent
|
|
1989
|
+
* id and `getOrCreate*` that found an existing row. Consumers that need
|
|
1990
|
+
* "did anything actually change" semantics apply their own per-operation
|
|
1991
|
+
* policy.
|
|
1992
|
+
* 4. A method that rejects counts 0 — even when the backend applied part of a
|
|
1993
|
+
* bulk input before failing. On SQLite a failed statement does not abort
|
|
1994
|
+
* the surrounding transaction, so a caller that catches the rejection and
|
|
1995
|
+
* commits can persist rows the receipt never counted. Do not read the
|
|
1996
|
+
* receipt as rows-affected in that scenario.
|
|
1997
|
+
* 5. A node `delete` under `cascade` / `disconnect` removes connected edges
|
|
1998
|
+
* through the backend, not the edge-collection surface; those removals do
|
|
1999
|
+
* not appear in `edges`.
|
|
2000
|
+
* 6. Rows-affected fidelity is intentionally out of scope for this first
|
|
2001
|
+
* version; a future extension could ask backends to return row counts.
|
|
2270
2002
|
*/
|
|
2271
|
-
|
|
2272
|
-
|
|
2273
|
-
|
|
2274
|
-
|
|
2275
|
-
|
|
2003
|
+
type TransactionReceipt = Readonly<{
|
|
2004
|
+
writes: Readonly<{
|
|
2005
|
+
/** Completed node write intents by node kind. */
|
|
2006
|
+
nodes: Readonly<Record<string, number>>;
|
|
2007
|
+
/** Completed edge write intents by edge kind. */
|
|
2008
|
+
edges: Readonly<Record<string, number>>;
|
|
2009
|
+
/** Sum of all node and edge write intents. */
|
|
2010
|
+
total: number;
|
|
2011
|
+
}>;
|
|
2276
2012
|
/**
|
|
2277
|
-
*
|
|
2278
|
-
*
|
|
2279
|
-
*
|
|
2280
|
-
* @
|
|
2013
|
+
* The recorded commit instant allocated for this store's graph by this
|
|
2014
|
+
* transaction. Undefined when history capture is off, the transaction is
|
|
2015
|
+
* read-only, or no captured writes were flushed. **Always undefined on a
|
|
2016
|
+
* scoped receipt from {@link ScopedMeasure}** (`tx.measure`) — the recorded
|
|
2017
|
+
* instant is a per-transaction flush concern allocated once when the whole
|
|
2018
|
+
* transaction's capture flushes, unknowable mid-transaction.
|
|
2281
2019
|
*/
|
|
2282
|
-
|
|
2283
|
-
}
|
|
2284
|
-
|
|
2020
|
+
recorded?: RecordedInstant;
|
|
2021
|
+
}>;
|
|
2285
2022
|
/**
|
|
2286
|
-
*
|
|
2023
|
+
* Behavior when a get-or-create operation matches an existing record.
|
|
2287
2024
|
*/
|
|
2288
|
-
|
|
2289
|
-
interface ExecutableQueryLike<G extends GraphDef, R> {
|
|
2290
|
-
toAst(): QueryAst;
|
|
2291
|
-
}
|
|
2025
|
+
type IfExistsMode = "return" | "update";
|
|
2292
2026
|
/**
|
|
2293
|
-
*
|
|
2027
|
+
* Action taken by a get-or-create operation.
|
|
2294
2028
|
*/
|
|
2295
|
-
type
|
|
2296
|
-
|
|
2297
|
-
|
|
2298
|
-
|
|
2299
|
-
|
|
2300
|
-
|
|
2301
|
-
|
|
2302
|
-
traversals?: readonly Traversal[];
|
|
2303
|
-
selectFn?: (context: SelectContext<AliasMap, EdgeAliasMap>) => unknown;
|
|
2029
|
+
type GetOrCreateAction = "created" | "found" | "updated" | "resurrected";
|
|
2030
|
+
/**
|
|
2031
|
+
* Result of a node getOrCreateByConstraint operation.
|
|
2032
|
+
*/
|
|
2033
|
+
type NodeGetOrCreateByConstraintResult<N extends NodeType> = Readonly<{
|
|
2034
|
+
node: Node<N>;
|
|
2035
|
+
action: GetOrCreateAction;
|
|
2304
2036
|
}>;
|
|
2305
|
-
|
|
2306
|
-
|
|
2307
|
-
|
|
2308
|
-
|
|
2309
|
-
|
|
2310
|
-
|
|
2311
|
-
|
|
2312
|
-
|
|
2313
|
-
|
|
2314
|
-
|
|
2315
|
-
|
|
2316
|
-
/**
|
|
2317
|
-
* Combines with another query using INTERSECT.
|
|
2318
|
-
*/
|
|
2319
|
-
intersect(other: ExecutableQueryLike<G, R>): UnionableQuery<G, R>;
|
|
2320
|
-
/**
|
|
2321
|
-
* Combines with another query using EXCEPT.
|
|
2322
|
-
*/
|
|
2323
|
-
except(other: ExecutableQueryLike<G, R>): UnionableQuery<G, R>;
|
|
2324
|
-
/**
|
|
2325
|
-
* Limits the number of results from the combined query.
|
|
2326
|
-
*/
|
|
2327
|
-
limit(n: number): UnionableQuery<G, R>;
|
|
2328
|
-
/**
|
|
2329
|
-
* Offsets the results from the combined query.
|
|
2330
|
-
*/
|
|
2331
|
-
offset(n: number): UnionableQuery<G, R>;
|
|
2332
|
-
/**
|
|
2333
|
-
* Builds the set operation AST.
|
|
2334
|
-
*/
|
|
2335
|
-
toAst(): SetOperation;
|
|
2037
|
+
/**
|
|
2038
|
+
* Options for node getOrCreateByConstraint operations.
|
|
2039
|
+
*/
|
|
2040
|
+
type NodeGetOrCreateByConstraintOptions = Readonly<{
|
|
2041
|
+
/** Existing record behavior. Default: "return" */
|
|
2042
|
+
ifExists?: IfExistsMode;
|
|
2043
|
+
}>;
|
|
2044
|
+
/**
|
|
2045
|
+
* Options for node bulkFindByIndex operations.
|
|
2046
|
+
*/
|
|
2047
|
+
type NodeBulkFindByIndexOptions = Readonly<{
|
|
2336
2048
|
/**
|
|
2337
|
-
*
|
|
2049
|
+
* Maximum number of candidate nodes returned per input item. When omitted,
|
|
2050
|
+
* each input's candidate set is unbounded. Must be a positive integer.
|
|
2338
2051
|
*
|
|
2339
|
-
*
|
|
2340
|
-
* Use this
|
|
2341
|
-
*/
|
|
2342
|
-
toSQL(): Readonly<{
|
|
2343
|
-
sql: string;
|
|
2344
|
-
params: readonly unknown[];
|
|
2345
|
-
}>;
|
|
2346
|
-
/**
|
|
2347
|
-
* Compiles the set operation to SQL.
|
|
2348
|
-
*/
|
|
2349
|
-
compile(): CompiledSelectSql;
|
|
2350
|
-
/**
|
|
2351
|
-
* Executes the combined query.
|
|
2052
|
+
* Candidates are ordered deterministically by node id, so the cap is stable
|
|
2053
|
+
* across calls. Use this to bound fan-out on low-selectivity index keys.
|
|
2352
2054
|
*/
|
|
2353
|
-
|
|
2055
|
+
limitPerInput?: number;
|
|
2056
|
+
}>;
|
|
2057
|
+
/**
|
|
2058
|
+
* Per-endpoint fan-out cap shared by the live and view forms of the edge
|
|
2059
|
+
* bulk endpoint reads.
|
|
2060
|
+
*/
|
|
2061
|
+
type EdgeBulkFindOptions = Readonly<{
|
|
2354
2062
|
/**
|
|
2355
|
-
*
|
|
2063
|
+
* Maximum number of edges returned for each input endpoint. When omitted,
|
|
2064
|
+
* every input's edge set is unbounded. Must be a positive integer.
|
|
2356
2065
|
*
|
|
2357
|
-
*
|
|
2066
|
+
* The cap keeps each input's leading edges under the same ordering
|
|
2067
|
+
* `findFrom` / `findTo` return, so it bounds fan-out without reordering
|
|
2068
|
+
* anything.
|
|
2358
2069
|
*/
|
|
2359
|
-
|
|
2360
|
-
}
|
|
2361
|
-
|
|
2070
|
+
limitPerInput?: number;
|
|
2071
|
+
}>;
|
|
2362
2072
|
/**
|
|
2363
|
-
*
|
|
2073
|
+
* Options for the edge bulk endpoint reads: the temporal coordinate every
|
|
2074
|
+
* edge read accepts, plus the per-endpoint fan-out cap.
|
|
2364
2075
|
*/
|
|
2365
|
-
|
|
2076
|
+
type EdgeBulkFindEndpointOptions = QueryOptions & EdgeBulkFindOptions;
|
|
2077
|
+
/** A kind-grouped source list for a heterogeneous bulk edge read. */
|
|
2078
|
+
type BulkEdgeSourceGroup<G extends GraphDef> = {
|
|
2079
|
+
[K in NodeKinds<G>]: Readonly<{
|
|
2080
|
+
kind: K;
|
|
2081
|
+
ids: readonly NodeId<G["nodes"][K]["type"]>[];
|
|
2082
|
+
}>;
|
|
2083
|
+
}[NodeKinds<G>];
|
|
2084
|
+
/** A node reference whose kind and branded id remain correlated. */
|
|
2085
|
+
type GraphNodeReference<G extends GraphDef> = {
|
|
2086
|
+
[K in NodeKinds<G>]: Readonly<{
|
|
2087
|
+
kind: K;
|
|
2088
|
+
id: NodeId<G["nodes"][K]["type"]>;
|
|
2089
|
+
}>;
|
|
2090
|
+
}[NodeKinds<G>];
|
|
2091
|
+
/** Runtime edge union narrowed to the selected graph edge kinds. */
|
|
2092
|
+
type GraphEdgeForKinds<G extends GraphDef, K extends EdgeKinds<G>> = {
|
|
2093
|
+
[P in K]: Edge<G["edges"][P]["type"], G["edges"][P]["from"][number], G["edges"][P]["to"][number]>;
|
|
2094
|
+
}[K];
|
|
2095
|
+
/** Input for {@link Store.bulkFindEdgesFrom}. */
|
|
2096
|
+
type BulkFindEdgesFromParams<G extends GraphDef, K extends EdgeKinds<G>> = Readonly<{
|
|
2097
|
+
sources: readonly BulkEdgeSourceGroup<G>[];
|
|
2098
|
+
edgeKinds: readonly K[];
|
|
2099
|
+
}>;
|
|
2100
|
+
/** One source bucket returned by {@link Store.bulkFindEdgesFrom}. */
|
|
2101
|
+
type BulkFindEdgesFromResult<G extends GraphDef, K extends EdgeKinds<G>> = Readonly<{
|
|
2102
|
+
source: GraphNodeReference<G>;
|
|
2103
|
+
edges: readonly GraphEdgeForKinds<G, K>[];
|
|
2104
|
+
}>;
|
|
2366
2105
|
/**
|
|
2367
|
-
*
|
|
2106
|
+
* Result of an edge getOrCreateByEndpoints operation.
|
|
2368
2107
|
*/
|
|
2369
|
-
|
|
2370
|
-
|
|
2371
|
-
|
|
2372
|
-
|
|
2373
|
-
|
|
2374
|
-
|
|
2375
|
-
|
|
2376
|
-
|
|
2377
|
-
* Orders results.
|
|
2378
|
-
*/
|
|
2379
|
-
orderBy<A extends (keyof Aliases | keyof EdgeAliases) & string>(alias: A, field: string, direction?: SortDirection): ExecutableQuery<G, Aliases, EdgeAliases, RecursiveAliases, R>;
|
|
2380
|
-
/**
|
|
2381
|
-
* Limits the number of results.
|
|
2382
|
-
*/
|
|
2383
|
-
limit(n: number): ExecutableQuery<G, Aliases, EdgeAliases, RecursiveAliases, R>;
|
|
2384
|
-
/**
|
|
2385
|
-
* Offsets the results.
|
|
2386
|
-
*/
|
|
2387
|
-
offset(n: number): ExecutableQuery<G, Aliases, EdgeAliases, RecursiveAliases, R>;
|
|
2108
|
+
type EdgeGetOrCreateByEndpointsResult<E extends AnyEdgeType, From extends NodeType = NodeType, To extends NodeType = NodeType> = Readonly<{
|
|
2109
|
+
edge: Edge<E, From, To>;
|
|
2110
|
+
action: GetOrCreateAction;
|
|
2111
|
+
}>;
|
|
2112
|
+
/**
|
|
2113
|
+
* Options for edge findByEndpoints operations.
|
|
2114
|
+
*/
|
|
2115
|
+
type EdgeFindByEndpointsOptions<E extends AnyEdgeType> = Readonly<{
|
|
2388
2116
|
/**
|
|
2389
|
-
*
|
|
2390
|
-
*
|
|
2391
|
-
* Useful for applying post-select transformations like ordering,
|
|
2392
|
-
* limits, and offsets from reusable fragments.
|
|
2393
|
-
*
|
|
2394
|
-
* @example
|
|
2395
|
-
* ```typescript
|
|
2396
|
-
* const paginated = (q) => q.orderBy("u", "createdAt", "desc").limit(10);
|
|
2397
|
-
*
|
|
2398
|
-
* const results = await query()
|
|
2399
|
-
* .from("User", "u")
|
|
2400
|
-
* .select((ctx) => ctx.u)
|
|
2401
|
-
* .pipe(paginated)
|
|
2402
|
-
* .execute();
|
|
2403
|
-
* ```
|
|
2404
|
-
*
|
|
2405
|
-
* @param fragment - A function that transforms the executable query
|
|
2406
|
-
* @returns The transformed executable query
|
|
2117
|
+
* Edge property fields to include in the match alongside the (from, to) endpoints.
|
|
2118
|
+
* When omitted, matches on endpoints only (returns the first edge at the read coordinate).
|
|
2407
2119
|
*/
|
|
2408
|
-
|
|
2120
|
+
matchOn?: readonly (keyof z.input<E["schema"]>)[];
|
|
2121
|
+
/** Property values to match against when matchOn is specified. */
|
|
2122
|
+
props?: Partial<z.input<E["schema"]>>;
|
|
2123
|
+
}>;
|
|
2124
|
+
/**
|
|
2125
|
+
* Options for edge getOrCreateByEndpoints operations.
|
|
2126
|
+
*/
|
|
2127
|
+
type EdgeGetOrCreateByEndpointsOptions<E extends AnyEdgeType> = Readonly<{
|
|
2409
2128
|
/**
|
|
2410
|
-
*
|
|
2129
|
+
* Edge property fields to include in the match key alongside the (from, to) endpoints.
|
|
2130
|
+
* Default: `[]` — match on endpoints only.
|
|
2411
2131
|
*/
|
|
2412
|
-
|
|
2132
|
+
matchOn?: readonly (keyof z.input<E["schema"]>)[];
|
|
2133
|
+
/** Existing record behavior. Default: "return" */
|
|
2134
|
+
ifExists?: IfExistsMode;
|
|
2413
2135
|
/**
|
|
2414
|
-
*
|
|
2136
|
+
* Valid-time start for a newly created edge. Ignored when an edge is found,
|
|
2137
|
+
* updated, or resurrected.
|
|
2415
2138
|
*/
|
|
2416
|
-
|
|
2139
|
+
validFrom?: string;
|
|
2417
2140
|
/**
|
|
2418
|
-
*
|
|
2141
|
+
* Valid-time end for a created, updated, or resurrected edge. Ignored when
|
|
2142
|
+
* the operation returns an existing edge without writing.
|
|
2419
2143
|
*/
|
|
2420
|
-
|
|
2144
|
+
validTo?: string;
|
|
2145
|
+
}>;
|
|
2146
|
+
/**
|
|
2147
|
+
* A collection of nodes of a specific type.
|
|
2148
|
+
*
|
|
2149
|
+
* Provides ergonomic CRUD operations for a single node type.
|
|
2150
|
+
*/
|
|
2151
|
+
type NodeCollection<N extends NodeType, CN extends string = string> = Readonly<{
|
|
2421
2152
|
/**
|
|
2422
|
-
*
|
|
2153
|
+
* Create a new node.
|
|
2154
|
+
*
|
|
2155
|
+
* `validFrom` defaults to the operation's creation timestamp when omitted.
|
|
2423
2156
|
*/
|
|
2424
|
-
|
|
2157
|
+
create: (props: z.input<N["schema"]>, options?: Readonly<{
|
|
2158
|
+
id?: string;
|
|
2159
|
+
validFrom?: string;
|
|
2160
|
+
validTo?: string;
|
|
2161
|
+
}>) => Promise<Node<N>>;
|
|
2162
|
+
/** Get a node by ID */
|
|
2163
|
+
getById: (id: NodeId<N>, options?: QueryOptions) => Promise<Node<N> | undefined>;
|
|
2164
|
+
/** Get multiple nodes by ID, preserving input order (undefined for missing) */
|
|
2165
|
+
getByIds: (ids: readonly NodeId<N>[], options?: QueryOptions) => Promise<readonly (Node<N> | undefined)[]>;
|
|
2166
|
+
/** Update a node */
|
|
2167
|
+
update: (id: NodeId<N>, props: Partial<z.input<N["schema"]>>, options?: Readonly<{
|
|
2168
|
+
validTo?: string;
|
|
2169
|
+
}>) => Promise<Node<N>>;
|
|
2425
2170
|
/**
|
|
2426
|
-
*
|
|
2171
|
+
* Updates every current node selected by the supplied predicates in one
|
|
2172
|
+
* set-based write. Relationship clauses are independent EXISTS predicates
|
|
2173
|
+
* and are ANDed with each other and with `where`.
|
|
2174
|
+
*/
|
|
2175
|
+
updateWhere: (params: Readonly<{
|
|
2176
|
+
patch: Partial<z.input<N["schema"]>>;
|
|
2177
|
+
where?: (accessor: string extends N["kind"] ? DynamicNodeAccessor : NodeAccessor<N>) => Predicate;
|
|
2178
|
+
exists?: readonly Readonly<{
|
|
2179
|
+
edgeKind: string;
|
|
2180
|
+
direction: "out" | "in";
|
|
2181
|
+
relatedKind: string;
|
|
2182
|
+
whereEdge?: (accessor: DynamicEdgeAccessor) => Predicate;
|
|
2183
|
+
whereRelated?: (accessor: DynamicNodeAccessor) => Predicate;
|
|
2184
|
+
}>[];
|
|
2185
|
+
all?: true;
|
|
2186
|
+
}>) => Promise<Readonly<{
|
|
2187
|
+
affectedCount: number;
|
|
2188
|
+
}>>;
|
|
2189
|
+
/** Delete a node (soft delete - sets deletedAt timestamp) */
|
|
2190
|
+
delete: (id: NodeId<N>) => Promise<void>;
|
|
2191
|
+
/**
|
|
2192
|
+
* Permanently delete a node from the database.
|
|
2427
2193
|
*
|
|
2428
|
-
*
|
|
2429
|
-
*
|
|
2194
|
+
* Unlike `delete()` which performs a soft delete, this permanently
|
|
2195
|
+
* removes the node and its associated data (uniqueness entries, embeddings).
|
|
2196
|
+
*
|
|
2197
|
+
* **Warning:** This operation is irreversible and should be used carefully.
|
|
2198
|
+
* Consider using soft delete (`delete()`) for most use cases.
|
|
2199
|
+
*
|
|
2200
|
+
* @throws Error if edges are still connected to this node (delete edges first)
|
|
2430
2201
|
*/
|
|
2431
|
-
|
|
2432
|
-
sql: string;
|
|
2433
|
-
params: readonly unknown[];
|
|
2434
|
-
}>;
|
|
2202
|
+
hardDelete: (id: NodeId<N>) => Promise<void>;
|
|
2435
2203
|
/**
|
|
2436
|
-
*
|
|
2204
|
+
* Find nodes matching criteria.
|
|
2437
2205
|
*
|
|
2438
|
-
*
|
|
2439
|
-
*
|
|
2206
|
+
* Supports predicate filtering via the `where` option for SQL-level filtering.
|
|
2207
|
+
* For simple queries. Use store.query() for complex traversals.
|
|
2440
2208
|
*/
|
|
2441
|
-
|
|
2209
|
+
find: (filter?: Readonly<{
|
|
2210
|
+
where?: (accessor: NodeAccessor<N>) => Predicate;
|
|
2211
|
+
limit?: number;
|
|
2212
|
+
offset?: number;
|
|
2213
|
+
}>, temporal?: QueryOptions) => Promise<Node<N>[]>;
|
|
2214
|
+
/** Count nodes matching criteria */
|
|
2215
|
+
count: (temporal?: QueryOptions) => Promise<number>;
|
|
2442
2216
|
/**
|
|
2443
|
-
*
|
|
2444
|
-
* times with different parameter bindings. Builds and structurally
|
|
2445
|
-
* validates the AST once (a malformed query fails fast, here, instead of on
|
|
2446
|
-
* first use); the prepared query then compiles once into a reusable template
|
|
2447
|
-
* and fills a fresh read instant per execute() — see PreparedQuery's class
|
|
2448
|
-
* doc comment.
|
|
2217
|
+
* Create a node from untyped data, relying on runtime Zod validation.
|
|
2449
2218
|
*
|
|
2450
|
-
* Use
|
|
2451
|
-
*
|
|
2219
|
+
* Use this for dynamic dispatch (changesets, migrations, imports) where
|
|
2220
|
+
* the data shape is determined at runtime, not compile time.
|
|
2221
|
+
* The return type is fully typed — only the input gate is relaxed.
|
|
2452
2222
|
*
|
|
2453
|
-
*
|
|
2454
|
-
|
|
2455
|
-
|
|
2223
|
+
* `validFrom` defaults to the operation's creation timestamp when omitted.
|
|
2224
|
+
*/
|
|
2225
|
+
createFromRecord: (data: Record<string, unknown>, options?: Readonly<{
|
|
2226
|
+
id?: string;
|
|
2227
|
+
validFrom?: string;
|
|
2228
|
+
validTo?: string;
|
|
2229
|
+
}>) => Promise<Node<N>>;
|
|
2230
|
+
/**
|
|
2231
|
+
* Create or update a node.
|
|
2456
2232
|
*
|
|
2457
|
-
*
|
|
2458
|
-
*
|
|
2459
|
-
* .whereNode("p", (p) => p.name.eq(param("name")))
|
|
2460
|
-
* .select((ctx) => ctx.p)
|
|
2461
|
-
* .prepare();
|
|
2233
|
+
* If a node with the given ID exists, updates it with the provided props.
|
|
2234
|
+
* Otherwise, creates a new node with that ID.
|
|
2462
2235
|
*
|
|
2463
|
-
*
|
|
2464
|
-
*
|
|
2465
|
-
|
|
2236
|
+
* `validFrom` only applies on the create branch, defaulting to the
|
|
2237
|
+
* operation's creation timestamp when omitted; it has no effect on update.
|
|
2238
|
+
*/
|
|
2239
|
+
upsertById: (id: string, props: z.input<N["schema"]>, options?: Readonly<{
|
|
2240
|
+
validFrom?: string;
|
|
2241
|
+
validTo?: string;
|
|
2242
|
+
}>) => Promise<Node<N>>;
|
|
2243
|
+
/**
|
|
2244
|
+
* Upsert a node from untyped data, relying on runtime Zod validation.
|
|
2466
2245
|
*
|
|
2467
|
-
*
|
|
2246
|
+
* Use this for dynamic dispatch (changesets, migrations, imports) where
|
|
2247
|
+
* the data shape is determined at runtime, not compile time.
|
|
2248
|
+
* The return type is fully typed — only the input gate is relaxed.
|
|
2249
|
+
*
|
|
2250
|
+
* `validFrom` only applies on the create branch, defaulting to the
|
|
2251
|
+
* operation's creation timestamp when omitted; it has no effect on update.
|
|
2468
2252
|
*/
|
|
2469
|
-
|
|
2253
|
+
upsertByIdFromRecord: (id: string, data: Record<string, unknown>, options?: Readonly<{
|
|
2254
|
+
validFrom?: string;
|
|
2255
|
+
validTo?: string;
|
|
2256
|
+
}>) => Promise<Node<N>>;
|
|
2470
2257
|
/**
|
|
2471
|
-
*
|
|
2258
|
+
* Create multiple nodes in a batch.
|
|
2472
2259
|
*
|
|
2473
|
-
*
|
|
2474
|
-
*
|
|
2475
|
-
* references (no method calls or computations), generates optimized SQL
|
|
2476
|
-
* that only extracts those fields instead of the full props blob.
|
|
2260
|
+
* More efficient than calling create() multiple times.
|
|
2261
|
+
* Use `bulkInsert` for the dedicated fast path that skips returning results.
|
|
2477
2262
|
*
|
|
2478
|
-
*
|
|
2263
|
+
* `validFrom` defaults to the operation's creation timestamp when omitted.
|
|
2479
2264
|
*/
|
|
2480
|
-
|
|
2265
|
+
bulkCreate: (items: readonly Readonly<{
|
|
2266
|
+
props: z.input<N["schema"]>;
|
|
2267
|
+
id?: string;
|
|
2268
|
+
validFrom?: string;
|
|
2269
|
+
validTo?: string;
|
|
2270
|
+
}>[]) => Promise<Node<N>[]>;
|
|
2481
2271
|
/**
|
|
2482
|
-
*
|
|
2272
|
+
* Create or update multiple nodes in a batch.
|
|
2273
|
+
*
|
|
2274
|
+
* For each item, if a node with the given ID exists, updates it.
|
|
2275
|
+
* Otherwise, creates a new node with that ID.
|
|
2483
2276
|
*
|
|
2484
|
-
*
|
|
2485
|
-
*
|
|
2486
|
-
* pipeline runs identically to `execute()`, but against the given backend.
|
|
2277
|
+
* `validFrom` only applies on the create branch, defaulting to the
|
|
2278
|
+
* operation's creation timestamp when omitted; it has no effect on update.
|
|
2487
2279
|
*/
|
|
2488
|
-
|
|
2280
|
+
bulkUpsertById: (items: readonly Readonly<{
|
|
2281
|
+
id: string;
|
|
2282
|
+
props: z.input<N["schema"]>;
|
|
2283
|
+
validFrom?: string;
|
|
2284
|
+
validTo?: string;
|
|
2285
|
+
}>[]) => Promise<Node<N>[]>;
|
|
2489
2286
|
/**
|
|
2490
|
-
*
|
|
2287
|
+
* Insert multiple nodes without returning results.
|
|
2491
2288
|
*
|
|
2492
|
-
*
|
|
2493
|
-
*
|
|
2289
|
+
* This is the dedicated fast path for bulk inserts. Unlike `bulkCreate`
|
|
2290
|
+
* with `returnResults: false`, the intent is unambiguous: no results
|
|
2291
|
+
* are returned and the operation is wrapped in a transaction.
|
|
2494
2292
|
*
|
|
2495
|
-
*
|
|
2496
|
-
* @throws ValidationError if ORDER BY is not specified
|
|
2497
|
-
* @throws ValidationError if cursor columns don't match query ORDER BY columns
|
|
2293
|
+
* `validFrom` defaults to the operation's creation timestamp when omitted.
|
|
2498
2294
|
*/
|
|
2499
|
-
|
|
2295
|
+
bulkInsert: (items: readonly Readonly<{
|
|
2296
|
+
props: z.input<N["schema"]>;
|
|
2297
|
+
id?: string;
|
|
2298
|
+
validFrom?: string;
|
|
2299
|
+
validTo?: string;
|
|
2300
|
+
}>[]) => Promise<void>;
|
|
2500
2301
|
/**
|
|
2501
|
-
*
|
|
2302
|
+
* Delete multiple nodes by ID.
|
|
2502
2303
|
*
|
|
2503
|
-
*
|
|
2504
|
-
*
|
|
2304
|
+
* Atomic when the backend supports transactions. Silently ignores IDs
|
|
2305
|
+
* that don't exist.
|
|
2306
|
+
*/
|
|
2307
|
+
bulkDelete: (ids: readonly NodeId<N>[]) => Promise<void>;
|
|
2308
|
+
/**
|
|
2309
|
+
* Find a node by uniqueness constraint.
|
|
2505
2310
|
*
|
|
2506
|
-
*
|
|
2507
|
-
*
|
|
2311
|
+
* Looks up a live node by the named constraint key computed from `props`.
|
|
2312
|
+
* Returns the node if found, or undefined. Soft-deleted nodes are excluded.
|
|
2313
|
+
*
|
|
2314
|
+
* @param constraintName - Name of the uniqueness constraint to match on
|
|
2315
|
+
* @param props - Properties to compute the constraint key from
|
|
2508
2316
|
*/
|
|
2509
|
-
|
|
2510
|
-
}
|
|
2511
|
-
|
|
2512
|
-
/**
|
|
2513
|
-
* TraversalBuilder - Intermediate builder for edge traversals.
|
|
2514
|
-
*/
|
|
2515
|
-
|
|
2516
|
-
/**
|
|
2517
|
-
* Resolves the edge type for an edge alias based on its kind type parameter.
|
|
2518
|
-
*
|
|
2519
|
-
* For `traverse(...)`, `EK` is a literal like `"authoredBy"` and the
|
|
2520
|
-
* type comes from the typed graph. For `traverseDynamic(...)`, `EK` is
|
|
2521
|
-
* widened to `string` — `string extends EK` distinguishes that case and
|
|
2522
|
-
* resolves to `DynamicEdgeType`, so the conditional accessor types fire.
|
|
2523
|
-
*/
|
|
2524
|
-
type EdgeTypeForKey<G extends GraphDef, EK> = string extends EK ? DynamicEdgeType : EK extends keyof G["edges"] & string ? G["edges"][EK]["type"] : DynamicEdgeType;
|
|
2525
|
-
/**
|
|
2526
|
-
* State for variable-length traversal configuration.
|
|
2527
|
-
*/
|
|
2528
|
-
interface VariableLengthState {
|
|
2529
|
-
enabled: boolean;
|
|
2530
|
-
minDepth: number;
|
|
2531
|
-
maxDepth: number;
|
|
2532
|
-
cyclePolicy: RecursiveCyclePolicy;
|
|
2533
|
-
pathEnabled: boolean;
|
|
2534
|
-
pathAlias?: string;
|
|
2535
|
-
depthEnabled: boolean;
|
|
2536
|
-
depthAlias?: string;
|
|
2537
|
-
}
|
|
2538
|
-
/**
|
|
2539
|
-
* Intermediate builder for traversal operations.
|
|
2540
|
-
*
|
|
2541
|
-
* Type parameters track the edge kind and direction to constrain
|
|
2542
|
-
* which node kinds are valid targets in the `to()` method.
|
|
2543
|
-
*/
|
|
2544
|
-
declare class TraversalBuilder<G extends GraphDef, Aliases extends AliasMap, EdgeAliases extends EdgeAliasMap = EmptyEdgeAliasMap, EK extends keyof G["edges"] & string = keyof G["edges"] & string, EA extends string = string, Dir extends TraversalDirection$1 = "out", Optional extends boolean = false, DC extends boolean | string = false, PC extends boolean | string = false, RecAliases extends RecursiveAliasMap = EmptyRecursiveAliasMap, CoordinateState extends QueryCoordinateState = "open"> {
|
|
2545
|
-
#private;
|
|
2546
|
-
constructor(config: QueryBuilderConfig, state: QueryBuilderState, edgeKinds: readonly string[], edgeAlias: EA, direction: Dir, fromAlias: string, inverseEdgeKinds?: readonly string[], optional?: Optional, variableLength?: VariableLengthState, pendingEdgePredicates?: readonly NodePredicate[]);
|
|
2317
|
+
findByConstraint: (constraintName: CN, props: z.input<N["schema"]>) => Promise<Node<N> | undefined>;
|
|
2547
2318
|
/**
|
|
2548
|
-
*
|
|
2549
|
-
*
|
|
2550
|
-
*
|
|
2319
|
+
* Batch version of findByConstraint.
|
|
2320
|
+
*
|
|
2321
|
+
* Results are returned in the same order as the input items.
|
|
2322
|
+
* Returns undefined for entries that don't match.
|
|
2551
2323
|
*/
|
|
2552
|
-
|
|
2553
|
-
|
|
2554
|
-
}
|
|
2555
|
-
path: infer P extends boolean | string;
|
|
2556
|
-
} ? P : PC, RecAliases, CoordinateState>;
|
|
2324
|
+
bulkFindByConstraint: (constraintName: CN, items: readonly Readonly<{
|
|
2325
|
+
props: z.input<N["schema"]>;
|
|
2326
|
+
}>[]) => Promise<(Node<N> | undefined)[]>;
|
|
2557
2327
|
/**
|
|
2558
|
-
*
|
|
2328
|
+
* Batched candidate retrieval against a declared node index.
|
|
2329
|
+
*
|
|
2330
|
+
* For each input item, TypeGraph computes the index lookup key from
|
|
2331
|
+
* `index.fields` (JSON-pointer extraction, partial-`where` applied to
|
|
2332
|
+
* stored rows, null-safe matching) and returns the live, non-soft-deleted
|
|
2333
|
+
* nodes that share that key. Unlike {@link bulkFindByConstraint}, the index
|
|
2334
|
+
* may be non-unique, so each input yields a (possibly empty) array.
|
|
2559
2335
|
*
|
|
2560
|
-
*
|
|
2561
|
-
*
|
|
2336
|
+
* Results preserve input order; each inner array is ordered by node id.
|
|
2337
|
+
* Empty input returns `[]`. An unknown index name throws
|
|
2338
|
+
* `NodeIndexNotFoundError`; a type-incompatible indexed field throws
|
|
2339
|
+
* `ValidationError`. This is candidate retrieval, not a uniqueness or
|
|
2340
|
+
* identity guarantee.
|
|
2341
|
+
*
|
|
2342
|
+
* @param indexName - Name of the declared node index to match on
|
|
2343
|
+
* @param items - Records whose `props` supply the indexed-field values
|
|
2344
|
+
* @param options - Optional `limitPerInput` to bound per-input fan-out
|
|
2562
2345
|
*/
|
|
2563
|
-
|
|
2346
|
+
bulkFindByIndex: (indexName: string, items: readonly Readonly<{
|
|
2347
|
+
props: Partial<z.input<N["schema"]>>;
|
|
2348
|
+
}>[], options?: NodeBulkFindByIndexOptions) => Promise<readonly Node<N>[][]>;
|
|
2564
2349
|
/**
|
|
2565
|
-
*
|
|
2350
|
+
* Get an existing node by uniqueness constraint, or create a new one.
|
|
2566
2351
|
*
|
|
2567
|
-
*
|
|
2568
|
-
*
|
|
2569
|
-
*
|
|
2352
|
+
* Looks up a node by the named constraint key computed from `props`.
|
|
2353
|
+
* If found, returns it (optionally updating with `ifExists: "update"`).
|
|
2354
|
+
* If not found, creates a new node. Soft-deleted matches are always resurrected.
|
|
2570
2355
|
*
|
|
2571
|
-
* @param
|
|
2572
|
-
* @param
|
|
2356
|
+
* @param constraintName - Name of the uniqueness constraint to match on
|
|
2357
|
+
* @param props - Full properties for create, or merge source for update
|
|
2358
|
+
* @param options - Existing record behavior (default: "return")
|
|
2573
2359
|
*/
|
|
2574
|
-
|
|
2575
|
-
includeSubClasses?: false;
|
|
2576
|
-
}): QueryBuilder<G, Aliases & Record<A, NodeAlias<G["nodes"][K]["type"], Optional>>, EdgeAliases & Record<EA, EdgeAlias<G["edges"][EK]["type"], Optional>>, RecAliases & BuildRecursiveAliases<DC, PC, A>, CoordinateState>;
|
|
2577
|
-
to<K extends ValidEdgeTargets<G, EK, Dir>, A extends string>(kind: K, alias: UniqueAlias<A, Aliases>, options: {
|
|
2578
|
-
includeSubClasses: true;
|
|
2579
|
-
}): QueryBuilder<G, Aliases & Record<A, NodeAlias<NodeType, Optional>>, EdgeAliases & Record<EA, EdgeAlias<G["edges"][EK]["type"], Optional>>, RecAliases & BuildRecursiveAliases<DC, PC, A>, CoordinateState>;
|
|
2360
|
+
getOrCreateByConstraint: (constraintName: CN, props: z.input<N["schema"]>, options?: NodeGetOrCreateByConstraintOptions) => Promise<NodeGetOrCreateByConstraintResult<N>>;
|
|
2580
2361
|
/**
|
|
2581
|
-
*
|
|
2582
|
-
*
|
|
2362
|
+
* Batch version of getOrCreateByConstraint.
|
|
2363
|
+
*
|
|
2364
|
+
* Results are returned in the same order as the input items.
|
|
2365
|
+
* Atomic when the backend supports transactions.
|
|
2583
2366
|
*/
|
|
2584
|
-
|
|
2585
|
-
|
|
2586
|
-
}
|
|
2587
|
-
}
|
|
2588
|
-
|
|
2367
|
+
bulkGetOrCreateByConstraint: (constraintName: CN, items: readonly Readonly<{
|
|
2368
|
+
props: z.input<N["schema"]>;
|
|
2369
|
+
}>[], options?: NodeGetOrCreateByConstraintOptions) => Promise<NodeGetOrCreateByConstraintResult<N>[]>;
|
|
2370
|
+
}>;
|
|
2589
2371
|
/**
|
|
2590
|
-
*
|
|
2372
|
+
* Reference to a node of a specific kind.
|
|
2373
|
+
*
|
|
2374
|
+
* Accepts either:
|
|
2375
|
+
* - A Node instance of the correct kind
|
|
2376
|
+
* - An explicit { kind, id } object with the correct kind name
|
|
2377
|
+
*
|
|
2378
|
+
* This provides compile-time checking that edge endpoints match the
|
|
2379
|
+
* allowed node kinds defined in the edge registration.
|
|
2591
2380
|
*/
|
|
2592
|
-
|
|
2593
|
-
|
|
2381
|
+
type NodeRef<N extends NodeType = NodeType> = Node<N> | Readonly<{
|
|
2382
|
+
kind: N["kind"];
|
|
2383
|
+
id: string;
|
|
2384
|
+
}>;
|
|
2594
2385
|
/**
|
|
2595
|
-
*
|
|
2386
|
+
* Options for creating an edge.
|
|
2387
|
+
*/
|
|
2388
|
+
type EdgeCreateOptions = Readonly<{
|
|
2389
|
+
id?: string;
|
|
2390
|
+
validFrom?: string;
|
|
2391
|
+
validTo?: string;
|
|
2392
|
+
}>;
|
|
2393
|
+
/**
|
|
2394
|
+
* Arguments for edge creation, with props optional when schema allows empty object.
|
|
2596
2395
|
*
|
|
2597
|
-
*
|
|
2598
|
-
* - G: The graph definition
|
|
2599
|
-
* - Aliases: Map of alias names to their node kinds
|
|
2600
|
-
* - EdgeAliases: Map of alias names to their edge kinds (accumulated during traversals)
|
|
2396
|
+
* Uses `{}` to check if an empty object literal satisfies the schema input type.
|
|
2601
2397
|
*/
|
|
2602
|
-
|
|
2603
|
-
|
|
2604
|
-
|
|
2605
|
-
|
|
2398
|
+
type EdgeCreateArguments<E extends AnyEdgeType> = {} extends z.input<E["schema"]> ? [
|
|
2399
|
+
props?: z.input<E["schema"]>,
|
|
2400
|
+
options?: EdgeCreateOptions
|
|
2401
|
+
] : [props: z.input<E["schema"]>, options?: EdgeCreateOptions];
|
|
2402
|
+
/**
|
|
2403
|
+
* A collection of edges of a specific type.
|
|
2404
|
+
*
|
|
2405
|
+
* Provides ergonomic CRUD operations for a single edge type.
|
|
2406
|
+
* The From and To type parameters enforce that edge endpoints
|
|
2407
|
+
* match the allowed node types at compile time.
|
|
2408
|
+
*
|
|
2409
|
+
* @example
|
|
2410
|
+
* ```typescript
|
|
2411
|
+
* // Create an edge - pass Node objects directly
|
|
2412
|
+
* const edge = await store.edges.worksAt.create(alice, acme, { role: "Engineer" });
|
|
2413
|
+
*
|
|
2414
|
+
* // TypeScript error: Company is not a valid 'from' type for worksAt
|
|
2415
|
+
* // store.edges.worksAt.create(acme, alice, { role: "Engineer" });
|
|
2416
|
+
*
|
|
2417
|
+
* // For edges with empty schemas, props is optional
|
|
2418
|
+
* await store.edges.wrote.create(author, book);
|
|
2419
|
+
*
|
|
2420
|
+
* // Find edges from a node
|
|
2421
|
+
* const edges = await store.edges.worksAt.findFrom(alice);
|
|
2422
|
+
* ```
|
|
2423
|
+
*/
|
|
2424
|
+
type EdgeCollection<E extends AnyEdgeType, From extends NodeType = NodeType, To extends NodeType = NodeType> = Readonly<{
|
|
2606
2425
|
/**
|
|
2607
|
-
*
|
|
2426
|
+
* Create a new edge.
|
|
2608
2427
|
*
|
|
2609
|
-
*
|
|
2610
|
-
*
|
|
2611
|
-
|
|
2612
|
-
|
|
2613
|
-
|
|
2614
|
-
}): QueryBuilder<G, Aliases & Record<A, NodeAlias<G["nodes"][K]["type"]>>, EdgeAliases, RecursiveAliases, CoordinateState>;
|
|
2615
|
-
from<K extends keyof G["nodes"] & string, A extends string>(kind: K, alias: UniqueAlias<A, Aliases>, options: {
|
|
2616
|
-
includeSubClasses: true;
|
|
2617
|
-
}): QueryBuilder<G, Aliases & Record<A, NodeAlias>, EdgeAliases, RecursiveAliases, CoordinateState>;
|
|
2618
|
-
/**
|
|
2619
|
-
* String-keyed sibling of `from` for runtime-declared kinds. Throws
|
|
2620
|
-
* `KindNotFoundError` if the kind is not registered. Predicates use
|
|
2621
|
-
* the `n.field("name").number().gte(...)` discriminator.
|
|
2428
|
+
* `validFrom` defaults to the operation's creation timestamp when omitted.
|
|
2429
|
+
*
|
|
2430
|
+
* @param from - Source node (must be one of the allowed 'from' types)
|
|
2431
|
+
* @param to - Target node (must be one of the allowed 'to' types)
|
|
2432
|
+
* @param args - Edge properties (optional if schema is empty) and creation options
|
|
2622
2433
|
*/
|
|
2623
|
-
|
|
2624
|
-
|
|
2625
|
-
|
|
2434
|
+
create: (from: NodeRef<From>, to: NodeRef<To>, ...args: EdgeCreateArguments<E>) => Promise<Edge<E, From, To>>;
|
|
2435
|
+
/** Get an edge by ID */
|
|
2436
|
+
getById: (id: EdgeId<E>, options?: QueryOptions) => Promise<Edge<E, From, To> | undefined>;
|
|
2437
|
+
/** Get multiple edges by ID, preserving input order (undefined for missing) */
|
|
2438
|
+
getByIds: (ids: readonly EdgeId<E>[], options?: QueryOptions) => Promise<readonly (Edge<E, From, To> | undefined)[]>;
|
|
2439
|
+
/** Update an edge's properties */
|
|
2440
|
+
update: (id: EdgeId<E>, props: Partial<z.input<E["schema"]>>, options?: Readonly<{
|
|
2441
|
+
validTo?: string;
|
|
2442
|
+
}>) => Promise<Edge<E, From, To>>;
|
|
2626
2443
|
/**
|
|
2627
|
-
*
|
|
2444
|
+
* Find edges from a specific node.
|
|
2445
|
+
*
|
|
2446
|
+
* Honors the same temporal model as `getById` / `find`: with no
|
|
2447
|
+
* `options`, the graph's default `temporalMode` applies (excluding
|
|
2448
|
+
* soft-deleted edges and, in `current` / `asOf` modes, edges outside
|
|
2449
|
+
* their validity window). Pass `temporalMode` / `asOf` to read the
|
|
2450
|
+
* endpoint's edges at another temporal coordinate.
|
|
2628
2451
|
*/
|
|
2629
|
-
|
|
2452
|
+
findFrom: (from: NodeRef<From>, options?: QueryOptions) => Promise<Edge<E, From, To>[]>;
|
|
2630
2453
|
/**
|
|
2631
|
-
*
|
|
2454
|
+
* Find edges to a specific node.
|
|
2632
2455
|
*
|
|
2633
|
-
*
|
|
2634
|
-
* @param predicateFunction - A function that builds predicates using the edge accessor
|
|
2456
|
+
* Temporal semantics mirror {@link EdgeCollection.findFrom}.
|
|
2635
2457
|
*/
|
|
2636
|
-
|
|
2458
|
+
findTo: (to: NodeRef<To>, options?: QueryOptions) => Promise<Edge<E, From, To>[]>;
|
|
2637
2459
|
/**
|
|
2638
|
-
*
|
|
2460
|
+
* Find the edges from a SET of source nodes in one read.
|
|
2639
2461
|
*
|
|
2640
|
-
*
|
|
2641
|
-
*
|
|
2462
|
+
* `findFrom` with a widened endpoint predicate and nothing else: the same
|
|
2463
|
+
* temporal model, the same soft-delete filtering, and the same per-source
|
|
2464
|
+
* ordering — but `from_id IN (...)` instead of `from_id = ?`, so a page of
|
|
2465
|
+
* N sources costs one statement per distinct source kind and bind-budget
|
|
2466
|
+
* chunk rather than N singleton statements.
|
|
2642
2467
|
*
|
|
2643
|
-
*
|
|
2644
|
-
*
|
|
2645
|
-
|
|
2646
|
-
|
|
2647
|
-
|
|
2648
|
-
|
|
2649
|
-
from?: keyof Aliases & string;
|
|
2650
|
-
}): TraversalBuilder<G, Aliases, EdgeAliases, EK, EA, "out", false, false, false, RecursiveAliases, CoordinateState>;
|
|
2651
|
-
/**
|
|
2652
|
-
* Traverses an edge to another node (incoming direction).
|
|
2468
|
+
* Results are grouped per input: the outer array is parallel to `froms`
|
|
2469
|
+
* (index `i` holds the edges of `froms[i]`), and repeated inputs each get
|
|
2470
|
+
* their own copy of the same edge set. Empty input returns `[]`; a source
|
|
2471
|
+
* with no edges gets an empty array. Large inputs are split across
|
|
2472
|
+
* statements to respect the backend's bound-parameter budget, which is
|
|
2473
|
+
* invisible in the result.
|
|
2653
2474
|
*
|
|
2654
|
-
*
|
|
2655
|
-
*
|
|
2475
|
+
* Requires a backend implementing `findEdgesByEndpointSet` — both bundled
|
|
2476
|
+
* Drizzle backends do. On one that does not, this **refuses** with a
|
|
2477
|
+
* `ConfigurationError` rather than looping `findFrom` per input: asking for
|
|
2478
|
+
* a bulk read is asking for set-oriented statements, and silently issuing N
|
|
2479
|
+
* singleton statements is the cost surprise the method exists to remove.
|
|
2656
2480
|
*
|
|
2657
|
-
* @param
|
|
2658
|
-
* @param options
|
|
2659
|
-
* @
|
|
2481
|
+
* @param froms - Source nodes to read the edges of
|
|
2482
|
+
* @param options - Temporal coordinate plus optional `limitPerInput`
|
|
2483
|
+
* @throws {ConfigurationError} when the backend cannot read an endpoint set
|
|
2660
2484
|
*/
|
|
2661
|
-
|
|
2662
|
-
direction: "in";
|
|
2663
|
-
expand?: TraversalExpansion;
|
|
2664
|
-
from?: keyof Aliases & string;
|
|
2665
|
-
}): TraversalBuilder<G, Aliases, EdgeAliases, EK, EA, "in", false, false, false, RecursiveAliases, CoordinateState>;
|
|
2485
|
+
bulkFindFrom: (froms: readonly NodeRef<From>[], options?: EdgeBulkFindEndpointOptions) => Promise<readonly Edge<E, From, To>[][]>;
|
|
2666
2486
|
/**
|
|
2667
|
-
*
|
|
2668
|
-
*
|
|
2487
|
+
* Find the edges into a SET of target nodes in one read.
|
|
2488
|
+
*
|
|
2489
|
+
* Mirrors {@link EdgeCollection.bulkFindFrom} on the `to` endpoint.
|
|
2669
2490
|
*/
|
|
2670
|
-
|
|
2671
|
-
direction?: TraversalDirection$1;
|
|
2672
|
-
expand?: TraversalExpansion;
|
|
2673
|
-
from?: keyof Aliases & string;
|
|
2674
|
-
}): TraversalBuilder<G, Aliases, EdgeAliases & Record<EA, EdgeAlias<DynamicEdgeType>>, string, EA, TraversalDirection$1, false, false, false, RecursiveAliases, CoordinateState>;
|
|
2491
|
+
bulkFindTo: (tos: readonly NodeRef<To>[], options?: EdgeBulkFindEndpointOptions) => Promise<readonly Edge<E, From, To>[][]>;
|
|
2675
2492
|
/**
|
|
2676
|
-
*
|
|
2677
|
-
* If no matching edge/node exists, the result will include null values.
|
|
2493
|
+
* Deferred variant of `findFrom` for use with `store.batch()`.
|
|
2678
2494
|
*
|
|
2679
|
-
*
|
|
2680
|
-
*
|
|
2495
|
+
* Returns a `BatchableQuery` instead of executing immediately. Accepts
|
|
2496
|
+
* the same temporal `options` as {@link EdgeCollection.findFrom}.
|
|
2681
2497
|
*
|
|
2682
|
-
*
|
|
2683
|
-
*
|
|
2684
|
-
*
|
|
2498
|
+
* Batching these still issues one statement per call — it does not merge
|
|
2499
|
+
* the reads, and whether they share a connection is up to the adapter. It
|
|
2500
|
+
* is not a snapshot: PostgreSQL's default read-committed isolation lets a
|
|
2501
|
+
* later read observe a commit the earlier ones did not. To read edges for
|
|
2502
|
+
* many sources in one statement, traverse from them in a single query.
|
|
2685
2503
|
*/
|
|
2686
|
-
|
|
2687
|
-
direction?: "out";
|
|
2688
|
-
expand?: TraversalExpansion;
|
|
2689
|
-
from?: keyof Aliases & string;
|
|
2690
|
-
}): TraversalBuilder<G, Aliases, EdgeAliases, EK, EA, "out", true, false, false, RecursiveAliases, CoordinateState>;
|
|
2691
|
-
optionalTraverse<EK extends keyof G["edges"] & string, EA extends string>(edgeKind: EK, edgeAlias: EA, options: {
|
|
2692
|
-
direction: "in";
|
|
2693
|
-
expand?: TraversalExpansion;
|
|
2694
|
-
from?: keyof Aliases & string;
|
|
2695
|
-
}): TraversalBuilder<G, Aliases, EdgeAliases, EK, EA, "in", true, false, false, RecursiveAliases, CoordinateState>;
|
|
2504
|
+
batchFindFrom: (from: NodeRef<From>, options?: QueryOptions) => BatchableQuery<Edge<E, From, To>>;
|
|
2696
2505
|
/**
|
|
2697
|
-
*
|
|
2698
|
-
*
|
|
2699
|
-
*
|
|
2700
|
-
*
|
|
2506
|
+
* Deferred variant of `findTo` for use with `store.batch()`.
|
|
2507
|
+
*
|
|
2508
|
+
* Returns a `BatchableQuery` instead of executing immediately. Accepts
|
|
2509
|
+
* the same temporal `options` as {@link EdgeCollection.findTo}. Costs one
|
|
2510
|
+
* statement per call, like {@link EdgeCollection.batchFindFrom}.
|
|
2701
2511
|
*/
|
|
2702
|
-
|
|
2703
|
-
direction?: TraversalDirection$1;
|
|
2704
|
-
expand?: TraversalExpansion;
|
|
2705
|
-
from?: keyof Aliases & string;
|
|
2706
|
-
}): TraversalBuilder<G, Aliases, EdgeAliases & Record<EA, EdgeAlias<DynamicEdgeType, true>>, string, EA, TraversalDirection$1, true, false, false, RecursiveAliases, CoordinateState>;
|
|
2512
|
+
batchFindTo: (to: NodeRef<To>, options?: QueryOptions) => BatchableQuery<Edge<E, From, To>>;
|
|
2707
2513
|
/**
|
|
2708
|
-
*
|
|
2514
|
+
* Deferred variant of `findByEndpoints` for use with `store.batch()`.
|
|
2515
|
+
*
|
|
2516
|
+
* Returns a `BatchableQuery` that yields a 0-or-1 element array
|
|
2517
|
+
* (matching `findByEndpoints`' at-most-one semantics). Costs one statement
|
|
2518
|
+
* per call, like {@link EdgeCollection.batchFindFrom}.
|
|
2709
2519
|
*/
|
|
2710
|
-
|
|
2520
|
+
batchFindByEndpoints: (from: NodeRef<From>, to: NodeRef<To>, options?: EdgeFindByEndpointsOptions<E>, temporal?: QueryOptions) => BatchableQuery<Edge<E, From, To>>;
|
|
2521
|
+
/** Delete an edge (soft delete - sets deletedAt timestamp) */
|
|
2522
|
+
delete: (id: EdgeId<E>) => Promise<void>;
|
|
2711
2523
|
/**
|
|
2712
|
-
*
|
|
2713
|
-
* Use with groupBy() for aggregate queries.
|
|
2524
|
+
* Permanently delete an edge from the database.
|
|
2714
2525
|
*
|
|
2715
|
-
*
|
|
2526
|
+
* Unlike `delete()` which performs a soft delete, this permanently
|
|
2527
|
+
* removes the edge record.
|
|
2528
|
+
*
|
|
2529
|
+
* **Warning:** This operation is irreversible and should be used carefully.
|
|
2530
|
+
* Consider using soft delete (`delete()`) for most use cases.
|
|
2716
2531
|
*/
|
|
2717
|
-
|
|
2532
|
+
hardDelete: (id: EdgeId<E>) => Promise<void>;
|
|
2533
|
+
/** Find edges matching endpoint and pagination criteria */
|
|
2534
|
+
find: (filter?: Readonly<{
|
|
2535
|
+
from?: NodeRef<From>;
|
|
2536
|
+
to?: NodeRef<To>;
|
|
2537
|
+
limit?: number;
|
|
2538
|
+
offset?: number;
|
|
2539
|
+
}>, temporal?: QueryOptions) => Promise<Edge<E, From, To>[]>;
|
|
2540
|
+
/** Count edges matching criteria */
|
|
2541
|
+
count: (filter?: Readonly<{
|
|
2542
|
+
from?: NodeRef<From>;
|
|
2543
|
+
to?: NodeRef<To>;
|
|
2544
|
+
}>, temporal?: QueryOptions) => Promise<number>;
|
|
2718
2545
|
/**
|
|
2719
|
-
*
|
|
2546
|
+
* Create multiple edges in a batch.
|
|
2547
|
+
*
|
|
2548
|
+
* More efficient than calling create() multiple times.
|
|
2549
|
+
* Use `bulkInsert` for the dedicated fast path that skips returning results.
|
|
2550
|
+
*
|
|
2551
|
+
* `validFrom` defaults to the operation's creation timestamp when omitted.
|
|
2720
2552
|
*/
|
|
2721
|
-
|
|
2553
|
+
bulkCreate: (items: readonly Readonly<{
|
|
2554
|
+
from: NodeRef<From>;
|
|
2555
|
+
to: NodeRef<To>;
|
|
2556
|
+
props?: z.input<E["schema"]>;
|
|
2557
|
+
id?: string;
|
|
2558
|
+
validFrom?: string;
|
|
2559
|
+
validTo?: string;
|
|
2560
|
+
}>[]) => Promise<Edge<E, From, To>[]>;
|
|
2722
2561
|
/**
|
|
2723
|
-
*
|
|
2562
|
+
* Create or update multiple edges in a batch.
|
|
2563
|
+
*
|
|
2564
|
+
* For each item, if an edge with the given ID exists, updates it.
|
|
2565
|
+
* Otherwise, creates a new edge with that ID.
|
|
2566
|
+
*
|
|
2567
|
+
* `validFrom` only applies on the create branch, defaulting to the
|
|
2568
|
+
* operation's creation timestamp when omitted; it has no effect on update.
|
|
2724
2569
|
*/
|
|
2725
|
-
|
|
2570
|
+
bulkUpsertById: (items: readonly Readonly<{
|
|
2571
|
+
id: EdgeId<E>;
|
|
2572
|
+
from: NodeRef<From>;
|
|
2573
|
+
to: NodeRef<To>;
|
|
2574
|
+
props?: z.input<E["schema"]>;
|
|
2575
|
+
validFrom?: string;
|
|
2576
|
+
validTo?: string;
|
|
2577
|
+
}>[]) => Promise<Edge<E, From, To>[]>;
|
|
2726
2578
|
/**
|
|
2727
|
-
*
|
|
2579
|
+
* Insert multiple edges without returning results.
|
|
2580
|
+
*
|
|
2581
|
+
* This is the dedicated fast path for bulk inserts. Unlike `bulkCreate`
|
|
2582
|
+
* with `returnResults: false`, the intent is unambiguous: no results
|
|
2583
|
+
* are returned and the operation is wrapped in a transaction.
|
|
2584
|
+
*
|
|
2585
|
+
* `validFrom` defaults to the operation's creation timestamp when omitted.
|
|
2728
2586
|
*/
|
|
2729
|
-
|
|
2587
|
+
bulkInsert: (items: readonly Readonly<{
|
|
2588
|
+
from: NodeRef<From>;
|
|
2589
|
+
to: NodeRef<To>;
|
|
2590
|
+
props?: z.input<E["schema"]>;
|
|
2591
|
+
id?: string;
|
|
2592
|
+
validFrom?: string;
|
|
2593
|
+
validTo?: string;
|
|
2594
|
+
}>[]) => Promise<void>;
|
|
2730
2595
|
/**
|
|
2731
|
-
*
|
|
2732
|
-
* Use with aggregate functions like COUNT, SUM, AVG in select().
|
|
2596
|
+
* Delete multiple edges by ID.
|
|
2733
2597
|
*
|
|
2734
|
-
*
|
|
2735
|
-
*
|
|
2598
|
+
* Atomic when the backend supports transactions. Silently ignores IDs
|
|
2599
|
+
* that don't exist.
|
|
2736
2600
|
*/
|
|
2737
|
-
|
|
2601
|
+
bulkDelete: (ids: readonly EdgeId<E>[]) => Promise<void>;
|
|
2738
2602
|
/**
|
|
2739
|
-
*
|
|
2740
|
-
* Use when you want to group by a complete node rather than a specific field.
|
|
2603
|
+
* Find an edge by endpoints and optional property fields.
|
|
2741
2604
|
*
|
|
2742
|
-
*
|
|
2605
|
+
* Returns the first matching edge at the read coordinate, or undefined.
|
|
2606
|
+
* Honors the temporal model like `findFrom` / `findTo`: by default
|
|
2607
|
+
* (`current` mode) soft-deleted and out-of-window edges are excluded; under
|
|
2608
|
+
* `includeTombstones` a soft-deleted edge can be returned.
|
|
2609
|
+
*
|
|
2610
|
+
* @param from - Source node
|
|
2611
|
+
* @param to - Target node
|
|
2612
|
+
* @param options - Match criteria (matchOn fields and property values)
|
|
2613
|
+
* @param temporal - Temporal coordinate. With no `temporal`, the graph's
|
|
2614
|
+
* default `temporalMode` applies (so under the default `"current"` mode,
|
|
2615
|
+
* edges outside their validity window are excluded). Pass
|
|
2616
|
+
* `temporalMode` / `asOf` to read the edge as of another coordinate.
|
|
2743
2617
|
*/
|
|
2744
|
-
|
|
2618
|
+
findByEndpoints: (from: NodeRef<From>, to: NodeRef<To>, options?: EdgeFindByEndpointsOptions<E>, temporal?: QueryOptions) => Promise<Edge<E, From, To> | undefined>;
|
|
2745
2619
|
/**
|
|
2746
|
-
*
|
|
2747
|
-
* Use after groupBy() to filter based on aggregate values.
|
|
2620
|
+
* Get an existing edge by endpoints and optional property fields, or create a new one.
|
|
2748
2621
|
*
|
|
2749
|
-
*
|
|
2622
|
+
* Matches edges of this kind between `(from, to)`. When `matchOn` specifies
|
|
2623
|
+
* property fields, only edges whose properties match on those fields are considered.
|
|
2624
|
+
* Soft-deleted matches are resurrected when cardinality allows.
|
|
2625
|
+
*
|
|
2626
|
+
* `validFrom` only applies on the create branch, defaulting to the
|
|
2627
|
+
* operation's creation timestamp when omitted. `validTo` applies on create,
|
|
2628
|
+
* update, and resurrection, but not when an existing edge is returned
|
|
2629
|
+
* without a write.
|
|
2630
|
+
*
|
|
2631
|
+
* @param from - Source node
|
|
2632
|
+
* @param to - Target node
|
|
2633
|
+
* @param props - Full properties for create, or merge source for update
|
|
2634
|
+
* @param options - Match criteria and conflict resolution
|
|
2750
2635
|
*/
|
|
2751
|
-
|
|
2636
|
+
getOrCreateByEndpoints: (from: NodeRef<From>, to: NodeRef<To>, props: z.input<E["schema"]>, options?: EdgeGetOrCreateByEndpointsOptions<E>) => Promise<EdgeGetOrCreateByEndpointsResult<E, From, To>>;
|
|
2752
2637
|
/**
|
|
2753
|
-
*
|
|
2754
|
-
*
|
|
2755
|
-
* Applies only when the query contains both a `.similarTo()` and a
|
|
2756
|
-
* `.$fulltext.matches()` predicate. Without this call, the default is
|
|
2757
|
-
* RRF with k=60 and equal weights. A mismatch between `.fuseWith()`
|
|
2758
|
-
* configuration and the predicates on the query is caught during
|
|
2759
|
-
* compilation, not here.
|
|
2638
|
+
* Batch version of getOrCreateByEndpoints.
|
|
2760
2639
|
*
|
|
2761
|
-
*
|
|
2762
|
-
*
|
|
2763
|
-
* store.query()
|
|
2764
|
-
* .from("Document", "d")
|
|
2765
|
-
* .whereNode("d", d =>
|
|
2766
|
-
* d.$fulltext.matches("renewable energy", 50)
|
|
2767
|
-
* .and(d.embedding.similarTo(vec, 50))
|
|
2768
|
-
* .and(d.tenantId.eq(tenant))
|
|
2769
|
-
* )
|
|
2770
|
-
* .fuseWith({ k: 60, weights: { fulltext: 1.5 } })
|
|
2771
|
-
* .limit(10)
|
|
2772
|
-
* .execute();
|
|
2773
|
-
* ```
|
|
2640
|
+
* Results are returned in the same order as the input items.
|
|
2641
|
+
* Atomic when the backend supports transactions.
|
|
2774
2642
|
*/
|
|
2775
|
-
|
|
2643
|
+
bulkGetOrCreateByEndpoints: (items: readonly Readonly<{
|
|
2644
|
+
from: NodeRef<From>;
|
|
2645
|
+
to: NodeRef<To>;
|
|
2646
|
+
props: z.input<E["schema"]>;
|
|
2647
|
+
validFrom?: string;
|
|
2648
|
+
validTo?: string;
|
|
2649
|
+
}>[], options?: Pick<EdgeGetOrCreateByEndpointsOptions<E>, "matchOn" | "ifExists">) => Promise<EdgeGetOrCreateByEndpointsResult<E, From, To>[]>;
|
|
2650
|
+
}>;
|
|
2651
|
+
/**
|
|
2652
|
+
* Extract uniqueness constraint names from a NodeRegistration.
|
|
2653
|
+
*
|
|
2654
|
+
* - Returns `never` when no uniqueness constraints are configured.
|
|
2655
|
+
* - Returns a literal union when names are inferred via `defineGraph` const params.
|
|
2656
|
+
* - Falls back to `string` when names are widened/dynamic.
|
|
2657
|
+
*/
|
|
2658
|
+
type ConstraintNames<R extends NodeRegistration> = "unique" extends keyof R ? R["unique"] extends readonly {
|
|
2659
|
+
readonly name: infer N;
|
|
2660
|
+
}[] ? N & string : string : never;
|
|
2661
|
+
/**
|
|
2662
|
+
* Extract the union of 'from' node types from an EdgeRegistration.
|
|
2663
|
+
*/
|
|
2664
|
+
type EdgeFromTypes<R extends EdgeRegistration> = R["from"] extends readonly (infer N)[] ? N : never;
|
|
2665
|
+
/**
|
|
2666
|
+
* Extract the union of 'to' node types from an EdgeRegistration.
|
|
2667
|
+
*/
|
|
2668
|
+
type EdgeToTypes<R extends EdgeRegistration> = R["to"] extends readonly (infer N)[] ? N : never;
|
|
2669
|
+
/**
|
|
2670
|
+
* Create a type-safe EdgeCollection from an EdgeRegistration.
|
|
2671
|
+
* Extracts the edge type and from/to node types automatically.
|
|
2672
|
+
*/
|
|
2673
|
+
type TypedEdgeCollection<R extends EdgeRegistration> = EdgeCollection<R["type"], EdgeFromTypes<R> extends NodeType ? EdgeFromTypes<R> : NodeType, EdgeToTypes<R> extends NodeType ? EdgeToTypes<R> : NodeType>;
|
|
2674
|
+
/** Mapped type of all node collections for a graph. */
|
|
2675
|
+
type GraphNodeCollections<G extends GraphDef> = {
|
|
2676
|
+
[K in keyof G["nodes"] & string]-?: NodeCollection<G["nodes"][K]["type"], ConstraintNames<G["nodes"][K]>>;
|
|
2677
|
+
};
|
|
2678
|
+
/** Mapped type of all edge collections for a graph. */
|
|
2679
|
+
type GraphEdgeCollections<G extends GraphDef> = {
|
|
2680
|
+
[K in keyof G["edges"] & string]-?: TypedEdgeCollection<G["edges"][K]>;
|
|
2681
|
+
};
|
|
2682
|
+
/** Temporal-aware node reads — a {@link StoreView} pins these. */
|
|
2683
|
+
type NodeTemporalReads<N extends NodeType, CN extends string = string> = Pick<NodeCollection<N, CN>, (typeof NODE_TEMPORAL_READ_NAMES)[number]>;
|
|
2684
|
+
/**
|
|
2685
|
+
* Current-state-only node reads (constraint / index lookups). No temporal
|
|
2686
|
+
* axis, so a {@link StoreView} delegates them on a `current` pin and refuses
|
|
2687
|
+
* them on a temporal pin.
|
|
2688
|
+
*/
|
|
2689
|
+
type NodeCurrentReads<N extends NodeType, CN extends string = string> = Pick<NodeCollection<N, CN>, (typeof CURRENT_ONLY_READ_NAMES)[number]>;
|
|
2690
|
+
/** Node writes — never available on a read-only {@link StoreView}. */
|
|
2691
|
+
type NodeWrites<N extends NodeType, CN extends string = string> = Pick<NodeCollection<N, CN>, (typeof NODE_WRITE_NAMES)[number]>;
|
|
2692
|
+
/** Temporal-aware edge reads — a {@link StoreView} pins these. */
|
|
2693
|
+
type EdgeTemporalReads<E extends AnyEdgeType, From extends NodeType = NodeType, To extends NodeType = NodeType> = Pick<EdgeCollection<E, From, To>, (typeof EDGE_TEMPORAL_READ_NAMES)[number]>;
|
|
2694
|
+
/**
|
|
2695
|
+
* Deferred edge reads for `store.batch()` — absent from a {@link StoreView},
|
|
2696
|
+
* which has no batch context.
|
|
2697
|
+
*/
|
|
2698
|
+
type EdgeBatchReads<E extends AnyEdgeType, From extends NodeType = NodeType, To extends NodeType = NodeType> = Pick<EdgeCollection<E, From, To>, (typeof EDGE_BATCH_READ_NAMES)[number]>;
|
|
2699
|
+
/** Edge writes — never available on a read-only {@link StoreView}. */
|
|
2700
|
+
type EdgeWrites<E extends AnyEdgeType, From extends NodeType = NodeType, To extends NodeType = NodeType> = Pick<EdgeCollection<E, From, To>, (typeof EDGE_WRITE_NAMES)[number]>;
|
|
2701
|
+
/**
|
|
2702
|
+
* The read-only node surface a {@link StoreView} exposes for one node kind.
|
|
2703
|
+
* The temporal reads drop the per-call temporal argument — the pin owns the
|
|
2704
|
+
* axis; the current reads ({@link NodeCurrentReads}) are exposed as-is
|
|
2705
|
+
* (delegated on a `current` view, refused on a temporal pin). Writes live on
|
|
2706
|
+
* the live `Store`. The conformance test asserts the temporal part equals the
|
|
2707
|
+
* pinned form of {@link NodeTemporalReads}.
|
|
2708
|
+
*/
|
|
2709
|
+
type StoreViewNodeCollection<N extends NodeType, CN extends string = string> = Readonly<{
|
|
2710
|
+
/** Get a node by ID at the view's pinned coordinate. */
|
|
2711
|
+
getById: (id: NodeId<N>) => Promise<Node<N> | undefined>;
|
|
2712
|
+
/** Get multiple nodes by ID, preserving input order (undefined for missing). */
|
|
2713
|
+
getByIds: (ids: readonly NodeId<N>[]) => Promise<readonly (Node<N> | undefined)[]>;
|
|
2714
|
+
/** Find nodes matching criteria at the view's pinned coordinate. */
|
|
2715
|
+
find: (filter?: Readonly<{
|
|
2716
|
+
where?: (accessor: NodeAccessor<N>) => Predicate;
|
|
2717
|
+
limit?: number;
|
|
2718
|
+
offset?: number;
|
|
2719
|
+
}>) => Promise<Node<N>[]>;
|
|
2720
|
+
/** Count nodes at the view's pinned coordinate. */
|
|
2721
|
+
count: () => Promise<number>;
|
|
2722
|
+
}> & NodeCurrentReads<N, CN>;
|
|
2723
|
+
/**
|
|
2724
|
+
* The read-only edge surface a {@link StoreView} exposes for one edge
|
|
2725
|
+
* kind, mirroring {@link StoreViewNodeCollection}. Every edge read —
|
|
2726
|
+
* including `findByEndpoints` — honors the pin via the same temporal model,
|
|
2727
|
+
* so (unlike nodes) there are no current-state-only edge reads.
|
|
2728
|
+
*/
|
|
2729
|
+
type StoreViewEdgeCollection<E extends AnyEdgeType, From extends NodeType = NodeType, To extends NodeType = NodeType> = Readonly<{
|
|
2730
|
+
/** Get an edge by ID at the view's pinned coordinate. */
|
|
2731
|
+
getById: (id: EdgeId<E>) => Promise<Edge<E, From, To> | undefined>;
|
|
2732
|
+
/** Get multiple edges by ID, preserving input order (undefined for missing). */
|
|
2733
|
+
getByIds: (ids: readonly EdgeId<E>[]) => Promise<readonly (Edge<E, From, To> | undefined)[]>;
|
|
2734
|
+
/** Find edges matching endpoint and pagination criteria. */
|
|
2735
|
+
find: (filter?: Readonly<{
|
|
2736
|
+
from?: NodeRef<From>;
|
|
2737
|
+
to?: NodeRef<To>;
|
|
2738
|
+
limit?: number;
|
|
2739
|
+
offset?: number;
|
|
2740
|
+
}>) => Promise<Edge<E, From, To>[]>;
|
|
2741
|
+
/** Count edges matching criteria at the view's pinned coordinate. */
|
|
2742
|
+
count: (filter?: Readonly<{
|
|
2743
|
+
from?: NodeRef<From>;
|
|
2744
|
+
to?: NodeRef<To>;
|
|
2745
|
+
}>) => Promise<number>;
|
|
2746
|
+
/** Find edges from a specific node at the view's pinned coordinate. */
|
|
2747
|
+
findFrom: (from: NodeRef<From>) => Promise<Edge<E, From, To>[]>;
|
|
2748
|
+
/** Find edges to a specific node at the view's pinned coordinate. */
|
|
2749
|
+
findTo: (to: NodeRef<To>) => Promise<Edge<E, From, To>[]>;
|
|
2750
|
+
/** Find the edges from a set of source nodes at the view's pinned coordinate. */
|
|
2751
|
+
bulkFindFrom: (froms: readonly NodeRef<From>[], options?: EdgeBulkFindOptions) => Promise<readonly Edge<E, From, To>[][]>;
|
|
2752
|
+
/** Find the edges into a set of target nodes at the view's pinned coordinate. */
|
|
2753
|
+
bulkFindTo: (tos: readonly NodeRef<To>[], options?: EdgeBulkFindOptions) => Promise<readonly Edge<E, From, To>[][]>;
|
|
2754
|
+
/** Find the edge between two endpoints at the view's pinned coordinate. */
|
|
2755
|
+
findByEndpoints: (from: NodeRef<From>, to: NodeRef<To>, options?: EdgeFindByEndpointsOptions<E>) => Promise<Edge<E, From, To> | undefined>;
|
|
2756
|
+
}>;
|
|
2757
|
+
/**
|
|
2758
|
+
* Read-only view edge collection derived from an `EdgeRegistration`,
|
|
2759
|
+
* extracting the edge type and from/to node types — the read-only
|
|
2760
|
+
* counterpart of {@link TypedEdgeCollection}.
|
|
2761
|
+
*/
|
|
2762
|
+
type TypedStoreViewEdgeCollection<R extends EdgeRegistration> = StoreViewEdgeCollection<R["type"], EdgeFromTypes<R> extends NodeType ? EdgeFromTypes<R> : NodeType, EdgeToTypes<R> extends NodeType ? EdgeToTypes<R> : NodeType>;
|
|
2763
|
+
/** Mapped type of all read-only view node collections for a graph. */
|
|
2764
|
+
type StoreViewNodeCollections<G extends GraphDef> = {
|
|
2765
|
+
[K in keyof G["nodes"] & string]-?: StoreViewNodeCollection<G["nodes"][K]["type"]>;
|
|
2766
|
+
};
|
|
2767
|
+
/** Mapped type of all read-only view edge collections for a graph. */
|
|
2768
|
+
type StoreViewEdgeCollections<G extends GraphDef> = {
|
|
2769
|
+
[K in keyof G["edges"] & string]-?: TypedStoreViewEdgeCollection<G["edges"][K]>;
|
|
2770
|
+
};
|
|
2771
|
+
/** Options for one bounded, forward-only recorded-time collection scan. */
|
|
2772
|
+
type RecordedScanOptions = Readonly<{
|
|
2773
|
+
/** Maximum entities to return. Defaults to 1,000 and cannot exceed 1,000. */
|
|
2774
|
+
limit?: number;
|
|
2775
|
+
/** Opaque cursor returned by the preceding page. */
|
|
2776
|
+
after?: string;
|
|
2777
|
+
}>;
|
|
2778
|
+
/** One page from a deterministic recorded-time collection scan. */
|
|
2779
|
+
type RecordedScanPage<T> = Readonly<{
|
|
2780
|
+
/** Entities ordered by canonical id ascending. */
|
|
2781
|
+
data: readonly T[];
|
|
2782
|
+
/** Cursor for the next page, or `undefined` when the scan is complete. */
|
|
2783
|
+
nextCursor: string | undefined;
|
|
2784
|
+
/** Whether another page exists after this one. */
|
|
2785
|
+
hasNextPage: boolean;
|
|
2786
|
+
}>;
|
|
2787
|
+
/** Recorded-time reconstructing reads for one node kind. */
|
|
2788
|
+
type RecordedStoreViewNodeCollection<N extends NodeType> = Pick<StoreViewNodeCollection<N>, (typeof RECORDED_POINT_READ_NAMES)[number]> & Readonly<{
|
|
2789
|
+
/** Scan one bounded page at the view's pinned coordinate. */
|
|
2790
|
+
scan: (options?: RecordedScanOptions) => Promise<RecordedScanPage<Node<N>>>;
|
|
2791
|
+
}>;
|
|
2792
|
+
/** Recorded-time reconstructing reads for one edge kind. */
|
|
2793
|
+
type RecordedStoreViewEdgeCollection<E extends AnyEdgeType, From extends NodeType = NodeType, To extends NodeType = NodeType> = Pick<StoreViewEdgeCollection<E, From, To>, (typeof RECORDED_POINT_READ_NAMES)[number]> & Readonly<{
|
|
2794
|
+
/** Scan one bounded page at the view's pinned coordinate. */
|
|
2795
|
+
scan: (options?: RecordedScanOptions) => Promise<RecordedScanPage<Edge<E, From, To>>>;
|
|
2796
|
+
}>;
|
|
2797
|
+
/** Recorded-time edge collection derived from an `EdgeRegistration`. */
|
|
2798
|
+
type TypedRecordedStoreViewEdgeCollection<R extends EdgeRegistration> = RecordedStoreViewEdgeCollection<R["type"], EdgeFromTypes<R> extends NodeType ? EdgeFromTypes<R> : NodeType, EdgeToTypes<R> extends NodeType ? EdgeToTypes<R> : NodeType>;
|
|
2799
|
+
/** Mapped type of all recorded-time node reconstructing-read collections. */
|
|
2800
|
+
type RecordedStoreViewNodeCollections<G extends GraphDef> = {
|
|
2801
|
+
[K in keyof G["nodes"] & string]-?: RecordedStoreViewNodeCollection<G["nodes"][K]["type"]>;
|
|
2802
|
+
};
|
|
2803
|
+
/** Mapped type of all recorded-time edge reconstructing-read collections. */
|
|
2804
|
+
type RecordedStoreViewEdgeCollections<G extends GraphDef> = {
|
|
2805
|
+
[K in keyof G["edges"] & string]-?: TypedRecordedStoreViewEdgeCollection<G["edges"][K]>;
|
|
2806
|
+
};
|
|
2807
|
+
/**
|
|
2808
|
+
* Whether — and why — `tx.sql` can be used on a transaction context. A single
|
|
2809
|
+
* required discriminant covering exactly the four states raw-SQL access can be
|
|
2810
|
+
* in, so an adapter caller branches on capability instead of truthiness-testing
|
|
2811
|
+
* `tx.sql`. The non-available variants omit `sql` entirely, so even reading the
|
|
2812
|
+
* handle requires first narrowing `sqlAvailability` to `"available"`. The
|
|
2813
|
+
* runtime object keeps a fail-loud getter under history / revision tracking for
|
|
2814
|
+
* JavaScript and type-suppressed callers. See
|
|
2815
|
+
* {@link AdapterTransactionContext} for the per-value semantics.
|
|
2816
|
+
*/
|
|
2817
|
+
type SqlAvailability = "available" | "history" | "revisionTracking" | "unavailable";
|
|
2818
|
+
type AdapterTransactionSqlAccess<TNativeTransaction> = Readonly<{
|
|
2819
|
+
sql: TNativeTransaction;
|
|
2820
|
+
sqlAvailability: "available";
|
|
2821
|
+
}> | Readonly<{
|
|
2822
|
+
sqlAvailability: "history" | "revisionTracking";
|
|
2823
|
+
}> | Readonly<{
|
|
2824
|
+
sqlAvailability: "unavailable";
|
|
2825
|
+
}>;
|
|
2826
|
+
declare const TRANSACTION_RUNTIME: unique symbol;
|
|
2827
|
+
type TransactionRuntime = Readonly<{
|
|
2828
|
+
backend: TransactionBackend;
|
|
2829
|
+
runNodeOperationHooks: <T>(operation: "create" | "update" | "delete", kind: string, id: string, fn: () => Promise<T>) => Promise<T>;
|
|
2830
|
+
}>;
|
|
2831
|
+
/**
|
|
2832
|
+
* The portable transaction context mirrors the Store's typed graph operations
|
|
2833
|
+
* while exposing only a read-only backend projection bound to the transaction.
|
|
2834
|
+
* Adapter-native handles are available only through
|
|
2835
|
+
* {@link AdapterTransactionContext}; arbitrary backend writes are absent from
|
|
2836
|
+
* every public transaction context. TypeGraph's non-enumerable symbol port is
|
|
2837
|
+
* an unsupported implementation detail, not a JavaScript security boundary:
|
|
2838
|
+
* reflective code can still discover symbol properties.
|
|
2839
|
+
*
|
|
2840
|
+
* @example
|
|
2841
|
+
* ```typescript
|
|
2842
|
+
* await store.transaction(async (tx) => {
|
|
2843
|
+
* const person = await tx.nodes.Person.create({ name: "Alice" });
|
|
2844
|
+
* const company = await tx.nodes.Company.create({ name: "Acme" });
|
|
2845
|
+
* await tx.edges.worksAt.create(person, company, { role: "Engineer" });
|
|
2846
|
+
* });
|
|
2847
|
+
* ```
|
|
2848
|
+
*/
|
|
2849
|
+
type TransactionCollections<G extends GraphDef> = Readonly<{
|
|
2850
|
+
[TRANSACTION_RUNTIME]: TransactionRuntime;
|
|
2851
|
+
nodes: GraphNodeCollections<G>;
|
|
2852
|
+
edges: GraphEdgeCollections<G>;
|
|
2853
|
+
/** Read-only backend projection bound to the same graph transaction. */
|
|
2854
|
+
backend: TransactionReadBackend;
|
|
2776
2855
|
/**
|
|
2777
|
-
*
|
|
2778
|
-
*
|
|
2779
|
-
*
|
|
2780
|
-
* traversals, ordering, and other query operations. Use this for
|
|
2781
|
-
* composing complex queries from simpler, reusable parts.
|
|
2782
|
-
*
|
|
2783
|
-
* @example
|
|
2784
|
-
* ```typescript
|
|
2785
|
-
* // Define a reusable fragment
|
|
2786
|
-
* const activeUsers = createFragment<MyGraph>()((q) =>
|
|
2787
|
-
* q.whereNode("u", ({ status }) => status.eq("active"))
|
|
2788
|
-
* );
|
|
2789
|
-
*
|
|
2790
|
-
* // Apply the fragment
|
|
2791
|
-
* const results = await query()
|
|
2792
|
-
* .from("User", "u")
|
|
2793
|
-
* .pipe(activeUsers)
|
|
2794
|
-
* .select((ctx) => ctx.u)
|
|
2795
|
-
* .execute();
|
|
2796
|
-
* ```
|
|
2797
|
-
*
|
|
2798
|
-
* @param fragment - A function that transforms the builder
|
|
2799
|
-
* @returns The transformed builder
|
|
2856
|
+
* Runtime string-keyed node collection access, mirroring
|
|
2857
|
+
* `Store.getNodeCollection`. Returns `undefined` when `kind` is not
|
|
2858
|
+
* registered in this graph.
|
|
2800
2859
|
*/
|
|
2801
|
-
|
|
2802
|
-
}
|
|
2803
|
-
|
|
2860
|
+
getNodeCollection: (kind: string) => DynamicNodeCollection | undefined;
|
|
2861
|
+
}>;
|
|
2804
2862
|
/**
|
|
2805
|
-
*
|
|
2863
|
+
* A portable transaction context containing only TypeGraph-owned graph
|
|
2864
|
+
* operations. Managed Stores use this surface so adapter-native handles never
|
|
2865
|
+
* enter their public contract.
|
|
2866
|
+
*/
|
|
2867
|
+
type TransactionContext<G extends GraphDef> = TransactionCollections<G>;
|
|
2868
|
+
/**
|
|
2869
|
+
* A transaction context exposed by an {@link AdapterStore}. In addition to the
|
|
2870
|
+
* portable graph collections, it carries the adapter-native handle when that
|
|
2871
|
+
* capability is available. The TypeGraph backend remains the same runtime
|
|
2872
|
+
* read projection as the portable context; adapter-native writes intentionally
|
|
2873
|
+
* go through `sql`, making that escape hatch explicit.
|
|
2874
|
+
*/
|
|
2875
|
+
type AdapterTransactionContext<G extends GraphDef, TNativeTransaction> = TransactionCollections<G> & AdapterTransactionSqlAccess<TNativeTransaction>;
|
|
2876
|
+
/**
|
|
2877
|
+
* Scoped write measurement, available only on the receipt-enabled transaction
|
|
2878
|
+
* contexts (`transactionWithReceipt`, `withRecordedTransaction`). Runs `fn`,
|
|
2879
|
+
* passing it a **scoped context** — a second view over the same transaction — and
|
|
2880
|
+
* returns a {@link TransactionOutcome} whose receipt counts exactly the writes
|
|
2881
|
+
* made *through that scoped context* (`scoped.nodes` / `scoped.edges`).
|
|
2806
2882
|
*
|
|
2807
|
-
*
|
|
2808
|
-
*
|
|
2883
|
+
* Attribution is by **which context you write through**, not by timing. A write
|
|
2884
|
+
* through the scoped context counts in both the scope and the outer receipt (it
|
|
2885
|
+
* happened in the transaction); a write through the outer `tx` during the scope
|
|
2886
|
+
* counts only in the outer receipt. This makes overlapping and concurrent
|
|
2887
|
+
* measures safe by construction — two scopes running under `Promise.all`, each
|
|
2888
|
+
* writing through its own scoped context, never cross-count. Nesting composes:
|
|
2889
|
+
* `scoped.measure(...)` opens a child scope that counts in itself, every
|
|
2890
|
+
* ancestor scope, and the outer receipt.
|
|
2809
2891
|
*
|
|
2810
|
-
*
|
|
2811
|
-
*
|
|
2892
|
+
* Counts otherwise inherit {@link TransactionReceipt} (bulk by input length, a
|
|
2893
|
+
* rejected write counts 0). The returned receipt's `recorded` is **always
|
|
2894
|
+
* `undefined`**: the recorded commit instant is a per-transaction flush concern,
|
|
2895
|
+
* unknowable mid-transaction.
|
|
2812
2896
|
*/
|
|
2813
|
-
|
|
2814
|
-
|
|
2815
|
-
|
|
2897
|
+
type ScopedMeasure<Context> = <T>(fn: (scoped: Context) => Promise<T>) => Promise<TransactionOutcome<T>>;
|
|
2898
|
+
/**
|
|
2899
|
+
* A {@link TransactionContext} that also exposes {@link ScopedMeasure}. Only the
|
|
2900
|
+
* receipt-enabled entry points (`transactionWithReceipt`,
|
|
2901
|
+
* `withRecordedTransaction`) hand a callback this type; plain `transaction()`
|
|
2902
|
+
* contexts have no recorder and therefore no `measure`, keeping that path
|
|
2903
|
+
* zero-overhead. Assignable to {@link TransactionContext}, so a projector helper
|
|
2904
|
+
* typed `(tx: TransactionContext<G>) => ...` accepts a measurable context. The
|
|
2905
|
+
* scoped context handed to `measure` is itself measurable, so scopes nest.
|
|
2906
|
+
*/
|
|
2907
|
+
type MeasurableTransactionContext<G extends GraphDef> = TransactionContext<G> & Readonly<{
|
|
2908
|
+
measure: ScopedMeasure<MeasurableTransactionContext<G>>;
|
|
2909
|
+
}>;
|
|
2910
|
+
/** Receipt-enabled transaction context for an {@link AdapterStore}. */
|
|
2911
|
+
type MeasurableAdapterTransactionContext<G extends GraphDef, TNativeTransaction> = AdapterTransactionContext<G, TNativeTransaction> & Readonly<{
|
|
2912
|
+
measure: ScopedMeasure<MeasurableAdapterTransactionContext<G, TNativeTransaction>>;
|
|
2913
|
+
}>;
|
|
2914
|
+
/**
|
|
2915
|
+
* Replace branded `NodeId` / `EdgeId` with plain `string` in each
|
|
2916
|
+
* method's parameter list. Return types are preserved unchanged.
|
|
2917
|
+
*
|
|
2918
|
+
* Handles three shapes:
|
|
2919
|
+
* 1. Direct branded ID parameter → `string`
|
|
2920
|
+
* 2. `readonly NodeId[]` / `readonly EdgeId[]` → `readonly string[]`
|
|
2921
|
+
* 3. Branded IDs nested one level inside bulk-item object arrays
|
|
2922
|
+
*/
|
|
2923
|
+
type WidenBrandedIds<T> = {
|
|
2924
|
+
readonly [K in keyof T]: T[K] extends (...args: infer A) => infer R ? (...args: {
|
|
2925
|
+
[P in keyof A]: UnbrandParam<A[P]>;
|
|
2926
|
+
}) => R : T[K];
|
|
2927
|
+
};
|
|
2928
|
+
/** Replace a branded ID with `string`, recursing one level into arrays. */
|
|
2929
|
+
type UnbrandParam<T> = T extends NodeId<NodeType> ? string : T extends EdgeId<AnyEdgeType> ? string : T extends readonly NodeId<NodeType>[] ? readonly string[] : T extends readonly EdgeId<AnyEdgeType>[] ? readonly string[] : T extends readonly (infer Item extends Record<string, unknown>)[] ? readonly UnbrandRecord<Item>[] : T;
|
|
2930
|
+
/** Replace branded ID values in object properties (does not recurse into nested structures). */
|
|
2931
|
+
type UnbrandRecord<T extends Record<string, unknown>> = {
|
|
2932
|
+
readonly [K in keyof T]: T[K] extends NodeId<NodeType> ? string : T[K] extends EdgeId<AnyEdgeType> ? string : T[K];
|
|
2933
|
+
};
|
|
2934
|
+
/**
|
|
2935
|
+
* A node collection with widened generics for runtime string-keyed access.
|
|
2936
|
+
*
|
|
2937
|
+
* This is the return type of `store.getNodeCollection(kind)`. It exposes
|
|
2938
|
+
* the full `NodeCollection` API but with `NodeType` and `string` constraint
|
|
2939
|
+
* names instead of the specific generic parameters, since the concrete type
|
|
2940
|
+
* is not known at compile time.
|
|
2941
|
+
*
|
|
2942
|
+
* ID parameters accept plain `string` instead of branded `NodeId<N>`, since
|
|
2943
|
+
* the dynamic path typically receives IDs from edge metadata, snapshots,
|
|
2944
|
+
* or external input where the brand is not available.
|
|
2945
|
+
*/
|
|
2946
|
+
type DynamicNodeCollection = WidenBrandedIds<NodeCollection<NodeType, string>>;
|
|
2947
|
+
/**
|
|
2948
|
+
* An edge collection with widened generics for runtime string-keyed access.
|
|
2949
|
+
*
|
|
2950
|
+
* This is the return type of `store.getEdgeCollection(kind)`. It exposes
|
|
2951
|
+
* the full `EdgeCollection` API but with `NodeType` endpoint types, since
|
|
2952
|
+
* the concrete from/to types are not known at compile time.
|
|
2953
|
+
*
|
|
2954
|
+
* ID parameters accept plain `string` instead of branded `EdgeId<E>`, since
|
|
2955
|
+
* the dynamic path typically receives IDs from edge metadata, snapshots,
|
|
2956
|
+
* or external input where the brand is not available.
|
|
2957
|
+
*/
|
|
2958
|
+
type DynamicEdgeCollection = WidenBrandedIds<EdgeCollection<AnyEdgeType, NodeType, NodeType>>;
|
|
2959
|
+
/**
|
|
2960
|
+
* A type-level projection of a store's surface onto a subset of its
|
|
2961
|
+
* node and edge collections.
|
|
2962
|
+
*
|
|
2963
|
+
* Node collections are projected with constraint names erased (`never`),
|
|
2964
|
+
* so constraint-based methods like `findByConstraint` become uncallable.
|
|
2965
|
+
* This is intentional: unique constraints are graph-registration-level
|
|
2966
|
+
* details that differ between graphs sharing the same node types.
|
|
2967
|
+
*
|
|
2968
|
+
* @example
|
|
2969
|
+
* ```typescript
|
|
2970
|
+
* type CoreStore = StoreProjection<
|
|
2971
|
+
* typeof myGraph,
|
|
2972
|
+
* "Document" | "Chunk",
|
|
2973
|
+
* "hasChunk"
|
|
2974
|
+
* >;
|
|
2975
|
+
*
|
|
2976
|
+
* async function ingestChunk(
|
|
2977
|
+
* store: CoreStore,
|
|
2978
|
+
* document: Node<typeof Document>,
|
|
2979
|
+
* text: string,
|
|
2980
|
+
* ) {
|
|
2981
|
+
* const chunk = await store.nodes.Chunk.create({ text });
|
|
2982
|
+
* await store.edges.hasChunk.create(document, chunk);
|
|
2983
|
+
* return chunk;
|
|
2984
|
+
* }
|
|
2985
|
+
* ```
|
|
2986
|
+
*
|
|
2987
|
+
* Both `Store<G>` and `TransactionContext<G>` are structurally assignable
|
|
2988
|
+
* to a `StoreProjection` whose keys are a subset of `G`.
|
|
2989
|
+
*/
|
|
2990
|
+
type StoreProjection<G extends GraphDef, N extends keyof G["nodes"] & string = never, E extends keyof G["edges"] & string = never> = Readonly<{
|
|
2991
|
+
nodes: {
|
|
2992
|
+
[K in N]-?: NodeCollection<G["nodes"][K]["type"], never>;
|
|
2993
|
+
};
|
|
2994
|
+
edges: Pick<GraphEdgeCollections<G>, E>;
|
|
2995
|
+
}>;
|
|
2816
2996
|
|
|
2817
2997
|
/**
|
|
2818
2998
|
* Shared types for Tier 1 graph algorithms.
|
|
@@ -3574,9 +3754,9 @@ declare class StoreSearch<G extends GraphDef> {
|
|
|
3574
3754
|
* transactions stay internal because each can mutate live rows without a
|
|
3575
3755
|
* corresponding capture flush.
|
|
3576
3756
|
*/
|
|
3577
|
-
declare const HISTORY_STORE_BACKEND_KEYS: readonly ["assertRuntimeContributionsInitialized", "assertVectorSlotInitialized", "assertVectorSlotsInitialized", "bootstrapTables", "capabilities", "checkUnique", "checkUniqueBatch", "claimIndexMaterialization", "close", "commitSchemaVersion", "compileSql", "countEdgesByKind", "countEdgesFrom", "countNodesByKind", "createVectorIndex", "deleteEdge", "deleteEdgesBatch", "deleteEmbedding", "deleteFulltext", "deleteFulltextBatch", "deleteNode", "deleteUnique", "deleteVectorSlotContribution", "dialect", "dropVectorIndex", "edgeExistsBetween", "ensureContributionMaterializationsTable", "ensureFulltextTable", "ensureIndexMaterializationsTable", "ensureKindRemovalsTable", "ensureReconciliationMarkersTable", "ensureRevisionOriginsTable", "ensureRuntimeContributions", "ensureVectorSlotContribution", "ensureVectorSlotContributions", "execute", "executeTemporaryStatement", "findEdgesByKind", "findEdgesConnectedTo", "findNodesByKind", "fulltextSearch", "fulltextStrategy", "getActiveSchema", "getAllKindRemovals", "getContributionMaterialization", "getEdge", "getEdges", "getIndexMaterialization", "getIndexMaterializations", "getNode", "getNodes", "getPendingKindRemovals", "getReconciliationMarker", "getSchemaVersion", "hardDeleteEdge", "hardDeleteEdgesBatch", "hardDeleteNode", "hybridSearch", "insertEdge", "insertEdgeNoReturn", "insertEdgesBatch", "insertEdgesBatchReturning", "insertNode", "insertNodeNoReturn", "insertNodesBatch", "insertNodesBatchReturning", "insertUnique", "insertUniqueBatch", "recordContributionMaterialization", "recordIndexMaterialization", "recordKindRemoval", "refreshStatistics", "releaseIndexMaterializationClaim", "setActiveVersion", "setReconciliationMarker", "tableNames", "updateEdge", "updateNode", "upsertEmbedding", "upsertEmbeddingBatch", "upsertFulltext", "upsertFulltextBatch", "vectorSearch", "vectorStrategy"];
|
|
3757
|
+
declare const HISTORY_STORE_BACKEND_KEYS: readonly ["assertRuntimeContributionsInitialized", "assertVectorSlotInitialized", "assertVectorSlotsInitialized", "bootstrapTables", "capabilities", "checkUnique", "checkUniqueBatch", "claimIndexMaterialization", "close", "commitSchemaVersion", "commitSchemaVersionIfKindsEmpty", "lockSchemaVersionForWrite", "compileSql", "countEdgesByKind", "countEdgesFrom", "countNodesByKind", "createVectorIndex", "deleteEdge", "deleteEdgesBatch", "deleteEmbedding", "deleteEmbeddingBatch", "deleteFulltext", "deleteFulltextBatch", "deleteNode", "deleteUnique", "hardDeleteUniquesByNodeIds", "deleteVectorSlotContribution", "dialect", "dropVectorIndex", "edgeExistsBetween", "ensureContributionMaterializationsTable", "ensureFulltextTable", "ensureIndexMaterializationsTable", "ensureKindRemovalsTable", "ensureReconciliationMarkersTable", "ensureRevisionOriginsTable", "ensureRuntimeContributions", "ensureVectorSlotContribution", "ensureVectorSlotContributions", "execute", "executeTemporaryStatement", "findEdgesByKind", "findEdgesByEndpointSet", "findEdgesByHeterogeneousEndpointSet", "findEdgesConnectedTo", "findNodesByKind", "fulltextSearch", "fulltextStrategy", "getActiveSchema", "getAllKindRemovals", "getContributionMaterialization", "getEdge", "getEdges", "getIndexMaterialization", "getIndexMaterializations", "getNode", "getNodes", "getPendingKindRemovals", "getReconciliationMarker", "getSchemaVersion", "hardDeleteEdge", "hardDeleteEdgesBatch", "hardDeleteNode", "hardDeleteUniquesByNodeIds", "hybridSearch", "insertEdge", "insertEdgeNoReturn", "insertEdgesBatch", "insertEdgesBatchReturning", "insertNode", "insertNodeNoReturn", "insertNodesBatch", "insertNodesBatchReturning", "insertUnique", "insertUniqueBatch", "recordContributionMaterialization", "recordIndexMaterialization", "recordKindRemoval", "refreshStatistics", "releaseIndexMaterializationClaim", "setActiveVersion", "setReconciliationMarker", "tableNames", "updateEdge", "updateNode", "updateNodeSet", "upsertEmbedding", "upsertEmbeddingBatch", "upsertFulltext", "upsertFulltextBatch", "vectorSearch", "vectorStrategy", "verifyContributions"];
|
|
3578
3758
|
type HistoryStoreBackendMember = (typeof HISTORY_STORE_BACKEND_KEYS)[number];
|
|
3579
|
-
type UnsafeHistoryStoreBackendMember = "clearGraph" | "executeDdl" | "executeRaw" | "executeStatement" | "transaction" | "trustedImport";
|
|
3759
|
+
type UnsafeHistoryStoreBackendMember = "clearGraph" | "executeDdl" | "executeRaw" | "executeStatement" | "repairContributions" | "schemaWriteTransaction" | "transaction" | "trustedImport";
|
|
3580
3760
|
type UnclassifiedHistoryStoreBackendMember = Exclude<keyof GraphBackend, HistoryStoreBackendMember | UnsafeHistoryStoreBackendMember>;
|
|
3581
3761
|
type HistoryStoreBackend = UnclassifiedHistoryStoreBackendMember extends never ? Readonly<Pick<GraphBackend, HistoryStoreBackendMember>> : never;
|
|
3582
3762
|
|
|
@@ -3662,8 +3842,8 @@ type UniqueIntrospection = Readonly<{
|
|
|
3662
3842
|
* budget); the data deletion happens here, scoped per-deployment via
|
|
3663
3843
|
* the `typegraph_kind_removals` status table. Splitting the verbs
|
|
3664
3844
|
* mirrors how `materializeIndexes` complements `evolve`: schema
|
|
3665
|
-
* commits are atomic and fast, data work is bounded by row count and
|
|
3666
|
-
* deferrable
|
|
3845
|
+
* commits are atomic and fast, while data work is bounded by row count and
|
|
3846
|
+
* deferrable. Candidates run sequentially because they share one graph lock.
|
|
3667
3847
|
*/
|
|
3668
3848
|
|
|
3669
3849
|
type MaterializeRemovalsOptions = Readonly<{
|
|
@@ -3672,11 +3852,40 @@ type MaterializeRemovalsOptions = Readonly<{
|
|
|
3672
3852
|
/** Halt on first failure. Default: false (best-effort). */
|
|
3673
3853
|
stopOnError?: boolean;
|
|
3674
3854
|
}>;
|
|
3855
|
+
/**
|
|
3856
|
+
* Outcome of one queued kind removal, discriminated on `status`.
|
|
3857
|
+
*
|
|
3858
|
+
* A union rather than one shape with optional fields, so each outcome carries
|
|
3859
|
+
* exactly its own payload: `"failed"` always has an `error`, `"skipped"`
|
|
3860
|
+
* always has a `reason`, and `"removed"` has neither. The flat form permitted
|
|
3861
|
+
* impossible states — a `"skipped"` with no reason, or a `"removed"` carrying
|
|
3862
|
+
* `reason: "kind-is-live"` — and narrowing on `status` still left both fields
|
|
3863
|
+
* optional at the use site.
|
|
3864
|
+
*/
|
|
3675
3865
|
type MaterializeRemovalsEntry = Readonly<{
|
|
3676
3866
|
kind: string;
|
|
3677
3867
|
entity: KindEntity;
|
|
3678
|
-
status: "removed"
|
|
3679
|
-
|
|
3868
|
+
status: "removed";
|
|
3869
|
+
}> | Readonly<{
|
|
3870
|
+
kind: string;
|
|
3871
|
+
entity: KindEntity;
|
|
3872
|
+
status: "failed";
|
|
3873
|
+
error: Error;
|
|
3874
|
+
}> | Readonly<{
|
|
3875
|
+
kind: string;
|
|
3876
|
+
entity: KindEntity;
|
|
3877
|
+
status: "skipped";
|
|
3878
|
+
/**
|
|
3879
|
+
* `"kind-is-live"`: the active schema declares this kind again — it was
|
|
3880
|
+
* dropped, then re-added — so deleting its rows would destroy live
|
|
3881
|
+
* data. The queue row stays pending, so a later removal of the same
|
|
3882
|
+
* kind still reclaims it.
|
|
3883
|
+
*
|
|
3884
|
+
* Reported rather than silent: an empty `results` array would otherwise
|
|
3885
|
+
* be indistinguishable from "nothing was pending", leaving the queue at
|
|
3886
|
+
* a non-zero depth with nothing explaining why.
|
|
3887
|
+
*/
|
|
3888
|
+
reason: "kind-is-live";
|
|
3680
3889
|
}>;
|
|
3681
3890
|
/**
|
|
3682
3891
|
* Outcome of reclaiming one per-`(graphId, kind, field)` vector table that
|
|
@@ -4001,12 +4210,15 @@ type StoreCore<G extends GraphDef> = Readonly<{
|
|
|
4001
4210
|
BatchableQuery<unknown>,
|
|
4002
4211
|
...BatchableQuery<unknown>[]
|
|
4003
4212
|
]>(...queries: Queries) => Promise<BatchResults<Queries>>;
|
|
4213
|
+
bulkFindEdgesFrom: <const K extends EdgeKinds<G>>(params: BulkFindEdgesFromParams<G, K>, options?: EdgeBulkFindEndpointOptions) => Promise<readonly BulkFindEdgesFromResult<G, K>[]>;
|
|
4004
4214
|
subgraph: <const EK extends EdgeKinds<G>, const NK extends NodeKinds<G> = NodeKinds<G>, const P extends SubgraphProject<G, NK, EK> | undefined = undefined>(rootId: NodeId<AllNodeTypes<G>>, options: SubgraphOptions<G, EK, NK, P>) => Promise<SubgraphResult<G, NK, EK, P>>;
|
|
4005
4215
|
clear: () => Promise<void>;
|
|
4006
4216
|
refreshStatistics: () => Promise<void>;
|
|
4007
4217
|
materializeIndexes: (options?: MaterializeIndexesOptions) => Promise<MaterializeIndexesResult>;
|
|
4008
4218
|
materializeSystemIndexes: (options?: MaterializeSystemIndexesOptions) => Promise<MaterializeIndexesResult>;
|
|
4009
4219
|
reembedVectorField: (kind: string, fieldPath: string, options?: ReembedVectorFieldOptions) => Promise<ReembedVectorFieldResult>;
|
|
4220
|
+
verifyContributions: () => Promise<readonly ContributionDiagnostic[]>;
|
|
4221
|
+
repairContributions: () => Promise<ContributionRepairResult>;
|
|
4010
4222
|
materializeRemovals: (options?: MaterializeRemovalsOptions) => Promise<MaterializeRemovalsResult>;
|
|
4011
4223
|
close: () => Promise<void>;
|
|
4012
4224
|
}>;
|
|
@@ -4185,6 +4397,10 @@ declare function createAdapterStore<G extends GraphDef, TNativeTransaction>(grap
|
|
|
4185
4397
|
* - Initializes the schema on first run (version 1)
|
|
4186
4398
|
* - Auto-migrates safe changes (additive changes)
|
|
4187
4399
|
* - Throws MigrationError for breaking changes
|
|
4400
|
+
* - Fences managed writes against concurrent schema-version commits; a stale Store
|
|
4401
|
+
* fails before writing instead of landing rows against a replaced schema
|
|
4402
|
+
* (official transactional backends only; unsupported custom backends fail
|
|
4403
|
+
* closed on their first managed write)
|
|
4188
4404
|
*
|
|
4189
4405
|
* @param graph - The graph definition
|
|
4190
4406
|
* @param backend - The database backend
|
|
@@ -4245,6 +4461,11 @@ declare function createAdapterStoreWithSchema<G extends GraphDef, TNativeTransac
|
|
|
4245
4461
|
* initialized, or `StoreNotInitializedError` when the schema is
|
|
4246
4462
|
* current but the runtime-contribution markers are missing/stale.
|
|
4247
4463
|
* The runtime can use a least-privilege, DML-only database role.
|
|
4464
|
+
* Managed writes are fenced against concurrent schema-version commits just like
|
|
4465
|
+
* `createStoreWithSchema`; a stale verified Store fails before writing.
|
|
4466
|
+
* Runtime backends must support transactions and the schema-write fence;
|
|
4467
|
+
* unsupported custom or HTTP backends attach for reads but fail closed on a
|
|
4468
|
+
* managed write.
|
|
4248
4469
|
* - **`createStore(graph, backend)`** is the same zero-DDL attach
|
|
4249
4470
|
* *without* the verification gate — fastest, but schema drift goes
|
|
4250
4471
|
* undetected until a hot-path operation trips.
|
|
@@ -4444,6 +4665,8 @@ declare class StoreView<G extends GraphDef> extends CoordinatePinnedView<G> {
|
|
|
4444
4665
|
get nodes(): StoreViewNodeCollections<G>;
|
|
4445
4666
|
/** Read-only edge collections pinned to this view's coordinate. */
|
|
4446
4667
|
get edges(): StoreViewEdgeCollections<G>;
|
|
4668
|
+
/** Heterogeneous multi-kind edge read pinned to this view's coordinate. */
|
|
4669
|
+
bulkFindEdgesFrom<const K extends EdgeKinds<G>>(params: BulkFindEdgesFromParams<G, K>, options?: Omit<EdgeBulkFindEndpointOptions, "temporalMode" | "asOf">): Promise<readonly BulkFindEdgesFromResult<G, K>[]>;
|
|
4447
4670
|
/**
|
|
4448
4671
|
* Read-only search facade. On a `current` view the read methods
|
|
4449
4672
|
* (`fulltext` / `vector` / `hybrid`) delegate to the live `store.search`,
|
|
@@ -4472,4 +4695,4 @@ declare class RecordedStoreView<G extends GraphDef> extends CoordinatePinnedView
|
|
|
4472
4695
|
get edges(): RecordedStoreViewEdgeCollections<G>;
|
|
4473
4696
|
}
|
|
4474
4697
|
|
|
4475
|
-
export {
|
|
4698
|
+
export { type EdgeGetOrCreateByEndpointsResult as $, type AliasMap as A, type BaseStoreOptions as B, type ConstraintNames as C, type DegreeOptions as D, type EdgeAliasMap as E, type DynamicEdgeType as F, type DynamicFieldBuilder as G, type HistoryStoreOptions as H, type DynamicNodeAccessor as I, type DynamicNodeCollection as J, type DynamicNodeType as K, type LiveStoreOptions as L, type DynamicSelectableEdge as M, type DynamicSelectableNode as N, type Edge as O, type EdgeAccessor as P, type QueryCoordinateState as Q, type RecordedReadStoreOptions as R, type StoreOptions as S, TraversalBuilder as T, type UnboundLiveStoreOptions as U, type EdgeBatchReads as V, type EdgeBulkFindEndpointOptions as W, type EdgeBulkFindOptions as X, type EdgeCollection as Y, type EdgeFindByEndpointsOptions as Z, type EdgeGetOrCreateByEndpointsOptions as _, type Store as a, type RebuildFulltextOptions as a$, type EdgeIntrospection as a0, type EdgeTemporalReads as a1, type EdgeWrites as a2, type EmptyAliasMap as a3, type EmptyEdgeAliasMap as a4, ExecutableAggregateQuery as a5, ExecutableQuery as a6, type FieldAccessor as a7, type FulltextSearchHit as a8, type FulltextSearchOptions as a9, type NodeAccessor as aA, type NodeAlias as aB, type NodeBulkFindByIndexOptions as aC, type NodeCollection as aD, type NodeCurrentReads as aE, type NodeGetOrCreateByConstraintOptions as aF, type NodeGetOrCreateByConstraintResult as aG, type NodeIdentifier as aH, type NodeRef as aI, type NodeTemporalReads as aJ, type NodeWrites as aK, type OntologyIntrospection as aL, type OperationHookContext as aM, type PageRankOptions as aN, type PageRankScore as aO, type PaginateOptions as aP, type PaginatedResult as aQ, type PathNode as aR, type PersonalizedPageRankOptions as aS, type PersonalizedPageRankSeed as aT, type Predicate as aU, PreparedQuery as aV, type PropsAccessor as aW, type QueryHookContext as aX, type QueryOptions as aY, type ReachableNode as aZ, type ReachableOptions as a_, type GetOrCreateAction as aa, type GraphAlgorithms as ab, type GraphEdgeCollections as ac, type GraphEdgeForKinds as ad, type GraphNodeCollections as ae, type GraphNodeReference as af, type HistoryStoreBackend as ag, type HookContext as ah, type HybridFulltextOptions as ai, type HybridSearchHit as aj, type HybridSearchOptions as ak, type HybridVectorOptions as al, type IfExistsMode as am, type InitialQueryBuilder as an, type KindIntrospection as ao, type LabelPropagationMembership as ap, type LabelPropagationOptions as aq, type MaterializeRemovalsEntry as ar, type MaterializeRemovalsOptions as as, type MaterializeRemovalsResult as at, type MeasurableAdapterHistoryTransactionContext as au, type MeasurableAdapterTransactionContext as av, type MeasurableTransactionContext as aw, type NeighborsOptions as ax, type NoRecordedCoordinate as ay, type Node as az, type HistoryStore as b, type UpdateNodeInput as b$, type RebuildFulltextResult as b0, type ReclaimedVectorFieldEntry as b1, type ReconciledSchema as b2, type RecordedScanOptions as b3, type RecordedScanPage as b4, RecordedStoreView as b5, type RecordedStoreViewEdgeCollection as b6, type RecordedStoreViewEdgeCollections as b7, type RecordedStoreViewNodeCollection as b8, type RecordedStoreViewNodeCollections as b9, type StoreViewNodeCollection as bA, type StoreViewNodeCollections as bB, type StoreViewPageRankOptions as bC, type StoreViewPersonalizedPageRankOptions as bD, type StoreViewReachableOptions as bE, type StoreViewShortestPathOptions as bF, type StoreViewSubgraphOptions as bG, type StoreViewWeaklyConnectedComponentsOptions as bH, type StoreViewWeightedShortestPathOptions as bI, type StreamOptions as bJ, type SubgraphEdgeResult as bK, type SubgraphNodeResult as bL, type SubgraphOptions as bM, type SubgraphResult as bN, type SubsetEdge as bO, type SubsetNode as bP, type TemporalAlgorithmOptions as bQ, type TransactionContext as bR, type TransactionOutcome as bS, type TransactionReceipt as bT, type TraversalDirection as bU, type TypedEdgeCollection as bV, type TypedRecordedStoreViewEdgeCollection as bW, type TypedStoreViewEdgeCollection as bX, UnionableQuery as bY, type UniqueIntrospection as bZ, type UpdateEdgeInput as b_, type RecursiveTraversalOptions as ba, type ReembedFunction as bb, type ReembedVectorFieldOptions as bc, type ReembedVectorFieldResult as bd, type SchemaIntrospection as be, type ScopedMeasure as bf, type SearchScopeOptions as bg, type SelectContext as bh, type SelectableEdge as bi, type SelectableNode as bj, type ShortestPathOptions as bk, type ShortestPathResult as bl, type SqlAvailability as bm, type StoreHooks as bn, type StoreProjection as bo, type StoreRef as bp, StoreSearch as bq, StoreView as br, type StoreViewCanReachOptions as bs, type StoreViewCoordinate as bt, type StoreViewDegreeOptions as bu, type StoreViewEdgeCollection as bv, type StoreViewEdgeCollections as bw, type StoreViewGraphAlgorithms as bx, type StoreViewLabelPropagationOptions as by, type StoreViewNeighborsOptions as bz, type RecordedReadStore as c, type VectorSearchHit as c0, type VectorSearchOptions as c1, type WeaklyConnectedComponentMembership as c2, type WeaklyConnectedComponentsOptions as c3, type WeightedShortestPathOptions as c4, type WeightedShortestPathResult as c5, createAdapterStore as c6, createAdapterStoreWithSchema as c7, createQueryBuilder as c8, createStore as c9, createStoreWithSchema as ca, createVerifiedAdapterStore as cb, createVerifiedStore as cc, defineSubgraphProject as cd, exists as ce, fieldRef as cf, inSubquery as cg, isParameterRef as ch, notExists as ci, notInSubquery as cj, param as ck, type RecursiveAliasMap as d, QueryBuilder as e, type EmptyRecursiveAliasMap as f, type AdapterHistoryStore as g, type AdapterHistoryTransactionContext as h, type AdapterRecordedReadStore as i, type AdapterStore as j, type AdapterTransactionContext as k, type AggregateResult as l, type AlgorithmCyclePolicy as m, type AnyEdge as n, type AnyNode as o, type BaseTraversalOptions as p, type BatchResults as q, type BatchableQuery as r, type BulkEdgeSourceGroup as s, type BulkFindEdgesFromParams as t, type BulkFindEdgesFromResult as u, type BulkOperationHookContext as v, type CreateEdgeInput as w, type CreateNodeInput as x, type DynamicEdgeAccessor as y, type DynamicEdgeCollection as z };
|