prosperon/scripts/diff.js

100 lines
2.4 KiB
JavaScript
Raw Normal View History

2024-09-26 11:36:09 -05:00
function deep_copy(from) {
return json.decode(json.encode(from));
}
2024-09-26 11:36:09 -05:00
function valdiff(from, to) {
2023-10-26 11:48:02 -05:00
if (typeof from !== typeof to) return from;
2024-09-26 11:36:09 -05:00
if (typeof from === "function") return undefined;
if (typeof from === "undefined") return undefined;
if (typeof from === "number") {
return to;
2023-10-26 11:48:02 -05:00
return undefined;
}
2024-09-26 11:36:09 -05:00
if (typeof from === "object") return ediff(from, to);
2023-10-26 11:48:02 -05:00
if (from !== to) return to;
return undefined;
}
2024-09-26 11:36:09 -05:00
function ediff(from, to) {
2023-10-26 11:48:02 -05:00
var ret = {};
2024-09-26 11:36:09 -05:00
2023-10-26 11:48:02 -05:00
if (!to)
2024-09-26 11:36:09 -05:00
// return ediff(from, {});
2023-10-26 11:48:02 -05:00
return deep_copy(from);
2024-09-26 11:36:09 -05:00
Object.entries(from).forEach(function ([key, v]) {
if (typeof v === "function") return;
if (typeof v === "undefined") return;
2023-10-26 11:48:02 -05:00
if (Array.isArray(v)) {
if (!Array.isArray(to[key]) || v.length !== to[key].length) {
2024-09-26 11:36:09 -05:00
var r = ediff(v, []);
2024-04-03 17:17:32 -05:00
if (r) ret[key] = Object.values(r);
return;
}
2023-10-26 11:48:02 -05:00
var diff = ediff(from[key], to[key]);
2024-09-26 11:36:09 -05:00
if (diff && !Object.empty(diff)) ret[key] = Object.values(ediff(v, []));
2023-10-26 11:48:02 -05:00
return;
}
2024-09-26 11:36:09 -05:00
if (typeof v === "object" && v !== null) {
2023-10-26 11:48:02 -05:00
var diff = ediff(v, to[key]);
2024-09-26 11:36:09 -05:00
if (diff && !Object.empty(diff)) ret[key] = diff;
2023-10-26 11:48:02 -05:00
return;
}
2024-09-26 11:36:09 -05:00
if (typeof v === "number" || v === null) {
if (!isFinite(v)) v = null; // Squash infinity to null
2024-09-26 11:36:09 -05:00
if (v !== to[key]) ret[key] = v;
2023-10-26 11:48:02 -05:00
return;
}
2024-09-26 11:36:09 -05:00
if (!to || v !== to[key]) ret[key] = v;
2023-10-26 11:48:02 -05:00
});
2024-02-19 20:31:26 -06:00
if (Object.empty(ret)) return undefined;
2024-09-26 11:36:09 -05:00
2023-10-26 11:48:02 -05:00
return ret;
}
ediff.doc = "Given a from and to object, returns an object that, if applied to from, will make it the same as to. Does not include deletion; it is only additive. If one element in an array is different, the entire array is copied. Squashes infinite numbers to null for use in JSON.";
2023-10-26 11:48:02 -05:00
2024-09-26 11:36:09 -05:00
function samediff(from, to) {
2023-10-26 11:48:02 -05:00
var same = [];
if (!to) return same;
2024-09-26 11:36:09 -05:00
if (typeof to !== "object") {
2024-02-25 17:31:48 -06:00
console.warn("'To' must be an object. Got " + to);
2023-10-26 11:48:02 -05:00
return same;
}
2024-09-26 11:36:09 -05:00
Object.keys(from).forEach(function (k) {
2023-10-26 11:48:02 -05:00
if (Object.isObject(from[k])) {
samediff(from[k], to[k]);
return;
}
2024-09-26 11:36:09 -05:00
// if (Array.isArray(from[k])) {
// var d = valdiff(from[k], to[k]);
// if (!d)
// }
2023-10-26 11:48:02 -05:00
var d = valdiff(from[k], to[k]);
2024-09-26 11:36:09 -05:00
if (!d) delete from[k];
2023-10-26 11:48:02 -05:00
});
return same;
}
samediff.doc = "Given a from and to object, returns an array of keys that are the same on from as on to.";
return {
deep_copy,
ediff,
samediff,
2024-09-26 11:36:09 -05:00
};