var _ = require('lodash'); var update = require('react-addons-update'); var RecursiveIterator = require('recursive-iterator'); function Tree(srcState) { this._keyCount = 0; this._state = srcState || {}; } var p = Tree.prototype; p.get = function(pathArr) { var obj = this._state; for(var i = 0, len = pathArr.length; i < len; ++i) { obj = obj[pathArr[i]]; if(!obj) throw new Error('Unexistant tree path: "'+pathArr.join('.')+'"'); } return obj; }; p.update = function(pathArr, updateCommands) { var updateQuery = this._createUpdateQueryForPath(pathArr, updateCommands); this._state = update(this._state, updateQuery); return this; }; p.del = function(pathArr) { var prop = pathArr[pathArr.length-1]; var parentPath = pathArr.slice(0, -1); this.update(parentPath, { "$apply": function(item) { delete item[prop]; return item; } }); return this; }; p.find = function(obj) { var iterator = this._getStateIterator(); for(var item = iterator.next(); !item.done; item = iterator.next()) { var state = item.value; if(state.node === obj) { return state; } } }; p.getState = function() { return this._state; }; p.toJSON = function() { return this._state; }; p._getStateIterator = function() { var iterator = new RecursiveIterator(this._state); return iterator; }; p._createUpdateQueryForPath = function(pathArr, updateCommands) { var cursor, query = {}; cursor = query; for(var i = 0, len = pathArr.length; i < len-1; ++i) { cursor = cursor[pathArr[i]] = {}; } cursor[pathArr[pathArr.length-1]] = updateCommands; return query; }; module.exports = Tree;