{"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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"}