@bjornpagen/bumbledb 0.12.0 → 0.14.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 +10 -8
- package/README.md +5 -4
- package/dist/capacity.d.ts +2 -2
- package/dist/closed.d.ts +4 -4
- package/dist/db.d.ts +109 -60
- package/dist/db.d.ts.map +1 -1
- package/dist/db.js +90 -71
- package/dist/db.js.map +1 -1
- package/dist/exhume.d.ts +2 -2
- package/dist/face.d.ts +3 -3
- package/dist/fields.d.ts +1 -1
- package/dist/index.d.ts +32 -32
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js.map +1 -1
- package/dist/law.d.ts +5 -5
- package/dist/lower.d.ts +5 -5
- package/dist/marshal.d.ts +8 -30
- package/dist/marshal.d.ts.map +1 -1
- package/dist/marshal.js +4 -21
- package/dist/marshal.js.map +1 -1
- package/dist/native.d.ts +38 -21
- package/dist/native.d.ts.map +1 -1
- package/dist/native.js.map +1 -1
- package/dist/query/atom.d.ts +4 -4
- package/dist/query/find.d.ts +18 -13
- package/dist/query/find.d.ts.map +1 -1
- package/dist/query/find.js +2 -2
- package/dist/query/find.js.map +1 -1
- package/dist/query/lower.d.ts +10 -10
- package/dist/query/lower.d.ts.map +1 -1
- package/dist/query/lower.js +5 -4
- package/dist/query/lower.js.map +1 -1
- package/dist/query/parse-ir.d.ts +1 -1
- package/dist/query/parse-ir.d.ts.map +1 -1
- package/dist/query/parse-ir.js +11 -9
- package/dist/query/parse-ir.js.map +1 -1
- package/dist/query/run.d.ts +3 -3
- package/dist/query/scope.d.ts +5 -5
- package/dist/relation.d.ts +6 -17
- package/dist/relation.d.ts.map +1 -1
- package/dist/relation.js +3 -4
- package/dist/relation.js.map +1 -1
- package/dist/schema.d.ts +4 -4
- package/dist/statements.d.ts +4 -4
- package/package.json +4 -3
- package/src/db.ts +248 -168
- package/src/index.ts +8 -2
- package/src/marshal.ts +5 -35
- package/src/native.ts +34 -16
- package/src/query/find.ts +19 -14
- package/src/query/lower.ts +7 -6
- package/src/query/parse-ir.ts +11 -9
- package/src/relation.ts +3 -15
package/COOKBOOK.md
CHANGED
|
@@ -1043,9 +1043,9 @@ const outcome = db.read(function attempt(snap) {
|
|
|
1043
1043
|
return abandon("nothing queued")
|
|
1044
1044
|
}
|
|
1045
1045
|
for (const row of queued) {
|
|
1046
|
-
tx.delete(Job, { id: row.id, state: "Queued", payload: row.payload })
|
|
1047
|
-
tx.insert(Job, { id: row.id, state: "Running", payload: row.payload })
|
|
1048
|
-
tx.insert(Lease, { job: row.id, worker: 7n, until: 60n })
|
|
1046
|
+
tx.delete(Job, [{ id: row.id, state: "Queued", payload: row.payload }])
|
|
1047
|
+
tx.insert(Job, [{ id: row.id, state: "Running", payload: row.payload }])
|
|
1048
|
+
tx.insert(Lease, [{ job: row.id, worker: 7n, until: 60n }])
|
|
1049
1049
|
}
|
|
1050
1050
|
return undefined
|
|
1051
1051
|
})
|
|
@@ -1599,9 +1599,11 @@ const db = await Db.create("./courses.db", KeyedRead)
|
|
|
1599
1599
|
|
|
1600
1600
|
const minted: { grp?: bigint } = {}
|
|
1601
1601
|
db.write((tx) => {
|
|
1602
|
-
const g = tx.
|
|
1603
|
-
tx.insert(
|
|
1604
|
-
|
|
1602
|
+
const g = tx.reserve(Grp, "id", 1n).at(0n)!
|
|
1603
|
+
tx.insert(Grp, [{ id: g, label: "algebra" }])
|
|
1604
|
+
const course = tx.reserve(Course, "id", 1n).at(0n)!
|
|
1605
|
+
tx.insert(Course, [{ id: course, grp: g, title: "linear equations" }])
|
|
1606
|
+
minted.grp = g
|
|
1605
1607
|
})
|
|
1606
1608
|
const grp = minted.grp ?? 0n
|
|
1607
1609
|
|
|
@@ -1616,8 +1618,8 @@ const viaSnap = db.read((snap) => snap.get(Course, courseGrpKey, { grp }))
|
|
|
1616
1618
|
db.write((tx) => {
|
|
1617
1619
|
const current = tx.get(Course, courseGrpKey, { grp })
|
|
1618
1620
|
if (current !== undefined) {
|
|
1619
|
-
tx.delete(Course, current)
|
|
1620
|
-
tx.insert(Course, { id: current.id, grp: current.grp, title: "linear equations II" })
|
|
1621
|
+
tx.delete(Course, [current])
|
|
1622
|
+
tx.insert(Course, [{ id: current.id, grp: current.grp, title: "linear equations II" }])
|
|
1621
1623
|
}
|
|
1622
1624
|
})
|
|
1623
1625
|
|
package/README.md
CHANGED
|
@@ -6,7 +6,7 @@ bumbledb models data as relations judged by statements (functionality, containme
|
|
|
6
6
|
|
|
7
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
8
|
|
|
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.
|
|
9
|
+
> **Research-grade, one platform.** This is **0.14.0**, 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 (`bdb_abi_version()` is **2** — collection insert/delete, `reserve`). Treat it as an early adopter's tool, not a production datastore.
|
|
10
10
|
|
|
11
11
|
## Platform support
|
|
12
12
|
|
|
@@ -63,8 +63,9 @@ const db = await Db.create("./review.db", Review)
|
|
|
63
63
|
// column takes the handle name — a wrong string is a compile error AND a
|
|
64
64
|
// marshal refusal.
|
|
65
65
|
const result = db.write((tx) => {
|
|
66
|
-
const
|
|
67
|
-
tx.insert(
|
|
66
|
+
const id = tx.reserve(Attempt, "id", 1n).at(0n)!
|
|
67
|
+
tx.insert(Attempt, [{ id, kind: "DirectPass" }])
|
|
68
|
+
tx.insert(Certificate, [{ attempt: id, kind: "DirectPass" }])
|
|
68
69
|
})
|
|
69
70
|
|
|
70
71
|
// Rejection-as-data: no throw — a rejected commit is a typed value carrying
|
|
@@ -128,7 +129,7 @@ The drizzle law governs this surface: the SDK's job at the host boundary is tran
|
|
|
128
129
|
|
|
129
130
|
- The structural type kernel — fields as pure structure (`bool`, `bytes`, `i64`, `u64`, `str`, `interval`, `span`), `relation()`, and `closed()` sealed rosters with typed axiom payloads. A closed reference's value type IS the handle union (`Infer` speaks it); dispatch is native `switch` narrowing with `satisfies never` exhaustiveness. Domains are never declared: `schema()` computes every field's class from the statement list.
|
|
130
131
|
- The statement algebra — `schema()`, `key`, `contained`, `mirrors`, `capacity`; faces via `on` (set membership is a plain array in `.where`); windows via `within` (`within(n)` exact, `within(lo, hi)` range, `within(lo, "*")` floor), measures via `weigh` (`weigh("f")` a u64 field, `weigh(duration("f"))` an interval's measure), dependent bounds via `ref`/`duration` read from the target row; ψ-selection via `.where` on relations and closed rosters.
|
|
131
|
-
- The `Db` runtime — `Db.create`/`Db.open` (exclusive-lock stores; a second open of the same path is `EnvironmentLocked`), transactions, typed violations, scoped snapshot reads (`db.read(fn)`, or `using snap = db.read()` — lifetimes are disposables, never `close()`), the write verbs with `abandon` (returning `abandon(payload)` from `write` or `writeFrom` rolls the transaction back; the outcome arm is in the result type).
|
|
132
|
+
- The `Db` runtime — `Db.create`/`Db.open` (exclusive-lock stores; a second open of the same path is `EnvironmentLocked`), transactions, typed violations, scoped snapshot reads (`db.read(fn)`, or `using snap = db.read()` — lifetimes are disposables, never `close()`), the write verbs with `abandon` (returning `abandon(payload)` from `write` or `writeFrom` rolls the transaction back; the outcome arm is in the result type). Collection writes: `tx.insert(Rel, [{...}])` / `tx.delete(Rel, facts)` return `MutationReport { submitted, changed }`; mint is `tx.reserve(Rel, field, 1n)` (empty is not a minted id). ETL is a host loop of `write`.
|
|
132
133
|
- The query surface — `query(S).rule(r => ...)`: `v(R)`-minted vars (identity is the object reference — reusing one across binding positions IS the join), `find({...})` named result heads (renames are real), params typed by use unchanged, negation, aggregates, and the free comparison/connective exports (`eq`, `ne`, `lt`, `le`, `gt`, `ge`, `and`, `or`, `not`, `allen`/`ALLEN`, `pointIn`); set membership at a closed field is a plain array in the match record (`r.match(Ticket, { priority: ["Normal", "Urgent"] })` — closed-only there: an ordinary field's membership is a bound `r.inSet` param); named interiors and one linear rec via `q.interior` / `q.reach`; `db.prepare` as a plain value.
|
|
133
134
|
- 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`). A disposable lifetime: `using exhumed = await Db.exhume(path)` releases the store's exclusive lock at scope exit.
|
|
134
135
|
|
package/dist/capacity.d.ts
CHANGED
|
@@ -34,8 +34,8 @@
|
|
|
34
34
|
* crosses as bigint always, PRD-04's law); the witnessed measure comes
|
|
35
35
|
* back as `bigint` too (u128-wide engine accumulator, C3).
|
|
36
36
|
*/
|
|
37
|
-
import type { AnyFace, FaceFields, FaceSource, ProjectedShape } from "
|
|
38
|
-
import type { CapacityWindowSpec, WeightSpec } from "
|
|
37
|
+
import type { AnyFace, FaceFields, FaceSource, ProjectedShape } from "./face.js";
|
|
38
|
+
import type { CapacityWindowSpec, WeightSpec } from "./spec.js";
|
|
39
39
|
/**
|
|
40
40
|
* The admission brand — a module-private symbol, deliberately unexported
|
|
41
41
|
* (the standing statement-mint pattern): `CapacityWindowSpec` and
|
package/dist/closed.d.ts
CHANGED
|
@@ -29,10 +29,10 @@
|
|
|
29
29
|
* unwritable by construction: the value simply lacks the writable relation
|
|
30
30
|
* shape.
|
|
31
31
|
*/
|
|
32
|
-
import { type AnyField, type ClosedIdField, type Infer } from "
|
|
33
|
-
import type { AnyRelation, RelationField } from "
|
|
34
|
-
import { type SelectionBinding, type SelectionInput } from "
|
|
35
|
-
import type { LiteralSpec } from "
|
|
32
|
+
import { type AnyField, type ClosedIdField, type Infer } from "./fields.js";
|
|
33
|
+
import type { AnyRelation, RelationField } from "./relation.js";
|
|
34
|
+
import { type SelectionBinding, type SelectionInput } from "./relation.js";
|
|
35
|
+
import type { LiteralSpec } from "./spec.js";
|
|
36
36
|
/**
|
|
37
37
|
* A payload column of a closed relation: any field descriptor except a
|
|
38
38
|
* fresh-marked one (a vocabulary's rows are ground axioms, never minted).
|
package/dist/db.d.ts
CHANGED
|
@@ -29,20 +29,45 @@
|
|
|
29
29
|
* marshal shape, a moved generation on {@link Db.writeFrom} — throw
|
|
30
30
|
* `@superbuilders/errors` wrapped errors instead.
|
|
31
31
|
*/
|
|
32
|
-
import type { Exhumed } from "
|
|
33
|
-
import { type KeyFact
|
|
34
|
-
import type { FactValue } from "
|
|
35
|
-
import type { Query } from "
|
|
36
|
-
import type { ParamsRecord } from "
|
|
37
|
-
import type { AnyRelation, Fact,
|
|
38
|
-
import type { Schema, SchemaRelations } from "
|
|
39
|
-
import { type KeyStatement, type Statement } from "
|
|
32
|
+
import type { Exhumed } from "./exhume.js";
|
|
33
|
+
import { type KeyFact } from "./marshal.js";
|
|
34
|
+
import type { FactValue } from "./native.js";
|
|
35
|
+
import type { Query } from "./query/lower.js";
|
|
36
|
+
import type { ParamsRecord } from "./query/scope.js";
|
|
37
|
+
import type { AnyRelation, Fact, FreshKeys } from "./relation.js";
|
|
38
|
+
import type { Schema, SchemaRelations } from "./schema.js";
|
|
39
|
+
import { type KeyStatement, type Statement } from "./statements.js";
|
|
40
40
|
/**
|
|
41
41
|
* The ordinary (writable, scannable) relations of a schema's record — the
|
|
42
42
|
* only values the runtime methods accept: closed relations lack the
|
|
43
43
|
* relation shape entirely, so passing one is a type error.
|
|
44
44
|
*/
|
|
45
45
|
type MemberRelation<Rels extends SchemaRelations> = Extract<Rels[keyof Rels], AnyRelation>;
|
|
46
|
+
/**
|
|
47
|
+
* Facts consumed vs facts that changed the in-memory final-state view.
|
|
48
|
+
* The length-1 report is `{ submitted: 1n, changed: 0n | 1n }`.
|
|
49
|
+
*/
|
|
50
|
+
interface MutationReport {
|
|
51
|
+
readonly submitted: bigint;
|
|
52
|
+
readonly changed: bigint;
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* Half-open fresh-id range from one `reserve`. Empty cannot yield a
|
|
56
|
+
* minted id — `start` exists only on the nonempty arm.
|
|
57
|
+
*/
|
|
58
|
+
type FreshRange = {
|
|
59
|
+
readonly empty: true;
|
|
60
|
+
readonly count: 0n;
|
|
61
|
+
at(index: bigint): undefined;
|
|
62
|
+
[Symbol.iterator](): IterableIterator<bigint>;
|
|
63
|
+
} | {
|
|
64
|
+
readonly empty: false;
|
|
65
|
+
readonly start: bigint;
|
|
66
|
+
readonly endExclusive: bigint;
|
|
67
|
+
readonly count: bigint;
|
|
68
|
+
at(index: bigint): bigint | undefined;
|
|
69
|
+
[Symbol.iterator](): IterableIterator<bigint>;
|
|
70
|
+
};
|
|
46
71
|
/**
|
|
47
72
|
* The key object of a key-statement-selected `get`: exactly the selected
|
|
48
73
|
* `key()` statement's projection fields, each at the relation's own BARE
|
|
@@ -65,52 +90,77 @@ interface OffendingFact<Rels extends SchemaRelations> {
|
|
|
65
90
|
readonly fact: Readonly<Record<string, FactValue>>;
|
|
66
91
|
}
|
|
67
92
|
/**
|
|
68
|
-
*
|
|
69
|
-
* `statement` is
|
|
70
|
-
*
|
|
71
|
-
*
|
|
72
|
-
*
|
|
73
|
-
* duplicate of them). `canonical` is the ENGINE's rendering of the
|
|
74
|
-
* violated materialized statement — for a `mirrors` statement BOTH
|
|
75
|
-
* materialized slots render as the one `==` utterance in the written
|
|
76
|
-
* orientation (identical strings; the engine's `render.rs` renders each
|
|
77
|
-
* partner of a mirrored pair as the `==` spelling, never a bare `<=`
|
|
78
|
-
* direction). `direction` (`sourceUnsatisfied` | `targetRequired`) and
|
|
79
|
-
* `measure` are the containment/capacity form payloads, passed through
|
|
80
|
-
* from the engine VERBATIM (`measure` the capacity form's witnessed group
|
|
81
|
-
* total — u128-wide, crossing whole as bigint, C3) — `direction` is
|
|
82
|
-
* relative to the violated SLOT's
|
|
83
|
-
* own orientation, so for a `mirrors` statement it alone cannot say which
|
|
84
|
-
* side of the `==` was violated: the slot identity is carried by
|
|
85
|
-
* `orientation`, present exactly for `mirrors` slots — `written` is the
|
|
86
|
-
* `source <= target` slot as the statement was spelled, `mirrored` the
|
|
87
|
-
* engine-materialized `target <= source` partner.
|
|
93
|
+
* Shared body of every violation arm: the engine's canonical rendering and
|
|
94
|
+
* the cited facts. `statement` is NOT here — its presence is the
|
|
95
|
+
* discriminant. Implied auto-keys have no SDK spelling (`statement` is
|
|
96
|
+
* the value `undefined`); every declared form carries the IDENTICAL
|
|
97
|
+
* statement value the schema declared (consumers `===`-match it).
|
|
88
98
|
*/
|
|
89
|
-
type
|
|
90
|
-
readonly kind: "functionality";
|
|
91
|
-
readonly statement?: Statement;
|
|
99
|
+
type ViolationBody<Rels extends SchemaRelations> = {
|
|
92
100
|
readonly canonical: string;
|
|
93
101
|
readonly facts: readonly OffendingFact<Rels>[];
|
|
94
|
-
}
|
|
102
|
+
};
|
|
103
|
+
/**
|
|
104
|
+
* A functionality violation of an engine-materialized fresh-implied or
|
|
105
|
+
* closed auto-key. These slots have no declared spelling (`schema()`
|
|
106
|
+
* rejects an explicit duplicate); `statement` is present and `undefined`.
|
|
107
|
+
*/
|
|
108
|
+
type ImpliedKeyViolation<Rels extends SchemaRelations> = ViolationBody<Rels> & {
|
|
109
|
+
readonly kind: "functionality";
|
|
110
|
+
readonly statement: undefined;
|
|
111
|
+
};
|
|
112
|
+
/**
|
|
113
|
+
* A functionality violation of a declared `key()` statement. `statement`
|
|
114
|
+
* is the IDENTICAL SDK value the schema declared.
|
|
115
|
+
*/
|
|
116
|
+
type DeclaredKeyViolation<Rels extends SchemaRelations> = ViolationBody<Rels> & {
|
|
117
|
+
readonly kind: "functionality";
|
|
118
|
+
readonly statement: Statement;
|
|
119
|
+
};
|
|
120
|
+
/**
|
|
121
|
+
* A containment violation of a declared `contained()` statement (no
|
|
122
|
+
* `orientation` — that property exists exactly on {@link MirrorViolation}).
|
|
123
|
+
*/
|
|
124
|
+
type ContainmentViolation<Rels extends SchemaRelations> = ViolationBody<Rels> & {
|
|
95
125
|
readonly kind: "containment";
|
|
96
|
-
readonly statement
|
|
97
|
-
readonly canonical: string;
|
|
126
|
+
readonly statement: Statement;
|
|
98
127
|
readonly direction: "sourceUnsatisfied" | "targetRequired";
|
|
99
|
-
|
|
100
|
-
|
|
128
|
+
};
|
|
129
|
+
/**
|
|
130
|
+
* A containment violation of one slot of a declared `mirrors()` statement.
|
|
131
|
+
* BOTH materialized slots render as the one `==` utterance in the written
|
|
132
|
+
* orientation (identical `canonical` strings; the engine's `render.rs`
|
|
133
|
+
* never emits a bare `<=` for a mirrored pair). `direction` is relative
|
|
134
|
+
* to the violated SLOT's own orientation, so it alone cannot say which
|
|
135
|
+
* side of the `==` was violated: `written` is the `source <= target` slot
|
|
136
|
+
* as the statement was spelled, `mirrored` the engine-materialized
|
|
137
|
+
* `target <= source` partner.
|
|
138
|
+
*/
|
|
139
|
+
type MirrorViolation<Rels extends SchemaRelations> = ViolationBody<Rels> & {
|
|
101
140
|
readonly kind: "containment";
|
|
102
|
-
readonly statement
|
|
103
|
-
readonly canonical: string;
|
|
141
|
+
readonly statement: Statement;
|
|
104
142
|
readonly direction: "sourceUnsatisfied" | "targetRequired";
|
|
105
143
|
readonly orientation: "written" | "mirrored";
|
|
106
|
-
|
|
107
|
-
|
|
144
|
+
};
|
|
145
|
+
/**
|
|
146
|
+
* A capacity violation of a declared `capacity()` statement. `measure` is
|
|
147
|
+
* the engine's witnessed group total — u128-wide, crossing whole as
|
|
148
|
+
* bigint (C3: truncation is unrepresentable).
|
|
149
|
+
*/
|
|
150
|
+
type CapacityViolation<Rels extends SchemaRelations> = ViolationBody<Rels> & {
|
|
108
151
|
readonly kind: "capacity";
|
|
109
|
-
readonly statement
|
|
110
|
-
readonly canonical: string;
|
|
152
|
+
readonly statement: Statement;
|
|
111
153
|
readonly measure: bigint;
|
|
112
|
-
readonly facts: readonly OffendingFact<Rels>[];
|
|
113
154
|
};
|
|
155
|
+
/**
|
|
156
|
+
* One violated statement of a rejected commit, as a typed value. The
|
|
157
|
+
* arms are a true discriminant: `statement === undefined` is exactly the
|
|
158
|
+
* implied-auto-key arm; every declared form carries `Statement` (not
|
|
159
|
+
* `Statement | undefined`, not an omit-optional). `canonical` is the
|
|
160
|
+
* ENGINE's rendering. `direction` / `measure` pass through from the
|
|
161
|
+
* engine VERBATIM.
|
|
162
|
+
*/
|
|
163
|
+
type Violation<Rels extends SchemaRelations> = ImpliedKeyViolation<Rels> | DeclaredKeyViolation<Rels> | ContainmentViolation<Rels> | MirrorViolation<Rels> | CapacityViolation<Rels>;
|
|
114
164
|
/**
|
|
115
165
|
* The abandoned arm of a write result (ruled 2026-07-23, R10): present in
|
|
116
166
|
* the type EXACTLY when the callback can abandon — the conditional
|
|
@@ -179,23 +229,22 @@ declare function abandon<P>(payload: P): Abandon<P>;
|
|
|
179
229
|
*/
|
|
180
230
|
interface Tx<Rels extends SchemaRelations> {
|
|
181
231
|
/**
|
|
182
|
-
* Records
|
|
183
|
-
*
|
|
184
|
-
*
|
|
185
|
-
*
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
*
|
|
190
|
-
*
|
|
191
|
-
|
|
192
|
-
|
|
232
|
+
* Records a collection of inserts. Singleton is `[fact]`. Empty is
|
|
233
|
+
* lawful. Returns how many facts were consumed and how many changed
|
|
234
|
+
* the in-memory final-state view. Every fact is complete — omitted
|
|
235
|
+
* fresh cells are a type error; mint first with {@link Tx.reserve}.
|
|
236
|
+
*/
|
|
237
|
+
insert<R extends MemberRelation<Rels>>(relation: R, facts: Iterable<Fact<R>>): MutationReport;
|
|
238
|
+
/**
|
|
239
|
+
* Records a collection of deletes. Singleton is `[fact]`. Returns
|
|
240
|
+
* how many facts were consumed and how many changed the view.
|
|
241
|
+
*/
|
|
242
|
+
delete<R extends MemberRelation<Rels>>(relation: R, facts: Iterable<Fact<R>>): MutationReport;
|
|
243
|
+
/**
|
|
244
|
+
* Mints `count` consecutive fresh values for a `.fresh` field.
|
|
245
|
+
* `count === 0n` is empty and does not yield a start.
|
|
193
246
|
*/
|
|
194
|
-
|
|
195
|
-
readonly changed: boolean;
|
|
196
|
-
} & Minted<R>;
|
|
197
|
-
/** Records one delete; `true` iff the final state changed. */
|
|
198
|
-
delete<R extends MemberRelation<Rels>>(relation: R, fact: Fact<R>): boolean;
|
|
247
|
+
reserve<R extends MemberRelation<Rels>>(relation: R, field: FreshKeys<R> & string, count: bigint): FreshRange;
|
|
199
248
|
/** Final-state membership of one complete fact. */
|
|
200
249
|
contains<R extends MemberRelation<Rels>>(relation: R, fact: Fact<R>): boolean;
|
|
201
250
|
/**
|
|
@@ -392,6 +441,6 @@ declare const Db: Readonly<{
|
|
|
392
441
|
*/
|
|
393
442
|
exhume(storePath: string): Promise<Exhumed>;
|
|
394
443
|
}>;
|
|
395
|
-
export type { Abandon, AbandonedArm, DeclaredKeyFact, DeltaBuild, MemberRelation, OffendingFact, Prepared, ReadScope, Tx, Violation, WriteResult };
|
|
444
|
+
export type { Abandon, AbandonedArm, CapacityViolation, ContainmentViolation, DeclaredKeyFact, DeclaredKeyViolation, DeltaBuild, FreshRange, ImpliedKeyViolation, MemberRelation, MirrorViolation, MutationReport, OffendingFact, Prepared, ReadScope, Tx, Violation, WriteResult };
|
|
396
445
|
export { abandon, Db, ErrGenerationMoved, ErrNewtypeMismatch };
|
|
397
446
|
//# sourceMappingURL=db.d.ts.map
|
package/dist/db.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"db.d.ts","sourceRoot":"","sources":["../src/db.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8BG;AAKH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,YAAY,CAAA;AAIzC,OAAO,
|
|
1
|
+
{"version":3,"file":"db.d.ts","sourceRoot":"","sources":["../src/db.ts"],"names":[],"mappings":"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"}
|
package/dist/db.js
CHANGED
|
@@ -35,11 +35,45 @@ import { isClosedMember, sealedFieldsOf } from "#closed.ts";
|
|
|
35
35
|
import { exhumeStore } from "#exhume.ts";
|
|
36
36
|
import { rosterOf } from "#fields.ts";
|
|
37
37
|
import { lower } from "#lower.ts";
|
|
38
|
-
import { factOf, handleOf, isFreshField,
|
|
38
|
+
import { factOf, handleOf, isFreshField, keyRowOf, recordOf, rowOf } from "#marshal.ts";
|
|
39
39
|
import { bridged, native } from "#native.ts";
|
|
40
40
|
import { lowerQuery } from "#query/lower.ts";
|
|
41
41
|
import { decodeAnswers, wireParams } from "#query/run.ts";
|
|
42
42
|
import { isStatement } from "#statements.ts";
|
|
43
|
+
function freshRangeOf(wire) {
|
|
44
|
+
if (wire.empty) {
|
|
45
|
+
return Object.freeze({
|
|
46
|
+
empty: true,
|
|
47
|
+
count: 0n,
|
|
48
|
+
at(_index) {
|
|
49
|
+
return undefined;
|
|
50
|
+
},
|
|
51
|
+
*[Symbol.iterator]() { }
|
|
52
|
+
});
|
|
53
|
+
}
|
|
54
|
+
const start = wire.start;
|
|
55
|
+
const endExclusive = wire.endExclusive;
|
|
56
|
+
const count = endExclusive - start;
|
|
57
|
+
return Object.freeze({
|
|
58
|
+
empty: false,
|
|
59
|
+
start,
|
|
60
|
+
endExclusive,
|
|
61
|
+
get count() {
|
|
62
|
+
return count;
|
|
63
|
+
},
|
|
64
|
+
at(index) {
|
|
65
|
+
if (index < 0n || index >= count) {
|
|
66
|
+
return undefined;
|
|
67
|
+
}
|
|
68
|
+
return start + index;
|
|
69
|
+
},
|
|
70
|
+
*[Symbol.iterator]() {
|
|
71
|
+
for (let id = start; id < endExclusive; id++) {
|
|
72
|
+
yield id;
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
});
|
|
76
|
+
}
|
|
43
77
|
/**
|
|
44
78
|
* The runtime discriminant of {@link Abandon} values — a property probe is
|
|
45
79
|
* how `write`/`writeFrom` distinguish "abort without committing" from an
|
|
@@ -302,36 +336,6 @@ const planReclaimer = new FinalizationRegistry(function reclaimPlan(handle) {
|
|
|
302
336
|
* policy. Match with `errors.is`.
|
|
303
337
|
*/
|
|
304
338
|
const ErrGenerationMoved = errors.new("bumbledb generationMoved: a state-changing commit landed since the witness snapshot");
|
|
305
|
-
/**
|
|
306
|
-
* Fills one insert's omitted fresh cells through the engine's
|
|
307
|
-
* alloc-then-insert dyn lane (there is no insert-with-omitted-fields wire
|
|
308
|
-
* spelling) and collects every fresh cell — minted or resupplied — for the
|
|
309
|
-
* insert's return. Mutates `values` in place with the minted cells.
|
|
310
|
-
*/
|
|
311
|
-
function mintFreshCells(txHandle, entry, relation, values) {
|
|
312
|
-
const fresh = {};
|
|
313
|
-
for (const declared of relation.data.fields) {
|
|
314
|
-
if (!isFreshField(declared.field)) {
|
|
315
|
-
continue;
|
|
316
|
-
}
|
|
317
|
-
let cell = values[declared.name];
|
|
318
|
-
if (cell === undefined) {
|
|
319
|
-
const fieldId = entry.fieldIds.get(declared.name);
|
|
320
|
-
if (fieldId === undefined) {
|
|
321
|
-
throw errors.new(`bumbledb manifest drift: relation ${relation.name} has no field id for ${declared.name}`);
|
|
322
|
-
}
|
|
323
|
-
cell = bridged("bumbledb tx alloc", function mint() {
|
|
324
|
-
return native.txAlloc(txHandle, entry.id, fieldId);
|
|
325
|
-
});
|
|
326
|
-
values[declared.name] = cell;
|
|
327
|
-
}
|
|
328
|
-
if (typeof cell !== "bigint") {
|
|
329
|
-
throw errors.new(`relation ${relation.name} field ${declared.name}: a fresh cell is a u64 bigint, got ${typeof cell}`);
|
|
330
|
-
}
|
|
331
|
-
fresh[declared.name] = cell;
|
|
332
|
-
}
|
|
333
|
-
return fresh;
|
|
334
|
-
}
|
|
335
339
|
/**
|
|
336
340
|
* Constructs one open `Db` over an already-admitted handle: builds the
|
|
337
341
|
* id-resolution tables once and closes over them — the `Db` owns handle
|
|
@@ -380,16 +384,24 @@ function openDb(handle, theory, manifest) {
|
|
|
380
384
|
throw errors.new(`bumbledb violation cites unknown statement id ${wire.statementId}`);
|
|
381
385
|
}
|
|
382
386
|
const facts = Object.freeze(wire.facts.map(offendingFactOf));
|
|
383
|
-
const statement = entry.statement;
|
|
384
387
|
const canonical = wire.canonical;
|
|
385
388
|
if (entry.kind === "functionality") {
|
|
386
|
-
|
|
389
|
+
if (!("statement" in entry)) {
|
|
390
|
+
return Object.freeze({ kind: "functionality", statement: undefined, canonical, facts });
|
|
391
|
+
}
|
|
392
|
+
return Object.freeze({ kind: "functionality", statement: entry.statement, canonical, facts });
|
|
387
393
|
}
|
|
388
394
|
if (entry.kind === "capacity") {
|
|
389
395
|
if (wire.kind !== "capacity") {
|
|
390
396
|
throw errors.new(`bumbledb violation ${wire.statementId} is a capacity slot without a measure`);
|
|
391
397
|
}
|
|
392
|
-
return Object.freeze({
|
|
398
|
+
return Object.freeze({
|
|
399
|
+
kind: "capacity",
|
|
400
|
+
statement: entry.statement,
|
|
401
|
+
canonical,
|
|
402
|
+
measure: wire.measure,
|
|
403
|
+
facts
|
|
404
|
+
});
|
|
393
405
|
}
|
|
394
406
|
if (wire.kind !== "containment") {
|
|
395
407
|
throw errors.new(`bumbledb violation ${wire.statementId} is a containment slot without a direction`);
|
|
@@ -397,14 +409,20 @@ function openDb(handle, theory, manifest) {
|
|
|
397
409
|
if (entry.kind === "mirrors") {
|
|
398
410
|
return Object.freeze({
|
|
399
411
|
kind: "containment",
|
|
400
|
-
statement,
|
|
412
|
+
statement: entry.statement,
|
|
401
413
|
canonical,
|
|
402
414
|
direction: wire.direction,
|
|
403
415
|
orientation: entry.orientation,
|
|
404
416
|
facts
|
|
405
417
|
});
|
|
406
418
|
}
|
|
407
|
-
return Object.freeze({
|
|
419
|
+
return Object.freeze({
|
|
420
|
+
kind: "containment",
|
|
421
|
+
statement: entry.statement,
|
|
422
|
+
canonical,
|
|
423
|
+
direction: wire.direction,
|
|
424
|
+
facts
|
|
425
|
+
});
|
|
408
426
|
}
|
|
409
427
|
/**
|
|
410
428
|
* Resolves a key-statement-selected read: the statement must be the
|
|
@@ -415,7 +433,7 @@ function openDb(handle, theory, manifest) {
|
|
|
415
433
|
*/
|
|
416
434
|
function declaredKeyOf(relation, statement) {
|
|
417
435
|
const statementId = tables.statements.findIndex(function byIdentity(candidate) {
|
|
418
|
-
return candidate.statement === statement;
|
|
436
|
+
return "statement" in candidate && candidate.statement === statement;
|
|
419
437
|
});
|
|
420
438
|
const entry = tables.statements[statementId];
|
|
421
439
|
if (entry === undefined) {
|
|
@@ -640,35 +658,55 @@ function openDb(handle, theory, manifest) {
|
|
|
640
658
|
});
|
|
641
659
|
}
|
|
642
660
|
});
|
|
643
|
-
function insert(relation,
|
|
661
|
+
function insert(relation, facts) {
|
|
644
662
|
assertLive();
|
|
663
|
+
const rows = [];
|
|
664
|
+
for (const fact of facts) {
|
|
665
|
+
rows.push(rowOf(relation.data, recordOf(fact)));
|
|
666
|
+
}
|
|
645
667
|
const entry = resolveOrdinary(relation);
|
|
646
668
|
const txHandle = resolveTx();
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
const fresh = mintFreshCells(txHandle, entry, relation, values);
|
|
650
|
-
const row = rowOf(relation.data, values);
|
|
651
|
-
const changed = bridged("bumbledb tx insert", function record() {
|
|
652
|
-
return native.txInsert(txHandle, entry.id, row);
|
|
669
|
+
const report = bridged("bumbledb tx insert", function record() {
|
|
670
|
+
return native.txInsert(txHandle, entry.id, rows);
|
|
653
671
|
});
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
|
|
672
|
+
return Object.freeze({ submitted: report.submitted, changed: report.changed });
|
|
673
|
+
}
|
|
674
|
+
function remove(relation, facts) {
|
|
675
|
+
assertLive();
|
|
676
|
+
const rows = [];
|
|
677
|
+
for (const fact of facts) {
|
|
678
|
+
rows.push(rowOf(relation.data, recordOf(fact)));
|
|
657
679
|
}
|
|
658
|
-
|
|
680
|
+
const entry = resolveOrdinary(relation);
|
|
681
|
+
const txHandle = resolveTx();
|
|
682
|
+
const report = bridged("bumbledb tx delete", function record() {
|
|
683
|
+
return native.txDelete(txHandle, entry.id, rows);
|
|
684
|
+
});
|
|
685
|
+
return Object.freeze({ submitted: report.submitted, changed: report.changed });
|
|
659
686
|
}
|
|
660
|
-
function
|
|
687
|
+
function reserve(relation, field, count) {
|
|
661
688
|
assertLive();
|
|
662
689
|
const entry = resolveOrdinary(relation);
|
|
690
|
+
const declared = relation.data.fields.find(function byName(candidate) {
|
|
691
|
+
return candidate.name === field;
|
|
692
|
+
});
|
|
693
|
+
if (declared === undefined || !isFreshField(declared.field)) {
|
|
694
|
+
throw errors.new(`relation ${relation.name}: field ${field} is not a fresh cell`);
|
|
695
|
+
}
|
|
696
|
+
const fieldId = entry.fieldIds.get(field);
|
|
697
|
+
if (fieldId === undefined) {
|
|
698
|
+
throw errors.new(`bumbledb manifest drift: relation ${relation.name} has no field id for ${field}`);
|
|
699
|
+
}
|
|
663
700
|
const txHandle = resolveTx();
|
|
664
|
-
const
|
|
665
|
-
|
|
666
|
-
return native.txDelete(txHandle, entry.id, row);
|
|
701
|
+
const range = bridged("bumbledb tx reserve", function mint() {
|
|
702
|
+
return native.txReserve(txHandle, entry.id, fieldId, count);
|
|
667
703
|
});
|
|
704
|
+
return freshRangeOf(range);
|
|
668
705
|
}
|
|
669
706
|
const tx = Object.freeze({
|
|
670
707
|
insert,
|
|
671
708
|
delete: remove,
|
|
709
|
+
reserve,
|
|
672
710
|
contains: reads.contains,
|
|
673
711
|
get: reads.get
|
|
674
712
|
});
|
|
@@ -821,24 +859,6 @@ function openDb(handle, theory, manifest) {
|
|
|
821
859
|
* what the types claim.
|
|
822
860
|
*/
|
|
823
861
|
const ErrNewtypeMismatch = errors.new("bumbledb newtypeMismatch: a statement pairs faces whose newtypes disagree — the faces of a dependency agree on their newtype, or neither carries one");
|
|
824
|
-
/**
|
|
825
|
-
* `Tx.insert` returns the flattened `{ changed, ...fresh }` record (R11),
|
|
826
|
-
* where the spread wins: a FRESH field literally named `changed` would
|
|
827
|
-
* shadow the engine's changed-state report on every insert of its
|
|
828
|
-
* relation. No field name is reserved SILENTLY — the one unspeakable
|
|
829
|
-
* spelling is refused here at admission, before any store is touched.
|
|
830
|
-
* Supplied (non-fresh) fields named `changed` never enter the return
|
|
831
|
-
* record and stay legal.
|
|
832
|
-
*/
|
|
833
|
-
function refuseShadowedChanged(theory) {
|
|
834
|
-
for (const [name, member] of Object.entries(theory.relations)) {
|
|
835
|
-
for (const declared of sealedFieldsOf(member)) {
|
|
836
|
-
if (declared.name === "changed" && isFreshField(declared.field)) {
|
|
837
|
-
throw errors.new(`relation ${name}: a fresh field named "changed" would shadow tx.insert's changed-state report in its { changed, ...fresh } return (R11) — rename the fresh field; a supplied field named "changed" stays legal (only fresh cells ride the return)`);
|
|
838
|
-
}
|
|
839
|
-
}
|
|
840
|
-
}
|
|
841
|
-
}
|
|
842
862
|
/**
|
|
843
863
|
* The one admission path both verbs share: lower the theory, run one
|
|
844
864
|
* bridge call, and wrap the domain refusals — `schemaError` (spec
|
|
@@ -851,7 +871,6 @@ function refuseShadowedChanged(theory) {
|
|
|
851
871
|
* "another live handle holds this environment's lock".
|
|
852
872
|
*/
|
|
853
873
|
function admit(verb, storePath, theory) {
|
|
854
|
-
refuseShadowedChanged(theory);
|
|
855
874
|
const canonical = path.resolve(storePath);
|
|
856
875
|
const spec = lower(theory);
|
|
857
876
|
const opened = bridged(`${verb} bumbledb store at ${canonical}`, function callBridge() {
|