Socket
Socket
Sign inDemoInstall

@egjs/list-differ

Package Overview
Dependencies
0
Maintainers
8
Versions
6
Alerts
File Explorer

Advanced tools

Install Socket

Detect and block malicious and high-risk dependencies

Install

Comparing version 0.0.1 to 0.1.0

.DS_Store

1

declaration/HashMap.d.ts

@@ -5,3 +5,2 @@ export default class HashMap<T> {

set(key: number | string, value: T): void;
has(key: number | string): boolean;
}
export default class PolyMap<T> {
private keys;
private values;
has(key: T): boolean;
get(key: T): number;
set(key: T, value: number): void;
}
export interface MapInteface<T, U> {
get(key: T): U;
get(key: T): U | undefined;
set(key: T, value: U): any;
has(key: T): boolean;
}

@@ -17,7 +16,5 @@ export declare type MapConstructor<T, U> = new () => MapInteface<T, U>;

changed: number[][];
changedBeforeAdded: number[][];
changedAfterAdded: number[][];
orderedBeforeAdded: number[][];
orderedAfterAdded: number[][];
ordered: number[][];
pureChanged: number[][];
maintained: number[][];
}
import { DiffResult } from "./types";
export declare function orderChanged(changed: number[][]): void;
export declare function diff<T>(prevList: T[], list: T[], findKeyCallback?: (e: T, i: number, arr: T[]) => any): DiffResult<T>;
/*
Copyright (c) 2019-present NAVER Corp.
Copyright (c) NAVER Corp.
name: @egjs/list-differ

@@ -7,3 +7,3 @@ license: MIT

repository: https://github.com/naver/egjs-list-differ
version: 0.0.1
version: 0.1.0
*/

@@ -20,6 +20,2 @@ var PolyMap =

__proto.has = function (key) {
return this.keys.indexOf(key) > -1;
};
__proto.get = function (key) {

@@ -58,6 +54,2 @@ return this.values[this.keys.indexOf(key)];

__proto.has = function (key) {
return key in this.object;
};
return HashMap;

@@ -68,152 +60,241 @@ }();

