@bjornpagen/bumbledb 0.20.2 → 1.0.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 +283 -1611
- package/README.md +156 -118
- package/dist/capacity.d.ts +16 -12
- package/dist/capacity.d.ts.map +1 -1
- package/dist/capacity.js +16 -48
- package/dist/capacity.js.map +1 -1
- package/dist/changes.d.ts +54 -0
- package/dist/changes.d.ts.map +1 -0
- package/dist/changes.js +245 -0
- package/dist/changes.js.map +1 -0
- package/dist/close.d.ts +24 -0
- package/dist/close.d.ts.map +1 -0
- package/dist/close.js +34 -0
- package/dist/close.js.map +1 -0
- package/dist/closed.d.ts +1 -3
- package/dist/closed.d.ts.map +1 -1
- package/dist/closed.js +24 -12
- package/dist/closed.js.map +1 -1
- package/dist/codec.d.ts +56 -0
- package/dist/codec.d.ts.map +1 -0
- package/dist/codec.js +289 -0
- package/dist/codec.js.map +1 -0
- package/dist/compile.d.ts +68 -0
- package/dist/compile.d.ts.map +1 -0
- package/dist/compile.js +75 -0
- package/dist/compile.js.map +1 -0
- package/dist/db-native.d.ts +170 -0
- package/dist/db-native.d.ts.map +1 -0
- package/dist/db-native.js +5 -0
- package/dist/db-native.js.map +1 -0
- package/dist/db.d.ts +101 -233
- package/dist/db.d.ts.map +1 -1
- package/dist/db.js +232 -1084
- package/dist/db.js.map +1 -1
- package/dist/errors.d.ts +57 -0
- package/dist/errors.d.ts.map +1 -0
- package/dist/errors.js +32 -0
- package/dist/errors.js.map +1 -0
- package/dist/face.d.ts.map +1 -1
- package/dist/face.js +2 -2
- package/dist/face.js.map +1 -1
- package/dist/fields.d.ts +65 -24
- package/dist/fields.d.ts.map +1 -1
- package/dist/fields.js +94 -24
- package/dist/fields.js.map +1 -1
- package/dist/index.d.ts +37 -32
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +17 -21
- package/dist/index.js.map +1 -1
- package/dist/internal/log.d.ts +24 -0
- package/dist/internal/log.d.ts.map +1 -0
- package/dist/internal/log.js +10 -0
- package/dist/internal/log.js.map +1 -0
- package/dist/law.d.ts +8 -13
- package/dist/law.d.ts.map +1 -1
- package/dist/law.js +6 -59
- package/dist/law.js.map +1 -1
- package/dist/lower.d.ts +0 -13
- package/dist/lower.d.ts.map +1 -1
- package/dist/lower.js +9 -17
- package/dist/lower.js.map +1 -1
- package/dist/migration.d.ts +33 -0
- package/dist/migration.d.ts.map +1 -0
- package/dist/migration.js +48 -0
- package/dist/migration.js.map +1 -0
- package/dist/native.d.ts +256 -301
- package/dist/native.d.ts.map +1 -1
- package/dist/native.js +65 -108
- package/dist/native.js.map +1 -1
- package/dist/query/atom.d.ts +24 -13
- package/dist/query/atom.d.ts.map +1 -1
- package/dist/query/atom.js +7 -3
- package/dist/query/atom.js.map +1 -1
- package/dist/query/compute.d.ts +68 -0
- package/dist/query/compute.d.ts.map +1 -0
- package/dist/query/compute.js +141 -0
- package/dist/query/compute.js.map +1 -0
- package/dist/query/find.d.ts +15 -8
- package/dist/query/find.d.ts.map +1 -1
- package/dist/query/find.js +6 -2
- package/dist/query/find.js.map +1 -1
- package/dist/query/lower.d.ts +23 -2
- package/dist/query/lower.d.ts.map +1 -1
- package/dist/query/lower.js +433 -80
- package/dist/query/lower.js.map +1 -1
- package/dist/query/parse-ir.d.ts.map +1 -1
- package/dist/query/parse-ir.js +17 -8
- package/dist/query/parse-ir.js.map +1 -1
- package/dist/query/run.d.ts +12 -2
- package/dist/query/run.d.ts.map +1 -1
- package/dist/query/run.js +26 -9
- package/dist/query/run.js.map +1 -1
- package/dist/query/scope.d.ts +47 -3
- package/dist/query/scope.d.ts.map +1 -1
- package/dist/query/scope.js +83 -19
- package/dist/query/scope.js.map +1 -1
- package/dist/relation.d.ts +3 -8
- package/dist/relation.d.ts.map +1 -1
- package/dist/relation.js +16 -10
- package/dist/relation.js.map +1 -1
- package/dist/result.d.ts +47 -0
- package/dist/result.d.ts.map +1 -0
- package/dist/result.js +50 -0
- package/dist/result.js.map +1 -0
- package/dist/rows.d.ts +69 -0
- package/dist/rows.d.ts.map +1 -0
- package/dist/rows.js +328 -0
- package/dist/rows.js.map +1 -0
- package/dist/runtime-codes.d.ts +2 -0
- package/dist/runtime-codes.d.ts.map +1 -0
- package/dist/runtime-codes.js +19 -0
- package/dist/runtime-codes.js.map +1 -0
- package/dist/runtime-errors.d.ts +106 -0
- package/dist/runtime-errors.d.ts.map +1 -0
- package/dist/runtime-errors.js +62 -0
- package/dist/runtime-errors.js.map +1 -0
- package/dist/runtime-native.d.ts +171 -0
- package/dist/runtime-native.d.ts.map +1 -0
- package/dist/runtime-native.js +5 -0
- package/dist/runtime-native.js.map +1 -0
- package/dist/runtime.d.ts +73 -0
- package/dist/runtime.d.ts.map +1 -0
- package/dist/runtime.js +293 -0
- package/dist/runtime.js.map +1 -0
- package/dist/scalar.d.ts +165 -0
- package/dist/scalar.d.ts.map +1 -0
- package/dist/scalar.js +344 -0
- package/dist/scalar.js.map +1 -0
- package/dist/schema.d.ts +1 -1
- package/dist/schema.d.ts.map +1 -1
- package/dist/schema.js +34 -37
- package/dist/schema.js.map +1 -1
- package/dist/shape.d.ts +28 -0
- package/dist/shape.d.ts.map +1 -0
- package/dist/shape.js +2 -0
- package/dist/shape.js.map +1 -0
- package/dist/spec.d.ts +27 -3
- package/dist/spec.d.ts.map +1 -1
- package/dist/spec.js +22 -1
- package/dist/spec.js.map +1 -1
- package/dist/statements.d.ts +16 -3
- package/dist/statements.d.ts.map +1 -1
- package/dist/statements.js +54 -28
- package/dist/statements.js.map +1 -1
- package/dist/uuid.d.ts +23 -0
- package/dist/uuid.d.ts.map +1 -0
- package/dist/uuid.js +54 -0
- package/dist/uuid.js.map +1 -0
- package/pack-provenance.json +7 -0
- package/package.json +12 -16
- package/src/capacity.ts +34 -54
- package/src/changes.ts +361 -0
- package/src/close.ts +53 -0
- package/src/closed.ts +25 -19
- package/src/codec.ts +379 -0
- package/src/compile.ts +149 -0
- package/src/db-native.ts +247 -0
- package/src/db.ts +461 -1632
- package/src/errors.ts +50 -0
- package/src/face.ts +2 -2
- package/src/fields.ts +182 -55
- package/src/index.ts +62 -126
- package/src/internal/log.ts +51 -0
- package/src/law.ts +13 -28
- package/src/lower.ts +9 -4
- package/src/migration.ts +69 -0
- package/src/native.ts +326 -487
- package/src/query/atom.ts +61 -25
- package/src/query/compute.ts +237 -0
- package/src/query/find.ts +31 -12
- package/src/query/lower.ts +531 -143
- package/src/query/parse-ir.ts +18 -13
- package/src/query/run.ts +32 -16
- package/src/query/scope.ts +140 -8
- package/src/relation.ts +17 -21
- package/src/result.ts +130 -0
- package/src/rows.ts +404 -0
- package/src/runtime-codes.ts +18 -0
- package/src/runtime-errors.ts +69 -0
- package/src/runtime-native.ts +242 -0
- package/src/runtime.ts +440 -0
- package/src/scalar.ts +560 -0
- package/src/schema.ts +35 -37
- package/src/shape.ts +31 -0
- package/src/spec.ts +33 -3
- package/src/statements.ts +75 -68
- package/src/uuid.ts +69 -0
- package/dist/marshal.d.ts +0 -44
- package/dist/marshal.d.ts.map +0 -1
- package/dist/marshal.js +0 -165
- package/dist/marshal.js.map +0 -1
- package/src/marshal.ts +0 -200
package/dist/marshal.js
DELETED
|
@@ -1,165 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* The marshal layer: fact object ⇄ positional `FactValue[]` by field
|
|
3
|
-
* ordinal, schema-directed, in ONE place only. The write side lowers named
|
|
4
|
-
* host objects to rows in the relation's field-declaration order
|
|
5
|
-
* (declaration order = ordinal ids, the macro's law); the read side decodes
|
|
6
|
-
* rows back to named objects of BARE structural values — the marshal
|
|
7
|
-
* boundary is pure both ways. CAST-FREE, LITERALLY: with structural values
|
|
8
|
-
* there is no brand to assert on the way out (the historical "one
|
|
9
|
-
* sanctioned marshal cast" died with the brand era), so product code
|
|
10
|
-
* carries zero casts — the only trusted seams are the completeness
|
|
11
|
-
* PREDICATES below, which verify the checkable half (every declared field
|
|
12
|
-
* present) and rely on the store as the proof carrier for the rest: a row
|
|
13
|
-
* the engine admitted IS a legal fact of its relation (the same trust
|
|
14
|
-
* direction as Rust's typed readback). Shape mismatches here are genuine
|
|
15
|
-
* failures and THROW typed; they are never domain data.
|
|
16
|
-
*
|
|
17
|
-
* THE CLOSED BIJECTION (0.4.0): a closed-referencing cell crosses this
|
|
18
|
-
* boundary as its handle NAME — the write side lowers name → u64 row id
|
|
19
|
-
* (declaration order = row ids, the sealed roster's own law, ≤ 256 rows),
|
|
20
|
-
* the read side lifts id → name, and both directions are total and static
|
|
21
|
-
* over the roster. An unknown name is a pointed THROW at the write seam —
|
|
22
|
-
* a deliberate UPGRADE over 0.3.0, where any bigint sailed through the
|
|
23
|
-
* marshal to a commit-time containment violation; the wrong spelling now
|
|
24
|
-
* dies here, before the engine ever sees the row. An out-of-roster id on
|
|
25
|
-
* the read side (reachable only in a store whose closed-typed column was
|
|
26
|
-
* never pinned by its containment law) is equally pointed — never a
|
|
27
|
-
* silent fallback, never `undefined`.
|
|
28
|
-
*/
|
|
29
|
-
import * as errors from "@superbuilders/errors";
|
|
30
|
-
import { isIntervalValue, literalShapeError, rosterOf } from "#fields.ts";
|
|
31
|
-
function isFreshField(field) {
|
|
32
|
-
return "fresh" in field && field.fresh === true;
|
|
33
|
-
}
|
|
34
|
-
function recordOf(fact) {
|
|
35
|
-
if (!isStringIndexed(fact)) {
|
|
36
|
-
throw errors.new("fact object is not string-indexable");
|
|
37
|
-
}
|
|
38
|
-
return fact;
|
|
39
|
-
}
|
|
40
|
-
function isStringIndexed(value) {
|
|
41
|
-
return typeof value === "object" || typeof value === "function";
|
|
42
|
-
}
|
|
43
|
-
/**
|
|
44
|
-
* The write half of the closed bijection: one handle NAME to its u64 row
|
|
45
|
-
* id (declaration order = row ids — the engine's own minting of the
|
|
46
|
-
* sealed extension). An unknown name is a pointed refusal naming the
|
|
47
|
-
* vocabulary and its roster — the 0.4.0 upgrade over any-bigint-compiles:
|
|
48
|
-
* the wrong spelling dies at the marshal, never as a commit-time
|
|
49
|
-
* violation. `indexOf` is the whole machine (the roster is ≤ 256 rows,
|
|
50
|
-
* engine law — no map is warranted).
|
|
51
|
-
*/
|
|
52
|
-
function closedCellOf(context, closed, name) {
|
|
53
|
-
const id = closed.handles.indexOf(name);
|
|
54
|
-
if (id === -1) {
|
|
55
|
-
throw errors.new(`${context}: "${name}" is not a handle of ${closed.name} — the roster is ${closed.handles.join(", ")}`);
|
|
56
|
-
}
|
|
57
|
-
return BigInt(id);
|
|
58
|
-
}
|
|
59
|
-
function handleOf(context, closed, cell) {
|
|
60
|
-
if (typeof cell !== "bigint") {
|
|
61
|
-
throw literalShapeError(context, `a ${closed.name} handle id (bigint)`, cell);
|
|
62
|
-
}
|
|
63
|
-
const handle = closed.handles[Number(cell)];
|
|
64
|
-
if (handle === undefined) {
|
|
65
|
-
throw errors.new(`${context}: id ${cell} is outside the ${closed.name} roster (${closed.handles.join(", ")}) — the column types ${closed.name} but no law pins it — a containment statement is the missing piece`);
|
|
66
|
-
}
|
|
67
|
-
return handle;
|
|
68
|
-
}
|
|
69
|
-
function cellOf(context, field, value) {
|
|
70
|
-
const roster = rosterOf(field);
|
|
71
|
-
if (roster !== undefined) {
|
|
72
|
-
if (typeof value !== "string") {
|
|
73
|
-
throw literalShapeError(context, `a ${roster.name} handle name (string)`, value);
|
|
74
|
-
}
|
|
75
|
-
return closedCellOf(context, roster, value);
|
|
76
|
-
}
|
|
77
|
-
switch (field.kind) {
|
|
78
|
-
case "bool": {
|
|
79
|
-
if (typeof value !== "boolean") {
|
|
80
|
-
throw literalShapeError(context, "boolean", value);
|
|
81
|
-
}
|
|
82
|
-
return value;
|
|
83
|
-
}
|
|
84
|
-
case "u64":
|
|
85
|
-
case "i64": {
|
|
86
|
-
if (typeof value !== "bigint") {
|
|
87
|
-
throw literalShapeError(context, "bigint", value);
|
|
88
|
-
}
|
|
89
|
-
return value;
|
|
90
|
-
}
|
|
91
|
-
case "str": {
|
|
92
|
-
if (typeof value !== "string") {
|
|
93
|
-
throw literalShapeError(context, "string", value);
|
|
94
|
-
}
|
|
95
|
-
if (!value.isWellFormed()) {
|
|
96
|
-
throw literalShapeError(context, "well-formed string", value);
|
|
97
|
-
}
|
|
98
|
-
return value;
|
|
99
|
-
}
|
|
100
|
-
case "bytes": {
|
|
101
|
-
if (!(value instanceof Uint8Array)) {
|
|
102
|
-
throw literalShapeError(context, "Uint8Array", value);
|
|
103
|
-
}
|
|
104
|
-
return value;
|
|
105
|
-
}
|
|
106
|
-
case "interval": {
|
|
107
|
-
if (!isIntervalValue(value)) {
|
|
108
|
-
throw literalShapeError(context, "interval ({ start, end } bigints)", value);
|
|
109
|
-
}
|
|
110
|
-
return { start: value.start, end: value.end };
|
|
111
|
-
}
|
|
112
|
-
}
|
|
113
|
-
}
|
|
114
|
-
function rowOf(relation, fact) {
|
|
115
|
-
return relation.fields.map(function marshalCell(declared) {
|
|
116
|
-
const value = fact[declared.name];
|
|
117
|
-
if (value === undefined) {
|
|
118
|
-
throw errors.new(`relation ${relation.name}: fact is missing field ${declared.name}`);
|
|
119
|
-
}
|
|
120
|
-
return cellOf(`relation ${relation.name} field ${declared.name}`, declared.field, value);
|
|
121
|
-
});
|
|
122
|
-
}
|
|
123
|
-
function keyRowOf(relation, projection, key) {
|
|
124
|
-
return projection.map(function marshalKeyCell(fieldName) {
|
|
125
|
-
const declared = relation.fields.find(function byName(candidate) {
|
|
126
|
-
return candidate.name === fieldName;
|
|
127
|
-
});
|
|
128
|
-
if (declared === undefined) {
|
|
129
|
-
throw errors.new(`relation ${relation.name}: key projection cites unknown field ${fieldName}`);
|
|
130
|
-
}
|
|
131
|
-
const value = key[fieldName];
|
|
132
|
-
if (value === undefined) {
|
|
133
|
-
throw errors.new(`relation ${relation.name}: key object is missing field ${fieldName} — get reads through the primary (first-declared) key, whose projection is (${projection.join(", ")})`);
|
|
134
|
-
}
|
|
135
|
-
return cellOf(`relation ${relation.name} key field ${fieldName}`, declared.field, value);
|
|
136
|
-
});
|
|
137
|
-
}
|
|
138
|
-
function isCompleteFact(relation, decoded) {
|
|
139
|
-
return relation.data.fields.every(function present(declared) {
|
|
140
|
-
return decoded[declared.name] !== undefined;
|
|
141
|
-
});
|
|
142
|
-
}
|
|
143
|
-
function factOf(relation, row) {
|
|
144
|
-
const data = relation.data;
|
|
145
|
-
if (row.length !== data.fields.length) {
|
|
146
|
-
throw errors.new(`relation ${data.name}: row arity ${row.length} does not match the ${data.fields.length} declared fields`);
|
|
147
|
-
}
|
|
148
|
-
const decoded = {};
|
|
149
|
-
data.fields.forEach(function decodeCell(declared, ordinal) {
|
|
150
|
-
const cell = row[ordinal];
|
|
151
|
-
if (cell === undefined) {
|
|
152
|
-
throw errors.new(`relation ${data.name}: row cell ${ordinal} (${declared.name}) is absent`);
|
|
153
|
-
}
|
|
154
|
-
const roster = rosterOf(declared.field);
|
|
155
|
-
decoded[declared.name] =
|
|
156
|
-
roster !== undefined ? handleOf(`relation ${data.name} field ${declared.name}`, roster, cell) : cell;
|
|
157
|
-
});
|
|
158
|
-
Object.freeze(decoded);
|
|
159
|
-
if (!isCompleteFact(relation, decoded)) {
|
|
160
|
-
throw errors.new(`relation ${data.name}: decoded row is not a complete fact`);
|
|
161
|
-
}
|
|
162
|
-
return decoded;
|
|
163
|
-
}
|
|
164
|
-
export { cellOf, factOf, handleOf, isFreshField, keyRowOf, recordOf, rowOf };
|
|
165
|
-
//# sourceMappingURL=marshal.js.map
|
package/dist/marshal.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"marshal.js","sourceRoot":"","sources":["../src/marshal.ts"],"names":[],"mappings":"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"}
|
package/src/marshal.ts
DELETED
|
@@ -1,200 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* The marshal layer: fact object ⇄ positional `FactValue[]` by field
|
|
3
|
-
* ordinal, schema-directed, in ONE place only. The write side lowers named
|
|
4
|
-
* host objects to rows in the relation's field-declaration order
|
|
5
|
-
* (declaration order = ordinal ids, the macro's law); the read side decodes
|
|
6
|
-
* rows back to named objects of BARE structural values — the marshal
|
|
7
|
-
* boundary is pure both ways. CAST-FREE, LITERALLY: with structural values
|
|
8
|
-
* there is no brand to assert on the way out (the historical "one
|
|
9
|
-
* sanctioned marshal cast" died with the brand era), so product code
|
|
10
|
-
* carries zero casts — the only trusted seams are the completeness
|
|
11
|
-
* PREDICATES below, which verify the checkable half (every declared field
|
|
12
|
-
* present) and rely on the store as the proof carrier for the rest: a row
|
|
13
|
-
* the engine admitted IS a legal fact of its relation (the same trust
|
|
14
|
-
* direction as Rust's typed readback). Shape mismatches here are genuine
|
|
15
|
-
* failures and THROW typed; they are never domain data.
|
|
16
|
-
*
|
|
17
|
-
* THE CLOSED BIJECTION (0.4.0): a closed-referencing cell crosses this
|
|
18
|
-
* boundary as its handle NAME — the write side lowers name → u64 row id
|
|
19
|
-
* (declaration order = row ids, the sealed roster's own law, ≤ 256 rows),
|
|
20
|
-
* the read side lifts id → name, and both directions are total and static
|
|
21
|
-
* over the roster. An unknown name is a pointed THROW at the write seam —
|
|
22
|
-
* a deliberate UPGRADE over 0.3.0, where any bigint sailed through the
|
|
23
|
-
* marshal to a commit-time containment violation; the wrong spelling now
|
|
24
|
-
* dies here, before the engine ever sees the row. An out-of-roster id on
|
|
25
|
-
* the read side (reachable only in a store whose closed-typed column was
|
|
26
|
-
* never pinned by its containment law) is equally pointed — never a
|
|
27
|
-
* silent fallback, never `undefined`.
|
|
28
|
-
*/
|
|
29
|
-
|
|
30
|
-
import * as errors from "@superbuilders/errors"
|
|
31
|
-
import type { AnyClosedRoster, AnyField } from "#fields.ts"
|
|
32
|
-
import { isIntervalValue, literalShapeError, rosterOf } from "#fields.ts"
|
|
33
|
-
import type { FactValue } from "#native.ts"
|
|
34
|
-
import type { AnyRelation, Fact, FreshKeys, RelationData } from "#relation.ts"
|
|
35
|
-
|
|
36
|
-
function isFreshField(field: AnyField): boolean {
|
|
37
|
-
return "fresh" in field && field.fresh === true
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
type KeyFact<R extends AnyRelation> = [FreshKeys<R>] extends [never]
|
|
41
|
-
? Partial<Fact<R>>
|
|
42
|
-
: { [K in FreshKeys<R>]: Fact<R>[K] }
|
|
43
|
-
|
|
44
|
-
function recordOf(fact: object): Readonly<Record<string, unknown>> {
|
|
45
|
-
if (!isStringIndexed(fact)) {
|
|
46
|
-
throw errors.new("fact object is not string-indexable")
|
|
47
|
-
}
|
|
48
|
-
return fact
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
function isStringIndexed(value: object): value is Readonly<Record<string, unknown>> {
|
|
52
|
-
return typeof value === "object" || typeof value === "function"
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
/**
|
|
56
|
-
* The write half of the closed bijection: one handle NAME to its u64 row
|
|
57
|
-
* id (declaration order = row ids — the engine's own minting of the
|
|
58
|
-
* sealed extension). An unknown name is a pointed refusal naming the
|
|
59
|
-
* vocabulary and its roster — the 0.4.0 upgrade over any-bigint-compiles:
|
|
60
|
-
* the wrong spelling dies at the marshal, never as a commit-time
|
|
61
|
-
* violation. `indexOf` is the whole machine (the roster is ≤ 256 rows,
|
|
62
|
-
* engine law — no map is warranted).
|
|
63
|
-
*/
|
|
64
|
-
function closedCellOf(context: string, closed: AnyClosedRoster, name: string): FactValue {
|
|
65
|
-
const id = closed.handles.indexOf(name)
|
|
66
|
-
if (id === -1) {
|
|
67
|
-
throw errors.new(
|
|
68
|
-
`${context}: "${name}" is not a handle of ${closed.name} — the roster is ${closed.handles.join(", ")}`
|
|
69
|
-
)
|
|
70
|
-
}
|
|
71
|
-
return BigInt(id)
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
function handleOf(context: string, closed: AnyClosedRoster, cell: FactValue): string {
|
|
75
|
-
if (typeof cell !== "bigint") {
|
|
76
|
-
throw literalShapeError(context, `a ${closed.name} handle id (bigint)`, cell)
|
|
77
|
-
}
|
|
78
|
-
const handle = closed.handles[Number(cell)]
|
|
79
|
-
if (handle === undefined) {
|
|
80
|
-
throw errors.new(
|
|
81
|
-
`${context}: id ${cell} is outside the ${closed.name} roster (${closed.handles.join(", ")}) — the column types ${closed.name} but no law pins it — a containment statement is the missing piece`
|
|
82
|
-
)
|
|
83
|
-
}
|
|
84
|
-
return handle
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
function cellOf(context: string, field: AnyField, value: unknown): FactValue {
|
|
88
|
-
const roster = rosterOf(field)
|
|
89
|
-
if (roster !== undefined) {
|
|
90
|
-
if (typeof value !== "string") {
|
|
91
|
-
throw literalShapeError(context, `a ${roster.name} handle name (string)`, value)
|
|
92
|
-
}
|
|
93
|
-
return closedCellOf(context, roster, value)
|
|
94
|
-
}
|
|
95
|
-
switch (field.kind) {
|
|
96
|
-
case "bool": {
|
|
97
|
-
if (typeof value !== "boolean") {
|
|
98
|
-
throw literalShapeError(context, "boolean", value)
|
|
99
|
-
}
|
|
100
|
-
return value
|
|
101
|
-
}
|
|
102
|
-
case "u64":
|
|
103
|
-
case "i64": {
|
|
104
|
-
if (typeof value !== "bigint") {
|
|
105
|
-
throw literalShapeError(context, "bigint", value)
|
|
106
|
-
}
|
|
107
|
-
return value
|
|
108
|
-
}
|
|
109
|
-
case "str": {
|
|
110
|
-
if (typeof value !== "string") {
|
|
111
|
-
throw literalShapeError(context, "string", value)
|
|
112
|
-
}
|
|
113
|
-
|
|
114
|
-
if (!value.isWellFormed()) {
|
|
115
|
-
throw literalShapeError(context, "well-formed string", value)
|
|
116
|
-
}
|
|
117
|
-
return value
|
|
118
|
-
}
|
|
119
|
-
case "bytes": {
|
|
120
|
-
if (!(value instanceof Uint8Array)) {
|
|
121
|
-
throw literalShapeError(context, "Uint8Array", value)
|
|
122
|
-
}
|
|
123
|
-
return value
|
|
124
|
-
}
|
|
125
|
-
case "interval": {
|
|
126
|
-
if (!isIntervalValue(value)) {
|
|
127
|
-
throw literalShapeError(context, "interval ({ start, end } bigints)", value)
|
|
128
|
-
}
|
|
129
|
-
return { start: value.start, end: value.end }
|
|
130
|
-
}
|
|
131
|
-
}
|
|
132
|
-
}
|
|
133
|
-
|
|
134
|
-
function rowOf(relation: RelationData, fact: Readonly<Record<string, unknown>>): FactValue[] {
|
|
135
|
-
return relation.fields.map(function marshalCell(declared) {
|
|
136
|
-
const value = fact[declared.name]
|
|
137
|
-
if (value === undefined) {
|
|
138
|
-
throw errors.new(`relation ${relation.name}: fact is missing field ${declared.name}`)
|
|
139
|
-
}
|
|
140
|
-
return cellOf(`relation ${relation.name} field ${declared.name}`, declared.field, value)
|
|
141
|
-
})
|
|
142
|
-
}
|
|
143
|
-
|
|
144
|
-
function keyRowOf(
|
|
145
|
-
relation: RelationData,
|
|
146
|
-
projection: readonly string[],
|
|
147
|
-
key: Readonly<Record<string, unknown>>
|
|
148
|
-
): FactValue[] {
|
|
149
|
-
return projection.map(function marshalKeyCell(fieldName) {
|
|
150
|
-
const declared = relation.fields.find(function byName(candidate) {
|
|
151
|
-
return candidate.name === fieldName
|
|
152
|
-
})
|
|
153
|
-
if (declared === undefined) {
|
|
154
|
-
throw errors.new(`relation ${relation.name}: key projection cites unknown field ${fieldName}`)
|
|
155
|
-
}
|
|
156
|
-
const value = key[fieldName]
|
|
157
|
-
if (value === undefined) {
|
|
158
|
-
throw errors.new(
|
|
159
|
-
`relation ${relation.name}: key object is missing field ${fieldName} — get reads through the primary (first-declared) key, whose projection is (${projection.join(", ")})`
|
|
160
|
-
)
|
|
161
|
-
}
|
|
162
|
-
return cellOf(`relation ${relation.name} key field ${fieldName}`, declared.field, value)
|
|
163
|
-
})
|
|
164
|
-
}
|
|
165
|
-
|
|
166
|
-
function isCompleteFact<R extends AnyRelation>(
|
|
167
|
-
relation: R,
|
|
168
|
-
decoded: Readonly<Record<string, FactValue>>
|
|
169
|
-
): decoded is Readonly<Record<string, FactValue>> & Fact<R> {
|
|
170
|
-
return relation.data.fields.every(function present(declared) {
|
|
171
|
-
return decoded[declared.name] !== undefined
|
|
172
|
-
})
|
|
173
|
-
}
|
|
174
|
-
|
|
175
|
-
function factOf<R extends AnyRelation>(relation: R, row: readonly FactValue[]): Fact<R> {
|
|
176
|
-
const data = relation.data
|
|
177
|
-
if (row.length !== data.fields.length) {
|
|
178
|
-
throw errors.new(
|
|
179
|
-
`relation ${data.name}: row arity ${row.length} does not match the ${data.fields.length} declared fields`
|
|
180
|
-
)
|
|
181
|
-
}
|
|
182
|
-
const decoded: Record<string, FactValue> = {}
|
|
183
|
-
data.fields.forEach(function decodeCell(declared, ordinal) {
|
|
184
|
-
const cell = row[ordinal]
|
|
185
|
-
if (cell === undefined) {
|
|
186
|
-
throw errors.new(`relation ${data.name}: row cell ${ordinal} (${declared.name}) is absent`)
|
|
187
|
-
}
|
|
188
|
-
const roster = rosterOf(declared.field)
|
|
189
|
-
decoded[declared.name] =
|
|
190
|
-
roster !== undefined ? handleOf(`relation ${data.name} field ${declared.name}`, roster, cell) : cell
|
|
191
|
-
})
|
|
192
|
-
Object.freeze(decoded)
|
|
193
|
-
if (!isCompleteFact(relation, decoded)) {
|
|
194
|
-
throw errors.new(`relation ${data.name}: decoded row is not a complete fact`)
|
|
195
|
-
}
|
|
196
|
-
return decoded
|
|
197
|
-
}
|
|
198
|
-
|
|
199
|
-
export type { KeyFact }
|
|
200
|
-
export { cellOf, factOf, handleOf, isFreshField, keyRowOf, recordOf, rowOf }
|