UNPKG

@tanstack/db

Version:

A reactive client store for building super fast apps on sync

112 lines (111 loc) 3.87 kB
"use strict"; Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" }); const predicateUtils = require("./predicate-utils.cjs"); class DeduplicatedLoadSubset { constructor(opts) { this.unlimitedWhere = void 0; this.hasLoadedAllData = false; this.limitedCalls = []; this.inflightCalls = []; this.generation = 0; this.loadSubset = (options) => { if (this.hasLoadedAllData) { this.onDeduplicate?.(options); return true; } if (this.unlimitedWhere !== void 0 && options.where !== void 0) { if (predicateUtils.isWhereSubset(options.where, this.unlimitedWhere)) { this.onDeduplicate?.(options); return true; } } if (options.limit !== void 0) { const alreadyLoaded = this.limitedCalls.some( (loaded) => predicateUtils.isPredicateSubset(options, loaded) ); if (alreadyLoaded) { this.onDeduplicate?.(options); return true; } } const matchingInflight = this.inflightCalls.find( (inflight) => predicateUtils.isPredicateSubset(options, inflight.options) ); if (matchingInflight !== void 0) { const prom = matchingInflight.promise; prom.then(() => this.onDeduplicate?.(options)).catch(); return prom; } const clonedOptions = cloneOptions(options); if (this.unlimitedWhere !== void 0 && options.limit === void 0) { clonedOptions.where = predicateUtils.minusWherePredicates(clonedOptions.where, this.unlimitedWhere) ?? clonedOptions.where; } const resultPromise = this._loadSubset(clonedOptions); if (resultPromise === true) { this.updateTracking(clonedOptions); return true; } else { const capturedGeneration = this.generation; const inflightEntry = { options: clonedOptions, // Store cloned options for subset matching promise: resultPromise.then((result) => { if (capturedGeneration === this.generation) { this.updateTracking(clonedOptions); } return result; }).finally(() => { const index = this.inflightCalls.indexOf(inflightEntry); if (index !== -1) { this.inflightCalls.splice(index, 1); } }) }; this.inflightCalls.push(inflightEntry); return inflightEntry.promise; } }; this._loadSubset = opts.loadSubset; this.onDeduplicate = opts.onDeduplicate; } /** * Reset all tracking state. * Clears the history of loaded predicates and in-flight calls. * Use this when you want to start fresh, for example after clearing the underlying data store. * * Note: Any in-flight requests will still complete, but they will not update the tracking * state after the reset. This prevents old requests from repopulating cleared state. */ reset() { this.unlimitedWhere = void 0; this.hasLoadedAllData = false; this.limitedCalls = []; this.inflightCalls = []; this.generation++; } updateTracking(options) { if (options.limit === void 0) { if (options.where === void 0) { this.hasLoadedAllData = true; this.unlimitedWhere = void 0; this.limitedCalls = []; this.inflightCalls = []; } else if (this.unlimitedWhere === void 0) { this.unlimitedWhere = options.where; } else { this.unlimitedWhere = predicateUtils.unionWherePredicates([ this.unlimitedWhere, options.where ]); } } else { this.limitedCalls.push(options); } } } function cloneOptions(options) { return { ...options }; } exports.DeduplicatedLoadSubset = DeduplicatedLoadSubset; exports.cloneOptions = cloneOptions; //# sourceMappingURL=subset-dedupe.cjs.map