UNPKG

@ablestack/rdo

Version:

A library to facilitate building and running graphs of Reactive Domain Objects - connecting JSON data sources to reactive client applications

123 lines 6.33 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.RdoKeyCollectionNWBase = void 0; const tslib_1 = require("tslib"); const lodash_1 = tslib_1.__importDefault(require("lodash")); const logger_1 = require("../../infrastructure/logger"); const rdo_collection_nw_base_1 = require("./rdo-collection-nw-base"); const logger = logger_1.Logger.make('RdoCollectionNWBase'); class RdoKeyCollectionNWBase extends rdo_collection_nw_base_1.RdoCollectionNWBase { constructor({ typeInfo, key, mutableNodeCache, wrappedParentRdoNode, wrappedSourceNode, defaultEqualityComparer, syncChildNode, matchingNodeOptions, globalNodeOptions, targetedOptionMatchersArray, eventEmitter, }) { super({ typeInfo, key, mutableNodeCache, wrappedParentRdoNode, wrappedSourceNode, defaultEqualityComparer, syncChildNode, matchingNodeOptions, globalNodeOptions, targetedOptionMatchersArray, eventEmitter }); } //------------------------------ // Protected //------------------------------ get views() { let mutableNodeCacheItem = this.mutableNodeCache.get({ sourceNodeInstancePath: this.wrappedSourceNode.sourceNodeInstancePath, dataKey: 'RdoIndexCollectionNWBase' }); if (!mutableNodeCacheItem) { mutableNodeCacheItem = { sourceArray: new Array(), sourceByKeyMap: new Map(), rdoByKeyMap: new Map() }; this.mutableNodeCache.set({ sourceNodeInstancePath: this.wrappedSourceNode.sourceNodeInstancePath, dataKey: 'RdoIndexCollectionNWBase', data: mutableNodeCacheItem }); } return mutableNodeCacheItem; } /** */ smartSync() { // // Setup let changed = false; const wrappedSourceNode = this.wrappedSourceNode; const last = { sourceArray: this.views.sourceArray, sourceByKeyMap: this.views.sourceByKeyMap, rdoByKeyMap: this.views.rdoByKeyMap, }; this.views.sourceArray = wrappedSourceNode.elements(); this.views.sourceByKeyMap = new Map(); this.views.rdoByKeyMap = new Map(); // // Loop and execute let indexOffset = 0; for (let i = 0; i < wrappedSourceNode.childElementCount(); i++) { // SETUP const nextSourceElement = this.views.sourceArray[i]; const index = i + indexOffset; const elementKey = wrappedSourceNode.makeCollectionKey(nextSourceElement, i); // Update maps if (this.views.sourceByKeyMap.has(elementKey)) continue; // If we have already seen the key, no need to add/update this.views.sourceByKeyMap.set(elementKey, nextSourceElement); // --------------------------- // New key - ADD // --------------------------- // If rdo not in previous, add if (!last.rdoByKeyMap.has(elementKey)) { // EXECUTE const newItem = this.makeRdoElement(nextSourceElement); // Tracking this.views.rdoByKeyMap.set(elementKey, newItem); indexOffset++; // Handle changed = this.handleAddElement({ addHandler: this.onAdd, index, collectionKey: elementKey, newItem, newSourceElement: nextSourceElement }) && changed; // If index is in previous source array } else { const lastSourceElement = last.sourceByKeyMap.get(elementKey); const origItem = last.rdoByKeyMap.get(elementKey); if (this.equalityComparer(lastSourceElement, nextSourceElement)) { // No change, no patch needed. Just update view const origItem = last.rdoByKeyMap.get(elementKey); this.views.rdoByKeyMap.set(elementKey, origItem); } else { // --------------------------- // REPLACE or UPDATE // --------------------------- // Tracking this.views.rdoByKeyMap.set(elementKey, origItem); // Handle const result = this.handleReplaceOrUpdate({ replaceHandler: ({ index, key, origItem, newItem }) => { this.views.rdoByKeyMap.set(key, origItem); return this.onReplace({ index, key, origItem, newItem }); }, index, collectionKey: elementKey, lastElementKey: elementKey, nextElementKey: elementKey, origItem, newSourceElement: nextSourceElement, previousSourceElement: lastSourceElement, }); // Add result in case element replaced this.views.rdoByKeyMap.set(elementKey, result.newItem); } } } const nextKeys = Array.from(this.views.rdoByKeyMap.keys()); const lastKeys = Array.from(last.rdoByKeyMap.keys()); const missingKeys = lodash_1.default.difference(lastKeys, nextKeys); if (missingKeys.length > 0) { // --------------------------- // Missing Index - DELETE // --------------------------- for (const elementKey of missingKeys) { const previousSourceElement = last.sourceByKeyMap.get(elementKey); const rdoToDelete = last.rdoByKeyMap.get(elementKey); changed = this.handleDeleteElement({ deleteHandler: this.onDelete, index: undefined, collectionKey: elementKey, rdoToDelete, previousSourceElement }) && changed; } } return changed; } getSourceNodeKeys() { return this.views.sourceByKeyMap.keys(); } getSourceNodeItem(key) { return this.views.sourceByKeyMap.get(key); } getRdoNodeItem(key) { return this.views.rdoByKeyMap.get(key); } } exports.RdoKeyCollectionNWBase = RdoKeyCollectionNWBase; //# sourceMappingURL=rdo-key-based-collection-nw-base.js.map