@nicia-ai/typegraph 0.46.1 → 0.47.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 +20 -1
- package/dist/backend/drizzle/indexes.cjs +9 -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 +5 -5
- package/dist/backend/index.cjs +50 -49
- package/dist/backend/index.d.cts +3 -3
- package/dist/backend/index.d.ts +3 -3
- package/dist/backend/index.js +11 -10
- package/dist/backend/postgres/index.cjs +27 -26
- package/dist/backend/postgres/index.d.cts +6 -6
- package/dist/backend/postgres/index.d.ts +6 -6
- package/dist/backend/postgres/index.js +14 -13
- package/dist/backend/postgres/pglite-store.cjs +34 -33
- 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 +30 -29
- package/dist/backend/postgres/pglite-store.js.map +1 -1
- package/dist/backend/postgres/pglite.cjs +16 -15
- package/dist/backend/postgres/pglite.d.cts +3 -3
- package/dist/backend/postgres/pglite.d.ts +3 -3
- package/dist/backend/postgres/pglite.js +15 -14
- package/dist/backend/sqlite/index.cjs +24 -23
- package/dist/backend/sqlite/index.d.cts +6 -6
- package/dist/backend/sqlite/index.d.ts +6 -6
- package/dist/backend/sqlite/index.js +12 -11
- package/dist/backend/sqlite/libsql.cjs +19 -18
- 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 +14 -13
- package/dist/backend/sqlite/libsql.js.map +1 -1
- package/dist/backend/sqlite/local-store.cjs +35 -34
- 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 +31 -30
- package/dist/backend/sqlite/local-store.js.map +1 -1
- package/dist/backend/sqlite/local.cjs +17 -16
- package/dist/backend/sqlite/local.d.cts +3 -3
- package/dist/backend/sqlite/local.d.ts +3 -3
- package/dist/backend/sqlite/local.js +15 -14
- package/dist/{chunk-NK5Q7UNE.cjs → chunk-26YKDNUD.cjs} +10 -10
- package/dist/{chunk-NK5Q7UNE.cjs.map → chunk-26YKDNUD.cjs.map} +1 -1
- package/dist/{chunk-PQBQG7IM.js → chunk-3DMMGT6S.js} +3 -3
- package/dist/{chunk-PQBQG7IM.js.map → chunk-3DMMGT6S.js.map} +1 -1
- package/dist/{chunk-XBYVV3MP.cjs → chunk-3HGRTCDU.cjs} +6 -4
- package/dist/chunk-3HGRTCDU.cjs.map +1 -0
- package/dist/{chunk-NFCVHQ5P.cjs → chunk-3U5ABFDW.cjs} +26 -26
- package/dist/{chunk-NFCVHQ5P.cjs.map → chunk-3U5ABFDW.cjs.map} +1 -1
- package/dist/{chunk-MCLYU6BN.cjs → chunk-425IZOQ5.cjs} +11 -164
- package/dist/chunk-425IZOQ5.cjs.map +1 -0
- package/dist/{chunk-M4BDU5RX.cjs → chunk-5FBRVORR.cjs} +12 -12
- package/dist/{chunk-M4BDU5RX.cjs.map → chunk-5FBRVORR.cjs.map} +1 -1
- package/dist/{chunk-C23WSN5E.js → chunk-5FT3TLPK.js} +20 -14
- package/dist/chunk-5FT3TLPK.js.map +1 -0
- package/dist/{chunk-YBFHZUXX.js → chunk-5UMTUOM5.js} +6 -6
- package/dist/{chunk-YBFHZUXX.js.map → chunk-5UMTUOM5.js.map} +1 -1
- package/dist/{chunk-HFHTMECK.js → chunk-6FWSNSRE.js} +7 -7
- package/dist/{chunk-HFHTMECK.js.map → chunk-6FWSNSRE.js.map} +1 -1
- package/dist/{chunk-65E3XWGF.cjs → chunk-6JVZSOHQ.cjs} +91 -91
- package/dist/{chunk-65E3XWGF.cjs.map → chunk-6JVZSOHQ.cjs.map} +1 -1
- package/dist/chunk-6KFLYYOC.cjs +161 -0
- package/dist/chunk-6KFLYYOC.cjs.map +1 -0
- package/dist/{chunk-LBJKZXDE.cjs → chunk-6NGW27EO.cjs} +10 -10
- package/dist/{chunk-LBJKZXDE.cjs.map → chunk-6NGW27EO.cjs.map} +1 -1
- package/dist/{chunk-5UVRGXD3.js → chunk-6SWPJEYN.js} +5 -5
- package/dist/{chunk-5UVRGXD3.js.map → chunk-6SWPJEYN.js.map} +1 -1
- package/dist/{chunk-BKCUOV7A.js → chunk-7SQSZN2J.js} +5 -5
- package/dist/{chunk-BKCUOV7A.js.map → chunk-7SQSZN2J.js.map} +1 -1
- package/dist/{chunk-YAAM3M2S.cjs → chunk-AMMWA76F.cjs} +51 -59
- package/dist/chunk-AMMWA76F.cjs.map +1 -0
- package/dist/{chunk-62ZP23AW.cjs → chunk-AOSSQDVO.cjs} +13 -13
- package/dist/{chunk-62ZP23AW.cjs.map → chunk-AOSSQDVO.cjs.map} +1 -1
- package/dist/{chunk-NLI2AVEF.js → chunk-AVGUJWVX.js} +30 -10
- package/dist/chunk-AVGUJWVX.js.map +1 -0
- package/dist/{chunk-TQR4KBY2.cjs → chunk-BCQ76AXA.cjs} +262 -155
- package/dist/chunk-BCQ76AXA.cjs.map +1 -0
- package/dist/{chunk-CXBHOOIQ.cjs → chunk-BFUOME67.cjs} +11 -11
- package/dist/{chunk-CXBHOOIQ.cjs.map → chunk-BFUOME67.cjs.map} +1 -1
- package/dist/{chunk-PNTCATDE.cjs → chunk-BR7SHKGM.cjs} +1672 -1400
- package/dist/chunk-BR7SHKGM.cjs.map +1 -0
- package/dist/{chunk-ASTI57H3.js → chunk-CHAOFCHV.js} +3 -3
- package/dist/{chunk-ASTI57H3.js.map → chunk-CHAOFCHV.js.map} +1 -1
- package/dist/chunk-CICO5GXD.cjs +12 -0
- package/dist/{chunk-A4OC4DVN.cjs.map → chunk-CICO5GXD.cjs.map} +1 -1
- package/dist/{chunk-T4XNKYXB.js → chunk-D5R42W5D.js} +4 -4
- package/dist/{chunk-T4XNKYXB.js.map → chunk-D5R42W5D.js.map} +1 -1
- package/dist/{chunk-S6PW7VV5.js → chunk-DJZTXBWY.js} +410 -138
- package/dist/chunk-DJZTXBWY.js.map +1 -0
- package/dist/{chunk-UDISNXDL.cjs → chunk-DO7SAMEK.cjs} +47 -47
- package/dist/{chunk-UDISNXDL.cjs.map → chunk-DO7SAMEK.cjs.map} +1 -1
- package/dist/{chunk-VCRRKBLN.cjs → chunk-EDN4Y4ZG.cjs} +9 -9
- package/dist/{chunk-VCRRKBLN.cjs.map → chunk-EDN4Y4ZG.cjs.map} +1 -1
- package/dist/{chunk-YVWGEQJE.cjs → chunk-EMIB2RXD.cjs} +139 -133
- package/dist/chunk-EMIB2RXD.cjs.map +1 -0
- package/dist/{chunk-2Z2Z3ZD6.js → chunk-EP4RUYD6.js} +3 -3
- package/dist/{chunk-2Z2Z3ZD6.js.map → chunk-EP4RUYD6.js.map} +1 -1
- package/dist/{chunk-M3WP7RQZ.js → chunk-FNOMT74T.js} +10 -8
- package/dist/chunk-FNOMT74T.js.map +1 -0
- package/dist/{chunk-E4WNQBEF.cjs → chunk-FQPEMEWX.cjs} +12 -12
- package/dist/{chunk-E4WNQBEF.cjs.map → chunk-FQPEMEWX.cjs.map} +1 -1
- package/dist/{chunk-WDGA7IYB.js → chunk-GLHXM7C4.js} +3 -3
- package/dist/{chunk-WDGA7IYB.js.map → chunk-GLHXM7C4.js.map} +1 -1
- package/dist/{chunk-7BQXPCGN.cjs → chunk-GYEG3ZLZ.cjs} +10 -10
- package/dist/{chunk-7BQXPCGN.cjs.map → chunk-GYEG3ZLZ.cjs.map} +1 -1
- package/dist/{chunk-VLT6PEWR.cjs → chunk-GYUJZARH.cjs} +4 -4
- package/dist/{chunk-VLT6PEWR.cjs.map → chunk-GYUJZARH.cjs.map} +1 -1
- package/dist/{chunk-RMQLSPA2.cjs → chunk-HDL2ARHX.cjs} +27 -27
- package/dist/{chunk-RMQLSPA2.cjs.map → chunk-HDL2ARHX.cjs.map} +1 -1
- package/dist/{chunk-775A4ZMN.js → chunk-HEV35TGT.js} +4 -4
- package/dist/{chunk-775A4ZMN.js.map → chunk-HEV35TGT.js.map} +1 -1
- package/dist/{chunk-3DHZCOT7.cjs → chunk-I4G3SQPF.cjs} +20 -20
- package/dist/{chunk-3DHZCOT7.cjs.map → chunk-I4G3SQPF.cjs.map} +1 -1
- package/dist/{chunk-VGTJPTIC.js → chunk-JONXFAPO.js} +5 -5
- package/dist/{chunk-VGTJPTIC.js.map → chunk-JONXFAPO.js.map} +1 -1
- package/dist/{chunk-BSFJMMV3.cjs → chunk-JR6SX5RH.cjs} +4 -4
- package/dist/{chunk-BSFJMMV3.cjs.map → chunk-JR6SX5RH.cjs.map} +1 -1
- package/dist/{chunk-YBQOHKHN.cjs → chunk-KABFHAL7.cjs} +100 -99
- package/dist/chunk-KABFHAL7.cjs.map +1 -0
- package/dist/{chunk-7VQXLT5O.js → chunk-KH7XW7VV.js} +111 -27
- package/dist/chunk-KH7XW7VV.js.map +1 -0
- package/dist/{chunk-DCQVHAYQ.js → chunk-KKBDXCLQ.js} +4 -4
- package/dist/{chunk-DCQVHAYQ.js.map → chunk-KKBDXCLQ.js.map} +1 -1
- package/dist/{chunk-4UGOKMI5.cjs → chunk-L3LQNR34.cjs} +161 -161
- package/dist/{chunk-4UGOKMI5.cjs.map → chunk-L3LQNR34.cjs.map} +1 -1
- package/dist/{chunk-NMWDXFPH.js → chunk-LEWHMOUY.js} +46 -56
- package/dist/chunk-LEWHMOUY.js.map +1 -0
- package/dist/{chunk-U63GDNRC.cjs → chunk-LRQKXRXO.cjs} +4 -4
- package/dist/{chunk-U63GDNRC.cjs.map → chunk-LRQKXRXO.cjs.map} +1 -1
- package/dist/{chunk-5763DULU.js → chunk-M35DF33T.js} +147 -40
- package/dist/chunk-M35DF33T.js.map +1 -0
- package/dist/{chunk-Q3G6A4I3.cjs → chunk-MFZR4QKM.cjs} +30 -28
- package/dist/chunk-MFZR4QKM.cjs.map +1 -0
- package/dist/chunk-MKJ4KXL5.cjs +12 -0
- package/dist/{chunk-VQH4VAWD.cjs.map → chunk-MKJ4KXL5.cjs.map} +1 -1
- package/dist/{chunk-NI72YOJB.cjs → chunk-MRDBBHIZ.cjs} +70 -2
- package/dist/chunk-MRDBBHIZ.cjs.map +1 -0
- package/dist/{chunk-DTVWX77L.cjs → chunk-MX4DHSQP.cjs} +1023 -360
- package/dist/chunk-MX4DHSQP.cjs.map +1 -0
- package/dist/{chunk-2LG2XB2M.js → chunk-MYKHJI2J.js} +3 -3
- package/dist/{chunk-2LG2XB2M.js.map → chunk-MYKHJI2J.js.map} +1 -1
- package/dist/{chunk-JZUR7ZWE.js → chunk-NAZ2RA4L.js} +3 -3
- package/dist/{chunk-JZUR7ZWE.js.map → chunk-NAZ2RA4L.js.map} +1 -1
- package/dist/{chunk-XL7SLCXS.js → chunk-NG2RB5WL.js} +4 -145
- package/dist/chunk-NG2RB5WL.js.map +1 -0
- package/dist/{chunk-GF3KXUTW.js → chunk-NNQ6A3RM.js} +803 -143
- package/dist/chunk-NNQ6A3RM.js.map +1 -0
- package/dist/{chunk-MSY7FSX4.js → chunk-NVY5CJFP.js} +4 -4
- package/dist/{chunk-MSY7FSX4.js.map → chunk-NVY5CJFP.js.map} +1 -1
- package/dist/{chunk-XCAGZAKP.cjs → chunk-OI2GQ25X.cjs} +7 -7
- package/dist/{chunk-XCAGZAKP.cjs.map → chunk-OI2GQ25X.cjs.map} +1 -1
- package/dist/{chunk-PF6F5NLJ.cjs → chunk-OIFSOPSR.cjs} +259 -238
- package/dist/chunk-OIFSOPSR.cjs.map +1 -0
- package/dist/{chunk-UV3SN74I.js → chunk-OMZ37BM2.js} +5 -5
- package/dist/{chunk-UV3SN74I.js.map → chunk-OMZ37BM2.js.map} +1 -1
- package/dist/{chunk-PNN7RHVR.cjs → chunk-OORXGFL5.cjs} +48 -48
- package/dist/{chunk-PNN7RHVR.cjs.map → chunk-OORXGFL5.cjs.map} +1 -1
- package/dist/{chunk-YWGVVALJ.js → chunk-OVI7IXYX.js} +3 -3
- package/dist/{chunk-YWGVVALJ.js.map → chunk-OVI7IXYX.js.map} +1 -1
- package/dist/{chunk-I5MOXA4H.js → chunk-P6YLZTRE.js} +3 -3
- package/dist/{chunk-I5MOXA4H.js.map → chunk-P6YLZTRE.js.map} +1 -1
- package/dist/{chunk-WQZLUGVR.js → chunk-QS3NQZVC.js} +82 -16
- package/dist/chunk-QS3NQZVC.js.map +1 -0
- package/dist/{chunk-5262ZMTR.js → chunk-QTD6HX4O.js} +5 -5
- package/dist/{chunk-5262ZMTR.js.map → chunk-QTD6HX4O.js.map} +1 -1
- package/dist/{chunk-MXJDTH5B.cjs → chunk-ROR5ZR6A.cjs} +45 -45
- package/dist/{chunk-MXJDTH5B.cjs.map → chunk-ROR5ZR6A.cjs.map} +1 -1
- package/dist/{chunk-CBTIUB76.js → chunk-SDBBMD4N.js} +3 -3
- package/dist/{chunk-CBTIUB76.js.map → chunk-SDBBMD4N.js.map} +1 -1
- package/dist/{chunk-L65OU2U3.js → chunk-SE6EGQSD.js} +78 -16
- package/dist/chunk-SE6EGQSD.js.map +1 -0
- package/dist/{chunk-JXA2ZP2Q.js → chunk-SHFBB23Q.js} +4 -4
- package/dist/{chunk-JXA2ZP2Q.js.map → chunk-SHFBB23Q.js.map} +1 -1
- package/dist/{chunk-AKLS3BYZ.js → chunk-SHSSRCFR.js} +5 -3
- package/dist/chunk-SHSSRCFR.js.map +1 -0
- package/dist/{chunk-2NA5DYLO.cjs → chunk-TZEGUG6D.cjs} +4 -4
- package/dist/{chunk-2NA5DYLO.cjs.map → chunk-TZEGUG6D.cjs.map} +1 -1
- package/dist/{chunk-CMWHLBVN.cjs → chunk-U5EDAVOJ.cjs} +140 -74
- package/dist/chunk-U5EDAVOJ.cjs.map +1 -0
- package/dist/{chunk-MUK4BU7K.cjs → chunk-UPAJHMW3.cjs} +210 -126
- package/dist/chunk-UPAJHMW3.cjs.map +1 -0
- package/dist/{chunk-PT7RIRIZ.cjs → chunk-WGX7JH7E.cjs} +235 -170
- package/dist/chunk-WGX7JH7E.cjs.map +1 -0
- package/dist/{chunk-U5SON7R2.cjs → chunk-WODMN3Q2.cjs} +27 -27
- package/dist/{chunk-U5SON7R2.cjs.map → chunk-WODMN3Q2.cjs.map} +1 -1
- package/dist/{chunk-K5ELX2GT.js → chunk-XVWOYKIK.js} +3 -3
- package/dist/{chunk-K5ELX2GT.js.map → chunk-XVWOYKIK.js.map} +1 -1
- package/dist/chunk-XY5OMOJD.js +147 -0
- package/dist/chunk-XY5OMOJD.js.map +1 -0
- package/dist/{chunk-LGHCOKTT.js → chunk-XYBQI6LE.js} +14 -14
- package/dist/{chunk-LGHCOKTT.js.map → chunk-XYBQI6LE.js.map} +1 -1
- package/dist/{chunk-YDFDBE6D.js → chunk-ZDKTPBGV.js} +4 -4
- package/dist/{chunk-YDFDBE6D.js.map → chunk-ZDKTPBGV.js.map} +1 -1
- package/dist/{chunk-MZLPX2R7.js → chunk-ZHNXLS3C.js} +9 -8
- package/dist/chunk-ZHNXLS3C.js.map +1 -0
- package/dist/{chunk-J3WZ3FA2.js → chunk-ZLONH2UD.js} +67 -3
- package/dist/chunk-ZLONH2UD.js.map +1 -0
- package/dist/core/index.cjs +28 -27
- package/dist/core/index.d.cts +4 -4
- package/dist/core/index.d.ts +4 -4
- package/dist/core/index.js +8 -7
- package/dist/{ddl-BXfGHbPN.d.ts → ddl-CprnMXJ-.d.ts} +3 -3
- package/dist/{ddl-BJcOp4WZ.d.cts → ddl-DJA7Lci5.d.cts} +3 -3
- package/dist/graph-extension/index.cjs +20 -20
- package/dist/graph-extension/index.d.cts +4 -4
- package/dist/graph-extension/index.d.ts +4 -4
- package/dist/graph-extension/index.js +4 -4
- package/dist/graph-merge/index.cjs +3204 -635
- package/dist/graph-merge/index.cjs.map +1 -1
- package/dist/graph-merge/index.d.cts +502 -60
- package/dist/graph-merge/index.d.ts +502 -60
- package/dist/graph-merge/index.js +2979 -427
- package/dist/graph-merge/index.js.map +1 -1
- package/dist/{index-BSHvKfok.d.ts → index-CHTv4XMZ.d.cts} +64 -3
- package/dist/{index-DxaYCv8Y.d.cts → index-CzoJ3MUw.d.ts} +64 -3
- package/dist/index.cjs +232 -215
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +11 -11
- package/dist/index.d.ts +11 -11
- package/dist/index.js +35 -34
- package/dist/index.js.map +1 -1
- package/dist/indexes/index.cjs +13 -13
- package/dist/indexes/index.d.cts +4 -4
- package/dist/indexes/index.d.ts +4 -4
- package/dist/indexes/index.js +6 -6
- package/dist/interchange/index.cjs +53 -52
- package/dist/interchange/index.cjs.map +1 -1
- package/dist/interchange/index.d.cts +17 -13
- package/dist/interchange/index.d.ts +17 -13
- package/dist/interchange/index.js +17 -16
- package/dist/interchange/index.js.map +1 -1
- package/dist/{manager-CfZAimti.d.ts → manager-B6sOQzcQ.d.ts} +2 -2
- package/dist/{manager-HGk6E_HW.d.cts → manager-DlY1vlla.d.cts} +2 -2
- package/dist/{materialize-indexes-BMJP6Tms.d.ts → materialize-indexes-DQL4xcpf.d.ts} +1 -1
- package/dist/{materialize-indexes-6A7dWGtb.d.cts → materialize-indexes-sskhp-c_.d.cts} +1 -1
- package/dist/{postgres-DFYWENdR.d.cts → postgres-B6YOUcaK.d.ts} +1 -1
- package/dist/{postgres-e7a9TdvR.d.ts → postgres-BXy_nyMs.d.cts} +1 -1
- package/dist/profiler/index.d.cts +9 -9
- package/dist/profiler/index.d.ts +9 -9
- package/dist/provenance/index.cjs +43 -42
- 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 +10 -9
- package/dist/provenance/index.js.map +1 -1
- package/dist/schema/index.cjs +45 -44
- package/dist/schema/index.d.cts +6 -6
- package/dist/schema/index.d.ts +6 -6
- package/dist/schema/index.js +18 -17
- package/dist/{searchable-CIje5XYD.d.cts → searchable-0Cn_lY8U.d.cts} +1 -1
- package/dist/{searchable-9OQoPuRs.d.ts → searchable-D9gMiwcS.d.ts} +1 -1
- package/dist/{sqlite-DerU5tc7.d.ts → sqlite-ClXuBYAj.d.ts} +1 -1
- package/dist/{sqlite-DitnISa9.d.cts → sqlite-DioSxaPe.d.cts} +1 -1
- package/dist/{store-ClQ-MZQS.d.ts → store-5j-w5onJ.d.ts} +128 -69
- package/dist/{store-B0h6x7wo.d.cts → store-CFedKGU5.d.cts} +128 -69
- package/dist/{temporal-Bn-Fi8FJ.d.cts → temporal-Ce1pG0S1.d.cts} +1 -1
- package/dist/{temporal-BtM4UALv.d.ts → temporal-CjO9FH1l.d.ts} +1 -1
- package/dist/{types-KFfk-8Ah.d.ts → types-BrdOFu48.d.ts} +1 -1
- package/dist/{types-HkveCCx0.d.ts → types-DKkMJZjR.d.cts} +39 -12
- package/dist/{types-HkveCCx0.d.cts → types-DKkMJZjR.d.ts} +39 -12
- package/dist/{types-CoIx8HX5.d.cts → types-oj_OGAaZ.d.cts} +1 -1
- package/dist/{where-ws5hf-Ov.d.ts → where-C8w2627G.d.ts} +1 -1
- package/dist/{where--fk7_0kv.d.cts → where-D1wKCJ4Q.d.cts} +1 -1
- package/package.json +1 -1
- package/dist/chunk-5763DULU.js.map +0 -1
- package/dist/chunk-7VQXLT5O.js.map +0 -1
- package/dist/chunk-A4OC4DVN.cjs +0 -12
- package/dist/chunk-AKLS3BYZ.js.map +0 -1
- package/dist/chunk-C23WSN5E.js.map +0 -1
- package/dist/chunk-CMWHLBVN.cjs.map +0 -1
- package/dist/chunk-DTVWX77L.cjs.map +0 -1
- package/dist/chunk-GF3KXUTW.js.map +0 -1
- package/dist/chunk-J3WZ3FA2.js.map +0 -1
- package/dist/chunk-L65OU2U3.js.map +0 -1
- package/dist/chunk-M3WP7RQZ.js.map +0 -1
- package/dist/chunk-MCLYU6BN.cjs.map +0 -1
- package/dist/chunk-MUK4BU7K.cjs.map +0 -1
- package/dist/chunk-MZLPX2R7.js.map +0 -1
- package/dist/chunk-NI72YOJB.cjs.map +0 -1
- package/dist/chunk-NLI2AVEF.js.map +0 -1
- package/dist/chunk-NMWDXFPH.js.map +0 -1
- package/dist/chunk-PF6F5NLJ.cjs.map +0 -1
- package/dist/chunk-PNTCATDE.cjs.map +0 -1
- package/dist/chunk-PT7RIRIZ.cjs.map +0 -1
- package/dist/chunk-Q3G6A4I3.cjs.map +0 -1
- package/dist/chunk-S6PW7VV5.js.map +0 -1
- package/dist/chunk-TQR4KBY2.cjs.map +0 -1
- package/dist/chunk-VQH4VAWD.cjs +0 -12
- package/dist/chunk-WQZLUGVR.js.map +0 -1
- package/dist/chunk-XBYVV3MP.cjs.map +0 -1
- package/dist/chunk-XL7SLCXS.js.map +0 -1
- package/dist/chunk-YAAM3M2S.cjs.map +0 -1
- package/dist/chunk-YBQOHKHN.cjs.map +0 -1
- package/dist/chunk-YVWGEQJE.cjs.map +0 -1
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
import { advanceRevisionClock, lockRecordedGraphWrite, uncapturedGraphWriteLock, identityAssertionSnapshotSource, identitySqlCoordinate, IDENTITY_ASSERTION_COLUMNS, compareCodePoints, withRecordedIdentityMutationTarget, recordedBindParamBudget, identityNodeVisibilitySql, historicalIdentityReconstructionCtes, generateId, identityNodeSnapshotSource } from './chunk-
|
|
2
|
-
import { chunk, isSqliteStaleSnapshotError, isMissingTableError } from './chunk-
|
|
3
|
-
import { runOptionallyInTransaction } from './chunk-
|
|
4
|
-
import { nowIso, canonicalizeDatabaseTimestamp } from './chunk-
|
|
5
|
-
import { getDialect } from './chunk-
|
|
6
|
-
import { asCompiledRowsSql, sql, asCompiledStatementSql } from './chunk-
|
|
7
|
-
import { ValidationError, ConfigurationError, NodeNotFoundError, KindNotFoundError, IdentityContradictionError, IdentitySeparationViolationError } from './chunk-
|
|
1
|
+
import { advanceRevisionClock, lockRecordedGraphWrite, uncapturedGraphWriteLock, identityAssertionSnapshotSource, identitySqlCoordinate, IDENTITY_ASSERTION_COLUMNS, compareCodePoints, withRecordedIdentityMutationTarget, recordedBindParamBudget, identityNodeVisibilitySql, historicalIdentityReconstructionCtes, generateId, identityNodeSnapshotSource } from './chunk-AVGUJWVX.js';
|
|
2
|
+
import { chunk, isSqliteStaleSnapshotError, isMissingTableError } from './chunk-NAZ2RA4L.js';
|
|
3
|
+
import { runOptionallyInTransaction } from './chunk-SHSSRCFR.js';
|
|
4
|
+
import { nowIso, canonicalizeDatabaseTimestamp, validateOptionalCanonicalIsoDate } from './chunk-NG2RB5WL.js';
|
|
5
|
+
import { getDialect } from './chunk-ZDKTPBGV.js';
|
|
6
|
+
import { asCompiledRowsSql, sql, asCompiledStatementSql } from './chunk-3DMMGT6S.js';
|
|
7
|
+
import { ValidationError, ConfigurationError, IdentityEndpointValidityError, NodeNotFoundError, KindNotFoundError, IdentityValidityWindowError, IdentityContradictionError, IdentitySeparationViolationError } from './chunk-ZLONH2UD.js';
|
|
8
8
|
import { requireDefined } from './chunk-DYATYRY4.js';
|
|
9
9
|
|
|
10
10
|
// src/errors/validation.ts
|
|
@@ -684,6 +684,12 @@ async function readIdentityAssertionsForInterchange(ctx, mode, options) {
|
|
|
684
684
|
|
|
685
685
|
// src/store/operations/write-transaction.ts
|
|
686
686
|
var writeTransactionSessions = /* @__PURE__ */ new WeakMap();
|
|
687
|
+
function forceWriteTransactionRevision(target) {
|
|
688
|
+
const session = writeTransactionSessions.get(target);
|
|
689
|
+
if (session === void 0) return false;
|
|
690
|
+
session.wrote = true;
|
|
691
|
+
return true;
|
|
692
|
+
}
|
|
687
693
|
var heldGraphWriteLocks = /* @__PURE__ */ new WeakMap();
|
|
688
694
|
async function withWriteTransactionSession(target, ctx, fn) {
|
|
689
695
|
const session = {
|
|
@@ -1490,6 +1496,51 @@ function separationMismatchError(graphId, detail) {
|
|
|
1490
1496
|
);
|
|
1491
1497
|
}
|
|
1492
1498
|
|
|
1499
|
+
// src/identity/validity-window.ts
|
|
1500
|
+
function hasExplicitIdentityValidityWindow(window) {
|
|
1501
|
+
return window?.validFrom !== void 0 || window?.validTo !== void 0;
|
|
1502
|
+
}
|
|
1503
|
+
function resolveIdentityValidityWindow(window, operationInstant) {
|
|
1504
|
+
const validFrom = validateOptionalCanonicalIsoDate(window?.validFrom, "validFrom") ?? operationInstant;
|
|
1505
|
+
const validTo = validateOptionalCanonicalIsoDate(window?.validTo, "validTo");
|
|
1506
|
+
if (compareCodePoints(validFrom, operationInstant) > 0) {
|
|
1507
|
+
throw new IdentityValidityWindowError({
|
|
1508
|
+
reason: "future-valid-from",
|
|
1509
|
+
validFrom,
|
|
1510
|
+
...validTo === void 0 ? {} : { validTo },
|
|
1511
|
+
operationInstant
|
|
1512
|
+
});
|
|
1513
|
+
}
|
|
1514
|
+
if (validTo !== void 0 && compareCodePoints(validTo, operationInstant) > 0) {
|
|
1515
|
+
throw new IdentityValidityWindowError({
|
|
1516
|
+
reason: "future-valid-to",
|
|
1517
|
+
validFrom,
|
|
1518
|
+
validTo,
|
|
1519
|
+
operationInstant
|
|
1520
|
+
});
|
|
1521
|
+
}
|
|
1522
|
+
if (validTo !== void 0 && compareCodePoints(validTo, validFrom) < 0) {
|
|
1523
|
+
throw new IdentityValidityWindowError({
|
|
1524
|
+
reason: "inverted",
|
|
1525
|
+
validFrom,
|
|
1526
|
+
validTo,
|
|
1527
|
+
operationInstant
|
|
1528
|
+
});
|
|
1529
|
+
}
|
|
1530
|
+
const effective = validTo === validFrom ? "empty" : validTo === void 0 ? "current" : "historical";
|
|
1531
|
+
return {
|
|
1532
|
+
validFrom,
|
|
1533
|
+
...validTo === void 0 ? {} : { validTo },
|
|
1534
|
+
effective
|
|
1535
|
+
};
|
|
1536
|
+
}
|
|
1537
|
+
function identityValidityWindowsOverlap(left, right) {
|
|
1538
|
+
if (left.validFrom === left.validTo || right.validFrom === right.validTo) {
|
|
1539
|
+
return false;
|
|
1540
|
+
}
|
|
1541
|
+
return (right.validTo === void 0 || left.validFrom < right.validTo) && (left.validTo === void 0 || right.validFrom < left.validTo);
|
|
1542
|
+
}
|
|
1543
|
+
|
|
1493
1544
|
// src/identity/service-mutation.ts
|
|
1494
1545
|
async function validateCurrentRelation(ctx, target, relation, operation, a, b) {
|
|
1495
1546
|
const classes = await loadCurrentStructuralClasses(
|
|
@@ -1557,23 +1608,50 @@ async function currentAssertionForPair(target, schema, graphId, relation, a, b)
|
|
|
1557
1608
|
);
|
|
1558
1609
|
return rows[0] === void 0 ? void 0 : normalizeIdentityAssertionRow(rows[0]);
|
|
1559
1610
|
}
|
|
1560
|
-
async function
|
|
1561
|
-
const
|
|
1611
|
+
async function assertionForExactWindow(target, schema, graphId, relation, a, b, window) {
|
|
1612
|
+
const validToMatch = window.validTo === void 0 ? sql`valid_to IS NULL` : sql`valid_to = ${window.validTo}`;
|
|
1613
|
+
const rows = await target.execute(
|
|
1614
|
+
asCompiledRowsSql(sql`
|
|
1615
|
+
SELECT ${IDENTITY_ASSERTION_COLUMNS}
|
|
1616
|
+
FROM ${schema.identityAssertionsTable}
|
|
1617
|
+
WHERE graph_id = ${graphId}
|
|
1618
|
+
AND rel = ${relation}
|
|
1619
|
+
AND a_kind = ${a.kind}
|
|
1620
|
+
AND a_id = ${a.id}
|
|
1621
|
+
AND b_kind = ${b.kind}
|
|
1622
|
+
AND b_id = ${b.id}
|
|
1623
|
+
AND valid_from = ${window.validFrom}
|
|
1624
|
+
AND ${validToMatch}
|
|
1625
|
+
AND deleted_at IS NULL
|
|
1626
|
+
LIMIT 1
|
|
1627
|
+
`)
|
|
1628
|
+
);
|
|
1629
|
+
return rows[0] === void 0 ? void 0 : normalizeIdentityAssertionRow(rows[0]);
|
|
1630
|
+
}
|
|
1631
|
+
async function insertAssertion(target, schema, graphId, relation, a, b, operationInstant, touch, options) {
|
|
1632
|
+
const row = buildAssertionRow(
|
|
1633
|
+
graphId,
|
|
1634
|
+
relation,
|
|
1635
|
+
a,
|
|
1636
|
+
b,
|
|
1637
|
+
operationInstant,
|
|
1638
|
+
options
|
|
1639
|
+
);
|
|
1562
1640
|
await insertAssertionRows(target, schema, [row]);
|
|
1563
1641
|
touch(graphId, row.id, row);
|
|
1564
1642
|
return row;
|
|
1565
1643
|
}
|
|
1566
|
-
function buildAssertionRow(graphId, relation, a, b, timestamp,
|
|
1644
|
+
function buildAssertionRow(graphId, relation, a, b, timestamp, options) {
|
|
1567
1645
|
return {
|
|
1568
1646
|
graph_id: graphId,
|
|
1569
|
-
id:
|
|
1647
|
+
id: options?.id ?? generateId(),
|
|
1570
1648
|
rel: relation,
|
|
1571
1649
|
a_kind: a.kind,
|
|
1572
1650
|
a_id: a.id,
|
|
1573
1651
|
b_kind: b.kind,
|
|
1574
1652
|
b_id: b.id,
|
|
1575
|
-
valid_from:
|
|
1576
|
-
valid_to:
|
|
1653
|
+
valid_from: options?.validFrom ?? timestamp,
|
|
1654
|
+
valid_to: options?.validTo,
|
|
1577
1655
|
created_at: timestamp,
|
|
1578
1656
|
updated_at: timestamp,
|
|
1579
1657
|
deleted_at: void 0,
|
|
@@ -1581,6 +1659,329 @@ function buildAssertionRow(graphId, relation, a, b, timestamp, preserved) {
|
|
|
1581
1659
|
ended_by_id: void 0
|
|
1582
1660
|
};
|
|
1583
1661
|
}
|
|
1662
|
+
function canonicalEndpointTimestamp(value) {
|
|
1663
|
+
if (value === void 0 || value === null) return void 0;
|
|
1664
|
+
return canonicalizeDatabaseTimestamp(value);
|
|
1665
|
+
}
|
|
1666
|
+
async function requireEndpointsCoverIdentityWindow(target, graphId, references, window) {
|
|
1667
|
+
for (const ref of references) {
|
|
1668
|
+
const row = await target.getNode(graphId, ref.kind, ref.id);
|
|
1669
|
+
if (row === void 0) throw new NodeNotFoundError(ref.kind, ref.id);
|
|
1670
|
+
if (window.effective === "empty") continue;
|
|
1671
|
+
const validFrom = canonicalEndpointTimestamp(row.valid_from);
|
|
1672
|
+
const validTo = canonicalEndpointTimestamp(row.valid_to);
|
|
1673
|
+
const deletedAt = canonicalEndpointTimestamp(row.deleted_at);
|
|
1674
|
+
const endpointWindow = {
|
|
1675
|
+
...validFrom === void 0 ? {} : { validFrom },
|
|
1676
|
+
...validTo === void 0 ? {} : { validTo },
|
|
1677
|
+
...deletedAt === void 0 ? {} : { deletedAt }
|
|
1678
|
+
};
|
|
1679
|
+
const startsTooLate = endpointWindow.validFrom !== void 0 && endpointWindow.validFrom > window.validFrom;
|
|
1680
|
+
const effectiveEnd = [endpointWindow.validTo, endpointWindow.deletedAt].filter((value) => value !== void 0).toSorted()[0];
|
|
1681
|
+
const endsTooEarly = window.validTo === void 0 ? effectiveEnd !== void 0 : effectiveEnd !== void 0 && effectiveEnd < window.validTo;
|
|
1682
|
+
if (!startsTooLate && !endsTooEarly) continue;
|
|
1683
|
+
throw new IdentityEndpointValidityError({
|
|
1684
|
+
endpoint: ref,
|
|
1685
|
+
assertionWindow: {
|
|
1686
|
+
validFrom: window.validFrom,
|
|
1687
|
+
...window.validTo === void 0 ? {} : { validTo: window.validTo }
|
|
1688
|
+
},
|
|
1689
|
+
endpointWindow
|
|
1690
|
+
});
|
|
1691
|
+
}
|
|
1692
|
+
}
|
|
1693
|
+
function windowOverlapSql(alias, lowerBoundary, upperBoundary) {
|
|
1694
|
+
const column = (name) => sql`${sql.identifier(alias)}.${sql.identifier(name)}`;
|
|
1695
|
+
return sql`
|
|
1696
|
+
${column("deleted_at")} IS NULL
|
|
1697
|
+
AND ${column("valid_from")} <= ${upperBoundary}
|
|
1698
|
+
AND (${column("valid_to")} IS NULL OR ${column("valid_to")} > ${lowerBoundary})
|
|
1699
|
+
`;
|
|
1700
|
+
}
|
|
1701
|
+
async function loadIdentityWindowLedger(target, schema, graphId, requests, operationInstant, sameIdAcrossKinds) {
|
|
1702
|
+
const activeRequests = requests.filter(
|
|
1703
|
+
(request) => request.window.effective !== "empty"
|
|
1704
|
+
);
|
|
1705
|
+
if (activeRequests.length === 0) return { nodes: [], assertions: [] };
|
|
1706
|
+
const referencesByKey = /* @__PURE__ */ new Map();
|
|
1707
|
+
for (const request of activeRequests) {
|
|
1708
|
+
for (const reference of request.references) {
|
|
1709
|
+
referencesByKey.set(refKey(reference), reference);
|
|
1710
|
+
}
|
|
1711
|
+
}
|
|
1712
|
+
const references = [...referencesByKey.values()];
|
|
1713
|
+
const lowerBoundary = requireDefined(
|
|
1714
|
+
activeRequests.map((request) => request.window.validFrom).toSorted()[0]
|
|
1715
|
+
);
|
|
1716
|
+
const upperBoundary = requireDefined(
|
|
1717
|
+
activeRequests.map((request) => request.window.validTo ?? operationInstant).toSorted().at(-1)
|
|
1718
|
+
);
|
|
1719
|
+
const seedChunkSize = identityChunkSize(target, {
|
|
1720
|
+
fixedParameters: 20,
|
|
1721
|
+
maxItems: MAX_REFERENCE_CHUNK_SIZE,
|
|
1722
|
+
parametersPerItem: 2
|
|
1723
|
+
});
|
|
1724
|
+
const rows = [];
|
|
1725
|
+
for (const referenceChunk of chunk(references, seedChunkSize)) {
|
|
1726
|
+
const seedRows = sql.join(
|
|
1727
|
+
referenceChunk.map(
|
|
1728
|
+
(reference) => sql`(${reference.kind}, ${reference.id})`
|
|
1729
|
+
),
|
|
1730
|
+
sql`, `
|
|
1731
|
+
);
|
|
1732
|
+
const component = sameIdAcrossKinds === "fold" ? sql`
|
|
1733
|
+
neighbor_modes(mode) AS (
|
|
1734
|
+
VALUES ('assertion'), ('fold')
|
|
1735
|
+
),
|
|
1736
|
+
component(kind, id) AS (
|
|
1737
|
+
SELECT seed_kind, seed_id FROM seeds
|
|
1738
|
+
UNION
|
|
1739
|
+
SELECT CASE
|
|
1740
|
+
WHEN neighbor_modes.mode = 'fold' THEN folded.kind
|
|
1741
|
+
WHEN assertion.a_kind = component.kind AND assertion.a_id = component.id
|
|
1742
|
+
THEN assertion.b_kind
|
|
1743
|
+
ELSE assertion.a_kind
|
|
1744
|
+
END,
|
|
1745
|
+
CASE
|
|
1746
|
+
WHEN neighbor_modes.mode = 'fold' THEN folded.id
|
|
1747
|
+
WHEN assertion.a_kind = component.kind AND assertion.a_id = component.id
|
|
1748
|
+
THEN assertion.b_id
|
|
1749
|
+
ELSE assertion.a_id
|
|
1750
|
+
END
|
|
1751
|
+
FROM component
|
|
1752
|
+
JOIN neighbor_modes ON 1 = 1
|
|
1753
|
+
LEFT JOIN ${schema.identityAssertionsTable} assertion
|
|
1754
|
+
ON neighbor_modes.mode = 'assertion'
|
|
1755
|
+
AND assertion.graph_id = ${graphId}
|
|
1756
|
+
AND assertion.rel = 'same'
|
|
1757
|
+
AND ${windowOverlapSql("assertion", lowerBoundary, upperBoundary)}
|
|
1758
|
+
AND ((assertion.a_kind = component.kind AND assertion.a_id = component.id)
|
|
1759
|
+
OR (assertion.b_kind = component.kind AND assertion.b_id = component.id))
|
|
1760
|
+
LEFT JOIN ${schema.nodesTable} folded
|
|
1761
|
+
ON neighbor_modes.mode = 'fold'
|
|
1762
|
+
AND folded.graph_id = ${graphId}
|
|
1763
|
+
AND folded.id = component.id
|
|
1764
|
+
WHERE assertion.id IS NOT NULL OR folded.id IS NOT NULL
|
|
1765
|
+
)
|
|
1766
|
+
` : sql`
|
|
1767
|
+
component(kind, id) AS (
|
|
1768
|
+
SELECT seed_kind, seed_id FROM seeds
|
|
1769
|
+
UNION
|
|
1770
|
+
SELECT CASE
|
|
1771
|
+
WHEN assertion.a_kind = component.kind AND assertion.a_id = component.id
|
|
1772
|
+
THEN assertion.b_kind
|
|
1773
|
+
ELSE assertion.a_kind
|
|
1774
|
+
END,
|
|
1775
|
+
CASE
|
|
1776
|
+
WHEN assertion.a_kind = component.kind AND assertion.a_id = component.id
|
|
1777
|
+
THEN assertion.b_id
|
|
1778
|
+
ELSE assertion.a_id
|
|
1779
|
+
END
|
|
1780
|
+
FROM component
|
|
1781
|
+
JOIN ${schema.identityAssertionsTable} assertion
|
|
1782
|
+
ON assertion.graph_id = ${graphId}
|
|
1783
|
+
AND assertion.rel = 'same'
|
|
1784
|
+
AND ${windowOverlapSql("assertion", lowerBoundary, upperBoundary)}
|
|
1785
|
+
AND ((assertion.a_kind = component.kind AND assertion.a_id = component.id)
|
|
1786
|
+
OR (assertion.b_kind = component.kind AND assertion.b_id = component.id))
|
|
1787
|
+
)
|
|
1788
|
+
`;
|
|
1789
|
+
rows.push(
|
|
1790
|
+
...await target.execute(
|
|
1791
|
+
asCompiledRowsSql(sql`
|
|
1792
|
+
WITH RECURSIVE
|
|
1793
|
+
seeds(seed_kind, seed_id) AS (VALUES ${seedRows}),
|
|
1794
|
+
${component},
|
|
1795
|
+
selected_assertions AS (
|
|
1796
|
+
SELECT DISTINCT assertion.*
|
|
1797
|
+
FROM ${schema.identityAssertionsTable} assertion
|
|
1798
|
+
JOIN component
|
|
1799
|
+
ON (assertion.a_kind = component.kind AND assertion.a_id = component.id)
|
|
1800
|
+
OR (assertion.b_kind = component.kind AND assertion.b_id = component.id)
|
|
1801
|
+
WHERE assertion.graph_id = ${graphId}
|
|
1802
|
+
AND ${windowOverlapSql("assertion", lowerBoundary, upperBoundary)}
|
|
1803
|
+
)
|
|
1804
|
+
SELECT 'assertion' AS row_type, ${IDENTITY_ASSERTION_COLUMNS},
|
|
1805
|
+
NULL AS node_kind, NULL AS node_id,
|
|
1806
|
+
NULL AS node_created_at, NULL AS node_deleted_at
|
|
1807
|
+
FROM selected_assertions
|
|
1808
|
+
UNION ALL
|
|
1809
|
+
SELECT 'node', NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
|
1810
|
+
NULL, NULL, NULL, NULL, NULL,
|
|
1811
|
+
node.kind, node.id, node.created_at, node.deleted_at
|
|
1812
|
+
FROM ${schema.nodesTable} node
|
|
1813
|
+
JOIN component ON component.kind = node.kind AND component.id = node.id
|
|
1814
|
+
WHERE node.graph_id = ${graphId}
|
|
1815
|
+
`)
|
|
1816
|
+
)
|
|
1817
|
+
);
|
|
1818
|
+
}
|
|
1819
|
+
const nodesByKey = /* @__PURE__ */ new Map();
|
|
1820
|
+
const assertionsById = /* @__PURE__ */ new Map();
|
|
1821
|
+
for (const row of rows) {
|
|
1822
|
+
if (row.row_type === "assertion") {
|
|
1823
|
+
const assertion = normalizeIdentityAssertionRow(row);
|
|
1824
|
+
assertionsById.set(assertion.id, assertion);
|
|
1825
|
+
continue;
|
|
1826
|
+
}
|
|
1827
|
+
if (typeof row.node_kind !== "string" || typeof row.node_id !== "string")
|
|
1828
|
+
continue;
|
|
1829
|
+
const createdAt = canonicalEndpointTimestamp(row.node_created_at);
|
|
1830
|
+
if (createdAt === void 0) continue;
|
|
1831
|
+
const deletedAt = canonicalEndpointTimestamp(row.node_deleted_at);
|
|
1832
|
+
const node = {
|
|
1833
|
+
ref: { kind: row.node_kind, id: row.node_id },
|
|
1834
|
+
createdAt,
|
|
1835
|
+
...deletedAt === void 0 ? {} : { deletedAt }
|
|
1836
|
+
};
|
|
1837
|
+
nodesByKey.set(refKey(node.ref), node);
|
|
1838
|
+
}
|
|
1839
|
+
return {
|
|
1840
|
+
nodes: [...nodesByKey.values()],
|
|
1841
|
+
assertions: [...assertionsById.values()]
|
|
1842
|
+
};
|
|
1843
|
+
}
|
|
1844
|
+
function identityWindowCheckpoints(window, operationInstant, nodes, assertions) {
|
|
1845
|
+
if (window.effective === "empty") return [];
|
|
1846
|
+
const checkpoints = /* @__PURE__ */ new Set([window.validFrom]);
|
|
1847
|
+
if (window.validTo === void 0) checkpoints.add(operationInstant);
|
|
1848
|
+
for (const row of [...assertions, ...nodes]) {
|
|
1849
|
+
for (const value of [
|
|
1850
|
+
"valid_from" in row ? row.valid_from : void 0,
|
|
1851
|
+
"valid_to" in row ? row.valid_to : void 0,
|
|
1852
|
+
"createdAt" in row ? row.createdAt : void 0,
|
|
1853
|
+
"deletedAt" in row ? row.deletedAt : void 0
|
|
1854
|
+
]) {
|
|
1855
|
+
const boundary = canonicalEndpointTimestamp(value);
|
|
1856
|
+
if (boundary === void 0 || boundary < window.validFrom) continue;
|
|
1857
|
+
if (window.validTo !== void 0 && boundary >= window.validTo) continue;
|
|
1858
|
+
if (boundary > operationInstant) continue;
|
|
1859
|
+
checkpoints.add(boundary);
|
|
1860
|
+
}
|
|
1861
|
+
}
|
|
1862
|
+
return [...checkpoints].toSorted();
|
|
1863
|
+
}
|
|
1864
|
+
function validateRelationAgainstLedger(ctx, nodes, assertions, relation, operation, a, b, window, operationInstant) {
|
|
1865
|
+
const checkpoints = identityWindowCheckpoints(
|
|
1866
|
+
window,
|
|
1867
|
+
operationInstant,
|
|
1868
|
+
nodes,
|
|
1869
|
+
assertions
|
|
1870
|
+
);
|
|
1871
|
+
for (const instant of checkpoints) {
|
|
1872
|
+
const structuralNodes = nodes.map((node) => node.ref);
|
|
1873
|
+
const activeAssertions = assertions.filter(
|
|
1874
|
+
(assertion) => assertion.deleted_at === void 0 && assertion.valid_from <= instant && (assertion.valid_to === void 0 || assertion.valid_to > instant)
|
|
1875
|
+
);
|
|
1876
|
+
const activeFoldReferences = nodes.filter(
|
|
1877
|
+
(node) => node.createdAt <= instant && (node.deletedAt === void 0 || node.deletedAt > instant)
|
|
1878
|
+
).map((node) => node.ref);
|
|
1879
|
+
const foldAssertions = [];
|
|
1880
|
+
if (ctx.sameIdAcrossKinds === "fold") {
|
|
1881
|
+
const byId = /* @__PURE__ */ new Map();
|
|
1882
|
+
for (const reference of activeFoldReferences) {
|
|
1883
|
+
const sameId = byId.get(reference.id) ?? [];
|
|
1884
|
+
sameId.push(reference);
|
|
1885
|
+
byId.set(reference.id, sameId);
|
|
1886
|
+
}
|
|
1887
|
+
for (const sameId of byId.values()) {
|
|
1888
|
+
const first = sameId[0];
|
|
1889
|
+
if (first === void 0) continue;
|
|
1890
|
+
for (const other of sameId.slice(1)) {
|
|
1891
|
+
foldAssertions.push({
|
|
1892
|
+
rel: "same",
|
|
1893
|
+
a_kind: first.kind,
|
|
1894
|
+
a_id: first.id,
|
|
1895
|
+
b_kind: other.kind,
|
|
1896
|
+
b_id: other.id
|
|
1897
|
+
});
|
|
1898
|
+
}
|
|
1899
|
+
}
|
|
1900
|
+
}
|
|
1901
|
+
const components = buildComponents(
|
|
1902
|
+
structuralNodes,
|
|
1903
|
+
[...activeAssertions, ...foldAssertions],
|
|
1904
|
+
"ignore"
|
|
1905
|
+
);
|
|
1906
|
+
const aClass = components.get(refKey(a)) ?? [];
|
|
1907
|
+
const bClass = components.get(refKey(b)) ?? [];
|
|
1908
|
+
if (relation === "different") {
|
|
1909
|
+
if (!containsRef(aClass, b)) continue;
|
|
1910
|
+
throw new IdentityContradictionError({
|
|
1911
|
+
operation,
|
|
1912
|
+
a,
|
|
1913
|
+
b,
|
|
1914
|
+
reason: "same-class"
|
|
1915
|
+
});
|
|
1916
|
+
}
|
|
1917
|
+
const different = spanningDifferentAssertion(
|
|
1918
|
+
activeAssertions,
|
|
1919
|
+
aClass,
|
|
1920
|
+
bClass
|
|
1921
|
+
);
|
|
1922
|
+
if (different !== void 0) {
|
|
1923
|
+
throw new IdentityContradictionError({
|
|
1924
|
+
operation,
|
|
1925
|
+
a,
|
|
1926
|
+
b,
|
|
1927
|
+
reason: "different-assertion",
|
|
1928
|
+
conflictingAssertionId: different.id
|
|
1929
|
+
});
|
|
1930
|
+
}
|
|
1931
|
+
const disjointKinds = classHasDisjointKinds(ctx.registry, aClass, bClass);
|
|
1932
|
+
if (disjointKinds === void 0) continue;
|
|
1933
|
+
throw new IdentityContradictionError({
|
|
1934
|
+
operation,
|
|
1935
|
+
a,
|
|
1936
|
+
b,
|
|
1937
|
+
reason: "disjoint-kinds",
|
|
1938
|
+
conflictingKinds: disjointKinds
|
|
1939
|
+
});
|
|
1940
|
+
}
|
|
1941
|
+
}
|
|
1942
|
+
async function createIdentityWindowValidator(ctx, target, requests, operationInstant, ignoredAssertionIds = /* @__PURE__ */ new Set()) {
|
|
1943
|
+
const ledger = await loadIdentityWindowLedger(
|
|
1944
|
+
target,
|
|
1945
|
+
ctx.schema,
|
|
1946
|
+
ctx.graphId,
|
|
1947
|
+
requests,
|
|
1948
|
+
operationInstant,
|
|
1949
|
+
ctx.sameIdAcrossKinds
|
|
1950
|
+
);
|
|
1951
|
+
if (ignoredAssertionIds.size > 0) {
|
|
1952
|
+
const retained = ledger.assertions.filter(
|
|
1953
|
+
(assertion) => !ignoredAssertionIds.has(assertion.id)
|
|
1954
|
+
);
|
|
1955
|
+
ledger.assertions.splice(0, ledger.assertions.length, ...retained);
|
|
1956
|
+
}
|
|
1957
|
+
return {
|
|
1958
|
+
validate(relation, operation, a, b, window) {
|
|
1959
|
+
validateRelationAgainstLedger(
|
|
1960
|
+
ctx,
|
|
1961
|
+
ledger.nodes,
|
|
1962
|
+
ledger.assertions,
|
|
1963
|
+
relation,
|
|
1964
|
+
operation,
|
|
1965
|
+
a,
|
|
1966
|
+
b,
|
|
1967
|
+
window,
|
|
1968
|
+
operationInstant
|
|
1969
|
+
);
|
|
1970
|
+
},
|
|
1971
|
+
record(assertion) {
|
|
1972
|
+
ledger.assertions.push(assertion);
|
|
1973
|
+
}
|
|
1974
|
+
};
|
|
1975
|
+
}
|
|
1976
|
+
async function validateRelationThroughoutIdentityWindow(ctx, target, relation, operation, a, b, window, operationInstant) {
|
|
1977
|
+
const validator = await createIdentityWindowValidator(
|
|
1978
|
+
ctx,
|
|
1979
|
+
target,
|
|
1980
|
+
[{ references: [a, b], window }],
|
|
1981
|
+
operationInstant
|
|
1982
|
+
);
|
|
1983
|
+
validator.validate(relation, operation, a, b, window);
|
|
1984
|
+
}
|
|
1584
1985
|
function nullableAssertionValue(value) {
|
|
1585
1986
|
return value === void 0 ? sql`NULL` : sql`${value}`;
|
|
1586
1987
|
}
|
|
@@ -1903,34 +2304,107 @@ async function mergeCurrentClasses(target, schema, graphId, a, b) {
|
|
|
1903
2304
|
}
|
|
1904
2305
|
await replaceSeparationForMembers(target, schema, graphId, fusedMembers);
|
|
1905
2306
|
}
|
|
1906
|
-
async function assertPair(ctx, target, relation, firstInput, secondInput, touch) {
|
|
2307
|
+
async function assertPair(ctx, target, relation, firstInput, secondInput, touch, windowInput, operationInstant, windowValidator) {
|
|
1907
2308
|
const first = registeredPlainRef(ctx, firstInput);
|
|
1908
2309
|
const second = registeredPlainRef(ctx, secondInput);
|
|
1909
2310
|
if (refKey(first) === refKey(second)) throw selfAssertionError(relation);
|
|
1910
2311
|
const [a, b] = normalizePair(first, second);
|
|
1911
|
-
|
|
1912
|
-
|
|
1913
|
-
|
|
1914
|
-
|
|
1915
|
-
|
|
2312
|
+
if (windowInput === void 0) {
|
|
2313
|
+
const current = await currentAssertionForPair(
|
|
2314
|
+
target,
|
|
2315
|
+
ctx.schema,
|
|
2316
|
+
ctx.graphId,
|
|
2317
|
+
relation,
|
|
2318
|
+
a,
|
|
2319
|
+
b
|
|
2320
|
+
);
|
|
2321
|
+
if (current !== void 0) {
|
|
2322
|
+
return assertionResult(publicAssertion(current), "existing");
|
|
2323
|
+
}
|
|
2324
|
+
await Promise.all([
|
|
2325
|
+
requireLiveEndpoint(target, ctx.graphId, a),
|
|
2326
|
+
requireLiveEndpoint(target, ctx.graphId, b)
|
|
2327
|
+
]);
|
|
2328
|
+
await validateCurrentRelation(
|
|
2329
|
+
ctx,
|
|
2330
|
+
target,
|
|
2331
|
+
relation,
|
|
2332
|
+
relation === "same" ? "assertSame" : "assertDifferent",
|
|
2333
|
+
a,
|
|
2334
|
+
b
|
|
2335
|
+
);
|
|
2336
|
+
const row2 = await insertAssertion(
|
|
2337
|
+
target,
|
|
2338
|
+
ctx.schema,
|
|
2339
|
+
ctx.graphId,
|
|
2340
|
+
relation,
|
|
2341
|
+
a,
|
|
2342
|
+
b,
|
|
2343
|
+
operationInstant,
|
|
2344
|
+
touch
|
|
2345
|
+
);
|
|
2346
|
+
windowValidator?.record(row2);
|
|
2347
|
+
if (relation === "same") {
|
|
2348
|
+
await mergeCurrentClasses(target, ctx.schema, ctx.graphId, a, b);
|
|
2349
|
+
} else {
|
|
2350
|
+
await replaceSeparationForReferences(target, ctx.schema, ctx.graphId, [
|
|
2351
|
+
a,
|
|
2352
|
+
b
|
|
2353
|
+
]);
|
|
2354
|
+
}
|
|
2355
|
+
return assertionResult(publicAssertion(row2), "created");
|
|
2356
|
+
}
|
|
2357
|
+
const window = resolveIdentityValidityWindow(windowInput, operationInstant);
|
|
2358
|
+
await requireEndpointsCoverIdentityWindow(
|
|
2359
|
+
target,
|
|
2360
|
+
ctx.graphId,
|
|
2361
|
+
[a, b],
|
|
2362
|
+
window
|
|
2363
|
+
);
|
|
2364
|
+
const existing = await assertionForExactWindow(
|
|
1916
2365
|
target,
|
|
1917
2366
|
ctx.schema,
|
|
1918
2367
|
ctx.graphId,
|
|
1919
2368
|
relation,
|
|
1920
2369
|
a,
|
|
1921
|
-
b
|
|
2370
|
+
b,
|
|
2371
|
+
window
|
|
1922
2372
|
);
|
|
1923
2373
|
if (existing !== void 0) {
|
|
1924
2374
|
return assertionResult(publicAssertion(existing), "existing");
|
|
1925
2375
|
}
|
|
1926
|
-
|
|
1927
|
-
|
|
1928
|
-
|
|
1929
|
-
|
|
1930
|
-
|
|
1931
|
-
|
|
1932
|
-
|
|
1933
|
-
|
|
2376
|
+
if (window.effective === "current") {
|
|
2377
|
+
const current = await currentAssertionForPair(
|
|
2378
|
+
target,
|
|
2379
|
+
ctx.schema,
|
|
2380
|
+
ctx.graphId,
|
|
2381
|
+
relation,
|
|
2382
|
+
a,
|
|
2383
|
+
b
|
|
2384
|
+
);
|
|
2385
|
+
if (current !== void 0) {
|
|
2386
|
+
throw new IdentityValidityWindowError({
|
|
2387
|
+
reason: "overlapping-open-window",
|
|
2388
|
+
validFrom: window.validFrom,
|
|
2389
|
+
operationInstant
|
|
2390
|
+
});
|
|
2391
|
+
}
|
|
2392
|
+
}
|
|
2393
|
+
const operation = relation === "same" ? "assertSame" : "assertDifferent";
|
|
2394
|
+
if (windowValidator === void 0) {
|
|
2395
|
+
await validateRelationThroughoutIdentityWindow(
|
|
2396
|
+
ctx,
|
|
2397
|
+
target,
|
|
2398
|
+
relation,
|
|
2399
|
+
operation,
|
|
2400
|
+
a,
|
|
2401
|
+
b,
|
|
2402
|
+
window,
|
|
2403
|
+
operationInstant
|
|
2404
|
+
);
|
|
2405
|
+
} else {
|
|
2406
|
+
windowValidator.validate(relation, operation, a, b, window);
|
|
2407
|
+
}
|
|
1934
2408
|
const row = await insertAssertion(
|
|
1935
2409
|
target,
|
|
1936
2410
|
ctx.schema,
|
|
@@ -1938,9 +2412,17 @@ async function assertPair(ctx, target, relation, firstInput, secondInput, touch)
|
|
|
1938
2412
|
relation,
|
|
1939
2413
|
a,
|
|
1940
2414
|
b,
|
|
1941
|
-
|
|
1942
|
-
touch
|
|
2415
|
+
operationInstant,
|
|
2416
|
+
touch,
|
|
2417
|
+
{
|
|
2418
|
+
validFrom: window.validFrom,
|
|
2419
|
+
...window.validTo === void 0 ? {} : { validTo: window.validTo }
|
|
2420
|
+
}
|
|
1943
2421
|
);
|
|
2422
|
+
windowValidator?.record(row);
|
|
2423
|
+
if (window.effective !== "current") {
|
|
2424
|
+
return assertionResult(publicAssertion(row), "created");
|
|
2425
|
+
}
|
|
1944
2426
|
if (relation === "same") {
|
|
1945
2427
|
await mergeCurrentClasses(target, ctx.schema, ctx.graphId, a, b);
|
|
1946
2428
|
} else {
|
|
@@ -2145,6 +2627,40 @@ async function bulkAssertPairs(ctx, target, relation, pairs, touch) {
|
|
|
2145
2627
|
}
|
|
2146
2628
|
return results;
|
|
2147
2629
|
}
|
|
2630
|
+
async function bulkAssertWindowedPairs(ctx, target, relation, pairs, touch, operationInstant) {
|
|
2631
|
+
const windowRequests = pairs.map((pair) => {
|
|
2632
|
+
const first = registeredPlainRef(ctx, pair.a);
|
|
2633
|
+
const second = registeredPlainRef(ctx, pair.b);
|
|
2634
|
+
return {
|
|
2635
|
+
references: normalizePair(first, second),
|
|
2636
|
+
window: resolveIdentityValidityWindow(pair, operationInstant)
|
|
2637
|
+
};
|
|
2638
|
+
});
|
|
2639
|
+
const windowValidator = await createIdentityWindowValidator(
|
|
2640
|
+
ctx,
|
|
2641
|
+
target,
|
|
2642
|
+
windowRequests,
|
|
2643
|
+
operationInstant
|
|
2644
|
+
);
|
|
2645
|
+
const results = [];
|
|
2646
|
+
for (const pair of pairs) {
|
|
2647
|
+
const window = hasExplicitIdentityValidityWindow(pair) ? pair : void 0;
|
|
2648
|
+
results.push(
|
|
2649
|
+
await assertPair(
|
|
2650
|
+
ctx,
|
|
2651
|
+
target,
|
|
2652
|
+
relation,
|
|
2653
|
+
pair.a,
|
|
2654
|
+
pair.b,
|
|
2655
|
+
touch,
|
|
2656
|
+
window,
|
|
2657
|
+
operationInstant,
|
|
2658
|
+
windowValidator
|
|
2659
|
+
)
|
|
2660
|
+
);
|
|
2661
|
+
}
|
|
2662
|
+
return results;
|
|
2663
|
+
}
|
|
2148
2664
|
async function findCurrentAssertionById(target, schema, graphId, id) {
|
|
2149
2665
|
const rows = await target.execute(
|
|
2150
2666
|
asCompiledRowsSql(sql`
|
|
@@ -2183,7 +2699,7 @@ async function retractById(ctx, target, id, touch) {
|
|
|
2183
2699
|
touch(ctx.graphId, id, ended);
|
|
2184
2700
|
return ended;
|
|
2185
2701
|
}
|
|
2186
|
-
async function
|
|
2702
|
+
async function retractCurrentAssertions(ctx, target, ids, touch, resolveValidTo) {
|
|
2187
2703
|
const uniqueIds = [...new Set(ids)];
|
|
2188
2704
|
if (uniqueIds.length === 0) return [];
|
|
2189
2705
|
const current = [];
|
|
@@ -2210,11 +2726,11 @@ async function retractByIds(ctx, target, ids, touch) {
|
|
|
2210
2726
|
current.push(...rows.map((row) => normalizeIdentityAssertionRow(row)));
|
|
2211
2727
|
}
|
|
2212
2728
|
if (current.length === 0) return [];
|
|
2213
|
-
const
|
|
2729
|
+
const operationInstant = nowIso();
|
|
2214
2730
|
const byValidTo = /* @__PURE__ */ new Map();
|
|
2215
2731
|
const endedById = /* @__PURE__ */ new Map();
|
|
2216
2732
|
for (const row of current) {
|
|
2217
|
-
const validTo =
|
|
2733
|
+
const validTo = resolveValidTo(row, operationInstant);
|
|
2218
2734
|
endedById.set(row.id, validTo);
|
|
2219
2735
|
const group = byValidTo.get(validTo) ?? [];
|
|
2220
2736
|
group.push(row.id);
|
|
@@ -2235,7 +2751,7 @@ async function retractByIds(ctx, target, ids, touch) {
|
|
|
2235
2751
|
target,
|
|
2236
2752
|
sql`
|
|
2237
2753
|
UPDATE ${ctx.schema.identityAssertionsTable}
|
|
2238
|
-
SET valid_to = ${validTo}, updated_at = ${
|
|
2754
|
+
SET valid_to = ${validTo}, updated_at = ${operationInstant}
|
|
2239
2755
|
WHERE graph_id = ${ctx.graphId}
|
|
2240
2756
|
AND id IN (${placeholders})
|
|
2241
2757
|
AND valid_to IS NULL
|
|
@@ -2251,7 +2767,7 @@ async function retractByIds(ctx, target, ids, touch) {
|
|
|
2251
2767
|
{
|
|
2252
2768
|
...row,
|
|
2253
2769
|
valid_to: requireDefined(endedById.get(row.id)),
|
|
2254
|
-
updated_at:
|
|
2770
|
+
updated_at: operationInstant
|
|
2255
2771
|
}
|
|
2256
2772
|
];
|
|
2257
2773
|
});
|
|
@@ -2260,6 +2776,44 @@ async function retractByIds(ctx, target, ids, touch) {
|
|
|
2260
2776
|
}
|
|
2261
2777
|
return ended;
|
|
2262
2778
|
}
|
|
2779
|
+
async function retractByIds(ctx, target, ids, touch) {
|
|
2780
|
+
return retractCurrentAssertions(
|
|
2781
|
+
ctx,
|
|
2782
|
+
target,
|
|
2783
|
+
ids,
|
|
2784
|
+
touch,
|
|
2785
|
+
(row, operationInstant) => clampValidTo(operationInstant, row.valid_from)
|
|
2786
|
+
);
|
|
2787
|
+
}
|
|
2788
|
+
async function retractPlannedAssertions(ctx, target, retractions, touch) {
|
|
2789
|
+
const retractionById = new Map(
|
|
2790
|
+
retractions.map((retraction) => [retraction.id, retraction])
|
|
2791
|
+
);
|
|
2792
|
+
return retractCurrentAssertions(
|
|
2793
|
+
ctx,
|
|
2794
|
+
target,
|
|
2795
|
+
retractions.map((retraction) => retraction.id),
|
|
2796
|
+
touch,
|
|
2797
|
+
(row, operationInstant) => {
|
|
2798
|
+
const retraction = requireDefined(retractionById.get(row.id));
|
|
2799
|
+
if (retraction.validTo === void 0) {
|
|
2800
|
+
throw new ConfigurationError(
|
|
2801
|
+
`Identity merge retraction ${retraction.id} is missing validTo.`,
|
|
2802
|
+
{
|
|
2803
|
+
code: "IDENTITY_MERGE_RETRACTION_REQUIRES_END",
|
|
2804
|
+
assertionId: retraction.id
|
|
2805
|
+
}
|
|
2806
|
+
);
|
|
2807
|
+
}
|
|
2808
|
+
return requireDefined(
|
|
2809
|
+
resolveIdentityValidityWindow(
|
|
2810
|
+
{ validFrom: row.valid_from, validTo: retraction.validTo },
|
|
2811
|
+
operationInstant
|
|
2812
|
+
).validTo
|
|
2813
|
+
);
|
|
2814
|
+
}
|
|
2815
|
+
);
|
|
2816
|
+
}
|
|
2263
2817
|
async function runIdentityMutation(ctx, fn) {
|
|
2264
2818
|
let touched = false;
|
|
2265
2819
|
return runInWriteTransaction(
|
|
@@ -2421,29 +2975,65 @@ function partitionRetractedEndpoints(retracted) {
|
|
|
2421
2975
|
function createIdentityFacade(ctx) {
|
|
2422
2976
|
return {
|
|
2423
2977
|
...createIdentityReadFacade(ctx),
|
|
2424
|
-
assertSame(a, b) {
|
|
2425
|
-
return runIdentityMutation(
|
|
2426
|
-
|
|
2427
|
-
|
|
2428
|
-
|
|
2978
|
+
assertSame(a, b, window) {
|
|
2979
|
+
return runIdentityMutation(ctx, (target, touch) => {
|
|
2980
|
+
const operationInstant = nowIso();
|
|
2981
|
+
return assertPair(
|
|
2982
|
+
ctx,
|
|
2983
|
+
target,
|
|
2984
|
+
"same",
|
|
2985
|
+
a,
|
|
2986
|
+
b,
|
|
2987
|
+
touch,
|
|
2988
|
+
hasExplicitIdentityValidityWindow(window) ? window : void 0,
|
|
2989
|
+
operationInstant
|
|
2990
|
+
);
|
|
2991
|
+
});
|
|
2429
2992
|
},
|
|
2430
|
-
assertDifferent(a, b) {
|
|
2431
|
-
return runIdentityMutation(
|
|
2432
|
-
|
|
2433
|
-
|
|
2434
|
-
|
|
2993
|
+
assertDifferent(a, b, window) {
|
|
2994
|
+
return runIdentityMutation(ctx, (target, touch) => {
|
|
2995
|
+
const operationInstant = nowIso();
|
|
2996
|
+
return assertPair(
|
|
2997
|
+
ctx,
|
|
2998
|
+
target,
|
|
2999
|
+
"different",
|
|
3000
|
+
a,
|
|
3001
|
+
b,
|
|
3002
|
+
touch,
|
|
3003
|
+
hasExplicitIdentityValidityWindow(window) ? window : void 0,
|
|
3004
|
+
operationInstant
|
|
3005
|
+
);
|
|
3006
|
+
});
|
|
2435
3007
|
},
|
|
2436
3008
|
bulkAssertSame(pairs) {
|
|
2437
|
-
return runIdentityMutation(
|
|
2438
|
-
|
|
2439
|
-
|
|
2440
|
-
|
|
3009
|
+
return runIdentityMutation(ctx, (target, touch) => {
|
|
3010
|
+
if (!pairs.some((pair) => hasExplicitIdentityValidityWindow(pair))) {
|
|
3011
|
+
return bulkAssertPairs(ctx, target, "same", pairs, touch);
|
|
3012
|
+
}
|
|
3013
|
+
return bulkAssertWindowedPairs(
|
|
3014
|
+
ctx,
|
|
3015
|
+
target,
|
|
3016
|
+
"same",
|
|
3017
|
+
pairs,
|
|
3018
|
+
touch,
|
|
3019
|
+
nowIso()
|
|
3020
|
+
);
|
|
3021
|
+
});
|
|
2441
3022
|
},
|
|
2442
3023
|
bulkAssertDifferent(pairs) {
|
|
2443
|
-
return runIdentityMutation(
|
|
2444
|
-
|
|
2445
|
-
|
|
2446
|
-
|
|
3024
|
+
return runIdentityMutation(ctx, (target, touch) => {
|
|
3025
|
+
if (!pairs.some((pair) => hasExplicitIdentityValidityWindow(pair))) {
|
|
3026
|
+
return bulkAssertPairs(ctx, target, "different", pairs, touch);
|
|
3027
|
+
}
|
|
3028
|
+
return bulkAssertWindowedPairs(
|
|
3029
|
+
ctx,
|
|
3030
|
+
target,
|
|
3031
|
+
"different",
|
|
3032
|
+
pairs,
|
|
3033
|
+
touch,
|
|
3034
|
+
nowIso()
|
|
3035
|
+
);
|
|
3036
|
+
});
|
|
2447
3037
|
},
|
|
2448
3038
|
retractAssertion(id) {
|
|
2449
3039
|
return runIdentityMutation(ctx, async (target, touch) => {
|
|
@@ -2560,7 +3150,7 @@ function transferShapeError(assertion, message, issue) {
|
|
|
2560
3150
|
]
|
|
2561
3151
|
});
|
|
2562
3152
|
}
|
|
2563
|
-
function validateTransferShape(ctx, assertion, mode) {
|
|
3153
|
+
function validateTransferShape(ctx, assertion, mode, operationInstant) {
|
|
2564
3154
|
if (!ctx.registry.nodeKinds.has(assertion.a.kind) || !ctx.registry.nodeKinds.has(assertion.b.kind)) {
|
|
2565
3155
|
throw transferShapeError(
|
|
2566
3156
|
assertion,
|
|
@@ -2602,25 +3192,31 @@ function validateTransferShape(ctx, assertion, mode) {
|
|
|
2602
3192
|
}
|
|
2603
3193
|
);
|
|
2604
3194
|
}
|
|
2605
|
-
|
|
2606
|
-
|
|
2607
|
-
|
|
2608
|
-
assertion,
|
|
2609
|
-
"Identity import cannot contain future-dated open assertions.",
|
|
3195
|
+
let window;
|
|
3196
|
+
try {
|
|
3197
|
+
window = resolveIdentityValidityWindow(
|
|
2610
3198
|
{
|
|
2611
|
-
|
|
2612
|
-
|
|
2613
|
-
}
|
|
3199
|
+
validFrom: assertion.validFrom,
|
|
3200
|
+
...assertion.validTo === void 0 ? {} : { validTo: assertion.validTo }
|
|
3201
|
+
},
|
|
3202
|
+
operationInstant
|
|
2614
3203
|
);
|
|
2615
|
-
}
|
|
2616
|
-
|
|
3204
|
+
} catch (error) {
|
|
3205
|
+
if (!(error instanceof IdentityValidityWindowError)) throw error;
|
|
3206
|
+
const issue = error.details.reason === "future-valid-from" ? {
|
|
3207
|
+
code: "IDENTITY_IMPORT_FUTURE_VALID_FROM",
|
|
3208
|
+
message: `Assertion ${assertion.id} validFrom is in the future`
|
|
3209
|
+
} : error.details.reason === "future-valid-to" ? {
|
|
3210
|
+
code: "IDENTITY_IMPORT_FUTURE_VALID_TO",
|
|
3211
|
+
message: `Assertion ${assertion.id} validTo is in the future`
|
|
3212
|
+
} : {
|
|
3213
|
+
code: "IDENTITY_IMPORT_INVALID_WINDOW",
|
|
3214
|
+
message: `Assertion ${assertion.id} validTo must not precede validFrom`
|
|
3215
|
+
};
|
|
2617
3216
|
throw transferShapeError(
|
|
2618
3217
|
assertion,
|
|
2619
|
-
"Identity
|
|
2620
|
-
|
|
2621
|
-
message: `Assertion ${assertion.id} validTo must not precede validFrom`,
|
|
2622
|
-
code: "IDENTITY_IMPORT_INVALID_WINDOW"
|
|
2623
|
-
}
|
|
3218
|
+
"Identity import contains an unsupported validity window.",
|
|
3219
|
+
issue
|
|
2624
3220
|
);
|
|
2625
3221
|
}
|
|
2626
3222
|
if (assertion.endedBy !== void 0) {
|
|
@@ -2646,17 +3242,7 @@ function validateTransferShape(ctx, assertion, mode) {
|
|
|
2646
3242
|
);
|
|
2647
3243
|
}
|
|
2648
3244
|
}
|
|
2649
|
-
|
|
2650
|
-
throw transferShapeError(
|
|
2651
|
-
assertion,
|
|
2652
|
-
"Identity import cannot contain assertions that end in the future.",
|
|
2653
|
-
{
|
|
2654
|
-
message: `Assertion ${assertion.id} validTo is in the future`,
|
|
2655
|
-
code: "IDENTITY_IMPORT_FUTURE_VALID_TO"
|
|
2656
|
-
}
|
|
2657
|
-
);
|
|
2658
|
-
}
|
|
2659
|
-
return normalized;
|
|
3245
|
+
return { endpoints: normalized, window };
|
|
2660
3246
|
}
|
|
2661
3247
|
var IDENTITY_IMPORT_FAILED_ASSERTION = /* @__PURE__ */ Symbol(
|
|
2662
3248
|
"typegraph.identity.failedAssertionId"
|
|
@@ -2679,13 +3265,14 @@ function rethrowTaggedWithAssertion(error, assertionId, progress) {
|
|
|
2679
3265
|
}
|
|
2680
3266
|
throw error;
|
|
2681
3267
|
}
|
|
2682
|
-
async function importIdentityAssertionsIntoTarget(ctx, target, assertions, mode) {
|
|
3268
|
+
async function importIdentityAssertionsIntoTarget(ctx, target, assertions, mode, ignoredAssertionIds = /* @__PURE__ */ new Set()) {
|
|
2683
3269
|
let created = 0;
|
|
2684
3270
|
let skipped = 0;
|
|
2685
3271
|
await withRecordedIdentityMutationTarget(target, async (rawTarget, touch) => {
|
|
3272
|
+
const operationInstant = nowIso();
|
|
2686
3273
|
const normalized = assertions.map((assertion) => ({
|
|
2687
3274
|
assertion,
|
|
2688
|
-
|
|
3275
|
+
...validateTransferShape(ctx, assertion, mode, operationInstant)
|
|
2689
3276
|
}));
|
|
2690
3277
|
const existingById = await loadAssertionsByIds(
|
|
2691
3278
|
rawTarget,
|
|
@@ -2740,7 +3327,17 @@ async function importIdentityAssertionsIntoTarget(ctx, target, assertions, mode)
|
|
|
2740
3327
|
} catch (error) {
|
|
2741
3328
|
attributeMissingEndpoint(error, true);
|
|
2742
3329
|
}
|
|
2743
|
-
|
|
3330
|
+
const windowValidator = await createIdentityWindowValidator(
|
|
3331
|
+
ctx,
|
|
3332
|
+
rawTarget,
|
|
3333
|
+
normalized.map(({ endpoints, window }) => ({
|
|
3334
|
+
references: endpoints,
|
|
3335
|
+
window
|
|
3336
|
+
})),
|
|
3337
|
+
operationInstant,
|
|
3338
|
+
ignoredAssertionIds
|
|
3339
|
+
);
|
|
3340
|
+
for (const { assertion, endpoints, window } of normalized) {
|
|
2744
3341
|
const [a, b] = endpoints;
|
|
2745
3342
|
try {
|
|
2746
3343
|
const sameId = existingById.get(assertion.id);
|
|
@@ -2759,73 +3356,102 @@ async function importIdentityAssertionsIntoTarget(ctx, target, assertions, mode)
|
|
|
2759
3356
|
}
|
|
2760
3357
|
);
|
|
2761
3358
|
}
|
|
2762
|
-
|
|
2763
|
-
const timestamp = assertion.validFrom;
|
|
2764
|
-
const row = {
|
|
2765
|
-
graph_id: ctx.graphId,
|
|
2766
|
-
id: assertion.id,
|
|
2767
|
-
rel: assertion.relation,
|
|
2768
|
-
a_kind: a.kind,
|
|
2769
|
-
a_id: a.id,
|
|
2770
|
-
b_kind: b.kind,
|
|
2771
|
-
b_id: b.id,
|
|
2772
|
-
valid_from: assertion.validFrom,
|
|
2773
|
-
valid_to: assertion.validTo,
|
|
2774
|
-
created_at: timestamp,
|
|
2775
|
-
updated_at: assertion.validTo,
|
|
2776
|
-
deleted_at: void 0,
|
|
2777
|
-
ended_by_kind: assertion.endedBy?.kind,
|
|
2778
|
-
ended_by_id: assertion.endedBy?.id
|
|
2779
|
-
};
|
|
2780
|
-
await insertAssertionRows(rawTarget, ctx.schema, [row]);
|
|
2781
|
-
touch(ctx.graphId, row.id, row);
|
|
2782
|
-
existingById.set(row.id, row);
|
|
2783
|
-
created += 1;
|
|
2784
|
-
continue;
|
|
2785
|
-
}
|
|
2786
|
-
const existing = await currentAssertionForPair(
|
|
3359
|
+
const exactWindow = await assertionForExactWindow(
|
|
2787
3360
|
rawTarget,
|
|
2788
3361
|
ctx.schema,
|
|
2789
3362
|
ctx.graphId,
|
|
2790
3363
|
assertion.relation,
|
|
2791
3364
|
a,
|
|
2792
|
-
b
|
|
3365
|
+
b,
|
|
3366
|
+
window
|
|
2793
3367
|
);
|
|
2794
|
-
if (
|
|
3368
|
+
if (exactWindow !== void 0) {
|
|
2795
3369
|
skipped += 1;
|
|
2796
3370
|
continue;
|
|
2797
3371
|
}
|
|
2798
|
-
|
|
2799
|
-
|
|
2800
|
-
|
|
2801
|
-
|
|
2802
|
-
|
|
2803
|
-
|
|
2804
|
-
|
|
2805
|
-
|
|
2806
|
-
|
|
2807
|
-
|
|
2808
|
-
|
|
2809
|
-
|
|
2810
|
-
|
|
2811
|
-
|
|
2812
|
-
|
|
2813
|
-
|
|
2814
|
-
|
|
2815
|
-
|
|
2816
|
-
|
|
2817
|
-
|
|
2818
|
-
|
|
2819
|
-
|
|
2820
|
-
|
|
2821
|
-
|
|
2822
|
-
|
|
3372
|
+
if (window.effective === "current") {
|
|
3373
|
+
const current = await currentAssertionForPair(
|
|
3374
|
+
rawTarget,
|
|
3375
|
+
ctx.schema,
|
|
3376
|
+
ctx.graphId,
|
|
3377
|
+
assertion.relation,
|
|
3378
|
+
a,
|
|
3379
|
+
b
|
|
3380
|
+
);
|
|
3381
|
+
if (current !== void 0) {
|
|
3382
|
+
skipped += 1;
|
|
3383
|
+
continue;
|
|
3384
|
+
}
|
|
3385
|
+
await requireEndpointsCoverIdentityWindow(
|
|
3386
|
+
rawTarget,
|
|
3387
|
+
ctx.graphId,
|
|
3388
|
+
[a, b],
|
|
3389
|
+
window
|
|
3390
|
+
);
|
|
3391
|
+
windowValidator.validate(assertion.relation, "import", a, b, window);
|
|
3392
|
+
await validateCurrentRelation(
|
|
3393
|
+
ctx,
|
|
3394
|
+
rawTarget,
|
|
3395
|
+
assertion.relation,
|
|
3396
|
+
"import",
|
|
3397
|
+
a,
|
|
3398
|
+
b
|
|
3399
|
+
);
|
|
3400
|
+
const inserted = await insertAssertion(
|
|
2823
3401
|
rawTarget,
|
|
2824
3402
|
ctx.schema,
|
|
2825
3403
|
ctx.graphId,
|
|
2826
|
-
|
|
3404
|
+
assertion.relation,
|
|
3405
|
+
a,
|
|
3406
|
+
b,
|
|
3407
|
+
operationInstant,
|
|
3408
|
+
touch,
|
|
3409
|
+
{ id: assertion.id, validFrom: window.validFrom }
|
|
2827
3410
|
);
|
|
3411
|
+
existingById.set(inserted.id, inserted);
|
|
3412
|
+
windowValidator.record(inserted);
|
|
3413
|
+
created += 1;
|
|
3414
|
+
if (assertion.relation === "same") {
|
|
3415
|
+
await mergeCurrentClasses(rawTarget, ctx.schema, ctx.graphId, a, b);
|
|
3416
|
+
} else {
|
|
3417
|
+
await replaceSeparationForReferences(
|
|
3418
|
+
rawTarget,
|
|
3419
|
+
ctx.schema,
|
|
3420
|
+
ctx.graphId,
|
|
3421
|
+
[a, b]
|
|
3422
|
+
);
|
|
3423
|
+
}
|
|
3424
|
+
continue;
|
|
2828
3425
|
}
|
|
3426
|
+
await requireEndpointsCoverIdentityWindow(
|
|
3427
|
+
rawTarget,
|
|
3428
|
+
ctx.graphId,
|
|
3429
|
+
[a, b],
|
|
3430
|
+
window
|
|
3431
|
+
);
|
|
3432
|
+
windowValidator.validate(assertion.relation, "import", a, b, window);
|
|
3433
|
+
const timestamp = window.validFrom;
|
|
3434
|
+
const row = {
|
|
3435
|
+
graph_id: ctx.graphId,
|
|
3436
|
+
id: assertion.id,
|
|
3437
|
+
rel: assertion.relation,
|
|
3438
|
+
a_kind: a.kind,
|
|
3439
|
+
a_id: a.id,
|
|
3440
|
+
b_kind: b.kind,
|
|
3441
|
+
b_id: b.id,
|
|
3442
|
+
valid_from: window.validFrom,
|
|
3443
|
+
valid_to: window.validTo,
|
|
3444
|
+
created_at: timestamp,
|
|
3445
|
+
updated_at: window.validTo ?? window.validFrom,
|
|
3446
|
+
deleted_at: void 0,
|
|
3447
|
+
ended_by_kind: assertion.endedBy?.kind,
|
|
3448
|
+
ended_by_id: assertion.endedBy?.id
|
|
3449
|
+
};
|
|
3450
|
+
await insertAssertionRows(rawTarget, ctx.schema, [row]);
|
|
3451
|
+
touch(ctx.graphId, row.id, row);
|
|
3452
|
+
existingById.set(row.id, row);
|
|
3453
|
+
windowValidator.record(row);
|
|
3454
|
+
created += 1;
|
|
2829
3455
|
} catch (error) {
|
|
2830
3456
|
rethrowTaggedWithAssertion(error, assertion.id, { created, skipped });
|
|
2831
3457
|
}
|
|
@@ -2833,12 +3459,17 @@ async function importIdentityAssertionsIntoTarget(ctx, target, assertions, mode)
|
|
|
2833
3459
|
});
|
|
2834
3460
|
return { created, skipped };
|
|
2835
3461
|
}
|
|
2836
|
-
async function applyIdentityChangesForContext(ctx,
|
|
2837
|
-
if (
|
|
3462
|
+
async function applyIdentityChangesForContext(ctx, retractions, assertions) {
|
|
3463
|
+
if (retractions.length === 0 && assertions.length === 0) {
|
|
2838
3464
|
return { created: 0, retracted: 0 };
|
|
2839
3465
|
}
|
|
2840
3466
|
return runIdentityMutation(ctx, async (target, touch, markWritten) => {
|
|
2841
|
-
const retracted = await
|
|
3467
|
+
const retracted = await retractPlannedAssertions(
|
|
3468
|
+
ctx,
|
|
3469
|
+
target,
|
|
3470
|
+
retractions,
|
|
3471
|
+
touch
|
|
3472
|
+
);
|
|
2842
3473
|
const { closureReferences, separationReferences } = partitionRetractedEndpoints(retracted);
|
|
2843
3474
|
if (closureReferences.length > 0) {
|
|
2844
3475
|
await replaceAffectedClosure(
|
|
@@ -2859,7 +3490,8 @@ async function applyIdentityChangesForContext(ctx, retractionIds, assertions) {
|
|
|
2859
3490
|
ctx,
|
|
2860
3491
|
target,
|
|
2861
3492
|
assertions,
|
|
2862
|
-
"
|
|
3493
|
+
"archival",
|
|
3494
|
+
new Set(retracted.map((assertion) => assertion.id))
|
|
2863
3495
|
);
|
|
2864
3496
|
if (summary.created > 0) markWritten();
|
|
2865
3497
|
return { created: summary.created, retracted: retracted.length };
|
|
@@ -3310,6 +3942,34 @@ async function readNodeDeletionInstant(target, schema, graphId, ref) {
|
|
|
3310
3942
|
const row = rows.at(0);
|
|
3311
3943
|
return row === void 0 ? void 0 : optionalIdentityTimestamp(row.deleted_at);
|
|
3312
3944
|
}
|
|
3945
|
+
async function requireNodeValidityEndCompatible(ctx, target, ref, validTo) {
|
|
3946
|
+
const rows = await target.execute(
|
|
3947
|
+
asCompiledRowsSql(sql`
|
|
3948
|
+
SELECT ${IDENTITY_ASSERTION_COLUMNS}
|
|
3949
|
+
FROM ${ctx.schema.identityAssertionsTable}
|
|
3950
|
+
WHERE graph_id = ${ctx.graphId}
|
|
3951
|
+
AND deleted_at IS NULL
|
|
3952
|
+
AND (valid_to IS NULL OR valid_to > ${validTo})
|
|
3953
|
+
AND (
|
|
3954
|
+
(a_kind = ${ref.kind} AND a_id = ${ref.id})
|
|
3955
|
+
OR (b_kind = ${ref.kind} AND b_id = ${ref.id})
|
|
3956
|
+
)
|
|
3957
|
+
ORDER BY id
|
|
3958
|
+
LIMIT 1
|
|
3959
|
+
`)
|
|
3960
|
+
);
|
|
3961
|
+
const row = rows.at(0);
|
|
3962
|
+
if (row === void 0) return;
|
|
3963
|
+
const assertion = normalizeIdentityAssertionRow(row);
|
|
3964
|
+
throw new IdentityEndpointValidityError({
|
|
3965
|
+
endpoint: ref,
|
|
3966
|
+
assertionWindow: {
|
|
3967
|
+
validFrom: assertion.valid_from,
|
|
3968
|
+
...assertion.valid_to === void 0 ? {} : { validTo: assertion.valid_to }
|
|
3969
|
+
},
|
|
3970
|
+
endpointWindow: { validTo }
|
|
3971
|
+
});
|
|
3972
|
+
}
|
|
3313
3973
|
async function detachIdentityForNode(ctx, target, ref, mode) {
|
|
3314
3974
|
await lockIdentityGraph(target, ctx.graphId);
|
|
3315
3975
|
await withRecordedIdentityMutationTarget(target, async (rawTarget, touch) => {
|
|
@@ -3388,6 +4048,6 @@ async function detachIdentityForNode(ctx, target, ref, mode) {
|
|
|
3388
4048
|
});
|
|
3389
4049
|
}
|
|
3390
4050
|
|
|
3391
|
-
export { IDENTITY_IMPORT_FAILED_ASSERTION, IDENTITY_IMPORT_PROGRESS, applyIdentityChangesForContext, assertAffectedIdentityClassesConsistent, createIdentityFacade, createIdentityReadFacade, createValidationError, deleteAssertionsTouchingKinds, detachIdentityForNode, encodeTupleKey, foldIdentityForCreatedNodes, hasAssertionsTouchingKinds, identityAssertionSemanticKey, identityReferenceKey, importIdentityAssertionsIntoTarget, liveNodeKindsSharingIds, loadAssertionsByIds, loadCurrentStructuralClasses, lockIdentityEnablementNodes, lockIdentityGraph, lockSchemaVersionForStoreWrite, normalizeIdentityPair, purgeAssertionsWithUnregisteredKinds, readIdentityAssertionPageAtTarget, readIdentityAssertionsForInterchange, rebuildIdentityClosureForContext, refKey, removeIdentityKindsForContext, runHookedWriteOperation, runInWriteTransaction, separationRebuildRequired, toTransferAssertion, validateEdgeProps, validateIdentityForContext, validateNodeProps, validateProps, withWriteTransactionSession, wrapZodError };
|
|
3392
|
-
//# sourceMappingURL=chunk-
|
|
3393
|
-
//# sourceMappingURL=chunk-
|
|
4051
|
+
export { IDENTITY_IMPORT_FAILED_ASSERTION, IDENTITY_IMPORT_PROGRESS, applyIdentityChangesForContext, assertAffectedIdentityClassesConsistent, createIdentityFacade, createIdentityReadFacade, createValidationError, deleteAssertionsTouchingKinds, detachIdentityForNode, encodeTupleKey, foldIdentityForCreatedNodes, forceWriteTransactionRevision, hasAssertionsTouchingKinds, identityAssertionSemanticKey, identityReferenceKey, identityValidityWindowsOverlap, importIdentityAssertionsIntoTarget, liveNodeKindsSharingIds, loadAssertionsByIds, loadCurrentStructuralClasses, lockIdentityEnablementNodes, lockIdentityGraph, lockSchemaVersionForStoreWrite, normalizeIdentityPair, purgeAssertionsWithUnregisteredKinds, readIdentityAssertionPageAtTarget, readIdentityAssertionsForInterchange, rebuildIdentityClosureForContext, refKey, removeIdentityKindsForContext, requireNodeValidityEndCompatible, runHookedWriteOperation, runInWriteTransaction, separationRebuildRequired, toTransferAssertion, validateEdgeProps, validateIdentityForContext, validateNodeProps, validateProps, withWriteTransactionSession, wrapZodError };
|
|
4052
|
+
//# sourceMappingURL=chunk-NNQ6A3RM.js.map
|
|
4053
|
+
//# sourceMappingURL=chunk-NNQ6A3RM.js.map
|