OPEN TECH FOUNDATION
The Fast, Accurate, JavaScript Objects Diffing & Patching Library.
LIVE DEMO
Features
Supported Types
-
Primitives
- Undefined
- Null
- Number
- String
- Boolean
- BigInt
-
Objects
- Plain Objects, eg:
{}
- Array
- Date
- Map
- Set
Installation
Install it using your favourite package manager.
npm install @opentf/obj-diff
yarn add @opentf/obj-diff
pnpm add @opentf/obj-diff
bun add @opentf/obj-diff
deno add @opentf/obj-diff
Usage
import { diff } from '@opentf/obj-diff';
diff(obj1: object, obj2: object): Array<DiffResult>
type DiffResult = {
t: 0 | 1 | 2;
p: Array<string | number>;
v?: unknown;
};
Examples
const a = {a: 1, b: 2};
const b = {a: 2, c: 3};
diff(a, b);
const a = [1, 2, 3, 4, 5];
const b = [1, 3, 5];
diff(a, b);
const a = {
foo: {
bar: {
a: ['a', 'b'],
b: 2,
c: ['x', 'y'],
e: 100
}
},
buzz: 'world'
};
const b = {
foo: {
bar: {
a: ['a'],
b: 2,
c: ['x', 'y', 'z'],
d: 'Hello, world!'
}
},
buzz: 'fizz'
};
diff(a, b);
Patching
You can apply the diff result onto the original object to get the modified object.
import { diff, patch } from '@opentf/obj-diff';
const a = {a: 1, b: 2};
const b = {a: 2, c: 3};
const out = patch(a, diff(a, b));
assert.deepStrictEqual(out, b);
Comparing Custom Types
By default, the diff function cannot compare every object types other than the list above.
You can extend the default diff function using the diffWith function.
Now you can compare any object types of your own.
Usage - diffWith()
diff(
obj1: object,
obj2: object,
fn: (a: object, b: object) => boolean | undefined
): Array<DiffResult>
Examples
Let us compare the MongoDB bson ObjectId objects.
import { ObjectId } from "bson";
import { diffWith } from "../src";
const record1 = {
_id: new ObjectId(),
title: "Article 1",
desc: "The article description.",
};
const record2 = {
_id: new ObjectId(),
title: "Article 1",
desc: "The new article description.",
};
const result = diffWith(record1, record2, (a, b) => {
if (a instanceof ObjectId && b instanceof ObjectId) {
return a.toString() !== b.toString();
}
});
console.log(result);
Benchmark
┌───┬──────────────────┬─────────┬───────────────────┬────────┬─────────┐
│ │ Task Name │ ops/sec │ Average Time (ns) │ Margin │ Samples │
├───┼──────────────────┼─────────┼───────────────────┼────────┼─────────┤
+ 0 │ diff │ 252,694 │ 3957.346814404028 │ ±1.60% │ 25270 │
│ 1 │ microdiff │ 218,441 │ 4577.892286564301 │ ±0.92% │ 21845 │
│ 2 │ deep-object-diff │ 121,385 │ 8238.188318642591 │ ±1.66% │ 12139 │
│ 3 │ just-diff │ 105,292 │ 9497.35384615396 │ ±1.66% │ 10530 │
│ 4 │ deep-diff │ 160,802 │ 6218.820533549017 │ ±1.59% │ 16081 │
└───┴──────────────────┴─────────┴───────────────────┴────────┴─────────┘
Running benchmarks
$ bun run build
$ bun benchmark.js
Articles
Please read our important articles:
License
Copyright (c) Thanga Ganapathy (MIT License).