@bjornpagen/bumbledb 0.3.0 → 0.4.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 (66) hide show
  1. package/COOKBOOK.md +66 -46
  2. package/README.md +28 -15
  3. package/dist/closed.d.ts +50 -73
  4. package/dist/closed.d.ts.map +1 -1
  5. package/dist/closed.js +38 -109
  6. package/dist/closed.js.map +1 -1
  7. package/dist/db.d.ts +4 -1
  8. package/dist/db.d.ts.map +1 -1
  9. package/dist/db.js +26 -3
  10. package/dist/db.js.map +1 -1
  11. package/dist/face.d.ts +39 -39
  12. package/dist/face.d.ts.map +1 -1
  13. package/dist/face.js +7 -16
  14. package/dist/face.js.map +1 -1
  15. package/dist/fields.d.ts +28 -14
  16. package/dist/fields.d.ts.map +1 -1
  17. package/dist/fields.js +15 -14
  18. package/dist/fields.js.map +1 -1
  19. package/dist/index.d.ts +2 -2
  20. package/dist/index.d.ts.map +1 -1
  21. package/dist/index.js +1 -1
  22. package/dist/index.js.map +1 -1
  23. package/dist/marshal.d.ts +33 -6
  24. package/dist/marshal.d.ts.map +1 -1
  25. package/dist/marshal.js +67 -6
  26. package/dist/marshal.js.map +1 -1
  27. package/dist/query/atom.d.ts +59 -14
  28. package/dist/query/atom.d.ts.map +1 -1
  29. package/dist/query/atom.js +3 -0
  30. package/dist/query/atom.js.map +1 -1
  31. package/dist/query/lower.d.ts.map +1 -1
  32. package/dist/query/lower.js +251 -26
  33. package/dist/query/lower.js.map +1 -1
  34. package/dist/query/run.d.ts +15 -5
  35. package/dist/query/run.d.ts.map +1 -1
  36. package/dist/query/run.js +26 -6
  37. package/dist/query/run.js.map +1 -1
  38. package/dist/query/scope.d.ts +35 -13
  39. package/dist/query/scope.d.ts.map +1 -1
  40. package/dist/query/scope.js +16 -4
  41. package/dist/query/scope.js.map +1 -1
  42. package/dist/relation.d.ts +8 -7
  43. package/dist/relation.d.ts.map +1 -1
  44. package/dist/relation.js +32 -10
  45. package/dist/relation.js.map +1 -1
  46. package/dist/spec.d.ts +3 -2
  47. package/dist/spec.d.ts.map +1 -1
  48. package/dist/spec.js.map +1 -1
  49. package/dist/statements.d.ts +10 -4
  50. package/dist/statements.d.ts.map +1 -1
  51. package/dist/statements.js +79 -7
  52. package/dist/statements.js.map +1 -1
  53. package/package.json +2 -2
  54. package/src/closed.ts +72 -179
  55. package/src/db.ts +42 -5
  56. package/src/face.ts +34 -45
  57. package/src/fields.ts +46 -34
  58. package/src/index.ts +1 -2
  59. package/src/marshal.ts +74 -7
  60. package/src/query/atom.ts +58 -15
  61. package/src/query/lower.ts +301 -28
  62. package/src/query/run.ts +26 -6
  63. package/src/query/scope.ts +49 -15
  64. package/src/relation.ts +45 -17
  65. package/src/spec.ts +3 -2
  66. package/src/statements.ts +86 -7
