@bjornpagen/bumbledb 0.1.0 → 0.3.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.
Files changed (112) hide show
  1. package/COOKBOOK.md +1450 -0
  2. package/README.md +69 -30
  3. package/dist/closed.d.ts +157 -38
  4. package/dist/closed.d.ts.map +1 -1
  5. package/dist/closed.js +232 -47
  6. package/dist/closed.js.map +1 -1
  7. package/dist/count.d.ts +64 -17
  8. package/dist/count.d.ts.map +1 -1
  9. package/dist/count.js +37 -14
  10. package/dist/count.js.map +1 -1
  11. package/dist/db.d.ts +27 -8
  12. package/dist/db.d.ts.map +1 -1
  13. package/dist/db.js +33 -10
  14. package/dist/db.js.map +1 -1
  15. package/dist/exhume.d.ts +12 -11
  16. package/dist/exhume.d.ts.map +1 -1
  17. package/dist/exhume.js +7 -6
  18. package/dist/exhume.js.map +1 -1
  19. package/dist/face.d.ts +135 -30
  20. package/dist/face.d.ts.map +1 -1
  21. package/dist/face.js +44 -19
  22. package/dist/face.js.map +1 -1
  23. package/dist/fields.d.ts +130 -130
  24. package/dist/fields.d.ts.map +1 -1
  25. package/dist/fields.js +60 -94
  26. package/dist/fields.js.map +1 -1
  27. package/dist/index.d.ts +29 -24
  28. package/dist/index.d.ts.map +1 -1
  29. package/dist/index.js +19 -14
  30. package/dist/index.js.map +1 -1
  31. package/dist/law.d.ts +224 -0
  32. package/dist/law.d.ts.map +1 -0
  33. package/dist/law.js +224 -0
  34. package/dist/law.js.map +1 -0
  35. package/dist/lower.d.ts +17 -7
  36. package/dist/lower.d.ts.map +1 -1
  37. package/dist/lower.js +66 -24
  38. package/dist/lower.js.map +1 -1
  39. package/dist/marshal.d.ts +36 -21
  40. package/dist/marshal.d.ts.map +1 -1
  41. package/dist/marshal.js +41 -25
  42. package/dist/marshal.js.map +1 -1
  43. package/dist/native.d.ts +6 -2
  44. package/dist/native.d.ts.map +1 -1
  45. package/dist/native.js +2 -2
  46. package/dist/native.js.map +1 -1
  47. package/dist/query/atom.d.ts +370 -174
  48. package/dist/query/atom.d.ts.map +1 -1
  49. package/dist/query/atom.js +75 -172
  50. package/dist/query/atom.js.map +1 -1
  51. package/dist/query/lower.d.ts +312 -109
  52. package/dist/query/lower.d.ts.map +1 -1
  53. package/dist/query/lower.js +906 -387
  54. package/dist/query/lower.js.map +1 -1
  55. package/dist/query/predicate.d.ts +70 -88
  56. package/dist/query/predicate.d.ts.map +1 -1
  57. package/dist/query/predicate.js +118 -72
  58. package/dist/query/predicate.js.map +1 -1
  59. package/dist/query/run.d.ts +19 -16
  60. package/dist/query/run.d.ts.map +1 -1
  61. package/dist/query/run.js +31 -24
  62. package/dist/query/run.js.map +1 -1
  63. package/dist/query/scope.d.ts +178 -127
  64. package/dist/query/scope.d.ts.map +1 -1
  65. package/dist/query/scope.js +111 -108
  66. package/dist/query/scope.js.map +1 -1
  67. package/dist/query/select.d.ts +102 -80
  68. package/dist/query/select.d.ts.map +1 -1
  69. package/dist/query/select.js +39 -34
  70. package/dist/query/select.js.map +1 -1
  71. package/dist/relation.d.ts +48 -38
  72. package/dist/relation.d.ts.map +1 -1
  73. package/dist/relation.js +24 -19
  74. package/dist/relation.js.map +1 -1
  75. package/dist/schema.d.ts +41 -3
  76. package/dist/schema.d.ts.map +1 -1
  77. package/dist/schema.js +34 -9
  78. package/dist/schema.js.map +1 -1
  79. package/dist/spec.d.ts +7 -5
  80. package/dist/spec.d.ts.map +1 -1
  81. package/dist/spec.js.map +1 -1
  82. package/dist/statements.d.ts +91 -36
  83. package/dist/statements.d.ts.map +1 -1
  84. package/dist/statements.js +42 -12
  85. package/dist/statements.js.map +1 -1
  86. package/package.json +4 -3
  87. package/src/closed.ts +448 -95
  88. package/src/count.ts +112 -18
  89. package/src/db.ts +45 -17
  90. package/src/exhume.ts +12 -11
  91. package/src/face.ts +211 -41
  92. package/src/fields.ts +199 -234
  93. package/src/index.ts +78 -61
  94. package/src/law.ts +519 -0
  95. package/src/lower.ts +82 -27
  96. package/src/marshal.ts +48 -30
  97. package/src/native.ts +8 -4
  98. package/src/query/atom.ts +525 -374
  99. package/src/query/lower.ts +1469 -538
  100. package/src/query/predicate.ts +208 -161
  101. package/src/query/run.ts +35 -25
  102. package/src/query/scope.ts +264 -218
  103. package/src/query/select.ts +168 -93
  104. package/src/relation.ts +47 -47
  105. package/src/schema.ts +69 -18
  106. package/src/spec.ts +7 -5
  107. package/src/statements.ts +124 -41
  108. package/dist/brand.d.ts +0 -59
  109. package/dist/brand.d.ts.map +0 -1
  110. package/dist/brand.js +0 -47
  111. package/dist/brand.js.map +0 -1
  112. package/src/brand.ts +0 -82
