@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
|
@@ -1,19 +1,19 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
import { deriveBackend } from './chunk-
|
|
6
|
-
import {
|
|
7
|
-
import { rowPropsToObject, isLiveNodeRow } from './chunk-
|
|
8
|
-
import {
|
|
9
|
-
import { validateOptionalCanonicalIsoDate, nowIso, resolveStampedValidityLowerBound, assertOrderedValidityWindow, preservesImmutableLowerBound, assertWritableValidityWindow } from './chunk-
|
|
10
|
-
import { getDialect, compileNodeIndexFieldKeys, compileIndexWhere } from './chunk-
|
|
11
|
-
import { sql, asCompiledRowsSql } from './chunk-
|
|
1
|
+
import { nodeClaimSites, nodeClaimEntries, getEmbeddingFields, createNodeWriteContext, applyNodeSetUpdate, applyNodeResurrect, applyNodeHardDelete, applyNodeSoftDelete, applyNodeUpdate, withNodeCreateClaimsBatch, applyNodeInsertSyncFansBatch, withNodeCreateClaims, applyNodeInsertSyncFans, checkUniquenessConstraints, createUniquenessContext } from './chunk-4DKY6RIU.js';
|
|
2
|
+
import { EDGE_CARDINALITY_SPECS, claimEdgeCardinalityBatch, claimEdgeCardinality, purgeEdgeClaims } from './chunk-NGQDGL5X.js';
|
|
3
|
+
import { refKey } from './chunk-WFSYYU4W.js';
|
|
4
|
+
import { runInWriteTransaction, runHookedWriteOperation, validateNodeProps, getNodeRowsByIds, generateId, nodeInsertDispatch, edgeInsertDispatch, runInsertBatch, runInsertBatchReturning, runInsertNoReturn } from './chunk-VAAC7L57.js';
|
|
5
|
+
import { deriveBackend, canonicalEqual } from './chunk-QG5VEOKX.js';
|
|
6
|
+
import { missingRequiredExtras } from './chunk-XORONCV3.js';
|
|
7
|
+
import { rowPropsToObject, bindExtraIfReachable, BATCH_POINT_READ, UNIQUE_SIDECAR_BATCH, createSqlSchema, DEFAULT_SQL_SCHEMA, isLiveNodeRow } from './chunk-LKZDQ2B4.js';
|
|
8
|
+
import { checkDisjointness, checkUniqueEdge, checkCardinality, uniquenessProbeKinds, encodeTupleKey, checkWherePredicate, computeUniqueKey } from './chunk-RVUL2HXY.js';
|
|
9
|
+
import { assertsStoredLowerBound, assertsStoredUpperBound, validateOptionalCanonicalIsoDate, nowIso, resolveStampedValidityLowerBound, assertOrderedValidityWindow, preservesImmutableLowerBound, assertWritableValidityWindow } from './chunk-K46SDNQD.js';
|
|
10
|
+
import { getDialect, compileNodeIndexFieldKeys, compileIndexWhere } from './chunk-7G5IYROL.js';
|
|
11
|
+
import { sql, asCompiledRowsSql } from './chunk-7QFRK6PU.js';
|
|
12
12
|
import { getSearchableFields } from './chunk-PC2UBAUB.js';
|
|
13
|
-
import { filterReservedKeys, RESERVED_NODE_KEYS, RESERVED_EDGE_KEYS, assertJsonValue } from './chunk-
|
|
14
|
-
import { ValidationError, ConfigurationError, DatabaseOperationError, UniquenessError,
|
|
13
|
+
import { filterReservedKeys, RESERVED_NODE_KEYS, RESERVED_EDGE_KEYS, assertJsonValue } from './chunk-FZHF5UWR.js';
|
|
14
|
+
import { ValidationError, ConfigurationError, DatabaseOperationError, UniquenessError, KindNotFoundError, NodeConstraintNotFoundError, NodeIndexNotFoundError, ENTITY_ALREADY_EXISTS_CODE, NodeNotFoundError } from './chunk-YDEJQWOL.js';
|
|
15
15
|
import { resolveJsonPointer } from './chunk-FWJKWH6U.js';
|
|
16
|
-
import {
|
|
16
|
+
import { createDataKeyedBag, requireDefined, hasOwnKey } from './chunk-DYATYRY4.js';
|
|
17
17
|
|
|
18
18
|
// src/store/row-mappers.ts
|
|
19
19
|
function nullToUndefined(value) {
|
|
@@ -68,13 +68,29 @@ function edgeWriteNeedsConstraintFence(cardinality) {
|
|
|
68
68
|
return cardinality === "many" ? void 0 : "edgeCardinality";
|
|
69
69
|
}
|
|
70
70
|
function nodeWriteNeedsConstraintFence(registry, kind, uniqueConstraints, operation) {
|
|
71
|
-
|
|
72
|
-
|
|
71
|
+
return nodeClaimSites(registry, kind, uniqueConstraints, operation).find(
|
|
72
|
+
(site) => site.needsLockFence
|
|
73
|
+
)?.refusalReason;
|
|
74
|
+
}
|
|
75
|
+
function graphOwesClaims(graph, registry) {
|
|
76
|
+
for (const [kind, registration] of Object.entries(graph.nodes)) {
|
|
77
|
+
for (const operation of ["create", "update"]) {
|
|
78
|
+
const gating = nodeClaimSites(
|
|
79
|
+
registry,
|
|
80
|
+
kind,
|
|
81
|
+
registration.unique ?? [],
|
|
82
|
+
operation
|
|
83
|
+
).find((site) => site.placement === "pre-insert");
|
|
84
|
+
if (gating !== void 0) return gating.refusalReason;
|
|
85
|
+
}
|
|
73
86
|
}
|
|
74
|
-
const
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
87
|
+
for (const registration of Object.values(graph.edges)) {
|
|
88
|
+
const reason = edgeWriteNeedsConstraintFence(
|
|
89
|
+
registration.cardinality ?? "many"
|
|
90
|
+
);
|
|
91
|
+
if (reason !== void 0) return reason;
|
|
92
|
+
}
|
|
93
|
+
return void 0;
|
|
78
94
|
}
|
|
79
95
|
async function checkDisjointnessConstraint(ctx, kind, id) {
|
|
80
96
|
const disjointKinds = ctx.registry.getDisjointKinds(kind);
|
|
@@ -87,71 +103,455 @@ async function checkDisjointnessConstraint(ctx, kind, id) {
|
|
|
87
103
|
}
|
|
88
104
|
}
|
|
89
105
|
async function checkCardinalityConstraint(ctx, edgeKind, cardinality, fromKind, fromId, toKind, toId, validTo) {
|
|
90
|
-
|
|
91
|
-
|
|
106
|
+
if (cardinality === "many") return;
|
|
107
|
+
const spec = EDGE_CARDINALITY_SPECS[cardinality];
|
|
108
|
+
if (!spec.claimsWhenBornEnded && validTo !== void 0) return;
|
|
109
|
+
if (spec.keyShape === "fromAndTo") {
|
|
110
|
+
const exists = await ctx.backend.edgeExistsBetween({
|
|
111
|
+
graphId: ctx.graphId,
|
|
112
|
+
edgeKind,
|
|
113
|
+
fromKind,
|
|
114
|
+
fromId,
|
|
115
|
+
toKind,
|
|
116
|
+
toId
|
|
117
|
+
});
|
|
118
|
+
const error2 = checkUniqueEdge(
|
|
119
|
+
edgeKind,
|
|
120
|
+
fromKind,
|
|
121
|
+
fromId,
|
|
122
|
+
toKind,
|
|
123
|
+
toId,
|
|
124
|
+
exists ? 1 : 0
|
|
125
|
+
);
|
|
126
|
+
if (error2) throw error2;
|
|
127
|
+
return;
|
|
128
|
+
}
|
|
129
|
+
const count = await ctx.backend.countEdgesFrom({
|
|
130
|
+
graphId: ctx.graphId,
|
|
131
|
+
edgeKind,
|
|
132
|
+
fromKind,
|
|
133
|
+
fromId,
|
|
134
|
+
activeOnly: spec.holderLiveness === "liveAndActive"
|
|
135
|
+
});
|
|
136
|
+
const error = checkCardinality(
|
|
137
|
+
edgeKind,
|
|
138
|
+
fromKind,
|
|
139
|
+
fromId,
|
|
140
|
+
cardinality,
|
|
141
|
+
count,
|
|
142
|
+
count > 0
|
|
143
|
+
);
|
|
144
|
+
if (error) throw error;
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
// src/store/operations/edge-batch-validation.ts
|
|
148
|
+
function buildEdgeEndpointCacheKey(graphId, kind, id) {
|
|
149
|
+
return encodeTupleKey([graphId, kind, id]);
|
|
150
|
+
}
|
|
151
|
+
function buildEdgeFromCacheKey(graphId, edgeKind, fromKind, fromId) {
|
|
152
|
+
return encodeTupleKey([graphId, edgeKind, fromKind, fromId]);
|
|
153
|
+
}
|
|
154
|
+
function buildEdgeBetweenCacheKey(graphId, edgeKind, fromKind, fromId, toKind, toId) {
|
|
155
|
+
return encodeTupleKey([graphId, edgeKind, fromKind, fromId, toKind, toId]);
|
|
156
|
+
}
|
|
157
|
+
function buildCountEdgesFromCacheKey(params) {
|
|
158
|
+
const activeOnly = params.activeOnly === true ? "1" : "0";
|
|
159
|
+
return encodeTupleKey([
|
|
160
|
+
params.graphId,
|
|
161
|
+
params.edgeKind,
|
|
162
|
+
params.fromKind,
|
|
163
|
+
params.fromId,
|
|
164
|
+
activeOnly
|
|
165
|
+
]);
|
|
166
|
+
}
|
|
167
|
+
function incrementPendingCount(counts, key) {
|
|
168
|
+
const previous = counts.get(key) ?? 0;
|
|
169
|
+
counts.set(key, previous + 1);
|
|
170
|
+
}
|
|
171
|
+
function createEdgeBatchValidationBackend(backend) {
|
|
172
|
+
const endpointCache = /* @__PURE__ */ new Map();
|
|
173
|
+
const countEdgesFromCache = /* @__PURE__ */ new Map();
|
|
174
|
+
const edgeExistsCache = /* @__PURE__ */ new Map();
|
|
175
|
+
const pendingOneCounts = /* @__PURE__ */ new Map();
|
|
176
|
+
const pendingOneActiveCounts = /* @__PURE__ */ new Map();
|
|
177
|
+
const pendingUniquePairs = /* @__PURE__ */ new Set();
|
|
178
|
+
async function getNodeCached(graphId, kind, id) {
|
|
179
|
+
const cacheKey = buildEdgeEndpointCacheKey(graphId, kind, id);
|
|
180
|
+
if (endpointCache.has(cacheKey)) {
|
|
181
|
+
return endpointCache.get(cacheKey);
|
|
182
|
+
}
|
|
183
|
+
const node = await backend.getNode(graphId, kind, id);
|
|
184
|
+
endpointCache.set(cacheKey, node);
|
|
185
|
+
return node;
|
|
186
|
+
}
|
|
187
|
+
function seedEndpointRow(graphId, kind, id, row) {
|
|
188
|
+
const cacheKey = buildEdgeEndpointCacheKey(graphId, kind, id);
|
|
189
|
+
if (endpointCache.has(cacheKey)) return;
|
|
190
|
+
endpointCache.set(cacheKey, row);
|
|
191
|
+
}
|
|
192
|
+
async function countEdgesFromCached(params) {
|
|
193
|
+
const cacheKey = buildCountEdgesFromCacheKey(params);
|
|
194
|
+
let baseCount = countEdgesFromCache.get(cacheKey);
|
|
195
|
+
if (baseCount === void 0) {
|
|
196
|
+
baseCount = await backend.countEdgesFrom(params);
|
|
197
|
+
countEdgesFromCache.set(cacheKey, baseCount);
|
|
198
|
+
}
|
|
199
|
+
const pendingKey = buildEdgeFromCacheKey(
|
|
200
|
+
params.graphId,
|
|
201
|
+
params.edgeKind,
|
|
202
|
+
params.fromKind,
|
|
203
|
+
params.fromId
|
|
204
|
+
);
|
|
205
|
+
const pendingCount = params.activeOnly === true ? pendingOneActiveCounts.get(pendingKey) ?? 0 : pendingOneCounts.get(pendingKey) ?? 0;
|
|
206
|
+
return baseCount + pendingCount;
|
|
207
|
+
}
|
|
208
|
+
async function edgeExistsBetweenCached(params) {
|
|
209
|
+
const cacheKey = buildEdgeBetweenCacheKey(
|
|
210
|
+
params.graphId,
|
|
211
|
+
params.edgeKind,
|
|
212
|
+
params.fromKind,
|
|
213
|
+
params.fromId,
|
|
214
|
+
params.toKind,
|
|
215
|
+
params.toId
|
|
216
|
+
);
|
|
217
|
+
if (pendingUniquePairs.has(cacheKey)) {
|
|
218
|
+
return true;
|
|
219
|
+
}
|
|
220
|
+
if (edgeExistsCache.has(cacheKey)) {
|
|
221
|
+
return edgeExistsCache.get(cacheKey) ?? false;
|
|
222
|
+
}
|
|
223
|
+
const exists = await backend.edgeExistsBetween(params);
|
|
224
|
+
edgeExistsCache.set(cacheKey, exists);
|
|
225
|
+
return exists;
|
|
226
|
+
}
|
|
227
|
+
function registerPendingEdgeForCardinality(insertParams, cardinality) {
|
|
228
|
+
const fromCacheKey = buildEdgeFromCacheKey(
|
|
229
|
+
insertParams.graphId,
|
|
230
|
+
insertParams.kind,
|
|
231
|
+
insertParams.fromKind,
|
|
232
|
+
insertParams.fromId
|
|
233
|
+
);
|
|
234
|
+
if (cardinality === "one") {
|
|
235
|
+
incrementPendingCount(pendingOneCounts, fromCacheKey);
|
|
92
236
|
return;
|
|
93
237
|
}
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
fromKind,
|
|
99
|
-
fromId
|
|
100
|
-
});
|
|
101
|
-
const error = checkCardinality(
|
|
102
|
-
edgeKind,
|
|
103
|
-
fromKind,
|
|
104
|
-
fromId,
|
|
105
|
-
"one",
|
|
106
|
-
count,
|
|
107
|
-
false
|
|
108
|
-
);
|
|
109
|
-
if (error) throw error;
|
|
238
|
+
if (cardinality === "oneActive") {
|
|
239
|
+
if (insertParams.validTo === void 0) {
|
|
240
|
+
incrementPendingCount(pendingOneActiveCounts, fromCacheKey);
|
|
241
|
+
}
|
|
110
242
|
return;
|
|
111
243
|
}
|
|
112
|
-
|
|
113
|
-
const
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
fromKind,
|
|
117
|
-
fromId,
|
|
118
|
-
toKind,
|
|
119
|
-
toId
|
|
120
|
-
});
|
|
121
|
-
const error = checkUniqueEdge(
|
|
122
|
-
edgeKind,
|
|
123
|
-
fromKind,
|
|
124
|
-
fromId,
|
|
125
|
-
toKind,
|
|
126
|
-
toId,
|
|
127
|
-
exists ? 1 : 0
|
|
244
|
+
if (cardinality === "unique") {
|
|
245
|
+
const uniqueCacheKey = buildEdgeBetweenCacheKey(
|
|
246
|
+
insertParams.graphId,
|
|
247
|
+
insertParams.kind,
|
|
248
|
+
insertParams.fromKind,
|
|
249
|
+
insertParams.fromId,
|
|
250
|
+
insertParams.toKind,
|
|
251
|
+
insertParams.toId
|
|
128
252
|
);
|
|
129
|
-
|
|
130
|
-
return;
|
|
253
|
+
pendingUniquePairs.add(uniqueCacheKey);
|
|
131
254
|
}
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
255
|
+
}
|
|
256
|
+
const validationBackend = deriveBackend(backend, {
|
|
257
|
+
getNode: getNodeCached,
|
|
258
|
+
countEdgesFrom: countEdgesFromCached,
|
|
259
|
+
edgeExistsBetween: edgeExistsBetweenCached
|
|
260
|
+
});
|
|
261
|
+
return {
|
|
262
|
+
backend: validationBackend,
|
|
263
|
+
registerPendingEdgeForCardinality,
|
|
264
|
+
seedEndpointRow
|
|
265
|
+
};
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
// src/store/operations/edge-write-pipeline.ts
|
|
269
|
+
function createEdgeWriteContext(graphId, lock, claimsVerdict) {
|
|
270
|
+
return { graphId, lock, claimsVerdict };
|
|
271
|
+
}
|
|
272
|
+
async function applyEdgeUpdate(ctx, args, backend) {
|
|
273
|
+
const { claim, ...rowWork } = args;
|
|
274
|
+
if (claim !== void 0) {
|
|
275
|
+
await claimEdgeCardinality(backend, ctx.claimsVerdict(), claim);
|
|
276
|
+
}
|
|
277
|
+
const updateParams = { graphId: ctx.graphId, ...rowWork };
|
|
278
|
+
return backend.updateEdge(updateParams);
|
|
279
|
+
}
|
|
280
|
+
function applyEdgeSoftDelete(ctx, work, backend) {
|
|
281
|
+
return backend.deleteEdge({
|
|
282
|
+
graphId: ctx.graphId,
|
|
283
|
+
id: work.id,
|
|
284
|
+
kind: work.kind
|
|
285
|
+
});
|
|
286
|
+
}
|
|
287
|
+
async function applyEdgeHardDelete(ctx, work, backend) {
|
|
288
|
+
await backend.hardDeleteEdge({
|
|
289
|
+
graphId: ctx.graphId,
|
|
290
|
+
id: work.id,
|
|
291
|
+
kind: work.kind
|
|
292
|
+
});
|
|
293
|
+
if (work.holdsCardinalityClaim) {
|
|
294
|
+
await purgeEdgeClaims(backend, ctx.claimsVerdict(), ctx.graphId, [work.id]);
|
|
295
|
+
}
|
|
296
|
+
}
|
|
297
|
+
|
|
298
|
+
// src/store/operations/write-fences.ts
|
|
299
|
+
function createWriteParamsDraft() {
|
|
300
|
+
return {};
|
|
301
|
+
}
|
|
302
|
+
function assertsStoredWindowState(fences) {
|
|
303
|
+
return assertsStoredLowerBound(fences.validityLowerBound) || assertsStoredUpperBound(fences.validityUpperBound);
|
|
304
|
+
}
|
|
305
|
+
var UnsupportedWriteFenceError = class extends Error {
|
|
306
|
+
fence;
|
|
307
|
+
kind;
|
|
308
|
+
constructor(fence, kind) {
|
|
309
|
+
super(
|
|
310
|
+
`The ${kind} statement cannot carry the "${fence}" fence, so the write is refused rather than run unfenced. Assert nothing ({}) or use a write shape whose statement carries it.`
|
|
311
|
+
);
|
|
312
|
+
this.name = "UnsupportedWriteFenceError";
|
|
313
|
+
this.fence = fence;
|
|
314
|
+
this.kind = kind;
|
|
315
|
+
}
|
|
316
|
+
};
|
|
317
|
+
function applyValidityLowerBound(fence, draft) {
|
|
318
|
+
if (!assertsStoredLowerBound(fence)) return;
|
|
319
|
+
draft.expectedValidFrom = fence.expectedValidFrom;
|
|
320
|
+
}
|
|
321
|
+
var NODE_UPDATE_FENCE_APPLIERS = {
|
|
322
|
+
validityLowerBound: applyValidityLowerBound
|
|
323
|
+
};
|
|
324
|
+
var NODE_SET_UPDATE_FENCE_APPLIERS = {
|
|
325
|
+
validityLowerBound: (fence) => {
|
|
326
|
+
if (!assertsStoredLowerBound(fence)) return;
|
|
327
|
+
throw new UnsupportedWriteFenceError("validityLowerBound", "nodeSetUpdate");
|
|
328
|
+
}
|
|
329
|
+
};
|
|
330
|
+
function applyEdgeIdentity(fence, draft) {
|
|
331
|
+
draft.kind = fence.kind;
|
|
332
|
+
if (fence.fromKind !== void 0) draft.fromKind = fence.fromKind;
|
|
333
|
+
if (fence.fromId !== void 0) draft.fromId = fence.fromId;
|
|
334
|
+
if (fence.toKind !== void 0) draft.toKind = fence.toKind;
|
|
335
|
+
if (fence.toId !== void 0) draft.toId = fence.toId;
|
|
336
|
+
}
|
|
337
|
+
function applyValidityUpperBound(fence, draft) {
|
|
338
|
+
if (!assertsStoredUpperBound(fence)) return;
|
|
339
|
+
draft.expectedValidTo = fence.expectedValidTo;
|
|
340
|
+
}
|
|
341
|
+
var EDGE_UPDATE_FENCE_APPLIERS = {
|
|
342
|
+
validityLowerBound: applyValidityLowerBound,
|
|
343
|
+
validityUpperBound: applyValidityUpperBound,
|
|
344
|
+
edgeIdentity: applyEdgeIdentity
|
|
345
|
+
};
|
|
346
|
+
function applyWriteFences(appliers, fences, draft) {
|
|
347
|
+
for (const key of Object.keys(appliers)) {
|
|
348
|
+
const applier = appliers[key];
|
|
349
|
+
applier(fences[key], draft);
|
|
350
|
+
}
|
|
351
|
+
}
|
|
352
|
+
|
|
353
|
+
// src/store/operations/write-session.ts
|
|
354
|
+
function unfencedTarget(target) {
|
|
355
|
+
return target;
|
|
356
|
+
}
|
|
357
|
+
function edgeBatchClaims(work) {
|
|
358
|
+
return work.flatMap((item) => item.claim === void 0 ? [] : [item.claim]);
|
|
359
|
+
}
|
|
360
|
+
function createWriteSession(ctx, target, lock) {
|
|
361
|
+
const writeContext = createNodeWriteContext(
|
|
362
|
+
ctx.graphId,
|
|
363
|
+
ctx.registry,
|
|
364
|
+
lock,
|
|
365
|
+
ctx.claimsVerdict,
|
|
366
|
+
ctx.uniqueSidecarBatch
|
|
367
|
+
);
|
|
368
|
+
const dispatch = nodeInsertDispatch(target);
|
|
369
|
+
const edgeContext = createEdgeWriteContext(
|
|
370
|
+
ctx.graphId,
|
|
371
|
+
lock,
|
|
372
|
+
ctx.claimsVerdict
|
|
373
|
+
);
|
|
374
|
+
const edgeDispatch = edgeInsertDispatch(target);
|
|
375
|
+
return {
|
|
376
|
+
// The pinned coordination order, spelled once per insert shape:
|
|
377
|
+
// pre-insert claims, the row, post-insert claims, the sync fans. The claim
|
|
378
|
+
// seam owns the two groups and the compensation between them; this surface
|
|
379
|
+
// owns only "the row write it gates is THIS one".
|
|
380
|
+
createNode: async (work) => {
|
|
381
|
+
const row = await withNodeCreateClaims(
|
|
382
|
+
writeContext,
|
|
383
|
+
work.claim,
|
|
384
|
+
target,
|
|
385
|
+
() => dispatch.one(work.params)
|
|
386
|
+
);
|
|
387
|
+
await applyNodeInsertSyncFans(writeContext, work.sideEffects, target);
|
|
388
|
+
return row;
|
|
389
|
+
},
|
|
390
|
+
createNodeNoReturn: async (work) => {
|
|
391
|
+
await withNodeCreateClaims(
|
|
392
|
+
writeContext,
|
|
393
|
+
work.claim,
|
|
394
|
+
target,
|
|
395
|
+
() => runInsertNoReturn(dispatch, work.params)
|
|
396
|
+
);
|
|
397
|
+
await applyNodeInsertSyncFans(writeContext, work.sideEffects, target);
|
|
398
|
+
},
|
|
399
|
+
createNodes: async (work) => {
|
|
400
|
+
const rows = await withNodeCreateClaimsBatch(
|
|
401
|
+
writeContext,
|
|
402
|
+
work.map((item) => item.claim),
|
|
403
|
+
target,
|
|
404
|
+
() => runInsertBatchReturning(
|
|
405
|
+
dispatch,
|
|
406
|
+
work.map((item) => item.params)
|
|
407
|
+
)
|
|
408
|
+
);
|
|
409
|
+
await applyNodeInsertSyncFansBatch(
|
|
410
|
+
writeContext,
|
|
411
|
+
work.map((item) => item.sideEffects),
|
|
412
|
+
target
|
|
413
|
+
);
|
|
414
|
+
return rows;
|
|
415
|
+
},
|
|
416
|
+
createNodesNoReturn: async (work) => {
|
|
417
|
+
await withNodeCreateClaimsBatch(
|
|
418
|
+
writeContext,
|
|
419
|
+
work.map((item) => item.claim),
|
|
420
|
+
target,
|
|
421
|
+
() => runInsertBatch(
|
|
422
|
+
dispatch,
|
|
423
|
+
work.map((item) => item.params)
|
|
424
|
+
)
|
|
425
|
+
);
|
|
426
|
+
await applyNodeInsertSyncFansBatch(
|
|
427
|
+
writeContext,
|
|
428
|
+
work.map((item) => item.sideEffects),
|
|
429
|
+
target
|
|
430
|
+
);
|
|
431
|
+
},
|
|
432
|
+
reviseNode: (work, fences) => {
|
|
433
|
+
const draft = createWriteParamsDraft();
|
|
434
|
+
applyWriteFences(NODE_UPDATE_FENCE_APPLIERS, fences, draft);
|
|
435
|
+
return applyNodeUpdate(writeContext, { ...work, ...draft }, target);
|
|
436
|
+
},
|
|
437
|
+
retireNode: (work, policy) => applyNodeSoftDelete(writeContext, work, target, policy),
|
|
438
|
+
purgeNode: (work) => applyNodeHardDelete(writeContext, work, target),
|
|
439
|
+
reviveNode: (work) => applyNodeResurrect(writeContext, work, target),
|
|
440
|
+
reviseNodeSet: (work, fences) => {
|
|
441
|
+
applyWriteFences(
|
|
442
|
+
NODE_SET_UPDATE_FENCE_APPLIERS,
|
|
443
|
+
fences,
|
|
444
|
+
createWriteParamsDraft()
|
|
445
|
+
);
|
|
446
|
+
return applyNodeSetUpdate(writeContext, work, target);
|
|
447
|
+
},
|
|
448
|
+
// An edge write obliges no DERIVED data, so these apply no sync fans — but a
|
|
449
|
+
// constrained kind owes its cardinality claim, at the same PRE-INSERT
|
|
450
|
+
// placement a node's scope-spanning claim takes and for the same reason: the
|
|
451
|
+
// probe that authorised the insert read a population no key fences. The
|
|
452
|
+
// batch issues ONE sorted statement (`claimEdgeCardinalityBatch` orders by
|
|
453
|
+
// `compareClaimTargets`), so a batch and a peer batch take their row locks
|
|
454
|
+
// in the same order.
|
|
455
|
+
createEdge: async (work) => {
|
|
456
|
+
if (work.claim !== void 0) {
|
|
457
|
+
await claimEdgeCardinality(target, ctx.claimsVerdict(), work.claim);
|
|
135
458
|
}
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
count > 0
|
|
459
|
+
return edgeDispatch.one(work.params);
|
|
460
|
+
},
|
|
461
|
+
createEdgeNoReturn: async (work) => {
|
|
462
|
+
if (work.claim !== void 0) {
|
|
463
|
+
await claimEdgeCardinality(target, ctx.claimsVerdict(), work.claim);
|
|
464
|
+
}
|
|
465
|
+
await runInsertNoReturn(edgeDispatch, work.params);
|
|
466
|
+
},
|
|
467
|
+
createEdges: async (work) => {
|
|
468
|
+
await claimEdgeCardinalityBatch(
|
|
469
|
+
target,
|
|
470
|
+
ctx.claimsVerdict(),
|
|
471
|
+
edgeBatchClaims(work)
|
|
150
472
|
);
|
|
151
|
-
|
|
152
|
-
|
|
473
|
+
return runInsertBatchReturning(
|
|
474
|
+
edgeDispatch,
|
|
475
|
+
work.map((item) => item.params)
|
|
476
|
+
);
|
|
477
|
+
},
|
|
478
|
+
createEdgesNoReturn: async (work) => {
|
|
479
|
+
await claimEdgeCardinalityBatch(
|
|
480
|
+
target,
|
|
481
|
+
ctx.claimsVerdict(),
|
|
482
|
+
edgeBatchClaims(work)
|
|
483
|
+
);
|
|
484
|
+
await runInsertBatch(
|
|
485
|
+
edgeDispatch,
|
|
486
|
+
work.map((item) => item.params)
|
|
487
|
+
);
|
|
488
|
+
},
|
|
489
|
+
reviseEdge: (work, fences) => {
|
|
490
|
+
const draft = createWriteParamsDraft();
|
|
491
|
+
applyWriteFences(EDGE_UPDATE_FENCE_APPLIERS, fences, draft);
|
|
492
|
+
return applyEdgeUpdate(edgeContext, { ...work, ...draft }, target);
|
|
493
|
+
},
|
|
494
|
+
retireEdge: (work) => applyEdgeSoftDelete(edgeContext, work, target),
|
|
495
|
+
purgeEdge: (work) => applyEdgeHardDelete(edgeContext, work, target)
|
|
496
|
+
};
|
|
497
|
+
}
|
|
498
|
+
|
|
499
|
+
// src/store/operations/write-executor.ts
|
|
500
|
+
function planFrame(ctx, plan, rowWork) {
|
|
501
|
+
return async (target, lock) => {
|
|
502
|
+
if (plan.requiresIdentityLock) {
|
|
503
|
+
const acquireIdentityLock = requireDefined(
|
|
504
|
+
ctx.identityLock,
|
|
505
|
+
"write plan declares identity participation with no acquirer"
|
|
506
|
+
);
|
|
507
|
+
await acquireIdentityLock(target);
|
|
153
508
|
}
|
|
154
|
-
|
|
509
|
+
const mintSessionOver = (sessionTarget) => createWriteSession(ctx, sessionTarget, lock);
|
|
510
|
+
const mintOverlaidSession = (reads) => mintSessionOver(deriveBackend(target, reads));
|
|
511
|
+
return rowWork(
|
|
512
|
+
mintSessionOver(target),
|
|
513
|
+
target,
|
|
514
|
+
mintOverlaidSession
|
|
515
|
+
);
|
|
516
|
+
};
|
|
517
|
+
}
|
|
518
|
+
function planTransactionOptions(plan, options) {
|
|
519
|
+
return { ...options, fencesConstraintProbe: plan.constraintProbe };
|
|
520
|
+
}
|
|
521
|
+
function runWritePlan(ctx, plan, backend, rowWork, options) {
|
|
522
|
+
return runInWriteTransaction(
|
|
523
|
+
ctx,
|
|
524
|
+
backend,
|
|
525
|
+
planFrame(ctx, plan, rowWork),
|
|
526
|
+
planTransactionOptions(plan, options)
|
|
527
|
+
);
|
|
528
|
+
}
|
|
529
|
+
function runHookedWritePlan(ctx, opContext, plan, backend, rowWork, options) {
|
|
530
|
+
return runHookedWriteOperation(
|
|
531
|
+
ctx,
|
|
532
|
+
opContext,
|
|
533
|
+
backend,
|
|
534
|
+
planFrame(ctx, plan, rowWork),
|
|
535
|
+
planTransactionOptions(plan, options)
|
|
536
|
+
);
|
|
537
|
+
}
|
|
538
|
+
|
|
539
|
+
// src/store/operations/write-plan.ts
|
|
540
|
+
function nodeWritePlan(constraintProbe, requiresIdentityLock) {
|
|
541
|
+
return { entity: "node", constraintProbe, requiresIdentityLock };
|
|
542
|
+
}
|
|
543
|
+
function nodeBatchWritePlan(constraintProbes, requiresIdentityLock) {
|
|
544
|
+
return {
|
|
545
|
+
entity: "node",
|
|
546
|
+
constraintProbe: constraintProbes.find((probe) => probe !== void 0),
|
|
547
|
+
requiresIdentityLock
|
|
548
|
+
};
|
|
549
|
+
}
|
|
550
|
+
function edgeWritePlan(constraintProbe) {
|
|
551
|
+
return { entity: "edge", constraintProbe, requiresIdentityLock: false };
|
|
552
|
+
}
|
|
553
|
+
function mixedWritePlan(constraintProbe, requiresIdentityLock) {
|
|
554
|
+
return { entity: "mixed", constraintProbe, requiresIdentityLock };
|
|
155
555
|
}
|
|
156
556
|
|
|
157
557
|
// src/store/validity-end.ts
|
|
@@ -266,12 +666,18 @@ function nodeFencesConstraintProbe(ctx, kind, operation) {
|
|
|
266
666
|
operation
|
|
267
667
|
);
|
|
268
668
|
}
|
|
269
|
-
function
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
669
|
+
function nodeBatchConstraintProbes(ctx, inputs, operation) {
|
|
670
|
+
return inputs.map(
|
|
671
|
+
(input) => nodeFencesConstraintProbe(ctx, input.kind, operation)
|
|
672
|
+
);
|
|
673
|
+
}
|
|
674
|
+
function nodeWritePlanContext(ctx) {
|
|
675
|
+
const identity = ctx.identity;
|
|
676
|
+
if (identity === void 0) return ctx;
|
|
677
|
+
return { ...ctx, identityLock: identity.lock };
|
|
678
|
+
}
|
|
679
|
+
function nodeRequiresIdentityLock(ctx) {
|
|
680
|
+
return ctx.identity !== void 0;
|
|
275
681
|
}
|
|
276
682
|
function buildNodeCacheKey(graphId, kind, id) {
|
|
277
683
|
return encodeTupleKey([graphId, kind, id]);
|
|
@@ -290,14 +696,14 @@ function buildInsertNodeParams(graphId, kind, id, props, validFrom, validTo) {
|
|
|
290
696
|
if (validTo !== void 0) insertParams.validTo = validTo;
|
|
291
697
|
return insertParams;
|
|
292
698
|
}
|
|
293
|
-
function createPendingUniqueRow(graphId, nodeKind, constraintName, key,
|
|
699
|
+
function createPendingUniqueRow(graphId, nodeKind, constraintName, key, owner) {
|
|
294
700
|
return {
|
|
295
701
|
graph_id: graphId,
|
|
296
702
|
node_kind: nodeKind,
|
|
297
703
|
constraint_name: constraintName,
|
|
298
704
|
key,
|
|
299
|
-
node_id: nodeId,
|
|
300
|
-
concrete_kind:
|
|
705
|
+
node_id: owner.nodeId,
|
|
706
|
+
concrete_kind: owner.concreteKind,
|
|
301
707
|
deleted_at: void 0
|
|
302
708
|
};
|
|
303
709
|
}
|
|
@@ -312,7 +718,7 @@ function resolveConstraint(graph, kind, constraintName) {
|
|
|
312
718
|
}
|
|
313
719
|
return constraint;
|
|
314
720
|
}
|
|
315
|
-
function
|
|
721
|
+
function createNodeBatchValidationSeams(graphId, registry, backend) {
|
|
316
722
|
const nodeCache = /* @__PURE__ */ new Map();
|
|
317
723
|
const pendingNodes = /* @__PURE__ */ new Map();
|
|
318
724
|
const uniqueCache = /* @__PURE__ */ new Map();
|
|
@@ -368,71 +774,72 @@ function createNodeBatchValidationBackend(graphId, registry, backend) {
|
|
|
368
774
|
});
|
|
369
775
|
}
|
|
370
776
|
function registerPendingUniqueEntries(kind, id, props, constraints) {
|
|
371
|
-
for (const
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
777
|
+
for (const entry of nodeClaimEntries(
|
|
778
|
+
registry,
|
|
779
|
+
kind,
|
|
780
|
+
id,
|
|
781
|
+
props,
|
|
782
|
+
constraints,
|
|
783
|
+
"create"
|
|
784
|
+
)) {
|
|
785
|
+
pendingUniqueOwners.set(
|
|
786
|
+
buildUniqueCacheKey(
|
|
787
|
+
graphId,
|
|
788
|
+
entry.axis,
|
|
789
|
+
entry.constraintName,
|
|
790
|
+
entry.key
|
|
791
|
+
),
|
|
792
|
+
{ concreteKind: kind, nodeId: id }
|
|
383
793
|
);
|
|
384
|
-
pendingUniqueOwners.set(concreteEntryKey, id);
|
|
385
|
-
if (constraint.scope !== "kind") {
|
|
386
|
-
const kindsToCheck = getKindsForUniquenessCheck(
|
|
387
|
-
kind,
|
|
388
|
-
constraint.scope,
|
|
389
|
-
registry
|
|
390
|
-
);
|
|
391
|
-
for (const kindToCheck of kindsToCheck) {
|
|
392
|
-
const inheritedEntryKey = buildUniqueCacheKey(
|
|
393
|
-
graphId,
|
|
394
|
-
kindToCheck,
|
|
395
|
-
constraint.name,
|
|
396
|
-
key
|
|
397
|
-
);
|
|
398
|
-
pendingUniqueOwners.set(inheritedEntryKey, id);
|
|
399
|
-
}
|
|
400
|
-
}
|
|
401
794
|
}
|
|
402
795
|
}
|
|
403
796
|
function registerAppliedNodeUpdate(kind, id, oldProps, newProps, constraints) {
|
|
797
|
+
const owner = { concreteKind: kind, nodeId: id };
|
|
798
|
+
const oldEntries = new Map(
|
|
799
|
+
nodeClaimEntries(registry, kind, id, oldProps, constraints, "update").map(
|
|
800
|
+
(entry) => [entry.constraintName, entry]
|
|
801
|
+
)
|
|
802
|
+
);
|
|
803
|
+
const newEntries = new Map(
|
|
804
|
+
nodeClaimEntries(registry, kind, id, newProps, constraints, "update").map(
|
|
805
|
+
(entry) => [entry.constraintName, entry]
|
|
806
|
+
)
|
|
807
|
+
);
|
|
404
808
|
for (const constraint of constraints) {
|
|
405
|
-
const
|
|
406
|
-
const
|
|
407
|
-
|
|
408
|
-
const
|
|
409
|
-
if (oldKey === newKey) continue;
|
|
410
|
-
const kindsToCheck = getKindsForUniquenessCheck(
|
|
809
|
+
const oldEntry = oldEntries.get(constraint.name);
|
|
810
|
+
const newEntry = newEntries.get(constraint.name);
|
|
811
|
+
if (oldEntry?.key === newEntry?.key) continue;
|
|
812
|
+
const kindsToCheck = uniquenessProbeKinds(
|
|
411
813
|
kind,
|
|
412
814
|
constraint.scope,
|
|
413
815
|
registry
|
|
414
816
|
);
|
|
415
|
-
if (
|
|
817
|
+
if (oldEntry !== void 0) {
|
|
416
818
|
for (const kindToCheck of kindsToCheck) {
|
|
417
819
|
const cacheKey = buildUniqueCacheKey(
|
|
418
820
|
graphId,
|
|
419
821
|
kindToCheck,
|
|
420
822
|
constraint.name,
|
|
421
|
-
|
|
823
|
+
oldEntry.key
|
|
422
824
|
);
|
|
423
825
|
pendingUniqueOwners.delete(cacheKey);
|
|
424
826
|
uniqueCache.set(cacheKey, void 0);
|
|
425
827
|
}
|
|
426
828
|
}
|
|
427
|
-
if (
|
|
829
|
+
if (newEntry !== void 0) {
|
|
428
830
|
for (const kindToCheck of kindsToCheck) {
|
|
429
831
|
const cacheKey = buildUniqueCacheKey(
|
|
430
832
|
graphId,
|
|
431
833
|
kindToCheck,
|
|
432
834
|
constraint.name,
|
|
433
|
-
|
|
835
|
+
newEntry.key
|
|
434
836
|
);
|
|
435
|
-
|
|
837
|
+
if (kindToCheck === newEntry.axis) {
|
|
838
|
+
pendingUniqueOwners.set(cacheKey, owner);
|
|
839
|
+
continue;
|
|
840
|
+
}
|
|
841
|
+
pendingUniqueOwners.delete(cacheKey);
|
|
842
|
+
uniqueCache.set(cacheKey, void 0);
|
|
436
843
|
}
|
|
437
844
|
}
|
|
438
845
|
}
|
|
@@ -447,12 +854,13 @@ function createNodeBatchValidationBackend(graphId, registry, backend) {
|
|
|
447
854
|
if (uniqueCache.has(cacheKey)) return;
|
|
448
855
|
uniqueCache.set(cacheKey, row);
|
|
449
856
|
}
|
|
450
|
-
const
|
|
857
|
+
const reads = {
|
|
451
858
|
getNode: getNodeCached,
|
|
452
859
|
checkUnique: checkUniqueCached
|
|
453
|
-
}
|
|
860
|
+
};
|
|
454
861
|
return {
|
|
455
|
-
|
|
862
|
+
reads,
|
|
863
|
+
reader: deriveBackend(backend, reads),
|
|
456
864
|
registerPendingNode,
|
|
457
865
|
registerPendingUniqueEntries,
|
|
458
866
|
registerAppliedNodeUpdate,
|
|
@@ -498,7 +906,12 @@ async function finishNodeCreatePreparation(ctx, draft, backend) {
|
|
|
498
906
|
};
|
|
499
907
|
await checkDisjointnessConstraint(constraintContext, kind, id);
|
|
500
908
|
await checkUniquenessConstraints(
|
|
501
|
-
createUniquenessContext(
|
|
909
|
+
createUniquenessContext(
|
|
910
|
+
ctx.graphId,
|
|
911
|
+
ctx.registry,
|
|
912
|
+
backend,
|
|
913
|
+
ctx.uniqueSidecarBatch
|
|
914
|
+
),
|
|
502
915
|
kind,
|
|
503
916
|
id,
|
|
504
917
|
validatedProps,
|
|
@@ -529,35 +942,33 @@ async function validateAndPrepareNodeCreate(ctx, input, id, backend, options) {
|
|
|
529
942
|
backend
|
|
530
943
|
);
|
|
531
944
|
}
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
945
|
+
function nodeCreateSideEffectItem(prepared) {
|
|
946
|
+
return {
|
|
947
|
+
kind: prepared.kind,
|
|
948
|
+
id: prepared.id,
|
|
949
|
+
schema: prepared.nodeKind.schema,
|
|
950
|
+
props: prepared.validatedProps,
|
|
951
|
+
uniqueConstraints: prepared.uniqueConstraints
|
|
952
|
+
};
|
|
953
|
+
}
|
|
954
|
+
function nodeCreateClaimItem(prepared) {
|
|
955
|
+
return {
|
|
956
|
+
kind: prepared.kind,
|
|
957
|
+
id: prepared.id,
|
|
958
|
+
props: prepared.validatedProps,
|
|
959
|
+
constraints: prepared.uniqueConstraints
|
|
960
|
+
};
|
|
961
|
+
}
|
|
962
|
+
function nodeInsertWork(prepared) {
|
|
963
|
+
return {
|
|
964
|
+
params: prepared.insertParams,
|
|
965
|
+
claim: nodeCreateClaimItem(prepared),
|
|
966
|
+
sideEffects: nodeCreateSideEffectItem(prepared)
|
|
967
|
+
};
|
|
544
968
|
}
|
|
545
969
|
function foldReferences(preparedCreates) {
|
|
546
970
|
return preparedCreates.filter((prepared) => prepared.idProvided).map((prepared) => ({ kind: prepared.kind, id: prepared.id }));
|
|
547
971
|
}
|
|
548
|
-
async function finalizeNodeCreate(ctx, prepared, backend, lock) {
|
|
549
|
-
await applyNodeInsertSideEffects(
|
|
550
|
-
createNodeWriteContext(ctx.graphId, ctx.registry, lock),
|
|
551
|
-
{
|
|
552
|
-
kind: prepared.kind,
|
|
553
|
-
id: prepared.id,
|
|
554
|
-
schema: prepared.nodeKind.schema,
|
|
555
|
-
props: prepared.validatedProps,
|
|
556
|
-
uniqueConstraints: prepared.uniqueConstraints
|
|
557
|
-
},
|
|
558
|
-
backend
|
|
559
|
-
);
|
|
560
|
-
}
|
|
561
972
|
function computeNodeUpdate(ctx, kind, id, existingProps, inputProps) {
|
|
562
973
|
const registration = getNodeRegistration(ctx.graph, kind);
|
|
563
974
|
const validatedProps = validateNodeProps(
|
|
@@ -591,10 +1002,10 @@ function nodeUpsertDirtyCheck(ctx, kind, id, existingProps, inputProps) {
|
|
|
591
1002
|
unchanged: canonicalEqual(validatedProps, existingProps)
|
|
592
1003
|
};
|
|
593
1004
|
}
|
|
594
|
-
async function performNodeUpdate(ctx, input,
|
|
1005
|
+
async function performNodeUpdate(ctx, input, session, target, options) {
|
|
595
1006
|
const { kind, id } = input;
|
|
596
1007
|
assertValidityEndMutation(input, { entityType: "node", kind, id });
|
|
597
|
-
const existing = await
|
|
1008
|
+
const existing = await target.getNode(ctx.graphId, kind, id);
|
|
598
1009
|
if (!existing) throw new NodeNotFoundError(kind, id);
|
|
599
1010
|
const { registration, validatedProps } = resolveNodeUpdateProps(
|
|
600
1011
|
ctx,
|
|
@@ -626,55 +1037,44 @@ async function performNodeUpdate(ctx, input, backend, lock, options) {
|
|
|
626
1037
|
},
|
|
627
1038
|
validTo
|
|
628
1039
|
);
|
|
629
|
-
const writeContext = createNodeWriteContext(ctx.graphId, ctx.registry, lock);
|
|
630
1040
|
const shared = {
|
|
631
1041
|
schema: nodeKind.schema,
|
|
632
1042
|
validatedProps,
|
|
633
1043
|
uniqueConstraints: registration.unique ?? [],
|
|
634
1044
|
...validTo !== void 0 && { validTo },
|
|
635
|
-
...input.clearValidTo === true && { clearValidTo: true }
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
// the verdict consult the effective bound, and WAS that bound the row's
|
|
640
|
-
// stored one — are answered where they are known. A plain
|
|
641
|
-
// `update({ props })` states no window, reads no bound, and stays unfenced:
|
|
642
|
-
// the same rule `UpdateEdgeParams`'s identity components follow, for the
|
|
643
|
-
// same reason. The resurrecting leg is judged against `resurrectionInstant`
|
|
644
|
-
// and so fences on `deleted_at IS NOT NULL` alone, converging through the
|
|
645
|
-
// recovery below.
|
|
646
|
-
...windowVerdict.storedLowerBoundFence
|
|
1045
|
+
...input.clearValidTo === true && { clearValidTo: true }
|
|
1046
|
+
};
|
|
1047
|
+
const fences = {
|
|
1048
|
+
validityLowerBound: windowVerdict.storedLowerBoundFence
|
|
647
1049
|
};
|
|
648
1050
|
if (options?.clearDeleted) {
|
|
649
1051
|
const resurrectionLowerBound = resurrectionInstant === void 0 ? validFrom !== void 0 && { validFrom } : { validFrom: resurrectionBound ?? null };
|
|
650
|
-
const row2 = await
|
|
651
|
-
writeContext,
|
|
1052
|
+
const row2 = await session.reviseNode(
|
|
652
1053
|
{ ...shared, existing, clearDeleted: true, ...resurrectionLowerBound },
|
|
653
|
-
|
|
1054
|
+
fences
|
|
654
1055
|
);
|
|
655
1056
|
return rowToNode(row2);
|
|
656
1057
|
}
|
|
657
1058
|
if (!isLiveNodeRow(existing)) throw new NodeNotFoundError(kind, id);
|
|
658
|
-
const row = await
|
|
659
|
-
writeContext,
|
|
1059
|
+
const row = await session.reviseNode(
|
|
660
1060
|
// An in-place update must not rewrite the stored bound, so it keeps the
|
|
661
1061
|
// conditional spread: `buildUpdateNode` ignores `validFrom` off the
|
|
662
1062
|
// resurrection leg, and stating one here would claim a rewrite that no
|
|
663
1063
|
// statement performs.
|
|
664
1064
|
{ ...shared, existing, ...validFrom !== void 0 && { validFrom } },
|
|
665
|
-
|
|
1065
|
+
fences
|
|
666
1066
|
);
|
|
667
1067
|
return rowToNode(row);
|
|
668
1068
|
}
|
|
669
1069
|
var NODE_UPDATE_ATTEMPTS = 2;
|
|
670
|
-
async function performNodeUpdateWithResurrectionRecovery(ctx, input,
|
|
1070
|
+
async function performNodeUpdateWithResurrectionRecovery(ctx, input, session, target, options) {
|
|
671
1071
|
for (let attempt = 1; attempt <= NODE_UPDATE_ATTEMPTS; attempt += 1) {
|
|
672
1072
|
try {
|
|
673
1073
|
return await performNodeUpdate(
|
|
674
1074
|
ctx,
|
|
675
1075
|
input,
|
|
1076
|
+
session,
|
|
676
1077
|
target,
|
|
677
|
-
lock,
|
|
678
1078
|
attempt === 1 ? options : void 0
|
|
679
1079
|
);
|
|
680
1080
|
} catch (error) {
|
|
@@ -702,7 +1102,12 @@ function nodeUpdateRaceError(input, error) {
|
|
|
702
1102
|
);
|
|
703
1103
|
}
|
|
704
1104
|
async function primeBatchValidationCaches(ctx, drafts, backend, seams) {
|
|
705
|
-
|
|
1105
|
+
const boundGetNodes = bindExtraIfReachable(
|
|
1106
|
+
backend,
|
|
1107
|
+
ctx.batchPointRead.extras.getNodes,
|
|
1108
|
+
BATCH_POINT_READ.id
|
|
1109
|
+
);
|
|
1110
|
+
if (boundGetNodes !== void 0) {
|
|
706
1111
|
const idsByKind = /* @__PURE__ */ new Map();
|
|
707
1112
|
for (const draft of drafts) {
|
|
708
1113
|
const ids = idsByKind.get(draft.kind) ?? /* @__PURE__ */ new Set();
|
|
@@ -711,24 +1116,33 @@ async function primeBatchValidationCaches(ctx, drafts, backend, seams) {
|
|
|
711
1116
|
}
|
|
712
1117
|
for (const [kind, ids] of idsByKind) {
|
|
713
1118
|
const orderedIds = [...ids];
|
|
714
|
-
const rows = await
|
|
1119
|
+
const rows = await boundGetNodes.getNodes(ctx.graphId, kind, orderedIds);
|
|
715
1120
|
const rowsById = new Map(rows.map((row) => [row.id, row]));
|
|
716
1121
|
for (const id of orderedIds) {
|
|
717
1122
|
seams.seedNodeRow(kind, id, rowsById.get(id));
|
|
718
1123
|
}
|
|
719
1124
|
}
|
|
720
1125
|
}
|
|
721
|
-
|
|
1126
|
+
const boundCheckUniqueBatch = bindExtraIfReachable(
|
|
1127
|
+
backend,
|
|
1128
|
+
ctx.uniqueSidecarBatch.extras.checkUniqueBatch,
|
|
1129
|
+
UNIQUE_SIDECAR_BATCH.id
|
|
1130
|
+
);
|
|
1131
|
+
if (boundCheckUniqueBatch !== void 0) {
|
|
722
1132
|
const groups = /* @__PURE__ */ new Map();
|
|
723
1133
|
for (const draft of drafts) {
|
|
724
|
-
for (const
|
|
725
|
-
|
|
726
|
-
|
|
727
|
-
|
|
728
|
-
|
|
729
|
-
|
|
730
|
-
|
|
731
|
-
|
|
1134
|
+
for (const entry of nodeClaimEntries(
|
|
1135
|
+
ctx.registry,
|
|
1136
|
+
draft.kind,
|
|
1137
|
+
draft.id,
|
|
1138
|
+
draft.validatedProps,
|
|
1139
|
+
draft.uniqueConstraints,
|
|
1140
|
+
"create"
|
|
1141
|
+
)) {
|
|
1142
|
+
if (entry.refusal.kind !== "uniqueness") continue;
|
|
1143
|
+
const constraint = entry.refusal.constraint;
|
|
1144
|
+
const key = entry.key;
|
|
1145
|
+
const kindsToCheck = uniquenessProbeKinds(
|
|
732
1146
|
draft.kind,
|
|
733
1147
|
constraint.scope,
|
|
734
1148
|
ctx.registry
|
|
@@ -747,7 +1161,7 @@ async function primeBatchValidationCaches(ctx, drafts, backend, seams) {
|
|
|
747
1161
|
}
|
|
748
1162
|
for (const group of groups.values()) {
|
|
749
1163
|
const orderedKeys = [...group.keys];
|
|
750
|
-
const rows = await
|
|
1164
|
+
const rows = await boundCheckUniqueBatch.checkUniqueBatch({
|
|
751
1165
|
graphId: ctx.graphId,
|
|
752
1166
|
nodeKind: group.nodeKind,
|
|
753
1167
|
constraintName: group.constraintName,
|
|
@@ -767,12 +1181,12 @@ async function primeBatchValidationCaches(ctx, drafts, backend, seams) {
|
|
|
767
1181
|
}
|
|
768
1182
|
async function prepareBatchCreates(ctx, inputs, backend, options) {
|
|
769
1183
|
const {
|
|
770
|
-
|
|
1184
|
+
reader: validationBackend,
|
|
771
1185
|
registerPendingNode,
|
|
772
1186
|
registerPendingUniqueEntries,
|
|
773
1187
|
seedNodeRow,
|
|
774
1188
|
seedUniqueRow
|
|
775
|
-
} =
|
|
1189
|
+
} = createNodeBatchValidationSeams(ctx.graphId, ctx.registry, backend);
|
|
776
1190
|
const drafts = inputs.map(
|
|
777
1191
|
(input) => draftNodeCreate(ctx, input, input.id ?? generateId(), options)
|
|
778
1192
|
);
|
|
@@ -813,7 +1227,7 @@ function partitionCreates(preparedCreates) {
|
|
|
813
1227
|
function isNodeUpdateNoRowError(error) {
|
|
814
1228
|
return error instanceof DatabaseOperationError && error.details.operation === "update" && error.details.entity === "node" && error.details.reason === "no_row_returned";
|
|
815
1229
|
}
|
|
816
|
-
async function resurrectPreparedNode(ctx,
|
|
1230
|
+
async function resurrectPreparedNode(ctx, session, target, prepared) {
|
|
817
1231
|
const current = await target.getNode(ctx.graphId, prepared.kind, prepared.id);
|
|
818
1232
|
if (current === void 0) {
|
|
819
1233
|
throw new DatabaseOperationError(
|
|
@@ -831,8 +1245,7 @@ async function resurrectPreparedNode(ctx, target, lock, prepared) {
|
|
|
831
1245
|
resurrectionInstant
|
|
832
1246
|
);
|
|
833
1247
|
try {
|
|
834
|
-
return await
|
|
835
|
-
createNodeWriteContext(ctx.graphId, ctx.registry, lock),
|
|
1248
|
+
return await session.reviseNode(
|
|
836
1249
|
{
|
|
837
1250
|
existing: current,
|
|
838
1251
|
clearDeleted: true,
|
|
@@ -845,7 +1258,11 @@ async function resurrectPreparedNode(ctx, target, lock, prepared) {
|
|
|
845
1258
|
validFrom: resurrectionBound ?? null,
|
|
846
1259
|
...prepared.insertParams.validTo === void 0 ? {} : { validTo: prepared.insertParams.validTo }
|
|
847
1260
|
},
|
|
848
|
-
|
|
1261
|
+
// This resurrection reads no stored bound: it rewrites the whole window
|
|
1262
|
+
// and is fenced by the UPDATE's own `deleted_at IS NOT NULL` predicate,
|
|
1263
|
+
// so it asserts nothing about `valid_from`. `{}` is how a write states
|
|
1264
|
+
// that, and it is the only way to state it.
|
|
1265
|
+
{ validityLowerBound: {} }
|
|
849
1266
|
);
|
|
850
1267
|
} catch (error) {
|
|
851
1268
|
if (!isNodeUpdateNoRowError(error)) throw error;
|
|
@@ -860,7 +1277,12 @@ async function resurrectPreparedNode(ctx, target, lock, prepared) {
|
|
|
860
1277
|
throw error;
|
|
861
1278
|
}
|
|
862
1279
|
}
|
|
1280
|
+
function prefersClaimRow(incumbent, candidate) {
|
|
1281
|
+
if (incumbent === void 0) return true;
|
|
1282
|
+
return incumbent.deleted_at !== void 0 && candidate.deleted_at === void 0;
|
|
1283
|
+
}
|
|
863
1284
|
async function findUniqueRowAcrossKinds(backend, graphId, constraintName, key, kindsToCheck, includeDeleted) {
|
|
1285
|
+
let preferred;
|
|
864
1286
|
for (const kindToCheck of kindsToCheck) {
|
|
865
1287
|
const row = await backend.checkUnique({
|
|
866
1288
|
graphId,
|
|
@@ -869,16 +1291,27 @@ async function findUniqueRowAcrossKinds(backend, graphId, constraintName, key, k
|
|
|
869
1291
|
key,
|
|
870
1292
|
includeDeleted
|
|
871
1293
|
});
|
|
872
|
-
if (row
|
|
1294
|
+
if (row === void 0) continue;
|
|
1295
|
+
if (!prefersClaimRow(preferred, row)) continue;
|
|
1296
|
+
preferred = row;
|
|
1297
|
+
if (row.deleted_at === void 0) return row;
|
|
873
1298
|
}
|
|
874
|
-
return
|
|
1299
|
+
return preferred;
|
|
875
1300
|
}
|
|
876
|
-
async function batchCheckUniqueAcrossKinds(backend, graphId, constraintName, uniqueKeys, kindsToCheck, includeDeleted) {
|
|
1301
|
+
async function batchCheckUniqueAcrossKinds(backend, uniqueSidecarBatch, graphId, constraintName, uniqueKeys, kindsToCheck, includeDeleted) {
|
|
877
1302
|
const existingByKey = /* @__PURE__ */ new Map();
|
|
1303
|
+
const boundCheckUniqueBatch = bindExtraIfReachable(
|
|
1304
|
+
backend,
|
|
1305
|
+
uniqueSidecarBatch.extras.checkUniqueBatch,
|
|
1306
|
+
UNIQUE_SIDECAR_BATCH.id
|
|
1307
|
+
);
|
|
878
1308
|
for (const kindToCheck of kindsToCheck) {
|
|
879
|
-
if (
|
|
1309
|
+
if (boundCheckUniqueBatch === void 0) {
|
|
880
1310
|
for (const key of uniqueKeys) {
|
|
881
|
-
|
|
1311
|
+
const incumbent = existingByKey.get(key);
|
|
1312
|
+
if (incumbent !== void 0 && incumbent.deleted_at === void 0) {
|
|
1313
|
+
continue;
|
|
1314
|
+
}
|
|
882
1315
|
const row = await backend.checkUnique({
|
|
883
1316
|
graphId,
|
|
884
1317
|
nodeKind: kindToCheck,
|
|
@@ -886,12 +1319,12 @@ async function batchCheckUniqueAcrossKinds(backend, graphId, constraintName, uni
|
|
|
886
1319
|
key,
|
|
887
1320
|
includeDeleted
|
|
888
1321
|
});
|
|
889
|
-
if (row !== void 0) {
|
|
1322
|
+
if (row !== void 0 && prefersClaimRow(incumbent, row)) {
|
|
890
1323
|
existingByKey.set(row.key, row);
|
|
891
1324
|
}
|
|
892
1325
|
}
|
|
893
1326
|
} else {
|
|
894
|
-
const rows = await
|
|
1327
|
+
const rows = await boundCheckUniqueBatch.checkUniqueBatch({
|
|
895
1328
|
graphId,
|
|
896
1329
|
nodeKind: kindToCheck,
|
|
897
1330
|
constraintName,
|
|
@@ -899,7 +1332,7 @@ async function batchCheckUniqueAcrossKinds(backend, graphId, constraintName, uni
|
|
|
899
1332
|
includeDeleted
|
|
900
1333
|
});
|
|
901
1334
|
for (const row of rows) {
|
|
902
|
-
if (
|
|
1335
|
+
if (prefersClaimRow(existingByKey.get(row.key), row)) {
|
|
903
1336
|
existingByKey.set(row.key, row);
|
|
904
1337
|
}
|
|
905
1338
|
}
|
|
@@ -912,13 +1345,16 @@ async function executeNodeCreateInternal(ctx, input, backend, options) {
|
|
|
912
1345
|
const id = input.id ?? generateId();
|
|
913
1346
|
const opContext = ctx.createOperationContext("create", "node", kind, id);
|
|
914
1347
|
const shouldReturnRow = options?.returnRow ?? true;
|
|
915
|
-
return
|
|
916
|
-
ctx,
|
|
1348
|
+
return runHookedWritePlan(
|
|
1349
|
+
nodeWritePlanContext(ctx),
|
|
917
1350
|
opContext,
|
|
1351
|
+
nodeWritePlan(
|
|
1352
|
+
nodeFencesConstraintProbe(ctx, kind, "create"),
|
|
1353
|
+
nodeRequiresIdentityLock(ctx)
|
|
1354
|
+
),
|
|
918
1355
|
backend,
|
|
919
|
-
async (
|
|
1356
|
+
async (session, target) => {
|
|
920
1357
|
const identity = ctx.identity;
|
|
921
|
-
if (identity !== void 0) await identity.lock(target);
|
|
922
1358
|
const prepared = await validateAndPrepareNodeCreate(
|
|
923
1359
|
ctx,
|
|
924
1360
|
input,
|
|
@@ -930,8 +1366,8 @@ async function executeNodeCreateInternal(ctx, input, backend, options) {
|
|
|
930
1366
|
if (existing !== void 0) {
|
|
931
1367
|
const resurrected = await resurrectPreparedNode(
|
|
932
1368
|
ctx,
|
|
1369
|
+
session,
|
|
933
1370
|
target,
|
|
934
|
-
lock,
|
|
935
1371
|
prepared
|
|
936
1372
|
);
|
|
937
1373
|
if (identity !== void 0) {
|
|
@@ -940,22 +1376,16 @@ async function executeNodeCreateInternal(ctx, input, backend, options) {
|
|
|
940
1376
|
return shouldReturnRow ? rowToNode(resurrected) : void 0;
|
|
941
1377
|
}
|
|
942
1378
|
const row = await withAlreadyExistsTranslation("node", async () => {
|
|
943
|
-
|
|
944
|
-
|
|
945
|
-
|
|
946
|
-
prepared.insertParams
|
|
947
|
-
);
|
|
1379
|
+
const work = nodeInsertWork(prepared);
|
|
1380
|
+
if (shouldReturnRow) return session.createNode(work);
|
|
1381
|
+
await session.createNodeNoReturn(work);
|
|
948
1382
|
return;
|
|
949
1383
|
});
|
|
950
|
-
await finalizeNodeCreate(ctx, prepared, target, lock);
|
|
951
1384
|
if (identity !== void 0) {
|
|
952
1385
|
await identity.foldCreated(target, foldReferences([prepared]));
|
|
953
1386
|
}
|
|
954
1387
|
if (row === void 0) return;
|
|
955
1388
|
return rowToNode(row);
|
|
956
|
-
},
|
|
957
|
-
{
|
|
958
|
-
fencesConstraintProbe: nodeFencesConstraintProbe(ctx, kind, "create")
|
|
959
1389
|
}
|
|
960
1390
|
);
|
|
961
1391
|
}
|
|
@@ -974,46 +1404,43 @@ async function executeNodeCreate(ctx, input, backend, options) {
|
|
|
974
1404
|
}
|
|
975
1405
|
async function executeNodeCreateNoReturnBatch(ctx, inputs, backend) {
|
|
976
1406
|
if (inputs.length === 0) return;
|
|
977
|
-
await
|
|
978
|
-
ctx,
|
|
1407
|
+
await runWritePlan(
|
|
1408
|
+
nodeWritePlanContext(ctx),
|
|
1409
|
+
nodeBatchWritePlan(
|
|
1410
|
+
nodeBatchConstraintProbes(ctx, inputs, "create"),
|
|
1411
|
+
nodeRequiresIdentityLock(ctx)
|
|
1412
|
+
),
|
|
979
1413
|
backend,
|
|
980
|
-
async (
|
|
1414
|
+
async (session, target) => {
|
|
981
1415
|
const identity = ctx.identity;
|
|
982
|
-
if (identity !== void 0) await identity.lock(target);
|
|
983
1416
|
const preparedCreates = await prepareBatchCreates(ctx, inputs, target);
|
|
984
1417
|
const partition = partitionCreates(preparedCreates);
|
|
985
1418
|
await withAlreadyExistsTranslation(
|
|
986
1419
|
"node",
|
|
987
|
-
() =>
|
|
988
|
-
|
|
989
|
-
partition.inserts.map((prepared) => prepared.insertParams)
|
|
1420
|
+
() => session.createNodesNoReturn(
|
|
1421
|
+
partition.inserts.map((prepared) => nodeInsertWork(prepared))
|
|
990
1422
|
)
|
|
991
1423
|
);
|
|
992
1424
|
for (const prepared of partition.resurrections) {
|
|
993
|
-
await resurrectPreparedNode(ctx,
|
|
1425
|
+
await resurrectPreparedNode(ctx, session, target, prepared);
|
|
994
1426
|
}
|
|
995
|
-
await finalizeNodeCreateBatch(ctx, partition.inserts, target, lock);
|
|
996
1427
|
if (identity !== void 0) {
|
|
997
1428
|
await identity.foldCreated(target, foldReferences(preparedCreates));
|
|
998
1429
|
}
|
|
999
|
-
},
|
|
1000
|
-
{
|
|
1001
|
-
fencesConstraintProbe: nodeBatchFencesConstraintProbe(
|
|
1002
|
-
ctx,
|
|
1003
|
-
inputs,
|
|
1004
|
-
"create"
|
|
1005
|
-
)
|
|
1006
1430
|
}
|
|
1007
1431
|
);
|
|
1008
1432
|
}
|
|
1009
1433
|
async function executeNodeCreateBatch(ctx, inputs, backend, options) {
|
|
1010
1434
|
if (inputs.length === 0) return [];
|
|
1011
|
-
return
|
|
1012
|
-
ctx,
|
|
1435
|
+
return runWritePlan(
|
|
1436
|
+
nodeWritePlanContext(ctx),
|
|
1437
|
+
nodeBatchWritePlan(
|
|
1438
|
+
nodeBatchConstraintProbes(ctx, inputs, "create"),
|
|
1439
|
+
nodeRequiresIdentityLock(ctx)
|
|
1440
|
+
),
|
|
1013
1441
|
backend,
|
|
1014
|
-
async (
|
|
1442
|
+
async (session, target) => {
|
|
1015
1443
|
const identity = ctx.identity;
|
|
1016
|
-
if (identity !== void 0) await identity.lock(target);
|
|
1017
1444
|
const preparedCreates = await prepareBatchCreates(
|
|
1018
1445
|
ctx,
|
|
1019
1446
|
inputs,
|
|
@@ -1023,18 +1450,16 @@ async function executeNodeCreateBatch(ctx, inputs, backend, options) {
|
|
|
1023
1450
|
const partition = partitionCreates(preparedCreates);
|
|
1024
1451
|
const inserted = await withAlreadyExistsTranslation(
|
|
1025
1452
|
"node",
|
|
1026
|
-
() =>
|
|
1027
|
-
|
|
1028
|
-
partition.inserts.map((prepared) => prepared.insertParams)
|
|
1453
|
+
() => session.createNodes(
|
|
1454
|
+
partition.inserts.map((prepared) => nodeInsertWork(prepared))
|
|
1029
1455
|
)
|
|
1030
1456
|
);
|
|
1031
1457
|
const resurrected = [];
|
|
1032
1458
|
for (const prepared of partition.resurrections) {
|
|
1033
1459
|
resurrected.push(
|
|
1034
|
-
await resurrectPreparedNode(ctx,
|
|
1460
|
+
await resurrectPreparedNode(ctx, session, target, prepared)
|
|
1035
1461
|
);
|
|
1036
1462
|
}
|
|
1037
|
-
await finalizeNodeCreateBatch(ctx, partition.inserts, target, lock);
|
|
1038
1463
|
const byReference = new Map(
|
|
1039
1464
|
[...inserted, ...resurrected].map((row) => [
|
|
1040
1465
|
refKey({ kind: row.kind, id: row.id }),
|
|
@@ -1051,39 +1476,36 @@ async function executeNodeCreateBatch(ctx, inputs, backend, options) {
|
|
|
1051
1476
|
await identity.foldCreated(target, foldReferences(preparedCreates));
|
|
1052
1477
|
}
|
|
1053
1478
|
return rows.map((row) => rowToNode(row));
|
|
1054
|
-
},
|
|
1055
|
-
{
|
|
1056
|
-
fencesConstraintProbe: nodeBatchFencesConstraintProbe(
|
|
1057
|
-
ctx,
|
|
1058
|
-
inputs,
|
|
1059
|
-
"create"
|
|
1060
|
-
)
|
|
1061
1479
|
}
|
|
1062
1480
|
);
|
|
1063
1481
|
}
|
|
1064
1482
|
async function executeNodeUpdate(ctx, input, backend, options) {
|
|
1483
|
+
if (input.clearValidTo === true) {
|
|
1484
|
+
assertClearValidToSupported(backend, "node");
|
|
1485
|
+
}
|
|
1065
1486
|
const opContext = ctx.createOperationContext(
|
|
1066
1487
|
"update",
|
|
1067
1488
|
"node",
|
|
1068
1489
|
input.kind,
|
|
1069
1490
|
input.id
|
|
1070
1491
|
);
|
|
1071
|
-
return
|
|
1072
|
-
ctx,
|
|
1492
|
+
return runHookedWritePlan(
|
|
1493
|
+
nodeWritePlanContext(ctx),
|
|
1073
1494
|
opContext,
|
|
1495
|
+
nodeWritePlan(
|
|
1496
|
+
nodeFencesConstraintProbe(ctx, input.kind, "update"),
|
|
1497
|
+
// Identity participates in an update when it RESURRECTS, and when it
|
|
1498
|
+
// states a validity end: a live-row update cannot change a node's kind, so
|
|
1499
|
+
// nothing folds, but an end reads the identity assertions that touch it.
|
|
1500
|
+
options?.clearDeleted === true || input.validTo !== void 0 ? nodeRequiresIdentityLock(ctx) : false
|
|
1501
|
+
),
|
|
1074
1502
|
backend,
|
|
1075
|
-
async (
|
|
1076
|
-
if (input.clearValidTo === true) {
|
|
1077
|
-
assertClearValidToSupported(backend, "node");
|
|
1078
|
-
}
|
|
1503
|
+
async (session, target) => {
|
|
1079
1504
|
const validTo = validateOptionalCanonicalIsoDate(
|
|
1080
1505
|
input.validTo,
|
|
1081
1506
|
"validTo"
|
|
1082
1507
|
);
|
|
1083
1508
|
const identity = ctx.identity;
|
|
1084
|
-
if (identity !== void 0 && (options?.clearDeleted === true || input.validTo !== void 0)) {
|
|
1085
|
-
await identity.lock(target);
|
|
1086
|
-
}
|
|
1087
1509
|
if (identity !== void 0 && validTo !== void 0) {
|
|
1088
1510
|
await identity.requireValidityEndCompatible(
|
|
1089
1511
|
target,
|
|
@@ -1094,8 +1516,8 @@ async function executeNodeUpdate(ctx, input, backend, options) {
|
|
|
1094
1516
|
const node = await performNodeUpdateWithResurrectionRecovery(
|
|
1095
1517
|
ctx,
|
|
1096
1518
|
input,
|
|
1519
|
+
session,
|
|
1097
1520
|
target,
|
|
1098
|
-
lock,
|
|
1099
1521
|
options
|
|
1100
1522
|
);
|
|
1101
1523
|
if (options?.clearDeleted && identity !== void 0) {
|
|
@@ -1104,13 +1526,6 @@ async function executeNodeUpdate(ctx, input, backend, options) {
|
|
|
1104
1526
|
]);
|
|
1105
1527
|
}
|
|
1106
1528
|
return node;
|
|
1107
|
-
},
|
|
1108
|
-
{
|
|
1109
|
-
fencesConstraintProbe: nodeFencesConstraintProbe(
|
|
1110
|
-
ctx,
|
|
1111
|
-
input.kind,
|
|
1112
|
-
"update"
|
|
1113
|
-
)
|
|
1114
1529
|
}
|
|
1115
1530
|
);
|
|
1116
1531
|
}
|
|
@@ -1184,7 +1599,11 @@ async function executeNodeUpdateWhere(ctx, kind, inputPatch, candidateIds, candi
|
|
|
1184
1599
|
}
|
|
1185
1600
|
);
|
|
1186
1601
|
}
|
|
1187
|
-
if (uniqueConstraints.length > 0 && (
|
|
1602
|
+
if (uniqueConstraints.length > 0 && missingRequiredExtras(
|
|
1603
|
+
UNIQUE_SIDECAR_BATCH,
|
|
1604
|
+
ctx.uniqueSidecarBatch,
|
|
1605
|
+
"set-based node update"
|
|
1606
|
+
).length > 0) {
|
|
1188
1607
|
throw new ConfigurationError(
|
|
1189
1608
|
"updateWhere() requires batched uniqueness sidecar operations for constrained nodes",
|
|
1190
1609
|
{ code: "SET_UPDATE_UNIQUENESS_UNSUPPORTED", kind }
|
|
@@ -1205,107 +1624,32 @@ async function executeNodeUpdateWhere(ctx, kind, inputPatch, candidateIds, candi
|
|
|
1205
1624
|
const hookContext = ctx.createBulkOperationContext("updateWhere", kind);
|
|
1206
1625
|
return ctx.withBulkOperationHooks(
|
|
1207
1626
|
hookContext,
|
|
1208
|
-
() =>
|
|
1209
|
-
ctx,
|
|
1627
|
+
() => runWritePlan(
|
|
1628
|
+
nodeWritePlanContext(ctx),
|
|
1629
|
+
// The set update re-checks every changed unique key across the
|
|
1630
|
+
// constraint's scope before rebuilding the sidecars, so a shared-scope
|
|
1631
|
+
// constraint makes it a constrained write like any other update.
|
|
1632
|
+
// Identity does not participate: a set update rewrites props, and no
|
|
1633
|
+
// patch can change a node's kind.
|
|
1634
|
+
nodeWritePlan(nodeFencesConstraintProbe(ctx, kind, "update"), false),
|
|
1210
1635
|
backend,
|
|
1211
|
-
|
|
1212
|
-
|
|
1213
|
-
if (updateNodeSet === void 0) {
|
|
1214
|
-
throw new ConfigurationError(
|
|
1215
|
-
"The transaction backend does not support set-based node updates",
|
|
1216
|
-
{ code: "SET_UPDATE_UNSUPPORTED", kind }
|
|
1217
|
-
);
|
|
1218
|
-
}
|
|
1219
|
-
const hardDeleteUniquesByNodeIds = target.hardDeleteUniquesByNodeIds;
|
|
1220
|
-
if (uniqueConstraints.length > 0 && (hardDeleteUniquesByNodeIds === void 0 || target.insertUniqueBatch === void 0 || target.checkUniqueBatch === void 0)) {
|
|
1221
|
-
throw new ConfigurationError(
|
|
1222
|
-
"The transaction backend lacks batched uniqueness operations",
|
|
1223
|
-
{ code: "SET_UPDATE_UNIQUENESS_UNSUPPORTED", kind }
|
|
1224
|
-
);
|
|
1225
|
-
}
|
|
1226
|
-
if (getSearchableFields(schema).length > 0 && (target.upsertFulltext === void 0 || target.deleteFulltext === void 0 || target.upsertFulltextBatch === void 0 || target.deleteFulltextBatch === void 0)) {
|
|
1227
|
-
throw new ConfigurationError(
|
|
1228
|
-
"The transaction backend lacks batched fulltext operations",
|
|
1229
|
-
{ code: "SET_UPDATE_FULLTEXT_UNSUPPORTED", kind }
|
|
1230
|
-
);
|
|
1231
|
-
}
|
|
1232
|
-
if (getEmbeddingFields(schema).length > 0 && (target.upsertEmbedding === void 0 || target.deleteEmbedding === void 0 || target.upsertEmbeddingBatch === void 0 || target.deleteEmbeddingBatch === void 0)) {
|
|
1233
|
-
throw new ConfigurationError(
|
|
1234
|
-
"The transaction backend lacks batched vector operations",
|
|
1235
|
-
{ code: "SET_UPDATE_VECTOR_UNSUPPORTED", kind }
|
|
1236
|
-
);
|
|
1237
|
-
}
|
|
1238
|
-
const result = await updateNodeSet({
|
|
1239
|
-
graphId: ctx.graphId,
|
|
1636
|
+
(session) => session.reviseNodeSet(
|
|
1637
|
+
{
|
|
1240
1638
|
kind,
|
|
1639
|
+
schema,
|
|
1640
|
+
uniqueConstraints,
|
|
1241
1641
|
patch,
|
|
1242
1642
|
unsetProperties,
|
|
1243
1643
|
candidateIds,
|
|
1244
1644
|
candidateIdColumn
|
|
1245
|
-
}
|
|
1246
|
-
|
|
1247
|
-
|
|
1248
|
-
|
|
1249
|
-
|
|
1250
|
-
|
|
1251
|
-
|
|
1252
|
-
|
|
1253
|
-
});
|
|
1254
|
-
if (!canonicalEqual(validatedProps, props)) {
|
|
1255
|
-
throw new ValidationError(
|
|
1256
|
-
`Set update would persist a non-canonical ${kind} row`,
|
|
1257
|
-
{
|
|
1258
|
-
entityType: "node",
|
|
1259
|
-
kind,
|
|
1260
|
-
operation: "update",
|
|
1261
|
-
id: row.id,
|
|
1262
|
-
issues: [
|
|
1263
|
-
{
|
|
1264
|
-
path: "props",
|
|
1265
|
-
message: "The complete row requires schema normalization"
|
|
1266
|
-
}
|
|
1267
|
-
]
|
|
1268
|
-
}
|
|
1269
|
-
);
|
|
1270
|
-
}
|
|
1271
|
-
return {
|
|
1272
|
-
kind,
|
|
1273
|
-
id: row.id,
|
|
1274
|
-
schema,
|
|
1275
|
-
props: validatedProps,
|
|
1276
|
-
uniqueConstraints
|
|
1277
|
-
};
|
|
1278
|
-
});
|
|
1279
|
-
if (uniqueConstraints.length > 0) {
|
|
1280
|
-
await validateResolvedNodeUniqueness(
|
|
1281
|
-
createUniquenessContext(ctx.graphId, ctx.registry, target),
|
|
1282
|
-
sidecarItems.map((item) => ({
|
|
1283
|
-
kind: item.kind,
|
|
1284
|
-
id: item.id,
|
|
1285
|
-
props: item.props,
|
|
1286
|
-
constraints: item.uniqueConstraints
|
|
1287
|
-
}))
|
|
1288
|
-
);
|
|
1289
|
-
await requireDefined(hardDeleteUniquesByNodeIds)({
|
|
1290
|
-
graphId: ctx.graphId,
|
|
1291
|
-
concreteKind: kind,
|
|
1292
|
-
nodeIds: result.rows.map((row) => row.id)
|
|
1293
|
-
});
|
|
1294
|
-
}
|
|
1295
|
-
await applyNodeInsertSideEffectsBatch(
|
|
1296
|
-
createNodeWriteContext(ctx.graphId, ctx.registry, lock),
|
|
1297
|
-
sidecarItems,
|
|
1298
|
-
target
|
|
1299
|
-
);
|
|
1300
|
-
return { affectedCount: result.affectedCount };
|
|
1301
|
-
},
|
|
1302
|
-
{
|
|
1303
|
-
didWrite: (result) => result.affectedCount > 0,
|
|
1304
|
-
// The set update re-checks every changed unique key across the
|
|
1305
|
-
// constraint's scope before rebuilding the sidecars, so a shared-scope
|
|
1306
|
-
// constraint makes it a constrained write like any other update.
|
|
1307
|
-
fencesConstraintProbe: nodeFencesConstraintProbe(ctx, kind, "update")
|
|
1308
|
-
}
|
|
1645
|
+
},
|
|
1646
|
+
// This path states no window — it patches properties — so the write
|
|
1647
|
+
// asserts no stored lower bound. The set UPDATE has no field to
|
|
1648
|
+
// carry one, so a future windowed set update is refused here rather
|
|
1649
|
+
// than run unfenced.
|
|
1650
|
+
{ validityLowerBound: {} }
|
|
1651
|
+
),
|
|
1652
|
+
{ didWrite: (result) => result.affectedCount > 0 }
|
|
1309
1653
|
)
|
|
1310
1654
|
);
|
|
1311
1655
|
}
|
|
@@ -1313,18 +1657,22 @@ async function executeNodeUpsertUpdate(ctx, input, backend, options) {
|
|
|
1313
1657
|
if (input.clearValidTo === true) {
|
|
1314
1658
|
assertClearValidToSupported(backend, "node");
|
|
1315
1659
|
}
|
|
1316
|
-
return
|
|
1317
|
-
ctx,
|
|
1660
|
+
return runWritePlan(
|
|
1661
|
+
nodeWritePlanContext(ctx),
|
|
1662
|
+
nodeWritePlan(
|
|
1663
|
+
nodeFencesConstraintProbe(ctx, input.kind, "update"),
|
|
1664
|
+
// Conditional for the same reason as {@link executeNodeUpdate}: a
|
|
1665
|
+
// resurrecting upsert folds, and stating a validity end reads the
|
|
1666
|
+
// identity's other members, so both take the lock.
|
|
1667
|
+
options?.clearDeleted === true || input.validTo !== void 0 ? nodeRequiresIdentityLock(ctx) : false
|
|
1668
|
+
),
|
|
1318
1669
|
backend,
|
|
1319
|
-
async (
|
|
1670
|
+
async (session, target) => {
|
|
1320
1671
|
const validTo = validateOptionalCanonicalIsoDate(
|
|
1321
1672
|
input.validTo,
|
|
1322
1673
|
"validTo"
|
|
1323
1674
|
);
|
|
1324
1675
|
const identity = ctx.identity;
|
|
1325
|
-
if (identity !== void 0 && (options?.clearDeleted === true || input.validTo !== void 0)) {
|
|
1326
|
-
await identity.lock(target);
|
|
1327
|
-
}
|
|
1328
1676
|
if (identity !== void 0 && validTo !== void 0) {
|
|
1329
1677
|
await identity.requireValidityEndCompatible(
|
|
1330
1678
|
target,
|
|
@@ -1335,8 +1683,8 @@ async function executeNodeUpsertUpdate(ctx, input, backend, options) {
|
|
|
1335
1683
|
const node = await performNodeUpdateWithResurrectionRecovery(
|
|
1336
1684
|
ctx,
|
|
1337
1685
|
input,
|
|
1686
|
+
session,
|
|
1338
1687
|
target,
|
|
1339
|
-
lock,
|
|
1340
1688
|
options
|
|
1341
1689
|
);
|
|
1342
1690
|
if (options?.clearDeleted && identity !== void 0) {
|
|
@@ -1345,13 +1693,6 @@ async function executeNodeUpsertUpdate(ctx, input, backend, options) {
|
|
|
1345
1693
|
]);
|
|
1346
1694
|
}
|
|
1347
1695
|
return node;
|
|
1348
|
-
},
|
|
1349
|
-
{
|
|
1350
|
-
fencesConstraintProbe: nodeFencesConstraintProbe(
|
|
1351
|
-
ctx,
|
|
1352
|
-
input.kind,
|
|
1353
|
-
"update"
|
|
1354
|
-
)
|
|
1355
1696
|
}
|
|
1356
1697
|
);
|
|
1357
1698
|
}
|
|
@@ -1359,26 +1700,22 @@ async function executeNodeDelete(ctx, kind, id, backend) {
|
|
|
1359
1700
|
const gate = await backend.getNode(ctx.graphId, kind, id);
|
|
1360
1701
|
if (!gate || gate.deleted_at) return;
|
|
1361
1702
|
const opContext = ctx.createOperationContext("delete", "node", kind, id);
|
|
1362
|
-
return
|
|
1363
|
-
ctx,
|
|
1703
|
+
return runHookedWritePlan(
|
|
1704
|
+
nodeWritePlanContext(ctx),
|
|
1364
1705
|
opContext,
|
|
1706
|
+
nodeWritePlan(void 0, nodeRequiresIdentityLock(ctx)),
|
|
1365
1707
|
backend,
|
|
1366
|
-
async (
|
|
1708
|
+
async (session, target) => {
|
|
1367
1709
|
const identity = ctx.identity;
|
|
1368
|
-
if (identity !== void 0) await identity.lock(target);
|
|
1369
1710
|
const registration = getNodeRegistration(ctx.graph, kind);
|
|
1370
1711
|
const preflight = await target.getNode(ctx.graphId, kind, id);
|
|
1371
1712
|
if (!preflight || !isLiveNodeRow(preflight)) return;
|
|
1372
|
-
await
|
|
1373
|
-
|
|
1374
|
-
|
|
1375
|
-
|
|
1376
|
-
|
|
1377
|
-
|
|
1378
|
-
onDelete: registration.onDelete
|
|
1379
|
-
},
|
|
1380
|
-
target
|
|
1381
|
-
);
|
|
1713
|
+
await session.retireNode({
|
|
1714
|
+
existing: preflight,
|
|
1715
|
+
schema: registration.type.schema,
|
|
1716
|
+
uniqueConstraints: registration.unique ?? [],
|
|
1717
|
+
onDelete: registration.onDelete
|
|
1718
|
+
});
|
|
1382
1719
|
if (identity !== void 0) {
|
|
1383
1720
|
await identity.detachDeleted(target, { kind, id }, "soft");
|
|
1384
1721
|
}
|
|
@@ -1386,32 +1723,23 @@ async function executeNodeDelete(ctx, kind, id, backend) {
|
|
|
1386
1723
|
);
|
|
1387
1724
|
}
|
|
1388
1725
|
async function executeNodeDeleteBatch(ctx, kind, ids, backend) {
|
|
1389
|
-
await
|
|
1390
|
-
ctx,
|
|
1726
|
+
await runWritePlan(
|
|
1727
|
+
nodeWritePlanContext(ctx),
|
|
1728
|
+
nodeWritePlan(void 0, nodeRequiresIdentityLock(ctx)),
|
|
1391
1729
|
backend,
|
|
1392
|
-
async (
|
|
1730
|
+
async (session, target) => {
|
|
1393
1731
|
const identity = ctx.identity;
|
|
1394
|
-
if (identity !== void 0) await identity.lock(target);
|
|
1395
1732
|
const registration = getNodeRegistration(ctx.graph, kind);
|
|
1396
|
-
const writeContext = createNodeWriteContext(
|
|
1397
|
-
ctx.graphId,
|
|
1398
|
-
ctx.registry,
|
|
1399
|
-
lock
|
|
1400
|
-
);
|
|
1401
1733
|
let affectedCount = 0;
|
|
1402
1734
|
for (const id of ids) {
|
|
1403
1735
|
const preflight = await target.getNode(ctx.graphId, kind, id);
|
|
1404
1736
|
if (!preflight || !isLiveNodeRow(preflight)) continue;
|
|
1405
|
-
await
|
|
1406
|
-
|
|
1407
|
-
|
|
1408
|
-
|
|
1409
|
-
|
|
1410
|
-
|
|
1411
|
-
onDelete: registration.onDelete
|
|
1412
|
-
},
|
|
1413
|
-
target
|
|
1414
|
-
);
|
|
1737
|
+
await session.retireNode({
|
|
1738
|
+
existing: preflight,
|
|
1739
|
+
schema: registration.type.schema,
|
|
1740
|
+
uniqueConstraints: registration.unique ?? [],
|
|
1741
|
+
onDelete: registration.onDelete
|
|
1742
|
+
});
|
|
1415
1743
|
if (identity !== void 0) {
|
|
1416
1744
|
await identity.detachDeleted(target, { kind, id }, "soft");
|
|
1417
1745
|
}
|
|
@@ -1426,24 +1754,20 @@ async function executeNodeHardDelete(ctx, kind, id, backend) {
|
|
|
1426
1754
|
const gate = await backend.getNode(ctx.graphId, kind, id);
|
|
1427
1755
|
if (!gate) return;
|
|
1428
1756
|
const opContext = ctx.createOperationContext("delete", "node", kind, id);
|
|
1429
|
-
return
|
|
1430
|
-
ctx,
|
|
1757
|
+
return runHookedWritePlan(
|
|
1758
|
+
nodeWritePlanContext(ctx),
|
|
1431
1759
|
opContext,
|
|
1760
|
+
nodeWritePlan(void 0, nodeRequiresIdentityLock(ctx)),
|
|
1432
1761
|
backend,
|
|
1433
|
-
async (
|
|
1762
|
+
async (session, target) => {
|
|
1434
1763
|
const identity = ctx.identity;
|
|
1435
|
-
if (identity !== void 0) await identity.lock(target);
|
|
1436
1764
|
const registration = getNodeRegistration(ctx.graph, kind);
|
|
1437
|
-
await
|
|
1438
|
-
|
|
1439
|
-
|
|
1440
|
-
|
|
1441
|
-
|
|
1442
|
-
|
|
1443
|
-
onDelete: registration.onDelete
|
|
1444
|
-
},
|
|
1445
|
-
target
|
|
1446
|
-
);
|
|
1765
|
+
await session.purgeNode({
|
|
1766
|
+
kind,
|
|
1767
|
+
id,
|
|
1768
|
+
schema: registration.type.schema,
|
|
1769
|
+
onDelete: registration.onDelete
|
|
1770
|
+
});
|
|
1447
1771
|
if (identity !== void 0) {
|
|
1448
1772
|
await identity.detachDeleted(target, { kind, id }, "hard");
|
|
1449
1773
|
}
|
|
@@ -1473,7 +1797,7 @@ async function executeNodeGetOrCreateByConstraint(ctx, kind, constraintName, pro
|
|
|
1473
1797
|
constraint.fields,
|
|
1474
1798
|
constraint.collation
|
|
1475
1799
|
);
|
|
1476
|
-
const kindsToCheck =
|
|
1800
|
+
const kindsToCheck = uniquenessProbeKinds(
|
|
1477
1801
|
kind,
|
|
1478
1802
|
constraint.scope,
|
|
1479
1803
|
ctx.registry
|
|
@@ -1548,7 +1872,7 @@ async function executeNodeFindByConstraint(ctx, kind, constraintName, props, bac
|
|
|
1548
1872
|
constraint.fields,
|
|
1549
1873
|
constraint.collation
|
|
1550
1874
|
);
|
|
1551
|
-
const kindsToCheck =
|
|
1875
|
+
const kindsToCheck = uniquenessProbeKinds(
|
|
1552
1876
|
kind,
|
|
1553
1877
|
constraint.scope,
|
|
1554
1878
|
ctx.registry
|
|
@@ -1602,13 +1926,14 @@ async function executeNodeBulkFindByConstraint(ctx, kind, constraintName, items,
|
|
|
1602
1926
|
const constraint = resolveConstraint(ctx.graph, kind, constraintName);
|
|
1603
1927
|
const validated = validateAndComputeKeys(nodeKind, kind, constraint, items);
|
|
1604
1928
|
const uniqueKeys = collectUniqueKeys(validated);
|
|
1605
|
-
const kindsToCheck =
|
|
1929
|
+
const kindsToCheck = uniquenessProbeKinds(
|
|
1606
1930
|
kind,
|
|
1607
1931
|
constraint.scope,
|
|
1608
1932
|
ctx.registry
|
|
1609
1933
|
);
|
|
1610
1934
|
const existingByKey = uniqueKeys.length > 0 ? await batchCheckUniqueAcrossKinds(
|
|
1611
1935
|
backend,
|
|
1936
|
+
ctx.uniqueSidecarBatch,
|
|
1612
1937
|
ctx.graphId,
|
|
1613
1938
|
constraint.name,
|
|
1614
1939
|
uniqueKeys,
|
|
@@ -1833,6 +2158,7 @@ async function executeNodeBulkFindByIndex(ctx, kind, indexName, items, backend,
|
|
|
1833
2158
|
const matches = limitPerInput !== void 0 && !capInSql ? capMatchesPerGroup(rawMatches, limitPerInput) : rawMatches;
|
|
1834
2159
|
const nodesById = await hydrateNodesById(
|
|
1835
2160
|
backend,
|
|
2161
|
+
ctx.batchPointRead,
|
|
1836
2162
|
ctx.graphId,
|
|
1837
2163
|
kind,
|
|
1838
2164
|
matches.map((match) => match.id)
|
|
@@ -1860,8 +2186,14 @@ function capMatchesPerGroup(matches, limitPerInput) {
|
|
|
1860
2186
|
}
|
|
1861
2187
|
return capped;
|
|
1862
2188
|
}
|
|
1863
|
-
async function hydrateNodesById(backend, graphId, kind, ids) {
|
|
1864
|
-
const rowsById = await getNodeRowsByIds(
|
|
2189
|
+
async function hydrateNodesById(backend, batchPointRead, graphId, kind, ids) {
|
|
2190
|
+
const rowsById = await getNodeRowsByIds(
|
|
2191
|
+
backend,
|
|
2192
|
+
batchPointRead,
|
|
2193
|
+
graphId,
|
|
2194
|
+
kind,
|
|
2195
|
+
ids
|
|
2196
|
+
);
|
|
1865
2197
|
const nodesById = /* @__PURE__ */ new Map();
|
|
1866
2198
|
for (const [id, row] of rowsById) {
|
|
1867
2199
|
if (row.deleted_at !== void 0) continue;
|
|
@@ -1877,7 +2209,7 @@ async function executeNodeBulkGetOrCreateByConstraint(ctx, kind, constraintName,
|
|
|
1877
2209
|
const constraint = resolveConstraint(ctx.graph, kind, constraintName);
|
|
1878
2210
|
const validated = validateAndComputeKeys(nodeKind, kind, constraint, items);
|
|
1879
2211
|
const uniqueKeys = collectUniqueKeys(validated);
|
|
1880
|
-
const kindsToCheck =
|
|
2212
|
+
const kindsToCheck = uniquenessProbeKinds(
|
|
1881
2213
|
kind,
|
|
1882
2214
|
constraint.scope,
|
|
1883
2215
|
ctx.registry
|
|
@@ -1885,6 +2217,7 @@ async function executeNodeBulkGetOrCreateByConstraint(ctx, kind, constraintName,
|
|
|
1885
2217
|
async function attempt() {
|
|
1886
2218
|
const existingByKey = uniqueKeys.length > 0 ? await batchCheckUniqueAcrossKinds(
|
|
1887
2219
|
backend,
|
|
2220
|
+
ctx.uniqueSidecarBatch,
|
|
1888
2221
|
ctx.graphId,
|
|
1889
2222
|
constraint.name,
|
|
1890
2223
|
uniqueKeys,
|
|
@@ -1985,6 +2318,6 @@ async function executeNodeBulkGetOrCreateByConstraint(ctx, kind, constraintName,
|
|
|
1985
2318
|
}
|
|
1986
2319
|
}
|
|
1987
2320
|
|
|
1988
|
-
export { assertClearValidToSupported, assertValidityEndMutation, checkCardinalityConstraint,
|
|
1989
|
-
//# sourceMappingURL=chunk-
|
|
1990
|
-
//# sourceMappingURL=chunk-
|
|
2321
|
+
export { assertClearValidToSupported, assertValidityEndMutation, assertsStoredWindowState, checkCardinalityConstraint, checkDisjointnessConstraint, createEdgeBatchValidationBackend, createNodeBatchValidationSeams, edgeWriteNeedsConstraintFence, edgeWritePlan, executeNodeBulkFindByConstraint, executeNodeBulkFindByIndex, executeNodeBulkGetOrCreateByConstraint, executeNodeCreate, executeNodeCreateBatch, executeNodeCreateNoReturnBatch, executeNodeDelete, executeNodeDeleteBatch, executeNodeFindByConstraint, executeNodeGetOrCreateByConstraint, executeNodeHardDelete, executeNodeUpdate, executeNodeUpdateWhere, executeNodeUpsertUpdate, graphOwesClaims, mixedWritePlan, nodeUpsertDirtyCheck, primeBatchValidationCaches, rowToEdge, rowToEdgeMeta, rowToNode, rowToNodeMeta, runHookedWritePlan, runWritePlan, unfencedTarget, validityEndAfterMutation, withAlreadyExistsTranslation };
|
|
2322
|
+
//# sourceMappingURL=chunk-TYEYRCXL.js.map
|
|
2323
|
+
//# sourceMappingURL=chunk-TYEYRCXL.js.map
|