@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/store/row-mappers.ts","../src/store/constraints.ts","../src/store/operations/edge-batch-validation.ts","../src/store/operations/edge-write-pipeline.ts","../src/store/operations/write-fences.ts","../src/store/operations/write-session.ts","../src/store/operations/write-executor.ts","../src/store/operations/write-plan.ts","../src/store/validity-end.ts","../src/store/operations/already-exists.ts","../src/store/operations/node-operations.ts"],"names":["rowPropsToObject","filterReservedKeys","RESERVED_NODE_KEYS","RESERVED_EDGE_KEYS","nodeClaimSites","checkDisjointness","EDGE_CARDINALITY_SPECS","error","checkUniqueEdge","checkCardinality","encodeTupleKey","deriveBackend","claimEdgeCardinality","purgeEdgeClaims","assertsStoredLowerBound","assertsStoredUpperBound","createNodeWriteContext","nodeInsertDispatch","edgeInsertDispatch","withNodeCreateClaims","applyNodeInsertSyncFans","runInsertNoReturn","withNodeCreateClaimsBatch","runInsertBatchReturning","applyNodeInsertSyncFansBatch","runInsertBatch","applyNodeUpdate","applyNodeSoftDelete","applyNodeHardDelete","applyNodeResurrect","applyNodeSetUpdate","claimEdgeCardinalityBatch","requireDefined","runInWriteTransaction","runHookedWriteOperation","ValidationError","ConfigurationError","ENTITY_ALREADY_EXISTS_CODE","DatabaseOperationError","hasOwnKey","KindNotFoundError","NodeConstraintNotFoundError","nodeClaimEntries","uniquenessProbeKinds","validateNodeProps","validateOptionalCanonicalIsoDate","assertOrderedValidityWindow","checkUniquenessConstraints","createUniquenessContext","canonicalEqual","NodeNotFoundError","nowIso","preservesImmutableLowerBound","resolveStampedValidityLowerBound","assertWritableValidityWindow","row","isLiveNodeRow","bindExtraIfReachable","BATCH_POINT_READ","UNIQUE_SIDECAR_BATCH","generateId","refKey","createDataKeyedBag","assertJsonValue","missingRequiredExtras","getSearchableFields","getEmbeddingFields","checkWherePredicate","computeUniqueKey","UniquenessError","NodeIndexNotFoundError","getDialect","resolveJsonPointer","createSqlSchema","DEFAULT_SQL_SCHEMA","sql","compileNodeIndexFieldKeys","compileIndexWhere","asCompiledRowsSql","getNodeRowsByIds"],"mappings":"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","file":"chunk-2KCTP3U2.cjs","sourcesContent":["/**\n * Row Mappers for Store\n *\n * Transforms database rows into typed Node and Edge objects.\n */\nimport {\n type EdgeRow as BackendEdgeRow,\n type NodeRow as BackendNodeRow,\n rowPropsToObject,\n} from \"../backend/types\";\nimport {\n filterReservedKeys,\n RESERVED_EDGE_KEYS,\n RESERVED_NODE_KEYS,\n} from \"./reserved-keys\";\nimport { type Edge, type EdgeMeta, type Node, type NodeMeta } from \"./types\";\n\n/**\n * Raw node row from database (without graph_id).\n * Derived from BackendNodeRow so BackendNodeRow is assignable without casts.\n */\nexport type NodeRow = Omit<BackendNodeRow, \"graph_id\">;\n\n/**\n * Raw edge row from database (without graph_id).\n * Derived from BackendEdgeRow so BackendEdgeRow is assignable without casts.\n */\nexport type EdgeRow = Omit<BackendEdgeRow, \"graph_id\">;\n\n/**\n * Converts null to undefined for consistent typing.\n * Database backends return null for missing values, but our types use undefined.\n */\nfunction nullToUndefined<T>(value: T | null | undefined): T | undefined {\n return value === null ? undefined : value;\n}\n\n/**\n * Transforms a database row into a typed Node object.\n *\n * Props are spread at top level, metadata goes under `meta`.\n * Reserved keys (id, kind, meta) in props are filtered out to prevent collisions.\n * Null values from database are normalized to undefined.\n */\nexport function rowToNode(row: NodeRow): Node {\n const rawProps = rowPropsToObject(row.props);\n const props = filterReservedKeys(rawProps, RESERVED_NODE_KEYS);\n return {\n kind: row.kind,\n id: row.id as Node[\"id\"],\n meta: rowToNodeMeta(row),\n ...props,\n };\n}\n\nexport function rowToNodeMeta(\n row: Pick<\n NodeRow,\n | \"version\"\n | \"valid_from\"\n | \"valid_to\"\n | \"created_at\"\n | \"updated_at\"\n | \"deleted_at\"\n >,\n): NodeMeta {\n return {\n version: row.version,\n validFrom: nullToUndefined(row.valid_from),\n validTo: nullToUndefined(row.valid_to),\n createdAt: row.created_at,\n updatedAt: row.updated_at,\n deletedAt: nullToUndefined(row.deleted_at),\n };\n}\n\n/**\n * Transforms a database row into a typed Edge object.\n *\n * Props are spread at top level, metadata goes under `meta`.\n * Reserved keys in props are filtered out to prevent collisions.\n * Null values from database are normalized to undefined.\n */\nexport function rowToEdge(row: EdgeRow): Edge {\n const rawProps = rowPropsToObject(row.props);\n const props = filterReservedKeys(rawProps, RESERVED_EDGE_KEYS);\n return {\n id: row.id,\n kind: row.kind,\n fromKind: row.from_kind,\n fromId: row.from_id,\n toKind: row.to_kind,\n toId: row.to_id,\n meta: rowToEdgeMeta(row),\n ...props,\n } as Edge;\n}\n\nexport function rowToEdgeMeta(\n row: Pick<\n EdgeRow,\n \"valid_from\" | \"valid_to\" | \"created_at\" | \"updated_at\" | \"deleted_at\"\n >,\n): EdgeMeta {\n return {\n validFrom: nullToUndefined(row.valid_from),\n validTo: nullToUndefined(row.valid_to),\n createdAt: row.created_at,\n updatedAt: row.updated_at,\n deletedAt: nullToUndefined(row.deleted_at),\n };\n}\n","/**\n * Constraint Checking for Store Operations\n *\n * Handles checking disjointness and cardinality constraints.\n *\n * ## The invariant these probes depend on\n *\n * **A declared constraint's probe and the write it guards commit under one\n * per-graph mutual exclusion, on every backend.** Every check in this module is\n * an APPLICATION probe: it reads, decides, and returns, and the caller then\n * writes. Nothing in the schema re-decides at write time, because for each of\n * these constraints the available key covers a different axis than the\n * constraint declares:\n *\n * - edge cardinality `one` / `unique` / `oneActive` is a predicate over\n * `(kind, from)` or `(kind, from, to)`, while the edges table's only\n * uniqueness is its `(graph_id, id)` primary key;\n * - disjointness is a predicate over `(graph_id, id)` ACROSS kinds, while the\n * nodes primary key is `(graph_id, kind, id)` — the same id under a disjoint\n * kind is a different row by construction;\n * - `scope: \"kindWithSubClasses\"` uniqueness probes the root kind and every\n * descendant. Its claim is now reserved at the scope's AXIS — the subclass\n * component's minimum — so sibling kinds contend for one row and the uniques\n * primary key does fence them (see {@link file://./claims/node-claims.ts});\n * the lock is kept because the probe still reads kinds the key does not\n * cover, including rows written before the axis existed.\n *\n * So the probe is only as good as the serialization around it. SQLite supplies\n * that for free (`BEGIN IMMEDIATE` admits one writer per database). PostgreSQL\n * supplied it only when history or revision tracking was enabled, because only\n * those took the per-graph advisory lock — leaving a default PostgreSQL store\n * open to two writers that both read \"no conflict\" and both commit.\n * {@link edgeWriteNeedsConstraintFence} / {@link nodeWriteNeedsConstraintFence}\n * are what the write paths ask so they take that same per-graph lock whenever\n * one of these probes is in play, and only then.\n */\nimport { type GraphEntityReadBackend } from \"../backend/types\";\nimport {\n checkCardinality,\n checkDisjointness,\n checkUniqueEdge,\n} from \"../constraints\";\nimport { type GraphDef } from \"../core/define-graph\";\nimport { type Cardinality, type UniqueConstraint } from \"../core/types\";\nimport { type KindRegistry } from \"../registry/kind-registry\";\nimport { type ConstraintFenceReason } from \"./claims/backing\";\nimport { EDGE_CARDINALITY_SPECS } from \"./claims/edge-claims\";\nimport { nodeClaimSites } from \"./claims/sites\";\n\nexport { type ConstraintFenceReason } from \"./claims/backing\";\n\n/**\n * Context for constraint operations.\n *\n * The backend is the graph-entity READ facet rather than the backend union:\n * every check in this module is an application probe that reads, decides and\n * returns, and the CALLER does the writing. Naming the facet is what lets a\n * probe run inside a write frame, whose row-work handle exposes reads only,\n * and it states in the type that no check here writes.\n */\nexport type ConstraintContext = Readonly<{\n graphId: string;\n registry: KindRegistry;\n backend: GraphEntityReadBackend;\n}>;\n\n/**\n * The constraint that makes an edge write of this cardinality constrained, or\n * `undefined` when it is not.\n *\n * `many` declares no constraint, so its create runs no cardinality probe and\n * must NOT pay for the lock — the fence is for writes that check something, not\n * for writes in general. Every other cardinality counts or existence-tests\n * sibling edges before inserting, and nothing in the schema repeats that test.\n *\n * The one owner of this classification: `checkCardinalityConstraint`'s `many`\n * arm and this predicate are the same decision seen from two sides, and a\n * second inline `!== \"many\"` at a write path would be the copy that drifts.\n */\nexport function edgeWriteNeedsConstraintFence(\n cardinality: Cardinality,\n): ConstraintFenceReason | undefined {\n return cardinality === \"many\" ? undefined : \"edgeCardinality\";\n}\n\n/**\n * The constraint that makes a node write of this kind constrained, or\n * `undefined` when it is not. A kind can qualify on both counts; the reason\n * reported is the first that applies, which is enough to name the class in a\n * refusal.\n *\n * Two probe families qualify, and they are reached by different operations:\n *\n * - **Disjointness** is probed only where a node comes into existence under a\n * kind — the create/resurrect preparation. An in-place update cannot change a\n * node's kind, so it re-derives no cross-kind verdict and needs no fence for\n * this reason.\n * - **Shared-scope uniqueness** is probed by create AND update. It qualifies\n * only when the constraint's scope actually spans more than the node's own\n * kind: a single-kind scope probes exactly the `(graph_id, node_kind,\n * constraint_name, key)` row that the claim then reserves, so the uniques\n * primary key IS the fence and the write needs no other.\n *\n * The whole answer is a PROJECTION of {@link nodeClaimSites}, not a second\n * spelling of it: that list already decided, per family, whether the site's\n * axis spans kinds beyond the writer's own — in order to decide where its claim\n * is written and when — and this reads that same decision back, reporting the\n * first site carrying it. Disjointness sites come first in that list, so a kind\n * qualifying on both counts keeps reporting the class it reports today, which\n * is what the refusal payload names.\n *\n * Deliberately typed over `\"create\" | \"update\"` alone, never the third\n * {@link NodeClaimOperation} `\"resurrect\"`: this projection feeds the per-graph\n * LOCK, whose trigger set this workstream leaves byte-identical to HEAD's, and\n * a resurrect's disjointness claim needs none — `insertUnique`'s own\n * `INSERT … ON CONFLICT … RETURNING` fences it, the same primary key that\n * already fences an own-kind uniqueness claim with no lock. `nodeClaimEntries`\n * reads `nodeClaimSites` at `\"resurrect\"` directly (see\n * `claims/node-claims.ts:planNodeClaimReinsert`) without going through this\n * projection at all.\n */\nexport function nodeWriteNeedsConstraintFence(\n registry: KindRegistry,\n kind: string,\n uniqueConstraints: readonly UniqueConstraint[],\n operation: \"create\" | \"update\",\n): ConstraintFenceReason | undefined {\n return nodeClaimSites(registry, kind, uniqueConstraints, operation).find(\n (site) => site.needsLockFence,\n )?.refusalReason;\n}\n\n/**\n * THE graph-level answer to \"does writing into this graph owe a claim that must\n * precede the row it gates?\", folded over the SAME per-kind functions the write\n * paths consult — a node kind any of whose claim sites is `pre-insert` under\n * either operation, or an edge kind whose cardinality is not `many`.\n *\n * It exists for `importGraph`, which takes no per-graph lock and therefore\n * cannot declare `fencesConstraintProbe`: that option carries a second decision\n * — take the lock — and holding a per-graph mutex for a whole bulk load is a\n * different change with a different owner. The CONSUMPTION is split; the\n * definition is not.\n *\n * BOTH operations are folded because an import performs both, and the answer is\n * needed before the payload is inspected. That makes the fold coarser than the\n * per-row seam on purpose: a payload whose every row fails its constraints'\n * `where` predicates owes nothing, yet the import is refused. That is the price\n * of answering up front — and answering up front is what makes the refusal\n * deterministic across a chunked stream, which imports per chunk and would\n * otherwise fail on chunk k with k-1 chunks already committed.\n *\n * It lives here rather than beside {@link nodeClaimSites} because it also folds\n * {@link edgeWriteNeedsConstraintFence}, and this module is the one that already\n * sees both per-kind predicates.\n */\nexport function graphOwesClaims(\n graph: GraphDef,\n registry: KindRegistry,\n): ConstraintFenceReason | undefined {\n for (const [kind, registration] of Object.entries(graph.nodes)) {\n for (const operation of [\"create\", \"update\"] as const) {\n const gating = nodeClaimSites(\n registry,\n kind,\n registration.unique ?? [],\n operation,\n ).find((site) => site.placement === \"pre-insert\");\n if (gating !== undefined) return gating.refusalReason;\n }\n }\n for (const registration of Object.values(graph.edges)) {\n const reason = edgeWriteNeedsConstraintFence(\n registration.cardinality ?? \"many\",\n );\n if (reason !== undefined) return reason;\n }\n return undefined;\n}\n\n/**\n * Checks disjointness constraints for a node.\n *\n * Ensures that a node with a given ID doesn't exist in any disjoint kinds.\n *\n * @throws ValidationError if disjointness constraint is violated\n */\nexport async function checkDisjointnessConstraint(\n ctx: ConstraintContext,\n kind: string,\n id: string,\n): Promise<void> {\n // Get all kinds that are disjoint with this kind\n const disjointKinds = ctx.registry.getDisjointKinds(kind);\n\n // For each disjoint kind, check if a node with this ID exists\n for (const disjointKind of disjointKinds) {\n const existing = await ctx.backend.getNode(ctx.graphId, disjointKind, id);\n if (existing && !existing.deleted_at) {\n const error = checkDisjointness(id, kind, [disjointKind], ctx.registry);\n if (error) throw error;\n }\n }\n}\n\n/**\n * Checks cardinality constraints for an edge.\n *\n * Reads {@link EDGE_CARDINALITY_SPECS} rather than re-spelling each\n * cardinality's rules: which endpoints the axis covers (`keyShape`), whether an\n * edge born already ended joins the population at all (`claimsWhenBornEnded`)\n * and whether the population is the live one or the active one\n * (`holderLiveness`) are the same three facts the claim's SQL reads. A probe\n * that spelled its own copy would be the drift that accepts a write the fence\n * then refuses (or the reverse).\n *\n * @throws CardinalityError if cardinality constraint is violated\n */\nexport async function checkCardinalityConstraint(\n ctx: ConstraintContext,\n edgeKind: string,\n cardinality: Cardinality,\n fromKind: string,\n fromId: string,\n toKind: string,\n toId: string,\n validTo: string | undefined,\n): Promise<void> {\n if (cardinality === \"many\") return;\n const spec = EDGE_CARDINALITY_SPECS[cardinality];\n\n // An edge born ended never joins an active-only population, so it has\n // nothing to check and nothing to claim.\n if (!spec.claimsWhenBornEnded && validTo !== undefined) return;\n\n if (spec.keyShape === \"fromAndTo\") {\n const exists = await ctx.backend.edgeExistsBetween({\n graphId: ctx.graphId,\n edgeKind,\n fromKind,\n fromId,\n toKind,\n toId,\n });\n const error = checkUniqueEdge(\n edgeKind,\n fromKind,\n fromId,\n toKind,\n toId,\n exists ? 1 : 0,\n );\n if (error) throw error;\n return;\n }\n\n const count = await ctx.backend.countEdgesFrom({\n graphId: ctx.graphId,\n edgeKind,\n fromKind,\n fromId,\n activeOnly: spec.holderLiveness === \"liveAndActive\",\n });\n const error = checkCardinality(\n edgeKind,\n fromKind,\n fromId,\n cardinality,\n count,\n count > 0,\n );\n if (error) throw error;\n}\n","/**\n * The in-batch cardinality accounting an edge batch validates against.\n *\n * A batch decides every row before it writes any of them, so a probe that read\n * only the database would let two rows of one batch each see \"no conflict\" and\n * both land — the in-batch collision. This wrapper is the state that closes\n * that: it overlays the reads a cardinality probe makes (`countEdgesFrom`,\n * `edgeExistsBetween`) with the rows the batch has already accepted, so row\n * k+1's probe sees rows 1..k and refuses per ROW rather than at the flush.\n *\n * It lives in its own module because it has two callers that reach it from\n * different directions: the store's batch create path\n * ({@link file://./edge-operations.ts prepareEdgeBatchCreates}) and\n * `interchange/import`'s edge slice. One owner of in-batch cardinality\n * accounting, not two implementations — a second copy is exactly how import's\n * edge path came to have none at all.\n *\n * It is a read overlay only. The CLAIM is issued against the real backend, once\n * per batch, by the caller — a claim against this wrapper would still reach the\n * real target (`deriveBackend` forwards every non-overlaid member) but\n * would be a second, unsorted, per-row claim in addition to the batch's.\n */\nimport { deriveBackend } from \"../../backend/derive-backend\";\nimport { type GraphBackend, type InsertEdgeParams } from \"../../backend/types\";\nimport { type Cardinality } from \"../../core/types\";\nimport { encodeTupleKey } from \"../../utils/tuple-key\";\nimport { type WriteTarget } from \"./write-session\";\n\nfunction buildEdgeEndpointCacheKey(\n graphId: string,\n kind: string,\n id: string,\n): string {\n return encodeTupleKey([graphId, kind, id]);\n}\n\nfunction buildEdgeFromCacheKey(\n graphId: string,\n edgeKind: string,\n fromKind: string,\n fromId: string,\n): string {\n return encodeTupleKey([graphId, edgeKind, fromKind, fromId]);\n}\n\nfunction buildEdgeBetweenCacheKey(\n graphId: string,\n edgeKind: string,\n fromKind: string,\n fromId: string,\n toKind: string,\n toId: string,\n): string {\n return encodeTupleKey([graphId, edgeKind, fromKind, fromId, toKind, toId]);\n}\n\nfunction buildCountEdgesFromCacheKey(\n params: Parameters<GraphBackend[\"countEdgesFrom\"]>[0],\n): string {\n const activeOnly = params.activeOnly === true ? \"1\" : \"0\";\n return encodeTupleKey([\n params.graphId,\n params.edgeKind,\n params.fromKind,\n params.fromId,\n activeOnly,\n ]);\n}\n\nfunction incrementPendingCount(counts: Map<string, number>, key: string): void {\n const previous = counts.get(key) ?? 0;\n counts.set(key, previous + 1);\n}\n\nexport function createEdgeBatchValidationBackend(\n backend: WriteTarget,\n): Readonly<{\n backend: WriteTarget;\n registerPendingEdgeForCardinality: (\n insertParams: InsertEdgeParams,\n cardinality: Cardinality,\n ) => void;\n seedEndpointRow: (\n graphId: string,\n kind: string,\n id: string,\n row: Awaited<ReturnType<GraphBackend[\"getNode\"]>>,\n ) => void;\n}> {\n const endpointCache = new Map<\n string,\n Awaited<ReturnType<GraphBackend[\"getNode\"]>>\n >();\n const countEdgesFromCache = new Map<string, number>();\n const edgeExistsCache = new Map<string, boolean>();\n const pendingOneCounts = new Map<string, number>();\n const pendingOneActiveCounts = new Map<string, number>();\n const pendingUniquePairs = new Set<string>();\n\n async function getNodeCached(\n graphId: string,\n kind: string,\n id: string,\n ): Promise<Awaited<ReturnType<GraphBackend[\"getNode\"]>>> {\n const cacheKey = buildEdgeEndpointCacheKey(graphId, kind, id);\n if (endpointCache.has(cacheKey)) {\n return endpointCache.get(cacheKey);\n }\n const node = await backend.getNode(graphId, kind, id);\n endpointCache.set(cacheKey, node);\n return node;\n }\n\n // Lets batch preparation prime the endpoint cache from one getNodes\n // round trip per (kind) instead of a per-edge getNode probe for each\n // from/to endpoint — mirrors seedNodeRow in createNodeBatchValidationBackend.\n // Seeding an absent result (`undefined`) is meaningful — it marks the key\n // as known-missing so the per-edge check skips the backend read. An\n // earlier lookup or seed always wins; seeding never overwrites.\n function seedEndpointRow(\n graphId: string,\n kind: string,\n id: string,\n row: Awaited<ReturnType<GraphBackend[\"getNode\"]>>,\n ): void {\n const cacheKey = buildEdgeEndpointCacheKey(graphId, kind, id);\n if (endpointCache.has(cacheKey)) return;\n endpointCache.set(cacheKey, row);\n }\n\n async function countEdgesFromCached(\n params: Parameters<GraphBackend[\"countEdgesFrom\"]>[0],\n ): Promise<number> {\n const cacheKey = buildCountEdgesFromCacheKey(params);\n let baseCount = countEdgesFromCache.get(cacheKey);\n if (baseCount === undefined) {\n baseCount = await backend.countEdgesFrom(params);\n countEdgesFromCache.set(cacheKey, baseCount);\n }\n const pendingKey = buildEdgeFromCacheKey(\n params.graphId,\n params.edgeKind,\n params.fromKind,\n params.fromId,\n );\n const pendingCount =\n params.activeOnly === true ?\n (pendingOneActiveCounts.get(pendingKey) ?? 0)\n : (pendingOneCounts.get(pendingKey) ?? 0);\n return baseCount + pendingCount;\n }\n\n async function edgeExistsBetweenCached(\n params: Parameters<GraphBackend[\"edgeExistsBetween\"]>[0],\n ): Promise<boolean> {\n const cacheKey = buildEdgeBetweenCacheKey(\n params.graphId,\n params.edgeKind,\n params.fromKind,\n params.fromId,\n params.toKind,\n params.toId,\n );\n if (pendingUniquePairs.has(cacheKey)) {\n return true;\n }\n if (edgeExistsCache.has(cacheKey)) {\n return edgeExistsCache.get(cacheKey) ?? false;\n }\n const exists = await backend.edgeExistsBetween(params);\n edgeExistsCache.set(cacheKey, exists);\n return exists;\n }\n\n function registerPendingEdgeForCardinality(\n insertParams: InsertEdgeParams,\n cardinality: Cardinality,\n ): void {\n const fromCacheKey = buildEdgeFromCacheKey(\n insertParams.graphId,\n insertParams.kind,\n insertParams.fromKind,\n insertParams.fromId,\n );\n if (cardinality === \"one\") {\n incrementPendingCount(pendingOneCounts, fromCacheKey);\n return;\n }\n if (cardinality === \"oneActive\") {\n if (insertParams.validTo === undefined) {\n incrementPendingCount(pendingOneActiveCounts, fromCacheKey);\n }\n return;\n }\n if (cardinality === \"unique\") {\n const uniqueCacheKey = buildEdgeBetweenCacheKey(\n insertParams.graphId,\n insertParams.kind,\n insertParams.fromKind,\n insertParams.fromId,\n insertParams.toKind,\n insertParams.toId,\n );\n pendingUniquePairs.add(uniqueCacheKey);\n }\n }\n\n const validationBackend = deriveBackend(backend, {\n getNode: getNodeCached,\n countEdgesFrom: countEdgesFromCached,\n edgeExistsBetween: edgeExistsBetweenCached,\n } satisfies Partial<WriteTarget>);\n\n return {\n backend: validationBackend,\n registerPendingEdgeForCardinality,\n seedEndpointRow,\n };\n}\n","/**\n * Composable edge write steps — the edge counterpart of\n * `node-write-pipeline.ts`.\n *\n * An edge mutation is a row write plus the CLAIM its declared cardinality owes.\n * Edges reserve no uniqueness entries, carry no fulltext rows and hold no\n * embeddings, so there are no sync fans to keep in step with the row — but the\n * cardinality claim is a sidecar in every sense that matters: it is written to a\n * different relation, in a fixed position relative to the row (before the write\n * it fences, after the write it cleans up), and a path that applied the row\n * without it would leave the constraint enforced by nothing but a probe. That is\n * why the claim travels ON the work record and is issued HERE rather than by the\n * operations module that decided it: the decision is a pure function of the\n * verdict the caller reached, and the write is a backend member only a step may\n * spell.\n *\n * The insert shapes are NOT here: `insert-dispatch.ts` already owns \"which of\n * the four insert members this backend supports\", for edges as much as for\n * nodes, and a pass-through step would be a second owner of that decision.\n *\n * The steps assume they run inside a write transaction (see\n * {@link runInWriteTransaction}); they perform no transaction management of\n * their own.\n */\nimport { type ClaimsVerdictThunk } from \"../../backend/capabilities/resolve\";\nimport {\n type BackendValidityEndMutation,\n type ClaimEdgeCardinalityParams,\n type EdgeRow,\n type GraphBackend,\n type TransactionBackend,\n type UpdateEdgeParams,\n} from \"../../backend/types\";\nimport { claimEdgeCardinality, purgeEdgeClaims } from \"../claims/edge-claims\";\nimport { type GraphWriteLock } from \"../recorded-capture/clock\";\nimport { type WriteParamsDraft } from \"./write-fences\";\n\ntype Backend = GraphBackend | TransactionBackend;\n\n/**\n * The graph-scoped state the edge write steps need.\n *\n * `lock` is compile-time evidence that the per-graph write-lock discipline was\n * satisfied BEFORE any row work (see {@link GraphWriteLock}), exactly as\n * {@link NodeWriteContext} requires it: the pipeline performs no locking of its\n * own, so requiring the token here makes \"row write before lock\" a type error\n * at the call site instead of a lock-order inversion in review. There is no\n * registry, because an edge write resolves no schema and no constraints — the\n * caller validated the props before the transaction opened.\n *\n * `claimsVerdict` is the `claims` bundle's memoized, at-most-once verdict\n * thunk (ruling B7 refinement 2), called at each site below that issues or\n * releases an edge-cardinality claim.\n */\nexport type EdgeWriteContext = Readonly<{\n graphId: string;\n lock: GraphWriteLock;\n claimsVerdict: ClaimsVerdictThunk;\n}>;\n\n/** Builds an {@link EdgeWriteContext} — the one constructor every call site shares. */\nexport function createEdgeWriteContext(\n graphId: string,\n lock: GraphWriteLock,\n claimsVerdict: ClaimsVerdictThunk,\n): EdgeWriteContext {\n return { graphId, lock, claimsVerdict };\n}\n\n/**\n * One edge update, minus every predicate the write's verdicts read.\n *\n * The asserted identity components and the asserted validity lower bound are\n * NOT here: they are the write's fences, applied by\n * `EDGE_UPDATE_FENCE_APPLIERS` into the draft this step is handed alongside\n * the work. An update that forgot to carry a bound its verdict consumed\n * therefore cannot be spelled — the fence record's keys are required — while\n * the work stays exactly \"what this write intends to change\".\n */\nexport type EdgeUpdateWork = Readonly<{\n id: string;\n props: Record<string, unknown>;\n /** See {@link UpdateEdgeParams.validFrom}: stored on the resurrecting leg. */\n validFrom?: string;\n clearDeleted?: boolean;\n /**\n * The cardinality claim this update owes, present only when the write\n * RE-ADMITS the row to the population its cardinality constrains — a\n * resurrection, or a reopened `oneActive` window. Built by the caller (a pure\n * function of the verdict it reached) and ISSUED here, at its PRE-INSERT\n * placement: the probe that authorised the write read a population no key\n * fences, so the claim row is what refuses a peer that read the same\n * population, and a claim issued after the row it fences is not a fence.\n */\n claim?: ClaimEdgeCardinalityParams;\n}> &\n // The window END is the SAME discriminated pair `UpdateEdgeParams` declares,\n // not a re-spelling with two independent optionals: \"state an end\" and \"clear\n // the end\" are mutually exclusive, and reusing the union is what makes the\n // spread below type-check without the step re-asserting the exclusivity.\n BackendValidityEndMutation;\n\n/**\n * Applies an edge update: the fenced UPDATE, and nothing else.\n *\n * Both halves of the statement's `WHERE` arrive as the draft — the identity\n * components the caller ASSERTED and, when its verdict read one, the stored\n * lower bound — so the row this writes is provably the row that was judged.\n * The step does not decide which of them to carry; the appliers did, from the\n * fence record the caller had to state.\n *\n * A zero-row result is NOT interpreted here. The backend's\n * `DatabaseOperationError` propagates unchanged, because the two callers of\n * this step read \"matched nothing\" differently — the store re-reads and either\n * converges or refuses ({@link withUnmatchedEdgeUpdateRefusal}), interchange\n * import records a per-row conflict and continues — and a fused unit owns row\n * plus fences plus sidecars, not one error policy for every caller.\n */\nexport async function applyEdgeUpdate(\n ctx: EdgeWriteContext,\n args: EdgeUpdateWork & WriteParamsDraft,\n backend: Backend,\n): Promise<EdgeRow> {\n const { claim, ...rowWork } = args;\n if (claim !== undefined) {\n await claimEdgeCardinality(backend, ctx.claimsVerdict(), claim);\n }\n // Every key of the work record and of the fence draft is a field of\n // `UpdateEdgeParams`, and both are built with the same \"present only when\n // stated\" discipline the call site used to apply field by field, so the\n // spread emits exactly the params the hand-built object emitted.\n const updateParams: UpdateEdgeParams = { graphId: ctx.graphId, ...rowWork };\n return backend.updateEdge(updateParams);\n}\n\n/**\n * One edge delete, soft or hard.\n *\n * `kind` is the identity this delete ASSERTS the target row already carries\n * (see {@link UpdateEdgeParams.kind}); it rides in the work rather than in a\n * fence record because a delete states nothing else and has no verdict to\n * fence — the statement IS its own recheck.\n */\nexport type EdgeDeleteWork = Readonly<{\n id: string;\n kind: string;\n}>;\n\n/** Tombstones one edge, asserting the kind the caller resolved it under. */\nexport function applyEdgeSoftDelete(\n ctx: EdgeWriteContext,\n work: EdgeDeleteWork,\n backend: Backend,\n): Promise<void> {\n return backend.deleteEdge({\n graphId: ctx.graphId,\n id: work.id,\n kind: work.kind,\n });\n}\n\n/**\n * One edge hard delete: the row, plus whether this kind holds a cardinality\n * claim to give back.\n *\n * The flag is DATA the caller decides from the kind's declaration, not a\n * capability probe: an unconstrained kind never claimed the axis and must pay no\n * statement for releasing one, which is the same rule its create follows.\n */\nexport type EdgeHardDeleteWork = EdgeDeleteWork &\n Readonly<{ holdsCardinalityClaim: boolean }>;\n\n/**\n * Permanently removes one edge, asserting the same kind, and releases the claim\n * it held.\n *\n * The release is POST-write housekeeping, not a fence: the claim's liveness\n * predicate already reads a row that is about to be gone, so the axis is\n * takeable either way. Dropping the row keeps the relation from growing by one\n * row per hard-deleted constrained edge.\n */\nexport async function applyEdgeHardDelete(\n ctx: EdgeWriteContext,\n work: EdgeHardDeleteWork,\n backend: Backend,\n): Promise<void> {\n await backend.hardDeleteEdge({\n graphId: ctx.graphId,\n id: work.id,\n kind: work.kind,\n });\n if (work.holdsCardinalityClaim) {\n await purgeEdgeClaims(backend, ctx.claimsVerdict(), ctx.graphId, [work.id]);\n }\n}\n","/**\n * What a write's verdicts READ, carried into the statement that honors them.\n *\n * Every member of a fence record is the predicate itself, never a flag a\n * caller re-derives one from. That shape already exists in this codebase —\n * `ValidityWindowVerdict.storedLowerBoundFence` hands back the\n * `expectedValidFrom` object rather than a boolean, and its docstring names\n * the over-fencing defect that shape closed — and this module generalizes it\n * per row-work kind.\n *\n * ## Why every key is REQUIRED\n *\n * `{}` is how a fence says \"assert nothing\", and it is the ONLY way to say it.\n * An optional key would reintroduce the absent state that the verdict shape\n * eliminated: \"I forgot to pass the fence\" and \"this write asserts nothing\"\n * would look identical at the call site, and the compiler could not tell them\n * apart either. With the key required, forgetting it is a type error and an\n * unfenced write is a stated decision.\n *\n * ## Why the applier maps are total\n *\n * Each map is `satisfies { [K in keyof F]-?: FenceApplier<F, K> }`, so a fence\n * key without an applier fails compilation. A fence a kind's statement cannot\n * carry is REFUSED by its applier, naming the fence and the kind — applied or\n * refused, never silently dropped.\n */\nimport {\n assertsStoredLowerBound,\n assertsStoredUpperBound,\n type ValidityLowerBoundFence,\n type ValidityUpperBoundFence,\n} from \"../../utils/date\";\nimport { type EdgeIdentityExpectation } from \"./edge-identity\";\n\n/**\n * The row-work shapes a fence can be applied to. Not {@link RowWorkKind}: a\n * node has two statement families with different fence capabilities (the\n * single-row UPDATE carries `expectedValidFrom`; the set UPDATE has no field\n * for it), and the refusal has to name which one refused.\n */\nexport type WriteFenceKind = \"nodeUpdate\" | \"nodeSetUpdate\" | \"edgeUpdate\";\n\n/**\n * The mutable predicate fields a fence applier may contribute to the write's\n * params. It is a DRAFT, not the params: the applier's whole job is to write\n * the predicate its fence states, and nothing else about the statement is\n * reachable from here.\n */\nexport interface WriteParamsDraft {\n expectedValidFrom?: string | null;\n expectedValidTo?: string | null;\n kind?: string;\n fromKind?: string;\n fromId?: string;\n toKind?: string;\n toId?: string;\n}\n\n/** A fresh, empty draft — the state \"this write asserts nothing yet\". */\nexport function createWriteParamsDraft(): WriteParamsDraft {\n return {};\n}\n\n/** Applies one fence key's predicate to the draft. */\ntype FenceApplier<F, K extends keyof F> = (\n fence: F[K],\n draft: WriteParamsDraft,\n) => void;\n\n/** A total applier map for a fence record: one applier per key, no key spare. */\nexport type FenceApplierMap<F> = { [K in keyof F]-?: FenceApplier<F, K> };\n\n/** The fences a single-row node UPDATE can carry. */\nexport type NodeUpdateFences = Readonly<{\n validityLowerBound: ValidityLowerBoundFence;\n}>;\n\n/**\n * The fences a set-based node UPDATE can carry. Same key as\n * {@link NodeUpdateFences}, DIFFERENT applier: `UpdateNodeSetParams` has no\n * `expectedValidFrom` field, so `{}` is the only value this kind can honor.\n */\nexport type NodeSetUpdateFences = Readonly<{\n validityLowerBound: ValidityLowerBoundFence;\n}>;\n\n/** The fences an edge UPDATE can carry. */\nexport type EdgeUpdateFences = Readonly<{\n validityLowerBound: ValidityLowerBoundFence;\n /**\n * The window END the verdict read. Non-empty only for a reopen that re-admits\n * the row to a counted population it was excluded from — the `oneActive`\n * case — because that verdict is the one that consumed the stored `valid_to`.\n */\n validityUpperBound: ValidityUpperBoundFence;\n /** The identity components the caller asserted; each optional INSIDE. */\n edgeIdentity: EdgeIdentityExpectation;\n}>;\n\n/**\n * Whether an edge update asserts ANY window state — the single owner of the\n * question the unmatched-update diagnosis asks.\n *\n * The diagnosis has to know whether \"no row matched\" could have been the window\n * predicates rather than the identity ones, and it must reach that answer from\n * the same two predicates the appliers consult. Re-deriving it from the emitted\n * params (which the diagnosis never sees) is how the copies drift.\n */\nexport function assertsStoredWindowState(fences: EdgeUpdateFences): boolean {\n return (\n assertsStoredLowerBound(fences.validityLowerBound) ||\n assertsStoredUpperBound(fences.validityUpperBound)\n );\n}\n\n/**\n * A fence the row work's statement has no field to carry.\n *\n * INTERNAL, with no allocated public error code, following\n * `EdgeUpdateTargetMoved`: no user-stated option can reach it — it fires only\n * when a write path hands a fence to a statement family that cannot express\n * it — so a public code would document a state users cannot produce. It is\n * exported for the tests that pin the refusal, not for callers to catch.\n */\nexport class UnsupportedWriteFenceError extends Error {\n readonly fence: string;\n readonly kind: WriteFenceKind;\n\n constructor(fence: string, kind: WriteFenceKind) {\n super(\n `The ${kind} statement cannot carry the \"${fence}\" fence, so the write ` +\n `is refused rather than run unfenced. Assert nothing ({}) or use a ` +\n `write shape whose statement carries it.`,\n );\n this.name = \"UnsupportedWriteFenceError\";\n this.fence = fence;\n this.kind = kind;\n }\n}\n\n/**\n * Carries the bound the verdict READ into the statement's own predicate.\n *\n * `assertsStoredLowerBound` owns the emptiness test — the same predicate\n * `node-write-pipeline.ts` consults when it builds the update params — so the\n * seam that validates a fence and the step that carries it cannot disagree\n * about what an empty fence is.\n */\nfunction applyValidityLowerBound(\n fence: ValidityLowerBoundFence,\n draft: WriteParamsDraft,\n): void {\n if (!assertsStoredLowerBound(fence)) return;\n draft.expectedValidFrom = fence.expectedValidFrom;\n}\n\nexport const NODE_UPDATE_FENCE_APPLIERS = {\n validityLowerBound: applyValidityLowerBound,\n} as const satisfies FenceApplierMap<NodeUpdateFences>;\n\n/**\n * The refusal branch. It is REACHABLE and TYPE-LEGAL: the record's one key is\n * required and `ValidityLowerBoundFence` legitimately carries\n * `expectedValidFrom`, so a caller can hand a set update a stated bound with\n * no cast and no unknown key. There is nowhere to put it in\n * `UpdateNodeSetParams`, so the write is refused rather than run unfenced.\n *\n * No caller reaches it today — the set-update path is props-only — and the\n * guard is what keeps that true when a future set update grows a window.\n */\nexport const NODE_SET_UPDATE_FENCE_APPLIERS = {\n validityLowerBound: (fence) => {\n if (!assertsStoredLowerBound(fence)) return;\n throw new UnsupportedWriteFenceError(\"validityLowerBound\", \"nodeSetUpdate\");\n },\n} as const satisfies FenceApplierMap<NodeSetUpdateFences>;\n\n/**\n * Carries every identity component the caller ASSERTED into the statement's\n * `WHERE`, so the row an edge update writes is provably the row that was\n * judged. Kind is always asserted; an endpoint component is asserted only when\n * the caller claimed it, because a component nobody claimed must not become a\n * predicate that refuses legitimate writes.\n */\nfunction applyEdgeIdentity(\n fence: EdgeIdentityExpectation,\n draft: WriteParamsDraft,\n): void {\n draft.kind = fence.kind;\n if (fence.fromKind !== undefined) draft.fromKind = fence.fromKind;\n if (fence.fromId !== undefined) draft.fromId = fence.fromId;\n if (fence.toKind !== undefined) draft.toKind = fence.toKind;\n if (fence.toId !== undefined) draft.toId = fence.toId;\n}\n\n/**\n * Carries the window END the verdict READ, on the same terms as its\n * lower-bound counterpart: present only when the verdict consulted it.\n */\nfunction applyValidityUpperBound(\n fence: ValidityUpperBoundFence,\n draft: WriteParamsDraft,\n): void {\n if (!assertsStoredUpperBound(fence)) return;\n draft.expectedValidTo = fence.expectedValidTo;\n}\n\nexport const EDGE_UPDATE_FENCE_APPLIERS = {\n validityLowerBound: applyValidityLowerBound,\n validityUpperBound: applyValidityUpperBound,\n edgeIdentity: applyEdgeIdentity,\n} as const satisfies FenceApplierMap<EdgeUpdateFences>;\n\n/**\n * Applies EVERY declared fence of a record to the draft.\n *\n * Iterating the applier map — which the type system pins total over the fence\n * record's keys — is what makes \"accepted, then ignored\" unrepresentable: a\n * key exists on the record only if an applier exists for it, and every applier\n * in the map runs. A per-kind dispatcher that named its keys by hand could\n * silently skip one; this cannot.\n */\nexport function applyWriteFences<F extends object>(\n appliers: FenceApplierMap<F>,\n fences: F,\n draft: WriteParamsDraft,\n): void {\n for (const key of Object.keys(appliers) as (keyof F)[]) {\n // One localized widening: indexing the map with a key UNION yields a union\n // of applier signatures, which TypeScript will not call even though every\n // member accepts the value indexed out of the record with the same key.\n // The map's totality is asserted by its `satisfies` clause, so the pairing\n // is sound; the cast only tells the compiler the keys line up.\n const applier: (fence: F[keyof F], draft: WriteParamsDraft) => void =\n appliers[key];\n applier(fences[key], draft);\n }\n}\n","/**\n * The only sanctioned surface that mutates graph state.\n *\n * Every method is a FUSED unit — the primary row plus every sidecar that row\n * obliges — so \"a new write path forgot a sidecar\" stops being expressible:\n * there is no row-only primitive for a migrated module to call, because the\n * raw backend members are banned outside the step and sidecar modules the\n * session composes.\n *\n * ## Names\n *\n * Deliberately disjoint from `WRITE_MEMBER_KEYS`. The lint rule that certifies\n * this migration is `no-restricted-syntax`, which is receiver-blind: a session\n * method named `insertNode` would be flagged by the very rule that enforces\n * the seam. Renaming is chosen over a type-aware rule because the alternative\n * is a custom rule package plus type information on the lint program — real\n * infrastructure, bought only to permit a name collision we do not need.\n *\n * ## The type grows per batch, and that is load-bearing\n *\n * A method exists only once the step module it delegates to exists. B0 shipped\n * the eight node methods whose delegates (`node-write-pipeline.ts`'s four\n * steps, `insert-dispatch.ts`'s four insert shapes) were already here; B1b\n * added `reviseNodeSet` in the same commit as `applyNodeSetUpdate`, and B2\n * added the seven edge methods in the same commit as `edge-write-pipeline.ts`.\n * That schedule is what lets this module spell NO banned member call at any\n * commit — which is why it needs no lint exemption on the day it lands or on\n * any day after.\n *\n * ## Four insert shapes, not three\n *\n * `insert-dispatch.ts` exposes `one`, `oneNoReturn`, `batch` and\n * `batchReturning`, and all four are live today. `createNodes` maps to the\n * RETURNING batch; `createNodesNoReturn` maps to the no-return batch.\n * Collapsing the two would make the migrating call sites emit\n * `insertNodesBatchReturning` where they emit `insertNodesBatch` today — a\n * statement change the no-behavior-change invariant forbids.\n */\nimport { type z } from \"zod\";\n\nimport { type UNIQUE_SIDECAR_BATCH } from \"../../backend/capabilities/bundle-registry\";\nimport {\n type BundleVerdictOf,\n type ClaimsVerdictThunk,\n} from \"../../backend/capabilities/resolve\";\nimport {\n type BackendIdentity,\n type ClaimEdgeCardinalityParams,\n type EdgeRow,\n type FulltextOperationBackend,\n type GraphBackend,\n type GraphEntityReadBackend,\n type InsertEdgeParams,\n type InsertNodeParams,\n type LiveNodeRow,\n type NodeRow,\n type QueryExecutionBackend,\n type RawQueryExecutionBackend,\n type RawStatementExecutionBackend,\n type SchemaReadBackend,\n type SqlCompilationBackend,\n type TombstonedNodeRow,\n type TransactionBackend,\n type UniqueConstraintBackend,\n type VectorOperationBackend,\n} from \"../../backend/types\";\nimport { type DeleteBehavior, type UniqueConstraint } from \"../../core/types\";\nimport { type KindRegistry } from \"../../registry/kind-registry\";\nimport { type Assert, type Equal } from \"../../utils/type-assert\";\nimport {\n claimEdgeCardinality,\n claimEdgeCardinalityBatch,\n} from \"../claims/edge-claims\";\nimport {\n type NodeClaimItem,\n withNodeCreateClaims,\n withNodeCreateClaimsBatch,\n} from \"../claims/node-claims\";\nimport {\n edgeInsertDispatch,\n nodeInsertDispatch,\n runInsertBatch,\n runInsertBatchReturning,\n runInsertNoReturn,\n} from \"../insert-dispatch\";\nimport { type GraphWriteLock } from \"../recorded-capture/clock\";\nimport {\n applyEdgeHardDelete,\n applyEdgeSoftDelete,\n applyEdgeUpdate,\n createEdgeWriteContext,\n type EdgeDeleteWork,\n type EdgeHardDeleteWork,\n type EdgeUpdateWork,\n} from \"./edge-write-pipeline\";\nimport {\n applyNodeHardDelete,\n applyNodeInsertSyncFans,\n applyNodeInsertSyncFansBatch,\n applyNodeResurrect,\n applyNodeSetUpdate,\n applyNodeSoftDelete,\n applyNodeUpdate,\n createNodeWriteContext,\n type NodeDeletePolicy,\n type NodeSetUpdateResult,\n type NodeSetUpdateWork,\n type NodeUpdateTarget,\n} from \"./node-write-pipeline\";\nimport {\n applyWriteFences,\n createWriteParamsDraft,\n EDGE_UPDATE_FENCE_APPLIERS,\n type EdgeUpdateFences,\n NODE_SET_UPDATE_FENCE_APPLIERS,\n NODE_UPDATE_FENCE_APPLIERS,\n type NodeSetUpdateFences,\n type NodeUpdateFences,\n} from \"./write-fences\";\nimport { type WriteMemberKey } from \"./write-members\";\n\n/**\n * The backend handle row work receives: a FACET COMPOSITION of the read\n * surfaces, never `Omit<GraphBackend | TransactionBackend, …>`.\n *\n * `Omit` over a union does not distribute — `keyof (A | B)` is the\n * INTERSECTION of the key sets — so an `Omit` here would silently collapse to\n * the members both alternatives have, and every top-level-only member would\n * vanish without anyone saying so. `TransactionBackend` and\n * `TransactionReadBackend` are the existing precedents for stating the\n * composition explicitly.\n *\n * This is a TYPE-ONLY projection. At runtime the executor hands row work the\n * very object `runInWriteTransaction` gave it: a runtime projection would\n * allocate per write and would destroy the `\"transaction\" in target`\n * discrimination the layers above depend on.\n */\nexport type WriteTarget = Readonly<\n BackendIdentity &\n GraphEntityReadBackend &\n SchemaReadBackend &\n QueryExecutionBackend &\n SqlCompilationBackend &\n RawQueryExecutionBackend &\n RawStatementExecutionBackend &\n Pick<UniqueConstraintBackend, \"checkUnique\" | \"checkUniqueBatch\"> &\n Pick<VectorOperationBackend, \"vectorSearch\"> &\n Pick<FulltextOperationBackend, \"fulltextSearch\">\n>;\n\n/**\n * THE COUNTED HOLE: widens the row-work projection back to the full backend\n * union.\n *\n * It existed because the migration moved call sites one module at a time while\n * their preparation helpers, constraint probes, uniqueness probes and identity\n * hooks were still typed `GraphBackend | TransactionBackend`; re-typing all of\n * those in the same batch that moved the call sites would have made every batch\n * a whole-module retype. So the widening was EXPLICIT, NAMED and COUNTED, and\n * the ratchet drove the count down as those signatures were re-typed. An `as`\n * cast at each site would have been the same unsoundness with no counter.\n *\n * **Exactly one caller remains, and it is structural, not debt.**\n * `executeEdgeBulkGetOrCreateByEndpoints` runs nested managed writes inside its\n * own frame: each nested leg re-enters the executor against THIS transaction\n * target, and re-entry needs the full union by construction — it mints a\n * session, which writes. Inlining those legs' row work would drop the nested\n * frames' schema fence and revision-clock advance, i.e. change behavior. The\n * ratchet therefore records ONE as a reasoned floor, the same way it records\n * two permanently allowlisted managed-write entry points, rather than pretending\n * a zero it would have to buy with a statement change.\n */\nexport function unfencedTarget(\n target: WriteTarget,\n): GraphBackend | TransactionBackend {\n return target as GraphBackend | TransactionBackend;\n}\n\n/** The graph-scoped state every session method's step modules need. */\nexport type WriteSessionContext = Readonly<{\n graphId: string;\n registry: KindRegistry;\n /**\n * The `claims` bundle's memoized, at-most-once verdict thunk (ruling B7\n * refinement 2). Called at the site that needs it — never hoisted into\n * store construction, which would resolve it eagerly and break a\n * contradictory-declaration backend's ability to construct a store at all.\n */\n claimsVerdict: ClaimsVerdictThunk;\n /**\n * The `uniqueSidecarBatch` bundle's verdict (ruling B8 spec item 2),\n * resolved once at store construction (or once per import call) and\n * threaded here for `createNodeWriteContext` — never re-resolved.\n */\n uniqueSidecarBatch: BundleVerdictOf<typeof UNIQUE_SIDECAR_BATCH>;\n}>;\n\n/** The derived data a node insert obliges, alongside the row itself. */\ntype NodeInsertSideEffects = Readonly<{\n kind: string;\n id: string;\n schema: z.ZodType;\n props: Record<string, unknown>;\n uniqueConstraints: readonly UniqueConstraint[];\n}>;\n\n/**\n * One node insert: the row params, the claims the row owes, and the sidecar\n * inputs, as ONE value. They travel together because they are applied together;\n * a caller cannot hand over the row and keep either half to itself.\n *\n * The claim item is the DECLARATION the claim seam reads its entries from — not\n * the entries themselves — because the seam owns both \"what claims does this row\n * owe\" and \"when is each due\", and a caller that could hand over a prepared\n * entry list could hand over a shorter one.\n */\nexport type NodeInsertWork = Readonly<{\n params: InsertNodeParams;\n claim: NodeClaimItem;\n sideEffects: NodeInsertSideEffects;\n}>;\n\n/**\n * One node update. The validity lower-bound predicate is NOT here: it is the\n * write's fence, passed separately and required, so an update that forgot to\n * carry the bound its verdict read cannot be spelled.\n */\ntype NodeUpdateWork = Readonly<{\n schema: z.ZodType;\n validatedProps: Record<string, unknown>;\n uniqueConstraints: readonly UniqueConstraint[];\n validFrom?: string | null;\n /**\n * The window end this update states, and the flag that clears one. Declared as\n * two independent optionals rather than as `BackendValidityEndMutation`'s\n * discriminated pair, because `applyNodeUpdate` — not this record — is what\n * resolves them into the mutually exclusive params, and the store's callers\n * build them with conditional spreads a union cannot narrow.\n */\n validTo?: string;\n clearValidTo?: true;\n}> &\n NodeUpdateTarget;\n\n/** One node soft delete, including the delete behavior its edges obey. */\ntype NodeDeleteWork = Readonly<{\n existing: LiveNodeRow;\n schema: z.ZodType;\n uniqueConstraints: readonly UniqueConstraint[];\n onDelete: DeleteBehavior | undefined;\n}>;\n\n/** One node hard delete. */\ntype NodeHardDeleteWork = Readonly<{\n kind: string;\n id: string;\n schema: z.ZodType;\n onDelete: DeleteBehavior | undefined;\n}>;\n\n/** One node resurrection: reopen a tombstone with its stored props. */\ntype NodeResurrectWork = Readonly<{\n existing: TombstonedNodeRow;\n schema: z.ZodType;\n uniqueConstraints: readonly UniqueConstraint[];\n}>;\n\n/**\n * One edge insert: the row params and the cardinality claim the row owes.\n *\n * An edge write obliges no DERIVED data — no uniqueness entries, no fulltext, no\n * embeddings — but a constrained kind owes a claim, and the claim is what fences\n * the axis its declaration spans. It is absent for an unconstrained kind and for\n * a born-ended row whose cardinality does not count it, which is what\n * `edgeCardinalityClaim` decides; the caller states the decision and this\n * surface applies it at its PRE-INSERT placement.\n *\n * The update and delete work records live in `edge-write-pipeline.ts` instead,\n * beside the steps that consume them; these four methods have no step module of\n * their own (they delegate to `insert-dispatch.ts`), so their work record lives\n * here with them.\n */\nexport type EdgeInsertWork = Readonly<{\n params: InsertEdgeParams;\n claim?: ClaimEdgeCardinalityParams;\n}>;\n\n/** The claims a batch of edge inserts owes, in the order the batch writer sorts. */\nfunction edgeBatchClaims(\n work: readonly EdgeInsertWork[],\n): readonly ClaimEdgeCardinalityParams[] {\n return work.flatMap((item) => (item.claim === undefined ? [] : [item.claim]));\n}\n\nexport type NodeWriteSession = Readonly<{\n // ---- B0: delegates to node-write-pipeline.ts + insert-dispatch.ts\n createNode: (work: NodeInsertWork) => Promise<NodeRow>;\n createNodeNoReturn: (work: NodeInsertWork) => Promise<void>;\n createNodes: (work: readonly NodeInsertWork[]) => Promise<readonly NodeRow[]>;\n createNodesNoReturn: (work: readonly NodeInsertWork[]) => Promise<void>;\n reviseNode: (\n work: NodeUpdateWork,\n fences: NodeUpdateFences,\n ) => Promise<NodeRow>;\n retireNode: (\n work: NodeDeleteWork,\n policy?: NodeDeletePolicy,\n ) => Promise<void>;\n purgeNode: (work: NodeHardDeleteWork) => Promise<void>;\n reviveNode: (work: NodeResurrectWork) => Promise<NodeRow>;\n\n // ---- B1b: delegates to node-write-pipeline.ts's applyNodeSetUpdate\n reviseNodeSet: (\n work: NodeSetUpdateWork,\n fences: NodeSetUpdateFences,\n ) => Promise<NodeSetUpdateResult>;\n}>;\n\nexport type EdgeWriteSession = Readonly<{\n // ---- B2: delegates to edge-write-pipeline.ts + insert-dispatch.ts\n createEdge: (work: EdgeInsertWork) => Promise<EdgeRow>;\n createEdgeNoReturn: (work: EdgeInsertWork) => Promise<void>;\n createEdges: (work: readonly EdgeInsertWork[]) => Promise<readonly EdgeRow[]>;\n createEdgesNoReturn: (work: readonly EdgeInsertWork[]) => Promise<void>;\n reviseEdge: (\n work: EdgeUpdateWork,\n fences: EdgeUpdateFences,\n ) => Promise<EdgeRow>;\n retireEdge: (work: EdgeDeleteWork) => Promise<void>;\n purgeEdge: (work: EdgeHardDeleteWork) => Promise<void>;\n}>;\n\nexport type WriteSession = NodeWriteSession & EdgeWriteSession;\n\nexport type WriteSessionFor<K extends \"node\" | \"edge\" | \"mixed\"> =\n K extends \"node\" ? NodeWriteSession\n : K extends \"edge\" ? EdgeWriteSession\n : WriteSession;\n\n// No session method may collide with a banned backend member name: the lint\n// rule is syntactic and receiver-blind, so a collision would make the rule\n// flag the migration's own call sites.\n// eslint-disable-next-line @typescript-eslint/no-unused-vars -- compile-time assertion\ntype _sessionNamesAreDisjointFromTheBan = Assert<\n Equal<Extract<keyof WriteSession, WriteMemberKey>, never>\n>;\n\n/**\n * Mints the session for one write frame.\n *\n * `target` is the raw transaction target the executor was handed — the same\n * object row work sees through {@link WriteTarget} — because the step modules\n * this composes take the raw union and probe optional members on it. `lock` is\n * the compile-time evidence that the per-graph write-lock discipline was\n * satisfied before any row work; the session performs no locking of its own.\n */\nexport function createWriteSession(\n ctx: WriteSessionContext,\n target: GraphBackend | TransactionBackend,\n lock: GraphWriteLock,\n): WriteSession {\n const writeContext = createNodeWriteContext(\n ctx.graphId,\n ctx.registry,\n lock,\n ctx.claimsVerdict,\n ctx.uniqueSidecarBatch,\n );\n const dispatch = nodeInsertDispatch(target);\n const edgeContext = createEdgeWriteContext(\n ctx.graphId,\n lock,\n ctx.claimsVerdict,\n );\n const edgeDispatch = edgeInsertDispatch(target);\n\n return {\n // The pinned coordination order, spelled once per insert shape:\n // pre-insert claims, the row, post-insert claims, the sync fans. The claim\n // seam owns the two groups and the compensation between them; this surface\n // owns only \"the row write it gates is THIS one\".\n createNode: async (work) => {\n const row = await withNodeCreateClaims(\n writeContext,\n work.claim,\n target,\n () => dispatch.one(work.params),\n );\n await applyNodeInsertSyncFans(writeContext, work.sideEffects, target);\n return row;\n },\n\n createNodeNoReturn: async (work) => {\n await withNodeCreateClaims(writeContext, work.claim, target, () =>\n runInsertNoReturn(dispatch, work.params),\n );\n await applyNodeInsertSyncFans(writeContext, work.sideEffects, target);\n },\n\n createNodes: async (work) => {\n const rows = await withNodeCreateClaimsBatch(\n writeContext,\n work.map((item) => item.claim),\n target,\n () =>\n runInsertBatchReturning(\n dispatch,\n work.map((item) => item.params),\n ),\n );\n await applyNodeInsertSyncFansBatch(\n writeContext,\n work.map((item) => item.sideEffects),\n target,\n );\n return rows;\n },\n\n createNodesNoReturn: async (work) => {\n await withNodeCreateClaimsBatch(\n writeContext,\n work.map((item) => item.claim),\n target,\n () =>\n runInsertBatch(\n dispatch,\n work.map((item) => item.params),\n ),\n );\n await applyNodeInsertSyncFansBatch(\n writeContext,\n work.map((item) => item.sideEffects),\n target,\n );\n },\n\n reviseNode: (work, fences) => {\n const draft = createWriteParamsDraft();\n applyWriteFences(NODE_UPDATE_FENCE_APPLIERS, fences, draft);\n return applyNodeUpdate(writeContext, { ...work, ...draft }, target);\n },\n\n retireNode: (work, policy) =>\n applyNodeSoftDelete(writeContext, work, target, policy),\n\n purgeNode: (work) => applyNodeHardDelete(writeContext, work, target),\n\n reviveNode: (work) => applyNodeResurrect(writeContext, work, target),\n\n reviseNodeSet: (work, fences) => {\n // The fences are applied for their REFUSAL, not for their contribution:\n // this kind's one applier throws for a stated bound and writes nothing\n // for an empty one, so a draft that survives the call is provably empty\n // and there is no predicate to thread into the statement. Skipping the\n // call would be this layer re-deciding what the applier decides.\n applyWriteFences(\n NODE_SET_UPDATE_FENCE_APPLIERS,\n fences,\n createWriteParamsDraft(),\n );\n return applyNodeSetUpdate(writeContext, work, target);\n },\n\n // An edge write obliges no DERIVED data, so these apply no sync fans — but a\n // constrained kind owes its cardinality claim, at the same PRE-INSERT\n // placement a node's scope-spanning claim takes and for the same reason: the\n // probe that authorised the insert read a population no key fences. The\n // batch issues ONE sorted statement (`claimEdgeCardinalityBatch` orders by\n // `compareClaimTargets`), so a batch and a peer batch take their row locks\n // in the same order.\n createEdge: async (work) => {\n if (work.claim !== undefined) {\n await claimEdgeCardinality(target, ctx.claimsVerdict(), work.claim);\n }\n return edgeDispatch.one(work.params);\n },\n\n createEdgeNoReturn: async (work) => {\n if (work.claim !== undefined) {\n await claimEdgeCardinality(target, ctx.claimsVerdict(), work.claim);\n }\n await runInsertNoReturn(edgeDispatch, work.params);\n },\n\n createEdges: async (work) => {\n await claimEdgeCardinalityBatch(\n target,\n ctx.claimsVerdict(),\n edgeBatchClaims(work),\n );\n return runInsertBatchReturning(\n edgeDispatch,\n work.map((item) => item.params),\n );\n },\n\n createEdgesNoReturn: async (work) => {\n await claimEdgeCardinalityBatch(\n target,\n ctx.claimsVerdict(),\n edgeBatchClaims(work),\n );\n await runInsertBatch(\n edgeDispatch,\n work.map((item) => item.params),\n );\n },\n\n reviseEdge: (work, fences) => {\n const draft = createWriteParamsDraft();\n applyWriteFences(EDGE_UPDATE_FENCE_APPLIERS, fences, draft);\n return applyEdgeUpdate(edgeContext, { ...work, ...draft }, target);\n },\n\n retireEdge: (work) => applyEdgeSoftDelete(edgeContext, work, target),\n\n purgeEdge: (work) => applyEdgeHardDelete(edgeContext, work, target),\n };\n}\n","/**\n * The one sanctioned caller of `runInWriteTransaction` /\n * `runHookedWriteOperation`.\n *\n * What the executor owns is small and complete: thread the plan's constraint\n * probe into the option `write-transaction.ts` already owns, acquire the\n * identity lock when the plan declares participation, mint the session, and\n * hand row work the read projection. Everything else — whether the per-graph\n * write lock is taken, whether the schema fence is taken, the lock ORDER —\n * stays with the module that owns the state those locks guard. The executor\n * re-spells none of it.\n *\n * Row work therefore cannot run before the locks: `runInWriteTransaction`\n * takes positions 1-2, this takes position 3, and `rowWork` is called after\n * both.\n */\nimport { deriveBackend } from \"../../backend/derive-backend\";\nimport {\n type GraphBackend,\n type TransactionBackend,\n} from \"../../backend/types\";\nimport { requireDefined } from \"../../utils/presence\";\nimport { type GraphWriteLock } from \"../recorded-capture/clock\";\nimport { type OperationHookContext } from \"../types\";\nimport { type RowWorkKind, type WritePlan } from \"./write-plan\";\nimport {\n createWriteSession,\n type WriteSession,\n type WriteSessionContext,\n type WriteSessionFor,\n type WriteTarget,\n} from \"./write-session\";\nimport {\n type HookedWriteOperationContext,\n runHookedWriteOperation,\n runInWriteTransaction,\n type WriteTransactionContext,\n type WriteTransactionOptions,\n} from \"./write-transaction\";\n\n/**\n * What a plan-driven write needs beyond the transaction context: the graph's\n * kind registry (the session's step modules resolve schemas and constraints\n * through it) and HOW this caller acquires the identity lock.\n *\n * `identityLock` is absent when the graph has no identity configured — in\n * which case plan builders derive `requiresIdentityLock: false`, so a declared\n * participation with no acquirer is a wiring bug. The executor asserts on it\n * rather than silently skipping the lock: no user-stated option can produce\n * that state, so it is an internal invariant, not a public refusal.\n */\nexport type WritePlanContext = WriteTransactionContext &\n WriteSessionContext &\n Readonly<{\n identityLock?: (target: GraphBackend | TransactionBackend) => Promise<void>;\n }>;\n\n/** The hooked variant's context: the above plus the hook wrapper. */\nexport type HookedWritePlanContext = WritePlanContext &\n HookedWriteOperationContext;\n\n/**\n * The transaction options a plan caller may still state.\n *\n * `fencesConstraintProbe` is subtracted because the executor OWNS it — it\n * comes from `plan.constraintProbe` and nowhere else. Subtracting the key\n * makes a doubly-spelled probe a type error at the call site instead of a\n * value the executor's spread silently discards, which is the same\n * \"accepted then dropped\" failure that deleted the lock-plan field. Written as\n * an `Omit` of the existing options type rather than a fresh literal, so an\n * option added to `WriteTransactionOptions` reaches plan callers on its own;\n * today the residue is exactly `didWrite`.\n */\nexport type WritePlanOptions<T> = Omit<\n WriteTransactionOptions<T>,\n \"fencesConstraintProbe\"\n>;\n\n/**\n * Mints a second session for THIS write frame over a READ OVERLAY of its\n * target: the frame's own handle, answering some reads from a pending-aware\n * cache and delegating everything else, which is what\n * `createNodeBatchValidationSeams` describes.\n *\n * It exists because a fused step reads and writes through ONE handle.\n * Interchange import's batched slice has to route the uniqueness pre-check\n * inside `reviseNode` through the overlay — so a key an unflushed create\n * earlier in the same slice already reserved degrades to a per-row error\n * instead of colliding at flush — while the write itself lands on the real\n * backend, which is precisely what that overlay does. Handing the leg the\n * frame's session over the raw target would silently drop the pending state,\n * and re-checking uniqueness outside the step would be a second spelling of a\n * decision the step owns.\n *\n * What this TAKES is the reads to answer, not a backend to write through. Row\n * work holds the read-only {@link WriteTarget}, so it cannot produce a\n * writable overlay without widening the very projection this seam exists to\n * keep narrow; the EXECUTOR owns the decoration, over the raw target it\n * already has. `Partial<WriteTarget>` is the exact bound that follows: an\n * overlay may redirect any read row work can see, and no write member at all.\n *\n * What this hands out is the CAPABILITY, not the evidence: the frame's\n * {@link GraphWriteLock} stays inside the executor, so row work still cannot\n * reach a step module directly. All it can obtain is another fused session,\n * whose methods apply the same sidecars and the same fences as the first.\n */\ntype WriteTargetReadOverlay = Partial<WriteTarget>;\n\nexport type OverlaidSessionMint<K extends RowWorkKind = RowWorkKind> = (\n reads: WriteTargetReadOverlay,\n) => WriteSessionFor<K>;\n\n/** Row work: the only place a plan-driven write may read or write rows. */\nexport type WriteRowWork<K extends RowWorkKind, T> = (\n session: WriteSessionFor<K>,\n target: WriteTarget,\n overlaidSession: OverlaidSessionMint<K>,\n) => Promise<T>;\n\n/**\n * The frame both entry points run: acquire position 3 when the plan declares\n * identity participation, then call row work with the session and the read\n * projection.\n *\n * ONE spelling, shared. A hooked write and a plain one differ only in what\n * wraps the transaction, so the identity decision — and the moment in the\n * frame it is taken at — must not be written twice.\n */\nfunction planFrame<K extends RowWorkKind, T>(\n ctx: WritePlanContext,\n plan: WritePlan<K>,\n rowWork: WriteRowWork<K, T>,\n) {\n return async (\n target: GraphBackend | TransactionBackend,\n lock: GraphWriteLock,\n ): Promise<T> => {\n if (plan.requiresIdentityLock) {\n const acquireIdentityLock = requireDefined(\n ctx.identityLock,\n \"write plan declares identity participation with no acquirer\",\n );\n await acquireIdentityLock(target);\n }\n // ONE spelling of \"mint a session for this frame\", used for the frame's own\n // session and for any overlaid one, so the two cannot be built from\n // different context or a different lock. The overlaid variant is that\n // spelling applied to a decorated target — the decoration is the ONLY\n // difference between them, and the frame's own session pays for no proxy.\n const mintSessionOver = (\n sessionTarget: GraphBackend | TransactionBackend,\n ): WriteSession => createWriteSession(ctx, sessionTarget, lock);\n const mintOverlaidSession: OverlaidSessionMint<K> = (reads) =>\n mintSessionOver(deriveBackend(target, reads)) as WriteSessionFor<K>;\n // The two handles are the SAME object: the session closes over the raw\n // target (its step modules probe optional members on it), while row work\n // sees it through the type-only `WriteTarget` projection. One value, two\n // static views.\n return rowWork(\n mintSessionOver(target) as WriteSessionFor<K>,\n target,\n mintOverlaidSession,\n );\n };\n}\n\n/**\n * The transaction options the executor hands down.\n *\n * `fencesConstraintProbe` is written LAST and from the plan alone, so no\n * caller-supplied residue can shadow it.\n */\nfunction planTransactionOptions<K extends RowWorkKind, T>(\n plan: WritePlan<K>,\n options: WritePlanOptions<T> | undefined,\n): WriteTransactionOptions<T> {\n return { ...options, fencesConstraintProbe: plan.constraintProbe };\n}\n\n/** Runs one managed write under its plan. */\nexport function runWritePlan<K extends RowWorkKind, T>(\n ctx: WritePlanContext,\n plan: WritePlan<K>,\n backend: GraphBackend | TransactionBackend,\n rowWork: WriteRowWork<K, T>,\n options?: WritePlanOptions<T>,\n): Promise<T> {\n return runInWriteTransaction(\n ctx,\n backend,\n planFrame(ctx, plan, rowWork),\n planTransactionOptions(plan, options),\n );\n}\n\n/**\n * Hooked variant: operation hooks WRAP the plan, exactly as\n * `runHookedWriteOperation` wraps the transaction today, so `onOperationEnd`\n * observes a durably committed result.\n */\nexport function runHookedWritePlan<K extends RowWorkKind, T>(\n ctx: HookedWritePlanContext,\n opContext: OperationHookContext,\n plan: WritePlan<K>,\n backend: GraphBackend | TransactionBackend,\n rowWork: WriteRowWork<K, T>,\n options?: WritePlanOptions<T>,\n): Promise<T> {\n return runHookedWriteOperation(\n ctx,\n opContext,\n backend,\n planFrame(ctx, plan, rowWork),\n planTransactionOptions(plan, options),\n );\n}\n","/**\n * The inert description of a managed write: what makes it constrained, and\n * whether identity participates in it.\n *\n * A plan is built SYNCHRONOUSLY and reads nothing. That is the invariant this\n * module exists to make structural rather than reviewable: every builder here\n * takes plain data and returns a {@link WritePlan}, never a promise and never\n * a backend, so no decision a write depends on can be made before the write's\n * locks are held. Everything that reads runs inside the executor's row-work\n * callback, which by construction runs after positions 1-3 of the lock order.\n *\n * What a plan deliberately does NOT own is the lock decision. Whether the\n * per-graph write lock is taken is decided by `write-transaction.ts` from\n * `ctx.historyEnabled`, `ctx.revisionTrackingEnabled` and the constraint\n * probe — two of the three are store configuration, not plan input — and\n * whether the schema fence is taken is unconditional for a schema-managed\n * store. A `LockPlan` field could only re-spell a decision it does not own,\n * and would be silently ignored on a non-capture store: exactly the\n * \"accepted, then dropped\" failure this pipeline exists to prevent.\n */\nimport { type ConstraintFenceReason } from \"../constraints\";\n\n/**\n * The row-work family, which determines the session surface handed to row\n * work. A node plan can call only node session methods, an edge plan only edge\n * methods, and the deliberately mixed import plan can call both.\n *\n * `\"mixed\"` is explicit rather than pretending a frame that writes both node\n * and edge rows belongs to one family. Interchange import is its sole caller.\n */\nexport type RowWorkKind = \"node\" | \"edge\" | \"mixed\";\n\n/**\n * Whether identity participates in this write. The executor owns only the lock\n * requirement; fold, detach, and assertion behavior remains typed row work and\n * is deliberately not encoded as inert plan data the executor would ignore.\n *\n * NOTE what this is not: a lock ORDER. There is no `LockPlan`. Positions 1, 2\n * and 5 are decided and acquired by `write-transaction.ts` and the capture\n * overlay, which own the state those locks guard; the plan re-spells none of\n * them.\n */\nexport type WritePlan<K extends RowWorkKind = RowWorkKind> = Readonly<{\n entity: K;\n /**\n * The declared constraint that makes this a constrained write, or\n * `undefined`. Threaded verbatim into `runInWriteTransaction`'s existing\n * `fencesConstraintProbe` option — the same value today's call sites pass,\n * now carried as data instead of spelled at the call.\n */\n constraintProbe: ConstraintFenceReason | undefined;\n requiresIdentityLock: boolean;\n}>;\n\n/** The plan for one node write. */\nexport function nodeWritePlan(\n constraintProbe: ConstraintFenceReason | undefined,\n requiresIdentityLock: boolean,\n): WritePlan<\"node\"> {\n return { entity: \"node\", constraintProbe, requiresIdentityLock };\n}\n\n/**\n * The plan for a batched node write.\n *\n * Owns one decision the single-write builder does not: **a batch is\n * constrained when ANY member is.** One transaction means one fence, so a\n * single constrained member makes the whole write constrained, and the first\n * such member names the class a refusal would report.\n *\n * `node-operations.ts`'s private `nodeBatchFencesConstraintProbe` is the\n * pre-migration spelling of this fold; it is replaced by this builder in the\n * batch that moves those call sites (B1), not left as a second owner.\n */\nexport function nodeBatchWritePlan(\n constraintProbes: readonly (ConstraintFenceReason | undefined)[],\n requiresIdentityLock: boolean,\n): WritePlan<\"node\"> {\n return {\n entity: \"node\",\n constraintProbe: constraintProbes.find((probe) => probe !== undefined),\n requiresIdentityLock,\n };\n}\n\n/**\n * The plan for one edge write. Edge writes do not participate in identity —\n * identity folds node references, and an edge carries none of its own — so the\n * participation is not a parameter.\n */\nexport function edgeWritePlan(\n constraintProbe: ConstraintFenceReason | undefined,\n): WritePlan<\"edge\"> {\n return { entity: \"edge\", constraintProbe, requiresIdentityLock: false };\n}\n\n/** A single frame that deliberately coordinates node and edge writes. */\nexport function mixedWritePlan(\n constraintProbe: ConstraintFenceReason | undefined,\n requiresIdentityLock: boolean,\n): WritePlan<\"mixed\"> {\n return { entity: \"mixed\", constraintProbe, requiresIdentityLock };\n}\n","import type { GraphBackend, TransactionBackend } from \"../backend/types\";\nimport type { KindEntity } from \"../core/types\";\nimport { ConfigurationError, ValidationError } from \"../errors\";\n\nexport type ValidityEndMutationInput = Readonly<{\n validTo?: string;\n clearValidTo?: true;\n}>;\n\n/** One owner for the mutually-exclusive validity-end write contract. */\nexport function assertValidityEndMutation(\n input: ValidityEndMutationInput,\n context: Readonly<{ entityType: KindEntity; kind: string; id?: string }>,\n): void {\n if (input.validTo === undefined || input.clearValidTo !== true) return;\n throw new ValidationError(\n '\"validTo\" and \"clearValidTo\" are mutually exclusive',\n {\n ...context,\n operation: \"update\",\n issues: [\n {\n path: \"clearValidTo\",\n message: 'Pass either \"validTo\" or \"clearValidTo\", not both',\n },\n ],\n },\n );\n}\n\n/** The end a row will hold after applying this mutation. */\nexport function validityEndAfterMutation(\n input: ValidityEndMutationInput,\n current: string | undefined,\n): string | undefined {\n if (input.clearValidTo === true) return undefined;\n return input.validTo ?? current;\n}\n\n/**\n * Custom backends explicitly opt in to clearing. The store refuses before\n * invoking a backend that has not promised to apply the new state.\n */\nexport function assertClearValidToSupported(\n backend: GraphBackend | TransactionBackend,\n entityType: KindEntity,\n): void {\n if (backend.capabilities.clearValidTo === true) return;\n throw new ConfigurationError(\n `This backend does not support clearing ${entityType} validTo`,\n {\n code: \"CLEAR_VALID_TO_UNSUPPORTED\",\n entityType,\n },\n );\n}\n","/**\n * The create API's \"this identity is already taken\" refusal, and the one\n * translation that turns a driver's duplicate-key report into it.\n *\n * A create learns an id is taken one of two ways: its own existence probe sees\n * the row, or the engine refuses the INSERT. The engine's report used to escape\n * as a `DrizzleQueryError` whose `.message` is the raw SQL text (issue #410), so\n * one condition surfaced as a typed user error down one path and an opaque system\n * error down the other, and a caller could not branch on it at all. Both paths\n * now raise the SAME error, carrying {@link ENTITY_ALREADY_EXISTS_CODE} on its\n * issue.\n *\n * The engine's path is reached two ways, and the second is not a race:\n *\n * - A NODE create probes first, but the probe and the INSERT are two statements.\n * PostgreSQL under its default READ COMMITTED does not serialize two write\n * transactions, so both can probe an absent row and both can then insert it,\n * and the loser finds out from the INSERT. SQLite cannot reach this shape:\n * `BEGIN IMMEDIATE` gives the writer slot to one transaction at a time (pinned\n * by the business-transaction write-lock cases in\n * `tests/backends/sqlite/sqlite-backend.test.ts`), so the loser's probe runs\n * after the winner committed and its verdict stands.\n * - An EDGE create has no existence probe at all — its id is caller-supplied or\n * freshly generated — so the engine's refusal is the ONLY report on EVERY\n * backend, race or no race. That is why the classification covers both\n * dialects and not just PostgreSQL.\n *\n * The backend does the classification (it owns the relation and constraint names\n * the engine reports); this module owns the store-level judgement of what that\n * classification means to a caller.\n */\nimport { type KindEntity } from \"../../core/types\";\nimport {\n DatabaseOperationError,\n ENTITY_ALREADY_EXISTS_CODE,\n ValidationError,\n} from \"../../errors\";\n\n/** An entity the refused statement tried to create. */\ntype AttemptedCreate = Readonly<{ kind: string; id: string }>;\n\n/** Sentence-initial and mid-sentence names for each entity. */\nconst ENTITY_LABELS = {\n node: { title: \"Node\", article: \"A node\" },\n edge: { title: \"Edge\", article: \"An edge\" },\n} as const satisfies Record<\n KindEntity,\n Readonly<{ title: string; article: string }>\n>;\n\nfunction alreadyExistsError(\n entity: KindEntity,\n kind: string,\n id: string | undefined,\n detail: string,\n cause: unknown,\n): ValidationError {\n const label = ENTITY_LABELS[entity];\n return new ValidationError(\n `${label.title} already exists: ${detail}`,\n {\n entityType: entity,\n kind,\n operation: \"create\",\n ...(id === undefined ? {} : { id }),\n issues: [\n {\n path: \"id\",\n code: ENTITY_ALREADY_EXISTS_CODE,\n message: `${label.article} with this ID already exists`,\n },\n ],\n },\n {\n suggestion: `Use a different ID or update the existing ${entity}.`,\n ...(cause === undefined ? {} : { cause }),\n },\n );\n}\n\n/**\n * The refusal a create raises for a taken id: the probe path's error, and the\n * target of the driver-report translation below.\n */\nexport function createAlreadyExistsError(\n entity: KindEntity,\n kind: string,\n id: string,\n): ValidationError {\n return alreadyExistsError(entity, kind, id, `${kind}/${id}`, undefined);\n}\n\nfunction isDuplicateKeyInsertError(\n error: unknown,\n entity: KindEntity,\n): error is DatabaseOperationError {\n return (\n error instanceof DatabaseOperationError &&\n error.details.operation === \"insert\" &&\n error.details.entity === entity &&\n error.details.reason === \"duplicate_key\"\n );\n}\n\n/**\n * Rethrows a classified duplicate-key insert as {@link createAlreadyExistsError},\n * and anything else untouched.\n *\n * A single insert names the row it lost on exactly. A multi-row one cannot: the\n * engine reports that the statement collided without saying which row did, and\n * the transaction is already aborted, so there is nothing left to probe. The\n * refusal then names the statement instead of inventing an attribution — same\n * error type, same issue code, `details.id` simply absent. The count is the\n * refused STATEMENT's rows, which is the caller's batch only until the backend\n * chunks it, so the message claims no more than that. Every batch here comes\n * from one collection, so the kind is always known.\n */\nfunction rethrowAsAlreadyExists(error: unknown, entity: KindEntity): never {\n if (!isDuplicateKeyInsertError(error, entity)) throw error;\n const attempted: readonly AttemptedCreate[] = error.details.attempted ?? [];\n const first = attempted[0];\n if (first === undefined) throw error;\n if (attempted.length === 1) {\n throw alreadyExistsError(\n entity,\n first.kind,\n first.id,\n `${first.kind}/${first.id}`,\n error,\n );\n }\n throw alreadyExistsError(\n entity,\n first.kind,\n undefined,\n `one of the ${attempted.length} ${first.kind} ids in the refused insert`,\n error,\n );\n}\n\n/**\n * Runs an insert (or a group of inserts issued as one unit) and converts a\n * duplicate-key refusal into the create API's already-exists error.\n */\nexport async function withAlreadyExistsTranslation<T>(\n entity: KindEntity,\n run: () => Promise<T>,\n): Promise<T> {\n try {\n return await run();\n } catch (error) {\n rethrowAsAlreadyExists(error, entity);\n }\n}\n","/**\n * Node Operations for Store\n *\n * Handles node CRUD operations: create, update, delete.\n *\n * ## A write asserts every component its verdict READ\n *\n * `performNodeUpdate` is a probe-and-write pair: it reads the row, decides from\n * what it finds, and then writes. Under PostgreSQL READ COMMITTED a concurrent\n * `hardDelete` + recreate re-resolves `(graph_id, kind, id)` between the two,\n * so anything the decision consumed and the statement does not restate is a\n * decision that can land on a row it was never computed for — and the write\n * reports success. Every value read off the probed row, and where it is\n * asserted:\n *\n * - `kind` / `id` — the write key itself, restated in every UPDATE's `WHERE`.\n * - `deleted_at` (which leg runs, and whether to sample a resurrection\n * instant) — asserted as `deleted_at IS NULL` on the in-place leg and\n * `IS NOT NULL` on the resurrecting one, so each leg can only hit a row in\n * the state it was chosen for.\n * - `valid_from` — asserted via `UpdateNodeParams.expectedValidFrom` WHEN the\n * window verdict read it ({@link ValidityWindowVerdict}): the caller stated\n * a `validFrom` to compare against the row's, or a lone `validTo` to invert\n * against it. A plain `update({ props })` states no window, so the verdict\n * is independent of the row's bound and the write carries no predicate for\n * it — the same \"only what it asserted\" rule the edge identity components\n * follow, and for the same reason: inventing a predicate for a component the\n * caller made no claim about refuses writes that are legitimate. A\n * resurrection is judged against the write instant rather than the row's\n * bound, so it asserts none either; its own tombstone predicate fences it.\n * - `props` — read twice, as the merge base for the caller's partial update\n * and as the `oldProps` side of the uniqueness diff — and NOT assertable: a\n * props blob is TEXT on SQLite and `jsonb` on PostgreSQL, and neither\n * comparison is stable under key reordering. Bounded instead, two ways: the\n * sidecar writes are gated on the primary UPDATE's rowcount (see\n * `applyNodeUpdate`), and\n * {@link performNodeUpdateWithResurrectionRecovery} re-reads and re-merges\n * whenever a predicate catches a replaced row.\n * - the uniques-table row behind `getOrCreateByConstraint` — read to resolve\n * WHICH node the key names. Not assertable by the node UPDATE (it is a\n * different table); bounded by the constraint write fence, which makes the\n * probe and the write it authorizes commit under one per-graph mutual\n * exclusion. Its `deleted_at`, however, is NOT the owner of \"does this write\n * resurrect\" — both the single and bulk paths read that from the node row\n * they are about to write, because one decision with two owners drifts.\n */\nimport { bindExtraIfReachable } from \"../../backend/capabilities/bind\";\nimport {\n BATCH_POINT_READ,\n UNIQUE_SIDECAR_BATCH,\n} from \"../../backend/capabilities/bundle-registry\";\nimport {\n type BundleVerdictOf,\n type ClaimsVerdictThunk,\n missingRequiredExtras,\n} from \"../../backend/capabilities/resolve\";\nimport { deriveBackend } from \"../../backend/derive-backend\";\nimport {\n type GraphBackend,\n type InsertNodeParams,\n isLiveNodeRow,\n type NodeRow as BackendNodeRow,\n rowPropsToObject,\n type TransactionBackend,\n type UniqueRow,\n} from \"../../backend/types\";\nimport { checkWherePredicate, computeUniqueKey } from \"../../constraints\";\nimport { type GraphDef } from \"../../core/define-graph\";\nimport { assertJsonValue } from \"../../core/json-value\";\nimport {\n type JsonValue,\n type KindEntity,\n type NodeType,\n type UniqueConstraint,\n} from \"../../core/types\";\nimport {\n ConfigurationError,\n DatabaseOperationError,\n KindNotFoundError,\n NodeConstraintNotFoundError,\n NodeIndexNotFoundError,\n NodeNotFoundError,\n UniquenessError,\n ValidationError,\n} from \"../../errors\";\nimport { validateNodeProps } from \"../../errors/validation\";\nimport { refKey } from \"../../identity/service\";\nimport { type IdentityTarget } from \"../../identity/sql-target\";\nimport {\n compileIndexWhere,\n compileNodeIndexFieldKeys,\n type IndexCompilationContext,\n} from \"../../indexes/compiler\";\nimport { type NodeIndexDeclaration } from \"../../indexes/types\";\nimport { type ValueType } from \"../../query/ast\";\nimport {\n createSqlSchema,\n DEFAULT_SQL_SCHEMA,\n type SqlSchema,\n} from \"../../query/compiler/schema\";\nimport { getDialect } from \"../../query/dialect\";\nimport { type DialectAdapter } from \"../../query/dialect/types\";\nimport { type JsonPointer, resolveJsonPointer } from \"../../query/json-pointer\";\nimport { sql, type SqlFragment } from \"../../query/sql-fragment\";\nimport type { CompiledSelectSql } from \"../../query/sql-intent\";\nimport { asCompiledRowsSql } from \"../../query/sql-intent\";\nimport { type KindRegistry } from \"../../registry/kind-registry\";\nimport { canonicalEqual } from \"../../schema/canonical\";\nimport {\n assertOrderedValidityWindow,\n assertWritableValidityWindow,\n nowIso,\n preservesImmutableLowerBound,\n resolveStampedValidityLowerBound,\n validateOptionalCanonicalIsoDate,\n} from \"../../utils/date\";\nimport { generateId } from \"../../utils/id\";\nimport { createDataKeyedBag, hasOwnKey } from \"../../utils/object\";\nimport { requireDefined } from \"../../utils/presence\";\nimport { encodeTupleKey } from \"../../utils/tuple-key\";\nimport { type ClaimOwner, uniquenessProbeKinds } from \"../claims/axis\";\nimport {\n checkUniquenessConstraints,\n createUniquenessContext,\n nodeClaimEntries,\n type NodeClaimItem,\n} from \"../claims/node-claims\";\nimport { type UpsertDirtyCheck } from \"../collections/coalesce\";\nimport { type UpsertUpdateNodeInput } from \"../collections/node-collection\";\nimport {\n checkDisjointnessConstraint,\n type ConstraintContext,\n type ConstraintFenceReason,\n nodeWriteNeedsConstraintFence,\n} from \"../constraints\";\nimport { getEmbeddingFields } from \"../embedding-sync\";\nimport { getSearchableFields } from \"../fulltext-sync\";\nimport { getNodeRowsByIds } from \"../node-fetch\";\nimport { type NodeRow, rowToNode } from \"../row-mappers\";\nimport {\n type BulkOperationHookContext,\n type CreateNodeInput,\n type GetOrCreateAction,\n type Node,\n type NodeBulkFindByIndexOptions,\n type NodeGetOrCreateByConstraintOptions,\n type OperationHookContext,\n type UpdateNodeInput,\n} from \"../types\";\nimport {\n assertClearValidToSupported,\n assertValidityEndMutation,\n} from \"../validity-end\";\nimport {\n createAlreadyExistsError,\n withAlreadyExistsTranslation,\n} from \"./already-exists\";\nimport { type NodeInsertSyncItem } from \"./node-write-pipeline\";\nimport {\n type HookedWritePlanContext,\n runHookedWritePlan,\n runWritePlan,\n} from \"./write-executor\";\nimport { type NodeUpdateFences } from \"./write-fences\";\nimport { nodeBatchWritePlan, nodeWritePlan } from \"./write-plan\";\nimport {\n type NodeInsertWork,\n type NodeWriteSession,\n type WriteTarget,\n} from \"./write-session\";\n\n// ============================================================\n// Types\n// ============================================================\n\nexport type NodeOperationContext<G extends GraphDef> = Readonly<{\n graph: G;\n graphId: string;\n schemaVersion: number | undefined;\n historyEnabled: boolean;\n revisionTrackingEnabled: boolean;\n coalesceUnchangedUpsertsEnabled: boolean;\n revisionSchema: SqlSchema;\n registry: KindRegistry;\n /**\n * The `claims` bundle's memoized, at-most-once verdict thunk (ruling B7\n * refinement 2) — threaded through to `createNodeWriteContext` by\n * `runWritePlan`'s session mint, and called at the write-session sites that\n * issue or release a claim.\n */\n claimsVerdict: ClaimsVerdictThunk;\n /** Threaded from `store.ts`'s `#batchPointRead` — never re-resolved here. */\n batchPointRead: BundleVerdictOf<typeof BATCH_POINT_READ>;\n /** Threaded from `store.ts`'s `#uniqueSidecarBatch` — never re-resolved here. */\n uniqueSidecarBatch: BundleVerdictOf<typeof UNIQUE_SIDECAR_BATCH>;\n createOperationContext: (\n operation: \"create\" | \"update\" | \"delete\",\n entity: KindEntity,\n kind: string,\n id: string,\n ) => OperationHookContext;\n withOperationHooks: <T>(\n ctx: OperationHookContext,\n fn: () => Promise<T>,\n ) => Promise<T>;\n createBulkOperationContext: (\n operation: \"updateWhere\",\n kind: string,\n ) => BulkOperationHookContext;\n withBulkOperationHooks: <T extends Readonly<{ affectedCount: number }>>(\n ctx: BulkOperationHookContext,\n fn: () => Promise<T>,\n ) => Promise<T>;\n /**\n * The identity hooks a node write participates in, on {@link IdentityTarget}\n * — the projection identity STATEMENTS run against — so a fold or a detach\n * can be issued from inside a write frame, whose handle is the read-only\n * {@link WriteTarget}. Identity assertions are not node rows: they never\n * travel through the session, and this is their seam.\n */\n identity?: Readonly<{\n lock: (target: IdentityTarget) => Promise<void>;\n foldCreated: (\n target: IdentityTarget,\n references: readonly Readonly<{ kind: string; id: string }>[],\n ) => Promise<void>;\n detachDeleted: (\n target: IdentityTarget,\n ref: Readonly<{ kind: string; id: string }>,\n mode: \"soft\" | \"hard\",\n ) => Promise<void>;\n requireValidityEndCompatible: (\n target: IdentityTarget,\n ref: Readonly<{ kind: string; id: string }>,\n validTo: string,\n ) => Promise<void>;\n }>;\n}>;\n\ntype NodeCreatePrepared = Readonly<{\n kind: string;\n id: string;\n nodeKind: NodeType;\n validatedProps: Record<string, unknown>;\n uniqueConstraints: readonly UniqueConstraint[];\n insertParams: InsertNodeParams;\n /**\n * `true` when the caller supplied `input.id`. A generated id cannot\n * already exist under another kind, so identity folding can skip its\n * cross-kind probe entirely for those rows.\n */\n idProvided: boolean;\n /**\n * The soft-deleted row occupying this id, or `undefined` when the id is\n * free. Named for what it can hold rather than what it was read as: the\n * duplicate-existence probe in {@link finishNodeCreatePreparation} throws\n * on a LIVE row, so what survives is always a tombstone awaiting\n * resurrection. Carrying it here is what lets the create path route\n * insert-vs-resurrect without re-reading the same (graph, kind, id).\n */\n tombstone: BackendNodeRow | undefined;\n}>;\n\ntype CachedNodeRow = Awaited<ReturnType<GraphBackend[\"getNode\"]>>;\ntype CachedUniqueRow = Awaited<ReturnType<GraphBackend[\"checkUnique\"]>>;\n\n// ============================================================\n// Helper Functions\n// ============================================================\n\n// Own-key membership, matching `store.getNodePropsSchema` and the collections\n// proxy: kind names are arbitrary identifiers, so a `toString`-named kind that\n// is NOT registered would otherwise read the inherited function as its\n// registration and fail with a `TypeError` off `registration.type` instead of\n// the `KindNotFoundError` this guard exists to raise.\nfunction getNodeRegistration<G extends GraphDef>(graph: G, kind: string) {\n if (!hasOwnKey(graph.nodes, kind)) throw new KindNotFoundError(kind, \"node\");\n const registration = graph.nodes[kind];\n if (registration === undefined) throw new KindNotFoundError(kind, \"node\");\n return registration;\n}\n\n/**\n * WHICH constraint makes this node write one whose probe no database key\n * repeats at write time, so it must take the per-graph write fence — or be\n * refused where no fence exists. The classification itself lives with the\n * constraints ({@link file://../constraints.ts nodeWriteNeedsConstraintFence});\n * this is only the graph-def lookup that feeds it.\n *\n * A kind this graph does not define answers `undefined`: choosing the fence\n * must not become the thing that reports an unknown kind, which the write path\n * raises from inside its hooked transaction where `onError` observes it.\n */\nfunction nodeFencesConstraintProbe<G extends GraphDef>(\n ctx: Pick<NodeOperationContext<G>, \"graph\" | \"registry\">,\n kind: string,\n operation: \"create\" | \"update\",\n): ConstraintFenceReason | undefined {\n if (!hasOwnKey(ctx.graph.nodes, kind)) return undefined;\n return nodeWriteNeedsConstraintFence(\n ctx.registry,\n kind,\n getNodeRegistration(ctx.graph, kind).unique ?? [],\n operation,\n );\n}\n\n/**\n * The per-item constraint probes a batch write plan folds.\n *\n * \"A batch fences when ANY item does\" is owned by {@link nodeBatchWritePlan};\n * this only supplies the per-item classifications it folds, so the rule has one\n * spelling instead of one here and one in the plan builder.\n */\nfunction nodeBatchConstraintProbes<G extends GraphDef>(\n ctx: Pick<NodeOperationContext<G>, \"graph\" | \"registry\">,\n inputs: readonly Readonly<{ kind: string }>[],\n operation: \"create\" | \"update\",\n): readonly (ConstraintFenceReason | undefined)[] {\n return inputs.map((input) =>\n nodeFencesConstraintProbe(ctx, input.kind, operation),\n );\n}\n\n/**\n * The executor context this module's writes run under: the operation context\n * plus HOW it acquires the identity lock.\n *\n * The plan says WHETHER identity participates; the context says how. A graph\n * with no identity configured supplies no acquirer, and its plans declare no\n * participation — the two are derived from the same `ctx.identity`, which is\n * what makes \"declared participation with no acquirer\" an unreachable wiring\n * bug rather than a silently skipped lock.\n */\nfunction nodeWritePlanContext<G extends GraphDef>(\n ctx: NodeOperationContext<G>,\n): HookedWritePlanContext {\n const identity = ctx.identity;\n if (identity === undefined) return ctx;\n return { ...ctx, identityLock: identity.lock };\n}\n\n/**\n * The participation a write declares, or `undefined` on a graph with no\n * identity — the one place the `if (identity !== undefined)` that used to be\n * re-spelled at every node write site now lives.\n */\nfunction nodeRequiresIdentityLock<G extends GraphDef>(\n ctx: NodeOperationContext<G>,\n): boolean {\n return ctx.identity !== undefined;\n}\n\nfunction buildNodeCacheKey(graphId: string, kind: string, id: string): string {\n return encodeTupleKey([graphId, kind, id]);\n}\n\nfunction buildUniqueCacheKey(\n graphId: string,\n nodeKind: string,\n constraintName: string,\n key: string,\n): string {\n return encodeTupleKey([graphId, nodeKind, constraintName, key]);\n}\n\nfunction buildInsertNodeParams(\n graphId: string,\n kind: string,\n id: string,\n props: Record<string, unknown>,\n validFrom: string | undefined,\n validTo: string | undefined,\n): InsertNodeParams {\n const insertParams: {\n graphId: string;\n kind: string;\n id: string;\n props: Record<string, unknown>;\n validFrom?: string;\n validTo?: string;\n } = {\n graphId,\n kind,\n id,\n props,\n };\n if (validFrom !== undefined) insertParams.validFrom = validFrom;\n if (validTo !== undefined) insertParams.validTo = validTo;\n return insertParams;\n}\n\n/**\n * Materializes the claim row a not-yet-flushed batch member holds, so a later\n * member's probe reads the same shape it would read from the database.\n *\n * It invents no kind: the owner pair comes from the pending registration. The\n * predecessor wrote `concrete_kind: nodeKind` — the axis the probe QUERIED,\n * which the pending writer never supplied — so `Employee \"X\"` followed by\n * `Contractor \"X\"` on one shared-scope key read back as the same owner, the\n * in-batch refusal was suppressed, and the real one arrived at the flush as a\n * whole-batch abort. This is the third renderer of claim ownership; it must\n * agree with the TypeScript predicate and the SQL arms.\n */\nfunction createPendingUniqueRow(\n graphId: string,\n nodeKind: string,\n constraintName: string,\n key: string,\n owner: ClaimOwner,\n): UniqueRow {\n return {\n graph_id: graphId,\n node_kind: nodeKind,\n constraint_name: constraintName,\n key,\n node_id: owner.nodeId,\n concrete_kind: owner.concreteKind,\n deleted_at: undefined,\n };\n}\n\nfunction resolveConstraint<G extends GraphDef>(\n graph: G,\n kind: string,\n constraintName: string,\n): UniqueConstraint {\n const registration = getNodeRegistration(graph, kind);\n const constraints = registration.unique ?? [];\n const constraint = constraints.find(\n (candidate) => candidate.name === constraintName,\n );\n if (constraint === undefined) {\n throw new NodeConstraintNotFoundError(constraintName, kind);\n }\n return constraint;\n}\n\n// ============================================================\n// Batch Validation Cache\n//\n// During batch operations, multiple items may reference the same\n// nodes/unique keys. This cache avoids redundant backend lookups\n// and tracks pending (not-yet-flushed) inserts so that later items\n// in the batch can see earlier ones during validation.\n// ============================================================\n\n/**\n * The reads a batch's pending-aware validation answers itself.\n *\n * Published as the OVERLAY SPEC alongside the reader built from it, because\n * two different handles have to carry these answers: the caller reads through\n * `reader`, and interchange import ALSO hands the spec to the executor, which\n * decorates the write frame's own target with it so a session can be minted\n * over the same pending state. A decorated backend alone could not do that —\n * its static type would have to be the full backend union for the session mint\n * to accept it, which is the widening this seam exists to remove — and two\n * independently built overlays would be two spellings of one decision.\n */\nexport type NodeBatchValidationReads = Readonly<\n Pick<WriteTarget, \"getNode\" | \"checkUnique\">\n>;\n\nexport function createNodeBatchValidationSeams(\n graphId: string,\n registry: KindRegistry,\n backend: WriteTarget,\n): Readonly<{\n reads: NodeBatchValidationReads;\n reader: WriteTarget;\n registerPendingNode: (params: InsertNodeParams) => void;\n registerPendingUniqueEntries: (\n kind: string,\n id: string,\n props: Record<string, unknown>,\n constraints: readonly UniqueConstraint[],\n ) => void;\n registerAppliedNodeUpdate: (\n kind: string,\n id: string,\n oldProps: Record<string, unknown>,\n newProps: Record<string, unknown>,\n constraints: readonly UniqueConstraint[],\n ) => void;\n seedNodeRow: (kind: string, id: string, row: CachedNodeRow) => void;\n seedUniqueRow: (\n kind: string,\n constraintName: string,\n key: string,\n row: CachedUniqueRow,\n ) => void;\n}> {\n const nodeCache = new Map<string, CachedNodeRow>();\n const pendingNodes = new Map<string, NonNullable<CachedNodeRow>>();\n const uniqueCache = new Map<string, CachedUniqueRow>();\n // The pending OWNER PAIR, never the bare id: two batch members sharing an id\n // under different kinds are two claimants, and an id-keyed cache reads them\n // as one.\n const pendingUniqueOwners = new Map<string, ClaimOwner>();\n\n async function getNodeCached(\n lookupGraphId: string,\n kind: string,\n id: string,\n ): Promise<CachedNodeRow> {\n const cacheKey = buildNodeCacheKey(lookupGraphId, kind, id);\n const pendingNode = pendingNodes.get(cacheKey);\n if (pendingNode !== undefined) return pendingNode;\n if (nodeCache.has(cacheKey)) return nodeCache.get(cacheKey);\n const existing = await backend.getNode(lookupGraphId, kind, id);\n nodeCache.set(cacheKey, existing);\n return existing;\n }\n\n async function checkUniqueCached(\n params: Parameters<GraphBackend[\"checkUnique\"]>[0],\n ): Promise<CachedUniqueRow> {\n const cacheKey = buildUniqueCacheKey(\n params.graphId,\n params.nodeKind,\n params.constraintName,\n params.key,\n );\n const pendingOwner = pendingUniqueOwners.get(cacheKey);\n if (pendingOwner !== undefined) {\n return createPendingUniqueRow(\n params.graphId,\n params.nodeKind,\n params.constraintName,\n params.key,\n pendingOwner,\n );\n }\n if (uniqueCache.has(cacheKey)) return uniqueCache.get(cacheKey);\n const existing = await backend.checkUnique(params);\n uniqueCache.set(cacheKey, existing);\n return existing;\n }\n\n function registerPendingNode(params: InsertNodeParams): void {\n const cacheKey = buildNodeCacheKey(params.graphId, params.kind, params.id);\n pendingNodes.set(cacheKey, {\n graph_id: params.graphId,\n kind: params.kind,\n id: params.id,\n props: JSON.stringify(params.props),\n version: 1,\n // The simulated cached row only needs a NodeRow-shaped valid_from\n // (string | undefined, never null) for existence/uniqueness checks,\n // which don't inspect its value — normalize import's explicit-NULL\n // sentinel away rather than widen this cache's row shape.\n valid_from: params.validFrom ?? undefined,\n valid_to: params.validTo,\n created_at: \"\",\n updated_at: \"\",\n deleted_at: undefined,\n });\n }\n\n // Records the claims a not-yet-flushed create will write, at the AXIS it will\n // write them: one entry per claim, not one per kind in scope. The fan-out\n // this replaces existed because the claim used to be written under the\n // node's own kind while the probe read every kind in scope; now both sides\n // name the axis, so a second entry would be a second spelling of the same\n // reservation.\n function registerPendingUniqueEntries(\n kind: string,\n id: string,\n props: Record<string, unknown>,\n constraints: readonly UniqueConstraint[],\n ): void {\n for (const entry of nodeClaimEntries(\n registry,\n kind,\n id,\n props,\n constraints,\n \"create\",\n )) {\n pendingUniqueOwners.set(\n buildUniqueCacheKey(\n graphId,\n entry.axis,\n entry.constraintName,\n entry.key,\n ),\n { concreteKind: kind, nodeId: id },\n );\n }\n }\n\n // Reflects a completed in-slice node update in the uniqueness caches so a\n // later row's pre-check sees the post-update reservation state — the state\n // the sequential path's per-row backend read would observe. The batch path\n // primes the caches ONCE before routing, but an in-slice update mutates the\n // real backend's uniqueness rows directly; without reconciling here a later\n // create either (a) claims a value this update just freed yet gets rejected\n // against the stale reservation, or (b) passes the stale \"free\" cache for a\n // value this update just took and then violates the real constraint at\n // flush, aborting the whole import. Mirrors the claim transition's key diff:\n // for each constraint whose key changed, the released old key becomes free\n // and the reserved new key becomes owned by this node AT ITS AXIS — the one\n // row the transition actually wrote — while the remaining kinds the probe\n // reads are recorded as vacant, which they are: the probe that let this\n // update through visited every one of them.\n function registerAppliedNodeUpdate(\n kind: string,\n id: string,\n oldProps: Record<string, unknown>,\n newProps: Record<string, unknown>,\n constraints: readonly UniqueConstraint[],\n ): void {\n const owner: ClaimOwner = { concreteKind: kind, nodeId: id };\n const oldEntries = new Map(\n nodeClaimEntries(registry, kind, id, oldProps, constraints, \"update\").map(\n (entry) => [entry.constraintName, entry],\n ),\n );\n const newEntries = new Map(\n nodeClaimEntries(registry, kind, id, newProps, constraints, \"update\").map(\n (entry) => [entry.constraintName, entry],\n ),\n );\n\n for (const constraint of constraints) {\n const oldEntry = oldEntries.get(constraint.name);\n const newEntry = newEntries.get(constraint.name);\n if (oldEntry?.key === newEntry?.key) continue;\n\n const kindsToCheck = uniquenessProbeKinds(\n kind,\n constraint.scope,\n registry,\n );\n\n if (oldEntry !== undefined) {\n for (const kindToCheck of kindsToCheck) {\n const cacheKey = buildUniqueCacheKey(\n graphId,\n kindToCheck,\n constraint.name,\n oldEntry.key,\n );\n // This node released the key on the real backend, so it is now\n // free. Clear any pending reservation and record the known-free\n // state (overwriting a stale seeded owner) so a later create's\n // pre-check sees a vacancy instead of a redundant backend read.\n pendingUniqueOwners.delete(cacheKey);\n uniqueCache.set(cacheKey, undefined);\n }\n }\n if (newEntry !== undefined) {\n for (const kindToCheck of kindsToCheck) {\n const cacheKey = buildUniqueCacheKey(\n graphId,\n kindToCheck,\n constraint.name,\n newEntry.key,\n );\n if (kindToCheck === newEntry.axis) {\n // This node now holds the key on the real backend. A pending owner\n // shadows the seeded uniqueCache entry (checkUniqueCached consults\n // it first), matching registerPendingUniqueEntries' reservation.\n pendingUniqueOwners.set(cacheKey, owner);\n continue;\n }\n pendingUniqueOwners.delete(cacheKey);\n uniqueCache.set(cacheKey, undefined);\n }\n }\n }\n }\n\n // Seed functions let batch preparation prime the caches from one\n // getNodes / checkUniqueBatch round trip instead of a per-row probe.\n // Seeding an absent result (`undefined`) is meaningful — it marks the\n // key as known-missing so the per-row check skips the backend read.\n // Existing entries are never overwritten: a pending registration or an\n // earlier lookup always wins.\n function seedNodeRow(kind: string, id: string, row: CachedNodeRow): void {\n const cacheKey = buildNodeCacheKey(graphId, kind, id);\n if (nodeCache.has(cacheKey)) return;\n nodeCache.set(cacheKey, row);\n }\n\n function seedUniqueRow(\n kind: string,\n constraintName: string,\n key: string,\n row: CachedUniqueRow,\n ): void {\n const cacheKey = buildUniqueCacheKey(graphId, kind, constraintName, key);\n if (uniqueCache.has(cacheKey)) return;\n uniqueCache.set(cacheKey, row);\n }\n\n const reads: NodeBatchValidationReads = {\n getNode: getNodeCached,\n checkUnique: checkUniqueCached,\n };\n\n return {\n reads,\n reader: deriveBackend(backend, reads),\n registerPendingNode,\n registerPendingUniqueEntries,\n registerAppliedNodeUpdate,\n seedNodeRow,\n seedUniqueRow,\n };\n}\n\n// ============================================================\n// Shared Create Pipeline\n// ============================================================\n\n/**\n * The synchronous half of create preparation: kind resolution, Zod\n * validation, and date validation. Produces everything the async\n * constraint checks need, so batch preparation can validate every input\n * first and then prime the validation caches with batched reads before\n * running {@link finishNodeCreatePreparation} per row.\n */\n/**\n * Internal create options threaded from operations that validated props\n * BEFORE calling into the create path. Never exposed on the public store\n * surface.\n */\ntype NodeCreateInternalOptions = Readonly<{\n /** `input.props` is already the output of `validateNodeProps`. */\n propsPreValidated?: boolean;\n}>;\n\nexport type NodeCreateDraft = Readonly<{\n kind: string;\n id: string;\n idProvided: boolean;\n nodeKind: NodeType;\n uniqueConstraints: readonly UniqueConstraint[];\n validatedProps: Record<string, unknown>;\n validFrom: string | undefined;\n validTo: string | undefined;\n}>;\n\nfunction draftNodeCreate<G extends GraphDef>(\n ctx: NodeOperationContext<G>,\n input: CreateNodeInput,\n id: string,\n options?: NodeCreateInternalOptions,\n): NodeCreateDraft {\n const kind = input.kind;\n const registration = getNodeRegistration(ctx.graph, kind);\n const nodeKind = registration.type;\n\n // getOrCreate / findByConstraint variants validate props up front (the\n // key computation needs the PARSED shape), then hand the validated\n // object here — re-running the full Zod parse on it would double the\n // validation cost of every create leg for no additional safety (hooks\n // wrap the transaction and cannot transform inputs in between).\n const validatedProps =\n options?.propsPreValidated === true ?\n input.props\n : validateNodeProps(nodeKind.schema, input.props, {\n kind,\n operation: \"create\",\n });\n\n const validFrom = validateOptionalCanonicalIsoDate(\n input.validFrom,\n \"validFrom\",\n );\n const validTo = validateOptionalCanonicalIsoDate(input.validTo, \"validTo\");\n // A stated pair must be ordered, and on an insert that is the COMPLETE rule.\n // A lone historical validTo is NOT an error — it means \"born already ended\"\n // (see assertWritableValidityWindow), and the insert stores no lower bound for\n // it rather than one past the stated end, so there is no effective bound left\n // for this layer to judge. Both create paths (single and batch) draft through\n // here, so this is the only insert-side check needed.\n assertOrderedValidityWindow(`${kind} \"${id}\"`, validFrom, validTo);\n\n return {\n kind,\n id,\n idProvided: input.id !== undefined,\n nodeKind,\n uniqueConstraints: registration.unique ?? [],\n validatedProps,\n validFrom,\n validTo,\n };\n}\n\n/**\n * The async half: existence, disjointness, and uniqueness checks.\n *\n * The existence probe's row is returned on the prepared record so fresh\n * inserts avoid a second read. Resurrection is the rare exception: it\n * re-checks the row immediately before writing because another transaction\n * may have resurrected it after preparation.\n */\nasync function finishNodeCreatePreparation<G extends GraphDef>(\n ctx: NodeOperationContext<G>,\n draft: NodeCreateDraft,\n backend: WriteTarget,\n): Promise<NodeCreatePrepared> {\n const { kind, id, validatedProps, uniqueConstraints } = draft;\n\n // This is the fast-path existence gate. Resurrection repeats it immediately\n // before the update because the row can change while constraints are checked.\n const existingNode = await backend.getNode(ctx.graphId, kind, id);\n if (existingNode && !existingNode.deleted_at) {\n throw createAlreadyExistsError(\"node\", kind, id);\n }\n\n const constraintContext: ConstraintContext = {\n graphId: ctx.graphId,\n registry: ctx.registry,\n backend,\n };\n await checkDisjointnessConstraint(constraintContext, kind, id);\n\n await checkUniquenessConstraints(\n createUniquenessContext(\n ctx.graphId,\n ctx.registry,\n backend,\n ctx.uniqueSidecarBatch,\n ),\n kind,\n id,\n validatedProps,\n uniqueConstraints,\n );\n\n return {\n kind,\n id,\n idProvided: draft.idProvided,\n tombstone: existingNode,\n nodeKind: draft.nodeKind,\n validatedProps,\n uniqueConstraints,\n insertParams: buildInsertNodeParams(\n ctx.graphId,\n kind,\n id,\n validatedProps,\n draft.validFrom,\n draft.validTo,\n ),\n };\n}\n\nasync function validateAndPrepareNodeCreate<G extends GraphDef>(\n ctx: NodeOperationContext<G>,\n input: CreateNodeInput,\n id: string,\n backend: WriteTarget,\n options?: NodeCreateInternalOptions,\n): Promise<NodeCreatePrepared> {\n return finishNodeCreatePreparation(\n ctx,\n draftNodeCreate(ctx, input, id, options),\n backend,\n );\n}\n\n/** What a prepared create hands the claim seam and the sync fans. */\nfunction nodeCreateSideEffectItem(\n prepared: NodeCreatePrepared,\n): NodeInsertSyncItem {\n return {\n kind: prepared.kind,\n id: prepared.id,\n schema: prepared.nodeKind.schema,\n props: prepared.validatedProps,\n uniqueConstraints: prepared.uniqueConstraints,\n };\n}\n\nfunction nodeCreateClaimItem(prepared: NodeCreatePrepared): NodeClaimItem {\n return {\n kind: prepared.kind,\n id: prepared.id,\n props: prepared.validatedProps,\n constraints: prepared.uniqueConstraints,\n };\n}\n\n/**\n * One prepared create as the session's insert unit: the row params, the claims\n * the row owes, and the sidecar inputs, as ONE value.\n *\n * This replaces the `finalizeNodeCreate` / `finalizeNodeCreateBatch` pair and\n * the claim seam the create paths used to open around their own insert. Each was\n * a HALF of a create, callable — and forgettable — on its own; the session takes\n * the whole unit and applies all three in the pinned order (pre-insert claims,\n * row, post-insert claims, sync fans).\n */\nfunction nodeInsertWork(prepared: NodeCreatePrepared): NodeInsertWork {\n return {\n params: prepared.insertParams,\n claim: nodeCreateClaimItem(prepared),\n sideEffects: nodeCreateSideEffectItem(prepared),\n };\n}\n\n/**\n * The created references identity folding actually has to consider.\n *\n * Folding looks for a live node carrying the SAME id under a DIFFERENT kind.\n * A generated id is fresh — nothing can already hold it — so only\n * caller-supplied ids can participate, and a batch of purely auto-id creates\n * needs no cross-kind probe at all.\n */\nfunction foldReferences(\n preparedCreates: readonly NodeCreatePrepared[],\n): readonly Readonly<{ kind: string; id: string }>[] {\n return preparedCreates\n .filter((prepared) => prepared.idProvided)\n .map((prepared) => ({ kind: prepared.kind, id: prepared.id }));\n}\n\n// ============================================================\n// Shared Update Pipeline\n//\n// executeNodeUpdate wraps this in operation hooks.\n// executeNodeUpsertUpdate calls it directly (no hooks) for\n// getOrCreate resurrections.\n// ============================================================\n\n/**\n * The exact props an update would persist: the caller's partial input merged\n * over the current props and run through the kind's Zod schema (defaults\n * applied, values normalized). Also returns the resolved registration so\n * callers need not look it up again. Operates on PARSED props so both the write\n * path (which parses the row) and the coalesce dirty-check (which may compare\n * against a batch-local running value, never a row) share one validation.\n */\nfunction computeNodeUpdate<G extends GraphDef>(\n ctx: NodeOperationContext<G>,\n kind: string,\n id: string,\n existingProps: Record<string, unknown>,\n inputProps: Partial<Record<string, unknown>>,\n) {\n const registration = getNodeRegistration(ctx.graph, kind);\n const validatedProps = validateNodeProps(\n registration.type.schema,\n { ...existingProps, ...inputProps },\n { kind, operation: \"update\", id },\n );\n return { registration, validatedProps };\n}\n\n/**\n * Row-based wrapper over {@link computeNodeUpdate} for the write path. Reads the\n * kind/id off the row (a `getNode(kind, id)` result always carries the\n * requested kind), matching {@link resolveEdgeUpdateProps}.\n */\nfunction resolveNodeUpdateProps<G extends GraphDef>(\n ctx: NodeOperationContext<G>,\n existing: Pick<NodeRow, \"kind\" | \"id\" | \"props\">,\n inputProps: Partial<Record<string, unknown>>,\n) {\n const existingProps = rowPropsToObject(existing.props);\n const { registration, validatedProps } = computeNodeUpdate(\n ctx,\n existing.kind,\n existing.id,\n existingProps,\n inputProps,\n );\n return { registration, existingProps, validatedProps };\n}\n\n/**\n * The coalesce dirty-check: returns the props an `upsertById` would persist and\n * whether they equal `existingProps` (so the write can be skipped). Compares on\n * the storage-normalized representation (validated, key-order-independent), so\n * it answers exactly \"would the persisted JSON differ?\". `existingProps` is the\n * PARSED current props — the row's, or the batch-local running value for a\n * repeated id in `bulkUpsertById`.\n */\nexport function nodeUpsertDirtyCheck<G extends GraphDef>(\n ctx: NodeOperationContext<G>,\n kind: string,\n id: string,\n existingProps: Record<string, unknown>,\n inputProps: Record<string, unknown>,\n): UpsertDirtyCheck {\n const { validatedProps } = computeNodeUpdate(\n ctx,\n kind,\n id,\n existingProps,\n inputProps,\n );\n return {\n validatedProps,\n unchanged: canonicalEqual(validatedProps, existingProps),\n };\n}\n\nasync function performNodeUpdate<G extends GraphDef>(\n ctx: NodeOperationContext<G>,\n input: UpsertUpdateNodeInput,\n session: NodeWriteSession,\n target: WriteTarget,\n options?: Readonly<{ clearDeleted?: boolean }>,\n): Promise<Node> {\n const { kind, id } = input;\n\n assertValidityEndMutation(input, { entityType: \"node\", kind, id });\n\n const existing = await target.getNode(ctx.graphId, kind, id);\n if (!existing) throw new NodeNotFoundError(kind, id);\n\n const { registration, validatedProps } = resolveNodeUpdateProps(\n ctx,\n existing,\n input.props,\n );\n const nodeKind = registration.type;\n\n const validTo = validateOptionalCanonicalIsoDate(input.validTo, \"validTo\");\n // A node resurrection RESETS `valid_from` (see `buildUpdateNode`), so its\n // effective lower bound is one this write stamps rather than the row's stored\n // one. The instant is sampled HERE and the bound resolved from it travels to\n // the backend as an explicit `validFrom`, because the guard has to measure\n // the bound the write will actually store: left to default, the builder's own\n // `resolveStampedValidityLowerBound` call would judge the backend's strictly\n // later sample, and a `validTo` at this instant would pass the guard as\n // zero-width and land as a different shape a millisecond later (issue #413).\n // An in-place update keeps the row's stored bound, which no write rewrites and\n // so needs no prediction.\n const resurrectionInstant =\n options?.clearDeleted === true && existing.deleted_at !== undefined ?\n nowIso()\n : undefined;\n // Event materializers may state the source row's lower bound on every\n // delivery while asking a live update to preserve the bound already stored.\n // This is explicit create/resurrection-only input, not the old silent drop:\n // the default remains `\"refuse\"`, and a resurrection still validates and\n // stores the stated value below.\n const preservesLiveLowerBound =\n resurrectionInstant === undefined &&\n preservesImmutableLowerBound(input.onImmutableLowerBound);\n const statedValidFrom = validateOptionalCanonicalIsoDate(\n input.validFrom,\n \"validFrom\",\n );\n const validFrom = preservesLiveLowerBound ? undefined : statedValidFrom;\n // The bound this resurrection will STORE, decided by the same owner every\n // insert builder decides through, against the instant sampled above. Asking\n // the owner rather than assuming `resurrectionInstant` is what makes a\n // resurrection carrying only a historical `validTo` reach the shape a create\n // reaches — no lower bound, \"ended at T, start unknown\" — instead of being\n // refused for inverting against an instant the write would never have stored\n // (I12). `undefined` here means \"no bound\", which is nothing to invert\n // against, so the verdict below judges exactly what lands.\n const resurrectionBound =\n resurrectionInstant === undefined ? undefined : (\n resolveStampedValidityLowerBound(validFrom, validTo, resurrectionInstant)\n );\n // A resurrection STORES a stated `validFrom` (it rewrites the whole window);\n // an in-place update never does, so one that differs from the row's stored\n // bound is refused rather than accepted and dropped.\n const windowVerdict = assertWritableValidityWindow(\n `${kind} \"${id}\"`,\n validFrom,\n resurrectionInstant === undefined ?\n {\n effectiveValidFrom: existing.valid_from,\n appliesStatedValidFrom: false,\n effectiveBoundIsStored: true,\n }\n : {\n effectiveValidFrom: resurrectionBound,\n appliesStatedValidFrom: true,\n // The bound this write is about to stamp, not one the row holds.\n effectiveBoundIsStored: false,\n },\n validTo,\n );\n\n const shared = {\n schema: nodeKind.schema,\n validatedProps,\n uniqueConstraints: registration.unique ?? [],\n ...(validTo !== undefined && { validTo }),\n ...(input.clearValidTo === true && { clearValidTo: true as const }),\n };\n // The bound the verdict above READ, carried into the UPDATE's own `WHERE` so\n // the row this writes is the row that was judged. The verdict hands over the\n // predicate rather than a flag, so both conditions that decide it — did the\n // verdict consult the effective bound, and WAS that bound the row's stored\n // one — are answered where they are known. A plain `update({ props })`\n // states no window, reads no bound, and stays unfenced: the same rule\n // `UpdateEdgeParams`'s identity components follow, for the same reason. The\n // resurrecting leg is judged against `resurrectionInstant` and so fences on\n // `deleted_at IS NOT NULL` alone, converging through the recovery below.\n //\n // It is now a REQUIRED argument rather than a spread convention: an update\n // that forgot to carry the bound its verdict read is a compile error.\n const fences: NodeUpdateFences = {\n validityLowerBound: windowVerdict.storedLowerBoundFence,\n };\n\n // A resurrecting upsert (clearDeleted) may target a tombstoned row; a plain\n // update must prove the row live — see NodeUpdateTarget.\n if (options?.clearDeleted) {\n // Keyed on the SAME condition the verdict was, because only that condition\n // produces a verdict to state. With `resurrectionInstant` defined this is\n // the DECISION, never an absence: omitting the key would let\n // `buildUpdateNode` re-derive the bound against the backend's own, strictly\n // later `timestamp`, so the two layers would agree only while the two clocks\n // do — the #413 hazard, one layer out. `null` is how `UpdateNodeParams`\n // spells \"store no lower bound\", which is what this decision resolves to for\n // a resurrection that ends at or before the instant it judged.\n //\n // With it UNDEFINED this read found the row live — a peer resurrected it\n // between the collection's probe and here — so the verdict judged the row's\n // stored bound and stamped nothing. There is no decision to state, and\n // stating one anyway would write away a `validFrom` the guard just ACCEPTED\n // as equal to that stored bound. The statement usually matches no row\n // (`deleted_at IS NOT NULL`) and the recovery below re-reads, but a peer that\n // re-tombstones before the UPDATE makes it match, so this leg carries the\n // stated bound exactly as the in-place leg does.\n const resurrectionLowerBound =\n resurrectionInstant === undefined ?\n validFrom !== undefined && { validFrom }\n // eslint-disable-next-line unicorn/no-null -- `validFrom: null` means \"store NULL\"; omitting the key means \"decide for me\", and this path has already decided. See UpdateNodeParams.validFrom.\n : { validFrom: resurrectionBound ?? null };\n const row = await session.reviseNode(\n { ...shared, existing, clearDeleted: true, ...resurrectionLowerBound },\n fences,\n );\n return rowToNode(row);\n }\n\n if (!isLiveNodeRow(existing)) throw new NodeNotFoundError(kind, id);\n const row = await session.reviseNode(\n // An in-place update must not rewrite the stored bound, so it keeps the\n // conditional spread: `buildUpdateNode` ignores `validFrom` off the\n // resurrection leg, and stating one here would claim a rewrite that no\n // statement performs.\n { ...shared, existing, ...(validFrom !== undefined && { validFrom }) },\n fences,\n );\n return rowToNode(row);\n}\n\n/**\n * How many probe-and-write rounds a node update gets before it stops trying to\n * converge. One retry: enough to absorb a single concurrent recreate, bounded\n * so a peer that keeps replacing the row cannot livelock this caller (the same\n * shape, and the same reasoning, as `getOrCreateByEndpoints`'s bounded loop).\n */\nconst NODE_UPDATE_ATTEMPTS = 2;\n\n/**\n * Runs a node update and CONVERGES on the row that is actually there when a\n * predicated UPDATE matches nothing.\n *\n * `performNodeUpdate` is a probe-and-write pair, and both of the predicates its\n * statement carries beyond `(graph_id, kind, id)` can stop matching between the\n * two under PostgreSQL READ COMMITTED:\n *\n * - `deleted_at IS NOT NULL` on the resurrecting leg — a peer resurrected the\n * tombstone first;\n * - `expectedValidFrom` on the in-place leg — a peer hard-deleted and\n * recreated the row, so the bound this update's window verdict was computed\n * against is gone.\n *\n * Both are the SAME event from the caller's side: the row moved under a\n * decision already made. Neither may surface as the zero-row\n * `DatabaseOperationError` the backend raises, which is an internal sentinel\n * and names nothing a caller can act on. So this re-reads and re-derives:\n *\n * - row gone, or tombstoned where the leg needs a live one — `NodeNotFoundError`,\n * exactly what the pre-write probe would have thrown;\n * - row live — retry the whole thing. The retry re-reads, re-merges the\n * caller's partial props over the CURRENT props, and re-judges the window\n * against the CURRENT bound, so a stated window that no longer fits is\n * refused with the same typed `ValidationError` the first attempt would have\n * raised. A resurrection that lost its race converges to an ordinary update,\n * which is upsert's documented semantics: the peer owns the new window, this\n * late writer owns the properties — and a caller that STATED a lower bound\n * for the resurrection it lost is therefore refused rather than silently\n * updated without it.\n *\n * Retrying rather than refusing is what keeps the fence from being a behavior\n * regression: the losing writer still lands its properties, on the row that is\n * really there, judged against the bounds that row really carries.\n */\nasync function performNodeUpdateWithResurrectionRecovery<G extends GraphDef>(\n ctx: NodeOperationContext<G>,\n input: UpsertUpdateNodeInput,\n session: NodeWriteSession,\n target: WriteTarget,\n options?: Readonly<{ clearDeleted?: boolean }>,\n): Promise<Node> {\n for (let attempt = 1; attempt <= NODE_UPDATE_ATTEMPTS; attempt += 1) {\n try {\n // Only the FIRST attempt may resurrect: reaching a retry means the row is\n // live, and an ordinary update is what converges on it.\n return await performNodeUpdate(\n ctx,\n input,\n session,\n target,\n attempt === 1 ? options : undefined,\n );\n } catch (error) {\n if (!isNodeUpdateNoRowError(error) || attempt === NODE_UPDATE_ATTEMPTS) {\n throw nodeUpdateRaceError(input, error);\n }\n const current = await target.getNode(ctx.graphId, input.kind, input.id);\n if (current === undefined || current.deleted_at !== undefined) {\n throw new NodeNotFoundError(input.kind, input.id);\n }\n }\n }\n // Unreachable: the loop either returns or throws on its last attempt.\n throw new NodeNotFoundError(input.kind, input.id);\n}\n\n/**\n * The error a caller sees when a node update exhausts its attempts, or fails\n * with something that is not the zero-row sentinel.\n *\n * A non-sentinel error passes through untouched. The sentinel does not: it says\n * \"the statement matched nothing\", which after {@link NODE_UPDATE_ATTEMPTS}\n * rounds means a peer is replacing this row faster than this writer can read\n * it. That is a contention fact, and it is reported as one rather than as a\n * missing node — the node is present, it just is not staying still.\n */\nfunction nodeUpdateRaceError(\n input: UpsertUpdateNodeInput,\n error: unknown,\n): unknown {\n if (!isNodeUpdateNoRowError(error)) return error;\n return new DatabaseOperationError(\n `Node update for ${input.kind} \"${input.id}\" could not be applied to a stable row after ${NODE_UPDATE_ATTEMPTS} attempts: the row was removed and recreated between each read and its write. A concurrent writer is replacing this node faster than it can be read; serialize the writers, or retry.`,\n {\n operation: \"update\",\n entity: \"node\",\n attempted: [{ kind: input.kind, id: input.id }],\n },\n { cause: error },\n );\n}\n\n// ============================================================\n// Shared Batch Preparation\n//\n// Both returning and non-returning batch creates share the same\n// validate-and-register loop. This extracts it.\n// ============================================================\n\n/**\n * Primes the batch validation caches with batched reads: one `getNodes`\n * per kind for existence probes and one `checkUniqueBatch` per\n * (constraint, kind) for uniqueness pre-checks. The per-row checks in\n * {@link finishNodeCreatePreparation} then hit memory instead of issuing\n * one probe per row. Backends without the batch primitives skip priming\n * and keep the per-row fallback.\n */\nexport async function primeBatchValidationCaches(\n ctx: Readonly<{\n graphId: string;\n registry: KindRegistry;\n batchPointRead: BundleVerdictOf<typeof BATCH_POINT_READ>;\n uniqueSidecarBatch: BundleVerdictOf<typeof UNIQUE_SIDECAR_BATCH>;\n }>,\n drafts: readonly NodeCreateDraft[],\n backend: WriteTarget,\n seams: Readonly<{\n seedNodeRow: (kind: string, id: string, row: CachedNodeRow) => void;\n seedUniqueRow: (\n kind: string,\n constraintName: string,\n key: string,\n row: CachedUniqueRow,\n ) => void;\n }>,\n): Promise<void> {\n const boundGetNodes = bindExtraIfReachable(\n backend,\n ctx.batchPointRead.extras.getNodes,\n BATCH_POINT_READ.id,\n );\n if (boundGetNodes !== undefined) {\n const idsByKind = new Map<string, Set<string>>();\n for (const draft of drafts) {\n const ids = idsByKind.get(draft.kind) ?? new Set<string>();\n ids.add(draft.id);\n idsByKind.set(draft.kind, ids);\n }\n for (const [kind, ids] of idsByKind) {\n const orderedIds = [...ids];\n const rows = await boundGetNodes.getNodes(ctx.graphId, kind, orderedIds);\n const rowsById = new Map(rows.map((row) => [row.id, row]));\n for (const id of orderedIds) {\n seams.seedNodeRow(kind, id, rowsById.get(id));\n }\n }\n }\n\n const boundCheckUniqueBatch = bindExtraIfReachable(\n backend,\n ctx.uniqueSidecarBatch.extras.checkUniqueBatch,\n UNIQUE_SIDECAR_BATCH.id,\n );\n if (boundCheckUniqueBatch !== undefined) {\n interface ProbeGroup {\n nodeKind: string;\n constraintName: string;\n keys: Set<string>;\n }\n const groups = new Map<string, ProbeGroup>();\n for (const draft of drafts) {\n for (const entry of nodeClaimEntries(\n ctx.registry,\n draft.kind,\n draft.id,\n draft.validatedProps,\n draft.uniqueConstraints,\n \"create\",\n )) {\n // Uniqueness entries only: this primes the reads the UNIQUENESS probe\n // makes. A disjointness entry's verdict comes from the disjoint\n // partner's node row, which no `checkUnique` read would supply.\n if (entry.refusal.kind !== \"uniqueness\") continue;\n const constraint = entry.refusal.constraint;\n const key = entry.key;\n // Seeded over exactly the kinds the per-row probe reads — the axis and\n // the legacy kinds — so priming stays a batched substitute for those\n // reads rather than a narrower set that sends them back to the\n // database one row at a time.\n const kindsToCheck = uniquenessProbeKinds(\n draft.kind,\n constraint.scope,\n ctx.registry,\n );\n for (const kindToCheck of kindsToCheck) {\n const groupKey = encodeTupleKey([kindToCheck, constraint.name]);\n const group = groups.get(groupKey) ?? {\n nodeKind: kindToCheck,\n constraintName: constraint.name,\n keys: new Set<string>(),\n };\n group.keys.add(key);\n groups.set(groupKey, group);\n }\n }\n }\n for (const group of groups.values()) {\n const orderedKeys = [...group.keys];\n const rows = await boundCheckUniqueBatch.checkUniqueBatch({\n graphId: ctx.graphId,\n nodeKind: group.nodeKind,\n constraintName: group.constraintName,\n keys: orderedKeys,\n });\n const rowsByKey = new Map(rows.map((row) => [row.key, row]));\n for (const key of orderedKeys) {\n seams.seedUniqueRow(\n group.nodeKind,\n group.constraintName,\n key,\n rowsByKey.get(key),\n );\n }\n }\n }\n}\n\nasync function prepareBatchCreates<G extends GraphDef>(\n ctx: NodeOperationContext<G>,\n inputs: readonly CreateNodeInput[],\n backend: WriteTarget,\n options?: NodeCreateInternalOptions,\n): Promise<readonly NodeCreatePrepared[]> {\n const {\n reader: validationBackend,\n registerPendingNode,\n registerPendingUniqueEntries,\n seedNodeRow,\n seedUniqueRow,\n } = createNodeBatchValidationSeams(ctx.graphId, ctx.registry, backend);\n\n // Pass 1 (synchronous): validate every input and assign ids. This\n // surfaces a later row's validation error before an earlier row's\n // constraint error — both fail the whole batch, so ordering across\n // error categories is not part of the contract.\n const drafts = inputs.map((input) =>\n draftNodeCreate(ctx, input, input.id ?? generateId(), options),\n );\n\n await primeBatchValidationCaches(ctx, drafts, backend, {\n seedNodeRow,\n seedUniqueRow,\n });\n\n // Pass 2: per-row constraint checks against the primed caches, in input\n // order, registering pendings so later rows see earlier ones.\n const preparedCreates: NodeCreatePrepared[] = [];\n for (const draft of drafts) {\n const prepared = await finishNodeCreatePreparation(\n ctx,\n draft,\n validationBackend,\n );\n preparedCreates.push(prepared);\n registerPendingNode(prepared.insertParams);\n registerPendingUniqueEntries(\n prepared.kind,\n prepared.id,\n prepared.validatedProps,\n prepared.uniqueConstraints,\n );\n }\n\n return preparedCreates;\n}\n\ntype CreatePartition = Readonly<{\n inserts: readonly NodeCreatePrepared[];\n resurrections: readonly NodeCreatePrepared[];\n}>;\n\n/**\n * Splits prepared creates into fresh inserts and tombstone resurrections.\n *\n * Purely in-memory: preparation already read each id's row under this write\n * lock (batched through `getNodes` when the backend has it, per-row through\n * the validation cache otherwise) and carried it on the prepared record, so\n * routing costs no additional round trip.\n */\nfunction partitionCreates(\n preparedCreates: readonly NodeCreatePrepared[],\n): CreatePartition {\n const inserts: NodeCreatePrepared[] = [];\n const resurrections: NodeCreatePrepared[] = [];\n\n for (const prepared of preparedCreates) {\n if (prepared.tombstone === undefined) {\n inserts.push(prepared);\n } else {\n resurrections.push(prepared);\n }\n }\n return { inserts, resurrections };\n}\n\nfunction isNodeUpdateNoRowError(\n error: unknown,\n): error is DatabaseOperationError {\n return (\n error instanceof DatabaseOperationError &&\n error.details.operation === \"update\" &&\n error.details.entity === \"node\" &&\n error.details.reason === \"no_row_returned\"\n );\n}\n\nasync function resurrectPreparedNode<G extends GraphDef>(\n ctx: NodeOperationContext<G>,\n session: NodeWriteSession,\n target: WriteTarget,\n prepared: NodeCreatePrepared,\n): Promise<BackendNodeRow> {\n const current = await target.getNode(ctx.graphId, prepared.kind, prepared.id);\n if (current === undefined) {\n throw new DatabaseOperationError(\n `Node tombstone disappeared before resurrection: ${prepared.kind} ${prepared.id}`,\n { operation: \"update\", entity: \"node\" },\n );\n }\n if (current.deleted_at === undefined) {\n throw createAlreadyExistsError(\"node\", prepared.kind, prepared.id);\n }\n // A create landing on a tombstone RESETS the window, so this leg stamps a\n // bound whenever the caller stated none — and it decides which one through\n // the same owner `performNodeUpdate`'s resurrection leg and every insert\n // builder use, against an instant sampled HERE. Two consequences. The stored\n // bound is the one this layer judged rather than the backend's strictly later\n // sample, so one write has one instant (issue #413). And a create carrying\n // only a historical `validTo` reaches the same stored shape on a tombstoned\n // id as on a fresh one — no lower bound (I12).\n const resurrectionInstant = nowIso();\n const resurrectionBound = resolveStampedValidityLowerBound(\n prepared.insertParams.validFrom,\n prepared.insertParams.validTo,\n resurrectionInstant,\n );\n try {\n return await session.reviseNode(\n {\n existing: current,\n clearDeleted: true,\n schema: prepared.nodeKind.schema,\n validatedProps: prepared.validatedProps,\n uniqueConstraints: prepared.uniqueConstraints,\n // The decision itself, never an absence — see the same spelling on\n // `performNodeUpdate`'s resurrection leg.\n // eslint-disable-next-line unicorn/no-null -- `validFrom: null` means \"store NULL\"; omitting the key means \"decide for me\", and this path has already decided. See UpdateNodeParams.validFrom.\n validFrom: resurrectionBound ?? null,\n ...(prepared.insertParams.validTo === undefined ?\n {}\n : { validTo: prepared.insertParams.validTo }),\n },\n // This resurrection reads no stored bound: it rewrites the whole window\n // and is fenced by the UPDATE's own `deleted_at IS NOT NULL` predicate,\n // so it asserts nothing about `valid_from`. `{}` is how a write states\n // that, and it is the only way to state it.\n { validityLowerBound: {} },\n );\n } catch (error) {\n if (!isNodeUpdateNoRowError(error)) throw error;\n // The UPDATE itself has a tombstone predicate, closing the remaining gap\n // between the re-read and write. Translate a peer resurrection into the\n // create API's stable duplicate error instead of leaking a 0-row update.\n const afterFailure = await target.getNode(\n ctx.graphId,\n prepared.kind,\n prepared.id,\n );\n if (afterFailure !== undefined && afterFailure.deleted_at === undefined) {\n throw createAlreadyExistsError(\"node\", prepared.kind, prepared.id);\n }\n throw error;\n }\n}\n\n// ============================================================\n// Shared Constraint Lookup\n//\n// Both single and bulk find/getOrCreate operations need to look up\n// unique constraint entries across all applicable kinds.\n// ============================================================\n\n/**\n * THE preference rule when a key has claim rows at more than one kind — which a\n * database carrying pre-axis rows legitimately can, at the axis AND at a\n * concrete kind, with different owners:\n *\n * 1. Visit the AXIS first, then the remaining kinds in scope in code-point\n * order — the order {@link uniquenessProbeKinds} defines, so this reads what\n * the write path claims before it reads what an older version claimed.\n * 2. Prefer a LIVE row over a tombstoned one, wherever each was found: a\n * tombstone is a released reservation, and reviving it while a live holder\n * exists would hand the caller the wrong node.\n * 3. Among rows of the same liveness prefer the axis row, which rule 1 already\n * delivers.\n *\n * Stated rather than left to iteration order because `getOrCreateByConstraint`\n * decides which node to revive from it.\n */\nfunction prefersClaimRow(\n incumbent: UniqueMatchRow | undefined,\n candidate: UniqueMatchRow,\n): boolean {\n if (incumbent === undefined) return true;\n return (\n incumbent.deleted_at !== undefined && candidate.deleted_at === undefined\n );\n}\n\nasync function findUniqueRowAcrossKinds(\n backend: WriteTarget,\n graphId: string,\n constraintName: string,\n key: string,\n kindsToCheck: readonly string[],\n includeDeleted: boolean,\n): Promise<UniqueMatchRow | undefined> {\n // `let` earns its place: a tombstoned hit does not end the search, because a\n // live row later in the order outranks it (rule 2).\n let preferred: UniqueMatchRow | undefined;\n for (const kindToCheck of kindsToCheck) {\n const row = await backend.checkUnique({\n graphId,\n nodeKind: kindToCheck,\n constraintName,\n key,\n includeDeleted,\n });\n if (row === undefined) continue;\n if (!prefersClaimRow(preferred, row)) continue;\n preferred = row;\n if (row.deleted_at === undefined) return row;\n }\n return preferred;\n}\n\ninterface UniqueMatchRow {\n node_id: string;\n concrete_kind: string;\n deleted_at: string | undefined;\n}\n\nasync function batchCheckUniqueAcrossKinds(\n backend: WriteTarget,\n uniqueSidecarBatch: BundleVerdictOf<typeof UNIQUE_SIDECAR_BATCH>,\n graphId: string,\n constraintName: string,\n uniqueKeys: readonly string[],\n kindsToCheck: readonly string[],\n includeDeleted: boolean,\n): Promise<Map<string, UniqueMatchRow>> {\n const existingByKey = new Map<string, UniqueMatchRow>();\n const boundCheckUniqueBatch = bindExtraIfReachable(\n backend,\n uniqueSidecarBatch.extras.checkUniqueBatch,\n UNIQUE_SIDECAR_BATCH.id,\n );\n\n for (const kindToCheck of kindsToCheck) {\n if (boundCheckUniqueBatch === undefined) {\n for (const key of uniqueKeys) {\n const incumbent = existingByKey.get(key);\n if (incumbent !== undefined && incumbent.deleted_at === undefined) {\n continue;\n }\n const row = await backend.checkUnique({\n graphId,\n nodeKind: kindToCheck,\n constraintName,\n key,\n includeDeleted,\n });\n if (row !== undefined && prefersClaimRow(incumbent, row)) {\n existingByKey.set(row.key, row);\n }\n }\n } else {\n const rows = await boundCheckUniqueBatch.checkUniqueBatch({\n graphId,\n nodeKind: kindToCheck,\n constraintName,\n keys: uniqueKeys,\n includeDeleted,\n });\n for (const row of rows) {\n if (prefersClaimRow(existingByKey.get(row.key), row)) {\n existingByKey.set(row.key, row);\n }\n }\n }\n }\n\n return existingByKey;\n}\n\n// ============================================================\n// Node Create Operations\n// ============================================================\n\nasync function executeNodeCreateInternal<G extends GraphDef>(\n ctx: NodeOperationContext<G>,\n input: CreateNodeInput,\n backend: GraphBackend | TransactionBackend,\n options?: Readonly<{ returnRow?: boolean }> & NodeCreateInternalOptions,\n): Promise<Node | undefined> {\n const kind = input.kind;\n const id = input.id ?? generateId();\n const opContext = ctx.createOperationContext(\"create\", \"node\", kind, id);\n const shouldReturnRow = options?.returnRow ?? true;\n\n return runHookedWritePlan(\n nodeWritePlanContext(ctx),\n opContext,\n nodeWritePlan(\n nodeFencesConstraintProbe(ctx, kind, \"create\"),\n nodeRequiresIdentityLock(ctx),\n ),\n backend,\n async (session, target) => {\n const identity = ctx.identity;\n const prepared = await validateAndPrepareNodeCreate(\n ctx,\n input,\n id,\n target,\n options,\n );\n\n const existing = prepared.tombstone;\n if (existing !== undefined) {\n const resurrected = await resurrectPreparedNode(\n ctx,\n session,\n target,\n prepared,\n );\n if (identity !== undefined) {\n await identity.foldCreated(target, foldReferences([prepared]));\n }\n return shouldReturnRow ? rowToNode(resurrected) : undefined;\n }\n\n // The existence probe above is not the last word: on an engine that does\n // not serialize the two writers, a concurrent create of the same new id\n // can commit between the probe and this INSERT, and only the engine's\n // refusal reports it. Both routes to that conclusion raise the same error.\n //\n // The claims are the session's, at their declared placements: the\n // pre-insert group gates the row and is compensated away if it does not\n // land, the post-insert group follows it. The translation spans the fused\n // unit — claims, row AND sidecars — because the session applies them\n // together. That widening is inert: `isDuplicateKeyInsertError` fires only\n // on a classified node-INSERT duplicate, which no claim, fulltext or\n // embedding write raises. The alternative — the session owning the\n // translation — would change import's create-leg error type on a lost\n // race, which it must not.\n const row = await withAlreadyExistsTranslation(\"node\", async () => {\n const work = nodeInsertWork(prepared);\n if (shouldReturnRow) return session.createNode(work);\n await session.createNodeNoReturn(work);\n return;\n });\n\n if (identity !== undefined) {\n await identity.foldCreated(target, foldReferences([prepared]));\n }\n\n if (row === undefined) return;\n return rowToNode(row);\n },\n );\n}\n\nexport async function executeNodeCreate<G extends GraphDef>(\n ctx: NodeOperationContext<G>,\n input: CreateNodeInput,\n backend: GraphBackend | TransactionBackend,\n options?: NodeCreateInternalOptions,\n): Promise<Node> {\n const result = await executeNodeCreateInternal(ctx, input, backend, {\n returnRow: true,\n ...options,\n });\n if (!result) {\n throw new DatabaseOperationError(\n \"Node create failed: expected created node row\",\n { operation: \"insert\", entity: \"node\" },\n );\n }\n return result;\n}\n\nexport async function executeNodeCreateNoReturn<G extends GraphDef>(\n ctx: NodeOperationContext<G>,\n input: CreateNodeInput,\n backend: GraphBackend | TransactionBackend,\n): Promise<void> {\n await executeNodeCreateInternal(ctx, input, backend, { returnRow: false });\n}\n\n/**\n * Executes batched node creates without returning inserted node payloads.\n *\n * Note: `withOperationHooks` is intentionally skipped for batch throughput.\n * Per-item hooks would negate the performance benefit of batching.\n */\nexport async function executeNodeCreateNoReturnBatch<G extends GraphDef>(\n ctx: NodeOperationContext<G>,\n inputs: readonly CreateNodeInput[],\n backend: GraphBackend | TransactionBackend,\n): Promise<void> {\n if (inputs.length === 0) return;\n\n await runWritePlan(\n nodeWritePlanContext(ctx),\n nodeBatchWritePlan(\n nodeBatchConstraintProbes(ctx, inputs, \"create\"),\n nodeRequiresIdentityLock(ctx),\n ),\n backend,\n async (session, target) => {\n const identity = ctx.identity;\n const preparedCreates = await prepareBatchCreates(ctx, inputs, target);\n\n const partition = partitionCreates(preparedCreates);\n // ## Resurrections follow the whole insert unit\n //\n // The batch INSERT, its claim groups and its sidecar batch are ONE session\n // call, so the resurrection updates that used to run BETWEEN the insert and\n // the fans now run after all of them. That is the one statement-order\n // difference this migration makes, and it is safe because the two groups\n // touch disjoint rows: a prepared create is either an insert or a\n // resurrection, never both, and the embedding/fulltext rows are\n // node-id-keyed. Their only shared resource is the claim relation — and two\n // batch members claiming one key are already refused during preparation,\n // which registers each row's pending claims so a later row sees an earlier\n // one ({@link prepareBatchCreates}). So no error this batch can raise\n // depends on which of the two groups writes first.\n await withAlreadyExistsTranslation(\"node\", () =>\n session.createNodesNoReturn(\n partition.inserts.map((prepared) => nodeInsertWork(prepared)),\n ),\n );\n for (const prepared of partition.resurrections) {\n await resurrectPreparedNode(ctx, session, target, prepared);\n }\n if (identity !== undefined) {\n await identity.foldCreated(target, foldReferences(preparedCreates));\n }\n },\n );\n}\n\n/**\n * Executes batched node creates and returns the inserted node payloads.\n *\n * Uses batch validation caching and a single multi-row INSERT with RETURNING\n * when the backend supports it. Falls back to sequential inserts otherwise.\n *\n * Note: `withOperationHooks` is intentionally skipped for batch throughput.\n * Per-item hooks would negate the performance benefit of batching.\n */\nexport async function executeNodeCreateBatch<G extends GraphDef>(\n ctx: NodeOperationContext<G>,\n inputs: readonly CreateNodeInput[],\n backend: GraphBackend | TransactionBackend,\n options?: NodeCreateInternalOptions,\n): Promise<readonly Node[]> {\n if (inputs.length === 0) return [];\n\n return runWritePlan(\n nodeWritePlanContext(ctx),\n nodeBatchWritePlan(\n nodeBatchConstraintProbes(ctx, inputs, \"create\"),\n nodeRequiresIdentityLock(ctx),\n ),\n backend,\n async (session, target) => {\n const identity = ctx.identity;\n const preparedCreates = await prepareBatchCreates(\n ctx,\n inputs,\n target,\n options,\n );\n\n const partition = partitionCreates(preparedCreates);\n // One call for claims + row + sidecars, so the resurrections follow the\n // whole unit — same reasoning as {@link executeNodeCreateNoReturnBatch}.\n const inserted = await withAlreadyExistsTranslation(\"node\", () =>\n session.createNodes(\n partition.inserts.map((prepared) => nodeInsertWork(prepared)),\n ),\n );\n const resurrected: BackendNodeRow[] = [];\n for (const prepared of partition.resurrections) {\n resurrected.push(\n await resurrectPreparedNode(ctx, session, target, prepared),\n );\n }\n const byReference = new Map(\n [...inserted, ...resurrected].map((row) => [\n refKey({ kind: row.kind, id: row.id }),\n row,\n ]),\n );\n const rows = preparedCreates.map((prepared) =>\n requireDefined(\n byReference.get(refKey({ kind: prepared.kind, id: prepared.id })),\n `Missing written row for ${prepared.kind} ${prepared.id}`,\n ),\n );\n if (identity !== undefined) {\n await identity.foldCreated(target, foldReferences(preparedCreates));\n }\n\n return rows.map((row) => rowToNode(row));\n },\n );\n}\n\n// ============================================================\n// Node Update Operations\n// ============================================================\n\nexport async function executeNodeUpdate<G extends GraphDef>(\n ctx: NodeOperationContext<G>,\n input: UpsertUpdateNodeInput,\n backend: GraphBackend | TransactionBackend,\n options?: Readonly<{ clearDeleted?: boolean }>,\n): Promise<Node> {\n // The capability refusal is taken on the backend the CALLER handed in, before\n // the frame opens: a stated `clearValidTo` a backend does not promise to apply\n // must be refused, never accepted and dropped, and no transaction is needed to\n // read a capability. Same placement as `executeNodeUpsertUpdate`'s.\n if (input.clearValidTo === true) {\n assertClearValidToSupported(backend, \"node\");\n }\n const opContext = ctx.createOperationContext(\n \"update\",\n \"node\",\n input.kind,\n input.id,\n );\n return runHookedWritePlan(\n nodeWritePlanContext(ctx),\n opContext,\n nodeWritePlan(\n nodeFencesConstraintProbe(ctx, input.kind, \"update\"),\n // Identity participates in an update when it RESURRECTS, and when it\n // states a validity end: a live-row update cannot change a node's kind, so\n // nothing folds, but an end reads the identity assertions that touch it.\n options?.clearDeleted === true || input.validTo !== undefined ?\n nodeRequiresIdentityLock(ctx)\n : false,\n ),\n backend,\n async (session, target) => {\n const validTo = validateOptionalCanonicalIsoDate(\n input.validTo,\n \"validTo\",\n );\n const identity = ctx.identity;\n if (identity !== undefined && validTo !== undefined) {\n await identity.requireValidityEndCompatible(\n target,\n { kind: input.kind, id: input.id },\n validTo,\n );\n }\n const node = await performNodeUpdateWithResurrectionRecovery(\n ctx,\n input,\n session,\n target,\n options,\n );\n if (options?.clearDeleted && identity !== undefined) {\n await identity.foldCreated(target, [\n { kind: input.kind, id: input.id },\n ]);\n }\n return node;\n },\n );\n}\n\n/**\n * Executes an atomic, set-based update of current nodes. The backend returns\n * every after-image so the Store can validate the complete rows before\n * rebuilding all derived sidecars inside the same transaction.\n */\nexport async function executeNodeUpdateWhere<G extends GraphDef>(\n ctx: NodeOperationContext<G>,\n kind: string,\n inputPatch: Record<string, unknown>,\n candidateIds: CompiledSelectSql,\n candidateIdColumn: string,\n backend: GraphBackend | TransactionBackend,\n): Promise<Readonly<{ affectedCount: number }>> {\n const registration = getNodeRegistration(ctx.graph, kind);\n const schema = registration.type.schema;\n const uniqueConstraints = registration.unique ?? [];\n\n if (!backend.capabilities.transactions) {\n throw new ConfigurationError(\n \"updateWhere() requires a transactional backend so validation and sidecars are atomic\",\n { code: \"SET_UPDATE_TRANSACTIONS_REQUIRED\", kind },\n );\n }\n if (backend.updateNodeSet === undefined) {\n throw new ConfigurationError(\n \"This backend does not support set-based node updates\",\n { code: \"SET_UPDATE_UNSUPPORTED\", kind },\n );\n }\n if (Object.keys(inputPatch).length === 0) {\n throw new ValidationError(\"updateWhere() patch must not be empty\", {\n entityType: \"node\",\n kind,\n operation: \"update\",\n issues: [{ path: \"patch\", message: \"Provide at least one property\" }],\n });\n }\n const unknownProperty = Object.keys(inputPatch).find(\n (property) => !Object.hasOwn(schema.shape, property),\n );\n if (unknownProperty !== undefined) {\n throw new ValidationError(\n `Unknown ${kind} property in updateWhere() patch: ${unknownProperty}`,\n {\n entityType: \"node\",\n kind,\n operation: \"update\",\n issues: [\n {\n path: unknownProperty,\n message: \"Property is not declared by the node schema\",\n },\n ],\n },\n );\n }\n\n const parsedPatch = validateNodeProps(schema.partial(), inputPatch, {\n kind,\n operation: \"update\",\n });\n // Data-keyed: `property` comes from the caller's patch object.\n const patch = createDataKeyedBag<JsonValue>();\n const unsetProperties: string[] = [];\n for (const [property, value] of Object.entries(parsedPatch)) {\n if (value === undefined) {\n unsetProperties.push(property);\n continue;\n }\n assertJsonValue(value, property, `Node \"${kind}\" updateWhere patch`);\n patch[property] = value as JsonValue;\n }\n if (Object.keys(patch).length === 0 && unsetProperties.length === 0) {\n throw new ValidationError(\n \"updateWhere() patch has no recognized properties\",\n {\n entityType: \"node\",\n kind,\n operation: \"update\",\n issues: [\n { path: \"patch\", message: \"Provide a declared node property\" },\n ],\n },\n );\n }\n\n if (\n uniqueConstraints.length > 0 &&\n missingRequiredExtras(\n UNIQUE_SIDECAR_BATCH,\n ctx.uniqueSidecarBatch,\n \"set-based node update\",\n ).length > 0\n ) {\n throw new ConfigurationError(\n \"updateWhere() requires batched uniqueness sidecar operations for constrained nodes\",\n { code: \"SET_UPDATE_UNIQUENESS_UNSUPPORTED\", kind },\n );\n }\n if (\n getSearchableFields(schema).length > 0 &&\n (backend.upsertFulltext === undefined ||\n backend.deleteFulltext === undefined ||\n backend.upsertFulltextBatch === undefined ||\n backend.deleteFulltextBatch === undefined)\n ) {\n throw new ConfigurationError(\n \"updateWhere() requires batched fulltext sidecar operations for searchable nodes\",\n { code: \"SET_UPDATE_FULLTEXT_UNSUPPORTED\", kind },\n );\n }\n if (\n getEmbeddingFields(schema).length > 0 &&\n (backend.upsertEmbedding === undefined ||\n backend.deleteEmbedding === undefined ||\n backend.upsertEmbeddingBatch === undefined ||\n backend.deleteEmbeddingBatch === undefined)\n ) {\n throw new ConfigurationError(\n \"updateWhere() requires batched vector sidecar operations for embedded nodes\",\n { code: \"SET_UPDATE_VECTOR_UNSUPPORTED\", kind },\n );\n }\n\n const hookContext = ctx.createBulkOperationContext(\"updateWhere\", kind);\n return ctx.withBulkOperationHooks(hookContext, () =>\n runWritePlan(\n nodeWritePlanContext(ctx),\n // The set update re-checks every changed unique key across the\n // constraint's scope before rebuilding the sidecars, so a shared-scope\n // constraint makes it a constrained write like any other update.\n // Identity does not participate: a set update rewrites props, and no\n // patch can change a node's kind.\n nodeWritePlan(nodeFencesConstraintProbe(ctx, kind, \"update\"), false),\n backend,\n (session) =>\n session.reviseNodeSet(\n {\n kind,\n schema,\n uniqueConstraints,\n patch,\n unsetProperties,\n candidateIds,\n candidateIdColumn,\n },\n // This path states no window — it patches properties — so the write\n // asserts no stored lower bound. The set UPDATE has no field to\n // carry one, so a future windowed set update is refused here rather\n // than run unfenced.\n { validityLowerBound: {} },\n ),\n { didWrite: (result) => result.affectedCount > 0 },\n ),\n );\n}\n\n/**\n * Executes a node update for upsert — bypasses operation hooks\n * and allows updating soft-deleted nodes when clearDeleted is set.\n */\nexport async function executeNodeUpsertUpdate<G extends GraphDef>(\n ctx: NodeOperationContext<G>,\n input: UpsertUpdateNodeInput,\n backend: GraphBackend | TransactionBackend,\n options?: Readonly<{ clearDeleted?: boolean }>,\n): Promise<Node> {\n if (input.clearValidTo === true) {\n assertClearValidToSupported(backend, \"node\");\n }\n return runWritePlan(\n nodeWritePlanContext(ctx),\n nodeWritePlan(\n nodeFencesConstraintProbe(ctx, input.kind, \"update\"),\n // Conditional for the same reason as {@link executeNodeUpdate}: a\n // resurrecting upsert folds, and stating a validity end reads the\n // identity's other members, so both take the lock.\n options?.clearDeleted === true || input.validTo !== undefined ?\n nodeRequiresIdentityLock(ctx)\n : false,\n ),\n backend,\n async (session, target) => {\n const validTo = validateOptionalCanonicalIsoDate(\n input.validTo,\n \"validTo\",\n );\n const identity = ctx.identity;\n if (identity !== undefined && validTo !== undefined) {\n await identity.requireValidityEndCompatible(\n target,\n { kind: input.kind, id: input.id },\n validTo,\n );\n }\n const node = await performNodeUpdateWithResurrectionRecovery(\n ctx,\n input,\n session,\n target,\n options,\n );\n if (options?.clearDeleted && identity !== undefined) {\n await identity.foldCreated(target, [\n { kind: input.kind, id: input.id },\n ]);\n }\n return node;\n },\n );\n}\n\n// ============================================================\n// Node Delete Operations\n// ============================================================\n\nexport async function executeNodeDelete<G extends GraphDef>(\n ctx: NodeOperationContext<G>,\n kind: string,\n id: string,\n backend: GraphBackend | TransactionBackend,\n): Promise<void> {\n // Gate outside hooks and transaction (matching edge deletes): an absent or\n // already-tombstoned node is a no-op, so it neither fires hooks nor opens a\n // write transaction (empty transactions are costly on libsql). The cascade\n // re-reads inside the transaction, so a node concurrently deleted between\n // this gate and the write lock is still handled correctly.\n const gate = await backend.getNode(ctx.graphId, kind, id);\n if (!gate || gate.deleted_at) return;\n\n const opContext = ctx.createOperationContext(\"delete\", \"node\", kind, id);\n\n return runHookedWritePlan(\n nodeWritePlanContext(ctx),\n opContext,\n nodeWritePlan(undefined, nodeRequiresIdentityLock(ctx)),\n backend,\n async (session, target) => {\n const identity = ctx.identity;\n const registration = getNodeRegistration(ctx.graph, kind);\n // This preflight is NOT removable round-trip fat: the soft-delete\n // pipeline consumes the pre-image (uniqueness entries are keyed by\n // props-derived constraint keys), and this in-transaction read is\n // the concurrency-correct source for it.\n const preflight = await target.getNode(ctx.graphId, kind, id);\n if (!preflight || !isLiveNodeRow(preflight)) return;\n\n // The cascade (connected edges, uniques, embeddings, fulltext, node) is\n // not individually atomic, so it runs in one write transaction. Under\n // recorded-time capture this also collapses the cascade into a single\n // recorded commit instant instead of one instant per sub-write.\n await session.retireNode({\n existing: preflight,\n schema: registration.type.schema,\n uniqueConstraints: registration.unique ?? [],\n onDelete: registration.onDelete,\n });\n if (identity !== undefined) {\n await identity.detachDeleted(target, { kind, id }, \"soft\");\n }\n },\n );\n}\n\n/**\n * Soft-deletes a batch without per-item operation hooks.\n *\n * Batch collection methods deliberately omit per-item hooks for throughput.\n * Owning the write transaction here also prevents a per-item success from\n * being reported before the batch's outer COMMIT.\n */\nexport async function executeNodeDeleteBatch<G extends GraphDef>(\n ctx: NodeOperationContext<G>,\n kind: string,\n ids: readonly string[],\n backend: GraphBackend | TransactionBackend,\n): Promise<void> {\n await runWritePlan(\n nodeWritePlanContext(ctx),\n nodeWritePlan(undefined, nodeRequiresIdentityLock(ctx)),\n backend,\n async (session, target) => {\n const identity = ctx.identity;\n const registration = getNodeRegistration(ctx.graph, kind);\n let affectedCount = 0;\n\n for (const id of ids) {\n // This is both the existence gate and the concurrency-correct\n // pre-image consumed by uniqueness cleanup. It must stay inside the\n // batch transaction after the graph write lock is held.\n const preflight = await target.getNode(ctx.graphId, kind, id);\n if (!preflight || !isLiveNodeRow(preflight)) continue;\n\n await session.retireNode({\n existing: preflight,\n schema: registration.type.schema,\n uniqueConstraints: registration.unique ?? [],\n onDelete: registration.onDelete,\n });\n if (identity !== undefined) {\n await identity.detachDeleted(target, { kind, id }, \"soft\");\n }\n affectedCount += 1;\n }\n\n return affectedCount;\n },\n { didWrite: (affectedCount) => affectedCount > 0 },\n );\n}\n\n/**\n * Executes a node hard delete operation (permanent removal).\n *\n * Unlike soft delete, this permanently removes the node and all\n * associated data (uniqueness entries, embeddings) from the database.\n */\nexport async function executeNodeHardDelete<G extends GraphDef>(\n ctx: NodeOperationContext<G>,\n kind: string,\n id: string,\n backend: GraphBackend | TransactionBackend,\n): Promise<void> {\n // Gate outside hooks and transaction so an absent node neither fires hooks\n // nor opens an empty transaction (see executeNodeDelete). The cascade\n // re-reads inside the transaction.\n const gate = await backend.getNode(ctx.graphId, kind, id);\n if (!gate) return;\n\n const opContext = ctx.createOperationContext(\"delete\", \"node\", kind, id);\n\n return runHookedWritePlan(\n nodeWritePlanContext(ctx),\n opContext,\n nodeWritePlan(undefined, nodeRequiresIdentityLock(ctx)),\n backend,\n async (session, target) => {\n const identity = ctx.identity;\n const registration = getNodeRegistration(ctx.graph, kind);\n // No in-transaction preflight (unlike soft delete, whose pipeline\n // consumes the pre-image for uniqueness-key cleanup): every hard\n // cascade member is id-keyed and idempotent — the delete-behavior\n // check re-reads edges itself, `hardDeleteNode` deletes by primary\n // key, and embeddings clean up by id — so a node concurrently\n // removed between the gate and the write lock makes each statement\n // a 0-row no-op.\n\n // The cascade (edges, node, embeddings) is not individually atomic, so\n // it runs in one write transaction. Embeddings live in strategy-owned\n // per-`(kind, field)` tables, so they are cleaned up here rather than\n // in the backend's graph-agnostic `hardDeleteNode` cascade.\n await session.purgeNode({\n kind,\n id,\n schema: registration.type.schema,\n onDelete: registration.onDelete,\n });\n if (identity !== undefined) {\n await identity.detachDeleted(target, { kind, id }, \"hard\");\n }\n },\n );\n}\n\n// ============================================================\n// Get-Or-Create Operations\n// ============================================================\n\nexport async function executeNodeGetOrCreateByConstraint<G extends GraphDef>(\n ctx: NodeOperationContext<G>,\n kind: string,\n constraintName: string,\n props: Record<string, unknown>,\n backend: GraphBackend | TransactionBackend,\n options?: NodeGetOrCreateByConstraintOptions,\n): Promise<Readonly<{ node: Node; action: GetOrCreateAction }>> {\n const ifExists = options?.ifExists ?? \"return\";\n\n const registration = getNodeRegistration(ctx.graph, kind);\n const nodeKind = registration.type;\n const validatedProps = validateNodeProps(nodeKind.schema, props, {\n kind,\n operation: \"create\",\n });\n\n const constraint = resolveConstraint(ctx.graph, kind, constraintName);\n\n if (!checkWherePredicate(constraint, validatedProps)) {\n const node = await executeNodeCreate(\n ctx,\n { kind, props: validatedProps },\n backend,\n { propsPreValidated: true },\n );\n return { node, action: \"created\" };\n }\n\n const key = computeUniqueKey(\n validatedProps,\n constraint.fields,\n constraint.collation,\n );\n\n const kindsToCheck = uniquenessProbeKinds(\n kind,\n constraint.scope,\n ctx.registry,\n );\n\n // The probe runs outside any transaction (the found path is a pure read),\n // and each write leg opens its own hooked transaction. A concurrent create\n // can therefore reserve the key between the probe and the create — that\n // surfaces as UniquenessError, and the caller retries the probe once to\n // converge on the row the winner created.\n async function attempt(): Promise<\n Readonly<{ node: Node; action: GetOrCreateAction }>\n > {\n const existingUniqueRow = await findUniqueRowAcrossKinds(\n backend,\n ctx.graphId,\n constraint.name,\n key,\n kindsToCheck,\n true,\n );\n\n if (existingUniqueRow === undefined) {\n const node = await executeNodeCreate(\n ctx,\n { kind, props: validatedProps },\n backend,\n { propsPreValidated: true },\n );\n return { node, action: \"created\" };\n }\n\n // Fetch using concrete_kind (may differ from requested kind\n // when scope is \"kindWithSubClasses\" and the match is on a sibling/parent kind)\n const existingRow = await backend.getNode(\n ctx.graphId,\n existingUniqueRow.concrete_kind,\n existingUniqueRow.node_id,\n );\n\n if (existingRow === undefined) {\n const node = await executeNodeCreate(\n ctx,\n { kind, props: validatedProps },\n backend,\n { propsPreValidated: true },\n );\n return { node, action: \"created\" };\n }\n\n const isSoftDeleted = existingRow.deleted_at !== undefined;\n\n if (isSoftDeleted || ifExists === \"update\") {\n const concreteKind = existingUniqueRow.concrete_kind;\n const node = await executeNodeUpsertUpdate(\n ctx,\n {\n kind: concreteKind,\n id: existingRow.id as UpdateNodeInput[\"id\"],\n props: validatedProps,\n },\n backend,\n { clearDeleted: isSoftDeleted },\n );\n return { node, action: isSoftDeleted ? \"resurrected\" : \"updated\" };\n }\n\n return { node: rowToNode(existingRow), action: \"found\" };\n }\n\n try {\n return await attempt();\n } catch (error) {\n if (!(error instanceof UniquenessError)) throw error;\n return attempt();\n }\n}\n\n// ============================================================\n// Find-By-Constraint Operations\n// ============================================================\n\nexport async function executeNodeFindByConstraint<G extends GraphDef>(\n ctx: NodeOperationContext<G>,\n kind: string,\n constraintName: string,\n props: Record<string, unknown>,\n backend: GraphBackend | TransactionBackend,\n): Promise<Node | undefined> {\n const registration = getNodeRegistration(ctx.graph, kind);\n const nodeKind = registration.type;\n const validatedProps = validateNodeProps(nodeKind.schema, props, {\n kind,\n operation: \"create\",\n });\n\n const constraint = resolveConstraint(ctx.graph, kind, constraintName);\n if (!checkWherePredicate(constraint, validatedProps)) return undefined;\n\n const key = computeUniqueKey(\n validatedProps,\n constraint.fields,\n constraint.collation,\n );\n\n const kindsToCheck = uniquenessProbeKinds(\n kind,\n constraint.scope,\n ctx.registry,\n );\n\n const existingUniqueRow = await findUniqueRowAcrossKinds(\n backend,\n ctx.graphId,\n constraint.name,\n key,\n kindsToCheck,\n false,\n );\n\n if (existingUniqueRow === undefined) return undefined;\n\n const existingRow = await backend.getNode(\n ctx.graphId,\n existingUniqueRow.concrete_kind,\n existingUniqueRow.node_id,\n );\n\n if (existingRow === undefined || existingRow.deleted_at !== undefined)\n return undefined;\n\n return rowToNode(existingRow);\n}\n\n// ============================================================\n// Bulk Find-By-Constraint\n// ============================================================\n\n/**\n * Validates all items and computes unique constraint keys.\n * Shared by both bulk find and bulk getOrCreate.\n */\nfunction validateAndComputeKeys(\n nodeKind: NodeType,\n kind: string,\n constraint: UniqueConstraint,\n items: readonly Readonly<{ props: Record<string, unknown> }>[],\n): { validatedProps: Record<string, unknown>; key: string | undefined }[] {\n const validated: {\n validatedProps: Record<string, unknown>;\n key: string | undefined;\n }[] = [];\n\n for (const item of items) {\n const validatedProps = validateNodeProps(nodeKind.schema, item.props, {\n kind,\n operation: \"create\",\n });\n const applies = checkWherePredicate(constraint, validatedProps);\n const key =\n applies ?\n computeUniqueKey(\n validatedProps,\n constraint.fields,\n constraint.collation,\n )\n : undefined;\n validated.push({ validatedProps, key });\n }\n\n return validated;\n}\n\nfunction collectUniqueKeys(\n validated: readonly { key: string | undefined }[],\n): string[] {\n return [\n ...new Set(\n validated\n .map((entry) => entry.key)\n .filter((key): key is string => key !== undefined),\n ),\n ];\n}\n\nexport async function executeNodeBulkFindByConstraint<G extends GraphDef>(\n ctx: NodeOperationContext<G>,\n kind: string,\n constraintName: string,\n items: readonly Readonly<{ props: Record<string, unknown> }>[],\n backend: GraphBackend | TransactionBackend,\n): Promise<(Node | undefined)[]> {\n if (items.length === 0) return [];\n\n const registration = getNodeRegistration(ctx.graph, kind);\n const nodeKind = registration.type;\n const constraint = resolveConstraint(ctx.graph, kind, constraintName);\n\n const validated = validateAndComputeKeys(nodeKind, kind, constraint, items);\n const uniqueKeys = collectUniqueKeys(validated);\n\n const kindsToCheck = uniquenessProbeKinds(\n kind,\n constraint.scope,\n ctx.registry,\n );\n\n const existingByKey =\n uniqueKeys.length > 0 ?\n await batchCheckUniqueAcrossKinds(\n backend,\n ctx.uniqueSidecarBatch,\n ctx.graphId,\n constraint.name,\n uniqueKeys,\n kindsToCheck,\n false,\n )\n : new Map<string, { node_id: string; concrete_kind: string }>();\n\n // Assemble results, deduplicating keys seen within the batch\n const results: (Node | undefined)[] = Array.from({ length: items.length });\n const seenKeys = new Map<string, number>();\n\n for (const [index, { key }] of validated.entries()) {\n if (key === undefined) {\n results[index] = undefined;\n continue;\n }\n\n const previousIndex = seenKeys.get(key);\n if (previousIndex !== undefined) {\n results[index] = results[previousIndex];\n continue;\n }\n seenKeys.set(key, index);\n\n const existing = existingByKey.get(key);\n if (existing === undefined) {\n results[index] = undefined;\n continue;\n }\n\n const existingRow = await backend.getNode(\n ctx.graphId,\n existing.concrete_kind,\n existing.node_id,\n );\n\n if (existingRow === undefined || existingRow.deleted_at !== undefined) {\n results[index] = undefined;\n continue;\n }\n\n results[index] = rowToNode(existingRow);\n }\n\n return results;\n}\n\n// ============================================================\n// Bulk Find-By-Index\n// ============================================================\n\n/**\n * Resolves a declared node index by name, validating the kind first.\n *\n * @throws {KindNotFoundError} when the node kind is not registered\n * @throws {NodeIndexNotFoundError} when no node index of that name exists\n */\nfunction resolveNodeIndex<G extends GraphDef>(\n graph: G,\n kind: string,\n indexName: string,\n): NodeIndexDeclaration {\n getNodeRegistration(graph, kind);\n\n const declaration = graph.indexes?.find(\n (candidate) =>\n candidate.entity === \"node\" &&\n candidate.kind === kind &&\n candidate.name === indexName,\n );\n\n if (declaration?.entity !== \"node\") {\n throw new NodeIndexNotFoundError(indexName, kind);\n }\n\n // GIN-family indexes serve containment / substring predicates, not the\n // equality probes bulkFindByIndex compiles — targeting one here would\n // silently probe with the wrong extraction semantics.\n if (declaration.method !== undefined) {\n throw new ConfigurationError(\n `bulkFindByIndex cannot probe index \"${indexName}\" (method ` +\n `\"${declaration.method}\"): only btree indexes serve equality probes.`,\n { indexName, kind, method: declaration.method },\n );\n }\n\n return declaration;\n}\n\nconst INDEX_PROBE_EXPECTED_TYPEOF: Partial<Record<ValueType, string>> = {\n string: \"string\",\n number: \"number\",\n boolean: \"boolean\",\n};\n\n/**\n * Validates a single probe value against its declared index-field type.\n * Missing/null values are valid (null probes); only a present, scalar\n * value of the wrong type is rejected.\n */\nfunction validateIndexProbeValue(\n value: unknown,\n valueType: ValueType | undefined,\n pointer: JsonPointer,\n kind: string,\n): void {\n if (value === undefined || value === null) return;\n\n // Index keys are scalar; a non-scalar probe can't be bound and must fail\n // with a typed error rather than a cryptic driver bind error downstream.\n if (\n typeof value !== \"string\" &&\n typeof value !== \"number\" &&\n typeof value !== \"boolean\" &&\n !(value instanceof Date)\n ) {\n throw indexProbeTypeError(\n pointer,\n kind,\n \"a scalar (string, number, boolean, or Date)\",\n value,\n );\n }\n\n if (valueType === \"date\") {\n if (value instanceof Date || typeof value === \"string\") return;\n throw indexProbeTypeError(\n pointer,\n kind,\n \"date (Date or ISO string)\",\n value,\n );\n }\n\n const expected = INDEX_PROBE_EXPECTED_TYPEOF[valueType ?? \"unknown\"];\n if (expected === undefined) return;\n if (typeof value !== expected) {\n throw indexProbeTypeError(pointer, kind, expected, value);\n }\n}\n\nfunction indexProbeTypeError(\n pointer: JsonPointer,\n kind: string,\n expected: string,\n value: unknown,\n): ValidationError {\n return new ValidationError(\n `Index probe value for \"${pointer}\" on node kind \"${kind}\" has an incompatible type`,\n {\n entityType: \"node\",\n kind,\n issues: [\n {\n path: pointer,\n message: `Expected ${expected}, received ${typeof value}`,\n code: \"invalid_type\",\n },\n ],\n },\n );\n}\n\n/** Coerces a non-null probe value into a driver-bindable scalar. */\nfunction coerceIndexProbeBind(\n value: unknown,\n adapter: DialectAdapter,\n): unknown {\n return adapter.bindValue(normalizeProbeScalar(value as ProbeScalar));\n}\n\ntype ProbeScalar = string | number | boolean | Date;\n\n/**\n * Canonical scalar form of a validated probe value, shared by the dedup key\n * and the bound SQL value so the two can never drift (a Date and its ISO\n * string normalize identically — and produce identical predicates).\n */\nfunction normalizeProbeScalar(value: ProbeScalar): string | number | boolean {\n return value instanceof Date ? value.toISOString() : value;\n}\n\nconst PROBE_NULL_TAG = 0;\nconst PROBE_VALUE_TAG = 1;\n\n/**\n * Stable dedup key for a probe tuple. Each slot is tagged so a null/undefined\n * value can never collide with a string that happens to equal a sentinel -\n * null maps to [0], a present scalar to [1, normalized].\n */\nfunction canonicalIndexProbeKey(probe: readonly unknown[]): string {\n return JSON.stringify(\n probe.map((value) =>\n value === undefined || value === null ?\n [PROBE_NULL_TAG]\n : [PROBE_VALUE_TAG, normalizeProbeScalar(value as ProbeScalar)],\n ),\n );\n}\n\n/**\n * Batched candidate retrieval against a declared node index.\n *\n * Emits a single query against the nodes table: each input's indexed-field\n * values become a probe predicate (null-safe equality, reusing the index's\n * own extraction expressions so the planner can use the physical index), and\n * a `CASE` selector tags each matched row with the deduped probe group it\n * satisfies. Rows are grouped back to input positions in order; each input's\n * candidate set is ordered by node id.\n */\nexport async function executeNodeBulkFindByIndex<G extends GraphDef>(\n ctx: NodeOperationContext<G>,\n kind: string,\n indexName: string,\n items: readonly Readonly<{ props: Record<string, unknown> }>[],\n backend: GraphBackend | TransactionBackend,\n options?: NodeBulkFindByIndexOptions,\n): Promise<Node[][]> {\n if (items.length === 0) return [];\n\n const index = resolveNodeIndex(ctx.graph, kind, indexName);\n\n if (index.fields.length === 0) {\n throw new ConfigurationError(\n `bulkFindByIndex requires an index with at least one prop-based field on index \"${indexName}\" (node kind \"${kind}\")`,\n { indexName, kind },\n {\n suggestion:\n \"bulkFindByIndex probes by prop values from each item; an index declared with only keySystemColumns/coveringFields (no fields) has nothing to probe by.\",\n },\n );\n }\n\n // Date-typed lookup keys can't satisfy the cross-backend parity guarantee:\n // SQLite compares stored ISO text byte-wise while Postgres compares\n // timestamptz instants, so equal instants in different ISO forms diverge.\n // Declare the gap rather than return backend-dependent results.\n if (index.fieldValueTypes.includes(\"date\")) {\n throw new ConfigurationError(\n `bulkFindByIndex does not support date-typed key fields on index \"${indexName}\" (node kind \"${kind}\")`,\n { indexName, kind },\n {\n suggestion:\n \"Date index keys compare differently across SQLite and PostgreSQL. Use a string-encoded key field, or query date predicates via store.query(...).where(...).\",\n },\n );\n }\n\n const limitPerInput = options?.limitPerInput;\n if (\n limitPerInput !== undefined &&\n (!Number.isInteger(limitPerInput) || limitPerInput <= 0)\n ) {\n throw new ValidationError(\n \"bulkFindByIndex limitPerInput must be a positive integer\",\n {\n entityType: \"node\",\n kind,\n issues: [\n {\n path: \"limitPerInput\",\n message: `Expected a positive integer, received ${String(limitPerInput)}`,\n code: \"invalid_value\",\n },\n ],\n },\n );\n }\n\n const adapter = getDialect(backend.dialect);\n\n // 1. Extract + validate each input's indexed-field probe tuple.\n const probes: unknown[][] = items.map((item) =>\n index.fields.map((pointer, position) => {\n const value = resolveJsonPointer(item.props, pointer);\n validateIndexProbeValue(\n value,\n index.fieldValueTypes[position],\n pointer,\n kind,\n );\n return value;\n }),\n );\n\n // 2. Dedupe probe tuples; map each distinct tuple to its input positions.\n const groupByKey = new Map<string, number>();\n const groupProbes: unknown[][] = [];\n const groupToInputs: number[][] = [];\n for (const [inputIndex, probe] of probes.entries()) {\n const key = canonicalIndexProbeKey(probe);\n const existing = groupByKey.get(key);\n if (existing === undefined) {\n groupByKey.set(key, groupProbes.length);\n groupProbes.push(probe);\n groupToInputs.push([inputIndex]);\n continue;\n }\n groupToInputs[existing]?.push(inputIndex);\n }\n\n // 3. Build probe predicates shared by the CASE selector and WHERE filter.\n const schema =\n backend.tableNames ?\n createSqlSchema(backend.tableNames)\n : DEFAULT_SQL_SCHEMA;\n const compileContext: IndexCompilationContext = {\n dialect: backend.dialect,\n propsColumn: sql.raw(`\"props\"`),\n systemColumn: (column) => sql.raw(`\"${column}\"`),\n };\n const fieldKeys = compileNodeIndexFieldKeys(index, compileContext);\n\n const groupPredicates = groupProbes.map(\n (probe) =>\n sql`(${sql.join(\n fieldKeys.map((fieldKey, position) => {\n const value = probe[position];\n if (value === undefined || value === null) {\n return sql`${fieldKey} IS NULL`;\n }\n return adapter.nullSafeEquals(\n fieldKey,\n sql`${coerceIndexProbeBind(value, adapter)}`,\n );\n }),\n sql` AND `,\n )})`,\n );\n\n const caseBranches = groupPredicates.map(\n (predicate, group) => sql`WHEN ${predicate} THEN ${sql.raw(String(group))}`,\n );\n const probeIndexExpr = sql`CASE ${sql.join(caseBranches, sql` `)} ELSE NULL END`;\n\n const conditions: SqlFragment[] = [\n sql`\"graph_id\" = ${ctx.graphId}`,\n sql`\"kind\" = ${kind}`,\n sql`\"deleted_at\" IS NULL`,\n ];\n if (index.where !== undefined) {\n conditions.push(compileIndexWhere(compileContext, index.where));\n }\n conditions.push(sql`(${sql.join(groupPredicates, sql` OR `)})`);\n const whereClause = sql.join(conditions, sql` AND `);\n\n // The probe matching runs against the nodes table; rows are hydrated\n // separately via the backend's normalized node reads so the returned\n // shape is identical to every other node API (props/timestamp\n // normalization is backend-owned, not re-derived from raw driver rows).\n const probedSelect = sql`SELECT \"id\", ${probeIndexExpr} AS probe_idx FROM ${schema.nodesTable} WHERE ${whereClause}`;\n\n // limitPerInput caps each input's candidates per probe group. When the\n // backend supports window functions we cap in SQL (`ROW_NUMBER()`), which\n // also avoids transferring excess ids on low-selectivity keys. Otherwise we\n // degrade gracefully: fetch all matching ids and cap per group in JS before\n // hydration — the cap stays correct, only the id transfer is unbounded.\n const capInSql =\n limitPerInput !== undefined && backend.capabilities.windowFunctions;\n\n const query =\n capInSql ?\n sql`SELECT \"id\", probe_idx FROM (SELECT \"id\", probe_idx, ROW_NUMBER() OVER (PARTITION BY probe_idx ORDER BY \"id\") AS probe_rank FROM (${probedSelect}) AS probed) AS ranked WHERE probe_rank <= ${limitPerInput} ORDER BY probe_idx, \"id\"`\n : sql`${probedSelect} ORDER BY probe_idx, \"id\"`;\n\n // 4. Execute, hydrate matched nodes, and group back to input positions.\n const rawMatches = await backend.execute<ProbeMatch>(\n asCompiledRowsSql(query),\n );\n const matches =\n limitPerInput !== undefined && !capInSql ?\n capMatchesPerGroup(rawMatches, limitPerInput)\n : rawMatches;\n\n const nodesById = await hydrateNodesById(\n backend,\n ctx.batchPointRead,\n ctx.graphId,\n kind,\n matches.map((match) => match.id),\n );\n\n const results: Node[][] = Array.from({ length: items.length }, () => []);\n for (const match of matches) {\n const node = nodesById.get(match.id);\n if (node === undefined) continue;\n const inputs = groupToInputs[match.probe_idx];\n if (inputs === undefined) continue;\n for (const inputIndex of inputs) {\n results[inputIndex]?.push(node);\n }\n }\n\n return results;\n}\n\ntype ProbeMatch = Readonly<{ id: string; probe_idx: number }>;\n\n/**\n * Caps matches to the first `limitPerInput` per probe group (the JS-side\n * equivalent of the `ROW_NUMBER()` window). Relies on `matches` already being\n * ordered by `(probe_idx, id)`, so the kept rows are the lowest ids per group.\n */\nfunction capMatchesPerGroup(\n matches: readonly ProbeMatch[],\n limitPerInput: number,\n): ProbeMatch[] {\n const perGroupCount = new Map<number, number>();\n const capped: ProbeMatch[] = [];\n for (const match of matches) {\n const count = perGroupCount.get(match.probe_idx) ?? 0;\n if (count >= limitPerInput) continue;\n perGroupCount.set(match.probe_idx, count + 1);\n capped.push(match);\n }\n return capped;\n}\n\n/** Hydrates live nodes by id via the backend's normalized node reads. */\nasync function hydrateNodesById(\n backend: GraphBackend | TransactionBackend,\n batchPointRead: BundleVerdictOf<typeof BATCH_POINT_READ>,\n graphId: string,\n kind: string,\n ids: readonly string[],\n): Promise<Map<string, Node>> {\n const rowsById = await getNodeRowsByIds(\n backend,\n batchPointRead,\n graphId,\n kind,\n ids,\n );\n const nodesById = new Map<string, Node>();\n for (const [id, row] of rowsById) {\n if (row.deleted_at !== undefined) continue;\n nodesById.set(id, rowToNode(row));\n }\n return nodesById;\n}\n\n// ============================================================\n// Bulk Get-Or-Create-By-Constraint\n// ============================================================\n\nexport async function executeNodeBulkGetOrCreateByConstraint<\n G extends GraphDef,\n>(\n ctx: NodeOperationContext<G>,\n kind: string,\n constraintName: string,\n items: readonly Readonly<{ props: Record<string, unknown> }>[],\n backend: GraphBackend | TransactionBackend,\n options?: NodeGetOrCreateByConstraintOptions,\n): Promise<Readonly<{ node: Node; action: GetOrCreateAction }>[]> {\n if (items.length === 0) return [];\n\n const ifExists = options?.ifExists ?? \"return\";\n const registration = getNodeRegistration(ctx.graph, kind);\n const nodeKind = registration.type;\n const constraint = resolveConstraint(ctx.graph, kind, constraintName);\n\n // Step 1: Validate all props and compute keys\n const validated = validateAndComputeKeys(nodeKind, kind, constraint, items);\n const uniqueKeys = collectUniqueKeys(validated);\n\n const kindsToCheck = uniquenessProbeKinds(\n kind,\n constraint.scope,\n ctx.registry,\n );\n\n type Result = Readonly<{ node: Node; action: GetOrCreateAction }>;\n\n // Steps 2-6 are one convergence attempt: the batch probe runs outside any\n // transaction and each write leg opens its own, so a concurrent create can\n // reserve a key between them. The uniques primary key catches that and raises\n // `UniquenessError`; re-running the whole attempt converges on the winner's\n // row. Without this the single-item path retried and the batch failed\n // outright, which is the asymmetry #428 called out.\n async function attempt(): Promise<Result[]> {\n // Step 2: Batch-check existing keys\n const existingByKey =\n uniqueKeys.length > 0 ?\n await batchCheckUniqueAcrossKinds(\n backend,\n ctx.uniqueSidecarBatch,\n ctx.graphId,\n constraint.name,\n uniqueKeys,\n kindsToCheck,\n true,\n )\n : new Map<\n string,\n {\n node_id: string;\n concrete_kind: string;\n deleted_at: string | undefined;\n }\n >();\n\n // Step 3: Partition into toCreate, toFetch, and duplicates\n const toCreate: { index: number; input: CreateNodeInput }[] = [];\n const toFetch: {\n index: number;\n nodeId: string;\n concreteKind: string;\n validatedProps: Record<string, unknown>;\n }[] = [];\n const duplicateOf: { index: number; sourceIndex: number }[] = [];\n const seenKeys = new Map<string, number>();\n\n for (const [index, { validatedProps, key }] of validated.entries()) {\n if (key === undefined) {\n toCreate.push({ index, input: { kind, props: validatedProps } });\n continue;\n }\n\n const previousIndex = seenKeys.get(key);\n if (previousIndex !== undefined) {\n duplicateOf.push({ index, sourceIndex: previousIndex });\n continue;\n }\n\n seenKeys.set(key, index);\n\n const existing = existingByKey.get(key);\n if (existing === undefined) {\n toCreate.push({ index, input: { kind, props: validatedProps } });\n } else {\n toFetch.push({\n index,\n nodeId: existing.node_id,\n concreteKind: existing.concrete_kind,\n validatedProps,\n });\n }\n }\n\n const results: Result[] = Array.from({ length: items.length });\n\n // Step 4: Execute creates\n if (toCreate.length > 0) {\n const createInputs = toCreate.map((entry) => entry.input);\n const createdNodes = await executeNodeCreateBatch(\n ctx,\n createInputs,\n backend,\n { propsPreValidated: true },\n );\n for (const [batchIndex, entry] of toCreate.entries()) {\n results[entry.index] = {\n node: requireDefined(createdNodes[batchIndex]),\n action: \"created\",\n };\n }\n }\n\n // Step 5: Handle existing nodes (fetch/update/resurrect)\n for (const entry of toFetch) {\n const { index, concreteKind, validatedProps, nodeId } = entry;\n\n const existingRow = await backend.getNode(\n ctx.graphId,\n concreteKind,\n nodeId,\n );\n\n if (existingRow === undefined) {\n const node = await executeNodeCreate(\n ctx,\n { kind, props: validatedProps },\n backend,\n { propsPreValidated: true },\n );\n results[index] = { node, action: \"created\" };\n continue;\n }\n\n // Read from the NODE ROW this loop just fetched, not from the uniques row\n // the batch probe captured back in step 2 — the single-item path has\n // always derived it here (see `executeNodeGetOrCreateByConstraint`), and\n // one decision with two owners drifts. The uniques copy is also the\n // staler of the two: step 4's creates run between the probe and this\n // read, and a peer can soft-delete or resurrect the node in that window.\n // Whether this write RESURRECTS has to come from the row it will target.\n const isSoftDeleted = existingRow.deleted_at !== undefined;\n\n if (isSoftDeleted || ifExists === \"update\") {\n const node = await executeNodeUpsertUpdate(\n ctx,\n {\n kind: concreteKind,\n id: existingRow.id as UpdateNodeInput[\"id\"],\n props: validatedProps,\n },\n backend,\n { clearDeleted: isSoftDeleted },\n );\n results[index] = {\n node,\n action: isSoftDeleted ? \"resurrected\" : \"updated\",\n };\n } else {\n results[index] = { node: rowToNode(existingRow), action: \"found\" };\n }\n }\n\n // Step 6: Resolve within-batch duplicates by copying the first occurrence's result\n for (const { index, sourceIndex } of duplicateOf) {\n const sourceResult = requireDefined(results[sourceIndex]);\n results[index] = { node: sourceResult.node, action: \"found\" };\n }\n\n return results;\n }\n\n try {\n return await attempt();\n } catch (error) {\n if (!(error instanceof UniquenessError)) throw error;\n return attempt();\n }\n}\n"]}
|