@bjornpagen/bumbledb 0.6.0 → 0.8.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 (98) hide show
  1. package/COOKBOOK.md +150 -9
  2. package/README.md +18 -5
  3. package/dist/capacity.d.ts +310 -0
  4. package/dist/capacity.d.ts.map +1 -0
  5. package/dist/capacity.js +138 -0
  6. package/dist/capacity.js.map +1 -0
  7. package/dist/closed.d.ts +7 -5
  8. package/dist/closed.d.ts.map +1 -1
  9. package/dist/closed.js +4 -1
  10. package/dist/closed.js.map +1 -1
  11. package/dist/db.d.ts +115 -76
  12. package/dist/db.d.ts.map +1 -1
  13. package/dist/db.js +178 -122
  14. package/dist/db.js.map +1 -1
  15. package/dist/exhume.d.ts +22 -10
  16. package/dist/exhume.d.ts.map +1 -1
  17. package/dist/exhume.js +42 -9
  18. package/dist/exhume.js.map +1 -1
  19. package/dist/face.d.ts +11 -7
  20. package/dist/face.d.ts.map +1 -1
  21. package/dist/face.js.map +1 -1
  22. package/dist/fields.d.ts +38 -16
  23. package/dist/fields.d.ts.map +1 -1
  24. package/dist/fields.js +33 -8
  25. package/dist/fields.js.map +1 -1
  26. package/dist/index.d.ts +8 -8
  27. package/dist/index.d.ts.map +1 -1
  28. package/dist/index.js +3 -3
  29. package/dist/index.js.map +1 -1
  30. package/dist/law.d.ts +3 -2
  31. package/dist/law.d.ts.map +1 -1
  32. package/dist/law.js +1 -1
  33. package/dist/law.js.map +1 -1
  34. package/dist/lower.d.ts +9 -9
  35. package/dist/lower.d.ts.map +1 -1
  36. package/dist/lower.js +20 -14
  37. package/dist/lower.js.map +1 -1
  38. package/dist/marshal.d.ts +17 -7
  39. package/dist/marshal.d.ts.map +1 -1
  40. package/dist/marshal.js +32 -10
  41. package/dist/marshal.js.map +1 -1
  42. package/dist/native.d.ts +66 -12
  43. package/dist/native.d.ts.map +1 -1
  44. package/dist/native.js.map +1 -1
  45. package/dist/query/atom.d.ts +72 -7
  46. package/dist/query/atom.d.ts.map +1 -1
  47. package/dist/query/atom.js +12 -9
  48. package/dist/query/atom.js.map +1 -1
  49. package/dist/query/lower.d.ts +8 -0
  50. package/dist/query/lower.d.ts.map +1 -1
  51. package/dist/query/lower.js +80 -13
  52. package/dist/query/lower.js.map +1 -1
  53. package/dist/query/run.d.ts +5 -5
  54. package/dist/query/run.d.ts.map +1 -1
  55. package/dist/query/run.js +7 -12
  56. package/dist/query/run.js.map +1 -1
  57. package/dist/query/scope.d.ts +15 -5
  58. package/dist/query/scope.d.ts.map +1 -1
  59. package/dist/query/scope.js.map +1 -1
  60. package/dist/relation.d.ts.map +1 -1
  61. package/dist/relation.js +3 -1
  62. package/dist/relation.js.map +1 -1
  63. package/dist/schema.d.ts.map +1 -1
  64. package/dist/schema.js +12 -2
  65. package/dist/schema.js.map +1 -1
  66. package/dist/spec.d.ts +95 -32
  67. package/dist/spec.d.ts.map +1 -1
  68. package/dist/spec.js +39 -7
  69. package/dist/spec.js.map +1 -1
  70. package/dist/statements.d.ts +62 -25
  71. package/dist/statements.d.ts.map +1 -1
  72. package/dist/statements.js +105 -22
  73. package/dist/statements.js.map +1 -1
  74. package/package.json +3 -3
  75. package/src/capacity.ts +454 -0
  76. package/src/closed.ts +13 -7
  77. package/src/db.ts +302 -184
  78. package/src/exhume.ts +48 -11
  79. package/src/face.ts +14 -6
  80. package/src/fields.ts +51 -15
  81. package/src/index.ts +20 -9
  82. package/src/law.ts +3 -2
  83. package/src/lower.ts +20 -14
  84. package/src/marshal.ts +38 -13
  85. package/src/native.ts +65 -11
  86. package/src/query/atom.ts +119 -15
  87. package/src/query/lower.ts +117 -15
  88. package/src/query/run.ts +7 -12
  89. package/src/query/scope.ts +15 -6
  90. package/src/relation.ts +3 -1
  91. package/src/schema.ts +14 -2
  92. package/src/spec.ts +112 -34
  93. package/src/statements.ts +188 -38
  94. package/dist/count.d.ts +0 -102
  95. package/dist/count.d.ts.map +0 -1
  96. package/dist/count.js +0 -115
  97. package/dist/count.js.map +0 -1
  98. package/src/count.ts +0 -211
