@bluelovers/deep-diff
Version:
Javascript utility for calculating deep difference, capturing changes, and applying changes across objects; for nodejs and the browser.
3 lines (2 loc) • 6.72 kB
JavaScript
!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?t(exports):"function"==typeof define&&define.amd?define(["exports"],t):t((e="undefined"!=typeof globalThis?globalThis:e||self).BlueloversDeepDiff={})}(this,(function(e){"use strict";var t;e.EnumKinds=void 0,(t=e.EnumKinds||(e.EnumKinds={})).DiffEdit="E",t.DiffNew="N",t.DiffDeleted="D",t.DiffArray="A";const n=["N","E","A","D"];class Diff{constructor(e,t){this.kind=e,null!=t&&t.length&&(this.path=t)}}class DiffEdit extends Diff{constructor(e,t,n){super("E",e),this.lhs=t,this.rhs=n}}class DiffNew extends Diff{constructor(e,t){super("N",e),this.rhs=t}}class DiffDeleted extends Diff{constructor(e,t){super("D",e),this.lhs=t}}class DiffArray extends Diff{constructor(e,t,n){super("A",e),this.index=t,this.item=n}}function arrayRemove(e,t){return e.splice(t,1)}function realTypeOf(e){const t=typeof e;return"object"!==t?t:e===Math?"math":null===e?"null":Array.isArray(e)?"array":"[object Date]"===Object.prototype.toString.call(e)?"date":"function"==typeof e.toString&&/^\/.*\//.test(e.toString())?"regexp":"object"}function hashThisString(e){let t=0;if(0===e.length)return t;for(let n=0;n<e.length;n++)t=(t<<5)-t+e.charCodeAt(n),t&=t;return t}function getOrderIndependentHash(e){let t=0;const n=realTypeOf(e);if("array"===n){e.forEach((function(e){t+=getOrderIndependentHash(e)}));const r=normalizeHashDesc(n,{hash:t});return t+hashThisString(r)}if("object"===n){for(const r in e)if(e.hasOwnProperty(r)){const f=normalizeHashDesc(n,{key:r,hash:getOrderIndependentHash(e[r])});t+=hashThisString(f)}return t}const r=normalizeHashDesc(n,{value:e});return t+hashThisString(r)}function normalizeHashDesc(e,t){switch(e){case"array":return`[ type: ${e} , hash: ${t.hash}]`;case"object":return`[ type: ${e}, key: ${t.key} , hash: ${t.hash}]`;default:return`[ type: ${e} , value: ${t.value}]`}}function _deepDiff(e,t,n,r,f,i,a,s){n=n||[],a=a||[];const h=(f=f||[]).slice(0);if(null!=i){if(r){if("function"==typeof r&&r(h,i))return;if("object"==typeof r){if(r.prefilter&&r.prefilter(h,i))return;if(r.normalize){const n=r.normalize(h,i,e,t);n&&(e=n[0],t=n[1])}}}h.push(i)}"regexp"===realTypeOf(e)&&"regexp"===realTypeOf(t)&&(e=e.toString(),t=t.toString());const o=typeof e,l=typeof t;let p,d,c,u;const D="undefined"!==o||a&&a.length>0&&a[a.length-1].lhs&&Object.getOwnPropertyDescriptor(a[a.length-1].lhs,i),g="undefined"!==l||a&&a.length>0&&a[a.length-1].rhs&&Object.getOwnPropertyDescriptor(a[a.length-1].rhs,i);if(!D&&g)n.push(new DiffNew(h,t));else if(!g&&D)n.push(new DiffDeleted(h,e));else if(realTypeOf(e)!==realTypeOf(t))n.push(new DiffEdit(h,e,t));else if("date"===realTypeOf(e)&&e-t!=0)n.push(new DiffEdit(h,e,t));else if("object"===o&&null!==e&&null!==t){for(p=a.length-1;p>-1;--p)if(a[p].lhs===e){u=!0;break}if(u)e!==t&&n.push(new DiffEdit(h,e,t));else{if(a.push({lhs:e,rhs:t}),Array.isArray(e)){for(s&&(e.sort((function(e,t){return getOrderIndependentHash(e)-getOrderIndependentHash(t)})),t.sort((function(e,t){return getOrderIndependentHash(e)-getOrderIndependentHash(t)}))),p=t.length-1,d=e.length-1;p>d;)n.push(new DiffArray(h,p,new DiffNew(void 0,t[p--])));for(;d>p;)n.push(new DiffArray(h,d,new DiffDeleted(void 0,e[d--])));for(;p>=0;--p)_deepDiff(e[p],t[p],n,r,h,p,a,s)}else{const f=Object.keys(e).concat(Object.getOwnPropertySymbols(e)),i=Object.keys(t).concat(Object.getOwnPropertySymbols(t));for(p=0;p<f.length;++p)c=f[p],u=i.indexOf(c),u>=0?(_deepDiff(e[c],t[c],n,r,h,c,a,s),i[u]=null):_deepDiff(e[c],void 0,n,r,h,c,a,s);for(p=0;p<i.length;++p)c=i[p],c&&_deepDiff(void 0,t[c],n,r,h,c,a,s)}a.length=a.length-1}}else e!==t&&("number"===o&&isNaN(e)&&isNaN(t)||n.push(new DiffEdit(h,e,t)))}function observableDiff(e,t,n,r,f){const i=[];if(_deepDiff(e,t,i,r,null,null,null,f),n)for(let e=0;e<i.length;++e)n(i[e]);return i}function deepDiff(e,t,n,r){const f=observableDiff(e,t,r?function(e){e&&r.push(e)}:void 0,n);return r||(f.length?f:void 0)}function _applyArrayChange(e,t,n){var r;if(null!==(r=n.path)&&void 0!==r&&r.length){let[r,f]=function _traversalObject(e,t){const n=(t=t.slice()).pop();let r=e;return t.reduce(((e,t)=>r=e[t]),r),[r,n]}(e[t],n.path);switch(n.kind){case"A":_applyArrayChange(r[f],n.index,n.item);break;case"D":delete r[f];break;case"E":case"N":r[f]=n.rhs}}else switch(n.kind){case"A":_applyArrayChange(e[t],n.index,n.item);break;case"D":e=arrayRemove(e,t);break;case"E":case"N":e[t]=n.rhs}return e}function isIDiffNode(e){return null!=e&&e&&n.includes(e.kind)}function applyChange(e,t,n){if(void 0===n&&isIDiffNode(t)&&(n=t),e&&n&&n.kind){let t=e,r=-1,f=n.path?n.path.length-1:0;for(;++r<f;)void 0===t[n.path[r]]&&(t[n.path[r]]=void 0!==n.path[r+1]&&"number"==typeof n.path[r+1]?[]:{}),t=t[n.path[r]];switch(n.kind){case"A":n.path&&void 0===t[n.path[r]]&&(t[n.path[r]]=[]),_applyArrayChange(n.path?t[n.path[r]]:t,n.index,n.item);break;case"D":delete t[n.path[r]];break;case"E":case"N":t[n.path[r]]=n.rhs}}}function revertArrayChange(e,t,n){if(n.path&&n.path.length){let r,f=e[t],i=n.path.length-1;for(r=0;r<i;r++)f=f[n.path[r]];switch(n.kind){case"A":revertArrayChange(f[n.path[r]],n.index,n.item);break;case"D":case"E":f[n.path[r]]=n.lhs;break;case"N":delete f[n.path[r]]}}else switch(n.kind){case"A":revertArrayChange(e[t],n.index,n.item);break;case"D":case"E":e[t]=n.lhs;break;case"N":e=arrayRemove(e,t)}return e}function revertChange(e,t,n){if(e&&t&&null!=n&&n.kind){let t,r,f=e;for(r=n.path.length-1,t=0;t<r;t++)void 0===f[n.path[t]]&&(f[n.path[t]]={}),f=f[n.path[t]];switch(n.kind){case"A":revertArrayChange(f[n.path[t]],n.index,n.item);break;case"D":case"E":f[n.path[t]]=n.lhs;break;case"N":delete f[n.path[t]]}}}function _applyDiffChangeCore(e,t,n){return t.forEach((t=>{n(e,!0,t)})),!0}e.Diff=Diff,e.DiffArray=DiffArray,e.DiffDeleted=DiffDeleted,e.DiffEdit=DiffEdit,e.DiffNew=DiffNew,e.applyChange=applyChange,e.applyDiff=function applyDiff(e,t,n){return e&&t&&observableDiff(e,t,(function(r){n&&!n(e,t,r)||applyChange(e,t,r)})),e},e.applyDiffChange=function applyDiffChange(e,t){if(_applyDiffChangeCore(e,t,applyChange))return e},e.deepDiff=deepDiff,e.default=deepDiff,e.diff=deepDiff,e.getOrderIndependentHash=getOrderIndependentHash,e.isIDiffNode=isIDiffNode,e.observableDiff=observableDiff,e.orderIndependentDiff=function orderIndependentDiff(e,t,n,r){const f=observableDiff(e,t,r?function(e){e&&r.push(e)}:void 0,n,!0);return r||(f.length?f:void 0)},e.orderIndependentObservableDiff=function orderIndependentObservableDiff(e,t,n,r,f,i,a){return _deepDiff(e,t,n,r,f,i,a,!0)},e.revertChange=revertChange,e.revertDiffChange=function revertDiffChange(e,t){if(_applyDiffChangeCore(e,t,revertChange))return e},Object.defineProperty(e,"__esModule",{value:!0})}));
//# sourceMappingURL=index.umd.production.min.cjs.map