function patch(dispatch, context) {
  return function (DOMElement, action) {
    _diff.Actions.case({
      setAttribute: function setAttribute(name, value, previousValue) {
        (0, _setAttribute2.setAttribute)(DOMElement, name, value, previousValue);
      },
      removeAttribute: function removeAttribute(name, previousValue) {
        (0, _setAttribute2.removeAttribute)(DOMElement, name, previousValue);
      },
      insertBefore: function insertBefore(index) {
        insertAtIndex(DOMElement.parentNode, index, DOMElement);
      },
      sameNode: function sameNode() {},
      updateChildren: function updateChildren(changes) {
        // Create a clone of the children so we can reference them later
        // using their original position even if they move around
        var childNodes = Array.prototype.slice.apply(DOMElement.childNodes);

        changes.forEach(function (change) {
          _diff.Actions.case({
            insertChild: function insertChild(vnode, index, path) {
              insertAtIndex(DOMElement, index, (0, _create2.default)(vnode, path, dispatch, context));
            },
            removeChild: function removeChild(index) {
              DOMElement.removeChild(childNodes[index]);
            },
            updateChild: function updateChild(index, actions) {
              var update = patch(dispatch, context);
              actions.forEach(function (action) {
                return update(childNodes[index], action);
              });
            }
          }, change);
        });
      },
      updateThunk: function updateThunk(prev, next, path) {
        var props = next.props;
        var children = next.children;
        var component = next.component;
        var onUpdate = component.onUpdate;

        var render = typeof component === 'function' ? component : component.render;
        var prevNode = prev.state.vnode;
        var model = {
          children: children,
          props: props,
          path: path,
          dispatch: dispatch,
          context: context
        };
        var nextNode = render(model);
        var changes = (0, _diff.diffNode)(prevNode, nextNode, (0, _element.createPath)(path, '0'));
        DOMElement = changes.reduce(patch(dispatch, context), DOMElement);
        if (onUpdate) onUpdate(model);
        next.state = {
          vnode: nextNode,
          model: model
        };
      },
      replaceNode: function replaceNode(prev, next, path) {
        var newEl = (0, _create2.default)(next, path, dispatch, context);
        var parentEl = DOMElement.parentNode;
        if (parentEl) parentEl.replaceChild(newEl, DOMElement);
        DOMElement = newEl;
        removeThunks(prev);
      },
      removeNode: function removeNode(prev) {
        removeThunks(prev);
        DOMElement.parentNode.removeChild(DOMElement);
        DOMElement = null;
      }
    }, action);

    return DOMElement;
  };
}
Modify a DOM element given an array of actions. A context can be set
that will be used to render any custom elements.