@nicia-ai/typegraph 0.65.0 → 0.66.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +33 -0
- package/dist/{atomic-mutation-program-BznZQ06C.d.ts → atomic-mutation-program-BhP75Qn0.d.ts} +1 -1
- package/dist/{atomic-mutation-program-Bfu5z-je.d.cts → atomic-mutation-program-DMdmc4s0.d.cts} +1 -1
- package/dist/backend/drizzle/engine/index.cjs +13 -13
- package/dist/backend/drizzle/engine/index.d.cts +9 -9
- package/dist/backend/drizzle/engine/index.d.ts +9 -9
- package/dist/backend/drizzle/engine/index.js +8 -8
- package/dist/backend/drizzle/indexes.d.cts +1 -1
- package/dist/backend/drizzle/indexes.d.ts +1 -1
- package/dist/backend/index.cjs +91 -91
- package/dist/backend/index.d.cts +7 -7
- package/dist/backend/index.d.ts +7 -7
- package/dist/backend/index.js +8 -8
- package/dist/backend/postgres/index.cjs +23 -23
- package/dist/backend/postgres/index.d.cts +8 -8
- package/dist/backend/postgres/index.d.ts +8 -8
- package/dist/backend/postgres/index.js +8 -8
- package/dist/backend/postgres/pglite-store.cjs +1 -1
- package/dist/backend/postgres/pglite-store.d.cts +6 -6
- package/dist/backend/postgres/pglite-store.d.ts +6 -6
- package/dist/backend/postgres/pglite-store.js +1 -1
- package/dist/backend/postgres/pglite.cjs +10 -10
- package/dist/backend/postgres/pglite.d.cts +3 -3
- package/dist/backend/postgres/pglite.d.ts +3 -3
- package/dist/backend/postgres/pglite.js +9 -9
- package/dist/backend/sqlite/index.cjs +21 -21
- package/dist/backend/sqlite/index.d.cts +7 -7
- package/dist/backend/sqlite/index.d.ts +7 -7
- package/dist/backend/sqlite/index.js +8 -8
- package/dist/backend/sqlite/libsql.cjs +14 -14
- package/dist/backend/sqlite/libsql.d.cts +3 -3
- package/dist/backend/sqlite/libsql.d.ts +3 -3
- package/dist/backend/sqlite/libsql.js +8 -8
- package/dist/backend/sqlite/local-store.cjs +1 -1
- package/dist/backend/sqlite/local-store.d.cts +6 -6
- package/dist/backend/sqlite/local-store.d.ts +6 -6
- package/dist/backend/sqlite/local-store.js +1 -1
- package/dist/backend/sqlite/local.cjs +10 -10
- package/dist/backend/sqlite/local.d.cts +3 -3
- package/dist/backend/sqlite/local.d.ts +3 -3
- package/dist/backend/sqlite/local.js +9 -9
- package/dist/{chunk-PFXNQFFY.js → chunk-2DJKHZQ4.js} +75 -8
- package/dist/chunk-2DJKHZQ4.js.map +1 -0
- package/dist/{chunk-337ONI2I.js → chunk-3SUZXB5X.js} +146 -80
- package/dist/chunk-3SUZXB5X.js.map +1 -0
- package/dist/{chunk-4VTCIEK3.js → chunk-4TQOIBWH.js} +3 -3
- package/dist/{chunk-4VTCIEK3.js.map → chunk-4TQOIBWH.js.map} +1 -1
- package/dist/{chunk-JRWKRBI5.cjs → chunk-5JOCIMQ3.cjs} +6 -6
- package/dist/{chunk-JRWKRBI5.cjs.map → chunk-5JOCIMQ3.cjs.map} +1 -1
- package/dist/{chunk-BWQA3POT.cjs → chunk-6B3LQUYG.cjs} +206 -138
- package/dist/chunk-6B3LQUYG.cjs.map +1 -0
- package/dist/{chunk-RQPCUHIH.js → chunk-6ECNYQDW.js} +3 -3
- package/dist/{chunk-RQPCUHIH.js.map → chunk-6ECNYQDW.js.map} +1 -1
- package/dist/{chunk-OLB75LRQ.js → chunk-6GKKAQMW.js} +5 -5
- package/dist/{chunk-OLB75LRQ.js.map → chunk-6GKKAQMW.js.map} +1 -1
- package/dist/{chunk-OC5ROP7V.cjs → chunk-6JRVV2SS.cjs} +8 -2
- package/dist/chunk-6JRVV2SS.cjs.map +1 -0
- package/dist/{chunk-DSX3P4S5.cjs → chunk-76OB5RSH.cjs} +6 -6
- package/dist/{chunk-DSX3P4S5.cjs.map → chunk-76OB5RSH.cjs.map} +1 -1
- package/dist/{chunk-DHRLOQLQ.cjs → chunk-7LQTDGV5.cjs} +11 -11
- package/dist/{chunk-DHRLOQLQ.cjs.map → chunk-7LQTDGV5.cjs.map} +1 -1
- package/dist/{chunk-Q25QYSOH.js → chunk-7YJHUY4T.js} +9 -9
- package/dist/{chunk-Q25QYSOH.js.map → chunk-7YJHUY4T.js.map} +1 -1
- package/dist/{chunk-JERQGJKG.cjs → chunk-ANMCKLZQ.cjs} +18 -18
- package/dist/{chunk-JERQGJKG.cjs.map → chunk-ANMCKLZQ.cjs.map} +1 -1
- package/dist/{chunk-BBOMNH44.js → chunk-BABP4D5B.js} +3 -3
- package/dist/{chunk-BBOMNH44.js.map → chunk-BABP4D5B.js.map} +1 -1
- package/dist/{chunk-EVGZ2TRQ.js → chunk-BE75G3M5.js} +3 -3
- package/dist/{chunk-EVGZ2TRQ.js.map → chunk-BE75G3M5.js.map} +1 -1
- package/dist/{chunk-FXGZT3WO.cjs → chunk-BX42F7IJ.cjs} +41 -41
- package/dist/{chunk-FXGZT3WO.cjs.map → chunk-BX42F7IJ.cjs.map} +1 -1
- package/dist/{chunk-G6T23JU7.js → chunk-CDKNGCE7.js} +3 -3
- package/dist/{chunk-G6T23JU7.js.map → chunk-CDKNGCE7.js.map} +1 -1
- package/dist/{chunk-BNTJ5YFO.cjs → chunk-EACDHXJL.cjs} +4 -4
- package/dist/{chunk-BNTJ5YFO.cjs.map → chunk-EACDHXJL.cjs.map} +1 -1
- package/dist/{chunk-SNDJUTMB.cjs → chunk-EBQX7MYL.cjs} +72 -72
- package/dist/{chunk-SNDJUTMB.cjs.map → chunk-EBQX7MYL.cjs.map} +1 -1
- package/dist/{chunk-GKSAEUX6.js → chunk-FXOFJ4FS.js} +7 -7
- package/dist/{chunk-GKSAEUX6.js.map → chunk-FXOFJ4FS.js.map} +1 -1
- package/dist/{chunk-ZOWRACZQ.cjs → chunk-G7OKJDMG.cjs} +5 -5
- package/dist/{chunk-ZOWRACZQ.cjs.map → chunk-G7OKJDMG.cjs.map} +1 -1
- package/dist/{chunk-MKJPBSID.cjs → chunk-I7SBZJI2.cjs} +4 -4
- package/dist/{chunk-MKJPBSID.cjs.map → chunk-I7SBZJI2.cjs.map} +1 -1
- package/dist/{chunk-H346QK3V.cjs → chunk-K7YACILO.cjs} +9 -9
- package/dist/{chunk-H346QK3V.cjs.map → chunk-K7YACILO.cjs.map} +1 -1
- package/dist/{chunk-3KWF25MF.cjs → chunk-MN325MG4.cjs} +313 -246
- package/dist/chunk-MN325MG4.cjs.map +1 -0
- package/dist/{chunk-KDNRACRG.cjs → chunk-MRUOOAIQ.cjs} +4 -4
- package/dist/{chunk-KDNRACRG.cjs.map → chunk-MRUOOAIQ.cjs.map} +1 -1
- package/dist/{chunk-HTSJTWUT.js → chunk-OF63ZHSD.js} +4 -4
- package/dist/{chunk-HTSJTWUT.js.map → chunk-OF63ZHSD.js.map} +1 -1
- package/dist/{chunk-NGA3THGU.cjs → chunk-QR7W37HG.cjs} +14 -14
- package/dist/{chunk-NGA3THGU.cjs.map → chunk-QR7W37HG.cjs.map} +1 -1
- package/dist/{chunk-QFEO4M5W.js → chunk-RTPMG6LQ.js} +11 -11
- package/dist/{chunk-QFEO4M5W.js.map → chunk-RTPMG6LQ.js.map} +1 -1
- package/dist/{chunk-PFD4NUYV.js → chunk-SSDHR2C2.js} +3 -3
- package/dist/{chunk-PFD4NUYV.js.map → chunk-SSDHR2C2.js.map} +1 -1
- package/dist/{chunk-THK3SCQA.js → chunk-SYXTWPX6.js} +5 -5
- package/dist/{chunk-THK3SCQA.js.map → chunk-SYXTWPX6.js.map} +1 -1
- package/dist/{chunk-XSLQYGNR.cjs → chunk-T3VU3YRQ.cjs} +69 -69
- package/dist/{chunk-XSLQYGNR.cjs.map → chunk-T3VU3YRQ.cjs.map} +1 -1
- package/dist/{chunk-MIBWA6HX.js → chunk-TR7QTODF.js} +213 -33
- package/dist/chunk-TR7QTODF.js.map +1 -0
- package/dist/{chunk-AD3NLSV5.js → chunk-TU22BFMP.js} +8 -2
- package/dist/chunk-TU22BFMP.js.map +1 -0
- package/dist/{chunk-WTMSUIRO.js → chunk-UFKYMQJ5.js} +3 -3
- package/dist/{chunk-WTMSUIRO.js.map → chunk-UFKYMQJ5.js.map} +1 -1
- package/dist/{chunk-35LDKSMM.cjs → chunk-VNJMM2QQ.cjs} +30 -30
- package/dist/{chunk-35LDKSMM.cjs.map → chunk-VNJMM2QQ.cjs.map} +1 -1
- package/dist/{chunk-53ZEBIMD.js → chunk-WB55URNM.js} +6 -6
- package/dist/{chunk-53ZEBIMD.js.map → chunk-WB55URNM.js.map} +1 -1
- package/dist/{chunk-L2GBVYRU.cjs → chunk-WWSYGZED.cjs} +11 -11
- package/dist/{chunk-L2GBVYRU.cjs.map → chunk-WWSYGZED.cjs.map} +1 -1
- package/dist/{chunk-D2JPOFRZ.cjs → chunk-WY3IFEKV.cjs} +191 -191
- package/dist/{chunk-D2JPOFRZ.cjs.map → chunk-WY3IFEKV.cjs.map} +1 -1
- package/dist/{chunk-3RSFLZ7A.cjs → chunk-Y4X6ODVY.cjs} +943 -763
- package/dist/chunk-Y4X6ODVY.cjs.map +1 -0
- package/dist/{chunk-VZRXXABW.js → chunk-YHMXF7OZ.js} +5 -5
- package/dist/{chunk-VZRXXABW.js.map → chunk-YHMXF7OZ.js.map} +1 -1
- package/dist/{chunk-VROJKWZ7.js → chunk-ZONDBN6H.js} +5 -5
- package/dist/{chunk-VROJKWZ7.js.map → chunk-ZONDBN6H.js.map} +1 -1
- package/dist/core/index.d.cts +3 -3
- package/dist/core/index.d.ts +3 -3
- package/dist/{ddl-DvW9aobX.d.ts → ddl-2q7xLM1X.d.ts} +3 -3
- package/dist/{ddl-BjuXbPfw.d.cts → ddl-D_09BfbN.d.cts} +3 -3
- package/dist/graph-extension/index.d.cts +2 -2
- package/dist/graph-extension/index.d.ts +2 -2
- package/dist/graph-merge/index.cjs +156 -156
- package/dist/graph-merge/index.d.cts +7 -7
- package/dist/graph-merge/index.d.ts +7 -7
- package/dist/graph-merge/index.js +14 -14
- package/dist/{graph-templates-1vMqlPsu.d.cts → graph-templates-B5Q7oYAA.d.cts} +2 -2
- package/dist/{graph-templates-Y52w16dH.d.ts → graph-templates-D9N-Z9kw.d.ts} +2 -2
- package/dist/index.cjs +99 -99
- package/dist/index.d.cts +10 -10
- package/dist/index.d.ts +10 -10
- package/dist/index.js +18 -18
- package/dist/indexes/index.d.cts +4 -4
- package/dist/indexes/index.d.ts +4 -4
- package/dist/{ingestion-import-target-CCKeXZbW.d.ts → ingestion-import-target-B8EU6ug2.d.ts} +1 -1
- package/dist/{ingestion-import-target-774QRgkF.d.cts → ingestion-import-target-C5sHNFJF.d.cts} +1 -1
- package/dist/interchange/index.cjs +34 -34
- package/dist/interchange/index.d.cts +7 -7
- package/dist/interchange/index.d.ts +7 -7
- package/dist/interchange/index.js +11 -11
- package/dist/{local-store-impl-DFKS7QTV.js → local-store-impl-ERPNYOCL.js} +18 -18
- package/dist/{local-store-impl-DFKS7QTV.js.map → local-store-impl-ERPNYOCL.js.map} +1 -1
- package/dist/{local-store-impl-3E4VLFCI.cjs → local-store-impl-OUINMCYI.cjs} +22 -22
- package/dist/{local-store-impl-3E4VLFCI.cjs.map → local-store-impl-OUINMCYI.cjs.map} +1 -1
- package/dist/{pglite-store-impl-N63GGBU2.js → pglite-store-impl-DUJBQZS5.js} +18 -18
- package/dist/{pglite-store-impl-N63GGBU2.js.map → pglite-store-impl-DUJBQZS5.js.map} +1 -1
- package/dist/{pglite-store-impl-T75O3LVQ.cjs → pglite-store-impl-Z3SOOP75.cjs} +22 -22
- package/dist/{pglite-store-impl-T75O3LVQ.cjs.map → pglite-store-impl-Z3SOOP75.cjs.map} +1 -1
- package/dist/{postgres-C9gitL71.d.ts → postgres-BbTYW3b_.d.ts} +3 -3
- package/dist/{postgres-BONrXHb4.d.cts → postgres-DOBXcZVg.d.cts} +1 -1
- package/dist/{postgres-DAFRdnTr.d.ts → postgres-DhZixg92.d.ts} +1 -1
- package/dist/{postgres-2FYdVYCm.d.cts → postgres-Dp3MpyJt.d.cts} +3 -3
- package/dist/{profile-CAD65CqS.d.ts → profile-Ch5SSewK.d.ts} +8 -8
- package/dist/{profile-Bmcg07Ki.d.cts → profile-DppApFgt.d.cts} +8 -8
- package/dist/profiler/index.d.cts +8 -8
- package/dist/profiler/index.d.ts +8 -8
- package/dist/provenance/index.cjs +22 -22
- package/dist/provenance/index.d.cts +6 -6
- package/dist/provenance/index.d.ts +6 -6
- package/dist/provenance/index.js +6 -6
- package/dist/{repair-validity-windows-CinP91t7.d.cts → repair-validity-windows-CpP_GpIx.d.cts} +1 -1
- package/dist/{repair-validity-windows-BJz4nffP.d.ts → repair-validity-windows-lfe275bY.d.ts} +1 -1
- package/dist/{resolve-DgOSlXx_.d.ts → resolve-CoYqHqno.d.cts} +7 -2
- package/dist/{resolve-DQXSEN_A.d.cts → resolve-DV0Iposp.d.ts} +7 -2
- package/dist/schema/index.cjs +37 -37
- package/dist/schema/index.d.cts +7 -7
- package/dist/schema/index.d.ts +7 -7
- package/dist/schema/index.js +7 -7
- package/dist/{searchable-DMdCwkXO.d.cts → searchable-C7Xt6g45.d.cts} +1 -1
- package/dist/{searchable-BPRF0Bah.d.ts → searchable-KKXrPet3.d.ts} +1 -1
- package/dist/{sqlite-DgbYa-1Y.d.cts → sqlite-BkQM9ZeI.d.cts} +1 -1
- package/dist/{sqlite-Co_uIpfs.d.cts → sqlite-BpRtjC36.d.cts} +3 -3
- package/dist/{sqlite-DcDAAYow.d.ts → sqlite-CH0Zq0Qv.d.ts} +3 -3
- package/dist/{sqlite-UlG5prJQ.d.ts → sqlite-CcCSeXGg.d.ts} +1 -1
- package/dist/{store-HxoFyQMu.d.cts → store-3nfPQK5j.d.cts} +30 -7
- package/dist/{store-C9T1c9Az.d.ts → store-C8ZPl7OW.d.ts} +30 -7
- package/dist/{types-CRCyg1fJ.d.cts → types-BynPp5kU.d.cts} +18 -2
- package/dist/{types-CRCyg1fJ.d.ts → types-BynPp5kU.d.ts} +18 -2
- package/dist/{types-Dg_prBqC.d.ts → types-C9YwrkSe.d.ts} +1 -1
- package/dist/{types-B5AUesS1.d.cts → types-JG-4CG6P.d.cts} +1 -1
- package/dist/{where-gRyc3jj_.d.cts → where-D1gBDqQ_.d.cts} +1 -1
- package/dist/{where-D-NDKMPw.d.ts → where-D2GqMFp-.d.ts} +1 -1
- package/package.json +1 -1
- package/dist/chunk-337ONI2I.js.map +0 -1
- package/dist/chunk-3KWF25MF.cjs.map +0 -1
- package/dist/chunk-3RSFLZ7A.cjs.map +0 -1
- package/dist/chunk-AD3NLSV5.js.map +0 -1
- package/dist/chunk-BWQA3POT.cjs.map +0 -1
- package/dist/chunk-MIBWA6HX.js.map +0 -1
- package/dist/chunk-OC5ROP7V.cjs.map +0 -1
- package/dist/chunk-PFXNQFFY.js.map +0 -1
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { claimsMembers, isMissingTableError } from './chunk-
|
|
1
|
+
import { claimsMembers, isMissingTableError } from './chunk-TU22BFMP.js';
|
|
2
2
|
import { edgeCardinalityAxis, encodeTupleKey, checkUniqueEdge, checkCardinality, compareClaimTargets } from './chunk-OXJNL2PW.js';
|
|
3
3
|
import { CardinalityError, ConfigurationError } from './chunk-GMKPIYHY.js';
|
|
4
4
|
|
|
@@ -154,5 +154,5 @@ async function purgeEdgeClaims(backend, verdict, graphId, edgeIds) {
|
|
|
154
154
|
}
|
|
155
155
|
|
|
156
156
|
export { EDGE_CARDINALITY_SPECS, claimEdgeCardinality, claimEdgeCardinalityBatch, edgeCardinalityAxesForKind, edgeCardinalityClaim, edgeCardinalityClaimMode, edgeCardinalityClaimRefusal, edgeCardinalityClaimTarget, edgeClaimRelationMissing, purgeEdgeClaims };
|
|
157
|
-
//# sourceMappingURL=chunk-
|
|
158
|
-
//# sourceMappingURL=chunk-
|
|
157
|
+
//# sourceMappingURL=chunk-CDKNGCE7.js.map
|
|
158
|
+
//# sourceMappingURL=chunk-CDKNGCE7.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/store/claims/backing.ts","../src/store/claims/edge-claims.ts"],"names":["outcome"],"mappings":"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","file":"chunk-G6T23JU7.js","sourcesContent":["/**\n * What backs each constraint fence class.\n *\n * A constrained write is fenced by one of two things: a per-graph lock that\n * serializes the probe with the write it guards, or a CLAIM row whose primary\n * key refuses a second claimant outright. The second is strictly stronger — it\n * holds without a lock, which is what an import needs — and this module records\n * which class has reached it, so \"is this fence a lock or a key?\" is answered\n * from one table rather than inferred from whichever module a reader lands in.\n *\n * It also owns the runtime half of the same question — {@link claimSupport},\n * the one reader of \"can THIS object hold a claim?\" — so the declaration and\n * the surface are reconciled in one place rather than at each claim site.\n * `claimSupport` is now a thin binder over the `claims` capability bundle\n * (`backend/capabilities`): the bidirectional declaration/surface cross-check\n * lives once in `resolve.ts`'s `assertClaimsBidirectionalAgreement`, reached\n * through the verdict every caller threads in, and this module owns only the\n * per-write port bind (`claimsMembers`) and this decision's shape.\n */\nimport {\n type BundleBinding,\n claimsMembers,\n} from \"../../backend/capabilities/bind\";\nimport type { CLAIMS } from \"../../backend/capabilities/bundle-registry\";\nimport { type BundleVerdictOf } from \"../../backend/capabilities/resolve\";\nimport { type GraphBackend } from \"../../backend/types\";\n\n/**\n * The runtime extent of the fence classes. {@link ConstraintFenceReason} is\n * DERIVED from it rather than declared beside it: a union type has no runtime\n * extent, so a totality test over a map keyed by the union could only iterate\n * that map's own keys and would be trivially true.\n */\nexport const CONSTRAINT_FENCE_REASONS = [\n \"edgeCardinality\",\n \"edgeMatchKeyConvergence\",\n \"nodeDisjointness\",\n \"nodeUniquenessClaim\",\n \"nodeUniquenessScope\",\n] as const;\n\n/**\n * WHICH declared constraint makes a write constrained.\n *\n * The classification names the reason rather than answering yes/no, because\n * the reason is load-bearing twice over: it is what the fence is taken FOR, and\n * — on a backend that cannot hold the fence — it is what the refusal has to\n * tell the caller. \"This backend cannot fence constrained writes\" is unusable\n * advice; \"your `cardinality: 'one'` edge cannot be enforced here\" is\n * actionable, and only the classifier knows which it was.\n */\nexport type ConstraintFenceReason = (typeof CONSTRAINT_FENCE_REASONS)[number];\n\n/** The relation whose key fences a class, or `lockOnly` when nothing does yet. */\ntype ConstraintFenceBacking = \"uniques\" | \"edgeClaims\" | \"lockOnly\";\n\n/**\n * Which claim relation backs each fence class. The `satisfies` forces totality:\n * a new reason cannot be added without stating what backs it.\n *\n * `nodeUniquenessScope` is `\"uniques\"` because a shared-scope claim is now\n * written at the scope's axis, so two writers of two kinds in one hierarchy\n * contend for one row. `nodeUniquenessClaim` is the same relation seen from the\n * other side: the claim row is the fence, and the class exists because a write\n * that must issue it BEFORE the row it gates needs a transaction to undo the\n * pair together — which is what its refusal names. `nodeDisjointness` is the\n * same relation again, at a third kind of axis: a claim keyed on the declared\n * PAIR and on the node's id, which is the axis disjointness actually declares\n * and the one the nodes primary key `(graph_id, kind, id)` cannot fence.\n * `edgeCardinality` is the other relation: a claim keyed on\n * `(<cardinality>:<edgeKind>, endpoint identity)`, which is the axis the\n * declaration actually spans and the one the edges primary key `(graph_id, id)`\n * cannot fence. The classes still marked `lockOnly` are fenced by the per-graph\n * write lock alone, which is why they are also the classes a non-transactional\n * backend refuses.\n */\nexport const CONSTRAINT_FENCE_BACKING = {\n edgeCardinality: \"edgeClaims\",\n edgeMatchKeyConvergence: \"lockOnly\",\n nodeDisjointness: \"uniques\",\n nodeUniquenessClaim: \"uniques\",\n nodeUniquenessScope: \"uniques\",\n} as const satisfies Record<ConstraintFenceReason, ConstraintFenceBacking>;\n\n/** The decision {@link claimSupport} returns — never a flag a caller re-derives. */\nexport type ClaimSupport =\n /** Capability declared AND every claim member present: the members, bound off the port. */\n | Readonly<{\n supported: true;\n claims: BundleBinding<(typeof CLAIMS)[\"core\"][number]>;\n }>\n /** Capability absent or false AND no claim member present: the declared gap. */\n | Readonly<{ supported: false }>;\n\n/**\n * THE one reader of \"can this object hold a claim?\", asked about the object the\n * claim is about to be written to.\n *\n * Takes the bundle's VERDICT — resolved once, against `GraphBackend`, by the\n * caller's `ClaimsVerdictThunk` (ruling B1/B7) — rather than resolving it\n * itself: the declaration/surface cross-check\n * (`resolve.ts`'s `assertClaimsBidirectionalAgreement`) runs exactly once,\n * inside that resolution, and this function never re-derives it. What this\n * function still owns is the PER-WRITE bind: `claimsMembers` (`bind.ts`) binds\n * the verdict's named members off `target` — the object the write actually\n * executes on, which may be a `TransactionBackend` the verdict was never\n * resolved against — and throws the bundle's port-surface code\n * (`CONSTRAINT_CLAIM_SURFACE_MISMATCH`) if `target` disagrees with what the\n * verdict says is present.\n *\n * @throws ConfigurationError (`CONSTRAINT_CLAIM_SURFACE_MISMATCH`) when\n * `target` is missing a member the verdict says is present.\n */\nexport function claimSupport(\n target: Readonly<\n Partial<Pick<GraphBackend, (typeof CLAIMS)[\"core\"][number]>>\n >,\n verdict: BundleVerdictOf<typeof CLAIMS>,\n): ClaimSupport {\n if (!verdict.supported) return { supported: false };\n return { supported: true, claims: claimsMembers(target, verdict) };\n}\n","/**\n * Edge claims — what an edge write reserves on a declared cardinality axis.\n *\n * A declared cardinality is a predicate over `(kind, from)` or\n * `(kind, from, to)`, and the edges relation's only uniqueness is its\n * `(graph_id, id)` primary key, so nothing in the schema re-decides at write\n * time what the probe decided at read time. This module is the reservation that\n * does: one row per `(graph_id, axis, key)` in `typegraph_edge_claims`, whose\n * primary key refuses a second concurrent claimant.\n *\n * The claim needs no release path. A claim whose holder is no longer live (or,\n * for `oneActive`, no longer active) fails the liveness predicate the takeover\n * statement carries and is taken over in place, so the fence never depends on\n * any delete path having run. `purgeEdgeClaims` exists to bound table growth,\n * not to make the fence correct.\n */\nimport type { CLAIMS } from \"../../backend/capabilities/bundle-registry\";\nimport { type BundleVerdictOf } from \"../../backend/capabilities/resolve\";\nimport {\n type ClaimEdgeCardinalityParams,\n type GraphBackend,\n type InsertEdgeParams,\n} from \"../../backend/types\";\nimport { checkCardinality, checkUniqueEdge } from \"../../constraints\";\nimport { type Cardinality } from \"../../core/types\";\nimport { CardinalityError, ConfigurationError } from \"../../errors\";\nimport { isMissingTableError } from \"../../utils/sql-errors\";\nimport { encodeTupleKey } from \"../../utils/tuple-key\";\nimport {\n type ClaimTarget,\n compareClaimTargets,\n edgeCardinalityAxis,\n} from \"./axis\";\nimport { claimSupport } from \"./backing\";\n\n/** A cardinality that declares something — `many` declares nothing. */\nexport type ConstrainedCardinality = Exclude<Cardinality, \"many\">;\n\n/**\n * What one declared cardinality means to every layer that has to agree about\n * it: which endpoints its axis key covers, whether an edge born already ended\n * claims at all, and what a holder must still BE for its claim to stand.\n */\nexport type EdgeCardinalitySpec = Readonly<{\n /** Which endpoints the axis key covers. */\n keyShape: \"from\" | \"fromAndTo\";\n /** Whether a new edge that is born ENDED makes a claim at all. */\n claimsWhenBornEnded: boolean;\n /** What a holder must still be for its claim to stand. */\n holderLiveness: \"live\" | \"liveAndActive\";\n}>;\n\n/**\n * THE table both renderers of the cardinality predicate read: the TypeScript\n * probe ({@link file://../constraints.ts checkCardinalityConstraint}) and the\n * SQL takeover statement\n * ({@link file://../../backend/drizzle/operations/edge-claims.ts}).\n *\n * Two renderers, one table, exhaustive by type: a new cardinality cannot be\n * added without stating all three facts, and the probe and the fence cannot\n * disagree about any of them — a disagreement is exactly the shape where the\n * probe accepts a write the fence then refuses forever (or the reverse).\n */\nexport const EDGE_CARDINALITY_SPECS = {\n one: { keyShape: \"from\", claimsWhenBornEnded: true, holderLiveness: \"live\" },\n unique: {\n keyShape: \"fromAndTo\",\n claimsWhenBornEnded: true,\n holderLiveness: \"live\",\n },\n oneActive: {\n keyShape: \"from\",\n claimsWhenBornEnded: false,\n holderLiveness: \"liveAndActive\",\n },\n} as const satisfies Record<ConstrainedCardinality, EdgeCardinalitySpec>;\n\n/** Every axis an edge kind's claims can sit on, for housekeeping reaps. */\nexport function edgeCardinalityAxesForKind(\n edgeKind: string,\n): readonly string[] {\n return Object.keys(EDGE_CARDINALITY_SPECS).map((cardinality) =>\n edgeCardinalityAxis(cardinality, edgeKind),\n );\n}\n\n/**\n * THE claim row one edge write reserves: its axis, and the endpoint identity\n * the axis is keyed by.\n *\n * The key is {@link encodeTupleKey}, not a delimiter join: node ids are\n * arbitrary caller data (only kind names pass `assertClaimAxisSafe`), and a\n * delimiter that a value may contain makes two different endpoint tuples\n * collapse onto one key — which would refuse a write no constraint forbids.\n */\nexport function edgeCardinalityClaimTarget(\n params: ClaimEdgeCardinalityParams,\n): ClaimTarget {\n const spec = EDGE_CARDINALITY_SPECS[params.cardinality];\n return {\n relation: \"edgeClaims\",\n graphId: params.graphId,\n axis: edgeCardinalityAxis(params.cardinality, params.edgeKind),\n key:\n spec.keyShape === \"from\" ?\n encodeTupleKey([params.fromKind, params.fromId])\n : encodeTupleKey([\n params.fromKind,\n params.fromId,\n params.toKind,\n params.toId,\n ]),\n };\n}\n\n/**\n * The fields a claim is decided from: the row's identity and the upper bound\n * that decides whether it joins an active-only population. Narrower than\n * {@link InsertEdgeParams} on purpose — a resurrect has no insert params to\n * hand over, and passing an invented `props` to satisfy a type would be a\n * fabricated value a reader has to check is unread.\n */\nexport type EdgeClaimSubject = Pick<\n InsertEdgeParams,\n \"graphId\" | \"id\" | \"kind\" | \"fromKind\" | \"fromId\" | \"toKind\" | \"toId\"\n> &\n Readonly<{ validTo?: string }>;\n\n/**\n * THE claim an edge insert owes, or `undefined` when it owes none.\n *\n * `many` declares no constraint, and an `oneActive` edge born already ended\n * joins no active population — `claimsWhenBornEnded` is the one place that\n * second exemption is written down, and the probe reads the same field, so the\n * two cannot drift into \"probed but unclaimed\" (a silent hole) or \"claimed but\n * unprobed\" (a refusal with no matching error).\n */\nexport function edgeCardinalityClaim(\n cardinality: Cardinality,\n subject: EdgeClaimSubject,\n): ClaimEdgeCardinalityParams | undefined {\n if (cardinality === \"many\") return undefined;\n if (\n !EDGE_CARDINALITY_SPECS[cardinality].claimsWhenBornEnded &&\n subject.validTo !== undefined\n ) {\n return undefined;\n }\n return {\n graphId: subject.graphId,\n cardinality,\n edgeKind: subject.kind,\n edgeId: subject.id,\n fromKind: subject.fromKind,\n fromId: subject.fromId,\n toKind: subject.toKind,\n toId: subject.toId,\n };\n}\n\n/**\n * The refusal a lost claim raises — built by the SAME owners the probe calls,\n * so the fence's error is `instanceof` the same class and carries the same\n * payload as the probe's for the same violation (I3).\n */\n/**\n * Builds the public cardinality refusal for a claim decision.\n *\n * Both the ordinary claim path and the fused claim-plus-edge path call this\n * owner. Keeping the translation here prevents a backend result discriminator\n * from growing a second spelling of the same typed error.\n */\nexport function edgeCardinalityClaimRefusal(\n params: ClaimEdgeCardinalityParams,\n): CardinalityError {\n const error =\n params.cardinality === \"unique\" ?\n checkUniqueEdge(\n params.edgeKind,\n params.fromKind,\n params.fromId,\n params.toKind,\n params.toId,\n 1,\n )\n : checkCardinality(\n params.edgeKind,\n params.fromKind,\n params.fromId,\n params.cardinality,\n 1,\n true,\n );\n // Both owners refuse for an incumbent count of one on every constrained\n // cardinality; the fallback keeps the return type honest without inventing a\n // second spelling of the message.\n return (\n error ??\n new CardinalityError({\n edgeKind: params.edgeKind,\n fromKind: params.fromKind,\n fromId: params.fromId,\n cardinality: params.cardinality,\n existingCount: 1,\n })\n );\n}\n\n/**\n * Converts the engine's \"relation does not exist\" into a typed precondition\n * error naming the relation and the way to create it.\n *\n * Checked at FIRST USE rather than at store construction: a graph with no\n * constrained edge kind never issues a claim and must not pay a catalog read\n * for a relation it will never touch. A database bootstrapped before this\n * relation existed reaches it here, on the first constrained edge write, with\n * an error that says what to run instead of an opaque driver failure.\n */\nexport function edgeClaimRelationMissing(\n graphId: string,\n cause: unknown,\n): ConfigurationError {\n return new ConfigurationError(\n \"Enforcing a declared edge cardinality needs the edge claim relation \" +\n \"(typegraph_edge_claims), and this database does not have it. \" +\n \"Databases initialized before this relation existed were never sent \" +\n \"its CREATE TABLE, because the bootstrap DDL runs only on first boot.\",\n { code: \"EDGE_CLAIM_RELATION_MISSING\", graphId },\n {\n cause,\n suggestion:\n \"Run the generated migration SQL (generatePostgresMigrationSQL / \" +\n \"generateSqliteMigrationSQL) against this database, or declare the \" +\n 'edge kind `cardinality: \"many\"` and enforce the limit in ' +\n \"application code.\",\n },\n );\n}\n\nasync function withEdgeClaimRelationPrecondition<T>(\n graphId: string,\n issue: () => Promise<T>,\n): Promise<T> {\n try {\n return await issue();\n } catch (error) {\n if (!isMissingTableError(error)) throw error;\n throw edgeClaimRelationMissing(graphId, error);\n }\n}\n\ntype ClaimModeTarget = Readonly<\n Partial<\n Pick<\n GraphBackend,\n (typeof CLAIMS)[\"core\"][number] | \"claimEdgeCardinalityGuarded\"\n >\n >\n>;\n\n/** The narrow backend facet an edge claim is written through. */\ntype ClaimTargetMembers = ClaimModeTarget;\n\n/**\n * The one owner of whether a single write may replace its entity probe with a\n * guarded claim. Both claim-bundle support and the optional strong member are\n * required: the member is the backend's explicit opt-in contract, while the\n * bundle verdict proves the target can actually persist claims. Either absence\n * deliberately preserves the legacy probe-then-claim protocol.\n */\nexport function edgeCardinalityClaimMode(\n backend: ClaimModeTarget,\n verdict: BundleVerdictOf<typeof CLAIMS>,\n):\n | Readonly<{\n kind: \"guarded\";\n claim: NonNullable<GraphBackend[\"claimEdgeCardinalityGuarded\"]>;\n }>\n | Readonly<{\n kind: \"probeThenClaim\";\n support: ReturnType<typeof claimSupport>;\n }> {\n const support = claimSupport(backend, verdict);\n const guardedClaim = backend.claimEdgeCardinalityGuarded;\n return !support.supported || guardedClaim === undefined ?\n { kind: \"probeThenClaim\", support }\n : { kind: \"guarded\", claim: guardedClaim };\n}\n\n/**\n * Issues ONE edge cardinality claim against the object the row write goes to,\n * refusing with the declared error when a live incumbent holds the axis.\n *\n * A backend that declares no claim support writes no claim and keeps exactly\n * the fence it has today (the per-graph write lock around the probe) — a\n * declared gap with a parity-matrix row, never a silent unfencing and never a\n * new refusal.\n */\nexport async function claimEdgeCardinality(\n backend: ClaimTargetMembers,\n verdict: BundleVerdictOf<typeof CLAIMS>,\n claim: ClaimEdgeCardinalityParams,\n): Promise<void> {\n const mode = edgeCardinalityClaimMode(backend, verdict);\n if (mode.kind === \"guarded\") {\n const outcome = await withEdgeClaimRelationPrecondition(claim.graphId, () =>\n mode.claim(claim),\n );\n if (outcome.status === \"refused\") {\n throw edgeCardinalityClaimRefusal(claim);\n }\n return;\n }\n const support = mode.support;\n if (!support.supported) return;\n const outcome = await withEdgeClaimRelationPrecondition(claim.graphId, () =>\n support.claims.claimEdgeCardinality(claim),\n );\n if (outcome.status === \"refused\") throw edgeCardinalityClaimRefusal(claim);\n}\n\n/**\n * Issues a batch's claims as ONE statement, entries sorted by\n * {@link compareClaimTargets}.\n *\n * One statement takes its row locks in a fixed order, so a batch cannot\n * deadlock against itself; sorting is what stops two writers of the same two\n * axes from taking them in opposite orders. In-batch duplicates are refused\n * before this by the batch validation wrapper's pending-cardinality state, so\n * the backend's duplicate-conflict-target guard stays a defensive invariant.\n */\nexport async function claimEdgeCardinalityBatch(\n backend: ClaimTargetMembers,\n verdict: BundleVerdictOf<typeof CLAIMS>,\n claims: readonly ClaimEdgeCardinalityParams[],\n): Promise<void> {\n if (claims.length === 0) return;\n const support = claimSupport(backend, verdict);\n if (!support.supported) return;\n const ordered = claims\n .map((claim) => ({ claim, target: edgeCardinalityClaimTarget(claim) }))\n .toSorted((left, right) => compareClaimTargets(left.target, right.target));\n const graphId = ordered[0]?.claim.graphId ?? \"\";\n const outcomes = await withEdgeClaimRelationPrecondition(graphId, () =>\n support.claims.claimEdgeCardinalityBatch(\n ordered.map((entry) => entry.claim),\n ),\n );\n for (const [index, outcome] of outcomes.entries()) {\n const entry = ordered[index];\n if (entry !== undefined && outcome.status === \"refused\") {\n throw edgeCardinalityClaimRefusal(entry.claim);\n }\n }\n}\n\n/**\n * Housekeeping: drops the claim rows named edges held.\n *\n * Never a fence and never load-bearing — a claim whose holder is gone already\n * fails the takeover statement's liveness predicate, so the axis is reusable\n * whether or not this ran. It exists so a hard delete does not leave a row\n * behind forever. A backend without claim support has nothing to purge.\n */\nexport async function purgeEdgeClaims(\n backend: ClaimTargetMembers,\n verdict: BundleVerdictOf<typeof CLAIMS>,\n graphId: string,\n edgeIds: readonly string[],\n): Promise<void> {\n if (edgeIds.length === 0) return;\n const support = claimSupport(backend, verdict);\n if (!support.supported) return;\n await withEdgeClaimRelationPrecondition(graphId, () =>\n support.claims.purgeEdgeClaims({ graphId, edgeIds }),\n );\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/store/claims/backing.ts","../src/store/claims/edge-claims.ts"],"names":["outcome"],"mappings":"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","file":"chunk-CDKNGCE7.js","sourcesContent":["/**\n * What backs each constraint fence class.\n *\n * A constrained write is fenced by one of two things: a per-graph lock that\n * serializes the probe with the write it guards, or a CLAIM row whose primary\n * key refuses a second claimant outright. The second is strictly stronger — it\n * holds without a lock, which is what an import needs — and this module records\n * which class has reached it, so \"is this fence a lock or a key?\" is answered\n * from one table rather than inferred from whichever module a reader lands in.\n *\n * It also owns the runtime half of the same question — {@link claimSupport},\n * the one reader of \"can THIS object hold a claim?\" — so the declaration and\n * the surface are reconciled in one place rather than at each claim site.\n * `claimSupport` is now a thin binder over the `claims` capability bundle\n * (`backend/capabilities`): the bidirectional declaration/surface cross-check\n * lives once in `resolve.ts`'s `assertClaimsBidirectionalAgreement`, reached\n * through the verdict every caller threads in, and this module owns only the\n * per-write port bind (`claimsMembers`) and this decision's shape.\n */\nimport {\n type BundleBinding,\n claimsMembers,\n} from \"../../backend/capabilities/bind\";\nimport type { CLAIMS } from \"../../backend/capabilities/bundle-registry\";\nimport { type BundleVerdictOf } from \"../../backend/capabilities/resolve\";\nimport { type GraphBackend } from \"../../backend/types\";\n\n/**\n * The runtime extent of the fence classes. {@link ConstraintFenceReason} is\n * DERIVED from it rather than declared beside it: a union type has no runtime\n * extent, so a totality test over a map keyed by the union could only iterate\n * that map's own keys and would be trivially true.\n */\nexport const CONSTRAINT_FENCE_REASONS = [\n \"edgeCardinality\",\n \"edgeMatchKeyConvergence\",\n \"nodeDisjointness\",\n \"nodeUniquenessClaim\",\n \"nodeUniquenessScope\",\n] as const;\n\n/**\n * WHICH declared constraint makes a write constrained.\n *\n * The classification names the reason rather than answering yes/no, because\n * the reason is load-bearing twice over: it is what the fence is taken FOR, and\n * — on a backend that cannot hold the fence — it is what the refusal has to\n * tell the caller. \"This backend cannot fence constrained writes\" is unusable\n * advice; \"your `cardinality: 'one'` edge cannot be enforced here\" is\n * actionable, and only the classifier knows which it was.\n */\nexport type ConstraintFenceReason = (typeof CONSTRAINT_FENCE_REASONS)[number];\n\n/** The relation whose key fences a class, or `lockOnly` when nothing does yet. */\ntype ConstraintFenceBacking = \"uniques\" | \"edgeClaims\" | \"lockOnly\";\n\n/**\n * Which claim relation backs each fence class. The `satisfies` forces totality:\n * a new reason cannot be added without stating what backs it.\n *\n * `nodeUniquenessScope` is `\"uniques\"` because a shared-scope claim is now\n * written at the scope's axis, so two writers of two kinds in one hierarchy\n * contend for one row. `nodeUniquenessClaim` is the same relation seen from the\n * other side: the claim row is the fence, and the class exists because a write\n * that must issue it BEFORE the row it gates needs a transaction to undo the\n * pair together — which is what its refusal names. `nodeDisjointness` is the\n * same relation again, at a third kind of axis: a claim keyed on the declared\n * PAIR and on the node's id, which is the axis disjointness actually declares\n * and the one the nodes primary key `(graph_id, kind, id)` cannot fence.\n * `edgeCardinality` is the other relation: a claim keyed on\n * `(<cardinality>:<edgeKind>, endpoint identity)`, which is the axis the\n * declaration actually spans and the one the edges primary key `(graph_id, id)`\n * cannot fence. The classes still marked `lockOnly` are fenced by the per-graph\n * write lock alone, which is why they are also the classes a non-transactional\n * backend refuses.\n */\nexport const CONSTRAINT_FENCE_BACKING = {\n edgeCardinality: \"edgeClaims\",\n edgeMatchKeyConvergence: \"lockOnly\",\n nodeDisjointness: \"uniques\",\n nodeUniquenessClaim: \"uniques\",\n nodeUniquenessScope: \"uniques\",\n} as const satisfies Record<ConstraintFenceReason, ConstraintFenceBacking>;\n\n/** The decision {@link claimSupport} returns — never a flag a caller re-derives. */\nexport type ClaimSupport =\n /** Capability declared AND every claim member present: the members, bound off the port. */\n | Readonly<{\n supported: true;\n claims: BundleBinding<(typeof CLAIMS)[\"core\"][number]>;\n }>\n /** Capability absent or false AND no claim member present: the declared gap. */\n | Readonly<{ supported: false }>;\n\n/**\n * THE one reader of \"can this object hold a claim?\", asked about the object the\n * claim is about to be written to.\n *\n * Takes the bundle's VERDICT — resolved once, against `GraphBackend`, by the\n * caller's `ClaimsVerdictThunk` (ruling B1/B7) — rather than resolving it\n * itself: the declaration/surface cross-check\n * (`resolve.ts`'s `assertClaimsBidirectionalAgreement`) runs exactly once,\n * inside that resolution, and this function never re-derives it. What this\n * function still owns is the PER-WRITE bind: `claimsMembers` (`bind.ts`) binds\n * the verdict's named members off `target` — the object the write actually\n * executes on, which may be a `TransactionBackend` the verdict was never\n * resolved against — and throws the bundle's port-surface code\n * (`CONSTRAINT_CLAIM_SURFACE_MISMATCH`) if `target` disagrees with what the\n * verdict says is present.\n *\n * @throws ConfigurationError (`CONSTRAINT_CLAIM_SURFACE_MISMATCH`) when\n * `target` is missing a member the verdict says is present.\n */\nexport function claimSupport(\n target: Readonly<\n Partial<Pick<GraphBackend, (typeof CLAIMS)[\"core\"][number]>>\n >,\n verdict: BundleVerdictOf<typeof CLAIMS>,\n): ClaimSupport {\n if (!verdict.supported) return { supported: false };\n return { supported: true, claims: claimsMembers(target, verdict) };\n}\n","/**\n * Edge claims — what an edge write reserves on a declared cardinality axis.\n *\n * A declared cardinality is a predicate over `(kind, from)` or\n * `(kind, from, to)`, and the edges relation's only uniqueness is its\n * `(graph_id, id)` primary key, so nothing in the schema re-decides at write\n * time what the probe decided at read time. This module is the reservation that\n * does: one row per `(graph_id, axis, key)` in `typegraph_edge_claims`, whose\n * primary key refuses a second concurrent claimant.\n *\n * The claim needs no release path. A claim whose holder is no longer live (or,\n * for `oneActive`, no longer active) fails the liveness predicate the takeover\n * statement carries and is taken over in place, so the fence never depends on\n * any delete path having run. `purgeEdgeClaims` exists to bound table growth,\n * not to make the fence correct.\n */\nimport type { CLAIMS } from \"../../backend/capabilities/bundle-registry\";\nimport { type BundleVerdictOf } from \"../../backend/capabilities/resolve\";\nimport {\n type ClaimEdgeCardinalityParams,\n type GraphBackend,\n type InsertEdgeParams,\n} from \"../../backend/types\";\nimport { checkCardinality, checkUniqueEdge } from \"../../constraints\";\nimport { type Cardinality } from \"../../core/types\";\nimport { CardinalityError, ConfigurationError } from \"../../errors\";\nimport { isMissingTableError } from \"../../utils/sql-errors\";\nimport { encodeTupleKey } from \"../../utils/tuple-key\";\nimport {\n type ClaimTarget,\n compareClaimTargets,\n edgeCardinalityAxis,\n} from \"./axis\";\nimport { claimSupport } from \"./backing\";\n\n/** A cardinality that declares something — `many` declares nothing. */\nexport type ConstrainedCardinality = Exclude<Cardinality, \"many\">;\n\n/**\n * What one declared cardinality means to every layer that has to agree about\n * it: which endpoints its axis key covers, whether an edge born already ended\n * claims at all, and what a holder must still BE for its claim to stand.\n */\nexport type EdgeCardinalitySpec = Readonly<{\n /** Which endpoints the axis key covers. */\n keyShape: \"from\" | \"fromAndTo\";\n /** Whether a new edge that is born ENDED makes a claim at all. */\n claimsWhenBornEnded: boolean;\n /** What a holder must still be for its claim to stand. */\n holderLiveness: \"live\" | \"liveAndActive\";\n}>;\n\n/**\n * THE table both renderers of the cardinality predicate read: the TypeScript\n * probe ({@link file://../constraints.ts checkCardinalityConstraint}) and the\n * SQL takeover statement\n * ({@link file://../../backend/drizzle/operations/edge-claims.ts}).\n *\n * Two renderers, one table, exhaustive by type: a new cardinality cannot be\n * added without stating all three facts, and the probe and the fence cannot\n * disagree about any of them — a disagreement is exactly the shape where the\n * probe accepts a write the fence then refuses forever (or the reverse).\n */\nexport const EDGE_CARDINALITY_SPECS = {\n one: { keyShape: \"from\", claimsWhenBornEnded: true, holderLiveness: \"live\" },\n unique: {\n keyShape: \"fromAndTo\",\n claimsWhenBornEnded: true,\n holderLiveness: \"live\",\n },\n oneActive: {\n keyShape: \"from\",\n claimsWhenBornEnded: false,\n holderLiveness: \"liveAndActive\",\n },\n} as const satisfies Record<ConstrainedCardinality, EdgeCardinalitySpec>;\n\n/** Every axis an edge kind's claims can sit on, for housekeeping reaps. */\nexport function edgeCardinalityAxesForKind(\n edgeKind: string,\n): readonly string[] {\n return Object.keys(EDGE_CARDINALITY_SPECS).map((cardinality) =>\n edgeCardinalityAxis(cardinality, edgeKind),\n );\n}\n\n/**\n * THE claim row one edge write reserves: its axis, and the endpoint identity\n * the axis is keyed by.\n *\n * The key is {@link encodeTupleKey}, not a delimiter join: node ids are\n * arbitrary caller data (only kind names pass `assertClaimAxisSafe`), and a\n * delimiter that a value may contain makes two different endpoint tuples\n * collapse onto one key — which would refuse a write no constraint forbids.\n */\nexport function edgeCardinalityClaimTarget(\n params: ClaimEdgeCardinalityParams,\n): ClaimTarget {\n const spec = EDGE_CARDINALITY_SPECS[params.cardinality];\n return {\n relation: \"edgeClaims\",\n graphId: params.graphId,\n axis: edgeCardinalityAxis(params.cardinality, params.edgeKind),\n key:\n spec.keyShape === \"from\" ?\n encodeTupleKey([params.fromKind, params.fromId])\n : encodeTupleKey([\n params.fromKind,\n params.fromId,\n params.toKind,\n params.toId,\n ]),\n };\n}\n\n/**\n * The fields a claim is decided from: the row's identity and the upper bound\n * that decides whether it joins an active-only population. Narrower than\n * {@link InsertEdgeParams} on purpose — a resurrect has no insert params to\n * hand over, and passing an invented `props` to satisfy a type would be a\n * fabricated value a reader has to check is unread.\n */\nexport type EdgeClaimSubject = Pick<\n InsertEdgeParams,\n \"graphId\" | \"id\" | \"kind\" | \"fromKind\" | \"fromId\" | \"toKind\" | \"toId\"\n> &\n Readonly<{ validTo?: string }>;\n\n/**\n * THE claim an edge insert owes, or `undefined` when it owes none.\n *\n * `many` declares no constraint, and an `oneActive` edge born already ended\n * joins no active population — `claimsWhenBornEnded` is the one place that\n * second exemption is written down, and the probe reads the same field, so the\n * two cannot drift into \"probed but unclaimed\" (a silent hole) or \"claimed but\n * unprobed\" (a refusal with no matching error).\n */\nexport function edgeCardinalityClaim(\n cardinality: Cardinality,\n subject: EdgeClaimSubject,\n): ClaimEdgeCardinalityParams | undefined {\n if (cardinality === \"many\") return undefined;\n if (\n !EDGE_CARDINALITY_SPECS[cardinality].claimsWhenBornEnded &&\n subject.validTo !== undefined\n ) {\n return undefined;\n }\n return {\n graphId: subject.graphId,\n cardinality,\n edgeKind: subject.kind,\n edgeId: subject.id,\n fromKind: subject.fromKind,\n fromId: subject.fromId,\n toKind: subject.toKind,\n toId: subject.toId,\n };\n}\n\n/**\n * The refusal a lost claim raises — built by the SAME owners the probe calls,\n * so the fence's error is `instanceof` the same class and carries the same\n * payload as the probe's for the same violation (I3).\n */\n/**\n * Builds the public cardinality refusal for a claim decision.\n *\n * Both the ordinary claim path and the fused claim-plus-edge path call this\n * owner. Keeping the translation here prevents a backend result discriminator\n * from growing a second spelling of the same typed error.\n */\nexport function edgeCardinalityClaimRefusal(\n params: ClaimEdgeCardinalityParams,\n): CardinalityError {\n const error =\n params.cardinality === \"unique\" ?\n checkUniqueEdge(\n params.edgeKind,\n params.fromKind,\n params.fromId,\n params.toKind,\n params.toId,\n 1,\n )\n : checkCardinality(\n params.edgeKind,\n params.fromKind,\n params.fromId,\n params.cardinality,\n 1,\n true,\n );\n // Both owners refuse for an incumbent count of one on every constrained\n // cardinality; the fallback keeps the return type honest without inventing a\n // second spelling of the message.\n return (\n error ??\n new CardinalityError({\n edgeKind: params.edgeKind,\n fromKind: params.fromKind,\n fromId: params.fromId,\n cardinality: params.cardinality,\n existingCount: 1,\n })\n );\n}\n\n/**\n * Converts the engine's \"relation does not exist\" into a typed precondition\n * error naming the relation and the way to create it.\n *\n * Checked at FIRST USE rather than at store construction: a graph with no\n * constrained edge kind never issues a claim and must not pay a catalog read\n * for a relation it will never touch. A database bootstrapped before this\n * relation existed reaches it here, on the first constrained edge write, with\n * an error that says what to run instead of an opaque driver failure.\n */\nexport function edgeClaimRelationMissing(\n graphId: string,\n cause: unknown,\n): ConfigurationError {\n return new ConfigurationError(\n \"Enforcing a declared edge cardinality needs the edge claim relation \" +\n \"(typegraph_edge_claims), and this database does not have it. \" +\n \"Databases initialized before this relation existed were never sent \" +\n \"its CREATE TABLE, because the bootstrap DDL runs only on first boot.\",\n { code: \"EDGE_CLAIM_RELATION_MISSING\", graphId },\n {\n cause,\n suggestion:\n \"Run the generated migration SQL (generatePostgresMigrationSQL / \" +\n \"generateSqliteMigrationSQL) against this database, or declare the \" +\n 'edge kind `cardinality: \"many\"` and enforce the limit in ' +\n \"application code.\",\n },\n );\n}\n\nasync function withEdgeClaimRelationPrecondition<T>(\n graphId: string,\n issue: () => Promise<T>,\n): Promise<T> {\n try {\n return await issue();\n } catch (error) {\n if (!isMissingTableError(error)) throw error;\n throw edgeClaimRelationMissing(graphId, error);\n }\n}\n\ntype ClaimModeTarget = Readonly<\n Partial<\n Pick<\n GraphBackend,\n (typeof CLAIMS)[\"core\"][number] | \"claimEdgeCardinalityGuarded\"\n >\n >\n>;\n\n/** The narrow backend facet an edge claim is written through. */\ntype ClaimTargetMembers = ClaimModeTarget;\n\n/**\n * The one owner of whether a single write may replace its entity probe with a\n * guarded claim. Both claim-bundle support and the optional strong member are\n * required: the member is the backend's explicit opt-in contract, while the\n * bundle verdict proves the target can actually persist claims. Either absence\n * deliberately preserves the legacy probe-then-claim protocol.\n */\nexport function edgeCardinalityClaimMode(\n backend: ClaimModeTarget,\n verdict: BundleVerdictOf<typeof CLAIMS>,\n):\n | Readonly<{\n kind: \"guarded\";\n claim: NonNullable<GraphBackend[\"claimEdgeCardinalityGuarded\"]>;\n }>\n | Readonly<{\n kind: \"probeThenClaim\";\n support: ReturnType<typeof claimSupport>;\n }> {\n const support = claimSupport(backend, verdict);\n const guardedClaim = backend.claimEdgeCardinalityGuarded;\n return !support.supported || guardedClaim === undefined ?\n { kind: \"probeThenClaim\", support }\n : { kind: \"guarded\", claim: guardedClaim };\n}\n\n/**\n * Issues ONE edge cardinality claim against the object the row write goes to,\n * refusing with the declared error when a live incumbent holds the axis.\n *\n * A backend that declares no claim support writes no claim and keeps exactly\n * the fence it has today (the per-graph write lock around the probe) — a\n * declared gap with a parity-matrix row, never a silent unfencing and never a\n * new refusal.\n */\nexport async function claimEdgeCardinality(\n backend: ClaimTargetMembers,\n verdict: BundleVerdictOf<typeof CLAIMS>,\n claim: ClaimEdgeCardinalityParams,\n): Promise<void> {\n const mode = edgeCardinalityClaimMode(backend, verdict);\n if (mode.kind === \"guarded\") {\n const outcome = await withEdgeClaimRelationPrecondition(claim.graphId, () =>\n mode.claim(claim),\n );\n if (outcome.status === \"refused\") {\n throw edgeCardinalityClaimRefusal(claim);\n }\n return;\n }\n const support = mode.support;\n if (!support.supported) return;\n const outcome = await withEdgeClaimRelationPrecondition(claim.graphId, () =>\n support.claims.claimEdgeCardinality(claim),\n );\n if (outcome.status === \"refused\") throw edgeCardinalityClaimRefusal(claim);\n}\n\n/**\n * Issues a batch's claims as ONE statement, entries sorted by\n * {@link compareClaimTargets}.\n *\n * One statement takes its row locks in a fixed order, so a batch cannot\n * deadlock against itself; sorting is what stops two writers of the same two\n * axes from taking them in opposite orders. In-batch duplicates are refused\n * before this by the batch validation wrapper's pending-cardinality state, so\n * the backend's duplicate-conflict-target guard stays a defensive invariant.\n */\nexport async function claimEdgeCardinalityBatch(\n backend: ClaimTargetMembers,\n verdict: BundleVerdictOf<typeof CLAIMS>,\n claims: readonly ClaimEdgeCardinalityParams[],\n): Promise<void> {\n if (claims.length === 0) return;\n const support = claimSupport(backend, verdict);\n if (!support.supported) return;\n const ordered = claims\n .map((claim) => ({ claim, target: edgeCardinalityClaimTarget(claim) }))\n .toSorted((left, right) => compareClaimTargets(left.target, right.target));\n const graphId = ordered[0]?.claim.graphId ?? \"\";\n const outcomes = await withEdgeClaimRelationPrecondition(graphId, () =>\n support.claims.claimEdgeCardinalityBatch(\n ordered.map((entry) => entry.claim),\n ),\n );\n for (const [index, outcome] of outcomes.entries()) {\n const entry = ordered[index];\n if (entry !== undefined && outcome.status === \"refused\") {\n throw edgeCardinalityClaimRefusal(entry.claim);\n }\n }\n}\n\n/**\n * Housekeeping: drops the claim rows named edges held.\n *\n * Never a fence and never load-bearing — a claim whose holder is gone already\n * fails the takeover statement's liveness predicate, so the axis is reusable\n * whether or not this ran. It exists so a hard delete does not leave a row\n * behind forever. A backend without claim support has nothing to purge.\n */\nexport async function purgeEdgeClaims(\n backend: ClaimTargetMembers,\n verdict: BundleVerdictOf<typeof CLAIMS>,\n graphId: string,\n edgeIds: readonly string[],\n): Promise<void> {\n if (edgeIds.length === 0) return;\n const support = claimSupport(backend, verdict);\n if (!support.supported) return;\n await withEdgeClaimRelationPrecondition(graphId, () =>\n support.claims.purgeEdgeClaims({ graphId, edgeIds }),\n );\n}\n"]}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
var
|
|
3
|
+
var chunk6JRVV2SS_cjs = require('./chunk-6JRVV2SS.cjs');
|
|
4
4
|
|
|
5
5
|
// src/backend/table-names.ts
|
|
6
6
|
var LEGACY_EMBEDDINGS_TABLE_NAME = "typegraph_node_embeddings";
|
|
@@ -11,7 +11,7 @@ function definedTableNameOverrides(override) {
|
|
|
11
11
|
);
|
|
12
12
|
}
|
|
13
13
|
function resolvedTableNames(backend, override) {
|
|
14
|
-
return
|
|
14
|
+
return chunk6JRVV2SS_cjs.createSqlSchema({
|
|
15
15
|
...backend.tableNames,
|
|
16
16
|
...definedTableNameOverrides(override)
|
|
17
17
|
}).tables;
|
|
@@ -19,5 +19,5 @@ function resolvedTableNames(backend, override) {
|
|
|
19
19
|
|
|
20
20
|
exports.LEGACY_EMBEDDINGS_TABLE_NAME = LEGACY_EMBEDDINGS_TABLE_NAME;
|
|
21
21
|
exports.resolvedTableNames = resolvedTableNames;
|
|
22
|
-
//# sourceMappingURL=chunk-
|
|
23
|
-
//# sourceMappingURL=chunk-
|
|
22
|
+
//# sourceMappingURL=chunk-EACDHXJL.cjs.map
|
|
23
|
+
//# sourceMappingURL=chunk-EACDHXJL.cjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/backend/table-names.ts"],"names":["createSqlSchema"],"mappings":";;;;;AAiBO,IAAM,4BAAA,GAA+B;AAE5C,SAAS,0BACP,QAAA,EACwB;AACxB,EAAA,IAAI,QAAA,KAAa,MAAA,EAAW,OAAO,EAAC;AACpC,EAAA,OAAO,MAAA,CAAO,WAAA;AAAA,IACZ,MAAA,CAAO,OAAA,CAAQ,QAAQ,CAAA,CAAE,MAAA,CAAO,CAAC,GAAG,SAAS,CAAA,KAAM,SAAA,KAAc,MAAS;AAAA,GAC5E;AACF;AAYO,SAAS,kBAAA,CACd,SACA,QAAA,EACuB;AACvB,EAAA,OAAOA,iCAAA,CAAgB;AAAA,IACrB,GAAG,OAAA,CAAQ,UAAA;AAAA,IACX,GAAG,0BAA0B,QAAQ;AAAA,GACtC,CAAA,CAAE,MAAA;AACL","file":"chunk-
|
|
1
|
+
{"version":3,"sources":["../src/backend/table-names.ts"],"names":["createSqlSchema"],"mappings":";;;;;AAiBO,IAAM,4BAAA,GAA+B;AAE5C,SAAS,0BACP,QAAA,EACwB;AACxB,EAAA,IAAI,QAAA,KAAa,MAAA,EAAW,OAAO,EAAC;AACpC,EAAA,OAAO,MAAA,CAAO,WAAA;AAAA,IACZ,MAAA,CAAO,OAAA,CAAQ,QAAQ,CAAA,CAAE,MAAA,CAAO,CAAC,GAAG,SAAS,CAAA,KAAM,SAAA,KAAc,MAAS;AAAA,GAC5E;AACF;AAYO,SAAS,kBAAA,CACd,SACA,QAAA,EACuB;AACvB,EAAA,OAAOA,iCAAA,CAAgB;AAAA,IACrB,GAAG,OAAA,CAAQ,UAAA;AAAA,IACX,GAAG,0BAA0B,QAAQ;AAAA,GACtC,CAAA,CAAE,MAAA;AACL","file":"chunk-EACDHXJL.cjs","sourcesContent":["/**\n * The one owner of \"which physical relations does this offline operation\n * touch?\" for the maintenance entrypoints that accept a `tableNames` override.\n */\nimport {\n createSqlSchema,\n type ResolvedSqlTableNames,\n type SqlTableNames,\n} from \"../query/compiler/schema\";\nimport type { GraphBackend } from \"./types\";\n\n/**\n * Physical name of the legacy single shared embeddings table, dropped in\n * the cross-backend vector cutover (the clean cut of #157). Strategies now\n * own per-`(nodeKind, fieldPath)` typed storage. Retained only so the\n * one-time migration utility can address and drain the old table.\n */\nexport const LEGACY_EMBEDDINGS_TABLE_NAME = \"typegraph_node_embeddings\";\n\nfunction definedTableNameOverrides(\n override: Partial<SqlTableNames> | undefined,\n): Partial<SqlTableNames> {\n if (override === undefined) return {};\n return Object.fromEntries(\n Object.entries(override).filter(([, tableName]) => tableName !== undefined),\n );\n}\n\n/**\n * Resolves the relations an offline maintenance call targets.\n *\n * An override is a PATCH over the backend's own names. This matches the\n * `Partial<SqlTableNames>` input contract: naming only `nodes`, for example,\n * must not silently retarget edges and recorded relations to the built-in\n * defaults. `migrateLegacyRecordedTime` and\n * `repairInvertedValidityWindows` share this owner so an offline write can never\n * resolve the same partial override two different ways.\n */\nexport function resolvedTableNames(\n backend: Pick<GraphBackend, \"tableNames\">,\n override: Partial<SqlTableNames> | undefined,\n): ResolvedSqlTableNames {\n return createSqlSchema({\n ...backend.tableNames,\n ...definedTableNameOverrides(override),\n }).tables;\n}\n"]}
|