@bjornpagen/bumbledb 0.2.0 → 0.3.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 +462 -406
- package/README.md +66 -31
- package/dist/closed.d.ts +121 -25
- package/dist/closed.d.ts.map +1 -1
- package/dist/closed.js +108 -42
- package/dist/closed.js.map +1 -1
- package/dist/db.d.ts +12 -1
- package/dist/db.d.ts.map +1 -1
- package/dist/db.js +20 -5
- package/dist/db.js.map +1 -1
- package/dist/face.d.ts +100 -55
- package/dist/face.d.ts.map +1 -1
- package/dist/face.js +36 -10
- package/dist/face.js.map +1 -1
- package/dist/fields.d.ts +50 -79
- package/dist/fields.d.ts.map +1 -1
- package/dist/fields.js +20 -53
- package/dist/fields.js.map +1 -1
- package/dist/index.d.ts +17 -12
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +10 -6
- 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/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 +88 -50
- package/dist/query/atom.d.ts.map +1 -1
- package/dist/query/atom.js +4 -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 +90 -43
- 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/scope.d.ts +76 -41
- package/dist/query/scope.d.ts.map +1 -1
- package/dist/query/scope.js +77 -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 +21 -8
- package/dist/relation.d.ts.map +1 -1
- package/dist/relation.js +13 -7
- 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 +7 -6
- package/dist/spec.d.ts.map +1 -1
- package/dist/spec.js.map +1 -1
- package/dist/statements.d.ts +61 -31
- package/dist/statements.d.ts.map +1 -1
- package/dist/statements.js +22 -17
- package/dist/statements.js.map +1 -1
- package/package.json +2 -2
- package/src/closed.ts +243 -68
- package/src/db.ts +23 -5
- package/src/face.ts +162 -84
- package/src/fields.ts +57 -136
- package/src/index.ts +42 -16
- package/src/law.ts +519 -0
- package/src/lower.ts +36 -23
- package/src/native.ts +6 -2
- package/src/query/atom.ts +105 -58
- package/src/query/lower.ts +271 -139
- package/src/query/predicate.ts +43 -33
- package/src/query/scope.ts +125 -49
- package/src/query/select.ts +5 -5
- package/src/relation.ts +15 -9
- package/src/schema.ts +48 -7
- package/src/spec.ts +7 -6
- package/src/statements.ts +83 -43
package/README.md
CHANGED
|
@@ -4,6 +4,8 @@ Type-theoretic TypeScript SDK for the [bumbledb](https://github.com/bjornpagen/b
|
|
|
4
4
|
|
|
5
5
|
bumbledb models data as relations judged by statements (functionality, containment, cardinality) and queried with Datalog expressed as plain values — no SQL, no query-string parser. The SDK is a thin, fully typed surface over an in-process native engine (LMDB storage, MVCC snapshots, a single-writer witnessed write loop).
|
|
6
6
|
|
|
7
|
+
The surface is structural to the bone. Relation declarations are pure structure — kind, width, element, fresh, nothing else — and domains are never declared anywhere: **the laws type the columns**. `schema()` computes every field's equivalence class from the statement list itself, so the containments and mirrors you already write ARE the typing, at compile time and again at construction. Values stay bare (`bigint`, `string`, …); identity lives in the class the laws compute, not in a wrapper.
|
|
8
|
+
|
|
7
9
|
> **Research-grade, one platform.** This is a `0.x` release of an embedded engine under active development. It targets a single platform today (below), the API is not yet frozen across `0.x`, and the FFI ABI is pinned exactly per version. Treat it as an early adopter's tool, not a production datastore.
|
|
8
10
|
|
|
9
11
|
## Platform support
|
|
@@ -18,32 +20,47 @@ pnpm add @bjornpagen/bumbledb
|
|
|
18
20
|
|
|
19
21
|
## Quick start
|
|
20
22
|
|
|
21
|
-
Declare
|
|
22
|
-
|
|
23
|
-
|
|
23
|
+
Declare relations as pure structure, let the statement list type every column,
|
|
24
|
+
write facts through a transaction, and query with Datalog as values.
|
|
25
|
+
Everything is typed end to end — bare structural values in law-computed
|
|
26
|
+
classes, inferred query rows, and rejections that arrive as data rather than
|
|
27
|
+
exceptions.
|
|
24
28
|
|
|
25
29
|
```ts
|
|
26
|
-
import {
|
|
27
|
-
|
|
28
|
-
//
|
|
29
|
-
const
|
|
30
|
-
|
|
30
|
+
import { bool, closed, contained, Db, gt, key, on, query, relation, schema, u64 } from "@bjornpagen/bumbledb"
|
|
31
|
+
|
|
32
|
+
// A closed relation: a sealed roster of axioms with typed payload columns.
|
|
33
|
+
const Kind = closed(
|
|
34
|
+
"Kind",
|
|
35
|
+
{ mastered: bool, rank: u64 },
|
|
36
|
+
{
|
|
37
|
+
DirectPass: { mastered: true, rank: 30n },
|
|
38
|
+
JudgedPass: { mastered: true, rank: 20n },
|
|
39
|
+
Failed: { mastered: false, rank: 10n }
|
|
40
|
+
}
|
|
41
|
+
)
|
|
31
42
|
|
|
32
|
-
// Relations
|
|
33
|
-
|
|
34
|
-
const
|
|
43
|
+
// Relations are pure structure — no domain is declared anywhere.
|
|
44
|
+
// `u64.fresh` marks an engine-minted primary key.
|
|
45
|
+
const Attempt = relation("Attempt", { id: u64.fresh, kind: Kind.id })
|
|
46
|
+
const Certificate = relation("Certificate", { attempt: u64, kind: Kind.id })
|
|
35
47
|
|
|
36
|
-
//
|
|
37
|
-
|
|
48
|
+
// THE LAWS TYPE THE COLUMNS: schema() computes every field's class FROM this
|
|
49
|
+
// statement list — the containments are the typing. The last statement uses
|
|
50
|
+
// ψ-selection: a certificate may only ever cite a mastered kind.
|
|
51
|
+
const Review = schema("Review", { Kind, Attempt, Certificate }, [
|
|
52
|
+
contained(on(Attempt, "kind"), on(Kind, "id")),
|
|
53
|
+
key(Certificate, ["attempt"]),
|
|
54
|
+
contained(on(Certificate, "attempt"), on(Attempt, "id")),
|
|
55
|
+
contained(on(Certificate, "kind"), on(Kind.where({ mastered: true }), "id"))
|
|
56
|
+
])
|
|
38
57
|
|
|
39
|
-
const db = await Db.create("./
|
|
58
|
+
const db = await Db.create("./review.db", Review)
|
|
40
59
|
|
|
41
60
|
// Write. The delta is judged against every statement at commit.
|
|
42
|
-
let adaId: Brand<bigint, "HolderId"> | undefined
|
|
43
61
|
const result = db.write((tx) => {
|
|
44
|
-
const
|
|
45
|
-
|
|
46
|
-
tx.insert(Account, { holder: ada.id })
|
|
62
|
+
const attempt = tx.insert(Attempt, { kind: Kind.DirectPass }) // attempt.id minted, a bare bigint
|
|
63
|
+
tx.insert(Certificate, { attempt: attempt.id, kind: Kind.DirectPass })
|
|
47
64
|
})
|
|
48
65
|
|
|
49
66
|
// Rejection-as-data: no throw — a rejected commit is a typed value carrying
|
|
@@ -54,28 +71,46 @@ if (!result.ok) {
|
|
|
54
71
|
}
|
|
55
72
|
}
|
|
56
73
|
|
|
57
|
-
// Query: Datalog as values.
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
74
|
+
// Query: Datalog as values. Vars are named and typed by the class of their
|
|
75
|
+
// first binding; params are typed by use; rows are typed from the select.
|
|
76
|
+
// `gt` is one of the free comparison exports.
|
|
77
|
+
const certifiedAbove = query(Review).rule((r) => {
|
|
78
|
+
const { a, k, rank } = r.vars("a", "k", "rank")
|
|
79
|
+
return r
|
|
80
|
+
.match(Certificate, { attempt: a, kind: k })
|
|
81
|
+
.match(Kind, { id: k, mastered: true, rank }) // ψ on the read side too
|
|
82
|
+
.where(gt(rank, r.param("floor")))
|
|
83
|
+
.select("a", "rank")
|
|
62
84
|
})
|
|
63
85
|
|
|
64
|
-
const prepared = db.prepare(
|
|
65
|
-
const rows = db.execute(prepared, {
|
|
86
|
+
const prepared = db.prepare(certifiedAbove)
|
|
87
|
+
const rows = db.execute(prepared, { floor: 15n }) // rows: { a: bigint; rank: bigint }[]
|
|
88
|
+
console.log(rows)
|
|
89
|
+
|
|
90
|
+
// Host dispatch over the sealed roster — exhaustive by construction; each
|
|
91
|
+
// arm receives its axiom row.
|
|
92
|
+
const label = Kind.match(Kind.JudgedPass, {
|
|
93
|
+
DirectPass: (row) => `mastered, rank ${row.rank}`,
|
|
94
|
+
JudgedPass: (row) => `mastered, rank ${row.rank}`,
|
|
95
|
+
Failed: () => "not mastered"
|
|
96
|
+
})
|
|
97
|
+
console.log(label) // "mastered, rank 20"
|
|
66
98
|
```
|
|
67
99
|
|
|
100
|
+
Every `ts` fence in this README is extracted and type-checked against the
|
|
101
|
+
real surface by `test/readme.test.ts` — the examples cannot drift.
|
|
102
|
+
|
|
68
103
|
## Surface
|
|
69
104
|
|
|
70
|
-
- The type kernel —
|
|
71
|
-
- The statement algebra — `schema()`, `key`, `contained`, `mirrors`, `window`.
|
|
72
|
-
- The `Db` runtime — path-cached stores, transactions, typed violations, scoped snapshot reads, the witnessed write loop
|
|
73
|
-
- The query surface — Datalog as values
|
|
74
|
-
- The exhume surface — `Db.exhume`, the schema-independent read path: a store's self-described shapes and raw facts by name.
|
|
105
|
+
- The structural type kernel — fields as pure structure (`bool`, `bytes`, `i64`, `u64`, `str`, `interval`, `span`), `relation()`, and `closed()` sealed rosters with typed axiom payloads and exhaustive host dispatch via `.match`. Domains are never declared: `schema()` computes every field's class from the statement list.
|
|
106
|
+
- The statement algebra — `schema()`, `key`, `contained`, `mirrors`, `window`; faces via `on`/`oneOf`; counts via `exactly`, `atLeast`, `atMost`, `between`, `none`; ψ-selection via `.where` on relations and closed rosters.
|
|
107
|
+
- The `Db` runtime — `Db.create`/`Db.open`, path-cached stores, transactions, typed violations, scoped snapshot reads, the witnessed write loop with `abandon`.
|
|
108
|
+
- The query surface — Datalog as values, `query(S).rule(r => ...)`: named vars, params typed by use, negation, aggregates, and the free comparison/connective exports (`eq`, `ne`, `lt`, `le`, `gt`, `ge`, `and`, `or`, `not`, `allen`/`ALLEN`, `pointIn`, `covers`); stratified recursion via `program()`; `db.prepare` as a plain value.
|
|
109
|
+
- The exhume surface — `Db.exhume`, the schema-independent read path: a store's self-described shapes and raw facts by name, with typed refusals (`ErrExhumeNoDescriptor`, `ErrExhumeFormatMismatch`, `ErrExhumeCorruption`).
|
|
75
110
|
|
|
76
111
|
## Cookbook
|
|
77
112
|
|
|
78
|
-
The engine cookbook's 29 modeling recipes, translated to this SDK's structural API: [COOKBOOK.md](./COOKBOOK.md).
|
|
113
|
+
The engine cookbook's 29 modeling recipes, translated to this SDK's structural API: [COOKBOOK.md](./COOKBOOK.md). Two referees hold it: `test/cookbook-doc.test.ts` extracts the document's own `ts` fences and type-checks them against the real surface (the doc itself cannot drift), and `test/cookbook.test.ts` runs compiled copies of the recipes — each schema admitted by the real engine, its fingerprint asserted against the cross-host goldens the Rust cookbook suite also pins, every query snippet lowered through `db.prepare`.
|
|
79
114
|
|
|
80
115
|
## Architecture
|
|
81
116
|
|
package/dist/closed.d.ts
CHANGED
|
@@ -4,19 +4,31 @@
|
|
|
4
4
|
* tiers, one function. The emission per closed relation mirrors the
|
|
5
5
|
* macro's (host-enum analog): handle CONSTANTS on the value
|
|
6
6
|
* (`Kind.Checking`, ids = declaration order, each a BARE `bigint` — no
|
|
7
|
-
* brand), the `fromId` weld, an `id` field descriptor carrying the
|
|
8
|
-
*
|
|
7
|
+
* brand), the `fromId` weld, an `id` field descriptor carrying the CLOSED
|
|
8
|
+
* LINKAGE (the roster — pure structure, no declared domain: the laws type
|
|
9
|
+
* the columns, and `schema()` names the id's generator class `"Kind.id"`)
|
|
9
10
|
* for other relations' field blocks (`kind: Kind.id`), payload readback
|
|
10
11
|
* (`Kind.axioms`), and the declared payload column descriptors
|
|
11
12
|
* (`Kind.columns` — the runtime twin of the `Cols` type parameter, which
|
|
12
|
-
* the face layer's
|
|
13
|
-
* "Savings"])`. Payload tier: `closed("Sev", { pages: bool }
|
|
14
|
-
* { pages: true }, ... })` —
|
|
15
|
-
*
|
|
16
|
-
*
|
|
17
|
-
*
|
|
13
|
+
* the face layer's structural wall reads). Bare tier: `closed("Kind", ["Checking",
|
|
14
|
+
* "Savings"])`. Payload tier: `closed("Sev", { pages: bool }, { Critical:
|
|
15
|
+
* { pages: true }, ... })` — one call, three arguments (the curried tier-2
|
|
16
|
+
* spelling is DELETED — canonical utterance): the axioms record IS the
|
|
17
|
+
* handle declaration, every handle carrying every column exactly once
|
|
18
|
+
* (type-enforced). No fact type and no insert surface exist — closed
|
|
19
|
+
* relations are unwritable by construction: the value simply lacks the
|
|
20
|
+
* writable relation shape. Both tiers mint `match()` — exhaustive dispatch
|
|
21
|
+
* over the handle union (arms typed by the mapped type, so a missing or
|
|
22
|
+
* extra arm is a compile error; the payload tier's arm receives the typed
|
|
23
|
+
* axiom row). The payload tier additionally mints `where()` — the
|
|
24
|
+
* ψ-selection surface (`Kind.where({ mastered: true })` as a face source),
|
|
25
|
+
* resolved through the ONE selection machine
|
|
26
|
+
* (`relation.ts::resolveSelection`); the bare tier has no payload columns to
|
|
27
|
+
* select on, so `.where` is absent there, at the type AND on the value.
|
|
18
28
|
*/
|
|
29
|
+
import type { OneOf } from "#face.ts";
|
|
19
30
|
import { type AnyField, type ClosedIdField, type Infer } from "#fields.ts";
|
|
31
|
+
import { type SelectionBinding } from "#relation.ts";
|
|
20
32
|
import type { LiteralSpec } from "#spec.ts";
|
|
21
33
|
/**
|
|
22
34
|
* A payload column of a closed relation: any field descriptor except a
|
|
@@ -25,6 +37,19 @@ import type { LiteralSpec } from "#spec.ts";
|
|
|
25
37
|
type PayloadField = Exclude<AnyField, {
|
|
26
38
|
readonly fresh: true;
|
|
27
39
|
}>;
|
|
40
|
+
/**
|
|
41
|
+
* A declared payload column BLOCK: name → descriptor, with `id`
|
|
42
|
+
* unspellable — the sealed shape mints the synthetic `id` itself (ordinal
|
|
43
|
+
* 0 of the matchable fields), so a declared column named `id` would be
|
|
44
|
+
* shadowed by the synthetic slot everywhere the shape resolves by name
|
|
45
|
+
* (`matchFieldsOf`, the projected face, `spec.rs`'s resolver). The wall is
|
|
46
|
+
* typed here and judged again at construction in {@link mintClosed} — the
|
|
47
|
+
* runtime twin for untyped callers, warmer and earlier than the engine's
|
|
48
|
+
* `DuplicateFieldName` at `Db.create`.
|
|
49
|
+
*/
|
|
50
|
+
type PayloadColumns = Record<string, PayloadField> & {
|
|
51
|
+
readonly id?: never;
|
|
52
|
+
};
|
|
28
53
|
/** One declared payload column: name plus its field descriptor. */
|
|
29
54
|
interface ClosedColumn {
|
|
30
55
|
readonly name: string;
|
|
@@ -67,36 +92,102 @@ type Axioms<Handles extends string, Cols extends Record<string, PayloadField>> =
|
|
|
67
92
|
interface ClosedCore<Name extends string, Handles extends string, Cols extends Record<string, PayloadField>> {
|
|
68
93
|
readonly name: Name;
|
|
69
94
|
/**
|
|
70
|
-
* The
|
|
71
|
-
*
|
|
72
|
-
*
|
|
73
|
-
*
|
|
95
|
+
* The closed reference descriptor: `kind: Kind.id` in another relation's
|
|
96
|
+
* field block is the reference through which bare handle ids become
|
|
97
|
+
* legal in that relation's selections. Pure structure plus the roster —
|
|
98
|
+
* the referencing field's domain is law-born: `schema()` computes it
|
|
99
|
+
* from the declared containment (`"Kind.id"`, the generator class).
|
|
74
100
|
*/
|
|
75
|
-
readonly id: ClosedIdField
|
|
101
|
+
readonly id: ClosedIdField;
|
|
76
102
|
readonly data: ClosedData;
|
|
77
103
|
/** Payload readback: handle to its declared column values, bare and structural. */
|
|
78
104
|
readonly axioms: Axioms<Handles, Cols>;
|
|
79
105
|
/**
|
|
80
|
-
* The declared payload columns, name →
|
|
106
|
+
* The declared payload columns, name → field descriptor — an HONEST
|
|
81
107
|
* frozen runtime record (the descriptors themselves, by identity), and
|
|
82
|
-
* the typed carrier a projected payload column's
|
|
108
|
+
* the typed carrier a projected payload column's structural shape is
|
|
83
109
|
* recovered through off the schema type (the face layer's
|
|
84
|
-
* `
|
|
110
|
+
* `ProjectedShape` reads it; `data.columns` carries the same
|
|
85
111
|
* descriptors in declaration order for the lowering).
|
|
86
112
|
*/
|
|
87
113
|
readonly columns: Cols;
|
|
88
114
|
/** The weld: declaration-order id back to its handle, or undefined beyond the roster. */
|
|
89
115
|
fromId(id: bigint): Handles | undefined;
|
|
90
116
|
}
|
|
117
|
+
/**
|
|
118
|
+
* The `where()` argument of a closed relation: per PAYLOAD column, a bare
|
|
119
|
+
* structural literal of that column's value type or an `oneOf(a, b, ...)`
|
|
120
|
+
* literal set — the ordinary `where()`'s vocabulary exactly. The synthetic
|
|
121
|
+
* `id` is deliberately absent: an id selection is spelled only as handle
|
|
122
|
+
* literals on the REFERENCING side (the canonical-utterance law).
|
|
123
|
+
*/
|
|
124
|
+
type ClosedSelectionInput<Cols extends Record<string, PayloadField>> = {
|
|
125
|
+
readonly [C in keyof Cols]?: Infer<Cols[C]> | OneOf<Infer<Cols[C]>>;
|
|
126
|
+
};
|
|
127
|
+
/**
|
|
128
|
+
* A closed relation with a ψ selection applied — what `on()` consumes as a
|
|
129
|
+
* σ-carrying closed source (`on(Kind.where({ mastered: true }), "id")`).
|
|
130
|
+
* Deliberately the SAME discriminant shape as the ordinary `Selected`
|
|
131
|
+
* (`relation`/`selection` — `face.ts::faceParts` splits both by `"relation"
|
|
132
|
+
* in source`), and structurally UNMISTAKABLE for one: an `AnyClosed` lacks
|
|
133
|
+
* the relation shape (no `fields` record, no `RelationData`).
|
|
134
|
+
*/
|
|
135
|
+
interface SelectedClosed<Name extends string, Handles extends string, Cols extends Record<string, PayloadField>> {
|
|
136
|
+
readonly relation: Closed<Name, Handles, Cols>;
|
|
137
|
+
readonly selection: readonly SelectionBinding[];
|
|
138
|
+
}
|
|
139
|
+
/** Any ψ-selected closed relation value. */
|
|
140
|
+
interface AnySelectedClosed {
|
|
141
|
+
readonly relation: AnyClosed;
|
|
142
|
+
readonly selection: readonly SelectionBinding[];
|
|
143
|
+
}
|
|
144
|
+
/**
|
|
145
|
+
* The ψ-selection surface of a payload-tier closed value. The selection is
|
|
146
|
+
* resolved EAGERLY against the declared columns and lowered as-is — the SDK
|
|
147
|
+
* never pre-folds ψ into an id set: pass-through lowering is what the macro
|
|
148
|
+
* does, and the ENGINE folds against the sealed extension at validate
|
|
149
|
+
* (`compile_member_set`).
|
|
150
|
+
*/
|
|
151
|
+
interface ClosedSelectable<Name extends string, Handles extends string, Cols extends Record<string, PayloadField>> {
|
|
152
|
+
where(selection: ClosedSelectionInput<Cols>): SelectedClosed<Name, Handles, Cols>;
|
|
153
|
+
}
|
|
154
|
+
/**
|
|
155
|
+
* Exhaustive dispatch over a BARE closed vocabulary: one arm per handle,
|
|
156
|
+
* no literal types and no brands — the handle-name union on the value's
|
|
157
|
+
* type IS the exhaustiveness proof (a missing arm is a missing-property
|
|
158
|
+
* compile error; an extra arm an excess-property compile error). The bare
|
|
159
|
+
* tier declares no payload, so an arm takes nothing. The arms record types
|
|
160
|
+
* any `bigint` in — the runtime roster refuses an out-of-vocabulary id
|
|
161
|
+
* with a throw, never a misdispatch.
|
|
162
|
+
*/
|
|
163
|
+
interface ClosedMatchBare<Handles extends string> {
|
|
164
|
+
match<T>(id: bigint, arms: {
|
|
165
|
+
readonly [H in Handles]: () => T;
|
|
166
|
+
}): T;
|
|
167
|
+
}
|
|
168
|
+
/**
|
|
169
|
+
* Exhaustive dispatch over a PAYLOAD-tier closed vocabulary: the same
|
|
170
|
+
* mapped-type exhaustiveness as the bare tier, and each arm receives its
|
|
171
|
+
* handle's typed axiom row (the declared columns, bare and structural —
|
|
172
|
+
* the frozen readback row from `axioms`).
|
|
173
|
+
*/
|
|
174
|
+
interface ClosedMatchPayload<Handles extends string, Cols extends Record<string, PayloadField>> {
|
|
175
|
+
match<T>(id: bigint, arms: {
|
|
176
|
+
readonly [H in Handles]: (row: AxiomRow<Cols>) => T;
|
|
177
|
+
}): T;
|
|
178
|
+
}
|
|
91
179
|
/**
|
|
92
180
|
* A closed relation value: the core surface plus one BARE constant per
|
|
93
181
|
* handle (`Kind.Checking: bigint`, ids = declaration order — the value is
|
|
94
182
|
* structural; the roster judges out-of-vocabulary ids at construction and
|
|
95
|
-
* the engine at commit)
|
|
183
|
+
* the engine at commit), plus `match()` on BOTH tiers (bare arms take
|
|
184
|
+
* nothing; payload arms receive the typed axiom row), plus — exactly when
|
|
185
|
+
* payload columns exist — `where()` (the bare tier has nothing to select
|
|
186
|
+
* on, so the method is ABSENT there, not merely uncallable).
|
|
96
187
|
*/
|
|
97
188
|
type Closed<Name extends string, Handles extends string, Cols extends Record<string, PayloadField>> = ClosedCore<Name, Handles, Cols> & {
|
|
98
189
|
readonly [H in Handles]: bigint;
|
|
99
|
-
};
|
|
190
|
+
} & ([keyof Cols] extends [never] ? ClosedMatchBare<Handles> : ClosedSelectable<Name, Handles, Cols> & ClosedMatchPayload<Handles, Cols>);
|
|
100
191
|
/** Any closed relation value, whatever its roster and columns. */
|
|
101
192
|
interface AnyClosed {
|
|
102
193
|
readonly name: string;
|
|
@@ -108,13 +199,18 @@ interface AnyClosed {
|
|
|
108
199
|
/** Bare tier: `closed("Kind", ["Checking", "Savings"])` — handles only. */
|
|
109
200
|
declare function closed<const Name extends string, const Handles extends readonly [string, ...string[]]>(name: Name, handles: Handles): Closed<Name, Handles[number], Record<never, never>>;
|
|
110
201
|
/**
|
|
111
|
-
* Payload tier: declared columns
|
|
112
|
-
* { mastered: bool }
|
|
113
|
-
* false } })`. The
|
|
114
|
-
*
|
|
115
|
-
*
|
|
202
|
+
* Payload tier: declared columns AND ground axioms, one call — `closed(
|
|
203
|
+
* "Grade", { mastered: bool }, { DirectPass: { mastered: true }, Failed:
|
|
204
|
+
* { mastered: false } })`. The curried tier-2 spelling is DELETED
|
|
205
|
+
* (canonical utterance): `Cols` infers from the column block, the handle
|
|
206
|
+
* set from the axioms record's keys (reverse mapped-type inference), and
|
|
207
|
+
* every row is contextually checked against the declared columns — a
|
|
208
|
+
* wrong-typed value errors ON its property. The axioms record's keys ARE
|
|
209
|
+
* the handles (declaration order = key order, integer-index names
|
|
210
|
+
* rejected); every row carries every column exactly once (type-enforced by
|
|
211
|
+
* {@link Axioms}).
|
|
116
212
|
*/
|
|
117
|
-
declare function closed<const Name extends string, const Cols extends
|
|
118
|
-
export type { AnyClosed, AxiomRow, Axioms, Closed, ClosedColumn, ClosedCore, ClosedData, ClosedRow, PayloadField };
|
|
213
|
+
declare function closed<const Name extends string, const Cols extends PayloadColumns, Handles extends string>(name: Name, columns: Cols, axioms: Axioms<Handles, Cols>): Closed<Name, Handles, Cols>;
|
|
214
|
+
export type { AnyClosed, AnySelectedClosed, AxiomRow, Axioms, Closed, ClosedColumn, ClosedCore, ClosedData, ClosedRow, ClosedSelectionInput, PayloadField, SelectedClosed };
|
|
119
215
|
export { closed };
|
|
120
216
|
//# 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
|
@@ -4,25 +4,39 @@
|
|
|
4
4
|
* tiers, one function. The emission per closed relation mirrors the
|
|
5
5
|
* macro's (host-enum analog): handle CONSTANTS on the value
|
|
6
6
|
* (`Kind.Checking`, ids = declaration order, each a BARE `bigint` — no
|
|
7
|
-
* brand), the `fromId` weld, an `id` field descriptor carrying the
|
|
8
|
-
*
|
|
7
|
+
* brand), the `fromId` weld, an `id` field descriptor carrying the CLOSED
|
|
8
|
+
* LINKAGE (the roster — pure structure, no declared domain: the laws type
|
|
9
|
+
* the columns, and `schema()` names the id's generator class `"Kind.id"`)
|
|
9
10
|
* for other relations' field blocks (`kind: Kind.id`), payload readback
|
|
10
11
|
* (`Kind.axioms`), and the declared payload column descriptors
|
|
11
12
|
* (`Kind.columns` — the runtime twin of the `Cols` type parameter, which
|
|
12
|
-
* the face layer's
|
|
13
|
-
* "Savings"])`. Payload tier: `closed("Sev", { pages: bool }
|
|
14
|
-
* { pages: true }, ... })` —
|
|
15
|
-
*
|
|
16
|
-
*
|
|
17
|
-
*
|
|
13
|
+
* the face layer's structural wall reads). Bare tier: `closed("Kind", ["Checking",
|
|
14
|
+
* "Savings"])`. Payload tier: `closed("Sev", { pages: bool }, { Critical:
|
|
15
|
+
* { pages: true }, ... })` — one call, three arguments (the curried tier-2
|
|
16
|
+
* spelling is DELETED — canonical utterance): the axioms record IS the
|
|
17
|
+
* handle declaration, every handle carrying every column exactly once
|
|
18
|
+
* (type-enforced). No fact type and no insert surface exist — closed
|
|
19
|
+
* relations are unwritable by construction: the value simply lacks the
|
|
20
|
+
* writable relation shape. Both tiers mint `match()` — exhaustive dispatch
|
|
21
|
+
* over the handle union (arms typed by the mapped type, so a missing or
|
|
22
|
+
* extra arm is a compile error; the payload tier's arm receives the typed
|
|
23
|
+
* axiom row). The payload tier additionally mints `where()` — the
|
|
24
|
+
* ψ-selection surface (`Kind.where({ mastered: true })` as a face source),
|
|
25
|
+
* resolved through the ONE selection machine
|
|
26
|
+
* (`relation.ts::resolveSelection`); the bare tier has no payload columns to
|
|
27
|
+
* select on, so `.where` is absent there, at the type AND on the value.
|
|
18
28
|
*/
|
|
19
29
|
import * as errors from "@superbuilders/errors";
|
|
20
30
|
import { assertDeclarationOrderKey, literalOf } from "#fields.ts";
|
|
31
|
+
import { resolveSelection } from "#relation.ts";
|
|
21
32
|
/**
|
|
22
33
|
* The value-surface property names a handle may not shadow — the macro's
|
|
23
34
|
* name-collision diagnostic, here over the closed value's own properties
|
|
24
35
|
* (`relation`/`selection` are reserved so a closed value can never be
|
|
25
|
-
* mistaken for a selected relation by `on()`'s discriminant
|
|
36
|
+
* mistaken for a selected relation by `on()`'s discriminant; `where` is
|
|
37
|
+
* reserved because the payload tier mints the ψ-selection method under
|
|
38
|
+
* exactly that name; `match` because BOTH tiers mint the exhaustive
|
|
39
|
+
* dispatch under exactly that name).
|
|
26
40
|
*/
|
|
27
41
|
const reservedHandleNames = Object.freeze([
|
|
28
42
|
"name",
|
|
@@ -31,6 +45,8 @@ const reservedHandleNames = Object.freeze([
|
|
|
31
45
|
"axioms",
|
|
32
46
|
"columns",
|
|
33
47
|
"fromId",
|
|
48
|
+
"where",
|
|
49
|
+
"match",
|
|
34
50
|
"relation",
|
|
35
51
|
"selection"
|
|
36
52
|
]);
|
|
@@ -117,11 +133,17 @@ function mintHandleConstants(name, handles) {
|
|
|
117
133
|
}
|
|
118
134
|
return out;
|
|
119
135
|
}
|
|
120
|
-
function closed(name, shape) {
|
|
136
|
+
function closed(name, shape, axioms) {
|
|
121
137
|
if (isHandleTuple(shape)) {
|
|
138
|
+
if (axioms !== undefined) {
|
|
139
|
+
throw errors.new(`closed relation ${name}: the bare tier declares no columns, so ground axioms are inadmissible`);
|
|
140
|
+
}
|
|
122
141
|
return closedBare(name, shape);
|
|
123
142
|
}
|
|
124
|
-
|
|
143
|
+
if (axioms === undefined) {
|
|
144
|
+
throw errors.new(`closed relation ${name}: payload columns declared without ground axioms — the payload tier is spelled closed(name, columns, axioms) (the curried spelling is deleted)`);
|
|
145
|
+
}
|
|
146
|
+
return closedPayload(name, shape, axioms);
|
|
125
147
|
}
|
|
126
148
|
/** The bare tier's precisely-typed builder: no columns, no axioms. */
|
|
127
149
|
function closedBare(name, handles) {
|
|
@@ -129,31 +151,42 @@ function closedBare(name, handles) {
|
|
|
129
151
|
}
|
|
130
152
|
/**
|
|
131
153
|
* The payload tier's precisely-typed builder: column names are judged
|
|
132
|
-
*
|
|
133
|
-
*
|
|
134
|
-
* set off the axioms record's own keys.
|
|
154
|
+
* first (the macro-expansion analog), then the handle set is read off the
|
|
155
|
+
* axioms record's own keys.
|
|
135
156
|
*/
|
|
136
|
-
function closedPayload(name, columns) {
|
|
157
|
+
function closedPayload(name, columns, axioms) {
|
|
137
158
|
for (const columnName of Object.keys(columns)) {
|
|
138
159
|
assertDeclarationOrderKey(`closed relation ${name} column`, columnName);
|
|
139
160
|
}
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
161
|
+
const handles = Object.keys(axioms);
|
|
162
|
+
for (const handle of handles) {
|
|
163
|
+
assertDeclarationOrderKey(`closed relation ${name} handle`, handle);
|
|
164
|
+
}
|
|
165
|
+
if (!handleKeysOwn(axioms, handles)) {
|
|
166
|
+
throw errors.new(`closed relation ${name}: handle enumeration incomplete`);
|
|
167
|
+
}
|
|
168
|
+
return mintClosed(name, handles, columns, axioms);
|
|
169
|
+
}
|
|
170
|
+
/**
|
|
171
|
+
* The trusted seam of the ergonomic-surface mint: `match` reads back as an
|
|
172
|
+
* own function on BOTH tiers, and `where` exactly when payload columns
|
|
173
|
+
* exist — the runtime twin of the {@link Closed} type's conditional arm
|
|
174
|
+
* (`ClosedMatchBare` vs `ClosedSelectable & ClosedMatchPayload`), verified
|
|
175
|
+
* before the minted value is admitted at the conditional type.
|
|
176
|
+
*/
|
|
177
|
+
function surfaceMinted(value, cols) {
|
|
178
|
+
const matchable = "match" in value && typeof value.match === "function";
|
|
179
|
+
const selectable = "where" in value && typeof value.where === "function";
|
|
180
|
+
return matchable && (cols.length > 0 ? selectable : !selectable);
|
|
150
181
|
}
|
|
151
182
|
/**
|
|
152
183
|
* Mints one closed relation value — the shared seam of both tiers, HONESTLY
|
|
153
184
|
* typed end to end (a wrong-shaped mint is a compile error here, not a
|
|
154
185
|
* laundered `unknown`): roster checks, eager axiom lowering, the
|
|
155
|
-
*
|
|
156
|
-
* twin of the `Cols` type parameter),
|
|
186
|
+
* roster-carrying `id` descriptor, the frozen `columns` carrier (the runtime
|
|
187
|
+
* twin of the `Cols` type parameter), the handle constants, the exhaustive
|
|
188
|
+
* `match()` on both tiers, and — on the payload tier only — the
|
|
189
|
+
* ψ-selection `where()`.
|
|
157
190
|
*/
|
|
158
191
|
function mintClosed(name, handles, columns, axioms) {
|
|
159
192
|
if (handles.length === 0) {
|
|
@@ -174,6 +207,9 @@ function mintClosed(name, handles, columns, axioms) {
|
|
|
174
207
|
const cols = [];
|
|
175
208
|
for (const [columnName, field] of Object.entries(columns)) {
|
|
176
209
|
assertDeclarationOrderKey(`closed relation ${name} column`, columnName);
|
|
210
|
+
if (columnName === "id") {
|
|
211
|
+
throw errors.new(`closed relation ${name}: the payload column id collides with the sealed shape's synthetic id (the relation mints its own id at ordinal 0; name the column something else)`);
|
|
212
|
+
}
|
|
177
213
|
cols.push(Object.freeze({ name: columnName, field }));
|
|
178
214
|
}
|
|
179
215
|
Object.freeze(cols);
|
|
@@ -190,11 +226,7 @@ function mintClosed(name, handles, columns, axioms) {
|
|
|
190
226
|
columns: cols,
|
|
191
227
|
rows: Object.freeze(rows)
|
|
192
228
|
});
|
|
193
|
-
const id = Object.freeze({
|
|
194
|
-
kind: "u64",
|
|
195
|
-
domain: `${name}Id`,
|
|
196
|
-
closed: roster
|
|
197
|
-
});
|
|
229
|
+
const id = Object.freeze({ kind: "u64", closed: roster });
|
|
198
230
|
/**
|
|
199
231
|
* Handle names are arbitrary identifiers, so rows and constants are
|
|
200
232
|
* minted with OWN-property definition (inside {@link mintAxioms} and
|
|
@@ -210,17 +242,51 @@ function mintClosed(name, handles, columns, axioms) {
|
|
|
210
242
|
const constants = mintHandleConstants(name, handleList);
|
|
211
243
|
const columnsOut = { ...columns };
|
|
212
244
|
Object.freeze(columnsOut);
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
245
|
+
function fromId(idValue) {
|
|
246
|
+
return handleList[Number(idValue)];
|
|
247
|
+
}
|
|
248
|
+
const holder = { value: undefined };
|
|
249
|
+
/**
|
|
250
|
+
* The ψ selection: resolved against the declared payload columns through
|
|
251
|
+
* the ONE selection machine (`relation.ts::resolveSelection` — a
|
|
252
|
+
* `ClosedColumn` is structurally a `RelationField`), never pre-folded
|
|
253
|
+
* into an id set (the engine folds at validate).
|
|
254
|
+
*/
|
|
255
|
+
function where(selection) {
|
|
256
|
+
const owner = holder.value;
|
|
257
|
+
if (owner === undefined) {
|
|
258
|
+
throw errors.new(`closed relation ${name}: self-reference read before construction completed`);
|
|
222
259
|
}
|
|
223
|
-
|
|
260
|
+
return Object.freeze({
|
|
261
|
+
relation: owner,
|
|
262
|
+
selection: resolveSelection(name, cols, Object.entries(selection))
|
|
263
|
+
});
|
|
264
|
+
}
|
|
265
|
+
/**
|
|
266
|
+
* The exhaustive dispatch: the ROSTER judges the id (the structural type
|
|
267
|
+
* admits any bigint — a dishonest id is a THROW, never a misdispatch),
|
|
268
|
+
* and the chosen arm receives the handle's frozen axiom row (the bare
|
|
269
|
+
* tier's arms are typed to take nothing; the empty row rides along
|
|
270
|
+
* unread). One implementation serves both tiers — the conditional
|
|
271
|
+
* {@link Closed} arm claims the tier-exact arm signature and
|
|
272
|
+
* {@link surfaceMinted} is the trusted seam that admits it.
|
|
273
|
+
*/
|
|
274
|
+
function match(idValue, arms) {
|
|
275
|
+
const handle = fromId(idValue);
|
|
276
|
+
if (handle === undefined) {
|
|
277
|
+
throw errors.new(`closed relation ${name}: match on id ${idValue} misses the roster (${handleList.join(", ")})`);
|
|
278
|
+
}
|
|
279
|
+
return arms[handle](axiomsOut[handle]);
|
|
280
|
+
}
|
|
281
|
+
const core = { name, id, data, axioms: axiomsOut, columns: columnsOut, fromId };
|
|
282
|
+
const value = cols.length > 0
|
|
283
|
+
? Object.freeze({ ...constants, ...core, where, match })
|
|
284
|
+
: Object.freeze({ ...constants, ...core, match });
|
|
285
|
+
if (!surfaceMinted(value, cols)) {
|
|
286
|
+
throw errors.new(`closed relation ${name}: ergonomic-surface minting incomplete`);
|
|
287
|
+
}
|
|
288
|
+
holder.value = value;
|
|
289
|
+
return value;
|
|
224
290
|
}
|
|
225
291
|
export { closed };
|
|
226
292
|
//# 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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"}
|