@bjornpagen/bumbledb 1.3.1 → 2.0.0-rc.1
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 +153 -77
- package/README.md +107 -41
- package/dist/alternatives.d.ts +5 -6
- package/dist/alternatives.d.ts.map +1 -1
- package/dist/alternatives.js +5 -6
- package/dist/alternatives.js.map +1 -1
- package/dist/bin.d.ts +3 -0
- package/dist/bin.d.ts.map +1 -0
- package/dist/bin.js +85 -0
- package/dist/bin.js.map +1 -0
- package/dist/capacity.d.ts +14 -17
- package/dist/capacity.d.ts.map +1 -1
- package/dist/capacity.js +7 -7
- package/dist/capacity.js.map +1 -1
- package/dist/changes.d.ts +32 -40
- package/dist/changes.d.ts.map +1 -1
- package/dist/changes.js +86 -104
- package/dist/changes.js.map +1 -1
- package/dist/closed.d.ts +2 -2
- package/dist/closed.d.ts.map +1 -1
- package/dist/closed.js +5 -5
- package/dist/closed.js.map +1 -1
- package/dist/codec.d.ts +13 -27
- package/dist/codec.d.ts.map +1 -1
- package/dist/codec.js +20 -21
- package/dist/codec.js.map +1 -1
- package/dist/compile.d.ts +26 -50
- package/dist/compile.d.ts.map +1 -1
- package/dist/compile.js +75 -64
- package/dist/compile.js.map +1 -1
- package/dist/database/database.d.ts +98 -0
- package/dist/database/database.d.ts.map +1 -0
- package/dist/database/database.js +249 -0
- package/dist/database/database.js.map +1 -0
- package/dist/database/driver.d.ts +40 -0
- package/dist/database/driver.d.ts.map +1 -0
- package/dist/database/driver.js +68 -0
- package/dist/database/driver.js.map +1 -0
- package/dist/database/fs.d.ts +12 -0
- package/dist/database/fs.d.ts.map +1 -0
- package/dist/database/fs.js +120 -0
- package/dist/database/fs.js.map +1 -0
- package/dist/database/generate.d.ts +26 -0
- package/dist/database/generate.d.ts.map +1 -0
- package/dist/database/generate.js +102 -0
- package/dist/database/generate.js.map +1 -0
- package/dist/database/hosted.d.ts +32 -0
- package/dist/database/hosted.d.ts.map +1 -0
- package/dist/database/hosted.js +44 -0
- package/dist/database/hosted.js.map +1 -0
- package/dist/database/io.d.ts +94 -0
- package/dist/database/io.d.ts.map +1 -0
- package/dist/database/io.js +35 -0
- package/dist/database/io.js.map +1 -0
- package/dist/database/mem.d.ts +26 -0
- package/dist/database/mem.d.ts.map +1 -0
- package/dist/database/mem.js +67 -0
- package/dist/database/mem.js.map +1 -0
- package/dist/database/migration.d.ts +55 -0
- package/dist/database/migration.d.ts.map +1 -0
- package/dist/database/migration.js +46 -0
- package/dist/database/migration.js.map +1 -0
- package/dist/database/s3.d.ts +36 -0
- package/dist/database/s3.d.ts.map +1 -0
- package/dist/database/s3.js +141 -0
- package/dist/database/s3.js.map +1 -0
- package/dist/db.d.ts +44 -128
- package/dist/db.d.ts.map +1 -1
- package/dist/db.js +163 -287
- package/dist/db.js.map +1 -1
- package/dist/engine.d.ts +7 -0
- package/dist/engine.d.ts.map +1 -0
- package/dist/engine.js +2 -0
- package/dist/engine.js.map +1 -0
- package/dist/errors.d.ts +152 -46
- package/dist/errors.d.ts.map +1 -1
- package/dist/errors.js +107 -19
- package/dist/errors.js.map +1 -1
- package/dist/face.d.ts +5 -5
- package/dist/face.d.ts.map +1 -1
- package/dist/face.js +6 -6
- package/dist/face.js.map +1 -1
- package/dist/fields.d.ts +4 -5
- package/dist/fields.d.ts.map +1 -1
- package/dist/fields.js +3 -3
- package/dist/fields.js.map +1 -1
- package/dist/index.d.ts +60 -57
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +27 -28
- package/dist/index.js.map +1 -1
- package/dist/judgment.d.ts +1 -1
- package/dist/judgment.js +1 -1
- package/dist/law.d.ts +16 -68
- package/dist/law.d.ts.map +1 -1
- package/dist/law.js +3 -3
- package/dist/law.js.map +1 -1
- package/dist/lower.d.ts +3 -3
- package/dist/lower.d.ts.map +1 -1
- package/dist/lower.js +35 -39
- package/dist/lower.js.map +1 -1
- package/dist/native/addon.d.ts +23 -0
- package/dist/native/addon.d.ts.map +1 -0
- package/dist/native/addon.js +15 -0
- package/dist/native/addon.js.map +1 -0
- package/dist/native/binding.d.ts +996 -0
- package/dist/native/json.d.ts +14 -0
- package/dist/native/json.d.ts.map +1 -0
- package/dist/native/json.js +73 -0
- package/dist/native/json.js.map +1 -0
- package/dist/native/load.d.ts +9 -0
- package/dist/native/load.d.ts.map +1 -0
- package/dist/native/load.js +30 -0
- package/dist/native/load.js.map +1 -0
- package/dist/native/op.d.ts +29 -0
- package/dist/native/op.d.ts.map +1 -0
- package/dist/native/op.js +50 -0
- package/dist/native/op.js.map +1 -0
- package/dist/query/atom.d.ts +13 -14
- package/dist/query/atom.d.ts.map +1 -1
- package/dist/query/atom.js +2 -2
- package/dist/query/atom.js.map +1 -1
- package/dist/query/compute.d.ts +4 -4
- package/dist/query/compute.d.ts.map +1 -1
- package/dist/query/compute.js +4 -4
- package/dist/query/compute.js.map +1 -1
- package/dist/query/find.d.ts +8 -8
- package/dist/query/find.d.ts.map +1 -1
- package/dist/query/find.js +1 -1
- package/dist/query/lower.d.ts +22 -17
- package/dist/query/lower.d.ts.map +1 -1
- package/dist/query/lower.js +230 -343
- package/dist/query/lower.js.map +1 -1
- package/dist/query/run.d.ts +5 -5
- package/dist/query/run.d.ts.map +1 -1
- package/dist/query/run.js +32 -15
- package/dist/query/run.js.map +1 -1
- package/dist/query/scope.d.ts +20 -28
- package/dist/query/scope.d.ts.map +1 -1
- package/dist/query/scope.js +7 -7
- package/dist/query/scope.js.map +1 -1
- package/dist/query/segments.d.ts +2 -2
- package/dist/query/segments.d.ts.map +1 -1
- package/dist/query/segments.js +3 -3
- package/dist/query/segments.js.map +1 -1
- package/dist/relation.d.ts +1 -1
- package/dist/relation.d.ts.map +1 -1
- package/dist/relation.js +4 -4
- package/dist/relation.js.map +1 -1
- package/dist/result.d.ts +15 -22
- package/dist/result.d.ts.map +1 -1
- package/dist/result.js +30 -39
- package/dist/result.js.map +1 -1
- package/dist/rows.d.ts +9 -33
- package/dist/rows.d.ts.map +1 -1
- package/dist/rows.js +8 -12
- package/dist/rows.js.map +1 -1
- package/dist/runtime.d.ts +17 -20
- package/dist/runtime.d.ts.map +1 -1
- package/dist/runtime.js +41 -205
- package/dist/runtime.js.map +1 -1
- package/dist/scalar.d.ts +4 -4
- package/dist/scalar.d.ts.map +1 -1
- package/dist/scalar.js +24 -8
- package/dist/scalar.js.map +1 -1
- package/dist/schema.d.ts +7 -18
- package/dist/schema.d.ts.map +1 -1
- package/dist/schema.js +18 -228
- package/dist/schema.js.map +1 -1
- package/dist/selection.d.ts +4 -4
- package/dist/selection.d.ts.map +1 -1
- package/dist/selection.js +5 -5
- package/dist/selection.js.map +1 -1
- package/dist/shape.d.ts +5 -5
- package/dist/shape.d.ts.map +1 -1
- package/dist/spec.d.ts +7 -79
- package/dist/spec.d.ts.map +1 -1
- package/dist/spec.js.map +1 -1
- package/dist/statements.d.ts +3 -3
- package/dist/statements.d.ts.map +1 -1
- package/dist/statements.js +10 -10
- package/dist/statements.js.map +1 -1
- package/dist/uuid.d.ts +1 -1
- package/dist/uuid.d.ts.map +1 -1
- package/dist/uuid.js +1 -1
- package/dist/uuid.js.map +1 -1
- package/dist/values.d.ts +2 -2
- package/dist/values.d.ts.map +1 -1
- package/dist/values.js +2 -2
- package/dist/values.js.map +1 -1
- package/package.json +18 -18
- package/src/alternatives.ts +7 -8
- package/src/bin.ts +82 -0
- package/src/capacity.ts +20 -23
- package/src/changes.ts +134 -191
- package/src/closed.ts +5 -5
- package/src/codec.ts +35 -49
- package/src/compile.ts +91 -113
- package/src/database/database.ts +413 -0
- package/src/database/driver.ts +134 -0
- package/src/database/fs.ts +119 -0
- package/src/database/generate.ts +116 -0
- package/src/database/hosted.ts +102 -0
- package/src/database/io.ts +134 -0
- package/src/database/mem.ts +113 -0
- package/src/database/migration.ts +107 -0
- package/src/database/s3.ts +231 -0
- package/src/db.ts +290 -547
- package/src/engine.ts +14 -0
- package/src/errors.ts +118 -39
- package/src/face.ts +9 -9
- package/src/fields.ts +6 -7
- package/src/index.ts +92 -105
- package/src/judgment.ts +1 -1
- package/src/law.ts +18 -70
- package/src/lower.ts +61 -72
- package/src/native/addon.ts +54 -0
- package/src/native/binding.d.ts +996 -0
- package/src/native/json.ts +100 -0
- package/src/native/load.ts +31 -0
- package/src/native/op.ts +73 -0
- package/src/query/atom.ts +15 -16
- package/src/query/compute.ts +7 -7
- package/src/query/find.ts +8 -8
- package/src/query/lower.ts +270 -392
- package/src/query/run.ts +42 -21
- package/src/query/scope.ts +29 -37
- package/src/query/segments.ts +4 -4
- package/src/relation.ts +4 -4
- package/src/result.ts +53 -80
- package/src/rows.ts +18 -46
- package/src/runtime.ts +50 -277
- package/src/scalar.ts +32 -12
- package/src/schema.ts +23 -284
- package/src/selection.ts +6 -6
- package/src/shape.ts +5 -5
- package/src/spec.ts +7 -85
- package/src/statements.ts +11 -11
- package/src/uuid.ts +1 -1
- package/src/values.ts +4 -4
- package/dist/close.d.ts +0 -24
- package/dist/close.d.ts.map +0 -1
- package/dist/close.js +0 -34
- package/dist/close.js.map +0 -1
- package/dist/db-native.d.ts +0 -189
- package/dist/db-native.d.ts.map +0 -1
- package/dist/db-native.js +0 -13
- package/dist/db-native.js.map +0 -1
- package/dist/internal/log.d.ts +0 -26
- package/dist/internal/log.d.ts.map +0 -1
- package/dist/internal/log.js +0 -12
- package/dist/internal/log.js.map +0 -1
- package/dist/native.d.ts +0 -562
- package/dist/native.d.ts.map +0 -1
- package/dist/native.js +0 -123
- package/dist/native.js.map +0 -1
- package/dist/query/description.d.ts +0 -41
- package/dist/query/description.d.ts.map +0 -1
- package/dist/query/description.js +0 -311
- package/dist/query/description.js.map +0 -1
- package/dist/query/parse-ir.d.ts +0 -10
- package/dist/query/parse-ir.d.ts.map +0 -1
- package/dist/query/parse-ir.js +0 -280
- package/dist/query/parse-ir.js.map +0 -1
- package/dist/runtime-codes.d.ts +0 -2
- package/dist/runtime-codes.d.ts.map +0 -1
- package/dist/runtime-codes.js +0 -19
- package/dist/runtime-codes.js.map +0 -1
- package/dist/runtime-errors.d.ts +0 -138
- package/dist/runtime-errors.d.ts.map +0 -1
- package/dist/runtime-errors.js +0 -111
- package/dist/runtime-errors.js.map +0 -1
- package/dist/runtime-native.d.ts +0 -136
- package/dist/runtime-native.d.ts.map +0 -1
- package/dist/runtime-native.js +0 -5
- package/dist/runtime-native.js.map +0 -1
- package/dist/schema-file.d.ts +0 -7
- package/dist/schema-file.d.ts.map +0 -1
- package/dist/schema-file.js +0 -24
- package/dist/schema-file.js.map +0 -1
- package/pack-provenance.json +0 -7
- package/src/close.ts +0 -53
- package/src/db-native.ts +0 -235
- package/src/internal/log.ts +0 -46
- package/src/native.ts +0 -736
- package/src/query/description.ts +0 -424
- package/src/query/parse-ir.ts +0 -293
- package/src/runtime-codes.ts +0 -18
- package/src/runtime-errors.ts +0 -122
- package/src/runtime-native.ts +0 -181
- package/src/schema-file.ts +0 -38
package/src/schema.ts
CHANGED
|
@@ -1,42 +1,24 @@
|
|
|
1
1
|
import { isDeepStrictEqual } from "node:util"
|
|
2
|
-
import {
|
|
2
|
+
import { isCompiledSchema, registerCompiled } from "./compile.ts"
|
|
3
|
+
import { AuthoringError, internalError } from "./errors.ts"
|
|
3
4
|
/**
|
|
4
|
-
* `schema`
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
* implied-key duplicates, duplicate statements, a belt-and-braces handle
|
|
8
|
-
* re-verification — and the TARGET-KEY WALL ({@link verifyTargetKeys}),
|
|
9
|
-
* the value tier of the two-tier containment law
|
|
10
|
-
* (60-containment-parity): every containment/mirrors/capacity target
|
|
11
|
-
* projection must set-match a key of its relation, judged HERE with the
|
|
12
|
-
* engine's exact rule so `lower` never emits an engine-refused
|
|
13
|
-
* containment. The type tier is `law.ts`'s `TargetKeyWall` (best effort,
|
|
14
|
-
* statically known tuples); every OTHER semantic judgment (key-internal
|
|
15
|
-
* legality, …) stays the engine's `SchemaError` at
|
|
16
|
-
* `Db.create` — the engine is the final authority for every boundary,
|
|
17
|
-
* this wall just makes the SDK agree with it first.
|
|
5
|
+
* `schema` assembles relations and statements into a schema value and has the engine compile it.
|
|
6
|
+
* The SDK checks only what the engine cannot see: that every statement names this schema's own
|
|
7
|
+
* relation values. Every other judgment is the engine's, reported as an `AuthoringError`.
|
|
18
8
|
*/
|
|
19
9
|
|
|
20
|
-
import type { AnyClosed } from "
|
|
21
|
-
import {
|
|
22
|
-
import
|
|
23
|
-
import {
|
|
24
|
-
import {
|
|
25
|
-
import
|
|
26
|
-
import type
|
|
27
|
-
import
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
interface ImpliedKeys {
|
|
32
|
-
readonly rendered: ReadonlySet<string>
|
|
33
|
-
readonly roster: ReadonlyMap<string, ReadonlyArray<readonly string[]>>
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
function collectImplied(name: string, relations: SchemaRelations): ImpliedKeys {
|
|
10
|
+
import type { AnyClosed } from "./closed.ts"
|
|
11
|
+
import { memberDescriptor, membersAgree } from "./closed.ts"
|
|
12
|
+
import { assertDeclarationOrderKey, assertDeclarationRecord } from "./fields.ts"
|
|
13
|
+
import { descriptorCache, isImmutable } from "./immutable.ts"
|
|
14
|
+
import { type ClassesOf, classesComplete, computeClasses, type LawfulStatements, type SchemaClasses } from "./law.ts"
|
|
15
|
+
import type { AnyRelation } from "./relation.ts"
|
|
16
|
+
import { renderStatement, type Statement, statementDescriptor } from "./statements.ts"
|
|
17
|
+
import { arrayValue, recordValue } from "./values.ts"
|
|
18
|
+
|
|
19
|
+
/** Each relation's record key is its declared name. */
|
|
20
|
+
function verifyRelationNames(name: string, relations: SchemaRelations): void {
|
|
37
21
|
assertDeclarationRecord(`schema ${name} relations`, relations)
|
|
38
|
-
const rendered = new Set<string>()
|
|
39
|
-
const roster = new Map<string, ReadonlyArray<readonly string[]>>()
|
|
40
22
|
for (const [recordKey, member] of Object.entries(relations)) {
|
|
41
23
|
assertDeclarationOrderKey(`schema ${name} relation`, recordKey)
|
|
42
24
|
if (member.name !== recordKey) {
|
|
@@ -44,16 +26,7 @@ function collectImplied(name: string, relations: SchemaRelations): ImpliedKeys {
|
|
|
44
26
|
message: `schema ${name}: record key ${recordKey} holds relation ${member.name} — the key must equal the relation's declared name`
|
|
45
27
|
})
|
|
46
28
|
}
|
|
47
|
-
const projections: Array<readonly string[]> = []
|
|
48
|
-
if (isClosedMember(member)) {
|
|
49
|
-
projections.push(Object.freeze(["id"]))
|
|
50
|
-
}
|
|
51
|
-
for (const projection of projections) {
|
|
52
|
-
rendered.add(`${member.name}(${projection.join(", ")}) -> ${member.name}`)
|
|
53
|
-
}
|
|
54
|
-
roster.set(member.name, Object.freeze(projections))
|
|
55
29
|
}
|
|
56
|
-
return { rendered, roster }
|
|
57
30
|
}
|
|
58
31
|
|
|
59
32
|
function statementOwners(statement: Statement): readonly SchemaRelation[] {
|
|
@@ -80,226 +53,6 @@ function verifyMembership(name: string, relations: SchemaRelations, statement: S
|
|
|
80
53
|
}
|
|
81
54
|
}
|
|
82
55
|
|
|
83
|
-
function bindingLiterals(set: LiteralSetSpec): readonly LiteralSpec[] {
|
|
84
|
-
if (set.kind === "one") {
|
|
85
|
-
return [set.literal]
|
|
86
|
-
}
|
|
87
|
-
return set.literals
|
|
88
|
-
}
|
|
89
|
-
|
|
90
|
-
function verifyBindingHandles(
|
|
91
|
-
name: string,
|
|
92
|
-
face: AnyFace,
|
|
93
|
-
binding: { readonly field: string; readonly set: LiteralSetSpec },
|
|
94
|
-
rendered: string
|
|
95
|
-
): void {
|
|
96
|
-
const roster = rosterOf(sealedFieldOf(face.owner, binding.field))
|
|
97
|
-
for (const literal of bindingLiterals(binding.set)) {
|
|
98
|
-
if (literal.kind !== "handle") {
|
|
99
|
-
continue
|
|
100
|
-
}
|
|
101
|
-
if (roster === undefined) {
|
|
102
|
-
throw new AuthoringError({
|
|
103
|
-
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}`
|
|
104
|
-
})
|
|
105
|
-
}
|
|
106
|
-
if (!roster.handles.includes(literal.handle)) {
|
|
107
|
-
throw new AuthoringError({
|
|
108
|
-
message: `schema ${name}: closed relation ${roster.name} has no handle ${literal.handle} — ${rendered}`
|
|
109
|
-
})
|
|
110
|
-
}
|
|
111
|
-
}
|
|
112
|
-
}
|
|
113
|
-
|
|
114
|
-
function verifyHandles(name: string, statement: Statement, rendered: string): void {
|
|
115
|
-
const data = statement
|
|
116
|
-
if (data.kind === "key") {
|
|
117
|
-
return
|
|
118
|
-
}
|
|
119
|
-
for (const face of [data.source, data.target]) {
|
|
120
|
-
for (const binding of face.selection) {
|
|
121
|
-
verifyBindingHandles(name, face, binding, rendered)
|
|
122
|
-
}
|
|
123
|
-
}
|
|
124
|
-
}
|
|
125
|
-
|
|
126
|
-
function closedTargetOf(statements: readonly Statement[], owner: string, field: string): string | undefined {
|
|
127
|
-
for (const statement of statements) {
|
|
128
|
-
const data = statement
|
|
129
|
-
if (data.kind !== "containment" && data.kind !== "mirrors") {
|
|
130
|
-
continue
|
|
131
|
-
}
|
|
132
|
-
const pairs: Array<readonly [AnyFace, AnyFace]> = [[data.source, data.target]]
|
|
133
|
-
if (data.kind === "mirrors") {
|
|
134
|
-
pairs.push([data.target, data.source])
|
|
135
|
-
}
|
|
136
|
-
for (const [source, target] of pairs) {
|
|
137
|
-
if (
|
|
138
|
-
source.owner.name === owner &&
|
|
139
|
-
source.projection.length === 1 &&
|
|
140
|
-
source.projection[0] === field &&
|
|
141
|
-
target.projection.length === 1 &&
|
|
142
|
-
target.projection[0] === "id" &&
|
|
143
|
-
isClosedMember(target.owner)
|
|
144
|
-
) {
|
|
145
|
-
return target.owner.name
|
|
146
|
-
}
|
|
147
|
-
}
|
|
148
|
-
}
|
|
149
|
-
return undefined
|
|
150
|
-
}
|
|
151
|
-
|
|
152
|
-
function verifyClosedReferences(name: string, statements: readonly Statement[]): void {
|
|
153
|
-
for (const statement of statements) {
|
|
154
|
-
const data = statement
|
|
155
|
-
if (data.kind === "key") {
|
|
156
|
-
continue
|
|
157
|
-
}
|
|
158
|
-
const rendered = renderStatement(statement)
|
|
159
|
-
for (const face of [data.source, data.target]) {
|
|
160
|
-
for (const binding of face.selection) {
|
|
161
|
-
verifyClosedReferenceBinding(name, statements, face, binding, rendered)
|
|
162
|
-
}
|
|
163
|
-
}
|
|
164
|
-
}
|
|
165
|
-
}
|
|
166
|
-
|
|
167
|
-
function verifyClosedReferenceBinding(
|
|
168
|
-
name: string,
|
|
169
|
-
statements: readonly Statement[],
|
|
170
|
-
face: AnyFace,
|
|
171
|
-
binding: { readonly field: string; readonly set: LiteralSetSpec },
|
|
172
|
-
rendered: string
|
|
173
|
-
): void {
|
|
174
|
-
const spellsHandle = bindingLiterals(binding.set).some(function isHandle(literal) {
|
|
175
|
-
return literal.kind === "handle"
|
|
176
|
-
})
|
|
177
|
-
if (!spellsHandle) {
|
|
178
|
-
return
|
|
179
|
-
}
|
|
180
|
-
const roster = rosterOf(sealedFieldOf(face.owner, binding.field))
|
|
181
|
-
if (roster === undefined) {
|
|
182
|
-
return
|
|
183
|
-
}
|
|
184
|
-
if (isClosedMember(face.owner) && binding.field === "id") {
|
|
185
|
-
return
|
|
186
|
-
}
|
|
187
|
-
const resolved = closedTargetOf(statements, face.owner.name, binding.field)
|
|
188
|
-
if (resolved !== roster.name) {
|
|
189
|
-
throw new AuthoringError({
|
|
190
|
-
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}`
|
|
191
|
-
})
|
|
192
|
-
}
|
|
193
|
-
}
|
|
194
|
-
|
|
195
|
-
/**
|
|
196
|
-
* THE TARGET-KEY WALL, value tier (60-containment-parity — the runtime
|
|
197
|
-
* twin of `law.ts`'s `TargetKeyWall`, the engine's `resolve_target_key` /
|
|
198
|
-
* `resolve_capacity_target` mirrored exactly): every `contained`/
|
|
199
|
-
* `mirrors`/`capacity` statement's target projection must resolve a key
|
|
200
|
-
* of the target relation, judged over the SAME key population the engine
|
|
201
|
-
* materializes — the closed auto-keys
|
|
202
|
-
* ({@link collectImplied}'s roster) first, then the declared `key`
|
|
203
|
-
* statements in written order (a key may be declared after its probe, so
|
|
204
|
-
* this wall runs over the COMPLETE list, never inside the statement
|
|
205
|
-
* loop). `mirrors` materializes as two containments source-first, so both
|
|
206
|
-
* orientations judge their own target. SOUNDNESS BAR: the set-match +
|
|
207
|
-
* closed-id rule below is the engine's COMPLETE rule for this law
|
|
208
|
-
* (`matching_functionality` compares field SETS — permutations resolve,
|
|
209
|
-
* subsets/supersets refuse), so this wall never rejects what the engine
|
|
210
|
-
* accepts; every other schema judgment stays engine-first.
|
|
211
|
-
*/
|
|
212
|
-
function verifyTargetKeys(
|
|
213
|
-
name: string,
|
|
214
|
-
statements: readonly Statement[],
|
|
215
|
-
implied: ReadonlyMap<string, ReadonlyArray<readonly string[]>>
|
|
216
|
-
): void {
|
|
217
|
-
const declared = new Map<string, Array<readonly string[]>>()
|
|
218
|
-
for (const statement of statements) {
|
|
219
|
-
const data = statement
|
|
220
|
-
if (data.kind !== "key") {
|
|
221
|
-
continue
|
|
222
|
-
}
|
|
223
|
-
const keys = declared.get(data.owner.name)
|
|
224
|
-
if (keys === undefined) {
|
|
225
|
-
declared.set(data.owner.name, [data.projection])
|
|
226
|
-
} else {
|
|
227
|
-
keys.push(data.projection)
|
|
228
|
-
}
|
|
229
|
-
}
|
|
230
|
-
for (const statement of statements) {
|
|
231
|
-
const data = statement
|
|
232
|
-
if (data.kind === "key") {
|
|
233
|
-
continue
|
|
234
|
-
}
|
|
235
|
-
const rendered = renderStatement(statement)
|
|
236
|
-
|
|
237
|
-
const faces = data.kind === "mirrors" ? [data.target, data.source] : [data.target]
|
|
238
|
-
for (const face of faces) {
|
|
239
|
-
verifyTargetKeyFace(name, face, implied, declared, rendered)
|
|
240
|
-
}
|
|
241
|
-
}
|
|
242
|
-
}
|
|
243
|
-
|
|
244
|
-
/**
|
|
245
|
-
* One target face's key resolution (the {@link verifyTargetKeys} leaf).
|
|
246
|
-
* Closed target: the handle id is the ONE probe-able identity of a closed
|
|
247
|
-
* relation, so the projection must be exactly `["id"]` — its own refusal
|
|
248
|
-
* (the engine's `ClosedTargetNotHandle`): the rule is CLOSEDNESS, not key
|
|
249
|
-
* absence. Ordinary target: the projection's field-name SET must equal
|
|
250
|
-
* some roster member's set (the engine's `matching_functionality` —
|
|
251
|
-
* permutations resolve, subsets and supersets do not). The refusal speaks
|
|
252
|
-
* the engine's shape in NAMES, with the engine's pointwise hint verbatim
|
|
253
|
-
* when the projection carries an interval position.
|
|
254
|
-
*/
|
|
255
|
-
function verifyTargetKeyFace(
|
|
256
|
-
name: string,
|
|
257
|
-
face: AnyFace,
|
|
258
|
-
implied: ReadonlyMap<string, ReadonlyArray<readonly string[]>>,
|
|
259
|
-
declared: ReadonlyMap<string, ReadonlyArray<readonly string[]>>,
|
|
260
|
-
rendered: string
|
|
261
|
-
): void {
|
|
262
|
-
if (isClosedMember(face.owner)) {
|
|
263
|
-
if (face.projection.length === 1 && face.projection[0] === "id") {
|
|
264
|
-
return
|
|
265
|
-
}
|
|
266
|
-
throw new AuthoringError({
|
|
267
|
-
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"))`
|
|
268
|
-
})
|
|
269
|
-
}
|
|
270
|
-
const roster = [...(implied.get(face.owner.name) ?? []), ...(declared.get(face.owner.name) ?? [])]
|
|
271
|
-
const want = new Set(face.projection)
|
|
272
|
-
const matched = roster.some(function sameFieldSet(key) {
|
|
273
|
-
// engine's FieldSet refuses (duplicates are refused at the key()
|
|
274
|
-
|
|
275
|
-
if (key.length !== face.projection.length || want.size !== face.projection.length) {
|
|
276
|
-
return false
|
|
277
|
-
}
|
|
278
|
-
const keySet = new Set(key)
|
|
279
|
-
if (keySet.size !== want.size) {
|
|
280
|
-
return false
|
|
281
|
-
}
|
|
282
|
-
for (const field of keySet) {
|
|
283
|
-
if (!want.has(field)) {
|
|
284
|
-
return false
|
|
285
|
-
}
|
|
286
|
-
}
|
|
287
|
-
return true
|
|
288
|
-
})
|
|
289
|
-
if (matched) {
|
|
290
|
-
return
|
|
291
|
-
}
|
|
292
|
-
const available = roster.length === 0 ? "none" : roster.map((key) => `(${key.join(", ")})`).join("; ")
|
|
293
|
-
const pointwise = face.projection.some(function carriesInterval(fieldName) {
|
|
294
|
-
const descriptor = sealedFieldOf(face.owner, fieldName)
|
|
295
|
-
return descriptor !== undefined && descriptor.kind === "interval"
|
|
296
|
-
})
|
|
297
|
-
const hint = pointwise ? "; hint: declare the exact pointwise key `R(prefix…, interval) -> R`" : ""
|
|
298
|
-
throw new AuthoringError({
|
|
299
|
-
message: `schema ${name}: ${rendered}: target projection (${face.projection.join(", ")}) matches no declared key of ${face.owner.name} — available keys: ${available}${hint}`
|
|
300
|
-
})
|
|
301
|
-
}
|
|
302
|
-
|
|
303
56
|
type SchemaRelation = AnyRelation | AnyClosed
|
|
304
57
|
|
|
305
58
|
type SchemaRelations = Record<string, SchemaRelation>
|
|
@@ -351,7 +104,7 @@ const schemaComparisons = new WeakMap<AnySchema, WeakMap<AnySchema, boolean>>()
|
|
|
351
104
|
function schemaDescriptor<S extends AnySchema>(input: S): S
|
|
352
105
|
function schemaDescriptor(input: unknown): AnySchema
|
|
353
106
|
function schemaDescriptor(input: unknown): AnySchema {
|
|
354
|
-
return checkedSchema(input)
|
|
107
|
+
return isCompiledSchema(input) && isImmutable(input) ? input : checkedSchema(input)
|
|
355
108
|
}
|
|
356
109
|
|
|
357
110
|
const checkedSchema = descriptorCache((input): AnySchema => {
|
|
@@ -394,29 +147,15 @@ function schema<const Rels extends SchemaRelations, const Stmts extends readonly
|
|
|
394
147
|
assertDeclarationOrderKey("schema", name)
|
|
395
148
|
const ownedRelations = ownRelations(name, relations)
|
|
396
149
|
const ownedStatements = arrayValue("schema statements", statements, (_, statement) => statementDescriptor(statement))
|
|
397
|
-
|
|
398
|
-
const
|
|
399
|
-
for (const statement of ownedStatements) {
|
|
400
|
-
const rendered = renderStatement(statement)
|
|
401
|
-
verifyMembership(name, ownedRelations, statement, rendered)
|
|
402
|
-
if (implied.rendered.has(rendered)) {
|
|
403
|
-
throw new AuthoringError({
|
|
404
|
-
message: `schema ${name}: ${rendered} is redundant here (closedness already implies it) — and rejected as a duplicate`
|
|
405
|
-
})
|
|
406
|
-
}
|
|
407
|
-
if (seen.has(rendered)) {
|
|
408
|
-
throw new AuthoringError({ message: `schema ${name}: duplicate statement — ${rendered}` })
|
|
409
|
-
}
|
|
410
|
-
seen.add(rendered)
|
|
411
|
-
verifyHandles(name, statement, rendered)
|
|
412
|
-
}
|
|
413
|
-
verifyClosedReferences(name, ownedStatements)
|
|
414
|
-
verifyTargetKeys(name, ownedStatements, implied.roster)
|
|
150
|
+
verifyRelationNames(name, ownedRelations)
|
|
151
|
+
for (const statement of ownedStatements) verifyMembership(name, ownedRelations, statement, renderStatement(statement))
|
|
415
152
|
const classes = computeClasses(name, ownedRelations, ownedStatements)
|
|
416
153
|
if (!classesComplete<EvaluatedClasses<ClassesOf<Rels, Stmts>>>(classes, ownedRelations)) {
|
|
417
|
-
throw
|
|
154
|
+
throw internalError(`schema ${name}: class-map construction incomplete`)
|
|
418
155
|
}
|
|
419
|
-
|
|
156
|
+
const result = Object.freeze({ name, relations: ownedRelations, statements: Object.freeze(ownedStatements), classes })
|
|
157
|
+
registerCompiled(result)
|
|
158
|
+
return result
|
|
420
159
|
}
|
|
421
160
|
|
|
422
161
|
export type { AnySchema, Schema, SchemaRelation, SchemaRelations }
|
package/src/selection.ts
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import { type AnyClosed, memberDescriptor, sealedFieldOf, sealedFieldsOf } from "
|
|
2
|
-
import { AuthoringError } from "
|
|
3
|
-
import { type AnyField, assertDeclarationRecord, type ClosedIdField, type Infer, literalOf } from "
|
|
4
|
-
import type { AnyRelation, RelationFields } from "
|
|
5
|
-
import { type LiteralSetSpec, type LiteralSpec, renderLiteral } from "
|
|
6
|
-
import { arrayValue, recordValue } from "
|
|
1
|
+
import { type AnyClosed, memberDescriptor, sealedFieldOf, sealedFieldsOf } from "./closed.ts"
|
|
2
|
+
import { AuthoringError } from "./errors.ts"
|
|
3
|
+
import { type AnyField, assertDeclarationRecord, type ClosedIdField, type Infer, literalOf } from "./fields.ts"
|
|
4
|
+
import type { AnyRelation, RelationFields } from "./relation.ts"
|
|
5
|
+
import { type LiteralSetSpec, type LiteralSpec, renderLiteral } from "./spec.ts"
|
|
6
|
+
import { arrayValue, recordValue } from "./values.ts"
|
|
7
7
|
|
|
8
8
|
type Selectable = AnyRelation | AnyClosed
|
|
9
9
|
type FieldsOf<R extends Selectable> = R extends AnyRelation
|
package/src/shape.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import type { Query } from "
|
|
2
|
-
import type { inferred, ParamsRecord } from "
|
|
1
|
+
import type { Query } from "./query/lower.ts"
|
|
2
|
+
import type { inferred, ParamsRecord } from "./query/scope.ts"
|
|
3
3
|
/**
|
|
4
4
|
* Shared derived types: `S` is a
|
|
5
5
|
* declared core schema value's type, `Rel<S>` its ordinary (writable)
|
|
@@ -8,9 +8,9 @@ import type { inferred, ParamsRecord } from "#query/scope.ts"
|
|
|
8
8
|
* immutable schema-bound logical query template. All are derived from the
|
|
9
9
|
* existing typed descriptors — no second hand-maintained roster.
|
|
10
10
|
*/
|
|
11
|
-
import type { AnyRelation, Fact } from "
|
|
12
|
-
import type { AnySchema } from "
|
|
13
|
-
import type { KeyStatement } from "
|
|
11
|
+
import type { AnyRelation, Fact } from "./relation.ts"
|
|
12
|
+
import type { AnySchema } from "./schema.ts"
|
|
13
|
+
import type { KeyStatement } from "./statements.ts"
|
|
14
14
|
|
|
15
15
|
/** The ordinary relations of a schema (closed vocabularies are ground axioms, never ingestion targets). */
|
|
16
16
|
type Rel<S extends AnySchema> = Extract<S["relations"][keyof S["relations"]], AnyRelation>
|
package/src/spec.ts
CHANGED
|
@@ -1,19 +1,5 @@
|
|
|
1
1
|
import { regex } from "arkregex"
|
|
2
2
|
|
|
3
|
-
type ValueTypeSpec =
|
|
4
|
-
| { readonly kind: "bool" }
|
|
5
|
-
| { readonly kind: "u64" }
|
|
6
|
-
| { readonly kind: "i64" }
|
|
7
|
-
| { readonly kind: "f64" }
|
|
8
|
-
| { readonly kind: "uuid" }
|
|
9
|
-
| { readonly kind: "string" }
|
|
10
|
-
| { readonly kind: "fixedBytes"; readonly len: number }
|
|
11
|
-
| {
|
|
12
|
-
readonly kind: "interval"
|
|
13
|
-
readonly element: "u64" | "i64" | "f64"
|
|
14
|
-
readonly width: bigint | undefined
|
|
15
|
-
}
|
|
16
|
-
|
|
17
3
|
type ValueSpec =
|
|
18
4
|
| { readonly kind: "bool"; readonly value: boolean }
|
|
19
5
|
| { readonly kind: "u64"; readonly value: bigint }
|
|
@@ -26,6 +12,11 @@ type ValueSpec =
|
|
|
26
12
|
| { readonly kind: "intervalI64"; readonly start: bigint; readonly end: bigint }
|
|
27
13
|
| { readonly kind: "intervalF64"; readonly start: number; readonly end: number }
|
|
28
14
|
|
|
15
|
+
/** A tagged value on the data plane: a query param, or a member of a set param. */
|
|
16
|
+
type TaggedValue = ValueSpec
|
|
17
|
+
|
|
18
|
+
type QueryParam = TaggedValue | { readonly kind: "set"; readonly values: readonly TaggedValue[] }
|
|
19
|
+
|
|
29
20
|
type LiteralSpec =
|
|
30
21
|
| { readonly kind: "value"; readonly value: ValueSpec }
|
|
31
22
|
| { readonly kind: "handle"; readonly handle: string }
|
|
@@ -34,12 +25,6 @@ type LiteralSetSpec =
|
|
|
34
25
|
| { readonly kind: "one"; readonly literal: LiteralSpec }
|
|
35
26
|
| { readonly kind: "many"; readonly literals: readonly LiteralSpec[] }
|
|
36
27
|
|
|
37
|
-
interface SideSpec {
|
|
38
|
-
readonly relation: string
|
|
39
|
-
readonly projection: readonly string[]
|
|
40
|
-
readonly selection: ReadonlyArray<readonly [string, LiteralSetSpec]>
|
|
41
|
-
}
|
|
42
|
-
|
|
43
28
|
type CapacityBoundSpec =
|
|
44
29
|
| { readonly kind: "lit"; readonly value: bigint }
|
|
45
30
|
| { readonly kind: "field"; readonly field: string }
|
|
@@ -55,64 +40,6 @@ type CapacityWindowSpec =
|
|
|
55
40
|
| { readonly kind: "range"; readonly lo: CapacityBoundSpec; readonly hi: CapacityBoundSpec }
|
|
56
41
|
| { readonly kind: "floor"; readonly lo: CapacityBoundSpec }
|
|
57
42
|
|
|
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.
|
|
62
|
-
*/
|
|
63
|
-
interface FieldSpec {
|
|
64
|
-
readonly name: string
|
|
65
|
-
readonly valueType: ValueTypeSpec
|
|
66
|
-
readonly newtype: string | undefined
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
interface RowSpec {
|
|
70
|
-
readonly handle: string
|
|
71
|
-
readonly values: readonly LiteralSpec[]
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
/**
|
|
75
|
-
* A relation's closedness as ONE sum (ruled 2026-07-23, R7): the handle
|
|
76
|
-
* newtype and the ground axioms travel together — the two illegal states
|
|
77
|
-
* (a roster without its newtype, a newtype without its roster) are
|
|
78
|
-
* unspellable on the wire exactly as they are unrepresentable in the
|
|
79
|
-
* fused Rust `RelationSpec`. `newtype` is the id's law-computed generator
|
|
80
|
-
* class (`` `${name}.id` `` — the same label every referencing field
|
|
81
|
-
* carries by law), which is how the engine resolves a handle literal back
|
|
82
|
-
* to its roster.
|
|
83
|
-
*/
|
|
84
|
-
interface ClosedSpec {
|
|
85
|
-
readonly newtype: string
|
|
86
|
-
readonly rows: readonly RowSpec[]
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
interface RelationSpec {
|
|
90
|
-
readonly name: string
|
|
91
|
-
readonly fields: readonly FieldSpec[]
|
|
92
|
-
readonly closed: ClosedSpec | undefined
|
|
93
|
-
}
|
|
94
|
-
|
|
95
|
-
type StatementSpec =
|
|
96
|
-
| { readonly kind: "fd"; readonly relation: string; readonly projection: readonly string[] }
|
|
97
|
-
| {
|
|
98
|
-
readonly kind: "containment"
|
|
99
|
-
readonly source: SideSpec
|
|
100
|
-
readonly target: SideSpec
|
|
101
|
-
readonly bidirectional: boolean
|
|
102
|
-
}
|
|
103
|
-
| {
|
|
104
|
-
readonly kind: "capacity"
|
|
105
|
-
readonly target: SideSpec
|
|
106
|
-
readonly weight: WeightSpec
|
|
107
|
-
readonly window: CapacityWindowSpec
|
|
108
|
-
readonly source: SideSpec
|
|
109
|
-
}
|
|
110
|
-
|
|
111
|
-
interface SchemaSpec {
|
|
112
|
-
readonly relations: readonly RelationSpec[]
|
|
113
|
-
readonly statements: readonly StatementSpec[]
|
|
114
|
-
}
|
|
115
|
-
|
|
116
43
|
const NON_PRINTABLE = regex("[\\p{C}\\p{Z}]", "u")
|
|
117
44
|
|
|
118
45
|
const GRAPHEME_EXTEND = regex("\\p{Grapheme_Extend}", "u")
|
|
@@ -263,16 +190,11 @@ function renderWeight(weight: WeightSpec): string {
|
|
|
263
190
|
export type {
|
|
264
191
|
CapacityBoundSpec,
|
|
265
192
|
CapacityWindowSpec,
|
|
266
|
-
FieldSpec,
|
|
267
193
|
LiteralSetSpec,
|
|
268
194
|
LiteralSpec,
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
SchemaSpec,
|
|
272
|
-
SideSpec,
|
|
273
|
-
StatementSpec,
|
|
195
|
+
QueryParam,
|
|
196
|
+
TaggedValue,
|
|
274
197
|
ValueSpec,
|
|
275
|
-
ValueTypeSpec,
|
|
276
198
|
WeightSpec
|
|
277
199
|
}
|
|
278
200
|
export { f64BitsHex, renderCapacityWindow, renderLiteral, renderLiteralSet, renderWeight }
|
package/src/statements.ts
CHANGED
|
@@ -7,15 +7,15 @@ import {
|
|
|
7
7
|
type UnitDimensionBan,
|
|
8
8
|
unitWeight,
|
|
9
9
|
type WeightOnSource
|
|
10
|
-
} from "
|
|
11
|
-
import { isClosedMember, memberDescriptor, sealedFieldOf } from "
|
|
12
|
-
import { AuthoringError } from "
|
|
13
|
-
import { type AnyFace, faceDescriptor, renderFace, type SameArity, type SameShapes } from "
|
|
14
|
-
import { type AnyClosedRoster, assertDeclarationRecord, rosterOf, rostersAgree, signaturesAgree } from "
|
|
15
|
-
import { descriptorCache } from "
|
|
16
|
-
import type { AnyRelation, RelationFields } from "
|
|
17
|
-
import { type CapacityWindowSpec, renderCapacityWindow, renderWeight, type WeightSpec } from "
|
|
18
|
-
import { arrayValue, recordValue } from "
|
|
10
|
+
} from "./capacity.ts"
|
|
11
|
+
import { isClosedMember, memberDescriptor, sealedFieldOf } from "./closed.ts"
|
|
12
|
+
import { AuthoringError } from "./errors.ts"
|
|
13
|
+
import { type AnyFace, faceDescriptor, renderFace, type SameArity, type SameShapes } from "./face.ts"
|
|
14
|
+
import { type AnyClosedRoster, assertDeclarationRecord, rosterOf, rostersAgree, signaturesAgree } from "./fields.ts"
|
|
15
|
+
import { descriptorCache } from "./immutable.ts"
|
|
16
|
+
import type { AnyRelation, RelationFields } from "./relation.ts"
|
|
17
|
+
import { type CapacityWindowSpec, renderCapacityWindow, renderWeight, type WeightSpec } from "./spec.ts"
|
|
18
|
+
import { arrayValue, recordValue } from "./values.ts"
|
|
19
19
|
|
|
20
20
|
interface KeyStatement<R extends AnyRelation = AnyRelation, Projection extends readonly string[] = readonly string[]> {
|
|
21
21
|
readonly kind: "key"
|
|
@@ -46,7 +46,7 @@ function renderRosterSide(roster: AnyClosedRoster | undefined): string {
|
|
|
46
46
|
}
|
|
47
47
|
|
|
48
48
|
/**
|
|
49
|
-
* The runtime twin of {@link SameArity}
|
|
49
|
+
* The runtime twin of {@link SameArity}: the two
|
|
50
50
|
* faces must project equally many fields, judged at CONSTRUCTION for
|
|
51
51
|
* untyped callers too — without it an arity-mismatched containment
|
|
52
52
|
* silently truncates to the shorter projection (this module's positionwise
|
|
@@ -195,7 +195,7 @@ const checkedStatement = descriptorCache((raw): Statement => {
|
|
|
195
195
|
if (statement.kind === "capacity") {
|
|
196
196
|
const { weight, window } = statement
|
|
197
197
|
if (weight.kind === "unit" && window.kind === "range" && window.hi.kind === "durationField") {
|
|
198
|
-
throw new AuthoringError({ message: "a unit (count) window against a duration bound mixes dimensions
|
|
198
|
+
throw new AuthoringError({ message: "a unit (count) window against a duration bound mixes dimensions" })
|
|
199
199
|
}
|
|
200
200
|
assertWeightOnSource(weight, source, statement)
|
|
201
201
|
assertBoundsOnTarget(window, target, statement)
|
package/src/uuid.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { Result } from "effect"
|
|
2
|
-
import { DbError } from "
|
|
2
|
+
import { DbError } from "./errors.ts"
|
|
3
3
|
|
|
4
4
|
/** Structural UUID spelling, compatible with host generators and ordinary literals.
|
|
5
5
|
* Exact hexadecimal width and canonical case are checked at runtime boundaries.
|
package/src/values.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { type AuthoringDiagnostic, AuthoringError } from "
|
|
2
|
-
import type { AnyField, Infer } from "
|
|
3
|
-
import type { ValueSpec } from "
|
|
4
|
-
import { Uuid } from "
|
|
1
|
+
import { type AuthoringDiagnostic, AuthoringError } from "./errors.ts"
|
|
2
|
+
import type { AnyField, Infer } from "./fields.ts"
|
|
3
|
+
import type { ValueSpec } from "./spec.ts"
|
|
4
|
+
import { Uuid } from "./uuid.ts"
|
|
5
5
|
|
|
6
6
|
const U64_MAX = 0xffffffffffffffffn
|
|
7
7
|
const I64_MIN = -0x8000000000000000n
|
package/dist/close.d.ts
DELETED
|
@@ -1,24 +0,0 @@
|
|
|
1
|
-
import { Effect } from "effect";
|
|
2
|
-
import type { CloseReport } from "./runtime-errors.js";
|
|
3
|
-
/**
|
|
4
|
-
* Shared close/drain adapters for scoped core owners (drafts, changes,
|
|
5
|
-
* snapshots, sessions, results, cursors, databases). Early `close()` joins
|
|
6
|
-
* the native close transition and
|
|
7
|
-
* returns the honest {@link CloseReport}; a scope FINALIZER runs the same
|
|
8
|
-
* close and surfaces `incomplete`/`failed` as a structured `CloseFailure`
|
|
9
|
-
* DEFECT in the finalizer Cause — never catch-and-log, never false
|
|
10
|
-
* quiescence. Teardown uses the runtime's reserved cleanup envelope
|
|
11
|
-
* natively; repeated close joins the same stored transition (idempotent).
|
|
12
|
-
*/
|
|
13
|
-
import type { CloseWire } from "./runtime-native.js";
|
|
14
|
-
/**
|
|
15
|
-
* Adapts one native close verb to `Effect<CloseReport>`: registration is
|
|
16
|
-
* synchronous, completion resumes exactly once, and the whole wait is
|
|
17
|
-
* uninterruptible — a close is a bounded registration/drain handshake, not
|
|
18
|
-
* long maskable work (the native side owns the cleanup deadline).
|
|
19
|
-
*/
|
|
20
|
-
declare function drainClose(operation: string, start: (callback: (report: CloseWire) => void) => void): Effect.Effect<CloseReport>;
|
|
21
|
-
/** The finalizer policy: run the close, then die on incomplete/failed (E stays never). */
|
|
22
|
-
declare function releaseOwner(operation: string, start: (callback: (report: CloseWire) => void) => void): Effect.Effect<void>;
|
|
23
|
-
export { drainClose, releaseOwner };
|
|
24
|
-
//# sourceMappingURL=close.d.ts.map
|
package/dist/close.d.ts.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"close.d.ts","sourceRoot":"","sources":["../src/close.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAA;AAE/B,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAA;AAErD;;;;;;;;;GASG;AACH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAA;AASnD;;;;;GAKG;AACH,iBAAS,UAAU,CAClB,SAAS,EAAE,MAAM,EACjB,KAAK,EAAE,CAAC,QAAQ,EAAE,CAAC,MAAM,EAAE,SAAS,KAAK,IAAI,KAAK,IAAI,GACpD,MAAM,CAAC,MAAM,CAAC,WAAW,CAAC,CAa5B;AAED,0FAA0F;AAC1F,iBAAS,YAAY,CAAC,SAAS,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC,QAAQ,EAAE,CAAC,MAAM,EAAE,SAAS,KAAK,IAAI,KAAK,IAAI,GAAG,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,CAEpH;AAED,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,CAAA"}
|
package/dist/close.js
DELETED
|
@@ -1,34 +0,0 @@
|
|
|
1
|
-
import { Effect } from "effect";
|
|
2
|
-
import { finalizeClose } from "#runtime.ts";
|
|
3
|
-
import { DbError } from "#runtime-errors.ts";
|
|
4
|
-
function reportOf(operation, wire) {
|
|
5
|
-
if (wire.kind === "failed") {
|
|
6
|
-
return { kind: "failed", error: new DbError({ operation, reason: { _tag: "Internal" } }) };
|
|
7
|
-
}
|
|
8
|
-
return wire;
|
|
9
|
-
}
|
|
10
|
-
/**
|
|
11
|
-
* Adapts one native close verb to `Effect<CloseReport>`: registration is
|
|
12
|
-
* synchronous, completion resumes exactly once, and the whole wait is
|
|
13
|
-
* uninterruptible — a close is a bounded registration/drain handshake, not
|
|
14
|
-
* long maskable work (the native side owns the cleanup deadline).
|
|
15
|
-
*/
|
|
16
|
-
function drainClose(operation, start) {
|
|
17
|
-
return Effect.callback((resume) => {
|
|
18
|
-
try {
|
|
19
|
-
start((report) => resume(Effect.succeed(reportOf(operation, report))));
|
|
20
|
-
}
|
|
21
|
-
catch (cause) {
|
|
22
|
-
resume(Effect.succeed({
|
|
23
|
-
kind: "failed",
|
|
24
|
-
error: cause instanceof DbError ? cause : new DbError({ operation, reason: { _tag: "Internal" } })
|
|
25
|
-
}));
|
|
26
|
-
}
|
|
27
|
-
}).pipe(Effect.uninterruptible);
|
|
28
|
-
}
|
|
29
|
-
/** The finalizer policy: run the close, then die on incomplete/failed (E stays never). */
|
|
30
|
-
function releaseOwner(operation, start) {
|
|
31
|
-
return drainClose(operation, start).pipe(Effect.flatMap((report) => finalizeClose(operation, report)));
|
|
32
|
-
}
|
|
33
|
-
export { drainClose, releaseOwner };
|
|
34
|
-
//# sourceMappingURL=close.js.map
|
package/dist/close.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"close.js","sourceRoot":"","sources":["../src/close.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAA;AAC/B,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAA;AAE3C,OAAO,EAAE,OAAO,EAAE,MAAM,oBAAoB,CAAA;AAa5C,SAAS,QAAQ,CAAC,SAAiB,EAAE,IAAe;IACnD,IAAI,IAAI,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;QAC5B,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,KAAK,EAAE,IAAI,OAAO,CAAC,EAAE,SAAS,EAAE,MAAM,EAAE,EAAE,IAAI,EAAE,UAAU,EAAE,EAAE,CAAC,EAAE,CAAA;IAC3F,CAAC;IACD,OAAO,IAAI,CAAA;AACZ,CAAC;AAED;;;;;GAKG;AACH,SAAS,UAAU,CAClB,SAAiB,EACjB,KAAsD;IAEtD,OAAO,MAAM,CAAC,QAAQ,CAAc,CAAC,MAAM,EAAE,EAAE;QAC9C,IAAI,CAAC;YACJ,KAAK,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC,CAAA;QACvE,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YAChB,MAAM,CACL,MAAM,CAAC,OAAO,CAAC;gBACd,IAAI,EAAE,QAAQ;gBACd,KAAK,EAAE,KAAK,YAAY,OAAO,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,OAAO,CAAC,EAAE,SAAS,EAAE,MAAM,EAAE,EAAE,IAAI,EAAE,UAAU,EAAE,EAAE,CAAC;aAClG,CAAC,CACF,CAAA;QACF,CAAC;IACF,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,eAAe,CAAC,CAAA;AAChC,CAAC;AAED,0FAA0F;AAC1F,SAAS,YAAY,CAAC,SAAiB,EAAE,KAAsD;IAC9F,OAAO,UAAU,CAAC,SAAS,EAAE,KAAK,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,aAAa,CAAC,SAAS,EAAE,MAAM,CAAC,CAAC,CAAC,CAAA;AACvG,CAAC;AAED,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,CAAA"}
|