diff
, diff3
, patch
(nearly) arbitary json documents.
var x = require('xdiff')
var a = SOMEOBJECT
var b = SOMEOBJECT_AFTER_CHANGES
var diff = x.diff(a, b)
// can apply a diff to A to get B
var patched = x.patch(a, diff)
require('assert').deepEqual(a, patched)
with diff
you can create a diff that is applyable with patch
you can diff nested objects, and arrays.
with diff3
you create a diff from two objects that have been edited concurrently,
you need to also to pass the concestor.
also see adiff which xdiff depends on to diff arrays.
xdiff is compatible with snob
var a = {a: true, c: 'deleteme'}
var b = {a: true, b: false}
var p = x.diff(a, b)
will create a diff like this:
[ ['set', ['root', 'b'], false]
, ['del', ['root', 'c']] ]
operations on nested objects are represented by thier path, unless the object has an ID. (see below)
var a0 = {A: {AA: '?'}}
var a1 = {A: {AA: 'aardvark'}}
var p = x.diff(a, b)
will create diff like this:
[['set', ['root', 'A', 'AA'], 'aardvark']]
var a = [1, 2 , 3]
var b = [0, 1, 'hello', 3]
var p = x.diff(a, b)
will create a diff like
[ 'splice', ['root'], [
[ 1, 1, 'hello] //at index 1 delete one item and insert hello
, [ 0, 0, 0] //at index 0 delete 0 items and insert `0`
]
if you give objects an ID, then xdiff will beable to track it properly, even if it's moved. even if it's concurrently changed.
var a = [{__id__: '#1'}, 5, {__id__: '#2'}]
var b = [5, {__id__: '#2'}, {__id__: '#1', prop: 'surprise'}]
var p = x.diff(a, b)
will produce a diff like this
[ ['set', ['#1', 'prop'], 'surprise'] //this applies the change to object #1
, ['splice', ['root'], [
[ 3, 0, '#=*#1'] //this just updates the reference!
, [ 0, 1]
] ]
]
if you don't don't use id's xdiff
won't know that an object that has changed
is actually the same object. this would cause it to reinsert a new copy of that object.
id's are this is really useful when you need to do 3-way-merges to merge together concurrent changes.
in a future version, xdiff will allow changing the id key. currently it uses only the __id__
property.
three way merge takes 3 objects, mine
, yours
and an old
object, which must be the concestor of both mine and yours.
if there are concurrent changes, xdiff will choose to use the change from mine
in a future version, xdiff will support injectable resolve function, so that you can choose how to rosolve the merge.
MIT / Apache2