|
1 "use strict"; |
|
2 |
|
3 var method = require("../method/core") |
|
4 |
|
5 // Method is designed to work with data structures representing application |
|
6 // state. Calling it with a state should return object representing `delta` |
|
7 // that has being applied to a previous state to get to a current state. |
|
8 // |
|
9 // Example |
|
10 // |
|
11 // diff(state) // => { "item-id-1": { title: "some title" } "item-id-2": null } |
|
12 var diff = method("diff@diffpatcher") |
|
13 |
|
14 // diff between `null` / `undefined` to any hash is a hash itself. |
|
15 diff.define(null, function(from, to) { return to }) |
|
16 diff.define(undefined, function(from, to) { return to }) |
|
17 diff.define(Object, function(from, to) { |
|
18 return calculate(from, to || {}) || {} |
|
19 }) |
|
20 |
|
21 function calculate(from, to) { |
|
22 var diff = {} |
|
23 var changes = 0 |
|
24 Object.keys(from).forEach(function(key) { |
|
25 changes = changes + 1 |
|
26 if (!(key in to) && from[key] != null) diff[key] = null |
|
27 else changes = changes - 1 |
|
28 }) |
|
29 Object.keys(to).forEach(function(key) { |
|
30 changes = changes + 1 |
|
31 var previous = from[key] |
|
32 var current = to[key] |
|
33 if (previous === current) return (changes = changes - 1) |
|
34 if (typeof(current) !== "object") return diff[key] = current |
|
35 if (typeof(previous) !== "object") return diff[key] = current |
|
36 var delta = calculate(previous, current) |
|
37 if (delta) diff[key] = delta |
|
38 else changes = changes - 1 |
|
39 }) |
|
40 return changes ? diff : null |
|
41 } |
|
42 |
|
43 diff.calculate = calculate |
|
44 |
|
45 module.exports = diff |