UNPKG

@tanstack/db

Version:

A reactive client store for building super fast apps on sync

258 lines (257 loc) 6.08 kB
import { Func, Aggregate } from "../ir.js"; import { toExpression, isRefProxy } from "./ref-proxy.js"; function eq(left, right) { return new Func(`eq`, [toExpression(left), toExpression(right)]); } function gt(left, right) { return new Func(`gt`, [toExpression(left), toExpression(right)]); } function gte(left, right) { return new Func(`gte`, [toExpression(left), toExpression(right)]); } function lt(left, right) { return new Func(`lt`, [toExpression(left), toExpression(right)]); } function lte(left, right) { return new Func(`lte`, [toExpression(left), toExpression(right)]); } function and(left, right, ...rest) { const allArgs = [left, right, ...rest]; return new Func( `and`, allArgs.map((arg) => toExpression(arg)) ); } function or(left, right, ...rest) { const allArgs = [left, right, ...rest]; return new Func( `or`, allArgs.map((arg) => toExpression(arg)) ); } function not(value) { return new Func(`not`, [toExpression(value)]); } function isUndefined(value) { return new Func(`isUndefined`, [toExpression(value)]); } function isNull(value) { return new Func(`isNull`, [toExpression(value)]); } function inArray(value, array) { return new Func(`in`, [toExpression(value), toExpression(array)]); } function like(left, right) { return new Func(`like`, [toExpression(left), toExpression(right)]); } function ilike(left, right) { return new Func(`ilike`, [toExpression(left), toExpression(right)]); } function upper(arg) { return new Func(`upper`, [toExpression(arg)]); } function lower(arg) { return new Func(`lower`, [toExpression(arg)]); } function length(arg) { return new Func(`length`, [toExpression(arg)]); } function concat(...args) { const toArrayArg = args.find( (arg) => arg instanceof ToArrayWrapper ); if (toArrayArg) { if (args.length !== 1) { throw new Error( `concat(toArray(...)) currently supports only a single toArray(...) argument` ); } return new ConcatToArrayWrapper(toArrayArg.query); } return new Func( `concat`, args.map((arg) => toExpression(arg)) ); } function coalesce(...args) { return new Func( `coalesce`, args.map((arg) => toExpression(arg)) ); } function caseWhen(...args) { if (args.length < 2) { throw new Error(`caseWhen() requires at least two arguments`); } const pairCount = Math.floor(args.length / 2); for (let i = 0; i < pairCount; i++) { const condition = args[i * 2]; if (!isConditionValue(condition)) { throw new Error(`caseWhen() conditions must be expression-like values`); } } if (caseWhenHasOnlyExpressionValues(args)) { return new Func( `caseWhen`, args.map((arg) => toExpression(arg)) ); } return new CaseWhenWrapper(args); } function add(left, right) { return new Func(`add`, [ toExpression(left), toExpression(right) ]); } function count(arg) { return new Aggregate(`count`, [toExpression(arg)]); } function avg(arg) { return new Aggregate(`avg`, [toExpression(arg)]); } function sum(arg) { return new Aggregate(`sum`, [toExpression(arg)]); } function min(arg) { return new Aggregate(`min`, [toExpression(arg)]); } function max(arg) { return new Aggregate(`max`, [toExpression(arg)]); } const operators = [ // Comparison operators `eq`, `gt`, `gte`, `lt`, `lte`, `in`, `like`, `ilike`, // Logical operators `and`, `or`, `not`, // Null checking `isNull`, `isUndefined`, // String functions `upper`, `lower`, `length`, `concat`, // Numeric functions `add`, // Utility functions `coalesce`, `caseWhen`, // Aggregate functions `count`, `avg`, `sum`, `min`, `max` ]; class ToArrayWrapper { constructor(query) { this.query = query; this.__brand = `ToArrayWrapper`; } } class ConcatToArrayWrapper { constructor(query) { this.query = query; this.__brand = `ConcatToArrayWrapper`; } } class CaseWhenWrapper { constructor(args) { this.args = args; this.__brand = `CaseWhenWrapper`; } } class MaterializeWrapper { constructor(query) { this.query = query; this.__brand = `MaterializeWrapper`; } } function toArray(query) { return new ToArrayWrapper(query); } function caseWhenHasOnlyExpressionValues(args) { const valueIndexes = getCaseWhenValueIndexes(args.length); return valueIndexes.every((index) => isExpressionValue(args[index])); } function getCaseWhenValueIndexes(argCount) { const valueIndexes = []; const hasDefaultValue = argCount % 2 === 1; const pairCount = Math.floor(argCount / 2); for (let i = 0; i < pairCount; i++) { valueIndexes.push(i * 2 + 1); } if (hasDefaultValue) { valueIndexes.push(argCount - 1); } return valueIndexes; } function isExpressionValue(value) { if (isRefProxy(value)) return true; if (value instanceof Aggregate || value instanceof Func) return true; if (value == null) return true; if (typeof value === `string` || typeof value === `number` || typeof value === `boolean` || typeof value === `bigint`) { return true; } if (value instanceof Date || Array.isArray(value)) return true; if (typeof value === `object`) { const candidate = value; if ((candidate.type === `agg` || candidate.type === `func`) && typeof candidate.name === `string` && Array.isArray(candidate.args)) { return true; } if (candidate.type === `ref` && Array.isArray(candidate.path)) return true; if (candidate.type === `val` && `value` in candidate) return true; } return false; } function isConditionValue(value) { return isExpressionValue(value) && !Array.isArray(value); } function materialize(query) { return new MaterializeWrapper(query); } export { CaseWhenWrapper, ConcatToArrayWrapper, MaterializeWrapper, ToArrayWrapper, add, and, avg, caseWhen, coalesce, concat, count, eq, gt, gte, ilike, inArray, isNull, isUndefined, length, like, lower, lt, lte, materialize, max, min, not, operators, or, sum, toArray, upper }; //# sourceMappingURL=functions.js.map