UNPKG

@tanstack/db

Version:

A reactive client store for building super fast apps on sync

147 lines (146 loc) 4.51 kB
"use strict"; Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" }); const dbIvm = require("@tanstack/db-ivm"); const ir = require("../ir.cjs"); const evaluators = require("./evaluators.cjs"); function unwrapVal(input) { if (input instanceof ir.Value) return input.value; return input; } function processMerge(op, namespacedRow, selectResults) { const value = op.source(namespacedRow); if (value && typeof value === `object`) { let cursor = selectResults; const path = op.targetPath; if (path.length === 0) { for (const [k, v] of Object.entries(value)) { selectResults[k] = unwrapVal(v); } } else { for (let i = 0; i < path.length; i++) { const seg = path[i]; if (i === path.length - 1) { const dest = cursor[seg] ??= {}; if (typeof dest === `object`) { for (const [k, v] of Object.entries(value)) { dest[k] = unwrapVal(v); } } } else { const next = cursor[seg]; if (next == null || typeof next !== `object`) { cursor[seg] = {}; } cursor = cursor[seg]; } } } } } function processNonMergeOp(op, namespacedRow, selectResults) { const path = op.alias.split(`.`); if (path.length === 1) { selectResults[op.alias] = op.compiled(namespacedRow); } else { let cursor = selectResults; for (let i = 0; i < path.length - 1; i++) { const seg = path[i]; const next = cursor[seg]; if (next == null || typeof next !== `object`) { cursor[seg] = {}; } cursor = cursor[seg]; } cursor[path[path.length - 1]] = unwrapVal(op.compiled(namespacedRow)); } } function processRow([key, namespacedRow], ops) { const selectResults = {}; for (const op of ops) { if (op.kind === `merge`) { processMerge(op, namespacedRow, selectResults); } else { processNonMergeOp(op, namespacedRow, selectResults); } } return [ key, { ...namespacedRow, __select_results: selectResults } ]; } function processSelect(pipeline, select, _allInputs) { const ops = []; addFromObject([], select, ops); return pipeline.pipe(dbIvm.map((row) => processRow(row, ops))); } function isAggregateExpression(expr) { return expr.type === `agg`; } function isNestedSelectObject(obj) { return obj && typeof obj === `object` && !ir.isExpressionLike(obj); } function addFromObject(prefixPath, obj, ops) { for (const [key, value] of Object.entries(obj)) { if (key.startsWith(`__SPREAD_SENTINEL__`)) { const rest = key.slice(`__SPREAD_SENTINEL__`.length); const splitIndex = rest.lastIndexOf(`__`); const pathStr = splitIndex >= 0 ? rest.slice(0, splitIndex) : rest; const isRefExpr = value && typeof value === `object` && `type` in value && value.type === `ref`; if (pathStr.includes(`.`) || isRefExpr) { const targetPath = [...prefixPath]; const expr = isRefExpr ? value : new ir.PropRef(pathStr.split(`.`)); const compiled = evaluators.compileExpression(expr); ops.push({ kind: `merge`, targetPath, source: compiled }); } else { const tableAlias = pathStr; const targetPath = [...prefixPath]; ops.push({ kind: `merge`, targetPath, source: (row) => row[tableAlias] }); } continue; } const expression = value; if (isNestedSelectObject(expression)) { addFromObject([...prefixPath, key], expression, ops); continue; } if (isAggregateExpression(expression)) { ops.push({ kind: `field`, alias: [...prefixPath, key].join(`.`), compiled: () => null }); } else { if (expression === void 0 || !ir.isExpressionLike(expression)) { ops.push({ kind: `field`, alias: [...prefixPath, key].join(`.`), compiled: () => expression }); continue; } if (expression instanceof ir.Value) { const val = expression.value; ops.push({ kind: `field`, alias: [...prefixPath, key].join(`.`), compiled: () => val }); } else { ops.push({ kind: `field`, alias: [...prefixPath, key].join(`.`), compiled: evaluators.compileExpression(expression) }); } } } } exports.processSelect = processSelect; //# sourceMappingURL=select.cjs.map