@bjornpagen/bumbledb 0.15.0 → 0.17.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 +33 -49
- package/README.md +3 -3
- package/dist/capacity.d.ts +24 -136
- package/dist/capacity.d.ts.map +1 -1
- package/dist/capacity.js +18 -40
- package/dist/capacity.js.map +1 -1
- package/dist/closed.d.ts +0 -156
- package/dist/closed.d.ts.map +1 -1
- package/dist/closed.js +0 -104
- package/dist/closed.js.map +1 -1
- package/dist/db.d.ts +7 -223
- package/dist/db.d.ts.map +1 -1
- package/dist/db.js +147 -396
- package/dist/db.js.map +1 -1
- package/dist/face.d.ts +0 -133
- package/dist/face.d.ts.map +1 -1
- package/dist/face.js +0 -33
- package/dist/face.js.map +1 -1
- package/dist/fields.d.ts +1 -145
- package/dist/fields.d.ts.map +1 -1
- package/dist/fields.js +2 -91
- package/dist/fields.js.map +1 -1
- package/dist/index.d.ts +11 -15
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +9 -13
- package/dist/index.js.map +1 -1
- package/dist/law.d.ts +111 -93
- package/dist/law.d.ts.map +1 -1
- package/dist/law.js +23 -27
- package/dist/law.js.map +1 -1
- package/dist/lower.d.ts +9 -35
- package/dist/lower.d.ts.map +1 -1
- package/dist/lower.js +8 -53
- package/dist/lower.js.map +1 -1
- package/dist/marshal.d.ts +0 -65
- package/dist/marshal.d.ts.map +1 -1
- package/dist/marshal.js +0 -72
- package/dist/marshal.js.map +1 -1
- package/dist/native.d.ts +25 -290
- package/dist/native.d.ts.map +1 -1
- package/dist/native.js +6 -66
- package/dist/native.js.map +1 -1
- package/dist/query/atom.d.ts +10 -276
- package/dist/query/atom.d.ts.map +1 -1
- package/dist/query/atom.js +1 -96
- package/dist/query/atom.js.map +1 -1
- package/dist/query/find.d.ts +10 -76
- package/dist/query/find.d.ts.map +1 -1
- package/dist/query/find.js +0 -30
- package/dist/query/find.js.map +1 -1
- package/dist/query/lower.d.ts +64 -146
- package/dist/query/lower.d.ts.map +1 -1
- package/dist/query/lower.js +19 -256
- package/dist/query/lower.js.map +1 -1
- package/dist/query/parse-ir.d.ts +0 -7
- package/dist/query/parse-ir.d.ts.map +1 -1
- package/dist/query/parse-ir.js +1 -13
- package/dist/query/parse-ir.js.map +1 -1
- package/dist/query/run.d.ts +0 -36
- package/dist/query/run.d.ts.map +1 -1
- package/dist/query/run.js +0 -44
- package/dist/query/run.js.map +1 -1
- package/dist/query/scope.d.ts +24 -180
- package/dist/query/scope.d.ts.map +1 -1
- package/dist/query/scope.js +2 -66
- package/dist/query/scope.js.map +1 -1
- package/dist/relation.d.ts +2 -50
- package/dist/relation.d.ts.map +1 -1
- package/dist/relation.js +2 -37
- package/dist/relation.js.map +1 -1
- package/dist/schema.d.ts +13 -63
- package/dist/schema.d.ts.map +1 -1
- package/dist/schema.js +118 -92
- package/dist/schema.js.map +1 -1
- package/dist/spec.d.ts +1 -140
- package/dist/spec.d.ts.map +1 -1
- package/dist/spec.js +1 -68
- package/dist/spec.js.map +1 -1
- package/dist/statements.d.ts +6 -137
- package/dist/statements.d.ts.map +1 -1
- package/dist/statements.js +16 -119
- package/dist/statements.js.map +1 -1
- package/package.json +2 -2
- package/src/capacity.ts +26 -140
- package/src/closed.ts +5 -206
- package/src/db.ts +203 -692
- package/src/face.ts +0 -142
- package/src/fields.ts +4 -172
- package/src/index.ts +9 -15
- package/src/law.ts +201 -129
- package/src/lower.ts +8 -53
- package/src/marshal.ts +1 -85
- package/src/native.ts +47 -323
- package/src/query/atom.ts +26 -313
- package/src/query/find.ts +24 -110
- package/src/query/lower.ts +132 -377
- package/src/query/parse-ir.ts +1 -14
- package/src/query/run.ts +0 -45
- package/src/query/scope.ts +25 -186
- package/src/relation.ts +2 -66
- package/src/schema.ts +143 -122
- package/src/spec.ts +1 -160
- package/src/statements.ts +22 -174
package/dist/statements.js
CHANGED
|
@@ -1,66 +1,13 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Dependency statements as typed values (`docs/architecture/30-dependencies.md`
|
|
3
|
-
* owns the semantics; `docs/architecture/70-api.md` the surface): the FD key
|
|
4
|
-
* form, conditional containment, the bidirectional `==` abbreviation, and
|
|
5
|
-
* the capacity statement. A statement value is opaque and inert — no
|
|
6
|
-
* methods, no fluent continuation: a fact about the theory, not a builder.
|
|
7
|
-
*
|
|
8
|
-
* Every field reference is checked against the relation it names in the
|
|
9
|
-
* TYPE — existence through {@link FaceFields} (`on(R, "nope")` does not
|
|
10
|
-
* compile) and STRUCTURAL compatibility through {@link SameShapes}: the two
|
|
11
|
-
* faces' projected kind/width/element/roster quadruples are read off the
|
|
12
|
-
* schema type (the minimal kernel — descriptors are pure structure) and
|
|
13
|
-
* constrained positionwise equal, so a u64 face against a str face, a
|
|
14
|
-
* bytes width mismatch, an interval element mismatch, or a bare column
|
|
15
|
-
* against a closed reference is a compile error. TWO of those walls carry
|
|
16
|
-
* construction-time runtime twins here for untyped callers: ARITY
|
|
17
|
-
* ({@link assertArityAgreement} — cleanup-0.5.0 ruling 9: an
|
|
18
|
-
* arity-mismatched pairing fails at the statement, never by silent
|
|
19
|
-
* truncation) and the ROSTER slot ({@link assertRosterAgreement} —
|
|
20
|
-
* roster IDENTITY, positionwise: a closed vocabulary's referencing column
|
|
21
|
-
* is spelled with the vocabulary's own id descriptor, the ONE spelling, so
|
|
22
|
-
* a plain u64 column can never alias a vocabulary through a declared law
|
|
23
|
-
* and the SDK's descriptor-keyed closed judgments stay sound). Domains are
|
|
24
|
-
* NOT compared here — there is no domain to compare at construction: the
|
|
25
|
-
* statements themselves are what define the equivalence classes, and the
|
|
26
|
-
* domain wall lives where they aggregate — `schema()` (the
|
|
27
|
-
* one-generator-per-class law) and query joins (class names off the schema
|
|
28
|
-
* type). What is only a SEMANTIC property — the target side of a
|
|
29
|
-
* containment resolving a declared key of its relation — is DELIBERATELY
|
|
30
|
-
* not (and cannot be) stated here: whether `B(y)` is a key of `B` depends
|
|
31
|
-
* on which `key()` statements the surrounding `schema()` collects, a set no
|
|
32
|
-
* face type can see; it stays the engine's typed `SchemaError` judgment at
|
|
33
|
-
* `Db.create`/`Db.open` (the two-boundary split, engine as final
|
|
34
|
-
* authority).
|
|
35
|
-
*/
|
|
36
1
|
import * as errors from "@superbuilders/errors";
|
|
37
2
|
import { isCapacityWeight, isCapacityWindow, unitWeight } from "#capacity.ts";
|
|
38
3
|
import { isClosedMember, sealedFieldOf } from "#closed.ts";
|
|
39
4
|
import { renderFace } from "#face.ts";
|
|
40
5
|
import { rosterOf } from "#fields.ts";
|
|
41
6
|
import { renderCapacityWindow, renderWeight } from "#spec.ts";
|
|
42
|
-
/**
|
|
43
|
-
* The admission brand — a module-private symbol, deliberately unexported
|
|
44
|
-
* (the `capacity.ts` pattern): `Statement` is a public structural type, so
|
|
45
|
-
* without this brand a forged plain object of the right shape would walk
|
|
46
|
-
* past the construction-time arity and roster walls into `schema()` — and
|
|
47
|
-
* the roster wall is the one the engine cannot backstop (the wire carries
|
|
48
|
-
* plain u64s, no rosters). The symbol makes the four constructors the ONLY
|
|
49
|
-
* mints, so a statement that skipped the walls is unspellable.
|
|
50
|
-
*/
|
|
51
7
|
const admitted = Symbol("bumbledb.statement.admitted");
|
|
52
|
-
/**
|
|
53
|
-
* Narrows any value to an admitted statement — the probe is the
|
|
54
|
-
* module-private {@link admitted} brand only the four constructors set, so
|
|
55
|
-
* no host-built value (fact cells are structurally OPEN — an interval with
|
|
56
|
-
* an excess `kind` property is a legal cell) can ever be misread as one.
|
|
57
|
-
* The keyed-get selector dispatch and `schema()`'s admission both judge
|
|
58
|
-
* through here.
|
|
59
|
-
*/
|
|
60
8
|
function isStatement(value) {
|
|
61
9
|
return typeof value === "object" && value !== null && admitted in value;
|
|
62
10
|
}
|
|
63
|
-
/** Renders one face position's closedness for the roster-agreement diagnostics. */
|
|
64
11
|
function renderRosterSide(roster) {
|
|
65
12
|
return roster === undefined ? "a bare column" : `a ${roster.name} reference`;
|
|
66
13
|
}
|
|
@@ -78,22 +25,6 @@ function assertArityAgreement(source, target, statement) {
|
|
|
78
25
|
throw errors.new(`${source.owner.name}(${source.projection.join(", ")}) and ${target.owner.name}(${target.projection.join(", ")}) project ${source.projection.length} vs ${target.projection.length} fields — positional pairing requires both faces to project equally many — ${renderStatement(statement)}`);
|
|
79
26
|
}
|
|
80
27
|
}
|
|
81
|
-
/**
|
|
82
|
-
* The runtime twin of {@link SameShapes}'s roster slot: the two faces'
|
|
83
|
-
* projected descriptors must agree POSITIONWISE on closedness — the same
|
|
84
|
-
* roster (value identity — vocabulary identity is value identity, the
|
|
85
|
-
* SDK's membership rule everywhere) or none. Without this wall a plain u64
|
|
86
|
-
* column could alias a closed vocabulary through a declared containment
|
|
87
|
-
* (`docs/architecture/10-data-model.md` spells the ENGINE encoding that
|
|
88
|
-
* way), and every descriptor-keyed closed judgment — the orderable ban,
|
|
89
|
-
* the name↔id marshal, answer decode — would silently miss it. The
|
|
90
|
-
* vocabulary's own descriptor (`Kind.id`) is the ONE spelling of a closed
|
|
91
|
-
* reference at this surface (the canonical-utterance law); the engine
|
|
92
|
-
* cannot backstop this one — the wire carries plain u64s, no rosters.
|
|
93
|
-
* Arity agreement ({@link assertArityAgreement}) runs first, so the
|
|
94
|
-
* positionwise walk here never sees an unpaired position from a well-typed
|
|
95
|
-
* OR an untyped caller.
|
|
96
|
-
*/
|
|
97
28
|
function assertRosterAgreement(source, target, statement) {
|
|
98
29
|
source.projection.forEach(function agreeAt(fieldName, position) {
|
|
99
30
|
const targetField = target.projection[position];
|
|
@@ -116,12 +47,24 @@ function assertRosterAgreement(source, target, statement) {
|
|
|
116
47
|
* checked against `R`'s field block in the type, and the tuple is carried
|
|
117
48
|
* in the returned value's type ({@link KeyStatement}) — keyed point reads
|
|
118
49
|
* through THIS statement are typed field-for-field, descriptors resolvable
|
|
119
|
-
* through the owner's schema type.
|
|
50
|
+
* through the owner's schema type. A DUPLICATE field in the projection is
|
|
51
|
+
* refused here, at the mint (the engine's `FieldSet` refuses the same
|
|
52
|
+
* duplicate at `Db.create`; canonical utterance says the twice-spelled
|
|
53
|
+
* field is the once-spelled projection respelled) — without this wall a
|
|
54
|
+
* `new Set`-collapsed duplicate could set-match a shorter target
|
|
55
|
+
* projection the engine refuses.
|
|
120
56
|
*/
|
|
121
57
|
function key(relation, fields) {
|
|
122
58
|
if (isClosedMember(relation)) {
|
|
123
59
|
throw errors.new(`key(${relation.name}, ...): closedness already materializes ${relation.name}(id) -> ${relation.name} — an explicit key on a closed relation is rejected as a duplicate`);
|
|
124
60
|
}
|
|
61
|
+
const seen = new Set();
|
|
62
|
+
for (const fieldName of fields) {
|
|
63
|
+
if (seen.has(fieldName)) {
|
|
64
|
+
throw errors.new(`key(${relation.name}, ...): the projection spells ${fieldName} twice — write it once (the canonical-utterance law: one meaning, one spelling)`);
|
|
65
|
+
}
|
|
66
|
+
seen.add(fieldName);
|
|
67
|
+
}
|
|
125
68
|
const data = Object.freeze({
|
|
126
69
|
kind: "key",
|
|
127
70
|
owner: relation,
|
|
@@ -129,15 +72,6 @@ function key(relation, fields) {
|
|
|
129
72
|
});
|
|
130
73
|
return Object.freeze({ data, [admitted]: true });
|
|
131
74
|
}
|
|
132
|
-
/**
|
|
133
|
-
* `A(X|φ) <= B(Y|ψ)` — conditional inclusion, source left. Arity mismatch
|
|
134
|
-
* between the two faces is a type error ({@link SameArity}); a structurally
|
|
135
|
-
* mismatched pair is a type error ({@link SameShapes} — positionwise
|
|
136
|
-
* equality of the projected kind/width/element triples). The target side
|
|
137
|
-
* must resolve a declared key of B — a SEMANTIC property of the whole
|
|
138
|
-
* statement set that no face type can state, DELIBERATELY judged by the
|
|
139
|
-
* engine at `Db.create`/`Db.open` (`SchemaError`), never re-checked here.
|
|
140
|
-
*/
|
|
141
75
|
function contained(source, target) {
|
|
142
76
|
const data = Object.freeze({
|
|
143
77
|
kind: "containment",
|
|
@@ -149,15 +83,6 @@ function contained(source, target) {
|
|
|
149
83
|
assertRosterAgreement(data.source, data.target, statement);
|
|
150
84
|
return statement;
|
|
151
85
|
}
|
|
152
|
-
/**
|
|
153
|
-
* `A(X|φ) == B(Y|ψ)` — the bidirectional abbreviation, one utterance: the
|
|
154
|
-
* selected `==` bijection, a keyed one-to-one correspondence between the
|
|
155
|
-
* two faces (each side contains the other). It lowers to the two adjacent
|
|
156
|
-
* containments in the `A <= B` first order (macro parity — the engine
|
|
157
|
-
* performs the split, source-first) and renders as `==` once, in the
|
|
158
|
-
* written orientation. Faces pair by arity AND structural shape, exactly
|
|
159
|
-
* as {@link contained}.
|
|
160
|
-
*/
|
|
161
86
|
function mirrors(source, target) {
|
|
162
87
|
const data = Object.freeze({
|
|
163
88
|
kind: "mirrors",
|
|
@@ -169,14 +94,6 @@ function mirrors(source, target) {
|
|
|
169
94
|
assertRosterAgreement(data.source, data.target, statement);
|
|
170
95
|
return statement;
|
|
171
96
|
}
|
|
172
|
-
/**
|
|
173
|
-
* The runtime twin of the weight source wall ({@link WeightOnSource}): the
|
|
174
|
-
* weighed field must be a u64-encoded position of the SOURCE's own row
|
|
175
|
-
* (a signed weight would break the polarity scheduler — the illegal weight
|
|
176
|
-
* is unrepresentable, not checked), an interval position for the
|
|
177
|
-
* `Duration(...)` form. Judged at CONSTRUCTION for untyped callers; the
|
|
178
|
-
* engine's `validate_capacity` stays the final authority.
|
|
179
|
-
*/
|
|
180
97
|
function assertWeightOnSource(weight, source, statement) {
|
|
181
98
|
if (weight.kind === "unit") {
|
|
182
99
|
return;
|
|
@@ -192,14 +109,6 @@ function assertWeightOnSource(weight, source, statement) {
|
|
|
192
109
|
throw errors.new(`${source.owner.name}.${weight.field} is ${field.kind}, not an interval — Duration(...) weighs an interval field's measure — ${renderStatement(statement)}`);
|
|
193
110
|
}
|
|
194
111
|
}
|
|
195
|
-
/**
|
|
196
|
-
* The runtime twin of the dependent-bound target wall
|
|
197
|
-
* ({@link BoundsOnTarget}): a `ref()` bound must name a u64 field of the
|
|
198
|
-
* TARGET's own row, a `duration()` bound an interval field — bound names
|
|
199
|
-
* resolve against the target's FULL roster (C1), never the projection.
|
|
200
|
-
* `within()` mints dependent bounds in the hi slot only (C6), but the walk
|
|
201
|
-
* here is total over the window's bound slots.
|
|
202
|
-
*/
|
|
203
112
|
function assertBoundsOnTarget(window, target, statement) {
|
|
204
113
|
const bounds = window.kind === "range" ? [window.lo, window.hi] : [window.kind === "exact" ? window.n : window.lo];
|
|
205
114
|
for (const bound of bounds) {
|
|
@@ -236,10 +145,10 @@ function capacity(target, second, third, fourth) {
|
|
|
236
145
|
if (weight.kind === "unit" && window.kind === "floor" && window.lo.kind === "lit" && window.lo.value === 1n) {
|
|
237
146
|
throw errors.new("`{1..*}` on the unit instance says only what the bare containment says — drop the annotation and write the containment: contained(source, target)");
|
|
238
147
|
}
|
|
239
|
-
|
|
148
|
+
if (weight.kind === "unit" && window.kind === "floor") {
|
|
149
|
+
throw errors.new("`{N..*}` on the unit instance — a bare count floor is refused; weigh the source (`<=[w]{N..*}` stays legal) or drop the bound");
|
|
150
|
+
}
|
|
240
151
|
// CapacityDimensionMixing twin — ruled 2026-07-24): a count of facts
|
|
241
|
-
// bounded by a span of time mixes dimensions. Judged here for untyped
|
|
242
|
-
// callers; the engine's validate_capacity stays the final authority.
|
|
243
152
|
if (weight.kind === "unit" && window.kind === "range" && window.hi.kind === "durationField") {
|
|
244
153
|
throw errors.new(`a unit (count) window against the duration() bound on ${window.hi.field} mixes dimensions (C18) — weigh the source with weigh(duration(field)), or bound by a u64 field or literal`);
|
|
245
154
|
}
|
|
@@ -257,18 +166,6 @@ function capacity(target, second, third, fourth) {
|
|
|
257
166
|
assertBoundsOnTarget(window, data.target, statement);
|
|
258
167
|
return statement;
|
|
259
168
|
}
|
|
260
|
-
/**
|
|
261
|
-
* Renders one statement in the CANONICAL macro spelling
|
|
262
|
-
* (`docs/architecture/70-api.md`; the engine's `schema/render.rs` emits the
|
|
263
|
-
* same shapes for violations) — `Account(id) -> Account`,
|
|
264
|
-
* `Account(holder) <= Holder(id)`,
|
|
265
|
-
* `Account(id | kind == Savings) == SavingsTerms(account)`,
|
|
266
|
-
* `Holder(id) <={0..3} Account(holder)`,
|
|
267
|
-
* `Pool(id) <=[watts]{0..supply} Device(pool)` — so TS-side errors and
|
|
268
|
-
* engine-side diagnostics read identically. A renderer, never a parser:
|
|
269
|
-
* strings are output-only. The unit weight renders nothing — the count
|
|
270
|
-
* utterance falls out of the one printer.
|
|
271
|
-
*/
|
|
272
169
|
function renderStatement(statement) {
|
|
273
170
|
const data = statement.data;
|
|
274
171
|
switch (data.kind) {
|
package/dist/statements.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"statements.js","sourceRoot":"","sources":["../src/statements.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"statements.js","sourceRoot":"","sources":["../src/statements.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@bjornpagen/bumbledb",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.17.0",
|
|
4
4
|
"description": "Embedded relational database for TypeScript with typed schemas, queries, and commit-time constraints",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"exports": {
|
|
@@ -54,7 +54,7 @@
|
|
|
54
54
|
},
|
|
55
55
|
"private": false,
|
|
56
56
|
"optionalDependencies": {
|
|
57
|
-
"@bjornpagen/bumbledb-darwin-arm64": "0.
|
|
57
|
+
"@bjornpagen/bumbledb-darwin-arm64": "0.17.0"
|
|
58
58
|
},
|
|
59
59
|
"scripts": {
|
|
60
60
|
"build": "node scripts/build.ts",
|
package/src/capacity.ts
CHANGED
|
@@ -1,31 +1,31 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Capacity-law mints — the window, weight, and dependent-bound vocabulary
|
|
3
|
-
* the one `capacity
|
|
4
|
-
*
|
|
5
|
-
* around the aggregate form). `within
|
|
3
|
+
* the one `capacity` statement constructor consumes
|
|
4
|
+
* § the canonical-utterance law, restated
|
|
5
|
+
* around the aggregate form). `within` is the ONE window spelling —
|
|
6
6
|
* `within(n)` exact (`within(0n)` IS the exclusion's one spelling),
|
|
7
7
|
* `within(lo, hi)` range (`within(0n, hi)` the canonical ceiling),
|
|
8
|
-
* `within(lo, "*")` floor — `weigh
|
|
8
|
+
* `within(lo, "*")` floor — `weigh` names the measure on the SOURCE row
|
|
9
9
|
* (`weigh("watts")` a u64 field, `weigh(duration("booked"))` an interval's
|
|
10
|
-
* measure), and `ref
|
|
10
|
+
* measure), and `ref`/`duration` read a dependent bound from the
|
|
11
11
|
* TARGET row (hi slot only — ruled 2026-07-24, C6). The ban table is
|
|
12
12
|
* enforced REPRESENTATIONALLY in two tiers, split per-aggregate where
|
|
13
13
|
* weight-sensitive (design § 6: a ban is canonical-utterance policing when
|
|
14
14
|
* it is weight-independent, semantic deduplication when it is not):
|
|
15
15
|
*
|
|
16
16
|
* - **The type tier**: a banned spelling written as a LITERAL does not
|
|
17
|
-
*
|
|
18
|
-
*
|
|
19
|
-
*
|
|
20
|
-
*
|
|
21
|
-
*
|
|
22
|
-
*
|
|
23
|
-
*
|
|
17
|
+
* compile — every negative bound, `within(n, n)`, `within(0n, 0n)`, and
|
|
18
|
+
* `within(0n, "*")` are type errors naming the canonical form. The
|
|
19
|
+
* weight-SENSITIVE row rides the `capacity` overloads themselves:
|
|
20
|
+
* `within(1n, "*")` is banned on the unit overload only (`{1..*}` on the
|
|
21
|
+
* count instance is the bare containment respelled —
|
|
22
|
+
* `window_floor_containment`), and LEGAL on the weighted one ("positive
|
|
23
|
+
* total" is not an existence claim over rows).
|
|
24
24
|
* - **The construction tier**: a bound the type level cannot judge — a
|
|
25
|
-
*
|
|
26
|
-
*
|
|
27
|
-
*
|
|
28
|
-
*
|
|
25
|
+
* COMPUTED `bigint`, or an inverted `within(lo, hi)` order — is judged at
|
|
26
|
+
* construction with the same canonical-naming errors; and past both
|
|
27
|
+
* tiers the engine's own spec validation remains the law for a hostile
|
|
28
|
+
* FFI caller (the standing two-tier ban enforcement).
|
|
29
29
|
*
|
|
30
30
|
* The weight vocabulary is closed at the row (ruled 2026-07-24, ruling 6):
|
|
31
31
|
* a path weight (`weigh("model.watts")`) is a typed refusal at BOTH tiers
|
|
@@ -39,76 +39,36 @@ import * as errors from "@superbuilders/errors"
|
|
|
39
39
|
import type { AnyFace, FaceFields, FaceSource, ProjectedShape } from "#face.ts"
|
|
40
40
|
import type { CapacityBoundSpec, CapacityWindowSpec, WeightSpec } from "#spec.ts"
|
|
41
41
|
|
|
42
|
-
/**
|
|
43
|
-
* The admission brand — a module-private symbol, deliberately unexported
|
|
44
|
-
* (the standing statement-mint pattern): `CapacityWindowSpec` and
|
|
45
|
-
* `WeightSpec` are public wire types, so without this brand every banned
|
|
46
|
-
* spelling in the ban table would be writable as a plain object literal.
|
|
47
|
-
* The symbol makes `within()` and `weigh()` the ONLY producers of the
|
|
48
|
-
* values `capacity()` accepts, which is what "the ban table is unwritable"
|
|
49
|
-
* means.
|
|
50
|
-
*/
|
|
51
42
|
const admitted: unique symbol = Symbol("bumbledb.capacity.admitted")
|
|
52
43
|
|
|
53
|
-
/**
|
|
54
|
-
* An admitted capacity window — opaque and inert: a fact about the theory,
|
|
55
|
-
* not a builder. Only `within()` produces one; the spec is carried at its
|
|
56
|
-
* EXACT type so the weight-sensitive `{1..*}` ban and the dependent-bound
|
|
57
|
-
* target wall are judged at the `capacity()` call.
|
|
58
|
-
*/
|
|
59
44
|
interface CapacityWindow<S extends CapacityWindowSpec = CapacityWindowSpec> {
|
|
60
45
|
readonly window: S
|
|
61
46
|
readonly [admitted]: true
|
|
62
47
|
}
|
|
63
48
|
|
|
64
|
-
/**
|
|
65
|
-
* An admitted measure — `weigh()`'s product, the `[w]` bracket of the
|
|
66
|
-
* operator. The spec is carried at its exact type so the u64/interval
|
|
67
|
-
* source wall ({@link WeightOnSource}) reads the weighed field's name off
|
|
68
|
-
* the value.
|
|
69
|
-
*/
|
|
70
49
|
interface CapacityWeight<S extends WeightSpec = WeightSpec> {
|
|
71
50
|
readonly weight: S
|
|
72
51
|
readonly [admitted]: true
|
|
73
52
|
}
|
|
74
53
|
|
|
75
|
-
/**
|
|
76
|
-
* A dependent bound naming a u64 field of the TARGET row — `ref()`'s
|
|
77
|
-
* product, legal in `within()`'s hi slot only (C6: a dependent floor has
|
|
78
|
-
* no use case; inversion with idents is unrepresentable). Carries no
|
|
79
|
-
* value: bounds resolve per target row at judge time.
|
|
80
|
-
*/
|
|
81
54
|
interface FieldRef<F extends string = string> {
|
|
82
55
|
readonly kind: "field"
|
|
83
56
|
readonly field: F
|
|
84
57
|
}
|
|
85
58
|
|
|
86
|
-
/**
|
|
87
|
-
* A dependent interval-measure bound (`Duration(field)` of the TARGET
|
|
88
|
-
* row), or — handed to `weigh()` — the interval-measure weight of the
|
|
89
|
-
* SOURCE row. One mint, both slots: the interval enters through the
|
|
90
|
-
* measure argument, never the group key.
|
|
91
|
-
*/
|
|
92
59
|
interface DurationRef<F extends string = string> {
|
|
93
60
|
readonly kind: "durationField"
|
|
94
61
|
readonly field: F
|
|
95
62
|
}
|
|
96
63
|
|
|
97
|
-
/** Narrows any value to an admitted capacity window through the module-private brand. */
|
|
98
64
|
function isCapacityWindow(value: unknown): value is CapacityWindow {
|
|
99
65
|
return typeof value === "object" && value !== null && admitted in value && "window" in value
|
|
100
66
|
}
|
|
101
67
|
|
|
102
|
-
/** Narrows any value to an admitted capacity weight through the module-private brand. */
|
|
103
68
|
function isCapacityWeight(value: unknown): value is CapacityWeight {
|
|
104
69
|
return typeof value === "object" && value !== null && admitted in value && "weight" in value
|
|
105
70
|
}
|
|
106
71
|
|
|
107
|
-
/**
|
|
108
|
-
* The legible banned-spelling verdict: intersected into a mint's parameter
|
|
109
|
-
* when the LITERAL argument spells a banned window, naming the canonical
|
|
110
|
-
* form — the compile-time face of the ban table.
|
|
111
|
-
*/
|
|
112
72
|
interface BannedWindow<Canonical extends string> {
|
|
113
73
|
readonly "banned window spelling — the canonical-utterance law names the one legal form": Canonical
|
|
114
74
|
}
|
|
@@ -122,7 +82,6 @@ interface RefusedPath<Idiom extends string> {
|
|
|
122
82
|
readonly "path spelling refused — the vocabulary is closed at the row": Idiom
|
|
123
83
|
}
|
|
124
84
|
|
|
125
|
-
/** `true` exactly when the literal bigint `N` is negative (out of the u64 bound domain). */
|
|
126
85
|
type IsNegative<N extends bigint> = `${N}` extends `-${string}` ? true : false
|
|
127
86
|
|
|
128
87
|
/**
|
|
@@ -137,19 +96,12 @@ type PathBan<F extends string> = string extends F
|
|
|
137
96
|
? RefusedPath<"pin the column — a two-column containment (Source(ref, f) <= Catalog(id, f)) proves the local copy, then name the local field">
|
|
138
97
|
: unknown
|
|
139
98
|
|
|
140
|
-
/** The ban verdict on a single bound: negatives are out of the u64 domain. */
|
|
141
99
|
type NegativeBan<N extends bigint> = bigint extends N
|
|
142
100
|
? unknown
|
|
143
101
|
: IsNegative<N> extends true
|
|
144
102
|
? BannedWindow<"capacity bounds are u64 — a negative bound is out of domain">
|
|
145
103
|
: unknown
|
|
146
104
|
|
|
147
|
-
/**
|
|
148
|
-
* The ban verdict on `within(lo, "*")`: `{0..*}` is vacuous —
|
|
149
|
-
* weight-independent (sums are ≥ 0). `{1..*}` is NOT judged here: the ban
|
|
150
|
-
* is weight-sensitive (Count-instance only) and rides the `capacity()`
|
|
151
|
-
* unit overload ({@link UnitWindowBan}).
|
|
152
|
-
*/
|
|
153
105
|
type FloorBan<N extends bigint> = bigint extends N
|
|
154
106
|
? unknown
|
|
155
107
|
: IsNegative<N> extends true
|
|
@@ -158,13 +110,6 @@ type FloorBan<N extends bigint> = bigint extends N
|
|
|
158
110
|
? BannedWindow<"`{0..*}` is vacuous — it provably says nothing; delete the statement">
|
|
159
111
|
: unknown
|
|
160
112
|
|
|
161
|
-
/**
|
|
162
|
-
* The ban verdict on `within(lo, hi)` with both literals known: `{n..n}`
|
|
163
|
-
* is the exact measure respelled (`within(n)`, or `within(0n)` at 0) —
|
|
164
|
-
* weight-independent canonical policing. Bound ORDER (`{hi..lo}` inverted)
|
|
165
|
-
* is not type-expressible — bigint literals have no type-level comparison
|
|
166
|
-
* — so inversion stays a construction error.
|
|
167
|
-
*/
|
|
168
113
|
type RangeBan<Lo extends bigint, Hi extends bigint> = bigint extends Lo
|
|
169
114
|
? unknown
|
|
170
115
|
: bigint extends Hi
|
|
@@ -181,26 +126,20 @@ type RangeBan<Lo extends bigint, Hi extends bigint> = bigint extends Lo
|
|
|
181
126
|
: unknown
|
|
182
127
|
: unknown
|
|
183
128
|
|
|
184
|
-
/**
|
|
185
|
-
* The weight-SENSITIVE ban row, judged at the `capacity()` call where the
|
|
186
|
-
* aggregate instance is known (design § 6): on the UNIT overload a
|
|
187
|
-
* `{1..*}` floor says only what the bare containment says
|
|
188
|
-
* (`window_floor_containment`) and is banned naming `contained`; on the
|
|
189
|
-
* weighted overload the same window is LEGAL — "positive total" admits
|
|
190
|
-
* zero-weight rows and is a different, weaker law.
|
|
191
|
-
*/
|
|
192
129
|
type UnitWindowBan<W extends CapacityWindow> = W["window"] extends {
|
|
193
130
|
readonly kind: "floor"
|
|
194
131
|
readonly lo: { readonly kind: "lit"; readonly value: 1n }
|
|
195
132
|
}
|
|
196
133
|
? BannedWindow<"`{1..*}` on the unit instance says only what the bare containment says — write contained(source, target)">
|
|
197
|
-
:
|
|
134
|
+
: W["window"] extends { readonly kind: "floor" }
|
|
135
|
+
? BannedWindow<"`{N..*}` on the unit instance — a bare count floor is refused; weigh the source (`<=[w]{N..*}` stays legal) or drop the bound">
|
|
136
|
+
: unknown
|
|
198
137
|
|
|
199
138
|
/**
|
|
200
139
|
* The C18 dimension gate's ban row, unit instance (the engine's
|
|
201
140
|
* `CapacityDimensionMixing` twin, ruled 2026-07-24): a unit (count)
|
|
202
|
-
* window against a `duration
|
|
203
|
-
* time — a dimension error. Judged on the `capacity
|
|
141
|
+
* window against a `duration` bound counts facts against a span of
|
|
142
|
+
* time — a dimension error. Judged on the `capacity` UNIT overload
|
|
204
143
|
* only: Duration weights pair with Duration-capable bounds, so the
|
|
205
144
|
* weighted overload takes the same window freely.
|
|
206
145
|
*/
|
|
@@ -210,16 +149,9 @@ type UnitDimensionBan<W extends CapacityWindow> = W["window"] extends {
|
|
|
210
149
|
? BannedWindow<"a count of facts bounded by a span of time mixes dimensions (C18) — weigh the source with weigh(duration(field)), or bound by a u64 field or literal">
|
|
211
150
|
: unknown
|
|
212
151
|
|
|
213
|
-
/** The projected kind of one field of a face's source, read off the schema type. */
|
|
214
152
|
type KindAt<S extends FaceSource, K extends string> =
|
|
215
153
|
ProjectedShape<S, K> extends readonly [infer Kind, ...unknown[]] ? Kind : undefined
|
|
216
154
|
|
|
217
|
-
/**
|
|
218
|
-
* The legible off-roster verdict for a dependent bound: bound names
|
|
219
|
-
* resolve against the TARGET's full field roster (C1 — the written
|
|
220
|
-
* projection tuple stays the pure grouping key), and the verdict names
|
|
221
|
-
* that roster.
|
|
222
|
-
*/
|
|
223
155
|
interface BoundOffTargetRoster<K, Roster> {
|
|
224
156
|
readonly "dependent bound must name a field of the TARGET's own row — bound names resolve against the target's full roster": readonly [
|
|
225
157
|
K,
|
|
@@ -227,7 +159,6 @@ interface BoundOffTargetRoster<K, Roster> {
|
|
|
227
159
|
]
|
|
228
160
|
}
|
|
229
161
|
|
|
230
|
-
/** The legible kind-mismatch verdict for a dependent bound: `ref()` needs u64, `duration()` an interval. */
|
|
231
162
|
interface BoundKindMismatch<K, Want> {
|
|
232
163
|
readonly "dependent bound kind mismatch — ref() reads a u64 field, duration() an interval field, of the TARGET row": readonly [
|
|
233
164
|
K,
|
|
@@ -235,11 +166,6 @@ interface BoundKindMismatch<K, Want> {
|
|
|
235
166
|
]
|
|
236
167
|
}
|
|
237
168
|
|
|
238
|
-
/**
|
|
239
|
-
* One dependent-bound slot judged against the target face's roster and
|
|
240
|
-
* kinds. A WIDE field name (the untyped-caller path — literal identity
|
|
241
|
-
* already lost) passes the type tier and is judged at construction.
|
|
242
|
-
*/
|
|
243
169
|
type BoundOnTarget<K extends string, Want extends "u64" | "interval", B extends AnyFace> = string extends K
|
|
244
170
|
? unknown
|
|
245
171
|
: K extends FaceFields<B["source"]>
|
|
@@ -248,13 +174,6 @@ type BoundOnTarget<K extends string, Want extends "u64" | "interval", B extends
|
|
|
248
174
|
: BoundKindMismatch<K, Want>
|
|
249
175
|
: BoundOffTargetRoster<K, FaceFields<B["source"]>>
|
|
250
176
|
|
|
251
|
-
/**
|
|
252
|
-
* The dependent-bound target wall (type tier): for a `ref(K)` bound in the
|
|
253
|
-
* window's hi slot, `K` must name a u64 field of the TARGET face's own
|
|
254
|
-
* row; for a `duration(K)` bound, an interval field. Literal-bound windows
|
|
255
|
-
* pass untouched. The runtime twin for untyped callers lives at the
|
|
256
|
-
* `capacity()` construction (`statements.ts`).
|
|
257
|
-
*/
|
|
258
177
|
type BoundsOnTarget<W extends CapacityWindow, B extends AnyFace> = W["window"] extends {
|
|
259
178
|
readonly hi: FieldRef<infer K>
|
|
260
179
|
}
|
|
@@ -263,7 +182,6 @@ type BoundsOnTarget<W extends CapacityWindow, B extends AnyFace> = W["window"] e
|
|
|
263
182
|
? BoundOnTarget<K, "interval", B>
|
|
264
183
|
: unknown
|
|
265
184
|
|
|
266
|
-
/** The legible off-roster verdict for a weight: the vocabulary is closed at the SOURCE row. */
|
|
267
185
|
interface WeightOffSourceRoster<K, Roster> {
|
|
268
186
|
readonly "weight must name a field of the SOURCE's own row — the weight vocabulary is closed at the row": readonly [
|
|
269
187
|
K,
|
|
@@ -271,11 +189,6 @@ interface WeightOffSourceRoster<K, Roster> {
|
|
|
271
189
|
]
|
|
272
190
|
}
|
|
273
191
|
|
|
274
|
-
/**
|
|
275
|
-
* The legible kind-mismatch verdict for a weight: a signed weight would
|
|
276
|
-
* break the polarity scheduler (an insert could lower a sum), so the
|
|
277
|
-
* illegal weight is unrepresentable, not checked.
|
|
278
|
-
*/
|
|
279
192
|
interface WeightKindMismatch<K, Want> {
|
|
280
193
|
readonly "weight kind mismatch — weigh(field) reads a u64 field, weigh(duration(field)) an interval field, of the SOURCE row": readonly [
|
|
281
194
|
K,
|
|
@@ -287,7 +200,7 @@ interface WeightKindMismatch<K, Want> {
|
|
|
287
200
|
* The weight source wall (type tier): `weigh(K)`'s field must be a
|
|
288
201
|
* u64-encoded position of the SOURCE face's own row (signed encodings are
|
|
289
202
|
* the typed polarity refusal), `weigh(duration(K))`'s an interval
|
|
290
|
-
* position. Checked at the `capacity
|
|
203
|
+
* position. Checked at the `capacity` call where the source face is
|
|
291
204
|
* inferred — the proven constrain-after-inference pattern.
|
|
292
205
|
*/
|
|
293
206
|
type WeightOnSource<M extends CapacityWeight, A extends AnyFace> = M["weight"] extends {
|
|
@@ -311,10 +224,8 @@ type WeightOnSource<M extends CapacityWeight, A extends AnyFace> = M["weight"] e
|
|
|
311
224
|
: WeightOffSourceRoster<K, FaceFields<A["source"]>>
|
|
312
225
|
: unknown
|
|
313
226
|
|
|
314
|
-
/** The unit weight — a case, not an absence (C4): the count instance's one wire spelling. */
|
|
315
227
|
const unitWeight: WeightSpec = Object.freeze({ kind: "unit" })
|
|
316
228
|
|
|
317
|
-
/** The construction-tier twin of {@link PathBan}: a dotted name refuses naming the idiom. */
|
|
318
229
|
function assertRowLocal(field: string, role: string): string {
|
|
319
230
|
if (field.includes(".")) {
|
|
320
231
|
throw errors.new(
|
|
@@ -324,31 +235,19 @@ function assertRowLocal(field: string, role: string): string {
|
|
|
324
235
|
return field
|
|
325
236
|
}
|
|
326
237
|
|
|
327
|
-
/** Stamps one admitted window spec as a frozen branded value. */
|
|
328
238
|
function admitWindow<S extends CapacityWindowSpec>(window: S): CapacityWindow<S> {
|
|
329
239
|
const value: CapacityWindow<S> = { window, [admitted]: true }
|
|
330
240
|
return Object.freeze(value)
|
|
331
241
|
}
|
|
332
242
|
|
|
333
|
-
/** One literal bound. */
|
|
334
243
|
function lit(value: bigint): CapacityBoundSpec {
|
|
335
244
|
return Object.freeze({ kind: "lit", value })
|
|
336
245
|
}
|
|
337
246
|
|
|
338
|
-
/**
|
|
339
|
-
* `{n}` — THE exact-measure spelling; `within(0n)` IS the exclusion's one
|
|
340
|
-
* spelling on the unit instance, and the weaker "total is zero" law on a
|
|
341
|
-
* weighted one (zero-weight rows may exist — design § 6, stated loudly).
|
|
342
|
-
*/
|
|
343
247
|
function within<const N extends bigint>(
|
|
344
248
|
n: N & NegativeBan<N>
|
|
345
249
|
): CapacityWindow<{ readonly kind: "exact"; readonly n: { readonly kind: "lit"; readonly value: N } }>
|
|
346
|
-
|
|
347
|
-
* `{lo..*}` — a floor with no ceiling. `within(0n, "*")` is vacuous
|
|
348
|
-
* (unwritable as a literal); `within(1n, "*")` constructs — the `{1..*}`
|
|
349
|
-
* ban is weight-sensitive and judged at the `capacity()` call (unit
|
|
350
|
-
* instance only).
|
|
351
|
-
*/
|
|
250
|
+
|
|
352
251
|
function within<const Lo extends bigint>(
|
|
353
252
|
lo: Lo & FloorBan<Lo>,
|
|
354
253
|
hi: "*"
|
|
@@ -367,13 +266,7 @@ function within<const Lo extends bigint, const R extends FieldRef | DurationRef>
|
|
|
367
266
|
readonly lo: { readonly kind: "lit"; readonly value: Lo }
|
|
368
267
|
readonly hi: R
|
|
369
268
|
}>
|
|
370
|
-
|
|
371
|
-
* `{lo..hi}` — both bounds explicit, lo < hi; `within(0n, hi)` is the
|
|
372
|
-
* canonical ceiling. `lo === hi` is the exact measure respelled
|
|
373
|
-
* (unwritable as literals — {@link RangeBan} names `within(n)`), rejected
|
|
374
|
-
* at construction when computed; an inverted window is unsatisfiable and
|
|
375
|
-
* rejected at construction (bigint literals carry no type-level order).
|
|
376
|
-
*/
|
|
269
|
+
|
|
377
270
|
function within<const Lo extends bigint, const Hi extends bigint>(
|
|
378
271
|
lo: Lo,
|
|
379
272
|
hi: Hi & RangeBan<Lo, Hi>
|
|
@@ -419,7 +312,6 @@ function within(lo: bigint, hi?: bigint | "*" | FieldRef | DurationRef): Capacit
|
|
|
419
312
|
return admitWindow({ kind: "range", lo: lit(lo), hi: Object.freeze({ kind: "field", field }) })
|
|
420
313
|
}
|
|
421
314
|
|
|
422
|
-
/** Stamps one admitted weight spec as a frozen branded value. */
|
|
423
315
|
function admitWeight<S extends WeightSpec>(weight: S): CapacityWeight<S> {
|
|
424
316
|
const value: CapacityWeight<S> = { weight, [admitted]: true }
|
|
425
317
|
return Object.freeze(value)
|
|
@@ -444,20 +336,14 @@ function weigh(measure: string | DurationRef): CapacityWeight {
|
|
|
444
336
|
return admitWeight({ kind: "durationField", field: assertRowLocal(measure.field, "weight") })
|
|
445
337
|
}
|
|
446
338
|
|
|
447
|
-
/**
|
|
448
|
-
* A dependent bound by name — `within(0n, ref("supply"))` reads each
|
|
449
|
-
* group's ceiling from the TARGET row's u64 field (bound names resolve
|
|
450
|
-
* against the target's FULL roster, C1 — the projection tuple stays the
|
|
451
|
-
* pure grouping key). Carries no value.
|
|
452
|
-
*/
|
|
453
339
|
function ref<const F extends string>(field: F & PathBan<F>): FieldRef<F> {
|
|
454
340
|
return Object.freeze({ kind: "field", field: assertRowLocal(field, "dependent bound") }) as FieldRef<F>
|
|
455
341
|
}
|
|
456
342
|
|
|
457
343
|
/**
|
|
458
344
|
* `Duration(field)` — the interval-measure spelling, one mint for both
|
|
459
|
-
* slots: handed to `weigh
|
|
460
|
-
* in `within
|
|
345
|
+
* slots: handed to `weigh` it is the SOURCE row's interval measure;
|
|
346
|
+
* in `within`'s hi slot it is the TARGET row's interval-measure bound
|
|
461
347
|
* (Duration weights pair with Duration-capable bounds — C18).
|
|
462
348
|
*/
|
|
463
349
|
function duration<const F extends string>(field: F & PathBan<F>): DurationRef<F> {
|