@nicia-ai/typegraph 0.37.1 → 0.39.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/README.md +12 -10
- package/dist/backend/drizzle/indexes.cjs +32 -0
- package/dist/backend/drizzle/indexes.cjs.map +1 -0
- package/dist/backend/drizzle/indexes.d.cts +43 -0
- package/dist/backend/drizzle/indexes.d.ts +43 -0
- package/dist/backend/drizzle/indexes.js +11 -0
- package/dist/backend/drizzle/indexes.js.map +1 -0
- package/dist/backend/index.cjs +161 -0
- package/dist/backend/index.cjs.map +1 -0
- package/dist/backend/index.d.cts +3 -0
- package/dist/backend/index.d.ts +3 -0
- package/dist/backend/index.js +8 -0
- package/dist/backend/index.js.map +1 -0
- package/dist/backend/postgres/index.cjs +32 -28
- package/dist/backend/postgres/index.d.cts +13 -12
- package/dist/backend/postgres/index.d.ts +13 -12
- package/dist/backend/postgres/index.js +19 -15
- package/dist/backend/postgres/pglite-store.cjs +67 -0
- package/dist/backend/postgres/pglite-store.cjs.map +1 -0
- package/dist/backend/postgres/pglite-store.d.cts +38 -0
- package/dist/backend/postgres/pglite-store.d.ts +38 -0
- package/dist/backend/postgres/pglite-store.js +65 -0
- package/dist/backend/postgres/pglite-store.js.map +1 -0
- package/dist/backend/postgres/pglite.cjs +25 -50
- package/dist/backend/postgres/pglite.cjs.map +1 -1
- package/dist/backend/postgres/pglite.d.cts +10 -9
- package/dist/backend/postgres/pglite.d.ts +10 -9
- package/dist/backend/postgres/pglite.js +20 -52
- package/dist/backend/postgres/pglite.js.map +1 -1
- package/dist/backend/sqlite/index.cjs +29 -25
- package/dist/backend/sqlite/index.d.cts +11 -11
- package/dist/backend/sqlite/index.d.ts +11 -11
- package/dist/backend/sqlite/index.js +17 -13
- package/dist/backend/sqlite/libsql.cjs +23 -19
- package/dist/backend/sqlite/libsql.cjs.map +1 -1
- package/dist/backend/sqlite/libsql.d.cts +9 -10
- package/dist/backend/sqlite/libsql.d.ts +9 -10
- package/dist/backend/sqlite/libsql.js +19 -15
- package/dist/backend/sqlite/libsql.js.map +1 -1
- package/dist/backend/sqlite/local-store.cjs +72 -0
- package/dist/backend/sqlite/local-store.cjs.map +1 -0
- package/dist/backend/sqlite/local-store.d.cts +42 -0
- package/dist/backend/sqlite/local-store.d.ts +42 -0
- package/dist/backend/sqlite/local-store.js +67 -0
- package/dist/backend/sqlite/local-store.js.map +1 -0
- package/dist/backend/sqlite/local.cjs +28 -183
- package/dist/backend/sqlite/local.cjs.map +1 -1
- package/dist/backend/sqlite/local.d.cts +8 -81
- package/dist/backend/sqlite/local.d.ts +8 -81
- package/dist/backend/sqlite/local.js +20 -180
- package/dist/backend/sqlite/local.js.map +1 -1
- package/dist/chunk-2EBMPJBO.js +16 -0
- package/dist/chunk-2EBMPJBO.js.map +1 -0
- package/dist/chunk-35S6P5ZU.js +27 -0
- package/dist/chunk-35S6P5ZU.js.map +1 -0
- package/dist/chunk-3LKL3S6X.js +50 -0
- package/dist/chunk-3LKL3S6X.js.map +1 -0
- package/dist/{chunk-RCVLFTCT.js → chunk-3SK4SVTW.js} +13 -12
- package/dist/chunk-3SK4SVTW.js.map +1 -0
- package/dist/chunk-3YFDFOYB.cjs +192 -0
- package/dist/chunk-3YFDFOYB.cjs.map +1 -0
- package/dist/{chunk-WOJMKB3N.cjs → chunk-5ELKD2FQ.cjs} +1677 -308
- package/dist/chunk-5ELKD2FQ.cjs.map +1 -0
- package/dist/{chunk-5AVRFNP4.cjs → chunk-6SRLCSAV.cjs} +3012 -1513
- package/dist/chunk-6SRLCSAV.cjs.map +1 -0
- package/dist/chunk-6XDBRDZE.js +312 -0
- package/dist/chunk-6XDBRDZE.js.map +1 -0
- package/dist/chunk-764JHTLT.cjs +15 -0
- package/dist/chunk-764JHTLT.cjs.map +1 -0
- package/dist/chunk-76HE7DJP.js +68 -0
- package/dist/chunk-76HE7DJP.js.map +1 -0
- package/dist/{chunk-VGDDG3XJ.cjs → chunk-7M3NACL3.cjs} +12 -12
- package/dist/{chunk-VGDDG3XJ.cjs.map → chunk-7M3NACL3.cjs.map} +1 -1
- package/dist/chunk-AOL64O4Z.js +165 -0
- package/dist/chunk-AOL64O4Z.js.map +1 -0
- package/dist/{chunk-27SSDCEP.cjs → chunk-B63IFHXR.cjs} +53 -74
- package/dist/chunk-B63IFHXR.cjs.map +1 -0
- package/dist/{chunk-3XXGYU62.cjs → chunk-BKAKAVRW.cjs} +56 -53
- package/dist/chunk-BKAKAVRW.cjs.map +1 -0
- package/dist/{chunk-YTSN73ND.js → chunk-BQITNFQJ.js} +3 -3
- package/dist/{chunk-YTSN73ND.js.map → chunk-BQITNFQJ.js.map} +1 -1
- package/dist/{chunk-GA4TT3DH.js → chunk-CBK2IVI2.js} +1999 -503
- package/dist/chunk-CBK2IVI2.js.map +1 -0
- package/dist/{chunk-6EEO3OVU.cjs → chunk-CWX77JB4.cjs} +22 -59
- package/dist/chunk-CWX77JB4.cjs.map +1 -0
- package/dist/{chunk-UGZUAYAR.js → chunk-D7PG5D5K.js} +4 -3
- package/dist/chunk-D7PG5D5K.js.map +1 -0
- package/dist/chunk-DDCIXXOO.js +9 -0
- package/dist/chunk-DDCIXXOO.js.map +1 -0
- package/dist/chunk-DDCYVIVV.cjs +44 -0
- package/dist/chunk-DDCYVIVV.cjs.map +1 -0
- package/dist/{chunk-UV3WP5WZ.js → chunk-DOKUXLFH.js} +61 -29
- package/dist/chunk-DOKUXLFH.js.map +1 -0
- package/dist/{chunk-XPCZADMT.cjs → chunk-DOVMTPKE.cjs} +89 -27
- package/dist/chunk-DOVMTPKE.cjs.map +1 -0
- package/dist/{chunk-5PNMDJ7J.js → chunk-DPNA466P.js} +14 -9
- package/dist/chunk-DPNA466P.js.map +1 -0
- package/dist/{chunk-BYPOGQWK.js → chunk-DRACN6XG.js} +6 -4
- package/dist/chunk-DRACN6XG.js.map +1 -0
- package/dist/{chunk-TGOMW4MB.cjs → chunk-E2Q7SP2K.cjs} +110 -109
- package/dist/chunk-E2Q7SP2K.cjs.map +1 -0
- package/dist/chunk-E6TXEISH.cjs +175 -0
- package/dist/chunk-E6TXEISH.cjs.map +1 -0
- package/dist/{chunk-3C2RYI6L.cjs → chunk-EOJFGECD.cjs} +11 -11
- package/dist/chunk-EOJFGECD.cjs.map +1 -0
- package/dist/{chunk-XWV4JT34.js → chunk-ERZ4QPQX.js} +27 -22
- package/dist/chunk-ERZ4QPQX.js.map +1 -0
- package/dist/{chunk-DFVLCOP6.js → chunk-EZH7FNUS.js} +3 -3
- package/dist/{chunk-DFVLCOP6.js.map → chunk-EZH7FNUS.js.map} +1 -1
- package/dist/{chunk-WWFHO375.cjs → chunk-FJMPR3OH.cjs} +4 -3
- package/dist/chunk-FJMPR3OH.cjs.map +1 -0
- package/dist/chunk-FMNUSGZ4.cjs +12 -0
- package/dist/chunk-FMNUSGZ4.cjs.map +1 -0
- package/dist/{chunk-EXU3RASM.js → chunk-G3CSQLLT.js} +20 -474
- package/dist/chunk-G3CSQLLT.js.map +1 -0
- package/dist/{chunk-EJYMTO3K.cjs → chunk-GKQU44SQ.cjs} +150 -118
- package/dist/chunk-GKQU44SQ.cjs.map +1 -0
- package/dist/chunk-GNPGGLAE.cjs +212 -0
- package/dist/chunk-GNPGGLAE.cjs.map +1 -0
- package/dist/{chunk-QARBLBXT.cjs → chunk-GUUWKPTK.cjs} +7 -7
- package/dist/{chunk-QARBLBXT.cjs.map → chunk-GUUWKPTK.cjs.map} +1 -1
- package/dist/chunk-GYA4JRP5.js +31 -0
- package/dist/chunk-GYA4JRP5.js.map +1 -0
- package/dist/{chunk-3GH67G4Z.cjs → chunk-HP6LWBLB.cjs} +16 -42
- package/dist/chunk-HP6LWBLB.cjs.map +1 -0
- package/dist/{chunk-NXQFATMF.cjs → chunk-HTQOBY75.cjs} +153 -123
- package/dist/chunk-HTQOBY75.cjs.map +1 -0
- package/dist/chunk-I6FX7AAG.js +39 -0
- package/dist/chunk-I6FX7AAG.js.map +1 -0
- package/dist/{chunk-VKGKDOKR.js → chunk-IFDXG2YJ.js} +1539 -206
- package/dist/chunk-IFDXG2YJ.js.map +1 -0
- package/dist/{chunk-IXGYRP2P.js → chunk-IFRPHG7O.js} +79 -49
- package/dist/chunk-IFRPHG7O.js.map +1 -0
- package/dist/chunk-IMQKXL4E.cjs +12 -0
- package/dist/{chunk-QSXTWU4U.cjs.map → chunk-IMQKXL4E.cjs.map} +1 -1
- package/dist/chunk-J6IJARLG.js +94 -0
- package/dist/chunk-J6IJARLG.js.map +1 -0
- package/dist/{chunk-3DS7Z4T4.cjs → chunk-JD2YC62H.cjs} +44 -43
- package/dist/chunk-JD2YC62H.cjs.map +1 -0
- package/dist/{chunk-W63OVYY4.js → chunk-K34OPSJK.js} +3 -3
- package/dist/{chunk-W63OVYY4.js.map → chunk-K34OPSJK.js.map} +1 -1
- package/dist/chunk-KAFXPB2L.js +184 -0
- package/dist/chunk-KAFXPB2L.js.map +1 -0
- package/dist/chunk-KIZSHRUI.cjs +49 -0
- package/dist/chunk-KIZSHRUI.cjs.map +1 -0
- package/dist/{chunk-K3Q3LJY3.js → chunk-KXFUQNF2.js} +201 -100
- package/dist/chunk-KXFUQNF2.js.map +1 -0
- package/dist/{chunk-UXLSNRYL.js → chunk-MTNEGGM2.js} +4 -4
- package/dist/chunk-MTNEGGM2.js.map +1 -0
- package/dist/{chunk-IP3CGGPA.cjs → chunk-N2V3HJFV.cjs} +92 -185
- package/dist/chunk-N2V3HJFV.cjs.map +1 -0
- package/dist/chunk-NAUA4PW5.cjs +28 -0
- package/dist/chunk-NAUA4PW5.cjs.map +1 -0
- package/dist/chunk-NMQ6C6TS.cjs +61 -0
- package/dist/chunk-NMQ6C6TS.cjs.map +1 -0
- package/dist/{chunk-2N6EOBTH.cjs → chunk-NPWACFQJ.cjs} +58 -53
- package/dist/chunk-NPWACFQJ.cjs.map +1 -0
- package/dist/{chunk-TKT2XHED.js → chunk-NQBYTLPW.js} +13 -12
- package/dist/chunk-NQBYTLPW.js.map +1 -0
- package/dist/{chunk-5KEQ74YU.cjs → chunk-NT6ILURI.cjs} +9 -86
- package/dist/chunk-NT6ILURI.cjs.map +1 -0
- package/dist/{chunk-3SLPDKHQ.js → chunk-PH4IJ3V5.js} +5 -77
- package/dist/chunk-PH4IJ3V5.js.map +1 -0
- package/dist/chunk-PWXGB77L.cjs +56 -0
- package/dist/chunk-PWXGB77L.cjs.map +1 -0
- package/dist/chunk-PZHC5GCD.js +193 -0
- package/dist/chunk-PZHC5GCD.js.map +1 -0
- package/dist/chunk-QMQLUA66.js +12 -0
- package/dist/chunk-QMQLUA66.js.map +1 -0
- package/dist/{chunk-5WWVZMVX.js → chunk-QZ7A6HBM.js} +2 -2
- package/dist/{chunk-5WWVZMVX.js.map → chunk-QZ7A6HBM.js.map} +1 -1
- package/dist/chunk-RW24SAHI.cjs +74 -0
- package/dist/chunk-RW24SAHI.cjs.map +1 -0
- package/dist/{chunk-BVRDGYXQ.cjs → chunk-SAFZ6JTI.cjs} +14 -9
- package/dist/chunk-SAFZ6JTI.cjs.map +1 -0
- package/dist/{chunk-L7HQ2OSI.js → chunk-SCTZRFW5.js} +87 -166
- package/dist/chunk-SCTZRFW5.js.map +1 -0
- package/dist/{chunk-5KPNWT6X.js → chunk-SDHV2MWU.js} +24 -45
- package/dist/chunk-SDHV2MWU.js.map +1 -0
- package/dist/{chunk-3RWZPJKV.js → chunk-SU7VQOJ3.js} +21 -78
- package/dist/chunk-SU7VQOJ3.js.map +1 -0
- package/dist/chunk-SVJ5GEXW.cjs +45 -0
- package/dist/chunk-SVJ5GEXW.cjs.map +1 -0
- package/dist/chunk-SVUKGWSN.cjs +102 -0
- package/dist/chunk-SVUKGWSN.cjs.map +1 -0
- package/dist/chunk-TAUGGLNQ.js +59 -0
- package/dist/chunk-TAUGGLNQ.js.map +1 -0
- package/dist/{chunk-A42GCBGX.cjs → chunk-TRF4EBJT.cjs} +6 -4
- package/dist/chunk-TRF4EBJT.cjs.map +1 -0
- package/dist/{chunk-KQJ54OG5.js → chunk-U4JDJKPD.js} +19 -56
- package/dist/chunk-U4JDJKPD.js.map +1 -0
- package/dist/chunk-UH2USOMG.cjs +627 -0
- package/dist/chunk-UH2USOMG.cjs.map +1 -0
- package/dist/{chunk-XGPUQ56G.js → chunk-UUIBACKJ.js} +15 -38
- package/dist/chunk-UUIBACKJ.js.map +1 -0
- package/dist/{chunk-5VQM6VWP.cjs → chunk-UWG5GX6E.cjs} +2 -2
- package/dist/{chunk-5VQM6VWP.cjs.map → chunk-UWG5GX6E.cjs.map} +1 -1
- package/dist/{chunk-K5UBVGJN.js → chunk-VDYA2HMS.js} +6 -6
- package/dist/{chunk-K5UBVGJN.js.map → chunk-VDYA2HMS.js.map} +1 -1
- package/dist/{chunk-NUIG3BCV.cjs → chunk-VXAFOF6Z.cjs} +93 -155
- package/dist/chunk-VXAFOF6Z.cjs.map +1 -0
- package/dist/chunk-X4PVHAZ6.cjs +83 -0
- package/dist/chunk-X4PVHAZ6.cjs.map +1 -0
- package/dist/{chunk-UYQMBBWJ.js → chunk-X6CNEA32.js} +23 -20
- package/dist/chunk-X6CNEA32.js.map +1 -0
- package/dist/chunk-X6RDQ5NB.cjs +335 -0
- package/dist/chunk-X6RDQ5NB.cjs.map +1 -0
- package/dist/{chunk-DEFQM7JU.cjs → chunk-XRU7V7FF.cjs} +7 -7
- package/dist/{chunk-DEFQM7JU.cjs.map → chunk-XRU7V7FF.cjs.map} +1 -1
- package/dist/{chunk-TPF25IG6.js → chunk-XZA3Y4YH.js} +3 -3
- package/dist/{chunk-TPF25IG6.js.map → chunk-XZA3Y4YH.js.map} +1 -1
- package/dist/{chunk-DIQ3AV5W.cjs → chunk-Y6UA55YS.cjs} +324 -224
- package/dist/chunk-Y6UA55YS.cjs.map +1 -0
- package/dist/chunk-Y7M44XEK.js +462 -0
- package/dist/chunk-Y7M44XEK.js.map +1 -0
- package/dist/{chunk-RRSNR3TP.js → chunk-YIRLBUNN.js} +3 -3
- package/dist/{chunk-RRSNR3TP.js.map → chunk-YIRLBUNN.js.map} +1 -1
- package/dist/chunk-YPUNPG2T.js +47 -0
- package/dist/chunk-YPUNPG2T.js.map +1 -0
- package/dist/{chunk-QERAIDRJ.js → chunk-Z2PPIVOO.js} +82 -22
- package/dist/chunk-Z2PPIVOO.js.map +1 -0
- package/dist/chunk-Z5QHVL5U.cjs +12 -0
- package/dist/chunk-Z5QHVL5U.cjs.map +1 -0
- package/dist/chunk-ZDH3DX3C.cjs +30 -0
- package/dist/chunk-ZDH3DX3C.cjs.map +1 -0
- package/dist/chunk-ZE6NVENI.js +77 -0
- package/dist/chunk-ZE6NVENI.js.map +1 -0
- package/dist/chunk-ZKZAIX42.cjs +479 -0
- package/dist/chunk-ZKZAIX42.cjs.map +1 -0
- package/dist/{chunk-TEDRJXOG.cjs → chunk-ZY4GXIVN.cjs} +5 -5
- package/dist/{chunk-TEDRJXOG.cjs.map → chunk-ZY4GXIVN.cjs.map} +1 -1
- package/dist/core/index.cjs +117 -0
- package/dist/core/index.cjs.map +1 -0
- package/dist/core/index.d.cts +225 -0
- package/dist/core/index.d.ts +225 -0
- package/dist/core/index.js +12 -0
- package/dist/core/index.js.map +1 -0
- package/dist/{ddl-CS0KUVwB.d.ts → ddl-Dx3Z0_WC.d.ts} +3 -3
- package/dist/{ddl-BD-ZfKeX.d.cts → ddl-J6sDyABg.d.cts} +3 -3
- package/dist/define-graph-CzEvA_8F.d.cts +174 -0
- package/dist/define-graph-DRo9xpYN.d.ts +174 -0
- package/dist/{extension-types-BM2ACfYO.d.cts → extension-types-BLEVH4SG.d.cts} +1 -1
- package/dist/{extension-types-BM2ACfYO.d.ts → extension-types-BLEVH4SG.d.ts} +1 -1
- package/dist/graph-extension/index.cjs +21 -19
- package/dist/graph-extension/index.d.cts +4 -4
- package/dist/graph-extension/index.d.ts +4 -4
- package/dist/graph-extension/index.js +6 -4
- package/dist/graph-merge/index.cjs +267 -218
- package/dist/graph-merge/index.cjs.map +1 -1
- package/dist/graph-merge/index.d.cts +17 -93
- package/dist/graph-merge/index.d.ts +17 -93
- package/dist/graph-merge/index.js +143 -94
- package/dist/graph-merge/index.js.map +1 -1
- package/dist/{index-BeacbPoe.d.ts → index-BD_3TCgh.d.ts} +6 -4
- package/dist/{index-BPM59vsg.d.cts → index-BihFPsPu.d.cts} +6 -4
- package/dist/{fulltext-strategy-C27vXaeB.d.cts → index-Bq7vSPHy.d.ts} +3195 -2646
- package/dist/{fulltext-strategy-DebsMrqg.d.ts → index-CrFL_ENI.d.cts} +3195 -2646
- package/dist/index.cjs +326 -315
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +59 -240
- package/dist/index.d.ts +59 -240
- package/dist/index.js +46 -79
- package/dist/index.js.map +1 -1
- package/dist/indexes/index.cjs +26 -38
- package/dist/indexes/index.d.cts +6 -41
- package/dist/indexes/index.d.ts +6 -41
- package/dist/indexes/index.js +14 -10
- package/dist/interchange/index.cjs +48 -39
- package/dist/interchange/index.cjs.map +1 -1
- package/dist/interchange/index.d.cts +7 -8
- package/dist/interchange/index.d.ts +7 -8
- package/dist/interchange/index.js +23 -14
- package/dist/interchange/index.js.map +1 -1
- package/dist/local-options-CZ1BnIoF.d.cts +29 -0
- package/dist/local-options-CZ1BnIoF.d.ts +29 -0
- package/dist/{manager-D00_NXvT.d.ts → manager-CASfhmzV.d.ts} +4 -173
- package/dist/{manager-nU1vTJLy.d.cts → manager-nCEJiYBb.d.cts} +4 -173
- package/dist/{materialize-indexes-zK2J_flP.d.ts → materialize-indexes-D4iei4Kp.d.ts} +1 -1
- package/dist/{materialize-indexes-CuR3gAZb.d.cts → materialize-indexes-ExQ6OrAh.d.cts} +1 -1
- package/dist/{postgres-IaBA4RgE.d.ts → postgres-Cl1ZAN1G.d.ts} +1 -1
- package/dist/{postgres-YrYmPlaU.d.cts → postgres-DMgIKQU-.d.cts} +1 -1
- package/dist/postgres-execution-fKW0qRiN.d.cts +14 -0
- package/dist/postgres-execution-fKW0qRiN.d.ts +14 -0
- package/dist/profiler/index.cjs +9 -8
- package/dist/profiler/index.cjs.map +1 -1
- package/dist/profiler/index.d.cts +9 -17
- package/dist/profiler/index.d.ts +9 -17
- package/dist/profiler/index.js +8 -7
- package/dist/profiler/index.js.map +1 -1
- package/dist/provenance/index.cjs +61 -55
- package/dist/provenance/index.cjs.map +1 -1
- package/dist/provenance/index.d.cts +7 -8
- package/dist/provenance/index.d.ts +7 -8
- package/dist/provenance/index.js +34 -28
- package/dist/provenance/index.js.map +1 -1
- package/dist/schema/index.cjs +46 -37
- package/dist/schema/index.cjs.map +1 -1
- package/dist/schema/index.d.cts +8 -10
- package/dist/schema/index.d.ts +8 -10
- package/dist/schema/index.js +22 -13
- package/dist/schema/index.js.map +1 -1
- package/dist/{sqlite-BUOHPx7p.d.ts → sqlite-BDkW39aa.d.cts} +1 -1
- package/dist/{sqlite-Pp8O19WE.d.cts → sqlite-CYfhvESj.d.ts} +1 -1
- package/dist/sqlite-execution-DwbE2a9y.d.cts +32 -0
- package/dist/sqlite-execution-DwbE2a9y.d.ts +32 -0
- package/dist/{store-view-X96Rd00T.d.cts → store-view-BJd6Vwpt.d.cts} +427 -1404
- package/dist/{store-view-ANL6mTph.d.ts → store-view-CLIhwMMX.d.ts} +427 -1404
- package/dist/temporal-BC_NQV5Y.d.cts +281 -0
- package/dist/temporal-DqtOEo_B.d.ts +281 -0
- package/dist/{types-r-Zyq2Hz.d.cts → types-COq3-vMC.d.cts} +2 -2
- package/dist/{types-wsvuBgPK.d.ts → types-CUevi_D1.d.ts} +2 -2
- package/dist/{where-CJOpJj3a.d.ts → where-BdE_cYtx.d.ts} +5 -5
- package/dist/{where-K3uBP33l.d.cts → where-C92TXCzT.d.cts} +5 -5
- package/package.json +37 -6
- package/dist/chunk-27SSDCEP.cjs.map +0 -1
- package/dist/chunk-2N6EOBTH.cjs.map +0 -1
- package/dist/chunk-3C2RYI6L.cjs.map +0 -1
- package/dist/chunk-3DS7Z4T4.cjs.map +0 -1
- package/dist/chunk-3GH67G4Z.cjs.map +0 -1
- package/dist/chunk-3RWZPJKV.js.map +0 -1
- package/dist/chunk-3SLPDKHQ.js.map +0 -1
- package/dist/chunk-3XXGYU62.cjs.map +0 -1
- package/dist/chunk-44TA22QT.js +0 -1478
- package/dist/chunk-44TA22QT.js.map +0 -1
- package/dist/chunk-5AVRFNP4.cjs.map +0 -1
- package/dist/chunk-5KEQ74YU.cjs.map +0 -1
- package/dist/chunk-5KPNWT6X.js.map +0 -1
- package/dist/chunk-5PNMDJ7J.js.map +0 -1
- package/dist/chunk-6EEO3OVU.cjs.map +0 -1
- package/dist/chunk-7YSP4V4R.cjs +0 -69
- package/dist/chunk-7YSP4V4R.cjs.map +0 -1
- package/dist/chunk-A42GCBGX.cjs.map +0 -1
- package/dist/chunk-BVRDGYXQ.cjs.map +0 -1
- package/dist/chunk-BYPOGQWK.js.map +0 -1
- package/dist/chunk-CUHM5CWJ.cjs +0 -12
- package/dist/chunk-CUHM5CWJ.cjs.map +0 -1
- package/dist/chunk-DIQ3AV5W.cjs.map +0 -1
- package/dist/chunk-EJYMTO3K.cjs.map +0 -1
- package/dist/chunk-EXU3RASM.js.map +0 -1
- package/dist/chunk-GA4TT3DH.js.map +0 -1
- package/dist/chunk-IP3CGGPA.cjs.map +0 -1
- package/dist/chunk-IPSVVTWT.cjs +0 -1540
- package/dist/chunk-IPSVVTWT.cjs.map +0 -1
- package/dist/chunk-IXGYRP2P.js.map +0 -1
- package/dist/chunk-K3Q3LJY3.js.map +0 -1
- package/dist/chunk-KQJ54OG5.js.map +0 -1
- package/dist/chunk-L7HQ2OSI.js.map +0 -1
- package/dist/chunk-M6VES7V6.js +0 -239
- package/dist/chunk-M6VES7V6.js.map +0 -1
- package/dist/chunk-NUIG3BCV.cjs.map +0 -1
- package/dist/chunk-NXQFATMF.cjs.map +0 -1
- package/dist/chunk-OHMP6N2J.js +0 -47
- package/dist/chunk-OHMP6N2J.js.map +0 -1
- package/dist/chunk-QERAIDRJ.js.map +0 -1
- package/dist/chunk-QSXTWU4U.cjs +0 -12
- package/dist/chunk-RCVLFTCT.js.map +0 -1
- package/dist/chunk-TGOMW4MB.cjs.map +0 -1
- package/dist/chunk-TKT2XHED.js.map +0 -1
- package/dist/chunk-UGZUAYAR.js.map +0 -1
- package/dist/chunk-UV3WP5WZ.js.map +0 -1
- package/dist/chunk-UXLSNRYL.js.map +0 -1
- package/dist/chunk-UYQMBBWJ.js.map +0 -1
- package/dist/chunk-VKGKDOKR.js.map +0 -1
- package/dist/chunk-VL2V6PEN.cjs +0 -261
- package/dist/chunk-VL2V6PEN.cjs.map +0 -1
- package/dist/chunk-WOJMKB3N.cjs.map +0 -1
- package/dist/chunk-WWFHO375.cjs.map +0 -1
- package/dist/chunk-XGPUQ56G.js.map +0 -1
- package/dist/chunk-XGU7DZDA.cjs +0 -1095
- package/dist/chunk-XGU7DZDA.cjs.map +0 -1
- package/dist/chunk-XPCZADMT.cjs.map +0 -1
- package/dist/chunk-XWV4JT34.js.map +0 -1
|
@@ -1,25 +1,32 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
1
|
+
import { compareStrings, compareCodePoints } from './chunk-DRACN6XG.js';
|
|
2
|
+
import { createEdgeRowMapper, createNodeRowMapper, SQLITE_ROW_MAPPER_CONFIG, POSTGRES_ROW_MAPPER_CONFIG } from './chunk-AOL64O4Z.js';
|
|
3
|
+
import { rowToNode, executeNodeBulkFindByIndex, executeNodeBulkFindByConstraint, executeNodeFindByConstraint, executeNodeBulkGetOrCreateByConstraint, executeNodeGetOrCreateByConstraint, executeNodeHardDelete, executeNodeDelete, nodeUpsertDirtyCheck, executeNodeUpsertUpdate, executeNodeUpdate, executeNodeCreateNoReturnBatch, executeNodeCreateBatch, executeNodeCreate, rowToEdge, runInWriteTransaction, checkCardinalityConstraint, runHookedWriteOperation, rowToNodeMeta, rowToEdgeMeta } from './chunk-3SK4SVTW.js';
|
|
4
|
+
import { isParameterRef, fieldRef, buildFieldBuilderForTypeInfo, stringField, createFulltextAccessor, storeRuntime, CURRENT_READ_INSTANT_PLACEHOLDER, DEFAULT_SQL_SCHEMA, requireSqlSchema, recordedReadSchemaFor, withPinnedReadInstant, STORE_RUNTIME, assertRevisionTrackableBackend, createSqlSchema, requireExternalRecordedReadSource, createRecordedReadBinding, createRecordedBackend, readRecordedClock, ensureRevisionOrigin, TRANSACTION_RUNTIME, withRecordedFlushObserver, recordedCaptureRequiresCallbackTransactionError, assertRecordedCaptureTransactionIsolation, createRecordedTransactionScope, lockRecordedGraphWrite, generateId, createGraphBackendProjection, vectorSlotKey, baseField, objectField, arrayField, dateField, numberField, computeFulltextContent, AUTO_REFRESH_STATISTICS_ROW_THRESHOLD, advanceRevisionClock, recordedReadSqlSchema, requireRecordedReadBinding, runInsertBatch, edgeInsertDispatch, runInsertBatchReturning, projectBackendMembers, sqlValueList, getEmbeddingFields, getNodeRowsByIds, getEdgeRowsByIds, compileKindFilter, currentReadInstant, compileTemporalFilter, validateEdgeEndpoints, buildPredicateIndex, compileFieldValue, recordedBindParamBudget, extractVectorSimilarityPredicates, extractFulltextMatchPredicates, currentReadInstantFor, extractTemporalOptions, compilePredicateExpression, getPredicatesForAlias, getFieldPointer, getNodeKindsForAlias, getHybridTargetAlias, closeRecordedHardDeletedKind, throwHistoryUnsafeSqlAccess, throwRevisionTrackingUnsafeSqlAccess, compilePredicateClauses, ALIAS_CTE_PREFIX, EMBEDDINGS_CTE_ALIAS, FULLTEXT_CTE_ALIAS, HYBRID_CANDIDATES_CTE_ALIAS } from './chunk-IFDXG2YJ.js';
|
|
5
|
+
import { chunk } from './chunk-35S6P5ZU.js';
|
|
6
|
+
import { runOptionallyInTransaction, createTransactionReadBackend, rowPropsToObject, createBackendOverlay, INTERNAL_TEMPORARY_WRITES } from './chunk-PZHC5GCD.js';
|
|
7
|
+
import { resolveReadCoordinate, withRecordedCoordinate, describeCoordinate, coordinateContext, asRecordedInstant, assertValidRecordedInstant } from './chunk-J6IJARLG.js';
|
|
8
|
+
import { loadAndMergeGraphExtensionDocument, ensureSchema, loadAndVerifyGraph, buildKindRegistry, mergeGraphExtension, commitNewSchemaVersion, applyDeprecatedKinds, loadActiveSchemaWithBootstrap, parseSerializedSchema, extensionKindNames, serializeSchemaProperties, buildGraphExtensionOntologyKeySet, compileTimeOntologyKey, serializeIndexDeclaration } from './chunk-SU7VQOJ3.js';
|
|
9
|
+
import { getTypeName } from './chunk-76HE7DJP.js';
|
|
10
|
+
import { validateEdgeProps } from './chunk-ZE6NVENI.js';
|
|
5
11
|
import { canonicalEqual, sortedReplacer } from './chunk-UR7W5YQK.js';
|
|
6
|
-
import {
|
|
7
|
-
import {
|
|
8
|
-
import {
|
|
9
|
-
import {
|
|
10
|
-
import {
|
|
11
|
-
import {
|
|
12
|
-
import {
|
|
13
|
-
import {
|
|
14
|
-
import {
|
|
15
|
-
import {
|
|
16
|
-
import {
|
|
17
|
-
import {
|
|
18
|
-
import {
|
|
12
|
+
import { withRecordedRelationsPrecondition, isMissingTableError } from './chunk-UUIBACKJ.js';
|
|
13
|
+
import { isKnownKind } from './chunk-PH4IJ3V5.js';
|
|
14
|
+
import { nowIso, validateOptionalCanonicalIsoDate } from './chunk-I6FX7AAG.js';
|
|
15
|
+
import { generateIndexDDL } from './chunk-U4JDJKPD.js';
|
|
16
|
+
import { SYSTEM_INDEX_DECLARATIONS, resolveSystemIndexTableName, systemIndexName, resolveSystemIndexNames, generateSystemIndexDDL } from './chunk-BQITNFQJ.js';
|
|
17
|
+
import { NODE_META_KEYS, EDGE_META_KEYS } from './chunk-VDYA2HMS.js';
|
|
18
|
+
import { sha256Hex, fnv1aBase36 } from './chunk-K34OPSJK.js';
|
|
19
|
+
import { DEFAULT_PAGINATION_LIMIT, DEFAULT_STREAM_BATCH_SIZE, SQLITE_PATH_DELIMITER, PG_ARRAY_START, PG_ARRAY_END, PG_PATH_ELEMENT_SEPARATOR, MAX_PG_IDENTIFIER_LENGTH } from './chunk-2EBMPJBO.js';
|
|
20
|
+
import { getDialect } from './chunk-G3CSQLLT.js';
|
|
21
|
+
import { assertVectorMinScore, vectorScoreExpression, vectorMinScoreCondition } from './chunk-Y7M44XEK.js';
|
|
22
|
+
import { isSqlPlaceholder, bindSqlValue, markAnnIndexScan, asCompiledSelectSql, isRawExecutable, annIndexScanTypes, sql, asCompiledRowsSql, markForceCustomPlan, asCompiledTemporaryStatementSql, asCompiledStatementSql } from './chunk-6XDBRDZE.js';
|
|
23
|
+
import { createSchemaIntrospector } from './chunk-D7PG5D5K.js';
|
|
24
|
+
import { requireDefined, isPresent } from './chunk-QMQLUA66.js';
|
|
19
25
|
import { getSearchableFields, resolveEmbeddingFields, resolveGraphVectorSlots, resolveDeclaredFulltextLanguage } from './chunk-PC2UBAUB.js';
|
|
20
|
-
import {
|
|
26
|
+
import { IncompatibleChangeError, RemoveCompileTimeKindError, KindHasReferentsError } from './chunk-SCTZRFW5.js';
|
|
27
|
+
import { validateProjectionField } from './chunk-XZA3Y4YH.js';
|
|
28
|
+
import { ConfigurationError, UnsupportedPredicateError, ValidationError, KindNotFoundError, EndpointError, EagerMaterializationError, CompilerInvariantError, CardinalityError, EdgeNotFoundError, DatabaseOperationError, UnsupportedBackendCapabilityError, GraphAlgorithmConvergenceError, EndpointNotFoundError, InvalidEdgeWeightError } from './chunk-DPNA466P.js';
|
|
21
29
|
import { jsonPointer, parseJsonPointer, resolveJsonPointer } from './chunk-G6Q5UM7U.js';
|
|
22
|
-
import { Placeholder, sql } from 'drizzle-orm';
|
|
23
30
|
|
|
24
31
|
// src/store/collection-surface.ts
|
|
25
32
|
var CURRENT_ONLY_READ_NAMES = [
|
|
@@ -176,7 +183,7 @@ function createBatchReadRefusal(entity, method, coordinate) {
|
|
|
176
183
|
function createRecordedUnsupportedRefusal(entity, method, coordinate) {
|
|
177
184
|
return () => Promise.reject(
|
|
178
185
|
new ConfigurationError(
|
|
179
|
-
`'${method}' is not available on a RecordedStoreView (${describeCoordinate(coordinate)}). Recorded-time reads are reconstructing reads; this view exposes only query, subgraph, graph algorithms, and
|
|
186
|
+
`'${method}' is not available on a RecordedStoreView (${describeCoordinate(coordinate)}). Recorded-time reads are reconstructing reads; this view exposes only query, subgraph, graph algorithms, and collection getById/getByIds/scan reads.`,
|
|
180
187
|
{
|
|
181
188
|
code: "RECORDED_STORE_VIEW_UNSUPPORTED",
|
|
182
189
|
entity,
|
|
@@ -279,7 +286,7 @@ function pinnedCollections(live, coordinate, isKind, wrap) {
|
|
|
279
286
|
if (cached !== void 0) return cached;
|
|
280
287
|
const wrapped = wrap(
|
|
281
288
|
kind,
|
|
282
|
-
live[kind],
|
|
289
|
+
requireDefined(live[kind]),
|
|
283
290
|
coordinate
|
|
284
291
|
);
|
|
285
292
|
cache.set(kind, wrapped);
|
|
@@ -306,15 +313,17 @@ function pinnedEdgeCollectionsFor(store, coordinate, wrap) {
|
|
|
306
313
|
}
|
|
307
314
|
function recordedNodeCollection(store, kind, live, coordinate) {
|
|
308
315
|
const reads = {
|
|
309
|
-
getById: (id) => store.recordedNodeGetById(kind, id, coordinate),
|
|
310
|
-
getByIds: (ids) => store.recordedNodeGetByIds(kind, ids, coordinate)
|
|
316
|
+
getById: (id) => storeRuntime(store).recordedNodeGetById(kind, id, coordinate),
|
|
317
|
+
getByIds: (ids) => storeRuntime(store).recordedNodeGetByIds(kind, ids, coordinate),
|
|
318
|
+
scan: (options) => storeRuntime(store).recordedNodeScan(kind, coordinate, options)
|
|
311
319
|
};
|
|
312
320
|
return recordedCollectionProxy(reads, live, coordinate, "node");
|
|
313
321
|
}
|
|
314
322
|
function recordedEdgeCollection(store, kind, live, coordinate) {
|
|
315
323
|
const reads = {
|
|
316
|
-
getById: (id) => store.recordedEdgeGetById(kind, id, coordinate),
|
|
317
|
-
getByIds: (ids) => store.recordedEdgeGetByIds(kind, ids, coordinate)
|
|
324
|
+
getById: (id) => storeRuntime(store).recordedEdgeGetById(kind, id, coordinate),
|
|
325
|
+
getByIds: (ids) => storeRuntime(store).recordedEdgeGetByIds(kind, ids, coordinate),
|
|
326
|
+
scan: (options) => storeRuntime(store).recordedEdgeScan(kind, coordinate, options)
|
|
318
327
|
};
|
|
319
328
|
return recordedCollectionProxy(reads, live, coordinate, "edge");
|
|
320
329
|
}
|
|
@@ -414,12 +423,12 @@ var CoordinatePinnedView = class {
|
|
|
414
423
|
* view's coordinate cannot be overridden on a per-query basis.
|
|
415
424
|
*/
|
|
416
425
|
query() {
|
|
417
|
-
return this.store.sealedQuery(this.coordinate);
|
|
426
|
+
return storeRuntime(this.store).sealedQuery(this.coordinate);
|
|
418
427
|
}
|
|
419
428
|
internalAlgorithms() {
|
|
420
|
-
this.#internalAlgorithms ??=
|
|
421
|
-
this.
|
|
422
|
-
);
|
|
429
|
+
this.#internalAlgorithms ??= storeRuntime(
|
|
430
|
+
this.store
|
|
431
|
+
).algorithmsAtCoordinate(this.coordinate);
|
|
423
432
|
return this.#internalAlgorithms;
|
|
424
433
|
}
|
|
425
434
|
/** Graph algorithms pinned to this view's immutable temporal coordinate. */
|
|
@@ -431,7 +440,10 @@ var CoordinatePinnedView = class {
|
|
|
431
440
|
canReach: (from, to, options) => this.canReach(from, to, options),
|
|
432
441
|
neighbors: (node, options) => this.neighbors(node, options),
|
|
433
442
|
degree: (node, options) => this.degree(node, options),
|
|
434
|
-
|
|
443
|
+
labelPropagation: (options) => this.labelPropagation(options),
|
|
444
|
+
weaklyConnectedComponents: (options) => this.weaklyConnectedComponents(options),
|
|
445
|
+
pageRank: (options) => this.pageRank(options),
|
|
446
|
+
personalizedPageRank: (options) => this.personalizedPageRank(options)
|
|
435
447
|
});
|
|
436
448
|
return this.#algorithmFacade;
|
|
437
449
|
}
|
|
@@ -441,7 +453,10 @@ var CoordinatePinnedView = class {
|
|
|
441
453
|
...options,
|
|
442
454
|
...withCoordinate(this.coordinate)
|
|
443
455
|
};
|
|
444
|
-
return this.store.subgraphAtCoordinate(
|
|
456
|
+
return storeRuntime(this.store).subgraphAtCoordinate(
|
|
457
|
+
rootId,
|
|
458
|
+
internalOptions
|
|
459
|
+
);
|
|
445
460
|
}
|
|
446
461
|
/** Shortest path between two nodes at this view's pinned coordinate. */
|
|
447
462
|
shortestPath(from, to, options) {
|
|
@@ -485,6 +500,13 @@ var CoordinatePinnedView = class {
|
|
|
485
500
|
...withCoordinate(this.coordinate)
|
|
486
501
|
});
|
|
487
502
|
}
|
|
503
|
+
/** Deterministic label-propagation memberships at this view's coordinate. */
|
|
504
|
+
labelPropagation(options) {
|
|
505
|
+
return this.internalAlgorithms().labelPropagation({
|
|
506
|
+
...options,
|
|
507
|
+
...withCoordinate(this.coordinate)
|
|
508
|
+
});
|
|
509
|
+
}
|
|
488
510
|
/** Exact WCC memberships at this view's pinned coordinate. */
|
|
489
511
|
weaklyConnectedComponents(options) {
|
|
490
512
|
return this.internalAlgorithms().weaklyConnectedComponents({
|
|
@@ -492,6 +514,20 @@ var CoordinatePinnedView = class {
|
|
|
492
514
|
...withCoordinate(this.coordinate)
|
|
493
515
|
});
|
|
494
516
|
}
|
|
517
|
+
/** Global PageRank scores at this view's pinned coordinate. */
|
|
518
|
+
pageRank(options) {
|
|
519
|
+
return this.internalAlgorithms().pageRank({
|
|
520
|
+
...options,
|
|
521
|
+
...withCoordinate(this.coordinate)
|
|
522
|
+
});
|
|
523
|
+
}
|
|
524
|
+
/** Personalized PageRank scores at this view's pinned coordinate. */
|
|
525
|
+
personalizedPageRank(options) {
|
|
526
|
+
return this.internalAlgorithms().personalizedPageRank({
|
|
527
|
+
...options,
|
|
528
|
+
...withCoordinate(this.coordinate)
|
|
529
|
+
});
|
|
530
|
+
}
|
|
495
531
|
};
|
|
496
532
|
var StoreView = class extends CoordinatePinnedView {
|
|
497
533
|
#nodes;
|
|
@@ -585,7 +621,7 @@ var RecordedStoreView = class extends CoordinatePinnedView {
|
|
|
585
621
|
}
|
|
586
622
|
return recorded.asOf;
|
|
587
623
|
}
|
|
588
|
-
/** Recorded-time node
|
|
624
|
+
/** Recorded-time node reconstructing-read collections. */
|
|
589
625
|
get nodes() {
|
|
590
626
|
this.#nodes ??= pinnedNodeCollectionsFor(
|
|
591
627
|
this.store,
|
|
@@ -594,7 +630,7 @@ var RecordedStoreView = class extends CoordinatePinnedView {
|
|
|
594
630
|
);
|
|
595
631
|
return this.#nodes;
|
|
596
632
|
}
|
|
597
|
-
/** Recorded-time edge
|
|
633
|
+
/** Recorded-time edge reconstructing-read collections. */
|
|
598
634
|
get edges() {
|
|
599
635
|
this.#edges ??= pinnedEdgeCollectionsFor(
|
|
600
636
|
this.store,
|
|
@@ -788,6 +824,8 @@ function inspectSetOperationPlan(logicalPlan) {
|
|
|
788
824
|
sortNode
|
|
789
825
|
};
|
|
790
826
|
}
|
|
827
|
+
|
|
828
|
+
// src/query/compiler/emitter/recursive.ts
|
|
791
829
|
function assertRecursiveEmitterClauseAlignment(logicalPlan, input) {
|
|
792
830
|
const planShape = inspectRecursiveProjectPlan(logicalPlan);
|
|
793
831
|
if (planShape.hasSort && input.orderBy === void 0) {
|
|
@@ -832,6 +870,8 @@ function emitRecursiveQuerySql(input) {
|
|
|
832
870
|
}
|
|
833
871
|
return sql.join(parts, sql` `);
|
|
834
872
|
}
|
|
873
|
+
|
|
874
|
+
// src/query/compiler/emitter/set-operations.ts
|
|
835
875
|
function assertSetOperationEmitterClauseAlignment(logicalPlan, suffixClauses) {
|
|
836
876
|
const shape = inspectSetOperationPlan(logicalPlan);
|
|
837
877
|
const hasSuffixClauses = suffixClauses !== void 0 && suffixClauses.length > 0;
|
|
@@ -874,6 +914,8 @@ function emitSetOperationQuerySql(input) {
|
|
|
874
914
|
}
|
|
875
915
|
return sql.join(parts, sql` `);
|
|
876
916
|
}
|
|
917
|
+
|
|
918
|
+
// src/query/compiler/emitter/standard.ts
|
|
877
919
|
function assertStandardEmitterClauseAlignment(logicalPlan, input) {
|
|
878
920
|
const planShape = inspectStandardProjectPlan(logicalPlan);
|
|
879
921
|
if (input.groupBy !== void 0 && !planShape.hasAggregate) {
|
|
@@ -942,7 +984,7 @@ function truncateToBytes(value, maxBytes) {
|
|
|
942
984
|
const encoded = TEXT_ENCODER.encode(value);
|
|
943
985
|
if (encoded.byteLength <= maxBytes) return value;
|
|
944
986
|
let end = maxBytes;
|
|
945
|
-
while (end > 0 && encoded[end] >= 128 && encoded[end] < 192) {
|
|
987
|
+
while (end > 0 && requireDefined(encoded[end]) >= 128 && requireDefined(encoded[end]) < 192) {
|
|
946
988
|
end--;
|
|
947
989
|
}
|
|
948
990
|
return new TextDecoder().decode(encoded.slice(0, end));
|
|
@@ -1009,6 +1051,94 @@ function compileSelectivePropsExtraction(field2, column, dialect) {
|
|
|
1009
1051
|
});
|
|
1010
1052
|
}
|
|
1011
1053
|
|
|
1054
|
+
// src/query/compiler/utils.ts
|
|
1055
|
+
var NODE_COLUMNS = [
|
|
1056
|
+
"id",
|
|
1057
|
+
"kind",
|
|
1058
|
+
"props",
|
|
1059
|
+
"version",
|
|
1060
|
+
"valid_from",
|
|
1061
|
+
"valid_to",
|
|
1062
|
+
"created_at",
|
|
1063
|
+
"updated_at",
|
|
1064
|
+
"deleted_at"
|
|
1065
|
+
];
|
|
1066
|
+
var EDGE_COLUMNS = [
|
|
1067
|
+
"id",
|
|
1068
|
+
"kind",
|
|
1069
|
+
"from_id",
|
|
1070
|
+
"to_id",
|
|
1071
|
+
"props",
|
|
1072
|
+
"valid_from",
|
|
1073
|
+
"valid_to",
|
|
1074
|
+
"created_at",
|
|
1075
|
+
"updated_at",
|
|
1076
|
+
"deleted_at"
|
|
1077
|
+
];
|
|
1078
|
+
var EMPTY_REQUIRED_COLUMNS = /* @__PURE__ */ new Set();
|
|
1079
|
+
function quoteIdentifier(identifier) {
|
|
1080
|
+
return sql.identifier(identifier);
|
|
1081
|
+
}
|
|
1082
|
+
function shouldProjectColumn(requiredColumns, column, alwaysRequiredColumns) {
|
|
1083
|
+
if (alwaysRequiredColumns?.has(column)) return true;
|
|
1084
|
+
if (requiredColumns === void 0) return true;
|
|
1085
|
+
return requiredColumns.has(column);
|
|
1086
|
+
}
|
|
1087
|
+
function addRequiredColumn(requiredColumnsByAlias, alias, column) {
|
|
1088
|
+
const existing = requiredColumnsByAlias.get(alias);
|
|
1089
|
+
if (existing) {
|
|
1090
|
+
existing.add(column);
|
|
1091
|
+
return;
|
|
1092
|
+
}
|
|
1093
|
+
requiredColumnsByAlias.set(alias, /* @__PURE__ */ new Set([column]));
|
|
1094
|
+
}
|
|
1095
|
+
function markFieldRefAsRequired(requiredColumnsByAlias, field2) {
|
|
1096
|
+
const column = field2.path[0];
|
|
1097
|
+
if (column === void 0) return;
|
|
1098
|
+
addRequiredColumn(requiredColumnsByAlias, field2.alias, column);
|
|
1099
|
+
}
|
|
1100
|
+
function mapSelectiveSystemFieldToColumn(field2) {
|
|
1101
|
+
if (field2 === "fromId") return "from_id";
|
|
1102
|
+
if (field2 === "toId") return "to_id";
|
|
1103
|
+
if (field2.startsWith("meta.")) {
|
|
1104
|
+
return field2.slice(5).replaceAll(/([A-Z])/g, "_$1").toLowerCase();
|
|
1105
|
+
}
|
|
1106
|
+
return field2;
|
|
1107
|
+
}
|
|
1108
|
+
function markSelectiveFieldAsRequired(requiredColumnsByAlias, field2) {
|
|
1109
|
+
if (field2.isSystemField) {
|
|
1110
|
+
addRequiredColumn(
|
|
1111
|
+
requiredColumnsByAlias,
|
|
1112
|
+
field2.alias,
|
|
1113
|
+
mapSelectiveSystemFieldToColumn(field2.field)
|
|
1114
|
+
);
|
|
1115
|
+
return;
|
|
1116
|
+
}
|
|
1117
|
+
addRequiredColumn(requiredColumnsByAlias, field2.alias, "props");
|
|
1118
|
+
}
|
|
1119
|
+
function getTopLevelPropsFieldName(field2) {
|
|
1120
|
+
const pointer = getFieldPointer(field2);
|
|
1121
|
+
if (pointer === void 0) return void 0;
|
|
1122
|
+
const segments = parseJsonPointer(pointer);
|
|
1123
|
+
return segments.length === 1 ? segments[0] : void 0;
|
|
1124
|
+
}
|
|
1125
|
+
function findSelectivePropsFieldForFieldRef(selectiveFields, field2) {
|
|
1126
|
+
if (selectiveFields === void 0 || selectiveFields.length === 0) {
|
|
1127
|
+
return void 0;
|
|
1128
|
+
}
|
|
1129
|
+
const propsFieldName = getTopLevelPropsFieldName(field2);
|
|
1130
|
+
if (propsFieldName === void 0) return void 0;
|
|
1131
|
+
return selectiveFields.find(
|
|
1132
|
+
(selectiveField) => !selectiveField.isSystemField && selectiveField.alias === field2.alias && selectiveField.field === propsFieldName
|
|
1133
|
+
);
|
|
1134
|
+
}
|
|
1135
|
+
function isIdFieldRef(field2) {
|
|
1136
|
+
return field2.path.length === 1 && field2.path[0] === "id" && field2.jsonPointer === void 0;
|
|
1137
|
+
}
|
|
1138
|
+
function isAggregateExpr(source) {
|
|
1139
|
+
return "__type" in source && source.__type === "aggregate";
|
|
1140
|
+
}
|
|
1141
|
+
|
|
1012
1142
|
// src/query/compiler/emitter/standard-builders.ts
|
|
1013
1143
|
function compileColumnReference(tableAlias, column) {
|
|
1014
1144
|
if (tableAlias === void 0) {
|
|
@@ -1137,7 +1267,7 @@ function buildStandardTraversalCte(input) {
|
|
|
1137
1267
|
traversalIndex,
|
|
1138
1268
|
traversalLimit
|
|
1139
1269
|
} = input;
|
|
1140
|
-
const traversal = ast.traversals[traversalIndex];
|
|
1270
|
+
const traversal = requireDefined(ast.traversals[traversalIndex]);
|
|
1141
1271
|
const traversalLimitValue = traversalIndex === ast.traversals.length - 1 ? traversalLimit : void 0;
|
|
1142
1272
|
const previousNodeKinds = getNodeKindsForAlias(ast, traversal.joinFromAlias);
|
|
1143
1273
|
const directEdgeKinds = [...new Set(traversal.edgeKinds)];
|
|
@@ -1540,7 +1670,10 @@ function buildLateMaterializedTopKCte(input) {
|
|
|
1540
1670
|
limit: input.limit,
|
|
1541
1671
|
offset: input.offset
|
|
1542
1672
|
});
|
|
1543
|
-
const parts = [
|
|
1673
|
+
const parts = [
|
|
1674
|
+
sql`SELECT ${sql.join(columns, sql`, `)}`,
|
|
1675
|
+
fromClause
|
|
1676
|
+
];
|
|
1544
1677
|
if (innerOrderBy !== void 0) parts.push(innerOrderBy);
|
|
1545
1678
|
if (limitOffset !== void 0) parts.push(limitOffset);
|
|
1546
1679
|
return sql`${sql.raw(LATE_MAT_TOPK_CTE_ALIAS)} AS (${sql.join(parts, sql` `)})`;
|
|
@@ -2369,7 +2502,7 @@ function lowerSetOperationToLogicalPlanNode(op, graphId, dialect, nextPlanNodeId
|
|
|
2369
2502
|
if (op.limit !== void 0 && op.offset !== void 0) {
|
|
2370
2503
|
currentNode = { ...limitOffsetBase, limit: op.limit, offset: op.offset };
|
|
2371
2504
|
} else if (op.limit === void 0) {
|
|
2372
|
-
currentNode = { ...limitOffsetBase, offset: op.offset };
|
|
2505
|
+
currentNode = { ...limitOffsetBase, offset: requireDefined(op.offset) };
|
|
2373
2506
|
} else {
|
|
2374
2507
|
currentNode = { ...limitOffsetBase, limit: op.limit };
|
|
2375
2508
|
}
|
|
@@ -2995,6 +3128,8 @@ function decodeByValueType(value, valueType) {
|
|
|
2995
3128
|
}
|
|
2996
3129
|
}
|
|
2997
3130
|
}
|
|
3131
|
+
|
|
3132
|
+
// src/store/recursive-cte.ts
|
|
2998
3133
|
function buildReachableCte(options) {
|
|
2999
3134
|
const trackPath = options.cyclePolicy === "prevent" || options.includePath;
|
|
3000
3135
|
const edgeKindFilter = compileKindFilter(
|
|
@@ -3196,26 +3331,35 @@ async function executeSubgraph(params) {
|
|
|
3196
3331
|
});
|
|
3197
3332
|
const includedIdsCte = buildIncludedIdsCte(ctx);
|
|
3198
3333
|
let membership;
|
|
3199
|
-
|
|
3200
|
-
|
|
3201
|
-
|
|
3202
|
-
|
|
3203
|
-
|
|
3204
|
-
|
|
3205
|
-
|
|
3206
|
-
|
|
3207
|
-
|
|
3208
|
-
|
|
3209
|
-
|
|
3210
|
-
|
|
3211
|
-
|
|
3212
|
-
|
|
3213
|
-
|
|
3214
|
-
|
|
3215
|
-
|
|
3216
|
-
|
|
3217
|
-
|
|
3218
|
-
|
|
3334
|
+
const dialect = ctx.dialect.name;
|
|
3335
|
+
switch (dialect) {
|
|
3336
|
+
case "postgres": {
|
|
3337
|
+
const includedIds = await fetchIncludedIds(
|
|
3338
|
+
ctx,
|
|
3339
|
+
reachableCte,
|
|
3340
|
+
includedIdsCte
|
|
3341
|
+
);
|
|
3342
|
+
const idsArray = textArrayParam(includedIds);
|
|
3343
|
+
membership = {
|
|
3344
|
+
prefix: sql``,
|
|
3345
|
+
idFilter: (column) => sql`EXISTS (SELECT 1 FROM unnest(${idsArray}) AS tg_included(id) WHERE tg_included.id = ${column})`,
|
|
3346
|
+
parameterDependentPlan: true
|
|
3347
|
+
};
|
|
3348
|
+
break;
|
|
3349
|
+
}
|
|
3350
|
+
case "sqlite": {
|
|
3351
|
+
membership = {
|
|
3352
|
+
prefix: sql`${reachableCte}${includedIdsCte} `,
|
|
3353
|
+
// SQLite: `column IN (subquery)` evaluates via a transient index —
|
|
3354
|
+
// optimal as-is. (Postgres takes the parameterized text[] form above.)
|
|
3355
|
+
idFilter: (column) => sql`${column} IN (SELECT id FROM included_ids)`,
|
|
3356
|
+
parameterDependentPlan: false
|
|
3357
|
+
};
|
|
3358
|
+
break;
|
|
3359
|
+
}
|
|
3360
|
+
default: {
|
|
3361
|
+
throw new Error(`Unsupported SQL dialect: ${String(dialect)}`);
|
|
3362
|
+
}
|
|
3219
3363
|
}
|
|
3220
3364
|
const [nodeRows, edgeRows] = await Promise.all([
|
|
3221
3365
|
fetchSubgraphNodes(ctx, membership, nodeProjectionPlan),
|
|
@@ -3473,7 +3617,7 @@ function mapSubgraphNodeRow(row, projectionPlan) {
|
|
|
3473
3617
|
id: row.id
|
|
3474
3618
|
};
|
|
3475
3619
|
if (kindPlan.includeMeta) {
|
|
3476
|
-
projectedNode
|
|
3620
|
+
projectedNode["meta"] = rowToNodeMeta(row);
|
|
3477
3621
|
}
|
|
3478
3622
|
applyProjectedFields(projectedNode, row, kindPlan);
|
|
3479
3623
|
return projectedNode;
|
|
@@ -3495,11 +3639,13 @@ function mapSubgraphEdgeRow(row, projectionPlan) {
|
|
|
3495
3639
|
toId: row.to_id
|
|
3496
3640
|
};
|
|
3497
3641
|
if (kindPlan.includeMeta) {
|
|
3498
|
-
projectedEdge
|
|
3642
|
+
projectedEdge["meta"] = rowToEdgeMeta(row);
|
|
3499
3643
|
}
|
|
3500
3644
|
applyProjectedFields(projectedEdge, row, kindPlan);
|
|
3501
3645
|
return projectedEdge;
|
|
3502
3646
|
}
|
|
3647
|
+
|
|
3648
|
+
// src/query/compiler/set-operations.ts
|
|
3503
3649
|
var OPERATOR_MAP = {
|
|
3504
3650
|
union: "UNION",
|
|
3505
3651
|
unionAll: "UNION ALL",
|
|
@@ -4114,7 +4260,7 @@ function tryLowerSingleHopRecursiveTraversal(ast) {
|
|
|
4114
4260
|
if (ast.traversals.length !== 1) {
|
|
4115
4261
|
return void 0;
|
|
4116
4262
|
}
|
|
4117
|
-
const traversal = ast.traversals[0];
|
|
4263
|
+
const traversal = requireDefined(ast.traversals[0]);
|
|
4118
4264
|
const variableLength = traversal.variableLength;
|
|
4119
4265
|
if (!variableLength) {
|
|
4120
4266
|
return void 0;
|
|
@@ -4210,11 +4356,11 @@ function resolveCountAggregateFastPath(ast) {
|
|
|
4210
4356
|
if (ast.orderBy?.some((orderSpec) => orderSpec.field.alias !== ast.start.alias)) {
|
|
4211
4357
|
return void 0;
|
|
4212
4358
|
}
|
|
4213
|
-
const traversal = ast.traversals[0];
|
|
4359
|
+
const traversal = requireDefined(ast.traversals[0]);
|
|
4214
4360
|
if ((traversal.inverseEdgeKinds?.length ?? 0) > 0) {
|
|
4215
4361
|
return void 0;
|
|
4216
4362
|
}
|
|
4217
|
-
const groupField = ast.groupBy.fields[0];
|
|
4363
|
+
const groupField = requireDefined(ast.groupBy.fields[0]);
|
|
4218
4364
|
if (groupField.alias !== ast.start.alias || !isIdFieldRef(groupField)) {
|
|
4219
4365
|
return void 0;
|
|
4220
4366
|
}
|
|
@@ -4981,14 +5127,14 @@ function decodeCursor(cursor) {
|
|
|
4981
5127
|
}
|
|
4982
5128
|
const json = atob(base64);
|
|
4983
5129
|
const raw = JSON.parse(json);
|
|
4984
|
-
if (typeof raw
|
|
5130
|
+
if (typeof raw["v"] !== "number" || raw["v"] > CURSOR_VERSION) {
|
|
4985
5131
|
throw new ValidationError(
|
|
4986
|
-
`Unsupported cursor version: ${String(raw
|
|
5132
|
+
`Unsupported cursor version: ${String(raw["v"])}. Maximum supported: ${CURSOR_VERSION}`,
|
|
4987
5133
|
{
|
|
4988
5134
|
issues: [
|
|
4989
5135
|
{
|
|
4990
5136
|
path: "cursor",
|
|
4991
|
-
message: `Cursor version ${String(raw
|
|
5137
|
+
message: `Cursor version ${String(raw["v"])} is not supported`
|
|
4992
5138
|
}
|
|
4993
5139
|
]
|
|
4994
5140
|
},
|
|
@@ -4997,17 +5143,20 @@ function decodeCursor(cursor) {
|
|
|
4997
5143
|
}
|
|
4998
5144
|
);
|
|
4999
5145
|
}
|
|
5000
|
-
if (raw
|
|
5001
|
-
throw new ValidationError(
|
|
5002
|
-
|
|
5003
|
-
|
|
5004
|
-
|
|
5005
|
-
|
|
5006
|
-
|
|
5007
|
-
|
|
5008
|
-
|
|
5146
|
+
if (raw["d"] !== "f" && raw["d"] !== "b") {
|
|
5147
|
+
throw new ValidationError(
|
|
5148
|
+
`Invalid cursor direction: ${String(raw["d"])}`,
|
|
5149
|
+
{
|
|
5150
|
+
issues: [
|
|
5151
|
+
{
|
|
5152
|
+
path: "cursor",
|
|
5153
|
+
message: `Direction must be "f" (forward) or "b" (backward)`
|
|
5154
|
+
}
|
|
5155
|
+
]
|
|
5156
|
+
}
|
|
5157
|
+
);
|
|
5009
5158
|
}
|
|
5010
|
-
if (!Array.isArray(raw
|
|
5159
|
+
if (!Array.isArray(raw["vals"]) || !Array.isArray(raw["cols"])) {
|
|
5011
5160
|
throw new ValidationError("Invalid cursor structure", {
|
|
5012
5161
|
issues: [
|
|
5013
5162
|
{
|
|
@@ -5017,21 +5166,21 @@ function decodeCursor(cursor) {
|
|
|
5017
5166
|
]
|
|
5018
5167
|
});
|
|
5019
5168
|
}
|
|
5020
|
-
if (raw
|
|
5169
|
+
if (raw["vals"].length !== raw["cols"].length) {
|
|
5021
5170
|
throw new ValidationError("Cursor column count mismatch", {
|
|
5022
5171
|
issues: [
|
|
5023
5172
|
{
|
|
5024
5173
|
path: "cursor",
|
|
5025
|
-
message: `vals (${raw
|
|
5174
|
+
message: `vals (${raw["vals"].length}) and cols (${raw["cols"].length}) must have same length`
|
|
5026
5175
|
}
|
|
5027
5176
|
]
|
|
5028
5177
|
});
|
|
5029
5178
|
}
|
|
5030
5179
|
return {
|
|
5031
|
-
v: raw
|
|
5032
|
-
d: raw
|
|
5033
|
-
vals: raw
|
|
5034
|
-
cols: raw
|
|
5180
|
+
v: raw["v"],
|
|
5181
|
+
d: raw["d"],
|
|
5182
|
+
vals: raw["vals"],
|
|
5183
|
+
cols: raw["cols"]
|
|
5035
5184
|
};
|
|
5036
5185
|
} catch (error) {
|
|
5037
5186
|
if (error instanceof ValidationError) {
|
|
@@ -5138,11 +5287,11 @@ function buildCursorPredicate(cursorData, orderBy, direction, targetAlias) {
|
|
|
5138
5287
|
for (let index = 0; index < orderBy.length; index++) {
|
|
5139
5288
|
const andConditions = [];
|
|
5140
5289
|
for (let index_ = 0; index_ < index; index_++) {
|
|
5141
|
-
const spec = orderBy[index_];
|
|
5290
|
+
const spec = requireDefined(orderBy[index_]);
|
|
5142
5291
|
const value = values[index_];
|
|
5143
5292
|
andConditions.push(buildEqualityPredicate(spec.field, value));
|
|
5144
5293
|
}
|
|
5145
|
-
const currentSpec = orderBy[index];
|
|
5294
|
+
const currentSpec = requireDefined(orderBy[index]);
|
|
5146
5295
|
const currentValue = values[index];
|
|
5147
5296
|
const isAsc = currentSpec.direction === "asc";
|
|
5148
5297
|
const isForward = direction === "forward";
|
|
@@ -5151,12 +5300,12 @@ function buildCursorPredicate(cursorData, orderBy, direction, targetAlias) {
|
|
|
5151
5300
|
buildComparisonPredicate(currentSpec.field, op, currentValue)
|
|
5152
5301
|
);
|
|
5153
5302
|
if (andConditions.length === 1) {
|
|
5154
|
-
orConditions.push(andConditions[0]);
|
|
5303
|
+
orConditions.push(requireDefined(andConditions[0]));
|
|
5155
5304
|
} else {
|
|
5156
5305
|
orConditions.push({ __type: "and", predicates: andConditions });
|
|
5157
5306
|
}
|
|
5158
5307
|
}
|
|
5159
|
-
const expression = orConditions.length === 1 ? orConditions[0] : { __type: "or", predicates: orConditions };
|
|
5308
|
+
const expression = orConditions.length === 1 ? requireDefined(orConditions[0]) : { __type: "or", predicates: orConditions };
|
|
5160
5309
|
return {
|
|
5161
5310
|
targetAlias,
|
|
5162
5311
|
expression
|
|
@@ -5191,8 +5340,8 @@ function buildPaginatedResult(data, orderedRows, orderBy, limit, hasMore, isBack
|
|
|
5191
5340
|
let nextCursor;
|
|
5192
5341
|
let previousCursor;
|
|
5193
5342
|
if (orderedRows.length > 0) {
|
|
5194
|
-
const firstRow = orderedRows[0];
|
|
5195
|
-
const lastRow = orderedRows.at(-1);
|
|
5343
|
+
const firstRow = requireDefined(orderedRows[0]);
|
|
5344
|
+
const lastRow = requireDefined(orderedRows.at(-1));
|
|
5196
5345
|
const firstContext = buildContext(firstRow);
|
|
5197
5346
|
const lastContext = buildContext(lastRow);
|
|
5198
5347
|
previousCursor = buildCursorFromContext(firstContext, orderBy, "b");
|
|
@@ -5646,7 +5795,7 @@ function buildRequiredAliasValue(row, plan) {
|
|
|
5646
5795
|
for (const field2 of plan.metaFields) {
|
|
5647
5796
|
meta[field2.metaKey] = nullToUndefined(row[field2.outputName]);
|
|
5648
5797
|
}
|
|
5649
|
-
base
|
|
5798
|
+
base["meta"] = createGuardedProxy(meta, `${plan.alias}.meta`);
|
|
5650
5799
|
}
|
|
5651
5800
|
for (const field2 of plan.propsFields) {
|
|
5652
5801
|
const decoded = decodeSelectedValue(row[field2.outputName], field2.typeInfo);
|
|
@@ -5673,9 +5822,11 @@ function createGuardedProxy(target, debugPath) {
|
|
|
5673
5822
|
}
|
|
5674
5823
|
});
|
|
5675
5824
|
}
|
|
5825
|
+
|
|
5826
|
+
// src/query/builder/read-instant-template.ts
|
|
5676
5827
|
function templateHasReadInstant(template) {
|
|
5677
5828
|
return template.params.some(
|
|
5678
|
-
(parameter) => parameter
|
|
5829
|
+
(parameter) => isSqlPlaceholder(parameter) && parameter.name === CURRENT_READ_INSTANT_PLACEHOLDER
|
|
5679
5830
|
);
|
|
5680
5831
|
}
|
|
5681
5832
|
function queryAstNeedsCurrentReadInstant(ast) {
|
|
@@ -5709,10 +5860,9 @@ function buildQueryTemplate(ast, graphId, compileOptions, backend) {
|
|
|
5709
5860
|
});
|
|
5710
5861
|
}
|
|
5711
5862
|
function fillTemplateParams(params, bindings, dialect) {
|
|
5712
|
-
const adapter = getDialect(dialect);
|
|
5713
5863
|
let readInstant;
|
|
5714
5864
|
return params.map((parameter) => {
|
|
5715
|
-
if (!(parameter
|
|
5865
|
+
if (!isSqlPlaceholder(parameter)) return parameter;
|
|
5716
5866
|
const name = parameter.name;
|
|
5717
5867
|
if (name === CURRENT_READ_INSTANT_PLACEHOLDER) {
|
|
5718
5868
|
readInstant ??= nowIso();
|
|
@@ -5724,8 +5874,7 @@ function fillTemplateParams(params, bindings, dialect) {
|
|
|
5724
5874
|
parameterName: name
|
|
5725
5875
|
});
|
|
5726
5876
|
}
|
|
5727
|
-
|
|
5728
|
-
return adapter.bindValue(value);
|
|
5877
|
+
return bindSqlValue(value, dialect);
|
|
5729
5878
|
});
|
|
5730
5879
|
}
|
|
5731
5880
|
|
|
@@ -5981,7 +6130,7 @@ var PreparedQuery = class {
|
|
|
5981
6130
|
bindings,
|
|
5982
6131
|
this.#dialect
|
|
5983
6132
|
);
|
|
5984
|
-
const rawRows2 = await
|
|
6133
|
+
const rawRows2 = await executeRaw(
|
|
5985
6134
|
template.sql,
|
|
5986
6135
|
params
|
|
5987
6136
|
);
|
|
@@ -6703,10 +6852,10 @@ var ExecutableQuery = class _ExecutableQuery {
|
|
|
6703
6852
|
return this.#config.backend.compileSql(this.compile());
|
|
6704
6853
|
}
|
|
6705
6854
|
/**
|
|
6706
|
-
* Compiles the query to
|
|
6855
|
+
* Compiles the query to TypeGraph's database-independent SQL fragment.
|
|
6707
6856
|
*
|
|
6708
|
-
*
|
|
6709
|
-
*
|
|
6857
|
+
* Pass the result to a GraphBackend, or use toSQL() to render SQL text and
|
|
6858
|
+
* parameters for the configured dialect.
|
|
6710
6859
|
*/
|
|
6711
6860
|
compile() {
|
|
6712
6861
|
const ast = this.toAst();
|
|
@@ -6827,13 +6976,9 @@ var ExecutableQuery = class _ExecutableQuery {
|
|
|
6827
6976
|
const template = executeRaw === void 0 ? void 0 : this.#templateFor(ast, slot);
|
|
6828
6977
|
const rawRows = await this.#executeOnBackend(
|
|
6829
6978
|
backend,
|
|
6830
|
-
template !== void 0 && executeRaw !== void 0 ? (
|
|
6831
|
-
|
|
6832
|
-
|
|
6833
|
-
backend.executeRaw(
|
|
6834
|
-
template.sql,
|
|
6835
|
-
fillTemplateParams(template.params, {}, this.#dialect())
|
|
6836
|
-
)
|
|
6979
|
+
template !== void 0 && executeRaw !== void 0 ? executeRaw(
|
|
6980
|
+
template.sql,
|
|
6981
|
+
fillTemplateParams(template.params, {}, this.#dialect())
|
|
6837
6982
|
) : backend.execute(
|
|
6838
6983
|
compileQuery(ast, this.#config.graphId, this.#compileOptions())
|
|
6839
6984
|
),
|
|
@@ -7147,12 +7292,12 @@ var ExecutableQuery = class _ExecutableQuery {
|
|
|
7147
7292
|
if (orderedRows.length > 0) {
|
|
7148
7293
|
try {
|
|
7149
7294
|
previousCursor = this.#buildCursorFromSelectiveRow(
|
|
7150
|
-
orderedRows[0],
|
|
7295
|
+
requireDefined(orderedRows[0]),
|
|
7151
7296
|
selectiveFields,
|
|
7152
7297
|
"b"
|
|
7153
7298
|
);
|
|
7154
7299
|
nextCursor = this.#buildCursorFromSelectiveRow(
|
|
7155
|
-
orderedRows.at(-1),
|
|
7300
|
+
requireDefined(orderedRows.at(-1)),
|
|
7156
7301
|
selectiveFields,
|
|
7157
7302
|
"f"
|
|
7158
7303
|
);
|
|
@@ -7180,7 +7325,7 @@ var ExecutableQuery = class _ExecutableQuery {
|
|
|
7180
7325
|
for (const spec of this.#paginationOrderBy()) {
|
|
7181
7326
|
const field2 = spec.field;
|
|
7182
7327
|
if (field2.path.length === 1 && field2.path[0] !== "props" && field2.jsonPointer === void 0) {
|
|
7183
|
-
tracker.record(field2.alias, field2.path[0], true);
|
|
7328
|
+
tracker.record(field2.alias, requireDefined(field2.path[0]), true);
|
|
7184
7329
|
continue;
|
|
7185
7330
|
}
|
|
7186
7331
|
if (field2.path.length !== 1 || field2.path[0] !== "props") {
|
|
@@ -7193,7 +7338,7 @@ var ExecutableQuery = class _ExecutableQuery {
|
|
|
7193
7338
|
if (segments.length !== 1) {
|
|
7194
7339
|
return false;
|
|
7195
7340
|
}
|
|
7196
|
-
tracker.record(field2.alias, segments[0], false);
|
|
7341
|
+
tracker.record(field2.alias, requireDefined(segments[0]), false);
|
|
7197
7342
|
}
|
|
7198
7343
|
return true;
|
|
7199
7344
|
}
|
|
@@ -7226,7 +7371,7 @@ var ExecutableQuery = class _ExecutableQuery {
|
|
|
7226
7371
|
if (spec.field.path.length !== 1) {
|
|
7227
7372
|
throw new MissingSelectiveFieldError(alias, "orderBy");
|
|
7228
7373
|
}
|
|
7229
|
-
const fieldName = spec.field.path[0];
|
|
7374
|
+
const fieldName = requireDefined(spec.field.path[0]);
|
|
7230
7375
|
const outputName2 = outputNameByAliasField.get(
|
|
7231
7376
|
`${alias}\0${fieldName}`
|
|
7232
7377
|
);
|
|
@@ -7241,7 +7386,7 @@ var ExecutableQuery = class _ExecutableQuery {
|
|
|
7241
7386
|
if (segments.length === 0) {
|
|
7242
7387
|
throw new MissingSelectiveFieldError(alias, "orderBy");
|
|
7243
7388
|
}
|
|
7244
|
-
const topField = segments[0];
|
|
7389
|
+
const topField = requireDefined(segments[0]);
|
|
7245
7390
|
const outputName = outputNameByAliasField.get(
|
|
7246
7391
|
`${alias}\0${topField}`
|
|
7247
7392
|
);
|
|
@@ -7271,7 +7416,7 @@ var ExecutableQuery = class _ExecutableQuery {
|
|
|
7271
7416
|
}
|
|
7272
7417
|
let current = aliasObject;
|
|
7273
7418
|
for (let index = 0; index < segments.length - 1; index++) {
|
|
7274
|
-
const segment = segments[index];
|
|
7419
|
+
const segment = requireDefined(segments[index]);
|
|
7275
7420
|
const existing_ = current[segment];
|
|
7276
7421
|
if (typeof existing_ === "object" && existing_ !== null) {
|
|
7277
7422
|
current = existing_;
|
|
@@ -7281,7 +7426,7 @@ var ExecutableQuery = class _ExecutableQuery {
|
|
|
7281
7426
|
current = created;
|
|
7282
7427
|
}
|
|
7283
7428
|
}
|
|
7284
|
-
current[segments.at(-1)] = decoded;
|
|
7429
|
+
current[requireDefined(segments.at(-1))] = decoded;
|
|
7285
7430
|
}
|
|
7286
7431
|
return cursorContext;
|
|
7287
7432
|
}
|
|
@@ -7573,7 +7718,7 @@ var ExecutableAggregateQuery = class _ExecutableAggregateQuery {
|
|
|
7573
7718
|
return this.#config.backend.compileSql(this.compile());
|
|
7574
7719
|
}
|
|
7575
7720
|
/**
|
|
7576
|
-
* Compiles the query to
|
|
7721
|
+
* Compiles the query to TypeGraph's database-independent SQL fragment.
|
|
7577
7722
|
*/
|
|
7578
7723
|
compile() {
|
|
7579
7724
|
const ast = this.toAst();
|
|
@@ -7617,16 +7762,12 @@ var ExecutableAggregateQuery = class _ExecutableAggregateQuery {
|
|
|
7617
7762
|
}
|
|
7618
7763
|
const executeRaw = backend.executeRaw;
|
|
7619
7764
|
const template = executeRaw === void 0 ? void 0 : this.#resolveTemplate(ast);
|
|
7620
|
-
const rows = template !== void 0 && executeRaw !== void 0 ? (
|
|
7621
|
-
|
|
7622
|
-
|
|
7623
|
-
|
|
7624
|
-
|
|
7625
|
-
|
|
7626
|
-
template.params,
|
|
7627
|
-
{},
|
|
7628
|
-
this.#config.dialect ?? "sqlite"
|
|
7629
|
-
)
|
|
7765
|
+
const rows = template !== void 0 && executeRaw !== void 0 ? await executeRaw(
|
|
7766
|
+
template.sql,
|
|
7767
|
+
fillTemplateParams(
|
|
7768
|
+
template.params,
|
|
7769
|
+
{},
|
|
7770
|
+
this.#config.dialect ?? "sqlite"
|
|
7630
7771
|
)
|
|
7631
7772
|
) : await backend.execute(
|
|
7632
7773
|
compileQuery(ast, this.#config.graphId, this.#compileOptions())
|
|
@@ -8969,16 +9110,12 @@ var UnionableQuery = class _UnionableQuery {
|
|
|
8969
9110
|
return executeOnBackend(
|
|
8970
9111
|
backend,
|
|
8971
9112
|
recordedAsOfForComposableQuery(ast),
|
|
8972
|
-
template !== void 0 && executeRaw !== void 0 ? (
|
|
8973
|
-
|
|
8974
|
-
|
|
8975
|
-
|
|
8976
|
-
|
|
8977
|
-
|
|
8978
|
-
template.params,
|
|
8979
|
-
{},
|
|
8980
|
-
this.#config.dialect ?? "sqlite"
|
|
8981
|
-
)
|
|
9113
|
+
template !== void 0 && executeRaw !== void 0 ? executeRaw(
|
|
9114
|
+
template.sql,
|
|
9115
|
+
fillTemplateParams(
|
|
9116
|
+
template.params,
|
|
9117
|
+
{},
|
|
9118
|
+
this.#config.dialect ?? "sqlite"
|
|
8982
9119
|
)
|
|
8983
9120
|
) : backend.execute(
|
|
8984
9121
|
compileSetOperation2(
|
|
@@ -9441,6 +9578,8 @@ function processPage(schema, rows) {
|
|
|
9441
9578
|
}
|
|
9442
9579
|
return { toUpsert, toDelete, skipped, skippedIds };
|
|
9443
9580
|
}
|
|
9581
|
+
|
|
9582
|
+
// src/store/search.ts
|
|
9444
9583
|
var SEARCH_CANDIDATE_ALIAS = "_sc";
|
|
9445
9584
|
function buildKindCandidates(ctx, nodeKind, where) {
|
|
9446
9585
|
if (where === void 0) return void 0;
|
|
@@ -9550,7 +9689,7 @@ async function executeFulltextSearch(ctx, nodeKind, options) {
|
|
|
9550
9689
|
kinds.map(async (kind) => {
|
|
9551
9690
|
const candidates = buildKindCandidates(ctx, kind, options.where);
|
|
9552
9691
|
const language = effectiveFulltextLanguage(ctx, kind, options.language);
|
|
9553
|
-
const rows = await backend.fulltextSearch({
|
|
9692
|
+
const rows = await requireDefined(backend.fulltextSearch)({
|
|
9554
9693
|
graphId,
|
|
9555
9694
|
nodeKind: kind,
|
|
9556
9695
|
query: options.query,
|
|
@@ -9572,7 +9711,7 @@ async function executeFulltextSearch(ctx, nodeKind, options) {
|
|
|
9572
9711
|
}));
|
|
9573
9712
|
})
|
|
9574
9713
|
);
|
|
9575
|
-
const merged = singleKind ? perKindRows[0] : perKindRows.flat().toSorted(
|
|
9714
|
+
const merged = singleKind ? requireDefined(perKindRows[0]) : perKindRows.flat().toSorted(
|
|
9576
9715
|
(a, b) => b.score - a.score || compareCodePoints(a.kind, b.kind) || compareCodePoints(a.nodeId, b.nodeId)
|
|
9577
9716
|
).slice(offset, offset + options.limit);
|
|
9578
9717
|
if (merged.length === 0) return [];
|
|
@@ -9629,12 +9768,12 @@ async function executeVectorSearch(ctx, nodeKind, options) {
|
|
|
9629
9768
|
}
|
|
9630
9769
|
const offset = options.offset ?? 0;
|
|
9631
9770
|
const singleKind = searchKinds.length === 1;
|
|
9632
|
-
const metric = options.metric ?? searchKinds[0].slot.metric;
|
|
9771
|
+
const metric = options.metric ?? requireDefined(searchKinds[0]).slot.metric;
|
|
9633
9772
|
const perKindRows = await Promise.all(
|
|
9634
9773
|
searchKinds.map(
|
|
9635
9774
|
async ({ kind, slot }) => {
|
|
9636
9775
|
const candidates = buildKindCandidates(ctx, kind, options.where);
|
|
9637
|
-
const rows = await backend.vectorSearch({
|
|
9776
|
+
const rows = await requireDefined(backend.vectorSearch)({
|
|
9638
9777
|
graphId,
|
|
9639
9778
|
nodeKind: kind,
|
|
9640
9779
|
fieldPath: options.fieldPath,
|
|
@@ -9662,7 +9801,7 @@ async function executeVectorSearch(ctx, nodeKind, options) {
|
|
|
9662
9801
|
}
|
|
9663
9802
|
)
|
|
9664
9803
|
);
|
|
9665
|
-
const merged = singleKind ? perKindRows[0] : mergeVectorRows(perKindRows, metric).slice(
|
|
9804
|
+
const merged = singleKind ? requireDefined(perKindRows[0]) : mergeVectorRows(perKindRows, metric).slice(
|
|
9666
9805
|
offset,
|
|
9667
9806
|
offset + options.limit
|
|
9668
9807
|
);
|
|
@@ -9771,7 +9910,7 @@ async function executeHybridSearch(ctx, nodeKind, options) {
|
|
|
9771
9910
|
"hybridSearch.vector.minScore"
|
|
9772
9911
|
);
|
|
9773
9912
|
}
|
|
9774
|
-
const vectorMetric = options.vector.metric ?? vectorKinds[0].slot.metric;
|
|
9913
|
+
const vectorMetric = options.vector.metric ?? requireDefined(vectorKinds[0]).slot.metric;
|
|
9775
9914
|
const candidatesByKind = /* @__PURE__ */ new Map();
|
|
9776
9915
|
for (const kind of fulltextKinds) {
|
|
9777
9916
|
candidatesByKind.set(kind, buildKindCandidates(ctx, kind, options.where));
|
|
@@ -9781,9 +9920,9 @@ async function executeHybridSearch(ctx, nodeKind, options) {
|
|
|
9781
9920
|
candidatesByKind.set(kind, buildKindCandidates(ctx, kind, options.where));
|
|
9782
9921
|
}
|
|
9783
9922
|
}
|
|
9784
|
-
if (backend.hybridSearch !== void 0 && fulltextKinds.length === 1 && vectorKinds.length === 1 && fulltextKinds[0] === vectorKinds[0].kind) {
|
|
9923
|
+
if (backend.hybridSearch !== void 0 && fulltextKinds.length === 1 && vectorKinds.length === 1 && fulltextKinds[0] === requireDefined(vectorKinds[0]).kind) {
|
|
9785
9924
|
const kind = fulltextKinds[0];
|
|
9786
|
-
const { slot } = vectorKinds[0];
|
|
9925
|
+
const { slot } = requireDefined(vectorKinds[0]);
|
|
9787
9926
|
const candidates = candidatesByKind.get(kind);
|
|
9788
9927
|
const hybridFulltextLanguage = effectiveFulltextLanguage(
|
|
9789
9928
|
ctx,
|
|
@@ -9844,7 +9983,7 @@ async function executeHybridSearch(ctx, nodeKind, options) {
|
|
|
9844
9983
|
vectorKinds.map(
|
|
9845
9984
|
async ({ kind, slot }) => {
|
|
9846
9985
|
const candidates = candidatesByKind.get(kind);
|
|
9847
|
-
const rows = await backend.vectorSearch({
|
|
9986
|
+
const rows = await requireDefined(backend.vectorSearch)({
|
|
9848
9987
|
graphId,
|
|
9849
9988
|
nodeKind: kind,
|
|
9850
9989
|
fieldPath: options.vector.fieldPath,
|
|
@@ -9874,7 +10013,7 @@ async function executeHybridSearch(ctx, nodeKind, options) {
|
|
|
9874
10013
|
kind,
|
|
9875
10014
|
options.fulltext.language
|
|
9876
10015
|
);
|
|
9877
|
-
const rows = await backend.fulltextSearch({
|
|
10016
|
+
const rows = await requireDefined(backend.fulltextSearch)({
|
|
9878
10017
|
graphId,
|
|
9879
10018
|
nodeKind: kind,
|
|
9880
10019
|
query: options.fulltext.query,
|
|
@@ -10314,7 +10453,7 @@ function classifyProperties(kind, existing, next, recorders) {
|
|
|
10314
10453
|
}
|
|
10315
10454
|
for (const name of nextNames) {
|
|
10316
10455
|
if (!existingNames.has(name)) {
|
|
10317
|
-
const property = next[name];
|
|
10456
|
+
const property = requireDefined(next[name]);
|
|
10318
10457
|
if (property.optional === true) continue;
|
|
10319
10458
|
recorders.recordRequireEmpty({
|
|
10320
10459
|
kind,
|
|
@@ -10325,7 +10464,13 @@ function classifyProperties(kind, existing, next, recorders) {
|
|
|
10325
10464
|
}
|
|
10326
10465
|
for (const name of existingNames) {
|
|
10327
10466
|
if (!nextNames.has(name)) continue;
|
|
10328
|
-
classifyProperty(
|
|
10467
|
+
classifyProperty(
|
|
10468
|
+
kind,
|
|
10469
|
+
name,
|
|
10470
|
+
requireDefined(existing[name]),
|
|
10471
|
+
requireDefined(next[name]),
|
|
10472
|
+
recorders
|
|
10473
|
+
);
|
|
10329
10474
|
}
|
|
10330
10475
|
}
|
|
10331
10476
|
function classifyProperty(kind, field2, existing, next, recorders) {
|
|
@@ -10816,6 +10961,33 @@ function assertEdgeKinds(edges) {
|
|
|
10816
10961
|
);
|
|
10817
10962
|
}
|
|
10818
10963
|
}
|
|
10964
|
+
function compileNodeKindSeedFilter(nodeKinds) {
|
|
10965
|
+
if (nodeKinds === void 0) return sql`TRUE`;
|
|
10966
|
+
return compileKindFilter(sql.raw("n.kind"), nodeKinds);
|
|
10967
|
+
}
|
|
10968
|
+
function normalizeNodeKinds(nodeKinds) {
|
|
10969
|
+
if (nodeKinds === void 0) return void 0;
|
|
10970
|
+
return [...new Set(nodeKinds)].toSorted(
|
|
10971
|
+
(left, right) => compareCodePoints(left, right)
|
|
10972
|
+
);
|
|
10973
|
+
}
|
|
10974
|
+
function assertGraphAnalyticsSupported(ctx, algorithm, options = {}) {
|
|
10975
|
+
const graphAnalytics = ctx.backend.capabilities.graphAnalytics?.supported === true;
|
|
10976
|
+
const windowFunctions = ctx.backend.capabilities.windowFunctions;
|
|
10977
|
+
if (graphAnalytics && (options.requiresWindowFunctions !== true || windowFunctions)) {
|
|
10978
|
+
return;
|
|
10979
|
+
}
|
|
10980
|
+
throw new UnsupportedBackendCapabilityError(
|
|
10981
|
+
algorithm,
|
|
10982
|
+
"graphAnalytics",
|
|
10983
|
+
{
|
|
10984
|
+
dialect: ctx.backend.dialect,
|
|
10985
|
+
supported: graphAnalytics,
|
|
10986
|
+
...options.requiresWindowFunctions === true ? { windowFunctions } : {}
|
|
10987
|
+
},
|
|
10988
|
+
"Use a built-in transactional SQLite/PostgreSQL backend, or declare graphAnalytics support on a compatible custom backend."
|
|
10989
|
+
);
|
|
10990
|
+
}
|
|
10819
10991
|
|
|
10820
10992
|
// src/store/algorithms/degree.ts
|
|
10821
10993
|
async function executeDegree(ctx, nodeId, options = {}) {
|
|
@@ -10857,11 +11029,23 @@ function compileDirectionFilter(ctx, direction, nodeId, nodesTable) {
|
|
|
10857
11029
|
}
|
|
10858
11030
|
}
|
|
10859
11031
|
}
|
|
11032
|
+
|
|
11033
|
+
// src/store/algorithms/iterative-graph-operation.ts
|
|
10860
11034
|
function frontierIndexIdentifier(context) {
|
|
10861
11035
|
return sql.identifier(
|
|
10862
11036
|
`typegraph_iterative_${context.runId.replaceAll("-", "_")}_frontier`
|
|
10863
11037
|
);
|
|
10864
11038
|
}
|
|
11039
|
+
async function countWorkingTableRows(context) {
|
|
11040
|
+
const rows = await context.backend.execute(
|
|
11041
|
+
asCompiledRowsSql(sql`
|
|
11042
|
+
SELECT COUNT(*) AS count
|
|
11043
|
+
FROM ${context.workingTable}
|
|
11044
|
+
WHERE graph_id = ${context.graphId} AND run_id = ${context.runId}
|
|
11045
|
+
`)
|
|
11046
|
+
);
|
|
11047
|
+
return Number(rows[0]?.count ?? 0);
|
|
11048
|
+
}
|
|
10865
11049
|
var DEFAULT_MAX_BIND_PARAMETERS = 999;
|
|
10866
11050
|
var RESERVED_TEMPORAL_BIND_PARAMETERS_PER_BRANCH = 12;
|
|
10867
11051
|
var RESERVED_WEIGHT_BIND_PARAMETERS_PER_BRANCH = 4;
|
|
@@ -10912,71 +11096,69 @@ async function runIterativeGraphOperation(ctx, options, plan) {
|
|
|
10912
11096
|
{ dialect: ctx.backend.dialect }
|
|
10913
11097
|
);
|
|
10914
11098
|
}
|
|
10915
|
-
|
|
10916
|
-
|
|
10917
|
-
|
|
10918
|
-
|
|
10919
|
-
|
|
10920
|
-
|
|
11099
|
+
const transactionOptions = {
|
|
11100
|
+
isolationLevel: "repeatable_read",
|
|
11101
|
+
accessMode: "read_only",
|
|
11102
|
+
temporaryWrites: INTERNAL_TEMPORARY_WRITES
|
|
11103
|
+
};
|
|
11104
|
+
return ctx.backend.transaction(async (backend) => {
|
|
11105
|
+
const temporaryBackend = requireTemporaryStatements(backend);
|
|
11106
|
+
const runId = generateId();
|
|
11107
|
+
const workingTable = sql.identifier(
|
|
11108
|
+
`typegraph_iterative_${runId.replaceAll("-", "_")}`
|
|
11109
|
+
);
|
|
11110
|
+
const context = {
|
|
11111
|
+
operation: createOperation(ctx, options, temporaryBackend),
|
|
11112
|
+
backend: temporaryBackend,
|
|
11113
|
+
workingTable,
|
|
11114
|
+
graphId: ctx.graphId,
|
|
11115
|
+
runId,
|
|
11116
|
+
executeTemporary: async (query) => {
|
|
11117
|
+
await temporaryBackend.executeTemporaryStatement(
|
|
11118
|
+
asCompiledTemporaryStatementSql(query)
|
|
11119
|
+
);
|
|
11120
|
+
}
|
|
11121
|
+
};
|
|
11122
|
+
if (context.operation.workingMemory !== void 0) {
|
|
11123
|
+
const workingMemoryStatement = ctx.dialect.setTransactionWorkingMemory(
|
|
11124
|
+
context.operation.workingMemory
|
|
10921
11125
|
);
|
|
10922
|
-
|
|
10923
|
-
|
|
10924
|
-
|
|
10925
|
-
|
|
10926
|
-
|
|
10927
|
-
|
|
10928
|
-
|
|
10929
|
-
|
|
10930
|
-
|
|
11126
|
+
if (workingMemoryStatement !== void 0) {
|
|
11127
|
+
await context.executeTemporary(workingMemoryStatement);
|
|
11128
|
+
}
|
|
11129
|
+
}
|
|
11130
|
+
await context.executeTemporary(plan.createWorkingTable(context));
|
|
11131
|
+
let operationFailure;
|
|
11132
|
+
try {
|
|
11133
|
+
let state = await plan.initialize(context);
|
|
11134
|
+
let analyzedRowCount = await refreshWorkingTableStatistics(
|
|
11135
|
+
context,
|
|
11136
|
+
state.workingTableSize
|
|
11137
|
+
);
|
|
11138
|
+
for (let iteration = 1; iteration <= plan.maxIterations && !plan.hasConverged(state); iteration++) {
|
|
11139
|
+
state = await plan.runRound(context, state, iteration);
|
|
11140
|
+
if (iteration < plan.maxIterations && !plan.hasConverged(state)) {
|
|
11141
|
+
analyzedRowCount = await refreshWorkingTableStatistics(
|
|
11142
|
+
context,
|
|
11143
|
+
state.workingTableSize,
|
|
11144
|
+
analyzedRowCount
|
|
10931
11145
|
);
|
|
10932
11146
|
}
|
|
10933
|
-
};
|
|
10934
|
-
if (context.operation.workingMemory !== void 0) {
|
|
10935
|
-
const workingMemoryStatement = ctx.dialect.setTransactionWorkingMemory(
|
|
10936
|
-
context.operation.workingMemory
|
|
10937
|
-
);
|
|
10938
|
-
if (workingMemoryStatement !== void 0) {
|
|
10939
|
-
await context.executeTemporary(workingMemoryStatement);
|
|
10940
|
-
}
|
|
10941
11147
|
}
|
|
10942
|
-
|
|
10943
|
-
|
|
10944
|
-
|
|
10945
|
-
|
|
10946
|
-
let analyzedRowCount = await refreshWorkingTableStatistics(
|
|
10947
|
-
context,
|
|
10948
|
-
state.workingTableSize
|
|
11148
|
+
if (!plan.hasConverged(state)) {
|
|
11149
|
+
throw new GraphAlgorithmConvergenceError(
|
|
11150
|
+
plan.algorithm,
|
|
11151
|
+
plan.maxIterations
|
|
10949
11152
|
);
|
|
10950
|
-
for (let iteration = 1; iteration <= plan.maxIterations && !plan.hasConverged(state); iteration++) {
|
|
10951
|
-
state = await plan.runRound(context, state, iteration);
|
|
10952
|
-
if (iteration < plan.maxIterations && !plan.hasConverged(state)) {
|
|
10953
|
-
analyzedRowCount = await refreshWorkingTableStatistics(
|
|
10954
|
-
context,
|
|
10955
|
-
state.workingTableSize,
|
|
10956
|
-
analyzedRowCount
|
|
10957
|
-
);
|
|
10958
|
-
}
|
|
10959
|
-
}
|
|
10960
|
-
if (!plan.hasConverged(state)) {
|
|
10961
|
-
throw new GraphAlgorithmConvergenceError(
|
|
10962
|
-
plan.algorithm,
|
|
10963
|
-
plan.maxIterations
|
|
10964
|
-
);
|
|
10965
|
-
}
|
|
10966
|
-
return await plan.extractResult(context, state);
|
|
10967
|
-
} catch (error) {
|
|
10968
|
-
operationError = error;
|
|
10969
|
-
throw error;
|
|
10970
|
-
} finally {
|
|
10971
|
-
await dropWorkingTable(context, operationError);
|
|
10972
11153
|
}
|
|
10973
|
-
|
|
10974
|
-
{
|
|
10975
|
-
|
|
10976
|
-
|
|
10977
|
-
|
|
11154
|
+
return await plan.extractResult(context, state);
|
|
11155
|
+
} catch (error) {
|
|
11156
|
+
operationFailure = { error };
|
|
11157
|
+
throw error;
|
|
11158
|
+
} finally {
|
|
11159
|
+
await cleanupWorkingTables(context, plan.cleanup, operationFailure);
|
|
10978
11160
|
}
|
|
10979
|
-
);
|
|
11161
|
+
}, transactionOptions);
|
|
10980
11162
|
}
|
|
10981
11163
|
function shouldRefreshWorkingTableStatistics(workingTableSize, analyzedRowCount) {
|
|
10982
11164
|
if (workingTableSize < WORKING_TABLE_ANALYZE_MINIMUM_ROWS) return false;
|
|
@@ -10994,14 +11176,27 @@ async function refreshWorkingTableStatistics(context, workingTableSize, analyzed
|
|
|
10994
11176
|
await context.executeTemporary(statement);
|
|
10995
11177
|
return workingTableSize;
|
|
10996
11178
|
}
|
|
10997
|
-
async function dropWorkingTable(context,
|
|
11179
|
+
async function dropWorkingTable(context, hasPrimaryFailure) {
|
|
10998
11180
|
try {
|
|
10999
11181
|
await context.executeTemporary(
|
|
11000
11182
|
sql`DROP TABLE IF EXISTS ${context.workingTable}`
|
|
11001
11183
|
);
|
|
11002
11184
|
} catch (cleanupError) {
|
|
11003
|
-
if (
|
|
11185
|
+
if (!hasPrimaryFailure) throw cleanupError;
|
|
11186
|
+
}
|
|
11187
|
+
}
|
|
11188
|
+
async function cleanupWorkingTables(context, cleanup, operationFailure) {
|
|
11189
|
+
let cleanupFailure;
|
|
11190
|
+
try {
|
|
11191
|
+
await cleanup?.(context);
|
|
11192
|
+
} catch (error) {
|
|
11193
|
+
if (operationFailure === void 0) cleanupFailure = { error };
|
|
11004
11194
|
}
|
|
11195
|
+
await dropWorkingTable(
|
|
11196
|
+
context,
|
|
11197
|
+
operationFailure !== void 0 || cleanupFailure !== void 0
|
|
11198
|
+
);
|
|
11199
|
+
if (cleanupFailure !== void 0) throw cleanupFailure.error;
|
|
11005
11200
|
}
|
|
11006
11201
|
async function fetchVisibleWorkingNodes(operation, nodeIds) {
|
|
11007
11202
|
const nodes = /* @__PURE__ */ new Map();
|
|
@@ -11254,100 +11449,833 @@ function requireTemporaryStatements(backend) {
|
|
|
11254
11449
|
return backend;
|
|
11255
11450
|
}
|
|
11256
11451
|
|
|
11257
|
-
// src/store/algorithms/
|
|
11258
|
-
|
|
11259
|
-
|
|
11260
|
-
|
|
11261
|
-
|
|
11262
|
-
|
|
11263
|
-
}
|
|
11264
|
-
|
|
11265
|
-
|
|
11266
|
-
|
|
11267
|
-
|
|
11268
|
-
|
|
11269
|
-
|
|
11270
|
-
|
|
11271
|
-
|
|
11272
|
-
|
|
11273
|
-
|
|
11274
|
-
|
|
11275
|
-
|
|
11276
|
-
|
|
11277
|
-
|
|
11278
|
-
|
|
11279
|
-
|
|
11452
|
+
// src/store/algorithms/label-propagation.ts
|
|
11453
|
+
var DEFAULT_LABEL_PROPAGATION_MAX_ITERATIONS = 1e3;
|
|
11454
|
+
async function executeLabelPropagation(ctx, options) {
|
|
11455
|
+
assertEdgeKinds(options.edges);
|
|
11456
|
+
assertGraphAnalyticsSupported(ctx, "labelPropagation", {
|
|
11457
|
+
requiresWindowFunctions: true
|
|
11458
|
+
});
|
|
11459
|
+
const maxIterations = resolveMaxIterations(
|
|
11460
|
+
options.maxIterations,
|
|
11461
|
+
DEFAULT_LABEL_PROPAGATION_MAX_ITERATIONS,
|
|
11462
|
+
"labelPropagation"
|
|
11463
|
+
);
|
|
11464
|
+
const nodeKinds = normalizeNodeKinds(options.nodeKinds);
|
|
11465
|
+
const policy = {
|
|
11466
|
+
detector: createOscillationDetector(),
|
|
11467
|
+
maxIterations,
|
|
11468
|
+
onMaxIterations: options.onMaxIterations ?? "throw"
|
|
11469
|
+
};
|
|
11470
|
+
const traversalOptions = {
|
|
11471
|
+
edges: options.edges,
|
|
11472
|
+
direction: "both",
|
|
11473
|
+
...pickTemporalOptions(options),
|
|
11474
|
+
...options.workingMemory === void 0 ? {} : { workingMemory: options.workingMemory }
|
|
11475
|
+
};
|
|
11476
|
+
return runIterativeGraphOperation(ctx, traversalOptions, {
|
|
11477
|
+
algorithm: "labelPropagation",
|
|
11478
|
+
maxIterations,
|
|
11280
11479
|
createWorkingTable,
|
|
11281
|
-
|
|
11282
|
-
|
|
11283
|
-
return {
|
|
11284
|
-
depth: 0,
|
|
11285
|
-
frontierCount: seeded.length,
|
|
11286
|
-
workingTableSize: seeded.length
|
|
11287
|
-
};
|
|
11288
|
-
},
|
|
11289
|
-
async runRound(context, state) {
|
|
11290
|
-
const nextDepth = state.depth + 1;
|
|
11291
|
-
const frontierCount = await expandReachableWorkingTableRound(
|
|
11292
|
-
context,
|
|
11293
|
-
"forward",
|
|
11294
|
-
state.depth,
|
|
11295
|
-
nextDepth,
|
|
11296
|
-
context.operation.direction
|
|
11297
|
-
);
|
|
11298
|
-
return {
|
|
11299
|
-
depth: nextDepth,
|
|
11300
|
-
frontierCount,
|
|
11301
|
-
workingTableSize: state.workingTableSize + frontierCount
|
|
11302
|
-
};
|
|
11303
|
-
},
|
|
11480
|
+
initialize: (context) => initializeWorkingTables(context, nodeKinds),
|
|
11481
|
+
runRound: (context, state, iteration) => runLabelPropagationRound(context, state, iteration, policy),
|
|
11304
11482
|
hasConverged(state) {
|
|
11305
|
-
return state.
|
|
11483
|
+
return state.changedCount === 0 || state.completed;
|
|
11306
11484
|
},
|
|
11307
|
-
|
|
11308
|
-
|
|
11309
|
-
return rows.map((row) => ({
|
|
11310
|
-
id: row.node_id,
|
|
11311
|
-
kind: row.node_kind,
|
|
11312
|
-
depth: Number(row.depth)
|
|
11313
|
-
})).toSorted(
|
|
11314
|
-
(left, right) => left.depth - right.depth || compareNodeIdentity(left, right)
|
|
11315
|
-
);
|
|
11316
|
-
}
|
|
11485
|
+
extractResult: extractMemberships,
|
|
11486
|
+
cleanup: dropNeighborTable
|
|
11317
11487
|
});
|
|
11318
11488
|
}
|
|
11319
|
-
|
|
11320
|
-
|
|
11321
|
-
|
|
11322
|
-
|
|
11323
|
-
|
|
11324
|
-
|
|
11325
|
-
const
|
|
11326
|
-
const
|
|
11327
|
-
|
|
11328
|
-
|
|
11329
|
-
|
|
11330
|
-
|
|
11331
|
-
|
|
11332
|
-
|
|
11333
|
-
|
|
11334
|
-
|
|
11335
|
-
|
|
11336
|
-
|
|
11337
|
-
|
|
11338
|
-
|
|
11339
|
-
|
|
11340
|
-
const
|
|
11341
|
-
|
|
11342
|
-
|
|
11343
|
-
|
|
11344
|
-
|
|
11345
|
-
|
|
11346
|
-
|
|
11347
|
-
|
|
11348
|
-
|
|
11349
|
-
|
|
11350
|
-
|
|
11489
|
+
function createOscillationDetector() {
|
|
11490
|
+
const shadowLabels = /* @__PURE__ */ new Map();
|
|
11491
|
+
let previousRound;
|
|
11492
|
+
return {
|
|
11493
|
+
/** Records one applied round; true when the round inverts the previous. */
|
|
11494
|
+
observeRound(changedRows) {
|
|
11495
|
+
const round = /* @__PURE__ */ new Map();
|
|
11496
|
+
for (const row of changedRows) {
|
|
11497
|
+
const node = nodeIdentityKey({ id: row.node_id, kind: row.node_kind });
|
|
11498
|
+
const after = nodeIdentityKey({
|
|
11499
|
+
id: row.label_id,
|
|
11500
|
+
kind: row.label_kind
|
|
11501
|
+
});
|
|
11502
|
+
const before = shadowLabels.get(node) ?? node;
|
|
11503
|
+
round.set(node, { before, after });
|
|
11504
|
+
shadowLabels.set(node, after);
|
|
11505
|
+
}
|
|
11506
|
+
const priorRound = previousRound;
|
|
11507
|
+
previousRound = round;
|
|
11508
|
+
if (priorRound?.size !== round.size) return false;
|
|
11509
|
+
if (round.size === 0) return false;
|
|
11510
|
+
for (const [node, change] of round) {
|
|
11511
|
+
if (priorRound.get(node)?.before !== change.after) return false;
|
|
11512
|
+
}
|
|
11513
|
+
return true;
|
|
11514
|
+
}
|
|
11515
|
+
};
|
|
11516
|
+
}
|
|
11517
|
+
function createWorkingTable(context) {
|
|
11518
|
+
return sql`
|
|
11519
|
+
CREATE TEMP TABLE ${context.workingTable} (
|
|
11520
|
+
graph_id TEXT NOT NULL,
|
|
11521
|
+
run_id TEXT NOT NULL,
|
|
11522
|
+
node_id TEXT NOT NULL,
|
|
11523
|
+
node_kind TEXT NOT NULL,
|
|
11524
|
+
label_id TEXT NOT NULL,
|
|
11525
|
+
label_kind TEXT NOT NULL,
|
|
11526
|
+
next_label_id TEXT NOT NULL,
|
|
11527
|
+
next_label_kind TEXT NOT NULL,
|
|
11528
|
+
changed_round INTEGER NOT NULL,
|
|
11529
|
+
active_round INTEGER NOT NULL,
|
|
11530
|
+
PRIMARY KEY (graph_id, run_id, node_kind, node_id)
|
|
11531
|
+
)
|
|
11532
|
+
`;
|
|
11533
|
+
}
|
|
11534
|
+
function neighborTableIdentifier(context) {
|
|
11535
|
+
return sql.identifier(
|
|
11536
|
+
`typegraph_iterative_n_${context.runId.replaceAll("-", "_")}`
|
|
11537
|
+
);
|
|
11538
|
+
}
|
|
11539
|
+
function activeIndexIdentifier(context) {
|
|
11540
|
+
return sql.identifier(
|
|
11541
|
+
`typegraph_iterative_a_${context.runId.replaceAll("-", "_")}`
|
|
11542
|
+
);
|
|
11543
|
+
}
|
|
11544
|
+
async function initializeWorkingTables(context, nodeKinds) {
|
|
11545
|
+
const { operation, workingTable, graphId, runId } = context;
|
|
11546
|
+
const nodeKindFilter = compileNodeKindSeedFilter(nodeKinds);
|
|
11547
|
+
await context.executeTemporary(sql`
|
|
11548
|
+
INSERT INTO ${workingTable}
|
|
11549
|
+
(graph_id, run_id, node_id, node_kind, label_id, label_kind,
|
|
11550
|
+
next_label_id, next_label_kind, changed_round, active_round)
|
|
11551
|
+
SELECT
|
|
11552
|
+
${graphId}, ${runId}, n.id, n.kind, n.id, n.kind, n.id, n.kind, 0, 1
|
|
11553
|
+
FROM ${operation.schema.nodesTable} n
|
|
11554
|
+
WHERE n.graph_id = ${graphId}
|
|
11555
|
+
AND ${nodeKindFilter}
|
|
11556
|
+
AND ${operation.nodeTemporalFilter}
|
|
11557
|
+
`);
|
|
11558
|
+
await context.executeTemporary(sql`
|
|
11559
|
+
CREATE INDEX ${frontierIndexIdentifier(context)}
|
|
11560
|
+
ON ${workingTable} (graph_id, run_id, changed_round)
|
|
11561
|
+
`);
|
|
11562
|
+
await context.executeTemporary(sql`
|
|
11563
|
+
CREATE INDEX ${activeIndexIdentifier(context)}
|
|
11564
|
+
ON ${workingTable} (graph_id, run_id, active_round)
|
|
11565
|
+
`);
|
|
11566
|
+
const neighborTable = neighborTableIdentifier(context);
|
|
11567
|
+
await context.executeTemporary(sql`
|
|
11568
|
+
CREATE TEMP TABLE ${neighborTable} (
|
|
11569
|
+
target_id TEXT NOT NULL,
|
|
11570
|
+
target_kind TEXT NOT NULL,
|
|
11571
|
+
neighbor_id TEXT NOT NULL,
|
|
11572
|
+
neighbor_kind TEXT NOT NULL,
|
|
11573
|
+
PRIMARY KEY (target_kind, target_id, neighbor_kind, neighbor_id)
|
|
11574
|
+
)
|
|
11575
|
+
`);
|
|
11576
|
+
for (const edgeKinds of operation.edgeKindChunks) {
|
|
11577
|
+
await materializeChunkNeighbors(context, edgeKinds);
|
|
11578
|
+
}
|
|
11579
|
+
const analyzeNeighbors = operation.ctx.dialect.analyzeTemporaryTable(neighborTable);
|
|
11580
|
+
if (analyzeNeighbors !== void 0) {
|
|
11581
|
+
await context.executeTemporary(analyzeNeighbors);
|
|
11582
|
+
}
|
|
11583
|
+
const workingTableSize = await countWorkingTableRows(context);
|
|
11584
|
+
return {
|
|
11585
|
+
changedCount: workingTableSize,
|
|
11586
|
+
workingTableSize,
|
|
11587
|
+
completed: false,
|
|
11588
|
+
finishNextRound: false
|
|
11589
|
+
};
|
|
11590
|
+
}
|
|
11591
|
+
async function runLabelPropagationRound(context, state, iteration, policy) {
|
|
11592
|
+
if (iteration > 1) {
|
|
11593
|
+
await markActiveNeighbors(context, iteration);
|
|
11594
|
+
}
|
|
11595
|
+
await selectWinningLabels(context, iteration);
|
|
11596
|
+
const changedRows = await applyNextLabels(context, iteration);
|
|
11597
|
+
const next = {
|
|
11598
|
+
changedCount: changedRows.length,
|
|
11599
|
+
workingTableSize: state.workingTableSize,
|
|
11600
|
+
completed: false,
|
|
11601
|
+
finishNextRound: false
|
|
11602
|
+
};
|
|
11603
|
+
if (next.changedCount === 0) return next;
|
|
11604
|
+
if (state.finishNextRound) return { ...next, completed: true };
|
|
11605
|
+
if (policy.detector.observeRound(changedRows)) {
|
|
11606
|
+
return resolveOscillation(next, iteration, policy);
|
|
11607
|
+
}
|
|
11608
|
+
if (policy.onMaxIterations === "return" && iteration === policy.maxIterations) {
|
|
11609
|
+
return { ...next, completed: true };
|
|
11610
|
+
}
|
|
11611
|
+
return next;
|
|
11612
|
+
}
|
|
11613
|
+
function resolveOscillation(state, iteration, policy) {
|
|
11614
|
+
if (policy.onMaxIterations === "throw") {
|
|
11615
|
+
throw new GraphAlgorithmConvergenceError(
|
|
11616
|
+
"labelPropagation",
|
|
11617
|
+
policy.maxIterations,
|
|
11618
|
+
{ oscillating: true }
|
|
11619
|
+
);
|
|
11620
|
+
}
|
|
11621
|
+
const remaining = policy.maxIterations - iteration;
|
|
11622
|
+
if (remaining % 2 === 0) return { ...state, completed: true };
|
|
11623
|
+
return { ...state, finishNextRound: true };
|
|
11624
|
+
}
|
|
11625
|
+
async function markActiveNeighbors(context, iteration) {
|
|
11626
|
+
const { workingTable, graphId, runId } = context;
|
|
11627
|
+
const neighborTable = neighborTableIdentifier(context);
|
|
11628
|
+
await context.executeTemporary(sql`
|
|
11629
|
+
WITH candidates AS (
|
|
11630
|
+
SELECT DISTINCT neighbors.neighbor_id, neighbors.neighbor_kind
|
|
11631
|
+
FROM ${workingTable} changed
|
|
11632
|
+
JOIN ${neighborTable} neighbors
|
|
11633
|
+
ON neighbors.target_id = changed.node_id
|
|
11634
|
+
AND neighbors.target_kind = changed.node_kind
|
|
11635
|
+
WHERE changed.graph_id = ${graphId}
|
|
11636
|
+
AND changed.run_id = ${runId}
|
|
11637
|
+
AND changed.changed_round = ${iteration - 1}
|
|
11638
|
+
)
|
|
11639
|
+
UPDATE ${workingTable} AS target
|
|
11640
|
+
SET active_round = ${iteration}
|
|
11641
|
+
FROM candidates
|
|
11642
|
+
WHERE target.graph_id = ${graphId}
|
|
11643
|
+
AND target.run_id = ${runId}
|
|
11644
|
+
AND target.node_id = candidates.neighbor_id
|
|
11645
|
+
AND target.node_kind = candidates.neighbor_kind
|
|
11646
|
+
`);
|
|
11647
|
+
}
|
|
11648
|
+
async function materializeChunkNeighbors(context, edgeKinds) {
|
|
11649
|
+
const { operation, workingTable, graphId, runId } = context;
|
|
11650
|
+
const expansion = compileWorkingTableEdgeExpansion(
|
|
11651
|
+
operation,
|
|
11652
|
+
workingTable,
|
|
11653
|
+
sql`
|
|
11654
|
+
w.graph_id = ${graphId}
|
|
11655
|
+
AND w.run_id = ${runId}
|
|
11656
|
+
`,
|
|
11657
|
+
"both",
|
|
11658
|
+
edgeKinds
|
|
11659
|
+
);
|
|
11660
|
+
const neighborTable = neighborTableIdentifier(context);
|
|
11661
|
+
await context.executeTemporary(sql`
|
|
11662
|
+
INSERT INTO ${neighborTable}
|
|
11663
|
+
(target_id, target_kind, neighbor_id, neighbor_kind)
|
|
11664
|
+
SELECT DISTINCT
|
|
11665
|
+
expanded.source_id,
|
|
11666
|
+
expanded.source_kind,
|
|
11667
|
+
expanded.target_id,
|
|
11668
|
+
expanded.target_kind
|
|
11669
|
+
FROM (${expansion}) expanded
|
|
11670
|
+
JOIN ${workingTable} scoped_neighbor
|
|
11671
|
+
ON scoped_neighbor.graph_id = ${graphId}
|
|
11672
|
+
AND scoped_neighbor.run_id = ${runId}
|
|
11673
|
+
AND scoped_neighbor.node_id = expanded.target_id
|
|
11674
|
+
AND scoped_neighbor.node_kind = expanded.target_kind
|
|
11675
|
+
WHERE expanded.source_id <> expanded.target_id
|
|
11676
|
+
OR expanded.source_kind <> expanded.target_kind
|
|
11677
|
+
ON CONFLICT (target_kind, target_id, neighbor_kind, neighbor_id)
|
|
11678
|
+
DO NOTHING
|
|
11679
|
+
`);
|
|
11680
|
+
}
|
|
11681
|
+
async function selectWinningLabels(context, iteration) {
|
|
11682
|
+
const { operation, workingTable, graphId, runId } = context;
|
|
11683
|
+
const neighborTable = neighborTableIdentifier(context);
|
|
11684
|
+
const targetId = operation.ctx.dialect.binaryText(sql`totals.target_id`);
|
|
11685
|
+
const targetKind = operation.ctx.dialect.binaryText(sql`totals.target_kind`);
|
|
11686
|
+
const labelId = operation.ctx.dialect.binaryText(sql`totals.label_id`);
|
|
11687
|
+
const labelKind = operation.ctx.dialect.binaryText(sql`totals.label_kind`);
|
|
11688
|
+
await context.executeTemporary(sql`
|
|
11689
|
+
WITH totals AS (
|
|
11690
|
+
SELECT
|
|
11691
|
+
neighbors.target_id,
|
|
11692
|
+
neighbors.target_kind,
|
|
11693
|
+
neighbor.label_id,
|
|
11694
|
+
neighbor.label_kind,
|
|
11695
|
+
COUNT(*) AS total_votes
|
|
11696
|
+
FROM ${neighborTable} neighbors
|
|
11697
|
+
JOIN ${workingTable} active
|
|
11698
|
+
ON active.graph_id = ${graphId}
|
|
11699
|
+
AND active.run_id = ${runId}
|
|
11700
|
+
AND active.active_round = ${iteration}
|
|
11701
|
+
AND active.node_id = neighbors.target_id
|
|
11702
|
+
AND active.node_kind = neighbors.target_kind
|
|
11703
|
+
JOIN ${workingTable} neighbor
|
|
11704
|
+
ON neighbor.graph_id = ${graphId}
|
|
11705
|
+
AND neighbor.run_id = ${runId}
|
|
11706
|
+
AND neighbor.node_id = neighbors.neighbor_id
|
|
11707
|
+
AND neighbor.node_kind = neighbors.neighbor_kind
|
|
11708
|
+
GROUP BY
|
|
11709
|
+
target_id,
|
|
11710
|
+
target_kind,
|
|
11711
|
+
neighbor.label_id,
|
|
11712
|
+
neighbor.label_kind
|
|
11713
|
+
), ranked AS (
|
|
11714
|
+
SELECT
|
|
11715
|
+
target_id,
|
|
11716
|
+
target_kind,
|
|
11717
|
+
label_id,
|
|
11718
|
+
label_kind,
|
|
11719
|
+
ROW_NUMBER() OVER (
|
|
11720
|
+
PARTITION BY ${targetKind}, ${targetId}
|
|
11721
|
+
ORDER BY total_votes DESC, ${labelId}, ${labelKind}
|
|
11722
|
+
) AS label_rank
|
|
11723
|
+
FROM totals
|
|
11724
|
+
)
|
|
11725
|
+
UPDATE ${workingTable} AS target
|
|
11726
|
+
SET next_label_id = ranked.label_id,
|
|
11727
|
+
next_label_kind = ranked.label_kind
|
|
11728
|
+
FROM ranked
|
|
11729
|
+
WHERE target.graph_id = ${graphId}
|
|
11730
|
+
AND target.run_id = ${runId}
|
|
11731
|
+
AND target.active_round = ${iteration}
|
|
11732
|
+
AND target.node_id = ranked.target_id
|
|
11733
|
+
AND target.node_kind = ranked.target_kind
|
|
11734
|
+
AND ranked.label_rank = 1
|
|
11735
|
+
AND (
|
|
11736
|
+
target.next_label_id <> ranked.label_id
|
|
11737
|
+
OR target.next_label_kind <> ranked.label_kind
|
|
11738
|
+
)
|
|
11739
|
+
`);
|
|
11740
|
+
}
|
|
11741
|
+
function applyNextLabels(context, iteration) {
|
|
11742
|
+
return context.backend.execute(
|
|
11743
|
+
asCompiledRowsSql(sql`
|
|
11744
|
+
UPDATE ${context.workingTable}
|
|
11745
|
+
SET label_id = next_label_id,
|
|
11746
|
+
label_kind = next_label_kind,
|
|
11747
|
+
changed_round = ${iteration}
|
|
11748
|
+
WHERE graph_id = ${context.graphId}
|
|
11749
|
+
AND run_id = ${context.runId}
|
|
11750
|
+
AND active_round = ${iteration}
|
|
11751
|
+
AND (
|
|
11752
|
+
label_id <> next_label_id OR label_kind <> next_label_kind
|
|
11753
|
+
)
|
|
11754
|
+
RETURNING node_id, node_kind, label_id, label_kind
|
|
11755
|
+
`)
|
|
11756
|
+
);
|
|
11757
|
+
}
|
|
11758
|
+
async function extractMemberships(context) {
|
|
11759
|
+
const { operation } = context;
|
|
11760
|
+
const labelId = operation.ctx.dialect.binaryText(sql`label_id`);
|
|
11761
|
+
const labelKind = operation.ctx.dialect.binaryText(sql`label_kind`);
|
|
11762
|
+
const nodeId = operation.ctx.dialect.binaryText(sql`node_id`);
|
|
11763
|
+
const nodeKind = operation.ctx.dialect.binaryText(sql`node_kind`);
|
|
11764
|
+
const rows = await context.backend.execute(
|
|
11765
|
+
asCompiledRowsSql(sql`
|
|
11766
|
+
SELECT
|
|
11767
|
+
node_id,
|
|
11768
|
+
node_kind,
|
|
11769
|
+
label_id,
|
|
11770
|
+
label_kind
|
|
11771
|
+
FROM ${context.workingTable}
|
|
11772
|
+
WHERE graph_id = ${context.graphId} AND run_id = ${context.runId}
|
|
11773
|
+
ORDER BY ${labelId}, ${labelKind}, ${nodeId}, ${nodeKind}
|
|
11774
|
+
`)
|
|
11775
|
+
);
|
|
11776
|
+
return rows.map((row) => ({
|
|
11777
|
+
id: row.node_id,
|
|
11778
|
+
kind: row.node_kind,
|
|
11779
|
+
labelId: row.label_id,
|
|
11780
|
+
labelKind: row.label_kind
|
|
11781
|
+
}));
|
|
11782
|
+
}
|
|
11783
|
+
async function dropNeighborTable(context) {
|
|
11784
|
+
await context.executeTemporary(
|
|
11785
|
+
sql`DROP TABLE IF EXISTS ${neighborTableIdentifier(context)}`
|
|
11786
|
+
);
|
|
11787
|
+
}
|
|
11788
|
+
|
|
11789
|
+
// src/store/algorithms/page-rank.ts
|
|
11790
|
+
var DEFAULT_DAMPING_FACTOR = 0.85;
|
|
11791
|
+
var DEFAULT_TOLERANCE = 1e-8;
|
|
11792
|
+
var DEFAULT_MAX_ITERATIONS = 1e3;
|
|
11793
|
+
var BIND_PARAMETERS_PER_SEED = 3;
|
|
11794
|
+
var RESERVED_SEED_STATEMENT_BIND_PARAMETERS = 2;
|
|
11795
|
+
async function executePageRank(ctx, options) {
|
|
11796
|
+
return executePageRankOperation(ctx, options, void 0);
|
|
11797
|
+
}
|
|
11798
|
+
async function executePersonalizedPageRank(ctx, options) {
|
|
11799
|
+
return executePageRankOperation(ctx, options, normalizeSeeds(options.seeds));
|
|
11800
|
+
}
|
|
11801
|
+
function executePageRankOperation(ctx, options, seeds) {
|
|
11802
|
+
const algorithm = seeds === void 0 ? "pageRank" : "personalizedPageRank";
|
|
11803
|
+
assertEdgeKinds(options.edges);
|
|
11804
|
+
assertGraphAnalyticsSupported(ctx, algorithm);
|
|
11805
|
+
const resolved = resolvePageRankOptions(options, algorithm);
|
|
11806
|
+
const traversalOptions = {
|
|
11807
|
+
edges: options.edges,
|
|
11808
|
+
direction: options.direction ?? "out",
|
|
11809
|
+
...pickTemporalOptions(options),
|
|
11810
|
+
...options.workingMemory === void 0 ? {} : { workingMemory: options.workingMemory }
|
|
11811
|
+
};
|
|
11812
|
+
return runIterativeGraphOperation(ctx, traversalOptions, {
|
|
11813
|
+
algorithm,
|
|
11814
|
+
maxIterations: resolved.maxIterations,
|
|
11815
|
+
createWorkingTable: createWorkingTable2,
|
|
11816
|
+
initialize: (context) => initializeWorkingTable(context, resolved.nodeKinds, seeds),
|
|
11817
|
+
runRound: (context, state) => runPowerIterationRound(context, state, resolved.dampingFactor),
|
|
11818
|
+
hasConverged(state) {
|
|
11819
|
+
return state.maximumChange <= resolved.tolerance;
|
|
11820
|
+
},
|
|
11821
|
+
extractResult: extractScores
|
|
11822
|
+
});
|
|
11823
|
+
}
|
|
11824
|
+
function resolvePageRankOptions(options, algorithm) {
|
|
11825
|
+
const dampingFactor = options.dampingFactor ?? DEFAULT_DAMPING_FACTOR;
|
|
11826
|
+
if (!Number.isFinite(dampingFactor) || dampingFactor < 0 || dampingFactor >= 1) {
|
|
11827
|
+
throw new ConfigurationError(
|
|
11828
|
+
`PageRank dampingFactor must be finite and in [0, 1), got ${String(dampingFactor)}.`,
|
|
11829
|
+
{ dampingFactor }
|
|
11830
|
+
);
|
|
11831
|
+
}
|
|
11832
|
+
const tolerance = options.tolerance ?? DEFAULT_TOLERANCE;
|
|
11833
|
+
if (!Number.isFinite(tolerance) || tolerance <= 0) {
|
|
11834
|
+
throw new ConfigurationError(
|
|
11835
|
+
`PageRank tolerance must be finite and greater than 0, got ${String(tolerance)}.`,
|
|
11836
|
+
{ tolerance }
|
|
11837
|
+
);
|
|
11838
|
+
}
|
|
11839
|
+
return {
|
|
11840
|
+
dampingFactor,
|
|
11841
|
+
tolerance,
|
|
11842
|
+
maxIterations: resolveMaxIterations(
|
|
11843
|
+
options.maxIterations,
|
|
11844
|
+
DEFAULT_MAX_ITERATIONS,
|
|
11845
|
+
algorithm
|
|
11846
|
+
),
|
|
11847
|
+
nodeKinds: normalizeNodeKinds(options.nodeKinds)
|
|
11848
|
+
};
|
|
11849
|
+
}
|
|
11850
|
+
function normalizeSeeds(seeds) {
|
|
11851
|
+
if (seeds.length === 0) {
|
|
11852
|
+
throw new ConfigurationError(
|
|
11853
|
+
"Personalized PageRank requires at least one seed.",
|
|
11854
|
+
{ seeds }
|
|
11855
|
+
);
|
|
11856
|
+
}
|
|
11857
|
+
const combined = /* @__PURE__ */ new Map();
|
|
11858
|
+
for (const seed of seeds) {
|
|
11859
|
+
if (typeof seed.id !== "string" || seed.id.length === 0 || seed.id.includes("\0") || typeof seed.kind !== "string" || seed.kind.length === 0 || seed.kind.includes("\0")) {
|
|
11860
|
+
throw new ConfigurationError(
|
|
11861
|
+
"Personalized PageRank seed id and kind must be non-empty strings without NUL characters.",
|
|
11862
|
+
{ seed }
|
|
11863
|
+
);
|
|
11864
|
+
}
|
|
11865
|
+
const weight = seed.weight ?? 1;
|
|
11866
|
+
if (!Number.isFinite(weight) || weight <= 0) {
|
|
11867
|
+
throw new ConfigurationError(
|
|
11868
|
+
`Personalized PageRank seed weight must be finite and greater than 0, got ${String(weight)}.`,
|
|
11869
|
+
{ seed }
|
|
11870
|
+
);
|
|
11871
|
+
}
|
|
11872
|
+
const key = nodeIdentityKey(seed);
|
|
11873
|
+
const previous = combined.get(key);
|
|
11874
|
+
const combinedWeight = (previous?.weight ?? 0) + weight;
|
|
11875
|
+
if (!Number.isFinite(combinedWeight)) {
|
|
11876
|
+
throw new ConfigurationError(
|
|
11877
|
+
"Personalized PageRank seed weights overflowed while combining duplicate seeds.",
|
|
11878
|
+
{ seed }
|
|
11879
|
+
);
|
|
11880
|
+
}
|
|
11881
|
+
combined.set(key, { id: seed.id, kind: seed.kind, weight: combinedWeight });
|
|
11882
|
+
}
|
|
11883
|
+
const combinedSeeds = [...combined.values()];
|
|
11884
|
+
let maximumWeight = 0;
|
|
11885
|
+
for (const seed of combinedSeeds) {
|
|
11886
|
+
maximumWeight = Math.max(maximumWeight, seed.weight);
|
|
11887
|
+
}
|
|
11888
|
+
const scaledTotal = combinedSeeds.reduce(
|
|
11889
|
+
(total, seed) => total + seed.weight / maximumWeight,
|
|
11890
|
+
0
|
|
11891
|
+
);
|
|
11892
|
+
return combinedSeeds.map((seed) => {
|
|
11893
|
+
const weight = seed.weight / maximumWeight / scaledTotal;
|
|
11894
|
+
if (weight === 0) {
|
|
11895
|
+
throw new ConfigurationError(
|
|
11896
|
+
"Personalized PageRank seed weights differ too much to normalize without underflow.",
|
|
11897
|
+
{ seed }
|
|
11898
|
+
);
|
|
11899
|
+
}
|
|
11900
|
+
return { id: seed.id, kind: seed.kind, weight };
|
|
11901
|
+
}).toSorted((left, right) => compareNodeIdentity(left, right));
|
|
11902
|
+
}
|
|
11903
|
+
function createWorkingTable2(context) {
|
|
11904
|
+
return sql`
|
|
11905
|
+
CREATE TEMP TABLE ${context.workingTable} (
|
|
11906
|
+
graph_id TEXT NOT NULL,
|
|
11907
|
+
run_id TEXT NOT NULL,
|
|
11908
|
+
node_id TEXT NOT NULL,
|
|
11909
|
+
node_kind TEXT NOT NULL,
|
|
11910
|
+
score DOUBLE PRECISION NOT NULL,
|
|
11911
|
+
next_score DOUBLE PRECISION NOT NULL,
|
|
11912
|
+
personalization DOUBLE PRECISION NOT NULL,
|
|
11913
|
+
out_weight DOUBLE PRECISION NOT NULL,
|
|
11914
|
+
PRIMARY KEY (graph_id, run_id, node_kind, node_id)
|
|
11915
|
+
)
|
|
11916
|
+
`;
|
|
11917
|
+
}
|
|
11918
|
+
async function initializeWorkingTable(context, nodeKinds, seeds) {
|
|
11919
|
+
const { operation, workingTable, graphId, runId } = context;
|
|
11920
|
+
const nodeKindFilter = compileNodeKindSeedFilter(nodeKinds);
|
|
11921
|
+
await context.executeTemporary(sql`
|
|
11922
|
+
INSERT INTO ${workingTable}
|
|
11923
|
+
(graph_id, run_id, node_id, node_kind, score, next_score,
|
|
11924
|
+
personalization, out_weight)
|
|
11925
|
+
SELECT ${graphId}, ${runId}, n.id, n.kind, 0.0, 0.0, 0.0, 0.0
|
|
11926
|
+
FROM ${operation.schema.nodesTable} n
|
|
11927
|
+
WHERE n.graph_id = ${graphId}
|
|
11928
|
+
AND ${nodeKindFilter}
|
|
11929
|
+
AND ${operation.nodeTemporalFilter}
|
|
11930
|
+
`);
|
|
11931
|
+
const workingTableSize = await countWorkingTableRows(context);
|
|
11932
|
+
if (workingTableSize === 0) {
|
|
11933
|
+
if (seeds !== void 0) {
|
|
11934
|
+
throw missingSeedError(seeds);
|
|
11935
|
+
}
|
|
11936
|
+
return {
|
|
11937
|
+
activeScoreColumn: "score",
|
|
11938
|
+
maximumChange: 0,
|
|
11939
|
+
workingTableSize
|
|
11940
|
+
};
|
|
11941
|
+
}
|
|
11942
|
+
if (seeds === void 0) {
|
|
11943
|
+
const uniformWeight = 1 / workingTableSize;
|
|
11944
|
+
await context.executeTemporary(sql`
|
|
11945
|
+
UPDATE ${workingTable}
|
|
11946
|
+
SET score = ${uniformWeight},
|
|
11947
|
+
personalization = ${uniformWeight}
|
|
11948
|
+
WHERE graph_id = ${graphId} AND run_id = ${runId}
|
|
11949
|
+
`);
|
|
11950
|
+
} else {
|
|
11951
|
+
await initializePersonalization(context, seeds);
|
|
11952
|
+
}
|
|
11953
|
+
for (const edgeKinds of operation.edgeKindChunks) {
|
|
11954
|
+
await accumulateOutWeights(context, edgeKinds);
|
|
11955
|
+
}
|
|
11956
|
+
return {
|
|
11957
|
+
activeScoreColumn: "score",
|
|
11958
|
+
maximumChange: Number.POSITIVE_INFINITY,
|
|
11959
|
+
workingTableSize
|
|
11960
|
+
};
|
|
11961
|
+
}
|
|
11962
|
+
async function initializePersonalization(context, seeds) {
|
|
11963
|
+
const parameterLimit = context.operation.backend.capabilities.maxBindParameters ?? DEFAULT_MAX_BIND_PARAMETERS;
|
|
11964
|
+
const seedChunkSize = Math.floor(
|
|
11965
|
+
(parameterLimit - RESERVED_SEED_STATEMENT_BIND_PARAMETERS) / BIND_PARAMETERS_PER_SEED
|
|
11966
|
+
);
|
|
11967
|
+
if (seedChunkSize < 1) {
|
|
11968
|
+
throw new ConfigurationError(
|
|
11969
|
+
"Personalized PageRank cannot fit one seed within the backend bind-parameter limit.",
|
|
11970
|
+
{ parameterLimit }
|
|
11971
|
+
);
|
|
11972
|
+
}
|
|
11973
|
+
for (let offset = 0; offset < seeds.length; offset += seedChunkSize) {
|
|
11974
|
+
const chunk2 = seeds.slice(offset, offset + seedChunkSize);
|
|
11975
|
+
const values = sql.join(
|
|
11976
|
+
chunk2.map(
|
|
11977
|
+
(seed) => sql`(${seed.id}, ${seed.kind}, CAST(${seed.weight} AS DOUBLE PRECISION))`
|
|
11978
|
+
),
|
|
11979
|
+
sql`, `
|
|
11980
|
+
);
|
|
11981
|
+
await context.executeTemporary(sql`
|
|
11982
|
+
WITH seed_values(node_id, node_kind, weight) AS (VALUES ${values})
|
|
11983
|
+
UPDATE ${context.workingTable} AS target
|
|
11984
|
+
SET score = seed_values.weight,
|
|
11985
|
+
personalization = seed_values.weight
|
|
11986
|
+
FROM seed_values
|
|
11987
|
+
WHERE target.graph_id = ${context.graphId}
|
|
11988
|
+
AND target.run_id = ${context.runId}
|
|
11989
|
+
AND target.node_id = seed_values.node_id
|
|
11990
|
+
AND target.node_kind = seed_values.node_kind
|
|
11991
|
+
`);
|
|
11992
|
+
}
|
|
11993
|
+
const matchedRows = await context.backend.execute(
|
|
11994
|
+
asCompiledRowsSql(sql`
|
|
11995
|
+
SELECT node_id, node_kind
|
|
11996
|
+
FROM ${context.workingTable}
|
|
11997
|
+
WHERE graph_id = ${context.graphId}
|
|
11998
|
+
AND run_id = ${context.runId}
|
|
11999
|
+
AND personalization > 0
|
|
12000
|
+
`)
|
|
12001
|
+
);
|
|
12002
|
+
const matched = new Set(
|
|
12003
|
+
matchedRows.map(
|
|
12004
|
+
(row) => nodeIdentityKey({ id: row.node_id, kind: row.node_kind })
|
|
12005
|
+
)
|
|
12006
|
+
);
|
|
12007
|
+
const missing = seeds.filter((seed) => !matched.has(nodeIdentityKey(seed)));
|
|
12008
|
+
if (missing.length > 0) throw missingSeedError(missing);
|
|
12009
|
+
}
|
|
12010
|
+
function missingSeedError(seeds) {
|
|
12011
|
+
return new ConfigurationError(
|
|
12012
|
+
"Personalized PageRank seeds must identify visible nodes inside the selected induced subgraph.",
|
|
12013
|
+
{ missingSeeds: seeds.map((seed) => ({ id: seed.id, kind: seed.kind })) }
|
|
12014
|
+
);
|
|
12015
|
+
}
|
|
12016
|
+
async function accumulateOutWeights(context, edgeKinds) {
|
|
12017
|
+
const { operation, workingTable, graphId, runId } = context;
|
|
12018
|
+
const expansion = compileWorkingTableEdgeExpansion(
|
|
12019
|
+
operation,
|
|
12020
|
+
workingTable,
|
|
12021
|
+
sql`w.graph_id = ${graphId} AND w.run_id = ${runId}`,
|
|
12022
|
+
operation.direction,
|
|
12023
|
+
edgeKinds
|
|
12024
|
+
);
|
|
12025
|
+
const transitionWeight = compileTransitionWeight(operation.direction);
|
|
12026
|
+
await context.executeTemporary(sql`
|
|
12027
|
+
WITH scoped_edges AS (
|
|
12028
|
+
SELECT
|
|
12029
|
+
expanded.source_id,
|
|
12030
|
+
expanded.source_kind,
|
|
12031
|
+
${transitionWeight} AS transition_weight
|
|
12032
|
+
FROM (${expansion}) expanded
|
|
12033
|
+
JOIN ${workingTable} scoped_target
|
|
12034
|
+
ON scoped_target.graph_id = ${graphId}
|
|
12035
|
+
AND scoped_target.run_id = ${runId}
|
|
12036
|
+
AND scoped_target.node_id = expanded.target_id
|
|
12037
|
+
AND scoped_target.node_kind = expanded.target_kind
|
|
12038
|
+
), degrees AS (
|
|
12039
|
+
SELECT source_id, source_kind, SUM(transition_weight) AS out_weight
|
|
12040
|
+
FROM scoped_edges
|
|
12041
|
+
GROUP BY source_id, source_kind
|
|
12042
|
+
)
|
|
12043
|
+
UPDATE ${workingTable} AS target
|
|
12044
|
+
SET out_weight = target.out_weight + degrees.out_weight
|
|
12045
|
+
FROM degrees
|
|
12046
|
+
WHERE target.graph_id = ${graphId}
|
|
12047
|
+
AND target.run_id = ${runId}
|
|
12048
|
+
AND target.node_id = degrees.source_id
|
|
12049
|
+
AND target.node_kind = degrees.source_kind
|
|
12050
|
+
`);
|
|
12051
|
+
}
|
|
12052
|
+
function compileTransitionWeight(direction) {
|
|
12053
|
+
if (direction !== "both") return sql`1.0`;
|
|
12054
|
+
return sql`
|
|
12055
|
+
CASE
|
|
12056
|
+
WHEN expanded.source_id = expanded.target_id
|
|
12057
|
+
AND expanded.source_kind = expanded.target_kind
|
|
12058
|
+
THEN 0.5
|
|
12059
|
+
ELSE 1.0
|
|
12060
|
+
END
|
|
12061
|
+
`;
|
|
12062
|
+
}
|
|
12063
|
+
async function runPowerIterationRound(context, state, dampingFactor) {
|
|
12064
|
+
const sourceScoreColumn = state.activeScoreColumn;
|
|
12065
|
+
const targetScoreColumn = sourceScoreColumn === "score" ? "next_score" : "score";
|
|
12066
|
+
await resetTargetScores(
|
|
12067
|
+
context,
|
|
12068
|
+
sourceScoreColumn,
|
|
12069
|
+
targetScoreColumn,
|
|
12070
|
+
dampingFactor
|
|
12071
|
+
);
|
|
12072
|
+
for (const edgeKinds of context.operation.edgeKindChunks) {
|
|
12073
|
+
await accumulateContributions(
|
|
12074
|
+
context,
|
|
12075
|
+
edgeKinds,
|
|
12076
|
+
dampingFactor,
|
|
12077
|
+
sourceScoreColumn,
|
|
12078
|
+
targetScoreColumn
|
|
12079
|
+
);
|
|
12080
|
+
}
|
|
12081
|
+
const maximumChange = await readMaximumChange(
|
|
12082
|
+
context,
|
|
12083
|
+
sourceScoreColumn,
|
|
12084
|
+
targetScoreColumn
|
|
12085
|
+
);
|
|
12086
|
+
return {
|
|
12087
|
+
activeScoreColumn: targetScoreColumn,
|
|
12088
|
+
maximumChange,
|
|
12089
|
+
workingTableSize: state.workingTableSize
|
|
12090
|
+
};
|
|
12091
|
+
}
|
|
12092
|
+
async function resetTargetScores(context, sourceScoreColumn, targetScoreColumn, dampingFactor) {
|
|
12093
|
+
const sourceScore = sql.identifier(sourceScoreColumn);
|
|
12094
|
+
const targetScore = sql.identifier(targetScoreColumn);
|
|
12095
|
+
await context.executeTemporary(sql`
|
|
12096
|
+
UPDATE ${context.workingTable}
|
|
12097
|
+
SET ${targetScore} = personalization * (
|
|
12098
|
+
${1 - dampingFactor} + ${dampingFactor} * (
|
|
12099
|
+
SELECT COALESCE(SUM(dangling.${sourceScore}), 0.0)
|
|
12100
|
+
FROM ${context.workingTable} dangling
|
|
12101
|
+
WHERE dangling.graph_id = ${context.graphId}
|
|
12102
|
+
AND dangling.run_id = ${context.runId}
|
|
12103
|
+
AND dangling.out_weight = 0.0
|
|
12104
|
+
)
|
|
12105
|
+
)
|
|
12106
|
+
WHERE graph_id = ${context.graphId} AND run_id = ${context.runId}
|
|
12107
|
+
`);
|
|
12108
|
+
}
|
|
12109
|
+
async function accumulateContributions(context, edgeKinds, dampingFactor, sourceScoreColumn, targetScoreColumn) {
|
|
12110
|
+
const { operation, workingTable, graphId, runId } = context;
|
|
12111
|
+
const sourceScore = sql.identifier(sourceScoreColumn);
|
|
12112
|
+
const targetScore = sql.identifier(targetScoreColumn);
|
|
12113
|
+
const expansion = compileWorkingTableEdgeExpansion(
|
|
12114
|
+
operation,
|
|
12115
|
+
workingTable,
|
|
12116
|
+
sql`w.graph_id = ${graphId} AND w.run_id = ${runId}`,
|
|
12117
|
+
operation.direction,
|
|
12118
|
+
edgeKinds,
|
|
12119
|
+
sql`w.${sourceScore} AS source_score, w.out_weight AS source_out_weight`
|
|
12120
|
+
);
|
|
12121
|
+
const transitionWeight = compileTransitionWeight(operation.direction);
|
|
12122
|
+
await context.executeTemporary(sql`
|
|
12123
|
+
WITH scoped_edges AS (
|
|
12124
|
+
SELECT
|
|
12125
|
+
expanded.target_id,
|
|
12126
|
+
expanded.target_kind,
|
|
12127
|
+
expanded.source_score,
|
|
12128
|
+
expanded.source_out_weight,
|
|
12129
|
+
${transitionWeight} AS transition_weight
|
|
12130
|
+
FROM (${expansion}) expanded
|
|
12131
|
+
JOIN ${workingTable} scoped_target
|
|
12132
|
+
ON scoped_target.graph_id = ${graphId}
|
|
12133
|
+
AND scoped_target.run_id = ${runId}
|
|
12134
|
+
AND scoped_target.node_id = expanded.target_id
|
|
12135
|
+
AND scoped_target.node_kind = expanded.target_kind
|
|
12136
|
+
WHERE expanded.source_out_weight > 0.0
|
|
12137
|
+
), contributions AS (
|
|
12138
|
+
SELECT
|
|
12139
|
+
target_id,
|
|
12140
|
+
target_kind,
|
|
12141
|
+
SUM(source_score * transition_weight / source_out_weight) AS score
|
|
12142
|
+
FROM scoped_edges
|
|
12143
|
+
GROUP BY target_id, target_kind
|
|
12144
|
+
)
|
|
12145
|
+
UPDATE ${workingTable} AS target
|
|
12146
|
+
SET ${targetScore} = target.${targetScore} + ${dampingFactor} * contributions.score
|
|
12147
|
+
FROM contributions
|
|
12148
|
+
WHERE target.graph_id = ${graphId}
|
|
12149
|
+
AND target.run_id = ${runId}
|
|
12150
|
+
AND target.node_id = contributions.target_id
|
|
12151
|
+
AND target.node_kind = contributions.target_kind
|
|
12152
|
+
`);
|
|
12153
|
+
}
|
|
12154
|
+
async function readMaximumChange(context, sourceScoreColumn, targetScoreColumn) {
|
|
12155
|
+
const sourceScore = sql.identifier(sourceScoreColumn);
|
|
12156
|
+
const targetScore = sql.identifier(targetScoreColumn);
|
|
12157
|
+
const rows = await context.backend.execute(
|
|
12158
|
+
asCompiledRowsSql(sql`
|
|
12159
|
+
SELECT COALESCE(MAX(ABS(${targetScore} - ${sourceScore})), 0.0) AS value
|
|
12160
|
+
FROM ${context.workingTable}
|
|
12161
|
+
WHERE graph_id = ${context.graphId} AND run_id = ${context.runId}
|
|
12162
|
+
`)
|
|
12163
|
+
);
|
|
12164
|
+
return Number(rows[0]?.value ?? 0);
|
|
12165
|
+
}
|
|
12166
|
+
async function extractScores(context, state) {
|
|
12167
|
+
const score = sql.identifier(state.activeScoreColumn);
|
|
12168
|
+
const nodeId = context.operation.ctx.dialect.binaryText(sql`node_id`);
|
|
12169
|
+
const nodeKind = context.operation.ctx.dialect.binaryText(sql`node_kind`);
|
|
12170
|
+
const rows = await context.backend.execute(
|
|
12171
|
+
asCompiledRowsSql(sql`
|
|
12172
|
+
SELECT node_id, node_kind, ${score} AS score
|
|
12173
|
+
FROM ${context.workingTable}
|
|
12174
|
+
WHERE graph_id = ${context.graphId} AND run_id = ${context.runId}
|
|
12175
|
+
ORDER BY ${score} DESC, ${nodeId}, ${nodeKind}
|
|
12176
|
+
`)
|
|
12177
|
+
);
|
|
12178
|
+
return rows.map((row) => ({
|
|
12179
|
+
id: row.node_id,
|
|
12180
|
+
kind: row.node_kind,
|
|
12181
|
+
score: Number(row.score)
|
|
12182
|
+
}));
|
|
12183
|
+
}
|
|
12184
|
+
|
|
12185
|
+
// src/store/algorithms/breadth-first.ts
|
|
12186
|
+
async function findReachableNodes(ctx, sourceId, maxHops, options) {
|
|
12187
|
+
if (supportsTemporaryIteration(ctx)) {
|
|
12188
|
+
return findReachableNodesInWorkingTable(ctx, sourceId, maxHops, options);
|
|
12189
|
+
}
|
|
12190
|
+
return findReachableNodesInline(ctx, sourceId, maxHops, options);
|
|
12191
|
+
}
|
|
12192
|
+
async function findShortestPath(ctx, sourceId, targetId, maxHops, options) {
|
|
12193
|
+
if (supportsTemporaryIteration(ctx)) {
|
|
12194
|
+
return findShortestPathInWorkingTable(
|
|
12195
|
+
ctx,
|
|
12196
|
+
sourceId,
|
|
12197
|
+
targetId,
|
|
12198
|
+
maxHops,
|
|
12199
|
+
options
|
|
12200
|
+
);
|
|
12201
|
+
}
|
|
12202
|
+
return findShortestPathInline(ctx, sourceId, targetId, maxHops, options);
|
|
12203
|
+
}
|
|
12204
|
+
async function findReachableNodesInWorkingTable(ctx, sourceId, maxHops, options) {
|
|
12205
|
+
return runIterativeGraphOperation(ctx, options, {
|
|
12206
|
+
algorithm: "reachable",
|
|
12207
|
+
maxIterations: maxHops,
|
|
12208
|
+
createWorkingTable: createWorkingTable3,
|
|
12209
|
+
async initialize(context) {
|
|
12210
|
+
const seeded = await seedWorkingSide(context, sourceId, "forward");
|
|
12211
|
+
return {
|
|
12212
|
+
depth: 0,
|
|
12213
|
+
frontierCount: seeded.length,
|
|
12214
|
+
workingTableSize: seeded.length
|
|
12215
|
+
};
|
|
12216
|
+
},
|
|
12217
|
+
async runRound(context, state) {
|
|
12218
|
+
const nextDepth = state.depth + 1;
|
|
12219
|
+
const frontierCount = await expandReachableWorkingTableRound(
|
|
12220
|
+
context,
|
|
12221
|
+
"forward",
|
|
12222
|
+
state.depth,
|
|
12223
|
+
nextDepth,
|
|
12224
|
+
context.operation.direction
|
|
12225
|
+
);
|
|
12226
|
+
return {
|
|
12227
|
+
depth: nextDepth,
|
|
12228
|
+
frontierCount,
|
|
12229
|
+
workingTableSize: state.workingTableSize + frontierCount
|
|
12230
|
+
};
|
|
12231
|
+
},
|
|
12232
|
+
hasConverged(state) {
|
|
12233
|
+
return state.frontierCount === 0 || state.depth >= maxHops;
|
|
12234
|
+
},
|
|
12235
|
+
async extractResult(context) {
|
|
12236
|
+
const rows = await readWorkingRows(context, "forward");
|
|
12237
|
+
return rows.map((row) => ({
|
|
12238
|
+
id: row.node_id,
|
|
12239
|
+
kind: row.node_kind,
|
|
12240
|
+
depth: Number(row.depth)
|
|
12241
|
+
})).toSorted(
|
|
12242
|
+
(left, right) => left.depth - right.depth || compareNodeIdentity(left, right)
|
|
12243
|
+
);
|
|
12244
|
+
}
|
|
12245
|
+
});
|
|
12246
|
+
}
|
|
12247
|
+
async function findShortestPathInWorkingTable(ctx, sourceId, targetId, maxHops, options) {
|
|
12248
|
+
return runIterativeGraphOperation(ctx, options, {
|
|
12249
|
+
algorithm: "shortestPath",
|
|
12250
|
+
maxIterations: maxHops,
|
|
12251
|
+
createWorkingTable: createWorkingTable3,
|
|
12252
|
+
async initialize(context) {
|
|
12253
|
+
const forwardSeeds = await seedWorkingSide(context, sourceId, "forward");
|
|
12254
|
+
const reverseSeeds = await seedWorkingSide(context, targetId, "reverse");
|
|
12255
|
+
return {
|
|
12256
|
+
forwardDepth: 0,
|
|
12257
|
+
reverseDepth: 0,
|
|
12258
|
+
forwardFrontierCount: forwardSeeds.length,
|
|
12259
|
+
reverseFrontierCount: reverseSeeds.length,
|
|
12260
|
+
meeting: findSeedMeeting(forwardSeeds, reverseSeeds),
|
|
12261
|
+
workingTableSize: forwardSeeds.length + reverseSeeds.length
|
|
12262
|
+
};
|
|
12263
|
+
},
|
|
12264
|
+
async runRound(context, state) {
|
|
12265
|
+
const expandForward = state.forwardFrontierCount <= state.reverseFrontierCount;
|
|
12266
|
+
const side = expandForward ? "forward" : "reverse";
|
|
12267
|
+
const currentDepth = expandForward ? state.forwardDepth : state.reverseDepth;
|
|
12268
|
+
const nextDepth = currentDepth + 1;
|
|
12269
|
+
const direction = expandForward ? context.operation.direction : reverseDirection(context.operation.direction);
|
|
12270
|
+
const round = await expandWorkingTableRound(
|
|
12271
|
+
context,
|
|
12272
|
+
side,
|
|
12273
|
+
currentDepth,
|
|
12274
|
+
nextDepth,
|
|
12275
|
+
direction,
|
|
12276
|
+
maxHops
|
|
12277
|
+
);
|
|
12278
|
+
return {
|
|
11351
12279
|
forwardDepth: expandForward ? nextDepth : state.forwardDepth,
|
|
11352
12280
|
reverseDepth: expandForward ? state.reverseDepth : nextDepth,
|
|
11353
12281
|
forwardFrontierCount: expandForward ? round.insertedCount : state.forwardFrontierCount,
|
|
@@ -11370,7 +12298,7 @@ async function findShortestPathInWorkingTable(ctx, sourceId, targetId, maxHops,
|
|
|
11370
12298
|
}
|
|
11371
12299
|
});
|
|
11372
12300
|
}
|
|
11373
|
-
function
|
|
12301
|
+
function createWorkingTable3(context) {
|
|
11374
12302
|
return sql`
|
|
11375
12303
|
CREATE TEMP TABLE ${context.workingTable} (
|
|
11376
12304
|
graph_id TEXT NOT NULL,
|
|
@@ -11612,7 +12540,8 @@ async function findShortestPathInline(ctx, sourceId, targetId, maxHops, options)
|
|
|
11612
12540
|
const sources = visibleNodes.filter((node) => node.id === sourceId);
|
|
11613
12541
|
const targets = visibleNodes.filter((node) => node.id === targetId);
|
|
11614
12542
|
if (sources.length === 0 || targets.length === 0) return;
|
|
11615
|
-
if (sourceId === targetId)
|
|
12543
|
+
if (sourceId === targetId)
|
|
12544
|
+
return { nodes: [requireDefined(sources[0])], depth: 0 };
|
|
11616
12545
|
const forwardVisited = createVisitedMap(sources);
|
|
11617
12546
|
const reverseVisited = createVisitedMap(targets);
|
|
11618
12547
|
let forwardWorkingSet = sources;
|
|
@@ -11813,18 +12742,20 @@ async function executeShortestPath(ctx, sourceId, targetId, options) {
|
|
|
11813
12742
|
);
|
|
11814
12743
|
return findShortestPath(ctx, sourceId, targetId, maxHops, options);
|
|
11815
12744
|
}
|
|
12745
|
+
|
|
12746
|
+
// src/store/algorithms/weakly-connected-components.ts
|
|
11816
12747
|
var DEFAULT_WCC_MAX_ITERATIONS = 1e3;
|
|
11817
12748
|
async function executeWeaklyConnectedComponents(ctx, options) {
|
|
11818
12749
|
assertEdgeKinds(options.edges);
|
|
11819
|
-
|
|
12750
|
+
assertGraphAnalyticsSupported(ctx, "weaklyConnectedComponents", {
|
|
12751
|
+
requiresWindowFunctions: true
|
|
12752
|
+
});
|
|
11820
12753
|
const maxIterations = resolveMaxIterations(
|
|
11821
12754
|
options.maxIterations,
|
|
11822
12755
|
DEFAULT_WCC_MAX_ITERATIONS,
|
|
11823
12756
|
"weaklyConnectedComponents"
|
|
11824
12757
|
);
|
|
11825
|
-
const nodeKinds =
|
|
11826
|
-
(left, right) => compareCodePoints(left, right)
|
|
11827
|
-
);
|
|
12758
|
+
const nodeKinds = normalizeNodeKinds(options.nodeKinds);
|
|
11828
12759
|
const traversalOptions = {
|
|
11829
12760
|
edges: options.edges,
|
|
11830
12761
|
direction: "both",
|
|
@@ -11834,31 +12765,16 @@ async function executeWeaklyConnectedComponents(ctx, options) {
|
|
|
11834
12765
|
return runIterativeGraphOperation(ctx, traversalOptions, {
|
|
11835
12766
|
algorithm: "weaklyConnectedComponents",
|
|
11836
12767
|
maxIterations,
|
|
11837
|
-
createWorkingTable:
|
|
11838
|
-
initialize: (context) =>
|
|
11839
|
-
runRound:
|
|
12768
|
+
createWorkingTable: createWorkingTable4,
|
|
12769
|
+
initialize: (context) => initializeWorkingTable2(context, nodeKinds),
|
|
12770
|
+
runRound: runLabelPropagationRound2,
|
|
11840
12771
|
hasConverged(state) {
|
|
11841
12772
|
return state.changedCount === 0;
|
|
11842
12773
|
},
|
|
11843
|
-
extractResult:
|
|
12774
|
+
extractResult: extractMemberships2
|
|
11844
12775
|
});
|
|
11845
12776
|
}
|
|
11846
|
-
function
|
|
11847
|
-
if (ctx.backend.capabilities.graphAnalytics?.supported === true && ctx.backend.capabilities.windowFunctions) {
|
|
11848
|
-
return;
|
|
11849
|
-
}
|
|
11850
|
-
throw new UnsupportedBackendCapabilityError(
|
|
11851
|
-
"weaklyConnectedComponents",
|
|
11852
|
-
"graphAnalytics",
|
|
11853
|
-
{
|
|
11854
|
-
dialect: ctx.backend.dialect,
|
|
11855
|
-
supported: ctx.backend.capabilities.graphAnalytics?.supported === true,
|
|
11856
|
-
windowFunctions: ctx.backend.capabilities.windowFunctions
|
|
11857
|
-
},
|
|
11858
|
-
"Use a built-in transactional SQLite/PostgreSQL backend, or declare graphAnalytics support on a compatible custom backend."
|
|
11859
|
-
);
|
|
11860
|
-
}
|
|
11861
|
-
function createWorkingTable2(context) {
|
|
12777
|
+
function createWorkingTable4(context) {
|
|
11862
12778
|
return sql`
|
|
11863
12779
|
CREATE TEMP TABLE ${context.workingTable} (
|
|
11864
12780
|
graph_id TEXT NOT NULL,
|
|
@@ -11874,9 +12790,9 @@ function createWorkingTable2(context) {
|
|
|
11874
12790
|
)
|
|
11875
12791
|
`;
|
|
11876
12792
|
}
|
|
11877
|
-
async function
|
|
12793
|
+
async function initializeWorkingTable2(context, nodeKinds) {
|
|
11878
12794
|
const { operation, workingTable, graphId, runId } = context;
|
|
11879
|
-
const nodeKindFilter =
|
|
12795
|
+
const nodeKindFilter = compileNodeKindSeedFilter(nodeKinds);
|
|
11880
12796
|
await context.executeTemporary(sql`
|
|
11881
12797
|
INSERT INTO ${workingTable}
|
|
11882
12798
|
(graph_id, run_id, node_id, node_kind, label_id, label_kind,
|
|
@@ -11892,21 +12808,14 @@ async function initializeWorkingTable(context, nodeKinds) {
|
|
|
11892
12808
|
CREATE INDEX ${frontierIndexIdentifier(context)}
|
|
11893
12809
|
ON ${workingTable} (graph_id, run_id, improved_round)
|
|
11894
12810
|
`);
|
|
11895
|
-
const
|
|
11896
|
-
asCompiledRowsSql(sql`
|
|
11897
|
-
SELECT COUNT(*) AS count
|
|
11898
|
-
FROM ${workingTable}
|
|
11899
|
-
WHERE graph_id = ${graphId} AND run_id = ${runId}
|
|
11900
|
-
`)
|
|
11901
|
-
);
|
|
11902
|
-
const workingTableSize = Number(rows[0]?.count ?? 0);
|
|
12811
|
+
const workingTableSize = await countWorkingTableRows(context);
|
|
11903
12812
|
return { changedCount: workingTableSize, workingTableSize };
|
|
11904
12813
|
}
|
|
11905
|
-
async function
|
|
12814
|
+
async function runLabelPropagationRound2(context, state, iteration) {
|
|
11906
12815
|
for (const edgeKinds of context.operation.edgeKindChunks) {
|
|
11907
12816
|
await propagateChunkLabels(context, edgeKinds, iteration);
|
|
11908
12817
|
}
|
|
11909
|
-
const changedRows = await
|
|
12818
|
+
const changedRows = await applyNextLabels2(context, iteration);
|
|
11910
12819
|
return {
|
|
11911
12820
|
changedCount: changedRows.length,
|
|
11912
12821
|
workingTableSize: state.workingTableSize
|
|
@@ -11981,7 +12890,7 @@ async function propagateChunkLabels(context, edgeKinds, iteration) {
|
|
|
11981
12890
|
)
|
|
11982
12891
|
`);
|
|
11983
12892
|
}
|
|
11984
|
-
function
|
|
12893
|
+
function applyNextLabels2(context, iteration) {
|
|
11985
12894
|
return context.backend.execute(
|
|
11986
12895
|
asCompiledRowsSql(sql`
|
|
11987
12896
|
UPDATE ${context.workingTable}
|
|
@@ -11997,7 +12906,7 @@ function applyNextLabels(context, iteration) {
|
|
|
11997
12906
|
`)
|
|
11998
12907
|
);
|
|
11999
12908
|
}
|
|
12000
|
-
async function
|
|
12909
|
+
async function extractMemberships2(context) {
|
|
12001
12910
|
const { operation } = context;
|
|
12002
12911
|
const componentId = operation.ctx.dialect.binaryText(sql`label_id`);
|
|
12003
12912
|
const componentKind = operation.ctx.dialect.binaryText(sql`label_kind`);
|
|
@@ -12026,6 +12935,8 @@ async function extractMemberships(context) {
|
|
|
12026
12935
|
size: Number(row.component_size)
|
|
12027
12936
|
}));
|
|
12028
12937
|
}
|
|
12938
|
+
|
|
12939
|
+
// src/store/algorithms/weighted-shortest-path.ts
|
|
12029
12940
|
var DEFAULT_WEIGHTED_SHORTEST_PATH_MAX_ITERATIONS = 1e3;
|
|
12030
12941
|
var WEIGHTED_ALGORITHM_NAME = "weightedShortestPath";
|
|
12031
12942
|
var MAX_EDGE_WEIGHT = Number.MAX_VALUE / 2 ** 64;
|
|
@@ -12145,7 +13056,7 @@ async function findWeightedShortestPathInWorkingTable(ctx, sourceId, targetId, m
|
|
|
12145
13056
|
return runIterativeGraphOperation(ctx, options, {
|
|
12146
13057
|
algorithm: WEIGHTED_ALGORITHM_NAME,
|
|
12147
13058
|
maxIterations,
|
|
12148
|
-
createWorkingTable:
|
|
13059
|
+
createWorkingTable: createWorkingTable5,
|
|
12149
13060
|
async initialize(context) {
|
|
12150
13061
|
await assertValidEdgeWeights(
|
|
12151
13062
|
context.operation,
|
|
@@ -12208,7 +13119,7 @@ async function hasVisibleNode(operation, nodeId) {
|
|
|
12208
13119
|
);
|
|
12209
13120
|
return rows.length > 0;
|
|
12210
13121
|
}
|
|
12211
|
-
function
|
|
13122
|
+
function createWorkingTable5(context) {
|
|
12212
13123
|
return sql`
|
|
12213
13124
|
CREATE TEMP TABLE ${context.workingTable} (
|
|
12214
13125
|
graph_id TEXT NOT NULL,
|
|
@@ -12562,13 +13473,33 @@ function createGraphAlgorithms(params) {
|
|
|
12562
13473
|
assertRecordedAsOfInternalOnly(options, "degree", allowRecordedAsOf);
|
|
12563
13474
|
return executeDegree(ctx, resolveNodeId(node), options ?? {});
|
|
12564
13475
|
},
|
|
12565
|
-
|
|
13476
|
+
labelPropagation(options) {
|
|
13477
|
+
assertRecordedAsOfInternalOnly(
|
|
13478
|
+
options,
|
|
13479
|
+
"labelPropagation",
|
|
13480
|
+
allowRecordedAsOf
|
|
13481
|
+
);
|
|
13482
|
+
return executeLabelPropagation(ctx, options);
|
|
13483
|
+
},
|
|
13484
|
+
weaklyConnectedComponents(options) {
|
|
13485
|
+
assertRecordedAsOfInternalOnly(
|
|
13486
|
+
options,
|
|
13487
|
+
"weaklyConnectedComponents",
|
|
13488
|
+
allowRecordedAsOf
|
|
13489
|
+
);
|
|
13490
|
+
return executeWeaklyConnectedComponents(ctx, options);
|
|
13491
|
+
},
|
|
13492
|
+
pageRank(options) {
|
|
13493
|
+
assertRecordedAsOfInternalOnly(options, "pageRank", allowRecordedAsOf);
|
|
13494
|
+
return executePageRank(ctx, options);
|
|
13495
|
+
},
|
|
13496
|
+
personalizedPageRank(options) {
|
|
12566
13497
|
assertRecordedAsOfInternalOnly(
|
|
12567
13498
|
options,
|
|
12568
|
-
"
|
|
13499
|
+
"personalizedPageRank",
|
|
12569
13500
|
allowRecordedAsOf
|
|
12570
13501
|
);
|
|
12571
|
-
return
|
|
13502
|
+
return executePersonalizedPageRank(ctx, options);
|
|
12572
13503
|
}
|
|
12573
13504
|
};
|
|
12574
13505
|
}
|
|
@@ -12795,10 +13726,10 @@ function createEdgeCollection(config) {
|
|
|
12795
13726
|
itemIndex++;
|
|
12796
13727
|
continue;
|
|
12797
13728
|
}
|
|
12798
|
-
const deletedAt = pendingEntry === void 0 ? original.deleted_at : void 0;
|
|
13729
|
+
const deletedAt = pendingEntry === void 0 ? requireDefined(original).deleted_at : void 0;
|
|
12799
13730
|
let dirty;
|
|
12800
13731
|
if (config.upsertDirtyCheck !== void 0) {
|
|
12801
|
-
const currentProps = pendingEntry?.props ?? rowPropsToObject(original.props);
|
|
13732
|
+
const currentProps = pendingEntry?.props ?? rowPropsToObject(requireDefined(original).props);
|
|
12802
13733
|
try {
|
|
12803
13734
|
dirty = config.upsertDirtyCheck(
|
|
12804
13735
|
original?.kind ?? kind,
|
|
@@ -12813,7 +13744,9 @@ function createEdgeCollection(config) {
|
|
|
12813
13744
|
const coalesce = dirty?.unchanged === true && deletedAt === void 0 && item.validFrom === void 0 && item.validTo === void 0;
|
|
12814
13745
|
if (coalesce) {
|
|
12815
13746
|
if (pendingEntry === void 0) {
|
|
12816
|
-
results2[itemIndex] = narrowEdge(
|
|
13747
|
+
results2[itemIndex] = narrowEdge(
|
|
13748
|
+
rowToEdge2(requireDefined(original))
|
|
13749
|
+
);
|
|
12817
13750
|
} else {
|
|
12818
13751
|
deferred.push({
|
|
12819
13752
|
index: itemIndex,
|
|
@@ -12839,7 +13772,9 @@ function createEdgeCollection(config) {
|
|
|
12839
13772
|
const createInputs = toCreate.map((entry2) => entry2.input);
|
|
12840
13773
|
const created = await executeEdgeCreateBatch2(createInputs, target);
|
|
12841
13774
|
for (const [index, entry2] of toCreate.entries()) {
|
|
12842
|
-
results2[entry2.index] = narrowEdge(
|
|
13775
|
+
results2[entry2.index] = narrowEdge(
|
|
13776
|
+
requireDefined(created[index])
|
|
13777
|
+
);
|
|
12843
13778
|
}
|
|
12844
13779
|
}
|
|
12845
13780
|
for (const entry2 of toUpdate) {
|
|
@@ -12849,7 +13784,7 @@ function createEdgeCollection(config) {
|
|
|
12849
13784
|
results2[entry2.index] = narrowEdge(result);
|
|
12850
13785
|
}
|
|
12851
13786
|
for (const { index, sourceIndex } of deferred) {
|
|
12852
|
-
results2[index] = results2[sourceIndex];
|
|
13787
|
+
results2[index] = requireDefined(results2[sourceIndex]);
|
|
12853
13788
|
}
|
|
12854
13789
|
return { results: results2, mutations: toCreate.length + toUpdate.length };
|
|
12855
13790
|
};
|
|
@@ -13057,7 +13992,7 @@ function createNodeCollection(config) {
|
|
|
13057
13992
|
temporal,
|
|
13058
13993
|
defaultTemporalMode
|
|
13059
13994
|
);
|
|
13060
|
-
let query = createQuery().from(kind, "_n").temporal(asOf === void 0 ? temporalMode : "asOf", asOf).whereNode("_n", filter.where).select((ctx) => ctx
|
|
13995
|
+
let query = createQuery().from(kind, "_n").temporal(asOf === void 0 ? temporalMode : "asOf", asOf).whereNode("_n", filter.where).select((ctx) => ctx["_n"]);
|
|
13061
13996
|
if (filter.limit !== void 0) query = query.limit(filter.limit);
|
|
13062
13997
|
if (filter.offset !== void 0) query = query.offset(filter.offset);
|
|
13063
13998
|
const results = await query.execute();
|
|
@@ -13087,7 +14022,7 @@ function createNodeCollection(config) {
|
|
|
13087
14022
|
async upsertByIdFromRecord(id, data, options) {
|
|
13088
14023
|
const existing = await backend.getNode(graphId, kind, id);
|
|
13089
14024
|
if (existing) {
|
|
13090
|
-
const runDirtyCheck = config.upsertDirtyCheck && (() => config.upsertDirtyCheck(
|
|
14025
|
+
const runDirtyCheck = config.upsertDirtyCheck && (() => requireDefined(config.upsertDirtyCheck)(
|
|
13091
14026
|
kind,
|
|
13092
14027
|
id,
|
|
13093
14028
|
rowPropsToObject(existing.props),
|
|
@@ -13157,10 +14092,10 @@ function createNodeCollection(config) {
|
|
|
13157
14092
|
itemIndex++;
|
|
13158
14093
|
continue;
|
|
13159
14094
|
}
|
|
13160
|
-
const deletedAt = pendingEntry === void 0 ? original.deleted_at : void 0;
|
|
14095
|
+
const deletedAt = pendingEntry === void 0 ? requireDefined(original).deleted_at : void 0;
|
|
13161
14096
|
let dirty;
|
|
13162
14097
|
if (config.upsertDirtyCheck !== void 0) {
|
|
13163
|
-
const currentProps = pendingEntry?.props ?? rowPropsToObject(original.props);
|
|
14098
|
+
const currentProps = pendingEntry?.props ?? rowPropsToObject(requireDefined(original).props);
|
|
13164
14099
|
try {
|
|
13165
14100
|
dirty = config.upsertDirtyCheck(
|
|
13166
14101
|
kind,
|
|
@@ -13175,7 +14110,9 @@ function createNodeCollection(config) {
|
|
|
13175
14110
|
const coalesce = dirty?.unchanged === true && deletedAt === void 0 && item.validFrom === void 0 && item.validTo === void 0;
|
|
13176
14111
|
if (coalesce) {
|
|
13177
14112
|
if (pendingEntry === void 0) {
|
|
13178
|
-
results2[itemIndex] = narrowNode(
|
|
14113
|
+
results2[itemIndex] = narrowNode(
|
|
14114
|
+
rowToNode2(requireDefined(original))
|
|
14115
|
+
);
|
|
13179
14116
|
} else {
|
|
13180
14117
|
deferred.push({
|
|
13181
14118
|
index: itemIndex,
|
|
@@ -13201,7 +14138,9 @@ function createNodeCollection(config) {
|
|
|
13201
14138
|
const createInputs = toCreate.map((entry2) => entry2.input);
|
|
13202
14139
|
const created = await executeNodeCreateBatch2(createInputs, target);
|
|
13203
14140
|
for (const [index, entry2] of toCreate.entries()) {
|
|
13204
|
-
results2[entry2.index] = narrowNode(
|
|
14141
|
+
results2[entry2.index] = narrowNode(
|
|
14142
|
+
requireDefined(created[index])
|
|
14143
|
+
);
|
|
13205
14144
|
}
|
|
13206
14145
|
}
|
|
13207
14146
|
for (const entry2 of toUpdate) {
|
|
@@ -13211,7 +14150,7 @@ function createNodeCollection(config) {
|
|
|
13211
14150
|
results2[entry2.index] = narrowNode(result);
|
|
13212
14151
|
}
|
|
13213
14152
|
for (const { index, sourceIndex } of deferred) {
|
|
13214
|
-
results2[index] = results2[sourceIndex];
|
|
14153
|
+
results2[index] = requireDefined(results2[sourceIndex]);
|
|
13215
14154
|
}
|
|
13216
14155
|
return { results: results2, mutations: toCreate.length + toUpdate.length };
|
|
13217
14156
|
};
|
|
@@ -13363,6 +14302,99 @@ function createEdgeCollectionsProxy(graph, graphId, registry, backend, operation
|
|
|
13363
14302
|
});
|
|
13364
14303
|
}
|
|
13365
14304
|
|
|
14305
|
+
// src/store/history-store-backend.ts
|
|
14306
|
+
var HISTORY_STORE_BACKEND_KEYS = [
|
|
14307
|
+
"assertRuntimeContributionsInitialized",
|
|
14308
|
+
"assertVectorSlotInitialized",
|
|
14309
|
+
"assertVectorSlotsInitialized",
|
|
14310
|
+
"bootstrapTables",
|
|
14311
|
+
"capabilities",
|
|
14312
|
+
"checkUnique",
|
|
14313
|
+
"checkUniqueBatch",
|
|
14314
|
+
"claimIndexMaterialization",
|
|
14315
|
+
"close",
|
|
14316
|
+
"commitSchemaVersion",
|
|
14317
|
+
"compileSql",
|
|
14318
|
+
"countEdgesByKind",
|
|
14319
|
+
"countEdgesFrom",
|
|
14320
|
+
"countNodesByKind",
|
|
14321
|
+
"createVectorIndex",
|
|
14322
|
+
"deleteEdge",
|
|
14323
|
+
"deleteEdgesBatch",
|
|
14324
|
+
"deleteEmbedding",
|
|
14325
|
+
"deleteFulltext",
|
|
14326
|
+
"deleteFulltextBatch",
|
|
14327
|
+
"deleteNode",
|
|
14328
|
+
"deleteUnique",
|
|
14329
|
+
"deleteVectorSlotContribution",
|
|
14330
|
+
"dialect",
|
|
14331
|
+
"dropVectorIndex",
|
|
14332
|
+
"edgeExistsBetween",
|
|
14333
|
+
"ensureContributionMaterializationsTable",
|
|
14334
|
+
"ensureFulltextTable",
|
|
14335
|
+
"ensureIndexMaterializationsTable",
|
|
14336
|
+
"ensureKindRemovalsTable",
|
|
14337
|
+
"ensureReconciliationMarkersTable",
|
|
14338
|
+
"ensureRevisionOriginsTable",
|
|
14339
|
+
"ensureRuntimeContributions",
|
|
14340
|
+
"ensureVectorSlotContribution",
|
|
14341
|
+
"ensureVectorSlotContributions",
|
|
14342
|
+
"execute",
|
|
14343
|
+
"executeTemporaryStatement",
|
|
14344
|
+
"findEdgesByKind",
|
|
14345
|
+
"findEdgesConnectedTo",
|
|
14346
|
+
"findNodesByKind",
|
|
14347
|
+
"fulltextSearch",
|
|
14348
|
+
"fulltextStrategy",
|
|
14349
|
+
"getActiveSchema",
|
|
14350
|
+
"getAllKindRemovals",
|
|
14351
|
+
"getContributionMaterialization",
|
|
14352
|
+
"getEdge",
|
|
14353
|
+
"getEdges",
|
|
14354
|
+
"getIndexMaterialization",
|
|
14355
|
+
"getIndexMaterializations",
|
|
14356
|
+
"getNode",
|
|
14357
|
+
"getNodes",
|
|
14358
|
+
"getPendingKindRemovals",
|
|
14359
|
+
"getReconciliationMarker",
|
|
14360
|
+
"getSchemaVersion",
|
|
14361
|
+
"hardDeleteEdge",
|
|
14362
|
+
"hardDeleteEdgesBatch",
|
|
14363
|
+
"hardDeleteNode",
|
|
14364
|
+
"hybridSearch",
|
|
14365
|
+
"insertEdge",
|
|
14366
|
+
"insertEdgeNoReturn",
|
|
14367
|
+
"insertEdgesBatch",
|
|
14368
|
+
"insertEdgesBatchReturning",
|
|
14369
|
+
"insertNode",
|
|
14370
|
+
"insertNodeNoReturn",
|
|
14371
|
+
"insertNodesBatch",
|
|
14372
|
+
"insertNodesBatchReturning",
|
|
14373
|
+
"insertUnique",
|
|
14374
|
+
"insertUniqueBatch",
|
|
14375
|
+
"recordContributionMaterialization",
|
|
14376
|
+
"recordIndexMaterialization",
|
|
14377
|
+
"recordKindRemoval",
|
|
14378
|
+
"refreshStatistics",
|
|
14379
|
+
"releaseIndexMaterializationClaim",
|
|
14380
|
+
"setActiveVersion",
|
|
14381
|
+
"setReconciliationMarker",
|
|
14382
|
+
"tableNames",
|
|
14383
|
+
"updateEdge",
|
|
14384
|
+
"updateNode",
|
|
14385
|
+
"upsertEmbedding",
|
|
14386
|
+
"upsertEmbeddingBatch",
|
|
14387
|
+
"upsertFulltext",
|
|
14388
|
+
"upsertFulltextBatch",
|
|
14389
|
+
"vectorSearch",
|
|
14390
|
+
"vectorStrategy"
|
|
14391
|
+
];
|
|
14392
|
+
function createHistoryStoreBackendProjection(backend) {
|
|
14393
|
+
return Object.freeze(
|
|
14394
|
+
projectBackendMembers(backend, HISTORY_STORE_BACKEND_KEYS)
|
|
14395
|
+
);
|
|
14396
|
+
}
|
|
14397
|
+
|
|
13366
14398
|
// src/store/introspect.ts
|
|
13367
14399
|
function introspectSchema(graph, context) {
|
|
13368
14400
|
const extension = graph.extension;
|
|
@@ -13474,6 +14506,18 @@ async function runMaterialization(items, options, runOne) {
|
|
|
13474
14506
|
var CLAIM_LEASE_MS = 15 * 6e4;
|
|
13475
14507
|
var CLAIM_RETRY_DELAY_MS = 200;
|
|
13476
14508
|
var CLAIM_WAIT_TIMEOUT_MS = CLAIM_LEASE_MS + 6e4;
|
|
14509
|
+
var INDEX_DIALECT_BEHAVIOR = {
|
|
14510
|
+
postgres: {
|
|
14511
|
+
concurrentBuilds: true,
|
|
14512
|
+
hasInvalidIndexState: true,
|
|
14513
|
+
supportsGinFamily: true
|
|
14514
|
+
},
|
|
14515
|
+
sqlite: {
|
|
14516
|
+
concurrentBuilds: false,
|
|
14517
|
+
hasInvalidIndexState: false,
|
|
14518
|
+
supportsGinFamily: false
|
|
14519
|
+
}
|
|
14520
|
+
};
|
|
13477
14521
|
function hasIndexBuildClaimProtocol(backend) {
|
|
13478
14522
|
return backend.claimIndexMaterialization !== void 0 && backend.releaseIndexMaterializationClaim !== void 0;
|
|
13479
14523
|
}
|
|
@@ -13518,7 +14562,7 @@ async function materializeIndexes(context, options = {}) {
|
|
|
13518
14562
|
const tableNames = backend.tableNames;
|
|
13519
14563
|
const ddlOptions = {
|
|
13520
14564
|
ifNotExists: true,
|
|
13521
|
-
concurrent: dialect
|
|
14565
|
+
concurrent: INDEX_DIALECT_BEHAVIOR[dialect].concurrentBuilds,
|
|
13522
14566
|
...tableNames?.nodes === void 0 ? {} : { nodesTableName: tableNames.nodes },
|
|
13523
14567
|
...tableNames?.edges === void 0 ? {} : { edgesTableName: tableNames.edges }
|
|
13524
14568
|
};
|
|
@@ -13599,7 +14643,7 @@ function parallelBucketKey(declaration) {
|
|
|
13599
14643
|
return declaration.entity;
|
|
13600
14644
|
}
|
|
13601
14645
|
async function materializeRelationalIndex(declaration, backend, dialect, ddlOptions, graphId, schemaVersion, existingByStatusKey, invalidLeftovers) {
|
|
13602
|
-
if (declaration.method !== void 0 && dialect
|
|
14646
|
+
if (declaration.method !== void 0 && !INDEX_DIALECT_BEHAVIOR[dialect].supportsGinFamily) {
|
|
13603
14647
|
return {
|
|
13604
14648
|
indexName: declaration.name,
|
|
13605
14649
|
entity: declaration.entity,
|
|
@@ -13621,9 +14665,11 @@ async function materializeRelationalIndex(declaration, backend, dialect, ddlOpti
|
|
|
13621
14665
|
driftLabel: "Index",
|
|
13622
14666
|
run: async () => {
|
|
13623
14667
|
if (declaration.method === "trigram") {
|
|
13624
|
-
await backend.executeDdl(
|
|
14668
|
+
await requireDefined(backend.executeDdl)(
|
|
14669
|
+
"CREATE EXTENSION IF NOT EXISTS pg_trgm;"
|
|
14670
|
+
);
|
|
13625
14671
|
}
|
|
13626
|
-
await backend.executeDdl(ddl);
|
|
14672
|
+
await requireDefined(backend.executeDdl)(ddl);
|
|
13627
14673
|
},
|
|
13628
14674
|
existingByStatusKey,
|
|
13629
14675
|
physicalRebuildPreload: invalidLeftovers
|
|
@@ -13671,7 +14717,7 @@ async function materializeVectorIndex(declaration, backend, graphId, schemaVersi
|
|
|
13671
14717
|
efConstruction: declaration.indexParams.efConstruction,
|
|
13672
14718
|
...declaration.indexParams.lists === void 0 ? {} : { lists: declaration.indexParams.lists }
|
|
13673
14719
|
},
|
|
13674
|
-
concurrent: backend.dialect
|
|
14720
|
+
concurrent: INDEX_DIALECT_BEHAVIOR[backend.dialect].concurrentBuilds
|
|
13675
14721
|
};
|
|
13676
14722
|
return materializeOne(declaration, backend, graphId, schemaVersion, {
|
|
13677
14723
|
// Compound status-table key for vector entries. Pgvector creates
|
|
@@ -13682,13 +14728,15 @@ async function materializeVectorIndex(declaration, backend, graphId, schemaVersi
|
|
|
13682
14728
|
statusKey: vectorStatusKey(graphId, declaration.name),
|
|
13683
14729
|
signature,
|
|
13684
14730
|
driftLabel: "Vector index",
|
|
13685
|
-
run: () => backend.createVectorIndex(params),
|
|
14731
|
+
run: () => requireDefined(backend.createVectorIndex)(params),
|
|
13686
14732
|
existingByStatusKey,
|
|
13687
14733
|
physicalRebuildPreload: invalidLeftovers
|
|
13688
14734
|
});
|
|
13689
14735
|
}
|
|
13690
14736
|
async function materializeOne(declaration, backend, graphId, schemaVersion, action) {
|
|
13691
|
-
const recordIndexMaterialization =
|
|
14737
|
+
const recordIndexMaterialization = requireDefined(
|
|
14738
|
+
backend.recordIndexMaterialization
|
|
14739
|
+
);
|
|
13692
14740
|
const { statusKey, signature, driftLabel, run, existingByStatusKey } = action;
|
|
13693
14741
|
const statusOverride = statusKey === declaration.name ? void 0 : { statusName: statusKey };
|
|
13694
14742
|
const settled = await settleAgainstExisting(
|
|
@@ -13760,7 +14808,7 @@ async function settleAgainstExisting(existing, declaration, backend, graphId, sc
|
|
|
13760
14808
|
const error = new Error(
|
|
13761
14809
|
`${driftLabel} "${declaration.name}" already materialized with a different signature (recorded by graph "${existing.graphId}" at version ${existing.schemaVersion}). Drop the index manually and retry, or rename the new declaration.`
|
|
13762
14810
|
);
|
|
13763
|
-
await backend.recordIndexMaterialization(
|
|
14811
|
+
await requireDefined(backend.recordIndexMaterialization)(
|
|
13764
14812
|
buildAttempt({
|
|
13765
14813
|
declaration,
|
|
13766
14814
|
graphId,
|
|
@@ -13776,11 +14824,13 @@ async function settleAgainstExisting(existing, declaration, backend, graphId, sc
|
|
|
13776
14824
|
async function materializeWithClaim(declaration, backend, graphId, schemaVersion, action) {
|
|
13777
14825
|
const { statusKey, signature, driftLabel, run } = action;
|
|
13778
14826
|
const statusOverride = statusKey === declaration.name ? void 0 : { statusName: statusKey };
|
|
13779
|
-
const recordIndexMaterialization =
|
|
14827
|
+
const recordIndexMaterialization = requireDefined(
|
|
14828
|
+
backend.recordIndexMaterialization
|
|
14829
|
+
);
|
|
13780
14830
|
const token = `${statusKey}:${nowIso()}:${Math.floor(performance.now() * 1e3)}`;
|
|
13781
14831
|
const deadline = Date.now() + CLAIM_WAIT_TIMEOUT_MS;
|
|
13782
14832
|
for (; ; ) {
|
|
13783
|
-
const claimed = await backend.claimIndexMaterialization({
|
|
14833
|
+
const claimed = await requireDefined(backend.claimIndexMaterialization)({
|
|
13784
14834
|
indexName: statusKey,
|
|
13785
14835
|
graphId,
|
|
13786
14836
|
entity: declaration.entity,
|
|
@@ -13804,7 +14854,9 @@ async function materializeWithClaim(declaration, backend, graphId, schemaVersion
|
|
|
13804
14854
|
continue;
|
|
13805
14855
|
}
|
|
13806
14856
|
try {
|
|
13807
|
-
const fresh = await backend.getIndexMaterialization(
|
|
14857
|
+
const fresh = await requireDefined(backend.getIndexMaterialization)(
|
|
14858
|
+
statusKey
|
|
14859
|
+
);
|
|
13808
14860
|
const settled = await settleAgainstExisting(
|
|
13809
14861
|
fresh,
|
|
13810
14862
|
declaration,
|
|
@@ -13858,7 +14910,7 @@ async function materializeWithClaim(declaration, backend, graphId, schemaVersion
|
|
|
13858
14910
|
}
|
|
13859
14911
|
} finally {
|
|
13860
14912
|
try {
|
|
13861
|
-
await backend.releaseIndexMaterializationClaim({
|
|
14913
|
+
await requireDefined(backend.releaseIndexMaterializationClaim)({
|
|
13862
14914
|
indexName: statusKey,
|
|
13863
14915
|
token
|
|
13864
14916
|
});
|
|
@@ -13872,7 +14924,9 @@ async function materializeWithClaim(declaration, backend, graphId, schemaVersion
|
|
|
13872
14924
|
}
|
|
13873
14925
|
}
|
|
13874
14926
|
async function hasInvalidIndexLeftover(backend, physicalIndexName) {
|
|
13875
|
-
if (backend.dialect
|
|
14927
|
+
if (!INDEX_DIALECT_BEHAVIOR[backend.dialect].hasInvalidIndexState) {
|
|
14928
|
+
return false;
|
|
14929
|
+
}
|
|
13876
14930
|
const rows = await backend.execute(
|
|
13877
14931
|
asCompiledRowsSql(sql`
|
|
13878
14932
|
SELECT NOT i.indisvalid AS invalid
|
|
@@ -13885,7 +14939,7 @@ async function hasInvalidIndexLeftover(backend, physicalIndexName) {
|
|
|
13885
14939
|
return rows[0]?.invalid === true;
|
|
13886
14940
|
}
|
|
13887
14941
|
async function preloadInvalidIndexLeftovers(backend, physicalIndexNames) {
|
|
13888
|
-
if (backend.dialect
|
|
14942
|
+
if (!INDEX_DIALECT_BEHAVIOR[backend.dialect].hasInvalidIndexState || physicalIndexNames.length === 0) {
|
|
13889
14943
|
return /* @__PURE__ */ new Set();
|
|
13890
14944
|
}
|
|
13891
14945
|
const { invalid } = await preloadPhysicalIndexStates(
|
|
@@ -13896,55 +14950,69 @@ async function preloadInvalidIndexLeftovers(backend, physicalIndexNames) {
|
|
|
13896
14950
|
}
|
|
13897
14951
|
async function preloadExistingTables(backend, tableNames) {
|
|
13898
14952
|
if (tableNames.length === 0) return /* @__PURE__ */ new Set();
|
|
13899
|
-
|
|
13900
|
-
|
|
13901
|
-
|
|
13902
|
-
|
|
13903
|
-
|
|
13904
|
-
|
|
13905
|
-
|
|
13906
|
-
|
|
13907
|
-
|
|
13908
|
-
|
|
13909
|
-
|
|
14953
|
+
switch (backend.dialect) {
|
|
14954
|
+
case "postgres": {
|
|
14955
|
+
const rows = await backend.execute(
|
|
14956
|
+
asCompiledRowsSql(sql`
|
|
14957
|
+
SELECT c.relname AS name
|
|
14958
|
+
FROM pg_class c
|
|
14959
|
+
WHERE c.relname IN (${sqlValueList(tableNames)})
|
|
14960
|
+
AND c.relkind IN ('r', 'p')
|
|
14961
|
+
AND pg_catalog.pg_table_is_visible(c.oid)
|
|
14962
|
+
`)
|
|
14963
|
+
);
|
|
14964
|
+
return new Set(rows.map((row) => row.name));
|
|
14965
|
+
}
|
|
14966
|
+
case "sqlite": {
|
|
14967
|
+
const rows = await backend.execute(
|
|
14968
|
+
asCompiledRowsSql(sql`
|
|
14969
|
+
SELECT name
|
|
14970
|
+
FROM sqlite_master
|
|
14971
|
+
WHERE type = 'table'
|
|
14972
|
+
AND name IN (${sqlValueList(tableNames)})
|
|
14973
|
+
`)
|
|
14974
|
+
);
|
|
14975
|
+
return new Set(rows.map((row) => row.name));
|
|
14976
|
+
}
|
|
14977
|
+
default: {
|
|
14978
|
+
return backend.dialect;
|
|
14979
|
+
}
|
|
13910
14980
|
}
|
|
13911
|
-
const rows = await backend.execute(
|
|
13912
|
-
asCompiledRowsSql(sql`
|
|
13913
|
-
SELECT name
|
|
13914
|
-
FROM sqlite_master
|
|
13915
|
-
WHERE type = 'table'
|
|
13916
|
-
AND name IN (${sqlValueList(tableNames)})
|
|
13917
|
-
`)
|
|
13918
|
-
);
|
|
13919
|
-
return new Set(rows.map((row) => row.name));
|
|
13920
14981
|
}
|
|
13921
14982
|
async function preloadPhysicalIndexStates(backend, physicalIndexNames) {
|
|
13922
14983
|
const valid = /* @__PURE__ */ new Set();
|
|
13923
14984
|
const invalid = /* @__PURE__ */ new Set();
|
|
13924
14985
|
if (physicalIndexNames.length === 0) return { valid, invalid };
|
|
13925
|
-
|
|
13926
|
-
|
|
13927
|
-
|
|
13928
|
-
|
|
13929
|
-
|
|
13930
|
-
|
|
13931
|
-
|
|
13932
|
-
|
|
13933
|
-
|
|
13934
|
-
|
|
13935
|
-
|
|
13936
|
-
|
|
14986
|
+
switch (backend.dialect) {
|
|
14987
|
+
case "postgres": {
|
|
14988
|
+
const rows = await backend.execute(
|
|
14989
|
+
asCompiledRowsSql(sql`
|
|
14990
|
+
SELECT c.relname AS name, i.indisvalid AS valid
|
|
14991
|
+
FROM pg_class c
|
|
14992
|
+
JOIN pg_index i ON i.indexrelid = c.oid
|
|
14993
|
+
WHERE c.relname IN (${sqlValueList(physicalIndexNames)})
|
|
14994
|
+
AND pg_catalog.pg_table_is_visible(c.oid)
|
|
14995
|
+
`)
|
|
14996
|
+
);
|
|
14997
|
+
for (const row of rows) (row.valid ? valid : invalid).add(row.name);
|
|
14998
|
+
return { valid, invalid };
|
|
14999
|
+
}
|
|
15000
|
+
case "sqlite": {
|
|
15001
|
+
const rows = await backend.execute(
|
|
15002
|
+
asCompiledRowsSql(sql`
|
|
15003
|
+
SELECT name
|
|
15004
|
+
FROM sqlite_master
|
|
15005
|
+
WHERE type = 'index'
|
|
15006
|
+
AND name IN (${sqlValueList(physicalIndexNames)})
|
|
15007
|
+
`)
|
|
15008
|
+
);
|
|
15009
|
+
for (const row of rows) valid.add(row.name);
|
|
15010
|
+
return { valid, invalid };
|
|
15011
|
+
}
|
|
15012
|
+
default: {
|
|
15013
|
+
return backend.dialect;
|
|
15014
|
+
}
|
|
13937
15015
|
}
|
|
13938
|
-
const rows = await backend.execute(
|
|
13939
|
-
asCompiledRowsSql(sql`
|
|
13940
|
-
SELECT name
|
|
13941
|
-
FROM sqlite_master
|
|
13942
|
-
WHERE type = 'index'
|
|
13943
|
-
AND name IN (${sqlValueList(physicalIndexNames)})
|
|
13944
|
-
`)
|
|
13945
|
-
);
|
|
13946
|
-
for (const row of rows) valid.add(row.name);
|
|
13947
|
-
return { valid, invalid };
|
|
13948
15016
|
}
|
|
13949
15017
|
async function dropInvalidIndexLeftover(backend, physicalIndexName) {
|
|
13950
15018
|
if (backend.executeDdl === void 0) return;
|
|
@@ -13984,10 +15052,10 @@ async function preloadMaterializations(backend, statusKeys) {
|
|
|
13984
15052
|
for (const row of rows2) map.set(row.indexName, row);
|
|
13985
15053
|
return map;
|
|
13986
15054
|
}
|
|
13987
|
-
const getOne = backend.getIndexMaterialization;
|
|
15055
|
+
const getOne = requireDefined(backend.getIndexMaterialization);
|
|
13988
15056
|
const rows = await Promise.all(statusKeys.map((key) => getOne(key)));
|
|
13989
15057
|
for (const [index, row] of rows.entries()) {
|
|
13990
|
-
if (row !== void 0) map.set(statusKeys[index], row);
|
|
15058
|
+
if (row !== void 0) map.set(requireDefined(statusKeys[index]), row);
|
|
13991
15059
|
}
|
|
13992
15060
|
return map;
|
|
13993
15061
|
}
|
|
@@ -14024,7 +15092,7 @@ async function materializeSystemIndexes(context, options = {}) {
|
|
|
14024
15092
|
backend,
|
|
14025
15093
|
backend.ensureIndexMaterializationsTable
|
|
14026
15094
|
);
|
|
14027
|
-
const concurrent = backend.dialect
|
|
15095
|
+
const concurrent = INDEX_DIALECT_BEHAVIOR[backend.dialect].concurrentBuilds;
|
|
14028
15096
|
const candidates = SYSTEM_INDEX_DECLARATIONS.map((declaration) => {
|
|
14029
15097
|
const physicalTable = resolveSystemIndexTableName(
|
|
14030
15098
|
declaration.table,
|
|
@@ -14091,7 +15159,7 @@ async function materializeSystemIndexes(context, options = {}) {
|
|
|
14091
15159
|
statusKey: candidate.name,
|
|
14092
15160
|
signature,
|
|
14093
15161
|
driftLabel: "System index",
|
|
14094
|
-
run: () => backend.executeDdl(ddl),
|
|
15162
|
+
run: () => requireDefined(backend.executeDdl)(ddl),
|
|
14095
15163
|
existingByStatusKey,
|
|
14096
15164
|
physicalRebuildPreload,
|
|
14097
15165
|
freshNeedsPhysicalRebuild: async (physicalIndexName) => {
|
|
@@ -14128,6 +15196,8 @@ async function computeIndexSignature(dialect, targetTableName, declaration) {
|
|
|
14128
15196
|
const json = JSON.stringify(hashable, sortedReplacer);
|
|
14129
15197
|
return sha256Hex(json, 16);
|
|
14130
15198
|
}
|
|
15199
|
+
|
|
15200
|
+
// src/store/materialize-removals.ts
|
|
14131
15201
|
var ENTITY_KINDS = ["node", "edge"];
|
|
14132
15202
|
function buildPendingKindRemoval(args) {
|
|
14133
15203
|
return { ...args, removedAt: void 0, error: void 0 };
|
|
@@ -14185,7 +15255,7 @@ async function reconcilePendingRemovals(context) {
|
|
|
14185
15255
|
}
|
|
14186
15256
|
const marker = backend.getReconciliationMarker === void 0 ? void 0 : await backend.getReconciliationMarker(graphId);
|
|
14187
15257
|
if (marker !== void 0 && marker >= activeRow.version) return;
|
|
14188
|
-
const allRemovals = await (backend.getAllKindRemovals === void 0 ? backend.getPendingKindRemovals(graphId) : backend.getAllKindRemovals(graphId));
|
|
15258
|
+
const allRemovals = await (backend.getAllKindRemovals === void 0 ? requireDefined(backend.getPendingKindRemovals)(graphId) : backend.getAllKindRemovals(graphId));
|
|
14189
15259
|
const recorded = new Set(
|
|
14190
15260
|
allRemovals.map(
|
|
14191
15261
|
(row) => kindRemovalKey(row.entity, row.kindName, row.schemaVersion)
|
|
@@ -14244,7 +15314,7 @@ function kindRemovalKey(entity, kindName, version) {
|
|
|
14244
15314
|
return `${entity}|${kindName}|${version}`;
|
|
14245
15315
|
}
|
|
14246
15316
|
async function materializeOne2(row, ctx) {
|
|
14247
|
-
const recordKindRemoval = ctx.backend.recordKindRemoval;
|
|
15317
|
+
const recordKindRemoval = requireDefined(ctx.backend.recordKindRemoval);
|
|
14248
15318
|
try {
|
|
14249
15319
|
await closeRecordedAndDeleteLiveRows(ctx, row);
|
|
14250
15320
|
await Promise.all(buildEmbeddingTableCleanup(ctx, row));
|
|
@@ -14324,7 +15394,9 @@ async function executeDeleteStatements(target, statements) {
|
|
|
14324
15394
|
if (target.executeStatement !== void 0) {
|
|
14325
15395
|
await Promise.all(
|
|
14326
15396
|
statements.map(
|
|
14327
|
-
(statement) => target.executeStatement(
|
|
15397
|
+
(statement) => requireDefined(target.executeStatement)(
|
|
15398
|
+
asCompiledStatementSql(sql.raw(statement))
|
|
15399
|
+
)
|
|
14328
15400
|
)
|
|
14329
15401
|
);
|
|
14330
15402
|
return;
|
|
@@ -14336,13 +15408,13 @@ async function executeDeleteStatements(target, statements) {
|
|
|
14336
15408
|
);
|
|
14337
15409
|
}
|
|
14338
15410
|
await Promise.all(
|
|
14339
|
-
statements.map((statement) => target.executeDdl(statement))
|
|
15411
|
+
statements.map((statement) => requireDefined(target.executeDdl)(statement))
|
|
14340
15412
|
);
|
|
14341
15413
|
}
|
|
14342
15414
|
function buildEmbeddingTableCleanup(ctx, row) {
|
|
14343
15415
|
const vectorStrategy = ctx.backend.vectorStrategy;
|
|
14344
15416
|
if (vectorStrategy === void 0) return [];
|
|
14345
|
-
const executeDdl = ctx.backend.executeDdl;
|
|
15417
|
+
const executeDdl = requireDefined(ctx.backend.executeDdl);
|
|
14346
15418
|
const cleanup = (async () => {
|
|
14347
15419
|
const slots = await resolveRemovedKindEmbeddingSlots(ctx.backend, row);
|
|
14348
15420
|
await Promise.all(
|
|
@@ -14976,7 +16048,7 @@ async function executeEdgeFindByEndpoints(ctx, kind, fromKind, fromId, toKind, t
|
|
|
14976
16048
|
...options?.asOf !== void 0 && { asOf: options.asOf }
|
|
14977
16049
|
});
|
|
14978
16050
|
if (candidateRows.length === 0) return void 0;
|
|
14979
|
-
if (matchOn.length === 0) return rowToEdge(candidateRows[0]);
|
|
16051
|
+
if (matchOn.length === 0) return rowToEdge(requireDefined(candidateRows[0]));
|
|
14980
16052
|
const { liveRow } = findMatchingEdge(candidateRows, matchOn, props);
|
|
14981
16053
|
return liveRow === void 0 ? void 0 : rowToEdge(liveRow);
|
|
14982
16054
|
}
|
|
@@ -15209,7 +16281,10 @@ async function executeEdgeBulkGetOrCreateByEndpoints(ctx, kind, items, backend,
|
|
|
15209
16281
|
found[entry2.index] = { edge: rowToEdge(entry2.row), action: "found" };
|
|
15210
16282
|
}
|
|
15211
16283
|
for (const { index, sourceIndex } of probe.duplicateOf) {
|
|
15212
|
-
found[index] = {
|
|
16284
|
+
found[index] = {
|
|
16285
|
+
edge: requireDefined(found[sourceIndex]).edge,
|
|
16286
|
+
action: "found"
|
|
16287
|
+
};
|
|
15213
16288
|
}
|
|
15214
16289
|
return found;
|
|
15215
16290
|
}
|
|
@@ -15228,7 +16303,7 @@ async function executeEdgeBulkGetOrCreateByEndpoints(ctx, kind, items, backend,
|
|
|
15228
16303
|
);
|
|
15229
16304
|
for (const [batchIndex, entry2] of toCreate.entries()) {
|
|
15230
16305
|
results[entry2.index] = {
|
|
15231
|
-
edge: createdEdges[batchIndex],
|
|
16306
|
+
edge: requireDefined(createdEdges[batchIndex]),
|
|
15232
16307
|
action: "created"
|
|
15233
16308
|
};
|
|
15234
16309
|
}
|
|
@@ -15270,13 +16345,16 @@ async function executeEdgeBulkGetOrCreateByEndpoints(ctx, kind, items, backend,
|
|
|
15270
16345
|
}
|
|
15271
16346
|
}
|
|
15272
16347
|
for (const { index, sourceIndex } of duplicateOf) {
|
|
15273
|
-
const sourceResult = results[sourceIndex];
|
|
16348
|
+
const sourceResult = requireDefined(results[sourceIndex]);
|
|
15274
16349
|
results[index] = { edge: sourceResult.edge, action: "found" };
|
|
15275
16350
|
}
|
|
15276
16351
|
return results;
|
|
15277
16352
|
});
|
|
15278
16353
|
}
|
|
16354
|
+
|
|
16355
|
+
// src/store/recorded-read-service.ts
|
|
15279
16356
|
var RECORDED_POINT_READ_FIXED_BIND_PARAMS = 8;
|
|
16357
|
+
var RECORDED_SCAN_LIMIT = 1e3;
|
|
15280
16358
|
function recordedPointReadIdChunk(backend) {
|
|
15281
16359
|
const budget = recordedBindParamBudget(backend);
|
|
15282
16360
|
return Math.max(1, budget - RECORDED_POINT_READ_FIXED_BIND_PARAMS);
|
|
@@ -15291,12 +16369,13 @@ function withRelationsPrecondition(backend, promise, surface) {
|
|
|
15291
16369
|
);
|
|
15292
16370
|
}
|
|
15293
16371
|
function createRecordedReadBackend(backend, surface) {
|
|
15294
|
-
|
|
16372
|
+
const projectedBackend = createGraphBackendProjection(backend);
|
|
16373
|
+
return createBackendOverlay(projectedBackend, {
|
|
15295
16374
|
execute: (query) => withRelationsPrecondition(backend, backend.execute(query), surface),
|
|
15296
16375
|
...backend.executeRaw === void 0 ? {} : {
|
|
15297
16376
|
executeRaw: (sqlText, params) => withRelationsPrecondition(
|
|
15298
16377
|
backend,
|
|
15299
|
-
backend.executeRaw(sqlText, params),
|
|
16378
|
+
requireDefined(backend.executeRaw)(sqlText, params),
|
|
15300
16379
|
surface
|
|
15301
16380
|
)
|
|
15302
16381
|
}
|
|
@@ -15320,7 +16399,7 @@ function recordedTemporalFilter(backend, coordinate, tableAlias) {
|
|
|
15320
16399
|
}
|
|
15321
16400
|
function recordedRelationInvariantError(params) {
|
|
15322
16401
|
return new ConfigurationError(
|
|
15323
|
-
"Recorded relation invariant violation: more than one recorded row matched the requested
|
|
16402
|
+
"Recorded relation invariant violation: more than one recorded row matched the requested read.",
|
|
15324
16403
|
{
|
|
15325
16404
|
code: "RECORDED_RELATION_INVARIANT_VIOLATION",
|
|
15326
16405
|
graphId: params.graphId,
|
|
@@ -15336,6 +16415,57 @@ function recordedRelationInvariantError(params) {
|
|
|
15336
16415
|
}
|
|
15337
16416
|
);
|
|
15338
16417
|
}
|
|
16418
|
+
function validateRecordedScanLimit(limit) {
|
|
16419
|
+
if (limit === void 0) return RECORDED_SCAN_LIMIT;
|
|
16420
|
+
if (!Number.isInteger(limit) || limit <= 0 || limit > RECORDED_SCAN_LIMIT) {
|
|
16421
|
+
throw new ValidationError(
|
|
16422
|
+
`Recorded scan limit must be an integer between 1 and ${RECORDED_SCAN_LIMIT}, got: ${String(limit)}`,
|
|
16423
|
+
{
|
|
16424
|
+
issues: [
|
|
16425
|
+
{
|
|
16426
|
+
path: "limit",
|
|
16427
|
+
message: `Must be an integer between 1 and ${RECORDED_SCAN_LIMIT}.`
|
|
16428
|
+
}
|
|
16429
|
+
]
|
|
16430
|
+
}
|
|
16431
|
+
);
|
|
16432
|
+
}
|
|
16433
|
+
return limit;
|
|
16434
|
+
}
|
|
16435
|
+
function recordedScanCursorScope(graphId, entity, kind, coordinate) {
|
|
16436
|
+
return JSON.stringify([
|
|
16437
|
+
"recorded-scan",
|
|
16438
|
+
graphId,
|
|
16439
|
+
entity,
|
|
16440
|
+
kind,
|
|
16441
|
+
coordinate.valid.mode,
|
|
16442
|
+
coordinate.valid.asOf,
|
|
16443
|
+
coordinate.recorded?.asOf
|
|
16444
|
+
]);
|
|
16445
|
+
}
|
|
16446
|
+
function invalidRecordedScanCursor() {
|
|
16447
|
+
return new ValidationError(
|
|
16448
|
+
"Recorded scan cursor does not match this graph, collection, or temporal coordinate.",
|
|
16449
|
+
{
|
|
16450
|
+
issues: [
|
|
16451
|
+
{
|
|
16452
|
+
path: "after",
|
|
16453
|
+
message: "Use a cursor returned by the same recorded collection scan."
|
|
16454
|
+
}
|
|
16455
|
+
]
|
|
16456
|
+
}
|
|
16457
|
+
);
|
|
16458
|
+
}
|
|
16459
|
+
function decodeRecordedScanCursor(cursor, expectedScope) {
|
|
16460
|
+
const decoded = decodeCursor(cursor);
|
|
16461
|
+
if (decoded.d !== "f" || decoded.cols.length !== 1 || decoded.cols[0] !== expectedScope || decoded.vals.length !== 1 || typeof decoded.vals[0] !== "string") {
|
|
16462
|
+
throw invalidRecordedScanCursor();
|
|
16463
|
+
}
|
|
16464
|
+
return decoded.vals[0];
|
|
16465
|
+
}
|
|
16466
|
+
function encodeRecordedScanCursor(id, scope) {
|
|
16467
|
+
return encodeCursor({ v: 1, d: "f", vals: [id], cols: [scope] });
|
|
16468
|
+
}
|
|
15339
16469
|
function createRecordedReadService(params) {
|
|
15340
16470
|
const {
|
|
15341
16471
|
graphId,
|
|
@@ -15345,6 +16475,11 @@ function createRecordedReadService(params) {
|
|
|
15345
16475
|
mapRecordedEdgeRow
|
|
15346
16476
|
} = params;
|
|
15347
16477
|
const recordedSchema = recordedReadBinding === void 0 ? void 0 : recordedReadSqlSchema(recordedReadBinding);
|
|
16478
|
+
function schemaForRecordedRead(surface) {
|
|
16479
|
+
return recordedSchema ?? recordedReadSqlSchema(
|
|
16480
|
+
requireRecordedReadBinding(recordedReadBinding, surface)
|
|
16481
|
+
);
|
|
16482
|
+
}
|
|
15348
16483
|
async function recordedGetByIds(read) {
|
|
15349
16484
|
const { table, alias, kind, ids, coordinate, toEntity, entity } = read;
|
|
15350
16485
|
if (ids.length === 0) return [];
|
|
@@ -15387,10 +16522,51 @@ function createRecordedReadService(params) {
|
|
|
15387
16522
|
}
|
|
15388
16523
|
return ids.map((id) => byId.get(id));
|
|
15389
16524
|
}
|
|
16525
|
+
async function recordedScan(scan) {
|
|
16526
|
+
const { table, alias, kind, coordinate, options, toEntity, entity } = scan;
|
|
16527
|
+
const limit = validateRecordedScanLimit(options?.limit);
|
|
16528
|
+
const scope = recordedScanCursorScope(graphId, entity, kind, coordinate);
|
|
16529
|
+
const after = options?.after === void 0 ? void 0 : decodeRecordedScanCursor(options.after, scope);
|
|
16530
|
+
const aliasSql = sql.raw(alias);
|
|
16531
|
+
const temporalFilter = recordedTemporalFilter(backend, coordinate, alias);
|
|
16532
|
+
const rows = await withRelationsPrecondition(
|
|
16533
|
+
backend,
|
|
16534
|
+
backend.execute(
|
|
16535
|
+
asCompiledRowsSql(sql`
|
|
16536
|
+
SELECT * FROM ${table} ${aliasSql}
|
|
16537
|
+
WHERE ${aliasSql}.graph_id = ${graphId}
|
|
16538
|
+
AND ${aliasSql}.kind = ${kind}
|
|
16539
|
+
${after === void 0 ? sql.raw("") : sql`AND ${aliasSql}.id > ${after}`}
|
|
16540
|
+
AND ${temporalFilter}
|
|
16541
|
+
ORDER BY ${aliasSql}.id ASC, ${aliasSql}.recorded_from ASC
|
|
16542
|
+
LIMIT ${limit + 1}
|
|
16543
|
+
`)
|
|
16544
|
+
),
|
|
16545
|
+
"recorded-scan"
|
|
16546
|
+
);
|
|
16547
|
+
const entities = rows.map((row) => toEntity(row));
|
|
16548
|
+
for (let index = 1; index < entities.length; index += 1) {
|
|
16549
|
+
const previous = requireDefined(entities[index - 1]);
|
|
16550
|
+
const current = requireDefined(entities[index]);
|
|
16551
|
+
if (previous.id !== current.id) continue;
|
|
16552
|
+
throw recordedRelationInvariantError({
|
|
16553
|
+
graphId,
|
|
16554
|
+
entity,
|
|
16555
|
+
kind,
|
|
16556
|
+
id: current.id,
|
|
16557
|
+
coordinate
|
|
16558
|
+
});
|
|
16559
|
+
}
|
|
16560
|
+
const hasNextPage = entities.length > limit;
|
|
16561
|
+
const data = hasNextPage ? entities.slice(0, limit) : entities;
|
|
16562
|
+
return {
|
|
16563
|
+
data,
|
|
16564
|
+
nextCursor: hasNextPage ? encodeRecordedScanCursor(requireDefined(data.at(-1)).id, scope) : void 0,
|
|
16565
|
+
hasNextPage
|
|
16566
|
+
};
|
|
16567
|
+
}
|
|
15390
16568
|
function nodeGetByIds(kind, ids, coordinate) {
|
|
15391
|
-
const schema =
|
|
15392
|
-
requireRecordedReadBinding(recordedReadBinding, "recorded-point-read")
|
|
15393
|
-
);
|
|
16569
|
+
const schema = schemaForRecordedRead("recorded-point-read");
|
|
15394
16570
|
return recordedGetByIds({
|
|
15395
16571
|
entity: "node",
|
|
15396
16572
|
table: schema.nodesTable,
|
|
@@ -15402,9 +16578,7 @@ function createRecordedReadService(params) {
|
|
|
15402
16578
|
});
|
|
15403
16579
|
}
|
|
15404
16580
|
function edgeGetByIds(kind, ids, coordinate) {
|
|
15405
|
-
const schema =
|
|
15406
|
-
requireRecordedReadBinding(recordedReadBinding, "recorded-point-read")
|
|
15407
|
-
);
|
|
16581
|
+
const schema = schemaForRecordedRead("recorded-point-read");
|
|
15408
16582
|
return recordedGetByIds({
|
|
15409
16583
|
entity: "edge",
|
|
15410
16584
|
table: schema.edgesTable,
|
|
@@ -15415,6 +16589,30 @@ function createRecordedReadService(params) {
|
|
|
15415
16589
|
toEntity: (row) => rowToEdge(mapRecordedEdgeRow(row))
|
|
15416
16590
|
});
|
|
15417
16591
|
}
|
|
16592
|
+
function nodeScan(kind, coordinate, options) {
|
|
16593
|
+
const schema = schemaForRecordedRead("recorded-scan");
|
|
16594
|
+
return recordedScan({
|
|
16595
|
+
entity: "node",
|
|
16596
|
+
table: schema.nodesTable,
|
|
16597
|
+
alias: "n",
|
|
16598
|
+
kind,
|
|
16599
|
+
coordinate,
|
|
16600
|
+
options,
|
|
16601
|
+
toEntity: (row) => rowToNode(mapRecordedNodeRow(row))
|
|
16602
|
+
});
|
|
16603
|
+
}
|
|
16604
|
+
function edgeScan(kind, coordinate, options) {
|
|
16605
|
+
const schema = schemaForRecordedRead("recorded-scan");
|
|
16606
|
+
return recordedScan({
|
|
16607
|
+
entity: "edge",
|
|
16608
|
+
table: schema.edgesTable,
|
|
16609
|
+
alias: "e",
|
|
16610
|
+
kind,
|
|
16611
|
+
coordinate,
|
|
16612
|
+
options,
|
|
16613
|
+
toEntity: (row) => rowToEdge(mapRecordedEdgeRow(row))
|
|
16614
|
+
});
|
|
16615
|
+
}
|
|
15418
16616
|
return {
|
|
15419
16617
|
backendForCoordinate(coordinate, surface) {
|
|
15420
16618
|
if (coordinate.recorded === void 0) return backend;
|
|
@@ -15426,11 +16624,13 @@ function createRecordedReadService(params) {
|
|
|
15426
16624
|
return results[0];
|
|
15427
16625
|
},
|
|
15428
16626
|
nodeGetByIds,
|
|
16627
|
+
nodeScan,
|
|
15429
16628
|
async edgeGetById(kind, id, coordinate) {
|
|
15430
16629
|
const results = await edgeGetByIds(kind, [id], coordinate);
|
|
15431
16630
|
return results[0];
|
|
15432
16631
|
},
|
|
15433
|
-
edgeGetByIds
|
|
16632
|
+
edgeGetByIds,
|
|
16633
|
+
edgeScan
|
|
15434
16634
|
};
|
|
15435
16635
|
}
|
|
15436
16636
|
|
|
@@ -15604,9 +16804,6 @@ function wrapTransactionCollections(nodes, edges, recorder) {
|
|
|
15604
16804
|
};
|
|
15605
16805
|
}
|
|
15606
16806
|
|
|
15607
|
-
// src/store/types.ts
|
|
15608
|
-
var AUTO_REFRESH_STATISTICS_ROW_THRESHOLD = 1e3;
|
|
15609
|
-
|
|
15610
16807
|
// src/store/store.ts
|
|
15611
16808
|
var UNKNOWN_SCHEMA_METADATA = Object.freeze({
|
|
15612
16809
|
schemaVersion: void 0,
|
|
@@ -15633,8 +16830,12 @@ var CAUGHT_UP_VERB_DETAILS = {
|
|
|
15633
16830
|
code: "REEMBED_BEFORE_INITIALIZE"
|
|
15634
16831
|
}
|
|
15635
16832
|
};
|
|
16833
|
+
var ROW_MAPPER_CONFIGS = {
|
|
16834
|
+
postgres: POSTGRES_ROW_MAPPER_CONFIG,
|
|
16835
|
+
sqlite: SQLITE_ROW_MAPPER_CONFIG
|
|
16836
|
+
};
|
|
15636
16837
|
function rowMapperConfigFor(backend) {
|
|
15637
|
-
return backend.dialect
|
|
16838
|
+
return ROW_MAPPER_CONFIGS[backend.dialect];
|
|
15638
16839
|
}
|
|
15639
16840
|
function asError(error) {
|
|
15640
16841
|
return error instanceof Error ? error : new Error(String(error));
|
|
@@ -15649,7 +16850,25 @@ function transactionOutcome(result, recorder, recordedByGraph, graphId) {
|
|
|
15649
16850
|
)
|
|
15650
16851
|
};
|
|
15651
16852
|
}
|
|
15652
|
-
|
|
16853
|
+
function overlayPropertyDescriptors(base, overlay) {
|
|
16854
|
+
return Object.defineProperties(Object.create(Reflect.getPrototypeOf(base)), {
|
|
16855
|
+
...Object.getOwnPropertyDescriptors(base),
|
|
16856
|
+
...Object.getOwnPropertyDescriptors(overlay)
|
|
16857
|
+
});
|
|
16858
|
+
}
|
|
16859
|
+
function defineUnavailableSqlGuard(context, guard) {
|
|
16860
|
+
Object.defineProperty(context, "sql", {
|
|
16861
|
+
configurable: false,
|
|
16862
|
+
enumerable: true,
|
|
16863
|
+
get: guard
|
|
16864
|
+
});
|
|
16865
|
+
}
|
|
16866
|
+
function syncStoreReplacementRef(ref, replacement) {
|
|
16867
|
+
if (ref === void 0) return;
|
|
16868
|
+
ref.current = replacement;
|
|
16869
|
+
}
|
|
16870
|
+
var StoreImplementation = class _StoreImplementation {
|
|
16871
|
+
[STORE_RUNTIME];
|
|
15653
16872
|
#graph;
|
|
15654
16873
|
/**
|
|
15655
16874
|
* Bare backend for DDL, vector-storage, and bulk-materialization work that must
|
|
@@ -15657,6 +16876,7 @@ var Store = class _Store {
|
|
|
15657
16876
|
*/
|
|
15658
16877
|
#baseBackend;
|
|
15659
16878
|
#backend;
|
|
16879
|
+
#adapterBackend;
|
|
15660
16880
|
#captureEnabled;
|
|
15661
16881
|
#revisionTrackingEnabled;
|
|
15662
16882
|
#revisionOrigin;
|
|
@@ -15676,9 +16896,10 @@ var Store = class _Store {
|
|
|
15676
16896
|
#edgeCollections;
|
|
15677
16897
|
#algorithms;
|
|
15678
16898
|
#search;
|
|
15679
|
-
constructor(graph, backend, options, schemaMetadata) {
|
|
16899
|
+
constructor(graph, backend, options, schemaMetadata, adapterBackend) {
|
|
15680
16900
|
this.#graph = graph;
|
|
15681
16901
|
this.#baseBackend = asRawBackend(backend);
|
|
16902
|
+
this.#adapterBackend = adapterBackend;
|
|
15682
16903
|
this.#captureEnabled = options?.history === true;
|
|
15683
16904
|
this.#revisionTrackingEnabled = this.#captureEnabled || options?.revisionTracking === true;
|
|
15684
16905
|
if (this.#revisionTrackingEnabled) {
|
|
@@ -15715,6 +16936,23 @@ var Store = class _Store {
|
|
|
15715
16936
|
this.#defaultTraversalExpansion = options?.queryDefaults?.traversalExpansion ?? "inverse";
|
|
15716
16937
|
this.#options = options;
|
|
15717
16938
|
this.#schemaMetadata = schemaMetadata ?? UNKNOWN_SCHEMA_METADATA;
|
|
16939
|
+
this[STORE_RUNTIME] = {
|
|
16940
|
+
backend: this.#backend,
|
|
16941
|
+
sealedQuery: (coordinate) => this.sealedQuery(coordinate),
|
|
16942
|
+
recordedNodeGetById: (kind, id, coordinate) => this.recordedNodeGetById(kind, id, coordinate),
|
|
16943
|
+
recordedNodeGetByIds: (kind, ids, coordinate) => this.recordedNodeGetByIds(kind, ids, coordinate),
|
|
16944
|
+
recordedNodeScan: (kind, coordinate, options2) => this.recordedNodeScan(kind, coordinate, options2),
|
|
16945
|
+
recordedEdgeGetById: (kind, id, coordinate) => this.recordedEdgeGetById(kind, id, coordinate),
|
|
16946
|
+
recordedEdgeGetByIds: (kind, ids, coordinate) => this.recordedEdgeGetByIds(kind, ids, coordinate),
|
|
16947
|
+
recordedEdgeScan: (kind, coordinate, options2) => this.recordedEdgeScan(kind, coordinate, options2),
|
|
16948
|
+
subgraphAtCoordinate: (rootId, subgraphOptions) => this.subgraphAtCoordinate(rootId, subgraphOptions),
|
|
16949
|
+
algorithmsAtCoordinate: (coordinate) => this.algorithmsAtCoordinate(coordinate)
|
|
16950
|
+
};
|
|
16951
|
+
Object.defineProperty(this, STORE_RUNTIME, {
|
|
16952
|
+
configurable: false,
|
|
16953
|
+
enumerable: false,
|
|
16954
|
+
writable: false
|
|
16955
|
+
});
|
|
15718
16956
|
}
|
|
15719
16957
|
// === Accessors ===
|
|
15720
16958
|
/** The graph definition */
|
|
@@ -15725,14 +16963,14 @@ var Store = class _Store {
|
|
|
15725
16963
|
get graphId() {
|
|
15726
16964
|
return this.#graph.id;
|
|
15727
16965
|
}
|
|
16966
|
+
/** Runtime features available through this store's configured backend. */
|
|
16967
|
+
get capabilities() {
|
|
16968
|
+
return this.#baseBackend.capabilities;
|
|
16969
|
+
}
|
|
15728
16970
|
/** The kind registry for ontology lookups */
|
|
15729
16971
|
get registry() {
|
|
15730
16972
|
return this.#registry;
|
|
15731
16973
|
}
|
|
15732
|
-
/** The database backend */
|
|
15733
|
-
get backend() {
|
|
15734
|
-
return this.#backend;
|
|
15735
|
-
}
|
|
15736
16974
|
/**
|
|
15737
16975
|
* Whether recorded-time capture is enabled for this store.
|
|
15738
16976
|
*
|
|
@@ -15937,7 +17175,7 @@ var Store = class _Store {
|
|
|
15937
17175
|
*/
|
|
15938
17176
|
getNodePropsSchema(kind) {
|
|
15939
17177
|
if (!Object.hasOwn(this.#graph.nodes, kind)) return void 0;
|
|
15940
|
-
return this.#graph.nodes[kind].type.schema;
|
|
17178
|
+
return requireDefined(this.#graph.nodes[kind]).type.schema;
|
|
15941
17179
|
}
|
|
15942
17180
|
/**
|
|
15943
17181
|
* Returns the Zod props schema for the given node kind. Throws
|
|
@@ -15958,7 +17196,7 @@ var Store = class _Store {
|
|
|
15958
17196
|
*/
|
|
15959
17197
|
getEdgePropsSchema(kind) {
|
|
15960
17198
|
if (!Object.hasOwn(this.#graph.edges, kind)) return void 0;
|
|
15961
|
-
return this.#graph.edges[kind].type.schema;
|
|
17199
|
+
return requireDefined(this.#graph.edges[kind]).type.schema;
|
|
15962
17200
|
}
|
|
15963
17201
|
/**
|
|
15964
17202
|
* Returns the Zod props schema for the given edge kind. Throws
|
|
@@ -16182,6 +17420,10 @@ var Store = class _Store {
|
|
|
16182
17420
|
async recordedNodeGetByIds(kind, ids, coordinate) {
|
|
16183
17421
|
return this.#recordedReads.nodeGetByIds(kind, ids, coordinate);
|
|
16184
17422
|
}
|
|
17423
|
+
/** @internal Bounded recorded-time node enumeration for RecordedStoreView. */
|
|
17424
|
+
async recordedNodeScan(kind, coordinate, options) {
|
|
17425
|
+
return this.#recordedReads.nodeScan(kind, coordinate, options);
|
|
17426
|
+
}
|
|
16185
17427
|
/**
|
|
16186
17428
|
* Internal seam for {@link RecordedStoreView}: reconstruct an edge point read
|
|
16187
17429
|
* from the recorded-time relation while preserving live getById behavior.
|
|
@@ -16200,6 +17442,10 @@ var Store = class _Store {
|
|
|
16200
17442
|
async recordedEdgeGetByIds(kind, ids, coordinate) {
|
|
16201
17443
|
return this.#recordedReads.edgeGetByIds(kind, ids, coordinate);
|
|
16202
17444
|
}
|
|
17445
|
+
/** @internal Bounded recorded-time edge enumeration for RecordedStoreView. */
|
|
17446
|
+
async recordedEdgeScan(kind, coordinate, options) {
|
|
17447
|
+
return this.#recordedReads.edgeScan(kind, coordinate, options);
|
|
17448
|
+
}
|
|
16203
17449
|
// === Temporal Views ===
|
|
16204
17450
|
/**
|
|
16205
17451
|
* Returns a read-only {@link StoreView} pinned to a valid-time instant.
|
|
@@ -16572,15 +17818,21 @@ var Store = class _Store {
|
|
|
16572
17818
|
edges,
|
|
16573
17819
|
// No real transaction: `tx.sql` is absent and there is no atomicity.
|
|
16574
17820
|
sqlAvailability: "unavailable",
|
|
16575
|
-
backend: this.#backend,
|
|
16576
|
-
|
|
16577
|
-
|
|
16578
|
-
|
|
16579
|
-
|
|
16580
|
-
|
|
16581
|
-
|
|
16582
|
-
|
|
17821
|
+
backend: createTransactionReadBackend(this.#backend),
|
|
17822
|
+
[TRANSACTION_RUNTIME]: {
|
|
17823
|
+
backend: this.#backend,
|
|
17824
|
+
runNodeOperationHooks: (operation, kind, id, hookedFunction) => this.#withOperationHooks(
|
|
17825
|
+
this.#createOperationContext(operation, "node", kind, id),
|
|
17826
|
+
hookedFunction
|
|
17827
|
+
)
|
|
17828
|
+
},
|
|
17829
|
+
getNodeCollection: (kind) => this.#resolveDynamicNodeCollection(nodes, kind)
|
|
16583
17830
|
};
|
|
17831
|
+
Object.defineProperty(fallbackContext, TRANSACTION_RUNTIME, {
|
|
17832
|
+
configurable: false,
|
|
17833
|
+
enumerable: false,
|
|
17834
|
+
writable: false
|
|
17835
|
+
});
|
|
16584
17836
|
const result = await invoke(
|
|
16585
17837
|
receiptRecorder === void 0 ? fallbackContext : this.#attachMeasure(fallbackContext)
|
|
16586
17838
|
);
|
|
@@ -16593,15 +17845,19 @@ var Store = class _Store {
|
|
|
16593
17845
|
recordedByGraph = instants;
|
|
16594
17846
|
}) : backendOptions;
|
|
16595
17847
|
try {
|
|
16596
|
-
const
|
|
16597
|
-
|
|
16598
|
-
|
|
16599
|
-
|
|
16600
|
-
|
|
16601
|
-
|
|
16602
|
-
|
|
16603
|
-
|
|
16604
|
-
|
|
17848
|
+
const run = async (txBackend, nativeTransaction) => invoke(
|
|
17849
|
+
this.#buildTransactionContext(
|
|
17850
|
+
txBackend,
|
|
17851
|
+
nativeTransaction,
|
|
17852
|
+
runHooks,
|
|
17853
|
+
receiptRecorder
|
|
17854
|
+
)
|
|
17855
|
+
);
|
|
17856
|
+
const result = this.#captureEnabled || this.#adapterBackend === void 0 ? await this.#backend.transaction(
|
|
17857
|
+
(txBackend) => run(txBackend, void 0),
|
|
17858
|
+
transactionOptions
|
|
17859
|
+
) : await this.#adapterBackend.transactionWithNative(
|
|
17860
|
+
(txBackend, nativeTransaction) => run(txBackend, nativeTransaction),
|
|
16605
17861
|
transactionOptions
|
|
16606
17862
|
);
|
|
16607
17863
|
for (const outcome of pending) {
|
|
@@ -16618,12 +17874,86 @@ var Store = class _Store {
|
|
|
16618
17874
|
throw error;
|
|
16619
17875
|
}
|
|
16620
17876
|
}
|
|
17877
|
+
/**
|
|
17878
|
+
* Adopts a caller-owned, already-open Drizzle transaction so the graph
|
|
17879
|
+
* store and the caller's relational writes commit or roll back as one
|
|
17880
|
+
* Postgres/SQLite transaction (#134).
|
|
17881
|
+
*
|
|
17882
|
+
* Use this when the **relational layer owns the transaction**: the
|
|
17883
|
+
* caller has opened a transaction and needs TypeGraph writes enlisted
|
|
17884
|
+
* on the *same* connection. Unlike {@link transaction}, this opens no
|
|
17885
|
+
* transaction — the caller's transaction is the single commit/rollback
|
|
17886
|
+
* boundary.
|
|
17887
|
+
*
|
|
17888
|
+
* `withTransaction` is driver-agnostic; how the caller opens the
|
|
17889
|
+
* transaction is not. **Async drivers** (node-postgres,
|
|
17890
|
+
* `neon-serverless` Pool, libsql) use `db.transaction(async …)`.
|
|
17891
|
+
* **Synchronous `better-sqlite3`** cannot — its driver rejects an
|
|
17892
|
+
* `async` transaction callback (`Transaction function cannot return a
|
|
17893
|
+
* promise`) and the async continuation would run outside the
|
|
17894
|
+
* rolled-back transaction — so the caller opens the transaction with
|
|
17895
|
+
* explicit `BEGIN`/`COMMIT`/`ROLLBACK` on the single connection
|
|
17896
|
+
* instead. See the "Cross-Store Transactions" recipe for both shapes.
|
|
17897
|
+
*
|
|
17898
|
+
* The returned context reuses this store's already-resolved
|
|
17899
|
+
* schema/registry: it runs **no** schema bootstrap, `evolve`, or
|
|
17900
|
+
* migration, and emits **no DDL** inside the caller's transaction.
|
|
17901
|
+
* Fulltext operations assert the durable materialization marker (a
|
|
17902
|
+
* cached SELECT) and throw {@link StoreNotInitializedError} on a
|
|
17903
|
+
* missing/stale/failed marker rather than migrating mid-transaction —
|
|
17904
|
+
* so boot the parent store via `createAdapterStoreWithSchema` once at
|
|
17905
|
+
* startup.
|
|
17906
|
+
*
|
|
17907
|
+
* @example
|
|
17908
|
+
* ```typescript
|
|
17909
|
+
* // Async driver (Postgres / libsql):
|
|
17910
|
+
* await db.transaction(async (sqlTx) => {
|
|
17911
|
+
* const connector = await createConnectorRow(sqlTx, input); // Drizzle
|
|
17912
|
+
* const txStore = store.withTransaction(sqlTx);
|
|
17913
|
+
* await txStore.nodes.ArtifactSource.create({ // TypeGraph
|
|
17914
|
+
* connectorId: connector.id,
|
|
17915
|
+
* });
|
|
17916
|
+
* }); // one COMMIT / ROLLBACK across both layers
|
|
17917
|
+
* ```
|
|
17918
|
+
*
|
|
17919
|
+
* **The caller owns the connection — don't overlap writes on it.** The graph
|
|
17920
|
+
* store and your Drizzle writes share the one connection the caller's
|
|
17921
|
+
* transaction pinned. TypeGraph serializes the statements *its* collections
|
|
17922
|
+
* issue, but your raw Drizzle statements (and any graph write run alongside
|
|
17923
|
+
* them) are yours to sequence: a `Promise.all` mixing the two races two
|
|
17924
|
+
* queries on that connection — the overlap Postgres removes in `pg@9`. Await
|
|
17925
|
+
* each write before starting the next.
|
|
17926
|
+
*
|
|
17927
|
+
* Not available when the store was created with `{ history: true }`: a
|
|
17928
|
+
* caller-owned transaction context would let writes happen after capture has
|
|
17929
|
+
* lost its flush point. {@link AdapterHistoryStore} omits this method, while
|
|
17930
|
+
* the runtime guard still throws `ConfigurationError` if the public contract
|
|
17931
|
+
* is bypassed
|
|
17932
|
+
* (`RECORDED_CAPTURE_REQUIRES_CALLBACK_TRANSACTION`) if the check is
|
|
17933
|
+
* suppressed. Use {@link AdapterStore.withRecordedTransaction} on a history-enabled
|
|
17934
|
+
* store, which adopts the same external transaction but flushes recorded-time
|
|
17935
|
+
* capture before the caller commits.
|
|
17936
|
+
*
|
|
17937
|
+
* @throws {ConfigurationError} when the store has history capture enabled
|
|
17938
|
+
* (use {@link AdapterStore.withRecordedTransaction} instead), or when the backend
|
|
17939
|
+
* cannot adopt an external transaction — either it is not a Drizzle
|
|
17940
|
+
* Postgres/SQLite backend, or `backend.capabilities.transactions` is `false`
|
|
17941
|
+
* (`drizzle-orm/neon-http`, Cloudflare D1, SQLite
|
|
17942
|
+
* `transactionMode: "none"`). A non-atomic fallback is deliberately
|
|
17943
|
+
* not offered here: the caller's relational write *would* still
|
|
17944
|
+
* commit, defeating the purpose of cross-store atomicity.
|
|
17945
|
+
* @throws {StoreNotInitializedError} at point of use, when a fulltext
|
|
17946
|
+
* operation on the returned context observes a missing/stale/failed
|
|
17947
|
+
* durable materialization marker (parent store not booted via
|
|
17948
|
+
* `createAdapterStoreWithSchema`). Rolls back the caller's transaction
|
|
17949
|
+
* without emitting any DDL.
|
|
17950
|
+
*/
|
|
16621
17951
|
withTransaction(externalTx) {
|
|
16622
17952
|
if (this.#captureEnabled) {
|
|
16623
17953
|
throw recordedCaptureRequiresCallbackTransactionError();
|
|
16624
17954
|
}
|
|
16625
|
-
const adopt = this.#
|
|
16626
|
-
if (
|
|
17955
|
+
const adopt = this.#adapterBackend?.adoptTransaction;
|
|
17956
|
+
if (adopt === void 0) {
|
|
16627
17957
|
throw new ConfigurationError(
|
|
16628
17958
|
"This backend cannot adopt an external transaction for cross-store atomicity. adoptTransaction is provided only by the Drizzle Postgres/SQLite backends with transaction support. Check backend.capabilities.transactions, or run the relational and graph writes as separate transactions with manual compensation.",
|
|
16629
17959
|
{ capability: "adoptTransaction" }
|
|
@@ -16632,8 +17962,8 @@ var Store = class _Store {
|
|
|
16632
17962
|
return this.#buildTransactionContext(adopt(externalTx), externalTx);
|
|
16633
17963
|
}
|
|
16634
17964
|
async withRecordedTransaction(externalTx, fn) {
|
|
16635
|
-
const adopt = this.#
|
|
16636
|
-
if (
|
|
17965
|
+
const adopt = this.#adapterBackend?.adoptTransaction;
|
|
17966
|
+
if (adopt === void 0) {
|
|
16637
17967
|
throw new ConfigurationError(
|
|
16638
17968
|
"This backend cannot adopt an external transaction for recorded-time capture.",
|
|
16639
17969
|
{ capability: "adoptTransaction" },
|
|
@@ -16694,16 +18024,17 @@ var Store = class _Store {
|
|
|
16694
18024
|
context.edges,
|
|
16695
18025
|
scopeRecorder
|
|
16696
18026
|
);
|
|
16697
|
-
const scoped = this.#attachMeasure(
|
|
16698
|
-
|
|
16699
|
-
|
|
16700
|
-
|
|
16701
|
-
|
|
16702
|
-
|
|
18027
|
+
const scoped = this.#attachMeasure(
|
|
18028
|
+
overlayPropertyDescriptors(context, {
|
|
18029
|
+
nodes,
|
|
18030
|
+
edges,
|
|
18031
|
+
getNodeCollection: (kind) => this.#resolveDynamicNodeCollection(nodes, kind)
|
|
18032
|
+
})
|
|
18033
|
+
);
|
|
16703
18034
|
const result = await fn(scoped);
|
|
16704
18035
|
return { result, receipt: scopeRecorder.snapshot() };
|
|
16705
18036
|
};
|
|
16706
|
-
return
|
|
18037
|
+
return overlayPropertyDescriptors(context, { measure });
|
|
16707
18038
|
}
|
|
16708
18039
|
/**
|
|
16709
18040
|
* Builds the `{ nodes, edges, sql }` projection bound to a
|
|
@@ -16715,7 +18046,7 @@ var Store = class _Store {
|
|
|
16715
18046
|
* (#140); when history capture is enabled it is replaced with a fail-loud
|
|
16716
18047
|
* guard because raw graph writes would bypass recorded-time capture.
|
|
16717
18048
|
*/
|
|
16718
|
-
#buildTransactionContext(txBackend,
|
|
18049
|
+
#buildTransactionContext(txBackend, sql2, runHooks = this.#immediateHookRunner(), receiptRecorder) {
|
|
16719
18050
|
const txNodeOperations = {
|
|
16720
18051
|
...this.#buildNodeOperations(this.#createNodeOperationContext(runHooks)),
|
|
16721
18052
|
createQuery: () => this.#createQueryForBackend(txBackend),
|
|
@@ -16749,19 +18080,39 @@ var Store = class _Store {
|
|
|
16749
18080
|
));
|
|
16750
18081
|
}
|
|
16751
18082
|
const getNodeCollection = (kind) => this.#resolveDynamicNodeCollection(nodes, kind);
|
|
16752
|
-
const sqlAvailability = this.#captureEnabled ? "history" : this.#revisionTrackingEnabled ? "revisionTracking" : sql19 === void 0 ? "unavailable" : "available";
|
|
16753
18083
|
const base = {
|
|
16754
18084
|
nodes,
|
|
16755
18085
|
edges,
|
|
16756
|
-
|
|
16757
|
-
backend: txBackend,
|
|
16758
|
-
getNodeCollection
|
|
16759
|
-
runNodeOperationHooks
|
|
16760
|
-
};
|
|
16761
|
-
const withSql = sql19 === void 0 ? base : {
|
|
16762
|
-
...base,
|
|
16763
|
-
sql: this.#captureEnabled ? createHistoryUnsafeSqlRef() : this.#revisionTrackingEnabled ? createRevisionTrackingUnsafeSqlRef() : sql19
|
|
18086
|
+
backend: createTransactionReadBackend(txBackend),
|
|
18087
|
+
[TRANSACTION_RUNTIME]: { backend: txBackend, runNodeOperationHooks },
|
|
18088
|
+
getNodeCollection
|
|
16764
18089
|
};
|
|
18090
|
+
let withSql;
|
|
18091
|
+
if (this.#captureEnabled) {
|
|
18092
|
+
withSql = {
|
|
18093
|
+
...base,
|
|
18094
|
+
sqlAvailability: "history"
|
|
18095
|
+
};
|
|
18096
|
+
defineUnavailableSqlGuard(withSql, () => throwHistoryUnsafeSqlAccess());
|
|
18097
|
+
} else if (this.#revisionTrackingEnabled) {
|
|
18098
|
+
withSql = {
|
|
18099
|
+
...base,
|
|
18100
|
+
sqlAvailability: "revisionTracking"
|
|
18101
|
+
};
|
|
18102
|
+
defineUnavailableSqlGuard(
|
|
18103
|
+
withSql,
|
|
18104
|
+
() => throwRevisionTrackingUnsafeSqlAccess()
|
|
18105
|
+
);
|
|
18106
|
+
} else if (sql2 === void 0) {
|
|
18107
|
+
withSql = { ...base, sqlAvailability: "unavailable" };
|
|
18108
|
+
} else {
|
|
18109
|
+
withSql = { ...base, sql: sql2, sqlAvailability: "available" };
|
|
18110
|
+
}
|
|
18111
|
+
Object.defineProperty(withSql, TRANSACTION_RUNTIME, {
|
|
18112
|
+
configurable: false,
|
|
18113
|
+
enumerable: false,
|
|
18114
|
+
writable: false
|
|
18115
|
+
});
|
|
16765
18116
|
return receiptRecorder === void 0 ? withSql : this.#attachMeasure(withSql);
|
|
16766
18117
|
}
|
|
16767
18118
|
// === Graph Lifecycle ===
|
|
@@ -16913,7 +18264,7 @@ var Store = class _Store {
|
|
|
16913
18264
|
const merged = mergeGraphExtension(baseline, extension);
|
|
16914
18265
|
if (merged === baseline) {
|
|
16915
18266
|
if (baseline === this.#graph) {
|
|
16916
|
-
|
|
18267
|
+
syncStoreReplacementRef(options?.ref, this);
|
|
16917
18268
|
if (options?.eager !== void 0) {
|
|
16918
18269
|
await this.#runEagerOrThrow(this, options.eager);
|
|
16919
18270
|
}
|
|
@@ -17260,7 +18611,7 @@ var Store = class _Store {
|
|
|
17260
18611
|
const plan = planRemovals(baseline, names);
|
|
17261
18612
|
if (plan.removedNodeKinds.length === 0 && plan.removedEdgeKinds.length === 0) {
|
|
17262
18613
|
if (baseline === this.#graph) {
|
|
17263
|
-
|
|
18614
|
+
syncStoreReplacementRef(options?.ref, this);
|
|
17264
18615
|
return this;
|
|
17265
18616
|
}
|
|
17266
18617
|
return this.#cloneWithGraph(
|
|
@@ -17351,7 +18702,7 @@ var Store = class _Store {
|
|
|
17351
18702
|
}
|
|
17352
18703
|
if (setsEqual(nextSet, baseline.deprecatedKinds)) {
|
|
17353
18704
|
if (baseline === this.#graph) {
|
|
17354
|
-
|
|
18705
|
+
syncStoreReplacementRef(options?.ref, this);
|
|
17355
18706
|
return this;
|
|
17356
18707
|
}
|
|
17357
18708
|
return this.#cloneWithGraph(
|
|
@@ -17443,13 +18794,18 @@ var Store = class _Store {
|
|
|
17443
18794
|
return nonEmpty;
|
|
17444
18795
|
}
|
|
17445
18796
|
#cloneWithGraph(graph, ref, schemaMetadata = this.#schemaMetadata) {
|
|
17446
|
-
const next = new
|
|
18797
|
+
const next = this.#adapterBackend === void 0 ? new _StoreImplementation(
|
|
17447
18798
|
graph,
|
|
17448
18799
|
this.#baseBackend,
|
|
17449
18800
|
this.#options,
|
|
17450
18801
|
schemaMetadata
|
|
18802
|
+
) : new AdapterStoreImplementation(
|
|
18803
|
+
graph,
|
|
18804
|
+
this.#adapterBackend,
|
|
18805
|
+
this.#options,
|
|
18806
|
+
schemaMetadata
|
|
17451
18807
|
);
|
|
17452
|
-
|
|
18808
|
+
syncStoreReplacementRef(ref, next);
|
|
17453
18809
|
return next;
|
|
17454
18810
|
}
|
|
17455
18811
|
/**
|
|
@@ -17591,8 +18947,100 @@ var Store = class _Store {
|
|
|
17591
18947
|
);
|
|
17592
18948
|
}
|
|
17593
18949
|
};
|
|
18950
|
+
var AdapterStoreImplementation = class extends StoreImplementation {
|
|
18951
|
+
backend;
|
|
18952
|
+
constructor(graph, backend, options, schemaMetadata) {
|
|
18953
|
+
super(graph, backend, options, schemaMetadata, backend);
|
|
18954
|
+
this.backend = options?.history === true ? createHistoryStoreBackendProjection(this[STORE_RUNTIME].backend) : Object.freeze(
|
|
18955
|
+
createGraphBackendProjection(this[STORE_RUNTIME].backend)
|
|
18956
|
+
);
|
|
18957
|
+
}
|
|
18958
|
+
async evolve(extension, options) {
|
|
18959
|
+
return this.#withAdapterReplacement(
|
|
18960
|
+
options?.ref,
|
|
18961
|
+
(replacementRef) => super.evolve(
|
|
18962
|
+
extension,
|
|
18963
|
+
options?.eager === void 0 ? { ref: replacementRef } : { eager: options.eager, ref: replacementRef }
|
|
18964
|
+
)
|
|
18965
|
+
);
|
|
18966
|
+
}
|
|
18967
|
+
async deprecateKinds(names, options) {
|
|
18968
|
+
return this.#withAdapterReplacement(
|
|
18969
|
+
options?.ref,
|
|
18970
|
+
(replacementRef) => super.deprecateKinds(names, { ref: replacementRef })
|
|
18971
|
+
);
|
|
18972
|
+
}
|
|
18973
|
+
async undeprecateKinds(names, options) {
|
|
18974
|
+
return this.#withAdapterReplacement(
|
|
18975
|
+
options?.ref,
|
|
18976
|
+
(replacementRef) => super.undeprecateKinds(names, { ref: replacementRef })
|
|
18977
|
+
);
|
|
18978
|
+
}
|
|
18979
|
+
async removeKinds(names, options) {
|
|
18980
|
+
return this.#withAdapterReplacement(
|
|
18981
|
+
options?.ref,
|
|
18982
|
+
(replacementRef) => super.removeKinds(
|
|
18983
|
+
names,
|
|
18984
|
+
options?.eager === void 0 ? { ref: replacementRef } : { eager: options.eager, ref: replacementRef }
|
|
18985
|
+
)
|
|
18986
|
+
);
|
|
18987
|
+
}
|
|
18988
|
+
async #withAdapterReplacement(ref, operation) {
|
|
18989
|
+
const tracked = createTrackedReplacementRef(this);
|
|
18990
|
+
try {
|
|
18991
|
+
await operation(tracked.ref);
|
|
18992
|
+
} catch (error) {
|
|
18993
|
+
if (tracked.wasReplaced()) {
|
|
18994
|
+
const replacement2 = requireAdapterStoreImplementation(tracked.ref.current);
|
|
18995
|
+
syncAdapterReplacementRef(ref, replacement2);
|
|
18996
|
+
}
|
|
18997
|
+
throw error;
|
|
18998
|
+
}
|
|
18999
|
+
const replacement = requireAdapterStoreImplementation(tracked.ref.current);
|
|
19000
|
+
syncAdapterReplacementRef(ref, replacement);
|
|
19001
|
+
return replacement;
|
|
19002
|
+
}
|
|
19003
|
+
};
|
|
19004
|
+
function createTrackedReplacementRef(initial) {
|
|
19005
|
+
let current = initial;
|
|
19006
|
+
let replaced = false;
|
|
19007
|
+
return {
|
|
19008
|
+
ref: {
|
|
19009
|
+
get current() {
|
|
19010
|
+
return current;
|
|
19011
|
+
},
|
|
19012
|
+
set current(next) {
|
|
19013
|
+
current = next;
|
|
19014
|
+
replaced = true;
|
|
19015
|
+
}
|
|
19016
|
+
},
|
|
19017
|
+
wasReplaced: () => replaced
|
|
19018
|
+
};
|
|
19019
|
+
}
|
|
19020
|
+
function syncAdapterReplacementRef(ref, replacement) {
|
|
19021
|
+
if (ref === void 0) return;
|
|
19022
|
+
ref.current = replacement;
|
|
19023
|
+
}
|
|
19024
|
+
function requireAdapterStoreImplementation(store) {
|
|
19025
|
+
if (isAdapterStoreImplementation(store)) return store;
|
|
19026
|
+
throw new ConfigurationError(
|
|
19027
|
+
"Adapter store replacement lost its adapter capabilities.",
|
|
19028
|
+
{ code: "ADAPTER_STORE_REPLACEMENT_INVARIANT" }
|
|
19029
|
+
);
|
|
19030
|
+
}
|
|
19031
|
+
function isAdapterStoreImplementation(store) {
|
|
19032
|
+
return store instanceof AdapterStoreImplementation;
|
|
19033
|
+
}
|
|
19034
|
+
function asAdapterStoreSurface(store) {
|
|
19035
|
+
return store;
|
|
19036
|
+
}
|
|
17594
19037
|
function createStore(graph, backend, options) {
|
|
17595
|
-
return new
|
|
19038
|
+
return new StoreImplementation(graph, backend, options);
|
|
19039
|
+
}
|
|
19040
|
+
function createAdapterStore(graph, backend, options) {
|
|
19041
|
+
return asAdapterStoreSurface(
|
|
19042
|
+
new AdapterStoreImplementation(graph, backend, options)
|
|
19043
|
+
);
|
|
17596
19044
|
}
|
|
17597
19045
|
function isKnownEdgeKind(graph, name) {
|
|
17598
19046
|
return Object.hasOwn(graph.edges, name);
|
|
@@ -17637,6 +19085,18 @@ async function materializeVectorContributions(backend, graph) {
|
|
|
17637
19085
|
}
|
|
17638
19086
|
}
|
|
17639
19087
|
async function createStoreWithSchema(graph, backend, options) {
|
|
19088
|
+
const prepared = await prepareStoreWithSchema(graph, backend, options);
|
|
19089
|
+
return [
|
|
19090
|
+
new StoreImplementation(
|
|
19091
|
+
prepared.graph,
|
|
19092
|
+
backend,
|
|
19093
|
+
options,
|
|
19094
|
+
prepared.schemaMetadata
|
|
19095
|
+
),
|
|
19096
|
+
prepared.result
|
|
19097
|
+
];
|
|
19098
|
+
}
|
|
19099
|
+
async function prepareStoreWithSchema(graph, backend, options) {
|
|
17640
19100
|
const {
|
|
17641
19101
|
graph: merged,
|
|
17642
19102
|
activeRow,
|
|
@@ -17651,13 +19111,25 @@ async function createStoreWithSchema(graph, backend, options) {
|
|
|
17651
19111
|
if (options?.systemIndexes !== "skip") {
|
|
17652
19112
|
await materializeSystemIndexesOnBoot(backend, merged.id, result);
|
|
17653
19113
|
}
|
|
17654
|
-
|
|
17655
|
-
merged,
|
|
17656
|
-
|
|
17657
|
-
|
|
17658
|
-
|
|
17659
|
-
|
|
17660
|
-
|
|
19114
|
+
return {
|
|
19115
|
+
graph: merged,
|
|
19116
|
+
result,
|
|
19117
|
+
schemaMetadata: schemaMetadataForResult(activeRow, result)
|
|
19118
|
+
};
|
|
19119
|
+
}
|
|
19120
|
+
async function createAdapterStoreWithSchema(graph, backend, options) {
|
|
19121
|
+
const prepared = await prepareStoreWithSchema(graph, backend, options);
|
|
19122
|
+
return [
|
|
19123
|
+
asAdapterStoreSurface(
|
|
19124
|
+
new AdapterStoreImplementation(
|
|
19125
|
+
prepared.graph,
|
|
19126
|
+
backend,
|
|
19127
|
+
options,
|
|
19128
|
+
prepared.schemaMetadata
|
|
19129
|
+
)
|
|
19130
|
+
),
|
|
19131
|
+
prepared.result
|
|
19132
|
+
];
|
|
17661
19133
|
}
|
|
17662
19134
|
async function materializeSystemIndexesOnBoot(backend, graphId, result) {
|
|
17663
19135
|
if (result.status === "breaking") return;
|
|
@@ -17684,20 +19156,44 @@ async function materializeSystemIndexesOnBoot(backend, graphId, result) {
|
|
|
17684
19156
|
}
|
|
17685
19157
|
}
|
|
17686
19158
|
async function createVerifiedStore(graph, backend, options) {
|
|
19159
|
+
const prepared = await prepareVerifiedStore(graph, backend);
|
|
19160
|
+
return [
|
|
19161
|
+
new StoreImplementation(
|
|
19162
|
+
prepared.graph,
|
|
19163
|
+
backend,
|
|
19164
|
+
options,
|
|
19165
|
+
prepared.schemaMetadata
|
|
19166
|
+
),
|
|
19167
|
+
prepared.result
|
|
19168
|
+
];
|
|
19169
|
+
}
|
|
19170
|
+
async function prepareVerifiedStore(graph, backend) {
|
|
17687
19171
|
const {
|
|
17688
19172
|
graph: merged,
|
|
17689
19173
|
activeRow,
|
|
17690
19174
|
result
|
|
17691
19175
|
} = await loadAndVerifyGraph(backend, graph);
|
|
17692
|
-
|
|
17693
|
-
merged,
|
|
17694
|
-
|
|
17695
|
-
|
|
17696
|
-
|
|
17697
|
-
|
|
17698
|
-
|
|
19176
|
+
return {
|
|
19177
|
+
graph: merged,
|
|
19178
|
+
result,
|
|
19179
|
+
schemaMetadata: schemaMetadataFromRow(activeRow)
|
|
19180
|
+
};
|
|
19181
|
+
}
|
|
19182
|
+
async function createVerifiedAdapterStore(graph, backend, options) {
|
|
19183
|
+
const prepared = await prepareVerifiedStore(graph, backend);
|
|
19184
|
+
return [
|
|
19185
|
+
asAdapterStoreSurface(
|
|
19186
|
+
new AdapterStoreImplementation(
|
|
19187
|
+
prepared.graph,
|
|
19188
|
+
backend,
|
|
19189
|
+
options,
|
|
19190
|
+
prepared.schemaMetadata
|
|
19191
|
+
)
|
|
19192
|
+
),
|
|
19193
|
+
prepared.result
|
|
19194
|
+
];
|
|
17699
19195
|
}
|
|
17700
19196
|
|
|
17701
|
-
export { ExecutableAggregateQuery, ExecutableQuery, MAX_EXPLICIT_RECURSIVE_DEPTH, MAX_RECURSIVE_DEPTH, PreparedQuery, QueryBuilder, RecordedStoreView, StoreSearch, StoreView, UnionableQuery, avg, composeFragments, count, countDistinct, countDistinctEdges, countEdges, createFragment, createQueryBuilder, createStore, createStoreWithSchema, createVerifiedStore, defineSubgraphProject, field, having, havingEq, havingGt, havingGte, havingLt, havingLte, limitFragment, max, min, offsetFragment, orderByFragment, sum };
|
|
17702
|
-
//# sourceMappingURL=chunk-
|
|
17703
|
-
//# sourceMappingURL=chunk-
|
|
19197
|
+
export { ExecutableAggregateQuery, ExecutableQuery, MAX_EXPLICIT_RECURSIVE_DEPTH, MAX_RECURSIVE_DEPTH, PreparedQuery, QueryBuilder, RecordedStoreView, StoreSearch, StoreView, UnionableQuery, avg, composeFragments, count, countDistinct, countDistinctEdges, countEdges, createAdapterStore, createAdapterStoreWithSchema, createFragment, createQueryBuilder, createStore, createStoreWithSchema, createVerifiedAdapterStore, createVerifiedStore, defineSubgraphProject, field, having, havingEq, havingGt, havingGte, havingLt, havingLte, limitFragment, max, min, offsetFragment, orderByFragment, sum };
|
|
19198
|
+
//# sourceMappingURL=chunk-CBK2IVI2.js.map
|
|
19199
|
+
//# sourceMappingURL=chunk-CBK2IVI2.js.map
|