@enspirit/bmg-js 1.0.1 → 1.0.2

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 (158) hide show
  1. package/LICENSE.md +21 -0
  2. package/dist/{src/Relation → Relation}/Memory.d.ts +45 -46
  3. package/dist/{src/src/Relation → Relation}/index.d.ts +1 -1
  4. package/dist/bmg.cjs +1 -1
  5. package/dist/bmg.cjs.map +1 -1
  6. package/dist/bmg.modern.js +1 -1
  7. package/dist/bmg.modern.js.map +1 -1
  8. package/dist/bmg.module.js +1 -1
  9. package/dist/bmg.module.js.map +1 -1
  10. package/dist/bmg.umd.js +1 -1
  11. package/dist/bmg.umd.js.map +1 -1
  12. package/dist/index.d.ts +27 -1
  13. package/dist/lib-definitions.d.ts +1 -0
  14. package/dist/{src/operators → operators}/_helpers.d.ts +142 -142
  15. package/dist/{src/operators → operators}/allbut.d.ts +2 -2
  16. package/dist/{src/operators → operators}/autowrap.d.ts +2 -2
  17. package/dist/{src/operators → operators}/constants.d.ts +2 -2
  18. package/dist/{src/operators → operators}/cross_product.d.ts +3 -3
  19. package/dist/{src/operators → operators}/exclude.d.ts +2 -2
  20. package/dist/{src/operators → operators}/extend.d.ts +2 -2
  21. package/dist/{src/src/operators → operators}/group.d.ts +2 -2
  22. package/dist/{src/operators → operators}/image.d.ts +2 -2
  23. package/dist/{src/operators → operators}/index.d.ts +30 -30
  24. package/dist/{src/src/operators → operators}/intersect.d.ts +2 -2
  25. package/dist/{src/src/operators → operators}/isEqual.d.ts +2 -2
  26. package/dist/{src/operators → operators}/isRelation.d.ts +1 -1
  27. package/dist/{src/operators → operators}/join.d.ts +2 -2
  28. package/dist/{src/operators → operators}/left_join.d.ts +2 -2
  29. package/dist/{src/src/operators → operators}/matching.d.ts +2 -2
  30. package/dist/{src/src/operators → operators}/minus.d.ts +2 -2
  31. package/dist/{src/src/operators → operators}/not_matching.d.ts +2 -2
  32. package/dist/{src/operators → operators}/one.d.ts +2 -2
  33. package/dist/{src/operators → operators}/prefix.d.ts +2 -2
  34. package/dist/{src/src/operators → operators}/project.d.ts +2 -2
  35. package/dist/{src/operators → operators}/rename.d.ts +2 -2
  36. package/dist/{src/operators → operators}/restrict.d.ts +2 -2
  37. package/dist/{src/operators → operators}/suffix.d.ts +2 -2
  38. package/dist/{src/operators → operators}/summarize.d.ts +2 -2
  39. package/dist/{src/operators → operators}/transform.d.ts +2 -2
  40. package/dist/{src/src/operators → operators}/ungroup.d.ts +2 -2
  41. package/dist/{src/operators → operators}/union.d.ts +2 -2
  42. package/dist/{src/operators → operators}/unwrap.d.ts +2 -2
  43. package/dist/{src/operators → operators}/where.d.ts +1 -1
  44. package/dist/{src/operators → operators}/wrap.d.ts +2 -2
  45. package/dist/{src/operators → operators}/yByX.d.ts +2 -2
  46. package/dist/{src/src/support → support}/toPredicateFunc.d.ts +2 -2
  47. package/dist/{src/src/types.d.ts → types.d.ts} +162 -101
  48. package/package.json +6 -4
  49. package/src/Relation/Memory.ts +13 -12
  50. package/src/index.ts +1 -1
  51. package/src/lib-definitions.ts +281 -0
  52. package/src/types.ts +142 -54
  53. package/dist/src/Relation/index.d.ts +0 -1
  54. package/dist/src/Relation.d.ts +0 -8
  55. package/dist/src/index.d.ts +0 -27
  56. package/dist/src/operators/group.d.ts +0 -2
  57. package/dist/src/operators/intersect.d.ts +0 -2
  58. package/dist/src/operators/isEqual.d.ts +0 -2
  59. package/dist/src/operators/matching.d.ts +0 -2
  60. package/dist/src/operators/minus.d.ts +0 -2
  61. package/dist/src/operators/not_matching.d.ts +0 -2
  62. package/dist/src/operators/project.d.ts +0 -2
  63. package/dist/src/operators/ungroup.d.ts +0 -2
  64. package/dist/src/src/Relation/Memory.d.ts +0 -46
  65. package/dist/src/src/index.d.ts +0 -27
  66. package/dist/src/src/operators/_helpers.d.ts +0 -142
  67. package/dist/src/src/operators/allbut.d.ts +0 -2
  68. package/dist/src/src/operators/autowrap.d.ts +0 -2
  69. package/dist/src/src/operators/constants.d.ts +0 -2
  70. package/dist/src/src/operators/cross_product.d.ts +0 -3
  71. package/dist/src/src/operators/exclude.d.ts +0 -2
  72. package/dist/src/src/operators/extend.d.ts +0 -2
  73. package/dist/src/src/operators/image.d.ts +0 -2
  74. package/dist/src/src/operators/index.d.ts +0 -30
  75. package/dist/src/src/operators/isRelation.d.ts +0 -1
  76. package/dist/src/src/operators/join.d.ts +0 -2
  77. package/dist/src/src/operators/left_join.d.ts +0 -2
  78. package/dist/src/src/operators/one.d.ts +0 -2
  79. package/dist/src/src/operators/prefix.d.ts +0 -2
  80. package/dist/src/src/operators/rename.d.ts +0 -2
  81. package/dist/src/src/operators/restrict.d.ts +0 -2
  82. package/dist/src/src/operators/suffix.d.ts +0 -2
  83. package/dist/src/src/operators/summarize.d.ts +0 -2
  84. package/dist/src/src/operators/transform.d.ts +0 -2
  85. package/dist/src/src/operators/union.d.ts +0 -2
  86. package/dist/src/src/operators/unwrap.d.ts +0 -2
  87. package/dist/src/src/operators/where.d.ts +0 -1
  88. package/dist/src/src/operators/wrap.d.ts +0 -2
  89. package/dist/src/src/operators/yByX.d.ts +0 -2
  90. package/dist/src/src/utility-types.d.ts +0 -43
  91. package/dist/src/support/toPredicateFunc.d.ts +0 -2
  92. package/dist/src/tests/bmg.test.d.ts +0 -1
  93. package/dist/src/tests/fixtures.d.ts +0 -6
  94. package/dist/src/tests/operators/allbut.test.d.ts +0 -1
  95. package/dist/src/tests/operators/autowrap.test.d.ts +0 -1
  96. package/dist/src/tests/operators/constants.test.d.ts +0 -1
  97. package/dist/src/tests/operators/cross_product.test.d.ts +0 -1
  98. package/dist/src/tests/operators/exclude.test.d.ts +0 -1
  99. package/dist/src/tests/operators/extend.test.d.ts +0 -1
  100. package/dist/src/tests/operators/group.test.d.ts +0 -1
  101. package/dist/src/tests/operators/image.test.d.ts +0 -1
  102. package/dist/src/tests/operators/intersect.test.d.ts +0 -1
  103. package/dist/src/tests/operators/isEqual.test.d.ts +0 -1
  104. package/dist/src/tests/operators/join.test.d.ts +0 -1
  105. package/dist/src/tests/operators/left_join.test.d.ts +0 -1
  106. package/dist/src/tests/operators/matching.test.d.ts +0 -1
  107. package/dist/src/tests/operators/minus.test.d.ts +0 -1
  108. package/dist/src/tests/operators/not_matching.test.d.ts +0 -1
  109. package/dist/src/tests/operators/one.test.d.ts +0 -1
  110. package/dist/src/tests/operators/prefix.test.d.ts +0 -1
  111. package/dist/src/tests/operators/project.test.d.ts +0 -1
  112. package/dist/src/tests/operators/rename.test.d.ts +0 -1
  113. package/dist/src/tests/operators/restrict.test.d.ts +0 -1
  114. package/dist/src/tests/operators/suffix.test.d.ts +0 -1
  115. package/dist/src/tests/operators/summarize.test.d.ts +0 -1
  116. package/dist/src/tests/operators/transform.test.d.ts +0 -1
  117. package/dist/src/tests/operators/ungroup.test.d.ts +0 -1
  118. package/dist/src/tests/operators/union.test.d.ts +0 -1
  119. package/dist/src/tests/operators/unwrap.test.d.ts +0 -1
  120. package/dist/src/tests/operators/where.test.d.ts +0 -1
  121. package/dist/src/tests/operators/wrap.test.d.ts +0 -1
  122. package/dist/src/tests/operators/yByX.test.d.ts +0 -1
  123. package/dist/src/tests/types/relation.test.d.ts +0 -1
  124. package/dist/src/types.d.ts +0 -101
  125. package/dist/src/utility-types.d.ts +0 -43
  126. package/dist/tests/bmg.test.d.ts +0 -1
  127. package/dist/tests/fixtures.d.ts +0 -6
  128. package/dist/tests/operators/allbut.test.d.ts +0 -1
  129. package/dist/tests/operators/autowrap.test.d.ts +0 -1
  130. package/dist/tests/operators/constants.test.d.ts +0 -1
  131. package/dist/tests/operators/cross_product.test.d.ts +0 -1
  132. package/dist/tests/operators/exclude.test.d.ts +0 -1
  133. package/dist/tests/operators/extend.test.d.ts +0 -1
  134. package/dist/tests/operators/group.test.d.ts +0 -1
  135. package/dist/tests/operators/image.test.d.ts +0 -1
  136. package/dist/tests/operators/intersect.test.d.ts +0 -1
  137. package/dist/tests/operators/isEqual.test.d.ts +0 -1
  138. package/dist/tests/operators/join.test.d.ts +0 -1
  139. package/dist/tests/operators/left_join.test.d.ts +0 -1
  140. package/dist/tests/operators/matching.test.d.ts +0 -1
  141. package/dist/tests/operators/minus.test.d.ts +0 -1
  142. package/dist/tests/operators/not_matching.test.d.ts +0 -1
  143. package/dist/tests/operators/one.test.d.ts +0 -1
  144. package/dist/tests/operators/prefix.test.d.ts +0 -1
  145. package/dist/tests/operators/project.test.d.ts +0 -1
  146. package/dist/tests/operators/rename.test.d.ts +0 -1
  147. package/dist/tests/operators/restrict.test.d.ts +0 -1
  148. package/dist/tests/operators/suffix.test.d.ts +0 -1
  149. package/dist/tests/operators/summarize.test.d.ts +0 -1
  150. package/dist/tests/operators/transform.test.d.ts +0 -1
  151. package/dist/tests/operators/ungroup.test.d.ts +0 -1
  152. package/dist/tests/operators/union.test.d.ts +0 -1
  153. package/dist/tests/operators/unwrap.test.d.ts +0 -1
  154. package/dist/tests/operators/where.test.d.ts +0 -1
  155. package/dist/tests/operators/wrap.test.d.ts +0 -1
  156. package/dist/tests/operators/yByX.test.d.ts +0 -1
  157. package/dist/tests/types/relation.test.d.ts +0 -1
  158. package/src/utility-types.ts +0 -77
