@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.
Files changed (112) hide show
  1. package/COOKBOOK.md +1450 -0
  2. package/README.md +69 -30
  3. package/dist/closed.d.ts +157 -38
  4. package/dist/closed.d.ts.map +1 -1
  5. package/dist/closed.js +232 -47
  6. package/dist/closed.js.map +1 -1
  7. package/dist/count.d.ts +64 -17
  8. package/dist/count.d.ts.map +1 -1
  9. package/dist/count.js +37 -14
  10. package/dist/count.js.map +1 -1
  11. package/dist/db.d.ts +27 -8
  12. package/dist/db.d.ts.map +1 -1
  13. package/dist/db.js +33 -10
  14. package/dist/db.js.map +1 -1
  15. package/dist/exhume.d.ts +12 -11
  16. package/dist/exhume.d.ts.map +1 -1
  17. package/dist/exhume.js +7 -6
  18. package/dist/exhume.js.map +1 -1
  19. package/dist/face.d.ts +135 -30
  20. package/dist/face.d.ts.map +1 -1
  21. package/dist/face.js +44 -19
  22. package/dist/face.js.map +1 -1
  23. package/dist/fields.d.ts +130 -130
  24. package/dist/fields.d.ts.map +1 -1
  25. package/dist/fields.js +60 -94
  26. package/dist/fields.js.map +1 -1
  27. package/dist/index.d.ts +29 -24
  28. package/dist/index.d.ts.map +1 -1
  29. package/dist/index.js +19 -14
  30. package/dist/index.js.map +1 -1
  31. package/dist/law.d.ts +224 -0
  32. package/dist/law.d.ts.map +1 -0
  33. package/dist/law.js +224 -0
  34. package/dist/law.js.map +1 -0
  35. package/dist/lower.d.ts +17 -7
  36. package/dist/lower.d.ts.map +1 -1
  37. package/dist/lower.js +66 -24
  38. package/dist/lower.js.map +1 -1
  39. package/dist/marshal.d.ts +36 -21
  40. package/dist/marshal.d.ts.map +1 -1
  41. package/dist/marshal.js +41 -25
  42. package/dist/marshal.js.map +1 -1
  43. package/dist/native.d.ts +6 -2
  44. package/dist/native.d.ts.map +1 -1
  45. package/dist/native.js +2 -2
  46. package/dist/native.js.map +1 -1
  47. package/dist/query/atom.d.ts +370 -174
  48. package/dist/query/atom.d.ts.map +1 -1
  49. package/dist/query/atom.js +75 -172
  50. package/dist/query/atom.js.map +1 -1
  51. package/dist/query/lower.d.ts +312 -109
  52. package/dist/query/lower.d.ts.map +1 -1
  53. package/dist/query/lower.js +906 -387
  54. package/dist/query/lower.js.map +1 -1
  55. package/dist/query/predicate.d.ts +70 -88
  56. package/dist/query/predicate.d.ts.map +1 -1
  57. package/dist/query/predicate.js +118 -72
  58. package/dist/query/predicate.js.map +1 -1
  59. package/dist/query/run.d.ts +19 -16
  60. package/dist/query/run.d.ts.map +1 -1
  61. package/dist/query/run.js +31 -24
  62. package/dist/query/run.js.map +1 -1
  63. package/dist/query/scope.d.ts +178 -127
  64. package/dist/query/scope.d.ts.map +1 -1
  65. package/dist/query/scope.js +111 -108
  66. package/dist/query/scope.js.map +1 -1
  67. package/dist/query/select.d.ts +102 -80
  68. package/dist/query/select.d.ts.map +1 -1
  69. package/dist/query/select.js +39 -34
  70. package/dist/query/select.js.map +1 -1
  71. package/dist/relation.d.ts +48 -38
  72. package/dist/relation.d.ts.map +1 -1
  73. package/dist/relation.js +24 -19
  74. package/dist/relation.js.map +1 -1
  75. package/dist/schema.d.ts +41 -3
  76. package/dist/schema.d.ts.map +1 -1
  77. package/dist/schema.js +34 -9
  78. package/dist/schema.js.map +1 -1
  79. package/dist/spec.d.ts +7 -5
  80. package/dist/spec.d.ts.map +1 -1
  81. package/dist/spec.js.map +1 -1
  82. package/dist/statements.d.ts +91 -36
  83. package/dist/statements.d.ts.map +1 -1
  84. package/dist/statements.js +42 -12
  85. package/dist/statements.js.map +1 -1
  86. package/package.json +4 -3
  87. package/src/closed.ts +448 -95
  88. package/src/count.ts +112 -18
  89. package/src/db.ts +45 -17
  90. package/src/exhume.ts +12 -11
  91. package/src/face.ts +211 -41
  92. package/src/fields.ts +199 -234
  93. package/src/index.ts +78 -61
  94. package/src/law.ts +519 -0
  95. package/src/lower.ts +82 -27
  96. package/src/marshal.ts +48 -30
  97. package/src/native.ts +8 -4
  98. package/src/query/atom.ts +525 -374
  99. package/src/query/lower.ts +1469 -538
  100. package/src/query/predicate.ts +208 -161
  101. package/src/query/run.ts +35 -25
  102. package/src/query/scope.ts +264 -218
  103. package/src/query/select.ts +168 -93
  104. package/src/relation.ts +47 -47
  105. package/src/schema.ts +69 -18
  106. package/src/spec.ts +7 -5
  107. package/src/statements.ts +124 -41
  108. package/dist/brand.d.ts +0 -59
  109. package/dist/brand.d.ts.map +0 -1
  110. package/dist/brand.js +0 -47
  111. package/dist/brand.js.map +0 -1
  112. 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 kernel
