text: import { createError, REV_CONFLICT } from 'pouchdb-errors';
  import isDeleted from './isDeleted';
  import { parseDoc as parseDoc } from './parseDoc';
  import calculateWinningRev from '../merge/winningRev';
  import merge from '../merge/index';
  import revExists from '../merge/revExists';
  
  function updateDoc(revLimit, prev, docInfo, results,
                     i, cb, writeDoc, newEdits) {
  
    if (revExists(prev.rev_tree, docInfo.metadata.rev)) {
      results[i] = docInfo;
      return cb();
    }
  
    // sometimes this is pre-calculated. historically not always
    var previousWinningRev = prev.winningRev || calculateWinningRev(prev);
    var previouslyDeleted = 'deleted' in prev ? prev.deleted :
      isDeleted(prev, previousWinningRev);
    var deleted = 'deleted' in docInfo.metadata ? docInfo.metadata.deleted :
      isDeleted(docInfo.metadata);
    var isRoot = /^1-/.test(docInfo.metadata.rev);
  
    if (previouslyDeleted && !deleted && newEdits && isRoot) {
      var newDoc = docInfo.data;
      newDoc._rev = previousWinningRev;
      newDoc._id = docInfo.metadata.id;
      docInfo = parseDoc(newDoc, newEdits);
    }
  
    var merged = merge(prev.rev_tree, docInfo.metadata.rev_tree[0], revLimit);
  
    var inConflict = newEdits && (((previouslyDeleted && deleted) ||
      (!previouslyDeleted && merged.conflicts !== 'new_leaf') ||
      (previouslyDeleted && !deleted && merged.conflicts === 'new_branch')));
  
    if (inConflict) {
      var err = createError(REV_CONFLICT);
      results[i] = err;
      return cb();
    }
  
    var newRev = docInfo.metadata.rev;
    docInfo.metadata.rev_tree = merged.tree;
    docInfo.stemmedRevs = merged.stemmedRevs || [];
    /* istanbul ignore else */
    if (prev.rev_map) {
      docInfo.metadata.rev_map = prev.rev_map; // used only by leveldb
    }
  
    // recalculate
    var winningRev = calculateWinningRev(docInfo.metadata);
    var winningRevIsDeleted = isDeleted(docInfo.metadata, winningRev);
  
    // calculate the total number of documents that were added/removed,
    // from the perspective of total_rows/doc_count
    var delta = (previouslyDeleted === winningRevIsDeleted) ? 0 :
      previouslyDeleted < winningRevIsDeleted ? -1 : 1;
  
    var newRevIsDeleted;
    if (newRev === winningRev) {
      // if the new rev is the same as the winning rev, we can reuse that value
      newRevIsDeleted = winningRevIsDeleted;
    } else {
      // if they're not the same, then we need to recalculate
      newRevIsDeleted = isDeleted(docInfo.metadata, newRev);
    }
  
    writeDoc(docInfo, winningRev, winningRevIsDeleted, newRevIsDeleted,
      true, delta, i, cb);
  }
  
  export default updateDoc;
  