function orderChanged(changed) {
changed.forEach(function (_a, i) {
var from = _a[0],
to = _a[1]; // Index Count due to be pushed back
var Link =
/*#__PURE__*/
function () {
function Link() {}
var changedOffset = changed.slice(i + 1).filter(function (group) {
return from > group[0] && to < group[1] && from <= to;
}).length;
changed[i][1] += changedOffset;
to += changedOffset; // After the index changes, the index of 'from'(prevList's list) is pushed by one space.
var __proto = Link.prototype;
for (var j = i + 1; j < changed.length; ++j) {
if (to <= changed[j][0] && changed[j][0] < from) {
// pushed index
++changed[j][0];
}
}
});
}
function diff(prevList, list, findKeyCallback) {
var mapClass = SUPPORT_MAP ? Map : findKeyCallback ? HashMap : PolyMap;
__proto.connect = function (prevLink, nextLink) {
this.prev = prevLink;
this.next = nextLink;
prevLink && (prevLink.next = this);
nextLink && (nextLink.prev = this);
};
var callback = findKeyCallback || function (e) {
return e;
__proto.disconnect = function () {
// In double linked list, diconnect the interconnected relationship.
var prevLink = this.prev;
var nextLink = this.next;
prevLink && (prevLink.next = nextLink);
nextLink && (nextLink.prev = prevLink);
};
var added = [];
var removed = [];
var maintained = [];
var changed = [];
var prevKeys = prevList.map(callback);
var keys = list.map(callback);
var prevKeyMap = new mapClass();
var keyMap = new mapClass();
prevKeys.forEach(function (key, i) {
prevKeyMap.set(key, i);
});
keys.forEach(function (key, i) {
keyMap.set(key, i);
__proto.getIndex = function () {
var link = this;
var index = -1;
if (!prevKeyMap.has(key)) {
added.push(i);
while (link) {
link = link.prev;
++index;
}
});
prevKeys.forEach(function (key, i) {
var index = keyMap.get(key);
if (typeof index === "undefined") {
removed.push(i);
} else {
maintained.push([i, index]);
return index;
};
if (i !== index) {
changed.push([i, index]);
}
}
}); // Sort by ascending order of 'to(list's index).
return Link;
}();
changed.sort(function (a, b) {
return a[1] > b[1] ? 1 : -1;
});
maintained.sort(function (a, b) {
return a[1] > b[1] ? 1 : -1;
}); // start ordering
function orderChanged(changed, fixed) {
// It is roughly in the order of these examples.
// 4, 6, 0, 2, 1, 3, 5, 7
var fromLinks = []; // 0, 1, 2, 3, 4, 5, 6, 7
var orderedBefore = changed.map(function (_a) {
var toLinks = [];
changed.forEach(function (_a) {
var from = _a[0],
to = _a[1];
return [from, to];
var link = new Link();
fromLinks[from] = link;
toLinks[to] = link;
}); // `fromLinks` are connected to each other by double linked list.
fromLinks.forEach(function (link, i) {
link.connect(fromLinks[i - 1]);
});
var orderedAfter = changed.map(function (_a) {
return changed.filter(function (_, i) {
return !fixed[i];
}).map(function (_a, i) {
var from = _a[0],
to = _a[1];
return [from, to];
}); // The index is removed in reverse order.
removed.reverse().forEach(function (index) {
// Array with removed.
orderedBefore.forEach(function (group) {
if (group[0] >= index) {
--group[0];
if (from === to) {
return [0, 0];
}
var fromLink = fromLinks[from];
var toLink = toLinks[to - 1];
var fromIndex = fromLink.getIndex(); // Disconnect the link connected to `fromLink`.
fromLink.disconnect(); // Connect `fromLink` to the right of `toLink`.
if (!toLink) {
fromLink.connect(undefined, fromLinks[0]);
} else {
fromLink.connect(toLink, toLink.next);
}
var toIndex = fromLink.getIndex();
return [fromIndex, toIndex];
});
}
var Result =
/*#__PURE__*/
function () {
function Result(prevList, list, added, removed, changed, maintained, changedBeforeAdded, fixed) {
this.prevList = prevList;
this.list = list;
this.added = added;
this.removed = removed;
this.changed = changed;
this.maintained = maintained;
this.changedBeforeAdded = changedBeforeAdded;
this.fixed = fixed;
}
var __proto = Result.prototype;
Object.defineProperty(__proto, "ordered", {
get: function () {
if (!this.cacheOrdered) {
this.caculateOrdered();
}
}); // Array with removed.
orderedAfter.forEach(function (group) {
if (group[0] >= index) {
--group[0];
return this.cacheOrdered;
},
enumerable: true,
configurable: true
});
Object.defineProperty(__proto, "pureChanged", {
get: function () {
if (!this.cachePureChanged) {
this.caculateOrdered();
}
});
return this.cachePureChanged;
},
enumerable: true,
configurable: true
});
var _loop_1 = function (i) {
var index = added[i]; // Revert to an array where adding is not applied.
__proto.caculateOrdered = function () {
var ordered = orderChanged(this.changedBeforeAdded, this.fixed);
var changed = this.changed;
var pureChanged = [];
this.cacheOrdered = ordered.filter(function (_a, i) {
var from = _a[0],
to = _a[1];
var _b = changed[i],
fromBefore = _b[0],
toBefore = _b[1];
orderedBefore.forEach(function (group) {
if (group[1] >= index) {
--group[1];
if (from !== to) {
pureChanged.push([fromBefore, toBefore]);
return true;
}
});
this.cachePureChanged = pureChanged;
};
for (var i = added.length - 1; i >= 0; --i) {
_loop_1(i);
}
return Result;
}();
added.forEach(function (index) {
orderedAfter.forEach(function (group) {
if (group[0] >= index) {
++group[0];
}
});
});
orderChanged(orderedBefore);
orderChanged(orderedAfter);
/**
*
* @memberof eg.ListDiffer
* @static
* @function
* @param - Previous List <ko> ์ด์ „ ๋ชฉ๋ก </ko>
* @param - List to Update <ko> ์—…๋ฐ์ดํŠธ ํ•  ๋ชฉ๋ก </ko>
* @param - This callback function returns the key of the item. <ko> ์•„์ดํ…œ์˜ ํ‚ค๋ฅผ ๋ฐ˜ํ™˜ํ•˜๋Š” ์ฝœ๋ฐฑ ํ•จ์ˆ˜์ž…๋‹ˆ๋‹ค.</ko>
* @return - Returns the diff between `prevList` and `list` <ko> `prevList`์™€ `list`์˜ ๋‹ค๋ฅธ ์ ์„ ๋ฐ˜ํ™˜ํ•œ๋‹ค.</ko>
* @example
* import { diff } from "@egjs/list-differ";
* // script => eg.ListDiffer.diff
* const result = diff([0, 1, 2, 3, 4, 5], [7, 8, 0, 4, 3, 6, 2, 1], e => e);
* // List before update
* // [1, 2, 3, 4, 5]
* console.log(result.prevList);
* // Updated list
* // [4, 3, 6, 2, 1]
* console.log(result.list);
* // Index array of values added to `list`
* // [0, 1, 5]
* console.log(result.added);
* // Index array of values removed in `prevList`
* // [5]
* console.log(result.removed);
* // An array of index pairs of `prevList` and `list` with different indexes from `prevList` and `list`
* // [[0, 2], [4, 3], [3, 4], [2, 6], [1, 7]]
* console.log(result.changed);
* // The subset of `changed` and an array of index pairs that moved data directly. Indicate an array of absolute index pairs of `ordered`.(Formatted by: Array<[index of prevList, index of list]>)
* // [[4, 3], [3, 4], [2, 6]]
* console.log(result.pureChanged);
* // An array of index pairs to be `ordered` that can synchronize `list` before adding data. (Formatted by: Array<[prevIndex, nextIndex]>)
* // [[4, 1], [4, 2], [4, 3]]
* console.log(result.ordered);
* // An array of index pairs of `prevList` and `list` that have not been added/removed so data is preserved
* // [[0, 2], [4, 3], [3, 4], [2, 6], [1, 7]]
* console.log(result.maintained);
*/
function diff(prevList, list, findKeyCallback) {
var mapClass = SUPPORT_MAP ? Map : findKeyCallback ? HashMap : PolyMap;
var callback = findKeyCallback || function (e) {
return e;
};
var added = [];
var removed = [];
var maintained = [];
var prevKeys = prevList.map(callback);
var keys = list.map(callback);
var prevKeyMap = new mapClass();
var keyMap = new mapClass();
var changedBeforeAdded = [];
var changedAfterAdded = [];
var orderedBeforeAdded = [];
var orderedAfterAdded = [];
changed.forEach(function (_a, i) {
var from = _a[0],
to = _a[1];
var _b = orderedBefore[i],
fromBefore = _b[0],
toBefore = _b[1];
var _c = orderedAfter[i],
fromAfter = _c[0],
toAfter = _c[1]; // There is no change in index.
var fixed = [];
var removedMap = {};
var changed = [];
var addedCount = 0;
var removedCount = 0; // Add prevKeys and keys to the hashmap.
if (fromBefore !== toBefore) {
changedBeforeAdded.push([from, to]);
orderedBeforeAdded.push([fromBefore, toBefore]);
prevKeys.forEach(function (key, prevListIndex) {
prevKeyMap.set(key, prevListIndex);
});
keys.forEach(function (key, listIndex) {
keyMap.set(key, listIndex);
}); // Compare `prevKeys` and `keys` and add them to `removed` if they are not in `keys`.
prevKeys.forEach(function (key, prevListIndex) {
var listIndex = keyMap.get(key); // In prevList, but not in list, it is removed.
if (typeof listIndex === "undefined") {
++removedCount;
removed.push(prevListIndex);
} else {
removedMap[listIndex] = removedCount;
}
}); // Compare `prevKeys` and `keys` and add them to `added` if they are not in `prevKeys`.
if (fromAfter !== toAfter) {
changedAfterAdded.push([from, to]);
orderedAfterAdded.push([fromAfter, toAfter]);
keys.forEach(function (key, listIndex) {
var prevListIndex = prevKeyMap.get(key); // In list, but not in prevList, it is added.
if (typeof prevListIndex === "undefined") {
added.push(listIndex);
++addedCount;
} else {
maintained.push([prevListIndex, listIndex]);
removedCount = removedMap[listIndex] || 0;
changedBeforeAdded.push([prevListIndex - removedCount, listIndex - addedCount]);
fixed.push(listIndex === prevListIndex);
if (prevListIndex !== listIndex) {
changed.push([prevListIndex, listIndex]);
}
}
});
return {
prevList: prevList,
list: list,
added: added,
maintained: maintained,
changed: changed,
changedBeforeAdded: changedBeforeAdded,
changedAfterAdded: changedAfterAdded,
orderedBeforeAdded: orderedBeforeAdded,
orderedAfterAdded: orderedAfterAdded,
removed: removed
};
}); // Sort by ascending order of 'to(list's index).
removed.reverse();
return new Result(prevList, list, added, removed, changed, maintained, changedBeforeAdded, fixed);
}

@@ -231,3 +312,3 @@

/**
* @param - Initializing Data Array <ko> ์ดˆ๊ธฐ ์„ค์ •ํ•  ๋ฐ์ดํ„ฐ ๋ฐฐ์—ด </ko>
* @param - Initializing Data Array. <ko> ์ดˆ๊ธฐ ์„ค์ •ํ•  ๋ฐ์ดํ„ฐ ๋ฐฐ์—ด.</ko>
* @param - This callback function returns the key of the item. <ko> ์•„์ดํ…œ์˜ ํ‚ค๋ฅผ ๋ฐ˜ํ™˜ํ•˜๋Š” ์ฝœ๋ฐฑ ํ•จ์ˆ˜์ž…๋‹ˆ๋‹ค.</ko>

@@ -245,24 +326,18 @@ * @example

* console.log(result.list);
* // Index array of values added to `list`
* // Index array of values added to `list`.
* // [0, 1, 5]
* console.log(result.added);
* // Index array of values removed in `prevList`
* // Index array of values removed in `prevList`.
* // [5]
* console.log(result.removed);
* // Tuple arrays of index of `prevList` and `list` with different indexes from `prevList` and `list`
* // An array of index pairs of `prevList` and `list` with different indexes from `prevList` and `list`.
* // [[0, 2], [4, 3], [3, 4], [2, 6], [1, 7]]
* console.log(result.changed);
* // Tuple arrays of index of `prevList` and `list` with different indexes from `prevList` and `list` before data is added
* // The subset of `changed` and an array of index pairs that moved data directly. Indicate an array of absolute index pairs of `ordered`.(Formatted by: Array<[index of prevList, index of list]>)
* // [[4, 3], [3, 4], [2, 6]]
* console.log(result.changedBeforeAdded);
* // Tuple arrays of index of `prevList` and `list` with different indexes from `prevList` and `list` after data is added
* // [[4, 3], [3, 4], [2, 6], [1, 7]]
* console.log(result.changedAfterAdded);
* // Tuple arrays of `prevIndex` and `nextIndex` to change the order of `prevList` to `list` before data is added.
* console.log(result.pureChanged);
* // An array of index pairs to be `ordered` that can synchronize `list` before adding data. (Formatted by: Array<[prevIndex, nextIndex]>)
* // [[4, 1], [4, 2], [4, 3]]
* console.log(result.orderedBeforeAdded);
* // Tuple arrays of `prevIndex` and `nextIndex` to change the order of `prevList` to `list` after data is added
* // [[7, 3], [7, 4], [6, 7], [5, 7]]
* console.log(result.orderedAfterAdded);
* // Tuple arrays of index of `prevList` and `list` that have not been added/removed so data is preserved
* console.log(result.ordered);
* // An array of index pairs of `prevList` and `list` that have not been added/removed so data is preserved.
* // [[0, 2], [4, 3], [3, 4], [2, 6], [1, 7]]

@@ -280,6 +355,6 @@ * console.log(result.maintained);

/**
* Update list. If there's a change in the list, 'update' event is called.
* @ko ๋ฐ์ดํ„ฐ๋ฅผ ์—…๋ฐ์ดํŠธ๋ฅผ ํ•ฉ๋‹ˆ๋‹ค. ๋ฐ์ดํ„ฐ์— ๋ณ€ํ™”๊ฐ€ ๊ฐ์ง€ ๋˜๋ฉด 'update' ์ด๋ฒคํŠธ๊ฐ€ ํ˜ธ์ถœ๋ฉ๋‹ˆ๋‹ค.
* @param list - Data to update
* @return - Results updated
* Update list.
* @ko ๋ฆฌ์ŠคํŠธ๋ฅผ ์—…๋ฐ์ดํŠธ๋ฅผ ํ•ฉ๋‹ˆ๋‹ค.
* @param - List to update <ko> ์—…๋ฐ์ดํŠธํ•  ๋ฆฌ์ŠคํŠธ </ko>
* @return - Returns the results of an update from `prevList` to `list`.<ko> `prevList`์—์„œ `list`๋กœ ์—…๋ฐ์ดํŠธํ•œ ๊ฒฐ๊ณผ๋ฅผ ๋ฐ˜ํ™˜ํ•œ๋‹ค. </ko>
*/

@@ -286,0 +361,0 @@

/*
Copyright (c) 2019-present NAVER Corp.
Copyright (c) NAVER Corp.
name: @egjs/list-differ

@@ -7,3 +7,3 @@ license: MIT

repository: https://github.com/naver/egjs-list-differ
version: 0.0.1
version: 0.1.0
*/

@@ -26,6 +26,2 @@ (function (global, factory) {

__proto.has = function (key) {
return this.keys.indexOf(key) > -1;
};
__proto.get = function (key) {

@@ -64,6 +60,2 @@ return this.values[this.keys.indexOf(key)];

__proto.has = function (key) {
return key in this.object;
};
return HashMap;

@@ -74,152 +66,241 @@ }();

function orderChanged(changed) {
changed.forEach(function (_a, i) {
var from = _a[0],
to = _a[1]; // Index Count due to be pushed back
var Link =
/*#__PURE__*/
function () {
function Link() {}
var changedOffset = changed.slice(i + 1).filter(function (group) {
return from > group[0] && to < group[1] && from <= to;
}).length;
changed[i][1] += changedOffset;
to += changedOffset; // After the index changes, the index of 'from'(prevList's list) is pushed by one space.
var __proto = Link.prototype;
for (var j = i + 1; j < changed.length; ++j) {
if (to <= changed[j][0] && changed[j][0] < from) {
// pushed index
++changed[j][0];
}
}
});
}
function diff(prevList, list, findKeyCallback) {
var mapClass = SUPPORT_MAP ? Map : findKeyCallback ? HashMap : PolyMap;
__proto.connect = function (prevLink, nextLink) {
this.prev = prevLink;
this.next = nextLink;
prevLink && (prevLink.next = this);
nextLink && (nextLink.prev = this);
};
var callback = findKeyCallback || function (e) {
return e;
__proto.disconnect = function () {
// In double linked list, diconnect the interconnected relationship.
var prevLink = this.prev;
var nextLink = this.next;
prevLink && (prevLink.next = nextLink);
nextLink && (nextLink.prev = prevLink);
};
var added = [];
var removed = [];
var maintained = [];
var changed = [];
var prevKeys = prevList.map(callback);
var keys = list.map(callback);
var prevKeyMap = new mapClass();
var keyMap = new mapClass();
prevKeys.forEach(function (key, i) {
prevKeyMap.set(key, i);
});
keys.forEach(function (key, i) {
keyMap.set(key, i);
__proto.getIndex = function () {
var link = this;
var index = -1;
if (!prevKeyMap.has(key)) {
added.push(i);
while (link) {
link = link.prev;
++index;
}
});
prevKeys.forEach(function (key, i) {
var index = keyMap.get(key);
if (typeof index === "undefined") {
removed.push(i);
} else {
maintained.push([i, index]);
return index;
};
if (i !== index) {
changed.push([i, index]);
}
}
}); // Sort by ascending order of 'to(list's index).
return Link;
}();
changed.sort(function (a, b) {
return a[1] > b[1] ? 1 : -1;
});
maintained.sort(function (a, b) {
return a[1] > b[1] ? 1 : -1;
}); // start ordering
function orderChanged(changed, fixed) {
// It is roughly in the order of these examples.
// 4, 6, 0, 2, 1, 3, 5, 7
var fromLinks = []; // 0, 1, 2, 3, 4, 5, 6, 7
var orderedBefore = changed.map(function (_a) {
var toLinks = [];
changed.forEach(function (_a) {
var from = _a[0],
to = _a[1];
return [from, to];
var link = new Link();
fromLinks[from] = link;
toLinks[to] = link;
}); // `fromLinks` are connected to each other by double linked list.
fromLinks.forEach(function (link, i) {
link.connect(fromLinks[i - 1]);
});
var orderedAfter = changed.map(function (_a) {
return changed.filter(function (_, i) {
return !fixed[i];
}).map(function (_a, i) {
var from = _a[0],
to = _a[1];
return [from, to];
}); // The index is removed in reverse order.
removed.reverse().forEach(function (index) {
// Array with removed.
orderedBefore.forEach(function (group) {
if (group[0] >= index) {
--group[0];
if (from === to) {
return [0, 0];
}
var fromLink = fromLinks[from];
var toLink = toLinks[to - 1];
var fromIndex = fromLink.getIndex(); // Disconnect the link connected to `fromLink`.
fromLink.disconnect(); // Connect `fromLink` to the right of `toLink`.
if (!toLink) {
fromLink.connect(undefined, fromLinks[0]);
} else {
fromLink.connect(toLink, toLink.next);
}
var toIndex = fromLink.getIndex();
return [fromIndex, toIndex];
});
}
var Result =
/*#__PURE__*/
function () {
function Result(prevList, list, added, removed, changed, maintained, changedBeforeAdded, fixed) {
this.prevList = prevList;
this.list = list;
this.added = added;
this.removed = removed;
this.changed = changed;
this.maintained = maintained;
this.changedBeforeAdded = changedBeforeAdded;
this.fixed = fixed;
}
var __proto = Result.prototype;
Object.defineProperty(__proto, "ordered", {
get: function () {
if (!this.cacheOrdered) {
this.caculateOrdered();
}
}); // Array with removed.
orderedAfter.forEach(function (group) {
if (group[0] >= index) {
--group[0];
return this.cacheOrdered;
},
enumerable: true,
configurable: true
});
Object.defineProperty(__proto, "pureChanged", {
get: function () {
if (!this.cachePureChanged) {
this.caculateOrdered();
}
});
return this.cachePureChanged;
},
enumerable: true,
configurable: true
});
var _loop_1 = function (i) {
var index = added[i]; // Revert to an array where adding is not applied.
__proto.caculateOrdered = function () {
var ordered = orderChanged(this.changedBeforeAdded, this.fixed);
var changed = this.changed;
var pureChanged = [];
this.cacheOrdered = ordered.filter(function (_a, i) {
var from = _a[0],
to = _a[1];
var _b = changed[i],
fromBefore = _b[0],
toBefore = _b[1];
orderedBefore.forEach(function (group) {
if (group[1] >= index) {
--group[1];
if (from !== to) {
pureChanged.push([fromBefore, toBefore]);
return true;
}
});
this.cachePureChanged = pureChanged;
};
for (var i = added.length - 1; i >= 0; --i) {
_loop_1(i);
}
return Result;
}();
added.forEach(function (index) {
orderedAfter.forEach(function (group) {
if (group[0] >= index) {
++group[0];
}
});
});
orderChanged(orderedBefore);
orderChanged(orderedAfter);
/**
*
* @memberof eg.ListDiffer
* @static
* @function
* @param - Previous List <ko> ์ด์ „ ๋ชฉ๋ก </ko>
* @param - List to Update <ko> ์—…๋ฐ์ดํŠธ ํ•  ๋ชฉ๋ก </ko>
* @param - This callback function returns the key of the item. <ko> ์•„์ดํ…œ์˜ ํ‚ค๋ฅผ ๋ฐ˜ํ™˜ํ•˜๋Š” ์ฝœ๋ฐฑ ํ•จ์ˆ˜์ž…๋‹ˆ๋‹ค.</ko>
* @return - Returns the diff between `prevList` and `list` <ko> `prevList`์™€ `list`์˜ ๋‹ค๋ฅธ ์ ์„ ๋ฐ˜ํ™˜ํ•œ๋‹ค.</ko>
* @example
* import { diff } from "@egjs/list-differ";
* // script => eg.ListDiffer.diff
* const result = diff([0, 1, 2, 3, 4, 5], [7, 8, 0, 4, 3, 6, 2, 1], e => e);
* // List before update
* // [1, 2, 3, 4, 5]
* console.log(result.prevList);
* // Updated list
* // [4, 3, 6, 2, 1]
* console.log(result.list);
* // Index array of values added to `list`
* // [0, 1, 5]
* console.log(result.added);
* // Index array of values removed in `prevList`
* // [5]
* console.log(result.removed);
* // An array of index pairs of `prevList` and `list` with different indexes from `prevList` and `list`
* // [[0, 2], [4, 3], [3, 4], [2, 6], [1, 7]]
* console.log(result.changed);
* // The subset of `changed` and an array of index pairs that moved data directly. Indicate an array of absolute index pairs of `ordered`.(Formatted by: Array<[index of prevList, index of list]>)
* // [[4, 3], [3, 4], [2, 6]]
* console.log(result.pureChanged);
* // An array of index pairs to be `ordered` that can synchronize `list` before adding data. (Formatted by: Array<[prevIndex, nextIndex]>)
* // [[4, 1], [4, 2], [4, 3]]
* console.log(result.ordered);
* // An array of index pairs of `prevList` and `list` that have not been added/removed so data is preserved
* // [[0, 2], [4, 3], [3, 4], [2, 6], [1, 7]]
* console.log(result.maintained);
*/
function diff(prevList, list, findKeyCallback) {
var mapClass = SUPPORT_MAP ? Map : findKeyCallback ? HashMap : PolyMap;
var callback = findKeyCallback || function (e) {
return e;
};
var added = [];
var removed = [];
var maintained = [];
var prevKeys = prevList.map(callback);
var keys = list.map(callback);
var prevKeyMap = new mapClass();
var keyMap = new mapClass();
var changedBeforeAdded = [];
var changedAfterAdded = [];
var orderedBeforeAdded = [];
var orderedAfterAdded = [];
changed.forEach(function (_a, i) {
var from = _a[0],
to = _a[1];
var _b = orderedBefore[i],
fromBefore = _b[0],
toBefore = _b[1];
var _c = orderedAfter[i],
fromAfter = _c[0],
toAfter = _c[1]; // There is no change in index.
var fixed = [];
var removedMap = {};
var changed = [];
var addedCount = 0;
var removedCount = 0; // Add prevKeys and keys to the hashmap.
if (fromBefore !== toBefore) {
changedBeforeAdded.push([from, to]);
orderedBeforeAdded.push([fromBefore, toBefore]);
prevKeys.forEach(function (key, prevListIndex) {
prevKeyMap.set(key, prevListIndex);
});
keys.forEach(function (key, listIndex) {
keyMap.set(key, listIndex);
}); // Compare `prevKeys` and `keys` and add them to `removed` if they are not in `keys`.
prevKeys.forEach(function (key, prevListIndex) {
var listIndex = keyMap.get(key); // In prevList, but not in list, it is removed.
if (typeof listIndex === "undefined") {
++removedCount;
removed.push(prevListIndex);
} else {
removedMap[listIndex] = removedCount;
}
}); // Compare `prevKeys` and `keys` and add them to `added` if they are not in `prevKeys`.
if (fromAfter !== toAfter) {
changedAfterAdded.push([from, to]);
orderedAfterAdded.push([fromAfter, toAfter]);
keys.forEach(function (key, listIndex) {
var prevListIndex = prevKeyMap.get(key); // In list, but not in prevList, it is added.
if (typeof prevListIndex === "undefined") {
added.push(listIndex);
++addedCount;
} else {
maintained.push([prevListIndex, listIndex]);
removedCount = removedMap[listIndex] || 0;
changedBeforeAdded.push([prevListIndex - removedCount, listIndex - addedCount]);
fixed.push(listIndex === prevListIndex);
if (prevListIndex !== listIndex) {
changed.push([prevListIndex, listIndex]);
}
}
});
return {
prevList: prevList,
list: list,
added: added,
maintained: maintained,
changed: changed,
changedBeforeAdded: changedBeforeAdded,
changedAfterAdded: changedAfterAdded,
orderedBeforeAdded: orderedBeforeAdded,
orderedAfterAdded: orderedAfterAdded,
removed: removed
};
}); // Sort by ascending order of 'to(list's index).
removed.reverse();
return new Result(prevList, list, added, removed, changed, maintained, changedBeforeAdded, fixed);
}

@@ -237,3 +318,3 @@

/**
* @param - Initializing Data Array <ko> ์ดˆ๊ธฐ ์„ค์ •ํ•  ๋ฐ์ดํ„ฐ ๋ฐฐ์—ด </ko>
* @param - Initializing Data Array. <ko> ์ดˆ๊ธฐ ์„ค์ •ํ•  ๋ฐ์ดํ„ฐ ๋ฐฐ์—ด.</ko>
* @param - This callback function returns the key of the item. <ko> ์•„์ดํ…œ์˜ ํ‚ค๋ฅผ ๋ฐ˜ํ™˜ํ•˜๋Š” ์ฝœ๋ฐฑ ํ•จ์ˆ˜์ž…๋‹ˆ๋‹ค.</ko>

@@ -251,24 +332,18 @@ * @example

* console.log(result.list);
* // Index array of values added to `list`
* // Index array of values added to `list`.
* // [0, 1, 5]
* console.log(result.added);
* // Index array of values removed in `prevList`
* // Index array of values removed in `prevList`.
* // [5]
* console.log(result.removed);
* // Tuple arrays of index of `prevList` and `list` with different indexes from `prevList` and `list`
* // An array of index pairs of `prevList` and `list` with different indexes from `prevList` and `list`.
* // [[0, 2], [4, 3], [3, 4], [2, 6], [1, 7]]
* console.log(result.changed);
* // Tuple arrays of index of `prevList` and `list` with different indexes from `prevList` and `list` before data is added
* // The subset of `changed` and an array of index pairs that moved data directly. Indicate an array of absolute index pairs of `ordered`.(Formatted by: Array<[index of prevList, index of list]>)
* // [[4, 3], [3, 4], [2, 6]]
* console.log(result.changedBeforeAdded);
* // Tuple arrays of index of `prevList` and `list` with different indexes from `prevList` and `list` after data is added
* // [[4, 3], [3, 4], [2, 6], [1, 7]]
* console.log(result.changedAfterAdded);
* // Tuple arrays of `prevIndex` and `nextIndex` to change the order of `prevList` to `list` before data is added.
* console.log(result.pureChanged);
* // An array of index pairs to be `ordered` that can synchronize `list` before adding data. (Formatted by: Array<[prevIndex, nextIndex]>)
* // [[4, 1], [4, 2], [4, 3]]
* console.log(result.orderedBeforeAdded);
* // Tuple arrays of `prevIndex` and `nextIndex` to change the order of `prevList` to `list` after data is added
* // [[7, 3], [7, 4], [6, 7], [5, 7]]
* console.log(result.orderedAfterAdded);
* // Tuple arrays of index of `prevList` and `list` that have not been added/removed so data is preserved
* console.log(result.ordered);
* // An array of index pairs of `prevList` and `list` that have not been added/removed so data is preserved.
* // [[0, 2], [4, 3], [3, 4], [2, 6], [1, 7]]

@@ -286,6 +361,6 @@ * console.log(result.maintained);

/**
* Update list. If there's a change in the list, 'update' event is called.
* @ko ๋ฐ์ดํ„ฐ๋ฅผ ์—…๋ฐ์ดํŠธ๋ฅผ ํ•ฉ๋‹ˆ๋‹ค. ๋ฐ์ดํ„ฐ์— ๋ณ€ํ™”๊ฐ€ ๊ฐ์ง€ ๋˜๋ฉด 'update' ์ด๋ฒคํŠธ๊ฐ€ ํ˜ธ์ถœ๋ฉ๋‹ˆ๋‹ค.
* @param list - Data to update
* @return - Results updated
* Update list.
* @ko ๋ฆฌ์ŠคํŠธ๋ฅผ ์—…๋ฐ์ดํŠธ๋ฅผ ํ•ฉ๋‹ˆ๋‹ค.
* @param - List to update <ko> ์—…๋ฐ์ดํŠธํ•  ๋ฆฌ์ŠคํŠธ </ko>
* @return - Returns the results of an update from `prevList` to `list`.<ko> `prevList`์—์„œ `list`๋กœ ์—…๋ฐ์ดํŠธํ•œ ๊ฒฐ๊ณผ๋ฅผ ๋ฐ˜ํ™˜ํ•œ๋‹ค. </ko>
*/

@@ -292,0 +367,0 @@

/*
Copyright (c) 2019-present NAVER Corp.
Copyright (c) NAVER Corp.
name: @egjs/list-differ

@@ -7,5 +7,5 @@ license: MIT

repository: https://github.com/naver/egjs-list-differ
version: 0.0.1
version: 0.1.0
*/
!function(t,n){"object"==typeof exports&&"undefined"!=typeof module?module.exports=n():"function"==typeof define&&define.amd?define(n):((t=t||self).eg=t.eg||{},t.eg.ListDiffer=n())}(this,function(){"use strict";var k=function(){function t(){this.keys=[],this.values=[]}var n=t.prototype;return n.has=function(t){return-1<this.keys.indexOf(t)},n.get=function(t){return this.values[this.keys.indexOf(t)]},n.set=function(t,n){var e=this.keys,r=this.values,i=e.indexOf(t),o=-1===i?e.length:i;e[o]=t,r[o]=n},t}(),A=function(){function t(){this.object={}}var n=t.prototype;return n.get=function(t){return this.object[t]},n.set=function(t,n){this.object[t]=n},n.has=function(t){return t in this.object},t}(),j="function"==typeof Map;function x(f){f.forEach(function(t,n){var e=t[0],r=t[1],i=f.slice(n+1).filter(function(t){return e>t[0]&&r<t[1]&&e<=r}).length;f[n][1]+=i,r+=i;for(var o=n+1;o<f.length;++o)r<=f[o][0]&&f[o][0]<e&&++f[o][0]})}function r(t,n,e){var r=j?Map:e?A:k,i=e||function(t){return t},o=[],f=[],u=[],c=[],s=t.map(i),a=n.map(i),h=new r,d=new r;s.forEach(function(t,n){h.set(t,n)}),a.forEach(function(t,n){d.set(t,n),h.has(t)||o.push(n)}),s.forEach(function(t,n){var e=d.get(t);void 0===e?f.push(n):(u.push([n,e]),n!==e&&c.push([n,e]))}),c.sort(function(t,n){return t[1]>n[1]?1:-1}),u.sort(function(t,n){return t[1]>n[1]?1:-1});var p=c.map(function(t){return[t[0],t[1]]}),l=c.map(function(t){return[t[0],t[1]]});f.reverse().forEach(function(n){p.forEach(function(t){t[0]>=n&&--t[0]}),l.forEach(function(t){t[0]>=n&&--t[0]})});for(var v=function(t){var n=o[t];p.forEach(function(t){t[1]>=n&&--t[1]})},g=o.length-1;0<=g;--g)v(g);o.forEach(function(n){l.forEach(function(t){t[0]>=n&&++t[0]})}),x(p),x(l);var y=[],E=[],m=[],b=[];return c.forEach(function(t,n){var e=t[0],r=t[1],i=p[n],o=i[0],f=i[1],u=l[n],c=u[0],s=u[1];o!==f&&(y.push([e,r]),m.push([o,f])),c!==s&&(E.push([e,r]),b.push([c,s]))}),{prevList:t,list:n,added:o,maintained:u,changed:c,changedBeforeAdded:y,changedAfterAdded:E,orderedBeforeAdded:m,orderedAfterAdded:b,removed:f}}var t=function(){function t(t,n){void 0===t&&(t=[]),this.findKeyCallback=n,this.list=[].slice.call(t)}return t.prototype.update=function(t){var n=[].slice.call(t),e=r(this.list,n,this.findKeyCallback);return this.list=n,e},t}();return t.diff=r,t});
!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?module.exports=t():"function"==typeof define&&define.amd?define(t):((e=e||self).eg=e.eg||{},e.eg.ListDiffer=t())}(this,function(){"use strict";var x=function(){function e(){this.keys=[],this.values=[]}var t=e.prototype;return t.get=function(e){return this.values[this.keys.indexOf(e)]},t.set=function(e,t){var n=this.keys,i=this.values,r=n.indexOf(e),c=-1===r?n.length:r;n[c]=e,i[c]=t},e}(),b=function(){function e(){this.object={}}var t=e.prototype;return t.get=function(e){return this.object[e]},t.set=function(e,t){this.object[e]=t},e}(),m="function"==typeof Map,r=function(){function e(){}var t=e.prototype;return t.connect=function(e,t){this.prev=e,this.next=t,e&&(e.next=this),t&&(t.prev=this)},t.disconnect=function(){var e=this.prev,t=this.next;e&&(e.next=t),t&&(t.prev=e)},t.getIndex=function(){for(var e=this,t=-1;e;)e=e.prev,++t;return t},e}();var O=function(){function e(e,t,n,i,r,c,o,u){this.prevList=e,this.list=t,this.added=n,this.removed=i,this.changed=r,this.maintained=c,this.changedBeforeAdded=o,this.fixed=u}var t=e.prototype;return Object.defineProperty(t,"ordered",{get:function(){return this.cacheOrdered||this.caculateOrdered(),this.cacheOrdered},enumerable:!0,configurable:!0}),Object.defineProperty(t,"pureChanged",{get:function(){return this.cachePureChanged||this.caculateOrdered(),this.cachePureChanged},enumerable:!0,configurable:!0}),t.caculateOrdered=function(){var e=function(e,n){var u=[],s=[];return e.forEach(function(e){var t=e[0],n=e[1],i=new r;u[t]=i,s[n]=i}),u.forEach(function(e,t){e.connect(u[t-1])}),e.filter(function(e,t){return!n[t]}).map(function(e,t){var n=e[0],i=e[1];if(n===i)return[0,0];var r=u[n],c=s[i-1],o=r.getIndex();return r.disconnect(),c?r.connect(c,c.next):r.connect(void 0,u[0]),[o,r.getIndex()]})}(this.changedBeforeAdded,this.fixed),u=this.changed,s=[];this.cacheOrdered=e.filter(function(e,t){var n=e[0],i=e[1],r=u[t],c=r[0],o=r[1];if(n!==i)return s.push([c,o]),!0}),this.cachePureChanged=s},e}();function i(e,t,n){var i=m?Map:n?b:x,r=n||function(e){return e},c=[],o=[],u=[],s=e.map(r),f=t.map(r),a=new i,h=new i,d=[],p=[],v={},l=[],g=0,y=0;return s.forEach(function(e,t){a.set(e,t)}),f.forEach(function(e,t){h.set(e,t)}),s.forEach(function(e,t){var n=h.get(e);void 0===n?(++y,o.push(t)):v[n]=y}),f.forEach(function(e,t){var n=a.get(e);void 0===n?(c.push(t),++g):(u.push([n,t]),y=v[t]||0,d.push([n-y,t-g]),p.push(t===n),n!==t&&l.push([n,t]))}),o.reverse(),new O(e,t,c,o,l,u,d,p)}var e=function(){function e(e,t){void 0===e&&(e=[]),this.findKeyCallback=t,this.list=[].slice.call(e)}return e.prototype.update=function(e){var t=[].slice.call(e),n=i(this.list,t,this.findKeyCallback);return this.list=t,n},e}();return e.diff=i,e});
//# sourceMappingURL=list-differ.min.js.map
/*
Copyright (c) 2019-present NAVER Corp.
Copyright (c) NAVER Corp.
name: @egjs/list-differ

@@ -7,3 +7,3 @@ license: MIT

repository: https://github.com/naver/egjs-list-differ
version: 0.0.1
version: 0.1.0
*/

@@ -26,6 +26,2 @@ (function (global, factory) {

__proto.has = function (key) {
return this.keys.indexOf(key) > -1;
};
__proto.get = function (key) {

@@ -64,6 +60,2 @@ return this.values[this.keys.indexOf(key)];

__proto.has = function (key) {
return key in this.object;
};
return HashMap;

@@ -74,152 +66,241 @@ }();

function orderChanged(changed) {
changed.forEach(function (_a, i) {
var from = _a[0],
to = _a[1]; // Index Count due to be pushed back
var Link =
/*#__PURE__*/
function () {
function Link() {}
var changedOffset = changed.slice(i + 1).filter(function (group) {
return from > group[0] && to < group[1] && from <= to;
}).length;
changed[i][1] += changedOffset;
to += changedOffset; // After the index changes, the index of 'from'(prevList's list) is pushed by one space.
var __proto = Link.prototype;
for (var j = i + 1; j < changed.length; ++j) {
if (to <= changed[j][0] && changed[j][0] < from) {
// pushed index
++changed[j][0];
}
}
});
}
function diff(prevList, list, findKeyCallback) {
var mapClass = SUPPORT_MAP ? Map : findKeyCallback ? HashMap : PolyMap;
__proto.connect = function (prevLink, nextLink) {
this.prev = prevLink;
this.next = nextLink;
prevLink && (prevLink.next = this);
nextLink && (nextLink.prev = this);
};
var callback = findKeyCallback || function (e) {
return e;
__proto.disconnect = function () {
// In double linked list, diconnect the interconnected relationship.
var prevLink = this.prev;
var nextLink = this.next;
prevLink && (prevLink.next = nextLink);
nextLink && (nextLink.prev = prevLink);
};
var added = [];
var removed = [];
var maintained = [];
var changed = [];
var prevKeys = prevList.map(callback);
var keys = list.map(callback);
var prevKeyMap = new mapClass();
var keyMap = new mapClass();
prevKeys.forEach(function (key, i) {
prevKeyMap.set(key, i);
});
keys.forEach(function (key, i) {
keyMap.set(key, i);
__proto.getIndex = function () {
var link = this;
var index = -1;
if (!prevKeyMap.has(key)) {
added.push(i);
while (link) {
link = link.prev;
++index;
}
});
prevKeys.forEach(function (key, i) {
var index = keyMap.get(key);
if (typeof index === "undefined") {
removed.push(i);
} else {
maintained.push([i, index]);
return index;
};
if (i !== index) {
changed.push([i, index]);
}
}
}); // Sort by ascending order of 'to(list's index).
return Link;
}();
changed.sort(function (a, b) {
return a[1] > b[1] ? 1 : -1;
});
maintained.sort(function (a, b) {
return a[1] > b[1] ? 1 : -1;
}); // start ordering
function orderChanged(changed, fixed) {
// It is roughly in the order of these examples.
// 4, 6, 0, 2, 1, 3, 5, 7
var fromLinks = []; // 0, 1, 2, 3, 4, 5, 6, 7
var orderedBefore = changed.map(function (_a) {
var toLinks = [];
changed.forEach(function (_a) {
var from = _a[0],
to = _a[1];
return [from, to];
var link = new Link();
fromLinks[from] = link;
toLinks[to] = link;
}); // `fromLinks` are connected to each other by double linked list.
fromLinks.forEach(function (link, i) {
link.connect(fromLinks[i - 1]);
});
var orderedAfter = changed.map(function (_a) {
return changed.filter(function (_, i) {
return !fixed[i];
}).map(function (_a, i) {
var from = _a[0],
to = _a[1];
return [from, to];
}); // The index is removed in reverse order.
removed.reverse().forEach(function (index) {
// Array with removed.
orderedBefore.forEach(function (group) {
if (group[0] >= index) {
--group[0];
if (from === to) {
return [0, 0];
}
var fromLink = fromLinks[from];
var toLink = toLinks[to - 1];
var fromIndex = fromLink.getIndex(); // Disconnect the link connected to `fromLink`.
fromLink.disconnect(); // Connect `fromLink` to the right of `toLink`.
if (!toLink) {
fromLink.connect(undefined, fromLinks[0]);
} else {
fromLink.connect(toLink, toLink.next);
}
var toIndex = fromLink.getIndex();
return [fromIndex, toIndex];
});
}
var Result =
/*#__PURE__*/
function () {
function Result(prevList, list, added, removed, changed, maintained, changedBeforeAdded, fixed) {
this.prevList = prevList;
this.list = list;
this.added = added;
this.removed = removed;
this.changed = changed;
this.maintained = maintained;
this.changedBeforeAdded = changedBeforeAdded;
this.fixed = fixed;
}
var __proto = Result.prototype;
Object.defineProperty(__proto, "ordered", {
get: function () {
if (!this.cacheOrdered) {
this.caculateOrdered();
}
}); // Array with removed.
orderedAfter.forEach(function (group) {
if (group[0] >= index) {
--group[0];
return this.cacheOrdered;
},
enumerable: true,
configurable: true
});
Object.defineProperty(__proto, "pureChanged", {
get: function () {
if (!this.cachePureChanged) {
this.caculateOrdered();
}
});
return this.cachePureChanged;
},
enumerable: true,
configurable: true
});
var _loop_1 = function (i) {
var index = added[i]; // Revert to an array where adding is not applied.
__proto.caculateOrdered = function () {
var ordered = orderChanged(this.changedBeforeAdded, this.fixed);
var changed = this.changed;
var pureChanged = [];
this.cacheOrdered = ordered.filter(function (_a, i) {
var from = _a[0],
to = _a[1];
var _b = changed[i],
fromBefore = _b[0],
toBefore = _b[1];
orderedBefore.forEach(function (group) {
if (group[1] >= index) {
--group[1];
if (from !== to) {
pureChanged.push([fromBefore, toBefore]);
return true;
}
});
this.cachePureChanged = pureChanged;
};
for (var i = added.length - 1; i >= 0; --i) {
_loop_1(i);
}
return Result;
}();
added.forEach(function (index) {
orderedAfter.forEach(function (group) {
if (group[0] >= index) {
++group[0];
}
});
});
orderChanged(orderedBefore);
orderChanged(orderedAfter);
/**
*
* @memberof eg.ListDiffer
* @static
* @function
* @param - Previous List <ko> ์ด์ „ ๋ชฉ๋ก </ko>
* @param - List to Update <ko> ์—…๋ฐ์ดํŠธ ํ•  ๋ชฉ๋ก </ko>
* @param - This callback function returns the key of the item. <ko> ์•„์ดํ…œ์˜ ํ‚ค๋ฅผ ๋ฐ˜ํ™˜ํ•˜๋Š” ์ฝœ๋ฐฑ ํ•จ์ˆ˜์ž…๋‹ˆ๋‹ค.</ko>
* @return - Returns the diff between `prevList` and `list` <ko> `prevList`์™€ `list`์˜ ๋‹ค๋ฅธ ์ ์„ ๋ฐ˜ํ™˜ํ•œ๋‹ค.</ko>
* @example
* import { diff } from "@egjs/list-differ";
* // script => eg.ListDiffer.diff
* const result = diff([0, 1, 2, 3, 4, 5], [7, 8, 0, 4, 3, 6, 2, 1], e => e);
* // List before update
* // [1, 2, 3, 4, 5]
* console.log(result.prevList);
* // Updated list
* // [4, 3, 6, 2, 1]
* console.log(result.list);
* // Index array of values added to `list`
* // [0, 1, 5]
* console.log(result.added);
* // Index array of values removed in `prevList`
* // [5]
* console.log(result.removed);
* // An array of index pairs of `prevList` and `list` with different indexes from `prevList` and `list`
* // [[0, 2], [4, 3], [3, 4], [2, 6], [1, 7]]
* console.log(result.changed);
* // The subset of `changed` and an array of index pairs that moved data directly. Indicate an array of absolute index pairs of `ordered`.(Formatted by: Array<[index of prevList, index of list]>)
* // [[4, 3], [3, 4], [2, 6]]
* console.log(result.pureChanged);
* // An array of index pairs to be `ordered` that can synchronize `list` before adding data. (Formatted by: Array<[prevIndex, nextIndex]>)
* // [[4, 1], [4, 2], [4, 3]]
* console.log(result.ordered);
* // An array of index pairs of `prevList` and `list` that have not been added/removed so data is preserved
* // [[0, 2], [4, 3], [3, 4], [2, 6], [1, 7]]
* console.log(result.maintained);
*/
function diff(prevList, list, findKeyCallback) {
var mapClass = SUPPORT_MAP ? Map : findKeyCallback ? HashMap : PolyMap;
var callback = findKeyCallback || function (e) {
return e;
};
var added = [];
var removed = [];
var maintained = [];
var prevKeys = prevList.map(callback);
var keys = list.map(callback);
var prevKeyMap = new mapClass();
var keyMap = new mapClass();
var changedBeforeAdded = [];
var changedAfterAdded = [];
var orderedBeforeAdded = [];
var orderedAfterAdded = [];
changed.forEach(function (_a, i) {
var from = _a[0],
to = _a[1];
var _b = orderedBefore[i],
fromBefore = _b[0],
toBefore = _b[1];
var _c = orderedAfter[i],
fromAfter = _c[0],
toAfter = _c[1]; // There is no change in index.
var fixed = [];
var removedMap = {};
var changed = [];
var addedCount = 0;
var removedCount = 0; // Add prevKeys and keys to the hashmap.
if (fromBefore !== toBefore) {
changedBeforeAdded.push([from, to]);
orderedBeforeAdded.push([fromBefore, toBefore]);
prevKeys.forEach(function (key, prevListIndex) {
prevKeyMap.set(key, prevListIndex);
});
keys.forEach(function (key, listIndex) {
keyMap.set(key, listIndex);
}); // Compare `prevKeys` and `keys` and add them to `removed` if they are not in `keys`.
prevKeys.forEach(function (key, prevListIndex) {
var listIndex = keyMap.get(key); // In prevList, but not in list, it is removed.
if (typeof listIndex === "undefined") {
++removedCount;
removed.push(prevListIndex);
} else {
removedMap[listIndex] = removedCount;
}
}); // Compare `prevKeys` and `keys` and add them to `added` if they are not in `prevKeys`.
if (fromAfter !== toAfter) {
changedAfterAdded.push([from, to]);
orderedAfterAdded.push([fromAfter, toAfter]);
keys.forEach(function (key, listIndex) {
var prevListIndex = prevKeyMap.get(key); // In list, but not in prevList, it is added.
if (typeof prevListIndex === "undefined") {
added.push(listIndex);
++addedCount;
} else {
maintained.push([prevListIndex, listIndex]);
removedCount = removedMap[listIndex] || 0;
changedBeforeAdded.push([prevListIndex - removedCount, listIndex - addedCount]);
fixed.push(listIndex === prevListIndex);
if (prevListIndex !== listIndex) {
changed.push([prevListIndex, listIndex]);
}
}
});
return {
prevList: prevList,
list: list,
added: added,
maintained: maintained,
changed: changed,
changedBeforeAdded: changedBeforeAdded,
changedAfterAdded: changedAfterAdded,
orderedBeforeAdded: orderedBeforeAdded,
orderedAfterAdded: orderedAfterAdded,
removed: removed
};
}); // Sort by ascending order of 'to(list's index).
removed.reverse();
return new Result(prevList, list, added, removed, changed, maintained, changedBeforeAdded, fixed);
}

@@ -237,3 +318,3 @@

/**
* @param - Initializing Data Array <ko> ์ดˆ๊ธฐ ์„ค์ •ํ•  ๋ฐ์ดํ„ฐ ๋ฐฐ์—ด </ko>
* @param - Initializing Data Array. <ko> ์ดˆ๊ธฐ ์„ค์ •ํ•  ๋ฐ์ดํ„ฐ ๋ฐฐ์—ด.</ko>
* @param - This callback function returns the key of the item. <ko> ์•„์ดํ…œ์˜ ํ‚ค๋ฅผ ๋ฐ˜ํ™˜ํ•˜๋Š” ์ฝœ๋ฐฑ ํ•จ์ˆ˜์ž…๋‹ˆ๋‹ค.</ko>

@@ -251,24 +332,18 @@ * @example

* console.log(result.list);
* // Index array of values added to `list`
* // Index array of values added to `list`.
* // [0, 1, 5]
* console.log(result.added);
* // Index array of values removed in `prevList`
* // Index array of values removed in `prevList`.
* // [5]
* console.log(result.removed);
* // Tuple arrays of index of `prevList` and `list` with different indexes from `prevList` and `list`
* // An array of index pairs of `prevList` and `list` with different indexes from `prevList` and `list`.
* // [[0, 2], [4, 3], [3, 4], [2, 6], [1, 7]]
* console.log(result.changed);
* // Tuple arrays of index of `prevList` and `list` with different indexes from `prevList` and `list` before data is added
* // The subset of `changed` and an array of index pairs that moved data directly. Indicate an array of absolute index pairs of `ordered`.(Formatted by: Array<[index of prevList, index of list]>)
* // [[4, 3], [3, 4], [2, 6]]
* console.log(result.changedBeforeAdded);
* // Tuple arrays of index of `prevList` and `list` with different indexes from `prevList` and `list` after data is added
* // [[4, 3], [3, 4], [2, 6], [1, 7]]
* console.log(result.changedAfterAdded);
* // Tuple arrays of `prevIndex` and `nextIndex` to change the order of `prevList` to `list` before data is added.
* console.log(result.pureChanged);
* // An array of index pairs to be `ordered` that can synchronize `list` before adding data. (Formatted by: Array<[prevIndex, nextIndex]>)
* // [[4, 1], [4, 2], [4, 3]]
* console.log(result.orderedBeforeAdded);
* // Tuple arrays of `prevIndex` and `nextIndex` to change the order of `prevList` to `list` after data is added
* // [[7, 3], [7, 4], [6, 7], [5, 7]]
* console.log(result.orderedAfterAdded);
* // Tuple arrays of index of `prevList` and `list` that have not been added/removed so data is preserved
* console.log(result.ordered);
* // An array of index pairs of `prevList` and `list` that have not been added/removed so data is preserved.
* // [[0, 2], [4, 3], [3, 4], [2, 6], [1, 7]]

@@ -286,6 +361,6 @@ * console.log(result.maintained);

/**
* Update list. If there's a change in the list, 'update' event is called.
* @ko ๋ฐ์ดํ„ฐ๋ฅผ ์—…๋ฐ์ดํŠธ๋ฅผ ํ•ฉ๋‹ˆ๋‹ค. ๋ฐ์ดํ„ฐ์— ๋ณ€ํ™”๊ฐ€ ๊ฐ์ง€ ๋˜๋ฉด 'update' ์ด๋ฒคํŠธ๊ฐ€ ํ˜ธ์ถœ๋ฉ๋‹ˆ๋‹ค.
* @param list - Data to update
* @return - Results updated
* Update list.
* @ko ๋ฆฌ์ŠคํŠธ๋ฅผ ์—…๋ฐ์ดํŠธ๋ฅผ ํ•ฉ๋‹ˆ๋‹ค.
* @param - List to update <ko> ์—…๋ฐ์ดํŠธํ•  ๋ฆฌ์ŠคํŠธ </ko>
* @return - Returns the results of an update from `prevList` to `list`.<ko> `prevList`์—์„œ `list`๋กœ ์—…๋ฐ์ดํŠธํ•œ ๊ฒฐ๊ณผ๋ฅผ ๋ฐ˜ํ™˜ํ•œ๋‹ค. </ko>
*/

@@ -292,0 +367,0 @@

/*
Copyright (c) 2019-present NAVER Corp.
Copyright (c) NAVER Corp.
name: @egjs/list-differ

@@ -7,5 +7,5 @@ license: MIT

repository: https://github.com/naver/egjs-list-differ
version: 0.0.1
version: 0.1.0
*/
!function(t,n){"object"==typeof exports&&"undefined"!=typeof module?module.exports=n():"function"==typeof define&&define.amd?define(n):((t=t||self).eg=t.eg||{},t.eg.ListDiffer=n())}(this,function(){"use strict";var k=function(){function t(){this.keys=[],this.values=[]}var n=t.prototype;return n.has=function(t){return-1<this.keys.indexOf(t)},n.get=function(t){return this.values[this.keys.indexOf(t)]},n.set=function(t,n){var e=this.keys,r=this.values,i=e.indexOf(t),o=-1===i?e.length:i;e[o]=t,r[o]=n},t}(),A=function(){function t(){this.object={}}var n=t.prototype;return n.get=function(t){return this.object[t]},n.set=function(t,n){this.object[t]=n},n.has=function(t){return t in this.object},t}(),j="function"==typeof Map;function x(f){f.forEach(function(t,n){var e=t[0],r=t[1],i=f.slice(n+1).filter(function(t){return e>t[0]&&r<t[1]&&e<=r}).length;f[n][1]+=i,r+=i;for(var o=n+1;o<f.length;++o)r<=f[o][0]&&f[o][0]<e&&++f[o][0]})}function r(t,n,e){var r=j?Map:e?A:k,i=e||function(t){return t},o=[],f=[],u=[],c=[],s=t.map(i),a=n.map(i),h=new r,d=new r;s.forEach(function(t,n){h.set(t,n)}),a.forEach(function(t,n){d.set(t,n),h.has(t)||o.push(n)}),s.forEach(function(t,n){var e=d.get(t);void 0===e?f.push(n):(u.push([n,e]),n!==e&&c.push([n,e]))}),c.sort(function(t,n){return t[1]>n[1]?1:-1}),u.sort(function(t,n){return t[1]>n[1]?1:-1});var p=c.map(function(t){return[t[0],t[1]]}),l=c.map(function(t){return[t[0],t[1]]});f.reverse().forEach(function(n){p.forEach(function(t){t[0]>=n&&--t[0]}),l.forEach(function(t){t[0]>=n&&--t[0]})});for(var v=function(t){var n=o[t];p.forEach(function(t){t[1]>=n&&--t[1]})},g=o.length-1;0<=g;--g)v(g);o.forEach(function(n){l.forEach(function(t){t[0]>=n&&++t[0]})}),x(p),x(l);var y=[],E=[],m=[],b=[];return c.forEach(function(t,n){var e=t[0],r=t[1],i=p[n],o=i[0],f=i[1],u=l[n],c=u[0],s=u[1];o!==f&&(y.push([e,r]),m.push([o,f])),c!==s&&(E.push([e,r]),b.push([c,s]))}),{prevList:t,list:n,added:o,maintained:u,changed:c,changedBeforeAdded:y,changedAfterAdded:E,orderedBeforeAdded:m,orderedAfterAdded:b,removed:f}}var t=function(){function t(t,n){void 0===t&&(t=[]),this.findKeyCallback=n,this.list=[].slice.call(t)}return t.prototype.update=function(t){var n=[].slice.call(t),e=r(this.list,n,this.findKeyCallback);return this.list=n,e},t}();return t.diff=r,t});
!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?module.exports=t():"function"==typeof define&&define.amd?define(t):((e=e||self).eg=e.eg||{},e.eg.ListDiffer=t())}(this,function(){"use strict";var x=function(){function e(){this.keys=[],this.values=[]}var t=e.prototype;return t.get=function(e){return this.values[this.keys.indexOf(e)]},t.set=function(e,t){var n=this.keys,i=this.values,r=n.indexOf(e),c=-1===r?n.length:r;n[c]=e,i[c]=t},e}(),b=function(){function e(){this.object={}}var t=e.prototype;return t.get=function(e){return this.object[e]},t.set=function(e,t){this.object[e]=t},e}(),m="function"==typeof Map,r=function(){function e(){}var t=e.prototype;return t.connect=function(e,t){this.prev=e,this.next=t,e&&(e.next=this),t&&(t.prev=this)},t.disconnect=function(){var e=this.prev,t=this.next;e&&(e.next=t),t&&(t.prev=e)},t.getIndex=function(){for(var e=this,t=-1;e;)e=e.prev,++t;return t},e}();var O=function(){function e(e,t,n,i,r,c,o,u){this.prevList=e,this.list=t,this.added=n,this.removed=i,this.changed=r,this.maintained=c,this.changedBeforeAdded=o,this.fixed=u}var t=e.prototype;return Object.defineProperty(t,"ordered",{get:function(){return this.cacheOrdered||this.caculateOrdered(),this.cacheOrdered},enumerable:!0,configurable:!0}),Object.defineProperty(t,"pureChanged",{get:function(){return this.cachePureChanged||this.caculateOrdered(),this.cachePureChanged},enumerable:!0,configurable:!0}),t.caculateOrdered=function(){var e=function(e,n){var u=[],s=[];return e.forEach(function(e){var t=e[0],n=e[1],i=new r;u[t]=i,s[n]=i}),u.forEach(function(e,t){e.connect(u[t-1])}),e.filter(function(e,t){return!n[t]}).map(function(e,t){var n=e[0],i=e[1];if(n===i)return[0,0];var r=u[n],c=s[i-1],o=r.getIndex();return r.disconnect(),c?r.connect(c,c.next):r.connect(void 0,u[0]),[o,r.getIndex()]})}(this.changedBeforeAdded,this.fixed),u=this.changed,s=[];this.cacheOrdered=e.filter(function(e,t){var n=e[0],i=e[1],r=u[t],c=r[0],o=r[1];if(n!==i)return s.push([c,o]),!0}),this.cachePureChanged=s},e}();function i(e,t,n){var i=m?Map:n?b:x,r=n||function(e){return e},c=[],o=[],u=[],s=e.map(r),f=t.map(r),a=new i,h=new i,d=[],p=[],v={},l=[],g=0,y=0;return s.forEach(function(e,t){a.set(e,t)}),f.forEach(function(e,t){h.set(e,t)}),s.forEach(function(e,t){var n=h.get(e);void 0===n?(++y,o.push(t)):v[n]=y}),f.forEach(function(e,t){var n=a.get(e);void 0===n?(c.push(t),++g):(u.push([n,t]),y=v[t]||0,d.push([n-y,t-g]),p.push(t===n),n!==t&&l.push([n,t]))}),o.reverse(),new O(e,t,c,o,l,u,d,p)}var e=function(){function e(e,t){void 0===e&&(e=[]),this.findKeyCallback=t,this.list=[].slice.call(e)}return e.prototype.update=function(e){var t=[].slice.call(e),n=i(this.list,t,this.findKeyCallback);return this.list=t,n},e}();return e.diff=i,e});
//# sourceMappingURL=list-differ.pkgd.min.js.map
{
"name": "@egjs/list-differ",
"version": "0.0.1",
"version": "0.1.0",
"description": "A module that checks the diff when values are added, removed, or changed in an array.",

@@ -50,2 +50,3 @@ "main": "./dist/list-differ.js",

"@daybrush/jsdoc": "^0.3.7",
"@egjs/build-helper": "0.0.5",
"@egjs/release-helper": "0.0.3",

@@ -59,9 +60,4 @@ "@types/jest": "^24.0.11",

"print-coveralls": "^1.2.2",
"print-sizes": "0.0.4",
"print-sizes": "^0.1.0",
"rollup": "^1.8.0",
"rollup-plugin-node-resolve": "^4.1.0",
"rollup-plugin-prototype-minify": "^1.0.5",
"rollup-plugin-replace": "^2.1.1",
"rollup-plugin-typescript": "^1.0.1",
"rollup-plugin-uglify": "^6.0.2",
"sinon": "^7.3.1",

@@ -68,0 +64,0 @@ "ts-jest": "^24.0.1",

@@ -1,7 +0,13 @@

# list-differ [![npm version](https://badge.fury.io/js/%40egjs%2Flist-differ.svg)](https://badge.fury.io/js/%40egjs%2Flist-differ) [![Build Status](https://travis-ci.org/naver/egjs-list-differ.svg?branch=master)](https://travis-ci.org/naver/egjs-list-differ) [![Coverage Status](https://coveralls.io/repos/github/naver/egjs-list-differ/badge.svg?branch=master)](https://coveralls.io/github/naver/egjs-list-differ?branch=master)
A module that checks the diff when values are added, removed, or changed in an array.
<p align="middle"><img src="./demo/images/logo.png"/></p>
<h2 align="middle">@egjs/list-differ</h2>
<p align="middle"><a href="https://www.npmjs.com/package/@egjs/list-differ" target="_blank"><img src="https://img.shields.io/npm/v/@egjs/list-differ.svg?style=flat-square&color=007acc&label=version&logo=NPM" alt="version" /></a> <a href="https://travis-ci.org/naver/egjs-list-differ" target="_blank"><img alt="Travis (.org)" src="https://img.shields.io/travis/naver/egjs-list-differ.svg?style=flat-square&label=build&logo=travis%20ci" /></a> <a href="https://coveralls.io/github/naver/egjs-list-differ?branch=master&style=flat-square" target="_blank"><img alt="Coveralls github" src="https://img.shields.io/coveralls/github/naver/egjs-list-differ.svg?style=flat-square&label=%E2%9C%85%20coverage"></a> <a href="https://www.npmjs.com/package/@egjs/list-differ" target="_blank"><img src="https://img.shields.io/npm/dm/@egjs/list-differ.svg?style=flat-square&label=%E2%AC%87%20downloads&color=08CE5D" alt="npm downloads per month"></a> <a href="https://github.com/naver/egjs-list-differ/blob/master/LICENSE" target="_blank"><img alt="GitHub" src="https://img.shields.io/github/license/naver/egjs-list-differ.svg?style=flat-square&label=%F0%9F%93%9C%20license&color=08CE5D"></a></p>
## Installation
<p align="middle">โž•โž–๐Ÿ”„ A module that checks the diff when values are added, removed, or changed in an array.</p>
## โš™๏ธ Installation
```sh

@@ -11,12 +17,24 @@ $ npm i @egjs/list-differ

## Related Projects
* [@egjs/children-differ]()
* [@egjs/react-children-differ]()
* [@egjs/ng-children-differ]()
* [@egjs/vue-children-differ]()
```html
<script src="//naver.github.io/egjs-list-differ/release/latest/dist/list-differ.min.js"></script>
```
## How to use
## ๐Ÿ“– Documentation
* See [**Documentation**](https://naver.github.io/egjs-list-differ/release/latest/doc/index.html) page.
* [Introducing ListDiffer to track changes in data and track changes]()([ํ•œ๊ตญ์–ด]())
* [How to Make Cross Framework Component]()([ํ•œ๊ตญ์–ด]())
## ๐Ÿ“ฆ Packages
|Package|Version|Description|
|:-----:|:-----:|:-----:|
|[**@egjs/children-differ**](https://github.com/naver/egjs-children-differ)|<a href="https://www.npmjs.com/package/@egjs/children-differ" target="_blank"><img src="https://img.shields.io/npm/v/@egjs/children-differ.svg?style=flat-square&color=007acc&label=%F0%9F%94%96" alt="version" /></a>|A module that checks diff in DOM children.|
|[**@egjs/react-children-differ**](https://github.com/naver/egjs-children-differ/blob/master/packages/react-children-differ/README.md)|<a href="https://www.npmjs.com/package/@egjs/react-children-differ" target="_blank"><img src="https://img.shields.io/npm/v/@egjs/react-children-differ.svg?style=flat-square&color=00d8ff&label=%F0%9F%94%96" alt="version" /></a>|<img width="15" src="https://naver.github.io/egjs-flicking/images/react.svg" valign="middle" alt="React" /> [React](https://reactjs.org/) port of @egjs/children-differ|
|[**@egjs/react-children-differ**](https://github.com/naver/egjs-children-differ/blob/master/packages/react-children-differ/README.md)|<a href="https://www.npmjs.com/package/@egjs/react-children-differ" target="_blank"><img src="https://img.shields.io/npm/v/@egjs/react-children-differ.svg?style=flat-square&color=dd0031&label=%F0%9F%94%96" alt="version" /></a>|<img width="15" src="https://naver.github.io/egjs-flicking/images/angular.svg" valign="middle" alt="Angular" /> [Angular](https://angular.io/) port of @egjs/children-differ|
|[**@egjs/vue-children-differ**](https://github.com/naver/egjs-children-differ/blob/master/packages/vue-children-differ/README.md)|<a href="https://www.npmjs.com/package/@egjs/vue-children-differ" target="_blank"><img src="https://img.shields.io/npm/v/@egjs/vue-children-differ.svg?style=flat-square&color=42b883&label=%F0%9F%94%96" alt="version" /></a>|<img width="15" src="https://naver.github.io/egjs-flicking/images/vue.svg" valign="middle" alt="Vue.js" /> [Vue.js](https://vuejs.org/v2/guide/index.html) port of @egjs/children-differ|
## ๐Ÿƒ How to use
### checks the diff in array
```js
import ListDiffer from "@egjs/list-differ";
import ListDiffer, { diff } from "@egjs/list-differ";

@@ -26,2 +44,3 @@ // script => eg.ListDiffer

const differ = new ListDiffer([1, 2, 3, 4, 5, 6, 7], e => e);
// const result = diff([1, 2, 3, 4, 5, 6, 7], [4, 3, 6, 2, 1, 7], e => e);
const result = differ.update([4, 3, 6, 2, 1, 7]);

@@ -40,18 +59,12 @@ // List before update

console.log(result.removed);
// Tuple arrays of index of `prevList` and `list` with different indexes from `prevList` and `list`
// An array of index pairs of `prevList` and `list` with different indexes from `prevList` and `list`
// [[3, 0], [2, 1], [1, 3], [0, 4], [6, 5]]
console.log(result.changed);
// Tuple arrays of index of `prevList` and `list` with different indexes from `prevList` and `list` before data is added
// The subset of `changed` and an array of index pairs that moved data directly. Indicate an array of absolute index pairs of `ordered`.(Formatted by: Array<[index of prevList, index of list]>)
// [[3, 0], [2, 1], [1, 3]]
console.log(result.changedBeforeAdded);
// Tuple arrays of index of `prevList` and `list` with different indexes from `prevList` and `list` after data is added
// [[3, 0], [2, 1], [1, 3], [0, 4]]
console.log(result.changedAfterAdded);
// Tuple arrays of `prevIndex` and `nextIndex` to change the order of `prevList` to `list` before data is added.
console.log(result.pureChanged);
// An array of index pairs to be `ordered` that can synchronize `list` before adding data. (Formatted by: Array<[prevIndex, nextIndex]>)
// [[3, 0], [3, 1], [3, 2]]
console.log(result.orderedBeforeAdded);
// Tuple arrays of `prevIndex` and `nextIndex` to change the order of `prevList` to `list` after data is added
// [[4, 0], [4, 1], [3, 4], [2, 4]]
console.log(result.orderedAfterAdded);
// Tuple arrays of index of `prevList` and `list` that have not been added/removed so data is preserved
console.log(result.ordered);
// An array of index pairs of `prevList` and `list` that have not been added/removed so data is preserved
// [[3, 0], [2, 1], [1, 3], [0, 4], [6, 5]]

@@ -61,42 +74,31 @@ console.log(result.maintained);

### What is changed?
Tuple arrays of index of `prevList` and `list` with different indexes from `prevList` and `list`
* **changed**: An array of index pairs of `prevList` and `list` with different indexes from `prevList` and `list`
* **pureChanged**: The subset of `changed` and an array of index pairs that moved data directly. Indicate an array of absolute index pairs of `ordered`.(Formatted by: Array<[index of prevList, index of list]>)
||changed:|
|---:|---|
||[[3, 0], [2, 1], [1, 3], [0, 4], [6, 5]]|
|prevList|![prev_list](./images/changed_prev_list.png) |
|list|![list](./images/changed_list.png)|
||**changed**|**pureChanged:**|
|---:|---|---|
||[[3, 0], [2, 1], [1, 3], [0, 4], [6, 5]]|[[[3, 0], [2, 1], [1, 3]]||
|prevList|![prev_list](./images/changed_prev_list.png) |![](./images/changed_before_prev_list.png)|
|process|<p align="center">-</p>|![](./images/changed_before_animation.gif)|
|list|![](./images/changed_list.png)|![](./images/changed_before_list.png)|
### What is beforeAdded, afteradded?
### What is ordered?
An array of index pairs to be `ordered` that can synchronize `list` before adding data. (Formatted by: Array<[prevIndex, nextIndex]>)
* **beforeAdded**: Obtain a minimum of `changed` in time before data is `added`
* **changedBeforeAdded**: Tuple arrays of index of `prevList` and `list` with different indexes from `prevList` and `list` before data is added
* **orderedBeforeAdded**: Tuple arrays of `prevIndex` and `nextIndex` to change the order of `prevList` to `list` before data is added.
* **afterAdded**: Obtain a minimum of `changed` in time after data is `added`
* **changedAfterAdded**: Tuple arrays of index of `prevList` and `list` with different indexes from `prevList` and `list` after data is added
* **orderedAfterAdded**: Tuple arrays of `prevIndex` and `nextIndex` to change the order of `prevList` to `list` after data is added.
||removed -> ordered -> added|
|---:|---|
|prevList|![](./images/prev_list.png)|
|removed<br/>[5, 4]|![](./images/removed.png)|
|ordered|[[3, 0], [3, 1], [3, 2]]|
||![](./images/ordered_before_added.gif)|
|ordered[0]<br/>[3 => 0]| ![](./images/ordered_before_ordered0.png)|
|ordered[1]<br/>[3 => 1]| ![](./images/ordered_before_ordered1.png)|
|ordered[2]<br/>[3 => 2]| ![](./images/ordered_before_ordered2.png)|
|added<br/>[2]|![](./images/ordered_before_added.png)|
|list|![](./images/list.png)|
||beforeAdded||afterAdded|
|---:|---|---:|---|
||removed -> ordered -> added||removed -> added -> ordered|
|prevList|![](./images/prev_list.png)|prevList|![](./images/prev_list.png)|
|removed<br/>[5, 4]|![](./images/removed.png)|removed<br/>[5, 4]|![](./images/removed.png)|
|||added<br/>[2]|![](./images/ordered_after_added.png)|
||**orderedBeforeAdded:**||**orderedAfterAdded:**|
||[[3, 0], [3, 1], [3, 2]]||[[4, 0], [4, 1], [3, 4], [2, 4]]|
|ordered0<br/>[3 => 0]| ![](./images/ordered_before_ordered0.png)|ordered0<br/>[4 => 0]|![](./images/ordered_after_ordered0.png)|
|ordered1<br/>[3 => 1]| ![](./images/ordered_before_ordered1.png)|ordered1<br/>[4 => 1]|![](./images/ordered_after_ordered1.png)|
|ordered2<br/>[3 => 2]| ![](./images/ordered_before_ordered2.png)|ordered2<br/>[3 => 4]|![](./images/ordered_after_ordered2.png)|
|||ordered3<br/>[2 => 4]|![](./images/ordered_after_ordered3.png)|
|added<br/>[2]|![](./images/ordered_before_added.png)|||
|list|![](./images/list.png)|list|![](./images/list.png)|
||**changedBeforeAdded:**||**chanedAfterAdded:**|
||[[3, 0], [2, 1], [1, 3]]||[[3, 0], [2, 1], [1, 3], [0, 4]]|
|prevList|![](./images/changed_before_prev_list.png)|prevList|![](./images/changed_after_prev_list.png)|
|process|![](./images/changed_before_animation.gif)|process|![](./images/changed_after_animation.gif)|
|list|![](./images/changed_before_list.png)|list|![](./images/changed_after_list.png)|
## Examples for (prevList => list)
## Data Sync Examples
```js

@@ -107,8 +109,10 @@ import ListDiffer, { diff } from "@egjs/list-differ";

const list = [4, 3, 6, 2, 1, 7];
// const differ = new ListDiffer(prevList, e => e);
// const result = differ.update(list);
const result = diff(prevList, list, e => e);
```
### prevList => (removed => orderedBeforeAdded => added) => list
### removed => ordered => added
||removed => orderedBeforeAdded => added|
||removed => ordered => added|
|---|---|

@@ -119,2 +123,3 @@ |prevList|![](./images/prev_list.png)|

* Synchronize List
```js

@@ -125,5 +130,5 @@ const nextList = prevList.slice();

});
result.orderedBeforeAdded.forEach(([from, to], i) => {
result.ordered.forEach(([from, to], i) => {
nextList.splice(from, 1);
nextList.splice(to, 0, list[result.changedBeforeAdded[i][1]]);
nextList.splice(to, 0, list[result.pureChanged[i][1]]);
});

@@ -136,40 +141,38 @@ result.added.forEach(index => {

```
### prevList => (removed => added => orderdAfterAdded) => list
||removed => added => orderdAfterAdded|
|---|---|
|prevList|![](./images/prev_list.png)|
|process|![](./images/changed_after_animation.gif)|
|list|![](./images/list.png)|
* Synchronize DOM
```js
const nextList = prevList.slice();
const parentElement = document.querySelector(".parent");
const children = parentElement.children;
result.removed.forEach(index => {
nextList.splice(index, 1);
children[index].remove();
});
result.ordered.forEach(([from, to]) => {
parentElement.insertBefore(children[from], children[from < to ? to + 1 : to]);
});
result.added.forEach(index => {
nextList.splice(index, 0, list[index]);
parentElement.insertBefore(document.createElement("div"), children[index]);
});
result.orderedAfterAdded.forEach(([from, to], i) => {
nextList.splice(from, 1);
nextList.splice(to, 0, list[result.changedAfterAdded[i][1]]);
});
// `nextList` is the same as `list`.
console.log(nextList);
```
### prevList => (maintained => added) => list
||maintained => added|
### removed => maintaind => added
||maintaind => added|
|---|---|
|prevList|![](./images/prev_list.png)|
|process|![](./images/maintained_added.gif)|
|process|![](./images/maintained_with_added.gif)|
|list|![](./images/list.png)|
* Synchronize List
```js
const nextList = [];
const nextList: number[] = [];
result.removed.forEach(index => {
// There is a remove operation for the index.
// prevList[index];
});
result.maintained.forEach(([from, to]) => {
nextList.push(list[to]);
nextList[to] = list[to];
});
result.added.forEach(index => {
nextList.splice(index, 0, list[index]);
nextList[index] = list[index];
});

@@ -179,28 +182,29 @@ // `nextList` is the same as `list`.

```
### prevList => (added => maintaind) => list
||added => maintaind|
|---|---|
|prevList|![](./images/prev_list.png)|
|process|![](./images/added_maintained.gif)|
|list|![](./images/list.png)|
* Synchronize DOM
```js
const nextList = [];
result.added.forEach(index => {
nextList.push(list[index]);
const parentElement = document.querySelector(".parent");
const children = parentElement.children;
const prevChildren: Element[] = [].slice.call(parentElement.children);
result.removed.forEach(index => {
prevChildren[index].remove();
});
result.maintained.forEach(([from, to]) => {
nextList.splice(to, 0, list[to]);
parentElement.appendChild(prevChildren[from]);
});
// `nextList` is the same as `list`.
console.log(nextList);
result.added.forEach(index => {
parentElement.insertBefore(document.createElement("div"), children[index]);
});
```
## Bug Report
If you find a bug, please report to us opening a new [Issues](https://github.com/naver/egjs-list-differ/issues) on GitHub.
## ๐Ÿ™Œ Contributing
See [CONTRIBUTING.md](https://github.com/naver/egjs-list-differ/blob/master/CONTRIBUTING.md).
## ๐Ÿ“ Feedback
Please file an [Issue](https://github.com/naver/egjs-list-differ/issues).
## License
egjs-list-differ is released under the [MIT license](http://naver.github.io/egjs/license.txt).
## ๐Ÿ“œ License
@egjs/list-differ is released under the [MIT license](https://github.com/naver/egjs-list-differ/blob/master/LICENSE).

@@ -207,0 +211,0 @@ ```

const buildHelper = require("./config/config");
const buildHelper = require("@egjs/build-helper");
const defaultOptions = {

@@ -4,0 +4,0 @@ name: "eg.ListDiffer",

@@ -9,6 +9,3 @@ export default class HashMap<T> {

}
public has(key: number | string): boolean {
return key in this.object;
}
};

@@ -12,3 +12,3 @@ import { DiffResult, ListFormat } from "./types";

/**
* @param - Initializing Data Array <ko> ์ดˆ๊ธฐ ์„ค์ •ํ•  ๋ฐ์ดํ„ฐ ๋ฐฐ์—ด </ko>
* @param - Initializing Data Array. <ko> ์ดˆ๊ธฐ ์„ค์ •ํ•  ๋ฐ์ดํ„ฐ ๋ฐฐ์—ด.</ko>
* @param - This callback function returns the key of the item. <ko> ์•„์ดํ…œ์˜ ํ‚ค๋ฅผ ๋ฐ˜ํ™˜ํ•˜๋Š” ์ฝœ๋ฐฑ ํ•จ์ˆ˜์ž…๋‹ˆ๋‹ค.</ko>

@@ -26,24 +26,18 @@ * @example

* console.log(result.list);
* // Index array of values added to `list`
* // Index array of values added to `list`.
* // [0, 1, 5]
* console.log(result.added);
* // Index array of values removed in `prevList`
* // Index array of values removed in `prevList`.
* // [5]
* console.log(result.removed);
* // Tuple arrays of index of `prevList` and `list` with different indexes from `prevList` and `list`
* // An array of index pairs of `prevList` and `list` with different indexes from `prevList` and `list`.
* // [[0, 2], [4, 3], [3, 4], [2, 6], [1, 7]]
* console.log(result.changed);
* // Tuple arrays of index of `prevList` and `list` with different indexes from `prevList` and `list` before data is added
* // The subset of `changed` and an array of index pairs that moved data directly. Indicate an array of absolute index pairs of `ordered`.(Formatted by: Array<[index of prevList, index of list]>)
* // [[4, 3], [3, 4], [2, 6]]
* console.log(result.changedBeforeAdded);
* // Tuple arrays of index of `prevList` and `list` with different indexes from `prevList` and `list` after data is added
* // [[4, 3], [3, 4], [2, 6], [1, 7]]
* console.log(result.changedAfterAdded);
* // Tuple arrays of `prevIndex` and `nextIndex` to change the order of `prevList` to `list` before data is added.
* console.log(result.pureChanged);
* // An array of index pairs to be `ordered` that can synchronize `list` before adding data. (Formatted by: Array<[prevIndex, nextIndex]>)
* // [[4, 1], [4, 2], [4, 3]]
* console.log(result.orderedBeforeAdded);
* // Tuple arrays of `prevIndex` and `nextIndex` to change the order of `prevList` to `list` after data is added
* // [[7, 3], [7, 4], [6, 7], [5, 7]]
* console.log(result.orderedAfterAdded);
* // Tuple arrays of index of `prevList` and `list` that have not been added/removed so data is preserved
* console.log(result.ordered);
* // An array of index pairs of `prevList` and `list` that have not been added/removed so data is preserved.
* // [[0, 2], [4, 3], [3, 4], [2, 6], [1, 7]]

@@ -59,6 +53,6 @@ * console.log(result.maintained);

/**
* Update list. If there's a change in the list, 'update' event is called.
* @ko ๋ฐ์ดํ„ฐ๋ฅผ ์—…๋ฐ์ดํŠธ๋ฅผ ํ•ฉ๋‹ˆ๋‹ค. ๋ฐ์ดํ„ฐ์— ๋ณ€ํ™”๊ฐ€ ๊ฐ์ง€ ๋˜๋ฉด 'update' ์ด๋ฒคํŠธ๊ฐ€ ํ˜ธ์ถœ๋ฉ๋‹ˆ๋‹ค.
* @param list - Data to update
* @return - Results updated
* Update list.
* @ko ๋ฆฌ์ŠคํŠธ๋ฅผ ์—…๋ฐ์ดํŠธ๋ฅผ ํ•ฉ๋‹ˆ๋‹ค.
* @param - List to update <ko> ์—…๋ฐ์ดํŠธํ•  ๋ฆฌ์ŠคํŠธ </ko>
* @return - Returns the results of an update from `prevList` to `list`.<ko> `prevList`์—์„œ `list`๋กœ ์—…๋ฐ์ดํŠธํ•œ ๊ฒฐ๊ณผ๋ฅผ ๋ฐ˜ํ™˜ํ•œ๋‹ค. </ko>
*/

@@ -65,0 +59,0 @@ public update(list: ListFormat<T>): DiffResult<T> {

export default class PolyMap<T> {
private keys: T[] = [];
private values: number[] = [];
public has(key: T): boolean {
return this.keys.indexOf(key) > -1;
}
public get(key: T): number {

@@ -8,0 +5,0 @@ return this.values[this.keys.indexOf(key)];

export interface MapInteface<T, U> {
get(key: T): U;
get(key: T): U | undefined;
set(key: T, value: U): any;
has(key: T): boolean;
}

@@ -18,8 +17,6 @@ export type MapConstructor<T, U> = new () => MapInteface <T, U>;

* @property - Index array of values removed in `prevList` <ko>`prevList`์—์„œ ์ œ๊ฑฐ๋˜๋Š” ๋ฐ์ดํ„ฐ์˜ ์ธ๋ฑ์Šค ๋ฐฐ์—ด</ko>
* @property - Tuple arrays of index of `prevList` and `list` with different indexes from `prevList` and `list`<ko>์ด์ „ ๋ฆฌ์ŠคํŠธ`prevList`์™€ ์ง€๊ธˆ ๋ฆฌ์ŠคํŠธ`list`์—์„œ ์œ„์น˜๊ฐ€ ๋‹ค๋ฅธ `prevList`์™€ `list`์˜ ์ธ๋ฑ์Šค ๋ฐฐ์—ด๋“ค</ko>
* @property - Tuple arrays of index of `prevList` and `list` with different indexes from `prevList` and `list` before data is added<ko>๋ฐ์ดํ„ฐ๋ฅผ ์ถ”๊ฐ€๋˜๊ธฐ ์ „ `prevList`์™€ `list`์—์„œ ์œ„์น˜๊ฐ€ ๋‹ค๋ฅธ `prevList`์™€ `list`์˜ ์ธ๋ฑ์Šค ๋ฐฐ์—ด๋“ค</ko>
* @property - Tuple arrays of index of `prevList` and `list` with different indexes from `prevList` and `list` after data is added<ko>๋ฐ์ดํ„ฐ๋ฅผ ์ถ”๊ฐ€๋œ ํ›„ `prevList`์™€ `list`์—์„œ ์œ„์น˜๊ฐ€ ๋‹ค๋ฅธ `prevList`์™€ `list`์˜ ์ธ๋ฑ์Šค ๋ฐฐ์—ด๋“ค</ko>
* @property - Tuple arrays of `prevIndex` and `nextIndex` to change the order of `prevList` to `list` before data is added<ko>๋ฐ์ดํ„ฐ๋ฅผ ์ถ”๊ฐ€ํ•˜๊ธฐ ์ „ `prevList`๊ฐ€ `list`๋กœ ๋ฐ”๋€Œ๋„๋ก ์ˆœ์„œ๋ฅผ ๋ณ€๊ฒฝํ•˜๋Š” `prevIndex`์™€ `index`์˜ ๋ฐฐ์—ด๋“ค</ko>
* @property - Tuple arrays of `prevIndex` and `nextIndex` to change the order of `prevList` to `list` after data is added<ko>๋ฐ์ดํ„ฐ๋ฅผ ์ถ”๊ฐ€๋œ ํ›„ `prevList`๊ฐ€ `list`๋กœ ๋ฐ”๋€Œ๋„๋ก ์ˆœ์„œ๋ฅผ ๋ณ€๊ฒฝํ•˜๋Š” `prevIndex`์™€ `index`์˜ ๋ฐฐ์—ด๋“ค</ko>
* @property - Tuple arrays of index of `prevList` and `list` that have not been added/removed so data is preserved<ko>์ถ”๊ฐ€/์‚ญ์ œ ๋˜์ง€ ์•Š์•„ ๋ฐ์ดํ„ฐ๊ฐ€ ๋ณด์กด๋œ `prevList`์™€ `list`์˜ ์ธ๋ฑ์Šค ๋ฐฐ์—ด๋“ค</ko>
* @property - An array of index pairs of `prevList` and `list` with different indexes from `prevList` and `list`<ko>์ด์ „ ๋ฆฌ์ŠคํŠธ`prevList`์™€ ์ง€๊ธˆ ๋ฆฌ์ŠคํŠธ`list`์—์„œ ์œ„์น˜๊ฐ€ ๋‹ค๋ฅธ `prevList`์™€ `list`์˜ ์ธ๋ฑ์Šค ๋ฐฐ์—ด๋“ค</ko>
* @property - An array of index pairs to be `ordered` that can synchronize `list` before adding data. (Formatted by: Array<[prevIndex, nextIndex]>) <ko>๋ฐ์ดํ„ฐ๋ฅผ ์ถ”๊ฐ€ํ•˜๊ธฐ ์ „ `list`๋ฅผ ๋™๊ธฐํ™”ํ•  ์ˆ˜ ์žˆ๋Š” ์ •๋ ฌ๋˜๋Š” ์ธ๋ฑ์Šค ๋ฐฐ์—ด๋“ค(ํ˜•ํƒœ: Array<[์ด์ „ ์ธ๋ฑ์Šค, ๋‹ค์Œ ์ธ๋ฑ์Šค]>) </ko>
* @property - The subset of `changed` and an array of index pairs that moved data directly. Indicate an array of absolute index pairs of `ordered`.(Formatted by: Array<[index of prevList, index of list]>)<ko>`changed`์˜ ๋ถ€๋ถ„์ง‘ํ•ฉ์œผ๋กœ ๋ฐ์ดํ„ฐ๋ฅผ ์ถ”๊ฐ€ํ•˜๊ธฐ ์ „ ์ง์ ‘ ์›€์ง์ด๋Š” ๋ฐ์ดํ„ฐ์˜ ์ธ๋ฑ์Šค ๋ฐฐ์—ด๋“ค. `ordered`์˜ ์ ˆ๋Œ€์ ์ธ ์ธ๋ฑ์Šค ๋ฐฐ์—ด๋“ค์„ ๋‚˜ํƒ€๋‚ด๊ธฐ๋„ ํ•œ๋‹ค. (ํ˜•ํƒœ: Array<[prevList์ธ๋ฑ์Šค, list์ธ๋ฑ์Šค]>)</ko>
* @property - An array of index pairs of `prevList` and `list` that have not been added/removed so data is preserved<ko>์ถ”๊ฐ€/์‚ญ์ œ ๋˜์ง€ ์•Š์•„ ๋ฐ์ดํ„ฐ๊ฐ€ ๋ณด์กด๋œ `prevList`์™€ `list`์˜ ์ธ๋ฑ์Šค ๋ฐฐ์—ด๋“ค</ko>
*/

@@ -32,8 +29,6 @@ export interface DiffResult<T> {

changed: number[][];
changedBeforeAdded: number[][];
changedAfterAdded: number[][];
orderedBeforeAdded: number[][];
orderedAfterAdded: number[][];
ordered: number[][];
pureChanged: number[][];
maintained: number[][];
}
import { MapInteface, DiffResult } from "./types";
import PolyMap from "./PolyMap";
import HashMap from "./HashMap";
import {SUPPORT_MAP} from "./consts";
import { SUPPORT_MAP } from "./consts";
import Result from "./Result";
export function orderChanged(changed: number[][]) {
changed.forEach(([from, to], i)=> {
// Index Count due to be pushed back
const changedOffset = changed.slice(i + 1).filter(group => {
return from > group[0] && to < group[1] && from <= to;
}).length;
changed[i][1] += changedOffset;
to += changedOffset;
// After the index changes, the index of 'from'(prevList's list) is pushed by one space.
for (let j = i + 1; j < changed.length; ++j) {
if (to <= changed[j][0] && changed[j][0] < from) {
// pushed index
++changed[j][0];
}
}
});
}
/**
*
* @memberof eg.ListDiffer
* @static
* @function
* @param - Previous List <ko> ์ด์ „ ๋ชฉ๋ก </ko>
* @param - List to Update <ko> ์—…๋ฐ์ดํŠธ ํ•  ๋ชฉ๋ก </ko>
* @param - This callback function returns the key of the item. <ko> ์•„์ดํ…œ์˜ ํ‚ค๋ฅผ ๋ฐ˜ํ™˜ํ•˜๋Š” ์ฝœ๋ฐฑ ํ•จ์ˆ˜์ž…๋‹ˆ๋‹ค.</ko>
* @return - Returns the diff between `prevList` and `list` <ko> `prevList`์™€ `list`์˜ ๋‹ค๋ฅธ ์ ์„ ๋ฐ˜ํ™˜ํ•œ๋‹ค.</ko>
* @example
* import { diff } from "@egjs/list-differ";
* // script => eg.ListDiffer.diff
* const result = diff([0, 1, 2, 3, 4, 5], [7, 8, 0, 4, 3, 6, 2, 1], e => e);
* // List before update
* // [1, 2, 3, 4, 5]
* console.log(result.prevList);
* // Updated list
* // [4, 3, 6, 2, 1]
* console.log(result.list);
* // Index array of values added to `list`
* // [0, 1, 5]
* console.log(result.added);
* // Index array of values removed in `prevList`
* // [5]
* console.log(result.removed);
* // An array of index pairs of `prevList` and `list` with different indexes from `prevList` and `list`
* // [[0, 2], [4, 3], [3, 4], [2, 6], [1, 7]]
* console.log(result.changed);
* // The subset of `changed` and an array of index pairs that moved data directly. Indicate an array of absolute index pairs of `ordered`.(Formatted by: Array<[index of prevList, index of list]>)
* // [[4, 3], [3, 4], [2, 6]]
* console.log(result.pureChanged);
* // An array of index pairs to be `ordered` that can synchronize `list` before adding data. (Formatted by: Array<[prevIndex, nextIndex]>)
* // [[4, 1], [4, 2], [4, 3]]
* console.log(result.ordered);
* // An array of index pairs of `prevList` and `list` that have not been added/removed so data is preserved
* // [[0, 2], [4, 3], [3, 4], [2, 6], [1, 7]]
* console.log(result.maintained);
*/
export function diff<T>(

@@ -35,3 +55,2 @@ prevList: T[],

const maintained: number[][] = [];
const changed: number[][] = [];
const prevKeys = prevList.map(callback);

@@ -41,104 +60,65 @@ const keys = list.map(callback);

const keyMap: MapInteface<any, number> = new mapClass();
const changedBeforeAdded: number[][] = [];
const fixed: boolean[] = [];
const removedMap: object = {};
let changed: number[][] = [];
let addedCount = 0;
let removedCount = 0;
prevKeys.forEach((key, i) => {
prevKeyMap.set(key, i);
// Add prevKeys and keys to the hashmap.
prevKeys.forEach((key, prevListIndex) => {
prevKeyMap.set(key, prevListIndex);
});
keys.forEach((key, i) => {
keyMap.set(key, i);
if (!prevKeyMap.has(key)) {
added.push(i);
}
keys.forEach((key, listIndex) => {
keyMap.set(key, listIndex);
});
prevKeys.forEach((key, i) => {
const index = keyMap.get(key);
if (typeof index === "undefined") {
removed.push(i);
// Compare `prevKeys` and `keys` and add them to `removed` if they are not in `keys`.
prevKeys.forEach((key, prevListIndex) => {
const listIndex = keyMap.get(key);
// In prevList, but not in list, it is removed.
if (typeof listIndex === "undefined") {
++removedCount;
removed.push(prevListIndex);
} else {
maintained.push([i, index]);
if (i !== index) {
changed.push([i, index]);
}
removedMap[listIndex] = removedCount;
}
});
// Sort by ascending order of 'to(list's index).
changed.sort((a, b) => {
return a[1] > b[1] ? 1 : -1;
});
maintained.sort((a, b) => {
return a[1] > b[1] ? 1 : -1;
});
// start ordering
const orderedBefore = changed.map(([from, to]) => [from, to]);
const orderedAfter = changed.map(([from, to]) => [from, to]);
// Compare `prevKeys` and `keys` and add them to `added` if they are not in `prevKeys`.
keys.forEach((key, listIndex) => {
const prevListIndex = prevKeyMap.get(key);
// The index is removed in reverse order.
removed.reverse().forEach(index => {
// Array with removed.
orderedBefore.forEach(group => {
if (group[0] >= index) {
--group[0];
}
});
// Array with removed.
orderedAfter.forEach(group => {
if (group[0] >= index) {
--group[0];
}
});
});
for (let i = added.length - 1; i >= 0; --i) {
const index = added[i];
// In list, but not in prevList, it is added.
if (typeof prevListIndex === "undefined") {
added.push(listIndex);
++addedCount;
} else {
maintained.push([prevListIndex, listIndex]);
removedCount = removedMap[listIndex] || 0;
// Revert to an array where adding is not applied.
orderedBefore.forEach(group => {
if (group[1] >= index) {
--group[1];
changedBeforeAdded.push([
prevListIndex - removedCount,
listIndex - addedCount,
]);
fixed.push(listIndex === prevListIndex);
if (prevListIndex !== listIndex) {
changed.push([prevListIndex, listIndex]);
}
});
}
added.forEach(index => {
orderedAfter.forEach(group => {
if(group[0] >= index) {
++group[0];
}
})
});
orderChanged(orderedBefore);
orderChanged(orderedAfter);
const changedBeforeAdded: number[][] = [];
const changedAfterAdded: number[][] = [];
const orderedBeforeAdded: number[][] = [];
const orderedAfterAdded: number[][] = [];
changed.forEach(([from, to], i) => {
const [fromBefore, toBefore] = orderedBefore[i];
const [fromAfter, toAfter] = orderedAfter[i];
// There is no change in index.
if (fromBefore !== toBefore) {
changedBeforeAdded.push([from, to]);
orderedBeforeAdded.push([fromBefore, toBefore]);
}
if (fromAfter !== toAfter) {
changedAfterAdded.push([from, to]);
orderedAfterAdded.push([fromAfter, toAfter]);
}
});
// Sort by ascending order of 'to(list's index).
removed.reverse();
return {
return new Result(
prevList,
list,
added,
removed,
changed,
maintained,
changed,
changedBeforeAdded,
changedAfterAdded,
orderedBeforeAdded,
orderedAfterAdded,
removed,
};
fixed,
);
}

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with โšก๏ธ by Socket Inc