2.0.0 • Published 9 years ago
unist-diff v2.0.0
unist-diff

Diff two Unist trees.
Based on the vtree diffing algorithm in virtual-dom,
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:
npm install unist-diffUsage
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 patches.
Patch
Patches represent changes. They come with three properties:
type(string) — Type of changeleft(Node, optional) — Left noderight(Node,PropsDiff,MoveDiff, optional) — New thing
remove
type('remove')left(Node) — Left noderight(null)
insert
type('insert')left(null)right(Node) — Right node
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
PropsDiffof 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) — The moved node;right(number) — The index this node moved from (when inremoves) or to (when ininserts).