| 
/* 
 | 
* Licensed to the Apache Software Foundation (ASF) under one 
 | 
* or more contributor license agreements.  See the NOTICE file 
 | 
* distributed with this work for additional information 
 | 
* regarding copyright ownership.  The ASF licenses this file 
 | 
* to you under the Apache License, Version 2.0 (the 
 | 
* "License"); you may not use this file except in compliance 
 | 
* with the License.  You may obtain a copy of the License at 
 | 
* 
 | 
*   http://www.apache.org/licenses/LICENSE-2.0 
 | 
* 
 | 
* Unless required by applicable law or agreed to in writing, 
 | 
* software distributed under the License is distributed on an 
 | 
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 
 | 
* KIND, either express or implied.  See the License for the 
 | 
* specific language governing permissions and limitations 
 | 
* under the License. 
 | 
*/ 
 | 
  
 | 
  
 | 
/** 
 | 
 * AUTO-GENERATED FILE. DO NOT MODIFY. 
 | 
 */ 
 | 
  
 | 
/* 
 | 
* Licensed to the Apache Software Foundation (ASF) under one 
 | 
* or more contributor license agreements.  See the NOTICE file 
 | 
* distributed with this work for additional information 
 | 
* regarding copyright ownership.  The ASF licenses this file 
 | 
* to you under the Apache License, Version 2.0 (the 
 | 
* "License"); you may not use this file except in compliance 
 | 
* with the License.  You may obtain a copy of the License at 
 | 
* 
 | 
*   http://www.apache.org/licenses/LICENSE-2.0 
 | 
* 
 | 
* Unless required by applicable law or agreed to in writing, 
 | 
* software distributed under the License is distributed on an 
 | 
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 
 | 
* KIND, either express or implied.  See the License for the 
 | 
* specific language governing permissions and limitations 
 | 
* under the License. 
 | 
*/ 
 | 
function dataIndexMapValueLength(valNumOrArrLengthMoreThan2) { 
 | 
  return valNumOrArrLengthMoreThan2 == null ? 0 : valNumOrArrLengthMoreThan2.length || 1; 
 | 
} 
 | 
function defaultKeyGetter(item) { 
 | 
  return item; 
 | 
} 
 | 
