UNPKG

@tanstack/db

Version:

A reactive client store for building super fast apps on sync

1 lines 9.04 kB
{"version":3,"file":"lazy-index.cjs","sources":["../../../src/indexes/lazy-index.ts"],"sourcesContent":["import type {\n BaseIndex,\n IndexConstructor,\n IndexResolver,\n} from \"./base-index.js\"\nimport type { BasicExpression } from \"../query/ir.js\"\n\n/**\n * Utility to determine if a resolver is a constructor or async loader\n */\nfunction isConstructor<TKey extends string | number>(\n resolver: IndexResolver<TKey>\n): resolver is IndexConstructor<TKey> {\n // Check if it's a function with a prototype (constructor)\n return (\n typeof resolver === `function` &&\n resolver.prototype !== undefined &&\n resolver.prototype.constructor === resolver\n )\n}\n\n/**\n * Resolve index constructor from resolver\n */\nasync function resolveIndexConstructor<TKey extends string | number>(\n resolver: IndexResolver<TKey>\n): Promise<IndexConstructor<TKey>> {\n if (isConstructor(resolver)) {\n return resolver\n } else {\n // It's an async loader function\n return await resolver()\n }\n}\n\n/**\n * Wrapper that defers index creation until first sync\n */\nexport class LazyIndexWrapper<TKey extends string | number = string | number> {\n private indexPromise: Promise<BaseIndex<TKey>> | null = null\n private resolvedIndex: BaseIndex<TKey> | null = null\n\n constructor(\n private id: number,\n private expression: BasicExpression,\n private name: string | undefined,\n private resolver: IndexResolver<TKey>,\n private options: any,\n private collectionEntries?: Iterable<[TKey, any]>\n ) {\n // For synchronous constructors, resolve immediately\n if (isConstructor(this.resolver)) {\n this.resolvedIndex = new this.resolver(\n this.id,\n this.expression,\n this.name,\n this.options\n )\n // Build with initial data if provided\n if (this.collectionEntries) {\n this.resolvedIndex.build(this.collectionEntries)\n }\n }\n }\n\n /**\n * Resolve the actual index\n */\n async resolve(): Promise<BaseIndex<TKey>> {\n if (this.resolvedIndex) {\n return this.resolvedIndex\n }\n\n if (!this.indexPromise) {\n this.indexPromise = this.createIndex()\n }\n\n this.resolvedIndex = await this.indexPromise\n return this.resolvedIndex\n }\n\n /**\n * Check if already resolved\n */\n isResolved(): boolean {\n return this.resolvedIndex !== null\n }\n\n /**\n * Get resolved index (throws if not ready)\n */\n getResolved(): BaseIndex<TKey> {\n if (!this.resolvedIndex) {\n throw new Error(\n `Index ${this.id} has not been resolved yet. Ensure collection is synced.`\n )\n }\n return this.resolvedIndex\n }\n\n /**\n * Get the index ID\n */\n getId(): number {\n return this.id\n }\n\n /**\n * Get the index name\n */\n getName(): string | undefined {\n return this.name\n }\n\n /**\n * Get the index expression\n */\n getExpression(): BasicExpression {\n return this.expression\n }\n\n private async createIndex(): Promise<BaseIndex<TKey>> {\n const IndexClass = await resolveIndexConstructor(this.resolver)\n return new IndexClass(this.id, this.expression, this.name, this.options)\n }\n}\n\n/**\n * Proxy that provides synchronous interface while index loads asynchronously\n */\nexport class IndexProxy<TKey extends string | number = string | number> {\n constructor(\n private indexId: number,\n private lazyIndex: LazyIndexWrapper<TKey>\n ) {}\n\n /**\n * Get the resolved index (throws if not ready)\n */\n get index(): BaseIndex<TKey> {\n return this.lazyIndex.getResolved()\n }\n\n /**\n * Check if index is ready\n */\n get isReady(): boolean {\n return this.lazyIndex.isResolved()\n }\n\n /**\n * Wait for index to be ready\n */\n async whenReady(): Promise<BaseIndex<TKey>> {\n return await this.lazyIndex.resolve()\n }\n\n /**\n * Get the index ID\n */\n get id(): number {\n return this.indexId\n }\n\n /**\n * Get the index name (throws if not ready)\n */\n get name(): string | undefined {\n if (this.isReady) {\n return this.index.name\n }\n return this.lazyIndex.getName()\n }\n\n /**\n * Get the index expression (available immediately)\n */\n get expression(): BasicExpression {\n return this.lazyIndex.getExpression()\n }\n\n /**\n * Check if index supports an operation (throws if not ready)\n */\n supports(operation: any): boolean {\n return this.index.supports(operation)\n }\n\n /**\n * Get index statistics (throws if not ready)\n */\n getStats() {\n return this.index.getStats()\n }\n\n /**\n * Check if index matches a field path (available immediately)\n */\n matchesField(fieldPath: Array<string>): boolean {\n const expr = this.expression\n return (\n expr.type === `ref` &&\n expr.path.length === fieldPath.length &&\n expr.path.every((part, i) => part === fieldPath[i])\n )\n }\n\n /**\n * Get the key count (throws if not ready)\n */\n get keyCount(): number {\n return this.index.keyCount\n }\n\n // Test compatibility properties - delegate to resolved index\n get indexedKeysSet(): Set<TKey> {\n const resolved = this.index as any\n return resolved.indexedKeysSet\n }\n\n get orderedEntriesArray(): Array<[any, Set<TKey>]> {\n const resolved = this.index as any\n return resolved.orderedEntriesArray\n }\n\n get valueMapData(): Map<any, Set<TKey>> {\n const resolved = this.index as any\n return resolved.valueMapData\n }\n\n // BTreeIndex compatibility methods\n equalityLookup(value: any): Set<TKey> {\n const resolved = this.index as any\n return resolved.equalityLookup?.(value) ?? new Set()\n }\n\n rangeQuery(options: any): Set<TKey> {\n const resolved = this.index as any\n return resolved.rangeQuery?.(options) ?? new Set()\n }\n\n inArrayLookup(values: Array<any>): Set<TKey> {\n const resolved = this.index as any\n return resolved.inArrayLookup?.(values) ?? new Set()\n }\n\n // Internal method for the collection to get the lazy wrapper\n _getLazyWrapper(): LazyIndexWrapper<TKey> {\n return this.lazyIndex\n }\n}\n"],"names":[],"mappings":"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"}