unified

Project: syntax-tree/unist-diff

Package: unist-diff@2.0.0

  1. Dependencies: 4·Dependents: 0
  2. Diff two unist trees
  1. unist 97
  2. tree 40
  3. node 21
  4. diff 2

unist-diff Build Status Coverage Status

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-diff

Usage

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:

remove

insert

replace

props

text

order

PropsDiff

PropsDiff is an object mapping keys to new values.

In the diff:

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:

License

MIT © Titus Wormer