Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

recursive-diff

Package Overview
Dependencies
Maintainers
1
Versions
23
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

recursive-diff

Find diff between any two variables where variables be any valid JavaScript data type like string, numeric, array or object

  • 1.0.9
  • latest
  • Source
  • npm
  • Socket score

Version published
Weekly downloads
37K
increased by4.45%
Maintainers
1
Weekly downloads
 
Created
Source

NPM Version NPM Downloads Build Coverage Status Dependency Status

Recursive-Diff

A JavaScript library (with TypeScript support) to find diff between two JS Objects/Array, support for complex nested JS Objects


This library can be used to get diff between two JS Objects/Arrays(or other primitive values). Diff are returned in the form of Array where each ARRAY item represents a change in the original Object/Array. A diff item can have following three properties:

  • path: An array representation of nested path
  • op: Can be any one of the following - add, update or delete
  • val: New value after change
const rdiff = require('recursive-diff');
const initialVal = {
  a: {
    b: 1,
    c: 2,
    d: [1]
  }
}
const changedVal = {
  a: {
    b: 2,
    d: [1, 2],
  },
};

const diff = rdiff.getDiff(initialVal, changedVal);
/***
Diff of initialVal and changedVal is: [
  {
    "path": [
      "a",
      "b"
    ],
    "op": "update",
    "val": 2
  },
  {
    "path": [
      "a",
      "c"
    ],
    "op": "delete"
  },
  {
    "path": [
      "a",
      "d",
      1
    ],
    "op": "add",
    "val": 2
  }
]
**/

const c = rdiff.applyDiff(initialVal, diff);
assert.deepEqual(c, changedVal);

Api details

  • getDiff(oldVal, newVal, keepOldVal?): getDiff takes following parameters

    • oldVal (required): initial value, can be Array/Object or even primitive type such as number, boolean or string
    • newVal (required): changed value ( required ), can be Array/Object or even primitive type such as number, boolean or string
    • keepOldValueInDiff (optional): boolean parameter which if set to true, every diff value will have an additional property oldValue which will denote the old value before mutation
  • applyDiff (oldVal, diff, visitorCallbackFn?) applyDiff takes three arguments:

    • oldVal (required): original value,
    • diff (required): diff returned by getDiff API
    • visitorCallbackFn (optional): This callback function is called at each depth level while applying the diff. It can be used to mark the mutation path with some meta properties eg: { isMutated: true }. For more details, please check the examples directory of this repo.

Using recursive diff library in Node

  • Install library using the command : npm install recursive-diff
  • sample code is given below
const diff = require('recursive-diff');
const oldVal = {a:1};
const newVal = {a:2};
const delta = diff.getDiff(oldVal, newVal);
const ob3 = diff.applyDiff(oldVal, delta);
assert.deepEqual(ob3, newVal);

Using recursive diff library in the Browser

'dist/recursive-diff.min.js' can be directly injected into a HTML page using the URL https://unpkg.com/recursive-diff@latest/dist/recursive-diff.min.js. Once it is included into the HTML file, diff API is accessible using window.recursiveDiff. Example given below.

<script type="text" src="https://unpkg.com/recursive-diff@latest/dist/recursive-diff.min.js"/>
<script type="text/javascript">
 const oldVal = { a: 1 };
 const newVal = { a: 2 };
 const delta = recursiveDiff.getDiff(oldVal, newVal);
 const ob3 = recursiveDiff.applyDiff(oldVal, delta); //expect ob3 is deep equal to newVal
</script>

Using recursive diff library in TypeScript

import { getDiff, applyDiff, rdiffResult } from 'recursive-diff';

const oldVal = [1, 2];
const newVal = [2, 3, 4];
const diff:rdiffResult[] = getDiff(oldVal, newVal);
console.log('diff', diff);
const final = applyDiff(oldVal, diff);
console.log('applydiff', final); // final should deep equal to newVal

Tests

Unit test can be run using the command npm test. This repo has more than 99% code coverage.

Examples

You can find more examples in the example folder of this repo. Few of the examples are listed below.

/* eslint-disable no-param-reassign */
/* eslint-disable no-console */
import { getDiff, applyDiff } from '../dist/recursive-diff';

let [a, b, c, delta] = [];
// testing primitive data type
a = 3;
b = 10;
delta = getDiff(a, b);
console.log(delta);
// Output: [{path: [], op: 'update', val: 10}]
c = applyDiff(a, delta);
console.log(c); // Output: 10

// testing array
a = [1, 2];
b = [1, 30, 40];
delta = getDiff(a, b, true); // third parameter : keepOldValInDiff, see output below
console.log(delta);
/** *
Output:
[
  { path: [1], op: 'update', val: 30, oldVal: 2 },
  { path: [2], op: 'add', val: 40 },
]
* */
c = applyDiff(a, delta);
console.log(c); // Output: [1,30,40]

// testing objects
a = {
  a: '10',
  b: '20',
  c: '30',
};
b = {
  a: '10',
  b: '40',
};
delta = getDiff(a, b);
console.log(delta);
/** * Output:
[
  { path: ['b'], op: 'update', val: 40 },
  { path: ['c'], op: 'delete', val: undefined },
]
* */
c = applyDiff(a, delta);
console.log(c); // Output: {a:'10', 'b':40}

// testing complex deep object
a = {
  b: [1, 2, [3, 4]],
  c: {
    c1: 20,
    c2: {
      c21: 'hello',
    },
    c3: 'India',
  },
};
b = {
  b: [1, 2, [4]],
  c: {
    c1: 20,
    c2: {
      c21: 'hi',
      c22: 'welcome',
    },
    c3: 'cosmic',
  },
};

delta = getDiff(a, b);
console.log(delta);
/**
Output:
[
  { path: ['b', 2, 0], op: 'update', val: 4 },
  { path: ['b', 2, 1], op: 'delete', val: undefined },
  { path: ['c', 'c2', 'c21'], op: 'update', val: 'hi' },
  { path: ['c', 'c2', 'c22'], op: 'add', val: 'welcome' },
  { path: ['c', 'c3'], op: 'update', val: 'cosmic' },
]
* */
c = applyDiff(a, delta);
console.log(c);
/** *Output
 {
    b: [1,2,[4]],
    c: {
        c1 : 20,
        c2 : {
            c21: 'hi',
            c22: 'welcome'
        },
        c3: 'cosmic'
    }
}
* */

Keywords

FAQs

Package last updated on 19 Feb 2023

Did you know?

Socket

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Install

Related posts

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc