{"version":3,"file":"indexes.cjs","sources":["../../../src/collection/indexes.ts"],"sourcesContent":["import { IndexProxy, LazyIndexWrapper } from '../indexes/lazy-index'\nimport {\n  createSingleRowRefProxy,\n  toExpression,\n} from '../query/builder/ref-proxy'\nimport { BTreeIndex } from '../indexes/btree-index'\nimport type { StandardSchemaV1 } from '@standard-schema/spec'\nimport type { BaseIndex, IndexResolver } from '../indexes/base-index'\nimport type { ChangeMessage } from '../types'\nimport type { IndexOptions } from '../indexes/index-options'\nimport type { SingleRowRefProxy } from '../query/builder/ref-proxy'\nimport type { CollectionLifecycleManager } from './lifecycle'\nimport type { CollectionStateManager } from './state'\n\nexport class CollectionIndexesManager<\n  TOutput extends object = Record<string, unknown>,\n  TKey extends string | number = string | number,\n  TSchema extends StandardSchemaV1 = StandardSchemaV1,\n  TInput extends object = TOutput,\n> {\n  private lifecycle!: CollectionLifecycleManager<TOutput, TKey, TSchema, TInput>\n  private state!: CollectionStateManager<TOutput, TKey, TSchema, TInput>\n\n  public lazyIndexes = new Map<number, LazyIndexWrapper<TKey>>()\n  public resolvedIndexes = new Map<number, BaseIndex<TKey>>()\n  public isIndexesResolved = false\n  public indexCounter = 0\n\n  constructor() {}\n\n  setDeps(deps: {\n    state: CollectionStateManager<TOutput, TKey, TSchema, TInput>\n    lifecycle: CollectionLifecycleManager<TOutput, TKey, TSchema, TInput>\n  }) {\n    this.state = deps.state\n    this.lifecycle = deps.lifecycle\n  }\n\n  /**\n   * Creates an index on a collection for faster queries.\n   */\n  public createIndex<TResolver extends IndexResolver<TKey> = typeof BTreeIndex>(\n    indexCallback: (row: SingleRowRefProxy<TOutput>) => any,\n    config: IndexOptions<TResolver> = {},\n  ): IndexProxy<TKey> {\n    this.lifecycle.validateCollectionUsable(`createIndex`)\n\n    const indexId = ++this.indexCounter\n    const singleRowRefProxy = createSingleRowRefProxy<TOutput>()\n    const indexExpression = indexCallback(singleRowRefProxy)\n    const expression = toExpression(indexExpression)\n\n    // Default to BTreeIndex if no type specified\n    const resolver = config.indexType ?? (BTreeIndex as unknown as TResolver)\n\n    // Create lazy wrapper\n    const lazyIndex = new LazyIndexWrapper<TKey>(\n      indexId,\n      expression,\n      config.name,\n      resolver,\n      config.options,\n      this.state.entries(),\n    )\n\n    this.lazyIndexes.set(indexId, lazyIndex)\n\n    // For BTreeIndex, resolve immediately and synchronously\n    if ((resolver as unknown) === BTreeIndex) {\n      try {\n        const resolvedIndex = lazyIndex.getResolved()\n        this.resolvedIndexes.set(indexId, resolvedIndex)\n      } catch (error) {\n        console.warn(`Failed to resolve BTreeIndex:`, error)\n      }\n    } else if (typeof resolver === `function` && resolver.prototype) {\n      // Other synchronous constructors - resolve immediately\n      try {\n        const resolvedIndex = lazyIndex.getResolved()\n        this.resolvedIndexes.set(indexId, resolvedIndex)\n      } catch {\n        // Fallback to async resolution\n        this.resolveSingleIndex(indexId, lazyIndex).catch((error) => {\n          console.warn(`Failed to resolve single index:`, error)\n        })\n      }\n    } else if (this.isIndexesResolved) {\n      // Async loader but indexes are already resolved - resolve this one\n      this.resolveSingleIndex(indexId, lazyIndex).catch((error) => {\n        console.warn(`Failed to resolve single index:`, error)\n      })\n    }\n\n    return new IndexProxy(indexId, lazyIndex)\n  }\n\n  /**\n   * Resolve all lazy indexes (called when collection first syncs)\n   */\n  public async resolveAllIndexes(): Promise<void> {\n    if (this.isIndexesResolved) return\n\n    const resolutionPromises = Array.from(this.lazyIndexes.entries()).map(\n      async ([indexId, lazyIndex]) => {\n        const resolvedIndex = await lazyIndex.resolve()\n\n        // Build index with current data\n        resolvedIndex.build(this.state.entries())\n\n        this.resolvedIndexes.set(indexId, resolvedIndex)\n        return { indexId, resolvedIndex }\n      },\n    )\n\n    await Promise.all(resolutionPromises)\n    this.isIndexesResolved = true\n  }\n\n  /**\n   * Resolve a single index immediately\n   */\n  private async resolveSingleIndex(\n    indexId: number,\n    lazyIndex: LazyIndexWrapper<TKey>,\n  ): Promise<BaseIndex<TKey>> {\n    const resolvedIndex = await lazyIndex.resolve()\n    resolvedIndex.build(this.state.entries())\n    this.resolvedIndexes.set(indexId, resolvedIndex)\n    return resolvedIndex\n  }\n\n  /**\n   * Get resolved indexes for query optimization\n   */\n  get indexes(): Map<number, BaseIndex<TKey>> {\n    return this.resolvedIndexes\n  }\n\n  /**\n   * Updates all indexes when the collection changes\n   */\n  public updateIndexes(changes: Array<ChangeMessage<TOutput, TKey>>): void {\n    for (const index of this.resolvedIndexes.values()) {\n      for (const change of changes) {\n        switch (change.type) {\n          case `insert`:\n            index.add(change.key, change.value)\n            break\n          case `update`:\n            if (change.previousValue) {\n              index.update(change.key, change.previousValue, change.value)\n            } else {\n              index.add(change.key, change.value)\n            }\n            break\n          case `delete`:\n            index.remove(change.key, change.value)\n            break\n        }\n      }\n    }\n  }\n\n  /**\n   * Clean up the collection by stopping sync and clearing data\n   * This can be called manually or automatically by garbage collection\n   */\n  public cleanup(): void {\n    this.lazyIndexes.clear()\n    this.resolvedIndexes.clear()\n  }\n}\n"],"names":["createSingleRowRefProxy","toExpression","BTreeIndex","lazyIndex","LazyIndexWrapper","IndexProxy"],"mappings":"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"}