-
Notifications
You must be signed in to change notification settings - Fork 0
/
index.js
56 lines (48 loc) · 1.28 KB
/
index.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
module.exports = function diffResource(src, dst, opts) {
if (!opts) opts = {};
var equal = opts.equal || defaultEqual();
var key = opts.key || 'id';
var transforms = {put: [], post: [], del: []};
var hash = {};
var pk;
src.forEach(function(srcItem) {
var pk = srcItem[key];
if (!hash[pk]) hash[pk] = [];
hash[pk].push(srcItem);
});
dst.forEach(function(dstItem) {
var pk = dstItem[key];
// list same and different items
var sameItems = [];
var diffItems = (hash[pk] || []).filter(function(srcItem) {
var same = equal(srcItem, dstItem);
if (same) sameItems.push(srcItem);
return !same;
});
if (sameItems.length == 0) {
// nothing's the same so either put or post
if (diffItems.length) {
// set any item and remove the others
diffItems.shift();
transforms.put.push(dstItem);
} else {
// new item
transforms.post.push(dstItem);
}
srcItems = diffItems;
} else {
sameItems.shift();
srcItems = sameItems.concat(diffItems);
}
if (srcItems.length == 0) delete hash[pk];
else hash[pk] = srcItems;
});
for (pk in hash) transforms.del = transforms.del.concat(hash[pk]);
return transforms;
}
function defaultEqual() {
var deepEqual = require('deep-equal');
return function(a, b) {
return deepEqual(a, b, {strict: true});
}
}