unist-diff

Diff two unist trees

Downloads in past

Stats

StarsIssuesVersionUpdatedCreatedSize
unist-diff
1302.0.07 years ago7 years agoMinified + gzip package size for unist-diff in KB

Readme

Diff two Unistunist trees.
Based on the vtreevtree diffing algorithm in virtual-domvdom, 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 patchespatch.

Patch

Patches represent changes. They come with three properties:
optional) — New thing

remove

  • type ('remove')
  • left (Nodenode) — Left node
  • right (null)

insert

  • type ('insert')
  • left (null)
  • right (Nodenode) — 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 `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 (Nodenode) — The moved node;
  • right (number) — The index this node moved from (when in removes) or
to (when in `inserts`).

License

MITlicense © Titus Wormerauthor