package/dist/spec.d.ts CHANGED
@@ -96,10 +96,10 @@ type LiteralSetSpec = {
96
96
  readonly literals: readonly LiteralSpec[];
97
97
  };
98
98
  /**
99
- * One side of a containment or window: `R(fields… | field == literal…)`,
100
- * all names. `projection` is π in the statement's written order (positional
101
- * pairing with the other side); `selection` is σ as (field, literal-or-set)
102
- * pairs, read conjunctively.
99
+ * One side of a containment or capacity statement:
100
+ * `R(fields… | field == literal…)`, all names. `projection` is π in the
101
+ * statement's written order (positional pairing with the other side);
102
+ * `selection` is σ as (field, literal-or-set) pairs, read conjunctively.
103
103
  */
104
104
  interface SideSpec {
105
105
  readonly relation: string;
@@ -107,22 +107,58 @@ interface SideSpec {
107
107
  readonly selection: ReadonlyArray<readonly [string, LiteralSetSpec]>;
108
108
  }
109
109
  /**
110
- * A cardinality window's bounds the canonical-utterance law's surviving
111
- * spellings only, since the SDK's `Count` constructors make every banned
112
- * spelling unwritable or a construction error: `exact` is `{n}` (`{0}` the
113
- * exclusion), `range` is `{lo..hi}` with lo < hi, `floor` is `{lo..*}` with
114
- * lo 2.
110
+ * One capacity bound: a non-negative literal, a u64 field of the TARGET
111
+ * row (the dependent bound per-group capacity read at judge time), or
112
+ * the interval-measure of a TARGET-row field (`Duration(span)`). Names,
113
+ * not ids the spec is the name-level wire; the engine resolves bound
114
+ * names against the target's FULL roster (C1), never the projection.
115
115
  */
116
- type WindowSpec = {
116
+ type CapacityBoundSpec = {
117
+ readonly kind: "lit";
118
+ readonly value: bigint;
119
+ } | {
120
+ readonly kind: "field";
121
+ readonly field: string;
122
+ } | {
123
+ readonly kind: "durationField";
124
+ readonly field: string;
125
+ };
126
+ /**
127
+ * A capacity statement's weight — a TOTAL sum (C4: `unit` is a case, not
128
+ * an absence): the count instance (`unit`), a u64 field of the SOURCE row
129
+ * (`field`), or a SOURCE-row interval's measure (`durationField`). The
130
+ * wire always carries it — a unit statement crosses as `{ kind: "unit" }`,
131
+ * never by omission.
132
+ */
133
+ type WeightSpec = {
134
+ readonly kind: "unit";
135
+ } | {
136
+ readonly kind: "field";
137
+ readonly field: string;
138
+ } | {
139
+ readonly kind: "durationField";
140
+ readonly field: string;
141
+ };
142
+ /**
143
+ * A capacity statement's window — the canonical-utterance law's surviving
144
+ * spellings, per-aggregate where weight-sensitive (design § 6), since the
145
+ * SDK's `within()` mint makes every banned spelling unwritable or a
146
+ * construction error: `exact` is `{n}` (`{0}` the exclusion on the unit
147
+ * instance, "total is zero" on a weighted one), `range` is `{lo..hi}` with
148
+ * lo < hi (`{0..hi}` the canonical ceiling; the hi slot admits a dependent
149
+ * bound — C6: hi only), `floor` is `{lo..*}` (`{1..*}` legal on weighted
150
+ * statements only).
151
+ */
152
+ type CapacityWindowSpec = {
117
153
  readonly kind: "exact";
118
- readonly n: bigint;
154
+ readonly n: CapacityBoundSpec;
119
155
  } | {
120
156
  readonly kind: "range";
121
- readonly lo: bigint;
122
- readonly hi: bigint;
157
+ readonly lo: CapacityBoundSpec;
158
+ readonly hi: CapacityBoundSpec;
123
159
  } | {
124
160
  readonly kind: "floor";
125
- readonly lo: bigint;
161
+ readonly lo: CapacityBoundSpec;
126
162
  };
127
163
  /**
128
164
  * One field: name, structural type, host newtype name — the field's
@@ -145,26 +181,38 @@ interface RowSpec {
145
181
  readonly values: readonly LiteralSpec[];
146
182
  }
147
183
  /**
148
- * One relation. `extension: rows` declares it closed (the option is the
149
- * kind); a closed relation's `fields` are its declared intrinsic columns
150
- * only the synthetic (`id`, u64) handle field is materialized by the
151
- * engine's schema validation. `newtype` is the handle newtype of a closed
152
- * relation (the SDK emits the id's law-computed generator class,
153
- * `` `${name}.id` `` — the same label every referencing field carries by
154
- * law), undefined on an ordinary one.
184
+ * A relation's closedness as ONE sum (ruled 2026-07-23, R7): the handle
185
+ * newtype and the ground axioms travel together the two illegal states
186
+ * (a roster without its newtype, a newtype without its roster) are
187
+ * unspellable on the wire exactly as they are unrepresentable in the
188
+ * fused Rust `RelationSpec`. `newtype` is the id's law-computed generator
189
+ * class (`` `${name}.id` `` — the same label every referencing field
190
+ * carries by law), which is how the engine resolves a handle literal back
191
+ * to its roster.
192
+ */
193
+ interface ClosedSpec {
194
+ readonly newtype: string;
195
+ readonly rows: readonly RowSpec[];
196
+ }
197
+ /**
198
+ * One relation. A present `closed` declares it closed (the option is the
199
+ * kind, one sum — R7); a closed relation's `fields` are its declared
200
+ * intrinsic columns only — the synthetic (`id`, u64) handle field is
201
+ * materialized by the engine's schema validation.
155
202
  */
156
203
  interface RelationSpec {
157
204
  readonly name: string;
158
- readonly newtype: string | undefined;
159
205
  readonly fields: readonly FieldSpec[];
160
- readonly extension: readonly RowSpec[] | undefined;
206
+ readonly closed: ClosedSpec | undefined;
161
207
  }
162
208
  /**
163
209
  * One dependency statement, tagged by form. `==` is not a variant: a
164
210
  * bidirectional containment is `containment` with `bidirectional: true`,
165
211
  * lowered by the engine to the two adjacent containments (`source <=
166
- * target` first). `cardinality` is B-family, target-left: the target is the
167
- * per-group parent, the source is counted.
212
+ * target` first). `capacity` reads as the operator does (C2 — target,
213
+ * weight, window, source): the target is the per-group parent, the source
214
+ * is the weighed side, and the weight is ALWAYS present (`unit` the count
215
+ * instance).
168
216
  */
169
217
  type StatementSpec = {
170
218
  readonly kind: "fd";
@@ -176,9 +224,10 @@ type StatementSpec = {
176
224
  readonly target: SideSpec;
177
225
  readonly bidirectional: boolean;
178
226
  } | {
179
- readonly kind: "cardinality";
227
+ readonly kind: "capacity";
180
228
  readonly target: SideSpec;
181
- readonly window: WindowSpec;
229
+ readonly weight: WeightSpec;
230
+ readonly window: CapacityWindowSpec;
182
231
  readonly source: SideSpec;
183
232
  };
184
233
  /**
@@ -211,11 +260,25 @@ declare function renderLiteral(literal: LiteralSpec): string;
211
260
  */
212
261
  declare function renderLiteralSet(set: LiteralSetSpec): string;
213
262
  /**
214
- * Renders window bounds in their one canonical spelling: `{n}` exact
263
+ * Renders one capacity bound in its one canonical spelling: a literal as
264
+ * digits, a dependent bound bare by field name, an interval-measure bound
265
+ * as `Duration(field)` — the spellings the engine's renderer emits.
266
+ */
267
+ declare function renderCapacityBound(bound: CapacityBoundSpec): string;
268
+ /**
269
+ * Renders a capacity window in its one canonical spelling: `{n}` exact
215
270
  * (`{0}` the exclusion), `{lo..hi}`, `{lo..*}` — the spelling set the
216
- * engine's renderer emits for sealed statements.
271
+ * engine's renderer emits for sealed statements, bounds through
272
+ * {@link renderCapacityBound}.
273
+ */
274
+ declare function renderCapacityWindow(window: CapacityWindowSpec): string;
275
+ /**
276
+ * Renders a capacity weight as the operator's bracket: the unit weight
277
+ * renders NOTHING — the count utterance `<={lo..hi}` falls out of the one
278
+ * printer, never a second "legacy" arm — a field weight as `[field]`, an
279
+ * interval measure as `[Duration(field)]`.
217
280
  */
218
- declare function renderWindow(window: WindowSpec): string;
219
- export type { FieldSpec, LiteralSetSpec, LiteralSpec, RelationSpec, RowSpec, SchemaSpec, SideSpec, StatementSpec, ValueSpec, ValueTypeSpec, WindowSpec };
220
- export { renderLiteral, renderLiteralSet, renderWindow };
281
+ declare function renderWeight(weight: WeightSpec): string;
282
+ export type { CapacityBoundSpec, CapacityWindowSpec, ClosedSpec, FieldSpec, LiteralSetSpec, LiteralSpec, RelationSpec, RowSpec, SchemaSpec, SideSpec, StatementSpec, ValueSpec, ValueTypeSpec, WeightSpec };
283
+ export { renderCapacityBound, renderCapacityWindow, renderLiteral, renderLiteralSet, renderWeight };
221
284
  //# sourceMappingURL=spec.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"spec.d.ts","sourceRoot":"","sources":["../src/spec.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"spec.d.ts","sourceRoot":"","sources":["../src/spec.ts"],"names":[],"mappings":"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"}
package/dist/spec.js CHANGED
@@ -136,19 +136,51 @@ function renderLiteralSet(set) {
136
136
  return `{${set.literals.map(renderLiteral).join(", ")}}`;
137
137
  }
138
138
  /**
139
- * Renders window bounds in their one canonical spelling: `{n}` exact
139
+ * Renders one capacity bound in its one canonical spelling: a literal as
140
+ * digits, a dependent bound bare by field name, an interval-measure bound
141
+ * as `Duration(field)` — the spellings the engine's renderer emits.
142
+ */
143
+ function renderCapacityBound(bound) {
144
+ switch (bound.kind) {
145
+ case "lit":
146
+ return bound.value.toString();
147
+ case "field":
148
+ return bound.field;
149
+ case "durationField":
150
+ return `Duration(${bound.field})`;
151
+ }
152
+ }
153
+ /**
154
+ * Renders a capacity window in its one canonical spelling: `{n}` exact
140
155
  * (`{0}` the exclusion), `{lo..hi}`, `{lo..*}` — the spelling set the
141
- * engine's renderer emits for sealed statements.
156
+ * engine's renderer emits for sealed statements, bounds through
157
+ * {@link renderCapacityBound}.
142
158
  */
143
- function renderWindow(window) {
159
+ function renderCapacityWindow(window) {
144
160
  switch (window.kind) {
145
161
  case "exact":
146
- return `{${window.n}}`;
162
+ return `{${renderCapacityBound(window.n)}}`;
147
163
  case "range":
148
- return `{${window.lo}..${window.hi}}`;
164
+ return `{${renderCapacityBound(window.lo)}..${renderCapacityBound(window.hi)}}`;
149
165
  case "floor":
150
- return `{${window.lo}..*}`;
166
+ return `{${renderCapacityBound(window.lo)}..*}`;
167
+ }
168
+ }
169
+ /**
170
+ * Renders a capacity weight as the operator's bracket: the unit weight
171
+ * renders NOTHING — the count utterance `<={lo..hi}` falls out of the one
172
+ * printer, never a second "legacy" arm — a field weight as `[field]`, an
173
+ * interval measure as `[Duration(field)]`.
174
+ */
175
+ function renderWeight(weight) {
176
+ switch (weight.kind) {
177
+ case "unit":
178
+ return "";
179
+ case "field":
180
+ return `[${weight.field}]`;
181
+ case "durationField":
182
+ return `[Duration(${weight.field})]`;
151
183
  }
152
184
  }
153
- export { renderLiteral, renderLiteralSet, renderWindow };
185
+ export { renderCapacityBound, renderCapacityWindow, renderLiteral, renderLiteralSet, renderWeight };
154
186
  //# sourceMappingURL=spec.js.map
package/dist/spec.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"spec.js","sourceRoot":"","sources":["../src/spec.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"spec.js","sourceRoot":"","sources":["../src/spec.ts"],"names":[],"mappings":"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"}
@@ -2,7 +2,7 @@
2
2
  * Dependency statements as typed values (`docs/architecture/30-dependencies.md`
3
3
  * owns the semantics; `docs/architecture/70-api.md` the surface): the FD key
4
4
  * form, conditional containment, the bidirectional `==` abbreviation, and
5
- * the cardinality window. A statement value is opaque and inert — no
5
+ * the capacity statement. A statement value is opaque and inert — no
6
6
  * methods, no fluent continuation: a fact about the theory, not a builder.
7
7
  *
8
8
  * Every field reference is checked against the relation it names in the
@@ -33,10 +33,10 @@
33
33
  * `Db.create`/`Db.open` (the two-boundary split, engine as final
34
34
  * authority).
35
35
  */
36
- import type { Count } from "#count.ts";
36
+ import { type BoundsOnTarget, type CapacityWeight, type CapacityWindow, type UnitWindowBan, type WeightOnSource } from "#capacity.ts";
37
37
  import { type AnyFace, type FaceData, type SameArity, type SameShapes } from "#face.ts";
38
38
  import type { AnyRelation, RelationFields } from "#relation.ts";
39
- import { type WindowSpec } from "#spec.ts";
39
+ import { type CapacityWindowSpec, type WeightSpec } from "#spec.ts";
40
40
  /** A `key()` statement's runtime description — owner and projection carried at exact types. */
41
41
  interface KeyData<R extends AnyRelation, Projection extends readonly string[]> {
42
42
  readonly kind: "key";
@@ -56,19 +56,45 @@ interface ContainmentData<Src extends FaceData = FaceData, Tgt extends FaceData
56
56
  readonly target: Tgt;
57
57
  readonly bidirectional: boolean;
58
58
  }
59
- /** A window statement's runtime description — target-left, faces at exact types like {@link ContainmentData}. */
60
- interface WindowData<Tgt extends FaceData = FaceData, Src extends FaceData = FaceData> {
61
- readonly kind: "window";
59
+ /**
60
+ * A capacity statement's runtime description target-left, in the
61
+ * operator's own order (C2: target, weight, window, source), faces at
62
+ * exact types like {@link ContainmentData}. The weight is ALWAYS present
63
+ * (C4 — `unit` is a case, not an absence).
64
+ */
65
+ interface CapacityData<Tgt extends FaceData = FaceData, Src extends FaceData = FaceData> {
66
+ readonly kind: "capacity";
62
67
  readonly target: Tgt;
63
- readonly window: WindowSpec;
68
+ readonly weight: WeightSpec;
69
+ readonly window: CapacityWindowSpec;
64
70
  readonly source: Src;
65
71
  }
66
72
  /** One statement's runtime description, tagged by form. */
67
- type StatementData = KeyData<AnyRelation, readonly string[]> | ContainmentData | WindowData;
68
- /** An opaque statement value — what `schema()` assembles into a theory. */
73
+ type StatementData = KeyData<AnyRelation, readonly string[]> | ContainmentData | CapacityData;
74
+ /**
75
+ * The admission brand — a module-private symbol, deliberately unexported
76
+ * (the `capacity.ts` pattern): `Statement` is a public structural type, so
77
+ * without this brand a forged plain object of the right shape would walk
78
+ * past the construction-time arity and roster walls into `schema()` — and
79
+ * the roster wall is the one the engine cannot backstop (the wire carries
80
+ * plain u64s, no rosters). The symbol makes the four constructors the ONLY
81
+ * mints, so a statement that skipped the walls is unspellable.
82
+ */
83
+ declare const admitted: unique symbol;
84
+ /** An opaque statement value — what `schema()` assembles into a theory. Only the four constructors produce one. */
69
85
  interface Statement {
70
86
  readonly data: StatementData;
87
+ readonly [admitted]: true;
71
88
  }
89
+ /**
90
+ * Narrows any value to an admitted statement — the probe is the
91
+ * module-private {@link admitted} brand only the four constructors set, so
92
+ * no host-built value (fact cells are structurally OPEN — an interval with
93
+ * an excess `kind` property is a legal cell) can ever be misread as one.
94
+ * The keyed-get selector dispatch and `schema()`'s admission both judge
95
+ * through here.
96
+ */
97
+ declare function isStatement(value: unknown): value is Statement;
72
98
  /**
73
99
  * A containment (or `==` bijection) statement as a TYPED value: `data`
74
100
  * carries both faces at their exact types, so the schema-level class laws
@@ -80,9 +106,9 @@ interface Statement {
80
106
  interface ContainedStatement<Src extends FaceData, Tgt extends FaceData> extends Statement {
81
107
  readonly data: ContainmentData<Src, Tgt>;
82
108
  }
83
- /** A window statement as a TYPED value — the {@link ContainedStatement} of the window form. */
84
- interface WindowStatement<Tgt extends FaceData, Src extends FaceData> extends Statement {
85
- readonly data: WindowData<Tgt, Src>;
109
+ /** A capacity statement as a TYPED value — the {@link ContainedStatement} of the capacity form. */
110
+ interface CapacityStatement<Tgt extends FaceData, Src extends FaceData> extends Statement {
111
+ readonly data: CapacityData<Tgt, Src>;
86
112
  }
87
113
  /**
88
114
  * A `key()` statement as a TYPED value: its `data` carries the owner
@@ -129,27 +155,38 @@ declare function contained<A extends AnyFace, B extends AnyFace>(source: A, targ
129
155
  */
130
156
  declare function mirrors<A extends AnyFace, B extends AnyFace>(source: A, target: B & SameArity<A, B> & SameShapes<A, B>): ContainedStatement<A["data"], B["data"]>;
131
157
  /**
132
- * `B(Y|ψ) <={window} A(X|φ)` — the cardinality window. READ CAREFULLY: the
133
- * LEFT face is the window's TARGET, the per-group parent (B-family,
134
- * target-left macro parity), and the RIGHT face is the counted source.
135
- * `window(on(Holder, "id"), atMost(3n), on(Account, "holder"))` says: each
136
- * Holder id groups at most three Account rows by holder. The two faces
137
- * pair by arity AND structural shape ({@link SameShapes}), exactly as
138
- * containment the grouping join reads the same positionwise field
139
- * pairing.
158
+ * `B(Y|ψ) <=[w]{window} A(X|φ)` — the capacity statement, the one
159
+ * extension form: per ψ-selected target fact, the group of φ-selected
160
+ * source facts sharing its key tuple must have its MEASURE weight; the
161
+ * unit weight IS the count instance) inside the window. READ CAREFULLY:
162
+ * the LEFT face is the TARGET, the per-group parent (B-family, target-left
163
+ * macro parity), and the RIGHT face is the weighed source. Two
164
+ * overloads mirror the operator positionally (target, weight?, window,
165
+ * source): `capacity(on(Holder, "id"), within(0n, 3n), on(Account,
166
+ * "holder"))` says each Holder id groups at most three Account rows;
167
+ * `capacity(on(Pool, "id"), weigh("watts"), within(0n, ref("supply")),
168
+ * on(Device, "pool"))` bounds each pool's summed draw by the pool's own
169
+ * row. The two faces pair by arity AND structural shape
170
+ * ({@link SameShapes}), exactly as containment — the grouping join reads
171
+ * the same positionwise field pairing. The weight-sensitive `{1..*}` ban
172
+ * rides the UNIT overload only ({@link UnitWindowBan} — on a weighted
173
+ * statement "positive total" is a different, weaker law than containment).
140
174
  */
141
- declare function window<B extends AnyFace, A extends AnyFace>(target: B, count: Count, source: A & SameArity<B, A> & SameShapes<B, A>): WindowStatement<B["data"], A["data"]>;
175
+ declare function capacity<B extends AnyFace, W extends CapacityWindow, A extends AnyFace>(target: B, window: W & UnitWindowBan<W> & BoundsOnTarget<W, B>, source: A & SameArity<B, A> & SameShapes<B, A>): CapacityStatement<B["data"], A["data"]>;
176
+ declare function capacity<B extends AnyFace, M extends CapacityWeight, W extends CapacityWindow, A extends AnyFace>(target: B, weight: M & WeightOnSource<M, A>, window: W & BoundsOnTarget<W, B>, source: A & SameArity<B, A> & SameShapes<B, A>): CapacityStatement<B["data"], A["data"]>;
142
177
  /**
143
178
  * Renders one statement in the CANONICAL macro spelling
144
179
  * (`docs/architecture/70-api.md`; the engine's `schema/render.rs` emits the
145
180
  * same shapes for violations) — `Account(id) -> Account`,
146
181
  * `Account(holder) <= Holder(id)`,
147
182
  * `Account(id | kind == Savings) == SavingsTerms(account)`,
148
- * `Holder(id) <={0..3} Account(holder)` — so TS-side errors and
183
+ * `Holder(id) <={0..3} Account(holder)`,
184
+ * `Pool(id) <=[watts]{0..supply} Device(pool)` — so TS-side errors and
149
185
  * engine-side diagnostics read identically. A renderer, never a parser:
150
- * strings are output-only.
186
+ * strings are output-only. The unit weight renders nothing — the count
187
+ * utterance falls out of the one printer.
151
188
  */
152
189
  declare function renderStatement(statement: Statement): string;
153
- export type { ContainedStatement, ContainmentData, KeyData, KeyStatement, Statement, StatementData, WindowData, WindowStatement };
154
- export { contained, key, mirrors, renderStatement, window };
190
+ export type { CapacityData, CapacityStatement, ContainedStatement, ContainmentData, KeyData, KeyStatement, Statement, StatementData };
191
+ export { capacity, contained, isStatement, key, mirrors, renderStatement };
155
192
  //# sourceMappingURL=statements.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"statements.d.ts","sourceRoot":"","sources":["../src/statements.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"statements.d.ts","sourceRoot":"","sources":["../src/statements.ts"],"names":[],"mappings":"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"}
@@ -2,7 +2,7 @@
2
2
  * Dependency statements as typed values (`docs/architecture/30-dependencies.md`
3
3
  * owns the semantics; `docs/architecture/70-api.md` the surface): the FD key
4
4
  * form, conditional containment, the bidirectional `==` abbreviation, and
5
- * the cardinality window. A statement value is opaque and inert — no
5
+ * the capacity statement. A statement value is opaque and inert — no
6
6
  * methods, no fluent continuation: a fact about the theory, not a builder.
7
7
  *
8
8
  * Every field reference is checked against the relation it names in the
@@ -34,10 +34,32 @@
34
34
  * authority).
35
35
  */
36
36
  import * as errors from "@superbuilders/errors";
37
+ import { isCapacityWeight, isCapacityWindow, unitWeight } from "#capacity.ts";
37
38
  import { isClosedMember, sealedFieldOf } from "#closed.ts";
38
39
  import { renderFace } from "#face.ts";
39
40
  import { rosterOf } from "#fields.ts";
40
- import { renderWindow } from "#spec.ts";
41
+ 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
+ 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
+ function isStatement(value) {
61
+ return typeof value === "object" && value !== null && admitted in value;
62
+ }
41
63
  /** Renders one face position's closedness for the roster-agreement diagnostics. */
42
64
  function renderRosterSide(roster) {
43
65
  return roster === undefined ? "a bare column" : `a ${roster.name} reference`;
@@ -105,7 +127,7 @@ function key(relation, fields) {
105
127
  owner: relation,
106
128
  projection: Object.freeze(fields)
107
129
  });
108
- return Object.freeze({ data });
130
+ return Object.freeze({ data, [admitted]: true });
109
131
  }
110
132
  /**
111
133
  * `A(X|φ) <= B(Y|ψ)` — conditional inclusion, source left. Arity mismatch
@@ -123,7 +145,7 @@ function contained(source, target) {
123
145
  target: target.data,
124
146
  bidirectional: false
125
147
  });
126
- const statement = Object.freeze({ data });
148
+ const statement = Object.freeze({ data, [admitted]: true });
127
149
  assertArityAgreement(data.source, data.target, statement);
128
150
  assertRosterAgreement(data.source, data.target, statement);
129
151
  return statement;
@@ -144,31 +166,90 @@ function mirrors(source, target) {
144
166
  target: target.data,
145
167
  bidirectional: true
146
168
  });
147
- const statement = Object.freeze({ data });
169
+ const statement = Object.freeze({ data, [admitted]: true });
148
170
  assertArityAgreement(data.source, data.target, statement);
149
171
  assertRosterAgreement(data.source, data.target, statement);
150
172
  return statement;
151
173
  }
152
174
  /**
153
- * `B(Y|ψ) <={window} A(X|φ)` the cardinality window. READ CAREFULLY: the
154
- * LEFT face is the window's TARGET, the per-group parent (B-family,
155
- * target-left macro parity), and the RIGHT face is the counted source.
156
- * `window(on(Holder, "id"), atMost(3n), on(Account, "holder"))` says: each
157
- * Holder id groups at most three Account rows by holder. The two faces
158
- * pair by arity AND structural shape ({@link SameShapes}), exactly as
159
- * containment — the grouping join reads the same positionwise field
160
- * pairing.
175
+ * The runtime twin of the weight source wall ({@link WeightOnSource}): the
176
+ * weighed field must be a u64-encoded position of the SOURCE's own row
177
+ * (a signed weight would break the polarity scheduler the illegal weight
178
+ * is unrepresentable, not checked), an interval position for the
179
+ * `Duration(...)` form. Judged at CONSTRUCTION for untyped callers; the
180
+ * engine's `validate_capacity` stays the final authority.
181
+ */
182
+ function assertWeightOnSource(weight, source, statement) {
183
+ if (weight.kind === "unit") {
184
+ return;
185
+ }
186
+ const field = sealedFieldOf(source.owner, weight.field);
187
+ if (field === undefined) {
188
+ throw errors.new(`${source.owner.name} has no field ${weight.field} — a weight names a field of the SOURCE's own row (the weight vocabulary is closed at the row) — ${renderStatement(statement)}`);
189
+ }
190
+ if (weight.kind === "field" && field.kind !== "u64") {
191
+ throw errors.new(`${source.owner.name}.${weight.field} is ${field.kind}, not u64 — a weight is u64-encoded (a signed weight would break the polarity scheduler: an insert could lower a sum) — ${renderStatement(statement)}`);
192
+ }
193
+ if (weight.kind === "durationField" && field.kind !== "interval") {
194
+ throw errors.new(`${source.owner.name}.${weight.field} is ${field.kind}, not an interval — Duration(...) weighs an interval field's measure — ${renderStatement(statement)}`);
195
+ }
196
+ }
197
+ /**
198
+ * The runtime twin of the dependent-bound target wall
199
+ * ({@link BoundsOnTarget}): a `ref()` bound must name a u64 field of the
200
+ * TARGET's own row, a `duration()` bound an interval field — bound names
201
+ * resolve against the target's FULL roster (C1), never the projection.
202
+ * `within()` mints dependent bounds in the hi slot only (C6), but the walk
203
+ * here is total over the window's bound slots.
161
204
  */
162
- function window(target, count, source) {
205
+ function assertBoundsOnTarget(window, target, statement) {
206
+ const bounds = window.kind === "range" ? [window.lo, window.hi] : [window.kind === "exact" ? window.n : window.lo];
207
+ for (const bound of bounds) {
208
+ if (bound.kind === "lit") {
209
+ continue;
210
+ }
211
+ const field = sealedFieldOf(target.owner, bound.field);
212
+ if (field === undefined) {
213
+ throw errors.new(`${target.owner.name} has no field ${bound.field} — a dependent bound names a field of the TARGET's own row (bound names resolve against the target's full roster) — ${renderStatement(statement)}`);
214
+ }
215
+ if (bound.kind === "field" && field.kind !== "u64") {
216
+ throw errors.new(`${target.owner.name}.${bound.field} is ${field.kind}, not u64 — a dependent bound reads a u64 field of the TARGET row (Duration(...) is the interval-measure spelling) — ${renderStatement(statement)}`);
217
+ }
218
+ if (bound.kind === "durationField" && field.kind !== "interval") {
219
+ throw errors.new(`${target.owner.name}.${bound.field} is ${field.kind}, not an interval — Duration(...) bounds by an interval field's measure — ${renderStatement(statement)}`);
220
+ }
221
+ }
222
+ }
223
+ function capacity(target, second, third, fourth) {
224
+ const weighted = fourth !== undefined;
225
+ const windowValue = weighted ? third : second;
226
+ const source = weighted ? fourth : third;
227
+ if (!isCapacityWindow(windowValue)) {
228
+ throw errors.new("a capacity window is minted only by within() — a structural literal skips the ban table (the canonical-utterance law)");
229
+ }
230
+ let weight = unitWeight;
231
+ if (weighted) {
232
+ if (!isCapacityWeight(second)) {
233
+ throw errors.new("a capacity weight is minted only by weigh() — a structural literal skips the row-local weight wall");
234
+ }
235
+ weight = second.weight;
236
+ }
237
+ const window = windowValue.window;
238
+ if (weight.kind === "unit" && window.kind === "floor" && window.lo.kind === "lit" && window.lo.value === 1n) {
239
+ 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)");
240
+ }
163
241
  const data = Object.freeze({
164
- kind: "window",
242
+ kind: "capacity",
165
243
  target: target.data,
166
- window: count.window,
244
+ weight,
245
+ window,
167
246
  source: source.data
168
247
  });
169
- const statement = Object.freeze({ data });
248
+ const statement = Object.freeze({ data, [admitted]: true });
170
249
  assertArityAgreement(data.source, data.target, statement);
171
250
  assertRosterAgreement(data.source, data.target, statement);
251
+ assertWeightOnSource(weight, data.source, statement);
252
+ assertBoundsOnTarget(window, data.target, statement);
172
253
  return statement;
173
254
  }
174
255
  /**
@@ -177,9 +258,11 @@ function window(target, count, source) {
177
258
  * same shapes for violations) — `Account(id) -> Account`,
178
259
  * `Account(holder) <= Holder(id)`,
179
260
  * `Account(id | kind == Savings) == SavingsTerms(account)`,
180
- * `Holder(id) <={0..3} Account(holder)` — so TS-side errors and
261
+ * `Holder(id) <={0..3} Account(holder)`,
262
+ * `Pool(id) <=[watts]{0..supply} Device(pool)` — so TS-side errors and
181
263
  * engine-side diagnostics read identically. A renderer, never a parser:
182
- * strings are output-only.
264
+ * strings are output-only. The unit weight renders nothing — the count
265
+ * utterance falls out of the one printer.
183
266
  */
184
267
  function renderStatement(statement) {
185
268
  const data = statement.data;
@@ -190,9 +273,9 @@ function renderStatement(statement) {
190
273
  const operator = data.bidirectional ? "==" : "<=";
191
274
  return `${renderFace(data.source)} ${operator} ${renderFace(data.target)}`;
192
275
  }
193
- case "window":
194
- return `${renderFace(data.target)} <=${renderWindow(data.window)} ${renderFace(data.source)}`;
276
+ case "capacity":
277
+ return `${renderFace(data.target)} <=${renderWeight(data.weight)}${renderCapacityWindow(data.window)} ${renderFace(data.source)}`;
195
278
  }
196
279
  }
197
- export { contained, key, mirrors, renderStatement, window };
280
+ export { capacity, contained, isStatement, key, mirrors, renderStatement };
198
281
  //# sourceMappingURL=statements.js.map