package/COOKBOOK.md CHANGED
@@ -33,6 +33,7 @@ Everything below imports from the one package entry:
33
33
  import {
34
34
  ALLEN,
35
35
  Db,
36
+ type Infer,
36
37
  abandon,
37
38
  allen,
38
39
  bool,
@@ -150,8 +151,8 @@ relations, glued by bidirectional conditional containments.
150
151
 
151
152
  ```ts
152
153
  // The discriminator vocabulary is a closed relation: its ground axioms are
153
- // axioms, and the handle constants (`Kind.Deterministic`, bare bigints) are
154
- // the literals on every surface.
154
+ // axioms, and a handle is its NAME the string literal "Deterministic" is
155
+ // the ONE spelling, on every surface (statements, inserts, queries, rows).
155
156
  const Kind = closed("Kind", ["Deterministic", "CustomOperator"])
156
157
  const Task = relation("Task", { id: u64.fresh, kind: Kind.id })
157
158
  const DeterministicGrading = relation("DeterministicGrading", { task: u64, tolerance: i64 })
@@ -166,21 +167,28 @@ const Grading = schema("Grading", { Kind, Task, DeterministicGrading, CustomOper
166
167
  // exists WITH that kind — composite-FK-plus-CHECK, one statement. These
167
168
  // mirrors are also what type `task` on both arms: each lands in the
168
169
  // "Task.id" generator class.
169
- mirrors(on(Task.where({ kind: Kind.Deterministic }), "id"), on(DeterministicGrading, "task")),
170
- mirrors(on(Task.where({ kind: Kind.CustomOperator }), "id"), on(CustomOperatorGrading, "task"))
170
+ mirrors(on(Task.where({ kind: "Deterministic" }), "id"), on(DeterministicGrading, "task")),
171
+ mirrors(on(Task.where({ kind: "CustomOperator" }), "id"), on(CustomOperatorGrading, "task"))
171
172
  // Exclusivity is a theorem, not a statement: one id in two arms would
172
173
  // force `kind` to equal two handles against the fresh key on id.
173
174
  // The executor spends the same theorem again — recipe 22's free lunch.
174
175
  ])
175
176
 
176
- // Host dispatch over the discriminator is `match` exhaustive over the
177
- // sealed roster by construction (a missing arm is a compile error; an
178
- // out-of-roster id throws, never misdispatches):
179
- const gradedBy = (kind: bigint) =>
180
- Kind.match(kind, {
181
- Deterministic: () => "tolerance",
182
- CustomOperator: () => "operator"
183
- })
177
+ // Host dispatch over the discriminator is native `switch` narrowing over
178
+ // the handle union (`Infer<typeof Kind.id>` = "Deterministic" |
179
+ // "CustomOperator") rows already arrive carrying the handle name, and
180
+ // `satisfies never` makes the switch exhaustive: a missing arm is a
181
+ // compile error.
182
+ const gradedBy = (kind: Infer<typeof Kind.id>) => {
183
+ switch (kind) {
184
+ case "Deterministic":
185
+ return "tolerance"
186
+ case "CustomOperator":
187
+ return "operator"
188
+ default:
189
+ return kind satisfies never
190
+ }
191
+ }
184
192
  ```
185
193
 
186
194
  ## 3. 0..1 optional attributes
@@ -301,13 +309,13 @@ declared priority handles.
301
309
  The enum idiom's replacement, first-class: a vocabulary is a **closed
302
310
  relation** — its ground axioms are declared in the schema, sealed at
303
311
  validate, frozen by the fingerprint, virtual in storage. The store holds zero
304
- vocabulary bytes, and handles are the literals on every surface.
312
+ vocabulary bytes, and handle names are the string literals on every surface.
305
313
 
306
314
  ```ts
307
- // Tier 1: handles only. `closed()` mints one bare-bigint constant per handle
308
- // (ids = declaration order) an emission, not a type: the engine's
309
- // vocabulary stays relational; the host matches on `Priority.Urgent`, or
310
- // dispatches exhaustively with `Priority.match` (recipe 2).
315
+ // Tier 1: handles only. At the host surface a handle is its NAME — a string
316
+ // literal of the roster's union ("Low" | "Normal" | "Urgent"); the engine's
317
+ // vocabulary stays relational (ids = declaration order) and the marshal
318
+ // owns the bijection. Dispatch is native `switch` narrowing (recipe 2).
311
319
  const Priority = closed("Priority", ["Low", "Normal", "Urgent"])
312
320
 
313
321
  const Ticket = relation("Ticket", { id: u64.fresh, priority: Priority.id, opened_at: i64 })
@@ -327,7 +335,16 @@ const Tickets = schema("Tickets", { Priority, Ticket }, [
327
335
  // never written, only declared.
328
336
  const urgent = query(Tickets).rule((r) => {
329
337
  const { t } = r.vars("t")
330
- return r.match(Ticket, { id: t, priority: Priority.Urgent }).select("t")
338
+ return r.match(Ticket, { id: t, priority: "Urgent" }).select("t")
339
+ })
340
+
341
+ // Set membership is a plain array — the drizzle law's spelling, closed-only
342
+ // in query match records (an ordinary u64/str field's membership is a bound
343
+ // ∈-set param, `r.inSet`); the array folds to the same wire set the param
344
+ // spelling crosses. In `.where()` selections arrays work at EVERY field kind.
345
+ const actionable = query(Tickets).rule((r) => {
346
+ const { t } = r.vars("t")
347
+ return r.match(Ticket, { id: t, priority: ["Normal", "Urgent"] }).select("t")
331
348
  })
332
349
  ```
333
350
 
@@ -378,13 +395,16 @@ const masteredAttempts = query(Review).rule((r) => {
378
395
  .select("a")
379
396
  })
380
397
 
381
- // Host dispatch on the payload tier hands each arm its sealed axiom row:
382
- const label = (k: bigint) =>
383
- Kind.match(k, {
384
- DirectPass: (row) => `mastered, rank ${row.rank}`,
385
- JudgedPass: (row) => `mastered, rank ${row.rank}`,
386
- Failed: () => "not mastered"
387
- })
398
+ // Host dispatch on the payload tier is the record-table idiom a `Record`
399
+ // over the handle union is total by type (a missing or extra entry is a
400
+ // compile error), and each entry reads its sealed axiom row off the typed
401
+ // `Kind.axioms` readback:
402
+ const labels: Record<Infer<typeof Kind.id>, string> = {
403
+ DirectPass: `mastered, rank ${Kind.axioms.DirectPass.rank}`,
404
+ JudgedPass: `mastered, rank ${Kind.axioms.JudgedPass.rank}`,
405
+ Failed: "not mastered"
406
+ }
407
+ const label = (k: Infer<typeof Kind.id>) => labels[k]
388
408
  ```
389
409
 
390
410
  Two honest boundaries. The fold has limits: payload escaping to the head and
@@ -425,7 +445,7 @@ const Oncall = schema("Oncall", { Severity, Incident, Escalation }, [
425
445
  // The sub-vocabulary: an escalation carries a PAGING severity, by
426
446
  // statement. ψ over the sealed extension compiles to the member set
427
447
  // {Critical, Fatal}; the judgment is one bit test per touched fact,
428
- // and an escalation at Severity.Info aborts the commit.
448
+ // and an escalation at "Info" aborts the commit.
429
449
  contained(on(Escalation, "severity"), on(Severity.where({ pages: true }), "id"))
430
450
  ])
431
451
 
@@ -512,8 +532,8 @@ const Ast = schema("Ast", { Kind, Node, Lit, Add, Parent }, [
512
532
  key(Lit, ["node"]),
513
533
  key(Add, ["node"]),
514
534
  // Every node's arm is total, valid, and exclusive (recipe 2's theorems):
515
- mirrors(on(Node.where({ kind: Kind.Lit }), "id"), on(Lit, "node")),
516
- mirrors(on(Node.where({ kind: Kind.Add }), "id"), on(Add, "node")),
535
+ mirrors(on(Node.where({ kind: "Lit" }), "id"), on(Lit, "node")),
536
+ mirrors(on(Node.where({ kind: "Add" }), "id"), on(Add, "node")),
517
537
  // Every child edge resolves — no dangling subtrees, judged at commit
518
538
  // (these containments also put lhs/rhs in the "Node.id" class, which is
519
539
  // exactly what lets the query below join lhs against Lit.node):
@@ -635,7 +655,7 @@ const Orders = schema("Orders", { State, Order, Placement, Shipment }, [
635
655
  // The conditional target, both ways: every Shipment references an order
636
656
  // THAT IS Shipped (validity), and every Shipped order has its Shipment
637
657
  // (totality) — the transition and its evidence commit together.
638
- mirrors(on(Shipment, "order"), on(Order.where({ state: State.Shipped }), "id"))
658
+ mirrors(on(Shipment, "order"), on(Order.where({ state: "Shipped" }), "id"))
639
659
  // Transition predicates ("only Placed may ship") are host code under the
640
660
  // generation witness — recipe 20; the schema pins the states, not the paths.
641
661
  ])
@@ -643,7 +663,7 @@ const Orders = schema("Orders", { State, Order, Placement, Shipment }, [
643
663
  const shipped = query(Orders).rule((r) => {
644
664
  const { id, carrier } = r.vars("id", "carrier")
645
665
  return r
646
- .match(Order, { id, state: State.Shipped })
666
+ .match(Order, { id, state: "Shipped" })
647
667
  .match(Shipment, { order: id, carrier })
648
668
  .select("id", "carrier")
649
669
  })
@@ -701,11 +721,11 @@ const Calendar = schema("Calendar", { Rsvp, Arm, Person, Room, Event, Attendance
701
721
  // not declared. Policy is the presence or absence of one statement.
702
722
  // Accepting an invitation IS claiming the time (totality + validity) —
703
723
  // and this is the statement that types Claim.source:
704
- mirrors(on(Attendance.where({ rsvp: Rsvp.Accepted }), "id"), on(Claim.where({ arm: Arm.Busy }), "source")),
724
+ mirrors(on(Attendance.where({ rsvp: "Accepted" }), "id"), on(Claim.where({ arm: "Busy" }), "source")),
705
725
  // Busy time lies inside working hours, pointwise — coverage rides the
706
726
  // target's own key (disjoint + ordered is a theorem, not a request):
707
727
  key(WorkHours, ["person", "hours"]),
708
- contained(on(Claim.where({ arm: Arm.Busy }), ["person", "span"]), on(WorkHours, ["person", "hours"])),
728
+ contained(on(Claim.where({ arm: "Busy" }), ["person", "span"]), on(WorkHours, ["person", "hours"])),
709
729
  contained(on(Booking, "room"), on(Room, "id")),
710
730
  contained(on(Booking, "event"), on(Event, "id"))
711
731
  ])
@@ -953,13 +973,13 @@ const Jobs = schema("Jobs", { State, Job, Lease }, [
953
973
  key(Lease, ["job"]),
954
974
  // A lease exists iff its job is Running (recipe 13's conditional target):
955
975
  // claiming a job and leasing it commit together or not at all.
956
- mirrors(on(Lease, "job"), on(Job.where({ state: State.Running }), "id"))
976
+ mirrors(on(Lease, "job"), on(Job.where({ state: "Running" }), "id"))
957
977
  ])
958
978
 
959
979
  // update-where's premise — "still Queued" is the witness:
960
980
  const stillQueued = query(Jobs).rule((r) => {
961
981
  const { id, payload } = r.vars("id", "payload")
962
- return r.match(Job, { id, state: State.Queued, payload }).select("id", "payload")
982
+ return r.match(Job, { id, state: "Queued", payload }).select("id", "payload")
963
983
  })
964
984
 
965
985
  const db = await Db.create("./jobs.db", Jobs)
@@ -976,8 +996,8 @@ const outcome = db.writeWitnessed(function updateWhere(snap, tx) {
976
996
  return abandon("nothing queued")
977
997
  }
978
998
  for (const row of queued) {
979
- tx.delete(Job, { id: row.id, state: State.Queued, payload: row.payload })
980
- tx.insert(Job, { id: row.id, state: State.Running, payload: row.payload })
999
+ tx.delete(Job, { id: row.id, state: "Queued", payload: row.payload })
1000
+ tx.insert(Job, { id: row.id, state: "Running", payload: row.payload })
981
1001
  tx.insert(Lease, { job: row.id, worker: 7n, until: 60n })
982
1002
  }
983
1003
  return undefined
@@ -1007,7 +1027,7 @@ const Rollup = schema("Rollup", { Arm, Claim, BusySpan }, [
1007
1027
  // Soundness, pointwise: every stored rollup point is covered by busy
1008
1028
  // claims — an UNSOUND rollup (claiming busy time that isn't, or surviving
1009
1029
  // its sources' deletion) cannot commit, judged on every touching commit.
1010
- contained(on(BusySpan, ["person", "span"]), on(Claim.where({ arm: Arm.Busy }), ["person", "span"]))
1030
+ contained(on(BusySpan, ["person", "span"]), on(Claim.where({ arm: "Busy" }), ["person", "span"]))
1011
1031
  ])
1012
1032
 
1013
1033
  // Maintenance is the third witness idiom (recipe 20): re-run the deriving
@@ -1016,7 +1036,7 @@ const Rollup = schema("Rollup", { Arm, Claim, BusySpan }, [
1016
1036
  // coalesce):
1017
1037
  const deriving = query(Rollup).rule((r) => {
1018
1038
  const { person, span } = r.vars("person", "span")
1019
- return r.match(Claim, { person, span, arm: Arm.Busy }).select("person", r.pack("span"))
1039
+ return r.match(Claim, { person, span, arm: "Busy" }).select("person", r.pack("span"))
1020
1040
  })
1021
1041
  ```
1022
1042
 
@@ -1040,8 +1060,8 @@ const Payments = schema("Payments", { Kind, Payment, Card, Ach }, [
1040
1060
  contained(on(Payment, "kind"), on(Kind, "id")),
1041
1061
  key(Card, ["payment"]),
1042
1062
  key(Ach, ["payment"]),
1043
- mirrors(on(Payment.where({ kind: Kind.Card }), "id"), on(Card, "payment")),
1044
- mirrors(on(Payment.where({ kind: Kind.Ach }), "id"), on(Ach, "payment"))
1063
+ mirrors(on(Payment.where({ kind: "Card" }), "id"), on(Card, "payment")),
1064
+ mirrors(on(Payment.where({ kind: "Ach" }), "id"), on(Ach, "payment"))
1045
1065
  ])
1046
1066
 
1047
1067
  // One query, two rules (set union). The exclusivity theorem (recipe 2) is
@@ -1051,14 +1071,14 @@ const wholeDu = query(Payments)
1051
1071
  .rule((r) => {
1052
1072
  const { id, n } = r.vars("id", "n")
1053
1073
  return r
1054
- .match(Payment, { id, kind: Kind.Card })
1074
+ .match(Payment, { id, kind: "Card" })
1055
1075
  .match(Card, { payment: id, last4: n })
1056
1076
  .select("id", "n")
1057
1077
  })
1058
1078
  .rule((r) => {
1059
1079
  const { id, n } = r.vars("id", "n")
1060
1080
  return r
1061
- .match(Payment, { id, kind: Kind.Ach })
1081
+ .match(Payment, { id, kind: "Ach" })
1062
1082
  .match(Ach, { payment: id, routing: n })
1063
1083
  .select("id", "n")
1064
1084
  })
@@ -1323,13 +1343,13 @@ const MaintainedRollup = schema("MaintainedRollup", { Arm, Claim, BusySpan }, [
1323
1343
  key(Claim, ["source"]),
1324
1344
  key(Claim, ["person", "span"]),
1325
1345
  key(BusySpan, ["person", "span"]),
1326
- contained(on(BusySpan, ["person", "span"]), on(Claim.where({ arm: Arm.Busy }), ["person", "span"]))
1346
+ contained(on(BusySpan, ["person", "span"]), on(Claim.where({ arm: "Busy" }), ["person", "span"]))
1327
1347
  ])
1328
1348
 
1329
1349
  // Derive the desired rollup on the maintenance snapshot:
1330
1350
  const deriving = query(MaintainedRollup).rule((r) => {
1331
1351
  const { source, person, span } = r.vars("source", "person", "span")
1332
- return r.match(Claim, { source, person, arm: Arm.Busy, span }).select("person", r.pack("span"))
1352
+ return r.match(Claim, { source, person, arm: "Busy", span }).select("person", r.pack("span"))
1333
1353
  })
1334
1354
  ```
1335
1355
 
@@ -1437,8 +1457,8 @@ const ZoneLedger = schema("ZoneLedger", { Kind, Ledger, Zone, UnitSlot, PairSlot
1437
1457
  key(PairSlot, ["ledger", "at"]),
1438
1458
  // Each kind's zones carry exactly its sidecar's points — mixed widths,
1439
1459
  // one element domain:
1440
- mirrors(on(Zone.where({ kind: Kind.Unit }), ["ledger", "at"]), on(UnitSlot, ["ledger", "at"])),
1441
- mirrors(on(Zone.where({ kind: Kind.Pair }), ["ledger", "at"]), on(PairSlot, ["ledger", "at"]))
1460
+ mirrors(on(Zone.where({ kind: "Unit" }), ["ledger", "at"]), on(UnitSlot, ["ledger", "at"])),
1461
+ mirrors(on(Zone.where({ kind: "Pair" }), ["ledger", "at"]), on(PairSlot, ["ledger", "at"]))
1442
1462
  ])
1443
1463
  ```
1444
1464
 
package/README.md CHANGED
@@ -27,9 +27,11 @@ classes, inferred query rows, and rejections that arrive as data rather than
27
27
  exceptions.
28
28
 
29
29
  ```ts
30
- import { bool, closed, contained, Db, gt, key, on, query, relation, schema, u64 } from "@bjornpagen/bumbledb"
30
+ import { bool, closed, contained, Db, gt, type Infer, key, on, query, relation, schema, u64 } from "@bjornpagen/bumbledb"
31
31
 
32
32
  // A closed relation: a sealed roster of axioms with typed payload columns.
33
+ // At the host surface a handle is its NAME — the string literal "DirectPass"
34
+ // is the one spelling, and closed columns type as the handle union.
33
35
  const Kind = closed(
34
36
  "Kind",
35
37
  { mastered: bool, rank: u64 },
@@ -57,10 +59,12 @@ const Review = schema("Review", { Kind, Attempt, Certificate }, [
57
59
 
58
60
  const db = await Db.create("./review.db", Review)
59
61
 
60
- // Write. The delta is judged against every statement at commit.
62
+ // Write. The delta is judged against every statement at commit. A closed
63
+ // column takes the handle name — a wrong string is a compile error AND a
64
+ // marshal refusal.
61
65
  const result = db.write((tx) => {
62
- const attempt = tx.insert(Attempt, { kind: Kind.DirectPass }) // attempt.id minted, a bare bigint
63
- tx.insert(Certificate, { attempt: attempt.id, kind: Kind.DirectPass })
66
+ const attempt = tx.insert(Attempt, { kind: "DirectPass" }) // attempt.id minted, a bare bigint
67
+ tx.insert(Certificate, { attempt: attempt.id, kind: "DirectPass" })
64
68
  })
65
69
 
66
70
  // Rejection-as-data: no throw — a rejected commit is a typed value carrying
@@ -87,14 +91,21 @@ const prepared = db.prepare(certifiedAbove)
87
91
  const rows = db.execute(prepared, { floor: 15n }) // rows: { a: bigint; rank: bigint }[]
88
92
  console.log(rows)
89
93
 
90
- // Host dispatch over the sealed roster exhaustive by construction; each
91
- // arm receives its axiom row.
92
- const label = Kind.match(Kind.JudgedPass, {
93
- DirectPass: (row) => `mastered, rank ${row.rank}`,
94
- JudgedPass: (row) => `mastered, rank ${row.rank}`,
95
- Failed: () => "not mastered"
96
- })
97
- console.log(label) // "mastered, rank 20"
94
+ // Host dispatch over the sealed roster is native `switch` narrowing over
95
+ // the handle union ("DirectPass" | "JudgedPass" | "Failed") — exhaustive
96
+ // via `satisfies never`; the sealed axioms read back typed.
97
+ function describe(kind: Infer<typeof Kind.id>): string {
98
+ switch (kind) {
99
+ case "DirectPass":
100
+ case "JudgedPass":
101
+ return `mastered, rank ${Kind.axioms[kind].rank}`
102
+ case "Failed":
103
+ return "not mastered"
104
+ default:
105
+ return kind satisfies never
106
+ }
107
+ }
108
+ console.log(describe("JudgedPass")) // "mastered, rank 20"
98
109
  ```
99
110
 
100
111
  Every `ts` fence in this README is extracted and type-checked against the
@@ -102,10 +113,12 @@ real surface by `test/readme.test.ts` — the examples cannot drift.
102
113
 
103
114
  ## Surface
104
115
 
105
- - The structural type kernel fields as pure structure (`bool`, `bytes`, `i64`, `u64`, `str`, `interval`, `span`), `relation()`, and `closed()` sealed rosters with typed axiom payloads and exhaustive host dispatch via `.match`. Domains are never declared: `schema()` computes every field's class from the statement list.
106
- - The statement algebra — `schema()`, `key`, `contained`, `mirrors`, `window`; faces via `on`/`oneOf`; counts via `exactly`, `atLeast`, `atMost`, `between`, `none`; ψ-selection via `.where` on relations and closed rosters.
116
+ The drizzle law governs this surface: the SDK's job at the host boundary is translation, not abstraction every database idiom arrives as the modern TypeScript idiom for that concept, and the SDK never invents an operator where the language already has one.
117
+
118
+ - The structural type kernel — fields as pure structure (`bool`, `bytes`, `i64`, `u64`, `str`, `interval`, `span`), `relation()`, and `closed()` sealed rosters with typed axiom payloads. A closed reference's value type IS the handle union (`Infer` speaks it); dispatch is native `switch` narrowing with `satisfies never` exhaustiveness. Domains are never declared: `schema()` computes every field's class from the statement list.
119
+ - The statement algebra — `schema()`, `key`, `contained`, `mirrors`, `window`; faces via `on` (set membership is a plain array in `.where`); counts via `exactly`, `atLeast`, `atMost`, `between`, `none`; ψ-selection via `.where` on relations and closed rosters.
107
120
  - The `Db` runtime — `Db.create`/`Db.open`, path-cached stores, transactions, typed violations, scoped snapshot reads, the witnessed write loop with `abandon`.
108
- - The query surface — Datalog as values, `query(S).rule(r => ...)`: named vars, params typed by use, negation, aggregates, and the free comparison/connective exports (`eq`, `ne`, `lt`, `le`, `gt`, `ge`, `and`, `or`, `not`, `allen`/`ALLEN`, `pointIn`, `covers`); stratified recursion via `program()`; `db.prepare` as a plain value.
121
+ - The query surface — Datalog as values, `query(S).rule(r => ...)`: named vars, params typed by use, negation, aggregates, and the free comparison/connective exports (`eq`, `ne`, `lt`, `le`, `gt`, `ge`, `and`, `or`, `not`, `allen`/`ALLEN`, `pointIn`, `covers`); set membership at a closed field is a plain array in the match record (`r.match(Ticket, { priority: ["Normal", "Urgent"] })` — closed-only there: an ordinary field's membership is a bound `r.inSet` param); stratified recursion via `program()`; `db.prepare` as a plain value.
109
122
  - The exhume surface — `Db.exhume`, the schema-independent read path: a store's self-described shapes and raw facts by name, with typed refusals (`ErrExhumeNoDescriptor`, `ErrExhumeFormatMismatch`, `ErrExhumeCorruption`).
110
123
 
111
124
  ## Cookbook
package/dist/closed.d.ts CHANGED
@@ -1,34 +1,36 @@
1
1
  /**
2
2
  * Closed relations (`docs/architecture/10-data-model.md` § closed
3
3
  * relations): a vocabulary whose extension is declared in the schema — two
4
- * tiers, one function. The emission per closed relation mirrors the
5
- * macro's (host-enum analog): handle CONSTANTS on the value
6
- * (`Kind.Checking`, ids = declaration order, each a BARE `bigint` — no
7
- * brand), the `fromId` weld, an `id` field descriptor carrying the CLOSED
8
- * LINKAGE (the roster — pure structure, no declared domain: the laws type
9
- * the columns, and `schema()` names the id's generator class `"Kind.id"`)
10
- * for other relations' field blocks (`kind: Kind.id`), payload readback
11
- * (`Kind.axioms`), and the declared payload column descriptors
12
- * (`Kind.columns` — the runtime twin of the `Cols` type parameter, which
13
- * the face layer's structural wall reads). Bare tier: `closed("Kind", ["Checking",
4
+ * tiers, one function. Bare tier: `closed("Kind", ["Checking",
14
5
  * "Savings"])`. Payload tier: `closed("Sev", { pages: bool }, { Critical:
15
6
  * { pages: true }, ... })` — one call, three arguments (the curried tier-2
16
7
  * spelling is DELETED — canonical utterance): the axioms record IS the
17
8
  * handle declaration, every handle carrying every column exactly once
18
- * (type-enforced). No fact type and no insert surface existclosed
19
- * relations are unwritable by construction: the value simply lacks the
20
- * writable relation shape. Both tiers mint `match()` exhaustive dispatch
21
- * over the handle union (arms typed by the mapped type, so a missing or
22
- * extra arm is a compile error; the payload tier's arm receives the typed
23
- * axiom row). The payload tier additionally mints `where()` the
24
- * ψ-selection surface (`Kind.where({ mastered: true })` as a face source),
25
- * resolved through the ONE selection machine
26
- * (`relation.ts::resolveSelection`); the bare tier has no payload columns to
27
- * select on, so `.where` is absent there, at the type AND on the value.
9
+ * (type-enforced). At the host surface a handle is its NAME a string
10
+ * literal of the roster's union (the drizzle law: translation, not
11
+ * abstraction; dispatch over a vocabulary is native `switch` narrowing, so
12
+ * no match operator is minted and no handle constants exist the literal
13
+ * `"Checking"` is the ONE spelling). Handles are pure DATA, not properties
14
+ * of the value, so NO handle name is reserved: a vocabulary may legally
15
+ * contain handles named `match`, `where`, or `id` the axioms record and
16
+ * the roster are their own namespaces. The value's whole surface: `name`;
17
+ * `id` the field descriptor carrying the CLOSED LINKAGE (the roster —
18
+ * pure structure, no declared domain: the laws type the columns, and
19
+ * `schema()` names the id's generator class `"Kind.id"`) for other
20
+ * relations' field blocks (`kind: Kind.id`); `data` (the lowering
21
+ * carrier); `axioms` (payload readback, `Kind.axioms`); `columns` (the
22
+ * runtime twin of the `Cols` type parameter, which the face layer's
23
+ * structural wall reads); and — exactly when payload columns exist —
24
+ * `where()`, the ψ-selection surface (`Kind.where({ mastered: true })` as a
25
+ * face source), resolved through the ONE selection machine
26
+ * (`relation.ts::resolveSelection`); the bare tier has no payload columns
27
+ * to select on, so `.where` is absent there, at the type AND on the value.
28
+ * No fact type and no insert surface exist — closed relations are
29
+ * unwritable by construction: the value simply lacks the writable relation
30
+ * shape.
28
31
  */
29
- import type { OneOf } from "#face.ts";
30
32
  import { type AnyField, type ClosedIdField, type Infer } from "#fields.ts";
31
- import { type SelectionBinding } from "#relation.ts";
33
+ import { type SelectionBinding, type SelectionInput } from "#relation.ts";
32
34
  import type { LiteralSpec } from "#spec.ts";
33
35
  /**
34
36
  * A payload column of a closed relation: any field descriptor except a
@@ -93,12 +95,14 @@ interface ClosedCore<Name extends string, Handles extends string, Cols extends R
93
95
  readonly name: Name;
94
96
  /**
95
97
  * The closed reference descriptor: `kind: Kind.id` in another relation's
96
- * field block is the reference through which bare handle ids become
97
- * legal in that relation's selections. Pure structure plus the roster —
98
- * the referencing field's domain is law-born: `schema()` computes it
99
- * from the declared containment (`"Kind.id"`, the generator class).
98
+ * field block is the reference through which handle literals become
99
+ * legal in that relation's selections. Pure structure plus the PRECISE
100
+ * roster (`ClosedIdField<Handles>` the handle union is the field's
101
+ * value type under `Infer`); the referencing field's domain is law-born:
102
+ * `schema()` computes it from the declared containment (`"Kind.id"`, the
103
+ * generator class).
100
104
  */
101
- readonly id: ClosedIdField;
105
+ readonly id: ClosedIdField<Handles>;
102
106
  readonly data: ClosedData;
103
107
  /** Payload readback: handle to its declared column values, bare and structural. */
104
108
  readonly axioms: Axioms<Handles, Cols>;
@@ -111,19 +115,17 @@ interface ClosedCore<Name extends string, Handles extends string, Cols extends R
111
115
  * descriptors in declaration order for the lowering).
112
116
  */
113
117
  readonly columns: Cols;
114
- /** The weld: declaration-order id back to its handle, or undefined beyond the roster. */
115
- fromId(id: bigint): Handles | undefined;
116
118
  }
