@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.
Files changed (99) 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.map +1 -1
  5. package/dist/cjs/index.cjs +2 -0
  6. package/dist/cjs/index.cjs.map +1 -1
  7. package/dist/cjs/index.d.cts +1 -0
  8. package/dist/cjs/indexes.cjs.map +1 -1
  9. package/dist/cjs/multiset.cjs.map +1 -1
  10. package/dist/cjs/operators/concat.cjs.map +1 -1
  11. package/dist/cjs/operators/consolidate.cjs.map +1 -1
  12. package/dist/cjs/operators/count.cjs.map +1 -1
  13. package/dist/cjs/operators/debug.cjs.map +1 -1
  14. package/dist/cjs/operators/distinct.cjs.map +1 -1
  15. package/dist/cjs/operators/filter.cjs.map +1 -1
  16. package/dist/cjs/operators/filterBy.cjs.map +1 -1
  17. package/dist/cjs/operators/groupBy.cjs.map +1 -1
  18. package/dist/cjs/operators/join.cjs.map +1 -1
  19. package/dist/cjs/operators/keying.cjs.map +1 -1
  20. package/dist/cjs/operators/map.cjs.map +1 -1
  21. package/dist/cjs/operators/negate.cjs.map +1 -1
  22. package/dist/cjs/operators/orderBy.cjs.map +1 -1
  23. package/dist/cjs/operators/output.cjs.map +1 -1
  24. package/dist/cjs/operators/pipe.cjs.map +1 -1
  25. package/dist/cjs/operators/reduce.cjs.map +1 -1
  26. package/dist/cjs/operators/tap.cjs.map +1 -1
  27. package/dist/cjs/operators/topK.cjs.map +1 -1
  28. package/dist/cjs/operators/topKWithFractionalIndex.cjs +20 -35
  29. package/dist/cjs/operators/topKWithFractionalIndex.cjs.map +1 -1
  30. package/dist/cjs/operators/topKWithFractionalIndex.d.cts +3 -11
  31. package/dist/cjs/operators/topKWithFractionalIndexBTree.d.cts +4 -4
  32. package/dist/cjs/utils.cjs +9 -0
  33. package/dist/cjs/utils.cjs.map +1 -1
  34. package/dist/cjs/utils.d.cts +5 -0
  35. package/dist/esm/d2.js.map +1 -1
  36. package/dist/esm/graph.js.map +1 -1
  37. package/dist/esm/hashing/hash.js.map +1 -1
  38. package/dist/esm/index.d.ts +1 -0
  39. package/dist/esm/index.js +2 -0
  40. package/dist/esm/index.js.map +1 -1
  41. package/dist/esm/indexes.js.map +1 -1
  42. package/dist/esm/multiset.js.map +1 -1
  43. package/dist/esm/operators/concat.js.map +1 -1
  44. package/dist/esm/operators/consolidate.js.map +1 -1
  45. package/dist/esm/operators/count.js.map +1 -1
  46. package/dist/esm/operators/debug.js.map +1 -1
  47. package/dist/esm/operators/distinct.js.map +1 -1
  48. package/dist/esm/operators/filter.js.map +1 -1
  49. package/dist/esm/operators/filterBy.js.map +1 -1
  50. package/dist/esm/operators/groupBy.js.map +1 -1
  51. package/dist/esm/operators/join.js.map +1 -1
  52. package/dist/esm/operators/keying.js.map +1 -1
  53. package/dist/esm/operators/map.js.map +1 -1
  54. package/dist/esm/operators/negate.js.map +1 -1
  55. package/dist/esm/operators/orderBy.js.map +1 -1
  56. package/dist/esm/operators/output.js.map +1 -1
  57. package/dist/esm/operators/pipe.js.map +1 -1
  58. package/dist/esm/operators/reduce.js.map +1 -1
  59. package/dist/esm/operators/tap.js.map +1 -1
  60. package/dist/esm/operators/topK.js.map +1 -1
  61. package/dist/esm/operators/topKWithFractionalIndex.d.ts +3 -11
  62. package/dist/esm/operators/topKWithFractionalIndex.js +21 -36
  63. package/dist/esm/operators/topKWithFractionalIndex.js.map +1 -1
  64. package/dist/esm/operators/topKWithFractionalIndexBTree.d.ts +4 -4
  65. package/dist/esm/utils.d.ts +5 -0
  66. package/dist/esm/utils.js +9 -0
  67. package/dist/esm/utils.js.map +1 -1
  68. package/package.json +29 -29
  69. package/src/d2.ts +4 -4
  70. package/src/graph.ts +6 -6
  71. package/src/hashing/hash.ts +3 -3
  72. package/src/hashing/index.ts +2 -2
  73. package/src/index.ts +5 -4
  74. package/src/indexes.ts +8 -8
  75. package/src/multiset.ts +5 -5
  76. package/src/operators/concat.ts +6 -6
  77. package/src/operators/consolidate.ts +6 -6
  78. package/src/operators/count.ts +9 -9
  79. package/src/operators/debug.ts +8 -8
  80. package/src/operators/distinct.ts +11 -11
  81. package/src/operators/filter.ts +8 -8
  82. package/src/operators/filterBy.ts +7 -7
  83. package/src/operators/groupBy.ts +22 -22
  84. package/src/operators/index.ts +19 -19
  85. package/src/operators/join.ts +23 -23
  86. package/src/operators/keying.ts +4 -4
  87. package/src/operators/map.ts +8 -8
  88. package/src/operators/negate.ts +6 -6
  89. package/src/operators/orderBy.ts +26 -26
  90. package/src/operators/orderByBTree.ts +7 -7
  91. package/src/operators/output.ts +9 -9
  92. package/src/operators/pipe.ts +1 -1
  93. package/src/operators/reduce.ts +9 -9
  94. package/src/operators/tap.ts +8 -8
  95. package/src/operators/topK.ts +8 -8
  96. package/src/operators/topKWithFractionalIndex.ts +62 -83
  97. package/src/operators/topKWithFractionalIndexBTree.ts +19 -20
  98. package/src/types.ts +22 -22
  99. package/src/utils.ts +19 -4
