@tanstack/optimistic
Version:
Core optimistic updates library
95 lines (94 loc) • 2.79 kB
JavaScript
import { map, filter } from "@electric-sql/d2ts";
import { evaluateConditionOnNestedRow } from "./evaluators.js";
import { processJoinClause } from "./joins.js";
import { processGroupBy } from "./group-by.js";
import { processOrderBy } from "./order-by.js";
import { processKeyBy } from "./key-by.js";
import { processSelect } from "./select.js";
function compileQueryPipeline(query, inputs) {
const allInputs = { ...inputs };
if (query.with && query.with.length > 0) {
for (const withQuery of query.with) {
if (!withQuery.as) {
throw new Error(`WITH query must have an "as" property`);
}
if (withQuery.keyBy !== void 0) {
throw new Error(`WITH query cannot have a "keyBy" property`);
}
if (allInputs[withQuery.as]) {
throw new Error(`CTE with name "${withQuery.as}" already exists`);
}
const withQueryWithoutWith = { ...withQuery, with: void 0 };
const compiledWithQuery = compileQueryPipeline(
withQueryWithoutWith,
allInputs
);
allInputs[withQuery.as] = compiledWithQuery;
}
}
const tables = {};
const mainTableAlias = query.as || query.from;
const input = allInputs[query.from];
if (!input) {
throw new Error(`Input for table "${query.from}" not found in inputs map`);
}
tables[mainTableAlias] = input;
let pipeline = input.pipe(
map((row) => {
return { [mainTableAlias]: row };
})
);
if (query.join) {
pipeline = processJoinClause(
pipeline,
query,
tables,
mainTableAlias,
allInputs
);
}
if (query.where) {
pipeline = pipeline.pipe(
filter((nestedRow) => {
const result = evaluateConditionOnNestedRow(
nestedRow,
query.where,
mainTableAlias
);
return result;
})
);
}
if (query.groupBy) {
pipeline = processGroupBy(pipeline, query, mainTableAlias);
}
if (query.having) {
pipeline = pipeline.pipe(
filter((row) => {
const result = evaluateConditionOnNestedRow(
{ [mainTableAlias]: row, ...row },
query.having,
mainTableAlias
);
return result;
})
);
}
pipeline = processSelect(pipeline, query, mainTableAlias, allInputs);
let resultPipeline = pipeline;
if (query.keyBy) {
resultPipeline = processKeyBy(resultPipeline, query);
}
if (query.orderBy) {
resultPipeline = processOrderBy(resultPipeline, query, mainTableAlias);
} else if (query.limit !== void 0 || query.offset !== void 0) {
throw new Error(
`LIMIT and OFFSET require an ORDER BY clause to ensure deterministic results`
);
}
return resultPipeline;
}
export {
compileQueryPipeline
};
//# sourceMappingURL=pipeline-compiler.js.map