117
119
  /**
118
- * The `where()` argument of a closed relation: per PAYLOAD column, a bare
119
- * structural literal of that column's value type or an `oneOf(a, b, ...)`
120
- * literal set the ordinary `where()`'s vocabulary exactly. The synthetic
121
- * `id` is deliberately absent: an id selection is spelled only as handle
122
- * literals on the REFERENCING side (the canonical-utterance law).
120
+ * The `where()` argument of a closed relation: EXACTLY the relation
121
+ * surface's {@link SelectionInput}, over the declared payload columns the
122
+ * ONE selection vocabulary, so a spelling change there (H3's membership
123
+ * arrays) flows through with no local change here. The synthetic `id` is
124
+ * deliberately unspellable ({@link PayloadColumns} refuses an `id` column):
125
+ * an id selection is spelled only as handle literals on the REFERENCING
126
+ * side (the canonical-utterance law).
123
127
  */
124
- type ClosedSelectionInput<Cols extends Record<string, PayloadField>> = {
125
- readonly [C in keyof Cols]?: Infer<Cols[C]> | OneOf<Infer<Cols[C]>>;
126
- };
128
+ type ClosedSelectionInput<Cols extends Record<string, PayloadField>> = SelectionInput<Cols>;
127
129
  /**
128
130
  * A closed relation with a ψ selection applied — what `on()` consumes as a
129
131
  * σ-carrying closed source (`on(Kind.where({ mastered: true }), "id")`).
@@ -152,42 +154,17 @@ interface ClosedSelectable<Name extends string, Handles extends string, Cols ext
152
154
  where(selection: ClosedSelectionInput<Cols>): SelectedClosed<Name, Handles, Cols>;
153
155
  }
154
156
  /**
155
- * Exhaustive dispatch over a BARE closed vocabulary: one arm per handle,
156
- * no literal types and no brands the handle-name union on the value's
157
- * type IS the exhaustiveness proof (a missing arm is a missing-property
158
- * compile error; an extra arm an excess-property compile error). The bare
159
- * tier declares no payload, so an arm takes nothing. The arms record types
160
- * any `bigint` inthe runtime roster refuses an out-of-vocabulary id
161
- * with a throw, never a misdispatch.
162
- */
163
- interface ClosedMatchBare<Handles extends string> {
164
- match<T>(id: bigint, arms: {
165
- readonly [H in Handles]: () => T;
166
- }): T;
167
- }
168
- /**
169
- * Exhaustive dispatch over a PAYLOAD-tier closed vocabulary: the same
170
- * mapped-type exhaustiveness as the bare tier, and each arm receives its
171
- * handle's typed axiom row (the declared columns, bare and structural —
172
- * the frozen readback row from `axioms`).
173
- */
174
- interface ClosedMatchPayload<Handles extends string, Cols extends Record<string, PayloadField>> {
175
- match<T>(id: bigint, arms: {
176
- readonly [H in Handles]: (row: AxiomRow<Cols>) => T;
177
- }): T;
178
- }
179
- /**
180
- * A closed relation value: the core surface plus one BARE constant per
181
- * handle (`Kind.Checking: bigint`, ids = declaration order — the value is
182
- * structural; the roster judges out-of-vocabulary ids at construction and
183
- * the engine at commit), plus `match()` on BOTH tiers (bare arms take
184
- * nothing; payload arms receive the typed axiom row), plus — exactly when
185
- * payload columns exist — `where()` (the bare tier has nothing to select
186
- * on, so the method is ABSENT there, not merely uncallable).
157
+ * A closed relation value: the core surface plus exactly when payload
158
+ * columns exist `where()` (the bare tier has nothing to select on, so
159
+ * the method is ABSENT there, not merely uncallable). NOTHING else:
160
+ * handles are data on the roster, never properties of the value (the
161
+ * handle constants, the match operator, and the id-to-handle weld died
162
+ * with the bigint eradispatch is native `switch` narrowing over the
163
+ * handle union).
187
164
  */
