Diff two Unistunist trees.
Based on the
One caveat is that “Unist” does not support keys. Keys are what allow performant reordering of children. To deal with that,
Yields:
Patches represent changes. They come with three properties:
In the diff:
Based on the
vtree
vtree diffing algorithm in virtual-dom
vdom,
but for Unist.One caveat is that “Unist” does not support keys. Keys are what allow performant reordering of children. To deal with that,
unist-diff
uses
“synthetic” keys based on the properties on nodes (excluding their value
or their children). This is not ideal but it’s better than nothing.
Let’s see how it goes!Installation
npm install unist-diff## Usage
```js
var h = require('hastscript');
var diff = require('unist-diff');
var left = h('div', [
h('p', [
'Some ',
h('b', 'importance'),
' and ',
h('i', 'emphasis'),
'.'
]),
h('pre', h('code', 'foo()'))
]);
var right = h('div', [
h('p', [
'Some ',
h('strong', 'importance'),
' and ',
h('em', 'emphasis'),
'.'
]),
h('pre', h('code', 'bar()'))
]);
console.dir(diff(left, right), {depth: null});
Yields:
{ '1':
[ { type: 'insert',
left: null,
right:
{ type: 'element',
tagName: 'strong',
properties: {},
children: [ { type: 'text', value: 'importance' } ] } },
{ type: 'insert',
left: null,
right:
{ type: 'element',
tagName: 'em',
properties: {},
children: [ { type: 'text', value: 'emphasis' } ] } } ],
'3':
{ type: 'remove',
left:
{ type: 'element',
tagName: 'b',
properties: {},
children: [ { type: 'text', value: 'importance' } ] },
right: null },
'6':
{ type: 'remove',
left:
{ type: 'element',
tagName: 'i',
properties: {},
children: [ { type: 'text', value: 'emphasis' } ] },
right: null },
'11':
{ type: 'text',
left: { type: 'text', value: 'foo()' },
right: { type: 'text', value: 'bar()' } },
left:
{ type: 'element',
tagName: 'div',
properties: {},
children:
[ { type: 'element',
tagName: 'p',
properties: {},
children:
[ { type: 'text', value: 'Some ' },
{ type: 'element',
tagName: 'b',
properties: {},
children: [ { type: 'text', value: 'importance' } ] },
{ type: 'text', value: ' and ' },
{ type: 'element',
tagName: 'i',
properties: {},
children: [ { type: 'text', value: 'emphasis' } ] },
{ type: 'text', value: '.' } ] },
{ type: 'element',
tagName: 'pre',
properties: {},
children:
[ { type: 'element',
tagName: 'code',
properties: {},
children: [ { type: 'text', value: 'foo()' } ] } ] } ] } }
API
diff(left, right)
Parameters
Returns
Array.<Patch>
— List of one or patch
espatch.Patch
Patches represent changes. They come with three properties:type
(string
) — Type of changeleft
(Node
node, optional) — Left noderight
(Node
node,PropsDiff
propsdiff,MoveDiff
movediff,
optional) — New thing
remove
insert
replace
props
text
order
PropsDiff
PropsDiff
is an object mapping keys to new values.In the diff:
- If a key is removed, the key’s value is set to
undefined
. - If the new value and the old value are both plain objects, the key’s
value is set to a `PropsDiff` of both values.
- In all other cases, the key’s value is set to the new value.
MoveDiff
MoveDiff
is an object with two arrays: removes
and inserts
.
They always have equal lengths, and are never both empty. Objects in
inserts
and removes
have the following properties:left
(Node
node) — The moved node;right
(number
) — The index this node moved from (when inremoves
) or
to (when in `inserts`).