UNPKG

@tanstack/db

Version:

A reactive client store for building super fast apps on sync

142 lines (141 loc) 4.72 kB
"use strict"; Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" }); const refProxy = require("./query/builder/ref-proxy.cjs"); const evaluators = require("./query/compiler/evaluators.cjs"); const indexOptimization = require("./utils/index-optimization.cjs"); function currentStateAsChanges(collection, options = {}) { const collectFilteredResults = (filterFn) => { const result = []; for (const [key, value] of collection.entries()) { if ((filterFn == null ? void 0 : filterFn(value)) ?? true) { result.push({ type: `insert`, key, value }); } } return result; }; if (!options.where && !options.whereExpression) { return collectFilteredResults(); } try { let expression; if (options.whereExpression) { expression = options.whereExpression; } else if (options.where) { const singleRowRefProxy = refProxy.createSingleRowRefProxy(); const whereExpression = options.where(singleRowRefProxy); expression = refProxy.toExpression(whereExpression); } else { return []; } const optimizationResult = indexOptimization.optimizeExpressionWithIndexes( expression, collection.indexes ); if (optimizationResult.canOptimize) { const result = []; for (const key of optimizationResult.matchingKeys) { const value = collection.get(key); if (value !== void 0) { result.push({ type: `insert`, key, value }); } } return result; } else { const filterFn = options.where ? createFilterFunction(options.where) : createFilterFunctionFromExpression(expression); return collectFilteredResults(filterFn); } } catch (error) { console.warn( `Error processing where clause, falling back to full scan:`, error ); const filterFn = options.where ? createFilterFunction(options.where) : createFilterFunctionFromExpression(options.whereExpression); return collectFilteredResults(filterFn); } } function createFilterFunction(whereCallback) { return (item) => { try { const singleRowRefProxy = refProxy.createSingleRowRefProxy(); const whereExpression = whereCallback(singleRowRefProxy); const expression = refProxy.toExpression(whereExpression); const evaluator = evaluators.compileSingleRowExpression(expression); const result = evaluator(item); return result; } catch { try { const simpleProxy = new Proxy(item, { get(target, prop) { return target[prop]; } }); const result = whereCallback(simpleProxy); return result; } catch { return false; } } }; } function createFilterFunctionFromExpression(expression) { return (item) => { try { const evaluator = evaluators.compileSingleRowExpression(expression); const result = evaluator(item); return Boolean(result); } catch { return false; } }; } function createFilteredCallback(originalCallback, options) { const filterFn = options.whereExpression ? createFilterFunctionFromExpression(options.whereExpression) : createFilterFunction(options.where); return (changes) => { const filteredChanges = []; for (const change of changes) { if (change.type === `insert`) { if (filterFn(change.value)) { filteredChanges.push(change); } } else if (change.type === `update`) { const newValueMatches = filterFn(change.value); const oldValueMatches = change.previousValue ? filterFn(change.previousValue) : false; if (newValueMatches && oldValueMatches) { filteredChanges.push(change); } else if (newValueMatches && !oldValueMatches) { filteredChanges.push({ ...change, type: `insert` }); } else if (!newValueMatches && oldValueMatches) { filteredChanges.push({ ...change, type: `delete`, value: change.previousValue // Use the previous value for the delete }); } } else { if (filterFn(change.value)) { filteredChanges.push(change); } } } if (filteredChanges.length > 0 || changes.length === 0) { originalCallback(filteredChanges); } }; } exports.createFilterFunction = createFilterFunction; exports.createFilterFunctionFromExpression = createFilterFunctionFromExpression; exports.createFilteredCallback = createFilteredCallback; exports.currentStateAsChanges = currentStateAsChanges; //# sourceMappingURL=change-events.cjs.map