@nicia-ai/typegraph 0.50.0 → 0.51.1
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 -0
- package/dist/backend/drizzle/indexes.cjs +10 -8
- package/dist/backend/drizzle/indexes.d.cts +1 -1
- package/dist/backend/drizzle/indexes.d.ts +1 -1
- package/dist/backend/drizzle/indexes.js +6 -4
- package/dist/backend/index.cjs +183 -50
- package/dist/backend/index.d.cts +90 -4
- package/dist/backend/index.d.ts +90 -4
- package/dist/backend/index.js +6 -9
- package/dist/backend/postgres/index.cjs +30 -28
- package/dist/backend/postgres/index.d.cts +7 -7
- package/dist/backend/postgres/index.d.ts +7 -7
- package/dist/backend/postgres/index.js +16 -14
- package/dist/backend/postgres/pglite-store.cjs +6 -62
- package/dist/backend/postgres/pglite-store.cjs.map +1 -1
- package/dist/backend/postgres/pglite-store.d.cts +8 -8
- package/dist/backend/postgres/pglite-store.d.ts +8 -8
- package/dist/backend/postgres/pglite-store.js +6 -62
- package/dist/backend/postgres/pglite-store.js.map +1 -1
- package/dist/backend/postgres/pglite.cjs +18 -16
- package/dist/backend/postgres/pglite.d.cts +3 -3
- package/dist/backend/postgres/pglite.d.ts +3 -3
- package/dist/backend/postgres/pglite.js +17 -15
- package/dist/backend/sqlite/index.cjs +27 -25
- package/dist/backend/sqlite/index.d.cts +7 -7
- package/dist/backend/sqlite/index.d.ts +7 -7
- package/dist/backend/sqlite/index.js +14 -12
- package/dist/backend/sqlite/libsql.cjs +21 -19
- package/dist/backend/sqlite/libsql.cjs.map +1 -1
- package/dist/backend/sqlite/libsql.d.cts +3 -3
- package/dist/backend/sqlite/libsql.d.ts +3 -3
- package/dist/backend/sqlite/libsql.js +16 -14
- package/dist/backend/sqlite/libsql.js.map +1 -1
- package/dist/backend/sqlite/local-store.cjs +8 -64
- package/dist/backend/sqlite/local-store.cjs.map +1 -1
- package/dist/backend/sqlite/local-store.d.cts +8 -8
- package/dist/backend/sqlite/local-store.d.ts +8 -8
- package/dist/backend/sqlite/local-store.js +7 -64
- package/dist/backend/sqlite/local-store.js.map +1 -1
- package/dist/backend/sqlite/local.cjs +22 -19
- package/dist/backend/sqlite/local.d.cts +3 -3
- package/dist/backend/sqlite/local.d.ts +3 -3
- package/dist/backend/sqlite/local.js +18 -15
- package/dist/{chunk-TUVD4DFR.cjs → chunk-2CVDZCXH.cjs} +122 -51
- package/dist/chunk-2CVDZCXH.cjs.map +1 -0
- package/dist/{chunk-I5C6OTKR.js → chunk-2DWTBNSH.js} +3 -3
- package/dist/{chunk-I5C6OTKR.js.map → chunk-2DWTBNSH.js.map} +1 -1
- package/dist/{chunk-C76WFIVZ.cjs → chunk-2KCTP3U2.cjs} +180 -127
- package/dist/chunk-2KCTP3U2.cjs.map +1 -0
- package/dist/{chunk-BYBDM423.cjs → chunk-322TBTOQ.cjs} +48 -48
- package/dist/{chunk-BYBDM423.cjs.map → chunk-322TBTOQ.cjs.map} +1 -1
- package/dist/chunk-36SX6QXP.cjs +186 -0
- package/dist/chunk-36SX6QXP.cjs.map +1 -0
- package/dist/{chunk-H3XP6BAV.js → chunk-36VYWVQU.js} +3 -3
- package/dist/{chunk-H3XP6BAV.js.map → chunk-36VYWVQU.js.map} +1 -1
- package/dist/{chunk-VTJVMP4I.js → chunk-4DKY6RIU.js} +102 -31
- package/dist/chunk-4DKY6RIU.js.map +1 -0
- package/dist/chunk-4QKOZYMV.js +9 -0
- package/dist/chunk-4QKOZYMV.js.map +1 -0
- package/dist/{chunk-U3Z7XKAG.js → chunk-57JM6NW3.js} +8 -18
- package/dist/chunk-57JM6NW3.js.map +1 -0
- package/dist/{chunk-WCLMKNQE.cjs → chunk-5FVZSE3B.cjs} +1356 -1108
- package/dist/chunk-5FVZSE3B.cjs.map +1 -0
- package/dist/{chunk-XMY2SXOH.cjs → chunk-5WWEYV4H.cjs} +2208 -579
- package/dist/chunk-5WWEYV4H.cjs.map +1 -0
- package/dist/{chunk-WQBAQZHR.js → chunk-6NLYIMJO.js} +4 -4
- package/dist/{chunk-WQBAQZHR.js.map → chunk-6NLYIMJO.js.map} +1 -1
- package/dist/{chunk-G2TLHH6T.cjs → chunk-7B7I7YAW.cjs} +6 -6
- package/dist/{chunk-G2TLHH6T.cjs.map → chunk-7B7I7YAW.cjs.map} +1 -1
- package/dist/{chunk-EDLKIQRI.js → chunk-7G5IYROL.js} +6 -548
- package/dist/chunk-7G5IYROL.js.map +1 -0
- package/dist/{chunk-46UGOVRW.js → chunk-7QFRK6PU.js} +3 -7
- package/dist/chunk-7QFRK6PU.js.map +1 -0
- package/dist/chunk-A4C4NJ5U.cjs +12 -0
- package/dist/chunk-A4C4NJ5U.cjs.map +1 -0
- package/dist/{chunk-7CCMCMJO.cjs → chunk-AOGOC6JF.cjs} +77 -68
- package/dist/chunk-AOGOC6JF.cjs.map +1 -0
- package/dist/{chunk-TYGGUWMS.cjs → chunk-B3MN7EJR.cjs} +177 -137
- package/dist/chunk-B3MN7EJR.cjs.map +1 -0
- package/dist/{chunk-K6VKTBST.cjs → chunk-BZ5MVITP.cjs} +4 -4
- package/dist/{chunk-K6VKTBST.cjs.map → chunk-BZ5MVITP.cjs.map} +1 -1
- package/dist/{chunk-ZAQUKCUC.js → chunk-CBOD7TXH.js} +5 -5
- package/dist/{chunk-ZAQUKCUC.js.map → chunk-CBOD7TXH.js.map} +1 -1
- package/dist/{chunk-LLVOQOWE.cjs → chunk-CRZ56SZU.cjs} +6 -5
- package/dist/chunk-CRZ56SZU.cjs.map +1 -0
- package/dist/{chunk-ON47CBE4.cjs → chunk-D3GWARN7.cjs} +47 -47
- package/dist/{chunk-ON47CBE4.cjs.map → chunk-D3GWARN7.cjs.map} +1 -1
- package/dist/{chunk-W5SOCUBL.js → chunk-D3OUDFU7.js} +5 -5
- package/dist/{chunk-W5SOCUBL.js.map → chunk-D3OUDFU7.js.map} +1 -1
- package/dist/chunk-EKG2UXNX.cjs +23 -0
- package/dist/chunk-EKG2UXNX.cjs.map +1 -0
- package/dist/{chunk-2Q45FAIE.js → chunk-EVYW3532.js} +28 -19
- package/dist/chunk-EVYW3532.js.map +1 -0
- package/dist/{chunk-7PRMDZIA.cjs → chunk-FMMW3KX7.cjs} +21 -55
- package/dist/chunk-FMMW3KX7.cjs.map +1 -0
- package/dist/chunk-H2VWDQWC.cjs +571 -0
- package/dist/chunk-H2VWDQWC.cjs.map +1 -0
- package/dist/chunk-H4FY6OZK.js +13 -0
- package/dist/chunk-H4FY6OZK.js.map +1 -0
- package/dist/{chunk-OJHD3LXJ.cjs → chunk-H5IJSROF.cjs} +2 -8
- package/dist/chunk-H5IJSROF.cjs.map +1 -0
- package/dist/{chunk-U5EL6JUV.js → chunk-I5IOSA27.js} +101 -103
- package/dist/chunk-I5IOSA27.js.map +1 -0
- package/dist/{chunk-SHC7BCG5.cjs → chunk-I7YAY2VQ.cjs} +7 -7
- package/dist/{chunk-SHC7BCG5.cjs.map → chunk-I7YAY2VQ.cjs.map} +1 -1
- package/dist/chunk-IRCWIA3R.js +20 -0
- package/dist/chunk-IRCWIA3R.js.map +1 -0
- package/dist/chunk-IVQBLXBK.cjs +55 -0
- package/dist/chunk-IVQBLXBK.cjs.map +1 -0
- package/dist/{chunk-5PP4KRPV.js → chunk-IZD4HTCP.js} +5 -5
- package/dist/{chunk-5PP4KRPV.js.map → chunk-IZD4HTCP.js.map} +1 -1
- package/dist/{chunk-RDP6ZRSM.cjs → chunk-JQKMEKKW.cjs} +261 -204
- package/dist/chunk-JQKMEKKW.cjs.map +1 -0
- package/dist/chunk-JVA3KDEA.cjs +691 -0
- package/dist/chunk-JVA3KDEA.cjs.map +1 -0
- package/dist/{chunk-JG5XIJDY.js → chunk-K67P5DLL.js} +62 -22
- package/dist/chunk-K67P5DLL.js.map +1 -0
- package/dist/{chunk-MX7EKQPM.js → chunk-K6OZIHKI.js} +345 -97
- package/dist/chunk-K6OZIHKI.js.map +1 -0
- package/dist/{chunk-CS6JTQQ2.cjs → chunk-KACEYDYV.cjs} +94 -62
- package/dist/chunk-KACEYDYV.cjs.map +1 -0
- package/dist/{chunk-5OWHU7Z7.cjs → chunk-L6EVYIID.cjs} +248 -210
- package/dist/chunk-L6EVYIID.cjs.map +1 -0
- package/dist/{chunk-7OWE7WD6.js → chunk-LI4K2KEJ.js} +4 -4
- package/dist/{chunk-7OWE7WD6.js.map → chunk-LI4K2KEJ.js.map} +1 -1
- package/dist/chunk-LKZDQ2B4.js +1581 -0
- package/dist/chunk-LKZDQ2B4.js.map +1 -0
- package/dist/{chunk-45YZXI6X.cjs → chunk-LLFPQOBA.cjs} +27 -27
- package/dist/{chunk-45YZXI6X.cjs.map → chunk-LLFPQOBA.cjs.map} +1 -1
- package/dist/{chunk-ZRJTM7MT.js → chunk-LZMQ3SFK.js} +3 -3
- package/dist/{chunk-ZRJTM7MT.js.map → chunk-LZMQ3SFK.js.map} +1 -1
- package/dist/{chunk-DI6VC62F.js → chunk-M3VTS3F6.js} +3 -3
- package/dist/{chunk-DI6VC62F.js.map → chunk-M3VTS3F6.js.map} +1 -1
- package/dist/{chunk-MZ34E2GN.js → chunk-NBOS7BY3.js} +60 -21
- package/dist/chunk-NBOS7BY3.js.map +1 -0
- package/dist/{chunk-YA36ABIL.js → chunk-NGQDGL5X.js} +14 -48
- package/dist/chunk-NGQDGL5X.js.map +1 -0
- package/dist/{chunk-ZBFZGLZE.cjs → chunk-NLX5OWK7.cjs} +6 -2
- package/dist/chunk-NLX5OWK7.cjs.map +1 -0
- package/dist/chunk-NUQ2YFFH.cjs +1637 -0
- package/dist/chunk-NUQ2YFFH.cjs.map +1 -0
- package/dist/{chunk-TTCOPKUL.cjs → chunk-OGL4X4PH.cjs} +182 -184
- package/dist/chunk-OGL4X4PH.cjs.map +1 -0
- package/dist/{chunk-HY5BNOUN.cjs → chunk-OTNTGEXR.cjs} +4 -4
- package/dist/{chunk-HY5BNOUN.cjs.map → chunk-OTNTGEXR.cjs.map} +1 -1
- package/dist/chunk-OTWE63BW.js +53 -0
- package/dist/chunk-OTWE63BW.js.map +1 -0
- package/dist/chunk-PC5NGH5A.js +549 -0
- package/dist/chunk-PC5NGH5A.js.map +1 -0
- package/dist/{chunk-IPRP6TDL.cjs → chunk-PS3TUWJM.cjs} +7 -7
- package/dist/{chunk-IPRP6TDL.cjs.map → chunk-PS3TUWJM.cjs.map} +1 -1
- package/dist/{chunk-V76FGHY3.js → chunk-PVFFH7TL.js} +5 -5
- package/dist/{chunk-V76FGHY3.js.map → chunk-PVFFH7TL.js.map} +1 -1
- package/dist/chunk-QCD5JKU4.cjs +15 -0
- package/dist/chunk-QCD5JKU4.cjs.map +1 -0
- package/dist/{chunk-IRPYOHRC.js → chunk-QG5VEOKX.js} +6 -2
- package/dist/chunk-QG5VEOKX.js.map +1 -0
- package/dist/{chunk-2CYI5HRH.js → chunk-RI7RJH4G.js} +49 -17
- package/dist/chunk-RI7RJH4G.js.map +1 -0
- package/dist/{chunk-5LKOVCPP.js → chunk-RVUL2HXY.js} +6 -5
- package/dist/chunk-RVUL2HXY.js.map +1 -0
- package/dist/{chunk-WK23PGTP.cjs → chunk-S5GU4LUN.cjs} +11 -11
- package/dist/{chunk-WK23PGTP.cjs.map → chunk-S5GU4LUN.cjs.map} +1 -1
- package/dist/{chunk-S33YQEL7.js → chunk-SDPWO2Z5.js} +6 -6
- package/dist/{chunk-S33YQEL7.js.map → chunk-SDPWO2Z5.js.map} +1 -1
- package/dist/{chunk-6S3PTHL4.js → chunk-SLGGT2XD.js} +3 -3
- package/dist/{chunk-6S3PTHL4.js.map → chunk-SLGGT2XD.js.map} +1 -1
- package/dist/{chunk-HSEZ7X6Y.cjs → chunk-TIJUA4I6.cjs} +45 -45
- package/dist/{chunk-HSEZ7X6Y.cjs.map → chunk-TIJUA4I6.cjs.map} +1 -1
- package/dist/{chunk-CSNOYIB4.cjs → chunk-TM54OBHX.cjs} +13 -13
- package/dist/{chunk-CSNOYIB4.cjs.map → chunk-TM54OBHX.cjs.map} +1 -1
- package/dist/{chunk-MM3JHVKZ.cjs → chunk-TUWSVL6I.cjs} +4 -4
- package/dist/{chunk-MM3JHVKZ.cjs.map → chunk-TUWSVL6I.cjs.map} +1 -1
- package/dist/{chunk-2GIV5X4P.js → chunk-TYEYRCXL.js} +86 -33
- package/dist/chunk-TYEYRCXL.js.map +1 -0
- package/dist/{chunk-MJPZNEJZ.js → chunk-UKOVGCRN.js} +2095 -496
- package/dist/chunk-UKOVGCRN.js.map +1 -0
- package/dist/chunk-UYKDYE5D.cjs +12 -0
- package/dist/{chunk-KWNWG4RC.cjs.map → chunk-UYKDYE5D.cjs.map} +1 -1
- package/dist/{chunk-FX5ZW6PN.js → chunk-VAAC7L57.js} +95 -40
- package/dist/chunk-VAAC7L57.js.map +1 -0
- package/dist/{chunk-ISKCIQF2.cjs → chunk-VKHXYVN7.cjs} +14 -25
- package/dist/chunk-VKHXYVN7.cjs.map +1 -0
- package/dist/chunk-VUQZNUHU.js +171 -0
- package/dist/chunk-VUQZNUHU.js.map +1 -0
- package/dist/{chunk-K2XYLVVB.cjs → chunk-WDM5WQK4.cjs} +175 -136
- package/dist/chunk-WDM5WQK4.cjs.map +1 -0
- package/dist/{chunk-GVYVGGPJ.js → chunk-WFSYYU4W.js} +66 -28
- package/dist/chunk-WFSYYU4W.js.map +1 -0
- package/dist/{chunk-R7MRFE5P.js → chunk-WS5MT2UJ.js} +3 -3
- package/dist/{chunk-R7MRFE5P.js.map → chunk-WS5MT2UJ.js.map} +1 -1
- package/dist/chunk-XORONCV3.js +202 -0
- package/dist/chunk-XORONCV3.js.map +1 -0
- package/dist/chunk-ZGVTNKTX.cjs +217 -0
- package/dist/chunk-ZGVTNKTX.cjs.map +1 -0
- package/dist/core/index.cjs +20 -20
- package/dist/core/index.d.cts +4 -4
- package/dist/core/index.d.ts +4 -4
- package/dist/core/index.js +4 -4
- package/dist/{ddl-B49O7dB_.d.ts → ddl-BvcbgzHo.d.ts} +3 -3
- package/dist/{ddl-DcZG660s.d.cts → ddl-Ufebz5q5.d.cts} +3 -3
- package/dist/graph-extension/index.d.cts +2 -4
- package/dist/graph-extension/index.d.ts +2 -4
- package/dist/graph-merge/index.cjs +140 -125
- package/dist/graph-merge/index.cjs.map +1 -1
- package/dist/graph-merge/index.d.cts +8 -9
- package/dist/graph-merge/index.d.ts +8 -9
- package/dist/graph-merge/index.js +42 -27
- package/dist/graph-merge/index.js.map +1 -1
- package/dist/index.cjs +144 -143
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +11 -12
- package/dist/index.d.ts +11 -12
- package/dist/index.js +30 -29
- package/dist/index.js.map +1 -1
- package/dist/indexes/index.cjs +14 -12
- package/dist/indexes/index.d.cts +4 -4
- package/dist/indexes/index.d.ts +4 -4
- package/dist/indexes/index.js +7 -5
- package/dist/{ingestion-import-target-CI8OWIkM.d.ts → ingestion-import-target-CAs1OX-l.d.cts} +1 -1
- package/dist/{ingestion-import-target-DCpfM1PX.d.cts → ingestion-import-target-DCQSPfNx.d.ts} +1 -1
- package/dist/interchange/index.cjs +41 -39
- package/dist/interchange/index.cjs.map +1 -1
- package/dist/interchange/index.d.cts +8 -8
- package/dist/interchange/index.d.ts +8 -8
- package/dist/interchange/index.js +16 -14
- package/dist/interchange/index.js.map +1 -1
- package/dist/local-store-impl-JC7OBRAW.js +75 -0
- package/dist/local-store-impl-JC7OBRAW.js.map +1 -0
- package/dist/local-store-impl-UOS2LUIG.cjs +77 -0
- package/dist/local-store-impl-UOS2LUIG.cjs.map +1 -0
- package/dist/{manager-Cfg1ENj1.d.ts → manager-B68OrPR2.d.ts} +1 -2
- package/dist/{manager-D348fa6W.d.cts → manager-D_t7oK69.d.cts} +1 -2
- package/dist/pglite-store-impl-J5J5AA52.cjs +75 -0
- package/dist/pglite-store-impl-J5J5AA52.cjs.map +1 -0
- package/dist/pglite-store-impl-LDRH2DUH.js +73 -0
- package/dist/pglite-store-impl-LDRH2DUH.js.map +1 -0
- package/dist/{postgres-UStOycLI.d.ts → postgres-BPLSVyHM.d.ts} +1 -1
- package/dist/{postgres-CH1kkM5J.d.cts → postgres-CqvtFC2y.d.cts} +1 -1
- package/dist/profiler/index.d.cts +9 -9
- package/dist/profiler/index.d.ts +9 -9
- package/dist/provenance/index.cjs +33 -20
- package/dist/provenance/index.cjs.map +1 -1
- package/dist/provenance/index.d.cts +7 -7
- package/dist/provenance/index.d.ts +7 -7
- package/dist/provenance/index.js +24 -11
- package/dist/provenance/index.js.map +1 -1
- package/dist/{repair-validity-windows-aWX7VNvv.d.cts → repair-validity-windows-DEzCKAdy.d.cts} +7 -3
- package/dist/{repair-validity-windows-BtOEe2pS.d.ts → repair-validity-windows-GMdaS2AH.d.ts} +7 -3
- package/dist/resolve-D_H8MHtq.d.ts +1805 -0
- package/dist/resolve-WEW8gWws.d.cts +1805 -0
- package/dist/schema/index.cjs +42 -40
- package/dist/schema/index.d.cts +4 -6
- package/dist/schema/index.d.ts +4 -6
- package/dist/schema/index.js +15 -13
- package/dist/{searchable-z4BiFfHI.d.ts → searchable-C_UREI9K.d.ts} +1 -1
- package/dist/{searchable-C8-RrL3l.d.cts → searchable-ClgET_i7.d.cts} +1 -1
- package/dist/{sqlite-axLw5Lo5.d.ts → sqlite-D1mXO9Kp.d.cts} +2 -1
- package/dist/{sqlite-Cyx9j9o6.d.cts → sqlite-MZA3oZNB.d.ts} +2 -1
- package/dist/{store-CTfQ9taw.d.ts → store-CuFX7fCx.d.cts} +38 -41
- package/dist/{store-DR9J7JVB.d.cts → store-D-ZjXQpW.d.ts} +38 -41
- package/dist/{temporal-CBOrERz5.d.ts → temporal-CpyEiRY8.d.cts} +1 -1
- package/dist/{temporal-B4Ky4wzh.d.cts → temporal-y0Aep9Su.d.ts} +1 -1
- package/dist/{types-CWg4dTjj.d.ts → types-6yf0Vv-_.d.cts} +1672 -1
- package/dist/{types-CWg4dTjj.d.cts → types-6yf0Vv-_.d.ts} +1672 -1
- package/dist/{types-BScHXVM7.d.ts → types-DzJ4dlzk.d.cts} +1 -1
- package/dist/{types-BE921wRl.d.cts → types-_vVSB9k-.d.ts} +1 -1
- package/dist/{where-BWXUPV3C.d.ts → where-DuG2LCLe.d.ts} +1 -1
- package/dist/{where-CNtx1aLc.d.cts → where-Mhf_yyKX.d.cts} +1 -1
- package/package.json +5 -1
- package/dist/chunk-2CYI5HRH.js.map +0 -1
- package/dist/chunk-2GIV5X4P.js.map +0 -1
- package/dist/chunk-2Q45FAIE.js.map +0 -1
- package/dist/chunk-46UGOVRW.js.map +0 -1
- package/dist/chunk-5LKOVCPP.js.map +0 -1
- package/dist/chunk-5OWHU7Z7.cjs.map +0 -1
- package/dist/chunk-6LEOAIIB.js +0 -1160
- package/dist/chunk-6LEOAIIB.js.map +0 -1
- package/dist/chunk-7CCMCMJO.cjs.map +0 -1
- package/dist/chunk-7PRMDZIA.cjs.map +0 -1
- package/dist/chunk-C76WFIVZ.cjs.map +0 -1
- package/dist/chunk-CS6JTQQ2.cjs.map +0 -1
- package/dist/chunk-EDLKIQRI.js.map +0 -1
- package/dist/chunk-EH3JZJUM.cjs +0 -567
- package/dist/chunk-EH3JZJUM.cjs.map +0 -1
- package/dist/chunk-FX5ZW6PN.js.map +0 -1
- package/dist/chunk-GHZPZNFC.cjs +0 -132
- package/dist/chunk-GHZPZNFC.cjs.map +0 -1
- package/dist/chunk-GVYVGGPJ.js.map +0 -1
- package/dist/chunk-IHK5KA2Q.cjs +0 -262
- package/dist/chunk-IHK5KA2Q.cjs.map +0 -1
- package/dist/chunk-IRPYOHRC.js.map +0 -1
- package/dist/chunk-ISKCIQF2.cjs.map +0 -1
- package/dist/chunk-JG5XIJDY.js.map +0 -1
- package/dist/chunk-K2XYLVVB.cjs.map +0 -1
- package/dist/chunk-KWNWG4RC.cjs +0 -12
- package/dist/chunk-LLVOQOWE.cjs.map +0 -1
- package/dist/chunk-MJPZNEJZ.js.map +0 -1
- package/dist/chunk-MX7EKQPM.js.map +0 -1
- package/dist/chunk-MZ34E2GN.js.map +0 -1
- package/dist/chunk-OJHD3LXJ.cjs.map +0 -1
- package/dist/chunk-PALYTHGM.js +0 -114
- package/dist/chunk-PALYTHGM.js.map +0 -1
- package/dist/chunk-RDP6ZRSM.cjs.map +0 -1
- package/dist/chunk-S3SDEQMC.js +0 -532
- package/dist/chunk-S3SDEQMC.js.map +0 -1
- package/dist/chunk-TEC24ZDA.cjs +0 -1254
- package/dist/chunk-TEC24ZDA.cjs.map +0 -1
- package/dist/chunk-TP4NJTI3.cjs +0 -1192
- package/dist/chunk-TP4NJTI3.cjs.map +0 -1
- package/dist/chunk-TTCOPKUL.cjs.map +0 -1
- package/dist/chunk-TUVD4DFR.cjs.map +0 -1
- package/dist/chunk-TYGGUWMS.cjs.map +0 -1
- package/dist/chunk-U3Z7XKAG.js.map +0 -1
- package/dist/chunk-U5EL6JUV.js.map +0 -1
- package/dist/chunk-VTJVMP4I.js.map +0 -1
- package/dist/chunk-WCLMKNQE.cjs.map +0 -1
- package/dist/chunk-XMY2SXOH.cjs.map +0 -1
- package/dist/chunk-Y55DLLEG.js +0 -247
- package/dist/chunk-Y55DLLEG.js.map +0 -1
- package/dist/chunk-YA36ABIL.js.map +0 -1
- package/dist/chunk-ZBFZGLZE.cjs.map +0 -1
- package/dist/index-B0PrmE3K.d.cts +0 -1146
- package/dist/index-CwcXsL5R.d.ts +0 -1146
- package/dist/materialize-indexes-C9GG3O3C.d.ts +0 -266
- package/dist/materialize-indexes-CrSiW_lT.d.cts +0 -266
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/backend/table-contribution.ts","../src/query/dialect/fulltext-strategy.ts","../src/query/dialect/vector-strategy.ts"],"names":["sql","UnsupportedBackendCapabilityError","ConfigurationError","requireDefined","quoteIdentifier"],"mappings":"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","file":"chunk-H2VWDQWC.cjs","sourcesContent":["/**\n * Unified table-contribution contract (#129).\n *\n * Every table TypeGraph owns — whether modeled as a Drizzle table or\n * emitted as strategy-owned raw DDL — is described by a single\n * {@link TableContribution} shape. This is the one place that answers\n * \"what tables does this backend/strategy own?\", replacing the\n * previously split surfaces (Drizzle named exports, tables-factory\n * recursion, strategy raw DDL, per-table `ensureXTable` methods).\n *\n * Lives in the neutral `backend/` layer (sibling of `backend/types.ts`,\n * which `query/dialect` already depends on) and is deliberately\n * Drizzle-free, so declaring contributions does not pull the concrete\n * Drizzle backend runtime into the query/dialect layer.\n *\n * ## Identity vs. signature (prerequisite for #135)\n *\n * #135 (durable fulltext/contribution materialization) needs to make\n * \"not materialized\" vs. \"materialized but stale\" a decidable, durable\n * fact instead of an in-memory per-backend latch. That requires two\n * conceptually separate things, and #129's job is only to make both\n * *derivable* from the contract:\n *\n * - **Materialization identity** — `owner` + `logicalName` +\n * resolved physical `tableName`. Keying on `logicalName` alone is\n * insufficient: custom per-deployment table names must be\n * distinguishable, otherwise two deployments with different physical\n * names would collide on one durable marker. (#135 additionally\n * scopes this by `graphId` at persistence time.)\n * - **Drift signature** — a hash of the strategy identity/version,\n * the resolved table name(s), and the normalized `createDdl`. #129\n * guarantees `createDdl` is deterministic for a given resolved\n * configuration so the hash #135 computes is meaningful.\n *\n * The signature is intentionally **not** eagerly carried on the\n * contribution: hashing is async (Web Crypto, see `utils/hash`) and\n * #135 already owns signature persistence the same way\n * `materializeIndexes` does for declared indexes.\n */\n\n/**\n * `logicalName` of the strategy-owned fulltext slot. Used as a logic\n * discriminant (latch routing, runtime-ensure) across the strategies\n * and both backends — a shared constant so a strategy declaring a\n * different name fails loudly at the call site instead of silently\n * skipping the latched fulltext path.\n */\nexport const FULLTEXT_CONTRIBUTION_NAME = \"fulltext\";\n\n/** `owner` of core/base schema tables (not strategy-owned). */\nexport const BASE_CONTRIBUTION_OWNER = \"base\";\n\n/**\n * A single table TypeGraph owns.\n */\nexport type TableContribution = Readonly<{\n /**\n * Stable, graph- and deployment-independent identity for the logical\n * slot this contribution fills (e.g. `\"fulltext\"`). NOT the physical\n * table name. Stable across table-name overrides and across strategy\n * swaps of the *same* logical slot, so #135's durable marker can\n * survive both.\n */\n logicalName: string;\n /**\n * Identifies the producer of this contribution (e.g. a strategy id\n * like `\"tsvector\"` / `\"fts5\"`, or `\"base\"` for core schema tables).\n * Part of the #135 materialization identity and an input to the\n * drift signature — a strategy swap on the same `logicalName` is a\n * legitimate, detectable drift, not a silent reuse.\n */\n owner: string;\n /**\n * Resolved physical table name after any per-deployment name\n * override. Part of the #135 materialization identity (custom names\n * must be distinguishable) and used by diagnostics / the focused\n * bootstrap ensure.\n */\n tableName: string;\n /**\n * Idempotent (`CREATE ... IF NOT EXISTS`) statements that\n * materialize this contribution's table **and its supporting\n * indexes**. Running the full list is how the runtime ensure\n * self-heals partial states (table present, index missing) — it is\n * not a probe-and-skip. Deterministic for a given resolved\n * configuration: the canonical normalized input to #135's drift\n * signature.\n */\n createDdl: readonly string[];\n /**\n * Idempotent (`DROP ... IF EXISTS`) statements that tear this\n * contribution's storage down, ordered so that running the list\n * leaves nothing behind. Declaring it is what makes a contribution\n * *rebuildable*: the destructive\n * `store.rebuildContribution()` path drops through these statements\n * before re-running {@link createDdl}, which is the only repair for a\n * table provisioned at a shape the current `createDdl` no longer\n * produces.\n *\n * Optional because it is a capability, not an invariant. A\n * contribution whose content cannot be reconstructed from data\n * TypeGraph already stores has no business advertising a rebuild —\n * dropping it would destroy the only copy — and a third-party\n * strategy that predates this field keeps compiling and is reported\n * as not rebuildable rather than silently rebuilt through a\n * synthesized `DROP`. Backends surface the resulting gap as\n * `capabilities.contributions.rebuild`.\n *\n * The rebuild visits a strategy's `runtimeEnsure` contributions, the\n * same set the boot ensure provisions — so a companion table a strategy\n * declares outside that set is neither dropped nor recreated, and must\n * not be something the recreated storage depends on.\n */\n dropDdl?: readonly string[];\n /**\n * When `true`, the post-schema-load focused ensure\n * (`loadActiveSchemaWithBootstrap`) materializes this contribution\n * on every successful schema load.\n *\n * **Invariant: only strategy-declared contributions may set this.**\n * Core/base tables are always `false` — they are created by\n * drizzle-kit / `bootstrapTables`. This is what lets the boot path\n * derive runtime contributions straight from the strategy\n * (`fulltextStrategy.ownedTables`) without walking — and generating\n * DDL for — every base table.\n */\n runtimeEnsure: boolean;\n}>;\n\n/**\n * A table a {@link FulltextStrategy} declares it owns. An alias, not a\n * distinct shape: a strategy's declaration is already authoritative\n * (no resolution step). The name documents the producer role.\n */\nexport type StrategyTableContribution = TableContribution;\n","/**\n * Fulltext Strategy — pluggable DDL + SQL generation for a dialect's\n * fulltext stack. A strategy owns every SQL statement that touches its\n * backing table: DDL, upsert (single + batch), delete (single + batch),\n * MATCH condition, rank expression, and snippet expression.\n *\n * A dialect picks one as its default; `createPostgresBackend` /\n * `createSqliteBackend` accept an override for alternate Postgres stacks\n * (pg_trgm, ParadeDB/pg_search, pgroonga) to swap the entire fulltext\n * pipeline without forking TypeGraph.\n */\nimport {\n FULLTEXT_CONTRIBUTION_NAME,\n type StrategyTableContribution,\n} from \"../../backend/table-contribution\";\nimport {\n type DeleteFulltextBatchParams,\n type DeleteFulltextParams,\n type FulltextBatchRow,\n type FulltextCapabilities,\n type FulltextQueryMode,\n type UpsertFulltextBatchParams,\n type UpsertFulltextParams,\n} from \"../../backend/types\";\nimport { sql, type SqlFragment } from \"../sql-fragment\";\n\n/**\n * Every `FulltextQueryMode` both shipped strategies accept.\n */\nexport const ALL_FULLTEXT_MODES: readonly FulltextQueryMode[] = [\n \"websearch\",\n \"phrase\",\n \"plain\",\n \"raw\",\n] as const;\n\n/**\n * Derives the `FulltextCapabilities` backends advertise from the active\n * strategy, so the two never drift.\n */\nexport function buildFulltextCapabilities(\n strategy: FulltextStrategy,\n): FulltextCapabilities {\n return {\n supported: true,\n languages: strategy.languages,\n phraseQueries: strategy.supportedModes.includes(\"phrase\"),\n prefixQueries: strategy.supportsPrefix,\n highlighting: strategy.supportsSnippets,\n };\n}\n\n/**\n * A pluggable fulltext implementation. Each strategy is expected to be\n * self-contained: given a table name, a query string, and a parse mode,\n * it emits every SQL statement the compiler and backend need — DDL,\n * reads, and writes. No out-of-band conventions across layers.\n */\nexport type FulltextStrategy = Readonly<{\n /** Human-readable identifier used in error messages and telemetry. */\n name: string;\n\n /**\n * Parse modes this strategy can translate. Callers validate against\n * this list before emitting SQL; a mode outside the set means the\n * strategy rejects the query at compile time.\n */\n supportedModes: readonly FulltextQueryMode[];\n\n /**\n * Whether the strategy can emit a per-row highlighted snippet. When\n * false, `snippetExpression` returns a literal `NULL` so callers can\n * leave the `snippet` column in place without a branch.\n */\n supportsSnippets: boolean;\n\n /**\n * Whether the strategy supports prefix queries (`foo*`). Used to\n * populate `BackendCapabilities.fulltext.prefixQueries`. A strategy\n * may support prefix queries via dedicated syntax without advertising\n * \"raw\" mode (and vice-versa).\n */\n supportsPrefix: boolean;\n\n /**\n * Whether a per-query `language` override is honored. Postgres' tsvector\n * accepts any installed regconfig at query time; SQLite FTS5's tokenizer\n * is fixed at table-create time, so the override is silently ignored.\n * Callers may surface a warning when the user passes `language` to a\n * strategy that doesn't honor it.\n */\n supportsLanguageOverride: boolean;\n\n /**\n * Languages / tokenizer names understood by the strategy. Advisory — a\n * runtime backend like Postgres may accept other installed regconfigs.\n * Used to populate `BackendCapabilities.fulltext.languages`.\n */\n languages: readonly string[];\n\n /**\n * Emits the WHERE-side MATCH expression.\n *\n * @example\n * tsvector: `\"typegraph_node_fulltext\".\"tsv\" @@ websearch_to_tsquery('english', 'cats')`\n * fts5: `\"typegraph_node_fulltext\" MATCH '\"cats\"'`\n */\n matchCondition: (\n this: void,\n tableName: string,\n query: string,\n mode: FulltextQueryMode,\n language?: string,\n ) => SqlFragment;\n\n /**\n * Emits the relevance expression. Higher values = more relevant. The\n * compiler orders by this expression DESC, and both builder and\n * backend-direct paths use the same form so their top-k results agree.\n */\n rankExpression: (\n this: void,\n tableName: string,\n query: string,\n mode: FulltextQueryMode,\n language?: string,\n ) => SqlFragment;\n\n /**\n * Emits a per-row highlighted snippet expression, or `NULL` when\n * `supportsSnippets` is false. Snippet markup is `<mark>…</mark>` in\n * both shipped strategies so consumers can apply one stylesheet.\n */\n snippetExpression: (\n this: void,\n tableName: string,\n query: string,\n mode: FulltextQueryMode,\n language?: string,\n ) => SqlFragment;\n\n /**\n * The tables this strategy owns, as Drizzle-free, already\n * authoritative `TableContribution`s (`logicalName`, `owner`,\n * resolved `tableName`, idempotent `createDdl` for the table **and\n * its supporting indexes**, `runtimeEnsure`). A strategy never\n * constructs a Drizzle table itself; drizzle-kit visibility, when\n * applicable, is the schema barrel's responsibility (the default\n * Postgres strategy's `schema/postgres.ts` exports a matching\n * `tables.fulltext` — a non-default strategy must export its own).\n *\n * Replaces the former `generateDdl(tableName)`: DDL is now one field\n * of a contribution rather than the strategy's whole storage\n * surface. (Public API change — see #129.)\n *\n * Declare `dropDdl` on each contribution to opt the strategy into the\n * destructive `store.rebuildContribution(\"fulltext\")` path — the only\n * repair for storage provisioned at a shape `createDdl` no longer\n * produces. Fulltext content is reconstructed from the node rows, so a\n * rebuild loses nothing; a strategy that omits `dropDdl` is reported\n * as not rebuildable instead of being dropped through a synthesized\n * statement.\n */\n ownedTables: (\n this: void,\n primaryTableName: string,\n ) => readonly StrategyTableContribution[];\n\n /**\n * Emits the statements that upsert a single fulltext row. Returns one\n * or more statements — some backends (SQLite FTS5) cannot emulate\n * upsert in a single statement and need DELETE + INSERT.\n */\n buildUpsert: (\n this: void,\n tableName: string,\n params: UpsertFulltextParams,\n timestamp: string,\n ) => readonly SqlFragment[];\n\n /**\n * Emits the statements that upsert many fulltext rows at once. Input\n * rows are expected to be de-duplicated last-write-wins by the\n * strategy if the underlying SQL statement cannot tolerate duplicate\n * conflict keys. Returns `[]` when `params.rows` is empty.\n */\n buildBatchUpsert: (\n this: void,\n tableName: string,\n params: UpsertFulltextBatchParams,\n timestamp: string,\n ) => readonly SqlFragment[];\n\n /**\n * Emits the statements that delete a single fulltext row. Normally a\n * single PK-scoped DELETE, but strategies that maintain auxiliary\n * indexes (delete-triggered external stores, ParadeDB-style secondary\n * structures) may need more.\n */\n buildDelete: (\n this: void,\n tableName: string,\n params: DeleteFulltextParams,\n ) => readonly SqlFragment[];\n\n /**\n * Emits the statements that delete many fulltext rows at once. Returns\n * `[]` when `params.nodeIds` is empty.\n */\n buildBatchDelete: (\n this: void,\n tableName: string,\n params: DeleteFulltextBatchParams,\n ) => readonly SqlFragment[];\n}>;\n\n// ============================================================\n// Shared graph-scoped statements\n// ============================================================\n\n/**\n * Deletes every fulltext row one graph contributed.\n *\n * The fulltext table is DATABASE-global: one physical table whose rows are\n * keyed by `graph_id` and shared by every graph in the database. \"Remove this\n * graph's fulltext content\" therefore has more than one caller — `clearGraph`\n * and the destructive contribution rebuild — and it is one exported statement\n * both use rather than two spellings that would be free to drift.\n */\nexport function buildFulltextGraphDelete(\n tableName: string,\n graphId: string,\n): SqlFragment {\n return sql`\n DELETE FROM ${sql.identifier(tableName)}\n WHERE \"graph_id\" = ${graphId}\n `;\n}\n\n/**\n * The graph ids OTHER than `graphId` that currently have rows in the shared\n * fulltext table, capped at `limit` (the probe only needs to know whether the\n * set is empty, plus a few names for the operator-facing message).\n *\n * The predicate behind \"would tearing this table down destroy content this\n * process cannot put back?\". Fulltext content is derived from a graph's own\n * node rows through its own schema, so only the graph that owns those rows\n * can reconstruct them — another graph's rows are exactly the content a\n * `DROP TABLE` must never take with it.\n */\nexport function buildForeignFulltextGraphProbe(\n tableName: string,\n graphId: string,\n limit: number,\n): SqlFragment {\n return sql`\n SELECT DISTINCT \"graph_id\"\n FROM ${sql.identifier(tableName)}\n WHERE \"graph_id\" <> ${graphId}\n LIMIT ${limit}\n `;\n}\n\n// ============================================================\n// Internal helpers\n// ============================================================\n\nfunction quoteIdentifier(name: string): string {\n return `\"${name.replaceAll('\"', '\"\"')}\"`;\n}\n\nfunction tsvectorColumn(tableName: string): SqlFragment {\n return sql`${sql.identifier(tableName)}.\"tsv\"`;\n}\n\n/**\n * Dedupes batch rows last-write-wins by nodeId. Returns a plain array\n * in insertion order of the last occurrence of each id. Shared by both\n * shipped strategies.\n */\nfunction dedupeFulltextBatchRows(\n rows: readonly FulltextBatchRow[],\n): FulltextBatchRow[] {\n const seen = new Map<string, FulltextBatchRow>();\n for (const row of rows) seen.set(row.nodeId, row);\n return [...seen.values()];\n}\n\nfunction buildPkScopedDelete(\n tableName: string,\n params: DeleteFulltextParams,\n): SqlFragment {\n const table = sql.identifier(tableName);\n return sql`\n DELETE FROM ${table}\n WHERE \"graph_id\" = ${params.graphId}\n AND \"node_kind\" = ${params.nodeKind}\n AND \"node_id\" = ${params.nodeId}\n `;\n}\n\nfunction buildPkScopedBatchDelete(\n tableName: string,\n params: DeleteFulltextBatchParams,\n): SqlFragment | undefined {\n if (params.nodeIds.length === 0) return undefined;\n const unique = [...new Set(params.nodeIds)];\n const table = sql.identifier(tableName);\n return sql`\n DELETE FROM ${table}\n WHERE \"graph_id\" = ${params.graphId}\n AND \"node_kind\" = ${params.nodeKind}\n AND \"node_id\" IN (${sql.join(\n unique.map((id) => sql`${id}`),\n sql`, `,\n )})\n `;\n}\n\n// ============================================================\n// tsvector strategy (PostgreSQL built-in)\n// ============================================================\n\nfunction postgresTsquery(\n mode: FulltextQueryMode,\n query: string,\n language: string | undefined,\n): SqlFragment {\n // The `language` column is already `regconfig`, so the non-override\n // path references the column directly. The per-query override path\n // still arrives as a bound text parameter and needs the cast.\n const langExpr: SqlFragment =\n language === undefined ? sql`\"language\"` : sql`${language}::regconfig`;\n switch (mode) {\n case \"websearch\": {\n return sql`websearch_to_tsquery(${langExpr}, ${query})`;\n }\n case \"phrase\": {\n return sql`phraseto_tsquery(${langExpr}, ${query})`;\n }\n case \"plain\": {\n return sql`plainto_tsquery(${langExpr}, ${query})`;\n }\n case \"raw\": {\n return sql`to_tsquery(${langExpr}, ${query})`;\n }\n default: {\n const _exhaustive: never = mode;\n throw new Error(`Unsupported fulltext mode: ${String(_exhaustive)}`);\n }\n }\n}\n\nexport const tsvectorStrategy: FulltextStrategy = {\n name: \"tsvector\",\n supportedModes: ALL_FULLTEXT_MODES,\n supportsSnippets: true,\n // `raw` mode exposes `foo:*` prefix-match syntax to callers.\n supportsPrefix: true,\n supportsLanguageOverride: true,\n // Canonical Postgres stemmers; every stock install ships these plus a\n // few others. Runtime `to_tsvector` accepts any installed regconfig\n // name — this list is advisory for capability discovery.\n languages: [\n \"simple\",\n \"english\",\n \"french\",\n \"german\",\n \"italian\",\n \"portuguese\",\n \"russian\",\n \"spanish\",\n \"swedish\",\n ] as const,\n\n matchCondition(tableName, query, mode, language) {\n const q = postgresTsquery(mode, query, language);\n return sql`${tsvectorColumn(tableName)} @@ ${q}`;\n },\n\n rankExpression(tableName, query, mode, language) {\n const q = postgresTsquery(mode, query, language);\n return sql`ts_rank_cd(${tsvectorColumn(tableName)}, ${q})`;\n },\n\n snippetExpression(_tableName, query, mode, language) {\n const langExpr: SqlFragment =\n language === undefined ? sql`\"language\"` : sql`${language}::regconfig`;\n const q = postgresTsquery(mode, query, language);\n return sql`ts_headline(${langExpr}, \"content\", ${q}, 'StartSel=<mark>,StopSel=</mark>,MaxFragments=1,MinWords=5,MaxWords=30,ShortWord=3')`;\n },\n\n ownedTables(primaryTableName) {\n const name = quoteIdentifier(primaryTableName);\n const gin = quoteIdentifier(`${primaryTableName}_tsv_idx`);\n const kind = quoteIdentifier(`${primaryTableName}_kind_idx`);\n // `language` is `regconfig` so `to_tsvector(\"language\", \"content\")`\n // is an immutable expression — Postgres can then compute `tsv` as a\n // GENERATED STORED column and own the `content → tsv` invariant.\n // (The text→regconfig cast happens once at INSERT time against the\n // bound parameter, which is fine because it's not inside the\n // generated expression.)\n const createDdl = [\n `CREATE TABLE IF NOT EXISTS ${name} (\n \"graph_id\" TEXT NOT NULL,\n \"node_kind\" TEXT NOT NULL,\n \"node_id\" TEXT NOT NULL,\n \"content\" TEXT NOT NULL,\n \"language\" regconfig NOT NULL,\n \"tsv\" tsvector NOT NULL\n GENERATED ALWAYS AS (to_tsvector(\"language\", \"content\")) STORED,\n \"updated_at\" TIMESTAMPTZ NOT NULL,\n PRIMARY KEY (\"graph_id\", \"node_kind\", \"node_id\")\n);`,\n `CREATE INDEX IF NOT EXISTS ${gin} ON ${name} USING GIN (\"tsv\");`,\n `CREATE INDEX IF NOT EXISTS ${kind} ON ${name} (\"graph_id\", \"node_kind\");`,\n ];\n // drizzle-kit visibility for this default strategy comes from\n // `schema/postgres.ts` exporting the matching `tables.fulltext`\n // pgTable through the barrel — one object, not two. `runtimeEnsure`\n // because drizzle-kit-managed setups create every base table except\n // this strategy-owned one.\n return [\n {\n logicalName: FULLTEXT_CONTRIBUTION_NAME,\n owner: \"tsvector\",\n tableName: primaryTableName,\n createDdl,\n // Both indexes belong to the table, so Postgres drops them with\n // it; no separate DROP INDEX is needed or wanted (naming them\n // would break the moment a future createDdl renames one).\n dropDdl: [`DROP TABLE IF EXISTS ${name};`],\n runtimeEnsure: true,\n },\n ];\n },\n\n buildUpsert(tableName, params, timestamp) {\n const table = sql.identifier(tableName);\n // `tsv` is a GENERATED STORED column — Postgres computes it from\n // `content` + `language`, so it must not appear in the column list\n // or the ON CONFLICT update set.\n return [\n sql`\n INSERT INTO ${table} (\"graph_id\", \"node_kind\", \"node_id\", \"content\", \"language\", \"updated_at\")\n VALUES (\n ${params.graphId}, ${params.nodeKind}, ${params.nodeId},\n ${params.content}, ${params.language}::regconfig,\n ${timestamp}\n )\n ON CONFLICT (\"graph_id\", \"node_kind\", \"node_id\")\n DO UPDATE SET\n \"content\" = EXCLUDED.\"content\",\n \"language\" = EXCLUDED.\"language\",\n \"updated_at\" = EXCLUDED.\"updated_at\"\n `,\n ];\n },\n\n buildBatchUpsert(tableName, params, timestamp) {\n const rows = dedupeFulltextBatchRows(params.rows);\n if (rows.length === 0) return [];\n\n const table = sql.identifier(tableName);\n const valueTuples = rows.map(\n (row) => sql`\n (\n ${params.graphId}, ${params.nodeKind}, ${row.nodeId},\n ${row.content}, ${row.language}::regconfig,\n ${timestamp}\n )\n `,\n );\n\n return [\n sql`\n INSERT INTO ${table} (\"graph_id\", \"node_kind\", \"node_id\", \"content\", \"language\", \"updated_at\")\n VALUES ${sql.join(valueTuples, sql`, `)}\n ON CONFLICT (\"graph_id\", \"node_kind\", \"node_id\")\n DO UPDATE SET\n \"content\" = EXCLUDED.\"content\",\n \"language\" = EXCLUDED.\"language\",\n \"updated_at\" = EXCLUDED.\"updated_at\"\n `,\n ];\n },\n\n buildDelete(tableName, params) {\n return [buildPkScopedDelete(tableName, params)];\n },\n\n buildBatchDelete(tableName, params) {\n const stmt = buildPkScopedBatchDelete(tableName, params);\n return stmt === undefined ? [] : [stmt];\n },\n};\n\n// ============================================================\n// FTS5 strategy (SQLite)\n// ============================================================\n\nfunction translateToFts5Query(query: string, mode: FulltextQueryMode): string {\n switch (mode) {\n case \"phrase\": {\n return `\"${query.replaceAll('\"', '\"\"')}\"`;\n }\n case \"plain\": {\n return query\n .trim()\n .split(/\\s+/u)\n .filter((token) => token.length > 0)\n .map((token) => `\"${token.replaceAll('\"', '\"\"')}\"`)\n .join(\" \");\n }\n case \"websearch\": {\n return translateWebsearchToFts5(query);\n }\n case \"raw\": {\n return query;\n }\n default: {\n const _exhaustive: never = mode;\n throw new Error(`Unsupported fulltext mode: ${String(_exhaustive)}`);\n }\n }\n}\n\nfunction translateWebsearchToFts5(query: string): string {\n const tokens: string[] = [];\n let index = 0;\n\n function skipWhitespace(): void {\n while (index < query.length && /\\s/u.test(query[index] ?? \"\")) {\n index += 1;\n }\n }\n\n function readPhrase(): string {\n index += 1;\n let content = \"\";\n while (index < query.length && query[index] !== '\"') {\n content += query[index] ?? \"\";\n index += 1;\n }\n if (query[index] === '\"') index += 1;\n return `\"${content.replaceAll('\"', '\"\"')}\"`;\n }\n\n function readBareTerm(): string {\n let term = \"\";\n while (index < query.length && !/\\s/u.test(query[index] ?? \"\")) {\n term += query[index] ?? \"\";\n index += 1;\n }\n return term;\n }\n\n while (index < query.length) {\n skipWhitespace();\n if (index >= query.length) break;\n const ch = query[index];\n if (ch === '\"') {\n tokens.push(readPhrase());\n continue;\n }\n if (ch === \"-\") {\n index += 1;\n const term =\n query[index] === '\"' ?\n readPhrase()\n : `\"${readBareTerm().replaceAll('\"', '\"\"')}\"`;\n tokens.push(`NOT ${term}`);\n continue;\n }\n if (ch === \"+\") {\n index += 1;\n continue;\n }\n const bare = readBareTerm();\n if (bare.length === 0) continue;\n if (bare.toUpperCase() === \"OR\") {\n tokens.push(\"OR\");\n continue;\n }\n tokens.push(`\"${bare.replaceAll('\"', '\"\"')}\"`);\n }\n\n if (tokens.length > 0 && tokens[0]?.startsWith(\"NOT \")) {\n tokens.shift();\n }\n\n return tokens.join(\" \");\n}\n\nexport const fts5Strategy: FulltextStrategy = {\n name: \"fts5\",\n supportedModes: ALL_FULLTEXT_MODES,\n supportsSnippets: true,\n // FTS5 supports `foo*` prefix matching natively.\n supportsPrefix: true,\n // FTS5 tokenizer is fixed at table-create time; per-row / per-query\n // language metadata is stored but not consulted.\n supportsLanguageOverride: false,\n // The built-in tokenizer is `porter unicode61 remove_diacritics 2`; the\n // `language` field on searchable() is recorded for future use but not\n // applied at query time.\n languages: [\"porter\", \"unicode61\", \"trigram\"] as const,\n\n matchCondition(tableName, query, mode, _language) {\n const matchExpression = translateToFts5Query(query, mode);\n return sql`${sql.identifier(tableName)} MATCH ${matchExpression}`;\n },\n\n rankExpression(tableName, _query, _mode, _language) {\n // FTS5 bm25() returns a negative score where lower = more relevant.\n // Negate so callers see higher = better (uniform with tsvector).\n return sql`-bm25(${sql.identifier(tableName)})`;\n },\n\n snippetExpression(tableName, _query, _mode, _language) {\n return sql`snippet(${sql.identifier(tableName)}, -1, '<mark>', '</mark>', '…', 20)`;\n },\n\n ownedTables(primaryTableName) {\n const name = quoteIdentifier(primaryTableName);\n // FTS5 virtual tables cannot be modeled as a Drizzle table, so this\n // contribution is raw-ddl: emitted verbatim and invisible to\n // drizzle-kit. `runtimeEnsure` because no drizzle-kit-managed setup\n // can create it.\n return [\n {\n logicalName: FULLTEXT_CONTRIBUTION_NAME,\n owner: \"fts5\",\n tableName: primaryTableName,\n createDdl: [\n `CREATE VIRTUAL TABLE IF NOT EXISTS ${name} USING fts5(\n graph_id UNINDEXED,\n node_kind UNINDEXED,\n node_id UNINDEXED,\n language UNINDEXED,\n updated_at UNINDEXED,\n content,\n tokenize='porter unicode61 remove_diacritics 2'\n);`,\n ],\n // `DROP TABLE` on an FTS5 virtual table also removes the shadow\n // tables (`_data`, `_idx`, `_content`, …) the module created, so\n // one statement is the whole teardown.\n dropDdl: [`DROP TABLE IF EXISTS ${name};`],\n runtimeEnsure: true,\n },\n ];\n },\n\n buildUpsert(tableName, params, timestamp) {\n const table = sql.identifier(tableName);\n // FTS5 virtual tables don't support ON CONFLICT — emulate with\n // DELETE + INSERT, atomic under the caller's outer transaction.\n return [\n sql`\n DELETE FROM ${table}\n WHERE \"graph_id\" = ${params.graphId}\n AND \"node_kind\" = ${params.nodeKind}\n AND \"node_id\" = ${params.nodeId}\n `,\n sql`\n INSERT INTO ${table} (graph_id, node_kind, node_id, content, language, updated_at)\n VALUES (${params.graphId}, ${params.nodeKind}, ${params.nodeId}, ${params.content}, ${params.language}, ${timestamp})\n `,\n ];\n },\n\n buildBatchUpsert(tableName, params, timestamp) {\n const rows = dedupeFulltextBatchRows(params.rows);\n if (rows.length === 0) return [];\n\n const table = sql.identifier(tableName);\n const nodeIds = rows.map((row) => row.nodeId);\n\n const deleteStmt = sql`\n DELETE FROM ${table}\n WHERE \"graph_id\" = ${params.graphId}\n AND \"node_kind\" = ${params.nodeKind}\n AND \"node_id\" IN (${sql.join(\n nodeIds.map((id) => sql`${id}`),\n sql`, `,\n )})\n `;\n\n const valueTuples = rows.map(\n (row) => sql`\n (\n ${params.graphId}, ${params.nodeKind}, ${row.nodeId},\n ${row.content}, ${row.language}, ${timestamp}\n )\n `,\n );\n\n const insertStmt = sql`\n INSERT INTO ${table} (graph_id, node_kind, node_id, content, language, updated_at)\n VALUES ${sql.join(valueTuples, sql`, `)}\n `;\n\n return [deleteStmt, insertStmt];\n },\n\n buildDelete(tableName, params) {\n return [buildPkScopedDelete(tableName, params)];\n },\n\n buildBatchDelete(tableName, params) {\n const stmt = buildPkScopedBatchDelete(tableName, params);\n return stmt === undefined ? [] : [stmt];\n },\n};\n","/**\n * Vector Strategy — pluggable storage + SQL generation for a backend's\n * vector stack. The sibling of {@link FulltextStrategy}: a strategy owns\n * every statement that touches its embedding storage — the per-field DDL,\n * upsert, delete, similarity search, and (optional) ANN index lifecycle —\n * plus the capability advertisement and the distance/score expressions the\n * query compiler splices into its relevance CTE.\n *\n * ## Why a strategy, and why per-(kind, field) storage\n *\n * The spike behind #157 established that \"real\" ANN on every engine we\n * support converges on a\n * **typed, fixed-dimension structure per `(nodeKind, fieldPath)`**:\n *\n * - pgvector: a `vector(N)` column + HNSW/IVFFlat;\n * - libSQL native: an `F32_BLOB(N)` column + `libsql_vector_idx` +\n * `vector_top_k` (a plain `BLOB` or dimensionless `F32_BLOB` is rejected\n * by the index — the dimension must live in the column type);\n * - sqlite-vec: a `vec0(embedding float[N])` virtual table.\n *\n * The legacy single shared `typegraph_node_embeddings` table (one generic\n * column holding mixed-dimension vectors) can only ever be brute-forced;\n * pgvector was the sole engine that hid this, because its index supplies the\n * dimension via a `::vector(N)` cast expression. So storage is the\n * strategy's to own, slot by slot, rather than a fixed global table.\n *\n * Brute force remains a legitimate, capability-advertised mode (libSQL's\n * `vector_distance_cos` over a column with no index, sqlite-vec's\n * `vec_distance_cosine`): a strategy whose `capabilities.indexTypes` is\n * `[\"none\"]` simply never emits an ANN index and `buildSearch` always scans.\n */\nimport { type StrategyTableContribution } from \"../../backend/table-contribution\";\nimport {\n type DeleteEmbeddingParams,\n type UpsertEmbeddingBatchParams,\n type UpsertEmbeddingParams,\n type VectorCapabilities,\n type VectorIndexType,\n type VectorMetric,\n type VectorSearchFrontierTuning,\n type VectorSearchParams,\n} from \"../../backend/types\";\nimport {\n ConfigurationError,\n UnsupportedBackendCapabilityError,\n} from \"../../errors\";\nimport { requireDefined } from \"../../utils/presence\";\nimport { sql, type SqlFragment } from \"../sql-fragment\";\n\n/**\n * `logicalName` prefix of a strategy-owned vector slot. Each\n * `(nodeKind, fieldPath)` pair fills one logical vector slot; the full\n * logical name is `${VECTOR_CONTRIBUTION_PREFIX}:${nodeKind}.${fieldPath}`,\n * stable across table-name overrides and strategy swaps so #135's durable\n * materialization marker survives both.\n */\nexport const VECTOR_CONTRIBUTION_PREFIX = \"vector\";\n\n/**\n * The resolved identity of one embedding field's storage in a graph —\n * everything a strategy needs to DDL, address, and index it.\n *\n * Graph-scoped: each `(graphId, nodeKind, fieldPath)` gets its own physical\n * table. TypeGraph supports many graphs per physical database, and the same\n * `(kind, field)` can carry different embedding dimensions across graphs — a\n * shared per-`(kind, field)` table would collide on the fixed column type\n * (`vector(N)` / `F32_BLOB(N)`). Graph-scoping also makes libSQL's\n * table-global `vector_top_k` per-graph-exact (no cross-graph recall bleed).\n */\nexport type VectorSlot = Readonly<{\n /** Graph the embedding belongs to — scopes the physical table. */\n graphId: string;\n /** Node kind owning the embedding field (e.g. `\"Document\"`). */\n nodeKind: string;\n /** Dot-path of the embedding field within the node props (e.g. `\"embedding\"`). */\n fieldPath: string;\n /** Fixed vector dimension `N` for this field — carried into the column type. */\n dimensions: number;\n /** Distance metric the field's index is built for. */\n metric: VectorMetric;\n /**\n * Index type to materialize. `\"none\"` means brute-force only (no ANN\n * index emitted); the strategy still stores and searches the field.\n */\n indexType: VectorIndexType;\n /**\n * Optional ANN index tuning carried into the index DDL (pgvector\n * `m`/`ef_construction`/`lists`). Present on the create-index / re-embed\n * paths (resolved from the field's `embedding()` declaration); omitted on\n * the write/search ensure paths, where the strategy falls back to defaults.\n */\n indexParams?: Readonly<{\n m?: number;\n efConstruction?: number;\n lists?: number;\n }>;\n}>;\n\n/**\n * Derives the `VectorCapabilities` a backend advertises from its active\n * strategy, so the two never drift (mirrors `buildFulltextCapabilities`).\n * The strategy is the single source of truth; there are no per-call-site\n * `SQLITE_VECTOR_*` constants.\n */\nexport function buildVectorCapabilities(\n strategy: VectorStrategy,\n): VectorCapabilities {\n return strategy.capabilities;\n}\n\n/**\n * A pluggable vector implementation. Each strategy is self-contained:\n * given a {@link VectorSlot}, it emits every statement the backend and\n * compiler need — per-field storage DDL, writes, similarity search, ANN\n * index lifecycle — and advertises exactly the metrics and index types it\n * can honor. Adding the Nth backend is one of these objects; no core edits.\n */\nexport type VectorStrategy = Readonly<{\n /** Human-readable identifier used in error messages and telemetry. */\n name: string;\n\n /**\n * The metrics, index types, and dimension ceiling this strategy honors —\n * advertised verbatim as `backend.capabilities.vector`. Asymmetry across\n * engines is legitimate and explicit here (pgvector has `inner_product`;\n * libSQL/sqlite-vec do not), never a silent runtime failure.\n */\n capabilities: VectorCapabilities;\n\n /**\n * Deterministic physical table (or virtual-table) name backing a field in\n * a graph. The compiler references this to scan the right per-field storage,\n * and the backend uses it to route upserts/deletes. Must be a stable,\n * collision-safe SQL identifier derived from `(graphId, nodeKind, fieldPath)`.\n */\n tableName: (\n this: void,\n graphId: string,\n nodeKind: string,\n fieldPath: string,\n ) => string;\n\n /**\n * The per-field storage this strategy owns for `slot`, as Drizzle-free\n * `StrategyTableContribution`s (resolved `tableName`, deterministic\n * idempotent `createDdl` for the table **and** its ANN index when the\n * slot's `indexType` warrants one, `runtimeEnsure`). Rides the #129/#135\n * table-contribution + durable-materialization machinery exactly as the\n * FTS5 / tsvector virtual tables do — these are materialized per graph by\n * `materializeIndexes()`, not by global `bootstrapTables`.\n */\n ownedTables: (\n this: void,\n slot: VectorSlot,\n ) => readonly StrategyTableContribution[];\n\n /**\n * Emits the statement(s) that upsert a single embedding into the slot's\n * storage. Multiple statements are allowed for engines that cannot upsert\n * a vector in one statement (e.g. a `vec0` virtual table → DELETE+INSERT).\n */\n buildUpsert: (\n this: void,\n slot: VectorSlot,\n params: UpsertEmbeddingParams,\n timestamp: string,\n ) => readonly SqlFragment[];\n\n /**\n * Emits the statement(s) that upsert MANY embeddings into the slot's\n * storage in multi-row form. Optional — the backend falls back to one\n * {@link buildUpsert} per row when unset. The backend guarantees the\n * rows carry distinct `nodeId`s and fit the connection's bound-parameter\n * budget (it chunks before calling).\n */\n buildUpsertBatch?: (\n this: void,\n slot: VectorSlot,\n params: UpsertEmbeddingBatchParams,\n timestamp: string,\n ) => readonly SqlFragment[];\n\n /** Emits the statement(s) that delete a single embedding from the slot. */\n buildDelete: (\n this: void,\n slot: VectorSlot,\n params: DeleteEmbeddingParams,\n ) => readonly SqlFragment[];\n /** Emits one set-based delete for many node ids in a vector slot. */\n buildDeleteBatch: (\n this: void,\n slot: VectorSlot,\n params: Omit<DeleteEmbeddingParams, \"nodeId\"> &\n Readonly<{ nodeIds: readonly string[] }>,\n ) => readonly SqlFragment[];\n\n /**\n * Raw DDL statement(s) that drop the slot's entire physical storage\n * (table + ANN index, and any engine-managed shadow tables). Used by the\n * destructive `store.reembedVectorField()` path to recreate a field's\n * storage at a new dimension. Returned as raw strings (like\n * `ownedTables(...).createDdl`) for `backend.executeDdl`; must be idempotent\n * (`IF EXISTS`).\n */\n buildDropStorage: (this: void, slot: VectorSlot) => readonly string[];\n\n /**\n * Emits the similarity-search query for the `backend.vectorSearch` path,\n * returning rows shaped `{ node_id, score }` ordered best-first. The\n * strategy picks brute-force vs ANN based on whether `slot.indexType`\n * materialized an index — the caller never branches. `score` follows the\n * shared convention (cosine → similarity `1 - distance`; l2 /\n * inner_product → raw distance), so `coerceVectorScore` / fusion stay\n * dialect-neutral.\n *\n * `candidates`, when provided, is a subquery yielding the node ids\n * eligible to appear in results (the backend passes its live-node-ids\n * subquery so top-k is computed over live rows in SQL — see\n * `liveNodeIdsSubquery`). Strategies whose ANN form cannot take the\n * filter directly must over-fetch and post-filter, documenting the\n * recall bound. A custom strategy that ignores the argument keeps the\n * pre-pushdown behavior: tombstoned ids are dropped after top-k during\n * hydration, so results can shrink below `limit` under index drift.\n */\n buildSearch: (\n this: void,\n slot: VectorSlot,\n params: VectorSearchParams,\n candidates?: SqlFragment,\n ) => SqlFragment;\n\n /**\n * True when {@link buildSearch} returns EXACT rankings — a brute-force\n * engine form, not an approximate index (sqlite-vec's vec0 KNN scans\n * every row in C). The query compiler then routes the NON-approximate\n * `.similarTo()` branch through `buildSearch` too: same results as the\n * SQL distance scan, at engine speed (measured 489ms -> 113ms at 50k\n * on the SQLite lane). Leave false/absent when the engine form is or\n * can be approximate (pgvector planner rewrites, libSQL DiskANN):\n * exactness of the default path is a semantic guarantee.\n */\n searchIsExact?: boolean;\n\n /**\n * The distance expression over the slot's embedding column, used by the\n * **query compiler** to splice vector relevance into its CTE. This is the\n * one genuinely engine-specific fragment (`vec_distance_cosine` vs\n * `<=>` vs `vector_distance_cos`); the surrounding score / minScore /\n * ORDER BY math is shared (see {@link vectorScoreExpression} etc.).\n *\n * `embeddingColumn` is the already-qualified column SQL; `queryEmbedding`\n * is formatted by the strategy into its engine's literal form.\n */\n distanceExpression: (\n this: void,\n embeddingColumn: SqlFragment,\n queryEmbedding: readonly number[],\n metric: VectorMetric,\n ) => SqlFragment;\n\n /**\n * Emits the ANN index creation statement for a slot, or `undefined` when\n * indexing is inline (vec0) or unsupported (brute-force-only strategies).\n * Invoked through `backend.createVectorIndex` during `materializeIndexes`.\n */\n buildCreateIndex?: (\n this: void,\n slot: VectorSlot,\n options?: Readonly<{ concurrent?: boolean }>,\n ) => SqlFragment | undefined;\n\n /** Emits the ANN index drop statement, or `undefined` when not applicable. */\n buildDropIndex?: (this: void, slot: VectorSlot) => SqlFragment | undefined;\n}>;\n\n// ============================================================\n// Shared, dialect-neutral expression math\n// ============================================================\n//\n// These transforms are identical across pgvector / sqlite-vec / libSQL —\n// only `distanceExpression` differs — so they live once here and are reused\n// by both `buildSearch` implementations and the compiler CTE builder.\n\n/**\n * Converts a distance expression into a score expression (higher = better).\n * Cosine distance is mapped to similarity (`1 - d`); l2 and inner_product\n * are returned as-is (lower distance already ranks better, ordered ASC).\n */\nexport function vectorScoreExpression(\n distanceExpression: SqlFragment,\n metric: VectorMetric,\n): SqlFragment {\n switch (metric) {\n case \"cosine\": {\n return sql`(1 - (${distanceExpression}))`;\n }\n case \"l2\":\n case \"inner_product\": {\n return distanceExpression;\n }\n default: {\n const _exhaustive: never = metric;\n throw new Error(`Unsupported vector metric: ${String(_exhaustive)}`);\n }\n }\n}\n\n/**\n * Builds the `minScore` WHERE condition against a distance expression,\n * translating the score threshold back into the metric's distance space.\n */\nexport function vectorMinScoreCondition(\n distanceExpression: SqlFragment,\n metric: VectorMetric,\n minScore: number,\n): SqlFragment {\n // Validate against the RESOLVED metric — both the compiler's relevance CTE\n // and the backend search path funnel here, so an out-of-range floor (e.g. a\n // cosine minScore of 5 → `distance <= 1 - 5`, which matches nothing) is\n // rejected loudly instead of silently returning zero rows.\n assertVectorMinScore(minScore, metric);\n switch (metric) {\n case \"cosine\": {\n return sql`${distanceExpression} <= ${1 - minScore}`;\n }\n case \"l2\": {\n return sql`${distanceExpression} <= ${minScore}`;\n }\n case \"inner_product\": {\n return sql`${distanceExpression} <= ${-minScore}`;\n }\n default: {\n const _exhaustive: never = metric;\n throw new Error(`Unsupported vector metric: ${String(_exhaustive)}`);\n }\n }\n}\n\n/**\n * Validates that every value in an embedding is a finite number. Shared by\n * strategies so a NaN/Infinity is reported with the offending index before\n * it reaches engine-specific literal formatting (which would mask it).\n */\nexport function assertFiniteEmbedding(\n embedding: readonly number[],\n name: string,\n): void {\n for (const [index, value] of embedding.entries()) {\n if (typeof value !== \"number\" || !Number.isFinite(value)) {\n throw new TypeError(\n `${name}[${index}] must be a finite number, got: ${value}`,\n );\n }\n }\n}\n\n/**\n * Validates a vector-search `limit` is a positive integer. Enforced by the\n * backend's `vectorSearch` (defense in depth — the store boundary also\n * checks) so a direct backend call with `limit: 0` fails loudly instead of\n * silently scanning nothing.\n */\nexport function assertVectorSearchLimit(limit: number): void {\n if (!Number.isInteger(limit) || limit <= 0) {\n throw new RangeError(\n `vectorSearch limit must be a positive integer, got: ${limit}`,\n );\n }\n}\n\n/**\n * The frontier declaration of a backend's active vector strategy, or the\n * \"there is no vector engine here\" declaration when vector support is\n * disabled. Total, so a call site never has to invent a default: a backend\n * with no strategy has nothing to apply an override to and refuses on the\n * same arm as an engine that lacks the knob.\n */\nexport function vectorSearchFrontierTuning(\n strategy: VectorStrategy | undefined,\n): VectorSearchFrontierTuning {\n return (\n strategy?.capabilities.searchFrontierTuning ?? {\n tunable: false,\n reason: \"vector support is disabled on this backend\",\n }\n );\n}\n\n/** What one backend needs to decide whether it can apply an `efSearch`. */\nexport type EfSearchApplicability = Readonly<{\n /** The caller's override; `undefined` (no override) is always accepted. */\n efSearch: number | undefined;\n /** Index type of the slot being searched. */\n indexType: VectorIndexType;\n /** The active strategy's declaration. See {@link VectorSearchFrontierTuning}. */\n tuning: VectorSearchFrontierTuning;\n /** Whether the backend can open the frame a scoped override needs. */\n transactions: boolean;\n /**\n * Dialect name used in the refusal message (`\"PostgreSQL\"` / `\"SQLite\"`) —\n * the only dialect-specific token in the decision, so both backends read\n * the same predicate rather than re-spelling the arms.\n */\n dialect: string;\n /** Engine identity recorded in the refusal details (`strategy.name`). */\n engine: string;\n}>;\n\n/**\n * The single owner of \"may this backend apply a per-search `efSearch`?\" —\n * returning the engine parameter to set with it, or `undefined` when no\n * override was requested.\n *\n * An accepted option is applied or refused, never ignored: every arm below is\n * a state in which the option cannot reach the engine, and each throws naming\n * that state instead of dropping the value. Both backends call this before\n * building the search, so the SQLite and PostgreSQL behaviors are two readings\n * of one predicate — the sqlite-vec silent no-op existed precisely because the\n * decision lived only on the PostgreSQL side. Returning the parameter (rather\n * than only asserting) is what keeps it one owner: the caller that applies the\n * override never re-derives whether it may.\n *\n * Refusals:\n *\n * - engine has no per-search frontier knob at all (`tunable: false`) —\n * `UnsupportedBackendCapabilityError` on `vector.searchFrontierTuning`,\n * carrying the strategy's own `reason`.\n * - slot is not the tunable index type — `ConfigurationError` (the caller can\n * fix this by declaring the index, so it is configuration, not capability).\n * - the override needs a transaction to be scoped to and the backend has none\n * — `UnsupportedBackendCapabilityError` on `transactions`.\n *\n * Range validation (pgvector's 1..1000) stays with the engine that has the\n * range; this predicate answers only whether the knob exists here at all.\n */\nexport function resolveEfSearchOverride(\n applicability: EfSearchApplicability,\n): string | undefined {\n const { efSearch, indexType, tuning, transactions, dialect, engine } =\n applicability;\n if (efSearch === undefined) return undefined;\n if (!tuning.tunable) {\n throw new UnsupportedBackendCapabilityError(\n `${dialect} efSearch override`,\n \"vector.searchFrontierTuning\",\n { efSearch, engine, reason: tuning.reason },\n `Omit efSearch: ${engine} has no per-search ANN frontier parameter (${tuning.reason}). Tune recall with the search limit, or use an exact search.`,\n );\n }\n if (indexType !== tuning.indexType) {\n // \"an HNSW vector index\" — the article suits the one tunable index type\n // any bundled engine declares.\n throw new ConfigurationError(\n `${dialect} efSearch requires an ${tuning.indexType.toUpperCase()} vector index.`,\n { efSearch, indexType },\n {\n suggestion: `Configure the embedding with index: { type: \"${tuning.indexType}\" }, or omit efSearch.`,\n },\n );\n }\n if (tuning.requiresTransactionScope && !transactions) {\n throw new UnsupportedBackendCapabilityError(\n `${dialect} efSearch override`,\n \"transactions\",\n { efSearch, engine, parameter: tuning.parameter },\n `Use a transactional ${dialect} driver: ${tuning.parameter} is scoped to the search's own transaction, and a session-wide setting would leak into concurrent searches.`,\n );\n }\n return tuning.parameter;\n}\n\n/** What one call site needs to decide whether ANN retrieval can be honored. */\nexport type ApproximateRetrievalRequest = Readonly<{\n /** Whether the caller STATED `approximate: true`. */\n approximate: boolean | undefined;\n /**\n * The metric the caller explicitly overrode to, or `undefined` when they\n * passed none (in which case the slot's declared metric is used and no\n * mismatch is possible).\n */\n requestedMetric: VectorMetric | undefined;\n /** The metric the slot's storage and ANN structure were built for. */\n declaredMetric: VectorMetric;\n /** The slot's index type; `\"none\"` means there is no ANN structure at all. */\n indexType: VectorIndexType;\n /** Kind and field named in the refusal, so a union says WHICH slot refused. */\n nodeKind: string;\n fieldPath: string;\n}>;\n\n/**\n * The single owner of \"can this slot serve APPROXIMATE retrieval under the\n * metric the caller asked for?\".\n *\n * Every engine materializes metric-specific ANN structures — vec0 bakes\n * `distance_metric` into the virtual table, libSQL's DiskANN index is built\n * with `metric=…`, pgvector's index carries a per-metric operator class — so\n * an ANN structure can only retrieve under the metric it was built for.\n * Retrieving by the declared metric and re-scoring under an overridden one\n * returns the declared metric's neighbors wearing the override's scores: the\n * wrong rows, silently.\n *\n * Stating `approximate: true` alongside a mismatched `metric` therefore states\n * two things that cannot both hold. The option is refused naming both metrics\n * rather than downgraded to an exact scan behind the caller's back — the same\n * accepted-or-refused rule {@link resolveEfSearchOverride} applies to\n * `efSearch`.\n *\n * NOT refused, deliberately:\n *\n * - `indexType: \"none\"`. There is no ANN structure to be bound to a metric, so\n * `approximate` has nothing to opt into and compiles to the strategy's exact\n * scan under whichever metric was asked for. That degradation is stated on\n * the public `SimilarToOptions.approximate` option.\n * - A mismatched metric with NO `approximate`. An exact scan computes any\n * metric over the stored vectors correctly, and nothing was stated that the\n * engine cannot honor. (`store.search.vector` refuses that override too, on\n * its own broader rule — see `assertVectorQueryCompatible` in\n * `store/search.ts`. The query builder's exact path is deliberately the\n * wider surface; only the *silent* half is closed here.)\n */\nexport function assertApproximateMetricSupported(\n request: ApproximateRetrievalRequest,\n): void {\n const {\n approximate,\n requestedMetric,\n declaredMetric,\n indexType,\n nodeKind,\n fieldPath,\n } = request;\n if (approximate !== true) return;\n if (indexType === \"none\") return;\n if (requestedMetric === undefined || requestedMetric === declaredMetric) {\n return;\n }\n throw new ConfigurationError(\n `Approximate retrieval for \"${nodeKind}.${fieldPath}\" cannot use metric \"${requestedMetric}\": its ${indexType.toUpperCase()} index is built for \"${declaredMetric}\", and an ANN structure only retrieves under the metric it was built for.`,\n {\n nodeKind,\n fieldPath,\n requestedMetric,\n declaredMetric,\n indexType,\n },\n {\n suggestion: `Omit metric (or pass \"${declaredMetric}\") to keep approximate retrieval, or drop approximate to scan exactly under \"${requestedMetric}\".`,\n },\n );\n}\n\n/**\n * Validates a `minScore` floor against its (resolved) metric: it must be finite,\n * and for cosine it must lie in [-1, 1] (a cosine score is the `1 - distance`\n * similarity). Shared by the store facade, the compiler's relevance CTE\n * ({@link vectorMinScoreCondition}), and the backend search path so every entry\n * point rejects the same out-of-range floor instead of silently returning none.\n */\nexport function assertVectorMinScore(\n minScore: number,\n metric: VectorMetric,\n label = \"minScore\",\n): void {\n if (!Number.isFinite(minScore)) {\n throw new RangeError(`${label} must be a finite number, got: ${minScore}`);\n }\n if (metric === \"cosine\" && Math.abs(minScore) > 1) {\n throw new RangeError(\n `${label} for the cosine metric must be between -1 and 1, got: ${minScore}`,\n );\n }\n}\n\n// ============================================================\n// Shared physical naming\n// ============================================================\n\n/**\n * pgvector inherits Postgres' 63-byte identifier ceiling; SQLite/libSQL are\n * far more generous, so the smallest common cap keeps one naming scheme\n * across every strategy.\n */\nconst MAX_VECTOR_IDENTIFIER_LENGTH = 63;\n\nfunction sanitizeIdentifierPart(value: string): string {\n return value.toLowerCase().replaceAll(/[^a-z0-9_]/g, \"_\");\n}\n\n/**\n * Deterministic 8-char hash for collision-safe truncation of over-long\n * identifiers. Self-contained so the strategy layer has no backend-runtime\n * dependency.\n */\nexport function shortHash(input: string): string {\n let h1 = 0xde_ad_be_ef;\n let h2 = 0x41_c6_ce_57;\n for (let index = 0; index < input.length; index++) {\n const ch = requireDefined(input.codePointAt(index));\n h1 = Math.imul(h1 ^ ch, 0x9e_37_79_b1);\n h2 = Math.imul(h2 ^ ch, 0x5f_35_64_95);\n }\n h1 =\n Math.imul(h1 ^ (h1 >>> 16), 0x85_eb_ca_6b) ^\n Math.imul(h2 ^ (h2 >>> 13), 0xc2_b2_ae_35);\n h2 =\n Math.imul(h2 ^ (h2 >>> 16), 0x85_eb_ca_6b) ^\n Math.imul(h1 ^ (h1 >>> 13), 0xc2_b2_ae_35);\n const hi = (h2 >>> 0).toString(16).padStart(8, \"0\");\n const lo = (h1 >>> 0).toString(16).padStart(8, \"0\");\n return `${hi}${lo}`.slice(0, 8);\n}\n\n/**\n * Deterministic per-`(graphId, nodeKind, fieldPath)` physical name. Shared by\n * every strategy's `tableName`, by index naming, and by the compiler's\n * per-field table resolution so all three agree on which physical object backs\n * a field in a graph. Truncated with a hash suffix past the 63-char ceiling;\n * the hash covers all three parts, so truncation stays collision-safe even\n * when long graph ids dominate the prefix.\n *\n * @example `vectorPhysicalName(\"tg_vec\", \"g1\", \"Document\", \"embedding\")`\n * → `\"tg_vec_g1_document_embedding_<hash8>\"`\n */\nexport function vectorPhysicalName(\n prefix: string,\n graphId: string,\n nodeKind: string,\n fieldPath: string,\n): string {\n const readable = `${prefix}_${sanitizeIdentifierPart(graphId)}_${sanitizeIdentifierPart(nodeKind)}_${sanitizeIdentifierPart(fieldPath)}`;\n // Always suffix a hash of the EXACT (graphId, nodeKind, fieldPath) tuple.\n // Sanitization is lossy (case-folding, every non-`[a-z0-9_]` char → `_`) and\n // the `_` join is ambiguous, so distinct fields can share a readable part —\n // e.g. (\"a_b\",\"c\") vs (\"a\",\"b_c\"), or \"Doc-A\" vs \"Doc_A\" vs \"doc\". The hash\n // keeps their physical tables distinct so writes/searches never cross fields.\n const hash = shortHash(JSON.stringify([graphId, nodeKind, fieldPath]));\n const full = `${readable}_${hash}`;\n if (full.length <= MAX_VECTOR_IDENTIFIER_LENGTH) return full;\n // Over the ceiling: truncate the readable part, always keep the hash.\n return `${readable.slice(0, MAX_VECTOR_IDENTIFIER_LENGTH - 1 - hash.length)}_${hash}`;\n}\n\n/**\n * Double-quote a SQL identifier, escaping embedded quotes. Dialect-neutral\n * (both SQLite and Postgres use `\"...\"`), so the three vector strategies share\n * one implementation for quoting their per-field table / index names.\n */\nexport function quoteIdentifier(name: string): string {\n return `\"${name.replaceAll('\"', '\"\"')}\"`;\n}\n"]}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
// src/backend/sqlite/local-options.ts
|
|
2
|
+
var DEFAULT_LOCAL_SQLITE_PRAGMAS = {
|
|
3
|
+
journalMode: "wal",
|
|
4
|
+
synchronous: "normal",
|
|
5
|
+
busyTimeoutMs: 5e3,
|
|
6
|
+
cacheSizeKib: void 0,
|
|
7
|
+
mmapSizeBytes: void 0,
|
|
8
|
+
walAutocheckpointPages: void 0
|
|
9
|
+
};
|
|
10
|
+
|
|
11
|
+
export { DEFAULT_LOCAL_SQLITE_PRAGMAS };
|
|
12
|
+
//# sourceMappingURL=chunk-H4FY6OZK.js.map
|
|
13
|
+
//# sourceMappingURL=chunk-H4FY6OZK.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/backend/sqlite/local-options.ts"],"names":[],"mappings":";AA8BO,IAAM,4BAAA,GACX;AAAA,EACE,WAAA,EAAa,KAAA;AAAA,EACb,WAAA,EAAa,QAAA;AAAA,EACb,aAAA,EAAe,GAAA;AAAA,EACf,YAAA,EAAc,MAAA;AAAA,EACd,aAAA,EAAe,MAAA;AAAA,EACf,sBAAA,EAAwB;AAC1B","file":"chunk-H4FY6OZK.js","sourcesContent":["/** Journal modes accepted by local SQLite connections. */\nexport type LocalSqliteJournalMode =\n \"wal\" | \"delete\" | \"truncate\" | \"persist\" | \"memory\" | \"off\";\n\n/** Synchronous levels accepted by local SQLite connections. */\nexport type LocalSqliteSynchronousMode = \"off\" | \"normal\" | \"full\" | \"extra\";\n\n/** Connection pragmas applied when TypeGraph opens a local SQLite database. */\nexport type LocalSqlitePragmaOptions = Readonly<{\n /** `PRAGMA journal_mode`. Default: `\"wal\"` (no-op on `\":memory:\"`). */\n journalMode?: LocalSqliteJournalMode;\n /** `PRAGMA synchronous`. Default: `\"normal\"`. */\n synchronous?: LocalSqliteSynchronousMode;\n /** `PRAGMA busy_timeout`, in milliseconds. Default: `5000`. */\n busyTimeoutMs?: number;\n /**\n * `PRAGMA cache_size`, expressed as a negative KiB value. Positive values\n * mean pages in SQLite and are rejected to prevent accidental oversizing.\n */\n cacheSizeKib?: number | undefined;\n /** `PRAGMA mmap_size`, in non-negative bytes. */\n mmapSizeBytes?: number | undefined;\n /**\n * `PRAGMA wal_autocheckpoint`, in WAL pages. Use `0` to disable automatic\n * checkpoints and run them explicitly after controlled bulk loads.\n */\n walAutocheckpointPages?: number | undefined;\n}>;\n\n/** Defaults for TypeGraph-owned local SQLite connections. */\nexport const DEFAULT_LOCAL_SQLITE_PRAGMAS: Required<LocalSqlitePragmaOptions> =\n {\n journalMode: \"wal\",\n synchronous: \"normal\",\n busyTimeoutMs: 5000,\n cacheSizeKib: undefined,\n mmapSizeBytes: undefined,\n walAutocheckpointPages: undefined,\n };\n"]}
|
|
@@ -312,11 +312,6 @@ function renderSqlInline(fragment, dialect) {
|
|
|
312
312
|
return parts.join("");
|
|
313
313
|
}
|
|
314
314
|
|
|
315
|
-
// src/query/dialect/like-escape.ts
|
|
316
|
-
var LIKE_ESCAPE_CHARACTER = "\\";
|
|
317
|
-
var likeEscapeClause = sql`ESCAPE '\\'`;
|
|
318
|
-
|
|
319
|
-
exports.LIKE_ESCAPE_CHARACTER = LIKE_ESCAPE_CHARACTER;
|
|
320
315
|
exports.Placeholder = Placeholder;
|
|
321
316
|
exports.annIndexScanTypes = annIndexScanTypes;
|
|
322
317
|
exports.asCompiledRowsSql = asCompiledRowsSql;
|
|
@@ -329,7 +324,6 @@ exports.inlineSqlStringLiteral = inlineSqlStringLiteral;
|
|
|
329
324
|
exports.isRawExecutable = isRawExecutable;
|
|
330
325
|
exports.isSqlFragment = isSqlFragment;
|
|
331
326
|
exports.isSqlPlaceholder = isSqlPlaceholder;
|
|
332
|
-
exports.likeEscapeClause = likeEscapeClause;
|
|
333
327
|
exports.markAnnIndexScan = markAnnIndexScan;
|
|
334
328
|
exports.markForceCustomPlan = markForceCustomPlan;
|
|
335
329
|
exports.packSqlListValue = packSqlListValue;
|
|
@@ -341,5 +335,5 @@ exports.shouldForceCustomPlan = shouldForceCustomPlan;
|
|
|
341
335
|
exports.sql = sql;
|
|
342
336
|
exports.throwUnsupportedSqlChunk = throwUnsupportedSqlChunk;
|
|
343
337
|
exports.typeGraphGlobalSymbol = typeGraphGlobalSymbol;
|
|
344
|
-
//# sourceMappingURL=chunk-
|
|
345
|
-
//# sourceMappingURL=chunk-
|
|
338
|
+
//# sourceMappingURL=chunk-H5IJSROF.cjs.map
|
|
339
|
+
//# sourceMappingURL=chunk-H5IJSROF.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/utils/global-symbol.ts","../src/query/dialect/profile.ts","../src/query/sql-intent.ts","../src/query/sql-fragment.ts"],"names":["ConfigurationError"],"mappings":"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","file":"chunk-H5IJSROF.cjs","sourcesContent":["type TypeGraphGlobalSymbolName =\n | \"sql-fragment\"\n | \"sql-placeholder\"\n | \"sql-intent-registry\"\n | \"internal-temporary-writes-v1\"\n | \"external-recorded-read-source-v1\"\n | \"sql-schema-v1\"\n | \"store-runtime-v1\"\n | \"typegraph-recorded-read-source-v1\"\n | \"transaction-runtime-v1\";\n\n/** Returns a process-wide symbol shared across ESM/CJS package instances. */\nexport function typeGraphGlobalSymbol<TSymbol extends symbol>(\n name: TypeGraphGlobalSymbolName,\n): TSymbol {\n return Symbol.for(`@nicia-ai/typegraph/${name}`) as TSymbol;\n}\n","import { type SqlDialect } from \"./types\";\n\nexport type SqlDialectProfile = Readonly<{\n bindValue: (value: unknown) => unknown;\n booleanLiteralString: (value: boolean) => string;\n placeholder: (index: number) => string;\n}>;\n\nconst SQL_DIALECT_PROFILES = {\n postgres: {\n bindValue: (value: unknown) => value,\n booleanLiteralString: (value: boolean) => (value ? \"TRUE\" : \"FALSE\"),\n placeholder: (index: number) => `$${index}`,\n },\n sqlite: {\n bindValue: (value: unknown) =>\n typeof value === \"boolean\" ?\n value ? 1\n : 0\n : value,\n booleanLiteralString: (value: boolean) => (value ? \"1\" : \"0\"),\n placeholder: () => \"?\",\n },\n} satisfies Record<SqlDialect, SqlDialectProfile>;\n\nconst SQL_STRING_LITERAL_RENDERERS = {\n postgres: (value: string) => {\n if (value.includes(\"\\\\\")) {\n return `E'${value.replaceAll(\"\\\\\", \"\\\\\\\\\").replaceAll(\"'\", \"''\")}'`;\n }\n return `'${value.replaceAll(\"'\", \"''\")}'`;\n },\n sqlite: (value: string) => `'${value.replaceAll(\"'\", \"''\")}'`,\n} satisfies Record<SqlDialect, (value: string) => string>;\n\n/** Returns the primitive rendering and binding rules for a SQL dialect. */\nexport function getSqlDialectProfile(dialect: SqlDialect): SqlDialectProfile {\n return SQL_DIALECT_PROFILES[dialect];\n}\n\n/** Maps a JavaScript value to the representation expected by a SQL driver. */\nexport function bindSqlValue(value: unknown, dialect: SqlDialect): unknown {\n if (value instanceof Date) return value.toISOString();\n return getSqlDialectProfile(dialect).bindValue(value);\n}\n\n/**\n * Packs a scalar list into the single JSON-text value that a list-valued `IN`\n * parameter binds to. Every element is bound exactly as the literal form would\n * bind it, so `field.in([...])` and `field.in(param(...))` agree row for row.\n */\nexport function packSqlListValue(\n values: readonly unknown[],\n dialect: SqlDialect,\n): string {\n return JSON.stringify(values.map((value) => bindSqlValue(value, dialect)));\n}\n\n/** Renders one SQL string literal using the dialect's escaping rules. */\nexport function inlineSqlStringLiteral(\n value: string,\n dialect: SqlDialect,\n): string {\n return SQL_STRING_LITERAL_RENDERERS[dialect](value);\n}\n","import { typeGraphGlobalSymbol } from \"../utils/global-symbol\";\nimport { type SqlFragment } from \"./sql-fragment\";\n\ndeclare const SqlIntentBrand: unique symbol;\n\nexport type SqlIntent = \"rows\" | \"statement\" | \"temporary-statement\";\n\nexport type IntentSql<I extends SqlIntent> = SqlFragment &\n Readonly<{ [SqlIntentBrand]: I }>;\n\nexport type CompiledRowsSql = IntentSql<\"rows\">;\nexport type CompiledSelectSql = CompiledRowsSql;\nexport type CompiledStatementSql = IntentSql<\"statement\">;\nexport type CompiledTemporaryStatementSql = IntentSql<\"temporary-statement\">;\n\nexport function asCompiledRowsSql(query: SqlFragment): CompiledRowsSql {\n return query as CompiledRowsSql;\n}\n\nexport function asCompiledSelectSql(query: SqlFragment): CompiledSelectSql {\n return asCompiledRowsSql(query);\n}\n\nexport function asCompiledStatementSql(\n query: SqlFragment,\n): CompiledStatementSql {\n return query as CompiledStatementSql;\n}\n\n/**\n * Marks an internal statement that may write only connection-local temporary\n * state. This is intentionally separate from the public raw-statement intent:\n * history-enabled stores block arbitrary raw writes but iterative graph\n * operations still need to manage ephemeral working tables.\n */\nexport function asCompiledTemporaryStatementSql(\n query: SqlFragment,\n): CompiledTemporaryStatementSql {\n return query as CompiledTemporaryStatementSql;\n}\n\n/**\n * Statements whose good plan depends on the bound parameter values —\n * e.g. an id-array membership filter where the array cardinality varies\n * per call. PostgreSQL's prepared-statement machinery switches to a\n * generic (parameter-blind) plan after five executions, which for these\n * statements is catastrophically wrong (measured 21ms -> 310ms on the\n * subgraph edge fetch). Marked statements are executed unnamed so every\n * call is planned against the actual parameters; the re-parse cost is\n * ~1ms, the generic-plan cliff it avoids is 10-300ms.\n */\ntype SqlIntentRegistry = Readonly<{\n annIndexScanQueries: WeakMap<SqlFragment, readonly string[]>;\n forceCustomPlanQueries: WeakSet<SqlFragment>;\n}>;\n\nconst SQL_INTENT_REGISTRY: unique symbol = typeGraphGlobalSymbol(\n \"sql-intent-registry\",\n);\nconst globalWithSqlIntentRegistry = globalThis as typeof globalThis &\n Readonly<{\n [SQL_INTENT_REGISTRY]?: SqlIntentRegistry;\n }>;\nconst sqlIntentRegistry =\n globalWithSqlIntentRegistry[SQL_INTENT_REGISTRY] ??\n (() => {\n const registry: SqlIntentRegistry = {\n annIndexScanQueries: new WeakMap(),\n forceCustomPlanQueries: new WeakSet(),\n };\n Object.defineProperty(globalWithSqlIntentRegistry, SQL_INTENT_REGISTRY, {\n configurable: false,\n enumerable: false,\n value: registry,\n writable: false,\n });\n return registry;\n })();\n\nexport function markForceCustomPlan(query: SqlFragment): void {\n sqlIntentRegistry.forceCustomPlanQueries.add(query);\n}\n\nexport function shouldForceCustomPlan(query: SqlFragment): boolean {\n return sqlIntentRegistry.forceCustomPlanQueries.has(query);\n}\n\n/**\n * Statements whose plan includes an engine ANN index scan (the inline\n * `.similarTo(..., { approximate: true })` branch). The PostgreSQL\n * backend wraps their execution with the same pgvector GUC overrides\n * the search facade applies (`hnsw.iterative_scan = strict_order` /\n * `ivfflat.iterative_scan = relaxed_order` on pgvector >= 0.8), so a\n * filtered approximate query keeps scanning past the default ef_search\n * frontier instead of starving. Carries the slot index types so the\n * backend knows which GUCs apply. Backends without GUC semantics\n * ignore the brand.\n */\nexport function markAnnIndexScan(\n query: SqlFragment,\n indexTypes: readonly string[],\n): void {\n sqlIntentRegistry.annIndexScanQueries.set(query, indexTypes);\n}\n\nexport function annIndexScanTypes(\n query: SqlFragment,\n): readonly string[] | undefined {\n return sqlIntentRegistry.annIndexScanQueries.get(query);\n}\n\n/** @internal Copies execution semantics when immutable fragments are composed. */\nexport function copySqlIntents(\n target: SqlFragment,\n sources: readonly SqlFragment[],\n): void {\n if (sources.some((source) => shouldForceCustomPlan(source))) {\n markForceCustomPlan(target);\n }\n\n const indexTypes = new Set<string>();\n for (const source of sources) {\n for (const indexType of annIndexScanTypes(source) ?? []) {\n indexTypes.add(indexType);\n }\n }\n if (indexTypes.size > 0) markAnnIndexScan(target, [...indexTypes]);\n}\n\n/**\n * Whether a compiled statement can be run as raw text (`executeRaw`) without\n * losing execution semantics. Both brands above ride on the SQL *object* and\n * are honored only by `backend.execute`: the force-custom-plan flag makes\n * PostgreSQL re-plan against the actual parameters (opposed to reusing a\n * cached statement), and the ANN-scan brand drives the pgvector iterative-scan\n * GUC wrapper. A statement carrying either must not be flattened to text and\n * cached — callers fall back to `backend.execute`. Keeping this predicate\n * beside the brands means a future brand updates one place, not every caller.\n */\nexport function isRawExecutable(query: SqlFragment): boolean {\n return (\n !shouldForceCustomPlan(query) && annIndexScanTypes(query) === undefined\n );\n}\n","import { ConfigurationError } from \"../errors\";\nimport { typeGraphGlobalSymbol } from \"../utils/global-symbol\";\nimport {\n bindSqlValue,\n getSqlDialectProfile,\n inlineSqlStringLiteral,\n} from \"./dialect/profile\";\nimport { type SqlDialect } from \"./dialect/types\";\nimport { copySqlIntents } from \"./sql-intent\";\n\n/** Nominal identity shared by every package entrypoint. */\nconst SQL_FRAGMENT_BRAND: unique symbol = typeGraphGlobalSymbol(\"sql-fragment\");\nconst SQL_PLACEHOLDER_BRAND: unique symbol =\n typeGraphGlobalSymbol(\"sql-placeholder\");\n\nexport type SqlTextChunk = Readonly<{\n kind: \"text\";\n value: string;\n}>;\n\nexport type SqlParameterChunk = Readonly<{\n kind: \"parameter\";\n value: unknown;\n}>;\n\nexport type SqlIdentifierChunk = Readonly<{\n kind: \"identifier\";\n value: string;\n}>;\n\nexport type SqlPlaceholderChunk = Readonly<{\n kind: \"placeholder\";\n value: Placeholder;\n}>;\n\n/** One immutable unit in a database-independent SQL fragment. */\nexport type SqlChunk =\n SqlTextChunk | SqlParameterChunk | SqlIdentifierChunk | SqlPlaceholderChunk;\n\n/**\n * An immutable, database-independent SQL expression.\n *\n * Fragments contain syntax and bound values as separate nodes. A database\n * adapter renders the same fragment with its native placeholder convention at\n * the final execution boundary.\n */\nexport type SqlFragment = Readonly<{\n [SQL_FRAGMENT_BRAND]: true;\n append: (fragment: SqlFragment) => SqlFragment;\n chunks: readonly SqlChunk[];\n}>;\n\n/** A named value resolved when a prepared statement is executed. */\nexport class Placeholder {\n readonly [SQL_PLACEHOLDER_BRAND] = true as const;\n readonly name: string;\n\n constructor(name: string) {\n this.name = name;\n Object.freeze(this);\n }\n}\n\nclass SqlFragmentValue implements SqlFragment {\n readonly [SQL_FRAGMENT_BRAND] = true as const;\n\n readonly chunks: readonly SqlChunk[];\n\n constructor(chunks: readonly SqlChunk[]) {\n this.chunks = Object.freeze([...chunks]);\n Object.freeze(this);\n }\n\n append(fragment: SqlFragment): SqlFragment {\n return createFragment(\n [...this.chunks, ...getChunks(fragment)],\n [this, fragment],\n );\n }\n}\n\nfunction createFragment(\n chunks: readonly SqlChunk[],\n intentSources: readonly SqlFragment[] = [],\n): SqlFragment {\n const fragment = new SqlFragmentValue(chunks);\n copySqlIntents(fragment, intentSources);\n return fragment;\n}\n\nfunction getChunks(fragment: SqlFragment): readonly SqlChunk[] {\n if (!isSqlFragment(fragment)) {\n throw new ConfigurationError(\n \"Expected a SQL fragment created by TypeGraph's sql helper\",\n );\n }\n return fragment.chunks;\n}\n\n/** Returns whether a value is a TypeGraph-owned SQL fragment. */\nexport function isSqlFragment(value: unknown): value is SqlFragment {\n return (\n typeof value === \"object\" &&\n value !== null &&\n SQL_FRAGMENT_BRAND in value &&\n value[SQL_FRAGMENT_BRAND] === true &&\n \"chunks\" in value &&\n Array.isArray(value.chunks) &&\n \"append\" in value &&\n typeof value.append === \"function\"\n );\n}\n\n/** Returns whether a value is a TypeGraph named SQL placeholder. */\nexport function isSqlPlaceholder(value: unknown): value is Placeholder {\n return (\n typeof value === \"object\" &&\n value !== null &&\n SQL_PLACEHOLDER_BRAND in value &&\n value[SQL_PLACEHOLDER_BRAND] === true &&\n \"name\" in value &&\n typeof value.name === \"string\"\n );\n}\n\n/** @internal Enforces exhaustive handling at every fragment boundary. */\nexport function throwUnsupportedSqlChunk(chunk: never): never {\n throw new ConfigurationError(\"Unsupported SQL fragment chunk\", { chunk });\n}\n\nfunction textNode(value: string): SqlTextChunk {\n return Object.freeze({ kind: \"text\", value });\n}\n\nfunction parameterNode(value: unknown): SqlParameterChunk {\n return Object.freeze({ kind: \"parameter\", value });\n}\n\nfunction identifierNode(value: string): SqlIdentifierChunk {\n return Object.freeze({ kind: \"identifier\", value });\n}\n\nfunction placeholderNode(value: Placeholder): SqlPlaceholderChunk {\n return Object.freeze({ kind: \"placeholder\", value });\n}\n\nfunction templateSql(\n strings: TemplateStringsArray,\n ...values: readonly unknown[]\n): SqlFragment {\n const chunks: SqlChunk[] = [];\n const intentSources: SqlFragment[] = [];\n\n for (const [index, text] of strings.entries()) {\n if (text.length > 0) chunks.push(textNode(text));\n\n if (index >= values.length) continue;\n const value = values[index];\n if (isSqlFragment(value)) {\n chunks.push(...getChunks(value));\n intentSources.push(value);\n } else if (isSqlPlaceholder(value)) {\n chunks.push(placeholderNode(value));\n } else {\n chunks.push(parameterNode(value));\n }\n }\n\n return createFragment(chunks, intentSources);\n}\n\nfunction rawSql(value: string): SqlFragment {\n return createFragment(value.length === 0 ? [] : [textNode(value)]);\n}\n\nfunction identifierSql(value: string): SqlFragment {\n return createFragment([identifierNode(value)]);\n}\n\nfunction joinSql(\n fragments: readonly SqlFragment[],\n separator: SqlFragment = EMPTY_SQL,\n): SqlFragment {\n const chunks: SqlChunk[] = [];\n const intentSources: SqlFragment[] = [separator];\n\n for (const [index, fragment] of fragments.entries()) {\n if (index > 0) chunks.push(...getChunks(separator));\n chunks.push(...getChunks(fragment));\n intentSources.push(fragment);\n }\n\n return createFragment(chunks, intentSources);\n}\n\nfunction placeholderSql(name: string): SqlFragment {\n return createFragment([placeholderNode(new Placeholder(name))]);\n}\n\nconst EMPTY_SQL = createFragment([]);\n\n/** TypeGraph's database-independent SQL template and composition helpers. */\nexport type SqlTag = Readonly<{\n empty: () => SqlFragment;\n identifier: (value: string) => SqlFragment;\n join: (\n fragments: readonly SqlFragment[],\n separator?: SqlFragment,\n ) => SqlFragment;\n placeholder: (name: string) => SqlFragment;\n raw: (value: string) => SqlFragment;\n}> &\n ((\n strings: TemplateStringsArray,\n ...values: readonly unknown[]\n ) => SqlFragment);\n\n/** TypeGraph's database-independent SQL template and composition helpers. */\nexport const sql: SqlTag = Object.assign(templateSql, {\n empty: function empty(): SqlFragment {\n return EMPTY_SQL;\n },\n identifier: identifierSql,\n join: joinSql,\n placeholder: placeholderSql,\n raw: rawSql,\n});\n\n/** A rendered statement and its ordered bound parameters. */\nexport type RenderedSql = Readonly<{\n sql: string;\n params: readonly unknown[];\n}>;\n\nfunction quotedIdentifier(identifier: string): string {\n return `\"${identifier.replaceAll('\"', '\"\"')}\"`;\n}\n\nfunction resolvedPlaceholder(\n placeholder: Placeholder,\n bindings: Readonly<Record<string, unknown>> | undefined,\n dialect: SqlDialect,\n): unknown {\n if (bindings === undefined) return placeholder;\n\n if (!Object.hasOwn(bindings, placeholder.name)) {\n throw new ConfigurationError(\n `Missing binding for parameter \"${placeholder.name}\"`,\n { parameterName: placeholder.name },\n );\n }\n return bindSqlValue(bindings[placeholder.name], dialect);\n}\n\n/**\n * Renders a fragment for a database adapter.\n *\n * Named placeholders remain in `params` when `bindings` is omitted, allowing\n * a prepared template to resolve them later. Passing `bindings` resolves every\n * placeholder eagerly.\n */\nexport function renderSql(\n fragment: SqlFragment,\n dialect: SqlDialect,\n bindings?: Readonly<Record<string, unknown>>,\n): RenderedSql {\n const parts: string[] = [];\n const params: unknown[] = [];\n const profile = getSqlDialectProfile(dialect);\n\n for (const node of getChunks(fragment)) {\n switch (node.kind) {\n case \"text\": {\n parts.push(node.value);\n break;\n }\n case \"identifier\": {\n parts.push(quotedIdentifier(node.value));\n break;\n }\n case \"parameter\": {\n params.push(bindSqlValue(node.value, dialect));\n parts.push(profile.placeholder(params.length));\n break;\n }\n case \"placeholder\": {\n params.push(resolvedPlaceholder(node.value, bindings, dialect));\n parts.push(profile.placeholder(params.length));\n break;\n }\n default: {\n throwUnsupportedSqlChunk(node);\n }\n }\n }\n\n return Object.freeze({\n sql: parts.join(\"\"),\n params: Object.freeze(params),\n });\n}\n\n/** Renders a fragment using SQLite's `?` placeholders. */\nexport function renderSqlite(\n fragment: SqlFragment,\n bindings?: Readonly<Record<string, unknown>>,\n): RenderedSql {\n return renderSql(fragment, \"sqlite\", bindings);\n}\n\n/** Renders a fragment using PostgreSQL's numbered placeholders. */\nexport function renderPostgres(\n fragment: SqlFragment,\n bindings?: Readonly<Record<string, unknown>>,\n): RenderedSql {\n return renderSql(fragment, \"postgres\", bindings);\n}\n\nfunction inlineLiteral(value: unknown, dialect: SqlDialect): string {\n if (value === undefined || value === null) return \"NULL\";\n if (typeof value === \"string\") return inlineSqlStringLiteral(value, dialect);\n if (typeof value === \"number\") {\n if (!Number.isFinite(value)) {\n throw new ConfigurationError(\"Cannot inline a non-finite SQL number\", {\n value,\n });\n }\n return String(value);\n }\n if (typeof value === \"bigint\") return String(value);\n if (typeof value === \"boolean\") {\n return getSqlDialectProfile(dialect).booleanLiteralString(value);\n }\n if (value instanceof Date) {\n return inlineSqlStringLiteral(value.toISOString(), dialect);\n }\n\n throw new ConfigurationError(\"Cannot inline this SQL parameter value\", {\n value,\n });\n}\n\n/**\n * Renders a fragment with safe scalar literals instead of bound parameters.\n *\n * This is intentionally limited to DDL paths whose drivers cannot bind values.\n * Application queries should always use {@link renderSql}.\n */\nexport function renderSqlInline(\n fragment: SqlFragment,\n dialect: SqlDialect,\n): string {\n const parts: string[] = [];\n\n for (const node of getChunks(fragment)) {\n switch (node.kind) {\n case \"text\": {\n parts.push(node.value);\n break;\n }\n case \"identifier\": {\n parts.push(quotedIdentifier(node.value));\n break;\n }\n case \"parameter\": {\n parts.push(inlineLiteral(node.value, dialect));\n break;\n }\n case \"placeholder\": {\n throw new ConfigurationError(\n `Cannot inline unresolved SQL placeholder \"${node.value.name}\"`,\n { parameterName: node.value.name },\n );\n }\n default: {\n throwUnsupportedSqlChunk(node);\n }\n }\n }\n\n return parts.join(\"\");\n}\n"]}
|
|
@@ -1,25 +1,11 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import { runOptionallyInTransaction } from './chunk-
|
|
1
|
+
import { resolvedTableNames } from './chunk-IRCWIA3R.js';
|
|
2
|
+
import { statementExecutionVerdict } from './chunk-XORONCV3.js';
|
|
3
|
+
import { runOptionallyInTransaction, createSqlSchema, statementExecutionMembers } from './chunk-LKZDQ2B4.js';
|
|
4
4
|
import { asRecordedInstant, createRecordedInstant, RECORDED_MAX_REVISION } from './chunk-6NKSE5AU.js';
|
|
5
5
|
import { canonicalizeDatabaseTimestamp } from './chunk-K46SDNQD.js';
|
|
6
|
-
import { shortHash } from './chunk-
|
|
7
|
-
import { asCompiledRowsSql, sql, asCompiledStatementSql } from './chunk-
|
|
8
|
-
import { ConfigurationError, ValidationError } from './chunk-YDEJQWOL.js';
|
|
9
|
-
|
|
10
|
-
// src/backend/table-names.ts
|
|
11
|
-
function definedTableNameOverrides(override) {
|
|
12
|
-
if (override === void 0) return {};
|
|
13
|
-
return Object.fromEntries(
|
|
14
|
-
Object.entries(override).filter(([, tableName]) => tableName !== void 0)
|
|
15
|
-
);
|
|
16
|
-
}
|
|
17
|
-
function resolvedTableNames(backend, override) {
|
|
18
|
-
return createSqlSchema({
|
|
19
|
-
...backend.tableNames,
|
|
20
|
-
...definedTableNameOverrides(override)
|
|
21
|
-
}).tables;
|
|
22
|
-
}
|
|
6
|
+
import { shortHash } from './chunk-PC5NGH5A.js';
|
|
7
|
+
import { asCompiledRowsSql, sql, asCompiledStatementSql } from './chunk-7QFRK6PU.js';
|
|
8
|
+
import { ConfigurationError, UnsupportedBackendCapabilityError, ValidationError } from './chunk-YDEJQWOL.js';
|
|
23
9
|
|
|
24
10
|
// src/backend/migrate-recorded-time.ts
|
|
25
11
|
var LEGACY_RECORDED_MAX = "9999-12-31T23:59:59.999Z";
|
|
@@ -222,46 +208,48 @@ async function writeMappingRows(target, tableName, rows) {
|
|
|
222
208
|
);
|
|
223
209
|
}
|
|
224
210
|
}
|
|
225
|
-
function
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
211
|
+
function recordedMigrationDdl(recordedTableDdl, finalNames, temporaryNames) {
|
|
212
|
+
const temporaryDdl = recordedTableDdl(temporaryNames);
|
|
213
|
+
const finalDdl = recordedTableDdl(finalNames);
|
|
214
|
+
function composed(key) {
|
|
215
|
+
return {
|
|
216
|
+
createTable: temporaryDdl[key].createTable,
|
|
217
|
+
indexes: finalDdl[key].indexes
|
|
218
|
+
};
|
|
232
219
|
}
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
}
|
|
240
|
-
function ddlForRecordedTables(temporary, final) {
|
|
241
|
-
function statements(logicalName) {
|
|
242
|
-
const temporaryDdl = temporary.find(
|
|
243
|
-
(entry) => entry.logicalName === logicalName
|
|
244
|
-
)?.createDdl;
|
|
245
|
-
const finalDdl = final.find(
|
|
246
|
-
(entry) => entry.logicalName === logicalName
|
|
247
|
-
)?.createDdl;
|
|
248
|
-
if (temporaryDdl === void 0 || finalDdl === void 0) {
|
|
249
|
-
throw new ConfigurationError(
|
|
250
|
-
`Could not generate migration DDL for ${logicalName}.`
|
|
251
|
-
);
|
|
252
|
-
}
|
|
253
|
-
const createTable = temporaryDdl[0];
|
|
254
|
-
if (createTable === void 0) {
|
|
220
|
+
function primaryKeyConstraintRename(key) {
|
|
221
|
+
const temporaryConstraintName = temporaryDdl[key].primaryKeyConstraintName;
|
|
222
|
+
const finalConstraintName = finalDdl[key].primaryKeyConstraintName;
|
|
223
|
+
if (temporaryConstraintName === void 0 && finalConstraintName === void 0)
|
|
224
|
+
return { status: "none" };
|
|
225
|
+
if (temporaryConstraintName === void 0 || finalConstraintName === void 0)
|
|
255
226
|
throw new ConfigurationError(
|
|
256
|
-
|
|
227
|
+
"Recorded relation DDL must name both primary-key constraints or neither.",
|
|
228
|
+
{
|
|
229
|
+
code: "RECORDED_DDL_CONSTRAINT_NAME_MISMATCH",
|
|
230
|
+
relation: key,
|
|
231
|
+
finalTable: finalNames[key],
|
|
232
|
+
temporaryConstraintName,
|
|
233
|
+
finalConstraintName
|
|
234
|
+
}
|
|
257
235
|
);
|
|
258
|
-
|
|
259
|
-
|
|
236
|
+
return {
|
|
237
|
+
status: "rename",
|
|
238
|
+
from: temporaryConstraintName,
|
|
239
|
+
to: finalConstraintName
|
|
240
|
+
};
|
|
260
241
|
}
|
|
261
242
|
return {
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
243
|
+
ddl: {
|
|
244
|
+
recordedClock: composed("recordedClock"),
|
|
245
|
+
recordedEdges: composed("recordedEdges"),
|
|
246
|
+
recordedNodes: composed("recordedNodes")
|
|
247
|
+
},
|
|
248
|
+
primaryKeyConstraintRenames: {
|
|
249
|
+
recordedClock: primaryKeyConstraintRename("recordedClock"),
|
|
250
|
+
recordedEdges: primaryKeyConstraintRename("recordedEdges"),
|
|
251
|
+
recordedNodes: primaryKeyConstraintRename("recordedNodes")
|
|
252
|
+
}
|
|
265
253
|
};
|
|
266
254
|
}
|
|
267
255
|
function migratedColumn(column, legacyAlias) {
|
|
@@ -381,22 +369,31 @@ async function copyRecordedClock(target, options) {
|
|
|
381
369
|
`
|
|
382
370
|
);
|
|
383
371
|
}
|
|
384
|
-
async function replaceLegacyTables(target, tables, mappingTable) {
|
|
372
|
+
async function replaceLegacyTables(target, tables, mappingTable, recordedTableDdl) {
|
|
385
373
|
const temporary = {
|
|
386
374
|
recordedNodes: temporaryTableName(tables.recordedNodes, "rn"),
|
|
387
375
|
recordedEdges: temporaryTableName(tables.recordedEdges, "re"),
|
|
388
376
|
recordedClock: temporaryTableName(tables.recordedClock, "rc")
|
|
389
377
|
};
|
|
390
|
-
const
|
|
378
|
+
const finalNames = {
|
|
379
|
+
recordedNodes: tables.recordedNodes,
|
|
380
|
+
recordedEdges: tables.recordedEdges,
|
|
381
|
+
recordedClock: tables.recordedClock
|
|
382
|
+
};
|
|
383
|
+
const { ddl, primaryKeyConstraintRenames } = recordedMigrationDdl(
|
|
384
|
+
recordedTableDdl,
|
|
385
|
+
finalNames,
|
|
386
|
+
temporary
|
|
387
|
+
);
|
|
391
388
|
for (const table of Object.values(temporary)) {
|
|
392
389
|
await executeStatement(
|
|
393
390
|
target,
|
|
394
391
|
sql`DROP TABLE IF EXISTS ${sql.identifier(table)}`
|
|
395
392
|
);
|
|
396
393
|
}
|
|
397
|
-
await executeDdl(target,
|
|
398
|
-
await executeDdl(target,
|
|
399
|
-
await executeDdl(target,
|
|
394
|
+
await executeDdl(target, ddl.recordedNodes.createTable);
|
|
395
|
+
await executeDdl(target, ddl.recordedEdges.createTable);
|
|
396
|
+
await executeDdl(target, ddl.recordedClock.createTable);
|
|
400
397
|
await copyRecordedRelation(target, {
|
|
401
398
|
columns: RECORDED_NODE_COLUMNS,
|
|
402
399
|
legacyTable: tables.recordedNodes,
|
|
@@ -431,45 +428,38 @@ async function replaceLegacyTables(target, tables, mappingTable) {
|
|
|
431
428
|
await renameTable(target, temporary.recordedClock, tables.recordedClock);
|
|
432
429
|
await renamePrimaryKeyConstraint(
|
|
433
430
|
target,
|
|
434
|
-
|
|
435
|
-
|
|
431
|
+
tables.recordedNodes,
|
|
432
|
+
primaryKeyConstraintRenames.recordedNodes
|
|
436
433
|
);
|
|
437
434
|
await renamePrimaryKeyConstraint(
|
|
438
435
|
target,
|
|
439
|
-
|
|
440
|
-
|
|
436
|
+
tables.recordedEdges,
|
|
437
|
+
primaryKeyConstraintRenames.recordedEdges
|
|
441
438
|
);
|
|
442
439
|
await renamePrimaryKeyConstraint(
|
|
443
440
|
target,
|
|
444
|
-
|
|
445
|
-
|
|
441
|
+
tables.recordedClock,
|
|
442
|
+
primaryKeyConstraintRenames.recordedClock
|
|
446
443
|
);
|
|
447
444
|
for (const statement of [
|
|
448
|
-
...ddl.
|
|
449
|
-
...ddl.
|
|
450
|
-
...ddl.
|
|
445
|
+
...ddl.recordedNodes.indexes,
|
|
446
|
+
...ddl.recordedEdges.indexes,
|
|
447
|
+
...ddl.recordedClock.indexes
|
|
451
448
|
]) {
|
|
452
449
|
await executeDdl(target, statement);
|
|
453
450
|
}
|
|
454
451
|
}
|
|
455
|
-
async function renamePrimaryKeyConstraint(target,
|
|
456
|
-
if (
|
|
452
|
+
async function renamePrimaryKeyConstraint(target, finalTable, rename) {
|
|
453
|
+
if (rename.status === "none") return;
|
|
457
454
|
await executeStatement(
|
|
458
455
|
target,
|
|
459
456
|
sql`
|
|
460
457
|
ALTER TABLE ${sql.identifier(finalTable)}
|
|
461
|
-
RENAME CONSTRAINT ${sql.identifier(
|
|
462
|
-
TO ${sql.identifier(shortenedIdentifier(
|
|
458
|
+
RENAME CONSTRAINT ${sql.identifier(rename.from)}
|
|
459
|
+
TO ${sql.identifier(shortenedIdentifier(rename.to))}
|
|
463
460
|
`
|
|
464
461
|
);
|
|
465
462
|
}
|
|
466
|
-
function requireCreateTable(statements) {
|
|
467
|
-
const statement = statements[0];
|
|
468
|
-
if (statement === void 0) {
|
|
469
|
-
throw new ConfigurationError("Recorded migration table DDL was empty.");
|
|
470
|
-
}
|
|
471
|
-
return statement;
|
|
472
|
-
}
|
|
473
463
|
async function renameTable(target, from, to) {
|
|
474
464
|
try {
|
|
475
465
|
await executeStatement(
|
|
@@ -487,6 +477,7 @@ async function renameTable(target, from, to) {
|
|
|
487
477
|
async function migrateLegacyRecordedTime(options) {
|
|
488
478
|
const tables = resolvedTableNames(options.backend, options.tableNames);
|
|
489
479
|
const mapTable = mappingTableName(tables, options.mappingTableName);
|
|
480
|
+
const recordedTableDdl = options.backend.recordedTableDdl;
|
|
490
481
|
return options.backend.transaction(async (target) => {
|
|
491
482
|
const clockColumns = await columnNames(target, tables.recordedClock);
|
|
492
483
|
if (clockColumns.size === 0) {
|
|
@@ -530,10 +521,18 @@ async function migrateLegacyRecordedTime(options) {
|
|
|
530
521
|
{ tables }
|
|
531
522
|
);
|
|
532
523
|
}
|
|
524
|
+
if (recordedTableDdl === void 0) {
|
|
525
|
+
throw new UnsupportedBackendCapabilityError(
|
|
526
|
+
"migrateLegacyRecordedTime",
|
|
527
|
+
"recordedTableDdl",
|
|
528
|
+
{ dialect: target.dialect, tables },
|
|
529
|
+
"Migrating the timestamp-only preview recorded schema needs the backend to author its own recorded-relation DDL. Only the bundled SQLite and PostgreSQL backends created that schema."
|
|
530
|
+
);
|
|
531
|
+
}
|
|
533
532
|
await executeDdl(target, migrationMapDdl(target.dialect, mapTable));
|
|
534
533
|
const mapping = await readLegacyInstants(target, tables);
|
|
535
534
|
await writeMappingRows(target, mapTable, mapping);
|
|
536
|
-
await replaceLegacyTables(target, tables, mapTable);
|
|
535
|
+
await replaceLegacyTables(target, tables, mapTable, recordedTableDdl);
|
|
537
536
|
return {
|
|
538
537
|
migrated: true,
|
|
539
538
|
graphs: new Set(mapping.map((row) => row.graphId)).size,
|
|
@@ -575,12 +574,7 @@ async function migrateRecordedAnchor(options) {
|
|
|
575
574
|
);
|
|
576
575
|
}
|
|
577
576
|
async function deleteLegacyRecordedAnchorMap(options) {
|
|
578
|
-
|
|
579
|
-
throw new ConfigurationError(
|
|
580
|
-
"Deleting a recorded anchor migration map requires executeStatement support.",
|
|
581
|
-
{ dialect: options.backend.dialect }
|
|
582
|
-
);
|
|
583
|
-
}
|
|
577
|
+
requireStatements(options.backend);
|
|
584
578
|
const tables = resolvedTableNames(options.backend, options.tableNames);
|
|
585
579
|
const mapTable = mappingTableName(tables, options.mappingTableName);
|
|
586
580
|
await options.backend.transaction(async (target) => {
|
|
@@ -690,17 +684,14 @@ async function countMatching(target, table, predicate) {
|
|
|
690
684
|
);
|
|
691
685
|
return safeCount(rows[0]?.matches, table);
|
|
692
686
|
}
|
|
693
|
-
function
|
|
694
|
-
|
|
695
|
-
|
|
696
|
-
|
|
697
|
-
|
|
698
|
-
|
|
699
|
-
|
|
700
|
-
|
|
701
|
-
);
|
|
702
|
-
}
|
|
703
|
-
return target.executeStatement;
|
|
687
|
+
function statementExecutionRequiredError(dialect) {
|
|
688
|
+
return new ConfigurationError(
|
|
689
|
+
"Repairing inverted validity windows requires executeStatement support.",
|
|
690
|
+
{ dialect, mode: "apply" },
|
|
691
|
+
{
|
|
692
|
+
suggestion: 'Use a built-in SQLite or PostgreSQL backend to apply the repair. Detection needs no such support: call this with mode: "report" to count the affected rows on any backend.'
|
|
693
|
+
}
|
|
694
|
+
);
|
|
704
695
|
}
|
|
705
696
|
function translatedCaptureRefusal(error) {
|
|
706
697
|
if (!(error instanceof ConfigurationError) || error.details["code"] !== "RECORDED_CAPTURE_RAW_SQL_DISABLED") {
|
|
@@ -715,9 +706,12 @@ function translatedCaptureRefusal(error) {
|
|
|
715
706
|
}
|
|
716
707
|
);
|
|
717
708
|
}
|
|
718
|
-
async function repairRelation(target, table, predicate) {
|
|
709
|
+
async function repairRelation(target, verdict, table, predicate) {
|
|
710
|
+
if (!verdict.supported) {
|
|
711
|
+
throw statementExecutionRequiredError(target.dialect);
|
|
712
|
+
}
|
|
719
713
|
try {
|
|
720
|
-
await
|
|
714
|
+
await statementExecutionMembers(target, verdict).executeStatement(
|
|
721
715
|
asCompiledStatementSql(sql`
|
|
722
716
|
UPDATE ${sql.identifier(table)}
|
|
723
717
|
SET valid_from = NULL
|
|
@@ -753,7 +747,10 @@ function relationRecord(counts) {
|
|
|
753
747
|
async function repairInvertedValidityWindows(options) {
|
|
754
748
|
const tables = resolvedTableNames(options.backend, options.tableNames);
|
|
755
749
|
const relations = scopedRelations(options.relations);
|
|
756
|
-
|
|
750
|
+
const verdict = statementExecutionVerdict(options.backend);
|
|
751
|
+
if (options.mode === "apply" && !verdict.supported) {
|
|
752
|
+
throw statementExecutionRequiredError(options.backend.dialect);
|
|
753
|
+
}
|
|
757
754
|
return runOptionallyInTransaction(
|
|
758
755
|
options.backend,
|
|
759
756
|
async (target, execution) => {
|
|
@@ -780,6 +777,7 @@ async function repairInvertedValidityWindows(options) {
|
|
|
780
777
|
for (const relation of relations) {
|
|
781
778
|
await repairRelation(
|
|
782
779
|
target,
|
|
780
|
+
verdict,
|
|
783
781
|
relationTable(tables, relation),
|
|
784
782
|
predicate
|
|
785
783
|
);
|
|
@@ -797,5 +795,5 @@ async function repairInvertedValidityWindows(options) {
|
|
|
797
795
|
}
|
|
798
796
|
|
|
799
797
|
export { deleteLegacyRecordedAnchorMap, migrateLegacyRecordedTime, migrateRecordedAnchor, repairInvertedValidityWindows };
|
|
800
|
-
//# sourceMappingURL=chunk-
|
|
801
|
-
//# sourceMappingURL=chunk-
|
|
798
|
+
//# sourceMappingURL=chunk-I5IOSA27.js.map
|
|
799
|
+
//# sourceMappingURL=chunk-I5IOSA27.js.map
|