UNPKG

@tanstack/db

Version:

A reactive client store for building super fast apps on sync

1 lines • 5.81 kB
{"version":3,"file":"reverse-index.cjs","sources":["../../../src/indexes/reverse-index.ts"],"sourcesContent":["import { compareKeys } from '@tanstack/db-ivm'\nimport type { IndexInterface, IndexOperation, IndexReader } from './base-index'\nimport type { RangeQueryOptions } from './btree-index'\n\nexport class ReverseIndex<\n TKey extends string | number,\n> implements IndexReader<TKey> {\n private originalIndex: IndexInterface<TKey>\n\n /**\n * @param nullsFirst - Whether nullish values come first in the reversed\n * order. The original index keeps them at the opposite end, so reversing\n * it alone would move them; ordered reads put them back. Omit it to read\n * the original index's plain reversed walk, as earlier releases did.\n */\n constructor(\n index: IndexInterface<TKey>,\n private readonly nullsFirst?: boolean,\n ) {\n this.originalIndex = index\n }\n\n // Define the reversed operations\n\n lookup(operation: IndexOperation, value: any): Set<TKey> {\n const reverseOperation =\n operation === `gt`\n ? `lt`\n : operation === `gte`\n ? `lte`\n : operation === `lt`\n ? `gt`\n : operation === `lte`\n ? `gte`\n : operation\n return this.originalIndex.lookup(reverseOperation, value)\n }\n\n rangeQuery(options: RangeQueryOptions = {}): Set<TKey> {\n return this.originalIndex.rangeQueryReversed(options)\n }\n\n // Reversing the original index moves its nullish group to the opposite\n // end, so reads put the group back at the end the query asks for. Nullish\n // keys come in ascending key order; equal non-null values come in the\n // reversed walk's order. Each read gathers the nullish group, so its cost\n // grows with the number of nullish keys.\n\n take(n: number, from: any, filterFn?: (key: TKey) => boolean): Array<TKey> {\n if (this.nullsFirst === undefined) {\n return this.originalIndex.takeReversed(n, from, filterFn)\n }\n return this.read(n, filterFn, from ?? null)\n }\n\n takeFromStart(n: number, filterFn?: (key: TKey) => boolean): Array<TKey> {\n if (this.nullsFirst === undefined) {\n return this.originalIndex.takeReversedFromEnd(n, filterFn)\n }\n return this.read(n, filterFn)\n }\n\n /** Reads after `from` (`null` is the nullish group), or from the start. */\n private read(\n n: number,\n filterFn?: (key: TKey) => boolean,\n from?: unknown,\n ): Array<TKey> {\n // Every index implements `equalityLookup`; an `eq` lookup need not be\n // advertised by an index that ordered reads accept.\n const nullish = new Set([\n ...this.originalIndex.equalityLookup(null),\n ...this.originalIndex.equalityLookup(undefined),\n ])\n const keep = (key: TKey) => filterFn?.(key) ?? true\n const accept = (key: TKey) => !nullish.has(key) && keep(key)\n const values = (count: number) =>\n count <= 0\n ? []\n : from == null\n ? this.originalIndex.takeReversedFromEnd(count, accept)\n : this.originalIndex.takeReversed(count, from, accept)\n const nulls = (count: number) =>\n count <= 0\n ? []\n : [...nullish].sort(compareKeys).filter(keep).slice(0, count)\n if (from === null) return this.nullsFirst ? values(n) : []\n if (this.nullsFirst && from === undefined) {\n const head = nulls(n)\n return [...head, ...values(n - head.length)]\n }\n const keys = values(n)\n return this.nullsFirst ? keys : [...keys, ...nulls(n - keys.length)]\n }\n\n // All operations below delegate to the original index\n\n supports(operation: IndexOperation): boolean {\n return this.originalIndex.supports(operation)\n }\n\n get supportsRangeOptimization(): boolean {\n return this.originalIndex.supportsRangeOptimization\n }\n\n canOptimizeRangeFor(value: unknown): boolean {\n return this.originalIndex.canOptimizeRangeFor?.(value) ?? true\n }\n\n get keyCount(): number {\n return this.originalIndex.keyCount\n }\n}\n"],"names":["originalIndex","compareKeys"],"mappings":";;;AAIO,MAAM,aAEkB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAS7B,YACE,OACiB,YACjB;AADiB,SAAA,aAAA;AAEjB,SAAKA,KAAgB;AAAA,EACvB;AAAA;AAAA,EAIA,OAAO,WAA2B,OAAuB;AACvD,UAAM,mBACJ,cAAc,OACV,OACA,cAAc,QACZ,QACA,cAAc,OACZ,OACA,cAAc,QACZ,QACA;AACZ,WAAO,KAAKA,GAAc,OAAO,kBAAkB,KAAK;AAAA,EAC1D;AAAA,EAEA,WAAW,UAA6B,IAAe;AACrD,WAAO,KAAKA,GAAc,mBAAmB,OAAO;AAAA,EACtD;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,KAAK,GAAW,MAAW,UAAgD;AACzE,QAAI,KAAK,eAAe,QAAW;AACjC,aAAO,KAAKA,GAAc,aAAa,GAAG,MAAM,QAAQ;AAAA,IAC1D;AACA,WAAO,KAAK,KAAK,GAAG,UAAU,QAAQ,IAAI;AAAA,EAC5C;AAAA,EAEA,cAAc,GAAW,UAAgD;AACvE,QAAI,KAAK,eAAe,QAAW;AACjC,aAAO,KAAKA,GAAc,oBAAoB,GAAG,QAAQ;AAAA,IAC3D;AACA,WAAO,KAAK,KAAK,GAAG,QAAQ;AAAA,EAC9B;AAAA;AAAA,EAGQ,KACN,GACA,UACA,MACa;AAGb,UAAM,8BAAc,IAAI;AAAA,MACtB,GAAG,KAAKA,GAAc,eAAe,IAAI;AAAA,MACzC,GAAG,KAAKA,GAAc,eAAe,MAAS;AAAA,IAAA,CAC/C;AACD,UAAM,OAAO,CAAC,QAAc,WAAW,GAAG,KAAK;AAC/C,UAAM,SAAS,CAAC,QAAc,CAAC,QAAQ,IAAI,GAAG,KAAK,KAAK,GAAG;AAC3D,UAAM,SAAS,CAAC,UACd,SAAS,IACL,KACA,QAAQ,OACN,KAAKA,GAAc,oBAAoB,OAAO,MAAM,IACpD,KAAKA,GAAc,aAAa,OAAO,MAAM,MAAM;AAC3D,UAAM,QAAQ,CAAC,UACb,SAAS,IACL,CAAA,IACA,CAAC,GAAG,OAAO,EAAE,KAAKC,MAAAA,WAAW,EAAE,OAAO,IAAI,EAAE,MAAM,GAAG,KAAK;AAChE,QAAI,SAAS,KAAM,QAAO,KAAK,aAAa,OAAO,CAAC,IAAI,CAAA;AACxD,QAAI,KAAK,cAAc,SAAS,QAAW;AACzC,YAAM,OAAO,MAAM,CAAC;AACpB,aAAO,CAAC,GAAG,MAAM,GAAG,OAAO,IAAI,KAAK,MAAM,CAAC;AAAA,IAC7C;AACA,UAAM,OAAO,OAAO,CAAC;AACrB,WAAO,KAAK,aAAa,OAAO,CAAC,GAAG,MAAM,GAAG,MAAM,IAAI,KAAK,MAAM,CAAC;AAAA,EACrE;AAAA;AAAA,EAIA,SAAS,WAAoC;AAC3C,WAAO,KAAKD,GAAc,SAAS,SAAS;AAAA,EAC9C;AAAA,EAEA,IAAI,4BAAqC;AACvC,WAAO,KAAKA,GAAc;AAAA,EAC5B;AAAA,EAEA,oBAAoB,OAAyB;AAC3C,WAAO,KAAKA,GAAc,sBAAsB,KAAK,KAAK;AAAA,EAC5D;AAAA,EAEA,IAAI,WAAmB;AACrB,WAAO,KAAKA,GAAc;AAAA,EAC5B;AACF;;"}