@tanstack/db-ivm 0.1.22 → 0.1.25

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 (42) hide show
  1. package/dist/cjs/d2.cjs +12 -2
  2. package/dist/cjs/d2.cjs.map +1 -1
  3. package/dist/cjs/hashing/hash.cjs +75 -121
  4. package/dist/cjs/hashing/hash.cjs.map +1 -1
  5. package/dist/cjs/hashing/temporal.cjs +18 -0
  6. package/dist/cjs/hashing/temporal.cjs.map +1 -0
  7. package/dist/cjs/hashing/temporal.d.cts +5 -0
  8. package/dist/cjs/indexes.cjs +6 -3
  9. package/dist/cjs/indexes.cjs.map +1 -1
  10. package/dist/cjs/multiset.cjs +55 -92
  11. package/dist/cjs/multiset.cjs.map +1 -1
  12. package/dist/cjs/multiset.d.cts +15 -0
  13. package/dist/cjs/operators/groupBy.cjs +2 -2
  14. package/dist/cjs/operators/groupBy.cjs.map +1 -1
  15. package/dist/cjs/utils.cjs +17 -61
  16. package/dist/cjs/utils.cjs.map +1 -1
  17. package/dist/cjs/utils.d.cts +3 -32
  18. package/dist/esm/d2.js +12 -2
  19. package/dist/esm/d2.js.map +1 -1
  20. package/dist/esm/hashing/hash.js +75 -121
  21. package/dist/esm/hashing/hash.js.map +1 -1
  22. package/dist/esm/hashing/temporal.d.ts +5 -0
  23. package/dist/esm/hashing/temporal.js +18 -0
  24. package/dist/esm/hashing/temporal.js.map +1 -0
  25. package/dist/esm/indexes.js +6 -3
  26. package/dist/esm/indexes.js.map +1 -1
  27. package/dist/esm/multiset.d.ts +15 -0
  28. package/dist/esm/multiset.js +56 -93
  29. package/dist/esm/multiset.js.map +1 -1
  30. package/dist/esm/operators/groupBy.js +2 -2
  31. package/dist/esm/operators/groupBy.js.map +1 -1
  32. package/dist/esm/utils.d.ts +3 -32
  33. package/dist/esm/utils.js +17 -61
  34. package/dist/esm/utils.js.map +1 -1
  35. package/package.json +1 -1
  36. package/src/d2.ts +15 -2
  37. package/src/hashing/hash.ts +118 -172
  38. package/src/hashing/temporal.ts +25 -0
  39. package/src/indexes.ts +8 -3
  40. package/src/multiset.ts +79 -132
  41. package/src/operators/groupBy.ts +8 -2
  42. package/src/utils.ts +23 -75
