@bjornpagen/bumbledb 0.2.0 → 0.4.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 +503 -427
- package/README.md +84 -36
- package/dist/closed.d.ts +111 -38
- package/dist/closed.d.ts.map +1 -1
- package/dist/closed.js +94 -99
- package/dist/closed.js.map +1 -1
- package/dist/db.d.ts +16 -2
- package/dist/db.d.ts.map +1 -1
- package/dist/db.js +46 -8
- package/dist/db.js.map +1 -1
- package/dist/face.d.ts +114 -69
- package/dist/face.d.ts.map +1 -1
- package/dist/face.js +38 -21
- package/dist/face.js.map +1 -1
- package/dist/fields.d.ts +72 -87
- package/dist/fields.d.ts.map +1 -1
- package/dist/fields.js +35 -67
- package/dist/fields.js.map +1 -1
- package/dist/index.d.ts +18 -13
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +11 -7
- package/dist/index.js.map +1 -1
- package/dist/law.d.ts +224 -0
- package/dist/law.d.ts.map +1 -0
- package/dist/law.js +224 -0
- package/dist/law.js.map +1 -0
- package/dist/lower.d.ts +17 -10
- package/dist/lower.d.ts.map +1 -1
- package/dist/lower.js +34 -23
- package/dist/lower.js.map +1 -1
- package/dist/marshal.d.ts +33 -6
- package/dist/marshal.d.ts.map +1 -1
- package/dist/marshal.js +67 -6
- package/dist/marshal.js.map +1 -1
- package/dist/native.d.ts +6 -2
- package/dist/native.d.ts.map +1 -1
- package/dist/native.js.map +1 -1
- package/dist/query/atom.d.ts +139 -56
- package/dist/query/atom.d.ts.map +1 -1
- package/dist/query/atom.js +7 -1
- package/dist/query/atom.js.map +1 -1
- package/dist/query/lower.d.ts +71 -56
- package/dist/query/lower.d.ts.map +1 -1
- package/dist/query/lower.js +341 -69
- package/dist/query/lower.js.map +1 -1
- package/dist/query/predicate.d.ts +10 -9
- package/dist/query/predicate.d.ts.map +1 -1
- package/dist/query/predicate.js +2 -2
- package/dist/query/predicate.js.map +1 -1
- package/dist/query/run.d.ts +15 -5
- package/dist/query/run.d.ts.map +1 -1
- package/dist/query/run.js +26 -6
- package/dist/query/run.js.map +1 -1
- package/dist/query/scope.d.ts +100 -43
- package/dist/query/scope.d.ts.map +1 -1
- package/dist/query/scope.js +89 -30
- package/dist/query/scope.js.map +1 -1
- package/dist/query/select.d.ts +5 -5
- package/dist/query/select.d.ts.map +1 -1
- package/dist/relation.d.ts +29 -15
- package/dist/relation.d.ts.map +1 -1
- package/dist/relation.js +45 -17
- package/dist/relation.js.map +1 -1
- package/dist/schema.d.ts +41 -3
- package/dist/schema.d.ts.map +1 -1
- package/dist/schema.js +16 -2
- package/dist/schema.js.map +1 -1
- package/dist/spec.d.ts +10 -8
- package/dist/spec.d.ts.map +1 -1
- package/dist/spec.js.map +1 -1
- package/dist/statements.d.ts +67 -31
- package/dist/statements.d.ts.map +1 -1
- package/dist/statements.js +97 -20
- package/dist/statements.js.map +1 -1
- package/package.json +2 -2
- package/src/closed.ts +214 -146
- package/src/db.ts +65 -10
- package/src/face.ts +169 -102
- package/src/fields.ts +97 -164
- package/src/index.ts +43 -18
- package/src/law.ts +519 -0
- package/src/lower.ts +36 -23
- package/src/marshal.ts +74 -7
- package/src/native.ts +6 -2
- package/src/query/atom.ts +155 -65
- package/src/query/lower.ts +572 -167
- package/src/query/predicate.ts +43 -33
- package/src/query/run.ts +26 -6
- package/src/query/scope.ts +161 -51
- package/src/query/select.ts +5 -5
- package/src/relation.ts +60 -26
- package/src/schema.ts +48 -7
- package/src/spec.ts +10 -8
- package/src/statements.ts +165 -46
package/src/face.ts
CHANGED
|
@@ -4,16 +4,24 @@
|
|
|
4
4
|
* position, `on(Booking, ["room", "during"])` the composite/pointwise
|
|
5
5
|
* position (one spelling, arity-generic), `on(Account.where({ kind:
|
|
6
6
|
* Kind.Savings }), "id")` the σ-carrying source, `on(Kind, "id")` a closed
|
|
7
|
-
* relation's sealed shape opened through its synthetic `id
|
|
7
|
+
* relation's sealed shape opened through its synthetic `id`,
|
|
8
|
+
* `on(Kind.where({ mastered: true }), "id")` the ψ-selected closed source
|
|
9
|
+
* (the selection lowered as-is — the ENGINE folds it against the sealed
|
|
10
|
+
* extension at validate, never the SDK). Projection is
|
|
8
11
|
* positional: tuple order is preserved in the type, and the statement
|
|
9
12
|
* constructors pair the two sides' tuples by arity ({@link SameArity}) AND
|
|
10
|
-
* by
|
|
11
|
-
*
|
|
12
|
-
*
|
|
13
|
-
*
|
|
13
|
+
* by structural shape ({@link SameShapes}) — every projected field's
|
|
14
|
+
* kind/width/element/roster quadruple is read off the schema type (the
|
|
15
|
+
* minimal kernel: descriptors are pure structure, and a closed reference's
|
|
16
|
+
* roster IS part of that structure) and compared positionwise. There is no
|
|
17
|
+
* domain to compare at construction — domains are LAW-BORN: the statements
|
|
18
|
+
* themselves define the equivalence classes, and `schema()` is where they
|
|
19
|
+
* aggregate and get judged (the one-generator-per-class wall).
|
|
14
20
|
*/
|
|
15
21
|
|
|
16
|
-
import
|
|
22
|
+
import * as errors from "@superbuilders/errors"
|
|
23
|
+
import type { AnyClosed, AnySelectedClosed, PayloadField } from "#closed.ts"
|
|
24
|
+
import type { AnyField } from "#fields.ts"
|
|
17
25
|
import type { AnyRelation, AnySelected, FieldsShape, RelationFields, SelectionBinding } from "#relation.ts"
|
|
18
26
|
import { renderLiteralSet } from "#spec.ts"
|
|
19
27
|
|
|
@@ -21,10 +29,21 @@ import { renderLiteralSet } from "#spec.ts"
|
|
|
21
29
|
const emptySelection: readonly SelectionBinding[] = Object.freeze([])
|
|
22
30
|
|
|
23
31
|
/**
|
|
24
|
-
*
|
|
25
|
-
*
|
|
26
|
-
*
|
|
27
|
-
*
|
|
32
|
+
* The OWNER a face source resolves to: a selected relation — ordinary σ or
|
|
33
|
+
* closed ψ, one shape — projects from its underlying relation; a bare
|
|
34
|
+
* relation or closed relation is its own owner. The type-level twin of
|
|
35
|
+
* {@link faceParts}'s split, and what a statement's face `data` carries at
|
|
36
|
+
* its EXACT type — `schema()`'s law-typing reads the owner's literal name
|
|
37
|
+
* (and the projection tuple) straight off the statement type.
|
|
38
|
+
*/
|
|
39
|
+
type OwnerOf<S extends FaceSource> = S extends AnySelected | AnySelectedClosed ? S["relation"] : S
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* Splits a face source into its owner and σ: a selected relation — ordinary
|
|
43
|
+
* σ or closed ψ, one shape — carries its own bindings (`relation` is the
|
|
44
|
+
* discriminant — the property exists on no relation or closed value, and
|
|
45
|
+
* `closed()` reserves the name against handle collisions); a bare relation
|
|
46
|
+
* or closed relation carries none.
|
|
28
47
|
*/
|
|
29
48
|
function faceParts(source: FaceSource): {
|
|
30
49
|
readonly owner: FaceOwner
|
|
@@ -36,34 +55,20 @@ function faceParts(source: FaceSource): {
|
|
|
36
55
|
return { owner: source, selection: emptySelection }
|
|
37
56
|
}
|
|
38
57
|
|
|
39
|
-
/**
|
|
40
|
-
* A disjunctive literal set for a selection binding — `field == {A, B}`.
|
|
41
|
-
* The signature of {@link oneOf} demands two leading literals, so the
|
|
42
|
-
* one-element set (banned: it is the bare literal) and the empty set
|
|
43
|
-
* (banned: it selects nothing) are unwritable.
|
|
44
|
-
*/
|
|
45
|
-
interface OneOf<V> {
|
|
46
|
-
readonly literals: readonly [V, V, ...V[]]
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
/**
|
|
50
|
-
* Constructs a literal set (read disjunctively) for a `where()` binding.
|
|
51
|
-
* Two leading arguments by signature: the degenerate sets have no spelling
|
|
52
|
-
* (the canonical-utterance law, `docs/architecture/70-api.md`).
|
|
53
|
-
*/
|
|
54
|
-
function oneOf<V>(first: V, second: V, ...rest: V[]): OneOf<V> {
|
|
55
|
-
const literals: readonly [V, V, ...V[]] = [first, second, ...rest]
|
|
56
|
-
Object.freeze(literals)
|
|
57
|
-
return Object.freeze({ literals })
|
|
58
|
-
}
|
|
59
|
-
|
|
60
58
|
/** The relation a face projects from — ordinary or closed. */
|
|
61
59
|
type FaceOwner = AnyRelation | AnyClosed
|
|
62
60
|
|
|
63
|
-
/**
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
61
|
+
/**
|
|
62
|
+
* A face's runtime description: owner, π (written order), σ (resolved
|
|
63
|
+
* bindings). Generic over the owner and projection so a STATEMENT value
|
|
64
|
+
* carries its paired coordinates at their exact types — the honest runtime
|
|
65
|
+
* properties (`owner.name`, `projection`) ARE the type-level carrier
|
|
66
|
+
* `schema()`'s law-typing reads; the defaults are the wide shape every
|
|
67
|
+
* renderer and lowering walk consumes.
|
|
68
|
+
*/
|
|
69
|
+
interface FaceData<O extends FaceOwner = FaceOwner, P extends readonly string[] = readonly string[]> {
|
|
70
|
+
readonly owner: O
|
|
71
|
+
readonly projection: P
|
|
67
72
|
readonly selection: readonly SelectionBinding[]
|
|
68
73
|
}
|
|
69
74
|
|
|
@@ -72,70 +77,100 @@ interface FaceData {
|
|
|
72
77
|
* selected relation, or closed relation `on()` was handed — the statement
|
|
73
78
|
* constructors resolve each projected field's DOMAIN through it), and `P`
|
|
74
79
|
* is the projection tuple as written (its length is the positional-pairing
|
|
75
|
-
* arity). Both are honest runtime properties, not phantoms
|
|
80
|
+
* arity). Both are honest runtime properties, not phantoms — and `data`
|
|
81
|
+
* carries the resolved owner at its exact type, which is what a statement
|
|
82
|
+
* value hands to `schema()`'s law-typing.
|
|
76
83
|
*/
|
|
77
84
|
interface Face<S extends FaceSource, P extends readonly string[]> {
|
|
78
85
|
readonly source: S
|
|
79
86
|
readonly projection: P
|
|
80
|
-
readonly data: FaceData
|
|
87
|
+
readonly data: FaceData<OwnerOf<S>, P>
|
|
81
88
|
}
|
|
82
89
|
|
|
83
90
|
/** Any face value, whatever its source and projection. */
|
|
84
91
|
type AnyFace = Face<FaceSource, readonly string[]>
|
|
85
92
|
|
|
86
|
-
/** What `on()` accepts: a relation, a
|
|
87
|
-
type FaceSource = AnyRelation | AnyClosed | AnySelected
|
|
93
|
+
/** What `on()` accepts: a relation, a closed relation, or either with a selection applied. */
|
|
94
|
+
type FaceSource = AnyRelation | AnyClosed | AnySelected | AnySelectedClosed
|
|
88
95
|
|
|
89
96
|
/**
|
|
90
97
|
* The field names a face over `S` may project: a relation's declared
|
|
91
98
|
* fields; a selected relation's underlying fields; a closed relation's
|
|
92
|
-
* SEALED shape — the synthetic `id` plus its declared payload columns
|
|
93
|
-
* (`docs/architecture/70-api.md`: statement field
|
|
94
|
-
* shape).
|
|
99
|
+
* SEALED shape — the synthetic `id` plus its declared payload columns,
|
|
100
|
+
* bare or ψ-selected alike (`docs/architecture/70-api.md`: statement field
|
|
101
|
+
* names address the sealed shape).
|
|
95
102
|
*/
|
|
96
103
|
type FaceFields<S extends FaceSource> = S extends AnySelected
|
|
97
104
|
? keyof S["relation"]["fields"] & string
|
|
98
|
-
: S extends
|
|
99
|
-
? keyof S["
|
|
100
|
-
: S extends
|
|
101
|
-
? "
|
|
102
|
-
:
|
|
105
|
+
: S extends AnySelectedClosed
|
|
106
|
+
? "id" | (keyof S["relation"]["columns"] & string)
|
|
107
|
+
: S extends AnyRelation
|
|
108
|
+
? keyof S["fields"] & string
|
|
109
|
+
: S extends { readonly axioms: Readonly<Record<string, infer Row>> }
|
|
110
|
+
? "id" | (keyof Row & string)
|
|
111
|
+
: never
|
|
112
|
+
|
|
113
|
+
/**
|
|
114
|
+
* One descriptor's structural comparand: the kind/width/element/roster
|
|
115
|
+
* quadruple — exactly the structure the minimal kernel carries. The first
|
|
116
|
+
* three slots compare exactly as the engine's Q1 law pairs positions
|
|
117
|
+
* (`schema/validate.rs`): a `bytes` width is bound (bytes<16> vs bytes<32>
|
|
118
|
+
* mismatch), while an INTERVAL width is FREE — the pointwise judgments
|
|
119
|
+
* quantify over points, which carry an element domain and not a width, so
|
|
120
|
+
* `interval(u64)` pairs with `interval(u64, 1n)` (recipe 9's extent/slot
|
|
121
|
+
* mirrors, recipe 29's mixed-width zones) and the width slot reads
|
|
122
|
+
* `undefined` for every interval. Elements stay bound: u64-vs-i64 interval
|
|
123
|
+
* pairs still mismatch. The ROSTER slot is SDK-only structure (the engine's
|
|
124
|
+
* wire carries plain u64s): a closed reference contributes its handle
|
|
125
|
+
* union, every other kind `undefined`, so a plain u64 face cannot pair with
|
|
126
|
+
* a closed `[id]` face — the vocabulary's own descriptor (`Kind.id`) is the
|
|
127
|
+
* ONE spelling of a closed reference at this surface, and a bare column
|
|
128
|
+
* cannot alias a vocabulary through a declared law. The runtime twin is the
|
|
129
|
+
* statement constructors' roster-identity walk (`statements.ts`).
|
|
130
|
+
*/
|
|
131
|
+
type ShapeOf<F extends AnyField> = readonly [
|
|
132
|
+
F["kind"],
|
|
133
|
+
F extends { readonly element: unknown } ? undefined : F extends { readonly width: infer W } ? W : undefined,
|
|
134
|
+
F extends { readonly element: infer E } ? E : undefined,
|
|
135
|
+
F extends { readonly closed: { readonly handles: readonly (infer H extends string)[] } } ? H : undefined
|
|
136
|
+
]
|
|
103
137
|
|
|
104
|
-
/** One field's
|
|
105
|
-
type
|
|
138
|
+
/** One field's structural shape within a declared field block (`undefined` when the name is foreign). */
|
|
139
|
+
type ShapeIn<Fields extends FieldsShape, K extends string> = K extends keyof Fields ? ShapeOf<Fields[K]> : undefined
|
|
106
140
|
|
|
107
141
|
/**
|
|
108
|
-
* The
|
|
109
|
-
*
|
|
110
|
-
*
|
|
111
|
-
*
|
|
112
|
-
*
|
|
113
|
-
*
|
|
114
|
-
*
|
|
115
|
-
* compiles and a mismatched one refuses — the identical wall every other
|
|
116
|
-
* face position gets. The lowering carries the same label to the engine,
|
|
117
|
-
* which stays the final authority.
|
|
142
|
+
* The structural SHAPE of one projected field, read off the source's
|
|
143
|
+
* schema type — an ordinary or selected relation's field contributes its
|
|
144
|
+
* descriptor's triple; a closed relation (bare or ψ-selected) contributes
|
|
145
|
+
* its synthetic `id` as a u64 and its payload columns' declared
|
|
146
|
+
* descriptors' triples through the closed value's typed `columns` carrier
|
|
147
|
+
* (whose runtime twin is the frozen `columns` record the mint carries).
|
|
148
|
+
* The engine stays the final authority at `Db.create`/`Db.open`.
|
|
118
149
|
*/
|
|
119
|
-
type
|
|
120
|
-
?
|
|
121
|
-
: S extends
|
|
122
|
-
?
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
150
|
+
type ProjectedShape<S extends FaceSource, K extends string> = S extends AnySelected
|
|
151
|
+
? ShapeIn<RelationFields<S["relation"]>, K>
|
|
152
|
+
: S extends AnySelectedClosed
|
|
153
|
+
? K extends "id"
|
|
154
|
+
? ShapeOf<S["relation"]["id"]>
|
|
155
|
+
: ShapeIn<S["relation"]["columns"], K>
|
|
156
|
+
: S extends AnyRelation
|
|
157
|
+
? ShapeIn<RelationFields<S>, K>
|
|
158
|
+
: S extends {
|
|
159
|
+
readonly id: infer Id extends AnyField
|
|
160
|
+
readonly columns: infer Cols extends Record<string, PayloadField>
|
|
161
|
+
}
|
|
162
|
+
? K extends "id"
|
|
163
|
+
? ShapeOf<Id>
|
|
164
|
+
: ShapeIn<Cols, K>
|
|
165
|
+
: undefined
|
|
166
|
+
|
|
167
|
+
/** The positionwise structural-shape tuple of a projection over `S`. */
|
|
168
|
+
type ShapesOf<S extends FaceSource, P extends readonly string[]> = {
|
|
169
|
+
readonly [I in keyof P]: ProjectedShape<S, P[I] & string>
|
|
135
170
|
}
|
|
136
171
|
|
|
137
|
-
/** The
|
|
138
|
-
type
|
|
172
|
+
/** The shape tuple a face projects, positionwise — the comparand of {@link SameShapes}. */
|
|
173
|
+
type FaceShapes<F extends AnyFace> = F extends Face<infer S, infer P> ? ShapesOf<S, P> : never
|
|
139
174
|
|
|
140
175
|
/** The projection arity of a face. */
|
|
141
176
|
type Arity<F extends AnyFace> = F["projection"]["length"]
|
|
@@ -165,31 +200,37 @@ type SameArity<A extends AnyFace, B extends AnyFace> =
|
|
|
165
200
|
: FaceArityMismatch<Arity<A>, Arity<B>>
|
|
166
201
|
|
|
167
202
|
/**
|
|
168
|
-
* The legible
|
|
169
|
-
* bijection, or window project
|
|
170
|
-
* this type is intersected into the second face's parameter and
|
|
171
|
-
*
|
|
172
|
-
*
|
|
173
|
-
*
|
|
203
|
+
* The legible shape-mismatch verdict: when the two faces of a containment,
|
|
204
|
+
* bijection, or window project structurally incompatible fields at any
|
|
205
|
+
* position, this type is intersected into the second face's parameter and
|
|
206
|
+
* names both shape tuples — a u64 face against a str face, a bytes width
|
|
207
|
+
* mismatch, an interval element mismatch, or a bare column against a
|
|
208
|
+
* closed reference (the roster slot) is a COMPILE error.
|
|
174
209
|
*/
|
|
175
|
-
interface
|
|
176
|
-
readonly "face
|
|
210
|
+
interface FaceShapeMismatch<Left, Right> {
|
|
211
|
+
readonly "face shape mismatch — positionwise kind, width, element, and closed roster must be equal on both sides": readonly [
|
|
212
|
+
Left,
|
|
213
|
+
Right
|
|
214
|
+
]
|
|
177
215
|
}
|
|
178
216
|
|
|
179
217
|
/**
|
|
180
218
|
* Resolves to `unknown` (a no-op intersection) when the two faces project
|
|
181
|
-
* positionwise-equal
|
|
182
|
-
* otherwise. Equality is mutual tuple assignability over
|
|
183
|
-
*
|
|
184
|
-
*
|
|
185
|
-
*
|
|
219
|
+
* positionwise-equal structural shapes, and to {@link FaceShapeMismatch}
|
|
220
|
+
* otherwise. Equality is mutual tuple assignability over the
|
|
221
|
+
* kind/width/element/roster quadruples. This is the whole
|
|
222
|
+
* construction-time wall — deliberately: there is no domain to compare
|
|
223
|
+
* here (the roster is descriptor STRUCTURE, not a domain). The domain wall
|
|
224
|
+
* lives where domains are BORN: `schema()` computes every field's class
|
|
225
|
+
* from the statement list and holds the one-generator-per-class law, and
|
|
226
|
+
* query joins compare class names off the schema type.
|
|
186
227
|
*/
|
|
187
|
-
type
|
|
188
|
-
|
|
189
|
-
?
|
|
228
|
+
type SameShapes<A extends AnyFace, B extends AnyFace> =
|
|
229
|
+
FaceShapes<A> extends FaceShapes<B>
|
|
230
|
+
? FaceShapes<B> extends FaceShapes<A>
|
|
190
231
|
? unknown
|
|
191
|
-
:
|
|
192
|
-
:
|
|
232
|
+
: FaceShapeMismatch<FaceShapes<A>, FaceShapes<B>>
|
|
233
|
+
: FaceShapeMismatch<FaceShapes<A>, FaceShapes<B>>
|
|
193
234
|
|
|
194
235
|
/**
|
|
195
236
|
* Projects a face — one spelling, arity-generic: `on(Account, "holder")`
|
|
@@ -206,7 +247,7 @@ function on<S extends FaceSource, const P extends readonly [FaceFields<S>, ...Fa
|
|
|
206
247
|
source: S,
|
|
207
248
|
fields: P
|
|
208
249
|
): Face<S, P>
|
|
209
|
-
function on(source:
|
|
250
|
+
function on<S extends FaceSource>(source: S, fields: string | readonly string[]): Face<S, readonly string[]> {
|
|
210
251
|
const projection: readonly string[] = Object.freeze(typeof fields === "string" ? [fields] : [...fields])
|
|
211
252
|
const parts = faceParts(source)
|
|
212
253
|
const data: FaceData = Object.freeze({
|
|
@@ -214,7 +255,33 @@ function on(source: FaceSource, fields: string | readonly string[]): Face<FaceSo
|
|
|
214
255
|
projection,
|
|
215
256
|
selection: parts.selection
|
|
216
257
|
})
|
|
217
|
-
|
|
258
|
+
const value = Object.freeze({ source, projection, data })
|
|
259
|
+
if (!faceMinted<S, readonly string[]>(value, source, projection)) {
|
|
260
|
+
throw errors.new(`face over ${parts.owner.name}: face construction incomplete`)
|
|
261
|
+
}
|
|
262
|
+
return value
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
/**
|
|
266
|
+
* The trusted seam of the face mint (the `refsComplete` pattern): the
|
|
267
|
+
* checkable facts — the value carries exactly the source and projection it
|
|
268
|
+
* was built from, and `data.owner` is exactly the owner {@link faceParts}
|
|
269
|
+
* resolves for that source — are verified before the wide construction is
|
|
270
|
+
* admitted at the exact {@link Face} type (whose `data` claims the owner at
|
|
271
|
+
* its precise type, the carrier the schema-level law-typing reads).
|
|
272
|
+
*/
|
|
273
|
+
function faceMinted<S extends FaceSource, P extends readonly string[]>(
|
|
274
|
+
value: { readonly source: FaceSource; readonly projection: readonly string[]; readonly data: FaceData },
|
|
275
|
+
source: S,
|
|
276
|
+
projection: P
|
|
277
|
+
): value is Face<S, P> {
|
|
278
|
+
const owner = "relation" in source ? source.relation : source
|
|
279
|
+
return (
|
|
280
|
+
value.source === source &&
|
|
281
|
+
value.projection === projection &&
|
|
282
|
+
value.data.owner === owner &&
|
|
283
|
+
value.data.projection === projection
|
|
284
|
+
)
|
|
218
285
|
}
|
|
219
286
|
|
|
220
287
|
/**
|
|
@@ -241,13 +308,13 @@ export type {
|
|
|
241
308
|
Face,
|
|
242
309
|
FaceArityMismatch,
|
|
243
310
|
FaceData,
|
|
244
|
-
FaceDomainMismatch,
|
|
245
|
-
FaceDomains,
|
|
246
311
|
FaceFields,
|
|
247
312
|
FaceOwner,
|
|
313
|
+
FaceShapeMismatch,
|
|
314
|
+
FaceShapes,
|
|
248
315
|
FaceSource,
|
|
249
|
-
|
|
316
|
+
OwnerOf,
|
|
250
317
|
SameArity,
|
|
251
|
-
|
|
318
|
+
SameShapes
|
|
252
319
|
}
|
|
253
|
-
export { on,
|
|
320
|
+
export { on, renderFace }
|