@tanstack/optimistic
Version:
Core optimistic updates library
92 lines (91 loc) • 2.91 kB
JavaScript
;
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
const d2ts = require("@electric-sql/d2ts");
const extractors = require("./extractors.cjs");
const utils = require("./utils.cjs");
const { sum, count, avg, min, max, median, mode } = d2ts.groupByOperators;
function processGroupBy(pipeline, query, mainTableAlias) {
const groupByColumns = Array.isArray(query.groupBy) ? query.groupBy : [query.groupBy];
const keyExtractor = (nestedRow) => {
const key = {};
for (const column of groupByColumns) {
if (typeof column === `string` && column.startsWith(`@`)) {
const columnRef = column.substring(1);
const columnName = columnRef.includes(`.`) ? columnRef.split(`.`)[1] : columnRef;
key[columnName] = extractors.extractValueFromNestedRow(
nestedRow,
columnRef,
mainTableAlias
);
}
}
return key;
};
const aggregates = {};
for (const item of query.select) {
if (typeof item === `object`) {
for (const [alias, expr] of Object.entries(item)) {
if (typeof expr === `object` && utils.isAggregateFunctionCall(expr)) {
const functionName = Object.keys(expr)[0];
const columnRef = expr[functionName];
aggregates[alias] = getAggregateFunction(
functionName,
columnRef,
mainTableAlias
);
}
}
}
}
if (Object.keys(aggregates).length > 0) {
pipeline = pipeline.pipe(
d2ts.groupBy(keyExtractor, aggregates),
// Convert KeyValue<string, ResultType> to Record<string, unknown>
d2ts.map(([_key, value]) => {
return value;
})
);
}
return pipeline;
}
function getAggregateFunction(functionName, columnRef, mainTableAlias) {
const valueExtractor = (nestedRow) => {
let value;
if (typeof columnRef === `string` && columnRef.startsWith(`@`)) {
value = extractors.extractValueFromNestedRow(
nestedRow,
columnRef.substring(1),
mainTableAlias
);
} else {
value = extractors.evaluateOperandOnNestedRow(
nestedRow,
columnRef,
mainTableAlias
);
}
return typeof value === `number` ? value : 0;
};
switch (functionName.toUpperCase()) {
case `SUM`:
return sum(valueExtractor);
case `COUNT`:
return count();
// count() doesn't need a value extractor
case `AVG`:
return avg(valueExtractor);
case `MIN`:
return min(valueExtractor);
case `MAX`:
return max(valueExtractor);
case `MEDIAN`:
return median(valueExtractor);
case `MODE`:
return mode(valueExtractor);
default:
throw new Error(`Unsupported aggregate function: ${functionName}`);
}
}
exports.getAggregateFunction = getAggregateFunction;
exports.processGroupBy = processGroupBy;
//# sourceMappingURL=group-by.cjs.map