UNPKG

vscroll

Version:
263 lines 9.34 kB
import { DefaultSize } from './defaultSize'; import { Direction } from '../../inputs/index'; var ItemCache = /** @class */ (function () { function ItemCache(item, saveData) { this.$index = item.$index; this.data = saveData ? item.data : null; this.size = item.size; } ItemCache.prototype.changeIndex = function (value) { this.$index = value; }; return ItemCache; }()); export { ItemCache }; var Cache = /** @class */ (function () { function Cache(_a, logger) { var itemSize = _a.itemSize, cacheData = _a.cacheData, cacheOnReload = _a.cacheOnReload, sizeStrategy = _a.sizeStrategy; this.itemSize = itemSize; this.saveData = cacheData; this.cacheOnReload = cacheOnReload; this.sizeStrategy = sizeStrategy; this.logger = logger; this.items = new Map(); this.defaultSize = new DefaultSize(itemSize, sizeStrategy); this.reset(true); } Cache.prototype.reset = function (force) { force = force || !this.cacheOnReload; if (force) { this.minIndex = +Infinity; this.maxIndex = -Infinity; this.items.clear(); } this.defaultSize.reset(force); }; Object.defineProperty(Cache.prototype, "size", { get: function () { return this.items.size; }, enumerable: false, configurable: true }); Cache.prototype.get = function (index) { return this.items.get(index); }; Cache.prototype.getSizeByIndex = function (index) { var item = this.get(index); return (item && item.size) || this.defaultSize.get(); }; Cache.prototype.getDefaultSize = function () { return this.defaultSize.get(); }; Cache.prototype.recalculateDefaultSize = function () { var _this = this; if (this.defaultSize.recalculate(this.size)) { this.logger.log(function () { return "default size has been updated: ".concat(_this.defaultSize.get()); }); return true; } return false; }; /** * Adds item to Set by $index, replaces existed item if $index matches. * Maintains min/max indexes and default item size. * * @param {Item<Data>} item A Buffer item to be cached, an objects with { $index, data, size } props. * @returns {ItemCache<Data>} Cached item. */ Cache.prototype.add = function (item) { var itemCache = this.get(item.$index); if (itemCache) { // adding item is already cached if (this.saveData) { itemCache.data = item.data; } if (itemCache.size !== item.size) { if (itemCache.size) { this.defaultSize.setExisted(itemCache.size, item.size); } else { this.defaultSize.setNew(item.size); } itemCache.size = item.size; } } else { itemCache = new ItemCache(item, this.saveData); this.items.set(item.$index, itemCache); this.defaultSize.setNew(item.size); } if (item.$index < this.minIndex) { this.minIndex = item.$index; } if (item.$index > this.maxIndex) { this.maxIndex = item.$index; } return itemCache; }; /** * Inserts items to Set, shifts $indexes of items that remain. * Replaces current Set with a new one with new regular $indexes. * Maintains min/max indexes. * * @param {Data[]} toInsert List of non-indexed items to be inserted. * @param {number} index The index before/after which the insertion is performed. * @param {Direction} direction Determines the direction of insertion. * @param {boolean} fixRight Defines indexes shifting strategy. * If false, indexes that are greater than the inserted ones are increased. * If true, indexes that are less than than the inserted ones are decreased. */ Cache.prototype.insertItems = function (toInsert, index, direction, fixRight) { var _this = this; var items = new Map(); var length = toInsert.length; var min = Infinity, max = -Infinity; var set = function (item) { items.set(item.$index, item); min = item.$index < min ? item.$index : min; max = item.$index > max ? item.$index : max; }; this.items.forEach(function (item) { var shift = 0; if (direction === Direction.backward) { if (item.$index < index && fixRight) { shift = -length; } else if (item.$index >= index && !fixRight) { shift = length; } } else if (direction === Direction.forward) { if (item.$index <= index && fixRight) { shift = -length; } else if (item.$index > index && !fixRight) { shift = length; } } if (shift) { item.changeIndex(item.$index + shift); } set(item); }); if (this.saveData) { // persist data with no sizes toInsert.forEach(function (data, i) { var $index = index + i - (fixRight ? length : 0) + (direction === Direction.forward ? 1 : 0); var item = new ItemCache({ $index: $index, data: data }, _this.saveData); set(item); }); } this.items = items; this.minIndex = min; this.maxIndex = max; }; /** * Removes items from Set, shifts $indexes of items that remain. * Replaces current Set with a new one with new regular $indexes. * Maintains min/max indexes and default item size. * * @param {number[]} toRemove List of indexes to be removed. * @param {boolean} fixRight Defines indexes shifting strategy. * If false, indexes that are greater than the removed ones will be decreased. * If true, indexes that are less than than the removed ones will be increased. */ Cache.prototype.removeItems = function (toRemove, fixRight) { var _this = this; var items = new Map(); var min = Infinity, max = -Infinity; this.items.forEach(function (item) { if (toRemove.some(function (index) { return index === item.$index; })) { if (item.size) { _this.defaultSize.setRemoved(item.size); } return; } var diff = fixRight ? toRemove.reduce(function (acc, index) { return acc + (item.$index < index ? 1 : 0); }, 0) : toRemove.reduce(function (acc, index) { return acc - (item.$index > index ? 1 : 0); }, 0); item.changeIndex(item.$index + diff); items.set(item.$index, item); min = item.$index < min ? item.$index : min; max = item.$index > max ? item.$index : max; }); this.items = items; this.minIndex = min; this.maxIndex = max; }; /** * Destructively updates Set based on subset (before-after) changes. * Replaces current Set with a new one with new regular $indexes. * Maintains min/max indexes. Maintains default item size on remove only. * * @param {ItemUpdate[]} before Initial subset of items to be replaced by "after". * Each element is an object with { $index, size, toRemove } props. Must be $index-incremental. * Items to be removed must have toRemove flag: before[].toRemove = true. * @param {Item<Data>[]} after Transformed subset that replaces "before". Must be $index-incremental. * Must contain at least 1 $index from "before" or be empty. * @param {boolean} fixRight This is to fix right indexes during subset collapsing. Acts only if "after" is empty. */ Cache.prototype.updateSubset = function (before, after, fixRight) { var _this = this; if (!this.size || !before.length) { return; } var minB = before[0].$index, maxB = before[before.length - 1].$index; var leftDiff, rightDiff; if (after.length) { var minA = after[0].$index, maxA = after[after.length - 1].$index; leftDiff = minA - minB; rightDiff = maxA - maxB; } else { leftDiff = fixRight ? maxB - minB + 1 : 0; rightDiff = fixRight ? 0 : minB - maxB - 1; } var items = new Map(); this.items.forEach(function (item) { if (item.$index < minB) { // items to the left of the subset item.changeIndex(item.$index + leftDiff); items.set(item.$index, item); return; } else if (item.$index > maxB) { // items to the right of the subset item.changeIndex(item.$index + rightDiff); items.set(item.$index, item); return; } }); after.forEach(function (item // subset items ) { return items.set(item.$index, new ItemCache(item, _this.saveData)); }); before // to maintain default size on remove .filter(function (item) { return item.toRemove; }) .forEach(function (item) { return _this.defaultSize.setRemoved(item.size); }); this.minIndex += leftDiff; this.maxIndex += rightDiff; this.items = items; }; /** * Shifts all indexes by some value. * Replaces current Set with a new one with new regular $indexes. * Maintains min/max indexes. * * @param {number} delta A shift value. */ Cache.prototype.shiftIndexes = function (delta) { var items = new Map(); var min = Infinity, max = -Infinity; this.items.forEach(function (item) { item.changeIndex(item.$index + delta); items.set(item.$index, item); min = item.$index < min ? item.$index : min; max = item.$index > max ? item.$index : max; }); this.items = items; this.minIndex = min; this.maxIndex = max; }; return Cache; }()); export { Cache }; //# sourceMappingURL=cache.js.map