@@ -0,0 +1,281 @@
1
+ // Auto-generated from types.ts
2
+ // Run 'npm run generate:lib-definitions' to regenerate
3
+
4
+ export const LIB_DEFINITIONS = `
5
+ /**
6
+ * Type definitions for Bmg.js relational algebra library.
7
+ *
8
+ * This file defines all types needed for type-safe relational operations:
9
+ * - Base types (AttrName, Tuple)
10
+ * - Utility types for transformations (Renamed, Prefixed, Joined, etc.)
11
+ * - The Relation interface with all operators
12
+ * - Helper types for predicates, extensions, aggregators, etc.
13
+ */
14
+
15
+ // ============================================================================
16
+ // Base Types
17
+ // ============================================================================
18
+
19
+ /** Attribute name in a tuple */
20
+ type AttrName = string
21
+
22
+ /** A tuple is a record mapping attribute names to values */
23
+ type Tuple = Record<AttrName, unknown>
24
+
25
+ // ============================================================================
26
+ // Rename Types
27
+ // ============================================================================
28
+
29
+ /** Map from old attribute names to new attribute names */
30
+ type RenameMap<T> = { [K in keyof T]?: string };
31
+
32
+ /** Transform tuple type by renaming keys according to RenameMap */
33
+ type Renamed<T, R extends RenameMap<T>> = {
34
+ [K in keyof T as K extends keyof R ? (R[K] extends string ? R[K] : K) : K]: T[K];
35
+ };
36
+
37
+ // ============================================================================
38
+ // Prefix/Suffix Types
39
+ // ============================================================================
40
+
41
+ /** Prefix all keys except those in Except */
42
+ type Prefixed<T, P extends string, Except extends keyof T = never> = {
43
+ [K in keyof T as K extends Except ? K : \`\${P}\${K & string}\`]: T[K];
44
+ };
45
+
46
+ /** Suffix all keys except those in Except */
47
+ type Suffixed<T, S extends string, Except extends keyof T = never> = {
48
+ [K in keyof T as K extends Except ? K : \`\${K & string}\${S}\`]: T[K];
49
+ };
50
+
51
+ // ============================================================================
52
+ // Join Types
53
+ // ============================================================================
54
+
55
+ /** Extract common keys between two tuple types */
56
+ type CommonKeys<L, R> = Extract<keyof L, keyof R>;
57
+
58
+ /** Result of inner join: L & R with R's common keys removed */
59
+ type Joined<L, R> = L & Omit<R, CommonKeys<L, R>>;
60
+
61
+ /** Result of left join: L & optional R attributes (common keys removed) */
62
+ type LeftJoined<L, R> = L & Partial<Omit<R, CommonKeys<L, R>>>;
63
+
64
+ /**
65
+ * Typed join keys for array form: keys must exist on BOTH operands.
66
+ * Example: suppliers.join(parts, ['city']) - 'city' must be a key of both.
67
+ */
68
+ type TypedJoinKeysArray<L, R> = (keyof L & keyof R & string)[];
69
+
70
+ /**
71
+ * Typed join keys for object form: maps left keys to right keys.
72
+ * Example: suppliers.join(parts, { sid: 'supplier_id' })
73
+ * - Left key (sid) must exist on L
74
+ * - Right key (supplier_id) must exist on R
75
+ */
76
+ type TypedJoinKeysObject<L, R> = { [K in keyof L & string]?: keyof R & string };
77
+
78
+ // ============================================================================
79
+ // Wrap/Unwrap Types
80
+ // ============================================================================
81
+
82
+ /** Result of wrap: remove wrapped attrs, add nested object */
83
+ type Wrapped<T, K extends keyof T, As extends string> =
84
+ Omit<T, K> & Record<As, Pick<T, K>>;
85
+
86
+ /** Result of unwrap: remove object attr, spread its properties */
87
+ type Unwrapped<T, K extends keyof T> =
88
+ T[K] extends Record<string, unknown> ? Omit<T, K> & T[K] : Omit<T, K>;
89
+
90
+ /** Result of ungroup: remove relation attr, flatten its tuple type */
91
+ type Ungrouped<T, K extends keyof T> =
92
+ T[K] extends Relation<infer N> ? Omit<T, K> & N : Omit<T, K>;
93
+
94
+ // ============================================================================
95
+ // Aggregator Types
96
+ // ============================================================================
97
+
98
+ type AggregatorName = 'count' | 'sum' | 'min' | 'max' | 'avg' | 'collect'
99
+ type AggregatorSpec = { op: AggregatorName, attr: AttrName }
100
+ type AggregatorFunc = (tuples: Tuple[]) => unknown
101
+ type Aggregator = AggregatorName | AggregatorSpec | AggregatorFunc
102
+ type Aggregators = Record<AttrName, Aggregator>
103
+
104
+ /** Infer result type from aggregator specification */
105
+ type AggregatorResult<A> =
106
+ A extends 'count' ? number :
107
+ A extends { op: 'count' } ? number :
108
+ A extends { op: 'sum' | 'avg' | 'min' | 'max' } ? number | null :
109
+ A extends { op: 'collect' } ? unknown[] :
110
+ A extends (tuples: Tuple[]) => infer R ? R :
111
+ unknown;
112
+
113
+ /** Map aggregator definitions to their result types */
114
+ type AggregatorResults<Aggs extends Record<string, unknown>> = {
115
+ [K in keyof Aggs]: AggregatorResult<Aggs[K]>;
116
+ };
117
+
118
+ // ============================================================================
119
+ // Predicate Types
120
+ // ============================================================================
121
+
122
+ /** Predicate function that receives a typed tuple */
123
+ type TypedPredicateFunc<T> = (t: T) => boolean
124
+
125
+ /** Predicate: either a partial tuple for equality matching, or a function */
126
+ type TypedPredicate<T> = Partial<T> | TypedPredicateFunc<T>
127
+
128
+ // Legacy predicate types (for backwards compatibility with standalone operators)
129
+ type PredicateFunc = ((t: Tuple) => any)
130
+ type Predicate = Tuple | PredicateFunc
131
+
132
+ // ============================================================================
133
+ // Extension Types
134
+ // ============================================================================
135
+
136
+ /** Extension function that receives a typed tuple */
137
+ type TypedExtensionFunc<T, R> = (tuple: T) => R
138
+
139
+ /** Extension definition: function returning value, or attribute name to copy */
140
+ type TypedExtension<T, E extends Record<string, unknown>> = {
141
+ [K in keyof E]: TypedExtensionFunc<T, E[K]> | keyof T;
142
+ }
143
+
144
+ type ExtensionFunc = (tuple: Tuple) => unknown
145
+ type Extension = Record<AttrName, ExtensionFunc | AttrName>
146
+
147
+ // ============================================================================
148
+ // Other Helper Types
149
+ // ============================================================================
150
+
151
+ interface PrefixOptions {
152
+ except?: AttrName[]
153
+ }
154
+
155
+ interface SuffixOptions {
156
+ except?: AttrName[]
157
+ }
158
+
159
+ interface AutowrapOptions {
160
+ separator?: string
161
+ }
162
+
163
+ type Renaming = RenamingObj | RenamingFunc
164
+ type RenamingFunc = (attr: AttrName) => AttrName
165
+ type RenamingObj = Record<AttrName, AttrName>
166
+
167
+ type JoinKeys = AttrName[] | Record<AttrName, AttrName>
168
+
169
+ type TransformFunc = (value: unknown) => unknown
170
+ type Transformation = TransformFunc | TransformFunc[] | Record<AttrName, TransformFunc | TransformFunc[]>
171
+
172
+ // ============================================================================
173
+ // Relation Interface
174
+ // ============================================================================
175
+
176
+ /**
177
+ * Relation interface with generic type parameter for tuple type.
178
+ * Default parameter \`Tuple\` ensures backwards compatibility.
179
+ *
180
+ * @typeParam T - The tuple type for this relation. Defaults to \`Tuple\` (Record<string, unknown>).
181
+ *
182
+ * @example
183
+ * // Untyped usage (backwards compatible)
184
+ * const r = Bmg([{ id: 1 }]); // Relation<Tuple>
185
+ *
186
+ * @example
187
+ * // Typed usage with full type safety
188
+ * interface Person { id: number; name: string }
189
+ * const r = Bmg<Person>([{ id: 1, name: 'Alice' }]);
190
+ * r.project(['id']); // Relation<{ id: number }>
191
+ */
192
+ interface Relation<T = Tuple> {
193
+ // === Type-preserving operators ===
194
+
195
+ restrict(p: TypedPredicate<T>): Relation<T>
196
+ where(p: TypedPredicate<T>): Relation<T>
197
+ exclude(p: TypedPredicate<T>): Relation<T>
198
+
199
+ // === Projection operators ===
200
+
201
+ project<K extends keyof T>(attrs: K[]): Relation<Pick<T, K>>
202
+ allbut<K extends keyof T>(attrs: K[]): Relation<Omit<T, K>>
203
+
204
+ // === Extension operators ===
205
+
206
+ extend<E extends Record<string, unknown>>(e: TypedExtension<T, E>): Relation<T & E>
207
+ constants<C extends Tuple>(consts: C): Relation<T & C>
208
+
209
+ // === Rename operators ===
210
+
211
+ rename<R extends RenameMap<T>>(r: R): Relation<Renamed<T, R>>
212
+ prefix<P extends string, Ex extends keyof T = never>(pfx: P, options?: { except?: Ex[] }): Relation<Prefixed<T, P, Ex>>
213
+ suffix<S extends string, Ex extends keyof T = never>(sfx: S, options?: { except?: Ex[] }): Relation<Suffixed<T, S, Ex>>
214
+
215
+ // === Set operators (require same type) ===
216
+
217
+ union(right: RelationOperand<T>): Relation<T>
218
+ minus(right: RelationOperand<T>): Relation<T>
219
+ intersect(right: RelationOperand<T>): Relation<T>
220
+
221
+ // === Semi-join operators (preserve left type) ===
222
+
223
+ matching<R>(right: RelationOperand<R>, keys?: TypedJoinKeysArray<T, R> | TypedJoinKeysObject<T, R>): Relation<T>
224
+ not_matching<R>(right: RelationOperand<R>, keys?: TypedJoinKeysArray<T, R> | TypedJoinKeysObject<T, R>): Relation<T>
225
+
226
+ // === Join operators ===
227
+
228
+ join<R>(right: RelationOperand<R>, keys?: TypedJoinKeysArray<T, R> | TypedJoinKeysObject<T, R>): Relation<Joined<T, R>>
229
+ left_join<R>(right: RelationOperand<R>, keys?: TypedJoinKeysArray<T, R> | TypedJoinKeysObject<T, R>): Relation<LeftJoined<T, R>>
230
+ cross_product<R>(right: RelationOperand<R>): Relation<T & R>
231
+ cross_join<R>(right: RelationOperand<R>): Relation<T & R>
232
+
233
+ // === Nesting operators ===
234
+
235
+ image<R, As extends string>(right: RelationOperand<R>, as: As, keys?: TypedJoinKeysArray<T, R> | TypedJoinKeysObject<T, R>): Relation<T & Record<As, Relation<Omit<R, keyof T & keyof R>>>>
236
+ group<K extends keyof T, As extends string>(attrs: K[], as: As): Relation<Omit<T, K> & Record<As, Relation<Pick<T, K>>>>
237
+ ungroup<K extends keyof T>(attr: K): Relation<Ungrouped<T, K>>
238
+ wrap<K extends keyof T, As extends string>(attrs: K[], as: As): Relation<Wrapped<T, K, As>>
239
+ unwrap<K extends keyof T>(attr: K): Relation<Unwrapped<T, K>>
240
+
241
+ // === Aggregation ===
242
+
243
+ summarize<By extends keyof T, Aggs extends Aggregators>(by: By[], aggs: Aggs): Relation<Pick<T, By> & AggregatorResults<Aggs>>
244
+
245
+ // === Transform ===
246
+
247
+ transform(t: Transformation): Relation<T>
248
+
249
+ // === Dynamic (loses type precision) ===
250
+
251
+ autowrap(options?: AutowrapOptions): Relation<Tuple>
252
+
253
+ // === Non-relational ===
254
+
255
+ one(): T
256
+ yByX<Y extends keyof T, X extends keyof T>(y: Y, x: X): Record<T[X] & PropertyKey, T[Y]>
257
+ toArray(): T[]
258
+ isEqual(right: any): boolean
259
+ }
260
+
261
+ // ============================================================================
262
+ // Operands
263
+ // ============================================================================
264
+
265
+ type RelationOperand<T = Tuple> = Relation<T> | T[]
266
+
267
+ interface OperationalOperand<T = Tuple> {
268
+ tuples(): Iterable<T>
269
+ output(tuples: T[]): RelationOperand<T>
270
+ }
271
+
272
+ // ============================================================================
273
+ // Bmg Function Declaration
274
+ // ============================================================================
275
+
276
+ /** Create a relation from an array of tuples */
277
+ declare function Bmg<T>(tuples: T[]): Relation<T>
278
+ declare namespace Bmg {
279
+ function isRelation(op: unknown): boolean
280
+ }
281
+ `
package/src/types.ts CHANGED
@@ -1,36 +1,118 @@
1
- import type {
2
- RenameMap, Renamed,
3
- Prefixed, Suffixed,
4
- Joined, LeftJoined,
5
- Wrapped, Unwrapped,
6
- AggregatorResults
7
- } from './utility-types';
1
+ /**
2
+ * Type definitions for Bmg.js relational algebra library.
3
+ *
4
+ * This file defines all types needed for type-safe relational operations:
5
+ * - Base types (AttrName, Tuple)
6
+ * - Utility types for transformations (Renamed, Prefixed, Joined, etc.)
7
+ * - The Relation interface with all operators
8
+ * - Helper types for predicates, extensions, aggregators, etc.
9
+ */
10
+
11
+ // ============================================================================
12
+ // Base Types
13
+ // ============================================================================
14
+
15
+ /** Attribute name in a tuple */
16
+ export type AttrName = string
17
+
18
+ /** A tuple is a record mapping attribute names to values */
19
+ export type Tuple = Record<AttrName, unknown>
8
20
 
