@bjornpagen/bumbledb 0.1.0 → 0.2.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 +1394 -0
- package/README.md +4 -0
- package/dist/closed.d.ts +60 -37
- package/dist/closed.d.ts.map +1 -1
- package/dist/closed.js +159 -40
- package/dist/closed.js.map +1 -1
- package/dist/count.d.ts +64 -17
- package/dist/count.d.ts.map +1 -1
- package/dist/count.js +37 -14
- package/dist/count.js.map +1 -1
- package/dist/db.d.ts +15 -7
- package/dist/db.d.ts.map +1 -1
- package/dist/db.js +13 -5
- package/dist/db.js.map +1 -1
- package/dist/exhume.d.ts +12 -11
- package/dist/exhume.d.ts.map +1 -1
- package/dist/exhume.js +7 -6
- package/dist/exhume.js.map +1 -1
- package/dist/face.d.ts +79 -19
- package/dist/face.d.ts.map +1 -1
- package/dist/face.js +14 -15
- package/dist/face.js.map +1 -1
- package/dist/fields.d.ts +158 -129
- package/dist/fields.d.ts.map +1 -1
- package/dist/fields.js +80 -81
- package/dist/fields.js.map +1 -1
- package/dist/index.d.ts +21 -21
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +13 -12
- package/dist/index.js.map +1 -1
- package/dist/lower.d.ts +6 -3
- package/dist/lower.d.ts.map +1 -1
- package/dist/lower.js +48 -17
- package/dist/lower.js.map +1 -1
- package/dist/marshal.d.ts +36 -21
- package/dist/marshal.d.ts.map +1 -1
- package/dist/marshal.js +41 -25
- package/dist/marshal.js.map +1 -1
- package/dist/native.js +2 -2
- package/dist/query/atom.d.ts +332 -174
- package/dist/query/atom.d.ts.map +1 -1
- package/dist/query/atom.js +72 -172
- package/dist/query/atom.js.map +1 -1
- package/dist/query/lower.d.ts +295 -107
- package/dist/query/lower.d.ts.map +1 -1
- package/dist/query/lower.js +860 -388
- package/dist/query/lower.js.map +1 -1
- package/dist/query/predicate.d.ts +69 -88
- package/dist/query/predicate.d.ts.map +1 -1
- package/dist/query/predicate.js +118 -72
- package/dist/query/predicate.js.map +1 -1
- package/dist/query/run.d.ts +19 -16
- package/dist/query/run.d.ts.map +1 -1
- package/dist/query/run.js +31 -24
- package/dist/query/run.js.map +1 -1
- package/dist/query/scope.d.ts +139 -123
- package/dist/query/scope.d.ts.map +1 -1
- package/dist/query/scope.js +71 -115
- package/dist/query/scope.js.map +1 -1
- package/dist/query/select.d.ts +102 -80
- package/dist/query/select.d.ts.map +1 -1
- package/dist/query/select.js +39 -34
- package/dist/query/select.js.map +1 -1
- package/dist/relation.d.ts +33 -36
- package/dist/relation.d.ts.map +1 -1
- package/dist/relation.js +15 -16
- package/dist/relation.js.map +1 -1
- package/dist/schema.d.ts.map +1 -1
- package/dist/schema.js +19 -8
- package/dist/schema.js.map +1 -1
- package/dist/spec.d.ts +6 -5
- package/dist/spec.d.ts.map +1 -1
- package/dist/spec.js.map +1 -1
- package/dist/statements.d.ts +56 -31
- package/dist/statements.d.ts.map +1 -1
- package/dist/statements.js +38 -13
- package/dist/statements.js.map +1 -1
- package/package.json +4 -3
- package/src/closed.ts +271 -93
- package/src/count.ts +112 -18
- package/src/db.ts +22 -12
- package/src/exhume.ts +12 -11
- package/src/face.ts +114 -22
- package/src/fields.ts +261 -217
- package/src/index.ts +50 -59
- package/src/lower.ts +62 -20
- package/src/marshal.ts +48 -30
- package/src/native.ts +2 -2
- package/src/query/atom.ts +480 -376
- package/src/query/lower.ts +1341 -542
- package/src/query/predicate.ts +198 -161
- package/src/query/run.ts +35 -25
- package/src/query/scope.ts +188 -218
- package/src/query/select.ts +168 -93
- package/src/relation.ts +38 -44
- package/src/schema.ts +22 -12
- package/src/spec.ts +6 -5
- package/src/statements.ts +69 -26
- package/dist/brand.d.ts +0 -59
- package/dist/brand.d.ts.map +0 -1
- package/dist/brand.js +0 -47
- package/dist/brand.js.map +0 -1
- package/src/brand.ts +0 -82
package/README.md
CHANGED
|
@@ -73,6 +73,10 @@ const rows = db.execute(prepared, { holder: adaId }) // rows: { acct: AccountId
|
|
|
73
73
|
- The query surface — Datalog as values: scoped vars/params, atoms, negation, conditions, aggregates, engine recursion via predicates, `db.prepare`.
|
|
74
74
|
- The exhume surface — `Db.exhume`, the schema-independent read path: a store's self-described shapes and raw facts by name.
|
|
75
75
|
|
|
76
|
+
## Cookbook
|
|
77
|
+
|
|
78
|
+
The engine cookbook's 29 modeling recipes, translated to this SDK's structural API: [COOKBOOK.md](./COOKBOOK.md). Every recipe is compile-pinned by `test/cookbook.test.ts` — each schema is admitted by the real engine and every query snippet lowers through `db.prepare` — so the cookbook can never drift from the surface.
|
|
79
|
+
|
|
76
80
|
## Architecture
|
|
77
81
|
|
|
78
82
|
The SDK is a typed surface over the native engine; the model (relations,
|
package/dist/closed.d.ts
CHANGED
|
@@ -1,28 +1,34 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Closed relations (`docs/architecture/10-data-model.md` § closed
|
|
3
3
|
* relations): a vocabulary whose extension is declared in the schema — two
|
|
4
|
-
* tiers, one function. The emission per closed relation mirrors the
|
|
5
|
-
* (host-enum analog): handle CONSTANTS on the value
|
|
6
|
-
* declaration order
|
|
7
|
-
*
|
|
8
|
-
* (`
|
|
9
|
-
*
|
|
4
|
+
* tiers, one function. The emission per closed relation mirrors the
|
|
5
|
+
* macro's (host-enum analog): handle CONSTANTS on the value
|
|
6
|
+
* (`Kind.Checking`, ids = declaration order, each a BARE `bigint` — no
|
|
7
|
+
* brand), the `fromId` weld, an `id` field descriptor carrying the handle
|
|
8
|
+
* DOMAIN (`"KindId"`, mirroring Rust's `closed relation Kind as KindId`)
|
|
9
|
+
* for other relations' field blocks (`kind: Kind.id`), payload readback
|
|
10
|
+
* (`Kind.axioms`), and the declared payload column descriptors
|
|
11
|
+
* (`Kind.columns` — the runtime twin of the `Cols` type parameter, which
|
|
12
|
+
* the face layer's domain wall reads). Bare tier: `closed("Kind", ["Checking",
|
|
13
|
+
* "Savings"])`. Payload tier: `closed("Sev", { pages: bool })({ Critical:
|
|
14
|
+
* { pages: true }, ... })` — the axioms record IS the handle declaration,
|
|
15
|
+
* every handle carrying every column exactly once (type-enforced). No fact
|
|
16
|
+
* type and no insert surface exist — closed relations are unwritable by
|
|
10
17
|
* construction: the value simply lacks the writable relation shape.
|
|
11
18
|
*/
|
|
12
|
-
import type
|
|
13
|
-
import { type AnyField, type ClosedIdField, type FieldData, type FieldValue } from "#fields.ts";
|
|
19
|
+
import { type AnyField, type ClosedIdField, type Infer } from "#fields.ts";
|
|
14
20
|
import type { LiteralSpec } from "#spec.ts";
|
|
15
21
|
/**
|
|
16
|
-
* A payload column of a closed relation: any field
|
|
22
|
+
* A payload column of a closed relation: any field descriptor except a
|
|
17
23
|
* fresh-marked one (a vocabulary's rows are ground axioms, never minted).
|
|
18
24
|
*/
|
|
19
|
-
type PayloadField = AnyField
|
|
20
|
-
readonly
|
|
21
|
-
}
|
|
22
|
-
/** One declared payload column: name plus its field
|
|
25
|
+
type PayloadField = Exclude<AnyField, {
|
|
26
|
+
readonly fresh: true;
|
|
27
|
+
}>;
|
|
28
|
+
/** One declared payload column: name plus its field descriptor. */
|
|
23
29
|
interface ClosedColumn {
|
|
24
30
|
readonly name: string;
|
|
25
|
-
readonly field:
|
|
31
|
+
readonly field: PayloadField;
|
|
26
32
|
}
|
|
27
33
|
/**
|
|
28
34
|
* One ground axiom, already lowered: the handle plus one wire literal per
|
|
@@ -41,57 +47,74 @@ interface ClosedData {
|
|
|
41
47
|
readonly columns: readonly ClosedColumn[];
|
|
42
48
|
readonly rows: readonly ClosedRow[];
|
|
43
49
|
}
|
|
44
|
-
/** One axiom row as the host writes and reads it: column name to
|
|
45
|
-
type AxiomRow<Cols
|
|
46
|
-
readonly [C in keyof Cols]:
|
|
50
|
+
/** One axiom row as the host writes and reads it: column name to bare structural value. */
|
|
51
|
+
type AxiomRow<Cols extends Record<string, PayloadField>> = {
|
|
52
|
+
readonly [C in keyof Cols]: Infer<Cols[C]>;
|
|
47
53
|
};
|
|
48
54
|
/**
|
|
49
55
|
* The whole axiom record: every handle exactly once, every column exactly
|
|
50
|
-
* once per row — a missing or extra
|
|
51
|
-
*
|
|
56
|
+
* once per row — a missing or extra column is a TYPE error (each row is
|
|
57
|
+
* contextually checked against the declared columns), and the handle set
|
|
58
|
+
* IS the record's key set.
|
|
52
59
|
*/
|
|
53
|
-
type Axioms<Handles extends
|
|
54
|
-
readonly [H in Handles
|
|
60
|
+
type Axioms<Handles extends string, Cols extends Record<string, PayloadField>> = {
|
|
61
|
+
readonly [H in Handles]: AxiomRow<Cols>;
|
|
55
62
|
};
|
|
56
63
|
/**
|
|
57
64
|
* The named surface of a closed relation value, minus the handle constants
|
|
58
65
|
* (which {@link Closed} intersects in).
|
|
59
66
|
*/
|
|
60
|
-
interface ClosedCore<Name extends string, Handles extends
|
|
67
|
+
interface ClosedCore<Name extends string, Handles extends string, Cols extends Record<string, PayloadField>> {
|
|
61
68
|
readonly name: Name;
|
|
62
69
|
/**
|
|
63
|
-
* The
|
|
64
|
-
* relation's field block is the reference through which bare
|
|
65
|
-
* become legal in that relation's selections.
|
|
70
|
+
* The handle-domain reference descriptor: `kind: Kind.id` in another
|
|
71
|
+
* relation's field block is the reference through which bare handle ids
|
|
72
|
+
* become legal in that relation's selections. Its domain is the closed
|
|
73
|
+
* relation's handle domain (`"KindId"` — Rust's `as KindId`).
|
|
66
74
|
*/
|
|
67
|
-
readonly id: ClosedIdField
|
|
75
|
+
readonly id: ClosedIdField<`${Name}Id`>;
|
|
68
76
|
readonly data: ClosedData;
|
|
69
|
-
/** Payload readback: handle to its declared column values. */
|
|
77
|
+
/** Payload readback: handle to its declared column values, bare and structural. */
|
|
70
78
|
readonly axioms: Axioms<Handles, Cols>;
|
|
79
|
+
/**
|
|
80
|
+
* The declared payload columns, name → S1 field descriptor — an HONEST
|
|
81
|
+
* frozen runtime record (the descriptors themselves, by identity), and
|
|
82
|
+
* the typed carrier a projected payload column's domain label is
|
|
83
|
+
* recovered through off the schema type (the face layer's
|
|
84
|
+
* `ProjectedDomain` reads it; `data.columns` carries the same
|
|
85
|
+
* descriptors in declaration order for the lowering).
|
|
86
|
+
*/
|
|
87
|
+
readonly columns: Cols;
|
|
71
88
|
/** The weld: declaration-order id back to its handle, or undefined beyond the roster. */
|
|
72
|
-
fromId(id:
|
|
89
|
+
fromId(id: bigint): Handles | undefined;
|
|
73
90
|
}
|
|
74
91
|
/**
|
|
75
|
-
* A closed relation value: the core surface plus one
|
|
76
|
-
* handle (`Kind.Checking:
|
|
92
|
+
* A closed relation value: the core surface plus one BARE constant per
|
|
93
|
+
* handle (`Kind.Checking: bigint`, ids = declaration order — the value is
|
|
94
|
+
* structural; the roster judges out-of-vocabulary ids at construction and
|
|
95
|
+
* the engine at commit).
|
|
77
96
|
*/
|
|
78
|
-
type Closed<Name extends string, Handles extends
|
|
79
|
-
readonly [H in Handles
|
|
97
|
+
type Closed<Name extends string, Handles extends string, Cols extends Record<string, PayloadField>> = ClosedCore<Name, Handles, Cols> & {
|
|
98
|
+
readonly [H in Handles]: bigint;
|
|
80
99
|
};
|
|
81
100
|
/** Any closed relation value, whatever its roster and columns. */
|
|
82
101
|
interface AnyClosed {
|
|
83
102
|
readonly name: string;
|
|
84
|
-
readonly id: ClosedIdField
|
|
103
|
+
readonly id: ClosedIdField;
|
|
85
104
|
readonly data: ClosedData;
|
|
86
105
|
readonly axioms: Readonly<Record<string, object>>;
|
|
106
|
+
readonly columns: Readonly<Record<string, PayloadField>>;
|
|
87
107
|
}
|
|
88
108
|
/** Bare tier: `closed("Kind", ["Checking", "Savings"])` — handles only. */
|
|
89
|
-
declare function closed<const Name extends string, const Handles extends readonly [string, ...string[]]>(name: Name, handles: Handles): Closed<Name, Handles, Record<never, never>>;
|
|
109
|
+
declare function closed<const Name extends string, const Handles extends readonly [string, ...string[]]>(name: Name, handles: Handles): Closed<Name, Handles[number], Record<never, never>>;
|
|
90
110
|
/**
|
|
91
|
-
* Payload tier: declared columns
|
|
92
|
-
*
|
|
111
|
+
* Payload tier: declared columns, then ground axioms — `closed("Grade",
|
|
112
|
+
* { mastered: bool })({ DirectPass: { mastered: true }, Failed: { mastered:
|
|
113
|
+
* false } })`. The axioms record's keys ARE the handles (declaration order
|
|
114
|
+
* = key order, integer-index names rejected); every row carries every
|
|
115
|
+
* column exactly once (type-enforced by {@link Axioms}).
|
|
93
116
|
*/
|
|
94
|
-
declare function closed<const Name extends string, const
|
|
117
|
+
declare function closed<const Name extends string, const Cols extends Record<string, PayloadField>>(name: Name, columns: Cols): <Handles extends string>(axioms: Axioms<Handles, Cols>) => Closed<Name, Handles, Cols>;
|
|
95
118
|
export type { AnyClosed, AxiomRow, Axioms, Closed, ClosedColumn, ClosedCore, ClosedData, ClosedRow, PayloadField };
|
|
96
119
|
export { closed };
|
|
97
120
|
//# sourceMappingURL=closed.d.ts.map
|
package/dist/closed.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"closed.d.ts","sourceRoot":"","sources":["../src/closed.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"closed.d.ts","sourceRoot":"","sources":["../src/closed.ts"],"names":[],"mappings":"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"}
|
package/dist/closed.js
CHANGED
|
@@ -1,16 +1,23 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Closed relations (`docs/architecture/10-data-model.md` § closed
|
|
3
3
|
* relations): a vocabulary whose extension is declared in the schema — two
|
|
4
|
-
* tiers, one function. The emission per closed relation mirrors the
|
|
5
|
-
* (host-enum analog): handle CONSTANTS on the value
|
|
6
|
-
* declaration order
|
|
7
|
-
*
|
|
8
|
-
* (`
|
|
9
|
-
*
|
|
4
|
+
* tiers, one function. The emission per closed relation mirrors the
|
|
5
|
+
* macro's (host-enum analog): handle CONSTANTS on the value
|
|
6
|
+
* (`Kind.Checking`, ids = declaration order, each a BARE `bigint` — no
|
|
7
|
+
* brand), the `fromId` weld, an `id` field descriptor carrying the handle
|
|
8
|
+
* DOMAIN (`"KindId"`, mirroring Rust's `closed relation Kind as KindId`)
|
|
9
|
+
* for other relations' field blocks (`kind: Kind.id`), payload readback
|
|
10
|
+
* (`Kind.axioms`), and the declared payload column descriptors
|
|
11
|
+
* (`Kind.columns` — the runtime twin of the `Cols` type parameter, which
|
|
12
|
+
* the face layer's domain wall reads). Bare tier: `closed("Kind", ["Checking",
|
|
13
|
+
* "Savings"])`. Payload tier: `closed("Sev", { pages: bool })({ Critical:
|
|
14
|
+
* { pages: true }, ... })` — the axioms record IS the handle declaration,
|
|
15
|
+
* every handle carrying every column exactly once (type-enforced). No fact
|
|
16
|
+
* type and no insert surface exist — closed relations are unwritable by
|
|
10
17
|
* construction: the value simply lacks the writable relation shape.
|
|
11
18
|
*/
|
|
12
19
|
import * as errors from "@superbuilders/errors";
|
|
13
|
-
import { assertDeclarationOrderKey,
|
|
20
|
+
import { assertDeclarationOrderKey, literalOf } from "#fields.ts";
|
|
14
21
|
/**
|
|
15
22
|
* The value-surface property names a handle may not shadow — the macro's
|
|
16
23
|
* name-collision diagnostic, here over the closed value's own properties
|
|
@@ -22,26 +29,136 @@ const reservedHandleNames = Object.freeze([
|
|
|
22
29
|
"id",
|
|
23
30
|
"data",
|
|
24
31
|
"axioms",
|
|
32
|
+
"columns",
|
|
25
33
|
"fromId",
|
|
26
34
|
"relation",
|
|
27
35
|
"selection"
|
|
28
36
|
]);
|
|
37
|
+
/** Narrows the two-tier second argument: a handle tuple (bare tier) or a column block (payload tier). */
|
|
38
|
+
function isHandleTuple(shape) {
|
|
39
|
+
return Array.isArray(shape);
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* The trusted seam of the payload tier's handle enumeration: the axioms
|
|
43
|
+
* record's own enumerable keys ARE its handle set (the type says so —
|
|
44
|
+
* {@link Axioms} is keyed by the handles), and this guard verifies exactly
|
|
45
|
+
* that checkable fact before the key list is admitted at the handle type.
|
|
46
|
+
*/
|
|
47
|
+
function handleKeysOwn(axioms, names) {
|
|
48
|
+
return names.every(function ownHandle(name) {
|
|
49
|
+
return Object.hasOwn(axioms, name);
|
|
50
|
+
});
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* The trusted seam of the axiom-readback mint: every handle carries an own
|
|
54
|
+
* frozen row and every row carries every declared column as an own
|
|
55
|
+
* property — verified before the record is admitted as the typed
|
|
56
|
+
* {@link Axioms} (the `refsComplete` analog of `relation()`).
|
|
57
|
+
*/
|
|
58
|
+
function axiomsMinted(record, handles, cols) {
|
|
59
|
+
return handles.every(function rowMinted(handle) {
|
|
60
|
+
const row = record[handle];
|
|
61
|
+
return (row !== undefined &&
|
|
62
|
+
cols.every(function columnMinted(column) {
|
|
63
|
+
return Object.hasOwn(row, column.name);
|
|
64
|
+
}));
|
|
65
|
+
});
|
|
66
|
+
}
|
|
67
|
+
/**
|
|
68
|
+
* The trusted seam of the handle-constant mint: every handle reads back as
|
|
69
|
+
* an own bigint — verified before the record is admitted at the constants
|
|
70
|
+
* type (a "__proto__"-named handle riding the object-protocol accessor
|
|
71
|
+
* would fail exactly this check).
|
|
72
|
+
*/
|
|
73
|
+
function constantsMinted(record, handles) {
|
|
74
|
+
return handles.every(function constantMinted(handle) {
|
|
75
|
+
return typeof record[handle] === "bigint";
|
|
76
|
+
});
|
|
77
|
+
}
|
|
29
78
|
/**
|
|
30
|
-
* Reads one handle's axiom row
|
|
31
|
-
*
|
|
32
|
-
*
|
|
79
|
+
* Reads one handle's ground axiom row for lowering. The typed payload
|
|
80
|
+
* surface makes absence unrepresentable ({@link Axioms} carries every
|
|
81
|
+
* handle's row); the refusal below guards the one ill-typed path — payload
|
|
82
|
+
* columns with the bare tier's absent axioms — which no public spelling
|
|
83
|
+
* reaches.
|
|
33
84
|
*/
|
|
34
|
-
function
|
|
85
|
+
function groundRow(name, axioms, handle) {
|
|
35
86
|
if (axioms === undefined) {
|
|
36
87
|
throw errors.new(`closed relation ${name}: payload columns declared without ground axioms`);
|
|
37
88
|
}
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
89
|
+
return axioms[handle];
|
|
90
|
+
}
|
|
91
|
+
/**
|
|
92
|
+
* Mints the axiom-readback record: one own frozen row per handle (the bare
|
|
93
|
+
* tier's rows are empty — it declares no columns), each row a fresh copy of
|
|
94
|
+
* its ground axiom.
|
|
95
|
+
*/
|
|
96
|
+
function mintAxioms(name, handles, cols, axioms) {
|
|
97
|
+
const out = {};
|
|
98
|
+
for (const handle of handles) {
|
|
99
|
+
const row = axioms === undefined ? Object.freeze({}) : Object.freeze({ ...groundRow(name, axioms, handle) });
|
|
100
|
+
Object.defineProperty(out, handle, { value: row, enumerable: true });
|
|
101
|
+
}
|
|
102
|
+
Object.freeze(out);
|
|
103
|
+
if (!axiomsMinted(out, handles, cols)) {
|
|
104
|
+
throw errors.new(`closed relation ${name}: axiom-row minting incomplete`);
|
|
105
|
+
}
|
|
106
|
+
return out;
|
|
107
|
+
}
|
|
108
|
+
/** Mints the handle constants: one own bigint per handle, ids = declaration order. */
|
|
109
|
+
function mintHandleConstants(name, handles) {
|
|
110
|
+
const out = {};
|
|
111
|
+
handles.forEach(function mintHandleConstant(handle, index) {
|
|
112
|
+
Object.defineProperty(out, handle, { value: BigInt(index), enumerable: true });
|
|
113
|
+
});
|
|
114
|
+
Object.freeze(out);
|
|
115
|
+
if (!constantsMinted(out, handles)) {
|
|
116
|
+
throw errors.new(`closed relation ${name}: handle-constant minting incomplete`);
|
|
117
|
+
}
|
|
118
|
+
return out;
|
|
119
|
+
}
|
|
120
|
+
function closed(name, shape) {
|
|
121
|
+
if (isHandleTuple(shape)) {
|
|
122
|
+
return closedBare(name, shape);
|
|
123
|
+
}
|
|
124
|
+
return closedPayload(name, shape);
|
|
125
|
+
}
|
|
126
|
+
/** The bare tier's precisely-typed builder: no columns, no axioms. */
|
|
127
|
+
function closedBare(name, handles) {
|
|
128
|
+
return mintClosed(name, handles, {}, undefined);
|
|
129
|
+
}
|
|
130
|
+
/**
|
|
131
|
+
* The payload tier's precisely-typed builder: column names are judged
|
|
132
|
+
* EAGERLY (at `closed(name, columns)`, before any axioms arrive — the
|
|
133
|
+
* macro-expansion analog), and the returned `withAxioms` reads its handle
|
|
134
|
+
* set off the axioms record's own keys.
|
|
135
|
+
*/
|
|
136
|
+
function closedPayload(name, columns) {
|
|
137
|
+
for (const columnName of Object.keys(columns)) {
|
|
138
|
+
assertDeclarationOrderKey(`closed relation ${name} column`, columnName);
|
|
41
139
|
}
|
|
42
|
-
return
|
|
140
|
+
return function withAxioms(axioms) {
|
|
141
|
+
const handles = Object.keys(axioms);
|
|
142
|
+
for (const handle of handles) {
|
|
143
|
+
assertDeclarationOrderKey(`closed relation ${name} handle`, handle);
|
|
144
|
+
}
|
|
145
|
+
if (!handleKeysOwn(axioms, handles)) {
|
|
146
|
+
throw errors.new(`closed relation ${name}: handle enumeration incomplete`);
|
|
147
|
+
}
|
|
148
|
+
return mintClosed(name, handles, columns, axioms);
|
|
149
|
+
};
|
|
43
150
|
}
|
|
44
|
-
|
|
151
|
+
/**
|
|
152
|
+
* Mints one closed relation value — the shared seam of both tiers, HONESTLY
|
|
153
|
+
* typed end to end (a wrong-shaped mint is a compile error here, not a
|
|
154
|
+
* laundered `unknown`): roster checks, eager axiom lowering, the
|
|
155
|
+
* domain-labeled `id` descriptor, the frozen `columns` carrier (the runtime
|
|
156
|
+
* twin of the `Cols` type parameter), and the handle constants.
|
|
157
|
+
*/
|
|
158
|
+
function mintClosed(name, handles, columns, axioms) {
|
|
159
|
+
if (handles.length === 0) {
|
|
160
|
+
throw errors.new(`closed relation ${name}: at least one handle is required (an empty vocabulary declares nothing)`);
|
|
161
|
+
}
|
|
45
162
|
const seen = new Set();
|
|
46
163
|
for (const handle of handles) {
|
|
47
164
|
if (seen.has(handle)) {
|
|
@@ -52,17 +169,17 @@ function closed(name, handles, columns, axioms) {
|
|
|
52
169
|
throw errors.new(`closed relation ${name}: handle ${handle} collides with the closed value's own surface (${reservedHandleNames.join(", ")})`);
|
|
53
170
|
}
|
|
54
171
|
}
|
|
55
|
-
const
|
|
172
|
+
const handleList = Object.freeze([...handles]);
|
|
173
|
+
const roster = Object.freeze({ name, handles: handleList });
|
|
56
174
|
const cols = [];
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
cols.push(Object.freeze({ name: columnName, field: field.data }));
|
|
61
|
-
}
|
|
175
|
+
for (const [columnName, field] of Object.entries(columns)) {
|
|
176
|
+
assertDeclarationOrderKey(`closed relation ${name} column`, columnName);
|
|
177
|
+
cols.push(Object.freeze({ name: columnName, field }));
|
|
62
178
|
}
|
|
63
|
-
|
|
179
|
+
Object.freeze(cols);
|
|
180
|
+
const rows = handleList.map(function lowerRow(handle) {
|
|
64
181
|
const values = cols.map(function lowerAxiomLiteral(column) {
|
|
65
|
-
const row =
|
|
182
|
+
const row = groundRow(name, axioms, handle);
|
|
66
183
|
return Object.freeze(literalOf(column.field, row[column.name]));
|
|
67
184
|
});
|
|
68
185
|
return Object.freeze({ handle, values: Object.freeze(values) });
|
|
@@ -70,38 +187,40 @@ function closed(name, handles, columns, axioms) {
|
|
|
70
187
|
const data = Object.freeze({
|
|
71
188
|
name,
|
|
72
189
|
handles: roster.handles,
|
|
73
|
-
columns:
|
|
190
|
+
columns: cols,
|
|
74
191
|
rows: Object.freeze(rows)
|
|
75
192
|
});
|
|
76
193
|
const id = Object.freeze({
|
|
77
|
-
|
|
194
|
+
kind: "u64",
|
|
195
|
+
domain: `${name}Id`,
|
|
196
|
+
closed: roster
|
|
78
197
|
});
|
|
79
198
|
/**
|
|
80
199
|
* Handle names are arbitrary identifiers, so rows and constants are
|
|
81
|
-
* minted with OWN-property definition
|
|
200
|
+
* minted with OWN-property definition (inside {@link mintAxioms} and
|
|
201
|
+
* {@link mintHandleConstants}), never assignment: a handle named
|
|
82
202
|
* "__proto__" would otherwise ride the Object.prototype accessor —
|
|
83
203
|
* silently swapping the record's prototype instead of creating the row,
|
|
84
204
|
* and no-oping the constant (a primitive through the setter) — minting a
|
|
85
|
-
* value whose type claims
|
|
205
|
+
* value whose type claims a bigint constant but reads back an object.
|
|
206
|
+
* (Object SPREAD is CreateDataProperty by spec, so the copies below are
|
|
207
|
+
* own-property safe for column names too.)
|
|
86
208
|
*/
|
|
87
|
-
const axiomsOut =
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
209
|
+
const axiomsOut = mintAxioms(name, handleList, cols, axioms);
|
|
210
|
+
const constants = mintHandleConstants(name, handleList);
|
|
211
|
+
const columnsOut = { ...columns };
|
|
212
|
+
Object.freeze(columnsOut);
|
|
213
|
+
return Object.freeze({
|
|
214
|
+
...constants,
|
|
93
215
|
name,
|
|
94
216
|
id,
|
|
95
217
|
data,
|
|
96
|
-
axioms:
|
|
218
|
+
axioms: axiomsOut,
|
|
219
|
+
columns: columnsOut,
|
|
97
220
|
fromId(idValue) {
|
|
98
|
-
return
|
|
221
|
+
return handleList[Number(idValue)];
|
|
99
222
|
}
|
|
100
|
-
};
|
|
101
|
-
handles.forEach(function mintHandleConstant(handle, index) {
|
|
102
|
-
Object.defineProperty(value, handle, { value: BigInt(index), enumerable: true });
|
|
103
223
|
});
|
|
104
|
-
return Object.freeze(value);
|
|
105
224
|
}
|
|
106
225
|
export { closed };
|
|
107
226
|
//# sourceMappingURL=closed.js.map
|
package/dist/closed.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"closed.js","sourceRoot":"","sources":["../src/closed.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"closed.js","sourceRoot":"","sources":["../src/closed.ts"],"names":[],"mappings":"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"}
|
package/dist/count.d.ts
CHANGED
|
@@ -1,10 +1,22 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Cardinality-window counts — exactly five constructors, and nothing else
|
|
3
|
-
* (`docs/architecture/70-api.md` § the canonical-utterance law). The
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
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
|
+
*
|
|
8
20
|
* Bounds are `bigint` (u64 crosses as bigint always, PRD-04's law).
|
|
9
21
|
*/
|
|
10
22
|
import type { WindowSpec } from "#spec.ts";
|
|
@@ -26,30 +38,65 @@ interface Count {
|
|
|
26
38
|
readonly window: WindowSpec;
|
|
27
39
|
readonly [admitted]: true;
|
|
28
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>;
|
|
29
69
|
/**
|
|
30
70
|
* `{n}` — THE exact-count spelling, n ≥ 1. `exactly(0)` is the exclusion
|
|
31
|
-
* respelled
|
|
71
|
+
* respelled: unwritable as a literal ({@link ExactlyBan} names `none`),
|
|
72
|
+
* rejected at construction when computed.
|
|
32
73
|
*/
|
|
33
|
-
declare function exactly(n:
|
|
74
|
+
declare function exactly<const N extends bigint>(n: N & ExactlyBan<N>): Count;
|
|
34
75
|
/** `{0}` — the exclusion: no source fact may pair with the target group. */
|
|
35
76
|
declare const none: Count;
|
|
36
77
|
/**
|
|
37
|
-
* `{lo..hi}` — both bounds explicit,
|
|
38
|
-
* count respelled
|
|
39
|
-
*
|
|
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).
|
|
40
85
|
*/
|
|
41
|
-
declare function between(lo:
|
|
86
|
+
declare function between<const Lo extends bigint, const Hi extends bigint>(lo: Lo, hi: Hi & BetweenBan<Lo, Hi>): Count;
|
|
42
87
|
/**
|
|
43
88
|
* `{lo..*}` — a floor with no ceiling, lo ≥ 2: `atLeast(1)` says only what
|
|
44
|
-
* the bare containment says
|
|
45
|
-
*
|
|
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.
|
|
46
92
|
*/
|
|
47
|
-
declare function atLeast(lo:
|
|
93
|
+
declare function atLeast<const N extends bigint>(lo: N & AtLeastBan<N>): Count;
|
|
48
94
|
/**
|
|
49
|
-
* `{0..hi}` — a ceiling, hi ≥ 1: `atMost(0)` is the exclusion respelled
|
|
50
|
-
*
|
|
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.
|
|
51
98
|
*/
|
|
52
|
-
declare function atMost(hi:
|
|
99
|
+
declare function atMost<const N extends bigint>(hi: N & AtMostBan<N>): Count;
|
|
53
100
|
export type { Count };
|
|
54
101
|
export { atLeast, atMost, between, exactly, none };
|
|
55
102
|
//# sourceMappingURL=count.d.ts.map
|
package/dist/count.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"count.d.ts","sourceRoot":"","sources":["../src/count.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"count.d.ts","sourceRoot":"","sources":["../src/count.ts"],"names":[],"mappings":"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"}
|