@bjornpagen/bumbledb 0.1.0 → 0.3.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/COOKBOOK.md +1450 -0
- package/README.md +69 -30
- package/dist/closed.d.ts +157 -38
- package/dist/closed.d.ts.map +1 -1
- package/dist/closed.js +232 -47
- package/dist/closed.js.map +1 -1
- package/dist/count.d.ts +64 -17
- package/dist/count.d.ts.map +1 -1
- package/dist/count.js +37 -14
- package/dist/count.js.map +1 -1
- package/dist/db.d.ts +27 -8
- package/dist/db.d.ts.map +1 -1
- package/dist/db.js +33 -10
- package/dist/db.js.map +1 -1
- package/dist/exhume.d.ts +12 -11
- package/dist/exhume.d.ts.map +1 -1
- package/dist/exhume.js +7 -6
- package/dist/exhume.js.map +1 -1
- package/dist/face.d.ts +135 -30
- package/dist/face.d.ts.map +1 -1
- package/dist/face.js +44 -19
- package/dist/face.js.map +1 -1
- package/dist/fields.d.ts +130 -130
- package/dist/fields.d.ts.map +1 -1
- package/dist/fields.js +60 -94
- package/dist/fields.js.map +1 -1
- package/dist/index.d.ts +29 -24
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +19 -14
- package/dist/index.js.map +1 -1
- package/dist/law.d.ts +224 -0
- package/dist/law.d.ts.map +1 -0
- package/dist/law.js +224 -0
- package/dist/law.js.map +1 -0
- package/dist/lower.d.ts +17 -7
- package/dist/lower.d.ts.map +1 -1
- package/dist/lower.js +66 -24
- package/dist/lower.js.map +1 -1
- package/dist/marshal.d.ts +36 -21
- package/dist/marshal.d.ts.map +1 -1
- package/dist/marshal.js +41 -25
- package/dist/marshal.js.map +1 -1
- package/dist/native.d.ts +6 -2
- package/dist/native.d.ts.map +1 -1
- package/dist/native.js +2 -2
- package/dist/native.js.map +1 -1
- package/dist/query/atom.d.ts +370 -174
- package/dist/query/atom.d.ts.map +1 -1
- package/dist/query/atom.js +75 -172
- package/dist/query/atom.js.map +1 -1
- package/dist/query/lower.d.ts +312 -109
- package/dist/query/lower.d.ts.map +1 -1
- package/dist/query/lower.js +906 -387
- package/dist/query/lower.js.map +1 -1
- package/dist/query/predicate.d.ts +70 -88
- package/dist/query/predicate.d.ts.map +1 -1
- package/dist/query/predicate.js +118 -72
- package/dist/query/predicate.js.map +1 -1
- package/dist/query/run.d.ts +19 -16
- package/dist/query/run.d.ts.map +1 -1
- package/dist/query/run.js +31 -24
- package/dist/query/run.js.map +1 -1
- package/dist/query/scope.d.ts +178 -127
- package/dist/query/scope.d.ts.map +1 -1
- package/dist/query/scope.js +111 -108
- package/dist/query/scope.js.map +1 -1
- package/dist/query/select.d.ts +102 -80
- package/dist/query/select.d.ts.map +1 -1
- package/dist/query/select.js +39 -34
- package/dist/query/select.js.map +1 -1
- package/dist/relation.d.ts +48 -38
- package/dist/relation.d.ts.map +1 -1
- package/dist/relation.js +24 -19
- package/dist/relation.js.map +1 -1
- package/dist/schema.d.ts +41 -3
- package/dist/schema.d.ts.map +1 -1
- package/dist/schema.js +34 -9
- package/dist/schema.js.map +1 -1
- package/dist/spec.d.ts +7 -5
- package/dist/spec.d.ts.map +1 -1
- package/dist/spec.js.map +1 -1
- package/dist/statements.d.ts +91 -36
- package/dist/statements.d.ts.map +1 -1
- package/dist/statements.js +42 -12
- package/dist/statements.js.map +1 -1
- package/package.json +4 -3
- package/src/closed.ts +448 -95
- package/src/count.ts +112 -18
- package/src/db.ts +45 -17
- package/src/exhume.ts +12 -11
- package/src/face.ts +211 -41
- package/src/fields.ts +199 -234
- package/src/index.ts +78 -61
- package/src/law.ts +519 -0
- package/src/lower.ts +82 -27
- package/src/marshal.ts +48 -30
- package/src/native.ts +8 -4
- package/src/query/atom.ts +525 -374
- package/src/query/lower.ts +1469 -538
- package/src/query/predicate.ts +208 -161
- package/src/query/run.ts +35 -25
- package/src/query/scope.ts +264 -218
- package/src/query/select.ts +168 -93
- package/src/relation.ts +47 -47
- package/src/schema.ts +69 -18
- package/src/spec.ts +7 -5
- package/src/statements.ts +124 -41
- package/dist/brand.d.ts +0 -59
- package/dist/brand.d.ts.map +0 -1
- package/dist/brand.js +0 -47
- package/dist/brand.js.map +0 -1
- package/src/brand.ts +0 -82
package/dist/index.d.ts
CHANGED
|
@@ -1,49 +1,54 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* @bjornpagen/bumbledb — the type-theoretic TypeScript SDK for the
|
|
3
|
-
* bumbledb embedded relational engine. Public surface: the type
|
|
4
|
-
* (
|
|
5
|
-
*
|
|
3
|
+
* bumbledb embedded relational engine. Public surface: the structural type
|
|
4
|
+
* kernel (fields as pure structure, `relation()`, `closed()` — domains are
|
|
5
|
+
* never declared: THE LAWS TYPE THE COLUMNS, `schema()` computing every
|
|
6
|
+
* field's equivalence class FROM the statement list at both tiers), the
|
|
7
|
+
* statement algebra with `schema()` and `SchemaSpec` lowering (PRD-06), the `Db`
|
|
6
8
|
* runtime (path-cached stores, transactions, typed violations, scoped
|
|
7
9
|
* snapshot reads, the witnessed write loop with `abandon` — PRD-07, zero
|
|
8
|
-
* closables), the query surface (Datalog as values:
|
|
9
|
-
*
|
|
10
|
-
*
|
|
10
|
+
* closables), the query surface (Datalog as values, kysely-shaped:
|
|
11
|
+
* `query(S).rule(r => r.match(...).where(...).select(...))` with
|
|
12
|
+
* string-named domain-typed vars, params typed by use, negation,
|
|
13
|
+
* conditions, aggregates, and stratified recursion via `program()`/`rec` —
|
|
14
|
+
* `db.prepare` as a plain value; the comparison/connective builders are
|
|
15
|
+
* also free exports, and the free names `eq`/`not`/`and`/`or` collide with
|
|
16
|
+
* common host identifiers — import aliasing is the answer; the SDK does
|
|
17
|
+
* not rename for collision-avoidance), and the exhume surface
|
|
11
18
|
* (`Db.exhume` — the one schema-independent read path: the store's
|
|
12
|
-
* self-described shapes and raw facts by name,
|
|
13
|
-
*
|
|
14
|
-
* PRD-03 stub died here as scheduled).
|
|
19
|
+
* self-described shapes and raw facts by name, typed at bare structural
|
|
20
|
+
* values, deliberately schema-free). The raw native bridge is not exported.
|
|
15
21
|
*/
|
|
16
|
-
export type {
|
|
17
|
-
export { span } from "#brand.ts";
|
|
18
|
-
export type { AnyClosed, AxiomRow, Axioms, Closed, ClosedColumn, ClosedCore, ClosedData, ClosedRow, PayloadField } from "#closed.ts";
|
|
22
|
+
export type { AnyClosed, AnySelectedClosed, AxiomRow, Axioms, Closed, ClosedColumn, ClosedCore, ClosedData, ClosedRow, ClosedSelectionInput, PayloadField, SelectedClosed } from "#closed.ts";
|
|
19
23
|
export { closed } from "#closed.ts";
|
|
20
24
|
export type { Count } from "#count.ts";
|
|
21
25
|
export { atLeast, atMost, between, exactly, none } from "#count.ts";
|
|
22
26
|
export type { Abandon, DeclaredKeyFact, DeltaBuild, MemberRelation, OffendingFact, Prepared, ReadScope, Tx, Violation, WitnessedWriteResult, WriteResult } from "#db.ts";
|
|
23
|
-
export { abandon, Db } from "#db.ts";
|
|
27
|
+
export { abandon, Db, ErrNewtypeMismatch } from "#db.ts";
|
|
24
28
|
export type { Exhumed, ExhumedAxiom, ExhumedDescriptor, ExhumedFact, ExhumedField, ExhumedRelation } from "#exhume.ts";
|
|
25
29
|
export { ErrExhumeCorruption, ErrExhumeFormatMismatch, ErrExhumeNoDescriptor } from "#exhume.ts";
|
|
26
|
-
export type { AnyFace, Arity, Face, FaceArityMismatch, FaceData, FaceFields, FaceOwner, FaceSource, OneOf, SameArity } from "#face.ts";
|
|
30
|
+
export type { AnyFace, Arity, Face, FaceArityMismatch, FaceData, FaceFields, FaceOwner, FaceShapeMismatch, FaceShapes, FaceSource, OneOf, OwnerOf, SameArity, SameShapes } from "#face.ts";
|
|
27
31
|
export { on, oneOf } from "#face.ts";
|
|
28
|
-
export type { AnyField, BoolField, BytesField,
|
|
29
|
-
export { bool, bytes, i64, interval, str, u64 } from "#fields.ts";
|
|
32
|
+
export type { AnyField, BoolField, BytesField, ClosedIdField, ClosedRoster, FreshU64Field, I64Field, Infer, IntervalField, IntervalValue, StrField, U64Field } from "#fields.ts";
|
|
33
|
+
export { bool, bytes, i64, interval, span, str, u64 } from "#fields.ts";
|
|
34
|
+
export type { ClassesOf, ClassWall, LawfulStatements, RelationClasses, SchemaClasses } from "#law.ts";
|
|
30
35
|
export { lower, lowerClosed, lowerRelation } from "#lower.ts";
|
|
31
36
|
export type { KeyFact, Minted } from "#marshal.ts";
|
|
32
37
|
export type { FactValue, OccurrenceDrift, ProgramIr, Staleness, StatementKindTag } from "#native.ts";
|
|
33
|
-
export type {
|
|
34
|
-
export { ALLEN, allen, and, covers,
|
|
35
|
-
export type { AnyQuery, Query,
|
|
38
|
+
export type { AnyCond, BindingInput, Cmp, MatchFields, MatchOwner, MatchShape, NotAtom, RecData, RuleData, SelectColumn, Tree } from "#query/atom.ts";
|
|
39
|
+
export { ALLEN, allen, and, covers, eq, ge, gt, le, lt, ne, not, or, pointIn } from "#query/atom.ts";
|
|
40
|
+
export type { AnyQuery, AnyRuleValue, OutputRuleChain, OutputRuleScope, Query, QueryData, QueryParams, QueryRelation, QueryRow, QueryRuleChain, QueryRuleScope, QueryStart, RecRef, RecRuleChain, RecRuleScope, RuleValue, TermOps } from "#query/lower.ts";
|
|
36
41
|
export { lowerQuery, query } from "#query/lower.ts";
|
|
37
|
-
export type {
|
|
38
|
-
export
|
|
39
|
-
export type {
|
|
40
|
-
export {
|
|
42
|
+
export type { ProgramScope, Rec } from "#query/predicate.ts";
|
|
43
|
+
export { program } from "#query/predicate.ts";
|
|
44
|
+
export type { ClassedField, Duration, MaskParam, Param, ParamEntry, ParamsRecord, SetParam, Var, VarsRecord } from "#query/scope.ts";
|
|
45
|
+
export type { Agg, SelectEntry } from "#query/select.ts";
|
|
41
46
|
export type { AnyRelation, AnySelected, Fact, FieldRef, FieldRefs, FieldsShape, FreshKeys, InsertFact, Relation, RelationData, RelationField, RelationFields, Selected, SelectionBinding, SelectionInput } from "#relation.ts";
|
|
42
47
|
export { relation } from "#relation.ts";
|
|
43
48
|
export type { AnySchema, Schema, SchemaRelation, SchemaRelations } from "#schema.ts";
|
|
44
49
|
export { schema } from "#schema.ts";
|
|
45
50
|
export type { FieldSpec, LiteralSetSpec, LiteralSpec, RelationSpec, RowSpec, SchemaSpec, SideSpec, StatementSpec, ValueSpec, ValueTypeSpec, WindowSpec } from "#spec.ts";
|
|
46
51
|
export { renderLiteral, renderLiteralSet, renderWindow } from "#spec.ts";
|
|
47
|
-
export type { KeyStatement, Statement, StatementData } from "#statements.ts";
|
|
52
|
+
export type { ContainedStatement, ContainmentData, KeyData, KeyStatement, Statement, StatementData, WindowData, WindowStatement } from "#statements.ts";
|
|
48
53
|
export { contained, key, mirrors, renderStatement, window } from "#statements.ts";
|
|
49
54
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
package/dist/index.js
CHANGED
|
@@ -1,29 +1,34 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* @bjornpagen/bumbledb — the type-theoretic TypeScript SDK for the
|
|
3
|
-
* bumbledb embedded relational engine. Public surface: the type
|
|
4
|
-
* (
|
|
5
|
-
*
|
|
3
|
+
* bumbledb embedded relational engine. Public surface: the structural type
|
|
4
|
+
* kernel (fields as pure structure, `relation()`, `closed()` — domains are
|
|
5
|
+
* never declared: THE LAWS TYPE THE COLUMNS, `schema()` computing every
|
|
6
|
+
* field's equivalence class FROM the statement list at both tiers), the
|
|
7
|
+
* statement algebra with `schema()` and `SchemaSpec` lowering (PRD-06), the `Db`
|
|
6
8
|
* runtime (path-cached stores, transactions, typed violations, scoped
|
|
7
9
|
* snapshot reads, the witnessed write loop with `abandon` — PRD-07, zero
|
|
8
|
-
* closables), the query surface (Datalog as values:
|
|
9
|
-
*
|
|
10
|
-
*
|
|
10
|
+
* closables), the query surface (Datalog as values, kysely-shaped:
|
|
11
|
+
* `query(S).rule(r => r.match(...).where(...).select(...))` with
|
|
12
|
+
* string-named domain-typed vars, params typed by use, negation,
|
|
13
|
+
* conditions, aggregates, and stratified recursion via `program()`/`rec` —
|
|
14
|
+
* `db.prepare` as a plain value; the comparison/connective builders are
|
|
15
|
+
* also free exports, and the free names `eq`/`not`/`and`/`or` collide with
|
|
16
|
+
* common host identifiers — import aliasing is the answer; the SDK does
|
|
17
|
+
* not rename for collision-avoidance), and the exhume surface
|
|
11
18
|
* (`Db.exhume` — the one schema-independent read path: the store's
|
|
12
|
-
* self-described shapes and raw facts by name,
|
|
13
|
-
*
|
|
14
|
-
* PRD-03 stub died here as scheduled).
|
|
19
|
+
* self-described shapes and raw facts by name, typed at bare structural
|
|
20
|
+
* values, deliberately schema-free). The raw native bridge is not exported.
|
|
15
21
|
*/
|
|
16
|
-
export { span } from "#brand.ts";
|
|
17
22
|
export { closed } from "#closed.ts";
|
|
18
23
|
export { atLeast, atMost, between, exactly, none } from "#count.ts";
|
|
19
|
-
export { abandon, Db } from "#db.ts";
|
|
24
|
+
export { abandon, Db, ErrNewtypeMismatch } from "#db.ts";
|
|
20
25
|
export { ErrExhumeCorruption, ErrExhumeFormatMismatch, ErrExhumeNoDescriptor } from "#exhume.ts";
|
|
21
26
|
export { on, oneOf } from "#face.ts";
|
|
22
|
-
export { bool, bytes, i64, interval, str, u64 } from "#fields.ts";
|
|
27
|
+
export { bool, bytes, i64, interval, span, str, u64 } from "#fields.ts";
|
|
23
28
|
export { lower, lowerClosed, lowerRelation } from "#lower.ts";
|
|
24
|
-
export { ALLEN, allen, and, covers,
|
|
29
|
+
export { ALLEN, allen, and, covers, eq, ge, gt, le, lt, ne, not, or, pointIn } from "#query/atom.ts";
|
|
25
30
|
export { lowerQuery, query } from "#query/lower.ts";
|
|
26
|
-
export {
|
|
31
|
+
export { program } from "#query/predicate.ts";
|
|
27
32
|
export { relation } from "#relation.ts";
|
|
28
33
|
export { schema } from "#schema.ts";
|
|
29
34
|
export { renderLiteral, renderLiteralSet, renderWindow } from "#spec.ts";
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AAgBH,OAAO,EAAE,MAAM,EAAE,MAAM,YAAY,CAAA;AAEnC,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAA;AAcnE,OAAO,EAAE,OAAO,EAAE,EAAE,EAAE,kBAAkB,EAAE,MAAM,QAAQ,CAAA;AASxD,OAAO,EACN,mBAAmB,EACnB,uBAAuB,EACvB,qBAAqB,EACrB,MAAM,YAAY,CAAA;AAiBnB,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,MAAM,UAAU,CAAA;AAepC,OAAO,EAAE,IAAI,EAAE,KAAK,EAAE,GAAG,EAAE,QAAQ,EAAE,IAAI,EAAE,GAAG,EAAE,GAAG,EAAE,MAAM,YAAY,CAAA;AAEvE,OAAO,EAAE,KAAK,EAAE,WAAW,EAAE,aAAa,EAAE,MAAM,WAAW,CAAA;AAuB7D,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,GAAG,EAAE,MAAM,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,GAAG,EAAE,EAAE,EAAE,OAAO,EAAE,MAAM,gBAAgB,CAAA;AAoBpG,OAAO,EAAE,UAAU,EAAE,KAAK,EAAE,MAAM,iBAAiB,CAAA;AAEnD,OAAO,EAAE,OAAO,EAAE,MAAM,qBAAqB,CAAA;AA8B7C,OAAO,EAAE,QAAQ,EAAE,MAAM,cAAc,CAAA;AAEvC,OAAO,EAAE,MAAM,EAAE,MAAM,YAAY,CAAA;AAcnC,OAAO,EAAE,aAAa,EAAE,gBAAgB,EAAE,YAAY,EAAE,MAAM,UAAU,CAAA;AAWxE,OAAO,EAAE,SAAS,EAAE,GAAG,EAAE,OAAO,EAAE,eAAe,EAAE,MAAM,EAAE,MAAM,gBAAgB,CAAA"}
|
package/dist/law.d.ts
ADDED
|
@@ -0,0 +1,224 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The law-typing engine (owner ruling 2026-07-18, "option 2, zero debate"):
|
|
3
|
+
* THE LAWS TYPE THE COLUMNS. Domains are declared nowhere — `schema()`
|
|
4
|
+
* computes every field's domain FROM the statement list, at BOTH the type
|
|
5
|
+
* level (this module's type machinery, reading the statements tuple type)
|
|
6
|
+
* and at runtime (a plain union-find over the same pairs), and the two
|
|
7
|
+
* tiers are the same computation by construction.
|
|
8
|
+
*
|
|
9
|
+
* The three class laws (ratified; implemented exactly):
|
|
10
|
+
*
|
|
11
|
+
* 1. GENERATORS — a `fresh` field is a generator and names its class by
|
|
12
|
+
* its declaration coordinate (`"Account.id"`); a closed relation's
|
|
13
|
+
* synthetic id is a generator named `"Kind.id"`.
|
|
14
|
+
* 2. GENERATOR-LESS classes are named by their least member coordinate
|
|
15
|
+
* in relation-declaration × field-declaration order (readable off the
|
|
16
|
+
* relation record and each member's frozen field list at the VALUE
|
|
17
|
+
* tier — deterministic, pinned forever; the wire reads only this
|
|
18
|
+
* tier). At the TYPE tier the same class is carried as its
|
|
19
|
+
* member-coordinate SET (see {@link ClassOfCoord}): TypeScript's
|
|
20
|
+
* union member order is not observably deterministic, so a type-level
|
|
21
|
+
* least-member pick would drift between compilations — the set is the
|
|
22
|
+
* canonical deterministic spelling, the runtime name is always a
|
|
23
|
+
* member of it, and the join judgment is identical at both tiers.
|
|
24
|
+
* 3. BARE — a field in no law has NO class and pairs only with bare in
|
|
25
|
+
* queries (the deliberate sum-domain pointer stays legal).
|
|
26
|
+
*
|
|
27
|
+
* THE WALL: a class containing more than one generator is a contradiction
|
|
28
|
+
* (two mints cannot share a carrier) — a schema-level COMPILE error (the
|
|
29
|
+
* named, self-locating {@link ClassWall}: which generator coordinates
|
|
30
|
+
* collided, through which paired slots) with a construction-time runtime
|
|
31
|
+
* twin (`computeClasses` throws with the same content, naming the exact
|
|
32
|
+
* statement).
|
|
33
|
+
*
|
|
34
|
+
* Every paired face of the statement tuple unions its positionwise field
|
|
35
|
+
* slots: containment (ψ-selected targets included — a selection changes
|
|
36
|
+
* pairing not at all), the `==` bijection, and window source/target pairs.
|
|
37
|
+
* `key()` statements pair nothing (an FD constrains one relation's own
|
|
38
|
+
* rows; it identifies no carriers).
|
|
39
|
+
*
|
|
40
|
+
* The type tier reads pairs off the statement types' exact face data, so
|
|
41
|
+
* spell the statement list INLINE in `schema()` (the `const` type
|
|
42
|
+
* parameter keeps the tuple precise). A widened `Statement[]` list
|
|
43
|
+
* degrades the TYPE tier to generators-only (no pair is readable off a
|
|
44
|
+
* widened type) — the runtime map stays complete and authoritative, and
|
|
45
|
+
* the wire lowering reads only the runtime map. Every loop below is
|
|
46
|
+
* tail-recursive with an accumulator, so the machinery rides TypeScript's
|
|
47
|
+
* tail-recursion elimination at primer scale (~40 relations, ~200 slots,
|
|
48
|
+
* ~123 statements); should a schema ever exceed the compiler's limits, tsc
|
|
49
|
+
* fails LOUDLY with its own instantiation-depth error — the map is never
|
|
50
|
+
* silently widened.
|
|
51
|
+
*/
|
|
52
|
+
import type { AnyClosed } from "#closed.ts";
|
|
53
|
+
import type { FaceData } from "#face.ts";
|
|
54
|
+
import type { AnyRelation, RelationFields } from "#relation.ts";
|
|
55
|
+
import type { SchemaRelation, SchemaRelations } from "#schema.ts";
|
|
56
|
+
import { type Statement } from "#statements.ts";
|
|
57
|
+
/** One relation's computed classes: field name → class name, `undefined` = bare. */
|
|
58
|
+
type RelationClasses = {
|
|
59
|
+
readonly [field: string]: string | undefined;
|
|
60
|
+
};
|
|
61
|
+
/**
|
|
62
|
+
* The class map a schema carries — relation name → field name → the
|
|
63
|
+
* computed class name (`undefined` = bare). THE domain authority: queries
|
|
64
|
+
* and the wire lowering read domains from here and nowhere else. The wide
|
|
65
|
+
* shape is the default every `Schema`-generic surface accepts; a concrete
|
|
66
|
+
* schema's `classes` property carries the EXACT computed map
|
|
67
|
+
* ({@link ClassesOf}) at the type level and the frozen runtime twin
|
|
68
|
+
* (`computeClasses`) at the value level — one property, two tiers, one
|
|
69
|
+
* computation.
|
|
70
|
+
*/
|
|
71
|
+
type SchemaClasses = {
|
|
72
|
+
readonly [relation: string]: RelationClasses;
|
|
73
|
+
};
|
|
74
|
+
/** Looks one relation's class record up in a schema's class map (absent relation = no classes). */
|
|
75
|
+
type ClassRecordOf<Classes extends SchemaClasses, N extends string> = N extends keyof Classes ? Classes[N] : Record<never, never>;
|
|
76
|
+
/** Looks one field's class up in a relation's class record (absent field = bare). */
|
|
77
|
+
type ClassLookup<CR, K> = K extends keyof CR ? CR[K] & (string | undefined) : undefined;
|
|
78
|
+
/** A closed member's declared payload-column record (`never` on ordinary relations). */
|
|
79
|
+
type MemberColumns<M> = M extends AnyClosed ? M["columns"] : never;
|
|
80
|
+
/** The field names of one schema member: a relation's declared fields; a closed relation's sealed `id` + columns. */
|
|
81
|
+
type MemberFieldNames<M extends SchemaRelation> = M extends AnyClosed ? "id" | (keyof MemberColumns<M> & string) : M extends AnyRelation ? keyof RelationFields<M> & string : never;
|
|
82
|
+
/** The fresh-marked field names of one field block. */
|
|
83
|
+
type FreshFieldNames<Fields> = {
|
|
84
|
+
[F in keyof Fields & string]: Fields[F] extends {
|
|
85
|
+
readonly fresh: true;
|
|
86
|
+
} ? F : never;
|
|
87
|
+
}[keyof Fields & string];
|
|
88
|
+
/** One member's generator coordinates: fresh fields; a closed relation's synthetic id. */
|
|
89
|
+
type MemberGenerators<N extends string, M extends SchemaRelation> = M extends AnyClosed ? `${N}.id` : M extends AnyRelation ? `${N}.${FreshFieldNames<RelationFields<M>>}` : never;
|
|
90
|
+
/** Every generator coordinate of a relation record (a union). */
|
|
91
|
+
type GeneratorsOf<Rels extends SchemaRelations> = {
|
|
92
|
+
[N in keyof Rels & string]: MemberGenerators<N, Rels[N]>;
|
|
93
|
+
}[keyof Rels & string];
|
|
94
|
+
/** One paired-slot pair of coordinates. */
|
|
95
|
+
type Pair = readonly [string, string];
|
|
96
|
+
/** A list of slot pairs. */
|
|
97
|
+
type PairList = readonly Pair[];
|
|
98
|
+
/** Zips two faces' projections into coordinate pairs, positionwise. */
|
|
99
|
+
type ZipCoords<SN extends string, SP extends readonly string[], TN extends string, TP extends readonly string[], Acc extends PairList = []> = SP extends readonly [infer SH extends string, ...infer ST extends readonly string[]] ? TP extends readonly [infer TH extends string, ...infer TT extends readonly string[]] ? ZipCoords<SN, ST, TN, TT, readonly [...Acc, readonly [`${SN}.${SH}`, `${TN}.${TH}`]]> : Acc : Acc;
|
|
100
|
+
/**
|
|
101
|
+
* One statement's slot pairs: containments (bidirectional included — pair
|
|
102
|
+
* unions are symmetric) and windows pair their two faces positionwise;
|
|
103
|
+
* `key()` pairs nothing. A widened face (owner name or projection no
|
|
104
|
+
* longer literal) contributes nothing — the runtime map stays complete.
|
|
105
|
+
*/
|
|
106
|
+
type StatementPairs<St extends Statement> = St["data"] extends {
|
|
107
|
+
readonly source: infer S extends FaceData;
|
|
108
|
+
readonly target: infer T extends FaceData;
|
|
109
|
+
} ? string extends S["owner"]["name"] ? [] : string extends T["owner"]["name"] ? [] : ZipCoords<S["owner"]["name"], S["projection"], T["owner"]["name"], T["projection"]> : [];
|
|
110
|
+
/** Every slot pair of a statements tuple, in written order. */
|
|
111
|
+
type PairsOf<Stmts extends readonly Statement[], Acc extends PairList = []> = Stmts extends readonly [
|
|
112
|
+
infer H extends Statement,
|
|
113
|
+
...infer T extends readonly Statement[]
|
|
114
|
+
] ? PairsOf<T, readonly [...Acc, ...StatementPairs<H>]> : Acc;
|
|
115
|
+
/** The component (a union of coordinates) containing `X`, or `never` when `X` is in none. */
|
|
116
|
+
type CompOf<Comps extends readonly string[], X extends string> = Comps extends readonly [
|
|
117
|
+
infer H extends string,
|
|
118
|
+
...infer T extends readonly string[]
|
|
119
|
+
] ? [X] extends [H] ? H : CompOf<T, X> : never;
|
|
120
|
+
/** Rebuilds the component list without the component `C` (components are disjoint; identity is mutual extension). */
|
|
121
|
+
type WithoutComp<Comps extends readonly string[], C extends string, Acc extends readonly string[] = []> = Comps extends readonly [infer H extends string, ...infer T extends readonly string[]] ? [H, C] extends [C, H] ? WithoutComp<T, C, Acc> : WithoutComp<T, C, readonly [...Acc, H]> : Acc;
|
|
122
|
+
/** Unions one pair into the component list: create, extend, keep, or merge. */
|
|
123
|
+
type AddPair<Comps extends readonly string[], A extends string, B extends string> = [
|
|
124
|
+
CompOf<Comps, A>,
|
|
125
|
+
CompOf<Comps, B>
|
|
126
|
+
] extends [infer CA extends string, infer CB extends string] ? [CA] extends [never] ? [CB] extends [never] ? readonly [...Comps, A | B] : readonly [...WithoutComp<Comps, CB>, CB | A] : [CB] extends [never] ? readonly [...WithoutComp<Comps, CA>, CA | B] : [CA, CB] extends [CB, CA] ? Comps : readonly [...WithoutComp<WithoutComp<Comps, CA>, CB>, CA | CB] : Comps;
|
|
127
|
+
/** Folds every pair into connected components (tail-recursive — the whole walk is one loop). */
|
|
128
|
+
type BuildComps<Pairs extends PairList, Comps extends readonly string[] = readonly []> = Pairs extends readonly [
|
|
129
|
+
infer P extends Pair,
|
|
130
|
+
...infer T extends PairList
|
|
131
|
+
] ? BuildComps<T, AddPair<Comps, P[0], P[1]>> : Comps;
|
|
132
|
+
/** Whether a union holds two or more members (`All` captures the whole union across distribution). */
|
|
133
|
+
type IsMulti<U, All = U> = [U] extends [never] ? false : U extends unknown ? ([All] extends [U] ? false : true) : never;
|
|
134
|
+
/**
|
|
135
|
+
* The named, self-locating compile verdict of the one-generator wall: the
|
|
136
|
+
* generator coordinates that collided and the paired slots (rendered
|
|
137
|
+
* `A.x ~ B.y`, statement order) whose chain unified them. Intersected into
|
|
138
|
+
* `schema()`'s statements parameter, so the error lands ON the statement
|
|
139
|
+
* list with this key naming the law. The runtime twin throws from
|
|
140
|
+
* `computeClasses` with the same content, naming the exact statement.
|
|
141
|
+
*/
|
|
142
|
+
interface ClassWall<Generators extends string, Chain extends readonly string[]> {
|
|
143
|
+
readonly "schema class wall — the statements unify two generators into one class (two mints cannot share a carrier)": {
|
|
144
|
+
readonly generators: Generators;
|
|
145
|
+
readonly through: Chain;
|
|
146
|
+
};
|
|
147
|
+
}
|
|
148
|
+
/** The paired slots lying inside component `C`, rendered — the wall's self-locating chain. */
|
|
149
|
+
type ChainOf<Pairs extends PairList, C extends string, Acc extends readonly string[] = []> = Pairs extends readonly [
|
|
150
|
+
infer P extends Pair,
|
|
151
|
+
...infer T extends PairList
|
|
152
|
+
] ? [P[0]] extends [C] ? ChainOf<T, C, readonly [...Acc, `${P[0]} ~ ${P[1]}`]> : ChainOf<T, C, Acc> : Acc;
|
|
153
|
+
/** Scans the components for a two-generator class: `unknown` (lawful) or the {@link ClassWall}. */
|
|
154
|
+
type WallScan<Comps extends readonly string[], Gens extends string, Pairs extends PairList> = Comps extends readonly [
|
|
155
|
+
infer H extends string,
|
|
156
|
+
...infer T extends readonly string[]
|
|
157
|
+
] ? true extends IsMulti<Extract<H, Gens>> ? ClassWall<Extract<H, Gens>, ChainOf<Pairs, H>> : WallScan<T, Gens, Pairs> : unknown;
|
|
158
|
+
/**
|
|
159
|
+
* The one-generator-per-class law as a constraint: resolves to `unknown`
|
|
160
|
+
* (a no-op intersection into the statements parameter) when the statement
|
|
161
|
+
* list is lawful, and to the named {@link ClassWall} otherwise.
|
|
162
|
+
*/
|
|
163
|
+
type LawfulStatements<Rels extends SchemaRelations, Stmts extends readonly Statement[]> = WallScan<BuildComps<PairsOf<Stmts>>, GeneratorsOf<Rels>, PairsOf<Stmts>>;
|
|
164
|
+
/**
|
|
165
|
+
* One coordinate's class per the three laws, at the TYPE tier: its
|
|
166
|
+
* component's single generator (the exact literal — a generator names its
|
|
167
|
+
* class); a component-less generator is its own class; a component-less
|
|
168
|
+
* non-generator is bare (`undefined`); and a GENERATOR-LESS component is
|
|
169
|
+
* carried as its member-coordinate SET (the union of the component's
|
|
170
|
+
* coordinates — a canonical, deterministic type). The set REPRESENTS the
|
|
171
|
+
* runtime's least-member class name faithfully: the runtime name is by
|
|
172
|
+
* construction a member, two slots share a class exactly when their sets
|
|
173
|
+
* are identical (so `JoinOk` judges identically at both tiers), and bare
|
|
174
|
+
* never equals a set. The least-member PICK itself is deliberately not
|
|
175
|
+
* made at the type tier: TypeScript's union member order is not observably
|
|
176
|
+
* deterministic (the same key union tuples differently across checking
|
|
177
|
+
* contexts — measured, not conjectured), so any type-level "least in
|
|
178
|
+
* declaration order" would drift between compilations; the ratified
|
|
179
|
+
* declaration-order name lives at the VALUE tier (`computeClasses`), which
|
|
180
|
+
* is the only tier the wire reads.
|
|
181
|
+
*/
|
|
182
|
+
type ClassOfCoord<Comps extends readonly string[], Gens extends string, C extends string> = [CompOf<Comps, C>] extends [
|
|
183
|
+
infer M extends string
|
|
184
|
+
] ? [M] extends [never] ? [C] extends [Gens] ? C : undefined : [Extract<M, Gens>] extends [infer G extends string] ? [G] extends [never] ? M : G : never : never;
|
|
185
|
+
/** The computed class map over precomputed components/generators. */
|
|
186
|
+
type ComputedClasses<Rels extends SchemaRelations, Comps extends readonly string[], Gens extends string> = {
|
|
187
|
+
readonly [N in keyof Rels & string]: {
|
|
188
|
+
readonly [F in MemberFieldNames<Rels[N]>]: ClassOfCoord<Comps, Gens, `${N}.${F}`>;
|
|
189
|
+
};
|
|
190
|
+
};
|
|
191
|
+
/**
|
|
192
|
+
* THE type-level class map of a schema: relation name → field name → the
|
|
193
|
+
* law-computed class (`undefined` = bare) — what `schema()` returns as the
|
|
194
|
+
* `classes` property's type, and what query joins compare. Generator
|
|
195
|
+
* classes are exact name literals; generator-less classes are their
|
|
196
|
+
* member-coordinate sets (see {@link ClassOfCoord} — the runtime map's
|
|
197
|
+
* least-member name is always a member, so the property type is honest).
|
|
198
|
+
*/
|
|
199
|
+
type ClassesOf<Rels extends SchemaRelations, Stmts extends readonly Statement[]> = ComputedClasses<Rels, BuildComps<PairsOf<Stmts>>, GeneratorsOf<Rels>>;
|
|
200
|
+
/**
|
|
201
|
+
* Computes the class map — the runtime twin of {@link ClassesOf}, the SAME
|
|
202
|
+
* computation as a plain union-find: every paired face's positionwise slot
|
|
203
|
+
* pairs union their coordinates; a fresh field or closed id is a generator
|
|
204
|
+
* naming its class; a generator-less class is named by its least member in
|
|
205
|
+
* relation-declaration × field-declaration order; a slot in no law is bare
|
|
206
|
+
* (`undefined`). The one-generator wall throws HERE, naming the two
|
|
207
|
+
* coordinates and the statement that unified them — the same content the
|
|
208
|
+
* compile-tier {@link ClassWall} carries. The returned map is frozen, own
|
|
209
|
+
* properties throughout (arbitrary field names ride own-property
|
|
210
|
+
* definition, never the object protocol).
|
|
211
|
+
*/
|
|
212
|
+
declare function computeClasses(name: string, relations: SchemaRelations, statements: readonly Statement[]): SchemaClasses;
|
|
213
|
+
/**
|
|
214
|
+
* The trusted seam of the class-map mint (the `refsComplete` pattern): the
|
|
215
|
+
* checkable facts — one own record per declared relation, one own entry
|
|
216
|
+
* per declared field (the closed sealed shape's `id` included), everything
|
|
217
|
+
* frozen — are verified before the runtime map is admitted at the computed
|
|
218
|
+
* {@link ClassesOf} type. The NAME agreement of the two tiers is pinned by
|
|
219
|
+
* the generated fixture probes (the runtime/type diff check).
|
|
220
|
+
*/
|
|
221
|
+
declare function classesComplete<Classes extends SchemaClasses>(classes: SchemaClasses, relations: SchemaRelations): classes is Classes;
|
|
222
|
+
export type { ClassesOf, ClassLookup, ClassRecordOf, ClassWall, LawfulStatements, RelationClasses, SchemaClasses };
|
|
223
|
+
export { classesComplete, computeClasses };
|
|
224
|
+
//# sourceMappingURL=law.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"law.d.ts","sourceRoot":"","sources":["../src/law.ts"],"names":[],"mappings":"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"}
|
package/dist/law.js
ADDED
|
@@ -0,0 +1,224 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The law-typing engine (owner ruling 2026-07-18, "option 2, zero debate"):
|
|
3
|
+
* THE LAWS TYPE THE COLUMNS. Domains are declared nowhere — `schema()`
|
|
4
|
+
* computes every field's domain FROM the statement list, at BOTH the type
|
|
5
|
+
* level (this module's type machinery, reading the statements tuple type)
|
|
6
|
+
* and at runtime (a plain union-find over the same pairs), and the two
|
|
7
|
+
* tiers are the same computation by construction.
|
|
8
|
+
*
|
|
9
|
+
* The three class laws (ratified; implemented exactly):
|
|
10
|
+
*
|
|
11
|
+
* 1. GENERATORS — a `fresh` field is a generator and names its class by
|
|
12
|
+
* its declaration coordinate (`"Account.id"`); a closed relation's
|
|
13
|
+
* synthetic id is a generator named `"Kind.id"`.
|
|
14
|
+
* 2. GENERATOR-LESS classes are named by their least member coordinate
|
|
15
|
+
* in relation-declaration × field-declaration order (readable off the
|
|
16
|
+
* relation record and each member's frozen field list at the VALUE
|
|
17
|
+
* tier — deterministic, pinned forever; the wire reads only this
|
|
18
|
+
* tier). At the TYPE tier the same class is carried as its
|
|
19
|
+
* member-coordinate SET (see {@link ClassOfCoord}): TypeScript's
|
|
20
|
+
* union member order is not observably deterministic, so a type-level
|
|
21
|
+
* least-member pick would drift between compilations — the set is the
|
|
22
|
+
* canonical deterministic spelling, the runtime name is always a
|
|
23
|
+
* member of it, and the join judgment is identical at both tiers.
|
|
24
|
+
* 3. BARE — a field in no law has NO class and pairs only with bare in
|
|
25
|
+
* queries (the deliberate sum-domain pointer stays legal).
|
|
26
|
+
*
|
|
27
|
+
* THE WALL: a class containing more than one generator is a contradiction
|
|
28
|
+
* (two mints cannot share a carrier) — a schema-level COMPILE error (the
|
|
29
|
+
* named, self-locating {@link ClassWall}: which generator coordinates
|
|
30
|
+
* collided, through which paired slots) with a construction-time runtime
|
|
31
|
+
* twin (`computeClasses` throws with the same content, naming the exact
|
|
32
|
+
* statement).
|
|
33
|
+
*
|
|
34
|
+
* Every paired face of the statement tuple unions its positionwise field
|
|
35
|
+
* slots: containment (ψ-selected targets included — a selection changes
|
|
36
|
+
* pairing not at all), the `==` bijection, and window source/target pairs.
|
|
37
|
+
* `key()` statements pair nothing (an FD constrains one relation's own
|
|
38
|
+
* rows; it identifies no carriers).
|
|
39
|
+
*
|
|
40
|
+
* The type tier reads pairs off the statement types' exact face data, so
|
|
41
|
+
* spell the statement list INLINE in `schema()` (the `const` type
|
|
42
|
+
* parameter keeps the tuple precise). A widened `Statement[]` list
|
|
43
|
+
* degrades the TYPE tier to generators-only (no pair is readable off a
|
|
44
|
+
* widened type) — the runtime map stays complete and authoritative, and
|
|
45
|
+
* the wire lowering reads only the runtime map. Every loop below is
|
|
46
|
+
* tail-recursive with an accumulator, so the machinery rides TypeScript's
|
|
47
|
+
* tail-recursion elimination at primer scale (~40 relations, ~200 slots,
|
|
48
|
+
* ~123 statements); should a schema ever exceed the compiler's limits, tsc
|
|
49
|
+
* fails LOUDLY with its own instantiation-depth error — the map is never
|
|
50
|
+
* silently widened.
|
|
51
|
+
*/
|
|
52
|
+
import * as errors from "@superbuilders/errors";
|
|
53
|
+
import { renderStatement } from "#statements.ts";
|
|
54
|
+
/** Reads every member's coordinates off the relation record, declaration order throughout. */
|
|
55
|
+
function memberCoords(relations) {
|
|
56
|
+
const out = [];
|
|
57
|
+
for (const [relationName, member] of Object.entries(relations)) {
|
|
58
|
+
if ("handles" in member.data) {
|
|
59
|
+
const fields = [
|
|
60
|
+
{ name: "id", generator: true },
|
|
61
|
+
...member.data.columns.map(function columnCoord(column) {
|
|
62
|
+
return { name: column.name, generator: false };
|
|
63
|
+
})
|
|
64
|
+
];
|
|
65
|
+
out.push({ relation: relationName, fields });
|
|
66
|
+
continue;
|
|
67
|
+
}
|
|
68
|
+
const fields = member.data.fields.map(function fieldCoord(declared) {
|
|
69
|
+
return { name: declared.name, generator: "fresh" in declared.field && declared.field.fresh === true };
|
|
70
|
+
});
|
|
71
|
+
out.push({ relation: relationName, fields });
|
|
72
|
+
}
|
|
73
|
+
return out;
|
|
74
|
+
}
|
|
75
|
+
/** Builds the union-find. */
|
|
76
|
+
function makeUnionFind() {
|
|
77
|
+
const parent = new Map();
|
|
78
|
+
const generators = new Map();
|
|
79
|
+
function find(coord) {
|
|
80
|
+
const at = parent.get(coord);
|
|
81
|
+
if (at === undefined) {
|
|
82
|
+
parent.set(coord, coord);
|
|
83
|
+
return coord;
|
|
84
|
+
}
|
|
85
|
+
if (at === coord) {
|
|
86
|
+
return coord;
|
|
87
|
+
}
|
|
88
|
+
const root = find(at);
|
|
89
|
+
parent.set(coord, root);
|
|
90
|
+
return root;
|
|
91
|
+
}
|
|
92
|
+
return {
|
|
93
|
+
find,
|
|
94
|
+
union(a, b) {
|
|
95
|
+
const rootA = find(a);
|
|
96
|
+
const rootB = find(b);
|
|
97
|
+
if (rootA === rootB) {
|
|
98
|
+
return rootA;
|
|
99
|
+
}
|
|
100
|
+
parent.set(rootB, rootA);
|
|
101
|
+
const merged = [...(generators.get(rootA) ?? []), ...(generators.get(rootB) ?? [])];
|
|
102
|
+
generators.delete(rootB);
|
|
103
|
+
if (merged.length > 0) {
|
|
104
|
+
generators.set(rootA, merged);
|
|
105
|
+
}
|
|
106
|
+
return rootA;
|
|
107
|
+
},
|
|
108
|
+
generatorsOf(root) {
|
|
109
|
+
return generators.get(root) ?? [];
|
|
110
|
+
},
|
|
111
|
+
markGenerator(coord) {
|
|
112
|
+
const root = find(coord);
|
|
113
|
+
generators.set(root, [...(generators.get(root) ?? []), coord]);
|
|
114
|
+
}
|
|
115
|
+
};
|
|
116
|
+
}
|
|
117
|
+
/** The paired faces of one statement, or undefined for a key (an FD pairs nothing). */
|
|
118
|
+
function statementFaces(statement) {
|
|
119
|
+
const data = statement.data;
|
|
120
|
+
if (data.kind === "key") {
|
|
121
|
+
return undefined;
|
|
122
|
+
}
|
|
123
|
+
return [data.source, data.target];
|
|
124
|
+
}
|
|
125
|
+
/**
|
|
126
|
+
* Computes the class map — the runtime twin of {@link ClassesOf}, the SAME
|
|
127
|
+
* computation as a plain union-find: every paired face's positionwise slot
|
|
128
|
+
* pairs union their coordinates; a fresh field or closed id is a generator
|
|
129
|
+
* naming its class; a generator-less class is named by its least member in
|
|
130
|
+
* relation-declaration × field-declaration order; a slot in no law is bare
|
|
131
|
+
* (`undefined`). The one-generator wall throws HERE, naming the two
|
|
132
|
+
* coordinates and the statement that unified them — the same content the
|
|
133
|
+
* compile-tier {@link ClassWall} carries. The returned map is frozen, own
|
|
134
|
+
* properties throughout (arbitrary field names ride own-property
|
|
135
|
+
* definition, never the object protocol).
|
|
136
|
+
*/
|
|
137
|
+
function computeClasses(name, relations, statements) {
|
|
138
|
+
const members = memberCoords(relations);
|
|
139
|
+
const uf = makeUnionFind();
|
|
140
|
+
const paired = new Set();
|
|
141
|
+
const generatorSet = new Set();
|
|
142
|
+
for (const member of members) {
|
|
143
|
+
for (const field of member.fields) {
|
|
144
|
+
const coord = `${member.relation}.${field.name}`;
|
|
145
|
+
uf.find(coord);
|
|
146
|
+
if (field.generator) {
|
|
147
|
+
generatorSet.add(coord);
|
|
148
|
+
uf.markGenerator(coord);
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
for (const statement of statements) {
|
|
153
|
+
const faces = statementFaces(statement);
|
|
154
|
+
if (faces === undefined) {
|
|
155
|
+
continue;
|
|
156
|
+
}
|
|
157
|
+
const [source, target] = faces;
|
|
158
|
+
source.projection.forEach(function unionSlot(fieldName, position) {
|
|
159
|
+
const targetField = target.projection[position];
|
|
160
|
+
if (targetField === undefined) {
|
|
161
|
+
return;
|
|
162
|
+
}
|
|
163
|
+
const coordA = `${source.owner.name}.${fieldName}`;
|
|
164
|
+
const coordB = `${target.owner.name}.${targetField}`;
|
|
165
|
+
paired.add(coordA);
|
|
166
|
+
paired.add(coordB);
|
|
167
|
+
const root = uf.union(coordA, coordB);
|
|
168
|
+
const gens = uf.generatorsOf(root);
|
|
169
|
+
if (gens.length > 1) {
|
|
170
|
+
throw errors.new(`schema ${name}: the statements unify two generators into one class — ${gens.join(" and ")} (two mints cannot share a carrier) — ${renderStatement(statement)}`);
|
|
171
|
+
}
|
|
172
|
+
});
|
|
173
|
+
}
|
|
174
|
+
const names = new Map();
|
|
175
|
+
for (const member of members) {
|
|
176
|
+
for (const field of member.fields) {
|
|
177
|
+
const coord = `${member.relation}.${field.name}`;
|
|
178
|
+
const root = uf.find(coord);
|
|
179
|
+
if (!names.has(root)) {
|
|
180
|
+
const gens = uf.generatorsOf(root);
|
|
181
|
+
names.set(root, gens[0] ?? coord);
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
const classes = {};
|
|
186
|
+
for (const member of members) {
|
|
187
|
+
const record = {};
|
|
188
|
+
for (const field of member.fields) {
|
|
189
|
+
const coord = `${member.relation}.${field.name}`;
|
|
190
|
+
const classed = paired.has(coord) || generatorSet.has(coord);
|
|
191
|
+
Object.defineProperty(record, field.name, {
|
|
192
|
+
value: classed ? names.get(uf.find(coord)) : undefined,
|
|
193
|
+
enumerable: true
|
|
194
|
+
});
|
|
195
|
+
}
|
|
196
|
+
Object.freeze(record);
|
|
197
|
+
Object.defineProperty(classes, member.relation, { value: record, enumerable: true });
|
|
198
|
+
}
|
|
199
|
+
return Object.freeze(classes);
|
|
200
|
+
}
|
|
201
|
+
/**
|
|
202
|
+
* The trusted seam of the class-map mint (the `refsComplete` pattern): the
|
|
203
|
+
* checkable facts — one own record per declared relation, one own entry
|
|
204
|
+
* per declared field (the closed sealed shape's `id` included), everything
|
|
205
|
+
* frozen — are verified before the runtime map is admitted at the computed
|
|
206
|
+
* {@link ClassesOf} type. The NAME agreement of the two tiers is pinned by
|
|
207
|
+
* the generated fixture probes (the runtime/type diff check).
|
|
208
|
+
*/
|
|
209
|
+
function classesComplete(classes, relations) {
|
|
210
|
+
if (!Object.isFrozen(classes)) {
|
|
211
|
+
return false;
|
|
212
|
+
}
|
|
213
|
+
return memberCoords(relations).every(function relationMinted(member) {
|
|
214
|
+
const record = classes[member.relation];
|
|
215
|
+
if (record === undefined || !Object.isFrozen(record)) {
|
|
216
|
+
return false;
|
|
217
|
+
}
|
|
218
|
+
return member.fields.every(function fieldMinted(field) {
|
|
219
|
+
return Object.hasOwn(record, field.name);
|
|
220
|
+
});
|
|
221
|
+
});
|
|
222
|
+
}
|
|
223
|
+
export { classesComplete, computeClasses };
|
|
224
|
+
//# sourceMappingURL=law.js.map
|