{"version":3,"file":"index.cjs","sources":["../../../../src/query/compiler/index.ts"],"sourcesContent":["import {\n  distinct,\n  filter,\n  join as joinOperator,\n  map,\n  reduce,\n} from '@tanstack/db-ivm'\nimport { optimizeQuery } from '../optimizer.js'\nimport {\n  CollectionInputNotFoundError,\n  DistinctRequiresSelectError,\n  DuplicateAliasInSubqueryError,\n  FnSelectWithGroupByError,\n  HavingRequiresGroupByError,\n  LimitOffsetRequireOrderByError,\n  UnsupportedFromTypeError,\n} from '../../errors.js'\nimport { VIRTUAL_PROP_NAMES } from '../../virtual-props.js'\nimport {\n  IncludesSubquery,\n  PropRef,\n  Value as ValClass,\n  getWhereExpression,\n} from '../ir.js'\nimport { compileExpression, toBooleanPredicate } from './evaluators.js'\nimport { processJoins } from './joins.js'\nimport { containsAggregate, processGroupBy } from './group-by.js'\nimport { processOrderBy } from './order-by.js'\nimport { processSelect } from './select.js'\nimport type { CollectionSubscription } from '../../collection/subscription.js'\nimport type { OrderByOptimizationInfo } from './order-by.js'\nimport type {\n  BasicExpression,\n  CollectionRef,\n  IncludesMaterialization,\n  QueryIR,\n  QueryRef,\n} from '../ir.js'\nimport type { LazyCollectionCallbacks } from './joins.js'\nimport type { Collection } from '../../collection/index.js'\nimport type {\n  KeyedStream,\n  NamespacedAndKeyedStream,\n  ResultStream,\n} from '../../types.js'\nimport type { QueryCache, QueryMapping, WindowOptions } from './types.js'\n\nexport type { WindowOptions } from './types.js'\n\n/** Symbol used to tag parent $selected with routing metadata for includes */\nexport const INCLUDES_ROUTING = Symbol(`includesRouting`)\n\n/**\n * Result of compiling an includes subquery, including the child pipeline\n * and metadata needed to route child results to parent-scoped Collections.\n */\nexport interface IncludesCompilationResult {\n  /** Filtered child pipeline (post inner-join with parent keys) */\n  pipeline: ResultStream\n  /** Result field name on parent (e.g., \"issues\") */\n  fieldName: string\n  /** Parent-side correlation ref (e.g., project.id) */\n  correlationField: PropRef\n  /** Child-side correlation ref (e.g., issue.projectId) */\n  childCorrelationField: PropRef\n  /** Whether the child query has an ORDER BY clause */\n  hasOrderBy: boolean\n  /** Full compilation result for the child query (for nested includes + alias tracking) */\n  childCompilationResult: CompilationResult\n  /** Parent-side projection refs for parent-referencing filters */\n  parentProjection?: Array<PropRef>\n  /** How the output layer materializes the child result on the parent row */\n  materialization: IncludesMaterialization\n  /** Internal field used to unwrap scalar child selects */\n  scalarField?: string\n}\n\n/**\n * Result of query compilation including both the pipeline and source-specific WHERE clauses\n */\nexport interface CompilationResult {\n  /** The ID of the main collection */\n  collectionId: string\n\n  /** The compiled query pipeline (D2 stream) */\n  pipeline: ResultStream\n\n  /** Map of source aliases to their WHERE clauses for index optimization */\n  sourceWhereClauses: Map<string, BasicExpression<boolean>>\n\n  /**\n   * Maps each source alias to its collection ID. Enables per-alias subscriptions for self-joins.\n   * Example: `{ employee: 'employees-col-id', manager: 'employees-col-id' }`\n   */\n  aliasToCollectionId: Record<string, string>\n\n  /**\n   * Flattened mapping from outer alias to innermost alias for subqueries.\n   * Always provides one-hop lookups, never recursive chains.\n   *\n   * Example: `{ activeUser: 'user' }` when `.from({ activeUser: subquery })`\n   * where the subquery uses `.from({ user: collection })`.\n   *\n   * For deeply nested subqueries, the mapping goes directly to the innermost alias:\n   * `{ author: 'user' }` (not `{ author: 'activeUser' }`), so `aliasRemapping[alias]`\n   * always resolves in a single lookup.\n   *\n   * Used to resolve subscriptions during lazy loading when join aliases differ from\n   * the inner aliases where collection subscriptions were created.\n   */\n  aliasRemapping: Record<string, string>\n\n  /** Child pipelines for includes subqueries */\n  includes?: Array<IncludesCompilationResult>\n}\n\n/**\n * Compiles a query IR into a D2 pipeline\n * @param rawQuery The query IR to compile\n * @param inputs Mapping of source aliases to input streams (e.g., `{ employee: input1, manager: input2 }`)\n * @param collections Mapping of collection IDs to Collection instances\n * @param subscriptions Mapping of source aliases to CollectionSubscription instances\n * @param callbacks Mapping of source aliases to lazy loading callbacks\n * @param lazySources Set of source aliases that should load data lazily\n * @param optimizableOrderByCollections Map of collection IDs to order-by optimization info\n * @param cache Optional cache for compiled subqueries (used internally for recursion)\n * @param queryMapping Optional mapping from optimized queries to original queries\n * @returns A CompilationResult with the pipeline, source WHERE clauses, and alias metadata\n */\nexport function compileQuery(\n  rawQuery: QueryIR,\n  inputs: Record<string, KeyedStream>,\n  collections: Record<string, Collection<any, any, any, any, any>>,\n  subscriptions: Record<string, CollectionSubscription>,\n  callbacks: Record<string, LazyCollectionCallbacks>,\n  lazySources: Set<string>,\n  optimizableOrderByCollections: Record<string, OrderByOptimizationInfo>,\n  setWindowFn: (windowFn: (options: WindowOptions) => void) => void,\n  cache: QueryCache = new WeakMap(),\n  queryMapping: QueryMapping = new WeakMap(),\n  // For includes: parent key stream to inner-join with this query's FROM\n  parentKeyStream?: KeyedStream,\n  childCorrelationField?: PropRef,\n): CompilationResult {\n  // Check if the original raw query has already been compiled\n  const cachedResult = cache.get(rawQuery)\n  if (cachedResult) {\n    return cachedResult\n  }\n\n  // Validate the raw query BEFORE optimization to check user's original structure.\n  // This must happen before optimization because the optimizer may create internal\n  // subqueries (e.g., for predicate pushdown) that reuse aliases, which is fine.\n  validateQueryStructure(rawQuery)\n\n  // Optimize the query before compilation\n  const { optimizedQuery, sourceWhereClauses } = optimizeQuery(rawQuery)\n  // Use a mutable binding so we can shallow-clone select before includes mutation\n  let query = optimizedQuery\n\n  // Create mapping from optimized query to original for caching\n  queryMapping.set(query, rawQuery)\n  mapNestedQueries(query, rawQuery, queryMapping)\n\n  // Create a copy of the inputs map to avoid modifying the original\n  const allInputs = { ...inputs }\n\n  // Track alias to collection id relationships discovered during compilation.\n  // This includes all user-declared aliases plus inner aliases from subqueries.\n  const aliasToCollectionId: Record<string, string> = {}\n\n  // Track alias remapping for subqueries (outer alias → inner alias)\n  // e.g., when .join({ activeUser: subquery }) where subquery uses .from({ user: collection })\n  // we store: aliasRemapping['activeUser'] = 'user'\n  const aliasRemapping: Record<string, string> = {}\n\n  // Create a map of source aliases to input streams.\n  // Inputs MUST be keyed by alias (e.g., `{ employee: input1, manager: input2 }`),\n  // not by collection ID. This enables per-alias subscriptions where different aliases\n  // of the same collection (e.g., self-joins) maintain independent filtered streams.\n  const sources: Record<string, KeyedStream> = {}\n\n  // Process the FROM clause to get the main source\n  const {\n    alias: mainSource,\n    input: mainInput,\n    collectionId: mainCollectionId,\n  } = processFrom(\n    query.from,\n    allInputs,\n    collections,\n    subscriptions,\n    callbacks,\n    lazySources,\n    optimizableOrderByCollections,\n    setWindowFn,\n    cache,\n    queryMapping,\n    aliasToCollectionId,\n    aliasRemapping,\n    sourceWhereClauses,\n  )\n  sources[mainSource] = mainInput\n\n  // If this is an includes child query, inner-join the raw input with parent keys.\n  // This filters the child collection to only rows matching parents in the result set.\n  // The inner join happens BEFORE namespace wrapping / WHERE / SELECT / ORDER BY,\n  // so the child pipeline only processes rows that match parents.\n  let filteredMainInput = mainInput\n  if (parentKeyStream && childCorrelationField) {\n    // Re-key child input by correlation field: [correlationValue, [childKey, childRow]]\n    const childFieldPath = childCorrelationField.path.slice(1) // remove alias prefix\n    const childRekeyed = mainInput.pipe(\n      map(([key, row]: [unknown, any]) => {\n        const correlationValue = getNestedValue(row, childFieldPath)\n        return [correlationValue, [key, row]] as [unknown, [unknown, any]]\n      }),\n    )\n\n    // Inner join: only children whose correlation key exists in parent keys pass through\n    const joined = childRekeyed.pipe(joinOperator(parentKeyStream, `inner`))\n\n    // Extract: [correlationValue, [[childKey, childRow], parentContext]] → [childKey, childRow]\n    // Tag the row with __correlationKey for output routing\n    // If parentSide is non-null (parent context projected), attach as __parentContext\n    filteredMainInput = joined.pipe(\n      filter(([_correlationValue, [childSide]]: any) => {\n        return childSide != null\n      }),\n      map(([correlationValue, [childSide, parentSide]]: any) => {\n        const [childKey, childRow] = childSide\n        const tagged: any = { ...childRow, __correlationKey: correlationValue }\n        if (parentSide != null) {\n          tagged.__parentContext = parentSide\n        }\n        const effectiveKey =\n          parentSide != null\n            ? `${String(childKey)}::${JSON.stringify(parentSide)}`\n            : childKey\n        return [effectiveKey, tagged]\n      }),\n    )\n\n    // Update sources so the rest of the pipeline uses the filtered input\n    sources[mainSource] = filteredMainInput\n  }\n\n  // Prepare the initial pipeline with the main source wrapped in its alias\n  let pipeline: NamespacedAndKeyedStream = filteredMainInput.pipe(\n    map(([key, row]) => {\n      // Initialize the record with a nested structure\n      // If __parentContext exists (from parent-referencing includes), merge parent\n      // aliases into the namespaced row so WHERE can resolve parent refs\n      const { __parentContext, ...cleanRow } = row as any\n      const nsRow: Record<string, any> = { [mainSource]: cleanRow }\n      if (__parentContext) {\n        Object.assign(nsRow, __parentContext)\n        ;(nsRow as any).__parentContext = __parentContext\n      }\n      const ret = [key, nsRow] as [string, Record<string, typeof row>]\n      return ret\n    }),\n  )\n\n  // Process JOIN clauses if they exist\n  if (query.join && query.join.length > 0) {\n    pipeline = processJoins(\n      pipeline,\n      query.join,\n      sources,\n      mainCollectionId,\n      mainSource,\n      allInputs,\n      cache,\n      queryMapping,\n      collections,\n      subscriptions,\n      callbacks,\n      lazySources,\n      optimizableOrderByCollections,\n      setWindowFn,\n      rawQuery,\n      compileQuery,\n      aliasToCollectionId,\n      aliasRemapping,\n      sourceWhereClauses,\n    )\n  }\n\n  // Process the WHERE clause if it exists\n  if (query.where && query.where.length > 0) {\n    // Apply each WHERE condition as a filter (they are ANDed together)\n    for (const where of query.where) {\n      const whereExpression = getWhereExpression(where)\n      const compiledWhere = compileExpression(whereExpression)\n      pipeline = pipeline.pipe(\n        filter(([_key, namespacedRow]) => {\n          return toBooleanPredicate(compiledWhere(namespacedRow))\n        }),\n      )\n    }\n  }\n\n  // Process functional WHERE clauses if they exist\n  if (query.fnWhere && query.fnWhere.length > 0) {\n    for (const fnWhere of query.fnWhere) {\n      pipeline = pipeline.pipe(\n        filter(([_key, namespacedRow]) => {\n          return toBooleanPredicate(fnWhere(namespacedRow))\n        }),\n      )\n    }\n  }\n\n  // Extract includes from SELECT, compile child pipelines, and replace with placeholders.\n  // This must happen AFTER WHERE (so parent pipeline is filtered) but BEFORE processSelect\n  // (so IncludesSubquery nodes are stripped before select compilation).\n  const includesResults: Array<IncludesCompilationResult> = []\n  const includesRoutingFns: Array<{\n    fieldName: string\n    getRouting: (nsRow: any) => {\n      correlationKey: unknown\n      parentContext: Record<string, any> | null\n    }\n  }> = []\n  if (query.select) {\n    const includesEntries = extractIncludesFromSelect(query.select)\n    // Shallow-clone select before mutating so we don't modify the shared IR\n    // (the optimizer copies select by reference, so rawQuery.select === query.select)\n    if (includesEntries.length > 0) {\n      query = { ...query, select: { ...query.select } }\n    }\n    for (const { key, subquery } of includesEntries) {\n      // Branch parent pipeline: map to [correlationValue, parentContext]\n      // When parentProjection exists, project referenced parent fields; otherwise null (zero overhead)\n      const compiledCorrelation = compileExpression(subquery.correlationField)\n      let parentKeys: any\n      if (subquery.parentProjection && subquery.parentProjection.length > 0) {\n        const compiledProjections = subquery.parentProjection.map((ref) => ({\n          alias: ref.path[0]!,\n          field: ref.path.slice(1),\n          compiled: compileExpression(ref),\n        }))\n        parentKeys = pipeline.pipe(\n          map(([_key, nsRow]: any) => {\n            const parentContext: Record<string, Record<string, any>> = {}\n            for (const proj of compiledProjections) {\n              if (!parentContext[proj.alias]) {\n                parentContext[proj.alias] = {}\n              }\n              const value = proj.compiled(nsRow)\n              // Set nested field in the alias namespace\n              let target = parentContext[proj.alias]!\n              for (let i = 0; i < proj.field.length - 1; i++) {\n                if (!target[proj.field[i]!]) {\n                  target[proj.field[i]!] = {}\n                }\n                target = target[proj.field[i]!]\n              }\n              target[proj.field[proj.field.length - 1]!] = value\n            }\n            return [compiledCorrelation(nsRow), parentContext] as any\n          }),\n        )\n      } else {\n        parentKeys = pipeline.pipe(\n          map(\n            ([_key, nsRow]: any) => [compiledCorrelation(nsRow), null] as any,\n          ),\n        )\n      }\n\n      // Deduplicate: when multiple parents share the same correlation key (and\n      // parentContext), clamp multiplicity to 1 so the inner join doesn't\n      // produce duplicate child entries that cause incorrect deletions.\n      parentKeys = parentKeys.pipe(\n        reduce((values: Array<[any, number]>) =>\n          values.map(([v, mult]) => [v, mult > 0 ? 1 : 0] as [any, number]),\n        ),\n      )\n\n      // If parent filters exist, append them to the child query's WHERE\n      const childQuery =\n        subquery.parentFilters && subquery.parentFilters.length > 0\n          ? {\n              ...subquery.query,\n              where: [\n                ...(subquery.query.where || []),\n                ...subquery.parentFilters,\n              ],\n            }\n          : subquery.query\n\n      // Recursively compile child query WITH the parent key stream\n      const childResult = compileQuery(\n        childQuery,\n        allInputs,\n        collections,\n        subscriptions,\n        callbacks,\n        lazySources,\n        optimizableOrderByCollections,\n        setWindowFn,\n        cache,\n        queryMapping,\n        parentKeys,\n        subquery.childCorrelationField,\n      )\n\n      // Merge child's alias metadata into parent's\n      Object.assign(aliasToCollectionId, childResult.aliasToCollectionId)\n      Object.assign(aliasRemapping, childResult.aliasRemapping)\n\n      includesResults.push({\n        pipeline: childResult.pipeline,\n        fieldName: subquery.fieldName,\n        correlationField: subquery.correlationField,\n        childCorrelationField: subquery.childCorrelationField,\n        hasOrderBy: !!(\n          subquery.query.orderBy && subquery.query.orderBy.length > 0\n        ),\n        childCompilationResult: childResult,\n        parentProjection: subquery.parentProjection,\n        materialization: subquery.materialization,\n        scalarField: subquery.scalarField,\n      })\n\n      // Capture routing function for INCLUDES_ROUTING tagging\n      if (subquery.parentProjection && subquery.parentProjection.length > 0) {\n        const compiledProjs = subquery.parentProjection.map((ref) => ({\n          alias: ref.path[0]!,\n          field: ref.path.slice(1),\n          compiled: compileExpression(ref),\n        }))\n        const compiledCorr = compiledCorrelation\n        includesRoutingFns.push({\n          fieldName: subquery.fieldName,\n          getRouting: (nsRow: any) => {\n            const parentContext: Record<string, Record<string, any>> = {}\n            for (const proj of compiledProjs) {\n              if (!parentContext[proj.alias]) {\n                parentContext[proj.alias] = {}\n              }\n              const value = proj.compiled(nsRow)\n              let target = parentContext[proj.alias]!\n              for (let i = 0; i < proj.field.length - 1; i++) {\n                if (!target[proj.field[i]!]) {\n                  target[proj.field[i]!] = {}\n                }\n                target = target[proj.field[i]!]\n              }\n              target[proj.field[proj.field.length - 1]!] = value\n            }\n            return { correlationKey: compiledCorr(nsRow), parentContext }\n          },\n        })\n      } else {\n        includesRoutingFns.push({\n          fieldName: subquery.fieldName,\n          getRouting: (nsRow: any) => ({\n            correlationKey: compiledCorrelation(nsRow),\n            parentContext: null,\n          }),\n        })\n      }\n\n      // Replace includes entry in select with a null placeholder\n      replaceIncludesInSelect(query.select!, key)\n    }\n  }\n\n  if (query.distinct && !query.fnSelect && !query.select) {\n    throw new DistinctRequiresSelectError()\n  }\n\n  if (query.fnSelect && query.groupBy && query.groupBy.length > 0) {\n    throw new FnSelectWithGroupByError()\n  }\n\n  // Process the SELECT clause early - always create $selected\n  // This eliminates duplication and allows for DISTINCT implementation\n  if (query.fnSelect) {\n    // Handle functional select - apply the function to transform the row\n    pipeline = pipeline.pipe(\n      map(([key, namespacedRow]) => {\n        const selectResults = query.fnSelect!(namespacedRow)\n        return [\n          key,\n          {\n            ...namespacedRow,\n            $selected: selectResults,\n          },\n        ] as [string, typeof namespacedRow & { $selected: any }]\n      }),\n    )\n  } else if (query.select) {\n    pipeline = processSelect(pipeline, query.select, allInputs)\n  } else {\n    // If no SELECT clause, create $selected with the main table data\n    pipeline = pipeline.pipe(\n      map(([key, namespacedRow]) => {\n        const selectResults =\n          !query.join && !query.groupBy\n            ? namespacedRow[mainSource]\n            : namespacedRow\n\n        return [\n          key,\n          {\n            ...namespacedRow,\n            $selected: selectResults,\n          },\n        ] as [string, typeof namespacedRow & { $selected: any }]\n      }),\n    )\n  }\n\n  // Tag $selected with routing metadata for includes.\n  // This lets collection-config-builder extract routing info (correlationKey + parentContext)\n  // from parent results without depending on the user's select.\n  if (includesRoutingFns.length > 0) {\n    pipeline = pipeline.pipe(\n      map(([key, namespacedRow]: any) => {\n        const routing: Record<\n          string,\n          { correlationKey: unknown; parentContext: Record<string, any> | null }\n        > = {}\n        for (const { fieldName, getRouting } of includesRoutingFns) {\n          routing[fieldName] = getRouting(namespacedRow)\n        }\n        namespacedRow.$selected[INCLUDES_ROUTING] = routing\n        return [key, namespacedRow]\n      }),\n    )\n  }\n\n  // Process the GROUP BY clause if it exists.\n  // When in includes mode (parentKeyStream), pass mainSource so that groupBy\n  // preserves __correlationKey for per-parent aggregation.\n  const groupByMainSource = parentKeyStream ? mainSource : undefined\n  if (query.groupBy && query.groupBy.length > 0) {\n    pipeline = processGroupBy(\n      pipeline,\n      query.groupBy,\n      query.having,\n      query.select,\n      query.fnHaving,\n      mainCollectionId,\n      groupByMainSource,\n    )\n  } else if (query.select) {\n    // Check if SELECT contains aggregates but no GROUP BY (implicit single-group aggregation)\n    const hasAggregates = Object.values(query.select).some(\n      (expr) => expr.type === `agg` || containsAggregate(expr),\n    )\n    if (hasAggregates) {\n      // Handle implicit single-group aggregation\n      pipeline = processGroupBy(\n        pipeline,\n        [], // Empty group by means single group\n        query.having,\n        query.select,\n        query.fnHaving,\n        mainCollectionId,\n        groupByMainSource,\n      )\n    }\n  }\n\n  // Process the HAVING clause if it exists (only applies after GROUP BY)\n  if (query.having && (!query.groupBy || query.groupBy.length === 0)) {\n    // Check if we have aggregates in SELECT that would trigger implicit grouping\n    const hasAggregates = query.select\n      ? Object.values(query.select).some((expr) => expr.type === `agg`)\n      : false\n\n    if (!hasAggregates) {\n      throw new HavingRequiresGroupByError()\n    }\n  }\n\n  // Process functional HAVING clauses outside of GROUP BY (treat as additional WHERE filters)\n  if (\n    query.fnHaving &&\n    query.fnHaving.length > 0 &&\n    (!query.groupBy || query.groupBy.length === 0)\n  ) {\n    // If there's no GROUP BY but there are fnHaving clauses, apply them as filters\n    for (const fnHaving of query.fnHaving) {\n      pipeline = pipeline.pipe(\n        filter(([_key, namespacedRow]) => {\n          return fnHaving(namespacedRow)\n        }),\n      )\n    }\n  }\n\n  // Process the DISTINCT clause if it exists\n  if (query.distinct) {\n    pipeline = pipeline.pipe(distinct(([_key, row]) => row.$selected))\n  }\n\n  // Process orderBy parameter if it exists\n  if (query.orderBy && query.orderBy.length > 0) {\n    // When in includes mode with limit/offset, use grouped ordering so that\n    // the limit is applied per parent (per correlation key), not globally.\n    const includesGroupKeyFn =\n      parentKeyStream &&\n      (query.limit !== undefined || query.offset !== undefined)\n        ? (_key: unknown, row: unknown) => {\n            const correlationKey = (row as any)?.[mainSource]?.__correlationKey\n            const parentContext = (row as any)?.__parentContext\n            if (parentContext != null) {\n              return JSON.stringify([correlationKey, parentContext])\n            }\n            return correlationKey\n          }\n        : undefined\n\n    const orderedPipeline = processOrderBy(\n      rawQuery,\n      pipeline,\n      query.orderBy,\n      query.select || {},\n      collections[mainCollectionId]!,\n      optimizableOrderByCollections,\n      setWindowFn,\n      query.limit,\n      query.offset,\n      includesGroupKeyFn,\n    )\n\n    // Final step: extract the $selected and include orderBy index\n    const resultPipeline: ResultStream = orderedPipeline.pipe(\n      map(([key, [row, orderByIndex]]) => {\n        // Extract the final results from $selected and include orderBy index\n        const raw = (row as any).$selected\n        const finalResults = attachVirtualPropsToSelected(\n          unwrapValue(raw),\n          row as Record<string, any>,\n        )\n        // When in includes mode, embed the correlation key and parentContext\n        if (parentKeyStream) {\n          const correlationKey = (row as any)[mainSource]?.__correlationKey\n          const parentContext = (row as any).__parentContext ?? null\n          // Strip internal routing properties that may leak via spread selects\n          delete finalResults.__correlationKey\n          delete finalResults.__parentContext\n          return [\n            key,\n            [finalResults, orderByIndex, correlationKey, parentContext],\n          ] as any\n        }\n        return [key, [finalResults, orderByIndex]] as [unknown, [any, string]]\n      }),\n    ) as ResultStream\n\n    const result = resultPipeline\n    // Cache the result before returning (use original query as key)\n    const compilationResult: CompilationResult = {\n      collectionId: mainCollectionId,\n      pipeline: result,\n      sourceWhereClauses,\n      aliasToCollectionId,\n      aliasRemapping,\n      includes: includesResults.length > 0 ? includesResults : undefined,\n    }\n    cache.set(rawQuery, compilationResult)\n\n    return compilationResult\n  } else if (query.limit !== undefined || query.offset !== undefined) {\n    // If there's a limit or offset without orderBy, throw an error\n    throw new LimitOffsetRequireOrderByError()\n  }\n\n  // Final step: extract the $selected and return tuple format (no orderBy)\n  const resultPipeline: ResultStream = pipeline.pipe(\n    map(([key, row]) => {\n      // Extract the final results from $selected and return [key, [results, undefined]]\n      const raw = (row as any).$selected\n      const finalResults = attachVirtualPropsToSelected(\n        unwrapValue(raw),\n        row as Record<string, any>,\n      )\n      // When in includes mode, embed the correlation key and parentContext\n      if (parentKeyStream) {\n        const correlationKey = (row as any)[mainSource]?.__correlationKey\n        const parentContext = (row as any).__parentContext ?? null\n        // Strip internal routing properties that may leak via spread selects\n        delete finalResults.__correlationKey\n        delete finalResults.__parentContext\n        return [\n          key,\n          [finalResults, undefined, correlationKey, parentContext],\n        ] as any\n      }\n      return [key, [finalResults, undefined]] as [\n        unknown,\n        [any, string | undefined],\n      ]\n    }),\n  )\n\n  const result = resultPipeline\n  // Cache the result before returning (use original query as key)\n  const compilationResult: CompilationResult = {\n    collectionId: mainCollectionId,\n    pipeline: result,\n    sourceWhereClauses,\n    aliasToCollectionId,\n    aliasRemapping,\n    includes: includesResults.length > 0 ? includesResults : undefined,\n  }\n  cache.set(rawQuery, compilationResult)\n\n  return compilationResult\n}\n\n/**\n * Collects aliases used for DIRECT collection references (not subqueries).\n * Used to validate that subqueries don't reuse parent query collection aliases.\n * Only direct CollectionRef aliases matter - QueryRef aliases don't cause conflicts.\n */\nfunction collectDirectCollectionAliases(query: QueryIR): Set<string> {\n  const aliases = new Set<string>()\n\n  // Collect FROM alias only if it's a direct collection reference\n  if (query.from.type === `collectionRef`) {\n    aliases.add(query.from.alias)\n  }\n\n  // Collect JOIN aliases only for direct collection references\n  if (query.join) {\n    for (const joinClause of query.join) {\n      if (joinClause.from.type === `collectionRef`) {\n        aliases.add(joinClause.from.alias)\n      }\n    }\n  }\n\n  return aliases\n}\n\n/**\n * Validates the structure of a query and its subqueries.\n * Checks that subqueries don't reuse collection aliases from parent queries.\n * This must be called on the RAW query before optimization.\n */\nfunction validateQueryStructure(\n  query: QueryIR,\n  parentCollectionAliases: Set<string> = new Set(),\n): void {\n  // Collect direct collection aliases from this query level\n  const currentLevelAliases = collectDirectCollectionAliases(query)\n\n  // Check if any current alias conflicts with parent aliases\n  for (const alias of currentLevelAliases) {\n    if (parentCollectionAliases.has(alias)) {\n      throw new DuplicateAliasInSubqueryError(\n        alias,\n        Array.from(parentCollectionAliases),\n      )\n    }\n  }\n\n  // Combine parent and current aliases for checking nested subqueries\n  const combinedAliases = new Set([\n    ...parentCollectionAliases,\n    ...currentLevelAliases,\n  ])\n\n  // Recursively validate FROM subquery\n  if (query.from.type === `queryRef`) {\n    validateQueryStructure(query.from.query, combinedAliases)\n  }\n\n  // Recursively validate JOIN subqueries\n  if (query.join) {\n    for (const joinClause of query.join) {\n      if (joinClause.from.type === `queryRef`) {\n        validateQueryStructure(joinClause.from.query, combinedAliases)\n      }\n    }\n  }\n}\n\n/**\n * Processes the FROM clause, handling direct collection references and subqueries.\n * Populates `aliasToCollectionId` and `aliasRemapping` for per-alias subscription tracking.\n */\nfunction processFrom(\n  from: CollectionRef | QueryRef,\n  allInputs: Record<string, KeyedStream>,\n  collections: Record<string, Collection>,\n  subscriptions: Record<string, CollectionSubscription>,\n  callbacks: Record<string, LazyCollectionCallbacks>,\n  lazySources: Set<string>,\n  optimizableOrderByCollections: Record<string, OrderByOptimizationInfo>,\n  setWindowFn: (windowFn: (options: WindowOptions) => void) => void,\n  cache: QueryCache,\n  queryMapping: QueryMapping,\n  aliasToCollectionId: Record<string, string>,\n  aliasRemapping: Record<string, string>,\n  sourceWhereClauses: Map<string, BasicExpression<boolean>>,\n): { alias: string; input: KeyedStream; collectionId: string } {\n  switch (from.type) {\n    case `collectionRef`: {\n      const input = allInputs[from.alias]\n      if (!input) {\n        throw new CollectionInputNotFoundError(\n          from.alias,\n          from.collection.id,\n          Object.keys(allInputs),\n        )\n      }\n      aliasToCollectionId[from.alias] = from.collection.id\n      return { alias: from.alias, input, collectionId: from.collection.id }\n    }\n    case `queryRef`: {\n      // Find the original query for caching purposes\n      const originalQuery = queryMapping.get(from.query) || from.query\n\n      // Recursively compile the sub-query with cache\n      const subQueryResult = compileQuery(\n        originalQuery,\n        allInputs,\n        collections,\n        subscriptions,\n        callbacks,\n        lazySources,\n        optimizableOrderByCollections,\n        setWindowFn,\n        cache,\n        queryMapping,\n      )\n\n      // Pull up alias mappings from subquery to parent scope.\n      // This includes both the innermost alias-to-collection mappings AND\n      // any existing remappings from nested subquery levels.\n      Object.assign(aliasToCollectionId, subQueryResult.aliasToCollectionId)\n      Object.assign(aliasRemapping, subQueryResult.aliasRemapping)\n\n      // Pull up source WHERE clauses from subquery to parent scope.\n      // This enables loadSubset to receive the correct where clauses for subquery collections.\n      //\n      // IMPORTANT: Skip pull-up for optimizer-created subqueries. These are detected when:\n      // 1. The outer alias (from.alias) matches the inner alias (from.query.from.alias)\n      // 2. The subquery was found in queryMapping (it's a user-defined subquery, not optimizer-created)\n      //\n      // For optimizer-created subqueries, the parent already has the sourceWhereClauses\n      // extracted from the original raw query, so pulling up would be redundant.\n      // More importantly, pulling up for optimizer-created subqueries can cause issues\n      // when the optimizer has restructured the query.\n      const isUserDefinedSubquery = queryMapping.has(from.query)\n      const subqueryFromAlias = from.query.from.alias\n      const isOptimizerCreated =\n        !isUserDefinedSubquery && from.alias === subqueryFromAlias\n\n      if (!isOptimizerCreated) {\n        for (const [alias, whereClause] of subQueryResult.sourceWhereClauses) {\n          sourceWhereClauses.set(alias, whereClause)\n        }\n      }\n\n      // Create a FLATTENED remapping from outer alias to innermost alias.\n      // For nested subqueries, this ensures one-hop lookups (not recursive chains).\n      //\n      // Example with 3-level nesting:\n      //   Inner:  .from({ user: usersCollection })\n      //   Middle: .from({ activeUser: innerSubquery })     → creates: activeUser → user\n      //   Outer:  .from({ author: middleSubquery })        → creates: author → user (not author → activeUser)\n      //\n      // The key insight: We search through the PULLED-UP aliasToCollectionId (which contains\n      // the innermost 'user' alias), so we always map directly to the deepest level.\n      // This means aliasRemapping[alias] is always a single lookup, never recursive.\n      // Needed for subscription resolution during lazy loading.\n      const innerAlias = Object.keys(subQueryResult.aliasToCollectionId).find(\n        (alias) =>\n          subQueryResult.aliasToCollectionId[alias] ===\n          subQueryResult.collectionId,\n      )\n      if (innerAlias && innerAlias !== from.alias) {\n        aliasRemapping[from.alias] = innerAlias\n      }\n\n      // Extract the pipeline from the compilation result\n      const subQueryInput = subQueryResult.pipeline\n\n      // Subqueries may return [key, [value, orderByIndex]] (with ORDER BY) or [key, value] (without ORDER BY)\n      // We need to extract just the value for use in parent queries\n      const extractedInput = subQueryInput.pipe(\n        map((data: any) => {\n          const [key, [value, _orderByIndex]] = data\n          // Unwrap Value expressions that might have leaked through as the entire row\n          const unwrapped = unwrapValue(value)\n          return [key, unwrapped] as [unknown, any]\n        }),\n      )\n\n      return {\n        alias: from.alias,\n        input: extractedInput,\n        collectionId: subQueryResult.collectionId,\n      }\n    }\n    default:\n      throw new UnsupportedFromTypeError((from as any).type)\n  }\n}\n\n// Helper to check if a value is a Value expression\nfunction isValue(raw: any): boolean {\n  return (\n    raw instanceof ValClass ||\n    (raw && typeof raw === `object` && `type` in raw && raw.type === `val`)\n  )\n}\n\n// Helper to unwrap a Value expression or return the value itself\nfunction unwrapValue(value: any): any {\n  return isValue(value) ? value.value : value\n}\n\nfunction attachVirtualPropsToSelected(\n  selected: any,\n  row: Record<string, any>,\n): any {\n  if (!selected || typeof selected !== `object`) {\n    return selected\n  }\n\n  let needsMerge = false\n  for (const prop of VIRTUAL_PROP_NAMES) {\n    if (selected[prop] == null && prop in row) {\n      needsMerge = true\n      break\n    }\n  }\n\n  if (!needsMerge) {\n    return selected\n  }\n\n  for (const prop of VIRTUAL_PROP_NAMES) {\n    if (selected[prop] == null && prop in row) {\n      selected[prop] = row[prop]\n    }\n  }\n\n  return selected\n}\n\n/**\n * Recursively maps optimized subqueries to their original queries for proper caching.\n * This ensures that when we encounter the same QueryRef object in different contexts,\n * we can find the original query to check the cache.\n */\nfunction mapNestedQueries(\n  optimizedQuery: QueryIR,\n  originalQuery: QueryIR,\n  queryMapping: QueryMapping,\n): void {\n  // Map the FROM clause if it's a QueryRef\n  if (\n    optimizedQuery.from.type === `queryRef` &&\n    originalQuery.from.type === `queryRef`\n  ) {\n    queryMapping.set(optimizedQuery.from.query, originalQuery.from.query)\n    // Recursively map nested queries\n    mapNestedQueries(\n      optimizedQuery.from.query,\n      originalQuery.from.query,\n      queryMapping,\n    )\n  }\n\n  // Map JOIN clauses if they exist\n  if (optimizedQuery.join && originalQuery.join) {\n    for (\n      let i = 0;\n      i < optimizedQuery.join.length && i < originalQuery.join.length;\n      i++\n    ) {\n      const optimizedJoin = optimizedQuery.join[i]!\n      const originalJoin = originalQuery.join[i]!\n\n      if (\n        optimizedJoin.from.type === `queryRef` &&\n        originalJoin.from.type === `queryRef`\n      ) {\n        queryMapping.set(optimizedJoin.from.query, originalJoin.from.query)\n        // Recursively map nested queries in joins\n        mapNestedQueries(\n          optimizedJoin.from.query,\n          originalJoin.from.query,\n          queryMapping,\n        )\n      }\n    }\n  }\n}\n\nfunction getRefFromAlias(\n  query: QueryIR,\n  alias: string,\n): CollectionRef | QueryRef | void {\n  if (query.from.alias === alias) {\n    return query.from\n  }\n\n  for (const join of query.join || []) {\n    if (join.from.alias === alias) {\n      return join.from\n    }\n  }\n}\n\n/**\n * Follows the given reference in a query\n * until its finds the root field the reference points to.\n * @returns The collection, its alias, and the path to the root field in this collection\n */\nexport function followRef(\n  query: QueryIR,\n  ref: PropRef<any>,\n  collection: Collection,\n): { collection: Collection; path: Array<string> } | void {\n  if (ref.path.length === 0) {\n    return\n  }\n\n  if (ref.path.length === 1) {\n    // This field should be part of this collection\n    const field = ref.path[0]!\n    // is it part of the select clause?\n    if (query.select) {\n      const selectedField = query.select[field]\n      if (selectedField && selectedField.type === `ref`) {\n        return followRef(query, selectedField, collection)\n      }\n    }\n\n    // Either this field is not part of the select clause\n    // and thus it must be part of the collection itself\n    // or it is part of the select but is not a reference\n    // so we can stop here and don't have to follow it\n    return { collection, path: [field] }\n  }\n\n  if (ref.path.length > 1) {\n    // This is a nested field\n    const [alias, ...rest] = ref.path\n    const aliasRef = getRefFromAlias(query, alias!)\n    if (!aliasRef) {\n      return\n    }\n\n    if (aliasRef.type === `queryRef`) {\n      return followRef(aliasRef.query, new PropRef(rest), collection)\n    } else {\n      // This is a reference to a collection\n      // we can't follow it further\n      // so the field must be on the collection itself\n      return { collection: aliasRef.collection, path: rest }\n    }\n  }\n}\n\n/**\n * Walks a Select object to find IncludesSubquery entries at the top level.\n * Throws if an IncludesSubquery is found nested inside a sub-object, since\n * the compiler only supports includes at the top level of a select.\n */\nfunction extractIncludesFromSelect(\n  select: Record<string, any>,\n): Array<{ key: string; subquery: IncludesSubquery }> {\n  const results: Array<{ key: string; subquery: IncludesSubquery }> = []\n  for (const [key, value] of Object.entries(select)) {\n    if (key.startsWith(`__SPREAD_SENTINEL__`)) continue\n    if (value instanceof IncludesSubquery) {\n      results.push({ key, subquery: value })\n    } else if (isNestedSelectObject(value)) {\n      // Check nested objects for IncludesSubquery — not supported yet\n      assertNoNestedIncludes(value, key)\n    }\n  }\n  return results\n}\n\n/** Check if a value is a nested plain object in a select (not an IR expression node) */\nfunction isNestedSelectObject(value: any): value is Record<string, any> {\n  return (\n    value != null &&\n    typeof value === `object` &&\n    !Array.isArray(value) &&\n    typeof value.type !== `string`\n  )\n}\n\nfunction assertNoNestedIncludes(\n  obj: Record<string, any>,\n  parentPath: string,\n): void {\n  for (const [key, value] of Object.entries(obj)) {\n    if (key.startsWith(`__SPREAD_SENTINEL__`)) continue\n    if (value instanceof IncludesSubquery) {\n      throw new Error(\n        `Includes subqueries must be at the top level of select(). ` +\n          `Found nested includes at \"${parentPath}.${key}\".`,\n      )\n    }\n    if (isNestedSelectObject(value)) {\n      assertNoNestedIncludes(value, `${parentPath}.${key}`)\n    }\n  }\n}\n\n/**\n * Replaces an IncludesSubquery entry in the select object with a null Value placeholder.\n * This ensures processSelect() doesn't encounter it.\n */\nfunction replaceIncludesInSelect(\n  select: Record<string, any>,\n  key: string,\n): void {\n  select[key] = new ValClass(null)\n}\n\n/**\n * Gets a nested value from an object by path segments.\n * For v1 with single-level correlation fields (e.g., `projectId`), it's just `obj[path[0]]`.\n */\nfunction getNestedValue(obj: any, path: Array<string>): any {\n  let value = obj\n  for (const segment of path) {\n    if (value == null) return value\n    value = value[segment]\n  }\n  return value\n}\n\nexport type CompileQueryFn = typeof compileQuery\n"],"names":["optimizeQuery","map","joinOperator","filter","processJoins","getWhereExpression","compileExpression","toBooleanPredicate","reduce","DistinctRequiresSelectError","FnSelectWithGroupByError","processSelect","processGroupBy","containsAggregate","HavingRequiresGroupByError","distinct","processOrderBy","resultPipeline","result","compilationResult","LimitOffsetRequireOrderByError","DuplicateAliasInSubqueryError","CollectionInputNotFoundError","UnsupportedFromTypeError","ValClass","VIRTUAL_PROP_NAMES","select","IncludesSubquery"],"mappings":"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"}