@@ -237,7 +237,10 @@ export function min<T, V extends CanMinMax>(
237
237
  reduce: (values) => {
238
238
  let minValue: V | undefined
239
239
  for (const [value, _multiplicity] of values) {
240
- if (!minValue || (value && value < minValue)) {
240
+ if (
241
+ value !== undefined &&
242
+ (minValue === undefined || value < minValue)
243
+ ) {
241
244
  minValue = value
242
245
  }
243
246
  }
@@ -267,7 +270,10 @@ export function max<T, V extends CanMinMax>(
267
270
  reduce: (values) => {
268
271
  let maxValue: V | undefined
269
272
  for (const [value, _multiplicity] of values) {
270
- if (!maxValue || (value && value > maxValue)) {
273
+ if (
274
+ value !== undefined &&
275
+ (maxValue === undefined || value > maxValue)
276
+ ) {
271
277
  maxValue = value
272
278
  }
273
279
  }
package/src/utils.ts CHANGED
@@ -1,3 +1,5 @@
1
+ import { isTemporal } from './hashing/temporal.js'
2
+
1
3
  /**
2
4
  * Simple assertion function for runtime checks.
3
5
  * Throws an error if the condition is false.
@@ -11,36 +13,6 @@ export function assert(
11
13
  }
12
14
  }
13
15
 
14
- /**
15
- * A map that returns a default value for keys that are not present.
16
- */
17
- export class DefaultMap<K, V> extends Map<K, V> {
18
- constructor(
19
- private defaultValue: () => V,
20
- entries?: Iterable<[K, V]>,
21
- ) {
22
- super(entries)
23
- }
24
-
25
- get(key: K): V {
26
- if (!this.has(key)) {
27
- // this.set(key, this.defaultValue())
28
- return this.defaultValue()
29
- }
30
- return super.get(key)!
31
- }
32
-
33
- /**
34
- * Update the value for a key using a function.
35
- */
36
- update(key: K, updater: (value: V) => V): V {
37
- const value = this.get(key)
38
- const newValue = updater(value)
39
- this.set(key, newValue)
40
- return newValue
41
- }
42
- }
43
-
44
16
  // JS engines have various limits on how many args can be passed to a function
45
17
  // with a spread operator, so we need to split the operation into chunks
46
18
  // 32767 is the max for Chrome 14, all others are higher
@@ -79,55 +51,25 @@ export function binarySearch<T>(
79
51
  }
80
52
 
81
53
  /**
82
- * Utility for generating unique IDs for objects and values.
83
- * Uses WeakMap for object reference tracking and consistent hashing for primitives.
54
+ * A string identity within one consolidation: primitives by value, objects,
55
+ * functions, and symbols by identity.
84
56
  */
85
- export class ObjectIdGenerator {
86
- private objectIds = new WeakMap<object, number>()
87
- private nextId = 0
88
-
89
- /**
90
- * Get a unique identifier for any value.
91
- * - Objects: Uses WeakMap for reference-based identity
92
- * - Primitives: Uses consistent string-based hashing
93
- */
94
- getId(value: any): number {
95
- // For primitives, use a simple hash of their string representation
96
- if (typeof value !== `object` || value === null) {
97
- const str = String(value)
98
- let hashValue = 0
99
- for (let i = 0; i < str.length; i++) {
100
- const char = str.charCodeAt(i)
101
- hashValue = (hashValue << 5) - hashValue + char
102
- hashValue = hashValue & hashValue // Convert to 32-bit integer
103
- }
104
- return hashValue
105
- }
106
-
107
- // For objects, use WeakMap to assign unique IDs
108
- if (!this.objectIds.has(value)) {
109
- this.objectIds.set(value, this.nextId++)
110
- }
111
- return this.objectIds.get(value)!
112
- }
113
-
114
- /**
115
- * Get a string representation of the ID for use in composite keys.
116
- */
117
- getStringId(value: any): string {
118
- if (value === null) return `null`
119
- if (value === undefined) return `undefined`
120
- if (typeof value !== `object`) return `str_${String(value)}`
121
-
122
- return `obj_${this.getId(value)}`
57
+ export function getStringId(
58
+ value: unknown,
59
+ referenceIds: Map<object | symbol, number>,
60
+ ): string {
61
+ if (value === null) return `null`
62
+ if (value === undefined) return `undefined`
63
+ const type = typeof value
64
+ if (type === `object` || type === `function` || type === `symbol`) {
65
+ const reference = value as object | symbol
66
+ let id = referenceIds.get(reference)
67
+ if (id === undefined) referenceIds.set(reference, (id = referenceIds.size))
68
+ return `ref_${id}`
123
69
  }
70
+ return `${type}_${String(value)}`
124
71
  }
125
72
 
126
- /**
127
- * Global instance for cases where a shared object ID space is needed.
128
- */
129
- export const globalObjectIdGenerator = new ObjectIdGenerator()
130
-
131
73
  export function* concatIterable<T>(
132
74
  ...iterables: Array<Iterable<T>>
133
75
  ): Iterable<T> {
@@ -209,6 +151,7 @@ type CanonicalValue =
209
151
  | readonly [`bigint`, string]
210
152
  | readonly [`string`, string]
211
153
  | readonly [`date`, number | `Invalid`]
154
+ | readonly [`temporal`, string, string]
212
155
  | readonly [`regexp`, string, string]
213
156
  | readonly [`bytes`, Array<number>]
214
157
  | readonly [`array`, Array<CanonicalValue>]
@@ -265,6 +208,7 @@ function isJsonSafeStructuralValue(
265
208
  value instanceof Date ||
266
209
  value instanceof RegExp ||
267
210
  value instanceof Uint8Array ||
211
+ isTemporal(value) ||
268
212
  value instanceof Map ||
269
213
  value instanceof Set
270
214
  ) {
@@ -348,6 +292,10 @@ function toCanonicalValue(
348
292
  return [`bytes`, Array.from(value)]
349
293
  }
350
294
 
295
+ if (isTemporal(value)) {
296
+ return [`temporal`, value[Symbol.toStringTag], value.toString()]
297
+ }
298
+
351
299
  if (Array.isArray(value)) {
352
300
  return [`array`, value.map((item) => toCanonicalValue(item, ancestors))]
353
301
  }