( rawQuery: QueryIR, inputs: Record<string, KeyedStream>, collections: Record<string, Collection<any, any, any, any, any>>, subscriptions: Record<string, CollectionSubscription>, callbacks: Record<string, LazyCollectionCallbacks>, lazySources: Set<string>, optimizableOrderByCollections: Record<string, OrderByOptimizationInfo>, setWindowFn: (windowFn: (options: WindowOptions) => void) => void, cache: QueryCache = new WeakMap(), queryMapping: QueryMapping = new WeakMap(), // For includes: parent key stream to inner-join with this query's FROM parentKeyStream?: KeyedStream, childCorrelationField?: PropRef, )
| 160 | * @returns A CompilationResult with the pipeline, source WHERE clauses, and alias metadata |
| 161 | */ |
| 162 | export function compileQuery( |
| 163 | rawQuery: QueryIR, |
| 164 | inputs: Record<string, KeyedStream>, |
| 165 | collections: Record<string, Collection<any, any, any, any, any>>, |
| 166 | subscriptions: Record<string, CollectionSubscription>, |
| 167 | callbacks: Record<string, LazyCollectionCallbacks>, |
| 168 | lazySources: Set<string>, |
| 169 | optimizableOrderByCollections: Record<string, OrderByOptimizationInfo>, |
| 170 | setWindowFn: (windowFn: (options: WindowOptions) => void) => void, |
| 171 | cache: QueryCache = new WeakMap(), |
| 172 | queryMapping: QueryMapping = new WeakMap(), |
| 173 | // For includes: parent key stream to inner-join with this query's FROM |
| 174 | parentKeyStream?: KeyedStream, |
| 175 | childCorrelationField?: PropRef, |
| 176 | ): CompilationResult { |
| 177 | // Check if the original raw query has already been compiled |
| 178 | const cachedResult = cache.get(rawQuery) |
| 179 | if (cachedResult) { |
| 180 | return cachedResult |
| 181 | } |
| 182 | |
| 183 | // Validate the raw query BEFORE optimization to check user's original structure. |
| 184 | // This must happen before optimization because the optimizer may create internal |
| 185 | // subqueries (e.g., for predicate pushdown) that reuse aliases, which is fine. |
| 186 | validateQueryStructure(rawQuery) |
| 187 | |
| 188 | // Optimize the query before compilation |
| 189 | const { optimizedQuery, sourceWhereClauses } = optimizeQuery(rawQuery) |
| 190 | // Use a mutable binding so we can shallow-clone select before includes mutation |
| 191 | let query = optimizedQuery |
| 192 | |
| 193 | // Create mapping from optimized query to original for caching |
| 194 | queryMapping.set(query, rawQuery) |
| 195 | mapNestedQueries(query, rawQuery, queryMapping) |
| 196 | |
| 197 | // Create a copy of the inputs map to avoid modifying the original |
| 198 | const allInputs = { ...inputs } |
| 199 | |
| 200 | // Track alias to collection id relationships discovered during compilation. |
| 201 | // This includes all user-declared aliases plus inner aliases from subqueries. |
| 202 | const aliasToCollectionId: Record<string, string> = {} |
| 203 | |
| 204 | // Track alias remapping for subqueries (outer alias → inner alias) |
| 205 | // e.g., when .join({ activeUser: subquery }) where subquery uses .from({ user: collection }) |
| 206 | // we store: aliasRemapping['activeUser'] = 'user' |
| 207 | const aliasRemapping: Record<string, string> = {} |
| 208 | |
| 209 | // Create a map of source aliases to input streams. |
| 210 | // Inputs MUST be keyed by alias (e.g., `{ employee: input1, manager: input2 }`), |
| 211 | // not by collection ID. This enables per-alias subscriptions where different aliases |
| 212 | // of the same collection (e.g., self-joins) maintain independent filtered streams. |
| 213 | const sources: Record<string, KeyedStream> = {} |
| 214 | |
| 215 | // Process the FROM clause to get the source stream. |
| 216 | const { |
| 217 | alias: mainSource, |
| 218 | collectionId: mainCollectionId, |
| 219 | pipeline: initialPipeline, |
no test coverage detected