@bjornpagen/bumbledb 0.20.2 → 1.0.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 +283 -1611
- package/README.md +156 -118
- package/dist/capacity.d.ts +16 -12
- package/dist/capacity.d.ts.map +1 -1
- package/dist/capacity.js +16 -48
- package/dist/capacity.js.map +1 -1
- package/dist/changes.d.ts +54 -0
- package/dist/changes.d.ts.map +1 -0
- package/dist/changes.js +245 -0
- package/dist/changes.js.map +1 -0
- package/dist/close.d.ts +24 -0
- package/dist/close.d.ts.map +1 -0
- package/dist/close.js +34 -0
- package/dist/close.js.map +1 -0
- package/dist/closed.d.ts +1 -3
- package/dist/closed.d.ts.map +1 -1
- package/dist/closed.js +24 -12
- package/dist/closed.js.map +1 -1
- package/dist/codec.d.ts +56 -0
- package/dist/codec.d.ts.map +1 -0
- package/dist/codec.js +289 -0
- package/dist/codec.js.map +1 -0
- package/dist/compile.d.ts +68 -0
- package/dist/compile.d.ts.map +1 -0
- package/dist/compile.js +75 -0
- package/dist/compile.js.map +1 -0
- package/dist/db-native.d.ts +170 -0
- package/dist/db-native.d.ts.map +1 -0
- package/dist/db-native.js +5 -0
- package/dist/db-native.js.map +1 -0
- package/dist/db.d.ts +101 -233
- package/dist/db.d.ts.map +1 -1
- package/dist/db.js +232 -1084
- package/dist/db.js.map +1 -1
- package/dist/errors.d.ts +57 -0
- package/dist/errors.d.ts.map +1 -0
- package/dist/errors.js +32 -0
- package/dist/errors.js.map +1 -0
- package/dist/face.d.ts.map +1 -1
- package/dist/face.js +2 -2
- package/dist/face.js.map +1 -1
- package/dist/fields.d.ts +65 -24
- package/dist/fields.d.ts.map +1 -1
- package/dist/fields.js +94 -24
- package/dist/fields.js.map +1 -1
- package/dist/index.d.ts +37 -32
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +17 -21
- package/dist/index.js.map +1 -1
- package/dist/internal/log.d.ts +24 -0
- package/dist/internal/log.d.ts.map +1 -0
- package/dist/internal/log.js +10 -0
- package/dist/internal/log.js.map +1 -0
- package/dist/law.d.ts +8 -13
- package/dist/law.d.ts.map +1 -1
- package/dist/law.js +6 -59
- package/dist/law.js.map +1 -1
- package/dist/lower.d.ts +0 -13
- package/dist/lower.d.ts.map +1 -1
- package/dist/lower.js +9 -17
- package/dist/lower.js.map +1 -1
- package/dist/migration.d.ts +33 -0
- package/dist/migration.d.ts.map +1 -0
- package/dist/migration.js +48 -0
- package/dist/migration.js.map +1 -0
- package/dist/native.d.ts +256 -301
- package/dist/native.d.ts.map +1 -1
- package/dist/native.js +65 -108
- package/dist/native.js.map +1 -1
- package/dist/query/atom.d.ts +24 -13
- package/dist/query/atom.d.ts.map +1 -1
- package/dist/query/atom.js +7 -3
- package/dist/query/atom.js.map +1 -1
- package/dist/query/compute.d.ts +68 -0
- package/dist/query/compute.d.ts.map +1 -0
- package/dist/query/compute.js +141 -0
- package/dist/query/compute.js.map +1 -0
- package/dist/query/find.d.ts +15 -8
- package/dist/query/find.d.ts.map +1 -1
- package/dist/query/find.js +6 -2
- package/dist/query/find.js.map +1 -1
- package/dist/query/lower.d.ts +23 -2
- package/dist/query/lower.d.ts.map +1 -1
- package/dist/query/lower.js +433 -80
- package/dist/query/lower.js.map +1 -1
- package/dist/query/parse-ir.d.ts.map +1 -1
- package/dist/query/parse-ir.js +17 -8
- package/dist/query/parse-ir.js.map +1 -1
- package/dist/query/run.d.ts +12 -2
- package/dist/query/run.d.ts.map +1 -1
- package/dist/query/run.js +26 -9
- package/dist/query/run.js.map +1 -1
- package/dist/query/scope.d.ts +47 -3
- package/dist/query/scope.d.ts.map +1 -1
- package/dist/query/scope.js +83 -19
- package/dist/query/scope.js.map +1 -1
- package/dist/relation.d.ts +3 -8
- package/dist/relation.d.ts.map +1 -1
- package/dist/relation.js +16 -10
- package/dist/relation.js.map +1 -1
- package/dist/result.d.ts +47 -0
- package/dist/result.d.ts.map +1 -0
- package/dist/result.js +50 -0
- package/dist/result.js.map +1 -0
- package/dist/rows.d.ts +69 -0
- package/dist/rows.d.ts.map +1 -0
- package/dist/rows.js +328 -0
- package/dist/rows.js.map +1 -0
- package/dist/runtime-codes.d.ts +2 -0
- package/dist/runtime-codes.d.ts.map +1 -0
- package/dist/runtime-codes.js +19 -0
- package/dist/runtime-codes.js.map +1 -0
- package/dist/runtime-errors.d.ts +106 -0
- package/dist/runtime-errors.d.ts.map +1 -0
- package/dist/runtime-errors.js +62 -0
- package/dist/runtime-errors.js.map +1 -0
- package/dist/runtime-native.d.ts +171 -0
- package/dist/runtime-native.d.ts.map +1 -0
- package/dist/runtime-native.js +5 -0
- package/dist/runtime-native.js.map +1 -0
- package/dist/runtime.d.ts +73 -0
- package/dist/runtime.d.ts.map +1 -0
- package/dist/runtime.js +293 -0
- package/dist/runtime.js.map +1 -0
- package/dist/scalar.d.ts +165 -0
- package/dist/scalar.d.ts.map +1 -0
- package/dist/scalar.js +344 -0
- package/dist/scalar.js.map +1 -0
- package/dist/schema.d.ts +1 -1
- package/dist/schema.d.ts.map +1 -1
- package/dist/schema.js +34 -37
- package/dist/schema.js.map +1 -1
- package/dist/shape.d.ts +28 -0
- package/dist/shape.d.ts.map +1 -0
- package/dist/shape.js +2 -0
- package/dist/shape.js.map +1 -0
- package/dist/spec.d.ts +27 -3
- package/dist/spec.d.ts.map +1 -1
- package/dist/spec.js +22 -1
- package/dist/spec.js.map +1 -1
- package/dist/statements.d.ts +16 -3
- package/dist/statements.d.ts.map +1 -1
- package/dist/statements.js +54 -28
- package/dist/statements.js.map +1 -1
- package/dist/uuid.d.ts +23 -0
- package/dist/uuid.d.ts.map +1 -0
- package/dist/uuid.js +54 -0
- package/dist/uuid.js.map +1 -0
- package/pack-provenance.json +7 -0
- package/package.json +12 -16
- package/src/capacity.ts +34 -54
- package/src/changes.ts +361 -0
- package/src/close.ts +53 -0
- package/src/closed.ts +25 -19
- package/src/codec.ts +379 -0
- package/src/compile.ts +149 -0
- package/src/db-native.ts +247 -0
- package/src/db.ts +461 -1632
- package/src/errors.ts +50 -0
- package/src/face.ts +2 -2
- package/src/fields.ts +182 -55
- package/src/index.ts +62 -126
- package/src/internal/log.ts +51 -0
- package/src/law.ts +13 -28
- package/src/lower.ts +9 -4
- package/src/migration.ts +69 -0
- package/src/native.ts +326 -487
- package/src/query/atom.ts +61 -25
- package/src/query/compute.ts +237 -0
- package/src/query/find.ts +31 -12
- package/src/query/lower.ts +531 -143
- package/src/query/parse-ir.ts +18 -13
- package/src/query/run.ts +32 -16
- package/src/query/scope.ts +140 -8
- package/src/relation.ts +17 -21
- package/src/result.ts +130 -0
- package/src/rows.ts +404 -0
- package/src/runtime-codes.ts +18 -0
- package/src/runtime-errors.ts +69 -0
- package/src/runtime-native.ts +242 -0
- package/src/runtime.ts +440 -0
- package/src/scalar.ts +560 -0
- package/src/schema.ts +35 -37
- package/src/shape.ts +31 -0
- package/src/spec.ts +33 -3
- package/src/statements.ts +75 -68
- package/src/uuid.ts +69 -0
- package/dist/marshal.d.ts +0 -44
- package/dist/marshal.d.ts.map +0 -1
- package/dist/marshal.js +0 -165
- package/dist/marshal.js.map +0 -1
- package/src/marshal.ts +0 -200
package/src/schema.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { AuthoringError, SdkInvariantError } from "#errors.ts"
|
|
1
2
|
/**
|
|
2
3
|
* `schema` — assembles relations and statements into a theory value (the
|
|
3
4
|
* `Theory` analog; what `Db.create`/`Db.open` take). Construction-time
|
|
@@ -10,12 +11,11 @@
|
|
|
10
11
|
* engine's exact rule so `lower` never emits an engine-refused
|
|
11
12
|
* containment. The type tier is `law.ts`'s `TargetKeyWall` (best effort,
|
|
12
13
|
* statically known tuples); every OTHER semantic judgment (key-internal
|
|
13
|
-
* legality,
|
|
14
|
+
* legality, …) stays the engine's `SchemaError` at
|
|
14
15
|
* `Db.create` — the engine is the final authority for every boundary,
|
|
15
16
|
* this wall just makes the SDK agree with it first.
|
|
16
17
|
*/
|
|
17
18
|
|
|
18
|
-
import * as errors from "@superbuilders/errors"
|
|
19
19
|
import type { AnyClosed } from "#closed.ts"
|
|
20
20
|
import { isClosedMember, sealedFieldOf } from "#closed.ts"
|
|
21
21
|
import type { FaceData } from "#face.ts"
|
|
@@ -37,19 +37,13 @@ function collectImplied(name: string, relations: SchemaRelations): ImpliedKeys {
|
|
|
37
37
|
for (const [recordKey, member] of Object.entries(relations)) {
|
|
38
38
|
assertDeclarationOrderKey(`schema ${name} relation`, recordKey)
|
|
39
39
|
if (member.name !== recordKey) {
|
|
40
|
-
throw
|
|
41
|
-
`schema ${name}: record key ${recordKey} holds relation ${member.name} — the key must equal the relation's declared name`
|
|
42
|
-
)
|
|
40
|
+
throw new AuthoringError({
|
|
41
|
+
message: `schema ${name}: record key ${recordKey} holds relation ${member.name} — the key must equal the relation's declared name`
|
|
42
|
+
})
|
|
43
43
|
}
|
|
44
44
|
const projections: Array<readonly string[]> = []
|
|
45
45
|
if (isClosedMember(member)) {
|
|
46
46
|
projections.push(Object.freeze(["id"]))
|
|
47
|
-
} else {
|
|
48
|
-
for (const declared of member.data.fields) {
|
|
49
|
-
if ("fresh" in declared.field && declared.field.fresh === true) {
|
|
50
|
-
projections.push(Object.freeze([declared.name]))
|
|
51
|
-
}
|
|
52
|
-
}
|
|
53
47
|
}
|
|
54
48
|
for (const projection of projections) {
|
|
55
49
|
rendered.add(`${member.name}(${projection.join(", ")}) -> ${member.name}`)
|
|
@@ -71,12 +65,14 @@ function verifyMembership(name: string, relations: SchemaRelations, statement: S
|
|
|
71
65
|
for (const owner of statementOwners(statement)) {
|
|
72
66
|
const member = relations[owner.name]
|
|
73
67
|
if (member === undefined) {
|
|
74
|
-
throw
|
|
68
|
+
throw new AuthoringError({
|
|
69
|
+
message: `schema ${name}: relation ${owner.name} is not declared in this schema — ${rendered}`
|
|
70
|
+
})
|
|
75
71
|
}
|
|
76
72
|
if (member !== owner) {
|
|
77
|
-
throw
|
|
78
|
-
`schema ${name}: statement references a different relation value named ${owner.name} than the one this schema declares — ${rendered}`
|
|
79
|
-
)
|
|
73
|
+
throw new AuthoringError({
|
|
74
|
+
message: `schema ${name}: statement references a different relation value named ${owner.name} than the one this schema declares — ${rendered}`
|
|
75
|
+
})
|
|
80
76
|
}
|
|
81
77
|
}
|
|
82
78
|
}
|
|
@@ -100,12 +96,14 @@ function verifyBindingHandles(
|
|
|
100
96
|
continue
|
|
101
97
|
}
|
|
102
98
|
if (roster === undefined) {
|
|
103
|
-
throw
|
|
104
|
-
`schema ${name}: ${face.owner.name}.${binding.field} is not a closed-relation reference — the handle literal ${literal.handle} is legal only on a field carrying a closed relation's roster — ${rendered}`
|
|
105
|
-
)
|
|
99
|
+
throw new AuthoringError({
|
|
100
|
+
message: `schema ${name}: ${face.owner.name}.${binding.field} is not a closed-relation reference — the handle literal ${literal.handle} is legal only on a field carrying a closed relation's roster — ${rendered}`
|
|
101
|
+
})
|
|
106
102
|
}
|
|
107
103
|
if (!roster.handles.includes(literal.handle)) {
|
|
108
|
-
throw
|
|
104
|
+
throw new AuthoringError({
|
|
105
|
+
message: `schema ${name}: closed relation ${roster.name} has no handle ${literal.handle} — ${rendered}`
|
|
106
|
+
})
|
|
109
107
|
}
|
|
110
108
|
}
|
|
111
109
|
}
|
|
@@ -185,9 +183,9 @@ function verifyClosedReferenceBinding(
|
|
|
185
183
|
}
|
|
186
184
|
const resolved = closedTargetOf(statements, face.owner.name, binding.field)
|
|
187
185
|
if (resolved !== roster.name) {
|
|
188
|
-
throw
|
|
189
|
-
`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}`
|
|
190
|
-
)
|
|
186
|
+
throw new AuthoringError({
|
|
187
|
+
message: `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}`
|
|
188
|
+
})
|
|
191
189
|
}
|
|
192
190
|
}
|
|
193
191
|
|
|
@@ -197,7 +195,7 @@ function verifyClosedReferenceBinding(
|
|
|
197
195
|
* `resolve_capacity_target` mirrored exactly): every `contained`/
|
|
198
196
|
* `mirrors`/`capacity` statement's target projection must resolve a key
|
|
199
197
|
* of the target relation, judged over the SAME key population the engine
|
|
200
|
-
* materializes — the
|
|
198
|
+
* materializes — the closed auto-keys
|
|
201
199
|
* ({@link collectImplied}'s roster) first, then the declared `key`
|
|
202
200
|
* statements in written order (a key may be declared after its probe, so
|
|
203
201
|
* this wall runs over the COMPLETE list, never inside the statement
|
|
@@ -262,9 +260,9 @@ function verifyTargetKeyFace(
|
|
|
262
260
|
if (face.projection.length === 1 && face.projection[0] === "id") {
|
|
263
261
|
return
|
|
264
262
|
}
|
|
265
|
-
throw
|
|
266
|
-
`schema ${name}: ${rendered}: closed target ${face.owner.name} is addressed by its synthetic id only — projection (${face.projection.join(", ")}) must be exactly (id) (rewrite the target side as on(${face.owner.name}, "id"))`
|
|
267
|
-
)
|
|
263
|
+
throw new AuthoringError({
|
|
264
|
+
message: `schema ${name}: ${rendered}: closed target ${face.owner.name} is addressed by its synthetic id only — projection (${face.projection.join(", ")}) must be exactly (id) (rewrite the target side as on(${face.owner.name}, "id"))`
|
|
265
|
+
})
|
|
268
266
|
}
|
|
269
267
|
const roster = [...(implied.get(face.owner.name) ?? []), ...(declared.get(face.owner.name) ?? [])]
|
|
270
268
|
const want = new Set(face.projection)
|
|
@@ -294,9 +292,9 @@ function verifyTargetKeyFace(
|
|
|
294
292
|
return descriptor !== undefined && descriptor.kind === "interval"
|
|
295
293
|
})
|
|
296
294
|
const hint = pointwise ? "; hint: declare the exact pointwise key `R(prefix…, interval) -> R`" : ""
|
|
297
|
-
throw
|
|
298
|
-
`schema ${name}: ${rendered}: target projection (${face.projection.join(", ")}) matches no declared key of ${face.owner.name} — available keys: ${available}${hint}`
|
|
299
|
-
)
|
|
295
|
+
throw new AuthoringError({
|
|
296
|
+
message: `schema ${name}: ${rendered}: target projection (${face.projection.join(", ")}) matches no declared key of ${face.owner.name} — available keys: ${available}${hint}`
|
|
297
|
+
})
|
|
300
298
|
}
|
|
301
299
|
|
|
302
300
|
type SchemaRelation = AnyRelation | AnyClosed
|
|
@@ -325,19 +323,19 @@ function schema<const Rels extends SchemaRelations, const Stmts extends readonly
|
|
|
325
323
|
const seen = new Set<string>()
|
|
326
324
|
for (const statement of statements) {
|
|
327
325
|
if (!isStatement(statement)) {
|
|
328
|
-
throw
|
|
329
|
-
`schema ${name}: a statement is minted only by key/contained/mirrors/capacity — a structural literal skips the construction-time arity and roster walls`
|
|
330
|
-
)
|
|
326
|
+
throw new AuthoringError({
|
|
327
|
+
message: `schema ${name}: a statement is minted only by key/contained/mirrors/capacity — a structural literal skips the construction-time arity and roster walls`
|
|
328
|
+
})
|
|
331
329
|
}
|
|
332
330
|
const rendered = renderStatement(statement)
|
|
333
331
|
verifyMembership(name, relations, statement, rendered)
|
|
334
332
|
if (implied.rendered.has(rendered)) {
|
|
335
|
-
throw
|
|
336
|
-
`schema ${name}: ${rendered} is redundant here (
|
|
337
|
-
)
|
|
333
|
+
throw new AuthoringError({
|
|
334
|
+
message: `schema ${name}: ${rendered} is redundant here (closedness already implies it) — and rejected as a duplicate`
|
|
335
|
+
})
|
|
338
336
|
}
|
|
339
337
|
if (seen.has(rendered)) {
|
|
340
|
-
throw
|
|
338
|
+
throw new AuthoringError({ message: `schema ${name}: duplicate statement — ${rendered}` })
|
|
341
339
|
}
|
|
342
340
|
seen.add(rendered)
|
|
343
341
|
verifyHandles(name, statement, rendered)
|
|
@@ -346,7 +344,7 @@ function schema<const Rels extends SchemaRelations, const Stmts extends readonly
|
|
|
346
344
|
verifyTargetKeys(name, statements, implied.roster)
|
|
347
345
|
const classes = computeClasses(name, relations, statements)
|
|
348
346
|
if (!classesComplete<EvaluatedClasses<ClassesOf<Rels, Stmts>>>(classes, relations)) {
|
|
349
|
-
throw
|
|
347
|
+
throw new SdkInvariantError({ message: `schema ${name}: class-map construction incomplete` })
|
|
350
348
|
}
|
|
351
349
|
return Object.freeze({ name, relations, statements: Object.freeze([...statements]), classes })
|
|
352
350
|
}
|
package/src/shape.ts
ADDED
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import type { Query } from "#query/lower.ts"
|
|
2
|
+
import type { ParamsRecord } from "#query/scope.ts"
|
|
3
|
+
/**
|
|
4
|
+
* Shared derived-type vocabulary of the chapter 35 core roster: `S` is a
|
|
5
|
+
* declared core schema value's type, `Rel<S>` its ordinary (writable)
|
|
6
|
+
* relations, `Fact<R>` the inferred row object, `Key<R>` the primary-key
|
|
7
|
+
* object accepted by `QueryReader.get`, and `QueryTemplate<S, P, A>` the
|
|
8
|
+
* immutable schema-bound logical query template. All are derived from the
|
|
9
|
+
* existing typed descriptors — no second hand-maintained roster.
|
|
10
|
+
*/
|
|
11
|
+
import type { AnyRelation, Fact } from "#relation.ts"
|
|
12
|
+
import type { AnySchema } from "#schema.ts"
|
|
13
|
+
|
|
14
|
+
/** The ordinary relations of a schema (closed vocabularies are ground axioms, never ingestion targets). */
|
|
15
|
+
type Rel<S extends AnySchema> = Extract<S["relations"][keyof S["relations"]], AnyRelation>
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* The primary-key object of a relation: the fields of its FIRST
|
|
19
|
+
* materialized key statement (a closed relation's synthetic `(id)`,
|
|
20
|
+
* otherwise the first declared `key`). Keys are declared statements now —
|
|
21
|
+
* there is no fresh-implied key — so the exact projection is a schema
|
|
22
|
+
* fact, verified at execution against the compiled tables; the type admits
|
|
23
|
+
* any subset of the fact's own fields and the runtime refuses a mismatch
|
|
24
|
+
* with a typed `DbError` before any native work.
|
|
25
|
+
*/
|
|
26
|
+
type Key<R extends AnyRelation> = Partial<Fact<R>>
|
|
27
|
+
|
|
28
|
+
/** Chapter 35's spelling of the immutable typed query template. */
|
|
29
|
+
type QueryTemplate<S extends AnySchema, P extends ParamsRecord, A> = Query<S["relations"], A, P>
|
|
30
|
+
|
|
31
|
+
export type { Key, QueryTemplate, Rel }
|
package/src/spec.ts
CHANGED
|
@@ -4,11 +4,13 @@ type ValueTypeSpec =
|
|
|
4
4
|
| { readonly kind: "bool" }
|
|
5
5
|
| { readonly kind: "u64" }
|
|
6
6
|
| { readonly kind: "i64" }
|
|
7
|
+
| { readonly kind: "f64" }
|
|
8
|
+
| { readonly kind: "uuid" }
|
|
7
9
|
| { readonly kind: "string" }
|
|
8
10
|
| { readonly kind: "fixedBytes"; readonly len: number }
|
|
9
11
|
| {
|
|
10
12
|
readonly kind: "interval"
|
|
11
|
-
readonly element: "u64" | "i64"
|
|
13
|
+
readonly element: "u64" | "i64" | "f64"
|
|
12
14
|
readonly width: bigint | undefined
|
|
13
15
|
}
|
|
14
16
|
|
|
@@ -16,10 +18,13 @@ type ValueSpec =
|
|
|
16
18
|
| { readonly kind: "bool"; readonly value: boolean }
|
|
17
19
|
| { readonly kind: "u64"; readonly value: bigint }
|
|
18
20
|
| { readonly kind: "i64"; readonly value: bigint }
|
|
21
|
+
| { readonly kind: "f64"; readonly value: number }
|
|
22
|
+
| { readonly kind: "uuid"; readonly value: string }
|
|
19
23
|
| { readonly kind: "string"; readonly value: string }
|
|
20
24
|
| { readonly kind: "fixedBytes"; readonly value: Uint8Array }
|
|
21
25
|
| { readonly kind: "intervalU64"; readonly start: bigint; readonly end: bigint }
|
|
22
26
|
| { readonly kind: "intervalI64"; readonly start: bigint; readonly end: bigint }
|
|
27
|
+
| { readonly kind: "intervalF64"; readonly start: number; readonly end: number }
|
|
23
28
|
|
|
24
29
|
type LiteralSpec =
|
|
25
30
|
| { readonly kind: "value"; readonly value: ValueSpec }
|
|
@@ -50,11 +55,15 @@ type CapacityWindowSpec =
|
|
|
50
55
|
| { readonly kind: "range"; readonly lo: CapacityBoundSpec; readonly hi: CapacityBoundSpec }
|
|
51
56
|
| { readonly kind: "floor"; readonly lo: CapacityBoundSpec }
|
|
52
57
|
|
|
58
|
+
/**
|
|
59
|
+
* One field: name, structural type, and host newtype label. There is no
|
|
60
|
+
* `fresh` mark: the database issues no identity, and key laws are declared
|
|
61
|
+
* statements (C01, chapter 30).
|
|
62
|
+
*/
|
|
53
63
|
interface FieldSpec {
|
|
54
64
|
readonly name: string
|
|
55
65
|
readonly valueType: ValueTypeSpec
|
|
56
66
|
readonly newtype: string | undefined
|
|
57
|
-
readonly fresh: boolean
|
|
58
67
|
}
|
|
59
68
|
|
|
60
69
|
interface RowSpec {
|
|
@@ -170,6 +179,10 @@ function renderLiteral(literal: LiteralSpec): string {
|
|
|
170
179
|
case "u64":
|
|
171
180
|
case "i64":
|
|
172
181
|
return value.value.toString()
|
|
182
|
+
case "f64":
|
|
183
|
+
return `f64:0x${f64BitsHex(value.value)}`
|
|
184
|
+
case "uuid":
|
|
185
|
+
return `uuid:${value.value}`
|
|
173
186
|
case "string": {
|
|
174
187
|
let out = '"'
|
|
175
188
|
for (const ch of value.value) {
|
|
@@ -187,7 +200,24 @@ function renderLiteral(literal: LiteralSpec): string {
|
|
|
187
200
|
case "intervalU64":
|
|
188
201
|
case "intervalI64":
|
|
189
202
|
return `${value.start}..${value.end}`
|
|
203
|
+
case "intervalF64":
|
|
204
|
+
return `f64:0x${f64BitsHex(value.start)}..f64:0x${f64BitsHex(value.end)}`
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
/**
|
|
209
|
+
* The canonical binary64 bit image as sixteen lowercase hex digits — the
|
|
210
|
+
* one f64 rendering (chapter 11): every NaN is the quiet canonical NaN and
|
|
211
|
+
* `-0` renders as `+0`, mirroring the engine's `f64:0x{bits:016x}`.
|
|
212
|
+
*/
|
|
213
|
+
function f64BitsHex(value: number): string {
|
|
214
|
+
const image = new DataView(new ArrayBuffer(8))
|
|
215
|
+
if (Number.isNaN(value)) {
|
|
216
|
+
image.setBigUint64(0, 0x7ff8000000000000n)
|
|
217
|
+
} else {
|
|
218
|
+
image.setFloat64(0, value === 0 ? 0 : value)
|
|
190
219
|
}
|
|
220
|
+
return image.getBigUint64(0).toString(16).padStart(16, "0")
|
|
191
221
|
}
|
|
192
222
|
|
|
193
223
|
function renderLiteralSet(set: LiteralSetSpec): string {
|
|
@@ -245,4 +275,4 @@ export type {
|
|
|
245
275
|
ValueTypeSpec,
|
|
246
276
|
WeightSpec
|
|
247
277
|
}
|
|
248
|
-
export { renderCapacityWindow, renderLiteral, renderLiteralSet, renderWeight }
|
|
278
|
+
export { f64BitsHex, renderCapacityWindow, renderLiteral, renderLiteralSet, renderWeight }
|
package/src/statements.ts
CHANGED
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import * as errors from "@superbuilders/errors"
|
|
2
1
|
import {
|
|
3
2
|
type BoundsOnTarget,
|
|
4
3
|
type CapacityWeight,
|
|
@@ -6,11 +5,11 @@ import {
|
|
|
6
5
|
isCapacityWeight,
|
|
7
6
|
isCapacityWindow,
|
|
8
7
|
type UnitDimensionBan,
|
|
9
|
-
type UnitWindowBan,
|
|
10
8
|
unitWeight,
|
|
11
9
|
type WeightOnSource
|
|
12
10
|
} from "#capacity.ts"
|
|
13
11
|
import { isClosedMember, sealedFieldOf } from "#closed.ts"
|
|
12
|
+
import { AuthoringError } from "#errors.ts"
|
|
14
13
|
import { type AnyFace, type FaceData, renderFace, type SameArity, type SameShapes } from "#face.ts"
|
|
15
14
|
import { type AnyClosedRoster, rosterOf, rostersAgree } from "#fields.ts"
|
|
16
15
|
import type { AnyRelation, RelationFields } from "#relation.ts"
|
|
@@ -82,9 +81,9 @@ function renderRosterSide(roster: AnyClosedRoster | undefined): string {
|
|
|
82
81
|
*/
|
|
83
82
|
function assertArityAgreement(source: FaceData, target: FaceData, statement: Statement): void {
|
|
84
83
|
if (source.projection.length !== target.projection.length) {
|
|
85
|
-
throw
|
|
86
|
-
`${source.owner.name}(${source.projection.join(", ")}) and ${target.owner.name}(${target.projection.join(", ")}) project ${source.projection.length} vs ${target.projection.length} fields — positional pairing requires both faces to project equally many — ${renderStatement(statement)}`
|
|
87
|
-
)
|
|
84
|
+
throw new AuthoringError({
|
|
85
|
+
message: `${source.owner.name}(${source.projection.join(", ")}) and ${target.owner.name}(${target.projection.join(", ")}) project ${source.projection.length} vs ${target.projection.length} fields — positional pairing requires both faces to project equally many — ${renderStatement(statement)}`
|
|
86
|
+
})
|
|
88
87
|
}
|
|
89
88
|
}
|
|
90
89
|
|
|
@@ -97,9 +96,9 @@ function assertRosterAgreement(source: FaceData, target: FaceData, statement: St
|
|
|
97
96
|
const sourceRoster = rosterOf(sealedFieldOf(source.owner, fieldName))
|
|
98
97
|
const targetRoster = rosterOf(sealedFieldOf(target.owner, targetField))
|
|
99
98
|
if (!rostersAgree(sourceRoster, targetRoster)) {
|
|
100
|
-
throw
|
|
101
|
-
`${source.owner.name}.${fieldName} is ${renderRosterSide(sourceRoster)} but ${target.owner.name}.${targetField} is ${renderRosterSide(targetRoster)} — closedness rides the descriptor: a closed reference is spelled with the vocabulary's own id descriptor (one meaning, one spelling), so faces pair closed-with-closed through one roster or bare-with-bare, never across — ${renderStatement(statement)}`
|
|
102
|
-
)
|
|
99
|
+
throw new AuthoringError({
|
|
100
|
+
message: `${source.owner.name}.${fieldName} is ${renderRosterSide(sourceRoster)} but ${target.owner.name}.${targetField} is ${renderRosterSide(targetRoster)} — closedness rides the descriptor: a closed reference is spelled with the vocabulary's own id descriptor (one meaning, one spelling), so faces pair closed-with-closed through one roster or bare-with-bare, never across — ${renderStatement(statement)}`
|
|
101
|
+
})
|
|
103
102
|
}
|
|
104
103
|
})
|
|
105
104
|
}
|
|
@@ -125,16 +124,16 @@ function key<
|
|
|
125
124
|
const Projection extends readonly [keyof RelationFields<R> & string, ...(keyof RelationFields<R> & string)[]]
|
|
126
125
|
>(relation: R, fields: Projection): KeyStatement<R, Projection> {
|
|
127
126
|
if (isClosedMember(relation)) {
|
|
128
|
-
throw
|
|
129
|
-
`key(${relation.name}, ...): closedness already materializes ${relation.name}(id) -> ${relation.name} — an explicit key on a closed relation is rejected as a duplicate`
|
|
130
|
-
)
|
|
127
|
+
throw new AuthoringError({
|
|
128
|
+
message: `key(${relation.name}, ...): closedness already materializes ${relation.name}(id) -> ${relation.name} — an explicit key on a closed relation is rejected as a duplicate`
|
|
129
|
+
})
|
|
131
130
|
}
|
|
132
131
|
const seen = new Set<string>()
|
|
133
132
|
for (const fieldName of fields) {
|
|
134
133
|
if (seen.has(fieldName)) {
|
|
135
|
-
throw
|
|
136
|
-
`key(${relation.name}, ...): the projection spells ${fieldName} twice — write it once (the canonical-utterance law: one meaning, one spelling)`
|
|
137
|
-
)
|
|
134
|
+
throw new AuthoringError({
|
|
135
|
+
message: `key(${relation.name}, ...): the projection spells ${fieldName} twice — write it once (the canonical-utterance law: one meaning, one spelling)`
|
|
136
|
+
})
|
|
138
137
|
}
|
|
139
138
|
seen.add(fieldName)
|
|
140
139
|
}
|
|
@@ -182,19 +181,19 @@ function assertWeightOnSource(weight: WeightSpec, source: FaceData, statement: S
|
|
|
182
181
|
}
|
|
183
182
|
const field = sealedFieldOf(source.owner, weight.field)
|
|
184
183
|
if (field === undefined) {
|
|
185
|
-
throw
|
|
186
|
-
`${source.owner.name} has no field ${weight.field} — a weight names a field of the SOURCE's own row (the weight vocabulary is closed at the row) — ${renderStatement(statement)}`
|
|
187
|
-
)
|
|
184
|
+
throw new AuthoringError({
|
|
185
|
+
message: `${source.owner.name} has no field ${weight.field} — a weight names a field of the SOURCE's own row (the weight vocabulary is closed at the row) — ${renderStatement(statement)}`
|
|
186
|
+
})
|
|
188
187
|
}
|
|
189
188
|
if (weight.kind === "field" && field.kind !== "u64") {
|
|
190
|
-
throw
|
|
191
|
-
`${source.owner.name}.${weight.field} is ${field.kind}, not u64 — a weight is u64-encoded (a signed weight would break the polarity scheduler: an insert could lower a sum) — ${renderStatement(statement)}`
|
|
192
|
-
)
|
|
189
|
+
throw new AuthoringError({
|
|
190
|
+
message: `${source.owner.name}.${weight.field} is ${field.kind}, not u64 — a weight is u64-encoded (a signed weight would break the polarity scheduler: an insert could lower a sum) — ${renderStatement(statement)}`
|
|
191
|
+
})
|
|
193
192
|
}
|
|
194
193
|
if (weight.kind === "durationField" && field.kind !== "interval") {
|
|
195
|
-
throw
|
|
196
|
-
`${source.owner.name}.${weight.field} is ${field.kind}, not an interval — Duration(...) weighs an interval field's measure — ${renderStatement(statement)}`
|
|
197
|
-
)
|
|
194
|
+
throw new AuthoringError({
|
|
195
|
+
message: `${source.owner.name}.${weight.field} is ${field.kind}, not an interval — Duration(...) weighs an interval field's measure — ${renderStatement(statement)}`
|
|
196
|
+
})
|
|
198
197
|
}
|
|
199
198
|
}
|
|
200
199
|
|
|
@@ -206,75 +205,83 @@ function assertBoundsOnTarget(window: CapacityWindowSpec, target: FaceData, stat
|
|
|
206
205
|
}
|
|
207
206
|
const field = sealedFieldOf(target.owner, bound.field)
|
|
208
207
|
if (field === undefined) {
|
|
209
|
-
throw
|
|
210
|
-
`${target.owner.name} has no field ${bound.field} — a dependent bound names a field of the TARGET's own row (bound names resolve against the target's full roster) — ${renderStatement(statement)}`
|
|
211
|
-
)
|
|
208
|
+
throw new AuthoringError({
|
|
209
|
+
message: `${target.owner.name} has no field ${bound.field} — a dependent bound names a field of the TARGET's own row (bound names resolve against the target's full roster) — ${renderStatement(statement)}`
|
|
210
|
+
})
|
|
212
211
|
}
|
|
213
212
|
if (bound.kind === "field" && field.kind !== "u64") {
|
|
214
|
-
throw
|
|
215
|
-
`${target.owner.name}.${bound.field} is ${field.kind}, not u64 — a dependent bound reads a u64 field of the TARGET row (Duration(...) is the interval-measure spelling) — ${renderStatement(statement)}`
|
|
216
|
-
)
|
|
213
|
+
throw new AuthoringError({
|
|
214
|
+
message: `${target.owner.name}.${bound.field} is ${field.kind}, not u64 — a dependent bound reads a u64 field of the TARGET row (Duration(...) is the interval-measure spelling) — ${renderStatement(statement)}`
|
|
215
|
+
})
|
|
217
216
|
}
|
|
218
217
|
if (bound.kind === "durationField" && field.kind !== "interval") {
|
|
219
|
-
throw
|
|
220
|
-
`${target.owner.name}.${bound.field} is ${field.kind}, not an interval — Duration(...) bounds by an interval field's measure — ${renderStatement(statement)}`
|
|
221
|
-
)
|
|
218
|
+
throw new AuthoringError({
|
|
219
|
+
message: `${target.owner.name}.${bound.field} is ${field.kind}, not an interval — Duration(...) bounds by an interval field's measure — ${renderStatement(statement)}`
|
|
220
|
+
})
|
|
222
221
|
}
|
|
223
222
|
}
|
|
224
223
|
}
|
|
225
224
|
|
|
225
|
+
/**
|
|
226
|
+
* The chapter 34 NAMED-OPTIONS capacity call — it replaces the old four
|
|
227
|
+
* positional arguments: `capacity(target, { from, weight?, within })`.
|
|
228
|
+
* Unit weight is the default; `weigh(...)`/`within(...)` remain the only
|
|
229
|
+
* mints for the weight/window values.
|
|
230
|
+
*/
|
|
226
231
|
function capacity<B extends AnyFace, W extends CapacityWindow, A extends AnyFace>(
|
|
227
232
|
target: B,
|
|
228
|
-
|
|
229
|
-
|
|
233
|
+
options: {
|
|
234
|
+
readonly from: A & SameArity<B, A> & SameShapes<B, A>
|
|
235
|
+
readonly within: W & UnitDimensionBan<W> & BoundsOnTarget<W, B>
|
|
236
|
+
}
|
|
230
237
|
): CapacityStatement<B["data"], A["data"]>
|
|
231
238
|
function capacity<B extends AnyFace, M extends CapacityWeight, W extends CapacityWindow, A extends AnyFace>(
|
|
232
239
|
target: B,
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
240
|
+
options: {
|
|
241
|
+
readonly from: A & SameArity<B, A> & SameShapes<B, A>
|
|
242
|
+
readonly weight: M & WeightOnSource<M, A>
|
|
243
|
+
readonly within: W & BoundsOnTarget<W, B>
|
|
244
|
+
}
|
|
236
245
|
): CapacityStatement<B["data"], A["data"]>
|
|
237
246
|
function capacity(
|
|
238
247
|
target: AnyFace,
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
248
|
+
options: {
|
|
249
|
+
readonly from: AnyFace
|
|
250
|
+
readonly weight?: unknown
|
|
251
|
+
readonly within: unknown
|
|
252
|
+
}
|
|
242
253
|
): CapacityStatement<FaceData, FaceData> {
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
254
|
+
if (typeof options !== "object" || options === null || !("from" in options) || !("within" in options)) {
|
|
255
|
+
throw new AuthoringError({
|
|
256
|
+
message:
|
|
257
|
+
"capacity takes named options — capacity(target, { from, weight?, within }) (chapter 34's one spelling; the positional arguments are deleted)"
|
|
258
|
+
})
|
|
259
|
+
}
|
|
260
|
+
const windowValue = options.within
|
|
261
|
+
const source = options.from
|
|
246
262
|
if (!isCapacityWindow(windowValue)) {
|
|
247
|
-
throw
|
|
248
|
-
|
|
249
|
-
|
|
263
|
+
throw new AuthoringError({
|
|
264
|
+
message:
|
|
265
|
+
"a capacity window is minted only by within() — a structural literal skips the ban table (the canonical-utterance law)"
|
|
266
|
+
})
|
|
250
267
|
}
|
|
251
268
|
let weight: WeightSpec = unitWeight
|
|
252
|
-
if (
|
|
253
|
-
if (!isCapacityWeight(
|
|
254
|
-
throw
|
|
255
|
-
"a capacity weight is minted only by weigh() — a structural literal skips the row-local weight wall"
|
|
256
|
-
)
|
|
269
|
+
if (options.weight !== undefined) {
|
|
270
|
+
if (!isCapacityWeight(options.weight)) {
|
|
271
|
+
throw new AuthoringError({
|
|
272
|
+
message: "a capacity weight is minted only by weigh() — a structural literal skips the row-local weight wall"
|
|
273
|
+
})
|
|
257
274
|
}
|
|
258
|
-
weight =
|
|
275
|
+
weight = options.weight.weight
|
|
259
276
|
}
|
|
260
277
|
const window = windowValue.window
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
)
|
|
265
|
-
}
|
|
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
|
-
|
|
272
|
-
// CapacityDimensionMixing twin — ruled 2026-07-24): a count of facts
|
|
273
|
-
|
|
278
|
+
// The unit-floor and vacuous-window ban tables are deleted (C01):
|
|
279
|
+
// `{1..*}`, `{N..*}` and `{0..*}` are accepted canonical laws now.
|
|
280
|
+
// CapacityDimensionMixing (C18) remains — genuinely different semantics.
|
|
274
281
|
if (weight.kind === "unit" && window.kind === "range" && window.hi.kind === "durationField") {
|
|
275
|
-
throw
|
|
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`
|
|
277
|
-
)
|
|
282
|
+
throw new AuthoringError({
|
|
283
|
+
message: `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`
|
|
284
|
+
})
|
|
278
285
|
}
|
|
279
286
|
const data: CapacityData = Object.freeze({
|
|
280
287
|
kind: "capacity",
|
package/src/uuid.ts
ADDED
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
import { Result } from "effect"
|
|
2
|
+
import { DbError } from "#runtime-errors.ts"
|
|
3
|
+
|
|
4
|
+
/** Structural UUID spelling, compatible with host generators and ordinary literals.
|
|
5
|
+
* Exact hexadecimal width and canonical case are checked at runtime boundaries.
|
|
6
|
+
*/
|
|
7
|
+
type Uuid = `${string}-${string}-${string}-${string}-${string}`
|
|
8
|
+
|
|
9
|
+
const SYNTAX = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/
|
|
10
|
+
const HEX = "0123456789abcdef"
|
|
11
|
+
|
|
12
|
+
function invalid(operation: string): DbError {
|
|
13
|
+
return new DbError({ operation, reason: { _tag: "InvalidArgument" } })
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
/** Pure parsing: normalize hexadecimal case, never inspect UUID version or variant. */
|
|
17
|
+
function parse(text: string): Result.Result<Uuid, DbError> {
|
|
18
|
+
if (typeof text !== "string" || text.length !== 36) {
|
|
19
|
+
return Result.fail(invalid("Uuid.parse"))
|
|
20
|
+
}
|
|
21
|
+
const canonical = text.toLowerCase()
|
|
22
|
+
return isUuid(canonical) ? Result.succeed(canonical) : Result.fail(invalid("Uuid.parse"))
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
/** Canonical wire validation. No normalization is permitted at the native boundary. */
|
|
26
|
+
function isUuid(value: unknown): value is Uuid {
|
|
27
|
+
return typeof value === "string" && value.length === 36 && SYNTAX.test(value)
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
/** All sixteen-byte payloads are representable, including Nil, Max, and future versions. */
|
|
31
|
+
function fromBytes(bytes: Uint8Array): Result.Result<Uuid, DbError> {
|
|
32
|
+
if (!(bytes instanceof Uint8Array) || bytes.length !== 16) {
|
|
33
|
+
return Result.fail(invalid("Uuid.fromBytes"))
|
|
34
|
+
}
|
|
35
|
+
let text = ""
|
|
36
|
+
for (const byte of bytes) {
|
|
37
|
+
text += HEX.charAt(byte >>> 4)
|
|
38
|
+
text += HEX.charAt(byte & 15)
|
|
39
|
+
}
|
|
40
|
+
return Result.succeed<Uuid>(
|
|
41
|
+
`${text.slice(0, 8)}-${text.slice(8, 12)}-${text.slice(12, 16)}-${text.slice(16, 20)}-${text.slice(20)}`
|
|
42
|
+
)
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
function digit(code: number): number {
|
|
46
|
+
return code <= 57 ? code - 48 : code - 87
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
/** Validate the structural string before decoding fresh bytes in standard UUID order. */
|
|
50
|
+
function toBytes(value: Uuid): Result.Result<Uint8Array, DbError> {
|
|
51
|
+
if (!isUuid(value)) {
|
|
52
|
+
return Result.fail(invalid("Uuid.toBytes"))
|
|
53
|
+
}
|
|
54
|
+
const bytes = new Uint8Array(16)
|
|
55
|
+
let offset = 0
|
|
56
|
+
for (let index = 0; index < 16; index += 1) {
|
|
57
|
+
if (value.charCodeAt(offset) === 45) {
|
|
58
|
+
offset += 1
|
|
59
|
+
}
|
|
60
|
+
bytes[index] = (digit(value.charCodeAt(offset)) << 4) | digit(value.charCodeAt(offset + 1))
|
|
61
|
+
offset += 2
|
|
62
|
+
}
|
|
63
|
+
return Result.succeed(bytes)
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
/** Generate UUIDs with a host library; preserve the result across database retries. */
|
|
67
|
+
const Uuid = Object.freeze({ parse, fromBytes, toBytes, isUuid })
|
|
68
|
+
|
|
69
|
+
export { Uuid }
|
package/dist/marshal.d.ts
DELETED
|
@@ -1,44 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* The marshal layer: fact object ⇄ positional `FactValue[]` by field
|
|
3
|
-
* ordinal, schema-directed, in ONE place only. The write side lowers named
|
|
4
|
-
* host objects to rows in the relation's field-declaration order
|
|
5
|
-
* (declaration order = ordinal ids, the macro's law); the read side decodes
|
|
6
|
-
* rows back to named objects of BARE structural values — the marshal
|
|
7
|
-
* boundary is pure both ways. CAST-FREE, LITERALLY: with structural values
|
|
8
|
-
* there is no brand to assert on the way out (the historical "one
|
|
9
|
-
* sanctioned marshal cast" died with the brand era), so product code
|
|
10
|
-
* carries zero casts — the only trusted seams are the completeness
|
|
11
|
-
* PREDICATES below, which verify the checkable half (every declared field
|
|
12
|
-
* present) and rely on the store as the proof carrier for the rest: a row
|
|
13
|
-
* the engine admitted IS a legal fact of its relation (the same trust
|
|
14
|
-
* direction as Rust's typed readback). Shape mismatches here are genuine
|
|
15
|
-
* failures and THROW typed; they are never domain data.
|
|
16
|
-
*
|
|
17
|
-
* THE CLOSED BIJECTION (0.4.0): a closed-referencing cell crosses this
|
|
18
|
-
* boundary as its handle NAME — the write side lowers name → u64 row id
|
|
19
|
-
* (declaration order = row ids, the sealed roster's own law, ≤ 256 rows),
|
|
20
|
-
* the read side lifts id → name, and both directions are total and static
|
|
21
|
-
* over the roster. An unknown name is a pointed THROW at the write seam —
|
|
22
|
-
* a deliberate UPGRADE over 0.3.0, where any bigint sailed through the
|
|
23
|
-
* marshal to a commit-time containment violation; the wrong spelling now
|
|
24
|
-
* dies here, before the engine ever sees the row. An out-of-roster id on
|
|
25
|
-
* the read side (reachable only in a store whose closed-typed column was
|
|
26
|
-
* never pinned by its containment law) is equally pointed — never a
|
|
27
|
-
* silent fallback, never `undefined`.
|
|
28
|
-
*/
|
|
29
|
-
import type { AnyClosedRoster, AnyField } from "./fields.js";
|
|
30
|
-
import type { FactValue } from "./native.js";
|
|
31
|
-
import type { AnyRelation, Fact, FreshKeys, RelationData } from "./relation.js";
|
|
32
|
-
declare function isFreshField(field: AnyField): boolean;
|
|
33
|
-
type KeyFact<R extends AnyRelation> = [FreshKeys<R>] extends [never] ? Partial<Fact<R>> : {
|
|
34
|
-
[K in FreshKeys<R>]: Fact<R>[K];
|
|
35
|
-
};
|
|
36
|
-
declare function recordOf(fact: object): Readonly<Record<string, unknown>>;
|
|
37
|
-
declare function handleOf(context: string, closed: AnyClosedRoster, cell: FactValue): string;
|
|
38
|
-
declare function cellOf(context: string, field: AnyField, value: unknown): FactValue;
|
|
39
|
-
declare function rowOf(relation: RelationData, fact: Readonly<Record<string, unknown>>): FactValue[];
|
|
40
|
-
declare function keyRowOf(relation: RelationData, projection: readonly string[], key: Readonly<Record<string, unknown>>): FactValue[];
|
|
41
|
-
declare function factOf<R extends AnyRelation>(relation: R, row: readonly FactValue[]): Fact<R>;
|
|
42
|
-
export type { KeyFact };
|
|
43
|
-
export { cellOf, factOf, handleOf, isFreshField, keyRowOf, recordOf, rowOf };
|
|
44
|
-
//# sourceMappingURL=marshal.d.ts.map
|
package/dist/marshal.d.ts.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"marshal.d.ts","sourceRoot":"","sources":["../src/marshal.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AAGH,OAAO,KAAK,EAAE,eAAe,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAA;AAE3D,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,YAAY,CAAA;AAC3C,OAAO,KAAK,EAAE,WAAW,EAAE,IAAI,EAAE,SAAS,EAAE,YAAY,EAAE,MAAM,cAAc,CAAA;AAE9E,iBAAS,YAAY,CAAC,KAAK,EAAE,QAAQ,GAAG,OAAO,CAE9C;AAED,KAAK,OAAO,CAAC,CAAC,SAAS,WAAW,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,KAAK,CAAC,GACjE,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,GAChB;KAAG,CAAC,IAAI,SAAS,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;CAAE,CAAA;AAEtC,iBAAS,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAKjE;AAyBD,iBAAS,QAAQ,CAAC,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,eAAe,EAAE,IAAI,EAAE,SAAS,GAAG,MAAM,CAWnF;AAED,iBAAS,MAAM,CAAC,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,QAAQ,EAAE,KAAK,EAAE,OAAO,GAAG,SAAS,CA6C3E;AAED,iBAAS,KAAK,CAAC,QAAQ,EAAE,YAAY,EAAE,IAAI,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,GAAG,SAAS,EAAE,CAQ3F;AAED,iBAAS,QAAQ,CAChB,QAAQ,EAAE,YAAY,EACtB,UAAU,EAAE,SAAS,MAAM,EAAE,EAC7B,GAAG,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,GACpC,SAAS,EAAE,CAgBb;AAWD,iBAAS,MAAM,CAAC,CAAC,SAAS,WAAW,EAAE,QAAQ,EAAE,CAAC,EAAE,GAAG,EAAE,SAAS,SAAS,EAAE,GAAG,IAAI,CAAC,CAAC,CAAC,CAsBtF;AAED,YAAY,EAAE,OAAO,EAAE,CAAA;AACvB,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,YAAY,EAAE,QAAQ,EAAE,QAAQ,EAAE,KAAK,EAAE,CAAA"}
|