function Cursor(tree, path, hash) {
    var _this;

    _this = _Emitter.call(this) || this; // If no path were to be provided, we fallback to an empty path (root)

    path = path || []; // Privates

    _this._identity = '[object Cursor]';
    _this._archive = null; // Properties

    _this.tree = tree;
    _this.path = path;
    _this.hash = hash; // State

    _this.state = {
      killed: false,
      recording: false,
      undoing: false
    }; // Checking whether the given path is dynamic or not

    _this._dynamicPath = _type["default"].dynamicPath(_this.path); // Checking whether the given path will meet a monkey

    _this._monkeyPath = _type["default"].monkeyPath(_this.tree._monkeys, _this.path);
    if (!_this._dynamicPath) _this.solvedPath = _this.path;else _this.solvedPath = (0, _helpers.getIn)(_this.tree._data, _this.path).solvedPath;
    /**
     * Listener bound to the tree's writes so that cursors with dynamic paths
     * may update their solved path correctly.
     *
     * @param {object} event - The event fired by the tree.
     */

    _this._writeHandler = function (_ref) {
      var data = _ref.data;
      if (_this.state.killed || !(0, _helpers.solveUpdate)([data.path], _this._getComparedPaths())) return;
      _this.solvedPath = (0, _helpers.getIn)(_this.tree._data, _this.path).solvedPath;
    };
    /**
     * Function in charge of actually trigger the cursor's updates and
     * deal with the archived records.
     *
     * @note: probably should wrap the current solvedPath in closure to avoid
     * for tricky cases where it would fail.
     *
     * @param {mixed} previousData - the tree's previous data.
     */


    var fireUpdate = function fireUpdate(previousData) {
      var self = _assertThisInitialized(_this);

      var eventData = {
        get previousData() {
          return (0, _helpers.getIn)(previousData, self.solvedPath).data;
        },

        get currentData() {
          return self.get();
        }

      };
      if (_this.state.recording && !_this.state.undoing) _this.archive.add(eventData.previousData);
      _this.state.undoing = false;
      return _this.emit('update', eventData);
    };
    /**
     * Listener bound to the tree's updates and determining whether the
     * cursor is affected and should react accordingly.
     *
     * Note that this listener is lazily bound to the tree to be sure
     * one wouldn't leak listeners when only creating cursors for convenience
     * and not to listen to updates specifically.
     *
     * @param {object} event - The event fired by the tree.
     */


    _this._updateHandler = function (event) {
      if (_this.state.killed) return;

      var _event$data = event.data,
          paths = _event$data.paths,
          previousData = _event$data.previousData,
          update = fireUpdate.bind(_assertThisInitialized(_this), previousData),
          comparedPaths = _this._getComparedPaths();

      if ((0, _helpers.solveUpdate)(paths, comparedPaths)) return update();
    }; // Lazy binding


    var bound = false;

    _this._lazyBind = function () {
      if (bound) return;
      bound = true;
      if (_this._dynamicPath) _this.tree.on('write', _this._writeHandler);
      return _this.tree.on('update', _this._updateHandler);
    }; // If the path is dynamic, we actually need to listen to the tree


    if (_this._dynamicPath) {
      _this._lazyBind();
    } else {
      // Overriding the emitter `on` and `once` methods
      _this.on = (0, _helpers.before)(_this._lazyBind, _this.on.bind(_assertThisInitialized(_this)));
      _this.once = (0, _helpers.before)(_this._lazyBind, _this.once.bind(_assertThisInitialized(_this)));
    }

    return _this;
  }
Cursor class

@constructor
@param {Baobab} tree   - The cursor's root.
@param {array}  path   - The cursor's path in the tree.
@param {string} hash   - The path's hash computed ahead by the tree.