@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/marshal.ts CHANGED
@@ -1,24 +1,39 @@
1
1
  /**
2
- * The marshal layer (PRD-07): fact object ⇄ positional `FactValue[]` by
3
- * field ordinal, schema-directed, in ONE place only. The write side lowers
4
- * named host objects to rows in the relation's field-declaration order
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
5
  * (declaration order = ordinal ids, the macro's law); the read side decodes
6
- * rows back to named objects with brands applied by assertion — the store
7
- * is the proof carrier: a row the engine admitted IS a legal fact of its
8
- * relation, so readback asserts the brand instead of re-judging the value
9
- * (the same trust direction as Rust's typed readback). Shape mismatches
10
- * here are genuine failures and THROW typed; they are never domain data.
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.
11
16
  */
12
17
 
13
18
  import * as errors from "@superbuilders/errors"
14
- import type { FieldData } from "#fields.ts"
19
+ import type { AnyField } from "#fields.ts"
15
20
  import type { FactValue } from "#native.ts"
16
21
  import type { AnyRelation, Fact, FreshKeys, RelationData } from "#relation.ts"
17
22
 
23
+ /**
24
+ * The fresh-mark probe: `true` exactly for a `.fresh`-marked u64 descriptor
25
+ * (the S1 kernel's one structural mark — an unmarked u64's `fresh` property
26
+ * holds the MARKED descriptor, so the probe compares against the literal
27
+ * `true`, never truthiness).
28
+ */
29
+ function isFreshField(field: AnyField): boolean {
30
+ return "fresh" in field && field.fresh === true
31
+ }
32
+
18
33
  /**
19
34
  * The inferred object type `tx.insert` returns: one property per
20
- * fresh-marked field of `R`, carrying the minted (or resupplied) branded
21
- * id. A relation with no fresh field returns the empty object.
35
+ * fresh-marked field of `R`, carrying the minted (or resupplied) id as a
36
+ * bare `bigint`. A relation with no fresh field returns the empty object.
22
37
  */
23
38
  type Minted<R extends AnyRelation> = { [K in FreshKeys<R>]: Fact<R>[K] }
24
39
 
@@ -30,7 +45,8 @@ type Minted<R extends AnyRelation> = { [K in FreshKeys<R>]: Fact<R>[K] }
30
45
  * relation's primary key is always its fresh field. When `R` carries a
31
46
  * fresh field the type demands exactly that field; otherwise the primary
32
47
  * key lives in the schema's statement list, which the type system cannot
33
- * see (statements are untyped values), so the type admits any partial fact
48
+ * see (the schema's statement list is not carried in the schema's type,
49
+ * only in the KeyStatement values themselves), so the type admits any partial fact
34
50
  * and the projection is verified at runtime — a missing key field throws
35
51
  * naming the projection.
36
52
  */