9
21
  // ============================================================================
10
- // Group/Ungroup Types (defined here due to Relation dependency)
22
+ // Rename Types
11
23
  // ============================================================================
12
24
 
25
+ /** Map from old attribute names to new attribute names */
26
+ export type RenameMap<T> = { [K in keyof T]?: string };
27
+
28
+ /** Transform tuple type by renaming keys according to RenameMap */
29
+ export type Renamed<T, R extends RenameMap<T>> = {
30
+ [K in keyof T as K extends keyof R ? (R[K] extends string ? R[K] : K) : K]: T[K];
31
+ };
32
+
33
+ // ============================================================================
34
+ // Prefix/Suffix Types
35
+ // ============================================================================
36
+
37
+ /** Prefix all keys except those in Except */
38
+ export type Prefixed<T, P extends string, Except extends keyof T = never> = {
39
+ [K in keyof T as K extends Except ? K : `${P}${K & string}`]: T[K];
40
+ };
41
+
42
+ /** Suffix all keys except those in Except */
43
+ export type Suffixed<T, S extends string, Except extends keyof T = never> = {
44
+ [K in keyof T as K extends Except ? K : `${K & string}${S}`]: T[K];
45
+ };
46
+
47
+ // ============================================================================
48
+ // Join Types
49
+ // ============================================================================
50
+
51
+ /** Extract common keys between two tuple types */
52
+ export type CommonKeys<L, R> = Extract<keyof L, keyof R>;
53
+
54
+ /** Result of inner join: L & R with R's common keys removed */
55
+ export type Joined<L, R> = L & Omit<R, CommonKeys<L, R>>;
56
+
57
+ /** Result of left join: L & optional R attributes (common keys removed) */
58
+ export type LeftJoined<L, R> = L & Partial<Omit<R, CommonKeys<L, R>>>;
59
+
60
+ /**
61
+ * Typed join keys for array form: keys must exist on BOTH operands.
62
+ * Example: suppliers.join(parts, ['city']) - 'city' must be a key of both.
63
+ */
64
+ export type TypedJoinKeysArray<L, R> = (keyof L & keyof R & string)[];
65
+
66
+ /**
67
+ * Typed join keys for object form: maps left keys to right keys.
68
+ * Example: suppliers.join(parts, { sid: 'supplier_id' })
69
+ * - Left key (sid) must exist on L
70
+ * - Right key (supplier_id) must exist on R
71
+ */
72
+ export type TypedJoinKeysObject<L, R> = { [K in keyof L & string]?: keyof R & string };
73
+
74
+ // ============================================================================
75
+ // Wrap/Unwrap Types
76
+ // ============================================================================
77
+
78
+ /** Result of wrap: remove wrapped attrs, add nested object */
79
+ export type Wrapped<T, K extends keyof T, As extends string> =
80
+ Omit<T, K> & Record<As, Pick<T, K>>;
81
+
82
+ /** Result of unwrap: remove object attr, spread its properties */
83
+ export type Unwrapped<T, K extends keyof T> =
84
+ T[K] extends Record<string, unknown> ? Omit<T, K> & T[K] : Omit<T, K>;
85
+
13
86
  /** Result of ungroup: remove relation attr, flatten its tuple type */
