@nicia-ai/typegraph 0.49.0 → 0.51.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +12 -0
- package/dist/backend/drizzle/indexes.cjs +11 -9
- package/dist/backend/drizzle/indexes.d.cts +1 -1
- package/dist/backend/drizzle/indexes.d.ts +1 -1
- package/dist/backend/drizzle/indexes.js +7 -5
- package/dist/backend/index.cjs +190 -53
- package/dist/backend/index.d.cts +90 -4
- package/dist/backend/index.d.ts +90 -4
- package/dist/backend/index.js +9 -12
- package/dist/backend/postgres/index.cjs +36 -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 +19 -15
- package/dist/backend/postgres/pglite-store.cjs +7 -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 +7 -62
- package/dist/backend/postgres/pglite-store.js.map +1 -1
- package/dist/backend/postgres/pglite.cjs +21 -17
- package/dist/backend/postgres/pglite.d.cts +3 -3
- package/dist/backend/postgres/pglite.d.ts +3 -3
- package/dist/backend/postgres/pglite.js +20 -16
- package/dist/backend/sqlite/index.cjs +33 -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 +17 -13
- package/dist/backend/sqlite/libsql.cjs +24 -20
- 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 +19 -15
- package/dist/backend/sqlite/libsql.js.map +1 -1
- package/dist/backend/sqlite/local-store.cjs +9 -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 +8 -64
- package/dist/backend/sqlite/local-store.js.map +1 -1
- package/dist/backend/sqlite/local.cjs +25 -20
- package/dist/backend/sqlite/local.d.cts +3 -3
- package/dist/backend/sqlite/local.d.ts +3 -3
- package/dist/backend/sqlite/local.js +21 -16
- package/dist/chunk-2CVDZCXH.cjs +1278 -0
- package/dist/chunk-2CVDZCXH.cjs.map +1 -0
- package/dist/{chunk-MYKHJI2J.js → chunk-2DWTBNSH.js} +3 -3
- package/dist/{chunk-MYKHJI2J.js.map → chunk-2DWTBNSH.js.map} +1 -1
- package/dist/{chunk-JB6T4GLL.cjs → chunk-2KCTP3U2.cjs} +870 -528
- package/dist/chunk-2KCTP3U2.cjs.map +1 -0
- package/dist/{chunk-OORXGFL5.cjs → chunk-322TBTOQ.cjs} +48 -48
- package/dist/{chunk-OORXGFL5.cjs.map → chunk-322TBTOQ.cjs.map} +1 -1
- package/dist/{chunk-FA2AFWLP.cjs → chunk-36SX6QXP.cjs} +31 -12
- package/dist/chunk-36SX6QXP.cjs.map +1 -0
- package/dist/{chunk-SDBBMD4N.js → chunk-36VYWVQU.js} +3 -3
- package/dist/{chunk-SDBBMD4N.js.map → chunk-36VYWVQU.js.map} +1 -1
- package/dist/chunk-4DKY6RIU.js +1253 -0
- 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-WIC7DRXW.js → chunk-57JM6NW3.js} +9 -19
- package/dist/chunk-57JM6NW3.js.map +1 -0
- package/dist/chunk-5WWEYV4H.cjs +5113 -0
- package/dist/chunk-5WWEYV4H.cjs.map +1 -0
- package/dist/chunk-6KQEICJ6.cjs +12 -0
- package/dist/{chunk-MKJ4KXL5.cjs.map → chunk-6KQEICJ6.cjs.map} +1 -1
- package/dist/{chunk-DZAICA5J.js → chunk-6NKSE5AU.js} +4 -4
- package/dist/{chunk-DZAICA5J.js.map → chunk-6NKSE5AU.js.map} +1 -1
- package/dist/{chunk-KKBDXCLQ.js → chunk-6NLYIMJO.js} +4 -4
- package/dist/{chunk-KKBDXCLQ.js.map → chunk-6NLYIMJO.js.map} +1 -1
- package/dist/{chunk-BFUOME67.cjs → chunk-7B7I7YAW.cjs} +20 -11
- package/dist/chunk-7B7I7YAW.cjs.map +1 -0
- package/dist/{chunk-ZDKTPBGV.js → chunk-7G5IYROL.js} +6 -548
- package/dist/chunk-7G5IYROL.js.map +1 -0
- package/dist/{chunk-3DMMGT6S.js → chunk-7QFRK6PU.js} +4 -8
- 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-CHAOFCHV.js → chunk-AH2A74OZ.js} +3 -3
- package/dist/{chunk-CHAOFCHV.js.map → chunk-AH2A74OZ.js.map} +1 -1
- package/dist/{chunk-UGHQV7MP.cjs → chunk-B3MN7EJR.cjs} +228 -162
- package/dist/chunk-B3MN7EJR.cjs.map +1 -0
- package/dist/{chunk-TZEGUG6D.cjs → chunk-BZ5MVITP.cjs} +4 -4
- package/dist/{chunk-TZEGUG6D.cjs.map → chunk-BZ5MVITP.cjs.map} +1 -1
- package/dist/{chunk-YVF2EM7B.js → chunk-CAI6SMP6.js} +3 -3
- package/dist/{chunk-YVF2EM7B.js.map → chunk-CAI6SMP6.js.map} +1 -1
- package/dist/{chunk-JONXFAPO.js → chunk-CBOD7TXH.js} +5 -5
- package/dist/{chunk-JONXFAPO.js.map → chunk-CBOD7TXH.js.map} +1 -1
- package/dist/{chunk-FQPEMEWX.cjs → chunk-CRZ56SZU.cjs} +81 -32
- package/dist/chunk-CRZ56SZU.cjs.map +1 -0
- package/dist/{chunk-DO7SAMEK.cjs → chunk-D3GWARN7.cjs} +47 -47
- package/dist/{chunk-DO7SAMEK.cjs.map → chunk-D3GWARN7.cjs.map} +1 -1
- package/dist/{chunk-QTD6HX4O.js → chunk-D3OUDFU7.js} +5 -5
- package/dist/{chunk-QTD6HX4O.js.map → chunk-D3OUDFU7.js.map} +1 -1
- package/dist/{chunk-2QGYQBS2.cjs → chunk-DWUDZ66O.cjs} +10 -10
- package/dist/{chunk-2QGYQBS2.cjs.map → chunk-DWUDZ66O.cjs.map} +1 -1
- package/dist/chunk-EKG2UXNX.cjs +23 -0
- package/dist/chunk-EKG2UXNX.cjs.map +1 -0
- package/dist/chunk-FMMW3KX7.cjs +148 -0
- package/dist/chunk-FMMW3KX7.cjs.map +1 -0
- package/dist/{chunk-XVWOYKIK.js → chunk-FZHF5UWR.js} +3 -3
- package/dist/{chunk-XVWOYKIK.js.map → chunk-FZHF5UWR.js.map} +1 -1
- 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-EDN4Y4ZG.cjs → chunk-H5IJSROF.cjs} +9 -15
- package/dist/chunk-H5IJSROF.cjs.map +1 -0
- package/dist/chunk-HZUB5CON.js +27 -0
- package/dist/chunk-HZUB5CON.js.map +1 -0
- package/dist/{chunk-NACVVDWB.js → chunk-I5IOSA27.js} +103 -105
- package/dist/chunk-I5IOSA27.js.map +1 -0
- package/dist/{chunk-OI2GQ25X.cjs → chunk-I7YAY2VQ.cjs} +7 -7
- package/dist/{chunk-OI2GQ25X.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-7SQSZN2J.js → chunk-IZD4HTCP.js} +5 -5
- package/dist/{chunk-7SQSZN2J.js.map → chunk-IZD4HTCP.js.map} +1 -1
- package/dist/{chunk-3FPR224C.cjs → chunk-JHRUZ73O.cjs} +116 -107
- package/dist/chunk-JHRUZ73O.cjs.map +1 -0
- package/dist/{chunk-EZEEWCFJ.cjs → chunk-JQKMEKKW.cjs} +525 -298
- 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-5K2BKEBD.js → chunk-K46SDNQD.js} +10 -4
- package/dist/chunk-K46SDNQD.js.map +1 -0
- package/dist/{chunk-7LZJNLA5.js → chunk-K67P5DLL.js} +108 -42
- package/dist/chunk-K67P5DLL.js.map +1 -0
- package/dist/{chunk-3G5W2U2L.cjs → chunk-KACEYDYV.cjs} +335 -258
- package/dist/chunk-KACEYDYV.cjs.map +1 -0
- package/dist/{chunk-JFRT7S3B.cjs → chunk-L6EVYIID.cjs} +318 -478
- package/dist/chunk-L6EVYIID.cjs.map +1 -0
- package/dist/{chunk-SHFBB23Q.js → chunk-LI4K2KEJ.js} +6 -4
- package/dist/chunk-LI4K2KEJ.js.map +1 -0
- package/dist/chunk-LKZDQ2B4.js +1581 -0
- package/dist/chunk-LKZDQ2B4.js.map +1 -0
- package/dist/{chunk-WODMN3Q2.cjs → chunk-LLFPQOBA.cjs} +27 -27
- package/dist/{chunk-WODMN3Q2.cjs.map → chunk-LLFPQOBA.cjs.map} +1 -1
- package/dist/{chunk-P6YLZTRE.js → chunk-LZMQ3SFK.js} +3 -3
- package/dist/{chunk-P6YLZTRE.js.map → chunk-LZMQ3SFK.js.map} +1 -1
- package/dist/{chunk-HEV35TGT.js → chunk-M3VTS3F6.js} +13 -4
- package/dist/chunk-M3VTS3F6.js.map +1 -0
- package/dist/{chunk-TQHGE7UC.cjs → chunk-M5MSP3BI.cjs} +18 -10
- package/dist/chunk-M5MSP3BI.cjs.map +1 -0
- package/dist/{chunk-D4QLTJSM.js → chunk-NBOS7BY3.js} +63 -23
- package/dist/chunk-NBOS7BY3.js.map +1 -0
- package/dist/chunk-NGQDGL5X.js +140 -0
- package/dist/chunk-NGQDGL5X.js.map +1 -0
- package/dist/{chunk-SIT26LAZ.cjs → chunk-NLX5OWK7.cjs} +33 -5
- 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-UMGZDVOA.cjs → chunk-OGL4X4PH.cjs} +206 -208
- package/dist/chunk-OGL4X4PH.cjs.map +1 -0
- package/dist/{chunk-LRQKXRXO.cjs → chunk-OTNTGEXR.cjs} +4 -4
- package/dist/{chunk-LRQKXRXO.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-26YKDNUD.cjs → chunk-PS3TUWJM.cjs} +12 -10
- package/dist/chunk-PS3TUWJM.cjs.map +1 -0
- package/dist/{chunk-OMZ37BM2.js → chunk-PVFFH7TL.js} +5 -5
- package/dist/{chunk-OMZ37BM2.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-UGHG7PGX.js → chunk-QG5VEOKX.js} +30 -4
- package/dist/chunk-QG5VEOKX.js.map +1 -0
- package/dist/{chunk-TUNPBZY3.cjs → chunk-QLLZM5I3.cjs} +4 -4
- package/dist/{chunk-TUNPBZY3.cjs.map → chunk-QLLZM5I3.cjs.map} +1 -1
- package/dist/{chunk-BRRP76WO.js → chunk-RCBG6YMT.js} +781 -375
- package/dist/chunk-RCBG6YMT.js.map +1 -0
- package/dist/{chunk-LTXQOEIC.js → chunk-RI7RJH4G.js} +281 -204
- package/dist/chunk-RI7RJH4G.js.map +1 -0
- package/dist/{chunk-GYEG3ZLZ.cjs → chunk-RJMHU2MG.cjs} +121 -18
- package/dist/chunk-RJMHU2MG.cjs.map +1 -0
- package/dist/{chunk-GLHXM7C4.js → chunk-RVUL2HXY.js} +61 -23
- package/dist/chunk-RVUL2HXY.js.map +1 -0
- package/dist/chunk-RWUWTJQY.cjs +30 -0
- package/dist/chunk-RWUWTJQY.cjs.map +1 -0
- package/dist/{chunk-2O4PCIZ6.cjs → chunk-S5GU4LUN.cjs} +13 -13
- package/dist/{chunk-2O4PCIZ6.cjs.map → chunk-S5GU4LUN.cjs.map} +1 -1
- package/dist/{chunk-JPD2CTC3.js → chunk-SDPWO2Z5.js} +7 -7
- package/dist/{chunk-JPD2CTC3.js.map → chunk-SDPWO2Z5.js.map} +1 -1
- package/dist/{chunk-OVI7IXYX.js → chunk-SLGGT2XD.js} +3 -3
- package/dist/{chunk-OVI7IXYX.js.map → chunk-SLGGT2XD.js.map} +1 -1
- package/dist/{chunk-ROR5ZR6A.cjs → chunk-TIJUA4I6.cjs} +45 -45
- package/dist/{chunk-ROR5ZR6A.cjs.map → chunk-TIJUA4I6.cjs.map} +1 -1
- package/dist/{chunk-AOSSQDVO.cjs → chunk-TM54OBHX.cjs} +13 -13
- package/dist/{chunk-AOSSQDVO.cjs.map → chunk-TM54OBHX.cjs.map} +1 -1
- package/dist/{chunk-KF6K7TGH.js → chunk-TYEYRCXL.js} +766 -433
- package/dist/chunk-TYEYRCXL.js.map +1 -0
- package/dist/{chunk-Z2JCLZFJ.js → chunk-UKOVGCRN.js} +2151 -570
- package/dist/chunk-UKOVGCRN.js.map +1 -0
- package/dist/chunk-UYKDYE5D.cjs +12 -0
- package/dist/{chunk-CICO5GXD.cjs.map → chunk-UYKDYE5D.cjs.map} +1 -1
- package/dist/{chunk-S5TERQVW.js → chunk-VAAC7L57.js} +284 -66
- package/dist/chunk-VAAC7L57.js.map +1 -0
- package/dist/{chunk-7UOLHNWC.cjs → chunk-VKHXYVN7.cjs} +22 -33
- package/dist/chunk-VKHXYVN7.cjs.map +1 -0
- package/dist/{chunk-6NGW27EO.cjs → chunk-VLBTRXA2.cjs} +10 -10
- package/dist/{chunk-6NGW27EO.cjs.map → chunk-VLBTRXA2.cjs.map} +1 -1
- package/dist/{chunk-YIURNGXI.js → chunk-VUQZNUHU.js} +22 -6
- package/dist/chunk-VUQZNUHU.js.map +1 -0
- package/dist/{chunk-YYUHLYM2.cjs → chunk-WDM5WQK4.cjs} +183 -143
- package/dist/chunk-WDM5WQK4.cjs.map +1 -0
- package/dist/{chunk-ZFMCDJGB.js → chunk-WFSYYU4W.js} +70 -220
- package/dist/chunk-WFSYYU4W.js.map +1 -0
- package/dist/{chunk-SR725PWF.cjs → chunk-WRBV2FNH.cjs} +2065 -1659
- package/dist/chunk-WRBV2FNH.cjs.map +1 -0
- package/dist/{chunk-MRDBBHIZ.cjs → chunk-X4GDXBOP.cjs} +2 -2
- package/dist/chunk-X4GDXBOP.cjs.map +1 -0
- package/dist/chunk-XORONCV3.js +202 -0
- package/dist/chunk-XORONCV3.js.map +1 -0
- package/dist/{chunk-D5R42W5D.js → chunk-XZW2CTNO.js} +115 -12
- package/dist/chunk-XZW2CTNO.js.map +1 -0
- package/dist/{chunk-ZLONH2UD.js → chunk-YDEJQWOL.js} +2 -2
- package/dist/chunk-YDEJQWOL.js.map +1 -0
- package/dist/{chunk-2TYSSBU5.js → chunk-YT2IVFAI.js} +30 -21
- package/dist/chunk-YT2IVFAI.js.map +1 -0
- package/dist/chunk-ZGVTNKTX.cjs +217 -0
- package/dist/chunk-ZGVTNKTX.cjs.map +1 -0
- package/dist/core/index.cjs +29 -28
- package/dist/core/index.d.cts +4 -4
- package/dist/core/index.d.ts +4 -4
- package/dist/core/index.js +9 -8
- package/dist/{ddl-D_oW-EVO.d.ts → ddl-BvcbgzHo.d.ts} +3 -3
- package/dist/{ddl-BL1NZLMY.d.cts → ddl-Ufebz5q5.d.cts} +3 -3
- package/dist/graph-extension/index.cjs +21 -20
- package/dist/graph-extension/index.d.cts +2 -4
- package/dist/graph-extension/index.d.ts +2 -4
- package/dist/graph-extension/index.js +5 -4
- package/dist/graph-merge/index.cjs +324 -307
- 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 +51 -34
- package/dist/graph-merge/index.js.map +1 -1
- package/dist/index.cjs +224 -222
- 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 +38 -36
- package/dist/index.js.map +1 -1
- package/dist/indexes/index.cjs +15 -13
- package/dist/indexes/index.d.cts +4 -4
- package/dist/indexes/index.d.ts +4 -4
- package/dist/indexes/index.js +8 -6
- package/dist/{ingestion-import-target-dNeL7iAv.d.ts → ingestion-import-target-CAs1OX-l.d.cts} +1 -1
- package/dist/{ingestion-import-target-XPxZYw89.d.cts → ingestion-import-target-DCQSPfNx.d.ts} +1 -1
- package/dist/interchange/index.cjs +57 -54
- package/dist/interchange/index.cjs.map +1 -1
- package/dist/interchange/index.d.cts +19 -8
- package/dist/interchange/index.d.ts +19 -8
- package/dist/interchange/index.js +21 -18
- package/dist/interchange/index.js.map +1 -1
- package/dist/local-store-impl-6DDTFM32.cjs +77 -0
- package/dist/local-store-impl-6DDTFM32.cjs.map +1 -0
- package/dist/local-store-impl-OXTOVU2J.js +75 -0
- package/dist/local-store-impl-OXTOVU2J.js.map +1 -0
- package/dist/{manager-CYaff3n3.d.cts → manager-B68OrPR2.d.ts} +29 -2
- package/dist/{manager-D9eRT_ns.d.ts → manager-D_t7oK69.d.cts} +29 -2
- package/dist/pglite-store-impl-6EMZGL7K.js +73 -0
- package/dist/pglite-store-impl-6EMZGL7K.js.map +1 -0
- package/dist/pglite-store-impl-GJG3Y7RP.cjs +75 -0
- package/dist/pglite-store-impl-GJG3Y7RP.cjs.map +1 -0
- package/dist/{postgres-CcL4bAHS.d.ts → postgres-BPLSVyHM.d.ts} +279 -2
- package/dist/{postgres-DMj39MEu.d.cts → postgres-CqvtFC2y.d.cts} +279 -2
- package/dist/profiler/index.d.cts +9 -9
- package/dist/profiler/index.d.ts +9 -9
- package/dist/provenance/index.cjs +59 -44
- 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 +28 -13
- package/dist/provenance/index.js.map +1 -1
- package/dist/{repair-validity-windows-BFNZvd_H.d.cts → repair-validity-windows-DEzCKAdy.d.cts} +7 -3
- package/dist/{repair-validity-windows-DlUSqwCg.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 +48 -46
- package/dist/schema/index.d.cts +4 -6
- package/dist/schema/index.d.ts +4 -6
- package/dist/schema/index.js +21 -19
- package/dist/{searchable-bpE1bBfc.d.ts → searchable-C_UREI9K.d.ts} +1 -1
- package/dist/{searchable-DHJMh_nj.d.cts → searchable-ClgET_i7.d.cts} +1 -1
- package/dist/{sqlite-YppHrNFb.d.cts → sqlite-D1mXO9Kp.d.cts} +310 -2
- package/dist/{sqlite-D7Oz0SQh.d.ts → sqlite-MZA3oZNB.d.ts} +310 -2
- package/dist/{store-bphCSo7z.d.cts → store-CuFX7fCx.d.cts} +117 -31
- package/dist/{store-DRrFCx5x.d.ts → store-D-ZjXQpW.d.ts} +117 -31
- package/dist/{temporal-CbnLzTmM.d.ts → temporal-CpyEiRY8.d.cts} +1 -1
- package/dist/{temporal-5GqpYCk2.d.cts → temporal-y0Aep9Su.d.ts} +1 -1
- package/dist/{types-BqFZTQmV.d.cts → types-6yf0Vv-_.d.cts} +2016 -94
- package/dist/{types-BqFZTQmV.d.ts → types-6yf0Vv-_.d.ts} +2016 -94
- package/dist/{types-Bx74kaTt.d.ts → types-DzJ4dlzk.d.cts} +1 -1
- package/dist/{types-CXAhpW-c.d.cts → types-_vVSB9k-.d.ts} +1 -1
- package/dist/{where-O-k2wgYm.d.ts → where-DuG2LCLe.d.ts} +1 -1
- package/dist/{where-DI_Fqz-X.d.cts → where-Mhf_yyKX.d.cts} +1 -1
- package/package.json +7 -2
- package/dist/chunk-26YKDNUD.cjs.map +0 -1
- package/dist/chunk-2TYSSBU5.js.map +0 -1
- package/dist/chunk-3DMMGT6S.js.map +0 -1
- package/dist/chunk-3FPR224C.cjs.map +0 -1
- package/dist/chunk-3G5W2U2L.cjs.map +0 -1
- package/dist/chunk-3KOY4FH3.cjs +0 -934
- package/dist/chunk-3KOY4FH3.cjs.map +0 -1
- package/dist/chunk-3QNZ5SAJ.cjs +0 -3502
- package/dist/chunk-3QNZ5SAJ.cjs.map +0 -1
- package/dist/chunk-3U5ABFDW.cjs +0 -259
- package/dist/chunk-3U5ABFDW.cjs.map +0 -1
- package/dist/chunk-5K2BKEBD.js.map +0 -1
- package/dist/chunk-5PRKMB24.cjs +0 -124
- package/dist/chunk-5PRKMB24.cjs.map +0 -1
- package/dist/chunk-6LN7FIVU.js +0 -107
- package/dist/chunk-6LN7FIVU.js.map +0 -1
- package/dist/chunk-6SWPJEYN.js +0 -1126
- package/dist/chunk-6SWPJEYN.js.map +0 -1
- package/dist/chunk-7LZJNLA5.js.map +0 -1
- package/dist/chunk-7UOLHNWC.cjs.map +0 -1
- package/dist/chunk-BFUOME67.cjs.map +0 -1
- package/dist/chunk-BRRP76WO.js.map +0 -1
- package/dist/chunk-CICO5GXD.cjs +0 -12
- package/dist/chunk-D4QLTJSM.js.map +0 -1
- package/dist/chunk-D5R42W5D.js.map +0 -1
- package/dist/chunk-EDN4Y4ZG.cjs.map +0 -1
- package/dist/chunk-EZEEWCFJ.cjs.map +0 -1
- package/dist/chunk-FA2AFWLP.cjs.map +0 -1
- package/dist/chunk-FQPEMEWX.cjs.map +0 -1
- package/dist/chunk-GLHXM7C4.js.map +0 -1
- package/dist/chunk-GYEG3ZLZ.cjs.map +0 -1
- package/dist/chunk-HDL2ARHX.cjs +0 -1156
- package/dist/chunk-HDL2ARHX.cjs.map +0 -1
- package/dist/chunk-HEV35TGT.js.map +0 -1
- package/dist/chunk-I4GAZH5Z.js +0 -913
- package/dist/chunk-I4GAZH5Z.js.map +0 -1
- package/dist/chunk-JB6T4GLL.cjs.map +0 -1
- package/dist/chunk-JBQQ7THH.js +0 -20
- package/dist/chunk-JBQQ7THH.js.map +0 -1
- package/dist/chunk-JFRT7S3B.cjs.map +0 -1
- package/dist/chunk-KF6K7TGH.js.map +0 -1
- package/dist/chunk-L3LQNR34.cjs +0 -1254
- package/dist/chunk-L3LQNR34.cjs.map +0 -1
- package/dist/chunk-LTXQOEIC.js.map +0 -1
- package/dist/chunk-MKJ4KXL5.cjs +0 -12
- package/dist/chunk-MRDBBHIZ.cjs.map +0 -1
- package/dist/chunk-NACVVDWB.js.map +0 -1
- package/dist/chunk-NVY5CJFP.js +0 -244
- package/dist/chunk-NVY5CJFP.js.map +0 -1
- package/dist/chunk-PWLJ77UV.cjs +0 -23
- package/dist/chunk-PWLJ77UV.cjs.map +0 -1
- package/dist/chunk-S5TERQVW.js.map +0 -1
- package/dist/chunk-SHFBB23Q.js.map +0 -1
- package/dist/chunk-SIT26LAZ.cjs.map +0 -1
- package/dist/chunk-SR725PWF.cjs.map +0 -1
- package/dist/chunk-TQHGE7UC.cjs.map +0 -1
- package/dist/chunk-UGHG7PGX.js.map +0 -1
- package/dist/chunk-UGHQV7MP.cjs.map +0 -1
- package/dist/chunk-UMGZDVOA.cjs.map +0 -1
- package/dist/chunk-WIC7DRXW.js.map +0 -1
- package/dist/chunk-YIURNGXI.js.map +0 -1
- package/dist/chunk-YYUHLYM2.cjs.map +0 -1
- package/dist/chunk-Z2JCLZFJ.js.map +0 -1
- package/dist/chunk-ZDKTPBGV.js.map +0 -1
- package/dist/chunk-ZFMCDJGB.js.map +0 -1
- package/dist/chunk-ZLONH2UD.js.map +0 -1
- package/dist/index-COs_z6nV.d.cts +0 -1132
- package/dist/index-D7d1u2gr.d.ts +0 -1132
- package/dist/materialize-indexes-DJ3ykH59.d.ts +0 -266
- package/dist/materialize-indexes-DTtAnvfY.d.cts +0 -266
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/core/types.ts","../src/indexes/auto-derive.ts","../src/core/define-graph.ts"],"names":[],"mappings":"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","file":"chunk-M3VTS3F6.js","sourcesContent":["import { type z } from \"zod\";\n\nimport { ValidationError } from \"../errors\";\n\n// ============================================================\n// Cross-cutting Discriminators\n// ============================================================\n\n/**\n * Which side of the bipartite graph a kind lives on. Used everywhere a\n * function takes \"the entity that owns a kind\" — error metadata,\n * extension classifiers, removal queues, schema diffs.\n */\nexport type KindEntity = \"node\" | \"edge\";\n\n/**\n * Which physical surface an index targets. Vector indexes don't own a\n * kind directly (they back a per-`(kind, field)` typed embedding table\n * owned by the active `VectorStrategy`), but they participate in the same\n * materialization and diff pipelines, so they share this discriminator.\n *\n * `\"system\"` marks TypeGraph's own base-relation indexes\n * (`SYSTEM_INDEX_DECLARATIONS`) — graph-independent, but materialized and\n * status-tracked through the same pipeline; their status rows carry the\n * relation key (e.g. `\"recordedNodes\"`) in the `kind` column.\n */\nexport type IndexEntity = \"node\" | \"edge\" | \"vector\" | \"system\";\n\n/**\n * Field-level null-check operations that round-trip through persisted\n * documents (unique-constraint where clauses, index where clauses,\n * graph-extension where clauses, IsNullPredicate). Consolidated so a\n * single rename or extension touches one site.\n */\nexport type NullCheckOp = \"isNull\" | \"isNotNull\";\n\n// ============================================================\n// Brand Keys for Nominal Typing\n// ============================================================\n\n/** Brand key for NodeType */\nexport const NODE_TYPE_BRAND = \"__nodeType\" as const;\n\n/** Brand key for EdgeType */\nexport const EDGE_TYPE_BRAND = \"__edgeType\" as const;\n\n/** Brand symbol for NodeId */\ndeclare const __nodeId: unique symbol;\n\n/** Brand symbol for EdgeId */\ndeclare const __edgeId: unique symbol;\n\nfunction assertNonEmptyId(value: string, path: string): void {\n if (value.length > 0) {\n return;\n }\n\n throw new ValidationError(\n `${path} must be a non-empty string.`,\n {\n issues: [\n {\n path,\n message: \"Expected a non-empty string.\",\n },\n ],\n },\n {\n suggestion:\n \"Use a persisted node or edge id value, or let TypeGraph generate an id on create.\",\n },\n );\n}\n\n// ============================================================\n// Node Type\n// ============================================================\n\n/**\n * Any JSON-serializable value.\n *\n * Mirrors the JSON wire format: primitives, arrays, and string-keyed objects.\n * `null` is included because the JSON spec requires it for \"no value here\";\n * this is the one place in the public API that uses `null` over `undefined`.\n */\nexport type JsonValue =\n | null\n | string\n | number\n | boolean\n | readonly JsonValue[]\n | Readonly<{ [key: string]: JsonValue }>;\n\n/**\n * Consumer-owned per-kind annotations.\n *\n * Stable labels attached to a node or edge kind at definition time — UI hints,\n * audit policy, provenance pointers, tooling annotations.\n *\n * **Consumer-owned, fully.** TypeGraph never reads, validates, or interprets\n * values in this field. Consumers own the entire namespace; there are no\n * reserved keys or extension prefixes. Future library-owned per-kind state,\n * if needed, will use a separate sibling field rather than carving out keys\n * here.\n *\n * **Annotations participate in schema hashing.** Any change to an annotation\n * value (or adding/removing an annotation key) bumps the canonical schema\n * hash and is reported as a `safe`-severity diff by `getSchemaChanges`. If\n * you don't want versioning for a piece of state, do not put it here.\n *\n * Values must be JSON-serializable — `bigint`, `function`, `symbol`, `undefined`,\n * `Date`, and other class instances are rejected at definition time so they can\n * never silently break schema hashing or storage round-trips.\n */\nexport type KindAnnotations = Readonly<Record<string, JsonValue>>;\n\n/**\n * A node type definition.\n *\n * Created via `defineNode()`. Represents a type of node in the graph\n * with an associated Zod schema for properties.\n */\nexport type NodeType<\n K extends string = string,\n S extends z.ZodObject<z.ZodRawShape> = z.ZodObject<z.ZodRawShape>,\n> = Readonly<{\n [NODE_TYPE_BRAND]: true;\n kind: K;\n schema: S;\n description: string | undefined;\n annotations: KindAnnotations | undefined;\n}>;\n\n/**\n * Branded node ID type.\n *\n * Prevents mixing IDs from different node types at compile time.\n */\nexport type NodeId<N extends NodeType> = string &\n Readonly<{\n [__nodeId]: N;\n }>;\n\n/**\n * Brands a non-empty string as a {@link NodeId}.\n *\n * Use this when a persisted node id has round-tripped through untyped storage\n * or an external boundary and must be passed back to read/update/delete\n * surfaces such as `getById`, `getByIds`, `update`, or `delete`.\n * Write surfaces that mint or claim ids, such as `create({ id })` and\n * `upsertById`, intentionally accept plain strings.\n *\n * @throws {ValidationError} when `value` is empty.\n */\nexport function asNodeId<N extends NodeType = NodeType>(\n value: string,\n): NodeId<N> {\n assertNonEmptyId(value, \"asNodeId\");\n return value as NodeId<N>;\n}\n\n/**\n * Infer the props type from a NodeType.\n */\nexport type NodeProps<N extends NodeType> = z.infer<N[\"schema\"]>;\n\n// ============================================================\n// Edge Type\n// ============================================================\n\n/**\n * An edge type definition.\n *\n * Created via `defineEdge()`. Represents a type of edge in the graph\n * with an optional Zod schema for properties.\n *\n * Optionally includes `from` and `to` arrays that define the allowed\n * source and target node types (domain and range constraints).\n */\nexport type EdgeType<\n K extends string = string,\n S extends z.ZodObject<z.ZodRawShape> = z.ZodObject<z.ZodRawShape>,\n From extends readonly NodeType[] | undefined = undefined,\n To extends readonly NodeType[] | undefined = undefined,\n> = Readonly<{\n [EDGE_TYPE_BRAND]: true;\n kind: K;\n schema: S;\n description: string | undefined;\n annotations: KindAnnotations | undefined;\n from: From;\n to: To;\n}>;\n\n/**\n * Base edge type for use in constraints - accepts any from/to configuration.\n */\nexport type AnyEdgeType = EdgeType<\n string,\n z.ZodObject<z.ZodRawShape>,\n readonly NodeType[] | undefined,\n readonly NodeType[] | undefined\n>;\n\n/**\n * An edge type that has both from and to constraints defined.\n * Can be used directly in defineGraph without an EdgeRegistration wrapper.\n */\nexport type EdgeTypeWithEndpoints = EdgeType<\n string,\n z.ZodObject<z.ZodRawShape>,\n readonly NodeType[],\n readonly NodeType[]\n>;\n\n/**\n * Branded edge ID type.\n *\n * Prevents mixing IDs from different edge types at compile time.\n */\nexport type EdgeId<E extends AnyEdgeType = AnyEdgeType> = string &\n Readonly<{\n [__edgeId]: E;\n }>;\n\n/**\n * Brands a non-empty string as an {@link EdgeId}.\n *\n * Use this when a persisted edge id has round-tripped through untyped storage\n * or an external boundary and must be passed back to read/update/delete\n * surfaces such as `getById`, `getByIds`, `update`, or `delete`.\n * Write surfaces that mint ids intentionally accept plain strings.\n *\n * @throws {ValidationError} when `value` is empty.\n */\nexport function asEdgeId<E extends AnyEdgeType = AnyEdgeType>(\n value: string,\n): EdgeId<E> {\n assertNonEmptyId(value, \"asEdgeId\");\n return value as EdgeId<E>;\n}\n\n/**\n * Infer the props type from an EdgeType.\n */\nexport type EdgeProps<E extends AnyEdgeType> = z.infer<E[\"schema\"]>;\n\n// ============================================================\n// Configuration Types\n// ============================================================\n\n/**\n * Delete behaviors for nodes.\n */\nexport type DeleteBehavior = \"restrict\" | \"cascade\" | \"disconnect\";\n\n/**\n * Edge cardinality constraints.\n */\nexport type Cardinality =\n | \"many\" // No constraint (default)\n | \"one\" // At most one edge of this kind from any source node\n | \"unique\" // At most one edge of this kind between any (source, target) pair\n | \"oneActive\"; // At most one edge with valid_to IS NULL from any source\n\n/**\n * Endpoint existence modes for edge validation.\n */\nexport type EndpointExistence =\n | \"notDeleted\" // Endpoint deleted_at IS NULL (default)\n | \"currentlyValid\" // Endpoint not deleted AND temporally valid\n | \"ever\"; // Endpoint exists in any state\n\n/**\n * Temporal query modes.\n */\nexport type TemporalMode =\n | \"current\" // Valid now AND not deleted\n | \"asOf\" // Valid at specific date AND not deleted\n | \"includeEnded\" // All validity periods AND not deleted\n | \"includeTombstones\"; // Everything including soft-deleted\n\n/**\n * Uniqueness constraint scope.\n */\nexport type UniquenessScope =\n | \"kind\" // Unique within this exact kind only\n | \"kindWithSubClasses\"; // Unique across this kind and all subclasses\n\n/**\n * Collation for uniqueness constraints.\n */\nexport type Collation = \"binary\" | \"caseInsensitive\";\n\n// ============================================================\n// Uniqueness Constraint\n// ============================================================\n\n/**\n * Uniqueness constraint definition.\n */\nexport type UniqueConstraint<\n S extends z.ZodObject<z.ZodRawShape> = z.ZodObject<z.ZodRawShape>,\n> = Readonly<{\n name: string;\n fields: readonly (keyof z.infer<S> & string)[];\n where?: (\n props: UniqueConstraintPredicateBuilder<S>,\n ) => UniqueConstraintPredicate;\n scope: UniquenessScope;\n collation: Collation;\n}>;\n\n/**\n * Predicate builder for uniqueness constraint where clause.\n * Uses -? to make all fields required in the builder, even if optional in the schema.\n */\ntype UniqueConstraintPredicateBuilder<S extends z.ZodObject<z.ZodRawShape>> =\n Readonly<{\n [K in keyof z.infer<S>]-?: UniqueConstraintField;\n }>;\n\n/**\n * Field operations for uniqueness constraint predicates.\n */\ntype UniqueConstraintField = Readonly<{\n isNull: () => UniqueConstraintPredicate;\n isNotNull: () => UniqueConstraintPredicate;\n}>;\n\n/**\n * A uniqueness constraint predicate (internal representation).\n */\ntype UniqueConstraintPredicate = Readonly<{\n __type: \"unique_predicate\";\n field: string;\n op: NullCheckOp;\n}>;\n\n// ============================================================\n// Node Registration\n// ============================================================\n\n/**\n * Node registration in a graph definition.\n */\nexport type NodeRegistration<N extends NodeType = NodeType> = Readonly<{\n type: N;\n unique?: readonly UniqueConstraint<N[\"schema\"]>[];\n onDelete?: DeleteBehavior;\n}>;\n\n// ============================================================\n// Edge Registration\n// ============================================================\n\n/**\n * Edge registration in a graph definition.\n */\nexport type EdgeRegistration<\n E extends AnyEdgeType = AnyEdgeType,\n FromTypes extends NodeType = NodeType,\n ToTypes extends NodeType = NodeType,\n> = Readonly<{\n type: E;\n from: readonly FromTypes[];\n to: readonly ToTypes[];\n cardinality?: Cardinality;\n endpointExistence?: EndpointExistence;\n}>;\n\n// ============================================================\n// Graph Defaults\n// ============================================================\n\n/**\n * Default settings for a graph.\n */\nexport type GraphDefaults = Readonly<{\n onNodeDelete?: DeleteBehavior;\n temporalMode?: TemporalMode;\n}>;\n\n// ============================================================\n// Type Helpers\n// ============================================================\n\n/**\n * Checks if a value is a NodeType.\n */\nexport function isNodeType(value: unknown): value is NodeType {\n return (\n typeof value === \"object\" &&\n value !== null &&\n NODE_TYPE_BRAND in value &&\n (value as Record<string, unknown>)[NODE_TYPE_BRAND] === true\n );\n}\n\n/**\n * Checks if a value is an EdgeType.\n */\nexport function isEdgeType(value: unknown): value is AnyEdgeType {\n return (\n typeof value === \"object\" &&\n value !== null &&\n EDGE_TYPE_BRAND in value &&\n (value as Record<string, unknown>)[EDGE_TYPE_BRAND] === true\n );\n}\n\n/**\n * Checks if a value is an EdgeType with both from and to constraints defined.\n * Such edges can be used directly in defineGraph without an EdgeRegistration wrapper.\n */\nexport function isEdgeTypeWithEndpoints(\n value: unknown,\n): value is EdgeTypeWithEndpoints {\n return (\n isEdgeType(value) &&\n Array.isArray(value.from) &&\n value.from.length > 0 &&\n Array.isArray(value.to) &&\n value.to.length > 0\n );\n}\n","/**\n * Auto-derive vector index declarations from `embedding()` brands on\n * node schemas.\n *\n * Walks each node's top-level Zod shape, finds fields wrapped in\n * `embedding(dimensions, opts)` (including `.optional()` /\n * `.nullable()` wrappers), and emits one `VectorIndexDeclaration` per\n * (kind, field) pair. The declaration carries the resolved index\n * configuration from the embedding brand — metric, indexType, HNSW /\n * IVFFlat params — so the materializer doesn't need to reach back into\n * the Zod schema.\n *\n * Auto-derivation is intentionally limited to TOP-LEVEL embedding\n * fields. Embeddings nested inside object properties are out of scope\n * for v1 — vector slots are materialized as flat `(kind, fieldPath)`\n * storage units, and top-level fields keep that contract explicit.\n *\n * Explicit `defineVectorIndex(node, fieldPath, opts)` declarations\n * passed via `defineGraph({ indexes })` take precedence — when an\n * explicit declaration matches the same (kind, fieldPath) as an\n * auto-derived one, the explicit version wins. This lets consumers\n * override defaults without losing auto-derivation for other fields.\n */\n\nimport { type z } from \"zod\";\n\nimport {\n getEmbeddingIndex,\n isEmbeddingSchema,\n type ResolvedEmbeddingIndex,\n} from \"../core/embedding\";\nimport { type NodeRegistration } from \"../core/types\";\nimport { type IndexDeclaration, type VectorIndexDeclaration } from \"./types\";\n\n/**\n * Auto-derive vector index declarations from embedding brands on a\n * map of node registrations. Returns one declaration per\n * (kind, top-level field) pair. Empty array when no embeddings found.\n *\n * Cross-graph status-table disambiguation does NOT happen here — the\n * declaration name stays clean (`tg_vec_{kind}_{field}_{metric}`) so\n * `pg_indexes` and result-entry inspection are readable. The\n * materializer composes a graph-scoped key (`${graphId}::${name}`)\n * for status-table identity, applied uniformly to both auto-derived\n * and explicit `VectorIndexDeclaration` entries — see\n * `vectorStatusKey` in `store/materialize-indexes.ts`. This keeps\n * the disambiguation rule in one place that BOTH paths go through,\n * rather than depending on the auto-derive caller to produce a\n * graph-scoped name.\n */\nexport function autoDeriveVectorIndexes(\n nodes: Record<string, NodeRegistration>,\n): readonly VectorIndexDeclaration[] {\n const out: VectorIndexDeclaration[] = [];\n for (const registration of Object.values(nodes)) {\n const node = registration.type;\n const shape = readObjectShape(node.schema);\n if (shape === undefined) continue;\n for (const [fieldName, fieldSchema] of Object.entries(shape)) {\n const config = readEmbeddingIndex(fieldSchema);\n if (config === undefined) continue;\n const dimensions = readEmbeddingDimensions(fieldSchema);\n if (dimensions === undefined) continue;\n out.push(buildAutoDerived(node.kind, fieldName, dimensions, config));\n }\n }\n return out;\n}\n\n/**\n * Merge auto-derived declarations with explicit ones, preferring\n * explicit on (kind, fieldPath) collisions. Returns a flat list of all\n * indexes; non-vector entries from `explicit` pass through unchanged.\n */\nexport function mergeVectorIndexes(\n explicit: readonly IndexDeclaration[],\n autoDerived: readonly VectorIndexDeclaration[],\n): readonly IndexDeclaration[] {\n if (autoDerived.length === 0) return explicit;\n const explicitVectorKeys = new Set<string>();\n for (const declaration of explicit) {\n if (declaration.entity === \"vector\") {\n explicitVectorKeys.add(`${declaration.kind}|${declaration.fieldPath}`);\n }\n }\n const filteredAuto = autoDerived.filter(\n (entry) => !explicitVectorKeys.has(`${entry.kind}|${entry.fieldPath}`),\n );\n return [...explicit, ...filteredAuto];\n}\n\n/**\n * Generate the deterministic vector index name. The visible prefix\n * `tg_vec_<kind>_<field>_<metric>` keeps it scannable in result-entry\n * inspection and the `typegraph_index_materializations` table.\n *\n * Cross-graph disambiguation is handled separately at the\n * materialization boundary (see `vectorStatusKey`) so the declaration\n * name doesn't need to carry `graphId` — the same auto-derived name\n * is reusable across graphs and the materializer composes a\n * graph-scoped status key for both auto-derived and explicit entries\n * uniformly.\n */\nfunction buildAutoDerived(\n kind: string,\n fieldName: string,\n dimensions: number,\n config: ResolvedEmbeddingIndex,\n): VectorIndexDeclaration {\n const fieldPath = fieldName;\n return Object.freeze({\n entity: \"vector\" as const,\n name: `tg_vec_${sanitize(kind)}_${sanitize(fieldName)}_${config.metric}`,\n kind,\n fieldPath,\n dimensions,\n metric: config.metric,\n indexType: config.indexType,\n indexParams: Object.freeze({\n m: config.m,\n efConstruction: config.efConstruction,\n lists: config.lists,\n }),\n });\n}\n\nfunction sanitize(value: string): string {\n return value.replaceAll(/[^a-zA-Z0-9]/g, \"_\").toLowerCase();\n}\n\nfunction readObjectShape(\n schema: z.ZodType,\n): Record<string, z.ZodType> | undefined {\n if ((schema as { type?: string }).type !== \"object\") return undefined;\n const shape = (schema.def as { shape?: Record<string, z.ZodType> }).shape;\n return shape;\n}\n\nfunction readEmbeddingIndex(\n schema: z.ZodType,\n): ResolvedEmbeddingIndex | undefined {\n for (const candidate of unwrapChain(schema)) {\n const config = getEmbeddingIndex(candidate);\n if (config !== undefined) return config;\n }\n return undefined;\n}\n\nfunction readEmbeddingDimensions(schema: z.ZodType): number | undefined {\n for (const candidate of unwrapChain(schema)) {\n if (isEmbeddingSchema(candidate)) {\n return (candidate as unknown as Record<string, number>)[\n \"_embeddingDimensions\"\n ];\n }\n }\n return undefined;\n}\n\n/**\n * Yield the schema and every reachable inner schema by repeatedly\n * applying `.unwrap()` (Zod 4 optional/nullable/default) and\n * `.def.innerType` (some wrappers). Cycle-guarded by depth and\n * reference identity. Generators stop at the first non-unwrappable\n * schema OR after 8 levels — deeper wrapping is pathological and not\n * worth supporting.\n */\nfunction* unwrapChain(schema: z.ZodType): Generator<z.ZodType, void, void> {\n const seen = new Set<z.ZodType>();\n let current: z.ZodType | undefined = schema;\n let depth = 0;\n while (current !== undefined && !seen.has(current) && depth < 8) {\n seen.add(current);\n yield current;\n current = unwrapOnce(current);\n depth++;\n }\n}\n\nfunction unwrapOnce(schema: z.ZodType): z.ZodType | undefined {\n // Zod 4 wrappers expose `.unwrap()` on optional/nullable/default.\n const candidate = schema as unknown as { unwrap?: () => z.ZodType };\n if (typeof candidate.unwrap === \"function\") return candidate.unwrap();\n // Some wrappers expose the inner schema via `.def.innerType`.\n return (schema as unknown as { def?: { innerType?: z.ZodType } }).def\n ?.innerType;\n}\n","import { assertWhereFieldDeclared } from \"../constraints\";\nimport { ConfigurationError } from \"../errors/index\";\nimport { type GraphExtension } from \"../graph-extension/extension-types\";\nimport {\n autoDeriveVectorIndexes,\n mergeVectorIndexes,\n} from \"../indexes/auto-derive\";\nimport { type IndexDeclaration } from \"../indexes/types\";\nimport { type OntologyRelation } from \"../ontology/types\";\nimport { assertClaimAxisSafe } from \"../store/claims/axis\";\nimport { createDataKeyedBag } from \"../utils/object\";\nimport {\n type AnyEdgeType,\n type DeleteBehavior,\n type EdgeRegistration,\n type EdgeTypeWithEndpoints,\n type GraphDefaults,\n isEdgeType,\n isEdgeTypeWithEndpoints,\n type KindEntity,\n type NodeRegistration,\n type NodeType,\n type TemporalMode,\n} from \"./types\";\n\n// ============================================================\n// Graph Definition Brand Symbol\n// ============================================================\n\n/** Brand key for GraphDef */\nconst GRAPH_DEF_BRAND = \"__graphDef\" as const;\n\n// ============================================================\n// Edge Entry Types\n// ============================================================\n\n/**\n * An edge entry in the graph definition.\n * Can be:\n * - EdgeType directly (constrained or unconstrained)\n * - EdgeRegistration object (always works, can override/narrow defaults)\n */\ntype EdgeEntry = EdgeRegistration | AnyEdgeType;\n\n/**\n * Normalized edge map type - all entries become EdgeRegistration.\n * For bare EdgeTypes, constrained endpoints are extracted from the type;\n * unconstrained edges fall back to all node types in the graph.\n */\ntype NormalizedEdges<\n TNodes extends Record<string, NodeRegistration>,\n TEdges extends Record<string, EdgeEntry>,\n> = {\n [K in keyof TEdges]: TEdges[K] extends EdgeRegistration ? TEdges[K]\n : TEdges[K] extends AnyEdgeType ?\n EdgeRegistration<\n TEdges[K],\n TEdges[K][\"from\"] extends readonly (infer N extends NodeType)[] ? N\n : TNodes[keyof TNodes][\"type\"],\n TEdges[K][\"to\"] extends readonly (infer N extends NodeType)[] ? N\n : TNodes[keyof TNodes][\"type\"]\n >\n : never;\n};\n\n// ============================================================\n// Edge Normalization Functions\n// ============================================================\n\n/**\n * Validates that an EdgeRegistration's constraints don't widen beyond\n * the edge type's built-in domain/range constraints.\n */\nfunction validateConstraintNarrowing(\n name: string,\n edgeType: EdgeTypeWithEndpoints,\n registration: EdgeRegistration,\n): void {\n const builtInFromNames = new Set(edgeType.from.map((node) => node.kind));\n for (const fromNode of registration.from) {\n if (!builtInFromNames.has(fromNode.kind)) {\n throw new ConfigurationError(\n `Edge \"${name}\" registration has 'from' kind \"${fromNode.kind}\" ` +\n `not in edge's built-in domain: [${[...builtInFromNames].join(\", \")}]`,\n {\n edgeName: name,\n invalidFrom: fromNode.kind,\n allowedFrom: [...builtInFromNames],\n },\n {\n suggestion: `Edge registration can only narrow, not widen, the edge type's built-in constraints.`,\n },\n );\n }\n }\n\n const builtInToNames = new Set(edgeType.to.map((node) => node.kind));\n for (const toNode of registration.to) {\n if (!builtInToNames.has(toNode.kind)) {\n throw new ConfigurationError(\n `Edge \"${name}\" registration has 'to' kind \"${toNode.kind}\" ` +\n `not in edge's built-in range: [${[...builtInToNames].join(\", \")}]`,\n {\n edgeName: name,\n invalidTo: toNode.kind,\n allowedTo: [...builtInToNames],\n },\n {\n suggestion: `Edge registration can only narrow, not widen, the edge type's built-in constraints.`,\n },\n );\n }\n }\n}\n\n/**\n * Normalizes a single edge entry to EdgeRegistration.\n */\nfunction normalizeEdgeEntry(\n name: string,\n entry: EdgeEntry,\n allNodeTypes: readonly NodeType[],\n): EdgeRegistration {\n if (isEdgeType(entry)) {\n if (isEdgeTypeWithEndpoints(entry)) {\n // EdgeType with from/to — convert to EdgeRegistration\n return { type: entry, from: entry.from, to: entry.to };\n }\n // Unconstrained EdgeType — allow any→any\n return { type: entry, from: allNodeTypes, to: allNodeTypes };\n }\n\n // Already EdgeRegistration — validate narrowing if edge has built-in constraints\n if (isEdgeTypeWithEndpoints(entry.type)) {\n validateConstraintNarrowing(name, entry.type, entry);\n }\n\n return entry;\n}\n\n/**\n * Normalizes all edge entries to EdgeRegistration.\n *\n * The accumulator is a {@link createDataKeyedBag}: its keys are EDGE KIND\n * NAMES, which are data. `isValidKindName` admits `__proto__` exactly as it\n * admits `toString`, and a graph literal written with a computed key\n * (`edges: { [\"__proto__\"]: knows }`) carries it as an own key — so\n * `result[name] = …` into a `{}` literal would reach `Object.prototype`'s\n * `__proto__` setter, reparent the accumulator, and drop the declared edge.\n * `config.nodes` needs no such treatment: it is passed through by reference,\n * never re-accumulated.\n */\nfunction normalizeEdges(\n edges: Record<string, EdgeEntry>,\n allNodeTypes: readonly NodeType[],\n): Record<string, EdgeRegistration> {\n const result = createDataKeyedBag<EdgeRegistration>();\n for (const [name, entry] of Object.entries(edges)) {\n result[name] = normalizeEdgeEntry(name, entry, allNodeTypes);\n }\n // Spread at the boundary: this becomes `graph.edges` on the returned (and\n // publicly reachable) `GraphDef`. See `createDataKeyedBag` in\n // ../utils/object.ts.\n return { ...result };\n}\n\n// ============================================================\n// Graph Definition Configuration\n// ============================================================\n\n/** Durable graph-level configuration for the TypeGraph Identity Profile. */\nexport type GraphIdentityConfig = Readonly<{\n /** Whether equal ids in different kinds implicitly join one identity class. */\n sameIdAcrossKinds: \"fold\" | \"ignore\";\n}>;\n\n/**\n * Configuration for defineGraph.\n */\ntype GraphDefConfig<\n TNodes extends Record<string, NodeRegistration>,\n TEdges extends Record<string, EdgeEntry>,\n TOntology extends readonly OntologyRelation[],\n TIdentity extends GraphIdentityConfig | undefined,\n> = Readonly<{\n /** Unique identifier for this graph */\n id: string;\n /** Node registrations */\n nodes: TNodes;\n /** Edge registrations or EdgeTypes with built-in domain/range */\n edges: TEdges;\n /** Ontology relations */\n ontology?: TOntology;\n /** Graph-wide defaults */\n defaults?: GraphDefaults;\n /** Enables the TypeGraph Identity Profile for this graph. */\n identity?: TIdentity;\n /**\n * Index declarations attached to this graph.\n *\n * Accepts the outputs of `defineNodeIndex` / `defineEdgeIndex` (which\n * already return `IndexDeclaration` values) or pre-built declarations\n * reconstructed from a stored schema or graph extension.\n *\n * Validated at definition time: every index must reference a `kind`\n * that exists in `nodes` / `edges`, and index `name`s must be unique\n * within the graph.\n *\n * Index DDL is **not** generated by `defineGraph`. Indexes flow into\n * `SerializedSchema.indexes` so they can later be materialized via\n * `store.materializeIndexes()` — lifting the storage concern out of\n * the schema-version commit path.\n */\n indexes?: readonly IndexDeclaration[];\n}>;\n\n// ============================================================\n// Graph Definition Type\n// ============================================================\n\n/**\n * A graph definition.\n *\n * This is a compile-time artifact that describes the structure of a graph.\n * Use `createStore()` to create a runtime store from this definition.\n */\nexport type GraphDef<\n TNodes extends Record<string, NodeRegistration> = Record<\n string,\n NodeRegistration\n >,\n TEdges extends Record<string, EdgeRegistration> = Record<\n string,\n EdgeRegistration\n >,\n TOntology extends readonly OntologyRelation[] = readonly OntologyRelation[],\n TIdentity extends GraphIdentityConfig | undefined =\n GraphIdentityConfig | undefined,\n> = Readonly<{\n [GRAPH_DEF_BRAND]: true;\n id: string;\n nodes: TNodes;\n edges: TEdges;\n ontology: TOntology;\n /** Durable graph-level opt-in to the TypeGraph Identity Profile. */\n identity: TIdentity;\n defaults: Readonly<{\n onNodeDelete: DeleteBehavior;\n temporalMode: TemporalMode;\n }>;\n /**\n * Index declarations attached to this graph. Preserves whatever the\n * caller passed to `defineGraph` (including an explicit empty array)\n * for introspection purposes.\n *\n * The serialized canonical form is order-canonicalized (sorted by\n * `name`) and treats `undefined` and `[]` as the same \"no slice\" form\n * — an empty array does not bump the schema hash, since indexes are\n * an unordered set keyed by name and `[]` carries no semantic meaning\n * that an absent slice doesn't.\n */\n indexes: readonly IndexDeclaration[] | undefined;\n /**\n * Graph extension this graph was merged with, if any. Set by\n * `mergeGraphExtension`; never set by `defineGraph` directly.\n * Exists solely so re-serialization is stable — the rest of the\n * system reads the merged kinds through `nodes` / `edges` /\n * `ontology` and never inspects this field. Absent on graphs that\n * have never been extended; legacy graphs hash byte-identically.\n */\n extension: GraphExtension | undefined;\n /**\n * Soft-deprecated kind names attached to this graph. Set by the\n * loader from the persisted schema and by `store.deprecateKinds(...)`\n * / `store.undeprecateKinds(...)`. A purely informational signal\n * surfaced for introspection — does not gate reads, writes, or\n * queries. Defaults to the empty set on freshly-defined graphs.\n */\n deprecatedKinds: ReadonlySet<string>;\n}>;\n\n// ============================================================\n// Type Helpers\n// ============================================================\n\n/**\n * Extract node kind names from a GraphDef.\n */\nexport type NodeKinds<G extends GraphDef> = keyof G[\"nodes\"] & string;\n\n/**\n * Extract edge kind names from a GraphDef.\n */\nexport type EdgeKinds<G extends GraphDef> = keyof G[\"edges\"] & string;\n\n/**\n * Get a NodeType from a GraphDef by kind name.\n */\nexport type GetNodeType<\n G extends GraphDef,\n K extends NodeKinds<G>,\n> = G[\"nodes\"][K][\"type\"];\n\n/**\n * Get an EdgeType from a GraphDef by kind name.\n */\nexport type GetEdgeType<\n G extends GraphDef,\n K extends EdgeKinds<G>,\n> = G[\"edges\"][K][\"type\"];\n\n/**\n * Get all NodeTypes from a GraphDef.\n */\nexport type AllNodeTypes<G extends GraphDef> = {\n [K in NodeKinds<G>]: G[\"nodes\"][K][\"type\"];\n}[NodeKinds<G>];\n\n/**\n * Get all EdgeTypes from a GraphDef.\n */\nexport type AllEdgeTypes<G extends GraphDef> = {\n [K in EdgeKinds<G>]: G[\"edges\"][K][\"type\"];\n}[EdgeKinds<G>];\n\n// ============================================================\n// Define Graph Function\n// ============================================================\n\n/**\n * Creates a graph definition.\n *\n * @example\n * ```typescript\n * const graph = defineGraph({\n * id: \"my_graph\",\n * nodes: {\n * Person: { type: Person },\n * Company: { type: Company },\n * },\n * edges: {\n * // Traditional EdgeRegistration syntax\n * worksAt: {\n * type: worksAt,\n * from: [Person],\n * to: [Company],\n * cardinality: \"many\",\n * },\n * // Or use EdgeType directly if it has from/to defined\n * knows, // EdgeType with built-in domain/range\n * },\n * ontology: [\n * subClassOf(Company, Organization),\n * disjointWith(Person, Organization),\n * ],\n * defaults: {\n * onNodeDelete: \"restrict\",\n * temporalMode: \"current\",\n * },\n * });\n * ```\n */\nexport function defineGraph<\n const TNodes extends Record<string, NodeRegistration<NodeType>>,\n const TEdges extends Record<string, EdgeEntry>,\n const TOntology extends readonly OntologyRelation[],\n const TIdentity extends GraphIdentityConfig | undefined = undefined,\n>(\n config: GraphDefConfig<TNodes, TEdges, TOntology, TIdentity>,\n): GraphDef<TNodes, NormalizedEdges<TNodes, TEdges>, TOntology, TIdentity> {\n return defineGraphUnchecked(config);\n}\n\nfunction defineGraphUnchecked<\n const TNodes extends Record<string, NodeRegistration<NodeType>>,\n const TEdges extends Record<string, EdgeEntry>,\n const TOntology extends readonly OntologyRelation[],\n const TIdentity extends GraphIdentityConfig | undefined = undefined,\n>(\n config: GraphDefConfig<TNodes, TEdges, TOntology, TIdentity>,\n): GraphDef<TNodes, NormalizedEdges<TNodes, TEdges>, TOntology, TIdentity> {\n const defaults = {\n onNodeDelete: config.defaults?.onNodeDelete ?? \"restrict\",\n temporalMode: config.defaults?.temporalMode ?? \"current\",\n } as const;\n\n const allNodeTypes = Object.values(config.nodes).map((reg) => reg.type);\n const normalizedEdges = normalizeEdges(config.edges, allNodeTypes);\n assertClaimNamesAreSafe(config.nodes);\n assertUniqueConstraintsAreDeclared(config.nodes);\n // Vector indexes are auto-derived from `embedding()` brands on node\n // schemas (see `autoDeriveVectorIndexes`). Explicit declarations\n // passed via `defineGraph({ indexes })` win on (kind, fieldPath)\n // collisions so consumers can override defaults — see\n // `mergeVectorIndexes`. The merged list flows through\n // `normalizeIndexes` for the standard kind-registered + unique-name\n // checks.\n //\n // Preservation rule: if the consumer never passed `indexes` at all\n // AND no embedding brands exist, leave `graph.indexes` undefined to\n // keep the introspection surface stable for legacy graphs. If the\n // consumer passed an explicit `[]`, surface it as `[]` (not\n // `undefined`) to match the contract pinned by the\n // \"preserves an explicit empty indexes array\" test.\n const autoVectorIndexes = autoDeriveVectorIndexes(config.nodes);\n const explicitProvided = config.indexes !== undefined;\n const mergedIndexes = mergeVectorIndexes(\n config.indexes ?? [],\n autoVectorIndexes,\n );\n const indexes =\n !explicitProvided && mergedIndexes.length === 0 ?\n undefined\n : normalizeIndexes(mergedIndexes, config.nodes, normalizedEdges);\n\n return Object.freeze({\n [GRAPH_DEF_BRAND]: true as const,\n id: config.id,\n nodes: config.nodes,\n edges: normalizedEdges,\n ontology: config.ontology ?? ([] as unknown as TOntology),\n identity: config.identity as TIdentity,\n defaults,\n indexes,\n extension: undefined,\n deprecatedKinds: EMPTY_DEPRECATED_KINDS,\n }) as GraphDef<TNodes, NormalizedEdges<TNodes, TEdges>, TOntology, TIdentity>;\n}\n\n/**\n * @internal Marks a graph definition as framework-owned rather than\n * application-authored.\n *\n * It builds exactly what {@link defineGraph} builds — the name records the\n * caller, it does not reserve anything. There is NO reserved id namespace and\n * no id validation anywhere: an application may define a graph at any id a\n * framework-owned graph uses, the merge-provenance sidecar's\n * `<target>::merge-provenance` convention included. That convention is\n * protected at RUNTIME instead, by the ownership checks in the single gateway\n * that opens a sidecar (`openProvenanceStore`), which refuses an id occupied by\n * anything it cannot prove it owns.\n */\nexport function defineInternalGraph<\n const TNodes extends Record<string, NodeRegistration<NodeType>>,\n const TEdges extends Record<string, EdgeEntry>,\n const TOntology extends readonly OntologyRelation[],\n const TIdentity extends GraphIdentityConfig | undefined = undefined,\n>(\n config: GraphDefConfig<TNodes, TEdges, TOntology, TIdentity>,\n): GraphDef<TNodes, NormalizedEdges<TNodes, TEdges>, TOntology, TIdentity> {\n return defineGraphUnchecked(config);\n}\n\n// Sharing one frozen empty Set keeps the canonical-form hash stable\n// across graphs that never deprecate any kinds.\nconst EMPTY_DEPRECATED_KINDS: ReadonlySet<string> = Object.freeze(\n new Set<string>(),\n);\n\n// ============================================================\n// Unique Constraint Validation\n// ============================================================\n\n/**\n * Refuses any kind name or constraint name that could spell a reserved claim\n * axis.\n *\n * A node kind and a unique constraint name are both written verbatim into the\n * claim rows a write of that kind reserves, and the axes that are NOT kinds —\n * the disjoint pair axis, and the reserved constraint name its rows carry — are\n * built from a code point neither may contain. `defineGraph` is where that is\n * enforced for the whole graph: `defineNode` already refuses it for kinds it\n * builds, but the graph-extension compiler builds registrations without going\n * through it, and constraint names never pass `defineNode` at all.\n */\nfunction assertClaimNamesAreSafe(\n nodes: Record<string, NodeRegistration>,\n): void {\n for (const registration of Object.values(nodes)) {\n assertClaimAxisSafe(registration.type.kind, \"Node kind\");\n for (const constraint of registration.unique ?? []) {\n assertClaimAxisSafe(constraint.name, \"Unique constraint\");\n }\n }\n}\n\n/**\n * Refuses any uniqueness constraint whose `where` clause names a field its kind\n * does not declare.\n *\n * `defineGraph` is the one gate every constraint passes before a write can\n * evaluate it — the store reads constraints off `registration.unique`, and the\n * only other way a registration is built is `mergeGraphExtension`, whose\n * documents `validateGraphExtension` already refuses on the same grounds\n * (`UNKNOWN_UNIQUE_WHERE_FIELD`). Validating here therefore covers every write\n * path at once, instead of at each `checkWherePredicate` call site.\n *\n * Typed callers are already guarded by `UniqueConstraintPredicateBuilder`,\n * which declares exactly the schema's fields; this is the runtime half, for\n * untyped callers whose typo would otherwise produce a constraint that quietly\n * never applies.\n */\nfunction assertUniqueConstraintsAreDeclared(\n nodes: Record<string, NodeRegistration>,\n): void {\n for (const registration of Object.values(nodes)) {\n const constraints = registration.unique;\n if (constraints === undefined || constraints.length === 0) continue;\n\n const rawShape = (registration.type.schema as { shape?: unknown }).shape;\n const shape =\n typeof rawShape === \"object\" && rawShape !== null ?\n (rawShape as Readonly<Record<string, unknown>>)\n : undefined;\n\n for (const constraint of constraints) {\n // A schema exposing no `.shape` is not an object schema, so there is no\n // declared-field set to check the clause against. Skipping the check\n // silently would disable this guard for exactly the callers it was\n // written for — untyped ones, who are also the only callers who can put\n // a non-`ZodObject` here (`defineNode` / `defineEdge` and the\n // graph-extension compiler all produce `z.object(...)`). So the clause is\n // REFUSED rather than left unvalidated.\n //\n // Narrowly: only a constraint that actually carries a `where` is refused.\n // A plain `unique: [{ fields }]` needs no shape to be meaningful — it\n // names props by key and evaluates fine against a non-object schema — and\n // refusing it would break a working, if unusual, untyped graph for no\n // safety gain.\n if (shape === undefined) {\n if (constraint.where === undefined) continue;\n throw new ConfigurationError(\n `Unique constraint \"${constraint.name}\" on node kind \"${registration.type.kind}\" has a \\`where\\` clause, but the kind's schema is not an object schema, so its declared fields cannot be checked.`,\n {\n kind: registration.type.kind,\n constraintName: constraint.name,\n },\n {\n suggestion: `Declare the kind with an object schema (\\`z.object({ ... })\\`) so the \\`where\\` clause can be validated, or drop the \\`where\\` clause.`,\n },\n );\n }\n\n assertWhereFieldDeclared(registration.type.kind, constraint, shape);\n }\n }\n}\n\n// ============================================================\n// Index Normalization\n// ============================================================\n\n/**\n * Validates the `indexes` config slice:\n *\n * - Every index references a kind that exists in the graph's `nodes`\n * (for node indexes) or `edges` (for edge indexes).\n * - Index `name`s are unique within the graph.\n */\nfunction normalizeIndexes(\n inputs: readonly IndexDeclaration[],\n nodes: Record<string, NodeRegistration>,\n edges: Record<string, EdgeRegistration>,\n): readonly IndexDeclaration[] {\n if (inputs.length === 0) {\n return [];\n }\n\n const nodeKinds = collectKinds(nodes);\n const edgeKinds = collectKinds(edges);\n const seenNames = new Set<string>();\n\n for (const declaration of inputs) {\n if (declaration.entity === \"node\" || declaration.entity === \"vector\") {\n // Vector indexes attach to node kinds (the embedding lives on a\n // node field). Validation reuses the node-kind check.\n assertKindRegistered(declaration, nodeKinds, \"node\");\n } else {\n assertKindRegistered(declaration, edgeKinds, \"edge\");\n }\n\n if (seenNames.has(declaration.name)) {\n throw new ConfigurationError(\n `Duplicate index name \"${declaration.name}\" in defineGraph({ indexes }). ` +\n `Index names must be unique within a graph.`,\n { indexName: declaration.name },\n {\n suggestion: `Pass an explicit { name: \"...\" } to disambiguate.`,\n },\n );\n }\n seenNames.add(declaration.name);\n }\n\n return inputs;\n}\n\nfunction collectKinds(\n registrations: Record<string, { type: { kind: string } }>,\n): ReadonlySet<string> {\n const kinds = new Set<string>();\n for (const registration of Object.values(registrations)) {\n kinds.add(registration.type.kind);\n }\n return kinds;\n}\n\nfunction assertKindRegistered(\n declaration: IndexDeclaration,\n registeredKinds: ReadonlySet<string>,\n entity: KindEntity,\n): void {\n if (registeredKinds.has(declaration.kind)) return;\n\n const slot = entity === \"node\" ? \"nodes\" : \"edges\";\n const suggestion =\n entity === \"node\" ?\n `Add { ${declaration.kind}: { type: ${declaration.kind} } } to defineGraph({ nodes }) ` +\n `or remove the index from \"indexes\".`\n : `Register the edge in defineGraph({ edges }) or remove the index from \"indexes\".`;\n\n throw new ConfigurationError(\n `Index \"${declaration.name}\" references ${entity} kind \"${declaration.kind}\" ` +\n `which is not registered in this graph's \"${slot}\".`,\n {\n indexName: declaration.name,\n referencedKind: declaration.kind,\n availableKinds: [...registeredKinds],\n },\n { suggestion },\n );\n}\n\n// ============================================================\n// Graph Definition Utilities\n// ============================================================\n\n/**\n * Checks if a value is a GraphDef.\n */\nexport function isGraphDef(value: unknown): value is GraphDef {\n return (\n typeof value === \"object\" &&\n value !== null &&\n GRAPH_DEF_BRAND in value &&\n (value as Record<string, unknown>)[GRAPH_DEF_BRAND] === true\n );\n}\n\n/**\n * Gets all node kind names from a GraphDef.\n */\nexport function getNodeKinds<G extends GraphDef>(\n graph: G,\n): readonly (keyof G[\"nodes\"] & string)[] {\n return Object.keys(graph.nodes);\n}\n\n/**\n * Gets all edge kind names from a GraphDef.\n */\nexport function getEdgeKinds<G extends GraphDef>(\n graph: G,\n): readonly (keyof G[\"edges\"] & string)[] {\n return Object.keys(graph.edges);\n}\n\n/**\n * Returns true when `name` is registered as either a node or edge kind\n * on the given graph.\n */\nexport function isKnownKind(graph: GraphDef, name: string): boolean {\n return Object.hasOwn(graph.nodes, name) || Object.hasOwn(graph.edges, name);\n}\n"]}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
var
|
|
3
|
+
var chunkX4GDXBOP_cjs = require('./chunk-X4GDXBOP.cjs');
|
|
4
4
|
|
|
5
5
|
// src/utils/date.ts
|
|
6
6
|
var CANONICAL_ISO_DATE_PATTERN = /^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}\.\d{3}Z$/;
|
|
@@ -51,7 +51,7 @@ function isCanonicalIsoDate(value) {
|
|
|
51
51
|
}
|
|
52
52
|
function validateCanonicalIsoDate(value, fieldName) {
|
|
53
53
|
if (!isCanonicalIsoDate(value)) {
|
|
54
|
-
throw new
|
|
54
|
+
throw new chunkX4GDXBOP_cjs.ValidationError(
|
|
55
55
|
`Invalid canonical ISO 8601 datetime for "${fieldName}": "${value}". Expected fixed-width UTC: YYYY-MM-DDTHH:mm:ss.sssZ`,
|
|
56
56
|
{
|
|
57
57
|
issues: [
|
|
@@ -96,13 +96,13 @@ function resolveStatedValidityLowerBound(validFrom) {
|
|
|
96
96
|
}
|
|
97
97
|
function assertEffectiveValidityLowerBound(subject, effectiveValidFrom, validTo) {
|
|
98
98
|
if (!isInvertedValidityWindow(effectiveValidFrom, validTo)) return;
|
|
99
|
-
throw new
|
|
99
|
+
throw new chunkX4GDXBOP_cjs.ValidationError(
|
|
100
100
|
`Inverted validity window for ${subject}: the effective validFrom "${effectiveValidFrom}" is after validTo "${validTo}".`,
|
|
101
101
|
{
|
|
102
102
|
issues: [
|
|
103
103
|
{
|
|
104
104
|
path: "validTo",
|
|
105
|
-
code:
|
|
105
|
+
code: chunkX4GDXBOP_cjs.INVERTED_VALIDITY_WINDOW_CODE,
|
|
106
106
|
message: `Expected the effective validFrom <= validTo, got "${effectiveValidFrom}" > "${validTo}". The effective validFrom is the row's stored lower bound, or the write instant where the write stamps one.`
|
|
107
107
|
}
|
|
108
108
|
]
|
|
@@ -114,13 +114,13 @@ function assertEffectiveValidityLowerBound(subject, effectiveValidFrom, validTo)
|
|
|
114
114
|
}
|
|
115
115
|
function assertOrderedValidityWindow(subject, validFrom, validTo) {
|
|
116
116
|
if (!isInvertedValidityWindow(validFrom, validTo)) return;
|
|
117
|
-
throw new
|
|
117
|
+
throw new chunkX4GDXBOP_cjs.ValidationError(
|
|
118
118
|
`Inverted validity window for ${subject}: validFrom "${validFrom}" is after validTo "${validTo}".`,
|
|
119
119
|
{
|
|
120
120
|
issues: [
|
|
121
121
|
{
|
|
122
122
|
path: "validFrom",
|
|
123
|
-
code:
|
|
123
|
+
code: chunkX4GDXBOP_cjs.INVERTED_VALIDITY_WINDOW_CODE,
|
|
124
124
|
message: `Expected validFrom <= validTo, got "${validFrom}" > "${validTo}"`
|
|
125
125
|
}
|
|
126
126
|
]
|
|
@@ -130,19 +130,25 @@ function assertOrderedValidityWindow(subject, validFrom, validTo) {
|
|
|
130
130
|
}
|
|
131
131
|
);
|
|
132
132
|
}
|
|
133
|
+
function assertsStoredLowerBound(fence) {
|
|
134
|
+
return fence.expectedValidFrom !== void 0;
|
|
135
|
+
}
|
|
136
|
+
function assertsStoredUpperBound(fence) {
|
|
137
|
+
return fence.expectedValidTo !== void 0;
|
|
138
|
+
}
|
|
133
139
|
function preservesImmutableLowerBound(policy) {
|
|
134
140
|
return policy === "preserve";
|
|
135
141
|
}
|
|
136
142
|
function assertStatedLowerBoundIsApplicable(subject, statedValidFrom, storedValidFrom) {
|
|
137
143
|
if (statedBoundMatchesStored(statedValidFrom, storedValidFrom)) return;
|
|
138
144
|
const storedDescription = storedValidFrom === void 0 ? "the row has no lower bound" : `the row's stored lower bound is "${storedValidFrom}"`;
|
|
139
|
-
throw new
|
|
145
|
+
throw new chunkX4GDXBOP_cjs.ValidationError(
|
|
140
146
|
`Unappliable validFrom for ${subject}: stated "${statedValidFrom}", but ${storedDescription} and the row is live.`,
|
|
141
147
|
{
|
|
142
148
|
issues: [
|
|
143
149
|
{
|
|
144
150
|
path: "validFrom",
|
|
145
|
-
code:
|
|
151
|
+
code: chunkX4GDXBOP_cjs.IMMUTABLE_VALIDITY_LOWER_BOUND_CODE,
|
|
146
152
|
message: `A live row's lower bound is history and an in-place update never rewrites it, so "${statedValidFrom}" could not be applied.`
|
|
147
153
|
}
|
|
148
154
|
]
|
|
@@ -182,6 +188,8 @@ function nowIso() {
|
|
|
182
188
|
|
|
183
189
|
exports.assertOrderedValidityWindow = assertOrderedValidityWindow;
|
|
184
190
|
exports.assertWritableValidityWindow = assertWritableValidityWindow;
|
|
191
|
+
exports.assertsStoredLowerBound = assertsStoredLowerBound;
|
|
192
|
+
exports.assertsStoredUpperBound = assertsStoredUpperBound;
|
|
185
193
|
exports.canonicalizeDatabaseTimestamp = canonicalizeDatabaseTimestamp;
|
|
186
194
|
exports.isCanonicalIsoDate = isCanonicalIsoDate;
|
|
187
195
|
exports.isInvertedValidityWindow = isInvertedValidityWindow;
|
|
@@ -193,5 +201,5 @@ exports.statedBoundMatchesStored = statedBoundMatchesStored;
|
|
|
193
201
|
exports.validateCanonicalIsoDate = validateCanonicalIsoDate;
|
|
194
202
|
exports.validateOptionalCanonicalIsoDate = validateOptionalCanonicalIsoDate;
|
|
195
203
|
exports.validityWindowContainsInstant = validityWindowContainsInstant;
|
|
196
|
-
//# sourceMappingURL=chunk-
|
|
197
|
-
//# sourceMappingURL=chunk-
|
|
204
|
+
//# sourceMappingURL=chunk-M5MSP3BI.cjs.map
|
|
205
|
+
//# sourceMappingURL=chunk-M5MSP3BI.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/utils/date.ts"],"names":["ValidationError","INVERTED_VALIDITY_WINDOW_CODE","IMMUTABLE_VALIDITY_LOWER_BOUND_CODE"],"mappings":"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","file":"chunk-M5MSP3BI.cjs","sourcesContent":["/**\n * Date encoding utilities for consistent storage.\n *\n * Contract: All dates are stored as ISO 8601 strings in UTC.\n * - Always includes milliseconds\n * - Always UTC (Z suffix)\n * - Sorts correctly as strings\n */\n\nimport {\n IMMUTABLE_VALIDITY_LOWER_BOUND_CODE,\n INVERTED_VALIDITY_WINDOW_CODE,\n ValidationError,\n} from \"../errors\";\n\n/**\n * ISO 8601 datetime pattern.\n * Matches formats like:\n * - 2024-01-15T10:30:00.000Z\n * - 2024-01-15T10:30:00Z\n * - 2024-01-15T10:30:00.123Z\n */\nconst ISO_DATE_PATTERN = /^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}(?:\\.\\d{1,3})?Z$/;\n\n/**\n * Checks if a string is a valid ISO 8601 datetime.\n *\n * @param value - String to validate\n * @returns True if valid ISO 8601 datetime\n */\nexport function isValidIsoDate(value: string): boolean {\n if (!ISO_DATE_PATTERN.test(value)) {\n return false;\n }\n // Also check that Date parsing produces a valid date\n const date = new Date(value);\n return !Number.isNaN(date.getTime());\n}\n\n/**\n * Validates that a string is a valid ISO 8601 datetime.\n * Throws ValidationError if invalid.\n *\n * @param value - String to validate\n * @param fieldName - Name of field for error message\n * @returns The validated string\n * @throws ValidationError if not a valid ISO datetime\n */\nexport function validateIsoDate(value: string, fieldName: string): string {\n if (!isValidIsoDate(value)) {\n throw new ValidationError(\n `Invalid ISO 8601 datetime for \"${fieldName}\": \"${value}\". ` +\n `Expected format: YYYY-MM-DDTHH:mm:ss.sssZ`,\n {\n issues: [\n {\n path: fieldName,\n message: `Invalid ISO 8601 datetime format. Expected: YYYY-MM-DDTHH:mm:ss.sssZ, got: \"${value}\"`,\n },\n ],\n },\n {\n suggestion: `Use a valid ISO 8601 UTC datetime like \"2024-01-15T10:30:00.000Z\"`,\n },\n );\n }\n return value;\n}\n\n/**\n * Strict canonical ISO 8601 pattern: fixed-width UTC with exactly\n * millisecond precision (`YYYY-MM-DDTHH:mm:ss.sssZ`). Unlike\n * {@link ISO_DATE_PATTERN}, which tolerates a missing or variable-width\n * fractional part, this is the only shape whose lexicographic text order\n * matches chronological order — avoiding cases like `\"...:00.1Z\"` (= `.100`)\n * sorting *after* `\"...:00.101Z\"`.\n */\nconst CANONICAL_ISO_DATE_PATTERN =\n /^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}\\.\\d{3}Z$/;\n\nconst ZONELESS_DATETIME_PATTERN =\n /^\\d{4}-\\d{2}-\\d{2}[ T]\\d{2}:\\d{2}(?::\\d{2}(?:\\.\\d+)?)?$/;\nconst OFFSET_DATETIME_PATTERN =\n /^(\\d{4}-\\d{2}-\\d{2})[ T](\\d{2}:\\d{2}(?::\\d{2}(?:\\.\\d+)?)?)(Z|[+-]\\d{2}(?::?\\d{2})?)$/i;\nconst DATE_ONLY_PATTERN = /^\\d{4}-\\d{2}-\\d{2}$/;\n\nfunction normalizedOffset(offset: string): string {\n if (offset.toUpperCase() === \"Z\") return \"Z\";\n if (/^[+-]\\d{2}$/.test(offset)) return `${offset}:00`;\n if (/^[+-]\\d{4}$/.test(offset)) {\n return `${offset.slice(0, 3)}:${offset.slice(3)}`;\n }\n return offset;\n}\n\nfunction databaseTimestampMilliseconds(value: string): number {\n if (ZONELESS_DATETIME_PATTERN.test(value)) {\n return Date.parse(`${value.replace(\" \", \"T\")}Z`);\n }\n const offsetMatch = OFFSET_DATETIME_PATTERN.exec(value);\n if (offsetMatch !== null) {\n const date = offsetMatch[1];\n const time = offsetMatch[2];\n const offset = offsetMatch[3];\n if (date === undefined || time === undefined || offset === undefined) {\n return Number.NaN;\n }\n return Date.parse(`${date}T${time}${normalizedOffset(offset)}`);\n }\n if (DATE_ONLY_PATTERN.test(value)) {\n return Date.parse(`${value}T00:00:00.000Z`);\n }\n return Number.NaN;\n}\n\n/**\n * Canonicalizes a database-driver timestamp without interpreting a zoneless\n * string in the host timezone. PostgreSQL drivers can return values such as\n * `2026-06-25 12:00:00`; TypeGraph treats that shape as UTC so the same stored\n * clock value cannot move across hosts or daylight-saving boundaries.\n *\n * Returns `undefined` for an unsupported or unrepresentable value so callers\n * can raise an error specific to their storage boundary.\n */\nexport function canonicalizeDatabaseTimestamp(\n value: unknown,\n): string | undefined {\n if (value instanceof Date) {\n if (Number.isNaN(value.getTime())) return undefined;\n return value.toISOString();\n }\n if (typeof value !== \"string\") return undefined;\n const milliseconds = databaseTimestampMilliseconds(value);\n if (Number.isNaN(milliseconds)) return undefined;\n return new Date(milliseconds).toISOString();\n}\n\n/**\n * Checks if a string is a canonical UTC ISO 8601 datetime with fixed\n * millisecond width (`YYYY-MM-DDTHH:mm:ss.sssZ`).\n */\nexport function isCanonicalIsoDate(value: string): boolean {\n if (!CANONICAL_ISO_DATE_PATTERN.test(value)) return false;\n const date = new Date(value);\n return !Number.isNaN(date.getTime()) && date.toISOString() === value;\n}\n\n/**\n * Validates that a string is a canonical UTC ISO 8601 datetime with fixed\n * millisecond width. Stricter than {@link validateIsoDate} (which also\n * accepts missing or 1–2 digit milliseconds): required wherever the value\n * is compared **as text** against stored timestamps and must sort\n * chronologically — e.g. a temporal `asOf` coordinate, where a\n * variable-width value would mis-order and silently include or exclude the\n * wrong rows. Produce one with `new Date(value).toISOString()`.\n *\n * @param value - String to validate\n * @param fieldName - Name of field for error message\n * @returns The validated string\n * @throws ValidationError if not a canonical UTC ISO datetime\n */\nexport function validateCanonicalIsoDate(\n value: string,\n fieldName: string,\n): string {\n if (!isCanonicalIsoDate(value)) {\n throw new ValidationError(\n `Invalid canonical ISO 8601 datetime for \"${fieldName}\": \"${value}\". ` +\n `Expected fixed-width UTC: YYYY-MM-DDTHH:mm:ss.sssZ`,\n {\n issues: [\n {\n path: fieldName,\n message: `Expected canonical UTC ISO 8601 (YYYY-MM-DDTHH:mm:ss.sssZ), got: \"${value}\"`,\n },\n ],\n },\n {\n suggestion: `Use a fixed-width UTC datetime like \"2024-01-15T10:30:00.000Z\" (e.g. new Date(value).toISOString()).`,\n },\n );\n }\n return value;\n}\n\n/**\n * Validates an optional canonical ISO date string. Returns `undefined` for an\n * absent value; otherwise enforces canonical fixed-width UTC ISO 8601 via\n * {@link validateCanonicalIsoDate}. Used for stored validity-window inputs\n * (`validFrom` / `validTo`) so every timestamp the temporal filters compare as\n * text is canonical and sorts chronologically — the same contract the `asOf`\n * read coordinate already enforces.\n */\nexport function validateOptionalCanonicalIsoDate(\n value: string | undefined,\n fieldName: string,\n): string | undefined {\n if (value === undefined) return undefined;\n return validateCanonicalIsoDate(value, fieldName);\n}\n\n/**\n * Whether a CANONICAL stated bound names the same instant a row already stores.\n *\n * The one comparison of a caller's bound against a stored one, so the coalesce\n * dirty check (\"would this write move the window?\") and the write guard (\"can\n * this stated bound be applied?\") can never disagree about what \"the same bound\"\n * means. Two copies of it did disagree — one comparing driver text, one\n * comparing instants — which is how a re-stated window wrote on one backend and\n * coalesced on the other.\n *\n * Only the STORED side is canonicalized. It arrives as the driver rendered it,\n * and the dialects do not render a timestamp the same way (SQLite returns the\n * written text; a Postgres driver may hand back a zoned string equivalent to the\n * canonical form without being identical to it). The stated side needs no\n * canonicalization because every write path validates it as canonical first —\n * which is a PRECONDITION here, not an assumption: a non-canonical stated bound\n * would compare unequal to an equivalent stored instant and must be rejected by\n * {@link validateCanonicalIsoDate} rather than silently treated as a mismatch.\n */\nexport function statedBoundMatchesStored(\n stated: string,\n stored: string | undefined,\n): boolean {\n return stated === canonicalizeDatabaseTimestamp(stored);\n}\n\n/**\n * Whether a stated validity window has NEGATIVE width — a row that stopped\n * being true before it started. The one comparison every window refusal is\n * built on, so paths that must report the fault through their own error type\n * (trusted import) decide it identically to the ones that throw a\n * `ValidationError`.\n *\n * PRECONDITION: both endpoints are canonical fixed-width UTC ISO 8601, which is\n * what makes a lexicographic compare a chronological one. Every caller\n * establishes that before comparing, with no exception: the paths that throw a\n * `ValidationError` reach this through {@link validateOptionalCanonicalIsoDate},\n * and trusted import — which skips schema validation for throughput —\n * format-checks the stated window fields of every streamed row against\n * {@link isCanonicalIsoDate} before reaching here. A bound read back from a row\n * needs no check of its own: it is canonical because the write that stored it\n * was held to this same contract — SQLite hands that text back verbatim, and the\n * PostgreSQL row mapper normalizes the driver's shape back to it. So no caller\n * can compare a value that would mis-sort, here or later against an `asOf`\n * coordinate.\n *\n * ZERO width (`validFrom === validTo`) is not inverted: it is what a\n * same-instant retraction produces at millisecond precision, and the store's own\n * output must round-trip.\n */\nexport function isInvertedValidityWindow(\n validFrom: string | undefined,\n validTo: string | undefined,\n): boolean {\n if (validFrom === undefined || validTo === undefined) return false;\n return validFrom > validTo;\n}\n\n/**\n * Whether a validity window is readable at NO instant — inverted OR zero width.\n * The CHOICE predicate, sibling to {@link isInvertedValidityWindow}'s REFUSAL\n * predicate, and the two answer different questions on purpose:\n *\n * - a window a caller STATED in full is refused only when it is inverted, because\n * zero width is what a same-instant retraction produces and the store's own\n * output must round-trip;\n * - a bound a write CHOOSES for a caller who stated none must never satisfy this\n * one, because a row nobody can read at any coordinate is not a window the\n * caller asked for.\n *\n * `inverted ⇒ empty`, and `empty ∧ ¬inverted ⟺ zero width`. That law is a\n * property in `tests/property/temporal-window.test.ts`, so the pair cannot drift\n * into disagreeing about anything but the boundary they deliberately differ on.\n *\n * PRECONDITION: as {@link isInvertedValidityWindow} — both endpoints canonical\n * fixed-width UTC ISO 8601, so the lexicographic compare is a chronological one.\n */\nexport function isEmptyValidityWindow(\n validFrom: string | undefined,\n validTo: string | undefined,\n): boolean {\n if (validFrom === undefined || validTo === undefined) return false;\n return validFrom >= validTo;\n}\n\n/**\n * Whether a canonical instant belongs to the half-open validity interval\n * `[validFrom, validTo)`. An omitted bound is unbounded on that side.\n *\n * This is the single JavaScript owner of validity-window membership. SQL read\n * paths express the same decision through the shared temporal compiler.\n */\nexport function validityWindowContainsInstant(\n validFrom: string | undefined,\n validTo: string | undefined,\n instant: string,\n): boolean {\n return (\n (validFrom === undefined || validFrom <= instant) &&\n (validTo === undefined || instant < validTo)\n );\n}\n\n/**\n * THE lower bound a write that STAMPS its own start stores, decided against the\n * instant it is about to stamp. One owner for every such write, so no two of them\n * can spell the decision differently. Three inputs, three outcomes:\n *\n * - a stated `null` → no lower bound (a CONFIRMED open-left window, which is\n * how interchange round-trips a row that has none);\n * - a stated string → that bound, the caller's own assertion, verbatim;\n * - nothing stated → the write instant, UNLESS stamping it would leave the\n * window readable at no instant. A row carrying only a\n * `validTo` at or before the write instant is \"born already\n * ended\": its start is UNKNOWN, not at-or-after its end, so\n * it stores no lower bound and reads back at every `asOf`\n * before that end (issue #407).\n *\n * The comparison against `validTo` is NON-STRICT: `validTo === writeInstant`\n * stores no bound too. A stamped `[T, T)` is a successful write no coordinate can\n * observe, and the millisecond of skew between a caller's own `Date.now()` and the\n * backend's sample is enough to land there — so the rule is total, and there is no\n * input for which a stamped bound yields an empty window.\n *\n * The write instant is a PARAMETER, not a clock read: the caller passes the very\n * value it binds into `created_at`/`updated_at` (or, for a resurrection, the\n * instant its guard judged), so the decision and the stamp cannot come from two\n * different samples (issue #413's failure mode). This function has no way to\n * sample a clock, which is what makes that structural rather than tested.\n *\n * PRECONDITION: as {@link isEmptyValidityWindow}. This is called BELOW the\n * validation boundary, on a public `GraphBackend` surface, so canonicality is\n * established by whoever reached the backend: store paths through\n * {@link validateOptionalCanonicalIsoDate}, interchange import through its own\n * window validator, trusted import through its per-chunk format check. A direct\n * `GraphBackend` caller establishes it itself — a pre-existing property of that\n * surface, written down here rather than left implicit.\n */\nexport function resolveStampedValidityLowerBound(\n statedValidFrom: string | null | undefined,\n validTo: string | undefined,\n writeInstant: string,\n): string | undefined {\n if (statedValidFrom === null) return undefined;\n if (statedValidFrom !== undefined) return statedValidFrom;\n return isEmptyValidityWindow(writeInstant, validTo) ? undefined : (\n writeInstant\n );\n}\n\n/**\n * The lower bound a write that PASSES THROUGH a stated one stores: `null` — the\n * interchange spelling of a confirmed open-left window — becomes \"no bound\", and\n * a string is stored verbatim.\n *\n * Separate from {@link resolveStampedValidityLowerBound} because it answers a\n * different question. Its one caller (`buildUpdateEdge`'s resurrection leg) writes\n * the window only when the caller NAMED a lower bound; an edge resurrection that\n * names none RETAINS the stored window rather than choosing a new one, so there is\n * no instant to judge and none is offered.\n */\nexport function resolveStatedValidityLowerBound(\n validFrom: string | null,\n): string | undefined {\n return validFrom ?? undefined;\n}\n\n/**\n * Refuses a `validTo` whose EFFECTIVE lower bound would invert the window. On an\n * in-place update the row's stored lower bound is the effective one and must stay\n * <= the new `validTo`; on a resurrection that RESETS `valid_from` it is the\n * write instant, so a lone past `validTo` would be born inverted.\n *\n * A ZERO-width window (`validTo === effectiveValidFrom`) is legal and stays\n * legal: it is what a same-instant retraction produces at millisecond\n * precision, and the identity-import window check sanctions it for the same\n * reason. Only NEGATIVE width refuses.\n *\n * Reached through {@link assertWritableValidityWindow} rather than called\n * directly, so no writer can check the effective bound without also checking a\n * stated pair.\n */\nfunction assertEffectiveValidityLowerBound(\n subject: string,\n effectiveValidFrom: string | undefined,\n validTo: string | undefined,\n): void {\n if (!isInvertedValidityWindow(effectiveValidFrom, validTo)) return;\n throw new ValidationError(\n `Inverted validity window for ${subject}: the effective validFrom \"${effectiveValidFrom}\" is after validTo \"${validTo}\".`,\n {\n issues: [\n {\n path: \"validTo\",\n code: INVERTED_VALIDITY_WINDOW_CODE,\n message: `Expected the effective validFrom <= validTo, got \"${effectiveValidFrom}\" > \"${validTo}\". The effective validFrom is the row's stored lower bound, or the write instant where the write stamps one.`,\n },\n ],\n },\n {\n suggestion:\n \"Provide both validFrom and validTo for a historical window, or drop validTo to keep the row current.\",\n },\n );\n}\n\n/**\n * Rejects an inverted validity window. `validFrom > validTo` describes a row\n * that stopped being true before it started, so no current-mode or `asOf` read\n * can ever observe it — the write succeeds and the row is then reachable only\n * through `includeEnded`, which reads as data loss rather than as the error it\n * is. Call this wherever both endpoints are supplied together; both are\n * canonical ISO 8601 by then, so a lexicographic compare is a chronological\n * compare.\n *\n * @param subject - Human-readable identification of the row, for the message\n * (e.g. `Person \"01H...\"`).\n * @throws ValidationError if both endpoints are present and out of order\n */\nexport function assertOrderedValidityWindow(\n subject: string,\n validFrom: string | undefined,\n validTo: string | undefined,\n): void {\n if (!isInvertedValidityWindow(validFrom, validTo)) return;\n throw new ValidationError(\n `Inverted validity window for ${subject}: validFrom \"${validFrom}\" is after validTo \"${validTo}\".`,\n {\n issues: [\n {\n path: \"validFrom\",\n code: INVERTED_VALIDITY_WINDOW_CODE,\n message: `Expected validFrom <= validTo, got \"${validFrom}\" > \"${validTo}\"`,\n },\n ],\n },\n {\n suggestion:\n \"Pass a validFrom at or before validTo, or omit validTo to leave the window open.\",\n },\n );\n}\n\n/**\n * What an UPDATE will do with the row's validity lower bound — the two facts the\n * write guard needs, stated by the writer that knows them.\n *\n * Every update path must decide `appliesStatedValidFrom` explicitly, because the\n * answer is not a property of the guard's other arguments: the same\n * `(validFrom, storedBound, validTo)` triple is a legal window restatement on a\n * resurrection and an unappliable bound on an in-place update.\n */\nexport type UpdateValidityLowerBound = Readonly<{\n /**\n * The bound the row will hold when the caller states no `validFrom`: the\n * stored `valid_from` for an in-place update, the write instant for a\n * resurrection that stamps a new one, `undefined` where there is no bound to\n * invert against.\n */\n effectiveValidFrom: string | undefined;\n /**\n * Whether the write STORES a stated `validFrom`. False for an in-place update\n * of a live row — `buildUpdateNode` / `buildUpdateEdge` rewrite `valid_from`\n * only on a resurrection — which is what makes a differing stated bound a\n * refusal rather than a silent drop.\n */\n appliesStatedValidFrom: boolean;\n /**\n * Whether `effectiveValidFrom` IS the row's stored `valid_from` — the value an\n * `expectedValidFrom` predicate would name — rather than a bound this write is\n * about to stamp itself.\n *\n * A node resurrection resets `valid_from` to the write instant and passes THAT\n * as the effective bound, so its verdict never looked at what the row holds and\n * a fence on the stored value would predicate the write on something nothing\n * read. An edge retains its bound through a resurrection, so its effective\n * bound is the stored one on both legs.\n */\n effectiveBoundIsStored: boolean;\n}>;\n\n/**\n * The `expectedValidFrom` predicate a write owes its verdict, shaped for\n * spreading straight into the backend's update params.\n *\n * `{}` means \"assert nothing\"; `{ expectedValidFrom: null }` means \"assert the\n * row still has NO lower bound\". The two are different claims and the object\n * form keeps them distinguishable at every call site — see\n * `UpdateNodeParams.expectedValidFrom`.\n */\nexport type ValidityLowerBoundFence = Readonly<{\n expectedValidFrom?: string | null;\n}>;\n\n/**\n * Whether a {@link ValidityLowerBoundFence} STATES anything. Returns a\n * boolean, despite the `asserts` in its name reading like a TypeScript\n * assertion function: it answers \"does this fence assert the row's stored\n * lower bound?\".\n *\n * THE SINGLE OWNER of that question, placed beside the type it decides about.\n * Two spellings of it existed — `args.expectedValidFrom !== undefined` at the\n * write step that carries the fence into the UPDATE, and a key-membership test\n * wherever a fence had to be recognised as empty. They agree today under\n * `exactOptionalPropertyTypes`, which is exactly the state in which a second\n * implementation of an existing decision is still a defect: the copies WILL\n * drift, and this one decides whether a write is fenced at all.\n *\n * `{ expectedValidFrom: null }` is a STATED fence — \"assert the row still has\n * NO lower bound\" — not an empty one, which is why the test is against\n * `undefined` and not against nullishness.\n */\nexport function assertsStoredLowerBound<T extends ValidityLowerBoundFence>(\n fence: T,\n): fence is T & StatedValidityLowerBoundFence {\n return fence.expectedValidFrom !== undefined;\n}\n\n/**\n * A {@link ValidityLowerBoundFence} that states a bound — what\n * {@link assertsStoredLowerBound} narrows to, so a caller that has asked the\n * question does not have to re-ask it to satisfy `exactOptionalPropertyTypes`.\n * Re-asking is how the second spelling gets reintroduced.\n */\nexport type StatedValidityLowerBoundFence = Readonly<{\n expectedValidFrom: string | null;\n}>;\n\n/**\n * The `expectedValidTo` predicate a write owes a verdict that read the row's\n * stored window END, shaped for spreading straight into the update params.\n *\n * The counterpart of {@link ValidityLowerBoundFence}, and stated separately for\n * the same reason: `{}` means \"assert nothing\" and `{ expectedValidTo: null }`\n * means \"assert the row is still open-ended\". A reopen of an `oneActive` edge\n * judged the end the row carried, so its UPDATE asserts it.\n */\nexport type ValidityUpperBoundFence = Readonly<{\n expectedValidTo?: string | null;\n}>;\n\n/**\n * Whether a {@link ValidityUpperBoundFence} STATES anything — the single owner\n * of that question, for the same reason {@link assertsStoredLowerBound} is the\n * single owner of its own.\n */\nexport function assertsStoredUpperBound<T extends ValidityUpperBoundFence>(\n fence: T,\n): fence is T & Readonly<{ expectedValidTo: string | null }> {\n return fence.expectedValidTo !== undefined;\n}\n\n/**\n * What {@link assertWritableValidityWindow} reports back about the verdict it\n * just reached — not about the window, but about what the verdict DEPENDED ON.\n *\n * THE SINGLE OWNER of the question \"must this write assert the row's stored\n * lower bound?\", and it answers by handing over the predicate ITSELF rather than\n * a flag a caller then turns into one. A write asserts every component its\n * verdict read (see `UpdateNodeParams.expectedValidFrom`), and which components\n * those are is decided by which branches the guard actually took — so a caller\n * that could still spell the fence on its own would eventually spell a different\n * one. Interchange import did exactly that: it asserted the probed\n * `valid_from` unconditionally, over-fencing props-only updates the store paths\n * (correctly) left unfenced. There is now nothing to re-derive.\n *\n * Too FEW assertions is a silent race; too many is a refusal of writes that are\n * legitimate. Both failures come from a second spelling.\n */\nexport type ValidityWindowVerdict = Readonly<{\n /**\n * The fence this verdict obliges the write to carry. Non-empty when the\n * verdict consulted the row's STORED `valid_from` — either by comparing a\n * stated bound against it, or by inverting a lone `validTo` against it — and\n * empty when the caller named no window at all, when the write applies the\n * bound it stated, or when the effective bound was one this write will stamp\n * rather than one the row holds. In those cases the verdict is independent of\n * what the row carries, and predicating the write on it would refuse a\n * concurrent recreate that changed nothing this decision looked at.\n */\n storedLowerBoundFence: ValidityLowerBoundFence;\n}>;\n\n/**\n * Whether an upsert explicitly treats its stated lower bound as\n * create/resurrection-only input.\n *\n * This predicate owns the policy decision for both write execution and\n * unchanged-upsert coalescing, so those paths cannot drift on whether a live\n * row's stored lower bound is preserved.\n */\nexport function preservesImmutableLowerBound(\n policy: \"preserve\" | \"refuse\" | undefined,\n): policy is \"preserve\" {\n return policy === \"preserve\";\n}\n\n/**\n * Refuses a stated `validFrom` the write would not apply.\n *\n * A live row's lower bound is HISTORY: it records when the row started being\n * true, and an in-place update never moves it. Accepting a bound that names a\n * different instant and then dropping it is the API lying — the caller's stated\n * window silently is not the stored one, while the write still spends a version\n * bump and a history row moving nothing. Restating the bound the row already\n * holds stays legal, so a caller that echoes a row's own window back (a merge\n * commit, a re-delivered upsert) is unaffected.\n *\n * Reached through {@link assertWritableValidityWindow} rather than called\n * directly, so no writer can accept a lower bound without declaring whether it\n * applies one.\n */\nfunction assertStatedLowerBoundIsApplicable(\n subject: string,\n statedValidFrom: string,\n storedValidFrom: string | undefined,\n): void {\n if (statedBoundMatchesStored(statedValidFrom, storedValidFrom)) return;\n const storedDescription =\n storedValidFrom === undefined ?\n \"the row has no lower bound\"\n : `the row's stored lower bound is \"${storedValidFrom}\"`;\n throw new ValidationError(\n `Unappliable validFrom for ${subject}: stated \"${statedValidFrom}\", but ${storedDescription} and the row is live.`,\n {\n issues: [\n {\n path: \"validFrom\",\n code: IMMUTABLE_VALIDITY_LOWER_BOUND_CODE,\n message: `A live row's lower bound is history and an in-place update never rewrites it, so \"${statedValidFrom}\" could not be applied.`,\n },\n ],\n },\n {\n suggestion:\n storedValidFrom === undefined ?\n \"Omit validFrom: this row has no lower bound to restate, and only a resurrection can give it one.\"\n : `Restate the stored bound (\"${storedValidFrom}\") or omit validFrom.`,\n },\n );\n}\n\n/**\n * THE window-ordering guard a valid-time UPDATE goes through, identically for\n * nodes and edges. Refuses a window of negative width — a row that stopped\n * being true before it started — whether the caller states both endpoints or\n * only the new end. Also refuses a stated lower bound the write cannot apply,\n * so no update accepts a `validFrom` it will ignore.\n *\n * Three checks, because the failures deserve different messages: the caller who\n * supplied both endpoints out of order gets told about the pair, the caller who\n * stated a lower bound this write cannot store gets told which bound the row\n * holds, and the caller whose lone `validTo` inverts against the bound the row\n * will actually carry gets told which bound that is.\n *\n * The stated pair is judged FIRST — an inverted pair is wrong whatever the row\n * holds — and the applicability of the lower bound before the effective-bound\n * check, so a caller is told their bound will not be stored rather than being\n * told about a bound they did not name.\n *\n * INSERTS use {@link assertOrderedValidityWindow} alone, and that is now the\n * COMPLETE stated-pair rule rather than a partial one. An insert carrying a lone\n * historical `validTo` means \"born already ended\", and there is no bound to hold\n * the caller to because the write stamps none:\n * {@link resolveStampedValidityLowerBound} stores no lower bound whenever the\n * instant it would stamp cannot precede the stated end (I1b). So no insert path\n * can store a window readable at no coordinate, on any `GraphBackend` caller —\n * the decision lives in the SQL builders, below the store, below interchange and\n * below trusted import (I5). Only an UPDATE has a lower bound the caller can be\n * held to.\n *\n * @param subject - Human-readable identification of the row, for the message\n * (e.g. `Person \"01H...\"`).\n * @param validFrom - The caller's explicit lower bound, if any.\n * @param lowerBound - What the write will do with the row's lower bound; see\n * {@link UpdateValidityLowerBound}.\n * @returns {@link ValidityWindowVerdict} — the `expectedValidFrom` fence this\n * verdict obliges the write to carry, empty when it read no stored bound.\n * @throws ValidationError with issue code {@link INVERTED_VALIDITY_WINDOW_CODE}\n * or {@link IMMUTABLE_VALIDITY_LOWER_BOUND_CODE}\n */\nexport function assertWritableValidityWindow(\n subject: string,\n validFrom: string | undefined,\n lowerBound: UpdateValidityLowerBound,\n validTo: string | undefined,\n): ValidityWindowVerdict {\n assertOrderedValidityWindow(subject, validFrom, validTo);\n\n // The stated bound is COMPARED against the stored one only here — a write\n // that applies what the caller stated has nothing to compare it to.\n const comparedStatedBound =\n validFrom !== undefined && !lowerBound.appliesStatedValidFrom;\n if (comparedStatedBound) {\n assertStatedLowerBoundIsApplicable(\n subject,\n validFrom,\n lowerBound.effectiveValidFrom,\n );\n }\n\n assertEffectiveValidityLowerBound(\n subject,\n validFrom ?? lowerBound.effectiveValidFrom,\n validTo,\n );\n // ...and the inversion check falls back to the row's bound only when the\n // caller named an end without a start. Note this is true whether or not the\n // row HAS a bound: \"no lower bound to invert against\" is itself a reading of\n // the row, and a recreate that gives the row one changes the answer.\n const comparedStoredBoundAgainstEnd =\n validFrom === undefined && validTo !== undefined;\n\n const readEffectiveLowerBound =\n comparedStatedBound || comparedStoredBoundAgainstEnd;\n return {\n storedLowerBoundFence:\n readEffectiveLowerBound && lowerBound.effectiveBoundIsStored ?\n // eslint-disable-next-line unicorn/no-null -- `expectedValidFrom` distinguishes \"assert IS NULL\" (null) from \"assert nothing\" (an absent key); see UpdateNodeParams.\n { expectedValidFrom: lowerBound.effectiveValidFrom ?? null }\n : {},\n };\n}\n\n/**\n * Encodes a Date to an ISO 8601 string for storage.\n */\nexport function encodeDate(date: Date): string {\n return date.toISOString();\n}\n\n/**\n * Decodes an ISO 8601 string to a Date.\n * Validates the string format first.\n *\n * @throws ValidationError if not a valid ISO datetime\n */\nexport function decodeDate(isoString: string): Date {\n validateIsoDate(isoString, \"date\");\n return new Date(isoString);\n}\n\n/**\n * Returns the current timestamp as an ISO string.\n */\nexport function nowIso(): string {\n return new Date().toISOString();\n}\n"]}
|
|
@@ -1,12 +1,11 @@
|
|
|
1
|
-
import { contributionRebuildSupported, createSqliteOperationStrategy, createContributionMaterializer, gateFulltextMethods, assertTrustedImportDatabaseEmpty, suspendSqliteSecondaryIndexes, createSqliteTrustedImportSession, restoreSecondaryIndexes, analyzeImportedTables, mapContributionMaterializationRow, SQLITE_CONTRIBUTION_MAT_TIMESTAMPS, buildContributionInsertValues, buildContributionOnConflictSet, tableExistsFromRow, assertAdoptedDialect, buildKindRemovalInsertValues, SQLITE_KIND_REMOVAL_TIMESTAMPS, buildKindRemovalOnConflictSet, mapKindRemovalRow, buildMaterializationInsertValues, SQLITE_INDEX_MAT_TIMESTAMPS, buildMaterializationOnConflictSet, mapMaterializationRow, createCommonOperationBackend, vectorSlotFromParams, buildLiveNodeCandidates, mapVectorWriteError, mapHybridSearchRow, gateFulltext, FIND_EDGES_ENDPOINT_FIXED_PARAM_COUNT, EMBEDDING_UPSERT_PARAM_COUNT, vectorSlotFromDropIndexParams, vectorSlotFromCreateIndexParams, assertActiveSchemaVersion, getOrCreateLru, commitSchemaVersionIfKindsEmpty } from './chunk-
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
7
|
-
import {
|
|
8
|
-
import {
|
|
9
|
-
import { ConfigurationError, BackendDisposedError } from './chunk-ZLONH2UD.js';
|
|
1
|
+
import { tables2, assertBundledCapabilityDeclarations, contributionRebuildSupported, createSqliteOperationStrategy, createContributionMaterializer, gateFulltextMethods, assertTrustedImportDatabaseEmpty, suspendSqliteSecondaryIndexes, createSqliteTrustedImportSession, restoreSecondaryIndexes, analyzeImportedTables, generateSqliteCreateTableSQL, mapContributionMaterializationRow, SQLITE_CONTRIBUTION_MAT_TIMESTAMPS, buildContributionInsertValues, buildContributionOnConflictSet, tableExistsFromRow, assertAdoptedDialect, buildKindRemovalInsertValues, SQLITE_KIND_REMOVAL_TIMESTAMPS, buildKindRemovalOnConflictSet, mapKindRemovalRow, buildMaterializationInsertValues, SQLITE_INDEX_MAT_TIMESTAMPS, buildMaterializationOnConflictSet, mapMaterializationRow, generateSqliteDDL, createCommonOperationBackend, vectorSlotFromParams, buildLiveNodeCandidates, mapVectorWriteError, mapHybridSearchRow, gateFulltext, createSqliteTables, sqliteContributions, FIND_EDGES_ENDPOINT_FIXED_PARAM_COUNT, EMBEDDING_UPSERT_PARAM_COUNT, vectorSlotFromDropIndexParams, vectorSlotFromCreateIndexParams, assertActiveSchemaVersion, getOrCreateLru, commitSchemaVersionIfKindsEmpty } from './chunk-UKOVGCRN.js';
|
|
2
|
+
import { toDrizzleSql, compileQueryWithDialect } from './chunk-PVFFH7TL.js';
|
|
3
|
+
import { createNodeRowMapper, SQLITE_ROW_MAPPER_CONFIG, createEdgeRowMapper, createUniqueRowMapper, createSchemaVersionRowMapper, nowIso, coerceNumericScore } from './chunk-VUQZNUHU.js';
|
|
4
|
+
import { resolveDeclaredBackendResource, auditBackendResource, isSqliteNotAuthorizedError, isMissingTableError, chunk } from './chunk-QG5VEOKX.js';
|
|
5
|
+
import { normalizeGraphAnalyticsCapabilities, markFirstPartyFactory, INTERNAL_TEMPORARY_WRITES, SQLITE_CAPABILITIES, SQLITE_MAX_BIND_PARAMETERS, MODERN_SQLITE_MAX_BIND_PARAMETERS, DURABLE_OBJECT_MAX_BIND_PARAMETERS, D1_MAX_BIND_PARAMETERS } from './chunk-LKZDQ2B4.js';
|
|
6
|
+
import { fts5Strategy, buildVectorCapabilities, buildFulltextCapabilities, assertVectorSearchLimit, resolveEfSearchOverride, vectorSearchFrontierTuning } from './chunk-PC5NGH5A.js';
|
|
7
|
+
import { sql as sql$1, isSqlFragment } from './chunk-7QFRK6PU.js';
|
|
8
|
+
import { ConfigurationError, BackendDisposedError } from './chunk-YDEJQWOL.js';
|
|
10
9
|
import { requireDefined } from './chunk-DYATYRY4.js';
|
|
11
10
|
import { getTableName, sql, eq, and, isNull, inArray } from 'drizzle-orm';
|
|
12
11
|
import { BaseSQLiteDatabase } from 'drizzle-orm/sqlite-core';
|
|
@@ -295,6 +294,11 @@ var IDENTITY_TABLE_LOGICAL_NAMES = /* @__PURE__ */ new Set([
|
|
|
295
294
|
"identityClosure",
|
|
296
295
|
"identitySeparation"
|
|
297
296
|
]);
|
|
297
|
+
var RECORDED_TABLE_LOGICAL_NAMES = /* @__PURE__ */ new Set([
|
|
298
|
+
"recordedNodes",
|
|
299
|
+
"recordedEdges",
|
|
300
|
+
"recordedClock"
|
|
301
|
+
]);
|
|
298
302
|
function computeSqliteBatchChunkSizes(maxBindParameters) {
|
|
299
303
|
return {
|
|
300
304
|
checkUniqueBatchChunkSize: Math.max(
|
|
@@ -890,18 +894,20 @@ function createSqliteBackend(db, options = {}) {
|
|
|
890
894
|
capabilityOverrides.graphAnalytics
|
|
891
895
|
)
|
|
892
896
|
});
|
|
893
|
-
const capabilities =
|
|
894
|
-
|
|
895
|
-
|
|
896
|
-
|
|
897
|
-
|
|
898
|
-
|
|
899
|
-
|
|
900
|
-
|
|
901
|
-
|
|
902
|
-
|
|
897
|
+
const capabilities = assertBundledCapabilityDeclarations(
|
|
898
|
+
{
|
|
899
|
+
...declaredCapabilities,
|
|
900
|
+
contributions: {
|
|
901
|
+
supported: true,
|
|
902
|
+
probe: true,
|
|
903
|
+
rebuild: contributionRebuildSupported(
|
|
904
|
+
fulltextStrategy,
|
|
905
|
+
tables2$1.fulltextTableName,
|
|
906
|
+
declaredCapabilities.transactions
|
|
907
|
+
)
|
|
908
|
+
}
|
|
903
909
|
}
|
|
904
|
-
|
|
910
|
+
);
|
|
905
911
|
const tableNames = {
|
|
906
912
|
nodes: getTableName(tables2$1.nodes),
|
|
907
913
|
edges: getTableName(tables2$1.edges),
|
|
@@ -914,7 +920,8 @@ function createSqliteBackend(db, options = {}) {
|
|
|
914
920
|
identityClosure: getTableName(tables2$1.identityClosure),
|
|
915
921
|
identitySeparation: getTableName(tables2$1.identitySeparation),
|
|
916
922
|
fulltext: tables2$1.fulltextTableName,
|
|
917
|
-
uniques: getTableName(tables2$1.uniques)
|
|
923
|
+
uniques: getTableName(tables2$1.uniques),
|
|
924
|
+
edgeClaims: getTableName(tables2$1.edgeClaims)
|
|
918
925
|
};
|
|
919
926
|
const coreAnalyzeTables = [
|
|
920
927
|
tableNames.nodes,
|
|
@@ -1011,8 +1018,19 @@ function createSqliteBackend(db, options = {}) {
|
|
|
1011
1018
|
(contribution) => IDENTITY_TABLE_LOGICAL_NAMES.has(contribution.logicalName)
|
|
1012
1019
|
);
|
|
1013
1020
|
}
|
|
1021
|
+
function recordedContributionsFor(recordedTableNames) {
|
|
1022
|
+
const recordedTables = createSqliteTables({
|
|
1023
|
+
recordedNodes: recordedTableNames.recordedNodes,
|
|
1024
|
+
recordedEdges: recordedTableNames.recordedEdges,
|
|
1025
|
+
recordedClock: recordedTableNames.recordedClock
|
|
1026
|
+
});
|
|
1027
|
+
return sqliteContributions(recordedTables, fulltextStrategy).filter(
|
|
1028
|
+
(contribution) => RECORDED_TABLE_LOGICAL_NAMES.has(contribution.logicalName)
|
|
1029
|
+
);
|
|
1030
|
+
}
|
|
1014
1031
|
const contributionMaterializer = createContributionMaterializer({
|
|
1015
1032
|
dialect: "sqlite",
|
|
1033
|
+
fenceTarget: markFirstPartyFactory({ dialect: "sqlite", capabilities }),
|
|
1016
1034
|
fulltextStrategy,
|
|
1017
1035
|
fulltextTableName: tables2$1.fulltextTableName,
|
|
1018
1036
|
vectorStrategy,
|
|
@@ -1214,6 +1232,27 @@ function createSqliteBackend(db, options = {}) {
|
|
|
1214
1232
|
(contribution) => [...contribution.createDdl]
|
|
1215
1233
|
);
|
|
1216
1234
|
},
|
|
1235
|
+
recordedTableDdl(recordedTableNames) {
|
|
1236
|
+
const contributions = recordedContributionsFor(recordedTableNames);
|
|
1237
|
+
function ddlFor(logicalName) {
|
|
1238
|
+
const contribution = requireDefined(
|
|
1239
|
+
contributions.find((entry) => entry.logicalName === logicalName),
|
|
1240
|
+
`recordedTableDdl: no contribution for ${logicalName}.`
|
|
1241
|
+
);
|
|
1242
|
+
return {
|
|
1243
|
+
createTable: requireDefined(
|
|
1244
|
+
contribution.createDdl[0],
|
|
1245
|
+
`recordedTableDdl: empty DDL for ${logicalName}.`
|
|
1246
|
+
),
|
|
1247
|
+
indexes: contribution.createDdl.slice(1)
|
|
1248
|
+
};
|
|
1249
|
+
}
|
|
1250
|
+
return {
|
|
1251
|
+
recordedClock: ddlFor("recordedClock"),
|
|
1252
|
+
recordedEdges: ddlFor("recordedEdges"),
|
|
1253
|
+
recordedNodes: ddlFor("recordedNodes")
|
|
1254
|
+
};
|
|
1255
|
+
},
|
|
1217
1256
|
// Every fulltext-touching method asserts the durable marker instead
|
|
1218
1257
|
// of lazily emitting DDL. Steady state performs zero ensure; an
|
|
1219
1258
|
// uninitialized database throws `StoreNotInitializedError` rather
|
|
@@ -1501,6 +1540,7 @@ function createSqliteBackend(db, options = {}) {
|
|
|
1501
1540
|
}
|
|
1502
1541
|
};
|
|
1503
1542
|
auditBackendResource(backend, resourceAudit);
|
|
1543
|
+
markFirstPartyFactory(backend);
|
|
1504
1544
|
return backend;
|
|
1505
1545
|
}
|
|
1506
1546
|
function createTransactionBackend(options) {
|
|
@@ -1521,5 +1561,5 @@ function createTransactionBackend(options) {
|
|
|
1521
1561
|
}
|
|
1522
1562
|
|
|
1523
1563
|
export { createSqliteBackend, isLocalLibsqlClient };
|
|
1524
|
-
//# sourceMappingURL=chunk-
|
|
1525
|
-
//# sourceMappingURL=chunk-
|
|
1564
|
+
//# sourceMappingURL=chunk-NBOS7BY3.js.map
|
|
1565
|
+
//# sourceMappingURL=chunk-NBOS7BY3.js.map
|