@tanstack/db-ivm 0.1.12 → 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.
Files changed (108) hide show
  1. package/README.md +3 -3
  2. package/dist/cjs/d2.cjs.map +1 -1
  3. package/dist/cjs/graph.cjs.map +1 -1
  4. package/dist/cjs/hashing/hash.cjs +22 -3
  5. package/dist/cjs/hashing/hash.cjs.map +1 -1
  6. package/dist/cjs/hashing/murmur.cjs +15 -15
  7. package/dist/cjs/hashing/murmur.cjs.map +1 -1
  8. package/dist/cjs/hashing/murmur.d.cts +1 -1
  9. package/dist/cjs/index.cjs +2 -0
  10. package/dist/cjs/index.cjs.map +1 -1
  11. package/dist/cjs/index.d.cts +1 -0
  12. package/dist/cjs/indexes.cjs.map +1 -1
  13. package/dist/cjs/multiset.cjs.map +1 -1
  14. package/dist/cjs/operators/concat.cjs.map +1 -1
  15. package/dist/cjs/operators/consolidate.cjs.map +1 -1
  16. package/dist/cjs/operators/count.cjs.map +1 -1
  17. package/dist/cjs/operators/debug.cjs.map +1 -1
  18. package/dist/cjs/operators/distinct.cjs.map +1 -1
  19. package/dist/cjs/operators/filter.cjs.map +1 -1
  20. package/dist/cjs/operators/filterBy.cjs.map +1 -1
  21. package/dist/cjs/operators/groupBy.cjs.map +1 -1
  22. package/dist/cjs/operators/join.cjs.map +1 -1
  23. package/dist/cjs/operators/keying.cjs.map +1 -1
  24. package/dist/cjs/operators/map.cjs.map +1 -1
  25. package/dist/cjs/operators/negate.cjs.map +1 -1
  26. package/dist/cjs/operators/orderBy.cjs.map +1 -1
  27. package/dist/cjs/operators/output.cjs.map +1 -1
  28. package/dist/cjs/operators/pipe.cjs.map +1 -1
  29. package/dist/cjs/operators/reduce.cjs.map +1 -1
  30. package/dist/cjs/operators/tap.cjs.map +1 -1
  31. package/dist/cjs/operators/topK.cjs.map +1 -1
  32. package/dist/cjs/operators/topKWithFractionalIndex.cjs +20 -35
  33. package/dist/cjs/operators/topKWithFractionalIndex.cjs.map +1 -1
  34. package/dist/cjs/operators/topKWithFractionalIndex.d.cts +3 -11
  35. package/dist/cjs/operators/topKWithFractionalIndexBTree.d.cts +4 -4
  36. package/dist/cjs/utils.cjs +9 -0
  37. package/dist/cjs/utils.cjs.map +1 -1
  38. package/dist/cjs/utils.d.cts +5 -0
  39. package/dist/esm/d2.js.map +1 -1
  40. package/dist/esm/graph.js.map +1 -1
  41. package/dist/esm/hashing/hash.js +22 -3
  42. package/dist/esm/hashing/hash.js.map +1 -1
  43. package/dist/esm/hashing/murmur.d.ts +1 -1
  44. package/dist/esm/hashing/murmur.js +15 -15
  45. package/dist/esm/hashing/murmur.js.map +1 -1
  46. package/dist/esm/index.d.ts +1 -0
  47. package/dist/esm/index.js +2 -0
  48. package/dist/esm/index.js.map +1 -1
  49. package/dist/esm/indexes.js.map +1 -1
  50. package/dist/esm/multiset.js.map +1 -1
  51. package/dist/esm/operators/concat.js.map +1 -1
  52. package/dist/esm/operators/consolidate.js.map +1 -1
  53. package/dist/esm/operators/count.js.map +1 -1
  54. package/dist/esm/operators/debug.js.map +1 -1
  55. package/dist/esm/operators/distinct.js.map +1 -1
  56. package/dist/esm/operators/filter.js.map +1 -1
  57. package/dist/esm/operators/filterBy.js.map +1 -1
  58. package/dist/esm/operators/groupBy.js.map +1 -1
  59. package/dist/esm/operators/join.js.map +1 -1
  60. package/dist/esm/operators/keying.js.map +1 -1
  61. package/dist/esm/operators/map.js.map +1 -1
  62. package/dist/esm/operators/negate.js.map +1 -1
  63. package/dist/esm/operators/orderBy.js.map +1 -1
  64. package/dist/esm/operators/output.js.map +1 -1
  65. package/dist/esm/operators/pipe.js.map +1 -1
  66. package/dist/esm/operators/reduce.js.map +1 -1
  67. package/dist/esm/operators/tap.js.map +1 -1
  68. package/dist/esm/operators/topK.js.map +1 -1
  69. package/dist/esm/operators/topKWithFractionalIndex.d.ts +3 -11
  70. package/dist/esm/operators/topKWithFractionalIndex.js +21 -36
  71. package/dist/esm/operators/topKWithFractionalIndex.js.map +1 -1
  72. package/dist/esm/operators/topKWithFractionalIndexBTree.d.ts +4 -4
  73. package/dist/esm/utils.d.ts +5 -0
  74. package/dist/esm/utils.js +9 -0
  75. package/dist/esm/utils.js.map +1 -1
  76. package/package.json +29 -29
  77. package/src/d2.ts +4 -4
  78. package/src/graph.ts +6 -6
  79. package/src/hashing/hash.ts +39 -14
  80. package/src/hashing/index.ts +2 -2
  81. package/src/hashing/murmur.ts +15 -15
  82. package/src/index.ts +5 -4
  83. package/src/indexes.ts +8 -8
  84. package/src/multiset.ts +5 -5
  85. package/src/operators/concat.ts +6 -6
  86. package/src/operators/consolidate.ts +6 -6
  87. package/src/operators/count.ts +9 -9
  88. package/src/operators/debug.ts +8 -8
  89. package/src/operators/distinct.ts +11 -11
  90. package/src/operators/filter.ts +8 -8
  91. package/src/operators/filterBy.ts +7 -7
  92. package/src/operators/groupBy.ts +22 -22
  93. package/src/operators/index.ts +19 -19
  94. package/src/operators/join.ts +23 -23
  95. package/src/operators/keying.ts +4 -4
  96. package/src/operators/map.ts +8 -8
  97. package/src/operators/negate.ts +6 -6
  98. package/src/operators/orderBy.ts +26 -26
  99. package/src/operators/orderByBTree.ts +7 -7
  100. package/src/operators/output.ts +9 -9
  101. package/src/operators/pipe.ts +1 -1
  102. package/src/operators/reduce.ts +9 -9
  103. package/src/operators/tap.ts +8 -8
  104. package/src/operators/topK.ts +8 -8
  105. package/src/operators/topKWithFractionalIndex.ts +62 -83
  106. package/src/operators/topKWithFractionalIndexBTree.ts +19 -20
  107. package/src/types.ts +22 -22
  108. package/src/utils.ts +19 -4