14
87
  export type Ungrouped<T, K extends keyof T> =
15
88
  T[K] extends Relation<infer N> ? Omit<T, K> & N : Omit<T, K>;
16
89
 
17
- export type AttrName = string
18
- export type Tuple = Record<AttrName, unknown>
90
+ // ============================================================================
91
+ // Aggregator Types
92
+ // ============================================================================
19
93
 
20
- export interface PrefixOptions {
21
- except?: AttrName[]
22
- }
94
+ export type AggregatorName = 'count' | 'sum' | 'min' | 'max' | 'avg' | 'collect'
95
+ export type AggregatorSpec = { op: AggregatorName, attr: AttrName }
96
+ export type AggregatorFunc = (tuples: Tuple[]) => unknown
97
+ export type Aggregator = AggregatorName | AggregatorSpec | AggregatorFunc
98
+ export type Aggregators = Record<AttrName, Aggregator>
23
99
 
24
- export interface SuffixOptions {
25
- except?: AttrName[]
26
- }
100
+ /** Infer result type from aggregator specification */
101
+ export type AggregatorResult<A> =
102
+ A extends 'count' ? number :
103
+ A extends { op: 'count' } ? number :
104
+ A extends { op: 'sum' | 'avg' | 'min' | 'max' } ? number | null :
105
+ A extends { op: 'collect' } ? unknown[] :
106
+ A extends (tuples: Tuple[]) => infer R ? R :
107
+ unknown;
27
108
 
