Meilleure gestion arbre immutable

This commit is contained in:
2015-11-03 17:45:37 +01:00
parent d8a0136a99
commit 519ec99264
11 changed files with 236 additions and 114 deletions

View File

@@ -1,53 +1,73 @@
var _ = require('lodash');
var update = require('react-addons-update');
var RecursiveIterator = require('recursive-iterator');
// Tree manipulation helpers
function Tree(srcState) {
this._keyCount = 0;
this._state = srcState || {};
}
exports.walk = function(branch, func, parent) {
var p = Tree.prototype;
if(!branch) return;
var breakHere = func(branch, parent);
if(breakHere) return breakHere;
var items = branch.items;
if(!items) return;
for( var i = 0, item = items[i]; (item = items[i]); i++ ) {
breakHere = exports.walk(item, func, branch);
if(breakHere) return breakHere;
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;
};
exports.find = function(tree, obj) {
p.update = function(pathArr, updateCommands) {
var updateQuery = this._createUpdateQueryForPath(pathArr, updateCommands);
this._state = update(this._state, updateQuery);
return this;
};
var result;
exports.walk(tree, function(item, parent) {
if( _.isEqual(item, obj) ) {
result = {item: item, parent: parent};
return true;
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 result;
return this;
};
exports.matches = function(tree, obj) {
var results = [];
var matches = _.matches(obj);
exports.walk(tree, function(item) {
if( matches(item) ) {
results.push(item);
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;
}
});
return results;
}
};
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;