text: import _Object$keys from "@babel/runtime-corejs2/core-js/object/keys";
  import _objectSpread from "@babel/runtime-corejs2/helpers/objectSpread2";
  import _classCallCheck from "@babel/runtime-corejs2/helpers/classCallCheck";
  import _createClass from "@babel/runtime-corejs2/helpers/createClass";
  
  var ContextTree = /*#__PURE__*/function () {
    function ContextTree(value) {
      _classCallCheck(this, ContextTree);
  
      this.root = createNode(value || {});
    }
  
    _createClass(ContextTree, [{
      key: "set",
      value: function set(path, value) {
        var parent = this.getParent(path, true);
  
        if (!parent) {
          updateNode(this.root, value, null);
          return;
        }
  
        var key = path[path.length - 1];
        var children = parent.children;
  
        if (children[key]) {
          updateNode(children[key], value, parent);
          return;
        }
  
        children[key] = createNode(value, parent);
      } // Get the "best" node (node or nearest parent) and return its value.
  
    }, {
      key: "get",
      value: function get(path) {
        path = path || [];
  
        if (path.length < 1) {
          return this.root.value;
        }
  
        var branch = this.root;
        var child;
        var token;
  
        for (var i = 0; i < path.length; i += 1) {
          token = path[i];
          child = branch.children;
  
          if (!child[token]) {
            break;
          }
  
          branch = child[token];
        }
  
        return branch && branch.protoValue;
      }
    }, {
      key: "getParent",
      value: function getParent(path, ensureExists) {
        if (!path || path.length < 1) {
          return null;
        }
  
        if (path.length < 2) {
          return this.root;
        }
  
        return path.slice(0, -1).reduce(function (branch, token) {
          if (!branch) {
            return branch;
          }
  
          var children = branch.children;
  
          if (!children[token] && ensureExists) {
            children[token] = createNode(null, branch);
          }
  
          return children[token];
        }, this.root);
      }
    }]);
  
    return ContextTree;
  }(); // =========================
  // Utilities
  // =========================
  
  
  export { ContextTree as default };
  
  function createNode(value, parent) {
    return updateNode({
      children: {}
    }, value, parent);
  }
  
  function updateNode(node, value, parent) {
    node.value = value || {};
    node.protoValue = parent ? _objectSpread(_objectSpread({}, parent.protoValue), node.value) : node.value;
  
    _Object$keys(node.children).forEach(function (prop) {
      var child = node.children[prop];
      node.children[prop] = updateNode(child, child.value, node);
    });
  
    return node;
  }