@@ -1,5 +1,5 @@
1
- import { MurmurHashStream, randomHash } from "./murmur.js"
2
- import type { Hasher } from "./murmur.js"
1
+ import { MurmurHashStream, randomHash } from './murmur.js'
2
+ import type { Hasher } from './murmur.js'
3
3
 
4
4
  /*
5
5
  * Implementation of structural hashing based on the Composites polyfill implementation:
@@ -17,6 +17,12 @@ const OBJECT_MARKER = randomHash()
17
17
  const ARRAY_MARKER = randomHash()
18
18
  const MAP_MARKER = randomHash()
19
19
  const SET_MARKER = randomHash()
20
+ const UINT8ARRAY_MARKER = randomHash()
21
+
22
+ // Maximum byte length for Uint8Arrays to hash by content instead of reference
23
+ // Arrays smaller than this will be hashed by content, allowing proper equality comparisons
24
+ // for small arrays like ULIDs (16 bytes) while still avoiding performance costs for large arrays
25
+ const UINT8ARRAY_CONTENT_HASH_THRESHOLD = 128
20
26
 
21
27
  const hashCache = new WeakMap<object, number>()
22
28
 
@@ -35,6 +41,24 @@ function hashObject(input: object): number {
35
41
  let valueHash: number | undefined
36
42
  if (input instanceof Date) {
37
43
  valueHash = hashDate(input)
44
+ } else if (
45
+ // Check if input is a Uint8Array or Buffer
46
+ (typeof Buffer !== `undefined` && input instanceof Buffer) ||
47
+ input instanceof Uint8Array
48
+ ) {
49
+ // For small Uint8Arrays/Buffers (e.g., ULIDs, UUIDs), hash by content
50
+ // to enable proper equality comparisons. For large arrays, hash by reference
51
+ // to avoid performance costs.
52
+ if (input.byteLength <= UINT8ARRAY_CONTENT_HASH_THRESHOLD) {
53
+ valueHash = hashUint8Array(input)
54
+ } else {
55
+ // Deeply hashing large arrays would be too costly
56
+ // so we track them by reference and cache them in a weak map
57
+ return cachedReferenceHash(input)
58
+ }
59
+ } else if (input instanceof File) {
60
+ // Files are always hashed by reference due to their potentially large size
61
+ return cachedReferenceHash(input)
38
62
  } else {
39
63
  let plainObjectInput = input
40
64
  let marker = OBJECT_MARKER
@@ -53,17 +77,6 @@ function hashObject(input: object): number {
53
77
  plainObjectInput = [...input.entries()]
54
78
  }
55
79
 
56
- if (
57
- (typeof Buffer !== `undefined` && input instanceof Buffer) ||
58
- input instanceof Uint8Array ||
59
- input instanceof File
60
- ) {
61
- // Deeply hashing these objects would be too costly
62
- // but we also don't want to ignore them
63
- // so we track them by reference and cache them in a weak map
64
- return cachedReferenceHash(input)
65
- }
66
-
67
80
  valueHash = hashPlainObject(plainObjectInput, marker)
68
81
  }
69
82
 
@@ -78,6 +91,18 @@ function hashDate(input: Date): number {
78
91
  return hasher.digest()
79
92
  }
80
93
 
94
+ function hashUint8Array(input: Uint8Array): number {
95
+ const hasher = new MurmurHashStream()
96
+ hasher.update(UINT8ARRAY_MARKER)
97
+ // Hash the byte length first to differentiate arrays of different sizes
98
+ hasher.update(input.byteLength)
99
+ // Hash each byte in the array
100
+ for (let i = 0; i < input.byteLength; i++) {
101
+ hasher.writeByte(input[i]!)
102
+ }
103
+ return hasher.digest()
104
+ }
105
+
81
106
  function hashPlainObject(input: object, marker: number): number {
82
107
  const hasher = new MurmurHashStream()
83
108
 
@@ -125,7 +150,7 @@ function updateHasher(hasher: Hasher, input: unknown): void {
125
150
  return
126
151
  default:
127
152
  console.warn(
128
- `Ignored input during hashing because it is of type ${typeof input} which is not supported`
153
+ `Ignored input during hashing because it is of type ${typeof input} which is not supported`,
129
154
  )
130
155
  }
131
156
  }
@@ -1,2 +1,2 @@
1
- export { hash } from "./hash.js"
2
- export type { Hash, Hasher } from "./murmur.js"
1
+ export { hash } from './hash.js'
2
+ export type { Hash, Hasher } from './murmur.js'
@@ -51,7 +51,7 @@ export class MurmurHashStream implements Hasher {
51
51
  this.hash = Math.imul(this.hash, 5) + 0xe6546b64
52
52
  }
53
53
 
54
- private _writeByte(byte: number): void {
54
+ writeByte(byte: number): void {
55
55
  this.carry |= (byte & 0xff) << (8 * this.carryBytes)
56
56
  this.carryBytes++
57
57
  this.length++
@@ -74,8 +74,8 @@ export class MurmurHashStream implements Hasher {
74
74
 
75
75
  for (let i = 0; i < description.length; i++) {
76
76
  const code = description.charCodeAt(i)
77
- this._writeByte(code & 0xff)
78
- this._writeByte((code >>> 8) & 0xff)
77
+ this.writeByte(code & 0xff)
78
+ this.writeByte((code >>> 8) & 0xff)
79
79
  }
80
80
  return
81
81
  }
@@ -83,20 +83,20 @@ export class MurmurHashStream implements Hasher {
83
83
  this.update(STRING_MARKER)
84
84
  for (let i = 0; i < chunk.length; i++) {
85
85
  const code = chunk.charCodeAt(i)
86
- this._writeByte(code & 0xff)
87
- this._writeByte((code >>> 8) & 0xff)
86
+ this.writeByte(code & 0xff)
87
+ this.writeByte((code >>> 8) & 0xff)
88
88
  }
89
89
  return
90
90
  case `number`:
91
91
  dv.setFloat64(0, chunk, true) // fixed little-endian
92
- this._writeByte(u8[0]!)
93
- this._writeByte(u8[1]!)
94
- this._writeByte(u8[2]!)
95
- this._writeByte(u8[3]!)
96
- this._writeByte(u8[4]!)
97
- this._writeByte(u8[5]!)
98
- this._writeByte(u8[6]!)
99
- this._writeByte(u8[7]!)
92
+ this.writeByte(u8[0]!)
93
+ this.writeByte(u8[1]!)
94
+ this.writeByte(u8[2]!)
95
+ this.writeByte(u8[3]!)
96
+ this.writeByte(u8[4]!)
97
+ this.writeByte(u8[5]!)
98
+ this.writeByte(u8[6]!)
99
+ this.writeByte(u8[7]!)
100
100
  return
101
101
  case `bigint`: {
102
102
  let value = chunk
@@ -107,10 +107,10 @@ export class MurmurHashStream implements Hasher {
107
107
  this.update(BIG_INT_MARKER)
108
108
  }
109
109
  while (value > 0n) {
110
- this._writeByte(Number(value & 0xffn))
110
+ this.writeByte(Number(value & 0xffn))
111
111
  value >>= 8n
112
112
  }
113
- if (chunk === 0n) this._writeByte(0)
113
+ if (chunk === 0n) this.writeByte(0)
114
114
  return
115
115
  }
116
116
  default:
package/src/index.ts CHANGED
@@ -1,4 +1,5 @@
1
- export * from "./d2.js"
2
- export * from "./multiset.js"
3
- export * from "./operators/index.js"
4
- export * from "./types.js"
1
+ export * from './d2.js'
2
+ export * from './multiset.js'
3
+ export * from './operators/index.js'
4
+ export * from './types.js'
5
+ export { compareKeys } from './utils.js'
package/src/indexes.ts CHANGED
@@ -33,9 +33,9 @@
33
33
  * Prefixes extracted from array values: `['prefix', 'suffix']` → prefix='prefix'
34
34
  */