4
- * (brands, fields, `relation()`, `closed()` — PRD-05), the statement
5
- * algebra with `schema()` and `SchemaSpec` lowering (PRD-06), the `Db`
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: scoped vars/params,
9
- * atoms, negation, conditions, aggregates, engine recursion via predicates,
10
- * `db.prepare` as a plain value PRD-08), and the exhume surface
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, deliberately untyped
13
- * course-serialization PRD-02). The raw native bridge is not exported (the
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 { Brand, Interval, IntervalValue } from "#brand.ts";
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, BytesNewtype, ClosedIdField, ClosedRoster, Field, FieldData, FieldValue, FreshU64Newtype, I64Field, I64Newtype, Infer, IntervalField, IntervalNewtype, StrField, U64Field, U64Newtype } from "#fields.ts";
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 { AnyBodyItem, AnyCondition, ComparisonItem, ConditionTreeItem, Duration, MatchAtom, MatchInput, TermInput } from "#query/atom.ts";
34
- export { ALLEN, allen, and, covers, duration, ge, gt, is, le, lt, match, ne, not, or } from "#query/atom.ts";
35
- export type { AnyQuery, Query, QueryBuild, QueryParams, QueryRow, Scope } from "#query/lower.ts";
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 { Predicate, PredicateBindings, PredicateRuleInput, PredicateSelf } from "#query/predicate.ts";
38
- export type { MaskParam, Param, ParamSet, ParamsRecord, Var } from "#query/scope.ts";
39
- export type { Aggregate, RowOf, SelectShape } from "#query/select.ts";
40
- export { argmax, argmin, count, countDistinct, max, min, pack, sum } from "#query/select.ts";
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
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
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 kernel
4
- * (brands, fields, `relation()`, `closed()` — PRD-05), the statement
5
- * algebra with `schema()` and `SchemaSpec` lowering (PRD-06), the `Db`
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: scoped vars/params,
9
- * atoms, negation, conditions, aggregates, engine recursion via predicates,
10
- * `db.prepare` as a plain value PRD-08), and the exhume surface
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, deliberately untyped
13
- * course-serialization PRD-02). The raw native bridge is not exported (the
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, duration, ge, gt, is, le, lt, match, ne, not, or } from "#query/atom.ts";
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 { argmax, argmin, count, countDistinct, max, min, pack, sum } from "#query/select.ts";
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;;;;;;;;;;;;;;GAcG;AAGH,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAA;AAYhC,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,MAAM,QAAQ,CAAA;AASpC,OAAO,EACN,mBAAmB,EACnB,uBAAuB,EACvB,qBAAqB,EACrB,MAAM,YAAY,CAAA;AAanB,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,MAAM,UAAU,CAAA;AAqBpC,OAAO,EAAE,IAAI,EAAE,KAAK,EAAE,GAAG,EAAE,QAAQ,EAAE,GAAG,EAAE,GAAG,EAAE,MAAM,YAAY,CAAA;AACjE,OAAO,EAAE,KAAK,EAAE,WAAW,EAAE,aAAa,EAAE,MAAM,WAAW,CAAA;AAqB7D,OAAO,EACN,KAAK,EACL,KAAK,EACL,GAAG,EACH,MAAM,EACN,QAAQ,EACR,EAAE,EACF,EAAE,EACF,EAAE,EACF,EAAE,EACF,EAAE,EACF,KAAK,EACL,EAAE,EACF,GAAG,EACH,EAAE,EACF,MAAM,gBAAgB,CAAA;AAUvB,OAAO,EAAE,UAAU,EAAE,KAAK,EAAE,MAAM,iBAAiB,CAAA;AASnD,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,aAAa,EAAE,GAAG,EAAE,GAAG,EAAE,IAAI,EAAE,GAAG,EAAE,MAAM,kBAAkB,CAAA;AAkB5F,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;AAExE,OAAO,EAAE,SAAS,EAAE,GAAG,EAAE,OAAO,EAAE,eAAe,EAAE,MAAM,EAAE,MAAM,gBAAgB,CAAA"}
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