28
- export interface AutowrapOptions {
29
- separator?: string
30
- }
109
+ /** Map aggregator definitions to their result types */
110
+ export type AggregatorResults<Aggs extends Record<string, unknown>> = {
111
+ [K in keyof Aggs]: AggregatorResult<Aggs[K]>;
112
+ };
31
113
 
32
114
  // ============================================================================
33
- // Typed Predicates
115
+ // Predicate Types
34
116
  // ============================================================================
35
117
 
36
118
  /** Predicate function that receives a typed tuple */
@@ -39,8 +121,12 @@ export type TypedPredicateFunc<T> = (t: T) => boolean
39
121
  /** Predicate: either a partial tuple for equality matching, or a function */
40
122
  export type TypedPredicate<T> = Partial<T> | TypedPredicateFunc<T>
41
123
 
124
+ // Legacy predicate types (for backwards compatibility with standalone operators)
125
+ export type PredicateFunc = ((t: Tuple) => any)
126
+ export type Predicate = Tuple | PredicateFunc
127
+
42
128
  // ============================================================================
43
- // Typed Extensions
129
+ // Extension Types
44
130
  // ============================================================================
45
131
 
46
132
  /** Extension function that receives a typed tuple */
@@ -51,8 +137,36 @@ export type TypedExtension<T, E extends Record<string, unknown>> = {
51
137
  [K in keyof E]: TypedExtensionFunc<T, E[K]> | keyof T;
52
138
  }