35
35
 
36
- import { MultiSet } from "./multiset.js"
37
- import { hash } from "./hashing/index.js"
38
- import type { Hash } from "./hashing/index.js"
36
+ import { MultiSet } from './multiset.js'
37
+ import { hash } from './hashing/index.js'
38
+ import type { Hash } from './hashing/index.js'
39
39
 
40
40
  // We use a symbol to represent the absence of a prefix, unprefixed values a stored
41
41
  // against this key.
@@ -183,7 +183,7 @@ export class Index<TKey, TValue, TPrefix = any> {
183
183
  return `Index(${JSON.stringify(
184
184
  [...this.entries()],
185
185
  undefined,
186
- indent ? 2 : undefined
186
+ indent ? 2 : undefined,
187
187
  )})`
188
188
  }
189
189
 
@@ -325,7 +325,7 @@ export class Index<TKey, TValue, TPrefix = any> {
325
325
  key,
326
326
  mapOrSingleValue,
327
327
  value,
328
- multiplicity
328
+ multiplicity,
329
329
  )
330
330
  return
331
331
  }
@@ -362,7 +362,7 @@ export class Index<TKey, TValue, TPrefix = any> {
362
362
  key: TKey,
363
363
  currentSingleValue: SingleValue<TValue>,
364
364
  newValue: TValue,
365
- multiplicity: number
365
+ multiplicity: number,
366
366
  ) {
367
367
  const [currentValue, currentMultiplicity] = currentSingleValue
368
368
 
@@ -438,7 +438,7 @@ export class Index<TKey, TValue, TPrefix = any> {
438
438
  * @returns A multiset of the joined values.
439
439
  */
440
440
  join<TValue2>(
441
- other: Index<TKey, TValue2>
441
+ other: Index<TKey, TValue2>,
442
442
  ): MultiSet<[TKey, [TValue, TValue2]]> {
443
443
  const result: Array<[[TKey, [TValue, TValue2]], number]> = []
444
444
  // We want to iterate over the smaller of the two indexes to reduce the
@@ -499,7 +499,7 @@ function getPrefix<TValue, TPrefix>(value: TValue): TPrefix | NO_PREFIX {
499
499
  * @returns True if the value is a single value, false otherwise.
500
500
  */
501
501
  function isSingleValue<TValue>(
502
- value: SingleValue<TValue> | unknown
502
+ value: SingleValue<TValue> | unknown,
503
503
  ): value is SingleValue<TValue> {
504
504
  return Array.isArray(value)
505
505
  }
package/src/multiset.ts CHANGED
@@ -2,8 +2,8 @@ import {
2
2
  DefaultMap,
3
3
  chunkedArrayPush,
4
4
  globalObjectIdGenerator,
5
- } from "./utils.js"
6
- import { hash } from "./hashing/index.js"
5
+ } from './utils.js'
6
+ import { hash } from './hashing/index.js'
7
7
 
8
8
  export type MultiSetArray<T> = Array<[T, number]>
9
9
  export type KeyedData<T> = [key: string, value: T]
@@ -35,7 +35,7 @@ export class MultiSet<T> {
35
35
  */
36
36
  map<U>(f: (data: T) => U): MultiSet<U> {
37
37
  return new MultiSet(
38
- this.#inner.map(([data, multiplicity]) => [f(data), multiplicity])
38
+ this.#inner.map(([data, multiplicity]) => [f(data), multiplicity]),
39
39
  )
40
40
  }
41
41
 
@@ -51,7 +51,7 @@ export class MultiSet<T> {
51
51
  */
52
52
  negate(): MultiSet<T> {
53
53
  return new MultiSet(
54
- this.#inner.map(([data, multiplicity]) => [data, -multiplicity])
54
+ this.#inner.map(([data, multiplicity]) => [data, -multiplicity]),
55
55
  )
56
56
  }
57
57
 
@@ -142,7 +142,7 @@ export class MultiSet<T> {
142
142
  const compositeKey = key + `|` + valueId
143
143
  consolidated.set(
144
144
  compositeKey,
145
- (consolidated.get(compositeKey) || 0) + multiplicity
145
+ (consolidated.get(compositeKey) || 0) + multiplicity,
146
146
  )
147
147
 
148
148
  // Store the original data for the first occurrence
@@ -1,6 +1,6 @@
1
- import { BinaryOperator, DifferenceStreamWriter } from "../graph.js"
2
- import { StreamBuilder } from "../d2.js"
3
- import type { IStreamBuilder, PipedOperator } from "../types.js"
1
+ import { BinaryOperator, DifferenceStreamWriter } from '../graph.js'
2
+ import { StreamBuilder } from '../d2.js'
3
+ import type { IStreamBuilder, PipedOperator } from '../types.js'
4
4
 
5
5
  /**
6
6
  * Operator that concatenates two input streams
@@ -22,7 +22,7 @@ export class ConcatOperator<T, T2> extends BinaryOperator<T | T2> {
22
22
  * @param other - The other stream to concatenate
23
23
  */
24
24
  export function concat<T, T2>(
25
- other: IStreamBuilder<T2>
25
+ other: IStreamBuilder<T2>,
26
26
  ): PipedOperator<T, T | T2> {
27
27
  return (stream: IStreamBuilder<T | T2>): IStreamBuilder<T | T2> => {
28
28
  if (stream.graph !== other.graph) {
@@ -30,13 +30,13 @@ export function concat<T, T2>(
30
30
  }
31
31
  const output = new StreamBuilder<T | T2>(
32
32
  stream.graph,
33
- new DifferenceStreamWriter<T | T2>()
33
+ new DifferenceStreamWriter<T | T2>(),
34
34
  )
35
35
  const operator = new ConcatOperator<T, T2>(
36
36
  stream.graph.getNextOperatorId(),
37
37
  stream.connectReader(),
38
38
  other.connectReader(),
39
- output.writer
39
+ output.writer,
40
40
  )
41
41
  stream.graph.addOperator(operator)
42
42
  return output
@@ -1,7 +1,7 @@
1
- import { DifferenceStreamWriter, UnaryOperator } from "../graph.js"
2
- import { StreamBuilder } from "../d2.js"
3
- import { MultiSet } from "../multiset.js"
4
- import type { IStreamBuilder, PipedOperator } from "../types.js"
1
+ import { DifferenceStreamWriter, UnaryOperator } from '../graph.js'
2
+ import { StreamBuilder } from '../d2.js'
3
+ import { MultiSet } from '../multiset.js'
4
+ import type { IStreamBuilder, PipedOperator } from '../types.js'
5
5
 
6
6
  /**
7
7
  * Operator that consolidates collections
@@ -36,12 +36,12 @@ export function consolidate<T>(): PipedOperator<T, T> {
36
36
  return (stream: IStreamBuilder<T>): IStreamBuilder<T> => {
37
37
  const output = new StreamBuilder<T>(
38
38
  stream.graph,
39
- new DifferenceStreamWriter<T>()
39
+ new DifferenceStreamWriter<T>(),
40
40
  )
41
41
  const operator = new ConsolidateOperator<T>(
42
42
  stream.graph.getNextOperatorId(),
43
43
  stream.connectReader(),
44
- output.writer
44
+ output.writer,
45
45
  )
46
46
  stream.graph.addOperator(operator)
47
47
  return output
@@ -1,8 +1,8 @@
1
- import { DifferenceStreamWriter } from "../graph.js"
2
- import { StreamBuilder } from "../d2.js"
3
- import { ReduceOperator } from "./reduce.js"
4
- import type { DifferenceStreamReader } from "../graph.js"
5
- import type { IStreamBuilder, KeyValue } from "../types.js"
1
+ import { DifferenceStreamWriter } from '../graph.js'
2
+ import { StreamBuilder } from '../d2.js'
3
+ import { ReduceOperator } from './reduce.js'
4
+ import type { DifferenceStreamReader } from '../graph.js'
5
+ import type { IStreamBuilder, KeyValue } from '../types.js'
6
6
 
7
7
  /**
8
8
  * Operator that counts elements by key (version-free)
@@ -11,7 +11,7 @@ export class CountOperator<K, V> extends ReduceOperator<K, V, number> {
11
11
  constructor(
12
12
  id: number,
13
13
  inputA: DifferenceStreamReader<[K, V]>,
14
- output: DifferenceStreamWriter<[K, number]>
14
+ output: DifferenceStreamWriter<[K, number]>,
15
15
  ) {
16
16
  const countInner = (vals: Array<[V, number]>): Array<[number, number]> => {
17
17
  let totalCount = 0
@@ -34,16 +34,16 @@ export function count<
34
34
  T,
35
35
  >() {
36
36
  return (
37
- stream: IStreamBuilder<T>
37
+ stream: IStreamBuilder<T>,
38
38
  ): IStreamBuilder<KeyValue<KType, number>> => {
39
39
  const output = new StreamBuilder<KeyValue<KType, number>>(
40
40
  stream.graph,
41
- new DifferenceStreamWriter<KeyValue<KType, number>>()
41
+ new DifferenceStreamWriter<KeyValue<KType, number>>(),
42
42
  )
43
43
  const operator = new CountOperator<KType, VType>(
44
44
  stream.graph.getNextOperatorId(),
45
45
  stream.connectReader() as DifferenceStreamReader<KeyValue<KType, VType>>,
46
- output.writer
46
+ output.writer,
47
47
  )
48
48
  stream.graph.addOperator(operator)
49
49
  return output
@@ -1,7 +1,7 @@
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"
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
5
 
6
6
  /**
7
7
  * Operator that logs debug information about the stream
@@ -15,7 +15,7 @@ export class DebugOperator<T> extends UnaryOperator<T> {
15
15
  inputA: DifferenceStreamReader<T>,
16
16
  output: DifferenceStreamWriter<T>,
17
17
  name: string,
18
- indent: boolean = false
18
+ indent: boolean = false,
19
19
  ) {
20
20
  super(id, inputA, output)
21
21
  this.#name = name
@@ -37,19 +37,19 @@ export class DebugOperator<T> extends UnaryOperator<T> {
37
37
  */
38
38
  export function debug<T>(
39
39
  name: string,
40
- indent: boolean = false
40
+ indent: boolean = false,
41
41
  ): PipedOperator<T, T> {
42
42
  return (stream: IStreamBuilder<T>): IStreamBuilder<T> => {
43
43
  const output = new StreamBuilder<T>(
44
44
  stream.graph,
45
- new DifferenceStreamWriter<T>()
45
+ new DifferenceStreamWriter<T>(),
46
46
  )
47
47
  const operator = new DebugOperator<T>(
48
48
  stream.graph.getNextOperatorId(),
49
49
  stream.connectReader(),
50
50
  output.writer,
51
51
  name,
52
- indent
52
+ indent,
53
53
  )
54
54
  stream.graph.addOperator(operator)
55
55
  return output
@@ -1,10 +1,10 @@
1
- import { DifferenceStreamWriter, UnaryOperator } from "../graph.js"
2
- import { StreamBuilder } from "../d2.js"
3
- import { hash } from "../hashing/index.js"
4
- import { MultiSet } from "../multiset.js"
5
- import type { Hash } from "../hashing/index.js"
6
- import type { DifferenceStreamReader } from "../graph.js"
7
- import type { IStreamBuilder, KeyValue } from "../types.js"
1
+ import { DifferenceStreamWriter, UnaryOperator } from '../graph.js'
2
+ import { StreamBuilder } from '../d2.js'
3
+ import { hash } from '../hashing/index.js'
4
+ import { MultiSet } from '../multiset.js'
5
+ import type { Hash } from '../hashing/index.js'
6
+ import type { DifferenceStreamReader } from '../graph.js'
7
+ import type { IStreamBuilder, KeyValue } from '../types.js'
8
8
 
9
9
  type Multiplicity = number
10
10
 
@@ -23,7 +23,7 @@ export class DistinctOperator<
23
23
  id: number,
24
24
  input: DifferenceStreamReader<T>,
25
25
  output: DifferenceStreamWriter<KeyValue<number, GetValue<T>>>,
26
- by: (value: T) => any = (value: T) => value
26
+ by: (value: T) => any = (value: T) => value,
27
27
  ) {
28
28
  super(id, input, output)
29
29
  this.#by = by
@@ -83,18 +83,18 @@ export class DistinctOperator<
83
83
  * Removes duplicate values
84
84
  */
85
85
  export function distinct<T extends KeyValue<any, any>>(
86
- by: (value: T) => any = (value: T) => value
86
+ by: (value: T) => any = (value: T) => value,
87
87
  ) {
88
88
  return (stream: IStreamBuilder<T>): IStreamBuilder<T> => {
89
89
  const output = new StreamBuilder<T>(
90
90
  stream.graph,
91
- new DifferenceStreamWriter<T>()
91
+ new DifferenceStreamWriter<T>(),
92
92
  )
93
93
  const operator = new DistinctOperator<T>(
94
94
  stream.graph.getNextOperatorId(),
95
95
  stream.connectReader(),
96
96
  output.writer,
97
- by
97
+ by,
98
98
  )
99
99
  stream.graph.addOperator(operator)
100
100
  return output
@@ -1,8 +1,8 @@
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"
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 filters elements from the input stream
@@ -14,7 +14,7 @@ export class FilterOperator<T> extends LinearUnaryOperator<T, T> {
14
14
  id: number,
15
15
  inputA: DifferenceStreamReader<T>,
16
16
  output: DifferenceStreamWriter<T>,
17
- f: (data: T) => boolean
17
+ f: (data: T) => boolean,
18
18
  ) {
19
19
  super(id, inputA, output)
20
20
  this.#f = f
@@ -33,13 +33,13 @@ export function filter<T>(f: (data: T) => boolean): PipedOperator<T, T> {
33
33
  return (stream: IStreamBuilder<T>): IStreamBuilder<T> => {
34
34
  const output = new StreamBuilder<T>(
35
35
  stream.graph,
36
- new DifferenceStreamWriter<T>()
36
+ new DifferenceStreamWriter<T>(),
37
37
  )
38
38
  const operator = new FilterOperator<T>(
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
@@ -1,7 +1,7 @@
1
- import { map } from "./map.js"
2
- import { innerJoin } from "./join.js"
3
- import { consolidate } from "./consolidate.js"
4
- import type { IStreamBuilder, KeyValue, PipedOperator } from "../types.js"
1
+ import { map } from './map.js'
2
+ import { innerJoin } from './join.js'
3
+ import { consolidate } from './consolidate.js'
4
+ import type { IStreamBuilder, KeyValue, PipedOperator } from '../types.js'
5
5
 
6
6
  /**
7
7
  * Filters the elements of a keyed stream, by keys of another stream.
@@ -15,16 +15,16 @@ export function filterBy<
15
15
  V1 extends T extends KeyValue<infer _KT, infer VT> ? VT : never,
16
16
  T,
17
17
  >(
18
- other: IStreamBuilder<KeyValue<K, unknown>>
18
+ other: IStreamBuilder<KeyValue<K, unknown>>,
19
19
  ): PipedOperator<T, KeyValue<K, V1>> {
20
20
  return (stream: IStreamBuilder<T>): IStreamBuilder<KeyValue<K, V1>> => {
21
21
  const otherKeys = other.pipe(
22
- map(([key, _]) => [key, null] as KeyValue<K, null>)
22
+ map(([key, _]) => [key, null] as KeyValue<K, null>),
23
23
  )
24
24
  return stream.pipe(
25
25
  innerJoin(otherKeys),
26
26
  map(([key, [value, _]]) => [key, value] as KeyValue<K, V1>),
27
- consolidate()
27
+ consolidate(),
28
28
  )
29
29
  }
30
30
  }