{"id":13525862,"url":"https://github.com/cosmicanant/recursive-diff","last_synced_at":"2025-04-01T06:30:38.444Z","repository":{"id":33153025,"uuid":"36793377","full_name":"cosmicanant/recursive-diff","owner":"cosmicanant","description":"A JavaScript library to find diff between two JavaScript Objects. Support for Array, Number, Date and other primitive data types.","archived":false,"fork":false,"pushed_at":"2024-08-30T10:49:37.000Z","size":696,"stargazers_count":153,"open_issues_count":7,"forks_count":21,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-03-03T10:40:41.236Z","etag":null,"topics":["diff","javascript-library","node-module","nodejs","recursive-diff-library"],"latest_commit_sha":null,"homepage":"","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/cosmicanant.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":"CODE_OF_CONDUCT.md","threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2015-06-03T09:23:04.000Z","updated_at":"2025-03-02T15:47:55.000Z","dependencies_parsed_at":"2024-01-13T22:55:32.244Z","dependency_job_id":"b50518ee-661b-48f7-a391-c7301c9ec77a","html_url":"https://github.com/cosmicanant/recursive-diff","commit_stats":{"total_commits":102,"total_committers":6,"mean_commits":17.0,"dds":0.2647058823529411,"last_synced_commit":"108c687047141d5e45bdf350897bcafad64e1eb8"},"previous_names":[],"tags_count":1,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cosmicanant%2Frecursive-diff","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cosmicanant%2Frecursive-diff/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cosmicanant%2Frecursive-diff/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cosmicanant%2Frecursive-diff/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/cosmicanant","download_url":"https://codeload.github.com/cosmicanant/recursive-diff/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":246596548,"owners_count":20802844,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["diff","javascript-library","node-module","nodejs","recursive-diff-library"],"created_at":"2024-08-01T06:01:22.923Z","updated_at":"2025-04-01T06:30:38.149Z","avatar_url":"https://github.com/cosmicanant.png","language":"JavaScript","readme":" [![NPM Version][npm-image]][npm-url]\n  [![NPM Downloads][downloads-image]][downloads-url]\n  [![Build][travis-image]][travis-url]\n  [![Coverage Status][coveralls-image]][coveralls-url]\n  [![Dependency Status](https://david-dm.org/cosmicanant/recursive-diff.svg)](https://david-dm.org/cosmicanant/recursive-diff)\n\n# Recursive-Diff\n\n## A JavaScript library (with TypeScript support) to find diff between two JS Objects/Array, support for complex nested JS Objects\n\n* * *\n\nThis 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:\n\n-   `path`: An array representation of nested path\n-   `op`: Can be any one of the following - add, update or delete\n-   `val`: New value after change\n\n\n```js\nconst rdiff = require('recursive-diff');\nconst initialVal = {\n  a: {\n    b: 1,\n    c: 2,\n    d: [1]\n  }\n}\nconst changedVal = {\n  a: {\n    b: 2,\n    d: [1, 2],\n  },\n};\n\nconst diff = rdiff.getDiff(initialVal, changedVal);\n/***\nDiff of initialVal and changedVal is: [\n  {\n    \"path\": [\n      \"a\",\n      \"b\"\n    ],\n    \"op\": \"update\",\n    \"val\": 2\n  },\n  {\n    \"path\": [\n      \"a\",\n      \"c\"\n    ],\n    \"op\": \"delete\"\n  },\n  {\n    \"path\": [\n      \"a\",\n      \"d\",\n      1\n    ],\n    \"op\": \"add\",\n    \"val\": 2\n  }\n]\n**/\n\nconst c = rdiff.applyDiff(initialVal, diff);\nassert.deepEqual(c, changedVal);\n\n```\n\n## Api details\n\n-   **`getDiff(oldVal, newVal, keepOldVal?)`:** `getDiff` takes following parameters\n    -   `oldVal (required)`:  initial value, can be Array/Object or even primitive type such as number, boolean or string\n    -   `newVal (required)`: changed value ( required ), can be Array/Object or even primitive type such as number, boolean or string\n    -   `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\n\n-   **`applyDiff (oldVal, diff, visitorCallbackFn?)`** `applyDiff` will apply the diff on the oldVal and update it as per the diff object. It will update the original object. It three following three arguments:\n    -   `oldVal (required)`: original value,\n    -   `diff (required)`: diff returned by `getDiff` API\n    -   `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.\n\n## Using recursive diff library in Node\n\n-   Install library using the command : `npm install recursive-diff`\n-   sample code is given below\n\n```js\nconst diff = require('recursive-diff');\nconst oldVal = {a:1};\nconst newVal = {a:2};\nconst delta = diff.getDiff(oldVal, newVal);\nconst ob3 = diff.applyDiff(oldVal, delta);\nassert.deepEqual(ob3, newVal);\n```\n\n## Using recursive diff library in the Browser\n\n`'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.\n\n```html\n\u003cscript type=\"text\" src=\"https://unpkg.com/recursive-diff@latest/dist/recursive-diff.min.js\"/\u003e\n\u003cscript type=\"text/javascript\"\u003e\n const oldVal = { a: 1 };\n const newVal = { a: 2 };\n const delta = recursiveDiff.getDiff(oldVal, newVal);\n const ob3 = recursiveDiff.applyDiff(oldVal, delta); //expect ob3 is deep equal to newVal\n\u003c/script\u003e\n```\n\n## Using recursive diff library in TypeScript\n\n```js\nimport { getDiff, applyDiff, rdiffResult } from 'recursive-diff';\n\nconst oldVal = [1, 2];\nconst newVal = [2, 3, 4];\nconst diff:rdiffResult[] = getDiff(oldVal, newVal);\nconsole.log('diff', diff);\nconst final = applyDiff(oldVal, diff);\nconsole.log('applydiff', final); // final should deep equal to newVal\n```\n\n## Tests\n\nUnit test can be run using the command `npm test`. This repo has more than 99% code coverage.\n\n## Examples\n\nYou can find more examples in the example folder of this repo. Few of the examples are listed below.\n\n```js\n/* eslint-disable no-param-reassign */\n/* eslint-disable no-console */\nimport { getDiff, applyDiff } from '../dist/recursive-diff';\n\nlet [a, b, c, delta] = [];\n// testing primitive data type\na = 3;\nb = 10;\ndelta = getDiff(a, b);\nconsole.log(delta);\n// Output: [{path: [], op: 'update', val: 10}]\nc = applyDiff(a, delta);\nconsole.log(c); // Output: 10\n\n// testing array\na = [1, 2];\nb = [1, 30, 40];\ndelta = getDiff(a, b, true); // third parameter : keepOldValInDiff, see output below\nconsole.log(delta);\n/** *\nOutput:\n[\n  { path: [1], op: 'update', val: 30, oldVal: 2 },\n  { path: [2], op: 'add', val: 40 },\n]\n* */\nc = applyDiff(a, delta);\nconsole.log(c); // Output: [1,30,40]\n\n// testing objects\na = {\n  a: '10',\n  b: '20',\n  c: '30',\n};\nb = {\n  a: '10',\n  b: '40',\n};\ndelta = getDiff(a, b);\nconsole.log(delta);\n/** * Output:\n[\n  { path: ['b'], op: 'update', val: 40 },\n  { path: ['c'], op: 'delete', val: undefined },\n]\n* */\nc = applyDiff(a, delta);\nconsole.log(c); // Output: {a:'10', 'b':40}\n\n// testing complex deep object\na = {\n  b: [1, 2, [3, 4]],\n  c: {\n    c1: 20,\n    c2: {\n      c21: 'hello',\n    },\n    c3: 'India',\n  },\n};\nb = {\n  b: [1, 2, [4]],\n  c: {\n    c1: 20,\n    c2: {\n      c21: 'hi',\n      c22: 'welcome',\n    },\n    c3: 'cosmic',\n  },\n};\n\ndelta = getDiff(a, b);\nconsole.log(delta);\n/**\nOutput:\n[\n  { path: ['b', 2, 0], op: 'update', val: 4 },\n  { path: ['b', 2, 1], op: 'delete', val: undefined },\n  { path: ['c', 'c2', 'c21'], op: 'update', val: 'hi' },\n  { path: ['c', 'c2', 'c22'], op: 'add', val: 'welcome' },\n  { path: ['c', 'c3'], op: 'update', val: 'cosmic' },\n]\n* */\nc = applyDiff(a, delta);\nconsole.log(c);\n/** *Output\n {\n    b: [1,2,[4]],\n    c: {\n        c1 : 20,\n        c2 : {\n            c21: 'hi',\n            c22: 'welcome'\n        },\n        c3: 'cosmic'\n    }\n}\n* */\n\n```\n\n## Support Me\n[![Donate](https://img.shields.io/badge/Donate-PayPal-green.svg)](https://paypal.me/ananteng?country.x=IN\u0026locale.x=en_GB)\n\n[npm-image]: https://img.shields.io/npm/v/recursive-diff.svg\n\n[npm-url]: https://npmjs.org/package/recursive-diff\n\n[downloads-image]: https://img.shields.io/npm/dm/recursive-diff.svg\n\n[downloads-url]: https://npmjs.org/package/recursive-diff\n\n[travis-image]: https://img.shields.io/travis/cosmicanant/recursive-diff/master.svg\n\n[travis-url]: https://travis-ci.org/cosmicanant/recursive-diff\n\n[coveralls-image]: https://coveralls.io/repos/github/cosmicanant/recursive-diff/badge.svg?branch=master\n\n[coveralls-url]: https://coveralls.io/github/cosmicanant/recursive-diff?branch=master\n","funding_links":["https://paypal.me/ananteng?country.x=IN\u0026locale.x=en_GB"],"categories":["Repository","JavaScript"],"sub_categories":["Text/String"],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcosmicanant%2Frecursive-diff","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fcosmicanant%2Frecursive-diff","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcosmicanant%2Frecursive-diff/lists"}