@bjornpagen/bumbledb 0.1.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/LICENSE +12 -0
- package/README.md +84 -0
- package/dist/brand.d.ts +59 -0
- package/dist/brand.d.ts.map +1 -0
- package/dist/brand.js +47 -0
- package/dist/brand.js.map +1 -0
- package/dist/closed.d.ts +97 -0
- package/dist/closed.d.ts.map +1 -0
- package/dist/closed.js +107 -0
- package/dist/closed.js.map +1 -0
- package/dist/count.d.ts +55 -0
- package/dist/count.d.ts.map +1 -0
- package/dist/count.js +92 -0
- package/dist/count.js.map +1 -0
- package/dist/db.d.ts +341 -0
- package/dist/db.d.ts.map +1 -0
- package/dist/db.js +1016 -0
- package/dist/db.js.map +1 -0
- package/dist/exhume.d.ts +130 -0
- package/dist/exhume.d.ts.map +1 -0
- package/dist/exhume.js +145 -0
- package/dist/exhume.js.map +1 -0
- package/dist/face.d.ts +91 -0
- package/dist/face.d.ts.map +1 -0
- package/dist/face.js +69 -0
- package/dist/face.js.map +1 -0
- package/dist/fields.d.ts +187 -0
- package/dist/fields.d.ts.map +1 -0
- package/dist/fields.js +204 -0
- package/dist/fields.js.map +1 -0
- package/dist/index.d.ts +49 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +31 -0
- package/dist/index.js.map +1 -0
- package/dist/lower.d.ts +34 -0
- package/dist/lower.d.ts.map +1 -0
- package/dist/lower.js +105 -0
- package/dist/lower.js.map +1 -0
- package/dist/marshal.d.ts +79 -0
- package/dist/marshal.d.ts.map +1 -0
- package/dist/marshal.js +167 -0
- package/dist/marshal.js.map +1 -0
- package/dist/native.d.ts +532 -0
- package/dist/native.d.ts.map +1 -0
- package/dist/native.js +64 -0
- package/dist/native.js.map +1 -0
- package/dist/query/atom.d.ts +285 -0
- package/dist/query/atom.d.ts.map +1 -0
- package/dist/query/atom.js +281 -0
- package/dist/query/atom.js.map +1 -0
- package/dist/query/lower.d.ts +145 -0
- package/dist/query/lower.d.ts.map +1 -0
- package/dist/query/lower.js +604 -0
- package/dist/query/lower.js.map +1 -0
- package/dist/query/predicate.d.ts +101 -0
- package/dist/query/predicate.d.ts.map +1 -0
- package/dist/query/predicate.js +85 -0
- package/dist/query/predicate.js.map +1 -0
- package/dist/query/run.d.ts +30 -0
- package/dist/query/run.d.ts.map +1 -0
- package/dist/query/run.js +94 -0
- package/dist/query/run.js.map +1 -0
- package/dist/query/scope.d.ts +168 -0
- package/dist/query/scope.d.ts.map +1 -0
- package/dist/query/scope.js +134 -0
- package/dist/query/scope.js.map +1 -0
- package/dist/query/select.d.ts +106 -0
- package/dist/query/select.d.ts.map +1 -0
- package/dist/query/select.js +69 -0
- package/dist/query/select.js.map +1 -0
- package/dist/relation.d.ts +120 -0
- package/dist/relation.d.ts.map +1 -0
- package/dist/relation.js +108 -0
- package/dist/relation.js.map +1 -0
- package/dist/schema.d.ts +50 -0
- package/dist/schema.d.ts.map +1 -0
- package/dist/schema.js +235 -0
- package/dist/schema.js.map +1 -0
- package/dist/spec.d.ts +218 -0
- package/dist/spec.d.ts.map +1 -0
- package/dist/spec.js +154 -0
- package/dist/spec.js.map +1 -0
- package/dist/statements.d.ts +91 -0
- package/dist/statements.d.ts.map +1 -0
- package/dist/statements.js +101 -0
- package/dist/statements.js.map +1 -0
- package/package.json +66 -0
- package/src/brand.ts +82 -0
- package/src/closed.ts +228 -0
- package/src/count.ts +117 -0
- package/src/db.ts +1519 -0
- package/src/exhume.ts +243 -0
- package/src/face.ts +161 -0
- package/src/fields.ts +385 -0
- package/src/index.ts +185 -0
- package/src/lower.ts +118 -0
- package/src/marshal.ts +220 -0
- package/src/native.ts +576 -0
- package/src/query/atom.ts +556 -0
- package/src/query/lower.ts +855 -0
- package/src/query/predicate.ts +195 -0
- package/src/query/run.ts +106 -0
- package/src/query/scope.ts +301 -0
- package/src/query/select.ts +140 -0
- package/src/relation.ts +252 -0
- package/src/schema.ts +297 -0
- package/src/spec.ts +325 -0
- package/src/statements.ts +148 -0
package/dist/schema.js
ADDED
|
@@ -0,0 +1,235 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `schema()` — assembles relations and statements into a theory value (the
|
|
3
|
+
* `Theory` analog; what `Db.create`/`Db.open` take). Construction-time
|
|
4
|
+
* validation is the macro-EXPANSION-boundary analog and nothing more:
|
|
5
|
+
* membership, implied-key duplicates, duplicate statements, and a
|
|
6
|
+
* belt-and-braces handle re-verification. Everything semantically deeper
|
|
7
|
+
* (containment targets resolving declared keys, fresh-on-u64, …) is
|
|
8
|
+
* DELIBERATELY left to the engine's `SchemaError` at `Db.create` — the
|
|
9
|
+
* same judge, the same two-boundary split as Rust.
|
|
10
|
+
*/
|
|
11
|
+
import * as errors from "@superbuilders/errors";
|
|
12
|
+
import { assertDeclarationOrderKey } from "#fields.ts";
|
|
13
|
+
import { renderStatement } from "#statements.ts";
|
|
14
|
+
/**
|
|
15
|
+
* Validates the relation record and collects the implied keys: the
|
|
16
|
+
* fresh-implied `R(field) -> R` per minted field and the closed auto-key
|
|
17
|
+
* `R(id) -> R` per closed relation, each rendered canonically so an
|
|
18
|
+
* explicit duplicate is caught by string identity with the renderer as the
|
|
19
|
+
* single spelling authority.
|
|
20
|
+
*/
|
|
21
|
+
function collectImplied(name, relations) {
|
|
22
|
+
const implied = new Set();
|
|
23
|
+
for (const [recordKey, member] of Object.entries(relations)) {
|
|
24
|
+
assertDeclarationOrderKey(`schema ${name} relation`, recordKey);
|
|
25
|
+
if (member.name !== recordKey) {
|
|
26
|
+
throw errors.new(`schema ${name}: record key ${recordKey} holds relation ${member.name} — the key must equal the relation's declared name`);
|
|
27
|
+
}
|
|
28
|
+
if ("handles" in member.data) {
|
|
29
|
+
implied.add(`${member.name}(id) -> ${member.name}`);
|
|
30
|
+
continue;
|
|
31
|
+
}
|
|
32
|
+
for (const declared of member.data.fields) {
|
|
33
|
+
if (declared.field.minted) {
|
|
34
|
+
implied.add(`${member.name}(${declared.name}) -> ${member.name}`);
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
return implied;
|
|
39
|
+
}
|
|
40
|
+
/** The relation values a statement addresses, for membership checking. */
|
|
41
|
+
function statementOwners(statement) {
|
|
42
|
+
const data = statement.data;
|
|
43
|
+
if (data.kind === "key") {
|
|
44
|
+
return [data.owner];
|
|
45
|
+
}
|
|
46
|
+
return [data.source.owner, data.target.owner];
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* Requires every relation a statement addresses to be the IDENTICAL value
|
|
50
|
+
* the schema record declares — same-name-different-value is a forgery, not
|
|
51
|
+
* a membership.
|
|
52
|
+
*/
|
|
53
|
+
function verifyMembership(name, relations, statement, rendered) {
|
|
54
|
+
for (const owner of statementOwners(statement)) {
|
|
55
|
+
const member = relations[owner.name];
|
|
56
|
+
if (member === undefined) {
|
|
57
|
+
throw errors.new(`schema ${name}: relation ${owner.name} is not declared in this schema — ${rendered}`);
|
|
58
|
+
}
|
|
59
|
+
if (member !== owner) {
|
|
60
|
+
throw errors.new(`schema ${name}: statement references a different relation value named ${owner.name} than the one this schema declares — ${rendered}`);
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
/** Finds a face's field description by name, across both relation kinds. */
|
|
65
|
+
function faceField(face, fieldName) {
|
|
66
|
+
const data = face.owner.data;
|
|
67
|
+
if ("handles" in data) {
|
|
68
|
+
const column = data.columns.find(function byName(candidate) {
|
|
69
|
+
return candidate.name === fieldName;
|
|
70
|
+
});
|
|
71
|
+
return column?.field;
|
|
72
|
+
}
|
|
73
|
+
const declared = data.fields.find(function byName(candidate) {
|
|
74
|
+
return candidate.name === fieldName;
|
|
75
|
+
});
|
|
76
|
+
return declared?.field;
|
|
77
|
+
}
|
|
78
|
+
/** Flattens one binding's literal set into its literals. */
|
|
79
|
+
function bindingLiterals(set) {
|
|
80
|
+
if (set.kind === "one") {
|
|
81
|
+
return [set.literal];
|
|
82
|
+
}
|
|
83
|
+
return set.literals;
|
|
84
|
+
}
|
|
85
|
+
/**
|
|
86
|
+
* Re-verifies one binding's handle literals against the field's roster —
|
|
87
|
+
* belt-and-braces over what `where()` already resolved and the type level
|
|
88
|
+
* already blocked, so a forged binding fails here rather than at the
|
|
89
|
+
* engine boundary with a colder message.
|
|
90
|
+
*/
|
|
91
|
+
function verifyBindingHandles(name, face, binding, rendered) {
|
|
92
|
+
const field = faceField(face, binding.field);
|
|
93
|
+
for (const literal of bindingLiterals(binding.set)) {
|
|
94
|
+
if (literal.kind !== "handle") {
|
|
95
|
+
continue;
|
|
96
|
+
}
|
|
97
|
+
if (field?.closed === undefined) {
|
|
98
|
+
throw errors.new(`schema ${name}: ${face.owner.name}.${binding.field} is not a closed-relation reference — the handle literal ${literal.handle} is legal only on a field whose newtype is a closed relation's handle newtype — ${rendered}`);
|
|
99
|
+
}
|
|
100
|
+
if (!field.closed.handles.includes(literal.handle)) {
|
|
101
|
+
throw errors.new(`schema ${name}: closed relation ${field.closed.name} has no handle ${literal.handle} — ${rendered}`);
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
/** Walks every face of a statement through the handle re-verification. */
|
|
106
|
+
function verifyHandles(name, statement, rendered) {
|
|
107
|
+
const data = statement.data;
|
|
108
|
+
if (data.kind === "key") {
|
|
109
|
+
return;
|
|
110
|
+
}
|
|
111
|
+
for (const face of [data.source, data.target]) {
|
|
112
|
+
for (const binding of face.selection) {
|
|
113
|
+
verifyBindingHandles(name, face, binding, rendered);
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
/**
|
|
118
|
+
* Resolves the closed relation a `(relation, field)` pair references
|
|
119
|
+
* through the DECLARED containments — the identical walk the engine's
|
|
120
|
+
* canonical renderer performs (`schema/render.rs` `closed_target_of`): one
|
|
121
|
+
* hop, source projecting exactly `[field]`, target projecting exactly the
|
|
122
|
+
* closed relation's `[id]`, first declared match wins; a `mirrors`
|
|
123
|
+
* contributes both of its materialized orientations. `undefined` = the
|
|
124
|
+
* engine would render the field's selection literals as raw row ids.
|
|
125
|
+
*/
|
|
126
|
+
function closedTargetOf(statements, owner, field) {
|
|
127
|
+
for (const statement of statements) {
|
|
128
|
+
const data = statement.data;
|
|
129
|
+
if (data.kind !== "containment") {
|
|
130
|
+
continue;
|
|
131
|
+
}
|
|
132
|
+
const pairs = [[data.source, data.target]];
|
|
133
|
+
if (data.bidirectional) {
|
|
134
|
+
pairs.push([data.target, data.source]);
|
|
135
|
+
}
|
|
136
|
+
for (const [source, target] of pairs) {
|
|
137
|
+
if (source.owner.name === owner &&
|
|
138
|
+
source.projection.length === 1 &&
|
|
139
|
+
source.projection[0] === field &&
|
|
140
|
+
target.projection.length === 1 &&
|
|
141
|
+
target.projection[0] === "id" &&
|
|
142
|
+
"handles" in target.owner.data) {
|
|
143
|
+
return target.owner.name;
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
return undefined;
|
|
148
|
+
}
|
|
149
|
+
/**
|
|
150
|
+
* Admits a handle spelling only when the schema also declares the
|
|
151
|
+
* containment the ENGINE's canonical renderer resolves it through
|
|
152
|
+
* (`docs/architecture/10-data-model.md` § closed relations: a closed
|
|
153
|
+
* reference is the plain u64 column PLUS a declared containment). Without
|
|
154
|
+
* it the two renderers drift — `renderStatement` prints the handle name,
|
|
155
|
+
* the engine's violation `canonical` prints the raw row id — and the
|
|
156
|
+
* paste-back law (`violation.canonical === renderStatement(statement)`)
|
|
157
|
+
* breaks. Runs over the COMPLETE statement list, so declaration order
|
|
158
|
+
* never matters. The closed relation's own `id` field resolves directly
|
|
159
|
+
* (the walk's field-0 case).
|
|
160
|
+
*/
|
|
161
|
+
function verifyClosedReferences(name, statements) {
|
|
162
|
+
for (const statement of statements) {
|
|
163
|
+
const data = statement.data;
|
|
164
|
+
if (data.kind === "key") {
|
|
165
|
+
continue;
|
|
166
|
+
}
|
|
167
|
+
const rendered = renderStatement(statement);
|
|
168
|
+
for (const face of [data.source, data.target]) {
|
|
169
|
+
for (const binding of face.selection) {
|
|
170
|
+
verifyClosedReferenceBinding(name, statements, face, binding, rendered);
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
/** One binding's closed-reference resolution check (the {@link verifyClosedReferences} leaf). */
|
|
176
|
+
function verifyClosedReferenceBinding(name, statements, face, binding, rendered) {
|
|
177
|
+
const spellsHandle = bindingLiterals(binding.set).some(function isHandle(literal) {
|
|
178
|
+
return literal.kind === "handle";
|
|
179
|
+
});
|
|
180
|
+
if (!spellsHandle) {
|
|
181
|
+
return;
|
|
182
|
+
}
|
|
183
|
+
const roster = faceField(face, binding.field)?.closed;
|
|
184
|
+
if (roster === undefined) {
|
|
185
|
+
return;
|
|
186
|
+
}
|
|
187
|
+
if ("handles" in face.owner.data && binding.field === "id") {
|
|
188
|
+
return;
|
|
189
|
+
}
|
|
190
|
+
const resolved = closedTargetOf(statements, face.owner.name, binding.field);
|
|
191
|
+
if (resolved !== roster.name) {
|
|
192
|
+
throw errors.new(`schema ${name}: ${face.owner.name}.${binding.field} spells a ${roster.name} handle, but no declared containment resolves the closed reference — a closed reference is the plain u64 column plus its declared containment; declare contained(on(${face.owner.name}, "${binding.field}"), on(${roster.name}, "id")) — ${rendered}`);
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
/**
|
|
196
|
+
* Assembles a theory:
|
|
197
|
+
* `schema("Ledger", { Kind, Account, Holder }, [ ...statements ])`.
|
|
198
|
+
*
|
|
199
|
+
* Rejected here, each with the offending statement rendered canonically:
|
|
200
|
+
* a record key differing from its relation's declared name; a statement
|
|
201
|
+
* whose relation is not (identically) a member of the record; an explicit
|
|
202
|
+
* duplicate of a fresh-implied or closedness-implied key (macro parity:
|
|
203
|
+
* "redundant here — and rejected as a duplicate"); a duplicate statement
|
|
204
|
+
* (two statements rendering to one canonical utterance ARE one judgment);
|
|
205
|
+
* a handle selection that its roster does not hold (belt-and-braces —
|
|
206
|
+
* the type level already blocks it); and a handle selection whose closed
|
|
207
|
+
* reference no declared containment resolves (the engine's canonical
|
|
208
|
+
* renderer would print the raw row id where `renderStatement` prints the
|
|
209
|
+
* handle — the paste-back law demands the two spellings agree).
|
|
210
|
+
*
|
|
211
|
+
* The fresh-implied and closed auto-keys are NOT added to the statement
|
|
212
|
+
* list: the engine materializes them itself, in its own pinned order
|
|
213
|
+
* (`SchemaDescriptor::materialized_statements`), and restating them would
|
|
214
|
+
* double them.
|
|
215
|
+
*/
|
|
216
|
+
function schema(name, relations, statements) {
|
|
217
|
+
const implied = collectImplied(name, relations);
|
|
218
|
+
const seen = new Set();
|
|
219
|
+
for (const statement of statements) {
|
|
220
|
+
const rendered = renderStatement(statement);
|
|
221
|
+
verifyMembership(name, relations, statement, rendered);
|
|
222
|
+
if (implied.has(rendered)) {
|
|
223
|
+
throw errors.new(`schema ${name}: ${rendered} is redundant here (the fresh mark or closedness already implies it) — and rejected as a duplicate`);
|
|
224
|
+
}
|
|
225
|
+
if (seen.has(rendered)) {
|
|
226
|
+
throw errors.new(`schema ${name}: duplicate statement — ${rendered}`);
|
|
227
|
+
}
|
|
228
|
+
seen.add(rendered);
|
|
229
|
+
verifyHandles(name, statement, rendered);
|
|
230
|
+
}
|
|
231
|
+
verifyClosedReferences(name, statements);
|
|
232
|
+
return Object.freeze({ name, relations, statements: Object.freeze([...statements]) });
|
|
233
|
+
}
|
|
234
|
+
export { schema };
|
|
235
|
+
//# sourceMappingURL=schema.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"schema.js","sourceRoot":"","sources":["../src/schema.ts"],"names":[],"mappings":"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"}
|
package/dist/spec.d.ts
ADDED
|
@@ -0,0 +1,218 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The lowered wire shapes — a 1:1 TypeScript mirror of bumbledb's
|
|
3
|
+
* `SchemaSpec` bindings contract (PRD-01;
|
|
4
|
+
* `bumbledb/crates/bumbledb/src/schema/spec.rs`): a schema as named plain
|
|
5
|
+
* data, relations and dependency statements each in declaration order (the
|
|
6
|
+
* declaration-order law that mints every id). The SDK's `lower()` emits
|
|
7
|
+
* these values; the napi bridge (PRD-04) marshals them into the Rust
|
|
8
|
+
* `SchemaSpec` verbatim, and the engine's own judge (`SchemaSpec::descriptor`
|
|
9
|
+
* name resolution + `SchemaDescriptor::validate` at `Db.create`/`Db.open`)
|
|
10
|
+
* stays the single semantic authority — the SDK lowers, it never re-judges.
|
|
11
|
+
*
|
|
12
|
+
* Every u64 crosses as `bigint`, never `number` (PRD-04's marshaling law: no
|
|
13
|
+
* 53-bit hazards, no branch). Object keys are always written in one fixed
|
|
14
|
+
* literal order per shape, so serialization of a lowered schema is
|
|
15
|
+
* deterministic (byte-stable) by construction.
|
|
16
|
+
*/
|
|
17
|
+
/**
|
|
18
|
+
* A structural value type — the one type vocabulary of the `schema!` field
|
|
19
|
+
* grammar (`ValueType` in Rust): `bool`, `u64`, `i64`, `str` (`string`
|
|
20
|
+
* here), `bytes<N>` (`fixedBytes`), and the interval family (`width:
|
|
21
|
+
* undefined` is the general 16-byte encoding with rays representable;
|
|
22
|
+
* `width: w` is the fixed-width `interval<E, w>` whose encoding stores only
|
|
23
|
+
* the start).
|
|
24
|
+
*/
|
|
25
|
+
type ValueTypeSpec = {
|
|
26
|
+
readonly kind: "bool";
|
|
27
|
+
} | {
|
|
28
|
+
readonly kind: "u64";
|
|
29
|
+
} | {
|
|
30
|
+
readonly kind: "i64";
|
|
31
|
+
} | {
|
|
32
|
+
readonly kind: "string";
|
|
33
|
+
} | {
|
|
34
|
+
readonly kind: "fixedBytes";
|
|
35
|
+
readonly len: number;
|
|
36
|
+
} | {
|
|
37
|
+
readonly kind: "interval";
|
|
38
|
+
readonly element: "u64" | "i64";
|
|
39
|
+
readonly width: bigint | undefined;
|
|
40
|
+
};
|
|
41
|
+
/**
|
|
42
|
+
* One plain engine value as carried by a lowered literal — the mirror of
|
|
43
|
+
* `bumbledb::Value` restricted to the schema-literal vocabulary (Allen masks
|
|
44
|
+
* are query-side values, never schema literals). Intervals are half-open
|
|
45
|
+
* `[start, end)`.
|
|
46
|
+
*/
|
|
47
|
+
type ValueSpec = {
|
|
48
|
+
readonly kind: "bool";
|
|
49
|
+
readonly value: boolean;
|
|
50
|
+
} | {
|
|
51
|
+
readonly kind: "u64";
|
|
52
|
+
readonly value: bigint;
|
|
53
|
+
} | {
|
|
54
|
+
readonly kind: "i64";
|
|
55
|
+
readonly value: bigint;
|
|
56
|
+
} | {
|
|
57
|
+
readonly kind: "string";
|
|
58
|
+
readonly value: string;
|
|
59
|
+
} | {
|
|
60
|
+
readonly kind: "fixedBytes";
|
|
61
|
+
readonly value: Uint8Array;
|
|
62
|
+
} | {
|
|
63
|
+
readonly kind: "intervalU64";
|
|
64
|
+
readonly start: bigint;
|
|
65
|
+
readonly end: bigint;
|
|
66
|
+
} | {
|
|
67
|
+
readonly kind: "intervalI64";
|
|
68
|
+
readonly start: bigint;
|
|
69
|
+
readonly end: bigint;
|
|
70
|
+
};
|
|
71
|
+
/**
|
|
72
|
+
* One literal as spelled: a plain value, or a closed relation's handle by
|
|
73
|
+
* name (the `| status == Frozen` spelling) — resolved by the engine through
|
|
74
|
+
* the selected field's newtype to the handle's declaration-order row id,
|
|
75
|
+
* exactly as the macro resolves it at expansion.
|
|
76
|
+
*/
|
|
77
|
+
type LiteralSpec = {
|
|
78
|
+
readonly kind: "value";
|
|
79
|
+
readonly value: ValueSpec;
|
|
80
|
+
} | {
|
|
81
|
+
readonly kind: "handle";
|
|
82
|
+
readonly handle: string;
|
|
83
|
+
};
|
|
84
|
+
/**
|
|
85
|
+
* One σ binding's right side: a single literal or a literal set (read
|
|
86
|
+
* disjunctively). The SDK's selection constructors make the degenerate sets
|
|
87
|
+
* unwritable (`oneOf` demands two leading literals), so a lowered `many`
|
|
88
|
+
* always carries ≥ 2 literals.
|
|
89
|
+
*/
|
|
90
|
+
type LiteralSetSpec = {
|
|
91
|
+
readonly kind: "one";
|
|
92
|
+
readonly literal: LiteralSpec;
|
|
93
|
+
} | {
|
|
94
|
+
readonly kind: "many";
|
|
95
|
+
readonly literals: readonly LiteralSpec[];
|
|
96
|
+
};
|
|
97
|
+
/**
|
|
98
|
+
* One side of a containment or window: `R(fields… | field == literal…)`,
|
|
99
|
+
* all names. `projection` is π in the statement's written order (positional
|
|
100
|
+
* pairing with the other side); `selection` is σ as (field, literal-or-set)
|
|
101
|
+
* pairs, read conjunctively.
|
|
102
|
+
*/
|
|
103
|
+
interface SideSpec {
|
|
104
|
+
readonly relation: string;
|
|
105
|
+
readonly projection: readonly string[];
|
|
106
|
+
readonly selection: ReadonlyArray<readonly [string, LiteralSetSpec]>;
|
|
107
|
+
}
|
|
108
|
+
/**
|
|
109
|
+
* A cardinality window's bounds — the canonical-utterance law's surviving
|
|
110
|
+
* spellings only, since the SDK's `Count` constructors make every banned
|
|
111
|
+
* spelling unwritable or a construction error: `exact` is `{n}` (`{0}` the
|
|
112
|
+
* exclusion), `range` is `{lo..hi}` with lo < hi, `floor` is `{lo..*}` with
|
|
113
|
+
* lo ≥ 2.
|
|
114
|
+
*/
|
|
115
|
+
type WindowSpec = {
|
|
116
|
+
readonly kind: "exact";
|
|
117
|
+
readonly n: bigint;
|
|
118
|
+
} | {
|
|
119
|
+
readonly kind: "range";
|
|
120
|
+
readonly lo: bigint;
|
|
121
|
+
readonly hi: bigint;
|
|
122
|
+
} | {
|
|
123
|
+
readonly kind: "floor";
|
|
124
|
+
readonly lo: bigint;
|
|
125
|
+
};
|
|
126
|
+
/**
|
|
127
|
+
* One field: name, structural type, host newtype name (carried for handle
|
|
128
|
+
* resolution only — dropped by the engine at descriptor lowering), and the
|
|
129
|
+
* `fresh` mint mark.
|
|
130
|
+
*/
|
|
131
|
+
interface FieldSpec {
|
|
132
|
+
readonly name: string;
|
|
133
|
+
readonly valueType: ValueTypeSpec;
|
|
134
|
+
readonly newtype: string | undefined;
|
|
135
|
+
readonly fresh: boolean;
|
|
136
|
+
}
|
|
137
|
+
/**
|
|
138
|
+
* One ground axiom of a closed relation: the handle plus one literal per
|
|
139
|
+
* declared intrinsic column, in field-declaration order (row id = index).
|
|
140
|
+
*/
|
|
141
|
+
interface RowSpec {
|
|
142
|
+
readonly handle: string;
|
|
143
|
+
readonly values: readonly LiteralSpec[];
|
|
144
|
+
}
|
|
145
|
+
/**
|
|
146
|
+
* One relation. `extension: rows` declares it closed (the option is the
|
|
147
|
+
* kind); a closed relation's `fields` are its declared intrinsic columns
|
|
148
|
+
* only — the synthetic (`id`, u64) handle field is materialized by the
|
|
149
|
+
* engine's schema validation. `newtype` is the handle newtype of a closed
|
|
150
|
+
* relation (the SDK uses the closed relation's own name), undefined on an
|
|
151
|
+
* ordinary one.
|
|
152
|
+
*/
|
|
153
|
+
interface RelationSpec {
|
|
154
|
+
readonly name: string;
|
|
155
|
+
readonly newtype: string | undefined;
|
|
156
|
+
readonly fields: readonly FieldSpec[];
|
|
157
|
+
readonly extension: readonly RowSpec[] | undefined;
|
|
158
|
+
}
|
|
159
|
+
/**
|
|
160
|
+
* One dependency statement, tagged by form. `==` is not a variant: a
|
|
161
|
+
* bidirectional containment is `containment` with `bidirectional: true`,
|
|
162
|
+
* lowered by the engine to the two adjacent containments (`source <=
|
|
163
|
+
* target` first). `cardinality` is B-family, target-left: the target is the
|
|
164
|
+
* per-group parent, the source is counted.
|
|
165
|
+
*/
|
|
166
|
+
type StatementSpec = {
|
|
167
|
+
readonly kind: "fd";
|
|
168
|
+
readonly relation: string;
|
|
169
|
+
readonly projection: readonly string[];
|
|
170
|
+
} | {
|
|
171
|
+
readonly kind: "containment";
|
|
172
|
+
readonly source: SideSpec;
|
|
173
|
+
readonly target: SideSpec;
|
|
174
|
+
readonly bidirectional: boolean;
|
|
175
|
+
} | {
|
|
176
|
+
readonly kind: "cardinality";
|
|
177
|
+
readonly target: SideSpec;
|
|
178
|
+
readonly window: WindowSpec;
|
|
179
|
+
readonly source: SideSpec;
|
|
180
|
+
};
|
|
181
|
+
/**
|
|
182
|
+
* The whole theory as named plain data — what `lower()` produces and what
|
|
183
|
+
* the bridge's `dbCreate`/`dbOpen` take. Both lists are in declaration
|
|
184
|
+
* order. Only DECLARED statements appear: the engine materializes the
|
|
185
|
+
* fresh-implied and closed auto-keys itself
|
|
186
|
+
* (`SchemaDescriptor::materialized_statements` — fresh keys first, closed
|
|
187
|
+
* auto-keys second, declared statements last), so re-stating them here
|
|
188
|
+
* would double them and change the fingerprint.
|
|
189
|
+
*/
|
|
190
|
+
interface SchemaSpec {
|
|
191
|
+
readonly relations: readonly RelationSpec[];
|
|
192
|
+
readonly statements: readonly StatementSpec[];
|
|
193
|
+
}
|
|
194
|
+
/**
|
|
195
|
+
* Renders one lowered literal in the exact macro spelling the engine's own
|
|
196
|
+
* renderer uses (`schema/render.rs` `literal`): handles bare by name,
|
|
197
|
+
* integers as digits, `true`/`false`, intervals as `start..end`, strings
|
|
198
|
+
* char-escaped through the `char::escape_debug` mirror, bytes as `b"…"`
|
|
199
|
+
* byte-escaped through the `u8::escape_ascii` mirror — byte-for-byte the
|
|
200
|
+
* engine's violation canonicals, so TS-side construction errors and
|
|
201
|
+
* engine-side violations read identically and `renderStatement` equals the
|
|
202
|
+
* violation's `canonical`.
|
|
203
|
+
*/
|
|
204
|
+
declare function renderLiteral(literal: LiteralSpec): string;
|
|
205
|
+
/**
|
|
206
|
+
* Renders one σ binding's right side: a bare literal, or a disjunctive
|
|
207
|
+
* literal set in braces (`{A, B}`).
|
|
208
|
+
*/
|
|
209
|
+
declare function renderLiteralSet(set: LiteralSetSpec): string;
|
|
210
|
+
/**
|
|
211
|
+
* Renders window bounds in their one canonical spelling: `{n}` exact
|
|
212
|
+
* (`{0}` the exclusion), `{lo..hi}`, `{lo..*}` — the spelling set the
|
|
213
|
+
* engine's renderer emits for sealed statements.
|
|
214
|
+
*/
|
|
215
|
+
declare function renderWindow(window: WindowSpec): string;
|
|
216
|
+
export type { FieldSpec, LiteralSetSpec, LiteralSpec, RelationSpec, RowSpec, SchemaSpec, SideSpec, StatementSpec, ValueSpec, ValueTypeSpec, WindowSpec };
|
|
217
|
+
export { renderLiteral, renderLiteralSet, renderWindow };
|
|
218
|
+
//# sourceMappingURL=spec.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"spec.d.ts","sourceRoot":"","sources":["../src/spec.ts"],"names":[],"mappings":"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"}
|
package/dist/spec.js
ADDED
|
@@ -0,0 +1,154 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The lowered wire shapes — a 1:1 TypeScript mirror of bumbledb's
|
|
3
|
+
* `SchemaSpec` bindings contract (PRD-01;
|
|
4
|
+
* `bumbledb/crates/bumbledb/src/schema/spec.rs`): a schema as named plain
|
|
5
|
+
* data, relations and dependency statements each in declaration order (the
|
|
6
|
+
* declaration-order law that mints every id). The SDK's `lower()` emits
|
|
7
|
+
* these values; the napi bridge (PRD-04) marshals them into the Rust
|
|
8
|
+
* `SchemaSpec` verbatim, and the engine's own judge (`SchemaSpec::descriptor`
|
|
9
|
+
* name resolution + `SchemaDescriptor::validate` at `Db.create`/`Db.open`)
|
|
10
|
+
* stays the single semantic authority — the SDK lowers, it never re-judges.
|
|
11
|
+
*
|
|
12
|
+
* Every u64 crosses as `bigint`, never `number` (PRD-04's marshaling law: no
|
|
13
|
+
* 53-bit hazards, no branch). Object keys are always written in one fixed
|
|
14
|
+
* literal order per shape, so serialization of a lowered schema is
|
|
15
|
+
* deterministic (byte-stable) by construction.
|
|
16
|
+
*/
|
|
17
|
+
/**
|
|
18
|
+
* The characters Rust's `char::escape_debug` (the engine renderer's string
|
|
19
|
+
* formatter, `schema/render.rs` `literal`) escapes as `\u{…}`: everything
|
|
20
|
+
* non-printable per rustc's generated tables — the C categories (Cc, Cf,
|
|
21
|
+
* Cs, Co, Cn) and the Z separators (Zs, Zl, Zp) except U+0020 itself
|
|
22
|
+
* (`library/core/src/unicode/printable.py`).
|
|
23
|
+
*/
|
|
24
|
+
const NON_PRINTABLE = /[\p{C}\p{Z}]/u;
|
|
25
|
+
/** Grapheme-extending characters, which `char::escape_debug` always escapes even when printable. */
|
|
26
|
+
const GRAPHEME_EXTEND = /\p{Grapheme_Extend}/u;
|
|
27
|
+
/**
|
|
28
|
+
* One char exactly as Rust's `char::escape_debug` spells it (the engine
|
|
29
|
+
* renders strings char by char through it): `\0`, `\t`, `\r`, `\n`,
|
|
30
|
+
* backslash-escaped `\\`/`\'`/`\"`, `\u{hex}` (lowercase, unpadded) for
|
|
31
|
+
* grapheme-extending and non-printable chars, the char itself otherwise.
|
|
32
|
+
*/
|
|
33
|
+
function escapeDebugChar(ch) {
|
|
34
|
+
if (ch === "\0") {
|
|
35
|
+
return "\\0";
|
|
36
|
+
}
|
|
37
|
+
if (ch === "\t") {
|
|
38
|
+
return "\\t";
|
|
39
|
+
}
|
|
40
|
+
if (ch === "\r") {
|
|
41
|
+
return "\\r";
|
|
42
|
+
}
|
|
43
|
+
if (ch === "\n") {
|
|
44
|
+
return "\\n";
|
|
45
|
+
}
|
|
46
|
+
if (ch === "\\" || ch === "'" || ch === '"') {
|
|
47
|
+
return `\\${ch}`;
|
|
48
|
+
}
|
|
49
|
+
if (GRAPHEME_EXTEND.test(ch) || (ch !== " " && NON_PRINTABLE.test(ch))) {
|
|
50
|
+
const codePoint = ch.codePointAt(0);
|
|
51
|
+
if (codePoint === undefined) {
|
|
52
|
+
return ch;
|
|
53
|
+
}
|
|
54
|
+
return `\\u{${codePoint.toString(16)}}`;
|
|
55
|
+
}
|
|
56
|
+
return ch;
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* One byte exactly as Rust's `u8::escape_ascii` spells it (the engine
|
|
60
|
+
* renders `bytes<N>` literals byte by byte through it): `\t`, `\r`, `\n`,
|
|
61
|
+
* `\\`, `\'`, `\"` as two-char escapes, printable ASCII (0x20–0x7e)
|
|
62
|
+
* verbatim, everything else `\xNN` lowercase.
|
|
63
|
+
*/
|
|
64
|
+
function escapeAsciiByte(byte) {
|
|
65
|
+
if (byte === 0x09) {
|
|
66
|
+
return "\\t";
|
|
67
|
+
}
|
|
68
|
+
if (byte === 0x0d) {
|
|
69
|
+
return "\\r";
|
|
70
|
+
}
|
|
71
|
+
if (byte === 0x0a) {
|
|
72
|
+
return "\\n";
|
|
73
|
+
}
|
|
74
|
+
if (byte === 0x5c) {
|
|
75
|
+
return "\\\\";
|
|
76
|
+
}
|
|
77
|
+
if (byte === 0x27) {
|
|
78
|
+
return "\\'";
|
|
79
|
+
}
|
|
80
|
+
if (byte === 0x22) {
|
|
81
|
+
return '\\"';
|
|
82
|
+
}
|
|
83
|
+
if (byte >= 0x20 && byte <= 0x7e) {
|
|
84
|
+
return String.fromCharCode(byte);
|
|
85
|
+
}
|
|
86
|
+
return `\\x${byte.toString(16).padStart(2, "0")}`;
|
|
87
|
+
}
|
|
88
|
+
/**
|
|
89
|
+
* Renders one lowered literal in the exact macro spelling the engine's own
|
|
90
|
+
* renderer uses (`schema/render.rs` `literal`): handles bare by name,
|
|
91
|
+
* integers as digits, `true`/`false`, intervals as `start..end`, strings
|
|
92
|
+
* char-escaped through the `char::escape_debug` mirror, bytes as `b"…"`
|
|
93
|
+
* byte-escaped through the `u8::escape_ascii` mirror — byte-for-byte the
|
|
94
|
+
* engine's violation canonicals, so TS-side construction errors and
|
|
95
|
+
* engine-side violations read identically and `renderStatement` equals the
|
|
96
|
+
* violation's `canonical`.
|
|
97
|
+
*/
|
|
98
|
+
function renderLiteral(literal) {
|
|
99
|
+
if (literal.kind === "handle") {
|
|
100
|
+
return literal.handle;
|
|
101
|
+
}
|
|
102
|
+
const value = literal.value;
|
|
103
|
+
switch (value.kind) {
|
|
104
|
+
case "bool":
|
|
105
|
+
return value.value ? "true" : "false";
|
|
106
|
+
case "u64":
|
|
107
|
+
case "i64":
|
|
108
|
+
return value.value.toString();
|
|
109
|
+
case "string": {
|
|
110
|
+
let out = '"';
|
|
111
|
+
for (const ch of value.value) {
|
|
112
|
+
out += escapeDebugChar(ch);
|
|
113
|
+
}
|
|
114
|
+
return `${out}"`;
|
|
115
|
+
}
|
|
116
|
+
case "fixedBytes": {
|
|
117
|
+
let out = 'b"';
|
|
118
|
+
for (const byte of value.value) {
|
|
119
|
+
out += escapeAsciiByte(byte);
|
|
120
|
+
}
|
|
121
|
+
return `${out}"`;
|
|
122
|
+
}
|
|
123
|
+
case "intervalU64":
|
|
124
|
+
case "intervalI64":
|
|
125
|
+
return `${value.start}..${value.end}`;
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
/**
|
|
129
|
+
* Renders one σ binding's right side: a bare literal, or a disjunctive
|
|
130
|
+
* literal set in braces (`{A, B}`).
|
|
131
|
+
*/
|
|
132
|
+
function renderLiteralSet(set) {
|
|
133
|
+
if (set.kind === "one") {
|
|
134
|
+
return renderLiteral(set.literal);
|
|
135
|
+
}
|
|
136
|
+
return `{${set.literals.map(renderLiteral).join(", ")}}`;
|
|
137
|
+
}
|
|
138
|
+
/**
|
|
139
|
+
* Renders window bounds in their one canonical spelling: `{n}` exact
|
|
140
|
+
* (`{0}` the exclusion), `{lo..hi}`, `{lo..*}` — the spelling set the
|
|
141
|
+
* engine's renderer emits for sealed statements.
|
|
142
|
+
*/
|
|
143
|
+
function renderWindow(window) {
|
|
144
|
+
switch (window.kind) {
|
|
145
|
+
case "exact":
|
|
146
|
+
return `{${window.n}}`;
|
|
147
|
+
case "range":
|
|
148
|
+
return `{${window.lo}..${window.hi}}`;
|
|
149
|
+
case "floor":
|
|
150
|
+
return `{${window.lo}..*}`;
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
export { renderLiteral, renderLiteralSet, renderWindow };
|
|
154
|
+
//# sourceMappingURL=spec.js.map
|
package/dist/spec.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"spec.js","sourceRoot":"","sources":["../src/spec.ts"],"names":[],"mappings":"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"}
|