188
- type Closed<Name extends string, Handles extends string, Cols extends Record<string, PayloadField>> = ClosedCore<Name, Handles, Cols> & {
189
- readonly [H in Handles]: bigint;
190
- } & ([keyof Cols] extends [never] ? ClosedMatchBare<Handles> : ClosedSelectable<Name, Handles, Cols> & ClosedMatchPayload<Handles, Cols>);
165
+ type Closed<Name extends string, Handles extends string, Cols extends Record<string, PayloadField>> = [
166
+ keyof Cols
167
+ ] extends [never] ? ClosedCore<Name, Handles, Cols> : ClosedCore<Name, Handles, Cols> & ClosedSelectable<Name, Handles, Cols>;
191
168
  /** Any closed relation value, whatever its roster and columns. */
192
169
  interface AnyClosed {
193
170
  readonly name: string;
@@ -211,6 +188,6 @@ declare function closed<const Name extends string, const Handles extends readonl
211
188
  * {@link Axioms}).
212
189
  */
213
190
  declare function closed<const Name extends string, const Cols extends PayloadColumns, Handles extends string>(name: Name, columns: Cols, axioms: Axioms<Handles, Cols>): Closed<Name, Handles, Cols>;
214
- export type { AnyClosed, AnySelectedClosed, AxiomRow, Axioms, Closed, ClosedColumn, ClosedCore, ClosedData, ClosedRow, ClosedSelectionInput, PayloadField, SelectedClosed };
191
+ export type { AnyClosed, AnySelectedClosed, AxiomRow, Axioms, Closed, ClosedColumn, ClosedCore, ClosedData, ClosedRow, ClosedSelectable, ClosedSelectionInput, PayloadField, SelectedClosed };
215
192
  export { closed };
216
193
  //# sourceMappingURL=closed.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"closed.d.ts","sourceRoot":"","sources":["../src/closed.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"closed.d.ts","sourceRoot":"","sources":["../src/closed.ts"],"names":[],"mappings":"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"}