53
139
 
140
+ export type ExtensionFunc = (tuple: Tuple) => unknown
141
+ export type Extension = Record<AttrName, ExtensionFunc | AttrName>
142
+
54
143
  // ============================================================================
55
- // Generic Relation Interface
144
+ // Other Helper Types
145
+ // ============================================================================
146
+
147
+ export interface PrefixOptions {
148
+ except?: AttrName[]
149
+ }
150
+
151
+ export interface SuffixOptions {
152
+ except?: AttrName[]
153
+ }
154
+
155
+ export interface AutowrapOptions {
156
+ separator?: string
157
+ }
158
+
159
+ export type Renaming = RenamingObj | RenamingFunc
160
+ export type RenamingFunc = (attr: AttrName) => AttrName
161
+ export type RenamingObj = Record<AttrName, AttrName>
162
+
163
+ export type JoinKeys = AttrName[] | Record<AttrName, AttrName>
164
+
165
+ export type TransformFunc = (value: unknown) => unknown
166
+ export type Transformation = TransformFunc | TransformFunc[] | Record<AttrName, TransformFunc | TransformFunc[]>
167
+
168
+ // ============================================================================
169
+ // Relation Interface
56
170
  // ============================================================================
57
171
 
58
172
  /**
@@ -102,19 +216,19 @@ export interface Relation<T = Tuple> {
102
216
 
103
217
  // === Semi-join operators (preserve left type) ===
104
218
 
105
- matching<R>(right: RelationOperand<R>, keys?: JoinKeys): Relation<T>
106
- not_matching<R>(right: RelationOperand<R>, keys?: JoinKeys): Relation<T>
219
+ matching<R>(right: RelationOperand<R>, keys?: TypedJoinKeysArray<T, R> | TypedJoinKeysObject<T, R>): Relation<T>
220
+ not_matching<R>(right: RelationOperand<R>, keys?: TypedJoinKeysArray<T, R> | TypedJoinKeysObject<T, R>): Relation<T>
107
221
 
108
222
  // === Join operators ===
109
223
 
110
- join<R>(right: RelationOperand<R>, keys?: JoinKeys): Relation<Joined<T, R>>
111
- left_join<R>(right: RelationOperand<R>, keys?: JoinKeys): Relation<LeftJoined<T, R>>
224
+ join<R>(right: RelationOperand<R>, keys?: TypedJoinKeysArray<T, R> | TypedJoinKeysObject<T, R>): Relation<Joined<T, R>>
225
+ left_join<R>(right: RelationOperand<R>, keys?: TypedJoinKeysArray<T, R> | TypedJoinKeysObject<T, R>): Relation<LeftJoined<T, R>>
112
226
  cross_product<R>(right: RelationOperand<R>): Relation<T & R>
113
227
  cross_join<R>(right: RelationOperand<R>): Relation<T & R>
114
228
 
115
229
  // === Nesting operators ===
116
230
 
117
- image<R, As extends string>(right: RelationOperand<R>, as: As, keys?: JoinKeys): Relation<T & Record<As, Relation<Omit<R, keyof T & keyof R>>>>
231
+ image<R, As extends string>(right: RelationOperand<R>, as: As, keys?: TypedJoinKeysArray<T, R> | TypedJoinKeysObject<T, R>): Relation<T & Record<As, Relation<Omit<R, keyof T & keyof R>>>>
118
232
  group<K extends keyof T, As extends string>(attrs: K[], as: As): Relation<Omit<T, K> & Record<As, Relation<Pick<T, K>>>>
119
233
  ungroup<K extends keyof T>(attr: K): Relation<Ungrouped<T, K>>
120
234
  wrap<K extends keyof T, As extends string>(attrs: K[], as: As): Relation<Wrapped<T, K, As>>
@@ -141,7 +255,7 @@ export interface Relation<T = Tuple> {
141
255
  }
142
256
 
143
257
  // ============================================================================
144
- // Operands and Helpers
258
+ // Operands
145
259
  // ============================================================================
146
260
 
147
261
  export type RelationOperand<T = Tuple> = Relation<T> | T[]
@@ -150,29 +264,3 @@ export interface OperationalOperand<T = Tuple> {
150
264
  tuples(): Iterable<T>
151
265
  output(tuples: T[]): RelationOperand<T>
152
266
  }
153
-
154
- // Legacy predicate types (for backwards compatibility with standalone operators)
155
- export type PredicateFunc = ((t: Tuple) => any)
156
- export type Predicate = Tuple | PredicateFunc
157
-
158
- export type Renaming = RenamingObj | RenamingFunc
159
- export type RenamingFunc = (attr: AttrName) => AttrName
160
- export type RenamingObj = Record<AttrName, AttrName>
161
-
162
- export type ExtensionFunc = (tuple: Tuple) => unknown
163
- export type Extension = Record<AttrName, ExtensionFunc | AttrName>
164
-
165
- export type JoinKeys = AttrName[] | Record<AttrName, AttrName>
166
-
167
- export type AggregatorName = 'count' | 'sum' | 'min' | 'max' | 'avg' | 'collect'
168
- export type AggregatorSpec = { op: AggregatorName, attr: AttrName }
169
- export type AggregatorFunc = (tuples: Tuple[]) => unknown
170
- export type Aggregator = AggregatorName | AggregatorSpec | AggregatorFunc
171
- export type Aggregators = Record<AttrName, Aggregator>
172
-
173
- export type TransformFunc = (value: unknown) => unknown
174
- export type Transformation = TransformFunc | TransformFunc[] | Record<AttrName, TransformFunc | TransformFunc[]>
175
-
176
- // Re-export utility types for convenience
177
- export type { RenameMap, Renamed, Prefixed, Suffixed, Joined, LeftJoined, Wrapped, Unwrapped } from './utility-types';
178
- // Ungrouped is defined in this file (not utility-types) due to Relation dependency
@@ -1 +0,0 @@
1
- export * from './Memory';
@@ -1,8 +0,0 @@
1
- import { Predicate, Tuple } from "./types";
2
- export declare class Relation {
3
- private tuples;
4
- constructor(tuples: Tuple[]);
5
- restrict(p: Predicate): Relation;
6
- one(): Tuple;
7
- toArray(): Tuple[];
8
- }
@@ -1,27 +0,0 @@
1
- export * from './operators';
2
- export * from './types';
3
- export * from './utility-types';
4
- import { MemoryRelation } from './Relation';
5
- /**
6
- * Creates a new in-memory relation from an array of tuples.
7
- *
8
- * @typeParam T - The tuple type. Inferred from input or explicitly provided.
9
- *
10
- * @example
11
- * // Untyped usage (backwards compatible)
12
- * const r = Bmg([{ id: 1, name: 'Alice' }]);
13
- *
14
- * @example
15
- * // Typed usage with explicit type parameter
16
- * interface Person { id: number; name: string }
17
- * const r = Bmg<Person>([{ id: 1, name: 'Alice' }]);
18
- * r.project(['id']); // Autocomplete suggests 'id' | 'name'
19
- *
20
- * @example
21
- * // Type is inferred from input
22
- * const r = Bmg([{ id: 1, name: 'Alice' }] as const);
23
- */
24
- export declare function Bmg<T>(tuples: T[]): MemoryRelation<T>;
25
- export declare namespace Bmg {
26
- var isRelation: (op: any) => boolean;
27
- }
@@ -1,2 +0,0 @@
1
- import { RelationOperand, AttrName } from "../types";
2
- export declare const group: (operand: RelationOperand, attrs: AttrName[], as: AttrName) => RelationOperand;
@@ -1,2 +0,0 @@
1
- import { RelationOperand } from "../types";
2
- export declare const intersect: (left: RelationOperand, right: RelationOperand) => RelationOperand;
@@ -1,2 +0,0 @@
1
- import { RelationOperand } from "../types";
2
- export declare const isEqual: (left: RelationOperand, right: RelationOperand) => boolean;
@@ -1,2 +0,0 @@
1
- import { RelationOperand, JoinKeys } from "../types";
2
- export declare const matching: (left: RelationOperand, right: RelationOperand, keys?: JoinKeys) => RelationOperand;
@@ -1,2 +0,0 @@
1
- import { RelationOperand } from "../types";
2
- export declare const minus: (left: RelationOperand, right: RelationOperand) => RelationOperand;
@@ -1,2 +0,0 @@
1
- import { RelationOperand, JoinKeys } from "../types";
2
- export declare const not_matching: (left: RelationOperand, right: RelationOperand, keys?: JoinKeys) => RelationOperand;
@@ -1,2 +0,0 @@
1
- import { RelationOperand, AttrName } from "../types";
2
- export declare const project: (operand: RelationOperand, attrs: AttrName[]) => RelationOperand;
@@ -1,2 +0,0 @@
1
- import { RelationOperand, AttrName } from "../types";
2
- export declare const ungroup: (operand: RelationOperand, attr: AttrName) => RelationOperand;
@@ -1,46 +0,0 @@
1
- import type { AutowrapOptions, JoinKeys, Relation, RelationOperand, Transformation, Tuple, TypedPredicate, TypedExtension, RenameMap, Renamed, Prefixed, Suffixed, Joined, LeftJoined, Wrapped, Unwrapped, Ungrouped } from "../types";
2
- import type { AggregatorResults } from "../utility-types";
3
- /**
4
- * In-memory implementation of the Relation interface.
5
- *
6
- * @typeParam T - The tuple type for this relation. Defaults to `Tuple` (Record<string, unknown>).
7
- */
8
- export declare class MemoryRelation<T = Tuple> implements Relation<T> {
9
- private tuples;
10
- constructor(tuples: T[]);
11
- restrict(p: TypedPredicate<T>): Relation<T>;
12
- where(p: TypedPredicate<T>): Relation<T>;
13
- exclude(p: TypedPredicate<T>): Relation<T>;
14
- project<K extends keyof T>(attrs: K[]): Relation<Pick<T, K>>;
15
- allbut<K extends keyof T>(attrs: K[]): Relation<Omit<T, K>>;
16
- extend<E extends Record<string, unknown>>(e: TypedExtension<T, E>): Relation<T & E>;
17
- constants<C extends Tuple>(consts: C): Relation<T & C>;
18
- rename<R extends RenameMap<T>>(r: R): Relation<Renamed<T, R>>;
19
- prefix<P extends string, Ex extends keyof T = never>(pfx: P, options?: {
20
- except?: Ex[];
21
- }): Relation<Prefixed<T, P, Ex>>;
22
- suffix<S extends string, Ex extends keyof T = never>(sfx: S, options?: {
23
- except?: Ex[];
24
- }): Relation<Suffixed<T, S, Ex>>;
25
- union(right: RelationOperand<T>): Relation<T>;
26
- minus(right: RelationOperand<T>): Relation<T>;
27
- intersect(right: RelationOperand<T>): Relation<T>;
28
- matching<R>(right: RelationOperand<R>, keys?: JoinKeys): Relation<T>;
29
- not_matching<R>(right: RelationOperand<R>, keys?: JoinKeys): Relation<T>;
30
- join<R>(right: RelationOperand<R>, keys?: JoinKeys): Relation<Joined<T, R>>;
31
- left_join<R>(right: RelationOperand<R>, keys?: JoinKeys): Relation<LeftJoined<T, R>>;
32
- cross_product<R>(right: RelationOperand<R>): Relation<T & R>;
33
- cross_join<R>(right: RelationOperand<R>): Relation<T & R>;
34
- image<R, As extends string>(right: RelationOperand<R>, as: As, keys?: JoinKeys): Relation<T & Record<As, Relation<Omit<R, keyof T & keyof R>>>>;
35
- group<K extends keyof T, As extends string>(attrs: K[], as: As): Relation<Omit<T, K> & Record<As, Relation<Pick<T, K>>>>;
36
- ungroup<K extends keyof T>(attr: K): Relation<Ungrouped<T, K>>;
37
- wrap<K extends keyof T, As extends string>(attrs: K[], as: As): Relation<Wrapped<T, K, As>>;
38
- unwrap<K extends keyof T>(attr: K): Relation<Unwrapped<T, K>>;
39
- summarize<By extends keyof T, Aggs extends Record<string, unknown>>(by: By[], aggs: Aggs): Relation<Pick<T, By> & AggregatorResults<Aggs>>;
40
- transform(t: Transformation): Relation<T>;
41
- autowrap(options?: AutowrapOptions): Relation<Tuple>;
42
- one(): T;
43
- toArray(): T[];
44
- yByX<Y extends keyof T, X extends keyof T>(y: Y, x: X): Record<T[X] & PropertyKey, T[Y]>;
45
- isEqual(right: any): boolean;
46
- }