package/src/count.ts CHANGED
@@ -1,10 +1,22 @@
1
1
  /**
2
2
  * Cardinality-window counts — exactly five constructors, and nothing else
3
- * (`docs/architecture/70-api.md` § the canonical-utterance law). The ban
4
- * table is enforced REPRESENTATIONALLY, stronger than Rust's expansion
5
- * errors: `{1..*}`, `{n..n}`, `{0..0}`, `{0..*}`, and inverted windows have
6
- * NO constructor — the spellings that could produce them are construction
7
- * errors naming the canonical form, and no other spelling exists at all.
3
+ * (`docs/architecture/70-api.md` § the canonical-utterance law). The five
4
+ * constructors PARTITION the legal windows, and the ban table is enforced
5
+ * REPRESENTATIONALLY, stronger than Rust's expansion errors, in two tiers:
6
+ *
7
+ * - **The type tier**: a banned spelling written as a LITERAL does not
8
+ * compile — `exactly(0n)`, `between(n, n)`, `between(0n, hi)`,
9
+ * `atLeast(0n)`, `atLeast(1n)`, `atMost(0n)`, and every negative bound
10
+ * are type errors naming the canonical form (`{n..n}`, `{0..0}`,
11
+ * `{0..hi}`-via-between, `{0..*}`, `{1..*}` have NO argument shape that
12
+ * produces them), and no sixth constructor exists at all.
13
+ * - **The construction tier**: a bound the type level cannot judge — a
14
+ * COMPUTED `bigint`, whose literal identity is erased, or an inverted
15
+ * `between(lo, hi)` order, which type-level bigints cannot compare — is
16
+ * judged here at construction with the same canonical-naming errors; and
17
+ * past both tiers the engine's own spec validation remains the law for a
18
+ * hostile FFI caller (the standing two-tier ban enforcement).
19
+ *
8
20
  * Bounds are `bigint` (u64 crosses as bigint always, PRD-04's law).
9
21
  */
10
22
 
