@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.
- package/COOKBOOK.md +150 -9
- package/README.md +18 -5
- package/dist/capacity.d.ts +310 -0
- package/dist/capacity.d.ts.map +1 -0
- package/dist/capacity.js +138 -0
- package/dist/capacity.js.map +1 -0
- package/dist/closed.d.ts +7 -5
- package/dist/closed.d.ts.map +1 -1
- package/dist/closed.js +4 -1
- package/dist/closed.js.map +1 -1
- package/dist/db.d.ts +115 -76
- package/dist/db.d.ts.map +1 -1
- package/dist/db.js +178 -122
- package/dist/db.js.map +1 -1
- package/dist/exhume.d.ts +22 -10
- package/dist/exhume.d.ts.map +1 -1
- package/dist/exhume.js +42 -9
- package/dist/exhume.js.map +1 -1
- package/dist/face.d.ts +11 -7
- package/dist/face.d.ts.map +1 -1
- package/dist/face.js.map +1 -1
- package/dist/fields.d.ts +38 -16
- package/dist/fields.d.ts.map +1 -1
- package/dist/fields.js +33 -8
- package/dist/fields.js.map +1 -1
- package/dist/index.d.ts +8 -8
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3 -3
- package/dist/index.js.map +1 -1
- package/dist/law.d.ts +3 -2
- package/dist/law.d.ts.map +1 -1
- package/dist/law.js +1 -1
- package/dist/law.js.map +1 -1
- package/dist/lower.d.ts +9 -9
- package/dist/lower.d.ts.map +1 -1
- package/dist/lower.js +20 -14
- package/dist/lower.js.map +1 -1
- package/dist/marshal.d.ts +17 -7
- package/dist/marshal.d.ts.map +1 -1
- package/dist/marshal.js +32 -10
- package/dist/marshal.js.map +1 -1
- package/dist/native.d.ts +66 -12
- package/dist/native.d.ts.map +1 -1
- package/dist/native.js.map +1 -1
- package/dist/query/atom.d.ts +72 -7
- package/dist/query/atom.d.ts.map +1 -1
- package/dist/query/atom.js +12 -9
- package/dist/query/atom.js.map +1 -1
- package/dist/query/lower.d.ts +8 -0
- package/dist/query/lower.d.ts.map +1 -1
- package/dist/query/lower.js +80 -13
- package/dist/query/lower.js.map +1 -1
- package/dist/query/run.d.ts +5 -5
- package/dist/query/run.d.ts.map +1 -1
- package/dist/query/run.js +7 -12
- package/dist/query/run.js.map +1 -1
- package/dist/query/scope.d.ts +15 -5
- package/dist/query/scope.d.ts.map +1 -1
- package/dist/query/scope.js.map +1 -1
- package/dist/relation.d.ts.map +1 -1
- package/dist/relation.js +3 -1
- package/dist/relation.js.map +1 -1
- package/dist/schema.d.ts.map +1 -1
- package/dist/schema.js +12 -2
- package/dist/schema.js.map +1 -1
- package/dist/spec.d.ts +95 -32
- package/dist/spec.d.ts.map +1 -1
- package/dist/spec.js +39 -7
- package/dist/spec.js.map +1 -1
- package/dist/statements.d.ts +62 -25
- package/dist/statements.d.ts.map +1 -1
- package/dist/statements.js +105 -22
- package/dist/statements.js.map +1 -1
- package/package.json +3 -3
- package/src/capacity.ts +454 -0
- package/src/closed.ts +13 -7
- package/src/db.ts +302 -184
- package/src/exhume.ts +48 -11
- package/src/face.ts +14 -6
- package/src/fields.ts +51 -15
- package/src/index.ts +20 -9
- package/src/law.ts +3 -2
- package/src/lower.ts +20 -14
- package/src/marshal.ts +38 -13
- package/src/native.ts +65 -11
- package/src/query/atom.ts +119 -15
- package/src/query/lower.ts +117 -15
- package/src/query/run.ts +7 -12
- package/src/query/scope.ts +15 -6
- package/src/relation.ts +3 -1
- package/src/schema.ts +14 -2
- package/src/spec.ts +112 -34
- package/src/statements.ts +188 -38
- package/dist/count.d.ts +0 -102
- package/dist/count.d.ts.map +0 -1
- package/dist/count.js +0 -115
- package/dist/count.js.map +0 -1
- package/src/count.ts +0 -211
package/src/spec.ts
CHANGED
|
@@ -72,10 +72,10 @@ type LiteralSetSpec =
|
|
|
72
72
|
| { readonly kind: "many"; readonly literals: readonly LiteralSpec[] }
|
|
73
73
|
|
|
74
74
|
/**
|
|
75
|
-
* One side of a containment or
|
|
76
|
-
* all names. `projection` is π in the
|
|
77
|
-
* pairing with the other side);
|
|
78
|
-
* pairs, read conjunctively.
|
|
75
|
+
* One side of a containment or capacity statement:
|
|
76
|
+
* `R(fields… | field == literal…)`, all names. `projection` is π in the
|
|
77
|
+
* statement's written order (positional pairing with the other side);
|
|
78
|
+
* `selection` is σ as (field, literal-or-set) pairs, read conjunctively.
|
|
79
79
|
*/
|
|
80
80
|
interface SideSpec {
|
|
81
81
|
readonly relation: string
|
|
@@ -84,16 +84,43 @@ interface SideSpec {
|
|
|
84
84
|
}
|
|
85
85
|
|
|
86
86
|
/**
|
|
87
|
-
*
|
|
88
|
-
*
|
|
89
|
-
*
|
|
90
|
-
*
|
|
91
|
-
*
|
|
87
|
+
* One capacity bound: a non-negative literal, a u64 field of the TARGET
|
|
88
|
+
* row (the dependent bound — per-group capacity read at judge time), or
|
|
89
|
+
* the interval-measure of a TARGET-row field (`Duration(span)`). Names,
|
|
90
|
+
* not ids — the spec is the name-level wire; the engine resolves bound
|
|
91
|
+
* names against the target's FULL roster (C1), never the projection.
|
|
92
92
|
*/
|
|
93
|
-
type
|
|
94
|
-
| { readonly kind: "
|
|
95
|
-
| { readonly kind: "
|
|
96
|
-
| { readonly kind: "
|
|
93
|
+
type CapacityBoundSpec =
|
|
94
|
+
| { readonly kind: "lit"; readonly value: bigint }
|
|
95
|
+
| { readonly kind: "field"; readonly field: string }
|
|
96
|
+
| { readonly kind: "durationField"; readonly field: string }
|
|
97
|
+
|
|
98
|
+
/**
|
|
99
|
+
* A capacity statement's weight — a TOTAL sum (C4: `unit` is a case, not
|
|
100
|
+
* an absence): the count instance (`unit`), a u64 field of the SOURCE row
|
|
101
|
+
* (`field`), or a SOURCE-row interval's measure (`durationField`). The
|
|
102
|
+
* wire always carries it — a unit statement crosses as `{ kind: "unit" }`,
|
|
103
|
+
* never by omission.
|
|
104
|
+
*/
|
|
105
|
+
type WeightSpec =
|
|
106
|
+
| { readonly kind: "unit" }
|
|
107
|
+
| { readonly kind: "field"; readonly field: string }
|
|
108
|
+
| { readonly kind: "durationField"; readonly field: string }
|
|
109
|
+
|
|
110
|
+
/**
|
|
111
|
+
* A capacity statement's window — the canonical-utterance law's surviving
|
|
112
|
+
* spellings, per-aggregate where weight-sensitive (design § 6), since the
|
|
113
|
+
* SDK's `within()` mint makes every banned spelling unwritable or a
|
|
114
|
+
* construction error: `exact` is `{n}` (`{0}` the exclusion on the unit
|
|
115
|
+
* instance, "total is zero" on a weighted one), `range` is `{lo..hi}` with
|
|
116
|
+
* lo < hi (`{0..hi}` the canonical ceiling; the hi slot admits a dependent
|
|
117
|
+
* bound — C6: hi only), `floor` is `{lo..*}` (`{1..*}` legal on weighted
|
|
118
|
+
* statements only).
|
|
119
|
+
*/
|
|
120
|
+
type CapacityWindowSpec =
|
|
121
|
+
| { readonly kind: "exact"; readonly n: CapacityBoundSpec }
|
|
122
|
+
| { readonly kind: "range"; readonly lo: CapacityBoundSpec; readonly hi: CapacityBoundSpec }
|
|
123
|
+
| { readonly kind: "floor"; readonly lo: CapacityBoundSpec }
|
|
97
124
|
|
|
98
125
|
/**
|
|
99
126
|
* One field: name, structural type, host newtype name — the field's
|
|
@@ -118,27 +145,40 @@ interface RowSpec {
|
|
|
118
145
|
}
|
|
119
146
|
|
|
120
147
|
/**
|
|
121
|
-
*
|
|
122
|
-
*
|
|
123
|
-
*
|
|
124
|
-
*
|
|
125
|
-
*
|
|
126
|
-
* `` `${name}.id` `` — the same label every referencing field
|
|
127
|
-
* law),
|
|
148
|
+
* A relation's closedness as ONE sum (ruled 2026-07-23, R7): the handle
|
|
149
|
+
* newtype and the ground axioms travel together — the two illegal states
|
|
150
|
+
* (a roster without its newtype, a newtype without its roster) are
|
|
151
|
+
* unspellable on the wire exactly as they are unrepresentable in the
|
|
152
|
+
* fused Rust `RelationSpec`. `newtype` is the id's law-computed generator
|
|
153
|
+
* class (`` `${name}.id` `` — the same label every referencing field
|
|
154
|
+
* carries by law), which is how the engine resolves a handle literal back
|
|
155
|
+
* to its roster.
|
|
156
|
+
*/
|
|
157
|
+
interface ClosedSpec {
|
|
158
|
+
readonly newtype: string
|
|
159
|
+
readonly rows: readonly RowSpec[]
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
/**
|
|
163
|
+
* One relation. A present `closed` declares it closed (the option is the
|
|
164
|
+
* kind, one sum — R7); a closed relation's `fields` are its declared
|
|
165
|
+
* intrinsic columns only — the synthetic (`id`, u64) handle field is
|
|
166
|
+
* materialized by the engine's schema validation.
|
|
128
167
|
*/
|
|
129
168
|
interface RelationSpec {
|
|
130
169
|
readonly name: string
|
|
131
|
-
readonly newtype: string | undefined
|
|
132
170
|
readonly fields: readonly FieldSpec[]
|
|
133
|
-
readonly
|
|
171
|
+
readonly closed: ClosedSpec | undefined
|
|
134
172
|
}
|
|
135
173
|
|
|
136
174
|
/**
|
|
137
175
|
* One dependency statement, tagged by form. `==` is not a variant: a
|
|
138
176
|
* bidirectional containment is `containment` with `bidirectional: true`,
|
|
139
177
|
* lowered by the engine to the two adjacent containments (`source <=
|
|
140
|
-
* target` first). `
|
|
141
|
-
* per-group parent, the source
|
|
178
|
+
* target` first). `capacity` reads as the operator does (C2 — target,
|
|
179
|
+
* weight, window, source): the target is the per-group parent, the source
|
|
180
|
+
* is the weighed side, and the weight is ALWAYS present (`unit` the count
|
|
181
|
+
* instance).
|
|
142
182
|
*/
|
|
143
183
|
type StatementSpec =
|
|
144
184
|
| { readonly kind: "fd"; readonly relation: string; readonly projection: readonly string[] }
|
|
@@ -149,9 +189,10 @@ type StatementSpec =
|
|
|
149
189
|
readonly bidirectional: boolean
|
|
150
190
|
}
|
|
151
191
|
| {
|
|
152
|
-
readonly kind: "
|
|
192
|
+
readonly kind: "capacity"
|
|
153
193
|
readonly target: SideSpec
|
|
154
|
-
readonly
|
|
194
|
+
readonly weight: WeightSpec
|
|
195
|
+
readonly window: CapacityWindowSpec
|
|
155
196
|
readonly source: SideSpec
|
|
156
197
|
}
|
|
157
198
|
|
|
@@ -297,22 +338,59 @@ function renderLiteralSet(set: LiteralSetSpec): string {
|
|
|
297
338
|
}
|
|
298
339
|
|
|
299
340
|
/**
|
|
300
|
-
* Renders
|
|
341
|
+
* Renders one capacity bound in its one canonical spelling: a literal as
|
|
342
|
+
* digits, a dependent bound bare by field name, an interval-measure bound
|
|
343
|
+
* as `Duration(field)` — the spellings the engine's renderer emits.
|
|
344
|
+
*/
|
|
345
|
+
function renderCapacityBound(bound: CapacityBoundSpec): string {
|
|
346
|
+
switch (bound.kind) {
|
|
347
|
+
case "lit":
|
|
348
|
+
return bound.value.toString()
|
|
349
|
+
case "field":
|
|
350
|
+
return bound.field
|
|
351
|
+
case "durationField":
|
|
352
|
+
return `Duration(${bound.field})`
|
|
353
|
+
}
|
|
354
|
+
}
|
|
355
|
+
|
|
356
|
+
/**
|
|
357
|
+
* Renders a capacity window in its one canonical spelling: `{n}` exact
|
|
301
358
|
* (`{0}` the exclusion), `{lo..hi}`, `{lo..*}` — the spelling set the
|
|
302
|
-
* engine's renderer emits for sealed statements
|
|
359
|
+
* engine's renderer emits for sealed statements, bounds through
|
|
360
|
+
* {@link renderCapacityBound}.
|
|
303
361
|
*/
|
|
304
|
-
function
|
|
362
|
+
function renderCapacityWindow(window: CapacityWindowSpec): string {
|
|
305
363
|
switch (window.kind) {
|
|
306
364
|
case "exact":
|
|
307
|
-
return `{${window.n}}`
|
|
365
|
+
return `{${renderCapacityBound(window.n)}}`
|
|
308
366
|
case "range":
|
|
309
|
-
return `{${window.lo}..${window.hi}}`
|
|
367
|
+
return `{${renderCapacityBound(window.lo)}..${renderCapacityBound(window.hi)}}`
|
|
310
368
|
case "floor":
|
|
311
|
-
return `{${window.lo}..*}`
|
|
369
|
+
return `{${renderCapacityBound(window.lo)}..*}`
|
|
370
|
+
}
|
|
371
|
+
}
|
|
372
|
+
|
|
373
|
+
/**
|
|
374
|
+
* Renders a capacity weight as the operator's bracket: the unit weight
|
|
375
|
+
* renders NOTHING — the count utterance `<={lo..hi}` falls out of the one
|
|
376
|
+
* printer, never a second "legacy" arm — a field weight as `[field]`, an
|
|
377
|
+
* interval measure as `[Duration(field)]`.
|
|
378
|
+
*/
|
|
379
|
+
function renderWeight(weight: WeightSpec): string {
|
|
380
|
+
switch (weight.kind) {
|
|
381
|
+
case "unit":
|
|
382
|
+
return ""
|
|
383
|
+
case "field":
|
|
384
|
+
return `[${weight.field}]`
|
|
385
|
+
case "durationField":
|
|
386
|
+
return `[Duration(${weight.field})]`
|
|
312
387
|
}
|
|
313
388
|
}
|
|
314
389
|
|
|
315
390
|
export type {
|
|
391
|
+
CapacityBoundSpec,
|
|
392
|
+
CapacityWindowSpec,
|
|
393
|
+
ClosedSpec,
|
|
316
394
|
FieldSpec,
|
|
317
395
|
LiteralSetSpec,
|
|
318
396
|
LiteralSpec,
|
|
@@ -323,6 +401,6 @@ export type {
|
|
|
323
401
|
StatementSpec,
|
|
324
402
|
ValueSpec,
|
|
325
403
|
ValueTypeSpec,
|
|
326
|
-
|
|
404
|
+
WeightSpec
|
|
327
405
|
}
|
|
328
|
-
export { renderLiteral, renderLiteralSet,
|
|
406
|
+
export { renderCapacityBound, renderCapacityWindow, renderLiteral, renderLiteralSet, renderWeight }
|
package/src/statements.ts
CHANGED
|
@@ -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
|
|
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
|
|
@@ -35,12 +35,21 @@
|
|
|
35
35
|
*/
|
|
36
36
|
|
|
37
37
|
import * as errors from "@superbuilders/errors"
|
|
38
|
+
import {
|
|
39
|
+
type BoundsOnTarget,
|
|
40
|
+
type CapacityWeight,
|
|
41
|
+
type CapacityWindow,
|
|
42
|
+
isCapacityWeight,
|
|
43
|
+
isCapacityWindow,
|
|
44
|
+
type UnitWindowBan,
|
|
45
|
+
unitWeight,
|
|
46
|
+
type WeightOnSource
|
|
47
|
+
} from "#capacity.ts"
|
|
38
48
|
import { isClosedMember, sealedFieldOf } from "#closed.ts"
|
|
39
|
-
import type { Count } from "#count.ts"
|
|
40
49
|
import { type AnyFace, type FaceData, renderFace, type SameArity, type SameShapes } from "#face.ts"
|
|
41
50
|
import { type ClosedRoster, rosterOf } from "#fields.ts"
|
|
42
51
|
import type { AnyRelation, RelationFields } from "#relation.ts"
|
|
43
|
-
import {
|
|
52
|
+
import { type CapacityWindowSpec, renderCapacityWindow, renderWeight, type WeightSpec } from "#spec.ts"
|
|
44
53
|
|
|
45
54
|
/** A `key()` statement's runtime description — owner and projection carried at exact types. */
|
|
46
55
|
interface KeyData<R extends AnyRelation, Projection extends readonly string[]> {
|
|
@@ -63,20 +72,50 @@ interface ContainmentData<Src extends FaceData = FaceData, Tgt extends FaceData
|
|
|
63
72
|
readonly bidirectional: boolean
|
|
64
73
|
}
|
|
65
74
|
|
|
66
|
-
/**
|
|
67
|
-
|
|
68
|
-
|
|
75
|
+
/**
|
|
76
|
+
* A capacity statement's runtime description — target-left, in the
|
|
77
|
+
* operator's own order (C2: target, weight, window, source), faces at
|
|
78
|
+
* exact types like {@link ContainmentData}. The weight is ALWAYS present
|
|
79
|
+
* (C4 — `unit` is a case, not an absence).
|
|
80
|
+
*/
|
|
81
|
+
interface CapacityData<Tgt extends FaceData = FaceData, Src extends FaceData = FaceData> {
|
|
82
|
+
readonly kind: "capacity"
|
|
69
83
|
readonly target: Tgt
|
|
70
|
-
readonly
|
|
84
|
+
readonly weight: WeightSpec
|
|
85
|
+
readonly window: CapacityWindowSpec
|
|
71
86
|
readonly source: Src
|
|
72
87
|
}
|
|
73
88
|
|
|
74
89
|
/** One statement's runtime description, tagged by form. */
|
|
75
|
-
type StatementData = KeyData<AnyRelation, readonly string[]> | ContainmentData |
|
|
90
|
+
type StatementData = KeyData<AnyRelation, readonly string[]> | ContainmentData | CapacityData
|
|
76
91
|
|
|
77
|
-
/**
|
|
92
|
+
/**
|
|
93
|
+
* The admission brand — a module-private symbol, deliberately unexported
|
|
94
|
+
* (the `capacity.ts` pattern): `Statement` is a public structural type, so
|
|
95
|
+
* without this brand a forged plain object of the right shape would walk
|
|
96
|
+
* past the construction-time arity and roster walls into `schema()` — and
|
|
97
|
+
* the roster wall is the one the engine cannot backstop (the wire carries
|
|
98
|
+
* plain u64s, no rosters). The symbol makes the four constructors the ONLY
|
|
99
|
+
* mints, so a statement that skipped the walls is unspellable.
|
|
100
|
+
*/
|
|
101
|
+
const admitted: unique symbol = Symbol("bumbledb.statement.admitted")
|
|
102
|
+
|
|
103
|
+
/** An opaque statement value — what `schema()` assembles into a theory. Only the four constructors produce one. */
|
|
78
104
|
interface Statement {
|
|
79
105
|
readonly data: StatementData
|
|
106
|
+
readonly [admitted]: true
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
/**
|
|
110
|
+
* Narrows any value to an admitted statement — the probe is the
|
|
111
|
+
* module-private {@link admitted} brand only the four constructors set, so
|
|
112
|
+
* no host-built value (fact cells are structurally OPEN — an interval with
|
|
113
|
+
* an excess `kind` property is a legal cell) can ever be misread as one.
|
|
114
|
+
* The keyed-get selector dispatch and `schema()`'s admission both judge
|
|
115
|
+
* through here.
|
|
116
|
+
*/
|
|
117
|
+
function isStatement(value: unknown): value is Statement {
|
|
118
|
+
return typeof value === "object" && value !== null && admitted in value
|
|
80
119
|
}
|
|
81
120
|
|
|
82
121
|
/**
|
|
@@ -91,9 +130,9 @@ interface ContainedStatement<Src extends FaceData, Tgt extends FaceData> extends
|
|
|
91
130
|
readonly data: ContainmentData<Src, Tgt>
|
|
92
131
|
}
|
|
93
132
|
|
|
94
|
-
/** A
|
|
95
|
-
interface
|
|
96
|
-
readonly data:
|
|
133
|
+
/** A capacity statement as a TYPED value — the {@link ContainedStatement} of the capacity form. */
|
|
134
|
+
interface CapacityStatement<Tgt extends FaceData, Src extends FaceData> extends Statement {
|
|
135
|
+
readonly data: CapacityData<Tgt, Src>
|
|
97
136
|
}
|
|
98
137
|
|
|
99
138
|
/**
|
|
@@ -188,7 +227,7 @@ function key<
|
|
|
188
227
|
owner: relation,
|
|
189
228
|
projection: Object.freeze(fields)
|
|
190
229
|
})
|
|
191
|
-
return Object.freeze({ data })
|
|
230
|
+
return Object.freeze({ data, [admitted]: true as const })
|
|
192
231
|
}
|
|
193
232
|
|
|
194
233
|
/**
|
|
@@ -210,7 +249,7 @@ function contained<A extends AnyFace, B extends AnyFace>(
|
|
|
210
249
|
target: target.data,
|
|
211
250
|
bidirectional: false
|
|
212
251
|
})
|
|
213
|
-
const statement = Object.freeze({ data })
|
|
252
|
+
const statement = Object.freeze({ data, [admitted]: true as const })
|
|
214
253
|
assertArityAgreement(data.source, data.target, statement)
|
|
215
254
|
assertRosterAgreement(data.source, data.target, statement)
|
|
216
255
|
return statement
|
|
@@ -235,36 +274,145 @@ function mirrors<A extends AnyFace, B extends AnyFace>(
|
|
|
235
274
|
target: target.data,
|
|
236
275
|
bidirectional: true
|
|
237
276
|
})
|
|
238
|
-
const statement = Object.freeze({ data })
|
|
277
|
+
const statement = Object.freeze({ data, [admitted]: true as const })
|
|
239
278
|
assertArityAgreement(data.source, data.target, statement)
|
|
240
279
|
assertRosterAgreement(data.source, data.target, statement)
|
|
241
280
|
return statement
|
|
242
281
|
}
|
|
243
282
|
|
|
244
283
|
/**
|
|
245
|
-
*
|
|
246
|
-
*
|
|
247
|
-
*
|
|
248
|
-
*
|
|
249
|
-
*
|
|
250
|
-
*
|
|
251
|
-
|
|
252
|
-
|
|
284
|
+
* The runtime twin of the weight source wall ({@link WeightOnSource}): the
|
|
285
|
+
* weighed field must be a u64-encoded position of the SOURCE's own row
|
|
286
|
+
* (a signed weight would break the polarity scheduler — the illegal weight
|
|
287
|
+
* is unrepresentable, not checked), an interval position for the
|
|
288
|
+
* `Duration(...)` form. Judged at CONSTRUCTION for untyped callers; the
|
|
289
|
+
* engine's `validate_capacity` stays the final authority.
|
|
290
|
+
*/
|
|
291
|
+
function assertWeightOnSource(weight: WeightSpec, source: FaceData, statement: Statement): void {
|
|
292
|
+
if (weight.kind === "unit") {
|
|
293
|
+
return
|
|
294
|
+
}
|
|
295
|
+
const field = sealedFieldOf(source.owner, weight.field)
|
|
296
|
+
if (field === undefined) {
|
|
297
|
+
throw errors.new(
|
|
298
|
+
`${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)}`
|
|
299
|
+
)
|
|
300
|
+
}
|
|
301
|
+
if (weight.kind === "field" && field.kind !== "u64") {
|
|
302
|
+
throw errors.new(
|
|
303
|
+
`${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)}`
|
|
304
|
+
)
|
|
305
|
+
}
|
|
306
|
+
if (weight.kind === "durationField" && field.kind !== "interval") {
|
|
307
|
+
throw errors.new(
|
|
308
|
+
`${source.owner.name}.${weight.field} is ${field.kind}, not an interval — Duration(...) weighs an interval field's measure — ${renderStatement(statement)}`
|
|
309
|
+
)
|
|
310
|
+
}
|
|
311
|
+
}
|
|
312
|
+
|
|
313
|
+
/**
|
|
314
|
+
* The runtime twin of the dependent-bound target wall
|
|
315
|
+
* ({@link BoundsOnTarget}): a `ref()` bound must name a u64 field of the
|
|
316
|
+
* TARGET's own row, a `duration()` bound an interval field — bound names
|
|
317
|
+
* resolve against the target's FULL roster (C1), never the projection.
|
|
318
|
+
* `within()` mints dependent bounds in the hi slot only (C6), but the walk
|
|
319
|
+
* here is total over the window's bound slots.
|
|
320
|
+
*/
|
|
321
|
+
function assertBoundsOnTarget(window: CapacityWindowSpec, target: FaceData, statement: Statement): void {
|
|
322
|
+
const bounds = window.kind === "range" ? [window.lo, window.hi] : [window.kind === "exact" ? window.n : window.lo]
|
|
323
|
+
for (const bound of bounds) {
|
|
324
|
+
if (bound.kind === "lit") {
|
|
325
|
+
continue
|
|
326
|
+
}
|
|
327
|
+
const field = sealedFieldOf(target.owner, bound.field)
|
|
328
|
+
if (field === undefined) {
|
|
329
|
+
throw errors.new(
|
|
330
|
+
`${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)}`
|
|
331
|
+
)
|
|
332
|
+
}
|
|
333
|
+
if (bound.kind === "field" && field.kind !== "u64") {
|
|
334
|
+
throw errors.new(
|
|
335
|
+
`${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)}`
|
|
336
|
+
)
|
|
337
|
+
}
|
|
338
|
+
if (bound.kind === "durationField" && field.kind !== "interval") {
|
|
339
|
+
throw errors.new(
|
|
340
|
+
`${target.owner.name}.${bound.field} is ${field.kind}, not an interval — Duration(...) bounds by an interval field's measure — ${renderStatement(statement)}`
|
|
341
|
+
)
|
|
342
|
+
}
|
|
343
|
+
}
|
|
344
|
+
}
|
|
345
|
+
|
|
346
|
+
/**
|
|
347
|
+
* `B(Y|ψ) <=[w]{window} A(X|φ)` — the capacity statement, the one
|
|
348
|
+
* extension form: per ψ-selected target fact, the group of φ-selected
|
|
349
|
+
* source facts sharing its key tuple must have its MEASURE (Σ weight; the
|
|
350
|
+
* unit weight IS the count instance) inside the window. READ CAREFULLY:
|
|
351
|
+
* the LEFT face is the TARGET, the per-group parent (B-family, target-left
|
|
352
|
+
* — macro parity), and the RIGHT face is the weighed source. Two
|
|
353
|
+
* overloads mirror the operator positionally (target, weight?, window,
|
|
354
|
+
* source): `capacity(on(Holder, "id"), within(0n, 3n), on(Account,
|
|
355
|
+
* "holder"))` says each Holder id groups at most three Account rows;
|
|
356
|
+
* `capacity(on(Pool, "id"), weigh("watts"), within(0n, ref("supply")),
|
|
357
|
+
* on(Device, "pool"))` bounds each pool's summed draw by the pool's own
|
|
358
|
+
* row. The two faces pair by arity AND structural shape
|
|
359
|
+
* ({@link SameShapes}), exactly as containment — the grouping join reads
|
|
360
|
+
* the same positionwise field pairing. The weight-sensitive `{1..*}` ban
|
|
361
|
+
* rides the UNIT overload only ({@link UnitWindowBan} — on a weighted
|
|
362
|
+
* statement "positive total" is a different, weaker law than containment).
|
|
253
363
|
*/
|
|
254
|
-
function
|
|
364
|
+
function capacity<B extends AnyFace, W extends CapacityWindow, A extends AnyFace>(
|
|
255
365
|
target: B,
|
|
256
|
-
|
|
366
|
+
window: W & UnitWindowBan<W> & BoundsOnTarget<W, B>,
|
|
257
367
|
source: A & SameArity<B, A> & SameShapes<B, A>
|
|
258
|
-
):
|
|
259
|
-
|
|
260
|
-
|
|
368
|
+
): CapacityStatement<B["data"], A["data"]>
|
|
369
|
+
function capacity<B extends AnyFace, M extends CapacityWeight, W extends CapacityWindow, A extends AnyFace>(
|
|
370
|
+
target: B,
|
|
371
|
+
weight: M & WeightOnSource<M, A>,
|
|
372
|
+
window: W & BoundsOnTarget<W, B>,
|
|
373
|
+
source: A & SameArity<B, A> & SameShapes<B, A>
|
|
374
|
+
): CapacityStatement<B["data"], A["data"]>
|
|
375
|
+
function capacity(
|
|
376
|
+
target: AnyFace,
|
|
377
|
+
second: unknown,
|
|
378
|
+
third: unknown,
|
|
379
|
+
fourth?: AnyFace
|
|
380
|
+
): CapacityStatement<FaceData, FaceData> {
|
|
381
|
+
const weighted = fourth !== undefined
|
|
382
|
+
const windowValue = weighted ? third : second
|
|
383
|
+
const source = weighted ? fourth : (third as AnyFace)
|
|
384
|
+
if (!isCapacityWindow(windowValue)) {
|
|
385
|
+
throw errors.new(
|
|
386
|
+
"a capacity window is minted only by within() — a structural literal skips the ban table (the canonical-utterance law)"
|
|
387
|
+
)
|
|
388
|
+
}
|
|
389
|
+
let weight: WeightSpec = unitWeight
|
|
390
|
+
if (weighted) {
|
|
391
|
+
if (!isCapacityWeight(second)) {
|
|
392
|
+
throw errors.new(
|
|
393
|
+
"a capacity weight is minted only by weigh() — a structural literal skips the row-local weight wall"
|
|
394
|
+
)
|
|
395
|
+
}
|
|
396
|
+
weight = second.weight
|
|
397
|
+
}
|
|
398
|
+
const window = windowValue.window
|
|
399
|
+
if (weight.kind === "unit" && window.kind === "floor" && window.lo.kind === "lit" && window.lo.value === 1n) {
|
|
400
|
+
throw errors.new(
|
|
401
|
+
"`{1..*}` on the unit instance says only what the bare containment says — drop the annotation and write the containment: contained(source, target)"
|
|
402
|
+
)
|
|
403
|
+
}
|
|
404
|
+
const data: CapacityData = Object.freeze({
|
|
405
|
+
kind: "capacity",
|
|
261
406
|
target: target.data,
|
|
262
|
-
|
|
407
|
+
weight,
|
|
408
|
+
window,
|
|
263
409
|
source: source.data
|
|
264
410
|
})
|
|
265
|
-
const statement = Object.freeze({ data })
|
|
411
|
+
const statement = Object.freeze({ data, [admitted]: true as const })
|
|
266
412
|
assertArityAgreement(data.source, data.target, statement)
|
|
267
413
|
assertRosterAgreement(data.source, data.target, statement)
|
|
414
|
+
assertWeightOnSource(weight, data.source, statement)
|
|
415
|
+
assertBoundsOnTarget(window, data.target, statement)
|
|
268
416
|
return statement
|
|
269
417
|
}
|
|
270
418
|
|
|
@@ -274,9 +422,11 @@ function window<B extends AnyFace, A extends AnyFace>(
|
|
|
274
422
|
* same shapes for violations) — `Account(id) -> Account`,
|
|
275
423
|
* `Account(holder) <= Holder(id)`,
|
|
276
424
|
* `Account(id | kind == Savings) == SavingsTerms(account)`,
|
|
277
|
-
* `Holder(id) <={0..3} Account(holder)
|
|
425
|
+
* `Holder(id) <={0..3} Account(holder)`,
|
|
426
|
+
* `Pool(id) <=[watts]{0..supply} Device(pool)` — so TS-side errors and
|
|
278
427
|
* engine-side diagnostics read identically. A renderer, never a parser:
|
|
279
|
-
* strings are output-only.
|
|
428
|
+
* strings are output-only. The unit weight renders nothing — the count
|
|
429
|
+
* utterance falls out of the one printer.
|
|
280
430
|
*/
|
|
281
431
|
function renderStatement(statement: Statement): string {
|
|
282
432
|
const data = statement.data
|
|
@@ -287,19 +437,19 @@ function renderStatement(statement: Statement): string {
|
|
|
287
437
|
const operator = data.bidirectional ? "==" : "<="
|
|
288
438
|
return `${renderFace(data.source)} ${operator} ${renderFace(data.target)}`
|
|
289
439
|
}
|
|
290
|
-
case "
|
|
291
|
-
return `${renderFace(data.target)} <=${
|
|
440
|
+
case "capacity":
|
|
441
|
+
return `${renderFace(data.target)} <=${renderWeight(data.weight)}${renderCapacityWindow(data.window)} ${renderFace(data.source)}`
|
|
292
442
|
}
|
|
293
443
|
}
|
|
294
444
|
|
|
295
445
|
export type {
|
|
446
|
+
CapacityData,
|
|
447
|
+
CapacityStatement,
|
|
296
448
|
ContainedStatement,
|
|
297
449
|
ContainmentData,
|
|
298
450
|
KeyData,
|
|
299
451
|
KeyStatement,
|
|
300
452
|
Statement,
|
|
301
|
-
StatementData
|
|
302
|
-
WindowData,
|
|
303
|
-
WindowStatement
|
|
453
|
+
StatementData
|
|
304
454
|
}
|
|
305
|
-
export { contained, key, mirrors, renderStatement
|
|
455
|
+
export { capacity, contained, isStatement, key, mirrors, renderStatement }
|
package/dist/count.d.ts
DELETED
|
@@ -1,102 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Cardinality-window counts — exactly five constructors, and nothing else
|
|
3
|
-
* (`docs/architecture/70-api.md` § the canonical-utterance law). The five
|
|
4
|
-
* constructors PARTITION the legal windows, and the ban table is enforced
|
|
5
|
-
* REPRESENTATIONALLY, stronger than Rust's expansion errors, in two tiers:
|
|
6
|
-
*
|
|
7
|
-
* - **The type tier**: a banned spelling written as a LITERAL does not
|
|
8
|
-
* compile — `exactly(0n)`, `between(n, n)`, `between(0n, hi)`,
|
|
9
|
-
* `atLeast(0n)`, `atLeast(1n)`, `atMost(0n)`, and every negative bound
|
|
10
|
-
* are type errors naming the canonical form (`{n..n}`, `{0..0}`,
|
|
11
|
-
* `{0..hi}`-via-between, `{0..*}`, `{1..*}` have NO argument shape that
|
|
12
|
-
* produces them), and no sixth constructor exists at all.
|
|
13
|
-
* - **The construction tier**: a bound the type level cannot judge — a
|
|
14
|
-
* COMPUTED `bigint`, whose literal identity is erased, or an inverted
|
|
15
|
-
* `between(lo, hi)` order, which type-level bigints cannot compare — is
|
|
16
|
-
* judged here at construction with the same canonical-naming errors; and
|
|
17
|
-
* past both tiers the engine's own spec validation remains the law for a
|
|
18
|
-
* hostile FFI caller (the standing two-tier ban enforcement).
|
|
19
|
-
*
|
|
20
|
-
* Bounds are `bigint` (u64 crosses as bigint always, PRD-04's law).
|
|
21
|
-
*/
|
|
22
|
-
import type { WindowSpec } from "#spec.ts";
|
|
23
|
-
/**
|
|
24
|
-
* The admission brand — a module-private symbol, deliberately unexported:
|
|
25
|
-
* `WindowSpec` is a public wire type, so without this brand every banned
|
|
26
|
-
* spelling in the ban table would be writable as a plain object literal
|
|
27
|
-
* (`{ window: { kind: "floor", lo: 1n } }` typechecks structurally). The
|
|
28
|
-
* symbol makes the five constructors the ONLY producers of a `Count`
|
|
29
|
-
* value, which is what "the ban table is unwritable" means.
|
|
30
|
-
*/
|
|
31
|
-
declare const admitted: unique symbol;
|
|
32
|
-
/**
|
|
33
|
-
* An admitted window count — opaque and inert: a fact about the theory,
|
|
34
|
-
* not a builder. Only the five constructors below produce one (the
|
|
35
|
-
* module-private {@link admitted} brand forecloses structural literals).
|
|
36
|
-
*/
|
|
37
|
-
interface Count {
|
|
38
|
-
readonly window: WindowSpec;
|
|
39
|
-
readonly [admitted]: true;
|
|
40
|
-
}
|
|
41
|
-
/**
|
|
42
|
-
* The legible banned-spelling verdict: intersected into a count
|
|
43
|
-
* constructor's parameter when the LITERAL argument spells a banned window,
|
|
44
|
-
* naming the canonical form — the compile-time face of the ban table.
|
|
45
|
-
*/
|
|
46
|
-
interface BannedWindow<Canonical extends string> {
|
|
47
|
-
readonly "banned window spelling — the canonical-utterance law names the one legal form": Canonical;
|
|
48
|
-
}
|
|
49
|
-
/** `true` exactly when the literal bigint `N` is negative (out of the u64 count domain). */
|
|
50
|
-
type IsNegative<N extends bigint> = `${N}` extends `-${string}` ? true : false;
|
|
51
|
-
/** The ban verdict on `exactly(n)`: negatives are out of domain; `{0}` is the exclusion, written `none`. */
|
|
52
|
-
type ExactlyBan<N extends bigint> = bigint extends N ? unknown : IsNegative<N> extends true ? BannedWindow<"window counts are u64 — a negative count is out of domain"> : N extends 0n ? BannedWindow<"`{0}` is the exclusion — write none"> : unknown;
|
|
53
|
-
/** The ban verdict on `atLeast(lo)`: `{0..*}` is vacuous; `{1..*}` is the bare containment respelled. */
|
|
54
|
-
type AtLeastBan<N extends bigint> = bigint extends N ? unknown : IsNegative<N> extends true ? BannedWindow<"window counts are u64 — a negative count is out of domain"> : N extends 0n ? BannedWindow<"`{0..*}` is vacuous — it provably says nothing; delete the statement"> : N extends 1n ? BannedWindow<"`{1..*}` says only what the bare containment says — write contained(source, target)"> : unknown;
|
|
55
|
-
/** The ban verdict on `atMost(hi)`: `{0..0}` is the exclusion, written `none`. */
|
|
56
|
-
type AtMostBan<N extends bigint> = bigint extends N ? unknown : IsNegative<N> extends true ? BannedWindow<"window counts are u64 — a negative count is out of domain"> : N extends 0n ? BannedWindow<"`{0..0}` — the exclusion is written `{0}`: use none"> : unknown;
|
|
57
|
-
/** The ban verdict on a `between` floor of zero: `{0..hi}` is the ceiling respelled (`atMost(hi)`). */
|
|
58
|
-
type BetweenFloorBan<Lo extends bigint> = Lo extends 0n ? BannedWindow<"`{0..hi}` — a ceiling is written atMost(hi)"> : unknown;
|
|
59
|
-
/**
|
|
60
|
-
* The ban verdict on `between(lo, hi)`, judged on the second bound once
|
|
61
|
-
* both literals are known: `{n..n}` is the exact count respelled
|
|
62
|
-
* (`exactly(n)`, or `none` at 0), and `{0..hi}` is the ceiling respelled
|
|
63
|
-
* (`atMost(hi)` — the five constructors PARTITION the legal windows, so
|
|
64
|
-
* the one ceiling window keeps its one spelling). Bound ORDER (`{hi..lo}`
|
|
65
|
-
* inverted) is not type-expressible — bigint literals have no type-level
|
|
66
|
-
* comparison — so inversion stays a construction error below.
|
|
67
|
-
*/
|
|
68
|
-
type BetweenBan<Lo extends bigint, Hi extends bigint> = bigint extends Lo ? unknown : bigint extends Hi ? unknown : IsNegative<Lo> extends true ? BannedWindow<"window counts are u64 — a negative bound is out of domain"> : IsNegative<Hi> extends true ? BannedWindow<"window counts are u64 — a negative bound is out of domain"> : Lo extends Hi ? Hi extends Lo ? Lo extends 0n ? BannedWindow<"`{0..0}` — the exclusion is written `{0}`: use none"> : BannedWindow<"`{n..n}` — an exact count is written `{n}`: use exactly(n)"> : BetweenFloorBan<Lo> : BetweenFloorBan<Lo>;
|
|
69
|
-
/**
|
|
70
|
-
* `{n}` — THE exact-count spelling, n ≥ 1. `exactly(0)` is the exclusion
|
|
71
|
-
* respelled: unwritable as a literal ({@link ExactlyBan} names `none`),
|
|
72
|
-
* rejected at construction when computed.
|
|
73
|
-
*/
|
|
74
|
-
declare function exactly<const N extends bigint>(n: N & ExactlyBan<N>): Count;
|
|
75
|
-
/** `{0}` — the exclusion: no source fact may pair with the target group. */
|
|
76
|
-
declare const none: Count;
|
|
77
|
-
/**
|
|
78
|
-
* `{lo..hi}` — both bounds explicit, 1 ≤ lo < hi. `lo === hi` is the exact
|
|
79
|
-
* count respelled and `lo === 0` is the ceiling respelled: unwritable as
|
|
80
|
-
* literals ({@link BetweenBan} names `exactly(n)`, `none` at `{0..0}`, or
|
|
81
|
-
* `atMost(hi)` at a zero floor — the five constructors PARTITION the legal
|
|
82
|
-
* windows), rejected at construction when computed; an inverted window is
|
|
83
|
-
* unsatisfiable and rejected at construction (bigint literals carry no
|
|
84
|
-
* type-level order).
|
|
85
|
-
*/
|
|
86
|
-
declare function between<const Lo extends bigint, const Hi extends bigint>(lo: Lo, hi: Hi & BetweenBan<Lo, Hi>): Count;
|
|
87
|
-
/**
|
|
88
|
-
* `{lo..*}` — a floor with no ceiling, lo ≥ 2: `atLeast(1)` says only what
|
|
89
|
-
* the bare containment says and `atLeast(0)` is vacuous — both unwritable
|
|
90
|
-
* as literals ({@link AtLeastBan} names the canonical form), rejected at
|
|
91
|
-
* construction when computed.
|
|
92
|
-
*/
|
|
93
|
-
declare function atLeast<const N extends bigint>(lo: N & AtLeastBan<N>): Count;
|
|
94
|
-
/**
|
|
95
|
-
* `{0..hi}` — a ceiling, hi ≥ 1: `atMost(0)` is the exclusion respelled —
|
|
96
|
-
* unwritable as a literal ({@link AtMostBan} names `none`), rejected at
|
|
97
|
-
* construction when computed.
|
|
98
|
-
*/
|
|
99
|
-
declare function atMost<const N extends bigint>(hi: N & AtMostBan<N>): Count;
|
|
100
|
-
export type { Count };
|
|
101
|
-
export { atLeast, atMost, between, exactly, none };
|
|
102
|
-
//# sourceMappingURL=count.d.ts.map
|
package/dist/count.d.ts.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"count.d.ts","sourceRoot":"","sources":["../src/count.ts"],"names":[],"mappings":"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"}
|