@bjornpagen/bumbledb 0.5.0 → 0.7.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 (100) hide show
  1. package/COOKBOOK.md +140 -136
  2. package/README.md +24 -11
  3. package/dist/closed.d.ts +7 -5
  4. package/dist/closed.d.ts.map +1 -1
  5. package/dist/closed.js +4 -1
  6. package/dist/closed.js.map +1 -1
  7. package/dist/count.js +1 -1
  8. package/dist/count.js.map +1 -1
  9. package/dist/db.d.ts +110 -73
  10. package/dist/db.d.ts.map +1 -1
  11. package/dist/db.js +172 -116
  12. package/dist/db.js.map +1 -1
  13. package/dist/exhume.d.ts +22 -10
  14. package/dist/exhume.d.ts.map +1 -1
  15. package/dist/exhume.js +42 -9
  16. package/dist/exhume.js.map +1 -1
  17. package/dist/face.d.ts +10 -6
  18. package/dist/face.d.ts.map +1 -1
  19. package/dist/face.js.map +1 -1
  20. package/dist/fields.d.ts +38 -16
  21. package/dist/fields.d.ts.map +1 -1
  22. package/dist/fields.js +33 -8
  23. package/dist/fields.js.map +1 -1
  24. package/dist/index.d.ts +9 -6
  25. package/dist/index.d.ts.map +1 -1
  26. package/dist/index.js +5 -2
  27. package/dist/index.js.map +1 -1
  28. package/dist/lower.d.ts +9 -9
  29. package/dist/lower.d.ts.map +1 -1
  30. package/dist/lower.js +17 -12
  31. package/dist/lower.js.map +1 -1
  32. package/dist/marshal.d.ts +17 -7
  33. package/dist/marshal.d.ts.map +1 -1
  34. package/dist/marshal.js +32 -10
  35. package/dist/marshal.js.map +1 -1
  36. package/dist/native.d.ts +60 -9
  37. package/dist/native.d.ts.map +1 -1
  38. package/dist/native.js.map +1 -1
  39. package/dist/query/atom.d.ts +199 -203
  40. package/dist/query/atom.d.ts.map +1 -1
  41. package/dist/query/atom.js +39 -48
  42. package/dist/query/atom.js.map +1 -1
  43. package/dist/query/find.d.ts +116 -0
  44. package/dist/query/find.d.ts.map +1 -0
  45. package/dist/query/{select.js → find.js} +22 -22
  46. package/dist/query/find.js.map +1 -0
  47. package/dist/query/lower.d.ts +131 -158
  48. package/dist/query/lower.d.ts.map +1 -1
  49. package/dist/query/lower.js +505 -494
  50. package/dist/query/lower.js.map +1 -1
  51. package/dist/query/predicate.d.ts +22 -14
  52. package/dist/query/predicate.d.ts.map +1 -1
  53. package/dist/query/predicate.js +35 -42
  54. package/dist/query/predicate.js.map +1 -1
  55. package/dist/query/run.d.ts +8 -8
  56. package/dist/query/run.d.ts.map +1 -1
  57. package/dist/query/run.js +16 -21
  58. package/dist/query/run.js.map +1 -1
  59. package/dist/query/scope.d.ts +139 -74
  60. package/dist/query/scope.d.ts.map +1 -1
  61. package/dist/query/scope.js +80 -33
  62. package/dist/query/scope.js.map +1 -1
  63. package/dist/relation.d.ts.map +1 -1
  64. package/dist/relation.js +3 -1
  65. package/dist/relation.js.map +1 -1
  66. package/dist/schema.d.ts.map +1 -1
  67. package/dist/schema.js +12 -2
  68. package/dist/schema.js.map +1 -1
  69. package/dist/spec.d.ts +20 -10
  70. package/dist/spec.d.ts.map +1 -1
  71. package/dist/spec.js.map +1 -1
  72. package/dist/statements.d.ts +22 -2
  73. package/dist/statements.d.ts.map +1 -1
  74. package/dist/statements.js +26 -5
  75. package/dist/statements.js.map +1 -1
  76. package/package.json +3 -3
  77. package/src/closed.ts +13 -7
  78. package/src/count.ts +1 -1
  79. package/src/db.ts +293 -177
  80. package/src/exhume.ts +48 -11
  81. package/src/face.ts +13 -6
  82. package/src/fields.ts +51 -15
  83. package/src/index.ts +12 -8
  84. package/src/lower.ts +17 -12
  85. package/src/marshal.ts +38 -13
  86. package/src/native.ts +59 -8
  87. package/src/query/atom.ts +297 -275
  88. package/src/query/find.ts +212 -0
  89. package/src/query/lower.ts +692 -724
  90. package/src/query/predicate.ts +37 -45
  91. package/src/query/run.ts +17 -22
  92. package/src/query/scope.ts +184 -90
  93. package/src/relation.ts +3 -1
  94. package/src/schema.ts +14 -2
  95. package/src/spec.ts +21 -9
  96. package/src/statements.ts +30 -6
  97. package/dist/query/select.d.ts +0 -128
  98. package/dist/query/select.d.ts.map +0 -1
  99. package/dist/query/select.js.map +0 -1
  100. package/src/query/select.ts +0 -215