@@ -66,12 +82,13 @@ function recordOf(fact: object): Record<string, unknown> {
66
82
 
67
83
  /**
68
84
  * Marshals one host cell at its field position to the natural wire value,
69
- * schema-directed by the field's structural type (never guessed). Brands
70
- * are phantoms, so the runtime values are exactly the wire's natural JS
71
- * values; only widths and domains are left to the engine's own judge.
85
+ * schema-directed by the field descriptor's structural kind (never
86
+ * guessed). Values are bare, so the runtime values ARE the wire's natural
87
+ * JS values; widths and domain labels are the engine's own judgment at the
88
+ * write boundary.
72
89
  */
73
- function cellOf(context: string, field: FieldData, value: unknown): FactValue {
74
- switch (field.type.kind) {
90
+ function cellOf(context: string, field: AnyField, value: unknown): FactValue {
91
+ switch (field.kind) {
75
92
  case "bool": {
76
93
  if (typeof value !== "boolean") {
77
94
  throw cellShapeError(context, "boolean", value)
@@ -85,7 +102,7 @@ function cellOf(context: string, field: FieldData, value: unknown): FactValue {
85
102
  }
86
103
  return value
87
104
  }
88
- case "string": {
105
+ case "str": {
89
106
  if (typeof value !== "string") {
90
107
  throw cellShapeError(context, "string", value)
91
108
  }
@@ -101,7 +118,7 @@ function cellOf(context: string, field: FieldData, value: unknown): FactValue {
101
118
  }
102
119
  return value
103
120
  }
104
- case "fixedBytes": {
121
+ case "bytes": {
105
122
  if (!(value instanceof Uint8Array)) {
106
123
  throw cellShapeError(context, "Uint8Array", value)
107
124
  }
@@ -162,11 +179,11 @@ function keyRowOf(
162
179
 
163
180
  /**
164
181
  * The read-side trusted seam: a decoded row carrying every declared field
165
- * IS a fact of its relation — the engine admitted it, so the brand is
166
- * asserted, not re-derived. The checkable half (completeness) is verified;
167
- * the phantom half (brands) is carried by the store's own judgment.
182
+ * IS a fact of its relation — the engine admitted the row, and the values
183
+ * are BARE structural values, so nothing is asserted beyond presence (no
184
+ * brand exists to re-derive; the store is the proof carrier).
168
185
  */
169
- function isBrandedFact<R extends AnyRelation>(
186
+ function isCompleteFact<R extends AnyRelation>(
170
187
  relation: R,
171
188
  decoded: Readonly<Record<string, FactValue>>
172
189
  ): decoded is Readonly<Record<string, FactValue>> & Fact<R> {
@@ -178,21 +195,22 @@ function isBrandedFact<R extends AnyRelation>(
178
195
  /**
179
196
  * The insert-return trusted seam: the collected fresh cells of one insert
180
197
  * (minted by the engine or resupplied by the caller) are the relation's
181
- * branded fresh ids — same assertion direction as {@link isBrandedFact}.
198
+ * fresh ids as bare bigints — same presence-only direction as
199
+ * {@link isCompleteFact}.
182
200
  */
183
201
  function isMintedFresh<R extends AnyRelation>(
184
202
  relation: R,
185
203
  minted: Readonly<Record<string, FactValue>>
186
204
  ): minted is Readonly<Record<string, FactValue>> & Minted<R> {
187
205
  return relation.data.fields.every(function presentWhenFresh(declared) {
188
- return !declared.field.minted || minted[declared.name] !== undefined
206
+ return !isFreshField(declared.field) || minted[declared.name] !== undefined
189
207
  })
190
208
  }
191
209
 
192
210
  /**
193
- * Unmarshals one positional row to the relation's named, branded, frozen
194
- * fact object — the inverse of {@link rowOf}, ordinal-directed by the same
195
- * declaration order.
211
+ * Unmarshals one positional row to the relation's named, frozen fact object
212
+ * of bare structural values — the inverse of {@link rowOf},
213
+ * ordinal-directed by the same declaration order.
196
214
  */
197
215
  function factOf<R extends AnyRelation>(relation: R, row: readonly FactValue[]): Fact<R> {
198
216
  const data = relation.data
@@ -210,11 +228,11 @@ function factOf<R extends AnyRelation>(relation: R, row: readonly FactValue[]):
210
228
  decoded[declared.name] = cell
211
229
  })
212
230
  Object.freeze(decoded)
213
- if (!isBrandedFact(relation, decoded)) {
231
+ if (!isCompleteFact(relation, decoded)) {
214
232
  throw errors.new(`relation ${data.name}: decoded row is not a complete fact`)
215
233
  }
216
234
  return decoded
217
235
  }
218
236
 
219
237
  export type { KeyFact, Minted }
220
- export { cellOf, factOf, isMintedFresh, keyRowOf, recordOf, rowOf }
238
+ export { cellOf, factOf, isFreshField, isMintedFresh, keyRowOf, recordOf, rowOf }
package/src/native.ts CHANGED
@@ -244,13 +244,17 @@ interface Violation {
244
244
  * `dbCreate`/`dbOpen`'s domain outcome. `schemaError` covers both spec
245
245
  * resolution (unresolvable names, banned spellings — every issue in one
246
246
  * message) and schema validation at the declaration boundary;
247
- * `fingerprintMismatch` is `dbOpen`'s stored-theory refusal.
247
+ * `newtypeMismatch` is the coherence wall's own kind — a spec whose
248
+ * statement pairs faces with disagreeing newtype labels (the engine twin
249
+ * of the schema-level class wall; unreachable through the typed builder,
250
+ * which computes every label from the laws, so only a raw spec can reach
251
+ * it); `fingerprintMismatch` is `dbOpen`'s stored-theory refusal.
248
252
  */
249
253
  type DbOpenResult =
250
254
  | { readonly ok: true; readonly db: DbHandle }
251
255
  | {
252
256
  readonly ok: false
253
- readonly kind: "schemaError" | "fingerprintMismatch"
257
+ readonly kind: "schemaError" | "newtypeMismatch" | "fingerprintMismatch"
254
258
  readonly message: string
255
259
  }
256
260
 
@@ -479,8 +483,8 @@ const SHIPPED_PLATFORMS = "darwin-arm64"
479
483
  * It resolves the per-platform binary package by name (see
480
484
  * {@link loadNativeBinding}); the addon never crosses as a relative path.
481
485
  * createRequire is the only unflagged Node-API addon loader in ESM, and this
482
- * file is the package's single sanctioned FFI boundary
483
- * (docs/road-to-1.0.0/prd-03-arch-split-packaging.md).
486
+ * file is the package's single sanctioned FFI boundary (the arch-split
487
+ * packaging ruling).
484
488
  */
485
489
  const requireNative = createRequire(import.meta.url)
486
490