{"version":3,"file":"basic-index.cjs","sources":["../../../src/indexes/basic-index.ts"],"sourcesContent":["import { compareKeys } from '@tanstack/db-ivm'\nimport { areSameValueZeroEqual, normalizeValue } from '../utils/comparison.js'\nimport { codedMessage, devBuild } from '../error-message.js'\nimport {\n  compareKeysReversed,\n  findInsertPositionInArray,\n} from '../utils/array-utils.js'\nimport {\n  BaseIndex,\n  builtInIndexResolverNames,\n  warnRemovalFailure,\n} from './base-index.js'\nimport type { IndexComparisonOptions, IndexOperation } from './base-index.js'\nimport type { RangeQueryOptions } from './btree-index.js'\n\nexport type { RangeQueryOptions } from './btree-index.js'\n\n/**\n * Options for Basic index\n */\nexport type BasicIndexOptions = IndexComparisonOptions\n\nfunction orderValue(value: unknown): unknown {\n  return value instanceof Date ? value.getTime() : value\n}\n\n/**\n * Basic index using Map + sorted Array.\n *\n * - Map for O(1) equality lookups\n * - Sorted Array for O(log n) range queries via binary search\n * - O(n) updates to maintain sort order\n *\n * Simpler and smaller than BTreeIndex, good for read-heavy workloads.\n * Use BTreeIndex for write-heavy workloads with large collections.\n */\nexport class BasicIndex<\n  TKey extends string | number = string | number,\n> extends BaseIndex<TKey> {\n  // Map for O(1) equality lookups: indexedValue -> Set of PKs\n  private valueMap = new Map<any, Set<TKey>>()\n  // Sorted array of unique indexed values for range queries\n  private sortedValues: Array<any> = []\n  private sortedExactValues: Array<unknown> = []\n  // Set of all indexed PKs\n  private indexedKeys = new Set<TKey>()\n\n  /**\n   * Adds a value to the index\n   */\n  add(key: TKey, item: any): void {\n    const indexedValue = this.evaluateAddedValue(key, item)\n    const normalizedValue = normalizeValue(indexedValue)\n\n    this.addToBucket(key, normalizedValue, indexedValue)\n    this.addRangeValue(indexedValue)\n\n    this.indexedKeys.add(key)\n  }\n\n  private addToBucket(\n    key: TKey,\n    normalizedValue: unknown,\n    value: unknown,\n  ): void {\n    const keySet = this.valueMap.get(normalizedValue)\n    if (keySet) {\n      // Value already exists, just add the key to the set\n      keySet.add(key)\n    } else {\n      // New value. Find its sorted position first: a comparator failure must\n      // throw before the index changes.\n      const orderedValue = orderValue(value)\n      const insertIdx = findInsertPositionInArray(\n        this.sortedValues,\n        orderedValue,\n        this.compareFn,\n      )\n      this.valueMap.set(normalizedValue, new Set([key]))\n      this.sortedValues.splice(insertIdx, 0, orderedValue)\n      this.sortedExactValues.splice(insertIdx, 0, normalizedValue)\n    }\n  }\n\n  /**\n   * Removes a value from the index\n   */\n  remove(key: TKey, item: any): void {\n    let indexedValue: any\n    try {\n      indexedValue = this.evaluateIndexExpression(item)\n    } catch (error) {\n      warnRemovalFailure(key, error)\n      this.indexedKeys.delete(key)\n      return\n    }\n\n    const normalizedValue = normalizeValue(indexedValue)\n\n    this.removeFromBucket(key, normalizedValue, indexedValue)\n    this.removeRangeValue(indexedValue)\n\n    this.indexedKeys.delete(key)\n  }\n\n  private removeFromBucket(\n    key: TKey,\n    normalizedValue: unknown,\n    value: unknown,\n  ): void {\n    const keySet = this.valueMap.get(normalizedValue)\n    if (keySet?.has(key)) {\n      // The last key for this value leaves the sorted array too. Locate it\n      // before any change, so a comparator failure leaves the index unchanged.\n      if (keySet.size === 1) {\n        const orderedValue = orderValue(value)\n        let sortedIndex = findInsertPositionInArray(\n          this.sortedValues,\n          orderedValue,\n          this.compareFn,\n        )\n        // Distinct equality keys may share one comparator position.\n        while (\n          sortedIndex < this.sortedValues.length &&\n          this.compareFn(this.sortedValues[sortedIndex], orderedValue) === 0\n        ) {\n          if (\n            areSameValueZeroEqual(\n              this.sortedExactValues[sortedIndex],\n              normalizedValue,\n            )\n          ) {\n            this.sortedValues.splice(sortedIndex, 1)\n            this.sortedExactValues.splice(sortedIndex, 1)\n            break\n          }\n          sortedIndex++\n        }\n        this.valueMap.delete(normalizedValue)\n      }\n      keySet.delete(key)\n    }\n  }\n\n  /**\n   * Updates a value in the index\n   */\n  update(key: TKey, oldItem: any, newItem: any): void {\n    let oldIndexedValue: unknown\n    let newIndexedValue: unknown\n    try {\n      oldIndexedValue = this.evaluateIndexExpression(oldItem)\n      newIndexedValue = this.evaluateIndexExpression(newItem)\n    } catch {\n      this.remove(key, oldItem)\n      this.add(key, newItem)\n      return\n    }\n\n    const oldValue = normalizeValue(oldIndexedValue)\n    const newValue = normalizeValue(newIndexedValue)\n    if (\n      areSameValueZeroEqual(oldValue, newValue) &&\n      this.valueMap.get(newValue)?.has(key) &&\n      this.indexedKeys.has(key)\n    ) {\n      this.removeRangeValue(oldIndexedValue)\n      this.addRangeValue(newIndexedValue)\n      return\n    }\n\n    this.removeFromBucket(key, oldValue, oldIndexedValue)\n    this.removeRangeValue(oldIndexedValue)\n    this.addToBucket(key, newValue, newIndexedValue)\n    this.addRangeValue(newIndexedValue)\n    this.indexedKeys.add(key)\n  }\n\n  /**\n   * Builds the index from a collection of entries\n   */\n  build(entries: Iterable<[TKey, any]>): void {\n    this.clear()\n\n    for (const [key, item] of entries) {\n      const indexedValue = this.evaluateAddedValue(key, item)\n      const value = normalizeValue(indexedValue)\n      const keys = this.valueMap.get(value)\n      if (keys) keys.add(key)\n      else {\n        this.valueMap.set(value, new Set([key]))\n        this.sortedValues.push(orderValue(indexedValue))\n        this.sortedExactValues.push(value)\n      }\n      this.addRangeValue(indexedValue)\n      this.indexedKeys.add(key)\n    }\n\n    // Array.sort moves raw undefined values last without comparing them.\n    // Wrap values so nulls-first comparison runs during a full build.\n    const sortable = this.sortedValues.map((value, index) => ({\n      value,\n      exact: this.sortedExactValues[index],\n    }))\n    sortable.sort((left, right) => this.compareFn(left.value, right.value))\n    this.sortedValues = sortable.map(({ value }) => value)\n    this.sortedExactValues = sortable.map(({ exact }) => exact)\n  }\n\n  /**\n   * Clears all data from the index\n   */\n  clear(): void {\n    this.valueMap.clear()\n    this.sortedValues = []\n    this.sortedExactValues = []\n    this.indexedKeys.clear()\n    this.clearRangeValues()\n  }\n\n  lookup(operation: IndexOperation, value: any): Set<TKey> {\n    const result = this.lookupSupportedOperation(operation, value)\n    if (result !== undefined) return result\n    throw new Error(\n      devBuild() && process.env.NODE_ENV !== `production`\n        ? `Operation ${operation} not supported by BasicIndex`\n        : codedMessage(100, { operation }),\n    )\n  }\n\n  /**\n   * Gets the number of indexed keys\n   */\n  get keyCount(): number {\n    return this.indexedKeys.size\n  }\n\n  /**\n   * Performs an equality lookup - O(1)\n   */\n  equalityLookup(value: any): Set<TKey> {\n    const normalizedValue = normalizeValue(value)\n    return this.valueMap.get(normalizedValue) ?? new Set()\n  }\n\n  /**\n   * Performs a range query using binary search - O(log n + m)\n   */\n  rangeQuery(options: RangeQueryOptions = {}): Set<TKey> {\n    const { from, to, fromInclusive = true, toInclusive = true } = options\n    const result = new Set<TKey>()\n\n    if (this.sortedValues.length === 0) {\n      return result\n    }\n\n    const orderedFrom = orderValue(from)\n    const orderedTo = orderValue(to)\n    const hasFrom = `from` in options\n    const hasTo = `to` in options\n\n    // Find start index\n    let startIdx = 0\n    if (hasFrom) {\n      startIdx = findInsertPositionInArray(\n        this.sortedValues,\n        orderedFrom,\n        this.compareFn,\n      )\n      // Comparator-equal values form one range boundary even when they are\n      // distinct equality keys.\n      while (\n        !fromInclusive &&\n        startIdx < this.sortedValues.length &&\n        this.compareFn(this.sortedValues[startIdx], orderedFrom) === 0\n      ) {\n        startIdx++\n      }\n    }\n\n    // Find end index\n    let endIdx = this.sortedValues.length\n    if (hasTo) {\n      endIdx = findInsertPositionInArray(\n        this.sortedValues,\n        orderedTo,\n        this.compareFn,\n      )\n      // Include the whole comparator group at an inclusive upper boundary.\n      while (\n        toInclusive &&\n        endIdx < this.sortedValues.length &&\n        this.compareFn(this.sortedValues[endIdx], orderedTo) === 0\n      ) {\n        endIdx++\n      }\n    }\n\n    // Collect all keys in range\n    for (let i = startIdx; i < endIdx; i++) {\n      const keys = this.valueMap.get(this.sortedExactValues[i])\n      if (keys) {\n        keys.forEach((key) => result.add(key))\n      }\n    }\n\n    return result\n  }\n\n  /**\n   * Returns the next n items in sorted order\n   */\n  take(n: number, from: any, filterFn?: (key: TKey) => boolean): Array<TKey> {\n    const orderedFrom = orderValue(from)\n    let startIdx = findInsertPositionInArray(\n      this.sortedValues,\n      orderedFrom,\n      this.compareFn,\n    )\n    // Skip past the 'from' value (exclusive)\n    while (\n      startIdx < this.sortedValues.length &&\n      this.compareFn(this.sortedValues[startIdx], orderedFrom) <= 0\n    ) {\n      startIdx++\n    }\n\n    return this.takeFromIndex(n, startIdx, 1, filterFn)\n  }\n\n  /**\n   * Returns the next n items in reverse sorted order\n   */\n  takeReversed(\n    n: number,\n    from: any,\n    filterFn?: (key: TKey) => boolean,\n  ): Array<TKey> {\n    const orderedFrom = orderValue(from)\n    let startIdx =\n      findInsertPositionInArray(\n        this.sortedValues,\n        orderedFrom,\n        this.compareFn,\n      ) - 1\n    // Skip past the 'from' value (exclusive)\n    while (\n      startIdx >= 0 &&\n      this.compareFn(this.sortedValues[startIdx], orderedFrom) >= 0\n    ) {\n      startIdx--\n    }\n\n    return this.takeFromIndex(n, startIdx, -1, filterFn)\n  }\n\n  /**\n   * Returns the first n items in sorted order (from the start)\n   */\n  takeFromStart(n: number, filterFn?: (key: TKey) => boolean): Array<TKey> {\n    return this.takeFromIndex(n, 0, 1, filterFn)\n  }\n\n  /**\n   * Returns the first n items in reverse sorted order (from the end)\n   */\n  takeReversedFromEnd(\n    n: number,\n    filterFn?: (key: TKey) => boolean,\n  ): Array<TKey> {\n    return this.takeFromIndex(n, this.sortedValues.length - 1, -1, filterFn)\n  }\n\n  private takeFromIndex(\n    n: number,\n    startIndex: number,\n    step: 1 | -1,\n    filterFn?: (key: TKey) => boolean,\n  ): Array<TKey> {\n    const result: Array<TKey> = []\n    let index = startIndex\n    while (\n      index >= 0 &&\n      index < this.sortedValues.length &&\n      result.length < n\n    ) {\n      const groupValue = this.sortedValues[index]\n      const groupKeys: Array<TKey> = []\n      do {\n        for (const key of this.valueMap.get(this.sortedExactValues[index]) ??\n          []) {\n          groupKeys.push(key)\n        }\n        index += step\n      } while (\n        index >= 0 &&\n        index < this.sortedValues.length &&\n        this.compareFn(this.sortedValues[index], groupValue) === 0\n      )\n      groupKeys.sort(step === 1 ? compareKeys : compareKeysReversed)\n      for (const key of groupKeys) {\n        if (filterFn?.(key) ?? true) result.push(key)\n        if (result.length >= n) break\n      }\n    }\n    return result\n  }\n}\n\nbuiltInIndexResolverNames.set(BasicIndex, `BasicIndex`)\n"],"names":["BaseIndex","valueMap","sortedValues","sortedExactValues","indexedKeys","normalizeValue","addToBucket","findInsertPositionInArray","warnRemovalFailure","removeFromBucket","areSameValueZeroEqual","devBuild","codedMessage","takeFromIndex","compareKeys","compareKeysReversed","builtInIndexResolverNames"],"mappings":"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"}