Comparing version 1.1.3 to 1.2.0
interface Difference { | ||
type: "CREATE" | "REMOVE" | "CHANGE"; | ||
path: string[]; | ||
path: (string | number)[]; | ||
value?: any; | ||
} | ||
interface Options { | ||
cyclesFix: boolean; | ||
} | ||
export default function diff( | ||
obj: Record<string, any> | any[], | ||
newObj: Record<string, any> | any[], | ||
stack?: Record<string, any>[] | ||
options?: Partial<Options>, | ||
_stack?: Record<string, any>[] | ||
): Difference[]; | ||
export {}; |
const t = true; | ||
const richTypes = { Date: t, RegExp: t, String: t, Number: t }; | ||
export default function diff(obj, newObj, stack = []) { | ||
export default function diff( | ||
obj, | ||
newObj, | ||
options = { cyclesFix: true }, | ||
_stack = [] | ||
) { | ||
let diffs = []; | ||
for (const key in obj) { | ||
const objKey = obj[key]; | ||
const path = Array.isArray(obj) ? +key : key; | ||
if (!(key in newObj)) { | ||
diffs.push({ | ||
type: "REMOVE", | ||
path: [key], | ||
path: [path], | ||
}); | ||
} else if ( | ||
obj[key] && | ||
newObj[key] && | ||
typeof obj[key] === "object" && | ||
typeof newObj[key] === "object" && | ||
!richTypes[Object.getPrototypeOf(obj[key]).constructor.name] && | ||
!stack.includes(obj[key]) | ||
continue; | ||
} | ||
const newObjKey = newObj[key]; | ||
const areObjects = | ||
typeof objKey === "object" && typeof newObjKey === "object"; | ||
if ( | ||
objKey && | ||
newObjKey && | ||
areObjects && | ||
!richTypes[Object.getPrototypeOf(objKey).constructor.name] && | ||
(options.cyclesFix ? !_stack.includes(objKey) : true) | ||
) { | ||
const nestedDiffs = diff(obj[key], newObj[key], stack.concat([obj[key]])); | ||
diffs.push( | ||
...nestedDiffs.map((difference) => { | ||
difference.path.unshift(key); | ||
const nestedDiffs = diff( | ||
objKey, | ||
newObjKey, | ||
options, | ||
options.cyclesFix ? _stack.concat([objKey]) : [] | ||
); | ||
diffs.push.apply( | ||
diffs, | ||
nestedDiffs.map((difference) => { | ||
difference.path.unshift(path); | ||
return difference; | ||
@@ -27,15 +44,14 @@ }) | ||
} else if ( | ||
obj[key] !== newObj[key] && | ||
objKey !== newObjKey && | ||
!( | ||
typeof obj[key] === "object" && | ||
typeof newObj[key] === "object" && | ||
(isNaN(obj[key]) | ||
? obj[key] + "" === newObj[key] + "" | ||
: +obj[key] === +newObj[key]) | ||
areObjects && | ||
(isNaN(objKey) | ||
? objKey + "" === newObjKey + "" | ||
: +objKey === +newObjKey) | ||
) | ||
) { | ||
diffs.push({ | ||
path: [key], | ||
path: [path], | ||
type: "CHANGE", | ||
value: newObj[key], | ||
value: newObjKey, | ||
}); | ||
@@ -48,3 +64,3 @@ } | ||
type: "CREATE", | ||
path: [key], | ||
path: [Array.isArray(newObj) ? +key : key], | ||
value: newObj[key], | ||
@@ -51,0 +67,0 @@ }); |
{ | ||
"name": "microdiff", | ||
"version": "1.1.3", | ||
"version": "1.2.0", | ||
"description": "Small, fast, zero dependency deep object and array comparison", | ||
@@ -5,0 +5,0 @@ "main": "./dist/index.cjs", |
@@ -13,3 +13,3 @@ <div align="center"> | ||
- 🚀 100%+ faster than other object diff libraries | ||
- 🚀 More than double the speed of other object diff libraries | ||
- 📦 Extremely lightweight, <1kb minified | ||
@@ -53,4 +53,15 @@ - 🌎 Supports Deno, Node, the web, and even service workers. Also comes with built in Typescript types | ||
There are three different types of changes. `CREATE`, `REMOVE`, and `CHANGE`. The `path` property gives a path to the property in the new object (or the old object in the case of `REMOVE`). Each element in the array is a key to the next property a level deeper until you get to the property changed. The `value` property exists in types `CREATE` and `CHANGE`, and it contains the value of the property added/changed. | ||
There are three different types of changes. `CREATE`, `REMOVE`, and `CHANGE`. | ||
The `path` property gives a path to the property in the new object (or the old object in the case of `REMOVE`). | ||
Each element in the paths is a key to the next property a level deeper until you get to the property changed, and it is string or a number, depending on whether the object is an Array or Object (Objects with number keys will still be strings). | ||
The `value` property exists in types `CREATE` and `CHANGE`, and it contains the value of the property added/changed. | ||
# Cycles support | ||
By default cycles are supported, but if you are sure that the object has no cycles (for example if you are parsing JSON) you can disable cycles using the `cyclesFix` option. | ||
```js | ||
diff(obj1, obj2, { cyclesFix: false }); | ||
``` | ||
# Benchmarks | ||
@@ -57,0 +68,0 @@ |
Sorry, the diff of this file is not supported yet
8475
151
82
6