@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/src/query/atom.ts
CHANGED
|
@@ -1,40 +1,9 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Atoms and conditions, REFERENCE-IDENTITY edition — the body vocabulary of
|
|
3
|
-
* a rule, mirroring the engine IR variant for variant
|
|
4
|
-
* (`bumbledb/crates/bumbledb/src/ir.rs`, the bijection target;
|
|
5
|
-
* `docs/architecture/20-query-ir.md` normative). A `match` binding record
|
|
6
|
-
* binds fields to VARIABLES (minted by {@link v}), params, ∈-set params, or
|
|
7
|
-
* bare structural literals — a closed-reference field's literal is its
|
|
8
|
-
* handle NAME, and a plain ARRAY of names there is membership
|
|
9
|
-
* (unmentioned fields ARE the wildcard — no wildcard value exists);
|
|
10
|
-
* `not(Rel, {...})` is negation-as-position (anti-join); `eq`/`ne` and the
|
|
11
|
-
* order roster, `pointIn` (the one spelling of `ir::CmpOp::PointIn`,
|
|
12
|
-
* always lowered interval-left), `allen` (the 13-bit mask pair
|
|
13
|
-
* comparison), and `and`/`or` (the input condition-tree grammar) complete
|
|
14
|
-
* the roster. Nothing beyond the IR exists here — and the walls the engine
|
|
15
|
-
* enforces at prepare are TYPES first: a variable joins only class-equal
|
|
16
|
-
* fields, judged at every binding position against the var's MINT slot
|
|
17
|
-
* ({@link MintSlotOf}); because {@link JoinOk} is an equality, that ALONE
|
|
18
|
-
* makes every cross-binding join transitively class-equal (the env/sibling
|
|
19
|
-
* checks the name-keyed edition needed are gone). An interval-typed var
|
|
20
|
-
* under a non-`pointIn` comparison is unwritable. BOUNDNESS (a negated
|
|
21
|
-
* atom's variables must be positively bound) is the one check types cannot
|
|
22
|
-
* carry — object identity is invisible to TS — so it is a construction-time
|
|
23
|
-
* wall only.
|
|
24
|
-
*
|
|
25
|
-
* This module also owns the plain runtime DATA a built rule is made of
|
|
26
|
-
* (`RuleData`/`InteriorData`/`RecData` and friends): frozen values the
|
|
27
|
-
* lowering walks — pure data (variable references included), so lowering
|
|
28
|
-
* stays a pure, stable function of the query value.
|
|
29
|
-
*/
|
|
30
|
-
|
|
31
1
|
import * as errors from "@superbuilders/errors"
|
|
32
2
|
import type { AnyField, ClosedIdField, ClosedRoster, Infer, IntervalValue } from "#fields.ts"
|
|
33
3
|
import type { ClassLookup, ClassRecordOf, SchemaClasses } from "#law.ts"
|
|
34
4
|
import type {
|
|
35
5
|
AnyVar,
|
|
36
6
|
ClassedField,
|
|
37
|
-
Duration,
|
|
38
7
|
JoinOk,
|
|
39
8
|
MatchFields,
|
|
40
9
|
MatchOwner,
|
|
@@ -47,11 +16,6 @@ import type {
|
|
|
47
16
|
import { isTerm, term } from "#query/scope.ts"
|
|
48
17
|
import type { FieldsShape } from "#relation.ts"
|
|
49
18
|
|
|
50
|
-
/**
|
|
51
|
-
* One atom-binding position as runtime data. A variable rides BY REFERENCE
|
|
52
|
-
* (`ref`) — object identity is the join. `literalSet` is a membership
|
|
53
|
-
* ARRAY at a closed-reference field, folded into the query.
|
|
54
|
-
*/
|
|
55
19
|
type BindingTermData =
|
|
56
20
|
| { readonly kind: "var"; readonly ref: AnyVar }
|
|
57
21
|
| { readonly kind: "param"; readonly name: string }
|
|
@@ -59,7 +23,6 @@ type BindingTermData =
|
|
|
59
23
|
| { readonly kind: "literalSet"; readonly name: string; readonly members: readonly string[] }
|
|
60
24
|
| { readonly kind: "literal"; readonly value: unknown }
|
|
61
25
|
|
|
62
|
-
/** One resolved binding: the field's name, its descriptor, its law-computed class, and the term. */
|
|
63
26
|
interface BindingEntry {
|
|
64
27
|
readonly field: string
|
|
65
28
|
readonly data: AnyField
|
|
@@ -67,24 +30,19 @@ interface BindingEntry {
|
|
|
67
30
|
readonly term: BindingTermData
|
|
68
31
|
}
|
|
69
32
|
|
|
70
|
-
/** One EDB atom as runtime data (either polarity — polarity is the rule item's; a closed owner is a ψ atom). */
|
|
71
33
|
interface AtomData {
|
|
72
34
|
readonly relation: MatchOwner
|
|
73
35
|
readonly bindings: readonly BindingEntry[]
|
|
74
36
|
}
|
|
75
37
|
|
|
76
|
-
/** One comparison operator name (mirrors `ir::CmpOp`). */
|
|
77
38
|
type CmpKind = "eq" | "ne" | "lt" | "le" | "gt" | "ge" | "pointIn" | "allen"
|
|
78
39
|
|
|
79
|
-
/** One comparison side as runtime data (variables and the measure ride BY REFERENCE). */
|
|
80
40
|
type CmpTermData =
|
|
81
41
|
| { readonly kind: "var"; readonly ref: AnyVar }
|
|
82
42
|
| { readonly kind: "param"; readonly name: string }
|
|
83
43
|
| { readonly kind: "setParam"; readonly name: string }
|
|
84
|
-
| { readonly kind: "measure"; readonly ref: AnyVar }
|
|
85
44
|
| { readonly kind: "literal"; readonly value: unknown }
|
|
86
45
|
|
|
87
|
-
/** One comparison condition as runtime data; the mask lives inside `allen`. */
|
|
88
46
|
type CmpData = {
|
|
89
47
|
readonly kind: "cmp"
|
|
90
48
|
readonly lhs: CmpTermData
|
|
@@ -94,42 +52,27 @@ type CmpData = {
|
|
|
94
52
|
| { readonly op: { readonly kind: Exclude<CmpKind, "allen"> } }
|
|
95
53
|
)
|
|
96
54
|
|
|
97
|
-
/** One condition-tree node as runtime data (`ir::ConditionTree`). */
|
|
98
55
|
interface TreeData {
|
|
99
56
|
readonly kind: "tree"
|
|
100
57
|
readonly op: "and" | "or"
|
|
101
58
|
readonly children: readonly CondData[]
|
|
102
59
|
}
|
|
103
60
|
|
|
104
|
-
/** Any condition node as runtime data. */
|
|
105
61
|
type CondData = CmpData | TreeData
|
|
106
62
|
|
|
107
|
-
/** One aggregate's runtime description (find vocabulary, over variable REFERENCES). */
|
|
108
63
|
type AggData =
|
|
109
64
|
| { readonly op: "count" }
|
|
110
65
|
| {
|
|
111
66
|
readonly op: "fold"
|
|
112
67
|
readonly fold: "sum" | "min" | "max"
|
|
113
|
-
readonly over: AnyVar
|
|
68
|
+
readonly over: AnyVar
|
|
114
69
|
}
|
|
115
70
|
| { readonly op: "pack"; readonly over: AnyVar }
|
|
116
71
|
|
|
117
|
-
/** One classified find entry as runtime data (variables and the measure ride BY REFERENCE). */
|
|
118
72
|
type FindEntryData =
|
|
119
73
|
| { readonly kind: "var"; readonly over: AnyVar }
|
|
120
|
-
| { readonly kind: "measure"; readonly over: AnyVar }
|
|
121
74
|
| { readonly kind: "aggregate"; readonly agg: AggData }
|
|
122
75
|
|
|
123
|
-
/**
|
|
124
|
-
* One answer column: its name (the row object key — the find record's key,
|
|
125
|
-
* so renames are real and a duplicate column is unrepresentable), its entry,
|
|
126
|
-
* the classed mint SLOT its values flow from (a projected var;
|
|
127
|
-
* `undefined` for counts/folds/measures/pack, which derive numbers or
|
|
128
|
-
* intervals), and — when that slot is a closed reference —
|
|
129
|
-
* the roster the decode lifts row ids back to handle NAMES through
|
|
130
|
-
* (`undefined` on every bare column). The slice is SDK-side marshaling data
|
|
131
|
-
* only: the wire `QueryIr` never carries it.
|
|
132
|
-
*/
|
|
133
76
|
interface FindColumn {
|
|
134
77
|
readonly name: string
|
|
135
78
|
readonly entry: FindEntryData
|
|
@@ -137,12 +80,6 @@ interface FindColumn {
|
|
|
137
80
|
readonly slot: ClassedField | undefined
|
|
138
81
|
}
|
|
139
82
|
|
|
140
|
-
/**
|
|
141
|
-
* One body item of a rule, in written order. An interior join is a NAMED
|
|
142
|
-
* record over the derived table's head keys (`key`) bound to local
|
|
143
|
-
* variables (`ref`) — the typed wall a record's unordered keys would
|
|
144
|
-
* otherwise lose.
|
|
145
|
-
*/
|
|
146
83
|
type RuleItem =
|
|
147
84
|
| { readonly kind: "atom"; readonly atom: AtomData }
|
|
148
85
|
| { readonly kind: "negated"; readonly atom: AtomData }
|
|
@@ -158,35 +95,26 @@ type RuleItem =
|
|
|
158
95
|
}
|
|
159
96
|
| { readonly kind: "cond"; readonly cond: CondData }
|
|
160
97
|
|
|
161
|
-
/**
|
|
162
|
-
* One use of a parameter inside a rule, in written order: the census the
|
|
163
|
-
* query-level registry folds (first use mints the dense `ParamId`, first
|
|
164
|
-
* FIELD-ANCHORED use types the wire). `members` is present exactly on a
|
|
165
|
-
* membership-array use.
|
|
166
|
-
*/
|
|
167
98
|
interface ParamUse {
|
|
168
99
|
readonly name: string
|
|
169
100
|
readonly shape: "value" | "set"
|
|
170
|
-
readonly anchor: AnyField |
|
|
101
|
+
readonly anchor: AnyField | undefined
|
|
171
102
|
readonly op: "binding" | CmpKind
|
|
172
103
|
readonly members: readonly string[] | undefined
|
|
173
104
|
}
|
|
174
105
|
|
|
175
|
-
/** One complete rule as runtime data. */
|
|
176
106
|
interface RuleData {
|
|
177
107
|
readonly items: readonly RuleItem[]
|
|
178
108
|
readonly finds: readonly FindColumn[]
|
|
179
109
|
readonly paramUses: readonly ParamUse[]
|
|
180
110
|
}
|
|
181
111
|
|
|
182
|
-
/** One named interior's runtime description — identity keys the dense `InteriorId` at lowering. */
|
|
183
112
|
interface InteriorData {
|
|
184
113
|
readonly name: string
|
|
185
114
|
readonly finds: readonly FindColumn[]
|
|
186
115
|
readonly rules: readonly RuleData[]
|
|
187
116
|
}
|
|
188
117
|
|
|
189
|
-
/** A nonempty frozen list — empty base/rec/finds are unrepresentable on RecData. */
|
|
190
118
|
type NonEmpty<T> = readonly [T, ...T[]]
|
|
191
119
|
|
|
192
120
|
/**
|
|
@@ -197,34 +125,18 @@ interface RecHandle {
|
|
|
197
125
|
readonly name: string
|
|
198
126
|
}
|
|
199
127
|
|
|
200
|
-
/**
|
|
201
|
-
* Rec identity plus the sealed head, used while rec arms are in flight
|
|
202
|
-
* and as the target those arms capture.
|
|
203
|
-
*/
|
|
204
128
|
interface RecHead {
|
|
205
129
|
readonly name: string
|
|
206
130
|
readonly finds: NonEmpty<FindColumn>
|
|
207
131
|
}
|
|
208
132
|
|
|
209
|
-
/**
|
|
210
|
-
* The linear rec's runtime description — identity keys the dense
|
|
211
|
-
* `InteriorId` (`interiors.length`) at lowering. Base and rec arms are
|
|
212
|
-
* nonempty by type and sealed in one assignment.
|
|
213
|
-
*/
|
|
214
133
|
interface RecData extends RecHead {
|
|
215
134
|
readonly base: NonEmpty<RuleData>
|
|
216
135
|
readonly rec: NonEmpty<RuleData>
|
|
217
136
|
}
|
|
218
137
|
|
|
219
|
-
/** A named derived table (an interior or the rec) as `.interior(name)` / `r.not(name)` resolve it. */
|
|
220
138
|
type DerivedTable = InteriorData | RecHead
|
|
221
139
|
|
|
222
|
-
/**
|
|
223
|
-
* What a binding position of field `F` accepts: a bare structural literal
|
|
224
|
-
* of the field's value type, a variable/param/∈-set-param term — and, when
|
|
225
|
-
* the field is interval-typed, a bare point literal. A CLOSED-reference
|
|
226
|
-
* field additionally takes a plain ARRAY of handle names read as membership.
|
|
227
|
-
*/
|
|
228
140
|
type BindingInput<F extends AnyField> =
|
|
229
141
|
| Infer<F>
|
|
230
142
|
| (F extends ClosedIdField ? readonly Infer<F>[] : never)
|
|
@@ -233,33 +145,15 @@ type BindingInput<F extends AnyField> =
|
|
|
233
145
|
| Param<string>
|
|
234
146
|
| SetParam<string>
|
|
235
147
|
|
|
236
|
-
/**
|
|
237
|
-
* The `match`/`not` bindings record: per field, a term or literal of that
|
|
238
|
-
* field's structural type; unmentioned fields are wildcards (absence IS
|
|
239
|
-
* the wildcard — the IR has no wildcard variant to spell).
|
|
240
|
-
*/
|
|
241
148
|
type MatchShape<F extends FieldsShape> = {
|
|
242
149
|
readonly [K in keyof F]?: BindingInput<F[K]>
|
|
243
150
|
}
|
|
244
151
|
|
|
245
|
-
/**
|
|
246
|
-
* One field position of a bindings record as a classed slot: the declared
|
|
247
|
-
* descriptor plus the slot's law-computed class, read off the relation's
|
|
248
|
-
* class record (`CR`). The one shape a binding position's join judgment
|
|
249
|
-
* compares against.
|
|
250
|
-
*/
|
|
251
152
|
type SlotAt<F extends FieldsShape, CR, K> = {
|
|
252
153
|
readonly field: F[K & keyof F]
|
|
253
154
|
readonly class: ClassLookup<CR, K>
|
|
254
155
|
}
|
|
255
156
|
|
|
256
|
-
/**
|
|
257
|
-
* The per-property join judgment of a bindings record: a VARIABLE binding
|
|
258
|
-
* must join its own MINT slot to the position slot (a cross-class reuse maps
|
|
259
|
-
* the property to `never`). Because {@link JoinOk} is an equality, judging
|
|
260
|
-
* every position against the mint slot makes all cross-binding joins
|
|
261
|
-
* mutually class-equal by transitivity — no env or sibling arm is needed.
|
|
262
|
-
*/
|
|
263
157
|
type CheckBindings<Classes extends SchemaClasses, F extends FieldsShape, CR, B> = {
|
|
264
158
|
readonly [K in keyof B]: K extends keyof F
|
|
265
159
|
? B[K] extends AnyVar
|
|
@@ -270,7 +164,6 @@ type CheckBindings<Classes extends SchemaClasses, F extends FieldsShape, CR, B>
|
|
|
270
164
|
: never
|
|
271
165
|
}
|
|
272
166
|
|
|
273
|
-
/** The params-object fragments a bindings record contributes (one union member per param use). */
|
|
274
167
|
type BindParams<F extends FieldsShape, B> = {
|
|
275
168
|
[K in keyof B & keyof F]: B[K] extends Param<infer P extends string>
|
|
276
169
|
? { readonly [Q in P]: ParamValueAt<F[K]> }
|
|
@@ -279,12 +172,6 @@ type BindParams<F extends FieldsShape, B> = {
|
|
|
279
172
|
: never
|
|
280
173
|
}[keyof B & keyof F]
|
|
281
174
|
|
|
282
|
-
/**
|
|
283
|
-
* One comparison VALUE: op plus its operands, raw — the runtime
|
|
284
|
-
* representation carries the operands (variable references included), so
|
|
285
|
-
* `.where`'s judgment and the params inference both read the value itself.
|
|
286
|
-
* `mask` is populated exactly for `allen`.
|
|
287
|
-
*/
|
|
288
175
|
interface Cmp<Op extends CmpKind, L, R, M = undefined> {
|
|
289
176
|
readonly cond: "cmp"
|
|
290
177
|
readonly op: Op
|
|
@@ -293,7 +180,6 @@ interface Cmp<Op extends CmpKind, L, R, M = undefined> {
|
|
|
293
180
|
readonly mask: M
|
|
294
181
|
}
|
|
295
182
|
|
|
296
|
-
/** One condition-tree VALUE (`and`/`or` over comparisons and nested trees). */
|
|
297
183
|
interface Tree<Ch extends readonly AnyTreeChild[]> {
|
|
298
184
|
readonly cond: "tree"
|
|
299
185
|
readonly op: "and" | "or"
|
|
@@ -313,73 +199,40 @@ interface NotAtom<R extends MatchOwner, B> {
|
|
|
313
199
|
readonly bindings: B
|
|
314
200
|
}
|
|
315
201
|
|
|
316
|
-
/**
|
|
317
|
-
* One negated finished-table atom — negation OF an interior or of the
|
|
318
|
-
* finished rec is engine-legal in main (a finished set is a set), and
|
|
319
|
-
* this value is its one spelling: `r.not("reach", { c })`. Binds nothing,
|
|
320
|
-
* only rejects — every variable it names must be positively bound in the
|
|
321
|
-
* rule (the same safety rule as EDB negation).
|
|
322
|
-
*/
|
|
323
202
|
interface NotInteriorAtom<B> {
|
|
324
203
|
readonly cond: "notInterior"
|
|
325
204
|
readonly name: string
|
|
326
205
|
readonly bindings: B
|
|
327
206
|
}
|
|
328
207
|
|
|
329
|
-
/** Any comparison value. */
|
|
330
208
|
type AnyCmp = Cmp<CmpKind, unknown, unknown, unknown>
|
|
331
209
|
|
|
332
|
-
/** Any condition-tree child (trees hold comparisons and trees — never atoms). */
|
|
333
210
|
type AnyTreeChild = AnyCmp | Tree<readonly AnyTreeChild[]>
|
|
334
211
|
|
|
335
|
-
/** Any negated-atom value. */
|
|
336
212
|
type AnyNotAtom = NotAtom<MatchOwner, unknown>
|
|
337
213
|
|
|
338
|
-
/** Any negated finished-table value. */
|
|
339
214
|
type AnyNotInteriorAtom = NotInteriorAtom<unknown>
|
|
340
215
|
|
|
341
|
-
/** Any `.where` input: a comparison, a condition tree, or a negated atom (EDB, closed, or finished table). */
|
|
342
216
|
type AnyCond = AnyCmp | Tree<readonly AnyTreeChild[]> | AnyNotAtom | AnyNotInteriorAtom
|
|
343
217
|
|
|
344
|
-
/** What `eq`'s right side accepts (`ParamSet` is `Eq`-only — the IR's rule). */
|
|
345
218
|
type EqRight = AnyVar | Param<string> | SetParam<string> | bigint | string | boolean | Uint8Array | IntervalValue
|
|
346
219
|
|
|
347
|
-
/** What `ne`'s right side accepts. */
|
|
348
220
|
type NeRight = AnyVar | Param<string> | bigint | string | boolean | Uint8Array | IntervalValue
|
|
349
221
|
|
|
350
|
-
|
|
351
|
-
type OrderSide = AnyVar | Param<string> | Duration | bigint | boolean
|
|
222
|
+
type OrderSide = AnyVar | Param<string> | bigint | boolean
|
|
352
223
|
|
|
353
|
-
/** The point side of `pointIn`. */
|
|
354
224
|
type PointSide = AnyVar | Param<string> | bigint
|
|
355
225
|
|
|
356
|
-
/** The interval side of `pointIn`/`allen`. */
|
|
357
226
|
type IntervalSide = AnyVar | Param<string> | IntervalValue
|
|
358
227
|
|
|
359
|
-
/** Builds one comparison value. */
|
|
360
228
|
function comparison<Op extends CmpKind, L, R, M>(op: Op, lhs: L, rhs: R, mask: M): Cmp<Op, L, R, M> {
|
|
361
229
|
return Object.freeze({ cond: "cmp", op, lhs, rhs, mask })
|
|
362
230
|
}
|
|
363
231
|
|
|
364
|
-
/**
|
|
365
|
-
* Whether a comparison side is a VARIABLE side in the engine's sense — a
|
|
366
|
-
* bound variable or the measure. A param is a constant at execution, so a
|
|
367
|
-
* comparison whose every side is a param or literal is constant-valued:
|
|
368
|
-
* the engine's `ConstantComparison` conviction
|
|
369
|
-
* (`bumbledb/crates/bumbledb/src/ir/validate/context.rs`,
|
|
370
|
-
* `comparison_shape`'s last arm).
|
|
371
|
-
*/
|
|
372
232
|
function isVariableSide(value: unknown): boolean {
|
|
373
|
-
return isTerm(value) &&
|
|
233
|
+
return isTerm(value) && value[term] === "var"
|
|
374
234
|
}
|
|
375
235
|
|
|
376
|
-
/**
|
|
377
|
-
* Rejects a comparison with no variable side: it is constant-valued —
|
|
378
|
-
* params included, a param is a constant the moment it binds — the
|
|
379
|
-
* engine's own validation refuses it (`ConstantComparison`), and the
|
|
380
|
-
* lowering has no anchored position to type the literals by — fail here
|
|
381
|
-
* with the same verdict.
|
|
382
|
-
*/
|
|
383
236
|
function assertTermSide(op: string, lhs: unknown, rhs: unknown): void {
|
|
384
237
|
if (!isVariableSide(lhs) && !isVariableSide(rhs)) {
|
|
385
238
|
throw errors.new(
|
|
@@ -388,23 +241,14 @@ function assertTermSide(op: string, lhs: unknown, rhs: unknown): void {
|
|
|
388
241
|
}
|
|
389
242
|
}
|
|
390
243
|
|
|
391
|
-
/**
|
|
392
|
-
* The equality comparison (`ir::CmpOp::Eq`) — a bound variable against a
|
|
393
|
-
* variable (var-to-var unification, class-equal by the join judgment), a
|
|
394
|
-
* param (typed by the variable), an ∈-set param (`Eq`-only), or a bare
|
|
395
|
-
* literal of the variable's own value type. Prefer direct placement in
|
|
396
|
-
* `match` where punning applies.
|
|
397
|
-
*/
|
|
398
244
|
function eq<L extends AnyVar, const R extends EqRight>(left: L, right: R): Cmp<"eq", L, R> {
|
|
399
245
|
return comparison("eq", left, right, undefined)
|
|
400
246
|
}
|
|
401
247
|
|
|
402
|
-
/** Typed disequality (`ir::CmpOp::Ne`). "Not in set" has no operator — write a negated atom. */
|
|
403
248
|
function ne<L extends AnyVar, const R extends NeRight>(left: L, right: R): Cmp<"ne", L, R> {
|
|
404
249
|
return comparison("ne", left, right, undefined)
|
|
405
250
|
}
|
|
406
251
|
|
|
407
|
-
/** The shared order-comparison constructor. */
|
|
408
252
|
function order<Op extends "lt" | "le" | "gt" | "ge", const L extends OrderSide, const R extends OrderSide>(
|
|
409
253
|
op: Op,
|
|
410
254
|
left: L,
|
|
@@ -414,50 +258,29 @@ function order<Op extends "lt" | "le" | "gt" | "ge", const L extends OrderSide,
|
|
|
414
258
|
return comparison(op, left, right, undefined)
|
|
415
259
|
}
|
|
416
260
|
|
|
417
|
-
/** Strict less-than (`ir::CmpOp::Lt`) — orderable sides only (bool included: `false < true`, R3), never intervals/bytes/strings. */
|
|
418
261
|
function lt<const L extends OrderSide, const R extends OrderSide>(left: L, right: R): Cmp<"lt", L, R> {
|
|
419
262
|
return order("lt", left, right)
|
|
420
263
|
}
|
|
421
264
|
|
|
422
|
-
/** Less-or-equal (`ir::CmpOp::Le`). */
|
|
423
265
|
function le<const L extends OrderSide, const R extends OrderSide>(left: L, right: R): Cmp<"le", L, R> {
|
|
424
266
|
return order("le", left, right)
|
|
425
267
|
}
|
|
426
268
|
|
|
427
|
-
/** Strict greater-than (`ir::CmpOp::Gt`). */
|
|
428
269
|
function gt<const L extends OrderSide, const R extends OrderSide>(left: L, right: R): Cmp<"gt", L, R> {
|
|
429
270
|
return order("gt", left, right)
|
|
430
271
|
}
|
|
431
272
|
|
|
432
|
-
/** Greater-or-equal (`ir::CmpOp::Ge`). */
|
|
433
273
|
function ge<const L extends OrderSide, const R extends OrderSide>(left: L, right: R): Cmp<"ge", L, R> {
|
|
434
274
|
return order("ge", left, right)
|
|
435
275
|
}
|
|
436
276
|
|
|
437
|
-
/**
|
|
438
|
-
* Point membership as a predicate (`ir::CmpOp::PointIn`) — THE one
|
|
439
|
-
* spelling: `pointIn(t, w)` holds iff `w.start ≤ t < w.end`. The IR
|
|
440
|
-
* orders the operands interval-left, point-right; the value stores them
|
|
441
|
-
* that way whatever the surface argument order. Interval ⊇ interval is NOT
|
|
442
|
-
* this operator; that predicate is `allen(a, ALLEN.covers, b)`.
|
|
443
|
-
*/
|
|
444
277
|
function pointIn<const P extends PointSide, const I extends IntervalSide>(point: P, interval: I): Cmp<"pointIn", I, P> {
|
|
445
278
|
assertTermSide("pointIn", point, interval)
|
|
446
279
|
return comparison("pointIn", interval, point, undefined)
|
|
447
280
|
}
|
|
448
281
|
|
|
449
|
-
/**
|
|
450
|
-
* The 13-bit mask range: bits above the low 13 are unrepresentable in the
|
|
451
|
-
* engine's `AllenMask` (`bumbledb/crates/bumbledb/src/allen.rs`:
|
|
452
|
-
* `AllenMask::new` refuses them).
|
|
453
|
-
*/
|
|
454
282
|
const ALLEN_ALL_BITS = (1 << 13) - 1
|
|
455
283
|
|
|
456
|
-
/**
|
|
457
|
-
* The Allen coordinate system's named constants — the 13 basics in the
|
|
458
|
-
* engine's palindromic bit order plus the workload composites, values
|
|
459
|
-
* identical to the engine's. Compose with `|`: `ALLEN.before | ALLEN.meets`.
|
|
460
|
-
*/
|
|
461
284
|
const ALLEN = Object.freeze({
|
|
462
285
|
before: 1 << 0,
|
|
463
286
|
meets: 1 << 1,
|
|
@@ -472,21 +295,16 @@ const ALLEN = Object.freeze({
|
|
|
472
295
|
overlappedBy: 1 << 10,
|
|
473
296
|
metBy: 1 << 11,
|
|
474
297
|
after: 1 << 12,
|
|
475
|
-
|
|
298
|
+
|
|
476
299
|
intersects: (1 << 2) | (1 << 3) | (1 << 4) | (1 << 5) | (1 << 6) | (1 << 7) | (1 << 8) | (1 << 9) | (1 << 10),
|
|
477
|
-
|
|
300
|
+
|
|
478
301
|
covers: (1 << 6) | (1 << 8) | (1 << 9) | (1 << 7),
|
|
479
|
-
|
|
302
|
+
|
|
480
303
|
coveredBy: (1 << 6) | (1 << 4) | (1 << 3) | (1 << 5),
|
|
481
|
-
|
|
304
|
+
|
|
482
305
|
disjoint: (1 << 0) | (1 << 1) | (1 << 11) | (1 << 12)
|
|
483
306
|
})
|
|
484
307
|
|
|
485
|
-
/**
|
|
486
|
-
* THE interval-pair comparison (`ir::CmpOp::Allen`): two interval terms of
|
|
487
|
-
* one element type, satisfied iff the pair's classification is in the
|
|
488
|
-
* 13-bit mask — a literal built from the `ALLEN` constants.
|
|
489
|
-
*/
|
|
490
308
|
function allen<const A extends IntervalSide, const B extends IntervalSide>(
|
|
491
309
|
left: A,
|
|
492
310
|
mask: number,
|
|
@@ -501,27 +319,16 @@ function allen<const A extends IntervalSide, const B extends IntervalSide>(
|
|
|
501
319
|
return comparison("allen", left, right, mask)
|
|
502
320
|
}
|
|
503
321
|
|
|
504
|
-
/**
|
|
505
|
-
* Conjunction node of the input condition grammar (`ConditionTree::And`).
|
|
506
|
-
* The rule's condition list is already a conjunction — `and` exists for
|
|
507
|
-
* nesting under `or`, and the empty combination keeps the IR's algebraic
|
|
508
|
-
* reading (`And([])` is true).
|
|
509
|
-
*/
|
|
510
322
|
function and<const C extends readonly AnyTreeChild[]>(...children: C): Tree<C> {
|
|
511
323
|
return Object.freeze({ cond: "tree", op: "and", children: Object.freeze(children) })
|
|
512
324
|
}
|
|
513
325
|
|
|
514
|
-
/**
|
|
515
|
-
* Disjunction node of the input condition grammar (`ConditionTree::Or`) —
|
|
516
|
-
* the one place the surface admits a nested OR; validation distributes it
|
|
517
|
-
* to DNF rules engine-side. `Or([])` keeps its algebraic reading (false).
|
|
518
|
-
*/
|
|
519
326
|
function or<const C extends readonly AnyTreeChild[]>(...children: C): Tree<C> {
|
|
520
327
|
return Object.freeze({ cond: "tree", op: "or", children: Object.freeze(children) })
|
|
521
328
|
}
|
|
522
329
|
|
|
523
330
|
/**
|
|
524
|
-
* Negation — anti-join over sets: `not(Rel, { field: someVar
|
|
331
|
+
* Negation — anti-join over sets: `not(Rel, { field: someVar,... })`
|
|
525
332
|
* rejects every binding some matching fact extends. A negated atom binds
|
|
526
333
|
* nothing, only rejects: every variable it names must be positively bound
|
|
527
334
|
* in the rule, a construction-time wall (the engine's safety refusal stands
|
|
@@ -551,7 +358,7 @@ function not(
|
|
|
551
358
|
* interval's element domain, and a quantifier is not an addition, so bool
|
|
552
359
|
* (orderable, never numeric) is exactly here refused. A CLOSED reference
|
|
553
360
|
* is excluded even though its kind is `u64`: a vocabulary's declaration-id
|
|
554
|
-
* order is an accident, not semantics
|
|
361
|
+
* order is an accident, not semantics
|
|
555
362
|
* § orderability), so every order-comparison and fold position refuses
|
|
556
363
|
* closed-bound terms — the construction-time validations in
|
|
557
364
|
* `#query/lower.ts` are that ban's runtime twin.
|
|
@@ -562,63 +369,24 @@ type NumericVarOk<V extends AnyVar> = V["field"] extends { readonly closed: Clos
|
|
|
562
369
|
? true
|
|
563
370
|
: false
|
|
564
371
|
|
|
565
|
-
/**
|
|
566
|
-
* Whether a variable's OWN field is ORDERABLE (u64/i64/bool) — the one gate
|
|
567
|
-
* every order-comparison side, `min`/`max` input, and Arg key reads. Bool
|
|
568
|
-
* orders: `false < true`, the strict 0/1 encoding IS the order (ruled R3),
|
|
569
|
-
* exactly the engine's operand screen
|
|
570
|
-
* (`bumbledb/crates/bumbledb/src/ir/validate/context.rs`); bool has no
|
|
571
|
-
* closed variant, so the closed exclusion rides in {@link NumericVarOk}.
|
|
572
|
-
*/
|
|
573
372
|
type OrderVarOk<V extends AnyVar> = V["field"]["kind"] extends "bool" ? true : NumericVarOk<V>
|
|
574
373
|
|
|
575
|
-
/** Whether a variable's OWN field is interval-typed. */
|
|
576
374
|
type IntervalVarOk<V extends AnyVar> = V["field"]["kind"] extends "interval" ? true : false
|
|
577
375
|
|
|
578
|
-
|
|
579
|
-
* Whether a comparison has a VARIABLE side (a var or the measure) — the
|
|
580
|
-
* type-level twin of the engine's `ConstantComparison` rule: a param is a
|
|
581
|
-
* constant at execution, so param-vs-param and param-vs-literal are
|
|
582
|
-
* constant-valued whatever their domains ({@link assertTermSide} is the
|
|
583
|
-
* runtime wall behind this one).
|
|
584
|
-
*/
|
|
585
|
-
type CmpVarSideOk<L, R> = L extends AnyVar | Duration ? true : R extends AnyVar | Duration ? true : false
|
|
376
|
+
type CmpVarSideOk<L, R> = L extends AnyVar ? true : R extends AnyVar ? true : false
|
|
586
377
|
|
|
587
|
-
/**
|
|
588
|
-
* One order side's DOMAIN — the type-level twin of the engine's resolved
|
|
589
|
-
* operand type (`ir/validate/context.rs`, `classify`'s `Ord*` arms): a
|
|
590
|
-
* variable names its own field kind, the measure is u64 by definition (and
|
|
591
|
-
* never meets another measure — `DurationBothSides`), a bigint literal
|
|
592
|
-
* spans the integer domains, a param is typed by its sibling (`"open"`).
|
|
593
|
-
* `never` marks a side that is itself unorderable: interval/bytes/string
|
|
594
|
-
* vars (the operand screen), closed-bound vars (R4), a measure over a
|
|
595
|
-
* non-interval var.
|
|
596
|
-
*/
|
|
597
378
|
type OrderDomain<T> = T extends AnyVar
|
|
598
379
|
? OrderVarOk<T> extends true
|
|
599
380
|
? T["field"]["kind"]
|
|
600
381
|
: never
|
|
601
|
-
: T extends
|
|
602
|
-
?
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
? "integer"
|
|
609
|
-
: T extends boolean
|
|
610
|
-
? "bool"
|
|
611
|
-
: never
|
|
382
|
+
: T extends Param<string>
|
|
383
|
+
? "open"
|
|
384
|
+
: T extends bigint
|
|
385
|
+
? "integer"
|
|
386
|
+
: T extends boolean
|
|
387
|
+
? "bool"
|
|
388
|
+
: never
|
|
612
389
|
|
|
613
|
-
/**
|
|
614
|
-
* Whether two order domains may MEET under one operator — the engine's
|
|
615
|
-
* same-type rule judged pairwise, not per side: bool meets only bool (a
|
|
616
|
-
* bigint literal against a bool var is exactly `check_const`'s
|
|
617
|
-
* conviction; R3 made bool orderable, never cross-orderable), u64 and i64
|
|
618
|
-
* never meet, the measure's sibling must live in u64 (`OrdMeasureVar`:
|
|
619
|
-
* scalar ≠ U64 is `IllegalComparison`), two measures never meet, and an
|
|
620
|
-
* open side (param, integer literal) takes whatever its sibling names.
|
|
621
|
-
*/
|
|
622
390
|
type OrderDomainsOk<A, B> = [A] extends [never]
|
|
623
391
|
? false
|
|
624
392
|
: [B] extends [never]
|
|
@@ -627,51 +395,30 @@ type OrderDomainsOk<A, B> = [A] extends [never]
|
|
|
627
395
|
? true
|
|
628
396
|
: B extends "open"
|
|
629
397
|
? true
|
|
630
|
-
: A extends "
|
|
631
|
-
? B extends "
|
|
398
|
+
: A extends "bool"
|
|
399
|
+
? B extends "bool"
|
|
632
400
|
? true
|
|
633
401
|
: false
|
|
634
|
-
: B extends "
|
|
635
|
-
?
|
|
402
|
+
: B extends "bool"
|
|
403
|
+
? false
|
|
404
|
+
: A extends "integer"
|
|
636
405
|
? true
|
|
637
|
-
:
|
|
638
|
-
: A extends "bool"
|
|
639
|
-
? B extends "bool"
|
|
406
|
+
: B extends "integer"
|
|
640
407
|
? true
|
|
641
|
-
:
|
|
642
|
-
: B extends "bool"
|
|
643
|
-
? false
|
|
644
|
-
: A extends "integer"
|
|
408
|
+
: A extends B
|
|
645
409
|
? true
|
|
646
|
-
:
|
|
647
|
-
? true
|
|
648
|
-
: A extends B
|
|
649
|
-
? true
|
|
650
|
-
: false
|
|
410
|
+
: false
|
|
651
411
|
|
|
652
|
-
/** The whole order comparison's judgment: a variable side exists, and the sides' domains meet. */
|
|
653
412
|
type OrderPairOk<L, R> = CmpVarSideOk<L, R> extends true ? OrderDomainsOk<OrderDomain<L>, OrderDomain<R>> : false
|
|
654
413
|
|
|
655
|
-
/**
|
|
656
|
-
* An interval side's ELEMENT domain: a variable names its field's element
|
|
657
|
-
* (`never` on a non-interval var), a param or bare interval literal is
|
|
658
|
-
* `"open"` — no type exists to name its element at this tier; the engine
|
|
659
|
-
* anchors it at prepare.
|
|
660
|
-
*/
|
|
661
414
|
type IntervalElementDomain<T> = T extends AnyVar
|
|
662
415
|
? T["field"] extends { readonly kind: "interval"; readonly element: infer E extends "u64" | "i64" }
|
|
663
416
|
? E
|
|
664
417
|
: never
|
|
665
418
|
: "open"
|
|
666
419
|
|
|
667
|
-
/**
|
|
668
|
-
* The point side's domain — a point lives in the interval's element
|
|
669
|
-
* domain: a numeric var names its kind (never bool, never closed), a
|
|
670
|
-
* param or bigint literal is open.
|
|
671
|
-
*/
|
|
672
420
|
type PointDomain<T> = T extends AnyVar ? (NumericVarOk<T> extends true ? T["field"]["kind"] : never) : "open"
|
|
673
421
|
|
|
674
|
-
/** Whether two element domains meet: both legal, and equal unless one is open. */
|
|
675
422
|
type ElementMeets<A, B> = [A] extends [never]
|
|
676
423
|
? false
|
|
677
424
|
: [B] extends [never]
|
|
@@ -684,23 +431,12 @@ type ElementMeets<A, B> = [A] extends [never]
|
|
|
684
431
|
? true
|
|
685
432
|
: false
|
|
686
433
|
|
|
687
|
-
/**
|
|
688
|
-
* The whole `pointIn` judgment (operands already sealed interval-left):
|
|
689
|
-
* the point's domain must BE the interval's element domain — `pointIn(t,
|
|
690
|
-
* w)` with an i64-typed `t` against `interval(u64)` is the engine's
|
|
691
|
-
* `IllegalComparison`, judged here first.
|
|
692
|
-
*/
|
|
693
434
|
type PointInPairOk<L, R> =
|
|
694
435
|
CmpVarSideOk<L, R> extends true ? ElementMeets<IntervalElementDomain<L>, PointDomain<R>> : false
|
|
695
436
|
|
|
696
|
-
/**
|
|
697
|
-
* The whole `allen` judgment: two interval sides of ONE element domain
|
|
698
|
-
* (Q1 — widths meet freely, u64-vs-i64 stays illegal), judged pairwise.
|
|
699
|
-
*/
|
|
700
437
|
type AllenPairOk<L, R> =
|
|
701
438
|
CmpVarSideOk<L, R> extends true ? ElementMeets<IntervalElementDomain<L>, IntervalElementDomain<R>> : false
|
|
702
439
|
|
|
703
|
-
/** The `eq`/`ne` judgment: var-var joins by mint slot; var-literal is exact-typed by the var's own field. */
|
|
704
440
|
type EqOk<Classes extends SchemaClasses, L, R> = L extends AnyVar
|
|
705
441
|
? R extends AnyVar
|
|
706
442
|
? JoinOk<MintSlotOf<Classes, L>, MintSlotOf<Classes, R>> extends true
|
|
@@ -713,28 +449,20 @@ type EqOk<Classes extends SchemaClasses, L, R> = L extends AnyVar
|
|
|
713
449
|
: false
|
|
714
450
|
: false
|
|
715
451
|
|
|
716
|
-
/** One negated-atom binding's judgment: a variable must be class-equal (boundness is a runtime wall). */
|
|
717
452
|
type NotBindingOk<Classes extends SchemaClasses, S extends ClassedField, T> = T extends AnyVar
|
|
718
453
|
? JoinOk<MintSlotOf<Classes, T>, S> extends true
|
|
719
454
|
? true
|
|
720
455
|
: false
|
|
721
456
|
: true
|
|
722
457
|
|
|
723
|
-
/** The whole negated atom's judgment (`CR` — the negated relation's class record off the schema class map). */
|
|
724
458
|
type NotOk<Classes extends SchemaClasses, F extends FieldsShape, CR, B> = false extends {
|
|
725
459
|
[K in keyof B]: NotBindingOk<Classes, SlotAt<F, CR, K>, B[K]>
|
|
726
460
|
}[keyof B]
|
|
727
461
|
? false
|
|
728
462
|
: true
|
|
729
463
|
|
|
730
|
-
/** One negated finished-table position's judgment: a variable. */
|
|
731
464
|
type NotInteriorBindingOk<V> = V extends AnyVar ? true : false
|
|
732
465
|
|
|
733
|
-
/**
|
|
734
|
-
* The whole negated finished-table atom's judgment — variables only;
|
|
735
|
-
* arity and class against the named table's head are construction-time
|
|
736
|
-
* (the name is a string, so the head is not a type-level fact).
|
|
737
|
-
*/
|
|
738
466
|
type NotInteriorOk<B> = false extends { [K in keyof B]: NotInteriorBindingOk<B[K]> }[keyof B] ? false : true
|
|
739
467
|
|
|
740
468
|
/**
|
|
@@ -769,10 +497,8 @@ type CondOkBool<Classes extends SchemaClasses, C> = [AnyTreeChild] extends [C]
|
|
|
769
497
|
? NotOk<Classes, MatchFields<R>, ClassRecordOf<Classes, R["name"]>, B>
|
|
770
498
|
: false
|
|
771
499
|
|
|
772
|
-
/** The validated `.where` argument (intersect with the inferred condition type). */
|
|
773
500
|
type CheckCond<Classes extends SchemaClasses, C> = CondOkBool<Classes, C> extends true ? C : never
|
|
774
501
|
|
|
775
|
-
/** The `eq`/`ne` params contribution: the param typed by the left variable's own field. */
|
|
776
502
|
type EqParams<L, R> = L extends AnyVar
|
|
777
503
|
? R extends Param<infer P extends string>
|
|
778
504
|
? { readonly [Q in P]: Infer<L["field"]> }
|
|
@@ -781,27 +507,15 @@ type EqParams<L, R> = L extends AnyVar
|
|
|
781
507
|
: never
|
|
782
508
|
: never
|
|
783
509
|
|
|
784
|
-
/**
|
|
785
|
-
* An order side's params contribution, typed by the SIBLING side — the
|
|
786
|
-
* runtime anchors a param to its sibling variable's field, so a bool var
|
|
787
|
-
* orders against a `boolean` param; every var-less pairing stays `bigint`.
|
|
788
|
-
*/
|
|
789
510
|
type OrderSideParams<T, Sib> =
|
|
790
511
|
T extends Param<infer P extends string>
|
|
791
512
|
? { readonly [Q in P]: Sib extends AnyVar ? Infer<Sib["field"]> : bigint }
|
|
792
513
|
: never
|
|
793
514
|
|
|
794
|
-
/** The point side's params contribution (a point is always `bigint`). */
|
|
795
515
|
type PointParams<T> = T extends Param<infer P extends string> ? { readonly [Q in P]: bigint } : never
|
|
796
516
|
|
|
797
|
-
/** An interval side's params contribution. */
|
|
798
517
|
type IntervalSideParams<T> = T extends Param<infer P extends string> ? { readonly [Q in P]: IntervalValue } : never
|
|
799
518
|
|
|
800
|
-
/**
|
|
801
|
-
* One condition's params-object fragments (a union; the rule builder folds
|
|
802
|
-
* them into the inferred `Params` record) — every param typed by its use.
|
|
803
|
-
* The leading arm is the same base case as {@link CondOkBool}'s.
|
|
804
|
-
*/
|
|
805
519
|
type CondParams<C> = [AnyTreeChild] extends [C]
|
|
806
520
|
? never
|
|
807
521
|
: C extends Cmp<infer Op, infer L, infer R, infer _M>
|
|
@@ -863,7 +577,6 @@ export type {
|
|
|
863
577
|
NotInteriorAtom,
|
|
864
578
|
NumericVarOk,
|
|
865
579
|
OrderSide,
|
|
866
|
-
OrderVarOk,
|
|
867
580
|
ParamUse,
|
|
868
581
|
PointSide,
|
|
869
582
|
RecData,
|