@tanstack/db-ivm 0.1.13 → 0.1.14
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.
- package/README.md +3 -3
- package/dist/cjs/d2.cjs.map +1 -1
- package/dist/cjs/graph.cjs.map +1 -1
- package/dist/cjs/hashing/hash.cjs.map +1 -1
- package/dist/cjs/index.cjs +2 -0
- package/dist/cjs/index.cjs.map +1 -1
- package/dist/cjs/index.d.cts +1 -0
- package/dist/cjs/indexes.cjs.map +1 -1
- package/dist/cjs/multiset.cjs.map +1 -1
- package/dist/cjs/operators/concat.cjs.map +1 -1
- package/dist/cjs/operators/consolidate.cjs.map +1 -1
- package/dist/cjs/operators/count.cjs.map +1 -1
- package/dist/cjs/operators/debug.cjs.map +1 -1
- package/dist/cjs/operators/distinct.cjs.map +1 -1
- package/dist/cjs/operators/filter.cjs.map +1 -1
- package/dist/cjs/operators/filterBy.cjs.map +1 -1
- package/dist/cjs/operators/groupBy.cjs.map +1 -1
- package/dist/cjs/operators/join.cjs.map +1 -1
- package/dist/cjs/operators/keying.cjs.map +1 -1
- package/dist/cjs/operators/map.cjs.map +1 -1
- package/dist/cjs/operators/negate.cjs.map +1 -1
- package/dist/cjs/operators/orderBy.cjs.map +1 -1
- package/dist/cjs/operators/output.cjs.map +1 -1
- package/dist/cjs/operators/pipe.cjs.map +1 -1
- package/dist/cjs/operators/reduce.cjs.map +1 -1
- package/dist/cjs/operators/tap.cjs.map +1 -1
- package/dist/cjs/operators/topK.cjs.map +1 -1
- package/dist/cjs/operators/topKWithFractionalIndex.cjs +20 -35
- package/dist/cjs/operators/topKWithFractionalIndex.cjs.map +1 -1
- package/dist/cjs/operators/topKWithFractionalIndex.d.cts +3 -11
- package/dist/cjs/operators/topKWithFractionalIndexBTree.d.cts +4 -4
- package/dist/cjs/utils.cjs +9 -0
- package/dist/cjs/utils.cjs.map +1 -1
- package/dist/cjs/utils.d.cts +5 -0
- package/dist/esm/d2.js.map +1 -1
- package/dist/esm/graph.js.map +1 -1
- package/dist/esm/hashing/hash.js.map +1 -1
- package/dist/esm/index.d.ts +1 -0
- package/dist/esm/index.js +2 -0
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/indexes.js.map +1 -1
- package/dist/esm/multiset.js.map +1 -1
- package/dist/esm/operators/concat.js.map +1 -1
- package/dist/esm/operators/consolidate.js.map +1 -1
- package/dist/esm/operators/count.js.map +1 -1
- package/dist/esm/operators/debug.js.map +1 -1
- package/dist/esm/operators/distinct.js.map +1 -1
- package/dist/esm/operators/filter.js.map +1 -1
- package/dist/esm/operators/filterBy.js.map +1 -1
- package/dist/esm/operators/groupBy.js.map +1 -1
- package/dist/esm/operators/join.js.map +1 -1
- package/dist/esm/operators/keying.js.map +1 -1
- package/dist/esm/operators/map.js.map +1 -1
- package/dist/esm/operators/negate.js.map +1 -1
- package/dist/esm/operators/orderBy.js.map +1 -1
- package/dist/esm/operators/output.js.map +1 -1
- package/dist/esm/operators/pipe.js.map +1 -1
- package/dist/esm/operators/reduce.js.map +1 -1
- package/dist/esm/operators/tap.js.map +1 -1
- package/dist/esm/operators/topK.js.map +1 -1
- package/dist/esm/operators/topKWithFractionalIndex.d.ts +3 -11
- package/dist/esm/operators/topKWithFractionalIndex.js +21 -36
- package/dist/esm/operators/topKWithFractionalIndex.js.map +1 -1
- package/dist/esm/operators/topKWithFractionalIndexBTree.d.ts +4 -4
- package/dist/esm/utils.d.ts +5 -0
- package/dist/esm/utils.js +9 -0
- package/dist/esm/utils.js.map +1 -1
- package/package.json +29 -29
- package/src/d2.ts +4 -4
- package/src/graph.ts +6 -6
- package/src/hashing/hash.ts +3 -3
- package/src/hashing/index.ts +2 -2
- package/src/index.ts +5 -4
- package/src/indexes.ts +8 -8
- package/src/multiset.ts +5 -5
- package/src/operators/concat.ts +6 -6
- package/src/operators/consolidate.ts +6 -6
- package/src/operators/count.ts +9 -9
- package/src/operators/debug.ts +8 -8
- package/src/operators/distinct.ts +11 -11
- package/src/operators/filter.ts +8 -8
- package/src/operators/filterBy.ts +7 -7
- package/src/operators/groupBy.ts +22 -22
- package/src/operators/index.ts +19 -19
- package/src/operators/join.ts +23 -23
- package/src/operators/keying.ts +4 -4
- package/src/operators/map.ts +8 -8
- package/src/operators/negate.ts +6 -6
- package/src/operators/orderBy.ts +26 -26
- package/src/operators/orderByBTree.ts +7 -7
- package/src/operators/output.ts +9 -9
- package/src/operators/pipe.ts +1 -1
- package/src/operators/reduce.ts +9 -9
- package/src/operators/tap.ts +8 -8
- package/src/operators/topK.ts +8 -8
- package/src/operators/topKWithFractionalIndex.ts +62 -83
- package/src/operators/topKWithFractionalIndexBTree.ts +19 -20
- package/src/types.ts +22 -22
- package/src/utils.ts +19 -4
package/src/operators/groupBy.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { map } from
|
|
2
|
-
import { reduce } from
|
|
3
|
-
import type { IStreamBuilder, KeyValue } from
|
|
1
|
+
import { map } from './map.js'
|
|
2
|
+
import { reduce } from './reduce.js'
|
|
3
|
+
import type { IStreamBuilder, KeyValue } from '../types.js'
|
|
4
4
|
|
|
5
5
|
type GroupKey = Record<string, unknown>
|
|
6
6
|
|
|
@@ -26,7 +26,7 @@ type AggregatesReturnType<T, A> = {
|
|
|
26
26
|
}
|
|
27
27
|
|
|
28
28
|
function isPipedAggregateFunction<T, R>(
|
|
29
|
-
aggregate: AggregateFunction<T, R
|
|
29
|
+
aggregate: AggregateFunction<T, R>,
|
|
30
30
|
): aggregate is PipedAggregateFunction<T, R> {
|
|
31
31
|
return `pipe` in aggregate
|
|
32
32
|
}
|
|
@@ -45,20 +45,20 @@ export function groupBy<
|
|
|
45
45
|
|
|
46
46
|
const basicAggregates = Object.fromEntries(
|
|
47
47
|
Object.entries(aggregates).filter(
|
|
48
|
-
([_, aggregate]) => !isPipedAggregateFunction(aggregate)
|
|
49
|
-
)
|
|
48
|
+
([_, aggregate]) => !isPipedAggregateFunction(aggregate),
|
|
49
|
+
),
|
|
50
50
|
) as Record<string, BasicAggregateFunction<T, any, any>>
|
|
51
51
|
|
|
52
52
|
// @ts-expect-error - TODO: we don't use this yet, but we will
|
|
53
53
|
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
54
54
|
const pipedAggregates = Object.fromEntries(
|
|
55
55
|
Object.entries(aggregates).filter(([_, aggregate]) =>
|
|
56
|
-
isPipedAggregateFunction(aggregate)
|
|
57
|
-
)
|
|
56
|
+
isPipedAggregateFunction(aggregate),
|
|
57
|
+
),
|
|
58
58
|
) as Record<string, PipedAggregateFunction<T, any>>
|
|
59
59
|
|
|
60
60
|
return (
|
|
61
|
-
stream: IStreamBuilder<T
|
|
61
|
+
stream: IStreamBuilder<T>,
|
|
62
62
|
): IStreamBuilder<KeyValue<string, ResultType>> => {
|
|
63
63
|
// Special key to store the original key object
|
|
64
64
|
const KEY_SENTINEL = `__original_key__`
|
|
@@ -81,7 +81,7 @@ export function groupBy<
|
|
|
81
81
|
}
|
|
82
82
|
|
|
83
83
|
return [keyString, values] as KeyValue<string, Record<string, unknown>>
|
|
84
|
-
})
|
|
84
|
+
}),
|
|
85
85
|
)
|
|
86
86
|
|
|
87
87
|
// Then reduce to compute aggregates
|
|
@@ -107,13 +107,13 @@ export function groupBy<
|
|
|
107
107
|
// Apply each aggregate function
|
|
108
108
|
for (const [name, aggregate] of Object.entries(basicAggregates)) {
|
|
109
109
|
const preValues = values.map(
|
|
110
|
-
([v, m]) => [v[name], m] as [any, number]
|
|
110
|
+
([v, m]) => [v[name], m] as [any, number],
|
|
111
111
|
)
|
|
112
112
|
result[name] = aggregate.reduce(preValues)
|
|
113
113
|
}
|
|
114
114
|
|
|
115
115
|
return [[result, 1]]
|
|
116
|
-
})
|
|
116
|
+
}),
|
|
117
117
|
)
|
|
118
118
|
|
|
119
119
|
// Finally map to extract the key and include all values
|
|
@@ -139,7 +139,7 @@ export function groupBy<
|
|
|
139
139
|
|
|
140
140
|
// Return with the string key instead of the object
|
|
141
141
|
return [keyString, result] as KeyValue<string, ResultType>
|
|
142
|
-
})
|
|
142
|
+
}),
|
|
143
143
|
)
|
|
144
144
|
}
|
|
145
145
|
}
|
|
@@ -148,7 +148,7 @@ export function groupBy<
|
|
|
148
148
|
* Creates a sum aggregate function
|
|
149
149
|
*/
|
|
150
150
|
export function sum<T>(
|
|
151
|
-
valueExtractor: (value: T) => number = (v) => v as unknown as number
|
|
151
|
+
valueExtractor: (value: T) => number = (v) => v as unknown as number,
|
|
152
152
|
): AggregateFunction<T, number, number> {
|
|
153
153
|
return {
|
|
154
154
|
preMap: (data: T) => valueExtractor(data),
|
|
@@ -166,7 +166,7 @@ export function sum<T>(
|
|
|
166
166
|
* Creates a count aggregate function
|
|
167
167
|
*/
|
|
168
168
|
export function count<T>(
|
|
169
|
-
valueExtractor: (value: T) => any = (v) => v
|
|
169
|
+
valueExtractor: (value: T) => any = (v) => v,
|
|
170
170
|
): AggregateFunction<T, number, number> {
|
|
171
171
|
return {
|
|
172
172
|
// Count only not-null values (the `== null` comparison gives true for both null and undefined)
|
|
@@ -185,7 +185,7 @@ export function count<T>(
|
|
|
185
185
|
* Creates an average aggregate function
|
|
186
186
|
*/
|
|
187
187
|
export function avg<T>(
|
|
188
|
-
valueExtractor: (value: T) => number = (v) => v as unknown as number
|
|
188
|
+
valueExtractor: (value: T) => number = (v) => v as unknown as number,
|
|
189
189
|
): AggregateFunction<T, number, { sum: number; count: number }> {
|
|
190
190
|
return {
|
|
191
191
|
preMap: (data: T) => ({
|
|
@@ -222,10 +222,10 @@ export function min<T extends CanMinMax>(): AggregateFunction<
|
|
|
222
222
|
T | undefined
|
|
223
223
|
>
|
|
224
224
|
export function min<T, V extends CanMinMax>(
|
|
225
|
-
valueExtractor: (value: T) => V
|
|
225
|
+
valueExtractor: (value: T) => V,
|
|
226
226
|
): AggregateFunction<T, V | undefined, V | undefined>
|
|
227
227
|
export function min<T, V extends CanMinMax>(
|
|
228
|
-
valueExtractor?: (value: T) => V
|
|
228
|
+
valueExtractor?: (value: T) => V,
|
|
229
229
|
): AggregateFunction<T, V | undefined, V | undefined> {
|
|
230
230
|
const extractor = valueExtractor ?? ((v: T) => v as unknown as V)
|
|
231
231
|
return {
|
|
@@ -252,10 +252,10 @@ export function max<T extends CanMinMax>(): AggregateFunction<
|
|
|
252
252
|
T | undefined
|
|
253
253
|
>
|
|
254
254
|
export function max<T, V extends CanMinMax>(
|
|
255
|
-
valueExtractor: (value: T) => V
|
|
255
|
+
valueExtractor: (value: T) => V,
|
|
256
256
|
): AggregateFunction<T, V | undefined, V | undefined>
|
|
257
257
|
export function max<T, V extends CanMinMax>(
|
|
258
|
-
valueExtractor?: (value: T) => V
|
|
258
|
+
valueExtractor?: (value: T) => V,
|
|
259
259
|
): AggregateFunction<T, V | undefined, V | undefined> {
|
|
260
260
|
const extractor = valueExtractor ?? ((v: T) => v as unknown as V)
|
|
261
261
|
return {
|
|
@@ -278,7 +278,7 @@ export function max<T, V extends CanMinMax>(
|
|
|
278
278
|
* @param valueExtractor Function to extract a numeric value from each data entry
|
|
279
279
|
*/
|
|
280
280
|
export function median<T>(
|
|
281
|
-
valueExtractor: (value: T) => number = (v) => v as unknown as number
|
|
281
|
+
valueExtractor: (value: T) => number = (v) => v as unknown as number,
|
|
282
282
|
): AggregateFunction<T, number, Array<number>> {
|
|
283
283
|
return {
|
|
284
284
|
preMap: (data: T) => [valueExtractor(data)],
|
|
@@ -326,7 +326,7 @@ export function median<T>(
|
|
|
326
326
|
* @param valueExtractor Function to extract a value from each data entry
|
|
327
327
|
*/
|
|
328
328
|
export function mode<T>(
|
|
329
|
-
valueExtractor: (value: T) => number = (v) => v as unknown as number
|
|
329
|
+
valueExtractor: (value: T) => number = (v) => v as unknown as number,
|
|
330
330
|
): AggregateFunction<T, number, Map<number, number>> {
|
|
331
331
|
return {
|
|
332
332
|
preMap: (data: T) => {
|
package/src/operators/index.ts
CHANGED
|
@@ -1,19 +1,19 @@
|
|
|
1
|
-
export * from
|
|
2
|
-
export * from
|
|
3
|
-
export * from
|
|
4
|
-
export * from
|
|
5
|
-
export * from
|
|
6
|
-
export * from
|
|
7
|
-
export * from
|
|
8
|
-
export * from
|
|
9
|
-
export * from
|
|
10
|
-
export * from
|
|
11
|
-
export * from
|
|
12
|
-
export * from
|
|
13
|
-
export * from
|
|
14
|
-
export * from
|
|
15
|
-
export * from
|
|
16
|
-
export * from
|
|
17
|
-
export * from
|
|
18
|
-
export * from
|
|
19
|
-
export { groupBy, groupByOperators } from
|
|
1
|
+
export * from './pipe.js'
|
|
2
|
+
export * from './map.js'
|
|
3
|
+
export * from './tap.js'
|
|
4
|
+
export * from './filter.js'
|
|
5
|
+
export * from './negate.js'
|
|
6
|
+
export * from './concat.js'
|
|
7
|
+
export * from './debug.js'
|
|
8
|
+
export * from './output.js'
|
|
9
|
+
export * from './consolidate.js'
|
|
10
|
+
export * from './join.js'
|
|
11
|
+
export * from './reduce.js'
|
|
12
|
+
export * from './count.js'
|
|
13
|
+
export * from './distinct.js'
|
|
14
|
+
export * from './keying.js'
|
|
15
|
+
export * from './topK.js'
|
|
16
|
+
export * from './topKWithFractionalIndex.js'
|
|
17
|
+
export * from './orderBy.js'
|
|
18
|
+
export * from './filterBy.js'
|
|
19
|
+
export { groupBy, groupByOperators } from './groupBy.js'
|
package/src/operators/join.ts
CHANGED
|
@@ -48,12 +48,12 @@
|
|
|
48
48
|
* - **Bag semantics**: Proper multiplicity handling including negatives
|
|
49
49
|
*/
|
|
50
50
|
|
|
51
|
-
import { BinaryOperator, DifferenceStreamWriter } from
|
|
52
|
-
import { StreamBuilder } from
|
|
53
|
-
import { MultiSet } from
|
|
54
|
-
import { Index } from
|
|
55
|
-
import type { DifferenceStreamReader } from
|
|
56
|
-
import type { IStreamBuilder, KeyValue, PipedOperator } from
|
|
51
|
+
import { BinaryOperator, DifferenceStreamWriter } from '../graph.js'
|
|
52
|
+
import { StreamBuilder } from '../d2.js'
|
|
53
|
+
import { MultiSet } from '../multiset.js'
|
|
54
|
+
import { Index } from '../indexes.js'
|
|
55
|
+
import type { DifferenceStreamReader } from '../graph.js'
|
|
56
|
+
import type { IStreamBuilder, KeyValue, PipedOperator } from '../types.js'
|
|
57
57
|
|
|
58
58
|
/**
|
|
59
59
|
* Type of join to perform
|
|
@@ -75,7 +75,7 @@ export class JoinOperator<K, V1, V2> extends BinaryOperator<
|
|
|
75
75
|
inputA: DifferenceStreamReader<[K, V1]>,
|
|
76
76
|
inputB: DifferenceStreamReader<[K, V2]>,
|
|
77
77
|
output: DifferenceStreamWriter<any>,
|
|
78
|
-
mode: JoinType = `inner
|
|
78
|
+
mode: JoinType = `inner`,
|
|
79
79
|
) {
|
|
80
80
|
super(id, inputA, inputB, output)
|
|
81
81
|
this.#mode = mode
|
|
@@ -84,10 +84,10 @@ export class JoinOperator<K, V1, V2> extends BinaryOperator<
|
|
|
84
84
|
run(): void {
|
|
85
85
|
// Build deltas from input messages
|
|
86
86
|
const deltaA = Index.fromMultiSets<K, V1>(
|
|
87
|
-
this.inputAMessages() as Array<MultiSet<[K, V1]
|
|
87
|
+
this.inputAMessages() as Array<MultiSet<[K, V1]>>,
|
|
88
88
|
)
|
|
89
89
|
const deltaB = Index.fromMultiSets<K, V2>(
|
|
90
|
-
this.inputBMessages() as Array<MultiSet<[K, V2]
|
|
90
|
+
this.inputBMessages() as Array<MultiSet<[K, V2]>>,
|
|
91
91
|
)
|
|
92
92
|
|
|
93
93
|
// Early-out if nothing changed
|
|
@@ -130,7 +130,7 @@ export class JoinOperator<K, V1, V2> extends BinaryOperator<
|
|
|
130
130
|
private emitInnerResults(
|
|
131
131
|
deltaA: Index<K, V1>,
|
|
132
132
|
deltaB: Index<K, V2>,
|
|
133
|
-
results: MultiSet<any
|
|
133
|
+
results: MultiSet<any>,
|
|
134
134
|
): void {
|
|
135
135
|
// Emit the three standard delta terms: ΔA⋈B_old, A_old⋈ΔB, ΔA⋈ΔB
|
|
136
136
|
if (deltaA.size > 0) results.extend(deltaA.join(this.#indexB))
|
|
@@ -141,7 +141,7 @@ export class JoinOperator<K, V1, V2> extends BinaryOperator<
|
|
|
141
141
|
private emitLeftOuterResults(
|
|
142
142
|
deltaA: Index<K, V1>,
|
|
143
143
|
deltaB: Index<K, V2>,
|
|
144
|
-
results: MultiSet<any
|
|
144
|
+
results: MultiSet<any>,
|
|
145
145
|
): void {
|
|
146
146
|
// Emit unmatched left rows from deltaA
|
|
147
147
|
if (deltaA.size > 0) {
|
|
@@ -184,7 +184,7 @@ export class JoinOperator<K, V1, V2> extends BinaryOperator<
|
|
|
184
184
|
if (multiplicity !== 0) {
|
|
185
185
|
results.add(
|
|
186
186
|
[key, [value, null]],
|
|
187
|
-
transitioningToMatched ? -multiplicity : +multiplicity
|
|
187
|
+
transitioningToMatched ? -multiplicity : +multiplicity,
|
|
188
188
|
)
|
|
189
189
|
}
|
|
190
190
|
}
|
|
@@ -195,7 +195,7 @@ export class JoinOperator<K, V1, V2> extends BinaryOperator<
|
|
|
195
195
|
private emitRightOuterResults(
|
|
196
196
|
deltaA: Index<K, V1>,
|
|
197
197
|
deltaB: Index<K, V2>,
|
|
198
|
-
results: MultiSet<any
|
|
198
|
+
results: MultiSet<any>,
|
|
199
199
|
): void {
|
|
200
200
|
// Emit unmatched right rows from deltaB
|
|
201
201
|
if (deltaB.size > 0) {
|
|
@@ -238,7 +238,7 @@ export class JoinOperator<K, V1, V2> extends BinaryOperator<
|
|
|
238
238
|
if (multiplicity !== 0) {
|
|
239
239
|
results.add(
|
|
240
240
|
[key, [null, value]],
|
|
241
|
-
transitioningToMatched ? -multiplicity : +multiplicity
|
|
241
|
+
transitioningToMatched ? -multiplicity : +multiplicity,
|
|
242
242
|
)
|
|
243
243
|
}
|
|
244
244
|
}
|
|
@@ -259,24 +259,24 @@ export function join<
|
|
|
259
259
|
T,
|
|
260
260
|
>(
|
|
261
261
|
other: IStreamBuilder<KeyValue<K, V2>>,
|
|
262
|
-
type: JoinType = `inner
|
|
262
|
+
type: JoinType = `inner`,
|
|
263
263
|
): PipedOperator<T, KeyValue<K, [V1 | null, V2 | null]>> {
|
|
264
264
|
return (
|
|
265
|
-
stream: IStreamBuilder<T
|
|
265
|
+
stream: IStreamBuilder<T>,
|
|
266
266
|
): IStreamBuilder<KeyValue<K, [V1 | null, V2 | null]>> => {
|
|
267
267
|
if (stream.graph !== other.graph) {
|
|
268
268
|
throw new Error(`Cannot join streams from different graphs`)
|
|
269
269
|
}
|
|
270
270
|
const output = new StreamBuilder<KeyValue<K, [V1 | null, V2 | null]>>(
|
|
271
271
|
stream.graph,
|
|
272
|
-
new DifferenceStreamWriter<KeyValue<K, [V1 | null, V2 | null]>>()
|
|
272
|
+
new DifferenceStreamWriter<KeyValue<K, [V1 | null, V2 | null]>>(),
|
|
273
273
|
)
|
|
274
274
|
const operator = new JoinOperator<K, V1, V2>(
|
|
275
275
|
stream.graph.getNextOperatorId(),
|
|
276
276
|
stream.connectReader() as DifferenceStreamReader<KeyValue<K, V1>>,
|
|
277
277
|
other.connectReader(),
|
|
278
278
|
output.writer,
|
|
279
|
-
type
|
|
279
|
+
type,
|
|
280
280
|
)
|
|
281
281
|
stream.graph.addOperator(operator)
|
|
282
282
|
return output
|
|
@@ -293,7 +293,7 @@ export function innerJoin<
|
|
|
293
293
|
V2,
|
|
294
294
|
T,
|
|
295
295
|
>(
|
|
296
|
-
other: IStreamBuilder<KeyValue<K, V2
|
|
296
|
+
other: IStreamBuilder<KeyValue<K, V2>>,
|
|
297
297
|
): PipedOperator<T, KeyValue<K, [V1, V2]>> {
|
|
298
298
|
return join(other, `inner`) as unknown as PipedOperator<
|
|
299
299
|
T,
|
|
@@ -311,7 +311,7 @@ export function antiJoin<
|
|
|
311
311
|
V2,
|
|
312
312
|
T,
|
|
313
313
|
>(
|
|
314
|
-
other: IStreamBuilder<KeyValue<K, V2
|
|
314
|
+
other: IStreamBuilder<KeyValue<K, V2>>,
|
|
315
315
|
): PipedOperator<T, KeyValue<K, [V1, null]>> {
|
|
316
316
|
return join(other, `anti`) as unknown as PipedOperator<
|
|
317
317
|
T,
|
|
@@ -329,7 +329,7 @@ export function leftJoin<
|
|
|
329
329
|
V2,
|
|
330
330
|
T,
|
|
331
331
|
>(
|
|
332
|
-
other: IStreamBuilder<KeyValue<K, V2
|
|
332
|
+
other: IStreamBuilder<KeyValue<K, V2>>,
|
|
333
333
|
): PipedOperator<T, KeyValue<K, [V1, V2 | null]>> {
|
|
334
334
|
return join(other, `left`) as unknown as PipedOperator<
|
|
335
335
|
T,
|
|
@@ -347,7 +347,7 @@ export function rightJoin<
|
|
|
347
347
|
V2,
|
|
348
348
|
T,
|
|
349
349
|
>(
|
|
350
|
-
other: IStreamBuilder<KeyValue<K, V2
|
|
350
|
+
other: IStreamBuilder<KeyValue<K, V2>>,
|
|
351
351
|
): PipedOperator<T, KeyValue<K, [V1 | null, V2]>> {
|
|
352
352
|
return join(other, `right`) as unknown as PipedOperator<
|
|
353
353
|
T,
|
|
@@ -365,7 +365,7 @@ export function fullJoin<
|
|
|
365
365
|
V2,
|
|
366
366
|
T,
|
|
367
367
|
>(
|
|
368
|
-
other: IStreamBuilder<KeyValue<K, V2
|
|
368
|
+
other: IStreamBuilder<KeyValue<K, V2>>,
|
|
369
369
|
): PipedOperator<T, KeyValue<K, [V1 | null, V2 | null]>> {
|
|
370
370
|
return join(other, `full`) as unknown as PipedOperator<
|
|
371
371
|
T,
|
package/src/operators/keying.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { map } from
|
|
2
|
-
import type { PipedOperator } from
|
|
1
|
+
import { map } from './map.js'
|
|
2
|
+
import type { PipedOperator } from '../types.js'
|
|
3
3
|
|
|
4
4
|
/**
|
|
5
5
|
* Type for a keyed value
|
|
@@ -11,7 +11,7 @@ export type Keyed<K, V> = [K, V]
|
|
|
11
11
|
* @param keyFn - Function to generate the key for each value
|
|
12
12
|
*/
|
|
13
13
|
export function keyBy<T, K>(
|
|
14
|
-
keyFn: (value: T) => K
|
|
14
|
+
keyFn: (value: T) => K,
|
|
15
15
|
): PipedOperator<T, Keyed<K, T>> {
|
|
16
16
|
return map((value: T): Keyed<K, T> => [keyFn(value), value])
|
|
17
17
|
}
|
|
@@ -28,7 +28,7 @@ export function unkey<K, V>(): PipedOperator<Keyed<K, V>, V> {
|
|
|
28
28
|
* @param keyFn - Function to generate the new key for each value
|
|
29
29
|
*/
|
|
30
30
|
export function rekey<K1, K2, V>(
|
|
31
|
-
keyFn: (value: V) => K2
|
|
31
|
+
keyFn: (value: V) => K2,
|
|
32
32
|
): PipedOperator<Keyed<K1, V>, Keyed<K2, V>> {
|
|
33
33
|
return map(([_, value]: Keyed<K1, V>): Keyed<K2, V> => [keyFn(value), value])
|
|
34
34
|
}
|
package/src/operators/map.ts
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import { DifferenceStreamWriter, LinearUnaryOperator } from
|
|
2
|
-
import { StreamBuilder } from
|
|
3
|
-
import type { IStreamBuilder, PipedOperator } from
|
|
4
|
-
import type { DifferenceStreamReader } from
|
|
5
|
-
import type { MultiSet } from
|
|
1
|
+
import { DifferenceStreamWriter, LinearUnaryOperator } from '../graph.js'
|
|
2
|
+
import { StreamBuilder } from '../d2.js'
|
|
3
|
+
import type { IStreamBuilder, PipedOperator } from '../types.js'
|
|
4
|
+
import type { DifferenceStreamReader } from '../graph.js'
|
|
5
|
+
import type { MultiSet } from '../multiset.js'
|
|
6
6
|
|
|
7
7
|
/**
|
|
8
8
|
* Operator that applies a function to each element in the input stream
|
|
@@ -14,7 +14,7 @@ export class MapOperator<T, U> extends LinearUnaryOperator<T, U> {
|
|
|
14
14
|
id: number,
|
|
15
15
|
inputA: DifferenceStreamReader<T>,
|
|
16
16
|
output: DifferenceStreamWriter<U>,
|
|
17
|
-
f: (data: T) => U
|
|
17
|
+
f: (data: T) => U,
|
|
18
18
|
) {
|
|
19
19
|
super(id, inputA, output)
|
|
20
20
|
this.#f = f
|
|
@@ -33,13 +33,13 @@ export function map<T, O>(f: (data: T) => O): PipedOperator<T, O> {
|
|
|
33
33
|
return (stream: IStreamBuilder<T>): IStreamBuilder<O> => {
|
|
34
34
|
const output = new StreamBuilder<O>(
|
|
35
35
|
stream.graph,
|
|
36
|
-
new DifferenceStreamWriter<O>()
|
|
36
|
+
new DifferenceStreamWriter<O>(),
|
|
37
37
|
)
|
|
38
38
|
const operator = new MapOperator<T, O>(
|
|
39
39
|
stream.graph.getNextOperatorId(),
|
|
40
40
|
stream.connectReader(),
|
|
41
41
|
output.writer,
|
|
42
|
-
f
|
|
42
|
+
f,
|
|
43
43
|
)
|
|
44
44
|
stream.graph.addOperator(operator)
|
|
45
45
|
return output
|
package/src/operators/negate.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { DifferenceStreamWriter, LinearUnaryOperator } from
|
|
2
|
-
import { StreamBuilder } from
|
|
3
|
-
import type { IStreamBuilder, PipedOperator } from
|
|
4
|
-
import type { MultiSet } from
|
|
1
|
+
import { DifferenceStreamWriter, LinearUnaryOperator } from '../graph.js'
|
|
2
|
+
import { StreamBuilder } from '../d2.js'
|
|
3
|
+
import type { IStreamBuilder, PipedOperator } from '../types.js'
|
|
4
|
+
import type { MultiSet } from '../multiset.js'
|
|
5
5
|
|
|
6
6
|
/**
|
|
7
7
|
* Operator that negates the multiplicities in the input stream
|
|
@@ -19,12 +19,12 @@ export function negate<T>(): PipedOperator<T, T> {
|
|
|
19
19
|
return (stream: IStreamBuilder<T>): IStreamBuilder<T> => {
|
|
20
20
|
const output = new StreamBuilder<T>(
|
|
21
21
|
stream.graph,
|
|
22
|
-
new DifferenceStreamWriter<T>()
|
|
22
|
+
new DifferenceStreamWriter<T>(),
|
|
23
23
|
)
|
|
24
24
|
const operator = new NegateOperator<T>(
|
|
25
25
|
stream.graph.getNextOperatorId(),
|
|
26
26
|
stream.connectReader(),
|
|
27
|
-
output.writer
|
|
27
|
+
output.writer,
|
|
28
28
|
)
|
|
29
29
|
stream.graph.addOperator(operator)
|
|
30
30
|
return output
|
package/src/operators/orderBy.ts
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import { topK, topKWithIndex } from
|
|
2
|
-
import { topKWithFractionalIndex } from
|
|
3
|
-
import { map } from
|
|
4
|
-
import { innerJoin } from
|
|
5
|
-
import { consolidate } from
|
|
6
|
-
import type { IStreamBuilder, KeyValue } from
|
|
1
|
+
import { topK, topKWithIndex } from './topK.js'
|
|
2
|
+
import { topKWithFractionalIndex } from './topKWithFractionalIndex.js'
|
|
3
|
+
import { map } from './map.js'
|
|
4
|
+
import { innerJoin } from './join.js'
|
|
5
|
+
import { consolidate } from './consolidate.js'
|
|
6
|
+
import type { IStreamBuilder, KeyValue } from '../types.js'
|
|
7
7
|
|
|
8
8
|
export interface OrderByOptions<Ve> {
|
|
9
9
|
comparator?: (a: Ve, b: Ve) => number
|
|
@@ -14,7 +14,7 @@ export interface OrderByOptions<Ve> {
|
|
|
14
14
|
type OrderByWithFractionalIndexOptions<Ve> = OrderByOptions<Ve> & {
|
|
15
15
|
setSizeCallback?: (getSize: () => number) => void
|
|
16
16
|
setWindowFn?: (
|
|
17
|
-
windowFn: (options: { offset?: number; limit?: number }) => void
|
|
17
|
+
windowFn: (options: { offset?: number; limit?: number }) => void,
|
|
18
18
|
) => void
|
|
19
19
|
}
|
|
20
20
|
|
|
@@ -28,9 +28,9 @@ type OrderByWithFractionalIndexOptions<Ve> = OrderByOptions<Ve> & {
|
|
|
28
28
|
*/
|
|
29
29
|
export function orderBy<T extends KeyValue<unknown, unknown>, Ve = unknown>(
|
|
30
30
|
valueExtractor: (
|
|
31
|
-
value: T extends KeyValue<unknown, infer V> ? V : never
|
|
31
|
+
value: T extends KeyValue<unknown, infer V> ? V : never,
|
|
32
32
|
) => Ve,
|
|
33
|
-
options?: OrderByOptions<Ve
|
|
33
|
+
options?: OrderByOptions<Ve>,
|
|
34
34
|
) {
|
|
35
35
|
const limit = options?.limit ?? Infinity
|
|
36
36
|
const offset = options?.offset ?? 0
|
|
@@ -54,10 +54,10 @@ export function orderBy<T extends KeyValue<unknown, unknown>, Ve = unknown>(
|
|
|
54
54
|
[
|
|
55
55
|
key,
|
|
56
56
|
valueExtractor(
|
|
57
|
-
value as T extends KeyValue<unknown, infer V> ? V : never
|
|
57
|
+
value as T extends KeyValue<unknown, infer V> ? V : never,
|
|
58
58
|
),
|
|
59
59
|
],
|
|
60
|
-
] as KeyValue<null, [KeyType, Ve]
|
|
60
|
+
] as KeyValue<null, [KeyType, Ve]>,
|
|
61
61
|
),
|
|
62
62
|
topK((a, b) => comparator(a[1], b[1]), { limit, offset }),
|
|
63
63
|
map(([_, [key]]) => [key, null] as KeyValue<KeyType, null>),
|
|
@@ -65,7 +65,7 @@ export function orderBy<T extends KeyValue<unknown, unknown>, Ve = unknown>(
|
|
|
65
65
|
map(([key, value]) => {
|
|
66
66
|
return [key, value[1]] as T
|
|
67
67
|
}),
|
|
68
|
-
consolidate()
|
|
68
|
+
consolidate(),
|
|
69
69
|
)
|
|
70
70
|
}
|
|
71
71
|
}
|
|
@@ -84,9 +84,9 @@ export function orderByWithIndex<
|
|
|
84
84
|
Ve = unknown,
|
|
85
85
|
>(
|
|
86
86
|
valueExtractor: (
|
|
87
|
-
value: T extends KeyValue<unknown, infer V> ? V : never
|
|
87
|
+
value: T extends KeyValue<unknown, infer V> ? V : never,
|
|
88
88
|
) => Ve,
|
|
89
|
-
options?: OrderByOptions<Ve
|
|
89
|
+
options?: OrderByOptions<Ve>,
|
|
90
90
|
) {
|
|
91
91
|
const limit = options?.limit ?? Infinity
|
|
92
92
|
const offset = options?.offset ?? 0
|
|
@@ -100,7 +100,7 @@ export function orderByWithIndex<
|
|
|
100
100
|
})
|
|
101
101
|
|
|
102
102
|
return (
|
|
103
|
-
stream: IStreamBuilder<T
|
|
103
|
+
stream: IStreamBuilder<T>,
|
|
104
104
|
): IStreamBuilder<
|
|
105
105
|
KeyValue<
|
|
106
106
|
T extends KeyValue<infer K, unknown> ? K : never,
|
|
@@ -118,10 +118,10 @@ export function orderByWithIndex<
|
|
|
118
118
|
[
|
|
119
119
|
key,
|
|
120
120
|
valueExtractor(
|
|
121
|
-
value as T extends KeyValue<unknown, infer V> ? V : never
|
|
121
|
+
value as T extends KeyValue<unknown, infer V> ? V : never,
|
|
122
122
|
),
|
|
123
123
|
],
|
|
124
|
-
] as KeyValue<null, [KeyType, Ve]
|
|
124
|
+
] as KeyValue<null, [KeyType, Ve]>,
|
|
125
125
|
),
|
|
126
126
|
topKWithIndex((a, b) => comparator(a[1], b[1]), { limit, offset }),
|
|
127
127
|
map(([_, [[key], index]]) => [key, index] as KeyValue<KeyType, number>),
|
|
@@ -129,7 +129,7 @@ export function orderByWithIndex<
|
|
|
129
129
|
map(([key, [index, value]]) => {
|
|
130
130
|
return [key, [value, index]] as KeyValue<KeyType, [ValueType, number]>
|
|
131
131
|
}),
|
|
132
|
-
consolidate()
|
|
132
|
+
consolidate(),
|
|
133
133
|
)
|
|
134
134
|
}
|
|
135
135
|
}
|
|
@@ -140,9 +140,9 @@ export function orderByWithFractionalIndexBase<
|
|
|
140
140
|
>(
|
|
141
141
|
topKFunction: typeof topKWithFractionalIndex,
|
|
142
142
|
valueExtractor: (
|
|
143
|
-
value: T extends KeyValue<unknown, infer V> ? V : never
|
|
143
|
+
value: T extends KeyValue<unknown, infer V> ? V : never,
|
|
144
144
|
) => Ve,
|
|
145
|
-
options?: OrderByWithFractionalIndexOptions<Ve
|
|
145
|
+
options?: OrderByWithFractionalIndexOptions<Ve>,
|
|
146
146
|
) {
|
|
147
147
|
type KeyType = T extends KeyValue<infer K, unknown> ? K : never
|
|
148
148
|
type ValueType = T extends KeyValue<unknown, infer V> ? V : never
|
|
@@ -161,7 +161,7 @@ export function orderByWithFractionalIndexBase<
|
|
|
161
161
|
})
|
|
162
162
|
|
|
163
163
|
return (
|
|
164
|
-
stream: IStreamBuilder<T
|
|
164
|
+
stream: IStreamBuilder<T>,
|
|
165
165
|
): IStreamBuilder<[KeyType, [ValueType, string]]> => {
|
|
166
166
|
return stream.pipe(
|
|
167
167
|
topKFunction(
|
|
@@ -172,9 +172,9 @@ export function orderByWithFractionalIndexBase<
|
|
|
172
172
|
offset,
|
|
173
173
|
setSizeCallback,
|
|
174
174
|
setWindowFn,
|
|
175
|
-
}
|
|
175
|
+
},
|
|
176
176
|
),
|
|
177
|
-
consolidate()
|
|
177
|
+
consolidate(),
|
|
178
178
|
)
|
|
179
179
|
}
|
|
180
180
|
}
|
|
@@ -193,13 +193,13 @@ export function orderByWithFractionalIndex<
|
|
|
193
193
|
Ve = unknown,
|
|
194
194
|
>(
|
|
195
195
|
valueExtractor: (
|
|
196
|
-
value: T extends KeyValue<unknown, infer V> ? V : never
|
|
196
|
+
value: T extends KeyValue<unknown, infer V> ? V : never,
|
|
197
197
|
) => Ve,
|
|
198
|
-
options?: OrderByWithFractionalIndexOptions<Ve
|
|
198
|
+
options?: OrderByWithFractionalIndexOptions<Ve>,
|
|
199
199
|
) {
|
|
200
200
|
return orderByWithFractionalIndexBase(
|
|
201
201
|
topKWithFractionalIndex,
|
|
202
202
|
valueExtractor,
|
|
203
|
-
options
|
|
203
|
+
options,
|
|
204
204
|
)
|
|
205
205
|
}
|
|
@@ -1,20 +1,20 @@
|
|
|
1
|
-
import { orderByWithFractionalIndexBase } from
|
|
2
|
-
import { topKWithFractionalIndexBTree } from
|
|
3
|
-
import type { KeyValue } from
|
|
4
|
-
import type { OrderByOptions } from
|
|
1
|
+
import { orderByWithFractionalIndexBase } from './orderBy.js'
|
|
2
|
+
import { topKWithFractionalIndexBTree } from './topKWithFractionalIndexBTree.js'
|
|
3
|
+
import type { KeyValue } from '../types.js'
|
|
4
|
+
import type { OrderByOptions } from './orderBy.js'
|
|
5
5
|
|
|
6
6
|
export function orderByWithFractionalIndexBTree<
|
|
7
7
|
T extends KeyValue<unknown, unknown>,
|
|
8
8
|
Ve = unknown,
|
|
9
9
|
>(
|
|
10
10
|
valueExtractor: (
|
|
11
|
-
value: T extends KeyValue<unknown, infer V> ? V : never
|
|
11
|
+
value: T extends KeyValue<unknown, infer V> ? V : never,
|
|
12
12
|
) => Ve,
|
|
13
|
-
options?: OrderByOptions<Ve
|
|
13
|
+
options?: OrderByOptions<Ve>,
|
|
14
14
|
) {
|
|
15
15
|
return orderByWithFractionalIndexBase(
|
|
16
16
|
topKWithFractionalIndexBTree,
|
|
17
17
|
valueExtractor,
|
|
18
|
-
options
|
|
18
|
+
options,
|
|
19
19
|
)
|
|
20
20
|
}
|
package/src/operators/output.ts
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import { DifferenceStreamWriter, UnaryOperator } from
|
|
2
|
-
import { StreamBuilder } from
|
|
3
|
-
import type { IStreamBuilder, PipedOperator } from
|
|
4
|
-
import type { DifferenceStreamReader } from
|
|
5
|
-
import type { MultiSet } from
|
|
1
|
+
import { DifferenceStreamWriter, UnaryOperator } from '../graph.js'
|
|
2
|
+
import { StreamBuilder } from '../d2.js'
|
|
3
|
+
import type { IStreamBuilder, PipedOperator } from '../types.js'
|
|
4
|
+
import type { DifferenceStreamReader } from '../graph.js'
|
|
5
|
+
import type { MultiSet } from '../multiset.js'
|
|
6
6
|
|
|
7
7
|
/**
|
|
8
8
|
* Operator that outputs the messages in the stream
|
|
@@ -14,7 +14,7 @@ export class OutputOperator<T> extends UnaryOperator<T> {
|
|
|
14
14
|
id: number,
|
|
15
15
|
inputA: DifferenceStreamReader<T>,
|
|
16
16
|
outputWriter: DifferenceStreamWriter<T>,
|
|
17
|
-
fn: (data: MultiSet<T>) => void
|
|
17
|
+
fn: (data: MultiSet<T>) => void,
|
|
18
18
|
) {
|
|
19
19
|
super(id, inputA, outputWriter)
|
|
20
20
|
this.#fn = fn
|
|
@@ -33,18 +33,18 @@ export class OutputOperator<T> extends UnaryOperator<T> {
|
|
|
33
33
|
* @param fn - The function to call with each message
|
|
34
34
|
*/
|
|
35
35
|
export function output<T>(
|
|
36
|
-
fn: (data: MultiSet<T>) => void
|
|
36
|
+
fn: (data: MultiSet<T>) => void,
|
|
37
37
|
): PipedOperator<T, T> {
|
|
38
38
|
return (stream: IStreamBuilder<T>): IStreamBuilder<T> => {
|
|
39
39
|
const outputStream = new StreamBuilder<T>(
|
|
40
40
|
stream.graph,
|
|
41
|
-
new DifferenceStreamWriter<T>()
|
|
41
|
+
new DifferenceStreamWriter<T>(),
|
|
42
42
|
)
|
|
43
43
|
const operator = new OutputOperator<T>(
|
|
44
44
|
stream.graph.getNextOperatorId(),
|
|
45
45
|
stream.connectReader(),
|
|
46
46
|
outputStream.writer,
|
|
47
|
-
fn
|
|
47
|
+
fn,
|
|
48
48
|
)
|
|
49
49
|
stream.graph.addOperator(operator)
|
|
50
50
|
return outputStream
|
package/src/operators/pipe.ts
CHANGED