UNPKG

@tanstack/db

Version:

A reactive client store for building super fast apps on sync

105 lines (104 loc) 5.61 kB
import { comparisonFunctions } from '../query/builder/functions.js'; import { RangeQueryOptions } from './btree-index.js'; import { CompareOptions } from '../query/builder/types.js'; import { BasicExpression, OrderByDirection } from '../query/ir.js'; /** * Operations that indexes can support, imported from available comparison functions */ export declare const IndexOperation: readonly ["eq", "gt", "gte", "lt", "lte", "in", "like", "ilike"]; /** * Type for index operation values */ export type IndexOperation = (typeof comparisonFunctions)[number]; /** The read-side surface consumers use on a resolved (possibly reversed) index. */ export type IndexReader<TKey extends string | number = string | number> = Pick<IndexInterface<TKey>, `lookup` | `rangeQuery` | `take` | `takeFromStart` | `keyCount` | `supports` | `supportsRangeOptimization` | `canOptimizeRangeFor`>; export interface IndexInterface<TKey extends string | number = string | number> { add: (key: TKey, item: any) => void; remove: (key: TKey, item: any) => void; update: (key: TKey, oldItem: any, newItem: any) => void; build: (entries: Iterable<[TKey, any]>) => void; clear: () => void; lookup: (operation: IndexOperation, value: any) => Set<TKey>; equalityLookup: (value: any) => Set<TKey>; inArrayLookup: (values: Array<any>) => Set<TKey>; rangeQuery: (options: RangeQueryOptions) => Set<TKey>; rangeQueryReversed: (options: RangeQueryOptions) => Set<TKey>; take: (n: number, from: unknown, filterFn?: (key: TKey) => boolean) => Array<TKey>; takeFromStart: (n: number, filterFn?: (key: TKey) => boolean) => Array<TKey>; takeReversed: (n: number, from: unknown, filterFn?: (key: TKey) => boolean) => Array<TKey>; takeReversedFromEnd: (n: number, filterFn?: (key: TKey) => boolean) => Array<TKey>; get keyCount(): number; supports: (operation: IndexOperation) => boolean; /** * Whether range lookups (gt/gte/lt/lte) on this index can be trusted to * return every matching key. Range traversal relies on the index ordering, so * it is unsafe when the index uses a custom comparator, whose order may not * match the WHERE evaluator's relational operators. Callers must fall back to * a full scan when this is `false`. */ get supportsRangeOptimization(): boolean; /** * Whether the live values in this index share the predicate operand's * relational domain. Mixed domains can sort differently in the index and * WHERE evaluator, which can make a range lookup omit matching rows. */ canOptimizeRangeFor?: (value: unknown) => boolean; matchesField: (fieldPath: Array<string>) => boolean; matchesCompareOptions: (compareOptions: CompareOptions) => boolean; matchesDirection: (direction: OrderByDirection) => boolean; } /** * Base abstract class that all index types extend */ export declare abstract class BaseIndex<TKey extends string | number = string | number> implements IndexInterface<TKey> { readonly id: number; readonly name?: string; readonly expression: BasicExpression; abstract readonly supportedOperations: Set<IndexOperation>; protected compareOptions: CompareOptions; private compiledIndexEvaluator; /** * Set by subclasses when constructed with a user-supplied comparator, whose * ordering may not match the WHERE evaluator's relational operators. */ protected hasCustomComparator: boolean; private rangeValueDomains; constructor(id: number, expression: BasicExpression, name?: string, options?: any); abstract add(key: TKey, item: any): void; abstract remove(key: TKey, item: any): void; abstract update(key: TKey, oldItem: any, newItem: any): void; abstract build(entries: Iterable<[TKey, any]>): void; abstract clear(): void; abstract lookup(operation: IndexOperation, value: any): Set<TKey>; abstract take(n: number, from: unknown, filterFn?: (key: TKey) => boolean): Array<TKey>; abstract takeFromStart(n: number, filterFn?: (key: TKey) => boolean): Array<TKey>; abstract takeReversed(n: number, from: unknown, filterFn?: (key: TKey) => boolean): Array<TKey>; abstract takeReversedFromEnd(n: number, filterFn?: (key: TKey) => boolean): Array<TKey>; abstract get keyCount(): number; abstract equalityLookup(value: any): Set<TKey>; abstract inArrayLookup(values: Array<any>): Set<TKey>; abstract rangeQuery(options: RangeQueryOptions): Set<TKey>; rangeQueryReversed(options?: RangeQueryOptions): Set<TKey>; supports(operation: IndexOperation): boolean; get supportsRangeOptimization(): boolean; protected addRangeValue(value: unknown): void; protected removeRangeValue(value: unknown): void; protected clearRangeValues(): void; canOptimizeRangeFor(value: unknown): boolean; matchesField(fieldPath: Array<string>): boolean; /** * Checks if the compare options match the index's compare options. * The direction is ignored because the index can be reversed if the direction is different. */ matchesCompareOptions(compareOptions: CompareOptions): boolean; /** * Checks if the index matches the provided direction. */ matchesDirection(direction: OrderByDirection): boolean; protected abstract initialize(options?: any): void; protected evaluateIndexExpression(item: any): any; } /** * Type for index constructor */ export type IndexConstructor<TKey extends string | number = string | number> = new (id: number, expression: BasicExpression, name?: string, options?: any) => BaseIndex<TKey>;