all files / dist/ json-mount.js

33.33% Statements 34/102
0% Branches 0/16
0% Functions 0/24
33.33% Lines 34/102
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185                                                                                                                                                                                                                                                                                                             
'use strict';
 
var ReactUpdates = require('react/lib/ReactUpdates');
var ReactReconciler = require('react/lib/ReactReconciler');
var instantiateReactComponent = require('react/lib/instantiateReactComponent');
var ReactInstanceHandles = require('react/lib/ReactInstanceHandles');
var isEqual = require('lodash.isequal');
var keys = require('lodash.keys');
var map = require('lodash.map');
var defaults = require('lodash.defaults');
var filter = require('lodash.filter');
var pluck = require('lodash.pluck');
var pairs = require('lodash.pairs');
var first = require('lodash.first');
var TreeStream = require('./tree-stream');
 
var INTERVAL = 8;
var nodeCache = {};
var dirty = {};
var intervals = {};
var streams = {};
var components = {};
 
var getId = function getId(node) {
  return node.id;
};
 
var getNode = function getNode(id) {
  return nodeCache[id];
};
 
var getChildrenIds = function getChildrenIds(id) {
  return pluck(filter(map(keys(nodeCache), function (id) {
    return getNode(id);
  }), function (node) {
    return node.parent === id;
  }), 'id');
};
 
var setNode = function setNode(id, node) {
  if (isEqual(nodeCache[id], node)) {
    return node;
  }
 
  ReactInstanceHandles.traverseAncestors(id, function (id) {
    dirty[id] = true;
    return false;
  });
 
  nodeCache[id] = node;
  return node;
};
 
var purgeId = function purgeId(id) {
  map(getChildrenIds(id), purgeId);
  delete nodeCache[id];
  delete components[id];
  delete streams[id];
};
 
var buildTree = function buildTree(id) {
  var node = getNode(id);
  var children = getChildrenIds(id);
 
  return defaults({
    children: map(children, buildTree)
  }, node);
};
 
var startLoop = function startLoop(id) {
  if (intervals[id]) {
    return;
  }
 
  if (!keys(streams).length) {
    delete dirty[id];
    return;
  }
 
  intervals[id] = setTimeout(function () {
    tick(id);
  }, INTERVAL);
};
 
var tick = function tick(id) {
  delete intervals[id];
 
  var isDirty = function isDirty() {
    dirty[id] = false;
 
    if (!streams[id]) {
      return;
    }
 
    streams[id].writeTree(buildTree(id));
  };
 
  if (dirty[id]) {
    isDirty();
  }
 
  startLoop(id);
};
 
var getNodeInContainer = function getNodeInContainer(stream) {
  return map(filter(pairs(streams), function (kv) {
    return kv[1] === stream;
  }), function (kv) {
    return getNode(kv[0]);
  });
};
 
var getRootIds = function getRootIds(stream) {
  return map(getNodeInContainer(stream), function (node) {
    return getId(node);
  });
};
 
var register = function register(stream, component) {
  var rootId = first(getRootIds(stream));
 
  if (rootId) {
    rootId = ReactInstanceHandles.getReactRootIDFromNodeID(rootId);
  }
 
  if (!rootId) {
    rootId = ReactInstanceHandles.createReactRootID();
  }
 
  streams[rootId] = stream;
  components[rootId] = component;
 
  return rootId;
};
 
var mountComponent = function mountComponent(component, rootId, stream, context) {
  var transaction = ReactUpdates.ReactReconcileTransaction.getPooled();
 
  transaction.perform(function () {
    var node = ReactReconciler.mountComponent(component, rootId, transaction, context);
 
    dirty[node.id] = true;
    startLoop(node.id);
  });
 
  ReactUpdates.ReactReconcileTransaction.release(transaction);
};
 
var unmountComponent = function unmountComponent(rootId, component) {
  ReactReconciler.unmountComponent(component);
  purgeId(rootId);
};
 
var ReactMount = {
  render: function render(element) {
    var stream = new TreeStream();
 
    var component = instantiateReactComponent(element);
    var rootId = register(stream, component);
 
    ReactUpdates.batchedUpdates(mountComponent, component, rootId, stream, false);
 
    return stream;
  },
  unmountComponentAtNode: function unmountComponentAtNode(stream) {
    var rootId = first(getRootIds(stream));
    var component = components[rootId];
 
    if (!component) {
      return false;
    }
 
    ReactUpdates.batchedUpdates(unmountComponent, rootId, component, stream);
 
    stream.writeTree(null);
 
    return true;
  },
  getID: getId,
  getNode: getNode,
  setNode: setNode,
  purgeId: purgeId
};
 
module.exports = ReactMount;