UNPKG

@gamestdio/state-listener

Version:

Deeply compare JavaScript objects and listen to changes.

79 lines (78 loc) 2.54 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); function compare(tree1, tree2) { var patches = []; generate(tree1, tree2, patches, []); return patches; } exports.compare = compare; function concat(arr, value) { var newArr = arr.slice(); newArr.push(value); return newArr; } function objectKeys(obj) { if (Array.isArray(obj)) { var keys_1 = new Array(obj.length); for (var k = 0; k < keys_1.length; k++) { keys_1[k] = "" + k; } return keys_1; } if (Object.keys) { return Object.keys(obj); } var keys = []; for (var i in obj) { if (obj.hasOwnProperty(i)) { keys.push(i); } } return keys; } ; // Dirty check if obj is different from mirror, generate patches and update mirror function generate(mirror, obj, patches, path) { var newKeys = objectKeys(obj); var oldKeys = objectKeys(mirror); var deleted = false; for (var t = oldKeys.length - 1; t >= 0; t--) { var key = oldKeys[t]; var oldVal = mirror[key]; if (obj.hasOwnProperty(key) && !(obj[key] === undefined && oldVal !== undefined && Array.isArray(obj) === false)) { var newVal = obj[key]; if (typeof oldVal == "object" && oldVal != null && typeof newVal == "object" && newVal != null) { generate(oldVal, newVal, patches, concat(path, key)); } else { if (oldVal !== newVal) { patches.push({ operation: "replace", path: concat(path, key), value: newVal, previousValue: oldVal }); } } } else { patches.push({ operation: "remove", path: concat(path, key) }); deleted = true; // property has been deleted } } if (!deleted && newKeys.length == oldKeys.length) { return; } for (var t = newKeys.length - 1; t >= 0; t--) { var key = newKeys[t]; if (!mirror.hasOwnProperty(key) && obj[key] !== undefined) { var newVal = obj[key]; var addPath = concat(path, key); // compare deeper additions if (typeof newVal == "object" && newVal != null) { generate({}, newVal, patches, addPath); } patches.push({ operation: "add", path: addPath, value: newVal }); } } }