@bjornpagen/bumbledb 0.14.0 → 0.17.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 +58 -62
- package/README.md +82 -56
- package/dist/capacity.d.ts +24 -136
- package/dist/capacity.d.ts.map +1 -1
- package/dist/capacity.js +18 -40
- package/dist/capacity.js.map +1 -1
- package/dist/closed.d.ts +0 -156
- package/dist/closed.d.ts.map +1 -1
- package/dist/closed.js +0 -104
- package/dist/closed.js.map +1 -1
- package/dist/db.d.ts +93 -290
- package/dist/db.d.ts.map +1 -1
- package/dist/db.js +713 -556
- package/dist/db.js.map +1 -1
- package/dist/face.d.ts +0 -133
- package/dist/face.d.ts.map +1 -1
- package/dist/face.js +0 -33
- package/dist/face.js.map +1 -1
- package/dist/fields.d.ts +1 -145
- package/dist/fields.d.ts.map +1 -1
- package/dist/fields.js +2 -91
- package/dist/fields.js.map +1 -1
- package/dist/index.d.ts +13 -23
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +11 -20
- package/dist/index.js.map +1 -1
- package/dist/law.d.ts +111 -93
- package/dist/law.d.ts.map +1 -1
- package/dist/law.js +23 -27
- package/dist/law.js.map +1 -1
- package/dist/lower.d.ts +9 -35
- package/dist/lower.d.ts.map +1 -1
- package/dist/lower.js +8 -53
- package/dist/lower.js.map +1 -1
- package/dist/marshal.d.ts +0 -65
- package/dist/marshal.d.ts.map +1 -1
- package/dist/marshal.js +0 -72
- package/dist/marshal.js.map +1 -1
- package/dist/native.d.ts +97 -390
- package/dist/native.d.ts.map +1 -1
- package/dist/native.js +39 -61
- package/dist/native.js.map +1 -1
- package/dist/query/atom.d.ts +10 -276
- package/dist/query/atom.d.ts.map +1 -1
- package/dist/query/atom.js +1 -96
- package/dist/query/atom.js.map +1 -1
- package/dist/query/find.d.ts +10 -76
- package/dist/query/find.d.ts.map +1 -1
- package/dist/query/find.js +0 -30
- package/dist/query/find.js.map +1 -1
- package/dist/query/lower.d.ts +64 -146
- package/dist/query/lower.d.ts.map +1 -1
- package/dist/query/lower.js +19 -256
- package/dist/query/lower.js.map +1 -1
- package/dist/query/parse-ir.d.ts +0 -7
- package/dist/query/parse-ir.d.ts.map +1 -1
- package/dist/query/parse-ir.js +1 -13
- package/dist/query/parse-ir.js.map +1 -1
- package/dist/query/run.d.ts +0 -36
- package/dist/query/run.d.ts.map +1 -1
- package/dist/query/run.js +0 -44
- package/dist/query/run.js.map +1 -1
- package/dist/query/scope.d.ts +24 -180
- package/dist/query/scope.d.ts.map +1 -1
- package/dist/query/scope.js +2 -66
- package/dist/query/scope.js.map +1 -1
- package/dist/relation.d.ts +2 -50
- package/dist/relation.d.ts.map +1 -1
- package/dist/relation.js +2 -37
- package/dist/relation.js.map +1 -1
- package/dist/schema.d.ts +13 -63
- package/dist/schema.d.ts.map +1 -1
- package/dist/schema.js +118 -92
- package/dist/schema.js.map +1 -1
- package/dist/spec.d.ts +1 -140
- package/dist/spec.d.ts.map +1 -1
- package/dist/spec.js +1 -68
- package/dist/spec.js.map +1 -1
- package/dist/statements.d.ts +6 -137
- package/dist/statements.d.ts.map +1 -1
- package/dist/statements.js +16 -119
- package/dist/statements.js.map +1 -1
- package/package.json +3 -3
- package/src/capacity.ts +26 -140
- package/src/closed.ts +5 -206
- package/src/db.ts +997 -854
- package/src/face.ts +0 -142
- package/src/fields.ts +4 -172
- package/src/index.ts +32 -35
- package/src/law.ts +201 -129
- package/src/lower.ts +8 -53
- package/src/marshal.ts +1 -85
- package/src/native.ts +192 -413
- package/src/query/atom.ts +26 -313
- package/src/query/find.ts +24 -110
- package/src/query/lower.ts +132 -377
- package/src/query/parse-ir.ts +1 -14
- package/src/query/run.ts +0 -45
- package/src/query/scope.ts +25 -186
- package/src/relation.ts +2 -66
- package/src/schema.ts +143 -122
- package/src/spec.ts +1 -160
- package/src/statements.ts +22 -174
- package/dist/exhume.d.ts +0 -143
- package/dist/exhume.d.ts.map +0 -1
- package/dist/exhume.js +0 -166
- package/dist/exhume.js.map +0 -1
- package/src/exhume.ts +0 -267
package/src/statements.ts
CHANGED
|
@@ -1,39 +1,3 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Dependency statements as typed values (`docs/architecture/30-dependencies.md`
|
|
3
|
-
* owns the semantics; `docs/architecture/70-api.md` the surface): the FD key
|
|
4
|
-
* form, conditional containment, the bidirectional `==` abbreviation, and
|
|
5
|
-
* the capacity statement. A statement value is opaque and inert — no
|
|
6
|
-
* methods, no fluent continuation: a fact about the theory, not a builder.
|
|
7
|
-
*
|
|
8
|
-
* Every field reference is checked against the relation it names in the
|
|
9
|
-
* TYPE — existence through {@link FaceFields} (`on(R, "nope")` does not
|
|
10
|
-
* compile) and STRUCTURAL compatibility through {@link SameShapes}: the two
|
|
11
|
-
* faces' projected kind/width/element/roster quadruples are read off the
|
|
12
|
-
* schema type (the minimal kernel — descriptors are pure structure) and
|
|
13
|
-
* constrained positionwise equal, so a u64 face against a str face, a
|
|
14
|
-
* bytes width mismatch, an interval element mismatch, or a bare column
|
|
15
|
-
* against a closed reference is a compile error. TWO of those walls carry
|
|
16
|
-
* construction-time runtime twins here for untyped callers: ARITY
|
|
17
|
-
* ({@link assertArityAgreement} — cleanup-0.5.0 ruling 9: an
|
|
18
|
-
* arity-mismatched pairing fails at the statement, never by silent
|
|
19
|
-
* truncation) and the ROSTER slot ({@link assertRosterAgreement} —
|
|
20
|
-
* roster IDENTITY, positionwise: a closed vocabulary's referencing column
|
|
21
|
-
* is spelled with the vocabulary's own id descriptor, the ONE spelling, so
|
|
22
|
-
* a plain u64 column can never alias a vocabulary through a declared law
|
|
23
|
-
* and the SDK's descriptor-keyed closed judgments stay sound). Domains are
|
|
24
|
-
* NOT compared here — there is no domain to compare at construction: the
|
|
25
|
-
* statements themselves are what define the equivalence classes, and the
|
|
26
|
-
* domain wall lives where they aggregate — `schema()` (the
|
|
27
|
-
* one-generator-per-class law) and query joins (class names off the schema
|
|
28
|
-
* type). What is only a SEMANTIC property — the target side of a
|
|
29
|
-
* containment resolving a declared key of its relation — is DELIBERATELY
|
|
30
|
-
* not (and cannot be) stated here: whether `B(y)` is a key of `B` depends
|
|
31
|
-
* on which `key()` statements the surrounding `schema()` collects, a set no
|
|
32
|
-
* face type can see; it stays the engine's typed `SchemaError` judgment at
|
|
33
|
-
* `Db.create`/`Db.open` (the two-boundary split, engine as final
|
|
34
|
-
* authority).
|
|
35
|
-
*/
|
|
36
|
-
|
|
37
1
|
import * as errors from "@superbuilders/errors"
|
|
38
2
|
import {
|
|
39
3
|
type BoundsOnTarget,
|
|
@@ -52,20 +16,12 @@ import { type ClosedRoster, rosterOf } from "#fields.ts"
|
|
|
52
16
|
import type { AnyRelation, RelationFields } from "#relation.ts"
|
|
53
17
|
import { type CapacityWindowSpec, renderCapacityWindow, renderWeight, type WeightSpec } from "#spec.ts"
|
|
54
18
|
|
|
55
|
-
/** A `key()` statement's runtime description — owner and projection carried at exact types. */
|
|
56
19
|
interface KeyData<R extends AnyRelation, Projection extends readonly string[]> {
|
|
57
20
|
readonly kind: "key"
|
|
58
21
|
readonly owner: R
|
|
59
22
|
readonly projection: Projection
|
|
60
23
|
}
|
|
61
24
|
|
|
62
|
-
/**
|
|
63
|
-
* A containment statement's runtime description — the two faces carried at
|
|
64
|
-
* their EXACT types (owner names and projection tuples are honest runtime
|
|
65
|
-
* properties, and they are the type-level carrier `schema()`'s law-typing
|
|
66
|
-
* pairs slots through). The defaults are the wide shape renderers and the
|
|
67
|
-
* wire lowering consume.
|
|
68
|
-
*/
|
|
69
25
|
interface ContainmentData<Src extends FaceData = FaceData, Tgt extends FaceData = FaceData> {
|
|
70
26
|
readonly kind: "containment"
|
|
71
27
|
readonly source: Src
|
|
@@ -78,12 +34,6 @@ interface MirrorsData<Src extends FaceData = FaceData, Tgt extends FaceData = Fa
|
|
|
78
34
|
readonly target: Tgt
|
|
79
35
|
}
|
|
80
36
|
|
|
81
|
-
/**
|
|
82
|
-
* A capacity statement's runtime description — target-left, in the
|
|
83
|
-
* operator's own order (C2: target, weight, window, source), faces at
|
|
84
|
-
* exact types like {@link ContainmentData}. The weight is ALWAYS present
|
|
85
|
-
* (C4 — `unit` is a case, not an absence).
|
|
86
|
-
*/
|
|
87
37
|
interface CapacityData<Tgt extends FaceData = FaceData, Src extends FaceData = FaceData> {
|
|
88
38
|
readonly kind: "capacity"
|
|
89
39
|
readonly target: Tgt
|
|
@@ -92,69 +42,31 @@ interface CapacityData<Tgt extends FaceData = FaceData, Src extends FaceData = F
|
|
|
92
42
|
readonly source: Src
|
|
93
43
|
}
|
|
94
44
|
|
|
95
|
-
/** One statement's runtime description, tagged by form. */
|
|
96
45
|
type StatementData = KeyData<AnyRelation, readonly string[]> | ContainmentData | MirrorsData | CapacityData
|
|
97
46
|
|
|
98
|
-
/**
|
|
99
|
-
* The admission brand — a module-private symbol, deliberately unexported
|
|
100
|
-
* (the `capacity.ts` pattern): `Statement` is a public structural type, so
|
|
101
|
-
* without this brand a forged plain object of the right shape would walk
|
|
102
|
-
* past the construction-time arity and roster walls into `schema()` — and
|
|
103
|
-
* the roster wall is the one the engine cannot backstop (the wire carries
|
|
104
|
-
* plain u64s, no rosters). The symbol makes the four constructors the ONLY
|
|
105
|
-
* mints, so a statement that skipped the walls is unspellable.
|
|
106
|
-
*/
|
|
107
47
|
const admitted: unique symbol = Symbol("bumbledb.statement.admitted")
|
|
108
48
|
|
|
109
|
-
/** An opaque statement value — what `schema()` assembles into a theory. Only the four constructors produce one. */
|
|
110
49
|
interface Statement {
|
|
111
50
|
readonly data: StatementData
|
|
112
51
|
readonly [admitted]: true
|
|
113
52
|
}
|
|
114
53
|
|
|
115
|
-
/**
|
|
116
|
-
* Narrows any value to an admitted statement — the probe is the
|
|
117
|
-
* module-private {@link admitted} brand only the four constructors set, so
|
|
118
|
-
* no host-built value (fact cells are structurally OPEN — an interval with
|
|
119
|
-
* an excess `kind` property is a legal cell) can ever be misread as one.
|
|
120
|
-
* The keyed-get selector dispatch and `schema()`'s admission both judge
|
|
121
|
-
* through here.
|
|
122
|
-
*/
|
|
123
54
|
function isStatement(value: unknown): value is Statement {
|
|
124
55
|
return typeof value === "object" && value !== null && admitted in value
|
|
125
56
|
}
|
|
126
57
|
|
|
127
|
-
/**
|
|
128
|
-
* A containment (or `==` bijection) statement as a TYPED value: `data`
|
|
129
|
-
* carries both faces at their exact types, so the schema-level class laws
|
|
130
|
-
* can read every paired (relation, field) slot off the statement type —
|
|
131
|
-
* spell the statement list inline in `schema()` and the equivalence
|
|
132
|
-
* classes compute at the type level too. Structurally still a plain
|
|
133
|
-
* {@link Statement}.
|
|
134
|
-
*/
|
|
135
58
|
interface ContainedStatement<Src extends FaceData, Tgt extends FaceData> extends Statement {
|
|
136
59
|
readonly data: ContainmentData<Src, Tgt> | MirrorsData<Src, Tgt>
|
|
137
60
|
}
|
|
138
61
|
|
|
139
|
-
/** A capacity statement as a TYPED value — the {@link ContainedStatement} of the capacity form. */
|
|
140
62
|
interface CapacityStatement<Tgt extends FaceData, Src extends FaceData> extends Statement {
|
|
141
63
|
readonly data: CapacityData<Tgt, Src>
|
|
142
64
|
}
|
|
143
65
|
|
|
144
|
-
/**
|
|
145
|
-
* A `key()` statement as a TYPED value: its `data` carries the owner
|
|
146
|
-
* relation and the projection tuple at their EXACT types (honest runtime
|
|
147
|
-
* properties — no phantom), which is what the key-statement-selected
|
|
148
|
-
* `get(relation, keyStatement, key)` overload types its key object by
|
|
149
|
-
* (`docs/architecture/70-api.md` § the freeze, the multi-key typed get) and
|
|
150
|
-
* what resolves each projected field's descriptor through the owner's
|
|
151
|
-
* schema type. Structurally still a plain {@link Statement}.
|
|
152
|
-
*/
|
|
153
66
|
interface KeyStatement<R extends AnyRelation, Projection extends readonly string[]> extends Statement {
|
|
154
67
|
readonly data: KeyData<R, Projection>
|
|
155
68
|
}
|
|
156
69
|
|
|
157
|
-
/** Renders one face position's closedness for the roster-agreement diagnostics. */
|
|
158
70
|
function renderRosterSide(roster: ClosedRoster | undefined): string {
|
|
159
71
|
return roster === undefined ? "a bare column" : `a ${roster.name} reference`
|
|
160
72
|
}
|
|
@@ -176,22 +88,6 @@ function assertArityAgreement(source: FaceData, target: FaceData, statement: Sta
|
|
|
176
88
|
}
|
|
177
89
|
}
|
|
178
90
|
|
|
179
|
-
/**
|
|
180
|
-
* The runtime twin of {@link SameShapes}'s roster slot: the two faces'
|
|
181
|
-
* projected descriptors must agree POSITIONWISE on closedness — the same
|
|
182
|
-
* roster (value identity — vocabulary identity is value identity, the
|
|
183
|
-
* SDK's membership rule everywhere) or none. Without this wall a plain u64
|
|
184
|
-
* column could alias a closed vocabulary through a declared containment
|
|
185
|
-
* (`docs/architecture/10-data-model.md` spells the ENGINE encoding that
|
|
186
|
-
* way), and every descriptor-keyed closed judgment — the orderable ban,
|
|
187
|
-
* the name↔id marshal, answer decode — would silently miss it. The
|
|
188
|
-
* vocabulary's own descriptor (`Kind.id`) is the ONE spelling of a closed
|
|
189
|
-
* reference at this surface (the canonical-utterance law); the engine
|
|
190
|
-
* cannot backstop this one — the wire carries plain u64s, no rosters.
|
|
191
|
-
* Arity agreement ({@link assertArityAgreement}) runs first, so the
|
|
192
|
-
* positionwise walk here never sees an unpaired position from a well-typed
|
|
193
|
-
* OR an untyped caller.
|
|
194
|
-
*/
|
|
195
91
|
function assertRosterAgreement(source: FaceData, target: FaceData, statement: Statement): void {
|
|
196
92
|
source.projection.forEach(function agreeAt(fieldName, position) {
|
|
197
93
|
const targetField = target.projection[position]
|
|
@@ -217,7 +113,12 @@ function assertRosterAgreement(source: FaceData, target: FaceData, statement: St
|
|
|
217
113
|
* checked against `R`'s field block in the type, and the tuple is carried
|
|
218
114
|
* in the returned value's type ({@link KeyStatement}) — keyed point reads
|
|
219
115
|
* through THIS statement are typed field-for-field, descriptors resolvable
|
|
220
|
-
* through the owner's schema type.
|
|
116
|
+
* through the owner's schema type. A DUPLICATE field in the projection is
|
|
117
|
+
* refused here, at the mint (the engine's `FieldSet` refuses the same
|
|
118
|
+
* duplicate at `Db.create`; canonical utterance says the twice-spelled
|
|
119
|
+
* field is the once-spelled projection respelled) — without this wall a
|
|
120
|
+
* `new Set`-collapsed duplicate could set-match a shorter target
|
|
121
|
+
* projection the engine refuses.
|
|
221
122
|
*/
|
|
222
123
|
function key<
|
|
223
124
|
R extends AnyRelation,
|
|
@@ -228,6 +129,15 @@ function key<
|
|
|
228
129
|
`key(${relation.name}, ...): closedness already materializes ${relation.name}(id) -> ${relation.name} — an explicit key on a closed relation is rejected as a duplicate`
|
|
229
130
|
)
|
|
230
131
|
}
|
|
132
|
+
const seen = new Set<string>()
|
|
133
|
+
for (const fieldName of fields) {
|
|
134
|
+
if (seen.has(fieldName)) {
|
|
135
|
+
throw errors.new(
|
|
136
|
+
`key(${relation.name}, ...): the projection spells ${fieldName} twice — write it once (the canonical-utterance law: one meaning, one spelling)`
|
|
137
|
+
)
|
|
138
|
+
}
|
|
139
|
+
seen.add(fieldName)
|
|
140
|
+
}
|
|
231
141
|
const data: KeyData<R, Projection> = Object.freeze({
|
|
232
142
|
kind: "key",
|
|
233
143
|
owner: relation,
|
|
@@ -236,15 +146,6 @@ function key<
|
|
|
236
146
|
return Object.freeze({ data, [admitted]: true as const })
|
|
237
147
|
}
|
|
238
148
|
|
|
239
|
-
/**
|
|
240
|
-
* `A(X|φ) <= B(Y|ψ)` — conditional inclusion, source left. Arity mismatch
|
|
241
|
-
* between the two faces is a type error ({@link SameArity}); a structurally
|
|
242
|
-
* mismatched pair is a type error ({@link SameShapes} — positionwise
|
|
243
|
-
* equality of the projected kind/width/element triples). The target side
|
|
244
|
-
* must resolve a declared key of B — a SEMANTIC property of the whole
|
|
245
|
-
* statement set that no face type can state, DELIBERATELY judged by the
|
|
246
|
-
* engine at `Db.create`/`Db.open` (`SchemaError`), never re-checked here.
|
|
247
|
-
*/
|
|
248
149
|
function contained<A extends AnyFace, B extends AnyFace>(
|
|
249
150
|
source: A,
|
|
250
151
|
target: B & SameArity<A, B> & SameShapes<A, B>
|
|
@@ -260,15 +161,6 @@ function contained<A extends AnyFace, B extends AnyFace>(
|
|
|
260
161
|
return statement
|
|
261
162
|
}
|
|
262
163
|
|
|
263
|
-
/**
|
|
264
|
-
* `A(X|φ) == B(Y|ψ)` — the bidirectional abbreviation, one utterance: the
|
|
265
|
-
* selected `==` bijection, a keyed one-to-one correspondence between the
|
|
266
|
-
* two faces (each side contains the other). It lowers to the two adjacent
|
|
267
|
-
* containments in the `A <= B` first order (macro parity — the engine
|
|
268
|
-
* performs the split, source-first) and renders as `==` once, in the
|
|
269
|
-
* written orientation. Faces pair by arity AND structural shape, exactly
|
|
270
|
-
* as {@link contained}.
|
|
271
|
-
*/
|
|
272
164
|
function mirrors<A extends AnyFace, B extends AnyFace>(
|
|
273
165
|
source: A,
|
|
274
166
|
target: B & SameArity<A, B> & SameShapes<A, B>
|
|
@@ -284,14 +176,6 @@ function mirrors<A extends AnyFace, B extends AnyFace>(
|
|
|
284
176
|
return statement
|
|
285
177
|
}
|
|
286
178
|
|
|
287
|
-
/**
|
|
288
|
-
* The runtime twin of the weight source wall ({@link WeightOnSource}): the
|
|
289
|
-
* weighed field must be a u64-encoded position of the SOURCE's own row
|
|
290
|
-
* (a signed weight would break the polarity scheduler — the illegal weight
|
|
291
|
-
* is unrepresentable, not checked), an interval position for the
|
|
292
|
-
* `Duration(...)` form. Judged at CONSTRUCTION for untyped callers; the
|
|
293
|
-
* engine's `validate_capacity` stays the final authority.
|
|
294
|
-
*/
|
|
295
179
|
function assertWeightOnSource(weight: WeightSpec, source: FaceData, statement: Statement): void {
|
|
296
180
|
if (weight.kind === "unit") {
|
|
297
181
|
return
|
|
@@ -314,14 +198,6 @@ function assertWeightOnSource(weight: WeightSpec, source: FaceData, statement: S
|
|
|
314
198
|
}
|
|
315
199
|
}
|
|
316
200
|
|
|
317
|
-
/**
|
|
318
|
-
* The runtime twin of the dependent-bound target wall
|
|
319
|
-
* ({@link BoundsOnTarget}): a `ref()` bound must name a u64 field of the
|
|
320
|
-
* TARGET's own row, a `duration()` bound an interval field — bound names
|
|
321
|
-
* resolve against the target's FULL roster (C1), never the projection.
|
|
322
|
-
* `within()` mints dependent bounds in the hi slot only (C6), but the walk
|
|
323
|
-
* here is total over the window's bound slots.
|
|
324
|
-
*/
|
|
325
201
|
function assertBoundsOnTarget(window: CapacityWindowSpec, target: FaceData, statement: Statement): void {
|
|
326
202
|
const bounds = window.kind === "range" ? [window.lo, window.hi] : [window.kind === "exact" ? window.n : window.lo]
|
|
327
203
|
for (const bound of bounds) {
|
|
@@ -347,26 +223,6 @@ function assertBoundsOnTarget(window: CapacityWindowSpec, target: FaceData, stat
|
|
|
347
223
|
}
|
|
348
224
|
}
|
|
349
225
|
|
|
350
|
-
/**
|
|
351
|
-
* `B(Y|ψ) <=[w]{window} A(X|φ)` — the capacity statement, the one
|
|
352
|
-
* extension form: per ψ-selected target fact, the group of φ-selected
|
|
353
|
-
* source facts sharing its key tuple must have its MEASURE (Σ weight; the
|
|
354
|
-
* unit weight IS the count instance) inside the window. READ CAREFULLY:
|
|
355
|
-
* the LEFT face is the TARGET, the per-group parent (B-family, target-left
|
|
356
|
-
* — macro parity), and the RIGHT face is the weighed source. Two
|
|
357
|
-
* overloads mirror the operator positionally (target, weight?, window,
|
|
358
|
-
* source): `capacity(on(Holder, "id"), within(0n, 3n), on(Account,
|
|
359
|
-
* "holder"))` says each Holder id groups at most three Account rows;
|
|
360
|
-
* `capacity(on(Pool, "id"), weigh("watts"), within(0n, ref("supply")),
|
|
361
|
-
* on(Device, "pool"))` bounds each pool's summed draw by the pool's own
|
|
362
|
-
* row. The two faces pair by arity AND structural shape
|
|
363
|
-
* ({@link SameShapes}), exactly as containment — the grouping join reads
|
|
364
|
-
* the same positionwise field pairing. The weight-sensitive bans ride the
|
|
365
|
-
* UNIT overload only: `{1..*}` ({@link UnitWindowBan} — on a weighted
|
|
366
|
-
* statement "positive total" is a different, weaker law than containment)
|
|
367
|
-
* and the `duration()` bound ({@link UnitDimensionBan} — a count of facts
|
|
368
|
-
* bounded by a span of time mixes dimensions, C18).
|
|
369
|
-
*/
|
|
370
226
|
function capacity<B extends AnyFace, W extends CapacityWindow, A extends AnyFace>(
|
|
371
227
|
target: B,
|
|
372
228
|
window: W & UnitWindowBan<W> & UnitDimensionBan<W> & BoundsOnTarget<W, B>,
|
|
@@ -407,10 +263,14 @@ function capacity(
|
|
|
407
263
|
"`{1..*}` on the unit instance says only what the bare containment says — drop the annotation and write the containment: contained(source, target)"
|
|
408
264
|
)
|
|
409
265
|
}
|
|
410
|
-
|
|
266
|
+
if (weight.kind === "unit" && window.kind === "floor") {
|
|
267
|
+
throw errors.new(
|
|
268
|
+
"`{N..*}` on the unit instance — a bare count floor is refused; weigh the source (`<=[w]{N..*}` stays legal) or drop the bound"
|
|
269
|
+
)
|
|
270
|
+
}
|
|
271
|
+
|
|
411
272
|
// CapacityDimensionMixing twin — ruled 2026-07-24): a count of facts
|
|
412
|
-
|
|
413
|
-
// callers; the engine's validate_capacity stays the final authority.
|
|
273
|
+
|
|
414
274
|
if (weight.kind === "unit" && window.kind === "range" && window.hi.kind === "durationField") {
|
|
415
275
|
throw errors.new(
|
|
416
276
|
`a unit (count) window against the duration() bound on ${window.hi.field} mixes dimensions (C18) — weigh the source with weigh(duration(field)), or bound by a u64 field or literal`
|
|
@@ -431,18 +291,6 @@ function capacity(
|
|
|
431
291
|
return statement
|
|
432
292
|
}
|
|
433
293
|
|
|
434
|
-
/**
|
|
435
|
-
* Renders one statement in the CANONICAL macro spelling
|
|
436
|
-
* (`docs/architecture/70-api.md`; the engine's `schema/render.rs` emits the
|
|
437
|
-
* same shapes for violations) — `Account(id) -> Account`,
|
|
438
|
-
* `Account(holder) <= Holder(id)`,
|
|
439
|
-
* `Account(id | kind == Savings) == SavingsTerms(account)`,
|
|
440
|
-
* `Holder(id) <={0..3} Account(holder)`,
|
|
441
|
-
* `Pool(id) <=[watts]{0..supply} Device(pool)` — so TS-side errors and
|
|
442
|
-
* engine-side diagnostics read identically. A renderer, never a parser:
|
|
443
|
-
* strings are output-only. The unit weight renders nothing — the count
|
|
444
|
-
* utterance falls out of the one printer.
|
|
445
|
-
*/
|
|
446
294
|
function renderStatement(statement: Statement): string {
|
|
447
295
|
const data = statement.data
|
|
448
296
|
switch (data.kind) {
|
package/dist/exhume.d.ts
DELETED
|
@@ -1,143 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* The exhume surface — the SDK's ONE schema-independent read path
|
|
3
|
-
* (docs/course-serialization/prd-02-sdk-exhume-surface.md; engine
|
|
4
|
-
* 70-api.md § exhume): a read-only, theory-less open returning the store's
|
|
5
|
-
* SELF-DESCRIBED relation shapes and raw facts by relation name. The
|
|
6
|
-
* sighting it exists for: a run store whose creating schema has since
|
|
7
|
-
* evolved — the record outlives the schema, and exhume is how the record
|
|
8
|
-
* is read back for rebirth (exhume the old store, create the successor
|
|
9
|
-
* under the new theory, copy by NAME, re-derive).
|
|
10
|
-
*
|
|
11
|
-
* DELIBERATELY SCHEMA-FREE: no schema type appears anywhere on this
|
|
12
|
-
* surface. The caller's schema is the wrong theory for an exhumed store BY
|
|
13
|
-
* DEFINITION (a store the current theory could open would never need
|
|
14
|
-
* exhuming), so every value crosses TYPED at its bare structural form
|
|
15
|
-
* ({@link FactValue} — bigint/string/boolean/bytes/interval, never
|
|
16
|
-
* `unknown`) and every fact is keyed by field NAME. The SDK never
|
|
17
|
-
* reconstructs a `Schema` value from the descriptor — that inverse mapping
|
|
18
|
-
* is deliberately out of scope; the rebirth tool keys by name.
|
|
19
|
-
*
|
|
20
|
-
* LIFETIMES ARE DISPOSABLES, never `close()` (ruled 2026-07-23, R12): the
|
|
21
|
-
* `Exhumed` value implements `Symbol.dispose` — teardown is synchronous
|
|
22
|
-
* (one environment close) — and `using` is the documented idiom:
|
|
23
|
-
*
|
|
24
|
-
* using exhumed = await Db.exhume(path)
|
|
25
|
-
*
|
|
26
|
-
* Disposal releases the engine handle AND the store's exclusive advisory
|
|
27
|
-
* lock deterministically, scope-shaped in the language's own syntax, so a
|
|
28
|
-
* same-path reopen (retry after a half-failed migration, a second forensic
|
|
29
|
-
* read) never waits on an unforceable GC finalizer. Every verb after
|
|
30
|
-
* disposal is a typed used-after-dispose refusal. The engine-side drop
|
|
31
|
-
* remains the reclamation-only backstop for a collected-but-undisposed
|
|
32
|
-
* value; the store is never written through this surface, so there is
|
|
33
|
-
* nothing to flush.
|
|
34
|
-
*/
|
|
35
|
-
import type { FactValue } from "./native.js";
|
|
36
|
-
import type { ValueTypeSpec } from "./spec.js";
|
|
37
|
-
/**
|
|
38
|
-
* The typed `descriptorMissing` refusal: the store predates self-describing
|
|
39
|
-
* stores and has not been adopted. The remedy is in the message — one
|
|
40
|
-
* fingerprint-matching `Db.open` under the creating schema back-fills the
|
|
41
|
-
* descriptor (engine 50-storage.md § the `_meta` block) and the store is
|
|
42
|
-
* self-describing forever. Match with `errors.is`.
|
|
43
|
-
*/
|
|
44
|
-
declare const ErrExhumeNoDescriptor: Error;
|
|
45
|
-
/**
|
|
46
|
-
* The typed `formatMismatch` refusal: the store's on-disk format version is
|
|
47
|
-
* not this engine's (no migration path exists, as everywhere). Match with
|
|
48
|
-
* `errors.is`.
|
|
49
|
-
*/
|
|
50
|
-
declare const ErrExhumeFormatMismatch: Error;
|
|
51
|
-
/**
|
|
52
|
-
* The typed `corruption` refusal: the persisted descriptor fails its
|
|
53
|
-
* integrity gates (the stored bytes hash to something other than the stored
|
|
54
|
-
* fingerprint, or the bytes do not decode and re-encode faithfully). Match
|
|
55
|
-
* with `errors.is`.
|
|
56
|
-
*/
|
|
57
|
-
declare const ErrExhumeCorruption: Error;
|
|
58
|
-
/**
|
|
59
|
-
* One exhumed fact as a plain name-keyed record of bare structural values
|
|
60
|
-
* — deliberately schema-free (module doc): `bigint` for u64/i64, `string`
|
|
61
|
-
* for str, `boolean` for bool, `Uint8Array` for bytes<N>, a `{ start, end }`
|
|
62
|
-
* bigint pair for intervals. Closed-relation rows open with the synthetic
|
|
63
|
-
* `id` field, exactly as the descriptor's sealed field list declares.
|
|
64
|
-
*/
|
|
65
|
-
type ExhumedFact = Readonly<Record<string, FactValue>>;
|
|
66
|
-
/**
|
|
67
|
-
* One field of an exhumed relation, exactly as the store's creator declared
|
|
68
|
-
* it: the name and the structural type tag (byte width on `fixedBytes`,
|
|
69
|
-
* element and optional width on `interval`).
|
|
70
|
-
*/
|
|
71
|
-
interface ExhumedField {
|
|
72
|
-
readonly name: string;
|
|
73
|
-
readonly valueType: ValueTypeSpec;
|
|
74
|
-
}
|
|
75
|
-
/**
|
|
76
|
-
* One ground axiom of an exhumed closed relation: the handle (the row's
|
|
77
|
-
* identity, never a column), the declaration-order row id, and the declared
|
|
78
|
-
* payload columns by name.
|
|
79
|
-
*/
|
|
80
|
-
interface ExhumedAxiom {
|
|
81
|
-
readonly handle: string;
|
|
82
|
-
readonly id: bigint;
|
|
83
|
-
readonly values: ExhumedFact;
|
|
84
|
-
}
|
|
85
|
-
/**
|
|
86
|
-
* One relation of an exhumed store: the name, the SEALED field list in
|
|
87
|
-
* declaration order (a closed relation opens with the synthetic (`id`,
|
|
88
|
-
* u64) handle field), and — exactly on closed relations — the roster of
|
|
89
|
-
* ground axioms. Scan rows come back in this field order, so pairing a
|
|
90
|
-
* row's positions against `fields` is the name-keyed reading `scan`
|
|
91
|
-
* performs.
|
|
92
|
-
*/
|
|
93
|
-
interface ExhumedRelation {
|
|
94
|
-
readonly name: string;
|
|
95
|
-
readonly fields: readonly ExhumedField[];
|
|
96
|
-
readonly roster: readonly ExhumedAxiom[] | undefined;
|
|
97
|
-
}
|
|
98
|
-
/**
|
|
99
|
-
* The exhumed store's schema as declared, decoded from the store's own
|
|
100
|
-
* persisted descriptor: relations in engine-id order (declaration order
|
|
101
|
-
* mints every id), each with its ordered field descriptions and closed
|
|
102
|
-
* roster — enough for a caller to key facts by name and re-insert them
|
|
103
|
-
* into a differently-fingerprinted successor store. No schema type appears
|
|
104
|
-
* here (module doc: the surface is schema-free; rows are typed bare).
|
|
105
|
-
*/
|
|
106
|
-
interface ExhumedDescriptor {
|
|
107
|
-
readonly relations: readonly ExhumedRelation[];
|
|
108
|
-
}
|
|
109
|
-
/**
|
|
110
|
-
* One exhumed store: the self-described relation shapes and the raw facts
|
|
111
|
-
* by relation name. Read-only by construction — no write verb, no prepare
|
|
112
|
-
* verb. A DISPOSABLE lifetime (R12): `Symbol.dispose` releases the engine
|
|
113
|
-
* handle and the store's exclusive lock deterministically; `using` is the
|
|
114
|
-
* idiom, and a disposed value's verbs are typed refusals.
|
|
115
|
-
*/
|
|
116
|
-
interface Exhumed extends Disposable {
|
|
117
|
-
/** The store's own persisted schema, as its creator declared it. */
|
|
118
|
-
readonly descriptor: ExhumedDescriptor;
|
|
119
|
-
/**
|
|
120
|
-
* Full-relation export in row-id order, each row decoded per the
|
|
121
|
-
* STORED descriptor to a name-keyed record of natural values (str
|
|
122
|
-
* resolved through the engine's `_dict` before crossing; a closed
|
|
123
|
-
* relation scans its sealed roster). Each call reads one consistent
|
|
124
|
-
* snapshot. An unknown relation name is a typed error — the
|
|
125
|
-
* descriptor is the caller's roster.
|
|
126
|
-
*/
|
|
127
|
-
scan(relation: string): readonly ExhumedFact[];
|
|
128
|
-
}
|
|
129
|
-
/**
|
|
130
|
-
* Opens one exhumed store at an ALREADY-CANONICAL path (`Db.exhume` is the
|
|
131
|
-
* public spelling — the path law lives in db.ts beside `open`/`create`).
|
|
132
|
-
* The bridge's three domain refusals become the typed error constants
|
|
133
|
-
* ({@link ErrExhumeNoDescriptor}, {@link ErrExhumeFormatMismatch},
|
|
134
|
-
* {@link ErrExhumeCorruption}), each carrying the engine's message in its
|
|
135
|
-
* wrap. The returned value is NOT cached: exhume is a forensic read whose
|
|
136
|
-
* lifetime is the caller's `using` scope — disposal releases the store's
|
|
137
|
-
* exclusive lock deterministically (R12), so the path is reusable the
|
|
138
|
-
* moment the scope exits.
|
|
139
|
-
*/
|
|
140
|
-
declare function exhumeStore(canonical: string): Exhumed;
|
|
141
|
-
export type { Exhumed, ExhumedAxiom, ExhumedDescriptor, ExhumedFact, ExhumedField, ExhumedRelation };
|
|
142
|
-
export { ErrExhumeCorruption, ErrExhumeFormatMismatch, ErrExhumeNoDescriptor, exhumeStore };
|
|
143
|
-
//# sourceMappingURL=exhume.d.ts.map
|
package/dist/exhume.d.ts.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"exhume.d.ts","sourceRoot":"","sources":["../src/exhume.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiCG;AAGH,OAAO,KAAK,EAAE,SAAS,EAAY,MAAM,YAAY,CAAA;AAErD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,UAAU,CAAA;AAE7C;;;;;;GAMG;AACH,QAAA,MAAM,qBAAqB,OAE1B,CAAA;AAED;;;;GAIG;AACH,QAAA,MAAM,uBAAuB,OAE5B,CAAA;AAED;;;;;GAKG;AACH,QAAA,MAAM,mBAAmB,OAA2F,CAAA;AAEpH;;;;;;GAMG;AACH,KAAK,WAAW,GAAG,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,SAAS,CAAC,CAAC,CAAA;AAEtD;;;;GAIG;AACH,UAAU,YAAY;IACrB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;IACrB,QAAQ,CAAC,SAAS,EAAE,aAAa,CAAA;CACjC;AAED;;;;GAIG;AACH,UAAU,YAAY;IACrB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;IACvB,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAA;IACnB,QAAQ,CAAC,MAAM,EAAE,WAAW,CAAA;CAC5B;AAED;;;;;;;GAOG;AACH,UAAU,eAAe;IACxB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;IACrB,QAAQ,CAAC,MAAM,EAAE,SAAS,YAAY,EAAE,CAAA;IACxC,QAAQ,CAAC,MAAM,EAAE,SAAS,YAAY,EAAE,GAAG,SAAS,CAAA;CACpD;AAED;;;;;;;GAOG;AACH,UAAU,iBAAiB;IAC1B,QAAQ,CAAC,SAAS,EAAE,SAAS,eAAe,EAAE,CAAA;CAC9C;AAED;;;;;;GAMG;AACH,UAAU,OAAQ,SAAQ,UAAU;IACnC,oEAAoE;IACpE,QAAQ,CAAC,UAAU,EAAE,iBAAiB,CAAA;IACtC;;;;;;;OAOG;IACH,IAAI,CAAC,QAAQ,EAAE,MAAM,GAAG,SAAS,WAAW,EAAE,CAAA;CAC9C;AA+BD;;;;;;;;;;GAUG;AACH,iBAAS,WAAW,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CA8E/C;AAED,YAAY,EAAE,OAAO,EAAE,YAAY,EAAE,iBAAiB,EAAE,WAAW,EAAE,YAAY,EAAE,eAAe,EAAE,CAAA;AACpG,OAAO,EAAE,mBAAmB,EAAE,uBAAuB,EAAE,qBAAqB,EAAE,WAAW,EAAE,CAAA"}
|
package/dist/exhume.js
DELETED
|
@@ -1,166 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* The exhume surface — the SDK's ONE schema-independent read path
|
|
3
|
-
* (docs/course-serialization/prd-02-sdk-exhume-surface.md; engine
|
|
4
|
-
* 70-api.md § exhume): a read-only, theory-less open returning the store's
|
|
5
|
-
* SELF-DESCRIBED relation shapes and raw facts by relation name. The
|
|
6
|
-
* sighting it exists for: a run store whose creating schema has since
|
|
7
|
-
* evolved — the record outlives the schema, and exhume is how the record
|
|
8
|
-
* is read back for rebirth (exhume the old store, create the successor
|
|
9
|
-
* under the new theory, copy by NAME, re-derive).
|
|
10
|
-
*
|
|
11
|
-
* DELIBERATELY SCHEMA-FREE: no schema type appears anywhere on this
|
|
12
|
-
* surface. The caller's schema is the wrong theory for an exhumed store BY
|
|
13
|
-
* DEFINITION (a store the current theory could open would never need
|
|
14
|
-
* exhuming), so every value crosses TYPED at its bare structural form
|
|
15
|
-
* ({@link FactValue} — bigint/string/boolean/bytes/interval, never
|
|
16
|
-
* `unknown`) and every fact is keyed by field NAME. The SDK never
|
|
17
|
-
* reconstructs a `Schema` value from the descriptor — that inverse mapping
|
|
18
|
-
* is deliberately out of scope; the rebirth tool keys by name.
|
|
19
|
-
*
|
|
20
|
-
* LIFETIMES ARE DISPOSABLES, never `close()` (ruled 2026-07-23, R12): the
|
|
21
|
-
* `Exhumed` value implements `Symbol.dispose` — teardown is synchronous
|
|
22
|
-
* (one environment close) — and `using` is the documented idiom:
|
|
23
|
-
*
|
|
24
|
-
* using exhumed = await Db.exhume(path)
|
|
25
|
-
*
|
|
26
|
-
* Disposal releases the engine handle AND the store's exclusive advisory
|
|
27
|
-
* lock deterministically, scope-shaped in the language's own syntax, so a
|
|
28
|
-
* same-path reopen (retry after a half-failed migration, a second forensic
|
|
29
|
-
* read) never waits on an unforceable GC finalizer. Every verb after
|
|
30
|
-
* disposal is a typed used-after-dispose refusal. The engine-side drop
|
|
31
|
-
* remains the reclamation-only backstop for a collected-but-undisposed
|
|
32
|
-
* value; the store is never written through this surface, so there is
|
|
33
|
-
* nothing to flush.
|
|
34
|
-
*/
|
|
35
|
-
import * as errors from "@superbuilders/errors";
|
|
36
|
-
import { bridged, native } from "#native.ts";
|
|
37
|
-
/**
|
|
38
|
-
* The typed `descriptorMissing` refusal: the store predates self-describing
|
|
39
|
-
* stores and has not been adopted. The remedy is in the message — one
|
|
40
|
-
* fingerprint-matching `Db.open` under the creating schema back-fills the
|
|
41
|
-
* descriptor (engine 50-storage.md § the `_meta` block) and the store is
|
|
42
|
-
* self-describing forever. Match with `errors.is`.
|
|
43
|
-
*/
|
|
44
|
-
const ErrExhumeNoDescriptor = errors.new("bumbledb exhume: the store carries no schema descriptor (not yet adopted) — open it once under its creating schema (one fingerprint-matching Db.open back-fills the descriptor; engine 50-storage.md)");
|
|
45
|
-
/**
|
|
46
|
-
* The typed `formatMismatch` refusal: the store's on-disk format version is
|
|
47
|
-
* not this engine's (no migration path exists, as everywhere). Match with
|
|
48
|
-
* `errors.is`.
|
|
49
|
-
*/
|
|
50
|
-
const ErrExhumeFormatMismatch = errors.new("bumbledb exhume: storage format version mismatch — the store was written by a different engine format");
|
|
51
|
-
/**
|
|
52
|
-
* The typed `corruption` refusal: the persisted descriptor fails its
|
|
53
|
-
* integrity gates (the stored bytes hash to something other than the stored
|
|
54
|
-
* fingerprint, or the bytes do not decode and re-encode faithfully). Match
|
|
55
|
-
* with `errors.is`.
|
|
56
|
-
*/
|
|
57
|
-
const ErrExhumeCorruption = errors.new("bumbledb exhume: the persisted schema descriptor fails its integrity gates");
|
|
58
|
-
/**
|
|
59
|
-
* Shapes the bridge's manifest rendering of the stored descriptor into the
|
|
60
|
-
* SDK's {@link ExhumedDescriptor}: same relations in the same engine-id
|
|
61
|
-
* order, extension rows re-keyed by column name. Pure reshaping — no
|
|
62
|
-
* re-validation of engine-decoded values happens here (the bridge stays
|
|
63
|
-
* dumb and so does this).
|
|
64
|
-
*/
|
|
65
|
-
function descriptorOf(manifest) {
|
|
66
|
-
const relations = manifest.relations.map(function relationOf(relation) {
|
|
67
|
-
const fields = relation.fields.map(function fieldOf(field) {
|
|
68
|
-
return Object.freeze({ name: field.name, valueType: field.valueType });
|
|
69
|
-
});
|
|
70
|
-
let roster;
|
|
71
|
-
if (relation.extension !== undefined) {
|
|
72
|
-
roster = Object.freeze(relation.extension.map(function axiomOf(row) {
|
|
73
|
-
const values = {};
|
|
74
|
-
for (const cell of row.values) {
|
|
75
|
-
values[cell.name] = cell.value;
|
|
76
|
-
}
|
|
77
|
-
return Object.freeze({ handle: row.handle, id: row.id, values: Object.freeze(values) });
|
|
78
|
-
}));
|
|
79
|
-
}
|
|
80
|
-
return Object.freeze({ name: relation.name, fields: Object.freeze(fields), roster });
|
|
81
|
-
});
|
|
82
|
-
return Object.freeze({ relations: Object.freeze(relations) });
|
|
83
|
-
}
|
|
84
|
-
/**
|
|
85
|
-
* Opens one exhumed store at an ALREADY-CANONICAL path (`Db.exhume` is the
|
|
86
|
-
* public spelling — the path law lives in db.ts beside `open`/`create`).
|
|
87
|
-
* The bridge's three domain refusals become the typed error constants
|
|
88
|
-
* ({@link ErrExhumeNoDescriptor}, {@link ErrExhumeFormatMismatch},
|
|
89
|
-
* {@link ErrExhumeCorruption}), each carrying the engine's message in its
|
|
90
|
-
* wrap. The returned value is NOT cached: exhume is a forensic read whose
|
|
91
|
-
* lifetime is the caller's `using` scope — disposal releases the store's
|
|
92
|
-
* exclusive lock deterministically (R12), so the path is reusable the
|
|
93
|
-
* moment the scope exits.
|
|
94
|
-
*/
|
|
95
|
-
function exhumeStore(canonical) {
|
|
96
|
-
const outcome = bridged(`exhume bumbledb store at ${canonical}`, function callExhume() {
|
|
97
|
-
return native.dbExhume(canonical);
|
|
98
|
-
});
|
|
99
|
-
if (!outcome.ok) {
|
|
100
|
-
switch (outcome.kind) {
|
|
101
|
-
case "descriptorMissing":
|
|
102
|
-
throw errors.wrap(ErrExhumeNoDescriptor, `exhume ${canonical}: ${outcome.message}`);
|
|
103
|
-
case "formatMismatch":
|
|
104
|
-
throw errors.wrap(ErrExhumeFormatMismatch, `exhume ${canonical}: ${outcome.message}`);
|
|
105
|
-
case "corruption":
|
|
106
|
-
throw errors.wrap(ErrExhumeCorruption, `exhume ${canonical}: ${outcome.message}`);
|
|
107
|
-
}
|
|
108
|
-
}
|
|
109
|
-
const handle = outcome.exhume;
|
|
110
|
-
const manifest = bridged("read bumbledb exhumed descriptor", function callDescriptor() {
|
|
111
|
-
return native.exhumeDescriptor(handle);
|
|
112
|
-
});
|
|
113
|
-
const descriptor = descriptorOf(manifest);
|
|
114
|
-
const fieldNames = new Map();
|
|
115
|
-
for (const relation of descriptor.relations) {
|
|
116
|
-
fieldNames.set(relation.name, relation.fields.map(function nameOf(field) {
|
|
117
|
-
return field.name;
|
|
118
|
-
}));
|
|
119
|
-
}
|
|
120
|
-
/** The lifetime record: flipped once by {@link dispose}, judged by every verb. */
|
|
121
|
-
const lifetime = { live: true };
|
|
122
|
-
/**
|
|
123
|
-
* The `Symbol.dispose` teardown (R12): idempotent — a manual call inside
|
|
124
|
-
* a `using` scope must not double-close — and deterministic: the engine
|
|
125
|
-
* handle and the store's exclusive lock release HERE, never on a GC
|
|
126
|
-
* schedule.
|
|
127
|
-
*/
|
|
128
|
-
function dispose() {
|
|
129
|
-
if (!lifetime.live) {
|
|
130
|
-
return;
|
|
131
|
-
}
|
|
132
|
-
lifetime.live = false;
|
|
133
|
-
bridged(`close bumbledb exhumed store at ${canonical}`, function close() {
|
|
134
|
-
native.exhumeClose(handle);
|
|
135
|
-
});
|
|
136
|
-
}
|
|
137
|
-
function scan(relation) {
|
|
138
|
-
if (!lifetime.live) {
|
|
139
|
-
throw errors.new("bumbledb exhumed store is disposed — its using scope already exited");
|
|
140
|
-
}
|
|
141
|
-
const names = fieldNames.get(relation);
|
|
142
|
-
if (names === undefined) {
|
|
143
|
-
throw errors.new(`bumbledb exhume: the store's descriptor declares no relation ${relation}`);
|
|
144
|
-
}
|
|
145
|
-
const rows = bridged(`scan bumbledb exhumed relation ${relation}`, function callScan() {
|
|
146
|
-
return native.exhumeScan(handle, relation);
|
|
147
|
-
});
|
|
148
|
-
return Object.freeze(rows.map(function factOf(row) {
|
|
149
|
-
if (row.length !== names.length) {
|
|
150
|
-
throw errors.new(`bumbledb exhume drift: relation ${relation} row arity ${row.length} does not match the ${names.length} descriptor fields`);
|
|
151
|
-
}
|
|
152
|
-
const fact = {};
|
|
153
|
-
names.forEach(function pair(name, index) {
|
|
154
|
-
const cell = row[index];
|
|
155
|
-
if (cell === undefined) {
|
|
156
|
-
throw errors.new(`bumbledb exhume drift: relation ${relation} row has no value at position ${index} (${name})`);
|
|
157
|
-
}
|
|
158
|
-
fact[name] = cell;
|
|
159
|
-
});
|
|
160
|
-
return Object.freeze(fact);
|
|
161
|
-
}));
|
|
162
|
-
}
|
|
163
|
-
return Object.freeze({ descriptor, scan, [Symbol.dispose]: dispose });
|
|
164
|
-
}
|
|
165
|
-
export { ErrExhumeCorruption, ErrExhumeFormatMismatch, ErrExhumeNoDescriptor, exhumeStore };
|
|
166
|
-
//# sourceMappingURL=exhume.js.map
|
package/dist/exhume.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"exhume.js","sourceRoot":"","sources":["../src/exhume.ts"],"names":[],"mappings":"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"}
|