@@ -36,14 +48,87 @@ interface Count {
36
48
 
37
49
  /** Stamps one admitted window as a frozen `Count` value. */
38
50
  function admit(window: WindowSpec): Count {
39
- return Object.freeze({ window, [admitted]: true as const })
51
+ const count: Count = { window, [admitted]: true }
52
+ return Object.freeze(count)
40
53
  }
41
54
 
55
+ /**
56
+ * The legible banned-spelling verdict: intersected into a count
57
+ * constructor's parameter when the LITERAL argument spells a banned window,
58
+ * naming the canonical form — the compile-time face of the ban table.
59
+ */
60
+ interface BannedWindow<Canonical extends string> {
61
+ readonly "banned window spelling — the canonical-utterance law names the one legal form": Canonical
62
+ }
63
+
64
+ /** `true` exactly when the literal bigint `N` is negative (out of the u64 count domain). */
65
+ type IsNegative<N extends bigint> = `${N}` extends `-${string}` ? true : false
66
+
67
+ /** The ban verdict on `exactly(n)`: negatives are out of domain; `{0}` is the exclusion, written `none`. */
68
+ type ExactlyBan<N extends bigint> = bigint extends N
69
+ ? unknown
70
+ : IsNegative<N> extends true
71
+ ? BannedWindow<"window counts are u64 — a negative count is out of domain">
72
+ : N extends 0n
73
+ ? BannedWindow<"`{0}` is the exclusion — write none">
74
+ : unknown
75
+
76
+ /** The ban verdict on `atLeast(lo)`: `{0..*}` is vacuous; `{1..*}` is the bare containment respelled. */
77
+ type AtLeastBan<N extends bigint> = bigint extends N
78
+ ? unknown
79
+ : IsNegative<N> extends true
80
+ ? BannedWindow<"window counts are u64 — a negative count is out of domain">
81
+ : N extends 0n
82
+ ? BannedWindow<"`{0..*}` is vacuous — it provably says nothing; delete the statement">
83
+ : N extends 1n
84
+ ? BannedWindow<"`{1..*}` says only what the bare containment says — write contained(source, target)">
85
+ : unknown
86
+
87
+ /** The ban verdict on `atMost(hi)`: `{0..0}` is the exclusion, written `none`. */
88
+ type AtMostBan<N extends bigint> = bigint extends N
89
+ ? unknown
90
+ : IsNegative<N> extends true
91
+ ? BannedWindow<"window counts are u64 — a negative count is out of domain">
92
+ : N extends 0n
93
+ ? BannedWindow<"`{0..0}` — the exclusion is written `{0}`: use none">
94
+ : unknown
95
+
96
+ /** The ban verdict on a `between` floor of zero: `{0..hi}` is the ceiling respelled (`atMost(hi)`). */
97
+ type BetweenFloorBan<Lo extends bigint> = Lo extends 0n
98
+ ? BannedWindow<"`{0..hi}` — a ceiling is written atMost(hi)">
99
+ : unknown
100
+
101
+ /**
102
+ * The ban verdict on `between(lo, hi)`, judged on the second bound once
103
+ * both literals are known: `{n..n}` is the exact count respelled
104
+ * (`exactly(n)`, or `none` at 0), and `{0..hi}` is the ceiling respelled
105
+ * (`atMost(hi)` — the five constructors PARTITION the legal windows, so
106
+ * the one ceiling window keeps its one spelling). Bound ORDER (`{hi..lo}`
107
+ * inverted) is not type-expressible — bigint literals have no type-level
108
+ * comparison — so inversion stays a construction error below.
109
+ */
110
+ type BetweenBan<Lo extends bigint, Hi extends bigint> = bigint extends Lo
111
+ ? unknown
112
+ : bigint extends Hi
113
+ ? unknown
114
+ : IsNegative<Lo> extends true
115
+ ? BannedWindow<"window counts are u64 — a negative bound is out of domain">
116
+ : IsNegative<Hi> extends true
117
+ ? BannedWindow<"window counts are u64 — a negative bound is out of domain">
118
+ : Lo extends Hi
119
+ ? Hi extends Lo
120
+ ? Lo extends 0n
121
+ ? BannedWindow<"`{0..0}` — the exclusion is written `{0}`: use none">
122
+ : BannedWindow<"`{n..n}` — an exact count is written `{n}`: use exactly(n)">
123
+ : BetweenFloorBan<Lo>
124
+ : BetweenFloorBan<Lo>
125
+
42
126
  /**
43
127
  * `{n}` — THE exact-count spelling, n ≥ 1. `exactly(0)` is the exclusion
44
- * respelled and rejected naming `none`.
128
+ * respelled: unwritable as a literal ({@link ExactlyBan} names `none`),
129
+ * rejected at construction when computed.
45
130
  */
46
- function exactly(n: bigint): Count {
131
+ function exactly<const N extends bigint>(n: N & ExactlyBan<N>): Count {
47
132
  if (n < 0n) {
48
133
  throw errors.new(`window counts are u64: exactly(${n}) is out of domain`)
49
134
  }
@@ -57,11 +142,15 @@ function exactly(n: bigint): Count {
57
142
  const none: Count = admit(exclusion)
58
143
 
59
144
  /**
60
- * `{lo..hi}` — both bounds explicit, 0 ≤ lo < hi. `lo === hi` is the exact
61
- * count respelled (rejected naming `exactly(n)`, or `none` at 0); an
62
- * inverted window is unsatisfiable and rejected.
145
+ * `{lo..hi}` — both bounds explicit, 1 ≤ lo < hi. `lo === hi` is the exact
146
+ * count respelled and `lo === 0` is the ceiling respelled: unwritable as
147
+ * literals ({@link BetweenBan} names `exactly(n)`, `none` at `{0..0}`, or
148
+ * `atMost(hi)` at a zero floor — the five constructors PARTITION the legal
149
+ * windows), rejected at construction when computed; an inverted window is
150
+ * unsatisfiable and rejected at construction (bigint literals carry no
151
+ * type-level order).
63
152
  */
64
- function between(lo: bigint, hi: bigint): Count {
153
+ function between<const Lo extends bigint, const Hi extends bigint>(lo: Lo, hi: Hi & BetweenBan<Lo, Hi>): Count {
65
154
  if (lo < 0n || hi < 0n) {
66
155
  throw errors.new(`window counts are u64: between(${lo}, ${hi}) is out of domain`)
67
156
  }
@@ -76,15 +165,19 @@ function between(lo: bigint, hi: bigint): Count {
76
165
  }
77
166
  throw errors.new(`\`{${lo}..${lo}}\` — an exact count is written \`{${lo}}\`: use exactly(${lo})`)
78
167
  }
168
+ if (lo === 0n) {
169
+ throw errors.new(`\`{0..${hi}}\` — a ceiling is written atMost: use atMost(${hi})`)
170
+ }
79
171
  return admit(Object.freeze({ kind: "range", lo, hi }))
80
172
  }
81
173
 
82
174
  /**
83
175
  * `{lo..*}` — a floor with no ceiling, lo ≥ 2: `atLeast(1)` says only what
84
- * the bare containment says (rejected naming `contained`), and
85
- * `atLeast(0)` is vacuous (rejected naming deletion).
176
+ * the bare containment says and `atLeast(0)` is vacuous — both unwritable
177
+ * as literals ({@link AtLeastBan} names the canonical form), rejected at
178
+ * construction when computed.
86
179
  */
87
- function atLeast(lo: bigint): Count {
180
+ function atLeast<const N extends bigint>(lo: N & AtLeastBan<N>): Count {
88
181
  if (lo < 0n) {
89
182
  throw errors.new(`window counts are u64: atLeast(${lo}) is out of domain`)
90
183
  }
@@ -100,10 +193,11 @@ function atLeast(lo: bigint): Count {
100
193
  }
101
194
 
102
195
  /**
103
- * `{0..hi}` — a ceiling, hi ≥ 1: `atMost(0)` is the exclusion respelled
104
- * and rejected naming `none`.
196
+ * `{0..hi}` — a ceiling, hi ≥ 1: `atMost(0)` is the exclusion respelled
197
+ * unwritable as a literal ({@link AtMostBan} names `none`), rejected at
198
+ * construction when computed.
105
199
  */
106
- function atMost(hi: bigint): Count {
200
+ function atMost<const N extends bigint>(hi: N & AtMostBan<N>): Count {
107
201
  if (hi < 0n) {
108
202
  throw errors.new(`window counts are u64: atMost(${hi}) is out of domain`)
109
203
  }
package/src/db.ts CHANGED
@@ -32,11 +32,10 @@
32
32
 
33
33
  import * as path from "node:path"
34
34
  import * as errors from "@superbuilders/errors"
35
- import { phantom } from "#brand.ts"
36
35
  import type { Exhumed } from "#exhume.ts"
37
36
  import { exhumeStore } from "#exhume.ts"
38
37
  import { lower } from "#lower.ts"
39
- import { factOf, isMintedFresh, type KeyFact, keyRowOf, type Minted, recordOf, rowOf } from "#marshal.ts"
38
+ import { factOf, isFreshField, isMintedFresh, type KeyFact, keyRowOf, type Minted, recordOf, rowOf } from "#marshal.ts"
40
39
 
41
40
  import type {
42
41
  DbHandle,
@@ -51,7 +50,8 @@ import type {
51
50
  ViolationFact as WireViolationFact
52
51
  } from "#native.ts"
53
52
  import { native } from "#native.ts"
54
- import type { Query, SelectColumn } from "#query/lower.ts"
53
+ import type { SelectColumn } from "#query/atom.ts"
54
+ import type { Query } from "#query/lower.ts"
55
55
  import { lowerQuery } from "#query/lower.ts"
56
56
  import { decodeAnswers, wireParams } from "#query/run.ts"
57
57
  import type { ParamEntry, ParamsRecord } from "#query/scope.ts"
@@ -68,8 +68,8 @@ type MemberRelation<Rels extends SchemaRelations> = Extract<Rels[keyof Rels], An
68
68
 
69
69
  /**
70
70
  * The key object of a key-statement-selected `get`: exactly the selected
71
- * `key()` statement's projection fields, each carrying the relation's own
72
- * branded value type — the {@link KeyFact} rule generalized from the
71
+ * `key()` statement's projection fields, each at the relation's own BARE
72
+ * structural value type — the {@link KeyFact} rule generalized from the
73
73
  * primary key to ANY declared key statement.
74
74
  */
75
75
  type DeclaredKeyFact<R extends AnyRelation, Projection extends readonly string[]> = {
@@ -194,7 +194,7 @@ type WitnessedWriteResult<Rels extends SchemaRelations, R> =
194
194
  interface Tx<Rels extends SchemaRelations> {
195
195
  /**
196
196
  * Records one insert. Omitted fresh fields are MINTED through the
197
- * engine's alloc lane and returned branded; supplying them instead
197
+ * engine's alloc lane and returned as bare bigints; supplying them instead
198
198
  * preserves identity (the resupply idiom). Returns the relation's
199
199
  * fresh cells, minted or resupplied.
200
200
  */
@@ -236,7 +236,7 @@ interface ReadScope<Rels extends SchemaRelations> {
236
236
  * open and the generation read.
237
237
  */
238
238
  readonly generation: bigint
239
- /** Full-relation export in row-id order, decoded to branded facts. */
239
+ /** Full-relation export in row-id order, decoded to bare structural facts. */
240
240
  scan<R extends MemberRelation<Rels>>(relation: R): Fact<R>[]
241
241
  /**
242
242
  * Committed-state point lookup through the relation's primary key
@@ -258,12 +258,22 @@ interface ReadScope<Rels extends SchemaRelations> {
258
258
  /**
259
259
  * Executes a prepared query against this scope's snapshot with the
260
260
  * typed params object; returns the answer SET as plain rows with
261
- * branded values (no order — the host sorts). This is the ONE
261
+ * bare structural values (no order — the host sorts). This is the ONE
262
262
  * execution spelling ({@link Prepared} carries no `execute`).
263
263
  */
264
264
  execute<Row, Params extends ParamsRecord>(prepared: Prepared<Rels, Row, Params>, params: Params): Row[]
265
265
  }
266
266
 
267
+ /**
268
+ * The module-private inference slot of {@link Prepared}: an optional symbol
269
+ * property (never set at runtime) that keeps the prepared value's `Row` and
270
+ * `Params` type arguments load-bearing, so `execute` infers the typed rows
271
+ * and the typed params object from the value alone — the query module's
272
+ * `inferred` pattern, local to this module. A type-level carrier only:
273
+ * values stay bare, nothing is asserted.
274
+ */
275
+ const preparedTypes: unique symbol = Symbol("bumbledb.prepared.types")
276
+
267
277
  /**
268
278
  * One prepared query as a plain VALUE: explicit visible compilation
269
279
  * (`db.prepare(q)` lowers, pins the plan, and surfaces every engine roster
@@ -281,7 +291,7 @@ interface Prepared<Rels extends SchemaRelations, Row, Params extends ParamsRecor
281
291
  * re-prepare.
282
292
  */
283
293
  staleness(snap: ReadScope<Rels>): Staleness
284
- readonly [phantom]?: { readonly row: Row; readonly params: Params }
294
+ readonly [preparedTypes]?: { readonly row: Row; readonly params: Params }
285
295
  }
286
296
 
287
297
  /**
@@ -424,7 +434,7 @@ function impliedKeyEntries(theory: AnySchema): StatementEntry[] {
424
434
  continue
425
435
  }
426
436
  for (const declared of member.data.fields) {
427
- if (declared.field.minted) {
437
+ if (isFreshField(declared.field)) {
428
438
  entries.push({
429
439
  kind: "functionality",
430
440
  statement: undefined,
@@ -642,7 +652,7 @@ function mintFreshCells(
642
652
  ): Record<string, FactValue> {
643
653
  const fresh: Record<string, FactValue> = {}
644
654
  for (const declared of relation.data.fields) {
645
- if (!declared.field.minted) {
655
+ if (!isFreshField(declared.field)) {
646
656
  continue
647
657
  }
648
658
  let cell = values[declared.name]
@@ -1338,7 +1348,7 @@ function openDb<Rels extends SchemaRelations>(handle: DbHandle, theory: Schema<R
1338
1348
  Object.freeze({
1339
1349
  handle: preparedHandle,
1340
1350
  owner,
1341
- params: q.data.registry.params,
1351
+ params: q.data.params,
1342
1352
  select: q.data.select
1343
1353
  })
1344
1354
  )
@@ -1409,16 +1419,31 @@ process.once("exit", function closeCachedStores() {
1409
1419
  }
1410
1420
  })
1411
1421
 
1422
+ /**
1423
+ * The engine twin of the schema-level class wall, as a matchable value
1424
+ * (`errors.is`): the shared lowering rejected a spec whose statement pairs
1425
+ * faces with disagreeing newtype labels — the faces of a dependency agree
1426
+ * on their newtype, or neither carries one. UNREACHABLE through the typed
1427
+ * builder (the SDK computes every label from the laws, so its lowered
1428
+ * specs cohere by construction); a raw spec handed to the bridge is the
1429
+ * one road here, and the runtime referee that proves the engine judges
1430
+ * what the types claim.
1431
+ */
1432
+ const ErrNewtypeMismatch = errors.new(
1433
+ "bumbledb newtypeMismatch: a statement pairs faces whose newtypes disagree — the faces of a dependency agree on their newtype, or neither carries one"
1434
+ )
1435
+
1412
1436
  /**
1413
1437
  * The one admission path both verbs share: canonical-path cache lookup
1414
1438
  * first (a hit returns the SAME `Db` value for the identical theory, a
1415
1439
  * typed fingerprint error for a different one, and a typed refusal for
1416
1440
  * `create` — the store a cache entry proves initialized is exactly what
1417
1441
  * create refuses). On a miss: lower the theory, run one bridge call, and
1418
- * wrap the two domain refusals — `schemaError` (spec resolution + schema
1419
- * validation, every issue in one message) and `fingerprintMismatch` (a
1420
- * different theory cannot open the store) into typed errors carrying the
1421
- * engine's message intact.
1442
+ * wrap the domain refusals — `schemaError` (spec resolution + schema
1443
+ * validation, every issue in one message), `newtypeMismatch` (the
1444
+ * coherence wall, {@link ErrNewtypeMismatch}), and `fingerprintMismatch`
1445
+ * (a different theory cannot open the store) — into typed errors carrying
1446
+ * the engine's message intact.
1422
1447
  */
1423
1448
  function admit<Rels extends SchemaRelations>(
1424
1449
  verb: "create" | "open",
@@ -1448,6 +1473,9 @@ function admit<Rels extends SchemaRelations>(
1448
1473
  return native.dbOpen(canonical, spec)
1449
1474
  })
1450
1475
  if (!opened.ok) {
1476
+ if (opened.kind === "newtypeMismatch") {
1477
+ throw errors.wrap(ErrNewtypeMismatch, `${verb} ${canonical}: ${opened.message}`)
1478
+ }
1451
1479
  throw errors.new(`bumbledb ${opened.kind} (${verb} ${canonical}): ${opened.message}`)
1452
1480
  }
1453
1481
  const manifest = bridged("fetch bumbledb manifest", function fetchManifest() {
@@ -1516,4 +1544,4 @@ export type {
1516
1544
  WitnessedWriteResult,
1517
1545
  WriteResult
1518
1546
  }
1519
- export { abandon, Db }
1547
+ export { abandon, Db, ErrNewtypeMismatch }
package/src/exhume.ts CHANGED
@@ -8,13 +8,14 @@
8
8
  * is read back for rebirth (exhume the old store, create the successor
9
9
  * under the new theory, copy by NAME, re-derive).
10
10
  *
11
- * DELIBERATELY UNTYPED: no branded type appears anywhere on this surface.
12
- * The caller's schema is the wrong theory for an exhumed store BY
11
+ * DELIBERATELY SCHEMA-FREE: no schema type appears anywhere on this
12
+ * surface. The caller's schema is the wrong theory for an exhumed store BY
13
13
  * DEFINITION (a store the current theory could open would never need
14
- * exhuming), so every value crosses as its plain natural JS form and every
15
- * fact is keyed by field NAME. The SDK never reconstructs a `Schema` value
16
- * from the descriptor that inverse mapping is deliberately out of scope;
17
- * the rebirth tool keys by name.
14
+ * exhuming), so every value crosses TYPED at its bare structural form
15
+ * ({@link FactValue} bigint/string/boolean/bytes/interval, never
16
+ * `unknown`) and every fact is keyed by field NAME. The SDK never
17
+ * reconstructs a `Schema` value from the descriptor that inverse mapping
18
+ * is deliberately out of scope; the rebirth tool keys by name.
18
19
  *
19
20
  * ZERO CLOSABLES: no value here carries a close, dispose, or release
20
21
  * spelling. The engine-side handle (and the store's exclusive advisory
@@ -57,9 +58,9 @@ const ErrExhumeFormatMismatch = errors.new(
57
58
  const ErrExhumeCorruption = errors.new("bumbledb exhume: the persisted schema descriptor fails its integrity gates")
58
59
 
59
60
  /**
60
- * One exhumed fact as a plain name-keyed record of natural JS values
61
- * deliberately untyped (module doc): `bigint` for u64/i64, `string` for
62
- * str, `boolean` for bool, `Uint8Array` for bytes<N>, a `{ start, end }`
61
+ * One exhumed fact as a plain name-keyed record of bare structural values
62
+ * deliberately schema-free (module doc): `bigint` for u64/i64, `string`
63
+ * for str, `boolean` for bool, `Uint8Array` for bytes<N>, a `{ start, end }`
63
64
  * bigint pair for intervals. Closed-relation rows open with the synthetic
64
65
  * `id` field, exactly as the descriptor's sealed field list declares.
65
66
  */
@@ -105,8 +106,8 @@ interface ExhumedRelation {
105
106
  * persisted descriptor: relations in engine-id order (declaration order
106
107
  * mints every id), each with its ordered field descriptions and closed
107
108
  * roster — enough for a caller to key facts by name and re-insert them
108
- * into a differently-fingerprinted successor store. No branded type
109
- * appears here (module doc: exhumed data is deliberately untyped).
109
+ * into a differently-fingerprinted successor store. No schema type appears
110
+ * here (module doc: the surface is schema-free; rows are typed bare).
110
111
  */
111
112
  interface ExhumedDescriptor {
112
113
  readonly relations: readonly ExhumedRelation[]