var DataDiffer = /** @class */function () { 
 | 
  /** 
 | 
   * @param context Can be visited by this.context in callback. 
 | 
   */ 
 | 
  function DataDiffer(oldArr, newArr, oldKeyGetter, newKeyGetter, context, 
 | 
  // By default: 'oneToOne'. 
 | 
  diffMode) { 
 | 
    this._old = oldArr; 
 | 
    this._new = newArr; 
 | 
    this._oldKeyGetter = oldKeyGetter || defaultKeyGetter; 
 | 
    this._newKeyGetter = newKeyGetter || defaultKeyGetter; 
 | 
    // Visible in callback via `this.context`; 
 | 
    this.context = context; 
 | 
    this._diffModeMultiple = diffMode === 'multiple'; 
 | 
  } 
 | 
  /** 
 | 
   * Callback function when add a data 
 | 
   */ 
 | 
  DataDiffer.prototype.add = function (func) { 
 | 
    this._add = func; 
 | 
    return this; 
 | 
  }; 
 | 
  /** 
 | 
   * Callback function when update a data 
 | 
   */ 
 | 
  DataDiffer.prototype.update = function (func) { 
 | 
    this._update = func; 
 | 
    return this; 
 | 
  }; 
 | 
  /** 
 | 
   * Callback function when update a data and only work in `cbMode: 'byKey'`. 
 | 
   */ 
 | 
  DataDiffer.prototype.updateManyToOne = function (func) { 
 | 
    this._updateManyToOne = func; 
 | 
    return this; 
 | 
  }; 
 | 
  /** 
 | 
   * Callback function when update a data and only work in `cbMode: 'byKey'`. 
 | 
   */ 
 | 
  DataDiffer.prototype.updateOneToMany = function (func) { 
 | 
    this._updateOneToMany = func; 
 | 
    return this; 
 | 
  }; 
 | 
  /** 
 | 
   * Callback function when update a data and only work in `cbMode: 'byKey'`. 
 | 
   */ 
 | 
  DataDiffer.prototype.updateManyToMany = function (func) { 
 | 
    this._updateManyToMany = func; 
 | 
    return this; 
 | 
  }; 
 | 
  /** 
 | 
   * Callback function when remove a data 
 | 
   */ 
 | 
  DataDiffer.prototype.remove = function (func) { 
 | 
    this._remove = func; 
 | 
    return this; 
 | 
  }; 
 | 
  DataDiffer.prototype.execute = function () { 
 | 
    this[this._diffModeMultiple ? '_executeMultiple' : '_executeOneToOne'](); 
 | 
  }; 
 | 
  DataDiffer.prototype._executeOneToOne = function () { 
 | 
    var oldArr = this._old; 
 | 
    var newArr = this._new; 
 | 
    var newDataIndexMap = {}; 
 | 
    var oldDataKeyArr = new Array(oldArr.length); 
 | 
    var newDataKeyArr = new Array(newArr.length); 
 | 
    this._initIndexMap(oldArr, null, oldDataKeyArr, '_oldKeyGetter'); 
 | 
    this._initIndexMap(newArr, newDataIndexMap, newDataKeyArr, '_newKeyGetter'); 
 | 
    for (var i = 0; i < oldArr.length; i++) { 
 | 
      var oldKey = oldDataKeyArr[i]; 
 | 
      var newIdxMapVal = newDataIndexMap[oldKey]; 
 | 
      var newIdxMapValLen = dataIndexMapValueLength(newIdxMapVal); 
 | 
      // idx can never be empty array here. see 'set null' logic below. 
 | 
      if (newIdxMapValLen > 1) { 
 | 
        // Consider there is duplicate key (for example, use dataItem.name as key). 
 | 
        // We should make sure every item in newArr and oldArr can be visited. 
 | 
        var newIdx = newIdxMapVal.shift(); 
 | 
        if (newIdxMapVal.length === 1) { 
 | 
          newDataIndexMap[oldKey] = newIdxMapVal[0]; 
 | 
        } 
 | 
        this._update && this._update(newIdx, i); 
 | 
      } else if (newIdxMapValLen === 1) { 
 | 
        newDataIndexMap[oldKey] = null; 
 | 
        this._update && this._update(newIdxMapVal, i); 
 | 
      } else { 
 | 
        this._remove && this._remove(i); 
 | 
      } 
 | 
    } 
 | 
    this._performRestAdd(newDataKeyArr, newDataIndexMap); 
 | 
  }; 
 | 
  /** 
 | 
   * For example, consider the case: 
 | 
   * oldData: [o0, o1, o2, o3, o4, o5, o6, o7], 
 | 
   * newData: [n0, n1, n2, n3, n4, n5, n6, n7, n8], 
 | 
   * Where: 
 | 
   *     o0, o1, n0 has key 'a' (many to one) 
 | 
   *     o5, n4, n5, n6 has key 'b' (one to many) 
 | 
   *     o2, n1 has key 'c' (one to one) 
 | 
   *     n2, n3 has key 'd' (add) 
 | 
   *     o3, o4 has key 'e' (remove) 
 | 
   *     o6, o7, n7, n8 has key 'f' (many to many, treated as add and remove) 
 | 
   * Then: 
 | 
   *     (The order of the following directives are not ensured.) 
 | 
   *     this._updateManyToOne(n0, [o0, o1]); 
 | 
   *     this._updateOneToMany([n4, n5, n6], o5); 
 | 
   *     this._update(n1, o2); 
 | 
   *     this._remove(o3); 
 | 
   *     this._remove(o4); 
 | 
   *     this._remove(o6); 
 | 
   *     this._remove(o7); 
 | 
   *     this._add(n2); 
 | 
   *     this._add(n3); 
 | 
   *     this._add(n7); 
 | 
   *     this._add(n8); 
 | 
   */ 
 | 
  DataDiffer.prototype._executeMultiple = function () { 
 | 
    var oldArr = this._old; 
 | 
    var newArr = this._new; 
 | 
    var oldDataIndexMap = {}; 
 | 
    var newDataIndexMap = {}; 
 | 
    var oldDataKeyArr = []; 
 | 
    var newDataKeyArr = []; 
 | 
    this._initIndexMap(oldArr, oldDataIndexMap, oldDataKeyArr, '_oldKeyGetter'); 
 | 
    this._initIndexMap(newArr, newDataIndexMap, newDataKeyArr, '_newKeyGetter'); 
 | 
    for (var i = 0; i < oldDataKeyArr.length; i++) { 
 | 
      var oldKey = oldDataKeyArr[i]; 
 | 
      var oldIdxMapVal = oldDataIndexMap[oldKey]; 
 | 
      var newIdxMapVal = newDataIndexMap[oldKey]; 
 | 
      var oldIdxMapValLen = dataIndexMapValueLength(oldIdxMapVal); 
 | 
      var newIdxMapValLen = dataIndexMapValueLength(newIdxMapVal); 
 | 
      if (oldIdxMapValLen > 1 && newIdxMapValLen === 1) { 
 | 
        this._updateManyToOne && this._updateManyToOne(newIdxMapVal, oldIdxMapVal); 
 | 
        newDataIndexMap[oldKey] = null; 
 | 
      } else if (oldIdxMapValLen === 1 && newIdxMapValLen > 1) { 
 | 
        this._updateOneToMany && this._updateOneToMany(newIdxMapVal, oldIdxMapVal); 
 | 
        newDataIndexMap[oldKey] = null; 
 | 
      } else if (oldIdxMapValLen === 1 && newIdxMapValLen === 1) { 
 | 
        this._update && this._update(newIdxMapVal, oldIdxMapVal); 
 | 
        newDataIndexMap[oldKey] = null; 
 | 
      } else if (oldIdxMapValLen > 1 && newIdxMapValLen > 1) { 
 | 
        this._updateManyToMany && this._updateManyToMany(newIdxMapVal, oldIdxMapVal); 
 | 
        newDataIndexMap[oldKey] = null; 
 | 
      } else if (oldIdxMapValLen > 1) { 
 | 
        for (var i_1 = 0; i_1 < oldIdxMapValLen; i_1++) { 
 | 
          this._remove && this._remove(oldIdxMapVal[i_1]); 
 | 
        } 
 | 
      } else { 
 | 
        this._remove && this._remove(oldIdxMapVal); 
 | 
      } 
 | 
    } 
 | 
    this._performRestAdd(newDataKeyArr, newDataIndexMap); 
 | 
  }; 
 | 
  DataDiffer.prototype._performRestAdd = function (newDataKeyArr, newDataIndexMap) { 
 | 
    for (var i = 0; i < newDataKeyArr.length; i++) { 
 | 
      var newKey = newDataKeyArr[i]; 
 | 
      var newIdxMapVal = newDataIndexMap[newKey]; 
 | 
      var idxMapValLen = dataIndexMapValueLength(newIdxMapVal); 
 | 
      if (idxMapValLen > 1) { 
 | 
        for (var j = 0; j < idxMapValLen; j++) { 
 | 
          this._add && this._add(newIdxMapVal[j]); 
 | 
        } 
 | 
      } else if (idxMapValLen === 1) { 
 | 
        this._add && this._add(newIdxMapVal); 
 | 
      } 
 | 
      // Support both `newDataKeyArr` are duplication removed or not removed. 
 | 
      newDataIndexMap[newKey] = null; 
 | 
    } 
 | 
  }; 
 | 
  DataDiffer.prototype._initIndexMap = function (arr, 
 | 
  // Can be null. 
 | 
  map, 
 | 
  // In 'byKey', the output `keyArr` is duplication removed. 
 | 
  // In 'byIndex', the output `keyArr` is not duplication removed and 
 | 
  //     its indices are accurately corresponding to `arr`. 
 | 
  keyArr, keyGetterName) { 
 | 
    var cbModeMultiple = this._diffModeMultiple; 
 | 
    for (var i = 0; i < arr.length; i++) { 
 | 
      // Add prefix to avoid conflict with Object.prototype. 
 | 
      var key = '_ec_' + this[keyGetterName](arr[i], i); 
 | 
      if (!cbModeMultiple) { 
 | 
        keyArr[i] = key; 
 | 
      } 
 | 
      if (!map) { 
 | 
        continue; 
 | 
      } 
 | 
      var idxMapVal = map[key]; 
 | 
      var idxMapValLen = dataIndexMapValueLength(idxMapVal); 
 | 
      if (idxMapValLen === 0) { 
 | 
        // Simple optimize: in most cases, one index has one key, 
 | 
        // do not need array. 
 | 
        map[key] = i; 
 | 
        if (cbModeMultiple) { 
 | 
          keyArr.push(key); 
 | 
        } 
 | 
      } else if (idxMapValLen === 1) { 
 | 
        map[key] = [idxMapVal, i]; 
 | 
      } else { 
 | 
        idxMapVal.push(i); 
 | 
      } 
 | 
    } 
 | 
  }; 
 | 
  return DataDiffer; 
 | 
}(); 
 | 
export default DataDiffer; 
 |