package/dist/esm/utils.js CHANGED
@@ -103,11 +103,20 @@ function range(start, end) {
103
103
  for (let i = start; i < end; i++) out.push(i);
104
104
  return out;
105
105
  }
106
+ function compareKeys(a, b) {
107
+ if (typeof a === typeof b) {
108
+ if (a < b) return -1;
109
+ if (a > b) return 1;
110
+ return 0;
111
+ }
112
+ return typeof a === `string` ? -1 : 1;
113
+ }
106
114
  export {
107
115
  DefaultMap,
108
116
  ObjectIdGenerator,
109
117
  binarySearch,
110
118
  chunkedArrayPush,
119
+ compareKeys,
111
120
  diffHalfOpen,
112
121
  globalObjectIdGenerator
113
122
  };
@@ -1 +1 @@
1
- {"version":3,"file":"utils.js","sources":["../../src/utils.ts"],"sourcesContent":["/**\n * Simple assertion function for runtime checks.\n * Throws an error if the condition is false.\n */\nexport function assert(\n condition: unknown,\n message?: string\n): asserts condition {\n if (!condition) {\n throw new Error(message || `Assertion failed`)\n }\n}\n\n/**\n * A map that returns a default value for keys that are not present.\n */\nexport class DefaultMap<K, V> extends Map<K, V> {\n constructor(\n private defaultValue: () => V,\n entries?: Iterable<[K, V]>\n ) {\n super(entries)\n }\n\n get(key: K): V {\n if (!this.has(key)) {\n // this.set(key, this.defaultValue())\n return this.defaultValue()\n }\n return super.get(key)!\n }\n\n /**\n * Update the value for a key using a function.\n */\n update(key: K, updater: (value: V) => V): V {\n const value = this.get(key)\n const newValue = updater(value)\n this.set(key, newValue)\n return newValue\n }\n}\n\n// JS engines have various limits on how many args can be passed to a function\n// with a spread operator, so we need to split the operation into chunks\n// 32767 is the max for Chrome 14, all others are higher\n// TODO: investigate the performance of this and other approaches\nconst chunkSize = 30000\nexport function chunkedArrayPush(array: Array<unknown>, other: Array<unknown>) {\n if (other.length <= chunkSize) {\n array.push(...other)\n } else {\n for (let i = 0; i < other.length; i += chunkSize) {\n const chunk = other.slice(i, i + chunkSize)\n array.push(...chunk)\n }\n }\n}\n\nexport function binarySearch<T>(\n array: Array<T>,\n value: T,\n comparator: (a: T, b: T) => number\n): number {\n let low = 0\n let high = array.length\n while (low < high) {\n const mid = Math.floor((low + high) / 2)\n const comparison = comparator(array[mid]!, value)\n if (comparison < 0) {\n low = mid + 1\n } else if (comparison > 0) {\n high = mid\n } else {\n return mid\n }\n }\n return low\n}\n\n/**\n * Utility for generating unique IDs for objects and values.\n * Uses WeakMap for object reference tracking and consistent hashing for primitives.\n */\nexport class ObjectIdGenerator {\n private objectIds = new WeakMap<object, number>()\n private nextId = 0\n\n /**\n * Get a unique identifier for any value.\n * - Objects: Uses WeakMap for reference-based identity\n * - Primitives: Uses consistent string-based hashing\n */\n getId(value: any): number {\n // For primitives, use a simple hash of their string representation\n if (typeof value !== `object` || value === null) {\n const str = String(value)\n let hashValue = 0\n for (let i = 0; i < str.length; i++) {\n const char = str.charCodeAt(i)\n hashValue = (hashValue << 5) - hashValue + char\n hashValue = hashValue & hashValue // Convert to 32-bit integer\n }\n return hashValue\n }\n\n // For objects, use WeakMap to assign unique IDs\n if (!this.objectIds.has(value)) {\n this.objectIds.set(value, this.nextId++)\n }\n return this.objectIds.get(value)!\n }\n\n /**\n * Get a string representation of the ID for use in composite keys.\n */\n getStringId(value: any): string {\n if (value === null) return `null`\n if (value === undefined) return `undefined`\n if (typeof value !== `object`) return `str_${String(value)}`\n\n return `obj_${this.getId(value)}`\n }\n}\n\n/**\n * Global instance for cases where a shared object ID space is needed.\n */\nexport const globalObjectIdGenerator = new ObjectIdGenerator()\n\nexport function* concatIterable<T>(\n ...iterables: Array<Iterable<T>>\n): Iterable<T> {\n for (const iterable of iterables) {\n yield* iterable\n }\n}\n\nexport function* mapIterable<T, U>(\n it: Iterable<T>,\n fn: (t: T) => U\n): Iterable<U> {\n for (const t of it) {\n yield fn(t)\n }\n}\n\nexport type HRange = [number, number] // half-open [start, end[ i.e. end is exclusive\n\n/**\n * Computes the difference between two half-open ranges.\n * @param a - The first half-open range\n * @param b - The second half-open range\n * @returns The difference between the two ranges\n */\nexport function diffHalfOpen(a: HRange, b: HRange) {\n const [a1, a2] = a\n const [b1, b2] = b\n\n // A \\ B can be up to two segments (left and right of the overlap)\n const onlyInA: Array<number> = [\n ...range(a1, Math.min(a2, b1)), // left side of A outside B\n ...range(Math.max(a1, b2), a2), // right side of A outside B\n ]\n\n // B \\ A similarly\n const onlyInB: Array<number> = [\n ...range(b1, Math.min(b2, a1)),\n ...range(Math.max(b1, a2), b2),\n ]\n\n return { onlyInA, onlyInB }\n}\n\nfunction range(start: number, end: number): Array<number> {\n const out: Array<number> = []\n for (let i = start; i < end; i++) out.push(i)\n return out\n}\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"utils.js","sources":["../../src/utils.ts"],"sourcesContent":["/**\n * Simple assertion function for runtime checks.\n * Throws an error if the condition is false.\n */\nexport function assert(\n condition: unknown,\n message?: string,\n): asserts condition {\n if (!condition) {\n throw new Error(message || `Assertion failed`)\n }\n}\n\n/**\n * A map that returns a default value for keys that are not present.\n */\nexport class DefaultMap<K, V> extends Map<K, V> {\n constructor(\n private defaultValue: () => V,\n entries?: Iterable<[K, V]>,\n ) {\n super(entries)\n }\n\n get(key: K): V {\n if (!this.has(key)) {\n // this.set(key, this.defaultValue())\n return this.defaultValue()\n }\n return super.get(key)!\n }\n\n /**\n * Update the value for a key using a function.\n */\n update(key: K, updater: (value: V) => V): V {\n const value = this.get(key)\n const newValue = updater(value)\n this.set(key, newValue)\n return newValue\n }\n}\n\n// JS engines have various limits on how many args can be passed to a function\n// with a spread operator, so we need to split the operation into chunks\n// 32767 is the max for Chrome 14, all others are higher\n// TODO: investigate the performance of this and other approaches\nconst chunkSize = 30000\nexport function chunkedArrayPush(array: Array<unknown>, other: Array<unknown>) {\n if (other.length <= chunkSize) {\n array.push(...other)\n } else {\n for (let i = 0; i < other.length; i += chunkSize) {\n const chunk = other.slice(i, i + chunkSize)\n array.push(...chunk)\n }\n }\n}\n\nexport function binarySearch<T>(\n array: Array<T>,\n value: T,\n comparator: (a: T, b: T) => number,\n): number {\n let low = 0\n let high = array.length\n while (low < high) {\n const mid = Math.floor((low + high) / 2)\n const comparison = comparator(array[mid]!, value)\n if (comparison < 0) {\n low = mid + 1\n } else if (comparison > 0) {\n high = mid\n } else {\n return mid\n }\n }\n return low\n}\n\n/**\n * Utility for generating unique IDs for objects and values.\n * Uses WeakMap for object reference tracking and consistent hashing for primitives.\n */\nexport class ObjectIdGenerator {\n private objectIds = new WeakMap<object, number>()\n private nextId = 0\n\n /**\n * Get a unique identifier for any value.\n * - Objects: Uses WeakMap for reference-based identity\n * - Primitives: Uses consistent string-based hashing\n */\n getId(value: any): number {\n // For primitives, use a simple hash of their string representation\n if (typeof value !== `object` || value === null) {\n const str = String(value)\n let hashValue = 0\n for (let i = 0; i < str.length; i++) {\n const char = str.charCodeAt(i)\n hashValue = (hashValue << 5) - hashValue + char\n hashValue = hashValue & hashValue // Convert to 32-bit integer\n }\n return hashValue\n }\n\n // For objects, use WeakMap to assign unique IDs\n if (!this.objectIds.has(value)) {\n this.objectIds.set(value, this.nextId++)\n }\n return this.objectIds.get(value)!\n }\n\n /**\n * Get a string representation of the ID for use in composite keys.\n */\n getStringId(value: any): string {\n if (value === null) return `null`\n if (value === undefined) return `undefined`\n if (typeof value !== `object`) return `str_${String(value)}`\n\n return `obj_${this.getId(value)}`\n }\n}\n\n/**\n * Global instance for cases where a shared object ID space is needed.\n */\nexport const globalObjectIdGenerator = new ObjectIdGenerator()\n\nexport function* concatIterable<T>(\n ...iterables: Array<Iterable<T>>\n): Iterable<T> {\n for (const iterable of iterables) {\n yield* iterable\n }\n}\n\nexport function* mapIterable<T, U>(\n it: Iterable<T>,\n fn: (t: T) => U,\n): Iterable<U> {\n for (const t of it) {\n yield fn(t)\n }\n}\n\nexport type HRange = [number, number] // half-open [start, end[ i.e. end is exclusive\n\n/**\n * Computes the difference between two half-open ranges.\n * @param a - The first half-open range\n * @param b - The second half-open range\n * @returns The difference between the two ranges\n */\nexport function diffHalfOpen(a: HRange, b: HRange) {\n const [a1, a2] = a\n const [b1, b2] = b\n\n // A \\ B can be up to two segments (left and right of the overlap)\n const onlyInA: Array<number> = [\n ...range(a1, Math.min(a2, b1)), // left side of A outside B\n ...range(Math.max(a1, b2), a2), // right side of A outside B\n ]\n\n // B \\ A similarly\n const onlyInB: Array<number> = [\n ...range(b1, Math.min(b2, a1)),\n ...range(Math.max(b1, a2), b2),\n ]\n\n return { onlyInA, onlyInB }\n}\n\nfunction range(start: number, end: number): Array<number> {\n const out: Array<number> = []\n for (let i = start; i < end; i++) out.push(i)\n return out\n}\n\n/**\n * Compares two keys (string | number) in a consistent, deterministic way.\n * Handles mixed types by ordering strings before numbers.\n */\nexport function compareKeys(a: string | number, b: string | number): number {\n // Same type: compare directly\n if (typeof a === typeof b) {\n if (a < b) return -1\n if (a > b) return 1\n return 0\n }\n // Different types: strings come before numbers\n return typeof a === `string` ? -1 : 1\n}\n"],"names":[],"mappings":"AAgBO,MAAM,mBAAyB,IAAU;AAAA,EAC9C,YACU,cACR,SACA;AACA,UAAM,OAAO;AAHL,SAAA,eAAA;AAAA,EAIV;AAAA,EAEA,IAAI,KAAW;AACb,QAAI,CAAC,KAAK,IAAI,GAAG,GAAG;AAElB,aAAO,KAAK,aAAA;AAAA,IACd;AACA,WAAO,MAAM,IAAI,GAAG;AAAA,EACtB;AAAA;AAAA;AAAA;AAAA,EAKA,OAAO,KAAQ,SAA6B;AAC1C,UAAM,QAAQ,KAAK,IAAI,GAAG;AAC1B,UAAM,WAAW,QAAQ,KAAK;AAC9B,SAAK,IAAI,KAAK,QAAQ;AACtB,WAAO;AAAA,EACT;AACF;AAMA,MAAM,YAAY;AACX,SAAS,iBAAiB,OAAuB,OAAuB;AAC7E,MAAI,MAAM,UAAU,WAAW;AAC7B,UAAM,KAAK,GAAG,KAAK;AAAA,EACrB,OAAO;AACL,aAAS,IAAI,GAAG,IAAI,MAAM,QAAQ,KAAK,WAAW;AAChD,YAAM,QAAQ,MAAM,MAAM,GAAG,IAAI,SAAS;AAC1C,YAAM,KAAK,GAAG,KAAK;AAAA,IACrB;AAAA,EACF;AACF;AAEO,SAAS,aACd,OACA,OACA,YACQ;AACR,MAAI,MAAM;AACV,MAAI,OAAO,MAAM;AACjB,SAAO,MAAM,MAAM;AACjB,UAAM,MAAM,KAAK,OAAO,MAAM,QAAQ,CAAC;AACvC,UAAM,aAAa,WAAW,MAAM,GAAG,GAAI,KAAK;AAChD,QAAI,aAAa,GAAG;AAClB,YAAM,MAAM;AAAA,IACd,WAAW,aAAa,GAAG;AACzB,aAAO;AAAA,IACT,OAAO;AACL,aAAO;AAAA,IACT;AAAA,EACF;AACA,SAAO;AACT;AAMO,MAAM,kBAAkB;AAAA,EAAxB,cAAA;AACL,SAAQ,gCAAgB,QAAA;AACxB,SAAQ,SAAS;AAAA,EAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOjB,MAAM,OAAoB;AAExB,QAAI,OAAO,UAAU,YAAY,UAAU,MAAM;AAC/C,YAAM,MAAM,OAAO,KAAK;AACxB,UAAI,YAAY;AAChB,eAAS,IAAI,GAAG,IAAI,IAAI,QAAQ,KAAK;AACnC,cAAM,OAAO,IAAI,WAAW,CAAC;AAC7B,qBAAa,aAAa,KAAK,YAAY;AAC3C,oBAAY,YAAY;AAAA,MAC1B;AACA,aAAO;AAAA,IACT;AAGA,QAAI,CAAC,KAAK,UAAU,IAAI,KAAK,GAAG;AAC9B,WAAK,UAAU,IAAI,OAAO,KAAK,QAAQ;AAAA,IACzC;AACA,WAAO,KAAK,UAAU,IAAI,KAAK;AAAA,EACjC;AAAA;AAAA;AAAA;AAAA,EAKA,YAAY,OAAoB;AAC9B,QAAI,UAAU,KAAM,QAAO;AAC3B,QAAI,UAAU,OAAW,QAAO;AAChC,QAAI,OAAO,UAAU,iBAAiB,OAAO,OAAO,KAAK,CAAC;AAE1D,WAAO,OAAO,KAAK,MAAM,KAAK,CAAC;AAAA,EACjC;AACF;AAKO,MAAM,0BAA0B,IAAI,kBAAA;AA2BpC,SAAS,aAAa,GAAW,GAAW;AACjD,QAAM,CAAC,IAAI,EAAE,IAAI;AACjB,QAAM,CAAC,IAAI,EAAE,IAAI;AAGjB,QAAM,UAAyB;AAAA,IAC7B,GAAG,MAAM,IAAI,KAAK,IAAI,IAAI,EAAE,CAAC;AAAA;AAAA,IAC7B,GAAG,MAAM,KAAK,IAAI,IAAI,EAAE,GAAG,EAAE;AAAA;AAAA,EAAA;AAI/B,QAAM,UAAyB;AAAA,IAC7B,GAAG,MAAM,IAAI,KAAK,IAAI,IAAI,EAAE,CAAC;AAAA,IAC7B,GAAG,MAAM,KAAK,IAAI,IAAI,EAAE,GAAG,EAAE;AAAA,EAAA;AAG/B,SAAO,EAAE,SAAS,QAAA;AACpB;AAEA,SAAS,MAAM,OAAe,KAA4B;AACxD,QAAM,MAAqB,CAAA;AAC3B,WAAS,IAAI,OAAO,IAAI,KAAK,IAAK,KAAI,KAAK,CAAC;AAC5C,SAAO;AACT;AAMO,SAAS,YAAY,GAAoB,GAA4B;AAE1E,MAAI,OAAO,MAAM,OAAO,GAAG;AACzB,QAAI,IAAI,EAAG,QAAO;AAClB,QAAI,IAAI,EAAG,QAAO;AAClB,WAAO;AAAA,EACT;AAEA,SAAO,OAAO,MAAM,WAAW,KAAK;AACtC;"}
package/package.json CHANGED
@@ -1,15 +1,27 @@
1
1
  {
2
2
  "name": "@tanstack/db-ivm",
3
+ "version": "0.1.14",
3
4
  "description": "Incremental View Maintenance for TanStack DB based on Differential Dataflow",
4
- "version": "0.1.13",
5
- "dependencies": {
6
- "fractional-indexing": "^3.2.0",
7
- "sorted-btree": "^1.8.1"
8
- },
9
- "devDependencies": {
10
- "@types/debug": "^4.1.12",
11
- "@vitest/coverage-istanbul": "^3.2.4"
5
+ "author": "Sam Willis",
6
+ "license": "MIT",
7
+ "repository": {
8
+ "type": "git",
9
+ "url": "git+https://github.com/TanStack/db.git",
10
+ "directory": "packages/db-ivm"
12
11
  },
12
+ "homepage": "https://tanstack.com/db",
13
+ "keywords": [
14
+ "electric",
15
+ "sql",
16
+ "optimistic",
17
+ "typescript",
18
+ "ivm",
19
+ "differential-dataflow"
20
+ ],
21
+ "type": "module",
22
+ "main": "dist/cjs/index.cjs",
23
+ "module": "dist/esm/index.js",
24
+ "types": "dist/esm/index.d.ts",
13
25
  "exports": {
14
26
  ".": {
15
27
  "import": {
@@ -23,38 +35,26 @@
23
35
  },
24
36
  "./package.json": "./package.json"
25
37
  },
38
+ "sideEffects": false,
26
39
  "files": [
27
40
  "dist",
28
41
  "src"
29
42
  ],
30
- "main": "dist/cjs/index.cjs",
31
- "module": "dist/esm/index.js",
43
+ "dependencies": {
44
+ "fractional-indexing": "^3.2.0",
45
+ "sorted-btree": "^1.8.1"
46
+ },
32
47
  "peerDependencies": {
33
48
  "typescript": ">=4.7"
34
49
  },
35
- "author": "Sam Willis",
36
- "license": "MIT",
37
- "repository": {
38
- "type": "git",
39
- "url": "https://github.com/TanStack/db.git",
40
- "directory": "packages/db-ivm"
50
+ "devDependencies": {
51
+ "@types/debug": "^4.1.12",
52
+ "@vitest/coverage-istanbul": "^3.2.4"
41
53
  },
42
- "homepage": "https://tanstack.com/db",
43
- "keywords": [
44
- "electric",
45
- "sql",
46
- "optimistic",
47
- "typescript",
48
- "ivm",
49
- "differential-dataflow"
50
- ],
51
- "sideEffects": false,
52
- "type": "module",
53
- "types": "dist/esm/index.d.ts",
54
54
  "scripts": {
55
55
  "build": "vite build",
56
56
  "dev": "vite build --watch",
57
57
  "lint": "eslint . --fix",
58
- "test": "npx vitest --run"
58
+ "test": "vitest --run"
59
59
  }
60
60
  }
package/src/d2.ts CHANGED
@@ -1,11 +1,11 @@
1
- import { DifferenceStreamWriter } from "./graph.js"
1
+ import { DifferenceStreamWriter } from './graph.js'
2
2
  import type {
3
3
  BinaryOperator,
4
4
  DifferenceStreamReader,
5
5
  UnaryOperator,
6
- } from "./graph.js"
7
- import type { MultiSet, MultiSetArray } from "./multiset.js"
8
- import type { ID2, IStreamBuilder, PipedOperator } from "./types.js"
6
+ } from './graph.js'
7
+ import type { MultiSet, MultiSetArray } from './multiset.js'
8
+ import type { ID2, IStreamBuilder, PipedOperator } from './types.js'
9
9
 
10
10
  export class D2 implements ID2 {
11
11
  #operators: Array<UnaryOperator<any> | BinaryOperator<any>> = []
package/src/graph.ts CHANGED
@@ -1,10 +1,10 @@
1
- import { MultiSet } from "./multiset.js"
2
- import type { MultiSetArray } from "./multiset.js"
1
+ import { MultiSet } from './multiset.js'
2
+ import type { MultiSetArray } from './multiset.js'
3
3
  import type {
4
4
  IDifferenceStreamReader,
5
5
  IDifferenceStreamWriter,
6
6
  IOperator,
7
- } from "./types.js"
7
+ } from './types.js'
8
8
 
9
9
  /**
10
10
  * A read handle to a dataflow edge that receives data from a writer.
@@ -61,7 +61,7 @@ export abstract class Operator<T> implements IOperator<T> {
61
61
  constructor(
62
62
  public id: number,
63
63
  inputs: Array<DifferenceStreamReader<T>>,
64
- output: DifferenceStreamWriter<T>
64
+ output: DifferenceStreamWriter<T>,
65
65
  ) {
66
66
  this.inputs = inputs
67
67
  this.output = output
@@ -84,7 +84,7 @@ export abstract class UnaryOperator<Tin, Tout = Tin> extends Operator<
84
84
  constructor(
85
85
  public id: number,
86
86
  inputA: DifferenceStreamReader<Tin>,
87
- output: DifferenceStreamWriter<Tout>
87
+ output: DifferenceStreamWriter<Tout>,
88
88
  ) {
89
89
  super(id, [inputA], output)
90
90
  }
@@ -103,7 +103,7 @@ export abstract class BinaryOperator<T> extends Operator<T> {
103
103
  public id: number,
104
104
  inputA: DifferenceStreamReader<T>,
105
105
  inputB: DifferenceStreamReader<T>,
106
- output: DifferenceStreamWriter<T>
106
+ output: DifferenceStreamWriter<T>,
107
107
  ) {
108
108
  super(id, [inputA, inputB], output)
109
109
  }
@@ -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:
@@ -150,7 +150,7 @@ function updateHasher(hasher: Hasher, input: unknown): void {
150
150
  return
151
151
  default:
152
152
  console.warn(
153
- `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`,
154
154
  )
155
155
  }
156
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'
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
  }