@adobe/uxp-optimized
Version:
Library of react components optimized for Adobe's Unified Extensibility Platform
92 lines (90 loc) • 3.54 kB
JavaScript
;
/*
Copyright 2019 Adobe
All Rights Reserved.
NOTICE: Adobe permits you to use, modify, and distribute this file in
accordance with the terms of the Adobe license agreement accompanying
it. If you have received this file from a source other than Adobe,
then your use, modification, or distribution of it requires the prior
written permission of Adobe.
*/
Object.defineProperty(exports, "__esModule", { value: true });
const defaultTypes = () => "default";
function mapValuesToIndex(values) {
let map = new Map();
for (let i = 0; i < values.length; i++) {
map.set(values[i], i);
}
return map;
}
/**
* Returns a new array that contains as many values as possible
* within the same location as previous array.
* We also try to reuse indexes by type and never return a array smaller than the old array unless items have been completely removed.
*/
function getStableArray(oldValues, newSet, oldTypes = defaultTypes, newTypes = defaultTypes) {
let newSize = Math.max(oldValues.length, newSet.size);
// console.log("newSize: " + JSON.stringify({ old: oldValues.length, new: newSet.size }));
// let oldSet = new Set(oldValues);
let oldMap = mapValuesToIndex(oldValues);
let newMap = new Map();
let newValues = [];
function assign(newValue, newIndex) {
newValues[newIndex] = newValue;
// also track in our new map of where it went.
newMap.set(newValue, newIndex);
}
// 1. Reassign indexes to old values if value is present in both old and new
for (let newValue of newSet) {
let oldIndex = oldMap.get(newValue);
if (oldIndex != null) {
assign(newValue, oldIndex);
}
}
// 2. Reassign new values to unused indexes
let startIndex = 0;
for (let newValue of newSet) {
let oldIndex = oldMap.get(newValue);
if (oldIndex == null) {
// these elements were not in the old array
// we must add them now.
let foundUndefined = false;
for (let index = startIndex; true; index++) {
let oldValue = oldValues[index];
let oldType = oldValue != null ? oldTypes(oldValue) : null;
let newType = newTypes(newValue);
if (newValues[index] === undefined) {
foundUndefined = true;
if (oldType == null || oldType === newType) {
assign(newValue, index);
break;
}
}
else {
// we track where to start so that this isn't an
// n^2 algorithm.
if (!foundUndefined) {
startIndex = index;
}
}
}
}
}
// 3. Retain old values if there are still any unused indexes.
for (let i = 0; i < newSize; i++) {
let newValue = newValues[i];
if (newValue === undefined) {
let oldValue = oldValues[i];
assign(oldValue, i);
}
}
// return newValues removing any undefined values;
return newValues;
// return newValues.filter(value => value != null);
}
exports.default = getStableArray;
;
// Return also a Set of removed values.
// Those elements can be hidden and queued up for reuse by anything.
// If those elements are not toggled back open then they could end up being reused
// for their previous items which would be efficient and not uncommon.