@@ -0,0 +1,212 @@
1
+ /**
2
+ * Find entries and aggregates, REFERENCE-IDENTITY edition — the head
3
+ * vocabulary, mirroring the IR's aggregate roster exactly
4
+ * (`bumbledb/crates/bumbledb/src/ir.rs` `AggOp`/`FindTerm`;
5
+ * `docs/architecture/20-query-ir.md` § aggregation): `count` (nullary),
6
+ * `countDistinct`, `sum`/`min`/`max` (over an orderable variable or the
7
+ * measure), `argMax`/`argMin` (arg-restriction: carried value + orderable
8
+ * key), and `pack` (the coalescing fold — RELATION-SHAPED, the result
9
+ * position interval-typed). Aggregates fold VARIABLES by reference —
10
+ * `r.sum(w)` — and are typed by the variable's own descriptor.
11
+ *
12
+ * `select(strings)` is DEAD: the head is a `find` RECORD, whose KEYS name
13
+ * the answer columns (`find({ total: r.count(), owner: h })`). The keys are
14
+ * unique object keys, so a duplicate answer column is unrepresentable and a
15
+ * rename is a real typed key. Grouping is implicit: the non-aggregate
16
+ * entries are the group key; over empty input an all-aggregate find yields
17
+ * the EMPTY SET, never a zero row. The creation quarantine is
18
+ * representational: a head position is a variable, the measure, or an
19
+ * aggregate — no minting or arithmetic term exists to spell (permanent law).
20
+ */
21
+
22
+ import type { Infer } from "#fields.ts"
23
+ import type { SchemaClasses } from "#law.ts"
24
+ import type { IntervalVarOk, OrderVarOk } from "#query/atom.ts"
25
+ import type { AnyVar, Duration, MintSlotOf } from "#query/scope.ts"
26
+
27
+ /** One aggregate operator name of the find vocabulary. */
28
+ type AggOpName = "count" | "countDistinct" | "sum" | "min" | "max" | "argMax" | "argMin" | "pack"
29
+
30
+ /**
31
+ * One aggregate find VALUE: the op, the variable (or measure) it folds BY
32
+ * REFERENCE, and — for the Arg forms — the orderable key variable. The
33
+ * variable's own descriptor types the result.
34
+ */
35
+ interface Agg<
36
+ Op extends AggOpName,
37
+ Over extends AnyVar | Duration | undefined,
38
+ Key extends AnyVar | undefined = undefined
39
+ > {
40
+ readonly agg: Op
41
+ readonly over: Over
42
+ readonly key: Key
43
+ }
44
+
45
+ /** Any aggregate find value. */
46
+ type AnyAgg = Agg<AggOpName, AnyVar | Duration | undefined, AnyVar | undefined>
47
+
48
+ /** One find entry: a projected variable, the measure, or an aggregate. */
49
+ type FindEntry = AnyVar | Duration | AnyAgg
50
+
51
+ /** The `find` record: column name → find entry. Keys ARE the answer columns. */
52
+ type FindShape = Readonly<Record<string, FindEntry>>
53
+
54
+ /** Builds one aggregate value. */
55
+ function aggregate<Op extends AggOpName, Over extends AnyVar | Duration | undefined, Key extends AnyVar | undefined>(
56
+ op: Op,
57
+ over: Over,
58
+ key: Key
59
+ ): Agg<Op, Over, Key> {
60
+ return Object.freeze({ agg: op, over, key })
61
+ }
62
+
63
+ /** Nullary count: |the group's set of distinct full bindings|, `bigint`. */
64
+ function count(): Agg<"count", undefined> {
65
+ return aggregate("count", undefined, undefined)
66
+ }
67
+
68
+ /** |the distinct values of the variable across the group|, `bigint`; legal over every type. */
69
+ function countDistinct<const V extends AnyVar>(over: V): Agg<"countDistinct", V> {
70
+ return aggregate("countDistinct", over, undefined)
71
+ }
72
+
73
+ /**
74
+ * Exact checked sum over an orderable (u64/i64) variable — wide
75
+ * accumulator, one finalize range check; overflow is the engine's typed
76
+ * runtime error — or over the measure (`r.sum(r.duration(w))`).
77
+ */
78
+ function sum<const O extends AnyVar | Duration>(over: O): Agg<"sum", O> {
79
+ return aggregate("sum", over, undefined)
80
+ }
81
+
82
+ /** Minimum over an orderable variable or the measure (orderable types only). */
83
+ function min<const O extends AnyVar | Duration>(over: O): Agg<"min", O> {
84
+ return aggregate("min", over, undefined)
85
+ }
86
+
87
+ /** Maximum over an orderable variable or the measure (orderable types only). */
88
+ function max<const O extends AnyVar | Duration>(over: O): Agg<"max", O> {
89
+ return aggregate("max", over, undefined)
90
+ }
91
+
92
+ /**
93
+ * Arg-restriction toward the maximum of `key` (`ir::AggOp::ArgMax`): the
94
+ * group's binding set is restricted to the bindings attaining the extreme
95
+ * of the orderable key, and `value` is the carried payload — a tie yields
96
+ * every attaining row. All Arg entries of one query share one key and one
97
+ * direction; Arg and fold aggregates never mix (both the engine's rules).
98
+ */
99
+ function argMax<const V extends AnyVar, const K extends AnyVar>(value: V, key: K): Agg<"argMax", V, K> {
100
+ return aggregate("argMax", value, key)
101
+ }
102
+
103
+ /** Arg-restriction toward the minimum of `key`; rules as {@link argMax}. */
104
+ function argMin<const V extends AnyVar, const K extends AnyVar>(value: V, key: K): Agg<"argMin", V, K> {
105
+ return aggregate("argMin", value, key)
106
+ }
107
+
108
+ /**
109
+ * The coalescing fold (Snodgrass coalesce, `ir::AggOp::Pack`): per group,
110
+ * the maximal disjoint half-open segments of the union of the group's
111
+ * interval point sets — RELATION-SHAPED, one answer row per (group, maximal
112
+ * segment), the result position carrying one interval of the input's element
113
+ * type. At most one `pack` per find, never beside a fold or an Arg entry.
114
+ */
115
+ function pack<const V extends AnyVar>(over: V): Agg<"pack", V> {
116
+ return aggregate("pack", over, undefined)
117
+ }
118
+
119
+ /** A fold input's judgment: an orderable variable, or the measure of an interval variable. */
120
+ type FoldOverOk<O> = O extends AnyVar
121
+ ? OrderVarOk<O>
122
+ : O extends Duration<infer V extends AnyVar>
123
+ ? IntervalVarOk<V>
124
+ : false
125
+
126
+ /**
127
+ * One find entry's judgment (off the entry's own descriptor — no env, no
128
+ * class map needed): a projected variable is ok, the measure and `pack`
129
+ * demand interval-typed variables, folds and Arg keys demand orderable ones.
130
+ */
131
+ type FindEntryOk<E> = E extends AnyVar
132
+ ? true
133
+ : E extends Duration<infer V extends AnyVar>
134
+ ? IntervalVarOk<V>
135
+ : E extends Agg<"count", undefined>
136
+ ? true
137
+ : E extends Agg<"countDistinct", AnyVar>
138
+ ? true
139
+ : E extends Agg<"sum" | "min" | "max", infer O>
140
+ ? FoldOverOk<O>
141
+ : E extends Agg<"argMax" | "argMin", AnyVar, infer K extends AnyVar>
142
+ ? OrderVarOk<K> extends true
143
+ ? true
144
+ : false
145
+ : E extends Agg<"pack", infer V extends AnyVar>
146
+ ? IntervalVarOk<V>
147
+ : false
148
+
149
+ /** The validated find record (intersect with the inferred entries — errors land on the offending key). */
150
+ type CheckFind<F extends FindShape> = {
151
+ readonly [K in keyof F]: FindEntryOk<F[K]> extends true ? F[K] : never
152
+ }
153
+
154
+ /**
155
+ * The validated find record of a RECURSIVE rule: every entry must be a plain
156
+ * variable (aggregates and the measure are unwritable in a recursive head —
157
+ * the strata quarantine).
158
+ */
159
+ type CheckRecFind<F extends FindShape> = {
160
+ readonly [K in keyof F]: F[K] extends AnyVar ? F[K] : never
161
+ }
162
+
163
+ /**
164
+ * One find entry's answer-column value type: a variable carries its field's
165
+ * type, the measure/count/countDistinct are `bigint`, folds carry their
166
+ * input's type (a measure fold is `bigint`), the Arg forms carry the
167
+ * payload's type, `pack` its interval type.
168
+ */
169
+ type FindValue<E> = E extends AnyVar
170
+ ? Infer<E["field"]>
171
+ : E extends Duration<AnyVar>
172
+ ? bigint
173
+ : E extends Agg<"count", undefined>
174
+ ? bigint
175
+ : E extends Agg<"countDistinct", AnyVar>
176
+ ? bigint
177
+ : E extends Agg<"sum" | "min" | "max", infer O>
178
+ ? O extends AnyVar
179
+ ? Infer<O["field"]>
180
+ : bigint
181
+ : E extends Agg<"argMax" | "argMin", infer V extends AnyVar, AnyVar>
182
+ ? Infer<V["field"]>
183
+ : E extends Agg<"pack", infer V extends AnyVar>
184
+ ? Infer<V["field"]>
185
+ : never
186
+
187
+ /** The inferred answer-row object type of a find record — the keys ARE the columns. */
188
+ type RowOfFind<F extends FindShape> = { readonly [K in keyof F]: FindValue<F[K]> }
189
+
190
+ /**
191
+ * The head signature of a recursive rule's find record as classed mint
192
+ * slots (descriptor + law-computed class), keyed by column name — the
193
+ * signature an `idb` join pairs against (`F` is variable-only there).
194
+ */
195
+ type HeadRecordOf<Classes extends SchemaClasses, F extends FindShape> = {
196
+ readonly [K in keyof F]: F[K] extends AnyVar ? MintSlotOf<Classes, F[K]> : never
197
+ }
198
+
199
+ export type {
200
+ Agg,
201
+ AggOpName,
202
+ AnyAgg,
203
+ CheckFind,
204
+ CheckRecFind,
205
+ FindEntry,
206
+ FindEntryOk,
207
+ FindShape,
208
+ FindValue,
209
+ HeadRecordOf,
210
+ RowOfFind
211
+ }
212
+ export { argMax, argMin, count, countDistinct, max, min, pack, sum }