From 5f07e441ca80fee07ba0a7228c4f7b249057cb7b Mon Sep 17 00:00:00 2001 From: Yomguithereal Date: Fri, 27 Mar 2015 19:30:15 +0100 Subject: [PATCH 01/73] Removing history features from tree --- build/baobab.min.js | 2 +- src/baobab.js | 65 +++++-------------------------------------- test/suites/baobab.js | 42 ---------------------------- 3 files changed, 8 insertions(+), 101 deletions(-) diff --git a/build/baobab.min.js b/build/baobab.min.js index 52e1f87..ae60314 100644 --- a/build/baobab.min.js +++ b/build/baobab.min.js @@ -1,2 +1,2 @@ /* baobab.js - Version: 0.4.3 - Author: Yomguithereal (Guillaume Plique) */ -!function(t){if("object"==typeof exports&&"undefined"!=typeof module)module.exports=t();else if("function"==typeof define&&define.amd)define([],t);else{var e;e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:this,e.Baobab=t()}}(function(){var t;return function e(t,r,n){function o(s,a){if(!r[s]){if(!t[s]){var h="function"==typeof require&&require;if(!a&&h)return h(s,!0);if(i)return i(s,!0);var u=new Error("Cannot find module '"+s+"'");throw u.code="MODULE_NOT_FOUND",u}var c=r[s]={exports:{}};t[s][0].call(c.exports,function(e){var r=t[s][1][e];return o(r?r:e)},c,c.exports,e,t,r,n)}return r[s].exports}for(var i="function"==typeof require&&require,s=0;se;e++)n.push(t[e].handler);return n}var o={once:"boolean",scope:"object"},i=function(){this._enabled=!0,this._children=[],this._handlers={},this._handlersAll=[]};i.prototype.on=function(t,e,r){var n,s,a,h,u,c;if("function"==typeof e){for(u="string"==typeof t?[t]:t,n=0,s=u.length;n!==s;n+=1)if(h=u[n]){this._handlers[h]||(this._handlers[h]=[]),c={handler:e};for(a in r||{}){if(!o[a])throw new Error('The option "'+a+'" is not recognized by Emmett.');c[a]=r[a]}this._handlers[h].push(c)}}else if(t&&"object"==typeof t&&!Array.isArray(t))for(h in t)i.prototype.on.call(this,h,t[h],e);else{if("function"!=typeof t)throw new Error("Wrong arguments.");c={handler:t};for(a in r||{}){if(!o[a])throw new Error('The option "'+a+'" is not recognized by Emmett.');c[a]=r[a]}this._handlersAll.push(c)}return this},i.prototype.once=function(t,e,r){if("function"==typeof e)r=r||{},r.once=!0,this.on(t,e,r);else{if((!t||"object"!=typeof t||Array.isArray(t))&&"function"!=typeof t)throw new Error("Wrong arguments.");e=e||{},e.once=!0,this.on(t,e)}return this},i.prototype.off=function(t,e){var r,n,o,i,s,a,h,u="string"==typeof t?[t]:t;if(1===arguments.length&&"function"==typeof u){e=arguments[0];for(s in this._handlers){for(a=[],r=0,n=this._handlers[s].length;r!==n;r+=1)this._handlers[s][r].handler!==e&&a.push(this._handlers[s][r]);this._handlers[s]=a}for(a=[],r=0,n=this._handlersAll.length;r!==n;r+=1)this._handlersAll[r].handler!==e&&a.push(this._handlersAll[r]);this._handlersAll=a}else if(2===arguments.length)for(r=0,n=u.length;r!==n;r+=1){if(h=u[r],this._handlers[h]){for(a=[],o=0,i=this._handlers[h].length;o!==i;o+=1)this._handlers[h][o].handler!==e&&a.push(this._handlers[h][o]);this._handlers[h]=a}this._handlers[h]&&0===this._handlers[h].length&&delete this._handlers[h]}return this},i.prototype.unbindAll=function(){var t;this._handlersAll=[];for(t in this._handlers)delete this._handlers[t];return this},i.prototype.emit=function(t,e){var r,n,o,i,s,a,h,u,c,l,f="string"==typeof t?[t]:t;if(!this._enabled)return this;for(e=void 0===e?{}:e,r=0,n=f.length;r!==n;r+=1)if(l=f[r],c=(this._handlers[l]||[]).concat(this._handlersAll),c.length){for(h={type:l,data:e||{},target:this},a=[],o=0,i=c.length;o!==i;o+=1)(this._handlers[l]&&this._handlers[l].indexOf(c[o])>=0||this._handlersAll.indexOf(c[o])>=0)&&(c[o].handler.call("scope"in c[o]?c[o].scope:this,h),c[o].once&&a.push(c[o]));for(s=0;sr;r++)if(t._children[r]===e){t._children.splice(r,1);break}}),this._children.push(e),e},i.prototype.listeners=function(t){var r,n,o,i=[];if(t)for(i=e(this._handlers[t]),n=0,o=this._children.length;o>n;n++)i=i.concat(this._children[n].listeners(t));else{i=e(this._handlersAll);for(r in this._handlers)i=i.concat(e(this._handlers[r]));for(n=0,o=this._children.length;o>n;n++)i=i.concat(this._children[n].listeners())}return i},i.prototype.kill=function(){if(this.emit("emmett:kill"),this.unbindAll(),this._handlers=null,this._handlersAll=null,this._enabled=!1,this._children)for(var t=0,e=this._children.length;e>t;t++)this._children[t].kill();this._children=null},i.prototype.disable=function(){return this._enabled=!1,this},i.prototype.enable=function(){return this._enabled=!0,this},i.version="2.1.2","undefined"!=typeof n?("undefined"!=typeof r&&r.exports&&(n=r.exports=i),n.Emitter=i):"function"==typeof t&&t.amd?t("emmett",[],function(){return i}):this.Emitter=i}).call(this)},{}],4:[function(e,r,n){!function(){"use strict";function e(t){function e(t,o){var s,a,h,u,c,l,f,p,d=!1,y=!1,g=r.get(t);if("string"===r.get(o)){for(s=o.replace(/^[\?\!]/,"").split(/\|/),h=s.length,a=0;h>a;a++)if(i.indexOf(s[a])<0&&!(s[a]in n))throw new Error("Invalid type.");if(o.match(/^\?/)&&(d=!0),o.replace(/^\?/,"").match(/^\!/)&&(y=!0),y&&d)throw new Error("Invalid type.");for(a in s)if(n[s[a]]&&("function"==typeof n[s[a]].type?n[s[a]].type.call(r,t)===!0:!e(t,n[s[a]].type)))return y?(c=new Error,c.message='Expected a "'+o+'" but found a "'+s[a]+'".',c.expected=o,c.type=s[a],c.value=t,c):null;return null===t||void 0===t?y||d?null:(c=new Error,c.message='Expected a "'+o+'" but found a "'+g+'".',c.expected=o,c.type=g,c.value=t,c):(f=~s.indexOf("*"),p=~s.indexOf(g),y&&(f||p)?(c=new Error,c.message='Expected a "'+o+'" but found a "'+(p?g:"*")+'".',c.type=p?g:"*",c.expected=o,c.value=t,c):y||f||p?null:(c=new Error,c.message='Expected a "'+o+'" but found a "'+g+'".',c.expected=o,c.type=g,c.value=t,c))}if("object"===r.get(o)){if("object"!==g)return c=new Error,c.message='Expected an object but found a "'+g+'".',c.expected=o,c.type=g,c.value=t,c;for(u in o)if(l=e(t[u],o[u]))return c=l,c.path=c.path?[u].concat(c.path):[u],c;for(u in t)if(void 0===o[u])return c=new Error,c.message='Unexpected key "'+u+'".',c.type=g,c.value=t,c;return null}if("array"===r.get(o)){if(1!==o.length)throw new Error("Invalid type.");if("array"!==g)return c=new Error,c.message='Expected an array but found a "'+g+'".',c.expected=o,c.type=g,c.value=t,c;for(h=t.length,a=0;h>a;a++)if(l=e(t[a],o[0]))return c=l,c.path=c.path?[a].concat(c.path):[a],c;return null}throw new Error("Invalid type.")}var r=this,n={};if(this.add=function(t,e){var r,o,s,a,h,u;if(1===arguments.length){if("object"!==this.get(t))throw new Error("If types.add is called with one argument, this one has to be an object.");r=t,a=r.id,u=r.type}else{if(2!==arguments.length)throw new Error("types.add has to be called with one or two arguments.");if("string"!=typeof t||!t)throw new Error("If types.add is called with more than one argument, the first one must be the string id.");a=t,u=e}if("string"!==this.get(a)||0===a.length)throw new Error("A type requires an string id.");if(void 0!==n[a]&&"proto"!==n[a])throw new Error('The type "'+a+'" already exists.');if(~i.indexOf(a))throw new Error('"'+a+'" is a reserved type name.');n[a]=1,s=(r||{}).proto||[],s=Array.isArray(s)?s:[s],h={};for(o in s)void 0===n[s[o]]&&(n[s[o]]=1,h[s[o]]=1);if("function"!==this.get(u)&&!this.isValid(u))throw new Error("A type requires a valid definition. This one can be a preexistant type or else a function testing given objects.");if(n[a]=void 0===r?{id:a,type:u}:{},void 0!==r)for(o in r)n[a][o]=r[o];for(o in h)o!==a&&delete n[o];return this},this.has=function(t){return!!n[t]},this.get=function(t){return null===t||void 0===t?String(t):o[Object.prototype.toString.call(t)]||"object"},this.check=function(t,r,n){var o=e(t,r);if(n&&o)throw o;return!o},this.isValid=function(t){var e,r,o;if("string"===this.get(t)){e=t.replace(/^[\?\!]/,"").split(/\|/);for(o in e)if(i.indexOf(e[o])<0&&!(e[o]in n))return!1;return!0}if("object"===this.get(t)){for(r in t)if(!this.isValid(t[r]))return!1;return!0}return"array"===this.get(t)&&1===t.length?this.isValid(t[0]):!1},this.add("type",function(t){return this.isValid(t)}.bind(this)),this.add("primitive",function(t){return!t||!(t instanceof Object||"object"==typeof t)}),t=t||{},"object"!==this.get(t))throw Error("Invalid argument.");for(var s in t)this.add(s,t[s])}var o={},i=["*"];!function(){var t,e,r=["Arguments","Boolean","Number","String","Function","Array","Date","RegExp","Object"];for(t in r)e=r[t],i.push(e.toLowerCase()),o["[object "+e+"]"]=e.toLowerCase()}();var s=e;e.call(s),Object.defineProperty(s,"version",{value:"0.3.1"}),"undefined"!=typeof n?("undefined"!=typeof r&&r.exports&&(n=r.exports=s),n.types=s):"function"==typeof t&&t.amd?t("typology",[],function(){return s}):this.types=s}(this)},{}],5:[function(t,e){function r(t){return t+"$"+(new Date).getTime()+(""+Math.random()).replace("0.","")}function n(t,e){if(arguments.length<1&&(t={}),!(this instanceof n))return new n(t,e);if(!f.Object(t)&&!f.Array(t))throw Error("Baobab: invalid data.");if(i.call(this),this.options=a.shallowMerge(l,e),this._cloner=this.options.cloningFunction||a.deepClone,this._transaction={},this._future=void 0,this._history=[],this._cursors={},this.typology=this.options.typology?this.options.typology instanceof s?this.options.typology:new s(this.options.typology):new s,this.validate=this.options.validate||null,this.validate)try{this.typology.check(t,this.validate,!0)}catch(r){throw r.message="/"+r.path.join("/")+": "+r.message,r}this.data=this._cloner(t),this.mixin=c.baobab(this)}var o=t("./cursor.js"),i=t("emmett"),s=t("typology"),a=t("./helpers.js"),h=t("./update.js"),u=t("./merge.js"),c=t("./mixins.js"),l=t("../defaults.js"),f=t("./type.js");a.inherits(n,i),n.prototype._archive=function(){if(!(this.options.maxHistory<=0)){var t={data:this._cloner(this.data)};return this._history.length===this.options.maxHistory&&this._history.pop(),this._history.unshift(t),t}},n.prototype.commit=function(t){var e;if(t)this.data=t.data,e=t.log;else{this.options.shiftReferences&&(this.data=a.shallowClone(this.data));var r=this._archive();e=h(this.data,this._transaction,this.options),r&&(r.log=e)}if(this.validate){var n,o,i=[],s=e.length;for(o=0;s>o;o++)if(n=a.getIn(this.validate,e[o]))try{this.typology.check(this.get(e[o]),n,!0)}catch(u){u.path=e[o].concat(u.path||[]),i.push(u)}i.length&&this.emit("invalid",{errors:i})}return this._transaction={},this._future&&(this._future=clearTimeout(this._future)),this.emit("update",{log:e}),this},n.prototype.select=function(t){if(!t)throw Error("Baobab.select: invalid path.");if(arguments.length>1&&(t=a.arrayOf(arguments)),!f.Path(t))throw Error("Baobab.select: invalid path.");t=f.Array(t)?t:[t];var e,n=f.ComplexPath(t);if(n&&(e=a.solvePath(this.data,t)),this.options.cursorSingletons){var i=t.map(function(t){return f.Function(t)?r("fn"):f.Object(t)?r("ob"):t}).join("λ");if(this._cursors[i])return this._cursors[i];var s=new o(this,t,e,i);return this._cursors[i]=s,s}return new o(this,t)},n.prototype.root=function(){return this.select([])},n.prototype.reference=function(t){if(arguments.length>1&&(t=a.arrayOf(arguments)),!f.Path(t))throw Error("Baobab.get: invalid path.");return a.getIn(this.data,f.String(t)||f.Number(t)?[t]:t)},n.prototype.get=function(){var t=this.reference.apply(this,arguments);return this.options.clone?this._cloner(t):t},n.prototype.clone=function(){return this._cloner(this.reference.apply(this,arguments))},n.prototype.set=function(t,e){if(arguments.length<2)throw Error("Baobab.set: expects a key and a value.");var r={};if(f.Array(t)){var n=a.solvePath(this.data,t);if(!n)throw Error("Baobab.set: could not solve dynamic path.");r=a.pathObject(n,{$set:e})}else r[t]={$set:e};return this.update(r)},n.prototype.unset=function(t){if(!t&&0!==t)throw Error("Baobab.unset: expects a valid key to unset.");var e={};return e[t]={$unset:!0},this.update(e)},n.prototype.update=function(t){var e=this;if(!f.Object(t))throw Error("Baobab.update: wrong specification.");return this._transaction=u(t,this._transaction),this.options.autoCommit?this.options.asynchronous?(this._future||(this._future=setTimeout(e.commit.bind(e,null),0)),this):this.commit():this},n.prototype.hasHistory=function(){return!!this._history.length},n.prototype.getHistory=function(){return this._history},n.prototype.undo=function(){if(!this.hasHistory())throw Error("Baobab.undo: no history recorded, cannot undo.");var t=this._history.shift();this.commit(t)},n.prototype.release=function(){delete this.data,delete this._transaction,delete this._history;for(var t in this._cursors)this._cursors[t].release();delete this._cursors,this.kill()},n.prototype.toJSON=function(){return this.reference()},e.exports=n},{"../defaults.js":1,"./cursor.js":7,"./helpers.js":8,"./merge.js":9,"./mixins.js":10,"./type.js":11,"./update.js":12,emmett:3,typology:4}],6:[function(t,e){function r(t,e){e.on("update",t.cursorListener),t.tree.off("update",t.treeListener),t.tree.on("update",t.treeListener)}function n(t){var e=this;if(arguments.length<2)throw Error("baobab.Combination: not enough arguments.");var n=arguments[1],o=s.arrayOf(arguments).slice(2);if(n instanceof Array&&(o=n.slice(1),n=n[0]),!a.Cursor(n))throw Error("baobab.Combination: argument should be a cursor.");if("or"!==t&&"and"!==t)throw Error("baobab.Combination: invalid operator.");i.call(this),this.cursors=[n],this.operators=[],this.tree=n.tree,this.updates=new Array(this.cursors.length),this.cursorListener=function(){e.updates[e.cursors.indexOf(this)]=!0},this.treeListener=function(){var t,r,n=e.updates[0];for(t=1,r=e.cursors.length;r>t;t++)n="or"===e.operators[t-1]?n||e.updates[t]:n&&e.updates[t];n&&e.emit("update"),e.updates=new Array(e.cursors.length)},this.bound=!1;var h=this.on,u=this.once,c=function(){e.bound||(e.bound=!0,e.cursors.forEach(function(t){r(e,t)}))};this.on=function(){return c(),h.apply(this,arguments)},this.once=function(){return c(),u.apply(this,arguments)},o.forEach(function(e){this[t](e)},this)}function o(t){n.prototype[t]=function(e){if(!a.Cursor(e))throw this.release(),Error("baobab.Combination."+t+": argument should be a cursor.");if(~this.cursors.indexOf(e))throw this.release(),Error("baobab.Combination."+t+": cursor already in combination.");return this.cursors.push(e),this.operators.push(t),this.updates.length++,this.bound&&r(this,e),this}}var i=t("emmett"),s=t("./helpers.js"),a=t("./type.js");s.inherits(n,i),o("or"),o("and"),n.prototype.release=function(){this.cursors.forEach(function(t){t.off("update",this.cursorListener)},this),this.tree.off("update",this.treeListener),this.cursors=null,this.operators=null,this.tree=null,this.updates=null,this.kill()},e.exports=n},{"./helpers.js":8,"./type.js":11,emmett:3}],7:[function(t,e){function r(t,e,r,o){var a=this;n.call(this),e=e||[],this.tree=t,this.path=e,this.hash=o,this.relevant=void 0!==this.reference(),this.complexPath=!!r,this.solvedPath=this.complexPath?r:this.path,this.updateHandler=function(t){var e,r,n,o,i,h,u=t.data.log,c=!1;if(a.complexPath&&(a.solvedPath=s.solvePath(a.tree.data,a.path)),!a.path.length)return a.emit("update");t:for(i=0,n=u.length;n>i;i++)for(e=u[i],h=0,o=e.length;o>h&&(r=e[h],r===""+a.solvedPath[h]);h++)if(h+1===o||h+1===a.solvedPath.length){c=!0;break t}var l=void 0!==a.reference();a.relevant?l&&c?a.emit("update"):l||(a.emit("irrelevant"),a.relevant=!1):l&&c&&(a.emit("relevant"),a.emit("update"),a.relevant=!0)},this.mixin=i.cursor(this);var h=!1,u=this.on,c=this.once,l=function(){h||(h=!0,a.tree.on("update",a.updateHandler))};this.on=function(){return l(),u.apply(this,arguments)},this.once=function(){return l(),c.apply(this,arguments)}}var n=t("emmett"),o=t("./combination.js"),i=t("./mixins.js"),s=t("./helpers.js"),a=t("./type.js");s.inherits(r,n),r.prototype.isRoot=function(){return!this.path.length},r.prototype.isLeaf=function(){return a.Primitive(this.reference())},r.prototype.isBranch=function(){return!this.isLeaf()&&!this.isRoot()},r.prototype.root=function(){return this.tree.root()},r.prototype.select=function(t){if(arguments.length>1&&(t=s.arrayOf(arguments)),!a.Path(t))throw Error("baobab.Cursor.select: invalid path.");return this.tree.select(this.path.concat(t))},r.prototype.up=function(){return this.solvedPath&&this.solvedPath.length?this.tree.select(this.path.slice(0,-1)):null},r.prototype.left=function(){var t=+this.solvedPath[this.solvedPath.length-1];if(isNaN(t))throw Error("baobab.Cursor.left: cannot go left on a non-list type.");return t?this.tree.select(this.solvedPath.slice(0,-1).concat(t-1)):null},r.prototype.leftmost=function(){var t=+this.solvedPath[this.solvedPath.length-1];if(isNaN(t))throw Error("baobab.Cursor.leftmost: cannot go left on a non-list type.");return this.tree.select(this.solvedPath.slice(0,-1).concat(0))},r.prototype.right=function(){var t=+this.solvedPath[this.solvedPath.length-1];if(isNaN(t))throw Error("baobab.Cursor.right: cannot go right on a non-list type.");return t+1===this.up().reference().length?null:this.tree.select(this.solvedPath.slice(0,-1).concat(t+1))},r.prototype.rightmost=function(){var t=+this.solvedPath[this.solvedPath.length-1];if(isNaN(t))throw Error("baobab.Cursor.right: cannot go right on a non-list type.");var e=this.up().reference();return this.tree.select(this.solvedPath.slice(0,-1).concat(e.length-1))},r.prototype.down=function(){+this.solvedPath[this.solvedPath.length-1];return this.reference()instanceof Array?this.tree.select(this.solvedPath.concat(0)):null},r.prototype.get=function(t){return arguments.length>1&&(t=s.arrayOf(arguments)),this.tree.get(a.Step(t)?this.solvedPath.concat(t):this.solvedPath)},r.prototype.reference=function(t){return arguments.length>1&&(t=s.arrayOf(arguments)),this.tree.reference(a.Step(t)?this.solvedPath.concat(t):this.solvedPath)},r.prototype.clone=function(t){return arguments.length>1&&(t=s.arrayOf(arguments)),this.tree.clone(a.Step(t)?this.solvedPath.concat(t):this.solvedPath)},r.prototype.set=function(t,e){if(arguments.length<2)throw Error("baobab.Cursor.set: expecting at least key/value.");var r=this.reference();if("object"!=typeof r)throw Error("baobab.Cursor.set: trying to set key to a non-object.");var n={};if(a.Array(t)){var o=s.solvePath(r,t);if(!o)throw Error("baobab.Cursor.set: could not solve dynamic path.");n=s.pathObject(o,{$set:e})}else n[t]={$set:e};return this.update(n)},r.prototype.edit=function(t){return this.update({$set:t})},r.prototype.unset=function(t){if(!t&&0!==t)throw Error("baobab.Cursor.unset: expects a valid key to unset.");if("object"!=typeof this.reference())throw Error("baobab.Cursor.set: trying to set key to a non-object.");var e={};return e[t]={$unset:!0},this.update(e)},r.prototype.remove=function(){if(this.isRoot())throw Error("baobab.Cursor.remove: cannot remove root node.");return this.update({$unset:!0})},r.prototype.apply=function(t){if("function"!=typeof t)throw Error("baobab.Cursor.apply: argument is not a function.");return this.update({$apply:t})},r.prototype.chain=function(t){if("function"!=typeof t)throw Error("baobab.Cursor.chain: argument is not a function.");return this.update({$chain:t})},r.prototype.push=function(t){if(!(this.reference()instanceof Array))throw Error("baobab.Cursor.push: trying to push to non-array value.");return this.update(arguments.length>1?{$push:s.arrayOf(arguments)}:{$push:t})},r.prototype.unshift=function(t){if(!(this.reference()instanceof Array))throw Error("baobab.Cursor.push: trying to push to non-array value.");return this.update(arguments.length>1?{$unshift:s.arrayOf(arguments)}:{$unshift:t})},r.prototype.merge=function(t){if(!a.Object(t))throw Error("baobab.Cursor.merge: trying to merge a non-object.");if(!a.Object(this.reference()))throw Error("baobab.Cursor.merge: trying to merge into a non-object.");this.update({$merge:t})},r.prototype.update=function(t){return this.tree.update(s.pathObject(this.solvedPath,t)),this},r.prototype.or=function(t){return new o("or",this,t)},r.prototype.and=function(t){return new o("and",this,t)},r.prototype.release=function(){this.tree.off("update",this.updateHandler),this.hash&&delete this.tree._cursors[this.hash],delete this.tree,delete this.path,delete this.solvedPath,this.kill()},r.prototype.toJSON=function(){return this.reference()},a.Cursor=function(t){return t instanceof r},e.exports=r},{"./combination.js":6,"./helpers.js":8,"./mixins.js":10,"./type.js":11,emmett:3}],8:[function(t,e){function r(t){return Array.prototype.slice.call(t)}function n(t,e){var r,n={};for(r in t)n[r]=t[r];for(r in e)n[r]=e[r];return n}function o(t){var e=t.source,r="";return t.global&&(r+="g"),t.multiline&&(r+="m"),t.ignoreCase&&(r+="i"),t.sticky&&(r+="y"),t.unicode&&(r+="u"),new RegExp(e,r)}function i(t,e){if(!e||"object"!=typeof e||e instanceof Error||e instanceof ArrayBuffer)return e;if(g.Array(e)){if(t){var r,n,i=[];for(r=0,n=e.length;n>r;r++)i.push(m(e[r]));return i}return e.slice(0)}if(g.Date(e))return new Date(e.getTime());if(e instanceof RegExp)return o(e);if(g.Object(e)){var s,a={};e.constructor&&e.constructor!==Object&&(a=Object.create(e.constructor.prototype));for(s in e)e.hasOwnProperty(s)&&(a[s]=t?m(e[s]):e[s]);return a}return e}function s(t,e){return function(r){return e(t(r))}}function a(t,e){var r,n;for(r=0,n=t.length;n>r;r++)if(e(t[r]))return t[r]}function h(t,e){var r,n;for(r=0,n=t.length;n>r;r++)if(e(t[r]))return r;return-1}function u(t,e){var r,n=!0;if(!t)return!1;for(r in e)if(g.Object(e[r]))n=n&&u(t[r],e[r]);else if(g.Array(e[r]))n=n&&!!~e[r].indexOf(t[r]);else if(t[r]!==e[r])return!1;return n}function c(t,e){return a(t,function(t){return u(t,e)})}function l(t,e){return h(t,function(t){return u(t,e)})}function f(t,e){e=e||[];var r,n,o=t;for(r=0,n=e.length;n>r;r++){if(!o)return;if("function"==typeof e[r]){if(!g.Array(o))return;o=a(o,e[r])}else if("object"==typeof e[r]){if(!g.Array(o))return;o=c(o,e[r])}else o=o[e[r]]}return o}function p(t,e){var r,n,o,i=[],s=t;for(n=0,o=e.length;o>n;n++){if(!s)return null;if("function"==typeof e[n]){if(!g.Array(s))return;r=h(s,e[n]),i.push(r),s=s[r]}else if("object"==typeof e[n]){if(!g.Array(s))return;r=l(s,e[n]),i.push(r),s=s[r]}else i.push(e[n]),s=s[e[n]]||{}}return i}function d(t,e){var r,n=t.length,o={},i=o;for(n||(o=e),r=0;n>r;r++)i[t[r]]=r+1===n?e:{},i=i[t[r]];return o}function y(t,e){t.super_=e;var r=function(){};r.prototype=e.prototype,t.prototype=new r,t.prototype.constructor=t}var g=t("./type.js"),b=i.bind(null,!1),m=i.bind(null,!0);e.exports={arrayOf:r,deepClone:m,shallowClone:b,shallowMerge:n,compose:s,getIn:f,inherits:y,pathObject:d,solvePath:p}},{"./type.js":11}],9:[function(t,e){function r(t,e){return e in(t||{})}function n(t,e,n){return r(t,n)&&r(e,n)}function o(){var t,e,r,a,h={},u=arguments.length;for(r=u-1;r>=0;r--){if(arguments[r].$unset)delete h.$set,delete h.$apply,delete h.$merge,h.$unset=arguments[r].$unset;else{if(arguments[r].$set){delete h.$apply,delete h.$merge,delete h.$unset,h.$set=arguments[r].$set;continue}if(arguments[r].$merge){delete h.$set,delete h.$apply,delete h.$unset,h.$merge=arguments[r].$merge;continue}if(arguments[r].$apply){delete h.$set,delete h.$merge,delete h.$unset,h.$apply=arguments[r].$apply;continue}if(arguments[r].$chain){delete h.$set,delete h.$merge,delete h.$unset,h.$apply=h.$apply?i.compose(h.$apply,arguments[r].$chain):arguments[r].$chain;continue}}for(a in arguments[r])t=h[a],e=arguments[r][a],t&&s.Object(e)?n(t,e,"$push")?t.$push=s.Array(t.$push)?t.$push.concat(e.$push):[t.$push].concat(e.$push):n(t,e,"$unshift")?t.$unshift=s.Array(e.$unshift)?e.$unshift.concat(t.$unshift):[e.$unshift].concat(t.$unshift):h[a]=o(e,t):h[a]=e}return h}var i=t("./helpers.js"),s=t("./type.js");e.exports=o},{"./helpers.js":8,"./type.js":11}],10:[function(t,e){var r=t("./combination.js"),n=t("./type.js");e.exports={baobab:function(t){return{mixins:[{getInitialState:function(){if(this.tree=t,!this.cursor&&!this.cursors)return{};if(this.cursor&&this.cursors)throw Error("baobab.mixin: you cannot have both `component.cursor` and `component.cursors`. Please make up your mind.");if(this.__type=null,this.__updateHandler=function(){this.setState(this.__getCursorData())}.bind(this),this.cursor){if(!n.MixinCursor(this.cursor))throw Error("baobab.mixin.cursor: invalid data (cursor, string, array or function).");n.Function(this.cursor)&&(this.cursor=this.cursor()),n.Cursor(this.cursor)||(this.cursor=t.select(this.cursor)),this.__getCursorData=function(){return{cursor:this.cursor.get()}}.bind(this),this.__type="single"}else if(this.cursors){if(!n.MixinCursors(this.cursors))throw Error("baobab.mixin.cursor: invalid data (object, array or function).");if(n.Function(this.cursors)&&(this.cursors=this.cursors()),n.Array(this.cursors))this.cursors=this.cursors.map(function(e){return n.Cursor(e)?e:t.select(e)}),this.__getCursorData=function(){return{cursors:this.cursors.map(function(t){return t.get()})}}.bind(this),this.__type="array";else{for(var e in this.cursors)n.Cursor(this.cursors[e])||(this.cursors[e]=t.select(this.cursors[e]));this.__getCursorData=function(){var t={};for(e in this.cursors)t[e]=this.cursors[e].get();return{cursors:t}}.bind(this),this.__type="object"}}return this.__getCursorData()},componentDidMount:function(){"single"===this.__type?(this.__combination=new r("or",[this.cursor]),this.__combination.on("update",this.__updateHandler)):"array"===this.__type?(this.__combination=new r("or",this.cursors),this.__combination.on("update",this.__updateHandler)):"object"===this.__type&&(this.__combination=new r("or",Object.keys(this.cursors).map(function(t){return this.cursors[t]},this)),this.__combination.on("update",this.__updateHandler))},componentWillUnmount:function(){this.__combination&&this.__combination.release()}}].concat(t.options.mixins)}},cursor:function(t){return{mixins:[{getInitialState:function(){return this.cursor=t,this.__updateHandler=function(){this.setState({cursor:this.cursor.get()})}.bind(this),{cursor:this.cursor.get()}},componentDidMount:function(){this.cursor.on("update",this.__updateHandler)},componentWillUnmount:function(){this.cursor.off("update",this.__updateHandler)}}].concat(t.tree.options.mixins)}}}},{"./combination.js":6,"./type.js":11}],11:[function(t,e){var r=function(t){return Array.isArray(t)?"array":"object"==typeof t&&null!==t?"object":"string"==typeof t?"string":"number"==typeof t?"number":"boolean"==typeof t?"boolean":"function"==typeof t?"function":null===t?"null":void 0===t?"undefined":t instanceof Date?"date":"invalid"};r.Array=function(t){return Array.isArray(t)},r.Object=function(t){return!Array.isArray(t)&&"object"==typeof t&&null!==t},r.String=function(t){return"string"==typeof t},r.Number=function(t){return"number"==typeof t},r.Boolean=function(t){return"boolean"==typeof t},r.Function=function(t){return"function"==typeof t},r.Primitive=function(t){return"string"==typeof t||"number"==typeof t||"boolean"==typeof t},r.Date=function(t){return t instanceof Date},r.Step=function(t){var e=r(t),n=["null","undefined","invalid","date"];return-1===n.indexOf(e)},r.Path=function(t){var e=["object","string","number","function","undefined"];if(!r.Array(t))return e.indexOf(r(t))>=0;for(var n=0;n=0||r.Cursor(t)},r.MixinCursors=function(t){var e=["array","object","function"];return e.indexOf(r(t))>=0},r.ComplexPath=function(t){for(var e=["object","function"],n=0;n=0)return!0;return!1},e.exports=r},{}],12:[function(t,e){function r(t,e){var r=new Error("baobab.update: "+e+" at path /"+t.toString());return r.path=t,r}function n(t,e,n){n=n||{shiftReferences:!1};var a={};return function h(t,e,u,c){u=u||[];var l,f,p,d,y=u.join("λ");for(p in e)if(s[p])switch(d=e[p],a[y]=!0,p){case"$push":if(!i.Array(t))throw r(u,"using command $push to a non array");i.Array(d)?t.push.apply(t,d):t.push(d);break;case"$unshift":if(!i.Array(t))throw r(u,"using command $unshift to a non array");i.Array(d)?t.unshift.apply(t,d):t.unshift(d)}else if(f=y?y+"λ"+p:p,"$unset"in(e[p]||{}))a[f]=!0,i.Array(t)?n.shiftReferences?c[u[u.length-1]]=t.slice(0,+p).concat(t.slice(+p+1)):t.splice(p,1):delete t[p];else if("$set"in(e[p]||{}))d=e[p].$set,a[f]=!0,t[p]=d;else if("$apply"in(e[p]||{})||"$chain"in(e[p]||{})){if(l=e[p].$apply||e[p].$chain,"function"!=typeof l)throw r(u.concat(p),"using command $apply with a non function");a[f]=!0,t[p]=l.call(null,t[p])}else if("$merge"in(e[p]||{})){if(d=e[p].$merge,!i.Object(t[p]))throw r(u.concat(p),"using command $merge on a non-object");a[f]=!0,t[p]=o.shallowMerge(t[p],d)}else if(n.shiftReferences&&("$push"in(e[p]||{})||"$unshift"in(e[p]||{}))){if("$push"in(e[p]||{})){if(d=e[p].$push,!i.Array(t[p]))throw r(u.concat(p),"using command $push to a non array");t[p]=t[p].concat(d)}if("$unshift"in(e[p]||{})){if(d=e[p].$unshift,!i.Array(t[p]))throw r(u.concat(p),"using command $unshift to a non array");t[p]=(d instanceof Array?d:[d]).concat(t[p])}a[f]=!0}else"undefined"==typeof t[p]&&(t[p]={}),n.shiftReferences&&(t[p]=o.shallowClone(t[p])),h(t[p],e[p],u.concat(p),t)}(t,e),Object.keys(a).map(function(t){return t.split("λ")})}var o=t("./helpers.js"),i=t("./type.js"),s={};["$set","$push","$unshift","$apply","$merge"].forEach(function(t){s[t]=!0}),e.exports=n},{"./helpers.js":8,"./type.js":11}]},{},[2])(2)}); \ No newline at end of file +!function(t){if("object"==typeof exports&&"undefined"!=typeof module)module.exports=t();else if("function"==typeof define&&define.amd)define([],t);else{var e;e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:this,e.Baobab=t()}}(function(){var t;return function e(t,r,n){function o(s,a){if(!r[s]){if(!t[s]){var u="function"==typeof require&&require;if(!a&&u)return u(s,!0);if(i)return i(s,!0);var h=new Error("Cannot find module '"+s+"'");throw h.code="MODULE_NOT_FOUND",h}var c=r[s]={exports:{}};t[s][0].call(c.exports,function(e){var r=t[s][1][e];return o(r?r:e)},c,c.exports,e,t,r,n)}return r[s].exports}for(var i="function"==typeof require&&require,s=0;se;e++)n.push(t[e].handler);return n}var o={once:"boolean",scope:"object"},i=function(){this._enabled=!0,this._children=[],this._handlers={},this._handlersAll=[]};i.prototype.on=function(t,e,r){var n,s,a,u,h,c;if("function"==typeof e){for(h="string"==typeof t?[t]:t,n=0,s=h.length;n!==s;n+=1)if(u=h[n]){this._handlers[u]||(this._handlers[u]=[]),c={handler:e};for(a in r||{}){if(!o[a])throw new Error('The option "'+a+'" is not recognized by Emmett.');c[a]=r[a]}this._handlers[u].push(c)}}else if(t&&"object"==typeof t&&!Array.isArray(t))for(u in t)i.prototype.on.call(this,u,t[u],e);else{if("function"!=typeof t)throw new Error("Wrong arguments.");c={handler:t};for(a in r||{}){if(!o[a])throw new Error('The option "'+a+'" is not recognized by Emmett.');c[a]=r[a]}this._handlersAll.push(c)}return this},i.prototype.once=function(t,e,r){if("function"==typeof e)r=r||{},r.once=!0,this.on(t,e,r);else{if((!t||"object"!=typeof t||Array.isArray(t))&&"function"!=typeof t)throw new Error("Wrong arguments.");e=e||{},e.once=!0,this.on(t,e)}return this},i.prototype.off=function(t,e){var r,n,o,i,s,a,u,h="string"==typeof t?[t]:t;if(1===arguments.length&&"function"==typeof h){e=arguments[0];for(s in this._handlers){for(a=[],r=0,n=this._handlers[s].length;r!==n;r+=1)this._handlers[s][r].handler!==e&&a.push(this._handlers[s][r]);this._handlers[s]=a}for(a=[],r=0,n=this._handlersAll.length;r!==n;r+=1)this._handlersAll[r].handler!==e&&a.push(this._handlersAll[r]);this._handlersAll=a}else if(2===arguments.length)for(r=0,n=h.length;r!==n;r+=1){if(u=h[r],this._handlers[u]){for(a=[],o=0,i=this._handlers[u].length;o!==i;o+=1)this._handlers[u][o].handler!==e&&a.push(this._handlers[u][o]);this._handlers[u]=a}this._handlers[u]&&0===this._handlers[u].length&&delete this._handlers[u]}return this},i.prototype.unbindAll=function(){var t;this._handlersAll=[];for(t in this._handlers)delete this._handlers[t];return this},i.prototype.emit=function(t,e){var r,n,o,i,s,a,u,h,c,l,f="string"==typeof t?[t]:t;if(!this._enabled)return this;for(e=void 0===e?{}:e,r=0,n=f.length;r!==n;r+=1)if(l=f[r],c=(this._handlers[l]||[]).concat(this._handlersAll),c.length){for(u={type:l,data:e||{},target:this},a=[],o=0,i=c.length;o!==i;o+=1)(this._handlers[l]&&this._handlers[l].indexOf(c[o])>=0||this._handlersAll.indexOf(c[o])>=0)&&(c[o].handler.call("scope"in c[o]?c[o].scope:this,u),c[o].once&&a.push(c[o]));for(s=0;sr;r++)if(t._children[r]===e){t._children.splice(r,1);break}}),this._children.push(e),e},i.prototype.listeners=function(t){var r,n,o,i=[];if(t)for(i=e(this._handlers[t]),n=0,o=this._children.length;o>n;n++)i=i.concat(this._children[n].listeners(t));else{i=e(this._handlersAll);for(r in this._handlers)i=i.concat(e(this._handlers[r]));for(n=0,o=this._children.length;o>n;n++)i=i.concat(this._children[n].listeners())}return i},i.prototype.kill=function(){if(this.emit("emmett:kill"),this.unbindAll(),this._handlers=null,this._handlersAll=null,this._enabled=!1,this._children)for(var t=0,e=this._children.length;e>t;t++)this._children[t].kill();this._children=null},i.prototype.disable=function(){return this._enabled=!1,this},i.prototype.enable=function(){return this._enabled=!0,this},i.version="2.1.2","undefined"!=typeof n?("undefined"!=typeof r&&r.exports&&(n=r.exports=i),n.Emitter=i):"function"==typeof t&&t.amd?t("emmett",[],function(){return i}):this.Emitter=i}).call(this)},{}],4:[function(e,r,n){!function(){"use strict";function e(t){function e(t,o){var s,a,u,h,c,l,f,p,d=!1,y=!1,g=r.get(t);if("string"===r.get(o)){for(s=o.replace(/^[\?\!]/,"").split(/\|/),u=s.length,a=0;u>a;a++)if(i.indexOf(s[a])<0&&!(s[a]in n))throw new Error("Invalid type.");if(o.match(/^\?/)&&(d=!0),o.replace(/^\?/,"").match(/^\!/)&&(y=!0),y&&d)throw new Error("Invalid type.");for(a in s)if(n[s[a]]&&("function"==typeof n[s[a]].type?n[s[a]].type.call(r,t)===!0:!e(t,n[s[a]].type)))return y?(c=new Error,c.message='Expected a "'+o+'" but found a "'+s[a]+'".',c.expected=o,c.type=s[a],c.value=t,c):null;return null===t||void 0===t?y||d?null:(c=new Error,c.message='Expected a "'+o+'" but found a "'+g+'".',c.expected=o,c.type=g,c.value=t,c):(f=~s.indexOf("*"),p=~s.indexOf(g),y&&(f||p)?(c=new Error,c.message='Expected a "'+o+'" but found a "'+(p?g:"*")+'".',c.type=p?g:"*",c.expected=o,c.value=t,c):y||f||p?null:(c=new Error,c.message='Expected a "'+o+'" but found a "'+g+'".',c.expected=o,c.type=g,c.value=t,c))}if("object"===r.get(o)){if("object"!==g)return c=new Error,c.message='Expected an object but found a "'+g+'".',c.expected=o,c.type=g,c.value=t,c;for(h in o)if(l=e(t[h],o[h]))return c=l,c.path=c.path?[h].concat(c.path):[h],c;for(h in t)if(void 0===o[h])return c=new Error,c.message='Unexpected key "'+h+'".',c.type=g,c.value=t,c;return null}if("array"===r.get(o)){if(1!==o.length)throw new Error("Invalid type.");if("array"!==g)return c=new Error,c.message='Expected an array but found a "'+g+'".',c.expected=o,c.type=g,c.value=t,c;for(u=t.length,a=0;u>a;a++)if(l=e(t[a],o[0]))return c=l,c.path=c.path?[a].concat(c.path):[a],c;return null}throw new Error("Invalid type.")}var r=this,n={};if(this.add=function(t,e){var r,o,s,a,u,h;if(1===arguments.length){if("object"!==this.get(t))throw new Error("If types.add is called with one argument, this one has to be an object.");r=t,a=r.id,h=r.type}else{if(2!==arguments.length)throw new Error("types.add has to be called with one or two arguments.");if("string"!=typeof t||!t)throw new Error("If types.add is called with more than one argument, the first one must be the string id.");a=t,h=e}if("string"!==this.get(a)||0===a.length)throw new Error("A type requires an string id.");if(void 0!==n[a]&&"proto"!==n[a])throw new Error('The type "'+a+'" already exists.');if(~i.indexOf(a))throw new Error('"'+a+'" is a reserved type name.');n[a]=1,s=(r||{}).proto||[],s=Array.isArray(s)?s:[s],u={};for(o in s)void 0===n[s[o]]&&(n[s[o]]=1,u[s[o]]=1);if("function"!==this.get(h)&&!this.isValid(h))throw new Error("A type requires a valid definition. This one can be a preexistant type or else a function testing given objects.");if(n[a]=void 0===r?{id:a,type:h}:{},void 0!==r)for(o in r)n[a][o]=r[o];for(o in u)o!==a&&delete n[o];return this},this.has=function(t){return!!n[t]},this.get=function(t){return null===t||void 0===t?String(t):o[Object.prototype.toString.call(t)]||"object"},this.check=function(t,r,n){var o=e(t,r);if(n&&o)throw o;return!o},this.isValid=function(t){var e,r,o;if("string"===this.get(t)){e=t.replace(/^[\?\!]/,"").split(/\|/);for(o in e)if(i.indexOf(e[o])<0&&!(e[o]in n))return!1;return!0}if("object"===this.get(t)){for(r in t)if(!this.isValid(t[r]))return!1;return!0}return"array"===this.get(t)&&1===t.length?this.isValid(t[0]):!1},this.add("type",function(t){return this.isValid(t)}.bind(this)),this.add("primitive",function(t){return!t||!(t instanceof Object||"object"==typeof t)}),t=t||{},"object"!==this.get(t))throw Error("Invalid argument.");for(var s in t)this.add(s,t[s])}var o={},i=["*"];!function(){var t,e,r=["Arguments","Boolean","Number","String","Function","Array","Date","RegExp","Object"];for(t in r)e=r[t],i.push(e.toLowerCase()),o["[object "+e+"]"]=e.toLowerCase()}();var s=e;e.call(s),Object.defineProperty(s,"version",{value:"0.3.1"}),"undefined"!=typeof n?("undefined"!=typeof r&&r.exports&&(n=r.exports=s),n.types=s):"function"==typeof t&&t.amd?t("typology",[],function(){return s}):this.types=s}(this)},{}],5:[function(t,e){function r(t){return t+"$"+(new Date).getTime()+(""+Math.random()).replace("0.","")}function n(t,e){if(arguments.length<1&&(t={}),!(this instanceof n))return new n(t,e);if(!f.Object(t)&&!f.Array(t))throw Error("Baobab: invalid data.");if(i.call(this),this.options=a.shallowMerge(l,e),this._cloner=this.options.cloningFunction||a.deepClone,this._transaction={},this._future=void 0,this._cursors={},this.typology=this.options.typology?this.options.typology instanceof s?this.options.typology:new s(this.options.typology):new s,this.validate=this.options.validate||null,this.validate)try{this.typology.check(t,this.validate,!0)}catch(r){throw r.message="/"+r.path.join("/")+": "+r.message,r}this.data=this._cloner(t),this.mixin=c.baobab(this)}var o=t("./cursor.js"),i=t("emmett"),s=t("typology"),a=t("./helpers.js"),u=t("./update.js"),h=t("./merge.js"),c=t("./mixins.js"),l=t("../defaults.js"),f=t("./type.js");a.inherits(n,i),n.prototype.commit=function(){this.options.shiftReferences&&(this.data=a.shallowClone(this.data));var t=u(this.data,this._transaction,this.options);if(this.validate){var e,r,n=[],o=t.length;for(r=0;o>r;r++)if(e=a.getIn(this.validate,t[r]))try{this.typology.check(this.get(t[r]),e,!0)}catch(i){i.path=t[r].concat(i.path||[]),n.push(i)}n.length&&this.emit("invalid",{errors:n})}return this._transaction={},this._future&&(this._future=clearTimeout(this._future)),this.emit("update",{log:t}),this},n.prototype.select=function(t){if(!t)throw Error("Baobab.select: invalid path.");if(arguments.length>1&&(t=a.arrayOf(arguments)),!f.Path(t))throw Error("Baobab.select: invalid path.");t=f.Array(t)?t:[t];var e,n=f.ComplexPath(t);if(n&&(e=a.solvePath(this.data,t)),this.options.cursorSingletons){var i=t.map(function(t){return f.Function(t)?r("fn"):f.Object(t)?r("ob"):t}).join("λ");if(this._cursors[i])return this._cursors[i];var s=new o(this,t,e,i);return this._cursors[i]=s,s}return new o(this,t)},n.prototype.root=function(){return this.select([])},n.prototype.reference=function(t){if(arguments.length>1&&(t=a.arrayOf(arguments)),!f.Path(t))throw Error("Baobab.get: invalid path.");return a.getIn(this.data,f.String(t)||f.Number(t)?[t]:t)},n.prototype.get=function(){var t=this.reference.apply(this,arguments);return this.options.clone?this._cloner(t):t},n.prototype.clone=function(){return this._cloner(this.reference.apply(this,arguments))},n.prototype.set=function(t,e){if(arguments.length<2)throw Error("Baobab.set: expects a key and a value.");var r={};if(f.Array(t)){var n=a.solvePath(this.data,t);if(!n)throw Error("Baobab.set: could not solve dynamic path.");r=a.pathObject(n,{$set:e})}else r[t]={$set:e};return this.update(r)},n.prototype.unset=function(t){if(!t&&0!==t)throw Error("Baobab.unset: expects a valid key to unset.");var e={};return e[t]={$unset:!0},this.update(e)},n.prototype.update=function(t){var e=this;if(!f.Object(t))throw Error("Baobab.update: wrong specification.");return this._transaction=h(t,this._transaction),this.options.autoCommit?this.options.asynchronous?(this._future||(this._future=setTimeout(e.commit.bind(e,null),0)),this):this.commit():this},n.prototype.release=function(){delete this.data,delete this._transaction,delete this._history;for(var t in this._cursors)this._cursors[t].release();delete this._cursors,this.kill()},n.prototype.toJSON=function(){return this.reference()},e.exports=n},{"../defaults.js":1,"./cursor.js":7,"./helpers.js":8,"./merge.js":9,"./mixins.js":10,"./type.js":11,"./update.js":12,emmett:3,typology:4}],6:[function(t,e){function r(t,e){e.on("update",t.cursorListener),t.tree.off("update",t.treeListener),t.tree.on("update",t.treeListener)}function n(t){var e=this;if(arguments.length<2)throw Error("baobab.Combination: not enough arguments.");var n=arguments[1],o=s.arrayOf(arguments).slice(2);if(n instanceof Array&&(o=n.slice(1),n=n[0]),!a.Cursor(n))throw Error("baobab.Combination: argument should be a cursor.");if("or"!==t&&"and"!==t)throw Error("baobab.Combination: invalid operator.");i.call(this),this.cursors=[n],this.operators=[],this.tree=n.tree,this.updates=new Array(this.cursors.length),this.cursorListener=function(){e.updates[e.cursors.indexOf(this)]=!0},this.treeListener=function(){var t,r,n=e.updates[0];for(t=1,r=e.cursors.length;r>t;t++)n="or"===e.operators[t-1]?n||e.updates[t]:n&&e.updates[t];n&&e.emit("update"),e.updates=new Array(e.cursors.length)},this.bound=!1;var u=this.on,h=this.once,c=function(){e.bound||(e.bound=!0,e.cursors.forEach(function(t){r(e,t)}))};this.on=function(){return c(),u.apply(this,arguments)},this.once=function(){return c(),h.apply(this,arguments)},o.forEach(function(e){this[t](e)},this)}function o(t){n.prototype[t]=function(e){if(!a.Cursor(e))throw this.release(),Error("baobab.Combination."+t+": argument should be a cursor.");if(~this.cursors.indexOf(e))throw this.release(),Error("baobab.Combination."+t+": cursor already in combination.");return this.cursors.push(e),this.operators.push(t),this.updates.length++,this.bound&&r(this,e),this}}var i=t("emmett"),s=t("./helpers.js"),a=t("./type.js");s.inherits(n,i),o("or"),o("and"),n.prototype.release=function(){this.cursors.forEach(function(t){t.off("update",this.cursorListener)},this),this.tree.off("update",this.treeListener),this.cursors=null,this.operators=null,this.tree=null,this.updates=null,this.kill()},e.exports=n},{"./helpers.js":8,"./type.js":11,emmett:3}],7:[function(t,e){function r(t,e,r,o){var a=this;n.call(this),e=e||[],this.tree=t,this.path=e,this.hash=o,this.relevant=void 0!==this.reference(),this.complexPath=!!r,this.solvedPath=this.complexPath?r:this.path,this.updateHandler=function(t){var e,r,n,o,i,u,h=t.data.log,c=!1;if(a.complexPath&&(a.solvedPath=s.solvePath(a.tree.data,a.path)),!a.path.length)return a.emit("update");t:for(i=0,n=h.length;n>i;i++)for(e=h[i],u=0,o=e.length;o>u&&(r=e[u],r===""+a.solvedPath[u]);u++)if(u+1===o||u+1===a.solvedPath.length){c=!0;break t}var l=void 0!==a.reference();a.relevant?l&&c?a.emit("update"):l||(a.emit("irrelevant"),a.relevant=!1):l&&c&&(a.emit("relevant"),a.emit("update"),a.relevant=!0)},this.mixin=i.cursor(this);var u=!1,h=this.on,c=this.once,l=function(){u||(u=!0,a.tree.on("update",a.updateHandler))};this.on=function(){return l(),h.apply(this,arguments)},this.once=function(){return l(),c.apply(this,arguments)}}var n=t("emmett"),o=t("./combination.js"),i=t("./mixins.js"),s=t("./helpers.js"),a=t("./type.js");s.inherits(r,n),r.prototype.isRoot=function(){return!this.path.length},r.prototype.isLeaf=function(){return a.Primitive(this.reference())},r.prototype.isBranch=function(){return!this.isLeaf()&&!this.isRoot()},r.prototype.root=function(){return this.tree.root()},r.prototype.select=function(t){if(arguments.length>1&&(t=s.arrayOf(arguments)),!a.Path(t))throw Error("baobab.Cursor.select: invalid path.");return this.tree.select(this.path.concat(t))},r.prototype.up=function(){return this.solvedPath&&this.solvedPath.length?this.tree.select(this.path.slice(0,-1)):null},r.prototype.left=function(){var t=+this.solvedPath[this.solvedPath.length-1];if(isNaN(t))throw Error("baobab.Cursor.left: cannot go left on a non-list type.");return t?this.tree.select(this.solvedPath.slice(0,-1).concat(t-1)):null},r.prototype.leftmost=function(){var t=+this.solvedPath[this.solvedPath.length-1];if(isNaN(t))throw Error("baobab.Cursor.leftmost: cannot go left on a non-list type.");return this.tree.select(this.solvedPath.slice(0,-1).concat(0))},r.prototype.right=function(){var t=+this.solvedPath[this.solvedPath.length-1];if(isNaN(t))throw Error("baobab.Cursor.right: cannot go right on a non-list type.");return t+1===this.up().reference().length?null:this.tree.select(this.solvedPath.slice(0,-1).concat(t+1))},r.prototype.rightmost=function(){var t=+this.solvedPath[this.solvedPath.length-1];if(isNaN(t))throw Error("baobab.Cursor.right: cannot go right on a non-list type.");var e=this.up().reference();return this.tree.select(this.solvedPath.slice(0,-1).concat(e.length-1))},r.prototype.down=function(){+this.solvedPath[this.solvedPath.length-1];return this.reference()instanceof Array?this.tree.select(this.solvedPath.concat(0)):null},r.prototype.get=function(t){return arguments.length>1&&(t=s.arrayOf(arguments)),this.tree.get(a.Step(t)?this.solvedPath.concat(t):this.solvedPath)},r.prototype.reference=function(t){return arguments.length>1&&(t=s.arrayOf(arguments)),this.tree.reference(a.Step(t)?this.solvedPath.concat(t):this.solvedPath)},r.prototype.clone=function(t){return arguments.length>1&&(t=s.arrayOf(arguments)),this.tree.clone(a.Step(t)?this.solvedPath.concat(t):this.solvedPath)},r.prototype.set=function(t,e){if(arguments.length<2)throw Error("baobab.Cursor.set: expecting at least key/value.");var r=this.reference();if("object"!=typeof r)throw Error("baobab.Cursor.set: trying to set key to a non-object.");var n={};if(a.Array(t)){var o=s.solvePath(r,t);if(!o)throw Error("baobab.Cursor.set: could not solve dynamic path.");n=s.pathObject(o,{$set:e})}else n[t]={$set:e};return this.update(n)},r.prototype.edit=function(t){return this.update({$set:t})},r.prototype.unset=function(t){if(!t&&0!==t)throw Error("baobab.Cursor.unset: expects a valid key to unset.");if("object"!=typeof this.reference())throw Error("baobab.Cursor.set: trying to set key to a non-object.");var e={};return e[t]={$unset:!0},this.update(e)},r.prototype.remove=function(){if(this.isRoot())throw Error("baobab.Cursor.remove: cannot remove root node.");return this.update({$unset:!0})},r.prototype.apply=function(t){if("function"!=typeof t)throw Error("baobab.Cursor.apply: argument is not a function.");return this.update({$apply:t})},r.prototype.chain=function(t){if("function"!=typeof t)throw Error("baobab.Cursor.chain: argument is not a function.");return this.update({$chain:t})},r.prototype.push=function(t){if(!(this.reference()instanceof Array))throw Error("baobab.Cursor.push: trying to push to non-array value.");return this.update(arguments.length>1?{$push:s.arrayOf(arguments)}:{$push:t})},r.prototype.unshift=function(t){if(!(this.reference()instanceof Array))throw Error("baobab.Cursor.push: trying to push to non-array value.");return this.update(arguments.length>1?{$unshift:s.arrayOf(arguments)}:{$unshift:t})},r.prototype.merge=function(t){if(!a.Object(t))throw Error("baobab.Cursor.merge: trying to merge a non-object.");if(!a.Object(this.reference()))throw Error("baobab.Cursor.merge: trying to merge into a non-object.");this.update({$merge:t})},r.prototype.update=function(t){return this.tree.update(s.pathObject(this.solvedPath,t)),this},r.prototype.or=function(t){return new o("or",this,t)},r.prototype.and=function(t){return new o("and",this,t)},r.prototype.release=function(){this.tree.off("update",this.updateHandler),this.hash&&delete this.tree._cursors[this.hash],delete this.tree,delete this.path,delete this.solvedPath,this.kill()},r.prototype.toJSON=function(){return this.reference()},a.Cursor=function(t){return t instanceof r},e.exports=r},{"./combination.js":6,"./helpers.js":8,"./mixins.js":10,"./type.js":11,emmett:3}],8:[function(t,e){function r(t){return Array.prototype.slice.call(t)}function n(t,e){var r,n={};for(r in t)n[r]=t[r];for(r in e)n[r]=e[r];return n}function o(t){var e=t.source,r="";return t.global&&(r+="g"),t.multiline&&(r+="m"),t.ignoreCase&&(r+="i"),t.sticky&&(r+="y"),t.unicode&&(r+="u"),new RegExp(e,r)}function i(t,e){if(!e||"object"!=typeof e||e instanceof Error||e instanceof ArrayBuffer)return e;if(g.Array(e)){if(t){var r,n,i=[];for(r=0,n=e.length;n>r;r++)i.push(m(e[r]));return i}return e.slice(0)}if(g.Date(e))return new Date(e.getTime());if(e instanceof RegExp)return o(e);if(g.Object(e)){var s,a={};e.constructor&&e.constructor!==Object&&(a=Object.create(e.constructor.prototype));for(s in e)e.hasOwnProperty(s)&&(a[s]=t?m(e[s]):e[s]);return a}return e}function s(t,e){return function(r){return e(t(r))}}function a(t,e){var r,n;for(r=0,n=t.length;n>r;r++)if(e(t[r]))return t[r]}function u(t,e){var r,n;for(r=0,n=t.length;n>r;r++)if(e(t[r]))return r;return-1}function h(t,e){var r,n=!0;if(!t)return!1;for(r in e)if(g.Object(e[r]))n=n&&h(t[r],e[r]);else if(g.Array(e[r]))n=n&&!!~e[r].indexOf(t[r]);else if(t[r]!==e[r])return!1;return n}function c(t,e){return a(t,function(t){return h(t,e)})}function l(t,e){return u(t,function(t){return h(t,e)})}function f(t,e){e=e||[];var r,n,o=t;for(r=0,n=e.length;n>r;r++){if(!o)return;if("function"==typeof e[r]){if(!g.Array(o))return;o=a(o,e[r])}else if("object"==typeof e[r]){if(!g.Array(o))return;o=c(o,e[r])}else o=o[e[r]]}return o}function p(t,e){var r,n,o,i=[],s=t;for(n=0,o=e.length;o>n;n++){if(!s)return null;if("function"==typeof e[n]){if(!g.Array(s))return;r=u(s,e[n]),i.push(r),s=s[r]}else if("object"==typeof e[n]){if(!g.Array(s))return;r=l(s,e[n]),i.push(r),s=s[r]}else i.push(e[n]),s=s[e[n]]||{}}return i}function d(t,e){var r,n=t.length,o={},i=o;for(n||(o=e),r=0;n>r;r++)i[t[r]]=r+1===n?e:{},i=i[t[r]];return o}function y(t,e){t.super_=e;var r=function(){};r.prototype=e.prototype,t.prototype=new r,t.prototype.constructor=t}var g=t("./type.js"),b=i.bind(null,!1),m=i.bind(null,!0);e.exports={arrayOf:r,deepClone:m,shallowClone:b,shallowMerge:n,compose:s,getIn:f,inherits:y,pathObject:d,solvePath:p}},{"./type.js":11}],9:[function(t,e){function r(t,e){return e in(t||{})}function n(t,e,n){return r(t,n)&&r(e,n)}function o(){var t,e,r,a,u={},h=arguments.length;for(r=h-1;r>=0;r--){if(arguments[r].$unset)delete u.$set,delete u.$apply,delete u.$merge,u.$unset=arguments[r].$unset;else{if(arguments[r].$set){delete u.$apply,delete u.$merge,delete u.$unset,u.$set=arguments[r].$set;continue}if(arguments[r].$merge){delete u.$set,delete u.$apply,delete u.$unset,u.$merge=arguments[r].$merge;continue}if(arguments[r].$apply){delete u.$set,delete u.$merge,delete u.$unset,u.$apply=arguments[r].$apply;continue}if(arguments[r].$chain){delete u.$set,delete u.$merge,delete u.$unset,u.$apply=u.$apply?i.compose(u.$apply,arguments[r].$chain):arguments[r].$chain;continue}}for(a in arguments[r])t=u[a],e=arguments[r][a],t&&s.Object(e)?n(t,e,"$push")?t.$push=s.Array(t.$push)?t.$push.concat(e.$push):[t.$push].concat(e.$push):n(t,e,"$unshift")?t.$unshift=s.Array(e.$unshift)?e.$unshift.concat(t.$unshift):[e.$unshift].concat(t.$unshift):u[a]=o(e,t):u[a]=e}return u}var i=t("./helpers.js"),s=t("./type.js");e.exports=o},{"./helpers.js":8,"./type.js":11}],10:[function(t,e){var r=t("./combination.js"),n=t("./type.js");e.exports={baobab:function(t){return{mixins:[{getInitialState:function(){if(this.tree=t,!this.cursor&&!this.cursors)return{};if(this.cursor&&this.cursors)throw Error("baobab.mixin: you cannot have both `component.cursor` and `component.cursors`. Please make up your mind.");if(this.__type=null,this.__updateHandler=function(){this.setState(this.__getCursorData())}.bind(this),this.cursor){if(!n.MixinCursor(this.cursor))throw Error("baobab.mixin.cursor: invalid data (cursor, string, array or function).");n.Function(this.cursor)&&(this.cursor=this.cursor()),n.Cursor(this.cursor)||(this.cursor=t.select(this.cursor)),this.__getCursorData=function(){return{cursor:this.cursor.get()}}.bind(this),this.__type="single"}else if(this.cursors){if(!n.MixinCursors(this.cursors))throw Error("baobab.mixin.cursor: invalid data (object, array or function).");if(n.Function(this.cursors)&&(this.cursors=this.cursors()),n.Array(this.cursors))this.cursors=this.cursors.map(function(e){return n.Cursor(e)?e:t.select(e)}),this.__getCursorData=function(){return{cursors:this.cursors.map(function(t){return t.get()})}}.bind(this),this.__type="array";else{for(var e in this.cursors)n.Cursor(this.cursors[e])||(this.cursors[e]=t.select(this.cursors[e]));this.__getCursorData=function(){var t={};for(e in this.cursors)t[e]=this.cursors[e].get();return{cursors:t}}.bind(this),this.__type="object"}}return this.__getCursorData()},componentDidMount:function(){"single"===this.__type?(this.__combination=new r("or",[this.cursor]),this.__combination.on("update",this.__updateHandler)):"array"===this.__type?(this.__combination=new r("or",this.cursors),this.__combination.on("update",this.__updateHandler)):"object"===this.__type&&(this.__combination=new r("or",Object.keys(this.cursors).map(function(t){return this.cursors[t]},this)),this.__combination.on("update",this.__updateHandler))},componentWillUnmount:function(){this.__combination&&this.__combination.release()}}].concat(t.options.mixins)}},cursor:function(t){return{mixins:[{getInitialState:function(){return this.cursor=t,this.__updateHandler=function(){this.setState({cursor:this.cursor.get()})}.bind(this),{cursor:this.cursor.get()}},componentDidMount:function(){this.cursor.on("update",this.__updateHandler)},componentWillUnmount:function(){this.cursor.off("update",this.__updateHandler)}}].concat(t.tree.options.mixins)}}}},{"./combination.js":6,"./type.js":11}],11:[function(t,e){var r=function(t){return Array.isArray(t)?"array":"object"==typeof t&&null!==t?"object":"string"==typeof t?"string":"number"==typeof t?"number":"boolean"==typeof t?"boolean":"function"==typeof t?"function":null===t?"null":void 0===t?"undefined":t instanceof Date?"date":"invalid"};r.Array=function(t){return Array.isArray(t)},r.Object=function(t){return!Array.isArray(t)&&"object"==typeof t&&null!==t},r.String=function(t){return"string"==typeof t},r.Number=function(t){return"number"==typeof t},r.Boolean=function(t){return"boolean"==typeof t},r.Function=function(t){return"function"==typeof t},r.Primitive=function(t){return"string"==typeof t||"number"==typeof t||"boolean"==typeof t},r.Date=function(t){return t instanceof Date},r.Step=function(t){var e=r(t),n=["null","undefined","invalid","date"];return-1===n.indexOf(e)},r.Path=function(t){var e=["object","string","number","function","undefined"];if(!r.Array(t))return e.indexOf(r(t))>=0;for(var n=0;n=0||r.Cursor(t)},r.MixinCursors=function(t){var e=["array","object","function"];return e.indexOf(r(t))>=0},r.ComplexPath=function(t){for(var e=["object","function"],n=0;n=0)return!0;return!1},e.exports=r},{}],12:[function(t,e){function r(t,e){var r=new Error("baobab.update: "+e+" at path /"+t.toString());return r.path=t,r}function n(t,e,n){n=n||{shiftReferences:!1};var a={};return function u(t,e,h,c){h=h||[];var l,f,p,d,y=h.join("λ");for(p in e)if(s[p])switch(d=e[p],a[y]=!0,p){case"$push":if(!i.Array(t))throw r(h,"using command $push to a non array");i.Array(d)?t.push.apply(t,d):t.push(d);break;case"$unshift":if(!i.Array(t))throw r(h,"using command $unshift to a non array");i.Array(d)?t.unshift.apply(t,d):t.unshift(d)}else if(f=y?y+"λ"+p:p,"$unset"in(e[p]||{}))a[f]=!0,i.Array(t)?n.shiftReferences?c[h[h.length-1]]=t.slice(0,+p).concat(t.slice(+p+1)):t.splice(p,1):delete t[p];else if("$set"in(e[p]||{}))d=e[p].$set,a[f]=!0,t[p]=d;else if("$apply"in(e[p]||{})||"$chain"in(e[p]||{})){if(l=e[p].$apply||e[p].$chain,"function"!=typeof l)throw r(h.concat(p),"using command $apply with a non function");a[f]=!0,t[p]=l.call(null,t[p])}else if("$merge"in(e[p]||{})){if(d=e[p].$merge,!i.Object(t[p]))throw r(h.concat(p),"using command $merge on a non-object");a[f]=!0,t[p]=o.shallowMerge(t[p],d)}else if(n.shiftReferences&&("$push"in(e[p]||{})||"$unshift"in(e[p]||{}))){if("$push"in(e[p]||{})){if(d=e[p].$push,!i.Array(t[p]))throw r(h.concat(p),"using command $push to a non array");t[p]=t[p].concat(d)}if("$unshift"in(e[p]||{})){if(d=e[p].$unshift,!i.Array(t[p]))throw r(h.concat(p),"using command $unshift to a non array");t[p]=(d instanceof Array?d:[d]).concat(t[p])}a[f]=!0}else"undefined"==typeof t[p]&&(t[p]={}),n.shiftReferences&&(t[p]=o.shallowClone(t[p])),u(t[p],e[p],h.concat(p),t)}(t,e),Object.keys(a).map(function(t){return t.split("λ")})}var o=t("./helpers.js"),i=t("./type.js"),s={};["$set","$push","$unshift","$apply","$merge"].forEach(function(t){s[t]=!0}),e.exports=n},{"./helpers.js":8,"./type.js":11}]},{},[2])(2)}); \ No newline at end of file diff --git a/src/baobab.js b/src/baobab.js index 0269103..76f34ab 100644 --- a/src/baobab.js +++ b/src/baobab.js @@ -43,7 +43,6 @@ function Baobab(initialData, opts) { // Privates this._transaction = {}; this._future = undefined; - this._history = []; this._cursors = {}; // Internal typology @@ -74,52 +73,18 @@ function Baobab(initialData, opts) { helpers.inherits(Baobab, EventEmitter); -/** - * Private prototype - */ -Baobab.prototype._archive = function() { - if (this.options.maxHistory <= 0) - return; - - var record = { - data: this._cloner(this.data) - }; - - // Replacing - if (this._history.length === this.options.maxHistory) { - this._history.pop(); - } - this._history.unshift(record); - - return record; -}; - /** * Prototype */ -Baobab.prototype.commit = function(referenceRecord) { - var self = this, - log; - - if (referenceRecord) { - - // Override - this.data = referenceRecord.data; - log = referenceRecord.log; - } - else { - - // Shifting root reference - if (this.options.shiftReferences) - this.data = helpers.shallowClone(this.data); +Baobab.prototype.commit = function() { + var self = this; - // Applying modification (mutation) - var record = this._archive(); - log = update(this.data, this._transaction, this.options); + // Shifting root reference + if (this.options.shiftReferences) + this.data = helpers.shallowClone(this.data); - if (record) - record.log = log; - } + // Applying modification (mutation) + var log = update(this.data, this._transaction, this.options); if (this.validate) { var errors = [], @@ -289,22 +254,6 @@ Baobab.prototype.update = function(spec) { return this; }; -Baobab.prototype.hasHistory = function() { - return !!this._history.length; -}; - -Baobab.prototype.getHistory = function() { - return this._history; -}; - -Baobab.prototype.undo = function() { - if (!this.hasHistory()) - throw Error('Baobab.undo: no history recorded, cannot undo.'); - - var lastRecord = this._history.shift(); - this.commit(lastRecord); -}; - Baobab.prototype.release = function() { delete this.data; diff --git a/test/suites/baobab.js b/test/suites/baobab.js index 2030a87..4ed73df 100644 --- a/test/suites/baobab.js +++ b/test/suites/baobab.js @@ -290,46 +290,4 @@ describe('Baobab API', function() { baobab.set('hello', 42); }); }); - - describe('History', function() { - - it('should be possible to record passed states.', function(done) { - var baobab = new Baobab({name: 'Maria'}, {maxHistory: 1}); - - baobab.set('name', 'Estelle'); - - setTimeout(function() { - assert(baobab.hasHistory()); - assert.deepEqual(baobab.getHistory(), [{log: [['name']], data: {name: 'Maria'}}]); - done(); - }, 0); - }); - - it('should throw an error if trying to undo without history.', function() { - var baobab = new Baobab({hello: 'world'}); - - assert.throws(function() { - baobab.undo(); - }, /no history/); - }); - - it('should be possible to go back in time.', function(done) { - var baobab = new Baobab({name: 'Maria'}, {maxHistory: 2}); - - async.series([ - function(next) { - baobab.set('name', 'Estelle'); - setTimeout(next); - }, - function(next) { - assert(baobab.hasHistory()); - baobab.undo(); - assert.deepEqual(baobab.get(), {name: 'Maria'}); - done(); - } - ], function() { - done(); - }); - }); - }); }); From 912ad264d97ab66b51eda498fecdc50d1ccf3f63 Mon Sep 17 00:00:00 2001 From: Yomguithereal Date: Fri, 27 Mar 2015 19:33:42 +0100 Subject: [PATCH 02/73] Dropping typology dependency --- build/baobab.min.js | 2 +- package.json | 3 +-- src/baobab.js | 45 ------------------------------------------ test/suites/baobab.js | 46 ------------------------------------------- 4 files changed, 2 insertions(+), 94 deletions(-) diff --git a/build/baobab.min.js b/build/baobab.min.js index ae60314..97215d5 100644 --- a/build/baobab.min.js +++ b/build/baobab.min.js @@ -1,2 +1,2 @@ /* baobab.js - Version: 0.4.3 - Author: Yomguithereal (Guillaume Plique) */ -!function(t){if("object"==typeof exports&&"undefined"!=typeof module)module.exports=t();else if("function"==typeof define&&define.amd)define([],t);else{var e;e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:this,e.Baobab=t()}}(function(){var t;return function e(t,r,n){function o(s,a){if(!r[s]){if(!t[s]){var u="function"==typeof require&&require;if(!a&&u)return u(s,!0);if(i)return i(s,!0);var h=new Error("Cannot find module '"+s+"'");throw h.code="MODULE_NOT_FOUND",h}var c=r[s]={exports:{}};t[s][0].call(c.exports,function(e){var r=t[s][1][e];return o(r?r:e)},c,c.exports,e,t,r,n)}return r[s].exports}for(var i="function"==typeof require&&require,s=0;se;e++)n.push(t[e].handler);return n}var o={once:"boolean",scope:"object"},i=function(){this._enabled=!0,this._children=[],this._handlers={},this._handlersAll=[]};i.prototype.on=function(t,e,r){var n,s,a,u,h,c;if("function"==typeof e){for(h="string"==typeof t?[t]:t,n=0,s=h.length;n!==s;n+=1)if(u=h[n]){this._handlers[u]||(this._handlers[u]=[]),c={handler:e};for(a in r||{}){if(!o[a])throw new Error('The option "'+a+'" is not recognized by Emmett.');c[a]=r[a]}this._handlers[u].push(c)}}else if(t&&"object"==typeof t&&!Array.isArray(t))for(u in t)i.prototype.on.call(this,u,t[u],e);else{if("function"!=typeof t)throw new Error("Wrong arguments.");c={handler:t};for(a in r||{}){if(!o[a])throw new Error('The option "'+a+'" is not recognized by Emmett.');c[a]=r[a]}this._handlersAll.push(c)}return this},i.prototype.once=function(t,e,r){if("function"==typeof e)r=r||{},r.once=!0,this.on(t,e,r);else{if((!t||"object"!=typeof t||Array.isArray(t))&&"function"!=typeof t)throw new Error("Wrong arguments.");e=e||{},e.once=!0,this.on(t,e)}return this},i.prototype.off=function(t,e){var r,n,o,i,s,a,u,h="string"==typeof t?[t]:t;if(1===arguments.length&&"function"==typeof h){e=arguments[0];for(s in this._handlers){for(a=[],r=0,n=this._handlers[s].length;r!==n;r+=1)this._handlers[s][r].handler!==e&&a.push(this._handlers[s][r]);this._handlers[s]=a}for(a=[],r=0,n=this._handlersAll.length;r!==n;r+=1)this._handlersAll[r].handler!==e&&a.push(this._handlersAll[r]);this._handlersAll=a}else if(2===arguments.length)for(r=0,n=h.length;r!==n;r+=1){if(u=h[r],this._handlers[u]){for(a=[],o=0,i=this._handlers[u].length;o!==i;o+=1)this._handlers[u][o].handler!==e&&a.push(this._handlers[u][o]);this._handlers[u]=a}this._handlers[u]&&0===this._handlers[u].length&&delete this._handlers[u]}return this},i.prototype.unbindAll=function(){var t;this._handlersAll=[];for(t in this._handlers)delete this._handlers[t];return this},i.prototype.emit=function(t,e){var r,n,o,i,s,a,u,h,c,l,f="string"==typeof t?[t]:t;if(!this._enabled)return this;for(e=void 0===e?{}:e,r=0,n=f.length;r!==n;r+=1)if(l=f[r],c=(this._handlers[l]||[]).concat(this._handlersAll),c.length){for(u={type:l,data:e||{},target:this},a=[],o=0,i=c.length;o!==i;o+=1)(this._handlers[l]&&this._handlers[l].indexOf(c[o])>=0||this._handlersAll.indexOf(c[o])>=0)&&(c[o].handler.call("scope"in c[o]?c[o].scope:this,u),c[o].once&&a.push(c[o]));for(s=0;sr;r++)if(t._children[r]===e){t._children.splice(r,1);break}}),this._children.push(e),e},i.prototype.listeners=function(t){var r,n,o,i=[];if(t)for(i=e(this._handlers[t]),n=0,o=this._children.length;o>n;n++)i=i.concat(this._children[n].listeners(t));else{i=e(this._handlersAll);for(r in this._handlers)i=i.concat(e(this._handlers[r]));for(n=0,o=this._children.length;o>n;n++)i=i.concat(this._children[n].listeners())}return i},i.prototype.kill=function(){if(this.emit("emmett:kill"),this.unbindAll(),this._handlers=null,this._handlersAll=null,this._enabled=!1,this._children)for(var t=0,e=this._children.length;e>t;t++)this._children[t].kill();this._children=null},i.prototype.disable=function(){return this._enabled=!1,this},i.prototype.enable=function(){return this._enabled=!0,this},i.version="2.1.2","undefined"!=typeof n?("undefined"!=typeof r&&r.exports&&(n=r.exports=i),n.Emitter=i):"function"==typeof t&&t.amd?t("emmett",[],function(){return i}):this.Emitter=i}).call(this)},{}],4:[function(e,r,n){!function(){"use strict";function e(t){function e(t,o){var s,a,u,h,c,l,f,p,d=!1,y=!1,g=r.get(t);if("string"===r.get(o)){for(s=o.replace(/^[\?\!]/,"").split(/\|/),u=s.length,a=0;u>a;a++)if(i.indexOf(s[a])<0&&!(s[a]in n))throw new Error("Invalid type.");if(o.match(/^\?/)&&(d=!0),o.replace(/^\?/,"").match(/^\!/)&&(y=!0),y&&d)throw new Error("Invalid type.");for(a in s)if(n[s[a]]&&("function"==typeof n[s[a]].type?n[s[a]].type.call(r,t)===!0:!e(t,n[s[a]].type)))return y?(c=new Error,c.message='Expected a "'+o+'" but found a "'+s[a]+'".',c.expected=o,c.type=s[a],c.value=t,c):null;return null===t||void 0===t?y||d?null:(c=new Error,c.message='Expected a "'+o+'" but found a "'+g+'".',c.expected=o,c.type=g,c.value=t,c):(f=~s.indexOf("*"),p=~s.indexOf(g),y&&(f||p)?(c=new Error,c.message='Expected a "'+o+'" but found a "'+(p?g:"*")+'".',c.type=p?g:"*",c.expected=o,c.value=t,c):y||f||p?null:(c=new Error,c.message='Expected a "'+o+'" but found a "'+g+'".',c.expected=o,c.type=g,c.value=t,c))}if("object"===r.get(o)){if("object"!==g)return c=new Error,c.message='Expected an object but found a "'+g+'".',c.expected=o,c.type=g,c.value=t,c;for(h in o)if(l=e(t[h],o[h]))return c=l,c.path=c.path?[h].concat(c.path):[h],c;for(h in t)if(void 0===o[h])return c=new Error,c.message='Unexpected key "'+h+'".',c.type=g,c.value=t,c;return null}if("array"===r.get(o)){if(1!==o.length)throw new Error("Invalid type.");if("array"!==g)return c=new Error,c.message='Expected an array but found a "'+g+'".',c.expected=o,c.type=g,c.value=t,c;for(u=t.length,a=0;u>a;a++)if(l=e(t[a],o[0]))return c=l,c.path=c.path?[a].concat(c.path):[a],c;return null}throw new Error("Invalid type.")}var r=this,n={};if(this.add=function(t,e){var r,o,s,a,u,h;if(1===arguments.length){if("object"!==this.get(t))throw new Error("If types.add is called with one argument, this one has to be an object.");r=t,a=r.id,h=r.type}else{if(2!==arguments.length)throw new Error("types.add has to be called with one or two arguments.");if("string"!=typeof t||!t)throw new Error("If types.add is called with more than one argument, the first one must be the string id.");a=t,h=e}if("string"!==this.get(a)||0===a.length)throw new Error("A type requires an string id.");if(void 0!==n[a]&&"proto"!==n[a])throw new Error('The type "'+a+'" already exists.');if(~i.indexOf(a))throw new Error('"'+a+'" is a reserved type name.');n[a]=1,s=(r||{}).proto||[],s=Array.isArray(s)?s:[s],u={};for(o in s)void 0===n[s[o]]&&(n[s[o]]=1,u[s[o]]=1);if("function"!==this.get(h)&&!this.isValid(h))throw new Error("A type requires a valid definition. This one can be a preexistant type or else a function testing given objects.");if(n[a]=void 0===r?{id:a,type:h}:{},void 0!==r)for(o in r)n[a][o]=r[o];for(o in u)o!==a&&delete n[o];return this},this.has=function(t){return!!n[t]},this.get=function(t){return null===t||void 0===t?String(t):o[Object.prototype.toString.call(t)]||"object"},this.check=function(t,r,n){var o=e(t,r);if(n&&o)throw o;return!o},this.isValid=function(t){var e,r,o;if("string"===this.get(t)){e=t.replace(/^[\?\!]/,"").split(/\|/);for(o in e)if(i.indexOf(e[o])<0&&!(e[o]in n))return!1;return!0}if("object"===this.get(t)){for(r in t)if(!this.isValid(t[r]))return!1;return!0}return"array"===this.get(t)&&1===t.length?this.isValid(t[0]):!1},this.add("type",function(t){return this.isValid(t)}.bind(this)),this.add("primitive",function(t){return!t||!(t instanceof Object||"object"==typeof t)}),t=t||{},"object"!==this.get(t))throw Error("Invalid argument.");for(var s in t)this.add(s,t[s])}var o={},i=["*"];!function(){var t,e,r=["Arguments","Boolean","Number","String","Function","Array","Date","RegExp","Object"];for(t in r)e=r[t],i.push(e.toLowerCase()),o["[object "+e+"]"]=e.toLowerCase()}();var s=e;e.call(s),Object.defineProperty(s,"version",{value:"0.3.1"}),"undefined"!=typeof n?("undefined"!=typeof r&&r.exports&&(n=r.exports=s),n.types=s):"function"==typeof t&&t.amd?t("typology",[],function(){return s}):this.types=s}(this)},{}],5:[function(t,e){function r(t){return t+"$"+(new Date).getTime()+(""+Math.random()).replace("0.","")}function n(t,e){if(arguments.length<1&&(t={}),!(this instanceof n))return new n(t,e);if(!f.Object(t)&&!f.Array(t))throw Error("Baobab: invalid data.");if(i.call(this),this.options=a.shallowMerge(l,e),this._cloner=this.options.cloningFunction||a.deepClone,this._transaction={},this._future=void 0,this._cursors={},this.typology=this.options.typology?this.options.typology instanceof s?this.options.typology:new s(this.options.typology):new s,this.validate=this.options.validate||null,this.validate)try{this.typology.check(t,this.validate,!0)}catch(r){throw r.message="/"+r.path.join("/")+": "+r.message,r}this.data=this._cloner(t),this.mixin=c.baobab(this)}var o=t("./cursor.js"),i=t("emmett"),s=t("typology"),a=t("./helpers.js"),u=t("./update.js"),h=t("./merge.js"),c=t("./mixins.js"),l=t("../defaults.js"),f=t("./type.js");a.inherits(n,i),n.prototype.commit=function(){this.options.shiftReferences&&(this.data=a.shallowClone(this.data));var t=u(this.data,this._transaction,this.options);if(this.validate){var e,r,n=[],o=t.length;for(r=0;o>r;r++)if(e=a.getIn(this.validate,t[r]))try{this.typology.check(this.get(t[r]),e,!0)}catch(i){i.path=t[r].concat(i.path||[]),n.push(i)}n.length&&this.emit("invalid",{errors:n})}return this._transaction={},this._future&&(this._future=clearTimeout(this._future)),this.emit("update",{log:t}),this},n.prototype.select=function(t){if(!t)throw Error("Baobab.select: invalid path.");if(arguments.length>1&&(t=a.arrayOf(arguments)),!f.Path(t))throw Error("Baobab.select: invalid path.");t=f.Array(t)?t:[t];var e,n=f.ComplexPath(t);if(n&&(e=a.solvePath(this.data,t)),this.options.cursorSingletons){var i=t.map(function(t){return f.Function(t)?r("fn"):f.Object(t)?r("ob"):t}).join("λ");if(this._cursors[i])return this._cursors[i];var s=new o(this,t,e,i);return this._cursors[i]=s,s}return new o(this,t)},n.prototype.root=function(){return this.select([])},n.prototype.reference=function(t){if(arguments.length>1&&(t=a.arrayOf(arguments)),!f.Path(t))throw Error("Baobab.get: invalid path.");return a.getIn(this.data,f.String(t)||f.Number(t)?[t]:t)},n.prototype.get=function(){var t=this.reference.apply(this,arguments);return this.options.clone?this._cloner(t):t},n.prototype.clone=function(){return this._cloner(this.reference.apply(this,arguments))},n.prototype.set=function(t,e){if(arguments.length<2)throw Error("Baobab.set: expects a key and a value.");var r={};if(f.Array(t)){var n=a.solvePath(this.data,t);if(!n)throw Error("Baobab.set: could not solve dynamic path.");r=a.pathObject(n,{$set:e})}else r[t]={$set:e};return this.update(r)},n.prototype.unset=function(t){if(!t&&0!==t)throw Error("Baobab.unset: expects a valid key to unset.");var e={};return e[t]={$unset:!0},this.update(e)},n.prototype.update=function(t){var e=this;if(!f.Object(t))throw Error("Baobab.update: wrong specification.");return this._transaction=h(t,this._transaction),this.options.autoCommit?this.options.asynchronous?(this._future||(this._future=setTimeout(e.commit.bind(e,null),0)),this):this.commit():this},n.prototype.release=function(){delete this.data,delete this._transaction,delete this._history;for(var t in this._cursors)this._cursors[t].release();delete this._cursors,this.kill()},n.prototype.toJSON=function(){return this.reference()},e.exports=n},{"../defaults.js":1,"./cursor.js":7,"./helpers.js":8,"./merge.js":9,"./mixins.js":10,"./type.js":11,"./update.js":12,emmett:3,typology:4}],6:[function(t,e){function r(t,e){e.on("update",t.cursorListener),t.tree.off("update",t.treeListener),t.tree.on("update",t.treeListener)}function n(t){var e=this;if(arguments.length<2)throw Error("baobab.Combination: not enough arguments.");var n=arguments[1],o=s.arrayOf(arguments).slice(2);if(n instanceof Array&&(o=n.slice(1),n=n[0]),!a.Cursor(n))throw Error("baobab.Combination: argument should be a cursor.");if("or"!==t&&"and"!==t)throw Error("baobab.Combination: invalid operator.");i.call(this),this.cursors=[n],this.operators=[],this.tree=n.tree,this.updates=new Array(this.cursors.length),this.cursorListener=function(){e.updates[e.cursors.indexOf(this)]=!0},this.treeListener=function(){var t,r,n=e.updates[0];for(t=1,r=e.cursors.length;r>t;t++)n="or"===e.operators[t-1]?n||e.updates[t]:n&&e.updates[t];n&&e.emit("update"),e.updates=new Array(e.cursors.length)},this.bound=!1;var u=this.on,h=this.once,c=function(){e.bound||(e.bound=!0,e.cursors.forEach(function(t){r(e,t)}))};this.on=function(){return c(),u.apply(this,arguments)},this.once=function(){return c(),h.apply(this,arguments)},o.forEach(function(e){this[t](e)},this)}function o(t){n.prototype[t]=function(e){if(!a.Cursor(e))throw this.release(),Error("baobab.Combination."+t+": argument should be a cursor.");if(~this.cursors.indexOf(e))throw this.release(),Error("baobab.Combination."+t+": cursor already in combination.");return this.cursors.push(e),this.operators.push(t),this.updates.length++,this.bound&&r(this,e),this}}var i=t("emmett"),s=t("./helpers.js"),a=t("./type.js");s.inherits(n,i),o("or"),o("and"),n.prototype.release=function(){this.cursors.forEach(function(t){t.off("update",this.cursorListener)},this),this.tree.off("update",this.treeListener),this.cursors=null,this.operators=null,this.tree=null,this.updates=null,this.kill()},e.exports=n},{"./helpers.js":8,"./type.js":11,emmett:3}],7:[function(t,e){function r(t,e,r,o){var a=this;n.call(this),e=e||[],this.tree=t,this.path=e,this.hash=o,this.relevant=void 0!==this.reference(),this.complexPath=!!r,this.solvedPath=this.complexPath?r:this.path,this.updateHandler=function(t){var e,r,n,o,i,u,h=t.data.log,c=!1;if(a.complexPath&&(a.solvedPath=s.solvePath(a.tree.data,a.path)),!a.path.length)return a.emit("update");t:for(i=0,n=h.length;n>i;i++)for(e=h[i],u=0,o=e.length;o>u&&(r=e[u],r===""+a.solvedPath[u]);u++)if(u+1===o||u+1===a.solvedPath.length){c=!0;break t}var l=void 0!==a.reference();a.relevant?l&&c?a.emit("update"):l||(a.emit("irrelevant"),a.relevant=!1):l&&c&&(a.emit("relevant"),a.emit("update"),a.relevant=!0)},this.mixin=i.cursor(this);var u=!1,h=this.on,c=this.once,l=function(){u||(u=!0,a.tree.on("update",a.updateHandler))};this.on=function(){return l(),h.apply(this,arguments)},this.once=function(){return l(),c.apply(this,arguments)}}var n=t("emmett"),o=t("./combination.js"),i=t("./mixins.js"),s=t("./helpers.js"),a=t("./type.js");s.inherits(r,n),r.prototype.isRoot=function(){return!this.path.length},r.prototype.isLeaf=function(){return a.Primitive(this.reference())},r.prototype.isBranch=function(){return!this.isLeaf()&&!this.isRoot()},r.prototype.root=function(){return this.tree.root()},r.prototype.select=function(t){if(arguments.length>1&&(t=s.arrayOf(arguments)),!a.Path(t))throw Error("baobab.Cursor.select: invalid path.");return this.tree.select(this.path.concat(t))},r.prototype.up=function(){return this.solvedPath&&this.solvedPath.length?this.tree.select(this.path.slice(0,-1)):null},r.prototype.left=function(){var t=+this.solvedPath[this.solvedPath.length-1];if(isNaN(t))throw Error("baobab.Cursor.left: cannot go left on a non-list type.");return t?this.tree.select(this.solvedPath.slice(0,-1).concat(t-1)):null},r.prototype.leftmost=function(){var t=+this.solvedPath[this.solvedPath.length-1];if(isNaN(t))throw Error("baobab.Cursor.leftmost: cannot go left on a non-list type.");return this.tree.select(this.solvedPath.slice(0,-1).concat(0))},r.prototype.right=function(){var t=+this.solvedPath[this.solvedPath.length-1];if(isNaN(t))throw Error("baobab.Cursor.right: cannot go right on a non-list type.");return t+1===this.up().reference().length?null:this.tree.select(this.solvedPath.slice(0,-1).concat(t+1))},r.prototype.rightmost=function(){var t=+this.solvedPath[this.solvedPath.length-1];if(isNaN(t))throw Error("baobab.Cursor.right: cannot go right on a non-list type.");var e=this.up().reference();return this.tree.select(this.solvedPath.slice(0,-1).concat(e.length-1))},r.prototype.down=function(){+this.solvedPath[this.solvedPath.length-1];return this.reference()instanceof Array?this.tree.select(this.solvedPath.concat(0)):null},r.prototype.get=function(t){return arguments.length>1&&(t=s.arrayOf(arguments)),this.tree.get(a.Step(t)?this.solvedPath.concat(t):this.solvedPath)},r.prototype.reference=function(t){return arguments.length>1&&(t=s.arrayOf(arguments)),this.tree.reference(a.Step(t)?this.solvedPath.concat(t):this.solvedPath)},r.prototype.clone=function(t){return arguments.length>1&&(t=s.arrayOf(arguments)),this.tree.clone(a.Step(t)?this.solvedPath.concat(t):this.solvedPath)},r.prototype.set=function(t,e){if(arguments.length<2)throw Error("baobab.Cursor.set: expecting at least key/value.");var r=this.reference();if("object"!=typeof r)throw Error("baobab.Cursor.set: trying to set key to a non-object.");var n={};if(a.Array(t)){var o=s.solvePath(r,t);if(!o)throw Error("baobab.Cursor.set: could not solve dynamic path.");n=s.pathObject(o,{$set:e})}else n[t]={$set:e};return this.update(n)},r.prototype.edit=function(t){return this.update({$set:t})},r.prototype.unset=function(t){if(!t&&0!==t)throw Error("baobab.Cursor.unset: expects a valid key to unset.");if("object"!=typeof this.reference())throw Error("baobab.Cursor.set: trying to set key to a non-object.");var e={};return e[t]={$unset:!0},this.update(e)},r.prototype.remove=function(){if(this.isRoot())throw Error("baobab.Cursor.remove: cannot remove root node.");return this.update({$unset:!0})},r.prototype.apply=function(t){if("function"!=typeof t)throw Error("baobab.Cursor.apply: argument is not a function.");return this.update({$apply:t})},r.prototype.chain=function(t){if("function"!=typeof t)throw Error("baobab.Cursor.chain: argument is not a function.");return this.update({$chain:t})},r.prototype.push=function(t){if(!(this.reference()instanceof Array))throw Error("baobab.Cursor.push: trying to push to non-array value.");return this.update(arguments.length>1?{$push:s.arrayOf(arguments)}:{$push:t})},r.prototype.unshift=function(t){if(!(this.reference()instanceof Array))throw Error("baobab.Cursor.push: trying to push to non-array value.");return this.update(arguments.length>1?{$unshift:s.arrayOf(arguments)}:{$unshift:t})},r.prototype.merge=function(t){if(!a.Object(t))throw Error("baobab.Cursor.merge: trying to merge a non-object.");if(!a.Object(this.reference()))throw Error("baobab.Cursor.merge: trying to merge into a non-object.");this.update({$merge:t})},r.prototype.update=function(t){return this.tree.update(s.pathObject(this.solvedPath,t)),this},r.prototype.or=function(t){return new o("or",this,t)},r.prototype.and=function(t){return new o("and",this,t)},r.prototype.release=function(){this.tree.off("update",this.updateHandler),this.hash&&delete this.tree._cursors[this.hash],delete this.tree,delete this.path,delete this.solvedPath,this.kill()},r.prototype.toJSON=function(){return this.reference()},a.Cursor=function(t){return t instanceof r},e.exports=r},{"./combination.js":6,"./helpers.js":8,"./mixins.js":10,"./type.js":11,emmett:3}],8:[function(t,e){function r(t){return Array.prototype.slice.call(t)}function n(t,e){var r,n={};for(r in t)n[r]=t[r];for(r in e)n[r]=e[r];return n}function o(t){var e=t.source,r="";return t.global&&(r+="g"),t.multiline&&(r+="m"),t.ignoreCase&&(r+="i"),t.sticky&&(r+="y"),t.unicode&&(r+="u"),new RegExp(e,r)}function i(t,e){if(!e||"object"!=typeof e||e instanceof Error||e instanceof ArrayBuffer)return e;if(g.Array(e)){if(t){var r,n,i=[];for(r=0,n=e.length;n>r;r++)i.push(m(e[r]));return i}return e.slice(0)}if(g.Date(e))return new Date(e.getTime());if(e instanceof RegExp)return o(e);if(g.Object(e)){var s,a={};e.constructor&&e.constructor!==Object&&(a=Object.create(e.constructor.prototype));for(s in e)e.hasOwnProperty(s)&&(a[s]=t?m(e[s]):e[s]);return a}return e}function s(t,e){return function(r){return e(t(r))}}function a(t,e){var r,n;for(r=0,n=t.length;n>r;r++)if(e(t[r]))return t[r]}function u(t,e){var r,n;for(r=0,n=t.length;n>r;r++)if(e(t[r]))return r;return-1}function h(t,e){var r,n=!0;if(!t)return!1;for(r in e)if(g.Object(e[r]))n=n&&h(t[r],e[r]);else if(g.Array(e[r]))n=n&&!!~e[r].indexOf(t[r]);else if(t[r]!==e[r])return!1;return n}function c(t,e){return a(t,function(t){return h(t,e)})}function l(t,e){return u(t,function(t){return h(t,e)})}function f(t,e){e=e||[];var r,n,o=t;for(r=0,n=e.length;n>r;r++){if(!o)return;if("function"==typeof e[r]){if(!g.Array(o))return;o=a(o,e[r])}else if("object"==typeof e[r]){if(!g.Array(o))return;o=c(o,e[r])}else o=o[e[r]]}return o}function p(t,e){var r,n,o,i=[],s=t;for(n=0,o=e.length;o>n;n++){if(!s)return null;if("function"==typeof e[n]){if(!g.Array(s))return;r=u(s,e[n]),i.push(r),s=s[r]}else if("object"==typeof e[n]){if(!g.Array(s))return;r=l(s,e[n]),i.push(r),s=s[r]}else i.push(e[n]),s=s[e[n]]||{}}return i}function d(t,e){var r,n=t.length,o={},i=o;for(n||(o=e),r=0;n>r;r++)i[t[r]]=r+1===n?e:{},i=i[t[r]];return o}function y(t,e){t.super_=e;var r=function(){};r.prototype=e.prototype,t.prototype=new r,t.prototype.constructor=t}var g=t("./type.js"),b=i.bind(null,!1),m=i.bind(null,!0);e.exports={arrayOf:r,deepClone:m,shallowClone:b,shallowMerge:n,compose:s,getIn:f,inherits:y,pathObject:d,solvePath:p}},{"./type.js":11}],9:[function(t,e){function r(t,e){return e in(t||{})}function n(t,e,n){return r(t,n)&&r(e,n)}function o(){var t,e,r,a,u={},h=arguments.length;for(r=h-1;r>=0;r--){if(arguments[r].$unset)delete u.$set,delete u.$apply,delete u.$merge,u.$unset=arguments[r].$unset;else{if(arguments[r].$set){delete u.$apply,delete u.$merge,delete u.$unset,u.$set=arguments[r].$set;continue}if(arguments[r].$merge){delete u.$set,delete u.$apply,delete u.$unset,u.$merge=arguments[r].$merge;continue}if(arguments[r].$apply){delete u.$set,delete u.$merge,delete u.$unset,u.$apply=arguments[r].$apply;continue}if(arguments[r].$chain){delete u.$set,delete u.$merge,delete u.$unset,u.$apply=u.$apply?i.compose(u.$apply,arguments[r].$chain):arguments[r].$chain;continue}}for(a in arguments[r])t=u[a],e=arguments[r][a],t&&s.Object(e)?n(t,e,"$push")?t.$push=s.Array(t.$push)?t.$push.concat(e.$push):[t.$push].concat(e.$push):n(t,e,"$unshift")?t.$unshift=s.Array(e.$unshift)?e.$unshift.concat(t.$unshift):[e.$unshift].concat(t.$unshift):u[a]=o(e,t):u[a]=e}return u}var i=t("./helpers.js"),s=t("./type.js");e.exports=o},{"./helpers.js":8,"./type.js":11}],10:[function(t,e){var r=t("./combination.js"),n=t("./type.js");e.exports={baobab:function(t){return{mixins:[{getInitialState:function(){if(this.tree=t,!this.cursor&&!this.cursors)return{};if(this.cursor&&this.cursors)throw Error("baobab.mixin: you cannot have both `component.cursor` and `component.cursors`. Please make up your mind.");if(this.__type=null,this.__updateHandler=function(){this.setState(this.__getCursorData())}.bind(this),this.cursor){if(!n.MixinCursor(this.cursor))throw Error("baobab.mixin.cursor: invalid data (cursor, string, array or function).");n.Function(this.cursor)&&(this.cursor=this.cursor()),n.Cursor(this.cursor)||(this.cursor=t.select(this.cursor)),this.__getCursorData=function(){return{cursor:this.cursor.get()}}.bind(this),this.__type="single"}else if(this.cursors){if(!n.MixinCursors(this.cursors))throw Error("baobab.mixin.cursor: invalid data (object, array or function).");if(n.Function(this.cursors)&&(this.cursors=this.cursors()),n.Array(this.cursors))this.cursors=this.cursors.map(function(e){return n.Cursor(e)?e:t.select(e)}),this.__getCursorData=function(){return{cursors:this.cursors.map(function(t){return t.get()})}}.bind(this),this.__type="array";else{for(var e in this.cursors)n.Cursor(this.cursors[e])||(this.cursors[e]=t.select(this.cursors[e]));this.__getCursorData=function(){var t={};for(e in this.cursors)t[e]=this.cursors[e].get();return{cursors:t}}.bind(this),this.__type="object"}}return this.__getCursorData()},componentDidMount:function(){"single"===this.__type?(this.__combination=new r("or",[this.cursor]),this.__combination.on("update",this.__updateHandler)):"array"===this.__type?(this.__combination=new r("or",this.cursors),this.__combination.on("update",this.__updateHandler)):"object"===this.__type&&(this.__combination=new r("or",Object.keys(this.cursors).map(function(t){return this.cursors[t]},this)),this.__combination.on("update",this.__updateHandler))},componentWillUnmount:function(){this.__combination&&this.__combination.release()}}].concat(t.options.mixins)}},cursor:function(t){return{mixins:[{getInitialState:function(){return this.cursor=t,this.__updateHandler=function(){this.setState({cursor:this.cursor.get()})}.bind(this),{cursor:this.cursor.get()}},componentDidMount:function(){this.cursor.on("update",this.__updateHandler)},componentWillUnmount:function(){this.cursor.off("update",this.__updateHandler)}}].concat(t.tree.options.mixins)}}}},{"./combination.js":6,"./type.js":11}],11:[function(t,e){var r=function(t){return Array.isArray(t)?"array":"object"==typeof t&&null!==t?"object":"string"==typeof t?"string":"number"==typeof t?"number":"boolean"==typeof t?"boolean":"function"==typeof t?"function":null===t?"null":void 0===t?"undefined":t instanceof Date?"date":"invalid"};r.Array=function(t){return Array.isArray(t)},r.Object=function(t){return!Array.isArray(t)&&"object"==typeof t&&null!==t},r.String=function(t){return"string"==typeof t},r.Number=function(t){return"number"==typeof t},r.Boolean=function(t){return"boolean"==typeof t},r.Function=function(t){return"function"==typeof t},r.Primitive=function(t){return"string"==typeof t||"number"==typeof t||"boolean"==typeof t},r.Date=function(t){return t instanceof Date},r.Step=function(t){var e=r(t),n=["null","undefined","invalid","date"];return-1===n.indexOf(e)},r.Path=function(t){var e=["object","string","number","function","undefined"];if(!r.Array(t))return e.indexOf(r(t))>=0;for(var n=0;n=0||r.Cursor(t)},r.MixinCursors=function(t){var e=["array","object","function"];return e.indexOf(r(t))>=0},r.ComplexPath=function(t){for(var e=["object","function"],n=0;n=0)return!0;return!1},e.exports=r},{}],12:[function(t,e){function r(t,e){var r=new Error("baobab.update: "+e+" at path /"+t.toString());return r.path=t,r}function n(t,e,n){n=n||{shiftReferences:!1};var a={};return function u(t,e,h,c){h=h||[];var l,f,p,d,y=h.join("λ");for(p in e)if(s[p])switch(d=e[p],a[y]=!0,p){case"$push":if(!i.Array(t))throw r(h,"using command $push to a non array");i.Array(d)?t.push.apply(t,d):t.push(d);break;case"$unshift":if(!i.Array(t))throw r(h,"using command $unshift to a non array");i.Array(d)?t.unshift.apply(t,d):t.unshift(d)}else if(f=y?y+"λ"+p:p,"$unset"in(e[p]||{}))a[f]=!0,i.Array(t)?n.shiftReferences?c[h[h.length-1]]=t.slice(0,+p).concat(t.slice(+p+1)):t.splice(p,1):delete t[p];else if("$set"in(e[p]||{}))d=e[p].$set,a[f]=!0,t[p]=d;else if("$apply"in(e[p]||{})||"$chain"in(e[p]||{})){if(l=e[p].$apply||e[p].$chain,"function"!=typeof l)throw r(h.concat(p),"using command $apply with a non function");a[f]=!0,t[p]=l.call(null,t[p])}else if("$merge"in(e[p]||{})){if(d=e[p].$merge,!i.Object(t[p]))throw r(h.concat(p),"using command $merge on a non-object");a[f]=!0,t[p]=o.shallowMerge(t[p],d)}else if(n.shiftReferences&&("$push"in(e[p]||{})||"$unshift"in(e[p]||{}))){if("$push"in(e[p]||{})){if(d=e[p].$push,!i.Array(t[p]))throw r(h.concat(p),"using command $push to a non array");t[p]=t[p].concat(d)}if("$unshift"in(e[p]||{})){if(d=e[p].$unshift,!i.Array(t[p]))throw r(h.concat(p),"using command $unshift to a non array");t[p]=(d instanceof Array?d:[d]).concat(t[p])}a[f]=!0}else"undefined"==typeof t[p]&&(t[p]={}),n.shiftReferences&&(t[p]=o.shallowClone(t[p])),u(t[p],e[p],h.concat(p),t)}(t,e),Object.keys(a).map(function(t){return t.split("λ")})}var o=t("./helpers.js"),i=t("./type.js"),s={};["$set","$push","$unshift","$apply","$merge"].forEach(function(t){s[t]=!0}),e.exports=n},{"./helpers.js":8,"./type.js":11}]},{},[2])(2)}); \ No newline at end of file +!function(t){if("object"==typeof exports&&"undefined"!=typeof module)module.exports=t();else if("function"==typeof define&&define.amd)define([],t);else{var e;e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:this,e.Baobab=t()}}(function(){var t;return function e(t,r,n){function o(s,a){if(!r[s]){if(!t[s]){var u="function"==typeof require&&require;if(!a&&u)return u(s,!0);if(i)return i(s,!0);var h=new Error("Cannot find module '"+s+"'");throw h.code="MODULE_NOT_FOUND",h}var c=r[s]={exports:{}};t[s][0].call(c.exports,function(e){var r=t[s][1][e];return o(r?r:e)},c,c.exports,e,t,r,n)}return r[s].exports}for(var i="function"==typeof require&&require,s=0;se;e++)n.push(t[e].handler);return n}var o={once:"boolean",scope:"object"},i=function(){this._enabled=!0,this._children=[],this._handlers={},this._handlersAll=[]};i.prototype.on=function(t,e,r){var n,s,a,u,h,c;if("function"==typeof e){for(h="string"==typeof t?[t]:t,n=0,s=h.length;n!==s;n+=1)if(u=h[n]){this._handlers[u]||(this._handlers[u]=[]),c={handler:e};for(a in r||{}){if(!o[a])throw new Error('The option "'+a+'" is not recognized by Emmett.');c[a]=r[a]}this._handlers[u].push(c)}}else if(t&&"object"==typeof t&&!Array.isArray(t))for(u in t)i.prototype.on.call(this,u,t[u],e);else{if("function"!=typeof t)throw new Error("Wrong arguments.");c={handler:t};for(a in r||{}){if(!o[a])throw new Error('The option "'+a+'" is not recognized by Emmett.');c[a]=r[a]}this._handlersAll.push(c)}return this},i.prototype.once=function(t,e,r){if("function"==typeof e)r=r||{},r.once=!0,this.on(t,e,r);else{if((!t||"object"!=typeof t||Array.isArray(t))&&"function"!=typeof t)throw new Error("Wrong arguments.");e=e||{},e.once=!0,this.on(t,e)}return this},i.prototype.off=function(t,e){var r,n,o,i,s,a,u,h="string"==typeof t?[t]:t;if(1===arguments.length&&"function"==typeof h){e=arguments[0];for(s in this._handlers){for(a=[],r=0,n=this._handlers[s].length;r!==n;r+=1)this._handlers[s][r].handler!==e&&a.push(this._handlers[s][r]);this._handlers[s]=a}for(a=[],r=0,n=this._handlersAll.length;r!==n;r+=1)this._handlersAll[r].handler!==e&&a.push(this._handlersAll[r]);this._handlersAll=a}else if(2===arguments.length)for(r=0,n=h.length;r!==n;r+=1){if(u=h[r],this._handlers[u]){for(a=[],o=0,i=this._handlers[u].length;o!==i;o+=1)this._handlers[u][o].handler!==e&&a.push(this._handlers[u][o]);this._handlers[u]=a}this._handlers[u]&&0===this._handlers[u].length&&delete this._handlers[u]}return this},i.prototype.unbindAll=function(){var t;this._handlersAll=[];for(t in this._handlers)delete this._handlers[t];return this},i.prototype.emit=function(t,e){var r,n,o,i,s,a,u,h,c,l,f="string"==typeof t?[t]:t;if(!this._enabled)return this;for(e=void 0===e?{}:e,r=0,n=f.length;r!==n;r+=1)if(l=f[r],c=(this._handlers[l]||[]).concat(this._handlersAll),c.length){for(u={type:l,data:e||{},target:this},a=[],o=0,i=c.length;o!==i;o+=1)(this._handlers[l]&&this._handlers[l].indexOf(c[o])>=0||this._handlersAll.indexOf(c[o])>=0)&&(c[o].handler.call("scope"in c[o]?c[o].scope:this,u),c[o].once&&a.push(c[o]));for(s=0;sr;r++)if(t._children[r]===e){t._children.splice(r,1);break}}),this._children.push(e),e},i.prototype.listeners=function(t){var r,n,o,i=[];if(t)for(i=e(this._handlers[t]),n=0,o=this._children.length;o>n;n++)i=i.concat(this._children[n].listeners(t));else{i=e(this._handlersAll);for(r in this._handlers)i=i.concat(e(this._handlers[r]));for(n=0,o=this._children.length;o>n;n++)i=i.concat(this._children[n].listeners())}return i},i.prototype.kill=function(){if(this.emit("emmett:kill"),this.unbindAll(),this._handlers=null,this._handlersAll=null,this._enabled=!1,this._children)for(var t=0,e=this._children.length;e>t;t++)this._children[t].kill();this._children=null},i.prototype.disable=function(){return this._enabled=!1,this},i.prototype.enable=function(){return this._enabled=!0,this},i.version="2.1.2","undefined"!=typeof n?("undefined"!=typeof r&&r.exports&&(n=r.exports=i),n.Emitter=i):"function"==typeof t&&t.amd?t("emmett",[],function(){return i}):this.Emitter=i}).call(this)},{}],4:[function(t,e){function r(t){return t+"$"+(new Date).getTime()+(""+Math.random()).replace("0.","")}function n(t,e){if(arguments.length<1&&(t={}),!(this instanceof n))return new n(t,e);if(!l.Object(t)&&!l.Array(t))throw Error("Baobab: invalid data.");i.call(this),this.options=s.shallowMerge(c,e),this._cloner=this.options.cloningFunction||s.deepClone,this._transaction={},this._future=void 0,this._cursors={},this.data=this._cloner(t),this.mixin=h.baobab(this)}var o=t("./cursor.js"),i=t("emmett"),s=t("./helpers.js"),a=t("./update.js"),u=t("./merge.js"),h=t("./mixins.js"),c=t("../defaults.js"),l=t("./type.js");s.inherits(n,i),n.prototype.commit=function(){this.options.shiftReferences&&(this.data=s.shallowClone(this.data));var t=a(this.data,this._transaction,this.options);return this._transaction={},this._future&&(this._future=clearTimeout(this._future)),this.emit("update",{log:t}),this},n.prototype.select=function(t){if(!t)throw Error("Baobab.select: invalid path.");if(arguments.length>1&&(t=s.arrayOf(arguments)),!l.Path(t))throw Error("Baobab.select: invalid path.");t=l.Array(t)?t:[t];var e,n=l.ComplexPath(t);if(n&&(e=s.solvePath(this.data,t)),this.options.cursorSingletons){var i=t.map(function(t){return l.Function(t)?r("fn"):l.Object(t)?r("ob"):t}).join("λ");if(this._cursors[i])return this._cursors[i];var a=new o(this,t,e,i);return this._cursors[i]=a,a}return new o(this,t)},n.prototype.root=function(){return this.select([])},n.prototype.reference=function(t){if(arguments.length>1&&(t=s.arrayOf(arguments)),!l.Path(t))throw Error("Baobab.get: invalid path.");return s.getIn(this.data,l.String(t)||l.Number(t)?[t]:t)},n.prototype.get=function(){var t=this.reference.apply(this,arguments);return this.options.clone?this._cloner(t):t},n.prototype.clone=function(){return this._cloner(this.reference.apply(this,arguments))},n.prototype.set=function(t,e){if(arguments.length<2)throw Error("Baobab.set: expects a key and a value.");var r={};if(l.Array(t)){var n=s.solvePath(this.data,t);if(!n)throw Error("Baobab.set: could not solve dynamic path.");r=s.pathObject(n,{$set:e})}else r[t]={$set:e};return this.update(r)},n.prototype.unset=function(t){if(!t&&0!==t)throw Error("Baobab.unset: expects a valid key to unset.");var e={};return e[t]={$unset:!0},this.update(e)},n.prototype.update=function(t){var e=this;if(!l.Object(t))throw Error("Baobab.update: wrong specification.");return this._transaction=u(t,this._transaction),this.options.autoCommit?this.options.asynchronous?(this._future||(this._future=setTimeout(e.commit.bind(e,null),0)),this):this.commit():this},n.prototype.release=function(){delete this.data,delete this._transaction,delete this._history;for(var t in this._cursors)this._cursors[t].release();delete this._cursors,this.kill()},n.prototype.toJSON=function(){return this.reference()},e.exports=n},{"../defaults.js":1,"./cursor.js":6,"./helpers.js":7,"./merge.js":8,"./mixins.js":9,"./type.js":10,"./update.js":11,emmett:3}],5:[function(t,e){function r(t,e){e.on("update",t.cursorListener),t.tree.off("update",t.treeListener),t.tree.on("update",t.treeListener)}function n(t){var e=this;if(arguments.length<2)throw Error("baobab.Combination: not enough arguments.");var n=arguments[1],o=s.arrayOf(arguments).slice(2);if(n instanceof Array&&(o=n.slice(1),n=n[0]),!a.Cursor(n))throw Error("baobab.Combination: argument should be a cursor.");if("or"!==t&&"and"!==t)throw Error("baobab.Combination: invalid operator.");i.call(this),this.cursors=[n],this.operators=[],this.tree=n.tree,this.updates=new Array(this.cursors.length),this.cursorListener=function(){e.updates[e.cursors.indexOf(this)]=!0},this.treeListener=function(){var t,r,n=e.updates[0];for(t=1,r=e.cursors.length;r>t;t++)n="or"===e.operators[t-1]?n||e.updates[t]:n&&e.updates[t];n&&e.emit("update"),e.updates=new Array(e.cursors.length)},this.bound=!1;var u=this.on,h=this.once,c=function(){e.bound||(e.bound=!0,e.cursors.forEach(function(t){r(e,t)}))};this.on=function(){return c(),u.apply(this,arguments)},this.once=function(){return c(),h.apply(this,arguments)},o.forEach(function(e){this[t](e)},this)}function o(t){n.prototype[t]=function(e){if(!a.Cursor(e))throw this.release(),Error("baobab.Combination."+t+": argument should be a cursor.");if(~this.cursors.indexOf(e))throw this.release(),Error("baobab.Combination."+t+": cursor already in combination.");return this.cursors.push(e),this.operators.push(t),this.updates.length++,this.bound&&r(this,e),this}}var i=t("emmett"),s=t("./helpers.js"),a=t("./type.js");s.inherits(n,i),o("or"),o("and"),n.prototype.release=function(){this.cursors.forEach(function(t){t.off("update",this.cursorListener)},this),this.tree.off("update",this.treeListener),this.cursors=null,this.operators=null,this.tree=null,this.updates=null,this.kill()},e.exports=n},{"./helpers.js":7,"./type.js":10,emmett:3}],6:[function(t,e){function r(t,e,r,o){var a=this;n.call(this),e=e||[],this.tree=t,this.path=e,this.hash=o,this.relevant=void 0!==this.reference(),this.complexPath=!!r,this.solvedPath=this.complexPath?r:this.path,this.updateHandler=function(t){var e,r,n,o,i,u,h=t.data.log,c=!1;if(a.complexPath&&(a.solvedPath=s.solvePath(a.tree.data,a.path)),!a.path.length)return a.emit("update");t:for(i=0,n=h.length;n>i;i++)for(e=h[i],u=0,o=e.length;o>u&&(r=e[u],r===""+a.solvedPath[u]);u++)if(u+1===o||u+1===a.solvedPath.length){c=!0;break t}var l=void 0!==a.reference();a.relevant?l&&c?a.emit("update"):l||(a.emit("irrelevant"),a.relevant=!1):l&&c&&(a.emit("relevant"),a.emit("update"),a.relevant=!0)},this.mixin=i.cursor(this);var u=!1,h=this.on,c=this.once,l=function(){u||(u=!0,a.tree.on("update",a.updateHandler))};this.on=function(){return l(),h.apply(this,arguments)},this.once=function(){return l(),c.apply(this,arguments)}}var n=t("emmett"),o=t("./combination.js"),i=t("./mixins.js"),s=t("./helpers.js"),a=t("./type.js");s.inherits(r,n),r.prototype.isRoot=function(){return!this.path.length},r.prototype.isLeaf=function(){return a.Primitive(this.reference())},r.prototype.isBranch=function(){return!this.isLeaf()&&!this.isRoot()},r.prototype.root=function(){return this.tree.root()},r.prototype.select=function(t){if(arguments.length>1&&(t=s.arrayOf(arguments)),!a.Path(t))throw Error("baobab.Cursor.select: invalid path.");return this.tree.select(this.path.concat(t))},r.prototype.up=function(){return this.solvedPath&&this.solvedPath.length?this.tree.select(this.path.slice(0,-1)):null},r.prototype.left=function(){var t=+this.solvedPath[this.solvedPath.length-1];if(isNaN(t))throw Error("baobab.Cursor.left: cannot go left on a non-list type.");return t?this.tree.select(this.solvedPath.slice(0,-1).concat(t-1)):null},r.prototype.leftmost=function(){var t=+this.solvedPath[this.solvedPath.length-1];if(isNaN(t))throw Error("baobab.Cursor.leftmost: cannot go left on a non-list type.");return this.tree.select(this.solvedPath.slice(0,-1).concat(0))},r.prototype.right=function(){var t=+this.solvedPath[this.solvedPath.length-1];if(isNaN(t))throw Error("baobab.Cursor.right: cannot go right on a non-list type.");return t+1===this.up().reference().length?null:this.tree.select(this.solvedPath.slice(0,-1).concat(t+1))},r.prototype.rightmost=function(){var t=+this.solvedPath[this.solvedPath.length-1];if(isNaN(t))throw Error("baobab.Cursor.right: cannot go right on a non-list type.");var e=this.up().reference();return this.tree.select(this.solvedPath.slice(0,-1).concat(e.length-1))},r.prototype.down=function(){+this.solvedPath[this.solvedPath.length-1];return this.reference()instanceof Array?this.tree.select(this.solvedPath.concat(0)):null},r.prototype.get=function(t){return arguments.length>1&&(t=s.arrayOf(arguments)),this.tree.get(a.Step(t)?this.solvedPath.concat(t):this.solvedPath)},r.prototype.reference=function(t){return arguments.length>1&&(t=s.arrayOf(arguments)),this.tree.reference(a.Step(t)?this.solvedPath.concat(t):this.solvedPath)},r.prototype.clone=function(t){return arguments.length>1&&(t=s.arrayOf(arguments)),this.tree.clone(a.Step(t)?this.solvedPath.concat(t):this.solvedPath)},r.prototype.set=function(t,e){if(arguments.length<2)throw Error("baobab.Cursor.set: expecting at least key/value.");var r=this.reference();if("object"!=typeof r)throw Error("baobab.Cursor.set: trying to set key to a non-object.");var n={};if(a.Array(t)){var o=s.solvePath(r,t);if(!o)throw Error("baobab.Cursor.set: could not solve dynamic path.");n=s.pathObject(o,{$set:e})}else n[t]={$set:e};return this.update(n)},r.prototype.edit=function(t){return this.update({$set:t})},r.prototype.unset=function(t){if(!t&&0!==t)throw Error("baobab.Cursor.unset: expects a valid key to unset.");if("object"!=typeof this.reference())throw Error("baobab.Cursor.set: trying to set key to a non-object.");var e={};return e[t]={$unset:!0},this.update(e)},r.prototype.remove=function(){if(this.isRoot())throw Error("baobab.Cursor.remove: cannot remove root node.");return this.update({$unset:!0})},r.prototype.apply=function(t){if("function"!=typeof t)throw Error("baobab.Cursor.apply: argument is not a function.");return this.update({$apply:t})},r.prototype.chain=function(t){if("function"!=typeof t)throw Error("baobab.Cursor.chain: argument is not a function.");return this.update({$chain:t})},r.prototype.push=function(t){if(!(this.reference()instanceof Array))throw Error("baobab.Cursor.push: trying to push to non-array value.");return this.update(arguments.length>1?{$push:s.arrayOf(arguments)}:{$push:t})},r.prototype.unshift=function(t){if(!(this.reference()instanceof Array))throw Error("baobab.Cursor.push: trying to push to non-array value.");return this.update(arguments.length>1?{$unshift:s.arrayOf(arguments)}:{$unshift:t})},r.prototype.merge=function(t){if(!a.Object(t))throw Error("baobab.Cursor.merge: trying to merge a non-object.");if(!a.Object(this.reference()))throw Error("baobab.Cursor.merge: trying to merge into a non-object.");this.update({$merge:t})},r.prototype.update=function(t){return this.tree.update(s.pathObject(this.solvedPath,t)),this},r.prototype.or=function(t){return new o("or",this,t)},r.prototype.and=function(t){return new o("and",this,t)},r.prototype.release=function(){this.tree.off("update",this.updateHandler),this.hash&&delete this.tree._cursors[this.hash],delete this.tree,delete this.path,delete this.solvedPath,this.kill()},r.prototype.toJSON=function(){return this.reference()},a.Cursor=function(t){return t instanceof r},e.exports=r},{"./combination.js":5,"./helpers.js":7,"./mixins.js":9,"./type.js":10,emmett:3}],7:[function(t,e){function r(t){return Array.prototype.slice.call(t)}function n(t,e){var r,n={};for(r in t)n[r]=t[r];for(r in e)n[r]=e[r];return n}function o(t){var e=t.source,r="";return t.global&&(r+="g"),t.multiline&&(r+="m"),t.ignoreCase&&(r+="i"),t.sticky&&(r+="y"),t.unicode&&(r+="u"),new RegExp(e,r)}function i(t,e){if(!e||"object"!=typeof e||e instanceof Error||e instanceof ArrayBuffer)return e;if(b.Array(e)){if(t){var r,n,i=[];for(r=0,n=e.length;n>r;r++)i.push(m(e[r]));return i}return e.slice(0)}if(b.Date(e))return new Date(e.getTime());if(e instanceof RegExp)return o(e);if(b.Object(e)){var s,a={};e.constructor&&e.constructor!==Object&&(a=Object.create(e.constructor.prototype));for(s in e)e.hasOwnProperty(s)&&(a[s]=t?m(e[s]):e[s]);return a}return e}function s(t,e){return function(r){return e(t(r))}}function a(t,e){var r,n;for(r=0,n=t.length;n>r;r++)if(e(t[r]))return t[r]}function u(t,e){var r,n;for(r=0,n=t.length;n>r;r++)if(e(t[r]))return r;return-1}function h(t,e){var r,n=!0;if(!t)return!1;for(r in e)if(b.Object(e[r]))n=n&&h(t[r],e[r]);else if(b.Array(e[r]))n=n&&!!~e[r].indexOf(t[r]);else if(t[r]!==e[r])return!1;return n}function c(t,e){return a(t,function(t){return h(t,e)})}function l(t,e){return u(t,function(t){return h(t,e)})}function f(t,e){e=e||[];var r,n,o=t;for(r=0,n=e.length;n>r;r++){if(!o)return;if("function"==typeof e[r]){if(!b.Array(o))return;o=a(o,e[r])}else if("object"==typeof e[r]){if(!b.Array(o))return;o=c(o,e[r])}else o=o[e[r]]}return o}function p(t,e){var r,n,o,i=[],s=t;for(n=0,o=e.length;o>n;n++){if(!s)return null;if("function"==typeof e[n]){if(!b.Array(s))return;r=u(s,e[n]),i.push(r),s=s[r]}else if("object"==typeof e[n]){if(!b.Array(s))return;r=l(s,e[n]),i.push(r),s=s[r]}else i.push(e[n]),s=s[e[n]]||{}}return i}function d(t,e){var r,n=t.length,o={},i=o;for(n||(o=e),r=0;n>r;r++)i[t[r]]=r+1===n?e:{},i=i[t[r]];return o}function y(t,e){t.super_=e;var r=function(){};r.prototype=e.prototype,t.prototype=new r,t.prototype.constructor=t}var b=t("./type.js"),g=i.bind(null,!1),m=i.bind(null,!0);e.exports={arrayOf:r,deepClone:m,shallowClone:g,shallowMerge:n,compose:s,getIn:f,inherits:y,pathObject:d,solvePath:p}},{"./type.js":10}],8:[function(t,e){function r(t,e){return e in(t||{})}function n(t,e,n){return r(t,n)&&r(e,n)}function o(){var t,e,r,a,u={},h=arguments.length;for(r=h-1;r>=0;r--){if(arguments[r].$unset)delete u.$set,delete u.$apply,delete u.$merge,u.$unset=arguments[r].$unset;else{if(arguments[r].$set){delete u.$apply,delete u.$merge,delete u.$unset,u.$set=arguments[r].$set;continue}if(arguments[r].$merge){delete u.$set,delete u.$apply,delete u.$unset,u.$merge=arguments[r].$merge;continue}if(arguments[r].$apply){delete u.$set,delete u.$merge,delete u.$unset,u.$apply=arguments[r].$apply;continue}if(arguments[r].$chain){delete u.$set,delete u.$merge,delete u.$unset,u.$apply=u.$apply?i.compose(u.$apply,arguments[r].$chain):arguments[r].$chain;continue}}for(a in arguments[r])t=u[a],e=arguments[r][a],t&&s.Object(e)?n(t,e,"$push")?t.$push=s.Array(t.$push)?t.$push.concat(e.$push):[t.$push].concat(e.$push):n(t,e,"$unshift")?t.$unshift=s.Array(e.$unshift)?e.$unshift.concat(t.$unshift):[e.$unshift].concat(t.$unshift):u[a]=o(e,t):u[a]=e}return u}var i=t("./helpers.js"),s=t("./type.js");e.exports=o},{"./helpers.js":7,"./type.js":10}],9:[function(t,e){var r=t("./combination.js"),n=t("./type.js");e.exports={baobab:function(t){return{mixins:[{getInitialState:function(){if(this.tree=t,!this.cursor&&!this.cursors)return{};if(this.cursor&&this.cursors)throw Error("baobab.mixin: you cannot have both `component.cursor` and `component.cursors`. Please make up your mind.");if(this.__type=null,this.__updateHandler=function(){this.setState(this.__getCursorData())}.bind(this),this.cursor){if(!n.MixinCursor(this.cursor))throw Error("baobab.mixin.cursor: invalid data (cursor, string, array or function).");n.Function(this.cursor)&&(this.cursor=this.cursor()),n.Cursor(this.cursor)||(this.cursor=t.select(this.cursor)),this.__getCursorData=function(){return{cursor:this.cursor.get()}}.bind(this),this.__type="single"}else if(this.cursors){if(!n.MixinCursors(this.cursors))throw Error("baobab.mixin.cursor: invalid data (object, array or function).");if(n.Function(this.cursors)&&(this.cursors=this.cursors()),n.Array(this.cursors))this.cursors=this.cursors.map(function(e){return n.Cursor(e)?e:t.select(e)}),this.__getCursorData=function(){return{cursors:this.cursors.map(function(t){return t.get()})}}.bind(this),this.__type="array";else{for(var e in this.cursors)n.Cursor(this.cursors[e])||(this.cursors[e]=t.select(this.cursors[e]));this.__getCursorData=function(){var t={};for(e in this.cursors)t[e]=this.cursors[e].get();return{cursors:t}}.bind(this),this.__type="object"}}return this.__getCursorData()},componentDidMount:function(){"single"===this.__type?(this.__combination=new r("or",[this.cursor]),this.__combination.on("update",this.__updateHandler)):"array"===this.__type?(this.__combination=new r("or",this.cursors),this.__combination.on("update",this.__updateHandler)):"object"===this.__type&&(this.__combination=new r("or",Object.keys(this.cursors).map(function(t){return this.cursors[t]},this)),this.__combination.on("update",this.__updateHandler))},componentWillUnmount:function(){this.__combination&&this.__combination.release()}}].concat(t.options.mixins)}},cursor:function(t){return{mixins:[{getInitialState:function(){return this.cursor=t,this.__updateHandler=function(){this.setState({cursor:this.cursor.get()})}.bind(this),{cursor:this.cursor.get()}},componentDidMount:function(){this.cursor.on("update",this.__updateHandler)},componentWillUnmount:function(){this.cursor.off("update",this.__updateHandler)}}].concat(t.tree.options.mixins)}}}},{"./combination.js":5,"./type.js":10}],10:[function(t,e){var r=function(t){return Array.isArray(t)?"array":"object"==typeof t&&null!==t?"object":"string"==typeof t?"string":"number"==typeof t?"number":"boolean"==typeof t?"boolean":"function"==typeof t?"function":null===t?"null":void 0===t?"undefined":t instanceof Date?"date":"invalid"};r.Array=function(t){return Array.isArray(t)},r.Object=function(t){return!Array.isArray(t)&&"object"==typeof t&&null!==t},r.String=function(t){return"string"==typeof t},r.Number=function(t){return"number"==typeof t},r.Boolean=function(t){return"boolean"==typeof t},r.Function=function(t){return"function"==typeof t},r.Primitive=function(t){return"string"==typeof t||"number"==typeof t||"boolean"==typeof t},r.Date=function(t){return t instanceof Date},r.Step=function(t){var e=r(t),n=["null","undefined","invalid","date"];return-1===n.indexOf(e)},r.Path=function(t){var e=["object","string","number","function","undefined"];if(!r.Array(t))return e.indexOf(r(t))>=0;for(var n=0;n=0||r.Cursor(t)},r.MixinCursors=function(t){var e=["array","object","function"];return e.indexOf(r(t))>=0},r.ComplexPath=function(t){for(var e=["object","function"],n=0;n=0)return!0;return!1},e.exports=r},{}],11:[function(t,e){function r(t,e){var r=new Error("baobab.update: "+e+" at path /"+t.toString());return r.path=t,r}function n(t,e,n){n=n||{shiftReferences:!1};var a={};return function u(t,e,h,c){h=h||[];var l,f,p,d,y=h.join("λ");for(p in e)if(s[p])switch(d=e[p],a[y]=!0,p){case"$push":if(!i.Array(t))throw r(h,"using command $push to a non array");i.Array(d)?t.push.apply(t,d):t.push(d);break;case"$unshift":if(!i.Array(t))throw r(h,"using command $unshift to a non array");i.Array(d)?t.unshift.apply(t,d):t.unshift(d)}else if(f=y?y+"λ"+p:p,"$unset"in(e[p]||{}))a[f]=!0,i.Array(t)?n.shiftReferences?c[h[h.length-1]]=t.slice(0,+p).concat(t.slice(+p+1)):t.splice(p,1):delete t[p];else if("$set"in(e[p]||{}))d=e[p].$set,a[f]=!0,t[p]=d;else if("$apply"in(e[p]||{})||"$chain"in(e[p]||{})){if(l=e[p].$apply||e[p].$chain,"function"!=typeof l)throw r(h.concat(p),"using command $apply with a non function");a[f]=!0,t[p]=l.call(null,t[p])}else if("$merge"in(e[p]||{})){if(d=e[p].$merge,!i.Object(t[p]))throw r(h.concat(p),"using command $merge on a non-object");a[f]=!0,t[p]=o.shallowMerge(t[p],d)}else if(n.shiftReferences&&("$push"in(e[p]||{})||"$unshift"in(e[p]||{}))){if("$push"in(e[p]||{})){if(d=e[p].$push,!i.Array(t[p]))throw r(h.concat(p),"using command $push to a non array");t[p]=t[p].concat(d)}if("$unshift"in(e[p]||{})){if(d=e[p].$unshift,!i.Array(t[p]))throw r(h.concat(p),"using command $unshift to a non array");t[p]=(d instanceof Array?d:[d]).concat(t[p])}a[f]=!0}else"undefined"==typeof t[p]&&(t[p]={}),n.shiftReferences&&(t[p]=o.shallowClone(t[p])),u(t[p],e[p],h.concat(p),t)}(t,e),Object.keys(a).map(function(t){return t.split("λ")})}var o=t("./helpers.js"),i=t("./type.js"),s={};["$set","$push","$unshift","$apply","$merge"].forEach(function(t){s[t]=!0}),e.exports=n},{"./helpers.js":7,"./type.js":10}]},{},[2])(2)}); \ No newline at end of file diff --git a/package.json b/package.json index 5b68454..8598e4c 100644 --- a/package.json +++ b/package.json @@ -4,8 +4,7 @@ "description": "JavaScript data tree with cursors.", "main": "index.js", "dependencies": { - "emmett": "^2.1.2", - "typology": "^0.3.1" + "emmett": "^2.1.2" }, "devDependencies": { "async": "~0.9.0", diff --git a/src/baobab.js b/src/baobab.js index 76f34ab..effa619 100644 --- a/src/baobab.js +++ b/src/baobab.js @@ -6,7 +6,6 @@ */ var Cursor = require('./cursor.js'), EventEmitter = require('emmett'), - Typology = require('typology'), helpers = require('./helpers.js'), update = require('./update.js'), merge = require('./merge.js'), @@ -45,25 +44,6 @@ function Baobab(initialData, opts) { this._future = undefined; this._cursors = {}; - // Internal typology - this.typology = this.options.typology ? - (this.options.typology instanceof Typology ? - this.options.typology : - new Typology(this.options.typology)) : - new Typology(); - - // Internal validation - this.validate = this.options.validate || null; - - if (this.validate) - try { - this.typology.check(initialData, this.validate, true); - } - catch (e) { - e.message = '/' + e.path.join('/') + ': ' + e.message; - throw e; - } - // Properties this.data = this._cloner(initialData); @@ -86,31 +66,6 @@ Baobab.prototype.commit = function() { // Applying modification (mutation) var log = update(this.data, this._transaction, this.options); - if (this.validate) { - var errors = [], - l = log.length, - d, - i; - - for (i = 0; i < l; i++) { - d = helpers.getIn(this.validate, log[i]); - - if (!d) - continue; - - try { - this.typology.check(this.get(log[i]), d, true); - } - catch (e) { - e.path = log[i].concat((e.path || [])); - errors.push(e); - } - } - - if (errors.length) - this.emit('invalid', {errors: errors}); - } - // Resetting this._transaction = {}; diff --git a/test/suites/baobab.js b/test/suites/baobab.js index 4ed73df..177f737 100644 --- a/test/suites/baobab.js +++ b/test/suites/baobab.js @@ -244,50 +244,4 @@ describe('Baobab API', function() { assert(shiftingTree.reference().root.admin.other === shiftingOriginal.root.admin.other); }); }); - - describe('Custom typology', function() { - - it('a baobab should have an internal typology.', function() { - var baobab = new Baobab({hello: 'world'}); - assert(baobab.typology instanceof Typology); - }); - - it('should be possible to pass a custom typology at instantiation.', function() { - var typology = new Typology({user: '?object'}), - baobab = new Baobab({hello: 'world'}, {typology: typology}); - - assert(baobab.typology instanceof Typology); - assert(baobab.typology.isValid('user')); - }); - - it('should be possible to pass an object defining custom types at instantiation.', function() { - var definitions = {user: '?object'}, - baobab = new Baobab({hello: 'world'}, {typology: definitions}); - - assert(baobab.typology instanceof Typology); - assert(baobab.typology.isValid('user')); - }); - - it('invalid initial data should throw an error.', function() { - - assert.throws(function() { - new Baobab( - {hello: 'world'}, - { - validate: {hello: 'word'}, - typology: {word: 'object'} - } - ); - }, /Expected/); - }); - - it('should emit an "invalid" event when data validation fails on commit.', function(done) { - var baobab = new Baobab({hello: 'world'}, {validate: {hello: 'string'}}); - - baobab.on('invalid', function(e) { - done(); - }); - baobab.set('hello', 42); - }); - }); }); From ac16fa3d2b49eae4793d8761183be8c9116625a7 Mon Sep 17 00:00:00 2001 From: Yomguithereal Date: Fri, 27 Mar 2015 19:35:11 +0100 Subject: [PATCH 03/73] Removing useless line --- build/baobab.min.js | 2 +- src/baobab.js | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/build/baobab.min.js b/build/baobab.min.js index 97215d5..5d47779 100644 --- a/build/baobab.min.js +++ b/build/baobab.min.js @@ -1,2 +1,2 @@ /* baobab.js - Version: 0.4.3 - Author: Yomguithereal (Guillaume Plique) */ -!function(t){if("object"==typeof exports&&"undefined"!=typeof module)module.exports=t();else if("function"==typeof define&&define.amd)define([],t);else{var e;e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:this,e.Baobab=t()}}(function(){var t;return function e(t,r,n){function o(s,a){if(!r[s]){if(!t[s]){var u="function"==typeof require&&require;if(!a&&u)return u(s,!0);if(i)return i(s,!0);var h=new Error("Cannot find module '"+s+"'");throw h.code="MODULE_NOT_FOUND",h}var c=r[s]={exports:{}};t[s][0].call(c.exports,function(e){var r=t[s][1][e];return o(r?r:e)},c,c.exports,e,t,r,n)}return r[s].exports}for(var i="function"==typeof require&&require,s=0;se;e++)n.push(t[e].handler);return n}var o={once:"boolean",scope:"object"},i=function(){this._enabled=!0,this._children=[],this._handlers={},this._handlersAll=[]};i.prototype.on=function(t,e,r){var n,s,a,u,h,c;if("function"==typeof e){for(h="string"==typeof t?[t]:t,n=0,s=h.length;n!==s;n+=1)if(u=h[n]){this._handlers[u]||(this._handlers[u]=[]),c={handler:e};for(a in r||{}){if(!o[a])throw new Error('The option "'+a+'" is not recognized by Emmett.');c[a]=r[a]}this._handlers[u].push(c)}}else if(t&&"object"==typeof t&&!Array.isArray(t))for(u in t)i.prototype.on.call(this,u,t[u],e);else{if("function"!=typeof t)throw new Error("Wrong arguments.");c={handler:t};for(a in r||{}){if(!o[a])throw new Error('The option "'+a+'" is not recognized by Emmett.');c[a]=r[a]}this._handlersAll.push(c)}return this},i.prototype.once=function(t,e,r){if("function"==typeof e)r=r||{},r.once=!0,this.on(t,e,r);else{if((!t||"object"!=typeof t||Array.isArray(t))&&"function"!=typeof t)throw new Error("Wrong arguments.");e=e||{},e.once=!0,this.on(t,e)}return this},i.prototype.off=function(t,e){var r,n,o,i,s,a,u,h="string"==typeof t?[t]:t;if(1===arguments.length&&"function"==typeof h){e=arguments[0];for(s in this._handlers){for(a=[],r=0,n=this._handlers[s].length;r!==n;r+=1)this._handlers[s][r].handler!==e&&a.push(this._handlers[s][r]);this._handlers[s]=a}for(a=[],r=0,n=this._handlersAll.length;r!==n;r+=1)this._handlersAll[r].handler!==e&&a.push(this._handlersAll[r]);this._handlersAll=a}else if(2===arguments.length)for(r=0,n=h.length;r!==n;r+=1){if(u=h[r],this._handlers[u]){for(a=[],o=0,i=this._handlers[u].length;o!==i;o+=1)this._handlers[u][o].handler!==e&&a.push(this._handlers[u][o]);this._handlers[u]=a}this._handlers[u]&&0===this._handlers[u].length&&delete this._handlers[u]}return this},i.prototype.unbindAll=function(){var t;this._handlersAll=[];for(t in this._handlers)delete this._handlers[t];return this},i.prototype.emit=function(t,e){var r,n,o,i,s,a,u,h,c,l,f="string"==typeof t?[t]:t;if(!this._enabled)return this;for(e=void 0===e?{}:e,r=0,n=f.length;r!==n;r+=1)if(l=f[r],c=(this._handlers[l]||[]).concat(this._handlersAll),c.length){for(u={type:l,data:e||{},target:this},a=[],o=0,i=c.length;o!==i;o+=1)(this._handlers[l]&&this._handlers[l].indexOf(c[o])>=0||this._handlersAll.indexOf(c[o])>=0)&&(c[o].handler.call("scope"in c[o]?c[o].scope:this,u),c[o].once&&a.push(c[o]));for(s=0;sr;r++)if(t._children[r]===e){t._children.splice(r,1);break}}),this._children.push(e),e},i.prototype.listeners=function(t){var r,n,o,i=[];if(t)for(i=e(this._handlers[t]),n=0,o=this._children.length;o>n;n++)i=i.concat(this._children[n].listeners(t));else{i=e(this._handlersAll);for(r in this._handlers)i=i.concat(e(this._handlers[r]));for(n=0,o=this._children.length;o>n;n++)i=i.concat(this._children[n].listeners())}return i},i.prototype.kill=function(){if(this.emit("emmett:kill"),this.unbindAll(),this._handlers=null,this._handlersAll=null,this._enabled=!1,this._children)for(var t=0,e=this._children.length;e>t;t++)this._children[t].kill();this._children=null},i.prototype.disable=function(){return this._enabled=!1,this},i.prototype.enable=function(){return this._enabled=!0,this},i.version="2.1.2","undefined"!=typeof n?("undefined"!=typeof r&&r.exports&&(n=r.exports=i),n.Emitter=i):"function"==typeof t&&t.amd?t("emmett",[],function(){return i}):this.Emitter=i}).call(this)},{}],4:[function(t,e){function r(t){return t+"$"+(new Date).getTime()+(""+Math.random()).replace("0.","")}function n(t,e){if(arguments.length<1&&(t={}),!(this instanceof n))return new n(t,e);if(!l.Object(t)&&!l.Array(t))throw Error("Baobab: invalid data.");i.call(this),this.options=s.shallowMerge(c,e),this._cloner=this.options.cloningFunction||s.deepClone,this._transaction={},this._future=void 0,this._cursors={},this.data=this._cloner(t),this.mixin=h.baobab(this)}var o=t("./cursor.js"),i=t("emmett"),s=t("./helpers.js"),a=t("./update.js"),u=t("./merge.js"),h=t("./mixins.js"),c=t("../defaults.js"),l=t("./type.js");s.inherits(n,i),n.prototype.commit=function(){this.options.shiftReferences&&(this.data=s.shallowClone(this.data));var t=a(this.data,this._transaction,this.options);return this._transaction={},this._future&&(this._future=clearTimeout(this._future)),this.emit("update",{log:t}),this},n.prototype.select=function(t){if(!t)throw Error("Baobab.select: invalid path.");if(arguments.length>1&&(t=s.arrayOf(arguments)),!l.Path(t))throw Error("Baobab.select: invalid path.");t=l.Array(t)?t:[t];var e,n=l.ComplexPath(t);if(n&&(e=s.solvePath(this.data,t)),this.options.cursorSingletons){var i=t.map(function(t){return l.Function(t)?r("fn"):l.Object(t)?r("ob"):t}).join("λ");if(this._cursors[i])return this._cursors[i];var a=new o(this,t,e,i);return this._cursors[i]=a,a}return new o(this,t)},n.prototype.root=function(){return this.select([])},n.prototype.reference=function(t){if(arguments.length>1&&(t=s.arrayOf(arguments)),!l.Path(t))throw Error("Baobab.get: invalid path.");return s.getIn(this.data,l.String(t)||l.Number(t)?[t]:t)},n.prototype.get=function(){var t=this.reference.apply(this,arguments);return this.options.clone?this._cloner(t):t},n.prototype.clone=function(){return this._cloner(this.reference.apply(this,arguments))},n.prototype.set=function(t,e){if(arguments.length<2)throw Error("Baobab.set: expects a key and a value.");var r={};if(l.Array(t)){var n=s.solvePath(this.data,t);if(!n)throw Error("Baobab.set: could not solve dynamic path.");r=s.pathObject(n,{$set:e})}else r[t]={$set:e};return this.update(r)},n.prototype.unset=function(t){if(!t&&0!==t)throw Error("Baobab.unset: expects a valid key to unset.");var e={};return e[t]={$unset:!0},this.update(e)},n.prototype.update=function(t){var e=this;if(!l.Object(t))throw Error("Baobab.update: wrong specification.");return this._transaction=u(t,this._transaction),this.options.autoCommit?this.options.asynchronous?(this._future||(this._future=setTimeout(e.commit.bind(e,null),0)),this):this.commit():this},n.prototype.release=function(){delete this.data,delete this._transaction,delete this._history;for(var t in this._cursors)this._cursors[t].release();delete this._cursors,this.kill()},n.prototype.toJSON=function(){return this.reference()},e.exports=n},{"../defaults.js":1,"./cursor.js":6,"./helpers.js":7,"./merge.js":8,"./mixins.js":9,"./type.js":10,"./update.js":11,emmett:3}],5:[function(t,e){function r(t,e){e.on("update",t.cursorListener),t.tree.off("update",t.treeListener),t.tree.on("update",t.treeListener)}function n(t){var e=this;if(arguments.length<2)throw Error("baobab.Combination: not enough arguments.");var n=arguments[1],o=s.arrayOf(arguments).slice(2);if(n instanceof Array&&(o=n.slice(1),n=n[0]),!a.Cursor(n))throw Error("baobab.Combination: argument should be a cursor.");if("or"!==t&&"and"!==t)throw Error("baobab.Combination: invalid operator.");i.call(this),this.cursors=[n],this.operators=[],this.tree=n.tree,this.updates=new Array(this.cursors.length),this.cursorListener=function(){e.updates[e.cursors.indexOf(this)]=!0},this.treeListener=function(){var t,r,n=e.updates[0];for(t=1,r=e.cursors.length;r>t;t++)n="or"===e.operators[t-1]?n||e.updates[t]:n&&e.updates[t];n&&e.emit("update"),e.updates=new Array(e.cursors.length)},this.bound=!1;var u=this.on,h=this.once,c=function(){e.bound||(e.bound=!0,e.cursors.forEach(function(t){r(e,t)}))};this.on=function(){return c(),u.apply(this,arguments)},this.once=function(){return c(),h.apply(this,arguments)},o.forEach(function(e){this[t](e)},this)}function o(t){n.prototype[t]=function(e){if(!a.Cursor(e))throw this.release(),Error("baobab.Combination."+t+": argument should be a cursor.");if(~this.cursors.indexOf(e))throw this.release(),Error("baobab.Combination."+t+": cursor already in combination.");return this.cursors.push(e),this.operators.push(t),this.updates.length++,this.bound&&r(this,e),this}}var i=t("emmett"),s=t("./helpers.js"),a=t("./type.js");s.inherits(n,i),o("or"),o("and"),n.prototype.release=function(){this.cursors.forEach(function(t){t.off("update",this.cursorListener)},this),this.tree.off("update",this.treeListener),this.cursors=null,this.operators=null,this.tree=null,this.updates=null,this.kill()},e.exports=n},{"./helpers.js":7,"./type.js":10,emmett:3}],6:[function(t,e){function r(t,e,r,o){var a=this;n.call(this),e=e||[],this.tree=t,this.path=e,this.hash=o,this.relevant=void 0!==this.reference(),this.complexPath=!!r,this.solvedPath=this.complexPath?r:this.path,this.updateHandler=function(t){var e,r,n,o,i,u,h=t.data.log,c=!1;if(a.complexPath&&(a.solvedPath=s.solvePath(a.tree.data,a.path)),!a.path.length)return a.emit("update");t:for(i=0,n=h.length;n>i;i++)for(e=h[i],u=0,o=e.length;o>u&&(r=e[u],r===""+a.solvedPath[u]);u++)if(u+1===o||u+1===a.solvedPath.length){c=!0;break t}var l=void 0!==a.reference();a.relevant?l&&c?a.emit("update"):l||(a.emit("irrelevant"),a.relevant=!1):l&&c&&(a.emit("relevant"),a.emit("update"),a.relevant=!0)},this.mixin=i.cursor(this);var u=!1,h=this.on,c=this.once,l=function(){u||(u=!0,a.tree.on("update",a.updateHandler))};this.on=function(){return l(),h.apply(this,arguments)},this.once=function(){return l(),c.apply(this,arguments)}}var n=t("emmett"),o=t("./combination.js"),i=t("./mixins.js"),s=t("./helpers.js"),a=t("./type.js");s.inherits(r,n),r.prototype.isRoot=function(){return!this.path.length},r.prototype.isLeaf=function(){return a.Primitive(this.reference())},r.prototype.isBranch=function(){return!this.isLeaf()&&!this.isRoot()},r.prototype.root=function(){return this.tree.root()},r.prototype.select=function(t){if(arguments.length>1&&(t=s.arrayOf(arguments)),!a.Path(t))throw Error("baobab.Cursor.select: invalid path.");return this.tree.select(this.path.concat(t))},r.prototype.up=function(){return this.solvedPath&&this.solvedPath.length?this.tree.select(this.path.slice(0,-1)):null},r.prototype.left=function(){var t=+this.solvedPath[this.solvedPath.length-1];if(isNaN(t))throw Error("baobab.Cursor.left: cannot go left on a non-list type.");return t?this.tree.select(this.solvedPath.slice(0,-1).concat(t-1)):null},r.prototype.leftmost=function(){var t=+this.solvedPath[this.solvedPath.length-1];if(isNaN(t))throw Error("baobab.Cursor.leftmost: cannot go left on a non-list type.");return this.tree.select(this.solvedPath.slice(0,-1).concat(0))},r.prototype.right=function(){var t=+this.solvedPath[this.solvedPath.length-1];if(isNaN(t))throw Error("baobab.Cursor.right: cannot go right on a non-list type.");return t+1===this.up().reference().length?null:this.tree.select(this.solvedPath.slice(0,-1).concat(t+1))},r.prototype.rightmost=function(){var t=+this.solvedPath[this.solvedPath.length-1];if(isNaN(t))throw Error("baobab.Cursor.right: cannot go right on a non-list type.");var e=this.up().reference();return this.tree.select(this.solvedPath.slice(0,-1).concat(e.length-1))},r.prototype.down=function(){+this.solvedPath[this.solvedPath.length-1];return this.reference()instanceof Array?this.tree.select(this.solvedPath.concat(0)):null},r.prototype.get=function(t){return arguments.length>1&&(t=s.arrayOf(arguments)),this.tree.get(a.Step(t)?this.solvedPath.concat(t):this.solvedPath)},r.prototype.reference=function(t){return arguments.length>1&&(t=s.arrayOf(arguments)),this.tree.reference(a.Step(t)?this.solvedPath.concat(t):this.solvedPath)},r.prototype.clone=function(t){return arguments.length>1&&(t=s.arrayOf(arguments)),this.tree.clone(a.Step(t)?this.solvedPath.concat(t):this.solvedPath)},r.prototype.set=function(t,e){if(arguments.length<2)throw Error("baobab.Cursor.set: expecting at least key/value.");var r=this.reference();if("object"!=typeof r)throw Error("baobab.Cursor.set: trying to set key to a non-object.");var n={};if(a.Array(t)){var o=s.solvePath(r,t);if(!o)throw Error("baobab.Cursor.set: could not solve dynamic path.");n=s.pathObject(o,{$set:e})}else n[t]={$set:e};return this.update(n)},r.prototype.edit=function(t){return this.update({$set:t})},r.prototype.unset=function(t){if(!t&&0!==t)throw Error("baobab.Cursor.unset: expects a valid key to unset.");if("object"!=typeof this.reference())throw Error("baobab.Cursor.set: trying to set key to a non-object.");var e={};return e[t]={$unset:!0},this.update(e)},r.prototype.remove=function(){if(this.isRoot())throw Error("baobab.Cursor.remove: cannot remove root node.");return this.update({$unset:!0})},r.prototype.apply=function(t){if("function"!=typeof t)throw Error("baobab.Cursor.apply: argument is not a function.");return this.update({$apply:t})},r.prototype.chain=function(t){if("function"!=typeof t)throw Error("baobab.Cursor.chain: argument is not a function.");return this.update({$chain:t})},r.prototype.push=function(t){if(!(this.reference()instanceof Array))throw Error("baobab.Cursor.push: trying to push to non-array value.");return this.update(arguments.length>1?{$push:s.arrayOf(arguments)}:{$push:t})},r.prototype.unshift=function(t){if(!(this.reference()instanceof Array))throw Error("baobab.Cursor.push: trying to push to non-array value.");return this.update(arguments.length>1?{$unshift:s.arrayOf(arguments)}:{$unshift:t})},r.prototype.merge=function(t){if(!a.Object(t))throw Error("baobab.Cursor.merge: trying to merge a non-object.");if(!a.Object(this.reference()))throw Error("baobab.Cursor.merge: trying to merge into a non-object.");this.update({$merge:t})},r.prototype.update=function(t){return this.tree.update(s.pathObject(this.solvedPath,t)),this},r.prototype.or=function(t){return new o("or",this,t)},r.prototype.and=function(t){return new o("and",this,t)},r.prototype.release=function(){this.tree.off("update",this.updateHandler),this.hash&&delete this.tree._cursors[this.hash],delete this.tree,delete this.path,delete this.solvedPath,this.kill()},r.prototype.toJSON=function(){return this.reference()},a.Cursor=function(t){return t instanceof r},e.exports=r},{"./combination.js":5,"./helpers.js":7,"./mixins.js":9,"./type.js":10,emmett:3}],7:[function(t,e){function r(t){return Array.prototype.slice.call(t)}function n(t,e){var r,n={};for(r in t)n[r]=t[r];for(r in e)n[r]=e[r];return n}function o(t){var e=t.source,r="";return t.global&&(r+="g"),t.multiline&&(r+="m"),t.ignoreCase&&(r+="i"),t.sticky&&(r+="y"),t.unicode&&(r+="u"),new RegExp(e,r)}function i(t,e){if(!e||"object"!=typeof e||e instanceof Error||e instanceof ArrayBuffer)return e;if(b.Array(e)){if(t){var r,n,i=[];for(r=0,n=e.length;n>r;r++)i.push(m(e[r]));return i}return e.slice(0)}if(b.Date(e))return new Date(e.getTime());if(e instanceof RegExp)return o(e);if(b.Object(e)){var s,a={};e.constructor&&e.constructor!==Object&&(a=Object.create(e.constructor.prototype));for(s in e)e.hasOwnProperty(s)&&(a[s]=t?m(e[s]):e[s]);return a}return e}function s(t,e){return function(r){return e(t(r))}}function a(t,e){var r,n;for(r=0,n=t.length;n>r;r++)if(e(t[r]))return t[r]}function u(t,e){var r,n;for(r=0,n=t.length;n>r;r++)if(e(t[r]))return r;return-1}function h(t,e){var r,n=!0;if(!t)return!1;for(r in e)if(b.Object(e[r]))n=n&&h(t[r],e[r]);else if(b.Array(e[r]))n=n&&!!~e[r].indexOf(t[r]);else if(t[r]!==e[r])return!1;return n}function c(t,e){return a(t,function(t){return h(t,e)})}function l(t,e){return u(t,function(t){return h(t,e)})}function f(t,e){e=e||[];var r,n,o=t;for(r=0,n=e.length;n>r;r++){if(!o)return;if("function"==typeof e[r]){if(!b.Array(o))return;o=a(o,e[r])}else if("object"==typeof e[r]){if(!b.Array(o))return;o=c(o,e[r])}else o=o[e[r]]}return o}function p(t,e){var r,n,o,i=[],s=t;for(n=0,o=e.length;o>n;n++){if(!s)return null;if("function"==typeof e[n]){if(!b.Array(s))return;r=u(s,e[n]),i.push(r),s=s[r]}else if("object"==typeof e[n]){if(!b.Array(s))return;r=l(s,e[n]),i.push(r),s=s[r]}else i.push(e[n]),s=s[e[n]]||{}}return i}function d(t,e){var r,n=t.length,o={},i=o;for(n||(o=e),r=0;n>r;r++)i[t[r]]=r+1===n?e:{},i=i[t[r]];return o}function y(t,e){t.super_=e;var r=function(){};r.prototype=e.prototype,t.prototype=new r,t.prototype.constructor=t}var b=t("./type.js"),g=i.bind(null,!1),m=i.bind(null,!0);e.exports={arrayOf:r,deepClone:m,shallowClone:g,shallowMerge:n,compose:s,getIn:f,inherits:y,pathObject:d,solvePath:p}},{"./type.js":10}],8:[function(t,e){function r(t,e){return e in(t||{})}function n(t,e,n){return r(t,n)&&r(e,n)}function o(){var t,e,r,a,u={},h=arguments.length;for(r=h-1;r>=0;r--){if(arguments[r].$unset)delete u.$set,delete u.$apply,delete u.$merge,u.$unset=arguments[r].$unset;else{if(arguments[r].$set){delete u.$apply,delete u.$merge,delete u.$unset,u.$set=arguments[r].$set;continue}if(arguments[r].$merge){delete u.$set,delete u.$apply,delete u.$unset,u.$merge=arguments[r].$merge;continue}if(arguments[r].$apply){delete u.$set,delete u.$merge,delete u.$unset,u.$apply=arguments[r].$apply;continue}if(arguments[r].$chain){delete u.$set,delete u.$merge,delete u.$unset,u.$apply=u.$apply?i.compose(u.$apply,arguments[r].$chain):arguments[r].$chain;continue}}for(a in arguments[r])t=u[a],e=arguments[r][a],t&&s.Object(e)?n(t,e,"$push")?t.$push=s.Array(t.$push)?t.$push.concat(e.$push):[t.$push].concat(e.$push):n(t,e,"$unshift")?t.$unshift=s.Array(e.$unshift)?e.$unshift.concat(t.$unshift):[e.$unshift].concat(t.$unshift):u[a]=o(e,t):u[a]=e}return u}var i=t("./helpers.js"),s=t("./type.js");e.exports=o},{"./helpers.js":7,"./type.js":10}],9:[function(t,e){var r=t("./combination.js"),n=t("./type.js");e.exports={baobab:function(t){return{mixins:[{getInitialState:function(){if(this.tree=t,!this.cursor&&!this.cursors)return{};if(this.cursor&&this.cursors)throw Error("baobab.mixin: you cannot have both `component.cursor` and `component.cursors`. Please make up your mind.");if(this.__type=null,this.__updateHandler=function(){this.setState(this.__getCursorData())}.bind(this),this.cursor){if(!n.MixinCursor(this.cursor))throw Error("baobab.mixin.cursor: invalid data (cursor, string, array or function).");n.Function(this.cursor)&&(this.cursor=this.cursor()),n.Cursor(this.cursor)||(this.cursor=t.select(this.cursor)),this.__getCursorData=function(){return{cursor:this.cursor.get()}}.bind(this),this.__type="single"}else if(this.cursors){if(!n.MixinCursors(this.cursors))throw Error("baobab.mixin.cursor: invalid data (object, array or function).");if(n.Function(this.cursors)&&(this.cursors=this.cursors()),n.Array(this.cursors))this.cursors=this.cursors.map(function(e){return n.Cursor(e)?e:t.select(e)}),this.__getCursorData=function(){return{cursors:this.cursors.map(function(t){return t.get()})}}.bind(this),this.__type="array";else{for(var e in this.cursors)n.Cursor(this.cursors[e])||(this.cursors[e]=t.select(this.cursors[e]));this.__getCursorData=function(){var t={};for(e in this.cursors)t[e]=this.cursors[e].get();return{cursors:t}}.bind(this),this.__type="object"}}return this.__getCursorData()},componentDidMount:function(){"single"===this.__type?(this.__combination=new r("or",[this.cursor]),this.__combination.on("update",this.__updateHandler)):"array"===this.__type?(this.__combination=new r("or",this.cursors),this.__combination.on("update",this.__updateHandler)):"object"===this.__type&&(this.__combination=new r("or",Object.keys(this.cursors).map(function(t){return this.cursors[t]},this)),this.__combination.on("update",this.__updateHandler))},componentWillUnmount:function(){this.__combination&&this.__combination.release()}}].concat(t.options.mixins)}},cursor:function(t){return{mixins:[{getInitialState:function(){return this.cursor=t,this.__updateHandler=function(){this.setState({cursor:this.cursor.get()})}.bind(this),{cursor:this.cursor.get()}},componentDidMount:function(){this.cursor.on("update",this.__updateHandler)},componentWillUnmount:function(){this.cursor.off("update",this.__updateHandler)}}].concat(t.tree.options.mixins)}}}},{"./combination.js":5,"./type.js":10}],10:[function(t,e){var r=function(t){return Array.isArray(t)?"array":"object"==typeof t&&null!==t?"object":"string"==typeof t?"string":"number"==typeof t?"number":"boolean"==typeof t?"boolean":"function"==typeof t?"function":null===t?"null":void 0===t?"undefined":t instanceof Date?"date":"invalid"};r.Array=function(t){return Array.isArray(t)},r.Object=function(t){return!Array.isArray(t)&&"object"==typeof t&&null!==t},r.String=function(t){return"string"==typeof t},r.Number=function(t){return"number"==typeof t},r.Boolean=function(t){return"boolean"==typeof t},r.Function=function(t){return"function"==typeof t},r.Primitive=function(t){return"string"==typeof t||"number"==typeof t||"boolean"==typeof t},r.Date=function(t){return t instanceof Date},r.Step=function(t){var e=r(t),n=["null","undefined","invalid","date"];return-1===n.indexOf(e)},r.Path=function(t){var e=["object","string","number","function","undefined"];if(!r.Array(t))return e.indexOf(r(t))>=0;for(var n=0;n=0||r.Cursor(t)},r.MixinCursors=function(t){var e=["array","object","function"];return e.indexOf(r(t))>=0},r.ComplexPath=function(t){for(var e=["object","function"],n=0;n=0)return!0;return!1},e.exports=r},{}],11:[function(t,e){function r(t,e){var r=new Error("baobab.update: "+e+" at path /"+t.toString());return r.path=t,r}function n(t,e,n){n=n||{shiftReferences:!1};var a={};return function u(t,e,h,c){h=h||[];var l,f,p,d,y=h.join("λ");for(p in e)if(s[p])switch(d=e[p],a[y]=!0,p){case"$push":if(!i.Array(t))throw r(h,"using command $push to a non array");i.Array(d)?t.push.apply(t,d):t.push(d);break;case"$unshift":if(!i.Array(t))throw r(h,"using command $unshift to a non array");i.Array(d)?t.unshift.apply(t,d):t.unshift(d)}else if(f=y?y+"λ"+p:p,"$unset"in(e[p]||{}))a[f]=!0,i.Array(t)?n.shiftReferences?c[h[h.length-1]]=t.slice(0,+p).concat(t.slice(+p+1)):t.splice(p,1):delete t[p];else if("$set"in(e[p]||{}))d=e[p].$set,a[f]=!0,t[p]=d;else if("$apply"in(e[p]||{})||"$chain"in(e[p]||{})){if(l=e[p].$apply||e[p].$chain,"function"!=typeof l)throw r(h.concat(p),"using command $apply with a non function");a[f]=!0,t[p]=l.call(null,t[p])}else if("$merge"in(e[p]||{})){if(d=e[p].$merge,!i.Object(t[p]))throw r(h.concat(p),"using command $merge on a non-object");a[f]=!0,t[p]=o.shallowMerge(t[p],d)}else if(n.shiftReferences&&("$push"in(e[p]||{})||"$unshift"in(e[p]||{}))){if("$push"in(e[p]||{})){if(d=e[p].$push,!i.Array(t[p]))throw r(h.concat(p),"using command $push to a non array");t[p]=t[p].concat(d)}if("$unshift"in(e[p]||{})){if(d=e[p].$unshift,!i.Array(t[p]))throw r(h.concat(p),"using command $unshift to a non array");t[p]=(d instanceof Array?d:[d]).concat(t[p])}a[f]=!0}else"undefined"==typeof t[p]&&(t[p]={}),n.shiftReferences&&(t[p]=o.shallowClone(t[p])),u(t[p],e[p],h.concat(p),t)}(t,e),Object.keys(a).map(function(t){return t.split("λ")})}var o=t("./helpers.js"),i=t("./type.js"),s={};["$set","$push","$unshift","$apply","$merge"].forEach(function(t){s[t]=!0}),e.exports=n},{"./helpers.js":7,"./type.js":10}]},{},[2])(2)}); \ No newline at end of file +!function(t){if("object"==typeof exports&&"undefined"!=typeof module)module.exports=t();else if("function"==typeof define&&define.amd)define([],t);else{var e;e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:this,e.Baobab=t()}}(function(){var t;return function e(t,r,n){function o(s,a){if(!r[s]){if(!t[s]){var u="function"==typeof require&&require;if(!a&&u)return u(s,!0);if(i)return i(s,!0);var h=new Error("Cannot find module '"+s+"'");throw h.code="MODULE_NOT_FOUND",h}var c=r[s]={exports:{}};t[s][0].call(c.exports,function(e){var r=t[s][1][e];return o(r?r:e)},c,c.exports,e,t,r,n)}return r[s].exports}for(var i="function"==typeof require&&require,s=0;se;e++)n.push(t[e].handler);return n}var o={once:"boolean",scope:"object"},i=function(){this._enabled=!0,this._children=[],this._handlers={},this._handlersAll=[]};i.prototype.on=function(t,e,r){var n,s,a,u,h,c;if("function"==typeof e){for(h="string"==typeof t?[t]:t,n=0,s=h.length;n!==s;n+=1)if(u=h[n]){this._handlers[u]||(this._handlers[u]=[]),c={handler:e};for(a in r||{}){if(!o[a])throw new Error('The option "'+a+'" is not recognized by Emmett.');c[a]=r[a]}this._handlers[u].push(c)}}else if(t&&"object"==typeof t&&!Array.isArray(t))for(u in t)i.prototype.on.call(this,u,t[u],e);else{if("function"!=typeof t)throw new Error("Wrong arguments.");c={handler:t};for(a in r||{}){if(!o[a])throw new Error('The option "'+a+'" is not recognized by Emmett.');c[a]=r[a]}this._handlersAll.push(c)}return this},i.prototype.once=function(t,e,r){if("function"==typeof e)r=r||{},r.once=!0,this.on(t,e,r);else{if((!t||"object"!=typeof t||Array.isArray(t))&&"function"!=typeof t)throw new Error("Wrong arguments.");e=e||{},e.once=!0,this.on(t,e)}return this},i.prototype.off=function(t,e){var r,n,o,i,s,a,u,h="string"==typeof t?[t]:t;if(1===arguments.length&&"function"==typeof h){e=arguments[0];for(s in this._handlers){for(a=[],r=0,n=this._handlers[s].length;r!==n;r+=1)this._handlers[s][r].handler!==e&&a.push(this._handlers[s][r]);this._handlers[s]=a}for(a=[],r=0,n=this._handlersAll.length;r!==n;r+=1)this._handlersAll[r].handler!==e&&a.push(this._handlersAll[r]);this._handlersAll=a}else if(2===arguments.length)for(r=0,n=h.length;r!==n;r+=1){if(u=h[r],this._handlers[u]){for(a=[],o=0,i=this._handlers[u].length;o!==i;o+=1)this._handlers[u][o].handler!==e&&a.push(this._handlers[u][o]);this._handlers[u]=a}this._handlers[u]&&0===this._handlers[u].length&&delete this._handlers[u]}return this},i.prototype.unbindAll=function(){var t;this._handlersAll=[];for(t in this._handlers)delete this._handlers[t];return this},i.prototype.emit=function(t,e){var r,n,o,i,s,a,u,h,c,l,f="string"==typeof t?[t]:t;if(!this._enabled)return this;for(e=void 0===e?{}:e,r=0,n=f.length;r!==n;r+=1)if(l=f[r],c=(this._handlers[l]||[]).concat(this._handlersAll),c.length){for(u={type:l,data:e||{},target:this},a=[],o=0,i=c.length;o!==i;o+=1)(this._handlers[l]&&this._handlers[l].indexOf(c[o])>=0||this._handlersAll.indexOf(c[o])>=0)&&(c[o].handler.call("scope"in c[o]?c[o].scope:this,u),c[o].once&&a.push(c[o]));for(s=0;sr;r++)if(t._children[r]===e){t._children.splice(r,1);break}}),this._children.push(e),e},i.prototype.listeners=function(t){var r,n,o,i=[];if(t)for(i=e(this._handlers[t]),n=0,o=this._children.length;o>n;n++)i=i.concat(this._children[n].listeners(t));else{i=e(this._handlersAll);for(r in this._handlers)i=i.concat(e(this._handlers[r]));for(n=0,o=this._children.length;o>n;n++)i=i.concat(this._children[n].listeners())}return i},i.prototype.kill=function(){if(this.emit("emmett:kill"),this.unbindAll(),this._handlers=null,this._handlersAll=null,this._enabled=!1,this._children)for(var t=0,e=this._children.length;e>t;t++)this._children[t].kill();this._children=null},i.prototype.disable=function(){return this._enabled=!1,this},i.prototype.enable=function(){return this._enabled=!0,this},i.version="2.1.2","undefined"!=typeof n?("undefined"!=typeof r&&r.exports&&(n=r.exports=i),n.Emitter=i):"function"==typeof t&&t.amd?t("emmett",[],function(){return i}):this.Emitter=i}).call(this)},{}],4:[function(t,e){function r(t){return t+"$"+(new Date).getTime()+(""+Math.random()).replace("0.","")}function n(t,e){if(arguments.length<1&&(t={}),!(this instanceof n))return new n(t,e);if(!l.Object(t)&&!l.Array(t))throw Error("Baobab: invalid data.");i.call(this),this.options=s.shallowMerge(c,e),this._cloner=this.options.cloningFunction||s.deepClone,this._transaction={},this._future=void 0,this._cursors={},this.data=this._cloner(t),this.mixin=h.baobab(this)}var o=t("./cursor.js"),i=t("emmett"),s=t("./helpers.js"),a=t("./update.js"),u=t("./merge.js"),h=t("./mixins.js"),c=t("../defaults.js"),l=t("./type.js");s.inherits(n,i),n.prototype.commit=function(){this.options.shiftReferences&&(this.data=s.shallowClone(this.data));var t=a(this.data,this._transaction,this.options);return this._transaction={},this._future&&(this._future=clearTimeout(this._future)),this.emit("update",{log:t}),this},n.prototype.select=function(t){if(!t)throw Error("Baobab.select: invalid path.");if(arguments.length>1&&(t=s.arrayOf(arguments)),!l.Path(t))throw Error("Baobab.select: invalid path.");t=l.Array(t)?t:[t];var e,n=l.ComplexPath(t);if(n&&(e=s.solvePath(this.data,t)),this.options.cursorSingletons){var i=t.map(function(t){return l.Function(t)?r("fn"):l.Object(t)?r("ob"):t}).join("λ");if(this._cursors[i])return this._cursors[i];var a=new o(this,t,e,i);return this._cursors[i]=a,a}return new o(this,t)},n.prototype.root=function(){return this.select([])},n.prototype.reference=function(t){if(arguments.length>1&&(t=s.arrayOf(arguments)),!l.Path(t))throw Error("Baobab.get: invalid path.");return s.getIn(this.data,l.String(t)||l.Number(t)?[t]:t)},n.prototype.get=function(){var t=this.reference.apply(this,arguments);return this.options.clone?this._cloner(t):t},n.prototype.clone=function(){return this._cloner(this.reference.apply(this,arguments))},n.prototype.set=function(t,e){if(arguments.length<2)throw Error("Baobab.set: expects a key and a value.");var r={};if(l.Array(t)){var n=s.solvePath(this.data,t);if(!n)throw Error("Baobab.set: could not solve dynamic path.");r=s.pathObject(n,{$set:e})}else r[t]={$set:e};return this.update(r)},n.prototype.unset=function(t){if(!t&&0!==t)throw Error("Baobab.unset: expects a valid key to unset.");var e={};return e[t]={$unset:!0},this.update(e)},n.prototype.update=function(t){var e=this;if(!l.Object(t))throw Error("Baobab.update: wrong specification.");return this._transaction=u(t,this._transaction),this.options.autoCommit?this.options.asynchronous?(this._future||(this._future=setTimeout(e.commit.bind(e,null),0)),this):this.commit():this},n.prototype.release=function(){delete this.data,delete this._transaction;for(var t in this._cursors)this._cursors[t].release();delete this._cursors,this.kill()},n.prototype.toJSON=function(){return this.reference()},e.exports=n},{"../defaults.js":1,"./cursor.js":6,"./helpers.js":7,"./merge.js":8,"./mixins.js":9,"./type.js":10,"./update.js":11,emmett:3}],5:[function(t,e){function r(t,e){e.on("update",t.cursorListener),t.tree.off("update",t.treeListener),t.tree.on("update",t.treeListener)}function n(t){var e=this;if(arguments.length<2)throw Error("baobab.Combination: not enough arguments.");var n=arguments[1],o=s.arrayOf(arguments).slice(2);if(n instanceof Array&&(o=n.slice(1),n=n[0]),!a.Cursor(n))throw Error("baobab.Combination: argument should be a cursor.");if("or"!==t&&"and"!==t)throw Error("baobab.Combination: invalid operator.");i.call(this),this.cursors=[n],this.operators=[],this.tree=n.tree,this.updates=new Array(this.cursors.length),this.cursorListener=function(){e.updates[e.cursors.indexOf(this)]=!0},this.treeListener=function(){var t,r,n=e.updates[0];for(t=1,r=e.cursors.length;r>t;t++)n="or"===e.operators[t-1]?n||e.updates[t]:n&&e.updates[t];n&&e.emit("update"),e.updates=new Array(e.cursors.length)},this.bound=!1;var u=this.on,h=this.once,c=function(){e.bound||(e.bound=!0,e.cursors.forEach(function(t){r(e,t)}))};this.on=function(){return c(),u.apply(this,arguments)},this.once=function(){return c(),h.apply(this,arguments)},o.forEach(function(e){this[t](e)},this)}function o(t){n.prototype[t]=function(e){if(!a.Cursor(e))throw this.release(),Error("baobab.Combination."+t+": argument should be a cursor.");if(~this.cursors.indexOf(e))throw this.release(),Error("baobab.Combination."+t+": cursor already in combination.");return this.cursors.push(e),this.operators.push(t),this.updates.length++,this.bound&&r(this,e),this}}var i=t("emmett"),s=t("./helpers.js"),a=t("./type.js");s.inherits(n,i),o("or"),o("and"),n.prototype.release=function(){this.cursors.forEach(function(t){t.off("update",this.cursorListener)},this),this.tree.off("update",this.treeListener),this.cursors=null,this.operators=null,this.tree=null,this.updates=null,this.kill()},e.exports=n},{"./helpers.js":7,"./type.js":10,emmett:3}],6:[function(t,e){function r(t,e,r,o){var a=this;n.call(this),e=e||[],this.tree=t,this.path=e,this.hash=o,this.relevant=void 0!==this.reference(),this.complexPath=!!r,this.solvedPath=this.complexPath?r:this.path,this.updateHandler=function(t){var e,r,n,o,i,u,h=t.data.log,c=!1;if(a.complexPath&&(a.solvedPath=s.solvePath(a.tree.data,a.path)),!a.path.length)return a.emit("update");t:for(i=0,n=h.length;n>i;i++)for(e=h[i],u=0,o=e.length;o>u&&(r=e[u],r===""+a.solvedPath[u]);u++)if(u+1===o||u+1===a.solvedPath.length){c=!0;break t}var l=void 0!==a.reference();a.relevant?l&&c?a.emit("update"):l||(a.emit("irrelevant"),a.relevant=!1):l&&c&&(a.emit("relevant"),a.emit("update"),a.relevant=!0)},this.mixin=i.cursor(this);var u=!1,h=this.on,c=this.once,l=function(){u||(u=!0,a.tree.on("update",a.updateHandler))};this.on=function(){return l(),h.apply(this,arguments)},this.once=function(){return l(),c.apply(this,arguments)}}var n=t("emmett"),o=t("./combination.js"),i=t("./mixins.js"),s=t("./helpers.js"),a=t("./type.js");s.inherits(r,n),r.prototype.isRoot=function(){return!this.path.length},r.prototype.isLeaf=function(){return a.Primitive(this.reference())},r.prototype.isBranch=function(){return!this.isLeaf()&&!this.isRoot()},r.prototype.root=function(){return this.tree.root()},r.prototype.select=function(t){if(arguments.length>1&&(t=s.arrayOf(arguments)),!a.Path(t))throw Error("baobab.Cursor.select: invalid path.");return this.tree.select(this.path.concat(t))},r.prototype.up=function(){return this.solvedPath&&this.solvedPath.length?this.tree.select(this.path.slice(0,-1)):null},r.prototype.left=function(){var t=+this.solvedPath[this.solvedPath.length-1];if(isNaN(t))throw Error("baobab.Cursor.left: cannot go left on a non-list type.");return t?this.tree.select(this.solvedPath.slice(0,-1).concat(t-1)):null},r.prototype.leftmost=function(){var t=+this.solvedPath[this.solvedPath.length-1];if(isNaN(t))throw Error("baobab.Cursor.leftmost: cannot go left on a non-list type.");return this.tree.select(this.solvedPath.slice(0,-1).concat(0))},r.prototype.right=function(){var t=+this.solvedPath[this.solvedPath.length-1];if(isNaN(t))throw Error("baobab.Cursor.right: cannot go right on a non-list type.");return t+1===this.up().reference().length?null:this.tree.select(this.solvedPath.slice(0,-1).concat(t+1))},r.prototype.rightmost=function(){var t=+this.solvedPath[this.solvedPath.length-1];if(isNaN(t))throw Error("baobab.Cursor.right: cannot go right on a non-list type.");var e=this.up().reference();return this.tree.select(this.solvedPath.slice(0,-1).concat(e.length-1))},r.prototype.down=function(){+this.solvedPath[this.solvedPath.length-1];return this.reference()instanceof Array?this.tree.select(this.solvedPath.concat(0)):null},r.prototype.get=function(t){return arguments.length>1&&(t=s.arrayOf(arguments)),this.tree.get(a.Step(t)?this.solvedPath.concat(t):this.solvedPath)},r.prototype.reference=function(t){return arguments.length>1&&(t=s.arrayOf(arguments)),this.tree.reference(a.Step(t)?this.solvedPath.concat(t):this.solvedPath)},r.prototype.clone=function(t){return arguments.length>1&&(t=s.arrayOf(arguments)),this.tree.clone(a.Step(t)?this.solvedPath.concat(t):this.solvedPath)},r.prototype.set=function(t,e){if(arguments.length<2)throw Error("baobab.Cursor.set: expecting at least key/value.");var r=this.reference();if("object"!=typeof r)throw Error("baobab.Cursor.set: trying to set key to a non-object.");var n={};if(a.Array(t)){var o=s.solvePath(r,t);if(!o)throw Error("baobab.Cursor.set: could not solve dynamic path.");n=s.pathObject(o,{$set:e})}else n[t]={$set:e};return this.update(n)},r.prototype.edit=function(t){return this.update({$set:t})},r.prototype.unset=function(t){if(!t&&0!==t)throw Error("baobab.Cursor.unset: expects a valid key to unset.");if("object"!=typeof this.reference())throw Error("baobab.Cursor.set: trying to set key to a non-object.");var e={};return e[t]={$unset:!0},this.update(e)},r.prototype.remove=function(){if(this.isRoot())throw Error("baobab.Cursor.remove: cannot remove root node.");return this.update({$unset:!0})},r.prototype.apply=function(t){if("function"!=typeof t)throw Error("baobab.Cursor.apply: argument is not a function.");return this.update({$apply:t})},r.prototype.chain=function(t){if("function"!=typeof t)throw Error("baobab.Cursor.chain: argument is not a function.");return this.update({$chain:t})},r.prototype.push=function(t){if(!(this.reference()instanceof Array))throw Error("baobab.Cursor.push: trying to push to non-array value.");return this.update(arguments.length>1?{$push:s.arrayOf(arguments)}:{$push:t})},r.prototype.unshift=function(t){if(!(this.reference()instanceof Array))throw Error("baobab.Cursor.push: trying to push to non-array value.");return this.update(arguments.length>1?{$unshift:s.arrayOf(arguments)}:{$unshift:t})},r.prototype.merge=function(t){if(!a.Object(t))throw Error("baobab.Cursor.merge: trying to merge a non-object.");if(!a.Object(this.reference()))throw Error("baobab.Cursor.merge: trying to merge into a non-object.");this.update({$merge:t})},r.prototype.update=function(t){return this.tree.update(s.pathObject(this.solvedPath,t)),this},r.prototype.or=function(t){return new o("or",this,t)},r.prototype.and=function(t){return new o("and",this,t)},r.prototype.release=function(){this.tree.off("update",this.updateHandler),this.hash&&delete this.tree._cursors[this.hash],delete this.tree,delete this.path,delete this.solvedPath,this.kill()},r.prototype.toJSON=function(){return this.reference()},a.Cursor=function(t){return t instanceof r},e.exports=r},{"./combination.js":5,"./helpers.js":7,"./mixins.js":9,"./type.js":10,emmett:3}],7:[function(t,e){function r(t){return Array.prototype.slice.call(t)}function n(t,e){var r,n={};for(r in t)n[r]=t[r];for(r in e)n[r]=e[r];return n}function o(t){var e=t.source,r="";return t.global&&(r+="g"),t.multiline&&(r+="m"),t.ignoreCase&&(r+="i"),t.sticky&&(r+="y"),t.unicode&&(r+="u"),new RegExp(e,r)}function i(t,e){if(!e||"object"!=typeof e||e instanceof Error||e instanceof ArrayBuffer)return e;if(b.Array(e)){if(t){var r,n,i=[];for(r=0,n=e.length;n>r;r++)i.push(m(e[r]));return i}return e.slice(0)}if(b.Date(e))return new Date(e.getTime());if(e instanceof RegExp)return o(e);if(b.Object(e)){var s,a={};e.constructor&&e.constructor!==Object&&(a=Object.create(e.constructor.prototype));for(s in e)e.hasOwnProperty(s)&&(a[s]=t?m(e[s]):e[s]);return a}return e}function s(t,e){return function(r){return e(t(r))}}function a(t,e){var r,n;for(r=0,n=t.length;n>r;r++)if(e(t[r]))return t[r]}function u(t,e){var r,n;for(r=0,n=t.length;n>r;r++)if(e(t[r]))return r;return-1}function h(t,e){var r,n=!0;if(!t)return!1;for(r in e)if(b.Object(e[r]))n=n&&h(t[r],e[r]);else if(b.Array(e[r]))n=n&&!!~e[r].indexOf(t[r]);else if(t[r]!==e[r])return!1;return n}function c(t,e){return a(t,function(t){return h(t,e)})}function l(t,e){return u(t,function(t){return h(t,e)})}function f(t,e){e=e||[];var r,n,o=t;for(r=0,n=e.length;n>r;r++){if(!o)return;if("function"==typeof e[r]){if(!b.Array(o))return;o=a(o,e[r])}else if("object"==typeof e[r]){if(!b.Array(o))return;o=c(o,e[r])}else o=o[e[r]]}return o}function p(t,e){var r,n,o,i=[],s=t;for(n=0,o=e.length;o>n;n++){if(!s)return null;if("function"==typeof e[n]){if(!b.Array(s))return;r=u(s,e[n]),i.push(r),s=s[r]}else if("object"==typeof e[n]){if(!b.Array(s))return;r=l(s,e[n]),i.push(r),s=s[r]}else i.push(e[n]),s=s[e[n]]||{}}return i}function d(t,e){var r,n=t.length,o={},i=o;for(n||(o=e),r=0;n>r;r++)i[t[r]]=r+1===n?e:{},i=i[t[r]];return o}function y(t,e){t.super_=e;var r=function(){};r.prototype=e.prototype,t.prototype=new r,t.prototype.constructor=t}var b=t("./type.js"),g=i.bind(null,!1),m=i.bind(null,!0);e.exports={arrayOf:r,deepClone:m,shallowClone:g,shallowMerge:n,compose:s,getIn:f,inherits:y,pathObject:d,solvePath:p}},{"./type.js":10}],8:[function(t,e){function r(t,e){return e in(t||{})}function n(t,e,n){return r(t,n)&&r(e,n)}function o(){var t,e,r,a,u={},h=arguments.length;for(r=h-1;r>=0;r--){if(arguments[r].$unset)delete u.$set,delete u.$apply,delete u.$merge,u.$unset=arguments[r].$unset;else{if(arguments[r].$set){delete u.$apply,delete u.$merge,delete u.$unset,u.$set=arguments[r].$set;continue}if(arguments[r].$merge){delete u.$set,delete u.$apply,delete u.$unset,u.$merge=arguments[r].$merge;continue}if(arguments[r].$apply){delete u.$set,delete u.$merge,delete u.$unset,u.$apply=arguments[r].$apply;continue}if(arguments[r].$chain){delete u.$set,delete u.$merge,delete u.$unset,u.$apply=u.$apply?i.compose(u.$apply,arguments[r].$chain):arguments[r].$chain;continue}}for(a in arguments[r])t=u[a],e=arguments[r][a],t&&s.Object(e)?n(t,e,"$push")?t.$push=s.Array(t.$push)?t.$push.concat(e.$push):[t.$push].concat(e.$push):n(t,e,"$unshift")?t.$unshift=s.Array(e.$unshift)?e.$unshift.concat(t.$unshift):[e.$unshift].concat(t.$unshift):u[a]=o(e,t):u[a]=e}return u}var i=t("./helpers.js"),s=t("./type.js");e.exports=o},{"./helpers.js":7,"./type.js":10}],9:[function(t,e){var r=t("./combination.js"),n=t("./type.js");e.exports={baobab:function(t){return{mixins:[{getInitialState:function(){if(this.tree=t,!this.cursor&&!this.cursors)return{};if(this.cursor&&this.cursors)throw Error("baobab.mixin: you cannot have both `component.cursor` and `component.cursors`. Please make up your mind.");if(this.__type=null,this.__updateHandler=function(){this.setState(this.__getCursorData())}.bind(this),this.cursor){if(!n.MixinCursor(this.cursor))throw Error("baobab.mixin.cursor: invalid data (cursor, string, array or function).");n.Function(this.cursor)&&(this.cursor=this.cursor()),n.Cursor(this.cursor)||(this.cursor=t.select(this.cursor)),this.__getCursorData=function(){return{cursor:this.cursor.get()}}.bind(this),this.__type="single"}else if(this.cursors){if(!n.MixinCursors(this.cursors))throw Error("baobab.mixin.cursor: invalid data (object, array or function).");if(n.Function(this.cursors)&&(this.cursors=this.cursors()),n.Array(this.cursors))this.cursors=this.cursors.map(function(e){return n.Cursor(e)?e:t.select(e)}),this.__getCursorData=function(){return{cursors:this.cursors.map(function(t){return t.get()})}}.bind(this),this.__type="array";else{for(var e in this.cursors)n.Cursor(this.cursors[e])||(this.cursors[e]=t.select(this.cursors[e]));this.__getCursorData=function(){var t={};for(e in this.cursors)t[e]=this.cursors[e].get();return{cursors:t}}.bind(this),this.__type="object"}}return this.__getCursorData()},componentDidMount:function(){"single"===this.__type?(this.__combination=new r("or",[this.cursor]),this.__combination.on("update",this.__updateHandler)):"array"===this.__type?(this.__combination=new r("or",this.cursors),this.__combination.on("update",this.__updateHandler)):"object"===this.__type&&(this.__combination=new r("or",Object.keys(this.cursors).map(function(t){return this.cursors[t]},this)),this.__combination.on("update",this.__updateHandler))},componentWillUnmount:function(){this.__combination&&this.__combination.release()}}].concat(t.options.mixins)}},cursor:function(t){return{mixins:[{getInitialState:function(){return this.cursor=t,this.__updateHandler=function(){this.setState({cursor:this.cursor.get()})}.bind(this),{cursor:this.cursor.get()}},componentDidMount:function(){this.cursor.on("update",this.__updateHandler)},componentWillUnmount:function(){this.cursor.off("update",this.__updateHandler)}}].concat(t.tree.options.mixins)}}}},{"./combination.js":5,"./type.js":10}],10:[function(t,e){var r=function(t){return Array.isArray(t)?"array":"object"==typeof t&&null!==t?"object":"string"==typeof t?"string":"number"==typeof t?"number":"boolean"==typeof t?"boolean":"function"==typeof t?"function":null===t?"null":void 0===t?"undefined":t instanceof Date?"date":"invalid"};r.Array=function(t){return Array.isArray(t)},r.Object=function(t){return!Array.isArray(t)&&"object"==typeof t&&null!==t},r.String=function(t){return"string"==typeof t},r.Number=function(t){return"number"==typeof t},r.Boolean=function(t){return"boolean"==typeof t},r.Function=function(t){return"function"==typeof t},r.Primitive=function(t){return"string"==typeof t||"number"==typeof t||"boolean"==typeof t},r.Date=function(t){return t instanceof Date},r.Step=function(t){var e=r(t),n=["null","undefined","invalid","date"];return-1===n.indexOf(e)},r.Path=function(t){var e=["object","string","number","function","undefined"];if(!r.Array(t))return e.indexOf(r(t))>=0;for(var n=0;n=0||r.Cursor(t)},r.MixinCursors=function(t){var e=["array","object","function"];return e.indexOf(r(t))>=0},r.ComplexPath=function(t){for(var e=["object","function"],n=0;n=0)return!0;return!1},e.exports=r},{}],11:[function(t,e){function r(t,e){var r=new Error("baobab.update: "+e+" at path /"+t.toString());return r.path=t,r}function n(t,e,n){n=n||{shiftReferences:!1};var a={};return function u(t,e,h,c){h=h||[];var l,f,p,d,y=h.join("λ");for(p in e)if(s[p])switch(d=e[p],a[y]=!0,p){case"$push":if(!i.Array(t))throw r(h,"using command $push to a non array");i.Array(d)?t.push.apply(t,d):t.push(d);break;case"$unshift":if(!i.Array(t))throw r(h,"using command $unshift to a non array");i.Array(d)?t.unshift.apply(t,d):t.unshift(d)}else if(f=y?y+"λ"+p:p,"$unset"in(e[p]||{}))a[f]=!0,i.Array(t)?n.shiftReferences?c[h[h.length-1]]=t.slice(0,+p).concat(t.slice(+p+1)):t.splice(p,1):delete t[p];else if("$set"in(e[p]||{}))d=e[p].$set,a[f]=!0,t[p]=d;else if("$apply"in(e[p]||{})||"$chain"in(e[p]||{})){if(l=e[p].$apply||e[p].$chain,"function"!=typeof l)throw r(h.concat(p),"using command $apply with a non function");a[f]=!0,t[p]=l.call(null,t[p])}else if("$merge"in(e[p]||{})){if(d=e[p].$merge,!i.Object(t[p]))throw r(h.concat(p),"using command $merge on a non-object");a[f]=!0,t[p]=o.shallowMerge(t[p],d)}else if(n.shiftReferences&&("$push"in(e[p]||{})||"$unshift"in(e[p]||{}))){if("$push"in(e[p]||{})){if(d=e[p].$push,!i.Array(t[p]))throw r(h.concat(p),"using command $push to a non array");t[p]=t[p].concat(d)}if("$unshift"in(e[p]||{})){if(d=e[p].$unshift,!i.Array(t[p]))throw r(h.concat(p),"using command $unshift to a non array");t[p]=(d instanceof Array?d:[d]).concat(t[p])}a[f]=!0}else"undefined"==typeof t[p]&&(t[p]={}),n.shiftReferences&&(t[p]=o.shallowClone(t[p])),u(t[p],e[p],h.concat(p),t)}(t,e),Object.keys(a).map(function(t){return t.split("λ")})}var o=t("./helpers.js"),i=t("./type.js"),s={};["$set","$push","$unshift","$apply","$merge"].forEach(function(t){s[t]=!0}),e.exports=n},{"./helpers.js":7,"./type.js":10}]},{},[2])(2)}); \ No newline at end of file diff --git a/src/baobab.js b/src/baobab.js index effa619..8e25a02 100644 --- a/src/baobab.js +++ b/src/baobab.js @@ -213,7 +213,6 @@ Baobab.prototype.release = function() { delete this.data; delete this._transaction; - delete this._history; // Releasing cursors for (var k in this._cursors) From f93d86501cf65cf706f91761268d2abc2a208a85 Mon Sep 17 00:00:00 2001 From: Yomguithereal Date: Fri, 27 Mar 2015 19:39:53 +0100 Subject: [PATCH 04/73] Removing cloning options --- build/baobab.min.js | 2 +- src/baobab.js | 17 +++--------- src/cursor.js | 44 +++++++++---------------------- test/suites/baobab.js | 60 +++++++++++++++---------------------------- 4 files changed, 37 insertions(+), 86 deletions(-) diff --git a/build/baobab.min.js b/build/baobab.min.js index 5d47779..8c4f50a 100644 --- a/build/baobab.min.js +++ b/build/baobab.min.js @@ -1,2 +1,2 @@ /* baobab.js - Version: 0.4.3 - Author: Yomguithereal (Guillaume Plique) */ -!function(t){if("object"==typeof exports&&"undefined"!=typeof module)module.exports=t();else if("function"==typeof define&&define.amd)define([],t);else{var e;e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:this,e.Baobab=t()}}(function(){var t;return function e(t,r,n){function o(s,a){if(!r[s]){if(!t[s]){var u="function"==typeof require&&require;if(!a&&u)return u(s,!0);if(i)return i(s,!0);var h=new Error("Cannot find module '"+s+"'");throw h.code="MODULE_NOT_FOUND",h}var c=r[s]={exports:{}};t[s][0].call(c.exports,function(e){var r=t[s][1][e];return o(r?r:e)},c,c.exports,e,t,r,n)}return r[s].exports}for(var i="function"==typeof require&&require,s=0;se;e++)n.push(t[e].handler);return n}var o={once:"boolean",scope:"object"},i=function(){this._enabled=!0,this._children=[],this._handlers={},this._handlersAll=[]};i.prototype.on=function(t,e,r){var n,s,a,u,h,c;if("function"==typeof e){for(h="string"==typeof t?[t]:t,n=0,s=h.length;n!==s;n+=1)if(u=h[n]){this._handlers[u]||(this._handlers[u]=[]),c={handler:e};for(a in r||{}){if(!o[a])throw new Error('The option "'+a+'" is not recognized by Emmett.');c[a]=r[a]}this._handlers[u].push(c)}}else if(t&&"object"==typeof t&&!Array.isArray(t))for(u in t)i.prototype.on.call(this,u,t[u],e);else{if("function"!=typeof t)throw new Error("Wrong arguments.");c={handler:t};for(a in r||{}){if(!o[a])throw new Error('The option "'+a+'" is not recognized by Emmett.');c[a]=r[a]}this._handlersAll.push(c)}return this},i.prototype.once=function(t,e,r){if("function"==typeof e)r=r||{},r.once=!0,this.on(t,e,r);else{if((!t||"object"!=typeof t||Array.isArray(t))&&"function"!=typeof t)throw new Error("Wrong arguments.");e=e||{},e.once=!0,this.on(t,e)}return this},i.prototype.off=function(t,e){var r,n,o,i,s,a,u,h="string"==typeof t?[t]:t;if(1===arguments.length&&"function"==typeof h){e=arguments[0];for(s in this._handlers){for(a=[],r=0,n=this._handlers[s].length;r!==n;r+=1)this._handlers[s][r].handler!==e&&a.push(this._handlers[s][r]);this._handlers[s]=a}for(a=[],r=0,n=this._handlersAll.length;r!==n;r+=1)this._handlersAll[r].handler!==e&&a.push(this._handlersAll[r]);this._handlersAll=a}else if(2===arguments.length)for(r=0,n=h.length;r!==n;r+=1){if(u=h[r],this._handlers[u]){for(a=[],o=0,i=this._handlers[u].length;o!==i;o+=1)this._handlers[u][o].handler!==e&&a.push(this._handlers[u][o]);this._handlers[u]=a}this._handlers[u]&&0===this._handlers[u].length&&delete this._handlers[u]}return this},i.prototype.unbindAll=function(){var t;this._handlersAll=[];for(t in this._handlers)delete this._handlers[t];return this},i.prototype.emit=function(t,e){var r,n,o,i,s,a,u,h,c,l,f="string"==typeof t?[t]:t;if(!this._enabled)return this;for(e=void 0===e?{}:e,r=0,n=f.length;r!==n;r+=1)if(l=f[r],c=(this._handlers[l]||[]).concat(this._handlersAll),c.length){for(u={type:l,data:e||{},target:this},a=[],o=0,i=c.length;o!==i;o+=1)(this._handlers[l]&&this._handlers[l].indexOf(c[o])>=0||this._handlersAll.indexOf(c[o])>=0)&&(c[o].handler.call("scope"in c[o]?c[o].scope:this,u),c[o].once&&a.push(c[o]));for(s=0;sr;r++)if(t._children[r]===e){t._children.splice(r,1);break}}),this._children.push(e),e},i.prototype.listeners=function(t){var r,n,o,i=[];if(t)for(i=e(this._handlers[t]),n=0,o=this._children.length;o>n;n++)i=i.concat(this._children[n].listeners(t));else{i=e(this._handlersAll);for(r in this._handlers)i=i.concat(e(this._handlers[r]));for(n=0,o=this._children.length;o>n;n++)i=i.concat(this._children[n].listeners())}return i},i.prototype.kill=function(){if(this.emit("emmett:kill"),this.unbindAll(),this._handlers=null,this._handlersAll=null,this._enabled=!1,this._children)for(var t=0,e=this._children.length;e>t;t++)this._children[t].kill();this._children=null},i.prototype.disable=function(){return this._enabled=!1,this},i.prototype.enable=function(){return this._enabled=!0,this},i.version="2.1.2","undefined"!=typeof n?("undefined"!=typeof r&&r.exports&&(n=r.exports=i),n.Emitter=i):"function"==typeof t&&t.amd?t("emmett",[],function(){return i}):this.Emitter=i}).call(this)},{}],4:[function(t,e){function r(t){return t+"$"+(new Date).getTime()+(""+Math.random()).replace("0.","")}function n(t,e){if(arguments.length<1&&(t={}),!(this instanceof n))return new n(t,e);if(!l.Object(t)&&!l.Array(t))throw Error("Baobab: invalid data.");i.call(this),this.options=s.shallowMerge(c,e),this._cloner=this.options.cloningFunction||s.deepClone,this._transaction={},this._future=void 0,this._cursors={},this.data=this._cloner(t),this.mixin=h.baobab(this)}var o=t("./cursor.js"),i=t("emmett"),s=t("./helpers.js"),a=t("./update.js"),u=t("./merge.js"),h=t("./mixins.js"),c=t("../defaults.js"),l=t("./type.js");s.inherits(n,i),n.prototype.commit=function(){this.options.shiftReferences&&(this.data=s.shallowClone(this.data));var t=a(this.data,this._transaction,this.options);return this._transaction={},this._future&&(this._future=clearTimeout(this._future)),this.emit("update",{log:t}),this},n.prototype.select=function(t){if(!t)throw Error("Baobab.select: invalid path.");if(arguments.length>1&&(t=s.arrayOf(arguments)),!l.Path(t))throw Error("Baobab.select: invalid path.");t=l.Array(t)?t:[t];var e,n=l.ComplexPath(t);if(n&&(e=s.solvePath(this.data,t)),this.options.cursorSingletons){var i=t.map(function(t){return l.Function(t)?r("fn"):l.Object(t)?r("ob"):t}).join("λ");if(this._cursors[i])return this._cursors[i];var a=new o(this,t,e,i);return this._cursors[i]=a,a}return new o(this,t)},n.prototype.root=function(){return this.select([])},n.prototype.reference=function(t){if(arguments.length>1&&(t=s.arrayOf(arguments)),!l.Path(t))throw Error("Baobab.get: invalid path.");return s.getIn(this.data,l.String(t)||l.Number(t)?[t]:t)},n.prototype.get=function(){var t=this.reference.apply(this,arguments);return this.options.clone?this._cloner(t):t},n.prototype.clone=function(){return this._cloner(this.reference.apply(this,arguments))},n.prototype.set=function(t,e){if(arguments.length<2)throw Error("Baobab.set: expects a key and a value.");var r={};if(l.Array(t)){var n=s.solvePath(this.data,t);if(!n)throw Error("Baobab.set: could not solve dynamic path.");r=s.pathObject(n,{$set:e})}else r[t]={$set:e};return this.update(r)},n.prototype.unset=function(t){if(!t&&0!==t)throw Error("Baobab.unset: expects a valid key to unset.");var e={};return e[t]={$unset:!0},this.update(e)},n.prototype.update=function(t){var e=this;if(!l.Object(t))throw Error("Baobab.update: wrong specification.");return this._transaction=u(t,this._transaction),this.options.autoCommit?this.options.asynchronous?(this._future||(this._future=setTimeout(e.commit.bind(e,null),0)),this):this.commit():this},n.prototype.release=function(){delete this.data,delete this._transaction;for(var t in this._cursors)this._cursors[t].release();delete this._cursors,this.kill()},n.prototype.toJSON=function(){return this.reference()},e.exports=n},{"../defaults.js":1,"./cursor.js":6,"./helpers.js":7,"./merge.js":8,"./mixins.js":9,"./type.js":10,"./update.js":11,emmett:3}],5:[function(t,e){function r(t,e){e.on("update",t.cursorListener),t.tree.off("update",t.treeListener),t.tree.on("update",t.treeListener)}function n(t){var e=this;if(arguments.length<2)throw Error("baobab.Combination: not enough arguments.");var n=arguments[1],o=s.arrayOf(arguments).slice(2);if(n instanceof Array&&(o=n.slice(1),n=n[0]),!a.Cursor(n))throw Error("baobab.Combination: argument should be a cursor.");if("or"!==t&&"and"!==t)throw Error("baobab.Combination: invalid operator.");i.call(this),this.cursors=[n],this.operators=[],this.tree=n.tree,this.updates=new Array(this.cursors.length),this.cursorListener=function(){e.updates[e.cursors.indexOf(this)]=!0},this.treeListener=function(){var t,r,n=e.updates[0];for(t=1,r=e.cursors.length;r>t;t++)n="or"===e.operators[t-1]?n||e.updates[t]:n&&e.updates[t];n&&e.emit("update"),e.updates=new Array(e.cursors.length)},this.bound=!1;var u=this.on,h=this.once,c=function(){e.bound||(e.bound=!0,e.cursors.forEach(function(t){r(e,t)}))};this.on=function(){return c(),u.apply(this,arguments)},this.once=function(){return c(),h.apply(this,arguments)},o.forEach(function(e){this[t](e)},this)}function o(t){n.prototype[t]=function(e){if(!a.Cursor(e))throw this.release(),Error("baobab.Combination."+t+": argument should be a cursor.");if(~this.cursors.indexOf(e))throw this.release(),Error("baobab.Combination."+t+": cursor already in combination.");return this.cursors.push(e),this.operators.push(t),this.updates.length++,this.bound&&r(this,e),this}}var i=t("emmett"),s=t("./helpers.js"),a=t("./type.js");s.inherits(n,i),o("or"),o("and"),n.prototype.release=function(){this.cursors.forEach(function(t){t.off("update",this.cursorListener)},this),this.tree.off("update",this.treeListener),this.cursors=null,this.operators=null,this.tree=null,this.updates=null,this.kill()},e.exports=n},{"./helpers.js":7,"./type.js":10,emmett:3}],6:[function(t,e){function r(t,e,r,o){var a=this;n.call(this),e=e||[],this.tree=t,this.path=e,this.hash=o,this.relevant=void 0!==this.reference(),this.complexPath=!!r,this.solvedPath=this.complexPath?r:this.path,this.updateHandler=function(t){var e,r,n,o,i,u,h=t.data.log,c=!1;if(a.complexPath&&(a.solvedPath=s.solvePath(a.tree.data,a.path)),!a.path.length)return a.emit("update");t:for(i=0,n=h.length;n>i;i++)for(e=h[i],u=0,o=e.length;o>u&&(r=e[u],r===""+a.solvedPath[u]);u++)if(u+1===o||u+1===a.solvedPath.length){c=!0;break t}var l=void 0!==a.reference();a.relevant?l&&c?a.emit("update"):l||(a.emit("irrelevant"),a.relevant=!1):l&&c&&(a.emit("relevant"),a.emit("update"),a.relevant=!0)},this.mixin=i.cursor(this);var u=!1,h=this.on,c=this.once,l=function(){u||(u=!0,a.tree.on("update",a.updateHandler))};this.on=function(){return l(),h.apply(this,arguments)},this.once=function(){return l(),c.apply(this,arguments)}}var n=t("emmett"),o=t("./combination.js"),i=t("./mixins.js"),s=t("./helpers.js"),a=t("./type.js");s.inherits(r,n),r.prototype.isRoot=function(){return!this.path.length},r.prototype.isLeaf=function(){return a.Primitive(this.reference())},r.prototype.isBranch=function(){return!this.isLeaf()&&!this.isRoot()},r.prototype.root=function(){return this.tree.root()},r.prototype.select=function(t){if(arguments.length>1&&(t=s.arrayOf(arguments)),!a.Path(t))throw Error("baobab.Cursor.select: invalid path.");return this.tree.select(this.path.concat(t))},r.prototype.up=function(){return this.solvedPath&&this.solvedPath.length?this.tree.select(this.path.slice(0,-1)):null},r.prototype.left=function(){var t=+this.solvedPath[this.solvedPath.length-1];if(isNaN(t))throw Error("baobab.Cursor.left: cannot go left on a non-list type.");return t?this.tree.select(this.solvedPath.slice(0,-1).concat(t-1)):null},r.prototype.leftmost=function(){var t=+this.solvedPath[this.solvedPath.length-1];if(isNaN(t))throw Error("baobab.Cursor.leftmost: cannot go left on a non-list type.");return this.tree.select(this.solvedPath.slice(0,-1).concat(0))},r.prototype.right=function(){var t=+this.solvedPath[this.solvedPath.length-1];if(isNaN(t))throw Error("baobab.Cursor.right: cannot go right on a non-list type.");return t+1===this.up().reference().length?null:this.tree.select(this.solvedPath.slice(0,-1).concat(t+1))},r.prototype.rightmost=function(){var t=+this.solvedPath[this.solvedPath.length-1];if(isNaN(t))throw Error("baobab.Cursor.right: cannot go right on a non-list type.");var e=this.up().reference();return this.tree.select(this.solvedPath.slice(0,-1).concat(e.length-1))},r.prototype.down=function(){+this.solvedPath[this.solvedPath.length-1];return this.reference()instanceof Array?this.tree.select(this.solvedPath.concat(0)):null},r.prototype.get=function(t){return arguments.length>1&&(t=s.arrayOf(arguments)),this.tree.get(a.Step(t)?this.solvedPath.concat(t):this.solvedPath)},r.prototype.reference=function(t){return arguments.length>1&&(t=s.arrayOf(arguments)),this.tree.reference(a.Step(t)?this.solvedPath.concat(t):this.solvedPath)},r.prototype.clone=function(t){return arguments.length>1&&(t=s.arrayOf(arguments)),this.tree.clone(a.Step(t)?this.solvedPath.concat(t):this.solvedPath)},r.prototype.set=function(t,e){if(arguments.length<2)throw Error("baobab.Cursor.set: expecting at least key/value.");var r=this.reference();if("object"!=typeof r)throw Error("baobab.Cursor.set: trying to set key to a non-object.");var n={};if(a.Array(t)){var o=s.solvePath(r,t);if(!o)throw Error("baobab.Cursor.set: could not solve dynamic path.");n=s.pathObject(o,{$set:e})}else n[t]={$set:e};return this.update(n)},r.prototype.edit=function(t){return this.update({$set:t})},r.prototype.unset=function(t){if(!t&&0!==t)throw Error("baobab.Cursor.unset: expects a valid key to unset.");if("object"!=typeof this.reference())throw Error("baobab.Cursor.set: trying to set key to a non-object.");var e={};return e[t]={$unset:!0},this.update(e)},r.prototype.remove=function(){if(this.isRoot())throw Error("baobab.Cursor.remove: cannot remove root node.");return this.update({$unset:!0})},r.prototype.apply=function(t){if("function"!=typeof t)throw Error("baobab.Cursor.apply: argument is not a function.");return this.update({$apply:t})},r.prototype.chain=function(t){if("function"!=typeof t)throw Error("baobab.Cursor.chain: argument is not a function.");return this.update({$chain:t})},r.prototype.push=function(t){if(!(this.reference()instanceof Array))throw Error("baobab.Cursor.push: trying to push to non-array value.");return this.update(arguments.length>1?{$push:s.arrayOf(arguments)}:{$push:t})},r.prototype.unshift=function(t){if(!(this.reference()instanceof Array))throw Error("baobab.Cursor.push: trying to push to non-array value.");return this.update(arguments.length>1?{$unshift:s.arrayOf(arguments)}:{$unshift:t})},r.prototype.merge=function(t){if(!a.Object(t))throw Error("baobab.Cursor.merge: trying to merge a non-object.");if(!a.Object(this.reference()))throw Error("baobab.Cursor.merge: trying to merge into a non-object.");this.update({$merge:t})},r.prototype.update=function(t){return this.tree.update(s.pathObject(this.solvedPath,t)),this},r.prototype.or=function(t){return new o("or",this,t)},r.prototype.and=function(t){return new o("and",this,t)},r.prototype.release=function(){this.tree.off("update",this.updateHandler),this.hash&&delete this.tree._cursors[this.hash],delete this.tree,delete this.path,delete this.solvedPath,this.kill()},r.prototype.toJSON=function(){return this.reference()},a.Cursor=function(t){return t instanceof r},e.exports=r},{"./combination.js":5,"./helpers.js":7,"./mixins.js":9,"./type.js":10,emmett:3}],7:[function(t,e){function r(t){return Array.prototype.slice.call(t)}function n(t,e){var r,n={};for(r in t)n[r]=t[r];for(r in e)n[r]=e[r];return n}function o(t){var e=t.source,r="";return t.global&&(r+="g"),t.multiline&&(r+="m"),t.ignoreCase&&(r+="i"),t.sticky&&(r+="y"),t.unicode&&(r+="u"),new RegExp(e,r)}function i(t,e){if(!e||"object"!=typeof e||e instanceof Error||e instanceof ArrayBuffer)return e;if(b.Array(e)){if(t){var r,n,i=[];for(r=0,n=e.length;n>r;r++)i.push(m(e[r]));return i}return e.slice(0)}if(b.Date(e))return new Date(e.getTime());if(e instanceof RegExp)return o(e);if(b.Object(e)){var s,a={};e.constructor&&e.constructor!==Object&&(a=Object.create(e.constructor.prototype));for(s in e)e.hasOwnProperty(s)&&(a[s]=t?m(e[s]):e[s]);return a}return e}function s(t,e){return function(r){return e(t(r))}}function a(t,e){var r,n;for(r=0,n=t.length;n>r;r++)if(e(t[r]))return t[r]}function u(t,e){var r,n;for(r=0,n=t.length;n>r;r++)if(e(t[r]))return r;return-1}function h(t,e){var r,n=!0;if(!t)return!1;for(r in e)if(b.Object(e[r]))n=n&&h(t[r],e[r]);else if(b.Array(e[r]))n=n&&!!~e[r].indexOf(t[r]);else if(t[r]!==e[r])return!1;return n}function c(t,e){return a(t,function(t){return h(t,e)})}function l(t,e){return u(t,function(t){return h(t,e)})}function f(t,e){e=e||[];var r,n,o=t;for(r=0,n=e.length;n>r;r++){if(!o)return;if("function"==typeof e[r]){if(!b.Array(o))return;o=a(o,e[r])}else if("object"==typeof e[r]){if(!b.Array(o))return;o=c(o,e[r])}else o=o[e[r]]}return o}function p(t,e){var r,n,o,i=[],s=t;for(n=0,o=e.length;o>n;n++){if(!s)return null;if("function"==typeof e[n]){if(!b.Array(s))return;r=u(s,e[n]),i.push(r),s=s[r]}else if("object"==typeof e[n]){if(!b.Array(s))return;r=l(s,e[n]),i.push(r),s=s[r]}else i.push(e[n]),s=s[e[n]]||{}}return i}function d(t,e){var r,n=t.length,o={},i=o;for(n||(o=e),r=0;n>r;r++)i[t[r]]=r+1===n?e:{},i=i[t[r]];return o}function y(t,e){t.super_=e;var r=function(){};r.prototype=e.prototype,t.prototype=new r,t.prototype.constructor=t}var b=t("./type.js"),g=i.bind(null,!1),m=i.bind(null,!0);e.exports={arrayOf:r,deepClone:m,shallowClone:g,shallowMerge:n,compose:s,getIn:f,inherits:y,pathObject:d,solvePath:p}},{"./type.js":10}],8:[function(t,e){function r(t,e){return e in(t||{})}function n(t,e,n){return r(t,n)&&r(e,n)}function o(){var t,e,r,a,u={},h=arguments.length;for(r=h-1;r>=0;r--){if(arguments[r].$unset)delete u.$set,delete u.$apply,delete u.$merge,u.$unset=arguments[r].$unset;else{if(arguments[r].$set){delete u.$apply,delete u.$merge,delete u.$unset,u.$set=arguments[r].$set;continue}if(arguments[r].$merge){delete u.$set,delete u.$apply,delete u.$unset,u.$merge=arguments[r].$merge;continue}if(arguments[r].$apply){delete u.$set,delete u.$merge,delete u.$unset,u.$apply=arguments[r].$apply;continue}if(arguments[r].$chain){delete u.$set,delete u.$merge,delete u.$unset,u.$apply=u.$apply?i.compose(u.$apply,arguments[r].$chain):arguments[r].$chain;continue}}for(a in arguments[r])t=u[a],e=arguments[r][a],t&&s.Object(e)?n(t,e,"$push")?t.$push=s.Array(t.$push)?t.$push.concat(e.$push):[t.$push].concat(e.$push):n(t,e,"$unshift")?t.$unshift=s.Array(e.$unshift)?e.$unshift.concat(t.$unshift):[e.$unshift].concat(t.$unshift):u[a]=o(e,t):u[a]=e}return u}var i=t("./helpers.js"),s=t("./type.js");e.exports=o},{"./helpers.js":7,"./type.js":10}],9:[function(t,e){var r=t("./combination.js"),n=t("./type.js");e.exports={baobab:function(t){return{mixins:[{getInitialState:function(){if(this.tree=t,!this.cursor&&!this.cursors)return{};if(this.cursor&&this.cursors)throw Error("baobab.mixin: you cannot have both `component.cursor` and `component.cursors`. Please make up your mind.");if(this.__type=null,this.__updateHandler=function(){this.setState(this.__getCursorData())}.bind(this),this.cursor){if(!n.MixinCursor(this.cursor))throw Error("baobab.mixin.cursor: invalid data (cursor, string, array or function).");n.Function(this.cursor)&&(this.cursor=this.cursor()),n.Cursor(this.cursor)||(this.cursor=t.select(this.cursor)),this.__getCursorData=function(){return{cursor:this.cursor.get()}}.bind(this),this.__type="single"}else if(this.cursors){if(!n.MixinCursors(this.cursors))throw Error("baobab.mixin.cursor: invalid data (object, array or function).");if(n.Function(this.cursors)&&(this.cursors=this.cursors()),n.Array(this.cursors))this.cursors=this.cursors.map(function(e){return n.Cursor(e)?e:t.select(e)}),this.__getCursorData=function(){return{cursors:this.cursors.map(function(t){return t.get()})}}.bind(this),this.__type="array";else{for(var e in this.cursors)n.Cursor(this.cursors[e])||(this.cursors[e]=t.select(this.cursors[e]));this.__getCursorData=function(){var t={};for(e in this.cursors)t[e]=this.cursors[e].get();return{cursors:t}}.bind(this),this.__type="object"}}return this.__getCursorData()},componentDidMount:function(){"single"===this.__type?(this.__combination=new r("or",[this.cursor]),this.__combination.on("update",this.__updateHandler)):"array"===this.__type?(this.__combination=new r("or",this.cursors),this.__combination.on("update",this.__updateHandler)):"object"===this.__type&&(this.__combination=new r("or",Object.keys(this.cursors).map(function(t){return this.cursors[t]},this)),this.__combination.on("update",this.__updateHandler))},componentWillUnmount:function(){this.__combination&&this.__combination.release()}}].concat(t.options.mixins)}},cursor:function(t){return{mixins:[{getInitialState:function(){return this.cursor=t,this.__updateHandler=function(){this.setState({cursor:this.cursor.get()})}.bind(this),{cursor:this.cursor.get()}},componentDidMount:function(){this.cursor.on("update",this.__updateHandler)},componentWillUnmount:function(){this.cursor.off("update",this.__updateHandler)}}].concat(t.tree.options.mixins)}}}},{"./combination.js":5,"./type.js":10}],10:[function(t,e){var r=function(t){return Array.isArray(t)?"array":"object"==typeof t&&null!==t?"object":"string"==typeof t?"string":"number"==typeof t?"number":"boolean"==typeof t?"boolean":"function"==typeof t?"function":null===t?"null":void 0===t?"undefined":t instanceof Date?"date":"invalid"};r.Array=function(t){return Array.isArray(t)},r.Object=function(t){return!Array.isArray(t)&&"object"==typeof t&&null!==t},r.String=function(t){return"string"==typeof t},r.Number=function(t){return"number"==typeof t},r.Boolean=function(t){return"boolean"==typeof t},r.Function=function(t){return"function"==typeof t},r.Primitive=function(t){return"string"==typeof t||"number"==typeof t||"boolean"==typeof t},r.Date=function(t){return t instanceof Date},r.Step=function(t){var e=r(t),n=["null","undefined","invalid","date"];return-1===n.indexOf(e)},r.Path=function(t){var e=["object","string","number","function","undefined"];if(!r.Array(t))return e.indexOf(r(t))>=0;for(var n=0;n=0||r.Cursor(t)},r.MixinCursors=function(t){var e=["array","object","function"];return e.indexOf(r(t))>=0},r.ComplexPath=function(t){for(var e=["object","function"],n=0;n=0)return!0;return!1},e.exports=r},{}],11:[function(t,e){function r(t,e){var r=new Error("baobab.update: "+e+" at path /"+t.toString());return r.path=t,r}function n(t,e,n){n=n||{shiftReferences:!1};var a={};return function u(t,e,h,c){h=h||[];var l,f,p,d,y=h.join("λ");for(p in e)if(s[p])switch(d=e[p],a[y]=!0,p){case"$push":if(!i.Array(t))throw r(h,"using command $push to a non array");i.Array(d)?t.push.apply(t,d):t.push(d);break;case"$unshift":if(!i.Array(t))throw r(h,"using command $unshift to a non array");i.Array(d)?t.unshift.apply(t,d):t.unshift(d)}else if(f=y?y+"λ"+p:p,"$unset"in(e[p]||{}))a[f]=!0,i.Array(t)?n.shiftReferences?c[h[h.length-1]]=t.slice(0,+p).concat(t.slice(+p+1)):t.splice(p,1):delete t[p];else if("$set"in(e[p]||{}))d=e[p].$set,a[f]=!0,t[p]=d;else if("$apply"in(e[p]||{})||"$chain"in(e[p]||{})){if(l=e[p].$apply||e[p].$chain,"function"!=typeof l)throw r(h.concat(p),"using command $apply with a non function");a[f]=!0,t[p]=l.call(null,t[p])}else if("$merge"in(e[p]||{})){if(d=e[p].$merge,!i.Object(t[p]))throw r(h.concat(p),"using command $merge on a non-object");a[f]=!0,t[p]=o.shallowMerge(t[p],d)}else if(n.shiftReferences&&("$push"in(e[p]||{})||"$unshift"in(e[p]||{}))){if("$push"in(e[p]||{})){if(d=e[p].$push,!i.Array(t[p]))throw r(h.concat(p),"using command $push to a non array");t[p]=t[p].concat(d)}if("$unshift"in(e[p]||{})){if(d=e[p].$unshift,!i.Array(t[p]))throw r(h.concat(p),"using command $unshift to a non array");t[p]=(d instanceof Array?d:[d]).concat(t[p])}a[f]=!0}else"undefined"==typeof t[p]&&(t[p]={}),n.shiftReferences&&(t[p]=o.shallowClone(t[p])),u(t[p],e[p],h.concat(p),t)}(t,e),Object.keys(a).map(function(t){return t.split("λ")})}var o=t("./helpers.js"),i=t("./type.js"),s={};["$set","$push","$unshift","$apply","$merge"].forEach(function(t){s[t]=!0}),e.exports=n},{"./helpers.js":7,"./type.js":10}]},{},[2])(2)}); \ No newline at end of file +!function(t){if("object"==typeof exports&&"undefined"!=typeof module)module.exports=t();else if("function"==typeof define&&define.amd)define([],t);else{var e;e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:this,e.Baobab=t()}}(function(){var t;return function e(t,r,n){function o(s,a){if(!r[s]){if(!t[s]){var u="function"==typeof require&&require;if(!a&&u)return u(s,!0);if(i)return i(s,!0);var h=new Error("Cannot find module '"+s+"'");throw h.code="MODULE_NOT_FOUND",h}var c=r[s]={exports:{}};t[s][0].call(c.exports,function(e){var r=t[s][1][e];return o(r?r:e)},c,c.exports,e,t,r,n)}return r[s].exports}for(var i="function"==typeof require&&require,s=0;se;e++)n.push(t[e].handler);return n}var o={once:"boolean",scope:"object"},i=function(){this._enabled=!0,this._children=[],this._handlers={},this._handlersAll=[]};i.prototype.on=function(t,e,r){var n,s,a,u,h,c;if("function"==typeof e){for(h="string"==typeof t?[t]:t,n=0,s=h.length;n!==s;n+=1)if(u=h[n]){this._handlers[u]||(this._handlers[u]=[]),c={handler:e};for(a in r||{}){if(!o[a])throw new Error('The option "'+a+'" is not recognized by Emmett.');c[a]=r[a]}this._handlers[u].push(c)}}else if(t&&"object"==typeof t&&!Array.isArray(t))for(u in t)i.prototype.on.call(this,u,t[u],e);else{if("function"!=typeof t)throw new Error("Wrong arguments.");c={handler:t};for(a in r||{}){if(!o[a])throw new Error('The option "'+a+'" is not recognized by Emmett.');c[a]=r[a]}this._handlersAll.push(c)}return this},i.prototype.once=function(t,e,r){if("function"==typeof e)r=r||{},r.once=!0,this.on(t,e,r);else{if((!t||"object"!=typeof t||Array.isArray(t))&&"function"!=typeof t)throw new Error("Wrong arguments.");e=e||{},e.once=!0,this.on(t,e)}return this},i.prototype.off=function(t,e){var r,n,o,i,s,a,u,h="string"==typeof t?[t]:t;if(1===arguments.length&&"function"==typeof h){e=arguments[0];for(s in this._handlers){for(a=[],r=0,n=this._handlers[s].length;r!==n;r+=1)this._handlers[s][r].handler!==e&&a.push(this._handlers[s][r]);this._handlers[s]=a}for(a=[],r=0,n=this._handlersAll.length;r!==n;r+=1)this._handlersAll[r].handler!==e&&a.push(this._handlersAll[r]);this._handlersAll=a}else if(2===arguments.length)for(r=0,n=h.length;r!==n;r+=1){if(u=h[r],this._handlers[u]){for(a=[],o=0,i=this._handlers[u].length;o!==i;o+=1)this._handlers[u][o].handler!==e&&a.push(this._handlers[u][o]);this._handlers[u]=a}this._handlers[u]&&0===this._handlers[u].length&&delete this._handlers[u]}return this},i.prototype.unbindAll=function(){var t;this._handlersAll=[];for(t in this._handlers)delete this._handlers[t];return this},i.prototype.emit=function(t,e){var r,n,o,i,s,a,u,h,c,l,f="string"==typeof t?[t]:t;if(!this._enabled)return this;for(e=void 0===e?{}:e,r=0,n=f.length;r!==n;r+=1)if(l=f[r],c=(this._handlers[l]||[]).concat(this._handlersAll),c.length){for(u={type:l,data:e||{},target:this},a=[],o=0,i=c.length;o!==i;o+=1)(this._handlers[l]&&this._handlers[l].indexOf(c[o])>=0||this._handlersAll.indexOf(c[o])>=0)&&(c[o].handler.call("scope"in c[o]?c[o].scope:this,u),c[o].once&&a.push(c[o]));for(s=0;sr;r++)if(t._children[r]===e){t._children.splice(r,1);break}}),this._children.push(e),e},i.prototype.listeners=function(t){var r,n,o,i=[];if(t)for(i=e(this._handlers[t]),n=0,o=this._children.length;o>n;n++)i=i.concat(this._children[n].listeners(t));else{i=e(this._handlersAll);for(r in this._handlers)i=i.concat(e(this._handlers[r]));for(n=0,o=this._children.length;o>n;n++)i=i.concat(this._children[n].listeners())}return i},i.prototype.kill=function(){if(this.emit("emmett:kill"),this.unbindAll(),this._handlers=null,this._handlersAll=null,this._enabled=!1,this._children)for(var t=0,e=this._children.length;e>t;t++)this._children[t].kill();this._children=null},i.prototype.disable=function(){return this._enabled=!1,this},i.prototype.enable=function(){return this._enabled=!0,this},i.version="2.1.2","undefined"!=typeof n?("undefined"!=typeof r&&r.exports&&(n=r.exports=i),n.Emitter=i):"function"==typeof t&&t.amd?t("emmett",[],function(){return i}):this.Emitter=i}).call(this)},{}],4:[function(t,e){function r(t){return t+"$"+(new Date).getTime()+(""+Math.random()).replace("0.","")}function n(t,e){if(arguments.length<1&&(t={}),!(this instanceof n))return new n(t,e);if(!l.Object(t)&&!l.Array(t))throw Error("Baobab: invalid data.");i.call(this),this.options=s.shallowMerge(c,e),this._transaction={},this._future=void 0,this._cursors={},this.data=s.deepClone(t),this.mixin=h.baobab(this)}var o=t("./cursor.js"),i=t("emmett"),s=t("./helpers.js"),a=t("./update.js"),u=t("./merge.js"),h=t("./mixins.js"),c=t("../defaults.js"),l=t("./type.js");s.inherits(n,i),n.prototype.commit=function(){this.options.shiftReferences&&(this.data=s.shallowClone(this.data));var t=a(this.data,this._transaction,this.options);return this._transaction={},this._future&&(this._future=clearTimeout(this._future)),this.emit("update",{log:t}),this},n.prototype.select=function(t){if(!t)throw Error("Baobab.select: invalid path.");if(arguments.length>1&&(t=s.arrayOf(arguments)),!l.Path(t))throw Error("Baobab.select: invalid path.");t=l.Array(t)?t:[t];var e,n=l.ComplexPath(t);if(n&&(e=s.solvePath(this.data,t)),this.options.cursorSingletons){var i=t.map(function(t){return l.Function(t)?r("fn"):l.Object(t)?r("ob"):t}).join("λ");if(this._cursors[i])return this._cursors[i];var a=new o(this,t,e,i);return this._cursors[i]=a,a}return new o(this,t)},n.prototype.root=function(){return this.select([])},n.prototype.get=function(t){if(arguments.length>1&&(t=s.arrayOf(arguments)),!l.Path(t))throw Error("Baobab.get: invalid path.");return s.getIn(this.data,l.String(t)||l.Number(t)?[t]:t)},n.prototype.set=function(t,e){if(arguments.length<2)throw Error("Baobab.set: expects a key and a value.");var r={};if(l.Array(t)){var n=s.solvePath(this.data,t);if(!n)throw Error("Baobab.set: could not solve dynamic path.");r=s.pathObject(n,{$set:e})}else r[t]={$set:e};return this.update(r)},n.prototype.unset=function(t){if(!t&&0!==t)throw Error("Baobab.unset: expects a valid key to unset.");var e={};return e[t]={$unset:!0},this.update(e)},n.prototype.update=function(t){var e=this;if(!l.Object(t))throw Error("Baobab.update: wrong specification.");return this._transaction=u(t,this._transaction),this.options.autoCommit?this.options.asynchronous?(this._future||(this._future=setTimeout(e.commit.bind(e,null),0)),this):this.commit():this},n.prototype.release=function(){delete this.data,delete this._transaction;for(var t in this._cursors)this._cursors[t].release();delete this._cursors,this.kill()},n.prototype.toJSON=function(){return this.get()},e.exports=n},{"../defaults.js":1,"./cursor.js":6,"./helpers.js":7,"./merge.js":8,"./mixins.js":9,"./type.js":10,"./update.js":11,emmett:3}],5:[function(t,e){function r(t,e){e.on("update",t.cursorListener),t.tree.off("update",t.treeListener),t.tree.on("update",t.treeListener)}function n(t){var e=this;if(arguments.length<2)throw Error("baobab.Combination: not enough arguments.");var n=arguments[1],o=s.arrayOf(arguments).slice(2);if(n instanceof Array&&(o=n.slice(1),n=n[0]),!a.Cursor(n))throw Error("baobab.Combination: argument should be a cursor.");if("or"!==t&&"and"!==t)throw Error("baobab.Combination: invalid operator.");i.call(this),this.cursors=[n],this.operators=[],this.tree=n.tree,this.updates=new Array(this.cursors.length),this.cursorListener=function(){e.updates[e.cursors.indexOf(this)]=!0},this.treeListener=function(){var t,r,n=e.updates[0];for(t=1,r=e.cursors.length;r>t;t++)n="or"===e.operators[t-1]?n||e.updates[t]:n&&e.updates[t];n&&e.emit("update"),e.updates=new Array(e.cursors.length)},this.bound=!1;var u=this.on,h=this.once,c=function(){e.bound||(e.bound=!0,e.cursors.forEach(function(t){r(e,t)}))};this.on=function(){return c(),u.apply(this,arguments)},this.once=function(){return c(),h.apply(this,arguments)},o.forEach(function(e){this[t](e)},this)}function o(t){n.prototype[t]=function(e){if(!a.Cursor(e))throw this.release(),Error("baobab.Combination."+t+": argument should be a cursor.");if(~this.cursors.indexOf(e))throw this.release(),Error("baobab.Combination."+t+": cursor already in combination.");return this.cursors.push(e),this.operators.push(t),this.updates.length++,this.bound&&r(this,e),this}}var i=t("emmett"),s=t("./helpers.js"),a=t("./type.js");s.inherits(n,i),o("or"),o("and"),n.prototype.release=function(){this.cursors.forEach(function(t){t.off("update",this.cursorListener)},this),this.tree.off("update",this.treeListener),this.cursors=null,this.operators=null,this.tree=null,this.updates=null,this.kill()},e.exports=n},{"./helpers.js":7,"./type.js":10,emmett:3}],6:[function(t,e){function r(t,e,r,o){var a=this;n.call(this),e=e||[],this.tree=t,this.path=e,this.hash=o,this.relevant=void 0!==this.get(),this.complexPath=!!r,this.solvedPath=this.complexPath?r:this.path,this.updateHandler=function(t){var e,r,n,o,i,u,h=t.data.log,c=!1;if(a.complexPath&&(a.solvedPath=s.solvePath(a.tree.data,a.path)),!a.path.length)return a.emit("update");t:for(i=0,n=h.length;n>i;i++)for(e=h[i],u=0,o=e.length;o>u&&(r=e[u],r===""+a.solvedPath[u]);u++)if(u+1===o||u+1===a.solvedPath.length){c=!0;break t}var l=void 0!==a.get();a.relevant?l&&c?a.emit("update"):l||(a.emit("irrelevant"),a.relevant=!1):l&&c&&(a.emit("relevant"),a.emit("update"),a.relevant=!0)},this.mixin=i.cursor(this);var u=!1,h=this.on,c=this.once,l=function(){u||(u=!0,a.tree.on("update",a.updateHandler))};this.on=function(){return l(),h.apply(this,arguments)},this.once=function(){return l(),c.apply(this,arguments)}}var n=t("emmett"),o=t("./combination.js"),i=t("./mixins.js"),s=t("./helpers.js"),a=t("./type.js");s.inherits(r,n),r.prototype.isRoot=function(){return!this.path.length},r.prototype.isLeaf=function(){return a.Primitive(this.get())},r.prototype.isBranch=function(){return!this.isLeaf()&&!this.isRoot()},r.prototype.root=function(){return this.tree.root()},r.prototype.select=function(t){if(arguments.length>1&&(t=s.arrayOf(arguments)),!a.Path(t))throw Error("baobab.Cursor.select: invalid path.");return this.tree.select(this.path.concat(t))},r.prototype.up=function(){return this.solvedPath&&this.solvedPath.length?this.tree.select(this.path.slice(0,-1)):null},r.prototype.left=function(){var t=+this.solvedPath[this.solvedPath.length-1];if(isNaN(t))throw Error("baobab.Cursor.left: cannot go left on a non-list type.");return t?this.tree.select(this.solvedPath.slice(0,-1).concat(t-1)):null},r.prototype.leftmost=function(){var t=+this.solvedPath[this.solvedPath.length-1];if(isNaN(t))throw Error("baobab.Cursor.leftmost: cannot go left on a non-list type.");return this.tree.select(this.solvedPath.slice(0,-1).concat(0))},r.prototype.right=function(){var t=+this.solvedPath[this.solvedPath.length-1];if(isNaN(t))throw Error("baobab.Cursor.right: cannot go right on a non-list type.");return t+1===this.up().get().length?null:this.tree.select(this.solvedPath.slice(0,-1).concat(t+1))},r.prototype.rightmost=function(){var t=+this.solvedPath[this.solvedPath.length-1];if(isNaN(t))throw Error("baobab.Cursor.right: cannot go right on a non-list type.");var e=this.up().get();return this.tree.select(this.solvedPath.slice(0,-1).concat(e.length-1))},r.prototype.down=function(){+this.solvedPath[this.solvedPath.length-1];return this.get()instanceof Array?this.tree.select(this.solvedPath.concat(0)):null},r.prototype.get=function(t){return arguments.length>1&&(t=s.arrayOf(arguments)),this.tree.get(a.Step(t)?this.solvedPath.concat(t):this.solvedPath)},r.prototype.set=function(t,e){if(arguments.length<2)throw Error("baobab.Cursor.set: expecting at least key/value.");var r=this.get();if("object"!=typeof r)throw Error("baobab.Cursor.set: trying to set key to a non-object.");var n={};if(a.Array(t)){var o=s.solvePath(r,t);if(!o)throw Error("baobab.Cursor.set: could not solve dynamic path.");n=s.pathObject(o,{$set:e})}else n[t]={$set:e};return this.update(n)},r.prototype.edit=function(t){return this.update({$set:t})},r.prototype.unset=function(t){if(!t&&0!==t)throw Error("baobab.Cursor.unset: expects a valid key to unset.");if("object"!=typeof this.get())throw Error("baobab.Cursor.set: trying to set key to a non-object.");var e={};return e[t]={$unset:!0},this.update(e)},r.prototype.remove=function(){if(this.isRoot())throw Error("baobab.Cursor.remove: cannot remove root node.");return this.update({$unset:!0})},r.prototype.apply=function(t){if("function"!=typeof t)throw Error("baobab.Cursor.apply: argument is not a function.");return this.update({$apply:t})},r.prototype.chain=function(t){if("function"!=typeof t)throw Error("baobab.Cursor.chain: argument is not a function.");return this.update({$chain:t})},r.prototype.push=function(t){if(!(this.get()instanceof Array))throw Error("baobab.Cursor.push: trying to push to non-array value.");return this.update(arguments.length>1?{$push:s.arrayOf(arguments)}:{$push:t})},r.prototype.unshift=function(t){if(!(this.get()instanceof Array))throw Error("baobab.Cursor.push: trying to push to non-array value.");return this.update(arguments.length>1?{$unshift:s.arrayOf(arguments)}:{$unshift:t})},r.prototype.merge=function(t){if(!a.Object(t))throw Error("baobab.Cursor.merge: trying to merge a non-object.");if(!a.Object(this.get()))throw Error("baobab.Cursor.merge: trying to merge into a non-object.");this.update({$merge:t})},r.prototype.update=function(t){return this.tree.update(s.pathObject(this.solvedPath,t)),this},r.prototype.or=function(t){return new o("or",this,t)},r.prototype.and=function(t){return new o("and",this,t)},r.prototype.release=function(){this.tree.off("update",this.updateHandler),this.hash&&delete this.tree._cursors[this.hash],delete this.tree,delete this.path,delete this.solvedPath,this.kill()},r.prototype.toJSON=function(){return this.get()},a.Cursor=function(t){return t instanceof r},e.exports=r},{"./combination.js":5,"./helpers.js":7,"./mixins.js":9,"./type.js":10,emmett:3}],7:[function(t,e){function r(t){return Array.prototype.slice.call(t)}function n(t,e){var r,n={};for(r in t)n[r]=t[r];for(r in e)n[r]=e[r];return n}function o(t){var e=t.source,r="";return t.global&&(r+="g"),t.multiline&&(r+="m"),t.ignoreCase&&(r+="i"),t.sticky&&(r+="y"),t.unicode&&(r+="u"),new RegExp(e,r)}function i(t,e){if(!e||"object"!=typeof e||e instanceof Error||e instanceof ArrayBuffer)return e;if(g.Array(e)){if(t){var r,n,i=[];for(r=0,n=e.length;n>r;r++)i.push(m(e[r]));return i}return e.slice(0)}if(g.Date(e))return new Date(e.getTime());if(e instanceof RegExp)return o(e);if(g.Object(e)){var s,a={};e.constructor&&e.constructor!==Object&&(a=Object.create(e.constructor.prototype));for(s in e)e.hasOwnProperty(s)&&(a[s]=t?m(e[s]):e[s]);return a}return e}function s(t,e){return function(r){return e(t(r))}}function a(t,e){var r,n;for(r=0,n=t.length;n>r;r++)if(e(t[r]))return t[r]}function u(t,e){var r,n;for(r=0,n=t.length;n>r;r++)if(e(t[r]))return r;return-1}function h(t,e){var r,n=!0;if(!t)return!1;for(r in e)if(g.Object(e[r]))n=n&&h(t[r],e[r]);else if(g.Array(e[r]))n=n&&!!~e[r].indexOf(t[r]);else if(t[r]!==e[r])return!1;return n}function c(t,e){return a(t,function(t){return h(t,e)})}function l(t,e){return u(t,function(t){return h(t,e)})}function f(t,e){e=e||[];var r,n,o=t;for(r=0,n=e.length;n>r;r++){if(!o)return;if("function"==typeof e[r]){if(!g.Array(o))return;o=a(o,e[r])}else if("object"==typeof e[r]){if(!g.Array(o))return;o=c(o,e[r])}else o=o[e[r]]}return o}function p(t,e){var r,n,o,i=[],s=t;for(n=0,o=e.length;o>n;n++){if(!s)return null;if("function"==typeof e[n]){if(!g.Array(s))return;r=u(s,e[n]),i.push(r),s=s[r]}else if("object"==typeof e[n]){if(!g.Array(s))return;r=l(s,e[n]),i.push(r),s=s[r]}else i.push(e[n]),s=s[e[n]]||{}}return i}function d(t,e){var r,n=t.length,o={},i=o;for(n||(o=e),r=0;n>r;r++)i[t[r]]=r+1===n?e:{},i=i[t[r]];return o}function y(t,e){t.super_=e;var r=function(){};r.prototype=e.prototype,t.prototype=new r,t.prototype.constructor=t}var g=t("./type.js"),b=i.bind(null,!1),m=i.bind(null,!0);e.exports={arrayOf:r,deepClone:m,shallowClone:b,shallowMerge:n,compose:s,getIn:f,inherits:y,pathObject:d,solvePath:p}},{"./type.js":10}],8:[function(t,e){function r(t,e){return e in(t||{})}function n(t,e,n){return r(t,n)&&r(e,n)}function o(){var t,e,r,a,u={},h=arguments.length;for(r=h-1;r>=0;r--){if(arguments[r].$unset)delete u.$set,delete u.$apply,delete u.$merge,u.$unset=arguments[r].$unset;else{if(arguments[r].$set){delete u.$apply,delete u.$merge,delete u.$unset,u.$set=arguments[r].$set;continue}if(arguments[r].$merge){delete u.$set,delete u.$apply,delete u.$unset,u.$merge=arguments[r].$merge;continue}if(arguments[r].$apply){delete u.$set,delete u.$merge,delete u.$unset,u.$apply=arguments[r].$apply;continue}if(arguments[r].$chain){delete u.$set,delete u.$merge,delete u.$unset,u.$apply=u.$apply?i.compose(u.$apply,arguments[r].$chain):arguments[r].$chain;continue}}for(a in arguments[r])t=u[a],e=arguments[r][a],t&&s.Object(e)?n(t,e,"$push")?t.$push=s.Array(t.$push)?t.$push.concat(e.$push):[t.$push].concat(e.$push):n(t,e,"$unshift")?t.$unshift=s.Array(e.$unshift)?e.$unshift.concat(t.$unshift):[e.$unshift].concat(t.$unshift):u[a]=o(e,t):u[a]=e}return u}var i=t("./helpers.js"),s=t("./type.js");e.exports=o},{"./helpers.js":7,"./type.js":10}],9:[function(t,e){var r=t("./combination.js"),n=t("./type.js");e.exports={baobab:function(t){return{mixins:[{getInitialState:function(){if(this.tree=t,!this.cursor&&!this.cursors)return{};if(this.cursor&&this.cursors)throw Error("baobab.mixin: you cannot have both `component.cursor` and `component.cursors`. Please make up your mind.");if(this.__type=null,this.__updateHandler=function(){this.setState(this.__getCursorData())}.bind(this),this.cursor){if(!n.MixinCursor(this.cursor))throw Error("baobab.mixin.cursor: invalid data (cursor, string, array or function).");n.Function(this.cursor)&&(this.cursor=this.cursor()),n.Cursor(this.cursor)||(this.cursor=t.select(this.cursor)),this.__getCursorData=function(){return{cursor:this.cursor.get()}}.bind(this),this.__type="single"}else if(this.cursors){if(!n.MixinCursors(this.cursors))throw Error("baobab.mixin.cursor: invalid data (object, array or function).");if(n.Function(this.cursors)&&(this.cursors=this.cursors()),n.Array(this.cursors))this.cursors=this.cursors.map(function(e){return n.Cursor(e)?e:t.select(e)}),this.__getCursorData=function(){return{cursors:this.cursors.map(function(t){return t.get()})}}.bind(this),this.__type="array";else{for(var e in this.cursors)n.Cursor(this.cursors[e])||(this.cursors[e]=t.select(this.cursors[e]));this.__getCursorData=function(){var t={};for(e in this.cursors)t[e]=this.cursors[e].get();return{cursors:t}}.bind(this),this.__type="object"}}return this.__getCursorData()},componentDidMount:function(){"single"===this.__type?(this.__combination=new r("or",[this.cursor]),this.__combination.on("update",this.__updateHandler)):"array"===this.__type?(this.__combination=new r("or",this.cursors),this.__combination.on("update",this.__updateHandler)):"object"===this.__type&&(this.__combination=new r("or",Object.keys(this.cursors).map(function(t){return this.cursors[t]},this)),this.__combination.on("update",this.__updateHandler))},componentWillUnmount:function(){this.__combination&&this.__combination.release()}}].concat(t.options.mixins)}},cursor:function(t){return{mixins:[{getInitialState:function(){return this.cursor=t,this.__updateHandler=function(){this.setState({cursor:this.cursor.get()})}.bind(this),{cursor:this.cursor.get()}},componentDidMount:function(){this.cursor.on("update",this.__updateHandler)},componentWillUnmount:function(){this.cursor.off("update",this.__updateHandler)}}].concat(t.tree.options.mixins)}}}},{"./combination.js":5,"./type.js":10}],10:[function(t,e){var r=function(t){return Array.isArray(t)?"array":"object"==typeof t&&null!==t?"object":"string"==typeof t?"string":"number"==typeof t?"number":"boolean"==typeof t?"boolean":"function"==typeof t?"function":null===t?"null":void 0===t?"undefined":t instanceof Date?"date":"invalid"};r.Array=function(t){return Array.isArray(t)},r.Object=function(t){return!Array.isArray(t)&&"object"==typeof t&&null!==t},r.String=function(t){return"string"==typeof t},r.Number=function(t){return"number"==typeof t},r.Boolean=function(t){return"boolean"==typeof t},r.Function=function(t){return"function"==typeof t},r.Primitive=function(t){return"string"==typeof t||"number"==typeof t||"boolean"==typeof t},r.Date=function(t){return t instanceof Date},r.Step=function(t){var e=r(t),n=["null","undefined","invalid","date"];return-1===n.indexOf(e)},r.Path=function(t){var e=["object","string","number","function","undefined"];if(!r.Array(t))return e.indexOf(r(t))>=0;for(var n=0;n=0||r.Cursor(t)},r.MixinCursors=function(t){var e=["array","object","function"];return e.indexOf(r(t))>=0},r.ComplexPath=function(t){for(var e=["object","function"],n=0;n=0)return!0;return!1},e.exports=r},{}],11:[function(t,e){function r(t,e){var r=new Error("baobab.update: "+e+" at path /"+t.toString());return r.path=t,r}function n(t,e,n){n=n||{shiftReferences:!1};var a={};return function u(t,e,h,c){h=h||[];var l,f,p,d,y=h.join("λ");for(p in e)if(s[p])switch(d=e[p],a[y]=!0,p){case"$push":if(!i.Array(t))throw r(h,"using command $push to a non array");i.Array(d)?t.push.apply(t,d):t.push(d);break;case"$unshift":if(!i.Array(t))throw r(h,"using command $unshift to a non array");i.Array(d)?t.unshift.apply(t,d):t.unshift(d)}else if(f=y?y+"λ"+p:p,"$unset"in(e[p]||{}))a[f]=!0,i.Array(t)?n.shiftReferences?c[h[h.length-1]]=t.slice(0,+p).concat(t.slice(+p+1)):t.splice(p,1):delete t[p];else if("$set"in(e[p]||{}))d=e[p].$set,a[f]=!0,t[p]=d;else if("$apply"in(e[p]||{})||"$chain"in(e[p]||{})){if(l=e[p].$apply||e[p].$chain,"function"!=typeof l)throw r(h.concat(p),"using command $apply with a non function");a[f]=!0,t[p]=l.call(null,t[p])}else if("$merge"in(e[p]||{})){if(d=e[p].$merge,!i.Object(t[p]))throw r(h.concat(p),"using command $merge on a non-object");a[f]=!0,t[p]=o.shallowMerge(t[p],d)}else if(n.shiftReferences&&("$push"in(e[p]||{})||"$unshift"in(e[p]||{}))){if("$push"in(e[p]||{})){if(d=e[p].$push,!i.Array(t[p]))throw r(h.concat(p),"using command $push to a non array");t[p]=t[p].concat(d)}if("$unshift"in(e[p]||{})){if(d=e[p].$unshift,!i.Array(t[p]))throw r(h.concat(p),"using command $unshift to a non array");t[p]=(d instanceof Array?d:[d]).concat(t[p])}a[f]=!0}else"undefined"==typeof t[p]&&(t[p]={}),n.shiftReferences&&(t[p]=o.shallowClone(t[p])),u(t[p],e[p],h.concat(p),t)}(t,e),Object.keys(a).map(function(t){return t.split("λ")})}var o=t("./helpers.js"),i=t("./type.js"),s={};["$set","$push","$unshift","$apply","$merge"].forEach(function(t){s[t]=!0}),e.exports=n},{"./helpers.js":7,"./type.js":10}]},{},[2])(2)}); \ No newline at end of file diff --git a/src/baobab.js b/src/baobab.js index 8e25a02..e825cd6 100644 --- a/src/baobab.js +++ b/src/baobab.js @@ -37,7 +37,6 @@ function Baobab(initialData, opts) { // Merging defaults this.options = helpers.shallowMerge(defaults, opts); - this._cloner = this.options.cloningFunction || helpers.deepClone; // Privates this._transaction = {}; @@ -45,7 +44,7 @@ function Baobab(initialData, opts) { this._cursors = {}; // Properties - this.data = this._cloner(initialData); + this.data = helpers.deepClone(initialData); // Mixin this.mixin = mixins.baobab(this); @@ -130,7 +129,7 @@ Baobab.prototype.root = function() { return this.select([]); }; -Baobab.prototype.reference = function(path) { +Baobab.prototype.get = function(path) { var data; if (arguments.length > 1) @@ -144,16 +143,6 @@ Baobab.prototype.reference = function(path) { ); }; -Baobab.prototype.get = function() { - var ref = this.reference.apply(this, arguments); - - return this.options.clone ? this._cloner(ref) : ref; -}; - -Baobab.prototype.clone = function(path) { - return this._cloner(this.reference.apply(this, arguments)); -}; - Baobab.prototype.set = function(key, val) { if (arguments.length < 2) @@ -227,7 +216,7 @@ Baobab.prototype.release = function() { * Output */ Baobab.prototype.toJSON = function() { - return this.reference(); + return this.get(); }; /** diff --git a/src/cursor.js b/src/cursor.js index a2e6134..c4f8216 100644 --- a/src/cursor.js +++ b/src/cursor.js @@ -26,7 +26,7 @@ function Cursor(tree, path, solvedPath, hash) { this.tree = tree; this.path = path; this.hash = hash; - this.relevant = this.reference() !== undefined; + this.relevant = this.get() !== undefined; // Complex path? this.complexPath = !!solvedPath; @@ -67,7 +67,7 @@ function Cursor(tree, path, solvedPath, hash) { } // Handling relevancy - var data = self.reference() !== undefined; + var data = self.get() !== undefined; if (self.relevant) { if (data && shouldFire) { @@ -123,7 +123,7 @@ Cursor.prototype.isRoot = function() { }; Cursor.prototype.isLeaf = function() { - return type.Primitive(this.reference()); + return type.Primitive(this.get()); }; Cursor.prototype.isBranch = function() { @@ -179,7 +179,7 @@ Cursor.prototype.right = function() { if (isNaN(last)) throw Error('baobab.Cursor.right: cannot go right on a non-list type.'); - if (last + 1 === this.up().reference().length) + if (last + 1 === this.up().get().length) return null; return this.tree.select(this.solvedPath.slice(0, -1).concat(last + 1)); @@ -191,7 +191,7 @@ Cursor.prototype.rightmost = function() { if (isNaN(last)) throw Error('baobab.Cursor.right: cannot go right on a non-list type.'); - var list = this.up().reference(); + var list = this.up().get(); return this.tree.select(this.solvedPath.slice(0, -1).concat(list.length - 1)); }; @@ -199,7 +199,7 @@ Cursor.prototype.rightmost = function() { Cursor.prototype.down = function() { var last = +this.solvedPath[this.solvedPath.length - 1]; - if (!(this.reference() instanceof Array)) + if (!(this.get() instanceof Array)) return null; return this.tree.select(this.solvedPath.concat(0)); @@ -218,26 +218,6 @@ Cursor.prototype.get = function(path) { return this.tree.get(this.solvedPath); }; -Cursor.prototype.reference = function(path) { - if (arguments.length > 1) - path = helpers.arrayOf(arguments); - - if (type.Step(path)) - return this.tree.reference(this.solvedPath.concat(path)); - else - return this.tree.reference(this.solvedPath); -}; - -Cursor.prototype.clone = function(path) { - if (arguments.length > 1) - path = helpers.arrayOf(arguments); - - if (type.Step(path)) - return this.tree.clone(this.solvedPath.concat(path)); - else - return this.tree.clone(this.solvedPath); -}; - /** * Update */ @@ -245,7 +225,7 @@ Cursor.prototype.set = function(key, val) { if (arguments.length < 2) throw Error('baobab.Cursor.set: expecting at least key/value.'); - var data = this.reference(); + var data = this.get(); if (typeof data !== 'object') throw Error('baobab.Cursor.set: trying to set key to a non-object.'); @@ -275,7 +255,7 @@ Cursor.prototype.unset = function(key) { if (!key && key !== 0) throw Error('baobab.Cursor.unset: expects a valid key to unset.'); - if (typeof this.reference() !== 'object') + if (typeof this.get() !== 'object') throw Error('baobab.Cursor.set: trying to set key to a non-object.'); var spec = {}; @@ -305,7 +285,7 @@ Cursor.prototype.chain = function(fn) { }; Cursor.prototype.push = function(value) { - if (!(this.reference() instanceof Array)) + if (!(this.get() instanceof Array)) throw Error('baobab.Cursor.push: trying to push to non-array value.'); if (arguments.length > 1) @@ -315,7 +295,7 @@ Cursor.prototype.push = function(value) { }; Cursor.prototype.unshift = function(value) { - if (!(this.reference() instanceof Array)) + if (!(this.get() instanceof Array)) throw Error('baobab.Cursor.push: trying to push to non-array value.'); if (arguments.length > 1) @@ -328,7 +308,7 @@ Cursor.prototype.merge = function(o) { if (!type.Object(o)) throw Error('baobab.Cursor.merge: trying to merge a non-object.'); - if (!type.Object(this.reference())) + if (!type.Object(this.get())) throw Error('baobab.Cursor.merge: trying to merge into a non-object.'); this.update({$merge: o}); @@ -375,7 +355,7 @@ Cursor.prototype.release = function() { * Output */ Cursor.prototype.toJSON = function() { - return this.reference(); + return this.get(); }; type.Cursor = function (value) { diff --git a/test/suites/baobab.js b/test/suites/baobab.js index 177f737..71a6066 100644 --- a/test/suites/baobab.js +++ b/test/suites/baobab.js @@ -182,18 +182,6 @@ describe('Baobab API', function() { }, 0); }); - it('should be possible to serve cloned data.', function() { - var baobab1 = new Baobab({hello: 'world'}), - baobab2 = new Baobab({hello: 'world'}, {clone: true}); - - assert(baobab1.get() === baobab1.data); - assert(baobab1.clone() !== baobab1.data); - assert.deepEqual(baobab1.clone(), baobab1.data); - assert(baobab2.get() !== baobab2.data); - assert(baobab2.reference() === baobab2.data); - assert.deepEqual(baobab2.get(), {hello: 'world'}); - }); - it('should be possible to shunt the singleton cursors.', function() { var baobab1 = new Baobab({hello: 'world'}), baobab2 = new Baobab({hello: 'world'}, {cursorSingletons: false}); @@ -202,13 +190,6 @@ describe('Baobab API', function() { assert(baobab2.select('hello') !== baobab2.select('hello')); }); - it('should be possible to provide your own cloning function to the tree.', function() { - var baobab = new Baobab({hello: 'world'}, {cloningFunction: clone}); - - assert(baobab._cloner === clone); - assert.deepEqual(baobab.clone(), baobab.data); - }); - it('should be possible to tell the tree to shift references on updates.', function() { var list = [1], baobab = new Baobab({list: list}, {shiftReferences: true, asynchronous: false}); @@ -218,30 +199,31 @@ describe('Baobab API', function() { assert(list !== baobab.get('list')); }); - it('should also shift parent references.', function() { - var tree = new Baobab({root: {admin: {items: [1], other: [2]}}}, {asynchronous: false}), - shiftingTree = new Baobab({root: {admin: {items: [1], other: [2]}}}, {shiftReferences: true, asynchronous: false}); + // TODO: rehabilitate this test when further updates are made + // it('should also shift parent references.', function() { + // var tree = new Baobab({root: {admin: {items: [1], other: [2]}}}, {asynchronous: false}), + // shiftingTree = new Baobab({root: {admin: {items: [1], other: [2]}}}, {shiftReferences: true, asynchronous: false}); - var original = tree.reference(), - shiftingOriginal = shiftingTree.reference(); + // var original = tree.reference(), + // shiftingOriginal = shiftingTree.reference(); - tree.select('root', 'admin', 'items').push(2); - shiftingTree.select('root', 'admin', 'items').push(2); + // tree.select('root', 'admin', 'items').push(2); + // shiftingTree.select('root', 'admin', 'items').push(2); - assert.deepEqual(tree.reference('root', 'admin', 'items'), [1, 2]); - assert.deepEqual(shiftingTree.reference('root', 'admin', 'items'), [1, 2]); + // assert.deepEqual(tree.reference('root', 'admin', 'items'), [1, 2]); + // assert.deepEqual(shiftingTree.reference('root', 'admin', 'items'), [1, 2]); - assert(tree.reference() === original); - assert(tree.reference().root === original.root); - assert(tree.reference().root.admin === original.root.admin); - assert(tree.reference().root.admin.items === original.root.admin.items); - assert(tree.reference().root.admin.other === original.root.admin.other); + // assert(tree.reference() === original); + // assert(tree.reference().root === original.root); + // assert(tree.reference().root.admin === original.root.admin); + // assert(tree.reference().root.admin.items === original.root.admin.items); + // assert(tree.reference().root.admin.other === original.root.admin.other); - assert(shiftingTree.reference() !== shiftingOriginal); - assert(shiftingTree.reference().root !== shiftingOriginal.root); - assert(shiftingTree.reference().root.admin !== shiftingOriginal.root.admin); - assert(shiftingTree.reference().root.admin.items !== shiftingOriginal.root.admin.items); - assert(shiftingTree.reference().root.admin.other === shiftingOriginal.root.admin.other); - }); + // assert(shiftingTree.reference() !== shiftingOriginal); + // assert(shiftingTree.reference().root !== shiftingOriginal.root); + // assert(shiftingTree.reference().root.admin !== shiftingOriginal.root.admin); + // assert(shiftingTree.reference().root.admin.items !== shiftingOriginal.root.admin.items); + // assert(shiftingTree.reference().root.admin.other === shiftingOriginal.root.admin.other); + // }); }); }); From effbe70a4988416de9f68d85a54b3a1fdc952099 Mon Sep 17 00:00:00 2001 From: Yomguithereal Date: Fri, 27 Mar 2015 19:42:17 +0100 Subject: [PATCH 05/73] Removing cursorSingletons option --- build/baobab.min.js | 2 +- src/baobab.js | 33 ++++++++++++++------------------- test/suites/baobab.js | 8 -------- 3 files changed, 15 insertions(+), 28 deletions(-) diff --git a/build/baobab.min.js b/build/baobab.min.js index 8c4f50a..dcb6bd0 100644 --- a/build/baobab.min.js +++ b/build/baobab.min.js @@ -1,2 +1,2 @@ /* baobab.js - Version: 0.4.3 - Author: Yomguithereal (Guillaume Plique) */ -!function(t){if("object"==typeof exports&&"undefined"!=typeof module)module.exports=t();else if("function"==typeof define&&define.amd)define([],t);else{var e;e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:this,e.Baobab=t()}}(function(){var t;return function e(t,r,n){function o(s,a){if(!r[s]){if(!t[s]){var u="function"==typeof require&&require;if(!a&&u)return u(s,!0);if(i)return i(s,!0);var h=new Error("Cannot find module '"+s+"'");throw h.code="MODULE_NOT_FOUND",h}var c=r[s]={exports:{}};t[s][0].call(c.exports,function(e){var r=t[s][1][e];return o(r?r:e)},c,c.exports,e,t,r,n)}return r[s].exports}for(var i="function"==typeof require&&require,s=0;se;e++)n.push(t[e].handler);return n}var o={once:"boolean",scope:"object"},i=function(){this._enabled=!0,this._children=[],this._handlers={},this._handlersAll=[]};i.prototype.on=function(t,e,r){var n,s,a,u,h,c;if("function"==typeof e){for(h="string"==typeof t?[t]:t,n=0,s=h.length;n!==s;n+=1)if(u=h[n]){this._handlers[u]||(this._handlers[u]=[]),c={handler:e};for(a in r||{}){if(!o[a])throw new Error('The option "'+a+'" is not recognized by Emmett.');c[a]=r[a]}this._handlers[u].push(c)}}else if(t&&"object"==typeof t&&!Array.isArray(t))for(u in t)i.prototype.on.call(this,u,t[u],e);else{if("function"!=typeof t)throw new Error("Wrong arguments.");c={handler:t};for(a in r||{}){if(!o[a])throw new Error('The option "'+a+'" is not recognized by Emmett.');c[a]=r[a]}this._handlersAll.push(c)}return this},i.prototype.once=function(t,e,r){if("function"==typeof e)r=r||{},r.once=!0,this.on(t,e,r);else{if((!t||"object"!=typeof t||Array.isArray(t))&&"function"!=typeof t)throw new Error("Wrong arguments.");e=e||{},e.once=!0,this.on(t,e)}return this},i.prototype.off=function(t,e){var r,n,o,i,s,a,u,h="string"==typeof t?[t]:t;if(1===arguments.length&&"function"==typeof h){e=arguments[0];for(s in this._handlers){for(a=[],r=0,n=this._handlers[s].length;r!==n;r+=1)this._handlers[s][r].handler!==e&&a.push(this._handlers[s][r]);this._handlers[s]=a}for(a=[],r=0,n=this._handlersAll.length;r!==n;r+=1)this._handlersAll[r].handler!==e&&a.push(this._handlersAll[r]);this._handlersAll=a}else if(2===arguments.length)for(r=0,n=h.length;r!==n;r+=1){if(u=h[r],this._handlers[u]){for(a=[],o=0,i=this._handlers[u].length;o!==i;o+=1)this._handlers[u][o].handler!==e&&a.push(this._handlers[u][o]);this._handlers[u]=a}this._handlers[u]&&0===this._handlers[u].length&&delete this._handlers[u]}return this},i.prototype.unbindAll=function(){var t;this._handlersAll=[];for(t in this._handlers)delete this._handlers[t];return this},i.prototype.emit=function(t,e){var r,n,o,i,s,a,u,h,c,l,f="string"==typeof t?[t]:t;if(!this._enabled)return this;for(e=void 0===e?{}:e,r=0,n=f.length;r!==n;r+=1)if(l=f[r],c=(this._handlers[l]||[]).concat(this._handlersAll),c.length){for(u={type:l,data:e||{},target:this},a=[],o=0,i=c.length;o!==i;o+=1)(this._handlers[l]&&this._handlers[l].indexOf(c[o])>=0||this._handlersAll.indexOf(c[o])>=0)&&(c[o].handler.call("scope"in c[o]?c[o].scope:this,u),c[o].once&&a.push(c[o]));for(s=0;sr;r++)if(t._children[r]===e){t._children.splice(r,1);break}}),this._children.push(e),e},i.prototype.listeners=function(t){var r,n,o,i=[];if(t)for(i=e(this._handlers[t]),n=0,o=this._children.length;o>n;n++)i=i.concat(this._children[n].listeners(t));else{i=e(this._handlersAll);for(r in this._handlers)i=i.concat(e(this._handlers[r]));for(n=0,o=this._children.length;o>n;n++)i=i.concat(this._children[n].listeners())}return i},i.prototype.kill=function(){if(this.emit("emmett:kill"),this.unbindAll(),this._handlers=null,this._handlersAll=null,this._enabled=!1,this._children)for(var t=0,e=this._children.length;e>t;t++)this._children[t].kill();this._children=null},i.prototype.disable=function(){return this._enabled=!1,this},i.prototype.enable=function(){return this._enabled=!0,this},i.version="2.1.2","undefined"!=typeof n?("undefined"!=typeof r&&r.exports&&(n=r.exports=i),n.Emitter=i):"function"==typeof t&&t.amd?t("emmett",[],function(){return i}):this.Emitter=i}).call(this)},{}],4:[function(t,e){function r(t){return t+"$"+(new Date).getTime()+(""+Math.random()).replace("0.","")}function n(t,e){if(arguments.length<1&&(t={}),!(this instanceof n))return new n(t,e);if(!l.Object(t)&&!l.Array(t))throw Error("Baobab: invalid data.");i.call(this),this.options=s.shallowMerge(c,e),this._transaction={},this._future=void 0,this._cursors={},this.data=s.deepClone(t),this.mixin=h.baobab(this)}var o=t("./cursor.js"),i=t("emmett"),s=t("./helpers.js"),a=t("./update.js"),u=t("./merge.js"),h=t("./mixins.js"),c=t("../defaults.js"),l=t("./type.js");s.inherits(n,i),n.prototype.commit=function(){this.options.shiftReferences&&(this.data=s.shallowClone(this.data));var t=a(this.data,this._transaction,this.options);return this._transaction={},this._future&&(this._future=clearTimeout(this._future)),this.emit("update",{log:t}),this},n.prototype.select=function(t){if(!t)throw Error("Baobab.select: invalid path.");if(arguments.length>1&&(t=s.arrayOf(arguments)),!l.Path(t))throw Error("Baobab.select: invalid path.");t=l.Array(t)?t:[t];var e,n=l.ComplexPath(t);if(n&&(e=s.solvePath(this.data,t)),this.options.cursorSingletons){var i=t.map(function(t){return l.Function(t)?r("fn"):l.Object(t)?r("ob"):t}).join("λ");if(this._cursors[i])return this._cursors[i];var a=new o(this,t,e,i);return this._cursors[i]=a,a}return new o(this,t)},n.prototype.root=function(){return this.select([])},n.prototype.get=function(t){if(arguments.length>1&&(t=s.arrayOf(arguments)),!l.Path(t))throw Error("Baobab.get: invalid path.");return s.getIn(this.data,l.String(t)||l.Number(t)?[t]:t)},n.prototype.set=function(t,e){if(arguments.length<2)throw Error("Baobab.set: expects a key and a value.");var r={};if(l.Array(t)){var n=s.solvePath(this.data,t);if(!n)throw Error("Baobab.set: could not solve dynamic path.");r=s.pathObject(n,{$set:e})}else r[t]={$set:e};return this.update(r)},n.prototype.unset=function(t){if(!t&&0!==t)throw Error("Baobab.unset: expects a valid key to unset.");var e={};return e[t]={$unset:!0},this.update(e)},n.prototype.update=function(t){var e=this;if(!l.Object(t))throw Error("Baobab.update: wrong specification.");return this._transaction=u(t,this._transaction),this.options.autoCommit?this.options.asynchronous?(this._future||(this._future=setTimeout(e.commit.bind(e,null),0)),this):this.commit():this},n.prototype.release=function(){delete this.data,delete this._transaction;for(var t in this._cursors)this._cursors[t].release();delete this._cursors,this.kill()},n.prototype.toJSON=function(){return this.get()},e.exports=n},{"../defaults.js":1,"./cursor.js":6,"./helpers.js":7,"./merge.js":8,"./mixins.js":9,"./type.js":10,"./update.js":11,emmett:3}],5:[function(t,e){function r(t,e){e.on("update",t.cursorListener),t.tree.off("update",t.treeListener),t.tree.on("update",t.treeListener)}function n(t){var e=this;if(arguments.length<2)throw Error("baobab.Combination: not enough arguments.");var n=arguments[1],o=s.arrayOf(arguments).slice(2);if(n instanceof Array&&(o=n.slice(1),n=n[0]),!a.Cursor(n))throw Error("baobab.Combination: argument should be a cursor.");if("or"!==t&&"and"!==t)throw Error("baobab.Combination: invalid operator.");i.call(this),this.cursors=[n],this.operators=[],this.tree=n.tree,this.updates=new Array(this.cursors.length),this.cursorListener=function(){e.updates[e.cursors.indexOf(this)]=!0},this.treeListener=function(){var t,r,n=e.updates[0];for(t=1,r=e.cursors.length;r>t;t++)n="or"===e.operators[t-1]?n||e.updates[t]:n&&e.updates[t];n&&e.emit("update"),e.updates=new Array(e.cursors.length)},this.bound=!1;var u=this.on,h=this.once,c=function(){e.bound||(e.bound=!0,e.cursors.forEach(function(t){r(e,t)}))};this.on=function(){return c(),u.apply(this,arguments)},this.once=function(){return c(),h.apply(this,arguments)},o.forEach(function(e){this[t](e)},this)}function o(t){n.prototype[t]=function(e){if(!a.Cursor(e))throw this.release(),Error("baobab.Combination."+t+": argument should be a cursor.");if(~this.cursors.indexOf(e))throw this.release(),Error("baobab.Combination."+t+": cursor already in combination.");return this.cursors.push(e),this.operators.push(t),this.updates.length++,this.bound&&r(this,e),this}}var i=t("emmett"),s=t("./helpers.js"),a=t("./type.js");s.inherits(n,i),o("or"),o("and"),n.prototype.release=function(){this.cursors.forEach(function(t){t.off("update",this.cursorListener)},this),this.tree.off("update",this.treeListener),this.cursors=null,this.operators=null,this.tree=null,this.updates=null,this.kill()},e.exports=n},{"./helpers.js":7,"./type.js":10,emmett:3}],6:[function(t,e){function r(t,e,r,o){var a=this;n.call(this),e=e||[],this.tree=t,this.path=e,this.hash=o,this.relevant=void 0!==this.get(),this.complexPath=!!r,this.solvedPath=this.complexPath?r:this.path,this.updateHandler=function(t){var e,r,n,o,i,u,h=t.data.log,c=!1;if(a.complexPath&&(a.solvedPath=s.solvePath(a.tree.data,a.path)),!a.path.length)return a.emit("update");t:for(i=0,n=h.length;n>i;i++)for(e=h[i],u=0,o=e.length;o>u&&(r=e[u],r===""+a.solvedPath[u]);u++)if(u+1===o||u+1===a.solvedPath.length){c=!0;break t}var l=void 0!==a.get();a.relevant?l&&c?a.emit("update"):l||(a.emit("irrelevant"),a.relevant=!1):l&&c&&(a.emit("relevant"),a.emit("update"),a.relevant=!0)},this.mixin=i.cursor(this);var u=!1,h=this.on,c=this.once,l=function(){u||(u=!0,a.tree.on("update",a.updateHandler))};this.on=function(){return l(),h.apply(this,arguments)},this.once=function(){return l(),c.apply(this,arguments)}}var n=t("emmett"),o=t("./combination.js"),i=t("./mixins.js"),s=t("./helpers.js"),a=t("./type.js");s.inherits(r,n),r.prototype.isRoot=function(){return!this.path.length},r.prototype.isLeaf=function(){return a.Primitive(this.get())},r.prototype.isBranch=function(){return!this.isLeaf()&&!this.isRoot()},r.prototype.root=function(){return this.tree.root()},r.prototype.select=function(t){if(arguments.length>1&&(t=s.arrayOf(arguments)),!a.Path(t))throw Error("baobab.Cursor.select: invalid path.");return this.tree.select(this.path.concat(t))},r.prototype.up=function(){return this.solvedPath&&this.solvedPath.length?this.tree.select(this.path.slice(0,-1)):null},r.prototype.left=function(){var t=+this.solvedPath[this.solvedPath.length-1];if(isNaN(t))throw Error("baobab.Cursor.left: cannot go left on a non-list type.");return t?this.tree.select(this.solvedPath.slice(0,-1).concat(t-1)):null},r.prototype.leftmost=function(){var t=+this.solvedPath[this.solvedPath.length-1];if(isNaN(t))throw Error("baobab.Cursor.leftmost: cannot go left on a non-list type.");return this.tree.select(this.solvedPath.slice(0,-1).concat(0))},r.prototype.right=function(){var t=+this.solvedPath[this.solvedPath.length-1];if(isNaN(t))throw Error("baobab.Cursor.right: cannot go right on a non-list type.");return t+1===this.up().get().length?null:this.tree.select(this.solvedPath.slice(0,-1).concat(t+1))},r.prototype.rightmost=function(){var t=+this.solvedPath[this.solvedPath.length-1];if(isNaN(t))throw Error("baobab.Cursor.right: cannot go right on a non-list type.");var e=this.up().get();return this.tree.select(this.solvedPath.slice(0,-1).concat(e.length-1))},r.prototype.down=function(){+this.solvedPath[this.solvedPath.length-1];return this.get()instanceof Array?this.tree.select(this.solvedPath.concat(0)):null},r.prototype.get=function(t){return arguments.length>1&&(t=s.arrayOf(arguments)),this.tree.get(a.Step(t)?this.solvedPath.concat(t):this.solvedPath)},r.prototype.set=function(t,e){if(arguments.length<2)throw Error("baobab.Cursor.set: expecting at least key/value.");var r=this.get();if("object"!=typeof r)throw Error("baobab.Cursor.set: trying to set key to a non-object.");var n={};if(a.Array(t)){var o=s.solvePath(r,t);if(!o)throw Error("baobab.Cursor.set: could not solve dynamic path.");n=s.pathObject(o,{$set:e})}else n[t]={$set:e};return this.update(n)},r.prototype.edit=function(t){return this.update({$set:t})},r.prototype.unset=function(t){if(!t&&0!==t)throw Error("baobab.Cursor.unset: expects a valid key to unset.");if("object"!=typeof this.get())throw Error("baobab.Cursor.set: trying to set key to a non-object.");var e={};return e[t]={$unset:!0},this.update(e)},r.prototype.remove=function(){if(this.isRoot())throw Error("baobab.Cursor.remove: cannot remove root node.");return this.update({$unset:!0})},r.prototype.apply=function(t){if("function"!=typeof t)throw Error("baobab.Cursor.apply: argument is not a function.");return this.update({$apply:t})},r.prototype.chain=function(t){if("function"!=typeof t)throw Error("baobab.Cursor.chain: argument is not a function.");return this.update({$chain:t})},r.prototype.push=function(t){if(!(this.get()instanceof Array))throw Error("baobab.Cursor.push: trying to push to non-array value.");return this.update(arguments.length>1?{$push:s.arrayOf(arguments)}:{$push:t})},r.prototype.unshift=function(t){if(!(this.get()instanceof Array))throw Error("baobab.Cursor.push: trying to push to non-array value.");return this.update(arguments.length>1?{$unshift:s.arrayOf(arguments)}:{$unshift:t})},r.prototype.merge=function(t){if(!a.Object(t))throw Error("baobab.Cursor.merge: trying to merge a non-object.");if(!a.Object(this.get()))throw Error("baobab.Cursor.merge: trying to merge into a non-object.");this.update({$merge:t})},r.prototype.update=function(t){return this.tree.update(s.pathObject(this.solvedPath,t)),this},r.prototype.or=function(t){return new o("or",this,t)},r.prototype.and=function(t){return new o("and",this,t)},r.prototype.release=function(){this.tree.off("update",this.updateHandler),this.hash&&delete this.tree._cursors[this.hash],delete this.tree,delete this.path,delete this.solvedPath,this.kill()},r.prototype.toJSON=function(){return this.get()},a.Cursor=function(t){return t instanceof r},e.exports=r},{"./combination.js":5,"./helpers.js":7,"./mixins.js":9,"./type.js":10,emmett:3}],7:[function(t,e){function r(t){return Array.prototype.slice.call(t)}function n(t,e){var r,n={};for(r in t)n[r]=t[r];for(r in e)n[r]=e[r];return n}function o(t){var e=t.source,r="";return t.global&&(r+="g"),t.multiline&&(r+="m"),t.ignoreCase&&(r+="i"),t.sticky&&(r+="y"),t.unicode&&(r+="u"),new RegExp(e,r)}function i(t,e){if(!e||"object"!=typeof e||e instanceof Error||e instanceof ArrayBuffer)return e;if(g.Array(e)){if(t){var r,n,i=[];for(r=0,n=e.length;n>r;r++)i.push(m(e[r]));return i}return e.slice(0)}if(g.Date(e))return new Date(e.getTime());if(e instanceof RegExp)return o(e);if(g.Object(e)){var s,a={};e.constructor&&e.constructor!==Object&&(a=Object.create(e.constructor.prototype));for(s in e)e.hasOwnProperty(s)&&(a[s]=t?m(e[s]):e[s]);return a}return e}function s(t,e){return function(r){return e(t(r))}}function a(t,e){var r,n;for(r=0,n=t.length;n>r;r++)if(e(t[r]))return t[r]}function u(t,e){var r,n;for(r=0,n=t.length;n>r;r++)if(e(t[r]))return r;return-1}function h(t,e){var r,n=!0;if(!t)return!1;for(r in e)if(g.Object(e[r]))n=n&&h(t[r],e[r]);else if(g.Array(e[r]))n=n&&!!~e[r].indexOf(t[r]);else if(t[r]!==e[r])return!1;return n}function c(t,e){return a(t,function(t){return h(t,e)})}function l(t,e){return u(t,function(t){return h(t,e)})}function f(t,e){e=e||[];var r,n,o=t;for(r=0,n=e.length;n>r;r++){if(!o)return;if("function"==typeof e[r]){if(!g.Array(o))return;o=a(o,e[r])}else if("object"==typeof e[r]){if(!g.Array(o))return;o=c(o,e[r])}else o=o[e[r]]}return o}function p(t,e){var r,n,o,i=[],s=t;for(n=0,o=e.length;o>n;n++){if(!s)return null;if("function"==typeof e[n]){if(!g.Array(s))return;r=u(s,e[n]),i.push(r),s=s[r]}else if("object"==typeof e[n]){if(!g.Array(s))return;r=l(s,e[n]),i.push(r),s=s[r]}else i.push(e[n]),s=s[e[n]]||{}}return i}function d(t,e){var r,n=t.length,o={},i=o;for(n||(o=e),r=0;n>r;r++)i[t[r]]=r+1===n?e:{},i=i[t[r]];return o}function y(t,e){t.super_=e;var r=function(){};r.prototype=e.prototype,t.prototype=new r,t.prototype.constructor=t}var g=t("./type.js"),b=i.bind(null,!1),m=i.bind(null,!0);e.exports={arrayOf:r,deepClone:m,shallowClone:b,shallowMerge:n,compose:s,getIn:f,inherits:y,pathObject:d,solvePath:p}},{"./type.js":10}],8:[function(t,e){function r(t,e){return e in(t||{})}function n(t,e,n){return r(t,n)&&r(e,n)}function o(){var t,e,r,a,u={},h=arguments.length;for(r=h-1;r>=0;r--){if(arguments[r].$unset)delete u.$set,delete u.$apply,delete u.$merge,u.$unset=arguments[r].$unset;else{if(arguments[r].$set){delete u.$apply,delete u.$merge,delete u.$unset,u.$set=arguments[r].$set;continue}if(arguments[r].$merge){delete u.$set,delete u.$apply,delete u.$unset,u.$merge=arguments[r].$merge;continue}if(arguments[r].$apply){delete u.$set,delete u.$merge,delete u.$unset,u.$apply=arguments[r].$apply;continue}if(arguments[r].$chain){delete u.$set,delete u.$merge,delete u.$unset,u.$apply=u.$apply?i.compose(u.$apply,arguments[r].$chain):arguments[r].$chain;continue}}for(a in arguments[r])t=u[a],e=arguments[r][a],t&&s.Object(e)?n(t,e,"$push")?t.$push=s.Array(t.$push)?t.$push.concat(e.$push):[t.$push].concat(e.$push):n(t,e,"$unshift")?t.$unshift=s.Array(e.$unshift)?e.$unshift.concat(t.$unshift):[e.$unshift].concat(t.$unshift):u[a]=o(e,t):u[a]=e}return u}var i=t("./helpers.js"),s=t("./type.js");e.exports=o},{"./helpers.js":7,"./type.js":10}],9:[function(t,e){var r=t("./combination.js"),n=t("./type.js");e.exports={baobab:function(t){return{mixins:[{getInitialState:function(){if(this.tree=t,!this.cursor&&!this.cursors)return{};if(this.cursor&&this.cursors)throw Error("baobab.mixin: you cannot have both `component.cursor` and `component.cursors`. Please make up your mind.");if(this.__type=null,this.__updateHandler=function(){this.setState(this.__getCursorData())}.bind(this),this.cursor){if(!n.MixinCursor(this.cursor))throw Error("baobab.mixin.cursor: invalid data (cursor, string, array or function).");n.Function(this.cursor)&&(this.cursor=this.cursor()),n.Cursor(this.cursor)||(this.cursor=t.select(this.cursor)),this.__getCursorData=function(){return{cursor:this.cursor.get()}}.bind(this),this.__type="single"}else if(this.cursors){if(!n.MixinCursors(this.cursors))throw Error("baobab.mixin.cursor: invalid data (object, array or function).");if(n.Function(this.cursors)&&(this.cursors=this.cursors()),n.Array(this.cursors))this.cursors=this.cursors.map(function(e){return n.Cursor(e)?e:t.select(e)}),this.__getCursorData=function(){return{cursors:this.cursors.map(function(t){return t.get()})}}.bind(this),this.__type="array";else{for(var e in this.cursors)n.Cursor(this.cursors[e])||(this.cursors[e]=t.select(this.cursors[e]));this.__getCursorData=function(){var t={};for(e in this.cursors)t[e]=this.cursors[e].get();return{cursors:t}}.bind(this),this.__type="object"}}return this.__getCursorData()},componentDidMount:function(){"single"===this.__type?(this.__combination=new r("or",[this.cursor]),this.__combination.on("update",this.__updateHandler)):"array"===this.__type?(this.__combination=new r("or",this.cursors),this.__combination.on("update",this.__updateHandler)):"object"===this.__type&&(this.__combination=new r("or",Object.keys(this.cursors).map(function(t){return this.cursors[t]},this)),this.__combination.on("update",this.__updateHandler))},componentWillUnmount:function(){this.__combination&&this.__combination.release()}}].concat(t.options.mixins)}},cursor:function(t){return{mixins:[{getInitialState:function(){return this.cursor=t,this.__updateHandler=function(){this.setState({cursor:this.cursor.get()})}.bind(this),{cursor:this.cursor.get()}},componentDidMount:function(){this.cursor.on("update",this.__updateHandler)},componentWillUnmount:function(){this.cursor.off("update",this.__updateHandler)}}].concat(t.tree.options.mixins)}}}},{"./combination.js":5,"./type.js":10}],10:[function(t,e){var r=function(t){return Array.isArray(t)?"array":"object"==typeof t&&null!==t?"object":"string"==typeof t?"string":"number"==typeof t?"number":"boolean"==typeof t?"boolean":"function"==typeof t?"function":null===t?"null":void 0===t?"undefined":t instanceof Date?"date":"invalid"};r.Array=function(t){return Array.isArray(t)},r.Object=function(t){return!Array.isArray(t)&&"object"==typeof t&&null!==t},r.String=function(t){return"string"==typeof t},r.Number=function(t){return"number"==typeof t},r.Boolean=function(t){return"boolean"==typeof t},r.Function=function(t){return"function"==typeof t},r.Primitive=function(t){return"string"==typeof t||"number"==typeof t||"boolean"==typeof t},r.Date=function(t){return t instanceof Date},r.Step=function(t){var e=r(t),n=["null","undefined","invalid","date"];return-1===n.indexOf(e)},r.Path=function(t){var e=["object","string","number","function","undefined"];if(!r.Array(t))return e.indexOf(r(t))>=0;for(var n=0;n=0||r.Cursor(t)},r.MixinCursors=function(t){var e=["array","object","function"];return e.indexOf(r(t))>=0},r.ComplexPath=function(t){for(var e=["object","function"],n=0;n=0)return!0;return!1},e.exports=r},{}],11:[function(t,e){function r(t,e){var r=new Error("baobab.update: "+e+" at path /"+t.toString());return r.path=t,r}function n(t,e,n){n=n||{shiftReferences:!1};var a={};return function u(t,e,h,c){h=h||[];var l,f,p,d,y=h.join("λ");for(p in e)if(s[p])switch(d=e[p],a[y]=!0,p){case"$push":if(!i.Array(t))throw r(h,"using command $push to a non array");i.Array(d)?t.push.apply(t,d):t.push(d);break;case"$unshift":if(!i.Array(t))throw r(h,"using command $unshift to a non array");i.Array(d)?t.unshift.apply(t,d):t.unshift(d)}else if(f=y?y+"λ"+p:p,"$unset"in(e[p]||{}))a[f]=!0,i.Array(t)?n.shiftReferences?c[h[h.length-1]]=t.slice(0,+p).concat(t.slice(+p+1)):t.splice(p,1):delete t[p];else if("$set"in(e[p]||{}))d=e[p].$set,a[f]=!0,t[p]=d;else if("$apply"in(e[p]||{})||"$chain"in(e[p]||{})){if(l=e[p].$apply||e[p].$chain,"function"!=typeof l)throw r(h.concat(p),"using command $apply with a non function");a[f]=!0,t[p]=l.call(null,t[p])}else if("$merge"in(e[p]||{})){if(d=e[p].$merge,!i.Object(t[p]))throw r(h.concat(p),"using command $merge on a non-object");a[f]=!0,t[p]=o.shallowMerge(t[p],d)}else if(n.shiftReferences&&("$push"in(e[p]||{})||"$unshift"in(e[p]||{}))){if("$push"in(e[p]||{})){if(d=e[p].$push,!i.Array(t[p]))throw r(h.concat(p),"using command $push to a non array");t[p]=t[p].concat(d)}if("$unshift"in(e[p]||{})){if(d=e[p].$unshift,!i.Array(t[p]))throw r(h.concat(p),"using command $unshift to a non array");t[p]=(d instanceof Array?d:[d]).concat(t[p])}a[f]=!0}else"undefined"==typeof t[p]&&(t[p]={}),n.shiftReferences&&(t[p]=o.shallowClone(t[p])),u(t[p],e[p],h.concat(p),t)}(t,e),Object.keys(a).map(function(t){return t.split("λ")})}var o=t("./helpers.js"),i=t("./type.js"),s={};["$set","$push","$unshift","$apply","$merge"].forEach(function(t){s[t]=!0}),e.exports=n},{"./helpers.js":7,"./type.js":10}]},{},[2])(2)}); \ No newline at end of file +!function(t){if("object"==typeof exports&&"undefined"!=typeof module)module.exports=t();else if("function"==typeof define&&define.amd)define([],t);else{var e;e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:this,e.Baobab=t()}}(function(){var t;return function e(t,r,n){function o(s,a){if(!r[s]){if(!t[s]){var u="function"==typeof require&&require;if(!a&&u)return u(s,!0);if(i)return i(s,!0);var h=new Error("Cannot find module '"+s+"'");throw h.code="MODULE_NOT_FOUND",h}var c=r[s]={exports:{}};t[s][0].call(c.exports,function(e){var r=t[s][1][e];return o(r?r:e)},c,c.exports,e,t,r,n)}return r[s].exports}for(var i="function"==typeof require&&require,s=0;se;e++)n.push(t[e].handler);return n}var o={once:"boolean",scope:"object"},i=function(){this._enabled=!0,this._children=[],this._handlers={},this._handlersAll=[]};i.prototype.on=function(t,e,r){var n,s,a,u,h,c;if("function"==typeof e){for(h="string"==typeof t?[t]:t,n=0,s=h.length;n!==s;n+=1)if(u=h[n]){this._handlers[u]||(this._handlers[u]=[]),c={handler:e};for(a in r||{}){if(!o[a])throw new Error('The option "'+a+'" is not recognized by Emmett.');c[a]=r[a]}this._handlers[u].push(c)}}else if(t&&"object"==typeof t&&!Array.isArray(t))for(u in t)i.prototype.on.call(this,u,t[u],e);else{if("function"!=typeof t)throw new Error("Wrong arguments.");c={handler:t};for(a in r||{}){if(!o[a])throw new Error('The option "'+a+'" is not recognized by Emmett.');c[a]=r[a]}this._handlersAll.push(c)}return this},i.prototype.once=function(t,e,r){if("function"==typeof e)r=r||{},r.once=!0,this.on(t,e,r);else{if((!t||"object"!=typeof t||Array.isArray(t))&&"function"!=typeof t)throw new Error("Wrong arguments.");e=e||{},e.once=!0,this.on(t,e)}return this},i.prototype.off=function(t,e){var r,n,o,i,s,a,u,h="string"==typeof t?[t]:t;if(1===arguments.length&&"function"==typeof h){e=arguments[0];for(s in this._handlers){for(a=[],r=0,n=this._handlers[s].length;r!==n;r+=1)this._handlers[s][r].handler!==e&&a.push(this._handlers[s][r]);this._handlers[s]=a}for(a=[],r=0,n=this._handlersAll.length;r!==n;r+=1)this._handlersAll[r].handler!==e&&a.push(this._handlersAll[r]);this._handlersAll=a}else if(2===arguments.length)for(r=0,n=h.length;r!==n;r+=1){if(u=h[r],this._handlers[u]){for(a=[],o=0,i=this._handlers[u].length;o!==i;o+=1)this._handlers[u][o].handler!==e&&a.push(this._handlers[u][o]);this._handlers[u]=a}this._handlers[u]&&0===this._handlers[u].length&&delete this._handlers[u]}return this},i.prototype.unbindAll=function(){var t;this._handlersAll=[];for(t in this._handlers)delete this._handlers[t];return this},i.prototype.emit=function(t,e){var r,n,o,i,s,a,u,h,c,l,f="string"==typeof t?[t]:t;if(!this._enabled)return this;for(e=void 0===e?{}:e,r=0,n=f.length;r!==n;r+=1)if(l=f[r],c=(this._handlers[l]||[]).concat(this._handlersAll),c.length){for(u={type:l,data:e||{},target:this},a=[],o=0,i=c.length;o!==i;o+=1)(this._handlers[l]&&this._handlers[l].indexOf(c[o])>=0||this._handlersAll.indexOf(c[o])>=0)&&(c[o].handler.call("scope"in c[o]?c[o].scope:this,u),c[o].once&&a.push(c[o]));for(s=0;sr;r++)if(t._children[r]===e){t._children.splice(r,1);break}}),this._children.push(e),e},i.prototype.listeners=function(t){var r,n,o,i=[];if(t)for(i=e(this._handlers[t]),n=0,o=this._children.length;o>n;n++)i=i.concat(this._children[n].listeners(t));else{i=e(this._handlersAll);for(r in this._handlers)i=i.concat(e(this._handlers[r]));for(n=0,o=this._children.length;o>n;n++)i=i.concat(this._children[n].listeners())}return i},i.prototype.kill=function(){if(this.emit("emmett:kill"),this.unbindAll(),this._handlers=null,this._handlersAll=null,this._enabled=!1,this._children)for(var t=0,e=this._children.length;e>t;t++)this._children[t].kill();this._children=null},i.prototype.disable=function(){return this._enabled=!1,this},i.prototype.enable=function(){return this._enabled=!0,this},i.version="2.1.2","undefined"!=typeof n?("undefined"!=typeof r&&r.exports&&(n=r.exports=i),n.Emitter=i):"function"==typeof t&&t.amd?t("emmett",[],function(){return i}):this.Emitter=i}).call(this)},{}],4:[function(t,e){function r(t){return t+"$"+(new Date).getTime()+(""+Math.random()).replace("0.","")}function n(t,e){if(arguments.length<1&&(t={}),!(this instanceof n))return new n(t,e);if(!l.Object(t)&&!l.Array(t))throw Error("Baobab: invalid data.");i.call(this),this.options=s.shallowMerge(c,e),this._transaction={},this._future=void 0,this._cursors={},this.data=s.deepClone(t),this.mixin=h.baobab(this)}var o=t("./cursor.js"),i=t("emmett"),s=t("./helpers.js"),a=t("./update.js"),u=t("./merge.js"),h=t("./mixins.js"),c=t("../defaults.js"),l=t("./type.js");s.inherits(n,i),n.prototype.commit=function(){this.options.shiftReferences&&(this.data=s.shallowClone(this.data));var t=a(this.data,this._transaction,this.options);return this._transaction={},this._future&&(this._future=clearTimeout(this._future)),this.emit("update",{log:t}),this},n.prototype.select=function(t){if(!t)throw Error("Baobab.select: invalid path.");if(arguments.length>1&&(t=s.arrayOf(arguments)),!l.Path(t))throw Error("Baobab.select: invalid path.");t=l.Array(t)?t:[t];var e,n=l.ComplexPath(t);n&&(e=s.solvePath(this.data,t));var i=t.map(function(t){return l.Function(t)?r("fn"):l.Object(t)?r("ob"):t}).join("λ");if(this._cursors[i])return this._cursors[i];var a=new o(this,t,e,i);return this._cursors[i]=a,a},n.prototype.root=function(){return this.select([])},n.prototype.get=function(t){if(arguments.length>1&&(t=s.arrayOf(arguments)),!l.Path(t))throw Error("Baobab.get: invalid path.");return s.getIn(this.data,l.String(t)||l.Number(t)?[t]:t)},n.prototype.set=function(t,e){if(arguments.length<2)throw Error("Baobab.set: expects a key and a value.");var r={};if(l.Array(t)){var n=s.solvePath(this.data,t);if(!n)throw Error("Baobab.set: could not solve dynamic path.");r=s.pathObject(n,{$set:e})}else r[t]={$set:e};return this.update(r)},n.prototype.unset=function(t){if(!t&&0!==t)throw Error("Baobab.unset: expects a valid key to unset.");var e={};return e[t]={$unset:!0},this.update(e)},n.prototype.update=function(t){var e=this;if(!l.Object(t))throw Error("Baobab.update: wrong specification.");return this._transaction=u(t,this._transaction),this.options.autoCommit?this.options.asynchronous?(this._future||(this._future=setTimeout(e.commit.bind(e,null),0)),this):this.commit():this},n.prototype.release=function(){delete this.data,delete this._transaction;for(var t in this._cursors)this._cursors[t].release();delete this._cursors,this.kill()},n.prototype.toJSON=function(){return this.get()},e.exports=n},{"../defaults.js":1,"./cursor.js":6,"./helpers.js":7,"./merge.js":8,"./mixins.js":9,"./type.js":10,"./update.js":11,emmett:3}],5:[function(t,e){function r(t,e){e.on("update",t.cursorListener),t.tree.off("update",t.treeListener),t.tree.on("update",t.treeListener)}function n(t){var e=this;if(arguments.length<2)throw Error("baobab.Combination: not enough arguments.");var n=arguments[1],o=s.arrayOf(arguments).slice(2);if(n instanceof Array&&(o=n.slice(1),n=n[0]),!a.Cursor(n))throw Error("baobab.Combination: argument should be a cursor.");if("or"!==t&&"and"!==t)throw Error("baobab.Combination: invalid operator.");i.call(this),this.cursors=[n],this.operators=[],this.tree=n.tree,this.updates=new Array(this.cursors.length),this.cursorListener=function(){e.updates[e.cursors.indexOf(this)]=!0},this.treeListener=function(){var t,r,n=e.updates[0];for(t=1,r=e.cursors.length;r>t;t++)n="or"===e.operators[t-1]?n||e.updates[t]:n&&e.updates[t];n&&e.emit("update"),e.updates=new Array(e.cursors.length)},this.bound=!1;var u=this.on,h=this.once,c=function(){e.bound||(e.bound=!0,e.cursors.forEach(function(t){r(e,t)}))};this.on=function(){return c(),u.apply(this,arguments)},this.once=function(){return c(),h.apply(this,arguments)},o.forEach(function(e){this[t](e)},this)}function o(t){n.prototype[t]=function(e){if(!a.Cursor(e))throw this.release(),Error("baobab.Combination."+t+": argument should be a cursor.");if(~this.cursors.indexOf(e))throw this.release(),Error("baobab.Combination."+t+": cursor already in combination.");return this.cursors.push(e),this.operators.push(t),this.updates.length++,this.bound&&r(this,e),this}}var i=t("emmett"),s=t("./helpers.js"),a=t("./type.js");s.inherits(n,i),o("or"),o("and"),n.prototype.release=function(){this.cursors.forEach(function(t){t.off("update",this.cursorListener)},this),this.tree.off("update",this.treeListener),this.cursors=null,this.operators=null,this.tree=null,this.updates=null,this.kill()},e.exports=n},{"./helpers.js":7,"./type.js":10,emmett:3}],6:[function(t,e){function r(t,e,r,o){var a=this;n.call(this),e=e||[],this.tree=t,this.path=e,this.hash=o,this.relevant=void 0!==this.get(),this.complexPath=!!r,this.solvedPath=this.complexPath?r:this.path,this.updateHandler=function(t){var e,r,n,o,i,u,h=t.data.log,c=!1;if(a.complexPath&&(a.solvedPath=s.solvePath(a.tree.data,a.path)),!a.path.length)return a.emit("update");t:for(i=0,n=h.length;n>i;i++)for(e=h[i],u=0,o=e.length;o>u&&(r=e[u],r===""+a.solvedPath[u]);u++)if(u+1===o||u+1===a.solvedPath.length){c=!0;break t}var l=void 0!==a.get();a.relevant?l&&c?a.emit("update"):l||(a.emit("irrelevant"),a.relevant=!1):l&&c&&(a.emit("relevant"),a.emit("update"),a.relevant=!0)},this.mixin=i.cursor(this);var u=!1,h=this.on,c=this.once,l=function(){u||(u=!0,a.tree.on("update",a.updateHandler))};this.on=function(){return l(),h.apply(this,arguments)},this.once=function(){return l(),c.apply(this,arguments)}}var n=t("emmett"),o=t("./combination.js"),i=t("./mixins.js"),s=t("./helpers.js"),a=t("./type.js");s.inherits(r,n),r.prototype.isRoot=function(){return!this.path.length},r.prototype.isLeaf=function(){return a.Primitive(this.get())},r.prototype.isBranch=function(){return!this.isLeaf()&&!this.isRoot()},r.prototype.root=function(){return this.tree.root()},r.prototype.select=function(t){if(arguments.length>1&&(t=s.arrayOf(arguments)),!a.Path(t))throw Error("baobab.Cursor.select: invalid path.");return this.tree.select(this.path.concat(t))},r.prototype.up=function(){return this.solvedPath&&this.solvedPath.length?this.tree.select(this.path.slice(0,-1)):null},r.prototype.left=function(){var t=+this.solvedPath[this.solvedPath.length-1];if(isNaN(t))throw Error("baobab.Cursor.left: cannot go left on a non-list type.");return t?this.tree.select(this.solvedPath.slice(0,-1).concat(t-1)):null},r.prototype.leftmost=function(){var t=+this.solvedPath[this.solvedPath.length-1];if(isNaN(t))throw Error("baobab.Cursor.leftmost: cannot go left on a non-list type.");return this.tree.select(this.solvedPath.slice(0,-1).concat(0))},r.prototype.right=function(){var t=+this.solvedPath[this.solvedPath.length-1];if(isNaN(t))throw Error("baobab.Cursor.right: cannot go right on a non-list type.");return t+1===this.up().get().length?null:this.tree.select(this.solvedPath.slice(0,-1).concat(t+1))},r.prototype.rightmost=function(){var t=+this.solvedPath[this.solvedPath.length-1];if(isNaN(t))throw Error("baobab.Cursor.right: cannot go right on a non-list type.");var e=this.up().get();return this.tree.select(this.solvedPath.slice(0,-1).concat(e.length-1))},r.prototype.down=function(){+this.solvedPath[this.solvedPath.length-1];return this.get()instanceof Array?this.tree.select(this.solvedPath.concat(0)):null},r.prototype.get=function(t){return arguments.length>1&&(t=s.arrayOf(arguments)),this.tree.get(a.Step(t)?this.solvedPath.concat(t):this.solvedPath)},r.prototype.set=function(t,e){if(arguments.length<2)throw Error("baobab.Cursor.set: expecting at least key/value.");var r=this.get();if("object"!=typeof r)throw Error("baobab.Cursor.set: trying to set key to a non-object.");var n={};if(a.Array(t)){var o=s.solvePath(r,t);if(!o)throw Error("baobab.Cursor.set: could not solve dynamic path.");n=s.pathObject(o,{$set:e})}else n[t]={$set:e};return this.update(n)},r.prototype.edit=function(t){return this.update({$set:t})},r.prototype.unset=function(t){if(!t&&0!==t)throw Error("baobab.Cursor.unset: expects a valid key to unset.");if("object"!=typeof this.get())throw Error("baobab.Cursor.set: trying to set key to a non-object.");var e={};return e[t]={$unset:!0},this.update(e)},r.prototype.remove=function(){if(this.isRoot())throw Error("baobab.Cursor.remove: cannot remove root node.");return this.update({$unset:!0})},r.prototype.apply=function(t){if("function"!=typeof t)throw Error("baobab.Cursor.apply: argument is not a function.");return this.update({$apply:t})},r.prototype.chain=function(t){if("function"!=typeof t)throw Error("baobab.Cursor.chain: argument is not a function.");return this.update({$chain:t})},r.prototype.push=function(t){if(!(this.get()instanceof Array))throw Error("baobab.Cursor.push: trying to push to non-array value.");return this.update(arguments.length>1?{$push:s.arrayOf(arguments)}:{$push:t})},r.prototype.unshift=function(t){if(!(this.get()instanceof Array))throw Error("baobab.Cursor.push: trying to push to non-array value.");return this.update(arguments.length>1?{$unshift:s.arrayOf(arguments)}:{$unshift:t})},r.prototype.merge=function(t){if(!a.Object(t))throw Error("baobab.Cursor.merge: trying to merge a non-object.");if(!a.Object(this.get()))throw Error("baobab.Cursor.merge: trying to merge into a non-object.");this.update({$merge:t})},r.prototype.update=function(t){return this.tree.update(s.pathObject(this.solvedPath,t)),this},r.prototype.or=function(t){return new o("or",this,t)},r.prototype.and=function(t){return new o("and",this,t)},r.prototype.release=function(){this.tree.off("update",this.updateHandler),this.hash&&delete this.tree._cursors[this.hash],delete this.tree,delete this.path,delete this.solvedPath,this.kill()},r.prototype.toJSON=function(){return this.get()},a.Cursor=function(t){return t instanceof r},e.exports=r},{"./combination.js":5,"./helpers.js":7,"./mixins.js":9,"./type.js":10,emmett:3}],7:[function(t,e){function r(t){return Array.prototype.slice.call(t)}function n(t,e){var r,n={};for(r in t)n[r]=t[r];for(r in e)n[r]=e[r];return n}function o(t){var e=t.source,r="";return t.global&&(r+="g"),t.multiline&&(r+="m"),t.ignoreCase&&(r+="i"),t.sticky&&(r+="y"),t.unicode&&(r+="u"),new RegExp(e,r)}function i(t,e){if(!e||"object"!=typeof e||e instanceof Error||e instanceof ArrayBuffer)return e;if(g.Array(e)){if(t){var r,n,i=[];for(r=0,n=e.length;n>r;r++)i.push(m(e[r]));return i}return e.slice(0)}if(g.Date(e))return new Date(e.getTime());if(e instanceof RegExp)return o(e);if(g.Object(e)){var s,a={};e.constructor&&e.constructor!==Object&&(a=Object.create(e.constructor.prototype));for(s in e)e.hasOwnProperty(s)&&(a[s]=t?m(e[s]):e[s]);return a}return e}function s(t,e){return function(r){return e(t(r))}}function a(t,e){var r,n;for(r=0,n=t.length;n>r;r++)if(e(t[r]))return t[r]}function u(t,e){var r,n;for(r=0,n=t.length;n>r;r++)if(e(t[r]))return r;return-1}function h(t,e){var r,n=!0;if(!t)return!1;for(r in e)if(g.Object(e[r]))n=n&&h(t[r],e[r]);else if(g.Array(e[r]))n=n&&!!~e[r].indexOf(t[r]);else if(t[r]!==e[r])return!1;return n}function c(t,e){return a(t,function(t){return h(t,e)})}function l(t,e){return u(t,function(t){return h(t,e)})}function f(t,e){e=e||[];var r,n,o=t;for(r=0,n=e.length;n>r;r++){if(!o)return;if("function"==typeof e[r]){if(!g.Array(o))return;o=a(o,e[r])}else if("object"==typeof e[r]){if(!g.Array(o))return;o=c(o,e[r])}else o=o[e[r]]}return o}function p(t,e){var r,n,o,i=[],s=t;for(n=0,o=e.length;o>n;n++){if(!s)return null;if("function"==typeof e[n]){if(!g.Array(s))return;r=u(s,e[n]),i.push(r),s=s[r]}else if("object"==typeof e[n]){if(!g.Array(s))return;r=l(s,e[n]),i.push(r),s=s[r]}else i.push(e[n]),s=s[e[n]]||{}}return i}function d(t,e){var r,n=t.length,o={},i=o;for(n||(o=e),r=0;n>r;r++)i[t[r]]=r+1===n?e:{},i=i[t[r]];return o}function y(t,e){t.super_=e;var r=function(){};r.prototype=e.prototype,t.prototype=new r,t.prototype.constructor=t}var g=t("./type.js"),b=i.bind(null,!1),m=i.bind(null,!0);e.exports={arrayOf:r,deepClone:m,shallowClone:b,shallowMerge:n,compose:s,getIn:f,inherits:y,pathObject:d,solvePath:p}},{"./type.js":10}],8:[function(t,e){function r(t,e){return e in(t||{})}function n(t,e,n){return r(t,n)&&r(e,n)}function o(){var t,e,r,a,u={},h=arguments.length;for(r=h-1;r>=0;r--){if(arguments[r].$unset)delete u.$set,delete u.$apply,delete u.$merge,u.$unset=arguments[r].$unset;else{if(arguments[r].$set){delete u.$apply,delete u.$merge,delete u.$unset,u.$set=arguments[r].$set;continue}if(arguments[r].$merge){delete u.$set,delete u.$apply,delete u.$unset,u.$merge=arguments[r].$merge;continue}if(arguments[r].$apply){delete u.$set,delete u.$merge,delete u.$unset,u.$apply=arguments[r].$apply;continue}if(arguments[r].$chain){delete u.$set,delete u.$merge,delete u.$unset,u.$apply=u.$apply?i.compose(u.$apply,arguments[r].$chain):arguments[r].$chain;continue}}for(a in arguments[r])t=u[a],e=arguments[r][a],t&&s.Object(e)?n(t,e,"$push")?t.$push=s.Array(t.$push)?t.$push.concat(e.$push):[t.$push].concat(e.$push):n(t,e,"$unshift")?t.$unshift=s.Array(e.$unshift)?e.$unshift.concat(t.$unshift):[e.$unshift].concat(t.$unshift):u[a]=o(e,t):u[a]=e}return u}var i=t("./helpers.js"),s=t("./type.js");e.exports=o},{"./helpers.js":7,"./type.js":10}],9:[function(t,e){var r=t("./combination.js"),n=t("./type.js");e.exports={baobab:function(t){return{mixins:[{getInitialState:function(){if(this.tree=t,!this.cursor&&!this.cursors)return{};if(this.cursor&&this.cursors)throw Error("baobab.mixin: you cannot have both `component.cursor` and `component.cursors`. Please make up your mind.");if(this.__type=null,this.__updateHandler=function(){this.setState(this.__getCursorData())}.bind(this),this.cursor){if(!n.MixinCursor(this.cursor))throw Error("baobab.mixin.cursor: invalid data (cursor, string, array or function).");n.Function(this.cursor)&&(this.cursor=this.cursor()),n.Cursor(this.cursor)||(this.cursor=t.select(this.cursor)),this.__getCursorData=function(){return{cursor:this.cursor.get()}}.bind(this),this.__type="single"}else if(this.cursors){if(!n.MixinCursors(this.cursors))throw Error("baobab.mixin.cursor: invalid data (object, array or function).");if(n.Function(this.cursors)&&(this.cursors=this.cursors()),n.Array(this.cursors))this.cursors=this.cursors.map(function(e){return n.Cursor(e)?e:t.select(e)}),this.__getCursorData=function(){return{cursors:this.cursors.map(function(t){return t.get()})}}.bind(this),this.__type="array";else{for(var e in this.cursors)n.Cursor(this.cursors[e])||(this.cursors[e]=t.select(this.cursors[e]));this.__getCursorData=function(){var t={};for(e in this.cursors)t[e]=this.cursors[e].get();return{cursors:t}}.bind(this),this.__type="object"}}return this.__getCursorData()},componentDidMount:function(){"single"===this.__type?(this.__combination=new r("or",[this.cursor]),this.__combination.on("update",this.__updateHandler)):"array"===this.__type?(this.__combination=new r("or",this.cursors),this.__combination.on("update",this.__updateHandler)):"object"===this.__type&&(this.__combination=new r("or",Object.keys(this.cursors).map(function(t){return this.cursors[t]},this)),this.__combination.on("update",this.__updateHandler))},componentWillUnmount:function(){this.__combination&&this.__combination.release()}}].concat(t.options.mixins)}},cursor:function(t){return{mixins:[{getInitialState:function(){return this.cursor=t,this.__updateHandler=function(){this.setState({cursor:this.cursor.get()})}.bind(this),{cursor:this.cursor.get()}},componentDidMount:function(){this.cursor.on("update",this.__updateHandler)},componentWillUnmount:function(){this.cursor.off("update",this.__updateHandler)}}].concat(t.tree.options.mixins)}}}},{"./combination.js":5,"./type.js":10}],10:[function(t,e){var r=function(t){return Array.isArray(t)?"array":"object"==typeof t&&null!==t?"object":"string"==typeof t?"string":"number"==typeof t?"number":"boolean"==typeof t?"boolean":"function"==typeof t?"function":null===t?"null":void 0===t?"undefined":t instanceof Date?"date":"invalid"};r.Array=function(t){return Array.isArray(t)},r.Object=function(t){return!Array.isArray(t)&&"object"==typeof t&&null!==t},r.String=function(t){return"string"==typeof t},r.Number=function(t){return"number"==typeof t},r.Boolean=function(t){return"boolean"==typeof t},r.Function=function(t){return"function"==typeof t},r.Primitive=function(t){return"string"==typeof t||"number"==typeof t||"boolean"==typeof t},r.Date=function(t){return t instanceof Date},r.Step=function(t){var e=r(t),n=["null","undefined","invalid","date"];return-1===n.indexOf(e)},r.Path=function(t){var e=["object","string","number","function","undefined"];if(!r.Array(t))return e.indexOf(r(t))>=0;for(var n=0;n=0||r.Cursor(t)},r.MixinCursors=function(t){var e=["array","object","function"];return e.indexOf(r(t))>=0},r.ComplexPath=function(t){for(var e=["object","function"],n=0;n=0)return!0;return!1},e.exports=r},{}],11:[function(t,e){function r(t,e){var r=new Error("baobab.update: "+e+" at path /"+t.toString());return r.path=t,r}function n(t,e,n){n=n||{shiftReferences:!1};var a={};return function u(t,e,h,c){h=h||[];var l,f,p,d,y=h.join("λ");for(p in e)if(s[p])switch(d=e[p],a[y]=!0,p){case"$push":if(!i.Array(t))throw r(h,"using command $push to a non array");i.Array(d)?t.push.apply(t,d):t.push(d);break;case"$unshift":if(!i.Array(t))throw r(h,"using command $unshift to a non array");i.Array(d)?t.unshift.apply(t,d):t.unshift(d)}else if(f=y?y+"λ"+p:p,"$unset"in(e[p]||{}))a[f]=!0,i.Array(t)?n.shiftReferences?c[h[h.length-1]]=t.slice(0,+p).concat(t.slice(+p+1)):t.splice(p,1):delete t[p];else if("$set"in(e[p]||{}))d=e[p].$set,a[f]=!0,t[p]=d;else if("$apply"in(e[p]||{})||"$chain"in(e[p]||{})){if(l=e[p].$apply||e[p].$chain,"function"!=typeof l)throw r(h.concat(p),"using command $apply with a non function");a[f]=!0,t[p]=l.call(null,t[p])}else if("$merge"in(e[p]||{})){if(d=e[p].$merge,!i.Object(t[p]))throw r(h.concat(p),"using command $merge on a non-object");a[f]=!0,t[p]=o.shallowMerge(t[p],d)}else if(n.shiftReferences&&("$push"in(e[p]||{})||"$unshift"in(e[p]||{}))){if("$push"in(e[p]||{})){if(d=e[p].$push,!i.Array(t[p]))throw r(h.concat(p),"using command $push to a non array");t[p]=t[p].concat(d)}if("$unshift"in(e[p]||{})){if(d=e[p].$unshift,!i.Array(t[p]))throw r(h.concat(p),"using command $unshift to a non array");t[p]=(d instanceof Array?d:[d]).concat(t[p])}a[f]=!0}else"undefined"==typeof t[p]&&(t[p]={}),n.shiftReferences&&(t[p]=o.shallowClone(t[p])),u(t[p],e[p],h.concat(p),t)}(t,e),Object.keys(a).map(function(t){return t.split("λ")})}var o=t("./helpers.js"),i=t("./type.js"),s={};["$set","$push","$unshift","$apply","$merge"].forEach(function(t){s[t]=!0}),e.exports=n},{"./helpers.js":7,"./type.js":10}]},{},[2])(2)}); \ No newline at end of file diff --git a/src/baobab.js b/src/baobab.js index e825cd6..455092d 100644 --- a/src/baobab.js +++ b/src/baobab.js @@ -101,27 +101,22 @@ Baobab.prototype.select = function(path) { solvedPath = helpers.solvePath(this.data, path); // Registering a new cursor or giving the already existing one for path - if (!this.options.cursorSingletons) { - return new Cursor(this, path); + var hash = path.map(function(step) { + if (type.Function(step)) + return complexHash('fn'); + else if (type.Object(step)) + return complexHash('ob'); + else + return step; + }).join('λ'); + + if (!this._cursors[hash]) { + var cursor = new Cursor(this, path, solvedPath, hash); + this._cursors[hash] = cursor; + return cursor; } else { - var hash = path.map(function(step) { - if (type.Function(step)) - return complexHash('fn'); - else if (type.Object(step)) - return complexHash('ob'); - else - return step; - }).join('λ'); - - if (!this._cursors[hash]) { - var cursor = new Cursor(this, path, solvedPath, hash); - this._cursors[hash] = cursor; - return cursor; - } - else { - return this._cursors[hash]; - } + return this._cursors[hash]; } }; diff --git a/test/suites/baobab.js b/test/suites/baobab.js index 71a6066..95befc6 100644 --- a/test/suites/baobab.js +++ b/test/suites/baobab.js @@ -182,14 +182,6 @@ describe('Baobab API', function() { }, 0); }); - it('should be possible to shunt the singleton cursors.', function() { - var baobab1 = new Baobab({hello: 'world'}), - baobab2 = new Baobab({hello: 'world'}, {cursorSingletons: false}); - - assert(baobab1.select('hello') === baobab1.select('hello')); - assert(baobab2.select('hello') !== baobab2.select('hello')); - }); - it('should be possible to tell the tree to shift references on updates.', function() { var list = [1], baobab = new Baobab({list: list}, {shiftReferences: true, asynchronous: false}); From 27a49331737dc8917d57410c6c5f70278281d24a Mon Sep 17 00:00:00 2001 From: Yomguithereal Date: Fri, 27 Mar 2015 19:43:13 +0100 Subject: [PATCH 06/73] Cleaning defaults --- build/baobab.min.js | 2 +- defaults.js | 15 --------------- 2 files changed, 1 insertion(+), 16 deletions(-) diff --git a/build/baobab.min.js b/build/baobab.min.js index dcb6bd0..14fea95 100644 --- a/build/baobab.min.js +++ b/build/baobab.min.js @@ -1,2 +1,2 @@ /* baobab.js - Version: 0.4.3 - Author: Yomguithereal (Guillaume Plique) */ -!function(t){if("object"==typeof exports&&"undefined"!=typeof module)module.exports=t();else if("function"==typeof define&&define.amd)define([],t);else{var e;e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:this,e.Baobab=t()}}(function(){var t;return function e(t,r,n){function o(s,a){if(!r[s]){if(!t[s]){var u="function"==typeof require&&require;if(!a&&u)return u(s,!0);if(i)return i(s,!0);var h=new Error("Cannot find module '"+s+"'");throw h.code="MODULE_NOT_FOUND",h}var c=r[s]={exports:{}};t[s][0].call(c.exports,function(e){var r=t[s][1][e];return o(r?r:e)},c,c.exports,e,t,r,n)}return r[s].exports}for(var i="function"==typeof require&&require,s=0;se;e++)n.push(t[e].handler);return n}var o={once:"boolean",scope:"object"},i=function(){this._enabled=!0,this._children=[],this._handlers={},this._handlersAll=[]};i.prototype.on=function(t,e,r){var n,s,a,u,h,c;if("function"==typeof e){for(h="string"==typeof t?[t]:t,n=0,s=h.length;n!==s;n+=1)if(u=h[n]){this._handlers[u]||(this._handlers[u]=[]),c={handler:e};for(a in r||{}){if(!o[a])throw new Error('The option "'+a+'" is not recognized by Emmett.');c[a]=r[a]}this._handlers[u].push(c)}}else if(t&&"object"==typeof t&&!Array.isArray(t))for(u in t)i.prototype.on.call(this,u,t[u],e);else{if("function"!=typeof t)throw new Error("Wrong arguments.");c={handler:t};for(a in r||{}){if(!o[a])throw new Error('The option "'+a+'" is not recognized by Emmett.');c[a]=r[a]}this._handlersAll.push(c)}return this},i.prototype.once=function(t,e,r){if("function"==typeof e)r=r||{},r.once=!0,this.on(t,e,r);else{if((!t||"object"!=typeof t||Array.isArray(t))&&"function"!=typeof t)throw new Error("Wrong arguments.");e=e||{},e.once=!0,this.on(t,e)}return this},i.prototype.off=function(t,e){var r,n,o,i,s,a,u,h="string"==typeof t?[t]:t;if(1===arguments.length&&"function"==typeof h){e=arguments[0];for(s in this._handlers){for(a=[],r=0,n=this._handlers[s].length;r!==n;r+=1)this._handlers[s][r].handler!==e&&a.push(this._handlers[s][r]);this._handlers[s]=a}for(a=[],r=0,n=this._handlersAll.length;r!==n;r+=1)this._handlersAll[r].handler!==e&&a.push(this._handlersAll[r]);this._handlersAll=a}else if(2===arguments.length)for(r=0,n=h.length;r!==n;r+=1){if(u=h[r],this._handlers[u]){for(a=[],o=0,i=this._handlers[u].length;o!==i;o+=1)this._handlers[u][o].handler!==e&&a.push(this._handlers[u][o]);this._handlers[u]=a}this._handlers[u]&&0===this._handlers[u].length&&delete this._handlers[u]}return this},i.prototype.unbindAll=function(){var t;this._handlersAll=[];for(t in this._handlers)delete this._handlers[t];return this},i.prototype.emit=function(t,e){var r,n,o,i,s,a,u,h,c,l,f="string"==typeof t?[t]:t;if(!this._enabled)return this;for(e=void 0===e?{}:e,r=0,n=f.length;r!==n;r+=1)if(l=f[r],c=(this._handlers[l]||[]).concat(this._handlersAll),c.length){for(u={type:l,data:e||{},target:this},a=[],o=0,i=c.length;o!==i;o+=1)(this._handlers[l]&&this._handlers[l].indexOf(c[o])>=0||this._handlersAll.indexOf(c[o])>=0)&&(c[o].handler.call("scope"in c[o]?c[o].scope:this,u),c[o].once&&a.push(c[o]));for(s=0;sr;r++)if(t._children[r]===e){t._children.splice(r,1);break}}),this._children.push(e),e},i.prototype.listeners=function(t){var r,n,o,i=[];if(t)for(i=e(this._handlers[t]),n=0,o=this._children.length;o>n;n++)i=i.concat(this._children[n].listeners(t));else{i=e(this._handlersAll);for(r in this._handlers)i=i.concat(e(this._handlers[r]));for(n=0,o=this._children.length;o>n;n++)i=i.concat(this._children[n].listeners())}return i},i.prototype.kill=function(){if(this.emit("emmett:kill"),this.unbindAll(),this._handlers=null,this._handlersAll=null,this._enabled=!1,this._children)for(var t=0,e=this._children.length;e>t;t++)this._children[t].kill();this._children=null},i.prototype.disable=function(){return this._enabled=!1,this},i.prototype.enable=function(){return this._enabled=!0,this},i.version="2.1.2","undefined"!=typeof n?("undefined"!=typeof r&&r.exports&&(n=r.exports=i),n.Emitter=i):"function"==typeof t&&t.amd?t("emmett",[],function(){return i}):this.Emitter=i}).call(this)},{}],4:[function(t,e){function r(t){return t+"$"+(new Date).getTime()+(""+Math.random()).replace("0.","")}function n(t,e){if(arguments.length<1&&(t={}),!(this instanceof n))return new n(t,e);if(!l.Object(t)&&!l.Array(t))throw Error("Baobab: invalid data.");i.call(this),this.options=s.shallowMerge(c,e),this._transaction={},this._future=void 0,this._cursors={},this.data=s.deepClone(t),this.mixin=h.baobab(this)}var o=t("./cursor.js"),i=t("emmett"),s=t("./helpers.js"),a=t("./update.js"),u=t("./merge.js"),h=t("./mixins.js"),c=t("../defaults.js"),l=t("./type.js");s.inherits(n,i),n.prototype.commit=function(){this.options.shiftReferences&&(this.data=s.shallowClone(this.data));var t=a(this.data,this._transaction,this.options);return this._transaction={},this._future&&(this._future=clearTimeout(this._future)),this.emit("update",{log:t}),this},n.prototype.select=function(t){if(!t)throw Error("Baobab.select: invalid path.");if(arguments.length>1&&(t=s.arrayOf(arguments)),!l.Path(t))throw Error("Baobab.select: invalid path.");t=l.Array(t)?t:[t];var e,n=l.ComplexPath(t);n&&(e=s.solvePath(this.data,t));var i=t.map(function(t){return l.Function(t)?r("fn"):l.Object(t)?r("ob"):t}).join("λ");if(this._cursors[i])return this._cursors[i];var a=new o(this,t,e,i);return this._cursors[i]=a,a},n.prototype.root=function(){return this.select([])},n.prototype.get=function(t){if(arguments.length>1&&(t=s.arrayOf(arguments)),!l.Path(t))throw Error("Baobab.get: invalid path.");return s.getIn(this.data,l.String(t)||l.Number(t)?[t]:t)},n.prototype.set=function(t,e){if(arguments.length<2)throw Error("Baobab.set: expects a key and a value.");var r={};if(l.Array(t)){var n=s.solvePath(this.data,t);if(!n)throw Error("Baobab.set: could not solve dynamic path.");r=s.pathObject(n,{$set:e})}else r[t]={$set:e};return this.update(r)},n.prototype.unset=function(t){if(!t&&0!==t)throw Error("Baobab.unset: expects a valid key to unset.");var e={};return e[t]={$unset:!0},this.update(e)},n.prototype.update=function(t){var e=this;if(!l.Object(t))throw Error("Baobab.update: wrong specification.");return this._transaction=u(t,this._transaction),this.options.autoCommit?this.options.asynchronous?(this._future||(this._future=setTimeout(e.commit.bind(e,null),0)),this):this.commit():this},n.prototype.release=function(){delete this.data,delete this._transaction;for(var t in this._cursors)this._cursors[t].release();delete this._cursors,this.kill()},n.prototype.toJSON=function(){return this.get()},e.exports=n},{"../defaults.js":1,"./cursor.js":6,"./helpers.js":7,"./merge.js":8,"./mixins.js":9,"./type.js":10,"./update.js":11,emmett:3}],5:[function(t,e){function r(t,e){e.on("update",t.cursorListener),t.tree.off("update",t.treeListener),t.tree.on("update",t.treeListener)}function n(t){var e=this;if(arguments.length<2)throw Error("baobab.Combination: not enough arguments.");var n=arguments[1],o=s.arrayOf(arguments).slice(2);if(n instanceof Array&&(o=n.slice(1),n=n[0]),!a.Cursor(n))throw Error("baobab.Combination: argument should be a cursor.");if("or"!==t&&"and"!==t)throw Error("baobab.Combination: invalid operator.");i.call(this),this.cursors=[n],this.operators=[],this.tree=n.tree,this.updates=new Array(this.cursors.length),this.cursorListener=function(){e.updates[e.cursors.indexOf(this)]=!0},this.treeListener=function(){var t,r,n=e.updates[0];for(t=1,r=e.cursors.length;r>t;t++)n="or"===e.operators[t-1]?n||e.updates[t]:n&&e.updates[t];n&&e.emit("update"),e.updates=new Array(e.cursors.length)},this.bound=!1;var u=this.on,h=this.once,c=function(){e.bound||(e.bound=!0,e.cursors.forEach(function(t){r(e,t)}))};this.on=function(){return c(),u.apply(this,arguments)},this.once=function(){return c(),h.apply(this,arguments)},o.forEach(function(e){this[t](e)},this)}function o(t){n.prototype[t]=function(e){if(!a.Cursor(e))throw this.release(),Error("baobab.Combination."+t+": argument should be a cursor.");if(~this.cursors.indexOf(e))throw this.release(),Error("baobab.Combination."+t+": cursor already in combination.");return this.cursors.push(e),this.operators.push(t),this.updates.length++,this.bound&&r(this,e),this}}var i=t("emmett"),s=t("./helpers.js"),a=t("./type.js");s.inherits(n,i),o("or"),o("and"),n.prototype.release=function(){this.cursors.forEach(function(t){t.off("update",this.cursorListener)},this),this.tree.off("update",this.treeListener),this.cursors=null,this.operators=null,this.tree=null,this.updates=null,this.kill()},e.exports=n},{"./helpers.js":7,"./type.js":10,emmett:3}],6:[function(t,e){function r(t,e,r,o){var a=this;n.call(this),e=e||[],this.tree=t,this.path=e,this.hash=o,this.relevant=void 0!==this.get(),this.complexPath=!!r,this.solvedPath=this.complexPath?r:this.path,this.updateHandler=function(t){var e,r,n,o,i,u,h=t.data.log,c=!1;if(a.complexPath&&(a.solvedPath=s.solvePath(a.tree.data,a.path)),!a.path.length)return a.emit("update");t:for(i=0,n=h.length;n>i;i++)for(e=h[i],u=0,o=e.length;o>u&&(r=e[u],r===""+a.solvedPath[u]);u++)if(u+1===o||u+1===a.solvedPath.length){c=!0;break t}var l=void 0!==a.get();a.relevant?l&&c?a.emit("update"):l||(a.emit("irrelevant"),a.relevant=!1):l&&c&&(a.emit("relevant"),a.emit("update"),a.relevant=!0)},this.mixin=i.cursor(this);var u=!1,h=this.on,c=this.once,l=function(){u||(u=!0,a.tree.on("update",a.updateHandler))};this.on=function(){return l(),h.apply(this,arguments)},this.once=function(){return l(),c.apply(this,arguments)}}var n=t("emmett"),o=t("./combination.js"),i=t("./mixins.js"),s=t("./helpers.js"),a=t("./type.js");s.inherits(r,n),r.prototype.isRoot=function(){return!this.path.length},r.prototype.isLeaf=function(){return a.Primitive(this.get())},r.prototype.isBranch=function(){return!this.isLeaf()&&!this.isRoot()},r.prototype.root=function(){return this.tree.root()},r.prototype.select=function(t){if(arguments.length>1&&(t=s.arrayOf(arguments)),!a.Path(t))throw Error("baobab.Cursor.select: invalid path.");return this.tree.select(this.path.concat(t))},r.prototype.up=function(){return this.solvedPath&&this.solvedPath.length?this.tree.select(this.path.slice(0,-1)):null},r.prototype.left=function(){var t=+this.solvedPath[this.solvedPath.length-1];if(isNaN(t))throw Error("baobab.Cursor.left: cannot go left on a non-list type.");return t?this.tree.select(this.solvedPath.slice(0,-1).concat(t-1)):null},r.prototype.leftmost=function(){var t=+this.solvedPath[this.solvedPath.length-1];if(isNaN(t))throw Error("baobab.Cursor.leftmost: cannot go left on a non-list type.");return this.tree.select(this.solvedPath.slice(0,-1).concat(0))},r.prototype.right=function(){var t=+this.solvedPath[this.solvedPath.length-1];if(isNaN(t))throw Error("baobab.Cursor.right: cannot go right on a non-list type.");return t+1===this.up().get().length?null:this.tree.select(this.solvedPath.slice(0,-1).concat(t+1))},r.prototype.rightmost=function(){var t=+this.solvedPath[this.solvedPath.length-1];if(isNaN(t))throw Error("baobab.Cursor.right: cannot go right on a non-list type.");var e=this.up().get();return this.tree.select(this.solvedPath.slice(0,-1).concat(e.length-1))},r.prototype.down=function(){+this.solvedPath[this.solvedPath.length-1];return this.get()instanceof Array?this.tree.select(this.solvedPath.concat(0)):null},r.prototype.get=function(t){return arguments.length>1&&(t=s.arrayOf(arguments)),this.tree.get(a.Step(t)?this.solvedPath.concat(t):this.solvedPath)},r.prototype.set=function(t,e){if(arguments.length<2)throw Error("baobab.Cursor.set: expecting at least key/value.");var r=this.get();if("object"!=typeof r)throw Error("baobab.Cursor.set: trying to set key to a non-object.");var n={};if(a.Array(t)){var o=s.solvePath(r,t);if(!o)throw Error("baobab.Cursor.set: could not solve dynamic path.");n=s.pathObject(o,{$set:e})}else n[t]={$set:e};return this.update(n)},r.prototype.edit=function(t){return this.update({$set:t})},r.prototype.unset=function(t){if(!t&&0!==t)throw Error("baobab.Cursor.unset: expects a valid key to unset.");if("object"!=typeof this.get())throw Error("baobab.Cursor.set: trying to set key to a non-object.");var e={};return e[t]={$unset:!0},this.update(e)},r.prototype.remove=function(){if(this.isRoot())throw Error("baobab.Cursor.remove: cannot remove root node.");return this.update({$unset:!0})},r.prototype.apply=function(t){if("function"!=typeof t)throw Error("baobab.Cursor.apply: argument is not a function.");return this.update({$apply:t})},r.prototype.chain=function(t){if("function"!=typeof t)throw Error("baobab.Cursor.chain: argument is not a function.");return this.update({$chain:t})},r.prototype.push=function(t){if(!(this.get()instanceof Array))throw Error("baobab.Cursor.push: trying to push to non-array value.");return this.update(arguments.length>1?{$push:s.arrayOf(arguments)}:{$push:t})},r.prototype.unshift=function(t){if(!(this.get()instanceof Array))throw Error("baobab.Cursor.push: trying to push to non-array value.");return this.update(arguments.length>1?{$unshift:s.arrayOf(arguments)}:{$unshift:t})},r.prototype.merge=function(t){if(!a.Object(t))throw Error("baobab.Cursor.merge: trying to merge a non-object.");if(!a.Object(this.get()))throw Error("baobab.Cursor.merge: trying to merge into a non-object.");this.update({$merge:t})},r.prototype.update=function(t){return this.tree.update(s.pathObject(this.solvedPath,t)),this},r.prototype.or=function(t){return new o("or",this,t)},r.prototype.and=function(t){return new o("and",this,t)},r.prototype.release=function(){this.tree.off("update",this.updateHandler),this.hash&&delete this.tree._cursors[this.hash],delete this.tree,delete this.path,delete this.solvedPath,this.kill()},r.prototype.toJSON=function(){return this.get()},a.Cursor=function(t){return t instanceof r},e.exports=r},{"./combination.js":5,"./helpers.js":7,"./mixins.js":9,"./type.js":10,emmett:3}],7:[function(t,e){function r(t){return Array.prototype.slice.call(t)}function n(t,e){var r,n={};for(r in t)n[r]=t[r];for(r in e)n[r]=e[r];return n}function o(t){var e=t.source,r="";return t.global&&(r+="g"),t.multiline&&(r+="m"),t.ignoreCase&&(r+="i"),t.sticky&&(r+="y"),t.unicode&&(r+="u"),new RegExp(e,r)}function i(t,e){if(!e||"object"!=typeof e||e instanceof Error||e instanceof ArrayBuffer)return e;if(g.Array(e)){if(t){var r,n,i=[];for(r=0,n=e.length;n>r;r++)i.push(m(e[r]));return i}return e.slice(0)}if(g.Date(e))return new Date(e.getTime());if(e instanceof RegExp)return o(e);if(g.Object(e)){var s,a={};e.constructor&&e.constructor!==Object&&(a=Object.create(e.constructor.prototype));for(s in e)e.hasOwnProperty(s)&&(a[s]=t?m(e[s]):e[s]);return a}return e}function s(t,e){return function(r){return e(t(r))}}function a(t,e){var r,n;for(r=0,n=t.length;n>r;r++)if(e(t[r]))return t[r]}function u(t,e){var r,n;for(r=0,n=t.length;n>r;r++)if(e(t[r]))return r;return-1}function h(t,e){var r,n=!0;if(!t)return!1;for(r in e)if(g.Object(e[r]))n=n&&h(t[r],e[r]);else if(g.Array(e[r]))n=n&&!!~e[r].indexOf(t[r]);else if(t[r]!==e[r])return!1;return n}function c(t,e){return a(t,function(t){return h(t,e)})}function l(t,e){return u(t,function(t){return h(t,e)})}function f(t,e){e=e||[];var r,n,o=t;for(r=0,n=e.length;n>r;r++){if(!o)return;if("function"==typeof e[r]){if(!g.Array(o))return;o=a(o,e[r])}else if("object"==typeof e[r]){if(!g.Array(o))return;o=c(o,e[r])}else o=o[e[r]]}return o}function p(t,e){var r,n,o,i=[],s=t;for(n=0,o=e.length;o>n;n++){if(!s)return null;if("function"==typeof e[n]){if(!g.Array(s))return;r=u(s,e[n]),i.push(r),s=s[r]}else if("object"==typeof e[n]){if(!g.Array(s))return;r=l(s,e[n]),i.push(r),s=s[r]}else i.push(e[n]),s=s[e[n]]||{}}return i}function d(t,e){var r,n=t.length,o={},i=o;for(n||(o=e),r=0;n>r;r++)i[t[r]]=r+1===n?e:{},i=i[t[r]];return o}function y(t,e){t.super_=e;var r=function(){};r.prototype=e.prototype,t.prototype=new r,t.prototype.constructor=t}var g=t("./type.js"),b=i.bind(null,!1),m=i.bind(null,!0);e.exports={arrayOf:r,deepClone:m,shallowClone:b,shallowMerge:n,compose:s,getIn:f,inherits:y,pathObject:d,solvePath:p}},{"./type.js":10}],8:[function(t,e){function r(t,e){return e in(t||{})}function n(t,e,n){return r(t,n)&&r(e,n)}function o(){var t,e,r,a,u={},h=arguments.length;for(r=h-1;r>=0;r--){if(arguments[r].$unset)delete u.$set,delete u.$apply,delete u.$merge,u.$unset=arguments[r].$unset;else{if(arguments[r].$set){delete u.$apply,delete u.$merge,delete u.$unset,u.$set=arguments[r].$set;continue}if(arguments[r].$merge){delete u.$set,delete u.$apply,delete u.$unset,u.$merge=arguments[r].$merge;continue}if(arguments[r].$apply){delete u.$set,delete u.$merge,delete u.$unset,u.$apply=arguments[r].$apply;continue}if(arguments[r].$chain){delete u.$set,delete u.$merge,delete u.$unset,u.$apply=u.$apply?i.compose(u.$apply,arguments[r].$chain):arguments[r].$chain;continue}}for(a in arguments[r])t=u[a],e=arguments[r][a],t&&s.Object(e)?n(t,e,"$push")?t.$push=s.Array(t.$push)?t.$push.concat(e.$push):[t.$push].concat(e.$push):n(t,e,"$unshift")?t.$unshift=s.Array(e.$unshift)?e.$unshift.concat(t.$unshift):[e.$unshift].concat(t.$unshift):u[a]=o(e,t):u[a]=e}return u}var i=t("./helpers.js"),s=t("./type.js");e.exports=o},{"./helpers.js":7,"./type.js":10}],9:[function(t,e){var r=t("./combination.js"),n=t("./type.js");e.exports={baobab:function(t){return{mixins:[{getInitialState:function(){if(this.tree=t,!this.cursor&&!this.cursors)return{};if(this.cursor&&this.cursors)throw Error("baobab.mixin: you cannot have both `component.cursor` and `component.cursors`. Please make up your mind.");if(this.__type=null,this.__updateHandler=function(){this.setState(this.__getCursorData())}.bind(this),this.cursor){if(!n.MixinCursor(this.cursor))throw Error("baobab.mixin.cursor: invalid data (cursor, string, array or function).");n.Function(this.cursor)&&(this.cursor=this.cursor()),n.Cursor(this.cursor)||(this.cursor=t.select(this.cursor)),this.__getCursorData=function(){return{cursor:this.cursor.get()}}.bind(this),this.__type="single"}else if(this.cursors){if(!n.MixinCursors(this.cursors))throw Error("baobab.mixin.cursor: invalid data (object, array or function).");if(n.Function(this.cursors)&&(this.cursors=this.cursors()),n.Array(this.cursors))this.cursors=this.cursors.map(function(e){return n.Cursor(e)?e:t.select(e)}),this.__getCursorData=function(){return{cursors:this.cursors.map(function(t){return t.get()})}}.bind(this),this.__type="array";else{for(var e in this.cursors)n.Cursor(this.cursors[e])||(this.cursors[e]=t.select(this.cursors[e]));this.__getCursorData=function(){var t={};for(e in this.cursors)t[e]=this.cursors[e].get();return{cursors:t}}.bind(this),this.__type="object"}}return this.__getCursorData()},componentDidMount:function(){"single"===this.__type?(this.__combination=new r("or",[this.cursor]),this.__combination.on("update",this.__updateHandler)):"array"===this.__type?(this.__combination=new r("or",this.cursors),this.__combination.on("update",this.__updateHandler)):"object"===this.__type&&(this.__combination=new r("or",Object.keys(this.cursors).map(function(t){return this.cursors[t]},this)),this.__combination.on("update",this.__updateHandler))},componentWillUnmount:function(){this.__combination&&this.__combination.release()}}].concat(t.options.mixins)}},cursor:function(t){return{mixins:[{getInitialState:function(){return this.cursor=t,this.__updateHandler=function(){this.setState({cursor:this.cursor.get()})}.bind(this),{cursor:this.cursor.get()}},componentDidMount:function(){this.cursor.on("update",this.__updateHandler)},componentWillUnmount:function(){this.cursor.off("update",this.__updateHandler)}}].concat(t.tree.options.mixins)}}}},{"./combination.js":5,"./type.js":10}],10:[function(t,e){var r=function(t){return Array.isArray(t)?"array":"object"==typeof t&&null!==t?"object":"string"==typeof t?"string":"number"==typeof t?"number":"boolean"==typeof t?"boolean":"function"==typeof t?"function":null===t?"null":void 0===t?"undefined":t instanceof Date?"date":"invalid"};r.Array=function(t){return Array.isArray(t)},r.Object=function(t){return!Array.isArray(t)&&"object"==typeof t&&null!==t},r.String=function(t){return"string"==typeof t},r.Number=function(t){return"number"==typeof t},r.Boolean=function(t){return"boolean"==typeof t},r.Function=function(t){return"function"==typeof t},r.Primitive=function(t){return"string"==typeof t||"number"==typeof t||"boolean"==typeof t},r.Date=function(t){return t instanceof Date},r.Step=function(t){var e=r(t),n=["null","undefined","invalid","date"];return-1===n.indexOf(e)},r.Path=function(t){var e=["object","string","number","function","undefined"];if(!r.Array(t))return e.indexOf(r(t))>=0;for(var n=0;n=0||r.Cursor(t)},r.MixinCursors=function(t){var e=["array","object","function"];return e.indexOf(r(t))>=0},r.ComplexPath=function(t){for(var e=["object","function"],n=0;n=0)return!0;return!1},e.exports=r},{}],11:[function(t,e){function r(t,e){var r=new Error("baobab.update: "+e+" at path /"+t.toString());return r.path=t,r}function n(t,e,n){n=n||{shiftReferences:!1};var a={};return function u(t,e,h,c){h=h||[];var l,f,p,d,y=h.join("λ");for(p in e)if(s[p])switch(d=e[p],a[y]=!0,p){case"$push":if(!i.Array(t))throw r(h,"using command $push to a non array");i.Array(d)?t.push.apply(t,d):t.push(d);break;case"$unshift":if(!i.Array(t))throw r(h,"using command $unshift to a non array");i.Array(d)?t.unshift.apply(t,d):t.unshift(d)}else if(f=y?y+"λ"+p:p,"$unset"in(e[p]||{}))a[f]=!0,i.Array(t)?n.shiftReferences?c[h[h.length-1]]=t.slice(0,+p).concat(t.slice(+p+1)):t.splice(p,1):delete t[p];else if("$set"in(e[p]||{}))d=e[p].$set,a[f]=!0,t[p]=d;else if("$apply"in(e[p]||{})||"$chain"in(e[p]||{})){if(l=e[p].$apply||e[p].$chain,"function"!=typeof l)throw r(h.concat(p),"using command $apply with a non function");a[f]=!0,t[p]=l.call(null,t[p])}else if("$merge"in(e[p]||{})){if(d=e[p].$merge,!i.Object(t[p]))throw r(h.concat(p),"using command $merge on a non-object");a[f]=!0,t[p]=o.shallowMerge(t[p],d)}else if(n.shiftReferences&&("$push"in(e[p]||{})||"$unshift"in(e[p]||{}))){if("$push"in(e[p]||{})){if(d=e[p].$push,!i.Array(t[p]))throw r(h.concat(p),"using command $push to a non array");t[p]=t[p].concat(d)}if("$unshift"in(e[p]||{})){if(d=e[p].$unshift,!i.Array(t[p]))throw r(h.concat(p),"using command $unshift to a non array");t[p]=(d instanceof Array?d:[d]).concat(t[p])}a[f]=!0}else"undefined"==typeof t[p]&&(t[p]={}),n.shiftReferences&&(t[p]=o.shallowClone(t[p])),u(t[p],e[p],h.concat(p),t)}(t,e),Object.keys(a).map(function(t){return t.split("λ")})}var o=t("./helpers.js"),i=t("./type.js"),s={};["$set","$push","$unshift","$apply","$merge"].forEach(function(t){s[t]=!0}),e.exports=n},{"./helpers.js":7,"./type.js":10}]},{},[2])(2)}); \ No newline at end of file +!function(t){if("object"==typeof exports&&"undefined"!=typeof module)module.exports=t();else if("function"==typeof define&&define.amd)define([],t);else{var e;e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:this,e.Baobab=t()}}(function(){var t;return function e(t,r,n){function o(s,a){if(!r[s]){if(!t[s]){var u="function"==typeof require&&require;if(!a&&u)return u(s,!0);if(i)return i(s,!0);var h=new Error("Cannot find module '"+s+"'");throw h.code="MODULE_NOT_FOUND",h}var c=r[s]={exports:{}};t[s][0].call(c.exports,function(e){var r=t[s][1][e];return o(r?r:e)},c,c.exports,e,t,r,n)}return r[s].exports}for(var i="function"==typeof require&&require,s=0;se;e++)n.push(t[e].handler);return n}var o={once:"boolean",scope:"object"},i=function(){this._enabled=!0,this._children=[],this._handlers={},this._handlersAll=[]};i.prototype.on=function(t,e,r){var n,s,a,u,h,c;if("function"==typeof e){for(h="string"==typeof t?[t]:t,n=0,s=h.length;n!==s;n+=1)if(u=h[n]){this._handlers[u]||(this._handlers[u]=[]),c={handler:e};for(a in r||{}){if(!o[a])throw new Error('The option "'+a+'" is not recognized by Emmett.');c[a]=r[a]}this._handlers[u].push(c)}}else if(t&&"object"==typeof t&&!Array.isArray(t))for(u in t)i.prototype.on.call(this,u,t[u],e);else{if("function"!=typeof t)throw new Error("Wrong arguments.");c={handler:t};for(a in r||{}){if(!o[a])throw new Error('The option "'+a+'" is not recognized by Emmett.');c[a]=r[a]}this._handlersAll.push(c)}return this},i.prototype.once=function(t,e,r){if("function"==typeof e)r=r||{},r.once=!0,this.on(t,e,r);else{if((!t||"object"!=typeof t||Array.isArray(t))&&"function"!=typeof t)throw new Error("Wrong arguments.");e=e||{},e.once=!0,this.on(t,e)}return this},i.prototype.off=function(t,e){var r,n,o,i,s,a,u,h="string"==typeof t?[t]:t;if(1===arguments.length&&"function"==typeof h){e=arguments[0];for(s in this._handlers){for(a=[],r=0,n=this._handlers[s].length;r!==n;r+=1)this._handlers[s][r].handler!==e&&a.push(this._handlers[s][r]);this._handlers[s]=a}for(a=[],r=0,n=this._handlersAll.length;r!==n;r+=1)this._handlersAll[r].handler!==e&&a.push(this._handlersAll[r]);this._handlersAll=a}else if(2===arguments.length)for(r=0,n=h.length;r!==n;r+=1){if(u=h[r],this._handlers[u]){for(a=[],o=0,i=this._handlers[u].length;o!==i;o+=1)this._handlers[u][o].handler!==e&&a.push(this._handlers[u][o]);this._handlers[u]=a}this._handlers[u]&&0===this._handlers[u].length&&delete this._handlers[u]}return this},i.prototype.unbindAll=function(){var t;this._handlersAll=[];for(t in this._handlers)delete this._handlers[t];return this},i.prototype.emit=function(t,e){var r,n,o,i,s,a,u,h,c,l,f="string"==typeof t?[t]:t;if(!this._enabled)return this;for(e=void 0===e?{}:e,r=0,n=f.length;r!==n;r+=1)if(l=f[r],c=(this._handlers[l]||[]).concat(this._handlersAll),c.length){for(u={type:l,data:e||{},target:this},a=[],o=0,i=c.length;o!==i;o+=1)(this._handlers[l]&&this._handlers[l].indexOf(c[o])>=0||this._handlersAll.indexOf(c[o])>=0)&&(c[o].handler.call("scope"in c[o]?c[o].scope:this,u),c[o].once&&a.push(c[o]));for(s=0;sr;r++)if(t._children[r]===e){t._children.splice(r,1);break}}),this._children.push(e),e},i.prototype.listeners=function(t){var r,n,o,i=[];if(t)for(i=e(this._handlers[t]),n=0,o=this._children.length;o>n;n++)i=i.concat(this._children[n].listeners(t));else{i=e(this._handlersAll);for(r in this._handlers)i=i.concat(e(this._handlers[r]));for(n=0,o=this._children.length;o>n;n++)i=i.concat(this._children[n].listeners())}return i},i.prototype.kill=function(){if(this.emit("emmett:kill"),this.unbindAll(),this._handlers=null,this._handlersAll=null,this._enabled=!1,this._children)for(var t=0,e=this._children.length;e>t;t++)this._children[t].kill();this._children=null},i.prototype.disable=function(){return this._enabled=!1,this},i.prototype.enable=function(){return this._enabled=!0,this},i.version="2.1.2","undefined"!=typeof n?("undefined"!=typeof r&&r.exports&&(n=r.exports=i),n.Emitter=i):"function"==typeof t&&t.amd?t("emmett",[],function(){return i}):this.Emitter=i}).call(this)},{}],4:[function(t,e){function r(t){return t+"$"+(new Date).getTime()+(""+Math.random()).replace("0.","")}function n(t,e){if(arguments.length<1&&(t={}),!(this instanceof n))return new n(t,e);if(!l.Object(t)&&!l.Array(t))throw Error("Baobab: invalid data.");i.call(this),this.options=s.shallowMerge(c,e),this._transaction={},this._future=void 0,this._cursors={},this.data=s.deepClone(t),this.mixin=h.baobab(this)}var o=t("./cursor.js"),i=t("emmett"),s=t("./helpers.js"),a=t("./update.js"),u=t("./merge.js"),h=t("./mixins.js"),c=t("../defaults.js"),l=t("./type.js");s.inherits(n,i),n.prototype.commit=function(){this.options.shiftReferences&&(this.data=s.shallowClone(this.data));var t=a(this.data,this._transaction,this.options);return this._transaction={},this._future&&(this._future=clearTimeout(this._future)),this.emit("update",{log:t}),this},n.prototype.select=function(t){if(!t)throw Error("Baobab.select: invalid path.");if(arguments.length>1&&(t=s.arrayOf(arguments)),!l.Path(t))throw Error("Baobab.select: invalid path.");t=l.Array(t)?t:[t];var e,n=l.ComplexPath(t);n&&(e=s.solvePath(this.data,t));var i=t.map(function(t){return l.Function(t)?r("fn"):l.Object(t)?r("ob"):t}).join("λ");if(this._cursors[i])return this._cursors[i];var a=new o(this,t,e,i);return this._cursors[i]=a,a},n.prototype.root=function(){return this.select([])},n.prototype.get=function(t){if(arguments.length>1&&(t=s.arrayOf(arguments)),!l.Path(t))throw Error("Baobab.get: invalid path.");return s.getIn(this.data,l.String(t)||l.Number(t)?[t]:t)},n.prototype.set=function(t,e){if(arguments.length<2)throw Error("Baobab.set: expects a key and a value.");var r={};if(l.Array(t)){var n=s.solvePath(this.data,t);if(!n)throw Error("Baobab.set: could not solve dynamic path.");r=s.pathObject(n,{$set:e})}else r[t]={$set:e};return this.update(r)},n.prototype.unset=function(t){if(!t&&0!==t)throw Error("Baobab.unset: expects a valid key to unset.");var e={};return e[t]={$unset:!0},this.update(e)},n.prototype.update=function(t){var e=this;if(!l.Object(t))throw Error("Baobab.update: wrong specification.");return this._transaction=u(t,this._transaction),this.options.autoCommit?this.options.asynchronous?(this._future||(this._future=setTimeout(e.commit.bind(e,null),0)),this):this.commit():this},n.prototype.release=function(){delete this.data,delete this._transaction;for(var t in this._cursors)this._cursors[t].release();delete this._cursors,this.kill()},n.prototype.toJSON=function(){return this.get()},e.exports=n},{"../defaults.js":1,"./cursor.js":6,"./helpers.js":7,"./merge.js":8,"./mixins.js":9,"./type.js":10,"./update.js":11,emmett:3}],5:[function(t,e){function r(t,e){e.on("update",t.cursorListener),t.tree.off("update",t.treeListener),t.tree.on("update",t.treeListener)}function n(t){var e=this;if(arguments.length<2)throw Error("baobab.Combination: not enough arguments.");var n=arguments[1],o=s.arrayOf(arguments).slice(2);if(n instanceof Array&&(o=n.slice(1),n=n[0]),!a.Cursor(n))throw Error("baobab.Combination: argument should be a cursor.");if("or"!==t&&"and"!==t)throw Error("baobab.Combination: invalid operator.");i.call(this),this.cursors=[n],this.operators=[],this.tree=n.tree,this.updates=new Array(this.cursors.length),this.cursorListener=function(){e.updates[e.cursors.indexOf(this)]=!0},this.treeListener=function(){var t,r,n=e.updates[0];for(t=1,r=e.cursors.length;r>t;t++)n="or"===e.operators[t-1]?n||e.updates[t]:n&&e.updates[t];n&&e.emit("update"),e.updates=new Array(e.cursors.length)},this.bound=!1;var u=this.on,h=this.once,c=function(){e.bound||(e.bound=!0,e.cursors.forEach(function(t){r(e,t)}))};this.on=function(){return c(),u.apply(this,arguments)},this.once=function(){return c(),h.apply(this,arguments)},o.forEach(function(e){this[t](e)},this)}function o(t){n.prototype[t]=function(e){if(!a.Cursor(e))throw this.release(),Error("baobab.Combination."+t+": argument should be a cursor.");if(~this.cursors.indexOf(e))throw this.release(),Error("baobab.Combination."+t+": cursor already in combination.");return this.cursors.push(e),this.operators.push(t),this.updates.length++,this.bound&&r(this,e),this}}var i=t("emmett"),s=t("./helpers.js"),a=t("./type.js");s.inherits(n,i),o("or"),o("and"),n.prototype.release=function(){this.cursors.forEach(function(t){t.off("update",this.cursorListener)},this),this.tree.off("update",this.treeListener),this.cursors=null,this.operators=null,this.tree=null,this.updates=null,this.kill()},e.exports=n},{"./helpers.js":7,"./type.js":10,emmett:3}],6:[function(t,e){function r(t,e,r,o){var a=this;n.call(this),e=e||[],this.tree=t,this.path=e,this.hash=o,this.relevant=void 0!==this.get(),this.complexPath=!!r,this.solvedPath=this.complexPath?r:this.path,this.updateHandler=function(t){var e,r,n,o,i,u,h=t.data.log,c=!1;if(a.complexPath&&(a.solvedPath=s.solvePath(a.tree.data,a.path)),!a.path.length)return a.emit("update");t:for(i=0,n=h.length;n>i;i++)for(e=h[i],u=0,o=e.length;o>u&&(r=e[u],r===""+a.solvedPath[u]);u++)if(u+1===o||u+1===a.solvedPath.length){c=!0;break t}var l=void 0!==a.get();a.relevant?l&&c?a.emit("update"):l||(a.emit("irrelevant"),a.relevant=!1):l&&c&&(a.emit("relevant"),a.emit("update"),a.relevant=!0)},this.mixin=i.cursor(this);var u=!1,h=this.on,c=this.once,l=function(){u||(u=!0,a.tree.on("update",a.updateHandler))};this.on=function(){return l(),h.apply(this,arguments)},this.once=function(){return l(),c.apply(this,arguments)}}var n=t("emmett"),o=t("./combination.js"),i=t("./mixins.js"),s=t("./helpers.js"),a=t("./type.js");s.inherits(r,n),r.prototype.isRoot=function(){return!this.path.length},r.prototype.isLeaf=function(){return a.Primitive(this.get())},r.prototype.isBranch=function(){return!this.isLeaf()&&!this.isRoot()},r.prototype.root=function(){return this.tree.root()},r.prototype.select=function(t){if(arguments.length>1&&(t=s.arrayOf(arguments)),!a.Path(t))throw Error("baobab.Cursor.select: invalid path.");return this.tree.select(this.path.concat(t))},r.prototype.up=function(){return this.solvedPath&&this.solvedPath.length?this.tree.select(this.path.slice(0,-1)):null},r.prototype.left=function(){var t=+this.solvedPath[this.solvedPath.length-1];if(isNaN(t))throw Error("baobab.Cursor.left: cannot go left on a non-list type.");return t?this.tree.select(this.solvedPath.slice(0,-1).concat(t-1)):null},r.prototype.leftmost=function(){var t=+this.solvedPath[this.solvedPath.length-1];if(isNaN(t))throw Error("baobab.Cursor.leftmost: cannot go left on a non-list type.");return this.tree.select(this.solvedPath.slice(0,-1).concat(0))},r.prototype.right=function(){var t=+this.solvedPath[this.solvedPath.length-1];if(isNaN(t))throw Error("baobab.Cursor.right: cannot go right on a non-list type.");return t+1===this.up().get().length?null:this.tree.select(this.solvedPath.slice(0,-1).concat(t+1))},r.prototype.rightmost=function(){var t=+this.solvedPath[this.solvedPath.length-1];if(isNaN(t))throw Error("baobab.Cursor.right: cannot go right on a non-list type.");var e=this.up().get();return this.tree.select(this.solvedPath.slice(0,-1).concat(e.length-1))},r.prototype.down=function(){+this.solvedPath[this.solvedPath.length-1];return this.get()instanceof Array?this.tree.select(this.solvedPath.concat(0)):null},r.prototype.get=function(t){return arguments.length>1&&(t=s.arrayOf(arguments)),this.tree.get(a.Step(t)?this.solvedPath.concat(t):this.solvedPath)},r.prototype.set=function(t,e){if(arguments.length<2)throw Error("baobab.Cursor.set: expecting at least key/value.");var r=this.get();if("object"!=typeof r)throw Error("baobab.Cursor.set: trying to set key to a non-object.");var n={};if(a.Array(t)){var o=s.solvePath(r,t);if(!o)throw Error("baobab.Cursor.set: could not solve dynamic path.");n=s.pathObject(o,{$set:e})}else n[t]={$set:e};return this.update(n)},r.prototype.edit=function(t){return this.update({$set:t})},r.prototype.unset=function(t){if(!t&&0!==t)throw Error("baobab.Cursor.unset: expects a valid key to unset.");if("object"!=typeof this.get())throw Error("baobab.Cursor.set: trying to set key to a non-object.");var e={};return e[t]={$unset:!0},this.update(e)},r.prototype.remove=function(){if(this.isRoot())throw Error("baobab.Cursor.remove: cannot remove root node.");return this.update({$unset:!0})},r.prototype.apply=function(t){if("function"!=typeof t)throw Error("baobab.Cursor.apply: argument is not a function.");return this.update({$apply:t})},r.prototype.chain=function(t){if("function"!=typeof t)throw Error("baobab.Cursor.chain: argument is not a function.");return this.update({$chain:t})},r.prototype.push=function(t){if(!(this.get()instanceof Array))throw Error("baobab.Cursor.push: trying to push to non-array value.");return this.update(arguments.length>1?{$push:s.arrayOf(arguments)}:{$push:t})},r.prototype.unshift=function(t){if(!(this.get()instanceof Array))throw Error("baobab.Cursor.push: trying to push to non-array value.");return this.update(arguments.length>1?{$unshift:s.arrayOf(arguments)}:{$unshift:t})},r.prototype.merge=function(t){if(!a.Object(t))throw Error("baobab.Cursor.merge: trying to merge a non-object.");if(!a.Object(this.get()))throw Error("baobab.Cursor.merge: trying to merge into a non-object.");this.update({$merge:t})},r.prototype.update=function(t){return this.tree.update(s.pathObject(this.solvedPath,t)),this},r.prototype.or=function(t){return new o("or",this,t)},r.prototype.and=function(t){return new o("and",this,t)},r.prototype.release=function(){this.tree.off("update",this.updateHandler),this.hash&&delete this.tree._cursors[this.hash],delete this.tree,delete this.path,delete this.solvedPath,this.kill()},r.prototype.toJSON=function(){return this.get()},a.Cursor=function(t){return t instanceof r},e.exports=r},{"./combination.js":5,"./helpers.js":7,"./mixins.js":9,"./type.js":10,emmett:3}],7:[function(t,e){function r(t){return Array.prototype.slice.call(t)}function n(t,e){var r,n={};for(r in t)n[r]=t[r];for(r in e)n[r]=e[r];return n}function o(t){var e=t.source,r="";return t.global&&(r+="g"),t.multiline&&(r+="m"),t.ignoreCase&&(r+="i"),t.sticky&&(r+="y"),t.unicode&&(r+="u"),new RegExp(e,r)}function i(t,e){if(!e||"object"!=typeof e||e instanceof Error||e instanceof ArrayBuffer)return e;if(b.Array(e)){if(t){var r,n,i=[];for(r=0,n=e.length;n>r;r++)i.push(m(e[r]));return i}return e.slice(0)}if(b.Date(e))return new Date(e.getTime());if(e instanceof RegExp)return o(e);if(b.Object(e)){var s,a={};e.constructor&&e.constructor!==Object&&(a=Object.create(e.constructor.prototype));for(s in e)e.hasOwnProperty(s)&&(a[s]=t?m(e[s]):e[s]);return a}return e}function s(t,e){return function(r){return e(t(r))}}function a(t,e){var r,n;for(r=0,n=t.length;n>r;r++)if(e(t[r]))return t[r]}function u(t,e){var r,n;for(r=0,n=t.length;n>r;r++)if(e(t[r]))return r;return-1}function h(t,e){var r,n=!0;if(!t)return!1;for(r in e)if(b.Object(e[r]))n=n&&h(t[r],e[r]);else if(b.Array(e[r]))n=n&&!!~e[r].indexOf(t[r]);else if(t[r]!==e[r])return!1;return n}function c(t,e){return a(t,function(t){return h(t,e)})}function l(t,e){return u(t,function(t){return h(t,e)})}function f(t,e){e=e||[];var r,n,o=t;for(r=0,n=e.length;n>r;r++){if(!o)return;if("function"==typeof e[r]){if(!b.Array(o))return;o=a(o,e[r])}else if("object"==typeof e[r]){if(!b.Array(o))return;o=c(o,e[r])}else o=o[e[r]]}return o}function p(t,e){var r,n,o,i=[],s=t;for(n=0,o=e.length;o>n;n++){if(!s)return null;if("function"==typeof e[n]){if(!b.Array(s))return;r=u(s,e[n]),i.push(r),s=s[r]}else if("object"==typeof e[n]){if(!b.Array(s))return;r=l(s,e[n]),i.push(r),s=s[r]}else i.push(e[n]),s=s[e[n]]||{}}return i}function d(t,e){var r,n=t.length,o={},i=o;for(n||(o=e),r=0;n>r;r++)i[t[r]]=r+1===n?e:{},i=i[t[r]];return o}function y(t,e){t.super_=e;var r=function(){};r.prototype=e.prototype,t.prototype=new r,t.prototype.constructor=t}var b=t("./type.js"),g=i.bind(null,!1),m=i.bind(null,!0);e.exports={arrayOf:r,deepClone:m,shallowClone:g,shallowMerge:n,compose:s,getIn:f,inherits:y,pathObject:d,solvePath:p}},{"./type.js":10}],8:[function(t,e){function r(t,e){return e in(t||{})}function n(t,e,n){return r(t,n)&&r(e,n)}function o(){var t,e,r,a,u={},h=arguments.length;for(r=h-1;r>=0;r--){if(arguments[r].$unset)delete u.$set,delete u.$apply,delete u.$merge,u.$unset=arguments[r].$unset;else{if(arguments[r].$set){delete u.$apply,delete u.$merge,delete u.$unset,u.$set=arguments[r].$set;continue}if(arguments[r].$merge){delete u.$set,delete u.$apply,delete u.$unset,u.$merge=arguments[r].$merge;continue}if(arguments[r].$apply){delete u.$set,delete u.$merge,delete u.$unset,u.$apply=arguments[r].$apply;continue}if(arguments[r].$chain){delete u.$set,delete u.$merge,delete u.$unset,u.$apply=u.$apply?i.compose(u.$apply,arguments[r].$chain):arguments[r].$chain;continue}}for(a in arguments[r])t=u[a],e=arguments[r][a],t&&s.Object(e)?n(t,e,"$push")?t.$push=s.Array(t.$push)?t.$push.concat(e.$push):[t.$push].concat(e.$push):n(t,e,"$unshift")?t.$unshift=s.Array(e.$unshift)?e.$unshift.concat(t.$unshift):[e.$unshift].concat(t.$unshift):u[a]=o(e,t):u[a]=e}return u}var i=t("./helpers.js"),s=t("./type.js");e.exports=o},{"./helpers.js":7,"./type.js":10}],9:[function(t,e){var r=t("./combination.js"),n=t("./type.js");e.exports={baobab:function(t){return{mixins:[{getInitialState:function(){if(this.tree=t,!this.cursor&&!this.cursors)return{};if(this.cursor&&this.cursors)throw Error("baobab.mixin: you cannot have both `component.cursor` and `component.cursors`. Please make up your mind.");if(this.__type=null,this.__updateHandler=function(){this.setState(this.__getCursorData())}.bind(this),this.cursor){if(!n.MixinCursor(this.cursor))throw Error("baobab.mixin.cursor: invalid data (cursor, string, array or function).");n.Function(this.cursor)&&(this.cursor=this.cursor()),n.Cursor(this.cursor)||(this.cursor=t.select(this.cursor)),this.__getCursorData=function(){return{cursor:this.cursor.get()}}.bind(this),this.__type="single"}else if(this.cursors){if(!n.MixinCursors(this.cursors))throw Error("baobab.mixin.cursor: invalid data (object, array or function).");if(n.Function(this.cursors)&&(this.cursors=this.cursors()),n.Array(this.cursors))this.cursors=this.cursors.map(function(e){return n.Cursor(e)?e:t.select(e)}),this.__getCursorData=function(){return{cursors:this.cursors.map(function(t){return t.get()})}}.bind(this),this.__type="array";else{for(var e in this.cursors)n.Cursor(this.cursors[e])||(this.cursors[e]=t.select(this.cursors[e]));this.__getCursorData=function(){var t={};for(e in this.cursors)t[e]=this.cursors[e].get();return{cursors:t}}.bind(this),this.__type="object"}}return this.__getCursorData()},componentDidMount:function(){"single"===this.__type?(this.__combination=new r("or",[this.cursor]),this.__combination.on("update",this.__updateHandler)):"array"===this.__type?(this.__combination=new r("or",this.cursors),this.__combination.on("update",this.__updateHandler)):"object"===this.__type&&(this.__combination=new r("or",Object.keys(this.cursors).map(function(t){return this.cursors[t]},this)),this.__combination.on("update",this.__updateHandler))},componentWillUnmount:function(){this.__combination&&this.__combination.release()}}].concat(t.options.mixins)}},cursor:function(t){return{mixins:[{getInitialState:function(){return this.cursor=t,this.__updateHandler=function(){this.setState({cursor:this.cursor.get()})}.bind(this),{cursor:this.cursor.get()}},componentDidMount:function(){this.cursor.on("update",this.__updateHandler)},componentWillUnmount:function(){this.cursor.off("update",this.__updateHandler)}}].concat(t.tree.options.mixins)}}}},{"./combination.js":5,"./type.js":10}],10:[function(t,e){var r=function(t){return Array.isArray(t)?"array":"object"==typeof t&&null!==t?"object":"string"==typeof t?"string":"number"==typeof t?"number":"boolean"==typeof t?"boolean":"function"==typeof t?"function":null===t?"null":void 0===t?"undefined":t instanceof Date?"date":"invalid"};r.Array=function(t){return Array.isArray(t)},r.Object=function(t){return!Array.isArray(t)&&"object"==typeof t&&null!==t},r.String=function(t){return"string"==typeof t},r.Number=function(t){return"number"==typeof t},r.Boolean=function(t){return"boolean"==typeof t},r.Function=function(t){return"function"==typeof t},r.Primitive=function(t){return"string"==typeof t||"number"==typeof t||"boolean"==typeof t},r.Date=function(t){return t instanceof Date},r.Step=function(t){var e=r(t),n=["null","undefined","invalid","date"];return-1===n.indexOf(e)},r.Path=function(t){var e=["object","string","number","function","undefined"];if(!r.Array(t))return e.indexOf(r(t))>=0;for(var n=0;n=0||r.Cursor(t)},r.MixinCursors=function(t){var e=["array","object","function"];return e.indexOf(r(t))>=0},r.ComplexPath=function(t){for(var e=["object","function"],n=0;n=0)return!0;return!1},e.exports=r},{}],11:[function(t,e){function r(t,e){var r=new Error("baobab.update: "+e+" at path /"+t.toString());return r.path=t,r}function n(t,e,n){n=n||{shiftReferences:!1};var a={};return function u(t,e,h,c){h=h||[];var l,f,p,d,y=h.join("λ");for(p in e)if(s[p])switch(d=e[p],a[y]=!0,p){case"$push":if(!i.Array(t))throw r(h,"using command $push to a non array");i.Array(d)?t.push.apply(t,d):t.push(d);break;case"$unshift":if(!i.Array(t))throw r(h,"using command $unshift to a non array");i.Array(d)?t.unshift.apply(t,d):t.unshift(d)}else if(f=y?y+"λ"+p:p,"$unset"in(e[p]||{}))a[f]=!0,i.Array(t)?n.shiftReferences?c[h[h.length-1]]=t.slice(0,+p).concat(t.slice(+p+1)):t.splice(p,1):delete t[p];else if("$set"in(e[p]||{}))d=e[p].$set,a[f]=!0,t[p]=d;else if("$apply"in(e[p]||{})||"$chain"in(e[p]||{})){if(l=e[p].$apply||e[p].$chain,"function"!=typeof l)throw r(h.concat(p),"using command $apply with a non function");a[f]=!0,t[p]=l.call(null,t[p])}else if("$merge"in(e[p]||{})){if(d=e[p].$merge,!i.Object(t[p]))throw r(h.concat(p),"using command $merge on a non-object");a[f]=!0,t[p]=o.shallowMerge(t[p],d)}else if(n.shiftReferences&&("$push"in(e[p]||{})||"$unshift"in(e[p]||{}))){if("$push"in(e[p]||{})){if(d=e[p].$push,!i.Array(t[p]))throw r(h.concat(p),"using command $push to a non array");t[p]=t[p].concat(d)}if("$unshift"in(e[p]||{})){if(d=e[p].$unshift,!i.Array(t[p]))throw r(h.concat(p),"using command $unshift to a non array");t[p]=(d instanceof Array?d:[d]).concat(t[p])}a[f]=!0}else"undefined"==typeof t[p]&&(t[p]={}),n.shiftReferences&&(t[p]=o.shallowClone(t[p])),u(t[p],e[p],h.concat(p),t)}(t,e),Object.keys(a).map(function(t){return t.split("λ")})}var o=t("./helpers.js"),i=t("./type.js"),s={};["$set","$push","$unshift","$apply","$merge"].forEach(function(t){s[t]=!0}),e.exports=n},{"./helpers.js":7,"./type.js":10}]},{},[2])(2)}); \ No newline at end of file diff --git a/defaults.js b/defaults.js index 85ef97b..eb775bc 100644 --- a/defaults.js +++ b/defaults.js @@ -11,27 +11,12 @@ module.exports = { // Should the transactions be handled asynchronously? asynchronous: true, - // Should the tree clone data when giving it back to the user? - clone: false, - - // Which cloning function should the tree use? - cloningFunction: null, - - // Should cursors be singletons? - cursorSingletons: true, - - // Maximum records in the tree's history - maxHistory: 0, - // Collection of react mixins to merge with the tree's ones mixins: [], // Should the tree shift its internal reference when applying mutations? shiftReferences: false, - // Custom typology object to use along with the validation utilities - typology: null, - // Validation specifications validate: null }; From 65d9f8e2d3ecb604afd2330e91d96356d352e67f Mon Sep 17 00:00:00 2001 From: Yomguithereal Date: Fri, 27 Mar 2015 20:08:59 +0100 Subject: [PATCH 07/73] Cleaning things between cursor and tree --- .gitignore | 1 + build/baobab.min.js | 2 +- src/baobab.js | 111 ++++++++++++++------------------------------ src/cursor.js | 15 +++--- 4 files changed, 47 insertions(+), 82 deletions(-) diff --git a/.gitignore b/.gitignore index fd4f2b0..c5c4bd0 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,3 @@ node_modules .DS_Store +TODO.md diff --git a/build/baobab.min.js b/build/baobab.min.js index 14fea95..ec3717f 100644 --- a/build/baobab.min.js +++ b/build/baobab.min.js @@ -1,2 +1,2 @@ /* baobab.js - Version: 0.4.3 - Author: Yomguithereal (Guillaume Plique) */ -!function(t){if("object"==typeof exports&&"undefined"!=typeof module)module.exports=t();else if("function"==typeof define&&define.amd)define([],t);else{var e;e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:this,e.Baobab=t()}}(function(){var t;return function e(t,r,n){function o(s,a){if(!r[s]){if(!t[s]){var u="function"==typeof require&&require;if(!a&&u)return u(s,!0);if(i)return i(s,!0);var h=new Error("Cannot find module '"+s+"'");throw h.code="MODULE_NOT_FOUND",h}var c=r[s]={exports:{}};t[s][0].call(c.exports,function(e){var r=t[s][1][e];return o(r?r:e)},c,c.exports,e,t,r,n)}return r[s].exports}for(var i="function"==typeof require&&require,s=0;se;e++)n.push(t[e].handler);return n}var o={once:"boolean",scope:"object"},i=function(){this._enabled=!0,this._children=[],this._handlers={},this._handlersAll=[]};i.prototype.on=function(t,e,r){var n,s,a,u,h,c;if("function"==typeof e){for(h="string"==typeof t?[t]:t,n=0,s=h.length;n!==s;n+=1)if(u=h[n]){this._handlers[u]||(this._handlers[u]=[]),c={handler:e};for(a in r||{}){if(!o[a])throw new Error('The option "'+a+'" is not recognized by Emmett.');c[a]=r[a]}this._handlers[u].push(c)}}else if(t&&"object"==typeof t&&!Array.isArray(t))for(u in t)i.prototype.on.call(this,u,t[u],e);else{if("function"!=typeof t)throw new Error("Wrong arguments.");c={handler:t};for(a in r||{}){if(!o[a])throw new Error('The option "'+a+'" is not recognized by Emmett.');c[a]=r[a]}this._handlersAll.push(c)}return this},i.prototype.once=function(t,e,r){if("function"==typeof e)r=r||{},r.once=!0,this.on(t,e,r);else{if((!t||"object"!=typeof t||Array.isArray(t))&&"function"!=typeof t)throw new Error("Wrong arguments.");e=e||{},e.once=!0,this.on(t,e)}return this},i.prototype.off=function(t,e){var r,n,o,i,s,a,u,h="string"==typeof t?[t]:t;if(1===arguments.length&&"function"==typeof h){e=arguments[0];for(s in this._handlers){for(a=[],r=0,n=this._handlers[s].length;r!==n;r+=1)this._handlers[s][r].handler!==e&&a.push(this._handlers[s][r]);this._handlers[s]=a}for(a=[],r=0,n=this._handlersAll.length;r!==n;r+=1)this._handlersAll[r].handler!==e&&a.push(this._handlersAll[r]);this._handlersAll=a}else if(2===arguments.length)for(r=0,n=h.length;r!==n;r+=1){if(u=h[r],this._handlers[u]){for(a=[],o=0,i=this._handlers[u].length;o!==i;o+=1)this._handlers[u][o].handler!==e&&a.push(this._handlers[u][o]);this._handlers[u]=a}this._handlers[u]&&0===this._handlers[u].length&&delete this._handlers[u]}return this},i.prototype.unbindAll=function(){var t;this._handlersAll=[];for(t in this._handlers)delete this._handlers[t];return this},i.prototype.emit=function(t,e){var r,n,o,i,s,a,u,h,c,l,f="string"==typeof t?[t]:t;if(!this._enabled)return this;for(e=void 0===e?{}:e,r=0,n=f.length;r!==n;r+=1)if(l=f[r],c=(this._handlers[l]||[]).concat(this._handlersAll),c.length){for(u={type:l,data:e||{},target:this},a=[],o=0,i=c.length;o!==i;o+=1)(this._handlers[l]&&this._handlers[l].indexOf(c[o])>=0||this._handlersAll.indexOf(c[o])>=0)&&(c[o].handler.call("scope"in c[o]?c[o].scope:this,u),c[o].once&&a.push(c[o]));for(s=0;sr;r++)if(t._children[r]===e){t._children.splice(r,1);break}}),this._children.push(e),e},i.prototype.listeners=function(t){var r,n,o,i=[];if(t)for(i=e(this._handlers[t]),n=0,o=this._children.length;o>n;n++)i=i.concat(this._children[n].listeners(t));else{i=e(this._handlersAll);for(r in this._handlers)i=i.concat(e(this._handlers[r]));for(n=0,o=this._children.length;o>n;n++)i=i.concat(this._children[n].listeners())}return i},i.prototype.kill=function(){if(this.emit("emmett:kill"),this.unbindAll(),this._handlers=null,this._handlersAll=null,this._enabled=!1,this._children)for(var t=0,e=this._children.length;e>t;t++)this._children[t].kill();this._children=null},i.prototype.disable=function(){return this._enabled=!1,this},i.prototype.enable=function(){return this._enabled=!0,this},i.version="2.1.2","undefined"!=typeof n?("undefined"!=typeof r&&r.exports&&(n=r.exports=i),n.Emitter=i):"function"==typeof t&&t.amd?t("emmett",[],function(){return i}):this.Emitter=i}).call(this)},{}],4:[function(t,e){function r(t){return t+"$"+(new Date).getTime()+(""+Math.random()).replace("0.","")}function n(t,e){if(arguments.length<1&&(t={}),!(this instanceof n))return new n(t,e);if(!l.Object(t)&&!l.Array(t))throw Error("Baobab: invalid data.");i.call(this),this.options=s.shallowMerge(c,e),this._transaction={},this._future=void 0,this._cursors={},this.data=s.deepClone(t),this.mixin=h.baobab(this)}var o=t("./cursor.js"),i=t("emmett"),s=t("./helpers.js"),a=t("./update.js"),u=t("./merge.js"),h=t("./mixins.js"),c=t("../defaults.js"),l=t("./type.js");s.inherits(n,i),n.prototype.commit=function(){this.options.shiftReferences&&(this.data=s.shallowClone(this.data));var t=a(this.data,this._transaction,this.options);return this._transaction={},this._future&&(this._future=clearTimeout(this._future)),this.emit("update",{log:t}),this},n.prototype.select=function(t){if(!t)throw Error("Baobab.select: invalid path.");if(arguments.length>1&&(t=s.arrayOf(arguments)),!l.Path(t))throw Error("Baobab.select: invalid path.");t=l.Array(t)?t:[t];var e,n=l.ComplexPath(t);n&&(e=s.solvePath(this.data,t));var i=t.map(function(t){return l.Function(t)?r("fn"):l.Object(t)?r("ob"):t}).join("λ");if(this._cursors[i])return this._cursors[i];var a=new o(this,t,e,i);return this._cursors[i]=a,a},n.prototype.root=function(){return this.select([])},n.prototype.get=function(t){if(arguments.length>1&&(t=s.arrayOf(arguments)),!l.Path(t))throw Error("Baobab.get: invalid path.");return s.getIn(this.data,l.String(t)||l.Number(t)?[t]:t)},n.prototype.set=function(t,e){if(arguments.length<2)throw Error("Baobab.set: expects a key and a value.");var r={};if(l.Array(t)){var n=s.solvePath(this.data,t);if(!n)throw Error("Baobab.set: could not solve dynamic path.");r=s.pathObject(n,{$set:e})}else r[t]={$set:e};return this.update(r)},n.prototype.unset=function(t){if(!t&&0!==t)throw Error("Baobab.unset: expects a valid key to unset.");var e={};return e[t]={$unset:!0},this.update(e)},n.prototype.update=function(t){var e=this;if(!l.Object(t))throw Error("Baobab.update: wrong specification.");return this._transaction=u(t,this._transaction),this.options.autoCommit?this.options.asynchronous?(this._future||(this._future=setTimeout(e.commit.bind(e,null),0)),this):this.commit():this},n.prototype.release=function(){delete this.data,delete this._transaction;for(var t in this._cursors)this._cursors[t].release();delete this._cursors,this.kill()},n.prototype.toJSON=function(){return this.get()},e.exports=n},{"../defaults.js":1,"./cursor.js":6,"./helpers.js":7,"./merge.js":8,"./mixins.js":9,"./type.js":10,"./update.js":11,emmett:3}],5:[function(t,e){function r(t,e){e.on("update",t.cursorListener),t.tree.off("update",t.treeListener),t.tree.on("update",t.treeListener)}function n(t){var e=this;if(arguments.length<2)throw Error("baobab.Combination: not enough arguments.");var n=arguments[1],o=s.arrayOf(arguments).slice(2);if(n instanceof Array&&(o=n.slice(1),n=n[0]),!a.Cursor(n))throw Error("baobab.Combination: argument should be a cursor.");if("or"!==t&&"and"!==t)throw Error("baobab.Combination: invalid operator.");i.call(this),this.cursors=[n],this.operators=[],this.tree=n.tree,this.updates=new Array(this.cursors.length),this.cursorListener=function(){e.updates[e.cursors.indexOf(this)]=!0},this.treeListener=function(){var t,r,n=e.updates[0];for(t=1,r=e.cursors.length;r>t;t++)n="or"===e.operators[t-1]?n||e.updates[t]:n&&e.updates[t];n&&e.emit("update"),e.updates=new Array(e.cursors.length)},this.bound=!1;var u=this.on,h=this.once,c=function(){e.bound||(e.bound=!0,e.cursors.forEach(function(t){r(e,t)}))};this.on=function(){return c(),u.apply(this,arguments)},this.once=function(){return c(),h.apply(this,arguments)},o.forEach(function(e){this[t](e)},this)}function o(t){n.prototype[t]=function(e){if(!a.Cursor(e))throw this.release(),Error("baobab.Combination."+t+": argument should be a cursor.");if(~this.cursors.indexOf(e))throw this.release(),Error("baobab.Combination."+t+": cursor already in combination.");return this.cursors.push(e),this.operators.push(t),this.updates.length++,this.bound&&r(this,e),this}}var i=t("emmett"),s=t("./helpers.js"),a=t("./type.js");s.inherits(n,i),o("or"),o("and"),n.prototype.release=function(){this.cursors.forEach(function(t){t.off("update",this.cursorListener)},this),this.tree.off("update",this.treeListener),this.cursors=null,this.operators=null,this.tree=null,this.updates=null,this.kill()},e.exports=n},{"./helpers.js":7,"./type.js":10,emmett:3}],6:[function(t,e){function r(t,e,r,o){var a=this;n.call(this),e=e||[],this.tree=t,this.path=e,this.hash=o,this.relevant=void 0!==this.get(),this.complexPath=!!r,this.solvedPath=this.complexPath?r:this.path,this.updateHandler=function(t){var e,r,n,o,i,u,h=t.data.log,c=!1;if(a.complexPath&&(a.solvedPath=s.solvePath(a.tree.data,a.path)),!a.path.length)return a.emit("update");t:for(i=0,n=h.length;n>i;i++)for(e=h[i],u=0,o=e.length;o>u&&(r=e[u],r===""+a.solvedPath[u]);u++)if(u+1===o||u+1===a.solvedPath.length){c=!0;break t}var l=void 0!==a.get();a.relevant?l&&c?a.emit("update"):l||(a.emit("irrelevant"),a.relevant=!1):l&&c&&(a.emit("relevant"),a.emit("update"),a.relevant=!0)},this.mixin=i.cursor(this);var u=!1,h=this.on,c=this.once,l=function(){u||(u=!0,a.tree.on("update",a.updateHandler))};this.on=function(){return l(),h.apply(this,arguments)},this.once=function(){return l(),c.apply(this,arguments)}}var n=t("emmett"),o=t("./combination.js"),i=t("./mixins.js"),s=t("./helpers.js"),a=t("./type.js");s.inherits(r,n),r.prototype.isRoot=function(){return!this.path.length},r.prototype.isLeaf=function(){return a.Primitive(this.get())},r.prototype.isBranch=function(){return!this.isLeaf()&&!this.isRoot()},r.prototype.root=function(){return this.tree.root()},r.prototype.select=function(t){if(arguments.length>1&&(t=s.arrayOf(arguments)),!a.Path(t))throw Error("baobab.Cursor.select: invalid path.");return this.tree.select(this.path.concat(t))},r.prototype.up=function(){return this.solvedPath&&this.solvedPath.length?this.tree.select(this.path.slice(0,-1)):null},r.prototype.left=function(){var t=+this.solvedPath[this.solvedPath.length-1];if(isNaN(t))throw Error("baobab.Cursor.left: cannot go left on a non-list type.");return t?this.tree.select(this.solvedPath.slice(0,-1).concat(t-1)):null},r.prototype.leftmost=function(){var t=+this.solvedPath[this.solvedPath.length-1];if(isNaN(t))throw Error("baobab.Cursor.leftmost: cannot go left on a non-list type.");return this.tree.select(this.solvedPath.slice(0,-1).concat(0))},r.prototype.right=function(){var t=+this.solvedPath[this.solvedPath.length-1];if(isNaN(t))throw Error("baobab.Cursor.right: cannot go right on a non-list type.");return t+1===this.up().get().length?null:this.tree.select(this.solvedPath.slice(0,-1).concat(t+1))},r.prototype.rightmost=function(){var t=+this.solvedPath[this.solvedPath.length-1];if(isNaN(t))throw Error("baobab.Cursor.right: cannot go right on a non-list type.");var e=this.up().get();return this.tree.select(this.solvedPath.slice(0,-1).concat(e.length-1))},r.prototype.down=function(){+this.solvedPath[this.solvedPath.length-1];return this.get()instanceof Array?this.tree.select(this.solvedPath.concat(0)):null},r.prototype.get=function(t){return arguments.length>1&&(t=s.arrayOf(arguments)),this.tree.get(a.Step(t)?this.solvedPath.concat(t):this.solvedPath)},r.prototype.set=function(t,e){if(arguments.length<2)throw Error("baobab.Cursor.set: expecting at least key/value.");var r=this.get();if("object"!=typeof r)throw Error("baobab.Cursor.set: trying to set key to a non-object.");var n={};if(a.Array(t)){var o=s.solvePath(r,t);if(!o)throw Error("baobab.Cursor.set: could not solve dynamic path.");n=s.pathObject(o,{$set:e})}else n[t]={$set:e};return this.update(n)},r.prototype.edit=function(t){return this.update({$set:t})},r.prototype.unset=function(t){if(!t&&0!==t)throw Error("baobab.Cursor.unset: expects a valid key to unset.");if("object"!=typeof this.get())throw Error("baobab.Cursor.set: trying to set key to a non-object.");var e={};return e[t]={$unset:!0},this.update(e)},r.prototype.remove=function(){if(this.isRoot())throw Error("baobab.Cursor.remove: cannot remove root node.");return this.update({$unset:!0})},r.prototype.apply=function(t){if("function"!=typeof t)throw Error("baobab.Cursor.apply: argument is not a function.");return this.update({$apply:t})},r.prototype.chain=function(t){if("function"!=typeof t)throw Error("baobab.Cursor.chain: argument is not a function.");return this.update({$chain:t})},r.prototype.push=function(t){if(!(this.get()instanceof Array))throw Error("baobab.Cursor.push: trying to push to non-array value.");return this.update(arguments.length>1?{$push:s.arrayOf(arguments)}:{$push:t})},r.prototype.unshift=function(t){if(!(this.get()instanceof Array))throw Error("baobab.Cursor.push: trying to push to non-array value.");return this.update(arguments.length>1?{$unshift:s.arrayOf(arguments)}:{$unshift:t})},r.prototype.merge=function(t){if(!a.Object(t))throw Error("baobab.Cursor.merge: trying to merge a non-object.");if(!a.Object(this.get()))throw Error("baobab.Cursor.merge: trying to merge into a non-object.");this.update({$merge:t})},r.prototype.update=function(t){return this.tree.update(s.pathObject(this.solvedPath,t)),this},r.prototype.or=function(t){return new o("or",this,t)},r.prototype.and=function(t){return new o("and",this,t)},r.prototype.release=function(){this.tree.off("update",this.updateHandler),this.hash&&delete this.tree._cursors[this.hash],delete this.tree,delete this.path,delete this.solvedPath,this.kill()},r.prototype.toJSON=function(){return this.get()},a.Cursor=function(t){return t instanceof r},e.exports=r},{"./combination.js":5,"./helpers.js":7,"./mixins.js":9,"./type.js":10,emmett:3}],7:[function(t,e){function r(t){return Array.prototype.slice.call(t)}function n(t,e){var r,n={};for(r in t)n[r]=t[r];for(r in e)n[r]=e[r];return n}function o(t){var e=t.source,r="";return t.global&&(r+="g"),t.multiline&&(r+="m"),t.ignoreCase&&(r+="i"),t.sticky&&(r+="y"),t.unicode&&(r+="u"),new RegExp(e,r)}function i(t,e){if(!e||"object"!=typeof e||e instanceof Error||e instanceof ArrayBuffer)return e;if(b.Array(e)){if(t){var r,n,i=[];for(r=0,n=e.length;n>r;r++)i.push(m(e[r]));return i}return e.slice(0)}if(b.Date(e))return new Date(e.getTime());if(e instanceof RegExp)return o(e);if(b.Object(e)){var s,a={};e.constructor&&e.constructor!==Object&&(a=Object.create(e.constructor.prototype));for(s in e)e.hasOwnProperty(s)&&(a[s]=t?m(e[s]):e[s]);return a}return e}function s(t,e){return function(r){return e(t(r))}}function a(t,e){var r,n;for(r=0,n=t.length;n>r;r++)if(e(t[r]))return t[r]}function u(t,e){var r,n;for(r=0,n=t.length;n>r;r++)if(e(t[r]))return r;return-1}function h(t,e){var r,n=!0;if(!t)return!1;for(r in e)if(b.Object(e[r]))n=n&&h(t[r],e[r]);else if(b.Array(e[r]))n=n&&!!~e[r].indexOf(t[r]);else if(t[r]!==e[r])return!1;return n}function c(t,e){return a(t,function(t){return h(t,e)})}function l(t,e){return u(t,function(t){return h(t,e)})}function f(t,e){e=e||[];var r,n,o=t;for(r=0,n=e.length;n>r;r++){if(!o)return;if("function"==typeof e[r]){if(!b.Array(o))return;o=a(o,e[r])}else if("object"==typeof e[r]){if(!b.Array(o))return;o=c(o,e[r])}else o=o[e[r]]}return o}function p(t,e){var r,n,o,i=[],s=t;for(n=0,o=e.length;o>n;n++){if(!s)return null;if("function"==typeof e[n]){if(!b.Array(s))return;r=u(s,e[n]),i.push(r),s=s[r]}else if("object"==typeof e[n]){if(!b.Array(s))return;r=l(s,e[n]),i.push(r),s=s[r]}else i.push(e[n]),s=s[e[n]]||{}}return i}function d(t,e){var r,n=t.length,o={},i=o;for(n||(o=e),r=0;n>r;r++)i[t[r]]=r+1===n?e:{},i=i[t[r]];return o}function y(t,e){t.super_=e;var r=function(){};r.prototype=e.prototype,t.prototype=new r,t.prototype.constructor=t}var b=t("./type.js"),g=i.bind(null,!1),m=i.bind(null,!0);e.exports={arrayOf:r,deepClone:m,shallowClone:g,shallowMerge:n,compose:s,getIn:f,inherits:y,pathObject:d,solvePath:p}},{"./type.js":10}],8:[function(t,e){function r(t,e){return e in(t||{})}function n(t,e,n){return r(t,n)&&r(e,n)}function o(){var t,e,r,a,u={},h=arguments.length;for(r=h-1;r>=0;r--){if(arguments[r].$unset)delete u.$set,delete u.$apply,delete u.$merge,u.$unset=arguments[r].$unset;else{if(arguments[r].$set){delete u.$apply,delete u.$merge,delete u.$unset,u.$set=arguments[r].$set;continue}if(arguments[r].$merge){delete u.$set,delete u.$apply,delete u.$unset,u.$merge=arguments[r].$merge;continue}if(arguments[r].$apply){delete u.$set,delete u.$merge,delete u.$unset,u.$apply=arguments[r].$apply;continue}if(arguments[r].$chain){delete u.$set,delete u.$merge,delete u.$unset,u.$apply=u.$apply?i.compose(u.$apply,arguments[r].$chain):arguments[r].$chain;continue}}for(a in arguments[r])t=u[a],e=arguments[r][a],t&&s.Object(e)?n(t,e,"$push")?t.$push=s.Array(t.$push)?t.$push.concat(e.$push):[t.$push].concat(e.$push):n(t,e,"$unshift")?t.$unshift=s.Array(e.$unshift)?e.$unshift.concat(t.$unshift):[e.$unshift].concat(t.$unshift):u[a]=o(e,t):u[a]=e}return u}var i=t("./helpers.js"),s=t("./type.js");e.exports=o},{"./helpers.js":7,"./type.js":10}],9:[function(t,e){var r=t("./combination.js"),n=t("./type.js");e.exports={baobab:function(t){return{mixins:[{getInitialState:function(){if(this.tree=t,!this.cursor&&!this.cursors)return{};if(this.cursor&&this.cursors)throw Error("baobab.mixin: you cannot have both `component.cursor` and `component.cursors`. Please make up your mind.");if(this.__type=null,this.__updateHandler=function(){this.setState(this.__getCursorData())}.bind(this),this.cursor){if(!n.MixinCursor(this.cursor))throw Error("baobab.mixin.cursor: invalid data (cursor, string, array or function).");n.Function(this.cursor)&&(this.cursor=this.cursor()),n.Cursor(this.cursor)||(this.cursor=t.select(this.cursor)),this.__getCursorData=function(){return{cursor:this.cursor.get()}}.bind(this),this.__type="single"}else if(this.cursors){if(!n.MixinCursors(this.cursors))throw Error("baobab.mixin.cursor: invalid data (object, array or function).");if(n.Function(this.cursors)&&(this.cursors=this.cursors()),n.Array(this.cursors))this.cursors=this.cursors.map(function(e){return n.Cursor(e)?e:t.select(e)}),this.__getCursorData=function(){return{cursors:this.cursors.map(function(t){return t.get()})}}.bind(this),this.__type="array";else{for(var e in this.cursors)n.Cursor(this.cursors[e])||(this.cursors[e]=t.select(this.cursors[e]));this.__getCursorData=function(){var t={};for(e in this.cursors)t[e]=this.cursors[e].get();return{cursors:t}}.bind(this),this.__type="object"}}return this.__getCursorData()},componentDidMount:function(){"single"===this.__type?(this.__combination=new r("or",[this.cursor]),this.__combination.on("update",this.__updateHandler)):"array"===this.__type?(this.__combination=new r("or",this.cursors),this.__combination.on("update",this.__updateHandler)):"object"===this.__type&&(this.__combination=new r("or",Object.keys(this.cursors).map(function(t){return this.cursors[t]},this)),this.__combination.on("update",this.__updateHandler))},componentWillUnmount:function(){this.__combination&&this.__combination.release()}}].concat(t.options.mixins)}},cursor:function(t){return{mixins:[{getInitialState:function(){return this.cursor=t,this.__updateHandler=function(){this.setState({cursor:this.cursor.get()})}.bind(this),{cursor:this.cursor.get()}},componentDidMount:function(){this.cursor.on("update",this.__updateHandler)},componentWillUnmount:function(){this.cursor.off("update",this.__updateHandler)}}].concat(t.tree.options.mixins)}}}},{"./combination.js":5,"./type.js":10}],10:[function(t,e){var r=function(t){return Array.isArray(t)?"array":"object"==typeof t&&null!==t?"object":"string"==typeof t?"string":"number"==typeof t?"number":"boolean"==typeof t?"boolean":"function"==typeof t?"function":null===t?"null":void 0===t?"undefined":t instanceof Date?"date":"invalid"};r.Array=function(t){return Array.isArray(t)},r.Object=function(t){return!Array.isArray(t)&&"object"==typeof t&&null!==t},r.String=function(t){return"string"==typeof t},r.Number=function(t){return"number"==typeof t},r.Boolean=function(t){return"boolean"==typeof t},r.Function=function(t){return"function"==typeof t},r.Primitive=function(t){return"string"==typeof t||"number"==typeof t||"boolean"==typeof t},r.Date=function(t){return t instanceof Date},r.Step=function(t){var e=r(t),n=["null","undefined","invalid","date"];return-1===n.indexOf(e)},r.Path=function(t){var e=["object","string","number","function","undefined"];if(!r.Array(t))return e.indexOf(r(t))>=0;for(var n=0;n=0||r.Cursor(t)},r.MixinCursors=function(t){var e=["array","object","function"];return e.indexOf(r(t))>=0},r.ComplexPath=function(t){for(var e=["object","function"],n=0;n=0)return!0;return!1},e.exports=r},{}],11:[function(t,e){function r(t,e){var r=new Error("baobab.update: "+e+" at path /"+t.toString());return r.path=t,r}function n(t,e,n){n=n||{shiftReferences:!1};var a={};return function u(t,e,h,c){h=h||[];var l,f,p,d,y=h.join("λ");for(p in e)if(s[p])switch(d=e[p],a[y]=!0,p){case"$push":if(!i.Array(t))throw r(h,"using command $push to a non array");i.Array(d)?t.push.apply(t,d):t.push(d);break;case"$unshift":if(!i.Array(t))throw r(h,"using command $unshift to a non array");i.Array(d)?t.unshift.apply(t,d):t.unshift(d)}else if(f=y?y+"λ"+p:p,"$unset"in(e[p]||{}))a[f]=!0,i.Array(t)?n.shiftReferences?c[h[h.length-1]]=t.slice(0,+p).concat(t.slice(+p+1)):t.splice(p,1):delete t[p];else if("$set"in(e[p]||{}))d=e[p].$set,a[f]=!0,t[p]=d;else if("$apply"in(e[p]||{})||"$chain"in(e[p]||{})){if(l=e[p].$apply||e[p].$chain,"function"!=typeof l)throw r(h.concat(p),"using command $apply with a non function");a[f]=!0,t[p]=l.call(null,t[p])}else if("$merge"in(e[p]||{})){if(d=e[p].$merge,!i.Object(t[p]))throw r(h.concat(p),"using command $merge on a non-object");a[f]=!0,t[p]=o.shallowMerge(t[p],d)}else if(n.shiftReferences&&("$push"in(e[p]||{})||"$unshift"in(e[p]||{}))){if("$push"in(e[p]||{})){if(d=e[p].$push,!i.Array(t[p]))throw r(h.concat(p),"using command $push to a non array");t[p]=t[p].concat(d)}if("$unshift"in(e[p]||{})){if(d=e[p].$unshift,!i.Array(t[p]))throw r(h.concat(p),"using command $unshift to a non array");t[p]=(d instanceof Array?d:[d]).concat(t[p])}a[f]=!0}else"undefined"==typeof t[p]&&(t[p]={}),n.shiftReferences&&(t[p]=o.shallowClone(t[p])),u(t[p],e[p],h.concat(p),t)}(t,e),Object.keys(a).map(function(t){return t.split("λ")})}var o=t("./helpers.js"),i=t("./type.js"),s={};["$set","$push","$unshift","$apply","$merge"].forEach(function(t){s[t]=!0}),e.exports=n},{"./helpers.js":7,"./type.js":10}]},{},[2])(2)}); \ No newline at end of file +!function(t){if("object"==typeof exports&&"undefined"!=typeof module)module.exports=t();else if("function"==typeof define&&define.amd)define([],t);else{var e;e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:this,e.Baobab=t()}}(function(){var t;return function e(t,r,n){function o(s,a){if(!r[s]){if(!t[s]){var u="function"==typeof require&&require;if(!a&&u)return u(s,!0);if(i)return i(s,!0);var h=new Error("Cannot find module '"+s+"'");throw h.code="MODULE_NOT_FOUND",h}var c=r[s]={exports:{}};t[s][0].call(c.exports,function(e){var r=t[s][1][e];return o(r?r:e)},c,c.exports,e,t,r,n)}return r[s].exports}for(var i="function"==typeof require&&require,s=0;se;e++)n.push(t[e].handler);return n}var o={once:"boolean",scope:"object"},i=function(){this._enabled=!0,this._children=[],this._handlers={},this._handlersAll=[]};i.prototype.on=function(t,e,r){var n,s,a,u,h,c;if("function"==typeof e){for(h="string"==typeof t?[t]:t,n=0,s=h.length;n!==s;n+=1)if(u=h[n]){this._handlers[u]||(this._handlers[u]=[]),c={handler:e};for(a in r||{}){if(!o[a])throw new Error('The option "'+a+'" is not recognized by Emmett.');c[a]=r[a]}this._handlers[u].push(c)}}else if(t&&"object"==typeof t&&!Array.isArray(t))for(u in t)i.prototype.on.call(this,u,t[u],e);else{if("function"!=typeof t)throw new Error("Wrong arguments.");c={handler:t};for(a in r||{}){if(!o[a])throw new Error('The option "'+a+'" is not recognized by Emmett.');c[a]=r[a]}this._handlersAll.push(c)}return this},i.prototype.once=function(t,e,r){if("function"==typeof e)r=r||{},r.once=!0,this.on(t,e,r);else{if((!t||"object"!=typeof t||Array.isArray(t))&&"function"!=typeof t)throw new Error("Wrong arguments.");e=e||{},e.once=!0,this.on(t,e)}return this},i.prototype.off=function(t,e){var r,n,o,i,s,a,u,h="string"==typeof t?[t]:t;if(1===arguments.length&&"function"==typeof h){e=arguments[0];for(s in this._handlers){for(a=[],r=0,n=this._handlers[s].length;r!==n;r+=1)this._handlers[s][r].handler!==e&&a.push(this._handlers[s][r]);this._handlers[s]=a}for(a=[],r=0,n=this._handlersAll.length;r!==n;r+=1)this._handlersAll[r].handler!==e&&a.push(this._handlersAll[r]);this._handlersAll=a}else if(2===arguments.length)for(r=0,n=h.length;r!==n;r+=1){if(u=h[r],this._handlers[u]){for(a=[],o=0,i=this._handlers[u].length;o!==i;o+=1)this._handlers[u][o].handler!==e&&a.push(this._handlers[u][o]);this._handlers[u]=a}this._handlers[u]&&0===this._handlers[u].length&&delete this._handlers[u]}return this},i.prototype.unbindAll=function(){var t;this._handlersAll=[];for(t in this._handlers)delete this._handlers[t];return this},i.prototype.emit=function(t,e){var r,n,o,i,s,a,u,h,c,l,f="string"==typeof t?[t]:t;if(!this._enabled)return this;for(e=void 0===e?{}:e,r=0,n=f.length;r!==n;r+=1)if(l=f[r],c=(this._handlers[l]||[]).concat(this._handlersAll),c.length){for(u={type:l,data:e||{},target:this},a=[],o=0,i=c.length;o!==i;o+=1)(this._handlers[l]&&this._handlers[l].indexOf(c[o])>=0||this._handlersAll.indexOf(c[o])>=0)&&(c[o].handler.call("scope"in c[o]?c[o].scope:this,u),c[o].once&&a.push(c[o]));for(s=0;sr;r++)if(t._children[r]===e){t._children.splice(r,1);break}}),this._children.push(e),e},i.prototype.listeners=function(t){var r,n,o,i=[];if(t)for(i=e(this._handlers[t]),n=0,o=this._children.length;o>n;n++)i=i.concat(this._children[n].listeners(t));else{i=e(this._handlersAll);for(r in this._handlers)i=i.concat(e(this._handlers[r]));for(n=0,o=this._children.length;o>n;n++)i=i.concat(this._children[n].listeners())}return i},i.prototype.kill=function(){if(this.emit("emmett:kill"),this.unbindAll(),this._handlers=null,this._handlersAll=null,this._enabled=!1,this._children)for(var t=0,e=this._children.length;e>t;t++)this._children[t].kill();this._children=null},i.prototype.disable=function(){return this._enabled=!1,this},i.prototype.enable=function(){return this._enabled=!0,this},i.version="2.1.2","undefined"!=typeof n?("undefined"!=typeof r&&r.exports&&(n=r.exports=i),n.Emitter=i):"function"==typeof t&&t.amd?t("emmett",[],function(){return i}):this.Emitter=i}).call(this)},{}],4:[function(t,e){function r(t){return t+"$"+(new Date).getTime()+(""+Math.random()).replace("0.","")}function n(t,e){function r(t){this[t]=function(){var e=this.root[t].apply(this.root,arguments);return e instanceof o?this:e}}if(arguments.length<1&&(t={}),!(this instanceof n))return new n(t,e);if(!l.Object(t)&&!l.Array(t))throw Error("Baobab: invalid data.");i.call(this),this.options=s.shallowMerge(c,e),this._transaction={},this._future=void 0,this._cursors={},this.data=s.deepClone(t),this.root=this.select([]),["get","set","unset","update"].forEach(r.bind(this)),this.mixin=h.baobab(this)}var o=t("./cursor.js"),i=t("emmett"),s=t("./helpers.js"),a=t("./update.js"),u=t("./merge.js"),h=t("./mixins.js"),c=t("../defaults.js"),l=t("./type.js");s.inherits(n,i),n.prototype.select=function(t){if(!t)throw Error("Baobab.select: invalid path.");if(arguments.length>1&&(t=s.arrayOf(arguments)),!l.Path(t))throw Error("Baobab.select: invalid path.");t=l.Array(t)?t:[t];var e,n=l.ComplexPath(t);n&&(e=s.solvePath(this.data,t));var i=t.map(function(t){return l.Function(t)?r("fn"):l.Object(t)?r("ob"):t}).join("λ");if(this._cursors[i])return this._cursors[i];var a=new o(this,t,e,i);return this._cursors[i]=a,a},n.prototype.stack=function(t){var e=this;if(!l.Object(t))throw Error("Baobab.update: wrong specification.");return this._transaction=u(t,this._transaction),this.options.autoCommit?this.options.asynchronous?(this._future||(this._future=setTimeout(e.commit.bind(e,null),0)),this):this.commit():this},n.prototype.commit=function(){this.options.shiftReferences&&(this.data=s.shallowClone(this.data));var t=a(this.data,this._transaction,this.options);return this._transaction={},this._future&&(this._future=clearTimeout(this._future)),this.emit("update",{log:t}),this},n.prototype.release=function(){delete this.data,delete this._transaction;for(var t in this._cursors)this._cursors[t].release();delete this._cursors,this.kill()},n.prototype.toJSON=function(){return this.get()},e.exports=n},{"../defaults.js":1,"./cursor.js":6,"./helpers.js":7,"./merge.js":8,"./mixins.js":9,"./type.js":10,"./update.js":11,emmett:3}],5:[function(t,e){function r(t,e){e.on("update",t.cursorListener),t.tree.off("update",t.treeListener),t.tree.on("update",t.treeListener)}function n(t){var e=this;if(arguments.length<2)throw Error("baobab.Combination: not enough arguments.");var n=arguments[1],o=s.arrayOf(arguments).slice(2);if(n instanceof Array&&(o=n.slice(1),n=n[0]),!a.Cursor(n))throw Error("baobab.Combination: argument should be a cursor.");if("or"!==t&&"and"!==t)throw Error("baobab.Combination: invalid operator.");i.call(this),this.cursors=[n],this.operators=[],this.tree=n.tree,this.updates=new Array(this.cursors.length),this.cursorListener=function(){e.updates[e.cursors.indexOf(this)]=!0},this.treeListener=function(){var t,r,n=e.updates[0];for(t=1,r=e.cursors.length;r>t;t++)n="or"===e.operators[t-1]?n||e.updates[t]:n&&e.updates[t];n&&e.emit("update"),e.updates=new Array(e.cursors.length)},this.bound=!1;var u=this.on,h=this.once,c=function(){e.bound||(e.bound=!0,e.cursors.forEach(function(t){r(e,t)}))};this.on=function(){return c(),u.apply(this,arguments)},this.once=function(){return c(),h.apply(this,arguments)},o.forEach(function(e){this[t](e)},this)}function o(t){n.prototype[t]=function(e){if(!a.Cursor(e))throw this.release(),Error("baobab.Combination."+t+": argument should be a cursor.");if(~this.cursors.indexOf(e))throw this.release(),Error("baobab.Combination."+t+": cursor already in combination.");return this.cursors.push(e),this.operators.push(t),this.updates.length++,this.bound&&r(this,e),this}}var i=t("emmett"),s=t("./helpers.js"),a=t("./type.js");s.inherits(n,i),o("or"),o("and"),n.prototype.release=function(){this.cursors.forEach(function(t){t.off("update",this.cursorListener)},this),this.tree.off("update",this.treeListener),this.cursors=null,this.operators=null,this.tree=null,this.updates=null,this.kill()},e.exports=n},{"./helpers.js":7,"./type.js":10,emmett:3}],6:[function(t,e){function r(t,e,r,o){var a=this;n.call(this),e=e||[],this.tree=t,this.path=e,this.hash=o,this.complexPath=!!r,this.solvedPath=this.complexPath?r:this.path,this.relevant=void 0!==this.get(),this.updateHandler=function(t){var e,r,n,o,i,u,h=t.data.log,c=!1;if(a.complexPath&&(a.solvedPath=s.solvePath(a.tree.data,a.path)),!a.path.length)return a.emit("update");t:for(i=0,n=h.length;n>i;i++)for(e=h[i],u=0,o=e.length;o>u&&(r=e[u],r===""+a.solvedPath[u]);u++)if(u+1===o||u+1===a.solvedPath.length){c=!0;break t}var l=void 0!==a.get();a.relevant?l&&c?a.emit("update"):l||(a.emit("irrelevant"),a.relevant=!1):l&&c&&(a.emit("relevant"),a.emit("update"),a.relevant=!0)},this.mixin=i.cursor(this);var u=!1,h=this.on,c=this.once,l=function(){u||(u=!0,a.tree.on("update",a.updateHandler))};this.on=function(){return l(),h.apply(this,arguments)},this.once=function(){return l(),c.apply(this,arguments)}}var n=t("emmett"),o=t("./combination.js"),i=t("./mixins.js"),s=t("./helpers.js"),a=t("./type.js");s.inherits(r,n),r.prototype.isRoot=function(){return!this.path.length},r.prototype.isLeaf=function(){return a.Primitive(this.get())},r.prototype.isBranch=function(){return!this.isLeaf()&&!this.isRoot()},r.prototype.root=function(){return this.tree.root()},r.prototype.select=function(t){if(arguments.length>1&&(t=s.arrayOf(arguments)),!a.Path(t))throw Error("baobab.Cursor.select: invalid path.");return this.tree.select(this.path.concat(t))},r.prototype.up=function(){return this.solvedPath&&this.solvedPath.length?this.tree.select(this.path.slice(0,-1)):null},r.prototype.left=function(){var t=+this.solvedPath[this.solvedPath.length-1];if(isNaN(t))throw Error("baobab.Cursor.left: cannot go left on a non-list type.");return t?this.tree.select(this.solvedPath.slice(0,-1).concat(t-1)):null},r.prototype.leftmost=function(){var t=+this.solvedPath[this.solvedPath.length-1];if(isNaN(t))throw Error("baobab.Cursor.leftmost: cannot go left on a non-list type.");return this.tree.select(this.solvedPath.slice(0,-1).concat(0))},r.prototype.right=function(){var t=+this.solvedPath[this.solvedPath.length-1];if(isNaN(t))throw Error("baobab.Cursor.right: cannot go right on a non-list type.");return t+1===this.up().get().length?null:this.tree.select(this.solvedPath.slice(0,-1).concat(t+1))},r.prototype.rightmost=function(){var t=+this.solvedPath[this.solvedPath.length-1];if(isNaN(t))throw Error("baobab.Cursor.right: cannot go right on a non-list type.");var e=this.up().get();return this.tree.select(this.solvedPath.slice(0,-1).concat(e.length-1))},r.prototype.down=function(){+this.solvedPath[this.solvedPath.length-1];return this.get()instanceof Array?this.tree.select(this.solvedPath.concat(0)):null},r.prototype.get=function(t){arguments.length>1&&(t=s.arrayOf(arguments));var e=this.solvedPath.concat((a.String(t)||a.Number(t)?[t]:t)||[]);return s.getIn(this.tree.data,e)},r.prototype.set=function(t,e){if(arguments.length<2)throw Error("baobab.Cursor.set: expecting at least key/value.");var r=this.get();if("object"!=typeof r)throw Error("baobab.Cursor.set: trying to set key to a non-object.");var n={};if(a.Array(t)){var o=s.solvePath(r,t);if(!o)throw Error("baobab.Cursor.set: could not solve dynamic path.");n=s.pathObject(o,{$set:e})}else n[t]={$set:e};return this.update(n)},r.prototype.edit=function(t){return this.update({$set:t})},r.prototype.unset=function(t){if(!t&&0!==t)throw Error("baobab.Cursor.unset: expects a valid key to unset.");if("object"!=typeof this.get())throw Error("baobab.Cursor.set: trying to set key to a non-object.");var e={};return e[t]={$unset:!0},this.update(e)},r.prototype.remove=function(){if(this.isRoot())throw Error("baobab.Cursor.remove: cannot remove root node.");return this.update({$unset:!0})},r.prototype.apply=function(t){if("function"!=typeof t)throw Error("baobab.Cursor.apply: argument is not a function.");return this.update({$apply:t})},r.prototype.chain=function(t){if("function"!=typeof t)throw Error("baobab.Cursor.chain: argument is not a function.");return this.update({$chain:t})},r.prototype.push=function(t){if(!(this.get()instanceof Array))throw Error("baobab.Cursor.push: trying to push to non-array value.");return this.update(arguments.length>1?{$push:s.arrayOf(arguments)}:{$push:t})},r.prototype.unshift=function(t){if(!(this.get()instanceof Array))throw Error("baobab.Cursor.push: trying to push to non-array value.");return this.update(arguments.length>1?{$unshift:s.arrayOf(arguments)}:{$unshift:t})},r.prototype.merge=function(t){if(!a.Object(t))throw Error("baobab.Cursor.merge: trying to merge a non-object.");if(!a.Object(this.get()))throw Error("baobab.Cursor.merge: trying to merge into a non-object.");this.update({$merge:t})},r.prototype.update=function(t){return this.tree.stack(s.pathObject(this.solvedPath,t)),this},r.prototype.or=function(t){return new o("or",this,t)},r.prototype.and=function(t){return new o("and",this,t)},r.prototype.release=function(){this.tree.off("update",this.updateHandler),this.hash&&delete this.tree._cursors[this.hash],delete this.tree,delete this.path,delete this.solvedPath,this.kill()},r.prototype.toJSON=function(){return this.get()},a.Cursor=function(t){return t instanceof r},e.exports=r},{"./combination.js":5,"./helpers.js":7,"./mixins.js":9,"./type.js":10,emmett:3}],7:[function(t,e){function r(t){return Array.prototype.slice.call(t)}function n(t,e){var r,n={};for(r in t)n[r]=t[r];for(r in e)n[r]=e[r];return n}function o(t){var e=t.source,r="";return t.global&&(r+="g"),t.multiline&&(r+="m"),t.ignoreCase&&(r+="i"),t.sticky&&(r+="y"),t.unicode&&(r+="u"),new RegExp(e,r)}function i(t,e){if(!e||"object"!=typeof e||e instanceof Error||e instanceof ArrayBuffer)return e;if(g.Array(e)){if(t){var r,n,i=[];for(r=0,n=e.length;n>r;r++)i.push(m(e[r]));return i}return e.slice(0)}if(g.Date(e))return new Date(e.getTime());if(e instanceof RegExp)return o(e);if(g.Object(e)){var s,a={};e.constructor&&e.constructor!==Object&&(a=Object.create(e.constructor.prototype));for(s in e)e.hasOwnProperty(s)&&(a[s]=t?m(e[s]):e[s]);return a}return e}function s(t,e){return function(r){return e(t(r))}}function a(t,e){var r,n;for(r=0,n=t.length;n>r;r++)if(e(t[r]))return t[r]}function u(t,e){var r,n;for(r=0,n=t.length;n>r;r++)if(e(t[r]))return r;return-1}function h(t,e){var r,n=!0;if(!t)return!1;for(r in e)if(g.Object(e[r]))n=n&&h(t[r],e[r]);else if(g.Array(e[r]))n=n&&!!~e[r].indexOf(t[r]);else if(t[r]!==e[r])return!1;return n}function c(t,e){return a(t,function(t){return h(t,e)})}function l(t,e){return u(t,function(t){return h(t,e)})}function f(t,e){e=e||[];var r,n,o=t;for(r=0,n=e.length;n>r;r++){if(!o)return;if("function"==typeof e[r]){if(!g.Array(o))return;o=a(o,e[r])}else if("object"==typeof e[r]){if(!g.Array(o))return;o=c(o,e[r])}else o=o[e[r]]}return o}function p(t,e){var r,n,o,i=[],s=t;for(n=0,o=e.length;o>n;n++){if(!s)return null;if("function"==typeof e[n]){if(!g.Array(s))return;r=u(s,e[n]),i.push(r),s=s[r]}else if("object"==typeof e[n]){if(!g.Array(s))return;r=l(s,e[n]),i.push(r),s=s[r]}else i.push(e[n]),s=s[e[n]]||{}}return i}function d(t,e){var r,n=t.length,o={},i=o;for(n||(o=e),r=0;n>r;r++)i[t[r]]=r+1===n?e:{},i=i[t[r]];return o}function y(t,e){t.super_=e;var r=function(){};r.prototype=e.prototype,t.prototype=new r,t.prototype.constructor=t}var g=t("./type.js"),b=i.bind(null,!1),m=i.bind(null,!0);e.exports={arrayOf:r,deepClone:m,shallowClone:b,shallowMerge:n,compose:s,getIn:f,inherits:y,pathObject:d,solvePath:p}},{"./type.js":10}],8:[function(t,e){function r(t,e){return e in(t||{})}function n(t,e,n){return r(t,n)&&r(e,n)}function o(){var t,e,r,a,u={},h=arguments.length;for(r=h-1;r>=0;r--){if(arguments[r].$unset)delete u.$set,delete u.$apply,delete u.$merge,u.$unset=arguments[r].$unset;else{if(arguments[r].$set){delete u.$apply,delete u.$merge,delete u.$unset,u.$set=arguments[r].$set;continue}if(arguments[r].$merge){delete u.$set,delete u.$apply,delete u.$unset,u.$merge=arguments[r].$merge;continue}if(arguments[r].$apply){delete u.$set,delete u.$merge,delete u.$unset,u.$apply=arguments[r].$apply;continue}if(arguments[r].$chain){delete u.$set,delete u.$merge,delete u.$unset,u.$apply=u.$apply?i.compose(u.$apply,arguments[r].$chain):arguments[r].$chain;continue}}for(a in arguments[r])t=u[a],e=arguments[r][a],t&&s.Object(e)?n(t,e,"$push")?t.$push=s.Array(t.$push)?t.$push.concat(e.$push):[t.$push].concat(e.$push):n(t,e,"$unshift")?t.$unshift=s.Array(e.$unshift)?e.$unshift.concat(t.$unshift):[e.$unshift].concat(t.$unshift):u[a]=o(e,t):u[a]=e}return u}var i=t("./helpers.js"),s=t("./type.js");e.exports=o},{"./helpers.js":7,"./type.js":10}],9:[function(t,e){var r=t("./combination.js"),n=t("./type.js");e.exports={baobab:function(t){return{mixins:[{getInitialState:function(){if(this.tree=t,!this.cursor&&!this.cursors)return{};if(this.cursor&&this.cursors)throw Error("baobab.mixin: you cannot have both `component.cursor` and `component.cursors`. Please make up your mind.");if(this.__type=null,this.__updateHandler=function(){this.setState(this.__getCursorData())}.bind(this),this.cursor){if(!n.MixinCursor(this.cursor))throw Error("baobab.mixin.cursor: invalid data (cursor, string, array or function).");n.Function(this.cursor)&&(this.cursor=this.cursor()),n.Cursor(this.cursor)||(this.cursor=t.select(this.cursor)),this.__getCursorData=function(){return{cursor:this.cursor.get()}}.bind(this),this.__type="single"}else if(this.cursors){if(!n.MixinCursors(this.cursors))throw Error("baobab.mixin.cursor: invalid data (object, array or function).");if(n.Function(this.cursors)&&(this.cursors=this.cursors()),n.Array(this.cursors))this.cursors=this.cursors.map(function(e){return n.Cursor(e)?e:t.select(e)}),this.__getCursorData=function(){return{cursors:this.cursors.map(function(t){return t.get()})}}.bind(this),this.__type="array";else{for(var e in this.cursors)n.Cursor(this.cursors[e])||(this.cursors[e]=t.select(this.cursors[e]));this.__getCursorData=function(){var t={};for(e in this.cursors)t[e]=this.cursors[e].get();return{cursors:t}}.bind(this),this.__type="object"}}return this.__getCursorData()},componentDidMount:function(){"single"===this.__type?(this.__combination=new r("or",[this.cursor]),this.__combination.on("update",this.__updateHandler)):"array"===this.__type?(this.__combination=new r("or",this.cursors),this.__combination.on("update",this.__updateHandler)):"object"===this.__type&&(this.__combination=new r("or",Object.keys(this.cursors).map(function(t){return this.cursors[t]},this)),this.__combination.on("update",this.__updateHandler))},componentWillUnmount:function(){this.__combination&&this.__combination.release()}}].concat(t.options.mixins)}},cursor:function(t){return{mixins:[{getInitialState:function(){return this.cursor=t,this.__updateHandler=function(){this.setState({cursor:this.cursor.get()})}.bind(this),{cursor:this.cursor.get()}},componentDidMount:function(){this.cursor.on("update",this.__updateHandler)},componentWillUnmount:function(){this.cursor.off("update",this.__updateHandler)}}].concat(t.tree.options.mixins)}}}},{"./combination.js":5,"./type.js":10}],10:[function(t,e){var r=function(t){return Array.isArray(t)?"array":"object"==typeof t&&null!==t?"object":"string"==typeof t?"string":"number"==typeof t?"number":"boolean"==typeof t?"boolean":"function"==typeof t?"function":null===t?"null":void 0===t?"undefined":t instanceof Date?"date":"invalid"};r.Array=function(t){return Array.isArray(t)},r.Object=function(t){return!Array.isArray(t)&&"object"==typeof t&&null!==t},r.String=function(t){return"string"==typeof t},r.Number=function(t){return"number"==typeof t},r.Boolean=function(t){return"boolean"==typeof t},r.Function=function(t){return"function"==typeof t},r.Primitive=function(t){return"string"==typeof t||"number"==typeof t||"boolean"==typeof t},r.Date=function(t){return t instanceof Date},r.Step=function(t){var e=r(t),n=["null","undefined","invalid","date"];return-1===n.indexOf(e)},r.Path=function(t){var e=["object","string","number","function","undefined"];if(!r.Array(t))return e.indexOf(r(t))>=0;for(var n=0;n=0||r.Cursor(t)},r.MixinCursors=function(t){var e=["array","object","function"];return e.indexOf(r(t))>=0},r.ComplexPath=function(t){for(var e=["object","function"],n=0;n=0)return!0;return!1},e.exports=r},{}],11:[function(t,e){function r(t,e){var r=new Error("baobab.update: "+e+" at path /"+t.toString());return r.path=t,r}function n(t,e,n){n=n||{shiftReferences:!1};var a={};return function u(t,e,h,c){h=h||[];var l,f,p,d,y=h.join("λ");for(p in e)if(s[p])switch(d=e[p],a[y]=!0,p){case"$push":if(!i.Array(t))throw r(h,"using command $push to a non array");i.Array(d)?t.push.apply(t,d):t.push(d);break;case"$unshift":if(!i.Array(t))throw r(h,"using command $unshift to a non array");i.Array(d)?t.unshift.apply(t,d):t.unshift(d)}else if(f=y?y+"λ"+p:p,"$unset"in(e[p]||{}))a[f]=!0,i.Array(t)?n.shiftReferences?c[h[h.length-1]]=t.slice(0,+p).concat(t.slice(+p+1)):t.splice(p,1):delete t[p];else if("$set"in(e[p]||{}))d=e[p].$set,a[f]=!0,t[p]=d;else if("$apply"in(e[p]||{})||"$chain"in(e[p]||{})){if(l=e[p].$apply||e[p].$chain,"function"!=typeof l)throw r(h.concat(p),"using command $apply with a non function");a[f]=!0,t[p]=l.call(null,t[p])}else if("$merge"in(e[p]||{})){if(d=e[p].$merge,!i.Object(t[p]))throw r(h.concat(p),"using command $merge on a non-object");a[f]=!0,t[p]=o.shallowMerge(t[p],d)}else if(n.shiftReferences&&("$push"in(e[p]||{})||"$unshift"in(e[p]||{}))){if("$push"in(e[p]||{})){if(d=e[p].$push,!i.Array(t[p]))throw r(h.concat(p),"using command $push to a non array");t[p]=t[p].concat(d)}if("$unshift"in(e[p]||{})){if(d=e[p].$unshift,!i.Array(t[p]))throw r(h.concat(p),"using command $unshift to a non array");t[p]=(d instanceof Array?d:[d]).concat(t[p])}a[f]=!0}else"undefined"==typeof t[p]&&(t[p]={}),n.shiftReferences&&(t[p]=o.shallowClone(t[p])),u(t[p],e[p],h.concat(p),t)}(t,e),Object.keys(a).map(function(t){return t.split("λ")})}var o=t("./helpers.js"),i=t("./type.js"),s={};["$set","$push","$unshift","$apply","$merge"].forEach(function(t){s[t]=!0}),e.exports=n},{"./helpers.js":7,"./type.js":10}]},{},[2])(2)}); \ No newline at end of file diff --git a/src/baobab.js b/src/baobab.js index 455092d..8db1484 100644 --- a/src/baobab.js +++ b/src/baobab.js @@ -45,6 +45,17 @@ function Baobab(initialData, opts) { // Properties this.data = helpers.deepClone(initialData); + this.root = this.select([]); + + // Boostrapping root cursor's methods + function bootstrap(name) { + this[name] = function() { + var r = this.root[name].apply(this.root, arguments); + return r instanceof Cursor ? this : r; + }; + } + + ['get', 'set', 'unset', 'update'].forEach(bootstrap.bind(this)); // Mixin this.mixin = mixins.baobab(this); @@ -55,30 +66,6 @@ helpers.inherits(Baobab, EventEmitter); /** * Prototype */ -Baobab.prototype.commit = function() { - var self = this; - - // Shifting root reference - if (this.options.shiftReferences) - this.data = helpers.shallowClone(this.data); - - // Applying modification (mutation) - var log = update(this.data, this._transaction, this.options); - - // Resetting - this._transaction = {}; - - if (this._future) - this._future = clearTimeout(this._future); - - // Baobab-level update event - this.emit('update', { - log: log - }); - - return this; -}; - Baobab.prototype.select = function(path) { if (!path) throw Error('Baobab.select: invalid path.'); @@ -120,57 +107,7 @@ Baobab.prototype.select = function(path) { } }; -Baobab.prototype.root = function() { - return this.select([]); -}; - -Baobab.prototype.get = function(path) { - var data; - - if (arguments.length > 1) - path = helpers.arrayOf(arguments); - - if (!type.Path(path)) - throw Error('Baobab.get: invalid path.'); - - return helpers.getIn( - this.data, type.String(path) || type.Number(path) ? [path] : path - ); -}; - -Baobab.prototype.set = function(key, val) { - - if (arguments.length < 2) - throw Error('Baobab.set: expects a key and a value.'); - - var spec = {}; - - if (type.Array(key)) { - var path = helpers.solvePath(this.data, key); - - if (!path) - throw Error('Baobab.set: could not solve dynamic path.'); - - spec = helpers.pathObject(path, {$set: val}); - } - else { - spec[key] = {$set: val}; - } - - return this.update(spec); -}; - -Baobab.prototype.unset = function(key) { - if (!key && key !== 0) - throw Error('Baobab.unset: expects a valid key to unset.'); - - var spec = {}; - spec[key] = {$unset: true}; - - return this.update(spec); -}; - -Baobab.prototype.update = function(spec) { +Baobab.prototype.stack = function(spec) { var self = this; if (!type.Object(spec)) @@ -193,6 +130,30 @@ Baobab.prototype.update = function(spec) { return this; }; +Baobab.prototype.commit = function() { + var self = this; + + // Shifting root reference + if (this.options.shiftReferences) + this.data = helpers.shallowClone(this.data); + + // Applying modification (mutation) + var log = update(this.data, this._transaction, this.options); + + // Resetting + this._transaction = {}; + + if (this._future) + this._future = clearTimeout(this._future); + + // Baobab-level update event + this.emit('update', { + log: log + }); + + return this; +}; + Baobab.prototype.release = function() { delete this.data; diff --git a/src/cursor.js b/src/cursor.js index c4f8216..282aec5 100644 --- a/src/cursor.js +++ b/src/cursor.js @@ -26,12 +26,14 @@ function Cursor(tree, path, solvedPath, hash) { this.tree = tree; this.path = path; this.hash = hash; - this.relevant = this.get() !== undefined; // Complex path? this.complexPath = !!solvedPath; this.solvedPath = this.complexPath ? solvedPath : this.path; + // Relevant? + this.relevant = this.get() !== undefined; + // Root listeners this.updateHandler = function(e) { var log = e.data.log, @@ -212,10 +214,11 @@ Cursor.prototype.get = function(path) { if (arguments.length > 1) path = helpers.arrayOf(arguments); - if (type.Step(path)) - return this.tree.get(this.solvedPath.concat(path)); - else - return this.tree.get(this.solvedPath); + var fullPath = this.solvedPath.concat( + (type.String(path) || type.Number(path) ? [path] : path) || [] + ); + + return helpers.getIn(this.tree.data, fullPath); }; /** @@ -315,7 +318,7 @@ Cursor.prototype.merge = function(o) { }; Cursor.prototype.update = function(spec) { - this.tree.update(helpers.pathObject(this.solvedPath, spec)); + this.tree.stack(helpers.pathObject(this.solvedPath, spec)); return this; }; From e0b3b9260d78b0597436ad1906626738b87f42c6 Mon Sep 17 00:00:00 2001 From: Yomguithereal Date: Fri, 27 Mar 2015 20:17:50 +0100 Subject: [PATCH 08/73] Before decoration helper --- build/baobab.min.js | 2 +- src/combination.js | 11 ++--------- src/cursor.js | 15 +++------------ src/helpers.js | 9 +++++++++ test/suites/helpers.js | 12 ++++++++++++ 5 files changed, 27 insertions(+), 22 deletions(-) diff --git a/build/baobab.min.js b/build/baobab.min.js index ec3717f..79be86b 100644 --- a/build/baobab.min.js +++ b/build/baobab.min.js @@ -1,2 +1,2 @@ /* baobab.js - Version: 0.4.3 - Author: Yomguithereal (Guillaume Plique) */ -!function(t){if("object"==typeof exports&&"undefined"!=typeof module)module.exports=t();else if("function"==typeof define&&define.amd)define([],t);else{var e;e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:this,e.Baobab=t()}}(function(){var t;return function e(t,r,n){function o(s,a){if(!r[s]){if(!t[s]){var u="function"==typeof require&&require;if(!a&&u)return u(s,!0);if(i)return i(s,!0);var h=new Error("Cannot find module '"+s+"'");throw h.code="MODULE_NOT_FOUND",h}var c=r[s]={exports:{}};t[s][0].call(c.exports,function(e){var r=t[s][1][e];return o(r?r:e)},c,c.exports,e,t,r,n)}return r[s].exports}for(var i="function"==typeof require&&require,s=0;se;e++)n.push(t[e].handler);return n}var o={once:"boolean",scope:"object"},i=function(){this._enabled=!0,this._children=[],this._handlers={},this._handlersAll=[]};i.prototype.on=function(t,e,r){var n,s,a,u,h,c;if("function"==typeof e){for(h="string"==typeof t?[t]:t,n=0,s=h.length;n!==s;n+=1)if(u=h[n]){this._handlers[u]||(this._handlers[u]=[]),c={handler:e};for(a in r||{}){if(!o[a])throw new Error('The option "'+a+'" is not recognized by Emmett.');c[a]=r[a]}this._handlers[u].push(c)}}else if(t&&"object"==typeof t&&!Array.isArray(t))for(u in t)i.prototype.on.call(this,u,t[u],e);else{if("function"!=typeof t)throw new Error("Wrong arguments.");c={handler:t};for(a in r||{}){if(!o[a])throw new Error('The option "'+a+'" is not recognized by Emmett.');c[a]=r[a]}this._handlersAll.push(c)}return this},i.prototype.once=function(t,e,r){if("function"==typeof e)r=r||{},r.once=!0,this.on(t,e,r);else{if((!t||"object"!=typeof t||Array.isArray(t))&&"function"!=typeof t)throw new Error("Wrong arguments.");e=e||{},e.once=!0,this.on(t,e)}return this},i.prototype.off=function(t,e){var r,n,o,i,s,a,u,h="string"==typeof t?[t]:t;if(1===arguments.length&&"function"==typeof h){e=arguments[0];for(s in this._handlers){for(a=[],r=0,n=this._handlers[s].length;r!==n;r+=1)this._handlers[s][r].handler!==e&&a.push(this._handlers[s][r]);this._handlers[s]=a}for(a=[],r=0,n=this._handlersAll.length;r!==n;r+=1)this._handlersAll[r].handler!==e&&a.push(this._handlersAll[r]);this._handlersAll=a}else if(2===arguments.length)for(r=0,n=h.length;r!==n;r+=1){if(u=h[r],this._handlers[u]){for(a=[],o=0,i=this._handlers[u].length;o!==i;o+=1)this._handlers[u][o].handler!==e&&a.push(this._handlers[u][o]);this._handlers[u]=a}this._handlers[u]&&0===this._handlers[u].length&&delete this._handlers[u]}return this},i.prototype.unbindAll=function(){var t;this._handlersAll=[];for(t in this._handlers)delete this._handlers[t];return this},i.prototype.emit=function(t,e){var r,n,o,i,s,a,u,h,c,l,f="string"==typeof t?[t]:t;if(!this._enabled)return this;for(e=void 0===e?{}:e,r=0,n=f.length;r!==n;r+=1)if(l=f[r],c=(this._handlers[l]||[]).concat(this._handlersAll),c.length){for(u={type:l,data:e||{},target:this},a=[],o=0,i=c.length;o!==i;o+=1)(this._handlers[l]&&this._handlers[l].indexOf(c[o])>=0||this._handlersAll.indexOf(c[o])>=0)&&(c[o].handler.call("scope"in c[o]?c[o].scope:this,u),c[o].once&&a.push(c[o]));for(s=0;sr;r++)if(t._children[r]===e){t._children.splice(r,1);break}}),this._children.push(e),e},i.prototype.listeners=function(t){var r,n,o,i=[];if(t)for(i=e(this._handlers[t]),n=0,o=this._children.length;o>n;n++)i=i.concat(this._children[n].listeners(t));else{i=e(this._handlersAll);for(r in this._handlers)i=i.concat(e(this._handlers[r]));for(n=0,o=this._children.length;o>n;n++)i=i.concat(this._children[n].listeners())}return i},i.prototype.kill=function(){if(this.emit("emmett:kill"),this.unbindAll(),this._handlers=null,this._handlersAll=null,this._enabled=!1,this._children)for(var t=0,e=this._children.length;e>t;t++)this._children[t].kill();this._children=null},i.prototype.disable=function(){return this._enabled=!1,this},i.prototype.enable=function(){return this._enabled=!0,this},i.version="2.1.2","undefined"!=typeof n?("undefined"!=typeof r&&r.exports&&(n=r.exports=i),n.Emitter=i):"function"==typeof t&&t.amd?t("emmett",[],function(){return i}):this.Emitter=i}).call(this)},{}],4:[function(t,e){function r(t){return t+"$"+(new Date).getTime()+(""+Math.random()).replace("0.","")}function n(t,e){function r(t){this[t]=function(){var e=this.root[t].apply(this.root,arguments);return e instanceof o?this:e}}if(arguments.length<1&&(t={}),!(this instanceof n))return new n(t,e);if(!l.Object(t)&&!l.Array(t))throw Error("Baobab: invalid data.");i.call(this),this.options=s.shallowMerge(c,e),this._transaction={},this._future=void 0,this._cursors={},this.data=s.deepClone(t),this.root=this.select([]),["get","set","unset","update"].forEach(r.bind(this)),this.mixin=h.baobab(this)}var o=t("./cursor.js"),i=t("emmett"),s=t("./helpers.js"),a=t("./update.js"),u=t("./merge.js"),h=t("./mixins.js"),c=t("../defaults.js"),l=t("./type.js");s.inherits(n,i),n.prototype.select=function(t){if(!t)throw Error("Baobab.select: invalid path.");if(arguments.length>1&&(t=s.arrayOf(arguments)),!l.Path(t))throw Error("Baobab.select: invalid path.");t=l.Array(t)?t:[t];var e,n=l.ComplexPath(t);n&&(e=s.solvePath(this.data,t));var i=t.map(function(t){return l.Function(t)?r("fn"):l.Object(t)?r("ob"):t}).join("λ");if(this._cursors[i])return this._cursors[i];var a=new o(this,t,e,i);return this._cursors[i]=a,a},n.prototype.stack=function(t){var e=this;if(!l.Object(t))throw Error("Baobab.update: wrong specification.");return this._transaction=u(t,this._transaction),this.options.autoCommit?this.options.asynchronous?(this._future||(this._future=setTimeout(e.commit.bind(e,null),0)),this):this.commit():this},n.prototype.commit=function(){this.options.shiftReferences&&(this.data=s.shallowClone(this.data));var t=a(this.data,this._transaction,this.options);return this._transaction={},this._future&&(this._future=clearTimeout(this._future)),this.emit("update",{log:t}),this},n.prototype.release=function(){delete this.data,delete this._transaction;for(var t in this._cursors)this._cursors[t].release();delete this._cursors,this.kill()},n.prototype.toJSON=function(){return this.get()},e.exports=n},{"../defaults.js":1,"./cursor.js":6,"./helpers.js":7,"./merge.js":8,"./mixins.js":9,"./type.js":10,"./update.js":11,emmett:3}],5:[function(t,e){function r(t,e){e.on("update",t.cursorListener),t.tree.off("update",t.treeListener),t.tree.on("update",t.treeListener)}function n(t){var e=this;if(arguments.length<2)throw Error("baobab.Combination: not enough arguments.");var n=arguments[1],o=s.arrayOf(arguments).slice(2);if(n instanceof Array&&(o=n.slice(1),n=n[0]),!a.Cursor(n))throw Error("baobab.Combination: argument should be a cursor.");if("or"!==t&&"and"!==t)throw Error("baobab.Combination: invalid operator.");i.call(this),this.cursors=[n],this.operators=[],this.tree=n.tree,this.updates=new Array(this.cursors.length),this.cursorListener=function(){e.updates[e.cursors.indexOf(this)]=!0},this.treeListener=function(){var t,r,n=e.updates[0];for(t=1,r=e.cursors.length;r>t;t++)n="or"===e.operators[t-1]?n||e.updates[t]:n&&e.updates[t];n&&e.emit("update"),e.updates=new Array(e.cursors.length)},this.bound=!1;var u=this.on,h=this.once,c=function(){e.bound||(e.bound=!0,e.cursors.forEach(function(t){r(e,t)}))};this.on=function(){return c(),u.apply(this,arguments)},this.once=function(){return c(),h.apply(this,arguments)},o.forEach(function(e){this[t](e)},this)}function o(t){n.prototype[t]=function(e){if(!a.Cursor(e))throw this.release(),Error("baobab.Combination."+t+": argument should be a cursor.");if(~this.cursors.indexOf(e))throw this.release(),Error("baobab.Combination."+t+": cursor already in combination.");return this.cursors.push(e),this.operators.push(t),this.updates.length++,this.bound&&r(this,e),this}}var i=t("emmett"),s=t("./helpers.js"),a=t("./type.js");s.inherits(n,i),o("or"),o("and"),n.prototype.release=function(){this.cursors.forEach(function(t){t.off("update",this.cursorListener)},this),this.tree.off("update",this.treeListener),this.cursors=null,this.operators=null,this.tree=null,this.updates=null,this.kill()},e.exports=n},{"./helpers.js":7,"./type.js":10,emmett:3}],6:[function(t,e){function r(t,e,r,o){var a=this;n.call(this),e=e||[],this.tree=t,this.path=e,this.hash=o,this.complexPath=!!r,this.solvedPath=this.complexPath?r:this.path,this.relevant=void 0!==this.get(),this.updateHandler=function(t){var e,r,n,o,i,u,h=t.data.log,c=!1;if(a.complexPath&&(a.solvedPath=s.solvePath(a.tree.data,a.path)),!a.path.length)return a.emit("update");t:for(i=0,n=h.length;n>i;i++)for(e=h[i],u=0,o=e.length;o>u&&(r=e[u],r===""+a.solvedPath[u]);u++)if(u+1===o||u+1===a.solvedPath.length){c=!0;break t}var l=void 0!==a.get();a.relevant?l&&c?a.emit("update"):l||(a.emit("irrelevant"),a.relevant=!1):l&&c&&(a.emit("relevant"),a.emit("update"),a.relevant=!0)},this.mixin=i.cursor(this);var u=!1,h=this.on,c=this.once,l=function(){u||(u=!0,a.tree.on("update",a.updateHandler))};this.on=function(){return l(),h.apply(this,arguments)},this.once=function(){return l(),c.apply(this,arguments)}}var n=t("emmett"),o=t("./combination.js"),i=t("./mixins.js"),s=t("./helpers.js"),a=t("./type.js");s.inherits(r,n),r.prototype.isRoot=function(){return!this.path.length},r.prototype.isLeaf=function(){return a.Primitive(this.get())},r.prototype.isBranch=function(){return!this.isLeaf()&&!this.isRoot()},r.prototype.root=function(){return this.tree.root()},r.prototype.select=function(t){if(arguments.length>1&&(t=s.arrayOf(arguments)),!a.Path(t))throw Error("baobab.Cursor.select: invalid path.");return this.tree.select(this.path.concat(t))},r.prototype.up=function(){return this.solvedPath&&this.solvedPath.length?this.tree.select(this.path.slice(0,-1)):null},r.prototype.left=function(){var t=+this.solvedPath[this.solvedPath.length-1];if(isNaN(t))throw Error("baobab.Cursor.left: cannot go left on a non-list type.");return t?this.tree.select(this.solvedPath.slice(0,-1).concat(t-1)):null},r.prototype.leftmost=function(){var t=+this.solvedPath[this.solvedPath.length-1];if(isNaN(t))throw Error("baobab.Cursor.leftmost: cannot go left on a non-list type.");return this.tree.select(this.solvedPath.slice(0,-1).concat(0))},r.prototype.right=function(){var t=+this.solvedPath[this.solvedPath.length-1];if(isNaN(t))throw Error("baobab.Cursor.right: cannot go right on a non-list type.");return t+1===this.up().get().length?null:this.tree.select(this.solvedPath.slice(0,-1).concat(t+1))},r.prototype.rightmost=function(){var t=+this.solvedPath[this.solvedPath.length-1];if(isNaN(t))throw Error("baobab.Cursor.right: cannot go right on a non-list type.");var e=this.up().get();return this.tree.select(this.solvedPath.slice(0,-1).concat(e.length-1))},r.prototype.down=function(){+this.solvedPath[this.solvedPath.length-1];return this.get()instanceof Array?this.tree.select(this.solvedPath.concat(0)):null},r.prototype.get=function(t){arguments.length>1&&(t=s.arrayOf(arguments));var e=this.solvedPath.concat((a.String(t)||a.Number(t)?[t]:t)||[]);return s.getIn(this.tree.data,e)},r.prototype.set=function(t,e){if(arguments.length<2)throw Error("baobab.Cursor.set: expecting at least key/value.");var r=this.get();if("object"!=typeof r)throw Error("baobab.Cursor.set: trying to set key to a non-object.");var n={};if(a.Array(t)){var o=s.solvePath(r,t);if(!o)throw Error("baobab.Cursor.set: could not solve dynamic path.");n=s.pathObject(o,{$set:e})}else n[t]={$set:e};return this.update(n)},r.prototype.edit=function(t){return this.update({$set:t})},r.prototype.unset=function(t){if(!t&&0!==t)throw Error("baobab.Cursor.unset: expects a valid key to unset.");if("object"!=typeof this.get())throw Error("baobab.Cursor.set: trying to set key to a non-object.");var e={};return e[t]={$unset:!0},this.update(e)},r.prototype.remove=function(){if(this.isRoot())throw Error("baobab.Cursor.remove: cannot remove root node.");return this.update({$unset:!0})},r.prototype.apply=function(t){if("function"!=typeof t)throw Error("baobab.Cursor.apply: argument is not a function.");return this.update({$apply:t})},r.prototype.chain=function(t){if("function"!=typeof t)throw Error("baobab.Cursor.chain: argument is not a function.");return this.update({$chain:t})},r.prototype.push=function(t){if(!(this.get()instanceof Array))throw Error("baobab.Cursor.push: trying to push to non-array value.");return this.update(arguments.length>1?{$push:s.arrayOf(arguments)}:{$push:t})},r.prototype.unshift=function(t){if(!(this.get()instanceof Array))throw Error("baobab.Cursor.push: trying to push to non-array value.");return this.update(arguments.length>1?{$unshift:s.arrayOf(arguments)}:{$unshift:t})},r.prototype.merge=function(t){if(!a.Object(t))throw Error("baobab.Cursor.merge: trying to merge a non-object.");if(!a.Object(this.get()))throw Error("baobab.Cursor.merge: trying to merge into a non-object.");this.update({$merge:t})},r.prototype.update=function(t){return this.tree.stack(s.pathObject(this.solvedPath,t)),this},r.prototype.or=function(t){return new o("or",this,t)},r.prototype.and=function(t){return new o("and",this,t)},r.prototype.release=function(){this.tree.off("update",this.updateHandler),this.hash&&delete this.tree._cursors[this.hash],delete this.tree,delete this.path,delete this.solvedPath,this.kill()},r.prototype.toJSON=function(){return this.get()},a.Cursor=function(t){return t instanceof r},e.exports=r},{"./combination.js":5,"./helpers.js":7,"./mixins.js":9,"./type.js":10,emmett:3}],7:[function(t,e){function r(t){return Array.prototype.slice.call(t)}function n(t,e){var r,n={};for(r in t)n[r]=t[r];for(r in e)n[r]=e[r];return n}function o(t){var e=t.source,r="";return t.global&&(r+="g"),t.multiline&&(r+="m"),t.ignoreCase&&(r+="i"),t.sticky&&(r+="y"),t.unicode&&(r+="u"),new RegExp(e,r)}function i(t,e){if(!e||"object"!=typeof e||e instanceof Error||e instanceof ArrayBuffer)return e;if(g.Array(e)){if(t){var r,n,i=[];for(r=0,n=e.length;n>r;r++)i.push(m(e[r]));return i}return e.slice(0)}if(g.Date(e))return new Date(e.getTime());if(e instanceof RegExp)return o(e);if(g.Object(e)){var s,a={};e.constructor&&e.constructor!==Object&&(a=Object.create(e.constructor.prototype));for(s in e)e.hasOwnProperty(s)&&(a[s]=t?m(e[s]):e[s]);return a}return e}function s(t,e){return function(r){return e(t(r))}}function a(t,e){var r,n;for(r=0,n=t.length;n>r;r++)if(e(t[r]))return t[r]}function u(t,e){var r,n;for(r=0,n=t.length;n>r;r++)if(e(t[r]))return r;return-1}function h(t,e){var r,n=!0;if(!t)return!1;for(r in e)if(g.Object(e[r]))n=n&&h(t[r],e[r]);else if(g.Array(e[r]))n=n&&!!~e[r].indexOf(t[r]);else if(t[r]!==e[r])return!1;return n}function c(t,e){return a(t,function(t){return h(t,e)})}function l(t,e){return u(t,function(t){return h(t,e)})}function f(t,e){e=e||[];var r,n,o=t;for(r=0,n=e.length;n>r;r++){if(!o)return;if("function"==typeof e[r]){if(!g.Array(o))return;o=a(o,e[r])}else if("object"==typeof e[r]){if(!g.Array(o))return;o=c(o,e[r])}else o=o[e[r]]}return o}function p(t,e){var r,n,o,i=[],s=t;for(n=0,o=e.length;o>n;n++){if(!s)return null;if("function"==typeof e[n]){if(!g.Array(s))return;r=u(s,e[n]),i.push(r),s=s[r]}else if("object"==typeof e[n]){if(!g.Array(s))return;r=l(s,e[n]),i.push(r),s=s[r]}else i.push(e[n]),s=s[e[n]]||{}}return i}function d(t,e){var r,n=t.length,o={},i=o;for(n||(o=e),r=0;n>r;r++)i[t[r]]=r+1===n?e:{},i=i[t[r]];return o}function y(t,e){t.super_=e;var r=function(){};r.prototype=e.prototype,t.prototype=new r,t.prototype.constructor=t}var g=t("./type.js"),b=i.bind(null,!1),m=i.bind(null,!0);e.exports={arrayOf:r,deepClone:m,shallowClone:b,shallowMerge:n,compose:s,getIn:f,inherits:y,pathObject:d,solvePath:p}},{"./type.js":10}],8:[function(t,e){function r(t,e){return e in(t||{})}function n(t,e,n){return r(t,n)&&r(e,n)}function o(){var t,e,r,a,u={},h=arguments.length;for(r=h-1;r>=0;r--){if(arguments[r].$unset)delete u.$set,delete u.$apply,delete u.$merge,u.$unset=arguments[r].$unset;else{if(arguments[r].$set){delete u.$apply,delete u.$merge,delete u.$unset,u.$set=arguments[r].$set;continue}if(arguments[r].$merge){delete u.$set,delete u.$apply,delete u.$unset,u.$merge=arguments[r].$merge;continue}if(arguments[r].$apply){delete u.$set,delete u.$merge,delete u.$unset,u.$apply=arguments[r].$apply;continue}if(arguments[r].$chain){delete u.$set,delete u.$merge,delete u.$unset,u.$apply=u.$apply?i.compose(u.$apply,arguments[r].$chain):arguments[r].$chain;continue}}for(a in arguments[r])t=u[a],e=arguments[r][a],t&&s.Object(e)?n(t,e,"$push")?t.$push=s.Array(t.$push)?t.$push.concat(e.$push):[t.$push].concat(e.$push):n(t,e,"$unshift")?t.$unshift=s.Array(e.$unshift)?e.$unshift.concat(t.$unshift):[e.$unshift].concat(t.$unshift):u[a]=o(e,t):u[a]=e}return u}var i=t("./helpers.js"),s=t("./type.js");e.exports=o},{"./helpers.js":7,"./type.js":10}],9:[function(t,e){var r=t("./combination.js"),n=t("./type.js");e.exports={baobab:function(t){return{mixins:[{getInitialState:function(){if(this.tree=t,!this.cursor&&!this.cursors)return{};if(this.cursor&&this.cursors)throw Error("baobab.mixin: you cannot have both `component.cursor` and `component.cursors`. Please make up your mind.");if(this.__type=null,this.__updateHandler=function(){this.setState(this.__getCursorData())}.bind(this),this.cursor){if(!n.MixinCursor(this.cursor))throw Error("baobab.mixin.cursor: invalid data (cursor, string, array or function).");n.Function(this.cursor)&&(this.cursor=this.cursor()),n.Cursor(this.cursor)||(this.cursor=t.select(this.cursor)),this.__getCursorData=function(){return{cursor:this.cursor.get()}}.bind(this),this.__type="single"}else if(this.cursors){if(!n.MixinCursors(this.cursors))throw Error("baobab.mixin.cursor: invalid data (object, array or function).");if(n.Function(this.cursors)&&(this.cursors=this.cursors()),n.Array(this.cursors))this.cursors=this.cursors.map(function(e){return n.Cursor(e)?e:t.select(e)}),this.__getCursorData=function(){return{cursors:this.cursors.map(function(t){return t.get()})}}.bind(this),this.__type="array";else{for(var e in this.cursors)n.Cursor(this.cursors[e])||(this.cursors[e]=t.select(this.cursors[e]));this.__getCursorData=function(){var t={};for(e in this.cursors)t[e]=this.cursors[e].get();return{cursors:t}}.bind(this),this.__type="object"}}return this.__getCursorData()},componentDidMount:function(){"single"===this.__type?(this.__combination=new r("or",[this.cursor]),this.__combination.on("update",this.__updateHandler)):"array"===this.__type?(this.__combination=new r("or",this.cursors),this.__combination.on("update",this.__updateHandler)):"object"===this.__type&&(this.__combination=new r("or",Object.keys(this.cursors).map(function(t){return this.cursors[t]},this)),this.__combination.on("update",this.__updateHandler))},componentWillUnmount:function(){this.__combination&&this.__combination.release()}}].concat(t.options.mixins)}},cursor:function(t){return{mixins:[{getInitialState:function(){return this.cursor=t,this.__updateHandler=function(){this.setState({cursor:this.cursor.get()})}.bind(this),{cursor:this.cursor.get()}},componentDidMount:function(){this.cursor.on("update",this.__updateHandler)},componentWillUnmount:function(){this.cursor.off("update",this.__updateHandler)}}].concat(t.tree.options.mixins)}}}},{"./combination.js":5,"./type.js":10}],10:[function(t,e){var r=function(t){return Array.isArray(t)?"array":"object"==typeof t&&null!==t?"object":"string"==typeof t?"string":"number"==typeof t?"number":"boolean"==typeof t?"boolean":"function"==typeof t?"function":null===t?"null":void 0===t?"undefined":t instanceof Date?"date":"invalid"};r.Array=function(t){return Array.isArray(t)},r.Object=function(t){return!Array.isArray(t)&&"object"==typeof t&&null!==t},r.String=function(t){return"string"==typeof t},r.Number=function(t){return"number"==typeof t},r.Boolean=function(t){return"boolean"==typeof t},r.Function=function(t){return"function"==typeof t},r.Primitive=function(t){return"string"==typeof t||"number"==typeof t||"boolean"==typeof t},r.Date=function(t){return t instanceof Date},r.Step=function(t){var e=r(t),n=["null","undefined","invalid","date"];return-1===n.indexOf(e)},r.Path=function(t){var e=["object","string","number","function","undefined"];if(!r.Array(t))return e.indexOf(r(t))>=0;for(var n=0;n=0||r.Cursor(t)},r.MixinCursors=function(t){var e=["array","object","function"];return e.indexOf(r(t))>=0},r.ComplexPath=function(t){for(var e=["object","function"],n=0;n=0)return!0;return!1},e.exports=r},{}],11:[function(t,e){function r(t,e){var r=new Error("baobab.update: "+e+" at path /"+t.toString());return r.path=t,r}function n(t,e,n){n=n||{shiftReferences:!1};var a={};return function u(t,e,h,c){h=h||[];var l,f,p,d,y=h.join("λ");for(p in e)if(s[p])switch(d=e[p],a[y]=!0,p){case"$push":if(!i.Array(t))throw r(h,"using command $push to a non array");i.Array(d)?t.push.apply(t,d):t.push(d);break;case"$unshift":if(!i.Array(t))throw r(h,"using command $unshift to a non array");i.Array(d)?t.unshift.apply(t,d):t.unshift(d)}else if(f=y?y+"λ"+p:p,"$unset"in(e[p]||{}))a[f]=!0,i.Array(t)?n.shiftReferences?c[h[h.length-1]]=t.slice(0,+p).concat(t.slice(+p+1)):t.splice(p,1):delete t[p];else if("$set"in(e[p]||{}))d=e[p].$set,a[f]=!0,t[p]=d;else if("$apply"in(e[p]||{})||"$chain"in(e[p]||{})){if(l=e[p].$apply||e[p].$chain,"function"!=typeof l)throw r(h.concat(p),"using command $apply with a non function");a[f]=!0,t[p]=l.call(null,t[p])}else if("$merge"in(e[p]||{})){if(d=e[p].$merge,!i.Object(t[p]))throw r(h.concat(p),"using command $merge on a non-object");a[f]=!0,t[p]=o.shallowMerge(t[p],d)}else if(n.shiftReferences&&("$push"in(e[p]||{})||"$unshift"in(e[p]||{}))){if("$push"in(e[p]||{})){if(d=e[p].$push,!i.Array(t[p]))throw r(h.concat(p),"using command $push to a non array");t[p]=t[p].concat(d)}if("$unshift"in(e[p]||{})){if(d=e[p].$unshift,!i.Array(t[p]))throw r(h.concat(p),"using command $unshift to a non array");t[p]=(d instanceof Array?d:[d]).concat(t[p])}a[f]=!0}else"undefined"==typeof t[p]&&(t[p]={}),n.shiftReferences&&(t[p]=o.shallowClone(t[p])),u(t[p],e[p],h.concat(p),t)}(t,e),Object.keys(a).map(function(t){return t.split("λ")})}var o=t("./helpers.js"),i=t("./type.js"),s={};["$set","$push","$unshift","$apply","$merge"].forEach(function(t){s[t]=!0}),e.exports=n},{"./helpers.js":7,"./type.js":10}]},{},[2])(2)}); \ No newline at end of file +!function(t){if("object"==typeof exports&&"undefined"!=typeof module)module.exports=t();else if("function"==typeof define&&define.amd)define([],t);else{var e;e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:this,e.Baobab=t()}}(function(){var t;return function e(t,r,n){function o(s,a){if(!r[s]){if(!t[s]){var u="function"==typeof require&&require;if(!a&&u)return u(s,!0);if(i)return i(s,!0);var h=new Error("Cannot find module '"+s+"'");throw h.code="MODULE_NOT_FOUND",h}var c=r[s]={exports:{}};t[s][0].call(c.exports,function(e){var r=t[s][1][e];return o(r?r:e)},c,c.exports,e,t,r,n)}return r[s].exports}for(var i="function"==typeof require&&require,s=0;se;e++)n.push(t[e].handler);return n}var o={once:"boolean",scope:"object"},i=function(){this._enabled=!0,this._children=[],this._handlers={},this._handlersAll=[]};i.prototype.on=function(t,e,r){var n,s,a,u,h,c;if("function"==typeof e){for(h="string"==typeof t?[t]:t,n=0,s=h.length;n!==s;n+=1)if(u=h[n]){this._handlers[u]||(this._handlers[u]=[]),c={handler:e};for(a in r||{}){if(!o[a])throw new Error('The option "'+a+'" is not recognized by Emmett.');c[a]=r[a]}this._handlers[u].push(c)}}else if(t&&"object"==typeof t&&!Array.isArray(t))for(u in t)i.prototype.on.call(this,u,t[u],e);else{if("function"!=typeof t)throw new Error("Wrong arguments.");c={handler:t};for(a in r||{}){if(!o[a])throw new Error('The option "'+a+'" is not recognized by Emmett.');c[a]=r[a]}this._handlersAll.push(c)}return this},i.prototype.once=function(t,e,r){if("function"==typeof e)r=r||{},r.once=!0,this.on(t,e,r);else{if((!t||"object"!=typeof t||Array.isArray(t))&&"function"!=typeof t)throw new Error("Wrong arguments.");e=e||{},e.once=!0,this.on(t,e)}return this},i.prototype.off=function(t,e){var r,n,o,i,s,a,u,h="string"==typeof t?[t]:t;if(1===arguments.length&&"function"==typeof h){e=arguments[0];for(s in this._handlers){for(a=[],r=0,n=this._handlers[s].length;r!==n;r+=1)this._handlers[s][r].handler!==e&&a.push(this._handlers[s][r]);this._handlers[s]=a}for(a=[],r=0,n=this._handlersAll.length;r!==n;r+=1)this._handlersAll[r].handler!==e&&a.push(this._handlersAll[r]);this._handlersAll=a}else if(2===arguments.length)for(r=0,n=h.length;r!==n;r+=1){if(u=h[r],this._handlers[u]){for(a=[],o=0,i=this._handlers[u].length;o!==i;o+=1)this._handlers[u][o].handler!==e&&a.push(this._handlers[u][o]);this._handlers[u]=a}this._handlers[u]&&0===this._handlers[u].length&&delete this._handlers[u]}return this},i.prototype.unbindAll=function(){var t;this._handlersAll=[];for(t in this._handlers)delete this._handlers[t];return this},i.prototype.emit=function(t,e){var r,n,o,i,s,a,u,h,c,l,f="string"==typeof t?[t]:t;if(!this._enabled)return this;for(e=void 0===e?{}:e,r=0,n=f.length;r!==n;r+=1)if(l=f[r],c=(this._handlers[l]||[]).concat(this._handlersAll),c.length){for(u={type:l,data:e||{},target:this},a=[],o=0,i=c.length;o!==i;o+=1)(this._handlers[l]&&this._handlers[l].indexOf(c[o])>=0||this._handlersAll.indexOf(c[o])>=0)&&(c[o].handler.call("scope"in c[o]?c[o].scope:this,u),c[o].once&&a.push(c[o]));for(s=0;sr;r++)if(t._children[r]===e){t._children.splice(r,1);break}}),this._children.push(e),e},i.prototype.listeners=function(t){var r,n,o,i=[];if(t)for(i=e(this._handlers[t]),n=0,o=this._children.length;o>n;n++)i=i.concat(this._children[n].listeners(t));else{i=e(this._handlersAll);for(r in this._handlers)i=i.concat(e(this._handlers[r]));for(n=0,o=this._children.length;o>n;n++)i=i.concat(this._children[n].listeners())}return i},i.prototype.kill=function(){if(this.emit("emmett:kill"),this.unbindAll(),this._handlers=null,this._handlersAll=null,this._enabled=!1,this._children)for(var t=0,e=this._children.length;e>t;t++)this._children[t].kill();this._children=null},i.prototype.disable=function(){return this._enabled=!1,this},i.prototype.enable=function(){return this._enabled=!0,this},i.version="2.1.2","undefined"!=typeof n?("undefined"!=typeof r&&r.exports&&(n=r.exports=i),n.Emitter=i):"function"==typeof t&&t.amd?t("emmett",[],function(){return i}):this.Emitter=i}).call(this)},{}],4:[function(t,e){function r(t){return t+"$"+(new Date).getTime()+(""+Math.random()).replace("0.","")}function n(t,e){function r(t){this[t]=function(){var e=this.root[t].apply(this.root,arguments);return e instanceof o?this:e}}if(arguments.length<1&&(t={}),!(this instanceof n))return new n(t,e);if(!l.Object(t)&&!l.Array(t))throw Error("Baobab: invalid data.");i.call(this),this.options=s.shallowMerge(c,e),this._transaction={},this._future=void 0,this._cursors={},this.data=s.deepClone(t),this.root=this.select([]),["get","set","unset","update"].forEach(r.bind(this)),this.mixin=h.baobab(this)}var o=t("./cursor.js"),i=t("emmett"),s=t("./helpers.js"),a=t("./update.js"),u=t("./merge.js"),h=t("./mixins.js"),c=t("../defaults.js"),l=t("./type.js");s.inherits(n,i),n.prototype.select=function(t){if(!t)throw Error("Baobab.select: invalid path.");if(arguments.length>1&&(t=s.arrayOf(arguments)),!l.Path(t))throw Error("Baobab.select: invalid path.");t=l.Array(t)?t:[t];var e,n=l.ComplexPath(t);n&&(e=s.solvePath(this.data,t));var i=t.map(function(t){return l.Function(t)?r("fn"):l.Object(t)?r("ob"):t}).join("λ");if(this._cursors[i])return this._cursors[i];var a=new o(this,t,e,i);return this._cursors[i]=a,a},n.prototype.stack=function(t){var e=this;if(!l.Object(t))throw Error("Baobab.update: wrong specification.");return this._transaction=u(t,this._transaction),this.options.autoCommit?this.options.asynchronous?(this._future||(this._future=setTimeout(e.commit.bind(e,null),0)),this):this.commit():this},n.prototype.commit=function(){this.options.shiftReferences&&(this.data=s.shallowClone(this.data));var t=a(this.data,this._transaction,this.options);return this._transaction={},this._future&&(this._future=clearTimeout(this._future)),this.emit("update",{log:t}),this},n.prototype.release=function(){delete this.data,delete this._transaction;for(var t in this._cursors)this._cursors[t].release();delete this._cursors,this.kill()},n.prototype.toJSON=function(){return this.get()},e.exports=n},{"../defaults.js":1,"./cursor.js":6,"./helpers.js":7,"./merge.js":8,"./mixins.js":9,"./type.js":10,"./update.js":11,emmett:3}],5:[function(t,e){function r(t,e){e.on("update",t.cursorListener),t.tree.off("update",t.treeListener),t.tree.on("update",t.treeListener)}function n(t){var e=this;if(arguments.length<2)throw Error("baobab.Combination: not enough arguments.");var n=arguments[1],o=s.arrayOf(arguments).slice(2);if(n instanceof Array&&(o=n.slice(1),n=n[0]),!a.Cursor(n))throw Error("baobab.Combination: argument should be a cursor.");if("or"!==t&&"and"!==t)throw Error("baobab.Combination: invalid operator.");i.call(this),this.cursors=[n],this.operators=[],this.tree=n.tree,this.updates=new Array(this.cursors.length),this.cursorListener=function(){e.updates[e.cursors.indexOf(this)]=!0},this.treeListener=function(){var t,r,n=e.updates[0];for(t=1,r=e.cursors.length;r>t;t++)n="or"===e.operators[t-1]?n||e.updates[t]:n&&e.updates[t];n&&e.emit("update"),e.updates=new Array(e.cursors.length)},this.bound=!1;var u=(this.on,this.once,function(){e.bound||(e.bound=!0,e.cursors.forEach(function(t){r(e,t)}))});this.on=s.before(u,this.on.bind(this)),this.once=s.before(u,this.once.bind(this)),o.forEach(function(e){this[t](e)},this)}function o(t){n.prototype[t]=function(e){if(!a.Cursor(e))throw this.release(),Error("baobab.Combination."+t+": argument should be a cursor.");if(~this.cursors.indexOf(e))throw this.release(),Error("baobab.Combination."+t+": cursor already in combination.");return this.cursors.push(e),this.operators.push(t),this.updates.length++,this.bound&&r(this,e),this}}var i=t("emmett"),s=t("./helpers.js"),a=t("./type.js");s.inherits(n,i),o("or"),o("and"),n.prototype.release=function(){this.cursors.forEach(function(t){t.off("update",this.cursorListener)},this),this.tree.off("update",this.treeListener),this.cursors=null,this.operators=null,this.tree=null,this.updates=null,this.kill()},e.exports=n},{"./helpers.js":7,"./type.js":10,emmett:3}],6:[function(t,e){function r(t,e,r,o){var a=this;n.call(this),e=e||[],this.tree=t,this.path=e,this.hash=o,this.complexPath=!!r,this.solvedPath=this.complexPath?r:this.path,this.relevant=void 0!==this.get(),this.updateHandler=function(t){var e,r,n,o,i,u,h=t.data.log,c=!1;if(a.complexPath&&(a.solvedPath=s.solvePath(a.tree.data,a.path)),!a.path.length)return a.emit("update");t:for(i=0,n=h.length;n>i;i++)for(e=h[i],u=0,o=e.length;o>u&&(r=e[u],r===""+a.solvedPath[u]);u++)if(u+1===o||u+1===a.solvedPath.length){c=!0;break t}var l=void 0!==a.get();a.relevant?l&&c?a.emit("update"):l||(a.emit("irrelevant"),a.relevant=!1):l&&c&&(a.emit("relevant"),a.emit("update"),a.relevant=!0)},this.mixin=i.cursor(this);var u=!1,h=function(){u||(u=!0,a.tree.on("update",a.updateHandler))};this.on=s.before(h,this.on.bind(this)),this.once=s.before(h,this.once.bind(this))}var n=t("emmett"),o=t("./combination.js"),i=t("./mixins.js"),s=t("./helpers.js"),a=t("./type.js");s.inherits(r,n),r.prototype.isRoot=function(){return!this.path.length},r.prototype.isLeaf=function(){return a.Primitive(this.get())},r.prototype.isBranch=function(){return!this.isLeaf()&&!this.isRoot()},r.prototype.root=function(){return this.tree.root()},r.prototype.select=function(t){if(arguments.length>1&&(t=s.arrayOf(arguments)),!a.Path(t))throw Error("baobab.Cursor.select: invalid path.");return this.tree.select(this.path.concat(t))},r.prototype.up=function(){return this.solvedPath&&this.solvedPath.length?this.tree.select(this.path.slice(0,-1)):null},r.prototype.left=function(){var t=+this.solvedPath[this.solvedPath.length-1];if(isNaN(t))throw Error("baobab.Cursor.left: cannot go left on a non-list type.");return t?this.tree.select(this.solvedPath.slice(0,-1).concat(t-1)):null},r.prototype.leftmost=function(){var t=+this.solvedPath[this.solvedPath.length-1];if(isNaN(t))throw Error("baobab.Cursor.leftmost: cannot go left on a non-list type.");return this.tree.select(this.solvedPath.slice(0,-1).concat(0))},r.prototype.right=function(){var t=+this.solvedPath[this.solvedPath.length-1];if(isNaN(t))throw Error("baobab.Cursor.right: cannot go right on a non-list type.");return t+1===this.up().get().length?null:this.tree.select(this.solvedPath.slice(0,-1).concat(t+1))},r.prototype.rightmost=function(){var t=+this.solvedPath[this.solvedPath.length-1];if(isNaN(t))throw Error("baobab.Cursor.right: cannot go right on a non-list type.");var e=this.up().get();return this.tree.select(this.solvedPath.slice(0,-1).concat(e.length-1))},r.prototype.down=function(){+this.solvedPath[this.solvedPath.length-1];return this.get()instanceof Array?this.tree.select(this.solvedPath.concat(0)):null},r.prototype.get=function(t){arguments.length>1&&(t=s.arrayOf(arguments));var e=this.solvedPath.concat((a.String(t)||a.Number(t)?[t]:t)||[]);return s.getIn(this.tree.data,e)},r.prototype.set=function(t,e){if(arguments.length<2)throw Error("baobab.Cursor.set: expecting at least key/value.");var r=this.get();if("object"!=typeof r)throw Error("baobab.Cursor.set: trying to set key to a non-object.");var n={};if(a.Array(t)){var o=s.solvePath(r,t);if(!o)throw Error("baobab.Cursor.set: could not solve dynamic path.");n=s.pathObject(o,{$set:e})}else n[t]={$set:e};return this.update(n)},r.prototype.edit=function(t){return this.update({$set:t})},r.prototype.unset=function(t){if(!t&&0!==t)throw Error("baobab.Cursor.unset: expects a valid key to unset.");if("object"!=typeof this.get())throw Error("baobab.Cursor.set: trying to set key to a non-object.");var e={};return e[t]={$unset:!0},this.update(e)},r.prototype.remove=function(){if(this.isRoot())throw Error("baobab.Cursor.remove: cannot remove root node.");return this.update({$unset:!0})},r.prototype.apply=function(t){if("function"!=typeof t)throw Error("baobab.Cursor.apply: argument is not a function.");return this.update({$apply:t})},r.prototype.chain=function(t){if("function"!=typeof t)throw Error("baobab.Cursor.chain: argument is not a function.");return this.update({$chain:t})},r.prototype.push=function(t){if(!(this.get()instanceof Array))throw Error("baobab.Cursor.push: trying to push to non-array value.");return this.update(arguments.length>1?{$push:s.arrayOf(arguments)}:{$push:t})},r.prototype.unshift=function(t){if(!(this.get()instanceof Array))throw Error("baobab.Cursor.push: trying to push to non-array value.");return this.update(arguments.length>1?{$unshift:s.arrayOf(arguments)}:{$unshift:t})},r.prototype.merge=function(t){if(!a.Object(t))throw Error("baobab.Cursor.merge: trying to merge a non-object.");if(!a.Object(this.get()))throw Error("baobab.Cursor.merge: trying to merge into a non-object.");this.update({$merge:t})},r.prototype.update=function(t){return this.tree.stack(s.pathObject(this.solvedPath,t)),this},r.prototype.or=function(t){return new o("or",this,t)},r.prototype.and=function(t){return new o("and",this,t)},r.prototype.release=function(){this.tree.off("update",this.updateHandler),this.hash&&delete this.tree._cursors[this.hash],delete this.tree,delete this.path,delete this.solvedPath,this.kill()},r.prototype.toJSON=function(){return this.get()},a.Cursor=function(t){return t instanceof r},e.exports=r},{"./combination.js":5,"./helpers.js":7,"./mixins.js":9,"./type.js":10,emmett:3}],7:[function(t,e){function r(t){return Array.prototype.slice.call(t)}function n(t,e){return function(){t(),e.apply(null,arguments)}}function o(t,e){var r,n={};for(r in t)n[r]=t[r];for(r in e)n[r]=e[r];return n}function i(t){var e=t.source,r="";return t.global&&(r+="g"),t.multiline&&(r+="m"),t.ignoreCase&&(r+="i"),t.sticky&&(r+="y"),t.unicode&&(r+="u"),new RegExp(e,r)}function s(t,e){if(!e||"object"!=typeof e||e instanceof Error||e instanceof ArrayBuffer)return e;if(g.Array(e)){if(t){var r,n,o=[];for(r=0,n=e.length;n>r;r++)o.push(v(e[r]));return o}return e.slice(0)}if(g.Date(e))return new Date(e.getTime());if(e instanceof RegExp)return i(e);if(g.Object(e)){var s,a={};e.constructor&&e.constructor!==Object&&(a=Object.create(e.constructor.prototype));for(s in e)e.hasOwnProperty(s)&&(a[s]=t?v(e[s]):e[s]);return a}return e}function a(t,e){return function(r){return e(t(r))}}function u(t,e){var r,n;for(r=0,n=t.length;n>r;r++)if(e(t[r]))return t[r]}function h(t,e){var r,n;for(r=0,n=t.length;n>r;r++)if(e(t[r]))return r;return-1}function c(t,e){var r,n=!0;if(!t)return!1;for(r in e)if(g.Object(e[r]))n=n&&c(t[r],e[r]);else if(g.Array(e[r]))n=n&&!!~e[r].indexOf(t[r]);else if(t[r]!==e[r])return!1;return n}function l(t,e){return u(t,function(t){return c(t,e)})}function f(t,e){return h(t,function(t){return c(t,e)})}function p(t,e){e=e||[];var r,n,o=t;for(r=0,n=e.length;n>r;r++){if(!o)return;if("function"==typeof e[r]){if(!g.Array(o))return;o=u(o,e[r])}else if("object"==typeof e[r]){if(!g.Array(o))return;o=l(o,e[r])}else o=o[e[r]]}return o}function d(t,e){var r,n,o,i=[],s=t;for(n=0,o=e.length;o>n;n++){if(!s)return null;if("function"==typeof e[n]){if(!g.Array(s))return;r=h(s,e[n]),i.push(r),s=s[r]}else if("object"==typeof e[n]){if(!g.Array(s))return;r=f(s,e[n]),i.push(r),s=s[r]}else i.push(e[n]),s=s[e[n]]||{}}return i}function y(t,e){var r,n=t.length,o={},i=o;for(n||(o=e),r=0;n>r;r++)i[t[r]]=r+1===n?e:{},i=i[t[r]];return o}function b(t,e){t.super_=e;var r=function(){};r.prototype=e.prototype,t.prototype=new r,t.prototype.constructor=t}var g=t("./type.js"),m=s.bind(null,!1),v=s.bind(null,!0);e.exports={arrayOf:r,before:n,deepClone:v,shallowClone:m,shallowMerge:o,compose:a,getIn:p,inherits:b,pathObject:y,solvePath:d}},{"./type.js":10}],8:[function(t,e){function r(t,e){return e in(t||{})}function n(t,e,n){return r(t,n)&&r(e,n)}function o(){var t,e,r,a,u={},h=arguments.length;for(r=h-1;r>=0;r--){if(arguments[r].$unset)delete u.$set,delete u.$apply,delete u.$merge,u.$unset=arguments[r].$unset;else{if(arguments[r].$set){delete u.$apply,delete u.$merge,delete u.$unset,u.$set=arguments[r].$set;continue}if(arguments[r].$merge){delete u.$set,delete u.$apply,delete u.$unset,u.$merge=arguments[r].$merge;continue}if(arguments[r].$apply){delete u.$set,delete u.$merge,delete u.$unset,u.$apply=arguments[r].$apply;continue}if(arguments[r].$chain){delete u.$set,delete u.$merge,delete u.$unset,u.$apply=u.$apply?i.compose(u.$apply,arguments[r].$chain):arguments[r].$chain;continue}}for(a in arguments[r])t=u[a],e=arguments[r][a],t&&s.Object(e)?n(t,e,"$push")?t.$push=s.Array(t.$push)?t.$push.concat(e.$push):[t.$push].concat(e.$push):n(t,e,"$unshift")?t.$unshift=s.Array(e.$unshift)?e.$unshift.concat(t.$unshift):[e.$unshift].concat(t.$unshift):u[a]=o(e,t):u[a]=e}return u}var i=t("./helpers.js"),s=t("./type.js");e.exports=o},{"./helpers.js":7,"./type.js":10}],9:[function(t,e){var r=t("./combination.js"),n=t("./type.js");e.exports={baobab:function(t){return{mixins:[{getInitialState:function(){if(this.tree=t,!this.cursor&&!this.cursors)return{};if(this.cursor&&this.cursors)throw Error("baobab.mixin: you cannot have both `component.cursor` and `component.cursors`. Please make up your mind.");if(this.__type=null,this.__updateHandler=function(){this.setState(this.__getCursorData())}.bind(this),this.cursor){if(!n.MixinCursor(this.cursor))throw Error("baobab.mixin.cursor: invalid data (cursor, string, array or function).");n.Function(this.cursor)&&(this.cursor=this.cursor()),n.Cursor(this.cursor)||(this.cursor=t.select(this.cursor)),this.__getCursorData=function(){return{cursor:this.cursor.get()}}.bind(this),this.__type="single"}else if(this.cursors){if(!n.MixinCursors(this.cursors))throw Error("baobab.mixin.cursor: invalid data (object, array or function).");if(n.Function(this.cursors)&&(this.cursors=this.cursors()),n.Array(this.cursors))this.cursors=this.cursors.map(function(e){return n.Cursor(e)?e:t.select(e)}),this.__getCursorData=function(){return{cursors:this.cursors.map(function(t){return t.get()})}}.bind(this),this.__type="array";else{for(var e in this.cursors)n.Cursor(this.cursors[e])||(this.cursors[e]=t.select(this.cursors[e]));this.__getCursorData=function(){var t={};for(e in this.cursors)t[e]=this.cursors[e].get();return{cursors:t}}.bind(this),this.__type="object"}}return this.__getCursorData()},componentDidMount:function(){"single"===this.__type?(this.__combination=new r("or",[this.cursor]),this.__combination.on("update",this.__updateHandler)):"array"===this.__type?(this.__combination=new r("or",this.cursors),this.__combination.on("update",this.__updateHandler)):"object"===this.__type&&(this.__combination=new r("or",Object.keys(this.cursors).map(function(t){return this.cursors[t]},this)),this.__combination.on("update",this.__updateHandler))},componentWillUnmount:function(){this.__combination&&this.__combination.release()}}].concat(t.options.mixins)}},cursor:function(t){return{mixins:[{getInitialState:function(){return this.cursor=t,this.__updateHandler=function(){this.setState({cursor:this.cursor.get()})}.bind(this),{cursor:this.cursor.get()}},componentDidMount:function(){this.cursor.on("update",this.__updateHandler)},componentWillUnmount:function(){this.cursor.off("update",this.__updateHandler)}}].concat(t.tree.options.mixins)}}}},{"./combination.js":5,"./type.js":10}],10:[function(t,e){var r=function(t){return Array.isArray(t)?"array":"object"==typeof t&&null!==t?"object":"string"==typeof t?"string":"number"==typeof t?"number":"boolean"==typeof t?"boolean":"function"==typeof t?"function":null===t?"null":void 0===t?"undefined":t instanceof Date?"date":"invalid"};r.Array=function(t){return Array.isArray(t)},r.Object=function(t){return!Array.isArray(t)&&"object"==typeof t&&null!==t},r.String=function(t){return"string"==typeof t},r.Number=function(t){return"number"==typeof t},r.Boolean=function(t){return"boolean"==typeof t},r.Function=function(t){return"function"==typeof t},r.Primitive=function(t){return"string"==typeof t||"number"==typeof t||"boolean"==typeof t},r.Date=function(t){return t instanceof Date},r.Step=function(t){var e=r(t),n=["null","undefined","invalid","date"];return-1===n.indexOf(e)},r.Path=function(t){var e=["object","string","number","function","undefined"];if(!r.Array(t))return e.indexOf(r(t))>=0;for(var n=0;n=0||r.Cursor(t)},r.MixinCursors=function(t){var e=["array","object","function"];return e.indexOf(r(t))>=0},r.ComplexPath=function(t){for(var e=["object","function"],n=0;n=0)return!0;return!1},e.exports=r},{}],11:[function(t,e){function r(t,e){var r=new Error("baobab.update: "+e+" at path /"+t.toString());return r.path=t,r}function n(t,e,n){n=n||{shiftReferences:!1};var a={};return function u(t,e,h,c){h=h||[];var l,f,p,d,y=h.join("λ");for(p in e)if(s[p])switch(d=e[p],a[y]=!0,p){case"$push":if(!i.Array(t))throw r(h,"using command $push to a non array");i.Array(d)?t.push.apply(t,d):t.push(d);break;case"$unshift":if(!i.Array(t))throw r(h,"using command $unshift to a non array");i.Array(d)?t.unshift.apply(t,d):t.unshift(d)}else if(f=y?y+"λ"+p:p,"$unset"in(e[p]||{}))a[f]=!0,i.Array(t)?n.shiftReferences?c[h[h.length-1]]=t.slice(0,+p).concat(t.slice(+p+1)):t.splice(p,1):delete t[p];else if("$set"in(e[p]||{}))d=e[p].$set,a[f]=!0,t[p]=d;else if("$apply"in(e[p]||{})||"$chain"in(e[p]||{})){if(l=e[p].$apply||e[p].$chain,"function"!=typeof l)throw r(h.concat(p),"using command $apply with a non function");a[f]=!0,t[p]=l.call(null,t[p])}else if("$merge"in(e[p]||{})){if(d=e[p].$merge,!i.Object(t[p]))throw r(h.concat(p),"using command $merge on a non-object");a[f]=!0,t[p]=o.shallowMerge(t[p],d)}else if(n.shiftReferences&&("$push"in(e[p]||{})||"$unshift"in(e[p]||{}))){if("$push"in(e[p]||{})){if(d=e[p].$push,!i.Array(t[p]))throw r(h.concat(p),"using command $push to a non array");t[p]=t[p].concat(d)}if("$unshift"in(e[p]||{})){if(d=e[p].$unshift,!i.Array(t[p]))throw r(h.concat(p),"using command $unshift to a non array");t[p]=(d instanceof Array?d:[d]).concat(t[p])}a[f]=!0}else"undefined"==typeof t[p]&&(t[p]={}),n.shiftReferences&&(t[p]=o.shallowClone(t[p])),u(t[p],e[p],h.concat(p),t)}(t,e),Object.keys(a).map(function(t){return t.split("λ")})}var o=t("./helpers.js"),i=t("./type.js"),s={};["$set","$push","$unshift","$apply","$merge"].forEach(function(t){s[t]=!0}),e.exports=n},{"./helpers.js":7,"./type.js":10}]},{},[2])(2)}); \ No newline at end of file diff --git a/src/combination.js b/src/combination.js index ce4d349..ca06bde 100644 --- a/src/combination.js +++ b/src/combination.js @@ -90,15 +90,8 @@ function Combination(operator /*, &cursors */) { }); }; - this.on = function() { - lazyBind(); - return regularOn.apply(this, arguments); - }; - - this.once = function() { - lazyBind(); - return regularOnce.apply(this, arguments); - }; + this.on = helpers.before(lazyBind, this.on.bind(this)); + this.once = helpers.before(lazyBind, this.once.bind(this)); // Attaching any other passed cursors rest.forEach(function(cursor) { diff --git a/src/cursor.js b/src/cursor.js index 282aec5..e192e2a 100644 --- a/src/cursor.js +++ b/src/cursor.js @@ -93,9 +93,7 @@ function Cursor(tree, path, solvedPath, hash) { this.mixin = mixins.cursor(this); // Lazy binding - var bound = false, - regularOn = this.on, - regularOnce = this.once; + var bound = false; var lazyBind = function() { if (bound) @@ -104,15 +102,8 @@ function Cursor(tree, path, solvedPath, hash) { self.tree.on('update', self.updateHandler); }; - this.on = function() { - lazyBind(); - return regularOn.apply(this, arguments); - }; - - this.once = function() { - lazyBind(); - return regularOnce.apply(this, arguments); - }; + this.on = helpers.before(lazyBind, this.on.bind(this)); + this.once = helpers.before(lazyBind, this.once.bind(this)); } helpers.inherits(Cursor, EventEmitter); diff --git a/src/helpers.js b/src/helpers.js index 5c0c8bf..e73c513 100644 --- a/src/helpers.js +++ b/src/helpers.js @@ -11,6 +11,14 @@ function arrayOf(o) { return Array.prototype.slice.call(o); } +// Decorate a function by applying something before it +function before(decorator, fn) { + return function() { + decorator(); + fn.apply(null, arguments); + }; +} + // Shallow merge function shallowMerge(o1, o2) { var o = {}, @@ -247,6 +255,7 @@ function inherits(ctor, superCtor) { module.exports = { arrayOf: arrayOf, + before: before, deepClone: deepClone, shallowClone: shallowClone, shallowMerge: shallowMerge, diff --git a/test/suites/helpers.js b/test/suites/helpers.js index 6c97194..6931299 100644 --- a/test/suites/helpers.js +++ b/test/suites/helpers.js @@ -22,6 +22,18 @@ describe('Helpers', function() { }); }); + describe('Decoration', function() { + + it('should be possible to produce a before decoration.', function() { + var count = 0, + inc = function(i) { count++; }, + decorated = helpers.before(inc, inc); + + decorated(); + assert.strictEqual(count, 2); + }); + }); + describe('Nested get', function() { it('should be possible to retrieve nested items through the helper.', function() { assert.deepEqual(helpers.getIn(state, ['one', 'subtwo', 'colors']), state.one.subtwo.colors); From 4c76d7aeb8b69c2ccd2ea88f73a25d979e83041b Mon Sep 17 00:00:00 2001 From: Yomguithereal Date: Sat, 28 Mar 2015 00:11:16 +0100 Subject: [PATCH 09/73] Fixing tests --- test/suites/baobab.js | 1 - test/suites/cursor.js | 1 - 2 files changed, 2 deletions(-) diff --git a/test/suites/baobab.js b/test/suites/baobab.js index 95befc6..f1ff8ed 100644 --- a/test/suites/baobab.js +++ b/test/suites/baobab.js @@ -4,7 +4,6 @@ */ var assert = require('assert'), state = require('../state.js'), - Typology = require('typology'), Baobab = require('../../src/baobab.js'), Cursor = require('../../src/cursor.js'), async = require('async'), diff --git a/test/suites/cursor.js b/test/suites/cursor.js index afb0d75..b4fddab 100644 --- a/test/suites/cursor.js +++ b/test/suites/cursor.js @@ -5,7 +5,6 @@ var assert = require('assert'), state = require('../state.js'), helpers = require('../../src/helpers.js'), - Typology = require('typology'), Baobab = require('../../src/baobab.js'), async = require('async'); From cfe7d94f6d4cc9575b7ed641f9f74bb0b21d8bba Mon Sep 17 00:00:00 2001 From: Yomguithereal Date: Mon, 30 Mar 2015 09:45:47 +0200 Subject: [PATCH 10/73] Adding iojs to testing stack --- .travis.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.travis.yml b/.travis.yml index 587bd3e..18d1eb0 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1 +1,4 @@ language: node_js +node_js: + - "node" + - "iojs" From 319df87ad4775d53a5781aa3d663e2068b0092a3 Mon Sep 17 00:00:00 2001 From: Yomguithereal Date: Mon, 30 Mar 2015 19:27:13 +0200 Subject: [PATCH 11/73] Slight refactor --- build/baobab.min.js | 2 +- src/baobab.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/build/baobab.min.js b/build/baobab.min.js index 79be86b..ba82c43 100644 --- a/build/baobab.min.js +++ b/build/baobab.min.js @@ -1,2 +1,2 @@ /* baobab.js - Version: 0.4.3 - Author: Yomguithereal (Guillaume Plique) */ -!function(t){if("object"==typeof exports&&"undefined"!=typeof module)module.exports=t();else if("function"==typeof define&&define.amd)define([],t);else{var e;e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:this,e.Baobab=t()}}(function(){var t;return function e(t,r,n){function o(s,a){if(!r[s]){if(!t[s]){var u="function"==typeof require&&require;if(!a&&u)return u(s,!0);if(i)return i(s,!0);var h=new Error("Cannot find module '"+s+"'");throw h.code="MODULE_NOT_FOUND",h}var c=r[s]={exports:{}};t[s][0].call(c.exports,function(e){var r=t[s][1][e];return o(r?r:e)},c,c.exports,e,t,r,n)}return r[s].exports}for(var i="function"==typeof require&&require,s=0;se;e++)n.push(t[e].handler);return n}var o={once:"boolean",scope:"object"},i=function(){this._enabled=!0,this._children=[],this._handlers={},this._handlersAll=[]};i.prototype.on=function(t,e,r){var n,s,a,u,h,c;if("function"==typeof e){for(h="string"==typeof t?[t]:t,n=0,s=h.length;n!==s;n+=1)if(u=h[n]){this._handlers[u]||(this._handlers[u]=[]),c={handler:e};for(a in r||{}){if(!o[a])throw new Error('The option "'+a+'" is not recognized by Emmett.');c[a]=r[a]}this._handlers[u].push(c)}}else if(t&&"object"==typeof t&&!Array.isArray(t))for(u in t)i.prototype.on.call(this,u,t[u],e);else{if("function"!=typeof t)throw new Error("Wrong arguments.");c={handler:t};for(a in r||{}){if(!o[a])throw new Error('The option "'+a+'" is not recognized by Emmett.');c[a]=r[a]}this._handlersAll.push(c)}return this},i.prototype.once=function(t,e,r){if("function"==typeof e)r=r||{},r.once=!0,this.on(t,e,r);else{if((!t||"object"!=typeof t||Array.isArray(t))&&"function"!=typeof t)throw new Error("Wrong arguments.");e=e||{},e.once=!0,this.on(t,e)}return this},i.prototype.off=function(t,e){var r,n,o,i,s,a,u,h="string"==typeof t?[t]:t;if(1===arguments.length&&"function"==typeof h){e=arguments[0];for(s in this._handlers){for(a=[],r=0,n=this._handlers[s].length;r!==n;r+=1)this._handlers[s][r].handler!==e&&a.push(this._handlers[s][r]);this._handlers[s]=a}for(a=[],r=0,n=this._handlersAll.length;r!==n;r+=1)this._handlersAll[r].handler!==e&&a.push(this._handlersAll[r]);this._handlersAll=a}else if(2===arguments.length)for(r=0,n=h.length;r!==n;r+=1){if(u=h[r],this._handlers[u]){for(a=[],o=0,i=this._handlers[u].length;o!==i;o+=1)this._handlers[u][o].handler!==e&&a.push(this._handlers[u][o]);this._handlers[u]=a}this._handlers[u]&&0===this._handlers[u].length&&delete this._handlers[u]}return this},i.prototype.unbindAll=function(){var t;this._handlersAll=[];for(t in this._handlers)delete this._handlers[t];return this},i.prototype.emit=function(t,e){var r,n,o,i,s,a,u,h,c,l,f="string"==typeof t?[t]:t;if(!this._enabled)return this;for(e=void 0===e?{}:e,r=0,n=f.length;r!==n;r+=1)if(l=f[r],c=(this._handlers[l]||[]).concat(this._handlersAll),c.length){for(u={type:l,data:e||{},target:this},a=[],o=0,i=c.length;o!==i;o+=1)(this._handlers[l]&&this._handlers[l].indexOf(c[o])>=0||this._handlersAll.indexOf(c[o])>=0)&&(c[o].handler.call("scope"in c[o]?c[o].scope:this,u),c[o].once&&a.push(c[o]));for(s=0;sr;r++)if(t._children[r]===e){t._children.splice(r,1);break}}),this._children.push(e),e},i.prototype.listeners=function(t){var r,n,o,i=[];if(t)for(i=e(this._handlers[t]),n=0,o=this._children.length;o>n;n++)i=i.concat(this._children[n].listeners(t));else{i=e(this._handlersAll);for(r in this._handlers)i=i.concat(e(this._handlers[r]));for(n=0,o=this._children.length;o>n;n++)i=i.concat(this._children[n].listeners())}return i},i.prototype.kill=function(){if(this.emit("emmett:kill"),this.unbindAll(),this._handlers=null,this._handlersAll=null,this._enabled=!1,this._children)for(var t=0,e=this._children.length;e>t;t++)this._children[t].kill();this._children=null},i.prototype.disable=function(){return this._enabled=!1,this},i.prototype.enable=function(){return this._enabled=!0,this},i.version="2.1.2","undefined"!=typeof n?("undefined"!=typeof r&&r.exports&&(n=r.exports=i),n.Emitter=i):"function"==typeof t&&t.amd?t("emmett",[],function(){return i}):this.Emitter=i}).call(this)},{}],4:[function(t,e){function r(t){return t+"$"+(new Date).getTime()+(""+Math.random()).replace("0.","")}function n(t,e){function r(t){this[t]=function(){var e=this.root[t].apply(this.root,arguments);return e instanceof o?this:e}}if(arguments.length<1&&(t={}),!(this instanceof n))return new n(t,e);if(!l.Object(t)&&!l.Array(t))throw Error("Baobab: invalid data.");i.call(this),this.options=s.shallowMerge(c,e),this._transaction={},this._future=void 0,this._cursors={},this.data=s.deepClone(t),this.root=this.select([]),["get","set","unset","update"].forEach(r.bind(this)),this.mixin=h.baobab(this)}var o=t("./cursor.js"),i=t("emmett"),s=t("./helpers.js"),a=t("./update.js"),u=t("./merge.js"),h=t("./mixins.js"),c=t("../defaults.js"),l=t("./type.js");s.inherits(n,i),n.prototype.select=function(t){if(!t)throw Error("Baobab.select: invalid path.");if(arguments.length>1&&(t=s.arrayOf(arguments)),!l.Path(t))throw Error("Baobab.select: invalid path.");t=l.Array(t)?t:[t];var e,n=l.ComplexPath(t);n&&(e=s.solvePath(this.data,t));var i=t.map(function(t){return l.Function(t)?r("fn"):l.Object(t)?r("ob"):t}).join("λ");if(this._cursors[i])return this._cursors[i];var a=new o(this,t,e,i);return this._cursors[i]=a,a},n.prototype.stack=function(t){var e=this;if(!l.Object(t))throw Error("Baobab.update: wrong specification.");return this._transaction=u(t,this._transaction),this.options.autoCommit?this.options.asynchronous?(this._future||(this._future=setTimeout(e.commit.bind(e,null),0)),this):this.commit():this},n.prototype.commit=function(){this.options.shiftReferences&&(this.data=s.shallowClone(this.data));var t=a(this.data,this._transaction,this.options);return this._transaction={},this._future&&(this._future=clearTimeout(this._future)),this.emit("update",{log:t}),this},n.prototype.release=function(){delete this.data,delete this._transaction;for(var t in this._cursors)this._cursors[t].release();delete this._cursors,this.kill()},n.prototype.toJSON=function(){return this.get()},e.exports=n},{"../defaults.js":1,"./cursor.js":6,"./helpers.js":7,"./merge.js":8,"./mixins.js":9,"./type.js":10,"./update.js":11,emmett:3}],5:[function(t,e){function r(t,e){e.on("update",t.cursorListener),t.tree.off("update",t.treeListener),t.tree.on("update",t.treeListener)}function n(t){var e=this;if(arguments.length<2)throw Error("baobab.Combination: not enough arguments.");var n=arguments[1],o=s.arrayOf(arguments).slice(2);if(n instanceof Array&&(o=n.slice(1),n=n[0]),!a.Cursor(n))throw Error("baobab.Combination: argument should be a cursor.");if("or"!==t&&"and"!==t)throw Error("baobab.Combination: invalid operator.");i.call(this),this.cursors=[n],this.operators=[],this.tree=n.tree,this.updates=new Array(this.cursors.length),this.cursorListener=function(){e.updates[e.cursors.indexOf(this)]=!0},this.treeListener=function(){var t,r,n=e.updates[0];for(t=1,r=e.cursors.length;r>t;t++)n="or"===e.operators[t-1]?n||e.updates[t]:n&&e.updates[t];n&&e.emit("update"),e.updates=new Array(e.cursors.length)},this.bound=!1;var u=(this.on,this.once,function(){e.bound||(e.bound=!0,e.cursors.forEach(function(t){r(e,t)}))});this.on=s.before(u,this.on.bind(this)),this.once=s.before(u,this.once.bind(this)),o.forEach(function(e){this[t](e)},this)}function o(t){n.prototype[t]=function(e){if(!a.Cursor(e))throw this.release(),Error("baobab.Combination."+t+": argument should be a cursor.");if(~this.cursors.indexOf(e))throw this.release(),Error("baobab.Combination."+t+": cursor already in combination.");return this.cursors.push(e),this.operators.push(t),this.updates.length++,this.bound&&r(this,e),this}}var i=t("emmett"),s=t("./helpers.js"),a=t("./type.js");s.inherits(n,i),o("or"),o("and"),n.prototype.release=function(){this.cursors.forEach(function(t){t.off("update",this.cursorListener)},this),this.tree.off("update",this.treeListener),this.cursors=null,this.operators=null,this.tree=null,this.updates=null,this.kill()},e.exports=n},{"./helpers.js":7,"./type.js":10,emmett:3}],6:[function(t,e){function r(t,e,r,o){var a=this;n.call(this),e=e||[],this.tree=t,this.path=e,this.hash=o,this.complexPath=!!r,this.solvedPath=this.complexPath?r:this.path,this.relevant=void 0!==this.get(),this.updateHandler=function(t){var e,r,n,o,i,u,h=t.data.log,c=!1;if(a.complexPath&&(a.solvedPath=s.solvePath(a.tree.data,a.path)),!a.path.length)return a.emit("update");t:for(i=0,n=h.length;n>i;i++)for(e=h[i],u=0,o=e.length;o>u&&(r=e[u],r===""+a.solvedPath[u]);u++)if(u+1===o||u+1===a.solvedPath.length){c=!0;break t}var l=void 0!==a.get();a.relevant?l&&c?a.emit("update"):l||(a.emit("irrelevant"),a.relevant=!1):l&&c&&(a.emit("relevant"),a.emit("update"),a.relevant=!0)},this.mixin=i.cursor(this);var u=!1,h=function(){u||(u=!0,a.tree.on("update",a.updateHandler))};this.on=s.before(h,this.on.bind(this)),this.once=s.before(h,this.once.bind(this))}var n=t("emmett"),o=t("./combination.js"),i=t("./mixins.js"),s=t("./helpers.js"),a=t("./type.js");s.inherits(r,n),r.prototype.isRoot=function(){return!this.path.length},r.prototype.isLeaf=function(){return a.Primitive(this.get())},r.prototype.isBranch=function(){return!this.isLeaf()&&!this.isRoot()},r.prototype.root=function(){return this.tree.root()},r.prototype.select=function(t){if(arguments.length>1&&(t=s.arrayOf(arguments)),!a.Path(t))throw Error("baobab.Cursor.select: invalid path.");return this.tree.select(this.path.concat(t))},r.prototype.up=function(){return this.solvedPath&&this.solvedPath.length?this.tree.select(this.path.slice(0,-1)):null},r.prototype.left=function(){var t=+this.solvedPath[this.solvedPath.length-1];if(isNaN(t))throw Error("baobab.Cursor.left: cannot go left on a non-list type.");return t?this.tree.select(this.solvedPath.slice(0,-1).concat(t-1)):null},r.prototype.leftmost=function(){var t=+this.solvedPath[this.solvedPath.length-1];if(isNaN(t))throw Error("baobab.Cursor.leftmost: cannot go left on a non-list type.");return this.tree.select(this.solvedPath.slice(0,-1).concat(0))},r.prototype.right=function(){var t=+this.solvedPath[this.solvedPath.length-1];if(isNaN(t))throw Error("baobab.Cursor.right: cannot go right on a non-list type.");return t+1===this.up().get().length?null:this.tree.select(this.solvedPath.slice(0,-1).concat(t+1))},r.prototype.rightmost=function(){var t=+this.solvedPath[this.solvedPath.length-1];if(isNaN(t))throw Error("baobab.Cursor.right: cannot go right on a non-list type.");var e=this.up().get();return this.tree.select(this.solvedPath.slice(0,-1).concat(e.length-1))},r.prototype.down=function(){+this.solvedPath[this.solvedPath.length-1];return this.get()instanceof Array?this.tree.select(this.solvedPath.concat(0)):null},r.prototype.get=function(t){arguments.length>1&&(t=s.arrayOf(arguments));var e=this.solvedPath.concat((a.String(t)||a.Number(t)?[t]:t)||[]);return s.getIn(this.tree.data,e)},r.prototype.set=function(t,e){if(arguments.length<2)throw Error("baobab.Cursor.set: expecting at least key/value.");var r=this.get();if("object"!=typeof r)throw Error("baobab.Cursor.set: trying to set key to a non-object.");var n={};if(a.Array(t)){var o=s.solvePath(r,t);if(!o)throw Error("baobab.Cursor.set: could not solve dynamic path.");n=s.pathObject(o,{$set:e})}else n[t]={$set:e};return this.update(n)},r.prototype.edit=function(t){return this.update({$set:t})},r.prototype.unset=function(t){if(!t&&0!==t)throw Error("baobab.Cursor.unset: expects a valid key to unset.");if("object"!=typeof this.get())throw Error("baobab.Cursor.set: trying to set key to a non-object.");var e={};return e[t]={$unset:!0},this.update(e)},r.prototype.remove=function(){if(this.isRoot())throw Error("baobab.Cursor.remove: cannot remove root node.");return this.update({$unset:!0})},r.prototype.apply=function(t){if("function"!=typeof t)throw Error("baobab.Cursor.apply: argument is not a function.");return this.update({$apply:t})},r.prototype.chain=function(t){if("function"!=typeof t)throw Error("baobab.Cursor.chain: argument is not a function.");return this.update({$chain:t})},r.prototype.push=function(t){if(!(this.get()instanceof Array))throw Error("baobab.Cursor.push: trying to push to non-array value.");return this.update(arguments.length>1?{$push:s.arrayOf(arguments)}:{$push:t})},r.prototype.unshift=function(t){if(!(this.get()instanceof Array))throw Error("baobab.Cursor.push: trying to push to non-array value.");return this.update(arguments.length>1?{$unshift:s.arrayOf(arguments)}:{$unshift:t})},r.prototype.merge=function(t){if(!a.Object(t))throw Error("baobab.Cursor.merge: trying to merge a non-object.");if(!a.Object(this.get()))throw Error("baobab.Cursor.merge: trying to merge into a non-object.");this.update({$merge:t})},r.prototype.update=function(t){return this.tree.stack(s.pathObject(this.solvedPath,t)),this},r.prototype.or=function(t){return new o("or",this,t)},r.prototype.and=function(t){return new o("and",this,t)},r.prototype.release=function(){this.tree.off("update",this.updateHandler),this.hash&&delete this.tree._cursors[this.hash],delete this.tree,delete this.path,delete this.solvedPath,this.kill()},r.prototype.toJSON=function(){return this.get()},a.Cursor=function(t){return t instanceof r},e.exports=r},{"./combination.js":5,"./helpers.js":7,"./mixins.js":9,"./type.js":10,emmett:3}],7:[function(t,e){function r(t){return Array.prototype.slice.call(t)}function n(t,e){return function(){t(),e.apply(null,arguments)}}function o(t,e){var r,n={};for(r in t)n[r]=t[r];for(r in e)n[r]=e[r];return n}function i(t){var e=t.source,r="";return t.global&&(r+="g"),t.multiline&&(r+="m"),t.ignoreCase&&(r+="i"),t.sticky&&(r+="y"),t.unicode&&(r+="u"),new RegExp(e,r)}function s(t,e){if(!e||"object"!=typeof e||e instanceof Error||e instanceof ArrayBuffer)return e;if(g.Array(e)){if(t){var r,n,o=[];for(r=0,n=e.length;n>r;r++)o.push(v(e[r]));return o}return e.slice(0)}if(g.Date(e))return new Date(e.getTime());if(e instanceof RegExp)return i(e);if(g.Object(e)){var s,a={};e.constructor&&e.constructor!==Object&&(a=Object.create(e.constructor.prototype));for(s in e)e.hasOwnProperty(s)&&(a[s]=t?v(e[s]):e[s]);return a}return e}function a(t,e){return function(r){return e(t(r))}}function u(t,e){var r,n;for(r=0,n=t.length;n>r;r++)if(e(t[r]))return t[r]}function h(t,e){var r,n;for(r=0,n=t.length;n>r;r++)if(e(t[r]))return r;return-1}function c(t,e){var r,n=!0;if(!t)return!1;for(r in e)if(g.Object(e[r]))n=n&&c(t[r],e[r]);else if(g.Array(e[r]))n=n&&!!~e[r].indexOf(t[r]);else if(t[r]!==e[r])return!1;return n}function l(t,e){return u(t,function(t){return c(t,e)})}function f(t,e){return h(t,function(t){return c(t,e)})}function p(t,e){e=e||[];var r,n,o=t;for(r=0,n=e.length;n>r;r++){if(!o)return;if("function"==typeof e[r]){if(!g.Array(o))return;o=u(o,e[r])}else if("object"==typeof e[r]){if(!g.Array(o))return;o=l(o,e[r])}else o=o[e[r]]}return o}function d(t,e){var r,n,o,i=[],s=t;for(n=0,o=e.length;o>n;n++){if(!s)return null;if("function"==typeof e[n]){if(!g.Array(s))return;r=h(s,e[n]),i.push(r),s=s[r]}else if("object"==typeof e[n]){if(!g.Array(s))return;r=f(s,e[n]),i.push(r),s=s[r]}else i.push(e[n]),s=s[e[n]]||{}}return i}function y(t,e){var r,n=t.length,o={},i=o;for(n||(o=e),r=0;n>r;r++)i[t[r]]=r+1===n?e:{},i=i[t[r]];return o}function b(t,e){t.super_=e;var r=function(){};r.prototype=e.prototype,t.prototype=new r,t.prototype.constructor=t}var g=t("./type.js"),m=s.bind(null,!1),v=s.bind(null,!0);e.exports={arrayOf:r,before:n,deepClone:v,shallowClone:m,shallowMerge:o,compose:a,getIn:p,inherits:b,pathObject:y,solvePath:d}},{"./type.js":10}],8:[function(t,e){function r(t,e){return e in(t||{})}function n(t,e,n){return r(t,n)&&r(e,n)}function o(){var t,e,r,a,u={},h=arguments.length;for(r=h-1;r>=0;r--){if(arguments[r].$unset)delete u.$set,delete u.$apply,delete u.$merge,u.$unset=arguments[r].$unset;else{if(arguments[r].$set){delete u.$apply,delete u.$merge,delete u.$unset,u.$set=arguments[r].$set;continue}if(arguments[r].$merge){delete u.$set,delete u.$apply,delete u.$unset,u.$merge=arguments[r].$merge;continue}if(arguments[r].$apply){delete u.$set,delete u.$merge,delete u.$unset,u.$apply=arguments[r].$apply;continue}if(arguments[r].$chain){delete u.$set,delete u.$merge,delete u.$unset,u.$apply=u.$apply?i.compose(u.$apply,arguments[r].$chain):arguments[r].$chain;continue}}for(a in arguments[r])t=u[a],e=arguments[r][a],t&&s.Object(e)?n(t,e,"$push")?t.$push=s.Array(t.$push)?t.$push.concat(e.$push):[t.$push].concat(e.$push):n(t,e,"$unshift")?t.$unshift=s.Array(e.$unshift)?e.$unshift.concat(t.$unshift):[e.$unshift].concat(t.$unshift):u[a]=o(e,t):u[a]=e}return u}var i=t("./helpers.js"),s=t("./type.js");e.exports=o},{"./helpers.js":7,"./type.js":10}],9:[function(t,e){var r=t("./combination.js"),n=t("./type.js");e.exports={baobab:function(t){return{mixins:[{getInitialState:function(){if(this.tree=t,!this.cursor&&!this.cursors)return{};if(this.cursor&&this.cursors)throw Error("baobab.mixin: you cannot have both `component.cursor` and `component.cursors`. Please make up your mind.");if(this.__type=null,this.__updateHandler=function(){this.setState(this.__getCursorData())}.bind(this),this.cursor){if(!n.MixinCursor(this.cursor))throw Error("baobab.mixin.cursor: invalid data (cursor, string, array or function).");n.Function(this.cursor)&&(this.cursor=this.cursor()),n.Cursor(this.cursor)||(this.cursor=t.select(this.cursor)),this.__getCursorData=function(){return{cursor:this.cursor.get()}}.bind(this),this.__type="single"}else if(this.cursors){if(!n.MixinCursors(this.cursors))throw Error("baobab.mixin.cursor: invalid data (object, array or function).");if(n.Function(this.cursors)&&(this.cursors=this.cursors()),n.Array(this.cursors))this.cursors=this.cursors.map(function(e){return n.Cursor(e)?e:t.select(e)}),this.__getCursorData=function(){return{cursors:this.cursors.map(function(t){return t.get()})}}.bind(this),this.__type="array";else{for(var e in this.cursors)n.Cursor(this.cursors[e])||(this.cursors[e]=t.select(this.cursors[e]));this.__getCursorData=function(){var t={};for(e in this.cursors)t[e]=this.cursors[e].get();return{cursors:t}}.bind(this),this.__type="object"}}return this.__getCursorData()},componentDidMount:function(){"single"===this.__type?(this.__combination=new r("or",[this.cursor]),this.__combination.on("update",this.__updateHandler)):"array"===this.__type?(this.__combination=new r("or",this.cursors),this.__combination.on("update",this.__updateHandler)):"object"===this.__type&&(this.__combination=new r("or",Object.keys(this.cursors).map(function(t){return this.cursors[t]},this)),this.__combination.on("update",this.__updateHandler))},componentWillUnmount:function(){this.__combination&&this.__combination.release()}}].concat(t.options.mixins)}},cursor:function(t){return{mixins:[{getInitialState:function(){return this.cursor=t,this.__updateHandler=function(){this.setState({cursor:this.cursor.get()})}.bind(this),{cursor:this.cursor.get()}},componentDidMount:function(){this.cursor.on("update",this.__updateHandler)},componentWillUnmount:function(){this.cursor.off("update",this.__updateHandler)}}].concat(t.tree.options.mixins)}}}},{"./combination.js":5,"./type.js":10}],10:[function(t,e){var r=function(t){return Array.isArray(t)?"array":"object"==typeof t&&null!==t?"object":"string"==typeof t?"string":"number"==typeof t?"number":"boolean"==typeof t?"boolean":"function"==typeof t?"function":null===t?"null":void 0===t?"undefined":t instanceof Date?"date":"invalid"};r.Array=function(t){return Array.isArray(t)},r.Object=function(t){return!Array.isArray(t)&&"object"==typeof t&&null!==t},r.String=function(t){return"string"==typeof t},r.Number=function(t){return"number"==typeof t},r.Boolean=function(t){return"boolean"==typeof t},r.Function=function(t){return"function"==typeof t},r.Primitive=function(t){return"string"==typeof t||"number"==typeof t||"boolean"==typeof t},r.Date=function(t){return t instanceof Date},r.Step=function(t){var e=r(t),n=["null","undefined","invalid","date"];return-1===n.indexOf(e)},r.Path=function(t){var e=["object","string","number","function","undefined"];if(!r.Array(t))return e.indexOf(r(t))>=0;for(var n=0;n=0||r.Cursor(t)},r.MixinCursors=function(t){var e=["array","object","function"];return e.indexOf(r(t))>=0},r.ComplexPath=function(t){for(var e=["object","function"],n=0;n=0)return!0;return!1},e.exports=r},{}],11:[function(t,e){function r(t,e){var r=new Error("baobab.update: "+e+" at path /"+t.toString());return r.path=t,r}function n(t,e,n){n=n||{shiftReferences:!1};var a={};return function u(t,e,h,c){h=h||[];var l,f,p,d,y=h.join("λ");for(p in e)if(s[p])switch(d=e[p],a[y]=!0,p){case"$push":if(!i.Array(t))throw r(h,"using command $push to a non array");i.Array(d)?t.push.apply(t,d):t.push(d);break;case"$unshift":if(!i.Array(t))throw r(h,"using command $unshift to a non array");i.Array(d)?t.unshift.apply(t,d):t.unshift(d)}else if(f=y?y+"λ"+p:p,"$unset"in(e[p]||{}))a[f]=!0,i.Array(t)?n.shiftReferences?c[h[h.length-1]]=t.slice(0,+p).concat(t.slice(+p+1)):t.splice(p,1):delete t[p];else if("$set"in(e[p]||{}))d=e[p].$set,a[f]=!0,t[p]=d;else if("$apply"in(e[p]||{})||"$chain"in(e[p]||{})){if(l=e[p].$apply||e[p].$chain,"function"!=typeof l)throw r(h.concat(p),"using command $apply with a non function");a[f]=!0,t[p]=l.call(null,t[p])}else if("$merge"in(e[p]||{})){if(d=e[p].$merge,!i.Object(t[p]))throw r(h.concat(p),"using command $merge on a non-object");a[f]=!0,t[p]=o.shallowMerge(t[p],d)}else if(n.shiftReferences&&("$push"in(e[p]||{})||"$unshift"in(e[p]||{}))){if("$push"in(e[p]||{})){if(d=e[p].$push,!i.Array(t[p]))throw r(h.concat(p),"using command $push to a non array");t[p]=t[p].concat(d)}if("$unshift"in(e[p]||{})){if(d=e[p].$unshift,!i.Array(t[p]))throw r(h.concat(p),"using command $unshift to a non array");t[p]=(d instanceof Array?d:[d]).concat(t[p])}a[f]=!0}else"undefined"==typeof t[p]&&(t[p]={}),n.shiftReferences&&(t[p]=o.shallowClone(t[p])),u(t[p],e[p],h.concat(p),t)}(t,e),Object.keys(a).map(function(t){return t.split("λ")})}var o=t("./helpers.js"),i=t("./type.js"),s={};["$set","$push","$unshift","$apply","$merge"].forEach(function(t){s[t]=!0}),e.exports=n},{"./helpers.js":7,"./type.js":10}]},{},[2])(2)}); \ No newline at end of file +!function(t){if("object"==typeof exports&&"undefined"!=typeof module)module.exports=t();else if("function"==typeof define&&define.amd)define([],t);else{var e;e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:this,e.Baobab=t()}}(function(){var t;return function e(t,r,n){function o(s,a){if(!r[s]){if(!t[s]){var u="function"==typeof require&&require;if(!a&&u)return u(s,!0);if(i)return i(s,!0);var h=new Error("Cannot find module '"+s+"'");throw h.code="MODULE_NOT_FOUND",h}var c=r[s]={exports:{}};t[s][0].call(c.exports,function(e){var r=t[s][1][e];return o(r?r:e)},c,c.exports,e,t,r,n)}return r[s].exports}for(var i="function"==typeof require&&require,s=0;se;e++)n.push(t[e].handler);return n}var o={once:"boolean",scope:"object"},i=function(){this._enabled=!0,this._children=[],this._handlers={},this._handlersAll=[]};i.prototype.on=function(t,e,r){var n,s,a,u,h,c;if("function"==typeof e){for(h="string"==typeof t?[t]:t,n=0,s=h.length;n!==s;n+=1)if(u=h[n]){this._handlers[u]||(this._handlers[u]=[]),c={handler:e};for(a in r||{}){if(!o[a])throw new Error('The option "'+a+'" is not recognized by Emmett.');c[a]=r[a]}this._handlers[u].push(c)}}else if(t&&"object"==typeof t&&!Array.isArray(t))for(u in t)i.prototype.on.call(this,u,t[u],e);else{if("function"!=typeof t)throw new Error("Wrong arguments.");c={handler:t};for(a in r||{}){if(!o[a])throw new Error('The option "'+a+'" is not recognized by Emmett.');c[a]=r[a]}this._handlersAll.push(c)}return this},i.prototype.once=function(t,e,r){if("function"==typeof e)r=r||{},r.once=!0,this.on(t,e,r);else{if((!t||"object"!=typeof t||Array.isArray(t))&&"function"!=typeof t)throw new Error("Wrong arguments.");e=e||{},e.once=!0,this.on(t,e)}return this},i.prototype.off=function(t,e){var r,n,o,i,s,a,u,h="string"==typeof t?[t]:t;if(1===arguments.length&&"function"==typeof h){e=arguments[0];for(s in this._handlers){for(a=[],r=0,n=this._handlers[s].length;r!==n;r+=1)this._handlers[s][r].handler!==e&&a.push(this._handlers[s][r]);this._handlers[s]=a}for(a=[],r=0,n=this._handlersAll.length;r!==n;r+=1)this._handlersAll[r].handler!==e&&a.push(this._handlersAll[r]);this._handlersAll=a}else if(2===arguments.length)for(r=0,n=h.length;r!==n;r+=1){if(u=h[r],this._handlers[u]){for(a=[],o=0,i=this._handlers[u].length;o!==i;o+=1)this._handlers[u][o].handler!==e&&a.push(this._handlers[u][o]);this._handlers[u]=a}this._handlers[u]&&0===this._handlers[u].length&&delete this._handlers[u]}return this},i.prototype.unbindAll=function(){var t;this._handlersAll=[];for(t in this._handlers)delete this._handlers[t];return this},i.prototype.emit=function(t,e){var r,n,o,i,s,a,u,h,c,l,f="string"==typeof t?[t]:t;if(!this._enabled)return this;for(e=void 0===e?{}:e,r=0,n=f.length;r!==n;r+=1)if(l=f[r],c=(this._handlers[l]||[]).concat(this._handlersAll),c.length){for(u={type:l,data:e||{},target:this},a=[],o=0,i=c.length;o!==i;o+=1)(this._handlers[l]&&this._handlers[l].indexOf(c[o])>=0||this._handlersAll.indexOf(c[o])>=0)&&(c[o].handler.call("scope"in c[o]?c[o].scope:this,u),c[o].once&&a.push(c[o]));for(s=0;sr;r++)if(t._children[r]===e){t._children.splice(r,1);break}}),this._children.push(e),e},i.prototype.listeners=function(t){var r,n,o,i=[];if(t)for(i=e(this._handlers[t]),n=0,o=this._children.length;o>n;n++)i=i.concat(this._children[n].listeners(t));else{i=e(this._handlersAll);for(r in this._handlers)i=i.concat(e(this._handlers[r]));for(n=0,o=this._children.length;o>n;n++)i=i.concat(this._children[n].listeners())}return i},i.prototype.kill=function(){if(this.emit("emmett:kill"),this.unbindAll(),this._handlers=null,this._handlersAll=null,this._enabled=!1,this._children)for(var t=0,e=this._children.length;e>t;t++)this._children[t].kill();this._children=null},i.prototype.disable=function(){return this._enabled=!1,this},i.prototype.enable=function(){return this._enabled=!0,this},i.version="2.1.2","undefined"!=typeof n?("undefined"!=typeof r&&r.exports&&(n=r.exports=i),n.Emitter=i):"function"==typeof t&&t.amd?t("emmett",[],function(){return i}):this.Emitter=i}).call(this)},{}],4:[function(t,e){function r(t){return t+"$"+(new Date).getTime()+(""+Math.random()).replace("0.","")}function n(t,e){function r(t){this[t]=function(){var e=this.root[t].apply(this.root,arguments);return e instanceof o?this:e}}if(arguments.length<1&&(t={}),!(this instanceof n))return new n(t,e);if(!l.Object(t)&&!l.Array(t))throw Error("Baobab: invalid data.");i.call(this),this.options=s.shallowMerge(c,e),this._transaction={},this._future=void 0,this._cursors={},this.data=s.deepClone(t),this.root=this.select([]),["get","set","unset","update"].forEach(r.bind(this)),this.mixin=h.baobab(this)}var o=t("./cursor.js"),i=t("emmett"),s=t("./helpers.js"),a=t("./update.js"),u=t("./merge.js"),h=t("./mixins.js"),c=t("../defaults.js"),l=t("./type.js");s.inherits(n,i),n.prototype.select=function(t){if(!t)throw Error("Baobab.select: invalid path.");if(arguments.length>1&&(t=s.arrayOf(arguments)),!l.Path(t))throw Error("Baobab.select: invalid path.");t=[].concat(t);var e,n=l.ComplexPath(t);n&&(e=s.solvePath(this.data,t));var i=t.map(function(t){return l.Function(t)?r("fn"):l.Object(t)?r("ob"):t}).join("λ");if(this._cursors[i])return this._cursors[i];var a=new o(this,t,e,i);return this._cursors[i]=a,a},n.prototype.stack=function(t){var e=this;if(!l.Object(t))throw Error("Baobab.update: wrong specification.");return this._transaction=u(t,this._transaction),this.options.autoCommit?this.options.asynchronous?(this._future||(this._future=setTimeout(e.commit.bind(e,null),0)),this):this.commit():this},n.prototype.commit=function(){this.options.shiftReferences&&(this.data=s.shallowClone(this.data));var t=a(this.data,this._transaction,this.options);return this._transaction={},this._future&&(this._future=clearTimeout(this._future)),this.emit("update",{log:t}),this},n.prototype.release=function(){delete this.data,delete this._transaction;for(var t in this._cursors)this._cursors[t].release();delete this._cursors,this.kill()},n.prototype.toJSON=function(){return this.get()},e.exports=n},{"../defaults.js":1,"./cursor.js":6,"./helpers.js":7,"./merge.js":8,"./mixins.js":9,"./type.js":10,"./update.js":11,emmett:3}],5:[function(t,e){function r(t,e){e.on("update",t.cursorListener),t.tree.off("update",t.treeListener),t.tree.on("update",t.treeListener)}function n(t){var e=this;if(arguments.length<2)throw Error("baobab.Combination: not enough arguments.");var n=arguments[1],o=s.arrayOf(arguments).slice(2);if(n instanceof Array&&(o=n.slice(1),n=n[0]),!a.Cursor(n))throw Error("baobab.Combination: argument should be a cursor.");if("or"!==t&&"and"!==t)throw Error("baobab.Combination: invalid operator.");i.call(this),this.cursors=[n],this.operators=[],this.tree=n.tree,this.updates=new Array(this.cursors.length),this.cursorListener=function(){e.updates[e.cursors.indexOf(this)]=!0},this.treeListener=function(){var t,r,n=e.updates[0];for(t=1,r=e.cursors.length;r>t;t++)n="or"===e.operators[t-1]?n||e.updates[t]:n&&e.updates[t];n&&e.emit("update"),e.updates=new Array(e.cursors.length)},this.bound=!1;var u=(this.on,this.once,function(){e.bound||(e.bound=!0,e.cursors.forEach(function(t){r(e,t)}))});this.on=s.before(u,this.on.bind(this)),this.once=s.before(u,this.once.bind(this)),o.forEach(function(e){this[t](e)},this)}function o(t){n.prototype[t]=function(e){if(!a.Cursor(e))throw this.release(),Error("baobab.Combination."+t+": argument should be a cursor.");if(~this.cursors.indexOf(e))throw this.release(),Error("baobab.Combination."+t+": cursor already in combination.");return this.cursors.push(e),this.operators.push(t),this.updates.length++,this.bound&&r(this,e),this}}var i=t("emmett"),s=t("./helpers.js"),a=t("./type.js");s.inherits(n,i),o("or"),o("and"),n.prototype.release=function(){this.cursors.forEach(function(t){t.off("update",this.cursorListener)},this),this.tree.off("update",this.treeListener),this.cursors=null,this.operators=null,this.tree=null,this.updates=null,this.kill()},e.exports=n},{"./helpers.js":7,"./type.js":10,emmett:3}],6:[function(t,e){function r(t,e,r,o){var a=this;n.call(this),e=e||[],this.tree=t,this.path=e,this.hash=o,this.complexPath=!!r,this.solvedPath=this.complexPath?r:this.path,this.relevant=void 0!==this.get(),this.updateHandler=function(t){var e,r,n,o,i,u,h=t.data.log,c=!1;if(a.complexPath&&(a.solvedPath=s.solvePath(a.tree.data,a.path)),!a.path.length)return a.emit("update");t:for(i=0,n=h.length;n>i;i++)for(e=h[i],u=0,o=e.length;o>u&&(r=e[u],r===""+a.solvedPath[u]);u++)if(u+1===o||u+1===a.solvedPath.length){c=!0;break t}var l=void 0!==a.get();a.relevant?l&&c?a.emit("update"):l||(a.emit("irrelevant"),a.relevant=!1):l&&c&&(a.emit("relevant"),a.emit("update"),a.relevant=!0)},this.mixin=i.cursor(this);var u=!1,h=function(){u||(u=!0,a.tree.on("update",a.updateHandler))};this.on=s.before(h,this.on.bind(this)),this.once=s.before(h,this.once.bind(this))}var n=t("emmett"),o=t("./combination.js"),i=t("./mixins.js"),s=t("./helpers.js"),a=t("./type.js");s.inherits(r,n),r.prototype.isRoot=function(){return!this.path.length},r.prototype.isLeaf=function(){return a.Primitive(this.get())},r.prototype.isBranch=function(){return!this.isLeaf()&&!this.isRoot()},r.prototype.root=function(){return this.tree.root()},r.prototype.select=function(t){if(arguments.length>1&&(t=s.arrayOf(arguments)),!a.Path(t))throw Error("baobab.Cursor.select: invalid path.");return this.tree.select(this.path.concat(t))},r.prototype.up=function(){return this.solvedPath&&this.solvedPath.length?this.tree.select(this.path.slice(0,-1)):null},r.prototype.left=function(){var t=+this.solvedPath[this.solvedPath.length-1];if(isNaN(t))throw Error("baobab.Cursor.left: cannot go left on a non-list type.");return t?this.tree.select(this.solvedPath.slice(0,-1).concat(t-1)):null},r.prototype.leftmost=function(){var t=+this.solvedPath[this.solvedPath.length-1];if(isNaN(t))throw Error("baobab.Cursor.leftmost: cannot go left on a non-list type.");return this.tree.select(this.solvedPath.slice(0,-1).concat(0))},r.prototype.right=function(){var t=+this.solvedPath[this.solvedPath.length-1];if(isNaN(t))throw Error("baobab.Cursor.right: cannot go right on a non-list type.");return t+1===this.up().get().length?null:this.tree.select(this.solvedPath.slice(0,-1).concat(t+1))},r.prototype.rightmost=function(){var t=+this.solvedPath[this.solvedPath.length-1];if(isNaN(t))throw Error("baobab.Cursor.right: cannot go right on a non-list type.");var e=this.up().get();return this.tree.select(this.solvedPath.slice(0,-1).concat(e.length-1))},r.prototype.down=function(){+this.solvedPath[this.solvedPath.length-1];return this.get()instanceof Array?this.tree.select(this.solvedPath.concat(0)):null},r.prototype.get=function(t){arguments.length>1&&(t=s.arrayOf(arguments));var e=this.solvedPath.concat((a.String(t)||a.Number(t)?[t]:t)||[]);return s.getIn(this.tree.data,e)},r.prototype.set=function(t,e){if(arguments.length<2)throw Error("baobab.Cursor.set: expecting at least key/value.");var r=this.get();if("object"!=typeof r)throw Error("baobab.Cursor.set: trying to set key to a non-object.");var n={};if(a.Array(t)){var o=s.solvePath(r,t);if(!o)throw Error("baobab.Cursor.set: could not solve dynamic path.");n=s.pathObject(o,{$set:e})}else n[t]={$set:e};return this.update(n)},r.prototype.edit=function(t){return this.update({$set:t})},r.prototype.unset=function(t){if(!t&&0!==t)throw Error("baobab.Cursor.unset: expects a valid key to unset.");if("object"!=typeof this.get())throw Error("baobab.Cursor.set: trying to set key to a non-object.");var e={};return e[t]={$unset:!0},this.update(e)},r.prototype.remove=function(){if(this.isRoot())throw Error("baobab.Cursor.remove: cannot remove root node.");return this.update({$unset:!0})},r.prototype.apply=function(t){if("function"!=typeof t)throw Error("baobab.Cursor.apply: argument is not a function.");return this.update({$apply:t})},r.prototype.chain=function(t){if("function"!=typeof t)throw Error("baobab.Cursor.chain: argument is not a function.");return this.update({$chain:t})},r.prototype.push=function(t){if(!(this.get()instanceof Array))throw Error("baobab.Cursor.push: trying to push to non-array value.");return this.update(arguments.length>1?{$push:s.arrayOf(arguments)}:{$push:t})},r.prototype.unshift=function(t){if(!(this.get()instanceof Array))throw Error("baobab.Cursor.push: trying to push to non-array value.");return this.update(arguments.length>1?{$unshift:s.arrayOf(arguments)}:{$unshift:t})},r.prototype.merge=function(t){if(!a.Object(t))throw Error("baobab.Cursor.merge: trying to merge a non-object.");if(!a.Object(this.get()))throw Error("baobab.Cursor.merge: trying to merge into a non-object.");this.update({$merge:t})},r.prototype.update=function(t){return this.tree.stack(s.pathObject(this.solvedPath,t)),this},r.prototype.or=function(t){return new o("or",this,t)},r.prototype.and=function(t){return new o("and",this,t)},r.prototype.release=function(){this.tree.off("update",this.updateHandler),this.hash&&delete this.tree._cursors[this.hash],delete this.tree,delete this.path,delete this.solvedPath,this.kill()},r.prototype.toJSON=function(){return this.get()},a.Cursor=function(t){return t instanceof r},e.exports=r},{"./combination.js":5,"./helpers.js":7,"./mixins.js":9,"./type.js":10,emmett:3}],7:[function(t,e){function r(t){return Array.prototype.slice.call(t)}function n(t,e){return function(){t(),e.apply(null,arguments)}}function o(t,e){var r,n={};for(r in t)n[r]=t[r];for(r in e)n[r]=e[r];return n}function i(t){var e=t.source,r="";return t.global&&(r+="g"),t.multiline&&(r+="m"),t.ignoreCase&&(r+="i"),t.sticky&&(r+="y"),t.unicode&&(r+="u"),new RegExp(e,r)}function s(t,e){if(!e||"object"!=typeof e||e instanceof Error||e instanceof ArrayBuffer)return e;if(g.Array(e)){if(t){var r,n,o=[];for(r=0,n=e.length;n>r;r++)o.push(v(e[r]));return o}return e.slice(0)}if(g.Date(e))return new Date(e.getTime());if(e instanceof RegExp)return i(e);if(g.Object(e)){var s,a={};e.constructor&&e.constructor!==Object&&(a=Object.create(e.constructor.prototype));for(s in e)e.hasOwnProperty(s)&&(a[s]=t?v(e[s]):e[s]);return a}return e}function a(t,e){return function(r){return e(t(r))}}function u(t,e){var r,n;for(r=0,n=t.length;n>r;r++)if(e(t[r]))return t[r]}function h(t,e){var r,n;for(r=0,n=t.length;n>r;r++)if(e(t[r]))return r;return-1}function c(t,e){var r,n=!0;if(!t)return!1;for(r in e)if(g.Object(e[r]))n=n&&c(t[r],e[r]);else if(g.Array(e[r]))n=n&&!!~e[r].indexOf(t[r]);else if(t[r]!==e[r])return!1;return n}function l(t,e){return u(t,function(t){return c(t,e)})}function f(t,e){return h(t,function(t){return c(t,e)})}function p(t,e){e=e||[];var r,n,o=t;for(r=0,n=e.length;n>r;r++){if(!o)return;if("function"==typeof e[r]){if(!g.Array(o))return;o=u(o,e[r])}else if("object"==typeof e[r]){if(!g.Array(o))return;o=l(o,e[r])}else o=o[e[r]]}return o}function d(t,e){var r,n,o,i=[],s=t;for(n=0,o=e.length;o>n;n++){if(!s)return null;if("function"==typeof e[n]){if(!g.Array(s))return;r=h(s,e[n]),i.push(r),s=s[r]}else if("object"==typeof e[n]){if(!g.Array(s))return;r=f(s,e[n]),i.push(r),s=s[r]}else i.push(e[n]),s=s[e[n]]||{}}return i}function y(t,e){var r,n=t.length,o={},i=o;for(n||(o=e),r=0;n>r;r++)i[t[r]]=r+1===n?e:{},i=i[t[r]];return o}function b(t,e){t.super_=e;var r=function(){};r.prototype=e.prototype,t.prototype=new r,t.prototype.constructor=t}var g=t("./type.js"),m=s.bind(null,!1),v=s.bind(null,!0);e.exports={arrayOf:r,before:n,deepClone:v,shallowClone:m,shallowMerge:o,compose:a,getIn:p,inherits:b,pathObject:y,solvePath:d}},{"./type.js":10}],8:[function(t,e){function r(t,e){return e in(t||{})}function n(t,e,n){return r(t,n)&&r(e,n)}function o(){var t,e,r,a,u={},h=arguments.length;for(r=h-1;r>=0;r--){if(arguments[r].$unset)delete u.$set,delete u.$apply,delete u.$merge,u.$unset=arguments[r].$unset;else{if(arguments[r].$set){delete u.$apply,delete u.$merge,delete u.$unset,u.$set=arguments[r].$set;continue}if(arguments[r].$merge){delete u.$set,delete u.$apply,delete u.$unset,u.$merge=arguments[r].$merge;continue}if(arguments[r].$apply){delete u.$set,delete u.$merge,delete u.$unset,u.$apply=arguments[r].$apply;continue}if(arguments[r].$chain){delete u.$set,delete u.$merge,delete u.$unset,u.$apply=u.$apply?i.compose(u.$apply,arguments[r].$chain):arguments[r].$chain;continue}}for(a in arguments[r])t=u[a],e=arguments[r][a],t&&s.Object(e)?n(t,e,"$push")?t.$push=s.Array(t.$push)?t.$push.concat(e.$push):[t.$push].concat(e.$push):n(t,e,"$unshift")?t.$unshift=s.Array(e.$unshift)?e.$unshift.concat(t.$unshift):[e.$unshift].concat(t.$unshift):u[a]=o(e,t):u[a]=e}return u}var i=t("./helpers.js"),s=t("./type.js");e.exports=o},{"./helpers.js":7,"./type.js":10}],9:[function(t,e){var r=t("./combination.js"),n=t("./type.js");e.exports={baobab:function(t){return{mixins:[{getInitialState:function(){if(this.tree=t,!this.cursor&&!this.cursors)return{};if(this.cursor&&this.cursors)throw Error("baobab.mixin: you cannot have both `component.cursor` and `component.cursors`. Please make up your mind.");if(this.__type=null,this.__updateHandler=function(){this.setState(this.__getCursorData())}.bind(this),this.cursor){if(!n.MixinCursor(this.cursor))throw Error("baobab.mixin.cursor: invalid data (cursor, string, array or function).");n.Function(this.cursor)&&(this.cursor=this.cursor()),n.Cursor(this.cursor)||(this.cursor=t.select(this.cursor)),this.__getCursorData=function(){return{cursor:this.cursor.get()}}.bind(this),this.__type="single"}else if(this.cursors){if(!n.MixinCursors(this.cursors))throw Error("baobab.mixin.cursor: invalid data (object, array or function).");if(n.Function(this.cursors)&&(this.cursors=this.cursors()),n.Array(this.cursors))this.cursors=this.cursors.map(function(e){return n.Cursor(e)?e:t.select(e)}),this.__getCursorData=function(){return{cursors:this.cursors.map(function(t){return t.get()})}}.bind(this),this.__type="array";else{for(var e in this.cursors)n.Cursor(this.cursors[e])||(this.cursors[e]=t.select(this.cursors[e]));this.__getCursorData=function(){var t={};for(e in this.cursors)t[e]=this.cursors[e].get();return{cursors:t}}.bind(this),this.__type="object"}}return this.__getCursorData()},componentDidMount:function(){"single"===this.__type?(this.__combination=new r("or",[this.cursor]),this.__combination.on("update",this.__updateHandler)):"array"===this.__type?(this.__combination=new r("or",this.cursors),this.__combination.on("update",this.__updateHandler)):"object"===this.__type&&(this.__combination=new r("or",Object.keys(this.cursors).map(function(t){return this.cursors[t]},this)),this.__combination.on("update",this.__updateHandler))},componentWillUnmount:function(){this.__combination&&this.__combination.release()}}].concat(t.options.mixins)}},cursor:function(t){return{mixins:[{getInitialState:function(){return this.cursor=t,this.__updateHandler=function(){this.setState({cursor:this.cursor.get()})}.bind(this),{cursor:this.cursor.get()}},componentDidMount:function(){this.cursor.on("update",this.__updateHandler)},componentWillUnmount:function(){this.cursor.off("update",this.__updateHandler)}}].concat(t.tree.options.mixins)}}}},{"./combination.js":5,"./type.js":10}],10:[function(t,e){var r=function(t){return Array.isArray(t)?"array":"object"==typeof t&&null!==t?"object":"string"==typeof t?"string":"number"==typeof t?"number":"boolean"==typeof t?"boolean":"function"==typeof t?"function":null===t?"null":void 0===t?"undefined":t instanceof Date?"date":"invalid"};r.Array=function(t){return Array.isArray(t)},r.Object=function(t){return!Array.isArray(t)&&"object"==typeof t&&null!==t},r.String=function(t){return"string"==typeof t},r.Number=function(t){return"number"==typeof t},r.Boolean=function(t){return"boolean"==typeof t},r.Function=function(t){return"function"==typeof t},r.Primitive=function(t){return"string"==typeof t||"number"==typeof t||"boolean"==typeof t},r.Date=function(t){return t instanceof Date},r.Step=function(t){var e=r(t),n=["null","undefined","invalid","date"];return-1===n.indexOf(e)},r.Path=function(t){var e=["object","string","number","function","undefined"];if(!r.Array(t))return e.indexOf(r(t))>=0;for(var n=0;n=0||r.Cursor(t)},r.MixinCursors=function(t){var e=["array","object","function"];return e.indexOf(r(t))>=0},r.ComplexPath=function(t){for(var e=["object","function"],n=0;n=0)return!0;return!1},e.exports=r},{}],11:[function(t,e){function r(t,e){var r=new Error("baobab.update: "+e+" at path /"+t.toString());return r.path=t,r}function n(t,e,n){n=n||{shiftReferences:!1};var a={};return function u(t,e,h,c){h=h||[];var l,f,p,d,y=h.join("λ");for(p in e)if(s[p])switch(d=e[p],a[y]=!0,p){case"$push":if(!i.Array(t))throw r(h,"using command $push to a non array");i.Array(d)?t.push.apply(t,d):t.push(d);break;case"$unshift":if(!i.Array(t))throw r(h,"using command $unshift to a non array");i.Array(d)?t.unshift.apply(t,d):t.unshift(d)}else if(f=y?y+"λ"+p:p,"$unset"in(e[p]||{}))a[f]=!0,i.Array(t)?n.shiftReferences?c[h[h.length-1]]=t.slice(0,+p).concat(t.slice(+p+1)):t.splice(p,1):delete t[p];else if("$set"in(e[p]||{}))d=e[p].$set,a[f]=!0,t[p]=d;else if("$apply"in(e[p]||{})||"$chain"in(e[p]||{})){if(l=e[p].$apply||e[p].$chain,"function"!=typeof l)throw r(h.concat(p),"using command $apply with a non function");a[f]=!0,t[p]=l.call(null,t[p])}else if("$merge"in(e[p]||{})){if(d=e[p].$merge,!i.Object(t[p]))throw r(h.concat(p),"using command $merge on a non-object");a[f]=!0,t[p]=o.shallowMerge(t[p],d)}else if(n.shiftReferences&&("$push"in(e[p]||{})||"$unshift"in(e[p]||{}))){if("$push"in(e[p]||{})){if(d=e[p].$push,!i.Array(t[p]))throw r(h.concat(p),"using command $push to a non array");t[p]=t[p].concat(d)}if("$unshift"in(e[p]||{})){if(d=e[p].$unshift,!i.Array(t[p]))throw r(h.concat(p),"using command $unshift to a non array");t[p]=(d instanceof Array?d:[d]).concat(t[p])}a[f]=!0}else"undefined"==typeof t[p]&&(t[p]={}),n.shiftReferences&&(t[p]=o.shallowClone(t[p])),u(t[p],e[p],h.concat(p),t)}(t,e),Object.keys(a).map(function(t){return t.split("λ")})}var o=t("./helpers.js"),i=t("./type.js"),s={};["$set","$push","$unshift","$apply","$merge"].forEach(function(t){s[t]=!0}),e.exports=n},{"./helpers.js":7,"./type.js":10}]},{},[2])(2)}); \ No newline at end of file diff --git a/src/baobab.js b/src/baobab.js index 8db1484..237b018 100644 --- a/src/baobab.js +++ b/src/baobab.js @@ -77,7 +77,7 @@ Baobab.prototype.select = function(path) { throw Error('Baobab.select: invalid path.'); // Casting to array - path = !type.Array(path) ? [path] : path; + path = [].concat(path); // Complex path? var complex = type.ComplexPath(path); From 1457b9f73b3fe19aa484b34d36323eeb405d8d5a Mon Sep 17 00:00:00 2001 From: Yomguithereal Date: Mon, 30 Mar 2015 20:17:25 +0200 Subject: [PATCH 12/73] Refactoring merge --- build/baobab.min.js | 2 +- src/merge.js | 135 ++++++++++++++++---------------------------- 2 files changed, 50 insertions(+), 87 deletions(-) diff --git a/build/baobab.min.js b/build/baobab.min.js index ba82c43..5aab7f3 100644 --- a/build/baobab.min.js +++ b/build/baobab.min.js @@ -1,2 +1,2 @@ /* baobab.js - Version: 0.4.3 - Author: Yomguithereal (Guillaume Plique) */ -!function(t){if("object"==typeof exports&&"undefined"!=typeof module)module.exports=t();else if("function"==typeof define&&define.amd)define([],t);else{var e;e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:this,e.Baobab=t()}}(function(){var t;return function e(t,r,n){function o(s,a){if(!r[s]){if(!t[s]){var u="function"==typeof require&&require;if(!a&&u)return u(s,!0);if(i)return i(s,!0);var h=new Error("Cannot find module '"+s+"'");throw h.code="MODULE_NOT_FOUND",h}var c=r[s]={exports:{}};t[s][0].call(c.exports,function(e){var r=t[s][1][e];return o(r?r:e)},c,c.exports,e,t,r,n)}return r[s].exports}for(var i="function"==typeof require&&require,s=0;se;e++)n.push(t[e].handler);return n}var o={once:"boolean",scope:"object"},i=function(){this._enabled=!0,this._children=[],this._handlers={},this._handlersAll=[]};i.prototype.on=function(t,e,r){var n,s,a,u,h,c;if("function"==typeof e){for(h="string"==typeof t?[t]:t,n=0,s=h.length;n!==s;n+=1)if(u=h[n]){this._handlers[u]||(this._handlers[u]=[]),c={handler:e};for(a in r||{}){if(!o[a])throw new Error('The option "'+a+'" is not recognized by Emmett.');c[a]=r[a]}this._handlers[u].push(c)}}else if(t&&"object"==typeof t&&!Array.isArray(t))for(u in t)i.prototype.on.call(this,u,t[u],e);else{if("function"!=typeof t)throw new Error("Wrong arguments.");c={handler:t};for(a in r||{}){if(!o[a])throw new Error('The option "'+a+'" is not recognized by Emmett.');c[a]=r[a]}this._handlersAll.push(c)}return this},i.prototype.once=function(t,e,r){if("function"==typeof e)r=r||{},r.once=!0,this.on(t,e,r);else{if((!t||"object"!=typeof t||Array.isArray(t))&&"function"!=typeof t)throw new Error("Wrong arguments.");e=e||{},e.once=!0,this.on(t,e)}return this},i.prototype.off=function(t,e){var r,n,o,i,s,a,u,h="string"==typeof t?[t]:t;if(1===arguments.length&&"function"==typeof h){e=arguments[0];for(s in this._handlers){for(a=[],r=0,n=this._handlers[s].length;r!==n;r+=1)this._handlers[s][r].handler!==e&&a.push(this._handlers[s][r]);this._handlers[s]=a}for(a=[],r=0,n=this._handlersAll.length;r!==n;r+=1)this._handlersAll[r].handler!==e&&a.push(this._handlersAll[r]);this._handlersAll=a}else if(2===arguments.length)for(r=0,n=h.length;r!==n;r+=1){if(u=h[r],this._handlers[u]){for(a=[],o=0,i=this._handlers[u].length;o!==i;o+=1)this._handlers[u][o].handler!==e&&a.push(this._handlers[u][o]);this._handlers[u]=a}this._handlers[u]&&0===this._handlers[u].length&&delete this._handlers[u]}return this},i.prototype.unbindAll=function(){var t;this._handlersAll=[];for(t in this._handlers)delete this._handlers[t];return this},i.prototype.emit=function(t,e){var r,n,o,i,s,a,u,h,c,l,f="string"==typeof t?[t]:t;if(!this._enabled)return this;for(e=void 0===e?{}:e,r=0,n=f.length;r!==n;r+=1)if(l=f[r],c=(this._handlers[l]||[]).concat(this._handlersAll),c.length){for(u={type:l,data:e||{},target:this},a=[],o=0,i=c.length;o!==i;o+=1)(this._handlers[l]&&this._handlers[l].indexOf(c[o])>=0||this._handlersAll.indexOf(c[o])>=0)&&(c[o].handler.call("scope"in c[o]?c[o].scope:this,u),c[o].once&&a.push(c[o]));for(s=0;sr;r++)if(t._children[r]===e){t._children.splice(r,1);break}}),this._children.push(e),e},i.prototype.listeners=function(t){var r,n,o,i=[];if(t)for(i=e(this._handlers[t]),n=0,o=this._children.length;o>n;n++)i=i.concat(this._children[n].listeners(t));else{i=e(this._handlersAll);for(r in this._handlers)i=i.concat(e(this._handlers[r]));for(n=0,o=this._children.length;o>n;n++)i=i.concat(this._children[n].listeners())}return i},i.prototype.kill=function(){if(this.emit("emmett:kill"),this.unbindAll(),this._handlers=null,this._handlersAll=null,this._enabled=!1,this._children)for(var t=0,e=this._children.length;e>t;t++)this._children[t].kill();this._children=null},i.prototype.disable=function(){return this._enabled=!1,this},i.prototype.enable=function(){return this._enabled=!0,this},i.version="2.1.2","undefined"!=typeof n?("undefined"!=typeof r&&r.exports&&(n=r.exports=i),n.Emitter=i):"function"==typeof t&&t.amd?t("emmett",[],function(){return i}):this.Emitter=i}).call(this)},{}],4:[function(t,e){function r(t){return t+"$"+(new Date).getTime()+(""+Math.random()).replace("0.","")}function n(t,e){function r(t){this[t]=function(){var e=this.root[t].apply(this.root,arguments);return e instanceof o?this:e}}if(arguments.length<1&&(t={}),!(this instanceof n))return new n(t,e);if(!l.Object(t)&&!l.Array(t))throw Error("Baobab: invalid data.");i.call(this),this.options=s.shallowMerge(c,e),this._transaction={},this._future=void 0,this._cursors={},this.data=s.deepClone(t),this.root=this.select([]),["get","set","unset","update"].forEach(r.bind(this)),this.mixin=h.baobab(this)}var o=t("./cursor.js"),i=t("emmett"),s=t("./helpers.js"),a=t("./update.js"),u=t("./merge.js"),h=t("./mixins.js"),c=t("../defaults.js"),l=t("./type.js");s.inherits(n,i),n.prototype.select=function(t){if(!t)throw Error("Baobab.select: invalid path.");if(arguments.length>1&&(t=s.arrayOf(arguments)),!l.Path(t))throw Error("Baobab.select: invalid path.");t=[].concat(t);var e,n=l.ComplexPath(t);n&&(e=s.solvePath(this.data,t));var i=t.map(function(t){return l.Function(t)?r("fn"):l.Object(t)?r("ob"):t}).join("λ");if(this._cursors[i])return this._cursors[i];var a=new o(this,t,e,i);return this._cursors[i]=a,a},n.prototype.stack=function(t){var e=this;if(!l.Object(t))throw Error("Baobab.update: wrong specification.");return this._transaction=u(t,this._transaction),this.options.autoCommit?this.options.asynchronous?(this._future||(this._future=setTimeout(e.commit.bind(e,null),0)),this):this.commit():this},n.prototype.commit=function(){this.options.shiftReferences&&(this.data=s.shallowClone(this.data));var t=a(this.data,this._transaction,this.options);return this._transaction={},this._future&&(this._future=clearTimeout(this._future)),this.emit("update",{log:t}),this},n.prototype.release=function(){delete this.data,delete this._transaction;for(var t in this._cursors)this._cursors[t].release();delete this._cursors,this.kill()},n.prototype.toJSON=function(){return this.get()},e.exports=n},{"../defaults.js":1,"./cursor.js":6,"./helpers.js":7,"./merge.js":8,"./mixins.js":9,"./type.js":10,"./update.js":11,emmett:3}],5:[function(t,e){function r(t,e){e.on("update",t.cursorListener),t.tree.off("update",t.treeListener),t.tree.on("update",t.treeListener)}function n(t){var e=this;if(arguments.length<2)throw Error("baobab.Combination: not enough arguments.");var n=arguments[1],o=s.arrayOf(arguments).slice(2);if(n instanceof Array&&(o=n.slice(1),n=n[0]),!a.Cursor(n))throw Error("baobab.Combination: argument should be a cursor.");if("or"!==t&&"and"!==t)throw Error("baobab.Combination: invalid operator.");i.call(this),this.cursors=[n],this.operators=[],this.tree=n.tree,this.updates=new Array(this.cursors.length),this.cursorListener=function(){e.updates[e.cursors.indexOf(this)]=!0},this.treeListener=function(){var t,r,n=e.updates[0];for(t=1,r=e.cursors.length;r>t;t++)n="or"===e.operators[t-1]?n||e.updates[t]:n&&e.updates[t];n&&e.emit("update"),e.updates=new Array(e.cursors.length)},this.bound=!1;var u=(this.on,this.once,function(){e.bound||(e.bound=!0,e.cursors.forEach(function(t){r(e,t)}))});this.on=s.before(u,this.on.bind(this)),this.once=s.before(u,this.once.bind(this)),o.forEach(function(e){this[t](e)},this)}function o(t){n.prototype[t]=function(e){if(!a.Cursor(e))throw this.release(),Error("baobab.Combination."+t+": argument should be a cursor.");if(~this.cursors.indexOf(e))throw this.release(),Error("baobab.Combination."+t+": cursor already in combination.");return this.cursors.push(e),this.operators.push(t),this.updates.length++,this.bound&&r(this,e),this}}var i=t("emmett"),s=t("./helpers.js"),a=t("./type.js");s.inherits(n,i),o("or"),o("and"),n.prototype.release=function(){this.cursors.forEach(function(t){t.off("update",this.cursorListener)},this),this.tree.off("update",this.treeListener),this.cursors=null,this.operators=null,this.tree=null,this.updates=null,this.kill()},e.exports=n},{"./helpers.js":7,"./type.js":10,emmett:3}],6:[function(t,e){function r(t,e,r,o){var a=this;n.call(this),e=e||[],this.tree=t,this.path=e,this.hash=o,this.complexPath=!!r,this.solvedPath=this.complexPath?r:this.path,this.relevant=void 0!==this.get(),this.updateHandler=function(t){var e,r,n,o,i,u,h=t.data.log,c=!1;if(a.complexPath&&(a.solvedPath=s.solvePath(a.tree.data,a.path)),!a.path.length)return a.emit("update");t:for(i=0,n=h.length;n>i;i++)for(e=h[i],u=0,o=e.length;o>u&&(r=e[u],r===""+a.solvedPath[u]);u++)if(u+1===o||u+1===a.solvedPath.length){c=!0;break t}var l=void 0!==a.get();a.relevant?l&&c?a.emit("update"):l||(a.emit("irrelevant"),a.relevant=!1):l&&c&&(a.emit("relevant"),a.emit("update"),a.relevant=!0)},this.mixin=i.cursor(this);var u=!1,h=function(){u||(u=!0,a.tree.on("update",a.updateHandler))};this.on=s.before(h,this.on.bind(this)),this.once=s.before(h,this.once.bind(this))}var n=t("emmett"),o=t("./combination.js"),i=t("./mixins.js"),s=t("./helpers.js"),a=t("./type.js");s.inherits(r,n),r.prototype.isRoot=function(){return!this.path.length},r.prototype.isLeaf=function(){return a.Primitive(this.get())},r.prototype.isBranch=function(){return!this.isLeaf()&&!this.isRoot()},r.prototype.root=function(){return this.tree.root()},r.prototype.select=function(t){if(arguments.length>1&&(t=s.arrayOf(arguments)),!a.Path(t))throw Error("baobab.Cursor.select: invalid path.");return this.tree.select(this.path.concat(t))},r.prototype.up=function(){return this.solvedPath&&this.solvedPath.length?this.tree.select(this.path.slice(0,-1)):null},r.prototype.left=function(){var t=+this.solvedPath[this.solvedPath.length-1];if(isNaN(t))throw Error("baobab.Cursor.left: cannot go left on a non-list type.");return t?this.tree.select(this.solvedPath.slice(0,-1).concat(t-1)):null},r.prototype.leftmost=function(){var t=+this.solvedPath[this.solvedPath.length-1];if(isNaN(t))throw Error("baobab.Cursor.leftmost: cannot go left on a non-list type.");return this.tree.select(this.solvedPath.slice(0,-1).concat(0))},r.prototype.right=function(){var t=+this.solvedPath[this.solvedPath.length-1];if(isNaN(t))throw Error("baobab.Cursor.right: cannot go right on a non-list type.");return t+1===this.up().get().length?null:this.tree.select(this.solvedPath.slice(0,-1).concat(t+1))},r.prototype.rightmost=function(){var t=+this.solvedPath[this.solvedPath.length-1];if(isNaN(t))throw Error("baobab.Cursor.right: cannot go right on a non-list type.");var e=this.up().get();return this.tree.select(this.solvedPath.slice(0,-1).concat(e.length-1))},r.prototype.down=function(){+this.solvedPath[this.solvedPath.length-1];return this.get()instanceof Array?this.tree.select(this.solvedPath.concat(0)):null},r.prototype.get=function(t){arguments.length>1&&(t=s.arrayOf(arguments));var e=this.solvedPath.concat((a.String(t)||a.Number(t)?[t]:t)||[]);return s.getIn(this.tree.data,e)},r.prototype.set=function(t,e){if(arguments.length<2)throw Error("baobab.Cursor.set: expecting at least key/value.");var r=this.get();if("object"!=typeof r)throw Error("baobab.Cursor.set: trying to set key to a non-object.");var n={};if(a.Array(t)){var o=s.solvePath(r,t);if(!o)throw Error("baobab.Cursor.set: could not solve dynamic path.");n=s.pathObject(o,{$set:e})}else n[t]={$set:e};return this.update(n)},r.prototype.edit=function(t){return this.update({$set:t})},r.prototype.unset=function(t){if(!t&&0!==t)throw Error("baobab.Cursor.unset: expects a valid key to unset.");if("object"!=typeof this.get())throw Error("baobab.Cursor.set: trying to set key to a non-object.");var e={};return e[t]={$unset:!0},this.update(e)},r.prototype.remove=function(){if(this.isRoot())throw Error("baobab.Cursor.remove: cannot remove root node.");return this.update({$unset:!0})},r.prototype.apply=function(t){if("function"!=typeof t)throw Error("baobab.Cursor.apply: argument is not a function.");return this.update({$apply:t})},r.prototype.chain=function(t){if("function"!=typeof t)throw Error("baobab.Cursor.chain: argument is not a function.");return this.update({$chain:t})},r.prototype.push=function(t){if(!(this.get()instanceof Array))throw Error("baobab.Cursor.push: trying to push to non-array value.");return this.update(arguments.length>1?{$push:s.arrayOf(arguments)}:{$push:t})},r.prototype.unshift=function(t){if(!(this.get()instanceof Array))throw Error("baobab.Cursor.push: trying to push to non-array value.");return this.update(arguments.length>1?{$unshift:s.arrayOf(arguments)}:{$unshift:t})},r.prototype.merge=function(t){if(!a.Object(t))throw Error("baobab.Cursor.merge: trying to merge a non-object.");if(!a.Object(this.get()))throw Error("baobab.Cursor.merge: trying to merge into a non-object.");this.update({$merge:t})},r.prototype.update=function(t){return this.tree.stack(s.pathObject(this.solvedPath,t)),this},r.prototype.or=function(t){return new o("or",this,t)},r.prototype.and=function(t){return new o("and",this,t)},r.prototype.release=function(){this.tree.off("update",this.updateHandler),this.hash&&delete this.tree._cursors[this.hash],delete this.tree,delete this.path,delete this.solvedPath,this.kill()},r.prototype.toJSON=function(){return this.get()},a.Cursor=function(t){return t instanceof r},e.exports=r},{"./combination.js":5,"./helpers.js":7,"./mixins.js":9,"./type.js":10,emmett:3}],7:[function(t,e){function r(t){return Array.prototype.slice.call(t)}function n(t,e){return function(){t(),e.apply(null,arguments)}}function o(t,e){var r,n={};for(r in t)n[r]=t[r];for(r in e)n[r]=e[r];return n}function i(t){var e=t.source,r="";return t.global&&(r+="g"),t.multiline&&(r+="m"),t.ignoreCase&&(r+="i"),t.sticky&&(r+="y"),t.unicode&&(r+="u"),new RegExp(e,r)}function s(t,e){if(!e||"object"!=typeof e||e instanceof Error||e instanceof ArrayBuffer)return e;if(g.Array(e)){if(t){var r,n,o=[];for(r=0,n=e.length;n>r;r++)o.push(v(e[r]));return o}return e.slice(0)}if(g.Date(e))return new Date(e.getTime());if(e instanceof RegExp)return i(e);if(g.Object(e)){var s,a={};e.constructor&&e.constructor!==Object&&(a=Object.create(e.constructor.prototype));for(s in e)e.hasOwnProperty(s)&&(a[s]=t?v(e[s]):e[s]);return a}return e}function a(t,e){return function(r){return e(t(r))}}function u(t,e){var r,n;for(r=0,n=t.length;n>r;r++)if(e(t[r]))return t[r]}function h(t,e){var r,n;for(r=0,n=t.length;n>r;r++)if(e(t[r]))return r;return-1}function c(t,e){var r,n=!0;if(!t)return!1;for(r in e)if(g.Object(e[r]))n=n&&c(t[r],e[r]);else if(g.Array(e[r]))n=n&&!!~e[r].indexOf(t[r]);else if(t[r]!==e[r])return!1;return n}function l(t,e){return u(t,function(t){return c(t,e)})}function f(t,e){return h(t,function(t){return c(t,e)})}function p(t,e){e=e||[];var r,n,o=t;for(r=0,n=e.length;n>r;r++){if(!o)return;if("function"==typeof e[r]){if(!g.Array(o))return;o=u(o,e[r])}else if("object"==typeof e[r]){if(!g.Array(o))return;o=l(o,e[r])}else o=o[e[r]]}return o}function d(t,e){var r,n,o,i=[],s=t;for(n=0,o=e.length;o>n;n++){if(!s)return null;if("function"==typeof e[n]){if(!g.Array(s))return;r=h(s,e[n]),i.push(r),s=s[r]}else if("object"==typeof e[n]){if(!g.Array(s))return;r=f(s,e[n]),i.push(r),s=s[r]}else i.push(e[n]),s=s[e[n]]||{}}return i}function y(t,e){var r,n=t.length,o={},i=o;for(n||(o=e),r=0;n>r;r++)i[t[r]]=r+1===n?e:{},i=i[t[r]];return o}function b(t,e){t.super_=e;var r=function(){};r.prototype=e.prototype,t.prototype=new r,t.prototype.constructor=t}var g=t("./type.js"),m=s.bind(null,!1),v=s.bind(null,!0);e.exports={arrayOf:r,before:n,deepClone:v,shallowClone:m,shallowMerge:o,compose:a,getIn:p,inherits:b,pathObject:y,solvePath:d}},{"./type.js":10}],8:[function(t,e){function r(t,e){return e in(t||{})}function n(t,e,n){return r(t,n)&&r(e,n)}function o(){var t,e,r,a,u={},h=arguments.length;for(r=h-1;r>=0;r--){if(arguments[r].$unset)delete u.$set,delete u.$apply,delete u.$merge,u.$unset=arguments[r].$unset;else{if(arguments[r].$set){delete u.$apply,delete u.$merge,delete u.$unset,u.$set=arguments[r].$set;continue}if(arguments[r].$merge){delete u.$set,delete u.$apply,delete u.$unset,u.$merge=arguments[r].$merge;continue}if(arguments[r].$apply){delete u.$set,delete u.$merge,delete u.$unset,u.$apply=arguments[r].$apply;continue}if(arguments[r].$chain){delete u.$set,delete u.$merge,delete u.$unset,u.$apply=u.$apply?i.compose(u.$apply,arguments[r].$chain):arguments[r].$chain;continue}}for(a in arguments[r])t=u[a],e=arguments[r][a],t&&s.Object(e)?n(t,e,"$push")?t.$push=s.Array(t.$push)?t.$push.concat(e.$push):[t.$push].concat(e.$push):n(t,e,"$unshift")?t.$unshift=s.Array(e.$unshift)?e.$unshift.concat(t.$unshift):[e.$unshift].concat(t.$unshift):u[a]=o(e,t):u[a]=e}return u}var i=t("./helpers.js"),s=t("./type.js");e.exports=o},{"./helpers.js":7,"./type.js":10}],9:[function(t,e){var r=t("./combination.js"),n=t("./type.js");e.exports={baobab:function(t){return{mixins:[{getInitialState:function(){if(this.tree=t,!this.cursor&&!this.cursors)return{};if(this.cursor&&this.cursors)throw Error("baobab.mixin: you cannot have both `component.cursor` and `component.cursors`. Please make up your mind.");if(this.__type=null,this.__updateHandler=function(){this.setState(this.__getCursorData())}.bind(this),this.cursor){if(!n.MixinCursor(this.cursor))throw Error("baobab.mixin.cursor: invalid data (cursor, string, array or function).");n.Function(this.cursor)&&(this.cursor=this.cursor()),n.Cursor(this.cursor)||(this.cursor=t.select(this.cursor)),this.__getCursorData=function(){return{cursor:this.cursor.get()}}.bind(this),this.__type="single"}else if(this.cursors){if(!n.MixinCursors(this.cursors))throw Error("baobab.mixin.cursor: invalid data (object, array or function).");if(n.Function(this.cursors)&&(this.cursors=this.cursors()),n.Array(this.cursors))this.cursors=this.cursors.map(function(e){return n.Cursor(e)?e:t.select(e)}),this.__getCursorData=function(){return{cursors:this.cursors.map(function(t){return t.get()})}}.bind(this),this.__type="array";else{for(var e in this.cursors)n.Cursor(this.cursors[e])||(this.cursors[e]=t.select(this.cursors[e]));this.__getCursorData=function(){var t={};for(e in this.cursors)t[e]=this.cursors[e].get();return{cursors:t}}.bind(this),this.__type="object"}}return this.__getCursorData()},componentDidMount:function(){"single"===this.__type?(this.__combination=new r("or",[this.cursor]),this.__combination.on("update",this.__updateHandler)):"array"===this.__type?(this.__combination=new r("or",this.cursors),this.__combination.on("update",this.__updateHandler)):"object"===this.__type&&(this.__combination=new r("or",Object.keys(this.cursors).map(function(t){return this.cursors[t]},this)),this.__combination.on("update",this.__updateHandler))},componentWillUnmount:function(){this.__combination&&this.__combination.release()}}].concat(t.options.mixins)}},cursor:function(t){return{mixins:[{getInitialState:function(){return this.cursor=t,this.__updateHandler=function(){this.setState({cursor:this.cursor.get()})}.bind(this),{cursor:this.cursor.get()}},componentDidMount:function(){this.cursor.on("update",this.__updateHandler)},componentWillUnmount:function(){this.cursor.off("update",this.__updateHandler)}}].concat(t.tree.options.mixins)}}}},{"./combination.js":5,"./type.js":10}],10:[function(t,e){var r=function(t){return Array.isArray(t)?"array":"object"==typeof t&&null!==t?"object":"string"==typeof t?"string":"number"==typeof t?"number":"boolean"==typeof t?"boolean":"function"==typeof t?"function":null===t?"null":void 0===t?"undefined":t instanceof Date?"date":"invalid"};r.Array=function(t){return Array.isArray(t)},r.Object=function(t){return!Array.isArray(t)&&"object"==typeof t&&null!==t},r.String=function(t){return"string"==typeof t},r.Number=function(t){return"number"==typeof t},r.Boolean=function(t){return"boolean"==typeof t},r.Function=function(t){return"function"==typeof t},r.Primitive=function(t){return"string"==typeof t||"number"==typeof t||"boolean"==typeof t},r.Date=function(t){return t instanceof Date},r.Step=function(t){var e=r(t),n=["null","undefined","invalid","date"];return-1===n.indexOf(e)},r.Path=function(t){var e=["object","string","number","function","undefined"];if(!r.Array(t))return e.indexOf(r(t))>=0;for(var n=0;n=0||r.Cursor(t)},r.MixinCursors=function(t){var e=["array","object","function"];return e.indexOf(r(t))>=0},r.ComplexPath=function(t){for(var e=["object","function"],n=0;n=0)return!0;return!1},e.exports=r},{}],11:[function(t,e){function r(t,e){var r=new Error("baobab.update: "+e+" at path /"+t.toString());return r.path=t,r}function n(t,e,n){n=n||{shiftReferences:!1};var a={};return function u(t,e,h,c){h=h||[];var l,f,p,d,y=h.join("λ");for(p in e)if(s[p])switch(d=e[p],a[y]=!0,p){case"$push":if(!i.Array(t))throw r(h,"using command $push to a non array");i.Array(d)?t.push.apply(t,d):t.push(d);break;case"$unshift":if(!i.Array(t))throw r(h,"using command $unshift to a non array");i.Array(d)?t.unshift.apply(t,d):t.unshift(d)}else if(f=y?y+"λ"+p:p,"$unset"in(e[p]||{}))a[f]=!0,i.Array(t)?n.shiftReferences?c[h[h.length-1]]=t.slice(0,+p).concat(t.slice(+p+1)):t.splice(p,1):delete t[p];else if("$set"in(e[p]||{}))d=e[p].$set,a[f]=!0,t[p]=d;else if("$apply"in(e[p]||{})||"$chain"in(e[p]||{})){if(l=e[p].$apply||e[p].$chain,"function"!=typeof l)throw r(h.concat(p),"using command $apply with a non function");a[f]=!0,t[p]=l.call(null,t[p])}else if("$merge"in(e[p]||{})){if(d=e[p].$merge,!i.Object(t[p]))throw r(h.concat(p),"using command $merge on a non-object");a[f]=!0,t[p]=o.shallowMerge(t[p],d)}else if(n.shiftReferences&&("$push"in(e[p]||{})||"$unshift"in(e[p]||{}))){if("$push"in(e[p]||{})){if(d=e[p].$push,!i.Array(t[p]))throw r(h.concat(p),"using command $push to a non array");t[p]=t[p].concat(d)}if("$unshift"in(e[p]||{})){if(d=e[p].$unshift,!i.Array(t[p]))throw r(h.concat(p),"using command $unshift to a non array");t[p]=(d instanceof Array?d:[d]).concat(t[p])}a[f]=!0}else"undefined"==typeof t[p]&&(t[p]={}),n.shiftReferences&&(t[p]=o.shallowClone(t[p])),u(t[p],e[p],h.concat(p),t)}(t,e),Object.keys(a).map(function(t){return t.split("λ")})}var o=t("./helpers.js"),i=t("./type.js"),s={};["$set","$push","$unshift","$apply","$merge"].forEach(function(t){s[t]=!0}),e.exports=n},{"./helpers.js":7,"./type.js":10}]},{},[2])(2)}); \ No newline at end of file +!function(t){if("object"==typeof exports&&"undefined"!=typeof module)module.exports=t();else if("function"==typeof define&&define.amd)define([],t);else{var r;r="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:this,r.Baobab=t()}}(function(){var t;return function r(t,e,n){function o(s,a){if(!e[s]){if(!t[s]){var h="function"==typeof require&&require;if(!a&&h)return h(s,!0);if(i)return i(s,!0);var u=new Error("Cannot find module '"+s+"'");throw u.code="MODULE_NOT_FOUND",u}var c=e[s]={exports:{}};t[s][0].call(c.exports,function(r){var e=t[s][1][r];return o(e?e:r)},c,c.exports,r,t,e,n)}return e[s].exports}for(var i="function"==typeof require&&require,s=0;sr;r++)n.push(t[r].handler);return n}var o={once:"boolean",scope:"object"},i=function(){this._enabled=!0,this._children=[],this._handlers={},this._handlersAll=[]};i.prototype.on=function(t,r,e){var n,s,a,h,u,c;if("function"==typeof r){for(u="string"==typeof t?[t]:t,n=0,s=u.length;n!==s;n+=1)if(h=u[n]){this._handlers[h]||(this._handlers[h]=[]),c={handler:r};for(a in e||{}){if(!o[a])throw new Error('The option "'+a+'" is not recognized by Emmett.');c[a]=e[a]}this._handlers[h].push(c)}}else if(t&&"object"==typeof t&&!Array.isArray(t))for(h in t)i.prototype.on.call(this,h,t[h],r);else{if("function"!=typeof t)throw new Error("Wrong arguments.");c={handler:t};for(a in e||{}){if(!o[a])throw new Error('The option "'+a+'" is not recognized by Emmett.');c[a]=e[a]}this._handlersAll.push(c)}return this},i.prototype.once=function(t,r,e){if("function"==typeof r)e=e||{},e.once=!0,this.on(t,r,e);else{if((!t||"object"!=typeof t||Array.isArray(t))&&"function"!=typeof t)throw new Error("Wrong arguments.");r=r||{},r.once=!0,this.on(t,r)}return this},i.prototype.off=function(t,r){var e,n,o,i,s,a,h,u="string"==typeof t?[t]:t;if(1===arguments.length&&"function"==typeof u){r=arguments[0];for(s in this._handlers){for(a=[],e=0,n=this._handlers[s].length;e!==n;e+=1)this._handlers[s][e].handler!==r&&a.push(this._handlers[s][e]);this._handlers[s]=a}for(a=[],e=0,n=this._handlersAll.length;e!==n;e+=1)this._handlersAll[e].handler!==r&&a.push(this._handlersAll[e]);this._handlersAll=a}else if(2===arguments.length)for(e=0,n=u.length;e!==n;e+=1){if(h=u[e],this._handlers[h]){for(a=[],o=0,i=this._handlers[h].length;o!==i;o+=1)this._handlers[h][o].handler!==r&&a.push(this._handlers[h][o]);this._handlers[h]=a}this._handlers[h]&&0===this._handlers[h].length&&delete this._handlers[h]}return this},i.prototype.unbindAll=function(){var t;this._handlersAll=[];for(t in this._handlers)delete this._handlers[t];return this},i.prototype.emit=function(t,r){var e,n,o,i,s,a,h,u,c,f,l="string"==typeof t?[t]:t;if(!this._enabled)return this;for(r=void 0===r?{}:r,e=0,n=l.length;e!==n;e+=1)if(f=l[e],c=(this._handlers[f]||[]).concat(this._handlersAll),c.length){for(h={type:f,data:r||{},target:this},a=[],o=0,i=c.length;o!==i;o+=1)(this._handlers[f]&&this._handlers[f].indexOf(c[o])>=0||this._handlersAll.indexOf(c[o])>=0)&&(c[o].handler.call("scope"in c[o]?c[o].scope:this,h),c[o].once&&a.push(c[o]));for(s=0;se;e++)if(t._children[e]===r){t._children.splice(e,1);break}}),this._children.push(r),r},i.prototype.listeners=function(t){var e,n,o,i=[];if(t)for(i=r(this._handlers[t]),n=0,o=this._children.length;o>n;n++)i=i.concat(this._children[n].listeners(t));else{i=r(this._handlersAll);for(e in this._handlers)i=i.concat(r(this._handlers[e]));for(n=0,o=this._children.length;o>n;n++)i=i.concat(this._children[n].listeners())}return i},i.prototype.kill=function(){if(this.emit("emmett:kill"),this.unbindAll(),this._handlers=null,this._handlersAll=null,this._enabled=!1,this._children)for(var t=0,r=this._children.length;r>t;t++)this._children[t].kill();this._children=null},i.prototype.disable=function(){return this._enabled=!1,this},i.prototype.enable=function(){return this._enabled=!0,this},i.version="2.1.2","undefined"!=typeof n?("undefined"!=typeof e&&e.exports&&(n=e.exports=i),n.Emitter=i):"function"==typeof t&&t.amd?t("emmett",[],function(){return i}):this.Emitter=i}).call(this)},{}],4:[function(t,r){function e(t){return t+"$"+(new Date).getTime()+(""+Math.random()).replace("0.","")}function n(t,r){function e(t){this[t]=function(){var r=this.root[t].apply(this.root,arguments);return r instanceof o?this:r}}if(arguments.length<1&&(t={}),!(this instanceof n))return new n(t,r);if(!f.Object(t)&&!f.Array(t))throw Error("Baobab: invalid data.");i.call(this),this.options=s.shallowMerge(c,r),this._transaction={},this._future=void 0,this._cursors={},this.data=s.deepClone(t),this.root=this.select([]),["get","set","unset","update"].forEach(e.bind(this)),this.mixin=u.baobab(this)}var o=t("./cursor.js"),i=t("emmett"),s=t("./helpers.js"),a=t("./update.js"),h=t("./merge.js"),u=t("./mixins.js"),c=t("../defaults.js"),f=t("./type.js");s.inherits(n,i),n.prototype.select=function(t){if(!t)throw Error("Baobab.select: invalid path.");if(arguments.length>1&&(t=s.arrayOf(arguments)),!f.Path(t))throw Error("Baobab.select: invalid path.");t=[].concat(t);var r,n=f.ComplexPath(t);n&&(r=s.solvePath(this.data,t));var i=t.map(function(t){return f.Function(t)?e("fn"):f.Object(t)?e("ob"):t}).join("λ");if(this._cursors[i])return this._cursors[i];var a=new o(this,t,r,i);return this._cursors[i]=a,a},n.prototype.stack=function(t){var r=this;if(!f.Object(t))throw Error("Baobab.update: wrong specification.");return this._transaction=h(t,this._transaction),this.options.autoCommit?this.options.asynchronous?(this._future||(this._future=setTimeout(r.commit.bind(r,null),0)),this):this.commit():this},n.prototype.commit=function(){this.options.shiftReferences&&(this.data=s.shallowClone(this.data));var t=a(this.data,this._transaction,this.options);return this._transaction={},this._future&&(this._future=clearTimeout(this._future)),this.emit("update",{log:t}),this},n.prototype.release=function(){delete this.data,delete this._transaction;for(var t in this._cursors)this._cursors[t].release();delete this._cursors,this.kill()},n.prototype.toJSON=function(){return this.get()},r.exports=n},{"../defaults.js":1,"./cursor.js":6,"./helpers.js":7,"./merge.js":8,"./mixins.js":9,"./type.js":10,"./update.js":11,emmett:3}],5:[function(t,r){function e(t,r){r.on("update",t.cursorListener),t.tree.off("update",t.treeListener),t.tree.on("update",t.treeListener)}function n(t){var r=this;if(arguments.length<2)throw Error("baobab.Combination: not enough arguments.");var n=arguments[1],o=s.arrayOf(arguments).slice(2);if(n instanceof Array&&(o=n.slice(1),n=n[0]),!a.Cursor(n))throw Error("baobab.Combination: argument should be a cursor.");if("or"!==t&&"and"!==t)throw Error("baobab.Combination: invalid operator.");i.call(this),this.cursors=[n],this.operators=[],this.tree=n.tree,this.updates=new Array(this.cursors.length),this.cursorListener=function(){r.updates[r.cursors.indexOf(this)]=!0},this.treeListener=function(){var t,e,n=r.updates[0];for(t=1,e=r.cursors.length;e>t;t++)n="or"===r.operators[t-1]?n||r.updates[t]:n&&r.updates[t];n&&r.emit("update"),r.updates=new Array(r.cursors.length)},this.bound=!1;var h=(this.on,this.once,function(){r.bound||(r.bound=!0,r.cursors.forEach(function(t){e(r,t)}))});this.on=s.before(h,this.on.bind(this)),this.once=s.before(h,this.once.bind(this)),o.forEach(function(r){this[t](r)},this)}function o(t){n.prototype[t]=function(r){if(!a.Cursor(r))throw this.release(),Error("baobab.Combination."+t+": argument should be a cursor.");if(~this.cursors.indexOf(r))throw this.release(),Error("baobab.Combination."+t+": cursor already in combination.");return this.cursors.push(r),this.operators.push(t),this.updates.length++,this.bound&&e(this,r),this}}var i=t("emmett"),s=t("./helpers.js"),a=t("./type.js");s.inherits(n,i),o("or"),o("and"),n.prototype.release=function(){this.cursors.forEach(function(t){t.off("update",this.cursorListener)},this),this.tree.off("update",this.treeListener),this.cursors=null,this.operators=null,this.tree=null,this.updates=null,this.kill()},r.exports=n},{"./helpers.js":7,"./type.js":10,emmett:3}],6:[function(t,r){function e(t,r,e,o){var a=this;n.call(this),r=r||[],this.tree=t,this.path=r,this.hash=o,this.complexPath=!!e,this.solvedPath=this.complexPath?e:this.path,this.relevant=void 0!==this.get(),this.updateHandler=function(t){var r,e,n,o,i,h,u=t.data.log,c=!1;if(a.complexPath&&(a.solvedPath=s.solvePath(a.tree.data,a.path)),!a.path.length)return a.emit("update");t:for(i=0,n=u.length;n>i;i++)for(r=u[i],h=0,o=r.length;o>h&&(e=r[h],e===""+a.solvedPath[h]);h++)if(h+1===o||h+1===a.solvedPath.length){c=!0;break t}var f=void 0!==a.get();a.relevant?f&&c?a.emit("update"):f||(a.emit("irrelevant"),a.relevant=!1):f&&c&&(a.emit("relevant"),a.emit("update"),a.relevant=!0)},this.mixin=i.cursor(this);var h=!1,u=function(){h||(h=!0,a.tree.on("update",a.updateHandler))};this.on=s.before(u,this.on.bind(this)),this.once=s.before(u,this.once.bind(this))}var n=t("emmett"),o=t("./combination.js"),i=t("./mixins.js"),s=t("./helpers.js"),a=t("./type.js");s.inherits(e,n),e.prototype.isRoot=function(){return!this.path.length},e.prototype.isLeaf=function(){return a.Primitive(this.get())},e.prototype.isBranch=function(){return!this.isLeaf()&&!this.isRoot()},e.prototype.root=function(){return this.tree.root()},e.prototype.select=function(t){if(arguments.length>1&&(t=s.arrayOf(arguments)),!a.Path(t))throw Error("baobab.Cursor.select: invalid path.");return this.tree.select(this.path.concat(t))},e.prototype.up=function(){return this.solvedPath&&this.solvedPath.length?this.tree.select(this.path.slice(0,-1)):null},e.prototype.left=function(){var t=+this.solvedPath[this.solvedPath.length-1];if(isNaN(t))throw Error("baobab.Cursor.left: cannot go left on a non-list type.");return t?this.tree.select(this.solvedPath.slice(0,-1).concat(t-1)):null},e.prototype.leftmost=function(){var t=+this.solvedPath[this.solvedPath.length-1];if(isNaN(t))throw Error("baobab.Cursor.leftmost: cannot go left on a non-list type.");return this.tree.select(this.solvedPath.slice(0,-1).concat(0))},e.prototype.right=function(){var t=+this.solvedPath[this.solvedPath.length-1];if(isNaN(t))throw Error("baobab.Cursor.right: cannot go right on a non-list type.");return t+1===this.up().get().length?null:this.tree.select(this.solvedPath.slice(0,-1).concat(t+1))},e.prototype.rightmost=function(){var t=+this.solvedPath[this.solvedPath.length-1];if(isNaN(t))throw Error("baobab.Cursor.right: cannot go right on a non-list type.");var r=this.up().get();return this.tree.select(this.solvedPath.slice(0,-1).concat(r.length-1))},e.prototype.down=function(){+this.solvedPath[this.solvedPath.length-1];return this.get()instanceof Array?this.tree.select(this.solvedPath.concat(0)):null},e.prototype.get=function(t){arguments.length>1&&(t=s.arrayOf(arguments));var r=this.solvedPath.concat((a.String(t)||a.Number(t)?[t]:t)||[]);return s.getIn(this.tree.data,r)},e.prototype.set=function(t,r){if(arguments.length<2)throw Error("baobab.Cursor.set: expecting at least key/value.");var e=this.get();if("object"!=typeof e)throw Error("baobab.Cursor.set: trying to set key to a non-object.");var n={};if(a.Array(t)){var o=s.solvePath(e,t);if(!o)throw Error("baobab.Cursor.set: could not solve dynamic path.");n=s.pathObject(o,{$set:r})}else n[t]={$set:r};return this.update(n)},e.prototype.edit=function(t){return this.update({$set:t})},e.prototype.unset=function(t){if(!t&&0!==t)throw Error("baobab.Cursor.unset: expects a valid key to unset.");if("object"!=typeof this.get())throw Error("baobab.Cursor.set: trying to set key to a non-object.");var r={};return r[t]={$unset:!0},this.update(r)},e.prototype.remove=function(){if(this.isRoot())throw Error("baobab.Cursor.remove: cannot remove root node.");return this.update({$unset:!0})},e.prototype.apply=function(t){if("function"!=typeof t)throw Error("baobab.Cursor.apply: argument is not a function.");return this.update({$apply:t})},e.prototype.chain=function(t){if("function"!=typeof t)throw Error("baobab.Cursor.chain: argument is not a function.");return this.update({$chain:t})},e.prototype.push=function(t){if(!(this.get()instanceof Array))throw Error("baobab.Cursor.push: trying to push to non-array value.");return this.update(arguments.length>1?{$push:s.arrayOf(arguments)}:{$push:t})},e.prototype.unshift=function(t){if(!(this.get()instanceof Array))throw Error("baobab.Cursor.push: trying to push to non-array value.");return this.update(arguments.length>1?{$unshift:s.arrayOf(arguments)}:{$unshift:t})},e.prototype.merge=function(t){if(!a.Object(t))throw Error("baobab.Cursor.merge: trying to merge a non-object.");if(!a.Object(this.get()))throw Error("baobab.Cursor.merge: trying to merge into a non-object.");this.update({$merge:t})},e.prototype.update=function(t){return this.tree.stack(s.pathObject(this.solvedPath,t)),this},e.prototype.or=function(t){return new o("or",this,t)},e.prototype.and=function(t){return new o("and",this,t)},e.prototype.release=function(){this.tree.off("update",this.updateHandler),this.hash&&delete this.tree._cursors[this.hash],delete this.tree,delete this.path,delete this.solvedPath,this.kill()},e.prototype.toJSON=function(){return this.get()},a.Cursor=function(t){return t instanceof e},r.exports=e},{"./combination.js":5,"./helpers.js":7,"./mixins.js":9,"./type.js":10,emmett:3}],7:[function(t,r){function e(t){return Array.prototype.slice.call(t)}function n(t,r){return function(){t(),r.apply(null,arguments)}}function o(t,r){var e,n={};for(e in t)n[e]=t[e];for(e in r)n[e]=r[e];return n}function i(t){var r=t.source,e="";return t.global&&(e+="g"),t.multiline&&(e+="m"),t.ignoreCase&&(e+="i"),t.sticky&&(e+="y"),t.unicode&&(e+="u"),new RegExp(r,e)}function s(t,r){if(!r||"object"!=typeof r||r instanceof Error||r instanceof ArrayBuffer)return r;if(g.Array(r)){if(t){var e,n,o=[];for(e=0,n=r.length;n>e;e++)o.push(v(r[e]));return o}return r.slice(0)}if(g.Date(r))return new Date(r.getTime());if(r instanceof RegExp)return i(r);if(g.Object(r)){var s,a={};r.constructor&&r.constructor!==Object&&(a=Object.create(r.constructor.prototype));for(s in r)r.hasOwnProperty(s)&&(a[s]=t?v(r[s]):r[s]);return a}return r}function a(t,r){return function(e){return r(t(e))}}function h(t,r){var e,n;for(e=0,n=t.length;n>e;e++)if(r(t[e]))return t[e]}function u(t,r){var e,n;for(e=0,n=t.length;n>e;e++)if(r(t[e]))return e;return-1}function c(t,r){var e,n=!0;if(!t)return!1;for(e in r)if(g.Object(r[e]))n=n&&c(t[e],r[e]);else if(g.Array(r[e]))n=n&&!!~r[e].indexOf(t[e]);else if(t[e]!==r[e])return!1;return n}function f(t,r){return h(t,function(t){return c(t,r)})}function l(t,r){return u(t,function(t){return c(t,r)})}function p(t,r){r=r||[];var e,n,o=t;for(e=0,n=r.length;n>e;e++){if(!o)return;if("function"==typeof r[e]){if(!g.Array(o))return;o=h(o,r[e])}else if("object"==typeof r[e]){if(!g.Array(o))return;o=f(o,r[e])}else o=o[r[e]]}return o}function d(t,r){var e,n,o,i=[],s=t;for(n=0,o=r.length;o>n;n++){if(!s)return null;if("function"==typeof r[n]){if(!g.Array(s))return;e=u(s,r[n]),i.push(e),s=s[e]}else if("object"==typeof r[n]){if(!g.Array(s))return;e=l(s,r[n]),i.push(e),s=s[e]}else i.push(r[n]),s=s[r[n]]||{}}return i}function y(t,r){var e,n=t.length,o={},i=o;for(n||(o=r),e=0;n>e;e++)i[t[e]]=e+1===n?r:{},i=i[t[e]];return o}function b(t,r){t.super_=r;var e=function(){};e.prototype=r.prototype,t.prototype=new e,t.prototype.constructor=t}var g=t("./type.js"),m=s.bind(null,!1),v=s.bind(null,!0);r.exports={arrayOf:e,before:n,deepClone:v,shallowClone:m,shallowMerge:o,compose:a,getIn:p,inherits:b,pathObject:y,solvePath:d}},{"./type.js":10}],8:[function(t,r){function e(t,r,e){s.forEach(function(r){e!==r&&delete t[r]}),t[e]=r[e]}function n(t,r){var a,h=o.shallowClone(r||{});s.forEach(function(r){t[r]&&e(h,t,r)}),t.$chain&&(s.slice(0,-1).forEach(function(t){delete h[t]}),h.$apply=h.$apply?o.compose(h.$apply,t.$chain):t.$chain),t.$push&&h.$push?h.$push=i.Array(h.$push)?h.$push.concat(t.$push):[h.$push].concat(t.$push):t.$push&&(h.$push=t.$push),t.$unshift&&h.$unshift?h.$unshift=i.Array(t.$unshift)?t.$unshift.concat(h.$unshift):[t.$unshift].concat(h.$unshift):t.$unshift&&(h.$unshift=t.$unshift);for(a in t)i.Object(t[a])?h[a]=n(t[a],h[a]):"$"!==a[0]&&(h[a]=t[a]);return h}var o=t("./helpers.js"),i=t("./type.js"),s=["$unset","$set","$merge","$apply"];r.exports=n},{"./helpers.js":7,"./type.js":10}],9:[function(t,r){var e=t("./combination.js"),n=t("./type.js");r.exports={baobab:function(t){return{mixins:[{getInitialState:function(){if(this.tree=t,!this.cursor&&!this.cursors)return{};if(this.cursor&&this.cursors)throw Error("baobab.mixin: you cannot have both `component.cursor` and `component.cursors`. Please make up your mind.");if(this.__type=null,this.__updateHandler=function(){this.setState(this.__getCursorData())}.bind(this),this.cursor){if(!n.MixinCursor(this.cursor))throw Error("baobab.mixin.cursor: invalid data (cursor, string, array or function).");n.Function(this.cursor)&&(this.cursor=this.cursor()),n.Cursor(this.cursor)||(this.cursor=t.select(this.cursor)),this.__getCursorData=function(){return{cursor:this.cursor.get()}}.bind(this),this.__type="single"}else if(this.cursors){if(!n.MixinCursors(this.cursors))throw Error("baobab.mixin.cursor: invalid data (object, array or function).");if(n.Function(this.cursors)&&(this.cursors=this.cursors()),n.Array(this.cursors))this.cursors=this.cursors.map(function(r){return n.Cursor(r)?r:t.select(r)}),this.__getCursorData=function(){return{cursors:this.cursors.map(function(t){return t.get()})}}.bind(this),this.__type="array";else{for(var r in this.cursors)n.Cursor(this.cursors[r])||(this.cursors[r]=t.select(this.cursors[r]));this.__getCursorData=function(){var t={};for(r in this.cursors)t[r]=this.cursors[r].get();return{cursors:t}}.bind(this),this.__type="object"}}return this.__getCursorData()},componentDidMount:function(){"single"===this.__type?(this.__combination=new e("or",[this.cursor]),this.__combination.on("update",this.__updateHandler)):"array"===this.__type?(this.__combination=new e("or",this.cursors),this.__combination.on("update",this.__updateHandler)):"object"===this.__type&&(this.__combination=new e("or",Object.keys(this.cursors).map(function(t){return this.cursors[t]},this)),this.__combination.on("update",this.__updateHandler))},componentWillUnmount:function(){this.__combination&&this.__combination.release()}}].concat(t.options.mixins)}},cursor:function(t){return{mixins:[{getInitialState:function(){return this.cursor=t,this.__updateHandler=function(){this.setState({cursor:this.cursor.get()})}.bind(this),{cursor:this.cursor.get()}},componentDidMount:function(){this.cursor.on("update",this.__updateHandler)},componentWillUnmount:function(){this.cursor.off("update",this.__updateHandler)}}].concat(t.tree.options.mixins)}}}},{"./combination.js":5,"./type.js":10}],10:[function(t,r){var e=function(t){return Array.isArray(t)?"array":"object"==typeof t&&null!==t?"object":"string"==typeof t?"string":"number"==typeof t?"number":"boolean"==typeof t?"boolean":"function"==typeof t?"function":null===t?"null":void 0===t?"undefined":t instanceof Date?"date":"invalid"};e.Array=function(t){return Array.isArray(t)},e.Object=function(t){return!Array.isArray(t)&&"object"==typeof t&&null!==t},e.String=function(t){return"string"==typeof t},e.Number=function(t){return"number"==typeof t},e.Boolean=function(t){return"boolean"==typeof t},e.Function=function(t){return"function"==typeof t},e.Primitive=function(t){return"string"==typeof t||"number"==typeof t||"boolean"==typeof t},e.Date=function(t){return t instanceof Date},e.Step=function(t){var r=e(t),n=["null","undefined","invalid","date"];return-1===n.indexOf(r)},e.Path=function(t){var r=["object","string","number","function","undefined"];if(!e.Array(t))return r.indexOf(e(t))>=0;for(var n=0;n=0||e.Cursor(t)},e.MixinCursors=function(t){var r=["array","object","function"];return r.indexOf(e(t))>=0},e.ComplexPath=function(t){for(var r=["object","function"],n=0;n=0)return!0;return!1},r.exports=e},{}],11:[function(t,r){function e(t,r){var e=new Error("baobab.update: "+r+" at path /"+t.toString());return e.path=t,e}function n(t,r,n){n=n||{shiftReferences:!1};var a={};return function h(t,r,u,c){u=u||[];var f,l,p,d,y=u.join("λ");for(p in r)if(s[p])switch(d=r[p],a[y]=!0,p){case"$push":if(!i.Array(t))throw e(u,"using command $push to a non array");i.Array(d)?t.push.apply(t,d):t.push(d);break;case"$unshift":if(!i.Array(t))throw e(u,"using command $unshift to a non array");i.Array(d)?t.unshift.apply(t,d):t.unshift(d)}else if(l=y?y+"λ"+p:p,"$unset"in(r[p]||{}))a[l]=!0,i.Array(t)?n.shiftReferences?c[u[u.length-1]]=t.slice(0,+p).concat(t.slice(+p+1)):t.splice(p,1):delete t[p];else if("$set"in(r[p]||{}))d=r[p].$set,a[l]=!0,t[p]=d;else if("$apply"in(r[p]||{})||"$chain"in(r[p]||{})){if(f=r[p].$apply||r[p].$chain,"function"!=typeof f)throw e(u.concat(p),"using command $apply with a non function");a[l]=!0,t[p]=f.call(null,t[p])}else if("$merge"in(r[p]||{})){if(d=r[p].$merge,!i.Object(t[p]))throw e(u.concat(p),"using command $merge on a non-object");a[l]=!0,t[p]=o.shallowMerge(t[p],d)}else if(n.shiftReferences&&("$push"in(r[p]||{})||"$unshift"in(r[p]||{}))){if("$push"in(r[p]||{})){if(d=r[p].$push,!i.Array(t[p]))throw e(u.concat(p),"using command $push to a non array");t[p]=t[p].concat(d)}if("$unshift"in(r[p]||{})){if(d=r[p].$unshift,!i.Array(t[p]))throw e(u.concat(p),"using command $unshift to a non array");t[p]=(d instanceof Array?d:[d]).concat(t[p])}a[l]=!0}else"undefined"==typeof t[p]&&(t[p]={}),n.shiftReferences&&(t[p]=o.shallowClone(t[p])),h(t[p],r[p],u.concat(p),t)}(t,r),Object.keys(a).map(function(t){return t.split("λ")})}var o=t("./helpers.js"),i=t("./type.js"),s={};["$set","$push","$unshift","$apply","$merge"].forEach(function(t){s[t]=!0}),r.exports=n},{"./helpers.js":7,"./type.js":10}]},{},[2])(2)}); \ No newline at end of file diff --git a/src/merge.js b/src/merge.js index bf47520..acbede9 100644 --- a/src/merge.js +++ b/src/merge.js @@ -8,105 +8,68 @@ var helpers = require('./helpers.js'), type = require('./type.js'); // Helpers -function hasKey(o, key) { - return key in (o || {}); -} +var COMMANDS = ['$unset', '$set', '$merge', '$apply']; + +function only(o, n, keep) { + COMMANDS.forEach(function(c) { + if (keep !== c) + delete o[c]; + }); -function conflict(a, b, key) { - return hasKey(a, key) && hasKey(b, key); + o[keep] = n[keep]; } // Main function -function merge() { - var res = {}, - current, - next, - l = arguments.length, - i, - k; +function merge(a, b) { + var o = helpers.shallowClone(b || {}), + k, + i; - for (i = l - 1; i >= 0; i--) { + COMMANDS.forEach(function(c) { + if (a[c]) + only(o, a, c); + }); - // Upper $set/$apply... and conflicts - // When solving conflicts, here is the priority to apply: - // -- 0) $unset - // -- 1) $set - // -- 2) $merge - // -- 3) $apply - // -- 4) $chain - if (arguments[i].$unset) { - delete res.$set; - delete res.$apply; - delete res.$merge; - res.$unset = arguments[i].$unset; - } - else if (arguments[i].$set) { - delete res.$apply; - delete res.$merge; - delete res.$unset; - res.$set = arguments[i].$set; - continue; - } - else if (arguments[i].$merge) { - delete res.$set; - delete res.$apply; - delete res.$unset; - res.$merge = arguments[i].$merge; - continue; - } - else if (arguments[i].$apply){ - delete res.$set; - delete res.$merge; - delete res.$unset; - res.$apply = arguments[i].$apply; - continue; - } - else if (arguments[i].$chain) { - delete res.$set; - delete res.$merge; - delete res.$unset; + if (a.$chain) { + COMMANDS.slice(0, -1).forEach(function(c) { + delete o[c]; + }); - if (res.$apply) - res.$apply = helpers.compose(res.$apply, arguments[i].$chain); - else - res.$apply = arguments[i].$chain; - continue; - } - - for (k in arguments[i]) { - current = res[k]; - next = arguments[i][k]; + if (o.$apply) + o.$apply = helpers.compose(o.$apply, a.$chain); + else + o.$apply = a.$chain; + } - if (current && type.Object(next)) { + if (a.$push && o.$push) { + if (type.Array(o.$push)) + o.$push = o.$push.concat(a.$push); + else + o.$push = [o.$push].concat(a.$push); + } + else if (a.$push) { + o.$push = a.$push; + } - // $push conflict - if (conflict(current, next, '$push')) { - if (type.Array(current.$push)) - current.$push = current.$push.concat(next.$push); - else - current.$push = [current.$push].concat(next.$push); - } + if (a.$unshift && o.$unshift) { + if (type.Array(a.$unshift)) + o.$unshift = a.$unshift.concat(o.$unshift); + else + o.$unshift = [a.$unshift].concat(o.$unshift); + } + else if (a.$unshift) { + o.$unshift = a.$unshift; + } - // $unshift conflict - else if (conflict(current, next, '$unshift')) { - if (type.Array(next.$unshift)) - current.$unshift = next.$unshift.concat(current.$unshift); - else - current.$unshift = [next.$unshift].concat(current.$unshift); - } + for (k in a) { - // No conflict - else { - res[k] = merge(next, current); - } - } - else { - res[k] = next; - } - } + if (type.Object(a[k])) + o[k] = merge(a[k], o[k]); + else if (k[0] !== '$') + o[k] = a[k]; } - return res; + return o; } module.exports = merge; From b4603351fe9c460292e94aab831e260429c4cbf8 Mon Sep 17 00:00:00 2001 From: Yomguithereal Date: Tue, 31 Mar 2015 17:20:58 +0200 Subject: [PATCH 13/73] Refactoring update routine --- build/baobab.min.js | 2 +- defaults.js | 3 - src/baobab.js | 9 +- src/merge.js | 2 + src/update.js | 216 ++++++++++++++++++----------------------- test/suites/baobab.js | 61 +++++------- test/suites/helpers.js | 36 +++---- 7 files changed, 139 insertions(+), 190 deletions(-) diff --git a/build/baobab.min.js b/build/baobab.min.js index 5aab7f3..2ca3796 100644 --- a/build/baobab.min.js +++ b/build/baobab.min.js @@ -1,2 +1,2 @@ /* baobab.js - Version: 0.4.3 - Author: Yomguithereal (Guillaume Plique) */ -!function(t){if("object"==typeof exports&&"undefined"!=typeof module)module.exports=t();else if("function"==typeof define&&define.amd)define([],t);else{var r;r="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:this,r.Baobab=t()}}(function(){var t;return function r(t,e,n){function o(s,a){if(!e[s]){if(!t[s]){var h="function"==typeof require&&require;if(!a&&h)return h(s,!0);if(i)return i(s,!0);var u=new Error("Cannot find module '"+s+"'");throw u.code="MODULE_NOT_FOUND",u}var c=e[s]={exports:{}};t[s][0].call(c.exports,function(r){var e=t[s][1][r];return o(e?e:r)},c,c.exports,r,t,e,n)}return e[s].exports}for(var i="function"==typeof require&&require,s=0;sr;r++)n.push(t[r].handler);return n}var o={once:"boolean",scope:"object"},i=function(){this._enabled=!0,this._children=[],this._handlers={},this._handlersAll=[]};i.prototype.on=function(t,r,e){var n,s,a,h,u,c;if("function"==typeof r){for(u="string"==typeof t?[t]:t,n=0,s=u.length;n!==s;n+=1)if(h=u[n]){this._handlers[h]||(this._handlers[h]=[]),c={handler:r};for(a in e||{}){if(!o[a])throw new Error('The option "'+a+'" is not recognized by Emmett.');c[a]=e[a]}this._handlers[h].push(c)}}else if(t&&"object"==typeof t&&!Array.isArray(t))for(h in t)i.prototype.on.call(this,h,t[h],r);else{if("function"!=typeof t)throw new Error("Wrong arguments.");c={handler:t};for(a in e||{}){if(!o[a])throw new Error('The option "'+a+'" is not recognized by Emmett.');c[a]=e[a]}this._handlersAll.push(c)}return this},i.prototype.once=function(t,r,e){if("function"==typeof r)e=e||{},e.once=!0,this.on(t,r,e);else{if((!t||"object"!=typeof t||Array.isArray(t))&&"function"!=typeof t)throw new Error("Wrong arguments.");r=r||{},r.once=!0,this.on(t,r)}return this},i.prototype.off=function(t,r){var e,n,o,i,s,a,h,u="string"==typeof t?[t]:t;if(1===arguments.length&&"function"==typeof u){r=arguments[0];for(s in this._handlers){for(a=[],e=0,n=this._handlers[s].length;e!==n;e+=1)this._handlers[s][e].handler!==r&&a.push(this._handlers[s][e]);this._handlers[s]=a}for(a=[],e=0,n=this._handlersAll.length;e!==n;e+=1)this._handlersAll[e].handler!==r&&a.push(this._handlersAll[e]);this._handlersAll=a}else if(2===arguments.length)for(e=0,n=u.length;e!==n;e+=1){if(h=u[e],this._handlers[h]){for(a=[],o=0,i=this._handlers[h].length;o!==i;o+=1)this._handlers[h][o].handler!==r&&a.push(this._handlers[h][o]);this._handlers[h]=a}this._handlers[h]&&0===this._handlers[h].length&&delete this._handlers[h]}return this},i.prototype.unbindAll=function(){var t;this._handlersAll=[];for(t in this._handlers)delete this._handlers[t];return this},i.prototype.emit=function(t,r){var e,n,o,i,s,a,h,u,c,f,l="string"==typeof t?[t]:t;if(!this._enabled)return this;for(r=void 0===r?{}:r,e=0,n=l.length;e!==n;e+=1)if(f=l[e],c=(this._handlers[f]||[]).concat(this._handlersAll),c.length){for(h={type:f,data:r||{},target:this},a=[],o=0,i=c.length;o!==i;o+=1)(this._handlers[f]&&this._handlers[f].indexOf(c[o])>=0||this._handlersAll.indexOf(c[o])>=0)&&(c[o].handler.call("scope"in c[o]?c[o].scope:this,h),c[o].once&&a.push(c[o]));for(s=0;se;e++)if(t._children[e]===r){t._children.splice(e,1);break}}),this._children.push(r),r},i.prototype.listeners=function(t){var e,n,o,i=[];if(t)for(i=r(this._handlers[t]),n=0,o=this._children.length;o>n;n++)i=i.concat(this._children[n].listeners(t));else{i=r(this._handlersAll);for(e in this._handlers)i=i.concat(r(this._handlers[e]));for(n=0,o=this._children.length;o>n;n++)i=i.concat(this._children[n].listeners())}return i},i.prototype.kill=function(){if(this.emit("emmett:kill"),this.unbindAll(),this._handlers=null,this._handlersAll=null,this._enabled=!1,this._children)for(var t=0,r=this._children.length;r>t;t++)this._children[t].kill();this._children=null},i.prototype.disable=function(){return this._enabled=!1,this},i.prototype.enable=function(){return this._enabled=!0,this},i.version="2.1.2","undefined"!=typeof n?("undefined"!=typeof e&&e.exports&&(n=e.exports=i),n.Emitter=i):"function"==typeof t&&t.amd?t("emmett",[],function(){return i}):this.Emitter=i}).call(this)},{}],4:[function(t,r){function e(t){return t+"$"+(new Date).getTime()+(""+Math.random()).replace("0.","")}function n(t,r){function e(t){this[t]=function(){var r=this.root[t].apply(this.root,arguments);return r instanceof o?this:r}}if(arguments.length<1&&(t={}),!(this instanceof n))return new n(t,r);if(!f.Object(t)&&!f.Array(t))throw Error("Baobab: invalid data.");i.call(this),this.options=s.shallowMerge(c,r),this._transaction={},this._future=void 0,this._cursors={},this.data=s.deepClone(t),this.root=this.select([]),["get","set","unset","update"].forEach(e.bind(this)),this.mixin=u.baobab(this)}var o=t("./cursor.js"),i=t("emmett"),s=t("./helpers.js"),a=t("./update.js"),h=t("./merge.js"),u=t("./mixins.js"),c=t("../defaults.js"),f=t("./type.js");s.inherits(n,i),n.prototype.select=function(t){if(!t)throw Error("Baobab.select: invalid path.");if(arguments.length>1&&(t=s.arrayOf(arguments)),!f.Path(t))throw Error("Baobab.select: invalid path.");t=[].concat(t);var r,n=f.ComplexPath(t);n&&(r=s.solvePath(this.data,t));var i=t.map(function(t){return f.Function(t)?e("fn"):f.Object(t)?e("ob"):t}).join("λ");if(this._cursors[i])return this._cursors[i];var a=new o(this,t,r,i);return this._cursors[i]=a,a},n.prototype.stack=function(t){var r=this;if(!f.Object(t))throw Error("Baobab.update: wrong specification.");return this._transaction=h(t,this._transaction),this.options.autoCommit?this.options.asynchronous?(this._future||(this._future=setTimeout(r.commit.bind(r,null),0)),this):this.commit():this},n.prototype.commit=function(){this.options.shiftReferences&&(this.data=s.shallowClone(this.data));var t=a(this.data,this._transaction,this.options);return this._transaction={},this._future&&(this._future=clearTimeout(this._future)),this.emit("update",{log:t}),this},n.prototype.release=function(){delete this.data,delete this._transaction;for(var t in this._cursors)this._cursors[t].release();delete this._cursors,this.kill()},n.prototype.toJSON=function(){return this.get()},r.exports=n},{"../defaults.js":1,"./cursor.js":6,"./helpers.js":7,"./merge.js":8,"./mixins.js":9,"./type.js":10,"./update.js":11,emmett:3}],5:[function(t,r){function e(t,r){r.on("update",t.cursorListener),t.tree.off("update",t.treeListener),t.tree.on("update",t.treeListener)}function n(t){var r=this;if(arguments.length<2)throw Error("baobab.Combination: not enough arguments.");var n=arguments[1],o=s.arrayOf(arguments).slice(2);if(n instanceof Array&&(o=n.slice(1),n=n[0]),!a.Cursor(n))throw Error("baobab.Combination: argument should be a cursor.");if("or"!==t&&"and"!==t)throw Error("baobab.Combination: invalid operator.");i.call(this),this.cursors=[n],this.operators=[],this.tree=n.tree,this.updates=new Array(this.cursors.length),this.cursorListener=function(){r.updates[r.cursors.indexOf(this)]=!0},this.treeListener=function(){var t,e,n=r.updates[0];for(t=1,e=r.cursors.length;e>t;t++)n="or"===r.operators[t-1]?n||r.updates[t]:n&&r.updates[t];n&&r.emit("update"),r.updates=new Array(r.cursors.length)},this.bound=!1;var h=(this.on,this.once,function(){r.bound||(r.bound=!0,r.cursors.forEach(function(t){e(r,t)}))});this.on=s.before(h,this.on.bind(this)),this.once=s.before(h,this.once.bind(this)),o.forEach(function(r){this[t](r)},this)}function o(t){n.prototype[t]=function(r){if(!a.Cursor(r))throw this.release(),Error("baobab.Combination."+t+": argument should be a cursor.");if(~this.cursors.indexOf(r))throw this.release(),Error("baobab.Combination."+t+": cursor already in combination.");return this.cursors.push(r),this.operators.push(t),this.updates.length++,this.bound&&e(this,r),this}}var i=t("emmett"),s=t("./helpers.js"),a=t("./type.js");s.inherits(n,i),o("or"),o("and"),n.prototype.release=function(){this.cursors.forEach(function(t){t.off("update",this.cursorListener)},this),this.tree.off("update",this.treeListener),this.cursors=null,this.operators=null,this.tree=null,this.updates=null,this.kill()},r.exports=n},{"./helpers.js":7,"./type.js":10,emmett:3}],6:[function(t,r){function e(t,r,e,o){var a=this;n.call(this),r=r||[],this.tree=t,this.path=r,this.hash=o,this.complexPath=!!e,this.solvedPath=this.complexPath?e:this.path,this.relevant=void 0!==this.get(),this.updateHandler=function(t){var r,e,n,o,i,h,u=t.data.log,c=!1;if(a.complexPath&&(a.solvedPath=s.solvePath(a.tree.data,a.path)),!a.path.length)return a.emit("update");t:for(i=0,n=u.length;n>i;i++)for(r=u[i],h=0,o=r.length;o>h&&(e=r[h],e===""+a.solvedPath[h]);h++)if(h+1===o||h+1===a.solvedPath.length){c=!0;break t}var f=void 0!==a.get();a.relevant?f&&c?a.emit("update"):f||(a.emit("irrelevant"),a.relevant=!1):f&&c&&(a.emit("relevant"),a.emit("update"),a.relevant=!0)},this.mixin=i.cursor(this);var h=!1,u=function(){h||(h=!0,a.tree.on("update",a.updateHandler))};this.on=s.before(u,this.on.bind(this)),this.once=s.before(u,this.once.bind(this))}var n=t("emmett"),o=t("./combination.js"),i=t("./mixins.js"),s=t("./helpers.js"),a=t("./type.js");s.inherits(e,n),e.prototype.isRoot=function(){return!this.path.length},e.prototype.isLeaf=function(){return a.Primitive(this.get())},e.prototype.isBranch=function(){return!this.isLeaf()&&!this.isRoot()},e.prototype.root=function(){return this.tree.root()},e.prototype.select=function(t){if(arguments.length>1&&(t=s.arrayOf(arguments)),!a.Path(t))throw Error("baobab.Cursor.select: invalid path.");return this.tree.select(this.path.concat(t))},e.prototype.up=function(){return this.solvedPath&&this.solvedPath.length?this.tree.select(this.path.slice(0,-1)):null},e.prototype.left=function(){var t=+this.solvedPath[this.solvedPath.length-1];if(isNaN(t))throw Error("baobab.Cursor.left: cannot go left on a non-list type.");return t?this.tree.select(this.solvedPath.slice(0,-1).concat(t-1)):null},e.prototype.leftmost=function(){var t=+this.solvedPath[this.solvedPath.length-1];if(isNaN(t))throw Error("baobab.Cursor.leftmost: cannot go left on a non-list type.");return this.tree.select(this.solvedPath.slice(0,-1).concat(0))},e.prototype.right=function(){var t=+this.solvedPath[this.solvedPath.length-1];if(isNaN(t))throw Error("baobab.Cursor.right: cannot go right on a non-list type.");return t+1===this.up().get().length?null:this.tree.select(this.solvedPath.slice(0,-1).concat(t+1))},e.prototype.rightmost=function(){var t=+this.solvedPath[this.solvedPath.length-1];if(isNaN(t))throw Error("baobab.Cursor.right: cannot go right on a non-list type.");var r=this.up().get();return this.tree.select(this.solvedPath.slice(0,-1).concat(r.length-1))},e.prototype.down=function(){+this.solvedPath[this.solvedPath.length-1];return this.get()instanceof Array?this.tree.select(this.solvedPath.concat(0)):null},e.prototype.get=function(t){arguments.length>1&&(t=s.arrayOf(arguments));var r=this.solvedPath.concat((a.String(t)||a.Number(t)?[t]:t)||[]);return s.getIn(this.tree.data,r)},e.prototype.set=function(t,r){if(arguments.length<2)throw Error("baobab.Cursor.set: expecting at least key/value.");var e=this.get();if("object"!=typeof e)throw Error("baobab.Cursor.set: trying to set key to a non-object.");var n={};if(a.Array(t)){var o=s.solvePath(e,t);if(!o)throw Error("baobab.Cursor.set: could not solve dynamic path.");n=s.pathObject(o,{$set:r})}else n[t]={$set:r};return this.update(n)},e.prototype.edit=function(t){return this.update({$set:t})},e.prototype.unset=function(t){if(!t&&0!==t)throw Error("baobab.Cursor.unset: expects a valid key to unset.");if("object"!=typeof this.get())throw Error("baobab.Cursor.set: trying to set key to a non-object.");var r={};return r[t]={$unset:!0},this.update(r)},e.prototype.remove=function(){if(this.isRoot())throw Error("baobab.Cursor.remove: cannot remove root node.");return this.update({$unset:!0})},e.prototype.apply=function(t){if("function"!=typeof t)throw Error("baobab.Cursor.apply: argument is not a function.");return this.update({$apply:t})},e.prototype.chain=function(t){if("function"!=typeof t)throw Error("baobab.Cursor.chain: argument is not a function.");return this.update({$chain:t})},e.prototype.push=function(t){if(!(this.get()instanceof Array))throw Error("baobab.Cursor.push: trying to push to non-array value.");return this.update(arguments.length>1?{$push:s.arrayOf(arguments)}:{$push:t})},e.prototype.unshift=function(t){if(!(this.get()instanceof Array))throw Error("baobab.Cursor.push: trying to push to non-array value.");return this.update(arguments.length>1?{$unshift:s.arrayOf(arguments)}:{$unshift:t})},e.prototype.merge=function(t){if(!a.Object(t))throw Error("baobab.Cursor.merge: trying to merge a non-object.");if(!a.Object(this.get()))throw Error("baobab.Cursor.merge: trying to merge into a non-object.");this.update({$merge:t})},e.prototype.update=function(t){return this.tree.stack(s.pathObject(this.solvedPath,t)),this},e.prototype.or=function(t){return new o("or",this,t)},e.prototype.and=function(t){return new o("and",this,t)},e.prototype.release=function(){this.tree.off("update",this.updateHandler),this.hash&&delete this.tree._cursors[this.hash],delete this.tree,delete this.path,delete this.solvedPath,this.kill()},e.prototype.toJSON=function(){return this.get()},a.Cursor=function(t){return t instanceof e},r.exports=e},{"./combination.js":5,"./helpers.js":7,"./mixins.js":9,"./type.js":10,emmett:3}],7:[function(t,r){function e(t){return Array.prototype.slice.call(t)}function n(t,r){return function(){t(),r.apply(null,arguments)}}function o(t,r){var e,n={};for(e in t)n[e]=t[e];for(e in r)n[e]=r[e];return n}function i(t){var r=t.source,e="";return t.global&&(e+="g"),t.multiline&&(e+="m"),t.ignoreCase&&(e+="i"),t.sticky&&(e+="y"),t.unicode&&(e+="u"),new RegExp(r,e)}function s(t,r){if(!r||"object"!=typeof r||r instanceof Error||r instanceof ArrayBuffer)return r;if(g.Array(r)){if(t){var e,n,o=[];for(e=0,n=r.length;n>e;e++)o.push(v(r[e]));return o}return r.slice(0)}if(g.Date(r))return new Date(r.getTime());if(r instanceof RegExp)return i(r);if(g.Object(r)){var s,a={};r.constructor&&r.constructor!==Object&&(a=Object.create(r.constructor.prototype));for(s in r)r.hasOwnProperty(s)&&(a[s]=t?v(r[s]):r[s]);return a}return r}function a(t,r){return function(e){return r(t(e))}}function h(t,r){var e,n;for(e=0,n=t.length;n>e;e++)if(r(t[e]))return t[e]}function u(t,r){var e,n;for(e=0,n=t.length;n>e;e++)if(r(t[e]))return e;return-1}function c(t,r){var e,n=!0;if(!t)return!1;for(e in r)if(g.Object(r[e]))n=n&&c(t[e],r[e]);else if(g.Array(r[e]))n=n&&!!~r[e].indexOf(t[e]);else if(t[e]!==r[e])return!1;return n}function f(t,r){return h(t,function(t){return c(t,r)})}function l(t,r){return u(t,function(t){return c(t,r)})}function p(t,r){r=r||[];var e,n,o=t;for(e=0,n=r.length;n>e;e++){if(!o)return;if("function"==typeof r[e]){if(!g.Array(o))return;o=h(o,r[e])}else if("object"==typeof r[e]){if(!g.Array(o))return;o=f(o,r[e])}else o=o[r[e]]}return o}function d(t,r){var e,n,o,i=[],s=t;for(n=0,o=r.length;o>n;n++){if(!s)return null;if("function"==typeof r[n]){if(!g.Array(s))return;e=u(s,r[n]),i.push(e),s=s[e]}else if("object"==typeof r[n]){if(!g.Array(s))return;e=l(s,r[n]),i.push(e),s=s[e]}else i.push(r[n]),s=s[r[n]]||{}}return i}function y(t,r){var e,n=t.length,o={},i=o;for(n||(o=r),e=0;n>e;e++)i[t[e]]=e+1===n?r:{},i=i[t[e]];return o}function b(t,r){t.super_=r;var e=function(){};e.prototype=r.prototype,t.prototype=new e,t.prototype.constructor=t}var g=t("./type.js"),m=s.bind(null,!1),v=s.bind(null,!0);r.exports={arrayOf:e,before:n,deepClone:v,shallowClone:m,shallowMerge:o,compose:a,getIn:p,inherits:b,pathObject:y,solvePath:d}},{"./type.js":10}],8:[function(t,r){function e(t,r,e){s.forEach(function(r){e!==r&&delete t[r]}),t[e]=r[e]}function n(t,r){var a,h=o.shallowClone(r||{});s.forEach(function(r){t[r]&&e(h,t,r)}),t.$chain&&(s.slice(0,-1).forEach(function(t){delete h[t]}),h.$apply=h.$apply?o.compose(h.$apply,t.$chain):t.$chain),t.$push&&h.$push?h.$push=i.Array(h.$push)?h.$push.concat(t.$push):[h.$push].concat(t.$push):t.$push&&(h.$push=t.$push),t.$unshift&&h.$unshift?h.$unshift=i.Array(t.$unshift)?t.$unshift.concat(h.$unshift):[t.$unshift].concat(h.$unshift):t.$unshift&&(h.$unshift=t.$unshift);for(a in t)i.Object(t[a])?h[a]=n(t[a],h[a]):"$"!==a[0]&&(h[a]=t[a]);return h}var o=t("./helpers.js"),i=t("./type.js"),s=["$unset","$set","$merge","$apply"];r.exports=n},{"./helpers.js":7,"./type.js":10}],9:[function(t,r){var e=t("./combination.js"),n=t("./type.js");r.exports={baobab:function(t){return{mixins:[{getInitialState:function(){if(this.tree=t,!this.cursor&&!this.cursors)return{};if(this.cursor&&this.cursors)throw Error("baobab.mixin: you cannot have both `component.cursor` and `component.cursors`. Please make up your mind.");if(this.__type=null,this.__updateHandler=function(){this.setState(this.__getCursorData())}.bind(this),this.cursor){if(!n.MixinCursor(this.cursor))throw Error("baobab.mixin.cursor: invalid data (cursor, string, array or function).");n.Function(this.cursor)&&(this.cursor=this.cursor()),n.Cursor(this.cursor)||(this.cursor=t.select(this.cursor)),this.__getCursorData=function(){return{cursor:this.cursor.get()}}.bind(this),this.__type="single"}else if(this.cursors){if(!n.MixinCursors(this.cursors))throw Error("baobab.mixin.cursor: invalid data (object, array or function).");if(n.Function(this.cursors)&&(this.cursors=this.cursors()),n.Array(this.cursors))this.cursors=this.cursors.map(function(r){return n.Cursor(r)?r:t.select(r)}),this.__getCursorData=function(){return{cursors:this.cursors.map(function(t){return t.get()})}}.bind(this),this.__type="array";else{for(var r in this.cursors)n.Cursor(this.cursors[r])||(this.cursors[r]=t.select(this.cursors[r]));this.__getCursorData=function(){var t={};for(r in this.cursors)t[r]=this.cursors[r].get();return{cursors:t}}.bind(this),this.__type="object"}}return this.__getCursorData()},componentDidMount:function(){"single"===this.__type?(this.__combination=new e("or",[this.cursor]),this.__combination.on("update",this.__updateHandler)):"array"===this.__type?(this.__combination=new e("or",this.cursors),this.__combination.on("update",this.__updateHandler)):"object"===this.__type&&(this.__combination=new e("or",Object.keys(this.cursors).map(function(t){return this.cursors[t]},this)),this.__combination.on("update",this.__updateHandler))},componentWillUnmount:function(){this.__combination&&this.__combination.release()}}].concat(t.options.mixins)}},cursor:function(t){return{mixins:[{getInitialState:function(){return this.cursor=t,this.__updateHandler=function(){this.setState({cursor:this.cursor.get()})}.bind(this),{cursor:this.cursor.get()}},componentDidMount:function(){this.cursor.on("update",this.__updateHandler)},componentWillUnmount:function(){this.cursor.off("update",this.__updateHandler)}}].concat(t.tree.options.mixins)}}}},{"./combination.js":5,"./type.js":10}],10:[function(t,r){var e=function(t){return Array.isArray(t)?"array":"object"==typeof t&&null!==t?"object":"string"==typeof t?"string":"number"==typeof t?"number":"boolean"==typeof t?"boolean":"function"==typeof t?"function":null===t?"null":void 0===t?"undefined":t instanceof Date?"date":"invalid"};e.Array=function(t){return Array.isArray(t)},e.Object=function(t){return!Array.isArray(t)&&"object"==typeof t&&null!==t},e.String=function(t){return"string"==typeof t},e.Number=function(t){return"number"==typeof t},e.Boolean=function(t){return"boolean"==typeof t},e.Function=function(t){return"function"==typeof t},e.Primitive=function(t){return"string"==typeof t||"number"==typeof t||"boolean"==typeof t},e.Date=function(t){return t instanceof Date},e.Step=function(t){var r=e(t),n=["null","undefined","invalid","date"];return-1===n.indexOf(r)},e.Path=function(t){var r=["object","string","number","function","undefined"];if(!e.Array(t))return r.indexOf(e(t))>=0;for(var n=0;n=0||e.Cursor(t)},e.MixinCursors=function(t){var r=["array","object","function"];return r.indexOf(e(t))>=0},e.ComplexPath=function(t){for(var r=["object","function"],n=0;n=0)return!0;return!1},r.exports=e},{}],11:[function(t,r){function e(t,r){var e=new Error("baobab.update: "+r+" at path /"+t.toString());return e.path=t,e}function n(t,r,n){n=n||{shiftReferences:!1};var a={};return function h(t,r,u,c){u=u||[];var f,l,p,d,y=u.join("λ");for(p in r)if(s[p])switch(d=r[p],a[y]=!0,p){case"$push":if(!i.Array(t))throw e(u,"using command $push to a non array");i.Array(d)?t.push.apply(t,d):t.push(d);break;case"$unshift":if(!i.Array(t))throw e(u,"using command $unshift to a non array");i.Array(d)?t.unshift.apply(t,d):t.unshift(d)}else if(l=y?y+"λ"+p:p,"$unset"in(r[p]||{}))a[l]=!0,i.Array(t)?n.shiftReferences?c[u[u.length-1]]=t.slice(0,+p).concat(t.slice(+p+1)):t.splice(p,1):delete t[p];else if("$set"in(r[p]||{}))d=r[p].$set,a[l]=!0,t[p]=d;else if("$apply"in(r[p]||{})||"$chain"in(r[p]||{})){if(f=r[p].$apply||r[p].$chain,"function"!=typeof f)throw e(u.concat(p),"using command $apply with a non function");a[l]=!0,t[p]=f.call(null,t[p])}else if("$merge"in(r[p]||{})){if(d=r[p].$merge,!i.Object(t[p]))throw e(u.concat(p),"using command $merge on a non-object");a[l]=!0,t[p]=o.shallowMerge(t[p],d)}else if(n.shiftReferences&&("$push"in(r[p]||{})||"$unshift"in(r[p]||{}))){if("$push"in(r[p]||{})){if(d=r[p].$push,!i.Array(t[p]))throw e(u.concat(p),"using command $push to a non array");t[p]=t[p].concat(d)}if("$unshift"in(r[p]||{})){if(d=r[p].$unshift,!i.Array(t[p]))throw e(u.concat(p),"using command $unshift to a non array");t[p]=(d instanceof Array?d:[d]).concat(t[p])}a[l]=!0}else"undefined"==typeof t[p]&&(t[p]={}),n.shiftReferences&&(t[p]=o.shallowClone(t[p])),h(t[p],r[p],u.concat(p),t)}(t,r),Object.keys(a).map(function(t){return t.split("λ")})}var o=t("./helpers.js"),i=t("./type.js"),s={};["$set","$push","$unshift","$apply","$merge"].forEach(function(t){s[t]=!0}),r.exports=n},{"./helpers.js":7,"./type.js":10}]},{},[2])(2)}); \ No newline at end of file +!function(t){if("object"==typeof exports&&"undefined"!=typeof module)module.exports=t();else if("function"==typeof define&&define.amd)define([],t);else{var r;r="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:this,r.Baobab=t()}}(function(){var t;return function r(t,e,n){function o(s,a){if(!e[s]){if(!t[s]){var u="function"==typeof require&&require;if(!a&&u)return u(s,!0);if(i)return i(s,!0);var h=new Error("Cannot find module '"+s+"'");throw h.code="MODULE_NOT_FOUND",h}var c=e[s]={exports:{}};t[s][0].call(c.exports,function(r){var e=t[s][1][r];return o(e?e:r)},c,c.exports,r,t,e,n)}return e[s].exports}for(var i="function"==typeof require&&require,s=0;sr;r++)n.push(t[r].handler);return n}var o={once:"boolean",scope:"object"},i=function(){this._enabled=!0,this._children=[],this._handlers={},this._handlersAll=[]};i.prototype.on=function(t,r,e){var n,s,a,u,h,c;if("function"==typeof r){for(h="string"==typeof t?[t]:t,n=0,s=h.length;n!==s;n+=1)if(u=h[n]){this._handlers[u]||(this._handlers[u]=[]),c={handler:r};for(a in e||{}){if(!o[a])throw new Error('The option "'+a+'" is not recognized by Emmett.');c[a]=e[a]}this._handlers[u].push(c)}}else if(t&&"object"==typeof t&&!Array.isArray(t))for(u in t)i.prototype.on.call(this,u,t[u],r);else{if("function"!=typeof t)throw new Error("Wrong arguments.");c={handler:t};for(a in e||{}){if(!o[a])throw new Error('The option "'+a+'" is not recognized by Emmett.');c[a]=e[a]}this._handlersAll.push(c)}return this},i.prototype.once=function(t,r,e){if("function"==typeof r)e=e||{},e.once=!0,this.on(t,r,e);else{if((!t||"object"!=typeof t||Array.isArray(t))&&"function"!=typeof t)throw new Error("Wrong arguments.");r=r||{},r.once=!0,this.on(t,r)}return this},i.prototype.off=function(t,r){var e,n,o,i,s,a,u,h="string"==typeof t?[t]:t;if(1===arguments.length&&"function"==typeof h){r=arguments[0];for(s in this._handlers){for(a=[],e=0,n=this._handlers[s].length;e!==n;e+=1)this._handlers[s][e].handler!==r&&a.push(this._handlers[s][e]);this._handlers[s]=a}for(a=[],e=0,n=this._handlersAll.length;e!==n;e+=1)this._handlersAll[e].handler!==r&&a.push(this._handlersAll[e]);this._handlersAll=a}else if(2===arguments.length)for(e=0,n=h.length;e!==n;e+=1){if(u=h[e],this._handlers[u]){for(a=[],o=0,i=this._handlers[u].length;o!==i;o+=1)this._handlers[u][o].handler!==r&&a.push(this._handlers[u][o]);this._handlers[u]=a}this._handlers[u]&&0===this._handlers[u].length&&delete this._handlers[u]}return this},i.prototype.unbindAll=function(){var t;this._handlersAll=[];for(t in this._handlers)delete this._handlers[t];return this},i.prototype.emit=function(t,r){var e,n,o,i,s,a,u,h,c,l,f="string"==typeof t?[t]:t;if(!this._enabled)return this;for(r=void 0===r?{}:r,e=0,n=f.length;e!==n;e+=1)if(l=f[e],c=(this._handlers[l]||[]).concat(this._handlersAll),c.length){for(u={type:l,data:r||{},target:this},a=[],o=0,i=c.length;o!==i;o+=1)(this._handlers[l]&&this._handlers[l].indexOf(c[o])>=0||this._handlersAll.indexOf(c[o])>=0)&&(c[o].handler.call("scope"in c[o]?c[o].scope:this,u),c[o].once&&a.push(c[o]));for(s=0;se;e++)if(t._children[e]===r){t._children.splice(e,1);break}}),this._children.push(r),r},i.prototype.listeners=function(t){var e,n,o,i=[];if(t)for(i=r(this._handlers[t]),n=0,o=this._children.length;o>n;n++)i=i.concat(this._children[n].listeners(t));else{i=r(this._handlersAll);for(e in this._handlers)i=i.concat(r(this._handlers[e]));for(n=0,o=this._children.length;o>n;n++)i=i.concat(this._children[n].listeners())}return i},i.prototype.kill=function(){if(this.emit("emmett:kill"),this.unbindAll(),this._handlers=null,this._handlersAll=null,this._enabled=!1,this._children)for(var t=0,r=this._children.length;r>t;t++)this._children[t].kill();this._children=null},i.prototype.disable=function(){return this._enabled=!1,this},i.prototype.enable=function(){return this._enabled=!0,this},i.version="2.1.2","undefined"!=typeof n?("undefined"!=typeof e&&e.exports&&(n=e.exports=i),n.Emitter=i):"function"==typeof t&&t.amd?t("emmett",[],function(){return i}):this.Emitter=i}).call(this)},{}],4:[function(t,r){function e(t){return t+"$"+(new Date).getTime()+(""+Math.random()).replace("0.","")}function n(t,r){function e(t){this[t]=function(){var r=this.root[t].apply(this.root,arguments);return r instanceof o?this:r}}if(arguments.length<1&&(t={}),!(this instanceof n))return new n(t,r);if(!l.Object(t)&&!l.Array(t))throw Error("Baobab: invalid data.");i.call(this),this.options=s.shallowMerge(c,r),this._transaction={},this._future=void 0,this._cursors={},this.data=s.deepClone(t),this.root=this.select([]),["get","set","unset","update"].forEach(e.bind(this)),this.mixin=h.baobab(this)}var o=t("./cursor.js"),i=t("emmett"),s=t("./helpers.js"),a=t("./update.js"),u=t("./merge.js"),h=t("./mixins.js"),c=t("../defaults.js"),l=t("./type.js");s.inherits(n,i),n.prototype.select=function(t){if(!t)throw Error("Baobab.select: invalid path.");if(arguments.length>1&&(t=s.arrayOf(arguments)),!l.Path(t))throw Error("Baobab.select: invalid path.");t=[].concat(t);var r,n=l.ComplexPath(t);n&&(r=s.solvePath(this.data,t));var i=t.map(function(t){return l.Function(t)?e("fn"):l.Object(t)?e("ob"):t}).join("λ");if(this._cursors[i])return this._cursors[i];var a=new o(this,t,r,i);return this._cursors[i]=a,a},n.prototype.stack=function(t){var r=this;if(!l.Object(t))throw Error("Baobab.update: wrong specification.");return this._transaction=u(t,this._transaction),this.options.autoCommit?this.options.asynchronous?(this._future||(this._future=setTimeout(r.commit.bind(r,null),0)),this):this.commit():this},n.prototype.commit=function(){var t=a(this.data,this._transaction,this.options);return this.data=t.data,this._transaction={},this._future&&(this._future=clearTimeout(this._future)),this.emit("update",{log:t.log}),this},n.prototype.release=function(){delete this.data,delete this._transaction;for(var t in this._cursors)this._cursors[t].release();delete this._cursors,this.kill()},n.prototype.toJSON=function(){return this.get()},r.exports=n},{"../defaults.js":1,"./cursor.js":6,"./helpers.js":7,"./merge.js":8,"./mixins.js":9,"./type.js":10,"./update.js":11,emmett:3}],5:[function(t,r){function e(t,r){r.on("update",t.cursorListener),t.tree.off("update",t.treeListener),t.tree.on("update",t.treeListener)}function n(t){var r=this;if(arguments.length<2)throw Error("baobab.Combination: not enough arguments.");var n=arguments[1],o=s.arrayOf(arguments).slice(2);if(n instanceof Array&&(o=n.slice(1),n=n[0]),!a.Cursor(n))throw Error("baobab.Combination: argument should be a cursor.");if("or"!==t&&"and"!==t)throw Error("baobab.Combination: invalid operator.");i.call(this),this.cursors=[n],this.operators=[],this.tree=n.tree,this.updates=new Array(this.cursors.length),this.cursorListener=function(){r.updates[r.cursors.indexOf(this)]=!0},this.treeListener=function(){var t,e,n=r.updates[0];for(t=1,e=r.cursors.length;e>t;t++)n="or"===r.operators[t-1]?n||r.updates[t]:n&&r.updates[t];n&&r.emit("update"),r.updates=new Array(r.cursors.length)},this.bound=!1;var u=(this.on,this.once,function(){r.bound||(r.bound=!0,r.cursors.forEach(function(t){e(r,t)}))});this.on=s.before(u,this.on.bind(this)),this.once=s.before(u,this.once.bind(this)),o.forEach(function(r){this[t](r)},this)}function o(t){n.prototype[t]=function(r){if(!a.Cursor(r))throw this.release(),Error("baobab.Combination."+t+": argument should be a cursor.");if(~this.cursors.indexOf(r))throw this.release(),Error("baobab.Combination."+t+": cursor already in combination.");return this.cursors.push(r),this.operators.push(t),this.updates.length++,this.bound&&e(this,r),this}}var i=t("emmett"),s=t("./helpers.js"),a=t("./type.js");s.inherits(n,i),o("or"),o("and"),n.prototype.release=function(){this.cursors.forEach(function(t){t.off("update",this.cursorListener)},this),this.tree.off("update",this.treeListener),this.cursors=null,this.operators=null,this.tree=null,this.updates=null,this.kill()},r.exports=n},{"./helpers.js":7,"./type.js":10,emmett:3}],6:[function(t,r){function e(t,r,e,o){var a=this;n.call(this),r=r||[],this.tree=t,this.path=r,this.hash=o,this.complexPath=!!e,this.solvedPath=this.complexPath?e:this.path,this.relevant=void 0!==this.get(),this.updateHandler=function(t){var r,e,n,o,i,u,h=t.data.log,c=!1;if(a.complexPath&&(a.solvedPath=s.solvePath(a.tree.data,a.path)),!a.path.length)return a.emit("update");t:for(i=0,n=h.length;n>i;i++)for(r=h[i],u=0,o=r.length;o>u&&(e=r[u],e===""+a.solvedPath[u]);u++)if(u+1===o||u+1===a.solvedPath.length){c=!0;break t}var l=void 0!==a.get();a.relevant?l&&c?a.emit("update"):l||(a.emit("irrelevant"),a.relevant=!1):l&&c&&(a.emit("relevant"),a.emit("update"),a.relevant=!0)},this.mixin=i.cursor(this);var u=!1,h=function(){u||(u=!0,a.tree.on("update",a.updateHandler))};this.on=s.before(h,this.on.bind(this)),this.once=s.before(h,this.once.bind(this))}var n=t("emmett"),o=t("./combination.js"),i=t("./mixins.js"),s=t("./helpers.js"),a=t("./type.js");s.inherits(e,n),e.prototype.isRoot=function(){return!this.path.length},e.prototype.isLeaf=function(){return a.Primitive(this.get())},e.prototype.isBranch=function(){return!this.isLeaf()&&!this.isRoot()},e.prototype.root=function(){return this.tree.root()},e.prototype.select=function(t){if(arguments.length>1&&(t=s.arrayOf(arguments)),!a.Path(t))throw Error("baobab.Cursor.select: invalid path.");return this.tree.select(this.path.concat(t))},e.prototype.up=function(){return this.solvedPath&&this.solvedPath.length?this.tree.select(this.path.slice(0,-1)):null},e.prototype.left=function(){var t=+this.solvedPath[this.solvedPath.length-1];if(isNaN(t))throw Error("baobab.Cursor.left: cannot go left on a non-list type.");return t?this.tree.select(this.solvedPath.slice(0,-1).concat(t-1)):null},e.prototype.leftmost=function(){var t=+this.solvedPath[this.solvedPath.length-1];if(isNaN(t))throw Error("baobab.Cursor.leftmost: cannot go left on a non-list type.");return this.tree.select(this.solvedPath.slice(0,-1).concat(0))},e.prototype.right=function(){var t=+this.solvedPath[this.solvedPath.length-1];if(isNaN(t))throw Error("baobab.Cursor.right: cannot go right on a non-list type.");return t+1===this.up().get().length?null:this.tree.select(this.solvedPath.slice(0,-1).concat(t+1))},e.prototype.rightmost=function(){var t=+this.solvedPath[this.solvedPath.length-1];if(isNaN(t))throw Error("baobab.Cursor.right: cannot go right on a non-list type.");var r=this.up().get();return this.tree.select(this.solvedPath.slice(0,-1).concat(r.length-1))},e.prototype.down=function(){+this.solvedPath[this.solvedPath.length-1];return this.get()instanceof Array?this.tree.select(this.solvedPath.concat(0)):null},e.prototype.get=function(t){arguments.length>1&&(t=s.arrayOf(arguments));var r=this.solvedPath.concat((a.String(t)||a.Number(t)?[t]:t)||[]);return s.getIn(this.tree.data,r)},e.prototype.set=function(t,r){if(arguments.length<2)throw Error("baobab.Cursor.set: expecting at least key/value.");var e=this.get();if("object"!=typeof e)throw Error("baobab.Cursor.set: trying to set key to a non-object.");var n={};if(a.Array(t)){var o=s.solvePath(e,t);if(!o)throw Error("baobab.Cursor.set: could not solve dynamic path.");n=s.pathObject(o,{$set:r})}else n[t]={$set:r};return this.update(n)},e.prototype.edit=function(t){return this.update({$set:t})},e.prototype.unset=function(t){if(!t&&0!==t)throw Error("baobab.Cursor.unset: expects a valid key to unset.");if("object"!=typeof this.get())throw Error("baobab.Cursor.set: trying to set key to a non-object.");var r={};return r[t]={$unset:!0},this.update(r)},e.prototype.remove=function(){if(this.isRoot())throw Error("baobab.Cursor.remove: cannot remove root node.");return this.update({$unset:!0})},e.prototype.apply=function(t){if("function"!=typeof t)throw Error("baobab.Cursor.apply: argument is not a function.");return this.update({$apply:t})},e.prototype.chain=function(t){if("function"!=typeof t)throw Error("baobab.Cursor.chain: argument is not a function.");return this.update({$chain:t})},e.prototype.push=function(t){if(!(this.get()instanceof Array))throw Error("baobab.Cursor.push: trying to push to non-array value.");return this.update(arguments.length>1?{$push:s.arrayOf(arguments)}:{$push:t})},e.prototype.unshift=function(t){if(!(this.get()instanceof Array))throw Error("baobab.Cursor.push: trying to push to non-array value.");return this.update(arguments.length>1?{$unshift:s.arrayOf(arguments)}:{$unshift:t})},e.prototype.merge=function(t){if(!a.Object(t))throw Error("baobab.Cursor.merge: trying to merge a non-object.");if(!a.Object(this.get()))throw Error("baobab.Cursor.merge: trying to merge into a non-object.");this.update({$merge:t})},e.prototype.update=function(t){return this.tree.stack(s.pathObject(this.solvedPath,t)),this},e.prototype.or=function(t){return new o("or",this,t)},e.prototype.and=function(t){return new o("and",this,t)},e.prototype.release=function(){this.tree.off("update",this.updateHandler),this.hash&&delete this.tree._cursors[this.hash],delete this.tree,delete this.path,delete this.solvedPath,this.kill()},e.prototype.toJSON=function(){return this.get()},a.Cursor=function(t){return t instanceof e},r.exports=e},{"./combination.js":5,"./helpers.js":7,"./mixins.js":9,"./type.js":10,emmett:3}],7:[function(t,r){function e(t){return Array.prototype.slice.call(t)}function n(t,r){return function(){t(),r.apply(null,arguments)}}function o(t,r){var e,n={};for(e in t)n[e]=t[e];for(e in r)n[e]=r[e];return n}function i(t){var r=t.source,e="";return t.global&&(e+="g"),t.multiline&&(e+="m"),t.ignoreCase&&(e+="i"),t.sticky&&(e+="y"),t.unicode&&(e+="u"),new RegExp(r,e)}function s(t,r){if(!r||"object"!=typeof r||r instanceof Error||r instanceof ArrayBuffer)return r;if(g.Array(r)){if(t){var e,n,o=[];for(e=0,n=r.length;n>e;e++)o.push(v(r[e]));return o}return r.slice(0)}if(g.Date(r))return new Date(r.getTime());if(r instanceof RegExp)return i(r);if(g.Object(r)){var s,a={};r.constructor&&r.constructor!==Object&&(a=Object.create(r.constructor.prototype));for(s in r)r.hasOwnProperty(s)&&(a[s]=t?v(r[s]):r[s]);return a}return r}function a(t,r){return function(e){return r(t(e))}}function u(t,r){var e,n;for(e=0,n=t.length;n>e;e++)if(r(t[e]))return t[e]}function h(t,r){var e,n;for(e=0,n=t.length;n>e;e++)if(r(t[e]))return e;return-1}function c(t,r){var e,n=!0;if(!t)return!1;for(e in r)if(g.Object(r[e]))n=n&&c(t[e],r[e]);else if(g.Array(r[e]))n=n&&!!~r[e].indexOf(t[e]);else if(t[e]!==r[e])return!1;return n}function l(t,r){return u(t,function(t){return c(t,r)})}function f(t,r){return h(t,function(t){return c(t,r)})}function p(t,r){r=r||[];var e,n,o=t;for(e=0,n=r.length;n>e;e++){if(!o)return;if("function"==typeof r[e]){if(!g.Array(o))return;o=u(o,r[e])}else if("object"==typeof r[e]){if(!g.Array(o))return;o=l(o,r[e])}else o=o[r[e]]}return o}function d(t,r){var e,n,o,i=[],s=t;for(n=0,o=r.length;o>n;n++){if(!s)return null;if("function"==typeof r[n]){if(!g.Array(s))return;e=h(s,r[n]),i.push(e),s=s[e]}else if("object"==typeof r[n]){if(!g.Array(s))return;e=f(s,r[n]),i.push(e),s=s[e]}else i.push(r[n]),s=s[r[n]]||{}}return i}function b(t,r){var e,n=t.length,o={},i=o;for(n||(o=r),e=0;n>e;e++)i[t[e]]=e+1===n?r:{},i=i[t[e]];return o}function y(t,r){t.super_=r;var e=function(){};e.prototype=r.prototype,t.prototype=new e,t.prototype.constructor=t}var g=t("./type.js"),m=s.bind(null,!1),v=s.bind(null,!0);r.exports={arrayOf:e,before:n,deepClone:v,shallowClone:m,shallowMerge:o,compose:a,getIn:p,inherits:y,pathObject:b,solvePath:d}},{"./type.js":10}],8:[function(t,r){function e(t,r,e){s.forEach(function(r){e!==r&&delete t[r]}),t[e]=r[e]}function n(t,r){var a,u=o.shallowClone(r||{});s.forEach(function(r){t[r]&&e(u,t,r)}),t.$chain&&(s.slice(0,-1).forEach(function(t){delete u[t]}),u.$apply=u.$apply?o.compose(u.$apply,t.$chain):t.$chain),t.$push&&u.$push?u.$push=i.Array(u.$push)?u.$push.concat(t.$push):[u.$push].concat(t.$push):t.$push&&(u.$push=t.$push),t.$unshift&&u.$unshift?u.$unshift=i.Array(t.$unshift)?t.$unshift.concat(u.$unshift):[t.$unshift].concat(u.$unshift):t.$unshift&&(u.$unshift=t.$unshift);for(a in t)i.Object(t[a])?u[a]=n(t[a],u[a]):"$"!==a[0]&&(u[a]=t[a]);return u}var o=t("./helpers.js"),i=t("./type.js"),s=["$unset","$set","$merge","$apply"];r.exports=n},{"./helpers.js":7,"./type.js":10}],9:[function(t,r){var e=t("./combination.js"),n=t("./type.js");r.exports={baobab:function(t){return{mixins:[{getInitialState:function(){if(this.tree=t,!this.cursor&&!this.cursors)return{};if(this.cursor&&this.cursors)throw Error("baobab.mixin: you cannot have both `component.cursor` and `component.cursors`. Please make up your mind.");if(this.__type=null,this.__updateHandler=function(){this.setState(this.__getCursorData())}.bind(this),this.cursor){if(!n.MixinCursor(this.cursor))throw Error("baobab.mixin.cursor: invalid data (cursor, string, array or function).");n.Function(this.cursor)&&(this.cursor=this.cursor()),n.Cursor(this.cursor)||(this.cursor=t.select(this.cursor)),this.__getCursorData=function(){return{cursor:this.cursor.get()}}.bind(this),this.__type="single"}else if(this.cursors){if(!n.MixinCursors(this.cursors))throw Error("baobab.mixin.cursor: invalid data (object, array or function).");if(n.Function(this.cursors)&&(this.cursors=this.cursors()),n.Array(this.cursors))this.cursors=this.cursors.map(function(r){return n.Cursor(r)?r:t.select(r)}),this.__getCursorData=function(){return{cursors:this.cursors.map(function(t){return t.get()})}}.bind(this),this.__type="array";else{for(var r in this.cursors)n.Cursor(this.cursors[r])||(this.cursors[r]=t.select(this.cursors[r]));this.__getCursorData=function(){var t={};for(r in this.cursors)t[r]=this.cursors[r].get();return{cursors:t}}.bind(this),this.__type="object"}}return this.__getCursorData()},componentDidMount:function(){"single"===this.__type?(this.__combination=new e("or",[this.cursor]),this.__combination.on("update",this.__updateHandler)):"array"===this.__type?(this.__combination=new e("or",this.cursors),this.__combination.on("update",this.__updateHandler)):"object"===this.__type&&(this.__combination=new e("or",Object.keys(this.cursors).map(function(t){return this.cursors[t]},this)),this.__combination.on("update",this.__updateHandler))},componentWillUnmount:function(){this.__combination&&this.__combination.release()}}].concat(t.options.mixins)}},cursor:function(t){return{mixins:[{getInitialState:function(){return this.cursor=t,this.__updateHandler=function(){this.setState({cursor:this.cursor.get()})}.bind(this),{cursor:this.cursor.get()}},componentDidMount:function(){this.cursor.on("update",this.__updateHandler)},componentWillUnmount:function(){this.cursor.off("update",this.__updateHandler)}}].concat(t.tree.options.mixins)}}}},{"./combination.js":5,"./type.js":10}],10:[function(t,r){var e=function(t){return Array.isArray(t)?"array":"object"==typeof t&&null!==t?"object":"string"==typeof t?"string":"number"==typeof t?"number":"boolean"==typeof t?"boolean":"function"==typeof t?"function":null===t?"null":void 0===t?"undefined":t instanceof Date?"date":"invalid"};e.Array=function(t){return Array.isArray(t)},e.Object=function(t){return!Array.isArray(t)&&"object"==typeof t&&null!==t},e.String=function(t){return"string"==typeof t},e.Number=function(t){return"number"==typeof t},e.Boolean=function(t){return"boolean"==typeof t},e.Function=function(t){return"function"==typeof t},e.Primitive=function(t){return"string"==typeof t||"number"==typeof t||"boolean"==typeof t},e.Date=function(t){return t instanceof Date},e.Step=function(t){var r=e(t),n=["null","undefined","invalid","date"];return-1===n.indexOf(r)},e.Path=function(t){var r=["object","string","number","function","undefined"];if(!e.Array(t))return r.indexOf(e(t))>=0;for(var n=0;n=0||e.Cursor(t)},e.MixinCursors=function(t){var r=["array","object","function"];return r.indexOf(e(t))>=0},e.ComplexPath=function(t){for(var r=["object","function"],n=0;n=0)return!0;return!1},r.exports=e},{}],11:[function(t,r){function e(t,r){var e=new Error("baobab.update: "+r+" at path /"+t.slice(1).toString());return e.path=t,e}var n=t("./helpers.js"),o=t("./type.js");r.exports=function(t,r,i){if(i=i||{},!o.Object(t)&&!o.Array(t))throw Error("baobab.update: invalid target.");var s={};t={root:n.shallowClone(t)};var a=function(t,r,i,u){i=i||["root"];var h,c,l,f=i.join("λ"),p=i[i.length-1],d=Object.keys(r).some(function(t){return!!~["$unset","$set","$apply","$merge","$push","$unshift"].indexOf(t)});if(d){s[f]=!0;for(c in r){if("$unset"===c){var b=i[i.length-2];o.Array(t)?u[b]=t.slice(0,+p).concat(t.slice(+p+1)):(u[b]=n.shallowClone(t),delete u[b][p]);break}if("$set"===c){l=r.$set,t[p]=l;break}if("$apply"===c){if(h=r.$apply,"function"!=typeof h)throw e(i,"using command $apply with a non function");t[p]=h.call(null,t[p]);break}if("$merge"===c){if(l=r.$merge,!o.Object(t[p])||!o.Object(l))throw e(i,"using command $merge with a non object");t[p]=n.shallowMerge(t[p],l);break}if("$push"===c){if(l=r.$push,!o.Array(t[p]))throw e(i,"using command $push to a non array");t[p]=t[p].concat(l)}if("$unshift"===c){if(l=r.$unshift,!o.Array(t[p]))throw e(i,"using command $unshift to a non array");t[p]=[].concat(l).concat(t[p])}}}else for(c in r)t[p][c]="undefined"==typeof t[p][c]?{}:n.shallowClone(t[p][c]),a(t[p],r[c],i.concat(c),t)};return a(t,r),{data:t.root,log:Object.keys(s).map(function(t){return t.split("λ").slice(1)})}}},{"./helpers.js":7,"./type.js":10}]},{},[2])(2)}); \ No newline at end of file diff --git a/defaults.js b/defaults.js index eb775bc..fe264b8 100644 --- a/defaults.js +++ b/defaults.js @@ -14,9 +14,6 @@ module.exports = { // Collection of react mixins to merge with the tree's ones mixins: [], - // Should the tree shift its internal reference when applying mutations? - shiftReferences: false, - // Validation specifications validate: null }; diff --git a/src/baobab.js b/src/baobab.js index 237b018..f7cbdad 100644 --- a/src/baobab.js +++ b/src/baobab.js @@ -133,12 +133,9 @@ Baobab.prototype.stack = function(spec) { Baobab.prototype.commit = function() { var self = this; - // Shifting root reference - if (this.options.shiftReferences) - this.data = helpers.shallowClone(this.data); - // Applying modification (mutation) - var log = update(this.data, this._transaction, this.options); + var result = update(this.data, this._transaction, this.options); + this.data = result.data; // Resetting this._transaction = {}; @@ -148,7 +145,7 @@ Baobab.prototype.commit = function() { // Baobab-level update event this.emit('update', { - log: log + log: result.log }); return this; diff --git a/src/merge.js b/src/merge.js index acbede9..feaa55b 100644 --- a/src/merge.js +++ b/src/merge.js @@ -10,6 +10,7 @@ var helpers = require('./helpers.js'), // Helpers var COMMANDS = ['$unset', '$set', '$merge', '$apply']; +// TODO: delete every keys function only(o, n, keep) { COMMANDS.forEach(function(c) { if (keep !== c) @@ -20,6 +21,7 @@ function only(o, n, keep) { } // Main function +// TODO: use a better way than shallow cloning b? function merge(a, b) { var o = helpers.shallowClone(b || {}), k, diff --git a/src/update.js b/src/update.js index 1625b8e..4a26fd3 100644 --- a/src/update.js +++ b/src/update.js @@ -8,166 +8,140 @@ var helpers = require('./helpers.js'), type = require('./type.js'); -var COMMANDS = {}; -[ - '$set', - '$push', - '$unshift', - '$apply', - '$merge' -].forEach(function(c) { - COMMANDS[c] = true; -}); - // Helpers function makeError(path, message) { var e = new Error('baobab.update: ' + message + ' at path /' + - path.toString()); + path.slice(1).toString()); e.path = path; return e; } -// Core function -function update(target, spec, opts) { - opts = opts || {shiftReferences: false}; +module.exports = function(data, spec, opts) { + opts = opts || {}; + + if (!type.Object(data) && !type.Array(data)) + throw Error('baobab.update: invalid target.'); + var log = {}; - // Closure mutating the internal object - (function mutator(o, spec, path, parent) { - path = path || []; + // Shifting root + data = {root: helpers.shallowClone(data)}; + + // Closure performing the updates themselves + var mutator = function(o, spec, path, parent) { + path = path || ['root']; var hash = path.join('λ'), + lastKey = path[path.length - 1], fn, - h, k, v; - for (k in spec) { - if (COMMANDS[k]) { - v = spec[k]; - - // Logging update - log[hash] = true; - - // TODO: this could be before in the recursion - // Applying - switch (k) { - case '$push': - if (!type.Array(o)) - throw makeError(path, 'using command $push to a non array'); - - if (!type.Array(v)) - o.push(v); - else - o.push.apply(o, v); - break; - case '$unshift': - if (!type.Array(o)) - throw makeError(path, 'using command $unshift to a non array'); - - if (!type.Array(v)) - o.unshift(v); - else - o.unshift.apply(o, v); - break; - } - } - else { - h = hash ? hash + 'λ' + k : k; + var leafLevel = Object.keys(spec).some(function(k) { + return !!~['$unset', '$set', '$apply', '$merge', '$push', '$unshift'].indexOf(k); + }); + + if (leafLevel) { + log[hash] = true; - if ('$unset' in (spec[k] || {})) { + for (k in spec) { - // Logging update - log[h] = true; + // $unset + if (k === '$unset') { + var olderKey = path[path.length - 2]; if (type.Array(o)) { - if (!opts.shiftReferences) - o.splice(k, 1); - else - parent[path[path.length - 1]] = o.slice(0, +k).concat(o.slice(+k + 1)); + parent[olderKey] = o.slice(0, +lastKey).concat(o.slice(+lastKey + 1)); } else { - delete o[k]; + parent[olderKey] = helpers.shallowClone(o); + delete parent[olderKey][lastKey]; } + + break; } - else if ('$set' in (spec[k] || {})) { - v = spec[k].$set; - // Logging update - log[h] = true; - o[k] = v; + // $set + if (k === '$set') { + v = spec.$set; + + o[lastKey] = v; + break; } - else if ('$apply' in (spec[k] || {}) || '$chain' in (spec[k] || {})) { - // TODO: this should not happen likewise. - fn = spec[k].$apply || spec[k].$chain; + // $apply + if (k === '$apply') { + fn = spec.$apply; if (typeof fn !== 'function') - throw makeError(path.concat(k), 'using command $apply with a non function'); + throw makeError(path, 'using command $apply with a non function'); - // Logging update - log[h] = true; - o[k] = fn.call(null, o[k]); + o[lastKey] = fn.call(null, o[lastKey]); + break; } - else if ('$merge' in (spec[k] || {})) { - v = spec[k].$merge; - if (!type.Object(o[k])) - throw makeError(path.concat(k), 'using command $merge on a non-object'); + // $merge + if (k === '$merge') { + v = spec.$merge; + + if (!type.Object(o[lastKey]) || !type.Object(v)) + throw makeError(path, 'using command $merge with a non object'); - // Logging update - log[h] = true; - o[k] = helpers.shallowMerge(o[k], v); + o[lastKey] = helpers.shallowMerge(o[lastKey], v); + break; } - else if (opts.shiftReferences && - ('$push' in (spec[k] || {}) || - '$unshift' in (spec[k] || {}))) { - if ('$push' in (spec[k] || {})) { - v = spec[k].$push; - - if (!type.Array(o[k])) - throw makeError(path.concat(k), 'using command $push to a non array'); - o[k] = o[k].concat(v); - } - if ('$unshift' in (spec[k] || {})) { - v = spec[k].$unshift; - if (!type.Array(o[k])) - throw makeError(path.concat(k), 'using command $unshift to a non array'); - o[k] = (v instanceof Array ? v : [v]).concat(o[k]); - } + // $push + if (k === '$push') { + v = spec.$push; + + if (!type.Array(o[lastKey])) + throw makeError(path, 'using command $push to a non array'); - // Logging update - log[h] = true; + o[lastKey] = o[lastKey].concat(v); } - else { - - // If nested object does not exist, we create it - if (typeof o[k] === 'undefined') - o[k] = {}; - - // Shifting reference - if (opts.shiftReferences) - o[k] = helpers.shallowClone(o[k]); - - // Recur - // TODO: fix this horrendous behaviour. - mutator( - o[k], - spec[k], - path.concat(k), - o - ); + + // $unshift + if (k === '$unshift') { + v = spec.$unshift; + + if (!type.Array(o[lastKey])) + throw makeError(path, 'using command $unshift to a non array'); + + o[lastKey] = [].concat(v).concat(o[lastKey]); } } } - })(target, spec); + else { + for (k in spec) { + + // If nested object does not exist, we create it + if (typeof o[lastKey][k] === 'undefined') + o[lastKey][k] = {}; + else + o[lastKey][k] = helpers.shallowClone(o[lastKey][k]); + + // Recur + mutator( + o[lastKey], + spec[k], + path.concat(k), + o + ); + } + } + }; - return Object.keys(log).map(function(hash) { - return hash.split('λ'); - }); -} + mutator(data, spec); + + // Returning data and path log + return { + data: data.root, -// Exporting -module.exports = update; + // SHIFT LOG + log: Object.keys(log).map(function(hash) { + return hash.split('λ').slice(1); + }) + }; +}; diff --git a/test/suites/baobab.js b/test/suites/baobab.js index f1ff8ed..514565c 100644 --- a/test/suites/baobab.js +++ b/test/suites/baobab.js @@ -158,6 +158,31 @@ describe('Baobab API', function() { assert(baobab.data === undefined); }); + + it('the tree should shift references on updates.', function() { + var list = [1], + baobab = new Baobab({list: list}, {asynchronous: false}); + + baobab.select('list').push(2); + assert.deepEqual(baobab.get('list'), [1, 2]); + assert(list !== baobab.get('list')); + }); + + it('the tree should also shift parent references.', function() { + var shiftingTree = new Baobab({root: {admin: {items: [1], other: [2]}}}, {asynchronous: false}); + + var shiftingOriginal = shiftingTree.get(); + + shiftingTree.select('root', 'admin', 'items').push(2); + + assert.deepEqual(shiftingTree.get('root', 'admin', 'items'), [1, 2]); + + assert(shiftingTree.get() !== shiftingOriginal); + assert(shiftingTree.get().root !== shiftingOriginal.root); + assert(shiftingTree.get().root.admin !== shiftingOriginal.root.admin); + assert(shiftingTree.get().root.admin.items !== shiftingOriginal.root.admin.items); + assert(shiftingTree.get().root.admin.other === shiftingOriginal.root.admin.other); + }); }); describe('Options', function() { @@ -180,41 +205,5 @@ describe('Baobab API', function() { }, 0); }, 0); }); - - it('should be possible to tell the tree to shift references on updates.', function() { - var list = [1], - baobab = new Baobab({list: list}, {shiftReferences: true, asynchronous: false}); - - baobab.select('list').push(2); - assert.deepEqual(baobab.get('list'), [1, 2]); - assert(list !== baobab.get('list')); - }); - - // TODO: rehabilitate this test when further updates are made - // it('should also shift parent references.', function() { - // var tree = new Baobab({root: {admin: {items: [1], other: [2]}}}, {asynchronous: false}), - // shiftingTree = new Baobab({root: {admin: {items: [1], other: [2]}}}, {shiftReferences: true, asynchronous: false}); - - // var original = tree.reference(), - // shiftingOriginal = shiftingTree.reference(); - - // tree.select('root', 'admin', 'items').push(2); - // shiftingTree.select('root', 'admin', 'items').push(2); - - // assert.deepEqual(tree.reference('root', 'admin', 'items'), [1, 2]); - // assert.deepEqual(shiftingTree.reference('root', 'admin', 'items'), [1, 2]); - - // assert(tree.reference() === original); - // assert(tree.reference().root === original.root); - // assert(tree.reference().root.admin === original.root.admin); - // assert(tree.reference().root.admin.items === original.root.admin.items); - // assert(tree.reference().root.admin.other === original.root.admin.other); - - // assert(shiftingTree.reference() !== shiftingOriginal); - // assert(shiftingTree.reference().root !== shiftingOriginal.root); - // assert(shiftingTree.reference().root.admin !== shiftingOriginal.root.admin); - // assert(shiftingTree.reference().root.admin.items !== shiftingOriginal.root.admin.items); - // assert(shiftingTree.reference().root.admin.other === shiftingOriginal.root.admin.other); - // }); }); }); diff --git a/test/suites/helpers.js b/test/suites/helpers.js index 6931299..43dd89e 100644 --- a/test/suites/helpers.js +++ b/test/suites/helpers.js @@ -121,8 +121,7 @@ describe('Helpers', function() { it('should be possible to set nested values.', function() { var o1 = {hello: {world: 'one'}}, - o2 = clone(o1); - update(o2, {hello: {world: {$set: 'two'}}}); + o2 = update(o1, {hello: {world: {$set: 'two'}}}).data; assert.deepEqual(o1, {hello: {world: 'one'}}); assert.deepEqual(o2, {hello: {world: 'two'}}); @@ -130,8 +129,7 @@ describe('Helpers', function() { it('should be possible to push to nested values.', function() { var o1 = {colors: ['orange']}, - o2 = clone(o1); - update(o2, {colors: {$push: 'blue'}}); + o2 = update(o1, {colors: {$push: 'blue'}}).data; assert.deepEqual(o1, {colors: ['orange']}); assert.deepEqual(o2, {colors: ['orange', 'blue']}); @@ -139,8 +137,7 @@ describe('Helpers', function() { it('should be possible to unshift to nested values.', function() { var o1 = {colors: ['orange']}, - o2 = clone(o1); - update(o2, {colors: {$unshift: 'blue'}}); + o2 = update(o1, {colors: {$unshift: 'blue'}}).data; assert.deepEqual(o1, {colors: ['orange']}); assert.deepEqual(o2, {colors: ['blue', 'orange']}); @@ -148,15 +145,13 @@ describe('Helpers', function() { it('should be possible to append to nested values.', function() { var o1 = {colors: ['orange']}, - o2 = clone(o1); - update(o2, {colors: {$push: ['blue', 'purple']}}); + o2 = update(o1, {colors: {$push: ['blue', 'purple']}}).data; assert.deepEqual(o1, {colors: ['orange']}); assert.deepEqual(o2, {colors: ['orange', 'blue', 'purple']}); var o3 = {colors: ['orange']}, - o4 = clone(o1); - update(o4, {colors: {$push: 'blue'}}); + o4 = update(o3, {colors: {$push: 'blue'}}).data; assert.deepEqual(o3, {colors: ['orange']}); assert.deepEqual(o4, {colors: ['orange', 'blue']}); @@ -164,15 +159,13 @@ describe('Helpers', function() { it('should be possible to prepend to nested values.', function() { var o1 = {colors: ['orange']}, - o2 = clone(o1); - update(o2, {colors: {$unshift: ['blue', 'purple']}}); + o2 = update(o1, {colors: {$unshift: ['blue', 'purple']}}).data; assert.deepEqual(o1, {colors: ['orange']}); assert.deepEqual(o2, {colors: ['blue', 'purple', 'orange']}); var o3 = {colors: ['orange']}, - o4 = clone(o1); - update(o4, {colors: {$unshift: 'blue'}}); + o4 = update(o3, {colors: {$unshift: 'blue'}}).data; assert.deepEqual(o3, {colors: ['orange']}); assert.deepEqual(o4, {colors: ['blue', 'orange']}); @@ -180,24 +173,22 @@ describe('Helpers', function() { it('should be possible to apply a function to nested values.', function() { var o1 = {number: 10}, - o2 = clone(o1); - update(o2, {number: {$apply: function(n) { return n * 2; }}}); + o2 = update(o1, {number: {$apply: function(n) { return n * 2; }}}).data; assert.deepEqual(o1, {number: 10}); assert.deepEqual(o2, {number: 20}); }); it('should be possible to shallowly merge objects.', function() { - var o = {hey: {one: 1, two: 2}}; - update(o, {hey: {$merge: {three: 3, two: 4}}}); + var o1 = {hey: {one: 1, two: 2}}, + o2 = update(o1, {hey: {$merge: {three: 3, two: 4}}}).data; - assert.deepEqual(o, {hey: {one: 1, two: 4, three: 3}}); + assert.deepEqual(o2, {hey: {one: 1, two: 4, three: 3}}); }); it('should be possible to unset values.', function() { var o1 = {one: 1, two: 2}, - o2 = clone(o1); - update(o2, {one: {$unset: true}}); + o2 = update(o1, {one: {$unset: true}}).data; assert.deepEqual(o1, {one: 1, two: 2}); assert.deepEqual(o2, {two: 2}); @@ -205,8 +196,7 @@ describe('Helpers', function() { it('should be possible to unset values in an array', function() { var o1 = {list: [1, 2, 3]}, - o2 = clone(o1); - update(o2, {list: {1: {$unset: true}}}); + o2 = update(o1, {list: {1: {$unset: true}}}).data; assert.deepEqual(o1, {list: [1, 2, 3]}); assert.deepEqual(o2, {list: [1, 3]}); From 7c7b0c327666f7b0ea1b16abf018eba5e15ef361 Mon Sep 17 00:00:00 2001 From: Yomguithereal Date: Tue, 31 Mar 2015 17:41:35 +0200 Subject: [PATCH 14/73] Fix #137 - reorganizing unit tests --- test/suites/baobab.js | 109 +++------- test/suites/cursor.js | 472 ++++++++++++++++++++++++----------------- test/suites/helpers.js | 4 +- test/suites/mixins.js | 2 +- 4 files changed, 302 insertions(+), 285 deletions(-) diff --git a/test/suites/baobab.js b/test/suites/baobab.js index 514565c..6223552 100644 --- a/test/suites/baobab.js +++ b/test/suites/baobab.js @@ -14,68 +14,49 @@ describe('Baobab API', function() { describe('Basics', function() { var baobab = new Baobab(state); - it('should be possible to retrieve full data.', function() { - var data = baobab.get(); - assert.deepEqual(data, state); - }); - - it('should be possible to retrieve nested data.', function() { - var colors = baobab.get(['one', 'subtwo', 'colors']); - assert.deepEqual(colors, state.one.subtwo.colors); - - // Polymorphism - var primitive = baobab.get('primitive'); - assert.strictEqual(primitive, 3); + it('should throw an error when trying to instantiate an baobab with incorrect data.', function() { + assert.throws(function() { + new Baobab(undefined); + }, /invalid data/); }); - it('should be possible to get data from both maps and lists.', function() { - var yellow = baobab.get(['one', 'subtwo', 'colors', 1]); + it('should be possible to instantiate without the "new" keyword.', function() { + var special = Baobab(state); - assert.strictEqual(yellow, 'yellow'); + assert(special.get('two'), baobab.get('two')); }); + }); - it('should return undefined when data is not to be found through path.', function() { - var inexistant = baobab.get(['no']); - assert.strictEqual(inexistant, undefined); + describe('Selection', function() { + var baobab = new Baobab(state); - // Nesting - var nestedInexistant = baobab.get(['no', 'no']); - assert.strictEqual(nestedInexistant, undefined); + it('selecting data in the baobab should return a cursor.', function() { + assert(baobab.select(['one']) instanceof Cursor); }); - it('should be possible to retrieve items with a function in path.', function() { - var yellow = baobab.get('one', 'subtwo', 'colors', function(i) { return i === 'yellow'; }); + it('should be possible to use some polymorphism on the selection.', function() { + var altCursor = baobab.select('one', 'subtwo', 'colors'); - assert.strictEqual(yellow, 'yellow'); + assert.deepEqual(altCursor.get(), state.one.subtwo.colors); }); - it('should be possible to retrieve items with a descriptor object.', function() { - var firstItem = baobab.get('items', {id: 'one'}), - secondItem = baobab.get('items', {id: 'two', user: {name: 'John'}}), - thirdItem = baobab.get('items', {id: ['one', 'two']}); + it('should be possible to select data using a function.', function() { + var cursor = baobab.select('one', 'subtwo', 'colors', function(v) { + return v === 'yellow'; + }); - assert.deepEqual(firstItem, {id: 'one'}); - assert.deepEqual(secondItem, {id: 'two', user: {name: 'John', surname: 'Talbot'}}); - assert.deepEqual(firstItem, {id: 'one'}); + assert.strictEqual(cursor.get(), 'yellow'); }); - it('should not fail when retrieved data is null on the path.', function() { - var nullValue = baobab.get('setLater'); - assert.strictEqual(nullValue, null); + it('should be possible to select data using a descriptor object.', function() { + var cursor = baobab.select('items', {id: 'one'}); - var inexistant = baobab.get('setLater', 'a'); - assert.strictEqual(inexistant, undefined); - }); - - it('should throw an error when trying to instantiate an baobab with incorrect data.', function() { - assert.throws(function() { - new Baobab(undefined); - }, /invalid data/); + assert.deepEqual(cursor.get(), {id: 'one'}); }); + }); - it('selecting data in the baobab should return a cursor.', function() { - assert(baobab.select(['one']) instanceof Cursor); - }); + describe('Events', function() { + var baobab = new Baobab(state); it('should be possible to listen to update events.', function(done) { baobab.on('update', function(e) { @@ -102,44 +83,6 @@ describe('Baobab API', function() { done(); }, 30); }); - - it('should be possible to instantiate without the "new" keyword.', function() { - var special = Baobab(state); - - assert(special.get('two'), baobab.get('two')); - }); - }); - - describe('Updates', function() { - - it('should be possible to set a key using a path rather than a key.', function() { - var baobab = new Baobab(state, {asynchronous: false}); - - baobab.set(['two', 'age'], 34); - assert.strictEqual(baobab.get().two.age, 34); - }); - - it('should be possible to set a key at an nonexistent path.', function() { - var baobab = new Baobab(state, {asynchronous: false}); - - baobab.set(['nonexistent', 'key'], 'hello'); - assert.strictEqual(baobab.get().nonexistent.key, 'hello'); - }); - - it('should be possible to set a key using a dynamic path.', function() { - var baobab = new Baobab(state, {asynchronous: false}); - - baobab.set(['items', {id: 'two'}, 'user', 'age'], 34); - assert.strictEqual(baobab.get().items[1].user.age, 34); - }); - - it('should fail when setting a nonexistent dynamic path.', function() { - var baobab = new Baobab(state, {asynchronous: false}); - - assert.throws(function() { - baobab.set(['items', {id: 'four'}, 'user', 'age'], 34); - }, /solve/); - }); }); describe('Advanced', function() { diff --git a/test/suites/cursor.js b/test/suites/cursor.js index b4fddab..3d282c2 100644 --- a/test/suites/cursor.js +++ b/test/suites/cursor.js @@ -10,276 +10,260 @@ var assert = require('assert'), describe('Cursor API', function() { - describe('Basics', function() { + describe('Getters', function() { var baobab = new Baobab(state); - var colorCursor = baobab.select(['one', 'subtwo', 'colors']), - oneCursor = baobab.select('one'); + describe('Root cursor', function() { + it('should be possible to retrieve full data.', function() { + var data = baobab.get(); + assert.deepEqual(data, state); + }); - it('should be possible to retrieve data at cursor.', function() { - var colors = colorCursor.get(); + it('should be possible to retrieve nested data.', function() { + var colors = baobab.get(['one', 'subtwo', 'colors']); + assert.deepEqual(colors, state.one.subtwo.colors); - assert(colors instanceof Array); - assert.deepEqual(colors, state.one.subtwo.colors); - }); + // Polymorphism + var primitive = baobab.get('primitive'); + assert.strictEqual(primitive, 3); + }); - it('should be possible to retrieve data with a 0 key.', function() { - var sub = new Baobab([1, 2]); - assert.strictEqual(sub.get(0), 1); - assert.strictEqual(colorCursor.get(0), 'blue'); - }); + it('should be possible to get data from both maps and lists.', function() { + var yellow = baobab.get(['one', 'subtwo', 'colors', 1]); - it('should be possible to retrieve nested data.', function() { - var colors = oneCursor.get(['subtwo', 'colors']); + assert.strictEqual(yellow, 'yellow'); + }); - assert.deepEqual(colors, state.one.subtwo.colors); - }); + it('should return undefined when data is not to be found through path.', function() { + var inexistant = baobab.get(['no']); + assert.strictEqual(inexistant, undefined); - it('should be possible to use some polymorphism on the selection.', function() { - var altCursor = baobab.select('one', 'subtwo', 'colors'); + // Nesting + var nestedInexistant = baobab.get(['no', 'no']); + assert.strictEqual(nestedInexistant, undefined); + }); - assert.deepEqual(altCursor.get(), colorCursor.get()); - }); + it('should be possible to retrieve items with a function in path.', function() { + var yellow = baobab.get('one', 'subtwo', 'colors', function(i) { return i === 'yellow'; }); - it('should be possible to select data using a function.', function() { - var cursor = baobab.select('one', 'subtwo', 'colors', function(v) { - return v === 'yellow'; + assert.strictEqual(yellow, 'yellow'); }); - assert.strictEqual(cursor.get(), 'yellow'); - }); + it('should be possible to retrieve items with a descriptor object.', function() { + var firstItem = baobab.get('items', {id: 'one'}), + secondItem = baobab.get('items', {id: 'two', user: {name: 'John'}}), + thirdItem = baobab.get('items', {id: ['one', 'two']}); - it('should be possible to select data using a descriptor object.', function() { - var cursor = baobab.select('items', {id: 'one'}); + assert.deepEqual(firstItem, {id: 'one'}); + assert.deepEqual(secondItem, {id: 'two', user: {name: 'John', surname: 'Talbot'}}); + assert.deepEqual(firstItem, {id: 'one'}); + }); - assert.deepEqual(cursor.get(), {id: 'one'}); + it('should not fail when retrieved data is null on the path.', function() { + var nullValue = baobab.get('setLater'); + assert.strictEqual(nullValue, null); + + var inexistant = baobab.get('setLater', 'a'); + assert.strictEqual(inexistant, undefined); + }); }); - it('should be possible to use some polymorphism on the getter.', function() { - var altCursor = baobab.select('one'); + describe('Standard cursors', function() { + var colorCursor = baobab.select(['one', 'subtwo', 'colors']), + oneCursor = baobab.select('one'); - assert.deepEqual(altCursor.get('subtwo', 'colors'), state.one.subtwo.colors); - }); + it('should be possible to retrieve data at cursor.', function() { + var colors = colorCursor.get(); - it('should be possible to listen to updates.', function(done) { - colorCursor.on('update', function() { - assert.deepEqual(colorCursor.get(), ['blue', 'yellow', 'purple']); - done(); + assert(colors instanceof Array); + assert.deepEqual(colors, state.one.subtwo.colors); }); - colorCursor.push('purple'); - }); - }); + it('should be possible to retrieve data with a 0 key.', function() { + var sub = new Baobab([1, 2]); + assert.strictEqual(sub.get(0), 1); + assert.strictEqual(colorCursor.get(0), 'blue'); + }); - describe('Predicates', function() { - var baobab = new Baobab(state); + it('should be possible to retrieve nested data.', function() { + var colors = oneCursor.get(['subtwo', 'colors']); - it('should be possible to tell whether cursor is root.', function() { - assert(baobab.select('one').up().isRoot()); - assert(!baobab.select('one').isRoot()); - }); + assert.deepEqual(colors, state.one.subtwo.colors); + }); - it('should be possible to tell whether cursor is leaf.', function() { - assert(baobab.select('primitive').isLeaf()); - assert(!baobab.select('one').isLeaf()); - }); + it('should be possible to use some polymorphism on the getter.', function() { + var altCursor = baobab.select('one'); - it('should be possible to tell whether cursor is branch.', function() { - assert(baobab.select('one').isBranch()); - assert(!baobab.select('one').up().isBranch()); - assert(!baobab.select('primitive').isBranch()); + assert.deepEqual(altCursor.get('subtwo', 'colors'), state.one.subtwo.colors); + }); }); }); - describe('Updates', function() { - it('should be possible to set a key using a path rather than a key.', function() { - var baobab = new Baobab(state, {asynchronous: false}), - cursor = baobab.select('items'); - - cursor.set([1, 'user', 'age'], 34); - assert.strictEqual(cursor.get()[1].user.age, 34); - }); - - it('should be possible to set a key at an nonexistent path.', function() { - var baobab = new Baobab(state, {asynchronous: false}), - cursor = baobab.select('two'); - - cursor.set(['nonexistent', 'key'], 'hello'); - assert.strictEqual(cursor.get().nonexistent.key, 'hello'); - }); + describe('Setters', function() { - it('should be possible to set a key using a dynamic path.', function() { - var baobab = new Baobab(state, {asynchronous: false}), - cursor = baobab.select('items'); + describe('Root cursor', function() { + it('should be possible to set a key using a path rather than a key.', function() { + var baobab = new Baobab(state, {asynchronous: false}); - cursor.set([{id: 'two'}, 'user', 'age'], 34); - assert.strictEqual(cursor.get()[1].user.age, 34); - }); + baobab.set(['two', 'age'], 34); + assert.strictEqual(baobab.get().two.age, 34); + }); - it('should fail when setting a nonexistent dynamic path.', function() { - var baobab = new Baobab(state, {asynchronous: false}), - cursor = baobab.select('items'); + it('should be possible to set a key at an nonexistent path.', function() { + var baobab = new Baobab(state, {asynchronous: false}); - assert.throws(function() { - cursor.set([{id: 'four'}, 'user', 'age'], 34); - }, /solve/); - }); + baobab.set(['nonexistent', 'key'], 'hello'); + assert.strictEqual(baobab.get().nonexistent.key, 'hello'); + }); - it('should throw an error when trying to push to a non-array.', function() { - var baobab = new Baobab(state), - oneCursor = baobab.select('one'); + it('should be possible to set a key using a dynamic path.', function() { + var baobab = new Baobab(state, {asynchronous: false}); - assert.throws(function() { - oneCursor.push('test'); - }, /non-array/); - }); + baobab.set(['items', {id: 'two'}, 'user', 'age'], 34); + assert.strictEqual(baobab.get().items[1].user.age, 34); + }); - it('should throw an error when trying to unshift to a non-array.', function() { - var baobab = new Baobab(state), - oneCursor = baobab.select('one'); + it('should fail when setting a nonexistent dynamic path.', function() { + var baobab = new Baobab(state, {asynchronous: false}); - assert.throws(function() { - oneCursor.unshift('test'); - }, /non-array/); + assert.throws(function() { + baobab.set(['items', {id: 'four'}, 'user', 'age'], 34); + }, /solve/); + }); }); - it('should be possible to chain mutations.', function(done) { - var baobab = new Baobab({number: 1}), - inc = function(i) { return i + 1; }; + describe('Standard cursors', function() { + it('should be possible to set a key using a path rather than a key.', function() { + var baobab = new Baobab(state, {asynchronous: false}), + cursor = baobab.select('items'); - baobab.update({number: {$chain: inc}}); - baobab.update({number: {$chain: inc}}); - - baobab.on('update', function() { - assert.strictEqual(baobab.get('number'), 3); - done(); + cursor.set([1, 'user', 'age'], 34); + assert.strictEqual(cursor.get()[1].user.age, 34); }); - }); - it('a single $chain command should work like an $apply.', function() { - var baobab = new Baobab({number: 1}, {asynchronous: false}), - cursor = baobab.select('number'), - inc = function(i) { return i + 1; }; + it('should be possible to set a key at an nonexistent path.', function() { + var baobab = new Baobab(state, {asynchronous: false}), + cursor = baobab.select('two'); - assert.strictEqual(cursor.get(), 1); - cursor.chain(inc); - assert.strictEqual(cursor.get(), 2); - }); + cursor.set(['nonexistent', 'key'], 'hello'); + assert.strictEqual(cursor.get().nonexistent.key, 'hello'); + }); - it('should be possible to shallow merge two objects.', function(done) { - var baobab = new Baobab({o: {hello: 'world'}, string: 'test'}); + it('should be possible to set a key using a dynamic path.', function() { + var baobab = new Baobab(state, {asynchronous: false}), + cursor = baobab.select('items'); - assert.throws(function() { - baobab.select('test').merge({hello: 'moto'}); - }, /merge/); + cursor.set([{id: 'two'}, 'user', 'age'], 34); + assert.strictEqual(cursor.get()[1].user.age, 34); + }); - var cursor = baobab.select('o'); - cursor.merge({hello: 'jarl'}); + it('should fail when setting a nonexistent dynamic path.', function() { + var baobab = new Baobab(state, {asynchronous: false}), + cursor = baobab.select('items'); - baobab.on('update', function() { - assert.deepEqual(baobab.get('o'), {hello: 'jarl'}); - done(); + assert.throws(function() { + cursor.set([{id: 'four'}, 'user', 'age'], 34); + }, /solve/); }); - }); - it('should be possible to remove keys from the tree.', function() { - var tree = new Baobab({one: 1, two: 2}, {asynchronous: false}); + it('should throw an error when trying to push to a non-array.', function() { + var baobab = new Baobab(state), + oneCursor = baobab.select('one'); - assert.deepEqual(tree.get(), {one: 1, two: 2}); - tree.unset('one'); - assert.deepEqual(tree.get(), {two: 2}); - }); - - it('should be possible to remove keys from a cursor.', function() { - var tree = new Baobab({one: 1, two: {subone: 1, subtwo: 2}}, {asynchronous: false}), - cursor = tree.select('two'); + assert.throws(function() { + oneCursor.push('test'); + }, /non-array/); + }); - assert.deepEqual(cursor.get(), {subone: 1, subtwo: 2}); - cursor.unset('subone'); - assert.deepEqual(cursor.get(), {subtwo: 2}); - }); + it('should throw an error when trying to unshift to a non-array.', function() { + var baobab = new Baobab(state), + oneCursor = baobab.select('one'); - it('should be possible to remove data at cursor.', function() { - var tree = new Baobab({one: 1, two: {subone: 1, subtwo: 2}}, {asynchronous: false}), - cursor = tree.select('two'); + assert.throws(function() { + oneCursor.unshift('test'); + }, /non-array/); + }); - assert.deepEqual(cursor.get(), {subone: 1, subtwo: 2}); - cursor.remove(); - assert.strictEqual(cursor.get(), undefined); - }); - }); + it('should be possible to chain mutations.', function(done) { + var baobab = new Baobab({number: 1}), + inc = function(i) { return i + 1; }; - describe('Traversal', function() { - var baobab = new Baobab(state); + baobab.update({number: {$chain: inc}}); + baobab.update({number: {$chain: inc}}); - var colorCursor = baobab.select(['one', 'subtwo', 'colors']), - oneCursor = baobab.select('one'); + baobab.on('update', function() { + assert.strictEqual(baobab.get('number'), 3); + done(); + }); + }); - it('should be possible to create subcursors.', function() { - var sub = oneCursor.select(['subtwo', 'colors']); - assert.deepEqual(sub.get(), state.one.subtwo.colors); - }); + it('a single $chain command should work like an $apply.', function() { + var baobab = new Baobab({number: 1}, {asynchronous: false}), + cursor = baobab.select('number'), + inc = function(i) { return i + 1; }; - it('should be possible to go up.', function() { - var parent = colorCursor.up(); - assert.deepEqual(parent.get(), state.one.subtwo); - }); + assert.strictEqual(cursor.get(), 1); + cursor.chain(inc); + assert.strictEqual(cursor.get(), 2); + }); - it('a cusor going up to root cannot go higher and returns null.', function() { - var up = baobab.select('one').up(), - upper = up.up(); + it('should be possible to shallow merge two objects.', function(done) { + var baobab = new Baobab({o: {hello: 'world'}, string: 'test'}); - assert.strictEqual(upper, null); - }); + assert.throws(function() { + baobab.select('test').merge({hello: 'moto'}); + }, /merge/); - it('should be possible to go left.', function() { - var left = colorCursor.select(1).left(); + var cursor = baobab.select('o'); + cursor.merge({hello: 'jarl'}); - assert.strictEqual(left.get(), 'blue'); - assert.strictEqual(left.left(), null); + baobab.on('update', function() { + assert.deepEqual(baobab.get('o'), {hello: 'jarl'}); + done(); + }); + }); - assert.throws(function() { - colorCursor.left(); - }, /left/); - }); + it('should be possible to remove keys from the tree.', function() { + var tree = new Baobab({one: 1, two: 2}, {asynchronous: false}); - it('should be possible to go right.', function() { - var right = colorCursor.select(0).right(); + assert.deepEqual(tree.get(), {one: 1, two: 2}); + tree.unset('one'); + assert.deepEqual(tree.get(), {two: 2}); + }); - assert.strictEqual(right.get(), 'yellow'); - assert.strictEqual(right.right(), null); + it('should be possible to remove keys from a cursor.', function() { + var tree = new Baobab({one: 1, two: {subone: 1, subtwo: 2}}, {asynchronous: false}), + cursor = tree.select('two'); - assert.throws(function() { - colorCursor.right(); - }, /right/); - }); + assert.deepEqual(cursor.get(), {subone: 1, subtwo: 2}); + cursor.unset('subone'); + assert.deepEqual(cursor.get(), {subtwo: 2}); + }); - it('should be possible to descend.', function() { - var list = baobab.select('list'); + it('should be possible to remove data at cursor.', function() { + var tree = new Baobab({one: 1, two: {subone: 1, subtwo: 2}}, {asynchronous: false}), + cursor = tree.select('two'); - assert.deepEqual(list.down().get(), [1, 2]); - assert.strictEqual(colorCursor.down().get(), 'blue'); - assert.strictEqual(colorCursor.down().up().up().select('colors').down().get(), 'blue'); - assert.strictEqual(list.down().right().down().right().get(), 4); - assert.strictEqual(oneCursor.down(), null); + assert.deepEqual(cursor.get(), {subone: 1, subtwo: 2}); + cursor.remove(); + assert.strictEqual(cursor.get(), undefined); + }); }); + }); - it('should be possible to get to the leftmost item of a list.', function() { - var listItem = baobab.select('longList', 2); + describe('Events', function() { + var baobab = new Baobab(state); - assert.strictEqual(listItem.get(), 3); - assert.strictEqual(listItem.leftmost().get(), 1); - }); + it('should be possible to listen to updates.', function(done) { + var colorCursor = baobab.select('one', 'subtwo', 'colors'); - it('should be possible to get to the rightmost item of a list.', function() { - var listItem = baobab.select('longList', 2); + colorCursor.on('update', function() { + assert.deepEqual(colorCursor.get(), ['blue', 'yellow', 'purple']); + done(); + }); - assert.strictEqual(listItem.get(), 3); - assert.strictEqual(listItem.rightmost().get(), 4); + colorCursor.push('purple'); }); - }); - - describe('Events', function() { it('when a parent updates, so does the child.', function(done) { var baobab = new Baobab(state), @@ -417,6 +401,96 @@ describe('Cursor API', function() { }); }); + describe('Predicates', function() { + var baobab = new Baobab(state); + + it('should be possible to tell whether cursor is root.', function() { + assert(baobab.select('one').up().isRoot()); + assert(!baobab.select('one').isRoot()); + }); + + it('should be possible to tell whether cursor is leaf.', function() { + assert(baobab.select('primitive').isLeaf()); + assert(!baobab.select('one').isLeaf()); + }); + + it('should be possible to tell whether cursor is branch.', function() { + assert(baobab.select('one').isBranch()); + assert(!baobab.select('one').up().isBranch()); + assert(!baobab.select('primitive').isBranch()); + }); + }); + + describe('Traversal', function() { + var baobab = new Baobab(state); + + var colorCursor = baobab.select(['one', 'subtwo', 'colors']), + oneCursor = baobab.select('one'); + + it('should be possible to create subcursors.', function() { + var sub = oneCursor.select(['subtwo', 'colors']); + assert.deepEqual(sub.get(), state.one.subtwo.colors); + }); + + it('should be possible to go up.', function() { + var parent = colorCursor.up(); + assert.deepEqual(parent.get(), state.one.subtwo); + }); + + it('a cusor going up to root cannot go higher and returns null.', function() { + var up = baobab.select('one').up(), + upper = up.up(); + + assert.strictEqual(upper, null); + }); + + it('should be possible to go left.', function() { + var left = colorCursor.select(1).left(); + + assert.strictEqual(left.get(), 'blue'); + assert.strictEqual(left.left(), null); + + assert.throws(function() { + colorCursor.left(); + }, /left/); + }); + + it('should be possible to go right.', function() { + var right = colorCursor.select(0).right(); + + assert.strictEqual(right.get(), 'yellow'); + assert.strictEqual(right.right(), null); + + assert.throws(function() { + colorCursor.right(); + }, /right/); + }); + + it('should be possible to descend.', function() { + var list = baobab.select('list'); + + assert.deepEqual(list.down().get(), [1, 2]); + assert.strictEqual(colorCursor.down().get(), 'blue'); + assert.strictEqual(colorCursor.down().up().up().select('colors').down().get(), 'blue'); + assert.strictEqual(list.down().right().down().right().get(), 4); + assert.strictEqual(oneCursor.down(), null); + }); + + it('should be possible to get to the leftmost item of a list.', function() { + var listItem = baobab.select('longList', 2); + + assert.strictEqual(listItem.get(), 3); + assert.strictEqual(listItem.leftmost().get(), 1); + }); + + it('should be possible to get to the rightmost item of a list.', function() { + var listItem = baobab.select('longList', 2); + + assert.strictEqual(listItem.get(), 3); + assert.strictEqual(listItem.rightmost().get(), 4); + }); + }); + describe('Advanced', function() { it('should be possible to execute several orders within a single stack.', function(done) { var baobab = new Baobab({ diff --git a/test/suites/helpers.js b/test/suites/helpers.js index 43dd89e..97b102f 100644 --- a/test/suites/helpers.js +++ b/test/suites/helpers.js @@ -35,7 +35,7 @@ describe('Helpers', function() { }); describe('Nested get', function() { - it('should be possible to retrieve nested items through the helper.', function() { + it('should be possible to retrieve nested items.', function() { assert.deepEqual(helpers.getIn(state, ['one', 'subtwo', 'colors']), state.one.subtwo.colors); assert.strictEqual(helpers.getIn(state, ['primitive']), 3); assert.deepEqual(helpers.getIn(state), state); @@ -64,7 +64,7 @@ describe('Helpers', function() { describe('Solve path', function() { - it('should be able to solve a complex path', function() { + it('should be able to solve a complex path.', function() { var o = { things: [ { diff --git a/test/suites/mixins.js b/test/suites/mixins.js index 16075dd..49683aa 100644 --- a/test/suites/mixins.js +++ b/test/suites/mixins.js @@ -369,7 +369,7 @@ describe('React Mixins', function() { }); }); - it('should allow mixins in options to access the tree', function () { + it('should allow mixins in options to access the tree.', function () { var baobab = new Baobab({ items: [] }, { From 6c59e84432500cf0c3a0cce9b9c8d420a9797aca Mon Sep 17 00:00:00 2001 From: Yomguithereal Date: Tue, 31 Mar 2015 18:00:50 +0200 Subject: [PATCH 15/73] Preparing version --- bower.json | 2 +- build/baobab.min.js | 4 ++-- index.js | 2 +- package.json | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/bower.json b/bower.json index 02b31c0..3097923 100644 --- a/bower.json +++ b/bower.json @@ -1,7 +1,7 @@ { "name": "baobab", "main": "build/baobab.min.js", - "version": "0.4.3", + "version": "1.0.0-rc1", "homepage": "https://github.com/Yomguithereal/baobab", "author": { "name": "Guillaume Plique", diff --git a/build/baobab.min.js b/build/baobab.min.js index 2ca3796..ad084cf 100644 --- a/build/baobab.min.js +++ b/build/baobab.min.js @@ -1,2 +1,2 @@ -/* baobab.js - Version: 0.4.3 - Author: Yomguithereal (Guillaume Plique) */ -!function(t){if("object"==typeof exports&&"undefined"!=typeof module)module.exports=t();else if("function"==typeof define&&define.amd)define([],t);else{var r;r="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:this,r.Baobab=t()}}(function(){var t;return function r(t,e,n){function o(s,a){if(!e[s]){if(!t[s]){var u="function"==typeof require&&require;if(!a&&u)return u(s,!0);if(i)return i(s,!0);var h=new Error("Cannot find module '"+s+"'");throw h.code="MODULE_NOT_FOUND",h}var c=e[s]={exports:{}};t[s][0].call(c.exports,function(r){var e=t[s][1][r];return o(e?e:r)},c,c.exports,r,t,e,n)}return e[s].exports}for(var i="function"==typeof require&&require,s=0;sr;r++)n.push(t[r].handler);return n}var o={once:"boolean",scope:"object"},i=function(){this._enabled=!0,this._children=[],this._handlers={},this._handlersAll=[]};i.prototype.on=function(t,r,e){var n,s,a,u,h,c;if("function"==typeof r){for(h="string"==typeof t?[t]:t,n=0,s=h.length;n!==s;n+=1)if(u=h[n]){this._handlers[u]||(this._handlers[u]=[]),c={handler:r};for(a in e||{}){if(!o[a])throw new Error('The option "'+a+'" is not recognized by Emmett.');c[a]=e[a]}this._handlers[u].push(c)}}else if(t&&"object"==typeof t&&!Array.isArray(t))for(u in t)i.prototype.on.call(this,u,t[u],r);else{if("function"!=typeof t)throw new Error("Wrong arguments.");c={handler:t};for(a in e||{}){if(!o[a])throw new Error('The option "'+a+'" is not recognized by Emmett.');c[a]=e[a]}this._handlersAll.push(c)}return this},i.prototype.once=function(t,r,e){if("function"==typeof r)e=e||{},e.once=!0,this.on(t,r,e);else{if((!t||"object"!=typeof t||Array.isArray(t))&&"function"!=typeof t)throw new Error("Wrong arguments.");r=r||{},r.once=!0,this.on(t,r)}return this},i.prototype.off=function(t,r){var e,n,o,i,s,a,u,h="string"==typeof t?[t]:t;if(1===arguments.length&&"function"==typeof h){r=arguments[0];for(s in this._handlers){for(a=[],e=0,n=this._handlers[s].length;e!==n;e+=1)this._handlers[s][e].handler!==r&&a.push(this._handlers[s][e]);this._handlers[s]=a}for(a=[],e=0,n=this._handlersAll.length;e!==n;e+=1)this._handlersAll[e].handler!==r&&a.push(this._handlersAll[e]);this._handlersAll=a}else if(2===arguments.length)for(e=0,n=h.length;e!==n;e+=1){if(u=h[e],this._handlers[u]){for(a=[],o=0,i=this._handlers[u].length;o!==i;o+=1)this._handlers[u][o].handler!==r&&a.push(this._handlers[u][o]);this._handlers[u]=a}this._handlers[u]&&0===this._handlers[u].length&&delete this._handlers[u]}return this},i.prototype.unbindAll=function(){var t;this._handlersAll=[];for(t in this._handlers)delete this._handlers[t];return this},i.prototype.emit=function(t,r){var e,n,o,i,s,a,u,h,c,l,f="string"==typeof t?[t]:t;if(!this._enabled)return this;for(r=void 0===r?{}:r,e=0,n=f.length;e!==n;e+=1)if(l=f[e],c=(this._handlers[l]||[]).concat(this._handlersAll),c.length){for(u={type:l,data:r||{},target:this},a=[],o=0,i=c.length;o!==i;o+=1)(this._handlers[l]&&this._handlers[l].indexOf(c[o])>=0||this._handlersAll.indexOf(c[o])>=0)&&(c[o].handler.call("scope"in c[o]?c[o].scope:this,u),c[o].once&&a.push(c[o]));for(s=0;se;e++)if(t._children[e]===r){t._children.splice(e,1);break}}),this._children.push(r),r},i.prototype.listeners=function(t){var e,n,o,i=[];if(t)for(i=r(this._handlers[t]),n=0,o=this._children.length;o>n;n++)i=i.concat(this._children[n].listeners(t));else{i=r(this._handlersAll);for(e in this._handlers)i=i.concat(r(this._handlers[e]));for(n=0,o=this._children.length;o>n;n++)i=i.concat(this._children[n].listeners())}return i},i.prototype.kill=function(){if(this.emit("emmett:kill"),this.unbindAll(),this._handlers=null,this._handlersAll=null,this._enabled=!1,this._children)for(var t=0,r=this._children.length;r>t;t++)this._children[t].kill();this._children=null},i.prototype.disable=function(){return this._enabled=!1,this},i.prototype.enable=function(){return this._enabled=!0,this},i.version="2.1.2","undefined"!=typeof n?("undefined"!=typeof e&&e.exports&&(n=e.exports=i),n.Emitter=i):"function"==typeof t&&t.amd?t("emmett",[],function(){return i}):this.Emitter=i}).call(this)},{}],4:[function(t,r){function e(t){return t+"$"+(new Date).getTime()+(""+Math.random()).replace("0.","")}function n(t,r){function e(t){this[t]=function(){var r=this.root[t].apply(this.root,arguments);return r instanceof o?this:r}}if(arguments.length<1&&(t={}),!(this instanceof n))return new n(t,r);if(!l.Object(t)&&!l.Array(t))throw Error("Baobab: invalid data.");i.call(this),this.options=s.shallowMerge(c,r),this._transaction={},this._future=void 0,this._cursors={},this.data=s.deepClone(t),this.root=this.select([]),["get","set","unset","update"].forEach(e.bind(this)),this.mixin=h.baobab(this)}var o=t("./cursor.js"),i=t("emmett"),s=t("./helpers.js"),a=t("./update.js"),u=t("./merge.js"),h=t("./mixins.js"),c=t("../defaults.js"),l=t("./type.js");s.inherits(n,i),n.prototype.select=function(t){if(!t)throw Error("Baobab.select: invalid path.");if(arguments.length>1&&(t=s.arrayOf(arguments)),!l.Path(t))throw Error("Baobab.select: invalid path.");t=[].concat(t);var r,n=l.ComplexPath(t);n&&(r=s.solvePath(this.data,t));var i=t.map(function(t){return l.Function(t)?e("fn"):l.Object(t)?e("ob"):t}).join("λ");if(this._cursors[i])return this._cursors[i];var a=new o(this,t,r,i);return this._cursors[i]=a,a},n.prototype.stack=function(t){var r=this;if(!l.Object(t))throw Error("Baobab.update: wrong specification.");return this._transaction=u(t,this._transaction),this.options.autoCommit?this.options.asynchronous?(this._future||(this._future=setTimeout(r.commit.bind(r,null),0)),this):this.commit():this},n.prototype.commit=function(){var t=a(this.data,this._transaction,this.options);return this.data=t.data,this._transaction={},this._future&&(this._future=clearTimeout(this._future)),this.emit("update",{log:t.log}),this},n.prototype.release=function(){delete this.data,delete this._transaction;for(var t in this._cursors)this._cursors[t].release();delete this._cursors,this.kill()},n.prototype.toJSON=function(){return this.get()},r.exports=n},{"../defaults.js":1,"./cursor.js":6,"./helpers.js":7,"./merge.js":8,"./mixins.js":9,"./type.js":10,"./update.js":11,emmett:3}],5:[function(t,r){function e(t,r){r.on("update",t.cursorListener),t.tree.off("update",t.treeListener),t.tree.on("update",t.treeListener)}function n(t){var r=this;if(arguments.length<2)throw Error("baobab.Combination: not enough arguments.");var n=arguments[1],o=s.arrayOf(arguments).slice(2);if(n instanceof Array&&(o=n.slice(1),n=n[0]),!a.Cursor(n))throw Error("baobab.Combination: argument should be a cursor.");if("or"!==t&&"and"!==t)throw Error("baobab.Combination: invalid operator.");i.call(this),this.cursors=[n],this.operators=[],this.tree=n.tree,this.updates=new Array(this.cursors.length),this.cursorListener=function(){r.updates[r.cursors.indexOf(this)]=!0},this.treeListener=function(){var t,e,n=r.updates[0];for(t=1,e=r.cursors.length;e>t;t++)n="or"===r.operators[t-1]?n||r.updates[t]:n&&r.updates[t];n&&r.emit("update"),r.updates=new Array(r.cursors.length)},this.bound=!1;var u=(this.on,this.once,function(){r.bound||(r.bound=!0,r.cursors.forEach(function(t){e(r,t)}))});this.on=s.before(u,this.on.bind(this)),this.once=s.before(u,this.once.bind(this)),o.forEach(function(r){this[t](r)},this)}function o(t){n.prototype[t]=function(r){if(!a.Cursor(r))throw this.release(),Error("baobab.Combination."+t+": argument should be a cursor.");if(~this.cursors.indexOf(r))throw this.release(),Error("baobab.Combination."+t+": cursor already in combination.");return this.cursors.push(r),this.operators.push(t),this.updates.length++,this.bound&&e(this,r),this}}var i=t("emmett"),s=t("./helpers.js"),a=t("./type.js");s.inherits(n,i),o("or"),o("and"),n.prototype.release=function(){this.cursors.forEach(function(t){t.off("update",this.cursorListener)},this),this.tree.off("update",this.treeListener),this.cursors=null,this.operators=null,this.tree=null,this.updates=null,this.kill()},r.exports=n},{"./helpers.js":7,"./type.js":10,emmett:3}],6:[function(t,r){function e(t,r,e,o){var a=this;n.call(this),r=r||[],this.tree=t,this.path=r,this.hash=o,this.complexPath=!!e,this.solvedPath=this.complexPath?e:this.path,this.relevant=void 0!==this.get(),this.updateHandler=function(t){var r,e,n,o,i,u,h=t.data.log,c=!1;if(a.complexPath&&(a.solvedPath=s.solvePath(a.tree.data,a.path)),!a.path.length)return a.emit("update");t:for(i=0,n=h.length;n>i;i++)for(r=h[i],u=0,o=r.length;o>u&&(e=r[u],e===""+a.solvedPath[u]);u++)if(u+1===o||u+1===a.solvedPath.length){c=!0;break t}var l=void 0!==a.get();a.relevant?l&&c?a.emit("update"):l||(a.emit("irrelevant"),a.relevant=!1):l&&c&&(a.emit("relevant"),a.emit("update"),a.relevant=!0)},this.mixin=i.cursor(this);var u=!1,h=function(){u||(u=!0,a.tree.on("update",a.updateHandler))};this.on=s.before(h,this.on.bind(this)),this.once=s.before(h,this.once.bind(this))}var n=t("emmett"),o=t("./combination.js"),i=t("./mixins.js"),s=t("./helpers.js"),a=t("./type.js");s.inherits(e,n),e.prototype.isRoot=function(){return!this.path.length},e.prototype.isLeaf=function(){return a.Primitive(this.get())},e.prototype.isBranch=function(){return!this.isLeaf()&&!this.isRoot()},e.prototype.root=function(){return this.tree.root()},e.prototype.select=function(t){if(arguments.length>1&&(t=s.arrayOf(arguments)),!a.Path(t))throw Error("baobab.Cursor.select: invalid path.");return this.tree.select(this.path.concat(t))},e.prototype.up=function(){return this.solvedPath&&this.solvedPath.length?this.tree.select(this.path.slice(0,-1)):null},e.prototype.left=function(){var t=+this.solvedPath[this.solvedPath.length-1];if(isNaN(t))throw Error("baobab.Cursor.left: cannot go left on a non-list type.");return t?this.tree.select(this.solvedPath.slice(0,-1).concat(t-1)):null},e.prototype.leftmost=function(){var t=+this.solvedPath[this.solvedPath.length-1];if(isNaN(t))throw Error("baobab.Cursor.leftmost: cannot go left on a non-list type.");return this.tree.select(this.solvedPath.slice(0,-1).concat(0))},e.prototype.right=function(){var t=+this.solvedPath[this.solvedPath.length-1];if(isNaN(t))throw Error("baobab.Cursor.right: cannot go right on a non-list type.");return t+1===this.up().get().length?null:this.tree.select(this.solvedPath.slice(0,-1).concat(t+1))},e.prototype.rightmost=function(){var t=+this.solvedPath[this.solvedPath.length-1];if(isNaN(t))throw Error("baobab.Cursor.right: cannot go right on a non-list type.");var r=this.up().get();return this.tree.select(this.solvedPath.slice(0,-1).concat(r.length-1))},e.prototype.down=function(){+this.solvedPath[this.solvedPath.length-1];return this.get()instanceof Array?this.tree.select(this.solvedPath.concat(0)):null},e.prototype.get=function(t){arguments.length>1&&(t=s.arrayOf(arguments));var r=this.solvedPath.concat((a.String(t)||a.Number(t)?[t]:t)||[]);return s.getIn(this.tree.data,r)},e.prototype.set=function(t,r){if(arguments.length<2)throw Error("baobab.Cursor.set: expecting at least key/value.");var e=this.get();if("object"!=typeof e)throw Error("baobab.Cursor.set: trying to set key to a non-object.");var n={};if(a.Array(t)){var o=s.solvePath(e,t);if(!o)throw Error("baobab.Cursor.set: could not solve dynamic path.");n=s.pathObject(o,{$set:r})}else n[t]={$set:r};return this.update(n)},e.prototype.edit=function(t){return this.update({$set:t})},e.prototype.unset=function(t){if(!t&&0!==t)throw Error("baobab.Cursor.unset: expects a valid key to unset.");if("object"!=typeof this.get())throw Error("baobab.Cursor.set: trying to set key to a non-object.");var r={};return r[t]={$unset:!0},this.update(r)},e.prototype.remove=function(){if(this.isRoot())throw Error("baobab.Cursor.remove: cannot remove root node.");return this.update({$unset:!0})},e.prototype.apply=function(t){if("function"!=typeof t)throw Error("baobab.Cursor.apply: argument is not a function.");return this.update({$apply:t})},e.prototype.chain=function(t){if("function"!=typeof t)throw Error("baobab.Cursor.chain: argument is not a function.");return this.update({$chain:t})},e.prototype.push=function(t){if(!(this.get()instanceof Array))throw Error("baobab.Cursor.push: trying to push to non-array value.");return this.update(arguments.length>1?{$push:s.arrayOf(arguments)}:{$push:t})},e.prototype.unshift=function(t){if(!(this.get()instanceof Array))throw Error("baobab.Cursor.push: trying to push to non-array value.");return this.update(arguments.length>1?{$unshift:s.arrayOf(arguments)}:{$unshift:t})},e.prototype.merge=function(t){if(!a.Object(t))throw Error("baobab.Cursor.merge: trying to merge a non-object.");if(!a.Object(this.get()))throw Error("baobab.Cursor.merge: trying to merge into a non-object.");this.update({$merge:t})},e.prototype.update=function(t){return this.tree.stack(s.pathObject(this.solvedPath,t)),this},e.prototype.or=function(t){return new o("or",this,t)},e.prototype.and=function(t){return new o("and",this,t)},e.prototype.release=function(){this.tree.off("update",this.updateHandler),this.hash&&delete this.tree._cursors[this.hash],delete this.tree,delete this.path,delete this.solvedPath,this.kill()},e.prototype.toJSON=function(){return this.get()},a.Cursor=function(t){return t instanceof e},r.exports=e},{"./combination.js":5,"./helpers.js":7,"./mixins.js":9,"./type.js":10,emmett:3}],7:[function(t,r){function e(t){return Array.prototype.slice.call(t)}function n(t,r){return function(){t(),r.apply(null,arguments)}}function o(t,r){var e,n={};for(e in t)n[e]=t[e];for(e in r)n[e]=r[e];return n}function i(t){var r=t.source,e="";return t.global&&(e+="g"),t.multiline&&(e+="m"),t.ignoreCase&&(e+="i"),t.sticky&&(e+="y"),t.unicode&&(e+="u"),new RegExp(r,e)}function s(t,r){if(!r||"object"!=typeof r||r instanceof Error||r instanceof ArrayBuffer)return r;if(g.Array(r)){if(t){var e,n,o=[];for(e=0,n=r.length;n>e;e++)o.push(v(r[e]));return o}return r.slice(0)}if(g.Date(r))return new Date(r.getTime());if(r instanceof RegExp)return i(r);if(g.Object(r)){var s,a={};r.constructor&&r.constructor!==Object&&(a=Object.create(r.constructor.prototype));for(s in r)r.hasOwnProperty(s)&&(a[s]=t?v(r[s]):r[s]);return a}return r}function a(t,r){return function(e){return r(t(e))}}function u(t,r){var e,n;for(e=0,n=t.length;n>e;e++)if(r(t[e]))return t[e]}function h(t,r){var e,n;for(e=0,n=t.length;n>e;e++)if(r(t[e]))return e;return-1}function c(t,r){var e,n=!0;if(!t)return!1;for(e in r)if(g.Object(r[e]))n=n&&c(t[e],r[e]);else if(g.Array(r[e]))n=n&&!!~r[e].indexOf(t[e]);else if(t[e]!==r[e])return!1;return n}function l(t,r){return u(t,function(t){return c(t,r)})}function f(t,r){return h(t,function(t){return c(t,r)})}function p(t,r){r=r||[];var e,n,o=t;for(e=0,n=r.length;n>e;e++){if(!o)return;if("function"==typeof r[e]){if(!g.Array(o))return;o=u(o,r[e])}else if("object"==typeof r[e]){if(!g.Array(o))return;o=l(o,r[e])}else o=o[r[e]]}return o}function d(t,r){var e,n,o,i=[],s=t;for(n=0,o=r.length;o>n;n++){if(!s)return null;if("function"==typeof r[n]){if(!g.Array(s))return;e=h(s,r[n]),i.push(e),s=s[e]}else if("object"==typeof r[n]){if(!g.Array(s))return;e=f(s,r[n]),i.push(e),s=s[e]}else i.push(r[n]),s=s[r[n]]||{}}return i}function b(t,r){var e,n=t.length,o={},i=o;for(n||(o=r),e=0;n>e;e++)i[t[e]]=e+1===n?r:{},i=i[t[e]];return o}function y(t,r){t.super_=r;var e=function(){};e.prototype=r.prototype,t.prototype=new e,t.prototype.constructor=t}var g=t("./type.js"),m=s.bind(null,!1),v=s.bind(null,!0);r.exports={arrayOf:e,before:n,deepClone:v,shallowClone:m,shallowMerge:o,compose:a,getIn:p,inherits:y,pathObject:b,solvePath:d}},{"./type.js":10}],8:[function(t,r){function e(t,r,e){s.forEach(function(r){e!==r&&delete t[r]}),t[e]=r[e]}function n(t,r){var a,u=o.shallowClone(r||{});s.forEach(function(r){t[r]&&e(u,t,r)}),t.$chain&&(s.slice(0,-1).forEach(function(t){delete u[t]}),u.$apply=u.$apply?o.compose(u.$apply,t.$chain):t.$chain),t.$push&&u.$push?u.$push=i.Array(u.$push)?u.$push.concat(t.$push):[u.$push].concat(t.$push):t.$push&&(u.$push=t.$push),t.$unshift&&u.$unshift?u.$unshift=i.Array(t.$unshift)?t.$unshift.concat(u.$unshift):[t.$unshift].concat(u.$unshift):t.$unshift&&(u.$unshift=t.$unshift);for(a in t)i.Object(t[a])?u[a]=n(t[a],u[a]):"$"!==a[0]&&(u[a]=t[a]);return u}var o=t("./helpers.js"),i=t("./type.js"),s=["$unset","$set","$merge","$apply"];r.exports=n},{"./helpers.js":7,"./type.js":10}],9:[function(t,r){var e=t("./combination.js"),n=t("./type.js");r.exports={baobab:function(t){return{mixins:[{getInitialState:function(){if(this.tree=t,!this.cursor&&!this.cursors)return{};if(this.cursor&&this.cursors)throw Error("baobab.mixin: you cannot have both `component.cursor` and `component.cursors`. Please make up your mind.");if(this.__type=null,this.__updateHandler=function(){this.setState(this.__getCursorData())}.bind(this),this.cursor){if(!n.MixinCursor(this.cursor))throw Error("baobab.mixin.cursor: invalid data (cursor, string, array or function).");n.Function(this.cursor)&&(this.cursor=this.cursor()),n.Cursor(this.cursor)||(this.cursor=t.select(this.cursor)),this.__getCursorData=function(){return{cursor:this.cursor.get()}}.bind(this),this.__type="single"}else if(this.cursors){if(!n.MixinCursors(this.cursors))throw Error("baobab.mixin.cursor: invalid data (object, array or function).");if(n.Function(this.cursors)&&(this.cursors=this.cursors()),n.Array(this.cursors))this.cursors=this.cursors.map(function(r){return n.Cursor(r)?r:t.select(r)}),this.__getCursorData=function(){return{cursors:this.cursors.map(function(t){return t.get()})}}.bind(this),this.__type="array";else{for(var r in this.cursors)n.Cursor(this.cursors[r])||(this.cursors[r]=t.select(this.cursors[r]));this.__getCursorData=function(){var t={};for(r in this.cursors)t[r]=this.cursors[r].get();return{cursors:t}}.bind(this),this.__type="object"}}return this.__getCursorData()},componentDidMount:function(){"single"===this.__type?(this.__combination=new e("or",[this.cursor]),this.__combination.on("update",this.__updateHandler)):"array"===this.__type?(this.__combination=new e("or",this.cursors),this.__combination.on("update",this.__updateHandler)):"object"===this.__type&&(this.__combination=new e("or",Object.keys(this.cursors).map(function(t){return this.cursors[t]},this)),this.__combination.on("update",this.__updateHandler))},componentWillUnmount:function(){this.__combination&&this.__combination.release()}}].concat(t.options.mixins)}},cursor:function(t){return{mixins:[{getInitialState:function(){return this.cursor=t,this.__updateHandler=function(){this.setState({cursor:this.cursor.get()})}.bind(this),{cursor:this.cursor.get()}},componentDidMount:function(){this.cursor.on("update",this.__updateHandler)},componentWillUnmount:function(){this.cursor.off("update",this.__updateHandler)}}].concat(t.tree.options.mixins)}}}},{"./combination.js":5,"./type.js":10}],10:[function(t,r){var e=function(t){return Array.isArray(t)?"array":"object"==typeof t&&null!==t?"object":"string"==typeof t?"string":"number"==typeof t?"number":"boolean"==typeof t?"boolean":"function"==typeof t?"function":null===t?"null":void 0===t?"undefined":t instanceof Date?"date":"invalid"};e.Array=function(t){return Array.isArray(t)},e.Object=function(t){return!Array.isArray(t)&&"object"==typeof t&&null!==t},e.String=function(t){return"string"==typeof t},e.Number=function(t){return"number"==typeof t},e.Boolean=function(t){return"boolean"==typeof t},e.Function=function(t){return"function"==typeof t},e.Primitive=function(t){return"string"==typeof t||"number"==typeof t||"boolean"==typeof t},e.Date=function(t){return t instanceof Date},e.Step=function(t){var r=e(t),n=["null","undefined","invalid","date"];return-1===n.indexOf(r)},e.Path=function(t){var r=["object","string","number","function","undefined"];if(!e.Array(t))return r.indexOf(e(t))>=0;for(var n=0;n=0||e.Cursor(t)},e.MixinCursors=function(t){var r=["array","object","function"];return r.indexOf(e(t))>=0},e.ComplexPath=function(t){for(var r=["object","function"],n=0;n=0)return!0;return!1},r.exports=e},{}],11:[function(t,r){function e(t,r){var e=new Error("baobab.update: "+r+" at path /"+t.slice(1).toString());return e.path=t,e}var n=t("./helpers.js"),o=t("./type.js");r.exports=function(t,r,i){if(i=i||{},!o.Object(t)&&!o.Array(t))throw Error("baobab.update: invalid target.");var s={};t={root:n.shallowClone(t)};var a=function(t,r,i,u){i=i||["root"];var h,c,l,f=i.join("λ"),p=i[i.length-1],d=Object.keys(r).some(function(t){return!!~["$unset","$set","$apply","$merge","$push","$unshift"].indexOf(t)});if(d){s[f]=!0;for(c in r){if("$unset"===c){var b=i[i.length-2];o.Array(t)?u[b]=t.slice(0,+p).concat(t.slice(+p+1)):(u[b]=n.shallowClone(t),delete u[b][p]);break}if("$set"===c){l=r.$set,t[p]=l;break}if("$apply"===c){if(h=r.$apply,"function"!=typeof h)throw e(i,"using command $apply with a non function");t[p]=h.call(null,t[p]);break}if("$merge"===c){if(l=r.$merge,!o.Object(t[p])||!o.Object(l))throw e(i,"using command $merge with a non object");t[p]=n.shallowMerge(t[p],l);break}if("$push"===c){if(l=r.$push,!o.Array(t[p]))throw e(i,"using command $push to a non array");t[p]=t[p].concat(l)}if("$unshift"===c){if(l=r.$unshift,!o.Array(t[p]))throw e(i,"using command $unshift to a non array");t[p]=[].concat(l).concat(t[p])}}}else for(c in r)t[p][c]="undefined"==typeof t[p][c]?{}:n.shallowClone(t[p][c]),a(t[p],r[c],i.concat(c),t)};return a(t,r),{data:t.root,log:Object.keys(s).map(function(t){return t.split("λ").slice(1)})}}},{"./helpers.js":7,"./type.js":10}]},{},[2])(2)}); \ No newline at end of file +/* baobab.js - Version: 1.0.0-rc1 - Author: Yomguithereal (Guillaume Plique) */ +!function(t){if("object"==typeof exports&&"undefined"!=typeof module)module.exports=t();else if("function"==typeof define&&define.amd)define([],t);else{var r;r="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:this,r.Baobab=t()}}(function(){var t;return function r(t,e,n){function o(s,a){if(!e[s]){if(!t[s]){var u="function"==typeof require&&require;if(!a&&u)return u(s,!0);if(i)return i(s,!0);var h=new Error("Cannot find module '"+s+"'");throw h.code="MODULE_NOT_FOUND",h}var c=e[s]={exports:{}};t[s][0].call(c.exports,function(r){var e=t[s][1][r];return o(e?e:r)},c,c.exports,r,t,e,n)}return e[s].exports}for(var i="function"==typeof require&&require,s=0;sr;r++)n.push(t[r].handler);return n}var o={once:"boolean",scope:"object"},i=function(){this._enabled=!0,this._children=[],this._handlers={},this._handlersAll=[]};i.prototype.on=function(t,r,e){var n,s,a,u,h,c;if("function"==typeof r){for(h="string"==typeof t?[t]:t,n=0,s=h.length;n!==s;n+=1)if(u=h[n]){this._handlers[u]||(this._handlers[u]=[]),c={handler:r};for(a in e||{}){if(!o[a])throw new Error('The option "'+a+'" is not recognized by Emmett.');c[a]=e[a]}this._handlers[u].push(c)}}else if(t&&"object"==typeof t&&!Array.isArray(t))for(u in t)i.prototype.on.call(this,u,t[u],r);else{if("function"!=typeof t)throw new Error("Wrong arguments.");c={handler:t};for(a in e||{}){if(!o[a])throw new Error('The option "'+a+'" is not recognized by Emmett.');c[a]=e[a]}this._handlersAll.push(c)}return this},i.prototype.once=function(t,r,e){if("function"==typeof r)e=e||{},e.once=!0,this.on(t,r,e);else{if((!t||"object"!=typeof t||Array.isArray(t))&&"function"!=typeof t)throw new Error("Wrong arguments.");r=r||{},r.once=!0,this.on(t,r)}return this},i.prototype.off=function(t,r){var e,n,o,i,s,a,u,h="string"==typeof t?[t]:t;if(1===arguments.length&&"function"==typeof h){r=arguments[0];for(s in this._handlers){for(a=[],e=0,n=this._handlers[s].length;e!==n;e+=1)this._handlers[s][e].handler!==r&&a.push(this._handlers[s][e]);this._handlers[s]=a}for(a=[],e=0,n=this._handlersAll.length;e!==n;e+=1)this._handlersAll[e].handler!==r&&a.push(this._handlersAll[e]);this._handlersAll=a}else if(2===arguments.length)for(e=0,n=h.length;e!==n;e+=1){if(u=h[e],this._handlers[u]){for(a=[],o=0,i=this._handlers[u].length;o!==i;o+=1)this._handlers[u][o].handler!==r&&a.push(this._handlers[u][o]);this._handlers[u]=a}this._handlers[u]&&0===this._handlers[u].length&&delete this._handlers[u]}return this},i.prototype.unbindAll=function(){var t;this._handlersAll=[];for(t in this._handlers)delete this._handlers[t];return this},i.prototype.emit=function(t,r){var e,n,o,i,s,a,u,h,c,l,f="string"==typeof t?[t]:t;if(!this._enabled)return this;for(r=void 0===r?{}:r,e=0,n=f.length;e!==n;e+=1)if(l=f[e],c=(this._handlers[l]||[]).concat(this._handlersAll),c.length){for(u={type:l,data:r||{},target:this},a=[],o=0,i=c.length;o!==i;o+=1)(this._handlers[l]&&this._handlers[l].indexOf(c[o])>=0||this._handlersAll.indexOf(c[o])>=0)&&(c[o].handler.call("scope"in c[o]?c[o].scope:this,u),c[o].once&&a.push(c[o]));for(s=0;se;e++)if(t._children[e]===r){t._children.splice(e,1);break}}),this._children.push(r),r},i.prototype.listeners=function(t){var e,n,o,i=[];if(t)for(i=r(this._handlers[t]),n=0,o=this._children.length;o>n;n++)i=i.concat(this._children[n].listeners(t));else{i=r(this._handlersAll);for(e in this._handlers)i=i.concat(r(this._handlers[e]));for(n=0,o=this._children.length;o>n;n++)i=i.concat(this._children[n].listeners())}return i},i.prototype.kill=function(){if(this.emit("emmett:kill"),this.unbindAll(),this._handlers=null,this._handlersAll=null,this._enabled=!1,this._children)for(var t=0,r=this._children.length;r>t;t++)this._children[t].kill();this._children=null},i.prototype.disable=function(){return this._enabled=!1,this},i.prototype.enable=function(){return this._enabled=!0,this},i.version="2.1.2","undefined"!=typeof n?("undefined"!=typeof e&&e.exports&&(n=e.exports=i),n.Emitter=i):"function"==typeof t&&t.amd?t("emmett",[],function(){return i}):this.Emitter=i}).call(this)},{}],4:[function(t,r){function e(t){return t+"$"+(new Date).getTime()+(""+Math.random()).replace("0.","")}function n(t,r){function e(t){this[t]=function(){var r=this.root[t].apply(this.root,arguments);return r instanceof o?this:r}}if(arguments.length<1&&(t={}),!(this instanceof n))return new n(t,r);if(!l.Object(t)&&!l.Array(t))throw Error("Baobab: invalid data.");i.call(this),this.options=s.shallowMerge(c,r),this._transaction={},this._future=void 0,this._cursors={},this.data=s.deepClone(t),this.root=this.select([]),["get","set","unset","update"].forEach(e.bind(this)),this.mixin=h.baobab(this)}var o=t("./cursor.js"),i=t("emmett"),s=t("./helpers.js"),a=t("./update.js"),u=t("./merge.js"),h=t("./mixins.js"),c=t("../defaults.js"),l=t("./type.js");s.inherits(n,i),n.prototype.select=function(t){if(!t)throw Error("Baobab.select: invalid path.");if(arguments.length>1&&(t=s.arrayOf(arguments)),!l.Path(t))throw Error("Baobab.select: invalid path.");t=[].concat(t);var r,n=l.ComplexPath(t);n&&(r=s.solvePath(this.data,t));var i=t.map(function(t){return l.Function(t)?e("fn"):l.Object(t)?e("ob"):t}).join("λ");if(this._cursors[i])return this._cursors[i];var a=new o(this,t,r,i);return this._cursors[i]=a,a},n.prototype.stack=function(t){var r=this;if(!l.Object(t))throw Error("Baobab.update: wrong specification.");return this._transaction=u(t,this._transaction),this.options.autoCommit?this.options.asynchronous?(this._future||(this._future=setTimeout(r.commit.bind(r,null),0)),this):this.commit():this},n.prototype.commit=function(){var t=a(this.data,this._transaction,this.options);return this.data=t.data,this._transaction={},this._future&&(this._future=clearTimeout(this._future)),this.emit("update",{log:t.log}),this},n.prototype.release=function(){delete this.data,delete this._transaction;for(var t in this._cursors)this._cursors[t].release();delete this._cursors,this.kill()},n.prototype.toJSON=function(){return this.get()},r.exports=n},{"../defaults.js":1,"./cursor.js":6,"./helpers.js":7,"./merge.js":8,"./mixins.js":9,"./type.js":10,"./update.js":11,emmett:3}],5:[function(t,r){function e(t,r){r.on("update",t.cursorListener),t.tree.off("update",t.treeListener),t.tree.on("update",t.treeListener)}function n(t){var r=this;if(arguments.length<2)throw Error("baobab.Combination: not enough arguments.");var n=arguments[1],o=s.arrayOf(arguments).slice(2);if(n instanceof Array&&(o=n.slice(1),n=n[0]),!a.Cursor(n))throw Error("baobab.Combination: argument should be a cursor.");if("or"!==t&&"and"!==t)throw Error("baobab.Combination: invalid operator.");i.call(this),this.cursors=[n],this.operators=[],this.tree=n.tree,this.updates=new Array(this.cursors.length),this.cursorListener=function(){r.updates[r.cursors.indexOf(this)]=!0},this.treeListener=function(){var t,e,n=r.updates[0];for(t=1,e=r.cursors.length;e>t;t++)n="or"===r.operators[t-1]?n||r.updates[t]:n&&r.updates[t];n&&r.emit("update"),r.updates=new Array(r.cursors.length)},this.bound=!1;var u=(this.on,this.once,function(){r.bound||(r.bound=!0,r.cursors.forEach(function(t){e(r,t)}))});this.on=s.before(u,this.on.bind(this)),this.once=s.before(u,this.once.bind(this)),o.forEach(function(r){this[t](r)},this)}function o(t){n.prototype[t]=function(r){if(!a.Cursor(r))throw this.release(),Error("baobab.Combination."+t+": argument should be a cursor.");if(~this.cursors.indexOf(r))throw this.release(),Error("baobab.Combination."+t+": cursor already in combination.");return this.cursors.push(r),this.operators.push(t),this.updates.length++,this.bound&&e(this,r),this}}var i=t("emmett"),s=t("./helpers.js"),a=t("./type.js");s.inherits(n,i),o("or"),o("and"),n.prototype.release=function(){this.cursors.forEach(function(t){t.off("update",this.cursorListener)},this),this.tree.off("update",this.treeListener),this.cursors=null,this.operators=null,this.tree=null,this.updates=null,this.kill()},r.exports=n},{"./helpers.js":7,"./type.js":10,emmett:3}],6:[function(t,r){function e(t,r,e,o){var a=this;n.call(this),r=r||[],this.tree=t,this.path=r,this.hash=o,this.complexPath=!!e,this.solvedPath=this.complexPath?e:this.path,this.relevant=void 0!==this.get(),this.updateHandler=function(t){var r,e,n,o,i,u,h=t.data.log,c=!1;if(a.complexPath&&(a.solvedPath=s.solvePath(a.tree.data,a.path)),!a.path.length)return a.emit("update");t:for(i=0,n=h.length;n>i;i++)for(r=h[i],u=0,o=r.length;o>u&&(e=r[u],e===""+a.solvedPath[u]);u++)if(u+1===o||u+1===a.solvedPath.length){c=!0;break t}var l=void 0!==a.get();a.relevant?l&&c?a.emit("update"):l||(a.emit("irrelevant"),a.relevant=!1):l&&c&&(a.emit("relevant"),a.emit("update"),a.relevant=!0)},this.mixin=i.cursor(this);var u=!1,h=function(){u||(u=!0,a.tree.on("update",a.updateHandler))};this.on=s.before(h,this.on.bind(this)),this.once=s.before(h,this.once.bind(this))}var n=t("emmett"),o=t("./combination.js"),i=t("./mixins.js"),s=t("./helpers.js"),a=t("./type.js");s.inherits(e,n),e.prototype.isRoot=function(){return!this.path.length},e.prototype.isLeaf=function(){return a.Primitive(this.get())},e.prototype.isBranch=function(){return!this.isLeaf()&&!this.isRoot()},e.prototype.root=function(){return this.tree.root()},e.prototype.select=function(t){if(arguments.length>1&&(t=s.arrayOf(arguments)),!a.Path(t))throw Error("baobab.Cursor.select: invalid path.");return this.tree.select(this.path.concat(t))},e.prototype.up=function(){return this.solvedPath&&this.solvedPath.length?this.tree.select(this.path.slice(0,-1)):null},e.prototype.left=function(){var t=+this.solvedPath[this.solvedPath.length-1];if(isNaN(t))throw Error("baobab.Cursor.left: cannot go left on a non-list type.");return t?this.tree.select(this.solvedPath.slice(0,-1).concat(t-1)):null},e.prototype.leftmost=function(){var t=+this.solvedPath[this.solvedPath.length-1];if(isNaN(t))throw Error("baobab.Cursor.leftmost: cannot go left on a non-list type.");return this.tree.select(this.solvedPath.slice(0,-1).concat(0))},e.prototype.right=function(){var t=+this.solvedPath[this.solvedPath.length-1];if(isNaN(t))throw Error("baobab.Cursor.right: cannot go right on a non-list type.");return t+1===this.up().get().length?null:this.tree.select(this.solvedPath.slice(0,-1).concat(t+1))},e.prototype.rightmost=function(){var t=+this.solvedPath[this.solvedPath.length-1];if(isNaN(t))throw Error("baobab.Cursor.right: cannot go right on a non-list type.");var r=this.up().get();return this.tree.select(this.solvedPath.slice(0,-1).concat(r.length-1))},e.prototype.down=function(){+this.solvedPath[this.solvedPath.length-1];return this.get()instanceof Array?this.tree.select(this.solvedPath.concat(0)):null},e.prototype.get=function(t){arguments.length>1&&(t=s.arrayOf(arguments));var r=this.solvedPath.concat((a.String(t)||a.Number(t)?[t]:t)||[]);return s.getIn(this.tree.data,r)},e.prototype.set=function(t,r){if(arguments.length<2)throw Error("baobab.Cursor.set: expecting at least key/value.");var e=this.get();if("object"!=typeof e)throw Error("baobab.Cursor.set: trying to set key to a non-object.");var n={};if(a.Array(t)){var o=s.solvePath(e,t);if(!o)throw Error("baobab.Cursor.set: could not solve dynamic path.");n=s.pathObject(o,{$set:r})}else n[t]={$set:r};return this.update(n)},e.prototype.edit=function(t){return this.update({$set:t})},e.prototype.unset=function(t){if(!t&&0!==t)throw Error("baobab.Cursor.unset: expects a valid key to unset.");if("object"!=typeof this.get())throw Error("baobab.Cursor.set: trying to set key to a non-object.");var r={};return r[t]={$unset:!0},this.update(r)},e.prototype.remove=function(){if(this.isRoot())throw Error("baobab.Cursor.remove: cannot remove root node.");return this.update({$unset:!0})},e.prototype.apply=function(t){if("function"!=typeof t)throw Error("baobab.Cursor.apply: argument is not a function.");return this.update({$apply:t})},e.prototype.chain=function(t){if("function"!=typeof t)throw Error("baobab.Cursor.chain: argument is not a function.");return this.update({$chain:t})},e.prototype.push=function(t){if(!(this.get()instanceof Array))throw Error("baobab.Cursor.push: trying to push to non-array value.");return this.update(arguments.length>1?{$push:s.arrayOf(arguments)}:{$push:t})},e.prototype.unshift=function(t){if(!(this.get()instanceof Array))throw Error("baobab.Cursor.push: trying to push to non-array value.");return this.update(arguments.length>1?{$unshift:s.arrayOf(arguments)}:{$unshift:t})},e.prototype.merge=function(t){if(!a.Object(t))throw Error("baobab.Cursor.merge: trying to merge a non-object.");if(!a.Object(this.get()))throw Error("baobab.Cursor.merge: trying to merge into a non-object.");this.update({$merge:t})},e.prototype.update=function(t){return this.tree.stack(s.pathObject(this.solvedPath,t)),this},e.prototype.or=function(t){return new o("or",this,t)},e.prototype.and=function(t){return new o("and",this,t)},e.prototype.release=function(){this.tree.off("update",this.updateHandler),this.hash&&delete this.tree._cursors[this.hash],delete this.tree,delete this.path,delete this.solvedPath,this.kill()},e.prototype.toJSON=function(){return this.get()},a.Cursor=function(t){return t instanceof e},r.exports=e},{"./combination.js":5,"./helpers.js":7,"./mixins.js":9,"./type.js":10,emmett:3}],7:[function(t,r){function e(t){return Array.prototype.slice.call(t)}function n(t,r){return function(){t(),r.apply(null,arguments)}}function o(t,r){var e,n={};for(e in t)n[e]=t[e];for(e in r)n[e]=r[e];return n}function i(t){var r=t.source,e="";return t.global&&(e+="g"),t.multiline&&(e+="m"),t.ignoreCase&&(e+="i"),t.sticky&&(e+="y"),t.unicode&&(e+="u"),new RegExp(r,e)}function s(t,r){if(!r||"object"!=typeof r||r instanceof Error||r instanceof ArrayBuffer)return r;if(g.Array(r)){if(t){var e,n,o=[];for(e=0,n=r.length;n>e;e++)o.push(v(r[e]));return o}return r.slice(0)}if(g.Date(r))return new Date(r.getTime());if(r instanceof RegExp)return i(r);if(g.Object(r)){var s,a={};r.constructor&&r.constructor!==Object&&(a=Object.create(r.constructor.prototype));for(s in r)r.hasOwnProperty(s)&&(a[s]=t?v(r[s]):r[s]);return a}return r}function a(t,r){return function(e){return r(t(e))}}function u(t,r){var e,n;for(e=0,n=t.length;n>e;e++)if(r(t[e]))return t[e]}function h(t,r){var e,n;for(e=0,n=t.length;n>e;e++)if(r(t[e]))return e;return-1}function c(t,r){var e,n=!0;if(!t)return!1;for(e in r)if(g.Object(r[e]))n=n&&c(t[e],r[e]);else if(g.Array(r[e]))n=n&&!!~r[e].indexOf(t[e]);else if(t[e]!==r[e])return!1;return n}function l(t,r){return u(t,function(t){return c(t,r)})}function f(t,r){return h(t,function(t){return c(t,r)})}function p(t,r){r=r||[];var e,n,o=t;for(e=0,n=r.length;n>e;e++){if(!o)return;if("function"==typeof r[e]){if(!g.Array(o))return;o=u(o,r[e])}else if("object"==typeof r[e]){if(!g.Array(o))return;o=l(o,r[e])}else o=o[r[e]]}return o}function d(t,r){var e,n,o,i=[],s=t;for(n=0,o=r.length;o>n;n++){if(!s)return null;if("function"==typeof r[n]){if(!g.Array(s))return;e=h(s,r[n]),i.push(e),s=s[e]}else if("object"==typeof r[n]){if(!g.Array(s))return;e=f(s,r[n]),i.push(e),s=s[e]}else i.push(r[n]),s=s[r[n]]||{}}return i}function b(t,r){var e,n=t.length,o={},i=o;for(n||(o=r),e=0;n>e;e++)i[t[e]]=e+1===n?r:{},i=i[t[e]];return o}function y(t,r){t.super_=r;var e=function(){};e.prototype=r.prototype,t.prototype=new e,t.prototype.constructor=t}var g=t("./type.js"),m=s.bind(null,!1),v=s.bind(null,!0);r.exports={arrayOf:e,before:n,deepClone:v,shallowClone:m,shallowMerge:o,compose:a,getIn:p,inherits:y,pathObject:b,solvePath:d}},{"./type.js":10}],8:[function(t,r){function e(t,r,e){s.forEach(function(r){e!==r&&delete t[r]}),t[e]=r[e]}function n(t,r){var a,u=o.shallowClone(r||{});s.forEach(function(r){t[r]&&e(u,t,r)}),t.$chain&&(s.slice(0,-1).forEach(function(t){delete u[t]}),u.$apply=u.$apply?o.compose(u.$apply,t.$chain):t.$chain),t.$push&&u.$push?u.$push=i.Array(u.$push)?u.$push.concat(t.$push):[u.$push].concat(t.$push):t.$push&&(u.$push=t.$push),t.$unshift&&u.$unshift?u.$unshift=i.Array(t.$unshift)?t.$unshift.concat(u.$unshift):[t.$unshift].concat(u.$unshift):t.$unshift&&(u.$unshift=t.$unshift);for(a in t)i.Object(t[a])?u[a]=n(t[a],u[a]):"$"!==a[0]&&(u[a]=t[a]);return u}var o=t("./helpers.js"),i=t("./type.js"),s=["$unset","$set","$merge","$apply"];r.exports=n},{"./helpers.js":7,"./type.js":10}],9:[function(t,r){var e=t("./combination.js"),n=t("./type.js");r.exports={baobab:function(t){return{mixins:[{getInitialState:function(){if(this.tree=t,!this.cursor&&!this.cursors)return{};if(this.cursor&&this.cursors)throw Error("baobab.mixin: you cannot have both `component.cursor` and `component.cursors`. Please make up your mind.");if(this.__type=null,this.__updateHandler=function(){this.setState(this.__getCursorData())}.bind(this),this.cursor){if(!n.MixinCursor(this.cursor))throw Error("baobab.mixin.cursor: invalid data (cursor, string, array or function).");n.Function(this.cursor)&&(this.cursor=this.cursor()),n.Cursor(this.cursor)||(this.cursor=t.select(this.cursor)),this.__getCursorData=function(){return{cursor:this.cursor.get()}}.bind(this),this.__type="single"}else if(this.cursors){if(!n.MixinCursors(this.cursors))throw Error("baobab.mixin.cursor: invalid data (object, array or function).");if(n.Function(this.cursors)&&(this.cursors=this.cursors()),n.Array(this.cursors))this.cursors=this.cursors.map(function(r){return n.Cursor(r)?r:t.select(r)}),this.__getCursorData=function(){return{cursors:this.cursors.map(function(t){return t.get()})}}.bind(this),this.__type="array";else{for(var r in this.cursors)n.Cursor(this.cursors[r])||(this.cursors[r]=t.select(this.cursors[r]));this.__getCursorData=function(){var t={};for(r in this.cursors)t[r]=this.cursors[r].get();return{cursors:t}}.bind(this),this.__type="object"}}return this.__getCursorData()},componentDidMount:function(){"single"===this.__type?(this.__combination=new e("or",[this.cursor]),this.__combination.on("update",this.__updateHandler)):"array"===this.__type?(this.__combination=new e("or",this.cursors),this.__combination.on("update",this.__updateHandler)):"object"===this.__type&&(this.__combination=new e("or",Object.keys(this.cursors).map(function(t){return this.cursors[t]},this)),this.__combination.on("update",this.__updateHandler))},componentWillUnmount:function(){this.__combination&&this.__combination.release()}}].concat(t.options.mixins)}},cursor:function(t){return{mixins:[{getInitialState:function(){return this.cursor=t,this.__updateHandler=function(){this.setState({cursor:this.cursor.get()})}.bind(this),{cursor:this.cursor.get()}},componentDidMount:function(){this.cursor.on("update",this.__updateHandler)},componentWillUnmount:function(){this.cursor.off("update",this.__updateHandler)}}].concat(t.tree.options.mixins)}}}},{"./combination.js":5,"./type.js":10}],10:[function(t,r){var e=function(t){return Array.isArray(t)?"array":"object"==typeof t&&null!==t?"object":"string"==typeof t?"string":"number"==typeof t?"number":"boolean"==typeof t?"boolean":"function"==typeof t?"function":null===t?"null":void 0===t?"undefined":t instanceof Date?"date":"invalid"};e.Array=function(t){return Array.isArray(t)},e.Object=function(t){return!Array.isArray(t)&&"object"==typeof t&&null!==t},e.String=function(t){return"string"==typeof t},e.Number=function(t){return"number"==typeof t},e.Boolean=function(t){return"boolean"==typeof t},e.Function=function(t){return"function"==typeof t},e.Primitive=function(t){return"string"==typeof t||"number"==typeof t||"boolean"==typeof t},e.Date=function(t){return t instanceof Date},e.Step=function(t){var r=e(t),n=["null","undefined","invalid","date"];return-1===n.indexOf(r)},e.Path=function(t){var r=["object","string","number","function","undefined"];if(!e.Array(t))return r.indexOf(e(t))>=0;for(var n=0;n=0||e.Cursor(t)},e.MixinCursors=function(t){var r=["array","object","function"];return r.indexOf(e(t))>=0},e.ComplexPath=function(t){for(var r=["object","function"],n=0;n=0)return!0;return!1},r.exports=e},{}],11:[function(t,r){function e(t,r){var e=new Error("baobab.update: "+r+" at path /"+t.slice(1).toString());return e.path=t,e}var n=t("./helpers.js"),o=t("./type.js");r.exports=function(t,r,i){if(i=i||{},!o.Object(t)&&!o.Array(t))throw Error("baobab.update: invalid target.");var s={};t={root:n.shallowClone(t)};var a=function(t,r,i,u){i=i||["root"];var h,c,l,f=i.join("λ"),p=i[i.length-1],d=Object.keys(r).some(function(t){return!!~["$unset","$set","$apply","$merge","$push","$unshift"].indexOf(t)});if(d){s[f]=!0;for(c in r){if("$unset"===c){var b=i[i.length-2];o.Array(t)?u[b]=t.slice(0,+p).concat(t.slice(+p+1)):(u[b]=n.shallowClone(t),delete u[b][p]);break}if("$set"===c){l=r.$set,t[p]=l;break}if("$apply"===c){if(h=r.$apply,"function"!=typeof h)throw e(i,"using command $apply with a non function");t[p]=h.call(null,t[p]);break}if("$merge"===c){if(l=r.$merge,!o.Object(t[p])||!o.Object(l))throw e(i,"using command $merge with a non object");t[p]=n.shallowMerge(t[p],l);break}if("$push"===c){if(l=r.$push,!o.Array(t[p]))throw e(i,"using command $push to a non array");t[p]=t[p].concat(l)}if("$unshift"===c){if(l=r.$unshift,!o.Array(t[p]))throw e(i,"using command $unshift to a non array");t[p]=[].concat(l).concat(t[p])}}}else for(c in r)t[p][c]="undefined"==typeof t[p][c]?{}:n.shallowClone(t[p][c]),a(t[p],r[c],i.concat(c),t)};return a(t,r),{data:t.root,log:Object.keys(s).map(function(t){return t.split("λ").slice(1)})}}},{"./helpers.js":7,"./type.js":10}]},{},[2])(2)}); \ No newline at end of file diff --git a/index.js b/index.js index 0a6de10..ba9f056 100644 --- a/index.js +++ b/index.js @@ -9,7 +9,7 @@ var Baobab = require('./src/baobab.js'), // Non-writable version Object.defineProperty(Baobab, 'version', { - value: '0.4.3' + value: '1.0.0-rc1' }); // Exposing helpers diff --git a/package.json b/package.json index 8598e4c..028f741 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "baobab", - "version": "0.4.3", + "version": "1.0.0-rc1", "description": "JavaScript data tree with cursors.", "main": "index.js", "dependencies": { From 49126b61b00b983a7e2d99d2dc91764184c2e5a5 Mon Sep 17 00:00:00 2001 From: Yomguithereal Date: Wed, 1 Apr 2015 15:33:12 +0200 Subject: [PATCH 16/73] Refactoring internal type checking --- build/baobab.min.js | 2 +- src/type.js | 82 ++++++++++++++------------------------------- 2 files changed, 27 insertions(+), 57 deletions(-) diff --git a/build/baobab.min.js b/build/baobab.min.js index ad084cf..96b3cdf 100644 --- a/build/baobab.min.js +++ b/build/baobab.min.js @@ -1,2 +1,2 @@ /* baobab.js - Version: 1.0.0-rc1 - Author: Yomguithereal (Guillaume Plique) */ -!function(t){if("object"==typeof exports&&"undefined"!=typeof module)module.exports=t();else if("function"==typeof define&&define.amd)define([],t);else{var r;r="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:this,r.Baobab=t()}}(function(){var t;return function r(t,e,n){function o(s,a){if(!e[s]){if(!t[s]){var u="function"==typeof require&&require;if(!a&&u)return u(s,!0);if(i)return i(s,!0);var h=new Error("Cannot find module '"+s+"'");throw h.code="MODULE_NOT_FOUND",h}var c=e[s]={exports:{}};t[s][0].call(c.exports,function(r){var e=t[s][1][r];return o(e?e:r)},c,c.exports,r,t,e,n)}return e[s].exports}for(var i="function"==typeof require&&require,s=0;sr;r++)n.push(t[r].handler);return n}var o={once:"boolean",scope:"object"},i=function(){this._enabled=!0,this._children=[],this._handlers={},this._handlersAll=[]};i.prototype.on=function(t,r,e){var n,s,a,u,h,c;if("function"==typeof r){for(h="string"==typeof t?[t]:t,n=0,s=h.length;n!==s;n+=1)if(u=h[n]){this._handlers[u]||(this._handlers[u]=[]),c={handler:r};for(a in e||{}){if(!o[a])throw new Error('The option "'+a+'" is not recognized by Emmett.');c[a]=e[a]}this._handlers[u].push(c)}}else if(t&&"object"==typeof t&&!Array.isArray(t))for(u in t)i.prototype.on.call(this,u,t[u],r);else{if("function"!=typeof t)throw new Error("Wrong arguments.");c={handler:t};for(a in e||{}){if(!o[a])throw new Error('The option "'+a+'" is not recognized by Emmett.');c[a]=e[a]}this._handlersAll.push(c)}return this},i.prototype.once=function(t,r,e){if("function"==typeof r)e=e||{},e.once=!0,this.on(t,r,e);else{if((!t||"object"!=typeof t||Array.isArray(t))&&"function"!=typeof t)throw new Error("Wrong arguments.");r=r||{},r.once=!0,this.on(t,r)}return this},i.prototype.off=function(t,r){var e,n,o,i,s,a,u,h="string"==typeof t?[t]:t;if(1===arguments.length&&"function"==typeof h){r=arguments[0];for(s in this._handlers){for(a=[],e=0,n=this._handlers[s].length;e!==n;e+=1)this._handlers[s][e].handler!==r&&a.push(this._handlers[s][e]);this._handlers[s]=a}for(a=[],e=0,n=this._handlersAll.length;e!==n;e+=1)this._handlersAll[e].handler!==r&&a.push(this._handlersAll[e]);this._handlersAll=a}else if(2===arguments.length)for(e=0,n=h.length;e!==n;e+=1){if(u=h[e],this._handlers[u]){for(a=[],o=0,i=this._handlers[u].length;o!==i;o+=1)this._handlers[u][o].handler!==r&&a.push(this._handlers[u][o]);this._handlers[u]=a}this._handlers[u]&&0===this._handlers[u].length&&delete this._handlers[u]}return this},i.prototype.unbindAll=function(){var t;this._handlersAll=[];for(t in this._handlers)delete this._handlers[t];return this},i.prototype.emit=function(t,r){var e,n,o,i,s,a,u,h,c,l,f="string"==typeof t?[t]:t;if(!this._enabled)return this;for(r=void 0===r?{}:r,e=0,n=f.length;e!==n;e+=1)if(l=f[e],c=(this._handlers[l]||[]).concat(this._handlersAll),c.length){for(u={type:l,data:r||{},target:this},a=[],o=0,i=c.length;o!==i;o+=1)(this._handlers[l]&&this._handlers[l].indexOf(c[o])>=0||this._handlersAll.indexOf(c[o])>=0)&&(c[o].handler.call("scope"in c[o]?c[o].scope:this,u),c[o].once&&a.push(c[o]));for(s=0;se;e++)if(t._children[e]===r){t._children.splice(e,1);break}}),this._children.push(r),r},i.prototype.listeners=function(t){var e,n,o,i=[];if(t)for(i=r(this._handlers[t]),n=0,o=this._children.length;o>n;n++)i=i.concat(this._children[n].listeners(t));else{i=r(this._handlersAll);for(e in this._handlers)i=i.concat(r(this._handlers[e]));for(n=0,o=this._children.length;o>n;n++)i=i.concat(this._children[n].listeners())}return i},i.prototype.kill=function(){if(this.emit("emmett:kill"),this.unbindAll(),this._handlers=null,this._handlersAll=null,this._enabled=!1,this._children)for(var t=0,r=this._children.length;r>t;t++)this._children[t].kill();this._children=null},i.prototype.disable=function(){return this._enabled=!1,this},i.prototype.enable=function(){return this._enabled=!0,this},i.version="2.1.2","undefined"!=typeof n?("undefined"!=typeof e&&e.exports&&(n=e.exports=i),n.Emitter=i):"function"==typeof t&&t.amd?t("emmett",[],function(){return i}):this.Emitter=i}).call(this)},{}],4:[function(t,r){function e(t){return t+"$"+(new Date).getTime()+(""+Math.random()).replace("0.","")}function n(t,r){function e(t){this[t]=function(){var r=this.root[t].apply(this.root,arguments);return r instanceof o?this:r}}if(arguments.length<1&&(t={}),!(this instanceof n))return new n(t,r);if(!l.Object(t)&&!l.Array(t))throw Error("Baobab: invalid data.");i.call(this),this.options=s.shallowMerge(c,r),this._transaction={},this._future=void 0,this._cursors={},this.data=s.deepClone(t),this.root=this.select([]),["get","set","unset","update"].forEach(e.bind(this)),this.mixin=h.baobab(this)}var o=t("./cursor.js"),i=t("emmett"),s=t("./helpers.js"),a=t("./update.js"),u=t("./merge.js"),h=t("./mixins.js"),c=t("../defaults.js"),l=t("./type.js");s.inherits(n,i),n.prototype.select=function(t){if(!t)throw Error("Baobab.select: invalid path.");if(arguments.length>1&&(t=s.arrayOf(arguments)),!l.Path(t))throw Error("Baobab.select: invalid path.");t=[].concat(t);var r,n=l.ComplexPath(t);n&&(r=s.solvePath(this.data,t));var i=t.map(function(t){return l.Function(t)?e("fn"):l.Object(t)?e("ob"):t}).join("λ");if(this._cursors[i])return this._cursors[i];var a=new o(this,t,r,i);return this._cursors[i]=a,a},n.prototype.stack=function(t){var r=this;if(!l.Object(t))throw Error("Baobab.update: wrong specification.");return this._transaction=u(t,this._transaction),this.options.autoCommit?this.options.asynchronous?(this._future||(this._future=setTimeout(r.commit.bind(r,null),0)),this):this.commit():this},n.prototype.commit=function(){var t=a(this.data,this._transaction,this.options);return this.data=t.data,this._transaction={},this._future&&(this._future=clearTimeout(this._future)),this.emit("update",{log:t.log}),this},n.prototype.release=function(){delete this.data,delete this._transaction;for(var t in this._cursors)this._cursors[t].release();delete this._cursors,this.kill()},n.prototype.toJSON=function(){return this.get()},r.exports=n},{"../defaults.js":1,"./cursor.js":6,"./helpers.js":7,"./merge.js":8,"./mixins.js":9,"./type.js":10,"./update.js":11,emmett:3}],5:[function(t,r){function e(t,r){r.on("update",t.cursorListener),t.tree.off("update",t.treeListener),t.tree.on("update",t.treeListener)}function n(t){var r=this;if(arguments.length<2)throw Error("baobab.Combination: not enough arguments.");var n=arguments[1],o=s.arrayOf(arguments).slice(2);if(n instanceof Array&&(o=n.slice(1),n=n[0]),!a.Cursor(n))throw Error("baobab.Combination: argument should be a cursor.");if("or"!==t&&"and"!==t)throw Error("baobab.Combination: invalid operator.");i.call(this),this.cursors=[n],this.operators=[],this.tree=n.tree,this.updates=new Array(this.cursors.length),this.cursorListener=function(){r.updates[r.cursors.indexOf(this)]=!0},this.treeListener=function(){var t,e,n=r.updates[0];for(t=1,e=r.cursors.length;e>t;t++)n="or"===r.operators[t-1]?n||r.updates[t]:n&&r.updates[t];n&&r.emit("update"),r.updates=new Array(r.cursors.length)},this.bound=!1;var u=(this.on,this.once,function(){r.bound||(r.bound=!0,r.cursors.forEach(function(t){e(r,t)}))});this.on=s.before(u,this.on.bind(this)),this.once=s.before(u,this.once.bind(this)),o.forEach(function(r){this[t](r)},this)}function o(t){n.prototype[t]=function(r){if(!a.Cursor(r))throw this.release(),Error("baobab.Combination."+t+": argument should be a cursor.");if(~this.cursors.indexOf(r))throw this.release(),Error("baobab.Combination."+t+": cursor already in combination.");return this.cursors.push(r),this.operators.push(t),this.updates.length++,this.bound&&e(this,r),this}}var i=t("emmett"),s=t("./helpers.js"),a=t("./type.js");s.inherits(n,i),o("or"),o("and"),n.prototype.release=function(){this.cursors.forEach(function(t){t.off("update",this.cursorListener)},this),this.tree.off("update",this.treeListener),this.cursors=null,this.operators=null,this.tree=null,this.updates=null,this.kill()},r.exports=n},{"./helpers.js":7,"./type.js":10,emmett:3}],6:[function(t,r){function e(t,r,e,o){var a=this;n.call(this),r=r||[],this.tree=t,this.path=r,this.hash=o,this.complexPath=!!e,this.solvedPath=this.complexPath?e:this.path,this.relevant=void 0!==this.get(),this.updateHandler=function(t){var r,e,n,o,i,u,h=t.data.log,c=!1;if(a.complexPath&&(a.solvedPath=s.solvePath(a.tree.data,a.path)),!a.path.length)return a.emit("update");t:for(i=0,n=h.length;n>i;i++)for(r=h[i],u=0,o=r.length;o>u&&(e=r[u],e===""+a.solvedPath[u]);u++)if(u+1===o||u+1===a.solvedPath.length){c=!0;break t}var l=void 0!==a.get();a.relevant?l&&c?a.emit("update"):l||(a.emit("irrelevant"),a.relevant=!1):l&&c&&(a.emit("relevant"),a.emit("update"),a.relevant=!0)},this.mixin=i.cursor(this);var u=!1,h=function(){u||(u=!0,a.tree.on("update",a.updateHandler))};this.on=s.before(h,this.on.bind(this)),this.once=s.before(h,this.once.bind(this))}var n=t("emmett"),o=t("./combination.js"),i=t("./mixins.js"),s=t("./helpers.js"),a=t("./type.js");s.inherits(e,n),e.prototype.isRoot=function(){return!this.path.length},e.prototype.isLeaf=function(){return a.Primitive(this.get())},e.prototype.isBranch=function(){return!this.isLeaf()&&!this.isRoot()},e.prototype.root=function(){return this.tree.root()},e.prototype.select=function(t){if(arguments.length>1&&(t=s.arrayOf(arguments)),!a.Path(t))throw Error("baobab.Cursor.select: invalid path.");return this.tree.select(this.path.concat(t))},e.prototype.up=function(){return this.solvedPath&&this.solvedPath.length?this.tree.select(this.path.slice(0,-1)):null},e.prototype.left=function(){var t=+this.solvedPath[this.solvedPath.length-1];if(isNaN(t))throw Error("baobab.Cursor.left: cannot go left on a non-list type.");return t?this.tree.select(this.solvedPath.slice(0,-1).concat(t-1)):null},e.prototype.leftmost=function(){var t=+this.solvedPath[this.solvedPath.length-1];if(isNaN(t))throw Error("baobab.Cursor.leftmost: cannot go left on a non-list type.");return this.tree.select(this.solvedPath.slice(0,-1).concat(0))},e.prototype.right=function(){var t=+this.solvedPath[this.solvedPath.length-1];if(isNaN(t))throw Error("baobab.Cursor.right: cannot go right on a non-list type.");return t+1===this.up().get().length?null:this.tree.select(this.solvedPath.slice(0,-1).concat(t+1))},e.prototype.rightmost=function(){var t=+this.solvedPath[this.solvedPath.length-1];if(isNaN(t))throw Error("baobab.Cursor.right: cannot go right on a non-list type.");var r=this.up().get();return this.tree.select(this.solvedPath.slice(0,-1).concat(r.length-1))},e.prototype.down=function(){+this.solvedPath[this.solvedPath.length-1];return this.get()instanceof Array?this.tree.select(this.solvedPath.concat(0)):null},e.prototype.get=function(t){arguments.length>1&&(t=s.arrayOf(arguments));var r=this.solvedPath.concat((a.String(t)||a.Number(t)?[t]:t)||[]);return s.getIn(this.tree.data,r)},e.prototype.set=function(t,r){if(arguments.length<2)throw Error("baobab.Cursor.set: expecting at least key/value.");var e=this.get();if("object"!=typeof e)throw Error("baobab.Cursor.set: trying to set key to a non-object.");var n={};if(a.Array(t)){var o=s.solvePath(e,t);if(!o)throw Error("baobab.Cursor.set: could not solve dynamic path.");n=s.pathObject(o,{$set:r})}else n[t]={$set:r};return this.update(n)},e.prototype.edit=function(t){return this.update({$set:t})},e.prototype.unset=function(t){if(!t&&0!==t)throw Error("baobab.Cursor.unset: expects a valid key to unset.");if("object"!=typeof this.get())throw Error("baobab.Cursor.set: trying to set key to a non-object.");var r={};return r[t]={$unset:!0},this.update(r)},e.prototype.remove=function(){if(this.isRoot())throw Error("baobab.Cursor.remove: cannot remove root node.");return this.update({$unset:!0})},e.prototype.apply=function(t){if("function"!=typeof t)throw Error("baobab.Cursor.apply: argument is not a function.");return this.update({$apply:t})},e.prototype.chain=function(t){if("function"!=typeof t)throw Error("baobab.Cursor.chain: argument is not a function.");return this.update({$chain:t})},e.prototype.push=function(t){if(!(this.get()instanceof Array))throw Error("baobab.Cursor.push: trying to push to non-array value.");return this.update(arguments.length>1?{$push:s.arrayOf(arguments)}:{$push:t})},e.prototype.unshift=function(t){if(!(this.get()instanceof Array))throw Error("baobab.Cursor.push: trying to push to non-array value.");return this.update(arguments.length>1?{$unshift:s.arrayOf(arguments)}:{$unshift:t})},e.prototype.merge=function(t){if(!a.Object(t))throw Error("baobab.Cursor.merge: trying to merge a non-object.");if(!a.Object(this.get()))throw Error("baobab.Cursor.merge: trying to merge into a non-object.");this.update({$merge:t})},e.prototype.update=function(t){return this.tree.stack(s.pathObject(this.solvedPath,t)),this},e.prototype.or=function(t){return new o("or",this,t)},e.prototype.and=function(t){return new o("and",this,t)},e.prototype.release=function(){this.tree.off("update",this.updateHandler),this.hash&&delete this.tree._cursors[this.hash],delete this.tree,delete this.path,delete this.solvedPath,this.kill()},e.prototype.toJSON=function(){return this.get()},a.Cursor=function(t){return t instanceof e},r.exports=e},{"./combination.js":5,"./helpers.js":7,"./mixins.js":9,"./type.js":10,emmett:3}],7:[function(t,r){function e(t){return Array.prototype.slice.call(t)}function n(t,r){return function(){t(),r.apply(null,arguments)}}function o(t,r){var e,n={};for(e in t)n[e]=t[e];for(e in r)n[e]=r[e];return n}function i(t){var r=t.source,e="";return t.global&&(e+="g"),t.multiline&&(e+="m"),t.ignoreCase&&(e+="i"),t.sticky&&(e+="y"),t.unicode&&(e+="u"),new RegExp(r,e)}function s(t,r){if(!r||"object"!=typeof r||r instanceof Error||r instanceof ArrayBuffer)return r;if(g.Array(r)){if(t){var e,n,o=[];for(e=0,n=r.length;n>e;e++)o.push(v(r[e]));return o}return r.slice(0)}if(g.Date(r))return new Date(r.getTime());if(r instanceof RegExp)return i(r);if(g.Object(r)){var s,a={};r.constructor&&r.constructor!==Object&&(a=Object.create(r.constructor.prototype));for(s in r)r.hasOwnProperty(s)&&(a[s]=t?v(r[s]):r[s]);return a}return r}function a(t,r){return function(e){return r(t(e))}}function u(t,r){var e,n;for(e=0,n=t.length;n>e;e++)if(r(t[e]))return t[e]}function h(t,r){var e,n;for(e=0,n=t.length;n>e;e++)if(r(t[e]))return e;return-1}function c(t,r){var e,n=!0;if(!t)return!1;for(e in r)if(g.Object(r[e]))n=n&&c(t[e],r[e]);else if(g.Array(r[e]))n=n&&!!~r[e].indexOf(t[e]);else if(t[e]!==r[e])return!1;return n}function l(t,r){return u(t,function(t){return c(t,r)})}function f(t,r){return h(t,function(t){return c(t,r)})}function p(t,r){r=r||[];var e,n,o=t;for(e=0,n=r.length;n>e;e++){if(!o)return;if("function"==typeof r[e]){if(!g.Array(o))return;o=u(o,r[e])}else if("object"==typeof r[e]){if(!g.Array(o))return;o=l(o,r[e])}else o=o[r[e]]}return o}function d(t,r){var e,n,o,i=[],s=t;for(n=0,o=r.length;o>n;n++){if(!s)return null;if("function"==typeof r[n]){if(!g.Array(s))return;e=h(s,r[n]),i.push(e),s=s[e]}else if("object"==typeof r[n]){if(!g.Array(s))return;e=f(s,r[n]),i.push(e),s=s[e]}else i.push(r[n]),s=s[r[n]]||{}}return i}function b(t,r){var e,n=t.length,o={},i=o;for(n||(o=r),e=0;n>e;e++)i[t[e]]=e+1===n?r:{},i=i[t[e]];return o}function y(t,r){t.super_=r;var e=function(){};e.prototype=r.prototype,t.prototype=new e,t.prototype.constructor=t}var g=t("./type.js"),m=s.bind(null,!1),v=s.bind(null,!0);r.exports={arrayOf:e,before:n,deepClone:v,shallowClone:m,shallowMerge:o,compose:a,getIn:p,inherits:y,pathObject:b,solvePath:d}},{"./type.js":10}],8:[function(t,r){function e(t,r,e){s.forEach(function(r){e!==r&&delete t[r]}),t[e]=r[e]}function n(t,r){var a,u=o.shallowClone(r||{});s.forEach(function(r){t[r]&&e(u,t,r)}),t.$chain&&(s.slice(0,-1).forEach(function(t){delete u[t]}),u.$apply=u.$apply?o.compose(u.$apply,t.$chain):t.$chain),t.$push&&u.$push?u.$push=i.Array(u.$push)?u.$push.concat(t.$push):[u.$push].concat(t.$push):t.$push&&(u.$push=t.$push),t.$unshift&&u.$unshift?u.$unshift=i.Array(t.$unshift)?t.$unshift.concat(u.$unshift):[t.$unshift].concat(u.$unshift):t.$unshift&&(u.$unshift=t.$unshift);for(a in t)i.Object(t[a])?u[a]=n(t[a],u[a]):"$"!==a[0]&&(u[a]=t[a]);return u}var o=t("./helpers.js"),i=t("./type.js"),s=["$unset","$set","$merge","$apply"];r.exports=n},{"./helpers.js":7,"./type.js":10}],9:[function(t,r){var e=t("./combination.js"),n=t("./type.js");r.exports={baobab:function(t){return{mixins:[{getInitialState:function(){if(this.tree=t,!this.cursor&&!this.cursors)return{};if(this.cursor&&this.cursors)throw Error("baobab.mixin: you cannot have both `component.cursor` and `component.cursors`. Please make up your mind.");if(this.__type=null,this.__updateHandler=function(){this.setState(this.__getCursorData())}.bind(this),this.cursor){if(!n.MixinCursor(this.cursor))throw Error("baobab.mixin.cursor: invalid data (cursor, string, array or function).");n.Function(this.cursor)&&(this.cursor=this.cursor()),n.Cursor(this.cursor)||(this.cursor=t.select(this.cursor)),this.__getCursorData=function(){return{cursor:this.cursor.get()}}.bind(this),this.__type="single"}else if(this.cursors){if(!n.MixinCursors(this.cursors))throw Error("baobab.mixin.cursor: invalid data (object, array or function).");if(n.Function(this.cursors)&&(this.cursors=this.cursors()),n.Array(this.cursors))this.cursors=this.cursors.map(function(r){return n.Cursor(r)?r:t.select(r)}),this.__getCursorData=function(){return{cursors:this.cursors.map(function(t){return t.get()})}}.bind(this),this.__type="array";else{for(var r in this.cursors)n.Cursor(this.cursors[r])||(this.cursors[r]=t.select(this.cursors[r]));this.__getCursorData=function(){var t={};for(r in this.cursors)t[r]=this.cursors[r].get();return{cursors:t}}.bind(this),this.__type="object"}}return this.__getCursorData()},componentDidMount:function(){"single"===this.__type?(this.__combination=new e("or",[this.cursor]),this.__combination.on("update",this.__updateHandler)):"array"===this.__type?(this.__combination=new e("or",this.cursors),this.__combination.on("update",this.__updateHandler)):"object"===this.__type&&(this.__combination=new e("or",Object.keys(this.cursors).map(function(t){return this.cursors[t]},this)),this.__combination.on("update",this.__updateHandler))},componentWillUnmount:function(){this.__combination&&this.__combination.release()}}].concat(t.options.mixins)}},cursor:function(t){return{mixins:[{getInitialState:function(){return this.cursor=t,this.__updateHandler=function(){this.setState({cursor:this.cursor.get()})}.bind(this),{cursor:this.cursor.get()}},componentDidMount:function(){this.cursor.on("update",this.__updateHandler)},componentWillUnmount:function(){this.cursor.off("update",this.__updateHandler)}}].concat(t.tree.options.mixins)}}}},{"./combination.js":5,"./type.js":10}],10:[function(t,r){var e=function(t){return Array.isArray(t)?"array":"object"==typeof t&&null!==t?"object":"string"==typeof t?"string":"number"==typeof t?"number":"boolean"==typeof t?"boolean":"function"==typeof t?"function":null===t?"null":void 0===t?"undefined":t instanceof Date?"date":"invalid"};e.Array=function(t){return Array.isArray(t)},e.Object=function(t){return!Array.isArray(t)&&"object"==typeof t&&null!==t},e.String=function(t){return"string"==typeof t},e.Number=function(t){return"number"==typeof t},e.Boolean=function(t){return"boolean"==typeof t},e.Function=function(t){return"function"==typeof t},e.Primitive=function(t){return"string"==typeof t||"number"==typeof t||"boolean"==typeof t},e.Date=function(t){return t instanceof Date},e.Step=function(t){var r=e(t),n=["null","undefined","invalid","date"];return-1===n.indexOf(r)},e.Path=function(t){var r=["object","string","number","function","undefined"];if(!e.Array(t))return r.indexOf(e(t))>=0;for(var n=0;n=0||e.Cursor(t)},e.MixinCursors=function(t){var r=["array","object","function"];return r.indexOf(e(t))>=0},e.ComplexPath=function(t){for(var r=["object","function"],n=0;n=0)return!0;return!1},r.exports=e},{}],11:[function(t,r){function e(t,r){var e=new Error("baobab.update: "+r+" at path /"+t.slice(1).toString());return e.path=t,e}var n=t("./helpers.js"),o=t("./type.js");r.exports=function(t,r,i){if(i=i||{},!o.Object(t)&&!o.Array(t))throw Error("baobab.update: invalid target.");var s={};t={root:n.shallowClone(t)};var a=function(t,r,i,u){i=i||["root"];var h,c,l,f=i.join("λ"),p=i[i.length-1],d=Object.keys(r).some(function(t){return!!~["$unset","$set","$apply","$merge","$push","$unshift"].indexOf(t)});if(d){s[f]=!0;for(c in r){if("$unset"===c){var b=i[i.length-2];o.Array(t)?u[b]=t.slice(0,+p).concat(t.slice(+p+1)):(u[b]=n.shallowClone(t),delete u[b][p]);break}if("$set"===c){l=r.$set,t[p]=l;break}if("$apply"===c){if(h=r.$apply,"function"!=typeof h)throw e(i,"using command $apply with a non function");t[p]=h.call(null,t[p]);break}if("$merge"===c){if(l=r.$merge,!o.Object(t[p])||!o.Object(l))throw e(i,"using command $merge with a non object");t[p]=n.shallowMerge(t[p],l);break}if("$push"===c){if(l=r.$push,!o.Array(t[p]))throw e(i,"using command $push to a non array");t[p]=t[p].concat(l)}if("$unshift"===c){if(l=r.$unshift,!o.Array(t[p]))throw e(i,"using command $unshift to a non array");t[p]=[].concat(l).concat(t[p])}}}else for(c in r)t[p][c]="undefined"==typeof t[p][c]?{}:n.shallowClone(t[p][c]),a(t[p],r[c],i.concat(c),t)};return a(t,r),{data:t.root,log:Object.keys(s).map(function(t){return t.split("λ").slice(1)})}}},{"./helpers.js":7,"./type.js":10}]},{},[2])(2)}); \ No newline at end of file +!function(t){if("object"==typeof exports&&"undefined"!=typeof module)module.exports=t();else if("function"==typeof define&&define.amd)define([],t);else{var r;r="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:this,r.Baobab=t()}}(function(){var t;return function r(t,e,n){function o(s,a){if(!e[s]){if(!t[s]){var h="function"==typeof require&&require;if(!a&&h)return h(s,!0);if(i)return i(s,!0);var u=new Error("Cannot find module '"+s+"'");throw u.code="MODULE_NOT_FOUND",u}var c=e[s]={exports:{}};t[s][0].call(c.exports,function(r){var e=t[s][1][r];return o(e?e:r)},c,c.exports,r,t,e,n)}return e[s].exports}for(var i="function"==typeof require&&require,s=0;sr;r++)n.push(t[r].handler);return n}var o={once:"boolean",scope:"object"},i=function(){this._enabled=!0,this._children=[],this._handlers={},this._handlersAll=[]};i.prototype.on=function(t,r,e){var n,s,a,h,u,c;if("function"==typeof r){for(u="string"==typeof t?[t]:t,n=0,s=u.length;n!==s;n+=1)if(h=u[n]){this._handlers[h]||(this._handlers[h]=[]),c={handler:r};for(a in e||{}){if(!o[a])throw new Error('The option "'+a+'" is not recognized by Emmett.');c[a]=e[a]}this._handlers[h].push(c)}}else if(t&&"object"==typeof t&&!Array.isArray(t))for(h in t)i.prototype.on.call(this,h,t[h],r);else{if("function"!=typeof t)throw new Error("Wrong arguments.");c={handler:t};for(a in e||{}){if(!o[a])throw new Error('The option "'+a+'" is not recognized by Emmett.');c[a]=e[a]}this._handlersAll.push(c)}return this},i.prototype.once=function(t,r,e){if("function"==typeof r)e=e||{},e.once=!0,this.on(t,r,e);else{if((!t||"object"!=typeof t||Array.isArray(t))&&"function"!=typeof t)throw new Error("Wrong arguments.");r=r||{},r.once=!0,this.on(t,r)}return this},i.prototype.off=function(t,r){var e,n,o,i,s,a,h,u="string"==typeof t?[t]:t;if(1===arguments.length&&"function"==typeof u){r=arguments[0];for(s in this._handlers){for(a=[],e=0,n=this._handlers[s].length;e!==n;e+=1)this._handlers[s][e].handler!==r&&a.push(this._handlers[s][e]);this._handlers[s]=a}for(a=[],e=0,n=this._handlersAll.length;e!==n;e+=1)this._handlersAll[e].handler!==r&&a.push(this._handlersAll[e]);this._handlersAll=a}else if(2===arguments.length)for(e=0,n=u.length;e!==n;e+=1){if(h=u[e],this._handlers[h]){for(a=[],o=0,i=this._handlers[h].length;o!==i;o+=1)this._handlers[h][o].handler!==r&&a.push(this._handlers[h][o]);this._handlers[h]=a}this._handlers[h]&&0===this._handlers[h].length&&delete this._handlers[h]}return this},i.prototype.unbindAll=function(){var t;this._handlersAll=[];for(t in this._handlers)delete this._handlers[t];return this},i.prototype.emit=function(t,r){var e,n,o,i,s,a,h,u,c,l,f="string"==typeof t?[t]:t;if(!this._enabled)return this;for(r=void 0===r?{}:r,e=0,n=f.length;e!==n;e+=1)if(l=f[e],c=(this._handlers[l]||[]).concat(this._handlersAll),c.length){for(h={type:l,data:r||{},target:this},a=[],o=0,i=c.length;o!==i;o+=1)(this._handlers[l]&&this._handlers[l].indexOf(c[o])>=0||this._handlersAll.indexOf(c[o])>=0)&&(c[o].handler.call("scope"in c[o]?c[o].scope:this,h),c[o].once&&a.push(c[o]));for(s=0;se;e++)if(t._children[e]===r){t._children.splice(e,1);break}}),this._children.push(r),r},i.prototype.listeners=function(t){var e,n,o,i=[];if(t)for(i=r(this._handlers[t]),n=0,o=this._children.length;o>n;n++)i=i.concat(this._children[n].listeners(t));else{i=r(this._handlersAll);for(e in this._handlers)i=i.concat(r(this._handlers[e]));for(n=0,o=this._children.length;o>n;n++)i=i.concat(this._children[n].listeners())}return i},i.prototype.kill=function(){if(this.emit("emmett:kill"),this.unbindAll(),this._handlers=null,this._handlersAll=null,this._enabled=!1,this._children)for(var t=0,r=this._children.length;r>t;t++)this._children[t].kill();this._children=null},i.prototype.disable=function(){return this._enabled=!1,this},i.prototype.enable=function(){return this._enabled=!0,this},i.version="2.1.2","undefined"!=typeof n?("undefined"!=typeof e&&e.exports&&(n=e.exports=i),n.Emitter=i):"function"==typeof t&&t.amd?t("emmett",[],function(){return i}):this.Emitter=i}).call(this)},{}],4:[function(t,r){function e(t){return t+"$"+(new Date).getTime()+(""+Math.random()).replace("0.","")}function n(t,r){function e(t){this[t]=function(){var r=this.root[t].apply(this.root,arguments);return r instanceof o?this:r}}if(arguments.length<1&&(t={}),!(this instanceof n))return new n(t,r);if(!l.Object(t)&&!l.Array(t))throw Error("Baobab: invalid data.");i.call(this),this.options=s.shallowMerge(c,r),this._transaction={},this._future=void 0,this._cursors={},this.data=s.deepClone(t),this.root=this.select([]),["get","set","unset","update"].forEach(e.bind(this)),this.mixin=u.baobab(this)}var o=t("./cursor.js"),i=t("emmett"),s=t("./helpers.js"),a=t("./update.js"),h=t("./merge.js"),u=t("./mixins.js"),c=t("../defaults.js"),l=t("./type.js");s.inherits(n,i),n.prototype.select=function(t){if(!t)throw Error("Baobab.select: invalid path.");if(arguments.length>1&&(t=s.arrayOf(arguments)),!l.Path(t))throw Error("Baobab.select: invalid path.");t=[].concat(t);var r,n=l.ComplexPath(t);n&&(r=s.solvePath(this.data,t));var i=t.map(function(t){return l.Function(t)?e("fn"):l.Object(t)?e("ob"):t}).join("λ");if(this._cursors[i])return this._cursors[i];var a=new o(this,t,r,i);return this._cursors[i]=a,a},n.prototype.stack=function(t){var r=this;if(!l.Object(t))throw Error("Baobab.update: wrong specification.");return this._transaction=h(t,this._transaction),this.options.autoCommit?this.options.asynchronous?(this._future||(this._future=setTimeout(r.commit.bind(r,null),0)),this):this.commit():this},n.prototype.commit=function(){var t=a(this.data,this._transaction,this.options);return this.data=t.data,this._transaction={},this._future&&(this._future=clearTimeout(this._future)),this.emit("update",{log:t.log}),this},n.prototype.release=function(){delete this.data,delete this._transaction;for(var t in this._cursors)this._cursors[t].release();delete this._cursors,this.kill()},n.prototype.toJSON=function(){return this.get()},r.exports=n},{"../defaults.js":1,"./cursor.js":6,"./helpers.js":7,"./merge.js":8,"./mixins.js":9,"./type.js":10,"./update.js":11,emmett:3}],5:[function(t,r){function e(t,r){r.on("update",t.cursorListener),t.tree.off("update",t.treeListener),t.tree.on("update",t.treeListener)}function n(t){var r=this;if(arguments.length<2)throw Error("baobab.Combination: not enough arguments.");var n=arguments[1],o=s.arrayOf(arguments).slice(2);if(n instanceof Array&&(o=n.slice(1),n=n[0]),!a.Cursor(n))throw Error("baobab.Combination: argument should be a cursor.");if("or"!==t&&"and"!==t)throw Error("baobab.Combination: invalid operator.");i.call(this),this.cursors=[n],this.operators=[],this.tree=n.tree,this.updates=new Array(this.cursors.length),this.cursorListener=function(){r.updates[r.cursors.indexOf(this)]=!0},this.treeListener=function(){var t,e,n=r.updates[0];for(t=1,e=r.cursors.length;e>t;t++)n="or"===r.operators[t-1]?n||r.updates[t]:n&&r.updates[t];n&&r.emit("update"),r.updates=new Array(r.cursors.length)},this.bound=!1;var h=(this.on,this.once,function(){r.bound||(r.bound=!0,r.cursors.forEach(function(t){e(r,t)}))});this.on=s.before(h,this.on.bind(this)),this.once=s.before(h,this.once.bind(this)),o.forEach(function(r){this[t](r)},this)}function o(t){n.prototype[t]=function(r){if(!a.Cursor(r))throw this.release(),Error("baobab.Combination."+t+": argument should be a cursor.");if(~this.cursors.indexOf(r))throw this.release(),Error("baobab.Combination."+t+": cursor already in combination.");return this.cursors.push(r),this.operators.push(t),this.updates.length++,this.bound&&e(this,r),this}}var i=t("emmett"),s=t("./helpers.js"),a=t("./type.js");s.inherits(n,i),o("or"),o("and"),n.prototype.release=function(){this.cursors.forEach(function(t){t.off("update",this.cursorListener)},this),this.tree.off("update",this.treeListener),this.cursors=null,this.operators=null,this.tree=null,this.updates=null,this.kill()},r.exports=n},{"./helpers.js":7,"./type.js":10,emmett:3}],6:[function(t,r){function e(t,r,e,o){var a=this;n.call(this),r=r||[],this.tree=t,this.path=r,this.hash=o,this.complexPath=!!e,this.solvedPath=this.complexPath?e:this.path,this.relevant=void 0!==this.get(),this.updateHandler=function(t){var r,e,n,o,i,h,u=t.data.log,c=!1;if(a.complexPath&&(a.solvedPath=s.solvePath(a.tree.data,a.path)),!a.path.length)return a.emit("update");t:for(i=0,n=u.length;n>i;i++)for(r=u[i],h=0,o=r.length;o>h&&(e=r[h],e===""+a.solvedPath[h]);h++)if(h+1===o||h+1===a.solvedPath.length){c=!0;break t}var l=void 0!==a.get();a.relevant?l&&c?a.emit("update"):l||(a.emit("irrelevant"),a.relevant=!1):l&&c&&(a.emit("relevant"),a.emit("update"),a.relevant=!0)},this.mixin=i.cursor(this);var h=!1,u=function(){h||(h=!0,a.tree.on("update",a.updateHandler))};this.on=s.before(u,this.on.bind(this)),this.once=s.before(u,this.once.bind(this))}var n=t("emmett"),o=t("./combination.js"),i=t("./mixins.js"),s=t("./helpers.js"),a=t("./type.js");s.inherits(e,n),e.prototype.isRoot=function(){return!this.path.length},e.prototype.isLeaf=function(){return a.Primitive(this.get())},e.prototype.isBranch=function(){return!this.isLeaf()&&!this.isRoot()},e.prototype.root=function(){return this.tree.root()},e.prototype.select=function(t){if(arguments.length>1&&(t=s.arrayOf(arguments)),!a.Path(t))throw Error("baobab.Cursor.select: invalid path.");return this.tree.select(this.path.concat(t))},e.prototype.up=function(){return this.solvedPath&&this.solvedPath.length?this.tree.select(this.path.slice(0,-1)):null},e.prototype.left=function(){var t=+this.solvedPath[this.solvedPath.length-1];if(isNaN(t))throw Error("baobab.Cursor.left: cannot go left on a non-list type.");return t?this.tree.select(this.solvedPath.slice(0,-1).concat(t-1)):null},e.prototype.leftmost=function(){var t=+this.solvedPath[this.solvedPath.length-1];if(isNaN(t))throw Error("baobab.Cursor.leftmost: cannot go left on a non-list type.");return this.tree.select(this.solvedPath.slice(0,-1).concat(0))},e.prototype.right=function(){var t=+this.solvedPath[this.solvedPath.length-1];if(isNaN(t))throw Error("baobab.Cursor.right: cannot go right on a non-list type.");return t+1===this.up().get().length?null:this.tree.select(this.solvedPath.slice(0,-1).concat(t+1))},e.prototype.rightmost=function(){var t=+this.solvedPath[this.solvedPath.length-1];if(isNaN(t))throw Error("baobab.Cursor.right: cannot go right on a non-list type.");var r=this.up().get();return this.tree.select(this.solvedPath.slice(0,-1).concat(r.length-1))},e.prototype.down=function(){+this.solvedPath[this.solvedPath.length-1];return this.get()instanceof Array?this.tree.select(this.solvedPath.concat(0)):null},e.prototype.get=function(t){arguments.length>1&&(t=s.arrayOf(arguments));var r=this.solvedPath.concat((a.String(t)||a.Number(t)?[t]:t)||[]);return s.getIn(this.tree.data,r)},e.prototype.set=function(t,r){if(arguments.length<2)throw Error("baobab.Cursor.set: expecting at least key/value.");var e=this.get();if("object"!=typeof e)throw Error("baobab.Cursor.set: trying to set key to a non-object.");var n={};if(a.Array(t)){var o=s.solvePath(e,t);if(!o)throw Error("baobab.Cursor.set: could not solve dynamic path.");n=s.pathObject(o,{$set:r})}else n[t]={$set:r};return this.update(n)},e.prototype.edit=function(t){return this.update({$set:t})},e.prototype.unset=function(t){if(!t&&0!==t)throw Error("baobab.Cursor.unset: expects a valid key to unset.");if("object"!=typeof this.get())throw Error("baobab.Cursor.set: trying to set key to a non-object.");var r={};return r[t]={$unset:!0},this.update(r)},e.prototype.remove=function(){if(this.isRoot())throw Error("baobab.Cursor.remove: cannot remove root node.");return this.update({$unset:!0})},e.prototype.apply=function(t){if("function"!=typeof t)throw Error("baobab.Cursor.apply: argument is not a function.");return this.update({$apply:t})},e.prototype.chain=function(t){if("function"!=typeof t)throw Error("baobab.Cursor.chain: argument is not a function.");return this.update({$chain:t})},e.prototype.push=function(t){if(!(this.get()instanceof Array))throw Error("baobab.Cursor.push: trying to push to non-array value.");return this.update(arguments.length>1?{$push:s.arrayOf(arguments)}:{$push:t})},e.prototype.unshift=function(t){if(!(this.get()instanceof Array))throw Error("baobab.Cursor.push: trying to push to non-array value.");return this.update(arguments.length>1?{$unshift:s.arrayOf(arguments)}:{$unshift:t})},e.prototype.merge=function(t){if(!a.Object(t))throw Error("baobab.Cursor.merge: trying to merge a non-object.");if(!a.Object(this.get()))throw Error("baobab.Cursor.merge: trying to merge into a non-object.");this.update({$merge:t})},e.prototype.update=function(t){return this.tree.stack(s.pathObject(this.solvedPath,t)),this},e.prototype.or=function(t){return new o("or",this,t)},e.prototype.and=function(t){return new o("and",this,t)},e.prototype.release=function(){this.tree.off("update",this.updateHandler),this.hash&&delete this.tree._cursors[this.hash],delete this.tree,delete this.path,delete this.solvedPath,this.kill()},e.prototype.toJSON=function(){return this.get()},a.Cursor=function(t){return t instanceof e},r.exports=e},{"./combination.js":5,"./helpers.js":7,"./mixins.js":9,"./type.js":10,emmett:3}],7:[function(t,r){function e(t){return Array.prototype.slice.call(t)}function n(t,r){return function(){t(),r.apply(null,arguments)}}function o(t,r){var e,n={};for(e in t)n[e]=t[e];for(e in r)n[e]=r[e];return n}function i(t){var r=t.source,e="";return t.global&&(e+="g"),t.multiline&&(e+="m"),t.ignoreCase&&(e+="i"),t.sticky&&(e+="y"),t.unicode&&(e+="u"),new RegExp(r,e)}function s(t,r){if(!r||"object"!=typeof r||r instanceof Error||r instanceof ArrayBuffer)return r;if(g.Array(r)){if(t){var e,n,o=[];for(e=0,n=r.length;n>e;e++)o.push(_(r[e]));return o}return r.slice(0)}if(g.Date(r))return new Date(r.getTime());if(r instanceof RegExp)return i(r);if(g.Object(r)){var s,a={};r.constructor&&r.constructor!==Object&&(a=Object.create(r.constructor.prototype));for(s in r)r.hasOwnProperty(s)&&(a[s]=t?_(r[s]):r[s]);return a}return r}function a(t,r){return function(e){return r(t(e))}}function h(t,r){var e,n;for(e=0,n=t.length;n>e;e++)if(r(t[e]))return t[e]}function u(t,r){var e,n;for(e=0,n=t.length;n>e;e++)if(r(t[e]))return e;return-1}function c(t,r){var e,n=!0;if(!t)return!1;for(e in r)if(g.Object(r[e]))n=n&&c(t[e],r[e]);else if(g.Array(r[e]))n=n&&!!~r[e].indexOf(t[e]);else if(t[e]!==r[e])return!1;return n}function l(t,r){return h(t,function(t){return c(t,r)})}function f(t,r){return u(t,function(t){return c(t,r)})}function p(t,r){r=r||[];var e,n,o=t;for(e=0,n=r.length;n>e;e++){if(!o)return;if("function"==typeof r[e]){if(!g.Array(o))return;o=h(o,r[e])}else if("object"==typeof r[e]){if(!g.Array(o))return;o=l(o,r[e])}else o=o[r[e]]}return o}function d(t,r){var e,n,o,i=[],s=t;for(n=0,o=r.length;o>n;n++){if(!s)return null;if("function"==typeof r[n]){if(!g.Array(s))return;e=u(s,r[n]),i.push(e),s=s[e]}else if("object"==typeof r[n]){if(!g.Array(s))return;e=f(s,r[n]),i.push(e),s=s[e]}else i.push(r[n]),s=s[r[n]]||{}}return i}function b(t,r){var e,n=t.length,o={},i=o;for(n||(o=r),e=0;n>e;e++)i[t[e]]=e+1===n?r:{},i=i[t[e]];return o}function y(t,r){t.super_=r;var e=function(){};e.prototype=r.prototype,t.prototype=new e,t.prototype.constructor=t}var g=t("./type.js"),m=s.bind(null,!1),_=s.bind(null,!0);r.exports={arrayOf:e,before:n,deepClone:_,shallowClone:m,shallowMerge:o,compose:a,getIn:p,inherits:y,pathObject:b,solvePath:d}},{"./type.js":10}],8:[function(t,r){function e(t,r,e){s.forEach(function(r){e!==r&&delete t[r]}),t[e]=r[e]}function n(t,r){var a,h=o.shallowClone(r||{});s.forEach(function(r){t[r]&&e(h,t,r)}),t.$chain&&(s.slice(0,-1).forEach(function(t){delete h[t]}),h.$apply=h.$apply?o.compose(h.$apply,t.$chain):t.$chain),t.$push&&h.$push?h.$push=i.Array(h.$push)?h.$push.concat(t.$push):[h.$push].concat(t.$push):t.$push&&(h.$push=t.$push),t.$unshift&&h.$unshift?h.$unshift=i.Array(t.$unshift)?t.$unshift.concat(h.$unshift):[t.$unshift].concat(h.$unshift):t.$unshift&&(h.$unshift=t.$unshift);for(a in t)i.Object(t[a])?h[a]=n(t[a],h[a]):"$"!==a[0]&&(h[a]=t[a]);return h}var o=t("./helpers.js"),i=t("./type.js"),s=["$unset","$set","$merge","$apply"];r.exports=n},{"./helpers.js":7,"./type.js":10}],9:[function(t,r){var e=t("./combination.js"),n=t("./type.js");r.exports={baobab:function(t){return{mixins:[{getInitialState:function(){if(this.tree=t,!this.cursor&&!this.cursors)return{};if(this.cursor&&this.cursors)throw Error("baobab.mixin: you cannot have both `component.cursor` and `component.cursors`. Please make up your mind.");if(this.__type=null,this.__updateHandler=function(){this.setState(this.__getCursorData())}.bind(this),this.cursor){if(!n.MixinCursor(this.cursor))throw Error("baobab.mixin.cursor: invalid data (cursor, string, array or function).");n.Function(this.cursor)&&(this.cursor=this.cursor()),n.Cursor(this.cursor)||(this.cursor=t.select(this.cursor)),this.__getCursorData=function(){return{cursor:this.cursor.get()}}.bind(this),this.__type="single"}else if(this.cursors){if(!n.MixinCursors(this.cursors))throw Error("baobab.mixin.cursor: invalid data (object, array or function).");if(n.Function(this.cursors)&&(this.cursors=this.cursors()),n.Array(this.cursors))this.cursors=this.cursors.map(function(r){return n.Cursor(r)?r:t.select(r)}),this.__getCursorData=function(){return{cursors:this.cursors.map(function(t){return t.get()})}}.bind(this),this.__type="array";else{for(var r in this.cursors)n.Cursor(this.cursors[r])||(this.cursors[r]=t.select(this.cursors[r]));this.__getCursorData=function(){var t={};for(r in this.cursors)t[r]=this.cursors[r].get();return{cursors:t}}.bind(this),this.__type="object"}}return this.__getCursorData()},componentDidMount:function(){"single"===this.__type?(this.__combination=new e("or",[this.cursor]),this.__combination.on("update",this.__updateHandler)):"array"===this.__type?(this.__combination=new e("or",this.cursors),this.__combination.on("update",this.__updateHandler)):"object"===this.__type&&(this.__combination=new e("or",Object.keys(this.cursors).map(function(t){return this.cursors[t]},this)),this.__combination.on("update",this.__updateHandler))},componentWillUnmount:function(){this.__combination&&this.__combination.release()}}].concat(t.options.mixins)}},cursor:function(t){return{mixins:[{getInitialState:function(){return this.cursor=t,this.__updateHandler=function(){this.setState({cursor:this.cursor.get()})}.bind(this),{cursor:this.cursor.get()}},componentDidMount:function(){this.cursor.on("update",this.__updateHandler)},componentWillUnmount:function(){this.cursor.off("update",this.__updateHandler)}}].concat(t.tree.options.mixins)}}}},{"./combination.js":5,"./type.js":10}],10:[function(t,r){function e(t,r){return r.some(function(r){return n[r](t)})}var n={};n.Array=function(t){return Array.isArray(t)},n.Object=function(t){return!Array.isArray(t)&&"object"==typeof t&&null!==t},n.String=function(t){return"string"==typeof t},n.Number=function(t){return"number"==typeof t},n.Boolean=function(t){return"boolean"==typeof t},n.Function=function(t){return"function"==typeof t},n.Primitive=function(t){return"string"==typeof t||"number"==typeof t||"boolean"==typeof t},n.Date=function(t){return t instanceof Date},n.Path=function(t){var r=["String","Number","Function","Object"];return n.Array(t)?t.every(function(t){return e(t,r)}):e(t,r)},n.MixinCursor=function(t){return e(t,["String","Number","Array","Function","Cursor"])},n.MixinCursors=function(t){return e(t,["Object","Array","Function"])},n.ComplexPath=function(t){return e(t,["Object","Function"])},r.exports=n},{}],11:[function(t,r){function e(t,r){var e=new Error("baobab.update: "+r+" at path /"+t.slice(1).toString());return e.path=t,e}var n=t("./helpers.js"),o=t("./type.js");r.exports=function(t,r,i){if(i=i||{},!o.Object(t)&&!o.Array(t))throw Error("baobab.update: invalid target.");var s={};t={root:n.shallowClone(t)};var a=function(t,r,i,h){i=i||["root"];var u,c,l,f=i.join("λ"),p=i[i.length-1],d=Object.keys(r).some(function(t){return!!~["$unset","$set","$apply","$merge","$push","$unshift"].indexOf(t)});if(d){s[f]=!0;for(c in r){if("$unset"===c){var b=i[i.length-2];o.Array(t)?h[b]=t.slice(0,+p).concat(t.slice(+p+1)):(h[b]=n.shallowClone(t),delete h[b][p]);break}if("$set"===c){l=r.$set,t[p]=l;break}if("$apply"===c){if(u=r.$apply,"function"!=typeof u)throw e(i,"using command $apply with a non function");t[p]=u.call(null,t[p]);break}if("$merge"===c){if(l=r.$merge,!o.Object(t[p])||!o.Object(l))throw e(i,"using command $merge with a non object");t[p]=n.shallowMerge(t[p],l);break}if("$push"===c){if(l=r.$push,!o.Array(t[p]))throw e(i,"using command $push to a non array");t[p]=t[p].concat(l)}if("$unshift"===c){if(l=r.$unshift,!o.Array(t[p]))throw e(i,"using command $unshift to a non array");t[p]=[].concat(l).concat(t[p])}}}else for(c in r)t[p][c]="undefined"==typeof t[p][c]?{}:n.shallowClone(t[p][c]),a(t[p],r[c],i.concat(c),t)};return a(t,r),{data:t.root,log:Object.keys(s).map(function(t){return t.split("λ").slice(1)})}}},{"./helpers.js":7,"./type.js":10}]},{},[2])(2)}); \ No newline at end of file diff --git a/src/type.js b/src/type.js index c8b7cee..5070b10 100644 --- a/src/type.js +++ b/src/type.js @@ -7,33 +7,20 @@ * * @christianalfoni */ +var type = {}; -// Not reusing methods as it will just be an extra -// call on the stack -var type = function (value) { - if (Array.isArray(value)) { - return 'array'; - } else if (typeof value === 'object' && value !== null) { - return 'object'; - } else if (typeof value === 'string') { - return 'string'; - } else if (typeof value === 'number') { - return 'number'; - } else if (typeof value === 'boolean') { - return 'boolean'; - } else if (typeof value === 'function') { - return 'function'; - } else if (value === null) { - return 'null'; - } else if (value === undefined) { - return 'undefined'; - } else if (value instanceof Date) { - return 'date'; - } else { - return 'invalid'; - } -}; +/** + * Helpers + */ +function anyOf(value, allowed) { + return allowed.some(function(t) { + return type[t](value); + }) +} +/** + * Simple types + */ type.Array = function (value) { return Array.isArray(value); }; @@ -66,49 +53,32 @@ type.Date = function (value) { return value instanceof Date; }; -type.Step = function (value) { - var valueType = type(value); - var notValid = ['null', 'undefined', 'invalid', 'date']; - return notValid.indexOf(valueType) === -1; -}; - -// Should undefined be allowed? +/** + * Complex types + */ type.Path = function (value) { - var types = ['object', 'string', 'number', 'function', 'undefined']; + var allowed = ['String', 'Number', 'Function', 'Object']; + if (type.Array(value)) { - for (var x = 0; x < value.length; x++) { - if (types.indexOf(type(value[x])) === -1) { - return false; - } - } - } else { - return types.indexOf(type(value)) >= 0; + return value.every(function(step) { + return anyOf(step, allowed); + }); + } + else { + return anyOf(value, allowed); } - return true; - }; -// string|number|array|cursor|function type.MixinCursor = function (value) { - var allowedValues = ['string', 'number', 'array', 'function']; - return allowedValues.indexOf(type(value)) >= 0 || type.Cursor(value); + return anyOf(value, ['String', 'Number', 'Array', 'Function', 'Cursor']); }; -// array|object|function type.MixinCursors = function (value) { - var allowedValues = ['array', 'object', 'function']; - return allowedValues.indexOf(type(value)) >= 0; + return anyOf(value, ['Object', 'Array', 'Function']); }; -// Already know this is an array type.ComplexPath = function (value) { - var complexTypes = ['object', 'function']; - for (var x = 0; x < value.length; x++) { - if (complexTypes.indexOf(type(value[x])) >= 0) { - return true; - } - } - return false; + return anyOf(value, ['Object', 'Function']); }; module.exports = type; From 6b4cc23e21058052db6677b523fb71ab30e4b89d Mon Sep 17 00:00:00 2001 From: Yomguithereal Date: Wed, 1 Apr 2015 15:37:53 +0200 Subject: [PATCH 17/73] Removing unused code --- build/baobab.min.js | 2 +- src/type.js | 4 ---- 2 files changed, 1 insertion(+), 5 deletions(-) diff --git a/build/baobab.min.js b/build/baobab.min.js index 96b3cdf..96835dc 100644 --- a/build/baobab.min.js +++ b/build/baobab.min.js @@ -1,2 +1,2 @@ /* baobab.js - Version: 1.0.0-rc1 - Author: Yomguithereal (Guillaume Plique) */ -!function(t){if("object"==typeof exports&&"undefined"!=typeof module)module.exports=t();else if("function"==typeof define&&define.amd)define([],t);else{var r;r="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:this,r.Baobab=t()}}(function(){var t;return function r(t,e,n){function o(s,a){if(!e[s]){if(!t[s]){var h="function"==typeof require&&require;if(!a&&h)return h(s,!0);if(i)return i(s,!0);var u=new Error("Cannot find module '"+s+"'");throw u.code="MODULE_NOT_FOUND",u}var c=e[s]={exports:{}};t[s][0].call(c.exports,function(r){var e=t[s][1][r];return o(e?e:r)},c,c.exports,r,t,e,n)}return e[s].exports}for(var i="function"==typeof require&&require,s=0;sr;r++)n.push(t[r].handler);return n}var o={once:"boolean",scope:"object"},i=function(){this._enabled=!0,this._children=[],this._handlers={},this._handlersAll=[]};i.prototype.on=function(t,r,e){var n,s,a,h,u,c;if("function"==typeof r){for(u="string"==typeof t?[t]:t,n=0,s=u.length;n!==s;n+=1)if(h=u[n]){this._handlers[h]||(this._handlers[h]=[]),c={handler:r};for(a in e||{}){if(!o[a])throw new Error('The option "'+a+'" is not recognized by Emmett.');c[a]=e[a]}this._handlers[h].push(c)}}else if(t&&"object"==typeof t&&!Array.isArray(t))for(h in t)i.prototype.on.call(this,h,t[h],r);else{if("function"!=typeof t)throw new Error("Wrong arguments.");c={handler:t};for(a in e||{}){if(!o[a])throw new Error('The option "'+a+'" is not recognized by Emmett.');c[a]=e[a]}this._handlersAll.push(c)}return this},i.prototype.once=function(t,r,e){if("function"==typeof r)e=e||{},e.once=!0,this.on(t,r,e);else{if((!t||"object"!=typeof t||Array.isArray(t))&&"function"!=typeof t)throw new Error("Wrong arguments.");r=r||{},r.once=!0,this.on(t,r)}return this},i.prototype.off=function(t,r){var e,n,o,i,s,a,h,u="string"==typeof t?[t]:t;if(1===arguments.length&&"function"==typeof u){r=arguments[0];for(s in this._handlers){for(a=[],e=0,n=this._handlers[s].length;e!==n;e+=1)this._handlers[s][e].handler!==r&&a.push(this._handlers[s][e]);this._handlers[s]=a}for(a=[],e=0,n=this._handlersAll.length;e!==n;e+=1)this._handlersAll[e].handler!==r&&a.push(this._handlersAll[e]);this._handlersAll=a}else if(2===arguments.length)for(e=0,n=u.length;e!==n;e+=1){if(h=u[e],this._handlers[h]){for(a=[],o=0,i=this._handlers[h].length;o!==i;o+=1)this._handlers[h][o].handler!==r&&a.push(this._handlers[h][o]);this._handlers[h]=a}this._handlers[h]&&0===this._handlers[h].length&&delete this._handlers[h]}return this},i.prototype.unbindAll=function(){var t;this._handlersAll=[];for(t in this._handlers)delete this._handlers[t];return this},i.prototype.emit=function(t,r){var e,n,o,i,s,a,h,u,c,l,f="string"==typeof t?[t]:t;if(!this._enabled)return this;for(r=void 0===r?{}:r,e=0,n=f.length;e!==n;e+=1)if(l=f[e],c=(this._handlers[l]||[]).concat(this._handlersAll),c.length){for(h={type:l,data:r||{},target:this},a=[],o=0,i=c.length;o!==i;o+=1)(this._handlers[l]&&this._handlers[l].indexOf(c[o])>=0||this._handlersAll.indexOf(c[o])>=0)&&(c[o].handler.call("scope"in c[o]?c[o].scope:this,h),c[o].once&&a.push(c[o]));for(s=0;se;e++)if(t._children[e]===r){t._children.splice(e,1);break}}),this._children.push(r),r},i.prototype.listeners=function(t){var e,n,o,i=[];if(t)for(i=r(this._handlers[t]),n=0,o=this._children.length;o>n;n++)i=i.concat(this._children[n].listeners(t));else{i=r(this._handlersAll);for(e in this._handlers)i=i.concat(r(this._handlers[e]));for(n=0,o=this._children.length;o>n;n++)i=i.concat(this._children[n].listeners())}return i},i.prototype.kill=function(){if(this.emit("emmett:kill"),this.unbindAll(),this._handlers=null,this._handlersAll=null,this._enabled=!1,this._children)for(var t=0,r=this._children.length;r>t;t++)this._children[t].kill();this._children=null},i.prototype.disable=function(){return this._enabled=!1,this},i.prototype.enable=function(){return this._enabled=!0,this},i.version="2.1.2","undefined"!=typeof n?("undefined"!=typeof e&&e.exports&&(n=e.exports=i),n.Emitter=i):"function"==typeof t&&t.amd?t("emmett",[],function(){return i}):this.Emitter=i}).call(this)},{}],4:[function(t,r){function e(t){return t+"$"+(new Date).getTime()+(""+Math.random()).replace("0.","")}function n(t,r){function e(t){this[t]=function(){var r=this.root[t].apply(this.root,arguments);return r instanceof o?this:r}}if(arguments.length<1&&(t={}),!(this instanceof n))return new n(t,r);if(!l.Object(t)&&!l.Array(t))throw Error("Baobab: invalid data.");i.call(this),this.options=s.shallowMerge(c,r),this._transaction={},this._future=void 0,this._cursors={},this.data=s.deepClone(t),this.root=this.select([]),["get","set","unset","update"].forEach(e.bind(this)),this.mixin=u.baobab(this)}var o=t("./cursor.js"),i=t("emmett"),s=t("./helpers.js"),a=t("./update.js"),h=t("./merge.js"),u=t("./mixins.js"),c=t("../defaults.js"),l=t("./type.js");s.inherits(n,i),n.prototype.select=function(t){if(!t)throw Error("Baobab.select: invalid path.");if(arguments.length>1&&(t=s.arrayOf(arguments)),!l.Path(t))throw Error("Baobab.select: invalid path.");t=[].concat(t);var r,n=l.ComplexPath(t);n&&(r=s.solvePath(this.data,t));var i=t.map(function(t){return l.Function(t)?e("fn"):l.Object(t)?e("ob"):t}).join("λ");if(this._cursors[i])return this._cursors[i];var a=new o(this,t,r,i);return this._cursors[i]=a,a},n.prototype.stack=function(t){var r=this;if(!l.Object(t))throw Error("Baobab.update: wrong specification.");return this._transaction=h(t,this._transaction),this.options.autoCommit?this.options.asynchronous?(this._future||(this._future=setTimeout(r.commit.bind(r,null),0)),this):this.commit():this},n.prototype.commit=function(){var t=a(this.data,this._transaction,this.options);return this.data=t.data,this._transaction={},this._future&&(this._future=clearTimeout(this._future)),this.emit("update",{log:t.log}),this},n.prototype.release=function(){delete this.data,delete this._transaction;for(var t in this._cursors)this._cursors[t].release();delete this._cursors,this.kill()},n.prototype.toJSON=function(){return this.get()},r.exports=n},{"../defaults.js":1,"./cursor.js":6,"./helpers.js":7,"./merge.js":8,"./mixins.js":9,"./type.js":10,"./update.js":11,emmett:3}],5:[function(t,r){function e(t,r){r.on("update",t.cursorListener),t.tree.off("update",t.treeListener),t.tree.on("update",t.treeListener)}function n(t){var r=this;if(arguments.length<2)throw Error("baobab.Combination: not enough arguments.");var n=arguments[1],o=s.arrayOf(arguments).slice(2);if(n instanceof Array&&(o=n.slice(1),n=n[0]),!a.Cursor(n))throw Error("baobab.Combination: argument should be a cursor.");if("or"!==t&&"and"!==t)throw Error("baobab.Combination: invalid operator.");i.call(this),this.cursors=[n],this.operators=[],this.tree=n.tree,this.updates=new Array(this.cursors.length),this.cursorListener=function(){r.updates[r.cursors.indexOf(this)]=!0},this.treeListener=function(){var t,e,n=r.updates[0];for(t=1,e=r.cursors.length;e>t;t++)n="or"===r.operators[t-1]?n||r.updates[t]:n&&r.updates[t];n&&r.emit("update"),r.updates=new Array(r.cursors.length)},this.bound=!1;var h=(this.on,this.once,function(){r.bound||(r.bound=!0,r.cursors.forEach(function(t){e(r,t)}))});this.on=s.before(h,this.on.bind(this)),this.once=s.before(h,this.once.bind(this)),o.forEach(function(r){this[t](r)},this)}function o(t){n.prototype[t]=function(r){if(!a.Cursor(r))throw this.release(),Error("baobab.Combination."+t+": argument should be a cursor.");if(~this.cursors.indexOf(r))throw this.release(),Error("baobab.Combination."+t+": cursor already in combination.");return this.cursors.push(r),this.operators.push(t),this.updates.length++,this.bound&&e(this,r),this}}var i=t("emmett"),s=t("./helpers.js"),a=t("./type.js");s.inherits(n,i),o("or"),o("and"),n.prototype.release=function(){this.cursors.forEach(function(t){t.off("update",this.cursorListener)},this),this.tree.off("update",this.treeListener),this.cursors=null,this.operators=null,this.tree=null,this.updates=null,this.kill()},r.exports=n},{"./helpers.js":7,"./type.js":10,emmett:3}],6:[function(t,r){function e(t,r,e,o){var a=this;n.call(this),r=r||[],this.tree=t,this.path=r,this.hash=o,this.complexPath=!!e,this.solvedPath=this.complexPath?e:this.path,this.relevant=void 0!==this.get(),this.updateHandler=function(t){var r,e,n,o,i,h,u=t.data.log,c=!1;if(a.complexPath&&(a.solvedPath=s.solvePath(a.tree.data,a.path)),!a.path.length)return a.emit("update");t:for(i=0,n=u.length;n>i;i++)for(r=u[i],h=0,o=r.length;o>h&&(e=r[h],e===""+a.solvedPath[h]);h++)if(h+1===o||h+1===a.solvedPath.length){c=!0;break t}var l=void 0!==a.get();a.relevant?l&&c?a.emit("update"):l||(a.emit("irrelevant"),a.relevant=!1):l&&c&&(a.emit("relevant"),a.emit("update"),a.relevant=!0)},this.mixin=i.cursor(this);var h=!1,u=function(){h||(h=!0,a.tree.on("update",a.updateHandler))};this.on=s.before(u,this.on.bind(this)),this.once=s.before(u,this.once.bind(this))}var n=t("emmett"),o=t("./combination.js"),i=t("./mixins.js"),s=t("./helpers.js"),a=t("./type.js");s.inherits(e,n),e.prototype.isRoot=function(){return!this.path.length},e.prototype.isLeaf=function(){return a.Primitive(this.get())},e.prototype.isBranch=function(){return!this.isLeaf()&&!this.isRoot()},e.prototype.root=function(){return this.tree.root()},e.prototype.select=function(t){if(arguments.length>1&&(t=s.arrayOf(arguments)),!a.Path(t))throw Error("baobab.Cursor.select: invalid path.");return this.tree.select(this.path.concat(t))},e.prototype.up=function(){return this.solvedPath&&this.solvedPath.length?this.tree.select(this.path.slice(0,-1)):null},e.prototype.left=function(){var t=+this.solvedPath[this.solvedPath.length-1];if(isNaN(t))throw Error("baobab.Cursor.left: cannot go left on a non-list type.");return t?this.tree.select(this.solvedPath.slice(0,-1).concat(t-1)):null},e.prototype.leftmost=function(){var t=+this.solvedPath[this.solvedPath.length-1];if(isNaN(t))throw Error("baobab.Cursor.leftmost: cannot go left on a non-list type.");return this.tree.select(this.solvedPath.slice(0,-1).concat(0))},e.prototype.right=function(){var t=+this.solvedPath[this.solvedPath.length-1];if(isNaN(t))throw Error("baobab.Cursor.right: cannot go right on a non-list type.");return t+1===this.up().get().length?null:this.tree.select(this.solvedPath.slice(0,-1).concat(t+1))},e.prototype.rightmost=function(){var t=+this.solvedPath[this.solvedPath.length-1];if(isNaN(t))throw Error("baobab.Cursor.right: cannot go right on a non-list type.");var r=this.up().get();return this.tree.select(this.solvedPath.slice(0,-1).concat(r.length-1))},e.prototype.down=function(){+this.solvedPath[this.solvedPath.length-1];return this.get()instanceof Array?this.tree.select(this.solvedPath.concat(0)):null},e.prototype.get=function(t){arguments.length>1&&(t=s.arrayOf(arguments));var r=this.solvedPath.concat((a.String(t)||a.Number(t)?[t]:t)||[]);return s.getIn(this.tree.data,r)},e.prototype.set=function(t,r){if(arguments.length<2)throw Error("baobab.Cursor.set: expecting at least key/value.");var e=this.get();if("object"!=typeof e)throw Error("baobab.Cursor.set: trying to set key to a non-object.");var n={};if(a.Array(t)){var o=s.solvePath(e,t);if(!o)throw Error("baobab.Cursor.set: could not solve dynamic path.");n=s.pathObject(o,{$set:r})}else n[t]={$set:r};return this.update(n)},e.prototype.edit=function(t){return this.update({$set:t})},e.prototype.unset=function(t){if(!t&&0!==t)throw Error("baobab.Cursor.unset: expects a valid key to unset.");if("object"!=typeof this.get())throw Error("baobab.Cursor.set: trying to set key to a non-object.");var r={};return r[t]={$unset:!0},this.update(r)},e.prototype.remove=function(){if(this.isRoot())throw Error("baobab.Cursor.remove: cannot remove root node.");return this.update({$unset:!0})},e.prototype.apply=function(t){if("function"!=typeof t)throw Error("baobab.Cursor.apply: argument is not a function.");return this.update({$apply:t})},e.prototype.chain=function(t){if("function"!=typeof t)throw Error("baobab.Cursor.chain: argument is not a function.");return this.update({$chain:t})},e.prototype.push=function(t){if(!(this.get()instanceof Array))throw Error("baobab.Cursor.push: trying to push to non-array value.");return this.update(arguments.length>1?{$push:s.arrayOf(arguments)}:{$push:t})},e.prototype.unshift=function(t){if(!(this.get()instanceof Array))throw Error("baobab.Cursor.push: trying to push to non-array value.");return this.update(arguments.length>1?{$unshift:s.arrayOf(arguments)}:{$unshift:t})},e.prototype.merge=function(t){if(!a.Object(t))throw Error("baobab.Cursor.merge: trying to merge a non-object.");if(!a.Object(this.get()))throw Error("baobab.Cursor.merge: trying to merge into a non-object.");this.update({$merge:t})},e.prototype.update=function(t){return this.tree.stack(s.pathObject(this.solvedPath,t)),this},e.prototype.or=function(t){return new o("or",this,t)},e.prototype.and=function(t){return new o("and",this,t)},e.prototype.release=function(){this.tree.off("update",this.updateHandler),this.hash&&delete this.tree._cursors[this.hash],delete this.tree,delete this.path,delete this.solvedPath,this.kill()},e.prototype.toJSON=function(){return this.get()},a.Cursor=function(t){return t instanceof e},r.exports=e},{"./combination.js":5,"./helpers.js":7,"./mixins.js":9,"./type.js":10,emmett:3}],7:[function(t,r){function e(t){return Array.prototype.slice.call(t)}function n(t,r){return function(){t(),r.apply(null,arguments)}}function o(t,r){var e,n={};for(e in t)n[e]=t[e];for(e in r)n[e]=r[e];return n}function i(t){var r=t.source,e="";return t.global&&(e+="g"),t.multiline&&(e+="m"),t.ignoreCase&&(e+="i"),t.sticky&&(e+="y"),t.unicode&&(e+="u"),new RegExp(r,e)}function s(t,r){if(!r||"object"!=typeof r||r instanceof Error||r instanceof ArrayBuffer)return r;if(g.Array(r)){if(t){var e,n,o=[];for(e=0,n=r.length;n>e;e++)o.push(_(r[e]));return o}return r.slice(0)}if(g.Date(r))return new Date(r.getTime());if(r instanceof RegExp)return i(r);if(g.Object(r)){var s,a={};r.constructor&&r.constructor!==Object&&(a=Object.create(r.constructor.prototype));for(s in r)r.hasOwnProperty(s)&&(a[s]=t?_(r[s]):r[s]);return a}return r}function a(t,r){return function(e){return r(t(e))}}function h(t,r){var e,n;for(e=0,n=t.length;n>e;e++)if(r(t[e]))return t[e]}function u(t,r){var e,n;for(e=0,n=t.length;n>e;e++)if(r(t[e]))return e;return-1}function c(t,r){var e,n=!0;if(!t)return!1;for(e in r)if(g.Object(r[e]))n=n&&c(t[e],r[e]);else if(g.Array(r[e]))n=n&&!!~r[e].indexOf(t[e]);else if(t[e]!==r[e])return!1;return n}function l(t,r){return h(t,function(t){return c(t,r)})}function f(t,r){return u(t,function(t){return c(t,r)})}function p(t,r){r=r||[];var e,n,o=t;for(e=0,n=r.length;n>e;e++){if(!o)return;if("function"==typeof r[e]){if(!g.Array(o))return;o=h(o,r[e])}else if("object"==typeof r[e]){if(!g.Array(o))return;o=l(o,r[e])}else o=o[r[e]]}return o}function d(t,r){var e,n,o,i=[],s=t;for(n=0,o=r.length;o>n;n++){if(!s)return null;if("function"==typeof r[n]){if(!g.Array(s))return;e=u(s,r[n]),i.push(e),s=s[e]}else if("object"==typeof r[n]){if(!g.Array(s))return;e=f(s,r[n]),i.push(e),s=s[e]}else i.push(r[n]),s=s[r[n]]||{}}return i}function b(t,r){var e,n=t.length,o={},i=o;for(n||(o=r),e=0;n>e;e++)i[t[e]]=e+1===n?r:{},i=i[t[e]];return o}function y(t,r){t.super_=r;var e=function(){};e.prototype=r.prototype,t.prototype=new e,t.prototype.constructor=t}var g=t("./type.js"),m=s.bind(null,!1),_=s.bind(null,!0);r.exports={arrayOf:e,before:n,deepClone:_,shallowClone:m,shallowMerge:o,compose:a,getIn:p,inherits:y,pathObject:b,solvePath:d}},{"./type.js":10}],8:[function(t,r){function e(t,r,e){s.forEach(function(r){e!==r&&delete t[r]}),t[e]=r[e]}function n(t,r){var a,h=o.shallowClone(r||{});s.forEach(function(r){t[r]&&e(h,t,r)}),t.$chain&&(s.slice(0,-1).forEach(function(t){delete h[t]}),h.$apply=h.$apply?o.compose(h.$apply,t.$chain):t.$chain),t.$push&&h.$push?h.$push=i.Array(h.$push)?h.$push.concat(t.$push):[h.$push].concat(t.$push):t.$push&&(h.$push=t.$push),t.$unshift&&h.$unshift?h.$unshift=i.Array(t.$unshift)?t.$unshift.concat(h.$unshift):[t.$unshift].concat(h.$unshift):t.$unshift&&(h.$unshift=t.$unshift);for(a in t)i.Object(t[a])?h[a]=n(t[a],h[a]):"$"!==a[0]&&(h[a]=t[a]);return h}var o=t("./helpers.js"),i=t("./type.js"),s=["$unset","$set","$merge","$apply"];r.exports=n},{"./helpers.js":7,"./type.js":10}],9:[function(t,r){var e=t("./combination.js"),n=t("./type.js");r.exports={baobab:function(t){return{mixins:[{getInitialState:function(){if(this.tree=t,!this.cursor&&!this.cursors)return{};if(this.cursor&&this.cursors)throw Error("baobab.mixin: you cannot have both `component.cursor` and `component.cursors`. Please make up your mind.");if(this.__type=null,this.__updateHandler=function(){this.setState(this.__getCursorData())}.bind(this),this.cursor){if(!n.MixinCursor(this.cursor))throw Error("baobab.mixin.cursor: invalid data (cursor, string, array or function).");n.Function(this.cursor)&&(this.cursor=this.cursor()),n.Cursor(this.cursor)||(this.cursor=t.select(this.cursor)),this.__getCursorData=function(){return{cursor:this.cursor.get()}}.bind(this),this.__type="single"}else if(this.cursors){if(!n.MixinCursors(this.cursors))throw Error("baobab.mixin.cursor: invalid data (object, array or function).");if(n.Function(this.cursors)&&(this.cursors=this.cursors()),n.Array(this.cursors))this.cursors=this.cursors.map(function(r){return n.Cursor(r)?r:t.select(r)}),this.__getCursorData=function(){return{cursors:this.cursors.map(function(t){return t.get()})}}.bind(this),this.__type="array";else{for(var r in this.cursors)n.Cursor(this.cursors[r])||(this.cursors[r]=t.select(this.cursors[r]));this.__getCursorData=function(){var t={};for(r in this.cursors)t[r]=this.cursors[r].get();return{cursors:t}}.bind(this),this.__type="object"}}return this.__getCursorData()},componentDidMount:function(){"single"===this.__type?(this.__combination=new e("or",[this.cursor]),this.__combination.on("update",this.__updateHandler)):"array"===this.__type?(this.__combination=new e("or",this.cursors),this.__combination.on("update",this.__updateHandler)):"object"===this.__type&&(this.__combination=new e("or",Object.keys(this.cursors).map(function(t){return this.cursors[t]},this)),this.__combination.on("update",this.__updateHandler))},componentWillUnmount:function(){this.__combination&&this.__combination.release()}}].concat(t.options.mixins)}},cursor:function(t){return{mixins:[{getInitialState:function(){return this.cursor=t,this.__updateHandler=function(){this.setState({cursor:this.cursor.get()})}.bind(this),{cursor:this.cursor.get()}},componentDidMount:function(){this.cursor.on("update",this.__updateHandler)},componentWillUnmount:function(){this.cursor.off("update",this.__updateHandler)}}].concat(t.tree.options.mixins)}}}},{"./combination.js":5,"./type.js":10}],10:[function(t,r){function e(t,r){return r.some(function(r){return n[r](t)})}var n={};n.Array=function(t){return Array.isArray(t)},n.Object=function(t){return!Array.isArray(t)&&"object"==typeof t&&null!==t},n.String=function(t){return"string"==typeof t},n.Number=function(t){return"number"==typeof t},n.Boolean=function(t){return"boolean"==typeof t},n.Function=function(t){return"function"==typeof t},n.Primitive=function(t){return"string"==typeof t||"number"==typeof t||"boolean"==typeof t},n.Date=function(t){return t instanceof Date},n.Path=function(t){var r=["String","Number","Function","Object"];return n.Array(t)?t.every(function(t){return e(t,r)}):e(t,r)},n.MixinCursor=function(t){return e(t,["String","Number","Array","Function","Cursor"])},n.MixinCursors=function(t){return e(t,["Object","Array","Function"])},n.ComplexPath=function(t){return e(t,["Object","Function"])},r.exports=n},{}],11:[function(t,r){function e(t,r){var e=new Error("baobab.update: "+r+" at path /"+t.slice(1).toString());return e.path=t,e}var n=t("./helpers.js"),o=t("./type.js");r.exports=function(t,r,i){if(i=i||{},!o.Object(t)&&!o.Array(t))throw Error("baobab.update: invalid target.");var s={};t={root:n.shallowClone(t)};var a=function(t,r,i,h){i=i||["root"];var u,c,l,f=i.join("λ"),p=i[i.length-1],d=Object.keys(r).some(function(t){return!!~["$unset","$set","$apply","$merge","$push","$unshift"].indexOf(t)});if(d){s[f]=!0;for(c in r){if("$unset"===c){var b=i[i.length-2];o.Array(t)?h[b]=t.slice(0,+p).concat(t.slice(+p+1)):(h[b]=n.shallowClone(t),delete h[b][p]);break}if("$set"===c){l=r.$set,t[p]=l;break}if("$apply"===c){if(u=r.$apply,"function"!=typeof u)throw e(i,"using command $apply with a non function");t[p]=u.call(null,t[p]);break}if("$merge"===c){if(l=r.$merge,!o.Object(t[p])||!o.Object(l))throw e(i,"using command $merge with a non object");t[p]=n.shallowMerge(t[p],l);break}if("$push"===c){if(l=r.$push,!o.Array(t[p]))throw e(i,"using command $push to a non array");t[p]=t[p].concat(l)}if("$unshift"===c){if(l=r.$unshift,!o.Array(t[p]))throw e(i,"using command $unshift to a non array");t[p]=[].concat(l).concat(t[p])}}}else for(c in r)t[p][c]="undefined"==typeof t[p][c]?{}:n.shallowClone(t[p][c]),a(t[p],r[c],i.concat(c),t)};return a(t,r),{data:t.root,log:Object.keys(s).map(function(t){return t.split("λ").slice(1)})}}},{"./helpers.js":7,"./type.js":10}]},{},[2])(2)}); \ No newline at end of file +!function(t){if("object"==typeof exports&&"undefined"!=typeof module)module.exports=t();else if("function"==typeof define&&define.amd)define([],t);else{var r;r="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:this,r.Baobab=t()}}(function(){var t;return function r(t,e,n){function o(s,a){if(!e[s]){if(!t[s]){var h="function"==typeof require&&require;if(!a&&h)return h(s,!0);if(i)return i(s,!0);var u=new Error("Cannot find module '"+s+"'");throw u.code="MODULE_NOT_FOUND",u}var c=e[s]={exports:{}};t[s][0].call(c.exports,function(r){var e=t[s][1][r];return o(e?e:r)},c,c.exports,r,t,e,n)}return e[s].exports}for(var i="function"==typeof require&&require,s=0;sr;r++)n.push(t[r].handler);return n}var o={once:"boolean",scope:"object"},i=function(){this._enabled=!0,this._children=[],this._handlers={},this._handlersAll=[]};i.prototype.on=function(t,r,e){var n,s,a,h,u,c;if("function"==typeof r){for(u="string"==typeof t?[t]:t,n=0,s=u.length;n!==s;n+=1)if(h=u[n]){this._handlers[h]||(this._handlers[h]=[]),c={handler:r};for(a in e||{}){if(!o[a])throw new Error('The option "'+a+'" is not recognized by Emmett.');c[a]=e[a]}this._handlers[h].push(c)}}else if(t&&"object"==typeof t&&!Array.isArray(t))for(h in t)i.prototype.on.call(this,h,t[h],r);else{if("function"!=typeof t)throw new Error("Wrong arguments.");c={handler:t};for(a in e||{}){if(!o[a])throw new Error('The option "'+a+'" is not recognized by Emmett.');c[a]=e[a]}this._handlersAll.push(c)}return this},i.prototype.once=function(t,r,e){if("function"==typeof r)e=e||{},e.once=!0,this.on(t,r,e);else{if((!t||"object"!=typeof t||Array.isArray(t))&&"function"!=typeof t)throw new Error("Wrong arguments.");r=r||{},r.once=!0,this.on(t,r)}return this},i.prototype.off=function(t,r){var e,n,o,i,s,a,h,u="string"==typeof t?[t]:t;if(1===arguments.length&&"function"==typeof u){r=arguments[0];for(s in this._handlers){for(a=[],e=0,n=this._handlers[s].length;e!==n;e+=1)this._handlers[s][e].handler!==r&&a.push(this._handlers[s][e]);this._handlers[s]=a}for(a=[],e=0,n=this._handlersAll.length;e!==n;e+=1)this._handlersAll[e].handler!==r&&a.push(this._handlersAll[e]);this._handlersAll=a}else if(2===arguments.length)for(e=0,n=u.length;e!==n;e+=1){if(h=u[e],this._handlers[h]){for(a=[],o=0,i=this._handlers[h].length;o!==i;o+=1)this._handlers[h][o].handler!==r&&a.push(this._handlers[h][o]);this._handlers[h]=a}this._handlers[h]&&0===this._handlers[h].length&&delete this._handlers[h]}return this},i.prototype.unbindAll=function(){var t;this._handlersAll=[];for(t in this._handlers)delete this._handlers[t];return this},i.prototype.emit=function(t,r){var e,n,o,i,s,a,h,u,c,l,f="string"==typeof t?[t]:t;if(!this._enabled)return this;for(r=void 0===r?{}:r,e=0,n=f.length;e!==n;e+=1)if(l=f[e],c=(this._handlers[l]||[]).concat(this._handlersAll),c.length){for(h={type:l,data:r||{},target:this},a=[],o=0,i=c.length;o!==i;o+=1)(this._handlers[l]&&this._handlers[l].indexOf(c[o])>=0||this._handlersAll.indexOf(c[o])>=0)&&(c[o].handler.call("scope"in c[o]?c[o].scope:this,h),c[o].once&&a.push(c[o]));for(s=0;se;e++)if(t._children[e]===r){t._children.splice(e,1);break}}),this._children.push(r),r},i.prototype.listeners=function(t){var e,n,o,i=[];if(t)for(i=r(this._handlers[t]),n=0,o=this._children.length;o>n;n++)i=i.concat(this._children[n].listeners(t));else{i=r(this._handlersAll);for(e in this._handlers)i=i.concat(r(this._handlers[e]));for(n=0,o=this._children.length;o>n;n++)i=i.concat(this._children[n].listeners())}return i},i.prototype.kill=function(){if(this.emit("emmett:kill"),this.unbindAll(),this._handlers=null,this._handlersAll=null,this._enabled=!1,this._children)for(var t=0,r=this._children.length;r>t;t++)this._children[t].kill();this._children=null},i.prototype.disable=function(){return this._enabled=!1,this},i.prototype.enable=function(){return this._enabled=!0,this},i.version="2.1.2","undefined"!=typeof n?("undefined"!=typeof e&&e.exports&&(n=e.exports=i),n.Emitter=i):"function"==typeof t&&t.amd?t("emmett",[],function(){return i}):this.Emitter=i}).call(this)},{}],4:[function(t,r){function e(t){return t+"$"+(new Date).getTime()+(""+Math.random()).replace("0.","")}function n(t,r){function e(t){this[t]=function(){var r=this.root[t].apply(this.root,arguments);return r instanceof o?this:r}}if(arguments.length<1&&(t={}),!(this instanceof n))return new n(t,r);if(!l.Object(t)&&!l.Array(t))throw Error("Baobab: invalid data.");i.call(this),this.options=s.shallowMerge(c,r),this._transaction={},this._future=void 0,this._cursors={},this.data=s.deepClone(t),this.root=this.select([]),["get","set","unset","update"].forEach(e.bind(this)),this.mixin=u.baobab(this)}var o=t("./cursor.js"),i=t("emmett"),s=t("./helpers.js"),a=t("./update.js"),h=t("./merge.js"),u=t("./mixins.js"),c=t("../defaults.js"),l=t("./type.js");s.inherits(n,i),n.prototype.select=function(t){if(!t)throw Error("Baobab.select: invalid path.");if(arguments.length>1&&(t=s.arrayOf(arguments)),!l.Path(t))throw Error("Baobab.select: invalid path.");t=[].concat(t);var r,n=l.ComplexPath(t);n&&(r=s.solvePath(this.data,t));var i=t.map(function(t){return l.Function(t)?e("fn"):l.Object(t)?e("ob"):t}).join("λ");if(this._cursors[i])return this._cursors[i];var a=new o(this,t,r,i);return this._cursors[i]=a,a},n.prototype.stack=function(t){var r=this;if(!l.Object(t))throw Error("Baobab.update: wrong specification.");return this._transaction=h(t,this._transaction),this.options.autoCommit?this.options.asynchronous?(this._future||(this._future=setTimeout(r.commit.bind(r,null),0)),this):this.commit():this},n.prototype.commit=function(){var t=a(this.data,this._transaction,this.options);return this.data=t.data,this._transaction={},this._future&&(this._future=clearTimeout(this._future)),this.emit("update",{log:t.log}),this},n.prototype.release=function(){delete this.data,delete this._transaction;for(var t in this._cursors)this._cursors[t].release();delete this._cursors,this.kill()},n.prototype.toJSON=function(){return this.get()},r.exports=n},{"../defaults.js":1,"./cursor.js":6,"./helpers.js":7,"./merge.js":8,"./mixins.js":9,"./type.js":10,"./update.js":11,emmett:3}],5:[function(t,r){function e(t,r){r.on("update",t.cursorListener),t.tree.off("update",t.treeListener),t.tree.on("update",t.treeListener)}function n(t){var r=this;if(arguments.length<2)throw Error("baobab.Combination: not enough arguments.");var n=arguments[1],o=s.arrayOf(arguments).slice(2);if(n instanceof Array&&(o=n.slice(1),n=n[0]),!a.Cursor(n))throw Error("baobab.Combination: argument should be a cursor.");if("or"!==t&&"and"!==t)throw Error("baobab.Combination: invalid operator.");i.call(this),this.cursors=[n],this.operators=[],this.tree=n.tree,this.updates=new Array(this.cursors.length),this.cursorListener=function(){r.updates[r.cursors.indexOf(this)]=!0},this.treeListener=function(){var t,e,n=r.updates[0];for(t=1,e=r.cursors.length;e>t;t++)n="or"===r.operators[t-1]?n||r.updates[t]:n&&r.updates[t];n&&r.emit("update"),r.updates=new Array(r.cursors.length)},this.bound=!1;var h=(this.on,this.once,function(){r.bound||(r.bound=!0,r.cursors.forEach(function(t){e(r,t)}))});this.on=s.before(h,this.on.bind(this)),this.once=s.before(h,this.once.bind(this)),o.forEach(function(r){this[t](r)},this)}function o(t){n.prototype[t]=function(r){if(!a.Cursor(r))throw this.release(),Error("baobab.Combination."+t+": argument should be a cursor.");if(~this.cursors.indexOf(r))throw this.release(),Error("baobab.Combination."+t+": cursor already in combination.");return this.cursors.push(r),this.operators.push(t),this.updates.length++,this.bound&&e(this,r),this}}var i=t("emmett"),s=t("./helpers.js"),a=t("./type.js");s.inherits(n,i),o("or"),o("and"),n.prototype.release=function(){this.cursors.forEach(function(t){t.off("update",this.cursorListener)},this),this.tree.off("update",this.treeListener),this.cursors=null,this.operators=null,this.tree=null,this.updates=null,this.kill()},r.exports=n},{"./helpers.js":7,"./type.js":10,emmett:3}],6:[function(t,r){function e(t,r,e,o){var a=this;n.call(this),r=r||[],this.tree=t,this.path=r,this.hash=o,this.complexPath=!!e,this.solvedPath=this.complexPath?e:this.path,this.relevant=void 0!==this.get(),this.updateHandler=function(t){var r,e,n,o,i,h,u=t.data.log,c=!1;if(a.complexPath&&(a.solvedPath=s.solvePath(a.tree.data,a.path)),!a.path.length)return a.emit("update");t:for(i=0,n=u.length;n>i;i++)for(r=u[i],h=0,o=r.length;o>h&&(e=r[h],e===""+a.solvedPath[h]);h++)if(h+1===o||h+1===a.solvedPath.length){c=!0;break t}var l=void 0!==a.get();a.relevant?l&&c?a.emit("update"):l||(a.emit("irrelevant"),a.relevant=!1):l&&c&&(a.emit("relevant"),a.emit("update"),a.relevant=!0)},this.mixin=i.cursor(this);var h=!1,u=function(){h||(h=!0,a.tree.on("update",a.updateHandler))};this.on=s.before(u,this.on.bind(this)),this.once=s.before(u,this.once.bind(this))}var n=t("emmett"),o=t("./combination.js"),i=t("./mixins.js"),s=t("./helpers.js"),a=t("./type.js");s.inherits(e,n),e.prototype.isRoot=function(){return!this.path.length},e.prototype.isLeaf=function(){return a.Primitive(this.get())},e.prototype.isBranch=function(){return!this.isLeaf()&&!this.isRoot()},e.prototype.root=function(){return this.tree.root()},e.prototype.select=function(t){if(arguments.length>1&&(t=s.arrayOf(arguments)),!a.Path(t))throw Error("baobab.Cursor.select: invalid path.");return this.tree.select(this.path.concat(t))},e.prototype.up=function(){return this.solvedPath&&this.solvedPath.length?this.tree.select(this.path.slice(0,-1)):null},e.prototype.left=function(){var t=+this.solvedPath[this.solvedPath.length-1];if(isNaN(t))throw Error("baobab.Cursor.left: cannot go left on a non-list type.");return t?this.tree.select(this.solvedPath.slice(0,-1).concat(t-1)):null},e.prototype.leftmost=function(){var t=+this.solvedPath[this.solvedPath.length-1];if(isNaN(t))throw Error("baobab.Cursor.leftmost: cannot go left on a non-list type.");return this.tree.select(this.solvedPath.slice(0,-1).concat(0))},e.prototype.right=function(){var t=+this.solvedPath[this.solvedPath.length-1];if(isNaN(t))throw Error("baobab.Cursor.right: cannot go right on a non-list type.");return t+1===this.up().get().length?null:this.tree.select(this.solvedPath.slice(0,-1).concat(t+1))},e.prototype.rightmost=function(){var t=+this.solvedPath[this.solvedPath.length-1];if(isNaN(t))throw Error("baobab.Cursor.right: cannot go right on a non-list type.");var r=this.up().get();return this.tree.select(this.solvedPath.slice(0,-1).concat(r.length-1))},e.prototype.down=function(){+this.solvedPath[this.solvedPath.length-1];return this.get()instanceof Array?this.tree.select(this.solvedPath.concat(0)):null},e.prototype.get=function(t){arguments.length>1&&(t=s.arrayOf(arguments));var r=this.solvedPath.concat((a.String(t)||a.Number(t)?[t]:t)||[]);return s.getIn(this.tree.data,r)},e.prototype.set=function(t,r){if(arguments.length<2)throw Error("baobab.Cursor.set: expecting at least key/value.");var e=this.get();if("object"!=typeof e)throw Error("baobab.Cursor.set: trying to set key to a non-object.");var n={};if(a.Array(t)){var o=s.solvePath(e,t);if(!o)throw Error("baobab.Cursor.set: could not solve dynamic path.");n=s.pathObject(o,{$set:r})}else n[t]={$set:r};return this.update(n)},e.prototype.edit=function(t){return this.update({$set:t})},e.prototype.unset=function(t){if(!t&&0!==t)throw Error("baobab.Cursor.unset: expects a valid key to unset.");if("object"!=typeof this.get())throw Error("baobab.Cursor.set: trying to set key to a non-object.");var r={};return r[t]={$unset:!0},this.update(r)},e.prototype.remove=function(){if(this.isRoot())throw Error("baobab.Cursor.remove: cannot remove root node.");return this.update({$unset:!0})},e.prototype.apply=function(t){if("function"!=typeof t)throw Error("baobab.Cursor.apply: argument is not a function.");return this.update({$apply:t})},e.prototype.chain=function(t){if("function"!=typeof t)throw Error("baobab.Cursor.chain: argument is not a function.");return this.update({$chain:t})},e.prototype.push=function(t){if(!(this.get()instanceof Array))throw Error("baobab.Cursor.push: trying to push to non-array value.");return this.update(arguments.length>1?{$push:s.arrayOf(arguments)}:{$push:t})},e.prototype.unshift=function(t){if(!(this.get()instanceof Array))throw Error("baobab.Cursor.push: trying to push to non-array value.");return this.update(arguments.length>1?{$unshift:s.arrayOf(arguments)}:{$unshift:t})},e.prototype.merge=function(t){if(!a.Object(t))throw Error("baobab.Cursor.merge: trying to merge a non-object.");if(!a.Object(this.get()))throw Error("baobab.Cursor.merge: trying to merge into a non-object.");this.update({$merge:t})},e.prototype.update=function(t){return this.tree.stack(s.pathObject(this.solvedPath,t)),this},e.prototype.or=function(t){return new o("or",this,t)},e.prototype.and=function(t){return new o("and",this,t)},e.prototype.release=function(){this.tree.off("update",this.updateHandler),this.hash&&delete this.tree._cursors[this.hash],delete this.tree,delete this.path,delete this.solvedPath,this.kill()},e.prototype.toJSON=function(){return this.get()},a.Cursor=function(t){return t instanceof e},r.exports=e},{"./combination.js":5,"./helpers.js":7,"./mixins.js":9,"./type.js":10,emmett:3}],7:[function(t,r){function e(t){return Array.prototype.slice.call(t)}function n(t,r){return function(){t(),r.apply(null,arguments)}}function o(t,r){var e,n={};for(e in t)n[e]=t[e];for(e in r)n[e]=r[e];return n}function i(t){var r=t.source,e="";return t.global&&(e+="g"),t.multiline&&(e+="m"),t.ignoreCase&&(e+="i"),t.sticky&&(e+="y"),t.unicode&&(e+="u"),new RegExp(r,e)}function s(t,r){if(!r||"object"!=typeof r||r instanceof Error||r instanceof ArrayBuffer)return r;if(g.Array(r)){if(t){var e,n,o=[];for(e=0,n=r.length;n>e;e++)o.push(_(r[e]));return o}return r.slice(0)}if(g.Date(r))return new Date(r.getTime());if(r instanceof RegExp)return i(r);if(g.Object(r)){var s,a={};r.constructor&&r.constructor!==Object&&(a=Object.create(r.constructor.prototype));for(s in r)r.hasOwnProperty(s)&&(a[s]=t?_(r[s]):r[s]);return a}return r}function a(t,r){return function(e){return r(t(e))}}function h(t,r){var e,n;for(e=0,n=t.length;n>e;e++)if(r(t[e]))return t[e]}function u(t,r){var e,n;for(e=0,n=t.length;n>e;e++)if(r(t[e]))return e;return-1}function c(t,r){var e,n=!0;if(!t)return!1;for(e in r)if(g.Object(r[e]))n=n&&c(t[e],r[e]);else if(g.Array(r[e]))n=n&&!!~r[e].indexOf(t[e]);else if(t[e]!==r[e])return!1;return n}function l(t,r){return h(t,function(t){return c(t,r)})}function f(t,r){return u(t,function(t){return c(t,r)})}function p(t,r){r=r||[];var e,n,o=t;for(e=0,n=r.length;n>e;e++){if(!o)return;if("function"==typeof r[e]){if(!g.Array(o))return;o=h(o,r[e])}else if("object"==typeof r[e]){if(!g.Array(o))return;o=l(o,r[e])}else o=o[r[e]]}return o}function d(t,r){var e,n,o,i=[],s=t;for(n=0,o=r.length;o>n;n++){if(!s)return null;if("function"==typeof r[n]){if(!g.Array(s))return;e=u(s,r[n]),i.push(e),s=s[e]}else if("object"==typeof r[n]){if(!g.Array(s))return;e=f(s,r[n]),i.push(e),s=s[e]}else i.push(r[n]),s=s[r[n]]||{}}return i}function b(t,r){var e,n=t.length,o={},i=o;for(n||(o=r),e=0;n>e;e++)i[t[e]]=e+1===n?r:{},i=i[t[e]];return o}function y(t,r){t.super_=r;var e=function(){};e.prototype=r.prototype,t.prototype=new e,t.prototype.constructor=t}var g=t("./type.js"),m=s.bind(null,!1),_=s.bind(null,!0);r.exports={arrayOf:e,before:n,deepClone:_,shallowClone:m,shallowMerge:o,compose:a,getIn:p,inherits:y,pathObject:b,solvePath:d}},{"./type.js":10}],8:[function(t,r){function e(t,r,e){s.forEach(function(r){e!==r&&delete t[r]}),t[e]=r[e]}function n(t,r){var a,h=o.shallowClone(r||{});s.forEach(function(r){t[r]&&e(h,t,r)}),t.$chain&&(s.slice(0,-1).forEach(function(t){delete h[t]}),h.$apply=h.$apply?o.compose(h.$apply,t.$chain):t.$chain),t.$push&&h.$push?h.$push=i.Array(h.$push)?h.$push.concat(t.$push):[h.$push].concat(t.$push):t.$push&&(h.$push=t.$push),t.$unshift&&h.$unshift?h.$unshift=i.Array(t.$unshift)?t.$unshift.concat(h.$unshift):[t.$unshift].concat(h.$unshift):t.$unshift&&(h.$unshift=t.$unshift);for(a in t)i.Object(t[a])?h[a]=n(t[a],h[a]):"$"!==a[0]&&(h[a]=t[a]);return h}var o=t("./helpers.js"),i=t("./type.js"),s=["$unset","$set","$merge","$apply"];r.exports=n},{"./helpers.js":7,"./type.js":10}],9:[function(t,r){var e=t("./combination.js"),n=t("./type.js");r.exports={baobab:function(t){return{mixins:[{getInitialState:function(){if(this.tree=t,!this.cursor&&!this.cursors)return{};if(this.cursor&&this.cursors)throw Error("baobab.mixin: you cannot have both `component.cursor` and `component.cursors`. Please make up your mind.");if(this.__type=null,this.__updateHandler=function(){this.setState(this.__getCursorData())}.bind(this),this.cursor){if(!n.MixinCursor(this.cursor))throw Error("baobab.mixin.cursor: invalid data (cursor, string, array or function).");n.Function(this.cursor)&&(this.cursor=this.cursor()),n.Cursor(this.cursor)||(this.cursor=t.select(this.cursor)),this.__getCursorData=function(){return{cursor:this.cursor.get()}}.bind(this),this.__type="single"}else if(this.cursors){if(!n.MixinCursors(this.cursors))throw Error("baobab.mixin.cursor: invalid data (object, array or function).");if(n.Function(this.cursors)&&(this.cursors=this.cursors()),n.Array(this.cursors))this.cursors=this.cursors.map(function(r){return n.Cursor(r)?r:t.select(r)}),this.__getCursorData=function(){return{cursors:this.cursors.map(function(t){return t.get()})}}.bind(this),this.__type="array";else{for(var r in this.cursors)n.Cursor(this.cursors[r])||(this.cursors[r]=t.select(this.cursors[r]));this.__getCursorData=function(){var t={};for(r in this.cursors)t[r]=this.cursors[r].get();return{cursors:t}}.bind(this),this.__type="object"}}return this.__getCursorData()},componentDidMount:function(){"single"===this.__type?(this.__combination=new e("or",[this.cursor]),this.__combination.on("update",this.__updateHandler)):"array"===this.__type?(this.__combination=new e("or",this.cursors),this.__combination.on("update",this.__updateHandler)):"object"===this.__type&&(this.__combination=new e("or",Object.keys(this.cursors).map(function(t){return this.cursors[t]},this)),this.__combination.on("update",this.__updateHandler))},componentWillUnmount:function(){this.__combination&&this.__combination.release()}}].concat(t.options.mixins)}},cursor:function(t){return{mixins:[{getInitialState:function(){return this.cursor=t,this.__updateHandler=function(){this.setState({cursor:this.cursor.get()})}.bind(this),{cursor:this.cursor.get()}},componentDidMount:function(){this.cursor.on("update",this.__updateHandler)},componentWillUnmount:function(){this.cursor.off("update",this.__updateHandler)}}].concat(t.tree.options.mixins)}}}},{"./combination.js":5,"./type.js":10}],10:[function(t,r){function e(t,r){return r.some(function(r){return n[r](t)})}var n={};n.Array=function(t){return Array.isArray(t)},n.Object=function(t){return!Array.isArray(t)&&"object"==typeof t&&null!==t},n.String=function(t){return"string"==typeof t},n.Number=function(t){return"number"==typeof t},n.Function=function(t){return"function"==typeof t},n.Primitive=function(t){return"string"==typeof t||"number"==typeof t||"boolean"==typeof t},n.Date=function(t){return t instanceof Date},n.Path=function(t){var r=["String","Number","Function","Object"];return n.Array(t)?t.every(function(t){return e(t,r)}):e(t,r)},n.MixinCursor=function(t){return e(t,["String","Number","Array","Function","Cursor"])},n.MixinCursors=function(t){return e(t,["Object","Array","Function"])},n.ComplexPath=function(t){return e(t,["Object","Function"])},r.exports=n},{}],11:[function(t,r){function e(t,r){var e=new Error("baobab.update: "+r+" at path /"+t.slice(1).toString());return e.path=t,e}var n=t("./helpers.js"),o=t("./type.js");r.exports=function(t,r,i){if(i=i||{},!o.Object(t)&&!o.Array(t))throw Error("baobab.update: invalid target.");var s={};t={root:n.shallowClone(t)};var a=function(t,r,i,h){i=i||["root"];var u,c,l,f=i.join("λ"),p=i[i.length-1],d=Object.keys(r).some(function(t){return!!~["$unset","$set","$apply","$merge","$push","$unshift"].indexOf(t)});if(d){s[f]=!0;for(c in r){if("$unset"===c){var b=i[i.length-2];o.Array(t)?h[b]=t.slice(0,+p).concat(t.slice(+p+1)):(h[b]=n.shallowClone(t),delete h[b][p]);break}if("$set"===c){l=r.$set,t[p]=l;break}if("$apply"===c){if(u=r.$apply,"function"!=typeof u)throw e(i,"using command $apply with a non function");t[p]=u.call(null,t[p]);break}if("$merge"===c){if(l=r.$merge,!o.Object(t[p])||!o.Object(l))throw e(i,"using command $merge with a non object");t[p]=n.shallowMerge(t[p],l);break}if("$push"===c){if(l=r.$push,!o.Array(t[p]))throw e(i,"using command $push to a non array");t[p]=t[p].concat(l)}if("$unshift"===c){if(l=r.$unshift,!o.Array(t[p]))throw e(i,"using command $unshift to a non array");t[p]=[].concat(l).concat(t[p])}}}else for(c in r)t[p][c]="undefined"==typeof t[p][c]?{}:n.shallowClone(t[p][c]),a(t[p],r[c],i.concat(c),t)};return a(t,r),{data:t.root,log:Object.keys(s).map(function(t){return t.split("λ").slice(1)})}}},{"./helpers.js":7,"./type.js":10}]},{},[2])(2)}); \ No newline at end of file diff --git a/src/type.js b/src/type.js index 5070b10..cbfd848 100644 --- a/src/type.js +++ b/src/type.js @@ -37,10 +37,6 @@ type.Number = function (value) { return typeof value === 'number'; }; -type.Boolean = function (value) { - return typeof value === 'boolean'; -}; - type.Function = function (value) { return typeof value === 'function'; }; From 5a6dd54a9c2a4e2b6fd466b68fa601e5788fe704 Mon Sep 17 00:00:00 2001 From: Yomguithereal Date: Wed, 1 Apr 2015 15:50:06 +0200 Subject: [PATCH 18/73] Altering cursor.set behavior --- build/baobab.min.js | 2 +- src/cursor.js | 28 ++++++++++------------------ 2 files changed, 11 insertions(+), 19 deletions(-) diff --git a/build/baobab.min.js b/build/baobab.min.js index 96835dc..98371b0 100644 --- a/build/baobab.min.js +++ b/build/baobab.min.js @@ -1,2 +1,2 @@ /* baobab.js - Version: 1.0.0-rc1 - Author: Yomguithereal (Guillaume Plique) */ -!function(t){if("object"==typeof exports&&"undefined"!=typeof module)module.exports=t();else if("function"==typeof define&&define.amd)define([],t);else{var r;r="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:this,r.Baobab=t()}}(function(){var t;return function r(t,e,n){function o(s,a){if(!e[s]){if(!t[s]){var h="function"==typeof require&&require;if(!a&&h)return h(s,!0);if(i)return i(s,!0);var u=new Error("Cannot find module '"+s+"'");throw u.code="MODULE_NOT_FOUND",u}var c=e[s]={exports:{}};t[s][0].call(c.exports,function(r){var e=t[s][1][r];return o(e?e:r)},c,c.exports,r,t,e,n)}return e[s].exports}for(var i="function"==typeof require&&require,s=0;sr;r++)n.push(t[r].handler);return n}var o={once:"boolean",scope:"object"},i=function(){this._enabled=!0,this._children=[],this._handlers={},this._handlersAll=[]};i.prototype.on=function(t,r,e){var n,s,a,h,u,c;if("function"==typeof r){for(u="string"==typeof t?[t]:t,n=0,s=u.length;n!==s;n+=1)if(h=u[n]){this._handlers[h]||(this._handlers[h]=[]),c={handler:r};for(a in e||{}){if(!o[a])throw new Error('The option "'+a+'" is not recognized by Emmett.');c[a]=e[a]}this._handlers[h].push(c)}}else if(t&&"object"==typeof t&&!Array.isArray(t))for(h in t)i.prototype.on.call(this,h,t[h],r);else{if("function"!=typeof t)throw new Error("Wrong arguments.");c={handler:t};for(a in e||{}){if(!o[a])throw new Error('The option "'+a+'" is not recognized by Emmett.');c[a]=e[a]}this._handlersAll.push(c)}return this},i.prototype.once=function(t,r,e){if("function"==typeof r)e=e||{},e.once=!0,this.on(t,r,e);else{if((!t||"object"!=typeof t||Array.isArray(t))&&"function"!=typeof t)throw new Error("Wrong arguments.");r=r||{},r.once=!0,this.on(t,r)}return this},i.prototype.off=function(t,r){var e,n,o,i,s,a,h,u="string"==typeof t?[t]:t;if(1===arguments.length&&"function"==typeof u){r=arguments[0];for(s in this._handlers){for(a=[],e=0,n=this._handlers[s].length;e!==n;e+=1)this._handlers[s][e].handler!==r&&a.push(this._handlers[s][e]);this._handlers[s]=a}for(a=[],e=0,n=this._handlersAll.length;e!==n;e+=1)this._handlersAll[e].handler!==r&&a.push(this._handlersAll[e]);this._handlersAll=a}else if(2===arguments.length)for(e=0,n=u.length;e!==n;e+=1){if(h=u[e],this._handlers[h]){for(a=[],o=0,i=this._handlers[h].length;o!==i;o+=1)this._handlers[h][o].handler!==r&&a.push(this._handlers[h][o]);this._handlers[h]=a}this._handlers[h]&&0===this._handlers[h].length&&delete this._handlers[h]}return this},i.prototype.unbindAll=function(){var t;this._handlersAll=[];for(t in this._handlers)delete this._handlers[t];return this},i.prototype.emit=function(t,r){var e,n,o,i,s,a,h,u,c,l,f="string"==typeof t?[t]:t;if(!this._enabled)return this;for(r=void 0===r?{}:r,e=0,n=f.length;e!==n;e+=1)if(l=f[e],c=(this._handlers[l]||[]).concat(this._handlersAll),c.length){for(h={type:l,data:r||{},target:this},a=[],o=0,i=c.length;o!==i;o+=1)(this._handlers[l]&&this._handlers[l].indexOf(c[o])>=0||this._handlersAll.indexOf(c[o])>=0)&&(c[o].handler.call("scope"in c[o]?c[o].scope:this,h),c[o].once&&a.push(c[o]));for(s=0;se;e++)if(t._children[e]===r){t._children.splice(e,1);break}}),this._children.push(r),r},i.prototype.listeners=function(t){var e,n,o,i=[];if(t)for(i=r(this._handlers[t]),n=0,o=this._children.length;o>n;n++)i=i.concat(this._children[n].listeners(t));else{i=r(this._handlersAll);for(e in this._handlers)i=i.concat(r(this._handlers[e]));for(n=0,o=this._children.length;o>n;n++)i=i.concat(this._children[n].listeners())}return i},i.prototype.kill=function(){if(this.emit("emmett:kill"),this.unbindAll(),this._handlers=null,this._handlersAll=null,this._enabled=!1,this._children)for(var t=0,r=this._children.length;r>t;t++)this._children[t].kill();this._children=null},i.prototype.disable=function(){return this._enabled=!1,this},i.prototype.enable=function(){return this._enabled=!0,this},i.version="2.1.2","undefined"!=typeof n?("undefined"!=typeof e&&e.exports&&(n=e.exports=i),n.Emitter=i):"function"==typeof t&&t.amd?t("emmett",[],function(){return i}):this.Emitter=i}).call(this)},{}],4:[function(t,r){function e(t){return t+"$"+(new Date).getTime()+(""+Math.random()).replace("0.","")}function n(t,r){function e(t){this[t]=function(){var r=this.root[t].apply(this.root,arguments);return r instanceof o?this:r}}if(arguments.length<1&&(t={}),!(this instanceof n))return new n(t,r);if(!l.Object(t)&&!l.Array(t))throw Error("Baobab: invalid data.");i.call(this),this.options=s.shallowMerge(c,r),this._transaction={},this._future=void 0,this._cursors={},this.data=s.deepClone(t),this.root=this.select([]),["get","set","unset","update"].forEach(e.bind(this)),this.mixin=u.baobab(this)}var o=t("./cursor.js"),i=t("emmett"),s=t("./helpers.js"),a=t("./update.js"),h=t("./merge.js"),u=t("./mixins.js"),c=t("../defaults.js"),l=t("./type.js");s.inherits(n,i),n.prototype.select=function(t){if(!t)throw Error("Baobab.select: invalid path.");if(arguments.length>1&&(t=s.arrayOf(arguments)),!l.Path(t))throw Error("Baobab.select: invalid path.");t=[].concat(t);var r,n=l.ComplexPath(t);n&&(r=s.solvePath(this.data,t));var i=t.map(function(t){return l.Function(t)?e("fn"):l.Object(t)?e("ob"):t}).join("λ");if(this._cursors[i])return this._cursors[i];var a=new o(this,t,r,i);return this._cursors[i]=a,a},n.prototype.stack=function(t){var r=this;if(!l.Object(t))throw Error("Baobab.update: wrong specification.");return this._transaction=h(t,this._transaction),this.options.autoCommit?this.options.asynchronous?(this._future||(this._future=setTimeout(r.commit.bind(r,null),0)),this):this.commit():this},n.prototype.commit=function(){var t=a(this.data,this._transaction,this.options);return this.data=t.data,this._transaction={},this._future&&(this._future=clearTimeout(this._future)),this.emit("update",{log:t.log}),this},n.prototype.release=function(){delete this.data,delete this._transaction;for(var t in this._cursors)this._cursors[t].release();delete this._cursors,this.kill()},n.prototype.toJSON=function(){return this.get()},r.exports=n},{"../defaults.js":1,"./cursor.js":6,"./helpers.js":7,"./merge.js":8,"./mixins.js":9,"./type.js":10,"./update.js":11,emmett:3}],5:[function(t,r){function e(t,r){r.on("update",t.cursorListener),t.tree.off("update",t.treeListener),t.tree.on("update",t.treeListener)}function n(t){var r=this;if(arguments.length<2)throw Error("baobab.Combination: not enough arguments.");var n=arguments[1],o=s.arrayOf(arguments).slice(2);if(n instanceof Array&&(o=n.slice(1),n=n[0]),!a.Cursor(n))throw Error("baobab.Combination: argument should be a cursor.");if("or"!==t&&"and"!==t)throw Error("baobab.Combination: invalid operator.");i.call(this),this.cursors=[n],this.operators=[],this.tree=n.tree,this.updates=new Array(this.cursors.length),this.cursorListener=function(){r.updates[r.cursors.indexOf(this)]=!0},this.treeListener=function(){var t,e,n=r.updates[0];for(t=1,e=r.cursors.length;e>t;t++)n="or"===r.operators[t-1]?n||r.updates[t]:n&&r.updates[t];n&&r.emit("update"),r.updates=new Array(r.cursors.length)},this.bound=!1;var h=(this.on,this.once,function(){r.bound||(r.bound=!0,r.cursors.forEach(function(t){e(r,t)}))});this.on=s.before(h,this.on.bind(this)),this.once=s.before(h,this.once.bind(this)),o.forEach(function(r){this[t](r)},this)}function o(t){n.prototype[t]=function(r){if(!a.Cursor(r))throw this.release(),Error("baobab.Combination."+t+": argument should be a cursor.");if(~this.cursors.indexOf(r))throw this.release(),Error("baobab.Combination."+t+": cursor already in combination.");return this.cursors.push(r),this.operators.push(t),this.updates.length++,this.bound&&e(this,r),this}}var i=t("emmett"),s=t("./helpers.js"),a=t("./type.js");s.inherits(n,i),o("or"),o("and"),n.prototype.release=function(){this.cursors.forEach(function(t){t.off("update",this.cursorListener)},this),this.tree.off("update",this.treeListener),this.cursors=null,this.operators=null,this.tree=null,this.updates=null,this.kill()},r.exports=n},{"./helpers.js":7,"./type.js":10,emmett:3}],6:[function(t,r){function e(t,r,e,o){var a=this;n.call(this),r=r||[],this.tree=t,this.path=r,this.hash=o,this.complexPath=!!e,this.solvedPath=this.complexPath?e:this.path,this.relevant=void 0!==this.get(),this.updateHandler=function(t){var r,e,n,o,i,h,u=t.data.log,c=!1;if(a.complexPath&&(a.solvedPath=s.solvePath(a.tree.data,a.path)),!a.path.length)return a.emit("update");t:for(i=0,n=u.length;n>i;i++)for(r=u[i],h=0,o=r.length;o>h&&(e=r[h],e===""+a.solvedPath[h]);h++)if(h+1===o||h+1===a.solvedPath.length){c=!0;break t}var l=void 0!==a.get();a.relevant?l&&c?a.emit("update"):l||(a.emit("irrelevant"),a.relevant=!1):l&&c&&(a.emit("relevant"),a.emit("update"),a.relevant=!0)},this.mixin=i.cursor(this);var h=!1,u=function(){h||(h=!0,a.tree.on("update",a.updateHandler))};this.on=s.before(u,this.on.bind(this)),this.once=s.before(u,this.once.bind(this))}var n=t("emmett"),o=t("./combination.js"),i=t("./mixins.js"),s=t("./helpers.js"),a=t("./type.js");s.inherits(e,n),e.prototype.isRoot=function(){return!this.path.length},e.prototype.isLeaf=function(){return a.Primitive(this.get())},e.prototype.isBranch=function(){return!this.isLeaf()&&!this.isRoot()},e.prototype.root=function(){return this.tree.root()},e.prototype.select=function(t){if(arguments.length>1&&(t=s.arrayOf(arguments)),!a.Path(t))throw Error("baobab.Cursor.select: invalid path.");return this.tree.select(this.path.concat(t))},e.prototype.up=function(){return this.solvedPath&&this.solvedPath.length?this.tree.select(this.path.slice(0,-1)):null},e.prototype.left=function(){var t=+this.solvedPath[this.solvedPath.length-1];if(isNaN(t))throw Error("baobab.Cursor.left: cannot go left on a non-list type.");return t?this.tree.select(this.solvedPath.slice(0,-1).concat(t-1)):null},e.prototype.leftmost=function(){var t=+this.solvedPath[this.solvedPath.length-1];if(isNaN(t))throw Error("baobab.Cursor.leftmost: cannot go left on a non-list type.");return this.tree.select(this.solvedPath.slice(0,-1).concat(0))},e.prototype.right=function(){var t=+this.solvedPath[this.solvedPath.length-1];if(isNaN(t))throw Error("baobab.Cursor.right: cannot go right on a non-list type.");return t+1===this.up().get().length?null:this.tree.select(this.solvedPath.slice(0,-1).concat(t+1))},e.prototype.rightmost=function(){var t=+this.solvedPath[this.solvedPath.length-1];if(isNaN(t))throw Error("baobab.Cursor.right: cannot go right on a non-list type.");var r=this.up().get();return this.tree.select(this.solvedPath.slice(0,-1).concat(r.length-1))},e.prototype.down=function(){+this.solvedPath[this.solvedPath.length-1];return this.get()instanceof Array?this.tree.select(this.solvedPath.concat(0)):null},e.prototype.get=function(t){arguments.length>1&&(t=s.arrayOf(arguments));var r=this.solvedPath.concat((a.String(t)||a.Number(t)?[t]:t)||[]);return s.getIn(this.tree.data,r)},e.prototype.set=function(t,r){if(arguments.length<2)throw Error("baobab.Cursor.set: expecting at least key/value.");var e=this.get();if("object"!=typeof e)throw Error("baobab.Cursor.set: trying to set key to a non-object.");var n={};if(a.Array(t)){var o=s.solvePath(e,t);if(!o)throw Error("baobab.Cursor.set: could not solve dynamic path.");n=s.pathObject(o,{$set:r})}else n[t]={$set:r};return this.update(n)},e.prototype.edit=function(t){return this.update({$set:t})},e.prototype.unset=function(t){if(!t&&0!==t)throw Error("baobab.Cursor.unset: expects a valid key to unset.");if("object"!=typeof this.get())throw Error("baobab.Cursor.set: trying to set key to a non-object.");var r={};return r[t]={$unset:!0},this.update(r)},e.prototype.remove=function(){if(this.isRoot())throw Error("baobab.Cursor.remove: cannot remove root node.");return this.update({$unset:!0})},e.prototype.apply=function(t){if("function"!=typeof t)throw Error("baobab.Cursor.apply: argument is not a function.");return this.update({$apply:t})},e.prototype.chain=function(t){if("function"!=typeof t)throw Error("baobab.Cursor.chain: argument is not a function.");return this.update({$chain:t})},e.prototype.push=function(t){if(!(this.get()instanceof Array))throw Error("baobab.Cursor.push: trying to push to non-array value.");return this.update(arguments.length>1?{$push:s.arrayOf(arguments)}:{$push:t})},e.prototype.unshift=function(t){if(!(this.get()instanceof Array))throw Error("baobab.Cursor.push: trying to push to non-array value.");return this.update(arguments.length>1?{$unshift:s.arrayOf(arguments)}:{$unshift:t})},e.prototype.merge=function(t){if(!a.Object(t))throw Error("baobab.Cursor.merge: trying to merge a non-object.");if(!a.Object(this.get()))throw Error("baobab.Cursor.merge: trying to merge into a non-object.");this.update({$merge:t})},e.prototype.update=function(t){return this.tree.stack(s.pathObject(this.solvedPath,t)),this},e.prototype.or=function(t){return new o("or",this,t)},e.prototype.and=function(t){return new o("and",this,t)},e.prototype.release=function(){this.tree.off("update",this.updateHandler),this.hash&&delete this.tree._cursors[this.hash],delete this.tree,delete this.path,delete this.solvedPath,this.kill()},e.prototype.toJSON=function(){return this.get()},a.Cursor=function(t){return t instanceof e},r.exports=e},{"./combination.js":5,"./helpers.js":7,"./mixins.js":9,"./type.js":10,emmett:3}],7:[function(t,r){function e(t){return Array.prototype.slice.call(t)}function n(t,r){return function(){t(),r.apply(null,arguments)}}function o(t,r){var e,n={};for(e in t)n[e]=t[e];for(e in r)n[e]=r[e];return n}function i(t){var r=t.source,e="";return t.global&&(e+="g"),t.multiline&&(e+="m"),t.ignoreCase&&(e+="i"),t.sticky&&(e+="y"),t.unicode&&(e+="u"),new RegExp(r,e)}function s(t,r){if(!r||"object"!=typeof r||r instanceof Error||r instanceof ArrayBuffer)return r;if(g.Array(r)){if(t){var e,n,o=[];for(e=0,n=r.length;n>e;e++)o.push(_(r[e]));return o}return r.slice(0)}if(g.Date(r))return new Date(r.getTime());if(r instanceof RegExp)return i(r);if(g.Object(r)){var s,a={};r.constructor&&r.constructor!==Object&&(a=Object.create(r.constructor.prototype));for(s in r)r.hasOwnProperty(s)&&(a[s]=t?_(r[s]):r[s]);return a}return r}function a(t,r){return function(e){return r(t(e))}}function h(t,r){var e,n;for(e=0,n=t.length;n>e;e++)if(r(t[e]))return t[e]}function u(t,r){var e,n;for(e=0,n=t.length;n>e;e++)if(r(t[e]))return e;return-1}function c(t,r){var e,n=!0;if(!t)return!1;for(e in r)if(g.Object(r[e]))n=n&&c(t[e],r[e]);else if(g.Array(r[e]))n=n&&!!~r[e].indexOf(t[e]);else if(t[e]!==r[e])return!1;return n}function l(t,r){return h(t,function(t){return c(t,r)})}function f(t,r){return u(t,function(t){return c(t,r)})}function p(t,r){r=r||[];var e,n,o=t;for(e=0,n=r.length;n>e;e++){if(!o)return;if("function"==typeof r[e]){if(!g.Array(o))return;o=h(o,r[e])}else if("object"==typeof r[e]){if(!g.Array(o))return;o=l(o,r[e])}else o=o[r[e]]}return o}function d(t,r){var e,n,o,i=[],s=t;for(n=0,o=r.length;o>n;n++){if(!s)return null;if("function"==typeof r[n]){if(!g.Array(s))return;e=u(s,r[n]),i.push(e),s=s[e]}else if("object"==typeof r[n]){if(!g.Array(s))return;e=f(s,r[n]),i.push(e),s=s[e]}else i.push(r[n]),s=s[r[n]]||{}}return i}function b(t,r){var e,n=t.length,o={},i=o;for(n||(o=r),e=0;n>e;e++)i[t[e]]=e+1===n?r:{},i=i[t[e]];return o}function y(t,r){t.super_=r;var e=function(){};e.prototype=r.prototype,t.prototype=new e,t.prototype.constructor=t}var g=t("./type.js"),m=s.bind(null,!1),_=s.bind(null,!0);r.exports={arrayOf:e,before:n,deepClone:_,shallowClone:m,shallowMerge:o,compose:a,getIn:p,inherits:y,pathObject:b,solvePath:d}},{"./type.js":10}],8:[function(t,r){function e(t,r,e){s.forEach(function(r){e!==r&&delete t[r]}),t[e]=r[e]}function n(t,r){var a,h=o.shallowClone(r||{});s.forEach(function(r){t[r]&&e(h,t,r)}),t.$chain&&(s.slice(0,-1).forEach(function(t){delete h[t]}),h.$apply=h.$apply?o.compose(h.$apply,t.$chain):t.$chain),t.$push&&h.$push?h.$push=i.Array(h.$push)?h.$push.concat(t.$push):[h.$push].concat(t.$push):t.$push&&(h.$push=t.$push),t.$unshift&&h.$unshift?h.$unshift=i.Array(t.$unshift)?t.$unshift.concat(h.$unshift):[t.$unshift].concat(h.$unshift):t.$unshift&&(h.$unshift=t.$unshift);for(a in t)i.Object(t[a])?h[a]=n(t[a],h[a]):"$"!==a[0]&&(h[a]=t[a]);return h}var o=t("./helpers.js"),i=t("./type.js"),s=["$unset","$set","$merge","$apply"];r.exports=n},{"./helpers.js":7,"./type.js":10}],9:[function(t,r){var e=t("./combination.js"),n=t("./type.js");r.exports={baobab:function(t){return{mixins:[{getInitialState:function(){if(this.tree=t,!this.cursor&&!this.cursors)return{};if(this.cursor&&this.cursors)throw Error("baobab.mixin: you cannot have both `component.cursor` and `component.cursors`. Please make up your mind.");if(this.__type=null,this.__updateHandler=function(){this.setState(this.__getCursorData())}.bind(this),this.cursor){if(!n.MixinCursor(this.cursor))throw Error("baobab.mixin.cursor: invalid data (cursor, string, array or function).");n.Function(this.cursor)&&(this.cursor=this.cursor()),n.Cursor(this.cursor)||(this.cursor=t.select(this.cursor)),this.__getCursorData=function(){return{cursor:this.cursor.get()}}.bind(this),this.__type="single"}else if(this.cursors){if(!n.MixinCursors(this.cursors))throw Error("baobab.mixin.cursor: invalid data (object, array or function).");if(n.Function(this.cursors)&&(this.cursors=this.cursors()),n.Array(this.cursors))this.cursors=this.cursors.map(function(r){return n.Cursor(r)?r:t.select(r)}),this.__getCursorData=function(){return{cursors:this.cursors.map(function(t){return t.get()})}}.bind(this),this.__type="array";else{for(var r in this.cursors)n.Cursor(this.cursors[r])||(this.cursors[r]=t.select(this.cursors[r]));this.__getCursorData=function(){var t={};for(r in this.cursors)t[r]=this.cursors[r].get();return{cursors:t}}.bind(this),this.__type="object"}}return this.__getCursorData()},componentDidMount:function(){"single"===this.__type?(this.__combination=new e("or",[this.cursor]),this.__combination.on("update",this.__updateHandler)):"array"===this.__type?(this.__combination=new e("or",this.cursors),this.__combination.on("update",this.__updateHandler)):"object"===this.__type&&(this.__combination=new e("or",Object.keys(this.cursors).map(function(t){return this.cursors[t]},this)),this.__combination.on("update",this.__updateHandler))},componentWillUnmount:function(){this.__combination&&this.__combination.release()}}].concat(t.options.mixins)}},cursor:function(t){return{mixins:[{getInitialState:function(){return this.cursor=t,this.__updateHandler=function(){this.setState({cursor:this.cursor.get()})}.bind(this),{cursor:this.cursor.get()}},componentDidMount:function(){this.cursor.on("update",this.__updateHandler)},componentWillUnmount:function(){this.cursor.off("update",this.__updateHandler)}}].concat(t.tree.options.mixins)}}}},{"./combination.js":5,"./type.js":10}],10:[function(t,r){function e(t,r){return r.some(function(r){return n[r](t)})}var n={};n.Array=function(t){return Array.isArray(t)},n.Object=function(t){return!Array.isArray(t)&&"object"==typeof t&&null!==t},n.String=function(t){return"string"==typeof t},n.Number=function(t){return"number"==typeof t},n.Function=function(t){return"function"==typeof t},n.Primitive=function(t){return"string"==typeof t||"number"==typeof t||"boolean"==typeof t},n.Date=function(t){return t instanceof Date},n.Path=function(t){var r=["String","Number","Function","Object"];return n.Array(t)?t.every(function(t){return e(t,r)}):e(t,r)},n.MixinCursor=function(t){return e(t,["String","Number","Array","Function","Cursor"])},n.MixinCursors=function(t){return e(t,["Object","Array","Function"])},n.ComplexPath=function(t){return e(t,["Object","Function"])},r.exports=n},{}],11:[function(t,r){function e(t,r){var e=new Error("baobab.update: "+r+" at path /"+t.slice(1).toString());return e.path=t,e}var n=t("./helpers.js"),o=t("./type.js");r.exports=function(t,r,i){if(i=i||{},!o.Object(t)&&!o.Array(t))throw Error("baobab.update: invalid target.");var s={};t={root:n.shallowClone(t)};var a=function(t,r,i,h){i=i||["root"];var u,c,l,f=i.join("λ"),p=i[i.length-1],d=Object.keys(r).some(function(t){return!!~["$unset","$set","$apply","$merge","$push","$unshift"].indexOf(t)});if(d){s[f]=!0;for(c in r){if("$unset"===c){var b=i[i.length-2];o.Array(t)?h[b]=t.slice(0,+p).concat(t.slice(+p+1)):(h[b]=n.shallowClone(t),delete h[b][p]);break}if("$set"===c){l=r.$set,t[p]=l;break}if("$apply"===c){if(u=r.$apply,"function"!=typeof u)throw e(i,"using command $apply with a non function");t[p]=u.call(null,t[p]);break}if("$merge"===c){if(l=r.$merge,!o.Object(t[p])||!o.Object(l))throw e(i,"using command $merge with a non object");t[p]=n.shallowMerge(t[p],l);break}if("$push"===c){if(l=r.$push,!o.Array(t[p]))throw e(i,"using command $push to a non array");t[p]=t[p].concat(l)}if("$unshift"===c){if(l=r.$unshift,!o.Array(t[p]))throw e(i,"using command $unshift to a non array");t[p]=[].concat(l).concat(t[p])}}}else for(c in r)t[p][c]="undefined"==typeof t[p][c]?{}:n.shallowClone(t[p][c]),a(t[p],r[c],i.concat(c),t)};return a(t,r),{data:t.root,log:Object.keys(s).map(function(t){return t.split("λ").slice(1)})}}},{"./helpers.js":7,"./type.js":10}]},{},[2])(2)}); \ No newline at end of file +!function(t){if("object"==typeof exports&&"undefined"!=typeof module)module.exports=t();else if("function"==typeof define&&define.amd)define([],t);else{var r;r="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:this,r.Baobab=t()}}(function(){var t;return function r(t,e,n){function o(s,a){if(!e[s]){if(!t[s]){var h="function"==typeof require&&require;if(!a&&h)return h(s,!0);if(i)return i(s,!0);var u=new Error("Cannot find module '"+s+"'");throw u.code="MODULE_NOT_FOUND",u}var c=e[s]={exports:{}};t[s][0].call(c.exports,function(r){var e=t[s][1][r];return o(e?e:r)},c,c.exports,r,t,e,n)}return e[s].exports}for(var i="function"==typeof require&&require,s=0;sr;r++)n.push(t[r].handler);return n}var o={once:"boolean",scope:"object"},i=function(){this._enabled=!0,this._children=[],this._handlers={},this._handlersAll=[]};i.prototype.on=function(t,r,e){var n,s,a,h,u,c;if("function"==typeof r){for(u="string"==typeof t?[t]:t,n=0,s=u.length;n!==s;n+=1)if(h=u[n]){this._handlers[h]||(this._handlers[h]=[]),c={handler:r};for(a in e||{}){if(!o[a])throw new Error('The option "'+a+'" is not recognized by Emmett.');c[a]=e[a]}this._handlers[h].push(c)}}else if(t&&"object"==typeof t&&!Array.isArray(t))for(h in t)i.prototype.on.call(this,h,t[h],r);else{if("function"!=typeof t)throw new Error("Wrong arguments.");c={handler:t};for(a in e||{}){if(!o[a])throw new Error('The option "'+a+'" is not recognized by Emmett.');c[a]=e[a]}this._handlersAll.push(c)}return this},i.prototype.once=function(t,r,e){if("function"==typeof r)e=e||{},e.once=!0,this.on(t,r,e);else{if((!t||"object"!=typeof t||Array.isArray(t))&&"function"!=typeof t)throw new Error("Wrong arguments.");r=r||{},r.once=!0,this.on(t,r)}return this},i.prototype.off=function(t,r){var e,n,o,i,s,a,h,u="string"==typeof t?[t]:t;if(1===arguments.length&&"function"==typeof u){r=arguments[0];for(s in this._handlers){for(a=[],e=0,n=this._handlers[s].length;e!==n;e+=1)this._handlers[s][e].handler!==r&&a.push(this._handlers[s][e]);this._handlers[s]=a}for(a=[],e=0,n=this._handlersAll.length;e!==n;e+=1)this._handlersAll[e].handler!==r&&a.push(this._handlersAll[e]);this._handlersAll=a}else if(2===arguments.length)for(e=0,n=u.length;e!==n;e+=1){if(h=u[e],this._handlers[h]){for(a=[],o=0,i=this._handlers[h].length;o!==i;o+=1)this._handlers[h][o].handler!==r&&a.push(this._handlers[h][o]);this._handlers[h]=a}this._handlers[h]&&0===this._handlers[h].length&&delete this._handlers[h]}return this},i.prototype.unbindAll=function(){var t;this._handlersAll=[];for(t in this._handlers)delete this._handlers[t];return this},i.prototype.emit=function(t,r){var e,n,o,i,s,a,h,u,c,l,f="string"==typeof t?[t]:t;if(!this._enabled)return this;for(r=void 0===r?{}:r,e=0,n=f.length;e!==n;e+=1)if(l=f[e],c=(this._handlers[l]||[]).concat(this._handlersAll),c.length){for(h={type:l,data:r||{},target:this},a=[],o=0,i=c.length;o!==i;o+=1)(this._handlers[l]&&this._handlers[l].indexOf(c[o])>=0||this._handlersAll.indexOf(c[o])>=0)&&(c[o].handler.call("scope"in c[o]?c[o].scope:this,h),c[o].once&&a.push(c[o]));for(s=0;se;e++)if(t._children[e]===r){t._children.splice(e,1);break}}),this._children.push(r),r},i.prototype.listeners=function(t){var e,n,o,i=[];if(t)for(i=r(this._handlers[t]),n=0,o=this._children.length;o>n;n++)i=i.concat(this._children[n].listeners(t));else{i=r(this._handlersAll);for(e in this._handlers)i=i.concat(r(this._handlers[e]));for(n=0,o=this._children.length;o>n;n++)i=i.concat(this._children[n].listeners())}return i},i.prototype.kill=function(){if(this.emit("emmett:kill"),this.unbindAll(),this._handlers=null,this._handlersAll=null,this._enabled=!1,this._children)for(var t=0,r=this._children.length;r>t;t++)this._children[t].kill();this._children=null},i.prototype.disable=function(){return this._enabled=!1,this},i.prototype.enable=function(){return this._enabled=!0,this},i.version="2.1.2","undefined"!=typeof n?("undefined"!=typeof e&&e.exports&&(n=e.exports=i),n.Emitter=i):"function"==typeof t&&t.amd?t("emmett",[],function(){return i}):this.Emitter=i}).call(this)},{}],4:[function(t,r){function e(t){return t+"$"+(new Date).getTime()+(""+Math.random()).replace("0.","")}function n(t,r){function e(t){this[t]=function(){var r=this.root[t].apply(this.root,arguments);return r instanceof o?this:r}}if(arguments.length<1&&(t={}),!(this instanceof n))return new n(t,r);if(!l.Object(t)&&!l.Array(t))throw Error("Baobab: invalid data.");i.call(this),this.options=s.shallowMerge(c,r),this._transaction={},this._future=void 0,this._cursors={},this.data=s.deepClone(t),this.root=this.select([]),["get","set","unset","update"].forEach(e.bind(this)),this.mixin=u.baobab(this)}var o=t("./cursor.js"),i=t("emmett"),s=t("./helpers.js"),a=t("./update.js"),h=t("./merge.js"),u=t("./mixins.js"),c=t("../defaults.js"),l=t("./type.js");s.inherits(n,i),n.prototype.select=function(t){if(!t)throw Error("Baobab.select: invalid path.");if(arguments.length>1&&(t=s.arrayOf(arguments)),!l.Path(t))throw Error("Baobab.select: invalid path.");t=[].concat(t);var r,n=l.ComplexPath(t);n&&(r=s.solvePath(this.data,t));var i=t.map(function(t){return l.Function(t)?e("fn"):l.Object(t)?e("ob"):t}).join("λ");if(this._cursors[i])return this._cursors[i];var a=new o(this,t,r,i);return this._cursors[i]=a,a},n.prototype.stack=function(t){var r=this;if(!l.Object(t))throw Error("Baobab.update: wrong specification.");return this._transaction=h(t,this._transaction),this.options.autoCommit?this.options.asynchronous?(this._future||(this._future=setTimeout(r.commit.bind(r,null),0)),this):this.commit():this},n.prototype.commit=function(){var t=a(this.data,this._transaction,this.options);return this.data=t.data,this._transaction={},this._future&&(this._future=clearTimeout(this._future)),this.emit("update",{log:t.log}),this},n.prototype.release=function(){delete this.data,delete this._transaction;for(var t in this._cursors)this._cursors[t].release();delete this._cursors,this.kill()},n.prototype.toJSON=function(){return this.get()},r.exports=n},{"../defaults.js":1,"./cursor.js":6,"./helpers.js":7,"./merge.js":8,"./mixins.js":9,"./type.js":10,"./update.js":11,emmett:3}],5:[function(t,r){function e(t,r){r.on("update",t.cursorListener),t.tree.off("update",t.treeListener),t.tree.on("update",t.treeListener)}function n(t){var r=this;if(arguments.length<2)throw Error("baobab.Combination: not enough arguments.");var n=arguments[1],o=s.arrayOf(arguments).slice(2);if(n instanceof Array&&(o=n.slice(1),n=n[0]),!a.Cursor(n))throw Error("baobab.Combination: argument should be a cursor.");if("or"!==t&&"and"!==t)throw Error("baobab.Combination: invalid operator.");i.call(this),this.cursors=[n],this.operators=[],this.tree=n.tree,this.updates=new Array(this.cursors.length),this.cursorListener=function(){r.updates[r.cursors.indexOf(this)]=!0},this.treeListener=function(){var t,e,n=r.updates[0];for(t=1,e=r.cursors.length;e>t;t++)n="or"===r.operators[t-1]?n||r.updates[t]:n&&r.updates[t];n&&r.emit("update"),r.updates=new Array(r.cursors.length)},this.bound=!1;var h=(this.on,this.once,function(){r.bound||(r.bound=!0,r.cursors.forEach(function(t){e(r,t)}))});this.on=s.before(h,this.on.bind(this)),this.once=s.before(h,this.once.bind(this)),o.forEach(function(r){this[t](r)},this)}function o(t){n.prototype[t]=function(r){if(!a.Cursor(r))throw this.release(),Error("baobab.Combination."+t+": argument should be a cursor.");if(~this.cursors.indexOf(r))throw this.release(),Error("baobab.Combination."+t+": cursor already in combination.");return this.cursors.push(r),this.operators.push(t),this.updates.length++,this.bound&&e(this,r),this}}var i=t("emmett"),s=t("./helpers.js"),a=t("./type.js");s.inherits(n,i),o("or"),o("and"),n.prototype.release=function(){this.cursors.forEach(function(t){t.off("update",this.cursorListener)},this),this.tree.off("update",this.treeListener),this.cursors=null,this.operators=null,this.tree=null,this.updates=null,this.kill()},r.exports=n},{"./helpers.js":7,"./type.js":10,emmett:3}],6:[function(t,r){function e(t,r,e,o){var a=this;n.call(this),r=r||[],this.tree=t,this.path=r,this.hash=o,this.complexPath=!!e,this.solvedPath=this.complexPath?e:this.path,this.relevant=void 0!==this.get(),this.updateHandler=function(t){var r,e,n,o,i,h,u=t.data.log,c=!1;if(a.complexPath&&(a.solvedPath=s.solvePath(a.tree.data,a.path)),!a.path.length)return a.emit("update");t:for(i=0,n=u.length;n>i;i++)for(r=u[i],h=0,o=r.length;o>h&&(e=r[h],e===""+a.solvedPath[h]);h++)if(h+1===o||h+1===a.solvedPath.length){c=!0;break t}var l=void 0!==a.get();a.relevant?l&&c?a.emit("update"):l||(a.emit("irrelevant"),a.relevant=!1):l&&c&&(a.emit("relevant"),a.emit("update"),a.relevant=!0)},this.mixin=i.cursor(this);var h=!1,u=function(){h||(h=!0,a.tree.on("update",a.updateHandler))};this.on=s.before(u,this.on.bind(this)),this.once=s.before(u,this.once.bind(this))}var n=t("emmett"),o=t("./combination.js"),i=t("./mixins.js"),s=t("./helpers.js"),a=t("./type.js");s.inherits(e,n),e.prototype.isRoot=function(){return!this.path.length},e.prototype.isLeaf=function(){return a.Primitive(this.get())},e.prototype.isBranch=function(){return!this.isLeaf()&&!this.isRoot()},e.prototype.root=function(){return this.tree.root()},e.prototype.select=function(t){if(arguments.length>1&&(t=s.arrayOf(arguments)),!a.Path(t))throw Error("baobab.Cursor.select: invalid path.");return this.tree.select(this.path.concat(t))},e.prototype.up=function(){return this.solvedPath&&this.solvedPath.length?this.tree.select(this.path.slice(0,-1)):null},e.prototype.left=function(){var t=+this.solvedPath[this.solvedPath.length-1];if(isNaN(t))throw Error("baobab.Cursor.left: cannot go left on a non-list type.");return t?this.tree.select(this.solvedPath.slice(0,-1).concat(t-1)):null},e.prototype.leftmost=function(){var t=+this.solvedPath[this.solvedPath.length-1];if(isNaN(t))throw Error("baobab.Cursor.leftmost: cannot go left on a non-list type.");return this.tree.select(this.solvedPath.slice(0,-1).concat(0))},e.prototype.right=function(){var t=+this.solvedPath[this.solvedPath.length-1];if(isNaN(t))throw Error("baobab.Cursor.right: cannot go right on a non-list type.");return t+1===this.up().get().length?null:this.tree.select(this.solvedPath.slice(0,-1).concat(t+1))},e.prototype.rightmost=function(){var t=+this.solvedPath[this.solvedPath.length-1];if(isNaN(t))throw Error("baobab.Cursor.right: cannot go right on a non-list type.");var r=this.up().get();return this.tree.select(this.solvedPath.slice(0,-1).concat(r.length-1))},e.prototype.down=function(){+this.solvedPath[this.solvedPath.length-1];return this.get()instanceof Array?this.tree.select(this.solvedPath.concat(0)):null},e.prototype.get=function(t){arguments.length>1&&(t=s.arrayOf(arguments));var r=this.solvedPath.concat((a.String(t)||a.Number(t)?[t]:t)||[]);return s.getIn(this.tree.data,r)},e.prototype.set=function(t,r){arguments.length<2&&(r=t,t=[]);var e=[].concat(t),n=s.solvePath(this.get(),e);if(!n)throw Error("baobab.Cursor.set: could not solve dynamic path.");var o=s.pathObject(n,{$set:r});return this.update(o)},e.prototype.edit=function(t){return this.update({$set:t})},e.prototype.unset=function(t){if(!t&&0!==t)throw Error("baobab.Cursor.unset: expects a valid key to unset.");if("object"!=typeof this.get())throw Error("baobab.Cursor.set: trying to set key to a non-object.");var r={};return r[t]={$unset:!0},this.update(r)},e.prototype.remove=function(){if(this.isRoot())throw Error("baobab.Cursor.remove: cannot remove root node.");return this.update({$unset:!0})},e.prototype.apply=function(t){if("function"!=typeof t)throw Error("baobab.Cursor.apply: argument is not a function.");return this.update({$apply:t})},e.prototype.chain=function(t){if("function"!=typeof t)throw Error("baobab.Cursor.chain: argument is not a function.");return this.update({$chain:t})},e.prototype.push=function(t){if(!(this.get()instanceof Array))throw Error("baobab.Cursor.push: trying to push to non-array value.");return this.update(arguments.length>1?{$push:s.arrayOf(arguments)}:{$push:t})},e.prototype.unshift=function(t){if(!(this.get()instanceof Array))throw Error("baobab.Cursor.push: trying to push to non-array value.");return this.update(arguments.length>1?{$unshift:s.arrayOf(arguments)}:{$unshift:t})},e.prototype.merge=function(t){if(!a.Object(t))throw Error("baobab.Cursor.merge: trying to merge a non-object.");if(!a.Object(this.get()))throw Error("baobab.Cursor.merge: trying to merge into a non-object.");this.update({$merge:t})},e.prototype.update=function(t){return this.tree.stack(s.pathObject(this.solvedPath,t)),this},e.prototype.or=function(t){return new o("or",this,t)},e.prototype.and=function(t){return new o("and",this,t)},e.prototype.release=function(){this.tree.off("update",this.updateHandler),this.hash&&delete this.tree._cursors[this.hash],delete this.tree,delete this.path,delete this.solvedPath,this.kill()},e.prototype.toJSON=function(){return this.get()},a.Cursor=function(t){return t instanceof e},r.exports=e},{"./combination.js":5,"./helpers.js":7,"./mixins.js":9,"./type.js":10,emmett:3}],7:[function(t,r){function e(t){return Array.prototype.slice.call(t)}function n(t,r){return function(){t(),r.apply(null,arguments)}}function o(t,r){var e,n={};for(e in t)n[e]=t[e];for(e in r)n[e]=r[e];return n}function i(t){var r=t.source,e="";return t.global&&(e+="g"),t.multiline&&(e+="m"),t.ignoreCase&&(e+="i"),t.sticky&&(e+="y"),t.unicode&&(e+="u"),new RegExp(r,e)}function s(t,r){if(!r||"object"!=typeof r||r instanceof Error||r instanceof ArrayBuffer)return r;if(g.Array(r)){if(t){var e,n,o=[];for(e=0,n=r.length;n>e;e++)o.push(_(r[e]));return o}return r.slice(0)}if(g.Date(r))return new Date(r.getTime());if(r instanceof RegExp)return i(r);if(g.Object(r)){var s,a={};r.constructor&&r.constructor!==Object&&(a=Object.create(r.constructor.prototype));for(s in r)r.hasOwnProperty(s)&&(a[s]=t?_(r[s]):r[s]);return a}return r}function a(t,r){return function(e){return r(t(e))}}function h(t,r){var e,n;for(e=0,n=t.length;n>e;e++)if(r(t[e]))return t[e]}function u(t,r){var e,n;for(e=0,n=t.length;n>e;e++)if(r(t[e]))return e;return-1}function c(t,r){var e,n=!0;if(!t)return!1;for(e in r)if(g.Object(r[e]))n=n&&c(t[e],r[e]);else if(g.Array(r[e]))n=n&&!!~r[e].indexOf(t[e]);else if(t[e]!==r[e])return!1;return n}function l(t,r){return h(t,function(t){return c(t,r)})}function f(t,r){return u(t,function(t){return c(t,r)})}function p(t,r){r=r||[];var e,n,o=t;for(e=0,n=r.length;n>e;e++){if(!o)return;if("function"==typeof r[e]){if(!g.Array(o))return;o=h(o,r[e])}else if("object"==typeof r[e]){if(!g.Array(o))return;o=l(o,r[e])}else o=o[r[e]]}return o}function d(t,r){var e,n,o,i=[],s=t;for(n=0,o=r.length;o>n;n++){if(!s)return null;if("function"==typeof r[n]){if(!g.Array(s))return;e=u(s,r[n]),i.push(e),s=s[e]}else if("object"==typeof r[n]){if(!g.Array(s))return;e=f(s,r[n]),i.push(e),s=s[e]}else i.push(r[n]),s=s[r[n]]||{}}return i}function b(t,r){var e,n=t.length,o={},i=o;for(n||(o=r),e=0;n>e;e++)i[t[e]]=e+1===n?r:{},i=i[t[e]];return o}function y(t,r){t.super_=r;var e=function(){};e.prototype=r.prototype,t.prototype=new e,t.prototype.constructor=t}var g=t("./type.js"),m=s.bind(null,!1),_=s.bind(null,!0);r.exports={arrayOf:e,before:n,deepClone:_,shallowClone:m,shallowMerge:o,compose:a,getIn:p,inherits:y,pathObject:b,solvePath:d}},{"./type.js":10}],8:[function(t,r){function e(t,r,e){s.forEach(function(r){e!==r&&delete t[r]}),t[e]=r[e]}function n(t,r){var a,h=o.shallowClone(r||{});s.forEach(function(r){t[r]&&e(h,t,r)}),t.$chain&&(s.slice(0,-1).forEach(function(t){delete h[t]}),h.$apply=h.$apply?o.compose(h.$apply,t.$chain):t.$chain),t.$push&&h.$push?h.$push=i.Array(h.$push)?h.$push.concat(t.$push):[h.$push].concat(t.$push):t.$push&&(h.$push=t.$push),t.$unshift&&h.$unshift?h.$unshift=i.Array(t.$unshift)?t.$unshift.concat(h.$unshift):[t.$unshift].concat(h.$unshift):t.$unshift&&(h.$unshift=t.$unshift);for(a in t)i.Object(t[a])?h[a]=n(t[a],h[a]):"$"!==a[0]&&(h[a]=t[a]);return h}var o=t("./helpers.js"),i=t("./type.js"),s=["$unset","$set","$merge","$apply"];r.exports=n},{"./helpers.js":7,"./type.js":10}],9:[function(t,r){var e=t("./combination.js"),n=t("./type.js");r.exports={baobab:function(t){return{mixins:[{getInitialState:function(){if(this.tree=t,!this.cursor&&!this.cursors)return{};if(this.cursor&&this.cursors)throw Error("baobab.mixin: you cannot have both `component.cursor` and `component.cursors`. Please make up your mind.");if(this.__type=null,this.__updateHandler=function(){this.setState(this.__getCursorData())}.bind(this),this.cursor){if(!n.MixinCursor(this.cursor))throw Error("baobab.mixin.cursor: invalid data (cursor, string, array or function).");n.Function(this.cursor)&&(this.cursor=this.cursor()),n.Cursor(this.cursor)||(this.cursor=t.select(this.cursor)),this.__getCursorData=function(){return{cursor:this.cursor.get()}}.bind(this),this.__type="single"}else if(this.cursors){if(!n.MixinCursors(this.cursors))throw Error("baobab.mixin.cursor: invalid data (object, array or function).");if(n.Function(this.cursors)&&(this.cursors=this.cursors()),n.Array(this.cursors))this.cursors=this.cursors.map(function(r){return n.Cursor(r)?r:t.select(r)}),this.__getCursorData=function(){return{cursors:this.cursors.map(function(t){return t.get()})}}.bind(this),this.__type="array";else{for(var r in this.cursors)n.Cursor(this.cursors[r])||(this.cursors[r]=t.select(this.cursors[r]));this.__getCursorData=function(){var t={};for(r in this.cursors)t[r]=this.cursors[r].get();return{cursors:t}}.bind(this),this.__type="object"}}return this.__getCursorData()},componentDidMount:function(){"single"===this.__type?(this.__combination=new e("or",[this.cursor]),this.__combination.on("update",this.__updateHandler)):"array"===this.__type?(this.__combination=new e("or",this.cursors),this.__combination.on("update",this.__updateHandler)):"object"===this.__type&&(this.__combination=new e("or",Object.keys(this.cursors).map(function(t){return this.cursors[t]},this)),this.__combination.on("update",this.__updateHandler))},componentWillUnmount:function(){this.__combination&&this.__combination.release()}}].concat(t.options.mixins)}},cursor:function(t){return{mixins:[{getInitialState:function(){return this.cursor=t,this.__updateHandler=function(){this.setState({cursor:this.cursor.get()})}.bind(this),{cursor:this.cursor.get()}},componentDidMount:function(){this.cursor.on("update",this.__updateHandler)},componentWillUnmount:function(){this.cursor.off("update",this.__updateHandler)}}].concat(t.tree.options.mixins)}}}},{"./combination.js":5,"./type.js":10}],10:[function(t,r){function e(t,r){return r.some(function(r){return n[r](t)})}var n={};n.Array=function(t){return Array.isArray(t)},n.Object=function(t){return!Array.isArray(t)&&"object"==typeof t&&null!==t},n.String=function(t){return"string"==typeof t},n.Number=function(t){return"number"==typeof t},n.Function=function(t){return"function"==typeof t},n.Primitive=function(t){return"string"==typeof t||"number"==typeof t||"boolean"==typeof t},n.Date=function(t){return t instanceof Date},n.Path=function(t){var r=["String","Number","Function","Object"];return n.Array(t)?t.every(function(t){return e(t,r)}):e(t,r)},n.MixinCursor=function(t){return e(t,["String","Number","Array","Function","Cursor"])},n.MixinCursors=function(t){return e(t,["Object","Array","Function"])},n.ComplexPath=function(t){return e(t,["Object","Function"])},r.exports=n},{}],11:[function(t,r){function e(t,r){var e=new Error("baobab.update: "+r+" at path /"+t.slice(1).toString());return e.path=t,e}var n=t("./helpers.js"),o=t("./type.js");r.exports=function(t,r,i){if(i=i||{},!o.Object(t)&&!o.Array(t))throw Error("baobab.update: invalid target.");var s={};t={root:n.shallowClone(t)};var a=function(t,r,i,h){i=i||["root"];var u,c,l,f=i.join("λ"),p=i[i.length-1],d=Object.keys(r).some(function(t){return!!~["$unset","$set","$apply","$merge","$push","$unshift"].indexOf(t)});if(d){s[f]=!0;for(c in r){if("$unset"===c){var b=i[i.length-2];o.Array(t)?h[b]=t.slice(0,+p).concat(t.slice(+p+1)):(h[b]=n.shallowClone(t),delete h[b][p]);break}if("$set"===c){l=r.$set,t[p]=l;break}if("$apply"===c){if(u=r.$apply,"function"!=typeof u)throw e(i,"using command $apply with a non function");t[p]=u.call(null,t[p]);break}if("$merge"===c){if(l=r.$merge,!o.Object(t[p])||!o.Object(l))throw e(i,"using command $merge with a non object");t[p]=n.shallowMerge(t[p],l);break}if("$push"===c){if(l=r.$push,!o.Array(t[p]))throw e(i,"using command $push to a non array");t[p]=t[p].concat(l)}if("$unshift"===c){if(l=r.$unshift,!o.Array(t[p]))throw e(i,"using command $unshift to a non array");t[p]=[].concat(l).concat(t[p])}}}else for(c in r)t[p][c]="undefined"==typeof t[p][c]?{}:n.shallowClone(t[p][c]),a(t[p],r[c],i.concat(c),t)};return a(t,r),{data:t.root,log:Object.keys(s).map(function(t){return t.split("λ").slice(1)})}}},{"./helpers.js":7,"./type.js":10}]},{},[2])(2)}); \ No newline at end of file diff --git a/src/cursor.js b/src/cursor.js index e192e2a..9d5b59c 100644 --- a/src/cursor.js +++ b/src/cursor.js @@ -216,27 +216,19 @@ Cursor.prototype.get = function(path) { * Update */ Cursor.prototype.set = function(key, val) { - if (arguments.length < 2) - throw Error('baobab.Cursor.set: expecting at least key/value.'); - - var data = this.get(); - - if (typeof data !== 'object') - throw Error('baobab.Cursor.set: trying to set key to a non-object.'); - - var spec = {}; + if (arguments.length < 2) { + val = key; + key = []; + } - if (type.Array(key)) { - var path = helpers.solvePath(data, key); + // Solving path + var path = [].concat(key), + solvedPath = helpers.solvePath(this.get(), path); - if (!path) - throw Error('baobab.Cursor.set: could not solve dynamic path.'); + if (!solvedPath) + throw Error('baobab.Cursor.set: could not solve dynamic path.'); - spec = helpers.pathObject(path, {$set: val}); - } - else { - spec[key] = {$set: val}; - } + var spec = helpers.pathObject(solvedPath, {$set: val}); return this.update(spec); }; From 455dc18196e5ce7f324e6bba098ec42e4e10da85 Mon Sep 17 00:00:00 2001 From: Yomguithereal Date: Wed, 1 Apr 2015 15:54:32 +0200 Subject: [PATCH 19/73] Removing cursor.edit --- build/baobab.min.js | 2 +- src/cursor.js | 4 ---- test/suites/combination.js | 44 +++++++++++++++++++------------------- test/suites/cursor.js | 10 ++++----- 4 files changed, 28 insertions(+), 32 deletions(-) diff --git a/build/baobab.min.js b/build/baobab.min.js index 98371b0..2e4c66c 100644 --- a/build/baobab.min.js +++ b/build/baobab.min.js @@ -1,2 +1,2 @@ /* baobab.js - Version: 1.0.0-rc1 - Author: Yomguithereal (Guillaume Plique) */ -!function(t){if("object"==typeof exports&&"undefined"!=typeof module)module.exports=t();else if("function"==typeof define&&define.amd)define([],t);else{var r;r="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:this,r.Baobab=t()}}(function(){var t;return function r(t,e,n){function o(s,a){if(!e[s]){if(!t[s]){var h="function"==typeof require&&require;if(!a&&h)return h(s,!0);if(i)return i(s,!0);var u=new Error("Cannot find module '"+s+"'");throw u.code="MODULE_NOT_FOUND",u}var c=e[s]={exports:{}};t[s][0].call(c.exports,function(r){var e=t[s][1][r];return o(e?e:r)},c,c.exports,r,t,e,n)}return e[s].exports}for(var i="function"==typeof require&&require,s=0;sr;r++)n.push(t[r].handler);return n}var o={once:"boolean",scope:"object"},i=function(){this._enabled=!0,this._children=[],this._handlers={},this._handlersAll=[]};i.prototype.on=function(t,r,e){var n,s,a,h,u,c;if("function"==typeof r){for(u="string"==typeof t?[t]:t,n=0,s=u.length;n!==s;n+=1)if(h=u[n]){this._handlers[h]||(this._handlers[h]=[]),c={handler:r};for(a in e||{}){if(!o[a])throw new Error('The option "'+a+'" is not recognized by Emmett.');c[a]=e[a]}this._handlers[h].push(c)}}else if(t&&"object"==typeof t&&!Array.isArray(t))for(h in t)i.prototype.on.call(this,h,t[h],r);else{if("function"!=typeof t)throw new Error("Wrong arguments.");c={handler:t};for(a in e||{}){if(!o[a])throw new Error('The option "'+a+'" is not recognized by Emmett.');c[a]=e[a]}this._handlersAll.push(c)}return this},i.prototype.once=function(t,r,e){if("function"==typeof r)e=e||{},e.once=!0,this.on(t,r,e);else{if((!t||"object"!=typeof t||Array.isArray(t))&&"function"!=typeof t)throw new Error("Wrong arguments.");r=r||{},r.once=!0,this.on(t,r)}return this},i.prototype.off=function(t,r){var e,n,o,i,s,a,h,u="string"==typeof t?[t]:t;if(1===arguments.length&&"function"==typeof u){r=arguments[0];for(s in this._handlers){for(a=[],e=0,n=this._handlers[s].length;e!==n;e+=1)this._handlers[s][e].handler!==r&&a.push(this._handlers[s][e]);this._handlers[s]=a}for(a=[],e=0,n=this._handlersAll.length;e!==n;e+=1)this._handlersAll[e].handler!==r&&a.push(this._handlersAll[e]);this._handlersAll=a}else if(2===arguments.length)for(e=0,n=u.length;e!==n;e+=1){if(h=u[e],this._handlers[h]){for(a=[],o=0,i=this._handlers[h].length;o!==i;o+=1)this._handlers[h][o].handler!==r&&a.push(this._handlers[h][o]);this._handlers[h]=a}this._handlers[h]&&0===this._handlers[h].length&&delete this._handlers[h]}return this},i.prototype.unbindAll=function(){var t;this._handlersAll=[];for(t in this._handlers)delete this._handlers[t];return this},i.prototype.emit=function(t,r){var e,n,o,i,s,a,h,u,c,l,f="string"==typeof t?[t]:t;if(!this._enabled)return this;for(r=void 0===r?{}:r,e=0,n=f.length;e!==n;e+=1)if(l=f[e],c=(this._handlers[l]||[]).concat(this._handlersAll),c.length){for(h={type:l,data:r||{},target:this},a=[],o=0,i=c.length;o!==i;o+=1)(this._handlers[l]&&this._handlers[l].indexOf(c[o])>=0||this._handlersAll.indexOf(c[o])>=0)&&(c[o].handler.call("scope"in c[o]?c[o].scope:this,h),c[o].once&&a.push(c[o]));for(s=0;se;e++)if(t._children[e]===r){t._children.splice(e,1);break}}),this._children.push(r),r},i.prototype.listeners=function(t){var e,n,o,i=[];if(t)for(i=r(this._handlers[t]),n=0,o=this._children.length;o>n;n++)i=i.concat(this._children[n].listeners(t));else{i=r(this._handlersAll);for(e in this._handlers)i=i.concat(r(this._handlers[e]));for(n=0,o=this._children.length;o>n;n++)i=i.concat(this._children[n].listeners())}return i},i.prototype.kill=function(){if(this.emit("emmett:kill"),this.unbindAll(),this._handlers=null,this._handlersAll=null,this._enabled=!1,this._children)for(var t=0,r=this._children.length;r>t;t++)this._children[t].kill();this._children=null},i.prototype.disable=function(){return this._enabled=!1,this},i.prototype.enable=function(){return this._enabled=!0,this},i.version="2.1.2","undefined"!=typeof n?("undefined"!=typeof e&&e.exports&&(n=e.exports=i),n.Emitter=i):"function"==typeof t&&t.amd?t("emmett",[],function(){return i}):this.Emitter=i}).call(this)},{}],4:[function(t,r){function e(t){return t+"$"+(new Date).getTime()+(""+Math.random()).replace("0.","")}function n(t,r){function e(t){this[t]=function(){var r=this.root[t].apply(this.root,arguments);return r instanceof o?this:r}}if(arguments.length<1&&(t={}),!(this instanceof n))return new n(t,r);if(!l.Object(t)&&!l.Array(t))throw Error("Baobab: invalid data.");i.call(this),this.options=s.shallowMerge(c,r),this._transaction={},this._future=void 0,this._cursors={},this.data=s.deepClone(t),this.root=this.select([]),["get","set","unset","update"].forEach(e.bind(this)),this.mixin=u.baobab(this)}var o=t("./cursor.js"),i=t("emmett"),s=t("./helpers.js"),a=t("./update.js"),h=t("./merge.js"),u=t("./mixins.js"),c=t("../defaults.js"),l=t("./type.js");s.inherits(n,i),n.prototype.select=function(t){if(!t)throw Error("Baobab.select: invalid path.");if(arguments.length>1&&(t=s.arrayOf(arguments)),!l.Path(t))throw Error("Baobab.select: invalid path.");t=[].concat(t);var r,n=l.ComplexPath(t);n&&(r=s.solvePath(this.data,t));var i=t.map(function(t){return l.Function(t)?e("fn"):l.Object(t)?e("ob"):t}).join("λ");if(this._cursors[i])return this._cursors[i];var a=new o(this,t,r,i);return this._cursors[i]=a,a},n.prototype.stack=function(t){var r=this;if(!l.Object(t))throw Error("Baobab.update: wrong specification.");return this._transaction=h(t,this._transaction),this.options.autoCommit?this.options.asynchronous?(this._future||(this._future=setTimeout(r.commit.bind(r,null),0)),this):this.commit():this},n.prototype.commit=function(){var t=a(this.data,this._transaction,this.options);return this.data=t.data,this._transaction={},this._future&&(this._future=clearTimeout(this._future)),this.emit("update",{log:t.log}),this},n.prototype.release=function(){delete this.data,delete this._transaction;for(var t in this._cursors)this._cursors[t].release();delete this._cursors,this.kill()},n.prototype.toJSON=function(){return this.get()},r.exports=n},{"../defaults.js":1,"./cursor.js":6,"./helpers.js":7,"./merge.js":8,"./mixins.js":9,"./type.js":10,"./update.js":11,emmett:3}],5:[function(t,r){function e(t,r){r.on("update",t.cursorListener),t.tree.off("update",t.treeListener),t.tree.on("update",t.treeListener)}function n(t){var r=this;if(arguments.length<2)throw Error("baobab.Combination: not enough arguments.");var n=arguments[1],o=s.arrayOf(arguments).slice(2);if(n instanceof Array&&(o=n.slice(1),n=n[0]),!a.Cursor(n))throw Error("baobab.Combination: argument should be a cursor.");if("or"!==t&&"and"!==t)throw Error("baobab.Combination: invalid operator.");i.call(this),this.cursors=[n],this.operators=[],this.tree=n.tree,this.updates=new Array(this.cursors.length),this.cursorListener=function(){r.updates[r.cursors.indexOf(this)]=!0},this.treeListener=function(){var t,e,n=r.updates[0];for(t=1,e=r.cursors.length;e>t;t++)n="or"===r.operators[t-1]?n||r.updates[t]:n&&r.updates[t];n&&r.emit("update"),r.updates=new Array(r.cursors.length)},this.bound=!1;var h=(this.on,this.once,function(){r.bound||(r.bound=!0,r.cursors.forEach(function(t){e(r,t)}))});this.on=s.before(h,this.on.bind(this)),this.once=s.before(h,this.once.bind(this)),o.forEach(function(r){this[t](r)},this)}function o(t){n.prototype[t]=function(r){if(!a.Cursor(r))throw this.release(),Error("baobab.Combination."+t+": argument should be a cursor.");if(~this.cursors.indexOf(r))throw this.release(),Error("baobab.Combination."+t+": cursor already in combination.");return this.cursors.push(r),this.operators.push(t),this.updates.length++,this.bound&&e(this,r),this}}var i=t("emmett"),s=t("./helpers.js"),a=t("./type.js");s.inherits(n,i),o("or"),o("and"),n.prototype.release=function(){this.cursors.forEach(function(t){t.off("update",this.cursorListener)},this),this.tree.off("update",this.treeListener),this.cursors=null,this.operators=null,this.tree=null,this.updates=null,this.kill()},r.exports=n},{"./helpers.js":7,"./type.js":10,emmett:3}],6:[function(t,r){function e(t,r,e,o){var a=this;n.call(this),r=r||[],this.tree=t,this.path=r,this.hash=o,this.complexPath=!!e,this.solvedPath=this.complexPath?e:this.path,this.relevant=void 0!==this.get(),this.updateHandler=function(t){var r,e,n,o,i,h,u=t.data.log,c=!1;if(a.complexPath&&(a.solvedPath=s.solvePath(a.tree.data,a.path)),!a.path.length)return a.emit("update");t:for(i=0,n=u.length;n>i;i++)for(r=u[i],h=0,o=r.length;o>h&&(e=r[h],e===""+a.solvedPath[h]);h++)if(h+1===o||h+1===a.solvedPath.length){c=!0;break t}var l=void 0!==a.get();a.relevant?l&&c?a.emit("update"):l||(a.emit("irrelevant"),a.relevant=!1):l&&c&&(a.emit("relevant"),a.emit("update"),a.relevant=!0)},this.mixin=i.cursor(this);var h=!1,u=function(){h||(h=!0,a.tree.on("update",a.updateHandler))};this.on=s.before(u,this.on.bind(this)),this.once=s.before(u,this.once.bind(this))}var n=t("emmett"),o=t("./combination.js"),i=t("./mixins.js"),s=t("./helpers.js"),a=t("./type.js");s.inherits(e,n),e.prototype.isRoot=function(){return!this.path.length},e.prototype.isLeaf=function(){return a.Primitive(this.get())},e.prototype.isBranch=function(){return!this.isLeaf()&&!this.isRoot()},e.prototype.root=function(){return this.tree.root()},e.prototype.select=function(t){if(arguments.length>1&&(t=s.arrayOf(arguments)),!a.Path(t))throw Error("baobab.Cursor.select: invalid path.");return this.tree.select(this.path.concat(t))},e.prototype.up=function(){return this.solvedPath&&this.solvedPath.length?this.tree.select(this.path.slice(0,-1)):null},e.prototype.left=function(){var t=+this.solvedPath[this.solvedPath.length-1];if(isNaN(t))throw Error("baobab.Cursor.left: cannot go left on a non-list type.");return t?this.tree.select(this.solvedPath.slice(0,-1).concat(t-1)):null},e.prototype.leftmost=function(){var t=+this.solvedPath[this.solvedPath.length-1];if(isNaN(t))throw Error("baobab.Cursor.leftmost: cannot go left on a non-list type.");return this.tree.select(this.solvedPath.slice(0,-1).concat(0))},e.prototype.right=function(){var t=+this.solvedPath[this.solvedPath.length-1];if(isNaN(t))throw Error("baobab.Cursor.right: cannot go right on a non-list type.");return t+1===this.up().get().length?null:this.tree.select(this.solvedPath.slice(0,-1).concat(t+1))},e.prototype.rightmost=function(){var t=+this.solvedPath[this.solvedPath.length-1];if(isNaN(t))throw Error("baobab.Cursor.right: cannot go right on a non-list type.");var r=this.up().get();return this.tree.select(this.solvedPath.slice(0,-1).concat(r.length-1))},e.prototype.down=function(){+this.solvedPath[this.solvedPath.length-1];return this.get()instanceof Array?this.tree.select(this.solvedPath.concat(0)):null},e.prototype.get=function(t){arguments.length>1&&(t=s.arrayOf(arguments));var r=this.solvedPath.concat((a.String(t)||a.Number(t)?[t]:t)||[]);return s.getIn(this.tree.data,r)},e.prototype.set=function(t,r){arguments.length<2&&(r=t,t=[]);var e=[].concat(t),n=s.solvePath(this.get(),e);if(!n)throw Error("baobab.Cursor.set: could not solve dynamic path.");var o=s.pathObject(n,{$set:r});return this.update(o)},e.prototype.edit=function(t){return this.update({$set:t})},e.prototype.unset=function(t){if(!t&&0!==t)throw Error("baobab.Cursor.unset: expects a valid key to unset.");if("object"!=typeof this.get())throw Error("baobab.Cursor.set: trying to set key to a non-object.");var r={};return r[t]={$unset:!0},this.update(r)},e.prototype.remove=function(){if(this.isRoot())throw Error("baobab.Cursor.remove: cannot remove root node.");return this.update({$unset:!0})},e.prototype.apply=function(t){if("function"!=typeof t)throw Error("baobab.Cursor.apply: argument is not a function.");return this.update({$apply:t})},e.prototype.chain=function(t){if("function"!=typeof t)throw Error("baobab.Cursor.chain: argument is not a function.");return this.update({$chain:t})},e.prototype.push=function(t){if(!(this.get()instanceof Array))throw Error("baobab.Cursor.push: trying to push to non-array value.");return this.update(arguments.length>1?{$push:s.arrayOf(arguments)}:{$push:t})},e.prototype.unshift=function(t){if(!(this.get()instanceof Array))throw Error("baobab.Cursor.push: trying to push to non-array value.");return this.update(arguments.length>1?{$unshift:s.arrayOf(arguments)}:{$unshift:t})},e.prototype.merge=function(t){if(!a.Object(t))throw Error("baobab.Cursor.merge: trying to merge a non-object.");if(!a.Object(this.get()))throw Error("baobab.Cursor.merge: trying to merge into a non-object.");this.update({$merge:t})},e.prototype.update=function(t){return this.tree.stack(s.pathObject(this.solvedPath,t)),this},e.prototype.or=function(t){return new o("or",this,t)},e.prototype.and=function(t){return new o("and",this,t)},e.prototype.release=function(){this.tree.off("update",this.updateHandler),this.hash&&delete this.tree._cursors[this.hash],delete this.tree,delete this.path,delete this.solvedPath,this.kill()},e.prototype.toJSON=function(){return this.get()},a.Cursor=function(t){return t instanceof e},r.exports=e},{"./combination.js":5,"./helpers.js":7,"./mixins.js":9,"./type.js":10,emmett:3}],7:[function(t,r){function e(t){return Array.prototype.slice.call(t)}function n(t,r){return function(){t(),r.apply(null,arguments)}}function o(t,r){var e,n={};for(e in t)n[e]=t[e];for(e in r)n[e]=r[e];return n}function i(t){var r=t.source,e="";return t.global&&(e+="g"),t.multiline&&(e+="m"),t.ignoreCase&&(e+="i"),t.sticky&&(e+="y"),t.unicode&&(e+="u"),new RegExp(r,e)}function s(t,r){if(!r||"object"!=typeof r||r instanceof Error||r instanceof ArrayBuffer)return r;if(g.Array(r)){if(t){var e,n,o=[];for(e=0,n=r.length;n>e;e++)o.push(_(r[e]));return o}return r.slice(0)}if(g.Date(r))return new Date(r.getTime());if(r instanceof RegExp)return i(r);if(g.Object(r)){var s,a={};r.constructor&&r.constructor!==Object&&(a=Object.create(r.constructor.prototype));for(s in r)r.hasOwnProperty(s)&&(a[s]=t?_(r[s]):r[s]);return a}return r}function a(t,r){return function(e){return r(t(e))}}function h(t,r){var e,n;for(e=0,n=t.length;n>e;e++)if(r(t[e]))return t[e]}function u(t,r){var e,n;for(e=0,n=t.length;n>e;e++)if(r(t[e]))return e;return-1}function c(t,r){var e,n=!0;if(!t)return!1;for(e in r)if(g.Object(r[e]))n=n&&c(t[e],r[e]);else if(g.Array(r[e]))n=n&&!!~r[e].indexOf(t[e]);else if(t[e]!==r[e])return!1;return n}function l(t,r){return h(t,function(t){return c(t,r)})}function f(t,r){return u(t,function(t){return c(t,r)})}function p(t,r){r=r||[];var e,n,o=t;for(e=0,n=r.length;n>e;e++){if(!o)return;if("function"==typeof r[e]){if(!g.Array(o))return;o=h(o,r[e])}else if("object"==typeof r[e]){if(!g.Array(o))return;o=l(o,r[e])}else o=o[r[e]]}return o}function d(t,r){var e,n,o,i=[],s=t;for(n=0,o=r.length;o>n;n++){if(!s)return null;if("function"==typeof r[n]){if(!g.Array(s))return;e=u(s,r[n]),i.push(e),s=s[e]}else if("object"==typeof r[n]){if(!g.Array(s))return;e=f(s,r[n]),i.push(e),s=s[e]}else i.push(r[n]),s=s[r[n]]||{}}return i}function b(t,r){var e,n=t.length,o={},i=o;for(n||(o=r),e=0;n>e;e++)i[t[e]]=e+1===n?r:{},i=i[t[e]];return o}function y(t,r){t.super_=r;var e=function(){};e.prototype=r.prototype,t.prototype=new e,t.prototype.constructor=t}var g=t("./type.js"),m=s.bind(null,!1),_=s.bind(null,!0);r.exports={arrayOf:e,before:n,deepClone:_,shallowClone:m,shallowMerge:o,compose:a,getIn:p,inherits:y,pathObject:b,solvePath:d}},{"./type.js":10}],8:[function(t,r){function e(t,r,e){s.forEach(function(r){e!==r&&delete t[r]}),t[e]=r[e]}function n(t,r){var a,h=o.shallowClone(r||{});s.forEach(function(r){t[r]&&e(h,t,r)}),t.$chain&&(s.slice(0,-1).forEach(function(t){delete h[t]}),h.$apply=h.$apply?o.compose(h.$apply,t.$chain):t.$chain),t.$push&&h.$push?h.$push=i.Array(h.$push)?h.$push.concat(t.$push):[h.$push].concat(t.$push):t.$push&&(h.$push=t.$push),t.$unshift&&h.$unshift?h.$unshift=i.Array(t.$unshift)?t.$unshift.concat(h.$unshift):[t.$unshift].concat(h.$unshift):t.$unshift&&(h.$unshift=t.$unshift);for(a in t)i.Object(t[a])?h[a]=n(t[a],h[a]):"$"!==a[0]&&(h[a]=t[a]);return h}var o=t("./helpers.js"),i=t("./type.js"),s=["$unset","$set","$merge","$apply"];r.exports=n},{"./helpers.js":7,"./type.js":10}],9:[function(t,r){var e=t("./combination.js"),n=t("./type.js");r.exports={baobab:function(t){return{mixins:[{getInitialState:function(){if(this.tree=t,!this.cursor&&!this.cursors)return{};if(this.cursor&&this.cursors)throw Error("baobab.mixin: you cannot have both `component.cursor` and `component.cursors`. Please make up your mind.");if(this.__type=null,this.__updateHandler=function(){this.setState(this.__getCursorData())}.bind(this),this.cursor){if(!n.MixinCursor(this.cursor))throw Error("baobab.mixin.cursor: invalid data (cursor, string, array or function).");n.Function(this.cursor)&&(this.cursor=this.cursor()),n.Cursor(this.cursor)||(this.cursor=t.select(this.cursor)),this.__getCursorData=function(){return{cursor:this.cursor.get()}}.bind(this),this.__type="single"}else if(this.cursors){if(!n.MixinCursors(this.cursors))throw Error("baobab.mixin.cursor: invalid data (object, array or function).");if(n.Function(this.cursors)&&(this.cursors=this.cursors()),n.Array(this.cursors))this.cursors=this.cursors.map(function(r){return n.Cursor(r)?r:t.select(r)}),this.__getCursorData=function(){return{cursors:this.cursors.map(function(t){return t.get()})}}.bind(this),this.__type="array";else{for(var r in this.cursors)n.Cursor(this.cursors[r])||(this.cursors[r]=t.select(this.cursors[r]));this.__getCursorData=function(){var t={};for(r in this.cursors)t[r]=this.cursors[r].get();return{cursors:t}}.bind(this),this.__type="object"}}return this.__getCursorData()},componentDidMount:function(){"single"===this.__type?(this.__combination=new e("or",[this.cursor]),this.__combination.on("update",this.__updateHandler)):"array"===this.__type?(this.__combination=new e("or",this.cursors),this.__combination.on("update",this.__updateHandler)):"object"===this.__type&&(this.__combination=new e("or",Object.keys(this.cursors).map(function(t){return this.cursors[t]},this)),this.__combination.on("update",this.__updateHandler))},componentWillUnmount:function(){this.__combination&&this.__combination.release()}}].concat(t.options.mixins)}},cursor:function(t){return{mixins:[{getInitialState:function(){return this.cursor=t,this.__updateHandler=function(){this.setState({cursor:this.cursor.get()})}.bind(this),{cursor:this.cursor.get()}},componentDidMount:function(){this.cursor.on("update",this.__updateHandler)},componentWillUnmount:function(){this.cursor.off("update",this.__updateHandler)}}].concat(t.tree.options.mixins)}}}},{"./combination.js":5,"./type.js":10}],10:[function(t,r){function e(t,r){return r.some(function(r){return n[r](t)})}var n={};n.Array=function(t){return Array.isArray(t)},n.Object=function(t){return!Array.isArray(t)&&"object"==typeof t&&null!==t},n.String=function(t){return"string"==typeof t},n.Number=function(t){return"number"==typeof t},n.Function=function(t){return"function"==typeof t},n.Primitive=function(t){return"string"==typeof t||"number"==typeof t||"boolean"==typeof t},n.Date=function(t){return t instanceof Date},n.Path=function(t){var r=["String","Number","Function","Object"];return n.Array(t)?t.every(function(t){return e(t,r)}):e(t,r)},n.MixinCursor=function(t){return e(t,["String","Number","Array","Function","Cursor"])},n.MixinCursors=function(t){return e(t,["Object","Array","Function"])},n.ComplexPath=function(t){return e(t,["Object","Function"])},r.exports=n},{}],11:[function(t,r){function e(t,r){var e=new Error("baobab.update: "+r+" at path /"+t.slice(1).toString());return e.path=t,e}var n=t("./helpers.js"),o=t("./type.js");r.exports=function(t,r,i){if(i=i||{},!o.Object(t)&&!o.Array(t))throw Error("baobab.update: invalid target.");var s={};t={root:n.shallowClone(t)};var a=function(t,r,i,h){i=i||["root"];var u,c,l,f=i.join("λ"),p=i[i.length-1],d=Object.keys(r).some(function(t){return!!~["$unset","$set","$apply","$merge","$push","$unshift"].indexOf(t)});if(d){s[f]=!0;for(c in r){if("$unset"===c){var b=i[i.length-2];o.Array(t)?h[b]=t.slice(0,+p).concat(t.slice(+p+1)):(h[b]=n.shallowClone(t),delete h[b][p]);break}if("$set"===c){l=r.$set,t[p]=l;break}if("$apply"===c){if(u=r.$apply,"function"!=typeof u)throw e(i,"using command $apply with a non function");t[p]=u.call(null,t[p]);break}if("$merge"===c){if(l=r.$merge,!o.Object(t[p])||!o.Object(l))throw e(i,"using command $merge with a non object");t[p]=n.shallowMerge(t[p],l);break}if("$push"===c){if(l=r.$push,!o.Array(t[p]))throw e(i,"using command $push to a non array");t[p]=t[p].concat(l)}if("$unshift"===c){if(l=r.$unshift,!o.Array(t[p]))throw e(i,"using command $unshift to a non array");t[p]=[].concat(l).concat(t[p])}}}else for(c in r)t[p][c]="undefined"==typeof t[p][c]?{}:n.shallowClone(t[p][c]),a(t[p],r[c],i.concat(c),t)};return a(t,r),{data:t.root,log:Object.keys(s).map(function(t){return t.split("λ").slice(1)})}}},{"./helpers.js":7,"./type.js":10}]},{},[2])(2)}); \ No newline at end of file +!function(t){if("object"==typeof exports&&"undefined"!=typeof module)module.exports=t();else if("function"==typeof define&&define.amd)define([],t);else{var r;r="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:this,r.Baobab=t()}}(function(){var t;return function r(t,e,n){function o(s,a){if(!e[s]){if(!t[s]){var h="function"==typeof require&&require;if(!a&&h)return h(s,!0);if(i)return i(s,!0);var u=new Error("Cannot find module '"+s+"'");throw u.code="MODULE_NOT_FOUND",u}var c=e[s]={exports:{}};t[s][0].call(c.exports,function(r){var e=t[s][1][r];return o(e?e:r)},c,c.exports,r,t,e,n)}return e[s].exports}for(var i="function"==typeof require&&require,s=0;sr;r++)n.push(t[r].handler);return n}var o={once:"boolean",scope:"object"},i=function(){this._enabled=!0,this._children=[],this._handlers={},this._handlersAll=[]};i.prototype.on=function(t,r,e){var n,s,a,h,u,c;if("function"==typeof r){for(u="string"==typeof t?[t]:t,n=0,s=u.length;n!==s;n+=1)if(h=u[n]){this._handlers[h]||(this._handlers[h]=[]),c={handler:r};for(a in e||{}){if(!o[a])throw new Error('The option "'+a+'" is not recognized by Emmett.');c[a]=e[a]}this._handlers[h].push(c)}}else if(t&&"object"==typeof t&&!Array.isArray(t))for(h in t)i.prototype.on.call(this,h,t[h],r);else{if("function"!=typeof t)throw new Error("Wrong arguments.");c={handler:t};for(a in e||{}){if(!o[a])throw new Error('The option "'+a+'" is not recognized by Emmett.');c[a]=e[a]}this._handlersAll.push(c)}return this},i.prototype.once=function(t,r,e){if("function"==typeof r)e=e||{},e.once=!0,this.on(t,r,e);else{if((!t||"object"!=typeof t||Array.isArray(t))&&"function"!=typeof t)throw new Error("Wrong arguments.");r=r||{},r.once=!0,this.on(t,r)}return this},i.prototype.off=function(t,r){var e,n,o,i,s,a,h,u="string"==typeof t?[t]:t;if(1===arguments.length&&"function"==typeof u){r=arguments[0];for(s in this._handlers){for(a=[],e=0,n=this._handlers[s].length;e!==n;e+=1)this._handlers[s][e].handler!==r&&a.push(this._handlers[s][e]);this._handlers[s]=a}for(a=[],e=0,n=this._handlersAll.length;e!==n;e+=1)this._handlersAll[e].handler!==r&&a.push(this._handlersAll[e]);this._handlersAll=a}else if(2===arguments.length)for(e=0,n=u.length;e!==n;e+=1){if(h=u[e],this._handlers[h]){for(a=[],o=0,i=this._handlers[h].length;o!==i;o+=1)this._handlers[h][o].handler!==r&&a.push(this._handlers[h][o]);this._handlers[h]=a}this._handlers[h]&&0===this._handlers[h].length&&delete this._handlers[h]}return this},i.prototype.unbindAll=function(){var t;this._handlersAll=[];for(t in this._handlers)delete this._handlers[t];return this},i.prototype.emit=function(t,r){var e,n,o,i,s,a,h,u,c,l,f="string"==typeof t?[t]:t;if(!this._enabled)return this;for(r=void 0===r?{}:r,e=0,n=f.length;e!==n;e+=1)if(l=f[e],c=(this._handlers[l]||[]).concat(this._handlersAll),c.length){for(h={type:l,data:r||{},target:this},a=[],o=0,i=c.length;o!==i;o+=1)(this._handlers[l]&&this._handlers[l].indexOf(c[o])>=0||this._handlersAll.indexOf(c[o])>=0)&&(c[o].handler.call("scope"in c[o]?c[o].scope:this,h),c[o].once&&a.push(c[o]));for(s=0;se;e++)if(t._children[e]===r){t._children.splice(e,1);break}}),this._children.push(r),r},i.prototype.listeners=function(t){var e,n,o,i=[];if(t)for(i=r(this._handlers[t]),n=0,o=this._children.length;o>n;n++)i=i.concat(this._children[n].listeners(t));else{i=r(this._handlersAll);for(e in this._handlers)i=i.concat(r(this._handlers[e]));for(n=0,o=this._children.length;o>n;n++)i=i.concat(this._children[n].listeners())}return i},i.prototype.kill=function(){if(this.emit("emmett:kill"),this.unbindAll(),this._handlers=null,this._handlersAll=null,this._enabled=!1,this._children)for(var t=0,r=this._children.length;r>t;t++)this._children[t].kill();this._children=null},i.prototype.disable=function(){return this._enabled=!1,this},i.prototype.enable=function(){return this._enabled=!0,this},i.version="2.1.2","undefined"!=typeof n?("undefined"!=typeof e&&e.exports&&(n=e.exports=i),n.Emitter=i):"function"==typeof t&&t.amd?t("emmett",[],function(){return i}):this.Emitter=i}).call(this)},{}],4:[function(t,r){function e(t){return t+"$"+(new Date).getTime()+(""+Math.random()).replace("0.","")}function n(t,r){function e(t){this[t]=function(){var r=this.root[t].apply(this.root,arguments);return r instanceof o?this:r}}if(arguments.length<1&&(t={}),!(this instanceof n))return new n(t,r);if(!l.Object(t)&&!l.Array(t))throw Error("Baobab: invalid data.");i.call(this),this.options=s.shallowMerge(c,r),this._transaction={},this._future=void 0,this._cursors={},this.data=s.deepClone(t),this.root=this.select([]),["get","set","unset","update"].forEach(e.bind(this)),this.mixin=u.baobab(this)}var o=t("./cursor.js"),i=t("emmett"),s=t("./helpers.js"),a=t("./update.js"),h=t("./merge.js"),u=t("./mixins.js"),c=t("../defaults.js"),l=t("./type.js");s.inherits(n,i),n.prototype.select=function(t){if(!t)throw Error("Baobab.select: invalid path.");if(arguments.length>1&&(t=s.arrayOf(arguments)),!l.Path(t))throw Error("Baobab.select: invalid path.");t=[].concat(t);var r,n=l.ComplexPath(t);n&&(r=s.solvePath(this.data,t));var i=t.map(function(t){return l.Function(t)?e("fn"):l.Object(t)?e("ob"):t}).join("λ");if(this._cursors[i])return this._cursors[i];var a=new o(this,t,r,i);return this._cursors[i]=a,a},n.prototype.stack=function(t){var r=this;if(!l.Object(t))throw Error("Baobab.update: wrong specification.");return this._transaction=h(t,this._transaction),this.options.autoCommit?this.options.asynchronous?(this._future||(this._future=setTimeout(r.commit.bind(r,null),0)),this):this.commit():this},n.prototype.commit=function(){var t=a(this.data,this._transaction,this.options);return this.data=t.data,this._transaction={},this._future&&(this._future=clearTimeout(this._future)),this.emit("update",{log:t.log}),this},n.prototype.release=function(){delete this.data,delete this._transaction;for(var t in this._cursors)this._cursors[t].release();delete this._cursors,this.kill()},n.prototype.toJSON=function(){return this.get()},r.exports=n},{"../defaults.js":1,"./cursor.js":6,"./helpers.js":7,"./merge.js":8,"./mixins.js":9,"./type.js":10,"./update.js":11,emmett:3}],5:[function(t,r){function e(t,r){r.on("update",t.cursorListener),t.tree.off("update",t.treeListener),t.tree.on("update",t.treeListener)}function n(t){var r=this;if(arguments.length<2)throw Error("baobab.Combination: not enough arguments.");var n=arguments[1],o=s.arrayOf(arguments).slice(2);if(n instanceof Array&&(o=n.slice(1),n=n[0]),!a.Cursor(n))throw Error("baobab.Combination: argument should be a cursor.");if("or"!==t&&"and"!==t)throw Error("baobab.Combination: invalid operator.");i.call(this),this.cursors=[n],this.operators=[],this.tree=n.tree,this.updates=new Array(this.cursors.length),this.cursorListener=function(){r.updates[r.cursors.indexOf(this)]=!0},this.treeListener=function(){var t,e,n=r.updates[0];for(t=1,e=r.cursors.length;e>t;t++)n="or"===r.operators[t-1]?n||r.updates[t]:n&&r.updates[t];n&&r.emit("update"),r.updates=new Array(r.cursors.length)},this.bound=!1;var h=(this.on,this.once,function(){r.bound||(r.bound=!0,r.cursors.forEach(function(t){e(r,t)}))});this.on=s.before(h,this.on.bind(this)),this.once=s.before(h,this.once.bind(this)),o.forEach(function(r){this[t](r)},this)}function o(t){n.prototype[t]=function(r){if(!a.Cursor(r))throw this.release(),Error("baobab.Combination."+t+": argument should be a cursor.");if(~this.cursors.indexOf(r))throw this.release(),Error("baobab.Combination."+t+": cursor already in combination.");return this.cursors.push(r),this.operators.push(t),this.updates.length++,this.bound&&e(this,r),this}}var i=t("emmett"),s=t("./helpers.js"),a=t("./type.js");s.inherits(n,i),o("or"),o("and"),n.prototype.release=function(){this.cursors.forEach(function(t){t.off("update",this.cursorListener)},this),this.tree.off("update",this.treeListener),this.cursors=null,this.operators=null,this.tree=null,this.updates=null,this.kill()},r.exports=n},{"./helpers.js":7,"./type.js":10,emmett:3}],6:[function(t,r){function e(t,r,e,o){var a=this;n.call(this),r=r||[],this.tree=t,this.path=r,this.hash=o,this.complexPath=!!e,this.solvedPath=this.complexPath?e:this.path,this.relevant=void 0!==this.get(),this.updateHandler=function(t){var r,e,n,o,i,h,u=t.data.log,c=!1;if(a.complexPath&&(a.solvedPath=s.solvePath(a.tree.data,a.path)),!a.path.length)return a.emit("update");t:for(i=0,n=u.length;n>i;i++)for(r=u[i],h=0,o=r.length;o>h&&(e=r[h],e===""+a.solvedPath[h]);h++)if(h+1===o||h+1===a.solvedPath.length){c=!0;break t}var l=void 0!==a.get();a.relevant?l&&c?a.emit("update"):l||(a.emit("irrelevant"),a.relevant=!1):l&&c&&(a.emit("relevant"),a.emit("update"),a.relevant=!0)},this.mixin=i.cursor(this);var h=!1,u=function(){h||(h=!0,a.tree.on("update",a.updateHandler))};this.on=s.before(u,this.on.bind(this)),this.once=s.before(u,this.once.bind(this))}var n=t("emmett"),o=t("./combination.js"),i=t("./mixins.js"),s=t("./helpers.js"),a=t("./type.js");s.inherits(e,n),e.prototype.isRoot=function(){return!this.path.length},e.prototype.isLeaf=function(){return a.Primitive(this.get())},e.prototype.isBranch=function(){return!this.isLeaf()&&!this.isRoot()},e.prototype.root=function(){return this.tree.root()},e.prototype.select=function(t){if(arguments.length>1&&(t=s.arrayOf(arguments)),!a.Path(t))throw Error("baobab.Cursor.select: invalid path.");return this.tree.select(this.path.concat(t))},e.prototype.up=function(){return this.solvedPath&&this.solvedPath.length?this.tree.select(this.path.slice(0,-1)):null},e.prototype.left=function(){var t=+this.solvedPath[this.solvedPath.length-1];if(isNaN(t))throw Error("baobab.Cursor.left: cannot go left on a non-list type.");return t?this.tree.select(this.solvedPath.slice(0,-1).concat(t-1)):null},e.prototype.leftmost=function(){var t=+this.solvedPath[this.solvedPath.length-1];if(isNaN(t))throw Error("baobab.Cursor.leftmost: cannot go left on a non-list type.");return this.tree.select(this.solvedPath.slice(0,-1).concat(0))},e.prototype.right=function(){var t=+this.solvedPath[this.solvedPath.length-1];if(isNaN(t))throw Error("baobab.Cursor.right: cannot go right on a non-list type.");return t+1===this.up().get().length?null:this.tree.select(this.solvedPath.slice(0,-1).concat(t+1))},e.prototype.rightmost=function(){var t=+this.solvedPath[this.solvedPath.length-1];if(isNaN(t))throw Error("baobab.Cursor.right: cannot go right on a non-list type.");var r=this.up().get();return this.tree.select(this.solvedPath.slice(0,-1).concat(r.length-1))},e.prototype.down=function(){+this.solvedPath[this.solvedPath.length-1];return this.get()instanceof Array?this.tree.select(this.solvedPath.concat(0)):null},e.prototype.get=function(t){arguments.length>1&&(t=s.arrayOf(arguments));var r=this.solvedPath.concat((a.String(t)||a.Number(t)?[t]:t)||[]);return s.getIn(this.tree.data,r)},e.prototype.set=function(t,r){arguments.length<2&&(r=t,t=[]);var e=[].concat(t),n=s.solvePath(this.get(),e);if(!n)throw Error("baobab.Cursor.set: could not solve dynamic path.");var o=s.pathObject(n,{$set:r});return this.update(o)},e.prototype.unset=function(t){if(!t&&0!==t)throw Error("baobab.Cursor.unset: expects a valid key to unset.");if("object"!=typeof this.get())throw Error("baobab.Cursor.set: trying to set key to a non-object.");var r={};return r[t]={$unset:!0},this.update(r)},e.prototype.remove=function(){if(this.isRoot())throw Error("baobab.Cursor.remove: cannot remove root node.");return this.update({$unset:!0})},e.prototype.apply=function(t){if("function"!=typeof t)throw Error("baobab.Cursor.apply: argument is not a function.");return this.update({$apply:t})},e.prototype.chain=function(t){if("function"!=typeof t)throw Error("baobab.Cursor.chain: argument is not a function.");return this.update({$chain:t})},e.prototype.push=function(t){if(!(this.get()instanceof Array))throw Error("baobab.Cursor.push: trying to push to non-array value.");return this.update(arguments.length>1?{$push:s.arrayOf(arguments)}:{$push:t})},e.prototype.unshift=function(t){if(!(this.get()instanceof Array))throw Error("baobab.Cursor.push: trying to push to non-array value.");return this.update(arguments.length>1?{$unshift:s.arrayOf(arguments)}:{$unshift:t})},e.prototype.merge=function(t){if(!a.Object(t))throw Error("baobab.Cursor.merge: trying to merge a non-object.");if(!a.Object(this.get()))throw Error("baobab.Cursor.merge: trying to merge into a non-object.");this.update({$merge:t})},e.prototype.update=function(t){return this.tree.stack(s.pathObject(this.solvedPath,t)),this},e.prototype.or=function(t){return new o("or",this,t)},e.prototype.and=function(t){return new o("and",this,t)},e.prototype.release=function(){this.tree.off("update",this.updateHandler),this.hash&&delete this.tree._cursors[this.hash],delete this.tree,delete this.path,delete this.solvedPath,this.kill()},e.prototype.toJSON=function(){return this.get()},a.Cursor=function(t){return t instanceof e},r.exports=e},{"./combination.js":5,"./helpers.js":7,"./mixins.js":9,"./type.js":10,emmett:3}],7:[function(t,r){function e(t){return Array.prototype.slice.call(t)}function n(t,r){return function(){t(),r.apply(null,arguments)}}function o(t,r){var e,n={};for(e in t)n[e]=t[e];for(e in r)n[e]=r[e];return n}function i(t){var r=t.source,e="";return t.global&&(e+="g"),t.multiline&&(e+="m"),t.ignoreCase&&(e+="i"),t.sticky&&(e+="y"),t.unicode&&(e+="u"),new RegExp(r,e)}function s(t,r){if(!r||"object"!=typeof r||r instanceof Error||r instanceof ArrayBuffer)return r;if(g.Array(r)){if(t){var e,n,o=[];for(e=0,n=r.length;n>e;e++)o.push(_(r[e]));return o}return r.slice(0)}if(g.Date(r))return new Date(r.getTime());if(r instanceof RegExp)return i(r);if(g.Object(r)){var s,a={};r.constructor&&r.constructor!==Object&&(a=Object.create(r.constructor.prototype));for(s in r)r.hasOwnProperty(s)&&(a[s]=t?_(r[s]):r[s]);return a}return r}function a(t,r){return function(e){return r(t(e))}}function h(t,r){var e,n;for(e=0,n=t.length;n>e;e++)if(r(t[e]))return t[e]}function u(t,r){var e,n;for(e=0,n=t.length;n>e;e++)if(r(t[e]))return e;return-1}function c(t,r){var e,n=!0;if(!t)return!1;for(e in r)if(g.Object(r[e]))n=n&&c(t[e],r[e]);else if(g.Array(r[e]))n=n&&!!~r[e].indexOf(t[e]);else if(t[e]!==r[e])return!1;return n}function l(t,r){return h(t,function(t){return c(t,r)})}function f(t,r){return u(t,function(t){return c(t,r)})}function p(t,r){r=r||[];var e,n,o=t;for(e=0,n=r.length;n>e;e++){if(!o)return;if("function"==typeof r[e]){if(!g.Array(o))return;o=h(o,r[e])}else if("object"==typeof r[e]){if(!g.Array(o))return;o=l(o,r[e])}else o=o[r[e]]}return o}function d(t,r){var e,n,o,i=[],s=t;for(n=0,o=r.length;o>n;n++){if(!s)return null;if("function"==typeof r[n]){if(!g.Array(s))return;e=u(s,r[n]),i.push(e),s=s[e]}else if("object"==typeof r[n]){if(!g.Array(s))return;e=f(s,r[n]),i.push(e),s=s[e]}else i.push(r[n]),s=s[r[n]]||{}}return i}function b(t,r){var e,n=t.length,o={},i=o;for(n||(o=r),e=0;n>e;e++)i[t[e]]=e+1===n?r:{},i=i[t[e]];return o}function y(t,r){t.super_=r;var e=function(){};e.prototype=r.prototype,t.prototype=new e,t.prototype.constructor=t}var g=t("./type.js"),m=s.bind(null,!1),_=s.bind(null,!0);r.exports={arrayOf:e,before:n,deepClone:_,shallowClone:m,shallowMerge:o,compose:a,getIn:p,inherits:y,pathObject:b,solvePath:d}},{"./type.js":10}],8:[function(t,r){function e(t,r,e){s.forEach(function(r){e!==r&&delete t[r]}),t[e]=r[e]}function n(t,r){var a,h=o.shallowClone(r||{});s.forEach(function(r){t[r]&&e(h,t,r)}),t.$chain&&(s.slice(0,-1).forEach(function(t){delete h[t]}),h.$apply=h.$apply?o.compose(h.$apply,t.$chain):t.$chain),t.$push&&h.$push?h.$push=i.Array(h.$push)?h.$push.concat(t.$push):[h.$push].concat(t.$push):t.$push&&(h.$push=t.$push),t.$unshift&&h.$unshift?h.$unshift=i.Array(t.$unshift)?t.$unshift.concat(h.$unshift):[t.$unshift].concat(h.$unshift):t.$unshift&&(h.$unshift=t.$unshift);for(a in t)i.Object(t[a])?h[a]=n(t[a],h[a]):"$"!==a[0]&&(h[a]=t[a]);return h}var o=t("./helpers.js"),i=t("./type.js"),s=["$unset","$set","$merge","$apply"];r.exports=n},{"./helpers.js":7,"./type.js":10}],9:[function(t,r){var e=t("./combination.js"),n=t("./type.js");r.exports={baobab:function(t){return{mixins:[{getInitialState:function(){if(this.tree=t,!this.cursor&&!this.cursors)return{};if(this.cursor&&this.cursors)throw Error("baobab.mixin: you cannot have both `component.cursor` and `component.cursors`. Please make up your mind.");if(this.__type=null,this.__updateHandler=function(){this.setState(this.__getCursorData())}.bind(this),this.cursor){if(!n.MixinCursor(this.cursor))throw Error("baobab.mixin.cursor: invalid data (cursor, string, array or function).");n.Function(this.cursor)&&(this.cursor=this.cursor()),n.Cursor(this.cursor)||(this.cursor=t.select(this.cursor)),this.__getCursorData=function(){return{cursor:this.cursor.get()}}.bind(this),this.__type="single"}else if(this.cursors){if(!n.MixinCursors(this.cursors))throw Error("baobab.mixin.cursor: invalid data (object, array or function).");if(n.Function(this.cursors)&&(this.cursors=this.cursors()),n.Array(this.cursors))this.cursors=this.cursors.map(function(r){return n.Cursor(r)?r:t.select(r)}),this.__getCursorData=function(){return{cursors:this.cursors.map(function(t){return t.get()})}}.bind(this),this.__type="array";else{for(var r in this.cursors)n.Cursor(this.cursors[r])||(this.cursors[r]=t.select(this.cursors[r]));this.__getCursorData=function(){var t={};for(r in this.cursors)t[r]=this.cursors[r].get();return{cursors:t}}.bind(this),this.__type="object"}}return this.__getCursorData()},componentDidMount:function(){"single"===this.__type?(this.__combination=new e("or",[this.cursor]),this.__combination.on("update",this.__updateHandler)):"array"===this.__type?(this.__combination=new e("or",this.cursors),this.__combination.on("update",this.__updateHandler)):"object"===this.__type&&(this.__combination=new e("or",Object.keys(this.cursors).map(function(t){return this.cursors[t]},this)),this.__combination.on("update",this.__updateHandler))},componentWillUnmount:function(){this.__combination&&this.__combination.release()}}].concat(t.options.mixins)}},cursor:function(t){return{mixins:[{getInitialState:function(){return this.cursor=t,this.__updateHandler=function(){this.setState({cursor:this.cursor.get()})}.bind(this),{cursor:this.cursor.get()}},componentDidMount:function(){this.cursor.on("update",this.__updateHandler)},componentWillUnmount:function(){this.cursor.off("update",this.__updateHandler)}}].concat(t.tree.options.mixins)}}}},{"./combination.js":5,"./type.js":10}],10:[function(t,r){function e(t,r){return r.some(function(r){return n[r](t)})}var n={};n.Array=function(t){return Array.isArray(t)},n.Object=function(t){return!Array.isArray(t)&&"object"==typeof t&&null!==t},n.String=function(t){return"string"==typeof t},n.Number=function(t){return"number"==typeof t},n.Function=function(t){return"function"==typeof t},n.Primitive=function(t){return"string"==typeof t||"number"==typeof t||"boolean"==typeof t},n.Date=function(t){return t instanceof Date},n.Path=function(t){var r=["String","Number","Function","Object"];return n.Array(t)?t.every(function(t){return e(t,r)}):e(t,r)},n.MixinCursor=function(t){return e(t,["String","Number","Array","Function","Cursor"])},n.MixinCursors=function(t){return e(t,["Object","Array","Function"])},n.ComplexPath=function(t){return e(t,["Object","Function"])},r.exports=n},{}],11:[function(t,r){function e(t,r){var e=new Error("baobab.update: "+r+" at path /"+t.slice(1).toString());return e.path=t,e}var n=t("./helpers.js"),o=t("./type.js");r.exports=function(t,r,i){if(i=i||{},!o.Object(t)&&!o.Array(t))throw Error("baobab.update: invalid target.");var s={};t={root:n.shallowClone(t)};var a=function(t,r,i,h){i=i||["root"];var u,c,l,f=i.join("λ"),p=i[i.length-1],d=Object.keys(r).some(function(t){return!!~["$unset","$set","$apply","$merge","$push","$unshift"].indexOf(t)});if(d){s[f]=!0;for(c in r){if("$unset"===c){var b=i[i.length-2];o.Array(t)?h[b]=t.slice(0,+p).concat(t.slice(+p+1)):(h[b]=n.shallowClone(t),delete h[b][p]);break}if("$set"===c){l=r.$set,t[p]=l;break}if("$apply"===c){if(u=r.$apply,"function"!=typeof u)throw e(i,"using command $apply with a non function");t[p]=u.call(null,t[p]);break}if("$merge"===c){if(l=r.$merge,!o.Object(t[p])||!o.Object(l))throw e(i,"using command $merge with a non object");t[p]=n.shallowMerge(t[p],l);break}if("$push"===c){if(l=r.$push,!o.Array(t[p]))throw e(i,"using command $push to a non array");t[p]=t[p].concat(l)}if("$unshift"===c){if(l=r.$unshift,!o.Array(t[p]))throw e(i,"using command $unshift to a non array");t[p]=[].concat(l).concat(t[p])}}}else for(c in r)t[p][c]="undefined"==typeof t[p][c]?{}:n.shallowClone(t[p][c]),a(t[p],r[c],i.concat(c),t)};return a(t,r),{data:t.root,log:Object.keys(s).map(function(t){return t.split("λ").slice(1)})}}},{"./helpers.js":7,"./type.js":10}]},{},[2])(2)}); \ No newline at end of file diff --git a/src/cursor.js b/src/cursor.js index 9d5b59c..e3ec8aa 100644 --- a/src/cursor.js +++ b/src/cursor.js @@ -233,10 +233,6 @@ Cursor.prototype.set = function(key, val) { return this.update(spec); }; -Cursor.prototype.edit = function(val) { - return this.update({$set: val}); -}; - Cursor.prototype.unset = function(key) { if (!key && key !== 0) throw Error('baobab.Cursor.unset: expects a valid key to unset.'); diff --git a/test/suites/combination.js b/test/suites/combination.js index 8c778d8..acdb05a 100644 --- a/test/suites/combination.js +++ b/test/suites/combination.js @@ -47,8 +47,8 @@ describe('Combination', function() { baobab.commit(); // 3 - cursor.edit([1]); - othercursor.edit([4]); + cursor.set([1]); + othercursor.set([4]); baobab.commit(); assert.strictEqual(count, 3); @@ -72,8 +72,8 @@ describe('Combination', function() { baobab.commit(); // 3 - cursor.edit([1]); - othercursor.edit([4]); + cursor.set([1]); + othercursor.set([4]); baobab.commit(); assert.strictEqual(count, 1); @@ -97,12 +97,12 @@ describe('Combination', function() { baobab.commit(); // 3 - cursor.edit([1]); - othercursor.edit([4]); + cursor.set([1]); + othercursor.set([4]); baobab.commit(); // 4 - againCursor.edit([7]); + againCursor.set([7]); baobab.commit(); combination.release(); @@ -126,18 +126,18 @@ describe('Combination', function() { baobab.commit(); // 3 - cursor.edit([1]); - othercursor.edit([4]); + cursor.set([1]); + othercursor.set([4]); baobab.commit(); // 4 - againCursor.edit([7]); + againCursor.set([7]); baobab.commit(); // 5 - cursor.edit([1]); - othercursor.edit([4]); - againCursor.edit([7]); + cursor.set([1]); + othercursor.set([4]); + againCursor.set([7]); baobab.commit(); assert.strictEqual(count, 1); @@ -153,17 +153,17 @@ describe('Combination', function() { }); // 1 - cursor.edit([1]); - againCursor.edit([7]); + cursor.set([1]); + againCursor.set([7]); baobab.commit(); // 2 - againCursor.edit([7]); + againCursor.set([7]); baobab.commit(); // 3 - cursor.edit([1]); - othercursor.edit([4]); + cursor.set([1]); + othercursor.set([4]); baobab.commit(); assert.strictEqual(count, 1); @@ -189,8 +189,8 @@ describe('Combination', function() { baobab.commit(); // 3 - cursor.edit([1]); - othercursor.edit([4]); + cursor.set([1]); + othercursor.set([4]); baobab.commit(); assert.strictEqual(count, 3); @@ -213,8 +213,8 @@ describe('Combination', function() { baobab.commit(); // 3 - cursor.edit([1]); - othercursor.edit([4]); + cursor.set([1]); + othercursor.set([4]); baobab.commit(); assert.strictEqual(count, 3); diff --git a/test/suites/cursor.js b/test/suites/cursor.js index 3d282c2..ad31efc 100644 --- a/test/suites/cursor.js +++ b/test/suites/cursor.js @@ -291,7 +291,7 @@ describe('Cursor API', function() { done(); }); - parent.edit({firstname: 'Napoleon', lastname: 'Bonaparte'}); + parent.set({firstname: 'Napoleon', lastname: 'Bonaparte'}); }); it('when a child updates, so does the parent.', function(done) { @@ -319,7 +319,7 @@ describe('Cursor API', function() { done(); }); - child.edit('Napoleon'); + child.set('Napoleon'); }); it('when a leave updates, it should not update its siblings.', function(done) { @@ -355,7 +355,7 @@ describe('Cursor API', function() { done(); }); - leaf1.edit('tada'); + leaf1.set('tada'); }); it('should be possible to listen to the cursor\'s relevancy.', function(done) { @@ -397,7 +397,7 @@ describe('Cursor API', function() { done(); }); - cursor.edit('jacky'); + cursor.set('jacky'); }); }); @@ -534,7 +534,7 @@ describe('Cursor API', function() { it('an upper set should correctly resolve.', function(done) { var baobab = new Baobab({hello: {color: 'blue'}}); - baobab.select('hello', 'color').edit('yellow'); + baobab.select('hello', 'color').set('yellow'); baobab.set('hello', 'purple'); baobab.on('update', function() { From 93c1fa3f4a3034617fe926b1798e20757b254146 Mon Sep 17 00:00:00 2001 From: Yomguithereal Date: Wed, 1 Apr 2015 16:16:18 +0200 Subject: [PATCH 20/73] Dropping cursor.remove --- build/baobab.min.js | 2 +- src/cursor.js | 26 ++++++++++++++------------ src/type.js | 4 ++++ test/suites/cursor.js | 10 +--------- 4 files changed, 20 insertions(+), 22 deletions(-) diff --git a/build/baobab.min.js b/build/baobab.min.js index 2e4c66c..96a0d6c 100644 --- a/build/baobab.min.js +++ b/build/baobab.min.js @@ -1,2 +1,2 @@ /* baobab.js - Version: 1.0.0-rc1 - Author: Yomguithereal (Guillaume Plique) */ -!function(t){if("object"==typeof exports&&"undefined"!=typeof module)module.exports=t();else if("function"==typeof define&&define.amd)define([],t);else{var r;r="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:this,r.Baobab=t()}}(function(){var t;return function r(t,e,n){function o(s,a){if(!e[s]){if(!t[s]){var h="function"==typeof require&&require;if(!a&&h)return h(s,!0);if(i)return i(s,!0);var u=new Error("Cannot find module '"+s+"'");throw u.code="MODULE_NOT_FOUND",u}var c=e[s]={exports:{}};t[s][0].call(c.exports,function(r){var e=t[s][1][r];return o(e?e:r)},c,c.exports,r,t,e,n)}return e[s].exports}for(var i="function"==typeof require&&require,s=0;sr;r++)n.push(t[r].handler);return n}var o={once:"boolean",scope:"object"},i=function(){this._enabled=!0,this._children=[],this._handlers={},this._handlersAll=[]};i.prototype.on=function(t,r,e){var n,s,a,h,u,c;if("function"==typeof r){for(u="string"==typeof t?[t]:t,n=0,s=u.length;n!==s;n+=1)if(h=u[n]){this._handlers[h]||(this._handlers[h]=[]),c={handler:r};for(a in e||{}){if(!o[a])throw new Error('The option "'+a+'" is not recognized by Emmett.');c[a]=e[a]}this._handlers[h].push(c)}}else if(t&&"object"==typeof t&&!Array.isArray(t))for(h in t)i.prototype.on.call(this,h,t[h],r);else{if("function"!=typeof t)throw new Error("Wrong arguments.");c={handler:t};for(a in e||{}){if(!o[a])throw new Error('The option "'+a+'" is not recognized by Emmett.');c[a]=e[a]}this._handlersAll.push(c)}return this},i.prototype.once=function(t,r,e){if("function"==typeof r)e=e||{},e.once=!0,this.on(t,r,e);else{if((!t||"object"!=typeof t||Array.isArray(t))&&"function"!=typeof t)throw new Error("Wrong arguments.");r=r||{},r.once=!0,this.on(t,r)}return this},i.prototype.off=function(t,r){var e,n,o,i,s,a,h,u="string"==typeof t?[t]:t;if(1===arguments.length&&"function"==typeof u){r=arguments[0];for(s in this._handlers){for(a=[],e=0,n=this._handlers[s].length;e!==n;e+=1)this._handlers[s][e].handler!==r&&a.push(this._handlers[s][e]);this._handlers[s]=a}for(a=[],e=0,n=this._handlersAll.length;e!==n;e+=1)this._handlersAll[e].handler!==r&&a.push(this._handlersAll[e]);this._handlersAll=a}else if(2===arguments.length)for(e=0,n=u.length;e!==n;e+=1){if(h=u[e],this._handlers[h]){for(a=[],o=0,i=this._handlers[h].length;o!==i;o+=1)this._handlers[h][o].handler!==r&&a.push(this._handlers[h][o]);this._handlers[h]=a}this._handlers[h]&&0===this._handlers[h].length&&delete this._handlers[h]}return this},i.prototype.unbindAll=function(){var t;this._handlersAll=[];for(t in this._handlers)delete this._handlers[t];return this},i.prototype.emit=function(t,r){var e,n,o,i,s,a,h,u,c,l,f="string"==typeof t?[t]:t;if(!this._enabled)return this;for(r=void 0===r?{}:r,e=0,n=f.length;e!==n;e+=1)if(l=f[e],c=(this._handlers[l]||[]).concat(this._handlersAll),c.length){for(h={type:l,data:r||{},target:this},a=[],o=0,i=c.length;o!==i;o+=1)(this._handlers[l]&&this._handlers[l].indexOf(c[o])>=0||this._handlersAll.indexOf(c[o])>=0)&&(c[o].handler.call("scope"in c[o]?c[o].scope:this,h),c[o].once&&a.push(c[o]));for(s=0;se;e++)if(t._children[e]===r){t._children.splice(e,1);break}}),this._children.push(r),r},i.prototype.listeners=function(t){var e,n,o,i=[];if(t)for(i=r(this._handlers[t]),n=0,o=this._children.length;o>n;n++)i=i.concat(this._children[n].listeners(t));else{i=r(this._handlersAll);for(e in this._handlers)i=i.concat(r(this._handlers[e]));for(n=0,o=this._children.length;o>n;n++)i=i.concat(this._children[n].listeners())}return i},i.prototype.kill=function(){if(this.emit("emmett:kill"),this.unbindAll(),this._handlers=null,this._handlersAll=null,this._enabled=!1,this._children)for(var t=0,r=this._children.length;r>t;t++)this._children[t].kill();this._children=null},i.prototype.disable=function(){return this._enabled=!1,this},i.prototype.enable=function(){return this._enabled=!0,this},i.version="2.1.2","undefined"!=typeof n?("undefined"!=typeof e&&e.exports&&(n=e.exports=i),n.Emitter=i):"function"==typeof t&&t.amd?t("emmett",[],function(){return i}):this.Emitter=i}).call(this)},{}],4:[function(t,r){function e(t){return t+"$"+(new Date).getTime()+(""+Math.random()).replace("0.","")}function n(t,r){function e(t){this[t]=function(){var r=this.root[t].apply(this.root,arguments);return r instanceof o?this:r}}if(arguments.length<1&&(t={}),!(this instanceof n))return new n(t,r);if(!l.Object(t)&&!l.Array(t))throw Error("Baobab: invalid data.");i.call(this),this.options=s.shallowMerge(c,r),this._transaction={},this._future=void 0,this._cursors={},this.data=s.deepClone(t),this.root=this.select([]),["get","set","unset","update"].forEach(e.bind(this)),this.mixin=u.baobab(this)}var o=t("./cursor.js"),i=t("emmett"),s=t("./helpers.js"),a=t("./update.js"),h=t("./merge.js"),u=t("./mixins.js"),c=t("../defaults.js"),l=t("./type.js");s.inherits(n,i),n.prototype.select=function(t){if(!t)throw Error("Baobab.select: invalid path.");if(arguments.length>1&&(t=s.arrayOf(arguments)),!l.Path(t))throw Error("Baobab.select: invalid path.");t=[].concat(t);var r,n=l.ComplexPath(t);n&&(r=s.solvePath(this.data,t));var i=t.map(function(t){return l.Function(t)?e("fn"):l.Object(t)?e("ob"):t}).join("λ");if(this._cursors[i])return this._cursors[i];var a=new o(this,t,r,i);return this._cursors[i]=a,a},n.prototype.stack=function(t){var r=this;if(!l.Object(t))throw Error("Baobab.update: wrong specification.");return this._transaction=h(t,this._transaction),this.options.autoCommit?this.options.asynchronous?(this._future||(this._future=setTimeout(r.commit.bind(r,null),0)),this):this.commit():this},n.prototype.commit=function(){var t=a(this.data,this._transaction,this.options);return this.data=t.data,this._transaction={},this._future&&(this._future=clearTimeout(this._future)),this.emit("update",{log:t.log}),this},n.prototype.release=function(){delete this.data,delete this._transaction;for(var t in this._cursors)this._cursors[t].release();delete this._cursors,this.kill()},n.prototype.toJSON=function(){return this.get()},r.exports=n},{"../defaults.js":1,"./cursor.js":6,"./helpers.js":7,"./merge.js":8,"./mixins.js":9,"./type.js":10,"./update.js":11,emmett:3}],5:[function(t,r){function e(t,r){r.on("update",t.cursorListener),t.tree.off("update",t.treeListener),t.tree.on("update",t.treeListener)}function n(t){var r=this;if(arguments.length<2)throw Error("baobab.Combination: not enough arguments.");var n=arguments[1],o=s.arrayOf(arguments).slice(2);if(n instanceof Array&&(o=n.slice(1),n=n[0]),!a.Cursor(n))throw Error("baobab.Combination: argument should be a cursor.");if("or"!==t&&"and"!==t)throw Error("baobab.Combination: invalid operator.");i.call(this),this.cursors=[n],this.operators=[],this.tree=n.tree,this.updates=new Array(this.cursors.length),this.cursorListener=function(){r.updates[r.cursors.indexOf(this)]=!0},this.treeListener=function(){var t,e,n=r.updates[0];for(t=1,e=r.cursors.length;e>t;t++)n="or"===r.operators[t-1]?n||r.updates[t]:n&&r.updates[t];n&&r.emit("update"),r.updates=new Array(r.cursors.length)},this.bound=!1;var h=(this.on,this.once,function(){r.bound||(r.bound=!0,r.cursors.forEach(function(t){e(r,t)}))});this.on=s.before(h,this.on.bind(this)),this.once=s.before(h,this.once.bind(this)),o.forEach(function(r){this[t](r)},this)}function o(t){n.prototype[t]=function(r){if(!a.Cursor(r))throw this.release(),Error("baobab.Combination."+t+": argument should be a cursor.");if(~this.cursors.indexOf(r))throw this.release(),Error("baobab.Combination."+t+": cursor already in combination.");return this.cursors.push(r),this.operators.push(t),this.updates.length++,this.bound&&e(this,r),this}}var i=t("emmett"),s=t("./helpers.js"),a=t("./type.js");s.inherits(n,i),o("or"),o("and"),n.prototype.release=function(){this.cursors.forEach(function(t){t.off("update",this.cursorListener)},this),this.tree.off("update",this.treeListener),this.cursors=null,this.operators=null,this.tree=null,this.updates=null,this.kill()},r.exports=n},{"./helpers.js":7,"./type.js":10,emmett:3}],6:[function(t,r){function e(t,r,e,o){var a=this;n.call(this),r=r||[],this.tree=t,this.path=r,this.hash=o,this.complexPath=!!e,this.solvedPath=this.complexPath?e:this.path,this.relevant=void 0!==this.get(),this.updateHandler=function(t){var r,e,n,o,i,h,u=t.data.log,c=!1;if(a.complexPath&&(a.solvedPath=s.solvePath(a.tree.data,a.path)),!a.path.length)return a.emit("update");t:for(i=0,n=u.length;n>i;i++)for(r=u[i],h=0,o=r.length;o>h&&(e=r[h],e===""+a.solvedPath[h]);h++)if(h+1===o||h+1===a.solvedPath.length){c=!0;break t}var l=void 0!==a.get();a.relevant?l&&c?a.emit("update"):l||(a.emit("irrelevant"),a.relevant=!1):l&&c&&(a.emit("relevant"),a.emit("update"),a.relevant=!0)},this.mixin=i.cursor(this);var h=!1,u=function(){h||(h=!0,a.tree.on("update",a.updateHandler))};this.on=s.before(u,this.on.bind(this)),this.once=s.before(u,this.once.bind(this))}var n=t("emmett"),o=t("./combination.js"),i=t("./mixins.js"),s=t("./helpers.js"),a=t("./type.js");s.inherits(e,n),e.prototype.isRoot=function(){return!this.path.length},e.prototype.isLeaf=function(){return a.Primitive(this.get())},e.prototype.isBranch=function(){return!this.isLeaf()&&!this.isRoot()},e.prototype.root=function(){return this.tree.root()},e.prototype.select=function(t){if(arguments.length>1&&(t=s.arrayOf(arguments)),!a.Path(t))throw Error("baobab.Cursor.select: invalid path.");return this.tree.select(this.path.concat(t))},e.prototype.up=function(){return this.solvedPath&&this.solvedPath.length?this.tree.select(this.path.slice(0,-1)):null},e.prototype.left=function(){var t=+this.solvedPath[this.solvedPath.length-1];if(isNaN(t))throw Error("baobab.Cursor.left: cannot go left on a non-list type.");return t?this.tree.select(this.solvedPath.slice(0,-1).concat(t-1)):null},e.prototype.leftmost=function(){var t=+this.solvedPath[this.solvedPath.length-1];if(isNaN(t))throw Error("baobab.Cursor.leftmost: cannot go left on a non-list type.");return this.tree.select(this.solvedPath.slice(0,-1).concat(0))},e.prototype.right=function(){var t=+this.solvedPath[this.solvedPath.length-1];if(isNaN(t))throw Error("baobab.Cursor.right: cannot go right on a non-list type.");return t+1===this.up().get().length?null:this.tree.select(this.solvedPath.slice(0,-1).concat(t+1))},e.prototype.rightmost=function(){var t=+this.solvedPath[this.solvedPath.length-1];if(isNaN(t))throw Error("baobab.Cursor.right: cannot go right on a non-list type.");var r=this.up().get();return this.tree.select(this.solvedPath.slice(0,-1).concat(r.length-1))},e.prototype.down=function(){+this.solvedPath[this.solvedPath.length-1];return this.get()instanceof Array?this.tree.select(this.solvedPath.concat(0)):null},e.prototype.get=function(t){arguments.length>1&&(t=s.arrayOf(arguments));var r=this.solvedPath.concat((a.String(t)||a.Number(t)?[t]:t)||[]);return s.getIn(this.tree.data,r)},e.prototype.set=function(t,r){arguments.length<2&&(r=t,t=[]);var e=[].concat(t),n=s.solvePath(this.get(),e);if(!n)throw Error("baobab.Cursor.set: could not solve dynamic path.");var o=s.pathObject(n,{$set:r});return this.update(o)},e.prototype.unset=function(t){if(!t&&0!==t)throw Error("baobab.Cursor.unset: expects a valid key to unset.");if("object"!=typeof this.get())throw Error("baobab.Cursor.set: trying to set key to a non-object.");var r={};return r[t]={$unset:!0},this.update(r)},e.prototype.remove=function(){if(this.isRoot())throw Error("baobab.Cursor.remove: cannot remove root node.");return this.update({$unset:!0})},e.prototype.apply=function(t){if("function"!=typeof t)throw Error("baobab.Cursor.apply: argument is not a function.");return this.update({$apply:t})},e.prototype.chain=function(t){if("function"!=typeof t)throw Error("baobab.Cursor.chain: argument is not a function.");return this.update({$chain:t})},e.prototype.push=function(t){if(!(this.get()instanceof Array))throw Error("baobab.Cursor.push: trying to push to non-array value.");return this.update(arguments.length>1?{$push:s.arrayOf(arguments)}:{$push:t})},e.prototype.unshift=function(t){if(!(this.get()instanceof Array))throw Error("baobab.Cursor.push: trying to push to non-array value.");return this.update(arguments.length>1?{$unshift:s.arrayOf(arguments)}:{$unshift:t})},e.prototype.merge=function(t){if(!a.Object(t))throw Error("baobab.Cursor.merge: trying to merge a non-object.");if(!a.Object(this.get()))throw Error("baobab.Cursor.merge: trying to merge into a non-object.");this.update({$merge:t})},e.prototype.update=function(t){return this.tree.stack(s.pathObject(this.solvedPath,t)),this},e.prototype.or=function(t){return new o("or",this,t)},e.prototype.and=function(t){return new o("and",this,t)},e.prototype.release=function(){this.tree.off("update",this.updateHandler),this.hash&&delete this.tree._cursors[this.hash],delete this.tree,delete this.path,delete this.solvedPath,this.kill()},e.prototype.toJSON=function(){return this.get()},a.Cursor=function(t){return t instanceof e},r.exports=e},{"./combination.js":5,"./helpers.js":7,"./mixins.js":9,"./type.js":10,emmett:3}],7:[function(t,r){function e(t){return Array.prototype.slice.call(t)}function n(t,r){return function(){t(),r.apply(null,arguments)}}function o(t,r){var e,n={};for(e in t)n[e]=t[e];for(e in r)n[e]=r[e];return n}function i(t){var r=t.source,e="";return t.global&&(e+="g"),t.multiline&&(e+="m"),t.ignoreCase&&(e+="i"),t.sticky&&(e+="y"),t.unicode&&(e+="u"),new RegExp(r,e)}function s(t,r){if(!r||"object"!=typeof r||r instanceof Error||r instanceof ArrayBuffer)return r;if(g.Array(r)){if(t){var e,n,o=[];for(e=0,n=r.length;n>e;e++)o.push(_(r[e]));return o}return r.slice(0)}if(g.Date(r))return new Date(r.getTime());if(r instanceof RegExp)return i(r);if(g.Object(r)){var s,a={};r.constructor&&r.constructor!==Object&&(a=Object.create(r.constructor.prototype));for(s in r)r.hasOwnProperty(s)&&(a[s]=t?_(r[s]):r[s]);return a}return r}function a(t,r){return function(e){return r(t(e))}}function h(t,r){var e,n;for(e=0,n=t.length;n>e;e++)if(r(t[e]))return t[e]}function u(t,r){var e,n;for(e=0,n=t.length;n>e;e++)if(r(t[e]))return e;return-1}function c(t,r){var e,n=!0;if(!t)return!1;for(e in r)if(g.Object(r[e]))n=n&&c(t[e],r[e]);else if(g.Array(r[e]))n=n&&!!~r[e].indexOf(t[e]);else if(t[e]!==r[e])return!1;return n}function l(t,r){return h(t,function(t){return c(t,r)})}function f(t,r){return u(t,function(t){return c(t,r)})}function p(t,r){r=r||[];var e,n,o=t;for(e=0,n=r.length;n>e;e++){if(!o)return;if("function"==typeof r[e]){if(!g.Array(o))return;o=h(o,r[e])}else if("object"==typeof r[e]){if(!g.Array(o))return;o=l(o,r[e])}else o=o[r[e]]}return o}function d(t,r){var e,n,o,i=[],s=t;for(n=0,o=r.length;o>n;n++){if(!s)return null;if("function"==typeof r[n]){if(!g.Array(s))return;e=u(s,r[n]),i.push(e),s=s[e]}else if("object"==typeof r[n]){if(!g.Array(s))return;e=f(s,r[n]),i.push(e),s=s[e]}else i.push(r[n]),s=s[r[n]]||{}}return i}function b(t,r){var e,n=t.length,o={},i=o;for(n||(o=r),e=0;n>e;e++)i[t[e]]=e+1===n?r:{},i=i[t[e]];return o}function y(t,r){t.super_=r;var e=function(){};e.prototype=r.prototype,t.prototype=new e,t.prototype.constructor=t}var g=t("./type.js"),m=s.bind(null,!1),_=s.bind(null,!0);r.exports={arrayOf:e,before:n,deepClone:_,shallowClone:m,shallowMerge:o,compose:a,getIn:p,inherits:y,pathObject:b,solvePath:d}},{"./type.js":10}],8:[function(t,r){function e(t,r,e){s.forEach(function(r){e!==r&&delete t[r]}),t[e]=r[e]}function n(t,r){var a,h=o.shallowClone(r||{});s.forEach(function(r){t[r]&&e(h,t,r)}),t.$chain&&(s.slice(0,-1).forEach(function(t){delete h[t]}),h.$apply=h.$apply?o.compose(h.$apply,t.$chain):t.$chain),t.$push&&h.$push?h.$push=i.Array(h.$push)?h.$push.concat(t.$push):[h.$push].concat(t.$push):t.$push&&(h.$push=t.$push),t.$unshift&&h.$unshift?h.$unshift=i.Array(t.$unshift)?t.$unshift.concat(h.$unshift):[t.$unshift].concat(h.$unshift):t.$unshift&&(h.$unshift=t.$unshift);for(a in t)i.Object(t[a])?h[a]=n(t[a],h[a]):"$"!==a[0]&&(h[a]=t[a]);return h}var o=t("./helpers.js"),i=t("./type.js"),s=["$unset","$set","$merge","$apply"];r.exports=n},{"./helpers.js":7,"./type.js":10}],9:[function(t,r){var e=t("./combination.js"),n=t("./type.js");r.exports={baobab:function(t){return{mixins:[{getInitialState:function(){if(this.tree=t,!this.cursor&&!this.cursors)return{};if(this.cursor&&this.cursors)throw Error("baobab.mixin: you cannot have both `component.cursor` and `component.cursors`. Please make up your mind.");if(this.__type=null,this.__updateHandler=function(){this.setState(this.__getCursorData())}.bind(this),this.cursor){if(!n.MixinCursor(this.cursor))throw Error("baobab.mixin.cursor: invalid data (cursor, string, array or function).");n.Function(this.cursor)&&(this.cursor=this.cursor()),n.Cursor(this.cursor)||(this.cursor=t.select(this.cursor)),this.__getCursorData=function(){return{cursor:this.cursor.get()}}.bind(this),this.__type="single"}else if(this.cursors){if(!n.MixinCursors(this.cursors))throw Error("baobab.mixin.cursor: invalid data (object, array or function).");if(n.Function(this.cursors)&&(this.cursors=this.cursors()),n.Array(this.cursors))this.cursors=this.cursors.map(function(r){return n.Cursor(r)?r:t.select(r)}),this.__getCursorData=function(){return{cursors:this.cursors.map(function(t){return t.get()})}}.bind(this),this.__type="array";else{for(var r in this.cursors)n.Cursor(this.cursors[r])||(this.cursors[r]=t.select(this.cursors[r]));this.__getCursorData=function(){var t={};for(r in this.cursors)t[r]=this.cursors[r].get();return{cursors:t}}.bind(this),this.__type="object"}}return this.__getCursorData()},componentDidMount:function(){"single"===this.__type?(this.__combination=new e("or",[this.cursor]),this.__combination.on("update",this.__updateHandler)):"array"===this.__type?(this.__combination=new e("or",this.cursors),this.__combination.on("update",this.__updateHandler)):"object"===this.__type&&(this.__combination=new e("or",Object.keys(this.cursors).map(function(t){return this.cursors[t]},this)),this.__combination.on("update",this.__updateHandler))},componentWillUnmount:function(){this.__combination&&this.__combination.release()}}].concat(t.options.mixins)}},cursor:function(t){return{mixins:[{getInitialState:function(){return this.cursor=t,this.__updateHandler=function(){this.setState({cursor:this.cursor.get()})}.bind(this),{cursor:this.cursor.get()}},componentDidMount:function(){this.cursor.on("update",this.__updateHandler)},componentWillUnmount:function(){this.cursor.off("update",this.__updateHandler)}}].concat(t.tree.options.mixins)}}}},{"./combination.js":5,"./type.js":10}],10:[function(t,r){function e(t,r){return r.some(function(r){return n[r](t)})}var n={};n.Array=function(t){return Array.isArray(t)},n.Object=function(t){return!Array.isArray(t)&&"object"==typeof t&&null!==t},n.String=function(t){return"string"==typeof t},n.Number=function(t){return"number"==typeof t},n.Function=function(t){return"function"==typeof t},n.Primitive=function(t){return"string"==typeof t||"number"==typeof t||"boolean"==typeof t},n.Date=function(t){return t instanceof Date},n.Path=function(t){var r=["String","Number","Function","Object"];return n.Array(t)?t.every(function(t){return e(t,r)}):e(t,r)},n.MixinCursor=function(t){return e(t,["String","Number","Array","Function","Cursor"])},n.MixinCursors=function(t){return e(t,["Object","Array","Function"])},n.ComplexPath=function(t){return e(t,["Object","Function"])},r.exports=n},{}],11:[function(t,r){function e(t,r){var e=new Error("baobab.update: "+r+" at path /"+t.slice(1).toString());return e.path=t,e}var n=t("./helpers.js"),o=t("./type.js");r.exports=function(t,r,i){if(i=i||{},!o.Object(t)&&!o.Array(t))throw Error("baobab.update: invalid target.");var s={};t={root:n.shallowClone(t)};var a=function(t,r,i,h){i=i||["root"];var u,c,l,f=i.join("λ"),p=i[i.length-1],d=Object.keys(r).some(function(t){return!!~["$unset","$set","$apply","$merge","$push","$unshift"].indexOf(t)});if(d){s[f]=!0;for(c in r){if("$unset"===c){var b=i[i.length-2];o.Array(t)?h[b]=t.slice(0,+p).concat(t.slice(+p+1)):(h[b]=n.shallowClone(t),delete h[b][p]);break}if("$set"===c){l=r.$set,t[p]=l;break}if("$apply"===c){if(u=r.$apply,"function"!=typeof u)throw e(i,"using command $apply with a non function");t[p]=u.call(null,t[p]);break}if("$merge"===c){if(l=r.$merge,!o.Object(t[p])||!o.Object(l))throw e(i,"using command $merge with a non object");t[p]=n.shallowMerge(t[p],l);break}if("$push"===c){if(l=r.$push,!o.Array(t[p]))throw e(i,"using command $push to a non array");t[p]=t[p].concat(l)}if("$unshift"===c){if(l=r.$unshift,!o.Array(t[p]))throw e(i,"using command $unshift to a non array");t[p]=[].concat(l).concat(t[p])}}}else for(c in r)t[p][c]="undefined"==typeof t[p][c]?{}:n.shallowClone(t[p][c]),a(t[p],r[c],i.concat(c),t)};return a(t,r),{data:t.root,log:Object.keys(s).map(function(t){return t.split("λ").slice(1)})}}},{"./helpers.js":7,"./type.js":10}]},{},[2])(2)}); \ No newline at end of file +!function(t){if("object"==typeof exports&&"undefined"!=typeof module)module.exports=t();else if("function"==typeof define&&define.amd)define([],t);else{var r;r="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:this,r.Baobab=t()}}(function(){var t;return function r(t,e,n){function o(s,a){if(!e[s]){if(!t[s]){var h="function"==typeof require&&require;if(!a&&h)return h(s,!0);if(i)return i(s,!0);var u=new Error("Cannot find module '"+s+"'");throw u.code="MODULE_NOT_FOUND",u}var c=e[s]={exports:{}};t[s][0].call(c.exports,function(r){var e=t[s][1][r];return o(e?e:r)},c,c.exports,r,t,e,n)}return e[s].exports}for(var i="function"==typeof require&&require,s=0;sr;r++)n.push(t[r].handler);return n}var o={once:"boolean",scope:"object"},i=function(){this._enabled=!0,this._children=[],this._handlers={},this._handlersAll=[]};i.prototype.on=function(t,r,e){var n,s,a,h,u,c;if("function"==typeof r){for(u="string"==typeof t?[t]:t,n=0,s=u.length;n!==s;n+=1)if(h=u[n]){this._handlers[h]||(this._handlers[h]=[]),c={handler:r};for(a in e||{}){if(!o[a])throw new Error('The option "'+a+'" is not recognized by Emmett.');c[a]=e[a]}this._handlers[h].push(c)}}else if(t&&"object"==typeof t&&!Array.isArray(t))for(h in t)i.prototype.on.call(this,h,t[h],r);else{if("function"!=typeof t)throw new Error("Wrong arguments.");c={handler:t};for(a in e||{}){if(!o[a])throw new Error('The option "'+a+'" is not recognized by Emmett.');c[a]=e[a]}this._handlersAll.push(c)}return this},i.prototype.once=function(t,r,e){if("function"==typeof r)e=e||{},e.once=!0,this.on(t,r,e);else{if((!t||"object"!=typeof t||Array.isArray(t))&&"function"!=typeof t)throw new Error("Wrong arguments.");r=r||{},r.once=!0,this.on(t,r)}return this},i.prototype.off=function(t,r){var e,n,o,i,s,a,h,u="string"==typeof t?[t]:t;if(1===arguments.length&&"function"==typeof u){r=arguments[0];for(s in this._handlers){for(a=[],e=0,n=this._handlers[s].length;e!==n;e+=1)this._handlers[s][e].handler!==r&&a.push(this._handlers[s][e]);this._handlers[s]=a}for(a=[],e=0,n=this._handlersAll.length;e!==n;e+=1)this._handlersAll[e].handler!==r&&a.push(this._handlersAll[e]);this._handlersAll=a}else if(2===arguments.length)for(e=0,n=u.length;e!==n;e+=1){if(h=u[e],this._handlers[h]){for(a=[],o=0,i=this._handlers[h].length;o!==i;o+=1)this._handlers[h][o].handler!==r&&a.push(this._handlers[h][o]);this._handlers[h]=a}this._handlers[h]&&0===this._handlers[h].length&&delete this._handlers[h]}return this},i.prototype.unbindAll=function(){var t;this._handlersAll=[];for(t in this._handlers)delete this._handlers[t];return this},i.prototype.emit=function(t,r){var e,n,o,i,s,a,h,u,c,l,f="string"==typeof t?[t]:t;if(!this._enabled)return this;for(r=void 0===r?{}:r,e=0,n=f.length;e!==n;e+=1)if(l=f[e],c=(this._handlers[l]||[]).concat(this._handlersAll),c.length){for(h={type:l,data:r||{},target:this},a=[],o=0,i=c.length;o!==i;o+=1)(this._handlers[l]&&this._handlers[l].indexOf(c[o])>=0||this._handlersAll.indexOf(c[o])>=0)&&(c[o].handler.call("scope"in c[o]?c[o].scope:this,h),c[o].once&&a.push(c[o]));for(s=0;se;e++)if(t._children[e]===r){t._children.splice(e,1);break}}),this._children.push(r),r},i.prototype.listeners=function(t){var e,n,o,i=[];if(t)for(i=r(this._handlers[t]),n=0,o=this._children.length;o>n;n++)i=i.concat(this._children[n].listeners(t));else{i=r(this._handlersAll);for(e in this._handlers)i=i.concat(r(this._handlers[e]));for(n=0,o=this._children.length;o>n;n++)i=i.concat(this._children[n].listeners())}return i},i.prototype.kill=function(){if(this.emit("emmett:kill"),this.unbindAll(),this._handlers=null,this._handlersAll=null,this._enabled=!1,this._children)for(var t=0,r=this._children.length;r>t;t++)this._children[t].kill();this._children=null},i.prototype.disable=function(){return this._enabled=!1,this},i.prototype.enable=function(){return this._enabled=!0,this},i.version="2.1.2","undefined"!=typeof n?("undefined"!=typeof e&&e.exports&&(n=e.exports=i),n.Emitter=i):"function"==typeof t&&t.amd?t("emmett",[],function(){return i}):this.Emitter=i}).call(this)},{}],4:[function(t,r){function e(t){return t+"$"+(new Date).getTime()+(""+Math.random()).replace("0.","")}function n(t,r){function e(t){this[t]=function(){var r=this.root[t].apply(this.root,arguments);return r instanceof o?this:r}}if(arguments.length<1&&(t={}),!(this instanceof n))return new n(t,r);if(!l.Object(t)&&!l.Array(t))throw Error("Baobab: invalid data.");i.call(this),this.options=s.shallowMerge(c,r),this._transaction={},this._future=void 0,this._cursors={},this.data=s.deepClone(t),this.root=this.select([]),["get","set","unset","update"].forEach(e.bind(this)),this.mixin=u.baobab(this)}var o=t("./cursor.js"),i=t("emmett"),s=t("./helpers.js"),a=t("./update.js"),h=t("./merge.js"),u=t("./mixins.js"),c=t("../defaults.js"),l=t("./type.js");s.inherits(n,i),n.prototype.select=function(t){if(!t)throw Error("Baobab.select: invalid path.");if(arguments.length>1&&(t=s.arrayOf(arguments)),!l.Path(t))throw Error("Baobab.select: invalid path.");t=[].concat(t);var r,n=l.ComplexPath(t);n&&(r=s.solvePath(this.data,t));var i=t.map(function(t){return l.Function(t)?e("fn"):l.Object(t)?e("ob"):t}).join("λ");if(this._cursors[i])return this._cursors[i];var a=new o(this,t,r,i);return this._cursors[i]=a,a},n.prototype.stack=function(t){var r=this;if(!l.Object(t))throw Error("Baobab.update: wrong specification.");return this._transaction=h(t,this._transaction),this.options.autoCommit?this.options.asynchronous?(this._future||(this._future=setTimeout(r.commit.bind(r,null),0)),this):this.commit():this},n.prototype.commit=function(){var t=a(this.data,this._transaction,this.options);return this.data=t.data,this._transaction={},this._future&&(this._future=clearTimeout(this._future)),this.emit("update",{log:t.log}),this},n.prototype.release=function(){delete this.data,delete this._transaction;for(var t in this._cursors)this._cursors[t].release();delete this._cursors,this.kill()},n.prototype.toJSON=function(){return this.get()},r.exports=n},{"../defaults.js":1,"./cursor.js":6,"./helpers.js":7,"./merge.js":8,"./mixins.js":9,"./type.js":10,"./update.js":11,emmett:3}],5:[function(t,r){function e(t,r){r.on("update",t.cursorListener),t.tree.off("update",t.treeListener),t.tree.on("update",t.treeListener)}function n(t){var r=this;if(arguments.length<2)throw Error("baobab.Combination: not enough arguments.");var n=arguments[1],o=s.arrayOf(arguments).slice(2);if(n instanceof Array&&(o=n.slice(1),n=n[0]),!a.Cursor(n))throw Error("baobab.Combination: argument should be a cursor.");if("or"!==t&&"and"!==t)throw Error("baobab.Combination: invalid operator.");i.call(this),this.cursors=[n],this.operators=[],this.tree=n.tree,this.updates=new Array(this.cursors.length),this.cursorListener=function(){r.updates[r.cursors.indexOf(this)]=!0},this.treeListener=function(){var t,e,n=r.updates[0];for(t=1,e=r.cursors.length;e>t;t++)n="or"===r.operators[t-1]?n||r.updates[t]:n&&r.updates[t];n&&r.emit("update"),r.updates=new Array(r.cursors.length)},this.bound=!1;var h=(this.on,this.once,function(){r.bound||(r.bound=!0,r.cursors.forEach(function(t){e(r,t)}))});this.on=s.before(h,this.on.bind(this)),this.once=s.before(h,this.once.bind(this)),o.forEach(function(r){this[t](r)},this)}function o(t){n.prototype[t]=function(r){if(!a.Cursor(r))throw this.release(),Error("baobab.Combination."+t+": argument should be a cursor.");if(~this.cursors.indexOf(r))throw this.release(),Error("baobab.Combination."+t+": cursor already in combination.");return this.cursors.push(r),this.operators.push(t),this.updates.length++,this.bound&&e(this,r),this}}var i=t("emmett"),s=t("./helpers.js"),a=t("./type.js");s.inherits(n,i),o("or"),o("and"),n.prototype.release=function(){this.cursors.forEach(function(t){t.off("update",this.cursorListener)},this),this.tree.off("update",this.treeListener),this.cursors=null,this.operators=null,this.tree=null,this.updates=null,this.kill()},r.exports=n},{"./helpers.js":7,"./type.js":10,emmett:3}],6:[function(t,r){function e(t,r,e,o){var a=this;n.call(this),r=r||[],this.tree=t,this.path=r,this.hash=o,this.complexPath=!!e,this.solvedPath=this.complexPath?e:this.path,this.relevant=void 0!==this.get(),this.updateHandler=function(t){var r,e,n,o,i,h,u=t.data.log,c=!1;if(a.complexPath&&(a.solvedPath=s.solvePath(a.tree.data,a.path)),!a.path.length)return a.emit("update");t:for(i=0,n=u.length;n>i;i++)for(r=u[i],h=0,o=r.length;o>h&&(e=r[h],e===""+a.solvedPath[h]);h++)if(h+1===o||h+1===a.solvedPath.length){c=!0;break t}var l=void 0!==a.get();a.relevant?l&&c?a.emit("update"):l||(a.emit("irrelevant"),a.relevant=!1):l&&c&&(a.emit("relevant"),a.emit("update"),a.relevant=!0)},this.mixin=i.cursor(this);var h=!1,u=function(){h||(h=!0,a.tree.on("update",a.updateHandler))};this.on=s.before(u,this.on.bind(this)),this.once=s.before(u,this.once.bind(this))}var n=t("emmett"),o=t("./combination.js"),i=t("./mixins.js"),s=t("./helpers.js"),a=t("./type.js");s.inherits(e,n),e.prototype.isRoot=function(){return!this.path.length},e.prototype.isLeaf=function(){return a.Primitive(this.get())},e.prototype.isBranch=function(){return!this.isLeaf()&&!this.isRoot()},e.prototype.root=function(){return this.tree.root()},e.prototype.select=function(t){if(arguments.length>1&&(t=s.arrayOf(arguments)),!a.Path(t))throw Error("baobab.Cursor.select: invalid path.");return this.tree.select(this.path.concat(t))},e.prototype.up=function(){return this.solvedPath&&this.solvedPath.length?this.tree.select(this.path.slice(0,-1)):null},e.prototype.left=function(){var t=+this.solvedPath[this.solvedPath.length-1];if(isNaN(t))throw Error("baobab.Cursor.left: cannot go left on a non-list type.");return t?this.tree.select(this.solvedPath.slice(0,-1).concat(t-1)):null},e.prototype.leftmost=function(){var t=+this.solvedPath[this.solvedPath.length-1];if(isNaN(t))throw Error("baobab.Cursor.leftmost: cannot go left on a non-list type.");return this.tree.select(this.solvedPath.slice(0,-1).concat(0))},e.prototype.right=function(){var t=+this.solvedPath[this.solvedPath.length-1];if(isNaN(t))throw Error("baobab.Cursor.right: cannot go right on a non-list type.");return t+1===this.up().get().length?null:this.tree.select(this.solvedPath.slice(0,-1).concat(t+1))},e.prototype.rightmost=function(){var t=+this.solvedPath[this.solvedPath.length-1];if(isNaN(t))throw Error("baobab.Cursor.right: cannot go right on a non-list type.");var r=this.up().get();return this.tree.select(this.solvedPath.slice(0,-1).concat(r.length-1))},e.prototype.down=function(){+this.solvedPath[this.solvedPath.length-1];return this.get()instanceof Array?this.tree.select(this.solvedPath.concat(0)):null},e.prototype.get=function(t){arguments.length>1&&(t=s.arrayOf(arguments));var r=this.solvedPath.concat((a.String(t)||a.Number(t)?[t]:t)||[]);return s.getIn(this.tree.data,r)},e.prototype.set=function(t,r){arguments.length<2&&(r=t,t=[]);var e=[].concat(t),n=s.solvePath(this.get(),e);if(!n)throw Error("baobab.Cursor.set: could not solve dynamic path.");var o=s.pathObject(n,{$set:r});return this.update(o)},e.prototype.unset=function(t){if(void 0===t){if(this.isRoot())throw Error("baobab.Cursor.unset: cannot remove root node.");return this.update({$unset:!0})}var r=[].concat(t),e=s.solvePath(this.get(),r);if(!e)throw Error("baobab.Cursor.unset: could not solve dynamic path.");var n=s.pathObject(e,{$unset:!0});return this.update(n)},e.prototype.apply=function(t){if("function"!=typeof t)throw Error("baobab.Cursor.apply: argument is not a function.");return this.update({$apply:t})},e.prototype.chain=function(t){if("function"!=typeof t)throw Error("baobab.Cursor.chain: argument is not a function.");return this.update({$chain:t})},e.prototype.push=function(t){if(!(this.get()instanceof Array))throw Error("baobab.Cursor.push: trying to push to non-array value.");return this.update(arguments.length>1?{$push:s.arrayOf(arguments)}:{$push:t})},e.prototype.unshift=function(t){if(!(this.get()instanceof Array))throw Error("baobab.Cursor.push: trying to push to non-array value.");return this.update(arguments.length>1?{$unshift:s.arrayOf(arguments)}:{$unshift:t})},e.prototype.merge=function(t){if(!a.Object(t))throw Error("baobab.Cursor.merge: trying to merge a non-object.");if(!a.Object(this.get()))throw Error("baobab.Cursor.merge: trying to merge into a non-object.");this.update({$merge:t})},e.prototype.update=function(t){return this.tree.stack(s.pathObject(this.solvedPath,t)),this},e.prototype.or=function(t){return new o("or",this,t)},e.prototype.and=function(t){return new o("and",this,t)},e.prototype.release=function(){this.tree.off("update",this.updateHandler),this.hash&&delete this.tree._cursors[this.hash],delete this.tree,delete this.path,delete this.solvedPath,this.kill()},e.prototype.toJSON=function(){return this.get()},a.Cursor=function(t){return t instanceof e},r.exports=e},{"./combination.js":5,"./helpers.js":7,"./mixins.js":9,"./type.js":10,emmett:3}],7:[function(t,r){function e(t){return Array.prototype.slice.call(t)}function n(t,r){return function(){t(),r.apply(null,arguments)}}function o(t,r){var e,n={};for(e in t)n[e]=t[e];for(e in r)n[e]=r[e];return n}function i(t){var r=t.source,e="";return t.global&&(e+="g"),t.multiline&&(e+="m"),t.ignoreCase&&(e+="i"),t.sticky&&(e+="y"),t.unicode&&(e+="u"),new RegExp(r,e)}function s(t,r){if(!r||"object"!=typeof r||r instanceof Error||r instanceof ArrayBuffer)return r;if(g.Array(r)){if(t){var e,n,o=[];for(e=0,n=r.length;n>e;e++)o.push(_(r[e]));return o}return r.slice(0)}if(g.Date(r))return new Date(r.getTime());if(r instanceof RegExp)return i(r);if(g.Object(r)){var s,a={};r.constructor&&r.constructor!==Object&&(a=Object.create(r.constructor.prototype));for(s in r)r.hasOwnProperty(s)&&(a[s]=t?_(r[s]):r[s]);return a}return r}function a(t,r){return function(e){return r(t(e))}}function h(t,r){var e,n;for(e=0,n=t.length;n>e;e++)if(r(t[e]))return t[e]}function u(t,r){var e,n;for(e=0,n=t.length;n>e;e++)if(r(t[e]))return e;return-1}function c(t,r){var e,n=!0;if(!t)return!1;for(e in r)if(g.Object(r[e]))n=n&&c(t[e],r[e]);else if(g.Array(r[e]))n=n&&!!~r[e].indexOf(t[e]);else if(t[e]!==r[e])return!1;return n}function l(t,r){return h(t,function(t){return c(t,r)})}function f(t,r){return u(t,function(t){return c(t,r)})}function p(t,r){r=r||[];var e,n,o=t;for(e=0,n=r.length;n>e;e++){if(!o)return;if("function"==typeof r[e]){if(!g.Array(o))return;o=h(o,r[e])}else if("object"==typeof r[e]){if(!g.Array(o))return;o=l(o,r[e])}else o=o[r[e]]}return o}function d(t,r){var e,n,o,i=[],s=t;for(n=0,o=r.length;o>n;n++){if(!s)return null;if("function"==typeof r[n]){if(!g.Array(s))return;e=u(s,r[n]),i.push(e),s=s[e]}else if("object"==typeof r[n]){if(!g.Array(s))return;e=f(s,r[n]),i.push(e),s=s[e]}else i.push(r[n]),s=s[r[n]]||{}}return i}function b(t,r){var e,n=t.length,o={},i=o;for(n||(o=r),e=0;n>e;e++)i[t[e]]=e+1===n?r:{},i=i[t[e]];return o}function y(t,r){t.super_=r;var e=function(){};e.prototype=r.prototype,t.prototype=new e,t.prototype.constructor=t}var g=t("./type.js"),m=s.bind(null,!1),_=s.bind(null,!0);r.exports={arrayOf:e,before:n,deepClone:_,shallowClone:m,shallowMerge:o,compose:a,getIn:p,inherits:y,pathObject:b,solvePath:d}},{"./type.js":10}],8:[function(t,r){function e(t,r,e){s.forEach(function(r){e!==r&&delete t[r]}),t[e]=r[e]}function n(t,r){var a,h=o.shallowClone(r||{});s.forEach(function(r){t[r]&&e(h,t,r)}),t.$chain&&(s.slice(0,-1).forEach(function(t){delete h[t]}),h.$apply=h.$apply?o.compose(h.$apply,t.$chain):t.$chain),t.$push&&h.$push?h.$push=i.Array(h.$push)?h.$push.concat(t.$push):[h.$push].concat(t.$push):t.$push&&(h.$push=t.$push),t.$unshift&&h.$unshift?h.$unshift=i.Array(t.$unshift)?t.$unshift.concat(h.$unshift):[t.$unshift].concat(h.$unshift):t.$unshift&&(h.$unshift=t.$unshift);for(a in t)i.Object(t[a])?h[a]=n(t[a],h[a]):"$"!==a[0]&&(h[a]=t[a]);return h}var o=t("./helpers.js"),i=t("./type.js"),s=["$unset","$set","$merge","$apply"];r.exports=n},{"./helpers.js":7,"./type.js":10}],9:[function(t,r){var e=t("./combination.js"),n=t("./type.js");r.exports={baobab:function(t){return{mixins:[{getInitialState:function(){if(this.tree=t,!this.cursor&&!this.cursors)return{};if(this.cursor&&this.cursors)throw Error("baobab.mixin: you cannot have both `component.cursor` and `component.cursors`. Please make up your mind.");if(this.__type=null,this.__updateHandler=function(){this.setState(this.__getCursorData())}.bind(this),this.cursor){if(!n.MixinCursor(this.cursor))throw Error("baobab.mixin.cursor: invalid data (cursor, string, array or function).");n.Function(this.cursor)&&(this.cursor=this.cursor()),n.Cursor(this.cursor)||(this.cursor=t.select(this.cursor)),this.__getCursorData=function(){return{cursor:this.cursor.get()}}.bind(this),this.__type="single"}else if(this.cursors){if(!n.MixinCursors(this.cursors))throw Error("baobab.mixin.cursor: invalid data (object, array or function).");if(n.Function(this.cursors)&&(this.cursors=this.cursors()),n.Array(this.cursors))this.cursors=this.cursors.map(function(r){return n.Cursor(r)?r:t.select(r)}),this.__getCursorData=function(){return{cursors:this.cursors.map(function(t){return t.get()})}}.bind(this),this.__type="array";else{for(var r in this.cursors)n.Cursor(this.cursors[r])||(this.cursors[r]=t.select(this.cursors[r]));this.__getCursorData=function(){var t={};for(r in this.cursors)t[r]=this.cursors[r].get();return{cursors:t}}.bind(this),this.__type="object"}}return this.__getCursorData()},componentDidMount:function(){"single"===this.__type?(this.__combination=new e("or",[this.cursor]),this.__combination.on("update",this.__updateHandler)):"array"===this.__type?(this.__combination=new e("or",this.cursors),this.__combination.on("update",this.__updateHandler)):"object"===this.__type&&(this.__combination=new e("or",Object.keys(this.cursors).map(function(t){return this.cursors[t]},this)),this.__combination.on("update",this.__updateHandler))},componentWillUnmount:function(){this.__combination&&this.__combination.release()}}].concat(t.options.mixins)}},cursor:function(t){return{mixins:[{getInitialState:function(){return this.cursor=t,this.__updateHandler=function(){this.setState({cursor:this.cursor.get()})}.bind(this),{cursor:this.cursor.get()}},componentDidMount:function(){this.cursor.on("update",this.__updateHandler)},componentWillUnmount:function(){this.cursor.off("update",this.__updateHandler)}}].concat(t.tree.options.mixins)}}}},{"./combination.js":5,"./type.js":10}],10:[function(t,r){function e(t,r){return r.some(function(r){return n[r](t)})}var n={};n.Array=function(t){return Array.isArray(t)},n.Object=function(t){return!Array.isArray(t)&&"object"==typeof t&&null!==t},n.String=function(t){return"string"==typeof t},n.Number=function(t){return"number"==typeof t},n.Function=function(t){return"function"==typeof t},n.Primitive=function(t){return"string"==typeof t||"number"==typeof t||"boolean"==typeof t},n.Date=function(t){return t instanceof Date},n.NonScalar=function(t){return n.Object(t)||n.Array(t)},n.Path=function(t){var r=["String","Number","Function","Object"];return n.Array(t)?t.every(function(t){return e(t,r)}):e(t,r)},n.MixinCursor=function(t){return e(t,["String","Number","Array","Function","Cursor"])},n.MixinCursors=function(t){return e(t,["Object","Array","Function"])},n.ComplexPath=function(t){return e(t,["Object","Function"])},r.exports=n},{}],11:[function(t,r){function e(t,r){var e=new Error("baobab.update: "+r+" at path /"+t.slice(1).toString());return e.path=t,e}var n=t("./helpers.js"),o=t("./type.js");r.exports=function(t,r,i){if(i=i||{},!o.Object(t)&&!o.Array(t))throw Error("baobab.update: invalid target.");var s={};t={root:n.shallowClone(t)};var a=function(t,r,i,h){i=i||["root"];var u,c,l,f=i.join("λ"),p=i[i.length-1],d=Object.keys(r).some(function(t){return!!~["$unset","$set","$apply","$merge","$push","$unshift"].indexOf(t)});if(d){s[f]=!0;for(c in r){if("$unset"===c){var b=i[i.length-2];o.Array(t)?h[b]=t.slice(0,+p).concat(t.slice(+p+1)):(h[b]=n.shallowClone(t),delete h[b][p]);break}if("$set"===c){l=r.$set,t[p]=l;break}if("$apply"===c){if(u=r.$apply,"function"!=typeof u)throw e(i,"using command $apply with a non function");t[p]=u.call(null,t[p]);break}if("$merge"===c){if(l=r.$merge,!o.Object(t[p])||!o.Object(l))throw e(i,"using command $merge with a non object");t[p]=n.shallowMerge(t[p],l);break}if("$push"===c){if(l=r.$push,!o.Array(t[p]))throw e(i,"using command $push to a non array");t[p]=t[p].concat(l)}if("$unshift"===c){if(l=r.$unshift,!o.Array(t[p]))throw e(i,"using command $unshift to a non array");t[p]=[].concat(l).concat(t[p])}}}else for(c in r)t[p][c]="undefined"==typeof t[p][c]?{}:n.shallowClone(t[p][c]),a(t[p],r[c],i.concat(c),t)};return a(t,r),{data:t.root,log:Object.keys(s).map(function(t){return t.split("λ").slice(1)})}}},{"./helpers.js":7,"./type.js":10}]},{},[2])(2)}); \ No newline at end of file diff --git a/src/cursor.js b/src/cursor.js index e3ec8aa..17caabf 100644 --- a/src/cursor.js +++ b/src/cursor.js @@ -234,22 +234,24 @@ Cursor.prototype.set = function(key, val) { }; Cursor.prototype.unset = function(key) { - if (!key && key !== 0) - throw Error('baobab.Cursor.unset: expects a valid key to unset.'); + if (key === undefined) { - if (typeof this.get() !== 'object') - throw Error('baobab.Cursor.set: trying to set key to a non-object.'); + if (this.isRoot()) + throw Error('baobab.Cursor.unset: cannot remove root node.'); - var spec = {}; - spec[key] = {$unset: true}; - return this.update(spec); -}; + return this.update({$unset: true}); + } + else { + var path = [].concat(key), + solvedPath = helpers.solvePath(this.get(), path); -Cursor.prototype.remove = function() { - if (this.isRoot()) - throw Error('baobab.Cursor.remove: cannot remove root node.'); + if (!solvedPath) + throw Error('baobab.Cursor.unset: could not solve dynamic path.'); - return this.update({$unset: true}); + var spec = helpers.pathObject(solvedPath, {$unset: true}); + + return this.update(spec); + } }; Cursor.prototype.apply = function(fn) { diff --git a/src/type.js b/src/type.js index cbfd848..b227ba5 100644 --- a/src/type.js +++ b/src/type.js @@ -52,6 +52,10 @@ type.Date = function (value) { /** * Complex types */ +type.NonScalar = function(value) { + return type.Object(value) || type.Array(value); +}; + type.Path = function (value) { var allowed = ['String', 'Number', 'Function', 'Object']; diff --git a/test/suites/cursor.js b/test/suites/cursor.js index ad31efc..f5bf4e9 100644 --- a/test/suites/cursor.js +++ b/test/suites/cursor.js @@ -223,14 +223,6 @@ describe('Cursor API', function() { }); }); - it('should be possible to remove keys from the tree.', function() { - var tree = new Baobab({one: 1, two: 2}, {asynchronous: false}); - - assert.deepEqual(tree.get(), {one: 1, two: 2}); - tree.unset('one'); - assert.deepEqual(tree.get(), {two: 2}); - }); - it('should be possible to remove keys from a cursor.', function() { var tree = new Baobab({one: 1, two: {subone: 1, subtwo: 2}}, {asynchronous: false}), cursor = tree.select('two'); @@ -245,7 +237,7 @@ describe('Cursor API', function() { cursor = tree.select('two'); assert.deepEqual(cursor.get(), {subone: 1, subtwo: 2}); - cursor.remove(); + cursor.unset(); assert.strictEqual(cursor.get(), undefined); }); }); From cbbc3cb11921e368f425a0173af64deb562bc2d2 Mon Sep 17 00:00:00 2001 From: Yomguithereal Date: Wed, 1 Apr 2015 16:49:56 +0200 Subject: [PATCH 21/73] Building generic polymorphism --- build/baobab.min.js | 2 +- src/cursor.js | 57 +++++++++++++++++++++++++++------------------ 2 files changed, 35 insertions(+), 24 deletions(-) diff --git a/build/baobab.min.js b/build/baobab.min.js index 96a0d6c..e7c43e0 100644 --- a/build/baobab.min.js +++ b/build/baobab.min.js @@ -1,2 +1,2 @@ /* baobab.js - Version: 1.0.0-rc1 - Author: Yomguithereal (Guillaume Plique) */ -!function(t){if("object"==typeof exports&&"undefined"!=typeof module)module.exports=t();else if("function"==typeof define&&define.amd)define([],t);else{var r;r="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:this,r.Baobab=t()}}(function(){var t;return function r(t,e,n){function o(s,a){if(!e[s]){if(!t[s]){var h="function"==typeof require&&require;if(!a&&h)return h(s,!0);if(i)return i(s,!0);var u=new Error("Cannot find module '"+s+"'");throw u.code="MODULE_NOT_FOUND",u}var c=e[s]={exports:{}};t[s][0].call(c.exports,function(r){var e=t[s][1][r];return o(e?e:r)},c,c.exports,r,t,e,n)}return e[s].exports}for(var i="function"==typeof require&&require,s=0;sr;r++)n.push(t[r].handler);return n}var o={once:"boolean",scope:"object"},i=function(){this._enabled=!0,this._children=[],this._handlers={},this._handlersAll=[]};i.prototype.on=function(t,r,e){var n,s,a,h,u,c;if("function"==typeof r){for(u="string"==typeof t?[t]:t,n=0,s=u.length;n!==s;n+=1)if(h=u[n]){this._handlers[h]||(this._handlers[h]=[]),c={handler:r};for(a in e||{}){if(!o[a])throw new Error('The option "'+a+'" is not recognized by Emmett.');c[a]=e[a]}this._handlers[h].push(c)}}else if(t&&"object"==typeof t&&!Array.isArray(t))for(h in t)i.prototype.on.call(this,h,t[h],r);else{if("function"!=typeof t)throw new Error("Wrong arguments.");c={handler:t};for(a in e||{}){if(!o[a])throw new Error('The option "'+a+'" is not recognized by Emmett.');c[a]=e[a]}this._handlersAll.push(c)}return this},i.prototype.once=function(t,r,e){if("function"==typeof r)e=e||{},e.once=!0,this.on(t,r,e);else{if((!t||"object"!=typeof t||Array.isArray(t))&&"function"!=typeof t)throw new Error("Wrong arguments.");r=r||{},r.once=!0,this.on(t,r)}return this},i.prototype.off=function(t,r){var e,n,o,i,s,a,h,u="string"==typeof t?[t]:t;if(1===arguments.length&&"function"==typeof u){r=arguments[0];for(s in this._handlers){for(a=[],e=0,n=this._handlers[s].length;e!==n;e+=1)this._handlers[s][e].handler!==r&&a.push(this._handlers[s][e]);this._handlers[s]=a}for(a=[],e=0,n=this._handlersAll.length;e!==n;e+=1)this._handlersAll[e].handler!==r&&a.push(this._handlersAll[e]);this._handlersAll=a}else if(2===arguments.length)for(e=0,n=u.length;e!==n;e+=1){if(h=u[e],this._handlers[h]){for(a=[],o=0,i=this._handlers[h].length;o!==i;o+=1)this._handlers[h][o].handler!==r&&a.push(this._handlers[h][o]);this._handlers[h]=a}this._handlers[h]&&0===this._handlers[h].length&&delete this._handlers[h]}return this},i.prototype.unbindAll=function(){var t;this._handlersAll=[];for(t in this._handlers)delete this._handlers[t];return this},i.prototype.emit=function(t,r){var e,n,o,i,s,a,h,u,c,l,f="string"==typeof t?[t]:t;if(!this._enabled)return this;for(r=void 0===r?{}:r,e=0,n=f.length;e!==n;e+=1)if(l=f[e],c=(this._handlers[l]||[]).concat(this._handlersAll),c.length){for(h={type:l,data:r||{},target:this},a=[],o=0,i=c.length;o!==i;o+=1)(this._handlers[l]&&this._handlers[l].indexOf(c[o])>=0||this._handlersAll.indexOf(c[o])>=0)&&(c[o].handler.call("scope"in c[o]?c[o].scope:this,h),c[o].once&&a.push(c[o]));for(s=0;se;e++)if(t._children[e]===r){t._children.splice(e,1);break}}),this._children.push(r),r},i.prototype.listeners=function(t){var e,n,o,i=[];if(t)for(i=r(this._handlers[t]),n=0,o=this._children.length;o>n;n++)i=i.concat(this._children[n].listeners(t));else{i=r(this._handlersAll);for(e in this._handlers)i=i.concat(r(this._handlers[e]));for(n=0,o=this._children.length;o>n;n++)i=i.concat(this._children[n].listeners())}return i},i.prototype.kill=function(){if(this.emit("emmett:kill"),this.unbindAll(),this._handlers=null,this._handlersAll=null,this._enabled=!1,this._children)for(var t=0,r=this._children.length;r>t;t++)this._children[t].kill();this._children=null},i.prototype.disable=function(){return this._enabled=!1,this},i.prototype.enable=function(){return this._enabled=!0,this},i.version="2.1.2","undefined"!=typeof n?("undefined"!=typeof e&&e.exports&&(n=e.exports=i),n.Emitter=i):"function"==typeof t&&t.amd?t("emmett",[],function(){return i}):this.Emitter=i}).call(this)},{}],4:[function(t,r){function e(t){return t+"$"+(new Date).getTime()+(""+Math.random()).replace("0.","")}function n(t,r){function e(t){this[t]=function(){var r=this.root[t].apply(this.root,arguments);return r instanceof o?this:r}}if(arguments.length<1&&(t={}),!(this instanceof n))return new n(t,r);if(!l.Object(t)&&!l.Array(t))throw Error("Baobab: invalid data.");i.call(this),this.options=s.shallowMerge(c,r),this._transaction={},this._future=void 0,this._cursors={},this.data=s.deepClone(t),this.root=this.select([]),["get","set","unset","update"].forEach(e.bind(this)),this.mixin=u.baobab(this)}var o=t("./cursor.js"),i=t("emmett"),s=t("./helpers.js"),a=t("./update.js"),h=t("./merge.js"),u=t("./mixins.js"),c=t("../defaults.js"),l=t("./type.js");s.inherits(n,i),n.prototype.select=function(t){if(!t)throw Error("Baobab.select: invalid path.");if(arguments.length>1&&(t=s.arrayOf(arguments)),!l.Path(t))throw Error("Baobab.select: invalid path.");t=[].concat(t);var r,n=l.ComplexPath(t);n&&(r=s.solvePath(this.data,t));var i=t.map(function(t){return l.Function(t)?e("fn"):l.Object(t)?e("ob"):t}).join("λ");if(this._cursors[i])return this._cursors[i];var a=new o(this,t,r,i);return this._cursors[i]=a,a},n.prototype.stack=function(t){var r=this;if(!l.Object(t))throw Error("Baobab.update: wrong specification.");return this._transaction=h(t,this._transaction),this.options.autoCommit?this.options.asynchronous?(this._future||(this._future=setTimeout(r.commit.bind(r,null),0)),this):this.commit():this},n.prototype.commit=function(){var t=a(this.data,this._transaction,this.options);return this.data=t.data,this._transaction={},this._future&&(this._future=clearTimeout(this._future)),this.emit("update",{log:t.log}),this},n.prototype.release=function(){delete this.data,delete this._transaction;for(var t in this._cursors)this._cursors[t].release();delete this._cursors,this.kill()},n.prototype.toJSON=function(){return this.get()},r.exports=n},{"../defaults.js":1,"./cursor.js":6,"./helpers.js":7,"./merge.js":8,"./mixins.js":9,"./type.js":10,"./update.js":11,emmett:3}],5:[function(t,r){function e(t,r){r.on("update",t.cursorListener),t.tree.off("update",t.treeListener),t.tree.on("update",t.treeListener)}function n(t){var r=this;if(arguments.length<2)throw Error("baobab.Combination: not enough arguments.");var n=arguments[1],o=s.arrayOf(arguments).slice(2);if(n instanceof Array&&(o=n.slice(1),n=n[0]),!a.Cursor(n))throw Error("baobab.Combination: argument should be a cursor.");if("or"!==t&&"and"!==t)throw Error("baobab.Combination: invalid operator.");i.call(this),this.cursors=[n],this.operators=[],this.tree=n.tree,this.updates=new Array(this.cursors.length),this.cursorListener=function(){r.updates[r.cursors.indexOf(this)]=!0},this.treeListener=function(){var t,e,n=r.updates[0];for(t=1,e=r.cursors.length;e>t;t++)n="or"===r.operators[t-1]?n||r.updates[t]:n&&r.updates[t];n&&r.emit("update"),r.updates=new Array(r.cursors.length)},this.bound=!1;var h=(this.on,this.once,function(){r.bound||(r.bound=!0,r.cursors.forEach(function(t){e(r,t)}))});this.on=s.before(h,this.on.bind(this)),this.once=s.before(h,this.once.bind(this)),o.forEach(function(r){this[t](r)},this)}function o(t){n.prototype[t]=function(r){if(!a.Cursor(r))throw this.release(),Error("baobab.Combination."+t+": argument should be a cursor.");if(~this.cursors.indexOf(r))throw this.release(),Error("baobab.Combination."+t+": cursor already in combination.");return this.cursors.push(r),this.operators.push(t),this.updates.length++,this.bound&&e(this,r),this}}var i=t("emmett"),s=t("./helpers.js"),a=t("./type.js");s.inherits(n,i),o("or"),o("and"),n.prototype.release=function(){this.cursors.forEach(function(t){t.off("update",this.cursorListener)},this),this.tree.off("update",this.treeListener),this.cursors=null,this.operators=null,this.tree=null,this.updates=null,this.kill()},r.exports=n},{"./helpers.js":7,"./type.js":10,emmett:3}],6:[function(t,r){function e(t,r,e,o){var a=this;n.call(this),r=r||[],this.tree=t,this.path=r,this.hash=o,this.complexPath=!!e,this.solvedPath=this.complexPath?e:this.path,this.relevant=void 0!==this.get(),this.updateHandler=function(t){var r,e,n,o,i,h,u=t.data.log,c=!1;if(a.complexPath&&(a.solvedPath=s.solvePath(a.tree.data,a.path)),!a.path.length)return a.emit("update");t:for(i=0,n=u.length;n>i;i++)for(r=u[i],h=0,o=r.length;o>h&&(e=r[h],e===""+a.solvedPath[h]);h++)if(h+1===o||h+1===a.solvedPath.length){c=!0;break t}var l=void 0!==a.get();a.relevant?l&&c?a.emit("update"):l||(a.emit("irrelevant"),a.relevant=!1):l&&c&&(a.emit("relevant"),a.emit("update"),a.relevant=!0)},this.mixin=i.cursor(this);var h=!1,u=function(){h||(h=!0,a.tree.on("update",a.updateHandler))};this.on=s.before(u,this.on.bind(this)),this.once=s.before(u,this.once.bind(this))}var n=t("emmett"),o=t("./combination.js"),i=t("./mixins.js"),s=t("./helpers.js"),a=t("./type.js");s.inherits(e,n),e.prototype.isRoot=function(){return!this.path.length},e.prototype.isLeaf=function(){return a.Primitive(this.get())},e.prototype.isBranch=function(){return!this.isLeaf()&&!this.isRoot()},e.prototype.root=function(){return this.tree.root()},e.prototype.select=function(t){if(arguments.length>1&&(t=s.arrayOf(arguments)),!a.Path(t))throw Error("baobab.Cursor.select: invalid path.");return this.tree.select(this.path.concat(t))},e.prototype.up=function(){return this.solvedPath&&this.solvedPath.length?this.tree.select(this.path.slice(0,-1)):null},e.prototype.left=function(){var t=+this.solvedPath[this.solvedPath.length-1];if(isNaN(t))throw Error("baobab.Cursor.left: cannot go left on a non-list type.");return t?this.tree.select(this.solvedPath.slice(0,-1).concat(t-1)):null},e.prototype.leftmost=function(){var t=+this.solvedPath[this.solvedPath.length-1];if(isNaN(t))throw Error("baobab.Cursor.leftmost: cannot go left on a non-list type.");return this.tree.select(this.solvedPath.slice(0,-1).concat(0))},e.prototype.right=function(){var t=+this.solvedPath[this.solvedPath.length-1];if(isNaN(t))throw Error("baobab.Cursor.right: cannot go right on a non-list type.");return t+1===this.up().get().length?null:this.tree.select(this.solvedPath.slice(0,-1).concat(t+1))},e.prototype.rightmost=function(){var t=+this.solvedPath[this.solvedPath.length-1];if(isNaN(t))throw Error("baobab.Cursor.right: cannot go right on a non-list type.");var r=this.up().get();return this.tree.select(this.solvedPath.slice(0,-1).concat(r.length-1))},e.prototype.down=function(){+this.solvedPath[this.solvedPath.length-1];return this.get()instanceof Array?this.tree.select(this.solvedPath.concat(0)):null},e.prototype.get=function(t){arguments.length>1&&(t=s.arrayOf(arguments));var r=this.solvedPath.concat((a.String(t)||a.Number(t)?[t]:t)||[]);return s.getIn(this.tree.data,r)},e.prototype.set=function(t,r){arguments.length<2&&(r=t,t=[]);var e=[].concat(t),n=s.solvePath(this.get(),e);if(!n)throw Error("baobab.Cursor.set: could not solve dynamic path.");var o=s.pathObject(n,{$set:r});return this.update(o)},e.prototype.unset=function(t){if(void 0===t){if(this.isRoot())throw Error("baobab.Cursor.unset: cannot remove root node.");return this.update({$unset:!0})}var r=[].concat(t),e=s.solvePath(this.get(),r);if(!e)throw Error("baobab.Cursor.unset: could not solve dynamic path.");var n=s.pathObject(e,{$unset:!0});return this.update(n)},e.prototype.apply=function(t){if("function"!=typeof t)throw Error("baobab.Cursor.apply: argument is not a function.");return this.update({$apply:t})},e.prototype.chain=function(t){if("function"!=typeof t)throw Error("baobab.Cursor.chain: argument is not a function.");return this.update({$chain:t})},e.prototype.push=function(t){if(!(this.get()instanceof Array))throw Error("baobab.Cursor.push: trying to push to non-array value.");return this.update(arguments.length>1?{$push:s.arrayOf(arguments)}:{$push:t})},e.prototype.unshift=function(t){if(!(this.get()instanceof Array))throw Error("baobab.Cursor.push: trying to push to non-array value.");return this.update(arguments.length>1?{$unshift:s.arrayOf(arguments)}:{$unshift:t})},e.prototype.merge=function(t){if(!a.Object(t))throw Error("baobab.Cursor.merge: trying to merge a non-object.");if(!a.Object(this.get()))throw Error("baobab.Cursor.merge: trying to merge into a non-object.");this.update({$merge:t})},e.prototype.update=function(t){return this.tree.stack(s.pathObject(this.solvedPath,t)),this},e.prototype.or=function(t){return new o("or",this,t)},e.prototype.and=function(t){return new o("and",this,t)},e.prototype.release=function(){this.tree.off("update",this.updateHandler),this.hash&&delete this.tree._cursors[this.hash],delete this.tree,delete this.path,delete this.solvedPath,this.kill()},e.prototype.toJSON=function(){return this.get()},a.Cursor=function(t){return t instanceof e},r.exports=e},{"./combination.js":5,"./helpers.js":7,"./mixins.js":9,"./type.js":10,emmett:3}],7:[function(t,r){function e(t){return Array.prototype.slice.call(t)}function n(t,r){return function(){t(),r.apply(null,arguments)}}function o(t,r){var e,n={};for(e in t)n[e]=t[e];for(e in r)n[e]=r[e];return n}function i(t){var r=t.source,e="";return t.global&&(e+="g"),t.multiline&&(e+="m"),t.ignoreCase&&(e+="i"),t.sticky&&(e+="y"),t.unicode&&(e+="u"),new RegExp(r,e)}function s(t,r){if(!r||"object"!=typeof r||r instanceof Error||r instanceof ArrayBuffer)return r;if(g.Array(r)){if(t){var e,n,o=[];for(e=0,n=r.length;n>e;e++)o.push(_(r[e]));return o}return r.slice(0)}if(g.Date(r))return new Date(r.getTime());if(r instanceof RegExp)return i(r);if(g.Object(r)){var s,a={};r.constructor&&r.constructor!==Object&&(a=Object.create(r.constructor.prototype));for(s in r)r.hasOwnProperty(s)&&(a[s]=t?_(r[s]):r[s]);return a}return r}function a(t,r){return function(e){return r(t(e))}}function h(t,r){var e,n;for(e=0,n=t.length;n>e;e++)if(r(t[e]))return t[e]}function u(t,r){var e,n;for(e=0,n=t.length;n>e;e++)if(r(t[e]))return e;return-1}function c(t,r){var e,n=!0;if(!t)return!1;for(e in r)if(g.Object(r[e]))n=n&&c(t[e],r[e]);else if(g.Array(r[e]))n=n&&!!~r[e].indexOf(t[e]);else if(t[e]!==r[e])return!1;return n}function l(t,r){return h(t,function(t){return c(t,r)})}function f(t,r){return u(t,function(t){return c(t,r)})}function p(t,r){r=r||[];var e,n,o=t;for(e=0,n=r.length;n>e;e++){if(!o)return;if("function"==typeof r[e]){if(!g.Array(o))return;o=h(o,r[e])}else if("object"==typeof r[e]){if(!g.Array(o))return;o=l(o,r[e])}else o=o[r[e]]}return o}function d(t,r){var e,n,o,i=[],s=t;for(n=0,o=r.length;o>n;n++){if(!s)return null;if("function"==typeof r[n]){if(!g.Array(s))return;e=u(s,r[n]),i.push(e),s=s[e]}else if("object"==typeof r[n]){if(!g.Array(s))return;e=f(s,r[n]),i.push(e),s=s[e]}else i.push(r[n]),s=s[r[n]]||{}}return i}function b(t,r){var e,n=t.length,o={},i=o;for(n||(o=r),e=0;n>e;e++)i[t[e]]=e+1===n?r:{},i=i[t[e]];return o}function y(t,r){t.super_=r;var e=function(){};e.prototype=r.prototype,t.prototype=new e,t.prototype.constructor=t}var g=t("./type.js"),m=s.bind(null,!1),_=s.bind(null,!0);r.exports={arrayOf:e,before:n,deepClone:_,shallowClone:m,shallowMerge:o,compose:a,getIn:p,inherits:y,pathObject:b,solvePath:d}},{"./type.js":10}],8:[function(t,r){function e(t,r,e){s.forEach(function(r){e!==r&&delete t[r]}),t[e]=r[e]}function n(t,r){var a,h=o.shallowClone(r||{});s.forEach(function(r){t[r]&&e(h,t,r)}),t.$chain&&(s.slice(0,-1).forEach(function(t){delete h[t]}),h.$apply=h.$apply?o.compose(h.$apply,t.$chain):t.$chain),t.$push&&h.$push?h.$push=i.Array(h.$push)?h.$push.concat(t.$push):[h.$push].concat(t.$push):t.$push&&(h.$push=t.$push),t.$unshift&&h.$unshift?h.$unshift=i.Array(t.$unshift)?t.$unshift.concat(h.$unshift):[t.$unshift].concat(h.$unshift):t.$unshift&&(h.$unshift=t.$unshift);for(a in t)i.Object(t[a])?h[a]=n(t[a],h[a]):"$"!==a[0]&&(h[a]=t[a]);return h}var o=t("./helpers.js"),i=t("./type.js"),s=["$unset","$set","$merge","$apply"];r.exports=n},{"./helpers.js":7,"./type.js":10}],9:[function(t,r){var e=t("./combination.js"),n=t("./type.js");r.exports={baobab:function(t){return{mixins:[{getInitialState:function(){if(this.tree=t,!this.cursor&&!this.cursors)return{};if(this.cursor&&this.cursors)throw Error("baobab.mixin: you cannot have both `component.cursor` and `component.cursors`. Please make up your mind.");if(this.__type=null,this.__updateHandler=function(){this.setState(this.__getCursorData())}.bind(this),this.cursor){if(!n.MixinCursor(this.cursor))throw Error("baobab.mixin.cursor: invalid data (cursor, string, array or function).");n.Function(this.cursor)&&(this.cursor=this.cursor()),n.Cursor(this.cursor)||(this.cursor=t.select(this.cursor)),this.__getCursorData=function(){return{cursor:this.cursor.get()}}.bind(this),this.__type="single"}else if(this.cursors){if(!n.MixinCursors(this.cursors))throw Error("baobab.mixin.cursor: invalid data (object, array or function).");if(n.Function(this.cursors)&&(this.cursors=this.cursors()),n.Array(this.cursors))this.cursors=this.cursors.map(function(r){return n.Cursor(r)?r:t.select(r)}),this.__getCursorData=function(){return{cursors:this.cursors.map(function(t){return t.get()})}}.bind(this),this.__type="array";else{for(var r in this.cursors)n.Cursor(this.cursors[r])||(this.cursors[r]=t.select(this.cursors[r]));this.__getCursorData=function(){var t={};for(r in this.cursors)t[r]=this.cursors[r].get();return{cursors:t}}.bind(this),this.__type="object"}}return this.__getCursorData()},componentDidMount:function(){"single"===this.__type?(this.__combination=new e("or",[this.cursor]),this.__combination.on("update",this.__updateHandler)):"array"===this.__type?(this.__combination=new e("or",this.cursors),this.__combination.on("update",this.__updateHandler)):"object"===this.__type&&(this.__combination=new e("or",Object.keys(this.cursors).map(function(t){return this.cursors[t]},this)),this.__combination.on("update",this.__updateHandler))},componentWillUnmount:function(){this.__combination&&this.__combination.release()}}].concat(t.options.mixins)}},cursor:function(t){return{mixins:[{getInitialState:function(){return this.cursor=t,this.__updateHandler=function(){this.setState({cursor:this.cursor.get()})}.bind(this),{cursor:this.cursor.get()}},componentDidMount:function(){this.cursor.on("update",this.__updateHandler)},componentWillUnmount:function(){this.cursor.off("update",this.__updateHandler)}}].concat(t.tree.options.mixins)}}}},{"./combination.js":5,"./type.js":10}],10:[function(t,r){function e(t,r){return r.some(function(r){return n[r](t)})}var n={};n.Array=function(t){return Array.isArray(t)},n.Object=function(t){return!Array.isArray(t)&&"object"==typeof t&&null!==t},n.String=function(t){return"string"==typeof t},n.Number=function(t){return"number"==typeof t},n.Function=function(t){return"function"==typeof t},n.Primitive=function(t){return"string"==typeof t||"number"==typeof t||"boolean"==typeof t},n.Date=function(t){return t instanceof Date},n.NonScalar=function(t){return n.Object(t)||n.Array(t)},n.Path=function(t){var r=["String","Number","Function","Object"];return n.Array(t)?t.every(function(t){return e(t,r)}):e(t,r)},n.MixinCursor=function(t){return e(t,["String","Number","Array","Function","Cursor"])},n.MixinCursors=function(t){return e(t,["Object","Array","Function"])},n.ComplexPath=function(t){return e(t,["Object","Function"])},r.exports=n},{}],11:[function(t,r){function e(t,r){var e=new Error("baobab.update: "+r+" at path /"+t.slice(1).toString());return e.path=t,e}var n=t("./helpers.js"),o=t("./type.js");r.exports=function(t,r,i){if(i=i||{},!o.Object(t)&&!o.Array(t))throw Error("baobab.update: invalid target.");var s={};t={root:n.shallowClone(t)};var a=function(t,r,i,h){i=i||["root"];var u,c,l,f=i.join("λ"),p=i[i.length-1],d=Object.keys(r).some(function(t){return!!~["$unset","$set","$apply","$merge","$push","$unshift"].indexOf(t)});if(d){s[f]=!0;for(c in r){if("$unset"===c){var b=i[i.length-2];o.Array(t)?h[b]=t.slice(0,+p).concat(t.slice(+p+1)):(h[b]=n.shallowClone(t),delete h[b][p]);break}if("$set"===c){l=r.$set,t[p]=l;break}if("$apply"===c){if(u=r.$apply,"function"!=typeof u)throw e(i,"using command $apply with a non function");t[p]=u.call(null,t[p]);break}if("$merge"===c){if(l=r.$merge,!o.Object(t[p])||!o.Object(l))throw e(i,"using command $merge with a non object");t[p]=n.shallowMerge(t[p],l);break}if("$push"===c){if(l=r.$push,!o.Array(t[p]))throw e(i,"using command $push to a non array");t[p]=t[p].concat(l)}if("$unshift"===c){if(l=r.$unshift,!o.Array(t[p]))throw e(i,"using command $unshift to a non array");t[p]=[].concat(l).concat(t[p])}}}else for(c in r)t[p][c]="undefined"==typeof t[p][c]?{}:n.shallowClone(t[p][c]),a(t[p],r[c],i.concat(c),t)};return a(t,r),{data:t.root,log:Object.keys(s).map(function(t){return t.split("λ").slice(1)})}}},{"./helpers.js":7,"./type.js":10}]},{},[2])(2)}); \ No newline at end of file +!function(t){if("object"==typeof exports&&"undefined"!=typeof module)module.exports=t();else if("function"==typeof define&&define.amd)define([],t);else{var r;r="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:this,r.Baobab=t()}}(function(){var t;return function r(t,e,n){function o(s,a){if(!e[s]){if(!t[s]){var h="function"==typeof require&&require;if(!a&&h)return h(s,!0);if(i)return i(s,!0);var u=new Error("Cannot find module '"+s+"'");throw u.code="MODULE_NOT_FOUND",u}var c=e[s]={exports:{}};t[s][0].call(c.exports,function(r){var e=t[s][1][r];return o(e?e:r)},c,c.exports,r,t,e,n)}return e[s].exports}for(var i="function"==typeof require&&require,s=0;sr;r++)n.push(t[r].handler);return n}var o={once:"boolean",scope:"object"},i=function(){this._enabled=!0,this._children=[],this._handlers={},this._handlersAll=[]};i.prototype.on=function(t,r,e){var n,s,a,h,u,c;if("function"==typeof r){for(u="string"==typeof t?[t]:t,n=0,s=u.length;n!==s;n+=1)if(h=u[n]){this._handlers[h]||(this._handlers[h]=[]),c={handler:r};for(a in e||{}){if(!o[a])throw new Error('The option "'+a+'" is not recognized by Emmett.');c[a]=e[a]}this._handlers[h].push(c)}}else if(t&&"object"==typeof t&&!Array.isArray(t))for(h in t)i.prototype.on.call(this,h,t[h],r);else{if("function"!=typeof t)throw new Error("Wrong arguments.");c={handler:t};for(a in e||{}){if(!o[a])throw new Error('The option "'+a+'" is not recognized by Emmett.');c[a]=e[a]}this._handlersAll.push(c)}return this},i.prototype.once=function(t,r,e){if("function"==typeof r)e=e||{},e.once=!0,this.on(t,r,e);else{if((!t||"object"!=typeof t||Array.isArray(t))&&"function"!=typeof t)throw new Error("Wrong arguments.");r=r||{},r.once=!0,this.on(t,r)}return this},i.prototype.off=function(t,r){var e,n,o,i,s,a,h,u="string"==typeof t?[t]:t;if(1===arguments.length&&"function"==typeof u){r=arguments[0];for(s in this._handlers){for(a=[],e=0,n=this._handlers[s].length;e!==n;e+=1)this._handlers[s][e].handler!==r&&a.push(this._handlers[s][e]);this._handlers[s]=a}for(a=[],e=0,n=this._handlersAll.length;e!==n;e+=1)this._handlersAll[e].handler!==r&&a.push(this._handlersAll[e]);this._handlersAll=a}else if(2===arguments.length)for(e=0,n=u.length;e!==n;e+=1){if(h=u[e],this._handlers[h]){for(a=[],o=0,i=this._handlers[h].length;o!==i;o+=1)this._handlers[h][o].handler!==r&&a.push(this._handlers[h][o]);this._handlers[h]=a}this._handlers[h]&&0===this._handlers[h].length&&delete this._handlers[h]}return this},i.prototype.unbindAll=function(){var t;this._handlersAll=[];for(t in this._handlers)delete this._handlers[t];return this},i.prototype.emit=function(t,r){var e,n,o,i,s,a,h,u,c,l,f="string"==typeof t?[t]:t;if(!this._enabled)return this;for(r=void 0===r?{}:r,e=0,n=f.length;e!==n;e+=1)if(l=f[e],c=(this._handlers[l]||[]).concat(this._handlersAll),c.length){for(h={type:l,data:r||{},target:this},a=[],o=0,i=c.length;o!==i;o+=1)(this._handlers[l]&&this._handlers[l].indexOf(c[o])>=0||this._handlersAll.indexOf(c[o])>=0)&&(c[o].handler.call("scope"in c[o]?c[o].scope:this,h),c[o].once&&a.push(c[o]));for(s=0;se;e++)if(t._children[e]===r){t._children.splice(e,1);break}}),this._children.push(r),r},i.prototype.listeners=function(t){var e,n,o,i=[];if(t)for(i=r(this._handlers[t]),n=0,o=this._children.length;o>n;n++)i=i.concat(this._children[n].listeners(t));else{i=r(this._handlersAll);for(e in this._handlers)i=i.concat(r(this._handlers[e]));for(n=0,o=this._children.length;o>n;n++)i=i.concat(this._children[n].listeners())}return i},i.prototype.kill=function(){if(this.emit("emmett:kill"),this.unbindAll(),this._handlers=null,this._handlersAll=null,this._enabled=!1,this._children)for(var t=0,r=this._children.length;r>t;t++)this._children[t].kill();this._children=null},i.prototype.disable=function(){return this._enabled=!1,this},i.prototype.enable=function(){return this._enabled=!0,this},i.version="2.1.2","undefined"!=typeof n?("undefined"!=typeof e&&e.exports&&(n=e.exports=i),n.Emitter=i):"function"==typeof t&&t.amd?t("emmett",[],function(){return i}):this.Emitter=i}).call(this)},{}],4:[function(t,r){function e(t){return t+"$"+(new Date).getTime()+(""+Math.random()).replace("0.","")}function n(t,r){function e(t){this[t]=function(){var r=this.root[t].apply(this.root,arguments);return r instanceof o?this:r}}if(arguments.length<1&&(t={}),!(this instanceof n))return new n(t,r);if(!l.Object(t)&&!l.Array(t))throw Error("Baobab: invalid data.");i.call(this),this.options=s.shallowMerge(c,r),this._transaction={},this._future=void 0,this._cursors={},this.data=s.deepClone(t),this.root=this.select([]),["get","set","unset","update"].forEach(e.bind(this)),this.mixin=u.baobab(this)}var o=t("./cursor.js"),i=t("emmett"),s=t("./helpers.js"),a=t("./update.js"),h=t("./merge.js"),u=t("./mixins.js"),c=t("../defaults.js"),l=t("./type.js");s.inherits(n,i),n.prototype.select=function(t){if(!t)throw Error("Baobab.select: invalid path.");if(arguments.length>1&&(t=s.arrayOf(arguments)),!l.Path(t))throw Error("Baobab.select: invalid path.");t=[].concat(t);var r,n=l.ComplexPath(t);n&&(r=s.solvePath(this.data,t));var i=t.map(function(t){return l.Function(t)?e("fn"):l.Object(t)?e("ob"):t}).join("λ");if(this._cursors[i])return this._cursors[i];var a=new o(this,t,r,i);return this._cursors[i]=a,a},n.prototype.stack=function(t){var r=this;if(!l.Object(t))throw Error("Baobab.update: wrong specification.");return this._transaction=h(t,this._transaction),this.options.autoCommit?this.options.asynchronous?(this._future||(this._future=setTimeout(r.commit.bind(r,null),0)),this):this.commit():this},n.prototype.commit=function(){var t=a(this.data,this._transaction,this.options);return this.data=t.data,this._transaction={},this._future&&(this._future=clearTimeout(this._future)),this.emit("update",{log:t.log}),this},n.prototype.release=function(){delete this.data,delete this._transaction;for(var t in this._cursors)this._cursors[t].release();delete this._cursors,this.kill()},n.prototype.toJSON=function(){return this.get()},r.exports=n},{"../defaults.js":1,"./cursor.js":6,"./helpers.js":7,"./merge.js":8,"./mixins.js":9,"./type.js":10,"./update.js":11,emmett:3}],5:[function(t,r){function e(t,r){r.on("update",t.cursorListener),t.tree.off("update",t.treeListener),t.tree.on("update",t.treeListener)}function n(t){var r=this;if(arguments.length<2)throw Error("baobab.Combination: not enough arguments.");var n=arguments[1],o=s.arrayOf(arguments).slice(2);if(n instanceof Array&&(o=n.slice(1),n=n[0]),!a.Cursor(n))throw Error("baobab.Combination: argument should be a cursor.");if("or"!==t&&"and"!==t)throw Error("baobab.Combination: invalid operator.");i.call(this),this.cursors=[n],this.operators=[],this.tree=n.tree,this.updates=new Array(this.cursors.length),this.cursorListener=function(){r.updates[r.cursors.indexOf(this)]=!0},this.treeListener=function(){var t,e,n=r.updates[0];for(t=1,e=r.cursors.length;e>t;t++)n="or"===r.operators[t-1]?n||r.updates[t]:n&&r.updates[t];n&&r.emit("update"),r.updates=new Array(r.cursors.length)},this.bound=!1;var h=(this.on,this.once,function(){r.bound||(r.bound=!0,r.cursors.forEach(function(t){e(r,t)}))});this.on=s.before(h,this.on.bind(this)),this.once=s.before(h,this.once.bind(this)),o.forEach(function(r){this[t](r)},this)}function o(t){n.prototype[t]=function(r){if(!a.Cursor(r))throw this.release(),Error("baobab.Combination."+t+": argument should be a cursor.");if(~this.cursors.indexOf(r))throw this.release(),Error("baobab.Combination."+t+": cursor already in combination.");return this.cursors.push(r),this.operators.push(t),this.updates.length++,this.bound&&e(this,r),this}}var i=t("emmett"),s=t("./helpers.js"),a=t("./type.js");s.inherits(n,i),o("or"),o("and"),n.prototype.release=function(){this.cursors.forEach(function(t){t.off("update",this.cursorListener)},this),this.tree.off("update",this.treeListener),this.cursors=null,this.operators=null,this.tree=null,this.updates=null,this.kill()},r.exports=n},{"./helpers.js":7,"./type.js":10,emmett:3}],6:[function(t,r){function e(t,r,e,n){var i=this;o.call(this),r=r||[],this.tree=t,this.path=r,this.hash=n,this.complexPath=!!e,this.solvedPath=this.complexPath?e:this.path,this.relevant=void 0!==this.get(),this.updateHandler=function(t){var r,e,n,o,s,h,u=t.data.log,c=!1;if(i.complexPath&&(i.solvedPath=a.solvePath(i.tree.data,i.path)),!i.path.length)return i.emit("update");t:for(s=0,n=u.length;n>s;s++)for(r=u[s],h=0,o=r.length;o>h&&(e=r[h],e===""+i.solvedPath[h]);h++)if(h+1===o||h+1===i.solvedPath.length){c=!0;break t}var l=void 0!==i.get();i.relevant?l&&c?i.emit("update"):l||(i.emit("irrelevant"),i.relevant=!1):l&&c&&(i.emit("relevant"),i.emit("update"),i.relevant=!0)},this.mixin=s.cursor(this);var h=!1,u=function(){h||(h=!0,i.tree.on("update",i.updateHandler))};this.on=a.before(u,this.on.bind(this)),this.once=a.before(u,this.once.bind(this))}function n(t,r,e){arguments.length<3&&(e=r,r=[]),r=r||[];var n=[].concat(r),o=a.solvePath(this.get(),n);if(!o)throw Error("baobab.Cursor."+t+": could not solve dynamic path.");var i={};i["$"+t]=e;var s=a.pathObject(o,i);return s}var o=t("emmett"),i=t("./combination.js"),s=t("./mixins.js"),a=t("./helpers.js"),h=t("./type.js");a.inherits(e,o),e.prototype.isRoot=function(){return!this.path.length},e.prototype.isLeaf=function(){return h.Primitive(this.get())},e.prototype.isBranch=function(){return!this.isLeaf()&&!this.isRoot()},e.prototype.root=function(){return this.tree.root()},e.prototype.select=function(t){if(arguments.length>1&&(t=a.arrayOf(arguments)),!h.Path(t))throw Error("baobab.Cursor.select: invalid path.");return this.tree.select(this.path.concat(t))},e.prototype.up=function(){return this.solvedPath&&this.solvedPath.length?this.tree.select(this.path.slice(0,-1)):null},e.prototype.left=function(){var t=+this.solvedPath[this.solvedPath.length-1];if(isNaN(t))throw Error("baobab.Cursor.left: cannot go left on a non-list type.");return t?this.tree.select(this.solvedPath.slice(0,-1).concat(t-1)):null},e.prototype.leftmost=function(){var t=+this.solvedPath[this.solvedPath.length-1];if(isNaN(t))throw Error("baobab.Cursor.leftmost: cannot go left on a non-list type.");return this.tree.select(this.solvedPath.slice(0,-1).concat(0))},e.prototype.right=function(){var t=+this.solvedPath[this.solvedPath.length-1];if(isNaN(t))throw Error("baobab.Cursor.right: cannot go right on a non-list type.");return t+1===this.up().get().length?null:this.tree.select(this.solvedPath.slice(0,-1).concat(t+1))},e.prototype.rightmost=function(){var t=+this.solvedPath[this.solvedPath.length-1];if(isNaN(t))throw Error("baobab.Cursor.right: cannot go right on a non-list type.");var r=this.up().get();return this.tree.select(this.solvedPath.slice(0,-1).concat(r.length-1))},e.prototype.down=function(){+this.solvedPath[this.solvedPath.length-1];return this.get()instanceof Array?this.tree.select(this.solvedPath.concat(0)):null},e.prototype.get=function(t){arguments.length>1&&(t=a.arrayOf(arguments));var r=this.solvedPath.concat((h.String(t)||h.Number(t)?[t]:t)||[]);return a.getIn(this.tree.data,r)},e.prototype.set=function(){var t=n.bind(this,"set").apply(this,arguments);return this.update(t)},e.prototype.unset=function(t){if(void 0===t&&this.isRoot())throw Error("baobab.Cursor.unset: cannot remove root node.");var r=n.bind(this,"unset").apply(this,[t,!0]);return this.update(r)},e.prototype.apply=function(t){if("function"!=typeof t)throw Error("baobab.Cursor.apply: argument is not a function.");return this.update({$apply:t})},e.prototype.chain=function(t){if("function"!=typeof t)throw Error("baobab.Cursor.chain: argument is not a function.");return this.update({$chain:t})},e.prototype.push=function(t){if(!(this.get()instanceof Array))throw Error("baobab.Cursor.push: trying to push to non-array value.");return this.update(arguments.length>1?{$push:a.arrayOf(arguments)}:{$push:t})},e.prototype.unshift=function(t){if(!(this.get()instanceof Array))throw Error("baobab.Cursor.push: trying to push to non-array value.");return this.update(arguments.length>1?{$unshift:a.arrayOf(arguments)}:{$unshift:t})},e.prototype.merge=function(t){if(!h.Object(t))throw Error("baobab.Cursor.merge: trying to merge a non-object.");if(!h.Object(this.get()))throw Error("baobab.Cursor.merge: trying to merge into a non-object.");this.update({$merge:t})},e.prototype.update=function(t,r){if(arguments.length<2)return this.tree.stack(a.pathObject(this.solvedPath,t)),this;var e=[].concat(t),n=a.solvePath(this.get(),e);if(!n)throw Error("baobab.Cursor.update: could not solve dynamic path.");return this.tree.stack(a.pathObject(this.solvedPath.concat(n),r)),this},e.prototype.or=function(t){return new i("or",this,t)},e.prototype.and=function(t){return new i("and",this,t)},e.prototype.release=function(){this.tree.off("update",this.updateHandler),this.hash&&delete this.tree._cursors[this.hash],delete this.tree,delete this.path,delete this.solvedPath,this.kill()},e.prototype.toJSON=function(){return this.get()},h.Cursor=function(t){return t instanceof e},r.exports=e},{"./combination.js":5,"./helpers.js":7,"./mixins.js":9,"./type.js":10,emmett:3}],7:[function(t,r){function e(t){return Array.prototype.slice.call(t)}function n(t,r){return function(){t(),r.apply(null,arguments)}}function o(t,r){var e,n={};for(e in t)n[e]=t[e];for(e in r)n[e]=r[e];return n}function i(t){var r=t.source,e="";return t.global&&(e+="g"),t.multiline&&(e+="m"),t.ignoreCase&&(e+="i"),t.sticky&&(e+="y"),t.unicode&&(e+="u"),new RegExp(r,e)}function s(t,r){if(!r||"object"!=typeof r||r instanceof Error||r instanceof ArrayBuffer)return r;if(g.Array(r)){if(t){var e,n,o=[];for(e=0,n=r.length;n>e;e++)o.push(_(r[e]));return o}return r.slice(0)}if(g.Date(r))return new Date(r.getTime());if(r instanceof RegExp)return i(r);if(g.Object(r)){var s,a={};r.constructor&&r.constructor!==Object&&(a=Object.create(r.constructor.prototype));for(s in r)r.hasOwnProperty(s)&&(a[s]=t?_(r[s]):r[s]);return a}return r}function a(t,r){return function(e){return r(t(e))}}function h(t,r){var e,n;for(e=0,n=t.length;n>e;e++)if(r(t[e]))return t[e]}function u(t,r){var e,n;for(e=0,n=t.length;n>e;e++)if(r(t[e]))return e;return-1}function c(t,r){var e,n=!0;if(!t)return!1;for(e in r)if(g.Object(r[e]))n=n&&c(t[e],r[e]);else if(g.Array(r[e]))n=n&&!!~r[e].indexOf(t[e]);else if(t[e]!==r[e])return!1;return n}function l(t,r){return h(t,function(t){return c(t,r)})}function f(t,r){return u(t,function(t){return c(t,r)})}function p(t,r){r=r||[];var e,n,o=t;for(e=0,n=r.length;n>e;e++){if(!o)return;if("function"==typeof r[e]){if(!g.Array(o))return;o=h(o,r[e])}else if("object"==typeof r[e]){if(!g.Array(o))return;o=l(o,r[e])}else o=o[r[e]]}return o}function d(t,r){var e,n,o,i=[],s=t;for(n=0,o=r.length;o>n;n++){if(!s)return null;if("function"==typeof r[n]){if(!g.Array(s))return;e=u(s,r[n]),i.push(e),s=s[e]}else if("object"==typeof r[n]){if(!g.Array(s))return;e=f(s,r[n]),i.push(e),s=s[e]}else i.push(r[n]),s=s[r[n]]||{}}return i}function b(t,r){var e,n=t.length,o={},i=o;for(n||(o=r),e=0;n>e;e++)i[t[e]]=e+1===n?r:{},i=i[t[e]];return o}function y(t,r){t.super_=r;var e=function(){};e.prototype=r.prototype,t.prototype=new e,t.prototype.constructor=t}var g=t("./type.js"),m=s.bind(null,!1),_=s.bind(null,!0);r.exports={arrayOf:e,before:n,deepClone:_,shallowClone:m,shallowMerge:o,compose:a,getIn:p,inherits:y,pathObject:b,solvePath:d}},{"./type.js":10}],8:[function(t,r){function e(t,r,e){s.forEach(function(r){e!==r&&delete t[r]}),t[e]=r[e]}function n(t,r){var a,h=o.shallowClone(r||{});s.forEach(function(r){t[r]&&e(h,t,r)}),t.$chain&&(s.slice(0,-1).forEach(function(t){delete h[t]}),h.$apply=h.$apply?o.compose(h.$apply,t.$chain):t.$chain),t.$push&&h.$push?h.$push=i.Array(h.$push)?h.$push.concat(t.$push):[h.$push].concat(t.$push):t.$push&&(h.$push=t.$push),t.$unshift&&h.$unshift?h.$unshift=i.Array(t.$unshift)?t.$unshift.concat(h.$unshift):[t.$unshift].concat(h.$unshift):t.$unshift&&(h.$unshift=t.$unshift);for(a in t)i.Object(t[a])?h[a]=n(t[a],h[a]):"$"!==a[0]&&(h[a]=t[a]);return h}var o=t("./helpers.js"),i=t("./type.js"),s=["$unset","$set","$merge","$apply"];r.exports=n},{"./helpers.js":7,"./type.js":10}],9:[function(t,r){var e=t("./combination.js"),n=t("./type.js");r.exports={baobab:function(t){return{mixins:[{getInitialState:function(){if(this.tree=t,!this.cursor&&!this.cursors)return{};if(this.cursor&&this.cursors)throw Error("baobab.mixin: you cannot have both `component.cursor` and `component.cursors`. Please make up your mind.");if(this.__type=null,this.__updateHandler=function(){this.setState(this.__getCursorData())}.bind(this),this.cursor){if(!n.MixinCursor(this.cursor))throw Error("baobab.mixin.cursor: invalid data (cursor, string, array or function).");n.Function(this.cursor)&&(this.cursor=this.cursor()),n.Cursor(this.cursor)||(this.cursor=t.select(this.cursor)),this.__getCursorData=function(){return{cursor:this.cursor.get()}}.bind(this),this.__type="single"}else if(this.cursors){if(!n.MixinCursors(this.cursors))throw Error("baobab.mixin.cursor: invalid data (object, array or function).");if(n.Function(this.cursors)&&(this.cursors=this.cursors()),n.Array(this.cursors))this.cursors=this.cursors.map(function(r){return n.Cursor(r)?r:t.select(r)}),this.__getCursorData=function(){return{cursors:this.cursors.map(function(t){return t.get()})}}.bind(this),this.__type="array";else{for(var r in this.cursors)n.Cursor(this.cursors[r])||(this.cursors[r]=t.select(this.cursors[r]));this.__getCursorData=function(){var t={};for(r in this.cursors)t[r]=this.cursors[r].get();return{cursors:t}}.bind(this),this.__type="object"}}return this.__getCursorData()},componentDidMount:function(){"single"===this.__type?(this.__combination=new e("or",[this.cursor]),this.__combination.on("update",this.__updateHandler)):"array"===this.__type?(this.__combination=new e("or",this.cursors),this.__combination.on("update",this.__updateHandler)):"object"===this.__type&&(this.__combination=new e("or",Object.keys(this.cursors).map(function(t){return this.cursors[t]},this)),this.__combination.on("update",this.__updateHandler))},componentWillUnmount:function(){this.__combination&&this.__combination.release()}}].concat(t.options.mixins)}},cursor:function(t){return{mixins:[{getInitialState:function(){return this.cursor=t,this.__updateHandler=function(){this.setState({cursor:this.cursor.get()})}.bind(this),{cursor:this.cursor.get()}},componentDidMount:function(){this.cursor.on("update",this.__updateHandler)},componentWillUnmount:function(){this.cursor.off("update",this.__updateHandler)}}].concat(t.tree.options.mixins)}}}},{"./combination.js":5,"./type.js":10}],10:[function(t,r){function e(t,r){return r.some(function(r){return n[r](t)})}var n={};n.Array=function(t){return Array.isArray(t)},n.Object=function(t){return!Array.isArray(t)&&"object"==typeof t&&null!==t},n.String=function(t){return"string"==typeof t},n.Number=function(t){return"number"==typeof t},n.Function=function(t){return"function"==typeof t},n.Primitive=function(t){return"string"==typeof t||"number"==typeof t||"boolean"==typeof t},n.Date=function(t){return t instanceof Date},n.NonScalar=function(t){return n.Object(t)||n.Array(t)},n.Path=function(t){var r=["String","Number","Function","Object"];return n.Array(t)?t.every(function(t){return e(t,r)}):e(t,r)},n.MixinCursor=function(t){return e(t,["String","Number","Array","Function","Cursor"])},n.MixinCursors=function(t){return e(t,["Object","Array","Function"])},n.ComplexPath=function(t){return e(t,["Object","Function"])},r.exports=n},{}],11:[function(t,r){function e(t,r){var e=new Error("baobab.update: "+r+" at path /"+t.slice(1).toString());return e.path=t,e}var n=t("./helpers.js"),o=t("./type.js");r.exports=function(t,r,i){if(i=i||{},!o.Object(t)&&!o.Array(t))throw Error("baobab.update: invalid target.");var s={};t={root:n.shallowClone(t)};var a=function(t,r,i,h){i=i||["root"];var u,c,l,f=i.join("λ"),p=i[i.length-1],d=Object.keys(r).some(function(t){return!!~["$unset","$set","$apply","$merge","$push","$unshift"].indexOf(t)});if(d){s[f]=!0;for(c in r){if("$unset"===c){var b=i[i.length-2];o.Array(t)?h[b]=t.slice(0,+p).concat(t.slice(+p+1)):(h[b]=n.shallowClone(t),delete h[b][p]);break}if("$set"===c){l=r.$set,t[p]=l;break}if("$apply"===c){if(u=r.$apply,"function"!=typeof u)throw e(i,"using command $apply with a non function");t[p]=u.call(null,t[p]);break}if("$merge"===c){if(l=r.$merge,!o.Object(t[p])||!o.Object(l))throw e(i,"using command $merge with a non object");t[p]=n.shallowMerge(t[p],l);break}if("$push"===c){if(l=r.$push,!o.Array(t[p]))throw e(i,"using command $push to a non array");t[p]=t[p].concat(l)}if("$unshift"===c){if(l=r.$unshift,!o.Array(t[p]))throw e(i,"using command $unshift to a non array");t[p]=[].concat(l).concat(t[p])}}}else for(c in r)t[p][c]="undefined"==typeof t[p][c]?{}:n.shallowClone(t[p][c]),a(t[p],r[c],i.concat(c),t)};return a(t,r),{data:t.root,log:Object.keys(s).map(function(t){return t.split("λ").slice(1)})}}},{"./helpers.js":7,"./type.js":10}]},{},[2])(2)}); \ No newline at end of file diff --git a/src/cursor.js b/src/cursor.js index 17caabf..99aa94f 100644 --- a/src/cursor.js +++ b/src/cursor.js @@ -215,43 +215,41 @@ Cursor.prototype.get = function(path) { /** * Update */ -Cursor.prototype.set = function(key, val) { - if (arguments.length < 2) { +function pathPolymorphism(method, key, val) { + if (arguments.length < 3) { val = key; key = []; } - // Solving path + key = key || []; + var path = [].concat(key), solvedPath = helpers.solvePath(this.get(), path); if (!solvedPath) - throw Error('baobab.Cursor.set: could not solve dynamic path.'); + throw Error('baobab.Cursor.' + method + ': could not solve dynamic path.'); - var spec = helpers.pathObject(solvedPath, {$set: val}); + var leaf = {}; + leaf['$' + method] = val; - return this.update(spec); -}; + var spec = helpers.pathObject(solvedPath, leaf); -Cursor.prototype.unset = function(key) { - if (key === undefined) { + return spec; +} - if (this.isRoot()) - throw Error('baobab.Cursor.unset: cannot remove root node.'); +Cursor.prototype.set = function(key, val) { + var spec = pathPolymorphism.bind(this, 'set').apply(this, arguments); - return this.update({$unset: true}); - } - else { - var path = [].concat(key), - solvedPath = helpers.solvePath(this.get(), path); + return this.update(spec); +}; - if (!solvedPath) - throw Error('baobab.Cursor.unset: could not solve dynamic path.'); +Cursor.prototype.unset = function(key) { + if (key === undefined && this.isRoot()) + throw Error('baobab.Cursor.unset: cannot remove root node.'); - var spec = helpers.pathObject(solvedPath, {$unset: true}); + var spec = pathPolymorphism.bind(this, 'unset').apply(this, [key, true]); - return this.update(spec); - } + return this.update(spec); }; Cursor.prototype.apply = function(fn) { @@ -298,8 +296,21 @@ Cursor.prototype.merge = function(o) { this.update({$merge: o}); }; -Cursor.prototype.update = function(spec) { - this.tree.stack(helpers.pathObject(this.solvedPath, spec)); +// TODO: lazy bitch +Cursor.prototype.update = function(key, spec) { + if (arguments.length < 2) { + this.tree.stack(helpers.pathObject(this.solvedPath, key)); + return this; + } + + // Solving path + var path = [].concat(key), + solvedPath = helpers.solvePath(this.get(), path); + + if (!solvedPath) + throw Error('baobab.Cursor.update: could not solve dynamic path.'); + + this.tree.stack(helpers.pathObject(this.solvedPath.concat(solvedPath), spec)); return this; }; From 3dc0eaf28ab12231221e910eb0bfdc8a62378561 Mon Sep 17 00:00:00 2001 From: Yomguithereal Date: Wed, 1 Apr 2015 17:21:17 +0200 Subject: [PATCH 22/73] Harmonizing setters polymorphisms --- build/baobab.min.js | 2 +- src/cursor.js | 79 ++++++++++++++++--------------------------- src/update.js | 2 +- test/suites/cursor.js | 16 ++------- 4 files changed, 33 insertions(+), 66 deletions(-) diff --git a/build/baobab.min.js b/build/baobab.min.js index e7c43e0..807a71f 100644 --- a/build/baobab.min.js +++ b/build/baobab.min.js @@ -1,2 +1,2 @@ /* baobab.js - Version: 1.0.0-rc1 - Author: Yomguithereal (Guillaume Plique) */ -!function(t){if("object"==typeof exports&&"undefined"!=typeof module)module.exports=t();else if("function"==typeof define&&define.amd)define([],t);else{var r;r="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:this,r.Baobab=t()}}(function(){var t;return function r(t,e,n){function o(s,a){if(!e[s]){if(!t[s]){var h="function"==typeof require&&require;if(!a&&h)return h(s,!0);if(i)return i(s,!0);var u=new Error("Cannot find module '"+s+"'");throw u.code="MODULE_NOT_FOUND",u}var c=e[s]={exports:{}};t[s][0].call(c.exports,function(r){var e=t[s][1][r];return o(e?e:r)},c,c.exports,r,t,e,n)}return e[s].exports}for(var i="function"==typeof require&&require,s=0;sr;r++)n.push(t[r].handler);return n}var o={once:"boolean",scope:"object"},i=function(){this._enabled=!0,this._children=[],this._handlers={},this._handlersAll=[]};i.prototype.on=function(t,r,e){var n,s,a,h,u,c;if("function"==typeof r){for(u="string"==typeof t?[t]:t,n=0,s=u.length;n!==s;n+=1)if(h=u[n]){this._handlers[h]||(this._handlers[h]=[]),c={handler:r};for(a in e||{}){if(!o[a])throw new Error('The option "'+a+'" is not recognized by Emmett.');c[a]=e[a]}this._handlers[h].push(c)}}else if(t&&"object"==typeof t&&!Array.isArray(t))for(h in t)i.prototype.on.call(this,h,t[h],r);else{if("function"!=typeof t)throw new Error("Wrong arguments.");c={handler:t};for(a in e||{}){if(!o[a])throw new Error('The option "'+a+'" is not recognized by Emmett.');c[a]=e[a]}this._handlersAll.push(c)}return this},i.prototype.once=function(t,r,e){if("function"==typeof r)e=e||{},e.once=!0,this.on(t,r,e);else{if((!t||"object"!=typeof t||Array.isArray(t))&&"function"!=typeof t)throw new Error("Wrong arguments.");r=r||{},r.once=!0,this.on(t,r)}return this},i.prototype.off=function(t,r){var e,n,o,i,s,a,h,u="string"==typeof t?[t]:t;if(1===arguments.length&&"function"==typeof u){r=arguments[0];for(s in this._handlers){for(a=[],e=0,n=this._handlers[s].length;e!==n;e+=1)this._handlers[s][e].handler!==r&&a.push(this._handlers[s][e]);this._handlers[s]=a}for(a=[],e=0,n=this._handlersAll.length;e!==n;e+=1)this._handlersAll[e].handler!==r&&a.push(this._handlersAll[e]);this._handlersAll=a}else if(2===arguments.length)for(e=0,n=u.length;e!==n;e+=1){if(h=u[e],this._handlers[h]){for(a=[],o=0,i=this._handlers[h].length;o!==i;o+=1)this._handlers[h][o].handler!==r&&a.push(this._handlers[h][o]);this._handlers[h]=a}this._handlers[h]&&0===this._handlers[h].length&&delete this._handlers[h]}return this},i.prototype.unbindAll=function(){var t;this._handlersAll=[];for(t in this._handlers)delete this._handlers[t];return this},i.prototype.emit=function(t,r){var e,n,o,i,s,a,h,u,c,l,f="string"==typeof t?[t]:t;if(!this._enabled)return this;for(r=void 0===r?{}:r,e=0,n=f.length;e!==n;e+=1)if(l=f[e],c=(this._handlers[l]||[]).concat(this._handlersAll),c.length){for(h={type:l,data:r||{},target:this},a=[],o=0,i=c.length;o!==i;o+=1)(this._handlers[l]&&this._handlers[l].indexOf(c[o])>=0||this._handlersAll.indexOf(c[o])>=0)&&(c[o].handler.call("scope"in c[o]?c[o].scope:this,h),c[o].once&&a.push(c[o]));for(s=0;se;e++)if(t._children[e]===r){t._children.splice(e,1);break}}),this._children.push(r),r},i.prototype.listeners=function(t){var e,n,o,i=[];if(t)for(i=r(this._handlers[t]),n=0,o=this._children.length;o>n;n++)i=i.concat(this._children[n].listeners(t));else{i=r(this._handlersAll);for(e in this._handlers)i=i.concat(r(this._handlers[e]));for(n=0,o=this._children.length;o>n;n++)i=i.concat(this._children[n].listeners())}return i},i.prototype.kill=function(){if(this.emit("emmett:kill"),this.unbindAll(),this._handlers=null,this._handlersAll=null,this._enabled=!1,this._children)for(var t=0,r=this._children.length;r>t;t++)this._children[t].kill();this._children=null},i.prototype.disable=function(){return this._enabled=!1,this},i.prototype.enable=function(){return this._enabled=!0,this},i.version="2.1.2","undefined"!=typeof n?("undefined"!=typeof e&&e.exports&&(n=e.exports=i),n.Emitter=i):"function"==typeof t&&t.amd?t("emmett",[],function(){return i}):this.Emitter=i}).call(this)},{}],4:[function(t,r){function e(t){return t+"$"+(new Date).getTime()+(""+Math.random()).replace("0.","")}function n(t,r){function e(t){this[t]=function(){var r=this.root[t].apply(this.root,arguments);return r instanceof o?this:r}}if(arguments.length<1&&(t={}),!(this instanceof n))return new n(t,r);if(!l.Object(t)&&!l.Array(t))throw Error("Baobab: invalid data.");i.call(this),this.options=s.shallowMerge(c,r),this._transaction={},this._future=void 0,this._cursors={},this.data=s.deepClone(t),this.root=this.select([]),["get","set","unset","update"].forEach(e.bind(this)),this.mixin=u.baobab(this)}var o=t("./cursor.js"),i=t("emmett"),s=t("./helpers.js"),a=t("./update.js"),h=t("./merge.js"),u=t("./mixins.js"),c=t("../defaults.js"),l=t("./type.js");s.inherits(n,i),n.prototype.select=function(t){if(!t)throw Error("Baobab.select: invalid path.");if(arguments.length>1&&(t=s.arrayOf(arguments)),!l.Path(t))throw Error("Baobab.select: invalid path.");t=[].concat(t);var r,n=l.ComplexPath(t);n&&(r=s.solvePath(this.data,t));var i=t.map(function(t){return l.Function(t)?e("fn"):l.Object(t)?e("ob"):t}).join("λ");if(this._cursors[i])return this._cursors[i];var a=new o(this,t,r,i);return this._cursors[i]=a,a},n.prototype.stack=function(t){var r=this;if(!l.Object(t))throw Error("Baobab.update: wrong specification.");return this._transaction=h(t,this._transaction),this.options.autoCommit?this.options.asynchronous?(this._future||(this._future=setTimeout(r.commit.bind(r,null),0)),this):this.commit():this},n.prototype.commit=function(){var t=a(this.data,this._transaction,this.options);return this.data=t.data,this._transaction={},this._future&&(this._future=clearTimeout(this._future)),this.emit("update",{log:t.log}),this},n.prototype.release=function(){delete this.data,delete this._transaction;for(var t in this._cursors)this._cursors[t].release();delete this._cursors,this.kill()},n.prototype.toJSON=function(){return this.get()},r.exports=n},{"../defaults.js":1,"./cursor.js":6,"./helpers.js":7,"./merge.js":8,"./mixins.js":9,"./type.js":10,"./update.js":11,emmett:3}],5:[function(t,r){function e(t,r){r.on("update",t.cursorListener),t.tree.off("update",t.treeListener),t.tree.on("update",t.treeListener)}function n(t){var r=this;if(arguments.length<2)throw Error("baobab.Combination: not enough arguments.");var n=arguments[1],o=s.arrayOf(arguments).slice(2);if(n instanceof Array&&(o=n.slice(1),n=n[0]),!a.Cursor(n))throw Error("baobab.Combination: argument should be a cursor.");if("or"!==t&&"and"!==t)throw Error("baobab.Combination: invalid operator.");i.call(this),this.cursors=[n],this.operators=[],this.tree=n.tree,this.updates=new Array(this.cursors.length),this.cursorListener=function(){r.updates[r.cursors.indexOf(this)]=!0},this.treeListener=function(){var t,e,n=r.updates[0];for(t=1,e=r.cursors.length;e>t;t++)n="or"===r.operators[t-1]?n||r.updates[t]:n&&r.updates[t];n&&r.emit("update"),r.updates=new Array(r.cursors.length)},this.bound=!1;var h=(this.on,this.once,function(){r.bound||(r.bound=!0,r.cursors.forEach(function(t){e(r,t)}))});this.on=s.before(h,this.on.bind(this)),this.once=s.before(h,this.once.bind(this)),o.forEach(function(r){this[t](r)},this)}function o(t){n.prototype[t]=function(r){if(!a.Cursor(r))throw this.release(),Error("baobab.Combination."+t+": argument should be a cursor.");if(~this.cursors.indexOf(r))throw this.release(),Error("baobab.Combination."+t+": cursor already in combination.");return this.cursors.push(r),this.operators.push(t),this.updates.length++,this.bound&&e(this,r),this}}var i=t("emmett"),s=t("./helpers.js"),a=t("./type.js");s.inherits(n,i),o("or"),o("and"),n.prototype.release=function(){this.cursors.forEach(function(t){t.off("update",this.cursorListener)},this),this.tree.off("update",this.treeListener),this.cursors=null,this.operators=null,this.tree=null,this.updates=null,this.kill()},r.exports=n},{"./helpers.js":7,"./type.js":10,emmett:3}],6:[function(t,r){function e(t,r,e,n){var i=this;o.call(this),r=r||[],this.tree=t,this.path=r,this.hash=n,this.complexPath=!!e,this.solvedPath=this.complexPath?e:this.path,this.relevant=void 0!==this.get(),this.updateHandler=function(t){var r,e,n,o,s,h,u=t.data.log,c=!1;if(i.complexPath&&(i.solvedPath=a.solvePath(i.tree.data,i.path)),!i.path.length)return i.emit("update");t:for(s=0,n=u.length;n>s;s++)for(r=u[s],h=0,o=r.length;o>h&&(e=r[h],e===""+i.solvedPath[h]);h++)if(h+1===o||h+1===i.solvedPath.length){c=!0;break t}var l=void 0!==i.get();i.relevant?l&&c?i.emit("update"):l||(i.emit("irrelevant"),i.relevant=!1):l&&c&&(i.emit("relevant"),i.emit("update"),i.relevant=!0)},this.mixin=s.cursor(this);var h=!1,u=function(){h||(h=!0,i.tree.on("update",i.updateHandler))};this.on=a.before(u,this.on.bind(this)),this.once=a.before(u,this.once.bind(this))}function n(t,r,e){arguments.length<3&&(e=r,r=[]),r=r||[];var n=[].concat(r),o=a.solvePath(this.get(),n);if(!o)throw Error("baobab.Cursor."+t+": could not solve dynamic path.");var i={};i["$"+t]=e;var s=a.pathObject(o,i);return s}var o=t("emmett"),i=t("./combination.js"),s=t("./mixins.js"),a=t("./helpers.js"),h=t("./type.js");a.inherits(e,o),e.prototype.isRoot=function(){return!this.path.length},e.prototype.isLeaf=function(){return h.Primitive(this.get())},e.prototype.isBranch=function(){return!this.isLeaf()&&!this.isRoot()},e.prototype.root=function(){return this.tree.root()},e.prototype.select=function(t){if(arguments.length>1&&(t=a.arrayOf(arguments)),!h.Path(t))throw Error("baobab.Cursor.select: invalid path.");return this.tree.select(this.path.concat(t))},e.prototype.up=function(){return this.solvedPath&&this.solvedPath.length?this.tree.select(this.path.slice(0,-1)):null},e.prototype.left=function(){var t=+this.solvedPath[this.solvedPath.length-1];if(isNaN(t))throw Error("baobab.Cursor.left: cannot go left on a non-list type.");return t?this.tree.select(this.solvedPath.slice(0,-1).concat(t-1)):null},e.prototype.leftmost=function(){var t=+this.solvedPath[this.solvedPath.length-1];if(isNaN(t))throw Error("baobab.Cursor.leftmost: cannot go left on a non-list type.");return this.tree.select(this.solvedPath.slice(0,-1).concat(0))},e.prototype.right=function(){var t=+this.solvedPath[this.solvedPath.length-1];if(isNaN(t))throw Error("baobab.Cursor.right: cannot go right on a non-list type.");return t+1===this.up().get().length?null:this.tree.select(this.solvedPath.slice(0,-1).concat(t+1))},e.prototype.rightmost=function(){var t=+this.solvedPath[this.solvedPath.length-1];if(isNaN(t))throw Error("baobab.Cursor.right: cannot go right on a non-list type.");var r=this.up().get();return this.tree.select(this.solvedPath.slice(0,-1).concat(r.length-1))},e.prototype.down=function(){+this.solvedPath[this.solvedPath.length-1];return this.get()instanceof Array?this.tree.select(this.solvedPath.concat(0)):null},e.prototype.get=function(t){arguments.length>1&&(t=a.arrayOf(arguments));var r=this.solvedPath.concat((h.String(t)||h.Number(t)?[t]:t)||[]);return a.getIn(this.tree.data,r)},e.prototype.set=function(){var t=n.bind(this,"set").apply(this,arguments);return this.update(t)},e.prototype.unset=function(t){if(void 0===t&&this.isRoot())throw Error("baobab.Cursor.unset: cannot remove root node.");var r=n.bind(this,"unset").apply(this,[t,!0]);return this.update(r)},e.prototype.apply=function(t){if("function"!=typeof t)throw Error("baobab.Cursor.apply: argument is not a function.");return this.update({$apply:t})},e.prototype.chain=function(t){if("function"!=typeof t)throw Error("baobab.Cursor.chain: argument is not a function.");return this.update({$chain:t})},e.prototype.push=function(t){if(!(this.get()instanceof Array))throw Error("baobab.Cursor.push: trying to push to non-array value.");return this.update(arguments.length>1?{$push:a.arrayOf(arguments)}:{$push:t})},e.prototype.unshift=function(t){if(!(this.get()instanceof Array))throw Error("baobab.Cursor.push: trying to push to non-array value.");return this.update(arguments.length>1?{$unshift:a.arrayOf(arguments)}:{$unshift:t})},e.prototype.merge=function(t){if(!h.Object(t))throw Error("baobab.Cursor.merge: trying to merge a non-object.");if(!h.Object(this.get()))throw Error("baobab.Cursor.merge: trying to merge into a non-object.");this.update({$merge:t})},e.prototype.update=function(t,r){if(arguments.length<2)return this.tree.stack(a.pathObject(this.solvedPath,t)),this;var e=[].concat(t),n=a.solvePath(this.get(),e);if(!n)throw Error("baobab.Cursor.update: could not solve dynamic path.");return this.tree.stack(a.pathObject(this.solvedPath.concat(n),r)),this},e.prototype.or=function(t){return new i("or",this,t)},e.prototype.and=function(t){return new i("and",this,t)},e.prototype.release=function(){this.tree.off("update",this.updateHandler),this.hash&&delete this.tree._cursors[this.hash],delete this.tree,delete this.path,delete this.solvedPath,this.kill()},e.prototype.toJSON=function(){return this.get()},h.Cursor=function(t){return t instanceof e},r.exports=e},{"./combination.js":5,"./helpers.js":7,"./mixins.js":9,"./type.js":10,emmett:3}],7:[function(t,r){function e(t){return Array.prototype.slice.call(t)}function n(t,r){return function(){t(),r.apply(null,arguments)}}function o(t,r){var e,n={};for(e in t)n[e]=t[e];for(e in r)n[e]=r[e];return n}function i(t){var r=t.source,e="";return t.global&&(e+="g"),t.multiline&&(e+="m"),t.ignoreCase&&(e+="i"),t.sticky&&(e+="y"),t.unicode&&(e+="u"),new RegExp(r,e)}function s(t,r){if(!r||"object"!=typeof r||r instanceof Error||r instanceof ArrayBuffer)return r;if(g.Array(r)){if(t){var e,n,o=[];for(e=0,n=r.length;n>e;e++)o.push(_(r[e]));return o}return r.slice(0)}if(g.Date(r))return new Date(r.getTime());if(r instanceof RegExp)return i(r);if(g.Object(r)){var s,a={};r.constructor&&r.constructor!==Object&&(a=Object.create(r.constructor.prototype));for(s in r)r.hasOwnProperty(s)&&(a[s]=t?_(r[s]):r[s]);return a}return r}function a(t,r){return function(e){return r(t(e))}}function h(t,r){var e,n;for(e=0,n=t.length;n>e;e++)if(r(t[e]))return t[e]}function u(t,r){var e,n;for(e=0,n=t.length;n>e;e++)if(r(t[e]))return e;return-1}function c(t,r){var e,n=!0;if(!t)return!1;for(e in r)if(g.Object(r[e]))n=n&&c(t[e],r[e]);else if(g.Array(r[e]))n=n&&!!~r[e].indexOf(t[e]);else if(t[e]!==r[e])return!1;return n}function l(t,r){return h(t,function(t){return c(t,r)})}function f(t,r){return u(t,function(t){return c(t,r)})}function p(t,r){r=r||[];var e,n,o=t;for(e=0,n=r.length;n>e;e++){if(!o)return;if("function"==typeof r[e]){if(!g.Array(o))return;o=h(o,r[e])}else if("object"==typeof r[e]){if(!g.Array(o))return;o=l(o,r[e])}else o=o[r[e]]}return o}function d(t,r){var e,n,o,i=[],s=t;for(n=0,o=r.length;o>n;n++){if(!s)return null;if("function"==typeof r[n]){if(!g.Array(s))return;e=u(s,r[n]),i.push(e),s=s[e]}else if("object"==typeof r[n]){if(!g.Array(s))return;e=f(s,r[n]),i.push(e),s=s[e]}else i.push(r[n]),s=s[r[n]]||{}}return i}function b(t,r){var e,n=t.length,o={},i=o;for(n||(o=r),e=0;n>e;e++)i[t[e]]=e+1===n?r:{},i=i[t[e]];return o}function y(t,r){t.super_=r;var e=function(){};e.prototype=r.prototype,t.prototype=new e,t.prototype.constructor=t}var g=t("./type.js"),m=s.bind(null,!1),_=s.bind(null,!0);r.exports={arrayOf:e,before:n,deepClone:_,shallowClone:m,shallowMerge:o,compose:a,getIn:p,inherits:y,pathObject:b,solvePath:d}},{"./type.js":10}],8:[function(t,r){function e(t,r,e){s.forEach(function(r){e!==r&&delete t[r]}),t[e]=r[e]}function n(t,r){var a,h=o.shallowClone(r||{});s.forEach(function(r){t[r]&&e(h,t,r)}),t.$chain&&(s.slice(0,-1).forEach(function(t){delete h[t]}),h.$apply=h.$apply?o.compose(h.$apply,t.$chain):t.$chain),t.$push&&h.$push?h.$push=i.Array(h.$push)?h.$push.concat(t.$push):[h.$push].concat(t.$push):t.$push&&(h.$push=t.$push),t.$unshift&&h.$unshift?h.$unshift=i.Array(t.$unshift)?t.$unshift.concat(h.$unshift):[t.$unshift].concat(h.$unshift):t.$unshift&&(h.$unshift=t.$unshift);for(a in t)i.Object(t[a])?h[a]=n(t[a],h[a]):"$"!==a[0]&&(h[a]=t[a]);return h}var o=t("./helpers.js"),i=t("./type.js"),s=["$unset","$set","$merge","$apply"];r.exports=n},{"./helpers.js":7,"./type.js":10}],9:[function(t,r){var e=t("./combination.js"),n=t("./type.js");r.exports={baobab:function(t){return{mixins:[{getInitialState:function(){if(this.tree=t,!this.cursor&&!this.cursors)return{};if(this.cursor&&this.cursors)throw Error("baobab.mixin: you cannot have both `component.cursor` and `component.cursors`. Please make up your mind.");if(this.__type=null,this.__updateHandler=function(){this.setState(this.__getCursorData())}.bind(this),this.cursor){if(!n.MixinCursor(this.cursor))throw Error("baobab.mixin.cursor: invalid data (cursor, string, array or function).");n.Function(this.cursor)&&(this.cursor=this.cursor()),n.Cursor(this.cursor)||(this.cursor=t.select(this.cursor)),this.__getCursorData=function(){return{cursor:this.cursor.get()}}.bind(this),this.__type="single"}else if(this.cursors){if(!n.MixinCursors(this.cursors))throw Error("baobab.mixin.cursor: invalid data (object, array or function).");if(n.Function(this.cursors)&&(this.cursors=this.cursors()),n.Array(this.cursors))this.cursors=this.cursors.map(function(r){return n.Cursor(r)?r:t.select(r)}),this.__getCursorData=function(){return{cursors:this.cursors.map(function(t){return t.get()})}}.bind(this),this.__type="array";else{for(var r in this.cursors)n.Cursor(this.cursors[r])||(this.cursors[r]=t.select(this.cursors[r]));this.__getCursorData=function(){var t={};for(r in this.cursors)t[r]=this.cursors[r].get();return{cursors:t}}.bind(this),this.__type="object"}}return this.__getCursorData()},componentDidMount:function(){"single"===this.__type?(this.__combination=new e("or",[this.cursor]),this.__combination.on("update",this.__updateHandler)):"array"===this.__type?(this.__combination=new e("or",this.cursors),this.__combination.on("update",this.__updateHandler)):"object"===this.__type&&(this.__combination=new e("or",Object.keys(this.cursors).map(function(t){return this.cursors[t]},this)),this.__combination.on("update",this.__updateHandler))},componentWillUnmount:function(){this.__combination&&this.__combination.release()}}].concat(t.options.mixins)}},cursor:function(t){return{mixins:[{getInitialState:function(){return this.cursor=t,this.__updateHandler=function(){this.setState({cursor:this.cursor.get()})}.bind(this),{cursor:this.cursor.get()}},componentDidMount:function(){this.cursor.on("update",this.__updateHandler)},componentWillUnmount:function(){this.cursor.off("update",this.__updateHandler)}}].concat(t.tree.options.mixins)}}}},{"./combination.js":5,"./type.js":10}],10:[function(t,r){function e(t,r){return r.some(function(r){return n[r](t)})}var n={};n.Array=function(t){return Array.isArray(t)},n.Object=function(t){return!Array.isArray(t)&&"object"==typeof t&&null!==t},n.String=function(t){return"string"==typeof t},n.Number=function(t){return"number"==typeof t},n.Function=function(t){return"function"==typeof t},n.Primitive=function(t){return"string"==typeof t||"number"==typeof t||"boolean"==typeof t},n.Date=function(t){return t instanceof Date},n.NonScalar=function(t){return n.Object(t)||n.Array(t)},n.Path=function(t){var r=["String","Number","Function","Object"];return n.Array(t)?t.every(function(t){return e(t,r)}):e(t,r)},n.MixinCursor=function(t){return e(t,["String","Number","Array","Function","Cursor"])},n.MixinCursors=function(t){return e(t,["Object","Array","Function"])},n.ComplexPath=function(t){return e(t,["Object","Function"])},r.exports=n},{}],11:[function(t,r){function e(t,r){var e=new Error("baobab.update: "+r+" at path /"+t.slice(1).toString());return e.path=t,e}var n=t("./helpers.js"),o=t("./type.js");r.exports=function(t,r,i){if(i=i||{},!o.Object(t)&&!o.Array(t))throw Error("baobab.update: invalid target.");var s={};t={root:n.shallowClone(t)};var a=function(t,r,i,h){i=i||["root"];var u,c,l,f=i.join("λ"),p=i[i.length-1],d=Object.keys(r).some(function(t){return!!~["$unset","$set","$apply","$merge","$push","$unshift"].indexOf(t)});if(d){s[f]=!0;for(c in r){if("$unset"===c){var b=i[i.length-2];o.Array(t)?h[b]=t.slice(0,+p).concat(t.slice(+p+1)):(h[b]=n.shallowClone(t),delete h[b][p]);break}if("$set"===c){l=r.$set,t[p]=l;break}if("$apply"===c){if(u=r.$apply,"function"!=typeof u)throw e(i,"using command $apply with a non function");t[p]=u.call(null,t[p]);break}if("$merge"===c){if(l=r.$merge,!o.Object(t[p])||!o.Object(l))throw e(i,"using command $merge with a non object");t[p]=n.shallowMerge(t[p],l);break}if("$push"===c){if(l=r.$push,!o.Array(t[p]))throw e(i,"using command $push to a non array");t[p]=t[p].concat(l)}if("$unshift"===c){if(l=r.$unshift,!o.Array(t[p]))throw e(i,"using command $unshift to a non array");t[p]=[].concat(l).concat(t[p])}}}else for(c in r)t[p][c]="undefined"==typeof t[p][c]?{}:n.shallowClone(t[p][c]),a(t[p],r[c],i.concat(c),t)};return a(t,r),{data:t.root,log:Object.keys(s).map(function(t){return t.split("λ").slice(1)})}}},{"./helpers.js":7,"./type.js":10}]},{},[2])(2)}); \ No newline at end of file +!function(t){if("object"==typeof exports&&"undefined"!=typeof module)module.exports=t();else if("function"==typeof define&&define.amd)define([],t);else{var r;r="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:this,r.Baobab=t()}}(function(){var t;return function r(t,e,n){function i(s,a){if(!e[s]){if(!t[s]){var h="function"==typeof require&&require;if(!a&&h)return h(s,!0);if(o)return o(s,!0);var u=new Error("Cannot find module '"+s+"'");throw u.code="MODULE_NOT_FOUND",u}var c=e[s]={exports:{}};t[s][0].call(c.exports,function(r){var e=t[s][1][r];return i(e?e:r)},c,c.exports,r,t,e,n)}return e[s].exports}for(var o="function"==typeof require&&require,s=0;sr;r++)n.push(t[r].handler);return n}var i={once:"boolean",scope:"object"},o=function(){this._enabled=!0,this._children=[],this._handlers={},this._handlersAll=[]};o.prototype.on=function(t,r,e){var n,s,a,h,u,c;if("function"==typeof r){for(u="string"==typeof t?[t]:t,n=0,s=u.length;n!==s;n+=1)if(h=u[n]){this._handlers[h]||(this._handlers[h]=[]),c={handler:r};for(a in e||{}){if(!i[a])throw new Error('The option "'+a+'" is not recognized by Emmett.');c[a]=e[a]}this._handlers[h].push(c)}}else if(t&&"object"==typeof t&&!Array.isArray(t))for(h in t)o.prototype.on.call(this,h,t[h],r);else{if("function"!=typeof t)throw new Error("Wrong arguments.");c={handler:t};for(a in e||{}){if(!i[a])throw new Error('The option "'+a+'" is not recognized by Emmett.');c[a]=e[a]}this._handlersAll.push(c)}return this},o.prototype.once=function(t,r,e){if("function"==typeof r)e=e||{},e.once=!0,this.on(t,r,e);else{if((!t||"object"!=typeof t||Array.isArray(t))&&"function"!=typeof t)throw new Error("Wrong arguments.");r=r||{},r.once=!0,this.on(t,r)}return this},o.prototype.off=function(t,r){var e,n,i,o,s,a,h,u="string"==typeof t?[t]:t;if(1===arguments.length&&"function"==typeof u){r=arguments[0];for(s in this._handlers){for(a=[],e=0,n=this._handlers[s].length;e!==n;e+=1)this._handlers[s][e].handler!==r&&a.push(this._handlers[s][e]);this._handlers[s]=a}for(a=[],e=0,n=this._handlersAll.length;e!==n;e+=1)this._handlersAll[e].handler!==r&&a.push(this._handlersAll[e]);this._handlersAll=a}else if(2===arguments.length)for(e=0,n=u.length;e!==n;e+=1){if(h=u[e],this._handlers[h]){for(a=[],i=0,o=this._handlers[h].length;i!==o;i+=1)this._handlers[h][i].handler!==r&&a.push(this._handlers[h][i]);this._handlers[h]=a}this._handlers[h]&&0===this._handlers[h].length&&delete this._handlers[h]}return this},o.prototype.unbindAll=function(){var t;this._handlersAll=[];for(t in this._handlers)delete this._handlers[t];return this},o.prototype.emit=function(t,r){var e,n,i,o,s,a,h,u,c,l,f="string"==typeof t?[t]:t;if(!this._enabled)return this;for(r=void 0===r?{}:r,e=0,n=f.length;e!==n;e+=1)if(l=f[e],c=(this._handlers[l]||[]).concat(this._handlersAll),c.length){for(h={type:l,data:r||{},target:this},a=[],i=0,o=c.length;i!==o;i+=1)(this._handlers[l]&&this._handlers[l].indexOf(c[i])>=0||this._handlersAll.indexOf(c[i])>=0)&&(c[i].handler.call("scope"in c[i]?c[i].scope:this,h),c[i].once&&a.push(c[i]));for(s=0;se;e++)if(t._children[e]===r){t._children.splice(e,1);break}}),this._children.push(r),r},o.prototype.listeners=function(t){var e,n,i,o=[];if(t)for(o=r(this._handlers[t]),n=0,i=this._children.length;i>n;n++)o=o.concat(this._children[n].listeners(t));else{o=r(this._handlersAll);for(e in this._handlers)o=o.concat(r(this._handlers[e]));for(n=0,i=this._children.length;i>n;n++)o=o.concat(this._children[n].listeners())}return o},o.prototype.kill=function(){if(this.emit("emmett:kill"),this.unbindAll(),this._handlers=null,this._handlersAll=null,this._enabled=!1,this._children)for(var t=0,r=this._children.length;r>t;t++)this._children[t].kill();this._children=null},o.prototype.disable=function(){return this._enabled=!1,this},o.prototype.enable=function(){return this._enabled=!0,this},o.version="2.1.2","undefined"!=typeof n?("undefined"!=typeof e&&e.exports&&(n=e.exports=o),n.Emitter=o):"function"==typeof t&&t.amd?t("emmett",[],function(){return o}):this.Emitter=o}).call(this)},{}],4:[function(t,r){function e(t){return t+"$"+(new Date).getTime()+(""+Math.random()).replace("0.","")}function n(t,r){function e(t){this[t]=function(){var r=this.root[t].apply(this.root,arguments);return r instanceof i?this:r}}if(arguments.length<1&&(t={}),!(this instanceof n))return new n(t,r);if(!l.Object(t)&&!l.Array(t))throw Error("Baobab: invalid data.");o.call(this),this.options=s.shallowMerge(c,r),this._transaction={},this._future=void 0,this._cursors={},this.data=s.deepClone(t),this.root=this.select([]),["get","set","unset","update"].forEach(e.bind(this)),this.mixin=u.baobab(this)}var i=t("./cursor.js"),o=t("emmett"),s=t("./helpers.js"),a=t("./update.js"),h=t("./merge.js"),u=t("./mixins.js"),c=t("../defaults.js"),l=t("./type.js");s.inherits(n,o),n.prototype.select=function(t){if(!t)throw Error("Baobab.select: invalid path.");if(arguments.length>1&&(t=s.arrayOf(arguments)),!l.Path(t))throw Error("Baobab.select: invalid path.");t=[].concat(t);var r,n=l.ComplexPath(t);n&&(r=s.solvePath(this.data,t));var o=t.map(function(t){return l.Function(t)?e("fn"):l.Object(t)?e("ob"):t}).join("λ");if(this._cursors[o])return this._cursors[o];var a=new i(this,t,r,o);return this._cursors[o]=a,a},n.prototype.stack=function(t){var r=this;if(!l.Object(t))throw Error("Baobab.update: wrong specification.");return this._transaction=h(t,this._transaction),this.options.autoCommit?this.options.asynchronous?(this._future||(this._future=setTimeout(r.commit.bind(r,null),0)),this):this.commit():this},n.prototype.commit=function(){var t=a(this.data,this._transaction,this.options);return this.data=t.data,this._transaction={},this._future&&(this._future=clearTimeout(this._future)),this.emit("update",{log:t.log}),this},n.prototype.release=function(){delete this.data,delete this._transaction;for(var t in this._cursors)this._cursors[t].release();delete this._cursors,this.kill()},n.prototype.toJSON=function(){return this.get()},r.exports=n},{"../defaults.js":1,"./cursor.js":6,"./helpers.js":7,"./merge.js":8,"./mixins.js":9,"./type.js":10,"./update.js":11,emmett:3}],5:[function(t,r){function e(t,r){r.on("update",t.cursorListener),t.tree.off("update",t.treeListener),t.tree.on("update",t.treeListener)}function n(t){var r=this;if(arguments.length<2)throw Error("baobab.Combination: not enough arguments.");var n=arguments[1],i=s.arrayOf(arguments).slice(2);if(n instanceof Array&&(i=n.slice(1),n=n[0]),!a.Cursor(n))throw Error("baobab.Combination: argument should be a cursor.");if("or"!==t&&"and"!==t)throw Error("baobab.Combination: invalid operator.");o.call(this),this.cursors=[n],this.operators=[],this.tree=n.tree,this.updates=new Array(this.cursors.length),this.cursorListener=function(){r.updates[r.cursors.indexOf(this)]=!0},this.treeListener=function(){var t,e,n=r.updates[0];for(t=1,e=r.cursors.length;e>t;t++)n="or"===r.operators[t-1]?n||r.updates[t]:n&&r.updates[t];n&&r.emit("update"),r.updates=new Array(r.cursors.length)},this.bound=!1;var h=(this.on,this.once,function(){r.bound||(r.bound=!0,r.cursors.forEach(function(t){e(r,t)}))});this.on=s.before(h,this.on.bind(this)),this.once=s.before(h,this.once.bind(this)),i.forEach(function(r){this[t](r)},this)}function i(t){n.prototype[t]=function(r){if(!a.Cursor(r))throw this.release(),Error("baobab.Combination."+t+": argument should be a cursor.");if(~this.cursors.indexOf(r))throw this.release(),Error("baobab.Combination."+t+": cursor already in combination.");return this.cursors.push(r),this.operators.push(t),this.updates.length++,this.bound&&e(this,r),this}}var o=t("emmett"),s=t("./helpers.js"),a=t("./type.js");s.inherits(n,o),i("or"),i("and"),n.prototype.release=function(){this.cursors.forEach(function(t){t.off("update",this.cursorListener)},this),this.tree.off("update",this.treeListener),this.cursors=null,this.operators=null,this.tree=null,this.updates=null,this.kill()},r.exports=n},{"./helpers.js":7,"./type.js":10,emmett:3}],6:[function(t,r){function e(t,r,e,n){var i=this;o.call(this),r=r||[],this.tree=t,this.path=r,this.hash=n,this.complexPath=!!e,this.solvedPath=this.complexPath?e:this.path,this.relevant=void 0!==this.get(),this.updateHandler=function(t){var r,e,n,o,s,a,u=t.data.log,c=!1;if(i.complexPath&&(i.solvedPath=h.solvePath(i.tree.data,i.path)),!i.path.length)return i.emit("update");t:for(s=0,n=u.length;n>s;s++)for(r=u[s],a=0,o=r.length;o>a&&(e=r[a],e===""+i.solvedPath[a]);a++)if(a+1===o||a+1===i.solvedPath.length){c=!0;break t}var l=void 0!==i.get();i.relevant?l&&c?i.emit("update"):l||(i.emit("irrelevant"),i.relevant=!1):l&&c&&(i.emit("relevant"),i.emit("update"),i.relevant=!0)},this.mixin=a.cursor(this);var s=!1,u=function(){s||(s=!0,i.tree.on("update",i.updateHandler))};this.on=h.before(u,this.on.bind(this)),this.once=h.before(u,this.once.bind(this))}function n(t,r,e,n){arguments.length<4&&(n=e,e=[]),e=e||[];var i=[].concat(e),o=h.solvePath(this.get(),i);if(!o)throw Error("baobab.Cursor."+t+": could not solve dynamic path.");if(r){var s=this.get(o);if(!u[r](s))throw Error("baobab.Cursor."+t+": invalid target.")}var a={};a["$"+t]=n;var c=h.pathObject(o,a);return c}function i(t,r){e.prototype[t]=function(){var e=n.bind(this,t,r).apply(this,arguments);return this.update(e)}}var o=t("emmett"),s=t("./combination.js"),a=t("./mixins.js"),h=t("./helpers.js"),u=t("./type.js");h.inherits(e,o),e.prototype.isRoot=function(){return!this.path.length},e.prototype.isLeaf=function(){return u.Primitive(this.get())},e.prototype.isBranch=function(){return!this.isLeaf()&&!this.isRoot()},e.prototype.root=function(){return this.tree.root()},e.prototype.select=function(t){if(arguments.length>1&&(t=h.arrayOf(arguments)),!u.Path(t))throw Error("baobab.Cursor.select: invalid path.");return this.tree.select(this.path.concat(t))},e.prototype.up=function(){return this.solvedPath&&this.solvedPath.length?this.tree.select(this.path.slice(0,-1)):null},e.prototype.left=function(){var t=+this.solvedPath[this.solvedPath.length-1];if(isNaN(t))throw Error("baobab.Cursor.left: cannot go left on a non-list type.");return t?this.tree.select(this.solvedPath.slice(0,-1).concat(t-1)):null},e.prototype.leftmost=function(){var t=+this.solvedPath[this.solvedPath.length-1];if(isNaN(t))throw Error("baobab.Cursor.leftmost: cannot go left on a non-list type.");return this.tree.select(this.solvedPath.slice(0,-1).concat(0))},e.prototype.right=function(){var t=+this.solvedPath[this.solvedPath.length-1];if(isNaN(t))throw Error("baobab.Cursor.right: cannot go right on a non-list type.");return t+1===this.up().get().length?null:this.tree.select(this.solvedPath.slice(0,-1).concat(t+1))},e.prototype.rightmost=function(){var t=+this.solvedPath[this.solvedPath.length-1];if(isNaN(t))throw Error("baobab.Cursor.right: cannot go right on a non-list type.");var r=this.up().get();return this.tree.select(this.solvedPath.slice(0,-1).concat(r.length-1))},e.prototype.down=function(){+this.solvedPath[this.solvedPath.length-1];return this.get()instanceof Array?this.tree.select(this.solvedPath.concat(0)):null},e.prototype.get=function(t){arguments.length>1&&(t=h.arrayOf(arguments));var r=this.solvedPath.concat((u.String(t)||u.Number(t)?[t]:t)||[]);return h.getIn(this.tree.data,r)},i("set"),i("apply"),i("chain"),i("push","Array"),i("unshift","Array"),e.prototype.merge=function(t){if(!u.Object(t))throw Error("baobab.Cursor.merge: trying to merge a non-object.");var r=n.bind(this,"merge","Object").apply(this,arguments);return this.update(r)},e.prototype.unset=function(t){if(void 0===t&&this.isRoot())throw Error("baobab.Cursor.unset: cannot remove root node.");var r=n.bind(this,"unset",null).apply(this,[t,!0]);return this.update(r)},e.prototype.update=function(t,r){if(arguments.length<2)return this.tree.stack(h.pathObject(this.solvedPath,t)),this;var e=[].concat(t),n=h.solvePath(this.get(),e);if(!n)throw Error("baobab.Cursor.update: could not solve dynamic path.");return this.tree.stack(h.pathObject(this.solvedPath.concat(n),r)),this},e.prototype.or=function(t){return new s("or",this,t)},e.prototype.and=function(t){return new s("and",this,t)},e.prototype.release=function(){this.tree.off("update",this.updateHandler),this.hash&&delete this.tree._cursors[this.hash],delete this.tree,delete this.path,delete this.solvedPath,this.kill()},e.prototype.toJSON=function(){return this.get()},u.Cursor=function(t){return t instanceof e},r.exports=e},{"./combination.js":5,"./helpers.js":7,"./mixins.js":9,"./type.js":10,emmett:3}],7:[function(t,r){function e(t){return Array.prototype.slice.call(t)}function n(t,r){return function(){t(),r.apply(null,arguments)}}function i(t,r){var e,n={};for(e in t)n[e]=t[e];for(e in r)n[e]=r[e];return n}function o(t){var r=t.source,e="";return t.global&&(e+="g"),t.multiline&&(e+="m"),t.ignoreCase&&(e+="i"),t.sticky&&(e+="y"),t.unicode&&(e+="u"),new RegExp(r,e)}function s(t,r){if(!r||"object"!=typeof r||r instanceof Error||r instanceof ArrayBuffer)return r;if(m.Array(r)){if(t){var e,n,i=[];for(e=0,n=r.length;n>e;e++)i.push(v(r[e]));return i}return r.slice(0)}if(m.Date(r))return new Date(r.getTime());if(r instanceof RegExp)return o(r);if(m.Object(r)){var s,a={};r.constructor&&r.constructor!==Object&&(a=Object.create(r.constructor.prototype));for(s in r)r.hasOwnProperty(s)&&(a[s]=t?v(r[s]):r[s]);return a}return r}function a(t,r){return function(e){return r(t(e))}}function h(t,r){var e,n;for(e=0,n=t.length;n>e;e++)if(r(t[e]))return t[e]}function u(t,r){var e,n;for(e=0,n=t.length;n>e;e++)if(r(t[e]))return e;return-1}function c(t,r){var e,n=!0;if(!t)return!1;for(e in r)if(m.Object(r[e]))n=n&&c(t[e],r[e]);else if(m.Array(r[e]))n=n&&!!~r[e].indexOf(t[e]);else if(t[e]!==r[e])return!1;return n}function l(t,r){return h(t,function(t){return c(t,r)})}function f(t,r){return u(t,function(t){return c(t,r)})}function p(t,r){r=r||[];var e,n,i=t;for(e=0,n=r.length;n>e;e++){if(!i)return;if("function"==typeof r[e]){if(!m.Array(i))return;i=h(i,r[e])}else if("object"==typeof r[e]){if(!m.Array(i))return;i=l(i,r[e])}else i=i[r[e]]}return i}function d(t,r){var e,n,i,o=[],s=t;for(n=0,i=r.length;i>n;n++){if(!s)return null;if("function"==typeof r[n]){if(!m.Array(s))return;e=u(s,r[n]),o.push(e),s=s[e]}else if("object"==typeof r[n]){if(!m.Array(s))return;e=f(s,r[n]),o.push(e),s=s[e]}else o.push(r[n]),s=s[r[n]]||{}}return o}function b(t,r){var e,n=t.length,i={},o=i;for(n||(i=r),e=0;n>e;e++)o[t[e]]=e+1===n?r:{},o=o[t[e]];return i}function y(t,r){t.super_=r;var e=function(){};e.prototype=r.prototype,t.prototype=new e,t.prototype.constructor=t}var m=t("./type.js"),g=s.bind(null,!1),v=s.bind(null,!0);r.exports={arrayOf:e,before:n,deepClone:v,shallowClone:g,shallowMerge:i,compose:a,getIn:p,inherits:y,pathObject:b,solvePath:d}},{"./type.js":10}],8:[function(t,r){function e(t,r,e){s.forEach(function(r){e!==r&&delete t[r]}),t[e]=r[e]}function n(t,r){var a,h=i.shallowClone(r||{});s.forEach(function(r){t[r]&&e(h,t,r)}),t.$chain&&(s.slice(0,-1).forEach(function(t){delete h[t]}),h.$apply=h.$apply?i.compose(h.$apply,t.$chain):t.$chain),t.$push&&h.$push?h.$push=o.Array(h.$push)?h.$push.concat(t.$push):[h.$push].concat(t.$push):t.$push&&(h.$push=t.$push),t.$unshift&&h.$unshift?h.$unshift=o.Array(t.$unshift)?t.$unshift.concat(h.$unshift):[t.$unshift].concat(h.$unshift):t.$unshift&&(h.$unshift=t.$unshift);for(a in t)o.Object(t[a])?h[a]=n(t[a],h[a]):"$"!==a[0]&&(h[a]=t[a]);return h}var i=t("./helpers.js"),o=t("./type.js"),s=["$unset","$set","$merge","$apply"];r.exports=n},{"./helpers.js":7,"./type.js":10}],9:[function(t,r){var e=t("./combination.js"),n=t("./type.js");r.exports={baobab:function(t){return{mixins:[{getInitialState:function(){if(this.tree=t,!this.cursor&&!this.cursors)return{};if(this.cursor&&this.cursors)throw Error("baobab.mixin: you cannot have both `component.cursor` and `component.cursors`. Please make up your mind.");if(this.__type=null,this.__updateHandler=function(){this.setState(this.__getCursorData())}.bind(this),this.cursor){if(!n.MixinCursor(this.cursor))throw Error("baobab.mixin.cursor: invalid data (cursor, string, array or function).");n.Function(this.cursor)&&(this.cursor=this.cursor()),n.Cursor(this.cursor)||(this.cursor=t.select(this.cursor)),this.__getCursorData=function(){return{cursor:this.cursor.get()}}.bind(this),this.__type="single"}else if(this.cursors){if(!n.MixinCursors(this.cursors))throw Error("baobab.mixin.cursor: invalid data (object, array or function).");if(n.Function(this.cursors)&&(this.cursors=this.cursors()),n.Array(this.cursors))this.cursors=this.cursors.map(function(r){return n.Cursor(r)?r:t.select(r)}),this.__getCursorData=function(){return{cursors:this.cursors.map(function(t){return t.get()})}}.bind(this),this.__type="array";else{for(var r in this.cursors)n.Cursor(this.cursors[r])||(this.cursors[r]=t.select(this.cursors[r]));this.__getCursorData=function(){var t={};for(r in this.cursors)t[r]=this.cursors[r].get();return{cursors:t}}.bind(this),this.__type="object"}}return this.__getCursorData()},componentDidMount:function(){"single"===this.__type?(this.__combination=new e("or",[this.cursor]),this.__combination.on("update",this.__updateHandler)):"array"===this.__type?(this.__combination=new e("or",this.cursors),this.__combination.on("update",this.__updateHandler)):"object"===this.__type&&(this.__combination=new e("or",Object.keys(this.cursors).map(function(t){return this.cursors[t]},this)),this.__combination.on("update",this.__updateHandler))},componentWillUnmount:function(){this.__combination&&this.__combination.release()}}].concat(t.options.mixins)}},cursor:function(t){return{mixins:[{getInitialState:function(){return this.cursor=t,this.__updateHandler=function(){this.setState({cursor:this.cursor.get()})}.bind(this),{cursor:this.cursor.get()}},componentDidMount:function(){this.cursor.on("update",this.__updateHandler)},componentWillUnmount:function(){this.cursor.off("update",this.__updateHandler)}}].concat(t.tree.options.mixins)}}}},{"./combination.js":5,"./type.js":10}],10:[function(t,r){function e(t,r){return r.some(function(r){return n[r](t)})}var n={};n.Array=function(t){return Array.isArray(t)},n.Object=function(t){return!Array.isArray(t)&&"object"==typeof t&&null!==t},n.String=function(t){return"string"==typeof t},n.Number=function(t){return"number"==typeof t},n.Function=function(t){return"function"==typeof t},n.Primitive=function(t){return"string"==typeof t||"number"==typeof t||"boolean"==typeof t},n.Date=function(t){return t instanceof Date},n.NonScalar=function(t){return n.Object(t)||n.Array(t)},n.Path=function(t){var r=["String","Number","Function","Object"];return n.Array(t)?t.every(function(t){return e(t,r)}):e(t,r)},n.MixinCursor=function(t){return e(t,["String","Number","Array","Function","Cursor"])},n.MixinCursors=function(t){return e(t,["Object","Array","Function"])},n.ComplexPath=function(t){return e(t,["Object","Function"])},r.exports=n},{}],11:[function(t,r){function e(t,r){var e=new Error("baobab.update: "+r+" at path /"+t.slice(1).join("/"));return e.path=t,e}var n=t("./helpers.js"),i=t("./type.js");r.exports=function(t,r,o){if(o=o||{},!i.Object(t)&&!i.Array(t))throw Error("baobab.update: invalid target.");var s={};t={root:n.shallowClone(t)};var a=function(t,r,o,h){o=o||["root"];var u,c,l,f=o.join("λ"),p=o[o.length-1],d=Object.keys(r).some(function(t){return!!~["$unset","$set","$apply","$merge","$push","$unshift"].indexOf(t)});if(d){s[f]=!0;for(c in r){if("$unset"===c){var b=o[o.length-2];i.Array(t)?h[b]=t.slice(0,+p).concat(t.slice(+p+1)):(h[b]=n.shallowClone(t),delete h[b][p]);break}if("$set"===c){l=r.$set,t[p]=l;break}if("$apply"===c){if(u=r.$apply,"function"!=typeof u)throw e(o,"using command $apply with a non function");t[p]=u.call(null,t[p]);break}if("$merge"===c){if(l=r.$merge,!i.Object(t[p])||!i.Object(l))throw e(o,"using command $merge with a non object");t[p]=n.shallowMerge(t[p],l);break}if("$push"===c){if(l=r.$push,!i.Array(t[p]))throw e(o,"using command $push to a non array");t[p]=t[p].concat(l)}if("$unshift"===c){if(l=r.$unshift,!i.Array(t[p]))throw e(o,"using command $unshift to a non array");t[p]=[].concat(l).concat(t[p])}}}else for(c in r)t[p][c]="undefined"==typeof t[p][c]?{}:n.shallowClone(t[p][c]),a(t[p],r[c],o.concat(c),t)};return a(t,r),{data:t.root,log:Object.keys(s).map(function(t){return t.split("λ").slice(1)})}}},{"./helpers.js":7,"./type.js":10}]},{},[2])(2)}); \ No newline at end of file diff --git a/src/cursor.js b/src/cursor.js index 99aa94f..b9ff550 100644 --- a/src/cursor.js +++ b/src/cursor.js @@ -215,8 +215,8 @@ Cursor.prototype.get = function(path) { /** * Update */ -function pathPolymorphism(method, key, val) { - if (arguments.length < 3) { +function pathPolymorphism(method, allowedType, key, val) { + if (arguments.length < 4) { val = key; key = []; } @@ -229,6 +229,13 @@ function pathPolymorphism(method, key, val) { if (!solvedPath) throw Error('baobab.Cursor.' + method + ': could not solve dynamic path.'); + if (allowedType) { + var data = this.get(solvedPath); + + if (!type[allowedType](data)) + throw Error('baobab.Cursor.' + method + ': invalid target.'); + } + var leaf = {}; leaf['$' + method] = val; @@ -237,8 +244,25 @@ function pathPolymorphism(method, key, val) { return spec; } -Cursor.prototype.set = function(key, val) { - var spec = pathPolymorphism.bind(this, 'set').apply(this, arguments); +function makeUpdateMethod(command, type) { + Cursor.prototype[command] = function() { + var spec = pathPolymorphism.bind(this, command, type).apply(this, arguments); + + return this.update(spec); + }; +} + +makeUpdateMethod('set'); +makeUpdateMethod('apply'); +makeUpdateMethod('chain'); +makeUpdateMethod('push', 'Array'); +makeUpdateMethod('unshift', 'Array'); + +Cursor.prototype.merge = function(o) { + if (!type.Object(o)) + throw Error('baobab.Cursor.merge: trying to merge a non-object.'); + + var spec = pathPolymorphism.bind(this, 'merge', 'Object').apply(this, arguments); return this.update(spec); }; @@ -247,56 +271,11 @@ Cursor.prototype.unset = function(key) { if (key === undefined && this.isRoot()) throw Error('baobab.Cursor.unset: cannot remove root node.'); - var spec = pathPolymorphism.bind(this, 'unset').apply(this, [key, true]); + var spec = pathPolymorphism.bind(this, 'unset', null).apply(this, [key, true]); return this.update(spec); }; -Cursor.prototype.apply = function(fn) { - if (typeof fn !== 'function') - throw Error('baobab.Cursor.apply: argument is not a function.'); - - return this.update({$apply: fn}); -}; - -Cursor.prototype.chain = function(fn) { - if (typeof fn !== 'function') - throw Error('baobab.Cursor.chain: argument is not a function.'); - - return this.update({$chain: fn}); -}; - -Cursor.prototype.push = function(value) { - if (!(this.get() instanceof Array)) - throw Error('baobab.Cursor.push: trying to push to non-array value.'); - - if (arguments.length > 1) - return this.update({$push: helpers.arrayOf(arguments)}); - else - return this.update({$push: value}); -}; - -Cursor.prototype.unshift = function(value) { - if (!(this.get() instanceof Array)) - throw Error('baobab.Cursor.push: trying to push to non-array value.'); - - if (arguments.length > 1) - return this.update({$unshift: helpers.arrayOf(arguments)}); - else - return this.update({$unshift: value}); -}; - -Cursor.prototype.merge = function(o) { - if (!type.Object(o)) - throw Error('baobab.Cursor.merge: trying to merge a non-object.'); - - if (!type.Object(this.get())) - throw Error('baobab.Cursor.merge: trying to merge into a non-object.'); - - this.update({$merge: o}); -}; - -// TODO: lazy bitch Cursor.prototype.update = function(key, spec) { if (arguments.length < 2) { this.tree.stack(helpers.pathObject(this.solvedPath, key)); diff --git a/src/update.js b/src/update.js index 4a26fd3..3903b52 100644 --- a/src/update.js +++ b/src/update.js @@ -11,7 +11,7 @@ var helpers = require('./helpers.js'), // Helpers function makeError(path, message) { var e = new Error('baobab.update: ' + message + ' at path /' + - path.slice(1).toString()); + path.slice(1).join('/')); e.path = path; return e; diff --git a/test/suites/cursor.js b/test/suites/cursor.js index f5bf4e9..fc6134e 100644 --- a/test/suites/cursor.js +++ b/test/suites/cursor.js @@ -172,7 +172,7 @@ describe('Cursor API', function() { assert.throws(function() { oneCursor.push('test'); - }, /non-array/); + }, /target/); }); it('should throw an error when trying to unshift to a non-array.', function() { @@ -181,7 +181,7 @@ describe('Cursor API', function() { assert.throws(function() { oneCursor.unshift('test'); - }, /non-array/); + }, /target/); }); it('should be possible to chain mutations.', function(done) { @@ -511,18 +511,6 @@ describe('Cursor API', function() { }, 0); }); - it('should be possible to push several values through polymorphism.', function(done) { - var baobab = new Baobab({colors: ['blue']}), - colorCursor = baobab.select('colors'); - - colorCursor.push('yellow', 'green'); - - setTimeout(function() { - assert.deepEqual(colorCursor.get(), ['blue', 'yellow', 'green']); - done(); - }, 0); - }); - it('an upper set should correctly resolve.', function(done) { var baobab = new Baobab({hello: {color: 'blue'}}); From e22b6eef3dcbe9350cf25bf05e7c653a295fa098 Mon Sep 17 00:00:00 2001 From: Yomguithereal Date: Wed, 1 Apr 2015 18:08:34 +0200 Subject: [PATCH 23/73] $cursor command for cursor.get --- build/baobab.min.js | 2 +- src/cursor.js | 2 +- src/helpers.js | 18 +++++++++++++++--- test/state.js | 1 + test/suites/cursor.js | 12 ++++++++++++ 5 files changed, 30 insertions(+), 5 deletions(-) diff --git a/build/baobab.min.js b/build/baobab.min.js index 807a71f..613a22e 100644 --- a/build/baobab.min.js +++ b/build/baobab.min.js @@ -1,2 +1,2 @@ /* baobab.js - Version: 1.0.0-rc1 - Author: Yomguithereal (Guillaume Plique) */ -!function(t){if("object"==typeof exports&&"undefined"!=typeof module)module.exports=t();else if("function"==typeof define&&define.amd)define([],t);else{var r;r="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:this,r.Baobab=t()}}(function(){var t;return function r(t,e,n){function i(s,a){if(!e[s]){if(!t[s]){var h="function"==typeof require&&require;if(!a&&h)return h(s,!0);if(o)return o(s,!0);var u=new Error("Cannot find module '"+s+"'");throw u.code="MODULE_NOT_FOUND",u}var c=e[s]={exports:{}};t[s][0].call(c.exports,function(r){var e=t[s][1][r];return i(e?e:r)},c,c.exports,r,t,e,n)}return e[s].exports}for(var o="function"==typeof require&&require,s=0;sr;r++)n.push(t[r].handler);return n}var i={once:"boolean",scope:"object"},o=function(){this._enabled=!0,this._children=[],this._handlers={},this._handlersAll=[]};o.prototype.on=function(t,r,e){var n,s,a,h,u,c;if("function"==typeof r){for(u="string"==typeof t?[t]:t,n=0,s=u.length;n!==s;n+=1)if(h=u[n]){this._handlers[h]||(this._handlers[h]=[]),c={handler:r};for(a in e||{}){if(!i[a])throw new Error('The option "'+a+'" is not recognized by Emmett.');c[a]=e[a]}this._handlers[h].push(c)}}else if(t&&"object"==typeof t&&!Array.isArray(t))for(h in t)o.prototype.on.call(this,h,t[h],r);else{if("function"!=typeof t)throw new Error("Wrong arguments.");c={handler:t};for(a in e||{}){if(!i[a])throw new Error('The option "'+a+'" is not recognized by Emmett.');c[a]=e[a]}this._handlersAll.push(c)}return this},o.prototype.once=function(t,r,e){if("function"==typeof r)e=e||{},e.once=!0,this.on(t,r,e);else{if((!t||"object"!=typeof t||Array.isArray(t))&&"function"!=typeof t)throw new Error("Wrong arguments.");r=r||{},r.once=!0,this.on(t,r)}return this},o.prototype.off=function(t,r){var e,n,i,o,s,a,h,u="string"==typeof t?[t]:t;if(1===arguments.length&&"function"==typeof u){r=arguments[0];for(s in this._handlers){for(a=[],e=0,n=this._handlers[s].length;e!==n;e+=1)this._handlers[s][e].handler!==r&&a.push(this._handlers[s][e]);this._handlers[s]=a}for(a=[],e=0,n=this._handlersAll.length;e!==n;e+=1)this._handlersAll[e].handler!==r&&a.push(this._handlersAll[e]);this._handlersAll=a}else if(2===arguments.length)for(e=0,n=u.length;e!==n;e+=1){if(h=u[e],this._handlers[h]){for(a=[],i=0,o=this._handlers[h].length;i!==o;i+=1)this._handlers[h][i].handler!==r&&a.push(this._handlers[h][i]);this._handlers[h]=a}this._handlers[h]&&0===this._handlers[h].length&&delete this._handlers[h]}return this},o.prototype.unbindAll=function(){var t;this._handlersAll=[];for(t in this._handlers)delete this._handlers[t];return this},o.prototype.emit=function(t,r){var e,n,i,o,s,a,h,u,c,l,f="string"==typeof t?[t]:t;if(!this._enabled)return this;for(r=void 0===r?{}:r,e=0,n=f.length;e!==n;e+=1)if(l=f[e],c=(this._handlers[l]||[]).concat(this._handlersAll),c.length){for(h={type:l,data:r||{},target:this},a=[],i=0,o=c.length;i!==o;i+=1)(this._handlers[l]&&this._handlers[l].indexOf(c[i])>=0||this._handlersAll.indexOf(c[i])>=0)&&(c[i].handler.call("scope"in c[i]?c[i].scope:this,h),c[i].once&&a.push(c[i]));for(s=0;se;e++)if(t._children[e]===r){t._children.splice(e,1);break}}),this._children.push(r),r},o.prototype.listeners=function(t){var e,n,i,o=[];if(t)for(o=r(this._handlers[t]),n=0,i=this._children.length;i>n;n++)o=o.concat(this._children[n].listeners(t));else{o=r(this._handlersAll);for(e in this._handlers)o=o.concat(r(this._handlers[e]));for(n=0,i=this._children.length;i>n;n++)o=o.concat(this._children[n].listeners())}return o},o.prototype.kill=function(){if(this.emit("emmett:kill"),this.unbindAll(),this._handlers=null,this._handlersAll=null,this._enabled=!1,this._children)for(var t=0,r=this._children.length;r>t;t++)this._children[t].kill();this._children=null},o.prototype.disable=function(){return this._enabled=!1,this},o.prototype.enable=function(){return this._enabled=!0,this},o.version="2.1.2","undefined"!=typeof n?("undefined"!=typeof e&&e.exports&&(n=e.exports=o),n.Emitter=o):"function"==typeof t&&t.amd?t("emmett",[],function(){return o}):this.Emitter=o}).call(this)},{}],4:[function(t,r){function e(t){return t+"$"+(new Date).getTime()+(""+Math.random()).replace("0.","")}function n(t,r){function e(t){this[t]=function(){var r=this.root[t].apply(this.root,arguments);return r instanceof i?this:r}}if(arguments.length<1&&(t={}),!(this instanceof n))return new n(t,r);if(!l.Object(t)&&!l.Array(t))throw Error("Baobab: invalid data.");o.call(this),this.options=s.shallowMerge(c,r),this._transaction={},this._future=void 0,this._cursors={},this.data=s.deepClone(t),this.root=this.select([]),["get","set","unset","update"].forEach(e.bind(this)),this.mixin=u.baobab(this)}var i=t("./cursor.js"),o=t("emmett"),s=t("./helpers.js"),a=t("./update.js"),h=t("./merge.js"),u=t("./mixins.js"),c=t("../defaults.js"),l=t("./type.js");s.inherits(n,o),n.prototype.select=function(t){if(!t)throw Error("Baobab.select: invalid path.");if(arguments.length>1&&(t=s.arrayOf(arguments)),!l.Path(t))throw Error("Baobab.select: invalid path.");t=[].concat(t);var r,n=l.ComplexPath(t);n&&(r=s.solvePath(this.data,t));var o=t.map(function(t){return l.Function(t)?e("fn"):l.Object(t)?e("ob"):t}).join("λ");if(this._cursors[o])return this._cursors[o];var a=new i(this,t,r,o);return this._cursors[o]=a,a},n.prototype.stack=function(t){var r=this;if(!l.Object(t))throw Error("Baobab.update: wrong specification.");return this._transaction=h(t,this._transaction),this.options.autoCommit?this.options.asynchronous?(this._future||(this._future=setTimeout(r.commit.bind(r,null),0)),this):this.commit():this},n.prototype.commit=function(){var t=a(this.data,this._transaction,this.options);return this.data=t.data,this._transaction={},this._future&&(this._future=clearTimeout(this._future)),this.emit("update",{log:t.log}),this},n.prototype.release=function(){delete this.data,delete this._transaction;for(var t in this._cursors)this._cursors[t].release();delete this._cursors,this.kill()},n.prototype.toJSON=function(){return this.get()},r.exports=n},{"../defaults.js":1,"./cursor.js":6,"./helpers.js":7,"./merge.js":8,"./mixins.js":9,"./type.js":10,"./update.js":11,emmett:3}],5:[function(t,r){function e(t,r){r.on("update",t.cursorListener),t.tree.off("update",t.treeListener),t.tree.on("update",t.treeListener)}function n(t){var r=this;if(arguments.length<2)throw Error("baobab.Combination: not enough arguments.");var n=arguments[1],i=s.arrayOf(arguments).slice(2);if(n instanceof Array&&(i=n.slice(1),n=n[0]),!a.Cursor(n))throw Error("baobab.Combination: argument should be a cursor.");if("or"!==t&&"and"!==t)throw Error("baobab.Combination: invalid operator.");o.call(this),this.cursors=[n],this.operators=[],this.tree=n.tree,this.updates=new Array(this.cursors.length),this.cursorListener=function(){r.updates[r.cursors.indexOf(this)]=!0},this.treeListener=function(){var t,e,n=r.updates[0];for(t=1,e=r.cursors.length;e>t;t++)n="or"===r.operators[t-1]?n||r.updates[t]:n&&r.updates[t];n&&r.emit("update"),r.updates=new Array(r.cursors.length)},this.bound=!1;var h=(this.on,this.once,function(){r.bound||(r.bound=!0,r.cursors.forEach(function(t){e(r,t)}))});this.on=s.before(h,this.on.bind(this)),this.once=s.before(h,this.once.bind(this)),i.forEach(function(r){this[t](r)},this)}function i(t){n.prototype[t]=function(r){if(!a.Cursor(r))throw this.release(),Error("baobab.Combination."+t+": argument should be a cursor.");if(~this.cursors.indexOf(r))throw this.release(),Error("baobab.Combination."+t+": cursor already in combination.");return this.cursors.push(r),this.operators.push(t),this.updates.length++,this.bound&&e(this,r),this}}var o=t("emmett"),s=t("./helpers.js"),a=t("./type.js");s.inherits(n,o),i("or"),i("and"),n.prototype.release=function(){this.cursors.forEach(function(t){t.off("update",this.cursorListener)},this),this.tree.off("update",this.treeListener),this.cursors=null,this.operators=null,this.tree=null,this.updates=null,this.kill()},r.exports=n},{"./helpers.js":7,"./type.js":10,emmett:3}],6:[function(t,r){function e(t,r,e,n){var i=this;o.call(this),r=r||[],this.tree=t,this.path=r,this.hash=n,this.complexPath=!!e,this.solvedPath=this.complexPath?e:this.path,this.relevant=void 0!==this.get(),this.updateHandler=function(t){var r,e,n,o,s,a,u=t.data.log,c=!1;if(i.complexPath&&(i.solvedPath=h.solvePath(i.tree.data,i.path)),!i.path.length)return i.emit("update");t:for(s=0,n=u.length;n>s;s++)for(r=u[s],a=0,o=r.length;o>a&&(e=r[a],e===""+i.solvedPath[a]);a++)if(a+1===o||a+1===i.solvedPath.length){c=!0;break t}var l=void 0!==i.get();i.relevant?l&&c?i.emit("update"):l||(i.emit("irrelevant"),i.relevant=!1):l&&c&&(i.emit("relevant"),i.emit("update"),i.relevant=!0)},this.mixin=a.cursor(this);var s=!1,u=function(){s||(s=!0,i.tree.on("update",i.updateHandler))};this.on=h.before(u,this.on.bind(this)),this.once=h.before(u,this.once.bind(this))}function n(t,r,e,n){arguments.length<4&&(n=e,e=[]),e=e||[];var i=[].concat(e),o=h.solvePath(this.get(),i);if(!o)throw Error("baobab.Cursor."+t+": could not solve dynamic path.");if(r){var s=this.get(o);if(!u[r](s))throw Error("baobab.Cursor."+t+": invalid target.")}var a={};a["$"+t]=n;var c=h.pathObject(o,a);return c}function i(t,r){e.prototype[t]=function(){var e=n.bind(this,t,r).apply(this,arguments);return this.update(e)}}var o=t("emmett"),s=t("./combination.js"),a=t("./mixins.js"),h=t("./helpers.js"),u=t("./type.js");h.inherits(e,o),e.prototype.isRoot=function(){return!this.path.length},e.prototype.isLeaf=function(){return u.Primitive(this.get())},e.prototype.isBranch=function(){return!this.isLeaf()&&!this.isRoot()},e.prototype.root=function(){return this.tree.root()},e.prototype.select=function(t){if(arguments.length>1&&(t=h.arrayOf(arguments)),!u.Path(t))throw Error("baobab.Cursor.select: invalid path.");return this.tree.select(this.path.concat(t))},e.prototype.up=function(){return this.solvedPath&&this.solvedPath.length?this.tree.select(this.path.slice(0,-1)):null},e.prototype.left=function(){var t=+this.solvedPath[this.solvedPath.length-1];if(isNaN(t))throw Error("baobab.Cursor.left: cannot go left on a non-list type.");return t?this.tree.select(this.solvedPath.slice(0,-1).concat(t-1)):null},e.prototype.leftmost=function(){var t=+this.solvedPath[this.solvedPath.length-1];if(isNaN(t))throw Error("baobab.Cursor.leftmost: cannot go left on a non-list type.");return this.tree.select(this.solvedPath.slice(0,-1).concat(0))},e.prototype.right=function(){var t=+this.solvedPath[this.solvedPath.length-1];if(isNaN(t))throw Error("baobab.Cursor.right: cannot go right on a non-list type.");return t+1===this.up().get().length?null:this.tree.select(this.solvedPath.slice(0,-1).concat(t+1))},e.prototype.rightmost=function(){var t=+this.solvedPath[this.solvedPath.length-1];if(isNaN(t))throw Error("baobab.Cursor.right: cannot go right on a non-list type.");var r=this.up().get();return this.tree.select(this.solvedPath.slice(0,-1).concat(r.length-1))},e.prototype.down=function(){+this.solvedPath[this.solvedPath.length-1];return this.get()instanceof Array?this.tree.select(this.solvedPath.concat(0)):null},e.prototype.get=function(t){arguments.length>1&&(t=h.arrayOf(arguments));var r=this.solvedPath.concat((u.String(t)||u.Number(t)?[t]:t)||[]);return h.getIn(this.tree.data,r)},i("set"),i("apply"),i("chain"),i("push","Array"),i("unshift","Array"),e.prototype.merge=function(t){if(!u.Object(t))throw Error("baobab.Cursor.merge: trying to merge a non-object.");var r=n.bind(this,"merge","Object").apply(this,arguments);return this.update(r)},e.prototype.unset=function(t){if(void 0===t&&this.isRoot())throw Error("baobab.Cursor.unset: cannot remove root node.");var r=n.bind(this,"unset",null).apply(this,[t,!0]);return this.update(r)},e.prototype.update=function(t,r){if(arguments.length<2)return this.tree.stack(h.pathObject(this.solvedPath,t)),this;var e=[].concat(t),n=h.solvePath(this.get(),e);if(!n)throw Error("baobab.Cursor.update: could not solve dynamic path.");return this.tree.stack(h.pathObject(this.solvedPath.concat(n),r)),this},e.prototype.or=function(t){return new s("or",this,t)},e.prototype.and=function(t){return new s("and",this,t)},e.prototype.release=function(){this.tree.off("update",this.updateHandler),this.hash&&delete this.tree._cursors[this.hash],delete this.tree,delete this.path,delete this.solvedPath,this.kill()},e.prototype.toJSON=function(){return this.get()},u.Cursor=function(t){return t instanceof e},r.exports=e},{"./combination.js":5,"./helpers.js":7,"./mixins.js":9,"./type.js":10,emmett:3}],7:[function(t,r){function e(t){return Array.prototype.slice.call(t)}function n(t,r){return function(){t(),r.apply(null,arguments)}}function i(t,r){var e,n={};for(e in t)n[e]=t[e];for(e in r)n[e]=r[e];return n}function o(t){var r=t.source,e="";return t.global&&(e+="g"),t.multiline&&(e+="m"),t.ignoreCase&&(e+="i"),t.sticky&&(e+="y"),t.unicode&&(e+="u"),new RegExp(r,e)}function s(t,r){if(!r||"object"!=typeof r||r instanceof Error||r instanceof ArrayBuffer)return r;if(m.Array(r)){if(t){var e,n,i=[];for(e=0,n=r.length;n>e;e++)i.push(v(r[e]));return i}return r.slice(0)}if(m.Date(r))return new Date(r.getTime());if(r instanceof RegExp)return o(r);if(m.Object(r)){var s,a={};r.constructor&&r.constructor!==Object&&(a=Object.create(r.constructor.prototype));for(s in r)r.hasOwnProperty(s)&&(a[s]=t?v(r[s]):r[s]);return a}return r}function a(t,r){return function(e){return r(t(e))}}function h(t,r){var e,n;for(e=0,n=t.length;n>e;e++)if(r(t[e]))return t[e]}function u(t,r){var e,n;for(e=0,n=t.length;n>e;e++)if(r(t[e]))return e;return-1}function c(t,r){var e,n=!0;if(!t)return!1;for(e in r)if(m.Object(r[e]))n=n&&c(t[e],r[e]);else if(m.Array(r[e]))n=n&&!!~r[e].indexOf(t[e]);else if(t[e]!==r[e])return!1;return n}function l(t,r){return h(t,function(t){return c(t,r)})}function f(t,r){return u(t,function(t){return c(t,r)})}function p(t,r){r=r||[];var e,n,i=t;for(e=0,n=r.length;n>e;e++){if(!i)return;if("function"==typeof r[e]){if(!m.Array(i))return;i=h(i,r[e])}else if("object"==typeof r[e]){if(!m.Array(i))return;i=l(i,r[e])}else i=i[r[e]]}return i}function d(t,r){var e,n,i,o=[],s=t;for(n=0,i=r.length;i>n;n++){if(!s)return null;if("function"==typeof r[n]){if(!m.Array(s))return;e=u(s,r[n]),o.push(e),s=s[e]}else if("object"==typeof r[n]){if(!m.Array(s))return;e=f(s,r[n]),o.push(e),s=s[e]}else o.push(r[n]),s=s[r[n]]||{}}return o}function b(t,r){var e,n=t.length,i={},o=i;for(n||(i=r),e=0;n>e;e++)o[t[e]]=e+1===n?r:{},o=o[t[e]];return i}function y(t,r){t.super_=r;var e=function(){};e.prototype=r.prototype,t.prototype=new e,t.prototype.constructor=t}var m=t("./type.js"),g=s.bind(null,!1),v=s.bind(null,!0);r.exports={arrayOf:e,before:n,deepClone:v,shallowClone:g,shallowMerge:i,compose:a,getIn:p,inherits:y,pathObject:b,solvePath:d}},{"./type.js":10}],8:[function(t,r){function e(t,r,e){s.forEach(function(r){e!==r&&delete t[r]}),t[e]=r[e]}function n(t,r){var a,h=i.shallowClone(r||{});s.forEach(function(r){t[r]&&e(h,t,r)}),t.$chain&&(s.slice(0,-1).forEach(function(t){delete h[t]}),h.$apply=h.$apply?i.compose(h.$apply,t.$chain):t.$chain),t.$push&&h.$push?h.$push=o.Array(h.$push)?h.$push.concat(t.$push):[h.$push].concat(t.$push):t.$push&&(h.$push=t.$push),t.$unshift&&h.$unshift?h.$unshift=o.Array(t.$unshift)?t.$unshift.concat(h.$unshift):[t.$unshift].concat(h.$unshift):t.$unshift&&(h.$unshift=t.$unshift);for(a in t)o.Object(t[a])?h[a]=n(t[a],h[a]):"$"!==a[0]&&(h[a]=t[a]);return h}var i=t("./helpers.js"),o=t("./type.js"),s=["$unset","$set","$merge","$apply"];r.exports=n},{"./helpers.js":7,"./type.js":10}],9:[function(t,r){var e=t("./combination.js"),n=t("./type.js");r.exports={baobab:function(t){return{mixins:[{getInitialState:function(){if(this.tree=t,!this.cursor&&!this.cursors)return{};if(this.cursor&&this.cursors)throw Error("baobab.mixin: you cannot have both `component.cursor` and `component.cursors`. Please make up your mind.");if(this.__type=null,this.__updateHandler=function(){this.setState(this.__getCursorData())}.bind(this),this.cursor){if(!n.MixinCursor(this.cursor))throw Error("baobab.mixin.cursor: invalid data (cursor, string, array or function).");n.Function(this.cursor)&&(this.cursor=this.cursor()),n.Cursor(this.cursor)||(this.cursor=t.select(this.cursor)),this.__getCursorData=function(){return{cursor:this.cursor.get()}}.bind(this),this.__type="single"}else if(this.cursors){if(!n.MixinCursors(this.cursors))throw Error("baobab.mixin.cursor: invalid data (object, array or function).");if(n.Function(this.cursors)&&(this.cursors=this.cursors()),n.Array(this.cursors))this.cursors=this.cursors.map(function(r){return n.Cursor(r)?r:t.select(r)}),this.__getCursorData=function(){return{cursors:this.cursors.map(function(t){return t.get()})}}.bind(this),this.__type="array";else{for(var r in this.cursors)n.Cursor(this.cursors[r])||(this.cursors[r]=t.select(this.cursors[r]));this.__getCursorData=function(){var t={};for(r in this.cursors)t[r]=this.cursors[r].get();return{cursors:t}}.bind(this),this.__type="object"}}return this.__getCursorData()},componentDidMount:function(){"single"===this.__type?(this.__combination=new e("or",[this.cursor]),this.__combination.on("update",this.__updateHandler)):"array"===this.__type?(this.__combination=new e("or",this.cursors),this.__combination.on("update",this.__updateHandler)):"object"===this.__type&&(this.__combination=new e("or",Object.keys(this.cursors).map(function(t){return this.cursors[t]},this)),this.__combination.on("update",this.__updateHandler))},componentWillUnmount:function(){this.__combination&&this.__combination.release()}}].concat(t.options.mixins)}},cursor:function(t){return{mixins:[{getInitialState:function(){return this.cursor=t,this.__updateHandler=function(){this.setState({cursor:this.cursor.get()})}.bind(this),{cursor:this.cursor.get()}},componentDidMount:function(){this.cursor.on("update",this.__updateHandler)},componentWillUnmount:function(){this.cursor.off("update",this.__updateHandler)}}].concat(t.tree.options.mixins)}}}},{"./combination.js":5,"./type.js":10}],10:[function(t,r){function e(t,r){return r.some(function(r){return n[r](t)})}var n={};n.Array=function(t){return Array.isArray(t)},n.Object=function(t){return!Array.isArray(t)&&"object"==typeof t&&null!==t},n.String=function(t){return"string"==typeof t},n.Number=function(t){return"number"==typeof t},n.Function=function(t){return"function"==typeof t},n.Primitive=function(t){return"string"==typeof t||"number"==typeof t||"boolean"==typeof t},n.Date=function(t){return t instanceof Date},n.NonScalar=function(t){return n.Object(t)||n.Array(t)},n.Path=function(t){var r=["String","Number","Function","Object"];return n.Array(t)?t.every(function(t){return e(t,r)}):e(t,r)},n.MixinCursor=function(t){return e(t,["String","Number","Array","Function","Cursor"])},n.MixinCursors=function(t){return e(t,["Object","Array","Function"])},n.ComplexPath=function(t){return e(t,["Object","Function"])},r.exports=n},{}],11:[function(t,r){function e(t,r){var e=new Error("baobab.update: "+r+" at path /"+t.slice(1).join("/"));return e.path=t,e}var n=t("./helpers.js"),i=t("./type.js");r.exports=function(t,r,o){if(o=o||{},!i.Object(t)&&!i.Array(t))throw Error("baobab.update: invalid target.");var s={};t={root:n.shallowClone(t)};var a=function(t,r,o,h){o=o||["root"];var u,c,l,f=o.join("λ"),p=o[o.length-1],d=Object.keys(r).some(function(t){return!!~["$unset","$set","$apply","$merge","$push","$unshift"].indexOf(t)});if(d){s[f]=!0;for(c in r){if("$unset"===c){var b=o[o.length-2];i.Array(t)?h[b]=t.slice(0,+p).concat(t.slice(+p+1)):(h[b]=n.shallowClone(t),delete h[b][p]);break}if("$set"===c){l=r.$set,t[p]=l;break}if("$apply"===c){if(u=r.$apply,"function"!=typeof u)throw e(o,"using command $apply with a non function");t[p]=u.call(null,t[p]);break}if("$merge"===c){if(l=r.$merge,!i.Object(t[p])||!i.Object(l))throw e(o,"using command $merge with a non object");t[p]=n.shallowMerge(t[p],l);break}if("$push"===c){if(l=r.$push,!i.Array(t[p]))throw e(o,"using command $push to a non array");t[p]=t[p].concat(l)}if("$unshift"===c){if(l=r.$unshift,!i.Array(t[p]))throw e(o,"using command $unshift to a non array");t[p]=[].concat(l).concat(t[p])}}}else for(c in r)t[p][c]="undefined"==typeof t[p][c]?{}:n.shallowClone(t[p][c]),a(t[p],r[c],o.concat(c),t)};return a(t,r),{data:t.root,log:Object.keys(s).map(function(t){return t.split("λ").slice(1)})}}},{"./helpers.js":7,"./type.js":10}]},{},[2])(2)}); \ No newline at end of file +!function(t){if("object"==typeof exports&&"undefined"!=typeof module)module.exports=t();else if("function"==typeof define&&define.amd)define([],t);else{var r;r="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:this,r.Baobab=t()}}(function(){var t;return function r(t,e,n){function i(s,a){if(!e[s]){if(!t[s]){var h="function"==typeof require&&require;if(!a&&h)return h(s,!0);if(o)return o(s,!0);var u=new Error("Cannot find module '"+s+"'");throw u.code="MODULE_NOT_FOUND",u}var c=e[s]={exports:{}};t[s][0].call(c.exports,function(r){var e=t[s][1][r];return i(e?e:r)},c,c.exports,r,t,e,n)}return e[s].exports}for(var o="function"==typeof require&&require,s=0;sr;r++)n.push(t[r].handler);return n}var i={once:"boolean",scope:"object"},o=function(){this._enabled=!0,this._children=[],this._handlers={},this._handlersAll=[]};o.prototype.on=function(t,r,e){var n,s,a,h,u,c;if("function"==typeof r){for(u="string"==typeof t?[t]:t,n=0,s=u.length;n!==s;n+=1)if(h=u[n]){this._handlers[h]||(this._handlers[h]=[]),c={handler:r};for(a in e||{}){if(!i[a])throw new Error('The option "'+a+'" is not recognized by Emmett.');c[a]=e[a]}this._handlers[h].push(c)}}else if(t&&"object"==typeof t&&!Array.isArray(t))for(h in t)o.prototype.on.call(this,h,t[h],r);else{if("function"!=typeof t)throw new Error("Wrong arguments.");c={handler:t};for(a in e||{}){if(!i[a])throw new Error('The option "'+a+'" is not recognized by Emmett.');c[a]=e[a]}this._handlersAll.push(c)}return this},o.prototype.once=function(t,r,e){if("function"==typeof r)e=e||{},e.once=!0,this.on(t,r,e);else{if((!t||"object"!=typeof t||Array.isArray(t))&&"function"!=typeof t)throw new Error("Wrong arguments.");r=r||{},r.once=!0,this.on(t,r)}return this},o.prototype.off=function(t,r){var e,n,i,o,s,a,h,u="string"==typeof t?[t]:t;if(1===arguments.length&&"function"==typeof u){r=arguments[0];for(s in this._handlers){for(a=[],e=0,n=this._handlers[s].length;e!==n;e+=1)this._handlers[s][e].handler!==r&&a.push(this._handlers[s][e]);this._handlers[s]=a}for(a=[],e=0,n=this._handlersAll.length;e!==n;e+=1)this._handlersAll[e].handler!==r&&a.push(this._handlersAll[e]);this._handlersAll=a}else if(2===arguments.length)for(e=0,n=u.length;e!==n;e+=1){if(h=u[e],this._handlers[h]){for(a=[],i=0,o=this._handlers[h].length;i!==o;i+=1)this._handlers[h][i].handler!==r&&a.push(this._handlers[h][i]);this._handlers[h]=a}this._handlers[h]&&0===this._handlers[h].length&&delete this._handlers[h]}return this},o.prototype.unbindAll=function(){var t;this._handlersAll=[];for(t in this._handlers)delete this._handlers[t];return this},o.prototype.emit=function(t,r){var e,n,i,o,s,a,h,u,c,l,f="string"==typeof t?[t]:t;if(!this._enabled)return this;for(r=void 0===r?{}:r,e=0,n=f.length;e!==n;e+=1)if(l=f[e],c=(this._handlers[l]||[]).concat(this._handlersAll),c.length){for(h={type:l,data:r||{},target:this},a=[],i=0,o=c.length;i!==o;i+=1)(this._handlers[l]&&this._handlers[l].indexOf(c[i])>=0||this._handlersAll.indexOf(c[i])>=0)&&(c[i].handler.call("scope"in c[i]?c[i].scope:this,h),c[i].once&&a.push(c[i]));for(s=0;se;e++)if(t._children[e]===r){t._children.splice(e,1);break}}),this._children.push(r),r},o.prototype.listeners=function(t){var e,n,i,o=[];if(t)for(o=r(this._handlers[t]),n=0,i=this._children.length;i>n;n++)o=o.concat(this._children[n].listeners(t));else{o=r(this._handlersAll);for(e in this._handlers)o=o.concat(r(this._handlers[e]));for(n=0,i=this._children.length;i>n;n++)o=o.concat(this._children[n].listeners())}return o},o.prototype.kill=function(){if(this.emit("emmett:kill"),this.unbindAll(),this._handlers=null,this._handlersAll=null,this._enabled=!1,this._children)for(var t=0,r=this._children.length;r>t;t++)this._children[t].kill();this._children=null},o.prototype.disable=function(){return this._enabled=!1,this},o.prototype.enable=function(){return this._enabled=!0,this},o.version="2.1.2","undefined"!=typeof n?("undefined"!=typeof e&&e.exports&&(n=e.exports=o),n.Emitter=o):"function"==typeof t&&t.amd?t("emmett",[],function(){return o}):this.Emitter=o}).call(this)},{}],4:[function(t,r){function e(t){return t+"$"+(new Date).getTime()+(""+Math.random()).replace("0.","")}function n(t,r){function e(t){this[t]=function(){var r=this.root[t].apply(this.root,arguments);return r instanceof i?this:r}}if(arguments.length<1&&(t={}),!(this instanceof n))return new n(t,r);if(!l.Object(t)&&!l.Array(t))throw Error("Baobab: invalid data.");o.call(this),this.options=s.shallowMerge(c,r),this._transaction={},this._future=void 0,this._cursors={},this.data=s.deepClone(t),this.root=this.select([]),["get","set","unset","update"].forEach(e.bind(this)),this.mixin=u.baobab(this)}var i=t("./cursor.js"),o=t("emmett"),s=t("./helpers.js"),a=t("./update.js"),h=t("./merge.js"),u=t("./mixins.js"),c=t("../defaults.js"),l=t("./type.js");s.inherits(n,o),n.prototype.select=function(t){if(!t)throw Error("Baobab.select: invalid path.");if(arguments.length>1&&(t=s.arrayOf(arguments)),!l.Path(t))throw Error("Baobab.select: invalid path.");t=[].concat(t);var r,n=l.ComplexPath(t);n&&(r=s.solvePath(this.data,t));var o=t.map(function(t){return l.Function(t)?e("fn"):l.Object(t)?e("ob"):t}).join("λ");if(this._cursors[o])return this._cursors[o];var a=new i(this,t,r,o);return this._cursors[o]=a,a},n.prototype.stack=function(t){var r=this;if(!l.Object(t))throw Error("Baobab.update: wrong specification.");return this._transaction=h(t,this._transaction),this.options.autoCommit?this.options.asynchronous?(this._future||(this._future=setTimeout(r.commit.bind(r,null),0)),this):this.commit():this},n.prototype.commit=function(){var t=a(this.data,this._transaction,this.options);return this.data=t.data,this._transaction={},this._future&&(this._future=clearTimeout(this._future)),this.emit("update",{log:t.log}),this},n.prototype.release=function(){delete this.data,delete this._transaction;for(var t in this._cursors)this._cursors[t].release();delete this._cursors,this.kill()},n.prototype.toJSON=function(){return this.get()},r.exports=n},{"../defaults.js":1,"./cursor.js":6,"./helpers.js":7,"./merge.js":8,"./mixins.js":9,"./type.js":10,"./update.js":11,emmett:3}],5:[function(t,r){function e(t,r){r.on("update",t.cursorListener),t.tree.off("update",t.treeListener),t.tree.on("update",t.treeListener)}function n(t){var r=this;if(arguments.length<2)throw Error("baobab.Combination: not enough arguments.");var n=arguments[1],i=s.arrayOf(arguments).slice(2);if(n instanceof Array&&(i=n.slice(1),n=n[0]),!a.Cursor(n))throw Error("baobab.Combination: argument should be a cursor.");if("or"!==t&&"and"!==t)throw Error("baobab.Combination: invalid operator.");o.call(this),this.cursors=[n],this.operators=[],this.tree=n.tree,this.updates=new Array(this.cursors.length),this.cursorListener=function(){r.updates[r.cursors.indexOf(this)]=!0},this.treeListener=function(){var t,e,n=r.updates[0];for(t=1,e=r.cursors.length;e>t;t++)n="or"===r.operators[t-1]?n||r.updates[t]:n&&r.updates[t];n&&r.emit("update"),r.updates=new Array(r.cursors.length)},this.bound=!1;var h=(this.on,this.once,function(){r.bound||(r.bound=!0,r.cursors.forEach(function(t){e(r,t)}))});this.on=s.before(h,this.on.bind(this)),this.once=s.before(h,this.once.bind(this)),i.forEach(function(r){this[t](r)},this)}function i(t){n.prototype[t]=function(r){if(!a.Cursor(r))throw this.release(),Error("baobab.Combination."+t+": argument should be a cursor.");if(~this.cursors.indexOf(r))throw this.release(),Error("baobab.Combination."+t+": cursor already in combination.");return this.cursors.push(r),this.operators.push(t),this.updates.length++,this.bound&&e(this,r),this}}var o=t("emmett"),s=t("./helpers.js"),a=t("./type.js");s.inherits(n,o),i("or"),i("and"),n.prototype.release=function(){this.cursors.forEach(function(t){t.off("update",this.cursorListener)},this),this.tree.off("update",this.treeListener),this.cursors=null,this.operators=null,this.tree=null,this.updates=null,this.kill()},r.exports=n},{"./helpers.js":7,"./type.js":10,emmett:3}],6:[function(t,r){function e(t,r,e,n){var i=this;o.call(this),r=r||[],this.tree=t,this.path=r,this.hash=n,this.complexPath=!!e,this.solvedPath=this.complexPath?e:this.path,this.relevant=void 0!==this.get(),this.updateHandler=function(t){var r,e,n,o,s,a,u=t.data.log,c=!1;if(i.complexPath&&(i.solvedPath=h.solvePath(i.tree.data,i.path)),!i.path.length)return i.emit("update");t:for(s=0,n=u.length;n>s;s++)for(r=u[s],a=0,o=r.length;o>a&&(e=r[a],e===""+i.solvedPath[a]);a++)if(a+1===o||a+1===i.solvedPath.length){c=!0;break t}var l=void 0!==i.get();i.relevant?l&&c?i.emit("update"):l||(i.emit("irrelevant"),i.relevant=!1):l&&c&&(i.emit("relevant"),i.emit("update"),i.relevant=!0)},this.mixin=a.cursor(this);var s=!1,u=function(){s||(s=!0,i.tree.on("update",i.updateHandler))};this.on=h.before(u,this.on.bind(this)),this.once=h.before(u,this.once.bind(this))}function n(t,r,e,n){arguments.length<4&&(n=e,e=[]),e=e||[];var i=[].concat(e),o=h.solvePath(this.get(),i);if(!o)throw Error("baobab.Cursor."+t+": could not solve dynamic path.");if(r){var s=this.get(o);if(!u[r](s))throw Error("baobab.Cursor."+t+": invalid target.")}var a={};a["$"+t]=n;var c=h.pathObject(o,a);return c}function i(t,r){e.prototype[t]=function(){var e=n.bind(this,t,r).apply(this,arguments);return this.update(e)}}var o=t("emmett"),s=t("./combination.js"),a=t("./mixins.js"),h=t("./helpers.js"),u=t("./type.js");h.inherits(e,o),e.prototype.isRoot=function(){return!this.path.length},e.prototype.isLeaf=function(){return u.Primitive(this.get())},e.prototype.isBranch=function(){return!this.isLeaf()&&!this.isRoot()},e.prototype.root=function(){return this.tree.root()},e.prototype.select=function(t){if(arguments.length>1&&(t=h.arrayOf(arguments)),!u.Path(t))throw Error("baobab.Cursor.select: invalid path.");return this.tree.select(this.path.concat(t))},e.prototype.up=function(){return this.solvedPath&&this.solvedPath.length?this.tree.select(this.path.slice(0,-1)):null},e.prototype.left=function(){var t=+this.solvedPath[this.solvedPath.length-1];if(isNaN(t))throw Error("baobab.Cursor.left: cannot go left on a non-list type.");return t?this.tree.select(this.solvedPath.slice(0,-1).concat(t-1)):null},e.prototype.leftmost=function(){var t=+this.solvedPath[this.solvedPath.length-1];if(isNaN(t))throw Error("baobab.Cursor.leftmost: cannot go left on a non-list type.");return this.tree.select(this.solvedPath.slice(0,-1).concat(0))},e.prototype.right=function(){var t=+this.solvedPath[this.solvedPath.length-1];if(isNaN(t))throw Error("baobab.Cursor.right: cannot go right on a non-list type.");return t+1===this.up().get().length?null:this.tree.select(this.solvedPath.slice(0,-1).concat(t+1))},e.prototype.rightmost=function(){var t=+this.solvedPath[this.solvedPath.length-1];if(isNaN(t))throw Error("baobab.Cursor.right: cannot go right on a non-list type.");var r=this.up().get();return this.tree.select(this.solvedPath.slice(0,-1).concat(r.length-1))},e.prototype.down=function(){+this.solvedPath[this.solvedPath.length-1];return this.get()instanceof Array?this.tree.select(this.solvedPath.concat(0)):null},e.prototype.get=function(t){arguments.length>1&&(t=h.arrayOf(arguments));var r=this.solvedPath.concat((u.String(t)||u.Number(t)?[t]:t)||[]);return h.getIn(this.tree.data,r,this.tree)},i("set"),i("apply"),i("chain"),i("push","Array"),i("unshift","Array"),e.prototype.merge=function(t){if(!u.Object(t))throw Error("baobab.Cursor.merge: trying to merge a non-object.");var r=n.bind(this,"merge","Object").apply(this,arguments);return this.update(r)},e.prototype.unset=function(t){if(void 0===t&&this.isRoot())throw Error("baobab.Cursor.unset: cannot remove root node.");var r=n.bind(this,"unset",null).apply(this,[t,!0]);return this.update(r)},e.prototype.update=function(t,r){if(arguments.length<2)return this.tree.stack(h.pathObject(this.solvedPath,t)),this;var e=[].concat(t),n=h.solvePath(this.get(),e);if(!n)throw Error("baobab.Cursor.update: could not solve dynamic path.");return this.tree.stack(h.pathObject(this.solvedPath.concat(n),r)),this},e.prototype.or=function(t){return new s("or",this,t)},e.prototype.and=function(t){return new s("and",this,t)},e.prototype.release=function(){this.tree.off("update",this.updateHandler),this.hash&&delete this.tree._cursors[this.hash],delete this.tree,delete this.path,delete this.solvedPath,this.kill()},e.prototype.toJSON=function(){return this.get()},u.Cursor=function(t){return t instanceof e},r.exports=e},{"./combination.js":5,"./helpers.js":7,"./mixins.js":9,"./type.js":10,emmett:3}],7:[function(t,r){function e(t){return Array.prototype.slice.call(t)}function n(t,r){return function(){t(),r.apply(null,arguments)}}function i(t,r){var e,n={};for(e in t)n[e]=t[e];for(e in r)n[e]=r[e];return n}function o(t){var r=t.source,e="";return t.global&&(e+="g"),t.multiline&&(e+="m"),t.ignoreCase&&(e+="i"),t.sticky&&(e+="y"),t.unicode&&(e+="u"),new RegExp(r,e)}function s(t,r){if(!r||"object"!=typeof r||r instanceof Error||r instanceof ArrayBuffer)return r;if(m.Array(r)){if(t){var e,n,i=[];for(e=0,n=r.length;n>e;e++)i.push(v(r[e]));return i}return r.slice(0)}if(m.Date(r))return new Date(r.getTime());if(r instanceof RegExp)return o(r);if(m.Object(r)){var s,a={};r.constructor&&r.constructor!==Object&&(a=Object.create(r.constructor.prototype));for(s in r)r.hasOwnProperty(s)&&(a[s]=t?v(r[s]):r[s]);return a}return r}function a(t,r){return function(e){return r(t(e))}}function h(t,r){var e,n;for(e=0,n=t.length;n>e;e++)if(r(t[e]))return t[e]}function u(t,r){var e,n;for(e=0,n=t.length;n>e;e++)if(r(t[e]))return e;return-1}function c(t,r){var e,n=!0;if(!t)return!1;for(e in r)if(m.Object(r[e]))n=n&&c(t[e],r[e]);else if(m.Array(r[e]))n=n&&!!~r[e].indexOf(t[e]);else if(t[e]!==r[e])return!1;return n}function l(t,r){return h(t,function(t){return c(t,r)})}function f(t,r){return u(t,function(t){return c(t,r)})}function p(t,r,e){r=r||[];var n,i,o,s=t;for(i=0,o=r.length;o>i;i++){if(!s)return;if("function"==typeof r[i]){if(!m.Array(s))return;s=h(s,r[i])}else if("object"==typeof r[i])if("$cursor"in r[i]){if(!m.Path(r[i].$cursor))throw Error("baobab.getIn: $cursor path must be an array.");n=e.get(r[i].$cursor),s=s[n]}else{if(!m.Array(s))return;s=l(s,r[i])}else s=s[r[i]]}return s}function d(t,r){var e,n,i,o=[],s=t;for(n=0,i=r.length;i>n;n++){if(!s)return null;if("function"==typeof r[n]){if(!m.Array(s))return;e=u(s,r[n]),o.push(e),s=s[e]}else if("object"==typeof r[n]){if(!m.Array(s))return;e=f(s,r[n]),o.push(e),s=s[e]}else o.push(r[n]),s=s[r[n]]||{}}return o}function b(t,r){var e,n=t.length,i={},o=i;for(n||(i=r),e=0;n>e;e++)o[t[e]]=e+1===n?r:{},o=o[t[e]];return i}function y(t,r){t.super_=r;var e=function(){};e.prototype=r.prototype,t.prototype=new e,t.prototype.constructor=t}var m=t("./type.js"),g=s.bind(null,!1),v=s.bind(null,!0);r.exports={arrayOf:e,before:n,deepClone:v,shallowClone:g,shallowMerge:i,compose:a,getIn:p,inherits:y,pathObject:b,solvePath:d}},{"./type.js":10}],8:[function(t,r){function e(t,r,e){s.forEach(function(r){e!==r&&delete t[r]}),t[e]=r[e]}function n(t,r){var a,h=i.shallowClone(r||{});s.forEach(function(r){t[r]&&e(h,t,r)}),t.$chain&&(s.slice(0,-1).forEach(function(t){delete h[t]}),h.$apply=h.$apply?i.compose(h.$apply,t.$chain):t.$chain),t.$push&&h.$push?h.$push=o.Array(h.$push)?h.$push.concat(t.$push):[h.$push].concat(t.$push):t.$push&&(h.$push=t.$push),t.$unshift&&h.$unshift?h.$unshift=o.Array(t.$unshift)?t.$unshift.concat(h.$unshift):[t.$unshift].concat(h.$unshift):t.$unshift&&(h.$unshift=t.$unshift);for(a in t)o.Object(t[a])?h[a]=n(t[a],h[a]):"$"!==a[0]&&(h[a]=t[a]);return h}var i=t("./helpers.js"),o=t("./type.js"),s=["$unset","$set","$merge","$apply"];r.exports=n},{"./helpers.js":7,"./type.js":10}],9:[function(t,r){var e=t("./combination.js"),n=t("./type.js");r.exports={baobab:function(t){return{mixins:[{getInitialState:function(){if(this.tree=t,!this.cursor&&!this.cursors)return{};if(this.cursor&&this.cursors)throw Error("baobab.mixin: you cannot have both `component.cursor` and `component.cursors`. Please make up your mind.");if(this.__type=null,this.__updateHandler=function(){this.setState(this.__getCursorData())}.bind(this),this.cursor){if(!n.MixinCursor(this.cursor))throw Error("baobab.mixin.cursor: invalid data (cursor, string, array or function).");n.Function(this.cursor)&&(this.cursor=this.cursor()),n.Cursor(this.cursor)||(this.cursor=t.select(this.cursor)),this.__getCursorData=function(){return{cursor:this.cursor.get()}}.bind(this),this.__type="single"}else if(this.cursors){if(!n.MixinCursors(this.cursors))throw Error("baobab.mixin.cursor: invalid data (object, array or function).");if(n.Function(this.cursors)&&(this.cursors=this.cursors()),n.Array(this.cursors))this.cursors=this.cursors.map(function(r){return n.Cursor(r)?r:t.select(r)}),this.__getCursorData=function(){return{cursors:this.cursors.map(function(t){return t.get()})}}.bind(this),this.__type="array";else{for(var r in this.cursors)n.Cursor(this.cursors[r])||(this.cursors[r]=t.select(this.cursors[r]));this.__getCursorData=function(){var t={};for(r in this.cursors)t[r]=this.cursors[r].get();return{cursors:t}}.bind(this),this.__type="object"}}return this.__getCursorData()},componentDidMount:function(){"single"===this.__type?(this.__combination=new e("or",[this.cursor]),this.__combination.on("update",this.__updateHandler)):"array"===this.__type?(this.__combination=new e("or",this.cursors),this.__combination.on("update",this.__updateHandler)):"object"===this.__type&&(this.__combination=new e("or",Object.keys(this.cursors).map(function(t){return this.cursors[t]},this)),this.__combination.on("update",this.__updateHandler))},componentWillUnmount:function(){this.__combination&&this.__combination.release()}}].concat(t.options.mixins)}},cursor:function(t){return{mixins:[{getInitialState:function(){return this.cursor=t,this.__updateHandler=function(){this.setState({cursor:this.cursor.get()})}.bind(this),{cursor:this.cursor.get()}},componentDidMount:function(){this.cursor.on("update",this.__updateHandler)},componentWillUnmount:function(){this.cursor.off("update",this.__updateHandler)}}].concat(t.tree.options.mixins)}}}},{"./combination.js":5,"./type.js":10}],10:[function(t,r){function e(t,r){return r.some(function(r){return n[r](t)})}var n={};n.Array=function(t){return Array.isArray(t)},n.Object=function(t){return!Array.isArray(t)&&"object"==typeof t&&null!==t},n.String=function(t){return"string"==typeof t},n.Number=function(t){return"number"==typeof t},n.Function=function(t){return"function"==typeof t},n.Primitive=function(t){return"string"==typeof t||"number"==typeof t||"boolean"==typeof t},n.Date=function(t){return t instanceof Date},n.NonScalar=function(t){return n.Object(t)||n.Array(t)},n.Path=function(t){var r=["String","Number","Function","Object"];return n.Array(t)?t.every(function(t){return e(t,r)}):e(t,r)},n.MixinCursor=function(t){return e(t,["String","Number","Array","Function","Cursor"])},n.MixinCursors=function(t){return e(t,["Object","Array","Function"])},n.ComplexPath=function(t){return e(t,["Object","Function"])},r.exports=n},{}],11:[function(t,r){function e(t,r){var e=new Error("baobab.update: "+r+" at path /"+t.slice(1).join("/"));return e.path=t,e}var n=t("./helpers.js"),i=t("./type.js");r.exports=function(t,r,o){if(o=o||{},!i.Object(t)&&!i.Array(t))throw Error("baobab.update: invalid target.");var s={};t={root:n.shallowClone(t)};var a=function(t,r,o,h){o=o||["root"];var u,c,l,f=o.join("λ"),p=o[o.length-1],d=Object.keys(r).some(function(t){return!!~["$unset","$set","$apply","$merge","$push","$unshift"].indexOf(t)});if(d){s[f]=!0;for(c in r){if("$unset"===c){var b=o[o.length-2];i.Array(t)?h[b]=t.slice(0,+p).concat(t.slice(+p+1)):(h[b]=n.shallowClone(t),delete h[b][p]);break}if("$set"===c){l=r.$set,t[p]=l;break}if("$apply"===c){if(u=r.$apply,"function"!=typeof u)throw e(o,"using command $apply with a non function");t[p]=u.call(null,t[p]);break}if("$merge"===c){if(l=r.$merge,!i.Object(t[p])||!i.Object(l))throw e(o,"using command $merge with a non object");t[p]=n.shallowMerge(t[p],l);break}if("$push"===c){if(l=r.$push,!i.Array(t[p]))throw e(o,"using command $push to a non array");t[p]=t[p].concat(l)}if("$unshift"===c){if(l=r.$unshift,!i.Array(t[p]))throw e(o,"using command $unshift to a non array");t[p]=[].concat(l).concat(t[p])}}}else for(c in r)t[p][c]="undefined"==typeof t[p][c]?{}:n.shallowClone(t[p][c]),a(t[p],r[c],o.concat(c),t)};return a(t,r),{data:t.root,log:Object.keys(s).map(function(t){return t.split("λ").slice(1)})}}},{"./helpers.js":7,"./type.js":10}]},{},[2])(2)}); \ No newline at end of file diff --git a/src/cursor.js b/src/cursor.js index b9ff550..34d7bf1 100644 --- a/src/cursor.js +++ b/src/cursor.js @@ -209,7 +209,7 @@ Cursor.prototype.get = function(path) { (type.String(path) || type.Number(path) ? [path] : path) || [] ); - return helpers.getIn(this.tree.data, fullPath); + return helpers.getIn(this.tree.data, fullPath, this.tree); }; /** diff --git a/src/helpers.js b/src/helpers.js index e73c513..d463a1f 100644 --- a/src/helpers.js +++ b/src/helpers.js @@ -159,10 +159,11 @@ function indexByComparison(object, spec) { } // Retrieve nested objects -function getIn(object, path) { +function getIn(object, path, tree) { path = path || []; var c = object, + p, i, l; @@ -177,10 +178,21 @@ function getIn(object, path) { c = first(c, path[i]); } else if (typeof path[i] === 'object') { - if (!type.Array(c)) + if ('$cursor' in path[i]) { + if (!type.Path(path[i].$cursor)) + throw Error('baobab.getIn: $cursor path must be an array.'); + + p = tree.get(path[i].$cursor); + c = c[p]; + } + + else if (!type.Array(c)) { return; + } - c = firstByComparison(c, path[i]); + else { + c = firstByComparison(c, path[i]); + } } else { c = c[path[i]]; diff --git a/test/state.js b/test/state.js index 62fec29..061a996 100644 --- a/test/state.js +++ b/test/state.js @@ -13,6 +13,7 @@ module.exports = { firstname: 'John', lastname: 'Dillinger' }, + pointer: 1, setLater: null, list: [[1, 2], [3, 4]], longList: [1, 2, 3, 4], diff --git a/test/suites/cursor.js b/test/suites/cursor.js index fc6134e..4f4718a 100644 --- a/test/suites/cursor.js +++ b/test/suites/cursor.js @@ -66,6 +66,18 @@ describe('Cursor API', function() { var inexistant = baobab.get('setLater', 'a'); assert.strictEqual(inexistant, undefined); }); + + it('should be able to resolve a cursor pointer.', function() { + var color = baobab.get('one', 'subtwo', 'colors', {$cursor: ['pointer']}); + + assert.strictEqual(color, 'yellow'); + }); + + it('should fail when providing a wrong path to the $cursor command.', function() { + assert.throws(function() { + var color = baobab.get('one', 'subtwo', 'colors', {$cursor: null}); + }, /\$cursor/); + }); }); describe('Standard cursors', function() { From c4b3475b452da93c9a078223958dd93ee23db84e Mon Sep 17 00:00:00 2001 From: Yomguithereal Date: Tue, 7 Apr 2015 16:00:44 +0200 Subject: [PATCH 24/73] Cherry-picking IE9 fix commit --- build/baobab.min.js | 2 +- src/helpers.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/build/baobab.min.js b/build/baobab.min.js index 613a22e..b2bc300 100644 --- a/build/baobab.min.js +++ b/build/baobab.min.js @@ -1,2 +1,2 @@ /* baobab.js - Version: 1.0.0-rc1 - Author: Yomguithereal (Guillaume Plique) */ -!function(t){if("object"==typeof exports&&"undefined"!=typeof module)module.exports=t();else if("function"==typeof define&&define.amd)define([],t);else{var r;r="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:this,r.Baobab=t()}}(function(){var t;return function r(t,e,n){function i(s,a){if(!e[s]){if(!t[s]){var h="function"==typeof require&&require;if(!a&&h)return h(s,!0);if(o)return o(s,!0);var u=new Error("Cannot find module '"+s+"'");throw u.code="MODULE_NOT_FOUND",u}var c=e[s]={exports:{}};t[s][0].call(c.exports,function(r){var e=t[s][1][r];return i(e?e:r)},c,c.exports,r,t,e,n)}return e[s].exports}for(var o="function"==typeof require&&require,s=0;sr;r++)n.push(t[r].handler);return n}var i={once:"boolean",scope:"object"},o=function(){this._enabled=!0,this._children=[],this._handlers={},this._handlersAll=[]};o.prototype.on=function(t,r,e){var n,s,a,h,u,c;if("function"==typeof r){for(u="string"==typeof t?[t]:t,n=0,s=u.length;n!==s;n+=1)if(h=u[n]){this._handlers[h]||(this._handlers[h]=[]),c={handler:r};for(a in e||{}){if(!i[a])throw new Error('The option "'+a+'" is not recognized by Emmett.');c[a]=e[a]}this._handlers[h].push(c)}}else if(t&&"object"==typeof t&&!Array.isArray(t))for(h in t)o.prototype.on.call(this,h,t[h],r);else{if("function"!=typeof t)throw new Error("Wrong arguments.");c={handler:t};for(a in e||{}){if(!i[a])throw new Error('The option "'+a+'" is not recognized by Emmett.');c[a]=e[a]}this._handlersAll.push(c)}return this},o.prototype.once=function(t,r,e){if("function"==typeof r)e=e||{},e.once=!0,this.on(t,r,e);else{if((!t||"object"!=typeof t||Array.isArray(t))&&"function"!=typeof t)throw new Error("Wrong arguments.");r=r||{},r.once=!0,this.on(t,r)}return this},o.prototype.off=function(t,r){var e,n,i,o,s,a,h,u="string"==typeof t?[t]:t;if(1===arguments.length&&"function"==typeof u){r=arguments[0];for(s in this._handlers){for(a=[],e=0,n=this._handlers[s].length;e!==n;e+=1)this._handlers[s][e].handler!==r&&a.push(this._handlers[s][e]);this._handlers[s]=a}for(a=[],e=0,n=this._handlersAll.length;e!==n;e+=1)this._handlersAll[e].handler!==r&&a.push(this._handlersAll[e]);this._handlersAll=a}else if(2===arguments.length)for(e=0,n=u.length;e!==n;e+=1){if(h=u[e],this._handlers[h]){for(a=[],i=0,o=this._handlers[h].length;i!==o;i+=1)this._handlers[h][i].handler!==r&&a.push(this._handlers[h][i]);this._handlers[h]=a}this._handlers[h]&&0===this._handlers[h].length&&delete this._handlers[h]}return this},o.prototype.unbindAll=function(){var t;this._handlersAll=[];for(t in this._handlers)delete this._handlers[t];return this},o.prototype.emit=function(t,r){var e,n,i,o,s,a,h,u,c,l,f="string"==typeof t?[t]:t;if(!this._enabled)return this;for(r=void 0===r?{}:r,e=0,n=f.length;e!==n;e+=1)if(l=f[e],c=(this._handlers[l]||[]).concat(this._handlersAll),c.length){for(h={type:l,data:r||{},target:this},a=[],i=0,o=c.length;i!==o;i+=1)(this._handlers[l]&&this._handlers[l].indexOf(c[i])>=0||this._handlersAll.indexOf(c[i])>=0)&&(c[i].handler.call("scope"in c[i]?c[i].scope:this,h),c[i].once&&a.push(c[i]));for(s=0;se;e++)if(t._children[e]===r){t._children.splice(e,1);break}}),this._children.push(r),r},o.prototype.listeners=function(t){var e,n,i,o=[];if(t)for(o=r(this._handlers[t]),n=0,i=this._children.length;i>n;n++)o=o.concat(this._children[n].listeners(t));else{o=r(this._handlersAll);for(e in this._handlers)o=o.concat(r(this._handlers[e]));for(n=0,i=this._children.length;i>n;n++)o=o.concat(this._children[n].listeners())}return o},o.prototype.kill=function(){if(this.emit("emmett:kill"),this.unbindAll(),this._handlers=null,this._handlersAll=null,this._enabled=!1,this._children)for(var t=0,r=this._children.length;r>t;t++)this._children[t].kill();this._children=null},o.prototype.disable=function(){return this._enabled=!1,this},o.prototype.enable=function(){return this._enabled=!0,this},o.version="2.1.2","undefined"!=typeof n?("undefined"!=typeof e&&e.exports&&(n=e.exports=o),n.Emitter=o):"function"==typeof t&&t.amd?t("emmett",[],function(){return o}):this.Emitter=o}).call(this)},{}],4:[function(t,r){function e(t){return t+"$"+(new Date).getTime()+(""+Math.random()).replace("0.","")}function n(t,r){function e(t){this[t]=function(){var r=this.root[t].apply(this.root,arguments);return r instanceof i?this:r}}if(arguments.length<1&&(t={}),!(this instanceof n))return new n(t,r);if(!l.Object(t)&&!l.Array(t))throw Error("Baobab: invalid data.");o.call(this),this.options=s.shallowMerge(c,r),this._transaction={},this._future=void 0,this._cursors={},this.data=s.deepClone(t),this.root=this.select([]),["get","set","unset","update"].forEach(e.bind(this)),this.mixin=u.baobab(this)}var i=t("./cursor.js"),o=t("emmett"),s=t("./helpers.js"),a=t("./update.js"),h=t("./merge.js"),u=t("./mixins.js"),c=t("../defaults.js"),l=t("./type.js");s.inherits(n,o),n.prototype.select=function(t){if(!t)throw Error("Baobab.select: invalid path.");if(arguments.length>1&&(t=s.arrayOf(arguments)),!l.Path(t))throw Error("Baobab.select: invalid path.");t=[].concat(t);var r,n=l.ComplexPath(t);n&&(r=s.solvePath(this.data,t));var o=t.map(function(t){return l.Function(t)?e("fn"):l.Object(t)?e("ob"):t}).join("λ");if(this._cursors[o])return this._cursors[o];var a=new i(this,t,r,o);return this._cursors[o]=a,a},n.prototype.stack=function(t){var r=this;if(!l.Object(t))throw Error("Baobab.update: wrong specification.");return this._transaction=h(t,this._transaction),this.options.autoCommit?this.options.asynchronous?(this._future||(this._future=setTimeout(r.commit.bind(r,null),0)),this):this.commit():this},n.prototype.commit=function(){var t=a(this.data,this._transaction,this.options);return this.data=t.data,this._transaction={},this._future&&(this._future=clearTimeout(this._future)),this.emit("update",{log:t.log}),this},n.prototype.release=function(){delete this.data,delete this._transaction;for(var t in this._cursors)this._cursors[t].release();delete this._cursors,this.kill()},n.prototype.toJSON=function(){return this.get()},r.exports=n},{"../defaults.js":1,"./cursor.js":6,"./helpers.js":7,"./merge.js":8,"./mixins.js":9,"./type.js":10,"./update.js":11,emmett:3}],5:[function(t,r){function e(t,r){r.on("update",t.cursorListener),t.tree.off("update",t.treeListener),t.tree.on("update",t.treeListener)}function n(t){var r=this;if(arguments.length<2)throw Error("baobab.Combination: not enough arguments.");var n=arguments[1],i=s.arrayOf(arguments).slice(2);if(n instanceof Array&&(i=n.slice(1),n=n[0]),!a.Cursor(n))throw Error("baobab.Combination: argument should be a cursor.");if("or"!==t&&"and"!==t)throw Error("baobab.Combination: invalid operator.");o.call(this),this.cursors=[n],this.operators=[],this.tree=n.tree,this.updates=new Array(this.cursors.length),this.cursorListener=function(){r.updates[r.cursors.indexOf(this)]=!0},this.treeListener=function(){var t,e,n=r.updates[0];for(t=1,e=r.cursors.length;e>t;t++)n="or"===r.operators[t-1]?n||r.updates[t]:n&&r.updates[t];n&&r.emit("update"),r.updates=new Array(r.cursors.length)},this.bound=!1;var h=(this.on,this.once,function(){r.bound||(r.bound=!0,r.cursors.forEach(function(t){e(r,t)}))});this.on=s.before(h,this.on.bind(this)),this.once=s.before(h,this.once.bind(this)),i.forEach(function(r){this[t](r)},this)}function i(t){n.prototype[t]=function(r){if(!a.Cursor(r))throw this.release(),Error("baobab.Combination."+t+": argument should be a cursor.");if(~this.cursors.indexOf(r))throw this.release(),Error("baobab.Combination."+t+": cursor already in combination.");return this.cursors.push(r),this.operators.push(t),this.updates.length++,this.bound&&e(this,r),this}}var o=t("emmett"),s=t("./helpers.js"),a=t("./type.js");s.inherits(n,o),i("or"),i("and"),n.prototype.release=function(){this.cursors.forEach(function(t){t.off("update",this.cursorListener)},this),this.tree.off("update",this.treeListener),this.cursors=null,this.operators=null,this.tree=null,this.updates=null,this.kill()},r.exports=n},{"./helpers.js":7,"./type.js":10,emmett:3}],6:[function(t,r){function e(t,r,e,n){var i=this;o.call(this),r=r||[],this.tree=t,this.path=r,this.hash=n,this.complexPath=!!e,this.solvedPath=this.complexPath?e:this.path,this.relevant=void 0!==this.get(),this.updateHandler=function(t){var r,e,n,o,s,a,u=t.data.log,c=!1;if(i.complexPath&&(i.solvedPath=h.solvePath(i.tree.data,i.path)),!i.path.length)return i.emit("update");t:for(s=0,n=u.length;n>s;s++)for(r=u[s],a=0,o=r.length;o>a&&(e=r[a],e===""+i.solvedPath[a]);a++)if(a+1===o||a+1===i.solvedPath.length){c=!0;break t}var l=void 0!==i.get();i.relevant?l&&c?i.emit("update"):l||(i.emit("irrelevant"),i.relevant=!1):l&&c&&(i.emit("relevant"),i.emit("update"),i.relevant=!0)},this.mixin=a.cursor(this);var s=!1,u=function(){s||(s=!0,i.tree.on("update",i.updateHandler))};this.on=h.before(u,this.on.bind(this)),this.once=h.before(u,this.once.bind(this))}function n(t,r,e,n){arguments.length<4&&(n=e,e=[]),e=e||[];var i=[].concat(e),o=h.solvePath(this.get(),i);if(!o)throw Error("baobab.Cursor."+t+": could not solve dynamic path.");if(r){var s=this.get(o);if(!u[r](s))throw Error("baobab.Cursor."+t+": invalid target.")}var a={};a["$"+t]=n;var c=h.pathObject(o,a);return c}function i(t,r){e.prototype[t]=function(){var e=n.bind(this,t,r).apply(this,arguments);return this.update(e)}}var o=t("emmett"),s=t("./combination.js"),a=t("./mixins.js"),h=t("./helpers.js"),u=t("./type.js");h.inherits(e,o),e.prototype.isRoot=function(){return!this.path.length},e.prototype.isLeaf=function(){return u.Primitive(this.get())},e.prototype.isBranch=function(){return!this.isLeaf()&&!this.isRoot()},e.prototype.root=function(){return this.tree.root()},e.prototype.select=function(t){if(arguments.length>1&&(t=h.arrayOf(arguments)),!u.Path(t))throw Error("baobab.Cursor.select: invalid path.");return this.tree.select(this.path.concat(t))},e.prototype.up=function(){return this.solvedPath&&this.solvedPath.length?this.tree.select(this.path.slice(0,-1)):null},e.prototype.left=function(){var t=+this.solvedPath[this.solvedPath.length-1];if(isNaN(t))throw Error("baobab.Cursor.left: cannot go left on a non-list type.");return t?this.tree.select(this.solvedPath.slice(0,-1).concat(t-1)):null},e.prototype.leftmost=function(){var t=+this.solvedPath[this.solvedPath.length-1];if(isNaN(t))throw Error("baobab.Cursor.leftmost: cannot go left on a non-list type.");return this.tree.select(this.solvedPath.slice(0,-1).concat(0))},e.prototype.right=function(){var t=+this.solvedPath[this.solvedPath.length-1];if(isNaN(t))throw Error("baobab.Cursor.right: cannot go right on a non-list type.");return t+1===this.up().get().length?null:this.tree.select(this.solvedPath.slice(0,-1).concat(t+1))},e.prototype.rightmost=function(){var t=+this.solvedPath[this.solvedPath.length-1];if(isNaN(t))throw Error("baobab.Cursor.right: cannot go right on a non-list type.");var r=this.up().get();return this.tree.select(this.solvedPath.slice(0,-1).concat(r.length-1))},e.prototype.down=function(){+this.solvedPath[this.solvedPath.length-1];return this.get()instanceof Array?this.tree.select(this.solvedPath.concat(0)):null},e.prototype.get=function(t){arguments.length>1&&(t=h.arrayOf(arguments));var r=this.solvedPath.concat((u.String(t)||u.Number(t)?[t]:t)||[]);return h.getIn(this.tree.data,r,this.tree)},i("set"),i("apply"),i("chain"),i("push","Array"),i("unshift","Array"),e.prototype.merge=function(t){if(!u.Object(t))throw Error("baobab.Cursor.merge: trying to merge a non-object.");var r=n.bind(this,"merge","Object").apply(this,arguments);return this.update(r)},e.prototype.unset=function(t){if(void 0===t&&this.isRoot())throw Error("baobab.Cursor.unset: cannot remove root node.");var r=n.bind(this,"unset",null).apply(this,[t,!0]);return this.update(r)},e.prototype.update=function(t,r){if(arguments.length<2)return this.tree.stack(h.pathObject(this.solvedPath,t)),this;var e=[].concat(t),n=h.solvePath(this.get(),e);if(!n)throw Error("baobab.Cursor.update: could not solve dynamic path.");return this.tree.stack(h.pathObject(this.solvedPath.concat(n),r)),this},e.prototype.or=function(t){return new s("or",this,t)},e.prototype.and=function(t){return new s("and",this,t)},e.prototype.release=function(){this.tree.off("update",this.updateHandler),this.hash&&delete this.tree._cursors[this.hash],delete this.tree,delete this.path,delete this.solvedPath,this.kill()},e.prototype.toJSON=function(){return this.get()},u.Cursor=function(t){return t instanceof e},r.exports=e},{"./combination.js":5,"./helpers.js":7,"./mixins.js":9,"./type.js":10,emmett:3}],7:[function(t,r){function e(t){return Array.prototype.slice.call(t)}function n(t,r){return function(){t(),r.apply(null,arguments)}}function i(t,r){var e,n={};for(e in t)n[e]=t[e];for(e in r)n[e]=r[e];return n}function o(t){var r=t.source,e="";return t.global&&(e+="g"),t.multiline&&(e+="m"),t.ignoreCase&&(e+="i"),t.sticky&&(e+="y"),t.unicode&&(e+="u"),new RegExp(r,e)}function s(t,r){if(!r||"object"!=typeof r||r instanceof Error||r instanceof ArrayBuffer)return r;if(m.Array(r)){if(t){var e,n,i=[];for(e=0,n=r.length;n>e;e++)i.push(v(r[e]));return i}return r.slice(0)}if(m.Date(r))return new Date(r.getTime());if(r instanceof RegExp)return o(r);if(m.Object(r)){var s,a={};r.constructor&&r.constructor!==Object&&(a=Object.create(r.constructor.prototype));for(s in r)r.hasOwnProperty(s)&&(a[s]=t?v(r[s]):r[s]);return a}return r}function a(t,r){return function(e){return r(t(e))}}function h(t,r){var e,n;for(e=0,n=t.length;n>e;e++)if(r(t[e]))return t[e]}function u(t,r){var e,n;for(e=0,n=t.length;n>e;e++)if(r(t[e]))return e;return-1}function c(t,r){var e,n=!0;if(!t)return!1;for(e in r)if(m.Object(r[e]))n=n&&c(t[e],r[e]);else if(m.Array(r[e]))n=n&&!!~r[e].indexOf(t[e]);else if(t[e]!==r[e])return!1;return n}function l(t,r){return h(t,function(t){return c(t,r)})}function f(t,r){return u(t,function(t){return c(t,r)})}function p(t,r,e){r=r||[];var n,i,o,s=t;for(i=0,o=r.length;o>i;i++){if(!s)return;if("function"==typeof r[i]){if(!m.Array(s))return;s=h(s,r[i])}else if("object"==typeof r[i])if("$cursor"in r[i]){if(!m.Path(r[i].$cursor))throw Error("baobab.getIn: $cursor path must be an array.");n=e.get(r[i].$cursor),s=s[n]}else{if(!m.Array(s))return;s=l(s,r[i])}else s=s[r[i]]}return s}function d(t,r){var e,n,i,o=[],s=t;for(n=0,i=r.length;i>n;n++){if(!s)return null;if("function"==typeof r[n]){if(!m.Array(s))return;e=u(s,r[n]),o.push(e),s=s[e]}else if("object"==typeof r[n]){if(!m.Array(s))return;e=f(s,r[n]),o.push(e),s=s[e]}else o.push(r[n]),s=s[r[n]]||{}}return o}function b(t,r){var e,n=t.length,i={},o=i;for(n||(i=r),e=0;n>e;e++)o[t[e]]=e+1===n?r:{},o=o[t[e]];return i}function y(t,r){t.super_=r;var e=function(){};e.prototype=r.prototype,t.prototype=new e,t.prototype.constructor=t}var m=t("./type.js"),g=s.bind(null,!1),v=s.bind(null,!0);r.exports={arrayOf:e,before:n,deepClone:v,shallowClone:g,shallowMerge:i,compose:a,getIn:p,inherits:y,pathObject:b,solvePath:d}},{"./type.js":10}],8:[function(t,r){function e(t,r,e){s.forEach(function(r){e!==r&&delete t[r]}),t[e]=r[e]}function n(t,r){var a,h=i.shallowClone(r||{});s.forEach(function(r){t[r]&&e(h,t,r)}),t.$chain&&(s.slice(0,-1).forEach(function(t){delete h[t]}),h.$apply=h.$apply?i.compose(h.$apply,t.$chain):t.$chain),t.$push&&h.$push?h.$push=o.Array(h.$push)?h.$push.concat(t.$push):[h.$push].concat(t.$push):t.$push&&(h.$push=t.$push),t.$unshift&&h.$unshift?h.$unshift=o.Array(t.$unshift)?t.$unshift.concat(h.$unshift):[t.$unshift].concat(h.$unshift):t.$unshift&&(h.$unshift=t.$unshift);for(a in t)o.Object(t[a])?h[a]=n(t[a],h[a]):"$"!==a[0]&&(h[a]=t[a]);return h}var i=t("./helpers.js"),o=t("./type.js"),s=["$unset","$set","$merge","$apply"];r.exports=n},{"./helpers.js":7,"./type.js":10}],9:[function(t,r){var e=t("./combination.js"),n=t("./type.js");r.exports={baobab:function(t){return{mixins:[{getInitialState:function(){if(this.tree=t,!this.cursor&&!this.cursors)return{};if(this.cursor&&this.cursors)throw Error("baobab.mixin: you cannot have both `component.cursor` and `component.cursors`. Please make up your mind.");if(this.__type=null,this.__updateHandler=function(){this.setState(this.__getCursorData())}.bind(this),this.cursor){if(!n.MixinCursor(this.cursor))throw Error("baobab.mixin.cursor: invalid data (cursor, string, array or function).");n.Function(this.cursor)&&(this.cursor=this.cursor()),n.Cursor(this.cursor)||(this.cursor=t.select(this.cursor)),this.__getCursorData=function(){return{cursor:this.cursor.get()}}.bind(this),this.__type="single"}else if(this.cursors){if(!n.MixinCursors(this.cursors))throw Error("baobab.mixin.cursor: invalid data (object, array or function).");if(n.Function(this.cursors)&&(this.cursors=this.cursors()),n.Array(this.cursors))this.cursors=this.cursors.map(function(r){return n.Cursor(r)?r:t.select(r)}),this.__getCursorData=function(){return{cursors:this.cursors.map(function(t){return t.get()})}}.bind(this),this.__type="array";else{for(var r in this.cursors)n.Cursor(this.cursors[r])||(this.cursors[r]=t.select(this.cursors[r]));this.__getCursorData=function(){var t={};for(r in this.cursors)t[r]=this.cursors[r].get();return{cursors:t}}.bind(this),this.__type="object"}}return this.__getCursorData()},componentDidMount:function(){"single"===this.__type?(this.__combination=new e("or",[this.cursor]),this.__combination.on("update",this.__updateHandler)):"array"===this.__type?(this.__combination=new e("or",this.cursors),this.__combination.on("update",this.__updateHandler)):"object"===this.__type&&(this.__combination=new e("or",Object.keys(this.cursors).map(function(t){return this.cursors[t]},this)),this.__combination.on("update",this.__updateHandler))},componentWillUnmount:function(){this.__combination&&this.__combination.release()}}].concat(t.options.mixins)}},cursor:function(t){return{mixins:[{getInitialState:function(){return this.cursor=t,this.__updateHandler=function(){this.setState({cursor:this.cursor.get()})}.bind(this),{cursor:this.cursor.get()}},componentDidMount:function(){this.cursor.on("update",this.__updateHandler)},componentWillUnmount:function(){this.cursor.off("update",this.__updateHandler)}}].concat(t.tree.options.mixins)}}}},{"./combination.js":5,"./type.js":10}],10:[function(t,r){function e(t,r){return r.some(function(r){return n[r](t)})}var n={};n.Array=function(t){return Array.isArray(t)},n.Object=function(t){return!Array.isArray(t)&&"object"==typeof t&&null!==t},n.String=function(t){return"string"==typeof t},n.Number=function(t){return"number"==typeof t},n.Function=function(t){return"function"==typeof t},n.Primitive=function(t){return"string"==typeof t||"number"==typeof t||"boolean"==typeof t},n.Date=function(t){return t instanceof Date},n.NonScalar=function(t){return n.Object(t)||n.Array(t)},n.Path=function(t){var r=["String","Number","Function","Object"];return n.Array(t)?t.every(function(t){return e(t,r)}):e(t,r)},n.MixinCursor=function(t){return e(t,["String","Number","Array","Function","Cursor"])},n.MixinCursors=function(t){return e(t,["Object","Array","Function"])},n.ComplexPath=function(t){return e(t,["Object","Function"])},r.exports=n},{}],11:[function(t,r){function e(t,r){var e=new Error("baobab.update: "+r+" at path /"+t.slice(1).join("/"));return e.path=t,e}var n=t("./helpers.js"),i=t("./type.js");r.exports=function(t,r,o){if(o=o||{},!i.Object(t)&&!i.Array(t))throw Error("baobab.update: invalid target.");var s={};t={root:n.shallowClone(t)};var a=function(t,r,o,h){o=o||["root"];var u,c,l,f=o.join("λ"),p=o[o.length-1],d=Object.keys(r).some(function(t){return!!~["$unset","$set","$apply","$merge","$push","$unshift"].indexOf(t)});if(d){s[f]=!0;for(c in r){if("$unset"===c){var b=o[o.length-2];i.Array(t)?h[b]=t.slice(0,+p).concat(t.slice(+p+1)):(h[b]=n.shallowClone(t),delete h[b][p]);break}if("$set"===c){l=r.$set,t[p]=l;break}if("$apply"===c){if(u=r.$apply,"function"!=typeof u)throw e(o,"using command $apply with a non function");t[p]=u.call(null,t[p]);break}if("$merge"===c){if(l=r.$merge,!i.Object(t[p])||!i.Object(l))throw e(o,"using command $merge with a non object");t[p]=n.shallowMerge(t[p],l);break}if("$push"===c){if(l=r.$push,!i.Array(t[p]))throw e(o,"using command $push to a non array");t[p]=t[p].concat(l)}if("$unshift"===c){if(l=r.$unshift,!i.Array(t[p]))throw e(o,"using command $unshift to a non array");t[p]=[].concat(l).concat(t[p])}}}else for(c in r)t[p][c]="undefined"==typeof t[p][c]?{}:n.shallowClone(t[p][c]),a(t[p],r[c],o.concat(c),t)};return a(t,r),{data:t.root,log:Object.keys(s).map(function(t){return t.split("λ").slice(1)})}}},{"./helpers.js":7,"./type.js":10}]},{},[2])(2)}); \ No newline at end of file +!function(t){if("object"==typeof exports&&"undefined"!=typeof module)module.exports=t();else if("function"==typeof define&&define.amd)define([],t);else{var r;r="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:this,r.Baobab=t()}}(function(){var t;return function r(t,e,n){function i(s,a){if(!e[s]){if(!t[s]){var h="function"==typeof require&&require;if(!a&&h)return h(s,!0);if(o)return o(s,!0);var u=new Error("Cannot find module '"+s+"'");throw u.code="MODULE_NOT_FOUND",u}var c=e[s]={exports:{}};t[s][0].call(c.exports,function(r){var e=t[s][1][r];return i(e?e:r)},c,c.exports,r,t,e,n)}return e[s].exports}for(var o="function"==typeof require&&require,s=0;sr;r++)n.push(t[r].handler);return n}var i={once:"boolean",scope:"object"},o=function(){this._enabled=!0,this._children=[],this._handlers={},this._handlersAll=[]};o.prototype.on=function(t,r,e){var n,s,a,h,u,c;if("function"==typeof r){for(u="string"==typeof t?[t]:t,n=0,s=u.length;n!==s;n+=1)if(h=u[n]){this._handlers[h]||(this._handlers[h]=[]),c={handler:r};for(a in e||{}){if(!i[a])throw new Error('The option "'+a+'" is not recognized by Emmett.');c[a]=e[a]}this._handlers[h].push(c)}}else if(t&&"object"==typeof t&&!Array.isArray(t))for(h in t)o.prototype.on.call(this,h,t[h],r);else{if("function"!=typeof t)throw new Error("Wrong arguments.");c={handler:t};for(a in e||{}){if(!i[a])throw new Error('The option "'+a+'" is not recognized by Emmett.');c[a]=e[a]}this._handlersAll.push(c)}return this},o.prototype.once=function(t,r,e){if("function"==typeof r)e=e||{},e.once=!0,this.on(t,r,e);else{if((!t||"object"!=typeof t||Array.isArray(t))&&"function"!=typeof t)throw new Error("Wrong arguments.");r=r||{},r.once=!0,this.on(t,r)}return this},o.prototype.off=function(t,r){var e,n,i,o,s,a,h,u="string"==typeof t?[t]:t;if(1===arguments.length&&"function"==typeof u){r=arguments[0];for(s in this._handlers){for(a=[],e=0,n=this._handlers[s].length;e!==n;e+=1)this._handlers[s][e].handler!==r&&a.push(this._handlers[s][e]);this._handlers[s]=a}for(a=[],e=0,n=this._handlersAll.length;e!==n;e+=1)this._handlersAll[e].handler!==r&&a.push(this._handlersAll[e]);this._handlersAll=a}else if(2===arguments.length)for(e=0,n=u.length;e!==n;e+=1){if(h=u[e],this._handlers[h]){for(a=[],i=0,o=this._handlers[h].length;i!==o;i+=1)this._handlers[h][i].handler!==r&&a.push(this._handlers[h][i]);this._handlers[h]=a}this._handlers[h]&&0===this._handlers[h].length&&delete this._handlers[h]}return this},o.prototype.unbindAll=function(){var t;this._handlersAll=[];for(t in this._handlers)delete this._handlers[t];return this},o.prototype.emit=function(t,r){var e,n,i,o,s,a,h,u,c,l,f="string"==typeof t?[t]:t;if(!this._enabled)return this;for(r=void 0===r?{}:r,e=0,n=f.length;e!==n;e+=1)if(l=f[e],c=(this._handlers[l]||[]).concat(this._handlersAll),c.length){for(h={type:l,data:r||{},target:this},a=[],i=0,o=c.length;i!==o;i+=1)(this._handlers[l]&&this._handlers[l].indexOf(c[i])>=0||this._handlersAll.indexOf(c[i])>=0)&&(c[i].handler.call("scope"in c[i]?c[i].scope:this,h),c[i].once&&a.push(c[i]));for(s=0;se;e++)if(t._children[e]===r){t._children.splice(e,1);break}}),this._children.push(r),r},o.prototype.listeners=function(t){var e,n,i,o=[];if(t)for(o=r(this._handlers[t]),n=0,i=this._children.length;i>n;n++)o=o.concat(this._children[n].listeners(t));else{o=r(this._handlersAll);for(e in this._handlers)o=o.concat(r(this._handlers[e]));for(n=0,i=this._children.length;i>n;n++)o=o.concat(this._children[n].listeners())}return o},o.prototype.kill=function(){if(this.emit("emmett:kill"),this.unbindAll(),this._handlers=null,this._handlersAll=null,this._enabled=!1,this._children)for(var t=0,r=this._children.length;r>t;t++)this._children[t].kill();this._children=null},o.prototype.disable=function(){return this._enabled=!1,this},o.prototype.enable=function(){return this._enabled=!0,this},o.version="2.1.2","undefined"!=typeof n?("undefined"!=typeof e&&e.exports&&(n=e.exports=o),n.Emitter=o):"function"==typeof t&&t.amd?t("emmett",[],function(){return o}):this.Emitter=o}).call(this)},{}],4:[function(t,r){function e(t){return t+"$"+(new Date).getTime()+(""+Math.random()).replace("0.","")}function n(t,r){function e(t){this[t]=function(){var r=this.root[t].apply(this.root,arguments);return r instanceof i?this:r}}if(arguments.length<1&&(t={}),!(this instanceof n))return new n(t,r);if(!l.Object(t)&&!l.Array(t))throw Error("Baobab: invalid data.");o.call(this),this.options=s.shallowMerge(c,r),this._transaction={},this._future=void 0,this._cursors={},this.data=s.deepClone(t),this.root=this.select([]),["get","set","unset","update"].forEach(e.bind(this)),this.mixin=u.baobab(this)}var i=t("./cursor.js"),o=t("emmett"),s=t("./helpers.js"),a=t("./update.js"),h=t("./merge.js"),u=t("./mixins.js"),c=t("../defaults.js"),l=t("./type.js");s.inherits(n,o),n.prototype.select=function(t){if(!t)throw Error("Baobab.select: invalid path.");if(arguments.length>1&&(t=s.arrayOf(arguments)),!l.Path(t))throw Error("Baobab.select: invalid path.");t=[].concat(t);var r,n=l.ComplexPath(t);n&&(r=s.solvePath(this.data,t));var o=t.map(function(t){return l.Function(t)?e("fn"):l.Object(t)?e("ob"):t}).join("λ");if(this._cursors[o])return this._cursors[o];var a=new i(this,t,r,o);return this._cursors[o]=a,a},n.prototype.stack=function(t){var r=this;if(!l.Object(t))throw Error("Baobab.update: wrong specification.");return this._transaction=h(t,this._transaction),this.options.autoCommit?this.options.asynchronous?(this._future||(this._future=setTimeout(r.commit.bind(r,null),0)),this):this.commit():this},n.prototype.commit=function(){var t=a(this.data,this._transaction,this.options);return this.data=t.data,this._transaction={},this._future&&(this._future=clearTimeout(this._future)),this.emit("update",{log:t.log}),this},n.prototype.release=function(){delete this.data,delete this._transaction;for(var t in this._cursors)this._cursors[t].release();delete this._cursors,this.kill()},n.prototype.toJSON=function(){return this.get()},r.exports=n},{"../defaults.js":1,"./cursor.js":6,"./helpers.js":7,"./merge.js":8,"./mixins.js":9,"./type.js":10,"./update.js":11,emmett:3}],5:[function(t,r){function e(t,r){r.on("update",t.cursorListener),t.tree.off("update",t.treeListener),t.tree.on("update",t.treeListener)}function n(t){var r=this;if(arguments.length<2)throw Error("baobab.Combination: not enough arguments.");var n=arguments[1],i=s.arrayOf(arguments).slice(2);if(n instanceof Array&&(i=n.slice(1),n=n[0]),!a.Cursor(n))throw Error("baobab.Combination: argument should be a cursor.");if("or"!==t&&"and"!==t)throw Error("baobab.Combination: invalid operator.");o.call(this),this.cursors=[n],this.operators=[],this.tree=n.tree,this.updates=new Array(this.cursors.length),this.cursorListener=function(){r.updates[r.cursors.indexOf(this)]=!0},this.treeListener=function(){var t,e,n=r.updates[0];for(t=1,e=r.cursors.length;e>t;t++)n="or"===r.operators[t-1]?n||r.updates[t]:n&&r.updates[t];n&&r.emit("update"),r.updates=new Array(r.cursors.length)},this.bound=!1;var h=(this.on,this.once,function(){r.bound||(r.bound=!0,r.cursors.forEach(function(t){e(r,t)}))});this.on=s.before(h,this.on.bind(this)),this.once=s.before(h,this.once.bind(this)),i.forEach(function(r){this[t](r)},this)}function i(t){n.prototype[t]=function(r){if(!a.Cursor(r))throw this.release(),Error("baobab.Combination."+t+": argument should be a cursor.");if(~this.cursors.indexOf(r))throw this.release(),Error("baobab.Combination."+t+": cursor already in combination.");return this.cursors.push(r),this.operators.push(t),this.updates.length++,this.bound&&e(this,r),this}}var o=t("emmett"),s=t("./helpers.js"),a=t("./type.js");s.inherits(n,o),i("or"),i("and"),n.prototype.release=function(){this.cursors.forEach(function(t){t.off("update",this.cursorListener)},this),this.tree.off("update",this.treeListener),this.cursors=null,this.operators=null,this.tree=null,this.updates=null,this.kill()},r.exports=n},{"./helpers.js":7,"./type.js":10,emmett:3}],6:[function(t,r){function e(t,r,e,n){var i=this;o.call(this),r=r||[],this.tree=t,this.path=r,this.hash=n,this.complexPath=!!e,this.solvedPath=this.complexPath?e:this.path,this.relevant=void 0!==this.get(),this.updateHandler=function(t){var r,e,n,o,s,a,u=t.data.log,c=!1;if(i.complexPath&&(i.solvedPath=h.solvePath(i.tree.data,i.path)),!i.path.length)return i.emit("update");t:for(s=0,n=u.length;n>s;s++)for(r=u[s],a=0,o=r.length;o>a&&(e=r[a],e===""+i.solvedPath[a]);a++)if(a+1===o||a+1===i.solvedPath.length){c=!0;break t}var l=void 0!==i.get();i.relevant?l&&c?i.emit("update"):l||(i.emit("irrelevant"),i.relevant=!1):l&&c&&(i.emit("relevant"),i.emit("update"),i.relevant=!0)},this.mixin=a.cursor(this);var s=!1,u=function(){s||(s=!0,i.tree.on("update",i.updateHandler))};this.on=h.before(u,this.on.bind(this)),this.once=h.before(u,this.once.bind(this))}function n(t,r,e,n){arguments.length<4&&(n=e,e=[]),e=e||[];var i=[].concat(e),o=h.solvePath(this.get(),i);if(!o)throw Error("baobab.Cursor."+t+": could not solve dynamic path.");if(r){var s=this.get(o);if(!u[r](s))throw Error("baobab.Cursor."+t+": invalid target.")}var a={};a["$"+t]=n;var c=h.pathObject(o,a);return c}function i(t,r){e.prototype[t]=function(){var e=n.bind(this,t,r).apply(this,arguments);return this.update(e)}}var o=t("emmett"),s=t("./combination.js"),a=t("./mixins.js"),h=t("./helpers.js"),u=t("./type.js");h.inherits(e,o),e.prototype.isRoot=function(){return!this.path.length},e.prototype.isLeaf=function(){return u.Primitive(this.get())},e.prototype.isBranch=function(){return!this.isLeaf()&&!this.isRoot()},e.prototype.root=function(){return this.tree.root()},e.prototype.select=function(t){if(arguments.length>1&&(t=h.arrayOf(arguments)),!u.Path(t))throw Error("baobab.Cursor.select: invalid path.");return this.tree.select(this.path.concat(t))},e.prototype.up=function(){return this.solvedPath&&this.solvedPath.length?this.tree.select(this.path.slice(0,-1)):null},e.prototype.left=function(){var t=+this.solvedPath[this.solvedPath.length-1];if(isNaN(t))throw Error("baobab.Cursor.left: cannot go left on a non-list type.");return t?this.tree.select(this.solvedPath.slice(0,-1).concat(t-1)):null},e.prototype.leftmost=function(){var t=+this.solvedPath[this.solvedPath.length-1];if(isNaN(t))throw Error("baobab.Cursor.leftmost: cannot go left on a non-list type.");return this.tree.select(this.solvedPath.slice(0,-1).concat(0))},e.prototype.right=function(){var t=+this.solvedPath[this.solvedPath.length-1];if(isNaN(t))throw Error("baobab.Cursor.right: cannot go right on a non-list type.");return t+1===this.up().get().length?null:this.tree.select(this.solvedPath.slice(0,-1).concat(t+1))},e.prototype.rightmost=function(){var t=+this.solvedPath[this.solvedPath.length-1];if(isNaN(t))throw Error("baobab.Cursor.right: cannot go right on a non-list type.");var r=this.up().get();return this.tree.select(this.solvedPath.slice(0,-1).concat(r.length-1))},e.prototype.down=function(){+this.solvedPath[this.solvedPath.length-1];return this.get()instanceof Array?this.tree.select(this.solvedPath.concat(0)):null},e.prototype.get=function(t){arguments.length>1&&(t=h.arrayOf(arguments));var r=this.solvedPath.concat((u.String(t)||u.Number(t)?[t]:t)||[]);return h.getIn(this.tree.data,r,this.tree)},i("set"),i("apply"),i("chain"),i("push","Array"),i("unshift","Array"),e.prototype.merge=function(t){if(!u.Object(t))throw Error("baobab.Cursor.merge: trying to merge a non-object.");var r=n.bind(this,"merge","Object").apply(this,arguments);return this.update(r)},e.prototype.unset=function(t){if(void 0===t&&this.isRoot())throw Error("baobab.Cursor.unset: cannot remove root node.");var r=n.bind(this,"unset",null).apply(this,[t,!0]);return this.update(r)},e.prototype.update=function(t,r){if(arguments.length<2)return this.tree.stack(h.pathObject(this.solvedPath,t)),this;var e=[].concat(t),n=h.solvePath(this.get(),e);if(!n)throw Error("baobab.Cursor.update: could not solve dynamic path.");return this.tree.stack(h.pathObject(this.solvedPath.concat(n),r)),this},e.prototype.or=function(t){return new s("or",this,t)},e.prototype.and=function(t){return new s("and",this,t)},e.prototype.release=function(){this.tree.off("update",this.updateHandler),this.hash&&delete this.tree._cursors[this.hash],delete this.tree,delete this.path,delete this.solvedPath,this.kill()},e.prototype.toJSON=function(){return this.get()},u.Cursor=function(t){return t instanceof e},r.exports=e},{"./combination.js":5,"./helpers.js":7,"./mixins.js":9,"./type.js":10,emmett:3}],7:[function(t,r){(function(e){function n(t){return Array.prototype.slice.call(t)}function i(t,r){return function(){t(),r.apply(null,arguments)}}function o(t,r){var e,n={};for(e in t)n[e]=t[e];for(e in r)n[e]=r[e];return n}function s(t){var r=t.source,e="";return t.global&&(e+="g"),t.multiline&&(e+="m"),t.ignoreCase&&(e+="i"),t.sticky&&(e+="y"),t.unicode&&(e+="u"),new RegExp(r,e)}function a(t,r){if(!r||"object"!=typeof r||r instanceof Error||"ArrayBuffer"in e&&r instanceof ArrayBuffer)return r;if(m.Array(r)){if(t){var n,i,o=[];for(n=0,i=r.length;i>n;n++)o.push(_(r[n]));return o}return r.slice(0)}if(m.Date(r))return new Date(r.getTime());if(r instanceof RegExp)return s(r);if(m.Object(r)){var a,h={};r.constructor&&r.constructor!==Object&&(h=Object.create(r.constructor.prototype));for(a in r)r.hasOwnProperty(a)&&(h[a]=t?_(r[a]):r[a]);return h}return r}function h(t,r){return function(e){return r(t(e))}}function u(t,r){var e,n;for(e=0,n=t.length;n>e;e++)if(r(t[e]))return t[e]}function c(t,r){var e,n;for(e=0,n=t.length;n>e;e++)if(r(t[e]))return e;return-1}function l(t,r){var e,n=!0;if(!t)return!1;for(e in r)if(m.Object(r[e]))n=n&&l(t[e],r[e]);else if(m.Array(r[e]))n=n&&!!~r[e].indexOf(t[e]);else if(t[e]!==r[e])return!1;return n}function f(t,r){return u(t,function(t){return l(t,r)})}function p(t,r){return c(t,function(t){return l(t,r)})}function d(t,r,e){r=r||[];var n,i,o,s=t;for(i=0,o=r.length;o>i;i++){if(!s)return;if("function"==typeof r[i]){if(!m.Array(s))return;s=u(s,r[i])}else if("object"==typeof r[i])if("$cursor"in r[i]){if(!m.Path(r[i].$cursor))throw Error("baobab.getIn: $cursor path must be an array.");n=e.get(r[i].$cursor),s=s[n]}else{if(!m.Array(s))return;s=f(s,r[i])}else s=s[r[i]]}return s}function b(t,r){var e,n,i,o=[],s=t;for(n=0,i=r.length;i>n;n++){if(!s)return null;if("function"==typeof r[n]){if(!m.Array(s))return;e=c(s,r[n]),o.push(e),s=s[e]}else if("object"==typeof r[n]){if(!m.Array(s))return;e=p(s,r[n]),o.push(e),s=s[e]}else o.push(r[n]),s=s[r[n]]||{}}return o}function y(t,r){var e,n=t.length,i={},o=i;for(n||(i=r),e=0;n>e;e++)o[t[e]]=e+1===n?r:{},o=o[t[e]];return i}function g(t,r){t.super_=r;var e=function(){};e.prototype=r.prototype,t.prototype=new e,t.prototype.constructor=t}var m=t("./type.js"),v=a.bind(null,!1),_=a.bind(null,!0);r.exports={arrayOf:n,before:i,deepClone:_,shallowClone:v,shallowMerge:o,compose:h,getIn:d,inherits:g,pathObject:y,solvePath:b}}).call(this,"undefined"!=typeof global?global:"undefined"!=typeof self?self:"undefined"!=typeof window?window:{})},{"./type.js":10}],8:[function(t,r){function e(t,r,e){s.forEach(function(r){e!==r&&delete t[r]}),t[e]=r[e]}function n(t,r){var a,h=i.shallowClone(r||{});s.forEach(function(r){t[r]&&e(h,t,r)}),t.$chain&&(s.slice(0,-1).forEach(function(t){delete h[t]}),h.$apply=h.$apply?i.compose(h.$apply,t.$chain):t.$chain),t.$push&&h.$push?h.$push=o.Array(h.$push)?h.$push.concat(t.$push):[h.$push].concat(t.$push):t.$push&&(h.$push=t.$push),t.$unshift&&h.$unshift?h.$unshift=o.Array(t.$unshift)?t.$unshift.concat(h.$unshift):[t.$unshift].concat(h.$unshift):t.$unshift&&(h.$unshift=t.$unshift);for(a in t)o.Object(t[a])?h[a]=n(t[a],h[a]):"$"!==a[0]&&(h[a]=t[a]);return h}var i=t("./helpers.js"),o=t("./type.js"),s=["$unset","$set","$merge","$apply"];r.exports=n},{"./helpers.js":7,"./type.js":10}],9:[function(t,r){var e=t("./combination.js"),n=t("./type.js");r.exports={baobab:function(t){return{mixins:[{getInitialState:function(){if(this.tree=t,!this.cursor&&!this.cursors)return{};if(this.cursor&&this.cursors)throw Error("baobab.mixin: you cannot have both `component.cursor` and `component.cursors`. Please make up your mind.");if(this.__type=null,this.__updateHandler=function(){this.setState(this.__getCursorData())}.bind(this),this.cursor){if(!n.MixinCursor(this.cursor))throw Error("baobab.mixin.cursor: invalid data (cursor, string, array or function).");n.Function(this.cursor)&&(this.cursor=this.cursor()),n.Cursor(this.cursor)||(this.cursor=t.select(this.cursor)),this.__getCursorData=function(){return{cursor:this.cursor.get()}}.bind(this),this.__type="single"}else if(this.cursors){if(!n.MixinCursors(this.cursors))throw Error("baobab.mixin.cursor: invalid data (object, array or function).");if(n.Function(this.cursors)&&(this.cursors=this.cursors()),n.Array(this.cursors))this.cursors=this.cursors.map(function(r){return n.Cursor(r)?r:t.select(r)}),this.__getCursorData=function(){return{cursors:this.cursors.map(function(t){return t.get()})}}.bind(this),this.__type="array";else{for(var r in this.cursors)n.Cursor(this.cursors[r])||(this.cursors[r]=t.select(this.cursors[r]));this.__getCursorData=function(){var t={};for(r in this.cursors)t[r]=this.cursors[r].get();return{cursors:t}}.bind(this),this.__type="object"}}return this.__getCursorData()},componentDidMount:function(){"single"===this.__type?(this.__combination=new e("or",[this.cursor]),this.__combination.on("update",this.__updateHandler)):"array"===this.__type?(this.__combination=new e("or",this.cursors),this.__combination.on("update",this.__updateHandler)):"object"===this.__type&&(this.__combination=new e("or",Object.keys(this.cursors).map(function(t){return this.cursors[t]},this)),this.__combination.on("update",this.__updateHandler))},componentWillUnmount:function(){this.__combination&&this.__combination.release()}}].concat(t.options.mixins)}},cursor:function(t){return{mixins:[{getInitialState:function(){return this.cursor=t,this.__updateHandler=function(){this.setState({cursor:this.cursor.get()})}.bind(this),{cursor:this.cursor.get()}},componentDidMount:function(){this.cursor.on("update",this.__updateHandler)},componentWillUnmount:function(){this.cursor.off("update",this.__updateHandler)}}].concat(t.tree.options.mixins)}}}},{"./combination.js":5,"./type.js":10}],10:[function(t,r){function e(t,r){return r.some(function(r){return n[r](t)})}var n={};n.Array=function(t){return Array.isArray(t)},n.Object=function(t){return!Array.isArray(t)&&"object"==typeof t&&null!==t},n.String=function(t){return"string"==typeof t},n.Number=function(t){return"number"==typeof t},n.Function=function(t){return"function"==typeof t},n.Primitive=function(t){return"string"==typeof t||"number"==typeof t||"boolean"==typeof t},n.Date=function(t){return t instanceof Date},n.NonScalar=function(t){return n.Object(t)||n.Array(t)},n.Path=function(t){var r=["String","Number","Function","Object"];return n.Array(t)?t.every(function(t){return e(t,r)}):e(t,r)},n.MixinCursor=function(t){return e(t,["String","Number","Array","Function","Cursor"])},n.MixinCursors=function(t){return e(t,["Object","Array","Function"])},n.ComplexPath=function(t){return e(t,["Object","Function"])},r.exports=n},{}],11:[function(t,r){function e(t,r){var e=new Error("baobab.update: "+r+" at path /"+t.slice(1).join("/"));return e.path=t,e}var n=t("./helpers.js"),i=t("./type.js");r.exports=function(t,r,o){if(o=o||{},!i.Object(t)&&!i.Array(t))throw Error("baobab.update: invalid target.");var s={};t={root:n.shallowClone(t)};var a=function(t,r,o,h){o=o||["root"];var u,c,l,f=o.join("λ"),p=o[o.length-1],d=Object.keys(r).some(function(t){return!!~["$unset","$set","$apply","$merge","$push","$unshift"].indexOf(t)});if(d){s[f]=!0;for(c in r){if("$unset"===c){var b=o[o.length-2];i.Array(t)?h[b]=t.slice(0,+p).concat(t.slice(+p+1)):(h[b]=n.shallowClone(t),delete h[b][p]);break}if("$set"===c){l=r.$set,t[p]=l;break}if("$apply"===c){if(u=r.$apply,"function"!=typeof u)throw e(o,"using command $apply with a non function");t[p]=u.call(null,t[p]);break}if("$merge"===c){if(l=r.$merge,!i.Object(t[p])||!i.Object(l))throw e(o,"using command $merge with a non object");t[p]=n.shallowMerge(t[p],l);break}if("$push"===c){if(l=r.$push,!i.Array(t[p]))throw e(o,"using command $push to a non array");t[p]=t[p].concat(l)}if("$unshift"===c){if(l=r.$unshift,!i.Array(t[p]))throw e(o,"using command $unshift to a non array");t[p]=[].concat(l).concat(t[p])}}}else for(c in r)t[p][c]="undefined"==typeof t[p][c]?{}:n.shallowClone(t[p][c]),a(t[p],r[c],o.concat(c),t)};return a(t,r),{data:t.root,log:Object.keys(s).map(function(t){return t.split("λ").slice(1)})}}},{"./helpers.js":7,"./type.js":10}]},{},[2])(2)}); \ No newline at end of file diff --git a/src/helpers.js b/src/helpers.js index d463a1f..b9e3184 100644 --- a/src/helpers.js +++ b/src/helpers.js @@ -49,7 +49,7 @@ function clone(deep, item) { if (!item || typeof item !== 'object' || item instanceof Error || - item instanceof ArrayBuffer) + ('ArrayBuffer' in global && item instanceof ArrayBuffer)) return item; // Array From 08505822b14f1cd74a96e93b55802071f7a2cd8d Mon Sep 17 00:00:00 2001 From: Yomguithereal Date: Wed, 8 Apr 2015 16:53:37 +0200 Subject: [PATCH 25/73] Related to #128 - $cursor pointer selection --- build/baobab.min.js | 2 +- src/helpers.js | 10 +++++++++- test/suites/baobab.js | 12 ++++++++++++ 3 files changed, 22 insertions(+), 2 deletions(-) diff --git a/build/baobab.min.js b/build/baobab.min.js index b2bc300..c842263 100644 --- a/build/baobab.min.js +++ b/build/baobab.min.js @@ -1,2 +1,2 @@ /* baobab.js - Version: 1.0.0-rc1 - Author: Yomguithereal (Guillaume Plique) */ -!function(t){if("object"==typeof exports&&"undefined"!=typeof module)module.exports=t();else if("function"==typeof define&&define.amd)define([],t);else{var r;r="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:this,r.Baobab=t()}}(function(){var t;return function r(t,e,n){function i(s,a){if(!e[s]){if(!t[s]){var h="function"==typeof require&&require;if(!a&&h)return h(s,!0);if(o)return o(s,!0);var u=new Error("Cannot find module '"+s+"'");throw u.code="MODULE_NOT_FOUND",u}var c=e[s]={exports:{}};t[s][0].call(c.exports,function(r){var e=t[s][1][r];return i(e?e:r)},c,c.exports,r,t,e,n)}return e[s].exports}for(var o="function"==typeof require&&require,s=0;sr;r++)n.push(t[r].handler);return n}var i={once:"boolean",scope:"object"},o=function(){this._enabled=!0,this._children=[],this._handlers={},this._handlersAll=[]};o.prototype.on=function(t,r,e){var n,s,a,h,u,c;if("function"==typeof r){for(u="string"==typeof t?[t]:t,n=0,s=u.length;n!==s;n+=1)if(h=u[n]){this._handlers[h]||(this._handlers[h]=[]),c={handler:r};for(a in e||{}){if(!i[a])throw new Error('The option "'+a+'" is not recognized by Emmett.');c[a]=e[a]}this._handlers[h].push(c)}}else if(t&&"object"==typeof t&&!Array.isArray(t))for(h in t)o.prototype.on.call(this,h,t[h],r);else{if("function"!=typeof t)throw new Error("Wrong arguments.");c={handler:t};for(a in e||{}){if(!i[a])throw new Error('The option "'+a+'" is not recognized by Emmett.');c[a]=e[a]}this._handlersAll.push(c)}return this},o.prototype.once=function(t,r,e){if("function"==typeof r)e=e||{},e.once=!0,this.on(t,r,e);else{if((!t||"object"!=typeof t||Array.isArray(t))&&"function"!=typeof t)throw new Error("Wrong arguments.");r=r||{},r.once=!0,this.on(t,r)}return this},o.prototype.off=function(t,r){var e,n,i,o,s,a,h,u="string"==typeof t?[t]:t;if(1===arguments.length&&"function"==typeof u){r=arguments[0];for(s in this._handlers){for(a=[],e=0,n=this._handlers[s].length;e!==n;e+=1)this._handlers[s][e].handler!==r&&a.push(this._handlers[s][e]);this._handlers[s]=a}for(a=[],e=0,n=this._handlersAll.length;e!==n;e+=1)this._handlersAll[e].handler!==r&&a.push(this._handlersAll[e]);this._handlersAll=a}else if(2===arguments.length)for(e=0,n=u.length;e!==n;e+=1){if(h=u[e],this._handlers[h]){for(a=[],i=0,o=this._handlers[h].length;i!==o;i+=1)this._handlers[h][i].handler!==r&&a.push(this._handlers[h][i]);this._handlers[h]=a}this._handlers[h]&&0===this._handlers[h].length&&delete this._handlers[h]}return this},o.prototype.unbindAll=function(){var t;this._handlersAll=[];for(t in this._handlers)delete this._handlers[t];return this},o.prototype.emit=function(t,r){var e,n,i,o,s,a,h,u,c,l,f="string"==typeof t?[t]:t;if(!this._enabled)return this;for(r=void 0===r?{}:r,e=0,n=f.length;e!==n;e+=1)if(l=f[e],c=(this._handlers[l]||[]).concat(this._handlersAll),c.length){for(h={type:l,data:r||{},target:this},a=[],i=0,o=c.length;i!==o;i+=1)(this._handlers[l]&&this._handlers[l].indexOf(c[i])>=0||this._handlersAll.indexOf(c[i])>=0)&&(c[i].handler.call("scope"in c[i]?c[i].scope:this,h),c[i].once&&a.push(c[i]));for(s=0;se;e++)if(t._children[e]===r){t._children.splice(e,1);break}}),this._children.push(r),r},o.prototype.listeners=function(t){var e,n,i,o=[];if(t)for(o=r(this._handlers[t]),n=0,i=this._children.length;i>n;n++)o=o.concat(this._children[n].listeners(t));else{o=r(this._handlersAll);for(e in this._handlers)o=o.concat(r(this._handlers[e]));for(n=0,i=this._children.length;i>n;n++)o=o.concat(this._children[n].listeners())}return o},o.prototype.kill=function(){if(this.emit("emmett:kill"),this.unbindAll(),this._handlers=null,this._handlersAll=null,this._enabled=!1,this._children)for(var t=0,r=this._children.length;r>t;t++)this._children[t].kill();this._children=null},o.prototype.disable=function(){return this._enabled=!1,this},o.prototype.enable=function(){return this._enabled=!0,this},o.version="2.1.2","undefined"!=typeof n?("undefined"!=typeof e&&e.exports&&(n=e.exports=o),n.Emitter=o):"function"==typeof t&&t.amd?t("emmett",[],function(){return o}):this.Emitter=o}).call(this)},{}],4:[function(t,r){function e(t){return t+"$"+(new Date).getTime()+(""+Math.random()).replace("0.","")}function n(t,r){function e(t){this[t]=function(){var r=this.root[t].apply(this.root,arguments);return r instanceof i?this:r}}if(arguments.length<1&&(t={}),!(this instanceof n))return new n(t,r);if(!l.Object(t)&&!l.Array(t))throw Error("Baobab: invalid data.");o.call(this),this.options=s.shallowMerge(c,r),this._transaction={},this._future=void 0,this._cursors={},this.data=s.deepClone(t),this.root=this.select([]),["get","set","unset","update"].forEach(e.bind(this)),this.mixin=u.baobab(this)}var i=t("./cursor.js"),o=t("emmett"),s=t("./helpers.js"),a=t("./update.js"),h=t("./merge.js"),u=t("./mixins.js"),c=t("../defaults.js"),l=t("./type.js");s.inherits(n,o),n.prototype.select=function(t){if(!t)throw Error("Baobab.select: invalid path.");if(arguments.length>1&&(t=s.arrayOf(arguments)),!l.Path(t))throw Error("Baobab.select: invalid path.");t=[].concat(t);var r,n=l.ComplexPath(t);n&&(r=s.solvePath(this.data,t));var o=t.map(function(t){return l.Function(t)?e("fn"):l.Object(t)?e("ob"):t}).join("λ");if(this._cursors[o])return this._cursors[o];var a=new i(this,t,r,o);return this._cursors[o]=a,a},n.prototype.stack=function(t){var r=this;if(!l.Object(t))throw Error("Baobab.update: wrong specification.");return this._transaction=h(t,this._transaction),this.options.autoCommit?this.options.asynchronous?(this._future||(this._future=setTimeout(r.commit.bind(r,null),0)),this):this.commit():this},n.prototype.commit=function(){var t=a(this.data,this._transaction,this.options);return this.data=t.data,this._transaction={},this._future&&(this._future=clearTimeout(this._future)),this.emit("update",{log:t.log}),this},n.prototype.release=function(){delete this.data,delete this._transaction;for(var t in this._cursors)this._cursors[t].release();delete this._cursors,this.kill()},n.prototype.toJSON=function(){return this.get()},r.exports=n},{"../defaults.js":1,"./cursor.js":6,"./helpers.js":7,"./merge.js":8,"./mixins.js":9,"./type.js":10,"./update.js":11,emmett:3}],5:[function(t,r){function e(t,r){r.on("update",t.cursorListener),t.tree.off("update",t.treeListener),t.tree.on("update",t.treeListener)}function n(t){var r=this;if(arguments.length<2)throw Error("baobab.Combination: not enough arguments.");var n=arguments[1],i=s.arrayOf(arguments).slice(2);if(n instanceof Array&&(i=n.slice(1),n=n[0]),!a.Cursor(n))throw Error("baobab.Combination: argument should be a cursor.");if("or"!==t&&"and"!==t)throw Error("baobab.Combination: invalid operator.");o.call(this),this.cursors=[n],this.operators=[],this.tree=n.tree,this.updates=new Array(this.cursors.length),this.cursorListener=function(){r.updates[r.cursors.indexOf(this)]=!0},this.treeListener=function(){var t,e,n=r.updates[0];for(t=1,e=r.cursors.length;e>t;t++)n="or"===r.operators[t-1]?n||r.updates[t]:n&&r.updates[t];n&&r.emit("update"),r.updates=new Array(r.cursors.length)},this.bound=!1;var h=(this.on,this.once,function(){r.bound||(r.bound=!0,r.cursors.forEach(function(t){e(r,t)}))});this.on=s.before(h,this.on.bind(this)),this.once=s.before(h,this.once.bind(this)),i.forEach(function(r){this[t](r)},this)}function i(t){n.prototype[t]=function(r){if(!a.Cursor(r))throw this.release(),Error("baobab.Combination."+t+": argument should be a cursor.");if(~this.cursors.indexOf(r))throw this.release(),Error("baobab.Combination."+t+": cursor already in combination.");return this.cursors.push(r),this.operators.push(t),this.updates.length++,this.bound&&e(this,r),this}}var o=t("emmett"),s=t("./helpers.js"),a=t("./type.js");s.inherits(n,o),i("or"),i("and"),n.prototype.release=function(){this.cursors.forEach(function(t){t.off("update",this.cursorListener)},this),this.tree.off("update",this.treeListener),this.cursors=null,this.operators=null,this.tree=null,this.updates=null,this.kill()},r.exports=n},{"./helpers.js":7,"./type.js":10,emmett:3}],6:[function(t,r){function e(t,r,e,n){var i=this;o.call(this),r=r||[],this.tree=t,this.path=r,this.hash=n,this.complexPath=!!e,this.solvedPath=this.complexPath?e:this.path,this.relevant=void 0!==this.get(),this.updateHandler=function(t){var r,e,n,o,s,a,u=t.data.log,c=!1;if(i.complexPath&&(i.solvedPath=h.solvePath(i.tree.data,i.path)),!i.path.length)return i.emit("update");t:for(s=0,n=u.length;n>s;s++)for(r=u[s],a=0,o=r.length;o>a&&(e=r[a],e===""+i.solvedPath[a]);a++)if(a+1===o||a+1===i.solvedPath.length){c=!0;break t}var l=void 0!==i.get();i.relevant?l&&c?i.emit("update"):l||(i.emit("irrelevant"),i.relevant=!1):l&&c&&(i.emit("relevant"),i.emit("update"),i.relevant=!0)},this.mixin=a.cursor(this);var s=!1,u=function(){s||(s=!0,i.tree.on("update",i.updateHandler))};this.on=h.before(u,this.on.bind(this)),this.once=h.before(u,this.once.bind(this))}function n(t,r,e,n){arguments.length<4&&(n=e,e=[]),e=e||[];var i=[].concat(e),o=h.solvePath(this.get(),i);if(!o)throw Error("baobab.Cursor."+t+": could not solve dynamic path.");if(r){var s=this.get(o);if(!u[r](s))throw Error("baobab.Cursor."+t+": invalid target.")}var a={};a["$"+t]=n;var c=h.pathObject(o,a);return c}function i(t,r){e.prototype[t]=function(){var e=n.bind(this,t,r).apply(this,arguments);return this.update(e)}}var o=t("emmett"),s=t("./combination.js"),a=t("./mixins.js"),h=t("./helpers.js"),u=t("./type.js");h.inherits(e,o),e.prototype.isRoot=function(){return!this.path.length},e.prototype.isLeaf=function(){return u.Primitive(this.get())},e.prototype.isBranch=function(){return!this.isLeaf()&&!this.isRoot()},e.prototype.root=function(){return this.tree.root()},e.prototype.select=function(t){if(arguments.length>1&&(t=h.arrayOf(arguments)),!u.Path(t))throw Error("baobab.Cursor.select: invalid path.");return this.tree.select(this.path.concat(t))},e.prototype.up=function(){return this.solvedPath&&this.solvedPath.length?this.tree.select(this.path.slice(0,-1)):null},e.prototype.left=function(){var t=+this.solvedPath[this.solvedPath.length-1];if(isNaN(t))throw Error("baobab.Cursor.left: cannot go left on a non-list type.");return t?this.tree.select(this.solvedPath.slice(0,-1).concat(t-1)):null},e.prototype.leftmost=function(){var t=+this.solvedPath[this.solvedPath.length-1];if(isNaN(t))throw Error("baobab.Cursor.leftmost: cannot go left on a non-list type.");return this.tree.select(this.solvedPath.slice(0,-1).concat(0))},e.prototype.right=function(){var t=+this.solvedPath[this.solvedPath.length-1];if(isNaN(t))throw Error("baobab.Cursor.right: cannot go right on a non-list type.");return t+1===this.up().get().length?null:this.tree.select(this.solvedPath.slice(0,-1).concat(t+1))},e.prototype.rightmost=function(){var t=+this.solvedPath[this.solvedPath.length-1];if(isNaN(t))throw Error("baobab.Cursor.right: cannot go right on a non-list type.");var r=this.up().get();return this.tree.select(this.solvedPath.slice(0,-1).concat(r.length-1))},e.prototype.down=function(){+this.solvedPath[this.solvedPath.length-1];return this.get()instanceof Array?this.tree.select(this.solvedPath.concat(0)):null},e.prototype.get=function(t){arguments.length>1&&(t=h.arrayOf(arguments));var r=this.solvedPath.concat((u.String(t)||u.Number(t)?[t]:t)||[]);return h.getIn(this.tree.data,r,this.tree)},i("set"),i("apply"),i("chain"),i("push","Array"),i("unshift","Array"),e.prototype.merge=function(t){if(!u.Object(t))throw Error("baobab.Cursor.merge: trying to merge a non-object.");var r=n.bind(this,"merge","Object").apply(this,arguments);return this.update(r)},e.prototype.unset=function(t){if(void 0===t&&this.isRoot())throw Error("baobab.Cursor.unset: cannot remove root node.");var r=n.bind(this,"unset",null).apply(this,[t,!0]);return this.update(r)},e.prototype.update=function(t,r){if(arguments.length<2)return this.tree.stack(h.pathObject(this.solvedPath,t)),this;var e=[].concat(t),n=h.solvePath(this.get(),e);if(!n)throw Error("baobab.Cursor.update: could not solve dynamic path.");return this.tree.stack(h.pathObject(this.solvedPath.concat(n),r)),this},e.prototype.or=function(t){return new s("or",this,t)},e.prototype.and=function(t){return new s("and",this,t)},e.prototype.release=function(){this.tree.off("update",this.updateHandler),this.hash&&delete this.tree._cursors[this.hash],delete this.tree,delete this.path,delete this.solvedPath,this.kill()},e.prototype.toJSON=function(){return this.get()},u.Cursor=function(t){return t instanceof e},r.exports=e},{"./combination.js":5,"./helpers.js":7,"./mixins.js":9,"./type.js":10,emmett:3}],7:[function(t,r){(function(e){function n(t){return Array.prototype.slice.call(t)}function i(t,r){return function(){t(),r.apply(null,arguments)}}function o(t,r){var e,n={};for(e in t)n[e]=t[e];for(e in r)n[e]=r[e];return n}function s(t){var r=t.source,e="";return t.global&&(e+="g"),t.multiline&&(e+="m"),t.ignoreCase&&(e+="i"),t.sticky&&(e+="y"),t.unicode&&(e+="u"),new RegExp(r,e)}function a(t,r){if(!r||"object"!=typeof r||r instanceof Error||"ArrayBuffer"in e&&r instanceof ArrayBuffer)return r;if(m.Array(r)){if(t){var n,i,o=[];for(n=0,i=r.length;i>n;n++)o.push(_(r[n]));return o}return r.slice(0)}if(m.Date(r))return new Date(r.getTime());if(r instanceof RegExp)return s(r);if(m.Object(r)){var a,h={};r.constructor&&r.constructor!==Object&&(h=Object.create(r.constructor.prototype));for(a in r)r.hasOwnProperty(a)&&(h[a]=t?_(r[a]):r[a]);return h}return r}function h(t,r){return function(e){return r(t(e))}}function u(t,r){var e,n;for(e=0,n=t.length;n>e;e++)if(r(t[e]))return t[e]}function c(t,r){var e,n;for(e=0,n=t.length;n>e;e++)if(r(t[e]))return e;return-1}function l(t,r){var e,n=!0;if(!t)return!1;for(e in r)if(m.Object(r[e]))n=n&&l(t[e],r[e]);else if(m.Array(r[e]))n=n&&!!~r[e].indexOf(t[e]);else if(t[e]!==r[e])return!1;return n}function f(t,r){return u(t,function(t){return l(t,r)})}function p(t,r){return c(t,function(t){return l(t,r)})}function d(t,r,e){r=r||[];var n,i,o,s=t;for(i=0,o=r.length;o>i;i++){if(!s)return;if("function"==typeof r[i]){if(!m.Array(s))return;s=u(s,r[i])}else if("object"==typeof r[i])if("$cursor"in r[i]){if(!m.Path(r[i].$cursor))throw Error("baobab.getIn: $cursor path must be an array.");n=e.get(r[i].$cursor),s=s[n]}else{if(!m.Array(s))return;s=f(s,r[i])}else s=s[r[i]]}return s}function b(t,r){var e,n,i,o=[],s=t;for(n=0,i=r.length;i>n;n++){if(!s)return null;if("function"==typeof r[n]){if(!m.Array(s))return;e=c(s,r[n]),o.push(e),s=s[e]}else if("object"==typeof r[n]){if(!m.Array(s))return;e=p(s,r[n]),o.push(e),s=s[e]}else o.push(r[n]),s=s[r[n]]||{}}return o}function y(t,r){var e,n=t.length,i={},o=i;for(n||(i=r),e=0;n>e;e++)o[t[e]]=e+1===n?r:{},o=o[t[e]];return i}function g(t,r){t.super_=r;var e=function(){};e.prototype=r.prototype,t.prototype=new e,t.prototype.constructor=t}var m=t("./type.js"),v=a.bind(null,!1),_=a.bind(null,!0);r.exports={arrayOf:n,before:i,deepClone:_,shallowClone:v,shallowMerge:o,compose:h,getIn:d,inherits:g,pathObject:y,solvePath:b}}).call(this,"undefined"!=typeof global?global:"undefined"!=typeof self?self:"undefined"!=typeof window?window:{})},{"./type.js":10}],8:[function(t,r){function e(t,r,e){s.forEach(function(r){e!==r&&delete t[r]}),t[e]=r[e]}function n(t,r){var a,h=i.shallowClone(r||{});s.forEach(function(r){t[r]&&e(h,t,r)}),t.$chain&&(s.slice(0,-1).forEach(function(t){delete h[t]}),h.$apply=h.$apply?i.compose(h.$apply,t.$chain):t.$chain),t.$push&&h.$push?h.$push=o.Array(h.$push)?h.$push.concat(t.$push):[h.$push].concat(t.$push):t.$push&&(h.$push=t.$push),t.$unshift&&h.$unshift?h.$unshift=o.Array(t.$unshift)?t.$unshift.concat(h.$unshift):[t.$unshift].concat(h.$unshift):t.$unshift&&(h.$unshift=t.$unshift);for(a in t)o.Object(t[a])?h[a]=n(t[a],h[a]):"$"!==a[0]&&(h[a]=t[a]);return h}var i=t("./helpers.js"),o=t("./type.js"),s=["$unset","$set","$merge","$apply"];r.exports=n},{"./helpers.js":7,"./type.js":10}],9:[function(t,r){var e=t("./combination.js"),n=t("./type.js");r.exports={baobab:function(t){return{mixins:[{getInitialState:function(){if(this.tree=t,!this.cursor&&!this.cursors)return{};if(this.cursor&&this.cursors)throw Error("baobab.mixin: you cannot have both `component.cursor` and `component.cursors`. Please make up your mind.");if(this.__type=null,this.__updateHandler=function(){this.setState(this.__getCursorData())}.bind(this),this.cursor){if(!n.MixinCursor(this.cursor))throw Error("baobab.mixin.cursor: invalid data (cursor, string, array or function).");n.Function(this.cursor)&&(this.cursor=this.cursor()),n.Cursor(this.cursor)||(this.cursor=t.select(this.cursor)),this.__getCursorData=function(){return{cursor:this.cursor.get()}}.bind(this),this.__type="single"}else if(this.cursors){if(!n.MixinCursors(this.cursors))throw Error("baobab.mixin.cursor: invalid data (object, array or function).");if(n.Function(this.cursors)&&(this.cursors=this.cursors()),n.Array(this.cursors))this.cursors=this.cursors.map(function(r){return n.Cursor(r)?r:t.select(r)}),this.__getCursorData=function(){return{cursors:this.cursors.map(function(t){return t.get()})}}.bind(this),this.__type="array";else{for(var r in this.cursors)n.Cursor(this.cursors[r])||(this.cursors[r]=t.select(this.cursors[r]));this.__getCursorData=function(){var t={};for(r in this.cursors)t[r]=this.cursors[r].get();return{cursors:t}}.bind(this),this.__type="object"}}return this.__getCursorData()},componentDidMount:function(){"single"===this.__type?(this.__combination=new e("or",[this.cursor]),this.__combination.on("update",this.__updateHandler)):"array"===this.__type?(this.__combination=new e("or",this.cursors),this.__combination.on("update",this.__updateHandler)):"object"===this.__type&&(this.__combination=new e("or",Object.keys(this.cursors).map(function(t){return this.cursors[t]},this)),this.__combination.on("update",this.__updateHandler))},componentWillUnmount:function(){this.__combination&&this.__combination.release()}}].concat(t.options.mixins)}},cursor:function(t){return{mixins:[{getInitialState:function(){return this.cursor=t,this.__updateHandler=function(){this.setState({cursor:this.cursor.get()})}.bind(this),{cursor:this.cursor.get()}},componentDidMount:function(){this.cursor.on("update",this.__updateHandler)},componentWillUnmount:function(){this.cursor.off("update",this.__updateHandler)}}].concat(t.tree.options.mixins)}}}},{"./combination.js":5,"./type.js":10}],10:[function(t,r){function e(t,r){return r.some(function(r){return n[r](t)})}var n={};n.Array=function(t){return Array.isArray(t)},n.Object=function(t){return!Array.isArray(t)&&"object"==typeof t&&null!==t},n.String=function(t){return"string"==typeof t},n.Number=function(t){return"number"==typeof t},n.Function=function(t){return"function"==typeof t},n.Primitive=function(t){return"string"==typeof t||"number"==typeof t||"boolean"==typeof t},n.Date=function(t){return t instanceof Date},n.NonScalar=function(t){return n.Object(t)||n.Array(t)},n.Path=function(t){var r=["String","Number","Function","Object"];return n.Array(t)?t.every(function(t){return e(t,r)}):e(t,r)},n.MixinCursor=function(t){return e(t,["String","Number","Array","Function","Cursor"])},n.MixinCursors=function(t){return e(t,["Object","Array","Function"])},n.ComplexPath=function(t){return e(t,["Object","Function"])},r.exports=n},{}],11:[function(t,r){function e(t,r){var e=new Error("baobab.update: "+r+" at path /"+t.slice(1).join("/"));return e.path=t,e}var n=t("./helpers.js"),i=t("./type.js");r.exports=function(t,r,o){if(o=o||{},!i.Object(t)&&!i.Array(t))throw Error("baobab.update: invalid target.");var s={};t={root:n.shallowClone(t)};var a=function(t,r,o,h){o=o||["root"];var u,c,l,f=o.join("λ"),p=o[o.length-1],d=Object.keys(r).some(function(t){return!!~["$unset","$set","$apply","$merge","$push","$unshift"].indexOf(t)});if(d){s[f]=!0;for(c in r){if("$unset"===c){var b=o[o.length-2];i.Array(t)?h[b]=t.slice(0,+p).concat(t.slice(+p+1)):(h[b]=n.shallowClone(t),delete h[b][p]);break}if("$set"===c){l=r.$set,t[p]=l;break}if("$apply"===c){if(u=r.$apply,"function"!=typeof u)throw e(o,"using command $apply with a non function");t[p]=u.call(null,t[p]);break}if("$merge"===c){if(l=r.$merge,!i.Object(t[p])||!i.Object(l))throw e(o,"using command $merge with a non object");t[p]=n.shallowMerge(t[p],l);break}if("$push"===c){if(l=r.$push,!i.Array(t[p]))throw e(o,"using command $push to a non array");t[p]=t[p].concat(l)}if("$unshift"===c){if(l=r.$unshift,!i.Array(t[p]))throw e(o,"using command $unshift to a non array");t[p]=[].concat(l).concat(t[p])}}}else for(c in r)t[p][c]="undefined"==typeof t[p][c]?{}:n.shallowClone(t[p][c]),a(t[p],r[c],o.concat(c),t)};return a(t,r),{data:t.root,log:Object.keys(s).map(function(t){return t.split("λ").slice(1)})}}},{"./helpers.js":7,"./type.js":10}]},{},[2])(2)}); \ No newline at end of file +!function(t){if("object"==typeof exports&&"undefined"!=typeof module)module.exports=t();else if("function"==typeof define&&define.amd)define([],t);else{var r;r="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:this,r.Baobab=t()}}(function(){var t;return function r(t,e,n){function i(s,a){if(!e[s]){if(!t[s]){var h="function"==typeof require&&require;if(!a&&h)return h(s,!0);if(o)return o(s,!0);var u=new Error("Cannot find module '"+s+"'");throw u.code="MODULE_NOT_FOUND",u}var c=e[s]={exports:{}};t[s][0].call(c.exports,function(r){var e=t[s][1][r];return i(e?e:r)},c,c.exports,r,t,e,n)}return e[s].exports}for(var o="function"==typeof require&&require,s=0;sr;r++)n.push(t[r].handler);return n}var i={once:"boolean",scope:"object"},o=function(){this._enabled=!0,this._children=[],this._handlers={},this._handlersAll=[]};o.prototype.on=function(t,r,e){var n,s,a,h,u,c;if("function"==typeof r){for(u="string"==typeof t?[t]:t,n=0,s=u.length;n!==s;n+=1)if(h=u[n]){this._handlers[h]||(this._handlers[h]=[]),c={handler:r};for(a in e||{}){if(!i[a])throw new Error('The option "'+a+'" is not recognized by Emmett.');c[a]=e[a]}this._handlers[h].push(c)}}else if(t&&"object"==typeof t&&!Array.isArray(t))for(h in t)o.prototype.on.call(this,h,t[h],r);else{if("function"!=typeof t)throw new Error("Wrong arguments.");c={handler:t};for(a in e||{}){if(!i[a])throw new Error('The option "'+a+'" is not recognized by Emmett.');c[a]=e[a]}this._handlersAll.push(c)}return this},o.prototype.once=function(t,r,e){if("function"==typeof r)e=e||{},e.once=!0,this.on(t,r,e);else{if((!t||"object"!=typeof t||Array.isArray(t))&&"function"!=typeof t)throw new Error("Wrong arguments.");r=r||{},r.once=!0,this.on(t,r)}return this},o.prototype.off=function(t,r){var e,n,i,o,s,a,h,u="string"==typeof t?[t]:t;if(1===arguments.length&&"function"==typeof u){r=arguments[0];for(s in this._handlers){for(a=[],e=0,n=this._handlers[s].length;e!==n;e+=1)this._handlers[s][e].handler!==r&&a.push(this._handlers[s][e]);this._handlers[s]=a}for(a=[],e=0,n=this._handlersAll.length;e!==n;e+=1)this._handlersAll[e].handler!==r&&a.push(this._handlersAll[e]);this._handlersAll=a}else if(2===arguments.length)for(e=0,n=u.length;e!==n;e+=1){if(h=u[e],this._handlers[h]){for(a=[],i=0,o=this._handlers[h].length;i!==o;i+=1)this._handlers[h][i].handler!==r&&a.push(this._handlers[h][i]);this._handlers[h]=a}this._handlers[h]&&0===this._handlers[h].length&&delete this._handlers[h]}return this},o.prototype.unbindAll=function(){var t;this._handlersAll=[];for(t in this._handlers)delete this._handlers[t];return this},o.prototype.emit=function(t,r){var e,n,i,o,s,a,h,u,c,l,f="string"==typeof t?[t]:t;if(!this._enabled)return this;for(r=void 0===r?{}:r,e=0,n=f.length;e!==n;e+=1)if(l=f[e],c=(this._handlers[l]||[]).concat(this._handlersAll),c.length){for(h={type:l,data:r||{},target:this},a=[],i=0,o=c.length;i!==o;i+=1)(this._handlers[l]&&this._handlers[l].indexOf(c[i])>=0||this._handlersAll.indexOf(c[i])>=0)&&(c[i].handler.call("scope"in c[i]?c[i].scope:this,h),c[i].once&&a.push(c[i]));for(s=0;se;e++)if(t._children[e]===r){t._children.splice(e,1);break}}),this._children.push(r),r},o.prototype.listeners=function(t){var e,n,i,o=[];if(t)for(o=r(this._handlers[t]),n=0,i=this._children.length;i>n;n++)o=o.concat(this._children[n].listeners(t));else{o=r(this._handlersAll);for(e in this._handlers)o=o.concat(r(this._handlers[e]));for(n=0,i=this._children.length;i>n;n++)o=o.concat(this._children[n].listeners())}return o},o.prototype.kill=function(){if(this.emit("emmett:kill"),this.unbindAll(),this._handlers=null,this._handlersAll=null,this._enabled=!1,this._children)for(var t=0,r=this._children.length;r>t;t++)this._children[t].kill();this._children=null},o.prototype.disable=function(){return this._enabled=!1,this},o.prototype.enable=function(){return this._enabled=!0,this},o.version="2.1.2","undefined"!=typeof n?("undefined"!=typeof e&&e.exports&&(n=e.exports=o),n.Emitter=o):"function"==typeof t&&t.amd?t("emmett",[],function(){return o}):this.Emitter=o}).call(this)},{}],4:[function(t,r){function e(t){return t+"$"+(new Date).getTime()+(""+Math.random()).replace("0.","")}function n(t,r){function e(t){this[t]=function(){var r=this.root[t].apply(this.root,arguments);return r instanceof i?this:r}}if(arguments.length<1&&(t={}),!(this instanceof n))return new n(t,r);if(!l.Object(t)&&!l.Array(t))throw Error("Baobab: invalid data.");o.call(this),this.options=s.shallowMerge(c,r),this._transaction={},this._future=void 0,this._cursors={},this.data=s.deepClone(t),this.root=this.select([]),["get","set","unset","update"].forEach(e.bind(this)),this.mixin=u.baobab(this)}var i=t("./cursor.js"),o=t("emmett"),s=t("./helpers.js"),a=t("./update.js"),h=t("./merge.js"),u=t("./mixins.js"),c=t("../defaults.js"),l=t("./type.js");s.inherits(n,o),n.prototype.select=function(t){if(!t)throw Error("Baobab.select: invalid path.");if(arguments.length>1&&(t=s.arrayOf(arguments)),!l.Path(t))throw Error("Baobab.select: invalid path.");t=[].concat(t);var r,n=l.ComplexPath(t);n&&(r=s.solvePath(this.data,t));var o=t.map(function(t){return l.Function(t)?e("fn"):l.Object(t)?e("ob"):t}).join("λ");if(this._cursors[o])return this._cursors[o];var a=new i(this,t,r,o);return this._cursors[o]=a,a},n.prototype.stack=function(t){var r=this;if(!l.Object(t))throw Error("Baobab.update: wrong specification.");return this._transaction=h(t,this._transaction),this.options.autoCommit?this.options.asynchronous?(this._future||(this._future=setTimeout(r.commit.bind(r,null),0)),this):this.commit():this},n.prototype.commit=function(){var t=a(this.data,this._transaction,this.options);return this.data=t.data,this._transaction={},this._future&&(this._future=clearTimeout(this._future)),this.emit("update",{log:t.log}),this},n.prototype.release=function(){delete this.data,delete this._transaction;for(var t in this._cursors)this._cursors[t].release();delete this._cursors,this.kill()},n.prototype.toJSON=function(){return this.get()},r.exports=n},{"../defaults.js":1,"./cursor.js":6,"./helpers.js":7,"./merge.js":8,"./mixins.js":9,"./type.js":10,"./update.js":11,emmett:3}],5:[function(t,r){function e(t,r){r.on("update",t.cursorListener),t.tree.off("update",t.treeListener),t.tree.on("update",t.treeListener)}function n(t){var r=this;if(arguments.length<2)throw Error("baobab.Combination: not enough arguments.");var n=arguments[1],i=s.arrayOf(arguments).slice(2);if(n instanceof Array&&(i=n.slice(1),n=n[0]),!a.Cursor(n))throw Error("baobab.Combination: argument should be a cursor.");if("or"!==t&&"and"!==t)throw Error("baobab.Combination: invalid operator.");o.call(this),this.cursors=[n],this.operators=[],this.tree=n.tree,this.updates=new Array(this.cursors.length),this.cursorListener=function(){r.updates[r.cursors.indexOf(this)]=!0},this.treeListener=function(){var t,e,n=r.updates[0];for(t=1,e=r.cursors.length;e>t;t++)n="or"===r.operators[t-1]?n||r.updates[t]:n&&r.updates[t];n&&r.emit("update"),r.updates=new Array(r.cursors.length)},this.bound=!1;var h=(this.on,this.once,function(){r.bound||(r.bound=!0,r.cursors.forEach(function(t){e(r,t)}))});this.on=s.before(h,this.on.bind(this)),this.once=s.before(h,this.once.bind(this)),i.forEach(function(r){this[t](r)},this)}function i(t){n.prototype[t]=function(r){if(!a.Cursor(r))throw this.release(),Error("baobab.Combination."+t+": argument should be a cursor.");if(~this.cursors.indexOf(r))throw this.release(),Error("baobab.Combination."+t+": cursor already in combination.");return this.cursors.push(r),this.operators.push(t),this.updates.length++,this.bound&&e(this,r),this}}var o=t("emmett"),s=t("./helpers.js"),a=t("./type.js");s.inherits(n,o),i("or"),i("and"),n.prototype.release=function(){this.cursors.forEach(function(t){t.off("update",this.cursorListener)},this),this.tree.off("update",this.treeListener),this.cursors=null,this.operators=null,this.tree=null,this.updates=null,this.kill()},r.exports=n},{"./helpers.js":7,"./type.js":10,emmett:3}],6:[function(t,r){function e(t,r,e,n){var i=this;o.call(this),r=r||[],this.tree=t,this.path=r,this.hash=n,this.complexPath=!!e,this.solvedPath=this.complexPath?e:this.path,this.relevant=void 0!==this.get(),this.updateHandler=function(t){var r,e,n,o,s,a,u=t.data.log,c=!1;if(i.complexPath&&(i.solvedPath=h.solvePath(i.tree.data,i.path)),!i.path.length)return i.emit("update");t:for(s=0,n=u.length;n>s;s++)for(r=u[s],a=0,o=r.length;o>a&&(e=r[a],e===""+i.solvedPath[a]);a++)if(a+1===o||a+1===i.solvedPath.length){c=!0;break t}var l=void 0!==i.get();i.relevant?l&&c?i.emit("update"):l||(i.emit("irrelevant"),i.relevant=!1):l&&c&&(i.emit("relevant"),i.emit("update"),i.relevant=!0)},this.mixin=a.cursor(this);var s=!1,u=function(){s||(s=!0,i.tree.on("update",i.updateHandler))};this.on=h.before(u,this.on.bind(this)),this.once=h.before(u,this.once.bind(this))}function n(t,r,e,n){arguments.length<4&&(n=e,e=[]),e=e||[];var i=[].concat(e),o=h.solvePath(this.get(),i);if(!o)throw Error("baobab.Cursor."+t+": could not solve dynamic path.");if(r){var s=this.get(o);if(!u[r](s))throw Error("baobab.Cursor."+t+": invalid target.")}var a={};a["$"+t]=n;var c=h.pathObject(o,a);return c}function i(t,r){e.prototype[t]=function(){var e=n.bind(this,t,r).apply(this,arguments);return this.update(e)}}var o=t("emmett"),s=t("./combination.js"),a=t("./mixins.js"),h=t("./helpers.js"),u=t("./type.js");h.inherits(e,o),e.prototype.isRoot=function(){return!this.path.length},e.prototype.isLeaf=function(){return u.Primitive(this.get())},e.prototype.isBranch=function(){return!this.isLeaf()&&!this.isRoot()},e.prototype.root=function(){return this.tree.root()},e.prototype.select=function(t){if(arguments.length>1&&(t=h.arrayOf(arguments)),!u.Path(t))throw Error("baobab.Cursor.select: invalid path.");return this.tree.select(this.path.concat(t))},e.prototype.up=function(){return this.solvedPath&&this.solvedPath.length?this.tree.select(this.path.slice(0,-1)):null},e.prototype.left=function(){var t=+this.solvedPath[this.solvedPath.length-1];if(isNaN(t))throw Error("baobab.Cursor.left: cannot go left on a non-list type.");return t?this.tree.select(this.solvedPath.slice(0,-1).concat(t-1)):null},e.prototype.leftmost=function(){var t=+this.solvedPath[this.solvedPath.length-1];if(isNaN(t))throw Error("baobab.Cursor.leftmost: cannot go left on a non-list type.");return this.tree.select(this.solvedPath.slice(0,-1).concat(0))},e.prototype.right=function(){var t=+this.solvedPath[this.solvedPath.length-1];if(isNaN(t))throw Error("baobab.Cursor.right: cannot go right on a non-list type.");return t+1===this.up().get().length?null:this.tree.select(this.solvedPath.slice(0,-1).concat(t+1))},e.prototype.rightmost=function(){var t=+this.solvedPath[this.solvedPath.length-1];if(isNaN(t))throw Error("baobab.Cursor.right: cannot go right on a non-list type.");var r=this.up().get();return this.tree.select(this.solvedPath.slice(0,-1).concat(r.length-1))},e.prototype.down=function(){+this.solvedPath[this.solvedPath.length-1];return this.get()instanceof Array?this.tree.select(this.solvedPath.concat(0)):null},e.prototype.get=function(t){arguments.length>1&&(t=h.arrayOf(arguments));var r=this.solvedPath.concat((u.String(t)||u.Number(t)?[t]:t)||[]);return h.getIn(this.tree.data,r,this.tree)},i("set"),i("apply"),i("chain"),i("push","Array"),i("unshift","Array"),e.prototype.merge=function(t){if(!u.Object(t))throw Error("baobab.Cursor.merge: trying to merge a non-object.");var r=n.bind(this,"merge","Object").apply(this,arguments);return this.update(r)},e.prototype.unset=function(t){if(void 0===t&&this.isRoot())throw Error("baobab.Cursor.unset: cannot remove root node.");var r=n.bind(this,"unset",null).apply(this,[t,!0]);return this.update(r)},e.prototype.update=function(t,r){if(arguments.length<2)return this.tree.stack(h.pathObject(this.solvedPath,t)),this;var e=[].concat(t),n=h.solvePath(this.get(),e);if(!n)throw Error("baobab.Cursor.update: could not solve dynamic path.");return this.tree.stack(h.pathObject(this.solvedPath.concat(n),r)),this},e.prototype.or=function(t){return new s("or",this,t)},e.prototype.and=function(t){return new s("and",this,t)},e.prototype.release=function(){this.tree.off("update",this.updateHandler),this.hash&&delete this.tree._cursors[this.hash],delete this.tree,delete this.path,delete this.solvedPath,this.kill()},e.prototype.toJSON=function(){return this.get()},u.Cursor=function(t){return t instanceof e},r.exports=e},{"./combination.js":5,"./helpers.js":7,"./mixins.js":9,"./type.js":10,emmett:3}],7:[function(t,r){(function(e){function n(t){return Array.prototype.slice.call(t)}function i(t,r){return function(){t(),r.apply(null,arguments)}}function o(t,r){var e,n={};for(e in t)n[e]=t[e];for(e in r)n[e]=r[e];return n}function s(t){var r=t.source,e="";return t.global&&(e+="g"),t.multiline&&(e+="m"),t.ignoreCase&&(e+="i"),t.sticky&&(e+="y"),t.unicode&&(e+="u"),new RegExp(r,e)}function a(t,r){if(!r||"object"!=typeof r||r instanceof Error||"ArrayBuffer"in e&&r instanceof ArrayBuffer)return r;if(v.Array(r)){if(t){var n,i,o=[];for(n=0,i=r.length;i>n;n++)o.push(j(r[n]));return o}return r.slice(0)}if(v.Date(r))return new Date(r.getTime());if(r instanceof RegExp)return s(r);if(v.Object(r)){var a,h={};r.constructor&&r.constructor!==Object&&(h=Object.create(r.constructor.prototype));for(a in r)r.hasOwnProperty(a)&&(h[a]=t?j(r[a]):r[a]);return h}return r}function h(t,r){return function(e){return r(t(e))}}function u(t,r){var e,n;for(e=0,n=t.length;n>e;e++)if(r(t[e]))return t[e]}function c(t,r){var e,n;for(e=0,n=t.length;n>e;e++)if(r(t[e]))return e;return-1}function l(t,r){var e,n=!0;if(!t)return!1;for(e in r)if(v.Object(r[e]))n=n&&l(t[e],r[e]);else if(v.Array(r[e]))n=n&&!!~r[e].indexOf(t[e]);else if(t[e]!==r[e])return!1;return n}function f(t,r){return u(t,function(t){return l(t,r)})}function d(t,r){return c(t,function(t){return l(t,r)})}function b(t,r,e){r=r||[];var n,i,o,s=t;for(i=0,o=r.length;o>i;i++){if(!s)return;if("function"==typeof r[i]){if(!v.Array(s))return;s=u(s,r[i])}else if("object"==typeof r[i])if("$cursor"in r[i]){if(!v.Path(r[i].$cursor))throw Error("baobab.getIn: $cursor path must be an array.");n=e.get(r[i].$cursor),s=s[n]}else{if(!v.Array(s))return;s=f(s,r[i])}else s=s[r[i]]}return s}function y(t,r,e){var n,i,o,s=[],a=t;for(i=0,o=r.length;o>i;i++){if(!a)return null;if("function"==typeof r[i]){if(!v.Array(a))return;n=c(a,r[i]),s.push(n),a=a[n]}else if("object"==typeof r[i]){if("$cursor"in r[i]){if(!v.Path(r[i].$cursor))throw Error("baobab.getIn: $cursor path must be an array.");p=e.get(r[i].$cursor),a=a[p]}if(!v.Array(a))return;n=d(a,r[i]),s.push(n),a=a[n]}else s.push(r[i]),a=a[r[i]]||{}}return s}function g(t,r){var e,n=t.length,i={},o=i;for(n||(i=r),e=0;n>e;e++)o[t[e]]=e+1===n?r:{},o=o[t[e]];return i}function m(t,r){t.super_=r;var e=function(){};e.prototype=r.prototype,t.prototype=new e,t.prototype.constructor=t}var v=t("./type.js"),_=a.bind(null,!1),j=a.bind(null,!0);r.exports={arrayOf:n,before:i,deepClone:j,shallowClone:_,shallowMerge:o,compose:h,getIn:b,inherits:m,pathObject:g,solvePath:y}}).call(this,"undefined"!=typeof global?global:"undefined"!=typeof self?self:"undefined"!=typeof window?window:{})},{"./type.js":10}],8:[function(t,r){function e(t,r,e){s.forEach(function(r){e!==r&&delete t[r]}),t[e]=r[e]}function n(t,r){var a,h=i.shallowClone(r||{});s.forEach(function(r){t[r]&&e(h,t,r)}),t.$chain&&(s.slice(0,-1).forEach(function(t){delete h[t]}),h.$apply=h.$apply?i.compose(h.$apply,t.$chain):t.$chain),t.$push&&h.$push?h.$push=o.Array(h.$push)?h.$push.concat(t.$push):[h.$push].concat(t.$push):t.$push&&(h.$push=t.$push),t.$unshift&&h.$unshift?h.$unshift=o.Array(t.$unshift)?t.$unshift.concat(h.$unshift):[t.$unshift].concat(h.$unshift):t.$unshift&&(h.$unshift=t.$unshift);for(a in t)o.Object(t[a])?h[a]=n(t[a],h[a]):"$"!==a[0]&&(h[a]=t[a]);return h}var i=t("./helpers.js"),o=t("./type.js"),s=["$unset","$set","$merge","$apply"];r.exports=n},{"./helpers.js":7,"./type.js":10}],9:[function(t,r){var e=t("./combination.js"),n=t("./type.js");r.exports={baobab:function(t){return{mixins:[{getInitialState:function(){if(this.tree=t,!this.cursor&&!this.cursors)return{};if(this.cursor&&this.cursors)throw Error("baobab.mixin: you cannot have both `component.cursor` and `component.cursors`. Please make up your mind.");if(this.__type=null,this.__updateHandler=function(){this.setState(this.__getCursorData())}.bind(this),this.cursor){if(!n.MixinCursor(this.cursor))throw Error("baobab.mixin.cursor: invalid data (cursor, string, array or function).");n.Function(this.cursor)&&(this.cursor=this.cursor()),n.Cursor(this.cursor)||(this.cursor=t.select(this.cursor)),this.__getCursorData=function(){return{cursor:this.cursor.get()}}.bind(this),this.__type="single"}else if(this.cursors){if(!n.MixinCursors(this.cursors))throw Error("baobab.mixin.cursor: invalid data (object, array or function).");if(n.Function(this.cursors)&&(this.cursors=this.cursors()),n.Array(this.cursors))this.cursors=this.cursors.map(function(r){return n.Cursor(r)?r:t.select(r)}),this.__getCursorData=function(){return{cursors:this.cursors.map(function(t){return t.get()})}}.bind(this),this.__type="array";else{for(var r in this.cursors)n.Cursor(this.cursors[r])||(this.cursors[r]=t.select(this.cursors[r]));this.__getCursorData=function(){var t={};for(r in this.cursors)t[r]=this.cursors[r].get();return{cursors:t}}.bind(this),this.__type="object"}}return this.__getCursorData()},componentDidMount:function(){"single"===this.__type?(this.__combination=new e("or",[this.cursor]),this.__combination.on("update",this.__updateHandler)):"array"===this.__type?(this.__combination=new e("or",this.cursors),this.__combination.on("update",this.__updateHandler)):"object"===this.__type&&(this.__combination=new e("or",Object.keys(this.cursors).map(function(t){return this.cursors[t]},this)),this.__combination.on("update",this.__updateHandler))},componentWillUnmount:function(){this.__combination&&this.__combination.release()}}].concat(t.options.mixins)}},cursor:function(t){return{mixins:[{getInitialState:function(){return this.cursor=t,this.__updateHandler=function(){this.setState({cursor:this.cursor.get()})}.bind(this),{cursor:this.cursor.get()}},componentDidMount:function(){this.cursor.on("update",this.__updateHandler)},componentWillUnmount:function(){this.cursor.off("update",this.__updateHandler)}}].concat(t.tree.options.mixins)}}}},{"./combination.js":5,"./type.js":10}],10:[function(t,r){function e(t,r){return r.some(function(r){return n[r](t)})}var n={};n.Array=function(t){return Array.isArray(t)},n.Object=function(t){return!Array.isArray(t)&&"object"==typeof t&&null!==t},n.String=function(t){return"string"==typeof t},n.Number=function(t){return"number"==typeof t},n.Function=function(t){return"function"==typeof t},n.Primitive=function(t){return"string"==typeof t||"number"==typeof t||"boolean"==typeof t},n.Date=function(t){return t instanceof Date},n.NonScalar=function(t){return n.Object(t)||n.Array(t)},n.Path=function(t){var r=["String","Number","Function","Object"];return n.Array(t)?t.every(function(t){return e(t,r)}):e(t,r)},n.MixinCursor=function(t){return e(t,["String","Number","Array","Function","Cursor"])},n.MixinCursors=function(t){return e(t,["Object","Array","Function"])},n.ComplexPath=function(t){return e(t,["Object","Function"])},r.exports=n},{}],11:[function(t,r){function e(t,r){var e=new Error("baobab.update: "+r+" at path /"+t.slice(1).join("/"));return e.path=t,e}var n=t("./helpers.js"),i=t("./type.js");r.exports=function(t,r,o){if(o=o||{},!i.Object(t)&&!i.Array(t))throw Error("baobab.update: invalid target.");var s={};t={root:n.shallowClone(t)};var a=function(t,r,o,h){o=o||["root"];var u,c,l,f=o.join("λ"),p=o[o.length-1],d=Object.keys(r).some(function(t){return!!~["$unset","$set","$apply","$merge","$push","$unshift"].indexOf(t)});if(d){s[f]=!0;for(c in r){if("$unset"===c){var b=o[o.length-2];i.Array(t)?h[b]=t.slice(0,+p).concat(t.slice(+p+1)):(h[b]=n.shallowClone(t),delete h[b][p]);break}if("$set"===c){l=r.$set,t[p]=l;break}if("$apply"===c){if(u=r.$apply,"function"!=typeof u)throw e(o,"using command $apply with a non function");t[p]=u.call(null,t[p]);break}if("$merge"===c){if(l=r.$merge,!i.Object(t[p])||!i.Object(l))throw e(o,"using command $merge with a non object");t[p]=n.shallowMerge(t[p],l);break}if("$push"===c){if(l=r.$push,!i.Array(t[p]))throw e(o,"using command $push to a non array");t[p]=t[p].concat(l)}if("$unshift"===c){if(l=r.$unshift,!i.Array(t[p]))throw e(o,"using command $unshift to a non array");t[p]=[].concat(l).concat(t[p])}}}else for(c in r)t[p][c]="undefined"==typeof t[p][c]?{}:n.shallowClone(t[p][c]),a(t[p],r[c],o.concat(c),t)};return a(t,r),{data:t.root,log:Object.keys(s).map(function(t){return t.split("λ").slice(1)})}}},{"./helpers.js":7,"./type.js":10}]},{},[2])(2)}); \ No newline at end of file diff --git a/src/helpers.js b/src/helpers.js index b9e3184..5c48fc4 100644 --- a/src/helpers.js +++ b/src/helpers.js @@ -203,7 +203,7 @@ function getIn(object, path, tree) { } // Solve a complex path -function solvePath(object, path) { +function solvePath(object, path, tree) { var solvedPath = [], c = object, idx, @@ -223,6 +223,14 @@ function solvePath(object, path) { c = c[idx]; } else if (typeof path[i] === 'object') { + if ('$cursor' in path[i]) { + if (!type.Path(path[i].$cursor)) + throw Error('baobab.getIn: $cursor path must be an array.'); + + p = tree.get(path[i].$cursor); + c = c[p]; + } + if (!type.Array(c)) return; diff --git a/test/suites/baobab.js b/test/suites/baobab.js index 6223552..1d36969 100644 --- a/test/suites/baobab.js +++ b/test/suites/baobab.js @@ -53,6 +53,18 @@ describe('Baobab API', function() { assert.deepEqual(cursor.get(), {id: 'one'}); }); + + it('should be possible to select data using a cursor pointer.', function() { + var cursor = baobab.select('one', 'subtwo', 'colors', {$cursor: ['pointer']}); + + assert.strictEqual(cursor.get(), 'yellow'); + }); + + it('should fail when providing a wrong path to the $cursor command.', function() { + assert.throws(function() { + var color = baobab.select('one', 'subtwo', 'colors', {$cursor: null}); + }, /\$cursor/); + }); }); describe('Events', function() { From bc70a3096039be413a063ed1cd22dfcf0f26fee2 Mon Sep 17 00:00:00 2001 From: Yomguithereal Date: Wed, 8 Apr 2015 17:30:16 +0200 Subject: [PATCH 26/73] Starting iterating on history --- build/baobab.min.js | 2 +- src/cursor.js | 32 ++++++++++++++++++++++++++++++++ src/helpers.js | 22 ++++++++++++++++++++++ 3 files changed, 55 insertions(+), 1 deletion(-) diff --git a/build/baobab.min.js b/build/baobab.min.js index c842263..a8d334a 100644 --- a/build/baobab.min.js +++ b/build/baobab.min.js @@ -1,2 +1,2 @@ /* baobab.js - Version: 1.0.0-rc1 - Author: Yomguithereal (Guillaume Plique) */ -!function(t){if("object"==typeof exports&&"undefined"!=typeof module)module.exports=t();else if("function"==typeof define&&define.amd)define([],t);else{var r;r="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:this,r.Baobab=t()}}(function(){var t;return function r(t,e,n){function i(s,a){if(!e[s]){if(!t[s]){var h="function"==typeof require&&require;if(!a&&h)return h(s,!0);if(o)return o(s,!0);var u=new Error("Cannot find module '"+s+"'");throw u.code="MODULE_NOT_FOUND",u}var c=e[s]={exports:{}};t[s][0].call(c.exports,function(r){var e=t[s][1][r];return i(e?e:r)},c,c.exports,r,t,e,n)}return e[s].exports}for(var o="function"==typeof require&&require,s=0;sr;r++)n.push(t[r].handler);return n}var i={once:"boolean",scope:"object"},o=function(){this._enabled=!0,this._children=[],this._handlers={},this._handlersAll=[]};o.prototype.on=function(t,r,e){var n,s,a,h,u,c;if("function"==typeof r){for(u="string"==typeof t?[t]:t,n=0,s=u.length;n!==s;n+=1)if(h=u[n]){this._handlers[h]||(this._handlers[h]=[]),c={handler:r};for(a in e||{}){if(!i[a])throw new Error('The option "'+a+'" is not recognized by Emmett.');c[a]=e[a]}this._handlers[h].push(c)}}else if(t&&"object"==typeof t&&!Array.isArray(t))for(h in t)o.prototype.on.call(this,h,t[h],r);else{if("function"!=typeof t)throw new Error("Wrong arguments.");c={handler:t};for(a in e||{}){if(!i[a])throw new Error('The option "'+a+'" is not recognized by Emmett.');c[a]=e[a]}this._handlersAll.push(c)}return this},o.prototype.once=function(t,r,e){if("function"==typeof r)e=e||{},e.once=!0,this.on(t,r,e);else{if((!t||"object"!=typeof t||Array.isArray(t))&&"function"!=typeof t)throw new Error("Wrong arguments.");r=r||{},r.once=!0,this.on(t,r)}return this},o.prototype.off=function(t,r){var e,n,i,o,s,a,h,u="string"==typeof t?[t]:t;if(1===arguments.length&&"function"==typeof u){r=arguments[0];for(s in this._handlers){for(a=[],e=0,n=this._handlers[s].length;e!==n;e+=1)this._handlers[s][e].handler!==r&&a.push(this._handlers[s][e]);this._handlers[s]=a}for(a=[],e=0,n=this._handlersAll.length;e!==n;e+=1)this._handlersAll[e].handler!==r&&a.push(this._handlersAll[e]);this._handlersAll=a}else if(2===arguments.length)for(e=0,n=u.length;e!==n;e+=1){if(h=u[e],this._handlers[h]){for(a=[],i=0,o=this._handlers[h].length;i!==o;i+=1)this._handlers[h][i].handler!==r&&a.push(this._handlers[h][i]);this._handlers[h]=a}this._handlers[h]&&0===this._handlers[h].length&&delete this._handlers[h]}return this},o.prototype.unbindAll=function(){var t;this._handlersAll=[];for(t in this._handlers)delete this._handlers[t];return this},o.prototype.emit=function(t,r){var e,n,i,o,s,a,h,u,c,l,f="string"==typeof t?[t]:t;if(!this._enabled)return this;for(r=void 0===r?{}:r,e=0,n=f.length;e!==n;e+=1)if(l=f[e],c=(this._handlers[l]||[]).concat(this._handlersAll),c.length){for(h={type:l,data:r||{},target:this},a=[],i=0,o=c.length;i!==o;i+=1)(this._handlers[l]&&this._handlers[l].indexOf(c[i])>=0||this._handlersAll.indexOf(c[i])>=0)&&(c[i].handler.call("scope"in c[i]?c[i].scope:this,h),c[i].once&&a.push(c[i]));for(s=0;se;e++)if(t._children[e]===r){t._children.splice(e,1);break}}),this._children.push(r),r},o.prototype.listeners=function(t){var e,n,i,o=[];if(t)for(o=r(this._handlers[t]),n=0,i=this._children.length;i>n;n++)o=o.concat(this._children[n].listeners(t));else{o=r(this._handlersAll);for(e in this._handlers)o=o.concat(r(this._handlers[e]));for(n=0,i=this._children.length;i>n;n++)o=o.concat(this._children[n].listeners())}return o},o.prototype.kill=function(){if(this.emit("emmett:kill"),this.unbindAll(),this._handlers=null,this._handlersAll=null,this._enabled=!1,this._children)for(var t=0,r=this._children.length;r>t;t++)this._children[t].kill();this._children=null},o.prototype.disable=function(){return this._enabled=!1,this},o.prototype.enable=function(){return this._enabled=!0,this},o.version="2.1.2","undefined"!=typeof n?("undefined"!=typeof e&&e.exports&&(n=e.exports=o),n.Emitter=o):"function"==typeof t&&t.amd?t("emmett",[],function(){return o}):this.Emitter=o}).call(this)},{}],4:[function(t,r){function e(t){return t+"$"+(new Date).getTime()+(""+Math.random()).replace("0.","")}function n(t,r){function e(t){this[t]=function(){var r=this.root[t].apply(this.root,arguments);return r instanceof i?this:r}}if(arguments.length<1&&(t={}),!(this instanceof n))return new n(t,r);if(!l.Object(t)&&!l.Array(t))throw Error("Baobab: invalid data.");o.call(this),this.options=s.shallowMerge(c,r),this._transaction={},this._future=void 0,this._cursors={},this.data=s.deepClone(t),this.root=this.select([]),["get","set","unset","update"].forEach(e.bind(this)),this.mixin=u.baobab(this)}var i=t("./cursor.js"),o=t("emmett"),s=t("./helpers.js"),a=t("./update.js"),h=t("./merge.js"),u=t("./mixins.js"),c=t("../defaults.js"),l=t("./type.js");s.inherits(n,o),n.prototype.select=function(t){if(!t)throw Error("Baobab.select: invalid path.");if(arguments.length>1&&(t=s.arrayOf(arguments)),!l.Path(t))throw Error("Baobab.select: invalid path.");t=[].concat(t);var r,n=l.ComplexPath(t);n&&(r=s.solvePath(this.data,t));var o=t.map(function(t){return l.Function(t)?e("fn"):l.Object(t)?e("ob"):t}).join("λ");if(this._cursors[o])return this._cursors[o];var a=new i(this,t,r,o);return this._cursors[o]=a,a},n.prototype.stack=function(t){var r=this;if(!l.Object(t))throw Error("Baobab.update: wrong specification.");return this._transaction=h(t,this._transaction),this.options.autoCommit?this.options.asynchronous?(this._future||(this._future=setTimeout(r.commit.bind(r,null),0)),this):this.commit():this},n.prototype.commit=function(){var t=a(this.data,this._transaction,this.options);return this.data=t.data,this._transaction={},this._future&&(this._future=clearTimeout(this._future)),this.emit("update",{log:t.log}),this},n.prototype.release=function(){delete this.data,delete this._transaction;for(var t in this._cursors)this._cursors[t].release();delete this._cursors,this.kill()},n.prototype.toJSON=function(){return this.get()},r.exports=n},{"../defaults.js":1,"./cursor.js":6,"./helpers.js":7,"./merge.js":8,"./mixins.js":9,"./type.js":10,"./update.js":11,emmett:3}],5:[function(t,r){function e(t,r){r.on("update",t.cursorListener),t.tree.off("update",t.treeListener),t.tree.on("update",t.treeListener)}function n(t){var r=this;if(arguments.length<2)throw Error("baobab.Combination: not enough arguments.");var n=arguments[1],i=s.arrayOf(arguments).slice(2);if(n instanceof Array&&(i=n.slice(1),n=n[0]),!a.Cursor(n))throw Error("baobab.Combination: argument should be a cursor.");if("or"!==t&&"and"!==t)throw Error("baobab.Combination: invalid operator.");o.call(this),this.cursors=[n],this.operators=[],this.tree=n.tree,this.updates=new Array(this.cursors.length),this.cursorListener=function(){r.updates[r.cursors.indexOf(this)]=!0},this.treeListener=function(){var t,e,n=r.updates[0];for(t=1,e=r.cursors.length;e>t;t++)n="or"===r.operators[t-1]?n||r.updates[t]:n&&r.updates[t];n&&r.emit("update"),r.updates=new Array(r.cursors.length)},this.bound=!1;var h=(this.on,this.once,function(){r.bound||(r.bound=!0,r.cursors.forEach(function(t){e(r,t)}))});this.on=s.before(h,this.on.bind(this)),this.once=s.before(h,this.once.bind(this)),i.forEach(function(r){this[t](r)},this)}function i(t){n.prototype[t]=function(r){if(!a.Cursor(r))throw this.release(),Error("baobab.Combination."+t+": argument should be a cursor.");if(~this.cursors.indexOf(r))throw this.release(),Error("baobab.Combination."+t+": cursor already in combination.");return this.cursors.push(r),this.operators.push(t),this.updates.length++,this.bound&&e(this,r),this}}var o=t("emmett"),s=t("./helpers.js"),a=t("./type.js");s.inherits(n,o),i("or"),i("and"),n.prototype.release=function(){this.cursors.forEach(function(t){t.off("update",this.cursorListener)},this),this.tree.off("update",this.treeListener),this.cursors=null,this.operators=null,this.tree=null,this.updates=null,this.kill()},r.exports=n},{"./helpers.js":7,"./type.js":10,emmett:3}],6:[function(t,r){function e(t,r,e,n){var i=this;o.call(this),r=r||[],this.tree=t,this.path=r,this.hash=n,this.complexPath=!!e,this.solvedPath=this.complexPath?e:this.path,this.relevant=void 0!==this.get(),this.updateHandler=function(t){var r,e,n,o,s,a,u=t.data.log,c=!1;if(i.complexPath&&(i.solvedPath=h.solvePath(i.tree.data,i.path)),!i.path.length)return i.emit("update");t:for(s=0,n=u.length;n>s;s++)for(r=u[s],a=0,o=r.length;o>a&&(e=r[a],e===""+i.solvedPath[a]);a++)if(a+1===o||a+1===i.solvedPath.length){c=!0;break t}var l=void 0!==i.get();i.relevant?l&&c?i.emit("update"):l||(i.emit("irrelevant"),i.relevant=!1):l&&c&&(i.emit("relevant"),i.emit("update"),i.relevant=!0)},this.mixin=a.cursor(this);var s=!1,u=function(){s||(s=!0,i.tree.on("update",i.updateHandler))};this.on=h.before(u,this.on.bind(this)),this.once=h.before(u,this.once.bind(this))}function n(t,r,e,n){arguments.length<4&&(n=e,e=[]),e=e||[];var i=[].concat(e),o=h.solvePath(this.get(),i);if(!o)throw Error("baobab.Cursor."+t+": could not solve dynamic path.");if(r){var s=this.get(o);if(!u[r](s))throw Error("baobab.Cursor."+t+": invalid target.")}var a={};a["$"+t]=n;var c=h.pathObject(o,a);return c}function i(t,r){e.prototype[t]=function(){var e=n.bind(this,t,r).apply(this,arguments);return this.update(e)}}var o=t("emmett"),s=t("./combination.js"),a=t("./mixins.js"),h=t("./helpers.js"),u=t("./type.js");h.inherits(e,o),e.prototype.isRoot=function(){return!this.path.length},e.prototype.isLeaf=function(){return u.Primitive(this.get())},e.prototype.isBranch=function(){return!this.isLeaf()&&!this.isRoot()},e.prototype.root=function(){return this.tree.root()},e.prototype.select=function(t){if(arguments.length>1&&(t=h.arrayOf(arguments)),!u.Path(t))throw Error("baobab.Cursor.select: invalid path.");return this.tree.select(this.path.concat(t))},e.prototype.up=function(){return this.solvedPath&&this.solvedPath.length?this.tree.select(this.path.slice(0,-1)):null},e.prototype.left=function(){var t=+this.solvedPath[this.solvedPath.length-1];if(isNaN(t))throw Error("baobab.Cursor.left: cannot go left on a non-list type.");return t?this.tree.select(this.solvedPath.slice(0,-1).concat(t-1)):null},e.prototype.leftmost=function(){var t=+this.solvedPath[this.solvedPath.length-1];if(isNaN(t))throw Error("baobab.Cursor.leftmost: cannot go left on a non-list type.");return this.tree.select(this.solvedPath.slice(0,-1).concat(0))},e.prototype.right=function(){var t=+this.solvedPath[this.solvedPath.length-1];if(isNaN(t))throw Error("baobab.Cursor.right: cannot go right on a non-list type.");return t+1===this.up().get().length?null:this.tree.select(this.solvedPath.slice(0,-1).concat(t+1))},e.prototype.rightmost=function(){var t=+this.solvedPath[this.solvedPath.length-1];if(isNaN(t))throw Error("baobab.Cursor.right: cannot go right on a non-list type.");var r=this.up().get();return this.tree.select(this.solvedPath.slice(0,-1).concat(r.length-1))},e.prototype.down=function(){+this.solvedPath[this.solvedPath.length-1];return this.get()instanceof Array?this.tree.select(this.solvedPath.concat(0)):null},e.prototype.get=function(t){arguments.length>1&&(t=h.arrayOf(arguments));var r=this.solvedPath.concat((u.String(t)||u.Number(t)?[t]:t)||[]);return h.getIn(this.tree.data,r,this.tree)},i("set"),i("apply"),i("chain"),i("push","Array"),i("unshift","Array"),e.prototype.merge=function(t){if(!u.Object(t))throw Error("baobab.Cursor.merge: trying to merge a non-object.");var r=n.bind(this,"merge","Object").apply(this,arguments);return this.update(r)},e.prototype.unset=function(t){if(void 0===t&&this.isRoot())throw Error("baobab.Cursor.unset: cannot remove root node.");var r=n.bind(this,"unset",null).apply(this,[t,!0]);return this.update(r)},e.prototype.update=function(t,r){if(arguments.length<2)return this.tree.stack(h.pathObject(this.solvedPath,t)),this;var e=[].concat(t),n=h.solvePath(this.get(),e);if(!n)throw Error("baobab.Cursor.update: could not solve dynamic path.");return this.tree.stack(h.pathObject(this.solvedPath.concat(n),r)),this},e.prototype.or=function(t){return new s("or",this,t)},e.prototype.and=function(t){return new s("and",this,t)},e.prototype.release=function(){this.tree.off("update",this.updateHandler),this.hash&&delete this.tree._cursors[this.hash],delete this.tree,delete this.path,delete this.solvedPath,this.kill()},e.prototype.toJSON=function(){return this.get()},u.Cursor=function(t){return t instanceof e},r.exports=e},{"./combination.js":5,"./helpers.js":7,"./mixins.js":9,"./type.js":10,emmett:3}],7:[function(t,r){(function(e){function n(t){return Array.prototype.slice.call(t)}function i(t,r){return function(){t(),r.apply(null,arguments)}}function o(t,r){var e,n={};for(e in t)n[e]=t[e];for(e in r)n[e]=r[e];return n}function s(t){var r=t.source,e="";return t.global&&(e+="g"),t.multiline&&(e+="m"),t.ignoreCase&&(e+="i"),t.sticky&&(e+="y"),t.unicode&&(e+="u"),new RegExp(r,e)}function a(t,r){if(!r||"object"!=typeof r||r instanceof Error||"ArrayBuffer"in e&&r instanceof ArrayBuffer)return r;if(v.Array(r)){if(t){var n,i,o=[];for(n=0,i=r.length;i>n;n++)o.push(j(r[n]));return o}return r.slice(0)}if(v.Date(r))return new Date(r.getTime());if(r instanceof RegExp)return s(r);if(v.Object(r)){var a,h={};r.constructor&&r.constructor!==Object&&(h=Object.create(r.constructor.prototype));for(a in r)r.hasOwnProperty(a)&&(h[a]=t?j(r[a]):r[a]);return h}return r}function h(t,r){return function(e){return r(t(e))}}function u(t,r){var e,n;for(e=0,n=t.length;n>e;e++)if(r(t[e]))return t[e]}function c(t,r){var e,n;for(e=0,n=t.length;n>e;e++)if(r(t[e]))return e;return-1}function l(t,r){var e,n=!0;if(!t)return!1;for(e in r)if(v.Object(r[e]))n=n&&l(t[e],r[e]);else if(v.Array(r[e]))n=n&&!!~r[e].indexOf(t[e]);else if(t[e]!==r[e])return!1;return n}function f(t,r){return u(t,function(t){return l(t,r)})}function d(t,r){return c(t,function(t){return l(t,r)})}function b(t,r,e){r=r||[];var n,i,o,s=t;for(i=0,o=r.length;o>i;i++){if(!s)return;if("function"==typeof r[i]){if(!v.Array(s))return;s=u(s,r[i])}else if("object"==typeof r[i])if("$cursor"in r[i]){if(!v.Path(r[i].$cursor))throw Error("baobab.getIn: $cursor path must be an array.");n=e.get(r[i].$cursor),s=s[n]}else{if(!v.Array(s))return;s=f(s,r[i])}else s=s[r[i]]}return s}function y(t,r,e){var n,i,o,s=[],a=t;for(i=0,o=r.length;o>i;i++){if(!a)return null;if("function"==typeof r[i]){if(!v.Array(a))return;n=c(a,r[i]),s.push(n),a=a[n]}else if("object"==typeof r[i]){if("$cursor"in r[i]){if(!v.Path(r[i].$cursor))throw Error("baobab.getIn: $cursor path must be an array.");p=e.get(r[i].$cursor),a=a[p]}if(!v.Array(a))return;n=d(a,r[i]),s.push(n),a=a[n]}else s.push(r[i]),a=a[r[i]]||{}}return s}function g(t,r){var e,n=t.length,i={},o=i;for(n||(i=r),e=0;n>e;e++)o[t[e]]=e+1===n?r:{},o=o[t[e]];return i}function m(t,r){t.super_=r;var e=function(){};e.prototype=r.prototype,t.prototype=new e,t.prototype.constructor=t}var v=t("./type.js"),_=a.bind(null,!1),j=a.bind(null,!0);r.exports={arrayOf:n,before:i,deepClone:j,shallowClone:_,shallowMerge:o,compose:h,getIn:b,inherits:m,pathObject:g,solvePath:y}}).call(this,"undefined"!=typeof global?global:"undefined"!=typeof self?self:"undefined"!=typeof window?window:{})},{"./type.js":10}],8:[function(t,r){function e(t,r,e){s.forEach(function(r){e!==r&&delete t[r]}),t[e]=r[e]}function n(t,r){var a,h=i.shallowClone(r||{});s.forEach(function(r){t[r]&&e(h,t,r)}),t.$chain&&(s.slice(0,-1).forEach(function(t){delete h[t]}),h.$apply=h.$apply?i.compose(h.$apply,t.$chain):t.$chain),t.$push&&h.$push?h.$push=o.Array(h.$push)?h.$push.concat(t.$push):[h.$push].concat(t.$push):t.$push&&(h.$push=t.$push),t.$unshift&&h.$unshift?h.$unshift=o.Array(t.$unshift)?t.$unshift.concat(h.$unshift):[t.$unshift].concat(h.$unshift):t.$unshift&&(h.$unshift=t.$unshift);for(a in t)o.Object(t[a])?h[a]=n(t[a],h[a]):"$"!==a[0]&&(h[a]=t[a]);return h}var i=t("./helpers.js"),o=t("./type.js"),s=["$unset","$set","$merge","$apply"];r.exports=n},{"./helpers.js":7,"./type.js":10}],9:[function(t,r){var e=t("./combination.js"),n=t("./type.js");r.exports={baobab:function(t){return{mixins:[{getInitialState:function(){if(this.tree=t,!this.cursor&&!this.cursors)return{};if(this.cursor&&this.cursors)throw Error("baobab.mixin: you cannot have both `component.cursor` and `component.cursors`. Please make up your mind.");if(this.__type=null,this.__updateHandler=function(){this.setState(this.__getCursorData())}.bind(this),this.cursor){if(!n.MixinCursor(this.cursor))throw Error("baobab.mixin.cursor: invalid data (cursor, string, array or function).");n.Function(this.cursor)&&(this.cursor=this.cursor()),n.Cursor(this.cursor)||(this.cursor=t.select(this.cursor)),this.__getCursorData=function(){return{cursor:this.cursor.get()}}.bind(this),this.__type="single"}else if(this.cursors){if(!n.MixinCursors(this.cursors))throw Error("baobab.mixin.cursor: invalid data (object, array or function).");if(n.Function(this.cursors)&&(this.cursors=this.cursors()),n.Array(this.cursors))this.cursors=this.cursors.map(function(r){return n.Cursor(r)?r:t.select(r)}),this.__getCursorData=function(){return{cursors:this.cursors.map(function(t){return t.get()})}}.bind(this),this.__type="array";else{for(var r in this.cursors)n.Cursor(this.cursors[r])||(this.cursors[r]=t.select(this.cursors[r]));this.__getCursorData=function(){var t={};for(r in this.cursors)t[r]=this.cursors[r].get();return{cursors:t}}.bind(this),this.__type="object"}}return this.__getCursorData()},componentDidMount:function(){"single"===this.__type?(this.__combination=new e("or",[this.cursor]),this.__combination.on("update",this.__updateHandler)):"array"===this.__type?(this.__combination=new e("or",this.cursors),this.__combination.on("update",this.__updateHandler)):"object"===this.__type&&(this.__combination=new e("or",Object.keys(this.cursors).map(function(t){return this.cursors[t]},this)),this.__combination.on("update",this.__updateHandler))},componentWillUnmount:function(){this.__combination&&this.__combination.release()}}].concat(t.options.mixins)}},cursor:function(t){return{mixins:[{getInitialState:function(){return this.cursor=t,this.__updateHandler=function(){this.setState({cursor:this.cursor.get()})}.bind(this),{cursor:this.cursor.get()}},componentDidMount:function(){this.cursor.on("update",this.__updateHandler)},componentWillUnmount:function(){this.cursor.off("update",this.__updateHandler)}}].concat(t.tree.options.mixins)}}}},{"./combination.js":5,"./type.js":10}],10:[function(t,r){function e(t,r){return r.some(function(r){return n[r](t)})}var n={};n.Array=function(t){return Array.isArray(t)},n.Object=function(t){return!Array.isArray(t)&&"object"==typeof t&&null!==t},n.String=function(t){return"string"==typeof t},n.Number=function(t){return"number"==typeof t},n.Function=function(t){return"function"==typeof t},n.Primitive=function(t){return"string"==typeof t||"number"==typeof t||"boolean"==typeof t},n.Date=function(t){return t instanceof Date},n.NonScalar=function(t){return n.Object(t)||n.Array(t)},n.Path=function(t){var r=["String","Number","Function","Object"];return n.Array(t)?t.every(function(t){return e(t,r)}):e(t,r)},n.MixinCursor=function(t){return e(t,["String","Number","Array","Function","Cursor"])},n.MixinCursors=function(t){return e(t,["Object","Array","Function"])},n.ComplexPath=function(t){return e(t,["Object","Function"])},r.exports=n},{}],11:[function(t,r){function e(t,r){var e=new Error("baobab.update: "+r+" at path /"+t.slice(1).join("/"));return e.path=t,e}var n=t("./helpers.js"),i=t("./type.js");r.exports=function(t,r,o){if(o=o||{},!i.Object(t)&&!i.Array(t))throw Error("baobab.update: invalid target.");var s={};t={root:n.shallowClone(t)};var a=function(t,r,o,h){o=o||["root"];var u,c,l,f=o.join("λ"),p=o[o.length-1],d=Object.keys(r).some(function(t){return!!~["$unset","$set","$apply","$merge","$push","$unshift"].indexOf(t)});if(d){s[f]=!0;for(c in r){if("$unset"===c){var b=o[o.length-2];i.Array(t)?h[b]=t.slice(0,+p).concat(t.slice(+p+1)):(h[b]=n.shallowClone(t),delete h[b][p]);break}if("$set"===c){l=r.$set,t[p]=l;break}if("$apply"===c){if(u=r.$apply,"function"!=typeof u)throw e(o,"using command $apply with a non function");t[p]=u.call(null,t[p]);break}if("$merge"===c){if(l=r.$merge,!i.Object(t[p])||!i.Object(l))throw e(o,"using command $merge with a non object");t[p]=n.shallowMerge(t[p],l);break}if("$push"===c){if(l=r.$push,!i.Array(t[p]))throw e(o,"using command $push to a non array");t[p]=t[p].concat(l)}if("$unshift"===c){if(l=r.$unshift,!i.Array(t[p]))throw e(o,"using command $unshift to a non array");t[p]=[].concat(l).concat(t[p])}}}else for(c in r)t[p][c]="undefined"==typeof t[p][c]?{}:n.shallowClone(t[p][c]),a(t[p],r[c],o.concat(c),t)};return a(t,r),{data:t.root,log:Object.keys(s).map(function(t){return t.split("λ").slice(1)})}}},{"./helpers.js":7,"./type.js":10}]},{},[2])(2)}); \ No newline at end of file +!function(t){if("object"==typeof exports&&"undefined"!=typeof module)module.exports=t();else if("function"==typeof define&&define.amd)define([],t);else{var r;r="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:this,r.Baobab=t()}}(function(){var t;return function r(t,e,n){function i(s,a){if(!e[s]){if(!t[s]){var h="function"==typeof require&&require;if(!a&&h)return h(s,!0);if(o)return o(s,!0);var u=new Error("Cannot find module '"+s+"'");throw u.code="MODULE_NOT_FOUND",u}var c=e[s]={exports:{}};t[s][0].call(c.exports,function(r){var e=t[s][1][r];return i(e?e:r)},c,c.exports,r,t,e,n)}return e[s].exports}for(var o="function"==typeof require&&require,s=0;sr;r++)n.push(t[r].handler);return n}var i={once:"boolean",scope:"object"},o=function(){this._enabled=!0,this._children=[],this._handlers={},this._handlersAll=[]};o.prototype.on=function(t,r,e){var n,s,a,h,u,c;if("function"==typeof r){for(u="string"==typeof t?[t]:t,n=0,s=u.length;n!==s;n+=1)if(h=u[n]){this._handlers[h]||(this._handlers[h]=[]),c={handler:r};for(a in e||{}){if(!i[a])throw new Error('The option "'+a+'" is not recognized by Emmett.');c[a]=e[a]}this._handlers[h].push(c)}}else if(t&&"object"==typeof t&&!Array.isArray(t))for(h in t)o.prototype.on.call(this,h,t[h],r);else{if("function"!=typeof t)throw new Error("Wrong arguments.");c={handler:t};for(a in e||{}){if(!i[a])throw new Error('The option "'+a+'" is not recognized by Emmett.');c[a]=e[a]}this._handlersAll.push(c)}return this},o.prototype.once=function(t,r,e){if("function"==typeof r)e=e||{},e.once=!0,this.on(t,r,e);else{if((!t||"object"!=typeof t||Array.isArray(t))&&"function"!=typeof t)throw new Error("Wrong arguments.");r=r||{},r.once=!0,this.on(t,r)}return this},o.prototype.off=function(t,r){var e,n,i,o,s,a,h,u="string"==typeof t?[t]:t;if(1===arguments.length&&"function"==typeof u){r=arguments[0];for(s in this._handlers){for(a=[],e=0,n=this._handlers[s].length;e!==n;e+=1)this._handlers[s][e].handler!==r&&a.push(this._handlers[s][e]);this._handlers[s]=a}for(a=[],e=0,n=this._handlersAll.length;e!==n;e+=1)this._handlersAll[e].handler!==r&&a.push(this._handlersAll[e]);this._handlersAll=a}else if(2===arguments.length)for(e=0,n=u.length;e!==n;e+=1){if(h=u[e],this._handlers[h]){for(a=[],i=0,o=this._handlers[h].length;i!==o;i+=1)this._handlers[h][i].handler!==r&&a.push(this._handlers[h][i]);this._handlers[h]=a}this._handlers[h]&&0===this._handlers[h].length&&delete this._handlers[h]}return this},o.prototype.unbindAll=function(){var t;this._handlersAll=[];for(t in this._handlers)delete this._handlers[t];return this},o.prototype.emit=function(t,r){var e,n,i,o,s,a,h,u,c,l,f="string"==typeof t?[t]:t;if(!this._enabled)return this;for(r=void 0===r?{}:r,e=0,n=f.length;e!==n;e+=1)if(l=f[e],c=(this._handlers[l]||[]).concat(this._handlersAll),c.length){for(h={type:l,data:r||{},target:this},a=[],i=0,o=c.length;i!==o;i+=1)(this._handlers[l]&&this._handlers[l].indexOf(c[i])>=0||this._handlersAll.indexOf(c[i])>=0)&&(c[i].handler.call("scope"in c[i]?c[i].scope:this,h),c[i].once&&a.push(c[i]));for(s=0;se;e++)if(t._children[e]===r){t._children.splice(e,1);break}}),this._children.push(r),r},o.prototype.listeners=function(t){var e,n,i,o=[];if(t)for(o=r(this._handlers[t]),n=0,i=this._children.length;i>n;n++)o=o.concat(this._children[n].listeners(t));else{o=r(this._handlersAll);for(e in this._handlers)o=o.concat(r(this._handlers[e]));for(n=0,i=this._children.length;i>n;n++)o=o.concat(this._children[n].listeners())}return o},o.prototype.kill=function(){if(this.emit("emmett:kill"),this.unbindAll(),this._handlers=null,this._handlersAll=null,this._enabled=!1,this._children)for(var t=0,r=this._children.length;r>t;t++)this._children[t].kill();this._children=null},o.prototype.disable=function(){return this._enabled=!1,this},o.prototype.enable=function(){return this._enabled=!0,this},o.version="2.1.2","undefined"!=typeof n?("undefined"!=typeof e&&e.exports&&(n=e.exports=o),n.Emitter=o):"function"==typeof t&&t.amd?t("emmett",[],function(){return o}):this.Emitter=o}).call(this)},{}],4:[function(t,r){function e(t){return t+"$"+(new Date).getTime()+(""+Math.random()).replace("0.","")}function n(t,r){function e(t){this[t]=function(){var r=this.root[t].apply(this.root,arguments);return r instanceof i?this:r}}if(arguments.length<1&&(t={}),!(this instanceof n))return new n(t,r);if(!l.Object(t)&&!l.Array(t))throw Error("Baobab: invalid data.");o.call(this),this.options=s.shallowMerge(c,r),this._transaction={},this._future=void 0,this._cursors={},this.data=s.deepClone(t),this.root=this.select([]),["get","set","unset","update"].forEach(e.bind(this)),this.mixin=u.baobab(this)}var i=t("./cursor.js"),o=t("emmett"),s=t("./helpers.js"),a=t("./update.js"),h=t("./merge.js"),u=t("./mixins.js"),c=t("../defaults.js"),l=t("./type.js");s.inherits(n,o),n.prototype.select=function(t){if(!t)throw Error("Baobab.select: invalid path.");if(arguments.length>1&&(t=s.arrayOf(arguments)),!l.Path(t))throw Error("Baobab.select: invalid path.");t=[].concat(t);var r,n=l.ComplexPath(t);n&&(r=s.solvePath(this.data,t));var o=t.map(function(t){return l.Function(t)?e("fn"):l.Object(t)?e("ob"):t}).join("λ");if(this._cursors[o])return this._cursors[o];var a=new i(this,t,r,o);return this._cursors[o]=a,a},n.prototype.stack=function(t){var r=this;if(!l.Object(t))throw Error("Baobab.update: wrong specification.");return this._transaction=h(t,this._transaction),this.options.autoCommit?this.options.asynchronous?(this._future||(this._future=setTimeout(r.commit.bind(r,null),0)),this):this.commit():this},n.prototype.commit=function(){var t=a(this.data,this._transaction,this.options);return this.data=t.data,this._transaction={},this._future&&(this._future=clearTimeout(this._future)),this.emit("update",{log:t.log}),this},n.prototype.release=function(){delete this.data,delete this._transaction;for(var t in this._cursors)this._cursors[t].release();delete this._cursors,this.kill()},n.prototype.toJSON=function(){return this.get()},r.exports=n},{"../defaults.js":1,"./cursor.js":6,"./helpers.js":7,"./merge.js":8,"./mixins.js":9,"./type.js":10,"./update.js":11,emmett:3}],5:[function(t,r){function e(t,r){r.on("update",t.cursorListener),t.tree.off("update",t.treeListener),t.tree.on("update",t.treeListener)}function n(t){var r=this;if(arguments.length<2)throw Error("baobab.Combination: not enough arguments.");var n=arguments[1],i=s.arrayOf(arguments).slice(2);if(n instanceof Array&&(i=n.slice(1),n=n[0]),!a.Cursor(n))throw Error("baobab.Combination: argument should be a cursor.");if("or"!==t&&"and"!==t)throw Error("baobab.Combination: invalid operator.");o.call(this),this.cursors=[n],this.operators=[],this.tree=n.tree,this.updates=new Array(this.cursors.length),this.cursorListener=function(){r.updates[r.cursors.indexOf(this)]=!0},this.treeListener=function(){var t,e,n=r.updates[0];for(t=1,e=r.cursors.length;e>t;t++)n="or"===r.operators[t-1]?n||r.updates[t]:n&&r.updates[t];n&&r.emit("update"),r.updates=new Array(r.cursors.length)},this.bound=!1;var h=(this.on,this.once,function(){r.bound||(r.bound=!0,r.cursors.forEach(function(t){e(r,t)}))});this.on=s.before(h,this.on.bind(this)),this.once=s.before(h,this.once.bind(this)),i.forEach(function(r){this[t](r)},this)}function i(t){n.prototype[t]=function(r){if(!a.Cursor(r))throw this.release(),Error("baobab.Combination."+t+": argument should be a cursor.");if(~this.cursors.indexOf(r))throw this.release(),Error("baobab.Combination."+t+": cursor already in combination.");return this.cursors.push(r),this.operators.push(t),this.updates.length++,this.bound&&e(this,r),this}}var o=t("emmett"),s=t("./helpers.js"),a=t("./type.js");s.inherits(n,o),i("or"),i("and"),n.prototype.release=function(){this.cursors.forEach(function(t){t.off("update",this.cursorListener)},this),this.tree.off("update",this.treeListener),this.cursors=null,this.operators=null,this.tree=null,this.updates=null,this.kill()},r.exports=n},{"./helpers.js":7,"./type.js":10,emmett:3}],6:[function(t,r){function e(t,r,e,n){var i=this;o.call(this),r=r||[],this.tree=t,this.path=r,this.hash=n,this.archive=null,this.complexPath=!!e,this.solvedPath=this.complexPath?e:this.path,this.relevant=void 0!==this.get(),this.updateHandler=function(t){var r,e,n,o,s,a,u=t.data.log,c=!1;if(i.complexPath&&(i.solvedPath=h.solvePath(i.tree.data,i.path)),!i.path.length)return i.emit("update");t:for(s=0,n=u.length;n>s;s++)for(r=u[s],a=0,o=r.length;o>a&&(e=r[a],e===""+i.solvedPath[a]);a++)if(a+1===o||a+1===i.solvedPath.length){c=!0;break t}var l=void 0!==i.get();i.relevant?l&&c?i.emit("update"):l||(i.emit("irrelevant"),i.relevant=!1):l&&c&&(i.emit("relevant"),i.emit("update"),i.relevant=!0)},this.mixin=a.cursor(this);var s=!1,u=function(){s||(s=!0,i.tree.on("update",i.updateHandler))};this.on=h.before(u,this.on.bind(this)),this.once=h.before(u,this.once.bind(this))}function n(t,r,e,n){arguments.length<4&&(n=e,e=[]),e=e||[];var i=[].concat(e),o=h.solvePath(this.get(),i);if(!o)throw Error("baobab.Cursor."+t+": could not solve dynamic path.");if(r){var s=this.get(o);if(!u[r](s))throw Error("baobab.Cursor."+t+": invalid target.")}var a={};a["$"+t]=n;var c=h.pathObject(o,a);return c}function i(t,r){e.prototype[t]=function(){var e=n.bind(this,t,r).apply(this,arguments);return this.update(e)}}var o=t("emmett"),s=t("./combination.js"),a=t("./mixins.js"),h=t("./helpers.js"),u=t("./type.js");h.inherits(e,o),e.prototype.isRoot=function(){return!this.path.length},e.prototype.isLeaf=function(){return u.Primitive(this.get())},e.prototype.isBranch=function(){return!this.isLeaf()&&!this.isRoot()},e.prototype.root=function(){return this.tree.root()},e.prototype.select=function(t){if(arguments.length>1&&(t=h.arrayOf(arguments)),!u.Path(t))throw Error("baobab.Cursor.select: invalid path.");return this.tree.select(this.path.concat(t))},e.prototype.up=function(){return this.solvedPath&&this.solvedPath.length?this.tree.select(this.path.slice(0,-1)):null},e.prototype.left=function(){var t=+this.solvedPath[this.solvedPath.length-1];if(isNaN(t))throw Error("baobab.Cursor.left: cannot go left on a non-list type.");return t?this.tree.select(this.solvedPath.slice(0,-1).concat(t-1)):null},e.prototype.leftmost=function(){var t=+this.solvedPath[this.solvedPath.length-1];if(isNaN(t))throw Error("baobab.Cursor.leftmost: cannot go left on a non-list type.");return this.tree.select(this.solvedPath.slice(0,-1).concat(0))},e.prototype.right=function(){var t=+this.solvedPath[this.solvedPath.length-1];if(isNaN(t))throw Error("baobab.Cursor.right: cannot go right on a non-list type.");return t+1===this.up().get().length?null:this.tree.select(this.solvedPath.slice(0,-1).concat(t+1))},e.prototype.rightmost=function(){var t=+this.solvedPath[this.solvedPath.length-1];if(isNaN(t))throw Error("baobab.Cursor.right: cannot go right on a non-list type.");var r=this.up().get();return this.tree.select(this.solvedPath.slice(0,-1).concat(r.length-1))},e.prototype.down=function(){+this.solvedPath[this.solvedPath.length-1];return this.get()instanceof Array?this.tree.select(this.solvedPath.concat(0)):null},e.prototype.get=function(t){arguments.length>1&&(t=h.arrayOf(arguments));var r=this.solvedPath.concat((u.String(t)||u.Number(t)?[t]:t)||[]);return h.getIn(this.tree.data,r,this.tree)},i("set"),i("apply"),i("chain"),i("push","Array"),i("unshift","Array"),e.prototype.merge=function(t){if(!u.Object(t))throw Error("baobab.Cursor.merge: trying to merge a non-object.");var r=n.bind(this,"merge","Object").apply(this,arguments);return this.update(r)},e.prototype.unset=function(t){if(void 0===t&&this.isRoot())throw Error("baobab.Cursor.unset: cannot remove root node.");var r=n.bind(this,"unset",null).apply(this,[t,!0]);return this.update(r)},e.prototype.update=function(t,r){if(arguments.length<2)return this.tree.stack(h.pathObject(this.solvedPath,t)),this;var e=[].concat(t),n=h.solvePath(this.get(),e);if(!n)throw Error("baobab.Cursor.update: could not solve dynamic path.");return this.tree.stack(h.pathObject(this.solvedPath.concat(n),r)),this},e.prototype.or=function(t){return new s("or",this,t)},e.prototype.and=function(t){return new s("and",this,t)},e.prototype.startRecording=function(t){return this.archive?this:(this.archive=h.archive(t),this)},e.prototype.stopRecording=function(){return this.archive=null,this},e.prototype.undo=function(){},e.prototype.redo=function(){},e.prototype.hasHistory=function(){return this.archive&&this.archive.records.length},e.prototype.getHistory=function(){return this.archive.records},e.prototype.release=function(){this.tree.off("update",this.updateHandler),this.hash&&delete this.tree._cursors[this.hash],delete this.tree,delete this.path,delete this.solvedPath,this.kill()},e.prototype.toJSON=function(){return this.get()},u.Cursor=function(t){return t instanceof e},r.exports=e},{"./combination.js":5,"./helpers.js":7,"./mixins.js":9,"./type.js":10,emmett:3}],7:[function(t,r){(function(e){function n(t){return Array.prototype.slice.call(t)}function i(t,r){return function(){t(),r.apply(null,arguments)}}function o(t,r){var e,n={};for(e in t)n[e]=t[e];for(e in r)n[e]=r[e];return n}function s(t){var r=t.source,e="";return t.global&&(e+="g"),t.multiline&&(e+="m"),t.ignoreCase&&(e+="i"),t.sticky&&(e+="y"),t.unicode&&(e+="u"),new RegExp(r,e)}function a(t,r){if(!r||"object"!=typeof r||r instanceof Error||"ArrayBuffer"in e&&r instanceof ArrayBuffer)return r;if(_.Array(r)){if(t){var n,i,o=[];for(n=0,i=r.length;i>n;n++)o.push(w(r[n]));return o}return r.slice(0)}if(_.Date(r))return new Date(r.getTime());if(r instanceof RegExp)return s(r);if(_.Object(r)){var a,h={};r.constructor&&r.constructor!==Object&&(h=Object.create(r.constructor.prototype));for(a in r)r.hasOwnProperty(a)&&(h[a]=t?w(r[a]):r[a]);return h}return r}function h(t,r){return function(e){return r(t(e))}}function u(t,r){var e,n;for(e=0,n=t.length;n>e;e++)if(r(t[e]))return t[e]}function c(t,r){var e,n;for(e=0,n=t.length;n>e;e++)if(r(t[e]))return e;return-1}function l(t,r){var e,n=!0;if(!t)return!1;for(e in r)if(_.Object(r[e]))n=n&&l(t[e],r[e]);else if(_.Array(r[e]))n=n&&!!~r[e].indexOf(t[e]);else if(t[e]!==r[e])return!1;return n}function f(t,r){return u(t,function(t){return l(t,r)})}function d(t,r){return c(t,function(t){return l(t,r)})}function b(t,r,e){r=r||[];var n,i,o,s=t;for(i=0,o=r.length;o>i;i++){if(!s)return;if("function"==typeof r[i]){if(!_.Array(s))return;s=u(s,r[i])}else if("object"==typeof r[i])if("$cursor"in r[i]){if(!_.Path(r[i].$cursor))throw Error("baobab.getIn: $cursor path must be an array.");n=e.get(r[i].$cursor),s=s[n]}else{if(!_.Array(s))return;s=f(s,r[i])}else s=s[r[i]]}return s}function y(t,r,e){var n,i,o,s=[],a=t;for(i=0,o=r.length;o>i;i++){if(!a)return null;if("function"==typeof r[i]){if(!_.Array(a))return;n=c(a,r[i]),s.push(n),a=a[n]}else if("object"==typeof r[i]){if("$cursor"in r[i]){if(!_.Path(r[i].$cursor))throw Error("baobab.getIn: $cursor path must be an array.");p=e.get(r[i].$cursor),a=a[p]}if(!_.Array(a))return;n=d(a,r[i]),s.push(n),a=a[n]}else s.push(r[i]),a=a[r[i]]||{}}return s}function g(t,r){var e,n=t.length,i={},o=i;for(n||(i=r),e=0;n>e;e++)o[t[e]]=e+1===n?r:{},o=o[t[e]];return i}function m(t,r){t.super_=r;var e=function(){};e.prototype=r.prototype,t.prototype=new e,t.prototype.constructor=t}function v(t){this.size=t,this.records=[],this.add=function(r){for(this.records.unshift(r);this.records.length>t;)this.records.pop();return this},this.get=function(){return this.records}}var _=t("./type.js"),j=a.bind(null,!1),w=a.bind(null,!0);r.exports={archive:v,arrayOf:n,before:i,deepClone:w,shallowClone:j,shallowMerge:o,compose:h,getIn:b,inherits:m,pathObject:g,solvePath:y}}).call(this,"undefined"!=typeof global?global:"undefined"!=typeof self?self:"undefined"!=typeof window?window:{})},{"./type.js":10}],8:[function(t,r){function e(t,r,e){s.forEach(function(r){e!==r&&delete t[r]}),t[e]=r[e]}function n(t,r){var a,h=i.shallowClone(r||{});s.forEach(function(r){t[r]&&e(h,t,r)}),t.$chain&&(s.slice(0,-1).forEach(function(t){delete h[t]}),h.$apply=h.$apply?i.compose(h.$apply,t.$chain):t.$chain),t.$push&&h.$push?h.$push=o.Array(h.$push)?h.$push.concat(t.$push):[h.$push].concat(t.$push):t.$push&&(h.$push=t.$push),t.$unshift&&h.$unshift?h.$unshift=o.Array(t.$unshift)?t.$unshift.concat(h.$unshift):[t.$unshift].concat(h.$unshift):t.$unshift&&(h.$unshift=t.$unshift);for(a in t)o.Object(t[a])?h[a]=n(t[a],h[a]):"$"!==a[0]&&(h[a]=t[a]);return h}var i=t("./helpers.js"),o=t("./type.js"),s=["$unset","$set","$merge","$apply"];r.exports=n},{"./helpers.js":7,"./type.js":10}],9:[function(t,r){var e=t("./combination.js"),n=t("./type.js");r.exports={baobab:function(t){return{mixins:[{getInitialState:function(){if(this.tree=t,!this.cursor&&!this.cursors)return{};if(this.cursor&&this.cursors)throw Error("baobab.mixin: you cannot have both `component.cursor` and `component.cursors`. Please make up your mind.");if(this.__type=null,this.__updateHandler=function(){this.setState(this.__getCursorData())}.bind(this),this.cursor){if(!n.MixinCursor(this.cursor))throw Error("baobab.mixin.cursor: invalid data (cursor, string, array or function).");n.Function(this.cursor)&&(this.cursor=this.cursor()),n.Cursor(this.cursor)||(this.cursor=t.select(this.cursor)),this.__getCursorData=function(){return{cursor:this.cursor.get()}}.bind(this),this.__type="single"}else if(this.cursors){if(!n.MixinCursors(this.cursors))throw Error("baobab.mixin.cursor: invalid data (object, array or function).");if(n.Function(this.cursors)&&(this.cursors=this.cursors()),n.Array(this.cursors))this.cursors=this.cursors.map(function(r){return n.Cursor(r)?r:t.select(r)}),this.__getCursorData=function(){return{cursors:this.cursors.map(function(t){return t.get()})}}.bind(this),this.__type="array";else{for(var r in this.cursors)n.Cursor(this.cursors[r])||(this.cursors[r]=t.select(this.cursors[r]));this.__getCursorData=function(){var t={};for(r in this.cursors)t[r]=this.cursors[r].get();return{cursors:t}}.bind(this),this.__type="object"}}return this.__getCursorData()},componentDidMount:function(){"single"===this.__type?(this.__combination=new e("or",[this.cursor]),this.__combination.on("update",this.__updateHandler)):"array"===this.__type?(this.__combination=new e("or",this.cursors),this.__combination.on("update",this.__updateHandler)):"object"===this.__type&&(this.__combination=new e("or",Object.keys(this.cursors).map(function(t){return this.cursors[t]},this)),this.__combination.on("update",this.__updateHandler))},componentWillUnmount:function(){this.__combination&&this.__combination.release()}}].concat(t.options.mixins)}},cursor:function(t){return{mixins:[{getInitialState:function(){return this.cursor=t,this.__updateHandler=function(){this.setState({cursor:this.cursor.get()})}.bind(this),{cursor:this.cursor.get()}},componentDidMount:function(){this.cursor.on("update",this.__updateHandler)},componentWillUnmount:function(){this.cursor.off("update",this.__updateHandler)}}].concat(t.tree.options.mixins)}}}},{"./combination.js":5,"./type.js":10}],10:[function(t,r){function e(t,r){return r.some(function(r){return n[r](t)})}var n={};n.Array=function(t){return Array.isArray(t)},n.Object=function(t){return!Array.isArray(t)&&"object"==typeof t&&null!==t},n.String=function(t){return"string"==typeof t},n.Number=function(t){return"number"==typeof t},n.Function=function(t){return"function"==typeof t},n.Primitive=function(t){return"string"==typeof t||"number"==typeof t||"boolean"==typeof t},n.Date=function(t){return t instanceof Date},n.NonScalar=function(t){return n.Object(t)||n.Array(t)},n.Path=function(t){var r=["String","Number","Function","Object"];return n.Array(t)?t.every(function(t){return e(t,r)}):e(t,r)},n.MixinCursor=function(t){return e(t,["String","Number","Array","Function","Cursor"])},n.MixinCursors=function(t){return e(t,["Object","Array","Function"])},n.ComplexPath=function(t){return e(t,["Object","Function"])},r.exports=n},{}],11:[function(t,r){function e(t,r){var e=new Error("baobab.update: "+r+" at path /"+t.slice(1).join("/"));return e.path=t,e}var n=t("./helpers.js"),i=t("./type.js");r.exports=function(t,r,o){if(o=o||{},!i.Object(t)&&!i.Array(t))throw Error("baobab.update: invalid target.");var s={};t={root:n.shallowClone(t)};var a=function(t,r,o,h){o=o||["root"];var u,c,l,f=o.join("λ"),p=o[o.length-1],d=Object.keys(r).some(function(t){return!!~["$unset","$set","$apply","$merge","$push","$unshift"].indexOf(t)});if(d){s[f]=!0;for(c in r){if("$unset"===c){var b=o[o.length-2];i.Array(t)?h[b]=t.slice(0,+p).concat(t.slice(+p+1)):(h[b]=n.shallowClone(t),delete h[b][p]);break}if("$set"===c){l=r.$set,t[p]=l;break}if("$apply"===c){if(u=r.$apply,"function"!=typeof u)throw e(o,"using command $apply with a non function");t[p]=u.call(null,t[p]);break}if("$merge"===c){if(l=r.$merge,!i.Object(t[p])||!i.Object(l))throw e(o,"using command $merge with a non object");t[p]=n.shallowMerge(t[p],l);break}if("$push"===c){if(l=r.$push,!i.Array(t[p]))throw e(o,"using command $push to a non array");t[p]=t[p].concat(l)}if("$unshift"===c){if(l=r.$unshift,!i.Array(t[p]))throw e(o,"using command $unshift to a non array");t[p]=[].concat(l).concat(t[p])}}}else for(c in r)t[p][c]="undefined"==typeof t[p][c]?{}:n.shallowClone(t[p][c]),a(t[p],r[c],o.concat(c),t)};return a(t,r),{data:t.root,log:Object.keys(s).map(function(t){return t.split("λ").slice(1)})}}},{"./helpers.js":7,"./type.js":10}]},{},[2])(2)}); \ No newline at end of file diff --git a/src/cursor.js b/src/cursor.js index 34d7bf1..be06dc7 100644 --- a/src/cursor.js +++ b/src/cursor.js @@ -26,6 +26,7 @@ function Cursor(tree, path, solvedPath, hash) { this.tree = tree; this.path = path; this.hash = hash; + this.archive = null; // Complex path? this.complexPath = !!solvedPath; @@ -304,6 +305,37 @@ Cursor.prototype.and = function(otherCursor) { return new Combination('and', this, otherCursor); }; +/** + * History + */ +Cursor.prototype.startRecording = function(maxRecords) { + if (this.archive) + return this; + this.archive = helpers.archive(maxRecords); + return this; +}; + +Cursor.prototype.stopRecording = function() { + this.archive = null; + return this; +}; + +Cursor.prototype.undo = function() { + // TODO... +}; + +Cursor.prototype.redo = function() { + // TODO... +}; + +Cursor.prototype.hasHistory = function() { + return this.archive && this.archive.records.length; +}; + +Cursor.prototype.getHistory = function() { + return this.archive.records; +}; + /** * Releasing */ diff --git a/src/helpers.js b/src/helpers.js index 5c48fc4..06cd33f 100644 --- a/src/helpers.js +++ b/src/helpers.js @@ -265,6 +265,7 @@ function pathObject(path, spec) { return o; } +// Shim used for cross-compatible event emitting extension function inherits(ctor, superCtor) { ctor.super_ = superCtor; var TempCtor = function () {}; @@ -273,7 +274,28 @@ function inherits(ctor, superCtor) { ctor.prototype.constructor = ctor; } +// Archive +function archive(size) { + this.size = size; + this.records = [] + + // Adding a record + this.add = function(record) { + this.records.unshift(record); + + while (this.records.length > size) + this.records.pop(); + return this; + }; + + // Getting record data + this.get = function() { + return this.records; + }; +} + module.exports = { + archive: archive, arrayOf: arrayOf, before: before, deepClone: deepClone, From 122b5d9e13f09cb9e533bbdf9ffc128d6875b6c0 Mon Sep 17 00:00:00 2001 From: Yomguithereal Date: Wed, 8 Apr 2015 17:39:13 +0200 Subject: [PATCH 27/73] Exposing old values to log --- build/baobab.min.js | 2 +- src/cursor.js | 2 +- src/update.js | 7 +++++-- test/suites/baobab.js | 2 +- 4 files changed, 8 insertions(+), 5 deletions(-) diff --git a/build/baobab.min.js b/build/baobab.min.js index a8d334a..2514866 100644 --- a/build/baobab.min.js +++ b/build/baobab.min.js @@ -1,2 +1,2 @@ /* baobab.js - Version: 1.0.0-rc1 - Author: Yomguithereal (Guillaume Plique) */ -!function(t){if("object"==typeof exports&&"undefined"!=typeof module)module.exports=t();else if("function"==typeof define&&define.amd)define([],t);else{var r;r="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:this,r.Baobab=t()}}(function(){var t;return function r(t,e,n){function i(s,a){if(!e[s]){if(!t[s]){var h="function"==typeof require&&require;if(!a&&h)return h(s,!0);if(o)return o(s,!0);var u=new Error("Cannot find module '"+s+"'");throw u.code="MODULE_NOT_FOUND",u}var c=e[s]={exports:{}};t[s][0].call(c.exports,function(r){var e=t[s][1][r];return i(e?e:r)},c,c.exports,r,t,e,n)}return e[s].exports}for(var o="function"==typeof require&&require,s=0;sr;r++)n.push(t[r].handler);return n}var i={once:"boolean",scope:"object"},o=function(){this._enabled=!0,this._children=[],this._handlers={},this._handlersAll=[]};o.prototype.on=function(t,r,e){var n,s,a,h,u,c;if("function"==typeof r){for(u="string"==typeof t?[t]:t,n=0,s=u.length;n!==s;n+=1)if(h=u[n]){this._handlers[h]||(this._handlers[h]=[]),c={handler:r};for(a in e||{}){if(!i[a])throw new Error('The option "'+a+'" is not recognized by Emmett.');c[a]=e[a]}this._handlers[h].push(c)}}else if(t&&"object"==typeof t&&!Array.isArray(t))for(h in t)o.prototype.on.call(this,h,t[h],r);else{if("function"!=typeof t)throw new Error("Wrong arguments.");c={handler:t};for(a in e||{}){if(!i[a])throw new Error('The option "'+a+'" is not recognized by Emmett.');c[a]=e[a]}this._handlersAll.push(c)}return this},o.prototype.once=function(t,r,e){if("function"==typeof r)e=e||{},e.once=!0,this.on(t,r,e);else{if((!t||"object"!=typeof t||Array.isArray(t))&&"function"!=typeof t)throw new Error("Wrong arguments.");r=r||{},r.once=!0,this.on(t,r)}return this},o.prototype.off=function(t,r){var e,n,i,o,s,a,h,u="string"==typeof t?[t]:t;if(1===arguments.length&&"function"==typeof u){r=arguments[0];for(s in this._handlers){for(a=[],e=0,n=this._handlers[s].length;e!==n;e+=1)this._handlers[s][e].handler!==r&&a.push(this._handlers[s][e]);this._handlers[s]=a}for(a=[],e=0,n=this._handlersAll.length;e!==n;e+=1)this._handlersAll[e].handler!==r&&a.push(this._handlersAll[e]);this._handlersAll=a}else if(2===arguments.length)for(e=0,n=u.length;e!==n;e+=1){if(h=u[e],this._handlers[h]){for(a=[],i=0,o=this._handlers[h].length;i!==o;i+=1)this._handlers[h][i].handler!==r&&a.push(this._handlers[h][i]);this._handlers[h]=a}this._handlers[h]&&0===this._handlers[h].length&&delete this._handlers[h]}return this},o.prototype.unbindAll=function(){var t;this._handlersAll=[];for(t in this._handlers)delete this._handlers[t];return this},o.prototype.emit=function(t,r){var e,n,i,o,s,a,h,u,c,l,f="string"==typeof t?[t]:t;if(!this._enabled)return this;for(r=void 0===r?{}:r,e=0,n=f.length;e!==n;e+=1)if(l=f[e],c=(this._handlers[l]||[]).concat(this._handlersAll),c.length){for(h={type:l,data:r||{},target:this},a=[],i=0,o=c.length;i!==o;i+=1)(this._handlers[l]&&this._handlers[l].indexOf(c[i])>=0||this._handlersAll.indexOf(c[i])>=0)&&(c[i].handler.call("scope"in c[i]?c[i].scope:this,h),c[i].once&&a.push(c[i]));for(s=0;se;e++)if(t._children[e]===r){t._children.splice(e,1);break}}),this._children.push(r),r},o.prototype.listeners=function(t){var e,n,i,o=[];if(t)for(o=r(this._handlers[t]),n=0,i=this._children.length;i>n;n++)o=o.concat(this._children[n].listeners(t));else{o=r(this._handlersAll);for(e in this._handlers)o=o.concat(r(this._handlers[e]));for(n=0,i=this._children.length;i>n;n++)o=o.concat(this._children[n].listeners())}return o},o.prototype.kill=function(){if(this.emit("emmett:kill"),this.unbindAll(),this._handlers=null,this._handlersAll=null,this._enabled=!1,this._children)for(var t=0,r=this._children.length;r>t;t++)this._children[t].kill();this._children=null},o.prototype.disable=function(){return this._enabled=!1,this},o.prototype.enable=function(){return this._enabled=!0,this},o.version="2.1.2","undefined"!=typeof n?("undefined"!=typeof e&&e.exports&&(n=e.exports=o),n.Emitter=o):"function"==typeof t&&t.amd?t("emmett",[],function(){return o}):this.Emitter=o}).call(this)},{}],4:[function(t,r){function e(t){return t+"$"+(new Date).getTime()+(""+Math.random()).replace("0.","")}function n(t,r){function e(t){this[t]=function(){var r=this.root[t].apply(this.root,arguments);return r instanceof i?this:r}}if(arguments.length<1&&(t={}),!(this instanceof n))return new n(t,r);if(!l.Object(t)&&!l.Array(t))throw Error("Baobab: invalid data.");o.call(this),this.options=s.shallowMerge(c,r),this._transaction={},this._future=void 0,this._cursors={},this.data=s.deepClone(t),this.root=this.select([]),["get","set","unset","update"].forEach(e.bind(this)),this.mixin=u.baobab(this)}var i=t("./cursor.js"),o=t("emmett"),s=t("./helpers.js"),a=t("./update.js"),h=t("./merge.js"),u=t("./mixins.js"),c=t("../defaults.js"),l=t("./type.js");s.inherits(n,o),n.prototype.select=function(t){if(!t)throw Error("Baobab.select: invalid path.");if(arguments.length>1&&(t=s.arrayOf(arguments)),!l.Path(t))throw Error("Baobab.select: invalid path.");t=[].concat(t);var r,n=l.ComplexPath(t);n&&(r=s.solvePath(this.data,t));var o=t.map(function(t){return l.Function(t)?e("fn"):l.Object(t)?e("ob"):t}).join("λ");if(this._cursors[o])return this._cursors[o];var a=new i(this,t,r,o);return this._cursors[o]=a,a},n.prototype.stack=function(t){var r=this;if(!l.Object(t))throw Error("Baobab.update: wrong specification.");return this._transaction=h(t,this._transaction),this.options.autoCommit?this.options.asynchronous?(this._future||(this._future=setTimeout(r.commit.bind(r,null),0)),this):this.commit():this},n.prototype.commit=function(){var t=a(this.data,this._transaction,this.options);return this.data=t.data,this._transaction={},this._future&&(this._future=clearTimeout(this._future)),this.emit("update",{log:t.log}),this},n.prototype.release=function(){delete this.data,delete this._transaction;for(var t in this._cursors)this._cursors[t].release();delete this._cursors,this.kill()},n.prototype.toJSON=function(){return this.get()},r.exports=n},{"../defaults.js":1,"./cursor.js":6,"./helpers.js":7,"./merge.js":8,"./mixins.js":9,"./type.js":10,"./update.js":11,emmett:3}],5:[function(t,r){function e(t,r){r.on("update",t.cursorListener),t.tree.off("update",t.treeListener),t.tree.on("update",t.treeListener)}function n(t){var r=this;if(arguments.length<2)throw Error("baobab.Combination: not enough arguments.");var n=arguments[1],i=s.arrayOf(arguments).slice(2);if(n instanceof Array&&(i=n.slice(1),n=n[0]),!a.Cursor(n))throw Error("baobab.Combination: argument should be a cursor.");if("or"!==t&&"and"!==t)throw Error("baobab.Combination: invalid operator.");o.call(this),this.cursors=[n],this.operators=[],this.tree=n.tree,this.updates=new Array(this.cursors.length),this.cursorListener=function(){r.updates[r.cursors.indexOf(this)]=!0},this.treeListener=function(){var t,e,n=r.updates[0];for(t=1,e=r.cursors.length;e>t;t++)n="or"===r.operators[t-1]?n||r.updates[t]:n&&r.updates[t];n&&r.emit("update"),r.updates=new Array(r.cursors.length)},this.bound=!1;var h=(this.on,this.once,function(){r.bound||(r.bound=!0,r.cursors.forEach(function(t){e(r,t)}))});this.on=s.before(h,this.on.bind(this)),this.once=s.before(h,this.once.bind(this)),i.forEach(function(r){this[t](r)},this)}function i(t){n.prototype[t]=function(r){if(!a.Cursor(r))throw this.release(),Error("baobab.Combination."+t+": argument should be a cursor.");if(~this.cursors.indexOf(r))throw this.release(),Error("baobab.Combination."+t+": cursor already in combination.");return this.cursors.push(r),this.operators.push(t),this.updates.length++,this.bound&&e(this,r),this}}var o=t("emmett"),s=t("./helpers.js"),a=t("./type.js");s.inherits(n,o),i("or"),i("and"),n.prototype.release=function(){this.cursors.forEach(function(t){t.off("update",this.cursorListener)},this),this.tree.off("update",this.treeListener),this.cursors=null,this.operators=null,this.tree=null,this.updates=null,this.kill()},r.exports=n},{"./helpers.js":7,"./type.js":10,emmett:3}],6:[function(t,r){function e(t,r,e,n){var i=this;o.call(this),r=r||[],this.tree=t,this.path=r,this.hash=n,this.archive=null,this.complexPath=!!e,this.solvedPath=this.complexPath?e:this.path,this.relevant=void 0!==this.get(),this.updateHandler=function(t){var r,e,n,o,s,a,u=t.data.log,c=!1;if(i.complexPath&&(i.solvedPath=h.solvePath(i.tree.data,i.path)),!i.path.length)return i.emit("update");t:for(s=0,n=u.length;n>s;s++)for(r=u[s],a=0,o=r.length;o>a&&(e=r[a],e===""+i.solvedPath[a]);a++)if(a+1===o||a+1===i.solvedPath.length){c=!0;break t}var l=void 0!==i.get();i.relevant?l&&c?i.emit("update"):l||(i.emit("irrelevant"),i.relevant=!1):l&&c&&(i.emit("relevant"),i.emit("update"),i.relevant=!0)},this.mixin=a.cursor(this);var s=!1,u=function(){s||(s=!0,i.tree.on("update",i.updateHandler))};this.on=h.before(u,this.on.bind(this)),this.once=h.before(u,this.once.bind(this))}function n(t,r,e,n){arguments.length<4&&(n=e,e=[]),e=e||[];var i=[].concat(e),o=h.solvePath(this.get(),i);if(!o)throw Error("baobab.Cursor."+t+": could not solve dynamic path.");if(r){var s=this.get(o);if(!u[r](s))throw Error("baobab.Cursor."+t+": invalid target.")}var a={};a["$"+t]=n;var c=h.pathObject(o,a);return c}function i(t,r){e.prototype[t]=function(){var e=n.bind(this,t,r).apply(this,arguments);return this.update(e)}}var o=t("emmett"),s=t("./combination.js"),a=t("./mixins.js"),h=t("./helpers.js"),u=t("./type.js");h.inherits(e,o),e.prototype.isRoot=function(){return!this.path.length},e.prototype.isLeaf=function(){return u.Primitive(this.get())},e.prototype.isBranch=function(){return!this.isLeaf()&&!this.isRoot()},e.prototype.root=function(){return this.tree.root()},e.prototype.select=function(t){if(arguments.length>1&&(t=h.arrayOf(arguments)),!u.Path(t))throw Error("baobab.Cursor.select: invalid path.");return this.tree.select(this.path.concat(t))},e.prototype.up=function(){return this.solvedPath&&this.solvedPath.length?this.tree.select(this.path.slice(0,-1)):null},e.prototype.left=function(){var t=+this.solvedPath[this.solvedPath.length-1];if(isNaN(t))throw Error("baobab.Cursor.left: cannot go left on a non-list type.");return t?this.tree.select(this.solvedPath.slice(0,-1).concat(t-1)):null},e.prototype.leftmost=function(){var t=+this.solvedPath[this.solvedPath.length-1];if(isNaN(t))throw Error("baobab.Cursor.leftmost: cannot go left on a non-list type.");return this.tree.select(this.solvedPath.slice(0,-1).concat(0))},e.prototype.right=function(){var t=+this.solvedPath[this.solvedPath.length-1];if(isNaN(t))throw Error("baobab.Cursor.right: cannot go right on a non-list type.");return t+1===this.up().get().length?null:this.tree.select(this.solvedPath.slice(0,-1).concat(t+1))},e.prototype.rightmost=function(){var t=+this.solvedPath[this.solvedPath.length-1];if(isNaN(t))throw Error("baobab.Cursor.right: cannot go right on a non-list type.");var r=this.up().get();return this.tree.select(this.solvedPath.slice(0,-1).concat(r.length-1))},e.prototype.down=function(){+this.solvedPath[this.solvedPath.length-1];return this.get()instanceof Array?this.tree.select(this.solvedPath.concat(0)):null},e.prototype.get=function(t){arguments.length>1&&(t=h.arrayOf(arguments));var r=this.solvedPath.concat((u.String(t)||u.Number(t)?[t]:t)||[]);return h.getIn(this.tree.data,r,this.tree)},i("set"),i("apply"),i("chain"),i("push","Array"),i("unshift","Array"),e.prototype.merge=function(t){if(!u.Object(t))throw Error("baobab.Cursor.merge: trying to merge a non-object.");var r=n.bind(this,"merge","Object").apply(this,arguments);return this.update(r)},e.prototype.unset=function(t){if(void 0===t&&this.isRoot())throw Error("baobab.Cursor.unset: cannot remove root node.");var r=n.bind(this,"unset",null).apply(this,[t,!0]);return this.update(r)},e.prototype.update=function(t,r){if(arguments.length<2)return this.tree.stack(h.pathObject(this.solvedPath,t)),this;var e=[].concat(t),n=h.solvePath(this.get(),e);if(!n)throw Error("baobab.Cursor.update: could not solve dynamic path.");return this.tree.stack(h.pathObject(this.solvedPath.concat(n),r)),this},e.prototype.or=function(t){return new s("or",this,t)},e.prototype.and=function(t){return new s("and",this,t)},e.prototype.startRecording=function(t){return this.archive?this:(this.archive=h.archive(t),this)},e.prototype.stopRecording=function(){return this.archive=null,this},e.prototype.undo=function(){},e.prototype.redo=function(){},e.prototype.hasHistory=function(){return this.archive&&this.archive.records.length},e.prototype.getHistory=function(){return this.archive.records},e.prototype.release=function(){this.tree.off("update",this.updateHandler),this.hash&&delete this.tree._cursors[this.hash],delete this.tree,delete this.path,delete this.solvedPath,this.kill()},e.prototype.toJSON=function(){return this.get()},u.Cursor=function(t){return t instanceof e},r.exports=e},{"./combination.js":5,"./helpers.js":7,"./mixins.js":9,"./type.js":10,emmett:3}],7:[function(t,r){(function(e){function n(t){return Array.prototype.slice.call(t)}function i(t,r){return function(){t(),r.apply(null,arguments)}}function o(t,r){var e,n={};for(e in t)n[e]=t[e];for(e in r)n[e]=r[e];return n}function s(t){var r=t.source,e="";return t.global&&(e+="g"),t.multiline&&(e+="m"),t.ignoreCase&&(e+="i"),t.sticky&&(e+="y"),t.unicode&&(e+="u"),new RegExp(r,e)}function a(t,r){if(!r||"object"!=typeof r||r instanceof Error||"ArrayBuffer"in e&&r instanceof ArrayBuffer)return r;if(_.Array(r)){if(t){var n,i,o=[];for(n=0,i=r.length;i>n;n++)o.push(w(r[n]));return o}return r.slice(0)}if(_.Date(r))return new Date(r.getTime());if(r instanceof RegExp)return s(r);if(_.Object(r)){var a,h={};r.constructor&&r.constructor!==Object&&(h=Object.create(r.constructor.prototype));for(a in r)r.hasOwnProperty(a)&&(h[a]=t?w(r[a]):r[a]);return h}return r}function h(t,r){return function(e){return r(t(e))}}function u(t,r){var e,n;for(e=0,n=t.length;n>e;e++)if(r(t[e]))return t[e]}function c(t,r){var e,n;for(e=0,n=t.length;n>e;e++)if(r(t[e]))return e;return-1}function l(t,r){var e,n=!0;if(!t)return!1;for(e in r)if(_.Object(r[e]))n=n&&l(t[e],r[e]);else if(_.Array(r[e]))n=n&&!!~r[e].indexOf(t[e]);else if(t[e]!==r[e])return!1;return n}function f(t,r){return u(t,function(t){return l(t,r)})}function d(t,r){return c(t,function(t){return l(t,r)})}function b(t,r,e){r=r||[];var n,i,o,s=t;for(i=0,o=r.length;o>i;i++){if(!s)return;if("function"==typeof r[i]){if(!_.Array(s))return;s=u(s,r[i])}else if("object"==typeof r[i])if("$cursor"in r[i]){if(!_.Path(r[i].$cursor))throw Error("baobab.getIn: $cursor path must be an array.");n=e.get(r[i].$cursor),s=s[n]}else{if(!_.Array(s))return;s=f(s,r[i])}else s=s[r[i]]}return s}function y(t,r,e){var n,i,o,s=[],a=t;for(i=0,o=r.length;o>i;i++){if(!a)return null;if("function"==typeof r[i]){if(!_.Array(a))return;n=c(a,r[i]),s.push(n),a=a[n]}else if("object"==typeof r[i]){if("$cursor"in r[i]){if(!_.Path(r[i].$cursor))throw Error("baobab.getIn: $cursor path must be an array.");p=e.get(r[i].$cursor),a=a[p]}if(!_.Array(a))return;n=d(a,r[i]),s.push(n),a=a[n]}else s.push(r[i]),a=a[r[i]]||{}}return s}function g(t,r){var e,n=t.length,i={},o=i;for(n||(i=r),e=0;n>e;e++)o[t[e]]=e+1===n?r:{},o=o[t[e]];return i}function m(t,r){t.super_=r;var e=function(){};e.prototype=r.prototype,t.prototype=new e,t.prototype.constructor=t}function v(t){this.size=t,this.records=[],this.add=function(r){for(this.records.unshift(r);this.records.length>t;)this.records.pop();return this},this.get=function(){return this.records}}var _=t("./type.js"),j=a.bind(null,!1),w=a.bind(null,!0);r.exports={archive:v,arrayOf:n,before:i,deepClone:w,shallowClone:j,shallowMerge:o,compose:h,getIn:b,inherits:m,pathObject:g,solvePath:y}}).call(this,"undefined"!=typeof global?global:"undefined"!=typeof self?self:"undefined"!=typeof window?window:{})},{"./type.js":10}],8:[function(t,r){function e(t,r,e){s.forEach(function(r){e!==r&&delete t[r]}),t[e]=r[e]}function n(t,r){var a,h=i.shallowClone(r||{});s.forEach(function(r){t[r]&&e(h,t,r)}),t.$chain&&(s.slice(0,-1).forEach(function(t){delete h[t]}),h.$apply=h.$apply?i.compose(h.$apply,t.$chain):t.$chain),t.$push&&h.$push?h.$push=o.Array(h.$push)?h.$push.concat(t.$push):[h.$push].concat(t.$push):t.$push&&(h.$push=t.$push),t.$unshift&&h.$unshift?h.$unshift=o.Array(t.$unshift)?t.$unshift.concat(h.$unshift):[t.$unshift].concat(h.$unshift):t.$unshift&&(h.$unshift=t.$unshift);for(a in t)o.Object(t[a])?h[a]=n(t[a],h[a]):"$"!==a[0]&&(h[a]=t[a]);return h}var i=t("./helpers.js"),o=t("./type.js"),s=["$unset","$set","$merge","$apply"];r.exports=n},{"./helpers.js":7,"./type.js":10}],9:[function(t,r){var e=t("./combination.js"),n=t("./type.js");r.exports={baobab:function(t){return{mixins:[{getInitialState:function(){if(this.tree=t,!this.cursor&&!this.cursors)return{};if(this.cursor&&this.cursors)throw Error("baobab.mixin: you cannot have both `component.cursor` and `component.cursors`. Please make up your mind.");if(this.__type=null,this.__updateHandler=function(){this.setState(this.__getCursorData())}.bind(this),this.cursor){if(!n.MixinCursor(this.cursor))throw Error("baobab.mixin.cursor: invalid data (cursor, string, array or function).");n.Function(this.cursor)&&(this.cursor=this.cursor()),n.Cursor(this.cursor)||(this.cursor=t.select(this.cursor)),this.__getCursorData=function(){return{cursor:this.cursor.get()}}.bind(this),this.__type="single"}else if(this.cursors){if(!n.MixinCursors(this.cursors))throw Error("baobab.mixin.cursor: invalid data (object, array or function).");if(n.Function(this.cursors)&&(this.cursors=this.cursors()),n.Array(this.cursors))this.cursors=this.cursors.map(function(r){return n.Cursor(r)?r:t.select(r)}),this.__getCursorData=function(){return{cursors:this.cursors.map(function(t){return t.get()})}}.bind(this),this.__type="array";else{for(var r in this.cursors)n.Cursor(this.cursors[r])||(this.cursors[r]=t.select(this.cursors[r]));this.__getCursorData=function(){var t={};for(r in this.cursors)t[r]=this.cursors[r].get();return{cursors:t}}.bind(this),this.__type="object"}}return this.__getCursorData()},componentDidMount:function(){"single"===this.__type?(this.__combination=new e("or",[this.cursor]),this.__combination.on("update",this.__updateHandler)):"array"===this.__type?(this.__combination=new e("or",this.cursors),this.__combination.on("update",this.__updateHandler)):"object"===this.__type&&(this.__combination=new e("or",Object.keys(this.cursors).map(function(t){return this.cursors[t]},this)),this.__combination.on("update",this.__updateHandler))},componentWillUnmount:function(){this.__combination&&this.__combination.release()}}].concat(t.options.mixins)}},cursor:function(t){return{mixins:[{getInitialState:function(){return this.cursor=t,this.__updateHandler=function(){this.setState({cursor:this.cursor.get()})}.bind(this),{cursor:this.cursor.get()}},componentDidMount:function(){this.cursor.on("update",this.__updateHandler)},componentWillUnmount:function(){this.cursor.off("update",this.__updateHandler)}}].concat(t.tree.options.mixins)}}}},{"./combination.js":5,"./type.js":10}],10:[function(t,r){function e(t,r){return r.some(function(r){return n[r](t)})}var n={};n.Array=function(t){return Array.isArray(t)},n.Object=function(t){return!Array.isArray(t)&&"object"==typeof t&&null!==t},n.String=function(t){return"string"==typeof t},n.Number=function(t){return"number"==typeof t},n.Function=function(t){return"function"==typeof t},n.Primitive=function(t){return"string"==typeof t||"number"==typeof t||"boolean"==typeof t},n.Date=function(t){return t instanceof Date},n.NonScalar=function(t){return n.Object(t)||n.Array(t)},n.Path=function(t){var r=["String","Number","Function","Object"];return n.Array(t)?t.every(function(t){return e(t,r)}):e(t,r)},n.MixinCursor=function(t){return e(t,["String","Number","Array","Function","Cursor"])},n.MixinCursors=function(t){return e(t,["Object","Array","Function"])},n.ComplexPath=function(t){return e(t,["Object","Function"])},r.exports=n},{}],11:[function(t,r){function e(t,r){var e=new Error("baobab.update: "+r+" at path /"+t.slice(1).join("/"));return e.path=t,e}var n=t("./helpers.js"),i=t("./type.js");r.exports=function(t,r,o){if(o=o||{},!i.Object(t)&&!i.Array(t))throw Error("baobab.update: invalid target.");var s={};t={root:n.shallowClone(t)};var a=function(t,r,o,h){o=o||["root"];var u,c,l,f=o.join("λ"),p=o[o.length-1],d=Object.keys(r).some(function(t){return!!~["$unset","$set","$apply","$merge","$push","$unshift"].indexOf(t)});if(d){s[f]=!0;for(c in r){if("$unset"===c){var b=o[o.length-2];i.Array(t)?h[b]=t.slice(0,+p).concat(t.slice(+p+1)):(h[b]=n.shallowClone(t),delete h[b][p]);break}if("$set"===c){l=r.$set,t[p]=l;break}if("$apply"===c){if(u=r.$apply,"function"!=typeof u)throw e(o,"using command $apply with a non function");t[p]=u.call(null,t[p]);break}if("$merge"===c){if(l=r.$merge,!i.Object(t[p])||!i.Object(l))throw e(o,"using command $merge with a non object");t[p]=n.shallowMerge(t[p],l);break}if("$push"===c){if(l=r.$push,!i.Array(t[p]))throw e(o,"using command $push to a non array");t[p]=t[p].concat(l)}if("$unshift"===c){if(l=r.$unshift,!i.Array(t[p]))throw e(o,"using command $unshift to a non array");t[p]=[].concat(l).concat(t[p])}}}else for(c in r)t[p][c]="undefined"==typeof t[p][c]?{}:n.shallowClone(t[p][c]),a(t[p],r[c],o.concat(c),t)};return a(t,r),{data:t.root,log:Object.keys(s).map(function(t){return t.split("λ").slice(1)})}}},{"./helpers.js":7,"./type.js":10}]},{},[2])(2)}); \ No newline at end of file +!function(t){if("object"==typeof exports&&"undefined"!=typeof module)module.exports=t();else if("function"==typeof define&&define.amd)define([],t);else{var r;r="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:this,r.Baobab=t()}}(function(){var t;return function r(t,e,n){function i(s,a){if(!e[s]){if(!t[s]){var h="function"==typeof require&&require;if(!a&&h)return h(s,!0);if(o)return o(s,!0);var u=new Error("Cannot find module '"+s+"'");throw u.code="MODULE_NOT_FOUND",u}var c=e[s]={exports:{}};t[s][0].call(c.exports,function(r){var e=t[s][1][r];return i(e?e:r)},c,c.exports,r,t,e,n)}return e[s].exports}for(var o="function"==typeof require&&require,s=0;sr;r++)n.push(t[r].handler);return n}var i={once:"boolean",scope:"object"},o=function(){this._enabled=!0,this._children=[],this._handlers={},this._handlersAll=[]};o.prototype.on=function(t,r,e){var n,s,a,h,u,c;if("function"==typeof r){for(u="string"==typeof t?[t]:t,n=0,s=u.length;n!==s;n+=1)if(h=u[n]){this._handlers[h]||(this._handlers[h]=[]),c={handler:r};for(a in e||{}){if(!i[a])throw new Error('The option "'+a+'" is not recognized by Emmett.');c[a]=e[a]}this._handlers[h].push(c)}}else if(t&&"object"==typeof t&&!Array.isArray(t))for(h in t)o.prototype.on.call(this,h,t[h],r);else{if("function"!=typeof t)throw new Error("Wrong arguments.");c={handler:t};for(a in e||{}){if(!i[a])throw new Error('The option "'+a+'" is not recognized by Emmett.');c[a]=e[a]}this._handlersAll.push(c)}return this},o.prototype.once=function(t,r,e){if("function"==typeof r)e=e||{},e.once=!0,this.on(t,r,e);else{if((!t||"object"!=typeof t||Array.isArray(t))&&"function"!=typeof t)throw new Error("Wrong arguments.");r=r||{},r.once=!0,this.on(t,r)}return this},o.prototype.off=function(t,r){var e,n,i,o,s,a,h,u="string"==typeof t?[t]:t;if(1===arguments.length&&"function"==typeof u){r=arguments[0];for(s in this._handlers){for(a=[],e=0,n=this._handlers[s].length;e!==n;e+=1)this._handlers[s][e].handler!==r&&a.push(this._handlers[s][e]);this._handlers[s]=a}for(a=[],e=0,n=this._handlersAll.length;e!==n;e+=1)this._handlersAll[e].handler!==r&&a.push(this._handlersAll[e]);this._handlersAll=a}else if(2===arguments.length)for(e=0,n=u.length;e!==n;e+=1){if(h=u[e],this._handlers[h]){for(a=[],i=0,o=this._handlers[h].length;i!==o;i+=1)this._handlers[h][i].handler!==r&&a.push(this._handlers[h][i]);this._handlers[h]=a}this._handlers[h]&&0===this._handlers[h].length&&delete this._handlers[h]}return this},o.prototype.unbindAll=function(){var t;this._handlersAll=[];for(t in this._handlers)delete this._handlers[t];return this},o.prototype.emit=function(t,r){var e,n,i,o,s,a,h,u,c,l,f="string"==typeof t?[t]:t;if(!this._enabled)return this;for(r=void 0===r?{}:r,e=0,n=f.length;e!==n;e+=1)if(l=f[e],c=(this._handlers[l]||[]).concat(this._handlersAll),c.length){for(h={type:l,data:r||{},target:this},a=[],i=0,o=c.length;i!==o;i+=1)(this._handlers[l]&&this._handlers[l].indexOf(c[i])>=0||this._handlersAll.indexOf(c[i])>=0)&&(c[i].handler.call("scope"in c[i]?c[i].scope:this,h),c[i].once&&a.push(c[i]));for(s=0;se;e++)if(t._children[e]===r){t._children.splice(e,1);break}}),this._children.push(r),r},o.prototype.listeners=function(t){var e,n,i,o=[];if(t)for(o=r(this._handlers[t]),n=0,i=this._children.length;i>n;n++)o=o.concat(this._children[n].listeners(t));else{o=r(this._handlersAll);for(e in this._handlers)o=o.concat(r(this._handlers[e]));for(n=0,i=this._children.length;i>n;n++)o=o.concat(this._children[n].listeners())}return o},o.prototype.kill=function(){if(this.emit("emmett:kill"),this.unbindAll(),this._handlers=null,this._handlersAll=null,this._enabled=!1,this._children)for(var t=0,r=this._children.length;r>t;t++)this._children[t].kill();this._children=null},o.prototype.disable=function(){return this._enabled=!1,this},o.prototype.enable=function(){return this._enabled=!0,this},o.version="2.1.2","undefined"!=typeof n?("undefined"!=typeof e&&e.exports&&(n=e.exports=o),n.Emitter=o):"function"==typeof t&&t.amd?t("emmett",[],function(){return o}):this.Emitter=o}).call(this)},{}],4:[function(t,r){function e(t){return t+"$"+(new Date).getTime()+(""+Math.random()).replace("0.","")}function n(t,r){function e(t){this[t]=function(){var r=this.root[t].apply(this.root,arguments);return r instanceof i?this:r}}if(arguments.length<1&&(t={}),!(this instanceof n))return new n(t,r);if(!l.Object(t)&&!l.Array(t))throw Error("Baobab: invalid data.");o.call(this),this.options=s.shallowMerge(c,r),this._transaction={},this._future=void 0,this._cursors={},this.data=s.deepClone(t),this.root=this.select([]),["get","set","unset","update"].forEach(e.bind(this)),this.mixin=u.baobab(this)}var i=t("./cursor.js"),o=t("emmett"),s=t("./helpers.js"),a=t("./update.js"),h=t("./merge.js"),u=t("./mixins.js"),c=t("../defaults.js"),l=t("./type.js");s.inherits(n,o),n.prototype.select=function(t){if(!t)throw Error("Baobab.select: invalid path.");if(arguments.length>1&&(t=s.arrayOf(arguments)),!l.Path(t))throw Error("Baobab.select: invalid path.");t=[].concat(t);var r,n=l.ComplexPath(t);n&&(r=s.solvePath(this.data,t));var o=t.map(function(t){return l.Function(t)?e("fn"):l.Object(t)?e("ob"):t}).join("λ");if(this._cursors[o])return this._cursors[o];var a=new i(this,t,r,o);return this._cursors[o]=a,a},n.prototype.stack=function(t){var r=this;if(!l.Object(t))throw Error("Baobab.update: wrong specification.");return this._transaction=h(t,this._transaction),this.options.autoCommit?this.options.asynchronous?(this._future||(this._future=setTimeout(r.commit.bind(r,null),0)),this):this.commit():this},n.prototype.commit=function(){var t=a(this.data,this._transaction,this.options);return this.data=t.data,this._transaction={},this._future&&(this._future=clearTimeout(this._future)),this.emit("update",{log:t.log}),this},n.prototype.release=function(){delete this.data,delete this._transaction;for(var t in this._cursors)this._cursors[t].release();delete this._cursors,this.kill()},n.prototype.toJSON=function(){return this.get()},r.exports=n},{"../defaults.js":1,"./cursor.js":6,"./helpers.js":7,"./merge.js":8,"./mixins.js":9,"./type.js":10,"./update.js":11,emmett:3}],5:[function(t,r){function e(t,r){r.on("update",t.cursorListener),t.tree.off("update",t.treeListener),t.tree.on("update",t.treeListener)}function n(t){var r=this;if(arguments.length<2)throw Error("baobab.Combination: not enough arguments.");var n=arguments[1],i=s.arrayOf(arguments).slice(2);if(n instanceof Array&&(i=n.slice(1),n=n[0]),!a.Cursor(n))throw Error("baobab.Combination: argument should be a cursor.");if("or"!==t&&"and"!==t)throw Error("baobab.Combination: invalid operator.");o.call(this),this.cursors=[n],this.operators=[],this.tree=n.tree,this.updates=new Array(this.cursors.length),this.cursorListener=function(){r.updates[r.cursors.indexOf(this)]=!0},this.treeListener=function(){var t,e,n=r.updates[0];for(t=1,e=r.cursors.length;e>t;t++)n="or"===r.operators[t-1]?n||r.updates[t]:n&&r.updates[t];n&&r.emit("update"),r.updates=new Array(r.cursors.length)},this.bound=!1;var h=(this.on,this.once,function(){r.bound||(r.bound=!0,r.cursors.forEach(function(t){e(r,t)}))});this.on=s.before(h,this.on.bind(this)),this.once=s.before(h,this.once.bind(this)),i.forEach(function(r){this[t](r)},this)}function i(t){n.prototype[t]=function(r){if(!a.Cursor(r))throw this.release(),Error("baobab.Combination."+t+": argument should be a cursor.");if(~this.cursors.indexOf(r))throw this.release(),Error("baobab.Combination."+t+": cursor already in combination.");return this.cursors.push(r),this.operators.push(t),this.updates.length++,this.bound&&e(this,r),this}}var o=t("emmett"),s=t("./helpers.js"),a=t("./type.js");s.inherits(n,o),i("or"),i("and"),n.prototype.release=function(){this.cursors.forEach(function(t){t.off("update",this.cursorListener)},this),this.tree.off("update",this.treeListener),this.cursors=null,this.operators=null,this.tree=null,this.updates=null,this.kill()},r.exports=n},{"./helpers.js":7,"./type.js":10,emmett:3}],6:[function(t,r){function e(t,r,e,n){var i=this;o.call(this),r=r||[],this.tree=t,this.path=r,this.hash=n,this.archive=null,this.complexPath=!!e,this.solvedPath=this.complexPath?e:this.path,this.relevant=void 0!==this.get(),this.updateHandler=function(t){var r,e,n,o,s,a,u=t.data.log,c=!1;if(i.complexPath&&(i.solvedPath=h.solvePath(i.tree.data,i.path)),!i.path.length)return i.emit("update");t:for(s=0,n=u.length;n>s;s++)for(r=u[s].path,a=0,o=r.length;o>a&&(e=r[a],e===""+i.solvedPath[a]);a++)if(a+1===o||a+1===i.solvedPath.length){c=!0;break t}var l=void 0!==i.get();i.relevant?l&&c?i.emit("update"):l||(i.emit("irrelevant"),i.relevant=!1):l&&c&&(i.emit("relevant"),i.emit("update"),i.relevant=!0)},this.mixin=a.cursor(this);var s=!1,u=function(){s||(s=!0,i.tree.on("update",i.updateHandler))};this.on=h.before(u,this.on.bind(this)),this.once=h.before(u,this.once.bind(this))}function n(t,r,e,n){arguments.length<4&&(n=e,e=[]),e=e||[];var i=[].concat(e),o=h.solvePath(this.get(),i);if(!o)throw Error("baobab.Cursor."+t+": could not solve dynamic path.");if(r){var s=this.get(o);if(!u[r](s))throw Error("baobab.Cursor."+t+": invalid target.")}var a={};a["$"+t]=n;var c=h.pathObject(o,a);return c}function i(t,r){e.prototype[t]=function(){var e=n.bind(this,t,r).apply(this,arguments);return this.update(e)}}var o=t("emmett"),s=t("./combination.js"),a=t("./mixins.js"),h=t("./helpers.js"),u=t("./type.js");h.inherits(e,o),e.prototype.isRoot=function(){return!this.path.length},e.prototype.isLeaf=function(){return u.Primitive(this.get())},e.prototype.isBranch=function(){return!this.isLeaf()&&!this.isRoot()},e.prototype.root=function(){return this.tree.root()},e.prototype.select=function(t){if(arguments.length>1&&(t=h.arrayOf(arguments)),!u.Path(t))throw Error("baobab.Cursor.select: invalid path.");return this.tree.select(this.path.concat(t))},e.prototype.up=function(){return this.solvedPath&&this.solvedPath.length?this.tree.select(this.path.slice(0,-1)):null},e.prototype.left=function(){var t=+this.solvedPath[this.solvedPath.length-1];if(isNaN(t))throw Error("baobab.Cursor.left: cannot go left on a non-list type.");return t?this.tree.select(this.solvedPath.slice(0,-1).concat(t-1)):null},e.prototype.leftmost=function(){var t=+this.solvedPath[this.solvedPath.length-1];if(isNaN(t))throw Error("baobab.Cursor.leftmost: cannot go left on a non-list type.");return this.tree.select(this.solvedPath.slice(0,-1).concat(0))},e.prototype.right=function(){var t=+this.solvedPath[this.solvedPath.length-1];if(isNaN(t))throw Error("baobab.Cursor.right: cannot go right on a non-list type.");return t+1===this.up().get().length?null:this.tree.select(this.solvedPath.slice(0,-1).concat(t+1))},e.prototype.rightmost=function(){var t=+this.solvedPath[this.solvedPath.length-1];if(isNaN(t))throw Error("baobab.Cursor.right: cannot go right on a non-list type.");var r=this.up().get();return this.tree.select(this.solvedPath.slice(0,-1).concat(r.length-1))},e.prototype.down=function(){+this.solvedPath[this.solvedPath.length-1];return this.get()instanceof Array?this.tree.select(this.solvedPath.concat(0)):null},e.prototype.get=function(t){arguments.length>1&&(t=h.arrayOf(arguments));var r=this.solvedPath.concat((u.String(t)||u.Number(t)?[t]:t)||[]);return h.getIn(this.tree.data,r,this.tree)},i("set"),i("apply"),i("chain"),i("push","Array"),i("unshift","Array"),e.prototype.merge=function(t){if(!u.Object(t))throw Error("baobab.Cursor.merge: trying to merge a non-object.");var r=n.bind(this,"merge","Object").apply(this,arguments);return this.update(r)},e.prototype.unset=function(t){if(void 0===t&&this.isRoot())throw Error("baobab.Cursor.unset: cannot remove root node.");var r=n.bind(this,"unset",null).apply(this,[t,!0]);return this.update(r)},e.prototype.update=function(t,r){if(arguments.length<2)return this.tree.stack(h.pathObject(this.solvedPath,t)),this;var e=[].concat(t),n=h.solvePath(this.get(),e);if(!n)throw Error("baobab.Cursor.update: could not solve dynamic path.");return this.tree.stack(h.pathObject(this.solvedPath.concat(n),r)),this},e.prototype.or=function(t){return new s("or",this,t)},e.prototype.and=function(t){return new s("and",this,t)},e.prototype.startRecording=function(t){return this.archive?this:(this.archive=h.archive(t),this)},e.prototype.stopRecording=function(){return this.archive=null,this},e.prototype.undo=function(){},e.prototype.redo=function(){},e.prototype.hasHistory=function(){return this.archive&&this.archive.records.length},e.prototype.getHistory=function(){return this.archive.records},e.prototype.release=function(){this.tree.off("update",this.updateHandler),this.hash&&delete this.tree._cursors[this.hash],delete this.tree,delete this.path,delete this.solvedPath,this.kill()},e.prototype.toJSON=function(){return this.get()},u.Cursor=function(t){return t instanceof e},r.exports=e},{"./combination.js":5,"./helpers.js":7,"./mixins.js":9,"./type.js":10,emmett:3}],7:[function(t,r){(function(e){function n(t){return Array.prototype.slice.call(t)}function i(t,r){return function(){t(),r.apply(null,arguments)}}function o(t,r){var e,n={};for(e in t)n[e]=t[e];for(e in r)n[e]=r[e];return n}function s(t){var r=t.source,e="";return t.global&&(e+="g"),t.multiline&&(e+="m"),t.ignoreCase&&(e+="i"),t.sticky&&(e+="y"),t.unicode&&(e+="u"),new RegExp(r,e)}function a(t,r){if(!r||"object"!=typeof r||r instanceof Error||"ArrayBuffer"in e&&r instanceof ArrayBuffer)return r;if(_.Array(r)){if(t){var n,i,o=[];for(n=0,i=r.length;i>n;n++)o.push(w(r[n]));return o}return r.slice(0)}if(_.Date(r))return new Date(r.getTime());if(r instanceof RegExp)return s(r);if(_.Object(r)){var a,h={};r.constructor&&r.constructor!==Object&&(h=Object.create(r.constructor.prototype));for(a in r)r.hasOwnProperty(a)&&(h[a]=t?w(r[a]):r[a]);return h}return r}function h(t,r){return function(e){return r(t(e))}}function u(t,r){var e,n;for(e=0,n=t.length;n>e;e++)if(r(t[e]))return t[e]}function c(t,r){var e,n;for(e=0,n=t.length;n>e;e++)if(r(t[e]))return e;return-1}function l(t,r){var e,n=!0;if(!t)return!1;for(e in r)if(_.Object(r[e]))n=n&&l(t[e],r[e]);else if(_.Array(r[e]))n=n&&!!~r[e].indexOf(t[e]);else if(t[e]!==r[e])return!1;return n}function f(t,r){return u(t,function(t){return l(t,r)})}function d(t,r){return c(t,function(t){return l(t,r)})}function b(t,r,e){r=r||[];var n,i,o,s=t;for(i=0,o=r.length;o>i;i++){if(!s)return;if("function"==typeof r[i]){if(!_.Array(s))return;s=u(s,r[i])}else if("object"==typeof r[i])if("$cursor"in r[i]){if(!_.Path(r[i].$cursor))throw Error("baobab.getIn: $cursor path must be an array.");n=e.get(r[i].$cursor),s=s[n]}else{if(!_.Array(s))return;s=f(s,r[i])}else s=s[r[i]]}return s}function y(t,r,e){var n,i,o,s=[],a=t;for(i=0,o=r.length;o>i;i++){if(!a)return null;if("function"==typeof r[i]){if(!_.Array(a))return;n=c(a,r[i]),s.push(n),a=a[n]}else if("object"==typeof r[i]){if("$cursor"in r[i]){if(!_.Path(r[i].$cursor))throw Error("baobab.getIn: $cursor path must be an array.");p=e.get(r[i].$cursor),a=a[p]}if(!_.Array(a))return;n=d(a,r[i]),s.push(n),a=a[n]}else s.push(r[i]),a=a[r[i]]||{}}return s}function g(t,r){var e,n=t.length,i={},o=i;for(n||(i=r),e=0;n>e;e++)o[t[e]]=e+1===n?r:{},o=o[t[e]];return i}function m(t,r){t.super_=r;var e=function(){};e.prototype=r.prototype,t.prototype=new e,t.prototype.constructor=t}function v(t){this.size=t,this.records=[],this.add=function(r){for(this.records.unshift(r);this.records.length>t;)this.records.pop();return this},this.get=function(){return this.records}}var _=t("./type.js"),j=a.bind(null,!1),w=a.bind(null,!0);r.exports={archive:v,arrayOf:n,before:i,deepClone:w,shallowClone:j,shallowMerge:o,compose:h,getIn:b,inherits:m,pathObject:g,solvePath:y}}).call(this,"undefined"!=typeof global?global:"undefined"!=typeof self?self:"undefined"!=typeof window?window:{})},{"./type.js":10}],8:[function(t,r){function e(t,r,e){s.forEach(function(r){e!==r&&delete t[r]}),t[e]=r[e]}function n(t,r){var a,h=i.shallowClone(r||{});s.forEach(function(r){t[r]&&e(h,t,r)}),t.$chain&&(s.slice(0,-1).forEach(function(t){delete h[t]}),h.$apply=h.$apply?i.compose(h.$apply,t.$chain):t.$chain),t.$push&&h.$push?h.$push=o.Array(h.$push)?h.$push.concat(t.$push):[h.$push].concat(t.$push):t.$push&&(h.$push=t.$push),t.$unshift&&h.$unshift?h.$unshift=o.Array(t.$unshift)?t.$unshift.concat(h.$unshift):[t.$unshift].concat(h.$unshift):t.$unshift&&(h.$unshift=t.$unshift);for(a in t)o.Object(t[a])?h[a]=n(t[a],h[a]):"$"!==a[0]&&(h[a]=t[a]);return h}var i=t("./helpers.js"),o=t("./type.js"),s=["$unset","$set","$merge","$apply"];r.exports=n},{"./helpers.js":7,"./type.js":10}],9:[function(t,r){var e=t("./combination.js"),n=t("./type.js");r.exports={baobab:function(t){return{mixins:[{getInitialState:function(){if(this.tree=t,!this.cursor&&!this.cursors)return{};if(this.cursor&&this.cursors)throw Error("baobab.mixin: you cannot have both `component.cursor` and `component.cursors`. Please make up your mind.");if(this.__type=null,this.__updateHandler=function(){this.setState(this.__getCursorData())}.bind(this),this.cursor){if(!n.MixinCursor(this.cursor))throw Error("baobab.mixin.cursor: invalid data (cursor, string, array or function).");n.Function(this.cursor)&&(this.cursor=this.cursor()),n.Cursor(this.cursor)||(this.cursor=t.select(this.cursor)),this.__getCursorData=function(){return{cursor:this.cursor.get()}}.bind(this),this.__type="single"}else if(this.cursors){if(!n.MixinCursors(this.cursors))throw Error("baobab.mixin.cursor: invalid data (object, array or function).");if(n.Function(this.cursors)&&(this.cursors=this.cursors()),n.Array(this.cursors))this.cursors=this.cursors.map(function(r){return n.Cursor(r)?r:t.select(r)}),this.__getCursorData=function(){return{cursors:this.cursors.map(function(t){return t.get()})}}.bind(this),this.__type="array";else{for(var r in this.cursors)n.Cursor(this.cursors[r])||(this.cursors[r]=t.select(this.cursors[r]));this.__getCursorData=function(){var t={};for(r in this.cursors)t[r]=this.cursors[r].get();return{cursors:t}}.bind(this),this.__type="object"}}return this.__getCursorData()},componentDidMount:function(){"single"===this.__type?(this.__combination=new e("or",[this.cursor]),this.__combination.on("update",this.__updateHandler)):"array"===this.__type?(this.__combination=new e("or",this.cursors),this.__combination.on("update",this.__updateHandler)):"object"===this.__type&&(this.__combination=new e("or",Object.keys(this.cursors).map(function(t){return this.cursors[t]},this)),this.__combination.on("update",this.__updateHandler))},componentWillUnmount:function(){this.__combination&&this.__combination.release()}}].concat(t.options.mixins)}},cursor:function(t){return{mixins:[{getInitialState:function(){return this.cursor=t,this.__updateHandler=function(){this.setState({cursor:this.cursor.get()})}.bind(this),{cursor:this.cursor.get()}},componentDidMount:function(){this.cursor.on("update",this.__updateHandler)},componentWillUnmount:function(){this.cursor.off("update",this.__updateHandler)}}].concat(t.tree.options.mixins)}}}},{"./combination.js":5,"./type.js":10}],10:[function(t,r){function e(t,r){return r.some(function(r){return n[r](t)})}var n={};n.Array=function(t){return Array.isArray(t)},n.Object=function(t){return!Array.isArray(t)&&"object"==typeof t&&null!==t},n.String=function(t){return"string"==typeof t},n.Number=function(t){return"number"==typeof t},n.Function=function(t){return"function"==typeof t},n.Primitive=function(t){return"string"==typeof t||"number"==typeof t||"boolean"==typeof t},n.Date=function(t){return t instanceof Date},n.NonScalar=function(t){return n.Object(t)||n.Array(t)},n.Path=function(t){var r=["String","Number","Function","Object"];return n.Array(t)?t.every(function(t){return e(t,r)}):e(t,r)},n.MixinCursor=function(t){return e(t,["String","Number","Array","Function","Cursor"])},n.MixinCursors=function(t){return e(t,["Object","Array","Function"])},n.ComplexPath=function(t){return e(t,["Object","Function"])},r.exports=n},{}],11:[function(t,r){function e(t,r){var e=new Error("baobab.update: "+r+" at path /"+t.slice(1).join("/"));return e.path=t,e}var n=t("./helpers.js"),i=t("./type.js");r.exports=function(t,r,o){if(o=o||{},!i.Object(t)&&!i.Array(t))throw Error("baobab.update: invalid target.");var s={};t={root:n.shallowClone(t)};var a=function(t,r,o,h){o=o||["root"];var u,c,l,f=o.join("λ"),p=o[o.length-1],d=Object.keys(r).some(function(t){return!!~["$unset","$set","$apply","$merge","$push","$unshift"].indexOf(t)});if(d){s[f]=t[p];for(c in r){if("$unset"===c){var b=o[o.length-2];i.Array(t)?h[b]=t.slice(0,+p).concat(t.slice(+p+1)):(h[b]=n.shallowClone(t),delete h[b][p]);break}if("$set"===c){l=r.$set,t[p]=l;break}if("$apply"===c){if(u=r.$apply,"function"!=typeof u)throw e(o,"using command $apply with a non function");t[p]=u.call(null,t[p]);break}if("$merge"===c){if(l=r.$merge,!i.Object(t[p])||!i.Object(l))throw e(o,"using command $merge with a non object");t[p]=n.shallowMerge(t[p],l);break}if("$push"===c){if(l=r.$push,!i.Array(t[p]))throw e(o,"using command $push to a non array");t[p]=t[p].concat(l)}if("$unshift"===c){if(l=r.$unshift,!i.Array(t[p]))throw e(o,"using command $unshift to a non array");t[p]=[].concat(l).concat(t[p])}}}else for(c in r)t[p][c]="undefined"==typeof t[p][c]?{}:n.shallowClone(t[p][c]),a(t[p],r[c],o.concat(c),t)};return a(t,r),{data:t.root,log:Object.keys(s).map(function(t){return{path:t.split("λ").slice(1),oldValue:s[t]}})}}},{"./helpers.js":7,"./type.js":10}]},{},[2])(2)}); \ No newline at end of file diff --git a/src/cursor.js b/src/cursor.js index be06dc7..0ea6857 100644 --- a/src/cursor.js +++ b/src/cursor.js @@ -52,7 +52,7 @@ function Cursor(tree, path, solvedPath, hash) { // Checking update log to see whether the cursor should update. outer: for (i = 0, l = log.length; i < l; i++) { - c = log[i]; + c = log[i].path; for (j = 0, m = c.length; j < m; j++) { p = c[j]; diff --git a/src/update.js b/src/update.js index 3903b52..4823c07 100644 --- a/src/update.js +++ b/src/update.js @@ -43,7 +43,7 @@ module.exports = function(data, spec, opts) { }); if (leafLevel) { - log[hash] = true; + log[hash] = o[lastKey]; for (k in spec) { @@ -141,7 +141,10 @@ module.exports = function(data, spec, opts) { // SHIFT LOG log: Object.keys(log).map(function(hash) { - return hash.split('λ').slice(1); + return { + path: hash.split('λ').slice(1), + oldValue: log[hash] + }; }) }; }; diff --git a/test/suites/baobab.js b/test/suites/baobab.js index 1d36969..ff62f82 100644 --- a/test/suites/baobab.js +++ b/test/suites/baobab.js @@ -72,7 +72,7 @@ describe('Baobab API', function() { it('should be possible to listen to update events.', function(done) { baobab.on('update', function(e) { - assert.deepEqual(e.data.log, [['one', 'subtwo', 'colors']]); + assert.deepEqual(e.data.log, [{path: ['one', 'subtwo', 'colors'], oldValue: ['blue', 'yellow']}]); done(); }); From f8ee87ce624f9572f0a680c44927b04bbe4fff43 Mon Sep 17 00:00:00 2001 From: Yomguithereal Date: Wed, 8 Apr 2015 18:08:24 +0200 Subject: [PATCH 28/73] Fixing $cursor command solving --- build/baobab.min.js | 2 +- src/baobab.js | 2 +- src/cursor.js | 12 ++++++++---- src/helpers.js | 16 ++++++++++------ src/type.js | 4 +++- 5 files changed, 23 insertions(+), 13 deletions(-) diff --git a/build/baobab.min.js b/build/baobab.min.js index 2514866..1a29107 100644 --- a/build/baobab.min.js +++ b/build/baobab.min.js @@ -1,2 +1,2 @@ /* baobab.js - Version: 1.0.0-rc1 - Author: Yomguithereal (Guillaume Plique) */ -!function(t){if("object"==typeof exports&&"undefined"!=typeof module)module.exports=t();else if("function"==typeof define&&define.amd)define([],t);else{var r;r="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:this,r.Baobab=t()}}(function(){var t;return function r(t,e,n){function i(s,a){if(!e[s]){if(!t[s]){var h="function"==typeof require&&require;if(!a&&h)return h(s,!0);if(o)return o(s,!0);var u=new Error("Cannot find module '"+s+"'");throw u.code="MODULE_NOT_FOUND",u}var c=e[s]={exports:{}};t[s][0].call(c.exports,function(r){var e=t[s][1][r];return i(e?e:r)},c,c.exports,r,t,e,n)}return e[s].exports}for(var o="function"==typeof require&&require,s=0;sr;r++)n.push(t[r].handler);return n}var i={once:"boolean",scope:"object"},o=function(){this._enabled=!0,this._children=[],this._handlers={},this._handlersAll=[]};o.prototype.on=function(t,r,e){var n,s,a,h,u,c;if("function"==typeof r){for(u="string"==typeof t?[t]:t,n=0,s=u.length;n!==s;n+=1)if(h=u[n]){this._handlers[h]||(this._handlers[h]=[]),c={handler:r};for(a in e||{}){if(!i[a])throw new Error('The option "'+a+'" is not recognized by Emmett.');c[a]=e[a]}this._handlers[h].push(c)}}else if(t&&"object"==typeof t&&!Array.isArray(t))for(h in t)o.prototype.on.call(this,h,t[h],r);else{if("function"!=typeof t)throw new Error("Wrong arguments.");c={handler:t};for(a in e||{}){if(!i[a])throw new Error('The option "'+a+'" is not recognized by Emmett.');c[a]=e[a]}this._handlersAll.push(c)}return this},o.prototype.once=function(t,r,e){if("function"==typeof r)e=e||{},e.once=!0,this.on(t,r,e);else{if((!t||"object"!=typeof t||Array.isArray(t))&&"function"!=typeof t)throw new Error("Wrong arguments.");r=r||{},r.once=!0,this.on(t,r)}return this},o.prototype.off=function(t,r){var e,n,i,o,s,a,h,u="string"==typeof t?[t]:t;if(1===arguments.length&&"function"==typeof u){r=arguments[0];for(s in this._handlers){for(a=[],e=0,n=this._handlers[s].length;e!==n;e+=1)this._handlers[s][e].handler!==r&&a.push(this._handlers[s][e]);this._handlers[s]=a}for(a=[],e=0,n=this._handlersAll.length;e!==n;e+=1)this._handlersAll[e].handler!==r&&a.push(this._handlersAll[e]);this._handlersAll=a}else if(2===arguments.length)for(e=0,n=u.length;e!==n;e+=1){if(h=u[e],this._handlers[h]){for(a=[],i=0,o=this._handlers[h].length;i!==o;i+=1)this._handlers[h][i].handler!==r&&a.push(this._handlers[h][i]);this._handlers[h]=a}this._handlers[h]&&0===this._handlers[h].length&&delete this._handlers[h]}return this},o.prototype.unbindAll=function(){var t;this._handlersAll=[];for(t in this._handlers)delete this._handlers[t];return this},o.prototype.emit=function(t,r){var e,n,i,o,s,a,h,u,c,l,f="string"==typeof t?[t]:t;if(!this._enabled)return this;for(r=void 0===r?{}:r,e=0,n=f.length;e!==n;e+=1)if(l=f[e],c=(this._handlers[l]||[]).concat(this._handlersAll),c.length){for(h={type:l,data:r||{},target:this},a=[],i=0,o=c.length;i!==o;i+=1)(this._handlers[l]&&this._handlers[l].indexOf(c[i])>=0||this._handlersAll.indexOf(c[i])>=0)&&(c[i].handler.call("scope"in c[i]?c[i].scope:this,h),c[i].once&&a.push(c[i]));for(s=0;se;e++)if(t._children[e]===r){t._children.splice(e,1);break}}),this._children.push(r),r},o.prototype.listeners=function(t){var e,n,i,o=[];if(t)for(o=r(this._handlers[t]),n=0,i=this._children.length;i>n;n++)o=o.concat(this._children[n].listeners(t));else{o=r(this._handlersAll);for(e in this._handlers)o=o.concat(r(this._handlers[e]));for(n=0,i=this._children.length;i>n;n++)o=o.concat(this._children[n].listeners())}return o},o.prototype.kill=function(){if(this.emit("emmett:kill"),this.unbindAll(),this._handlers=null,this._handlersAll=null,this._enabled=!1,this._children)for(var t=0,r=this._children.length;r>t;t++)this._children[t].kill();this._children=null},o.prototype.disable=function(){return this._enabled=!1,this},o.prototype.enable=function(){return this._enabled=!0,this},o.version="2.1.2","undefined"!=typeof n?("undefined"!=typeof e&&e.exports&&(n=e.exports=o),n.Emitter=o):"function"==typeof t&&t.amd?t("emmett",[],function(){return o}):this.Emitter=o}).call(this)},{}],4:[function(t,r){function e(t){return t+"$"+(new Date).getTime()+(""+Math.random()).replace("0.","")}function n(t,r){function e(t){this[t]=function(){var r=this.root[t].apply(this.root,arguments);return r instanceof i?this:r}}if(arguments.length<1&&(t={}),!(this instanceof n))return new n(t,r);if(!l.Object(t)&&!l.Array(t))throw Error("Baobab: invalid data.");o.call(this),this.options=s.shallowMerge(c,r),this._transaction={},this._future=void 0,this._cursors={},this.data=s.deepClone(t),this.root=this.select([]),["get","set","unset","update"].forEach(e.bind(this)),this.mixin=u.baobab(this)}var i=t("./cursor.js"),o=t("emmett"),s=t("./helpers.js"),a=t("./update.js"),h=t("./merge.js"),u=t("./mixins.js"),c=t("../defaults.js"),l=t("./type.js");s.inherits(n,o),n.prototype.select=function(t){if(!t)throw Error("Baobab.select: invalid path.");if(arguments.length>1&&(t=s.arrayOf(arguments)),!l.Path(t))throw Error("Baobab.select: invalid path.");t=[].concat(t);var r,n=l.ComplexPath(t);n&&(r=s.solvePath(this.data,t));var o=t.map(function(t){return l.Function(t)?e("fn"):l.Object(t)?e("ob"):t}).join("λ");if(this._cursors[o])return this._cursors[o];var a=new i(this,t,r,o);return this._cursors[o]=a,a},n.prototype.stack=function(t){var r=this;if(!l.Object(t))throw Error("Baobab.update: wrong specification.");return this._transaction=h(t,this._transaction),this.options.autoCommit?this.options.asynchronous?(this._future||(this._future=setTimeout(r.commit.bind(r,null),0)),this):this.commit():this},n.prototype.commit=function(){var t=a(this.data,this._transaction,this.options);return this.data=t.data,this._transaction={},this._future&&(this._future=clearTimeout(this._future)),this.emit("update",{log:t.log}),this},n.prototype.release=function(){delete this.data,delete this._transaction;for(var t in this._cursors)this._cursors[t].release();delete this._cursors,this.kill()},n.prototype.toJSON=function(){return this.get()},r.exports=n},{"../defaults.js":1,"./cursor.js":6,"./helpers.js":7,"./merge.js":8,"./mixins.js":9,"./type.js":10,"./update.js":11,emmett:3}],5:[function(t,r){function e(t,r){r.on("update",t.cursorListener),t.tree.off("update",t.treeListener),t.tree.on("update",t.treeListener)}function n(t){var r=this;if(arguments.length<2)throw Error("baobab.Combination: not enough arguments.");var n=arguments[1],i=s.arrayOf(arguments).slice(2);if(n instanceof Array&&(i=n.slice(1),n=n[0]),!a.Cursor(n))throw Error("baobab.Combination: argument should be a cursor.");if("or"!==t&&"and"!==t)throw Error("baobab.Combination: invalid operator.");o.call(this),this.cursors=[n],this.operators=[],this.tree=n.tree,this.updates=new Array(this.cursors.length),this.cursorListener=function(){r.updates[r.cursors.indexOf(this)]=!0},this.treeListener=function(){var t,e,n=r.updates[0];for(t=1,e=r.cursors.length;e>t;t++)n="or"===r.operators[t-1]?n||r.updates[t]:n&&r.updates[t];n&&r.emit("update"),r.updates=new Array(r.cursors.length)},this.bound=!1;var h=(this.on,this.once,function(){r.bound||(r.bound=!0,r.cursors.forEach(function(t){e(r,t)}))});this.on=s.before(h,this.on.bind(this)),this.once=s.before(h,this.once.bind(this)),i.forEach(function(r){this[t](r)},this)}function i(t){n.prototype[t]=function(r){if(!a.Cursor(r))throw this.release(),Error("baobab.Combination."+t+": argument should be a cursor.");if(~this.cursors.indexOf(r))throw this.release(),Error("baobab.Combination."+t+": cursor already in combination.");return this.cursors.push(r),this.operators.push(t),this.updates.length++,this.bound&&e(this,r),this}}var o=t("emmett"),s=t("./helpers.js"),a=t("./type.js");s.inherits(n,o),i("or"),i("and"),n.prototype.release=function(){this.cursors.forEach(function(t){t.off("update",this.cursorListener)},this),this.tree.off("update",this.treeListener),this.cursors=null,this.operators=null,this.tree=null,this.updates=null,this.kill()},r.exports=n},{"./helpers.js":7,"./type.js":10,emmett:3}],6:[function(t,r){function e(t,r,e,n){var i=this;o.call(this),r=r||[],this.tree=t,this.path=r,this.hash=n,this.archive=null,this.complexPath=!!e,this.solvedPath=this.complexPath?e:this.path,this.relevant=void 0!==this.get(),this.updateHandler=function(t){var r,e,n,o,s,a,u=t.data.log,c=!1;if(i.complexPath&&(i.solvedPath=h.solvePath(i.tree.data,i.path)),!i.path.length)return i.emit("update");t:for(s=0,n=u.length;n>s;s++)for(r=u[s].path,a=0,o=r.length;o>a&&(e=r[a],e===""+i.solvedPath[a]);a++)if(a+1===o||a+1===i.solvedPath.length){c=!0;break t}var l=void 0!==i.get();i.relevant?l&&c?i.emit("update"):l||(i.emit("irrelevant"),i.relevant=!1):l&&c&&(i.emit("relevant"),i.emit("update"),i.relevant=!0)},this.mixin=a.cursor(this);var s=!1,u=function(){s||(s=!0,i.tree.on("update",i.updateHandler))};this.on=h.before(u,this.on.bind(this)),this.once=h.before(u,this.once.bind(this))}function n(t,r,e,n){arguments.length<4&&(n=e,e=[]),e=e||[];var i=[].concat(e),o=h.solvePath(this.get(),i);if(!o)throw Error("baobab.Cursor."+t+": could not solve dynamic path.");if(r){var s=this.get(o);if(!u[r](s))throw Error("baobab.Cursor."+t+": invalid target.")}var a={};a["$"+t]=n;var c=h.pathObject(o,a);return c}function i(t,r){e.prototype[t]=function(){var e=n.bind(this,t,r).apply(this,arguments);return this.update(e)}}var o=t("emmett"),s=t("./combination.js"),a=t("./mixins.js"),h=t("./helpers.js"),u=t("./type.js");h.inherits(e,o),e.prototype.isRoot=function(){return!this.path.length},e.prototype.isLeaf=function(){return u.Primitive(this.get())},e.prototype.isBranch=function(){return!this.isLeaf()&&!this.isRoot()},e.prototype.root=function(){return this.tree.root()},e.prototype.select=function(t){if(arguments.length>1&&(t=h.arrayOf(arguments)),!u.Path(t))throw Error("baobab.Cursor.select: invalid path.");return this.tree.select(this.path.concat(t))},e.prototype.up=function(){return this.solvedPath&&this.solvedPath.length?this.tree.select(this.path.slice(0,-1)):null},e.prototype.left=function(){var t=+this.solvedPath[this.solvedPath.length-1];if(isNaN(t))throw Error("baobab.Cursor.left: cannot go left on a non-list type.");return t?this.tree.select(this.solvedPath.slice(0,-1).concat(t-1)):null},e.prototype.leftmost=function(){var t=+this.solvedPath[this.solvedPath.length-1];if(isNaN(t))throw Error("baobab.Cursor.leftmost: cannot go left on a non-list type.");return this.tree.select(this.solvedPath.slice(0,-1).concat(0))},e.prototype.right=function(){var t=+this.solvedPath[this.solvedPath.length-1];if(isNaN(t))throw Error("baobab.Cursor.right: cannot go right on a non-list type.");return t+1===this.up().get().length?null:this.tree.select(this.solvedPath.slice(0,-1).concat(t+1))},e.prototype.rightmost=function(){var t=+this.solvedPath[this.solvedPath.length-1];if(isNaN(t))throw Error("baobab.Cursor.right: cannot go right on a non-list type.");var r=this.up().get();return this.tree.select(this.solvedPath.slice(0,-1).concat(r.length-1))},e.prototype.down=function(){+this.solvedPath[this.solvedPath.length-1];return this.get()instanceof Array?this.tree.select(this.solvedPath.concat(0)):null},e.prototype.get=function(t){arguments.length>1&&(t=h.arrayOf(arguments));var r=this.solvedPath.concat((u.String(t)||u.Number(t)?[t]:t)||[]);return h.getIn(this.tree.data,r,this.tree)},i("set"),i("apply"),i("chain"),i("push","Array"),i("unshift","Array"),e.prototype.merge=function(t){if(!u.Object(t))throw Error("baobab.Cursor.merge: trying to merge a non-object.");var r=n.bind(this,"merge","Object").apply(this,arguments);return this.update(r)},e.prototype.unset=function(t){if(void 0===t&&this.isRoot())throw Error("baobab.Cursor.unset: cannot remove root node.");var r=n.bind(this,"unset",null).apply(this,[t,!0]);return this.update(r)},e.prototype.update=function(t,r){if(arguments.length<2)return this.tree.stack(h.pathObject(this.solvedPath,t)),this;var e=[].concat(t),n=h.solvePath(this.get(),e);if(!n)throw Error("baobab.Cursor.update: could not solve dynamic path.");return this.tree.stack(h.pathObject(this.solvedPath.concat(n),r)),this},e.prototype.or=function(t){return new s("or",this,t)},e.prototype.and=function(t){return new s("and",this,t)},e.prototype.startRecording=function(t){return this.archive?this:(this.archive=h.archive(t),this)},e.prototype.stopRecording=function(){return this.archive=null,this},e.prototype.undo=function(){},e.prototype.redo=function(){},e.prototype.hasHistory=function(){return this.archive&&this.archive.records.length},e.prototype.getHistory=function(){return this.archive.records},e.prototype.release=function(){this.tree.off("update",this.updateHandler),this.hash&&delete this.tree._cursors[this.hash],delete this.tree,delete this.path,delete this.solvedPath,this.kill()},e.prototype.toJSON=function(){return this.get()},u.Cursor=function(t){return t instanceof e},r.exports=e},{"./combination.js":5,"./helpers.js":7,"./mixins.js":9,"./type.js":10,emmett:3}],7:[function(t,r){(function(e){function n(t){return Array.prototype.slice.call(t)}function i(t,r){return function(){t(),r.apply(null,arguments)}}function o(t,r){var e,n={};for(e in t)n[e]=t[e];for(e in r)n[e]=r[e];return n}function s(t){var r=t.source,e="";return t.global&&(e+="g"),t.multiline&&(e+="m"),t.ignoreCase&&(e+="i"),t.sticky&&(e+="y"),t.unicode&&(e+="u"),new RegExp(r,e)}function a(t,r){if(!r||"object"!=typeof r||r instanceof Error||"ArrayBuffer"in e&&r instanceof ArrayBuffer)return r;if(_.Array(r)){if(t){var n,i,o=[];for(n=0,i=r.length;i>n;n++)o.push(w(r[n]));return o}return r.slice(0)}if(_.Date(r))return new Date(r.getTime());if(r instanceof RegExp)return s(r);if(_.Object(r)){var a,h={};r.constructor&&r.constructor!==Object&&(h=Object.create(r.constructor.prototype));for(a in r)r.hasOwnProperty(a)&&(h[a]=t?w(r[a]):r[a]);return h}return r}function h(t,r){return function(e){return r(t(e))}}function u(t,r){var e,n;for(e=0,n=t.length;n>e;e++)if(r(t[e]))return t[e]}function c(t,r){var e,n;for(e=0,n=t.length;n>e;e++)if(r(t[e]))return e;return-1}function l(t,r){var e,n=!0;if(!t)return!1;for(e in r)if(_.Object(r[e]))n=n&&l(t[e],r[e]);else if(_.Array(r[e]))n=n&&!!~r[e].indexOf(t[e]);else if(t[e]!==r[e])return!1;return n}function f(t,r){return u(t,function(t){return l(t,r)})}function d(t,r){return c(t,function(t){return l(t,r)})}function b(t,r,e){r=r||[];var n,i,o,s=t;for(i=0,o=r.length;o>i;i++){if(!s)return;if("function"==typeof r[i]){if(!_.Array(s))return;s=u(s,r[i])}else if("object"==typeof r[i])if("$cursor"in r[i]){if(!_.Path(r[i].$cursor))throw Error("baobab.getIn: $cursor path must be an array.");n=e.get(r[i].$cursor),s=s[n]}else{if(!_.Array(s))return;s=f(s,r[i])}else s=s[r[i]]}return s}function y(t,r,e){var n,i,o,s=[],a=t;for(i=0,o=r.length;o>i;i++){if(!a)return null;if("function"==typeof r[i]){if(!_.Array(a))return;n=c(a,r[i]),s.push(n),a=a[n]}else if("object"==typeof r[i]){if("$cursor"in r[i]){if(!_.Path(r[i].$cursor))throw Error("baobab.getIn: $cursor path must be an array.");p=e.get(r[i].$cursor),a=a[p]}if(!_.Array(a))return;n=d(a,r[i]),s.push(n),a=a[n]}else s.push(r[i]),a=a[r[i]]||{}}return s}function g(t,r){var e,n=t.length,i={},o=i;for(n||(i=r),e=0;n>e;e++)o[t[e]]=e+1===n?r:{},o=o[t[e]];return i}function m(t,r){t.super_=r;var e=function(){};e.prototype=r.prototype,t.prototype=new e,t.prototype.constructor=t}function v(t){this.size=t,this.records=[],this.add=function(r){for(this.records.unshift(r);this.records.length>t;)this.records.pop();return this},this.get=function(){return this.records}}var _=t("./type.js"),j=a.bind(null,!1),w=a.bind(null,!0);r.exports={archive:v,arrayOf:n,before:i,deepClone:w,shallowClone:j,shallowMerge:o,compose:h,getIn:b,inherits:m,pathObject:g,solvePath:y}}).call(this,"undefined"!=typeof global?global:"undefined"!=typeof self?self:"undefined"!=typeof window?window:{})},{"./type.js":10}],8:[function(t,r){function e(t,r,e){s.forEach(function(r){e!==r&&delete t[r]}),t[e]=r[e]}function n(t,r){var a,h=i.shallowClone(r||{});s.forEach(function(r){t[r]&&e(h,t,r)}),t.$chain&&(s.slice(0,-1).forEach(function(t){delete h[t]}),h.$apply=h.$apply?i.compose(h.$apply,t.$chain):t.$chain),t.$push&&h.$push?h.$push=o.Array(h.$push)?h.$push.concat(t.$push):[h.$push].concat(t.$push):t.$push&&(h.$push=t.$push),t.$unshift&&h.$unshift?h.$unshift=o.Array(t.$unshift)?t.$unshift.concat(h.$unshift):[t.$unshift].concat(h.$unshift):t.$unshift&&(h.$unshift=t.$unshift);for(a in t)o.Object(t[a])?h[a]=n(t[a],h[a]):"$"!==a[0]&&(h[a]=t[a]);return h}var i=t("./helpers.js"),o=t("./type.js"),s=["$unset","$set","$merge","$apply"];r.exports=n},{"./helpers.js":7,"./type.js":10}],9:[function(t,r){var e=t("./combination.js"),n=t("./type.js");r.exports={baobab:function(t){return{mixins:[{getInitialState:function(){if(this.tree=t,!this.cursor&&!this.cursors)return{};if(this.cursor&&this.cursors)throw Error("baobab.mixin: you cannot have both `component.cursor` and `component.cursors`. Please make up your mind.");if(this.__type=null,this.__updateHandler=function(){this.setState(this.__getCursorData())}.bind(this),this.cursor){if(!n.MixinCursor(this.cursor))throw Error("baobab.mixin.cursor: invalid data (cursor, string, array or function).");n.Function(this.cursor)&&(this.cursor=this.cursor()),n.Cursor(this.cursor)||(this.cursor=t.select(this.cursor)),this.__getCursorData=function(){return{cursor:this.cursor.get()}}.bind(this),this.__type="single"}else if(this.cursors){if(!n.MixinCursors(this.cursors))throw Error("baobab.mixin.cursor: invalid data (object, array or function).");if(n.Function(this.cursors)&&(this.cursors=this.cursors()),n.Array(this.cursors))this.cursors=this.cursors.map(function(r){return n.Cursor(r)?r:t.select(r)}),this.__getCursorData=function(){return{cursors:this.cursors.map(function(t){return t.get()})}}.bind(this),this.__type="array";else{for(var r in this.cursors)n.Cursor(this.cursors[r])||(this.cursors[r]=t.select(this.cursors[r]));this.__getCursorData=function(){var t={};for(r in this.cursors)t[r]=this.cursors[r].get();return{cursors:t}}.bind(this),this.__type="object"}}return this.__getCursorData()},componentDidMount:function(){"single"===this.__type?(this.__combination=new e("or",[this.cursor]),this.__combination.on("update",this.__updateHandler)):"array"===this.__type?(this.__combination=new e("or",this.cursors),this.__combination.on("update",this.__updateHandler)):"object"===this.__type&&(this.__combination=new e("or",Object.keys(this.cursors).map(function(t){return this.cursors[t]},this)),this.__combination.on("update",this.__updateHandler))},componentWillUnmount:function(){this.__combination&&this.__combination.release()}}].concat(t.options.mixins)}},cursor:function(t){return{mixins:[{getInitialState:function(){return this.cursor=t,this.__updateHandler=function(){this.setState({cursor:this.cursor.get()})}.bind(this),{cursor:this.cursor.get()}},componentDidMount:function(){this.cursor.on("update",this.__updateHandler)},componentWillUnmount:function(){this.cursor.off("update",this.__updateHandler)}}].concat(t.tree.options.mixins)}}}},{"./combination.js":5,"./type.js":10}],10:[function(t,r){function e(t,r){return r.some(function(r){return n[r](t)})}var n={};n.Array=function(t){return Array.isArray(t)},n.Object=function(t){return!Array.isArray(t)&&"object"==typeof t&&null!==t},n.String=function(t){return"string"==typeof t},n.Number=function(t){return"number"==typeof t},n.Function=function(t){return"function"==typeof t},n.Primitive=function(t){return"string"==typeof t||"number"==typeof t||"boolean"==typeof t},n.Date=function(t){return t instanceof Date},n.NonScalar=function(t){return n.Object(t)||n.Array(t)},n.Path=function(t){var r=["String","Number","Function","Object"];return n.Array(t)?t.every(function(t){return e(t,r)}):e(t,r)},n.MixinCursor=function(t){return e(t,["String","Number","Array","Function","Cursor"])},n.MixinCursors=function(t){return e(t,["Object","Array","Function"])},n.ComplexPath=function(t){return e(t,["Object","Function"])},r.exports=n},{}],11:[function(t,r){function e(t,r){var e=new Error("baobab.update: "+r+" at path /"+t.slice(1).join("/"));return e.path=t,e}var n=t("./helpers.js"),i=t("./type.js");r.exports=function(t,r,o){if(o=o||{},!i.Object(t)&&!i.Array(t))throw Error("baobab.update: invalid target.");var s={};t={root:n.shallowClone(t)};var a=function(t,r,o,h){o=o||["root"];var u,c,l,f=o.join("λ"),p=o[o.length-1],d=Object.keys(r).some(function(t){return!!~["$unset","$set","$apply","$merge","$push","$unshift"].indexOf(t)});if(d){s[f]=t[p];for(c in r){if("$unset"===c){var b=o[o.length-2];i.Array(t)?h[b]=t.slice(0,+p).concat(t.slice(+p+1)):(h[b]=n.shallowClone(t),delete h[b][p]);break}if("$set"===c){l=r.$set,t[p]=l;break}if("$apply"===c){if(u=r.$apply,"function"!=typeof u)throw e(o,"using command $apply with a non function");t[p]=u.call(null,t[p]);break}if("$merge"===c){if(l=r.$merge,!i.Object(t[p])||!i.Object(l))throw e(o,"using command $merge with a non object");t[p]=n.shallowMerge(t[p],l);break}if("$push"===c){if(l=r.$push,!i.Array(t[p]))throw e(o,"using command $push to a non array");t[p]=t[p].concat(l)}if("$unshift"===c){if(l=r.$unshift,!i.Array(t[p]))throw e(o,"using command $unshift to a non array");t[p]=[].concat(l).concat(t[p])}}}else for(c in r)t[p][c]="undefined"==typeof t[p][c]?{}:n.shallowClone(t[p][c]),a(t[p],r[c],o.concat(c),t)};return a(t,r),{data:t.root,log:Object.keys(s).map(function(t){return{path:t.split("λ").slice(1),oldValue:s[t]}})}}},{"./helpers.js":7,"./type.js":10}]},{},[2])(2)}); \ No newline at end of file +!function(t){if("object"==typeof exports&&"undefined"!=typeof module)module.exports=t();else if("function"==typeof define&&define.amd)define([],t);else{var r;r="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:this,r.Baobab=t()}}(function(){var t;return function r(t,e,n){function i(s,a){if(!e[s]){if(!t[s]){var h="function"==typeof require&&require;if(!a&&h)return h(s,!0);if(o)return o(s,!0);var u=new Error("Cannot find module '"+s+"'");throw u.code="MODULE_NOT_FOUND",u}var c=e[s]={exports:{}};t[s][0].call(c.exports,function(r){var e=t[s][1][r];return i(e?e:r)},c,c.exports,r,t,e,n)}return e[s].exports}for(var o="function"==typeof require&&require,s=0;sr;r++)n.push(t[r].handler);return n}var i={once:"boolean",scope:"object"},o=function(){this._enabled=!0,this._children=[],this._handlers={},this._handlersAll=[]};o.prototype.on=function(t,r,e){var n,s,a,h,u,c;if("function"==typeof r){for(u="string"==typeof t?[t]:t,n=0,s=u.length;n!==s;n+=1)if(h=u[n]){this._handlers[h]||(this._handlers[h]=[]),c={handler:r};for(a in e||{}){if(!i[a])throw new Error('The option "'+a+'" is not recognized by Emmett.');c[a]=e[a]}this._handlers[h].push(c)}}else if(t&&"object"==typeof t&&!Array.isArray(t))for(h in t)o.prototype.on.call(this,h,t[h],r);else{if("function"!=typeof t)throw new Error("Wrong arguments.");c={handler:t};for(a in e||{}){if(!i[a])throw new Error('The option "'+a+'" is not recognized by Emmett.');c[a]=e[a]}this._handlersAll.push(c)}return this},o.prototype.once=function(t,r,e){if("function"==typeof r)e=e||{},e.once=!0,this.on(t,r,e);else{if((!t||"object"!=typeof t||Array.isArray(t))&&"function"!=typeof t)throw new Error("Wrong arguments.");r=r||{},r.once=!0,this.on(t,r)}return this},o.prototype.off=function(t,r){var e,n,i,o,s,a,h,u="string"==typeof t?[t]:t;if(1===arguments.length&&"function"==typeof u){r=arguments[0];for(s in this._handlers){for(a=[],e=0,n=this._handlers[s].length;e!==n;e+=1)this._handlers[s][e].handler!==r&&a.push(this._handlers[s][e]);this._handlers[s]=a}for(a=[],e=0,n=this._handlersAll.length;e!==n;e+=1)this._handlersAll[e].handler!==r&&a.push(this._handlersAll[e]);this._handlersAll=a}else if(2===arguments.length)for(e=0,n=u.length;e!==n;e+=1){if(h=u[e],this._handlers[h]){for(a=[],i=0,o=this._handlers[h].length;i!==o;i+=1)this._handlers[h][i].handler!==r&&a.push(this._handlers[h][i]);this._handlers[h]=a}this._handlers[h]&&0===this._handlers[h].length&&delete this._handlers[h]}return this},o.prototype.unbindAll=function(){var t;this._handlersAll=[];for(t in this._handlers)delete this._handlers[t];return this},o.prototype.emit=function(t,r){var e,n,i,o,s,a,h,u,c,l,f="string"==typeof t?[t]:t;if(!this._enabled)return this;for(r=void 0===r?{}:r,e=0,n=f.length;e!==n;e+=1)if(l=f[e],c=(this._handlers[l]||[]).concat(this._handlersAll),c.length){for(h={type:l,data:r||{},target:this},a=[],i=0,o=c.length;i!==o;i+=1)(this._handlers[l]&&this._handlers[l].indexOf(c[i])>=0||this._handlersAll.indexOf(c[i])>=0)&&(c[i].handler.call("scope"in c[i]?c[i].scope:this,h),c[i].once&&a.push(c[i]));for(s=0;se;e++)if(t._children[e]===r){t._children.splice(e,1);break}}),this._children.push(r),r},o.prototype.listeners=function(t){var e,n,i,o=[];if(t)for(o=r(this._handlers[t]),n=0,i=this._children.length;i>n;n++)o=o.concat(this._children[n].listeners(t));else{o=r(this._handlersAll);for(e in this._handlers)o=o.concat(r(this._handlers[e]));for(n=0,i=this._children.length;i>n;n++)o=o.concat(this._children[n].listeners())}return o},o.prototype.kill=function(){if(this.emit("emmett:kill"),this.unbindAll(),this._handlers=null,this._handlersAll=null,this._enabled=!1,this._children)for(var t=0,r=this._children.length;r>t;t++)this._children[t].kill();this._children=null},o.prototype.disable=function(){return this._enabled=!1,this},o.prototype.enable=function(){return this._enabled=!0,this},o.version="2.1.2","undefined"!=typeof n?("undefined"!=typeof e&&e.exports&&(n=e.exports=o),n.Emitter=o):"function"==typeof t&&t.amd?t("emmett",[],function(){return o}):this.Emitter=o}).call(this)},{}],4:[function(t,r){function e(t){return t+"$"+(new Date).getTime()+(""+Math.random()).replace("0.","")}function n(t,r){function e(t){this[t]=function(){var r=this.root[t].apply(this.root,arguments);return r instanceof i?this:r}}if(arguments.length<1&&(t={}),!(this instanceof n))return new n(t,r);if(!l.Object(t)&&!l.Array(t))throw Error("Baobab: invalid data.");o.call(this),this.options=s.shallowMerge(c,r),this._transaction={},this._future=void 0,this._cursors={},this.data=s.deepClone(t),this.root=this.select([]),["get","set","unset","update"].forEach(e.bind(this)),this.mixin=u.baobab(this)}var i=t("./cursor.js"),o=t("emmett"),s=t("./helpers.js"),a=t("./update.js"),h=t("./merge.js"),u=t("./mixins.js"),c=t("../defaults.js"),l=t("./type.js");s.inherits(n,o),n.prototype.select=function(t){if(!t)throw Error("Baobab.select: invalid path.");if(arguments.length>1&&(t=s.arrayOf(arguments)),!l.Path(t))throw Error("Baobab.select: invalid path.");t=[].concat(t);var r,n=l.ComplexPath(t);n&&(r=s.solvePath(this.data,t,this));var o=t.map(function(t){return l.Function(t)?e("fn"):l.Object(t)?e("ob"):t}).join("λ");if(this._cursors[o])return this._cursors[o];var a=new i(this,t,r,o);return this._cursors[o]=a,a},n.prototype.stack=function(t){var r=this;if(!l.Object(t))throw Error("Baobab.update: wrong specification.");return this._transaction=h(t,this._transaction),this.options.autoCommit?this.options.asynchronous?(this._future||(this._future=setTimeout(r.commit.bind(r,null),0)),this):this.commit():this},n.prototype.commit=function(){var t=a(this.data,this._transaction,this.options);return this.data=t.data,this._transaction={},this._future&&(this._future=clearTimeout(this._future)),this.emit("update",{log:t.log}),this},n.prototype.release=function(){delete this.data,delete this._transaction;for(var t in this._cursors)this._cursors[t].release();delete this._cursors,this.kill()},n.prototype.toJSON=function(){return this.get()},r.exports=n},{"../defaults.js":1,"./cursor.js":6,"./helpers.js":7,"./merge.js":8,"./mixins.js":9,"./type.js":10,"./update.js":11,emmett:3}],5:[function(t,r){function e(t,r){r.on("update",t.cursorListener),t.tree.off("update",t.treeListener),t.tree.on("update",t.treeListener)}function n(t){var r=this;if(arguments.length<2)throw Error("baobab.Combination: not enough arguments.");var n=arguments[1],i=s.arrayOf(arguments).slice(2);if(n instanceof Array&&(i=n.slice(1),n=n[0]),!a.Cursor(n))throw Error("baobab.Combination: argument should be a cursor.");if("or"!==t&&"and"!==t)throw Error("baobab.Combination: invalid operator.");o.call(this),this.cursors=[n],this.operators=[],this.tree=n.tree,this.updates=new Array(this.cursors.length),this.cursorListener=function(){r.updates[r.cursors.indexOf(this)]=!0},this.treeListener=function(){var t,e,n=r.updates[0];for(t=1,e=r.cursors.length;e>t;t++)n="or"===r.operators[t-1]?n||r.updates[t]:n&&r.updates[t];n&&r.emit("update"),r.updates=new Array(r.cursors.length)},this.bound=!1;var h=(this.on,this.once,function(){r.bound||(r.bound=!0,r.cursors.forEach(function(t){e(r,t)}))});this.on=s.before(h,this.on.bind(this)),this.once=s.before(h,this.once.bind(this)),i.forEach(function(r){this[t](r)},this)}function i(t){n.prototype[t]=function(r){if(!a.Cursor(r))throw this.release(),Error("baobab.Combination."+t+": argument should be a cursor.");if(~this.cursors.indexOf(r))throw this.release(),Error("baobab.Combination."+t+": cursor already in combination.");return this.cursors.push(r),this.operators.push(t),this.updates.length++,this.bound&&e(this,r),this}}var o=t("emmett"),s=t("./helpers.js"),a=t("./type.js");s.inherits(n,o),i("or"),i("and"),n.prototype.release=function(){this.cursors.forEach(function(t){t.off("update",this.cursorListener)},this),this.tree.off("update",this.treeListener),this.cursors=null,this.operators=null,this.tree=null,this.updates=null,this.kill()},r.exports=n},{"./helpers.js":7,"./type.js":10,emmett:3}],6:[function(t,r){function e(t,r,e,n){var i=this;o.call(this),r=r||[],this.tree=t,this.path=r,this.hash=n,this.archive=null,this.complexPath=!!e,this.solvedPath=this.complexPath?e:this.path,this.relevant=void 0!==this.get(),this.updateHandler=function(t){var r,e,n,o,s,a,u=t.data.log,c=!1;if(i.complexPath&&(i.solvedPath=h.solvePath(i.tree.data,i.path,i.tree)),!i.path.length)return i.emit("update");t:for(s=0,n=u.length;n>s;s++)for(r=u[s].path,a=0,o=r.length;o>a&&(e=r[a],e===""+i.solvedPath[a]);a++)if(a+1===o||a+1===i.solvedPath.length){c=!0;break t}var l=void 0!==i.get();i.relevant?l&&c?i.emit("update"):l||(i.emit("irrelevant"),i.relevant=!1):l&&c&&(i.emit("relevant"),i.emit("update"),i.relevant=!0)},this.mixin=a.cursor(this);var s=!1,u=function(){s||(s=!0,i.tree.on("update",i.updateHandler))};this.on=h.before(u,this.on.bind(this)),this.once=h.before(u,this.once.bind(this))}function n(t,r,e,n){arguments.length<4&&(n=e,e=[]),e=e||[];var i=[].concat(e),o=h.solvePath(this.get(),i,this.tree);if(!o)throw Error("baobab.Cursor."+t+": could not solve dynamic path.");if(r){var s=this.get(o);if(!u[r](s))throw Error("baobab.Cursor."+t+": invalid target.")}var a={};a["$"+t]=n;var c=h.pathObject(o,a);return c}function i(t,r){e.prototype[t]=function(){var e=n.bind(this,t,r).apply(this,arguments);return this.update(e)}}var o=t("emmett"),s=t("./combination.js"),a=t("./mixins.js"),h=t("./helpers.js"),u=t("./type.js");h.inherits(e,o),e.prototype.isRoot=function(){return!this.path.length},e.prototype.isLeaf=function(){return u.Primitive(this.get())},e.prototype.isBranch=function(){return!this.isLeaf()&&!this.isRoot()},e.prototype.root=function(){return this.tree.root()},e.prototype.select=function(t){if(arguments.length>1&&(t=h.arrayOf(arguments)),!u.Path(t))throw Error("baobab.Cursor.select: invalid path.");return this.tree.select(this.path.concat(t))},e.prototype.up=function(){return this.solvedPath&&this.solvedPath.length?this.tree.select(this.path.slice(0,-1)):null},e.prototype.left=function(){var t=+this.solvedPath[this.solvedPath.length-1];if(isNaN(t))throw Error("baobab.Cursor.left: cannot go left on a non-list type.");return t?this.tree.select(this.solvedPath.slice(0,-1).concat(t-1)):null},e.prototype.leftmost=function(){var t=+this.solvedPath[this.solvedPath.length-1];if(isNaN(t))throw Error("baobab.Cursor.leftmost: cannot go left on a non-list type.");return this.tree.select(this.solvedPath.slice(0,-1).concat(0))},e.prototype.right=function(){var t=+this.solvedPath[this.solvedPath.length-1];if(isNaN(t))throw Error("baobab.Cursor.right: cannot go right on a non-list type.");return t+1===this.up().get().length?null:this.tree.select(this.solvedPath.slice(0,-1).concat(t+1))},e.prototype.rightmost=function(){var t=+this.solvedPath[this.solvedPath.length-1];if(isNaN(t))throw Error("baobab.Cursor.right: cannot go right on a non-list type.");var r=this.up().get();return this.tree.select(this.solvedPath.slice(0,-1).concat(r.length-1))},e.prototype.down=function(){+this.solvedPath[this.solvedPath.length-1];return this.get()instanceof Array?this.tree.select(this.solvedPath.concat(0)):null},e.prototype.get=function(t){arguments.length>1&&(t=h.arrayOf(arguments));var r=this.solvedPath.concat((u.String(t)||u.Number(t)?[t]:t)||[]);return h.getIn(this.tree.data,r,this.tree)},i("set"),i("apply"),i("chain"),i("push","Array"),i("unshift","Array"),e.prototype.merge=function(t){if(!u.Object(t))throw Error("baobab.Cursor.merge: trying to merge a non-object.");var r=n.bind(this,"merge","Object").apply(this,arguments);return this.update(r)},e.prototype.unset=function(t){if(void 0===t&&this.isRoot())throw Error("baobab.Cursor.unset: cannot remove root node.");var r=n.bind(this,"unset",null).apply(this,[t,!0]);return this.update(r)},e.prototype.update=function(t,r){if(arguments.length<2)return this.tree.stack(h.pathObject(this.solvedPath,t)),this;var e=[].concat(t),n=h.solvePath(this.get(),e,this.tree);if(!n)throw Error("baobab.Cursor.update: could not solve dynamic path.");return this.tree.stack(h.pathObject(this.solvedPath.concat(n),r)),this},e.prototype.or=function(t){return new s("or",this,t)},e.prototype.and=function(t){return new s("and",this,t)},e.prototype.startRecording=function(t){return this.archive?this:(this.archive=h.archive(t),this)},e.prototype.stopRecording=function(){return this.archive=null,this},e.prototype.undo=function(){},e.prototype.redo=function(){},e.prototype.isRecording=function(){return!!this.archive},e.prototype.hasHistory=function(){return!(!this.archive||!this.archive.records.length)},e.prototype.getHistory=function(){return this.archive.records},e.prototype.release=function(){this.tree.off("update",this.updateHandler),this.hash&&delete this.tree._cursors[this.hash],delete this.tree,delete this.path,delete this.solvedPath,this.kill()},e.prototype.toJSON=function(){return this.get()},u.Cursor=function(t){return t instanceof e},r.exports=e},{"./combination.js":5,"./helpers.js":7,"./mixins.js":9,"./type.js":10,emmett:3}],7:[function(t,r){(function(e){function n(t){return Array.prototype.slice.call(t)}function i(t,r){return function(){t(),r.apply(null,arguments)}}function o(t,r){var e,n={};for(e in t)n[e]=t[e];for(e in r)n[e]=r[e];return n}function s(t){var r=t.source,e="";return t.global&&(e+="g"),t.multiline&&(e+="m"),t.ignoreCase&&(e+="i"),t.sticky&&(e+="y"),t.unicode&&(e+="u"),new RegExp(r,e)}function a(t,r){if(!r||"object"!=typeof r||r instanceof Error||"ArrayBuffer"in e&&r instanceof ArrayBuffer)return r;if(_.Array(r)){if(t){var n,i,o=[];for(n=0,i=r.length;i>n;n++)o.push(w(r[n]));return o}return r.slice(0)}if(_.Date(r))return new Date(r.getTime());if(r instanceof RegExp)return s(r);if(_.Object(r)){var a,h={};r.constructor&&r.constructor!==Object&&(h=Object.create(r.constructor.prototype));for(a in r)r.hasOwnProperty(a)&&(h[a]=t?w(r[a]):r[a]);return h}return r}function h(t,r){return function(e){return r(t(e))}}function u(t,r){var e,n;for(e=0,n=t.length;n>e;e++)if(r(t[e]))return t[e]}function c(t,r){var e,n;for(e=0,n=t.length;n>e;e++)if(r(t[e]))return e;return-1}function l(t,r){var e,n=!0;if(!t)return!1;for(e in r)if(_.Object(r[e]))n=n&&l(t[e],r[e]);else if(_.Array(r[e]))n=n&&!!~r[e].indexOf(t[e]);else if(t[e]!==r[e])return!1;return n}function f(t,r){return u(t,function(t){return l(t,r)})}function d(t,r){return c(t,function(t){return l(t,r)})}function b(t,r,e){r=r||[];var n,i,o,s=t;for(i=0,o=r.length;o>i;i++){if(!s)return;if("function"==typeof r[i]){if(!_.Array(s))return;s=u(s,r[i])}else if("object"==typeof r[i])if(e&&"$cursor"in r[i]){if(!_.Path(r[i].$cursor))throw Error("baobab.getIn: $cursor path must be an array.");n=e.get(r[i].$cursor),s=s[n]}else{if(!_.Array(s))return;s=f(s,r[i])}else s=s[r[i]]}return s}function y(t,r,e){var n,i,o,s=[],a=t;for(i=0,o=r.length;o>i;i++){if(!a)return null;if("function"==typeof r[i]){if(!_.Array(a))return;n=c(a,r[i]),s.push(n),a=a[n]}else if("object"==typeof r[i])if(e&&"$cursor"in r[i]){if(!_.Path(r[i].$cursor))throw Error("baobab.getIn: $cursor path must be an array.");p=e.get(r[i].$cursor),s.push(p),a=a[p]}else{if(!_.Array(a))return;n=d(a,r[i]),s.push(n),a=a[n]}else s.push(r[i]),a=a[r[i]]||{}}return s}function g(t,r){var e,n=t.length,i={},o=i;for(n||(i=r),e=0;n>e;e++)o[t[e]]=e+1===n?r:{},o=o[t[e]];return i}function m(t,r){t.super_=r;var e=function(){};e.prototype=r.prototype,t.prototype=new e,t.prototype.constructor=t}function v(t){this.size=t,this.records=[],this.add=function(r){for(this.records.unshift(r);this.records.length>t;)this.records.pop();return this},this.get=function(){return this.records}}var _=t("./type.js"),j=a.bind(null,!1),w=a.bind(null,!0);r.exports={archive:v,arrayOf:n,before:i,deepClone:w,shallowClone:j,shallowMerge:o,compose:h,getIn:b,inherits:m,pathObject:g,solvePath:y}}).call(this,"undefined"!=typeof global?global:"undefined"!=typeof self?self:"undefined"!=typeof window?window:{})},{"./type.js":10}],8:[function(t,r){function e(t,r,e){s.forEach(function(r){e!==r&&delete t[r]}),t[e]=r[e]}function n(t,r){var a,h=i.shallowClone(r||{});s.forEach(function(r){t[r]&&e(h,t,r)}),t.$chain&&(s.slice(0,-1).forEach(function(t){delete h[t]}),h.$apply=h.$apply?i.compose(h.$apply,t.$chain):t.$chain),t.$push&&h.$push?h.$push=o.Array(h.$push)?h.$push.concat(t.$push):[h.$push].concat(t.$push):t.$push&&(h.$push=t.$push),t.$unshift&&h.$unshift?h.$unshift=o.Array(t.$unshift)?t.$unshift.concat(h.$unshift):[t.$unshift].concat(h.$unshift):t.$unshift&&(h.$unshift=t.$unshift);for(a in t)o.Object(t[a])?h[a]=n(t[a],h[a]):"$"!==a[0]&&(h[a]=t[a]);return h}var i=t("./helpers.js"),o=t("./type.js"),s=["$unset","$set","$merge","$apply"];r.exports=n},{"./helpers.js":7,"./type.js":10}],9:[function(t,r){var e=t("./combination.js"),n=t("./type.js");r.exports={baobab:function(t){return{mixins:[{getInitialState:function(){if(this.tree=t,!this.cursor&&!this.cursors)return{};if(this.cursor&&this.cursors)throw Error("baobab.mixin: you cannot have both `component.cursor` and `component.cursors`. Please make up your mind.");if(this.__type=null,this.__updateHandler=function(){this.setState(this.__getCursorData())}.bind(this),this.cursor){if(!n.MixinCursor(this.cursor))throw Error("baobab.mixin.cursor: invalid data (cursor, string, array or function).");n.Function(this.cursor)&&(this.cursor=this.cursor()),n.Cursor(this.cursor)||(this.cursor=t.select(this.cursor)),this.__getCursorData=function(){return{cursor:this.cursor.get()}}.bind(this),this.__type="single"}else if(this.cursors){if(!n.MixinCursors(this.cursors))throw Error("baobab.mixin.cursor: invalid data (object, array or function).");if(n.Function(this.cursors)&&(this.cursors=this.cursors()),n.Array(this.cursors))this.cursors=this.cursors.map(function(r){return n.Cursor(r)?r:t.select(r)}),this.__getCursorData=function(){return{cursors:this.cursors.map(function(t){return t.get()})}}.bind(this),this.__type="array";else{for(var r in this.cursors)n.Cursor(this.cursors[r])||(this.cursors[r]=t.select(this.cursors[r]));this.__getCursorData=function(){var t={};for(r in this.cursors)t[r]=this.cursors[r].get();return{cursors:t}}.bind(this),this.__type="object"}}return this.__getCursorData()},componentDidMount:function(){"single"===this.__type?(this.__combination=new e("or",[this.cursor]),this.__combination.on("update",this.__updateHandler)):"array"===this.__type?(this.__combination=new e("or",this.cursors),this.__combination.on("update",this.__updateHandler)):"object"===this.__type&&(this.__combination=new e("or",Object.keys(this.cursors).map(function(t){return this.cursors[t]},this)),this.__combination.on("update",this.__updateHandler))},componentWillUnmount:function(){this.__combination&&this.__combination.release()}}].concat(t.options.mixins)}},cursor:function(t){return{mixins:[{getInitialState:function(){return this.cursor=t,this.__updateHandler=function(){this.setState({cursor:this.cursor.get()})}.bind(this),{cursor:this.cursor.get()}},componentDidMount:function(){this.cursor.on("update",this.__updateHandler)},componentWillUnmount:function(){this.cursor.off("update",this.__updateHandler)}}].concat(t.tree.options.mixins)}}}},{"./combination.js":5,"./type.js":10}],10:[function(t,r){function e(t,r){return r.some(function(r){return n[r](t)})}var n={};n.Array=function(t){return Array.isArray(t)},n.Object=function(t){return!Array.isArray(t)&&"object"==typeof t&&null!==t},n.String=function(t){return"string"==typeof t},n.Number=function(t){return"number"==typeof t},n.Function=function(t){return"function"==typeof t},n.Primitive=function(t){return"string"==typeof t||"number"==typeof t||"boolean"==typeof t},n.Date=function(t){return t instanceof Date},n.NonScalar=function(t){return n.Object(t)||n.Array(t)},n.Path=function(t){var r=["String","Number","Function","Object"];return n.Array(t)?t.every(function(t){return e(t,r)}):e(t,r)},n.MixinCursor=function(t){return e(t,["String","Number","Array","Function","Cursor"])},n.MixinCursors=function(t){return e(t,["Object","Array","Function"])},n.ComplexPath=function(t){return t.some(function(t){return e(t,["Object","Function"])})},r.exports=n},{}],11:[function(t,r){function e(t,r){var e=new Error("baobab.update: "+r+" at path /"+t.slice(1).join("/"));return e.path=t,e}var n=t("./helpers.js"),i=t("./type.js");r.exports=function(t,r,o){if(o=o||{},!i.Object(t)&&!i.Array(t))throw Error("baobab.update: invalid target.");var s={};t={root:n.shallowClone(t)};var a=function(t,r,o,h){o=o||["root"];var u,c,l,f=o.join("λ"),p=o[o.length-1],d=Object.keys(r).some(function(t){return!!~["$unset","$set","$apply","$merge","$push","$unshift"].indexOf(t)});if(d){s[f]=t[p];for(c in r){if("$unset"===c){var b=o[o.length-2];i.Array(t)?h[b]=t.slice(0,+p).concat(t.slice(+p+1)):(h[b]=n.shallowClone(t),delete h[b][p]);break}if("$set"===c){l=r.$set,t[p]=l;break}if("$apply"===c){if(u=r.$apply,"function"!=typeof u)throw e(o,"using command $apply with a non function");t[p]=u.call(null,t[p]);break}if("$merge"===c){if(l=r.$merge,!i.Object(t[p])||!i.Object(l))throw e(o,"using command $merge with a non object");t[p]=n.shallowMerge(t[p],l);break}if("$push"===c){if(l=r.$push,!i.Array(t[p]))throw e(o,"using command $push to a non array");t[p]=t[p].concat(l)}if("$unshift"===c){if(l=r.$unshift,!i.Array(t[p]))throw e(o,"using command $unshift to a non array");t[p]=[].concat(l).concat(t[p])}}}else for(c in r)t[p][c]="undefined"==typeof t[p][c]?{}:n.shallowClone(t[p][c]),a(t[p],r[c],o.concat(c),t)};return a(t,r),{data:t.root,log:Object.keys(s).map(function(t){return{path:t.split("λ").slice(1),oldValue:s[t]}})}}},{"./helpers.js":7,"./type.js":10}]},{},[2])(2)}); \ No newline at end of file diff --git a/src/baobab.js b/src/baobab.js index f7cbdad..47953fd 100644 --- a/src/baobab.js +++ b/src/baobab.js @@ -85,7 +85,7 @@ Baobab.prototype.select = function(path) { var solvedPath; if (complex) - solvedPath = helpers.solvePath(this.data, path); + solvedPath = helpers.solvePath(this.data, path, this); // Registering a new cursor or giving the already existing one for path var hash = path.map(function(step) { diff --git a/src/cursor.js b/src/cursor.js index 0ea6857..0a66689 100644 --- a/src/cursor.js +++ b/src/cursor.js @@ -43,7 +43,7 @@ function Cursor(tree, path, solvedPath, hash) { // Solving path if needed if (self.complexPath) - self.solvedPath = helpers.solvePath(self.tree.data, self.path); + self.solvedPath = helpers.solvePath(self.tree.data, self.path, self.tree); // If selector listens at tree, we fire if (!self.path.length) @@ -225,7 +225,7 @@ function pathPolymorphism(method, allowedType, key, val) { key = key || []; var path = [].concat(key), - solvedPath = helpers.solvePath(this.get(), path); + solvedPath = helpers.solvePath(this.get(), path, this.tree); if (!solvedPath) throw Error('baobab.Cursor.' + method + ': could not solve dynamic path.'); @@ -285,7 +285,7 @@ Cursor.prototype.update = function(key, spec) { // Solving path var path = [].concat(key), - solvedPath = helpers.solvePath(this.get(), path); + solvedPath = helpers.solvePath(this.get(), path, this.tree); if (!solvedPath) throw Error('baobab.Cursor.update: could not solve dynamic path.'); @@ -328,8 +328,12 @@ Cursor.prototype.redo = function() { // TODO... }; +Cursor.prototype.isRecording = function() { + return !!this.archive; +}; + Cursor.prototype.hasHistory = function() { - return this.archive && this.archive.records.length; + return !!(this.archive && this.archive.records.length); }; Cursor.prototype.getHistory = function() { diff --git a/src/helpers.js b/src/helpers.js index 06cd33f..03386c7 100644 --- a/src/helpers.js +++ b/src/helpers.js @@ -178,7 +178,7 @@ function getIn(object, path, tree) { c = first(c, path[i]); } else if (typeof path[i] === 'object') { - if ('$cursor' in path[i]) { + if (tree && '$cursor' in path[i]) { if (!type.Path(path[i].$cursor)) throw Error('baobab.getIn: $cursor path must be an array.'); @@ -223,20 +223,24 @@ function solvePath(object, path, tree) { c = c[idx]; } else if (typeof path[i] === 'object') { - if ('$cursor' in path[i]) { + if (tree && '$cursor' in path[i]) { if (!type.Path(path[i].$cursor)) throw Error('baobab.getIn: $cursor path must be an array.'); p = tree.get(path[i].$cursor); + solvedPath.push(p); c = c[p]; } - if (!type.Array(c)) + else if (!type.Array(c)) { return; + } - idx = indexByComparison(c, path[i]); - solvedPath.push(idx); - c = c[idx]; + else { + idx = indexByComparison(c, path[i]); + solvedPath.push(idx); + c = c[idx]; + } } else { solvedPath.push(path[i]); diff --git a/src/type.js b/src/type.js index b227ba5..adca9a3 100644 --- a/src/type.js +++ b/src/type.js @@ -78,7 +78,9 @@ type.MixinCursors = function (value) { }; type.ComplexPath = function (value) { - return anyOf(value, ['Object', 'Function']); + return value.some(function(v) { + return anyOf(v, ['Object', 'Function']); + }); }; module.exports = type; From 1d3190760e840b01d922665e92b6b5119e464bff Mon Sep 17 00:00:00 2001 From: Yomguithereal Date: Thu, 9 Apr 2015 16:27:03 +0200 Subject: [PATCH 29/73] Linter fixes --- src/helpers.js | 2 +- src/type.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/helpers.js b/src/helpers.js index 03386c7..eabe9e2 100644 --- a/src/helpers.js +++ b/src/helpers.js @@ -281,7 +281,7 @@ function inherits(ctor, superCtor) { // Archive function archive(size) { this.size = size; - this.records = [] + this.records = []; // Adding a record this.add = function(record) { diff --git a/src/type.js b/src/type.js index adca9a3..a65f88e 100644 --- a/src/type.js +++ b/src/type.js @@ -15,7 +15,7 @@ var type = {}; function anyOf(value, allowed) { return allowed.some(function(t) { return type[t](value); - }) + }); } /** From 24dd6c73510de4ce34abf34a7f8ec17cfa95932d Mon Sep 17 00:00:00 2001 From: Yomguithereal Date: Thu, 9 Apr 2015 17:06:53 +0200 Subject: [PATCH 30/73] Reverting commit adding logs to updates --- build/baobab.min.js | 2 +- src/cursor.js | 2 +- src/update.js | 7 ++----- test/suites/baobab.js | 2 +- 4 files changed, 5 insertions(+), 8 deletions(-) diff --git a/build/baobab.min.js b/build/baobab.min.js index 1a29107..18f87d8 100644 --- a/build/baobab.min.js +++ b/build/baobab.min.js @@ -1,2 +1,2 @@ /* baobab.js - Version: 1.0.0-rc1 - Author: Yomguithereal (Guillaume Plique) */ -!function(t){if("object"==typeof exports&&"undefined"!=typeof module)module.exports=t();else if("function"==typeof define&&define.amd)define([],t);else{var r;r="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:this,r.Baobab=t()}}(function(){var t;return function r(t,e,n){function i(s,a){if(!e[s]){if(!t[s]){var h="function"==typeof require&&require;if(!a&&h)return h(s,!0);if(o)return o(s,!0);var u=new Error("Cannot find module '"+s+"'");throw u.code="MODULE_NOT_FOUND",u}var c=e[s]={exports:{}};t[s][0].call(c.exports,function(r){var e=t[s][1][r];return i(e?e:r)},c,c.exports,r,t,e,n)}return e[s].exports}for(var o="function"==typeof require&&require,s=0;sr;r++)n.push(t[r].handler);return n}var i={once:"boolean",scope:"object"},o=function(){this._enabled=!0,this._children=[],this._handlers={},this._handlersAll=[]};o.prototype.on=function(t,r,e){var n,s,a,h,u,c;if("function"==typeof r){for(u="string"==typeof t?[t]:t,n=0,s=u.length;n!==s;n+=1)if(h=u[n]){this._handlers[h]||(this._handlers[h]=[]),c={handler:r};for(a in e||{}){if(!i[a])throw new Error('The option "'+a+'" is not recognized by Emmett.');c[a]=e[a]}this._handlers[h].push(c)}}else if(t&&"object"==typeof t&&!Array.isArray(t))for(h in t)o.prototype.on.call(this,h,t[h],r);else{if("function"!=typeof t)throw new Error("Wrong arguments.");c={handler:t};for(a in e||{}){if(!i[a])throw new Error('The option "'+a+'" is not recognized by Emmett.');c[a]=e[a]}this._handlersAll.push(c)}return this},o.prototype.once=function(t,r,e){if("function"==typeof r)e=e||{},e.once=!0,this.on(t,r,e);else{if((!t||"object"!=typeof t||Array.isArray(t))&&"function"!=typeof t)throw new Error("Wrong arguments.");r=r||{},r.once=!0,this.on(t,r)}return this},o.prototype.off=function(t,r){var e,n,i,o,s,a,h,u="string"==typeof t?[t]:t;if(1===arguments.length&&"function"==typeof u){r=arguments[0];for(s in this._handlers){for(a=[],e=0,n=this._handlers[s].length;e!==n;e+=1)this._handlers[s][e].handler!==r&&a.push(this._handlers[s][e]);this._handlers[s]=a}for(a=[],e=0,n=this._handlersAll.length;e!==n;e+=1)this._handlersAll[e].handler!==r&&a.push(this._handlersAll[e]);this._handlersAll=a}else if(2===arguments.length)for(e=0,n=u.length;e!==n;e+=1){if(h=u[e],this._handlers[h]){for(a=[],i=0,o=this._handlers[h].length;i!==o;i+=1)this._handlers[h][i].handler!==r&&a.push(this._handlers[h][i]);this._handlers[h]=a}this._handlers[h]&&0===this._handlers[h].length&&delete this._handlers[h]}return this},o.prototype.unbindAll=function(){var t;this._handlersAll=[];for(t in this._handlers)delete this._handlers[t];return this},o.prototype.emit=function(t,r){var e,n,i,o,s,a,h,u,c,l,f="string"==typeof t?[t]:t;if(!this._enabled)return this;for(r=void 0===r?{}:r,e=0,n=f.length;e!==n;e+=1)if(l=f[e],c=(this._handlers[l]||[]).concat(this._handlersAll),c.length){for(h={type:l,data:r||{},target:this},a=[],i=0,o=c.length;i!==o;i+=1)(this._handlers[l]&&this._handlers[l].indexOf(c[i])>=0||this._handlersAll.indexOf(c[i])>=0)&&(c[i].handler.call("scope"in c[i]?c[i].scope:this,h),c[i].once&&a.push(c[i]));for(s=0;se;e++)if(t._children[e]===r){t._children.splice(e,1);break}}),this._children.push(r),r},o.prototype.listeners=function(t){var e,n,i,o=[];if(t)for(o=r(this._handlers[t]),n=0,i=this._children.length;i>n;n++)o=o.concat(this._children[n].listeners(t));else{o=r(this._handlersAll);for(e in this._handlers)o=o.concat(r(this._handlers[e]));for(n=0,i=this._children.length;i>n;n++)o=o.concat(this._children[n].listeners())}return o},o.prototype.kill=function(){if(this.emit("emmett:kill"),this.unbindAll(),this._handlers=null,this._handlersAll=null,this._enabled=!1,this._children)for(var t=0,r=this._children.length;r>t;t++)this._children[t].kill();this._children=null},o.prototype.disable=function(){return this._enabled=!1,this},o.prototype.enable=function(){return this._enabled=!0,this},o.version="2.1.2","undefined"!=typeof n?("undefined"!=typeof e&&e.exports&&(n=e.exports=o),n.Emitter=o):"function"==typeof t&&t.amd?t("emmett",[],function(){return o}):this.Emitter=o}).call(this)},{}],4:[function(t,r){function e(t){return t+"$"+(new Date).getTime()+(""+Math.random()).replace("0.","")}function n(t,r){function e(t){this[t]=function(){var r=this.root[t].apply(this.root,arguments);return r instanceof i?this:r}}if(arguments.length<1&&(t={}),!(this instanceof n))return new n(t,r);if(!l.Object(t)&&!l.Array(t))throw Error("Baobab: invalid data.");o.call(this),this.options=s.shallowMerge(c,r),this._transaction={},this._future=void 0,this._cursors={},this.data=s.deepClone(t),this.root=this.select([]),["get","set","unset","update"].forEach(e.bind(this)),this.mixin=u.baobab(this)}var i=t("./cursor.js"),o=t("emmett"),s=t("./helpers.js"),a=t("./update.js"),h=t("./merge.js"),u=t("./mixins.js"),c=t("../defaults.js"),l=t("./type.js");s.inherits(n,o),n.prototype.select=function(t){if(!t)throw Error("Baobab.select: invalid path.");if(arguments.length>1&&(t=s.arrayOf(arguments)),!l.Path(t))throw Error("Baobab.select: invalid path.");t=[].concat(t);var r,n=l.ComplexPath(t);n&&(r=s.solvePath(this.data,t,this));var o=t.map(function(t){return l.Function(t)?e("fn"):l.Object(t)?e("ob"):t}).join("λ");if(this._cursors[o])return this._cursors[o];var a=new i(this,t,r,o);return this._cursors[o]=a,a},n.prototype.stack=function(t){var r=this;if(!l.Object(t))throw Error("Baobab.update: wrong specification.");return this._transaction=h(t,this._transaction),this.options.autoCommit?this.options.asynchronous?(this._future||(this._future=setTimeout(r.commit.bind(r,null),0)),this):this.commit():this},n.prototype.commit=function(){var t=a(this.data,this._transaction,this.options);return this.data=t.data,this._transaction={},this._future&&(this._future=clearTimeout(this._future)),this.emit("update",{log:t.log}),this},n.prototype.release=function(){delete this.data,delete this._transaction;for(var t in this._cursors)this._cursors[t].release();delete this._cursors,this.kill()},n.prototype.toJSON=function(){return this.get()},r.exports=n},{"../defaults.js":1,"./cursor.js":6,"./helpers.js":7,"./merge.js":8,"./mixins.js":9,"./type.js":10,"./update.js":11,emmett:3}],5:[function(t,r){function e(t,r){r.on("update",t.cursorListener),t.tree.off("update",t.treeListener),t.tree.on("update",t.treeListener)}function n(t){var r=this;if(arguments.length<2)throw Error("baobab.Combination: not enough arguments.");var n=arguments[1],i=s.arrayOf(arguments).slice(2);if(n instanceof Array&&(i=n.slice(1),n=n[0]),!a.Cursor(n))throw Error("baobab.Combination: argument should be a cursor.");if("or"!==t&&"and"!==t)throw Error("baobab.Combination: invalid operator.");o.call(this),this.cursors=[n],this.operators=[],this.tree=n.tree,this.updates=new Array(this.cursors.length),this.cursorListener=function(){r.updates[r.cursors.indexOf(this)]=!0},this.treeListener=function(){var t,e,n=r.updates[0];for(t=1,e=r.cursors.length;e>t;t++)n="or"===r.operators[t-1]?n||r.updates[t]:n&&r.updates[t];n&&r.emit("update"),r.updates=new Array(r.cursors.length)},this.bound=!1;var h=(this.on,this.once,function(){r.bound||(r.bound=!0,r.cursors.forEach(function(t){e(r,t)}))});this.on=s.before(h,this.on.bind(this)),this.once=s.before(h,this.once.bind(this)),i.forEach(function(r){this[t](r)},this)}function i(t){n.prototype[t]=function(r){if(!a.Cursor(r))throw this.release(),Error("baobab.Combination."+t+": argument should be a cursor.");if(~this.cursors.indexOf(r))throw this.release(),Error("baobab.Combination."+t+": cursor already in combination.");return this.cursors.push(r),this.operators.push(t),this.updates.length++,this.bound&&e(this,r),this}}var o=t("emmett"),s=t("./helpers.js"),a=t("./type.js");s.inherits(n,o),i("or"),i("and"),n.prototype.release=function(){this.cursors.forEach(function(t){t.off("update",this.cursorListener)},this),this.tree.off("update",this.treeListener),this.cursors=null,this.operators=null,this.tree=null,this.updates=null,this.kill()},r.exports=n},{"./helpers.js":7,"./type.js":10,emmett:3}],6:[function(t,r){function e(t,r,e,n){var i=this;o.call(this),r=r||[],this.tree=t,this.path=r,this.hash=n,this.archive=null,this.complexPath=!!e,this.solvedPath=this.complexPath?e:this.path,this.relevant=void 0!==this.get(),this.updateHandler=function(t){var r,e,n,o,s,a,u=t.data.log,c=!1;if(i.complexPath&&(i.solvedPath=h.solvePath(i.tree.data,i.path,i.tree)),!i.path.length)return i.emit("update");t:for(s=0,n=u.length;n>s;s++)for(r=u[s].path,a=0,o=r.length;o>a&&(e=r[a],e===""+i.solvedPath[a]);a++)if(a+1===o||a+1===i.solvedPath.length){c=!0;break t}var l=void 0!==i.get();i.relevant?l&&c?i.emit("update"):l||(i.emit("irrelevant"),i.relevant=!1):l&&c&&(i.emit("relevant"),i.emit("update"),i.relevant=!0)},this.mixin=a.cursor(this);var s=!1,u=function(){s||(s=!0,i.tree.on("update",i.updateHandler))};this.on=h.before(u,this.on.bind(this)),this.once=h.before(u,this.once.bind(this))}function n(t,r,e,n){arguments.length<4&&(n=e,e=[]),e=e||[];var i=[].concat(e),o=h.solvePath(this.get(),i,this.tree);if(!o)throw Error("baobab.Cursor."+t+": could not solve dynamic path.");if(r){var s=this.get(o);if(!u[r](s))throw Error("baobab.Cursor."+t+": invalid target.")}var a={};a["$"+t]=n;var c=h.pathObject(o,a);return c}function i(t,r){e.prototype[t]=function(){var e=n.bind(this,t,r).apply(this,arguments);return this.update(e)}}var o=t("emmett"),s=t("./combination.js"),a=t("./mixins.js"),h=t("./helpers.js"),u=t("./type.js");h.inherits(e,o),e.prototype.isRoot=function(){return!this.path.length},e.prototype.isLeaf=function(){return u.Primitive(this.get())},e.prototype.isBranch=function(){return!this.isLeaf()&&!this.isRoot()},e.prototype.root=function(){return this.tree.root()},e.prototype.select=function(t){if(arguments.length>1&&(t=h.arrayOf(arguments)),!u.Path(t))throw Error("baobab.Cursor.select: invalid path.");return this.tree.select(this.path.concat(t))},e.prototype.up=function(){return this.solvedPath&&this.solvedPath.length?this.tree.select(this.path.slice(0,-1)):null},e.prototype.left=function(){var t=+this.solvedPath[this.solvedPath.length-1];if(isNaN(t))throw Error("baobab.Cursor.left: cannot go left on a non-list type.");return t?this.tree.select(this.solvedPath.slice(0,-1).concat(t-1)):null},e.prototype.leftmost=function(){var t=+this.solvedPath[this.solvedPath.length-1];if(isNaN(t))throw Error("baobab.Cursor.leftmost: cannot go left on a non-list type.");return this.tree.select(this.solvedPath.slice(0,-1).concat(0))},e.prototype.right=function(){var t=+this.solvedPath[this.solvedPath.length-1];if(isNaN(t))throw Error("baobab.Cursor.right: cannot go right on a non-list type.");return t+1===this.up().get().length?null:this.tree.select(this.solvedPath.slice(0,-1).concat(t+1))},e.prototype.rightmost=function(){var t=+this.solvedPath[this.solvedPath.length-1];if(isNaN(t))throw Error("baobab.Cursor.right: cannot go right on a non-list type.");var r=this.up().get();return this.tree.select(this.solvedPath.slice(0,-1).concat(r.length-1))},e.prototype.down=function(){+this.solvedPath[this.solvedPath.length-1];return this.get()instanceof Array?this.tree.select(this.solvedPath.concat(0)):null},e.prototype.get=function(t){arguments.length>1&&(t=h.arrayOf(arguments));var r=this.solvedPath.concat((u.String(t)||u.Number(t)?[t]:t)||[]);return h.getIn(this.tree.data,r,this.tree)},i("set"),i("apply"),i("chain"),i("push","Array"),i("unshift","Array"),e.prototype.merge=function(t){if(!u.Object(t))throw Error("baobab.Cursor.merge: trying to merge a non-object.");var r=n.bind(this,"merge","Object").apply(this,arguments);return this.update(r)},e.prototype.unset=function(t){if(void 0===t&&this.isRoot())throw Error("baobab.Cursor.unset: cannot remove root node.");var r=n.bind(this,"unset",null).apply(this,[t,!0]);return this.update(r)},e.prototype.update=function(t,r){if(arguments.length<2)return this.tree.stack(h.pathObject(this.solvedPath,t)),this;var e=[].concat(t),n=h.solvePath(this.get(),e,this.tree);if(!n)throw Error("baobab.Cursor.update: could not solve dynamic path.");return this.tree.stack(h.pathObject(this.solvedPath.concat(n),r)),this},e.prototype.or=function(t){return new s("or",this,t)},e.prototype.and=function(t){return new s("and",this,t)},e.prototype.startRecording=function(t){return this.archive?this:(this.archive=h.archive(t),this)},e.prototype.stopRecording=function(){return this.archive=null,this},e.prototype.undo=function(){},e.prototype.redo=function(){},e.prototype.isRecording=function(){return!!this.archive},e.prototype.hasHistory=function(){return!(!this.archive||!this.archive.records.length)},e.prototype.getHistory=function(){return this.archive.records},e.prototype.release=function(){this.tree.off("update",this.updateHandler),this.hash&&delete this.tree._cursors[this.hash],delete this.tree,delete this.path,delete this.solvedPath,this.kill()},e.prototype.toJSON=function(){return this.get()},u.Cursor=function(t){return t instanceof e},r.exports=e},{"./combination.js":5,"./helpers.js":7,"./mixins.js":9,"./type.js":10,emmett:3}],7:[function(t,r){(function(e){function n(t){return Array.prototype.slice.call(t)}function i(t,r){return function(){t(),r.apply(null,arguments)}}function o(t,r){var e,n={};for(e in t)n[e]=t[e];for(e in r)n[e]=r[e];return n}function s(t){var r=t.source,e="";return t.global&&(e+="g"),t.multiline&&(e+="m"),t.ignoreCase&&(e+="i"),t.sticky&&(e+="y"),t.unicode&&(e+="u"),new RegExp(r,e)}function a(t,r){if(!r||"object"!=typeof r||r instanceof Error||"ArrayBuffer"in e&&r instanceof ArrayBuffer)return r;if(_.Array(r)){if(t){var n,i,o=[];for(n=0,i=r.length;i>n;n++)o.push(w(r[n]));return o}return r.slice(0)}if(_.Date(r))return new Date(r.getTime());if(r instanceof RegExp)return s(r);if(_.Object(r)){var a,h={};r.constructor&&r.constructor!==Object&&(h=Object.create(r.constructor.prototype));for(a in r)r.hasOwnProperty(a)&&(h[a]=t?w(r[a]):r[a]);return h}return r}function h(t,r){return function(e){return r(t(e))}}function u(t,r){var e,n;for(e=0,n=t.length;n>e;e++)if(r(t[e]))return t[e]}function c(t,r){var e,n;for(e=0,n=t.length;n>e;e++)if(r(t[e]))return e;return-1}function l(t,r){var e,n=!0;if(!t)return!1;for(e in r)if(_.Object(r[e]))n=n&&l(t[e],r[e]);else if(_.Array(r[e]))n=n&&!!~r[e].indexOf(t[e]);else if(t[e]!==r[e])return!1;return n}function f(t,r){return u(t,function(t){return l(t,r)})}function d(t,r){return c(t,function(t){return l(t,r)})}function b(t,r,e){r=r||[];var n,i,o,s=t;for(i=0,o=r.length;o>i;i++){if(!s)return;if("function"==typeof r[i]){if(!_.Array(s))return;s=u(s,r[i])}else if("object"==typeof r[i])if(e&&"$cursor"in r[i]){if(!_.Path(r[i].$cursor))throw Error("baobab.getIn: $cursor path must be an array.");n=e.get(r[i].$cursor),s=s[n]}else{if(!_.Array(s))return;s=f(s,r[i])}else s=s[r[i]]}return s}function y(t,r,e){var n,i,o,s=[],a=t;for(i=0,o=r.length;o>i;i++){if(!a)return null;if("function"==typeof r[i]){if(!_.Array(a))return;n=c(a,r[i]),s.push(n),a=a[n]}else if("object"==typeof r[i])if(e&&"$cursor"in r[i]){if(!_.Path(r[i].$cursor))throw Error("baobab.getIn: $cursor path must be an array.");p=e.get(r[i].$cursor),s.push(p),a=a[p]}else{if(!_.Array(a))return;n=d(a,r[i]),s.push(n),a=a[n]}else s.push(r[i]),a=a[r[i]]||{}}return s}function g(t,r){var e,n=t.length,i={},o=i;for(n||(i=r),e=0;n>e;e++)o[t[e]]=e+1===n?r:{},o=o[t[e]];return i}function m(t,r){t.super_=r;var e=function(){};e.prototype=r.prototype,t.prototype=new e,t.prototype.constructor=t}function v(t){this.size=t,this.records=[],this.add=function(r){for(this.records.unshift(r);this.records.length>t;)this.records.pop();return this},this.get=function(){return this.records}}var _=t("./type.js"),j=a.bind(null,!1),w=a.bind(null,!0);r.exports={archive:v,arrayOf:n,before:i,deepClone:w,shallowClone:j,shallowMerge:o,compose:h,getIn:b,inherits:m,pathObject:g,solvePath:y}}).call(this,"undefined"!=typeof global?global:"undefined"!=typeof self?self:"undefined"!=typeof window?window:{})},{"./type.js":10}],8:[function(t,r){function e(t,r,e){s.forEach(function(r){e!==r&&delete t[r]}),t[e]=r[e]}function n(t,r){var a,h=i.shallowClone(r||{});s.forEach(function(r){t[r]&&e(h,t,r)}),t.$chain&&(s.slice(0,-1).forEach(function(t){delete h[t]}),h.$apply=h.$apply?i.compose(h.$apply,t.$chain):t.$chain),t.$push&&h.$push?h.$push=o.Array(h.$push)?h.$push.concat(t.$push):[h.$push].concat(t.$push):t.$push&&(h.$push=t.$push),t.$unshift&&h.$unshift?h.$unshift=o.Array(t.$unshift)?t.$unshift.concat(h.$unshift):[t.$unshift].concat(h.$unshift):t.$unshift&&(h.$unshift=t.$unshift);for(a in t)o.Object(t[a])?h[a]=n(t[a],h[a]):"$"!==a[0]&&(h[a]=t[a]);return h}var i=t("./helpers.js"),o=t("./type.js"),s=["$unset","$set","$merge","$apply"];r.exports=n},{"./helpers.js":7,"./type.js":10}],9:[function(t,r){var e=t("./combination.js"),n=t("./type.js");r.exports={baobab:function(t){return{mixins:[{getInitialState:function(){if(this.tree=t,!this.cursor&&!this.cursors)return{};if(this.cursor&&this.cursors)throw Error("baobab.mixin: you cannot have both `component.cursor` and `component.cursors`. Please make up your mind.");if(this.__type=null,this.__updateHandler=function(){this.setState(this.__getCursorData())}.bind(this),this.cursor){if(!n.MixinCursor(this.cursor))throw Error("baobab.mixin.cursor: invalid data (cursor, string, array or function).");n.Function(this.cursor)&&(this.cursor=this.cursor()),n.Cursor(this.cursor)||(this.cursor=t.select(this.cursor)),this.__getCursorData=function(){return{cursor:this.cursor.get()}}.bind(this),this.__type="single"}else if(this.cursors){if(!n.MixinCursors(this.cursors))throw Error("baobab.mixin.cursor: invalid data (object, array or function).");if(n.Function(this.cursors)&&(this.cursors=this.cursors()),n.Array(this.cursors))this.cursors=this.cursors.map(function(r){return n.Cursor(r)?r:t.select(r)}),this.__getCursorData=function(){return{cursors:this.cursors.map(function(t){return t.get()})}}.bind(this),this.__type="array";else{for(var r in this.cursors)n.Cursor(this.cursors[r])||(this.cursors[r]=t.select(this.cursors[r]));this.__getCursorData=function(){var t={};for(r in this.cursors)t[r]=this.cursors[r].get();return{cursors:t}}.bind(this),this.__type="object"}}return this.__getCursorData()},componentDidMount:function(){"single"===this.__type?(this.__combination=new e("or",[this.cursor]),this.__combination.on("update",this.__updateHandler)):"array"===this.__type?(this.__combination=new e("or",this.cursors),this.__combination.on("update",this.__updateHandler)):"object"===this.__type&&(this.__combination=new e("or",Object.keys(this.cursors).map(function(t){return this.cursors[t]},this)),this.__combination.on("update",this.__updateHandler))},componentWillUnmount:function(){this.__combination&&this.__combination.release()}}].concat(t.options.mixins)}},cursor:function(t){return{mixins:[{getInitialState:function(){return this.cursor=t,this.__updateHandler=function(){this.setState({cursor:this.cursor.get()})}.bind(this),{cursor:this.cursor.get()}},componentDidMount:function(){this.cursor.on("update",this.__updateHandler)},componentWillUnmount:function(){this.cursor.off("update",this.__updateHandler)}}].concat(t.tree.options.mixins)}}}},{"./combination.js":5,"./type.js":10}],10:[function(t,r){function e(t,r){return r.some(function(r){return n[r](t)})}var n={};n.Array=function(t){return Array.isArray(t)},n.Object=function(t){return!Array.isArray(t)&&"object"==typeof t&&null!==t},n.String=function(t){return"string"==typeof t},n.Number=function(t){return"number"==typeof t},n.Function=function(t){return"function"==typeof t},n.Primitive=function(t){return"string"==typeof t||"number"==typeof t||"boolean"==typeof t},n.Date=function(t){return t instanceof Date},n.NonScalar=function(t){return n.Object(t)||n.Array(t)},n.Path=function(t){var r=["String","Number","Function","Object"];return n.Array(t)?t.every(function(t){return e(t,r)}):e(t,r)},n.MixinCursor=function(t){return e(t,["String","Number","Array","Function","Cursor"])},n.MixinCursors=function(t){return e(t,["Object","Array","Function"])},n.ComplexPath=function(t){return t.some(function(t){return e(t,["Object","Function"])})},r.exports=n},{}],11:[function(t,r){function e(t,r){var e=new Error("baobab.update: "+r+" at path /"+t.slice(1).join("/"));return e.path=t,e}var n=t("./helpers.js"),i=t("./type.js");r.exports=function(t,r,o){if(o=o||{},!i.Object(t)&&!i.Array(t))throw Error("baobab.update: invalid target.");var s={};t={root:n.shallowClone(t)};var a=function(t,r,o,h){o=o||["root"];var u,c,l,f=o.join("λ"),p=o[o.length-1],d=Object.keys(r).some(function(t){return!!~["$unset","$set","$apply","$merge","$push","$unshift"].indexOf(t)});if(d){s[f]=t[p];for(c in r){if("$unset"===c){var b=o[o.length-2];i.Array(t)?h[b]=t.slice(0,+p).concat(t.slice(+p+1)):(h[b]=n.shallowClone(t),delete h[b][p]);break}if("$set"===c){l=r.$set,t[p]=l;break}if("$apply"===c){if(u=r.$apply,"function"!=typeof u)throw e(o,"using command $apply with a non function");t[p]=u.call(null,t[p]);break}if("$merge"===c){if(l=r.$merge,!i.Object(t[p])||!i.Object(l))throw e(o,"using command $merge with a non object");t[p]=n.shallowMerge(t[p],l);break}if("$push"===c){if(l=r.$push,!i.Array(t[p]))throw e(o,"using command $push to a non array");t[p]=t[p].concat(l)}if("$unshift"===c){if(l=r.$unshift,!i.Array(t[p]))throw e(o,"using command $unshift to a non array");t[p]=[].concat(l).concat(t[p])}}}else for(c in r)t[p][c]="undefined"==typeof t[p][c]?{}:n.shallowClone(t[p][c]),a(t[p],r[c],o.concat(c),t)};return a(t,r),{data:t.root,log:Object.keys(s).map(function(t){return{path:t.split("λ").slice(1),oldValue:s[t]}})}}},{"./helpers.js":7,"./type.js":10}]},{},[2])(2)}); \ No newline at end of file +!function(t){if("object"==typeof exports&&"undefined"!=typeof module)module.exports=t();else if("function"==typeof define&&define.amd)define([],t);else{var r;r="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:this,r.Baobab=t()}}(function(){var t;return function r(t,e,n){function i(s,a){if(!e[s]){if(!t[s]){var h="function"==typeof require&&require;if(!a&&h)return h(s,!0);if(o)return o(s,!0);var u=new Error("Cannot find module '"+s+"'");throw u.code="MODULE_NOT_FOUND",u}var c=e[s]={exports:{}};t[s][0].call(c.exports,function(r){var e=t[s][1][r];return i(e?e:r)},c,c.exports,r,t,e,n)}return e[s].exports}for(var o="function"==typeof require&&require,s=0;sr;r++)n.push(t[r].handler);return n}var i={once:"boolean",scope:"object"},o=function(){this._enabled=!0,this._children=[],this._handlers={},this._handlersAll=[]};o.prototype.on=function(t,r,e){var n,s,a,h,u,c;if("function"==typeof r){for(u="string"==typeof t?[t]:t,n=0,s=u.length;n!==s;n+=1)if(h=u[n]){this._handlers[h]||(this._handlers[h]=[]),c={handler:r};for(a in e||{}){if(!i[a])throw new Error('The option "'+a+'" is not recognized by Emmett.');c[a]=e[a]}this._handlers[h].push(c)}}else if(t&&"object"==typeof t&&!Array.isArray(t))for(h in t)o.prototype.on.call(this,h,t[h],r);else{if("function"!=typeof t)throw new Error("Wrong arguments.");c={handler:t};for(a in e||{}){if(!i[a])throw new Error('The option "'+a+'" is not recognized by Emmett.');c[a]=e[a]}this._handlersAll.push(c)}return this},o.prototype.once=function(t,r,e){if("function"==typeof r)e=e||{},e.once=!0,this.on(t,r,e);else{if((!t||"object"!=typeof t||Array.isArray(t))&&"function"!=typeof t)throw new Error("Wrong arguments.");r=r||{},r.once=!0,this.on(t,r)}return this},o.prototype.off=function(t,r){var e,n,i,o,s,a,h,u="string"==typeof t?[t]:t;if(1===arguments.length&&"function"==typeof u){r=arguments[0];for(s in this._handlers){for(a=[],e=0,n=this._handlers[s].length;e!==n;e+=1)this._handlers[s][e].handler!==r&&a.push(this._handlers[s][e]);this._handlers[s]=a}for(a=[],e=0,n=this._handlersAll.length;e!==n;e+=1)this._handlersAll[e].handler!==r&&a.push(this._handlersAll[e]);this._handlersAll=a}else if(2===arguments.length)for(e=0,n=u.length;e!==n;e+=1){if(h=u[e],this._handlers[h]){for(a=[],i=0,o=this._handlers[h].length;i!==o;i+=1)this._handlers[h][i].handler!==r&&a.push(this._handlers[h][i]);this._handlers[h]=a}this._handlers[h]&&0===this._handlers[h].length&&delete this._handlers[h]}return this},o.prototype.unbindAll=function(){var t;this._handlersAll=[];for(t in this._handlers)delete this._handlers[t];return this},o.prototype.emit=function(t,r){var e,n,i,o,s,a,h,u,c,l,f="string"==typeof t?[t]:t;if(!this._enabled)return this;for(r=void 0===r?{}:r,e=0,n=f.length;e!==n;e+=1)if(l=f[e],c=(this._handlers[l]||[]).concat(this._handlersAll),c.length){for(h={type:l,data:r||{},target:this},a=[],i=0,o=c.length;i!==o;i+=1)(this._handlers[l]&&this._handlers[l].indexOf(c[i])>=0||this._handlersAll.indexOf(c[i])>=0)&&(c[i].handler.call("scope"in c[i]?c[i].scope:this,h),c[i].once&&a.push(c[i]));for(s=0;se;e++)if(t._children[e]===r){t._children.splice(e,1);break}}),this._children.push(r),r},o.prototype.listeners=function(t){var e,n,i,o=[];if(t)for(o=r(this._handlers[t]),n=0,i=this._children.length;i>n;n++)o=o.concat(this._children[n].listeners(t));else{o=r(this._handlersAll);for(e in this._handlers)o=o.concat(r(this._handlers[e]));for(n=0,i=this._children.length;i>n;n++)o=o.concat(this._children[n].listeners())}return o},o.prototype.kill=function(){if(this.emit("emmett:kill"),this.unbindAll(),this._handlers=null,this._handlersAll=null,this._enabled=!1,this._children)for(var t=0,r=this._children.length;r>t;t++)this._children[t].kill();this._children=null},o.prototype.disable=function(){return this._enabled=!1,this},o.prototype.enable=function(){return this._enabled=!0,this},o.version="2.1.2","undefined"!=typeof n?("undefined"!=typeof e&&e.exports&&(n=e.exports=o),n.Emitter=o):"function"==typeof t&&t.amd?t("emmett",[],function(){return o}):this.Emitter=o}).call(this)},{}],4:[function(t,r){function e(t){return t+"$"+(new Date).getTime()+(""+Math.random()).replace("0.","")}function n(t,r){function e(t){this[t]=function(){var r=this.root[t].apply(this.root,arguments);return r instanceof i?this:r}}if(arguments.length<1&&(t={}),!(this instanceof n))return new n(t,r);if(!l.Object(t)&&!l.Array(t))throw Error("Baobab: invalid data.");o.call(this),this.options=s.shallowMerge(c,r),this._transaction={},this._future=void 0,this._cursors={},this.data=s.deepClone(t),this.root=this.select([]),["get","set","unset","update"].forEach(e.bind(this)),this.mixin=u.baobab(this)}var i=t("./cursor.js"),o=t("emmett"),s=t("./helpers.js"),a=t("./update.js"),h=t("./merge.js"),u=t("./mixins.js"),c=t("../defaults.js"),l=t("./type.js");s.inherits(n,o),n.prototype.select=function(t){if(!t)throw Error("Baobab.select: invalid path.");if(arguments.length>1&&(t=s.arrayOf(arguments)),!l.Path(t))throw Error("Baobab.select: invalid path.");t=[].concat(t);var r,n=l.ComplexPath(t);n&&(r=s.solvePath(this.data,t,this));var o=t.map(function(t){return l.Function(t)?e("fn"):l.Object(t)?e("ob"):t}).join("λ");if(this._cursors[o])return this._cursors[o];var a=new i(this,t,r,o);return this._cursors[o]=a,a},n.prototype.stack=function(t){var r=this;if(!l.Object(t))throw Error("Baobab.update: wrong specification.");return this._transaction=h(t,this._transaction),this.options.autoCommit?this.options.asynchronous?(this._future||(this._future=setTimeout(r.commit.bind(r,null),0)),this):this.commit():this},n.prototype.commit=function(){var t=a(this.data,this._transaction,this.options);return this.data=t.data,this._transaction={},this._future&&(this._future=clearTimeout(this._future)),this.emit("update",{log:t.log}),this},n.prototype.release=function(){delete this.data,delete this._transaction;for(var t in this._cursors)this._cursors[t].release();delete this._cursors,this.kill()},n.prototype.toJSON=function(){return this.get()},r.exports=n},{"../defaults.js":1,"./cursor.js":6,"./helpers.js":7,"./merge.js":8,"./mixins.js":9,"./type.js":10,"./update.js":11,emmett:3}],5:[function(t,r){function e(t,r){r.on("update",t.cursorListener),t.tree.off("update",t.treeListener),t.tree.on("update",t.treeListener)}function n(t){var r=this;if(arguments.length<2)throw Error("baobab.Combination: not enough arguments.");var n=arguments[1],i=s.arrayOf(arguments).slice(2);if(n instanceof Array&&(i=n.slice(1),n=n[0]),!a.Cursor(n))throw Error("baobab.Combination: argument should be a cursor.");if("or"!==t&&"and"!==t)throw Error("baobab.Combination: invalid operator.");o.call(this),this.cursors=[n],this.operators=[],this.tree=n.tree,this.updates=new Array(this.cursors.length),this.cursorListener=function(){r.updates[r.cursors.indexOf(this)]=!0},this.treeListener=function(){var t,e,n=r.updates[0];for(t=1,e=r.cursors.length;e>t;t++)n="or"===r.operators[t-1]?n||r.updates[t]:n&&r.updates[t];n&&r.emit("update"),r.updates=new Array(r.cursors.length)},this.bound=!1;var h=(this.on,this.once,function(){r.bound||(r.bound=!0,r.cursors.forEach(function(t){e(r,t)}))});this.on=s.before(h,this.on.bind(this)),this.once=s.before(h,this.once.bind(this)),i.forEach(function(r){this[t](r)},this)}function i(t){n.prototype[t]=function(r){if(!a.Cursor(r))throw this.release(),Error("baobab.Combination."+t+": argument should be a cursor.");if(~this.cursors.indexOf(r))throw this.release(),Error("baobab.Combination."+t+": cursor already in combination.");return this.cursors.push(r),this.operators.push(t),this.updates.length++,this.bound&&e(this,r),this}}var o=t("emmett"),s=t("./helpers.js"),a=t("./type.js");s.inherits(n,o),i("or"),i("and"),n.prototype.release=function(){this.cursors.forEach(function(t){t.off("update",this.cursorListener)},this),this.tree.off("update",this.treeListener),this.cursors=null,this.operators=null,this.tree=null,this.updates=null,this.kill()},r.exports=n},{"./helpers.js":7,"./type.js":10,emmett:3}],6:[function(t,r){function e(t,r,e,n){var i=this;o.call(this),r=r||[],this.tree=t,this.path=r,this.hash=n,this.archive=null,this.complexPath=!!e,this.solvedPath=this.complexPath?e:this.path,this.relevant=void 0!==this.get(),this.updateHandler=function(t){var r,e,n,o,s,a,u=t.data.log,c=!1;if(i.complexPath&&(i.solvedPath=h.solvePath(i.tree.data,i.path,i.tree)),!i.path.length)return i.emit("update");t:for(s=0,n=u.length;n>s;s++)for(r=u[s],a=0,o=r.length;o>a&&(e=r[a],e===""+i.solvedPath[a]);a++)if(a+1===o||a+1===i.solvedPath.length){c=!0;break t}var l=void 0!==i.get();i.relevant?l&&c?i.emit("update"):l||(i.emit("irrelevant"),i.relevant=!1):l&&c&&(i.emit("relevant"),i.emit("update"),i.relevant=!0)},this.mixin=a.cursor(this);var s=!1,u=function(){s||(s=!0,i.tree.on("update",i.updateHandler))};this.on=h.before(u,this.on.bind(this)),this.once=h.before(u,this.once.bind(this))}function n(t,r,e,n){arguments.length<4&&(n=e,e=[]),e=e||[];var i=[].concat(e),o=h.solvePath(this.get(),i,this.tree);if(!o)throw Error("baobab.Cursor."+t+": could not solve dynamic path.");if(r){var s=this.get(o);if(!u[r](s))throw Error("baobab.Cursor."+t+": invalid target.")}var a={};a["$"+t]=n;var c=h.pathObject(o,a);return c}function i(t,r){e.prototype[t]=function(){var e=n.bind(this,t,r).apply(this,arguments);return this.update(e)}}var o=t("emmett"),s=t("./combination.js"),a=t("./mixins.js"),h=t("./helpers.js"),u=t("./type.js");h.inherits(e,o),e.prototype.isRoot=function(){return!this.path.length},e.prototype.isLeaf=function(){return u.Primitive(this.get())},e.prototype.isBranch=function(){return!this.isLeaf()&&!this.isRoot()},e.prototype.root=function(){return this.tree.root()},e.prototype.select=function(t){if(arguments.length>1&&(t=h.arrayOf(arguments)),!u.Path(t))throw Error("baobab.Cursor.select: invalid path.");return this.tree.select(this.path.concat(t))},e.prototype.up=function(){return this.solvedPath&&this.solvedPath.length?this.tree.select(this.path.slice(0,-1)):null},e.prototype.left=function(){var t=+this.solvedPath[this.solvedPath.length-1];if(isNaN(t))throw Error("baobab.Cursor.left: cannot go left on a non-list type.");return t?this.tree.select(this.solvedPath.slice(0,-1).concat(t-1)):null},e.prototype.leftmost=function(){var t=+this.solvedPath[this.solvedPath.length-1];if(isNaN(t))throw Error("baobab.Cursor.leftmost: cannot go left on a non-list type.");return this.tree.select(this.solvedPath.slice(0,-1).concat(0))},e.prototype.right=function(){var t=+this.solvedPath[this.solvedPath.length-1];if(isNaN(t))throw Error("baobab.Cursor.right: cannot go right on a non-list type.");return t+1===this.up().get().length?null:this.tree.select(this.solvedPath.slice(0,-1).concat(t+1))},e.prototype.rightmost=function(){var t=+this.solvedPath[this.solvedPath.length-1];if(isNaN(t))throw Error("baobab.Cursor.right: cannot go right on a non-list type.");var r=this.up().get();return this.tree.select(this.solvedPath.slice(0,-1).concat(r.length-1))},e.prototype.down=function(){+this.solvedPath[this.solvedPath.length-1];return this.get()instanceof Array?this.tree.select(this.solvedPath.concat(0)):null},e.prototype.get=function(t){arguments.length>1&&(t=h.arrayOf(arguments));var r=this.solvedPath.concat((u.String(t)||u.Number(t)?[t]:t)||[]);return h.getIn(this.tree.data,r,this.tree)},i("set"),i("apply"),i("chain"),i("push","Array"),i("unshift","Array"),e.prototype.merge=function(t){if(!u.Object(t))throw Error("baobab.Cursor.merge: trying to merge a non-object.");var r=n.bind(this,"merge","Object").apply(this,arguments);return this.update(r)},e.prototype.unset=function(t){if(void 0===t&&this.isRoot())throw Error("baobab.Cursor.unset: cannot remove root node.");var r=n.bind(this,"unset",null).apply(this,[t,!0]);return this.update(r)},e.prototype.update=function(t,r){if(arguments.length<2)return this.tree.stack(h.pathObject(this.solvedPath,t)),this;var e=[].concat(t),n=h.solvePath(this.get(),e,this.tree);if(!n)throw Error("baobab.Cursor.update: could not solve dynamic path.");return this.tree.stack(h.pathObject(this.solvedPath.concat(n),r)),this},e.prototype.or=function(t){return new s("or",this,t)},e.prototype.and=function(t){return new s("and",this,t)},e.prototype.startRecording=function(t){return this.archive?this:(this.archive=h.archive(t),this)},e.prototype.stopRecording=function(){return this.archive=null,this},e.prototype.undo=function(){},e.prototype.redo=function(){},e.prototype.isRecording=function(){return!!this.archive},e.prototype.hasHistory=function(){return!(!this.archive||!this.archive.records.length)},e.prototype.getHistory=function(){return this.archive.records},e.prototype.release=function(){this.tree.off("update",this.updateHandler),this.hash&&delete this.tree._cursors[this.hash],delete this.tree,delete this.path,delete this.solvedPath,this.kill()},e.prototype.toJSON=function(){return this.get()},u.Cursor=function(t){return t instanceof e},r.exports=e},{"./combination.js":5,"./helpers.js":7,"./mixins.js":9,"./type.js":10,emmett:3}],7:[function(t,r){(function(e){function n(t){return Array.prototype.slice.call(t)}function i(t,r){return function(){t(),r.apply(null,arguments)}}function o(t,r){var e,n={};for(e in t)n[e]=t[e];for(e in r)n[e]=r[e];return n}function s(t){var r=t.source,e="";return t.global&&(e+="g"),t.multiline&&(e+="m"),t.ignoreCase&&(e+="i"),t.sticky&&(e+="y"),t.unicode&&(e+="u"),new RegExp(r,e)}function a(t,r){if(!r||"object"!=typeof r||r instanceof Error||"ArrayBuffer"in e&&r instanceof ArrayBuffer)return r;if(_.Array(r)){if(t){var n,i,o=[];for(n=0,i=r.length;i>n;n++)o.push(w(r[n]));return o}return r.slice(0)}if(_.Date(r))return new Date(r.getTime());if(r instanceof RegExp)return s(r);if(_.Object(r)){var a,h={};r.constructor&&r.constructor!==Object&&(h=Object.create(r.constructor.prototype));for(a in r)r.hasOwnProperty(a)&&(h[a]=t?w(r[a]):r[a]);return h}return r}function h(t,r){return function(e){return r(t(e))}}function u(t,r){var e,n;for(e=0,n=t.length;n>e;e++)if(r(t[e]))return t[e]}function c(t,r){var e,n;for(e=0,n=t.length;n>e;e++)if(r(t[e]))return e;return-1}function l(t,r){var e,n=!0;if(!t)return!1;for(e in r)if(_.Object(r[e]))n=n&&l(t[e],r[e]);else if(_.Array(r[e]))n=n&&!!~r[e].indexOf(t[e]);else if(t[e]!==r[e])return!1;return n}function f(t,r){return u(t,function(t){return l(t,r)})}function d(t,r){return c(t,function(t){return l(t,r)})}function b(t,r,e){r=r||[];var n,i,o,s=t;for(i=0,o=r.length;o>i;i++){if(!s)return;if("function"==typeof r[i]){if(!_.Array(s))return;s=u(s,r[i])}else if("object"==typeof r[i])if(e&&"$cursor"in r[i]){if(!_.Path(r[i].$cursor))throw Error("baobab.getIn: $cursor path must be an array.");n=e.get(r[i].$cursor),s=s[n]}else{if(!_.Array(s))return;s=f(s,r[i])}else s=s[r[i]]}return s}function y(t,r,e){var n,i,o,s=[],a=t;for(i=0,o=r.length;o>i;i++){if(!a)return null;if("function"==typeof r[i]){if(!_.Array(a))return;n=c(a,r[i]),s.push(n),a=a[n]}else if("object"==typeof r[i])if(e&&"$cursor"in r[i]){if(!_.Path(r[i].$cursor))throw Error("baobab.getIn: $cursor path must be an array.");p=e.get(r[i].$cursor),s.push(p),a=a[p]}else{if(!_.Array(a))return;n=d(a,r[i]),s.push(n),a=a[n]}else s.push(r[i]),a=a[r[i]]||{}}return s}function g(t,r){var e,n=t.length,i={},o=i;for(n||(i=r),e=0;n>e;e++)o[t[e]]=e+1===n?r:{},o=o[t[e]];return i}function m(t,r){t.super_=r;var e=function(){};e.prototype=r.prototype,t.prototype=new e,t.prototype.constructor=t}function v(t){this.size=t,this.records=[],this.add=function(r){for(this.records.unshift(r);this.records.length>t;)this.records.pop();return this},this.get=function(){return this.records}}var _=t("./type.js"),j=a.bind(null,!1),w=a.bind(null,!0);r.exports={archive:v,arrayOf:n,before:i,deepClone:w,shallowClone:j,shallowMerge:o,compose:h,getIn:b,inherits:m,pathObject:g,solvePath:y}}).call(this,"undefined"!=typeof global?global:"undefined"!=typeof self?self:"undefined"!=typeof window?window:{})},{"./type.js":10}],8:[function(t,r){function e(t,r,e){s.forEach(function(r){e!==r&&delete t[r]}),t[e]=r[e]}function n(t,r){var a,h=i.shallowClone(r||{});s.forEach(function(r){t[r]&&e(h,t,r)}),t.$chain&&(s.slice(0,-1).forEach(function(t){delete h[t]}),h.$apply=h.$apply?i.compose(h.$apply,t.$chain):t.$chain),t.$push&&h.$push?h.$push=o.Array(h.$push)?h.$push.concat(t.$push):[h.$push].concat(t.$push):t.$push&&(h.$push=t.$push),t.$unshift&&h.$unshift?h.$unshift=o.Array(t.$unshift)?t.$unshift.concat(h.$unshift):[t.$unshift].concat(h.$unshift):t.$unshift&&(h.$unshift=t.$unshift);for(a in t)o.Object(t[a])?h[a]=n(t[a],h[a]):"$"!==a[0]&&(h[a]=t[a]);return h}var i=t("./helpers.js"),o=t("./type.js"),s=["$unset","$set","$merge","$apply"];r.exports=n},{"./helpers.js":7,"./type.js":10}],9:[function(t,r){var e=t("./combination.js"),n=t("./type.js");r.exports={baobab:function(t){return{mixins:[{getInitialState:function(){if(this.tree=t,!this.cursor&&!this.cursors)return{};if(this.cursor&&this.cursors)throw Error("baobab.mixin: you cannot have both `component.cursor` and `component.cursors`. Please make up your mind.");if(this.__type=null,this.__updateHandler=function(){this.setState(this.__getCursorData())}.bind(this),this.cursor){if(!n.MixinCursor(this.cursor))throw Error("baobab.mixin.cursor: invalid data (cursor, string, array or function).");n.Function(this.cursor)&&(this.cursor=this.cursor()),n.Cursor(this.cursor)||(this.cursor=t.select(this.cursor)),this.__getCursorData=function(){return{cursor:this.cursor.get()}}.bind(this),this.__type="single"}else if(this.cursors){if(!n.MixinCursors(this.cursors))throw Error("baobab.mixin.cursor: invalid data (object, array or function).");if(n.Function(this.cursors)&&(this.cursors=this.cursors()),n.Array(this.cursors))this.cursors=this.cursors.map(function(r){return n.Cursor(r)?r:t.select(r)}),this.__getCursorData=function(){return{cursors:this.cursors.map(function(t){return t.get()})}}.bind(this),this.__type="array";else{for(var r in this.cursors)n.Cursor(this.cursors[r])||(this.cursors[r]=t.select(this.cursors[r]));this.__getCursorData=function(){var t={};for(r in this.cursors)t[r]=this.cursors[r].get();return{cursors:t}}.bind(this),this.__type="object"}}return this.__getCursorData()},componentDidMount:function(){"single"===this.__type?(this.__combination=new e("or",[this.cursor]),this.__combination.on("update",this.__updateHandler)):"array"===this.__type?(this.__combination=new e("or",this.cursors),this.__combination.on("update",this.__updateHandler)):"object"===this.__type&&(this.__combination=new e("or",Object.keys(this.cursors).map(function(t){return this.cursors[t]},this)),this.__combination.on("update",this.__updateHandler))},componentWillUnmount:function(){this.__combination&&this.__combination.release()}}].concat(t.options.mixins)}},cursor:function(t){return{mixins:[{getInitialState:function(){return this.cursor=t,this.__updateHandler=function(){this.setState({cursor:this.cursor.get()})}.bind(this),{cursor:this.cursor.get()}},componentDidMount:function(){this.cursor.on("update",this.__updateHandler)},componentWillUnmount:function(){this.cursor.off("update",this.__updateHandler)}}].concat(t.tree.options.mixins)}}}},{"./combination.js":5,"./type.js":10}],10:[function(t,r){function e(t,r){return r.some(function(r){return n[r](t)})}var n={};n.Array=function(t){return Array.isArray(t)},n.Object=function(t){return!Array.isArray(t)&&"object"==typeof t&&null!==t},n.String=function(t){return"string"==typeof t},n.Number=function(t){return"number"==typeof t},n.Function=function(t){return"function"==typeof t},n.Primitive=function(t){return"string"==typeof t||"number"==typeof t||"boolean"==typeof t},n.Date=function(t){return t instanceof Date},n.NonScalar=function(t){return n.Object(t)||n.Array(t)},n.Path=function(t){var r=["String","Number","Function","Object"];return n.Array(t)?t.every(function(t){return e(t,r)}):e(t,r)},n.MixinCursor=function(t){return e(t,["String","Number","Array","Function","Cursor"])},n.MixinCursors=function(t){return e(t,["Object","Array","Function"])},n.ComplexPath=function(t){return t.some(function(t){return e(t,["Object","Function"])})},r.exports=n},{}],11:[function(t,r){function e(t,r){var e=new Error("baobab.update: "+r+" at path /"+t.slice(1).join("/"));return e.path=t,e}var n=t("./helpers.js"),i=t("./type.js");r.exports=function(t,r,o){if(o=o||{},!i.Object(t)&&!i.Array(t))throw Error("baobab.update: invalid target.");var s={};t={root:n.shallowClone(t)};var a=function(t,r,o,h){o=o||["root"];var u,c,l,f=o.join("λ"),p=o[o.length-1],d=Object.keys(r).some(function(t){return!!~["$unset","$set","$apply","$merge","$push","$unshift"].indexOf(t)});if(d){s[f]=!0;for(c in r){if("$unset"===c){var b=o[o.length-2];i.Array(t)?h[b]=t.slice(0,+p).concat(t.slice(+p+1)):(h[b]=n.shallowClone(t),delete h[b][p]);break}if("$set"===c){l=r.$set,t[p]=l;break}if("$apply"===c){if(u=r.$apply,"function"!=typeof u)throw e(o,"using command $apply with a non function");t[p]=u.call(null,t[p]);break}if("$merge"===c){if(l=r.$merge,!i.Object(t[p])||!i.Object(l))throw e(o,"using command $merge with a non object");t[p]=n.shallowMerge(t[p],l);break}if("$push"===c){if(l=r.$push,!i.Array(t[p]))throw e(o,"using command $push to a non array");t[p]=t[p].concat(l)}if("$unshift"===c){if(l=r.$unshift,!i.Array(t[p]))throw e(o,"using command $unshift to a non array");t[p]=[].concat(l).concat(t[p])}}}else for(c in r)t[p][c]="undefined"==typeof t[p][c]?{}:n.shallowClone(t[p][c]),a(t[p],r[c],o.concat(c),t)};return a(t,r),{data:t.root,log:Object.keys(s).map(function(t){return t.split("λ").slice(1)})}}},{"./helpers.js":7,"./type.js":10}]},{},[2])(2)}); \ No newline at end of file diff --git a/src/cursor.js b/src/cursor.js index 0a66689..a8cab05 100644 --- a/src/cursor.js +++ b/src/cursor.js @@ -52,7 +52,7 @@ function Cursor(tree, path, solvedPath, hash) { // Checking update log to see whether the cursor should update. outer: for (i = 0, l = log.length; i < l; i++) { - c = log[i].path; + c = log[i]; for (j = 0, m = c.length; j < m; j++) { p = c[j]; diff --git a/src/update.js b/src/update.js index 4823c07..3903b52 100644 --- a/src/update.js +++ b/src/update.js @@ -43,7 +43,7 @@ module.exports = function(data, spec, opts) { }); if (leafLevel) { - log[hash] = o[lastKey]; + log[hash] = true; for (k in spec) { @@ -141,10 +141,7 @@ module.exports = function(data, spec, opts) { // SHIFT LOG log: Object.keys(log).map(function(hash) { - return { - path: hash.split('λ').slice(1), - oldValue: log[hash] - }; + return hash.split('λ').slice(1); }) }; }; diff --git a/test/suites/baobab.js b/test/suites/baobab.js index ff62f82..1d36969 100644 --- a/test/suites/baobab.js +++ b/test/suites/baobab.js @@ -72,7 +72,7 @@ describe('Baobab API', function() { it('should be possible to listen to update events.', function(done) { baobab.on('update', function(e) { - assert.deepEqual(e.data.log, [{path: ['one', 'subtwo', 'colors'], oldValue: ['blue', 'yellow']}]); + assert.deepEqual(e.data.log, [['one', 'subtwo', 'colors']]); done(); }); From 3d8a1336e3a83866d87ca4888a443a73d2d7860d Mon Sep 17 00:00:00 2001 From: Yomguithereal Date: Thu, 9 Apr 2015 17:11:45 +0200 Subject: [PATCH 31/73] Emitting old tree data --- src/baobab.js | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/baobab.js b/src/baobab.js index 47953fd..cd64ed3 100644 --- a/src/baobab.js +++ b/src/baobab.js @@ -133,8 +133,10 @@ Baobab.prototype.stack = function(spec) { Baobab.prototype.commit = function() { var self = this; - // Applying modification (mutation) + // Applying modifications var result = update(this.data, this._transaction, this.options); + + var oldData = this.data; this.data = result.data; // Resetting @@ -145,7 +147,8 @@ Baobab.prototype.commit = function() { // Baobab-level update event this.emit('update', { - log: result.log + log: result.log, + previousState: oldData }); return this; From 6d9911b035e164915538c66ed8aa3be0b335f658 Mon Sep 17 00:00:00 2001 From: Yomguithereal Date: Thu, 9 Apr 2015 17:24:05 +0200 Subject: [PATCH 32/73] Fixing dynamic path edge case --- build/baobab.min.js | 2 +- src/cursor.js | 33 +++++++++++++++++---------------- 2 files changed, 18 insertions(+), 17 deletions(-) diff --git a/build/baobab.min.js b/build/baobab.min.js index 18f87d8..2ea1dd0 100644 --- a/build/baobab.min.js +++ b/build/baobab.min.js @@ -1,2 +1,2 @@ /* baobab.js - Version: 1.0.0-rc1 - Author: Yomguithereal (Guillaume Plique) */ -!function(t){if("object"==typeof exports&&"undefined"!=typeof module)module.exports=t();else if("function"==typeof define&&define.amd)define([],t);else{var r;r="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:this,r.Baobab=t()}}(function(){var t;return function r(t,e,n){function i(s,a){if(!e[s]){if(!t[s]){var h="function"==typeof require&&require;if(!a&&h)return h(s,!0);if(o)return o(s,!0);var u=new Error("Cannot find module '"+s+"'");throw u.code="MODULE_NOT_FOUND",u}var c=e[s]={exports:{}};t[s][0].call(c.exports,function(r){var e=t[s][1][r];return i(e?e:r)},c,c.exports,r,t,e,n)}return e[s].exports}for(var o="function"==typeof require&&require,s=0;sr;r++)n.push(t[r].handler);return n}var i={once:"boolean",scope:"object"},o=function(){this._enabled=!0,this._children=[],this._handlers={},this._handlersAll=[]};o.prototype.on=function(t,r,e){var n,s,a,h,u,c;if("function"==typeof r){for(u="string"==typeof t?[t]:t,n=0,s=u.length;n!==s;n+=1)if(h=u[n]){this._handlers[h]||(this._handlers[h]=[]),c={handler:r};for(a in e||{}){if(!i[a])throw new Error('The option "'+a+'" is not recognized by Emmett.');c[a]=e[a]}this._handlers[h].push(c)}}else if(t&&"object"==typeof t&&!Array.isArray(t))for(h in t)o.prototype.on.call(this,h,t[h],r);else{if("function"!=typeof t)throw new Error("Wrong arguments.");c={handler:t};for(a in e||{}){if(!i[a])throw new Error('The option "'+a+'" is not recognized by Emmett.');c[a]=e[a]}this._handlersAll.push(c)}return this},o.prototype.once=function(t,r,e){if("function"==typeof r)e=e||{},e.once=!0,this.on(t,r,e);else{if((!t||"object"!=typeof t||Array.isArray(t))&&"function"!=typeof t)throw new Error("Wrong arguments.");r=r||{},r.once=!0,this.on(t,r)}return this},o.prototype.off=function(t,r){var e,n,i,o,s,a,h,u="string"==typeof t?[t]:t;if(1===arguments.length&&"function"==typeof u){r=arguments[0];for(s in this._handlers){for(a=[],e=0,n=this._handlers[s].length;e!==n;e+=1)this._handlers[s][e].handler!==r&&a.push(this._handlers[s][e]);this._handlers[s]=a}for(a=[],e=0,n=this._handlersAll.length;e!==n;e+=1)this._handlersAll[e].handler!==r&&a.push(this._handlersAll[e]);this._handlersAll=a}else if(2===arguments.length)for(e=0,n=u.length;e!==n;e+=1){if(h=u[e],this._handlers[h]){for(a=[],i=0,o=this._handlers[h].length;i!==o;i+=1)this._handlers[h][i].handler!==r&&a.push(this._handlers[h][i]);this._handlers[h]=a}this._handlers[h]&&0===this._handlers[h].length&&delete this._handlers[h]}return this},o.prototype.unbindAll=function(){var t;this._handlersAll=[];for(t in this._handlers)delete this._handlers[t];return this},o.prototype.emit=function(t,r){var e,n,i,o,s,a,h,u,c,l,f="string"==typeof t?[t]:t;if(!this._enabled)return this;for(r=void 0===r?{}:r,e=0,n=f.length;e!==n;e+=1)if(l=f[e],c=(this._handlers[l]||[]).concat(this._handlersAll),c.length){for(h={type:l,data:r||{},target:this},a=[],i=0,o=c.length;i!==o;i+=1)(this._handlers[l]&&this._handlers[l].indexOf(c[i])>=0||this._handlersAll.indexOf(c[i])>=0)&&(c[i].handler.call("scope"in c[i]?c[i].scope:this,h),c[i].once&&a.push(c[i]));for(s=0;se;e++)if(t._children[e]===r){t._children.splice(e,1);break}}),this._children.push(r),r},o.prototype.listeners=function(t){var e,n,i,o=[];if(t)for(o=r(this._handlers[t]),n=0,i=this._children.length;i>n;n++)o=o.concat(this._children[n].listeners(t));else{o=r(this._handlersAll);for(e in this._handlers)o=o.concat(r(this._handlers[e]));for(n=0,i=this._children.length;i>n;n++)o=o.concat(this._children[n].listeners())}return o},o.prototype.kill=function(){if(this.emit("emmett:kill"),this.unbindAll(),this._handlers=null,this._handlersAll=null,this._enabled=!1,this._children)for(var t=0,r=this._children.length;r>t;t++)this._children[t].kill();this._children=null},o.prototype.disable=function(){return this._enabled=!1,this},o.prototype.enable=function(){return this._enabled=!0,this},o.version="2.1.2","undefined"!=typeof n?("undefined"!=typeof e&&e.exports&&(n=e.exports=o),n.Emitter=o):"function"==typeof t&&t.amd?t("emmett",[],function(){return o}):this.Emitter=o}).call(this)},{}],4:[function(t,r){function e(t){return t+"$"+(new Date).getTime()+(""+Math.random()).replace("0.","")}function n(t,r){function e(t){this[t]=function(){var r=this.root[t].apply(this.root,arguments);return r instanceof i?this:r}}if(arguments.length<1&&(t={}),!(this instanceof n))return new n(t,r);if(!l.Object(t)&&!l.Array(t))throw Error("Baobab: invalid data.");o.call(this),this.options=s.shallowMerge(c,r),this._transaction={},this._future=void 0,this._cursors={},this.data=s.deepClone(t),this.root=this.select([]),["get","set","unset","update"].forEach(e.bind(this)),this.mixin=u.baobab(this)}var i=t("./cursor.js"),o=t("emmett"),s=t("./helpers.js"),a=t("./update.js"),h=t("./merge.js"),u=t("./mixins.js"),c=t("../defaults.js"),l=t("./type.js");s.inherits(n,o),n.prototype.select=function(t){if(!t)throw Error("Baobab.select: invalid path.");if(arguments.length>1&&(t=s.arrayOf(arguments)),!l.Path(t))throw Error("Baobab.select: invalid path.");t=[].concat(t);var r,n=l.ComplexPath(t);n&&(r=s.solvePath(this.data,t,this));var o=t.map(function(t){return l.Function(t)?e("fn"):l.Object(t)?e("ob"):t}).join("λ");if(this._cursors[o])return this._cursors[o];var a=new i(this,t,r,o);return this._cursors[o]=a,a},n.prototype.stack=function(t){var r=this;if(!l.Object(t))throw Error("Baobab.update: wrong specification.");return this._transaction=h(t,this._transaction),this.options.autoCommit?this.options.asynchronous?(this._future||(this._future=setTimeout(r.commit.bind(r,null),0)),this):this.commit():this},n.prototype.commit=function(){var t=a(this.data,this._transaction,this.options);return this.data=t.data,this._transaction={},this._future&&(this._future=clearTimeout(this._future)),this.emit("update",{log:t.log}),this},n.prototype.release=function(){delete this.data,delete this._transaction;for(var t in this._cursors)this._cursors[t].release();delete this._cursors,this.kill()},n.prototype.toJSON=function(){return this.get()},r.exports=n},{"../defaults.js":1,"./cursor.js":6,"./helpers.js":7,"./merge.js":8,"./mixins.js":9,"./type.js":10,"./update.js":11,emmett:3}],5:[function(t,r){function e(t,r){r.on("update",t.cursorListener),t.tree.off("update",t.treeListener),t.tree.on("update",t.treeListener)}function n(t){var r=this;if(arguments.length<2)throw Error("baobab.Combination: not enough arguments.");var n=arguments[1],i=s.arrayOf(arguments).slice(2);if(n instanceof Array&&(i=n.slice(1),n=n[0]),!a.Cursor(n))throw Error("baobab.Combination: argument should be a cursor.");if("or"!==t&&"and"!==t)throw Error("baobab.Combination: invalid operator.");o.call(this),this.cursors=[n],this.operators=[],this.tree=n.tree,this.updates=new Array(this.cursors.length),this.cursorListener=function(){r.updates[r.cursors.indexOf(this)]=!0},this.treeListener=function(){var t,e,n=r.updates[0];for(t=1,e=r.cursors.length;e>t;t++)n="or"===r.operators[t-1]?n||r.updates[t]:n&&r.updates[t];n&&r.emit("update"),r.updates=new Array(r.cursors.length)},this.bound=!1;var h=(this.on,this.once,function(){r.bound||(r.bound=!0,r.cursors.forEach(function(t){e(r,t)}))});this.on=s.before(h,this.on.bind(this)),this.once=s.before(h,this.once.bind(this)),i.forEach(function(r){this[t](r)},this)}function i(t){n.prototype[t]=function(r){if(!a.Cursor(r))throw this.release(),Error("baobab.Combination."+t+": argument should be a cursor.");if(~this.cursors.indexOf(r))throw this.release(),Error("baobab.Combination."+t+": cursor already in combination.");return this.cursors.push(r),this.operators.push(t),this.updates.length++,this.bound&&e(this,r),this}}var o=t("emmett"),s=t("./helpers.js"),a=t("./type.js");s.inherits(n,o),i("or"),i("and"),n.prototype.release=function(){this.cursors.forEach(function(t){t.off("update",this.cursorListener)},this),this.tree.off("update",this.treeListener),this.cursors=null,this.operators=null,this.tree=null,this.updates=null,this.kill()},r.exports=n},{"./helpers.js":7,"./type.js":10,emmett:3}],6:[function(t,r){function e(t,r,e,n){var i=this;o.call(this),r=r||[],this.tree=t,this.path=r,this.hash=n,this.archive=null,this.complexPath=!!e,this.solvedPath=this.complexPath?e:this.path,this.relevant=void 0!==this.get(),this.updateHandler=function(t){var r,e,n,o,s,a,u=t.data.log,c=!1;if(i.complexPath&&(i.solvedPath=h.solvePath(i.tree.data,i.path,i.tree)),!i.path.length)return i.emit("update");t:for(s=0,n=u.length;n>s;s++)for(r=u[s],a=0,o=r.length;o>a&&(e=r[a],e===""+i.solvedPath[a]);a++)if(a+1===o||a+1===i.solvedPath.length){c=!0;break t}var l=void 0!==i.get();i.relevant?l&&c?i.emit("update"):l||(i.emit("irrelevant"),i.relevant=!1):l&&c&&(i.emit("relevant"),i.emit("update"),i.relevant=!0)},this.mixin=a.cursor(this);var s=!1,u=function(){s||(s=!0,i.tree.on("update",i.updateHandler))};this.on=h.before(u,this.on.bind(this)),this.once=h.before(u,this.once.bind(this))}function n(t,r,e,n){arguments.length<4&&(n=e,e=[]),e=e||[];var i=[].concat(e),o=h.solvePath(this.get(),i,this.tree);if(!o)throw Error("baobab.Cursor."+t+": could not solve dynamic path.");if(r){var s=this.get(o);if(!u[r](s))throw Error("baobab.Cursor."+t+": invalid target.")}var a={};a["$"+t]=n;var c=h.pathObject(o,a);return c}function i(t,r){e.prototype[t]=function(){var e=n.bind(this,t,r).apply(this,arguments);return this.update(e)}}var o=t("emmett"),s=t("./combination.js"),a=t("./mixins.js"),h=t("./helpers.js"),u=t("./type.js");h.inherits(e,o),e.prototype.isRoot=function(){return!this.path.length},e.prototype.isLeaf=function(){return u.Primitive(this.get())},e.prototype.isBranch=function(){return!this.isLeaf()&&!this.isRoot()},e.prototype.root=function(){return this.tree.root()},e.prototype.select=function(t){if(arguments.length>1&&(t=h.arrayOf(arguments)),!u.Path(t))throw Error("baobab.Cursor.select: invalid path.");return this.tree.select(this.path.concat(t))},e.prototype.up=function(){return this.solvedPath&&this.solvedPath.length?this.tree.select(this.path.slice(0,-1)):null},e.prototype.left=function(){var t=+this.solvedPath[this.solvedPath.length-1];if(isNaN(t))throw Error("baobab.Cursor.left: cannot go left on a non-list type.");return t?this.tree.select(this.solvedPath.slice(0,-1).concat(t-1)):null},e.prototype.leftmost=function(){var t=+this.solvedPath[this.solvedPath.length-1];if(isNaN(t))throw Error("baobab.Cursor.leftmost: cannot go left on a non-list type.");return this.tree.select(this.solvedPath.slice(0,-1).concat(0))},e.prototype.right=function(){var t=+this.solvedPath[this.solvedPath.length-1];if(isNaN(t))throw Error("baobab.Cursor.right: cannot go right on a non-list type.");return t+1===this.up().get().length?null:this.tree.select(this.solvedPath.slice(0,-1).concat(t+1))},e.prototype.rightmost=function(){var t=+this.solvedPath[this.solvedPath.length-1];if(isNaN(t))throw Error("baobab.Cursor.right: cannot go right on a non-list type.");var r=this.up().get();return this.tree.select(this.solvedPath.slice(0,-1).concat(r.length-1))},e.prototype.down=function(){+this.solvedPath[this.solvedPath.length-1];return this.get()instanceof Array?this.tree.select(this.solvedPath.concat(0)):null},e.prototype.get=function(t){arguments.length>1&&(t=h.arrayOf(arguments));var r=this.solvedPath.concat((u.String(t)||u.Number(t)?[t]:t)||[]);return h.getIn(this.tree.data,r,this.tree)},i("set"),i("apply"),i("chain"),i("push","Array"),i("unshift","Array"),e.prototype.merge=function(t){if(!u.Object(t))throw Error("baobab.Cursor.merge: trying to merge a non-object.");var r=n.bind(this,"merge","Object").apply(this,arguments);return this.update(r)},e.prototype.unset=function(t){if(void 0===t&&this.isRoot())throw Error("baobab.Cursor.unset: cannot remove root node.");var r=n.bind(this,"unset",null).apply(this,[t,!0]);return this.update(r)},e.prototype.update=function(t,r){if(arguments.length<2)return this.tree.stack(h.pathObject(this.solvedPath,t)),this;var e=[].concat(t),n=h.solvePath(this.get(),e,this.tree);if(!n)throw Error("baobab.Cursor.update: could not solve dynamic path.");return this.tree.stack(h.pathObject(this.solvedPath.concat(n),r)),this},e.prototype.or=function(t){return new s("or",this,t)},e.prototype.and=function(t){return new s("and",this,t)},e.prototype.startRecording=function(t){return this.archive?this:(this.archive=h.archive(t),this)},e.prototype.stopRecording=function(){return this.archive=null,this},e.prototype.undo=function(){},e.prototype.redo=function(){},e.prototype.isRecording=function(){return!!this.archive},e.prototype.hasHistory=function(){return!(!this.archive||!this.archive.records.length)},e.prototype.getHistory=function(){return this.archive.records},e.prototype.release=function(){this.tree.off("update",this.updateHandler),this.hash&&delete this.tree._cursors[this.hash],delete this.tree,delete this.path,delete this.solvedPath,this.kill()},e.prototype.toJSON=function(){return this.get()},u.Cursor=function(t){return t instanceof e},r.exports=e},{"./combination.js":5,"./helpers.js":7,"./mixins.js":9,"./type.js":10,emmett:3}],7:[function(t,r){(function(e){function n(t){return Array.prototype.slice.call(t)}function i(t,r){return function(){t(),r.apply(null,arguments)}}function o(t,r){var e,n={};for(e in t)n[e]=t[e];for(e in r)n[e]=r[e];return n}function s(t){var r=t.source,e="";return t.global&&(e+="g"),t.multiline&&(e+="m"),t.ignoreCase&&(e+="i"),t.sticky&&(e+="y"),t.unicode&&(e+="u"),new RegExp(r,e)}function a(t,r){if(!r||"object"!=typeof r||r instanceof Error||"ArrayBuffer"in e&&r instanceof ArrayBuffer)return r;if(_.Array(r)){if(t){var n,i,o=[];for(n=0,i=r.length;i>n;n++)o.push(w(r[n]));return o}return r.slice(0)}if(_.Date(r))return new Date(r.getTime());if(r instanceof RegExp)return s(r);if(_.Object(r)){var a,h={};r.constructor&&r.constructor!==Object&&(h=Object.create(r.constructor.prototype));for(a in r)r.hasOwnProperty(a)&&(h[a]=t?w(r[a]):r[a]);return h}return r}function h(t,r){return function(e){return r(t(e))}}function u(t,r){var e,n;for(e=0,n=t.length;n>e;e++)if(r(t[e]))return t[e]}function c(t,r){var e,n;for(e=0,n=t.length;n>e;e++)if(r(t[e]))return e;return-1}function l(t,r){var e,n=!0;if(!t)return!1;for(e in r)if(_.Object(r[e]))n=n&&l(t[e],r[e]);else if(_.Array(r[e]))n=n&&!!~r[e].indexOf(t[e]);else if(t[e]!==r[e])return!1;return n}function f(t,r){return u(t,function(t){return l(t,r)})}function d(t,r){return c(t,function(t){return l(t,r)})}function b(t,r,e){r=r||[];var n,i,o,s=t;for(i=0,o=r.length;o>i;i++){if(!s)return;if("function"==typeof r[i]){if(!_.Array(s))return;s=u(s,r[i])}else if("object"==typeof r[i])if(e&&"$cursor"in r[i]){if(!_.Path(r[i].$cursor))throw Error("baobab.getIn: $cursor path must be an array.");n=e.get(r[i].$cursor),s=s[n]}else{if(!_.Array(s))return;s=f(s,r[i])}else s=s[r[i]]}return s}function y(t,r,e){var n,i,o,s=[],a=t;for(i=0,o=r.length;o>i;i++){if(!a)return null;if("function"==typeof r[i]){if(!_.Array(a))return;n=c(a,r[i]),s.push(n),a=a[n]}else if("object"==typeof r[i])if(e&&"$cursor"in r[i]){if(!_.Path(r[i].$cursor))throw Error("baobab.getIn: $cursor path must be an array.");p=e.get(r[i].$cursor),s.push(p),a=a[p]}else{if(!_.Array(a))return;n=d(a,r[i]),s.push(n),a=a[n]}else s.push(r[i]),a=a[r[i]]||{}}return s}function g(t,r){var e,n=t.length,i={},o=i;for(n||(i=r),e=0;n>e;e++)o[t[e]]=e+1===n?r:{},o=o[t[e]];return i}function m(t,r){t.super_=r;var e=function(){};e.prototype=r.prototype,t.prototype=new e,t.prototype.constructor=t}function v(t){this.size=t,this.records=[],this.add=function(r){for(this.records.unshift(r);this.records.length>t;)this.records.pop();return this},this.get=function(){return this.records}}var _=t("./type.js"),j=a.bind(null,!1),w=a.bind(null,!0);r.exports={archive:v,arrayOf:n,before:i,deepClone:w,shallowClone:j,shallowMerge:o,compose:h,getIn:b,inherits:m,pathObject:g,solvePath:y}}).call(this,"undefined"!=typeof global?global:"undefined"!=typeof self?self:"undefined"!=typeof window?window:{})},{"./type.js":10}],8:[function(t,r){function e(t,r,e){s.forEach(function(r){e!==r&&delete t[r]}),t[e]=r[e]}function n(t,r){var a,h=i.shallowClone(r||{});s.forEach(function(r){t[r]&&e(h,t,r)}),t.$chain&&(s.slice(0,-1).forEach(function(t){delete h[t]}),h.$apply=h.$apply?i.compose(h.$apply,t.$chain):t.$chain),t.$push&&h.$push?h.$push=o.Array(h.$push)?h.$push.concat(t.$push):[h.$push].concat(t.$push):t.$push&&(h.$push=t.$push),t.$unshift&&h.$unshift?h.$unshift=o.Array(t.$unshift)?t.$unshift.concat(h.$unshift):[t.$unshift].concat(h.$unshift):t.$unshift&&(h.$unshift=t.$unshift);for(a in t)o.Object(t[a])?h[a]=n(t[a],h[a]):"$"!==a[0]&&(h[a]=t[a]);return h}var i=t("./helpers.js"),o=t("./type.js"),s=["$unset","$set","$merge","$apply"];r.exports=n},{"./helpers.js":7,"./type.js":10}],9:[function(t,r){var e=t("./combination.js"),n=t("./type.js");r.exports={baobab:function(t){return{mixins:[{getInitialState:function(){if(this.tree=t,!this.cursor&&!this.cursors)return{};if(this.cursor&&this.cursors)throw Error("baobab.mixin: you cannot have both `component.cursor` and `component.cursors`. Please make up your mind.");if(this.__type=null,this.__updateHandler=function(){this.setState(this.__getCursorData())}.bind(this),this.cursor){if(!n.MixinCursor(this.cursor))throw Error("baobab.mixin.cursor: invalid data (cursor, string, array or function).");n.Function(this.cursor)&&(this.cursor=this.cursor()),n.Cursor(this.cursor)||(this.cursor=t.select(this.cursor)),this.__getCursorData=function(){return{cursor:this.cursor.get()}}.bind(this),this.__type="single"}else if(this.cursors){if(!n.MixinCursors(this.cursors))throw Error("baobab.mixin.cursor: invalid data (object, array or function).");if(n.Function(this.cursors)&&(this.cursors=this.cursors()),n.Array(this.cursors))this.cursors=this.cursors.map(function(r){return n.Cursor(r)?r:t.select(r)}),this.__getCursorData=function(){return{cursors:this.cursors.map(function(t){return t.get()})}}.bind(this),this.__type="array";else{for(var r in this.cursors)n.Cursor(this.cursors[r])||(this.cursors[r]=t.select(this.cursors[r]));this.__getCursorData=function(){var t={};for(r in this.cursors)t[r]=this.cursors[r].get();return{cursors:t}}.bind(this),this.__type="object"}}return this.__getCursorData()},componentDidMount:function(){"single"===this.__type?(this.__combination=new e("or",[this.cursor]),this.__combination.on("update",this.__updateHandler)):"array"===this.__type?(this.__combination=new e("or",this.cursors),this.__combination.on("update",this.__updateHandler)):"object"===this.__type&&(this.__combination=new e("or",Object.keys(this.cursors).map(function(t){return this.cursors[t]},this)),this.__combination.on("update",this.__updateHandler))},componentWillUnmount:function(){this.__combination&&this.__combination.release()}}].concat(t.options.mixins)}},cursor:function(t){return{mixins:[{getInitialState:function(){return this.cursor=t,this.__updateHandler=function(){this.setState({cursor:this.cursor.get()})}.bind(this),{cursor:this.cursor.get()}},componentDidMount:function(){this.cursor.on("update",this.__updateHandler)},componentWillUnmount:function(){this.cursor.off("update",this.__updateHandler)}}].concat(t.tree.options.mixins)}}}},{"./combination.js":5,"./type.js":10}],10:[function(t,r){function e(t,r){return r.some(function(r){return n[r](t)})}var n={};n.Array=function(t){return Array.isArray(t)},n.Object=function(t){return!Array.isArray(t)&&"object"==typeof t&&null!==t},n.String=function(t){return"string"==typeof t},n.Number=function(t){return"number"==typeof t},n.Function=function(t){return"function"==typeof t},n.Primitive=function(t){return"string"==typeof t||"number"==typeof t||"boolean"==typeof t},n.Date=function(t){return t instanceof Date},n.NonScalar=function(t){return n.Object(t)||n.Array(t)},n.Path=function(t){var r=["String","Number","Function","Object"];return n.Array(t)?t.every(function(t){return e(t,r)}):e(t,r)},n.MixinCursor=function(t){return e(t,["String","Number","Array","Function","Cursor"])},n.MixinCursors=function(t){return e(t,["Object","Array","Function"])},n.ComplexPath=function(t){return t.some(function(t){return e(t,["Object","Function"])})},r.exports=n},{}],11:[function(t,r){function e(t,r){var e=new Error("baobab.update: "+r+" at path /"+t.slice(1).join("/"));return e.path=t,e}var n=t("./helpers.js"),i=t("./type.js");r.exports=function(t,r,o){if(o=o||{},!i.Object(t)&&!i.Array(t))throw Error("baobab.update: invalid target.");var s={};t={root:n.shallowClone(t)};var a=function(t,r,o,h){o=o||["root"];var u,c,l,f=o.join("λ"),p=o[o.length-1],d=Object.keys(r).some(function(t){return!!~["$unset","$set","$apply","$merge","$push","$unshift"].indexOf(t)});if(d){s[f]=!0;for(c in r){if("$unset"===c){var b=o[o.length-2];i.Array(t)?h[b]=t.slice(0,+p).concat(t.slice(+p+1)):(h[b]=n.shallowClone(t),delete h[b][p]);break}if("$set"===c){l=r.$set,t[p]=l;break}if("$apply"===c){if(u=r.$apply,"function"!=typeof u)throw e(o,"using command $apply with a non function");t[p]=u.call(null,t[p]);break}if("$merge"===c){if(l=r.$merge,!i.Object(t[p])||!i.Object(l))throw e(o,"using command $merge with a non object");t[p]=n.shallowMerge(t[p],l);break}if("$push"===c){if(l=r.$push,!i.Array(t[p]))throw e(o,"using command $push to a non array");t[p]=t[p].concat(l)}if("$unshift"===c){if(l=r.$unshift,!i.Array(t[p]))throw e(o,"using command $unshift to a non array");t[p]=[].concat(l).concat(t[p])}}}else for(c in r)t[p][c]="undefined"==typeof t[p][c]?{}:n.shallowClone(t[p][c]),a(t[p],r[c],o.concat(c),t)};return a(t,r),{data:t.root,log:Object.keys(s).map(function(t){return t.split("λ").slice(1)})}}},{"./helpers.js":7,"./type.js":10}]},{},[2])(2)}); \ No newline at end of file +!function(t){if("object"==typeof exports&&"undefined"!=typeof module)module.exports=t();else if("function"==typeof define&&define.amd)define([],t);else{var r;r="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:this,r.Baobab=t()}}(function(){var t;return function r(t,e,n){function i(s,a){if(!e[s]){if(!t[s]){var h="function"==typeof require&&require;if(!a&&h)return h(s,!0);if(o)return o(s,!0);var u=new Error("Cannot find module '"+s+"'");throw u.code="MODULE_NOT_FOUND",u}var c=e[s]={exports:{}};t[s][0].call(c.exports,function(r){var e=t[s][1][r];return i(e?e:r)},c,c.exports,r,t,e,n)}return e[s].exports}for(var o="function"==typeof require&&require,s=0;sr;r++)n.push(t[r].handler);return n}var i={once:"boolean",scope:"object"},o=function(){this._enabled=!0,this._children=[],this._handlers={},this._handlersAll=[]};o.prototype.on=function(t,r,e){var n,s,a,h,u,c;if("function"==typeof r){for(u="string"==typeof t?[t]:t,n=0,s=u.length;n!==s;n+=1)if(h=u[n]){this._handlers[h]||(this._handlers[h]=[]),c={handler:r};for(a in e||{}){if(!i[a])throw new Error('The option "'+a+'" is not recognized by Emmett.');c[a]=e[a]}this._handlers[h].push(c)}}else if(t&&"object"==typeof t&&!Array.isArray(t))for(h in t)o.prototype.on.call(this,h,t[h],r);else{if("function"!=typeof t)throw new Error("Wrong arguments.");c={handler:t};for(a in e||{}){if(!i[a])throw new Error('The option "'+a+'" is not recognized by Emmett.');c[a]=e[a]}this._handlersAll.push(c)}return this},o.prototype.once=function(t,r,e){if("function"==typeof r)e=e||{},e.once=!0,this.on(t,r,e);else{if((!t||"object"!=typeof t||Array.isArray(t))&&"function"!=typeof t)throw new Error("Wrong arguments.");r=r||{},r.once=!0,this.on(t,r)}return this},o.prototype.off=function(t,r){var e,n,i,o,s,a,h,u="string"==typeof t?[t]:t;if(1===arguments.length&&"function"==typeof u){r=arguments[0];for(s in this._handlers){for(a=[],e=0,n=this._handlers[s].length;e!==n;e+=1)this._handlers[s][e].handler!==r&&a.push(this._handlers[s][e]);this._handlers[s]=a}for(a=[],e=0,n=this._handlersAll.length;e!==n;e+=1)this._handlersAll[e].handler!==r&&a.push(this._handlersAll[e]);this._handlersAll=a}else if(2===arguments.length)for(e=0,n=u.length;e!==n;e+=1){if(h=u[e],this._handlers[h]){for(a=[],i=0,o=this._handlers[h].length;i!==o;i+=1)this._handlers[h][i].handler!==r&&a.push(this._handlers[h][i]);this._handlers[h]=a}this._handlers[h]&&0===this._handlers[h].length&&delete this._handlers[h]}return this},o.prototype.unbindAll=function(){var t;this._handlersAll=[];for(t in this._handlers)delete this._handlers[t];return this},o.prototype.emit=function(t,r){var e,n,i,o,s,a,h,u,c,l,f="string"==typeof t?[t]:t;if(!this._enabled)return this;for(r=void 0===r?{}:r,e=0,n=f.length;e!==n;e+=1)if(l=f[e],c=(this._handlers[l]||[]).concat(this._handlersAll),c.length){for(h={type:l,data:r||{},target:this},a=[],i=0,o=c.length;i!==o;i+=1)(this._handlers[l]&&this._handlers[l].indexOf(c[i])>=0||this._handlersAll.indexOf(c[i])>=0)&&(c[i].handler.call("scope"in c[i]?c[i].scope:this,h),c[i].once&&a.push(c[i]));for(s=0;se;e++)if(t._children[e]===r){t._children.splice(e,1);break}}),this._children.push(r),r},o.prototype.listeners=function(t){var e,n,i,o=[];if(t)for(o=r(this._handlers[t]),n=0,i=this._children.length;i>n;n++)o=o.concat(this._children[n].listeners(t));else{o=r(this._handlersAll);for(e in this._handlers)o=o.concat(r(this._handlers[e]));for(n=0,i=this._children.length;i>n;n++)o=o.concat(this._children[n].listeners())}return o},o.prototype.kill=function(){if(this.emit("emmett:kill"),this.unbindAll(),this._handlers=null,this._handlersAll=null,this._enabled=!1,this._children)for(var t=0,r=this._children.length;r>t;t++)this._children[t].kill();this._children=null},o.prototype.disable=function(){return this._enabled=!1,this},o.prototype.enable=function(){return this._enabled=!0,this},o.version="2.1.2","undefined"!=typeof n?("undefined"!=typeof e&&e.exports&&(n=e.exports=o),n.Emitter=o):"function"==typeof t&&t.amd?t("emmett",[],function(){return o}):this.Emitter=o}).call(this)},{}],4:[function(t,r){function e(t){return t+"$"+(new Date).getTime()+(""+Math.random()).replace("0.","")}function n(t,r){function e(t){this[t]=function(){var r=this.root[t].apply(this.root,arguments);return r instanceof i?this:r}}if(arguments.length<1&&(t={}),!(this instanceof n))return new n(t,r);if(!l.Object(t)&&!l.Array(t))throw Error("Baobab: invalid data.");o.call(this),this.options=s.shallowMerge(c,r),this._transaction={},this._future=void 0,this._cursors={},this.data=s.deepClone(t),this.root=this.select([]),["get","set","unset","update"].forEach(e.bind(this)),this.mixin=u.baobab(this)}var i=t("./cursor.js"),o=t("emmett"),s=t("./helpers.js"),a=t("./update.js"),h=t("./merge.js"),u=t("./mixins.js"),c=t("../defaults.js"),l=t("./type.js");s.inherits(n,o),n.prototype.select=function(t){if(!t)throw Error("Baobab.select: invalid path.");if(arguments.length>1&&(t=s.arrayOf(arguments)),!l.Path(t))throw Error("Baobab.select: invalid path.");t=[].concat(t);var r,n=l.ComplexPath(t);n&&(r=s.solvePath(this.data,t,this));var o=t.map(function(t){return l.Function(t)?e("fn"):l.Object(t)?e("ob"):t}).join("λ");if(this._cursors[o])return this._cursors[o];var a=new i(this,t,r,o);return this._cursors[o]=a,a},n.prototype.stack=function(t){var r=this;if(!l.Object(t))throw Error("Baobab.update: wrong specification.");return this._transaction=h(t,this._transaction),this.options.autoCommit?this.options.asynchronous?(this._future||(this._future=setTimeout(r.commit.bind(r,null),0)),this):this.commit():this},n.prototype.commit=function(){var t=a(this.data,this._transaction,this.options),r=this.data;return this.data=t.data,this._transaction={},this._future&&(this._future=clearTimeout(this._future)),this.emit("update",{log:t.log,previousState:r}),this},n.prototype.release=function(){delete this.data,delete this._transaction;for(var t in this._cursors)this._cursors[t].release();delete this._cursors,this.kill()},n.prototype.toJSON=function(){return this.get()},r.exports=n},{"../defaults.js":1,"./cursor.js":6,"./helpers.js":7,"./merge.js":8,"./mixins.js":9,"./type.js":10,"./update.js":11,emmett:3}],5:[function(t,r){function e(t,r){r.on("update",t.cursorListener),t.tree.off("update",t.treeListener),t.tree.on("update",t.treeListener)}function n(t){var r=this;if(arguments.length<2)throw Error("baobab.Combination: not enough arguments.");var n=arguments[1],i=s.arrayOf(arguments).slice(2);if(n instanceof Array&&(i=n.slice(1),n=n[0]),!a.Cursor(n))throw Error("baobab.Combination: argument should be a cursor.");if("or"!==t&&"and"!==t)throw Error("baobab.Combination: invalid operator.");o.call(this),this.cursors=[n],this.operators=[],this.tree=n.tree,this.updates=new Array(this.cursors.length),this.cursorListener=function(){r.updates[r.cursors.indexOf(this)]=!0},this.treeListener=function(){var t,e,n=r.updates[0];for(t=1,e=r.cursors.length;e>t;t++)n="or"===r.operators[t-1]?n||r.updates[t]:n&&r.updates[t];n&&r.emit("update"),r.updates=new Array(r.cursors.length)},this.bound=!1;var h=(this.on,this.once,function(){r.bound||(r.bound=!0,r.cursors.forEach(function(t){e(r,t)}))});this.on=s.before(h,this.on.bind(this)),this.once=s.before(h,this.once.bind(this)),i.forEach(function(r){this[t](r)},this)}function i(t){n.prototype[t]=function(r){if(!a.Cursor(r))throw this.release(),Error("baobab.Combination."+t+": argument should be a cursor.");if(~this.cursors.indexOf(r))throw this.release(),Error("baobab.Combination."+t+": cursor already in combination.");return this.cursors.push(r),this.operators.push(t),this.updates.length++,this.bound&&e(this,r),this}}var o=t("emmett"),s=t("./helpers.js"),a=t("./type.js");s.inherits(n,o),i("or"),i("and"),n.prototype.release=function(){this.cursors.forEach(function(t){t.off("update",this.cursorListener)},this),this.tree.off("update",this.treeListener),this.cursors=null,this.operators=null,this.tree=null,this.updates=null,this.kill()},r.exports=n},{"./helpers.js":7,"./type.js":10,emmett:3}],6:[function(t,r){function e(t,r,e,n){var i=this;o.call(this),r=r||[],this.tree=t,this.path=r,this.hash=n,this.archive=null,this.complexPath=!!e,this.solvedPath=this.complexPath?e:this.path,this.relevant=void 0!==this.get(),this.updateHandler=function(t){var r,e,n,o,s,a,u=t.data.log,c=!1;if(i.complexPath&&(i.solvedPath=h.solvePath(i.tree.data,i.path,i.tree)),!i.path.length)return i.emit("update");if(i.solvedPath)t:for(s=0,n=u.length;n>s;s++)for(r=u[s],a=0,o=r.length;o>a&&(e=r[a],e===""+i.solvedPath[a]);a++)if(a+1===o||a+1===i.solvedPath.length){c=!0;break t}var l=void 0!==i.get();i.relevant?l&&c?i.emit("update"):l||(i.emit("irrelevant"),i.relevant=!1):l&&c&&(i.emit("relevant"),i.emit("update"),i.relevant=!0)},this.mixin=a.cursor(this);var s=!1,u=function(){s||(s=!0,i.tree.on("update",i.updateHandler))};this.on=h.before(u,this.on.bind(this)),this.once=h.before(u,this.once.bind(this))}function n(t,r,e,n){arguments.length<4&&(n=e,e=[]),e=e||[];var i=[].concat(e),o=h.solvePath(this.get(),i,this.tree);if(!o)throw Error("baobab.Cursor."+t+": could not solve dynamic path.");if(r){var s=this.get(o);if(!u[r](s))throw Error("baobab.Cursor."+t+": invalid target.")}var a={};a["$"+t]=n;var c=h.pathObject(o,a);return c}function i(t,r){e.prototype[t]=function(){var e=n.bind(this,t,r).apply(this,arguments);return this.update(e)}}var o=t("emmett"),s=t("./combination.js"),a=t("./mixins.js"),h=t("./helpers.js"),u=t("./type.js");h.inherits(e,o),e.prototype.isRoot=function(){return!this.path.length},e.prototype.isLeaf=function(){return u.Primitive(this.get())},e.prototype.isBranch=function(){return!this.isLeaf()&&!this.isRoot()},e.prototype.root=function(){return this.tree.root()},e.prototype.select=function(t){if(arguments.length>1&&(t=h.arrayOf(arguments)),!u.Path(t))throw Error("baobab.Cursor.select: invalid path.");return this.tree.select(this.path.concat(t))},e.prototype.up=function(){return this.solvedPath&&this.solvedPath.length?this.tree.select(this.path.slice(0,-1)):null},e.prototype.left=function(){var t=+this.solvedPath[this.solvedPath.length-1];if(isNaN(t))throw Error("baobab.Cursor.left: cannot go left on a non-list type.");return t?this.tree.select(this.solvedPath.slice(0,-1).concat(t-1)):null},e.prototype.leftmost=function(){var t=+this.solvedPath[this.solvedPath.length-1];if(isNaN(t))throw Error("baobab.Cursor.leftmost: cannot go left on a non-list type.");return this.tree.select(this.solvedPath.slice(0,-1).concat(0))},e.prototype.right=function(){var t=+this.solvedPath[this.solvedPath.length-1];if(isNaN(t))throw Error("baobab.Cursor.right: cannot go right on a non-list type.");return t+1===this.up().get().length?null:this.tree.select(this.solvedPath.slice(0,-1).concat(t+1))},e.prototype.rightmost=function(){var t=+this.solvedPath[this.solvedPath.length-1];if(isNaN(t))throw Error("baobab.Cursor.right: cannot go right on a non-list type.");var r=this.up().get();return this.tree.select(this.solvedPath.slice(0,-1).concat(r.length-1))},e.prototype.down=function(){+this.solvedPath[this.solvedPath.length-1];return this.get()instanceof Array?this.tree.select(this.solvedPath.concat(0)):null},e.prototype.get=function(t){arguments.length>1&&(t=h.arrayOf(arguments));var r=this.solvedPath.concat((u.String(t)||u.Number(t)?[t]:t)||[]);return h.getIn(this.tree.data,r,this.tree)},i("set"),i("apply"),i("chain"),i("push","Array"),i("unshift","Array"),e.prototype.merge=function(t){if(!u.Object(t))throw Error("baobab.Cursor.merge: trying to merge a non-object.");var r=n.bind(this,"merge","Object").apply(this,arguments);return this.update(r)},e.prototype.unset=function(t){if(void 0===t&&this.isRoot())throw Error("baobab.Cursor.unset: cannot remove root node.");var r=n.bind(this,"unset",null).apply(this,[t,!0]);return this.update(r)},e.prototype.update=function(t,r){if(arguments.length<2)return this.tree.stack(h.pathObject(this.solvedPath,t)),this;var e=[].concat(t),n=h.solvePath(this.get(),e,this.tree);if(!n)throw Error("baobab.Cursor.update: could not solve dynamic path.");return this.tree.stack(h.pathObject(this.solvedPath.concat(n),r)),this},e.prototype.or=function(t){return new s("or",this,t)},e.prototype.and=function(t){return new s("and",this,t)},e.prototype.startRecording=function(t){return this.archive?this:(this.archive=h.archive(t),this)},e.prototype.stopRecording=function(){return this.archive=null,this},e.prototype.undo=function(){},e.prototype.redo=function(){},e.prototype.isRecording=function(){return!!this.archive},e.prototype.hasHistory=function(){return!(!this.archive||!this.archive.records.length)},e.prototype.getHistory=function(){return this.archive.records},e.prototype.release=function(){this.tree.off("update",this.updateHandler),this.hash&&delete this.tree._cursors[this.hash],delete this.tree,delete this.path,delete this.solvedPath,this.kill()},e.prototype.toJSON=function(){return this.get()},u.Cursor=function(t){return t instanceof e},r.exports=e},{"./combination.js":5,"./helpers.js":7,"./mixins.js":9,"./type.js":10,emmett:3}],7:[function(t,r){(function(e){function n(t){return Array.prototype.slice.call(t)}function i(t,r){return function(){t(),r.apply(null,arguments)}}function o(t,r){var e,n={};for(e in t)n[e]=t[e];for(e in r)n[e]=r[e];return n}function s(t){var r=t.source,e="";return t.global&&(e+="g"),t.multiline&&(e+="m"),t.ignoreCase&&(e+="i"),t.sticky&&(e+="y"),t.unicode&&(e+="u"),new RegExp(r,e)}function a(t,r){if(!r||"object"!=typeof r||r instanceof Error||"ArrayBuffer"in e&&r instanceof ArrayBuffer)return r;if(_.Array(r)){if(t){var n,i,o=[];for(n=0,i=r.length;i>n;n++)o.push(w(r[n]));return o}return r.slice(0)}if(_.Date(r))return new Date(r.getTime());if(r instanceof RegExp)return s(r);if(_.Object(r)){var a,h={};r.constructor&&r.constructor!==Object&&(h=Object.create(r.constructor.prototype));for(a in r)r.hasOwnProperty(a)&&(h[a]=t?w(r[a]):r[a]);return h}return r}function h(t,r){return function(e){return r(t(e))}}function u(t,r){var e,n;for(e=0,n=t.length;n>e;e++)if(r(t[e]))return t[e]}function c(t,r){var e,n;for(e=0,n=t.length;n>e;e++)if(r(t[e]))return e;return-1}function l(t,r){var e,n=!0;if(!t)return!1;for(e in r)if(_.Object(r[e]))n=n&&l(t[e],r[e]);else if(_.Array(r[e]))n=n&&!!~r[e].indexOf(t[e]);else if(t[e]!==r[e])return!1;return n}function f(t,r){return u(t,function(t){return l(t,r)})}function d(t,r){return c(t,function(t){return l(t,r)})}function b(t,r,e){r=r||[];var n,i,o,s=t;for(i=0,o=r.length;o>i;i++){if(!s)return;if("function"==typeof r[i]){if(!_.Array(s))return;s=u(s,r[i])}else if("object"==typeof r[i])if(e&&"$cursor"in r[i]){if(!_.Path(r[i].$cursor))throw Error("baobab.getIn: $cursor path must be an array.");n=e.get(r[i].$cursor),s=s[n]}else{if(!_.Array(s))return;s=f(s,r[i])}else s=s[r[i]]}return s}function y(t,r,e){var n,i,o,s=[],a=t;for(i=0,o=r.length;o>i;i++){if(!a)return null;if("function"==typeof r[i]){if(!_.Array(a))return;n=c(a,r[i]),s.push(n),a=a[n]}else if("object"==typeof r[i])if(e&&"$cursor"in r[i]){if(!_.Path(r[i].$cursor))throw Error("baobab.getIn: $cursor path must be an array.");p=e.get(r[i].$cursor),s.push(p),a=a[p]}else{if(!_.Array(a))return;n=d(a,r[i]),s.push(n),a=a[n]}else s.push(r[i]),a=a[r[i]]||{}}return s}function g(t,r){var e,n=t.length,i={},o=i;for(n||(i=r),e=0;n>e;e++)o[t[e]]=e+1===n?r:{},o=o[t[e]];return i}function m(t,r){t.super_=r;var e=function(){};e.prototype=r.prototype,t.prototype=new e,t.prototype.constructor=t}function v(t){this.size=t,this.records=[],this.add=function(r){for(this.records.unshift(r);this.records.length>t;)this.records.pop();return this},this.get=function(){return this.records}}var _=t("./type.js"),j=a.bind(null,!1),w=a.bind(null,!0);r.exports={archive:v,arrayOf:n,before:i,deepClone:w,shallowClone:j,shallowMerge:o,compose:h,getIn:b,inherits:m,pathObject:g,solvePath:y}}).call(this,"undefined"!=typeof global?global:"undefined"!=typeof self?self:"undefined"!=typeof window?window:{})},{"./type.js":10}],8:[function(t,r){function e(t,r,e){s.forEach(function(r){e!==r&&delete t[r]}),t[e]=r[e]}function n(t,r){var a,h=i.shallowClone(r||{});s.forEach(function(r){t[r]&&e(h,t,r)}),t.$chain&&(s.slice(0,-1).forEach(function(t){delete h[t]}),h.$apply=h.$apply?i.compose(h.$apply,t.$chain):t.$chain),t.$push&&h.$push?h.$push=o.Array(h.$push)?h.$push.concat(t.$push):[h.$push].concat(t.$push):t.$push&&(h.$push=t.$push),t.$unshift&&h.$unshift?h.$unshift=o.Array(t.$unshift)?t.$unshift.concat(h.$unshift):[t.$unshift].concat(h.$unshift):t.$unshift&&(h.$unshift=t.$unshift);for(a in t)o.Object(t[a])?h[a]=n(t[a],h[a]):"$"!==a[0]&&(h[a]=t[a]);return h}var i=t("./helpers.js"),o=t("./type.js"),s=["$unset","$set","$merge","$apply"];r.exports=n},{"./helpers.js":7,"./type.js":10}],9:[function(t,r){var e=t("./combination.js"),n=t("./type.js");r.exports={baobab:function(t){return{mixins:[{getInitialState:function(){if(this.tree=t,!this.cursor&&!this.cursors)return{};if(this.cursor&&this.cursors)throw Error("baobab.mixin: you cannot have both `component.cursor` and `component.cursors`. Please make up your mind.");if(this.__type=null,this.__updateHandler=function(){this.setState(this.__getCursorData())}.bind(this),this.cursor){if(!n.MixinCursor(this.cursor))throw Error("baobab.mixin.cursor: invalid data (cursor, string, array or function).");n.Function(this.cursor)&&(this.cursor=this.cursor()),n.Cursor(this.cursor)||(this.cursor=t.select(this.cursor)),this.__getCursorData=function(){return{cursor:this.cursor.get()}}.bind(this),this.__type="single"}else if(this.cursors){if(!n.MixinCursors(this.cursors))throw Error("baobab.mixin.cursor: invalid data (object, array or function).");if(n.Function(this.cursors)&&(this.cursors=this.cursors()),n.Array(this.cursors))this.cursors=this.cursors.map(function(r){return n.Cursor(r)?r:t.select(r)}),this.__getCursorData=function(){return{cursors:this.cursors.map(function(t){return t.get()})}}.bind(this),this.__type="array";else{for(var r in this.cursors)n.Cursor(this.cursors[r])||(this.cursors[r]=t.select(this.cursors[r]));this.__getCursorData=function(){var t={};for(r in this.cursors)t[r]=this.cursors[r].get();return{cursors:t}}.bind(this),this.__type="object"}}return this.__getCursorData()},componentDidMount:function(){"single"===this.__type?(this.__combination=new e("or",[this.cursor]),this.__combination.on("update",this.__updateHandler)):"array"===this.__type?(this.__combination=new e("or",this.cursors),this.__combination.on("update",this.__updateHandler)):"object"===this.__type&&(this.__combination=new e("or",Object.keys(this.cursors).map(function(t){return this.cursors[t]},this)),this.__combination.on("update",this.__updateHandler))},componentWillUnmount:function(){this.__combination&&this.__combination.release()}}].concat(t.options.mixins)}},cursor:function(t){return{mixins:[{getInitialState:function(){return this.cursor=t,this.__updateHandler=function(){this.setState({cursor:this.cursor.get()})}.bind(this),{cursor:this.cursor.get()}},componentDidMount:function(){this.cursor.on("update",this.__updateHandler)},componentWillUnmount:function(){this.cursor.off("update",this.__updateHandler)}}].concat(t.tree.options.mixins)}}}},{"./combination.js":5,"./type.js":10}],10:[function(t,r){function e(t,r){return r.some(function(r){return n[r](t)})}var n={};n.Array=function(t){return Array.isArray(t)},n.Object=function(t){return!Array.isArray(t)&&"object"==typeof t&&null!==t},n.String=function(t){return"string"==typeof t},n.Number=function(t){return"number"==typeof t},n.Function=function(t){return"function"==typeof t},n.Primitive=function(t){return"string"==typeof t||"number"==typeof t||"boolean"==typeof t},n.Date=function(t){return t instanceof Date},n.NonScalar=function(t){return n.Object(t)||n.Array(t)},n.Path=function(t){var r=["String","Number","Function","Object"];return n.Array(t)?t.every(function(t){return e(t,r)}):e(t,r)},n.MixinCursor=function(t){return e(t,["String","Number","Array","Function","Cursor"])},n.MixinCursors=function(t){return e(t,["Object","Array","Function"])},n.ComplexPath=function(t){return t.some(function(t){return e(t,["Object","Function"])})},r.exports=n},{}],11:[function(t,r){function e(t,r){var e=new Error("baobab.update: "+r+" at path /"+t.slice(1).join("/"));return e.path=t,e}var n=t("./helpers.js"),i=t("./type.js");r.exports=function(t,r,o){if(o=o||{},!i.Object(t)&&!i.Array(t))throw Error("baobab.update: invalid target.");var s={};t={root:n.shallowClone(t)};var a=function(t,r,o,h){o=o||["root"];var u,c,l,f=o.join("λ"),p=o[o.length-1],d=Object.keys(r).some(function(t){return!!~["$unset","$set","$apply","$merge","$push","$unshift"].indexOf(t)});if(d){s[f]=!0;for(c in r){if("$unset"===c){var b=o[o.length-2];i.Array(t)?h[b]=t.slice(0,+p).concat(t.slice(+p+1)):(h[b]=n.shallowClone(t),delete h[b][p]);break}if("$set"===c){l=r.$set,t[p]=l;break}if("$apply"===c){if(u=r.$apply,"function"!=typeof u)throw e(o,"using command $apply with a non function");t[p]=u.call(null,t[p]);break}if("$merge"===c){if(l=r.$merge,!i.Object(t[p])||!i.Object(l))throw e(o,"using command $merge with a non object");t[p]=n.shallowMerge(t[p],l);break}if("$push"===c){if(l=r.$push,!i.Array(t[p]))throw e(o,"using command $push to a non array");t[p]=t[p].concat(l)}if("$unshift"===c){if(l=r.$unshift,!i.Array(t[p]))throw e(o,"using command $unshift to a non array");t[p]=[].concat(l).concat(t[p])}}}else for(c in r)t[p][c]="undefined"==typeof t[p][c]?{}:n.shallowClone(t[p][c]),a(t[p],r[c],o.concat(c),t)};return a(t,r),{data:t.root,log:Object.keys(s).map(function(t){return t.split("λ").slice(1)})}}},{"./helpers.js":7,"./type.js":10}]},{},[2])(2)}); \ No newline at end of file diff --git a/src/cursor.js b/src/cursor.js index a8cab05..56d3a9f 100644 --- a/src/cursor.js +++ b/src/cursor.js @@ -50,24 +50,25 @@ function Cursor(tree, path, solvedPath, hash) { return self.emit('update'); // Checking update log to see whether the cursor should update. - outer: - for (i = 0, l = log.length; i < l; i++) { - c = log[i]; - - for (j = 0, m = c.length; j < m; j++) { - p = c[j]; - - // If path is not relevant to us, we break - if (p !== '' + self.solvedPath[j]) - break; - - // If we reached last item and we are relevant, we fire - if (j + 1 === m || j + 1 === self.solvedPath.length) { - shouldFire = true; - break outer; + if (self.solvedPath) + outer: + for (i = 0, l = log.length; i < l; i++) { + c = log[i]; + + for (j = 0, m = c.length; j < m; j++) { + p = c[j]; + + // If path is not relevant to us, we break + if (p !== '' + self.solvedPath[j]) + break; + + // If we reached last item and we are relevant, we fire + if (j + 1 === m || j + 1 === self.solvedPath.length) { + shouldFire = true; + break outer; + } } } - } // Handling relevancy var data = self.get() !== undefined; From 771921a451fa203fc5bea0d6bc80599857a3f181 Mon Sep 17 00:00:00 2001 From: Yomguithereal Date: Thu, 9 Apr 2015 18:33:05 +0200 Subject: [PATCH 33/73] Recording --- build/baobab.min.js | 2 +- src/cursor.js | 43 +++++++++++++++++++++++++++++++++++-------- src/helpers.js | 23 ++++++++++------------- test/suites/cursor.js | 33 ++++++++++++++++++++++++++++++++- 4 files changed, 78 insertions(+), 23 deletions(-) diff --git a/build/baobab.min.js b/build/baobab.min.js index 2ea1dd0..8150920 100644 --- a/build/baobab.min.js +++ b/build/baobab.min.js @@ -1,2 +1,2 @@ /* baobab.js - Version: 1.0.0-rc1 - Author: Yomguithereal (Guillaume Plique) */ -!function(t){if("object"==typeof exports&&"undefined"!=typeof module)module.exports=t();else if("function"==typeof define&&define.amd)define([],t);else{var r;r="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:this,r.Baobab=t()}}(function(){var t;return function r(t,e,n){function i(s,a){if(!e[s]){if(!t[s]){var h="function"==typeof require&&require;if(!a&&h)return h(s,!0);if(o)return o(s,!0);var u=new Error("Cannot find module '"+s+"'");throw u.code="MODULE_NOT_FOUND",u}var c=e[s]={exports:{}};t[s][0].call(c.exports,function(r){var e=t[s][1][r];return i(e?e:r)},c,c.exports,r,t,e,n)}return e[s].exports}for(var o="function"==typeof require&&require,s=0;sr;r++)n.push(t[r].handler);return n}var i={once:"boolean",scope:"object"},o=function(){this._enabled=!0,this._children=[],this._handlers={},this._handlersAll=[]};o.prototype.on=function(t,r,e){var n,s,a,h,u,c;if("function"==typeof r){for(u="string"==typeof t?[t]:t,n=0,s=u.length;n!==s;n+=1)if(h=u[n]){this._handlers[h]||(this._handlers[h]=[]),c={handler:r};for(a in e||{}){if(!i[a])throw new Error('The option "'+a+'" is not recognized by Emmett.');c[a]=e[a]}this._handlers[h].push(c)}}else if(t&&"object"==typeof t&&!Array.isArray(t))for(h in t)o.prototype.on.call(this,h,t[h],r);else{if("function"!=typeof t)throw new Error("Wrong arguments.");c={handler:t};for(a in e||{}){if(!i[a])throw new Error('The option "'+a+'" is not recognized by Emmett.');c[a]=e[a]}this._handlersAll.push(c)}return this},o.prototype.once=function(t,r,e){if("function"==typeof r)e=e||{},e.once=!0,this.on(t,r,e);else{if((!t||"object"!=typeof t||Array.isArray(t))&&"function"!=typeof t)throw new Error("Wrong arguments.");r=r||{},r.once=!0,this.on(t,r)}return this},o.prototype.off=function(t,r){var e,n,i,o,s,a,h,u="string"==typeof t?[t]:t;if(1===arguments.length&&"function"==typeof u){r=arguments[0];for(s in this._handlers){for(a=[],e=0,n=this._handlers[s].length;e!==n;e+=1)this._handlers[s][e].handler!==r&&a.push(this._handlers[s][e]);this._handlers[s]=a}for(a=[],e=0,n=this._handlersAll.length;e!==n;e+=1)this._handlersAll[e].handler!==r&&a.push(this._handlersAll[e]);this._handlersAll=a}else if(2===arguments.length)for(e=0,n=u.length;e!==n;e+=1){if(h=u[e],this._handlers[h]){for(a=[],i=0,o=this._handlers[h].length;i!==o;i+=1)this._handlers[h][i].handler!==r&&a.push(this._handlers[h][i]);this._handlers[h]=a}this._handlers[h]&&0===this._handlers[h].length&&delete this._handlers[h]}return this},o.prototype.unbindAll=function(){var t;this._handlersAll=[];for(t in this._handlers)delete this._handlers[t];return this},o.prototype.emit=function(t,r){var e,n,i,o,s,a,h,u,c,l,f="string"==typeof t?[t]:t;if(!this._enabled)return this;for(r=void 0===r?{}:r,e=0,n=f.length;e!==n;e+=1)if(l=f[e],c=(this._handlers[l]||[]).concat(this._handlersAll),c.length){for(h={type:l,data:r||{},target:this},a=[],i=0,o=c.length;i!==o;i+=1)(this._handlers[l]&&this._handlers[l].indexOf(c[i])>=0||this._handlersAll.indexOf(c[i])>=0)&&(c[i].handler.call("scope"in c[i]?c[i].scope:this,h),c[i].once&&a.push(c[i]));for(s=0;se;e++)if(t._children[e]===r){t._children.splice(e,1);break}}),this._children.push(r),r},o.prototype.listeners=function(t){var e,n,i,o=[];if(t)for(o=r(this._handlers[t]),n=0,i=this._children.length;i>n;n++)o=o.concat(this._children[n].listeners(t));else{o=r(this._handlersAll);for(e in this._handlers)o=o.concat(r(this._handlers[e]));for(n=0,i=this._children.length;i>n;n++)o=o.concat(this._children[n].listeners())}return o},o.prototype.kill=function(){if(this.emit("emmett:kill"),this.unbindAll(),this._handlers=null,this._handlersAll=null,this._enabled=!1,this._children)for(var t=0,r=this._children.length;r>t;t++)this._children[t].kill();this._children=null},o.prototype.disable=function(){return this._enabled=!1,this},o.prototype.enable=function(){return this._enabled=!0,this},o.version="2.1.2","undefined"!=typeof n?("undefined"!=typeof e&&e.exports&&(n=e.exports=o),n.Emitter=o):"function"==typeof t&&t.amd?t("emmett",[],function(){return o}):this.Emitter=o}).call(this)},{}],4:[function(t,r){function e(t){return t+"$"+(new Date).getTime()+(""+Math.random()).replace("0.","")}function n(t,r){function e(t){this[t]=function(){var r=this.root[t].apply(this.root,arguments);return r instanceof i?this:r}}if(arguments.length<1&&(t={}),!(this instanceof n))return new n(t,r);if(!l.Object(t)&&!l.Array(t))throw Error("Baobab: invalid data.");o.call(this),this.options=s.shallowMerge(c,r),this._transaction={},this._future=void 0,this._cursors={},this.data=s.deepClone(t),this.root=this.select([]),["get","set","unset","update"].forEach(e.bind(this)),this.mixin=u.baobab(this)}var i=t("./cursor.js"),o=t("emmett"),s=t("./helpers.js"),a=t("./update.js"),h=t("./merge.js"),u=t("./mixins.js"),c=t("../defaults.js"),l=t("./type.js");s.inherits(n,o),n.prototype.select=function(t){if(!t)throw Error("Baobab.select: invalid path.");if(arguments.length>1&&(t=s.arrayOf(arguments)),!l.Path(t))throw Error("Baobab.select: invalid path.");t=[].concat(t);var r,n=l.ComplexPath(t);n&&(r=s.solvePath(this.data,t,this));var o=t.map(function(t){return l.Function(t)?e("fn"):l.Object(t)?e("ob"):t}).join("λ");if(this._cursors[o])return this._cursors[o];var a=new i(this,t,r,o);return this._cursors[o]=a,a},n.prototype.stack=function(t){var r=this;if(!l.Object(t))throw Error("Baobab.update: wrong specification.");return this._transaction=h(t,this._transaction),this.options.autoCommit?this.options.asynchronous?(this._future||(this._future=setTimeout(r.commit.bind(r,null),0)),this):this.commit():this},n.prototype.commit=function(){var t=a(this.data,this._transaction,this.options),r=this.data;return this.data=t.data,this._transaction={},this._future&&(this._future=clearTimeout(this._future)),this.emit("update",{log:t.log,previousState:r}),this},n.prototype.release=function(){delete this.data,delete this._transaction;for(var t in this._cursors)this._cursors[t].release();delete this._cursors,this.kill()},n.prototype.toJSON=function(){return this.get()},r.exports=n},{"../defaults.js":1,"./cursor.js":6,"./helpers.js":7,"./merge.js":8,"./mixins.js":9,"./type.js":10,"./update.js":11,emmett:3}],5:[function(t,r){function e(t,r){r.on("update",t.cursorListener),t.tree.off("update",t.treeListener),t.tree.on("update",t.treeListener)}function n(t){var r=this;if(arguments.length<2)throw Error("baobab.Combination: not enough arguments.");var n=arguments[1],i=s.arrayOf(arguments).slice(2);if(n instanceof Array&&(i=n.slice(1),n=n[0]),!a.Cursor(n))throw Error("baobab.Combination: argument should be a cursor.");if("or"!==t&&"and"!==t)throw Error("baobab.Combination: invalid operator.");o.call(this),this.cursors=[n],this.operators=[],this.tree=n.tree,this.updates=new Array(this.cursors.length),this.cursorListener=function(){r.updates[r.cursors.indexOf(this)]=!0},this.treeListener=function(){var t,e,n=r.updates[0];for(t=1,e=r.cursors.length;e>t;t++)n="or"===r.operators[t-1]?n||r.updates[t]:n&&r.updates[t];n&&r.emit("update"),r.updates=new Array(r.cursors.length)},this.bound=!1;var h=(this.on,this.once,function(){r.bound||(r.bound=!0,r.cursors.forEach(function(t){e(r,t)}))});this.on=s.before(h,this.on.bind(this)),this.once=s.before(h,this.once.bind(this)),i.forEach(function(r){this[t](r)},this)}function i(t){n.prototype[t]=function(r){if(!a.Cursor(r))throw this.release(),Error("baobab.Combination."+t+": argument should be a cursor.");if(~this.cursors.indexOf(r))throw this.release(),Error("baobab.Combination."+t+": cursor already in combination.");return this.cursors.push(r),this.operators.push(t),this.updates.length++,this.bound&&e(this,r),this}}var o=t("emmett"),s=t("./helpers.js"),a=t("./type.js");s.inherits(n,o),i("or"),i("and"),n.prototype.release=function(){this.cursors.forEach(function(t){t.off("update",this.cursorListener)},this),this.tree.off("update",this.treeListener),this.cursors=null,this.operators=null,this.tree=null,this.updates=null,this.kill()},r.exports=n},{"./helpers.js":7,"./type.js":10,emmett:3}],6:[function(t,r){function e(t,r,e,n){var i=this;o.call(this),r=r||[],this.tree=t,this.path=r,this.hash=n,this.archive=null,this.complexPath=!!e,this.solvedPath=this.complexPath?e:this.path,this.relevant=void 0!==this.get(),this.updateHandler=function(t){var r,e,n,o,s,a,u=t.data.log,c=!1;if(i.complexPath&&(i.solvedPath=h.solvePath(i.tree.data,i.path,i.tree)),!i.path.length)return i.emit("update");if(i.solvedPath)t:for(s=0,n=u.length;n>s;s++)for(r=u[s],a=0,o=r.length;o>a&&(e=r[a],e===""+i.solvedPath[a]);a++)if(a+1===o||a+1===i.solvedPath.length){c=!0;break t}var l=void 0!==i.get();i.relevant?l&&c?i.emit("update"):l||(i.emit("irrelevant"),i.relevant=!1):l&&c&&(i.emit("relevant"),i.emit("update"),i.relevant=!0)},this.mixin=a.cursor(this);var s=!1,u=function(){s||(s=!0,i.tree.on("update",i.updateHandler))};this.on=h.before(u,this.on.bind(this)),this.once=h.before(u,this.once.bind(this))}function n(t,r,e,n){arguments.length<4&&(n=e,e=[]),e=e||[];var i=[].concat(e),o=h.solvePath(this.get(),i,this.tree);if(!o)throw Error("baobab.Cursor."+t+": could not solve dynamic path.");if(r){var s=this.get(o);if(!u[r](s))throw Error("baobab.Cursor."+t+": invalid target.")}var a={};a["$"+t]=n;var c=h.pathObject(o,a);return c}function i(t,r){e.prototype[t]=function(){var e=n.bind(this,t,r).apply(this,arguments);return this.update(e)}}var o=t("emmett"),s=t("./combination.js"),a=t("./mixins.js"),h=t("./helpers.js"),u=t("./type.js");h.inherits(e,o),e.prototype.isRoot=function(){return!this.path.length},e.prototype.isLeaf=function(){return u.Primitive(this.get())},e.prototype.isBranch=function(){return!this.isLeaf()&&!this.isRoot()},e.prototype.root=function(){return this.tree.root()},e.prototype.select=function(t){if(arguments.length>1&&(t=h.arrayOf(arguments)),!u.Path(t))throw Error("baobab.Cursor.select: invalid path.");return this.tree.select(this.path.concat(t))},e.prototype.up=function(){return this.solvedPath&&this.solvedPath.length?this.tree.select(this.path.slice(0,-1)):null},e.prototype.left=function(){var t=+this.solvedPath[this.solvedPath.length-1];if(isNaN(t))throw Error("baobab.Cursor.left: cannot go left on a non-list type.");return t?this.tree.select(this.solvedPath.slice(0,-1).concat(t-1)):null},e.prototype.leftmost=function(){var t=+this.solvedPath[this.solvedPath.length-1];if(isNaN(t))throw Error("baobab.Cursor.leftmost: cannot go left on a non-list type.");return this.tree.select(this.solvedPath.slice(0,-1).concat(0))},e.prototype.right=function(){var t=+this.solvedPath[this.solvedPath.length-1];if(isNaN(t))throw Error("baobab.Cursor.right: cannot go right on a non-list type.");return t+1===this.up().get().length?null:this.tree.select(this.solvedPath.slice(0,-1).concat(t+1))},e.prototype.rightmost=function(){var t=+this.solvedPath[this.solvedPath.length-1];if(isNaN(t))throw Error("baobab.Cursor.right: cannot go right on a non-list type.");var r=this.up().get();return this.tree.select(this.solvedPath.slice(0,-1).concat(r.length-1))},e.prototype.down=function(){+this.solvedPath[this.solvedPath.length-1];return this.get()instanceof Array?this.tree.select(this.solvedPath.concat(0)):null},e.prototype.get=function(t){arguments.length>1&&(t=h.arrayOf(arguments));var r=this.solvedPath.concat((u.String(t)||u.Number(t)?[t]:t)||[]);return h.getIn(this.tree.data,r,this.tree)},i("set"),i("apply"),i("chain"),i("push","Array"),i("unshift","Array"),e.prototype.merge=function(t){if(!u.Object(t))throw Error("baobab.Cursor.merge: trying to merge a non-object.");var r=n.bind(this,"merge","Object").apply(this,arguments);return this.update(r)},e.prototype.unset=function(t){if(void 0===t&&this.isRoot())throw Error("baobab.Cursor.unset: cannot remove root node.");var r=n.bind(this,"unset",null).apply(this,[t,!0]);return this.update(r)},e.prototype.update=function(t,r){if(arguments.length<2)return this.tree.stack(h.pathObject(this.solvedPath,t)),this;var e=[].concat(t),n=h.solvePath(this.get(),e,this.tree);if(!n)throw Error("baobab.Cursor.update: could not solve dynamic path.");return this.tree.stack(h.pathObject(this.solvedPath.concat(n),r)),this},e.prototype.or=function(t){return new s("or",this,t)},e.prototype.and=function(t){return new s("and",this,t)},e.prototype.startRecording=function(t){return this.archive?this:(this.archive=h.archive(t),this)},e.prototype.stopRecording=function(){return this.archive=null,this},e.prototype.undo=function(){},e.prototype.redo=function(){},e.prototype.isRecording=function(){return!!this.archive},e.prototype.hasHistory=function(){return!(!this.archive||!this.archive.records.length)},e.prototype.getHistory=function(){return this.archive.records},e.prototype.release=function(){this.tree.off("update",this.updateHandler),this.hash&&delete this.tree._cursors[this.hash],delete this.tree,delete this.path,delete this.solvedPath,this.kill()},e.prototype.toJSON=function(){return this.get()},u.Cursor=function(t){return t instanceof e},r.exports=e},{"./combination.js":5,"./helpers.js":7,"./mixins.js":9,"./type.js":10,emmett:3}],7:[function(t,r){(function(e){function n(t){return Array.prototype.slice.call(t)}function i(t,r){return function(){t(),r.apply(null,arguments)}}function o(t,r){var e,n={};for(e in t)n[e]=t[e];for(e in r)n[e]=r[e];return n}function s(t){var r=t.source,e="";return t.global&&(e+="g"),t.multiline&&(e+="m"),t.ignoreCase&&(e+="i"),t.sticky&&(e+="y"),t.unicode&&(e+="u"),new RegExp(r,e)}function a(t,r){if(!r||"object"!=typeof r||r instanceof Error||"ArrayBuffer"in e&&r instanceof ArrayBuffer)return r;if(_.Array(r)){if(t){var n,i,o=[];for(n=0,i=r.length;i>n;n++)o.push(w(r[n]));return o}return r.slice(0)}if(_.Date(r))return new Date(r.getTime());if(r instanceof RegExp)return s(r);if(_.Object(r)){var a,h={};r.constructor&&r.constructor!==Object&&(h=Object.create(r.constructor.prototype));for(a in r)r.hasOwnProperty(a)&&(h[a]=t?w(r[a]):r[a]);return h}return r}function h(t,r){return function(e){return r(t(e))}}function u(t,r){var e,n;for(e=0,n=t.length;n>e;e++)if(r(t[e]))return t[e]}function c(t,r){var e,n;for(e=0,n=t.length;n>e;e++)if(r(t[e]))return e;return-1}function l(t,r){var e,n=!0;if(!t)return!1;for(e in r)if(_.Object(r[e]))n=n&&l(t[e],r[e]);else if(_.Array(r[e]))n=n&&!!~r[e].indexOf(t[e]);else if(t[e]!==r[e])return!1;return n}function f(t,r){return u(t,function(t){return l(t,r)})}function d(t,r){return c(t,function(t){return l(t,r)})}function b(t,r,e){r=r||[];var n,i,o,s=t;for(i=0,o=r.length;o>i;i++){if(!s)return;if("function"==typeof r[i]){if(!_.Array(s))return;s=u(s,r[i])}else if("object"==typeof r[i])if(e&&"$cursor"in r[i]){if(!_.Path(r[i].$cursor))throw Error("baobab.getIn: $cursor path must be an array.");n=e.get(r[i].$cursor),s=s[n]}else{if(!_.Array(s))return;s=f(s,r[i])}else s=s[r[i]]}return s}function y(t,r,e){var n,i,o,s=[],a=t;for(i=0,o=r.length;o>i;i++){if(!a)return null;if("function"==typeof r[i]){if(!_.Array(a))return;n=c(a,r[i]),s.push(n),a=a[n]}else if("object"==typeof r[i])if(e&&"$cursor"in r[i]){if(!_.Path(r[i].$cursor))throw Error("baobab.getIn: $cursor path must be an array.");p=e.get(r[i].$cursor),s.push(p),a=a[p]}else{if(!_.Array(a))return;n=d(a,r[i]),s.push(n),a=a[n]}else s.push(r[i]),a=a[r[i]]||{}}return s}function g(t,r){var e,n=t.length,i={},o=i;for(n||(i=r),e=0;n>e;e++)o[t[e]]=e+1===n?r:{},o=o[t[e]];return i}function m(t,r){t.super_=r;var e=function(){};e.prototype=r.prototype,t.prototype=new e,t.prototype.constructor=t}function v(t){this.size=t,this.records=[],this.add=function(r){for(this.records.unshift(r);this.records.length>t;)this.records.pop();return this},this.get=function(){return this.records}}var _=t("./type.js"),j=a.bind(null,!1),w=a.bind(null,!0);r.exports={archive:v,arrayOf:n,before:i,deepClone:w,shallowClone:j,shallowMerge:o,compose:h,getIn:b,inherits:m,pathObject:g,solvePath:y}}).call(this,"undefined"!=typeof global?global:"undefined"!=typeof self?self:"undefined"!=typeof window?window:{})},{"./type.js":10}],8:[function(t,r){function e(t,r,e){s.forEach(function(r){e!==r&&delete t[r]}),t[e]=r[e]}function n(t,r){var a,h=i.shallowClone(r||{});s.forEach(function(r){t[r]&&e(h,t,r)}),t.$chain&&(s.slice(0,-1).forEach(function(t){delete h[t]}),h.$apply=h.$apply?i.compose(h.$apply,t.$chain):t.$chain),t.$push&&h.$push?h.$push=o.Array(h.$push)?h.$push.concat(t.$push):[h.$push].concat(t.$push):t.$push&&(h.$push=t.$push),t.$unshift&&h.$unshift?h.$unshift=o.Array(t.$unshift)?t.$unshift.concat(h.$unshift):[t.$unshift].concat(h.$unshift):t.$unshift&&(h.$unshift=t.$unshift);for(a in t)o.Object(t[a])?h[a]=n(t[a],h[a]):"$"!==a[0]&&(h[a]=t[a]);return h}var i=t("./helpers.js"),o=t("./type.js"),s=["$unset","$set","$merge","$apply"];r.exports=n},{"./helpers.js":7,"./type.js":10}],9:[function(t,r){var e=t("./combination.js"),n=t("./type.js");r.exports={baobab:function(t){return{mixins:[{getInitialState:function(){if(this.tree=t,!this.cursor&&!this.cursors)return{};if(this.cursor&&this.cursors)throw Error("baobab.mixin: you cannot have both `component.cursor` and `component.cursors`. Please make up your mind.");if(this.__type=null,this.__updateHandler=function(){this.setState(this.__getCursorData())}.bind(this),this.cursor){if(!n.MixinCursor(this.cursor))throw Error("baobab.mixin.cursor: invalid data (cursor, string, array or function).");n.Function(this.cursor)&&(this.cursor=this.cursor()),n.Cursor(this.cursor)||(this.cursor=t.select(this.cursor)),this.__getCursorData=function(){return{cursor:this.cursor.get()}}.bind(this),this.__type="single"}else if(this.cursors){if(!n.MixinCursors(this.cursors))throw Error("baobab.mixin.cursor: invalid data (object, array or function).");if(n.Function(this.cursors)&&(this.cursors=this.cursors()),n.Array(this.cursors))this.cursors=this.cursors.map(function(r){return n.Cursor(r)?r:t.select(r)}),this.__getCursorData=function(){return{cursors:this.cursors.map(function(t){return t.get()})}}.bind(this),this.__type="array";else{for(var r in this.cursors)n.Cursor(this.cursors[r])||(this.cursors[r]=t.select(this.cursors[r]));this.__getCursorData=function(){var t={};for(r in this.cursors)t[r]=this.cursors[r].get();return{cursors:t}}.bind(this),this.__type="object"}}return this.__getCursorData()},componentDidMount:function(){"single"===this.__type?(this.__combination=new e("or",[this.cursor]),this.__combination.on("update",this.__updateHandler)):"array"===this.__type?(this.__combination=new e("or",this.cursors),this.__combination.on("update",this.__updateHandler)):"object"===this.__type&&(this.__combination=new e("or",Object.keys(this.cursors).map(function(t){return this.cursors[t]},this)),this.__combination.on("update",this.__updateHandler))},componentWillUnmount:function(){this.__combination&&this.__combination.release()}}].concat(t.options.mixins)}},cursor:function(t){return{mixins:[{getInitialState:function(){return this.cursor=t,this.__updateHandler=function(){this.setState({cursor:this.cursor.get()})}.bind(this),{cursor:this.cursor.get()}},componentDidMount:function(){this.cursor.on("update",this.__updateHandler)},componentWillUnmount:function(){this.cursor.off("update",this.__updateHandler)}}].concat(t.tree.options.mixins)}}}},{"./combination.js":5,"./type.js":10}],10:[function(t,r){function e(t,r){return r.some(function(r){return n[r](t)})}var n={};n.Array=function(t){return Array.isArray(t)},n.Object=function(t){return!Array.isArray(t)&&"object"==typeof t&&null!==t},n.String=function(t){return"string"==typeof t},n.Number=function(t){return"number"==typeof t},n.Function=function(t){return"function"==typeof t},n.Primitive=function(t){return"string"==typeof t||"number"==typeof t||"boolean"==typeof t},n.Date=function(t){return t instanceof Date},n.NonScalar=function(t){return n.Object(t)||n.Array(t)},n.Path=function(t){var r=["String","Number","Function","Object"];return n.Array(t)?t.every(function(t){return e(t,r)}):e(t,r)},n.MixinCursor=function(t){return e(t,["String","Number","Array","Function","Cursor"])},n.MixinCursors=function(t){return e(t,["Object","Array","Function"])},n.ComplexPath=function(t){return t.some(function(t){return e(t,["Object","Function"])})},r.exports=n},{}],11:[function(t,r){function e(t,r){var e=new Error("baobab.update: "+r+" at path /"+t.slice(1).join("/"));return e.path=t,e}var n=t("./helpers.js"),i=t("./type.js");r.exports=function(t,r,o){if(o=o||{},!i.Object(t)&&!i.Array(t))throw Error("baobab.update: invalid target.");var s={};t={root:n.shallowClone(t)};var a=function(t,r,o,h){o=o||["root"];var u,c,l,f=o.join("λ"),p=o[o.length-1],d=Object.keys(r).some(function(t){return!!~["$unset","$set","$apply","$merge","$push","$unshift"].indexOf(t)});if(d){s[f]=!0;for(c in r){if("$unset"===c){var b=o[o.length-2];i.Array(t)?h[b]=t.slice(0,+p).concat(t.slice(+p+1)):(h[b]=n.shallowClone(t),delete h[b][p]);break}if("$set"===c){l=r.$set,t[p]=l;break}if("$apply"===c){if(u=r.$apply,"function"!=typeof u)throw e(o,"using command $apply with a non function");t[p]=u.call(null,t[p]);break}if("$merge"===c){if(l=r.$merge,!i.Object(t[p])||!i.Object(l))throw e(o,"using command $merge with a non object");t[p]=n.shallowMerge(t[p],l);break}if("$push"===c){if(l=r.$push,!i.Array(t[p]))throw e(o,"using command $push to a non array");t[p]=t[p].concat(l)}if("$unshift"===c){if(l=r.$unshift,!i.Array(t[p]))throw e(o,"using command $unshift to a non array");t[p]=[].concat(l).concat(t[p])}}}else for(c in r)t[p][c]="undefined"==typeof t[p][c]?{}:n.shallowClone(t[p][c]),a(t[p],r[c],o.concat(c),t)};return a(t,r),{data:t.root,log:Object.keys(s).map(function(t){return t.split("λ").slice(1)})}}},{"./helpers.js":7,"./type.js":10}]},{},[2])(2)}); \ No newline at end of file +!function(t){if("object"==typeof exports&&"undefined"!=typeof module)module.exports=t();else if("function"==typeof define&&define.amd)define([],t);else{var r;r="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:this,r.Baobab=t()}}(function(){var t;return function r(t,e,n){function i(s,a){if(!e[s]){if(!t[s]){var h="function"==typeof require&&require;if(!a&&h)return h(s,!0);if(o)return o(s,!0);var u=new Error("Cannot find module '"+s+"'");throw u.code="MODULE_NOT_FOUND",u}var c=e[s]={exports:{}};t[s][0].call(c.exports,function(r){var e=t[s][1][r];return i(e?e:r)},c,c.exports,r,t,e,n)}return e[s].exports}for(var o="function"==typeof require&&require,s=0;sr;r++)n.push(t[r].handler);return n}var i={once:"boolean",scope:"object"},o=function(){this._enabled=!0,this._children=[],this._handlers={},this._handlersAll=[]};o.prototype.on=function(t,r,e){var n,s,a,h,u,c;if("function"==typeof r){for(u="string"==typeof t?[t]:t,n=0,s=u.length;n!==s;n+=1)if(h=u[n]){this._handlers[h]||(this._handlers[h]=[]),c={handler:r};for(a in e||{}){if(!i[a])throw new Error('The option "'+a+'" is not recognized by Emmett.');c[a]=e[a]}this._handlers[h].push(c)}}else if(t&&"object"==typeof t&&!Array.isArray(t))for(h in t)o.prototype.on.call(this,h,t[h],r);else{if("function"!=typeof t)throw new Error("Wrong arguments.");c={handler:t};for(a in e||{}){if(!i[a])throw new Error('The option "'+a+'" is not recognized by Emmett.');c[a]=e[a]}this._handlersAll.push(c)}return this},o.prototype.once=function(t,r,e){if("function"==typeof r)e=e||{},e.once=!0,this.on(t,r,e);else{if((!t||"object"!=typeof t||Array.isArray(t))&&"function"!=typeof t)throw new Error("Wrong arguments.");r=r||{},r.once=!0,this.on(t,r)}return this},o.prototype.off=function(t,r){var e,n,i,o,s,a,h,u="string"==typeof t?[t]:t;if(1===arguments.length&&"function"==typeof u){r=arguments[0];for(s in this._handlers){for(a=[],e=0,n=this._handlers[s].length;e!==n;e+=1)this._handlers[s][e].handler!==r&&a.push(this._handlers[s][e]);this._handlers[s]=a}for(a=[],e=0,n=this._handlersAll.length;e!==n;e+=1)this._handlersAll[e].handler!==r&&a.push(this._handlersAll[e]);this._handlersAll=a}else if(2===arguments.length)for(e=0,n=u.length;e!==n;e+=1){if(h=u[e],this._handlers[h]){for(a=[],i=0,o=this._handlers[h].length;i!==o;i+=1)this._handlers[h][i].handler!==r&&a.push(this._handlers[h][i]);this._handlers[h]=a}this._handlers[h]&&0===this._handlers[h].length&&delete this._handlers[h]}return this},o.prototype.unbindAll=function(){var t;this._handlersAll=[];for(t in this._handlers)delete this._handlers[t];return this},o.prototype.emit=function(t,r){var e,n,i,o,s,a,h,u,c,l,f="string"==typeof t?[t]:t;if(!this._enabled)return this;for(r=void 0===r?{}:r,e=0,n=f.length;e!==n;e+=1)if(l=f[e],c=(this._handlers[l]||[]).concat(this._handlersAll),c.length){for(h={type:l,data:r||{},target:this},a=[],i=0,o=c.length;i!==o;i+=1)(this._handlers[l]&&this._handlers[l].indexOf(c[i])>=0||this._handlersAll.indexOf(c[i])>=0)&&(c[i].handler.call("scope"in c[i]?c[i].scope:this,h),c[i].once&&a.push(c[i]));for(s=0;se;e++)if(t._children[e]===r){t._children.splice(e,1);break}}),this._children.push(r),r},o.prototype.listeners=function(t){var e,n,i,o=[];if(t)for(o=r(this._handlers[t]),n=0,i=this._children.length;i>n;n++)o=o.concat(this._children[n].listeners(t));else{o=r(this._handlersAll);for(e in this._handlers)o=o.concat(r(this._handlers[e]));for(n=0,i=this._children.length;i>n;n++)o=o.concat(this._children[n].listeners())}return o},o.prototype.kill=function(){if(this.emit("emmett:kill"),this.unbindAll(),this._handlers=null,this._handlersAll=null,this._enabled=!1,this._children)for(var t=0,r=this._children.length;r>t;t++)this._children[t].kill();this._children=null},o.prototype.disable=function(){return this._enabled=!1,this},o.prototype.enable=function(){return this._enabled=!0,this},o.version="2.1.2","undefined"!=typeof n?("undefined"!=typeof e&&e.exports&&(n=e.exports=o),n.Emitter=o):"function"==typeof t&&t.amd?t("emmett",[],function(){return o}):this.Emitter=o}).call(this)},{}],4:[function(t,r){function e(t){return t+"$"+(new Date).getTime()+(""+Math.random()).replace("0.","")}function n(t,r){function e(t){this[t]=function(){var r=this.root[t].apply(this.root,arguments);return r instanceof i?this:r}}if(arguments.length<1&&(t={}),!(this instanceof n))return new n(t,r);if(!l.Object(t)&&!l.Array(t))throw Error("Baobab: invalid data.");o.call(this),this.options=s.shallowMerge(c,r),this._transaction={},this._future=void 0,this._cursors={},this.data=s.deepClone(t),this.root=this.select([]),["get","set","unset","update"].forEach(e.bind(this)),this.mixin=u.baobab(this)}var i=t("./cursor.js"),o=t("emmett"),s=t("./helpers.js"),a=t("./update.js"),h=t("./merge.js"),u=t("./mixins.js"),c=t("../defaults.js"),l=t("./type.js");s.inherits(n,o),n.prototype.select=function(t){if(!t)throw Error("Baobab.select: invalid path.");if(arguments.length>1&&(t=s.arrayOf(arguments)),!l.Path(t))throw Error("Baobab.select: invalid path.");t=[].concat(t);var r,n=l.ComplexPath(t);n&&(r=s.solvePath(this.data,t,this));var o=t.map(function(t){return l.Function(t)?e("fn"):l.Object(t)?e("ob"):t}).join("λ");if(this._cursors[o])return this._cursors[o];var a=new i(this,t,r,o);return this._cursors[o]=a,a},n.prototype.stack=function(t){var r=this;if(!l.Object(t))throw Error("Baobab.update: wrong specification.");return this._transaction=h(t,this._transaction),this.options.autoCommit?this.options.asynchronous?(this._future||(this._future=setTimeout(r.commit.bind(r,null),0)),this):this.commit():this},n.prototype.commit=function(){var t=a(this.data,this._transaction,this.options),r=this.data;return this.data=t.data,this._transaction={},this._future&&(this._future=clearTimeout(this._future)),this.emit("update",{log:t.log,previousState:r}),this},n.prototype.release=function(){delete this.data,delete this._transaction;for(var t in this._cursors)this._cursors[t].release();delete this._cursors,this.kill()},n.prototype.toJSON=function(){return this.get()},r.exports=n},{"../defaults.js":1,"./cursor.js":6,"./helpers.js":7,"./merge.js":8,"./mixins.js":9,"./type.js":10,"./update.js":11,emmett:3}],5:[function(t,r){function e(t,r){r.on("update",t.cursorListener),t.tree.off("update",t.treeListener),t.tree.on("update",t.treeListener)}function n(t){var r=this;if(arguments.length<2)throw Error("baobab.Combination: not enough arguments.");var n=arguments[1],i=s.arrayOf(arguments).slice(2);if(n instanceof Array&&(i=n.slice(1),n=n[0]),!a.Cursor(n))throw Error("baobab.Combination: argument should be a cursor.");if("or"!==t&&"and"!==t)throw Error("baobab.Combination: invalid operator.");o.call(this),this.cursors=[n],this.operators=[],this.tree=n.tree,this.updates=new Array(this.cursors.length),this.cursorListener=function(){r.updates[r.cursors.indexOf(this)]=!0},this.treeListener=function(){var t,e,n=r.updates[0];for(t=1,e=r.cursors.length;e>t;t++)n="or"===r.operators[t-1]?n||r.updates[t]:n&&r.updates[t];n&&r.emit("update"),r.updates=new Array(r.cursors.length)},this.bound=!1;var h=(this.on,this.once,function(){r.bound||(r.bound=!0,r.cursors.forEach(function(t){e(r,t)}))});this.on=s.before(h,this.on.bind(this)),this.once=s.before(h,this.once.bind(this)),i.forEach(function(r){this[t](r)},this)}function i(t){n.prototype[t]=function(r){if(!a.Cursor(r))throw this.release(),Error("baobab.Combination."+t+": argument should be a cursor.");if(~this.cursors.indexOf(r))throw this.release(),Error("baobab.Combination."+t+": cursor already in combination.");return this.cursors.push(r),this.operators.push(t),this.updates.length++,this.bound&&e(this,r),this}}var o=t("emmett"),s=t("./helpers.js"),a=t("./type.js");s.inherits(n,o),i("or"),i("and"),n.prototype.release=function(){this.cursors.forEach(function(t){t.off("update",this.cursorListener)},this),this.tree.off("update",this.treeListener),this.cursors=null,this.operators=null,this.tree=null,this.updates=null,this.kill()},r.exports=n},{"./helpers.js":7,"./type.js":10,emmett:3}],6:[function(t,r){function e(t,r,e,n){function i(t){if(s.isRecording()){var r=h.getIn(t,s.solvedPath,s.tree),e=h.deepClone(r);s.archive.add(e)}return s.emit("update")}var s=this;o.call(this),r=r||[],this.tree=t,this.path=r,this.hash=n,this.archive=null,this.complexPath=!!e,this.solvedPath=this.complexPath?e:this.path,this.relevant=void 0!==this.get(),this.updateHandler=function(t){var r,e,n,o,a,u,c=t.data.log,l=t.data.previousState,f=!1;if(s.complexPath&&(s.solvedPath=h.solvePath(s.tree.data,s.path,s.tree)),!s.path.length)return i(l);if(s.solvedPath)t:for(a=0,n=c.length;n>a;a++)for(r=c[a],u=0,o=r.length;o>u&&(e=r[u],e===""+s.solvedPath[u]);u++)if(u+1===o||u+1===s.solvedPath.length){f=!0;break t}var p=void 0!==s.get();s.relevant?p&&f?i(l):p||(s.emit("irrelevant"),s.relevant=!1):p&&f&&(s.emit("relevant"),i(l),s.relevant=!0)},this.mixin=a.cursor(this);var u=!1;this._lazyBind=function(){u||(u=!0,s.tree.on("update",s.updateHandler))},this.on=h.before(this._lazyBind,this.on.bind(this)),this.once=h.before(this._lazyBind,this.once.bind(this)),this.complexPath&&this._lazyBind()}function n(t,r,e,n){arguments.length<4&&(n=e,e=[]),e=e||[];var i=[].concat(e),o=h.solvePath(this.get(),i,this.tree);if(!o)throw Error("baobab.Cursor."+t+": could not solve dynamic path.");if(r){var s=this.get(o);if(!u[r](s))throw Error("baobab.Cursor."+t+": invalid target.")}var a={};a["$"+t]=n;var c=h.pathObject(o,a);return c}function i(t,r){e.prototype[t]=function(){var e=n.bind(this,t,r).apply(this,arguments);return this.update(e)}}var o=t("emmett"),s=t("./combination.js"),a=t("./mixins.js"),h=t("./helpers.js"),u=(t("../defaults.js"),t("./type.js"));h.inherits(e,o),e.prototype.isRoot=function(){return!this.path.length},e.prototype.isLeaf=function(){return u.Primitive(this.get())},e.prototype.isBranch=function(){return!this.isLeaf()&&!this.isRoot()},e.prototype.root=function(){return this.tree.root()},e.prototype.select=function(t){if(arguments.length>1&&(t=h.arrayOf(arguments)),!u.Path(t))throw Error("baobab.Cursor.select: invalid path.");return this.tree.select(this.path.concat(t))},e.prototype.up=function(){return this.solvedPath&&this.solvedPath.length?this.tree.select(this.path.slice(0,-1)):null},e.prototype.left=function(){var t=+this.solvedPath[this.solvedPath.length-1];if(isNaN(t))throw Error("baobab.Cursor.left: cannot go left on a non-list type.");return t?this.tree.select(this.solvedPath.slice(0,-1).concat(t-1)):null},e.prototype.leftmost=function(){var t=+this.solvedPath[this.solvedPath.length-1];if(isNaN(t))throw Error("baobab.Cursor.leftmost: cannot go left on a non-list type.");return this.tree.select(this.solvedPath.slice(0,-1).concat(0))},e.prototype.right=function(){var t=+this.solvedPath[this.solvedPath.length-1];if(isNaN(t))throw Error("baobab.Cursor.right: cannot go right on a non-list type.");return t+1===this.up().get().length?null:this.tree.select(this.solvedPath.slice(0,-1).concat(t+1))},e.prototype.rightmost=function(){var t=+this.solvedPath[this.solvedPath.length-1];if(isNaN(t))throw Error("baobab.Cursor.right: cannot go right on a non-list type.");var r=this.up().get();return this.tree.select(this.solvedPath.slice(0,-1).concat(r.length-1))},e.prototype.down=function(){+this.solvedPath[this.solvedPath.length-1];return this.get()instanceof Array?this.tree.select(this.solvedPath.concat(0)):null},e.prototype.get=function(t){arguments.length>1&&(t=h.arrayOf(arguments));var r=this.solvedPath.concat((u.String(t)||u.Number(t)?[t]:t)||[]);return h.getIn(this.tree.data,r,this.tree)},i("set"),i("apply"),i("chain"),i("push","Array"),i("unshift","Array"),e.prototype.merge=function(t){if(!u.Object(t))throw Error("baobab.Cursor.merge: trying to merge a non-object.");var r=n.bind(this,"merge","Object").apply(this,arguments);return this.update(r)},e.prototype.unset=function(t){if(void 0===t&&this.isRoot())throw Error("baobab.Cursor.unset: cannot remove root node.");var r=n.bind(this,"unset",null).apply(this,[t,!0]);return this.update(r)},e.prototype.update=function(t,r){if(arguments.length<2)return this.tree.stack(h.pathObject(this.solvedPath,t)),this;var e=[].concat(t),n=h.solvePath(this.get(),e,this.tree);if(!n)throw Error("baobab.Cursor.update: could not solve dynamic path.");return this.tree.stack(h.pathObject(this.solvedPath.concat(n),r)),this},e.prototype.or=function(t){return new s("or",this,t)},e.prototype.and=function(t){return new s("and",this,t)},e.prototype.startRecording=function(t){if(t=t||5,1>t)throw Error("baobab.Cursor.startRecording: invalid maximum number of records.");return this.archive?this:(this._lazyBind(),this.archive=h.archive(t),this)},e.prototype.stopRecording=function(){return this.archive=null,this},e.prototype.undo=function(){},e.prototype.redo=function(){},e.prototype.isRecording=function(){return!!this.archive},e.prototype.hasHistory=function(){return!(!this.archive||!this.archive.get().length)},e.prototype.getHistory=function(){return this.archive?this.archive.get():[]},e.prototype.release=function(){this.tree.off("update",this.updateHandler),this.hash&&delete this.tree._cursors[this.hash],delete this.tree,delete this.path,delete this.solvedPath,this.kill()},e.prototype.toJSON=function(){return this.get()},u.Cursor=function(t){return t instanceof e},r.exports=e},{"../defaults.js":1,"./combination.js":5,"./helpers.js":7,"./mixins.js":9,"./type.js":10,emmett:3}],7:[function(t,r){(function(e){function n(t){return Array.prototype.slice.call(t)}function i(t,r){return function(){t(),r.apply(null,arguments)}}function o(t,r){var e,n={};for(e in t)n[e]=t[e];for(e in r)n[e]=r[e];return n}function s(t){var r=t.source,e="";return t.global&&(e+="g"),t.multiline&&(e+="m"),t.ignoreCase&&(e+="i"),t.sticky&&(e+="y"),t.unicode&&(e+="u"),new RegExp(r,e)}function a(t,r){if(!r||"object"!=typeof r||r instanceof Error||"ArrayBuffer"in e&&r instanceof ArrayBuffer)return r;if(_.Array(r)){if(t){var n,i,o=[];for(n=0,i=r.length;i>n;n++)o.push(w(r[n]));return o}return r.slice(0)}if(_.Date(r))return new Date(r.getTime());if(r instanceof RegExp)return s(r);if(_.Object(r)){var a,h={};r.constructor&&r.constructor!==Object&&(h=Object.create(r.constructor.prototype));for(a in r)r.hasOwnProperty(a)&&(h[a]=t?w(r[a]):r[a]);return h}return r}function h(t,r){return function(e){return r(t(e))}}function u(t,r){var e,n;for(e=0,n=t.length;n>e;e++)if(r(t[e]))return t[e]}function c(t,r){var e,n;for(e=0,n=t.length;n>e;e++)if(r(t[e]))return e;return-1}function l(t,r){var e,n=!0;if(!t)return!1;for(e in r)if(_.Object(r[e]))n=n&&l(t[e],r[e]);else if(_.Array(r[e]))n=n&&!!~r[e].indexOf(t[e]);else if(t[e]!==r[e])return!1;return n}function f(t,r){return u(t,function(t){return l(t,r)})}function d(t,r){return c(t,function(t){return l(t,r)})}function b(t,r,e){r=r||[];var n,i,o,s=t;for(i=0,o=r.length;o>i;i++){if(!s)return;if("function"==typeof r[i]){if(!_.Array(s))return;s=u(s,r[i])}else if("object"==typeof r[i])if(e&&"$cursor"in r[i]){if(!_.Path(r[i].$cursor))throw Error("baobab.getIn: $cursor path must be an array.");n=e.get(r[i].$cursor),s=s[n]}else{if(!_.Array(s))return;s=f(s,r[i])}else s=s[r[i]]}return s}function y(t,r,e){var n,i,o,s=[],a=t;for(i=0,o=r.length;o>i;i++){if(!a)return null;if("function"==typeof r[i]){if(!_.Array(a))return;n=c(a,r[i]),s.push(n),a=a[n]}else if("object"==typeof r[i])if(e&&"$cursor"in r[i]){if(!_.Path(r[i].$cursor))throw Error("baobab.getIn: $cursor path must be an array.");p=e.get(r[i].$cursor),s.push(p),a=a[p]}else{if(!_.Array(a))return;n=d(a,r[i]),s.push(n),a=a[n]}else s.push(r[i]),a=a[r[i]]||{}}return s}function g(t,r){var e,n=t.length,i={},o=i;for(n||(i=r),e=0;n>e;e++)o[t[e]]=e+1===n?r:{},o=o[t[e]];return i}function m(t,r){t.super_=r;var e=function(){};e.prototype=r.prototype,t.prototype=new e,t.prototype.constructor=t}function v(t){var r=[];return{add:function(e){for(r.unshift(e);r.length>t;)r.pop()},get:function(){return r}}}var _=t("./type.js"),j=a.bind(null,!1),w=a.bind(null,!0);r.exports={archive:v,arrayOf:n,before:i,deepClone:w,shallowClone:j,shallowMerge:o,compose:h,getIn:b,inherits:m,pathObject:g,solvePath:y}}).call(this,"undefined"!=typeof global?global:"undefined"!=typeof self?self:"undefined"!=typeof window?window:{})},{"./type.js":10}],8:[function(t,r){function e(t,r,e){s.forEach(function(r){e!==r&&delete t[r]}),t[e]=r[e]}function n(t,r){var a,h=i.shallowClone(r||{});s.forEach(function(r){t[r]&&e(h,t,r)}),t.$chain&&(s.slice(0,-1).forEach(function(t){delete h[t]}),h.$apply=h.$apply?i.compose(h.$apply,t.$chain):t.$chain),t.$push&&h.$push?h.$push=o.Array(h.$push)?h.$push.concat(t.$push):[h.$push].concat(t.$push):t.$push&&(h.$push=t.$push),t.$unshift&&h.$unshift?h.$unshift=o.Array(t.$unshift)?t.$unshift.concat(h.$unshift):[t.$unshift].concat(h.$unshift):t.$unshift&&(h.$unshift=t.$unshift);for(a in t)o.Object(t[a])?h[a]=n(t[a],h[a]):"$"!==a[0]&&(h[a]=t[a]);return h}var i=t("./helpers.js"),o=t("./type.js"),s=["$unset","$set","$merge","$apply"];r.exports=n},{"./helpers.js":7,"./type.js":10}],9:[function(t,r){var e=t("./combination.js"),n=t("./type.js");r.exports={baobab:function(t){return{mixins:[{getInitialState:function(){if(this.tree=t,!this.cursor&&!this.cursors)return{};if(this.cursor&&this.cursors)throw Error("baobab.mixin: you cannot have both `component.cursor` and `component.cursors`. Please make up your mind.");if(this.__type=null,this.__updateHandler=function(){this.setState(this.__getCursorData())}.bind(this),this.cursor){if(!n.MixinCursor(this.cursor))throw Error("baobab.mixin.cursor: invalid data (cursor, string, array or function).");n.Function(this.cursor)&&(this.cursor=this.cursor()),n.Cursor(this.cursor)||(this.cursor=t.select(this.cursor)),this.__getCursorData=function(){return{cursor:this.cursor.get()}}.bind(this),this.__type="single"}else if(this.cursors){if(!n.MixinCursors(this.cursors))throw Error("baobab.mixin.cursor: invalid data (object, array or function).");if(n.Function(this.cursors)&&(this.cursors=this.cursors()),n.Array(this.cursors))this.cursors=this.cursors.map(function(r){return n.Cursor(r)?r:t.select(r)}),this.__getCursorData=function(){return{cursors:this.cursors.map(function(t){return t.get()})}}.bind(this),this.__type="array";else{for(var r in this.cursors)n.Cursor(this.cursors[r])||(this.cursors[r]=t.select(this.cursors[r]));this.__getCursorData=function(){var t={};for(r in this.cursors)t[r]=this.cursors[r].get();return{cursors:t}}.bind(this),this.__type="object"}}return this.__getCursorData()},componentDidMount:function(){"single"===this.__type?(this.__combination=new e("or",[this.cursor]),this.__combination.on("update",this.__updateHandler)):"array"===this.__type?(this.__combination=new e("or",this.cursors),this.__combination.on("update",this.__updateHandler)):"object"===this.__type&&(this.__combination=new e("or",Object.keys(this.cursors).map(function(t){return this.cursors[t]},this)),this.__combination.on("update",this.__updateHandler))},componentWillUnmount:function(){this.__combination&&this.__combination.release()}}].concat(t.options.mixins)}},cursor:function(t){return{mixins:[{getInitialState:function(){return this.cursor=t,this.__updateHandler=function(){this.setState({cursor:this.cursor.get()})}.bind(this),{cursor:this.cursor.get()}},componentDidMount:function(){this.cursor.on("update",this.__updateHandler)},componentWillUnmount:function(){this.cursor.off("update",this.__updateHandler)}}].concat(t.tree.options.mixins)}}}},{"./combination.js":5,"./type.js":10}],10:[function(t,r){function e(t,r){return r.some(function(r){return n[r](t)})}var n={};n.Array=function(t){return Array.isArray(t)},n.Object=function(t){return!Array.isArray(t)&&"object"==typeof t&&null!==t},n.String=function(t){return"string"==typeof t},n.Number=function(t){return"number"==typeof t},n.Function=function(t){return"function"==typeof t},n.Primitive=function(t){return"string"==typeof t||"number"==typeof t||"boolean"==typeof t},n.Date=function(t){return t instanceof Date},n.NonScalar=function(t){return n.Object(t)||n.Array(t)},n.Path=function(t){var r=["String","Number","Function","Object"];return n.Array(t)?t.every(function(t){return e(t,r)}):e(t,r)},n.MixinCursor=function(t){return e(t,["String","Number","Array","Function","Cursor"])},n.MixinCursors=function(t){return e(t,["Object","Array","Function"])},n.ComplexPath=function(t){return t.some(function(t){return e(t,["Object","Function"])})},r.exports=n},{}],11:[function(t,r){function e(t,r){var e=new Error("baobab.update: "+r+" at path /"+t.slice(1).join("/"));return e.path=t,e}var n=t("./helpers.js"),i=t("./type.js");r.exports=function(t,r,o){if(o=o||{},!i.Object(t)&&!i.Array(t))throw Error("baobab.update: invalid target.");var s={};t={root:n.shallowClone(t)};var a=function(t,r,o,h){o=o||["root"];var u,c,l,f=o.join("λ"),p=o[o.length-1],d=Object.keys(r).some(function(t){return!!~["$unset","$set","$apply","$merge","$push","$unshift"].indexOf(t)});if(d){s[f]=!0;for(c in r){if("$unset"===c){var b=o[o.length-2];i.Array(t)?h[b]=t.slice(0,+p).concat(t.slice(+p+1)):(h[b]=n.shallowClone(t),delete h[b][p]);break}if("$set"===c){l=r.$set,t[p]=l;break}if("$apply"===c){if(u=r.$apply,"function"!=typeof u)throw e(o,"using command $apply with a non function");t[p]=u.call(null,t[p]);break}if("$merge"===c){if(l=r.$merge,!i.Object(t[p])||!i.Object(l))throw e(o,"using command $merge with a non object");t[p]=n.shallowMerge(t[p],l);break}if("$push"===c){if(l=r.$push,!i.Array(t[p]))throw e(o,"using command $push to a non array");t[p]=t[p].concat(l)}if("$unshift"===c){if(l=r.$unshift,!i.Array(t[p]))throw e(o,"using command $unshift to a non array");t[p]=[].concat(l).concat(t[p])}}}else for(c in r)t[p][c]="undefined"==typeof t[p][c]?{}:n.shallowClone(t[p][c]),a(t[p],r[c],o.concat(c),t)};return a(t,r),{data:t.root,log:Object.keys(s).map(function(t){return t.split("λ").slice(1)})}}},{"./helpers.js":7,"./type.js":10}]},{},[2])(2)}); \ No newline at end of file diff --git a/src/cursor.js b/src/cursor.js index 56d3a9f..bd66d96 100644 --- a/src/cursor.js +++ b/src/cursor.js @@ -8,6 +8,7 @@ var EventEmitter = require('emmett'), Combination = require('./combination.js'), mixins = require('./mixins.js'), helpers = require('./helpers.js'), + defaults = require('../defaults.js'), type = require('./type.js'); /** @@ -36,8 +37,22 @@ function Cursor(tree, path, solvedPath, hash) { this.relevant = this.get() !== undefined; // Root listeners + function update(previousState) { + if (self.isRecording()) { + + // Handle archive + var data = helpers.getIn(previousState, self.solvedPath, self.tree), + record = helpers.deepClone(data); + + self.archive.add(record); + } + + return self.emit('update'); + } + this.updateHandler = function(e) { var log = e.data.log, + previousState = e.data.previousState, shouldFire = false, c, p, l, m, i, j; @@ -47,7 +62,7 @@ function Cursor(tree, path, solvedPath, hash) { // If selector listens at tree, we fire if (!self.path.length) - return self.emit('update'); + return update(previousState); // Checking update log to see whether the cursor should update. if (self.solvedPath) @@ -75,7 +90,7 @@ function Cursor(tree, path, solvedPath, hash) { if (self.relevant) { if (data && shouldFire) { - self.emit('update'); + update(previousState); } else if (!data) { self.emit('irrelevant'); @@ -85,7 +100,7 @@ function Cursor(tree, path, solvedPath, hash) { else { if (data && shouldFire) { self.emit('relevant'); - self.emit('update'); + update(previousState); self.relevant = true; } } @@ -97,15 +112,18 @@ function Cursor(tree, path, solvedPath, hash) { // Lazy binding var bound = false; - var lazyBind = function() { + this._lazyBind = function() { if (bound) return; bound = true; self.tree.on('update', self.updateHandler); }; - this.on = helpers.before(lazyBind, this.on.bind(this)); - this.once = helpers.before(lazyBind, this.once.bind(this)); + this.on = helpers.before(this._lazyBind, this.on.bind(this)); + this.once = helpers.before(this._lazyBind, this.once.bind(this)); + + if (this.complexPath) + this._lazyBind(); } helpers.inherits(Cursor, EventEmitter); @@ -310,8 +328,17 @@ Cursor.prototype.and = function(otherCursor) { * History */ Cursor.prototype.startRecording = function(maxRecords) { + maxRecords = maxRecords || 5; + + if (maxRecords < 1) + throw Error('baobab.Cursor.startRecording: invalid maximum number of records.'); + if (this.archive) return this; + + // Lazy bind + this._lazyBind(); + this.archive = helpers.archive(maxRecords); return this; }; @@ -334,11 +361,11 @@ Cursor.prototype.isRecording = function() { }; Cursor.prototype.hasHistory = function() { - return !!(this.archive && this.archive.records.length); + return !!(this.archive && this.archive.get().length); }; Cursor.prototype.getHistory = function() { - return this.archive.records; + return this.archive ? this.archive.get() : []; }; /** diff --git a/src/helpers.js b/src/helpers.js index eabe9e2..eb2c58f 100644 --- a/src/helpers.js +++ b/src/helpers.js @@ -280,21 +280,18 @@ function inherits(ctor, superCtor) { // Archive function archive(size) { - this.size = size; - this.records = []; + var records = []; - // Adding a record - this.add = function(record) { - this.records.unshift(record); + return { + add: function(record) { + records.unshift(record); - while (this.records.length > size) - this.records.pop(); - return this; - }; - - // Getting record data - this.get = function() { - return this.records; + while(records.length > size) + records.pop(); + }, + get: function() { + return records; + } }; } diff --git a/test/suites/cursor.js b/test/suites/cursor.js index 4f4718a..80f6ff5 100644 --- a/test/suites/cursor.js +++ b/test/suites/cursor.js @@ -6,7 +6,8 @@ var assert = require('assert'), state = require('../state.js'), helpers = require('../../src/helpers.js'), Baobab = require('../../src/baobab.js'), - async = require('async'); + async = require('async'), + _ = require('lodash'); describe('Cursor API', function() { @@ -495,6 +496,36 @@ describe('Cursor API', function() { }); }); + describe('History', function() { + + it('should be possible to record updates.', function() { + var baobab = new Baobab({item: 1}, {asynchronous: false}), + cursor = baobab.select('item'); + + assert(!cursor.isRecording()); + assert(!cursor.hasHistory()); + assert.deepEqual(cursor.getHistory(), []); + + cursor.startRecording(); + + assert(cursor.isRecording()); + + _.range(6).forEach(function() { + cursor.apply(function(e) { return e + 1; }); + }); + + assert(cursor.hasHistory()); + assert.strictEqual(cursor.get(), 7); + assert.deepEqual(cursor.getHistory(), [2, 3, 4, 5, 6].reverse()); + + cursor.stopRecording(); + + assert(!cursor.isRecording()); + assert(!cursor.hasHistory()); + assert.deepEqual(cursor.getHistory(), []); + }); + }); + describe('Advanced', function() { it('should be possible to execute several orders within a single stack.', function(done) { var baobab = new Baobab({ From 4543e8e09ea69e130d5fa6a41c2e20ad75f7e645 Mon Sep 17 00:00:00 2001 From: Yomguithereal Date: Thu, 9 Apr 2015 18:37:56 +0200 Subject: [PATCH 34/73] =?UTF-8?q?Silly=20|=CE=BB|=3F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- build/baobab.min.js | 2 +- src/baobab.js | 2 +- src/update.js | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/build/baobab.min.js b/build/baobab.min.js index 8150920..752b85d 100644 --- a/build/baobab.min.js +++ b/build/baobab.min.js @@ -1,2 +1,2 @@ /* baobab.js - Version: 1.0.0-rc1 - Author: Yomguithereal (Guillaume Plique) */ -!function(t){if("object"==typeof exports&&"undefined"!=typeof module)module.exports=t();else if("function"==typeof define&&define.amd)define([],t);else{var r;r="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:this,r.Baobab=t()}}(function(){var t;return function r(t,e,n){function i(s,a){if(!e[s]){if(!t[s]){var h="function"==typeof require&&require;if(!a&&h)return h(s,!0);if(o)return o(s,!0);var u=new Error("Cannot find module '"+s+"'");throw u.code="MODULE_NOT_FOUND",u}var c=e[s]={exports:{}};t[s][0].call(c.exports,function(r){var e=t[s][1][r];return i(e?e:r)},c,c.exports,r,t,e,n)}return e[s].exports}for(var o="function"==typeof require&&require,s=0;sr;r++)n.push(t[r].handler);return n}var i={once:"boolean",scope:"object"},o=function(){this._enabled=!0,this._children=[],this._handlers={},this._handlersAll=[]};o.prototype.on=function(t,r,e){var n,s,a,h,u,c;if("function"==typeof r){for(u="string"==typeof t?[t]:t,n=0,s=u.length;n!==s;n+=1)if(h=u[n]){this._handlers[h]||(this._handlers[h]=[]),c={handler:r};for(a in e||{}){if(!i[a])throw new Error('The option "'+a+'" is not recognized by Emmett.');c[a]=e[a]}this._handlers[h].push(c)}}else if(t&&"object"==typeof t&&!Array.isArray(t))for(h in t)o.prototype.on.call(this,h,t[h],r);else{if("function"!=typeof t)throw new Error("Wrong arguments.");c={handler:t};for(a in e||{}){if(!i[a])throw new Error('The option "'+a+'" is not recognized by Emmett.');c[a]=e[a]}this._handlersAll.push(c)}return this},o.prototype.once=function(t,r,e){if("function"==typeof r)e=e||{},e.once=!0,this.on(t,r,e);else{if((!t||"object"!=typeof t||Array.isArray(t))&&"function"!=typeof t)throw new Error("Wrong arguments.");r=r||{},r.once=!0,this.on(t,r)}return this},o.prototype.off=function(t,r){var e,n,i,o,s,a,h,u="string"==typeof t?[t]:t;if(1===arguments.length&&"function"==typeof u){r=arguments[0];for(s in this._handlers){for(a=[],e=0,n=this._handlers[s].length;e!==n;e+=1)this._handlers[s][e].handler!==r&&a.push(this._handlers[s][e]);this._handlers[s]=a}for(a=[],e=0,n=this._handlersAll.length;e!==n;e+=1)this._handlersAll[e].handler!==r&&a.push(this._handlersAll[e]);this._handlersAll=a}else if(2===arguments.length)for(e=0,n=u.length;e!==n;e+=1){if(h=u[e],this._handlers[h]){for(a=[],i=0,o=this._handlers[h].length;i!==o;i+=1)this._handlers[h][i].handler!==r&&a.push(this._handlers[h][i]);this._handlers[h]=a}this._handlers[h]&&0===this._handlers[h].length&&delete this._handlers[h]}return this},o.prototype.unbindAll=function(){var t;this._handlersAll=[];for(t in this._handlers)delete this._handlers[t];return this},o.prototype.emit=function(t,r){var e,n,i,o,s,a,h,u,c,l,f="string"==typeof t?[t]:t;if(!this._enabled)return this;for(r=void 0===r?{}:r,e=0,n=f.length;e!==n;e+=1)if(l=f[e],c=(this._handlers[l]||[]).concat(this._handlersAll),c.length){for(h={type:l,data:r||{},target:this},a=[],i=0,o=c.length;i!==o;i+=1)(this._handlers[l]&&this._handlers[l].indexOf(c[i])>=0||this._handlersAll.indexOf(c[i])>=0)&&(c[i].handler.call("scope"in c[i]?c[i].scope:this,h),c[i].once&&a.push(c[i]));for(s=0;se;e++)if(t._children[e]===r){t._children.splice(e,1);break}}),this._children.push(r),r},o.prototype.listeners=function(t){var e,n,i,o=[];if(t)for(o=r(this._handlers[t]),n=0,i=this._children.length;i>n;n++)o=o.concat(this._children[n].listeners(t));else{o=r(this._handlersAll);for(e in this._handlers)o=o.concat(r(this._handlers[e]));for(n=0,i=this._children.length;i>n;n++)o=o.concat(this._children[n].listeners())}return o},o.prototype.kill=function(){if(this.emit("emmett:kill"),this.unbindAll(),this._handlers=null,this._handlersAll=null,this._enabled=!1,this._children)for(var t=0,r=this._children.length;r>t;t++)this._children[t].kill();this._children=null},o.prototype.disable=function(){return this._enabled=!1,this},o.prototype.enable=function(){return this._enabled=!0,this},o.version="2.1.2","undefined"!=typeof n?("undefined"!=typeof e&&e.exports&&(n=e.exports=o),n.Emitter=o):"function"==typeof t&&t.amd?t("emmett",[],function(){return o}):this.Emitter=o}).call(this)},{}],4:[function(t,r){function e(t){return t+"$"+(new Date).getTime()+(""+Math.random()).replace("0.","")}function n(t,r){function e(t){this[t]=function(){var r=this.root[t].apply(this.root,arguments);return r instanceof i?this:r}}if(arguments.length<1&&(t={}),!(this instanceof n))return new n(t,r);if(!l.Object(t)&&!l.Array(t))throw Error("Baobab: invalid data.");o.call(this),this.options=s.shallowMerge(c,r),this._transaction={},this._future=void 0,this._cursors={},this.data=s.deepClone(t),this.root=this.select([]),["get","set","unset","update"].forEach(e.bind(this)),this.mixin=u.baobab(this)}var i=t("./cursor.js"),o=t("emmett"),s=t("./helpers.js"),a=t("./update.js"),h=t("./merge.js"),u=t("./mixins.js"),c=t("../defaults.js"),l=t("./type.js");s.inherits(n,o),n.prototype.select=function(t){if(!t)throw Error("Baobab.select: invalid path.");if(arguments.length>1&&(t=s.arrayOf(arguments)),!l.Path(t))throw Error("Baobab.select: invalid path.");t=[].concat(t);var r,n=l.ComplexPath(t);n&&(r=s.solvePath(this.data,t,this));var o=t.map(function(t){return l.Function(t)?e("fn"):l.Object(t)?e("ob"):t}).join("λ");if(this._cursors[o])return this._cursors[o];var a=new i(this,t,r,o);return this._cursors[o]=a,a},n.prototype.stack=function(t){var r=this;if(!l.Object(t))throw Error("Baobab.update: wrong specification.");return this._transaction=h(t,this._transaction),this.options.autoCommit?this.options.asynchronous?(this._future||(this._future=setTimeout(r.commit.bind(r,null),0)),this):this.commit():this},n.prototype.commit=function(){var t=a(this.data,this._transaction,this.options),r=this.data;return this.data=t.data,this._transaction={},this._future&&(this._future=clearTimeout(this._future)),this.emit("update",{log:t.log,previousState:r}),this},n.prototype.release=function(){delete this.data,delete this._transaction;for(var t in this._cursors)this._cursors[t].release();delete this._cursors,this.kill()},n.prototype.toJSON=function(){return this.get()},r.exports=n},{"../defaults.js":1,"./cursor.js":6,"./helpers.js":7,"./merge.js":8,"./mixins.js":9,"./type.js":10,"./update.js":11,emmett:3}],5:[function(t,r){function e(t,r){r.on("update",t.cursorListener),t.tree.off("update",t.treeListener),t.tree.on("update",t.treeListener)}function n(t){var r=this;if(arguments.length<2)throw Error("baobab.Combination: not enough arguments.");var n=arguments[1],i=s.arrayOf(arguments).slice(2);if(n instanceof Array&&(i=n.slice(1),n=n[0]),!a.Cursor(n))throw Error("baobab.Combination: argument should be a cursor.");if("or"!==t&&"and"!==t)throw Error("baobab.Combination: invalid operator.");o.call(this),this.cursors=[n],this.operators=[],this.tree=n.tree,this.updates=new Array(this.cursors.length),this.cursorListener=function(){r.updates[r.cursors.indexOf(this)]=!0},this.treeListener=function(){var t,e,n=r.updates[0];for(t=1,e=r.cursors.length;e>t;t++)n="or"===r.operators[t-1]?n||r.updates[t]:n&&r.updates[t];n&&r.emit("update"),r.updates=new Array(r.cursors.length)},this.bound=!1;var h=(this.on,this.once,function(){r.bound||(r.bound=!0,r.cursors.forEach(function(t){e(r,t)}))});this.on=s.before(h,this.on.bind(this)),this.once=s.before(h,this.once.bind(this)),i.forEach(function(r){this[t](r)},this)}function i(t){n.prototype[t]=function(r){if(!a.Cursor(r))throw this.release(),Error("baobab.Combination."+t+": argument should be a cursor.");if(~this.cursors.indexOf(r))throw this.release(),Error("baobab.Combination."+t+": cursor already in combination.");return this.cursors.push(r),this.operators.push(t),this.updates.length++,this.bound&&e(this,r),this}}var o=t("emmett"),s=t("./helpers.js"),a=t("./type.js");s.inherits(n,o),i("or"),i("and"),n.prototype.release=function(){this.cursors.forEach(function(t){t.off("update",this.cursorListener)},this),this.tree.off("update",this.treeListener),this.cursors=null,this.operators=null,this.tree=null,this.updates=null,this.kill()},r.exports=n},{"./helpers.js":7,"./type.js":10,emmett:3}],6:[function(t,r){function e(t,r,e,n){function i(t){if(s.isRecording()){var r=h.getIn(t,s.solvedPath,s.tree),e=h.deepClone(r);s.archive.add(e)}return s.emit("update")}var s=this;o.call(this),r=r||[],this.tree=t,this.path=r,this.hash=n,this.archive=null,this.complexPath=!!e,this.solvedPath=this.complexPath?e:this.path,this.relevant=void 0!==this.get(),this.updateHandler=function(t){var r,e,n,o,a,u,c=t.data.log,l=t.data.previousState,f=!1;if(s.complexPath&&(s.solvedPath=h.solvePath(s.tree.data,s.path,s.tree)),!s.path.length)return i(l);if(s.solvedPath)t:for(a=0,n=c.length;n>a;a++)for(r=c[a],u=0,o=r.length;o>u&&(e=r[u],e===""+s.solvedPath[u]);u++)if(u+1===o||u+1===s.solvedPath.length){f=!0;break t}var p=void 0!==s.get();s.relevant?p&&f?i(l):p||(s.emit("irrelevant"),s.relevant=!1):p&&f&&(s.emit("relevant"),i(l),s.relevant=!0)},this.mixin=a.cursor(this);var u=!1;this._lazyBind=function(){u||(u=!0,s.tree.on("update",s.updateHandler))},this.on=h.before(this._lazyBind,this.on.bind(this)),this.once=h.before(this._lazyBind,this.once.bind(this)),this.complexPath&&this._lazyBind()}function n(t,r,e,n){arguments.length<4&&(n=e,e=[]),e=e||[];var i=[].concat(e),o=h.solvePath(this.get(),i,this.tree);if(!o)throw Error("baobab.Cursor."+t+": could not solve dynamic path.");if(r){var s=this.get(o);if(!u[r](s))throw Error("baobab.Cursor."+t+": invalid target.")}var a={};a["$"+t]=n;var c=h.pathObject(o,a);return c}function i(t,r){e.prototype[t]=function(){var e=n.bind(this,t,r).apply(this,arguments);return this.update(e)}}var o=t("emmett"),s=t("./combination.js"),a=t("./mixins.js"),h=t("./helpers.js"),u=(t("../defaults.js"),t("./type.js"));h.inherits(e,o),e.prototype.isRoot=function(){return!this.path.length},e.prototype.isLeaf=function(){return u.Primitive(this.get())},e.prototype.isBranch=function(){return!this.isLeaf()&&!this.isRoot()},e.prototype.root=function(){return this.tree.root()},e.prototype.select=function(t){if(arguments.length>1&&(t=h.arrayOf(arguments)),!u.Path(t))throw Error("baobab.Cursor.select: invalid path.");return this.tree.select(this.path.concat(t))},e.prototype.up=function(){return this.solvedPath&&this.solvedPath.length?this.tree.select(this.path.slice(0,-1)):null},e.prototype.left=function(){var t=+this.solvedPath[this.solvedPath.length-1];if(isNaN(t))throw Error("baobab.Cursor.left: cannot go left on a non-list type.");return t?this.tree.select(this.solvedPath.slice(0,-1).concat(t-1)):null},e.prototype.leftmost=function(){var t=+this.solvedPath[this.solvedPath.length-1];if(isNaN(t))throw Error("baobab.Cursor.leftmost: cannot go left on a non-list type.");return this.tree.select(this.solvedPath.slice(0,-1).concat(0))},e.prototype.right=function(){var t=+this.solvedPath[this.solvedPath.length-1];if(isNaN(t))throw Error("baobab.Cursor.right: cannot go right on a non-list type.");return t+1===this.up().get().length?null:this.tree.select(this.solvedPath.slice(0,-1).concat(t+1))},e.prototype.rightmost=function(){var t=+this.solvedPath[this.solvedPath.length-1];if(isNaN(t))throw Error("baobab.Cursor.right: cannot go right on a non-list type.");var r=this.up().get();return this.tree.select(this.solvedPath.slice(0,-1).concat(r.length-1))},e.prototype.down=function(){+this.solvedPath[this.solvedPath.length-1];return this.get()instanceof Array?this.tree.select(this.solvedPath.concat(0)):null},e.prototype.get=function(t){arguments.length>1&&(t=h.arrayOf(arguments));var r=this.solvedPath.concat((u.String(t)||u.Number(t)?[t]:t)||[]);return h.getIn(this.tree.data,r,this.tree)},i("set"),i("apply"),i("chain"),i("push","Array"),i("unshift","Array"),e.prototype.merge=function(t){if(!u.Object(t))throw Error("baobab.Cursor.merge: trying to merge a non-object.");var r=n.bind(this,"merge","Object").apply(this,arguments);return this.update(r)},e.prototype.unset=function(t){if(void 0===t&&this.isRoot())throw Error("baobab.Cursor.unset: cannot remove root node.");var r=n.bind(this,"unset",null).apply(this,[t,!0]);return this.update(r)},e.prototype.update=function(t,r){if(arguments.length<2)return this.tree.stack(h.pathObject(this.solvedPath,t)),this;var e=[].concat(t),n=h.solvePath(this.get(),e,this.tree);if(!n)throw Error("baobab.Cursor.update: could not solve dynamic path.");return this.tree.stack(h.pathObject(this.solvedPath.concat(n),r)),this},e.prototype.or=function(t){return new s("or",this,t)},e.prototype.and=function(t){return new s("and",this,t)},e.prototype.startRecording=function(t){if(t=t||5,1>t)throw Error("baobab.Cursor.startRecording: invalid maximum number of records.");return this.archive?this:(this._lazyBind(),this.archive=h.archive(t),this)},e.prototype.stopRecording=function(){return this.archive=null,this},e.prototype.undo=function(){},e.prototype.redo=function(){},e.prototype.isRecording=function(){return!!this.archive},e.prototype.hasHistory=function(){return!(!this.archive||!this.archive.get().length)},e.prototype.getHistory=function(){return this.archive?this.archive.get():[]},e.prototype.release=function(){this.tree.off("update",this.updateHandler),this.hash&&delete this.tree._cursors[this.hash],delete this.tree,delete this.path,delete this.solvedPath,this.kill()},e.prototype.toJSON=function(){return this.get()},u.Cursor=function(t){return t instanceof e},r.exports=e},{"../defaults.js":1,"./combination.js":5,"./helpers.js":7,"./mixins.js":9,"./type.js":10,emmett:3}],7:[function(t,r){(function(e){function n(t){return Array.prototype.slice.call(t)}function i(t,r){return function(){t(),r.apply(null,arguments)}}function o(t,r){var e,n={};for(e in t)n[e]=t[e];for(e in r)n[e]=r[e];return n}function s(t){var r=t.source,e="";return t.global&&(e+="g"),t.multiline&&(e+="m"),t.ignoreCase&&(e+="i"),t.sticky&&(e+="y"),t.unicode&&(e+="u"),new RegExp(r,e)}function a(t,r){if(!r||"object"!=typeof r||r instanceof Error||"ArrayBuffer"in e&&r instanceof ArrayBuffer)return r;if(_.Array(r)){if(t){var n,i,o=[];for(n=0,i=r.length;i>n;n++)o.push(w(r[n]));return o}return r.slice(0)}if(_.Date(r))return new Date(r.getTime());if(r instanceof RegExp)return s(r);if(_.Object(r)){var a,h={};r.constructor&&r.constructor!==Object&&(h=Object.create(r.constructor.prototype));for(a in r)r.hasOwnProperty(a)&&(h[a]=t?w(r[a]):r[a]);return h}return r}function h(t,r){return function(e){return r(t(e))}}function u(t,r){var e,n;for(e=0,n=t.length;n>e;e++)if(r(t[e]))return t[e]}function c(t,r){var e,n;for(e=0,n=t.length;n>e;e++)if(r(t[e]))return e;return-1}function l(t,r){var e,n=!0;if(!t)return!1;for(e in r)if(_.Object(r[e]))n=n&&l(t[e],r[e]);else if(_.Array(r[e]))n=n&&!!~r[e].indexOf(t[e]);else if(t[e]!==r[e])return!1;return n}function f(t,r){return u(t,function(t){return l(t,r)})}function d(t,r){return c(t,function(t){return l(t,r)})}function b(t,r,e){r=r||[];var n,i,o,s=t;for(i=0,o=r.length;o>i;i++){if(!s)return;if("function"==typeof r[i]){if(!_.Array(s))return;s=u(s,r[i])}else if("object"==typeof r[i])if(e&&"$cursor"in r[i]){if(!_.Path(r[i].$cursor))throw Error("baobab.getIn: $cursor path must be an array.");n=e.get(r[i].$cursor),s=s[n]}else{if(!_.Array(s))return;s=f(s,r[i])}else s=s[r[i]]}return s}function y(t,r,e){var n,i,o,s=[],a=t;for(i=0,o=r.length;o>i;i++){if(!a)return null;if("function"==typeof r[i]){if(!_.Array(a))return;n=c(a,r[i]),s.push(n),a=a[n]}else if("object"==typeof r[i])if(e&&"$cursor"in r[i]){if(!_.Path(r[i].$cursor))throw Error("baobab.getIn: $cursor path must be an array.");p=e.get(r[i].$cursor),s.push(p),a=a[p]}else{if(!_.Array(a))return;n=d(a,r[i]),s.push(n),a=a[n]}else s.push(r[i]),a=a[r[i]]||{}}return s}function g(t,r){var e,n=t.length,i={},o=i;for(n||(i=r),e=0;n>e;e++)o[t[e]]=e+1===n?r:{},o=o[t[e]];return i}function m(t,r){t.super_=r;var e=function(){};e.prototype=r.prototype,t.prototype=new e,t.prototype.constructor=t}function v(t){var r=[];return{add:function(e){for(r.unshift(e);r.length>t;)r.pop()},get:function(){return r}}}var _=t("./type.js"),j=a.bind(null,!1),w=a.bind(null,!0);r.exports={archive:v,arrayOf:n,before:i,deepClone:w,shallowClone:j,shallowMerge:o,compose:h,getIn:b,inherits:m,pathObject:g,solvePath:y}}).call(this,"undefined"!=typeof global?global:"undefined"!=typeof self?self:"undefined"!=typeof window?window:{})},{"./type.js":10}],8:[function(t,r){function e(t,r,e){s.forEach(function(r){e!==r&&delete t[r]}),t[e]=r[e]}function n(t,r){var a,h=i.shallowClone(r||{});s.forEach(function(r){t[r]&&e(h,t,r)}),t.$chain&&(s.slice(0,-1).forEach(function(t){delete h[t]}),h.$apply=h.$apply?i.compose(h.$apply,t.$chain):t.$chain),t.$push&&h.$push?h.$push=o.Array(h.$push)?h.$push.concat(t.$push):[h.$push].concat(t.$push):t.$push&&(h.$push=t.$push),t.$unshift&&h.$unshift?h.$unshift=o.Array(t.$unshift)?t.$unshift.concat(h.$unshift):[t.$unshift].concat(h.$unshift):t.$unshift&&(h.$unshift=t.$unshift);for(a in t)o.Object(t[a])?h[a]=n(t[a],h[a]):"$"!==a[0]&&(h[a]=t[a]);return h}var i=t("./helpers.js"),o=t("./type.js"),s=["$unset","$set","$merge","$apply"];r.exports=n},{"./helpers.js":7,"./type.js":10}],9:[function(t,r){var e=t("./combination.js"),n=t("./type.js");r.exports={baobab:function(t){return{mixins:[{getInitialState:function(){if(this.tree=t,!this.cursor&&!this.cursors)return{};if(this.cursor&&this.cursors)throw Error("baobab.mixin: you cannot have both `component.cursor` and `component.cursors`. Please make up your mind.");if(this.__type=null,this.__updateHandler=function(){this.setState(this.__getCursorData())}.bind(this),this.cursor){if(!n.MixinCursor(this.cursor))throw Error("baobab.mixin.cursor: invalid data (cursor, string, array or function).");n.Function(this.cursor)&&(this.cursor=this.cursor()),n.Cursor(this.cursor)||(this.cursor=t.select(this.cursor)),this.__getCursorData=function(){return{cursor:this.cursor.get()}}.bind(this),this.__type="single"}else if(this.cursors){if(!n.MixinCursors(this.cursors))throw Error("baobab.mixin.cursor: invalid data (object, array or function).");if(n.Function(this.cursors)&&(this.cursors=this.cursors()),n.Array(this.cursors))this.cursors=this.cursors.map(function(r){return n.Cursor(r)?r:t.select(r)}),this.__getCursorData=function(){return{cursors:this.cursors.map(function(t){return t.get()})}}.bind(this),this.__type="array";else{for(var r in this.cursors)n.Cursor(this.cursors[r])||(this.cursors[r]=t.select(this.cursors[r]));this.__getCursorData=function(){var t={};for(r in this.cursors)t[r]=this.cursors[r].get();return{cursors:t}}.bind(this),this.__type="object"}}return this.__getCursorData()},componentDidMount:function(){"single"===this.__type?(this.__combination=new e("or",[this.cursor]),this.__combination.on("update",this.__updateHandler)):"array"===this.__type?(this.__combination=new e("or",this.cursors),this.__combination.on("update",this.__updateHandler)):"object"===this.__type&&(this.__combination=new e("or",Object.keys(this.cursors).map(function(t){return this.cursors[t]},this)),this.__combination.on("update",this.__updateHandler))},componentWillUnmount:function(){this.__combination&&this.__combination.release()}}].concat(t.options.mixins)}},cursor:function(t){return{mixins:[{getInitialState:function(){return this.cursor=t,this.__updateHandler=function(){this.setState({cursor:this.cursor.get()})}.bind(this),{cursor:this.cursor.get()}},componentDidMount:function(){this.cursor.on("update",this.__updateHandler)},componentWillUnmount:function(){this.cursor.off("update",this.__updateHandler)}}].concat(t.tree.options.mixins)}}}},{"./combination.js":5,"./type.js":10}],10:[function(t,r){function e(t,r){return r.some(function(r){return n[r](t)})}var n={};n.Array=function(t){return Array.isArray(t)},n.Object=function(t){return!Array.isArray(t)&&"object"==typeof t&&null!==t},n.String=function(t){return"string"==typeof t},n.Number=function(t){return"number"==typeof t},n.Function=function(t){return"function"==typeof t},n.Primitive=function(t){return"string"==typeof t||"number"==typeof t||"boolean"==typeof t},n.Date=function(t){return t instanceof Date},n.NonScalar=function(t){return n.Object(t)||n.Array(t)},n.Path=function(t){var r=["String","Number","Function","Object"];return n.Array(t)?t.every(function(t){return e(t,r)}):e(t,r)},n.MixinCursor=function(t){return e(t,["String","Number","Array","Function","Cursor"])},n.MixinCursors=function(t){return e(t,["Object","Array","Function"])},n.ComplexPath=function(t){return t.some(function(t){return e(t,["Object","Function"])})},r.exports=n},{}],11:[function(t,r){function e(t,r){var e=new Error("baobab.update: "+r+" at path /"+t.slice(1).join("/"));return e.path=t,e}var n=t("./helpers.js"),i=t("./type.js");r.exports=function(t,r,o){if(o=o||{},!i.Object(t)&&!i.Array(t))throw Error("baobab.update: invalid target.");var s={};t={root:n.shallowClone(t)};var a=function(t,r,o,h){o=o||["root"];var u,c,l,f=o.join("λ"),p=o[o.length-1],d=Object.keys(r).some(function(t){return!!~["$unset","$set","$apply","$merge","$push","$unshift"].indexOf(t)});if(d){s[f]=!0;for(c in r){if("$unset"===c){var b=o[o.length-2];i.Array(t)?h[b]=t.slice(0,+p).concat(t.slice(+p+1)):(h[b]=n.shallowClone(t),delete h[b][p]);break}if("$set"===c){l=r.$set,t[p]=l;break}if("$apply"===c){if(u=r.$apply,"function"!=typeof u)throw e(o,"using command $apply with a non function");t[p]=u.call(null,t[p]);break}if("$merge"===c){if(l=r.$merge,!i.Object(t[p])||!i.Object(l))throw e(o,"using command $merge with a non object");t[p]=n.shallowMerge(t[p],l);break}if("$push"===c){if(l=r.$push,!i.Array(t[p]))throw e(o,"using command $push to a non array");t[p]=t[p].concat(l)}if("$unshift"===c){if(l=r.$unshift,!i.Array(t[p]))throw e(o,"using command $unshift to a non array");t[p]=[].concat(l).concat(t[p])}}}else for(c in r)t[p][c]="undefined"==typeof t[p][c]?{}:n.shallowClone(t[p][c]),a(t[p],r[c],o.concat(c),t)};return a(t,r),{data:t.root,log:Object.keys(s).map(function(t){return t.split("λ").slice(1)})}}},{"./helpers.js":7,"./type.js":10}]},{},[2])(2)}); \ No newline at end of file +!function(t){if("object"==typeof exports&&"undefined"!=typeof module)module.exports=t();else if("function"==typeof define&&define.amd)define([],t);else{var r;r="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:this,r.Baobab=t()}}(function(){var t;return function r(t,e,n){function i(s,a){if(!e[s]){if(!t[s]){var h="function"==typeof require&&require;if(!a&&h)return h(s,!0);if(o)return o(s,!0);var u=new Error("Cannot find module '"+s+"'");throw u.code="MODULE_NOT_FOUND",u}var c=e[s]={exports:{}};t[s][0].call(c.exports,function(r){var e=t[s][1][r];return i(e?e:r)},c,c.exports,r,t,e,n)}return e[s].exports}for(var o="function"==typeof require&&require,s=0;sr;r++)n.push(t[r].handler);return n}var i={once:"boolean",scope:"object"},o=function(){this._enabled=!0,this._children=[],this._handlers={},this._handlersAll=[]};o.prototype.on=function(t,r,e){var n,s,a,h,u,c;if("function"==typeof r){for(u="string"==typeof t?[t]:t,n=0,s=u.length;n!==s;n+=1)if(h=u[n]){this._handlers[h]||(this._handlers[h]=[]),c={handler:r};for(a in e||{}){if(!i[a])throw new Error('The option "'+a+'" is not recognized by Emmett.');c[a]=e[a]}this._handlers[h].push(c)}}else if(t&&"object"==typeof t&&!Array.isArray(t))for(h in t)o.prototype.on.call(this,h,t[h],r);else{if("function"!=typeof t)throw new Error("Wrong arguments.");c={handler:t};for(a in e||{}){if(!i[a])throw new Error('The option "'+a+'" is not recognized by Emmett.');c[a]=e[a]}this._handlersAll.push(c)}return this},o.prototype.once=function(t,r,e){if("function"==typeof r)e=e||{},e.once=!0,this.on(t,r,e);else{if((!t||"object"!=typeof t||Array.isArray(t))&&"function"!=typeof t)throw new Error("Wrong arguments.");r=r||{},r.once=!0,this.on(t,r)}return this},o.prototype.off=function(t,r){var e,n,i,o,s,a,h,u="string"==typeof t?[t]:t;if(1===arguments.length&&"function"==typeof u){r=arguments[0];for(s in this._handlers){for(a=[],e=0,n=this._handlers[s].length;e!==n;e+=1)this._handlers[s][e].handler!==r&&a.push(this._handlers[s][e]);this._handlers[s]=a}for(a=[],e=0,n=this._handlersAll.length;e!==n;e+=1)this._handlersAll[e].handler!==r&&a.push(this._handlersAll[e]);this._handlersAll=a}else if(2===arguments.length)for(e=0,n=u.length;e!==n;e+=1){if(h=u[e],this._handlers[h]){for(a=[],i=0,o=this._handlers[h].length;i!==o;i+=1)this._handlers[h][i].handler!==r&&a.push(this._handlers[h][i]);this._handlers[h]=a}this._handlers[h]&&0===this._handlers[h].length&&delete this._handlers[h]}return this},o.prototype.unbindAll=function(){var t;this._handlersAll=[];for(t in this._handlers)delete this._handlers[t];return this},o.prototype.emit=function(t,r){var e,n,i,o,s,a,h,u,c,l,f="string"==typeof t?[t]:t;if(!this._enabled)return this;for(r=void 0===r?{}:r,e=0,n=f.length;e!==n;e+=1)if(l=f[e],c=(this._handlers[l]||[]).concat(this._handlersAll),c.length){for(h={type:l,data:r||{},target:this},a=[],i=0,o=c.length;i!==o;i+=1)(this._handlers[l]&&this._handlers[l].indexOf(c[i])>=0||this._handlersAll.indexOf(c[i])>=0)&&(c[i].handler.call("scope"in c[i]?c[i].scope:this,h),c[i].once&&a.push(c[i]));for(s=0;se;e++)if(t._children[e]===r){t._children.splice(e,1);break}}),this._children.push(r),r},o.prototype.listeners=function(t){var e,n,i,o=[];if(t)for(o=r(this._handlers[t]),n=0,i=this._children.length;i>n;n++)o=o.concat(this._children[n].listeners(t));else{o=r(this._handlersAll);for(e in this._handlers)o=o.concat(r(this._handlers[e]));for(n=0,i=this._children.length;i>n;n++)o=o.concat(this._children[n].listeners())}return o},o.prototype.kill=function(){if(this.emit("emmett:kill"),this.unbindAll(),this._handlers=null,this._handlersAll=null,this._enabled=!1,this._children)for(var t=0,r=this._children.length;r>t;t++)this._children[t].kill();this._children=null},o.prototype.disable=function(){return this._enabled=!1,this},o.prototype.enable=function(){return this._enabled=!0,this},o.version="2.1.2","undefined"!=typeof n?("undefined"!=typeof e&&e.exports&&(n=e.exports=o),n.Emitter=o):"function"==typeof t&&t.amd?t("emmett",[],function(){return o}):this.Emitter=o}).call(this)},{}],4:[function(t,r){function e(t){return t+"$"+(new Date).getTime()+(""+Math.random()).replace("0.","")}function n(t,r){function e(t){this[t]=function(){var r=this.root[t].apply(this.root,arguments);return r instanceof i?this:r}}if(arguments.length<1&&(t={}),!(this instanceof n))return new n(t,r);if(!l.Object(t)&&!l.Array(t))throw Error("Baobab: invalid data.");o.call(this),this.options=s.shallowMerge(c,r),this._transaction={},this._future=void 0,this._cursors={},this.data=s.deepClone(t),this.root=this.select([]),["get","set","unset","update"].forEach(e.bind(this)),this.mixin=u.baobab(this)}var i=t("./cursor.js"),o=t("emmett"),s=t("./helpers.js"),a=t("./update.js"),h=t("./merge.js"),u=t("./mixins.js"),c=t("../defaults.js"),l=t("./type.js");s.inherits(n,o),n.prototype.select=function(t){if(!t)throw Error("Baobab.select: invalid path.");if(arguments.length>1&&(t=s.arrayOf(arguments)),!l.Path(t))throw Error("Baobab.select: invalid path.");t=[].concat(t);var r,n=l.ComplexPath(t);n&&(r=s.solvePath(this.data,t,this));var o=t.map(function(t){return l.Function(t)?e("fn"):l.Object(t)?e("ob"):t}).join("|λ|");if(this._cursors[o])return this._cursors[o];var a=new i(this,t,r,o);return this._cursors[o]=a,a},n.prototype.stack=function(t){var r=this;if(!l.Object(t))throw Error("Baobab.update: wrong specification.");return this._transaction=h(t,this._transaction),this.options.autoCommit?this.options.asynchronous?(this._future||(this._future=setTimeout(r.commit.bind(r,null),0)),this):this.commit():this},n.prototype.commit=function(){var t=a(this.data,this._transaction,this.options),r=this.data;return this.data=t.data,this._transaction={},this._future&&(this._future=clearTimeout(this._future)),this.emit("update",{log:t.log,previousState:r}),this},n.prototype.release=function(){delete this.data,delete this._transaction;for(var t in this._cursors)this._cursors[t].release();delete this._cursors,this.kill()},n.prototype.toJSON=function(){return this.get()},r.exports=n},{"../defaults.js":1,"./cursor.js":6,"./helpers.js":7,"./merge.js":8,"./mixins.js":9,"./type.js":10,"./update.js":11,emmett:3}],5:[function(t,r){function e(t,r){r.on("update",t.cursorListener),t.tree.off("update",t.treeListener),t.tree.on("update",t.treeListener)}function n(t){var r=this;if(arguments.length<2)throw Error("baobab.Combination: not enough arguments.");var n=arguments[1],i=s.arrayOf(arguments).slice(2);if(n instanceof Array&&(i=n.slice(1),n=n[0]),!a.Cursor(n))throw Error("baobab.Combination: argument should be a cursor.");if("or"!==t&&"and"!==t)throw Error("baobab.Combination: invalid operator.");o.call(this),this.cursors=[n],this.operators=[],this.tree=n.tree,this.updates=new Array(this.cursors.length),this.cursorListener=function(){r.updates[r.cursors.indexOf(this)]=!0},this.treeListener=function(){var t,e,n=r.updates[0];for(t=1,e=r.cursors.length;e>t;t++)n="or"===r.operators[t-1]?n||r.updates[t]:n&&r.updates[t];n&&r.emit("update"),r.updates=new Array(r.cursors.length)},this.bound=!1;var h=(this.on,this.once,function(){r.bound||(r.bound=!0,r.cursors.forEach(function(t){e(r,t)}))});this.on=s.before(h,this.on.bind(this)),this.once=s.before(h,this.once.bind(this)),i.forEach(function(r){this[t](r)},this)}function i(t){n.prototype[t]=function(r){if(!a.Cursor(r))throw this.release(),Error("baobab.Combination."+t+": argument should be a cursor.");if(~this.cursors.indexOf(r))throw this.release(),Error("baobab.Combination."+t+": cursor already in combination.");return this.cursors.push(r),this.operators.push(t),this.updates.length++,this.bound&&e(this,r),this}}var o=t("emmett"),s=t("./helpers.js"),a=t("./type.js");s.inherits(n,o),i("or"),i("and"),n.prototype.release=function(){this.cursors.forEach(function(t){t.off("update",this.cursorListener)},this),this.tree.off("update",this.treeListener),this.cursors=null,this.operators=null,this.tree=null,this.updates=null,this.kill()},r.exports=n},{"./helpers.js":7,"./type.js":10,emmett:3}],6:[function(t,r){function e(t,r,e,n){function i(t){if(s.isRecording()){var r=h.getIn(t,s.solvedPath,s.tree),e=h.deepClone(r);s.archive.add(e)}return s.emit("update")}var s=this;o.call(this),r=r||[],this.tree=t,this.path=r,this.hash=n,this.archive=null,this.complexPath=!!e,this.solvedPath=this.complexPath?e:this.path,this.relevant=void 0!==this.get(),this.updateHandler=function(t){var r,e,n,o,a,u,c=t.data.log,l=t.data.previousState,f=!1;if(s.complexPath&&(s.solvedPath=h.solvePath(s.tree.data,s.path,s.tree)),!s.path.length)return i(l);if(s.solvedPath)t:for(a=0,n=c.length;n>a;a++)for(r=c[a],u=0,o=r.length;o>u&&(e=r[u],e===""+s.solvedPath[u]);u++)if(u+1===o||u+1===s.solvedPath.length){f=!0;break t}var p=void 0!==s.get();s.relevant?p&&f?i(l):p||(s.emit("irrelevant"),s.relevant=!1):p&&f&&(s.emit("relevant"),i(l),s.relevant=!0)},this.mixin=a.cursor(this);var u=!1;this._lazyBind=function(){u||(u=!0,s.tree.on("update",s.updateHandler))},this.on=h.before(this._lazyBind,this.on.bind(this)),this.once=h.before(this._lazyBind,this.once.bind(this)),this.complexPath&&this._lazyBind()}function n(t,r,e,n){arguments.length<4&&(n=e,e=[]),e=e||[];var i=[].concat(e),o=h.solvePath(this.get(),i,this.tree);if(!o)throw Error("baobab.Cursor."+t+": could not solve dynamic path.");if(r){var s=this.get(o);if(!u[r](s))throw Error("baobab.Cursor."+t+": invalid target.")}var a={};a["$"+t]=n;var c=h.pathObject(o,a);return c}function i(t,r){e.prototype[t]=function(){var e=n.bind(this,t,r).apply(this,arguments);return this.update(e)}}var o=t("emmett"),s=t("./combination.js"),a=t("./mixins.js"),h=t("./helpers.js"),u=(t("../defaults.js"),t("./type.js"));h.inherits(e,o),e.prototype.isRoot=function(){return!this.path.length},e.prototype.isLeaf=function(){return u.Primitive(this.get())},e.prototype.isBranch=function(){return!this.isLeaf()&&!this.isRoot()},e.prototype.root=function(){return this.tree.root()},e.prototype.select=function(t){if(arguments.length>1&&(t=h.arrayOf(arguments)),!u.Path(t))throw Error("baobab.Cursor.select: invalid path.");return this.tree.select(this.path.concat(t))},e.prototype.up=function(){return this.solvedPath&&this.solvedPath.length?this.tree.select(this.path.slice(0,-1)):null},e.prototype.left=function(){var t=+this.solvedPath[this.solvedPath.length-1];if(isNaN(t))throw Error("baobab.Cursor.left: cannot go left on a non-list type.");return t?this.tree.select(this.solvedPath.slice(0,-1).concat(t-1)):null},e.prototype.leftmost=function(){var t=+this.solvedPath[this.solvedPath.length-1];if(isNaN(t))throw Error("baobab.Cursor.leftmost: cannot go left on a non-list type.");return this.tree.select(this.solvedPath.slice(0,-1).concat(0))},e.prototype.right=function(){var t=+this.solvedPath[this.solvedPath.length-1];if(isNaN(t))throw Error("baobab.Cursor.right: cannot go right on a non-list type.");return t+1===this.up().get().length?null:this.tree.select(this.solvedPath.slice(0,-1).concat(t+1))},e.prototype.rightmost=function(){var t=+this.solvedPath[this.solvedPath.length-1];if(isNaN(t))throw Error("baobab.Cursor.right: cannot go right on a non-list type.");var r=this.up().get();return this.tree.select(this.solvedPath.slice(0,-1).concat(r.length-1))},e.prototype.down=function(){+this.solvedPath[this.solvedPath.length-1];return this.get()instanceof Array?this.tree.select(this.solvedPath.concat(0)):null},e.prototype.get=function(t){arguments.length>1&&(t=h.arrayOf(arguments));var r=this.solvedPath.concat((u.String(t)||u.Number(t)?[t]:t)||[]);return h.getIn(this.tree.data,r,this.tree)},i("set"),i("apply"),i("chain"),i("push","Array"),i("unshift","Array"),e.prototype.merge=function(t){if(!u.Object(t))throw Error("baobab.Cursor.merge: trying to merge a non-object.");var r=n.bind(this,"merge","Object").apply(this,arguments);return this.update(r)},e.prototype.unset=function(t){if(void 0===t&&this.isRoot())throw Error("baobab.Cursor.unset: cannot remove root node.");var r=n.bind(this,"unset",null).apply(this,[t,!0]);return this.update(r)},e.prototype.update=function(t,r){if(arguments.length<2)return this.tree.stack(h.pathObject(this.solvedPath,t)),this;var e=[].concat(t),n=h.solvePath(this.get(),e,this.tree);if(!n)throw Error("baobab.Cursor.update: could not solve dynamic path.");return this.tree.stack(h.pathObject(this.solvedPath.concat(n),r)),this},e.prototype.or=function(t){return new s("or",this,t)},e.prototype.and=function(t){return new s("and",this,t)},e.prototype.startRecording=function(t){if(t=t||5,1>t)throw Error("baobab.Cursor.startRecording: invalid maximum number of records.");return this.archive?this:(this._lazyBind(),this.archive=h.archive(t),this)},e.prototype.stopRecording=function(){return this.archive=null,this},e.prototype.undo=function(){},e.prototype.redo=function(){},e.prototype.isRecording=function(){return!!this.archive},e.prototype.hasHistory=function(){return!(!this.archive||!this.archive.get().length)},e.prototype.getHistory=function(){return this.archive?this.archive.get():[]},e.prototype.release=function(){this.tree.off("update",this.updateHandler),this.hash&&delete this.tree._cursors[this.hash],delete this.tree,delete this.path,delete this.solvedPath,this.kill()},e.prototype.toJSON=function(){return this.get()},u.Cursor=function(t){return t instanceof e},r.exports=e},{"../defaults.js":1,"./combination.js":5,"./helpers.js":7,"./mixins.js":9,"./type.js":10,emmett:3}],7:[function(t,r){(function(e){function n(t){return Array.prototype.slice.call(t)}function i(t,r){return function(){t(),r.apply(null,arguments)}}function o(t,r){var e,n={};for(e in t)n[e]=t[e];for(e in r)n[e]=r[e];return n}function s(t){var r=t.source,e="";return t.global&&(e+="g"),t.multiline&&(e+="m"),t.ignoreCase&&(e+="i"),t.sticky&&(e+="y"),t.unicode&&(e+="u"),new RegExp(r,e)}function a(t,r){if(!r||"object"!=typeof r||r instanceof Error||"ArrayBuffer"in e&&r instanceof ArrayBuffer)return r;if(_.Array(r)){if(t){var n,i,o=[];for(n=0,i=r.length;i>n;n++)o.push(w(r[n]));return o}return r.slice(0)}if(_.Date(r))return new Date(r.getTime());if(r instanceof RegExp)return s(r);if(_.Object(r)){var a,h={};r.constructor&&r.constructor!==Object&&(h=Object.create(r.constructor.prototype));for(a in r)r.hasOwnProperty(a)&&(h[a]=t?w(r[a]):r[a]);return h}return r}function h(t,r){return function(e){return r(t(e))}}function u(t,r){var e,n;for(e=0,n=t.length;n>e;e++)if(r(t[e]))return t[e]}function c(t,r){var e,n;for(e=0,n=t.length;n>e;e++)if(r(t[e]))return e;return-1}function l(t,r){var e,n=!0;if(!t)return!1;for(e in r)if(_.Object(r[e]))n=n&&l(t[e],r[e]);else if(_.Array(r[e]))n=n&&!!~r[e].indexOf(t[e]);else if(t[e]!==r[e])return!1;return n}function f(t,r){return u(t,function(t){return l(t,r)})}function d(t,r){return c(t,function(t){return l(t,r)})}function b(t,r,e){r=r||[];var n,i,o,s=t;for(i=0,o=r.length;o>i;i++){if(!s)return;if("function"==typeof r[i]){if(!_.Array(s))return;s=u(s,r[i])}else if("object"==typeof r[i])if(e&&"$cursor"in r[i]){if(!_.Path(r[i].$cursor))throw Error("baobab.getIn: $cursor path must be an array.");n=e.get(r[i].$cursor),s=s[n]}else{if(!_.Array(s))return;s=f(s,r[i])}else s=s[r[i]]}return s}function y(t,r,e){var n,i,o,s=[],a=t;for(i=0,o=r.length;o>i;i++){if(!a)return null;if("function"==typeof r[i]){if(!_.Array(a))return;n=c(a,r[i]),s.push(n),a=a[n]}else if("object"==typeof r[i])if(e&&"$cursor"in r[i]){if(!_.Path(r[i].$cursor))throw Error("baobab.getIn: $cursor path must be an array.");p=e.get(r[i].$cursor),s.push(p),a=a[p]}else{if(!_.Array(a))return;n=d(a,r[i]),s.push(n),a=a[n]}else s.push(r[i]),a=a[r[i]]||{}}return s}function g(t,r){var e,n=t.length,i={},o=i;for(n||(i=r),e=0;n>e;e++)o[t[e]]=e+1===n?r:{},o=o[t[e]];return i}function m(t,r){t.super_=r;var e=function(){};e.prototype=r.prototype,t.prototype=new e,t.prototype.constructor=t}function v(t){var r=[];return{add:function(e){for(r.unshift(e);r.length>t;)r.pop()},get:function(){return r}}}var _=t("./type.js"),j=a.bind(null,!1),w=a.bind(null,!0);r.exports={archive:v,arrayOf:n,before:i,deepClone:w,shallowClone:j,shallowMerge:o,compose:h,getIn:b,inherits:m,pathObject:g,solvePath:y}}).call(this,"undefined"!=typeof global?global:"undefined"!=typeof self?self:"undefined"!=typeof window?window:{})},{"./type.js":10}],8:[function(t,r){function e(t,r,e){s.forEach(function(r){e!==r&&delete t[r]}),t[e]=r[e]}function n(t,r){var a,h=i.shallowClone(r||{});s.forEach(function(r){t[r]&&e(h,t,r)}),t.$chain&&(s.slice(0,-1).forEach(function(t){delete h[t]}),h.$apply=h.$apply?i.compose(h.$apply,t.$chain):t.$chain),t.$push&&h.$push?h.$push=o.Array(h.$push)?h.$push.concat(t.$push):[h.$push].concat(t.$push):t.$push&&(h.$push=t.$push),t.$unshift&&h.$unshift?h.$unshift=o.Array(t.$unshift)?t.$unshift.concat(h.$unshift):[t.$unshift].concat(h.$unshift):t.$unshift&&(h.$unshift=t.$unshift);for(a in t)o.Object(t[a])?h[a]=n(t[a],h[a]):"$"!==a[0]&&(h[a]=t[a]);return h}var i=t("./helpers.js"),o=t("./type.js"),s=["$unset","$set","$merge","$apply"];r.exports=n},{"./helpers.js":7,"./type.js":10}],9:[function(t,r){var e=t("./combination.js"),n=t("./type.js");r.exports={baobab:function(t){return{mixins:[{getInitialState:function(){if(this.tree=t,!this.cursor&&!this.cursors)return{};if(this.cursor&&this.cursors)throw Error("baobab.mixin: you cannot have both `component.cursor` and `component.cursors`. Please make up your mind.");if(this.__type=null,this.__updateHandler=function(){this.setState(this.__getCursorData())}.bind(this),this.cursor){if(!n.MixinCursor(this.cursor))throw Error("baobab.mixin.cursor: invalid data (cursor, string, array or function).");n.Function(this.cursor)&&(this.cursor=this.cursor()),n.Cursor(this.cursor)||(this.cursor=t.select(this.cursor)),this.__getCursorData=function(){return{cursor:this.cursor.get()}}.bind(this),this.__type="single"}else if(this.cursors){if(!n.MixinCursors(this.cursors))throw Error("baobab.mixin.cursor: invalid data (object, array or function).");if(n.Function(this.cursors)&&(this.cursors=this.cursors()),n.Array(this.cursors))this.cursors=this.cursors.map(function(r){return n.Cursor(r)?r:t.select(r)}),this.__getCursorData=function(){return{cursors:this.cursors.map(function(t){return t.get()})}}.bind(this),this.__type="array";else{for(var r in this.cursors)n.Cursor(this.cursors[r])||(this.cursors[r]=t.select(this.cursors[r]));this.__getCursorData=function(){var t={};for(r in this.cursors)t[r]=this.cursors[r].get();return{cursors:t}}.bind(this),this.__type="object"}}return this.__getCursorData()},componentDidMount:function(){"single"===this.__type?(this.__combination=new e("or",[this.cursor]),this.__combination.on("update",this.__updateHandler)):"array"===this.__type?(this.__combination=new e("or",this.cursors),this.__combination.on("update",this.__updateHandler)):"object"===this.__type&&(this.__combination=new e("or",Object.keys(this.cursors).map(function(t){return this.cursors[t]},this)),this.__combination.on("update",this.__updateHandler))},componentWillUnmount:function(){this.__combination&&this.__combination.release()}}].concat(t.options.mixins)}},cursor:function(t){return{mixins:[{getInitialState:function(){return this.cursor=t,this.__updateHandler=function(){this.setState({cursor:this.cursor.get()})}.bind(this),{cursor:this.cursor.get()}},componentDidMount:function(){this.cursor.on("update",this.__updateHandler)},componentWillUnmount:function(){this.cursor.off("update",this.__updateHandler)}}].concat(t.tree.options.mixins)}}}},{"./combination.js":5,"./type.js":10}],10:[function(t,r){function e(t,r){return r.some(function(r){return n[r](t)})}var n={};n.Array=function(t){return Array.isArray(t)},n.Object=function(t){return!Array.isArray(t)&&"object"==typeof t&&null!==t},n.String=function(t){return"string"==typeof t},n.Number=function(t){return"number"==typeof t},n.Function=function(t){return"function"==typeof t},n.Primitive=function(t){return"string"==typeof t||"number"==typeof t||"boolean"==typeof t},n.Date=function(t){return t instanceof Date},n.NonScalar=function(t){return n.Object(t)||n.Array(t)},n.Path=function(t){var r=["String","Number","Function","Object"];return n.Array(t)?t.every(function(t){return e(t,r)}):e(t,r)},n.MixinCursor=function(t){return e(t,["String","Number","Array","Function","Cursor"])},n.MixinCursors=function(t){return e(t,["Object","Array","Function"])},n.ComplexPath=function(t){return t.some(function(t){return e(t,["Object","Function"])})},r.exports=n},{}],11:[function(t,r){function e(t,r){var e=new Error("baobab.update: "+r+" at path /"+t.slice(1).join("/"));return e.path=t,e}var n=t("./helpers.js"),i=t("./type.js");r.exports=function(t,r,o){if(o=o||{},!i.Object(t)&&!i.Array(t))throw Error("baobab.update: invalid target.");var s={};t={root:n.shallowClone(t)};var a=function(t,r,o,h){o=o||["root"];var u,c,l,f=o.join("|λ|"),p=o[o.length-1],d=Object.keys(r).some(function(t){return!!~["$unset","$set","$apply","$merge","$push","$unshift"].indexOf(t)});if(d){s[f]=!0;for(c in r){if("$unset"===c){var b=o[o.length-2];i.Array(t)?h[b]=t.slice(0,+p).concat(t.slice(+p+1)):(h[b]=n.shallowClone(t),delete h[b][p]);break}if("$set"===c){l=r.$set,t[p]=l;break}if("$apply"===c){if(u=r.$apply,"function"!=typeof u)throw e(o,"using command $apply with a non function");t[p]=u.call(null,t[p]);break}if("$merge"===c){if(l=r.$merge,!i.Object(t[p])||!i.Object(l))throw e(o,"using command $merge with a non object");t[p]=n.shallowMerge(t[p],l);break}if("$push"===c){if(l=r.$push,!i.Array(t[p]))throw e(o,"using command $push to a non array");t[p]=t[p].concat(l)}if("$unshift"===c){if(l=r.$unshift,!i.Array(t[p]))throw e(o,"using command $unshift to a non array");t[p]=[].concat(l).concat(t[p])}}}else for(c in r)t[p][c]="undefined"==typeof t[p][c]?{}:n.shallowClone(t[p][c]),a(t[p],r[c],o.concat(c),t)};return a(t,r),{data:t.root,log:Object.keys(s).map(function(t){return t.split("|λ|").slice(1)})}}},{"./helpers.js":7,"./type.js":10}]},{},[2])(2)}); \ No newline at end of file diff --git a/src/baobab.js b/src/baobab.js index cd64ed3..7b4f29e 100644 --- a/src/baobab.js +++ b/src/baobab.js @@ -95,7 +95,7 @@ Baobab.prototype.select = function(path) { return complexHash('ob'); else return step; - }).join('λ'); + }).join('|λ|'); if (!this._cursors[hash]) { var cursor = new Cursor(this, path, solvedPath, hash); diff --git a/src/update.js b/src/update.js index 3903b52..1075df2 100644 --- a/src/update.js +++ b/src/update.js @@ -32,7 +32,7 @@ module.exports = function(data, spec, opts) { var mutator = function(o, spec, path, parent) { path = path || ['root']; - var hash = path.join('λ'), + var hash = path.join('|λ|'), lastKey = path[path.length - 1], fn, k, @@ -141,7 +141,7 @@ module.exports = function(data, spec, opts) { // SHIFT LOG log: Object.keys(log).map(function(hash) { - return hash.split('λ').slice(1); + return hash.split('|λ|').slice(1); }) }; }; From e147407f7635f1e1995a0d3a97521e77abdde510 Mon Sep 17 00:00:00 2001 From: Yomguithereal Date: Thu, 9 Apr 2015 19:52:26 +0200 Subject: [PATCH 35/73] Fixing unit tests --- test/suites/cursor.js | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/test/suites/cursor.js b/test/suites/cursor.js index 80f6ff5..7588525 100644 --- a/test/suites/cursor.js +++ b/test/suites/cursor.js @@ -6,8 +6,7 @@ var assert = require('assert'), state = require('../state.js'), helpers = require('../../src/helpers.js'), Baobab = require('../../src/baobab.js'), - async = require('async'), - _ = require('lodash'); + async = require('async'); describe('Cursor API', function() { @@ -510,7 +509,7 @@ describe('Cursor API', function() { assert(cursor.isRecording()); - _.range(6).forEach(function() { + [1, 2, 3, 4, 5, 6].forEach(function() { cursor.apply(function(e) { return e + 1; }); }); From 43ccb8d73b9a3640bedd5aafef4672cf7c5b49e7 Mon Sep 17 00:00:00 2001 From: Yomguithereal Date: Thu, 9 Apr 2015 21:46:44 +0200 Subject: [PATCH 36/73] Working undo feature --- .gitignore | 1 + .npmignore | 1 + src/cursor.js | 25 +++++++++++++++++------ src/helpers.js | 7 +++++++ src/type.js | 4 ++++ test/suites/cursor.js | 46 +++++++++++++++++++++++++++++++++++++++++++ 6 files changed, 78 insertions(+), 6 deletions(-) diff --git a/.gitignore b/.gitignore index c5c4bd0..53c6e4a 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ node_modules .DS_Store TODO.md +*.log diff --git a/.npmignore b/.npmignore index d6e6c37..2a146cc 100644 --- a/.npmignore +++ b/.npmignore @@ -6,3 +6,4 @@ node_modules test/ build/ gulpfile.js +*.log diff --git a/src/cursor.js b/src/cursor.js index bd66d96..3dd8b58 100644 --- a/src/cursor.js +++ b/src/cursor.js @@ -28,6 +28,7 @@ function Cursor(tree, path, solvedPath, hash) { this.path = path; this.hash = hash; this.archive = null; + this.undoing = false; // Complex path? this.complexPath = !!solvedPath; @@ -38,7 +39,7 @@ function Cursor(tree, path, solvedPath, hash) { // Root listeners function update(previousState) { - if (self.isRecording()) { + if (self.isRecording() && !self.undoing) { // Handle archive var data = helpers.getIn(previousState, self.solvedPath, self.tree), @@ -47,6 +48,7 @@ function Cursor(tree, path, solvedPath, hash) { self.archive.add(record); } + self.undoing = false; return self.emit('update'); } @@ -348,12 +350,22 @@ Cursor.prototype.stopRecording = function() { return this; }; -Cursor.prototype.undo = function() { - // TODO... -}; +Cursor.prototype.undo = function(steps) { + steps = steps || 1; + + if (!this.isRecording()) + throw Error('baobab.Cursor.undo: cursor is not recording.'); + + if (!type.PositiveInteger(steps)) + throw Error('baobab.Cursor.undo: expecting a positive integer.'); + + var record = this.archive.back(steps); + + if (!record) + throw Error('boabab.Cursor.undo: cannot find a relevant record (' + steps + ' back).'); -Cursor.prototype.redo = function() { - // TODO... + this.undoing = true; + return this.set(record); }; Cursor.prototype.isRecording = function() { @@ -384,6 +396,7 @@ Cursor.prototype.release = function() { delete this.tree; delete this.path; delete this.solvedPath; + delete this.archive; // Killing emitter this.kill(); diff --git a/src/helpers.js b/src/helpers.js index eb2c58f..5141621 100644 --- a/src/helpers.js +++ b/src/helpers.js @@ -289,6 +289,13 @@ function archive(size) { while(records.length > size) records.pop(); }, + back: function(steps) { + var record = records[steps - 1]; + + if (record) + records = records.slice(steps); + return record; + }, get: function() { return records; } diff --git a/src/type.js b/src/type.js index a65f88e..af4f6aa 100644 --- a/src/type.js +++ b/src/type.js @@ -37,6 +37,10 @@ type.Number = function (value) { return typeof value === 'number'; }; +type.PositiveInteger = function(value) { + return typeof value === 'number' && value > 0 && !(value % 1); +}; + type.Function = function (value) { return typeof value === 'function'; }; diff --git a/test/suites/cursor.js b/test/suites/cursor.js index 7588525..94c357c 100644 --- a/test/suites/cursor.js +++ b/test/suites/cursor.js @@ -523,6 +523,52 @@ describe('Cursor API', function() { assert(!cursor.hasHistory()); assert.deepEqual(cursor.getHistory(), []); }); + + it('should throw an error if trying to undo a recordless cursor.', function() { + var baobab = new Baobab({item: 1}, {asynchronous: false}), + cursor = baobab.select('item'); + + assert.throws(function() { + cursor.undo(); + }, /recording/); + }); + + it('should be possible to go back in time.', function() { + var baobab = new Baobab({item: 1}, {asynchronous: false}), + cursor = baobab.select('item'); + + cursor.startRecording(); + + [1, 2, 3, 4, 5, 6].forEach(function() { + cursor.apply(function(e) { return e + 1; }); + }); + + assert.strictEqual(cursor.get(), 7); + + cursor.undo(); + assert.strictEqual(cursor.get(), 6); + assert.deepEqual(cursor.getHistory(), [2, 3, 4, 5].reverse()); + + cursor.undo().undo(); + + assert.strictEqual(cursor.get(), 4); + assert.deepEqual(cursor.getHistory(), [2, 3].reverse()); + + cursor.set(4).set(5); + + cursor.undo(3); + + assert.strictEqual(cursor.get(), 3); + assert.deepEqual(cursor.getHistory(), [2]); + + assert.throws(function() { + cursor.undo(5); + }, /relevant/); + + assert.throws(function() { + cursor.undo(-5); + }, /positive/); + }); }); describe('Advanced', function() { From 0e438de391415aa7b5e094b939e6d17bf5d26344 Mon Sep 17 00:00:00 2001 From: Yomguithereal Date: Thu, 9 Apr 2015 21:55:22 +0200 Subject: [PATCH 37/73] Fixing building procedure --- build/baobab.min.js | 2 +- gulpfile.js | 22 +++++++++------------- package.json | 4 ++-- 3 files changed, 12 insertions(+), 16 deletions(-) diff --git a/build/baobab.min.js b/build/baobab.min.js index 752b85d..2dc0d6c 100644 --- a/build/baobab.min.js +++ b/build/baobab.min.js @@ -1,2 +1,2 @@ /* baobab.js - Version: 1.0.0-rc1 - Author: Yomguithereal (Guillaume Plique) */ -!function(t){if("object"==typeof exports&&"undefined"!=typeof module)module.exports=t();else if("function"==typeof define&&define.amd)define([],t);else{var r;r="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:this,r.Baobab=t()}}(function(){var t;return function r(t,e,n){function i(s,a){if(!e[s]){if(!t[s]){var h="function"==typeof require&&require;if(!a&&h)return h(s,!0);if(o)return o(s,!0);var u=new Error("Cannot find module '"+s+"'");throw u.code="MODULE_NOT_FOUND",u}var c=e[s]={exports:{}};t[s][0].call(c.exports,function(r){var e=t[s][1][r];return i(e?e:r)},c,c.exports,r,t,e,n)}return e[s].exports}for(var o="function"==typeof require&&require,s=0;sr;r++)n.push(t[r].handler);return n}var i={once:"boolean",scope:"object"},o=function(){this._enabled=!0,this._children=[],this._handlers={},this._handlersAll=[]};o.prototype.on=function(t,r,e){var n,s,a,h,u,c;if("function"==typeof r){for(u="string"==typeof t?[t]:t,n=0,s=u.length;n!==s;n+=1)if(h=u[n]){this._handlers[h]||(this._handlers[h]=[]),c={handler:r};for(a in e||{}){if(!i[a])throw new Error('The option "'+a+'" is not recognized by Emmett.');c[a]=e[a]}this._handlers[h].push(c)}}else if(t&&"object"==typeof t&&!Array.isArray(t))for(h in t)o.prototype.on.call(this,h,t[h],r);else{if("function"!=typeof t)throw new Error("Wrong arguments.");c={handler:t};for(a in e||{}){if(!i[a])throw new Error('The option "'+a+'" is not recognized by Emmett.');c[a]=e[a]}this._handlersAll.push(c)}return this},o.prototype.once=function(t,r,e){if("function"==typeof r)e=e||{},e.once=!0,this.on(t,r,e);else{if((!t||"object"!=typeof t||Array.isArray(t))&&"function"!=typeof t)throw new Error("Wrong arguments.");r=r||{},r.once=!0,this.on(t,r)}return this},o.prototype.off=function(t,r){var e,n,i,o,s,a,h,u="string"==typeof t?[t]:t;if(1===arguments.length&&"function"==typeof u){r=arguments[0];for(s in this._handlers){for(a=[],e=0,n=this._handlers[s].length;e!==n;e+=1)this._handlers[s][e].handler!==r&&a.push(this._handlers[s][e]);this._handlers[s]=a}for(a=[],e=0,n=this._handlersAll.length;e!==n;e+=1)this._handlersAll[e].handler!==r&&a.push(this._handlersAll[e]);this._handlersAll=a}else if(2===arguments.length)for(e=0,n=u.length;e!==n;e+=1){if(h=u[e],this._handlers[h]){for(a=[],i=0,o=this._handlers[h].length;i!==o;i+=1)this._handlers[h][i].handler!==r&&a.push(this._handlers[h][i]);this._handlers[h]=a}this._handlers[h]&&0===this._handlers[h].length&&delete this._handlers[h]}return this},o.prototype.unbindAll=function(){var t;this._handlersAll=[];for(t in this._handlers)delete this._handlers[t];return this},o.prototype.emit=function(t,r){var e,n,i,o,s,a,h,u,c,l,f="string"==typeof t?[t]:t;if(!this._enabled)return this;for(r=void 0===r?{}:r,e=0,n=f.length;e!==n;e+=1)if(l=f[e],c=(this._handlers[l]||[]).concat(this._handlersAll),c.length){for(h={type:l,data:r||{},target:this},a=[],i=0,o=c.length;i!==o;i+=1)(this._handlers[l]&&this._handlers[l].indexOf(c[i])>=0||this._handlersAll.indexOf(c[i])>=0)&&(c[i].handler.call("scope"in c[i]?c[i].scope:this,h),c[i].once&&a.push(c[i]));for(s=0;se;e++)if(t._children[e]===r){t._children.splice(e,1);break}}),this._children.push(r),r},o.prototype.listeners=function(t){var e,n,i,o=[];if(t)for(o=r(this._handlers[t]),n=0,i=this._children.length;i>n;n++)o=o.concat(this._children[n].listeners(t));else{o=r(this._handlersAll);for(e in this._handlers)o=o.concat(r(this._handlers[e]));for(n=0,i=this._children.length;i>n;n++)o=o.concat(this._children[n].listeners())}return o},o.prototype.kill=function(){if(this.emit("emmett:kill"),this.unbindAll(),this._handlers=null,this._handlersAll=null,this._enabled=!1,this._children)for(var t=0,r=this._children.length;r>t;t++)this._children[t].kill();this._children=null},o.prototype.disable=function(){return this._enabled=!1,this},o.prototype.enable=function(){return this._enabled=!0,this},o.version="2.1.2","undefined"!=typeof n?("undefined"!=typeof e&&e.exports&&(n=e.exports=o),n.Emitter=o):"function"==typeof t&&t.amd?t("emmett",[],function(){return o}):this.Emitter=o}).call(this)},{}],4:[function(t,r){function e(t){return t+"$"+(new Date).getTime()+(""+Math.random()).replace("0.","")}function n(t,r){function e(t){this[t]=function(){var r=this.root[t].apply(this.root,arguments);return r instanceof i?this:r}}if(arguments.length<1&&(t={}),!(this instanceof n))return new n(t,r);if(!l.Object(t)&&!l.Array(t))throw Error("Baobab: invalid data.");o.call(this),this.options=s.shallowMerge(c,r),this._transaction={},this._future=void 0,this._cursors={},this.data=s.deepClone(t),this.root=this.select([]),["get","set","unset","update"].forEach(e.bind(this)),this.mixin=u.baobab(this)}var i=t("./cursor.js"),o=t("emmett"),s=t("./helpers.js"),a=t("./update.js"),h=t("./merge.js"),u=t("./mixins.js"),c=t("../defaults.js"),l=t("./type.js");s.inherits(n,o),n.prototype.select=function(t){if(!t)throw Error("Baobab.select: invalid path.");if(arguments.length>1&&(t=s.arrayOf(arguments)),!l.Path(t))throw Error("Baobab.select: invalid path.");t=[].concat(t);var r,n=l.ComplexPath(t);n&&(r=s.solvePath(this.data,t,this));var o=t.map(function(t){return l.Function(t)?e("fn"):l.Object(t)?e("ob"):t}).join("|λ|");if(this._cursors[o])return this._cursors[o];var a=new i(this,t,r,o);return this._cursors[o]=a,a},n.prototype.stack=function(t){var r=this;if(!l.Object(t))throw Error("Baobab.update: wrong specification.");return this._transaction=h(t,this._transaction),this.options.autoCommit?this.options.asynchronous?(this._future||(this._future=setTimeout(r.commit.bind(r,null),0)),this):this.commit():this},n.prototype.commit=function(){var t=a(this.data,this._transaction,this.options),r=this.data;return this.data=t.data,this._transaction={},this._future&&(this._future=clearTimeout(this._future)),this.emit("update",{log:t.log,previousState:r}),this},n.prototype.release=function(){delete this.data,delete this._transaction;for(var t in this._cursors)this._cursors[t].release();delete this._cursors,this.kill()},n.prototype.toJSON=function(){return this.get()},r.exports=n},{"../defaults.js":1,"./cursor.js":6,"./helpers.js":7,"./merge.js":8,"./mixins.js":9,"./type.js":10,"./update.js":11,emmett:3}],5:[function(t,r){function e(t,r){r.on("update",t.cursorListener),t.tree.off("update",t.treeListener),t.tree.on("update",t.treeListener)}function n(t){var r=this;if(arguments.length<2)throw Error("baobab.Combination: not enough arguments.");var n=arguments[1],i=s.arrayOf(arguments).slice(2);if(n instanceof Array&&(i=n.slice(1),n=n[0]),!a.Cursor(n))throw Error("baobab.Combination: argument should be a cursor.");if("or"!==t&&"and"!==t)throw Error("baobab.Combination: invalid operator.");o.call(this),this.cursors=[n],this.operators=[],this.tree=n.tree,this.updates=new Array(this.cursors.length),this.cursorListener=function(){r.updates[r.cursors.indexOf(this)]=!0},this.treeListener=function(){var t,e,n=r.updates[0];for(t=1,e=r.cursors.length;e>t;t++)n="or"===r.operators[t-1]?n||r.updates[t]:n&&r.updates[t];n&&r.emit("update"),r.updates=new Array(r.cursors.length)},this.bound=!1;var h=(this.on,this.once,function(){r.bound||(r.bound=!0,r.cursors.forEach(function(t){e(r,t)}))});this.on=s.before(h,this.on.bind(this)),this.once=s.before(h,this.once.bind(this)),i.forEach(function(r){this[t](r)},this)}function i(t){n.prototype[t]=function(r){if(!a.Cursor(r))throw this.release(),Error("baobab.Combination."+t+": argument should be a cursor.");if(~this.cursors.indexOf(r))throw this.release(),Error("baobab.Combination."+t+": cursor already in combination.");return this.cursors.push(r),this.operators.push(t),this.updates.length++,this.bound&&e(this,r),this}}var o=t("emmett"),s=t("./helpers.js"),a=t("./type.js");s.inherits(n,o),i("or"),i("and"),n.prototype.release=function(){this.cursors.forEach(function(t){t.off("update",this.cursorListener)},this),this.tree.off("update",this.treeListener),this.cursors=null,this.operators=null,this.tree=null,this.updates=null,this.kill()},r.exports=n},{"./helpers.js":7,"./type.js":10,emmett:3}],6:[function(t,r){function e(t,r,e,n){function i(t){if(s.isRecording()){var r=h.getIn(t,s.solvedPath,s.tree),e=h.deepClone(r);s.archive.add(e)}return s.emit("update")}var s=this;o.call(this),r=r||[],this.tree=t,this.path=r,this.hash=n,this.archive=null,this.complexPath=!!e,this.solvedPath=this.complexPath?e:this.path,this.relevant=void 0!==this.get(),this.updateHandler=function(t){var r,e,n,o,a,u,c=t.data.log,l=t.data.previousState,f=!1;if(s.complexPath&&(s.solvedPath=h.solvePath(s.tree.data,s.path,s.tree)),!s.path.length)return i(l);if(s.solvedPath)t:for(a=0,n=c.length;n>a;a++)for(r=c[a],u=0,o=r.length;o>u&&(e=r[u],e===""+s.solvedPath[u]);u++)if(u+1===o||u+1===s.solvedPath.length){f=!0;break t}var p=void 0!==s.get();s.relevant?p&&f?i(l):p||(s.emit("irrelevant"),s.relevant=!1):p&&f&&(s.emit("relevant"),i(l),s.relevant=!0)},this.mixin=a.cursor(this);var u=!1;this._lazyBind=function(){u||(u=!0,s.tree.on("update",s.updateHandler))},this.on=h.before(this._lazyBind,this.on.bind(this)),this.once=h.before(this._lazyBind,this.once.bind(this)),this.complexPath&&this._lazyBind()}function n(t,r,e,n){arguments.length<4&&(n=e,e=[]),e=e||[];var i=[].concat(e),o=h.solvePath(this.get(),i,this.tree);if(!o)throw Error("baobab.Cursor."+t+": could not solve dynamic path.");if(r){var s=this.get(o);if(!u[r](s))throw Error("baobab.Cursor."+t+": invalid target.")}var a={};a["$"+t]=n;var c=h.pathObject(o,a);return c}function i(t,r){e.prototype[t]=function(){var e=n.bind(this,t,r).apply(this,arguments);return this.update(e)}}var o=t("emmett"),s=t("./combination.js"),a=t("./mixins.js"),h=t("./helpers.js"),u=(t("../defaults.js"),t("./type.js"));h.inherits(e,o),e.prototype.isRoot=function(){return!this.path.length},e.prototype.isLeaf=function(){return u.Primitive(this.get())},e.prototype.isBranch=function(){return!this.isLeaf()&&!this.isRoot()},e.prototype.root=function(){return this.tree.root()},e.prototype.select=function(t){if(arguments.length>1&&(t=h.arrayOf(arguments)),!u.Path(t))throw Error("baobab.Cursor.select: invalid path.");return this.tree.select(this.path.concat(t))},e.prototype.up=function(){return this.solvedPath&&this.solvedPath.length?this.tree.select(this.path.slice(0,-1)):null},e.prototype.left=function(){var t=+this.solvedPath[this.solvedPath.length-1];if(isNaN(t))throw Error("baobab.Cursor.left: cannot go left on a non-list type.");return t?this.tree.select(this.solvedPath.slice(0,-1).concat(t-1)):null},e.prototype.leftmost=function(){var t=+this.solvedPath[this.solvedPath.length-1];if(isNaN(t))throw Error("baobab.Cursor.leftmost: cannot go left on a non-list type.");return this.tree.select(this.solvedPath.slice(0,-1).concat(0))},e.prototype.right=function(){var t=+this.solvedPath[this.solvedPath.length-1];if(isNaN(t))throw Error("baobab.Cursor.right: cannot go right on a non-list type.");return t+1===this.up().get().length?null:this.tree.select(this.solvedPath.slice(0,-1).concat(t+1))},e.prototype.rightmost=function(){var t=+this.solvedPath[this.solvedPath.length-1];if(isNaN(t))throw Error("baobab.Cursor.right: cannot go right on a non-list type.");var r=this.up().get();return this.tree.select(this.solvedPath.slice(0,-1).concat(r.length-1))},e.prototype.down=function(){+this.solvedPath[this.solvedPath.length-1];return this.get()instanceof Array?this.tree.select(this.solvedPath.concat(0)):null},e.prototype.get=function(t){arguments.length>1&&(t=h.arrayOf(arguments));var r=this.solvedPath.concat((u.String(t)||u.Number(t)?[t]:t)||[]);return h.getIn(this.tree.data,r,this.tree)},i("set"),i("apply"),i("chain"),i("push","Array"),i("unshift","Array"),e.prototype.merge=function(t){if(!u.Object(t))throw Error("baobab.Cursor.merge: trying to merge a non-object.");var r=n.bind(this,"merge","Object").apply(this,arguments);return this.update(r)},e.prototype.unset=function(t){if(void 0===t&&this.isRoot())throw Error("baobab.Cursor.unset: cannot remove root node.");var r=n.bind(this,"unset",null).apply(this,[t,!0]);return this.update(r)},e.prototype.update=function(t,r){if(arguments.length<2)return this.tree.stack(h.pathObject(this.solvedPath,t)),this;var e=[].concat(t),n=h.solvePath(this.get(),e,this.tree);if(!n)throw Error("baobab.Cursor.update: could not solve dynamic path.");return this.tree.stack(h.pathObject(this.solvedPath.concat(n),r)),this},e.prototype.or=function(t){return new s("or",this,t)},e.prototype.and=function(t){return new s("and",this,t)},e.prototype.startRecording=function(t){if(t=t||5,1>t)throw Error("baobab.Cursor.startRecording: invalid maximum number of records.");return this.archive?this:(this._lazyBind(),this.archive=h.archive(t),this)},e.prototype.stopRecording=function(){return this.archive=null,this},e.prototype.undo=function(){},e.prototype.redo=function(){},e.prototype.isRecording=function(){return!!this.archive},e.prototype.hasHistory=function(){return!(!this.archive||!this.archive.get().length)},e.prototype.getHistory=function(){return this.archive?this.archive.get():[]},e.prototype.release=function(){this.tree.off("update",this.updateHandler),this.hash&&delete this.tree._cursors[this.hash],delete this.tree,delete this.path,delete this.solvedPath,this.kill()},e.prototype.toJSON=function(){return this.get()},u.Cursor=function(t){return t instanceof e},r.exports=e},{"../defaults.js":1,"./combination.js":5,"./helpers.js":7,"./mixins.js":9,"./type.js":10,emmett:3}],7:[function(t,r){(function(e){function n(t){return Array.prototype.slice.call(t)}function i(t,r){return function(){t(),r.apply(null,arguments)}}function o(t,r){var e,n={};for(e in t)n[e]=t[e];for(e in r)n[e]=r[e];return n}function s(t){var r=t.source,e="";return t.global&&(e+="g"),t.multiline&&(e+="m"),t.ignoreCase&&(e+="i"),t.sticky&&(e+="y"),t.unicode&&(e+="u"),new RegExp(r,e)}function a(t,r){if(!r||"object"!=typeof r||r instanceof Error||"ArrayBuffer"in e&&r instanceof ArrayBuffer)return r;if(_.Array(r)){if(t){var n,i,o=[];for(n=0,i=r.length;i>n;n++)o.push(w(r[n]));return o}return r.slice(0)}if(_.Date(r))return new Date(r.getTime());if(r instanceof RegExp)return s(r);if(_.Object(r)){var a,h={};r.constructor&&r.constructor!==Object&&(h=Object.create(r.constructor.prototype));for(a in r)r.hasOwnProperty(a)&&(h[a]=t?w(r[a]):r[a]);return h}return r}function h(t,r){return function(e){return r(t(e))}}function u(t,r){var e,n;for(e=0,n=t.length;n>e;e++)if(r(t[e]))return t[e]}function c(t,r){var e,n;for(e=0,n=t.length;n>e;e++)if(r(t[e]))return e;return-1}function l(t,r){var e,n=!0;if(!t)return!1;for(e in r)if(_.Object(r[e]))n=n&&l(t[e],r[e]);else if(_.Array(r[e]))n=n&&!!~r[e].indexOf(t[e]);else if(t[e]!==r[e])return!1;return n}function f(t,r){return u(t,function(t){return l(t,r)})}function d(t,r){return c(t,function(t){return l(t,r)})}function b(t,r,e){r=r||[];var n,i,o,s=t;for(i=0,o=r.length;o>i;i++){if(!s)return;if("function"==typeof r[i]){if(!_.Array(s))return;s=u(s,r[i])}else if("object"==typeof r[i])if(e&&"$cursor"in r[i]){if(!_.Path(r[i].$cursor))throw Error("baobab.getIn: $cursor path must be an array.");n=e.get(r[i].$cursor),s=s[n]}else{if(!_.Array(s))return;s=f(s,r[i])}else s=s[r[i]]}return s}function y(t,r,e){var n,i,o,s=[],a=t;for(i=0,o=r.length;o>i;i++){if(!a)return null;if("function"==typeof r[i]){if(!_.Array(a))return;n=c(a,r[i]),s.push(n),a=a[n]}else if("object"==typeof r[i])if(e&&"$cursor"in r[i]){if(!_.Path(r[i].$cursor))throw Error("baobab.getIn: $cursor path must be an array.");p=e.get(r[i].$cursor),s.push(p),a=a[p]}else{if(!_.Array(a))return;n=d(a,r[i]),s.push(n),a=a[n]}else s.push(r[i]),a=a[r[i]]||{}}return s}function g(t,r){var e,n=t.length,i={},o=i;for(n||(i=r),e=0;n>e;e++)o[t[e]]=e+1===n?r:{},o=o[t[e]];return i}function m(t,r){t.super_=r;var e=function(){};e.prototype=r.prototype,t.prototype=new e,t.prototype.constructor=t}function v(t){var r=[];return{add:function(e){for(r.unshift(e);r.length>t;)r.pop()},get:function(){return r}}}var _=t("./type.js"),j=a.bind(null,!1),w=a.bind(null,!0);r.exports={archive:v,arrayOf:n,before:i,deepClone:w,shallowClone:j,shallowMerge:o,compose:h,getIn:b,inherits:m,pathObject:g,solvePath:y}}).call(this,"undefined"!=typeof global?global:"undefined"!=typeof self?self:"undefined"!=typeof window?window:{})},{"./type.js":10}],8:[function(t,r){function e(t,r,e){s.forEach(function(r){e!==r&&delete t[r]}),t[e]=r[e]}function n(t,r){var a,h=i.shallowClone(r||{});s.forEach(function(r){t[r]&&e(h,t,r)}),t.$chain&&(s.slice(0,-1).forEach(function(t){delete h[t]}),h.$apply=h.$apply?i.compose(h.$apply,t.$chain):t.$chain),t.$push&&h.$push?h.$push=o.Array(h.$push)?h.$push.concat(t.$push):[h.$push].concat(t.$push):t.$push&&(h.$push=t.$push),t.$unshift&&h.$unshift?h.$unshift=o.Array(t.$unshift)?t.$unshift.concat(h.$unshift):[t.$unshift].concat(h.$unshift):t.$unshift&&(h.$unshift=t.$unshift);for(a in t)o.Object(t[a])?h[a]=n(t[a],h[a]):"$"!==a[0]&&(h[a]=t[a]);return h}var i=t("./helpers.js"),o=t("./type.js"),s=["$unset","$set","$merge","$apply"];r.exports=n},{"./helpers.js":7,"./type.js":10}],9:[function(t,r){var e=t("./combination.js"),n=t("./type.js");r.exports={baobab:function(t){return{mixins:[{getInitialState:function(){if(this.tree=t,!this.cursor&&!this.cursors)return{};if(this.cursor&&this.cursors)throw Error("baobab.mixin: you cannot have both `component.cursor` and `component.cursors`. Please make up your mind.");if(this.__type=null,this.__updateHandler=function(){this.setState(this.__getCursorData())}.bind(this),this.cursor){if(!n.MixinCursor(this.cursor))throw Error("baobab.mixin.cursor: invalid data (cursor, string, array or function).");n.Function(this.cursor)&&(this.cursor=this.cursor()),n.Cursor(this.cursor)||(this.cursor=t.select(this.cursor)),this.__getCursorData=function(){return{cursor:this.cursor.get()}}.bind(this),this.__type="single"}else if(this.cursors){if(!n.MixinCursors(this.cursors))throw Error("baobab.mixin.cursor: invalid data (object, array or function).");if(n.Function(this.cursors)&&(this.cursors=this.cursors()),n.Array(this.cursors))this.cursors=this.cursors.map(function(r){return n.Cursor(r)?r:t.select(r)}),this.__getCursorData=function(){return{cursors:this.cursors.map(function(t){return t.get()})}}.bind(this),this.__type="array";else{for(var r in this.cursors)n.Cursor(this.cursors[r])||(this.cursors[r]=t.select(this.cursors[r]));this.__getCursorData=function(){var t={};for(r in this.cursors)t[r]=this.cursors[r].get();return{cursors:t}}.bind(this),this.__type="object"}}return this.__getCursorData()},componentDidMount:function(){"single"===this.__type?(this.__combination=new e("or",[this.cursor]),this.__combination.on("update",this.__updateHandler)):"array"===this.__type?(this.__combination=new e("or",this.cursors),this.__combination.on("update",this.__updateHandler)):"object"===this.__type&&(this.__combination=new e("or",Object.keys(this.cursors).map(function(t){return this.cursors[t]},this)),this.__combination.on("update",this.__updateHandler))},componentWillUnmount:function(){this.__combination&&this.__combination.release()}}].concat(t.options.mixins)}},cursor:function(t){return{mixins:[{getInitialState:function(){return this.cursor=t,this.__updateHandler=function(){this.setState({cursor:this.cursor.get()})}.bind(this),{cursor:this.cursor.get()}},componentDidMount:function(){this.cursor.on("update",this.__updateHandler)},componentWillUnmount:function(){this.cursor.off("update",this.__updateHandler)}}].concat(t.tree.options.mixins)}}}},{"./combination.js":5,"./type.js":10}],10:[function(t,r){function e(t,r){return r.some(function(r){return n[r](t)})}var n={};n.Array=function(t){return Array.isArray(t)},n.Object=function(t){return!Array.isArray(t)&&"object"==typeof t&&null!==t},n.String=function(t){return"string"==typeof t},n.Number=function(t){return"number"==typeof t},n.Function=function(t){return"function"==typeof t},n.Primitive=function(t){return"string"==typeof t||"number"==typeof t||"boolean"==typeof t},n.Date=function(t){return t instanceof Date},n.NonScalar=function(t){return n.Object(t)||n.Array(t)},n.Path=function(t){var r=["String","Number","Function","Object"];return n.Array(t)?t.every(function(t){return e(t,r)}):e(t,r)},n.MixinCursor=function(t){return e(t,["String","Number","Array","Function","Cursor"])},n.MixinCursors=function(t){return e(t,["Object","Array","Function"])},n.ComplexPath=function(t){return t.some(function(t){return e(t,["Object","Function"])})},r.exports=n},{}],11:[function(t,r){function e(t,r){var e=new Error("baobab.update: "+r+" at path /"+t.slice(1).join("/"));return e.path=t,e}var n=t("./helpers.js"),i=t("./type.js");r.exports=function(t,r,o){if(o=o||{},!i.Object(t)&&!i.Array(t))throw Error("baobab.update: invalid target.");var s={};t={root:n.shallowClone(t)};var a=function(t,r,o,h){o=o||["root"];var u,c,l,f=o.join("|λ|"),p=o[o.length-1],d=Object.keys(r).some(function(t){return!!~["$unset","$set","$apply","$merge","$push","$unshift"].indexOf(t)});if(d){s[f]=!0;for(c in r){if("$unset"===c){var b=o[o.length-2];i.Array(t)?h[b]=t.slice(0,+p).concat(t.slice(+p+1)):(h[b]=n.shallowClone(t),delete h[b][p]);break}if("$set"===c){l=r.$set,t[p]=l;break}if("$apply"===c){if(u=r.$apply,"function"!=typeof u)throw e(o,"using command $apply with a non function");t[p]=u.call(null,t[p]);break}if("$merge"===c){if(l=r.$merge,!i.Object(t[p])||!i.Object(l))throw e(o,"using command $merge with a non object");t[p]=n.shallowMerge(t[p],l);break}if("$push"===c){if(l=r.$push,!i.Array(t[p]))throw e(o,"using command $push to a non array");t[p]=t[p].concat(l)}if("$unshift"===c){if(l=r.$unshift,!i.Array(t[p]))throw e(o,"using command $unshift to a non array");t[p]=[].concat(l).concat(t[p])}}}else for(c in r)t[p][c]="undefined"==typeof t[p][c]?{}:n.shallowClone(t[p][c]),a(t[p],r[c],o.concat(c),t)};return a(t,r),{data:t.root,log:Object.keys(s).map(function(t){return t.split("|λ|").slice(1)})}}},{"./helpers.js":7,"./type.js":10}]},{},[2])(2)}); \ No newline at end of file +!function(t){if("object"==typeof exports&&"undefined"!=typeof module)module.exports=t();else if("function"==typeof define&&define.amd)define([],t);else{var r;r="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:this,r.Baobab=t()}}(function(){var t;return function r(t,e,n){function i(s,a){if(!e[s]){if(!t[s]){var h="function"==typeof require&&require;if(!a&&h)return h(s,!0);if(o)return o(s,!0);var u=new Error("Cannot find module '"+s+"'");throw u.code="MODULE_NOT_FOUND",u}var c=e[s]={exports:{}};t[s][0].call(c.exports,function(r){var e=t[s][1][r];return i(e?e:r)},c,c.exports,r,t,e,n)}return e[s].exports}for(var o="function"==typeof require&&require,s=0;sr;r++)n.push(t[r].handler);return n}var i={once:"boolean",scope:"object"},o=function(){this._enabled=!0,this._children=[],this._handlers={},this._handlersAll=[]};o.prototype.on=function(t,r,e){var n,s,a,h,u,c;if("function"==typeof r){for(u="string"==typeof t?[t]:t,n=0,s=u.length;n!==s;n+=1)if(h=u[n]){this._handlers[h]||(this._handlers[h]=[]),c={handler:r};for(a in e||{}){if(!i[a])throw new Error('The option "'+a+'" is not recognized by Emmett.');c[a]=e[a]}this._handlers[h].push(c)}}else if(t&&"object"==typeof t&&!Array.isArray(t))for(h in t)o.prototype.on.call(this,h,t[h],r);else{if("function"!=typeof t)throw new Error("Wrong arguments.");c={handler:t};for(a in e||{}){if(!i[a])throw new Error('The option "'+a+'" is not recognized by Emmett.');c[a]=e[a]}this._handlersAll.push(c)}return this},o.prototype.once=function(t,r,e){if("function"==typeof r)e=e||{},e.once=!0,this.on(t,r,e);else{if((!t||"object"!=typeof t||Array.isArray(t))&&"function"!=typeof t)throw new Error("Wrong arguments.");r=r||{},r.once=!0,this.on(t,r)}return this},o.prototype.off=function(t,r){var e,n,i,o,s,a,h,u="string"==typeof t?[t]:t;if(1===arguments.length&&"function"==typeof u){r=arguments[0];for(s in this._handlers){for(a=[],e=0,n=this._handlers[s].length;e!==n;e+=1)this._handlers[s][e].handler!==r&&a.push(this._handlers[s][e]);this._handlers[s]=a}for(a=[],e=0,n=this._handlersAll.length;e!==n;e+=1)this._handlersAll[e].handler!==r&&a.push(this._handlersAll[e]);this._handlersAll=a}else if(2===arguments.length)for(e=0,n=u.length;e!==n;e+=1){if(h=u[e],this._handlers[h]){for(a=[],i=0,o=this._handlers[h].length;i!==o;i+=1)this._handlers[h][i].handler!==r&&a.push(this._handlers[h][i]);this._handlers[h]=a}this._handlers[h]&&0===this._handlers[h].length&&delete this._handlers[h]}return this},o.prototype.unbindAll=function(){var t;this._handlersAll=[];for(t in this._handlers)delete this._handlers[t];return this},o.prototype.emit=function(t,r){var e,n,i,o,s,a,h,u,c,l,f="string"==typeof t?[t]:t;if(!this._enabled)return this;for(r=void 0===r?{}:r,e=0,n=f.length;e!==n;e+=1)if(l=f[e],c=(this._handlers[l]||[]).concat(this._handlersAll),c.length){for(h={type:l,data:r||{},target:this},a=[],i=0,o=c.length;i!==o;i+=1)(this._handlers[l]&&this._handlers[l].indexOf(c[i])>=0||this._handlersAll.indexOf(c[i])>=0)&&(c[i].handler.call("scope"in c[i]?c[i].scope:this,h),c[i].once&&a.push(c[i]));for(s=0;se;e++)if(t._children[e]===r){t._children.splice(e,1);break}}),this._children.push(r),r},o.prototype.listeners=function(t){var e,n,i,o=[];if(t)for(o=r(this._handlers[t]),n=0,i=this._children.length;i>n;n++)o=o.concat(this._children[n].listeners(t));else{o=r(this._handlersAll);for(e in this._handlers)o=o.concat(r(this._handlers[e]));for(n=0,i=this._children.length;i>n;n++)o=o.concat(this._children[n].listeners())}return o},o.prototype.kill=function(){if(this.emit("emmett:kill"),this.unbindAll(),this._handlers=null,this._handlersAll=null,this._enabled=!1,this._children)for(var t=0,r=this._children.length;r>t;t++)this._children[t].kill();this._children=null},o.prototype.disable=function(){return this._enabled=!1,this},o.prototype.enable=function(){return this._enabled=!0,this},o.version="2.1.2","undefined"!=typeof n?("undefined"!=typeof e&&e.exports&&(n=e.exports=o),n.Emitter=o):"function"==typeof t&&t.amd?t("emmett",[],function(){return o}):this.Emitter=o}).call(this)},{}],4:[function(t,r){function e(t){return t+"$"+(new Date).getTime()+(""+Math.random()).replace("0.","")}function n(t,r){function e(t){this[t]=function(){var r=this.root[t].apply(this.root,arguments);return r instanceof i?this:r}}if(arguments.length<1&&(t={}),!(this instanceof n))return new n(t,r);if(!l.Object(t)&&!l.Array(t))throw Error("Baobab: invalid data.");o.call(this),this.options=s.shallowMerge(c,r),this._transaction={},this._future=void 0,this._cursors={},this.data=s.deepClone(t),this.root=this.select([]),["get","set","unset","update"].forEach(e.bind(this)),this.mixin=u.baobab(this)}var i=t("./cursor.js"),o=t("emmett"),s=t("./helpers.js"),a=t("./update.js"),h=t("./merge.js"),u=t("./mixins.js"),c=t("../defaults.js"),l=t("./type.js");s.inherits(n,o),n.prototype.select=function(t){if(!t)throw Error("Baobab.select: invalid path.");if(arguments.length>1&&(t=s.arrayOf(arguments)),!l.Path(t))throw Error("Baobab.select: invalid path.");t=[].concat(t);var r,n=l.ComplexPath(t);n&&(r=s.solvePath(this.data,t,this));var o=t.map(function(t){return l.Function(t)?e("fn"):l.Object(t)?e("ob"):t}).join("|λ|");if(this._cursors[o])return this._cursors[o];var a=new i(this,t,r,o);return this._cursors[o]=a,a},n.prototype.stack=function(t){var r=this;if(!l.Object(t))throw Error("Baobab.update: wrong specification.");return this._transaction=h(t,this._transaction),this.options.autoCommit?this.options.asynchronous?(this._future||(this._future=setTimeout(r.commit.bind(r,null),0)),this):this.commit():this},n.prototype.commit=function(){var t=a(this.data,this._transaction,this.options),r=this.data;return this.data=t.data,this._transaction={},this._future&&(this._future=clearTimeout(this._future)),this.emit("update",{log:t.log,previousState:r}),this},n.prototype.release=function(){delete this.data,delete this._transaction;for(var t in this._cursors)this._cursors[t].release();delete this._cursors,this.kill()},n.prototype.toJSON=function(){return this.get()},r.exports=n},{"../defaults.js":2,"./cursor.js":6,"./helpers.js":7,"./merge.js":8,"./mixins.js":9,"./type.js":10,"./update.js":11,emmett:3}],5:[function(t,r){function e(t,r){r.on("update",t.cursorListener),t.tree.off("update",t.treeListener),t.tree.on("update",t.treeListener)}function n(t){var r=this;if(arguments.length<2)throw Error("baobab.Combination: not enough arguments.");var n=arguments[1],i=s.arrayOf(arguments).slice(2);if(n instanceof Array&&(i=n.slice(1),n=n[0]),!a.Cursor(n))throw Error("baobab.Combination: argument should be a cursor.");if("or"!==t&&"and"!==t)throw Error("baobab.Combination: invalid operator.");o.call(this),this.cursors=[n],this.operators=[],this.tree=n.tree,this.updates=new Array(this.cursors.length),this.cursorListener=function(){r.updates[r.cursors.indexOf(this)]=!0},this.treeListener=function(){var t,e,n=r.updates[0];for(t=1,e=r.cursors.length;e>t;t++)n="or"===r.operators[t-1]?n||r.updates[t]:n&&r.updates[t];n&&r.emit("update"),r.updates=new Array(r.cursors.length)},this.bound=!1;var h=(this.on,this.once,function(){r.bound||(r.bound=!0,r.cursors.forEach(function(t){e(r,t)}))});this.on=s.before(h,this.on.bind(this)),this.once=s.before(h,this.once.bind(this)),i.forEach(function(r){this[t](r)},this)}function i(t){n.prototype[t]=function(r){if(!a.Cursor(r))throw this.release(),Error("baobab.Combination."+t+": argument should be a cursor.");if(~this.cursors.indexOf(r))throw this.release(),Error("baobab.Combination."+t+": cursor already in combination.");return this.cursors.push(r),this.operators.push(t),this.updates.length++,this.bound&&e(this,r),this}}var o=t("emmett"),s=t("./helpers.js"),a=t("./type.js");s.inherits(n,o),i("or"),i("and"),n.prototype.release=function(){this.cursors.forEach(function(t){t.off("update",this.cursorListener)},this),this.tree.off("update",this.treeListener),this.cursors=null,this.operators=null,this.tree=null,this.updates=null,this.kill()},r.exports=n},{"./helpers.js":7,"./type.js":10,emmett:3}],6:[function(t,r){function e(t,r,e,n){function i(t){if(s.isRecording()&&!s.undoing){var r=h.getIn(t,s.solvedPath,s.tree),e=h.deepClone(r);s.archive.add(e)}return s.undoing=!1,s.emit("update")}var s=this;o.call(this),r=r||[],this.tree=t,this.path=r,this.hash=n,this.archive=null,this.undoing=!1,this.complexPath=!!e,this.solvedPath=this.complexPath?e:this.path,this.relevant=void 0!==this.get(),this.updateHandler=function(t){var r,e,n,o,a,u,c=t.data.log,l=t.data.previousState,f=!1;if(s.complexPath&&(s.solvedPath=h.solvePath(s.tree.data,s.path,s.tree)),!s.path.length)return i(l);if(s.solvedPath)t:for(a=0,n=c.length;n>a;a++)for(r=c[a],u=0,o=r.length;o>u&&(e=r[u],e===""+s.solvedPath[u]);u++)if(u+1===o||u+1===s.solvedPath.length){f=!0;break t}var p=void 0!==s.get();s.relevant?p&&f?i(l):p||(s.emit("irrelevant"),s.relevant=!1):p&&f&&(s.emit("relevant"),i(l),s.relevant=!0)},this.mixin=a.cursor(this);var u=!1;this._lazyBind=function(){u||(u=!0,s.tree.on("update",s.updateHandler))},this.on=h.before(this._lazyBind,this.on.bind(this)),this.once=h.before(this._lazyBind,this.once.bind(this)),this.complexPath&&this._lazyBind()}function n(t,r,e,n){arguments.length<4&&(n=e,e=[]),e=e||[];var i=[].concat(e),o=h.solvePath(this.get(),i,this.tree);if(!o)throw Error("baobab.Cursor."+t+": could not solve dynamic path.");if(r){var s=this.get(o);if(!u[r](s))throw Error("baobab.Cursor."+t+": invalid target.")}var a={};a["$"+t]=n;var c=h.pathObject(o,a);return c}function i(t,r){e.prototype[t]=function(){var e=n.bind(this,t,r).apply(this,arguments);return this.update(e)}}var o=t("emmett"),s=t("./combination.js"),a=t("./mixins.js"),h=t("./helpers.js"),u=(t("../defaults.js"),t("./type.js"));h.inherits(e,o),e.prototype.isRoot=function(){return!this.path.length},e.prototype.isLeaf=function(){return u.Primitive(this.get())},e.prototype.isBranch=function(){return!this.isLeaf()&&!this.isRoot()},e.prototype.root=function(){return this.tree.root()},e.prototype.select=function(t){if(arguments.length>1&&(t=h.arrayOf(arguments)),!u.Path(t))throw Error("baobab.Cursor.select: invalid path.");return this.tree.select(this.path.concat(t))},e.prototype.up=function(){return this.solvedPath&&this.solvedPath.length?this.tree.select(this.path.slice(0,-1)):null},e.prototype.left=function(){var t=+this.solvedPath[this.solvedPath.length-1];if(isNaN(t))throw Error("baobab.Cursor.left: cannot go left on a non-list type.");return t?this.tree.select(this.solvedPath.slice(0,-1).concat(t-1)):null},e.prototype.leftmost=function(){var t=+this.solvedPath[this.solvedPath.length-1];if(isNaN(t))throw Error("baobab.Cursor.leftmost: cannot go left on a non-list type.");return this.tree.select(this.solvedPath.slice(0,-1).concat(0))},e.prototype.right=function(){var t=+this.solvedPath[this.solvedPath.length-1];if(isNaN(t))throw Error("baobab.Cursor.right: cannot go right on a non-list type.");return t+1===this.up().get().length?null:this.tree.select(this.solvedPath.slice(0,-1).concat(t+1))},e.prototype.rightmost=function(){var t=+this.solvedPath[this.solvedPath.length-1];if(isNaN(t))throw Error("baobab.Cursor.right: cannot go right on a non-list type.");var r=this.up().get();return this.tree.select(this.solvedPath.slice(0,-1).concat(r.length-1))},e.prototype.down=function(){+this.solvedPath[this.solvedPath.length-1];return this.get()instanceof Array?this.tree.select(this.solvedPath.concat(0)):null},e.prototype.get=function(t){arguments.length>1&&(t=h.arrayOf(arguments));var r=this.solvedPath.concat((u.String(t)||u.Number(t)?[t]:t)||[]);return h.getIn(this.tree.data,r,this.tree)},i("set"),i("apply"),i("chain"),i("push","Array"),i("unshift","Array"),e.prototype.merge=function(t){if(!u.Object(t))throw Error("baobab.Cursor.merge: trying to merge a non-object.");var r=n.bind(this,"merge","Object").apply(this,arguments);return this.update(r)},e.prototype.unset=function(t){if(void 0===t&&this.isRoot())throw Error("baobab.Cursor.unset: cannot remove root node.");var r=n.bind(this,"unset",null).apply(this,[t,!0]);return this.update(r)},e.prototype.update=function(t,r){if(arguments.length<2)return this.tree.stack(h.pathObject(this.solvedPath,t)),this;var e=[].concat(t),n=h.solvePath(this.get(),e,this.tree);if(!n)throw Error("baobab.Cursor.update: could not solve dynamic path.");return this.tree.stack(h.pathObject(this.solvedPath.concat(n),r)),this},e.prototype.or=function(t){return new s("or",this,t)},e.prototype.and=function(t){return new s("and",this,t)},e.prototype.startRecording=function(t){if(t=t||5,1>t)throw Error("baobab.Cursor.startRecording: invalid maximum number of records.");return this.archive?this:(this._lazyBind(),this.archive=h.archive(t),this)},e.prototype.stopRecording=function(){return this.archive=null,this},e.prototype.undo=function(t){if(t=t||1,!this.isRecording())throw Error("baobab.Cursor.undo: cursor is not recording.");if(!u.PositiveInteger(t))throw Error("baobab.Cursor.undo: expecting a positive integer.");var r=this.archive.back(t);if(!r)throw Error("boabab.Cursor.undo: cannot find a relevant record ("+t+" back).");return this.undoing=!0,this.set(r)},e.prototype.isRecording=function(){return!!this.archive},e.prototype.hasHistory=function(){return!(!this.archive||!this.archive.get().length)},e.prototype.getHistory=function(){return this.archive?this.archive.get():[]},e.prototype.release=function(){this.tree.off("update",this.updateHandler),this.hash&&delete this.tree._cursors[this.hash],delete this.tree,delete this.path,delete this.solvedPath,delete this.archive,this.kill()},e.prototype.toJSON=function(){return this.get()},u.Cursor=function(t){return t instanceof e},r.exports=e},{"../defaults.js":2,"./combination.js":5,"./helpers.js":7,"./mixins.js":9,"./type.js":10,emmett:3}],7:[function(t,r){(function(e){function n(t){return Array.prototype.slice.call(t)}function i(t,r){return function(){t(),r.apply(null,arguments)}}function o(t,r){var e,n={};for(e in t)n[e]=t[e];for(e in r)n[e]=r[e];return n}function s(t){var r=t.source,e="";return t.global&&(e+="g"),t.multiline&&(e+="m"),t.ignoreCase&&(e+="i"),t.sticky&&(e+="y"),t.unicode&&(e+="u"),new RegExp(r,e)}function a(t,r){if(!r||"object"!=typeof r||r instanceof Error||"ArrayBuffer"in e&&r instanceof ArrayBuffer)return r;if(_.Array(r)){if(t){var n,i,o=[];for(n=0,i=r.length;i>n;n++)o.push(w(r[n]));return o}return r.slice(0)}if(_.Date(r))return new Date(r.getTime());if(r instanceof RegExp)return s(r);if(_.Object(r)){var a,h={};r.constructor&&r.constructor!==Object&&(h=Object.create(r.constructor.prototype));for(a in r)r.hasOwnProperty(a)&&(h[a]=t?w(r[a]):r[a]);return h}return r}function h(t,r){return function(e){return r(t(e))}}function u(t,r){var e,n;for(e=0,n=t.length;n>e;e++)if(r(t[e]))return t[e]}function c(t,r){var e,n;for(e=0,n=t.length;n>e;e++)if(r(t[e]))return e;return-1}function l(t,r){var e,n=!0;if(!t)return!1;for(e in r)if(_.Object(r[e]))n=n&&l(t[e],r[e]);else if(_.Array(r[e]))n=n&&!!~r[e].indexOf(t[e]);else if(t[e]!==r[e])return!1;return n}function f(t,r){return u(t,function(t){return l(t,r)})}function d(t,r){return c(t,function(t){return l(t,r)})}function b(t,r,e){r=r||[];var n,i,o,s=t;for(i=0,o=r.length;o>i;i++){if(!s)return;if("function"==typeof r[i]){if(!_.Array(s))return;s=u(s,r[i])}else if("object"==typeof r[i])if(e&&"$cursor"in r[i]){if(!_.Path(r[i].$cursor))throw Error("baobab.getIn: $cursor path must be an array.");n=e.get(r[i].$cursor),s=s[n]}else{if(!_.Array(s))return;s=f(s,r[i])}else s=s[r[i]]}return s}function y(t,r,e){var n,i,o,s=[],a=t;for(i=0,o=r.length;o>i;i++){if(!a)return null;if("function"==typeof r[i]){if(!_.Array(a))return;n=c(a,r[i]),s.push(n),a=a[n]}else if("object"==typeof r[i])if(e&&"$cursor"in r[i]){if(!_.Path(r[i].$cursor))throw Error("baobab.getIn: $cursor path must be an array.");p=e.get(r[i].$cursor),s.push(p),a=a[p]}else{if(!_.Array(a))return;n=d(a,r[i]),s.push(n),a=a[n]}else s.push(r[i]),a=a[r[i]]||{}}return s}function g(t,r){var e,n=t.length,i={},o=i;for(n||(i=r),e=0;n>e;e++)o[t[e]]=e+1===n?r:{},o=o[t[e]];return i}function m(t,r){t.super_=r;var e=function(){};e.prototype=r.prototype,t.prototype=new e,t.prototype.constructor=t}function v(t){var r=[];return{add:function(e){for(r.unshift(e);r.length>t;)r.pop()},back:function(t){var e=r[t-1];return e&&(r=r.slice(t)),e},get:function(){return r}}}var _=t("./type.js"),j=a.bind(null,!1),w=a.bind(null,!0);r.exports={archive:v,arrayOf:n,before:i,deepClone:w,shallowClone:j,shallowMerge:o,compose:h,getIn:b,inherits:m,pathObject:g,solvePath:y}}).call(this,"undefined"!=typeof global?global:"undefined"!=typeof self?self:"undefined"!=typeof window?window:{})},{"./type.js":10}],8:[function(t,r){function e(t,r,e){s.forEach(function(r){e!==r&&delete t[r]}),t[e]=r[e]}function n(t,r){var a,h=i.shallowClone(r||{});s.forEach(function(r){t[r]&&e(h,t,r)}),t.$chain&&(s.slice(0,-1).forEach(function(t){delete h[t]}),h.$apply=h.$apply?i.compose(h.$apply,t.$chain):t.$chain),t.$push&&h.$push?h.$push=o.Array(h.$push)?h.$push.concat(t.$push):[h.$push].concat(t.$push):t.$push&&(h.$push=t.$push),t.$unshift&&h.$unshift?h.$unshift=o.Array(t.$unshift)?t.$unshift.concat(h.$unshift):[t.$unshift].concat(h.$unshift):t.$unshift&&(h.$unshift=t.$unshift);for(a in t)o.Object(t[a])?h[a]=n(t[a],h[a]):"$"!==a[0]&&(h[a]=t[a]);return h}var i=t("./helpers.js"),o=t("./type.js"),s=["$unset","$set","$merge","$apply"];r.exports=n},{"./helpers.js":7,"./type.js":10}],9:[function(t,r){var e=t("./combination.js"),n=t("./type.js");r.exports={baobab:function(t){return{mixins:[{getInitialState:function(){if(this.tree=t,!this.cursor&&!this.cursors)return{};if(this.cursor&&this.cursors)throw Error("baobab.mixin: you cannot have both `component.cursor` and `component.cursors`. Please make up your mind.");if(this.__type=null,this.__updateHandler=function(){this.setState(this.__getCursorData())}.bind(this),this.cursor){if(!n.MixinCursor(this.cursor))throw Error("baobab.mixin.cursor: invalid data (cursor, string, array or function).");n.Function(this.cursor)&&(this.cursor=this.cursor()),n.Cursor(this.cursor)||(this.cursor=t.select(this.cursor)),this.__getCursorData=function(){return{cursor:this.cursor.get()}}.bind(this),this.__type="single"}else if(this.cursors){if(!n.MixinCursors(this.cursors))throw Error("baobab.mixin.cursor: invalid data (object, array or function).");if(n.Function(this.cursors)&&(this.cursors=this.cursors()),n.Array(this.cursors))this.cursors=this.cursors.map(function(r){return n.Cursor(r)?r:t.select(r)}),this.__getCursorData=function(){return{cursors:this.cursors.map(function(t){return t.get()})}}.bind(this),this.__type="array";else{for(var r in this.cursors)n.Cursor(this.cursors[r])||(this.cursors[r]=t.select(this.cursors[r]));this.__getCursorData=function(){var t={};for(r in this.cursors)t[r]=this.cursors[r].get();return{cursors:t}}.bind(this),this.__type="object"}}return this.__getCursorData()},componentDidMount:function(){"single"===this.__type?(this.__combination=new e("or",[this.cursor]),this.__combination.on("update",this.__updateHandler)):"array"===this.__type?(this.__combination=new e("or",this.cursors),this.__combination.on("update",this.__updateHandler)):"object"===this.__type&&(this.__combination=new e("or",Object.keys(this.cursors).map(function(t){return this.cursors[t]},this)),this.__combination.on("update",this.__updateHandler))},componentWillUnmount:function(){this.__combination&&this.__combination.release()}}].concat(t.options.mixins)}},cursor:function(t){return{mixins:[{getInitialState:function(){return this.cursor=t,this.__updateHandler=function(){this.setState({cursor:this.cursor.get()})}.bind(this),{cursor:this.cursor.get()}},componentDidMount:function(){this.cursor.on("update",this.__updateHandler)},componentWillUnmount:function(){this.cursor.off("update",this.__updateHandler)}}].concat(t.tree.options.mixins)}}}},{"./combination.js":5,"./type.js":10}],10:[function(t,r){function e(t,r){return r.some(function(r){return n[r](t)})}var n={};n.Array=function(t){return Array.isArray(t)},n.Object=function(t){return!Array.isArray(t)&&"object"==typeof t&&null!==t},n.String=function(t){return"string"==typeof t},n.Number=function(t){return"number"==typeof t},n.PositiveInteger=function(t){return"number"==typeof t&&t>0&&!(t%1)},n.Function=function(t){return"function"==typeof t},n.Primitive=function(t){return"string"==typeof t||"number"==typeof t||"boolean"==typeof t},n.Date=function(t){return t instanceof Date},n.NonScalar=function(t){return n.Object(t)||n.Array(t)},n.Path=function(t){var r=["String","Number","Function","Object"];return n.Array(t)?t.every(function(t){return e(t,r)}):e(t,r)},n.MixinCursor=function(t){return e(t,["String","Number","Array","Function","Cursor"])},n.MixinCursors=function(t){return e(t,["Object","Array","Function"])},n.ComplexPath=function(t){return t.some(function(t){return e(t,["Object","Function"])})},r.exports=n},{}],11:[function(t,r){function e(t,r){var e=new Error("baobab.update: "+r+" at path /"+t.slice(1).join("/"));return e.path=t,e}var n=t("./helpers.js"),i=t("./type.js");r.exports=function(t,r,o){if(o=o||{},!i.Object(t)&&!i.Array(t))throw Error("baobab.update: invalid target.");var s={};t={root:n.shallowClone(t)};var a=function(t,r,o,h){o=o||["root"];var u,c,l,f=o.join("|λ|"),p=o[o.length-1],d=Object.keys(r).some(function(t){return!!~["$unset","$set","$apply","$merge","$push","$unshift"].indexOf(t)});if(d){s[f]=!0;for(c in r){if("$unset"===c){var b=o[o.length-2];i.Array(t)?h[b]=t.slice(0,+p).concat(t.slice(+p+1)):(h[b]=n.shallowClone(t),delete h[b][p]);break}if("$set"===c){l=r.$set,t[p]=l;break}if("$apply"===c){if(u=r.$apply,"function"!=typeof u)throw e(o,"using command $apply with a non function");t[p]=u.call(null,t[p]);break}if("$merge"===c){if(l=r.$merge,!i.Object(t[p])||!i.Object(l))throw e(o,"using command $merge with a non object");t[p]=n.shallowMerge(t[p],l);break}if("$push"===c){if(l=r.$push,!i.Array(t[p]))throw e(o,"using command $push to a non array");t[p]=t[p].concat(l)}if("$unshift"===c){if(l=r.$unshift,!i.Array(t[p]))throw e(o,"using command $unshift to a non array");t[p]=[].concat(l).concat(t[p])}}}else for(c in r)t[p][c]="undefined"==typeof t[p][c]?{}:n.shallowClone(t[p][c]),a(t[p],r[c],o.concat(c),t)};return a(t,r),{data:t.root,log:Object.keys(s).map(function(t){return t.split("|λ|").slice(1)})}}},{"./helpers.js":7,"./type.js":10}]},{},[1])(1)}); \ No newline at end of file diff --git a/gulpfile.js b/gulpfile.js index 1b921be..1789313 100644 --- a/gulpfile.js +++ b/gulpfile.js @@ -2,10 +2,10 @@ var gulp = require('gulp'), jshint = require('gulp-jshint'), mocha = require('gulp-mocha'), uglify = require('gulp-uglify'), - rename = require('gulp-rename'), header = require('gulp-header'), replace = require('gulp-replace'), - transform = require('vinyl-transform'), + source = require('vinyl-source-stream'), + buffer = require('vinyl-buffer'), browserify = require('browserify'), pkg = require('./package.json'); @@ -34,19 +34,15 @@ gulp.task('test', ['gremlins'], function() { // Building gulp.task('build', function() { - var bundle = transform(function(filename) { - return browserify({ - entries: filename, - standalone: 'Baobab', - fullPaths: false - }).bundle(); - }); - - return gulp.src('./index.js') - .pipe(bundle) + return browserify({ + entries: './index.js', + standalone: 'Baobab', + fullPaths: false + }).bundle() + .pipe(source('baobab.min.js')) + .pipe(buffer()) .pipe(uglify()) .pipe(header('/* baobab.js - Version: ' + pkg.version + ' - Author: Yomguithereal (Guillaume Plique) */\n')) - .pipe(rename('baobab.min.js')) .pipe(gulp.dest('./build')); }); diff --git a/package.json b/package.json index 028f741..cacc4ee 100644 --- a/package.json +++ b/package.json @@ -13,14 +13,14 @@ "gulp-header": "^1.2.2", "gulp-jshint": "^1.9.0", "gulp-mocha": "^2.0.0", - "gulp-rename": "^1.2.0", "gulp-replace": "^0.5.3", "gulp-uglify": "^1.0.2", "jsdom": "^3.1.0", "lodash.clonedeep": "^3.0.0", "mocha": "^2.0.1", "react": "^0.13.0", - "vinyl-transform": "^1.0.0" + "vinyl-buffer": "^1.0.0", + "vinyl-source-stream": "^1.1.0" }, "scripts": { "test": "gulp test", From 69991304de35d751c0e166a628bb8a5fe17a6964 Mon Sep 17 00:00:00 2001 From: Yomguithereal Date: Thu, 9 Apr 2015 22:24:16 +0200 Subject: [PATCH 38/73] Fix #165 - warning when too many arguments are applied to setters. --- build/baobab.min.js | 2 +- src/cursor.js | 3 +++ test/suites/cursor.js | 9 +++++++++ 3 files changed, 13 insertions(+), 1 deletion(-) diff --git a/build/baobab.min.js b/build/baobab.min.js index 2dc0d6c..3c22cdb 100644 --- a/build/baobab.min.js +++ b/build/baobab.min.js @@ -1,2 +1,2 @@ /* baobab.js - Version: 1.0.0-rc1 - Author: Yomguithereal (Guillaume Plique) */ -!function(t){if("object"==typeof exports&&"undefined"!=typeof module)module.exports=t();else if("function"==typeof define&&define.amd)define([],t);else{var r;r="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:this,r.Baobab=t()}}(function(){var t;return function r(t,e,n){function i(s,a){if(!e[s]){if(!t[s]){var h="function"==typeof require&&require;if(!a&&h)return h(s,!0);if(o)return o(s,!0);var u=new Error("Cannot find module '"+s+"'");throw u.code="MODULE_NOT_FOUND",u}var c=e[s]={exports:{}};t[s][0].call(c.exports,function(r){var e=t[s][1][r];return i(e?e:r)},c,c.exports,r,t,e,n)}return e[s].exports}for(var o="function"==typeof require&&require,s=0;sr;r++)n.push(t[r].handler);return n}var i={once:"boolean",scope:"object"},o=function(){this._enabled=!0,this._children=[],this._handlers={},this._handlersAll=[]};o.prototype.on=function(t,r,e){var n,s,a,h,u,c;if("function"==typeof r){for(u="string"==typeof t?[t]:t,n=0,s=u.length;n!==s;n+=1)if(h=u[n]){this._handlers[h]||(this._handlers[h]=[]),c={handler:r};for(a in e||{}){if(!i[a])throw new Error('The option "'+a+'" is not recognized by Emmett.');c[a]=e[a]}this._handlers[h].push(c)}}else if(t&&"object"==typeof t&&!Array.isArray(t))for(h in t)o.prototype.on.call(this,h,t[h],r);else{if("function"!=typeof t)throw new Error("Wrong arguments.");c={handler:t};for(a in e||{}){if(!i[a])throw new Error('The option "'+a+'" is not recognized by Emmett.');c[a]=e[a]}this._handlersAll.push(c)}return this},o.prototype.once=function(t,r,e){if("function"==typeof r)e=e||{},e.once=!0,this.on(t,r,e);else{if((!t||"object"!=typeof t||Array.isArray(t))&&"function"!=typeof t)throw new Error("Wrong arguments.");r=r||{},r.once=!0,this.on(t,r)}return this},o.prototype.off=function(t,r){var e,n,i,o,s,a,h,u="string"==typeof t?[t]:t;if(1===arguments.length&&"function"==typeof u){r=arguments[0];for(s in this._handlers){for(a=[],e=0,n=this._handlers[s].length;e!==n;e+=1)this._handlers[s][e].handler!==r&&a.push(this._handlers[s][e]);this._handlers[s]=a}for(a=[],e=0,n=this._handlersAll.length;e!==n;e+=1)this._handlersAll[e].handler!==r&&a.push(this._handlersAll[e]);this._handlersAll=a}else if(2===arguments.length)for(e=0,n=u.length;e!==n;e+=1){if(h=u[e],this._handlers[h]){for(a=[],i=0,o=this._handlers[h].length;i!==o;i+=1)this._handlers[h][i].handler!==r&&a.push(this._handlers[h][i]);this._handlers[h]=a}this._handlers[h]&&0===this._handlers[h].length&&delete this._handlers[h]}return this},o.prototype.unbindAll=function(){var t;this._handlersAll=[];for(t in this._handlers)delete this._handlers[t];return this},o.prototype.emit=function(t,r){var e,n,i,o,s,a,h,u,c,l,f="string"==typeof t?[t]:t;if(!this._enabled)return this;for(r=void 0===r?{}:r,e=0,n=f.length;e!==n;e+=1)if(l=f[e],c=(this._handlers[l]||[]).concat(this._handlersAll),c.length){for(h={type:l,data:r||{},target:this},a=[],i=0,o=c.length;i!==o;i+=1)(this._handlers[l]&&this._handlers[l].indexOf(c[i])>=0||this._handlersAll.indexOf(c[i])>=0)&&(c[i].handler.call("scope"in c[i]?c[i].scope:this,h),c[i].once&&a.push(c[i]));for(s=0;se;e++)if(t._children[e]===r){t._children.splice(e,1);break}}),this._children.push(r),r},o.prototype.listeners=function(t){var e,n,i,o=[];if(t)for(o=r(this._handlers[t]),n=0,i=this._children.length;i>n;n++)o=o.concat(this._children[n].listeners(t));else{o=r(this._handlersAll);for(e in this._handlers)o=o.concat(r(this._handlers[e]));for(n=0,i=this._children.length;i>n;n++)o=o.concat(this._children[n].listeners())}return o},o.prototype.kill=function(){if(this.emit("emmett:kill"),this.unbindAll(),this._handlers=null,this._handlersAll=null,this._enabled=!1,this._children)for(var t=0,r=this._children.length;r>t;t++)this._children[t].kill();this._children=null},o.prototype.disable=function(){return this._enabled=!1,this},o.prototype.enable=function(){return this._enabled=!0,this},o.version="2.1.2","undefined"!=typeof n?("undefined"!=typeof e&&e.exports&&(n=e.exports=o),n.Emitter=o):"function"==typeof t&&t.amd?t("emmett",[],function(){return o}):this.Emitter=o}).call(this)},{}],4:[function(t,r){function e(t){return t+"$"+(new Date).getTime()+(""+Math.random()).replace("0.","")}function n(t,r){function e(t){this[t]=function(){var r=this.root[t].apply(this.root,arguments);return r instanceof i?this:r}}if(arguments.length<1&&(t={}),!(this instanceof n))return new n(t,r);if(!l.Object(t)&&!l.Array(t))throw Error("Baobab: invalid data.");o.call(this),this.options=s.shallowMerge(c,r),this._transaction={},this._future=void 0,this._cursors={},this.data=s.deepClone(t),this.root=this.select([]),["get","set","unset","update"].forEach(e.bind(this)),this.mixin=u.baobab(this)}var i=t("./cursor.js"),o=t("emmett"),s=t("./helpers.js"),a=t("./update.js"),h=t("./merge.js"),u=t("./mixins.js"),c=t("../defaults.js"),l=t("./type.js");s.inherits(n,o),n.prototype.select=function(t){if(!t)throw Error("Baobab.select: invalid path.");if(arguments.length>1&&(t=s.arrayOf(arguments)),!l.Path(t))throw Error("Baobab.select: invalid path.");t=[].concat(t);var r,n=l.ComplexPath(t);n&&(r=s.solvePath(this.data,t,this));var o=t.map(function(t){return l.Function(t)?e("fn"):l.Object(t)?e("ob"):t}).join("|λ|");if(this._cursors[o])return this._cursors[o];var a=new i(this,t,r,o);return this._cursors[o]=a,a},n.prototype.stack=function(t){var r=this;if(!l.Object(t))throw Error("Baobab.update: wrong specification.");return this._transaction=h(t,this._transaction),this.options.autoCommit?this.options.asynchronous?(this._future||(this._future=setTimeout(r.commit.bind(r,null),0)),this):this.commit():this},n.prototype.commit=function(){var t=a(this.data,this._transaction,this.options),r=this.data;return this.data=t.data,this._transaction={},this._future&&(this._future=clearTimeout(this._future)),this.emit("update",{log:t.log,previousState:r}),this},n.prototype.release=function(){delete this.data,delete this._transaction;for(var t in this._cursors)this._cursors[t].release();delete this._cursors,this.kill()},n.prototype.toJSON=function(){return this.get()},r.exports=n},{"../defaults.js":2,"./cursor.js":6,"./helpers.js":7,"./merge.js":8,"./mixins.js":9,"./type.js":10,"./update.js":11,emmett:3}],5:[function(t,r){function e(t,r){r.on("update",t.cursorListener),t.tree.off("update",t.treeListener),t.tree.on("update",t.treeListener)}function n(t){var r=this;if(arguments.length<2)throw Error("baobab.Combination: not enough arguments.");var n=arguments[1],i=s.arrayOf(arguments).slice(2);if(n instanceof Array&&(i=n.slice(1),n=n[0]),!a.Cursor(n))throw Error("baobab.Combination: argument should be a cursor.");if("or"!==t&&"and"!==t)throw Error("baobab.Combination: invalid operator.");o.call(this),this.cursors=[n],this.operators=[],this.tree=n.tree,this.updates=new Array(this.cursors.length),this.cursorListener=function(){r.updates[r.cursors.indexOf(this)]=!0},this.treeListener=function(){var t,e,n=r.updates[0];for(t=1,e=r.cursors.length;e>t;t++)n="or"===r.operators[t-1]?n||r.updates[t]:n&&r.updates[t];n&&r.emit("update"),r.updates=new Array(r.cursors.length)},this.bound=!1;var h=(this.on,this.once,function(){r.bound||(r.bound=!0,r.cursors.forEach(function(t){e(r,t)}))});this.on=s.before(h,this.on.bind(this)),this.once=s.before(h,this.once.bind(this)),i.forEach(function(r){this[t](r)},this)}function i(t){n.prototype[t]=function(r){if(!a.Cursor(r))throw this.release(),Error("baobab.Combination."+t+": argument should be a cursor.");if(~this.cursors.indexOf(r))throw this.release(),Error("baobab.Combination."+t+": cursor already in combination.");return this.cursors.push(r),this.operators.push(t),this.updates.length++,this.bound&&e(this,r),this}}var o=t("emmett"),s=t("./helpers.js"),a=t("./type.js");s.inherits(n,o),i("or"),i("and"),n.prototype.release=function(){this.cursors.forEach(function(t){t.off("update",this.cursorListener)},this),this.tree.off("update",this.treeListener),this.cursors=null,this.operators=null,this.tree=null,this.updates=null,this.kill()},r.exports=n},{"./helpers.js":7,"./type.js":10,emmett:3}],6:[function(t,r){function e(t,r,e,n){function i(t){if(s.isRecording()&&!s.undoing){var r=h.getIn(t,s.solvedPath,s.tree),e=h.deepClone(r);s.archive.add(e)}return s.undoing=!1,s.emit("update")}var s=this;o.call(this),r=r||[],this.tree=t,this.path=r,this.hash=n,this.archive=null,this.undoing=!1,this.complexPath=!!e,this.solvedPath=this.complexPath?e:this.path,this.relevant=void 0!==this.get(),this.updateHandler=function(t){var r,e,n,o,a,u,c=t.data.log,l=t.data.previousState,f=!1;if(s.complexPath&&(s.solvedPath=h.solvePath(s.tree.data,s.path,s.tree)),!s.path.length)return i(l);if(s.solvedPath)t:for(a=0,n=c.length;n>a;a++)for(r=c[a],u=0,o=r.length;o>u&&(e=r[u],e===""+s.solvedPath[u]);u++)if(u+1===o||u+1===s.solvedPath.length){f=!0;break t}var p=void 0!==s.get();s.relevant?p&&f?i(l):p||(s.emit("irrelevant"),s.relevant=!1):p&&f&&(s.emit("relevant"),i(l),s.relevant=!0)},this.mixin=a.cursor(this);var u=!1;this._lazyBind=function(){u||(u=!0,s.tree.on("update",s.updateHandler))},this.on=h.before(this._lazyBind,this.on.bind(this)),this.once=h.before(this._lazyBind,this.once.bind(this)),this.complexPath&&this._lazyBind()}function n(t,r,e,n){arguments.length<4&&(n=e,e=[]),e=e||[];var i=[].concat(e),o=h.solvePath(this.get(),i,this.tree);if(!o)throw Error("baobab.Cursor."+t+": could not solve dynamic path.");if(r){var s=this.get(o);if(!u[r](s))throw Error("baobab.Cursor."+t+": invalid target.")}var a={};a["$"+t]=n;var c=h.pathObject(o,a);return c}function i(t,r){e.prototype[t]=function(){var e=n.bind(this,t,r).apply(this,arguments);return this.update(e)}}var o=t("emmett"),s=t("./combination.js"),a=t("./mixins.js"),h=t("./helpers.js"),u=(t("../defaults.js"),t("./type.js"));h.inherits(e,o),e.prototype.isRoot=function(){return!this.path.length},e.prototype.isLeaf=function(){return u.Primitive(this.get())},e.prototype.isBranch=function(){return!this.isLeaf()&&!this.isRoot()},e.prototype.root=function(){return this.tree.root()},e.prototype.select=function(t){if(arguments.length>1&&(t=h.arrayOf(arguments)),!u.Path(t))throw Error("baobab.Cursor.select: invalid path.");return this.tree.select(this.path.concat(t))},e.prototype.up=function(){return this.solvedPath&&this.solvedPath.length?this.tree.select(this.path.slice(0,-1)):null},e.prototype.left=function(){var t=+this.solvedPath[this.solvedPath.length-1];if(isNaN(t))throw Error("baobab.Cursor.left: cannot go left on a non-list type.");return t?this.tree.select(this.solvedPath.slice(0,-1).concat(t-1)):null},e.prototype.leftmost=function(){var t=+this.solvedPath[this.solvedPath.length-1];if(isNaN(t))throw Error("baobab.Cursor.leftmost: cannot go left on a non-list type.");return this.tree.select(this.solvedPath.slice(0,-1).concat(0))},e.prototype.right=function(){var t=+this.solvedPath[this.solvedPath.length-1];if(isNaN(t))throw Error("baobab.Cursor.right: cannot go right on a non-list type.");return t+1===this.up().get().length?null:this.tree.select(this.solvedPath.slice(0,-1).concat(t+1))},e.prototype.rightmost=function(){var t=+this.solvedPath[this.solvedPath.length-1];if(isNaN(t))throw Error("baobab.Cursor.right: cannot go right on a non-list type.");var r=this.up().get();return this.tree.select(this.solvedPath.slice(0,-1).concat(r.length-1))},e.prototype.down=function(){+this.solvedPath[this.solvedPath.length-1];return this.get()instanceof Array?this.tree.select(this.solvedPath.concat(0)):null},e.prototype.get=function(t){arguments.length>1&&(t=h.arrayOf(arguments));var r=this.solvedPath.concat((u.String(t)||u.Number(t)?[t]:t)||[]);return h.getIn(this.tree.data,r,this.tree)},i("set"),i("apply"),i("chain"),i("push","Array"),i("unshift","Array"),e.prototype.merge=function(t){if(!u.Object(t))throw Error("baobab.Cursor.merge: trying to merge a non-object.");var r=n.bind(this,"merge","Object").apply(this,arguments);return this.update(r)},e.prototype.unset=function(t){if(void 0===t&&this.isRoot())throw Error("baobab.Cursor.unset: cannot remove root node.");var r=n.bind(this,"unset",null).apply(this,[t,!0]);return this.update(r)},e.prototype.update=function(t,r){if(arguments.length<2)return this.tree.stack(h.pathObject(this.solvedPath,t)),this;var e=[].concat(t),n=h.solvePath(this.get(),e,this.tree);if(!n)throw Error("baobab.Cursor.update: could not solve dynamic path.");return this.tree.stack(h.pathObject(this.solvedPath.concat(n),r)),this},e.prototype.or=function(t){return new s("or",this,t)},e.prototype.and=function(t){return new s("and",this,t)},e.prototype.startRecording=function(t){if(t=t||5,1>t)throw Error("baobab.Cursor.startRecording: invalid maximum number of records.");return this.archive?this:(this._lazyBind(),this.archive=h.archive(t),this)},e.prototype.stopRecording=function(){return this.archive=null,this},e.prototype.undo=function(t){if(t=t||1,!this.isRecording())throw Error("baobab.Cursor.undo: cursor is not recording.");if(!u.PositiveInteger(t))throw Error("baobab.Cursor.undo: expecting a positive integer.");var r=this.archive.back(t);if(!r)throw Error("boabab.Cursor.undo: cannot find a relevant record ("+t+" back).");return this.undoing=!0,this.set(r)},e.prototype.isRecording=function(){return!!this.archive},e.prototype.hasHistory=function(){return!(!this.archive||!this.archive.get().length)},e.prototype.getHistory=function(){return this.archive?this.archive.get():[]},e.prototype.release=function(){this.tree.off("update",this.updateHandler),this.hash&&delete this.tree._cursors[this.hash],delete this.tree,delete this.path,delete this.solvedPath,delete this.archive,this.kill()},e.prototype.toJSON=function(){return this.get()},u.Cursor=function(t){return t instanceof e},r.exports=e},{"../defaults.js":2,"./combination.js":5,"./helpers.js":7,"./mixins.js":9,"./type.js":10,emmett:3}],7:[function(t,r){(function(e){function n(t){return Array.prototype.slice.call(t)}function i(t,r){return function(){t(),r.apply(null,arguments)}}function o(t,r){var e,n={};for(e in t)n[e]=t[e];for(e in r)n[e]=r[e];return n}function s(t){var r=t.source,e="";return t.global&&(e+="g"),t.multiline&&(e+="m"),t.ignoreCase&&(e+="i"),t.sticky&&(e+="y"),t.unicode&&(e+="u"),new RegExp(r,e)}function a(t,r){if(!r||"object"!=typeof r||r instanceof Error||"ArrayBuffer"in e&&r instanceof ArrayBuffer)return r;if(_.Array(r)){if(t){var n,i,o=[];for(n=0,i=r.length;i>n;n++)o.push(w(r[n]));return o}return r.slice(0)}if(_.Date(r))return new Date(r.getTime());if(r instanceof RegExp)return s(r);if(_.Object(r)){var a,h={};r.constructor&&r.constructor!==Object&&(h=Object.create(r.constructor.prototype));for(a in r)r.hasOwnProperty(a)&&(h[a]=t?w(r[a]):r[a]);return h}return r}function h(t,r){return function(e){return r(t(e))}}function u(t,r){var e,n;for(e=0,n=t.length;n>e;e++)if(r(t[e]))return t[e]}function c(t,r){var e,n;for(e=0,n=t.length;n>e;e++)if(r(t[e]))return e;return-1}function l(t,r){var e,n=!0;if(!t)return!1;for(e in r)if(_.Object(r[e]))n=n&&l(t[e],r[e]);else if(_.Array(r[e]))n=n&&!!~r[e].indexOf(t[e]);else if(t[e]!==r[e])return!1;return n}function f(t,r){return u(t,function(t){return l(t,r)})}function d(t,r){return c(t,function(t){return l(t,r)})}function b(t,r,e){r=r||[];var n,i,o,s=t;for(i=0,o=r.length;o>i;i++){if(!s)return;if("function"==typeof r[i]){if(!_.Array(s))return;s=u(s,r[i])}else if("object"==typeof r[i])if(e&&"$cursor"in r[i]){if(!_.Path(r[i].$cursor))throw Error("baobab.getIn: $cursor path must be an array.");n=e.get(r[i].$cursor),s=s[n]}else{if(!_.Array(s))return;s=f(s,r[i])}else s=s[r[i]]}return s}function y(t,r,e){var n,i,o,s=[],a=t;for(i=0,o=r.length;o>i;i++){if(!a)return null;if("function"==typeof r[i]){if(!_.Array(a))return;n=c(a,r[i]),s.push(n),a=a[n]}else if("object"==typeof r[i])if(e&&"$cursor"in r[i]){if(!_.Path(r[i].$cursor))throw Error("baobab.getIn: $cursor path must be an array.");p=e.get(r[i].$cursor),s.push(p),a=a[p]}else{if(!_.Array(a))return;n=d(a,r[i]),s.push(n),a=a[n]}else s.push(r[i]),a=a[r[i]]||{}}return s}function g(t,r){var e,n=t.length,i={},o=i;for(n||(i=r),e=0;n>e;e++)o[t[e]]=e+1===n?r:{},o=o[t[e]];return i}function m(t,r){t.super_=r;var e=function(){};e.prototype=r.prototype,t.prototype=new e,t.prototype.constructor=t}function v(t){var r=[];return{add:function(e){for(r.unshift(e);r.length>t;)r.pop()},back:function(t){var e=r[t-1];return e&&(r=r.slice(t)),e},get:function(){return r}}}var _=t("./type.js"),j=a.bind(null,!1),w=a.bind(null,!0);r.exports={archive:v,arrayOf:n,before:i,deepClone:w,shallowClone:j,shallowMerge:o,compose:h,getIn:b,inherits:m,pathObject:g,solvePath:y}}).call(this,"undefined"!=typeof global?global:"undefined"!=typeof self?self:"undefined"!=typeof window?window:{})},{"./type.js":10}],8:[function(t,r){function e(t,r,e){s.forEach(function(r){e!==r&&delete t[r]}),t[e]=r[e]}function n(t,r){var a,h=i.shallowClone(r||{});s.forEach(function(r){t[r]&&e(h,t,r)}),t.$chain&&(s.slice(0,-1).forEach(function(t){delete h[t]}),h.$apply=h.$apply?i.compose(h.$apply,t.$chain):t.$chain),t.$push&&h.$push?h.$push=o.Array(h.$push)?h.$push.concat(t.$push):[h.$push].concat(t.$push):t.$push&&(h.$push=t.$push),t.$unshift&&h.$unshift?h.$unshift=o.Array(t.$unshift)?t.$unshift.concat(h.$unshift):[t.$unshift].concat(h.$unshift):t.$unshift&&(h.$unshift=t.$unshift);for(a in t)o.Object(t[a])?h[a]=n(t[a],h[a]):"$"!==a[0]&&(h[a]=t[a]);return h}var i=t("./helpers.js"),o=t("./type.js"),s=["$unset","$set","$merge","$apply"];r.exports=n},{"./helpers.js":7,"./type.js":10}],9:[function(t,r){var e=t("./combination.js"),n=t("./type.js");r.exports={baobab:function(t){return{mixins:[{getInitialState:function(){if(this.tree=t,!this.cursor&&!this.cursors)return{};if(this.cursor&&this.cursors)throw Error("baobab.mixin: you cannot have both `component.cursor` and `component.cursors`. Please make up your mind.");if(this.__type=null,this.__updateHandler=function(){this.setState(this.__getCursorData())}.bind(this),this.cursor){if(!n.MixinCursor(this.cursor))throw Error("baobab.mixin.cursor: invalid data (cursor, string, array or function).");n.Function(this.cursor)&&(this.cursor=this.cursor()),n.Cursor(this.cursor)||(this.cursor=t.select(this.cursor)),this.__getCursorData=function(){return{cursor:this.cursor.get()}}.bind(this),this.__type="single"}else if(this.cursors){if(!n.MixinCursors(this.cursors))throw Error("baobab.mixin.cursor: invalid data (object, array or function).");if(n.Function(this.cursors)&&(this.cursors=this.cursors()),n.Array(this.cursors))this.cursors=this.cursors.map(function(r){return n.Cursor(r)?r:t.select(r)}),this.__getCursorData=function(){return{cursors:this.cursors.map(function(t){return t.get()})}}.bind(this),this.__type="array";else{for(var r in this.cursors)n.Cursor(this.cursors[r])||(this.cursors[r]=t.select(this.cursors[r]));this.__getCursorData=function(){var t={};for(r in this.cursors)t[r]=this.cursors[r].get();return{cursors:t}}.bind(this),this.__type="object"}}return this.__getCursorData()},componentDidMount:function(){"single"===this.__type?(this.__combination=new e("or",[this.cursor]),this.__combination.on("update",this.__updateHandler)):"array"===this.__type?(this.__combination=new e("or",this.cursors),this.__combination.on("update",this.__updateHandler)):"object"===this.__type&&(this.__combination=new e("or",Object.keys(this.cursors).map(function(t){return this.cursors[t]},this)),this.__combination.on("update",this.__updateHandler))},componentWillUnmount:function(){this.__combination&&this.__combination.release()}}].concat(t.options.mixins)}},cursor:function(t){return{mixins:[{getInitialState:function(){return this.cursor=t,this.__updateHandler=function(){this.setState({cursor:this.cursor.get()})}.bind(this),{cursor:this.cursor.get()}},componentDidMount:function(){this.cursor.on("update",this.__updateHandler)},componentWillUnmount:function(){this.cursor.off("update",this.__updateHandler)}}].concat(t.tree.options.mixins)}}}},{"./combination.js":5,"./type.js":10}],10:[function(t,r){function e(t,r){return r.some(function(r){return n[r](t)})}var n={};n.Array=function(t){return Array.isArray(t)},n.Object=function(t){return!Array.isArray(t)&&"object"==typeof t&&null!==t},n.String=function(t){return"string"==typeof t},n.Number=function(t){return"number"==typeof t},n.PositiveInteger=function(t){return"number"==typeof t&&t>0&&!(t%1)},n.Function=function(t){return"function"==typeof t},n.Primitive=function(t){return"string"==typeof t||"number"==typeof t||"boolean"==typeof t},n.Date=function(t){return t instanceof Date},n.NonScalar=function(t){return n.Object(t)||n.Array(t)},n.Path=function(t){var r=["String","Number","Function","Object"];return n.Array(t)?t.every(function(t){return e(t,r)}):e(t,r)},n.MixinCursor=function(t){return e(t,["String","Number","Array","Function","Cursor"])},n.MixinCursors=function(t){return e(t,["Object","Array","Function"])},n.ComplexPath=function(t){return t.some(function(t){return e(t,["Object","Function"])})},r.exports=n},{}],11:[function(t,r){function e(t,r){var e=new Error("baobab.update: "+r+" at path /"+t.slice(1).join("/"));return e.path=t,e}var n=t("./helpers.js"),i=t("./type.js");r.exports=function(t,r,o){if(o=o||{},!i.Object(t)&&!i.Array(t))throw Error("baobab.update: invalid target.");var s={};t={root:n.shallowClone(t)};var a=function(t,r,o,h){o=o||["root"];var u,c,l,f=o.join("|λ|"),p=o[o.length-1],d=Object.keys(r).some(function(t){return!!~["$unset","$set","$apply","$merge","$push","$unshift"].indexOf(t)});if(d){s[f]=!0;for(c in r){if("$unset"===c){var b=o[o.length-2];i.Array(t)?h[b]=t.slice(0,+p).concat(t.slice(+p+1)):(h[b]=n.shallowClone(t),delete h[b][p]);break}if("$set"===c){l=r.$set,t[p]=l;break}if("$apply"===c){if(u=r.$apply,"function"!=typeof u)throw e(o,"using command $apply with a non function");t[p]=u.call(null,t[p]);break}if("$merge"===c){if(l=r.$merge,!i.Object(t[p])||!i.Object(l))throw e(o,"using command $merge with a non object");t[p]=n.shallowMerge(t[p],l);break}if("$push"===c){if(l=r.$push,!i.Array(t[p]))throw e(o,"using command $push to a non array");t[p]=t[p].concat(l)}if("$unshift"===c){if(l=r.$unshift,!i.Array(t[p]))throw e(o,"using command $unshift to a non array");t[p]=[].concat(l).concat(t[p])}}}else for(c in r)t[p][c]="undefined"==typeof t[p][c]?{}:n.shallowClone(t[p][c]),a(t[p],r[c],o.concat(c),t)};return a(t,r),{data:t.root,log:Object.keys(s).map(function(t){return t.split("|λ|").slice(1)})}}},{"./helpers.js":7,"./type.js":10}]},{},[1])(1)}); \ No newline at end of file +!function(t){if("object"==typeof exports&&"undefined"!=typeof module)module.exports=t();else if("function"==typeof define&&define.amd)define([],t);else{var r;r="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:this,r.Baobab=t()}}(function(){var t;return function r(t,e,n){function i(s,a){if(!e[s]){if(!t[s]){var h="function"==typeof require&&require;if(!a&&h)return h(s,!0);if(o)return o(s,!0);var u=new Error("Cannot find module '"+s+"'");throw u.code="MODULE_NOT_FOUND",u}var c=e[s]={exports:{}};t[s][0].call(c.exports,function(r){var e=t[s][1][r];return i(e?e:r)},c,c.exports,r,t,e,n)}return e[s].exports}for(var o="function"==typeof require&&require,s=0;sr;r++)n.push(t[r].handler);return n}var i={once:"boolean",scope:"object"},o=function(){this._enabled=!0,this._children=[],this._handlers={},this._handlersAll=[]};o.prototype.on=function(t,r,e){var n,s,a,h,u,c;if("function"==typeof r){for(u="string"==typeof t?[t]:t,n=0,s=u.length;n!==s;n+=1)if(h=u[n]){this._handlers[h]||(this._handlers[h]=[]),c={handler:r};for(a in e||{}){if(!i[a])throw new Error('The option "'+a+'" is not recognized by Emmett.');c[a]=e[a]}this._handlers[h].push(c)}}else if(t&&"object"==typeof t&&!Array.isArray(t))for(h in t)o.prototype.on.call(this,h,t[h],r);else{if("function"!=typeof t)throw new Error("Wrong arguments.");c={handler:t};for(a in e||{}){if(!i[a])throw new Error('The option "'+a+'" is not recognized by Emmett.');c[a]=e[a]}this._handlersAll.push(c)}return this},o.prototype.once=function(t,r,e){if("function"==typeof r)e=e||{},e.once=!0,this.on(t,r,e);else{if((!t||"object"!=typeof t||Array.isArray(t))&&"function"!=typeof t)throw new Error("Wrong arguments.");r=r||{},r.once=!0,this.on(t,r)}return this},o.prototype.off=function(t,r){var e,n,i,o,s,a,h,u="string"==typeof t?[t]:t;if(1===arguments.length&&"function"==typeof u){r=arguments[0];for(s in this._handlers){for(a=[],e=0,n=this._handlers[s].length;e!==n;e+=1)this._handlers[s][e].handler!==r&&a.push(this._handlers[s][e]);this._handlers[s]=a}for(a=[],e=0,n=this._handlersAll.length;e!==n;e+=1)this._handlersAll[e].handler!==r&&a.push(this._handlersAll[e]);this._handlersAll=a}else if(2===arguments.length)for(e=0,n=u.length;e!==n;e+=1){if(h=u[e],this._handlers[h]){for(a=[],i=0,o=this._handlers[h].length;i!==o;i+=1)this._handlers[h][i].handler!==r&&a.push(this._handlers[h][i]);this._handlers[h]=a}this._handlers[h]&&0===this._handlers[h].length&&delete this._handlers[h]}return this},o.prototype.unbindAll=function(){var t;this._handlersAll=[];for(t in this._handlers)delete this._handlers[t];return this},o.prototype.emit=function(t,r){var e,n,i,o,s,a,h,u,c,l,f="string"==typeof t?[t]:t;if(!this._enabled)return this;for(r=void 0===r?{}:r,e=0,n=f.length;e!==n;e+=1)if(l=f[e],c=(this._handlers[l]||[]).concat(this._handlersAll),c.length){for(h={type:l,data:r||{},target:this},a=[],i=0,o=c.length;i!==o;i+=1)(this._handlers[l]&&this._handlers[l].indexOf(c[i])>=0||this._handlersAll.indexOf(c[i])>=0)&&(c[i].handler.call("scope"in c[i]?c[i].scope:this,h),c[i].once&&a.push(c[i]));for(s=0;se;e++)if(t._children[e]===r){t._children.splice(e,1);break}}),this._children.push(r),r},o.prototype.listeners=function(t){var e,n,i,o=[];if(t)for(o=r(this._handlers[t]),n=0,i=this._children.length;i>n;n++)o=o.concat(this._children[n].listeners(t));else{o=r(this._handlersAll);for(e in this._handlers)o=o.concat(r(this._handlers[e]));for(n=0,i=this._children.length;i>n;n++)o=o.concat(this._children[n].listeners())}return o},o.prototype.kill=function(){if(this.emit("emmett:kill"),this.unbindAll(),this._handlers=null,this._handlersAll=null,this._enabled=!1,this._children)for(var t=0,r=this._children.length;r>t;t++)this._children[t].kill();this._children=null},o.prototype.disable=function(){return this._enabled=!1,this},o.prototype.enable=function(){return this._enabled=!0,this},o.version="2.1.2","undefined"!=typeof n?("undefined"!=typeof e&&e.exports&&(n=e.exports=o),n.Emitter=o):"function"==typeof t&&t.amd?t("emmett",[],function(){return o}):this.Emitter=o}).call(this)},{}],4:[function(t,r){function e(t){return t+"$"+(new Date).getTime()+(""+Math.random()).replace("0.","")}function n(t,r){function e(t){this[t]=function(){var r=this.root[t].apply(this.root,arguments);return r instanceof i?this:r}}if(arguments.length<1&&(t={}),!(this instanceof n))return new n(t,r);if(!l.Object(t)&&!l.Array(t))throw Error("Baobab: invalid data.");o.call(this),this.options=s.shallowMerge(c,r),this._transaction={},this._future=void 0,this._cursors={},this.data=s.deepClone(t),this.root=this.select([]),["get","set","unset","update"].forEach(e.bind(this)),this.mixin=u.baobab(this)}var i=t("./cursor.js"),o=t("emmett"),s=t("./helpers.js"),a=t("./update.js"),h=t("./merge.js"),u=t("./mixins.js"),c=t("../defaults.js"),l=t("./type.js");s.inherits(n,o),n.prototype.select=function(t){if(!t)throw Error("Baobab.select: invalid path.");if(arguments.length>1&&(t=s.arrayOf(arguments)),!l.Path(t))throw Error("Baobab.select: invalid path.");t=[].concat(t);var r,n=l.ComplexPath(t);n&&(r=s.solvePath(this.data,t,this));var o=t.map(function(t){return l.Function(t)?e("fn"):l.Object(t)?e("ob"):t}).join("|λ|");if(this._cursors[o])return this._cursors[o];var a=new i(this,t,r,o);return this._cursors[o]=a,a},n.prototype.stack=function(t){var r=this;if(!l.Object(t))throw Error("Baobab.update: wrong specification.");return this._transaction=h(t,this._transaction),this.options.autoCommit?this.options.asynchronous?(this._future||(this._future=setTimeout(r.commit.bind(r,null),0)),this):this.commit():this},n.prototype.commit=function(){var t=a(this.data,this._transaction,this.options),r=this.data;return this.data=t.data,this._transaction={},this._future&&(this._future=clearTimeout(this._future)),this.emit("update",{log:t.log,previousState:r}),this},n.prototype.release=function(){delete this.data,delete this._transaction;for(var t in this._cursors)this._cursors[t].release();delete this._cursors,this.kill()},n.prototype.toJSON=function(){return this.get()},r.exports=n},{"../defaults.js":2,"./cursor.js":6,"./helpers.js":7,"./merge.js":8,"./mixins.js":9,"./type.js":10,"./update.js":11,emmett:3}],5:[function(t,r){function e(t,r){r.on("update",t.cursorListener),t.tree.off("update",t.treeListener),t.tree.on("update",t.treeListener)}function n(t){var r=this;if(arguments.length<2)throw Error("baobab.Combination: not enough arguments.");var n=arguments[1],i=s.arrayOf(arguments).slice(2);if(n instanceof Array&&(i=n.slice(1),n=n[0]),!a.Cursor(n))throw Error("baobab.Combination: argument should be a cursor.");if("or"!==t&&"and"!==t)throw Error("baobab.Combination: invalid operator.");o.call(this),this.cursors=[n],this.operators=[],this.tree=n.tree,this.updates=new Array(this.cursors.length),this.cursorListener=function(){r.updates[r.cursors.indexOf(this)]=!0},this.treeListener=function(){var t,e,n=r.updates[0];for(t=1,e=r.cursors.length;e>t;t++)n="or"===r.operators[t-1]?n||r.updates[t]:n&&r.updates[t];n&&r.emit("update"),r.updates=new Array(r.cursors.length)},this.bound=!1;var h=(this.on,this.once,function(){r.bound||(r.bound=!0,r.cursors.forEach(function(t){e(r,t)}))});this.on=s.before(h,this.on.bind(this)),this.once=s.before(h,this.once.bind(this)),i.forEach(function(r){this[t](r)},this)}function i(t){n.prototype[t]=function(r){if(!a.Cursor(r))throw this.release(),Error("baobab.Combination."+t+": argument should be a cursor.");if(~this.cursors.indexOf(r))throw this.release(),Error("baobab.Combination."+t+": cursor already in combination.");return this.cursors.push(r),this.operators.push(t),this.updates.length++,this.bound&&e(this,r),this}}var o=t("emmett"),s=t("./helpers.js"),a=t("./type.js");s.inherits(n,o),i("or"),i("and"),n.prototype.release=function(){this.cursors.forEach(function(t){t.off("update",this.cursorListener)},this),this.tree.off("update",this.treeListener),this.cursors=null,this.operators=null,this.tree=null,this.updates=null,this.kill()},r.exports=n},{"./helpers.js":7,"./type.js":10,emmett:3}],6:[function(t,r){function e(t,r,e,n){function i(t){if(s.isRecording()&&!s.undoing){var r=h.getIn(t,s.solvedPath,s.tree),e=h.deepClone(r);s.archive.add(e)}return s.undoing=!1,s.emit("update")}var s=this;o.call(this),r=r||[],this.tree=t,this.path=r,this.hash=n,this.archive=null,this.undoing=!1,this.complexPath=!!e,this.solvedPath=this.complexPath?e:this.path,this.relevant=void 0!==this.get(),this.updateHandler=function(t){var r,e,n,o,a,u,c=t.data.log,l=t.data.previousState,f=!1;if(s.complexPath&&(s.solvedPath=h.solvePath(s.tree.data,s.path,s.tree)),!s.path.length)return i(l);if(s.solvedPath)t:for(a=0,n=c.length;n>a;a++)for(r=c[a],u=0,o=r.length;o>u&&(e=r[u],e===""+s.solvedPath[u]);u++)if(u+1===o||u+1===s.solvedPath.length){f=!0;break t}var p=void 0!==s.get();s.relevant?p&&f?i(l):p||(s.emit("irrelevant"),s.relevant=!1):p&&f&&(s.emit("relevant"),i(l),s.relevant=!0)},this.mixin=a.cursor(this);var u=!1;this._lazyBind=function(){u||(u=!0,s.tree.on("update",s.updateHandler))},this.on=h.before(this._lazyBind,this.on.bind(this)),this.once=h.before(this._lazyBind,this.once.bind(this)),this.complexPath&&this._lazyBind()}function n(t,r,e,n){if(arguments.length>5)throw Error("baobab.Cursor."+t+": too many arguments.");arguments.length<4&&(n=e,e=[]),e=e||[];var i=[].concat(e),o=h.solvePath(this.get(),i,this.tree);if(!o)throw Error("baobab.Cursor."+t+": could not solve dynamic path.");if(r){var s=this.get(o);if(!u[r](s))throw Error("baobab.Cursor."+t+": invalid target.")}var a={};a["$"+t]=n;var c=h.pathObject(o,a);return c}function i(t,r){e.prototype[t]=function(){var e=n.bind(this,t,r).apply(this,arguments);return this.update(e)}}var o=t("emmett"),s=t("./combination.js"),a=t("./mixins.js"),h=t("./helpers.js"),u=(t("../defaults.js"),t("./type.js"));h.inherits(e,o),e.prototype.isRoot=function(){return!this.path.length},e.prototype.isLeaf=function(){return u.Primitive(this.get())},e.prototype.isBranch=function(){return!this.isLeaf()&&!this.isRoot()},e.prototype.root=function(){return this.tree.root()},e.prototype.select=function(t){if(arguments.length>1&&(t=h.arrayOf(arguments)),!u.Path(t))throw Error("baobab.Cursor.select: invalid path.");return this.tree.select(this.path.concat(t))},e.prototype.up=function(){return this.solvedPath&&this.solvedPath.length?this.tree.select(this.path.slice(0,-1)):null},e.prototype.left=function(){var t=+this.solvedPath[this.solvedPath.length-1];if(isNaN(t))throw Error("baobab.Cursor.left: cannot go left on a non-list type.");return t?this.tree.select(this.solvedPath.slice(0,-1).concat(t-1)):null},e.prototype.leftmost=function(){var t=+this.solvedPath[this.solvedPath.length-1];if(isNaN(t))throw Error("baobab.Cursor.leftmost: cannot go left on a non-list type.");return this.tree.select(this.solvedPath.slice(0,-1).concat(0))},e.prototype.right=function(){var t=+this.solvedPath[this.solvedPath.length-1];if(isNaN(t))throw Error("baobab.Cursor.right: cannot go right on a non-list type.");return t+1===this.up().get().length?null:this.tree.select(this.solvedPath.slice(0,-1).concat(t+1))},e.prototype.rightmost=function(){var t=+this.solvedPath[this.solvedPath.length-1];if(isNaN(t))throw Error("baobab.Cursor.right: cannot go right on a non-list type.");var r=this.up().get();return this.tree.select(this.solvedPath.slice(0,-1).concat(r.length-1))},e.prototype.down=function(){+this.solvedPath[this.solvedPath.length-1];return this.get()instanceof Array?this.tree.select(this.solvedPath.concat(0)):null},e.prototype.get=function(t){arguments.length>1&&(t=h.arrayOf(arguments));var r=this.solvedPath.concat((u.String(t)||u.Number(t)?[t]:t)||[]);return h.getIn(this.tree.data,r,this.tree)},i("set"),i("apply"),i("chain"),i("push","Array"),i("unshift","Array"),e.prototype.merge=function(t){if(!u.Object(t))throw Error("baobab.Cursor.merge: trying to merge a non-object.");var r=n.bind(this,"merge","Object").apply(this,arguments);return this.update(r)},e.prototype.unset=function(t){if(void 0===t&&this.isRoot())throw Error("baobab.Cursor.unset: cannot remove root node.");var r=n.bind(this,"unset",null).apply(this,[t,!0]);return this.update(r)},e.prototype.update=function(t,r){if(arguments.length<2)return this.tree.stack(h.pathObject(this.solvedPath,t)),this;var e=[].concat(t),n=h.solvePath(this.get(),e,this.tree);if(!n)throw Error("baobab.Cursor.update: could not solve dynamic path.");return this.tree.stack(h.pathObject(this.solvedPath.concat(n),r)),this},e.prototype.or=function(t){return new s("or",this,t)},e.prototype.and=function(t){return new s("and",this,t)},e.prototype.startRecording=function(t){if(t=t||5,1>t)throw Error("baobab.Cursor.startRecording: invalid maximum number of records.");return this.archive?this:(this._lazyBind(),this.archive=h.archive(t),this)},e.prototype.stopRecording=function(){return this.archive=null,this},e.prototype.undo=function(t){if(t=t||1,!this.isRecording())throw Error("baobab.Cursor.undo: cursor is not recording.");if(!u.PositiveInteger(t))throw Error("baobab.Cursor.undo: expecting a positive integer.");var r=this.archive.back(t);if(!r)throw Error("boabab.Cursor.undo: cannot find a relevant record ("+t+" back).");return this.undoing=!0,this.set(r)},e.prototype.isRecording=function(){return!!this.archive},e.prototype.hasHistory=function(){return!(!this.archive||!this.archive.get().length)},e.prototype.getHistory=function(){return this.archive?this.archive.get():[]},e.prototype.release=function(){this.tree.off("update",this.updateHandler),this.hash&&delete this.tree._cursors[this.hash],delete this.tree,delete this.path,delete this.solvedPath,delete this.archive,this.kill()},e.prototype.toJSON=function(){return this.get()},u.Cursor=function(t){return t instanceof e},r.exports=e},{"../defaults.js":2,"./combination.js":5,"./helpers.js":7,"./mixins.js":9,"./type.js":10,emmett:3}],7:[function(t,r){(function(e){function n(t){return Array.prototype.slice.call(t)}function i(t,r){return function(){t(),r.apply(null,arguments)}}function o(t,r){var e,n={};for(e in t)n[e]=t[e];for(e in r)n[e]=r[e];return n}function s(t){var r=t.source,e="";return t.global&&(e+="g"),t.multiline&&(e+="m"),t.ignoreCase&&(e+="i"),t.sticky&&(e+="y"),t.unicode&&(e+="u"),new RegExp(r,e)}function a(t,r){if(!r||"object"!=typeof r||r instanceof Error||"ArrayBuffer"in e&&r instanceof ArrayBuffer)return r;if(_.Array(r)){if(t){var n,i,o=[];for(n=0,i=r.length;i>n;n++)o.push(w(r[n]));return o}return r.slice(0)}if(_.Date(r))return new Date(r.getTime());if(r instanceof RegExp)return s(r);if(_.Object(r)){var a,h={};r.constructor&&r.constructor!==Object&&(h=Object.create(r.constructor.prototype));for(a in r)r.hasOwnProperty(a)&&(h[a]=t?w(r[a]):r[a]);return h}return r}function h(t,r){return function(e){return r(t(e))}}function u(t,r){var e,n;for(e=0,n=t.length;n>e;e++)if(r(t[e]))return t[e]}function c(t,r){var e,n;for(e=0,n=t.length;n>e;e++)if(r(t[e]))return e;return-1}function l(t,r){var e,n=!0;if(!t)return!1;for(e in r)if(_.Object(r[e]))n=n&&l(t[e],r[e]);else if(_.Array(r[e]))n=n&&!!~r[e].indexOf(t[e]);else if(t[e]!==r[e])return!1;return n}function f(t,r){return u(t,function(t){return l(t,r)})}function d(t,r){return c(t,function(t){return l(t,r)})}function b(t,r,e){r=r||[];var n,i,o,s=t;for(i=0,o=r.length;o>i;i++){if(!s)return;if("function"==typeof r[i]){if(!_.Array(s))return;s=u(s,r[i])}else if("object"==typeof r[i])if(e&&"$cursor"in r[i]){if(!_.Path(r[i].$cursor))throw Error("baobab.getIn: $cursor path must be an array.");n=e.get(r[i].$cursor),s=s[n]}else{if(!_.Array(s))return;s=f(s,r[i])}else s=s[r[i]]}return s}function y(t,r,e){var n,i,o,s=[],a=t;for(i=0,o=r.length;o>i;i++){if(!a)return null;if("function"==typeof r[i]){if(!_.Array(a))return;n=c(a,r[i]),s.push(n),a=a[n]}else if("object"==typeof r[i])if(e&&"$cursor"in r[i]){if(!_.Path(r[i].$cursor))throw Error("baobab.getIn: $cursor path must be an array.");p=e.get(r[i].$cursor),s.push(p),a=a[p]}else{if(!_.Array(a))return;n=d(a,r[i]),s.push(n),a=a[n]}else s.push(r[i]),a=a[r[i]]||{}}return s}function g(t,r){var e,n=t.length,i={},o=i;for(n||(i=r),e=0;n>e;e++)o[t[e]]=e+1===n?r:{},o=o[t[e]];return i}function m(t,r){t.super_=r;var e=function(){};e.prototype=r.prototype,t.prototype=new e,t.prototype.constructor=t}function v(t){var r=[];return{add:function(e){for(r.unshift(e);r.length>t;)r.pop()},back:function(t){var e=r[t-1];return e&&(r=r.slice(t)),e},get:function(){return r}}}var _=t("./type.js"),j=a.bind(null,!1),w=a.bind(null,!0);r.exports={archive:v,arrayOf:n,before:i,deepClone:w,shallowClone:j,shallowMerge:o,compose:h,getIn:b,inherits:m,pathObject:g,solvePath:y}}).call(this,"undefined"!=typeof global?global:"undefined"!=typeof self?self:"undefined"!=typeof window?window:{})},{"./type.js":10}],8:[function(t,r){function e(t,r,e){s.forEach(function(r){e!==r&&delete t[r]}),t[e]=r[e]}function n(t,r){var a,h=i.shallowClone(r||{});s.forEach(function(r){t[r]&&e(h,t,r)}),t.$chain&&(s.slice(0,-1).forEach(function(t){delete h[t]}),h.$apply=h.$apply?i.compose(h.$apply,t.$chain):t.$chain),t.$push&&h.$push?h.$push=o.Array(h.$push)?h.$push.concat(t.$push):[h.$push].concat(t.$push):t.$push&&(h.$push=t.$push),t.$unshift&&h.$unshift?h.$unshift=o.Array(t.$unshift)?t.$unshift.concat(h.$unshift):[t.$unshift].concat(h.$unshift):t.$unshift&&(h.$unshift=t.$unshift);for(a in t)o.Object(t[a])?h[a]=n(t[a],h[a]):"$"!==a[0]&&(h[a]=t[a]);return h}var i=t("./helpers.js"),o=t("./type.js"),s=["$unset","$set","$merge","$apply"];r.exports=n},{"./helpers.js":7,"./type.js":10}],9:[function(t,r){var e=t("./combination.js"),n=t("./type.js");r.exports={baobab:function(t){return{mixins:[{getInitialState:function(){if(this.tree=t,!this.cursor&&!this.cursors)return{};if(this.cursor&&this.cursors)throw Error("baobab.mixin: you cannot have both `component.cursor` and `component.cursors`. Please make up your mind.");if(this.__type=null,this.__updateHandler=function(){this.setState(this.__getCursorData())}.bind(this),this.cursor){if(!n.MixinCursor(this.cursor))throw Error("baobab.mixin.cursor: invalid data (cursor, string, array or function).");n.Function(this.cursor)&&(this.cursor=this.cursor()),n.Cursor(this.cursor)||(this.cursor=t.select(this.cursor)),this.__getCursorData=function(){return{cursor:this.cursor.get()}}.bind(this),this.__type="single"}else if(this.cursors){if(!n.MixinCursors(this.cursors))throw Error("baobab.mixin.cursor: invalid data (object, array or function).");if(n.Function(this.cursors)&&(this.cursors=this.cursors()),n.Array(this.cursors))this.cursors=this.cursors.map(function(r){return n.Cursor(r)?r:t.select(r)}),this.__getCursorData=function(){return{cursors:this.cursors.map(function(t){return t.get()})}}.bind(this),this.__type="array";else{for(var r in this.cursors)n.Cursor(this.cursors[r])||(this.cursors[r]=t.select(this.cursors[r]));this.__getCursorData=function(){var t={};for(r in this.cursors)t[r]=this.cursors[r].get();return{cursors:t}}.bind(this),this.__type="object"}}return this.__getCursorData()},componentDidMount:function(){"single"===this.__type?(this.__combination=new e("or",[this.cursor]),this.__combination.on("update",this.__updateHandler)):"array"===this.__type?(this.__combination=new e("or",this.cursors),this.__combination.on("update",this.__updateHandler)):"object"===this.__type&&(this.__combination=new e("or",Object.keys(this.cursors).map(function(t){return this.cursors[t]},this)),this.__combination.on("update",this.__updateHandler))},componentWillUnmount:function(){this.__combination&&this.__combination.release()}}].concat(t.options.mixins)}},cursor:function(t){return{mixins:[{getInitialState:function(){return this.cursor=t,this.__updateHandler=function(){this.setState({cursor:this.cursor.get()})}.bind(this),{cursor:this.cursor.get()}},componentDidMount:function(){this.cursor.on("update",this.__updateHandler)},componentWillUnmount:function(){this.cursor.off("update",this.__updateHandler)}}].concat(t.tree.options.mixins)}}}},{"./combination.js":5,"./type.js":10}],10:[function(t,r){function e(t,r){return r.some(function(r){return n[r](t)})}var n={};n.Array=function(t){return Array.isArray(t)},n.Object=function(t){return!Array.isArray(t)&&"object"==typeof t&&null!==t},n.String=function(t){return"string"==typeof t},n.Number=function(t){return"number"==typeof t},n.PositiveInteger=function(t){return"number"==typeof t&&t>0&&!(t%1)},n.Function=function(t){return"function"==typeof t},n.Primitive=function(t){return"string"==typeof t||"number"==typeof t||"boolean"==typeof t},n.Date=function(t){return t instanceof Date},n.NonScalar=function(t){return n.Object(t)||n.Array(t)},n.Path=function(t){var r=["String","Number","Function","Object"];return n.Array(t)?t.every(function(t){return e(t,r)}):e(t,r)},n.MixinCursor=function(t){return e(t,["String","Number","Array","Function","Cursor"])},n.MixinCursors=function(t){return e(t,["Object","Array","Function"])},n.ComplexPath=function(t){return t.some(function(t){return e(t,["Object","Function"])})},r.exports=n},{}],11:[function(t,r){function e(t,r){var e=new Error("baobab.update: "+r+" at path /"+t.slice(1).join("/"));return e.path=t,e}var n=t("./helpers.js"),i=t("./type.js");r.exports=function(t,r,o){if(o=o||{},!i.Object(t)&&!i.Array(t))throw Error("baobab.update: invalid target.");var s={};t={root:n.shallowClone(t)};var a=function(t,r,o,h){o=o||["root"];var u,c,l,f=o.join("|λ|"),p=o[o.length-1],d=Object.keys(r).some(function(t){return!!~["$unset","$set","$apply","$merge","$push","$unshift"].indexOf(t)});if(d){s[f]=!0;for(c in r){if("$unset"===c){var b=o[o.length-2];i.Array(t)?h[b]=t.slice(0,+p).concat(t.slice(+p+1)):(h[b]=n.shallowClone(t),delete h[b][p]);break}if("$set"===c){l=r.$set,t[p]=l;break}if("$apply"===c){if(u=r.$apply,"function"!=typeof u)throw e(o,"using command $apply with a non function");t[p]=u.call(null,t[p]);break}if("$merge"===c){if(l=r.$merge,!i.Object(t[p])||!i.Object(l))throw e(o,"using command $merge with a non object");t[p]=n.shallowMerge(t[p],l);break}if("$push"===c){if(l=r.$push,!i.Array(t[p]))throw e(o,"using command $push to a non array");t[p]=t[p].concat(l)}if("$unshift"===c){if(l=r.$unshift,!i.Array(t[p]))throw e(o,"using command $unshift to a non array");t[p]=[].concat(l).concat(t[p])}}}else for(c in r)t[p][c]="undefined"==typeof t[p][c]?{}:n.shallowClone(t[p][c]),a(t[p],r[c],o.concat(c),t)};return a(t,r),{data:t.root,log:Object.keys(s).map(function(t){return t.split("|λ|").slice(1)})}}},{"./helpers.js":7,"./type.js":10}]},{},[1])(1)}); \ No newline at end of file diff --git a/src/cursor.js b/src/cursor.js index 3dd8b58..d432557 100644 --- a/src/cursor.js +++ b/src/cursor.js @@ -238,6 +238,9 @@ Cursor.prototype.get = function(path) { * Update */ function pathPolymorphism(method, allowedType, key, val) { + if (arguments.length > 5) + throw Error('baobab.Cursor.' + method + ': too many arguments.') + if (arguments.length < 4) { val = key; key = []; diff --git a/test/suites/cursor.js b/test/suites/cursor.js index 94c357c..f50385d 100644 --- a/test/suites/cursor.js +++ b/test/suites/cursor.js @@ -145,6 +145,15 @@ describe('Cursor API', function() { }); describe('Standard cursors', function() { + it('should warn the user when too many arguments are applied to a setter.', function() { + var baobab = new Baobab(state), + cursor = baobab.select('items'); + + assert.throws(function() { + cursor.set('this', 'is', 'my', 'destiny!'); + }, /too many/); + }); + it('should be possible to set a key using a path rather than a key.', function() { var baobab = new Baobab(state, {asynchronous: false}), cursor = baobab.select('items'); From e95787f90c14561e3411bfa68171ee513edfdff9 Mon Sep 17 00:00:00 2001 From: Yomguithereal Date: Thu, 9 Apr 2015 22:52:06 +0200 Subject: [PATCH 39/73] helpers.solveUpdate to replace cursor internal complexity --- build/baobab.min.js | 2 +- src/cursor.js | 19 +------------------ src/helpers.js | 37 ++++++++++++++++++++++++++++++++++++- 3 files changed, 38 insertions(+), 20 deletions(-) diff --git a/build/baobab.min.js b/build/baobab.min.js index 3c22cdb..eea11b9 100644 --- a/build/baobab.min.js +++ b/build/baobab.min.js @@ -1,2 +1,2 @@ /* baobab.js - Version: 1.0.0-rc1 - Author: Yomguithereal (Guillaume Plique) */ -!function(t){if("object"==typeof exports&&"undefined"!=typeof module)module.exports=t();else if("function"==typeof define&&define.amd)define([],t);else{var r;r="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:this,r.Baobab=t()}}(function(){var t;return function r(t,e,n){function i(s,a){if(!e[s]){if(!t[s]){var h="function"==typeof require&&require;if(!a&&h)return h(s,!0);if(o)return o(s,!0);var u=new Error("Cannot find module '"+s+"'");throw u.code="MODULE_NOT_FOUND",u}var c=e[s]={exports:{}};t[s][0].call(c.exports,function(r){var e=t[s][1][r];return i(e?e:r)},c,c.exports,r,t,e,n)}return e[s].exports}for(var o="function"==typeof require&&require,s=0;sr;r++)n.push(t[r].handler);return n}var i={once:"boolean",scope:"object"},o=function(){this._enabled=!0,this._children=[],this._handlers={},this._handlersAll=[]};o.prototype.on=function(t,r,e){var n,s,a,h,u,c;if("function"==typeof r){for(u="string"==typeof t?[t]:t,n=0,s=u.length;n!==s;n+=1)if(h=u[n]){this._handlers[h]||(this._handlers[h]=[]),c={handler:r};for(a in e||{}){if(!i[a])throw new Error('The option "'+a+'" is not recognized by Emmett.');c[a]=e[a]}this._handlers[h].push(c)}}else if(t&&"object"==typeof t&&!Array.isArray(t))for(h in t)o.prototype.on.call(this,h,t[h],r);else{if("function"!=typeof t)throw new Error("Wrong arguments.");c={handler:t};for(a in e||{}){if(!i[a])throw new Error('The option "'+a+'" is not recognized by Emmett.');c[a]=e[a]}this._handlersAll.push(c)}return this},o.prototype.once=function(t,r,e){if("function"==typeof r)e=e||{},e.once=!0,this.on(t,r,e);else{if((!t||"object"!=typeof t||Array.isArray(t))&&"function"!=typeof t)throw new Error("Wrong arguments.");r=r||{},r.once=!0,this.on(t,r)}return this},o.prototype.off=function(t,r){var e,n,i,o,s,a,h,u="string"==typeof t?[t]:t;if(1===arguments.length&&"function"==typeof u){r=arguments[0];for(s in this._handlers){for(a=[],e=0,n=this._handlers[s].length;e!==n;e+=1)this._handlers[s][e].handler!==r&&a.push(this._handlers[s][e]);this._handlers[s]=a}for(a=[],e=0,n=this._handlersAll.length;e!==n;e+=1)this._handlersAll[e].handler!==r&&a.push(this._handlersAll[e]);this._handlersAll=a}else if(2===arguments.length)for(e=0,n=u.length;e!==n;e+=1){if(h=u[e],this._handlers[h]){for(a=[],i=0,o=this._handlers[h].length;i!==o;i+=1)this._handlers[h][i].handler!==r&&a.push(this._handlers[h][i]);this._handlers[h]=a}this._handlers[h]&&0===this._handlers[h].length&&delete this._handlers[h]}return this},o.prototype.unbindAll=function(){var t;this._handlersAll=[];for(t in this._handlers)delete this._handlers[t];return this},o.prototype.emit=function(t,r){var e,n,i,o,s,a,h,u,c,l,f="string"==typeof t?[t]:t;if(!this._enabled)return this;for(r=void 0===r?{}:r,e=0,n=f.length;e!==n;e+=1)if(l=f[e],c=(this._handlers[l]||[]).concat(this._handlersAll),c.length){for(h={type:l,data:r||{},target:this},a=[],i=0,o=c.length;i!==o;i+=1)(this._handlers[l]&&this._handlers[l].indexOf(c[i])>=0||this._handlersAll.indexOf(c[i])>=0)&&(c[i].handler.call("scope"in c[i]?c[i].scope:this,h),c[i].once&&a.push(c[i]));for(s=0;se;e++)if(t._children[e]===r){t._children.splice(e,1);break}}),this._children.push(r),r},o.prototype.listeners=function(t){var e,n,i,o=[];if(t)for(o=r(this._handlers[t]),n=0,i=this._children.length;i>n;n++)o=o.concat(this._children[n].listeners(t));else{o=r(this._handlersAll);for(e in this._handlers)o=o.concat(r(this._handlers[e]));for(n=0,i=this._children.length;i>n;n++)o=o.concat(this._children[n].listeners())}return o},o.prototype.kill=function(){if(this.emit("emmett:kill"),this.unbindAll(),this._handlers=null,this._handlersAll=null,this._enabled=!1,this._children)for(var t=0,r=this._children.length;r>t;t++)this._children[t].kill();this._children=null},o.prototype.disable=function(){return this._enabled=!1,this},o.prototype.enable=function(){return this._enabled=!0,this},o.version="2.1.2","undefined"!=typeof n?("undefined"!=typeof e&&e.exports&&(n=e.exports=o),n.Emitter=o):"function"==typeof t&&t.amd?t("emmett",[],function(){return o}):this.Emitter=o}).call(this)},{}],4:[function(t,r){function e(t){return t+"$"+(new Date).getTime()+(""+Math.random()).replace("0.","")}function n(t,r){function e(t){this[t]=function(){var r=this.root[t].apply(this.root,arguments);return r instanceof i?this:r}}if(arguments.length<1&&(t={}),!(this instanceof n))return new n(t,r);if(!l.Object(t)&&!l.Array(t))throw Error("Baobab: invalid data.");o.call(this),this.options=s.shallowMerge(c,r),this._transaction={},this._future=void 0,this._cursors={},this.data=s.deepClone(t),this.root=this.select([]),["get","set","unset","update"].forEach(e.bind(this)),this.mixin=u.baobab(this)}var i=t("./cursor.js"),o=t("emmett"),s=t("./helpers.js"),a=t("./update.js"),h=t("./merge.js"),u=t("./mixins.js"),c=t("../defaults.js"),l=t("./type.js");s.inherits(n,o),n.prototype.select=function(t){if(!t)throw Error("Baobab.select: invalid path.");if(arguments.length>1&&(t=s.arrayOf(arguments)),!l.Path(t))throw Error("Baobab.select: invalid path.");t=[].concat(t);var r,n=l.ComplexPath(t);n&&(r=s.solvePath(this.data,t,this));var o=t.map(function(t){return l.Function(t)?e("fn"):l.Object(t)?e("ob"):t}).join("|λ|");if(this._cursors[o])return this._cursors[o];var a=new i(this,t,r,o);return this._cursors[o]=a,a},n.prototype.stack=function(t){var r=this;if(!l.Object(t))throw Error("Baobab.update: wrong specification.");return this._transaction=h(t,this._transaction),this.options.autoCommit?this.options.asynchronous?(this._future||(this._future=setTimeout(r.commit.bind(r,null),0)),this):this.commit():this},n.prototype.commit=function(){var t=a(this.data,this._transaction,this.options),r=this.data;return this.data=t.data,this._transaction={},this._future&&(this._future=clearTimeout(this._future)),this.emit("update",{log:t.log,previousState:r}),this},n.prototype.release=function(){delete this.data,delete this._transaction;for(var t in this._cursors)this._cursors[t].release();delete this._cursors,this.kill()},n.prototype.toJSON=function(){return this.get()},r.exports=n},{"../defaults.js":2,"./cursor.js":6,"./helpers.js":7,"./merge.js":8,"./mixins.js":9,"./type.js":10,"./update.js":11,emmett:3}],5:[function(t,r){function e(t,r){r.on("update",t.cursorListener),t.tree.off("update",t.treeListener),t.tree.on("update",t.treeListener)}function n(t){var r=this;if(arguments.length<2)throw Error("baobab.Combination: not enough arguments.");var n=arguments[1],i=s.arrayOf(arguments).slice(2);if(n instanceof Array&&(i=n.slice(1),n=n[0]),!a.Cursor(n))throw Error("baobab.Combination: argument should be a cursor.");if("or"!==t&&"and"!==t)throw Error("baobab.Combination: invalid operator.");o.call(this),this.cursors=[n],this.operators=[],this.tree=n.tree,this.updates=new Array(this.cursors.length),this.cursorListener=function(){r.updates[r.cursors.indexOf(this)]=!0},this.treeListener=function(){var t,e,n=r.updates[0];for(t=1,e=r.cursors.length;e>t;t++)n="or"===r.operators[t-1]?n||r.updates[t]:n&&r.updates[t];n&&r.emit("update"),r.updates=new Array(r.cursors.length)},this.bound=!1;var h=(this.on,this.once,function(){r.bound||(r.bound=!0,r.cursors.forEach(function(t){e(r,t)}))});this.on=s.before(h,this.on.bind(this)),this.once=s.before(h,this.once.bind(this)),i.forEach(function(r){this[t](r)},this)}function i(t){n.prototype[t]=function(r){if(!a.Cursor(r))throw this.release(),Error("baobab.Combination."+t+": argument should be a cursor.");if(~this.cursors.indexOf(r))throw this.release(),Error("baobab.Combination."+t+": cursor already in combination.");return this.cursors.push(r),this.operators.push(t),this.updates.length++,this.bound&&e(this,r),this}}var o=t("emmett"),s=t("./helpers.js"),a=t("./type.js");s.inherits(n,o),i("or"),i("and"),n.prototype.release=function(){this.cursors.forEach(function(t){t.off("update",this.cursorListener)},this),this.tree.off("update",this.treeListener),this.cursors=null,this.operators=null,this.tree=null,this.updates=null,this.kill()},r.exports=n},{"./helpers.js":7,"./type.js":10,emmett:3}],6:[function(t,r){function e(t,r,e,n){function i(t){if(s.isRecording()&&!s.undoing){var r=h.getIn(t,s.solvedPath,s.tree),e=h.deepClone(r);s.archive.add(e)}return s.undoing=!1,s.emit("update")}var s=this;o.call(this),r=r||[],this.tree=t,this.path=r,this.hash=n,this.archive=null,this.undoing=!1,this.complexPath=!!e,this.solvedPath=this.complexPath?e:this.path,this.relevant=void 0!==this.get(),this.updateHandler=function(t){var r,e,n,o,a,u,c=t.data.log,l=t.data.previousState,f=!1;if(s.complexPath&&(s.solvedPath=h.solvePath(s.tree.data,s.path,s.tree)),!s.path.length)return i(l);if(s.solvedPath)t:for(a=0,n=c.length;n>a;a++)for(r=c[a],u=0,o=r.length;o>u&&(e=r[u],e===""+s.solvedPath[u]);u++)if(u+1===o||u+1===s.solvedPath.length){f=!0;break t}var p=void 0!==s.get();s.relevant?p&&f?i(l):p||(s.emit("irrelevant"),s.relevant=!1):p&&f&&(s.emit("relevant"),i(l),s.relevant=!0)},this.mixin=a.cursor(this);var u=!1;this._lazyBind=function(){u||(u=!0,s.tree.on("update",s.updateHandler))},this.on=h.before(this._lazyBind,this.on.bind(this)),this.once=h.before(this._lazyBind,this.once.bind(this)),this.complexPath&&this._lazyBind()}function n(t,r,e,n){if(arguments.length>5)throw Error("baobab.Cursor."+t+": too many arguments.");arguments.length<4&&(n=e,e=[]),e=e||[];var i=[].concat(e),o=h.solvePath(this.get(),i,this.tree);if(!o)throw Error("baobab.Cursor."+t+": could not solve dynamic path.");if(r){var s=this.get(o);if(!u[r](s))throw Error("baobab.Cursor."+t+": invalid target.")}var a={};a["$"+t]=n;var c=h.pathObject(o,a);return c}function i(t,r){e.prototype[t]=function(){var e=n.bind(this,t,r).apply(this,arguments);return this.update(e)}}var o=t("emmett"),s=t("./combination.js"),a=t("./mixins.js"),h=t("./helpers.js"),u=(t("../defaults.js"),t("./type.js"));h.inherits(e,o),e.prototype.isRoot=function(){return!this.path.length},e.prototype.isLeaf=function(){return u.Primitive(this.get())},e.prototype.isBranch=function(){return!this.isLeaf()&&!this.isRoot()},e.prototype.root=function(){return this.tree.root()},e.prototype.select=function(t){if(arguments.length>1&&(t=h.arrayOf(arguments)),!u.Path(t))throw Error("baobab.Cursor.select: invalid path.");return this.tree.select(this.path.concat(t))},e.prototype.up=function(){return this.solvedPath&&this.solvedPath.length?this.tree.select(this.path.slice(0,-1)):null},e.prototype.left=function(){var t=+this.solvedPath[this.solvedPath.length-1];if(isNaN(t))throw Error("baobab.Cursor.left: cannot go left on a non-list type.");return t?this.tree.select(this.solvedPath.slice(0,-1).concat(t-1)):null},e.prototype.leftmost=function(){var t=+this.solvedPath[this.solvedPath.length-1];if(isNaN(t))throw Error("baobab.Cursor.leftmost: cannot go left on a non-list type.");return this.tree.select(this.solvedPath.slice(0,-1).concat(0))},e.prototype.right=function(){var t=+this.solvedPath[this.solvedPath.length-1];if(isNaN(t))throw Error("baobab.Cursor.right: cannot go right on a non-list type.");return t+1===this.up().get().length?null:this.tree.select(this.solvedPath.slice(0,-1).concat(t+1))},e.prototype.rightmost=function(){var t=+this.solvedPath[this.solvedPath.length-1];if(isNaN(t))throw Error("baobab.Cursor.right: cannot go right on a non-list type.");var r=this.up().get();return this.tree.select(this.solvedPath.slice(0,-1).concat(r.length-1))},e.prototype.down=function(){+this.solvedPath[this.solvedPath.length-1];return this.get()instanceof Array?this.tree.select(this.solvedPath.concat(0)):null},e.prototype.get=function(t){arguments.length>1&&(t=h.arrayOf(arguments));var r=this.solvedPath.concat((u.String(t)||u.Number(t)?[t]:t)||[]);return h.getIn(this.tree.data,r,this.tree)},i("set"),i("apply"),i("chain"),i("push","Array"),i("unshift","Array"),e.prototype.merge=function(t){if(!u.Object(t))throw Error("baobab.Cursor.merge: trying to merge a non-object.");var r=n.bind(this,"merge","Object").apply(this,arguments);return this.update(r)},e.prototype.unset=function(t){if(void 0===t&&this.isRoot())throw Error("baobab.Cursor.unset: cannot remove root node.");var r=n.bind(this,"unset",null).apply(this,[t,!0]);return this.update(r)},e.prototype.update=function(t,r){if(arguments.length<2)return this.tree.stack(h.pathObject(this.solvedPath,t)),this;var e=[].concat(t),n=h.solvePath(this.get(),e,this.tree);if(!n)throw Error("baobab.Cursor.update: could not solve dynamic path.");return this.tree.stack(h.pathObject(this.solvedPath.concat(n),r)),this},e.prototype.or=function(t){return new s("or",this,t)},e.prototype.and=function(t){return new s("and",this,t)},e.prototype.startRecording=function(t){if(t=t||5,1>t)throw Error("baobab.Cursor.startRecording: invalid maximum number of records.");return this.archive?this:(this._lazyBind(),this.archive=h.archive(t),this)},e.prototype.stopRecording=function(){return this.archive=null,this},e.prototype.undo=function(t){if(t=t||1,!this.isRecording())throw Error("baobab.Cursor.undo: cursor is not recording.");if(!u.PositiveInteger(t))throw Error("baobab.Cursor.undo: expecting a positive integer.");var r=this.archive.back(t);if(!r)throw Error("boabab.Cursor.undo: cannot find a relevant record ("+t+" back).");return this.undoing=!0,this.set(r)},e.prototype.isRecording=function(){return!!this.archive},e.prototype.hasHistory=function(){return!(!this.archive||!this.archive.get().length)},e.prototype.getHistory=function(){return this.archive?this.archive.get():[]},e.prototype.release=function(){this.tree.off("update",this.updateHandler),this.hash&&delete this.tree._cursors[this.hash],delete this.tree,delete this.path,delete this.solvedPath,delete this.archive,this.kill()},e.prototype.toJSON=function(){return this.get()},u.Cursor=function(t){return t instanceof e},r.exports=e},{"../defaults.js":2,"./combination.js":5,"./helpers.js":7,"./mixins.js":9,"./type.js":10,emmett:3}],7:[function(t,r){(function(e){function n(t){return Array.prototype.slice.call(t)}function i(t,r){return function(){t(),r.apply(null,arguments)}}function o(t,r){var e,n={};for(e in t)n[e]=t[e];for(e in r)n[e]=r[e];return n}function s(t){var r=t.source,e="";return t.global&&(e+="g"),t.multiline&&(e+="m"),t.ignoreCase&&(e+="i"),t.sticky&&(e+="y"),t.unicode&&(e+="u"),new RegExp(r,e)}function a(t,r){if(!r||"object"!=typeof r||r instanceof Error||"ArrayBuffer"in e&&r instanceof ArrayBuffer)return r;if(_.Array(r)){if(t){var n,i,o=[];for(n=0,i=r.length;i>n;n++)o.push(w(r[n]));return o}return r.slice(0)}if(_.Date(r))return new Date(r.getTime());if(r instanceof RegExp)return s(r);if(_.Object(r)){var a,h={};r.constructor&&r.constructor!==Object&&(h=Object.create(r.constructor.prototype));for(a in r)r.hasOwnProperty(a)&&(h[a]=t?w(r[a]):r[a]);return h}return r}function h(t,r){return function(e){return r(t(e))}}function u(t,r){var e,n;for(e=0,n=t.length;n>e;e++)if(r(t[e]))return t[e]}function c(t,r){var e,n;for(e=0,n=t.length;n>e;e++)if(r(t[e]))return e;return-1}function l(t,r){var e,n=!0;if(!t)return!1;for(e in r)if(_.Object(r[e]))n=n&&l(t[e],r[e]);else if(_.Array(r[e]))n=n&&!!~r[e].indexOf(t[e]);else if(t[e]!==r[e])return!1;return n}function f(t,r){return u(t,function(t){return l(t,r)})}function d(t,r){return c(t,function(t){return l(t,r)})}function b(t,r,e){r=r||[];var n,i,o,s=t;for(i=0,o=r.length;o>i;i++){if(!s)return;if("function"==typeof r[i]){if(!_.Array(s))return;s=u(s,r[i])}else if("object"==typeof r[i])if(e&&"$cursor"in r[i]){if(!_.Path(r[i].$cursor))throw Error("baobab.getIn: $cursor path must be an array.");n=e.get(r[i].$cursor),s=s[n]}else{if(!_.Array(s))return;s=f(s,r[i])}else s=s[r[i]]}return s}function y(t,r,e){var n,i,o,s=[],a=t;for(i=0,o=r.length;o>i;i++){if(!a)return null;if("function"==typeof r[i]){if(!_.Array(a))return;n=c(a,r[i]),s.push(n),a=a[n]}else if("object"==typeof r[i])if(e&&"$cursor"in r[i]){if(!_.Path(r[i].$cursor))throw Error("baobab.getIn: $cursor path must be an array.");p=e.get(r[i].$cursor),s.push(p),a=a[p]}else{if(!_.Array(a))return;n=d(a,r[i]),s.push(n),a=a[n]}else s.push(r[i]),a=a[r[i]]||{}}return s}function g(t,r){var e,n=t.length,i={},o=i;for(n||(i=r),e=0;n>e;e++)o[t[e]]=e+1===n?r:{},o=o[t[e]];return i}function m(t,r){t.super_=r;var e=function(){};e.prototype=r.prototype,t.prototype=new e,t.prototype.constructor=t}function v(t){var r=[];return{add:function(e){for(r.unshift(e);r.length>t;)r.pop()},back:function(t){var e=r[t-1];return e&&(r=r.slice(t)),e},get:function(){return r}}}var _=t("./type.js"),j=a.bind(null,!1),w=a.bind(null,!0);r.exports={archive:v,arrayOf:n,before:i,deepClone:w,shallowClone:j,shallowMerge:o,compose:h,getIn:b,inherits:m,pathObject:g,solvePath:y}}).call(this,"undefined"!=typeof global?global:"undefined"!=typeof self?self:"undefined"!=typeof window?window:{})},{"./type.js":10}],8:[function(t,r){function e(t,r,e){s.forEach(function(r){e!==r&&delete t[r]}),t[e]=r[e]}function n(t,r){var a,h=i.shallowClone(r||{});s.forEach(function(r){t[r]&&e(h,t,r)}),t.$chain&&(s.slice(0,-1).forEach(function(t){delete h[t]}),h.$apply=h.$apply?i.compose(h.$apply,t.$chain):t.$chain),t.$push&&h.$push?h.$push=o.Array(h.$push)?h.$push.concat(t.$push):[h.$push].concat(t.$push):t.$push&&(h.$push=t.$push),t.$unshift&&h.$unshift?h.$unshift=o.Array(t.$unshift)?t.$unshift.concat(h.$unshift):[t.$unshift].concat(h.$unshift):t.$unshift&&(h.$unshift=t.$unshift);for(a in t)o.Object(t[a])?h[a]=n(t[a],h[a]):"$"!==a[0]&&(h[a]=t[a]);return h}var i=t("./helpers.js"),o=t("./type.js"),s=["$unset","$set","$merge","$apply"];r.exports=n},{"./helpers.js":7,"./type.js":10}],9:[function(t,r){var e=t("./combination.js"),n=t("./type.js");r.exports={baobab:function(t){return{mixins:[{getInitialState:function(){if(this.tree=t,!this.cursor&&!this.cursors)return{};if(this.cursor&&this.cursors)throw Error("baobab.mixin: you cannot have both `component.cursor` and `component.cursors`. Please make up your mind.");if(this.__type=null,this.__updateHandler=function(){this.setState(this.__getCursorData())}.bind(this),this.cursor){if(!n.MixinCursor(this.cursor))throw Error("baobab.mixin.cursor: invalid data (cursor, string, array or function).");n.Function(this.cursor)&&(this.cursor=this.cursor()),n.Cursor(this.cursor)||(this.cursor=t.select(this.cursor)),this.__getCursorData=function(){return{cursor:this.cursor.get()}}.bind(this),this.__type="single"}else if(this.cursors){if(!n.MixinCursors(this.cursors))throw Error("baobab.mixin.cursor: invalid data (object, array or function).");if(n.Function(this.cursors)&&(this.cursors=this.cursors()),n.Array(this.cursors))this.cursors=this.cursors.map(function(r){return n.Cursor(r)?r:t.select(r)}),this.__getCursorData=function(){return{cursors:this.cursors.map(function(t){return t.get()})}}.bind(this),this.__type="array";else{for(var r in this.cursors)n.Cursor(this.cursors[r])||(this.cursors[r]=t.select(this.cursors[r]));this.__getCursorData=function(){var t={};for(r in this.cursors)t[r]=this.cursors[r].get();return{cursors:t}}.bind(this),this.__type="object"}}return this.__getCursorData()},componentDidMount:function(){"single"===this.__type?(this.__combination=new e("or",[this.cursor]),this.__combination.on("update",this.__updateHandler)):"array"===this.__type?(this.__combination=new e("or",this.cursors),this.__combination.on("update",this.__updateHandler)):"object"===this.__type&&(this.__combination=new e("or",Object.keys(this.cursors).map(function(t){return this.cursors[t]},this)),this.__combination.on("update",this.__updateHandler))},componentWillUnmount:function(){this.__combination&&this.__combination.release()}}].concat(t.options.mixins)}},cursor:function(t){return{mixins:[{getInitialState:function(){return this.cursor=t,this.__updateHandler=function(){this.setState({cursor:this.cursor.get()})}.bind(this),{cursor:this.cursor.get()}},componentDidMount:function(){this.cursor.on("update",this.__updateHandler)},componentWillUnmount:function(){this.cursor.off("update",this.__updateHandler)}}].concat(t.tree.options.mixins)}}}},{"./combination.js":5,"./type.js":10}],10:[function(t,r){function e(t,r){return r.some(function(r){return n[r](t)})}var n={};n.Array=function(t){return Array.isArray(t)},n.Object=function(t){return!Array.isArray(t)&&"object"==typeof t&&null!==t},n.String=function(t){return"string"==typeof t},n.Number=function(t){return"number"==typeof t},n.PositiveInteger=function(t){return"number"==typeof t&&t>0&&!(t%1)},n.Function=function(t){return"function"==typeof t},n.Primitive=function(t){return"string"==typeof t||"number"==typeof t||"boolean"==typeof t},n.Date=function(t){return t instanceof Date},n.NonScalar=function(t){return n.Object(t)||n.Array(t)},n.Path=function(t){var r=["String","Number","Function","Object"];return n.Array(t)?t.every(function(t){return e(t,r)}):e(t,r)},n.MixinCursor=function(t){return e(t,["String","Number","Array","Function","Cursor"])},n.MixinCursors=function(t){return e(t,["Object","Array","Function"])},n.ComplexPath=function(t){return t.some(function(t){return e(t,["Object","Function"])})},r.exports=n},{}],11:[function(t,r){function e(t,r){var e=new Error("baobab.update: "+r+" at path /"+t.slice(1).join("/"));return e.path=t,e}var n=t("./helpers.js"),i=t("./type.js");r.exports=function(t,r,o){if(o=o||{},!i.Object(t)&&!i.Array(t))throw Error("baobab.update: invalid target.");var s={};t={root:n.shallowClone(t)};var a=function(t,r,o,h){o=o||["root"];var u,c,l,f=o.join("|λ|"),p=o[o.length-1],d=Object.keys(r).some(function(t){return!!~["$unset","$set","$apply","$merge","$push","$unshift"].indexOf(t)});if(d){s[f]=!0;for(c in r){if("$unset"===c){var b=o[o.length-2];i.Array(t)?h[b]=t.slice(0,+p).concat(t.slice(+p+1)):(h[b]=n.shallowClone(t),delete h[b][p]);break}if("$set"===c){l=r.$set,t[p]=l;break}if("$apply"===c){if(u=r.$apply,"function"!=typeof u)throw e(o,"using command $apply with a non function");t[p]=u.call(null,t[p]);break}if("$merge"===c){if(l=r.$merge,!i.Object(t[p])||!i.Object(l))throw e(o,"using command $merge with a non object");t[p]=n.shallowMerge(t[p],l);break}if("$push"===c){if(l=r.$push,!i.Array(t[p]))throw e(o,"using command $push to a non array");t[p]=t[p].concat(l)}if("$unshift"===c){if(l=r.$unshift,!i.Array(t[p]))throw e(o,"using command $unshift to a non array");t[p]=[].concat(l).concat(t[p])}}}else for(c in r)t[p][c]="undefined"==typeof t[p][c]?{}:n.shallowClone(t[p][c]),a(t[p],r[c],o.concat(c),t)};return a(t,r),{data:t.root,log:Object.keys(s).map(function(t){return t.split("|λ|").slice(1)})}}},{"./helpers.js":7,"./type.js":10}]},{},[1])(1)}); \ No newline at end of file +!function(t){if("object"==typeof exports&&"undefined"!=typeof module)module.exports=t();else if("function"==typeof define&&define.amd)define([],t);else{var r;r="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:this,r.Baobab=t()}}(function(){var t;return function r(t,e,n){function i(s,a){if(!e[s]){if(!t[s]){var h="function"==typeof require&&require;if(!a&&h)return h(s,!0);if(o)return o(s,!0);var u=new Error("Cannot find module '"+s+"'");throw u.code="MODULE_NOT_FOUND",u}var c=e[s]={exports:{}};t[s][0].call(c.exports,function(r){var e=t[s][1][r];return i(e?e:r)},c,c.exports,r,t,e,n)}return e[s].exports}for(var o="function"==typeof require&&require,s=0;sr;r++)n.push(t[r].handler);return n}var i={once:"boolean",scope:"object"},o=function(){this._enabled=!0,this._children=[],this._handlers={},this._handlersAll=[]};o.prototype.on=function(t,r,e){var n,s,a,h,u,c;if("function"==typeof r){for(u="string"==typeof t?[t]:t,n=0,s=u.length;n!==s;n+=1)if(h=u[n]){this._handlers[h]||(this._handlers[h]=[]),c={handler:r};for(a in e||{}){if(!i[a])throw new Error('The option "'+a+'" is not recognized by Emmett.');c[a]=e[a]}this._handlers[h].push(c)}}else if(t&&"object"==typeof t&&!Array.isArray(t))for(h in t)o.prototype.on.call(this,h,t[h],r);else{if("function"!=typeof t)throw new Error("Wrong arguments.");c={handler:t};for(a in e||{}){if(!i[a])throw new Error('The option "'+a+'" is not recognized by Emmett.');c[a]=e[a]}this._handlersAll.push(c)}return this},o.prototype.once=function(t,r,e){if("function"==typeof r)e=e||{},e.once=!0,this.on(t,r,e);else{if((!t||"object"!=typeof t||Array.isArray(t))&&"function"!=typeof t)throw new Error("Wrong arguments.");r=r||{},r.once=!0,this.on(t,r)}return this},o.prototype.off=function(t,r){var e,n,i,o,s,a,h,u="string"==typeof t?[t]:t;if(1===arguments.length&&"function"==typeof u){r=arguments[0];for(s in this._handlers){for(a=[],e=0,n=this._handlers[s].length;e!==n;e+=1)this._handlers[s][e].handler!==r&&a.push(this._handlers[s][e]);this._handlers[s]=a}for(a=[],e=0,n=this._handlersAll.length;e!==n;e+=1)this._handlersAll[e].handler!==r&&a.push(this._handlersAll[e]);this._handlersAll=a}else if(2===arguments.length)for(e=0,n=u.length;e!==n;e+=1){if(h=u[e],this._handlers[h]){for(a=[],i=0,o=this._handlers[h].length;i!==o;i+=1)this._handlers[h][i].handler!==r&&a.push(this._handlers[h][i]);this._handlers[h]=a}this._handlers[h]&&0===this._handlers[h].length&&delete this._handlers[h]}return this},o.prototype.unbindAll=function(){var t;this._handlersAll=[];for(t in this._handlers)delete this._handlers[t];return this},o.prototype.emit=function(t,r){var e,n,i,o,s,a,h,u,c,l,f="string"==typeof t?[t]:t;if(!this._enabled)return this;for(r=void 0===r?{}:r,e=0,n=f.length;e!==n;e+=1)if(l=f[e],c=(this._handlers[l]||[]).concat(this._handlersAll),c.length){for(h={type:l,data:r||{},target:this},a=[],i=0,o=c.length;i!==o;i+=1)(this._handlers[l]&&this._handlers[l].indexOf(c[i])>=0||this._handlersAll.indexOf(c[i])>=0)&&(c[i].handler.call("scope"in c[i]?c[i].scope:this,h),c[i].once&&a.push(c[i]));for(s=0;se;e++)if(t._children[e]===r){t._children.splice(e,1);break}}),this._children.push(r),r},o.prototype.listeners=function(t){var e,n,i,o=[];if(t)for(o=r(this._handlers[t]),n=0,i=this._children.length;i>n;n++)o=o.concat(this._children[n].listeners(t));else{o=r(this._handlersAll);for(e in this._handlers)o=o.concat(r(this._handlers[e]));for(n=0,i=this._children.length;i>n;n++)o=o.concat(this._children[n].listeners())}return o},o.prototype.kill=function(){if(this.emit("emmett:kill"),this.unbindAll(),this._handlers=null,this._handlersAll=null,this._enabled=!1,this._children)for(var t=0,r=this._children.length;r>t;t++)this._children[t].kill();this._children=null},o.prototype.disable=function(){return this._enabled=!1,this},o.prototype.enable=function(){return this._enabled=!0,this},o.version="2.1.2","undefined"!=typeof n?("undefined"!=typeof e&&e.exports&&(n=e.exports=o),n.Emitter=o):"function"==typeof t&&t.amd?t("emmett",[],function(){return o}):this.Emitter=o}).call(this)},{}],4:[function(t,r){function e(t){return t+"$"+(new Date).getTime()+(""+Math.random()).replace("0.","")}function n(t,r){function e(t){this[t]=function(){var r=this.root[t].apply(this.root,arguments);return r instanceof i?this:r}}if(arguments.length<1&&(t={}),!(this instanceof n))return new n(t,r);if(!l.Object(t)&&!l.Array(t))throw Error("Baobab: invalid data.");o.call(this),this.options=s.shallowMerge(c,r),this._transaction={},this._future=void 0,this._cursors={},this.data=s.deepClone(t),this.root=this.select([]),["get","set","unset","update"].forEach(e.bind(this)),this.mixin=u.baobab(this)}var i=t("./cursor.js"),o=t("emmett"),s=t("./helpers.js"),a=t("./update.js"),h=t("./merge.js"),u=t("./mixins.js"),c=t("../defaults.js"),l=t("./type.js");s.inherits(n,o),n.prototype.select=function(t){if(!t)throw Error("Baobab.select: invalid path.");if(arguments.length>1&&(t=s.arrayOf(arguments)),!l.Path(t))throw Error("Baobab.select: invalid path.");t=[].concat(t);var r,n=l.ComplexPath(t);n&&(r=s.solvePath(this.data,t,this));var o=t.map(function(t){return l.Function(t)?e("fn"):l.Object(t)?e("ob"):t}).join("|λ|");if(this._cursors[o])return this._cursors[o];var a=new i(this,t,r,o);return this._cursors[o]=a,a},n.prototype.stack=function(t){var r=this;if(!l.Object(t))throw Error("Baobab.update: wrong specification.");return this._transaction=h(t,this._transaction),this.options.autoCommit?this.options.asynchronous?(this._future||(this._future=setTimeout(r.commit.bind(r,null),0)),this):this.commit():this},n.prototype.commit=function(){var t=a(this.data,this._transaction,this.options),r=this.data;return this.data=t.data,this._transaction={},this._future&&(this._future=clearTimeout(this._future)),this.emit("update",{log:t.log,previousState:r}),this},n.prototype.release=function(){delete this.data,delete this._transaction;for(var t in this._cursors)this._cursors[t].release();delete this._cursors,this.kill()},n.prototype.toJSON=function(){return this.get()},r.exports=n},{"../defaults.js":2,"./cursor.js":6,"./helpers.js":7,"./merge.js":8,"./mixins.js":9,"./type.js":10,"./update.js":11,emmett:3}],5:[function(t,r){function e(t,r){r.on("update",t.cursorListener),t.tree.off("update",t.treeListener),t.tree.on("update",t.treeListener)}function n(t){var r=this;if(arguments.length<2)throw Error("baobab.Combination: not enough arguments.");var n=arguments[1],i=s.arrayOf(arguments).slice(2);if(n instanceof Array&&(i=n.slice(1),n=n[0]),!a.Cursor(n))throw Error("baobab.Combination: argument should be a cursor.");if("or"!==t&&"and"!==t)throw Error("baobab.Combination: invalid operator.");o.call(this),this.cursors=[n],this.operators=[],this.tree=n.tree,this.updates=new Array(this.cursors.length),this.cursorListener=function(){r.updates[r.cursors.indexOf(this)]=!0},this.treeListener=function(){var t,e,n=r.updates[0];for(t=1,e=r.cursors.length;e>t;t++)n="or"===r.operators[t-1]?n||r.updates[t]:n&&r.updates[t];n&&r.emit("update"),r.updates=new Array(r.cursors.length)},this.bound=!1;var h=(this.on,this.once,function(){r.bound||(r.bound=!0,r.cursors.forEach(function(t){e(r,t)}))});this.on=s.before(h,this.on.bind(this)),this.once=s.before(h,this.once.bind(this)),i.forEach(function(r){this[t](r)},this)}function i(t){n.prototype[t]=function(r){if(!a.Cursor(r))throw this.release(),Error("baobab.Combination."+t+": argument should be a cursor.");if(~this.cursors.indexOf(r))throw this.release(),Error("baobab.Combination."+t+": cursor already in combination.");return this.cursors.push(r),this.operators.push(t),this.updates.length++,this.bound&&e(this,r),this}}var o=t("emmett"),s=t("./helpers.js"),a=t("./type.js");s.inherits(n,o),i("or"),i("and"),n.prototype.release=function(){this.cursors.forEach(function(t){t.off("update",this.cursorListener)},this),this.tree.off("update",this.treeListener),this.cursors=null,this.operators=null,this.tree=null,this.updates=null,this.kill()},r.exports=n},{"./helpers.js":7,"./type.js":10,emmett:3}],6:[function(t,r){function e(t,r,e,n){function i(t){if(s.isRecording()&&!s.undoing){var r=h.getIn(t,s.solvedPath,s.tree),e=h.deepClone(r);s.archive.add(e)}return s.undoing=!1,s.emit("update")}var s=this;o.call(this),r=r||[],this.tree=t,this.path=r,this.hash=n,this.archive=null,this.undoing=!1,this.complexPath=!!e,this.solvedPath=this.complexPath?e:this.path,this.relevant=void 0!==this.get(),this.updateHandler=function(t){var r=t.data.log,e=t.data.previousState,n=!1;if(s.complexPath&&(s.solvedPath=h.solvePath(s.tree.data,s.path,s.tree)),!s.path.length)return i(e);s.solvedPath&&(n=h.solveUpdate(r,[s.solvedPath]));var o=void 0!==s.get();s.relevant?o&&n?i(e):o||(s.emit("irrelevant"),s.relevant=!1):o&&n&&(s.emit("relevant"),i(e),s.relevant=!0)},this.mixin=a.cursor(this);var u=!1;this._lazyBind=function(){u||(u=!0,s.tree.on("update",s.updateHandler))},this.on=h.before(this._lazyBind,this.on.bind(this)),this.once=h.before(this._lazyBind,this.once.bind(this)),this.complexPath&&this._lazyBind()}function n(t,r,e,n){if(arguments.length>5)throw Error("baobab.Cursor."+t+": too many arguments.");arguments.length<4&&(n=e,e=[]),e=e||[];var i=[].concat(e),o=h.solvePath(this.get(),i,this.tree);if(!o)throw Error("baobab.Cursor."+t+": could not solve dynamic path.");if(r){var s=this.get(o);if(!u[r](s))throw Error("baobab.Cursor."+t+": invalid target.")}var a={};a["$"+t]=n;var c=h.pathObject(o,a);return c}function i(t,r){e.prototype[t]=function(){var e=n.bind(this,t,r).apply(this,arguments);return this.update(e)}}var o=t("emmett"),s=t("./combination.js"),a=t("./mixins.js"),h=t("./helpers.js"),u=(t("../defaults.js"),t("./type.js"));h.inherits(e,o),e.prototype.isRoot=function(){return!this.path.length},e.prototype.isLeaf=function(){return u.Primitive(this.get())},e.prototype.isBranch=function(){return!this.isLeaf()&&!this.isRoot()},e.prototype.root=function(){return this.tree.root()},e.prototype.select=function(t){if(arguments.length>1&&(t=h.arrayOf(arguments)),!u.Path(t))throw Error("baobab.Cursor.select: invalid path.");return this.tree.select(this.path.concat(t))},e.prototype.up=function(){return this.solvedPath&&this.solvedPath.length?this.tree.select(this.path.slice(0,-1)):null},e.prototype.left=function(){var t=+this.solvedPath[this.solvedPath.length-1];if(isNaN(t))throw Error("baobab.Cursor.left: cannot go left on a non-list type.");return t?this.tree.select(this.solvedPath.slice(0,-1).concat(t-1)):null},e.prototype.leftmost=function(){var t=+this.solvedPath[this.solvedPath.length-1];if(isNaN(t))throw Error("baobab.Cursor.leftmost: cannot go left on a non-list type.");return this.tree.select(this.solvedPath.slice(0,-1).concat(0))},e.prototype.right=function(){var t=+this.solvedPath[this.solvedPath.length-1];if(isNaN(t))throw Error("baobab.Cursor.right: cannot go right on a non-list type.");return t+1===this.up().get().length?null:this.tree.select(this.solvedPath.slice(0,-1).concat(t+1))},e.prototype.rightmost=function(){var t=+this.solvedPath[this.solvedPath.length-1];if(isNaN(t))throw Error("baobab.Cursor.right: cannot go right on a non-list type.");var r=this.up().get();return this.tree.select(this.solvedPath.slice(0,-1).concat(r.length-1))},e.prototype.down=function(){+this.solvedPath[this.solvedPath.length-1];return this.get()instanceof Array?this.tree.select(this.solvedPath.concat(0)):null},e.prototype.get=function(t){arguments.length>1&&(t=h.arrayOf(arguments));var r=this.solvedPath.concat((u.String(t)||u.Number(t)?[t]:t)||[]);return h.getIn(this.tree.data,r,this.tree)},i("set"),i("apply"),i("chain"),i("push","Array"),i("unshift","Array"),e.prototype.merge=function(t){if(!u.Object(t))throw Error("baobab.Cursor.merge: trying to merge a non-object.");var r=n.bind(this,"merge","Object").apply(this,arguments);return this.update(r)},e.prototype.unset=function(t){if(void 0===t&&this.isRoot())throw Error("baobab.Cursor.unset: cannot remove root node.");var r=n.bind(this,"unset",null).apply(this,[t,!0]);return this.update(r)},e.prototype.update=function(t,r){if(arguments.length<2)return this.tree.stack(h.pathObject(this.solvedPath,t)),this;var e=[].concat(t),n=h.solvePath(this.get(),e,this.tree);if(!n)throw Error("baobab.Cursor.update: could not solve dynamic path.");return this.tree.stack(h.pathObject(this.solvedPath.concat(n),r)),this},e.prototype.or=function(t){return new s("or",this,t)},e.prototype.and=function(t){return new s("and",this,t)},e.prototype.startRecording=function(t){if(t=t||5,1>t)throw Error("baobab.Cursor.startRecording: invalid maximum number of records.");return this.archive?this:(this._lazyBind(),this.archive=h.archive(t),this)},e.prototype.stopRecording=function(){return this.archive=null,this},e.prototype.undo=function(t){if(t=t||1,!this.isRecording())throw Error("baobab.Cursor.undo: cursor is not recording.");if(!u.PositiveInteger(t))throw Error("baobab.Cursor.undo: expecting a positive integer.");var r=this.archive.back(t);if(!r)throw Error("boabab.Cursor.undo: cannot find a relevant record ("+t+" back).");return this.undoing=!0,this.set(r)},e.prototype.isRecording=function(){return!!this.archive},e.prototype.hasHistory=function(){return!(!this.archive||!this.archive.get().length)},e.prototype.getHistory=function(){return this.archive?this.archive.get():[]},e.prototype.release=function(){this.tree.off("update",this.updateHandler),this.hash&&delete this.tree._cursors[this.hash],delete this.tree,delete this.path,delete this.solvedPath,delete this.archive,this.kill()},e.prototype.toJSON=function(){return this.get()},u.Cursor=function(t){return t instanceof e},r.exports=e},{"../defaults.js":2,"./combination.js":5,"./helpers.js":7,"./mixins.js":9,"./type.js":10,emmett:3}],7:[function(t,r){(function(e){function n(t){return Array.prototype.slice.call(t)}function i(t,r){return function(){t(),r.apply(null,arguments)}}function o(t,r){var e,n={};for(e in t)n[e]=t[e];for(e in r)n[e]=r[e];return n}function s(t){var r=t.source,e="";return t.global&&(e+="g"),t.multiline&&(e+="m"),t.ignoreCase&&(e+="i"),t.sticky&&(e+="y"),t.unicode&&(e+="u"),new RegExp(r,e)}function a(t,r){if(!r||"object"!=typeof r||r instanceof Error||"ArrayBuffer"in e&&r instanceof ArrayBuffer)return r;if(j.Array(r)){if(t){var n,i,o=[];for(n=0,i=r.length;i>n;n++)o.push($(r[n]));return o}return r.slice(0)}if(j.Date(r))return new Date(r.getTime());if(r instanceof RegExp)return s(r);if(j.Object(r)){var a,h={};r.constructor&&r.constructor!==Object&&(h=Object.create(r.constructor.prototype));for(a in r)r.hasOwnProperty(a)&&(h[a]=t?$(r[a]):r[a]);return h}return r}function h(t,r){return function(e){return r(t(e))}}function u(t,r){var e,n;for(e=0,n=t.length;n>e;e++)if(r(t[e]))return t[e]}function c(t,r){var e,n;for(e=0,n=t.length;n>e;e++)if(r(t[e]))return e;return-1}function l(t,r){var e,n=!0;if(!t)return!1;for(e in r)if(j.Object(r[e]))n=n&&l(t[e],r[e]);else if(j.Array(r[e]))n=n&&!!~r[e].indexOf(t[e]);else if(t[e]!==r[e])return!1;return n}function f(t,r){return u(t,function(t){return l(t,r)})}function d(t,r){return c(t,function(t){return l(t,r)})}function b(t,r,e){r=r||[];var n,i,o,s=t;for(i=0,o=r.length;o>i;i++){if(!s)return;if("function"==typeof r[i]){if(!j.Array(s))return;s=u(s,r[i])}else if("object"==typeof r[i])if(e&&"$cursor"in r[i]){if(!j.Path(r[i].$cursor))throw Error("baobab.getIn: $cursor path must be an array.");n=e.get(r[i].$cursor),s=s[n]}else{if(!j.Array(s))return;s=f(s,r[i])}else s=s[r[i]]}return s}function y(t,r,e){var n,i,o,s=[],a=t;for(i=0,o=r.length;o>i;i++){if(!a)return null;if("function"==typeof r[i]){if(!j.Array(a))return;n=c(a,r[i]),s.push(n),a=a[n]}else if("object"==typeof r[i])if(e&&"$cursor"in r[i]){if(!j.Path(r[i].$cursor))throw Error("baobab.getIn: $cursor path must be an array.");p=e.get(r[i].$cursor),s.push(p),a=a[p]}else{if(!j.Array(a))return;n=d(a,r[i]),s.push(n),a=a[n]}else s.push(r[i]),a=a[r[i]]||{}}return s}function g(t,r){var e,n,i,o,s,a,h,u,c;for(e=0,o=r.length;o>e;e++)for(h=r[e],n=0,s=t.length;s>n;n++)for(u=t[n],i=0,a=u.length;a>i&&(c=u[i],c==h[i]);i++)if(i+1===a||i+1===h.length)return!0;return!1}function m(t,r){var e,n=t.length,i={},o=i;for(n||(i=r),e=0;n>e;e++)o[t[e]]=e+1===n?r:{},o=o[t[e]];return i}function v(t,r){t.super_=r;var e=function(){};e.prototype=r.prototype,t.prototype=new e,t.prototype.constructor=t}function _(t){var r=[];return{add:function(e){for(r.unshift(e);r.length>t;)r.pop()},back:function(t){var e=r[t-1];return e&&(r=r.slice(t)),e},get:function(){return r}}}var j=t("./type.js"),w=a.bind(null,!1),$=a.bind(null,!0);r.exports={archive:_,arrayOf:n,before:i,deepClone:$,shallowClone:w,shallowMerge:o,compose:h,getIn:b,inherits:v,pathObject:m,solvePath:y,solveUpdate:g}}).call(this,"undefined"!=typeof global?global:"undefined"!=typeof self?self:"undefined"!=typeof window?window:{})},{"./type.js":10}],8:[function(t,r){function e(t,r,e){s.forEach(function(r){e!==r&&delete t[r]}),t[e]=r[e]}function n(t,r){var a,h=i.shallowClone(r||{});s.forEach(function(r){t[r]&&e(h,t,r)}),t.$chain&&(s.slice(0,-1).forEach(function(t){delete h[t]}),h.$apply=h.$apply?i.compose(h.$apply,t.$chain):t.$chain),t.$push&&h.$push?h.$push=o.Array(h.$push)?h.$push.concat(t.$push):[h.$push].concat(t.$push):t.$push&&(h.$push=t.$push),t.$unshift&&h.$unshift?h.$unshift=o.Array(t.$unshift)?t.$unshift.concat(h.$unshift):[t.$unshift].concat(h.$unshift):t.$unshift&&(h.$unshift=t.$unshift);for(a in t)o.Object(t[a])?h[a]=n(t[a],h[a]):"$"!==a[0]&&(h[a]=t[a]);return h}var i=t("./helpers.js"),o=t("./type.js"),s=["$unset","$set","$merge","$apply"];r.exports=n},{"./helpers.js":7,"./type.js":10}],9:[function(t,r){var e=t("./combination.js"),n=t("./type.js");r.exports={baobab:function(t){return{mixins:[{getInitialState:function(){if(this.tree=t,!this.cursor&&!this.cursors)return{};if(this.cursor&&this.cursors)throw Error("baobab.mixin: you cannot have both `component.cursor` and `component.cursors`. Please make up your mind.");if(this.__type=null,this.__updateHandler=function(){this.setState(this.__getCursorData())}.bind(this),this.cursor){if(!n.MixinCursor(this.cursor))throw Error("baobab.mixin.cursor: invalid data (cursor, string, array or function).");n.Function(this.cursor)&&(this.cursor=this.cursor()),n.Cursor(this.cursor)||(this.cursor=t.select(this.cursor)),this.__getCursorData=function(){return{cursor:this.cursor.get()}}.bind(this),this.__type="single"}else if(this.cursors){if(!n.MixinCursors(this.cursors))throw Error("baobab.mixin.cursor: invalid data (object, array or function).");if(n.Function(this.cursors)&&(this.cursors=this.cursors()),n.Array(this.cursors))this.cursors=this.cursors.map(function(r){return n.Cursor(r)?r:t.select(r)}),this.__getCursorData=function(){return{cursors:this.cursors.map(function(t){return t.get()})}}.bind(this),this.__type="array";else{for(var r in this.cursors)n.Cursor(this.cursors[r])||(this.cursors[r]=t.select(this.cursors[r]));this.__getCursorData=function(){var t={};for(r in this.cursors)t[r]=this.cursors[r].get();return{cursors:t}}.bind(this),this.__type="object"}}return this.__getCursorData()},componentDidMount:function(){"single"===this.__type?(this.__combination=new e("or",[this.cursor]),this.__combination.on("update",this.__updateHandler)):"array"===this.__type?(this.__combination=new e("or",this.cursors),this.__combination.on("update",this.__updateHandler)):"object"===this.__type&&(this.__combination=new e("or",Object.keys(this.cursors).map(function(t){return this.cursors[t]},this)),this.__combination.on("update",this.__updateHandler))},componentWillUnmount:function(){this.__combination&&this.__combination.release()}}].concat(t.options.mixins)}},cursor:function(t){return{mixins:[{getInitialState:function(){return this.cursor=t,this.__updateHandler=function(){this.setState({cursor:this.cursor.get()})}.bind(this),{cursor:this.cursor.get()}},componentDidMount:function(){this.cursor.on("update",this.__updateHandler)},componentWillUnmount:function(){this.cursor.off("update",this.__updateHandler)}}].concat(t.tree.options.mixins)}}}},{"./combination.js":5,"./type.js":10}],10:[function(t,r){function e(t,r){return r.some(function(r){return n[r](t)})}var n={};n.Array=function(t){return Array.isArray(t)},n.Object=function(t){return!Array.isArray(t)&&"object"==typeof t&&null!==t},n.String=function(t){return"string"==typeof t},n.Number=function(t){return"number"==typeof t},n.PositiveInteger=function(t){return"number"==typeof t&&t>0&&!(t%1)},n.Function=function(t){return"function"==typeof t},n.Primitive=function(t){return"string"==typeof t||"number"==typeof t||"boolean"==typeof t},n.Date=function(t){return t instanceof Date},n.NonScalar=function(t){return n.Object(t)||n.Array(t)},n.Path=function(t){var r=["String","Number","Function","Object"];return n.Array(t)?t.every(function(t){return e(t,r)}):e(t,r)},n.MixinCursor=function(t){return e(t,["String","Number","Array","Function","Cursor"])},n.MixinCursors=function(t){return e(t,["Object","Array","Function"])},n.ComplexPath=function(t){return t.some(function(t){return e(t,["Object","Function"])})},r.exports=n},{}],11:[function(t,r){function e(t,r){var e=new Error("baobab.update: "+r+" at path /"+t.slice(1).join("/"));return e.path=t,e}var n=t("./helpers.js"),i=t("./type.js");r.exports=function(t,r,o){if(o=o||{},!i.Object(t)&&!i.Array(t))throw Error("baobab.update: invalid target.");var s={};t={root:n.shallowClone(t)};var a=function(t,r,o,h){o=o||["root"];var u,c,l,f=o.join("|λ|"),p=o[o.length-1],d=Object.keys(r).some(function(t){return!!~["$unset","$set","$apply","$merge","$push","$unshift"].indexOf(t)});if(d){s[f]=!0;for(c in r){if("$unset"===c){var b=o[o.length-2];i.Array(t)?h[b]=t.slice(0,+p).concat(t.slice(+p+1)):(h[b]=n.shallowClone(t),delete h[b][p]);break}if("$set"===c){l=r.$set,t[p]=l;break}if("$apply"===c){if(u=r.$apply,"function"!=typeof u)throw e(o,"using command $apply with a non function");t[p]=u.call(null,t[p]);break}if("$merge"===c){if(l=r.$merge,!i.Object(t[p])||!i.Object(l))throw e(o,"using command $merge with a non object");t[p]=n.shallowMerge(t[p],l);break}if("$push"===c){if(l=r.$push,!i.Array(t[p]))throw e(o,"using command $push to a non array");t[p]=t[p].concat(l)}if("$unshift"===c){if(l=r.$unshift,!i.Array(t[p]))throw e(o,"using command $unshift to a non array");t[p]=[].concat(l).concat(t[p])}}}else for(c in r)t[p][c]="undefined"==typeof t[p][c]?{}:n.shallowClone(t[p][c]),a(t[p],r[c],o.concat(c),t)};return a(t,r),{data:t.root,log:Object.keys(s).map(function(t){return t.split("|λ|").slice(1)})}}},{"./helpers.js":7,"./type.js":10}]},{},[1])(1)}); \ No newline at end of file diff --git a/src/cursor.js b/src/cursor.js index d432557..11228c2 100644 --- a/src/cursor.js +++ b/src/cursor.js @@ -68,24 +68,7 @@ function Cursor(tree, path, solvedPath, hash) { // Checking update log to see whether the cursor should update. if (self.solvedPath) - outer: - for (i = 0, l = log.length; i < l; i++) { - c = log[i]; - - for (j = 0, m = c.length; j < m; j++) { - p = c[j]; - - // If path is not relevant to us, we break - if (p !== '' + self.solvedPath[j]) - break; - - // If we reached last item and we are relevant, we fire - if (j + 1 === m || j + 1 === self.solvedPath.length) { - shouldFire = true; - break outer; - } - } - } + shouldFire = helpers.solveUpdate(log, [self.solvedPath]); // Handling relevancy var data = self.get() !== undefined; diff --git a/src/helpers.js b/src/helpers.js index 5141621..d0ce637 100644 --- a/src/helpers.js +++ b/src/helpers.js @@ -251,6 +251,40 @@ function solvePath(object, path, tree) { return solvedPath; } +// Determine whether an update should fire for the given paths +// NOTES: 1) if performance becomes an issue, the threefold loop can be +// simplified to become a complex twofold one. +// 2) a regex version could also work but I am not confident it would be +// faster. +function solveUpdate(log, paths) { + var i, j, k, l, m, n, p, c, s; + + // Looping through possible paths + for (i = 0, l = paths.length; i < l; i++) { + p = paths[i]; + + // Looping through logged paths + for (j = 0, m = log.length; j < m; j++) { + c = log[j]; + + // Looping through steps + for (k = 0, n = c.length; k < n; k++) { + s = c[k]; + + // If path is not relevant, we break + if (s != p[k]) + break; + + // If we reached last item and we are relevant + if (k + 1 === n || k + 1 === p.length) + return true; + } + } + } + + return false; +} + // Return a fake object relative to the given path function pathObject(path, spec) { var l = path.length, @@ -313,5 +347,6 @@ module.exports = { getIn: getIn, inherits: inherits, pathObject: pathObject, - solvePath: solvePath + solvePath: solvePath, + solveUpdate: solveUpdate }; From 426e9934d7dafd7bb7840756ca625f9fd9836fd9 Mon Sep 17 00:00:00 2001 From: Yomguithereal Date: Thu, 9 Apr 2015 23:32:19 +0200 Subject: [PATCH 40/73] Replacing combination by watcher --- build/baobab.min.js | 2 +- src/baobab.js | 11 +++ src/combination.js | 158 -------------------------------------------- src/cursor.js | 12 ---- src/mixins.js | 28 ++++---- src/type.js | 4 +- src/watcher.js | 54 +++++++++++++++ test/endpoint.js | 2 +- 8 files changed, 82 insertions(+), 189 deletions(-) delete mode 100644 src/combination.js create mode 100644 src/watcher.js diff --git a/build/baobab.min.js b/build/baobab.min.js index eea11b9..9348f3b 100644 --- a/build/baobab.min.js +++ b/build/baobab.min.js @@ -1,2 +1,2 @@ /* baobab.js - Version: 1.0.0-rc1 - Author: Yomguithereal (Guillaume Plique) */ -!function(t){if("object"==typeof exports&&"undefined"!=typeof module)module.exports=t();else if("function"==typeof define&&define.amd)define([],t);else{var r;r="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:this,r.Baobab=t()}}(function(){var t;return function r(t,e,n){function i(s,a){if(!e[s]){if(!t[s]){var h="function"==typeof require&&require;if(!a&&h)return h(s,!0);if(o)return o(s,!0);var u=new Error("Cannot find module '"+s+"'");throw u.code="MODULE_NOT_FOUND",u}var c=e[s]={exports:{}};t[s][0].call(c.exports,function(r){var e=t[s][1][r];return i(e?e:r)},c,c.exports,r,t,e,n)}return e[s].exports}for(var o="function"==typeof require&&require,s=0;sr;r++)n.push(t[r].handler);return n}var i={once:"boolean",scope:"object"},o=function(){this._enabled=!0,this._children=[],this._handlers={},this._handlersAll=[]};o.prototype.on=function(t,r,e){var n,s,a,h,u,c;if("function"==typeof r){for(u="string"==typeof t?[t]:t,n=0,s=u.length;n!==s;n+=1)if(h=u[n]){this._handlers[h]||(this._handlers[h]=[]),c={handler:r};for(a in e||{}){if(!i[a])throw new Error('The option "'+a+'" is not recognized by Emmett.');c[a]=e[a]}this._handlers[h].push(c)}}else if(t&&"object"==typeof t&&!Array.isArray(t))for(h in t)o.prototype.on.call(this,h,t[h],r);else{if("function"!=typeof t)throw new Error("Wrong arguments.");c={handler:t};for(a in e||{}){if(!i[a])throw new Error('The option "'+a+'" is not recognized by Emmett.');c[a]=e[a]}this._handlersAll.push(c)}return this},o.prototype.once=function(t,r,e){if("function"==typeof r)e=e||{},e.once=!0,this.on(t,r,e);else{if((!t||"object"!=typeof t||Array.isArray(t))&&"function"!=typeof t)throw new Error("Wrong arguments.");r=r||{},r.once=!0,this.on(t,r)}return this},o.prototype.off=function(t,r){var e,n,i,o,s,a,h,u="string"==typeof t?[t]:t;if(1===arguments.length&&"function"==typeof u){r=arguments[0];for(s in this._handlers){for(a=[],e=0,n=this._handlers[s].length;e!==n;e+=1)this._handlers[s][e].handler!==r&&a.push(this._handlers[s][e]);this._handlers[s]=a}for(a=[],e=0,n=this._handlersAll.length;e!==n;e+=1)this._handlersAll[e].handler!==r&&a.push(this._handlersAll[e]);this._handlersAll=a}else if(2===arguments.length)for(e=0,n=u.length;e!==n;e+=1){if(h=u[e],this._handlers[h]){for(a=[],i=0,o=this._handlers[h].length;i!==o;i+=1)this._handlers[h][i].handler!==r&&a.push(this._handlers[h][i]);this._handlers[h]=a}this._handlers[h]&&0===this._handlers[h].length&&delete this._handlers[h]}return this},o.prototype.unbindAll=function(){var t;this._handlersAll=[];for(t in this._handlers)delete this._handlers[t];return this},o.prototype.emit=function(t,r){var e,n,i,o,s,a,h,u,c,l,f="string"==typeof t?[t]:t;if(!this._enabled)return this;for(r=void 0===r?{}:r,e=0,n=f.length;e!==n;e+=1)if(l=f[e],c=(this._handlers[l]||[]).concat(this._handlersAll),c.length){for(h={type:l,data:r||{},target:this},a=[],i=0,o=c.length;i!==o;i+=1)(this._handlers[l]&&this._handlers[l].indexOf(c[i])>=0||this._handlersAll.indexOf(c[i])>=0)&&(c[i].handler.call("scope"in c[i]?c[i].scope:this,h),c[i].once&&a.push(c[i]));for(s=0;se;e++)if(t._children[e]===r){t._children.splice(e,1);break}}),this._children.push(r),r},o.prototype.listeners=function(t){var e,n,i,o=[];if(t)for(o=r(this._handlers[t]),n=0,i=this._children.length;i>n;n++)o=o.concat(this._children[n].listeners(t));else{o=r(this._handlersAll);for(e in this._handlers)o=o.concat(r(this._handlers[e]));for(n=0,i=this._children.length;i>n;n++)o=o.concat(this._children[n].listeners())}return o},o.prototype.kill=function(){if(this.emit("emmett:kill"),this.unbindAll(),this._handlers=null,this._handlersAll=null,this._enabled=!1,this._children)for(var t=0,r=this._children.length;r>t;t++)this._children[t].kill();this._children=null},o.prototype.disable=function(){return this._enabled=!1,this},o.prototype.enable=function(){return this._enabled=!0,this},o.version="2.1.2","undefined"!=typeof n?("undefined"!=typeof e&&e.exports&&(n=e.exports=o),n.Emitter=o):"function"==typeof t&&t.amd?t("emmett",[],function(){return o}):this.Emitter=o}).call(this)},{}],4:[function(t,r){function e(t){return t+"$"+(new Date).getTime()+(""+Math.random()).replace("0.","")}function n(t,r){function e(t){this[t]=function(){var r=this.root[t].apply(this.root,arguments);return r instanceof i?this:r}}if(arguments.length<1&&(t={}),!(this instanceof n))return new n(t,r);if(!l.Object(t)&&!l.Array(t))throw Error("Baobab: invalid data.");o.call(this),this.options=s.shallowMerge(c,r),this._transaction={},this._future=void 0,this._cursors={},this.data=s.deepClone(t),this.root=this.select([]),["get","set","unset","update"].forEach(e.bind(this)),this.mixin=u.baobab(this)}var i=t("./cursor.js"),o=t("emmett"),s=t("./helpers.js"),a=t("./update.js"),h=t("./merge.js"),u=t("./mixins.js"),c=t("../defaults.js"),l=t("./type.js");s.inherits(n,o),n.prototype.select=function(t){if(!t)throw Error("Baobab.select: invalid path.");if(arguments.length>1&&(t=s.arrayOf(arguments)),!l.Path(t))throw Error("Baobab.select: invalid path.");t=[].concat(t);var r,n=l.ComplexPath(t);n&&(r=s.solvePath(this.data,t,this));var o=t.map(function(t){return l.Function(t)?e("fn"):l.Object(t)?e("ob"):t}).join("|λ|");if(this._cursors[o])return this._cursors[o];var a=new i(this,t,r,o);return this._cursors[o]=a,a},n.prototype.stack=function(t){var r=this;if(!l.Object(t))throw Error("Baobab.update: wrong specification.");return this._transaction=h(t,this._transaction),this.options.autoCommit?this.options.asynchronous?(this._future||(this._future=setTimeout(r.commit.bind(r,null),0)),this):this.commit():this},n.prototype.commit=function(){var t=a(this.data,this._transaction,this.options),r=this.data;return this.data=t.data,this._transaction={},this._future&&(this._future=clearTimeout(this._future)),this.emit("update",{log:t.log,previousState:r}),this},n.prototype.release=function(){delete this.data,delete this._transaction;for(var t in this._cursors)this._cursors[t].release();delete this._cursors,this.kill()},n.prototype.toJSON=function(){return this.get()},r.exports=n},{"../defaults.js":2,"./cursor.js":6,"./helpers.js":7,"./merge.js":8,"./mixins.js":9,"./type.js":10,"./update.js":11,emmett:3}],5:[function(t,r){function e(t,r){r.on("update",t.cursorListener),t.tree.off("update",t.treeListener),t.tree.on("update",t.treeListener)}function n(t){var r=this;if(arguments.length<2)throw Error("baobab.Combination: not enough arguments.");var n=arguments[1],i=s.arrayOf(arguments).slice(2);if(n instanceof Array&&(i=n.slice(1),n=n[0]),!a.Cursor(n))throw Error("baobab.Combination: argument should be a cursor.");if("or"!==t&&"and"!==t)throw Error("baobab.Combination: invalid operator.");o.call(this),this.cursors=[n],this.operators=[],this.tree=n.tree,this.updates=new Array(this.cursors.length),this.cursorListener=function(){r.updates[r.cursors.indexOf(this)]=!0},this.treeListener=function(){var t,e,n=r.updates[0];for(t=1,e=r.cursors.length;e>t;t++)n="or"===r.operators[t-1]?n||r.updates[t]:n&&r.updates[t];n&&r.emit("update"),r.updates=new Array(r.cursors.length)},this.bound=!1;var h=(this.on,this.once,function(){r.bound||(r.bound=!0,r.cursors.forEach(function(t){e(r,t)}))});this.on=s.before(h,this.on.bind(this)),this.once=s.before(h,this.once.bind(this)),i.forEach(function(r){this[t](r)},this)}function i(t){n.prototype[t]=function(r){if(!a.Cursor(r))throw this.release(),Error("baobab.Combination."+t+": argument should be a cursor.");if(~this.cursors.indexOf(r))throw this.release(),Error("baobab.Combination."+t+": cursor already in combination.");return this.cursors.push(r),this.operators.push(t),this.updates.length++,this.bound&&e(this,r),this}}var o=t("emmett"),s=t("./helpers.js"),a=t("./type.js");s.inherits(n,o),i("or"),i("and"),n.prototype.release=function(){this.cursors.forEach(function(t){t.off("update",this.cursorListener)},this),this.tree.off("update",this.treeListener),this.cursors=null,this.operators=null,this.tree=null,this.updates=null,this.kill()},r.exports=n},{"./helpers.js":7,"./type.js":10,emmett:3}],6:[function(t,r){function e(t,r,e,n){function i(t){if(s.isRecording()&&!s.undoing){var r=h.getIn(t,s.solvedPath,s.tree),e=h.deepClone(r);s.archive.add(e)}return s.undoing=!1,s.emit("update")}var s=this;o.call(this),r=r||[],this.tree=t,this.path=r,this.hash=n,this.archive=null,this.undoing=!1,this.complexPath=!!e,this.solvedPath=this.complexPath?e:this.path,this.relevant=void 0!==this.get(),this.updateHandler=function(t){var r=t.data.log,e=t.data.previousState,n=!1;if(s.complexPath&&(s.solvedPath=h.solvePath(s.tree.data,s.path,s.tree)),!s.path.length)return i(e);s.solvedPath&&(n=h.solveUpdate(r,[s.solvedPath]));var o=void 0!==s.get();s.relevant?o&&n?i(e):o||(s.emit("irrelevant"),s.relevant=!1):o&&n&&(s.emit("relevant"),i(e),s.relevant=!0)},this.mixin=a.cursor(this);var u=!1;this._lazyBind=function(){u||(u=!0,s.tree.on("update",s.updateHandler))},this.on=h.before(this._lazyBind,this.on.bind(this)),this.once=h.before(this._lazyBind,this.once.bind(this)),this.complexPath&&this._lazyBind()}function n(t,r,e,n){if(arguments.length>5)throw Error("baobab.Cursor."+t+": too many arguments.");arguments.length<4&&(n=e,e=[]),e=e||[];var i=[].concat(e),o=h.solvePath(this.get(),i,this.tree);if(!o)throw Error("baobab.Cursor."+t+": could not solve dynamic path.");if(r){var s=this.get(o);if(!u[r](s))throw Error("baobab.Cursor."+t+": invalid target.")}var a={};a["$"+t]=n;var c=h.pathObject(o,a);return c}function i(t,r){e.prototype[t]=function(){var e=n.bind(this,t,r).apply(this,arguments);return this.update(e)}}var o=t("emmett"),s=t("./combination.js"),a=t("./mixins.js"),h=t("./helpers.js"),u=(t("../defaults.js"),t("./type.js"));h.inherits(e,o),e.prototype.isRoot=function(){return!this.path.length},e.prototype.isLeaf=function(){return u.Primitive(this.get())},e.prototype.isBranch=function(){return!this.isLeaf()&&!this.isRoot()},e.prototype.root=function(){return this.tree.root()},e.prototype.select=function(t){if(arguments.length>1&&(t=h.arrayOf(arguments)),!u.Path(t))throw Error("baobab.Cursor.select: invalid path.");return this.tree.select(this.path.concat(t))},e.prototype.up=function(){return this.solvedPath&&this.solvedPath.length?this.tree.select(this.path.slice(0,-1)):null},e.prototype.left=function(){var t=+this.solvedPath[this.solvedPath.length-1];if(isNaN(t))throw Error("baobab.Cursor.left: cannot go left on a non-list type.");return t?this.tree.select(this.solvedPath.slice(0,-1).concat(t-1)):null},e.prototype.leftmost=function(){var t=+this.solvedPath[this.solvedPath.length-1];if(isNaN(t))throw Error("baobab.Cursor.leftmost: cannot go left on a non-list type.");return this.tree.select(this.solvedPath.slice(0,-1).concat(0))},e.prototype.right=function(){var t=+this.solvedPath[this.solvedPath.length-1];if(isNaN(t))throw Error("baobab.Cursor.right: cannot go right on a non-list type.");return t+1===this.up().get().length?null:this.tree.select(this.solvedPath.slice(0,-1).concat(t+1))},e.prototype.rightmost=function(){var t=+this.solvedPath[this.solvedPath.length-1];if(isNaN(t))throw Error("baobab.Cursor.right: cannot go right on a non-list type.");var r=this.up().get();return this.tree.select(this.solvedPath.slice(0,-1).concat(r.length-1))},e.prototype.down=function(){+this.solvedPath[this.solvedPath.length-1];return this.get()instanceof Array?this.tree.select(this.solvedPath.concat(0)):null},e.prototype.get=function(t){arguments.length>1&&(t=h.arrayOf(arguments));var r=this.solvedPath.concat((u.String(t)||u.Number(t)?[t]:t)||[]);return h.getIn(this.tree.data,r,this.tree)},i("set"),i("apply"),i("chain"),i("push","Array"),i("unshift","Array"),e.prototype.merge=function(t){if(!u.Object(t))throw Error("baobab.Cursor.merge: trying to merge a non-object.");var r=n.bind(this,"merge","Object").apply(this,arguments);return this.update(r)},e.prototype.unset=function(t){if(void 0===t&&this.isRoot())throw Error("baobab.Cursor.unset: cannot remove root node.");var r=n.bind(this,"unset",null).apply(this,[t,!0]);return this.update(r)},e.prototype.update=function(t,r){if(arguments.length<2)return this.tree.stack(h.pathObject(this.solvedPath,t)),this;var e=[].concat(t),n=h.solvePath(this.get(),e,this.tree);if(!n)throw Error("baobab.Cursor.update: could not solve dynamic path.");return this.tree.stack(h.pathObject(this.solvedPath.concat(n),r)),this},e.prototype.or=function(t){return new s("or",this,t)},e.prototype.and=function(t){return new s("and",this,t)},e.prototype.startRecording=function(t){if(t=t||5,1>t)throw Error("baobab.Cursor.startRecording: invalid maximum number of records.");return this.archive?this:(this._lazyBind(),this.archive=h.archive(t),this)},e.prototype.stopRecording=function(){return this.archive=null,this},e.prototype.undo=function(t){if(t=t||1,!this.isRecording())throw Error("baobab.Cursor.undo: cursor is not recording.");if(!u.PositiveInteger(t))throw Error("baobab.Cursor.undo: expecting a positive integer.");var r=this.archive.back(t);if(!r)throw Error("boabab.Cursor.undo: cannot find a relevant record ("+t+" back).");return this.undoing=!0,this.set(r)},e.prototype.isRecording=function(){return!!this.archive},e.prototype.hasHistory=function(){return!(!this.archive||!this.archive.get().length)},e.prototype.getHistory=function(){return this.archive?this.archive.get():[]},e.prototype.release=function(){this.tree.off("update",this.updateHandler),this.hash&&delete this.tree._cursors[this.hash],delete this.tree,delete this.path,delete this.solvedPath,delete this.archive,this.kill()},e.prototype.toJSON=function(){return this.get()},u.Cursor=function(t){return t instanceof e},r.exports=e},{"../defaults.js":2,"./combination.js":5,"./helpers.js":7,"./mixins.js":9,"./type.js":10,emmett:3}],7:[function(t,r){(function(e){function n(t){return Array.prototype.slice.call(t)}function i(t,r){return function(){t(),r.apply(null,arguments)}}function o(t,r){var e,n={};for(e in t)n[e]=t[e];for(e in r)n[e]=r[e];return n}function s(t){var r=t.source,e="";return t.global&&(e+="g"),t.multiline&&(e+="m"),t.ignoreCase&&(e+="i"),t.sticky&&(e+="y"),t.unicode&&(e+="u"),new RegExp(r,e)}function a(t,r){if(!r||"object"!=typeof r||r instanceof Error||"ArrayBuffer"in e&&r instanceof ArrayBuffer)return r;if(j.Array(r)){if(t){var n,i,o=[];for(n=0,i=r.length;i>n;n++)o.push($(r[n]));return o}return r.slice(0)}if(j.Date(r))return new Date(r.getTime());if(r instanceof RegExp)return s(r);if(j.Object(r)){var a,h={};r.constructor&&r.constructor!==Object&&(h=Object.create(r.constructor.prototype));for(a in r)r.hasOwnProperty(a)&&(h[a]=t?$(r[a]):r[a]);return h}return r}function h(t,r){return function(e){return r(t(e))}}function u(t,r){var e,n;for(e=0,n=t.length;n>e;e++)if(r(t[e]))return t[e]}function c(t,r){var e,n;for(e=0,n=t.length;n>e;e++)if(r(t[e]))return e;return-1}function l(t,r){var e,n=!0;if(!t)return!1;for(e in r)if(j.Object(r[e]))n=n&&l(t[e],r[e]);else if(j.Array(r[e]))n=n&&!!~r[e].indexOf(t[e]);else if(t[e]!==r[e])return!1;return n}function f(t,r){return u(t,function(t){return l(t,r)})}function d(t,r){return c(t,function(t){return l(t,r)})}function b(t,r,e){r=r||[];var n,i,o,s=t;for(i=0,o=r.length;o>i;i++){if(!s)return;if("function"==typeof r[i]){if(!j.Array(s))return;s=u(s,r[i])}else if("object"==typeof r[i])if(e&&"$cursor"in r[i]){if(!j.Path(r[i].$cursor))throw Error("baobab.getIn: $cursor path must be an array.");n=e.get(r[i].$cursor),s=s[n]}else{if(!j.Array(s))return;s=f(s,r[i])}else s=s[r[i]]}return s}function y(t,r,e){var n,i,o,s=[],a=t;for(i=0,o=r.length;o>i;i++){if(!a)return null;if("function"==typeof r[i]){if(!j.Array(a))return;n=c(a,r[i]),s.push(n),a=a[n]}else if("object"==typeof r[i])if(e&&"$cursor"in r[i]){if(!j.Path(r[i].$cursor))throw Error("baobab.getIn: $cursor path must be an array.");p=e.get(r[i].$cursor),s.push(p),a=a[p]}else{if(!j.Array(a))return;n=d(a,r[i]),s.push(n),a=a[n]}else s.push(r[i]),a=a[r[i]]||{}}return s}function g(t,r){var e,n,i,o,s,a,h,u,c;for(e=0,o=r.length;o>e;e++)for(h=r[e],n=0,s=t.length;s>n;n++)for(u=t[n],i=0,a=u.length;a>i&&(c=u[i],c==h[i]);i++)if(i+1===a||i+1===h.length)return!0;return!1}function m(t,r){var e,n=t.length,i={},o=i;for(n||(i=r),e=0;n>e;e++)o[t[e]]=e+1===n?r:{},o=o[t[e]];return i}function v(t,r){t.super_=r;var e=function(){};e.prototype=r.prototype,t.prototype=new e,t.prototype.constructor=t}function _(t){var r=[];return{add:function(e){for(r.unshift(e);r.length>t;)r.pop()},back:function(t){var e=r[t-1];return e&&(r=r.slice(t)),e},get:function(){return r}}}var j=t("./type.js"),w=a.bind(null,!1),$=a.bind(null,!0);r.exports={archive:_,arrayOf:n,before:i,deepClone:$,shallowClone:w,shallowMerge:o,compose:h,getIn:b,inherits:v,pathObject:m,solvePath:y,solveUpdate:g}}).call(this,"undefined"!=typeof global?global:"undefined"!=typeof self?self:"undefined"!=typeof window?window:{})},{"./type.js":10}],8:[function(t,r){function e(t,r,e){s.forEach(function(r){e!==r&&delete t[r]}),t[e]=r[e]}function n(t,r){var a,h=i.shallowClone(r||{});s.forEach(function(r){t[r]&&e(h,t,r)}),t.$chain&&(s.slice(0,-1).forEach(function(t){delete h[t]}),h.$apply=h.$apply?i.compose(h.$apply,t.$chain):t.$chain),t.$push&&h.$push?h.$push=o.Array(h.$push)?h.$push.concat(t.$push):[h.$push].concat(t.$push):t.$push&&(h.$push=t.$push),t.$unshift&&h.$unshift?h.$unshift=o.Array(t.$unshift)?t.$unshift.concat(h.$unshift):[t.$unshift].concat(h.$unshift):t.$unshift&&(h.$unshift=t.$unshift);for(a in t)o.Object(t[a])?h[a]=n(t[a],h[a]):"$"!==a[0]&&(h[a]=t[a]);return h}var i=t("./helpers.js"),o=t("./type.js"),s=["$unset","$set","$merge","$apply"];r.exports=n},{"./helpers.js":7,"./type.js":10}],9:[function(t,r){var e=t("./combination.js"),n=t("./type.js");r.exports={baobab:function(t){return{mixins:[{getInitialState:function(){if(this.tree=t,!this.cursor&&!this.cursors)return{};if(this.cursor&&this.cursors)throw Error("baobab.mixin: you cannot have both `component.cursor` and `component.cursors`. Please make up your mind.");if(this.__type=null,this.__updateHandler=function(){this.setState(this.__getCursorData())}.bind(this),this.cursor){if(!n.MixinCursor(this.cursor))throw Error("baobab.mixin.cursor: invalid data (cursor, string, array or function).");n.Function(this.cursor)&&(this.cursor=this.cursor()),n.Cursor(this.cursor)||(this.cursor=t.select(this.cursor)),this.__getCursorData=function(){return{cursor:this.cursor.get()}}.bind(this),this.__type="single"}else if(this.cursors){if(!n.MixinCursors(this.cursors))throw Error("baobab.mixin.cursor: invalid data (object, array or function).");if(n.Function(this.cursors)&&(this.cursors=this.cursors()),n.Array(this.cursors))this.cursors=this.cursors.map(function(r){return n.Cursor(r)?r:t.select(r)}),this.__getCursorData=function(){return{cursors:this.cursors.map(function(t){return t.get()})}}.bind(this),this.__type="array";else{for(var r in this.cursors)n.Cursor(this.cursors[r])||(this.cursors[r]=t.select(this.cursors[r]));this.__getCursorData=function(){var t={};for(r in this.cursors)t[r]=this.cursors[r].get();return{cursors:t}}.bind(this),this.__type="object"}}return this.__getCursorData()},componentDidMount:function(){"single"===this.__type?(this.__combination=new e("or",[this.cursor]),this.__combination.on("update",this.__updateHandler)):"array"===this.__type?(this.__combination=new e("or",this.cursors),this.__combination.on("update",this.__updateHandler)):"object"===this.__type&&(this.__combination=new e("or",Object.keys(this.cursors).map(function(t){return this.cursors[t]},this)),this.__combination.on("update",this.__updateHandler))},componentWillUnmount:function(){this.__combination&&this.__combination.release()}}].concat(t.options.mixins)}},cursor:function(t){return{mixins:[{getInitialState:function(){return this.cursor=t,this.__updateHandler=function(){this.setState({cursor:this.cursor.get()})}.bind(this),{cursor:this.cursor.get()}},componentDidMount:function(){this.cursor.on("update",this.__updateHandler)},componentWillUnmount:function(){this.cursor.off("update",this.__updateHandler)}}].concat(t.tree.options.mixins)}}}},{"./combination.js":5,"./type.js":10}],10:[function(t,r){function e(t,r){return r.some(function(r){return n[r](t)})}var n={};n.Array=function(t){return Array.isArray(t)},n.Object=function(t){return!Array.isArray(t)&&"object"==typeof t&&null!==t},n.String=function(t){return"string"==typeof t},n.Number=function(t){return"number"==typeof t},n.PositiveInteger=function(t){return"number"==typeof t&&t>0&&!(t%1)},n.Function=function(t){return"function"==typeof t},n.Primitive=function(t){return"string"==typeof t||"number"==typeof t||"boolean"==typeof t},n.Date=function(t){return t instanceof Date},n.NonScalar=function(t){return n.Object(t)||n.Array(t)},n.Path=function(t){var r=["String","Number","Function","Object"];return n.Array(t)?t.every(function(t){return e(t,r)}):e(t,r)},n.MixinCursor=function(t){return e(t,["String","Number","Array","Function","Cursor"])},n.MixinCursors=function(t){return e(t,["Object","Array","Function"])},n.ComplexPath=function(t){return t.some(function(t){return e(t,["Object","Function"])})},r.exports=n},{}],11:[function(t,r){function e(t,r){var e=new Error("baobab.update: "+r+" at path /"+t.slice(1).join("/"));return e.path=t,e}var n=t("./helpers.js"),i=t("./type.js");r.exports=function(t,r,o){if(o=o||{},!i.Object(t)&&!i.Array(t))throw Error("baobab.update: invalid target.");var s={};t={root:n.shallowClone(t)};var a=function(t,r,o,h){o=o||["root"];var u,c,l,f=o.join("|λ|"),p=o[o.length-1],d=Object.keys(r).some(function(t){return!!~["$unset","$set","$apply","$merge","$push","$unshift"].indexOf(t)});if(d){s[f]=!0;for(c in r){if("$unset"===c){var b=o[o.length-2];i.Array(t)?h[b]=t.slice(0,+p).concat(t.slice(+p+1)):(h[b]=n.shallowClone(t),delete h[b][p]);break}if("$set"===c){l=r.$set,t[p]=l;break}if("$apply"===c){if(u=r.$apply,"function"!=typeof u)throw e(o,"using command $apply with a non function");t[p]=u.call(null,t[p]);break}if("$merge"===c){if(l=r.$merge,!i.Object(t[p])||!i.Object(l))throw e(o,"using command $merge with a non object");t[p]=n.shallowMerge(t[p],l);break}if("$push"===c){if(l=r.$push,!i.Array(t[p]))throw e(o,"using command $push to a non array");t[p]=t[p].concat(l)}if("$unshift"===c){if(l=r.$unshift,!i.Array(t[p]))throw e(o,"using command $unshift to a non array");t[p]=[].concat(l).concat(t[p])}}}else for(c in r)t[p][c]="undefined"==typeof t[p][c]?{}:n.shallowClone(t[p][c]),a(t[p],r[c],o.concat(c),t)};return a(t,r),{data:t.root,log:Object.keys(s).map(function(t){return t.split("|λ|").slice(1)})}}},{"./helpers.js":7,"./type.js":10}]},{},[1])(1)}); \ No newline at end of file +!function(t){if("object"==typeof exports&&"undefined"!=typeof module)module.exports=t();else if("function"==typeof define&&define.amd)define([],t);else{var r;r="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:this,r.Baobab=t()}}(function(){var t;return function r(t,e,n){function i(s,a){if(!e[s]){if(!t[s]){var h="function"==typeof require&&require;if(!a&&h)return h(s,!0);if(o)return o(s,!0);var u=new Error("Cannot find module '"+s+"'");throw u.code="MODULE_NOT_FOUND",u}var c=e[s]={exports:{}};t[s][0].call(c.exports,function(r){var e=t[s][1][r];return i(e?e:r)},c,c.exports,r,t,e,n)}return e[s].exports}for(var o="function"==typeof require&&require,s=0;sr;r++)n.push(t[r].handler);return n}var i={once:"boolean",scope:"object"},o=function(){this._enabled=!0,this._children=[],this._handlers={},this._handlersAll=[]};o.prototype.on=function(t,r,e){var n,s,a,h,u,c;if("function"==typeof r){for(u="string"==typeof t?[t]:t,n=0,s=u.length;n!==s;n+=1)if(h=u[n]){this._handlers[h]||(this._handlers[h]=[]),c={handler:r};for(a in e||{}){if(!i[a])throw new Error('The option "'+a+'" is not recognized by Emmett.');c[a]=e[a]}this._handlers[h].push(c)}}else if(t&&"object"==typeof t&&!Array.isArray(t))for(h in t)o.prototype.on.call(this,h,t[h],r);else{if("function"!=typeof t)throw new Error("Wrong arguments.");c={handler:t};for(a in e||{}){if(!i[a])throw new Error('The option "'+a+'" is not recognized by Emmett.');c[a]=e[a]}this._handlersAll.push(c)}return this},o.prototype.once=function(t,r,e){if("function"==typeof r)e=e||{},e.once=!0,this.on(t,r,e);else{if((!t||"object"!=typeof t||Array.isArray(t))&&"function"!=typeof t)throw new Error("Wrong arguments.");r=r||{},r.once=!0,this.on(t,r)}return this},o.prototype.off=function(t,r){var e,n,i,o,s,a,h,u="string"==typeof t?[t]:t;if(1===arguments.length&&"function"==typeof u){r=arguments[0];for(s in this._handlers){for(a=[],e=0,n=this._handlers[s].length;e!==n;e+=1)this._handlers[s][e].handler!==r&&a.push(this._handlers[s][e]);this._handlers[s]=a}for(a=[],e=0,n=this._handlersAll.length;e!==n;e+=1)this._handlersAll[e].handler!==r&&a.push(this._handlersAll[e]);this._handlersAll=a}else if(2===arguments.length)for(e=0,n=u.length;e!==n;e+=1){if(h=u[e],this._handlers[h]){for(a=[],i=0,o=this._handlers[h].length;i!==o;i+=1)this._handlers[h][i].handler!==r&&a.push(this._handlers[h][i]);this._handlers[h]=a}this._handlers[h]&&0===this._handlers[h].length&&delete this._handlers[h]}return this},o.prototype.unbindAll=function(){var t;this._handlersAll=[];for(t in this._handlers)delete this._handlers[t];return this},o.prototype.emit=function(t,r){var e,n,i,o,s,a,h,u,c,l,f="string"==typeof t?[t]:t;if(!this._enabled)return this;for(r=void 0===r?{}:r,e=0,n=f.length;e!==n;e+=1)if(l=f[e],c=(this._handlers[l]||[]).concat(this._handlersAll),c.length){for(h={type:l,data:r||{},target:this},a=[],i=0,o=c.length;i!==o;i+=1)(this._handlers[l]&&this._handlers[l].indexOf(c[i])>=0||this._handlersAll.indexOf(c[i])>=0)&&(c[i].handler.call("scope"in c[i]?c[i].scope:this,h),c[i].once&&a.push(c[i]));for(s=0;se;e++)if(t._children[e]===r){t._children.splice(e,1);break}}),this._children.push(r),r},o.prototype.listeners=function(t){var e,n,i,o=[];if(t)for(o=r(this._handlers[t]),n=0,i=this._children.length;i>n;n++)o=o.concat(this._children[n].listeners(t));else{o=r(this._handlersAll);for(e in this._handlers)o=o.concat(r(this._handlers[e]));for(n=0,i=this._children.length;i>n;n++)o=o.concat(this._children[n].listeners())}return o},o.prototype.kill=function(){if(this.emit("emmett:kill"),this.unbindAll(),this._handlers=null,this._handlersAll=null,this._enabled=!1,this._children)for(var t=0,r=this._children.length;r>t;t++)this._children[t].kill();this._children=null},o.prototype.disable=function(){return this._enabled=!1,this},o.prototype.enable=function(){return this._enabled=!0,this},o.version="2.1.2","undefined"!=typeof n?("undefined"!=typeof e&&e.exports&&(n=e.exports=o),n.Emitter=o):"function"==typeof t&&t.amd?t("emmett",[],function(){return o}):this.Emitter=o}).call(this)},{}],4:[function(t,r){function e(t){return t+"$"+(new Date).getTime()+(""+Math.random()).replace("0.","")}function n(t,r){function e(t){this[t]=function(){var r=this.root[t].apply(this.root,arguments);return r instanceof i?this:r}}if(arguments.length<1&&(t={}),!(this instanceof n))return new n(t,r);if(!f.Object(t)&&!f.Array(t))throw Error("Baobab: invalid data.");o.call(this),this.options=a.shallowMerge(l,r),this._transaction={},this._future=void 0,this._cursors={},this.data=a.deepClone(t),this.root=this.select([]),["get","set","unset","update"].forEach(e.bind(this)),this.mixin=c.baobab(this)}var i=t("./cursor.js"),o=t("emmett"),s=t("./watcher.js"),a=t("./helpers.js"),h=t("./update.js"),u=t("./merge.js"),c=t("./mixins.js"),l=t("../defaults.js"),f=t("./type.js");a.inherits(n,o),n.prototype.select=function(t){if(!t)throw Error("Baobab.select: invalid path.");if(arguments.length>1&&(t=a.arrayOf(arguments)),!f.Path(t))throw Error("Baobab.select: invalid path.");t=[].concat(t);var r,n=f.ComplexPath(t);n&&(r=a.solvePath(this.data,t,this));var o=t.map(function(t){return f.Function(t)?e("fn"):f.Object(t)?e("ob"):t}).join("|λ|");if(this._cursors[o])return this._cursors[o];var s=new i(this,t,r,o);return this._cursors[o]=s,s},n.prototype.stack=function(t){var r=this;if(!f.Object(t))throw Error("Baobab.update: wrong specification.");return this._transaction=u(t,this._transaction),this.options.autoCommit?this.options.asynchronous?(this._future||(this._future=setTimeout(r.commit.bind(r,null),0)),this):this.commit():this},n.prototype.commit=function(){var t=h(this.data,this._transaction,this.options),r=this.data;return this.data=t.data,this._transaction={},this._future&&(this._future=clearTimeout(this._future)),this.emit("update",{log:t.log,previousState:r}),this},n.prototype.watch=function(t){if(!f.Array(t)||t.some(function(t){return!f.Path(t)}))throw Error("Baobab.watch: invalid paths.");return new s(this,[].concat(t))},n.prototype.release=function(){delete this.data,delete this._transaction;for(var t in this._cursors)this._cursors[t].release();delete this._cursors,this.kill()},n.prototype.toJSON=function(){return this.get()},r.exports=n},{"../defaults.js":2,"./cursor.js":5,"./helpers.js":6,"./merge.js":7,"./mixins.js":8,"./type.js":9,"./update.js":10,"./watcher.js":11,emmett:3}],5:[function(t,r){function e(t,r,e,n){function i(t){if(h.isRecording()&&!h.undoing){var r=a.getIn(t,h.solvedPath,h.tree),e=a.deepClone(r);h.archive.add(e)}return h.undoing=!1,h.emit("update")}var h=this;o.call(this),r=r||[],this.tree=t,this.path=r,this.hash=n,this.archive=null,this.undoing=!1,this.complexPath=!!e,this.solvedPath=this.complexPath?e:this.path,this.relevant=void 0!==this.get(),this.updateHandler=function(t){var r=t.data.log,e=t.data.previousState,n=!1;if(h.complexPath&&(h.solvedPath=a.solvePath(h.tree.data,h.path,h.tree)),!h.path.length)return i(e);h.solvedPath&&(n=a.solveUpdate(r,[h.solvedPath]));var o=void 0!==h.get();h.relevant?o&&n?i(e):o||(h.emit("irrelevant"),h.relevant=!1):o&&n&&(h.emit("relevant"),i(e),h.relevant=!0)},this.mixin=s.cursor(this);var u=!1;this._lazyBind=function(){u||(u=!0,h.tree.on("update",h.updateHandler))},this.on=a.before(this._lazyBind,this.on.bind(this)),this.once=a.before(this._lazyBind,this.once.bind(this)),this.complexPath&&this._lazyBind()}function n(t,r,e,n){if(arguments.length>5)throw Error("baobab.Cursor."+t+": too many arguments.");arguments.length<4&&(n=e,e=[]),e=e||[];var i=[].concat(e),o=a.solvePath(this.get(),i,this.tree);if(!o)throw Error("baobab.Cursor."+t+": could not solve dynamic path.");if(r){var s=this.get(o);if(!h[r](s))throw Error("baobab.Cursor."+t+": invalid target.")}var u={};u["$"+t]=n;var c=a.pathObject(o,u);return c}function i(t,r){e.prototype[t]=function(){var e=n.bind(this,t,r).apply(this,arguments);return this.update(e)}}var o=t("emmett"),s=t("./mixins.js"),a=t("./helpers.js"),h=(t("../defaults.js"),t("./type.js"));a.inherits(e,o),e.prototype.isRoot=function(){return!this.path.length},e.prototype.isLeaf=function(){return h.Primitive(this.get())},e.prototype.isBranch=function(){return!this.isLeaf()&&!this.isRoot()},e.prototype.root=function(){return this.tree.root()},e.prototype.select=function(t){if(arguments.length>1&&(t=a.arrayOf(arguments)),!h.Path(t))throw Error("baobab.Cursor.select: invalid path.");return this.tree.select(this.path.concat(t))},e.prototype.up=function(){return this.solvedPath&&this.solvedPath.length?this.tree.select(this.path.slice(0,-1)):null},e.prototype.left=function(){var t=+this.solvedPath[this.solvedPath.length-1];if(isNaN(t))throw Error("baobab.Cursor.left: cannot go left on a non-list type.");return t?this.tree.select(this.solvedPath.slice(0,-1).concat(t-1)):null},e.prototype.leftmost=function(){var t=+this.solvedPath[this.solvedPath.length-1];if(isNaN(t))throw Error("baobab.Cursor.leftmost: cannot go left on a non-list type.");return this.tree.select(this.solvedPath.slice(0,-1).concat(0))},e.prototype.right=function(){var t=+this.solvedPath[this.solvedPath.length-1];if(isNaN(t))throw Error("baobab.Cursor.right: cannot go right on a non-list type.");return t+1===this.up().get().length?null:this.tree.select(this.solvedPath.slice(0,-1).concat(t+1))},e.prototype.rightmost=function(){var t=+this.solvedPath[this.solvedPath.length-1];if(isNaN(t))throw Error("baobab.Cursor.right: cannot go right on a non-list type.");var r=this.up().get();return this.tree.select(this.solvedPath.slice(0,-1).concat(r.length-1))},e.prototype.down=function(){+this.solvedPath[this.solvedPath.length-1];return this.get()instanceof Array?this.tree.select(this.solvedPath.concat(0)):null},e.prototype.get=function(t){arguments.length>1&&(t=a.arrayOf(arguments));var r=this.solvedPath.concat((h.String(t)||h.Number(t)?[t]:t)||[]);return a.getIn(this.tree.data,r,this.tree)},i("set"),i("apply"),i("chain"),i("push","Array"),i("unshift","Array"),e.prototype.merge=function(t){if(!h.Object(t))throw Error("baobab.Cursor.merge: trying to merge a non-object.");var r=n.bind(this,"merge","Object").apply(this,arguments);return this.update(r)},e.prototype.unset=function(t){if(void 0===t&&this.isRoot())throw Error("baobab.Cursor.unset: cannot remove root node.");var r=n.bind(this,"unset",null).apply(this,[t,!0]);return this.update(r)},e.prototype.update=function(t,r){if(arguments.length<2)return this.tree.stack(a.pathObject(this.solvedPath,t)),this;var e=[].concat(t),n=a.solvePath(this.get(),e,this.tree);if(!n)throw Error("baobab.Cursor.update: could not solve dynamic path.");return this.tree.stack(a.pathObject(this.solvedPath.concat(n),r)),this},e.prototype.startRecording=function(t){if(t=t||5,1>t)throw Error("baobab.Cursor.startRecording: invalid maximum number of records.");return this.archive?this:(this._lazyBind(),this.archive=a.archive(t),this)},e.prototype.stopRecording=function(){return this.archive=null,this},e.prototype.undo=function(t){if(t=t||1,!this.isRecording())throw Error("baobab.Cursor.undo: cursor is not recording.");if(!h.PositiveInteger(t))throw Error("baobab.Cursor.undo: expecting a positive integer.");var r=this.archive.back(t);if(!r)throw Error("boabab.Cursor.undo: cannot find a relevant record ("+t+" back).");return this.undoing=!0,this.set(r)},e.prototype.isRecording=function(){return!!this.archive},e.prototype.hasHistory=function(){return!(!this.archive||!this.archive.get().length)},e.prototype.getHistory=function(){return this.archive?this.archive.get():[]},e.prototype.release=function(){this.tree.off("update",this.updateHandler),this.hash&&delete this.tree._cursors[this.hash],delete this.tree,delete this.path,delete this.solvedPath,delete this.archive,this.kill()},e.prototype.toJSON=function(){return this.get()},h.Cursor=function(t){return t instanceof e},r.exports=e},{"../defaults.js":2,"./helpers.js":6,"./mixins.js":8,"./type.js":9,emmett:3}],6:[function(t,r){(function(e){function n(t){return Array.prototype.slice.call(t)}function i(t,r){return function(){t(),r.apply(null,arguments)}}function o(t,r){var e,n={};for(e in t)n[e]=t[e];for(e in r)n[e]=r[e];return n}function s(t){var r=t.source,e="";return t.global&&(e+="g"),t.multiline&&(e+="m"),t.ignoreCase&&(e+="i"),t.sticky&&(e+="y"),t.unicode&&(e+="u"),new RegExp(r,e)}function a(t,r){if(!r||"object"!=typeof r||r instanceof Error||"ArrayBuffer"in e&&r instanceof ArrayBuffer)return r;if(j.Array(r)){if(t){var n,i,o=[];for(n=0,i=r.length;i>n;n++)o.push($(r[n]));return o}return r.slice(0)}if(j.Date(r))return new Date(r.getTime());if(r instanceof RegExp)return s(r);if(j.Object(r)){var a,h={};r.constructor&&r.constructor!==Object&&(h=Object.create(r.constructor.prototype));for(a in r)r.hasOwnProperty(a)&&(h[a]=t?$(r[a]):r[a]);return h}return r}function h(t,r){return function(e){return r(t(e))}}function u(t,r){var e,n;for(e=0,n=t.length;n>e;e++)if(r(t[e]))return t[e]}function c(t,r){var e,n;for(e=0,n=t.length;n>e;e++)if(r(t[e]))return e;return-1}function l(t,r){var e,n=!0;if(!t)return!1;for(e in r)if(j.Object(r[e]))n=n&&l(t[e],r[e]);else if(j.Array(r[e]))n=n&&!!~r[e].indexOf(t[e]);else if(t[e]!==r[e])return!1;return n}function f(t,r){return u(t,function(t){return l(t,r)})}function d(t,r){return c(t,function(t){return l(t,r)})}function y(t,r,e){r=r||[];var n,i,o,s=t;for(i=0,o=r.length;o>i;i++){if(!s)return;if("function"==typeof r[i]){if(!j.Array(s))return;s=u(s,r[i])}else if("object"==typeof r[i])if(e&&"$cursor"in r[i]){if(!j.Path(r[i].$cursor))throw Error("baobab.getIn: $cursor path must be an array.");n=e.get(r[i].$cursor),s=s[n]}else{if(!j.Array(s))return;s=f(s,r[i])}else s=s[r[i]]}return s}function g(t,r,e){var n,i,o,s=[],a=t;for(i=0,o=r.length;o>i;i++){if(!a)return null;if("function"==typeof r[i]){if(!j.Array(a))return;n=c(a,r[i]),s.push(n),a=a[n]}else if("object"==typeof r[i])if(e&&"$cursor"in r[i]){if(!j.Path(r[i].$cursor))throw Error("baobab.getIn: $cursor path must be an array.");p=e.get(r[i].$cursor),s.push(p),a=a[p]}else{if(!j.Array(a))return;n=d(a,r[i]),s.push(n),a=a[n]}else s.push(r[i]),a=a[r[i]]||{}}return s}function b(t,r){var e,n,i,o,s,a,h,u,c;for(e=0,o=r.length;o>e;e++)for(h=r[e],n=0,s=t.length;s>n;n++)for(u=t[n],i=0,a=u.length;a>i&&(c=u[i],c==h[i]);i++)if(i+1===a||i+1===h.length)return!0;return!1}function v(t,r){var e,n=t.length,i={},o=i;for(n||(i=r),e=0;n>e;e++)o[t[e]]=e+1===n?r:{},o=o[t[e]];return i}function m(t,r){t.super_=r;var e=function(){};e.prototype=r.prototype,t.prototype=new e,t.prototype.constructor=t}function _(t){var r=[];return{add:function(e){for(r.unshift(e);r.length>t;)r.pop()},back:function(t){var e=r[t-1];return e&&(r=r.slice(t)),e},get:function(){return r}}}var j=t("./type.js"),w=a.bind(null,!1),$=a.bind(null,!0);r.exports={archive:_,arrayOf:n,before:i,deepClone:$,shallowClone:w,shallowMerge:o,compose:h,getIn:y,inherits:m,pathObject:v,solvePath:g,solveUpdate:b}}).call(this,"undefined"!=typeof global?global:"undefined"!=typeof self?self:"undefined"!=typeof window?window:{})},{"./type.js":9}],7:[function(t,r){function e(t,r,e){s.forEach(function(r){e!==r&&delete t[r]}),t[e]=r[e]}function n(t,r){var a,h=i.shallowClone(r||{});s.forEach(function(r){t[r]&&e(h,t,r)}),t.$chain&&(s.slice(0,-1).forEach(function(t){delete h[t]}),h.$apply=h.$apply?i.compose(h.$apply,t.$chain):t.$chain),t.$push&&h.$push?h.$push=o.Array(h.$push)?h.$push.concat(t.$push):[h.$push].concat(t.$push):t.$push&&(h.$push=t.$push),t.$unshift&&h.$unshift?h.$unshift=o.Array(t.$unshift)?t.$unshift.concat(h.$unshift):[t.$unshift].concat(h.$unshift):t.$unshift&&(h.$unshift=t.$unshift);for(a in t)o.Object(t[a])?h[a]=n(t[a],h[a]):"$"!==a[0]&&(h[a]=t[a]);return h}var i=t("./helpers.js"),o=t("./type.js"),s=["$unset","$set","$merge","$apply"];r.exports=n},{"./helpers.js":6,"./type.js":9}],8:[function(t,r){var e=t("./type.js");r.exports={baobab:function(t){return{mixins:[{getInitialState:function(){if(this.tree=t,!this.cursor&&!this.cursors)return{};if(this.cursor&&this.cursors)throw Error("baobab.mixin: you cannot have both `component.cursor` and `component.cursors`. Please make up your mind.");if(this.__type=null,this.__updateHandler=function(){this.setState(this.__getCursorData())}.bind(this),this.cursor){if(!e.MixinCursor(this.cursor))throw Error("baobab.mixin.cursor: invalid data (cursor, string, array or function).");e.Function(this.cursor)&&(this.cursor=this.cursor()),e.Cursor(this.cursor)||(this.cursor=t.select(this.cursor)),this.__getCursorData=function(){return{cursor:this.cursor.get()}}.bind(this),this.__type="single"}else if(this.cursors){if(!e.MixinCursors(this.cursors))throw Error("baobab.mixin.cursor: invalid data (object, array or function).");if(e.Function(this.cursors)&&(this.cursors=this.cursors()),e.Array(this.cursors))this.cursors=this.cursors.map(function(r){return e.Cursor(r)?r:t.select(r)}),this.__getCursorData=function(){return{cursors:this.cursors.map(function(t){return t.get()})}}.bind(this),this.__type="array";else{for(var r in this.cursors)e.Cursor(this.cursors[r])||(this.cursors[r]=t.select(this.cursors[r]));this.__getCursorData=function(){var t={};for(r in this.cursors)t[r]=this.cursors[r].get();return{cursors:t}}.bind(this),this.__type="object"}}return this.__getCursorData()},componentDidMount:function(){"single"===this.__type?(this.__watcher=this.tree.watch([this.cursor.path]),this.__watcher.on("update",this.__updateHandler)):"array"===this.__type?(this.__watcher=this.tree.watch(this.cursors.map(function(t){return t.path})),this.__watcher.on("update",this.__updateHandler)):"object"===this.__type&&(this.__watcher=this.tree.watch(Object.keys(this.cursors).map(function(t){return this.cursors[t].path},this)),this.__watcher.on("update",this.__updateHandler))},componentWillUnmount:function(){this.__watcher&&this.__watcher.release()}}].concat(t.options.mixins)}},cursor:function(t){return{mixins:[{getInitialState:function(){return this.cursor=t,this.__updateHandler=function(){this.setState({cursor:this.cursor.get()})}.bind(this),{cursor:this.cursor.get()}},componentDidMount:function(){this.cursor.on("update",this.__updateHandler)},componentWillUnmount:function(){this.cursor.off("update",this.__updateHandler)}}].concat(t.tree.options.mixins)}}}},{"./type.js":9}],9:[function(t,r){function e(t,r){return r.some(function(r){return n[r](t)})}var n={};n.Array=function(t){return Array.isArray(t)},n.Object=function(t){return!Array.isArray(t)&&"object"==typeof t&&null!==t},n.String=function(t){return"string"==typeof t},n.Number=function(t){return"number"==typeof t},n.PositiveInteger=function(t){return"number"==typeof t&&t>0&&!(t%1)},n.Function=function(t){return"function"==typeof t},n.Primitive=function(t){return"string"==typeof t||"number"==typeof t||"boolean"==typeof t},n.Date=function(t){return t instanceof Date},n.NonScalar=function(t){return n.Object(t)||n.Array(t)},n.Path=function(t){var r=["String","Number","Function","Object"];return n.Array(t)?t.every(function(t){return e(t,r)}):e(t,r)},n.MixinCursor=function(t){return e(t,["String","Number","Array","Function","Cursor"])},n.MixinCursors=function(t){return e(t,["Object","Array","Function"])},n.ComplexPath=function(t){return t.some(function(t){return e(t,["Object","Function"])})},r.exports=n},{}],10:[function(t,r){function e(t,r){var e=new Error("baobab.update: "+r+" at path /"+t.slice(1).join("/"));return e.path=t,e}var n=t("./helpers.js"),i=t("./type.js");r.exports=function(t,r,o){if(o=o||{},!i.Object(t)&&!i.Array(t))throw Error("baobab.update: invalid target.");var s={};t={root:n.shallowClone(t)};var a=function(t,r,o,h){o=o||["root"];var u,c,l,f=o.join("|λ|"),p=o[o.length-1],d=Object.keys(r).some(function(t){return!!~["$unset","$set","$apply","$merge","$push","$unshift"].indexOf(t)});if(d){s[f]=!0;for(c in r){if("$unset"===c){var y=o[o.length-2];i.Array(t)?h[y]=t.slice(0,+p).concat(t.slice(+p+1)):(h[y]=n.shallowClone(t),delete h[y][p]);break}if("$set"===c){l=r.$set,t[p]=l;break}if("$apply"===c){if(u=r.$apply,"function"!=typeof u)throw e(o,"using command $apply with a non function");t[p]=u.call(null,t[p]);break}if("$merge"===c){if(l=r.$merge,!i.Object(t[p])||!i.Object(l))throw e(o,"using command $merge with a non object");t[p]=n.shallowMerge(t[p],l);break}if("$push"===c){if(l=r.$push,!i.Array(t[p]))throw e(o,"using command $push to a non array");t[p]=t[p].concat(l)}if("$unshift"===c){if(l=r.$unshift,!i.Array(t[p]))throw e(o,"using command $unshift to a non array");t[p]=[].concat(l).concat(t[p])}}}else for(c in r)t[p][c]="undefined"==typeof t[p][c]?{}:n.shallowClone(t[p][c]),a(t[p],r[c],o.concat(c),t)};return a(t,r),{data:t.root,log:Object.keys(s).map(function(t){return t.split("|λ|").slice(1)})}}},{"./helpers.js":6,"./type.js":9}],11:[function(t,r){function e(t,r){function e(){h&&(a=r.map(function(t){return i.solvePath(s.tree.data,t,s.tree)}))}var s=this;n.call(this),this.tree=t;var a=r,h=r.some(o.ComplexPath);this.updateHandler=function(t){var r=i.solveUpdate(t.data.log,a);r&&s.emit("update")},e(),this.tree.on("update",this.updateHandler)}var n=t("emmett"),i=t("./helpers.js"),o=t("./type.js");i.inherits(e,n),e.prototype.release=function(){this.tree.off("update",this.updateHandler),this.tree=null,this.kill()},r.exports=e},{"./helpers.js":6,"./type.js":9,emmett:3}]},{},[1])(1)}); \ No newline at end of file diff --git a/src/baobab.js b/src/baobab.js index 7b4f29e..b8a4059 100644 --- a/src/baobab.js +++ b/src/baobab.js @@ -6,6 +6,7 @@ */ var Cursor = require('./cursor.js'), EventEmitter = require('emmett'), + Watcher = require('./watcher.js'), helpers = require('./helpers.js'), update = require('./update.js'), merge = require('./merge.js'), @@ -154,6 +155,16 @@ Baobab.prototype.commit = function() { return this; }; +Baobab.prototype.watch = function(paths) { + if (!type.Array(paths) || + paths.some(function(p) { + return !type.Path(p); + })) + throw Error('Baobab.watch: invalid paths.'); + + return new Watcher(this, [].concat(paths)); +}; + Baobab.prototype.release = function() { delete this.data; diff --git a/src/combination.js b/src/combination.js deleted file mode 100644 index ca06bde..0000000 --- a/src/combination.js +++ /dev/null @@ -1,158 +0,0 @@ -/** - * Baobab Cursor Combination - * ========================== - * - * A useful abstraction dealing with cursor's update logical combinations. - */ -var EventEmitter = require('emmett'), - helpers = require('./helpers.js'), - type = require('./type.js'); - -/** - * Utilities - */ -function bindCursor(c, cursor) { - cursor.on('update', c.cursorListener); - c.tree.off('update', c.treeListener); - c.tree.on('update', c.treeListener); -} - -/** - * Main Class - */ -function Combination(operator /*, &cursors */) { - var self = this; - - // Safeguard - if (arguments.length < 2) - throw Error('baobab.Combination: not enough arguments.'); - - var first = arguments[1], - rest = helpers.arrayOf(arguments).slice(2); - - if (first instanceof Array) { - rest = first.slice(1); - first = first[0]; - } - - if (!type.Cursor(first)) - throw Error('baobab.Combination: argument should be a cursor.'); - - if (operator !== 'or' && operator !== 'and') - throw Error('baobab.Combination: invalid operator.'); - - // Extending event emitter - EventEmitter.call(this); - - // Properties - this.cursors = [first]; - this.operators = []; - this.tree = first.tree; - - // State - this.updates = new Array(this.cursors.length); - - // Listeners - this.cursorListener = function() { - self.updates[self.cursors.indexOf(this)] = true; - }; - - this.treeListener = function() { - var shouldFire = self.updates[0], - i, - l; - - for (i = 1, l = self.cursors.length; i < l; i++) { - shouldFire = self.operators[i - 1] === 'or' ? - shouldFire || self.updates[i] : - shouldFire && self.updates[i]; - } - - if (shouldFire) - self.emit('update'); - - // Waiting for next update - self.updates = new Array(self.cursors.length); - }; - - // Lazy binding - this.bound = false; - - var regularOn = this.on, - regularOnce = this.once; - - var lazyBind = function() { - if (self.bound) - return; - self.bound = true; - self.cursors.forEach(function(cursor) { - bindCursor(self, cursor); - }); - }; - - this.on = helpers.before(lazyBind, this.on.bind(this)); - this.once = helpers.before(lazyBind, this.once.bind(this)); - - // Attaching any other passed cursors - rest.forEach(function(cursor) { - this[operator](cursor); - }, this); -} - -helpers.inherits(Combination, EventEmitter); - -/** - * Prototype - */ -function makeOperator(operator) { - Combination.prototype[operator] = function(cursor) { - - // Safeguard - if (!type.Cursor(cursor)) { - this.release(); - throw Error('baobab.Combination.' + operator + ': argument should be a cursor.'); - } - - if (~this.cursors.indexOf(cursor)) { - this.release(); - throw Error('baobab.Combination.' + operator + ': cursor already in combination.'); - } - - this.cursors.push(cursor); - this.operators.push(operator); - this.updates.length++; - - if (this.bound) - bindCursor(this, cursor); - - return this; - }; -} - -makeOperator('or'); -makeOperator('and'); - -Combination.prototype.release = function() { - - // Dropping cursors listeners - this.cursors.forEach(function(cursor) { - cursor.off('update', this.cursorListener); - }, this); - - // Dropping tree listener - this.tree.off('update', this.treeListener); - - // Cleaning - this.cursors = null; - this.operators = null; - this.tree = null; - this.updates = null; - - // Dropping own listeners - this.kill(); -}; - -/** - * Exporting - */ -module.exports = Combination; diff --git a/src/cursor.js b/src/cursor.js index 11228c2..c1bda5f 100644 --- a/src/cursor.js +++ b/src/cursor.js @@ -5,7 +5,6 @@ * Nested selection into a baobab tree. */ var EventEmitter = require('emmett'), - Combination = require('./combination.js'), mixins = require('./mixins.js'), helpers = require('./helpers.js'), defaults = require('../defaults.js'), @@ -301,17 +300,6 @@ Cursor.prototype.update = function(key, spec) { return this; }; -/** - * Combination - */ -Cursor.prototype.or = function(otherCursor) { - return new Combination('or', this, otherCursor); -}; - -Cursor.prototype.and = function(otherCursor) { - return new Combination('and', this, otherCursor); -}; - /** * History */ diff --git a/src/mixins.js b/src/mixins.js index cce7a15..9b2e674 100644 --- a/src/mixins.js +++ b/src/mixins.js @@ -4,8 +4,7 @@ * * Compilation of react mixins designed to deal with cursors integration. */ -var Combination = require('./combination.js'), - type = require('./type.js'); +var type = require('./type.js'); module.exports = { baobab: function(baobab) { @@ -91,26 +90,25 @@ module.exports = { }, componentDidMount: function() { if (this.__type === 'single') { - this.__combination = new Combination('or', [this.cursor]); - this.__combination.on('update', this.__updateHandler); + this.__watcher = this.tree.watch([this.cursor.path]); + this.__watcher.on('update', this.__updateHandler); } else if (this.__type === 'array') { - this.__combination = new Combination('or', this.cursors); - this.__combination.on('update', this.__updateHandler); + this.__watcher = this.tree.watch(this.cursors.map(function(c) { + return c.path; + })); + this.__watcher.on('update', this.__updateHandler); } else if (this.__type === 'object') { - this.__combination = new Combination( - 'or', - Object.keys(this.cursors).map(function(k) { - return this.cursors[k]; - }, this) - ); - this.__combination.on('update', this.__updateHandler); + this.__watcher = this.tree.watch(Object.keys(this.cursors).map(function(k) { + return this.cursors[k].path; + }, this)); + this.__watcher.on('update', this.__updateHandler); } }, componentWillUnmount: function() { - if (this.__combination) - this.__combination.release(); + if (this.__watcher) + this.__watcher.release(); } }].concat(baobab.options.mixins) }; diff --git a/src/type.js b/src/type.js index af4f6aa..c7a63a3 100644 --- a/src/type.js +++ b/src/type.js @@ -82,8 +82,8 @@ type.MixinCursors = function (value) { }; type.ComplexPath = function (value) { - return value.some(function(v) { - return anyOf(v, ['Object', 'Function']); + return value.some(function(step) { + return anyOf(step, ['Object', 'Function']); }); }; diff --git a/src/watcher.js b/src/watcher.js new file mode 100644 index 0000000..5490a4d --- /dev/null +++ b/src/watcher.js @@ -0,0 +1,54 @@ +/** + * Baobab Paths Watcher + * ===================== + * + * A simple abstraction that will fire if any watched path updates. + */ +var EventEmitter = require('emmett'), + helpers = require('./helpers.js'), + type = require('./type.js'); + +/** + * Main Class + */ +function Watcher(tree, paths) { + var self = this; + + // Extending event emitter + EventEmitter.call(this); + + // Properties + this.tree = tree; + + // Privates + var solvedPaths = paths, + complex = paths.some(type.ComplexPath); + + function solvePaths() { + if (complex) + solvedPaths = paths.map(function(p) { + return helpers.solvePath(self.tree.data, p, self.tree); + }); + } + + this.updateHandler = function(e) { + var shoudlFire = helpers.solveUpdate(e.data.log, solvedPaths); + + if (shoudlFire) + self.emit('update'); + }; + + solvePaths(); + this.tree.on('update', this.updateHandler); +} + +helpers.inherits(Watcher, EventEmitter); + +Watcher.prototype.release = function() { + this.tree.off('update', this.updateHandler); + + this.tree = null; + this.kill(); +}; + +module.exports = Watcher; diff --git a/test/endpoint.js b/test/endpoint.js index 334ba01..5419059 100644 --- a/test/endpoint.js +++ b/test/endpoint.js @@ -7,5 +7,5 @@ require('./suites/helpers.js'); require('./suites/baobab.js'); require('./suites/cursor.js'); -require('./suites/combination.js'); +// require('./suites/combination.js'); require('./suites/mixins.js'); From e921c226603b1c92016f0a27d8fb45fc7ce6c2f2 Mon Sep 17 00:00:00 2001 From: Yomguithereal Date: Thu, 9 Apr 2015 23:33:39 +0200 Subject: [PATCH 41/73] Style normalization in type.js --- src/type.js | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/src/type.js b/src/type.js index c7a63a3..52084bb 100644 --- a/src/type.js +++ b/src/type.js @@ -21,19 +21,19 @@ function anyOf(value, allowed) { /** * Simple types */ -type.Array = function (value) { +type.Array = function(value) { return Array.isArray(value); }; -type.Object = function (value) { +type.Object = function(value) { return !Array.isArray(value) && typeof value === 'object' && value !== null; }; -type.String = function (value) { +type.String = function(value) { return typeof value === 'string'; }; -type.Number = function (value) { +type.Number = function(value) { return typeof value === 'number'; }; @@ -41,15 +41,15 @@ type.PositiveInteger = function(value) { return typeof value === 'number' && value > 0 && !(value % 1); }; -type.Function = function (value) { +type.Function = function(value) { return typeof value === 'function'; }; -type.Primitive = function (value) { +type.Primitive = function(value) { return typeof value === 'string' || typeof value === 'number' || typeof value === 'boolean'; }; -type.Date = function (value) { +type.Date = function(value) { return value instanceof Date; }; @@ -60,7 +60,7 @@ type.NonScalar = function(value) { return type.Object(value) || type.Array(value); }; -type.Path = function (value) { +type.Path = function(value) { var allowed = ['String', 'Number', 'Function', 'Object']; if (type.Array(value)) { @@ -73,15 +73,15 @@ type.Path = function (value) { } }; -type.MixinCursor = function (value) { +type.MixinCursor = function(value) { return anyOf(value, ['String', 'Number', 'Array', 'Function', 'Cursor']); }; -type.MixinCursors = function (value) { +type.MixinCursors = function(value) { return anyOf(value, ['Object', 'Array', 'Function']); }; -type.ComplexPath = function (value) { +type.ComplexPath = function(value) { return value.some(function(step) { return anyOf(step, ['Object', 'Function']); }); From ae48176dc7058e50205b2492ab7de7ac31175b24 Mon Sep 17 00:00:00 2001 From: Yomguithereal Date: Thu, 9 Apr 2015 23:44:43 +0200 Subject: [PATCH 42/73] Watcher unit testing --- test/endpoint.js | 2 +- test/suites/combination.js | 243 ------------------------------------- test/suites/watcher.js | 50 ++++++++ 3 files changed, 51 insertions(+), 244 deletions(-) delete mode 100644 test/suites/combination.js create mode 100644 test/suites/watcher.js diff --git a/test/endpoint.js b/test/endpoint.js index 5419059..165e1d2 100644 --- a/test/endpoint.js +++ b/test/endpoint.js @@ -7,5 +7,5 @@ require('./suites/helpers.js'); require('./suites/baobab.js'); require('./suites/cursor.js'); -// require('./suites/combination.js'); +require('./suites/watcher.js'); require('./suites/mixins.js'); diff --git a/test/suites/combination.js b/test/suites/combination.js deleted file mode 100644 index acdb05a..0000000 --- a/test/suites/combination.js +++ /dev/null @@ -1,243 +0,0 @@ -/** - * Baobab Helpers Unit Tests - * ========================== - */ -var assert = require('assert'), - state = require('../state.js'), - Baobab = require('../../src/baobab.js'), - Combination = require('../../src/combination.js'); - -describe('Combination', function() { - var baobab = new Baobab({list: [1, 2, 3], otherlist: [4, 5, 6], againList: [7, 8, 9]}, {autoCommit: false}), - cursor = baobab.select('list'), - othercursor = baobab.select('otherlist'), - againCursor = baobab.select('againList'); - - it('related cursor methods should return Combination instances.', function() { - var or = cursor.or(othercursor), - and = cursor.and(othercursor); - - assert(or instanceof Combination); - assert(and instanceof Combination); - - or.release(); - and.release(); - }); - - it('should fail when using combination wrongly.', function() { - assert.throws(function() { - cursor.or(cursor); - }, /already/); - }); - - it('should be possible to listen to "or" combinations.', function() { - var combination = cursor.or(othercursor), - count = 0; - - combination.on('update', function() { - count++; - }); - - // 1 - cursor.push(4); - baobab.commit(); - - // 2 - othercursor.push(7); - baobab.commit(); - - // 3 - cursor.set([1]); - othercursor.set([4]); - baobab.commit(); - - assert.strictEqual(count, 3); - combination.release(); - }); - - it('should be possible to listen to "and" combinations.', function() { - var combination = cursor.and(othercursor), - count = 0; - - combination.on('update', function() { - count++; - }); - - // 1 - cursor.push(4); - baobab.commit(); - - // 2 - othercursor.push(7); - baobab.commit(); - - // 3 - cursor.set([1]); - othercursor.set([4]); - baobab.commit(); - - assert.strictEqual(count, 1); - combination.release(); - }); - - it('should be possible to make complex "or" combinations.', function() { - var combination = cursor.or(othercursor).or(againCursor), - count = 0; - - combination.on('update', function() { - count++; - }); - - // 1 - cursor.push(4); - baobab.commit(); - - // 2 - othercursor.push(7); - baobab.commit(); - - // 3 - cursor.set([1]); - othercursor.set([4]); - baobab.commit(); - - // 4 - againCursor.set([7]); - baobab.commit(); - - combination.release(); - assert.strictEqual(count, 4); - }); - - it('should be possible to make complex "and" combinations.', function() { - var combination = cursor.and(othercursor).and(againCursor), - count = 0; - - combination.on('update', function() { - count++; - }); - - // 1 - cursor.push(4); - baobab.commit(); - - // 2 - othercursor.push(7); - baobab.commit(); - - // 3 - cursor.set([1]); - othercursor.set([4]); - baobab.commit(); - - // 4 - againCursor.set([7]); - baobab.commit(); - - // 5 - cursor.set([1]); - othercursor.set([4]); - againCursor.set([7]); - baobab.commit(); - - assert.strictEqual(count, 1); - combination.release(); - }); - - it('should be possible to mix combinations.', function() { - var combination = cursor.or(othercursor).and(againCursor), - count = 0; - - combination.on('update', function() { - count++; - }); - - // 1 - cursor.set([1]); - againCursor.set([7]); - baobab.commit(); - - // 2 - againCursor.set([7]); - baobab.commit(); - - // 3 - cursor.set([1]); - othercursor.set([4]); - baobab.commit(); - - assert.strictEqual(count, 1); - combination.release(); - }); - - it('should be possible to use some polymorphism.', function() { - - // First case - var combination = new Combination('or', [cursor, othercursor]), - count = 0; - - combination.on('update', function() { - count++; - }); - - // 1 - cursor.push(4); - baobab.commit(); - - // 2 - othercursor.push(7); - baobab.commit(); - - // 3 - cursor.set([1]); - othercursor.set([4]); - baobab.commit(); - - assert.strictEqual(count, 3); - combination.release(); - - // Second case - combination = new Combination('or', cursor, othercursor); - count = 0; - - combination.on('update', function() { - count++; - }); - - // 1 - cursor.push(4); - baobab.commit(); - - // 2 - othercursor.push(7); - baobab.commit(); - - // 3 - cursor.set([1]); - othercursor.set([4]); - baobab.commit(); - - assert.strictEqual(count, 3); - combination.release(); - }); - - it('a single cursor combination should work as expected.', function() { - var combination = new Combination('or', cursor), - count = 0; - - combination.on('update', function() { - count++; - }); - - // 1 - cursor.push(4); - baobab.commit(); - - // 2 - cursor.push(5); - baobab.commit(); - - assert.strictEqual(count, 2); - combination.release(); - }); -}); diff --git a/test/suites/watcher.js b/test/suites/watcher.js new file mode 100644 index 0000000..069b30f --- /dev/null +++ b/test/suites/watcher.js @@ -0,0 +1,50 @@ +/** + * Baobab Helpers Unit Tests + * ========================== + */ +var assert = require('assert'), + state = require('../state.js'), + Baobab = require('../../src/baobab.js'), + Watcher = require('../../src/watcher.js'); + +describe('Watcher', function() { + var baobab = new Baobab({list: [1, 2, 3], otherlist: [4, 5, 6], unrelated: 0}, {autoCommit: false}), + list = baobab.select('list'), + other = baobab.select('otherlist'), + unrelated = baobab.select('unrelated'); + + it('baobab.watch should return a watcher instance.', function() { + assert(baobab.watch([['list']]) instanceof Watcher); + }); + + it('should fire correctly.', function() { + var count = 0, + inc = function() {count++;}; + + var watcher = baobab.watch([['list'], ['otherlist']]); + watcher.on('update', inc); + + list.push(4); + baobab.commit(); + + assert.strictEqual(count, 1); + + unrelated.set(1); + baobab.commit(); + + assert.strictEqual(count, 1); + + other.push(4); + baobab.commit(); + + assert.strictEqual(count, 2); + + list.push(5); + other.push(5); + baobab.commit(); + + assert.strictEqual(count, 3); + + watcher.release(); + }); +}); From d371afd567cb1503394cca42505eae4f854ad5e6 Mon Sep 17 00:00:00 2001 From: Yomguithereal Date: Fri, 10 Apr 2015 14:05:42 +0200 Subject: [PATCH 43/73] Better type.Object --- build/baobab.min.js | 2 +- src/type.js | 5 ++++- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/build/baobab.min.js b/build/baobab.min.js index 9348f3b..375523a 100644 --- a/build/baobab.min.js +++ b/build/baobab.min.js @@ -1,2 +1,2 @@ /* baobab.js - Version: 1.0.0-rc1 - Author: Yomguithereal (Guillaume Plique) */ -!function(t){if("object"==typeof exports&&"undefined"!=typeof module)module.exports=t();else if("function"==typeof define&&define.amd)define([],t);else{var r;r="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:this,r.Baobab=t()}}(function(){var t;return function r(t,e,n){function i(s,a){if(!e[s]){if(!t[s]){var h="function"==typeof require&&require;if(!a&&h)return h(s,!0);if(o)return o(s,!0);var u=new Error("Cannot find module '"+s+"'");throw u.code="MODULE_NOT_FOUND",u}var c=e[s]={exports:{}};t[s][0].call(c.exports,function(r){var e=t[s][1][r];return i(e?e:r)},c,c.exports,r,t,e,n)}return e[s].exports}for(var o="function"==typeof require&&require,s=0;sr;r++)n.push(t[r].handler);return n}var i={once:"boolean",scope:"object"},o=function(){this._enabled=!0,this._children=[],this._handlers={},this._handlersAll=[]};o.prototype.on=function(t,r,e){var n,s,a,h,u,c;if("function"==typeof r){for(u="string"==typeof t?[t]:t,n=0,s=u.length;n!==s;n+=1)if(h=u[n]){this._handlers[h]||(this._handlers[h]=[]),c={handler:r};for(a in e||{}){if(!i[a])throw new Error('The option "'+a+'" is not recognized by Emmett.');c[a]=e[a]}this._handlers[h].push(c)}}else if(t&&"object"==typeof t&&!Array.isArray(t))for(h in t)o.prototype.on.call(this,h,t[h],r);else{if("function"!=typeof t)throw new Error("Wrong arguments.");c={handler:t};for(a in e||{}){if(!i[a])throw new Error('The option "'+a+'" is not recognized by Emmett.');c[a]=e[a]}this._handlersAll.push(c)}return this},o.prototype.once=function(t,r,e){if("function"==typeof r)e=e||{},e.once=!0,this.on(t,r,e);else{if((!t||"object"!=typeof t||Array.isArray(t))&&"function"!=typeof t)throw new Error("Wrong arguments.");r=r||{},r.once=!0,this.on(t,r)}return this},o.prototype.off=function(t,r){var e,n,i,o,s,a,h,u="string"==typeof t?[t]:t;if(1===arguments.length&&"function"==typeof u){r=arguments[0];for(s in this._handlers){for(a=[],e=0,n=this._handlers[s].length;e!==n;e+=1)this._handlers[s][e].handler!==r&&a.push(this._handlers[s][e]);this._handlers[s]=a}for(a=[],e=0,n=this._handlersAll.length;e!==n;e+=1)this._handlersAll[e].handler!==r&&a.push(this._handlersAll[e]);this._handlersAll=a}else if(2===arguments.length)for(e=0,n=u.length;e!==n;e+=1){if(h=u[e],this._handlers[h]){for(a=[],i=0,o=this._handlers[h].length;i!==o;i+=1)this._handlers[h][i].handler!==r&&a.push(this._handlers[h][i]);this._handlers[h]=a}this._handlers[h]&&0===this._handlers[h].length&&delete this._handlers[h]}return this},o.prototype.unbindAll=function(){var t;this._handlersAll=[];for(t in this._handlers)delete this._handlers[t];return this},o.prototype.emit=function(t,r){var e,n,i,o,s,a,h,u,c,l,f="string"==typeof t?[t]:t;if(!this._enabled)return this;for(r=void 0===r?{}:r,e=0,n=f.length;e!==n;e+=1)if(l=f[e],c=(this._handlers[l]||[]).concat(this._handlersAll),c.length){for(h={type:l,data:r||{},target:this},a=[],i=0,o=c.length;i!==o;i+=1)(this._handlers[l]&&this._handlers[l].indexOf(c[i])>=0||this._handlersAll.indexOf(c[i])>=0)&&(c[i].handler.call("scope"in c[i]?c[i].scope:this,h),c[i].once&&a.push(c[i]));for(s=0;se;e++)if(t._children[e]===r){t._children.splice(e,1);break}}),this._children.push(r),r},o.prototype.listeners=function(t){var e,n,i,o=[];if(t)for(o=r(this._handlers[t]),n=0,i=this._children.length;i>n;n++)o=o.concat(this._children[n].listeners(t));else{o=r(this._handlersAll);for(e in this._handlers)o=o.concat(r(this._handlers[e]));for(n=0,i=this._children.length;i>n;n++)o=o.concat(this._children[n].listeners())}return o},o.prototype.kill=function(){if(this.emit("emmett:kill"),this.unbindAll(),this._handlers=null,this._handlersAll=null,this._enabled=!1,this._children)for(var t=0,r=this._children.length;r>t;t++)this._children[t].kill();this._children=null},o.prototype.disable=function(){return this._enabled=!1,this},o.prototype.enable=function(){return this._enabled=!0,this},o.version="2.1.2","undefined"!=typeof n?("undefined"!=typeof e&&e.exports&&(n=e.exports=o),n.Emitter=o):"function"==typeof t&&t.amd?t("emmett",[],function(){return o}):this.Emitter=o}).call(this)},{}],4:[function(t,r){function e(t){return t+"$"+(new Date).getTime()+(""+Math.random()).replace("0.","")}function n(t,r){function e(t){this[t]=function(){var r=this.root[t].apply(this.root,arguments);return r instanceof i?this:r}}if(arguments.length<1&&(t={}),!(this instanceof n))return new n(t,r);if(!f.Object(t)&&!f.Array(t))throw Error("Baobab: invalid data.");o.call(this),this.options=a.shallowMerge(l,r),this._transaction={},this._future=void 0,this._cursors={},this.data=a.deepClone(t),this.root=this.select([]),["get","set","unset","update"].forEach(e.bind(this)),this.mixin=c.baobab(this)}var i=t("./cursor.js"),o=t("emmett"),s=t("./watcher.js"),a=t("./helpers.js"),h=t("./update.js"),u=t("./merge.js"),c=t("./mixins.js"),l=t("../defaults.js"),f=t("./type.js");a.inherits(n,o),n.prototype.select=function(t){if(!t)throw Error("Baobab.select: invalid path.");if(arguments.length>1&&(t=a.arrayOf(arguments)),!f.Path(t))throw Error("Baobab.select: invalid path.");t=[].concat(t);var r,n=f.ComplexPath(t);n&&(r=a.solvePath(this.data,t,this));var o=t.map(function(t){return f.Function(t)?e("fn"):f.Object(t)?e("ob"):t}).join("|λ|");if(this._cursors[o])return this._cursors[o];var s=new i(this,t,r,o);return this._cursors[o]=s,s},n.prototype.stack=function(t){var r=this;if(!f.Object(t))throw Error("Baobab.update: wrong specification.");return this._transaction=u(t,this._transaction),this.options.autoCommit?this.options.asynchronous?(this._future||(this._future=setTimeout(r.commit.bind(r,null),0)),this):this.commit():this},n.prototype.commit=function(){var t=h(this.data,this._transaction,this.options),r=this.data;return this.data=t.data,this._transaction={},this._future&&(this._future=clearTimeout(this._future)),this.emit("update",{log:t.log,previousState:r}),this},n.prototype.watch=function(t){if(!f.Array(t)||t.some(function(t){return!f.Path(t)}))throw Error("Baobab.watch: invalid paths.");return new s(this,[].concat(t))},n.prototype.release=function(){delete this.data,delete this._transaction;for(var t in this._cursors)this._cursors[t].release();delete this._cursors,this.kill()},n.prototype.toJSON=function(){return this.get()},r.exports=n},{"../defaults.js":2,"./cursor.js":5,"./helpers.js":6,"./merge.js":7,"./mixins.js":8,"./type.js":9,"./update.js":10,"./watcher.js":11,emmett:3}],5:[function(t,r){function e(t,r,e,n){function i(t){if(h.isRecording()&&!h.undoing){var r=a.getIn(t,h.solvedPath,h.tree),e=a.deepClone(r);h.archive.add(e)}return h.undoing=!1,h.emit("update")}var h=this;o.call(this),r=r||[],this.tree=t,this.path=r,this.hash=n,this.archive=null,this.undoing=!1,this.complexPath=!!e,this.solvedPath=this.complexPath?e:this.path,this.relevant=void 0!==this.get(),this.updateHandler=function(t){var r=t.data.log,e=t.data.previousState,n=!1;if(h.complexPath&&(h.solvedPath=a.solvePath(h.tree.data,h.path,h.tree)),!h.path.length)return i(e);h.solvedPath&&(n=a.solveUpdate(r,[h.solvedPath]));var o=void 0!==h.get();h.relevant?o&&n?i(e):o||(h.emit("irrelevant"),h.relevant=!1):o&&n&&(h.emit("relevant"),i(e),h.relevant=!0)},this.mixin=s.cursor(this);var u=!1;this._lazyBind=function(){u||(u=!0,h.tree.on("update",h.updateHandler))},this.on=a.before(this._lazyBind,this.on.bind(this)),this.once=a.before(this._lazyBind,this.once.bind(this)),this.complexPath&&this._lazyBind()}function n(t,r,e,n){if(arguments.length>5)throw Error("baobab.Cursor."+t+": too many arguments.");arguments.length<4&&(n=e,e=[]),e=e||[];var i=[].concat(e),o=a.solvePath(this.get(),i,this.tree);if(!o)throw Error("baobab.Cursor."+t+": could not solve dynamic path.");if(r){var s=this.get(o);if(!h[r](s))throw Error("baobab.Cursor."+t+": invalid target.")}var u={};u["$"+t]=n;var c=a.pathObject(o,u);return c}function i(t,r){e.prototype[t]=function(){var e=n.bind(this,t,r).apply(this,arguments);return this.update(e)}}var o=t("emmett"),s=t("./mixins.js"),a=t("./helpers.js"),h=(t("../defaults.js"),t("./type.js"));a.inherits(e,o),e.prototype.isRoot=function(){return!this.path.length},e.prototype.isLeaf=function(){return h.Primitive(this.get())},e.prototype.isBranch=function(){return!this.isLeaf()&&!this.isRoot()},e.prototype.root=function(){return this.tree.root()},e.prototype.select=function(t){if(arguments.length>1&&(t=a.arrayOf(arguments)),!h.Path(t))throw Error("baobab.Cursor.select: invalid path.");return this.tree.select(this.path.concat(t))},e.prototype.up=function(){return this.solvedPath&&this.solvedPath.length?this.tree.select(this.path.slice(0,-1)):null},e.prototype.left=function(){var t=+this.solvedPath[this.solvedPath.length-1];if(isNaN(t))throw Error("baobab.Cursor.left: cannot go left on a non-list type.");return t?this.tree.select(this.solvedPath.slice(0,-1).concat(t-1)):null},e.prototype.leftmost=function(){var t=+this.solvedPath[this.solvedPath.length-1];if(isNaN(t))throw Error("baobab.Cursor.leftmost: cannot go left on a non-list type.");return this.tree.select(this.solvedPath.slice(0,-1).concat(0))},e.prototype.right=function(){var t=+this.solvedPath[this.solvedPath.length-1];if(isNaN(t))throw Error("baobab.Cursor.right: cannot go right on a non-list type.");return t+1===this.up().get().length?null:this.tree.select(this.solvedPath.slice(0,-1).concat(t+1))},e.prototype.rightmost=function(){var t=+this.solvedPath[this.solvedPath.length-1];if(isNaN(t))throw Error("baobab.Cursor.right: cannot go right on a non-list type.");var r=this.up().get();return this.tree.select(this.solvedPath.slice(0,-1).concat(r.length-1))},e.prototype.down=function(){+this.solvedPath[this.solvedPath.length-1];return this.get()instanceof Array?this.tree.select(this.solvedPath.concat(0)):null},e.prototype.get=function(t){arguments.length>1&&(t=a.arrayOf(arguments));var r=this.solvedPath.concat((h.String(t)||h.Number(t)?[t]:t)||[]);return a.getIn(this.tree.data,r,this.tree)},i("set"),i("apply"),i("chain"),i("push","Array"),i("unshift","Array"),e.prototype.merge=function(t){if(!h.Object(t))throw Error("baobab.Cursor.merge: trying to merge a non-object.");var r=n.bind(this,"merge","Object").apply(this,arguments);return this.update(r)},e.prototype.unset=function(t){if(void 0===t&&this.isRoot())throw Error("baobab.Cursor.unset: cannot remove root node.");var r=n.bind(this,"unset",null).apply(this,[t,!0]);return this.update(r)},e.prototype.update=function(t,r){if(arguments.length<2)return this.tree.stack(a.pathObject(this.solvedPath,t)),this;var e=[].concat(t),n=a.solvePath(this.get(),e,this.tree);if(!n)throw Error("baobab.Cursor.update: could not solve dynamic path.");return this.tree.stack(a.pathObject(this.solvedPath.concat(n),r)),this},e.prototype.startRecording=function(t){if(t=t||5,1>t)throw Error("baobab.Cursor.startRecording: invalid maximum number of records.");return this.archive?this:(this._lazyBind(),this.archive=a.archive(t),this)},e.prototype.stopRecording=function(){return this.archive=null,this},e.prototype.undo=function(t){if(t=t||1,!this.isRecording())throw Error("baobab.Cursor.undo: cursor is not recording.");if(!h.PositiveInteger(t))throw Error("baobab.Cursor.undo: expecting a positive integer.");var r=this.archive.back(t);if(!r)throw Error("boabab.Cursor.undo: cannot find a relevant record ("+t+" back).");return this.undoing=!0,this.set(r)},e.prototype.isRecording=function(){return!!this.archive},e.prototype.hasHistory=function(){return!(!this.archive||!this.archive.get().length)},e.prototype.getHistory=function(){return this.archive?this.archive.get():[]},e.prototype.release=function(){this.tree.off("update",this.updateHandler),this.hash&&delete this.tree._cursors[this.hash],delete this.tree,delete this.path,delete this.solvedPath,delete this.archive,this.kill()},e.prototype.toJSON=function(){return this.get()},h.Cursor=function(t){return t instanceof e},r.exports=e},{"../defaults.js":2,"./helpers.js":6,"./mixins.js":8,"./type.js":9,emmett:3}],6:[function(t,r){(function(e){function n(t){return Array.prototype.slice.call(t)}function i(t,r){return function(){t(),r.apply(null,arguments)}}function o(t,r){var e,n={};for(e in t)n[e]=t[e];for(e in r)n[e]=r[e];return n}function s(t){var r=t.source,e="";return t.global&&(e+="g"),t.multiline&&(e+="m"),t.ignoreCase&&(e+="i"),t.sticky&&(e+="y"),t.unicode&&(e+="u"),new RegExp(r,e)}function a(t,r){if(!r||"object"!=typeof r||r instanceof Error||"ArrayBuffer"in e&&r instanceof ArrayBuffer)return r;if(j.Array(r)){if(t){var n,i,o=[];for(n=0,i=r.length;i>n;n++)o.push($(r[n]));return o}return r.slice(0)}if(j.Date(r))return new Date(r.getTime());if(r instanceof RegExp)return s(r);if(j.Object(r)){var a,h={};r.constructor&&r.constructor!==Object&&(h=Object.create(r.constructor.prototype));for(a in r)r.hasOwnProperty(a)&&(h[a]=t?$(r[a]):r[a]);return h}return r}function h(t,r){return function(e){return r(t(e))}}function u(t,r){var e,n;for(e=0,n=t.length;n>e;e++)if(r(t[e]))return t[e]}function c(t,r){var e,n;for(e=0,n=t.length;n>e;e++)if(r(t[e]))return e;return-1}function l(t,r){var e,n=!0;if(!t)return!1;for(e in r)if(j.Object(r[e]))n=n&&l(t[e],r[e]);else if(j.Array(r[e]))n=n&&!!~r[e].indexOf(t[e]);else if(t[e]!==r[e])return!1;return n}function f(t,r){return u(t,function(t){return l(t,r)})}function d(t,r){return c(t,function(t){return l(t,r)})}function y(t,r,e){r=r||[];var n,i,o,s=t;for(i=0,o=r.length;o>i;i++){if(!s)return;if("function"==typeof r[i]){if(!j.Array(s))return;s=u(s,r[i])}else if("object"==typeof r[i])if(e&&"$cursor"in r[i]){if(!j.Path(r[i].$cursor))throw Error("baobab.getIn: $cursor path must be an array.");n=e.get(r[i].$cursor),s=s[n]}else{if(!j.Array(s))return;s=f(s,r[i])}else s=s[r[i]]}return s}function g(t,r,e){var n,i,o,s=[],a=t;for(i=0,o=r.length;o>i;i++){if(!a)return null;if("function"==typeof r[i]){if(!j.Array(a))return;n=c(a,r[i]),s.push(n),a=a[n]}else if("object"==typeof r[i])if(e&&"$cursor"in r[i]){if(!j.Path(r[i].$cursor))throw Error("baobab.getIn: $cursor path must be an array.");p=e.get(r[i].$cursor),s.push(p),a=a[p]}else{if(!j.Array(a))return;n=d(a,r[i]),s.push(n),a=a[n]}else s.push(r[i]),a=a[r[i]]||{}}return s}function b(t,r){var e,n,i,o,s,a,h,u,c;for(e=0,o=r.length;o>e;e++)for(h=r[e],n=0,s=t.length;s>n;n++)for(u=t[n],i=0,a=u.length;a>i&&(c=u[i],c==h[i]);i++)if(i+1===a||i+1===h.length)return!0;return!1}function v(t,r){var e,n=t.length,i={},o=i;for(n||(i=r),e=0;n>e;e++)o[t[e]]=e+1===n?r:{},o=o[t[e]];return i}function m(t,r){t.super_=r;var e=function(){};e.prototype=r.prototype,t.prototype=new e,t.prototype.constructor=t}function _(t){var r=[];return{add:function(e){for(r.unshift(e);r.length>t;)r.pop()},back:function(t){var e=r[t-1];return e&&(r=r.slice(t)),e},get:function(){return r}}}var j=t("./type.js"),w=a.bind(null,!1),$=a.bind(null,!0);r.exports={archive:_,arrayOf:n,before:i,deepClone:$,shallowClone:w,shallowMerge:o,compose:h,getIn:y,inherits:m,pathObject:v,solvePath:g,solveUpdate:b}}).call(this,"undefined"!=typeof global?global:"undefined"!=typeof self?self:"undefined"!=typeof window?window:{})},{"./type.js":9}],7:[function(t,r){function e(t,r,e){s.forEach(function(r){e!==r&&delete t[r]}),t[e]=r[e]}function n(t,r){var a,h=i.shallowClone(r||{});s.forEach(function(r){t[r]&&e(h,t,r)}),t.$chain&&(s.slice(0,-1).forEach(function(t){delete h[t]}),h.$apply=h.$apply?i.compose(h.$apply,t.$chain):t.$chain),t.$push&&h.$push?h.$push=o.Array(h.$push)?h.$push.concat(t.$push):[h.$push].concat(t.$push):t.$push&&(h.$push=t.$push),t.$unshift&&h.$unshift?h.$unshift=o.Array(t.$unshift)?t.$unshift.concat(h.$unshift):[t.$unshift].concat(h.$unshift):t.$unshift&&(h.$unshift=t.$unshift);for(a in t)o.Object(t[a])?h[a]=n(t[a],h[a]):"$"!==a[0]&&(h[a]=t[a]);return h}var i=t("./helpers.js"),o=t("./type.js"),s=["$unset","$set","$merge","$apply"];r.exports=n},{"./helpers.js":6,"./type.js":9}],8:[function(t,r){var e=t("./type.js");r.exports={baobab:function(t){return{mixins:[{getInitialState:function(){if(this.tree=t,!this.cursor&&!this.cursors)return{};if(this.cursor&&this.cursors)throw Error("baobab.mixin: you cannot have both `component.cursor` and `component.cursors`. Please make up your mind.");if(this.__type=null,this.__updateHandler=function(){this.setState(this.__getCursorData())}.bind(this),this.cursor){if(!e.MixinCursor(this.cursor))throw Error("baobab.mixin.cursor: invalid data (cursor, string, array or function).");e.Function(this.cursor)&&(this.cursor=this.cursor()),e.Cursor(this.cursor)||(this.cursor=t.select(this.cursor)),this.__getCursorData=function(){return{cursor:this.cursor.get()}}.bind(this),this.__type="single"}else if(this.cursors){if(!e.MixinCursors(this.cursors))throw Error("baobab.mixin.cursor: invalid data (object, array or function).");if(e.Function(this.cursors)&&(this.cursors=this.cursors()),e.Array(this.cursors))this.cursors=this.cursors.map(function(r){return e.Cursor(r)?r:t.select(r)}),this.__getCursorData=function(){return{cursors:this.cursors.map(function(t){return t.get()})}}.bind(this),this.__type="array";else{for(var r in this.cursors)e.Cursor(this.cursors[r])||(this.cursors[r]=t.select(this.cursors[r]));this.__getCursorData=function(){var t={};for(r in this.cursors)t[r]=this.cursors[r].get();return{cursors:t}}.bind(this),this.__type="object"}}return this.__getCursorData()},componentDidMount:function(){"single"===this.__type?(this.__watcher=this.tree.watch([this.cursor.path]),this.__watcher.on("update",this.__updateHandler)):"array"===this.__type?(this.__watcher=this.tree.watch(this.cursors.map(function(t){return t.path})),this.__watcher.on("update",this.__updateHandler)):"object"===this.__type&&(this.__watcher=this.tree.watch(Object.keys(this.cursors).map(function(t){return this.cursors[t].path},this)),this.__watcher.on("update",this.__updateHandler))},componentWillUnmount:function(){this.__watcher&&this.__watcher.release()}}].concat(t.options.mixins)}},cursor:function(t){return{mixins:[{getInitialState:function(){return this.cursor=t,this.__updateHandler=function(){this.setState({cursor:this.cursor.get()})}.bind(this),{cursor:this.cursor.get()}},componentDidMount:function(){this.cursor.on("update",this.__updateHandler)},componentWillUnmount:function(){this.cursor.off("update",this.__updateHandler)}}].concat(t.tree.options.mixins)}}}},{"./type.js":9}],9:[function(t,r){function e(t,r){return r.some(function(r){return n[r](t)})}var n={};n.Array=function(t){return Array.isArray(t)},n.Object=function(t){return!Array.isArray(t)&&"object"==typeof t&&null!==t},n.String=function(t){return"string"==typeof t},n.Number=function(t){return"number"==typeof t},n.PositiveInteger=function(t){return"number"==typeof t&&t>0&&!(t%1)},n.Function=function(t){return"function"==typeof t},n.Primitive=function(t){return"string"==typeof t||"number"==typeof t||"boolean"==typeof t},n.Date=function(t){return t instanceof Date},n.NonScalar=function(t){return n.Object(t)||n.Array(t)},n.Path=function(t){var r=["String","Number","Function","Object"];return n.Array(t)?t.every(function(t){return e(t,r)}):e(t,r)},n.MixinCursor=function(t){return e(t,["String","Number","Array","Function","Cursor"])},n.MixinCursors=function(t){return e(t,["Object","Array","Function"])},n.ComplexPath=function(t){return t.some(function(t){return e(t,["Object","Function"])})},r.exports=n},{}],10:[function(t,r){function e(t,r){var e=new Error("baobab.update: "+r+" at path /"+t.slice(1).join("/"));return e.path=t,e}var n=t("./helpers.js"),i=t("./type.js");r.exports=function(t,r,o){if(o=o||{},!i.Object(t)&&!i.Array(t))throw Error("baobab.update: invalid target.");var s={};t={root:n.shallowClone(t)};var a=function(t,r,o,h){o=o||["root"];var u,c,l,f=o.join("|λ|"),p=o[o.length-1],d=Object.keys(r).some(function(t){return!!~["$unset","$set","$apply","$merge","$push","$unshift"].indexOf(t)});if(d){s[f]=!0;for(c in r){if("$unset"===c){var y=o[o.length-2];i.Array(t)?h[y]=t.slice(0,+p).concat(t.slice(+p+1)):(h[y]=n.shallowClone(t),delete h[y][p]);break}if("$set"===c){l=r.$set,t[p]=l;break}if("$apply"===c){if(u=r.$apply,"function"!=typeof u)throw e(o,"using command $apply with a non function");t[p]=u.call(null,t[p]);break}if("$merge"===c){if(l=r.$merge,!i.Object(t[p])||!i.Object(l))throw e(o,"using command $merge with a non object");t[p]=n.shallowMerge(t[p],l);break}if("$push"===c){if(l=r.$push,!i.Array(t[p]))throw e(o,"using command $push to a non array");t[p]=t[p].concat(l)}if("$unshift"===c){if(l=r.$unshift,!i.Array(t[p]))throw e(o,"using command $unshift to a non array");t[p]=[].concat(l).concat(t[p])}}}else for(c in r)t[p][c]="undefined"==typeof t[p][c]?{}:n.shallowClone(t[p][c]),a(t[p],r[c],o.concat(c),t)};return a(t,r),{data:t.root,log:Object.keys(s).map(function(t){return t.split("|λ|").slice(1)})}}},{"./helpers.js":6,"./type.js":9}],11:[function(t,r){function e(t,r){function e(){h&&(a=r.map(function(t){return i.solvePath(s.tree.data,t,s.tree)}))}var s=this;n.call(this),this.tree=t;var a=r,h=r.some(o.ComplexPath);this.updateHandler=function(t){var r=i.solveUpdate(t.data.log,a);r&&s.emit("update")},e(),this.tree.on("update",this.updateHandler)}var n=t("emmett"),i=t("./helpers.js"),o=t("./type.js");i.inherits(e,n),e.prototype.release=function(){this.tree.off("update",this.updateHandler),this.tree=null,this.kill()},r.exports=e},{"./helpers.js":6,"./type.js":9,emmett:3}]},{},[1])(1)}); \ No newline at end of file +!function(t){if("object"==typeof exports&&"undefined"!=typeof module)module.exports=t();else if("function"==typeof define&&define.amd)define([],t);else{var r;r="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:this,r.Baobab=t()}}(function(){var t;return function r(t,e,n){function i(s,a){if(!e[s]){if(!t[s]){var h="function"==typeof require&&require;if(!a&&h)return h(s,!0);if(o)return o(s,!0);var u=new Error("Cannot find module '"+s+"'");throw u.code="MODULE_NOT_FOUND",u}var c=e[s]={exports:{}};t[s][0].call(c.exports,function(r){var e=t[s][1][r];return i(e?e:r)},c,c.exports,r,t,e,n)}return e[s].exports}for(var o="function"==typeof require&&require,s=0;sr;r++)n.push(t[r].handler);return n}var i={once:"boolean",scope:"object"},o=function(){this._enabled=!0,this._children=[],this._handlers={},this._handlersAll=[]};o.prototype.on=function(t,r,e){var n,s,a,h,u,c;if("function"==typeof r){for(u="string"==typeof t?[t]:t,n=0,s=u.length;n!==s;n+=1)if(h=u[n]){this._handlers[h]||(this._handlers[h]=[]),c={handler:r};for(a in e||{}){if(!i[a])throw new Error('The option "'+a+'" is not recognized by Emmett.');c[a]=e[a]}this._handlers[h].push(c)}}else if(t&&"object"==typeof t&&!Array.isArray(t))for(h in t)o.prototype.on.call(this,h,t[h],r);else{if("function"!=typeof t)throw new Error("Wrong arguments.");c={handler:t};for(a in e||{}){if(!i[a])throw new Error('The option "'+a+'" is not recognized by Emmett.');c[a]=e[a]}this._handlersAll.push(c)}return this},o.prototype.once=function(t,r,e){if("function"==typeof r)e=e||{},e.once=!0,this.on(t,r,e);else{if((!t||"object"!=typeof t||Array.isArray(t))&&"function"!=typeof t)throw new Error("Wrong arguments.");r=r||{},r.once=!0,this.on(t,r)}return this},o.prototype.off=function(t,r){var e,n,i,o,s,a,h,u="string"==typeof t?[t]:t;if(1===arguments.length&&"function"==typeof u){r=arguments[0];for(s in this._handlers){for(a=[],e=0,n=this._handlers[s].length;e!==n;e+=1)this._handlers[s][e].handler!==r&&a.push(this._handlers[s][e]);this._handlers[s]=a}for(a=[],e=0,n=this._handlersAll.length;e!==n;e+=1)this._handlersAll[e].handler!==r&&a.push(this._handlersAll[e]);this._handlersAll=a}else if(2===arguments.length)for(e=0,n=u.length;e!==n;e+=1){if(h=u[e],this._handlers[h]){for(a=[],i=0,o=this._handlers[h].length;i!==o;i+=1)this._handlers[h][i].handler!==r&&a.push(this._handlers[h][i]);this._handlers[h]=a}this._handlers[h]&&0===this._handlers[h].length&&delete this._handlers[h]}return this},o.prototype.unbindAll=function(){var t;this._handlersAll=[];for(t in this._handlers)delete this._handlers[t];return this},o.prototype.emit=function(t,r){var e,n,i,o,s,a,h,u,c,l,f="string"==typeof t?[t]:t;if(!this._enabled)return this;for(r=void 0===r?{}:r,e=0,n=f.length;e!==n;e+=1)if(l=f[e],c=(this._handlers[l]||[]).concat(this._handlersAll),c.length){for(h={type:l,data:r||{},target:this},a=[],i=0,o=c.length;i!==o;i+=1)(this._handlers[l]&&this._handlers[l].indexOf(c[i])>=0||this._handlersAll.indexOf(c[i])>=0)&&(c[i].handler.call("scope"in c[i]?c[i].scope:this,h),c[i].once&&a.push(c[i]));for(s=0;se;e++)if(t._children[e]===r){t._children.splice(e,1);break}}),this._children.push(r),r},o.prototype.listeners=function(t){var e,n,i,o=[];if(t)for(o=r(this._handlers[t]),n=0,i=this._children.length;i>n;n++)o=o.concat(this._children[n].listeners(t));else{o=r(this._handlersAll);for(e in this._handlers)o=o.concat(r(this._handlers[e]));for(n=0,i=this._children.length;i>n;n++)o=o.concat(this._children[n].listeners())}return o},o.prototype.kill=function(){if(this.emit("emmett:kill"),this.unbindAll(),this._handlers=null,this._handlersAll=null,this._enabled=!1,this._children)for(var t=0,r=this._children.length;r>t;t++)this._children[t].kill();this._children=null},o.prototype.disable=function(){return this._enabled=!1,this},o.prototype.enable=function(){return this._enabled=!0,this},o.version="2.1.2","undefined"!=typeof n?("undefined"!=typeof e&&e.exports&&(n=e.exports=o),n.Emitter=o):"function"==typeof t&&t.amd?t("emmett",[],function(){return o}):this.Emitter=o}).call(this)},{}],4:[function(t,r){function e(t){return t+"$"+(new Date).getTime()+(""+Math.random()).replace("0.","")}function n(t,r){function e(t){this[t]=function(){var r=this.root[t].apply(this.root,arguments);return r instanceof i?this:r}}if(arguments.length<1&&(t={}),!(this instanceof n))return new n(t,r);if(!f.Object(t)&&!f.Array(t))throw Error("Baobab: invalid data.");o.call(this),this.options=a.shallowMerge(l,r),this._transaction={},this._future=void 0,this._cursors={},this.data=a.deepClone(t),this.root=this.select([]),["get","set","unset","update"].forEach(e.bind(this)),this.mixin=c.baobab(this)}var i=t("./cursor.js"),o=t("emmett"),s=t("./watcher.js"),a=t("./helpers.js"),h=t("./update.js"),u=t("./merge.js"),c=t("./mixins.js"),l=t("../defaults.js"),f=t("./type.js");a.inherits(n,o),n.prototype.select=function(t){if(!t)throw Error("Baobab.select: invalid path.");if(arguments.length>1&&(t=a.arrayOf(arguments)),!f.Path(t))throw Error("Baobab.select: invalid path.");t=[].concat(t);var r,n=f.ComplexPath(t);n&&(r=a.solvePath(this.data,t,this));var o=t.map(function(t){return f.Function(t)?e("fn"):f.Object(t)?e("ob"):t}).join("|λ|");if(this._cursors[o])return this._cursors[o];var s=new i(this,t,r,o);return this._cursors[o]=s,s},n.prototype.stack=function(t){var r=this;if(!f.Object(t))throw Error("Baobab.update: wrong specification.");return this._transaction=u(t,this._transaction),this.options.autoCommit?this.options.asynchronous?(this._future||(this._future=setTimeout(r.commit.bind(r,null),0)),this):this.commit():this},n.prototype.commit=function(){var t=h(this.data,this._transaction,this.options),r=this.data;return this.data=t.data,this._transaction={},this._future&&(this._future=clearTimeout(this._future)),this.emit("update",{log:t.log,previousState:r}),this},n.prototype.watch=function(t){if(!f.Array(t)||t.some(function(t){return!f.Path(t)}))throw Error("Baobab.watch: invalid paths.");return new s(this,[].concat(t))},n.prototype.release=function(){delete this.data,delete this._transaction;for(var t in this._cursors)this._cursors[t].release();delete this._cursors,this.kill()},n.prototype.toJSON=function(){return this.get()},r.exports=n},{"../defaults.js":2,"./cursor.js":5,"./helpers.js":6,"./merge.js":7,"./mixins.js":8,"./type.js":9,"./update.js":10,"./watcher.js":11,emmett:3}],5:[function(t,r){function e(t,r,e,n){function i(t){if(h.isRecording()&&!h.undoing){var r=a.getIn(t,h.solvedPath,h.tree),e=a.deepClone(r);h.archive.add(e)}return h.undoing=!1,h.emit("update")}var h=this;o.call(this),r=r||[],this.tree=t,this.path=r,this.hash=n,this.archive=null,this.undoing=!1,this.complexPath=!!e,this.solvedPath=this.complexPath?e:this.path,this.relevant=void 0!==this.get(),this.updateHandler=function(t){var r=t.data.log,e=t.data.previousState,n=!1;if(h.complexPath&&(h.solvedPath=a.solvePath(h.tree.data,h.path,h.tree)),!h.path.length)return i(e);h.solvedPath&&(n=a.solveUpdate(r,[h.solvedPath]));var o=void 0!==h.get();h.relevant?o&&n?i(e):o||(h.emit("irrelevant"),h.relevant=!1):o&&n&&(h.emit("relevant"),i(e),h.relevant=!0)},this.mixin=s.cursor(this);var u=!1;this._lazyBind=function(){u||(u=!0,h.tree.on("update",h.updateHandler))},this.on=a.before(this._lazyBind,this.on.bind(this)),this.once=a.before(this._lazyBind,this.once.bind(this)),this.complexPath&&this._lazyBind()}function n(t,r,e,n){if(arguments.length>5)throw Error("baobab.Cursor."+t+": too many arguments.");arguments.length<4&&(n=e,e=[]),e=e||[];var i=[].concat(e),o=a.solvePath(this.get(),i,this.tree);if(!o)throw Error("baobab.Cursor."+t+": could not solve dynamic path.");if(r){var s=this.get(o);if(!h[r](s))throw Error("baobab.Cursor."+t+": invalid target.")}var u={};u["$"+t]=n;var c=a.pathObject(o,u);return c}function i(t,r){e.prototype[t]=function(){var e=n.bind(this,t,r).apply(this,arguments);return this.update(e)}}var o=t("emmett"),s=t("./mixins.js"),a=t("./helpers.js"),h=(t("../defaults.js"),t("./type.js"));a.inherits(e,o),e.prototype.isRoot=function(){return!this.path.length},e.prototype.isLeaf=function(){return h.Primitive(this.get())},e.prototype.isBranch=function(){return!this.isLeaf()&&!this.isRoot()},e.prototype.root=function(){return this.tree.root()},e.prototype.select=function(t){if(arguments.length>1&&(t=a.arrayOf(arguments)),!h.Path(t))throw Error("baobab.Cursor.select: invalid path.");return this.tree.select(this.path.concat(t))},e.prototype.up=function(){return this.solvedPath&&this.solvedPath.length?this.tree.select(this.path.slice(0,-1)):null},e.prototype.left=function(){var t=+this.solvedPath[this.solvedPath.length-1];if(isNaN(t))throw Error("baobab.Cursor.left: cannot go left on a non-list type.");return t?this.tree.select(this.solvedPath.slice(0,-1).concat(t-1)):null},e.prototype.leftmost=function(){var t=+this.solvedPath[this.solvedPath.length-1];if(isNaN(t))throw Error("baobab.Cursor.leftmost: cannot go left on a non-list type.");return this.tree.select(this.solvedPath.slice(0,-1).concat(0))},e.prototype.right=function(){var t=+this.solvedPath[this.solvedPath.length-1];if(isNaN(t))throw Error("baobab.Cursor.right: cannot go right on a non-list type.");return t+1===this.up().get().length?null:this.tree.select(this.solvedPath.slice(0,-1).concat(t+1))},e.prototype.rightmost=function(){var t=+this.solvedPath[this.solvedPath.length-1];if(isNaN(t))throw Error("baobab.Cursor.right: cannot go right on a non-list type.");var r=this.up().get();return this.tree.select(this.solvedPath.slice(0,-1).concat(r.length-1))},e.prototype.down=function(){+this.solvedPath[this.solvedPath.length-1];return this.get()instanceof Array?this.tree.select(this.solvedPath.concat(0)):null},e.prototype.get=function(t){arguments.length>1&&(t=a.arrayOf(arguments));var r=this.solvedPath.concat((h.String(t)||h.Number(t)?[t]:t)||[]);return a.getIn(this.tree.data,r,this.tree)},i("set"),i("apply"),i("chain"),i("push","Array"),i("unshift","Array"),e.prototype.merge=function(t){if(!h.Object(t))throw Error("baobab.Cursor.merge: trying to merge a non-object.");var r=n.bind(this,"merge","Object").apply(this,arguments);return this.update(r)},e.prototype.unset=function(t){if(void 0===t&&this.isRoot())throw Error("baobab.Cursor.unset: cannot remove root node.");var r=n.bind(this,"unset",null).apply(this,[t,!0]);return this.update(r)},e.prototype.update=function(t,r){if(arguments.length<2)return this.tree.stack(a.pathObject(this.solvedPath,t)),this;var e=[].concat(t),n=a.solvePath(this.get(),e,this.tree);if(!n)throw Error("baobab.Cursor.update: could not solve dynamic path.");return this.tree.stack(a.pathObject(this.solvedPath.concat(n),r)),this},e.prototype.startRecording=function(t){if(t=t||5,1>t)throw Error("baobab.Cursor.startRecording: invalid maximum number of records.");return this.archive?this:(this._lazyBind(),this.archive=a.archive(t),this)},e.prototype.stopRecording=function(){return this.archive=null,this},e.prototype.undo=function(t){if(t=t||1,!this.isRecording())throw Error("baobab.Cursor.undo: cursor is not recording.");if(!h.PositiveInteger(t))throw Error("baobab.Cursor.undo: expecting a positive integer.");var r=this.archive.back(t);if(!r)throw Error("boabab.Cursor.undo: cannot find a relevant record ("+t+" back).");return this.undoing=!0,this.set(r)},e.prototype.isRecording=function(){return!!this.archive},e.prototype.hasHistory=function(){return!(!this.archive||!this.archive.get().length)},e.prototype.getHistory=function(){return this.archive?this.archive.get():[]},e.prototype.release=function(){this.tree.off("update",this.updateHandler),this.hash&&delete this.tree._cursors[this.hash],delete this.tree,delete this.path,delete this.solvedPath,delete this.archive,this.kill()},e.prototype.toJSON=function(){return this.get()},h.Cursor=function(t){return t instanceof e},r.exports=e},{"../defaults.js":2,"./helpers.js":6,"./mixins.js":8,"./type.js":9,emmett:3}],6:[function(t,r){(function(e){function n(t){return Array.prototype.slice.call(t)}function i(t,r){return function(){t(),r.apply(null,arguments)}}function o(t,r){var e,n={};for(e in t)n[e]=t[e];for(e in r)n[e]=r[e];return n}function s(t){var r=t.source,e="";return t.global&&(e+="g"),t.multiline&&(e+="m"),t.ignoreCase&&(e+="i"),t.sticky&&(e+="y"),t.unicode&&(e+="u"),new RegExp(r,e)}function a(t,r){if(!r||"object"!=typeof r||r instanceof Error||"ArrayBuffer"in e&&r instanceof ArrayBuffer)return r;if(j.Array(r)){if(t){var n,i,o=[];for(n=0,i=r.length;i>n;n++)o.push($(r[n]));return o}return r.slice(0)}if(j.Date(r))return new Date(r.getTime());if(r instanceof RegExp)return s(r);if(j.Object(r)){var a,h={};r.constructor&&r.constructor!==Object&&(h=Object.create(r.constructor.prototype));for(a in r)r.hasOwnProperty(a)&&(h[a]=t?$(r[a]):r[a]);return h}return r}function h(t,r){return function(e){return r(t(e))}}function u(t,r){var e,n;for(e=0,n=t.length;n>e;e++)if(r(t[e]))return t[e]}function c(t,r){var e,n;for(e=0,n=t.length;n>e;e++)if(r(t[e]))return e;return-1}function l(t,r){var e,n=!0;if(!t)return!1;for(e in r)if(j.Object(r[e]))n=n&&l(t[e],r[e]);else if(j.Array(r[e]))n=n&&!!~r[e].indexOf(t[e]);else if(t[e]!==r[e])return!1;return n}function f(t,r){return u(t,function(t){return l(t,r)})}function d(t,r){return c(t,function(t){return l(t,r)})}function y(t,r,e){r=r||[];var n,i,o,s=t;for(i=0,o=r.length;o>i;i++){if(!s)return;if("function"==typeof r[i]){if(!j.Array(s))return;s=u(s,r[i])}else if("object"==typeof r[i])if(e&&"$cursor"in r[i]){if(!j.Path(r[i].$cursor))throw Error("baobab.getIn: $cursor path must be an array.");n=e.get(r[i].$cursor),s=s[n]}else{if(!j.Array(s))return;s=f(s,r[i])}else s=s[r[i]]}return s}function g(t,r,e){var n,i,o,s=[],a=t;for(i=0,o=r.length;o>i;i++){if(!a)return null;if("function"==typeof r[i]){if(!j.Array(a))return;n=c(a,r[i]),s.push(n),a=a[n]}else if("object"==typeof r[i])if(e&&"$cursor"in r[i]){if(!j.Path(r[i].$cursor))throw Error("baobab.getIn: $cursor path must be an array.");p=e.get(r[i].$cursor),s.push(p),a=a[p]}else{if(!j.Array(a))return;n=d(a,r[i]),s.push(n),a=a[n]}else s.push(r[i]),a=a[r[i]]||{}}return s}function b(t,r){var e,n,i,o,s,a,h,u,c;for(e=0,o=r.length;o>e;e++)for(h=r[e],n=0,s=t.length;s>n;n++)for(u=t[n],i=0,a=u.length;a>i&&(c=u[i],c==h[i]);i++)if(i+1===a||i+1===h.length)return!0;return!1}function v(t,r){var e,n=t.length,i={},o=i;for(n||(i=r),e=0;n>e;e++)o[t[e]]=e+1===n?r:{},o=o[t[e]];return i}function m(t,r){t.super_=r;var e=function(){};e.prototype=r.prototype,t.prototype=new e,t.prototype.constructor=t}function _(t){var r=[];return{add:function(e){for(r.unshift(e);r.length>t;)r.pop()},back:function(t){var e=r[t-1];return e&&(r=r.slice(t)),e},get:function(){return r}}}var j=t("./type.js"),w=a.bind(null,!1),$=a.bind(null,!0);r.exports={archive:_,arrayOf:n,before:i,deepClone:$,shallowClone:w,shallowMerge:o,compose:h,getIn:y,inherits:m,pathObject:v,solvePath:g,solveUpdate:b}}).call(this,"undefined"!=typeof global?global:"undefined"!=typeof self?self:"undefined"!=typeof window?window:{})},{"./type.js":9}],7:[function(t,r){function e(t,r,e){s.forEach(function(r){e!==r&&delete t[r]}),t[e]=r[e]}function n(t,r){var a,h=i.shallowClone(r||{});s.forEach(function(r){t[r]&&e(h,t,r)}),t.$chain&&(s.slice(0,-1).forEach(function(t){delete h[t]}),h.$apply=h.$apply?i.compose(h.$apply,t.$chain):t.$chain),t.$push&&h.$push?h.$push=o.Array(h.$push)?h.$push.concat(t.$push):[h.$push].concat(t.$push):t.$push&&(h.$push=t.$push),t.$unshift&&h.$unshift?h.$unshift=o.Array(t.$unshift)?t.$unshift.concat(h.$unshift):[t.$unshift].concat(h.$unshift):t.$unshift&&(h.$unshift=t.$unshift);for(a in t)o.Object(t[a])?h[a]=n(t[a],h[a]):"$"!==a[0]&&(h[a]=t[a]);return h}var i=t("./helpers.js"),o=t("./type.js"),s=["$unset","$set","$merge","$apply"];r.exports=n},{"./helpers.js":6,"./type.js":9}],8:[function(t,r){var e=t("./type.js");r.exports={baobab:function(t){return{mixins:[{getInitialState:function(){if(this.tree=t,!this.cursor&&!this.cursors)return{};if(this.cursor&&this.cursors)throw Error("baobab.mixin: you cannot have both `component.cursor` and `component.cursors`. Please make up your mind.");if(this.__type=null,this.__updateHandler=function(){this.setState(this.__getCursorData())}.bind(this),this.cursor){if(!e.MixinCursor(this.cursor))throw Error("baobab.mixin.cursor: invalid data (cursor, string, array or function).");e.Function(this.cursor)&&(this.cursor=this.cursor()),e.Cursor(this.cursor)||(this.cursor=t.select(this.cursor)),this.__getCursorData=function(){return{cursor:this.cursor.get()}}.bind(this),this.__type="single"}else if(this.cursors){if(!e.MixinCursors(this.cursors))throw Error("baobab.mixin.cursor: invalid data (object, array or function).");if(e.Function(this.cursors)&&(this.cursors=this.cursors()),e.Array(this.cursors))this.cursors=this.cursors.map(function(r){return e.Cursor(r)?r:t.select(r)}),this.__getCursorData=function(){return{cursors:this.cursors.map(function(t){return t.get()})}}.bind(this),this.__type="array";else{for(var r in this.cursors)e.Cursor(this.cursors[r])||(this.cursors[r]=t.select(this.cursors[r]));this.__getCursorData=function(){var t={};for(r in this.cursors)t[r]=this.cursors[r].get();return{cursors:t}}.bind(this),this.__type="object"}}return this.__getCursorData()},componentDidMount:function(){"single"===this.__type?(this.__watcher=this.tree.watch([this.cursor.path]),this.__watcher.on("update",this.__updateHandler)):"array"===this.__type?(this.__watcher=this.tree.watch(this.cursors.map(function(t){return t.path})),this.__watcher.on("update",this.__updateHandler)):"object"===this.__type&&(this.__watcher=this.tree.watch(Object.keys(this.cursors).map(function(t){return this.cursors[t].path},this)),this.__watcher.on("update",this.__updateHandler))},componentWillUnmount:function(){this.__watcher&&this.__watcher.release()}}].concat(t.options.mixins)}},cursor:function(t){return{mixins:[{getInitialState:function(){return this.cursor=t,this.__updateHandler=function(){this.setState({cursor:this.cursor.get()})}.bind(this),{cursor:this.cursor.get()}},componentDidMount:function(){this.cursor.on("update",this.__updateHandler)},componentWillUnmount:function(){this.cursor.off("update",this.__updateHandler)}}].concat(t.tree.options.mixins)}}}},{"./type.js":9}],9:[function(t,r){function e(t,r){return r.some(function(r){return n[r](t)})}var n={};n.Array=function(t){return Array.isArray(t)},n.Object=function(t){return t&&"object"==typeof t&&!Array.isArray(t)&&!(t instanceof Function)},n.String=function(t){return"string"==typeof t},n.Number=function(t){return"number"==typeof t},n.PositiveInteger=function(t){return"number"==typeof t&&t>0&&!(t%1)},n.Function=function(t){return"function"==typeof t},n.Primitive=function(t){return"string"==typeof t||"number"==typeof t||"boolean"==typeof t},n.Date=function(t){return t instanceof Date},n.NonScalar=function(t){return n.Object(t)||n.Array(t)},n.Path=function(t){var r=["String","Number","Function","Object"];return n.Array(t)?t.every(function(t){return e(t,r)}):e(t,r)},n.MixinCursor=function(t){return e(t,["String","Number","Array","Function","Cursor"])},n.MixinCursors=function(t){return e(t,["Object","Array","Function"])},n.ComplexPath=function(t){return t.some(function(t){return e(t,["Object","Function"])})},r.exports=n},{}],10:[function(t,r){function e(t,r){var e=new Error("baobab.update: "+r+" at path /"+t.slice(1).join("/"));return e.path=t,e}var n=t("./helpers.js"),i=t("./type.js");r.exports=function(t,r,o){if(o=o||{},!i.Object(t)&&!i.Array(t))throw Error("baobab.update: invalid target.");var s={};t={root:n.shallowClone(t)};var a=function(t,r,o,h){o=o||["root"];var u,c,l,f=o.join("|λ|"),p=o[o.length-1],d=Object.keys(r).some(function(t){return!!~["$unset","$set","$apply","$merge","$push","$unshift"].indexOf(t)});if(d){s[f]=!0;for(c in r){if("$unset"===c){var y=o[o.length-2];i.Array(t)?h[y]=t.slice(0,+p).concat(t.slice(+p+1)):(h[y]=n.shallowClone(t),delete h[y][p]);break}if("$set"===c){l=r.$set,t[p]=l;break}if("$apply"===c){if(u=r.$apply,"function"!=typeof u)throw e(o,"using command $apply with a non function");t[p]=u.call(null,t[p]);break}if("$merge"===c){if(l=r.$merge,!i.Object(t[p])||!i.Object(l))throw e(o,"using command $merge with a non object");t[p]=n.shallowMerge(t[p],l);break}if("$push"===c){if(l=r.$push,!i.Array(t[p]))throw e(o,"using command $push to a non array");t[p]=t[p].concat(l)}if("$unshift"===c){if(l=r.$unshift,!i.Array(t[p]))throw e(o,"using command $unshift to a non array");t[p]=[].concat(l).concat(t[p])}}}else for(c in r)t[p][c]="undefined"==typeof t[p][c]?{}:n.shallowClone(t[p][c]),a(t[p],r[c],o.concat(c),t)};return a(t,r),{data:t.root,log:Object.keys(s).map(function(t){return t.split("|λ|").slice(1)})}}},{"./helpers.js":6,"./type.js":9}],11:[function(t,r){function e(t,r){function e(){h&&(a=r.map(function(t){return i.solvePath(s.tree.data,t,s.tree)}))}var s=this;n.call(this),this.tree=t;var a=r,h=r.some(o.ComplexPath);this.updateHandler=function(t){var r=i.solveUpdate(t.data.log,a);r&&s.emit("update")},e(),this.tree.on("update",this.updateHandler)}var n=t("emmett"),i=t("./helpers.js"),o=t("./type.js");i.inherits(e,n),e.prototype.release=function(){this.tree.off("update",this.updateHandler),this.tree=null,this.kill()},r.exports=e},{"./helpers.js":6,"./type.js":9,emmett:3}]},{},[1])(1)}); \ No newline at end of file diff --git a/src/type.js b/src/type.js index 52084bb..fc37f57 100644 --- a/src/type.js +++ b/src/type.js @@ -26,7 +26,10 @@ type.Array = function(value) { }; type.Object = function(value) { - return !Array.isArray(value) && typeof value === 'object' && value !== null; + return value && + typeof value === 'object' && + !Array.isArray(value) && + !(value instanceof Function); }; type.String = function(value) { From 6963f7f6a7bf1eca84493308950274c9ec3a11e5 Mon Sep 17 00:00:00 2001 From: Yomguithereal Date: Mon, 13 Apr 2015 16:41:03 +0200 Subject: [PATCH 44/73] Updating emmett to 3.0.0 --- build/baobab.min.js | 2 +- package.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/build/baobab.min.js b/build/baobab.min.js index 375523a..3a68def 100644 --- a/build/baobab.min.js +++ b/build/baobab.min.js @@ -1,2 +1,2 @@ /* baobab.js - Version: 1.0.0-rc1 - Author: Yomguithereal (Guillaume Plique) */ -!function(t){if("object"==typeof exports&&"undefined"!=typeof module)module.exports=t();else if("function"==typeof define&&define.amd)define([],t);else{var r;r="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:this,r.Baobab=t()}}(function(){var t;return function r(t,e,n){function i(s,a){if(!e[s]){if(!t[s]){var h="function"==typeof require&&require;if(!a&&h)return h(s,!0);if(o)return o(s,!0);var u=new Error("Cannot find module '"+s+"'");throw u.code="MODULE_NOT_FOUND",u}var c=e[s]={exports:{}};t[s][0].call(c.exports,function(r){var e=t[s][1][r];return i(e?e:r)},c,c.exports,r,t,e,n)}return e[s].exports}for(var o="function"==typeof require&&require,s=0;sr;r++)n.push(t[r].handler);return n}var i={once:"boolean",scope:"object"},o=function(){this._enabled=!0,this._children=[],this._handlers={},this._handlersAll=[]};o.prototype.on=function(t,r,e){var n,s,a,h,u,c;if("function"==typeof r){for(u="string"==typeof t?[t]:t,n=0,s=u.length;n!==s;n+=1)if(h=u[n]){this._handlers[h]||(this._handlers[h]=[]),c={handler:r};for(a in e||{}){if(!i[a])throw new Error('The option "'+a+'" is not recognized by Emmett.');c[a]=e[a]}this._handlers[h].push(c)}}else if(t&&"object"==typeof t&&!Array.isArray(t))for(h in t)o.prototype.on.call(this,h,t[h],r);else{if("function"!=typeof t)throw new Error("Wrong arguments.");c={handler:t};for(a in e||{}){if(!i[a])throw new Error('The option "'+a+'" is not recognized by Emmett.');c[a]=e[a]}this._handlersAll.push(c)}return this},o.prototype.once=function(t,r,e){if("function"==typeof r)e=e||{},e.once=!0,this.on(t,r,e);else{if((!t||"object"!=typeof t||Array.isArray(t))&&"function"!=typeof t)throw new Error("Wrong arguments.");r=r||{},r.once=!0,this.on(t,r)}return this},o.prototype.off=function(t,r){var e,n,i,o,s,a,h,u="string"==typeof t?[t]:t;if(1===arguments.length&&"function"==typeof u){r=arguments[0];for(s in this._handlers){for(a=[],e=0,n=this._handlers[s].length;e!==n;e+=1)this._handlers[s][e].handler!==r&&a.push(this._handlers[s][e]);this._handlers[s]=a}for(a=[],e=0,n=this._handlersAll.length;e!==n;e+=1)this._handlersAll[e].handler!==r&&a.push(this._handlersAll[e]);this._handlersAll=a}else if(2===arguments.length)for(e=0,n=u.length;e!==n;e+=1){if(h=u[e],this._handlers[h]){for(a=[],i=0,o=this._handlers[h].length;i!==o;i+=1)this._handlers[h][i].handler!==r&&a.push(this._handlers[h][i]);this._handlers[h]=a}this._handlers[h]&&0===this._handlers[h].length&&delete this._handlers[h]}return this},o.prototype.unbindAll=function(){var t;this._handlersAll=[];for(t in this._handlers)delete this._handlers[t];return this},o.prototype.emit=function(t,r){var e,n,i,o,s,a,h,u,c,l,f="string"==typeof t?[t]:t;if(!this._enabled)return this;for(r=void 0===r?{}:r,e=0,n=f.length;e!==n;e+=1)if(l=f[e],c=(this._handlers[l]||[]).concat(this._handlersAll),c.length){for(h={type:l,data:r||{},target:this},a=[],i=0,o=c.length;i!==o;i+=1)(this._handlers[l]&&this._handlers[l].indexOf(c[i])>=0||this._handlersAll.indexOf(c[i])>=0)&&(c[i].handler.call("scope"in c[i]?c[i].scope:this,h),c[i].once&&a.push(c[i]));for(s=0;se;e++)if(t._children[e]===r){t._children.splice(e,1);break}}),this._children.push(r),r},o.prototype.listeners=function(t){var e,n,i,o=[];if(t)for(o=r(this._handlers[t]),n=0,i=this._children.length;i>n;n++)o=o.concat(this._children[n].listeners(t));else{o=r(this._handlersAll);for(e in this._handlers)o=o.concat(r(this._handlers[e]));for(n=0,i=this._children.length;i>n;n++)o=o.concat(this._children[n].listeners())}return o},o.prototype.kill=function(){if(this.emit("emmett:kill"),this.unbindAll(),this._handlers=null,this._handlersAll=null,this._enabled=!1,this._children)for(var t=0,r=this._children.length;r>t;t++)this._children[t].kill();this._children=null},o.prototype.disable=function(){return this._enabled=!1,this},o.prototype.enable=function(){return this._enabled=!0,this},o.version="2.1.2","undefined"!=typeof n?("undefined"!=typeof e&&e.exports&&(n=e.exports=o),n.Emitter=o):"function"==typeof t&&t.amd?t("emmett",[],function(){return o}):this.Emitter=o}).call(this)},{}],4:[function(t,r){function e(t){return t+"$"+(new Date).getTime()+(""+Math.random()).replace("0.","")}function n(t,r){function e(t){this[t]=function(){var r=this.root[t].apply(this.root,arguments);return r instanceof i?this:r}}if(arguments.length<1&&(t={}),!(this instanceof n))return new n(t,r);if(!f.Object(t)&&!f.Array(t))throw Error("Baobab: invalid data.");o.call(this),this.options=a.shallowMerge(l,r),this._transaction={},this._future=void 0,this._cursors={},this.data=a.deepClone(t),this.root=this.select([]),["get","set","unset","update"].forEach(e.bind(this)),this.mixin=c.baobab(this)}var i=t("./cursor.js"),o=t("emmett"),s=t("./watcher.js"),a=t("./helpers.js"),h=t("./update.js"),u=t("./merge.js"),c=t("./mixins.js"),l=t("../defaults.js"),f=t("./type.js");a.inherits(n,o),n.prototype.select=function(t){if(!t)throw Error("Baobab.select: invalid path.");if(arguments.length>1&&(t=a.arrayOf(arguments)),!f.Path(t))throw Error("Baobab.select: invalid path.");t=[].concat(t);var r,n=f.ComplexPath(t);n&&(r=a.solvePath(this.data,t,this));var o=t.map(function(t){return f.Function(t)?e("fn"):f.Object(t)?e("ob"):t}).join("|λ|");if(this._cursors[o])return this._cursors[o];var s=new i(this,t,r,o);return this._cursors[o]=s,s},n.prototype.stack=function(t){var r=this;if(!f.Object(t))throw Error("Baobab.update: wrong specification.");return this._transaction=u(t,this._transaction),this.options.autoCommit?this.options.asynchronous?(this._future||(this._future=setTimeout(r.commit.bind(r,null),0)),this):this.commit():this},n.prototype.commit=function(){var t=h(this.data,this._transaction,this.options),r=this.data;return this.data=t.data,this._transaction={},this._future&&(this._future=clearTimeout(this._future)),this.emit("update",{log:t.log,previousState:r}),this},n.prototype.watch=function(t){if(!f.Array(t)||t.some(function(t){return!f.Path(t)}))throw Error("Baobab.watch: invalid paths.");return new s(this,[].concat(t))},n.prototype.release=function(){delete this.data,delete this._transaction;for(var t in this._cursors)this._cursors[t].release();delete this._cursors,this.kill()},n.prototype.toJSON=function(){return this.get()},r.exports=n},{"../defaults.js":2,"./cursor.js":5,"./helpers.js":6,"./merge.js":7,"./mixins.js":8,"./type.js":9,"./update.js":10,"./watcher.js":11,emmett:3}],5:[function(t,r){function e(t,r,e,n){function i(t){if(h.isRecording()&&!h.undoing){var r=a.getIn(t,h.solvedPath,h.tree),e=a.deepClone(r);h.archive.add(e)}return h.undoing=!1,h.emit("update")}var h=this;o.call(this),r=r||[],this.tree=t,this.path=r,this.hash=n,this.archive=null,this.undoing=!1,this.complexPath=!!e,this.solvedPath=this.complexPath?e:this.path,this.relevant=void 0!==this.get(),this.updateHandler=function(t){var r=t.data.log,e=t.data.previousState,n=!1;if(h.complexPath&&(h.solvedPath=a.solvePath(h.tree.data,h.path,h.tree)),!h.path.length)return i(e);h.solvedPath&&(n=a.solveUpdate(r,[h.solvedPath]));var o=void 0!==h.get();h.relevant?o&&n?i(e):o||(h.emit("irrelevant"),h.relevant=!1):o&&n&&(h.emit("relevant"),i(e),h.relevant=!0)},this.mixin=s.cursor(this);var u=!1;this._lazyBind=function(){u||(u=!0,h.tree.on("update",h.updateHandler))},this.on=a.before(this._lazyBind,this.on.bind(this)),this.once=a.before(this._lazyBind,this.once.bind(this)),this.complexPath&&this._lazyBind()}function n(t,r,e,n){if(arguments.length>5)throw Error("baobab.Cursor."+t+": too many arguments.");arguments.length<4&&(n=e,e=[]),e=e||[];var i=[].concat(e),o=a.solvePath(this.get(),i,this.tree);if(!o)throw Error("baobab.Cursor."+t+": could not solve dynamic path.");if(r){var s=this.get(o);if(!h[r](s))throw Error("baobab.Cursor."+t+": invalid target.")}var u={};u["$"+t]=n;var c=a.pathObject(o,u);return c}function i(t,r){e.prototype[t]=function(){var e=n.bind(this,t,r).apply(this,arguments);return this.update(e)}}var o=t("emmett"),s=t("./mixins.js"),a=t("./helpers.js"),h=(t("../defaults.js"),t("./type.js"));a.inherits(e,o),e.prototype.isRoot=function(){return!this.path.length},e.prototype.isLeaf=function(){return h.Primitive(this.get())},e.prototype.isBranch=function(){return!this.isLeaf()&&!this.isRoot()},e.prototype.root=function(){return this.tree.root()},e.prototype.select=function(t){if(arguments.length>1&&(t=a.arrayOf(arguments)),!h.Path(t))throw Error("baobab.Cursor.select: invalid path.");return this.tree.select(this.path.concat(t))},e.prototype.up=function(){return this.solvedPath&&this.solvedPath.length?this.tree.select(this.path.slice(0,-1)):null},e.prototype.left=function(){var t=+this.solvedPath[this.solvedPath.length-1];if(isNaN(t))throw Error("baobab.Cursor.left: cannot go left on a non-list type.");return t?this.tree.select(this.solvedPath.slice(0,-1).concat(t-1)):null},e.prototype.leftmost=function(){var t=+this.solvedPath[this.solvedPath.length-1];if(isNaN(t))throw Error("baobab.Cursor.leftmost: cannot go left on a non-list type.");return this.tree.select(this.solvedPath.slice(0,-1).concat(0))},e.prototype.right=function(){var t=+this.solvedPath[this.solvedPath.length-1];if(isNaN(t))throw Error("baobab.Cursor.right: cannot go right on a non-list type.");return t+1===this.up().get().length?null:this.tree.select(this.solvedPath.slice(0,-1).concat(t+1))},e.prototype.rightmost=function(){var t=+this.solvedPath[this.solvedPath.length-1];if(isNaN(t))throw Error("baobab.Cursor.right: cannot go right on a non-list type.");var r=this.up().get();return this.tree.select(this.solvedPath.slice(0,-1).concat(r.length-1))},e.prototype.down=function(){+this.solvedPath[this.solvedPath.length-1];return this.get()instanceof Array?this.tree.select(this.solvedPath.concat(0)):null},e.prototype.get=function(t){arguments.length>1&&(t=a.arrayOf(arguments));var r=this.solvedPath.concat((h.String(t)||h.Number(t)?[t]:t)||[]);return a.getIn(this.tree.data,r,this.tree)},i("set"),i("apply"),i("chain"),i("push","Array"),i("unshift","Array"),e.prototype.merge=function(t){if(!h.Object(t))throw Error("baobab.Cursor.merge: trying to merge a non-object.");var r=n.bind(this,"merge","Object").apply(this,arguments);return this.update(r)},e.prototype.unset=function(t){if(void 0===t&&this.isRoot())throw Error("baobab.Cursor.unset: cannot remove root node.");var r=n.bind(this,"unset",null).apply(this,[t,!0]);return this.update(r)},e.prototype.update=function(t,r){if(arguments.length<2)return this.tree.stack(a.pathObject(this.solvedPath,t)),this;var e=[].concat(t),n=a.solvePath(this.get(),e,this.tree);if(!n)throw Error("baobab.Cursor.update: could not solve dynamic path.");return this.tree.stack(a.pathObject(this.solvedPath.concat(n),r)),this},e.prototype.startRecording=function(t){if(t=t||5,1>t)throw Error("baobab.Cursor.startRecording: invalid maximum number of records.");return this.archive?this:(this._lazyBind(),this.archive=a.archive(t),this)},e.prototype.stopRecording=function(){return this.archive=null,this},e.prototype.undo=function(t){if(t=t||1,!this.isRecording())throw Error("baobab.Cursor.undo: cursor is not recording.");if(!h.PositiveInteger(t))throw Error("baobab.Cursor.undo: expecting a positive integer.");var r=this.archive.back(t);if(!r)throw Error("boabab.Cursor.undo: cannot find a relevant record ("+t+" back).");return this.undoing=!0,this.set(r)},e.prototype.isRecording=function(){return!!this.archive},e.prototype.hasHistory=function(){return!(!this.archive||!this.archive.get().length)},e.prototype.getHistory=function(){return this.archive?this.archive.get():[]},e.prototype.release=function(){this.tree.off("update",this.updateHandler),this.hash&&delete this.tree._cursors[this.hash],delete this.tree,delete this.path,delete this.solvedPath,delete this.archive,this.kill()},e.prototype.toJSON=function(){return this.get()},h.Cursor=function(t){return t instanceof e},r.exports=e},{"../defaults.js":2,"./helpers.js":6,"./mixins.js":8,"./type.js":9,emmett:3}],6:[function(t,r){(function(e){function n(t){return Array.prototype.slice.call(t)}function i(t,r){return function(){t(),r.apply(null,arguments)}}function o(t,r){var e,n={};for(e in t)n[e]=t[e];for(e in r)n[e]=r[e];return n}function s(t){var r=t.source,e="";return t.global&&(e+="g"),t.multiline&&(e+="m"),t.ignoreCase&&(e+="i"),t.sticky&&(e+="y"),t.unicode&&(e+="u"),new RegExp(r,e)}function a(t,r){if(!r||"object"!=typeof r||r instanceof Error||"ArrayBuffer"in e&&r instanceof ArrayBuffer)return r;if(j.Array(r)){if(t){var n,i,o=[];for(n=0,i=r.length;i>n;n++)o.push($(r[n]));return o}return r.slice(0)}if(j.Date(r))return new Date(r.getTime());if(r instanceof RegExp)return s(r);if(j.Object(r)){var a,h={};r.constructor&&r.constructor!==Object&&(h=Object.create(r.constructor.prototype));for(a in r)r.hasOwnProperty(a)&&(h[a]=t?$(r[a]):r[a]);return h}return r}function h(t,r){return function(e){return r(t(e))}}function u(t,r){var e,n;for(e=0,n=t.length;n>e;e++)if(r(t[e]))return t[e]}function c(t,r){var e,n;for(e=0,n=t.length;n>e;e++)if(r(t[e]))return e;return-1}function l(t,r){var e,n=!0;if(!t)return!1;for(e in r)if(j.Object(r[e]))n=n&&l(t[e],r[e]);else if(j.Array(r[e]))n=n&&!!~r[e].indexOf(t[e]);else if(t[e]!==r[e])return!1;return n}function f(t,r){return u(t,function(t){return l(t,r)})}function d(t,r){return c(t,function(t){return l(t,r)})}function y(t,r,e){r=r||[];var n,i,o,s=t;for(i=0,o=r.length;o>i;i++){if(!s)return;if("function"==typeof r[i]){if(!j.Array(s))return;s=u(s,r[i])}else if("object"==typeof r[i])if(e&&"$cursor"in r[i]){if(!j.Path(r[i].$cursor))throw Error("baobab.getIn: $cursor path must be an array.");n=e.get(r[i].$cursor),s=s[n]}else{if(!j.Array(s))return;s=f(s,r[i])}else s=s[r[i]]}return s}function g(t,r,e){var n,i,o,s=[],a=t;for(i=0,o=r.length;o>i;i++){if(!a)return null;if("function"==typeof r[i]){if(!j.Array(a))return;n=c(a,r[i]),s.push(n),a=a[n]}else if("object"==typeof r[i])if(e&&"$cursor"in r[i]){if(!j.Path(r[i].$cursor))throw Error("baobab.getIn: $cursor path must be an array.");p=e.get(r[i].$cursor),s.push(p),a=a[p]}else{if(!j.Array(a))return;n=d(a,r[i]),s.push(n),a=a[n]}else s.push(r[i]),a=a[r[i]]||{}}return s}function b(t,r){var e,n,i,o,s,a,h,u,c;for(e=0,o=r.length;o>e;e++)for(h=r[e],n=0,s=t.length;s>n;n++)for(u=t[n],i=0,a=u.length;a>i&&(c=u[i],c==h[i]);i++)if(i+1===a||i+1===h.length)return!0;return!1}function v(t,r){var e,n=t.length,i={},o=i;for(n||(i=r),e=0;n>e;e++)o[t[e]]=e+1===n?r:{},o=o[t[e]];return i}function m(t,r){t.super_=r;var e=function(){};e.prototype=r.prototype,t.prototype=new e,t.prototype.constructor=t}function _(t){var r=[];return{add:function(e){for(r.unshift(e);r.length>t;)r.pop()},back:function(t){var e=r[t-1];return e&&(r=r.slice(t)),e},get:function(){return r}}}var j=t("./type.js"),w=a.bind(null,!1),$=a.bind(null,!0);r.exports={archive:_,arrayOf:n,before:i,deepClone:$,shallowClone:w,shallowMerge:o,compose:h,getIn:y,inherits:m,pathObject:v,solvePath:g,solveUpdate:b}}).call(this,"undefined"!=typeof global?global:"undefined"!=typeof self?self:"undefined"!=typeof window?window:{})},{"./type.js":9}],7:[function(t,r){function e(t,r,e){s.forEach(function(r){e!==r&&delete t[r]}),t[e]=r[e]}function n(t,r){var a,h=i.shallowClone(r||{});s.forEach(function(r){t[r]&&e(h,t,r)}),t.$chain&&(s.slice(0,-1).forEach(function(t){delete h[t]}),h.$apply=h.$apply?i.compose(h.$apply,t.$chain):t.$chain),t.$push&&h.$push?h.$push=o.Array(h.$push)?h.$push.concat(t.$push):[h.$push].concat(t.$push):t.$push&&(h.$push=t.$push),t.$unshift&&h.$unshift?h.$unshift=o.Array(t.$unshift)?t.$unshift.concat(h.$unshift):[t.$unshift].concat(h.$unshift):t.$unshift&&(h.$unshift=t.$unshift);for(a in t)o.Object(t[a])?h[a]=n(t[a],h[a]):"$"!==a[0]&&(h[a]=t[a]);return h}var i=t("./helpers.js"),o=t("./type.js"),s=["$unset","$set","$merge","$apply"];r.exports=n},{"./helpers.js":6,"./type.js":9}],8:[function(t,r){var e=t("./type.js");r.exports={baobab:function(t){return{mixins:[{getInitialState:function(){if(this.tree=t,!this.cursor&&!this.cursors)return{};if(this.cursor&&this.cursors)throw Error("baobab.mixin: you cannot have both `component.cursor` and `component.cursors`. Please make up your mind.");if(this.__type=null,this.__updateHandler=function(){this.setState(this.__getCursorData())}.bind(this),this.cursor){if(!e.MixinCursor(this.cursor))throw Error("baobab.mixin.cursor: invalid data (cursor, string, array or function).");e.Function(this.cursor)&&(this.cursor=this.cursor()),e.Cursor(this.cursor)||(this.cursor=t.select(this.cursor)),this.__getCursorData=function(){return{cursor:this.cursor.get()}}.bind(this),this.__type="single"}else if(this.cursors){if(!e.MixinCursors(this.cursors))throw Error("baobab.mixin.cursor: invalid data (object, array or function).");if(e.Function(this.cursors)&&(this.cursors=this.cursors()),e.Array(this.cursors))this.cursors=this.cursors.map(function(r){return e.Cursor(r)?r:t.select(r)}),this.__getCursorData=function(){return{cursors:this.cursors.map(function(t){return t.get()})}}.bind(this),this.__type="array";else{for(var r in this.cursors)e.Cursor(this.cursors[r])||(this.cursors[r]=t.select(this.cursors[r]));this.__getCursorData=function(){var t={};for(r in this.cursors)t[r]=this.cursors[r].get();return{cursors:t}}.bind(this),this.__type="object"}}return this.__getCursorData()},componentDidMount:function(){"single"===this.__type?(this.__watcher=this.tree.watch([this.cursor.path]),this.__watcher.on("update",this.__updateHandler)):"array"===this.__type?(this.__watcher=this.tree.watch(this.cursors.map(function(t){return t.path})),this.__watcher.on("update",this.__updateHandler)):"object"===this.__type&&(this.__watcher=this.tree.watch(Object.keys(this.cursors).map(function(t){return this.cursors[t].path},this)),this.__watcher.on("update",this.__updateHandler))},componentWillUnmount:function(){this.__watcher&&this.__watcher.release()}}].concat(t.options.mixins)}},cursor:function(t){return{mixins:[{getInitialState:function(){return this.cursor=t,this.__updateHandler=function(){this.setState({cursor:this.cursor.get()})}.bind(this),{cursor:this.cursor.get()}},componentDidMount:function(){this.cursor.on("update",this.__updateHandler)},componentWillUnmount:function(){this.cursor.off("update",this.__updateHandler)}}].concat(t.tree.options.mixins)}}}},{"./type.js":9}],9:[function(t,r){function e(t,r){return r.some(function(r){return n[r](t)})}var n={};n.Array=function(t){return Array.isArray(t)},n.Object=function(t){return t&&"object"==typeof t&&!Array.isArray(t)&&!(t instanceof Function)},n.String=function(t){return"string"==typeof t},n.Number=function(t){return"number"==typeof t},n.PositiveInteger=function(t){return"number"==typeof t&&t>0&&!(t%1)},n.Function=function(t){return"function"==typeof t},n.Primitive=function(t){return"string"==typeof t||"number"==typeof t||"boolean"==typeof t},n.Date=function(t){return t instanceof Date},n.NonScalar=function(t){return n.Object(t)||n.Array(t)},n.Path=function(t){var r=["String","Number","Function","Object"];return n.Array(t)?t.every(function(t){return e(t,r)}):e(t,r)},n.MixinCursor=function(t){return e(t,["String","Number","Array","Function","Cursor"])},n.MixinCursors=function(t){return e(t,["Object","Array","Function"])},n.ComplexPath=function(t){return t.some(function(t){return e(t,["Object","Function"])})},r.exports=n},{}],10:[function(t,r){function e(t,r){var e=new Error("baobab.update: "+r+" at path /"+t.slice(1).join("/"));return e.path=t,e}var n=t("./helpers.js"),i=t("./type.js");r.exports=function(t,r,o){if(o=o||{},!i.Object(t)&&!i.Array(t))throw Error("baobab.update: invalid target.");var s={};t={root:n.shallowClone(t)};var a=function(t,r,o,h){o=o||["root"];var u,c,l,f=o.join("|λ|"),p=o[o.length-1],d=Object.keys(r).some(function(t){return!!~["$unset","$set","$apply","$merge","$push","$unshift"].indexOf(t)});if(d){s[f]=!0;for(c in r){if("$unset"===c){var y=o[o.length-2];i.Array(t)?h[y]=t.slice(0,+p).concat(t.slice(+p+1)):(h[y]=n.shallowClone(t),delete h[y][p]);break}if("$set"===c){l=r.$set,t[p]=l;break}if("$apply"===c){if(u=r.$apply,"function"!=typeof u)throw e(o,"using command $apply with a non function");t[p]=u.call(null,t[p]);break}if("$merge"===c){if(l=r.$merge,!i.Object(t[p])||!i.Object(l))throw e(o,"using command $merge with a non object");t[p]=n.shallowMerge(t[p],l);break}if("$push"===c){if(l=r.$push,!i.Array(t[p]))throw e(o,"using command $push to a non array");t[p]=t[p].concat(l)}if("$unshift"===c){if(l=r.$unshift,!i.Array(t[p]))throw e(o,"using command $unshift to a non array");t[p]=[].concat(l).concat(t[p])}}}else for(c in r)t[p][c]="undefined"==typeof t[p][c]?{}:n.shallowClone(t[p][c]),a(t[p],r[c],o.concat(c),t)};return a(t,r),{data:t.root,log:Object.keys(s).map(function(t){return t.split("|λ|").slice(1)})}}},{"./helpers.js":6,"./type.js":9}],11:[function(t,r){function e(t,r){function e(){h&&(a=r.map(function(t){return i.solvePath(s.tree.data,t,s.tree)}))}var s=this;n.call(this),this.tree=t;var a=r,h=r.some(o.ComplexPath);this.updateHandler=function(t){var r=i.solveUpdate(t.data.log,a);r&&s.emit("update")},e(),this.tree.on("update",this.updateHandler)}var n=t("emmett"),i=t("./helpers.js"),o=t("./type.js");i.inherits(e,n),e.prototype.release=function(){this.tree.off("update",this.updateHandler),this.tree=null,this.kill()},r.exports=e},{"./helpers.js":6,"./type.js":9,emmett:3}]},{},[1])(1)}); \ No newline at end of file +!function(t){if("object"==typeof exports&&"undefined"!=typeof module)module.exports=t();else if("function"==typeof define&&define.amd)define([],t);else{var r;r="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:this,r.Baobab=t()}}(function(){var t;return function r(t,e,n){function i(s,a){if(!e[s]){if(!t[s]){var u="function"==typeof require&&require;if(!a&&u)return u(s,!0);if(o)return o(s,!0);var h=new Error("Cannot find module '"+s+"'");throw h.code="MODULE_NOT_FOUND",h}var c=e[s]={exports:{}};t[s][0].call(c.exports,function(r){var e=t[s][1][r];return i(e?e:r)},c,c.exports,r,t,e,n)}return e[s].exports}for(var o="function"==typeof require&&require,s=0;sn;n++)t[n].fn!==r&&i.push(t[n]);return i}var s={once:"boolean",scope:"object"},a=0,u=function(){this._enabled=!0,this.unbindAll()};u.prototype.unbindAll=function(){return this._handlers={},this._handlersAll=[],this._handlersComplex=[],this},u.prototype.on=function(t,r,e){var n,o,u,h,c,l,f;if(i(t)){for(h in t)this.on(h,t[h],r);return this}for("function"==typeof t&&(e=r,r=t,t=null),c=[].concat(t),n=0,o=c.length;o>n;n++){if(h=c[n],f={order:a++,fn:r},"string"==typeof h)this._handlers[h]||(this._handlers[h]=[]),l=this._handlers[h];else if(h instanceof RegExp)l=this._handlersComplex,f.pattern=h;else{if(null!==h)throw Error("Emitter.on: invalid event.");l=this._handlersAll}for(u in e||{})s[u]&&(f[u]=e[u]);f.once&&(f.parent=l),l.push(f)}return this},u.prototype.once=function(){var t=Array.prototype.slice.call(arguments),e=t.length-1;return i(t[e])&&t.length>1?t[e]=r(t[e],{once:!0}):t.push({once:!0}),this.on.apply(this,t)},u.prototype.off=function(t,r){var e,n,s,a;if(1===arguments.length&&"function"==typeof t){r=arguments[0];for(s in this._handlers)this._handlers[s]=o(this._handlers[s],r),0===this._handlers[s].length&&delete this._handlers[s];this._handlersAll=o(this._handlersAll,r),this._handlersComplex=o(this._handlersComplex,r)}else if(1===arguments.length&&"string"==typeof t)delete this._handlers[t];else if(2===arguments.length){var u=[].concat(t);for(e=0,n=u.length;n>e;e++)a=u[e],this._handlers[a]=o(this._handlers[a],r),0===(this._handlers[a]||[]).length&&delete this._handlers[a]}else if(i(t))for(s in t)this.off(s,t[s]);return this},u.prototype.listeners=function(t){var r,e,n,i=this._handlersAll||[],o=!1;if(!t)throw Error("Emitter.listeners: no event provided.");for(i=i.concat(this._handlers[t]||[]),e=0,n=this._handlersComplex.length;n>e;e++)r=this._handlersComplex[e],~t.search(r.pattern)&&(o=!0,i.push(r));return this._handlersAll.length||o?i.sort(function(t,r){return t.order-r.order}):i.slice(0)},u.prototype.emit=function(t,r){if(!this._enabled)return this;if(i(t)){for(var e in t)this.emit(e,t[e]);return this}var n,o,s,a,u,h,c,l=[].concat(t),f=[];for(a=0,h=l.length;h>a;a++){for(o=this.listeners(l[a]),u=0,c=o.length;c>u;u++)s=o[u],n={type:l[a],target:this},arguments.length>1&&(n.data=r),s.fn.call("scope"in s?s.scope:this,n),s.once&&f.push(s);for(u=f.length-1;u>=0;u--)f[u].parent.splice(f[u].parent.indexOf(f[u]),1)}return this},u.prototype.kill=function(){this.unbindAll(),this._handlers=null,this._handlersAll=null,this._handlersComplex=null,this._enabled=!1},u.prototype.disable=function(){return this._enabled=!1,this},u.prototype.enable=function(){return this._enabled=!0,this},u.version="3.0.0","undefined"!=typeof n?("undefined"!=typeof e&&e.exports&&(n=e.exports=u),n.Emitter=u):"function"==typeof t&&t.amd?t("emmett",[],function(){return u}):this.Emitter=u}).call(this)},{}],4:[function(t,r){function e(t){return t+"$"+(new Date).getTime()+(""+Math.random()).replace("0.","")}function n(t,r){function e(t){this[t]=function(){var r=this.root[t].apply(this.root,arguments);return r instanceof i?this:r}}if(arguments.length<1&&(t={}),!(this instanceof n))return new n(t,r);if(!f.Object(t)&&!f.Array(t))throw Error("Baobab: invalid data.");o.call(this),this.options=a.shallowMerge(l,r),this._transaction={},this._future=void 0,this._cursors={},this.data=a.deepClone(t),this.root=this.select([]),["get","set","unset","update"].forEach(e.bind(this)),this.mixin=c.baobab(this)}var i=t("./cursor.js"),o=t("emmett"),s=t("./watcher.js"),a=t("./helpers.js"),u=t("./update.js"),h=t("./merge.js"),c=t("./mixins.js"),l=t("../defaults.js"),f=t("./type.js");a.inherits(n,o),n.prototype.select=function(t){if(!t)throw Error("Baobab.select: invalid path.");if(arguments.length>1&&(t=a.arrayOf(arguments)),!f.Path(t))throw Error("Baobab.select: invalid path.");t=[].concat(t);var r,n=f.ComplexPath(t);n&&(r=a.solvePath(this.data,t,this));var o=t.map(function(t){return f.Function(t)?e("fn"):f.Object(t)?e("ob"):t}).join("|λ|");if(this._cursors[o])return this._cursors[o];var s=new i(this,t,r,o);return this._cursors[o]=s,s},n.prototype.stack=function(t){var r=this;if(!f.Object(t))throw Error("Baobab.update: wrong specification.");return this._transaction=h(t,this._transaction),this.options.autoCommit?this.options.asynchronous?(this._future||(this._future=setTimeout(r.commit.bind(r,null),0)),this):this.commit():this},n.prototype.commit=function(){var t=u(this.data,this._transaction,this.options),r=this.data;return this.data=t.data,this._transaction={},this._future&&(this._future=clearTimeout(this._future)),this.emit("update",{log:t.log,previousState:r}),this},n.prototype.watch=function(t){if(!f.Array(t)||t.some(function(t){return!f.Path(t)}))throw Error("Baobab.watch: invalid paths.");return new s(this,[].concat(t))},n.prototype.release=function(){delete this.data,delete this._transaction;for(var t in this._cursors)this._cursors[t].release();delete this._cursors,this.kill()},n.prototype.toJSON=function(){return this.get()},r.exports=n},{"../defaults.js":2,"./cursor.js":5,"./helpers.js":6,"./merge.js":7,"./mixins.js":8,"./type.js":9,"./update.js":10,"./watcher.js":11,emmett:3}],5:[function(t,r){function e(t,r,e,n){function i(t){if(u.isRecording()&&!u.undoing){var r=a.getIn(t,u.solvedPath,u.tree),e=a.deepClone(r);u.archive.add(e)}return u.undoing=!1,u.emit("update")}var u=this;o.call(this),r=r||[],this.tree=t,this.path=r,this.hash=n,this.archive=null,this.undoing=!1,this.complexPath=!!e,this.solvedPath=this.complexPath?e:this.path,this.relevant=void 0!==this.get(),this.updateHandler=function(t){var r=t.data.log,e=t.data.previousState,n=!1;if(u.complexPath&&(u.solvedPath=a.solvePath(u.tree.data,u.path,u.tree)),!u.path.length)return i(e);u.solvedPath&&(n=a.solveUpdate(r,[u.solvedPath]));var o=void 0!==u.get();u.relevant?o&&n?i(e):o||(u.emit("irrelevant"),u.relevant=!1):o&&n&&(u.emit("relevant"),i(e),u.relevant=!0)},this.mixin=s.cursor(this);var h=!1;this._lazyBind=function(){h||(h=!0,u.tree.on("update",u.updateHandler))},this.on=a.before(this._lazyBind,this.on.bind(this)),this.once=a.before(this._lazyBind,this.once.bind(this)),this.complexPath&&this._lazyBind()}function n(t,r,e,n){if(arguments.length>5)throw Error("baobab.Cursor."+t+": too many arguments.");arguments.length<4&&(n=e,e=[]),e=e||[];var i=[].concat(e),o=a.solvePath(this.get(),i,this.tree);if(!o)throw Error("baobab.Cursor."+t+": could not solve dynamic path.");if(r){var s=this.get(o);if(!u[r](s))throw Error("baobab.Cursor."+t+": invalid target.")}var h={};h["$"+t]=n;var c=a.pathObject(o,h);return c}function i(t,r){e.prototype[t]=function(){var e=n.bind(this,t,r).apply(this,arguments);return this.update(e)}}var o=t("emmett"),s=t("./mixins.js"),a=t("./helpers.js"),u=(t("../defaults.js"),t("./type.js"));a.inherits(e,o),e.prototype.isRoot=function(){return!this.path.length},e.prototype.isLeaf=function(){return u.Primitive(this.get())},e.prototype.isBranch=function(){return!this.isLeaf()&&!this.isRoot()},e.prototype.root=function(){return this.tree.root()},e.prototype.select=function(t){if(arguments.length>1&&(t=a.arrayOf(arguments)),!u.Path(t))throw Error("baobab.Cursor.select: invalid path.");return this.tree.select(this.path.concat(t))},e.prototype.up=function(){return this.solvedPath&&this.solvedPath.length?this.tree.select(this.path.slice(0,-1)):null},e.prototype.left=function(){var t=+this.solvedPath[this.solvedPath.length-1];if(isNaN(t))throw Error("baobab.Cursor.left: cannot go left on a non-list type.");return t?this.tree.select(this.solvedPath.slice(0,-1).concat(t-1)):null},e.prototype.leftmost=function(){var t=+this.solvedPath[this.solvedPath.length-1];if(isNaN(t))throw Error("baobab.Cursor.leftmost: cannot go left on a non-list type.");return this.tree.select(this.solvedPath.slice(0,-1).concat(0))},e.prototype.right=function(){var t=+this.solvedPath[this.solvedPath.length-1];if(isNaN(t))throw Error("baobab.Cursor.right: cannot go right on a non-list type.");return t+1===this.up().get().length?null:this.tree.select(this.solvedPath.slice(0,-1).concat(t+1))},e.prototype.rightmost=function(){var t=+this.solvedPath[this.solvedPath.length-1];if(isNaN(t))throw Error("baobab.Cursor.right: cannot go right on a non-list type.");var r=this.up().get();return this.tree.select(this.solvedPath.slice(0,-1).concat(r.length-1))},e.prototype.down=function(){+this.solvedPath[this.solvedPath.length-1];return this.get()instanceof Array?this.tree.select(this.solvedPath.concat(0)):null},e.prototype.get=function(t){arguments.length>1&&(t=a.arrayOf(arguments));var r=this.solvedPath.concat((u.String(t)||u.Number(t)?[t]:t)||[]);return a.getIn(this.tree.data,r,this.tree)},i("set"),i("apply"),i("chain"),i("push","Array"),i("unshift","Array"),e.prototype.merge=function(t){if(!u.Object(t))throw Error("baobab.Cursor.merge: trying to merge a non-object.");var r=n.bind(this,"merge","Object").apply(this,arguments);return this.update(r)},e.prototype.unset=function(t){if(void 0===t&&this.isRoot())throw Error("baobab.Cursor.unset: cannot remove root node.");var r=n.bind(this,"unset",null).apply(this,[t,!0]);return this.update(r)},e.prototype.update=function(t,r){if(arguments.length<2)return this.tree.stack(a.pathObject(this.solvedPath,t)),this;var e=[].concat(t),n=a.solvePath(this.get(),e,this.tree);if(!n)throw Error("baobab.Cursor.update: could not solve dynamic path.");return this.tree.stack(a.pathObject(this.solvedPath.concat(n),r)),this},e.prototype.startRecording=function(t){if(t=t||5,1>t)throw Error("baobab.Cursor.startRecording: invalid maximum number of records.");return this.archive?this:(this._lazyBind(),this.archive=a.archive(t),this)},e.prototype.stopRecording=function(){return this.archive=null,this},e.prototype.undo=function(t){if(t=t||1,!this.isRecording())throw Error("baobab.Cursor.undo: cursor is not recording.");if(!u.PositiveInteger(t))throw Error("baobab.Cursor.undo: expecting a positive integer.");var r=this.archive.back(t);if(!r)throw Error("boabab.Cursor.undo: cannot find a relevant record ("+t+" back).");return this.undoing=!0,this.set(r)},e.prototype.isRecording=function(){return!!this.archive},e.prototype.hasHistory=function(){return!(!this.archive||!this.archive.get().length)},e.prototype.getHistory=function(){return this.archive?this.archive.get():[]},e.prototype.release=function(){this.tree.off("update",this.updateHandler),this.hash&&delete this.tree._cursors[this.hash],delete this.tree,delete this.path,delete this.solvedPath,delete this.archive,this.kill()},e.prototype.toJSON=function(){return this.get()},u.Cursor=function(t){return t instanceof e},r.exports=e},{"../defaults.js":2,"./helpers.js":6,"./mixins.js":8,"./type.js":9,emmett:3}],6:[function(t,r){(function(e){function n(t){return Array.prototype.slice.call(t)}function i(t,r){return function(){t(),r.apply(null,arguments)}}function o(t,r){var e,n={};for(e in t)n[e]=t[e];for(e in r)n[e]=r[e];return n}function s(t){var r=t.source,e="";return t.global&&(e+="g"),t.multiline&&(e+="m"),t.ignoreCase&&(e+="i"),t.sticky&&(e+="y"),t.unicode&&(e+="u"),new RegExp(r,e)}function a(t,r){if(!r||"object"!=typeof r||r instanceof Error||"ArrayBuffer"in e&&r instanceof ArrayBuffer)return r;if(j.Array(r)){if(t){var n,i,o=[];for(n=0,i=r.length;i>n;n++)o.push($(r[n]));return o}return r.slice(0)}if(j.Date(r))return new Date(r.getTime());if(r instanceof RegExp)return s(r);if(j.Object(r)){var a,u={};r.constructor&&r.constructor!==Object&&(u=Object.create(r.constructor.prototype));for(a in r)r.hasOwnProperty(a)&&(u[a]=t?$(r[a]):r[a]);return u}return r}function u(t,r){return function(e){return r(t(e))}}function h(t,r){var e,n;for(e=0,n=t.length;n>e;e++)if(r(t[e]))return t[e]}function c(t,r){var e,n;for(e=0,n=t.length;n>e;e++)if(r(t[e]))return e;return-1}function l(t,r){var e,n=!0;if(!t)return!1;for(e in r)if(j.Object(r[e]))n=n&&l(t[e],r[e]);else if(j.Array(r[e]))n=n&&!!~r[e].indexOf(t[e]);else if(t[e]!==r[e])return!1;return n}function f(t,r){return h(t,function(t){return l(t,r)})}function d(t,r){return c(t,function(t){return l(t,r)})}function y(t,r,e){r=r||[];var n,i,o,s=t;for(i=0,o=r.length;o>i;i++){if(!s)return;if("function"==typeof r[i]){if(!j.Array(s))return;s=h(s,r[i])}else if("object"==typeof r[i])if(e&&"$cursor"in r[i]){if(!j.Path(r[i].$cursor))throw Error("baobab.getIn: $cursor path must be an array.");n=e.get(r[i].$cursor),s=s[n]}else{if(!j.Array(s))return;s=f(s,r[i])}else s=s[r[i]]}return s}function g(t,r,e){var n,i,o,s=[],a=t;for(i=0,o=r.length;o>i;i++){if(!a)return null;if("function"==typeof r[i]){if(!j.Array(a))return;n=c(a,r[i]),s.push(n),a=a[n]}else if("object"==typeof r[i])if(e&&"$cursor"in r[i]){if(!j.Path(r[i].$cursor))throw Error("baobab.getIn: $cursor path must be an array.");p=e.get(r[i].$cursor),s.push(p),a=a[p]}else{if(!j.Array(a))return;n=d(a,r[i]),s.push(n),a=a[n]}else s.push(r[i]),a=a[r[i]]||{}}return s}function b(t,r){var e,n,i,o,s,a,u,h,c;for(e=0,o=r.length;o>e;e++)for(u=r[e],n=0,s=t.length;s>n;n++)for(h=t[n],i=0,a=h.length;a>i&&(c=h[i],c==u[i]);i++)if(i+1===a||i+1===u.length)return!0;return!1}function v(t,r){var e,n=t.length,i={},o=i;for(n||(i=r),e=0;n>e;e++)o[t[e]]=e+1===n?r:{},o=o[t[e]];return i}function m(t,r){t.super_=r;var e=function(){};e.prototype=r.prototype,t.prototype=new e,t.prototype.constructor=t}function _(t){var r=[];return{add:function(e){for(r.unshift(e);r.length>t;)r.pop()},back:function(t){var e=r[t-1];return e&&(r=r.slice(t)),e},get:function(){return r}}}var j=t("./type.js"),w=a.bind(null,!1),$=a.bind(null,!0);r.exports={archive:_,arrayOf:n,before:i,deepClone:$,shallowClone:w,shallowMerge:o,compose:u,getIn:y,inherits:m,pathObject:v,solvePath:g,solveUpdate:b}}).call(this,"undefined"!=typeof global?global:"undefined"!=typeof self?self:"undefined"!=typeof window?window:{})},{"./type.js":9}],7:[function(t,r){function e(t,r,e){s.forEach(function(r){e!==r&&delete t[r]}),t[e]=r[e]}function n(t,r){var a,u=i.shallowClone(r||{});s.forEach(function(r){t[r]&&e(u,t,r)}),t.$chain&&(s.slice(0,-1).forEach(function(t){delete u[t]}),u.$apply=u.$apply?i.compose(u.$apply,t.$chain):t.$chain),t.$push&&u.$push?u.$push=o.Array(u.$push)?u.$push.concat(t.$push):[u.$push].concat(t.$push):t.$push&&(u.$push=t.$push),t.$unshift&&u.$unshift?u.$unshift=o.Array(t.$unshift)?t.$unshift.concat(u.$unshift):[t.$unshift].concat(u.$unshift):t.$unshift&&(u.$unshift=t.$unshift);for(a in t)o.Object(t[a])?u[a]=n(t[a],u[a]):"$"!==a[0]&&(u[a]=t[a]);return u}var i=t("./helpers.js"),o=t("./type.js"),s=["$unset","$set","$merge","$apply"];r.exports=n},{"./helpers.js":6,"./type.js":9}],8:[function(t,r){var e=t("./type.js");r.exports={baobab:function(t){return{mixins:[{getInitialState:function(){if(this.tree=t,!this.cursor&&!this.cursors)return{};if(this.cursor&&this.cursors)throw Error("baobab.mixin: you cannot have both `component.cursor` and `component.cursors`. Please make up your mind.");if(this.__type=null,this.__updateHandler=function(){this.setState(this.__getCursorData())}.bind(this),this.cursor){if(!e.MixinCursor(this.cursor))throw Error("baobab.mixin.cursor: invalid data (cursor, string, array or function).");e.Function(this.cursor)&&(this.cursor=this.cursor()),e.Cursor(this.cursor)||(this.cursor=t.select(this.cursor)),this.__getCursorData=function(){return{cursor:this.cursor.get()}}.bind(this),this.__type="single"}else if(this.cursors){if(!e.MixinCursors(this.cursors))throw Error("baobab.mixin.cursor: invalid data (object, array or function).");if(e.Function(this.cursors)&&(this.cursors=this.cursors()),e.Array(this.cursors))this.cursors=this.cursors.map(function(r){return e.Cursor(r)?r:t.select(r)}),this.__getCursorData=function(){return{cursors:this.cursors.map(function(t){return t.get()})}}.bind(this),this.__type="array";else{for(var r in this.cursors)e.Cursor(this.cursors[r])||(this.cursors[r]=t.select(this.cursors[r]));this.__getCursorData=function(){var t={};for(r in this.cursors)t[r]=this.cursors[r].get();return{cursors:t}}.bind(this),this.__type="object"}}return this.__getCursorData()},componentDidMount:function(){"single"===this.__type?(this.__watcher=this.tree.watch([this.cursor.path]),this.__watcher.on("update",this.__updateHandler)):"array"===this.__type?(this.__watcher=this.tree.watch(this.cursors.map(function(t){return t.path})),this.__watcher.on("update",this.__updateHandler)):"object"===this.__type&&(this.__watcher=this.tree.watch(Object.keys(this.cursors).map(function(t){return this.cursors[t].path},this)),this.__watcher.on("update",this.__updateHandler))},componentWillUnmount:function(){this.__watcher&&this.__watcher.release()}}].concat(t.options.mixins)}},cursor:function(t){return{mixins:[{getInitialState:function(){return this.cursor=t,this.__updateHandler=function(){this.setState({cursor:this.cursor.get()})}.bind(this),{cursor:this.cursor.get()}},componentDidMount:function(){this.cursor.on("update",this.__updateHandler)},componentWillUnmount:function(){this.cursor.off("update",this.__updateHandler)}}].concat(t.tree.options.mixins)}}}},{"./type.js":9}],9:[function(t,r){function e(t,r){return r.some(function(r){return n[r](t)})}var n={};n.Array=function(t){return Array.isArray(t)},n.Object=function(t){return t&&"object"==typeof t&&!Array.isArray(t)&&!(t instanceof Function)},n.String=function(t){return"string"==typeof t},n.Number=function(t){return"number"==typeof t},n.PositiveInteger=function(t){return"number"==typeof t&&t>0&&!(t%1)},n.Function=function(t){return"function"==typeof t},n.Primitive=function(t){return"string"==typeof t||"number"==typeof t||"boolean"==typeof t},n.Date=function(t){return t instanceof Date},n.NonScalar=function(t){return n.Object(t)||n.Array(t)},n.Path=function(t){var r=["String","Number","Function","Object"];return n.Array(t)?t.every(function(t){return e(t,r)}):e(t,r)},n.MixinCursor=function(t){return e(t,["String","Number","Array","Function","Cursor"])},n.MixinCursors=function(t){return e(t,["Object","Array","Function"])},n.ComplexPath=function(t){return t.some(function(t){return e(t,["Object","Function"])})},r.exports=n},{}],10:[function(t,r){function e(t,r){var e=new Error("baobab.update: "+r+" at path /"+t.slice(1).join("/"));return e.path=t,e}var n=t("./helpers.js"),i=t("./type.js");r.exports=function(t,r,o){if(o=o||{},!i.Object(t)&&!i.Array(t))throw Error("baobab.update: invalid target.");var s={};t={root:n.shallowClone(t)};var a=function(t,r,o,u){o=o||["root"];var h,c,l,f=o.join("|λ|"),p=o[o.length-1],d=Object.keys(r).some(function(t){return!!~["$unset","$set","$apply","$merge","$push","$unshift"].indexOf(t)});if(d){s[f]=!0;for(c in r){if("$unset"===c){var y=o[o.length-2];i.Array(t)?u[y]=t.slice(0,+p).concat(t.slice(+p+1)):(u[y]=n.shallowClone(t),delete u[y][p]);break}if("$set"===c){l=r.$set,t[p]=l;break}if("$apply"===c){if(h=r.$apply,"function"!=typeof h)throw e(o,"using command $apply with a non function");t[p]=h.call(null,t[p]);break}if("$merge"===c){if(l=r.$merge,!i.Object(t[p])||!i.Object(l))throw e(o,"using command $merge with a non object");t[p]=n.shallowMerge(t[p],l);break}if("$push"===c){if(l=r.$push,!i.Array(t[p]))throw e(o,"using command $push to a non array");t[p]=t[p].concat(l)}if("$unshift"===c){if(l=r.$unshift,!i.Array(t[p]))throw e(o,"using command $unshift to a non array");t[p]=[].concat(l).concat(t[p])}}}else for(c in r)t[p][c]="undefined"==typeof t[p][c]?{}:n.shallowClone(t[p][c]),a(t[p],r[c],o.concat(c),t)};return a(t,r),{data:t.root,log:Object.keys(s).map(function(t){return t.split("|λ|").slice(1)})}}},{"./helpers.js":6,"./type.js":9}],11:[function(t,r){function e(t,r){function e(){u&&(a=r.map(function(t){return i.solvePath(s.tree.data,t,s.tree)}))}var s=this;n.call(this),this.tree=t;var a=r,u=r.some(o.ComplexPath);this.updateHandler=function(t){var r=i.solveUpdate(t.data.log,a);r&&s.emit("update")},e(),this.tree.on("update",this.updateHandler)}var n=t("emmett"),i=t("./helpers.js"),o=t("./type.js");i.inherits(e,n),e.prototype.release=function(){this.tree.off("update",this.updateHandler),this.tree=null,this.kill()},r.exports=e},{"./helpers.js":6,"./type.js":9,emmett:3}]},{},[1])(1)}); \ No newline at end of file diff --git a/package.json b/package.json index cacc4ee..8c61957 100644 --- a/package.json +++ b/package.json @@ -4,7 +4,7 @@ "description": "JavaScript data tree with cursors.", "main": "index.js", "dependencies": { - "emmett": "^2.1.2" + "emmett": "^3.0.0" }, "devDependencies": { "async": "~0.9.0", From 2f8bc25767ee8231f6ae393c645cfc46dd52e2e0 Mon Sep 17 00:00:00 2001 From: Yomguithereal Date: Tue, 14 Apr 2015 12:27:43 +0200 Subject: [PATCH 45/73] Starting facets --- defaults.js | 3 +++ src/baobab.js | 14 ++++++++++++++ src/cursor.js | 2 +- src/facet.js | 38 ++++++++++++++++++++++++++++++++++++++ src/helpers.js | 26 ++++++++++++++++++++++++++ src/type.js | 2 +- test/suites/helpers.js | 11 +++++++++++ 7 files changed, 94 insertions(+), 2 deletions(-) create mode 100644 src/facet.js diff --git a/defaults.js b/defaults.js index fe264b8..5ec615e 100644 --- a/defaults.js +++ b/defaults.js @@ -11,6 +11,9 @@ module.exports = { // Should the transactions be handled asynchronously? asynchronous: true, + // Facets registration + facets: {}, + // Collection of react mixins to merge with the tree's ones mixins: [], diff --git a/src/baobab.js b/src/baobab.js index b8a4059..946251b 100644 --- a/src/baobab.js +++ b/src/baobab.js @@ -7,6 +7,7 @@ var Cursor = require('./cursor.js'), EventEmitter = require('emmett'), Watcher = require('./watcher.js'), + Facet = require('./facet.js'), helpers = require('./helpers.js'), update = require('./update.js'), merge = require('./merge.js'), @@ -47,6 +48,7 @@ function Baobab(initialData, opts) { // Properties this.data = helpers.deepClone(initialData); this.root = this.select([]); + this.facets = {}; // Boostrapping root cursor's methods function bootstrap(name) { @@ -58,6 +60,13 @@ function Baobab(initialData, opts) { ['get', 'set', 'unset', 'update'].forEach(bootstrap.bind(this)); + // Facets + if (!type.Object(this.options.facets)) + throw Error('Baobab: invalid facets.'); + + for (var k in this.options.facets) + this.addFacet(k, this.options.facets[k]); + // Mixin this.mixin = mixins.baobab(this); } @@ -67,6 +76,11 @@ helpers.inherits(Baobab, EventEmitter); /** * Prototype */ +Baobab.prototype.addFacet = function(name, definition) { + this.facets[name] = new Facet(tree, definition); + return this; +}; + Baobab.prototype.select = function(path) { if (!path) throw Error('Baobab.select: invalid path.'); diff --git a/src/cursor.js b/src/cursor.js index c1bda5f..3cf391a 100644 --- a/src/cursor.js +++ b/src/cursor.js @@ -221,7 +221,7 @@ Cursor.prototype.get = function(path) { */ function pathPolymorphism(method, allowedType, key, val) { if (arguments.length > 5) - throw Error('baobab.Cursor.' + method + ': too many arguments.') + throw Error('baobab.Cursor.' + method + ': too many arguments.'); if (arguments.length < 4) { val = key; diff --git a/src/facet.js b/src/facet.js new file mode 100644 index 0000000..a53782c --- /dev/null +++ b/src/facet.js @@ -0,0 +1,38 @@ +/** + * Baobab Facet Abstraction + * ========================= + * + * Facets enable the user to define views on a given Baobab tree. + */ +var Watcher = require('./watcher.js'); + +function Facet(tree, definition) { + var self = this; + + // Private + var data = null, + solved = false + solver = definition.get; + + var paths = Object.keys(definition.cursors).map(function(k) { + return definition.cursors[k]; + }); + + // Watcher + var watcher = new Watcher(tree, paths); + + function bind(name) { + self[name] = watcher[name].bind(watcher); + } + + ['on', 'once'].forEach(bind); + + this.get = function() { + if (this.solved) + return data; + + // Solving + }; +} + +module.exports = Facet; diff --git a/src/helpers.js b/src/helpers.js index d0ce637..896719e 100644 --- a/src/helpers.js +++ b/src/helpers.js @@ -30,6 +30,31 @@ function shallowMerge(o1, o2) { return o; } +// Shallow equality +function shallowEqual(o1, o2) { + if (o1 === o2) + return true; + + if (typeof o1 !== 'object' || typeof o2 !== 'object' || + o1 === null || o2 === null) + return false; + + var k1 = Object.keys(o1), + k2 = Object.keys(o2); + + if (k1.length !== k2.length) + return false; + + var i, l; + + for (i = 0, l = k1.length; i < l; i++) { + if (o1[k1[i]] !== o2[k1[i]]) + return false; + } + + return true; +} + // Clone a regexp function cloneRegexp(re) { var pattern = re.source, @@ -342,6 +367,7 @@ module.exports = { before: before, deepClone: deepClone, shallowClone: shallowClone, + shallowEqual: shallowEqual, shallowMerge: shallowMerge, compose: compose, getIn: getIn, diff --git a/src/type.js b/src/type.js index fc37f57..6232c09 100644 --- a/src/type.js +++ b/src/type.js @@ -41,7 +41,7 @@ type.Number = function(value) { }; type.PositiveInteger = function(value) { - return typeof value === 'number' && value > 0 && !(value % 1); + return typeof value === 'number' && value > 0 && value % 1 === 0; }; type.Function = function(value) { diff --git a/test/suites/helpers.js b/test/suites/helpers.js index 97b102f..37022ad 100644 --- a/test/suites/helpers.js +++ b/test/suites/helpers.js @@ -117,6 +117,17 @@ describe('Helpers', function() { }); }); + describe('Shallow equality', function() { + var se = helpers.shallowEqual; + + it('should check equalities correctly.', function() { + assert(se('Hey!', 'Hey!')); + assert(se(0, 0)); + assert(se({hello: 'world'}, {hello: 'world'})); + assert(!se({hello: 'world'}, {hey: 'ho'})); + }); + }); + describe('Update API', function() { it('should be possible to set nested values.', function() { From 3a9a5b34bb7d5af5c2026ce061f8c64a74dce3ba Mon Sep 17 00:00:00 2001 From: Yomguithereal Date: Tue, 14 Apr 2015 13:17:12 +0200 Subject: [PATCH 46/73] Related to #139 - first working facets implementation --- build/baobab.min.js | 2 +- package.json | 2 +- src/baobab.js | 10 +++- src/cursor.js | 2 +- src/facet.js | 35 ++++++++--- test/suites/baobab.js | 133 ++++++++++++++++++++++++++++++++++++++++- test/suites/helpers.js | 3 +- 7 files changed, 172 insertions(+), 15 deletions(-) diff --git a/build/baobab.min.js b/build/baobab.min.js index 3a68def..c0f9dde 100644 --- a/build/baobab.min.js +++ b/build/baobab.min.js @@ -1,2 +1,2 @@ /* baobab.js - Version: 1.0.0-rc1 - Author: Yomguithereal (Guillaume Plique) */ -!function(t){if("object"==typeof exports&&"undefined"!=typeof module)module.exports=t();else if("function"==typeof define&&define.amd)define([],t);else{var r;r="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:this,r.Baobab=t()}}(function(){var t;return function r(t,e,n){function i(s,a){if(!e[s]){if(!t[s]){var u="function"==typeof require&&require;if(!a&&u)return u(s,!0);if(o)return o(s,!0);var h=new Error("Cannot find module '"+s+"'");throw h.code="MODULE_NOT_FOUND",h}var c=e[s]={exports:{}};t[s][0].call(c.exports,function(r){var e=t[s][1][r];return i(e?e:r)},c,c.exports,r,t,e,n)}return e[s].exports}for(var o="function"==typeof require&&require,s=0;sn;n++)t[n].fn!==r&&i.push(t[n]);return i}var s={once:"boolean",scope:"object"},a=0,u=function(){this._enabled=!0,this.unbindAll()};u.prototype.unbindAll=function(){return this._handlers={},this._handlersAll=[],this._handlersComplex=[],this},u.prototype.on=function(t,r,e){var n,o,u,h,c,l,f;if(i(t)){for(h in t)this.on(h,t[h],r);return this}for("function"==typeof t&&(e=r,r=t,t=null),c=[].concat(t),n=0,o=c.length;o>n;n++){if(h=c[n],f={order:a++,fn:r},"string"==typeof h)this._handlers[h]||(this._handlers[h]=[]),l=this._handlers[h];else if(h instanceof RegExp)l=this._handlersComplex,f.pattern=h;else{if(null!==h)throw Error("Emitter.on: invalid event.");l=this._handlersAll}for(u in e||{})s[u]&&(f[u]=e[u]);f.once&&(f.parent=l),l.push(f)}return this},u.prototype.once=function(){var t=Array.prototype.slice.call(arguments),e=t.length-1;return i(t[e])&&t.length>1?t[e]=r(t[e],{once:!0}):t.push({once:!0}),this.on.apply(this,t)},u.prototype.off=function(t,r){var e,n,s,a;if(1===arguments.length&&"function"==typeof t){r=arguments[0];for(s in this._handlers)this._handlers[s]=o(this._handlers[s],r),0===this._handlers[s].length&&delete this._handlers[s];this._handlersAll=o(this._handlersAll,r),this._handlersComplex=o(this._handlersComplex,r)}else if(1===arguments.length&&"string"==typeof t)delete this._handlers[t];else if(2===arguments.length){var u=[].concat(t);for(e=0,n=u.length;n>e;e++)a=u[e],this._handlers[a]=o(this._handlers[a],r),0===(this._handlers[a]||[]).length&&delete this._handlers[a]}else if(i(t))for(s in t)this.off(s,t[s]);return this},u.prototype.listeners=function(t){var r,e,n,i=this._handlersAll||[],o=!1;if(!t)throw Error("Emitter.listeners: no event provided.");for(i=i.concat(this._handlers[t]||[]),e=0,n=this._handlersComplex.length;n>e;e++)r=this._handlersComplex[e],~t.search(r.pattern)&&(o=!0,i.push(r));return this._handlersAll.length||o?i.sort(function(t,r){return t.order-r.order}):i.slice(0)},u.prototype.emit=function(t,r){if(!this._enabled)return this;if(i(t)){for(var e in t)this.emit(e,t[e]);return this}var n,o,s,a,u,h,c,l=[].concat(t),f=[];for(a=0,h=l.length;h>a;a++){for(o=this.listeners(l[a]),u=0,c=o.length;c>u;u++)s=o[u],n={type:l[a],target:this},arguments.length>1&&(n.data=r),s.fn.call("scope"in s?s.scope:this,n),s.once&&f.push(s);for(u=f.length-1;u>=0;u--)f[u].parent.splice(f[u].parent.indexOf(f[u]),1)}return this},u.prototype.kill=function(){this.unbindAll(),this._handlers=null,this._handlersAll=null,this._handlersComplex=null,this._enabled=!1},u.prototype.disable=function(){return this._enabled=!1,this},u.prototype.enable=function(){return this._enabled=!0,this},u.version="3.0.0","undefined"!=typeof n?("undefined"!=typeof e&&e.exports&&(n=e.exports=u),n.Emitter=u):"function"==typeof t&&t.amd?t("emmett",[],function(){return u}):this.Emitter=u}).call(this)},{}],4:[function(t,r){function e(t){return t+"$"+(new Date).getTime()+(""+Math.random()).replace("0.","")}function n(t,r){function e(t){this[t]=function(){var r=this.root[t].apply(this.root,arguments);return r instanceof i?this:r}}if(arguments.length<1&&(t={}),!(this instanceof n))return new n(t,r);if(!f.Object(t)&&!f.Array(t))throw Error("Baobab: invalid data.");o.call(this),this.options=a.shallowMerge(l,r),this._transaction={},this._future=void 0,this._cursors={},this.data=a.deepClone(t),this.root=this.select([]),["get","set","unset","update"].forEach(e.bind(this)),this.mixin=c.baobab(this)}var i=t("./cursor.js"),o=t("emmett"),s=t("./watcher.js"),a=t("./helpers.js"),u=t("./update.js"),h=t("./merge.js"),c=t("./mixins.js"),l=t("../defaults.js"),f=t("./type.js");a.inherits(n,o),n.prototype.select=function(t){if(!t)throw Error("Baobab.select: invalid path.");if(arguments.length>1&&(t=a.arrayOf(arguments)),!f.Path(t))throw Error("Baobab.select: invalid path.");t=[].concat(t);var r,n=f.ComplexPath(t);n&&(r=a.solvePath(this.data,t,this));var o=t.map(function(t){return f.Function(t)?e("fn"):f.Object(t)?e("ob"):t}).join("|λ|");if(this._cursors[o])return this._cursors[o];var s=new i(this,t,r,o);return this._cursors[o]=s,s},n.prototype.stack=function(t){var r=this;if(!f.Object(t))throw Error("Baobab.update: wrong specification.");return this._transaction=h(t,this._transaction),this.options.autoCommit?this.options.asynchronous?(this._future||(this._future=setTimeout(r.commit.bind(r,null),0)),this):this.commit():this},n.prototype.commit=function(){var t=u(this.data,this._transaction,this.options),r=this.data;return this.data=t.data,this._transaction={},this._future&&(this._future=clearTimeout(this._future)),this.emit("update",{log:t.log,previousState:r}),this},n.prototype.watch=function(t){if(!f.Array(t)||t.some(function(t){return!f.Path(t)}))throw Error("Baobab.watch: invalid paths.");return new s(this,[].concat(t))},n.prototype.release=function(){delete this.data,delete this._transaction;for(var t in this._cursors)this._cursors[t].release();delete this._cursors,this.kill()},n.prototype.toJSON=function(){return this.get()},r.exports=n},{"../defaults.js":2,"./cursor.js":5,"./helpers.js":6,"./merge.js":7,"./mixins.js":8,"./type.js":9,"./update.js":10,"./watcher.js":11,emmett:3}],5:[function(t,r){function e(t,r,e,n){function i(t){if(u.isRecording()&&!u.undoing){var r=a.getIn(t,u.solvedPath,u.tree),e=a.deepClone(r);u.archive.add(e)}return u.undoing=!1,u.emit("update")}var u=this;o.call(this),r=r||[],this.tree=t,this.path=r,this.hash=n,this.archive=null,this.undoing=!1,this.complexPath=!!e,this.solvedPath=this.complexPath?e:this.path,this.relevant=void 0!==this.get(),this.updateHandler=function(t){var r=t.data.log,e=t.data.previousState,n=!1;if(u.complexPath&&(u.solvedPath=a.solvePath(u.tree.data,u.path,u.tree)),!u.path.length)return i(e);u.solvedPath&&(n=a.solveUpdate(r,[u.solvedPath]));var o=void 0!==u.get();u.relevant?o&&n?i(e):o||(u.emit("irrelevant"),u.relevant=!1):o&&n&&(u.emit("relevant"),i(e),u.relevant=!0)},this.mixin=s.cursor(this);var h=!1;this._lazyBind=function(){h||(h=!0,u.tree.on("update",u.updateHandler))},this.on=a.before(this._lazyBind,this.on.bind(this)),this.once=a.before(this._lazyBind,this.once.bind(this)),this.complexPath&&this._lazyBind()}function n(t,r,e,n){if(arguments.length>5)throw Error("baobab.Cursor."+t+": too many arguments.");arguments.length<4&&(n=e,e=[]),e=e||[];var i=[].concat(e),o=a.solvePath(this.get(),i,this.tree);if(!o)throw Error("baobab.Cursor."+t+": could not solve dynamic path.");if(r){var s=this.get(o);if(!u[r](s))throw Error("baobab.Cursor."+t+": invalid target.")}var h={};h["$"+t]=n;var c=a.pathObject(o,h);return c}function i(t,r){e.prototype[t]=function(){var e=n.bind(this,t,r).apply(this,arguments);return this.update(e)}}var o=t("emmett"),s=t("./mixins.js"),a=t("./helpers.js"),u=(t("../defaults.js"),t("./type.js"));a.inherits(e,o),e.prototype.isRoot=function(){return!this.path.length},e.prototype.isLeaf=function(){return u.Primitive(this.get())},e.prototype.isBranch=function(){return!this.isLeaf()&&!this.isRoot()},e.prototype.root=function(){return this.tree.root()},e.prototype.select=function(t){if(arguments.length>1&&(t=a.arrayOf(arguments)),!u.Path(t))throw Error("baobab.Cursor.select: invalid path.");return this.tree.select(this.path.concat(t))},e.prototype.up=function(){return this.solvedPath&&this.solvedPath.length?this.tree.select(this.path.slice(0,-1)):null},e.prototype.left=function(){var t=+this.solvedPath[this.solvedPath.length-1];if(isNaN(t))throw Error("baobab.Cursor.left: cannot go left on a non-list type.");return t?this.tree.select(this.solvedPath.slice(0,-1).concat(t-1)):null},e.prototype.leftmost=function(){var t=+this.solvedPath[this.solvedPath.length-1];if(isNaN(t))throw Error("baobab.Cursor.leftmost: cannot go left on a non-list type.");return this.tree.select(this.solvedPath.slice(0,-1).concat(0))},e.prototype.right=function(){var t=+this.solvedPath[this.solvedPath.length-1];if(isNaN(t))throw Error("baobab.Cursor.right: cannot go right on a non-list type.");return t+1===this.up().get().length?null:this.tree.select(this.solvedPath.slice(0,-1).concat(t+1))},e.prototype.rightmost=function(){var t=+this.solvedPath[this.solvedPath.length-1];if(isNaN(t))throw Error("baobab.Cursor.right: cannot go right on a non-list type.");var r=this.up().get();return this.tree.select(this.solvedPath.slice(0,-1).concat(r.length-1))},e.prototype.down=function(){+this.solvedPath[this.solvedPath.length-1];return this.get()instanceof Array?this.tree.select(this.solvedPath.concat(0)):null},e.prototype.get=function(t){arguments.length>1&&(t=a.arrayOf(arguments));var r=this.solvedPath.concat((u.String(t)||u.Number(t)?[t]:t)||[]);return a.getIn(this.tree.data,r,this.tree)},i("set"),i("apply"),i("chain"),i("push","Array"),i("unshift","Array"),e.prototype.merge=function(t){if(!u.Object(t))throw Error("baobab.Cursor.merge: trying to merge a non-object.");var r=n.bind(this,"merge","Object").apply(this,arguments);return this.update(r)},e.prototype.unset=function(t){if(void 0===t&&this.isRoot())throw Error("baobab.Cursor.unset: cannot remove root node.");var r=n.bind(this,"unset",null).apply(this,[t,!0]);return this.update(r)},e.prototype.update=function(t,r){if(arguments.length<2)return this.tree.stack(a.pathObject(this.solvedPath,t)),this;var e=[].concat(t),n=a.solvePath(this.get(),e,this.tree);if(!n)throw Error("baobab.Cursor.update: could not solve dynamic path.");return this.tree.stack(a.pathObject(this.solvedPath.concat(n),r)),this},e.prototype.startRecording=function(t){if(t=t||5,1>t)throw Error("baobab.Cursor.startRecording: invalid maximum number of records.");return this.archive?this:(this._lazyBind(),this.archive=a.archive(t),this)},e.prototype.stopRecording=function(){return this.archive=null,this},e.prototype.undo=function(t){if(t=t||1,!this.isRecording())throw Error("baobab.Cursor.undo: cursor is not recording.");if(!u.PositiveInteger(t))throw Error("baobab.Cursor.undo: expecting a positive integer.");var r=this.archive.back(t);if(!r)throw Error("boabab.Cursor.undo: cannot find a relevant record ("+t+" back).");return this.undoing=!0,this.set(r)},e.prototype.isRecording=function(){return!!this.archive},e.prototype.hasHistory=function(){return!(!this.archive||!this.archive.get().length)},e.prototype.getHistory=function(){return this.archive?this.archive.get():[]},e.prototype.release=function(){this.tree.off("update",this.updateHandler),this.hash&&delete this.tree._cursors[this.hash],delete this.tree,delete this.path,delete this.solvedPath,delete this.archive,this.kill()},e.prototype.toJSON=function(){return this.get()},u.Cursor=function(t){return t instanceof e},r.exports=e},{"../defaults.js":2,"./helpers.js":6,"./mixins.js":8,"./type.js":9,emmett:3}],6:[function(t,r){(function(e){function n(t){return Array.prototype.slice.call(t)}function i(t,r){return function(){t(),r.apply(null,arguments)}}function o(t,r){var e,n={};for(e in t)n[e]=t[e];for(e in r)n[e]=r[e];return n}function s(t){var r=t.source,e="";return t.global&&(e+="g"),t.multiline&&(e+="m"),t.ignoreCase&&(e+="i"),t.sticky&&(e+="y"),t.unicode&&(e+="u"),new RegExp(r,e)}function a(t,r){if(!r||"object"!=typeof r||r instanceof Error||"ArrayBuffer"in e&&r instanceof ArrayBuffer)return r;if(j.Array(r)){if(t){var n,i,o=[];for(n=0,i=r.length;i>n;n++)o.push($(r[n]));return o}return r.slice(0)}if(j.Date(r))return new Date(r.getTime());if(r instanceof RegExp)return s(r);if(j.Object(r)){var a,u={};r.constructor&&r.constructor!==Object&&(u=Object.create(r.constructor.prototype));for(a in r)r.hasOwnProperty(a)&&(u[a]=t?$(r[a]):r[a]);return u}return r}function u(t,r){return function(e){return r(t(e))}}function h(t,r){var e,n;for(e=0,n=t.length;n>e;e++)if(r(t[e]))return t[e]}function c(t,r){var e,n;for(e=0,n=t.length;n>e;e++)if(r(t[e]))return e;return-1}function l(t,r){var e,n=!0;if(!t)return!1;for(e in r)if(j.Object(r[e]))n=n&&l(t[e],r[e]);else if(j.Array(r[e]))n=n&&!!~r[e].indexOf(t[e]);else if(t[e]!==r[e])return!1;return n}function f(t,r){return h(t,function(t){return l(t,r)})}function d(t,r){return c(t,function(t){return l(t,r)})}function y(t,r,e){r=r||[];var n,i,o,s=t;for(i=0,o=r.length;o>i;i++){if(!s)return;if("function"==typeof r[i]){if(!j.Array(s))return;s=h(s,r[i])}else if("object"==typeof r[i])if(e&&"$cursor"in r[i]){if(!j.Path(r[i].$cursor))throw Error("baobab.getIn: $cursor path must be an array.");n=e.get(r[i].$cursor),s=s[n]}else{if(!j.Array(s))return;s=f(s,r[i])}else s=s[r[i]]}return s}function g(t,r,e){var n,i,o,s=[],a=t;for(i=0,o=r.length;o>i;i++){if(!a)return null;if("function"==typeof r[i]){if(!j.Array(a))return;n=c(a,r[i]),s.push(n),a=a[n]}else if("object"==typeof r[i])if(e&&"$cursor"in r[i]){if(!j.Path(r[i].$cursor))throw Error("baobab.getIn: $cursor path must be an array.");p=e.get(r[i].$cursor),s.push(p),a=a[p]}else{if(!j.Array(a))return;n=d(a,r[i]),s.push(n),a=a[n]}else s.push(r[i]),a=a[r[i]]||{}}return s}function b(t,r){var e,n,i,o,s,a,u,h,c;for(e=0,o=r.length;o>e;e++)for(u=r[e],n=0,s=t.length;s>n;n++)for(h=t[n],i=0,a=h.length;a>i&&(c=h[i],c==u[i]);i++)if(i+1===a||i+1===u.length)return!0;return!1}function v(t,r){var e,n=t.length,i={},o=i;for(n||(i=r),e=0;n>e;e++)o[t[e]]=e+1===n?r:{},o=o[t[e]];return i}function m(t,r){t.super_=r;var e=function(){};e.prototype=r.prototype,t.prototype=new e,t.prototype.constructor=t}function _(t){var r=[];return{add:function(e){for(r.unshift(e);r.length>t;)r.pop()},back:function(t){var e=r[t-1];return e&&(r=r.slice(t)),e},get:function(){return r}}}var j=t("./type.js"),w=a.bind(null,!1),$=a.bind(null,!0);r.exports={archive:_,arrayOf:n,before:i,deepClone:$,shallowClone:w,shallowMerge:o,compose:u,getIn:y,inherits:m,pathObject:v,solvePath:g,solveUpdate:b}}).call(this,"undefined"!=typeof global?global:"undefined"!=typeof self?self:"undefined"!=typeof window?window:{})},{"./type.js":9}],7:[function(t,r){function e(t,r,e){s.forEach(function(r){e!==r&&delete t[r]}),t[e]=r[e]}function n(t,r){var a,u=i.shallowClone(r||{});s.forEach(function(r){t[r]&&e(u,t,r)}),t.$chain&&(s.slice(0,-1).forEach(function(t){delete u[t]}),u.$apply=u.$apply?i.compose(u.$apply,t.$chain):t.$chain),t.$push&&u.$push?u.$push=o.Array(u.$push)?u.$push.concat(t.$push):[u.$push].concat(t.$push):t.$push&&(u.$push=t.$push),t.$unshift&&u.$unshift?u.$unshift=o.Array(t.$unshift)?t.$unshift.concat(u.$unshift):[t.$unshift].concat(u.$unshift):t.$unshift&&(u.$unshift=t.$unshift);for(a in t)o.Object(t[a])?u[a]=n(t[a],u[a]):"$"!==a[0]&&(u[a]=t[a]);return u}var i=t("./helpers.js"),o=t("./type.js"),s=["$unset","$set","$merge","$apply"];r.exports=n},{"./helpers.js":6,"./type.js":9}],8:[function(t,r){var e=t("./type.js");r.exports={baobab:function(t){return{mixins:[{getInitialState:function(){if(this.tree=t,!this.cursor&&!this.cursors)return{};if(this.cursor&&this.cursors)throw Error("baobab.mixin: you cannot have both `component.cursor` and `component.cursors`. Please make up your mind.");if(this.__type=null,this.__updateHandler=function(){this.setState(this.__getCursorData())}.bind(this),this.cursor){if(!e.MixinCursor(this.cursor))throw Error("baobab.mixin.cursor: invalid data (cursor, string, array or function).");e.Function(this.cursor)&&(this.cursor=this.cursor()),e.Cursor(this.cursor)||(this.cursor=t.select(this.cursor)),this.__getCursorData=function(){return{cursor:this.cursor.get()}}.bind(this),this.__type="single"}else if(this.cursors){if(!e.MixinCursors(this.cursors))throw Error("baobab.mixin.cursor: invalid data (object, array or function).");if(e.Function(this.cursors)&&(this.cursors=this.cursors()),e.Array(this.cursors))this.cursors=this.cursors.map(function(r){return e.Cursor(r)?r:t.select(r)}),this.__getCursorData=function(){return{cursors:this.cursors.map(function(t){return t.get()})}}.bind(this),this.__type="array";else{for(var r in this.cursors)e.Cursor(this.cursors[r])||(this.cursors[r]=t.select(this.cursors[r]));this.__getCursorData=function(){var t={};for(r in this.cursors)t[r]=this.cursors[r].get();return{cursors:t}}.bind(this),this.__type="object"}}return this.__getCursorData()},componentDidMount:function(){"single"===this.__type?(this.__watcher=this.tree.watch([this.cursor.path]),this.__watcher.on("update",this.__updateHandler)):"array"===this.__type?(this.__watcher=this.tree.watch(this.cursors.map(function(t){return t.path})),this.__watcher.on("update",this.__updateHandler)):"object"===this.__type&&(this.__watcher=this.tree.watch(Object.keys(this.cursors).map(function(t){return this.cursors[t].path},this)),this.__watcher.on("update",this.__updateHandler))},componentWillUnmount:function(){this.__watcher&&this.__watcher.release()}}].concat(t.options.mixins)}},cursor:function(t){return{mixins:[{getInitialState:function(){return this.cursor=t,this.__updateHandler=function(){this.setState({cursor:this.cursor.get()})}.bind(this),{cursor:this.cursor.get()}},componentDidMount:function(){this.cursor.on("update",this.__updateHandler)},componentWillUnmount:function(){this.cursor.off("update",this.__updateHandler)}}].concat(t.tree.options.mixins)}}}},{"./type.js":9}],9:[function(t,r){function e(t,r){return r.some(function(r){return n[r](t)})}var n={};n.Array=function(t){return Array.isArray(t)},n.Object=function(t){return t&&"object"==typeof t&&!Array.isArray(t)&&!(t instanceof Function)},n.String=function(t){return"string"==typeof t},n.Number=function(t){return"number"==typeof t},n.PositiveInteger=function(t){return"number"==typeof t&&t>0&&!(t%1)},n.Function=function(t){return"function"==typeof t},n.Primitive=function(t){return"string"==typeof t||"number"==typeof t||"boolean"==typeof t},n.Date=function(t){return t instanceof Date},n.NonScalar=function(t){return n.Object(t)||n.Array(t)},n.Path=function(t){var r=["String","Number","Function","Object"];return n.Array(t)?t.every(function(t){return e(t,r)}):e(t,r)},n.MixinCursor=function(t){return e(t,["String","Number","Array","Function","Cursor"])},n.MixinCursors=function(t){return e(t,["Object","Array","Function"])},n.ComplexPath=function(t){return t.some(function(t){return e(t,["Object","Function"])})},r.exports=n},{}],10:[function(t,r){function e(t,r){var e=new Error("baobab.update: "+r+" at path /"+t.slice(1).join("/"));return e.path=t,e}var n=t("./helpers.js"),i=t("./type.js");r.exports=function(t,r,o){if(o=o||{},!i.Object(t)&&!i.Array(t))throw Error("baobab.update: invalid target.");var s={};t={root:n.shallowClone(t)};var a=function(t,r,o,u){o=o||["root"];var h,c,l,f=o.join("|λ|"),p=o[o.length-1],d=Object.keys(r).some(function(t){return!!~["$unset","$set","$apply","$merge","$push","$unshift"].indexOf(t)});if(d){s[f]=!0;for(c in r){if("$unset"===c){var y=o[o.length-2];i.Array(t)?u[y]=t.slice(0,+p).concat(t.slice(+p+1)):(u[y]=n.shallowClone(t),delete u[y][p]);break}if("$set"===c){l=r.$set,t[p]=l;break}if("$apply"===c){if(h=r.$apply,"function"!=typeof h)throw e(o,"using command $apply with a non function");t[p]=h.call(null,t[p]);break}if("$merge"===c){if(l=r.$merge,!i.Object(t[p])||!i.Object(l))throw e(o,"using command $merge with a non object");t[p]=n.shallowMerge(t[p],l);break}if("$push"===c){if(l=r.$push,!i.Array(t[p]))throw e(o,"using command $push to a non array");t[p]=t[p].concat(l)}if("$unshift"===c){if(l=r.$unshift,!i.Array(t[p]))throw e(o,"using command $unshift to a non array");t[p]=[].concat(l).concat(t[p])}}}else for(c in r)t[p][c]="undefined"==typeof t[p][c]?{}:n.shallowClone(t[p][c]),a(t[p],r[c],o.concat(c),t)};return a(t,r),{data:t.root,log:Object.keys(s).map(function(t){return t.split("|λ|").slice(1)})}}},{"./helpers.js":6,"./type.js":9}],11:[function(t,r){function e(t,r){function e(){u&&(a=r.map(function(t){return i.solvePath(s.tree.data,t,s.tree)}))}var s=this;n.call(this),this.tree=t;var a=r,u=r.some(o.ComplexPath);this.updateHandler=function(t){var r=i.solveUpdate(t.data.log,a);r&&s.emit("update")},e(),this.tree.on("update",this.updateHandler)}var n=t("emmett"),i=t("./helpers.js"),o=t("./type.js");i.inherits(e,n),e.prototype.release=function(){this.tree.off("update",this.updateHandler),this.tree=null,this.kill()},r.exports=e},{"./helpers.js":6,"./type.js":9,emmett:3}]},{},[1])(1)}); \ No newline at end of file +!function(t){if("object"==typeof exports&&"undefined"!=typeof module)module.exports=t();else if("function"==typeof define&&define.amd)define([],t);else{var r;r="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:this,r.Baobab=t()}}(function(){var t;return function r(t,e,n){function i(s,a){if(!e[s]){if(!t[s]){var u="function"==typeof require&&require;if(!a&&u)return u(s,!0);if(o)return o(s,!0);var h=new Error("Cannot find module '"+s+"'");throw h.code="MODULE_NOT_FOUND",h}var c=e[s]={exports:{}};t[s][0].call(c.exports,function(r){var e=t[s][1][r];return i(e?e:r)},c,c.exports,r,t,e,n)}return e[s].exports}for(var o="function"==typeof require&&require,s=0;sn;n++)t[n].fn!==r&&i.push(t[n]);return i}var s={once:"boolean",scope:"object"},a=0,u=function(){this._enabled=!0,this.unbindAll()};u.prototype.unbindAll=function(){return this._handlers={},this._handlersAll=[],this._handlersComplex=[],this},u.prototype.on=function(t,r,e){var n,o,u,h,c,l,f;if(i(t)){for(h in t)this.on(h,t[h],r);return this}for("function"==typeof t&&(e=r,r=t,t=null),c=[].concat(t),n=0,o=c.length;o>n;n++){if(h=c[n],f={order:a++,fn:r},"string"==typeof h)this._handlers[h]||(this._handlers[h]=[]),l=this._handlers[h];else if(h instanceof RegExp)l=this._handlersComplex,f.pattern=h;else{if(null!==h)throw Error("Emitter.on: invalid event.");l=this._handlersAll}for(u in e||{})s[u]&&(f[u]=e[u]);f.once&&(f.parent=l),l.push(f)}return this},u.prototype.once=function(){var t=Array.prototype.slice.call(arguments),e=t.length-1;return i(t[e])&&t.length>1?t[e]=r(t[e],{once:!0}):t.push({once:!0}),this.on.apply(this,t)},u.prototype.off=function(t,r){var e,n,s,a;if(1===arguments.length&&"function"==typeof t){r=arguments[0];for(s in this._handlers)this._handlers[s]=o(this._handlers[s],r),0===this._handlers[s].length&&delete this._handlers[s];this._handlersAll=o(this._handlersAll,r),this._handlersComplex=o(this._handlersComplex,r)}else if(1===arguments.length&&"string"==typeof t)delete this._handlers[t];else if(2===arguments.length){var u=[].concat(t);for(e=0,n=u.length;n>e;e++)a=u[e],this._handlers[a]=o(this._handlers[a],r),0===(this._handlers[a]||[]).length&&delete this._handlers[a]}else if(i(t))for(s in t)this.off(s,t[s]);return this},u.prototype.listeners=function(t){var r,e,n,i=this._handlersAll||[],o=!1;if(!t)throw Error("Emitter.listeners: no event provided.");for(i=i.concat(this._handlers[t]||[]),e=0,n=this._handlersComplex.length;n>e;e++)r=this._handlersComplex[e],~t.search(r.pattern)&&(o=!0,i.push(r));return this._handlersAll.length||o?i.sort(function(t,r){return t.order-r.order}):i.slice(0)},u.prototype.emit=function(t,r){if(!this._enabled)return this;if(i(t)){for(var e in t)this.emit(e,t[e]);return this}var n,o,s,a,u,h,c,l=[].concat(t),f=[];for(a=0,h=l.length;h>a;a++){for(o=this.listeners(l[a]),u=0,c=o.length;c>u;u++)s=o[u],n={type:l[a],target:this},arguments.length>1&&(n.data=r),s.fn.call("scope"in s?s.scope:this,n),s.once&&f.push(s);for(u=f.length-1;u>=0;u--)f[u].parent.splice(f[u].parent.indexOf(f[u]),1)}return this},u.prototype.kill=function(){this.unbindAll(),this._handlers=null,this._handlersAll=null,this._handlersComplex=null,this._enabled=!1},u.prototype.disable=function(){return this._enabled=!1,this},u.prototype.enable=function(){return this._enabled=!0,this},u.version="3.0.0","undefined"!=typeof n?("undefined"!=typeof e&&e.exports&&(n=e.exports=u),n.Emitter=u):"function"==typeof t&&t.amd?t("emmett",[],function(){return u}):this.Emitter=u}).call(this)},{}],4:[function(t,r,e){function n(t){return t+"$"+(new Date).getTime()+(""+Math.random()).replace("0.","")}function i(t,r){function e(t){this[t]=function(){var r=this.root[t].apply(this.root,arguments);return r instanceof o?this:r}}if(arguments.length<1&&(t={}),!(this instanceof i))return new i(t,r);if(!d.Object(t)&&!d.Array(t))throw Error("Baobab: invalid data.");if(s.call(this),this.options=h.shallowMerge(p,r),this._transaction={},this._future=void 0,this._cursors={},this.data=h.deepClone(t),this.root=this.select([]),this.facets={},["get","set","unset","update"].forEach(e.bind(this)),!d.Object(this.options.facets))throw Error("Baobab: invalid facets.");for(var n in this.options.facets)this.addFacet(n,this.options.facets[n]);this.mixin=f.baobab(this)}var o=t("./cursor.js"),s=t("emmett"),a=t("./watcher.js"),u=t("./facet.js"),h=t("./helpers.js"),c=t("./update.js"),l=t("./merge.js"),f=t("./mixins.js"),p=t("../defaults.js"),d=t("./type.js");h.inherits(i,s),i.prototype.addFacet=function(t,r){return this.facets[t]=new u(this,r),this},i.prototype.select=function(t){if(!t)throw Error("Baobab.select: invalid path.");if(arguments.length>1&&(t=h.arrayOf(arguments)),!d.Path(t))throw Error("Baobab.select: invalid path.");t=[].concat(t);var r,e=d.ComplexPath(t);e&&(r=h.solvePath(this.data,t,this));var i=t.map(function(t){return d.Function(t)?n("fn"):d.Object(t)?n("ob"):t}).join("|λ|");if(this._cursors[i])return this._cursors[i];var s=new o(this,t,r,i);return this._cursors[i]=s,s},i.prototype.stack=function(t){var r=this;if(!d.Object(t))throw Error("Baobab.update: wrong specification.");return this._transaction=l(t,this._transaction),this.options.autoCommit?this.options.asynchronous?(this._future||(this._future=setTimeout(r.commit.bind(r,null),0)),this):this.commit():this},i.prototype.commit=function(){var t=c(this.data,this._transaction,this.options),r=this.data;return this.data=t.data,this._transaction={},this._future&&(this._future=clearTimeout(this._future)),this.emit("update",{log:t.log,previousState:r}),this},i.prototype.watch=function(t){if(!d.Array(t)||t.some(function(t){return!d.Path(t)}))throw Error("Baobab.watch: invalid paths.");return new a(this,[].concat(t))},i.prototype.release=function(){var t;delete this.data,delete this._transaction;for(t in this._cursors)this._cursors[t].release();delete this._cursors;for(t in this.facets)this.facets[t].release();delete this.facets,this.kill()},i.prototype.toJSON=function(){return this.get()},r.exports=i},{"../defaults.js":2,"./cursor.js":5,"./facet.js":6,"./helpers.js":7,"./merge.js":8,"./mixins.js":9,"./type.js":10,"./update.js":11,"./watcher.js":12,emmett:3}],5:[function(t,r,e){function n(t,r,e,n){function i(t){if(o.isRecording()&&!o.undoing){var r=u.getIn(t,o.solvedPath,o.tree),e=u.deepClone(r);o.archive.add(e)}return o.undoing=!1,o.emit("update")}var o=this;s.call(this),r=r||[],this.tree=t,this.path=r,this.hash=n,this.archive=null,this.undoing=!1,this.complexPath=!!e,this.solvedPath=this.complexPath?e:this.path,this.relevant=void 0!==this.get(),this.updateHandler=function(t){var r=t.data.log,e=t.data.previousState,n=!1;if(o.complexPath&&(o.solvedPath=u.solvePath(o.tree.data,o.path,o.tree)),!o.path.length)return i(e);o.solvedPath&&(n=u.solveUpdate(r,[o.solvedPath]));var s=void 0!==o.get();o.relevant?s&&n?i(e):s||(o.emit("irrelevant"),o.relevant=!1):s&&n&&(o.emit("relevant"),i(e),o.relevant=!0)},this.mixin=a.cursor(this);var h=!1;this._lazyBind=function(){h||(h=!0,o.tree.on("update",o.updateHandler))},this.on=u.before(this._lazyBind,this.on.bind(this)),this.once=u.before(this._lazyBind,this.once.bind(this)),this.complexPath&&this._lazyBind()}function i(t,r,e,n){if(arguments.length>5)throw Error("baobab.Cursor."+t+": too many arguments.");arguments.length<4&&(n=e,e=[]),e=e||[];var i=[].concat(e),o=u.solvePath(this.get(),i,this.tree);if(!o)throw Error("baobab.Cursor."+t+": could not solve dynamic path.");if(r){var s=this.get(o);if(!h[r](s))throw Error("baobab.Cursor."+t+": invalid target.")}var a={};a["$"+t]=n;var c=u.pathObject(o,a);return c}function o(t,r){n.prototype[t]=function(){var e=i.bind(this,t,r).apply(this,arguments);return this.update(e)}}var s=t("emmett"),a=t("./mixins.js"),u=t("./helpers.js"),h=(t("../defaults.js"),t("./type.js"));u.inherits(n,s),n.prototype.isRoot=function(){return!this.path.length},n.prototype.isLeaf=function(){return h.Primitive(this.get())},n.prototype.isBranch=function(){return!this.isLeaf()&&!this.isRoot()},n.prototype.root=function(){return this.tree.root()},n.prototype.select=function(t){if(arguments.length>1&&(t=u.arrayOf(arguments)),!h.Path(t))throw Error("baobab.Cursor.select: invalid path.");return this.tree.select(this.path.concat(t))},n.prototype.up=function(){return this.solvedPath&&this.solvedPath.length?this.tree.select(this.path.slice(0,-1)):null},n.prototype.left=function(){var t=+this.solvedPath[this.solvedPath.length-1];if(isNaN(t))throw Error("baobab.Cursor.left: cannot go left on a non-list type.");return t?this.tree.select(this.solvedPath.slice(0,-1).concat(t-1)):null},n.prototype.leftmost=function(){var t=+this.solvedPath[this.solvedPath.length-1];if(isNaN(t))throw Error("baobab.Cursor.leftmost: cannot go left on a non-list type.");return this.tree.select(this.solvedPath.slice(0,-1).concat(0))},n.prototype.right=function(){var t=+this.solvedPath[this.solvedPath.length-1];if(isNaN(t))throw Error("baobab.Cursor.right: cannot go right on a non-list type.");return t+1===this.up().get().length?null:this.tree.select(this.solvedPath.slice(0,-1).concat(t+1))},n.prototype.rightmost=function(){var t=+this.solvedPath[this.solvedPath.length-1];if(isNaN(t))throw Error("baobab.Cursor.right: cannot go right on a non-list type.");var r=this.up().get();return this.tree.select(this.solvedPath.slice(0,-1).concat(r.length-1))},n.prototype.down=function(){+this.solvedPath[this.solvedPath.length-1];return this.get()instanceof Array?this.tree.select(this.solvedPath.concat(0)):null},n.prototype.get=function(t){arguments.length>1&&(t=u.arrayOf(arguments));var r=this.solvedPath.concat([].concat(t||0===t?t:[]));return u.getIn(this.tree.data,r,this.tree)},o("set"),o("apply"),o("chain"),o("push","Array"),o("unshift","Array"),n.prototype.merge=function(t){if(!h.Object(t))throw Error("baobab.Cursor.merge: trying to merge a non-object.");var r=i.bind(this,"merge","Object").apply(this,arguments);return this.update(r)},n.prototype.unset=function(t){if(void 0===t&&this.isRoot())throw Error("baobab.Cursor.unset: cannot remove root node.");var r=i.bind(this,"unset",null).apply(this,[t,!0]);return this.update(r)},n.prototype.update=function(t,r){if(arguments.length<2)return this.tree.stack(u.pathObject(this.solvedPath,t)),this;var e=[].concat(t),n=u.solvePath(this.get(),e,this.tree);if(!n)throw Error("baobab.Cursor.update: could not solve dynamic path.");return this.tree.stack(u.pathObject(this.solvedPath.concat(n),r)),this},n.prototype.startRecording=function(t){if(t=t||5,1>t)throw Error("baobab.Cursor.startRecording: invalid maximum number of records.");return this.archive?this:(this._lazyBind(),this.archive=u.archive(t),this)},n.prototype.stopRecording=function(){return this.archive=null,this},n.prototype.undo=function(t){if(t=t||1,!this.isRecording())throw Error("baobab.Cursor.undo: cursor is not recording.");if(!h.PositiveInteger(t))throw Error("baobab.Cursor.undo: expecting a positive integer.");var r=this.archive.back(t);if(!r)throw Error("boabab.Cursor.undo: cannot find a relevant record ("+t+" back).");return this.undoing=!0,this.set(r)},n.prototype.isRecording=function(){return!!this.archive},n.prototype.hasHistory=function(){return!(!this.archive||!this.archive.get().length)},n.prototype.getHistory=function(){return this.archive?this.archive.get():[]},n.prototype.release=function(){this.tree.off("update",this.updateHandler),this.hash&&delete this.tree._cursors[this.hash],delete this.tree,delete this.path,delete this.solvedPath,delete this.archive,this.kill()},n.prototype.toJSON=function(){return this.get()},h.Cursor=function(t){return t instanceof n},r.exports=n},{"../defaults.js":2,"./helpers.js":7,"./mixins.js":9,"./type.js":10,emmett:3}],6:[function(t,r,e){function n(t){return t}function i(t,r){function e(t){i[t]=l[t].bind(l)}var i=this,s=null,a=!1,u=r.get||n,h=r.cursors,c=Object.keys(h).map(function(t){return h[t]}),l=new o(t,c);["on","once","release"].forEach(e),this.get=function(){if(a)return s;var r={};for(var e in h)r[e]=t.get(h[e]);return s=u.call(null,r),a=!0,s},this.on("update",function(){a=!1})}{var o=t("./watcher.js");t("./helpers.js")}r.exports=i},{"./helpers.js":7,"./watcher.js":12}],7:[function(t,r,e){(function(e){function n(t){return Array.prototype.slice.call(t)}function i(t,r){return function(){t(),r.apply(null,arguments)}}function o(t,r){var e,n={};for(e in t)n[e]=t[e];for(e in r)n[e]=r[e];return n}function s(t,r){if(t===r)return!0;if("object"!=typeof t||"object"!=typeof r||null===t||null===r)return!1;var e=Object.keys(t),n=Object.keys(r);if(e.length!==n.length)return!1;var i,o;for(i=0,o=e.length;o>i;i++)if(t[e[i]]!==r[e[i]])return!1;return!0}function a(t){var r=t.source,e="";return t.global&&(e+="g"),t.multiline&&(e+="m"),t.ignoreCase&&(e+="i"),t.sticky&&(e+="y"),t.unicode&&(e+="u"),new RegExp(r,e)}function u(t,r){if(!r||"object"!=typeof r||r instanceof Error||"ArrayBuffer"in e&&r instanceof ArrayBuffer)return r;if(w.Array(r)){if(t){var n,i,o=[];for(n=0,i=r.length;i>n;n++)o.push(x(r[n]));return o}return r.slice(0)}if(w.Date(r))return new Date(r.getTime());if(r instanceof RegExp)return a(r);if(w.Object(r)){var s,u={};r.constructor&&r.constructor!==Object&&(u=Object.create(r.constructor.prototype));for(s in r)r.hasOwnProperty(s)&&(u[s]=t?x(r[s]):r[s]);return u}return r}function h(t,r){return function(e){return r(t(e))}}function c(t,r){var e,n;for(e=0,n=t.length;n>e;e++)if(r(t[e]))return t[e]}function l(t,r){var e,n;for(e=0,n=t.length;n>e;e++)if(r(t[e]))return e;return-1}function f(t,r){var e,n=!0;if(!t)return!1;for(e in r)if(w.Object(r[e]))n=n&&f(t[e],r[e]);else if(w.Array(r[e]))n=n&&!!~r[e].indexOf(t[e]);else if(t[e]!==r[e])return!1;return n}function d(t,r){return c(t,function(t){return f(t,r)})}function y(t,r){return l(t,function(t){return f(t,r)})}function b(t,r,e){r=r||[];var n,i,o,s=t;for(i=0,o=r.length;o>i;i++){if(!s)return;if("function"==typeof r[i]){if(!w.Array(s))return;s=c(s,r[i])}else if("object"==typeof r[i])if(e&&"$cursor"in r[i]){if(!w.Path(r[i].$cursor))throw Error("baobab.getIn: $cursor path must be an array.");n=e.get(r[i].$cursor),s=s[n]}else{if(!w.Array(s))return;s=d(s,r[i])}else s=s[r[i]]}return s}function g(t,r,e){var n,i,o,s=[],a=t;for(i=0,o=r.length;o>i;i++){if(!a)return null;if("function"==typeof r[i]){if(!w.Array(a))return;n=l(a,r[i]),s.push(n),a=a[n]}else if("object"==typeof r[i])if(e&&"$cursor"in r[i]){if(!w.Path(r[i].$cursor))throw Error("baobab.getIn: $cursor path must be an array.");p=e.get(r[i].$cursor),s.push(p),a=a[p]}else{if(!w.Array(a))return;n=y(a,r[i]),s.push(n),a=a[n]}else s.push(r[i]),a=a[r[i]]||{}}return s}function v(t,r){var e,n,i,o,s,a,u,h,c;for(e=0,o=r.length;o>e;e++)for(u=r[e],n=0,s=t.length;s>n;n++)for(h=t[n],i=0,a=h.length;a>i&&(c=h[i],c==u[i]);i++)if(i+1===a||i+1===u.length)return!0;return!1}function m(t,r){var e,n=t.length,i={},o=i;for(n||(i=r),e=0;n>e;e++)o[t[e]]=e+1===n?r:{},o=o[t[e]];return i}function _(t,r){t.super_=r;var e=function(){};e.prototype=r.prototype,t.prototype=new e,t.prototype.constructor=t}function j(t){var r=[];return{add:function(e){for(r.unshift(e);r.length>t;)r.pop()},back:function(t){var e=r[t-1];return e&&(r=r.slice(t)),e},get:function(){return r}}}var w=t("./type.js"),$=u.bind(null,!1),x=u.bind(null,!0);r.exports={archive:j,arrayOf:n,before:i,deepClone:x,shallowClone:$,shallowEqual:s,shallowMerge:o,compose:h,getIn:b,inherits:_,pathObject:m,solvePath:g,solveUpdate:v}}).call(this,"undefined"!=typeof global?global:"undefined"!=typeof self?self:"undefined"!=typeof window?window:{})},{"./type.js":10}],8:[function(t,r,e){function n(t,r,e){a.forEach(function(r){e!==r&&delete t[r]}),t[e]=r[e]}function i(t,r){var e,u=o.shallowClone(r||{});a.forEach(function(r){t[r]&&n(u,t,r)}),t.$chain&&(a.slice(0,-1).forEach(function(t){delete u[t]}),u.$apply=u.$apply?o.compose(u.$apply,t.$chain):t.$chain),t.$push&&u.$push?u.$push=s.Array(u.$push)?u.$push.concat(t.$push):[u.$push].concat(t.$push):t.$push&&(u.$push=t.$push),t.$unshift&&u.$unshift?u.$unshift=s.Array(t.$unshift)?t.$unshift.concat(u.$unshift):[t.$unshift].concat(u.$unshift):t.$unshift&&(u.$unshift=t.$unshift);for(e in t)s.Object(t[e])?u[e]=i(t[e],u[e]):"$"!==e[0]&&(u[e]=t[e]);return u}var o=t("./helpers.js"),s=t("./type.js"),a=["$unset","$set","$merge","$apply"];r.exports=i},{"./helpers.js":7,"./type.js":10}],9:[function(t,r,e){var n=t("./type.js");r.exports={baobab:function(t){return{mixins:[{getInitialState:function(){if(this.tree=t,!this.cursor&&!this.cursors)return{};if(this.cursor&&this.cursors)throw Error("baobab.mixin: you cannot have both `component.cursor` and `component.cursors`. Please make up your mind.");if(this.__type=null,this.__updateHandler=function(){this.setState(this.__getCursorData())}.bind(this),this.cursor){if(!n.MixinCursor(this.cursor))throw Error("baobab.mixin.cursor: invalid data (cursor, string, array or function).");n.Function(this.cursor)&&(this.cursor=this.cursor()),n.Cursor(this.cursor)||(this.cursor=t.select(this.cursor)),this.__getCursorData=function(){return{cursor:this.cursor.get()}}.bind(this),this.__type="single"}else if(this.cursors){if(!n.MixinCursors(this.cursors))throw Error("baobab.mixin.cursor: invalid data (object, array or function).");if(n.Function(this.cursors)&&(this.cursors=this.cursors()),n.Array(this.cursors))this.cursors=this.cursors.map(function(r){return n.Cursor(r)?r:t.select(r)}),this.__getCursorData=function(){return{cursors:this.cursors.map(function(t){return t.get()})}}.bind(this),this.__type="array";else{for(var r in this.cursors)n.Cursor(this.cursors[r])||(this.cursors[r]=t.select(this.cursors[r]));this.__getCursorData=function(){var t={};for(r in this.cursors)t[r]=this.cursors[r].get();return{cursors:t}}.bind(this),this.__type="object"}}return this.__getCursorData()},componentDidMount:function(){"single"===this.__type?(this.__watcher=this.tree.watch([this.cursor.path]),this.__watcher.on("update",this.__updateHandler)):"array"===this.__type?(this.__watcher=this.tree.watch(this.cursors.map(function(t){return t.path})),this.__watcher.on("update",this.__updateHandler)):"object"===this.__type&&(this.__watcher=this.tree.watch(Object.keys(this.cursors).map(function(t){return this.cursors[t].path},this)),this.__watcher.on("update",this.__updateHandler))},componentWillUnmount:function(){this.__watcher&&this.__watcher.release()}}].concat(t.options.mixins)}},cursor:function(t){return{mixins:[{getInitialState:function(){return this.cursor=t,this.__updateHandler=function(){this.setState({cursor:this.cursor.get()})}.bind(this),{cursor:this.cursor.get()}},componentDidMount:function(){this.cursor.on("update",this.__updateHandler)},componentWillUnmount:function(){this.cursor.off("update",this.__updateHandler)}}].concat(t.tree.options.mixins)}}}},{"./type.js":10}],10:[function(t,r,e){function n(t,r){return r.some(function(r){return i[r](t)})}var i={};i.Array=function(t){return Array.isArray(t)},i.Object=function(t){return t&&"object"==typeof t&&!Array.isArray(t)&&!(t instanceof Function)},i.String=function(t){return"string"==typeof t},i.Number=function(t){return"number"==typeof t},i.PositiveInteger=function(t){return"number"==typeof t&&t>0&&t%1===0},i.Function=function(t){return"function"==typeof t},i.Primitive=function(t){return"string"==typeof t||"number"==typeof t||"boolean"==typeof t},i.Date=function(t){return t instanceof Date},i.NonScalar=function(t){return i.Object(t)||i.Array(t)},i.Path=function(t){var r=["String","Number","Function","Object"];return i.Array(t)?t.every(function(t){return n(t,r)}):n(t,r)},i.MixinCursor=function(t){return n(t,["String","Number","Array","Function","Cursor"])},i.MixinCursors=function(t){return n(t,["Object","Array","Function"])},i.ComplexPath=function(t){return t.some(function(t){return n(t,["Object","Function"])})},r.exports=i},{}],11:[function(t,r,e){function n(t,r){var e=new Error("baobab.update: "+r+" at path /"+t.slice(1).join("/"));return e.path=t,e}var i=t("./helpers.js"),o=t("./type.js");r.exports=function(t,r,e){if(e=e||{},!o.Object(t)&&!o.Array(t))throw Error("baobab.update: invalid target.");var s={};t={root:i.shallowClone(t)};var a=function(t,r,e,u){e=e||["root"];var h,c,l,f=e.join("|λ|"),p=e[e.length-1],d=Object.keys(r).some(function(t){return!!~["$unset","$set","$apply","$merge","$push","$unshift"].indexOf(t)});if(d){s[f]=!0;for(c in r){if("$unset"===c){var y=e[e.length-2];o.Array(t)?u[y]=t.slice(0,+p).concat(t.slice(+p+1)):(u[y]=i.shallowClone(t),delete u[y][p]);break}if("$set"===c){l=r.$set,t[p]=l;break}if("$apply"===c){if(h=r.$apply,"function"!=typeof h)throw n(e,"using command $apply with a non function");t[p]=h.call(null,t[p]);break}if("$merge"===c){if(l=r.$merge,!o.Object(t[p])||!o.Object(l))throw n(e,"using command $merge with a non object");t[p]=i.shallowMerge(t[p],l);break}if("$push"===c){if(l=r.$push,!o.Array(t[p]))throw n(e,"using command $push to a non array");t[p]=t[p].concat(l)}if("$unshift"===c){if(l=r.$unshift,!o.Array(t[p]))throw n(e,"using command $unshift to a non array");t[p]=[].concat(l).concat(t[p])}}}else for(c in r)t[p][c]="undefined"==typeof t[p][c]?{}:i.shallowClone(t[p][c]),a(t[p],r[c],e.concat(c),t)};return a(t,r),{data:t.root,log:Object.keys(s).map(function(t){return t.split("|λ|").slice(1)})}}},{"./helpers.js":7,"./type.js":10}],12:[function(t,r,e){function n(t,r){function e(){u&&(a=r.map(function(t){return o.solvePath(n.tree.data,t,n.tree)}))}var n=this;i.call(this),this.tree=t;var a=r,u=r.some(s.ComplexPath);this.updateHandler=function(t){var r=o.solveUpdate(t.data.log,a);r&&n.emit("update")},e(),this.tree.on("update",this.updateHandler)}var i=t("emmett"),o=t("./helpers.js"),s=t("./type.js");o.inherits(n,i),n.prototype.release=function(){this.tree.off("update",this.updateHandler),this.tree=null,this.kill()},r.exports=n},{"./helpers.js":7,"./type.js":10,emmett:3}]},{},[1])(1)}); \ No newline at end of file diff --git a/package.json b/package.json index 8c61957..ee575ab 100644 --- a/package.json +++ b/package.json @@ -16,7 +16,7 @@ "gulp-replace": "^0.5.3", "gulp-uglify": "^1.0.2", "jsdom": "^3.1.0", - "lodash.clonedeep": "^3.0.0", + "lodash": "^3.6.0", "mocha": "^2.0.1", "react": "^0.13.0", "vinyl-buffer": "^1.0.0", diff --git a/src/baobab.js b/src/baobab.js index 946251b..ebd092e 100644 --- a/src/baobab.js +++ b/src/baobab.js @@ -77,7 +77,7 @@ helpers.inherits(Baobab, EventEmitter); * Prototype */ Baobab.prototype.addFacet = function(name, definition) { - this.facets[name] = new Facet(tree, definition); + this.facets[name] = new Facet(this, definition); return this; }; @@ -180,15 +180,21 @@ Baobab.prototype.watch = function(paths) { }; Baobab.prototype.release = function() { + var k; delete this.data; delete this._transaction; // Releasing cursors - for (var k in this._cursors) + for (k in this._cursors) this._cursors[k].release(); delete this._cursors; + // Releasing facets + for (k in this.facets) + this.facets[k].release(); + delete this.facets; + // Killing event emitter this.kill(); }; diff --git a/src/cursor.js b/src/cursor.js index 3cf391a..3a90cb4 100644 --- a/src/cursor.js +++ b/src/cursor.js @@ -210,7 +210,7 @@ Cursor.prototype.get = function(path) { path = helpers.arrayOf(arguments); var fullPath = this.solvedPath.concat( - (type.String(path) || type.Number(path) ? [path] : path) || [] + [].concat(path || path === 0 ? path : []) ); return helpers.getIn(this.tree.data, fullPath, this.tree); diff --git a/src/facet.js b/src/facet.js index a53782c..53de8ae 100644 --- a/src/facet.js +++ b/src/facet.js @@ -4,18 +4,24 @@ * * Facets enable the user to define views on a given Baobab tree. */ -var Watcher = require('./watcher.js'); +var Watcher = require('./watcher.js'), + helpers = require('./helpers.js'); + +function identity(v) { + return v; +} function Facet(tree, definition) { var self = this; // Private var data = null, - solved = false - solver = definition.get; + solved = false, + solver = definition.get || identity, + map = definition.cursors; - var paths = Object.keys(definition.cursors).map(function(k) { - return definition.cursors[k]; + var paths = Object.keys(map).map(function(k) { + return map[k]; }); // Watcher @@ -25,14 +31,29 @@ function Facet(tree, definition) { self[name] = watcher[name].bind(watcher); } - ['on', 'once'].forEach(bind); + ['on', 'once', 'release'].forEach(bind); + // Getting facet data this.get = function() { - if (this.solved) + if (solved) return data; // Solving + var cursorsData = {}; + + for (var k in map) + cursorsData[k] = tree.get(map[k]); + + data = solver.call(null, cursorsData); + solved = true; + + return data; }; + + // Resetting flag on cursor update + this.on('update', function() { + solved = false; + }); } module.exports = Facet; diff --git a/test/suites/baobab.js b/test/suites/baobab.js index 1d36969..630b152 100644 --- a/test/suites/baobab.js +++ b/test/suites/baobab.js @@ -7,7 +7,7 @@ var assert = require('assert'), Baobab = require('../../src/baobab.js'), Cursor = require('../../src/cursor.js'), async = require('async'), - clone = require('lodash.clonedeep'); + _ = require('lodash'); describe('Baobab API', function() { @@ -140,6 +140,137 @@ describe('Baobab API', function() { }); }); + describe('Facets', function() { + var baobab = new Baobab( + + // Data + { + projects: [ + { + id: 1, + name: 'Tezcatlipoca', + user: 'John' + }, + { + id: 2, + name: 'Huitzilopochtli', + user: 'John' + }, + { + id: 3, + name: 'Tlaloc', + user: 'Jack' + } + ], + currentProjectId: 1 + }, + + // Options + { + asynchronous: false, + facets: { + filtered: { + cursors: { + projects: ['projects'] + }, + get: function(data) { + return data.projects.filter(function(p) { + return p.user === 'John'; + }); + } + }, + current: { + cursors: { + id: ['currentProjectId'], + projects: ['projects'] + }, + get: function(data) { + return _.find(data.projects, {id: data.id}); + } + } + } + } + ); + + var filtered = baobab.facets.filtered, + current = baobab.facets.current; + + it('should be possible to get data from facets.', function() { + assert.deepEqual(filtered.get(), [ + { + id: 1, + name: 'Tezcatlipoca', + user: 'John' + }, + { + id: 2, + name: 'Huitzilopochtli', + user: 'John' + } + ]); + + assert.deepEqual(current.get(), { + id: 1, + name: 'Tezcatlipoca', + user: 'John' + }); + + baobab.update({ + projects: { + $push: { + id: 4, + name: 'Coatlicue', + user: 'John' + } + }, + currentProjectId: { + $set: 2 + } + }); + + assert.deepEqual(filtered.get(), [ + { + id: 1, + name: 'Tezcatlipoca', + user: 'John' + }, + { + id: 2, + name: 'Huitzilopochtli', + user: 'John' + }, + { + id: 4, + name: 'Coatlicue', + user: 'John' + } + ]); + + assert.deepEqual(current.get(), { + id: 2, + name: 'Huitzilopochtli', + user: 'John' + }); + }); + + it('should be possible to listen to facets.', function() { + var countF = 0, + countC = 0; + + var incF = function() {countF++;}, + incC = function() {countC++;}; + + filtered.on('update', incF); + current.on('update', incC); + + baobab.select('projects').push({id: 4, name: 'Coatlicue', user: 'John'}); + baobab.set('currentProjectId', 2); + + assert.strictEqual(countF, 1); + assert.strictEqual(countC, 2); + }); + }); + describe('Options', function() { it('should be possible to commit changes immediately.', function() { var baobab = new Baobab({hello: 'world'}, {asynchronous: false}); diff --git a/test/suites/helpers.js b/test/suites/helpers.js index 37022ad..400c1c5 100644 --- a/test/suites/helpers.js +++ b/test/suites/helpers.js @@ -6,8 +6,7 @@ var assert = require('assert'), state = require('../state.js'), Baobab = require('../../src/baobab.js'), helpers = require('../../src/helpers.js'), - update = require('../../src/update.js'), - clone = require('lodash.clonedeep'); + update = require('../../src/update.js'); describe('Helpers', function() { From 8c717269b40145d3dcb7f6408853a5940b046055 Mon Sep 17 00:00:00 2001 From: Yomguithereal Date: Tue, 14 Apr 2015 14:22:24 +0200 Subject: [PATCH 47/73] Replacing evil while by eviler evil --- build/baobab.min.js | 2 +- src/helpers.js | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/build/baobab.min.js b/build/baobab.min.js index c0f9dde..6f7cf6b 100644 --- a/build/baobab.min.js +++ b/build/baobab.min.js @@ -1,2 +1,2 @@ /* baobab.js - Version: 1.0.0-rc1 - Author: Yomguithereal (Guillaume Plique) */ -!function(t){if("object"==typeof exports&&"undefined"!=typeof module)module.exports=t();else if("function"==typeof define&&define.amd)define([],t);else{var r;r="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:this,r.Baobab=t()}}(function(){var t;return function r(t,e,n){function i(s,a){if(!e[s]){if(!t[s]){var u="function"==typeof require&&require;if(!a&&u)return u(s,!0);if(o)return o(s,!0);var h=new Error("Cannot find module '"+s+"'");throw h.code="MODULE_NOT_FOUND",h}var c=e[s]={exports:{}};t[s][0].call(c.exports,function(r){var e=t[s][1][r];return i(e?e:r)},c,c.exports,r,t,e,n)}return e[s].exports}for(var o="function"==typeof require&&require,s=0;sn;n++)t[n].fn!==r&&i.push(t[n]);return i}var s={once:"boolean",scope:"object"},a=0,u=function(){this._enabled=!0,this.unbindAll()};u.prototype.unbindAll=function(){return this._handlers={},this._handlersAll=[],this._handlersComplex=[],this},u.prototype.on=function(t,r,e){var n,o,u,h,c,l,f;if(i(t)){for(h in t)this.on(h,t[h],r);return this}for("function"==typeof t&&(e=r,r=t,t=null),c=[].concat(t),n=0,o=c.length;o>n;n++){if(h=c[n],f={order:a++,fn:r},"string"==typeof h)this._handlers[h]||(this._handlers[h]=[]),l=this._handlers[h];else if(h instanceof RegExp)l=this._handlersComplex,f.pattern=h;else{if(null!==h)throw Error("Emitter.on: invalid event.");l=this._handlersAll}for(u in e||{})s[u]&&(f[u]=e[u]);f.once&&(f.parent=l),l.push(f)}return this},u.prototype.once=function(){var t=Array.prototype.slice.call(arguments),e=t.length-1;return i(t[e])&&t.length>1?t[e]=r(t[e],{once:!0}):t.push({once:!0}),this.on.apply(this,t)},u.prototype.off=function(t,r){var e,n,s,a;if(1===arguments.length&&"function"==typeof t){r=arguments[0];for(s in this._handlers)this._handlers[s]=o(this._handlers[s],r),0===this._handlers[s].length&&delete this._handlers[s];this._handlersAll=o(this._handlersAll,r),this._handlersComplex=o(this._handlersComplex,r)}else if(1===arguments.length&&"string"==typeof t)delete this._handlers[t];else if(2===arguments.length){var u=[].concat(t);for(e=0,n=u.length;n>e;e++)a=u[e],this._handlers[a]=o(this._handlers[a],r),0===(this._handlers[a]||[]).length&&delete this._handlers[a]}else if(i(t))for(s in t)this.off(s,t[s]);return this},u.prototype.listeners=function(t){var r,e,n,i=this._handlersAll||[],o=!1;if(!t)throw Error("Emitter.listeners: no event provided.");for(i=i.concat(this._handlers[t]||[]),e=0,n=this._handlersComplex.length;n>e;e++)r=this._handlersComplex[e],~t.search(r.pattern)&&(o=!0,i.push(r));return this._handlersAll.length||o?i.sort(function(t,r){return t.order-r.order}):i.slice(0)},u.prototype.emit=function(t,r){if(!this._enabled)return this;if(i(t)){for(var e in t)this.emit(e,t[e]);return this}var n,o,s,a,u,h,c,l=[].concat(t),f=[];for(a=0,h=l.length;h>a;a++){for(o=this.listeners(l[a]),u=0,c=o.length;c>u;u++)s=o[u],n={type:l[a],target:this},arguments.length>1&&(n.data=r),s.fn.call("scope"in s?s.scope:this,n),s.once&&f.push(s);for(u=f.length-1;u>=0;u--)f[u].parent.splice(f[u].parent.indexOf(f[u]),1)}return this},u.prototype.kill=function(){this.unbindAll(),this._handlers=null,this._handlersAll=null,this._handlersComplex=null,this._enabled=!1},u.prototype.disable=function(){return this._enabled=!1,this},u.prototype.enable=function(){return this._enabled=!0,this},u.version="3.0.0","undefined"!=typeof n?("undefined"!=typeof e&&e.exports&&(n=e.exports=u),n.Emitter=u):"function"==typeof t&&t.amd?t("emmett",[],function(){return u}):this.Emitter=u}).call(this)},{}],4:[function(t,r,e){function n(t){return t+"$"+(new Date).getTime()+(""+Math.random()).replace("0.","")}function i(t,r){function e(t){this[t]=function(){var r=this.root[t].apply(this.root,arguments);return r instanceof o?this:r}}if(arguments.length<1&&(t={}),!(this instanceof i))return new i(t,r);if(!d.Object(t)&&!d.Array(t))throw Error("Baobab: invalid data.");if(s.call(this),this.options=h.shallowMerge(p,r),this._transaction={},this._future=void 0,this._cursors={},this.data=h.deepClone(t),this.root=this.select([]),this.facets={},["get","set","unset","update"].forEach(e.bind(this)),!d.Object(this.options.facets))throw Error("Baobab: invalid facets.");for(var n in this.options.facets)this.addFacet(n,this.options.facets[n]);this.mixin=f.baobab(this)}var o=t("./cursor.js"),s=t("emmett"),a=t("./watcher.js"),u=t("./facet.js"),h=t("./helpers.js"),c=t("./update.js"),l=t("./merge.js"),f=t("./mixins.js"),p=t("../defaults.js"),d=t("./type.js");h.inherits(i,s),i.prototype.addFacet=function(t,r){return this.facets[t]=new u(this,r),this},i.prototype.select=function(t){if(!t)throw Error("Baobab.select: invalid path.");if(arguments.length>1&&(t=h.arrayOf(arguments)),!d.Path(t))throw Error("Baobab.select: invalid path.");t=[].concat(t);var r,e=d.ComplexPath(t);e&&(r=h.solvePath(this.data,t,this));var i=t.map(function(t){return d.Function(t)?n("fn"):d.Object(t)?n("ob"):t}).join("|λ|");if(this._cursors[i])return this._cursors[i];var s=new o(this,t,r,i);return this._cursors[i]=s,s},i.prototype.stack=function(t){var r=this;if(!d.Object(t))throw Error("Baobab.update: wrong specification.");return this._transaction=l(t,this._transaction),this.options.autoCommit?this.options.asynchronous?(this._future||(this._future=setTimeout(r.commit.bind(r,null),0)),this):this.commit():this},i.prototype.commit=function(){var t=c(this.data,this._transaction,this.options),r=this.data;return this.data=t.data,this._transaction={},this._future&&(this._future=clearTimeout(this._future)),this.emit("update",{log:t.log,previousState:r}),this},i.prototype.watch=function(t){if(!d.Array(t)||t.some(function(t){return!d.Path(t)}))throw Error("Baobab.watch: invalid paths.");return new a(this,[].concat(t))},i.prototype.release=function(){var t;delete this.data,delete this._transaction;for(t in this._cursors)this._cursors[t].release();delete this._cursors;for(t in this.facets)this.facets[t].release();delete this.facets,this.kill()},i.prototype.toJSON=function(){return this.get()},r.exports=i},{"../defaults.js":2,"./cursor.js":5,"./facet.js":6,"./helpers.js":7,"./merge.js":8,"./mixins.js":9,"./type.js":10,"./update.js":11,"./watcher.js":12,emmett:3}],5:[function(t,r,e){function n(t,r,e,n){function i(t){if(o.isRecording()&&!o.undoing){var r=u.getIn(t,o.solvedPath,o.tree),e=u.deepClone(r);o.archive.add(e)}return o.undoing=!1,o.emit("update")}var o=this;s.call(this),r=r||[],this.tree=t,this.path=r,this.hash=n,this.archive=null,this.undoing=!1,this.complexPath=!!e,this.solvedPath=this.complexPath?e:this.path,this.relevant=void 0!==this.get(),this.updateHandler=function(t){var r=t.data.log,e=t.data.previousState,n=!1;if(o.complexPath&&(o.solvedPath=u.solvePath(o.tree.data,o.path,o.tree)),!o.path.length)return i(e);o.solvedPath&&(n=u.solveUpdate(r,[o.solvedPath]));var s=void 0!==o.get();o.relevant?s&&n?i(e):s||(o.emit("irrelevant"),o.relevant=!1):s&&n&&(o.emit("relevant"),i(e),o.relevant=!0)},this.mixin=a.cursor(this);var h=!1;this._lazyBind=function(){h||(h=!0,o.tree.on("update",o.updateHandler))},this.on=u.before(this._lazyBind,this.on.bind(this)),this.once=u.before(this._lazyBind,this.once.bind(this)),this.complexPath&&this._lazyBind()}function i(t,r,e,n){if(arguments.length>5)throw Error("baobab.Cursor."+t+": too many arguments.");arguments.length<4&&(n=e,e=[]),e=e||[];var i=[].concat(e),o=u.solvePath(this.get(),i,this.tree);if(!o)throw Error("baobab.Cursor."+t+": could not solve dynamic path.");if(r){var s=this.get(o);if(!h[r](s))throw Error("baobab.Cursor."+t+": invalid target.")}var a={};a["$"+t]=n;var c=u.pathObject(o,a);return c}function o(t,r){n.prototype[t]=function(){var e=i.bind(this,t,r).apply(this,arguments);return this.update(e)}}var s=t("emmett"),a=t("./mixins.js"),u=t("./helpers.js"),h=(t("../defaults.js"),t("./type.js"));u.inherits(n,s),n.prototype.isRoot=function(){return!this.path.length},n.prototype.isLeaf=function(){return h.Primitive(this.get())},n.prototype.isBranch=function(){return!this.isLeaf()&&!this.isRoot()},n.prototype.root=function(){return this.tree.root()},n.prototype.select=function(t){if(arguments.length>1&&(t=u.arrayOf(arguments)),!h.Path(t))throw Error("baobab.Cursor.select: invalid path.");return this.tree.select(this.path.concat(t))},n.prototype.up=function(){return this.solvedPath&&this.solvedPath.length?this.tree.select(this.path.slice(0,-1)):null},n.prototype.left=function(){var t=+this.solvedPath[this.solvedPath.length-1];if(isNaN(t))throw Error("baobab.Cursor.left: cannot go left on a non-list type.");return t?this.tree.select(this.solvedPath.slice(0,-1).concat(t-1)):null},n.prototype.leftmost=function(){var t=+this.solvedPath[this.solvedPath.length-1];if(isNaN(t))throw Error("baobab.Cursor.leftmost: cannot go left on a non-list type.");return this.tree.select(this.solvedPath.slice(0,-1).concat(0))},n.prototype.right=function(){var t=+this.solvedPath[this.solvedPath.length-1];if(isNaN(t))throw Error("baobab.Cursor.right: cannot go right on a non-list type.");return t+1===this.up().get().length?null:this.tree.select(this.solvedPath.slice(0,-1).concat(t+1))},n.prototype.rightmost=function(){var t=+this.solvedPath[this.solvedPath.length-1];if(isNaN(t))throw Error("baobab.Cursor.right: cannot go right on a non-list type.");var r=this.up().get();return this.tree.select(this.solvedPath.slice(0,-1).concat(r.length-1))},n.prototype.down=function(){+this.solvedPath[this.solvedPath.length-1];return this.get()instanceof Array?this.tree.select(this.solvedPath.concat(0)):null},n.prototype.get=function(t){arguments.length>1&&(t=u.arrayOf(arguments));var r=this.solvedPath.concat([].concat(t||0===t?t:[]));return u.getIn(this.tree.data,r,this.tree)},o("set"),o("apply"),o("chain"),o("push","Array"),o("unshift","Array"),n.prototype.merge=function(t){if(!h.Object(t))throw Error("baobab.Cursor.merge: trying to merge a non-object.");var r=i.bind(this,"merge","Object").apply(this,arguments);return this.update(r)},n.prototype.unset=function(t){if(void 0===t&&this.isRoot())throw Error("baobab.Cursor.unset: cannot remove root node.");var r=i.bind(this,"unset",null).apply(this,[t,!0]);return this.update(r)},n.prototype.update=function(t,r){if(arguments.length<2)return this.tree.stack(u.pathObject(this.solvedPath,t)),this;var e=[].concat(t),n=u.solvePath(this.get(),e,this.tree);if(!n)throw Error("baobab.Cursor.update: could not solve dynamic path.");return this.tree.stack(u.pathObject(this.solvedPath.concat(n),r)),this},n.prototype.startRecording=function(t){if(t=t||5,1>t)throw Error("baobab.Cursor.startRecording: invalid maximum number of records.");return this.archive?this:(this._lazyBind(),this.archive=u.archive(t),this)},n.prototype.stopRecording=function(){return this.archive=null,this},n.prototype.undo=function(t){if(t=t||1,!this.isRecording())throw Error("baobab.Cursor.undo: cursor is not recording.");if(!h.PositiveInteger(t))throw Error("baobab.Cursor.undo: expecting a positive integer.");var r=this.archive.back(t);if(!r)throw Error("boabab.Cursor.undo: cannot find a relevant record ("+t+" back).");return this.undoing=!0,this.set(r)},n.prototype.isRecording=function(){return!!this.archive},n.prototype.hasHistory=function(){return!(!this.archive||!this.archive.get().length)},n.prototype.getHistory=function(){return this.archive?this.archive.get():[]},n.prototype.release=function(){this.tree.off("update",this.updateHandler),this.hash&&delete this.tree._cursors[this.hash],delete this.tree,delete this.path,delete this.solvedPath,delete this.archive,this.kill()},n.prototype.toJSON=function(){return this.get()},h.Cursor=function(t){return t instanceof n},r.exports=n},{"../defaults.js":2,"./helpers.js":7,"./mixins.js":9,"./type.js":10,emmett:3}],6:[function(t,r,e){function n(t){return t}function i(t,r){function e(t){i[t]=l[t].bind(l)}var i=this,s=null,a=!1,u=r.get||n,h=r.cursors,c=Object.keys(h).map(function(t){return h[t]}),l=new o(t,c);["on","once","release"].forEach(e),this.get=function(){if(a)return s;var r={};for(var e in h)r[e]=t.get(h[e]);return s=u.call(null,r),a=!0,s},this.on("update",function(){a=!1})}{var o=t("./watcher.js");t("./helpers.js")}r.exports=i},{"./helpers.js":7,"./watcher.js":12}],7:[function(t,r,e){(function(e){function n(t){return Array.prototype.slice.call(t)}function i(t,r){return function(){t(),r.apply(null,arguments)}}function o(t,r){var e,n={};for(e in t)n[e]=t[e];for(e in r)n[e]=r[e];return n}function s(t,r){if(t===r)return!0;if("object"!=typeof t||"object"!=typeof r||null===t||null===r)return!1;var e=Object.keys(t),n=Object.keys(r);if(e.length!==n.length)return!1;var i,o;for(i=0,o=e.length;o>i;i++)if(t[e[i]]!==r[e[i]])return!1;return!0}function a(t){var r=t.source,e="";return t.global&&(e+="g"),t.multiline&&(e+="m"),t.ignoreCase&&(e+="i"),t.sticky&&(e+="y"),t.unicode&&(e+="u"),new RegExp(r,e)}function u(t,r){if(!r||"object"!=typeof r||r instanceof Error||"ArrayBuffer"in e&&r instanceof ArrayBuffer)return r;if(w.Array(r)){if(t){var n,i,o=[];for(n=0,i=r.length;i>n;n++)o.push(x(r[n]));return o}return r.slice(0)}if(w.Date(r))return new Date(r.getTime());if(r instanceof RegExp)return a(r);if(w.Object(r)){var s,u={};r.constructor&&r.constructor!==Object&&(u=Object.create(r.constructor.prototype));for(s in r)r.hasOwnProperty(s)&&(u[s]=t?x(r[s]):r[s]);return u}return r}function h(t,r){return function(e){return r(t(e))}}function c(t,r){var e,n;for(e=0,n=t.length;n>e;e++)if(r(t[e]))return t[e]}function l(t,r){var e,n;for(e=0,n=t.length;n>e;e++)if(r(t[e]))return e;return-1}function f(t,r){var e,n=!0;if(!t)return!1;for(e in r)if(w.Object(r[e]))n=n&&f(t[e],r[e]);else if(w.Array(r[e]))n=n&&!!~r[e].indexOf(t[e]);else if(t[e]!==r[e])return!1;return n}function d(t,r){return c(t,function(t){return f(t,r)})}function y(t,r){return l(t,function(t){return f(t,r)})}function b(t,r,e){r=r||[];var n,i,o,s=t;for(i=0,o=r.length;o>i;i++){if(!s)return;if("function"==typeof r[i]){if(!w.Array(s))return;s=c(s,r[i])}else if("object"==typeof r[i])if(e&&"$cursor"in r[i]){if(!w.Path(r[i].$cursor))throw Error("baobab.getIn: $cursor path must be an array.");n=e.get(r[i].$cursor),s=s[n]}else{if(!w.Array(s))return;s=d(s,r[i])}else s=s[r[i]]}return s}function g(t,r,e){var n,i,o,s=[],a=t;for(i=0,o=r.length;o>i;i++){if(!a)return null;if("function"==typeof r[i]){if(!w.Array(a))return;n=l(a,r[i]),s.push(n),a=a[n]}else if("object"==typeof r[i])if(e&&"$cursor"in r[i]){if(!w.Path(r[i].$cursor))throw Error("baobab.getIn: $cursor path must be an array.");p=e.get(r[i].$cursor),s.push(p),a=a[p]}else{if(!w.Array(a))return;n=y(a,r[i]),s.push(n),a=a[n]}else s.push(r[i]),a=a[r[i]]||{}}return s}function v(t,r){var e,n,i,o,s,a,u,h,c;for(e=0,o=r.length;o>e;e++)for(u=r[e],n=0,s=t.length;s>n;n++)for(h=t[n],i=0,a=h.length;a>i&&(c=h[i],c==u[i]);i++)if(i+1===a||i+1===u.length)return!0;return!1}function m(t,r){var e,n=t.length,i={},o=i;for(n||(i=r),e=0;n>e;e++)o[t[e]]=e+1===n?r:{},o=o[t[e]];return i}function _(t,r){t.super_=r;var e=function(){};e.prototype=r.prototype,t.prototype=new e,t.prototype.constructor=t}function j(t){var r=[];return{add:function(e){for(r.unshift(e);r.length>t;)r.pop()},back:function(t){var e=r[t-1];return e&&(r=r.slice(t)),e},get:function(){return r}}}var w=t("./type.js"),$=u.bind(null,!1),x=u.bind(null,!0);r.exports={archive:j,arrayOf:n,before:i,deepClone:x,shallowClone:$,shallowEqual:s,shallowMerge:o,compose:h,getIn:b,inherits:_,pathObject:m,solvePath:g,solveUpdate:v}}).call(this,"undefined"!=typeof global?global:"undefined"!=typeof self?self:"undefined"!=typeof window?window:{})},{"./type.js":10}],8:[function(t,r,e){function n(t,r,e){a.forEach(function(r){e!==r&&delete t[r]}),t[e]=r[e]}function i(t,r){var e,u=o.shallowClone(r||{});a.forEach(function(r){t[r]&&n(u,t,r)}),t.$chain&&(a.slice(0,-1).forEach(function(t){delete u[t]}),u.$apply=u.$apply?o.compose(u.$apply,t.$chain):t.$chain),t.$push&&u.$push?u.$push=s.Array(u.$push)?u.$push.concat(t.$push):[u.$push].concat(t.$push):t.$push&&(u.$push=t.$push),t.$unshift&&u.$unshift?u.$unshift=s.Array(t.$unshift)?t.$unshift.concat(u.$unshift):[t.$unshift].concat(u.$unshift):t.$unshift&&(u.$unshift=t.$unshift);for(e in t)s.Object(t[e])?u[e]=i(t[e],u[e]):"$"!==e[0]&&(u[e]=t[e]);return u}var o=t("./helpers.js"),s=t("./type.js"),a=["$unset","$set","$merge","$apply"];r.exports=i},{"./helpers.js":7,"./type.js":10}],9:[function(t,r,e){var n=t("./type.js");r.exports={baobab:function(t){return{mixins:[{getInitialState:function(){if(this.tree=t,!this.cursor&&!this.cursors)return{};if(this.cursor&&this.cursors)throw Error("baobab.mixin: you cannot have both `component.cursor` and `component.cursors`. Please make up your mind.");if(this.__type=null,this.__updateHandler=function(){this.setState(this.__getCursorData())}.bind(this),this.cursor){if(!n.MixinCursor(this.cursor))throw Error("baobab.mixin.cursor: invalid data (cursor, string, array or function).");n.Function(this.cursor)&&(this.cursor=this.cursor()),n.Cursor(this.cursor)||(this.cursor=t.select(this.cursor)),this.__getCursorData=function(){return{cursor:this.cursor.get()}}.bind(this),this.__type="single"}else if(this.cursors){if(!n.MixinCursors(this.cursors))throw Error("baobab.mixin.cursor: invalid data (object, array or function).");if(n.Function(this.cursors)&&(this.cursors=this.cursors()),n.Array(this.cursors))this.cursors=this.cursors.map(function(r){return n.Cursor(r)?r:t.select(r)}),this.__getCursorData=function(){return{cursors:this.cursors.map(function(t){return t.get()})}}.bind(this),this.__type="array";else{for(var r in this.cursors)n.Cursor(this.cursors[r])||(this.cursors[r]=t.select(this.cursors[r]));this.__getCursorData=function(){var t={};for(r in this.cursors)t[r]=this.cursors[r].get();return{cursors:t}}.bind(this),this.__type="object"}}return this.__getCursorData()},componentDidMount:function(){"single"===this.__type?(this.__watcher=this.tree.watch([this.cursor.path]),this.__watcher.on("update",this.__updateHandler)):"array"===this.__type?(this.__watcher=this.tree.watch(this.cursors.map(function(t){return t.path})),this.__watcher.on("update",this.__updateHandler)):"object"===this.__type&&(this.__watcher=this.tree.watch(Object.keys(this.cursors).map(function(t){return this.cursors[t].path},this)),this.__watcher.on("update",this.__updateHandler))},componentWillUnmount:function(){this.__watcher&&this.__watcher.release()}}].concat(t.options.mixins)}},cursor:function(t){return{mixins:[{getInitialState:function(){return this.cursor=t,this.__updateHandler=function(){this.setState({cursor:this.cursor.get()})}.bind(this),{cursor:this.cursor.get()}},componentDidMount:function(){this.cursor.on("update",this.__updateHandler)},componentWillUnmount:function(){this.cursor.off("update",this.__updateHandler)}}].concat(t.tree.options.mixins)}}}},{"./type.js":10}],10:[function(t,r,e){function n(t,r){return r.some(function(r){return i[r](t)})}var i={};i.Array=function(t){return Array.isArray(t)},i.Object=function(t){return t&&"object"==typeof t&&!Array.isArray(t)&&!(t instanceof Function)},i.String=function(t){return"string"==typeof t},i.Number=function(t){return"number"==typeof t},i.PositiveInteger=function(t){return"number"==typeof t&&t>0&&t%1===0},i.Function=function(t){return"function"==typeof t},i.Primitive=function(t){return"string"==typeof t||"number"==typeof t||"boolean"==typeof t},i.Date=function(t){return t instanceof Date},i.NonScalar=function(t){return i.Object(t)||i.Array(t)},i.Path=function(t){var r=["String","Number","Function","Object"];return i.Array(t)?t.every(function(t){return n(t,r)}):n(t,r)},i.MixinCursor=function(t){return n(t,["String","Number","Array","Function","Cursor"])},i.MixinCursors=function(t){return n(t,["Object","Array","Function"])},i.ComplexPath=function(t){return t.some(function(t){return n(t,["Object","Function"])})},r.exports=i},{}],11:[function(t,r,e){function n(t,r){var e=new Error("baobab.update: "+r+" at path /"+t.slice(1).join("/"));return e.path=t,e}var i=t("./helpers.js"),o=t("./type.js");r.exports=function(t,r,e){if(e=e||{},!o.Object(t)&&!o.Array(t))throw Error("baobab.update: invalid target.");var s={};t={root:i.shallowClone(t)};var a=function(t,r,e,u){e=e||["root"];var h,c,l,f=e.join("|λ|"),p=e[e.length-1],d=Object.keys(r).some(function(t){return!!~["$unset","$set","$apply","$merge","$push","$unshift"].indexOf(t)});if(d){s[f]=!0;for(c in r){if("$unset"===c){var y=e[e.length-2];o.Array(t)?u[y]=t.slice(0,+p).concat(t.slice(+p+1)):(u[y]=i.shallowClone(t),delete u[y][p]);break}if("$set"===c){l=r.$set,t[p]=l;break}if("$apply"===c){if(h=r.$apply,"function"!=typeof h)throw n(e,"using command $apply with a non function");t[p]=h.call(null,t[p]);break}if("$merge"===c){if(l=r.$merge,!o.Object(t[p])||!o.Object(l))throw n(e,"using command $merge with a non object");t[p]=i.shallowMerge(t[p],l);break}if("$push"===c){if(l=r.$push,!o.Array(t[p]))throw n(e,"using command $push to a non array");t[p]=t[p].concat(l)}if("$unshift"===c){if(l=r.$unshift,!o.Array(t[p]))throw n(e,"using command $unshift to a non array");t[p]=[].concat(l).concat(t[p])}}}else for(c in r)t[p][c]="undefined"==typeof t[p][c]?{}:i.shallowClone(t[p][c]),a(t[p],r[c],e.concat(c),t)};return a(t,r),{data:t.root,log:Object.keys(s).map(function(t){return t.split("|λ|").slice(1)})}}},{"./helpers.js":7,"./type.js":10}],12:[function(t,r,e){function n(t,r){function e(){u&&(a=r.map(function(t){return o.solvePath(n.tree.data,t,n.tree)}))}var n=this;i.call(this),this.tree=t;var a=r,u=r.some(s.ComplexPath);this.updateHandler=function(t){var r=o.solveUpdate(t.data.log,a);r&&n.emit("update")},e(),this.tree.on("update",this.updateHandler)}var i=t("emmett"),o=t("./helpers.js"),s=t("./type.js");o.inherits(n,i),n.prototype.release=function(){this.tree.off("update",this.updateHandler),this.tree=null,this.kill()},r.exports=n},{"./helpers.js":7,"./type.js":10,emmett:3}]},{},[1])(1)}); \ No newline at end of file +!function(t){if("object"==typeof exports&&"undefined"!=typeof module)module.exports=t();else if("function"==typeof define&&define.amd)define([],t);else{var r;r="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:this,r.Baobab=t()}}(function(){var t;return function r(t,e,n){function i(s,a){if(!e[s]){if(!t[s]){var u="function"==typeof require&&require;if(!a&&u)return u(s,!0);if(o)return o(s,!0);var h=new Error("Cannot find module '"+s+"'");throw h.code="MODULE_NOT_FOUND",h}var c=e[s]={exports:{}};t[s][0].call(c.exports,function(r){var e=t[s][1][r];return i(e?e:r)},c,c.exports,r,t,e,n)}return e[s].exports}for(var o="function"==typeof require&&require,s=0;sn;n++)t[n].fn!==r&&i.push(t[n]);return i}var s={once:"boolean",scope:"object"},a=0,u=function(){this._enabled=!0,this.unbindAll()};u.prototype.unbindAll=function(){return this._handlers={},this._handlersAll=[],this._handlersComplex=[],this},u.prototype.on=function(t,r,e){var n,o,u,h,c,l,f;if(i(t)){for(h in t)this.on(h,t[h],r);return this}for("function"==typeof t&&(e=r,r=t,t=null),c=[].concat(t),n=0,o=c.length;o>n;n++){if(h=c[n],f={order:a++,fn:r},"string"==typeof h)this._handlers[h]||(this._handlers[h]=[]),l=this._handlers[h];else if(h instanceof RegExp)l=this._handlersComplex,f.pattern=h;else{if(null!==h)throw Error("Emitter.on: invalid event.");l=this._handlersAll}for(u in e||{})s[u]&&(f[u]=e[u]);f.once&&(f.parent=l),l.push(f)}return this},u.prototype.once=function(){var t=Array.prototype.slice.call(arguments),e=t.length-1;return i(t[e])&&t.length>1?t[e]=r(t[e],{once:!0}):t.push({once:!0}),this.on.apply(this,t)},u.prototype.off=function(t,r){var e,n,s,a;if(1===arguments.length&&"function"==typeof t){r=arguments[0];for(s in this._handlers)this._handlers[s]=o(this._handlers[s],r),0===this._handlers[s].length&&delete this._handlers[s];this._handlersAll=o(this._handlersAll,r),this._handlersComplex=o(this._handlersComplex,r)}else if(1===arguments.length&&"string"==typeof t)delete this._handlers[t];else if(2===arguments.length){var u=[].concat(t);for(e=0,n=u.length;n>e;e++)a=u[e],this._handlers[a]=o(this._handlers[a],r),0===(this._handlers[a]||[]).length&&delete this._handlers[a]}else if(i(t))for(s in t)this.off(s,t[s]);return this},u.prototype.listeners=function(t){var r,e,n,i=this._handlersAll||[],o=!1;if(!t)throw Error("Emitter.listeners: no event provided.");for(i=i.concat(this._handlers[t]||[]),e=0,n=this._handlersComplex.length;n>e;e++)r=this._handlersComplex[e],~t.search(r.pattern)&&(o=!0,i.push(r));return this._handlersAll.length||o?i.sort(function(t,r){return t.order-r.order}):i.slice(0)},u.prototype.emit=function(t,r){if(!this._enabled)return this;if(i(t)){for(var e in t)this.emit(e,t[e]);return this}var n,o,s,a,u,h,c,l=[].concat(t),f=[];for(a=0,h=l.length;h>a;a++){for(o=this.listeners(l[a]),u=0,c=o.length;c>u;u++)s=o[u],n={type:l[a],target:this},arguments.length>1&&(n.data=r),s.fn.call("scope"in s?s.scope:this,n),s.once&&f.push(s);for(u=f.length-1;u>=0;u--)f[u].parent.splice(f[u].parent.indexOf(f[u]),1)}return this},u.prototype.kill=function(){this.unbindAll(),this._handlers=null,this._handlersAll=null,this._handlersComplex=null,this._enabled=!1},u.prototype.disable=function(){return this._enabled=!1,this},u.prototype.enable=function(){return this._enabled=!0,this},u.version="3.0.0","undefined"!=typeof n?("undefined"!=typeof e&&e.exports&&(n=e.exports=u),n.Emitter=u):"function"==typeof t&&t.amd?t("emmett",[],function(){return u}):this.Emitter=u}).call(this)},{}],4:[function(t,r,e){function n(t){return t+"$"+(new Date).getTime()+(""+Math.random()).replace("0.","")}function i(t,r){function e(t){this[t]=function(){var r=this.root[t].apply(this.root,arguments);return r instanceof o?this:r}}if(arguments.length<1&&(t={}),!(this instanceof i))return new i(t,r);if(!d.Object(t)&&!d.Array(t))throw Error("Baobab: invalid data.");if(s.call(this),this.options=h.shallowMerge(p,r),this._transaction={},this._future=void 0,this._cursors={},this.data=h.deepClone(t),this.root=this.select([]),this.facets={},["get","set","unset","update"].forEach(e.bind(this)),!d.Object(this.options.facets))throw Error("Baobab: invalid facets.");for(var n in this.options.facets)this.addFacet(n,this.options.facets[n]);this.mixin=f.baobab(this)}var o=t("./cursor.js"),s=t("emmett"),a=t("./watcher.js"),u=t("./facet.js"),h=t("./helpers.js"),c=t("./update.js"),l=t("./merge.js"),f=t("./mixins.js"),p=t("../defaults.js"),d=t("./type.js");h.inherits(i,s),i.prototype.addFacet=function(t,r){return this.facets[t]=new u(this,r),this},i.prototype.select=function(t){if(!t)throw Error("Baobab.select: invalid path.");if(arguments.length>1&&(t=h.arrayOf(arguments)),!d.Path(t))throw Error("Baobab.select: invalid path.");t=[].concat(t);var r,e=d.ComplexPath(t);e&&(r=h.solvePath(this.data,t,this));var i=t.map(function(t){return d.Function(t)?n("fn"):d.Object(t)?n("ob"):t}).join("|λ|");if(this._cursors[i])return this._cursors[i];var s=new o(this,t,r,i);return this._cursors[i]=s,s},i.prototype.stack=function(t){var r=this;if(!d.Object(t))throw Error("Baobab.update: wrong specification.");return this._transaction=l(t,this._transaction),this.options.autoCommit?this.options.asynchronous?(this._future||(this._future=setTimeout(r.commit.bind(r,null),0)),this):this.commit():this},i.prototype.commit=function(){var t=c(this.data,this._transaction,this.options),r=this.data;return this.data=t.data,this._transaction={},this._future&&(this._future=clearTimeout(this._future)),this.emit("update",{log:t.log,previousState:r}),this},i.prototype.watch=function(t){if(!d.Array(t)||t.some(function(t){return!d.Path(t)}))throw Error("Baobab.watch: invalid paths.");return new a(this,[].concat(t))},i.prototype.release=function(){var t;delete this.data,delete this._transaction;for(t in this._cursors)this._cursors[t].release();delete this._cursors;for(t in this.facets)this.facets[t].release();delete this.facets,this.kill()},i.prototype.toJSON=function(){return this.get()},r.exports=i},{"../defaults.js":2,"./cursor.js":5,"./facet.js":6,"./helpers.js":7,"./merge.js":8,"./mixins.js":9,"./type.js":10,"./update.js":11,"./watcher.js":12,emmett:3}],5:[function(t,r,e){function n(t,r,e,n){function i(t){if(o.isRecording()&&!o.undoing){var r=u.getIn(t,o.solvedPath,o.tree),e=u.deepClone(r);o.archive.add(e)}return o.undoing=!1,o.emit("update")}var o=this;s.call(this),r=r||[],this.tree=t,this.path=r,this.hash=n,this.archive=null,this.undoing=!1,this.complexPath=!!e,this.solvedPath=this.complexPath?e:this.path,this.relevant=void 0!==this.get(),this.updateHandler=function(t){var r=t.data.log,e=t.data.previousState,n=!1;if(o.complexPath&&(o.solvedPath=u.solvePath(o.tree.data,o.path,o.tree)),!o.path.length)return i(e);o.solvedPath&&(n=u.solveUpdate(r,[o.solvedPath]));var s=void 0!==o.get();o.relevant?s&&n?i(e):s||(o.emit("irrelevant"),o.relevant=!1):s&&n&&(o.emit("relevant"),i(e),o.relevant=!0)},this.mixin=a.cursor(this);var h=!1;this._lazyBind=function(){h||(h=!0,o.tree.on("update",o.updateHandler))},this.on=u.before(this._lazyBind,this.on.bind(this)),this.once=u.before(this._lazyBind,this.once.bind(this)),this.complexPath&&this._lazyBind()}function i(t,r,e,n){if(arguments.length>5)throw Error("baobab.Cursor."+t+": too many arguments.");arguments.length<4&&(n=e,e=[]),e=e||[];var i=[].concat(e),o=u.solvePath(this.get(),i,this.tree);if(!o)throw Error("baobab.Cursor."+t+": could not solve dynamic path.");if(r){var s=this.get(o);if(!h[r](s))throw Error("baobab.Cursor."+t+": invalid target.")}var a={};a["$"+t]=n;var c=u.pathObject(o,a);return c}function o(t,r){n.prototype[t]=function(){var e=i.bind(this,t,r).apply(this,arguments);return this.update(e)}}var s=t("emmett"),a=t("./mixins.js"),u=t("./helpers.js"),h=(t("../defaults.js"),t("./type.js"));u.inherits(n,s),n.prototype.isRoot=function(){return!this.path.length},n.prototype.isLeaf=function(){return h.Primitive(this.get())},n.prototype.isBranch=function(){return!this.isLeaf()&&!this.isRoot()},n.prototype.root=function(){return this.tree.root()},n.prototype.select=function(t){if(arguments.length>1&&(t=u.arrayOf(arguments)),!h.Path(t))throw Error("baobab.Cursor.select: invalid path.");return this.tree.select(this.path.concat(t))},n.prototype.up=function(){return this.solvedPath&&this.solvedPath.length?this.tree.select(this.path.slice(0,-1)):null},n.prototype.left=function(){var t=+this.solvedPath[this.solvedPath.length-1];if(isNaN(t))throw Error("baobab.Cursor.left: cannot go left on a non-list type.");return t?this.tree.select(this.solvedPath.slice(0,-1).concat(t-1)):null},n.prototype.leftmost=function(){var t=+this.solvedPath[this.solvedPath.length-1];if(isNaN(t))throw Error("baobab.Cursor.leftmost: cannot go left on a non-list type.");return this.tree.select(this.solvedPath.slice(0,-1).concat(0))},n.prototype.right=function(){var t=+this.solvedPath[this.solvedPath.length-1];if(isNaN(t))throw Error("baobab.Cursor.right: cannot go right on a non-list type.");return t+1===this.up().get().length?null:this.tree.select(this.solvedPath.slice(0,-1).concat(t+1))},n.prototype.rightmost=function(){var t=+this.solvedPath[this.solvedPath.length-1];if(isNaN(t))throw Error("baobab.Cursor.right: cannot go right on a non-list type.");var r=this.up().get();return this.tree.select(this.solvedPath.slice(0,-1).concat(r.length-1))},n.prototype.down=function(){+this.solvedPath[this.solvedPath.length-1];return this.get()instanceof Array?this.tree.select(this.solvedPath.concat(0)):null},n.prototype.get=function(t){arguments.length>1&&(t=u.arrayOf(arguments));var r=this.solvedPath.concat([].concat(t||0===t?t:[]));return u.getIn(this.tree.data,r,this.tree)},o("set"),o("apply"),o("chain"),o("push","Array"),o("unshift","Array"),n.prototype.merge=function(t){if(!h.Object(t))throw Error("baobab.Cursor.merge: trying to merge a non-object.");var r=i.bind(this,"merge","Object").apply(this,arguments);return this.update(r)},n.prototype.unset=function(t){if(void 0===t&&this.isRoot())throw Error("baobab.Cursor.unset: cannot remove root node.");var r=i.bind(this,"unset",null).apply(this,[t,!0]);return this.update(r)},n.prototype.update=function(t,r){if(arguments.length<2)return this.tree.stack(u.pathObject(this.solvedPath,t)),this;var e=[].concat(t),n=u.solvePath(this.get(),e,this.tree);if(!n)throw Error("baobab.Cursor.update: could not solve dynamic path.");return this.tree.stack(u.pathObject(this.solvedPath.concat(n),r)),this},n.prototype.startRecording=function(t){if(t=t||5,1>t)throw Error("baobab.Cursor.startRecording: invalid maximum number of records.");return this.archive?this:(this._lazyBind(),this.archive=u.archive(t),this)},n.prototype.stopRecording=function(){return this.archive=null,this},n.prototype.undo=function(t){if(t=t||1,!this.isRecording())throw Error("baobab.Cursor.undo: cursor is not recording.");if(!h.PositiveInteger(t))throw Error("baobab.Cursor.undo: expecting a positive integer.");var r=this.archive.back(t);if(!r)throw Error("boabab.Cursor.undo: cannot find a relevant record ("+t+" back).");return this.undoing=!0,this.set(r)},n.prototype.isRecording=function(){return!!this.archive},n.prototype.hasHistory=function(){return!(!this.archive||!this.archive.get().length)},n.prototype.getHistory=function(){return this.archive?this.archive.get():[]},n.prototype.release=function(){this.tree.off("update",this.updateHandler),this.hash&&delete this.tree._cursors[this.hash],delete this.tree,delete this.path,delete this.solvedPath,delete this.archive,this.kill()},n.prototype.toJSON=function(){return this.get()},h.Cursor=function(t){return t instanceof n},r.exports=n},{"../defaults.js":2,"./helpers.js":7,"./mixins.js":9,"./type.js":10,emmett:3}],6:[function(t,r,e){function n(t){return t}function i(t,r){function e(t){i[t]=l[t].bind(l)}var i=this,s=null,a=!1,u=r.get||n,h=r.cursors,c=Object.keys(h).map(function(t){return h[t]}),l=new o(t,c);["on","once","release"].forEach(e),this.get=function(){if(a)return s;var r={};for(var e in h)r[e]=t.get(h[e]);return s=u.call(null,r),a=!0,s},this.on("update",function(){a=!1})}{var o=t("./watcher.js");t("./helpers.js")}r.exports=i},{"./helpers.js":7,"./watcher.js":12}],7:[function(t,r,e){(function(e){function n(t){return Array.prototype.slice.call(t)}function i(t,r){return function(){t(),r.apply(null,arguments)}}function o(t,r){var e,n={};for(e in t)n[e]=t[e];for(e in r)n[e]=r[e];return n}function s(t,r){if(t===r)return!0;if("object"!=typeof t||"object"!=typeof r||null===t||null===r)return!1;var e=Object.keys(t),n=Object.keys(r);if(e.length!==n.length)return!1;var i,o;for(i=0,o=e.length;o>i;i++)if(t[e[i]]!==r[e[i]])return!1;return!0}function a(t){var r=t.source,e="";return t.global&&(e+="g"),t.multiline&&(e+="m"),t.ignoreCase&&(e+="i"),t.sticky&&(e+="y"),t.unicode&&(e+="u"),new RegExp(r,e)}function u(t,r){if(!r||"object"!=typeof r||r instanceof Error||"ArrayBuffer"in e&&r instanceof ArrayBuffer)return r;if(w.Array(r)){if(t){var n,i,o=[];for(n=0,i=r.length;i>n;n++)o.push(x(r[n]));return o}return r.slice(0)}if(w.Date(r))return new Date(r.getTime());if(r instanceof RegExp)return a(r);if(w.Object(r)){var s,u={};r.constructor&&r.constructor!==Object&&(u=Object.create(r.constructor.prototype));for(s in r)r.hasOwnProperty(s)&&(u[s]=t?x(r[s]):r[s]);return u}return r}function h(t,r){return function(e){return r(t(e))}}function c(t,r){var e,n;for(e=0,n=t.length;n>e;e++)if(r(t[e]))return t[e]}function l(t,r){var e,n;for(e=0,n=t.length;n>e;e++)if(r(t[e]))return e;return-1}function f(t,r){var e,n=!0;if(!t)return!1;for(e in r)if(w.Object(r[e]))n=n&&f(t[e],r[e]);else if(w.Array(r[e]))n=n&&!!~r[e].indexOf(t[e]);else if(t[e]!==r[e])return!1;return n}function d(t,r){return c(t,function(t){return f(t,r)})}function y(t,r){return l(t,function(t){return f(t,r)})}function g(t,r,e){r=r||[];var n,i,o,s=t;for(i=0,o=r.length;o>i;i++){if(!s)return;if("function"==typeof r[i]){if(!w.Array(s))return;s=c(s,r[i])}else if("object"==typeof r[i])if(e&&"$cursor"in r[i]){if(!w.Path(r[i].$cursor))throw Error("baobab.getIn: $cursor path must be an array.");n=e.get(r[i].$cursor),s=s[n]}else{if(!w.Array(s))return;s=d(s,r[i])}else s=s[r[i]]}return s}function b(t,r,e){var n,i,o,s=[],a=t;for(i=0,o=r.length;o>i;i++){if(!a)return null;if("function"==typeof r[i]){if(!w.Array(a))return;n=l(a,r[i]),s.push(n),a=a[n]}else if("object"==typeof r[i])if(e&&"$cursor"in r[i]){if(!w.Path(r[i].$cursor))throw Error("baobab.getIn: $cursor path must be an array.");p=e.get(r[i].$cursor),s.push(p),a=a[p]}else{if(!w.Array(a))return;n=y(a,r[i]),s.push(n),a=a[n]}else s.push(r[i]),a=a[r[i]]||{}}return s}function v(t,r){var e,n,i,o,s,a,u,h,c;for(e=0,o=r.length;o>e;e++)for(u=r[e],n=0,s=t.length;s>n;n++)for(h=t[n],i=0,a=h.length;a>i&&(c=h[i],c==u[i]);i++)if(i+1===a||i+1===u.length)return!0;return!1}function m(t,r){var e,n=t.length,i={},o=i;for(n||(i=r),e=0;n>e;e++)o[t[e]]=e+1===n?r:{},o=o[t[e]];return i}function _(t,r){t.super_=r;var e=function(){};e.prototype=r.prototype,t.prototype=new e,t.prototype.constructor=t}function j(t){var r=[];return{add:function(e){r.unshift(e),r.length>t&&(r.length=t)},back:function(t){var e=r[t-1];return e&&(r=r.slice(t)),e},get:function(){return r}}}var w=t("./type.js"),$=u.bind(null,!1),x=u.bind(null,!0);r.exports={archive:j,arrayOf:n,before:i,deepClone:x,shallowClone:$,shallowEqual:s,shallowMerge:o,compose:h,getIn:g,inherits:_,pathObject:m,solvePath:b,solveUpdate:v}}).call(this,"undefined"!=typeof global?global:"undefined"!=typeof self?self:"undefined"!=typeof window?window:{})},{"./type.js":10}],8:[function(t,r,e){function n(t,r,e){a.forEach(function(r){e!==r&&delete t[r]}),t[e]=r[e]}function i(t,r){var e,u=o.shallowClone(r||{});a.forEach(function(r){t[r]&&n(u,t,r)}),t.$chain&&(a.slice(0,-1).forEach(function(t){delete u[t]}),u.$apply=u.$apply?o.compose(u.$apply,t.$chain):t.$chain),t.$push&&u.$push?u.$push=s.Array(u.$push)?u.$push.concat(t.$push):[u.$push].concat(t.$push):t.$push&&(u.$push=t.$push),t.$unshift&&u.$unshift?u.$unshift=s.Array(t.$unshift)?t.$unshift.concat(u.$unshift):[t.$unshift].concat(u.$unshift):t.$unshift&&(u.$unshift=t.$unshift);for(e in t)s.Object(t[e])?u[e]=i(t[e],u[e]):"$"!==e[0]&&(u[e]=t[e]);return u}var o=t("./helpers.js"),s=t("./type.js"),a=["$unset","$set","$merge","$apply"];r.exports=i},{"./helpers.js":7,"./type.js":10}],9:[function(t,r,e){var n=t("./type.js");r.exports={baobab:function(t){return{mixins:[{getInitialState:function(){if(this.tree=t,!this.cursor&&!this.cursors)return{};if(this.cursor&&this.cursors)throw Error("baobab.mixin: you cannot have both `component.cursor` and `component.cursors`. Please make up your mind.");if(this.__type=null,this.__updateHandler=function(){this.setState(this.__getCursorData())}.bind(this),this.cursor){if(!n.MixinCursor(this.cursor))throw Error("baobab.mixin.cursor: invalid data (cursor, string, array or function).");n.Function(this.cursor)&&(this.cursor=this.cursor()),n.Cursor(this.cursor)||(this.cursor=t.select(this.cursor)),this.__getCursorData=function(){return{cursor:this.cursor.get()}}.bind(this),this.__type="single"}else if(this.cursors){if(!n.MixinCursors(this.cursors))throw Error("baobab.mixin.cursor: invalid data (object, array or function).");if(n.Function(this.cursors)&&(this.cursors=this.cursors()),n.Array(this.cursors))this.cursors=this.cursors.map(function(r){return n.Cursor(r)?r:t.select(r)}),this.__getCursorData=function(){return{cursors:this.cursors.map(function(t){return t.get()})}}.bind(this),this.__type="array";else{for(var r in this.cursors)n.Cursor(this.cursors[r])||(this.cursors[r]=t.select(this.cursors[r]));this.__getCursorData=function(){var t={};for(r in this.cursors)t[r]=this.cursors[r].get();return{cursors:t}}.bind(this),this.__type="object"}}return this.__getCursorData()},componentDidMount:function(){"single"===this.__type?(this.__watcher=this.tree.watch([this.cursor.path]),this.__watcher.on("update",this.__updateHandler)):"array"===this.__type?(this.__watcher=this.tree.watch(this.cursors.map(function(t){return t.path})),this.__watcher.on("update",this.__updateHandler)):"object"===this.__type&&(this.__watcher=this.tree.watch(Object.keys(this.cursors).map(function(t){return this.cursors[t].path},this)),this.__watcher.on("update",this.__updateHandler))},componentWillUnmount:function(){this.__watcher&&this.__watcher.release()}}].concat(t.options.mixins)}},cursor:function(t){return{mixins:[{getInitialState:function(){return this.cursor=t,this.__updateHandler=function(){this.setState({cursor:this.cursor.get()})}.bind(this),{cursor:this.cursor.get()}},componentDidMount:function(){this.cursor.on("update",this.__updateHandler)},componentWillUnmount:function(){this.cursor.off("update",this.__updateHandler)}}].concat(t.tree.options.mixins)}}}},{"./type.js":10}],10:[function(t,r,e){function n(t,r){return r.some(function(r){return i[r](t)})}var i={};i.Array=function(t){return Array.isArray(t)},i.Object=function(t){return t&&"object"==typeof t&&!Array.isArray(t)&&!(t instanceof Function)},i.String=function(t){return"string"==typeof t},i.Number=function(t){return"number"==typeof t},i.PositiveInteger=function(t){return"number"==typeof t&&t>0&&t%1===0},i.Function=function(t){return"function"==typeof t},i.Primitive=function(t){return"string"==typeof t||"number"==typeof t||"boolean"==typeof t},i.Date=function(t){return t instanceof Date},i.NonScalar=function(t){return i.Object(t)||i.Array(t)},i.Path=function(t){var r=["String","Number","Function","Object"];return i.Array(t)?t.every(function(t){return n(t,r)}):n(t,r)},i.MixinCursor=function(t){return n(t,["String","Number","Array","Function","Cursor"])},i.MixinCursors=function(t){return n(t,["Object","Array","Function"])},i.ComplexPath=function(t){return t.some(function(t){return n(t,["Object","Function"])})},r.exports=i},{}],11:[function(t,r,e){function n(t,r){var e=new Error("baobab.update: "+r+" at path /"+t.slice(1).join("/"));return e.path=t,e}var i=t("./helpers.js"),o=t("./type.js");r.exports=function(t,r,e){if(e=e||{},!o.Object(t)&&!o.Array(t))throw Error("baobab.update: invalid target.");var s={};t={root:i.shallowClone(t)};var a=function(t,r,e,u){e=e||["root"];var h,c,l,f=e.join("|λ|"),p=e[e.length-1],d=Object.keys(r).some(function(t){return!!~["$unset","$set","$apply","$merge","$push","$unshift"].indexOf(t)});if(d){s[f]=!0;for(c in r){if("$unset"===c){var y=e[e.length-2];o.Array(t)?u[y]=t.slice(0,+p).concat(t.slice(+p+1)):(u[y]=i.shallowClone(t),delete u[y][p]);break}if("$set"===c){l=r.$set,t[p]=l;break}if("$apply"===c){if(h=r.$apply,"function"!=typeof h)throw n(e,"using command $apply with a non function");t[p]=h.call(null,t[p]);break}if("$merge"===c){if(l=r.$merge,!o.Object(t[p])||!o.Object(l))throw n(e,"using command $merge with a non object");t[p]=i.shallowMerge(t[p],l);break}if("$push"===c){if(l=r.$push,!o.Array(t[p]))throw n(e,"using command $push to a non array");t[p]=t[p].concat(l)}if("$unshift"===c){if(l=r.$unshift,!o.Array(t[p]))throw n(e,"using command $unshift to a non array");t[p]=[].concat(l).concat(t[p])}}}else for(c in r)t[p][c]="undefined"==typeof t[p][c]?{}:i.shallowClone(t[p][c]),a(t[p],r[c],e.concat(c),t)};return a(t,r),{data:t.root,log:Object.keys(s).map(function(t){return t.split("|λ|").slice(1)})}}},{"./helpers.js":7,"./type.js":10}],12:[function(t,r,e){function n(t,r){function e(){u&&(a=r.map(function(t){return o.solvePath(n.tree.data,t,n.tree)}))}var n=this;i.call(this),this.tree=t;var a=r,u=r.some(s.ComplexPath);this.updateHandler=function(t){var r=o.solveUpdate(t.data.log,a);r&&n.emit("update")},e(),this.tree.on("update",this.updateHandler)}var i=t("emmett"),o=t("./helpers.js"),s=t("./type.js");o.inherits(n,i),n.prototype.release=function(){this.tree.off("update",this.updateHandler),this.tree=null,this.kill()},r.exports=n},{"./helpers.js":7,"./type.js":10,emmett:3}]},{},[1])(1)}); \ No newline at end of file diff --git a/src/helpers.js b/src/helpers.js index 896719e..674a84a 100644 --- a/src/helpers.js +++ b/src/helpers.js @@ -345,8 +345,8 @@ function archive(size) { add: function(record) { records.unshift(record); - while(records.length > size) - records.pop(); + if (records.length > size) + records.length = size; }, back: function(steps) { var record = records[steps - 1]; From 98d237b74d18221017ffc573615a85ef2000712d Mon Sep 17 00:00:00 2001 From: Yomguithereal Date: Tue, 14 Apr 2015 16:19:30 +0200 Subject: [PATCH 48/73] Exposing utilities --- build/baobab.min.js | 2 +- src/baobab.js | 11 ++++++++++- 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/build/baobab.min.js b/build/baobab.min.js index 6f7cf6b..79a7df6 100644 --- a/build/baobab.min.js +++ b/build/baobab.min.js @@ -1,2 +1,2 @@ /* baobab.js - Version: 1.0.0-rc1 - Author: Yomguithereal (Guillaume Plique) */ -!function(t){if("object"==typeof exports&&"undefined"!=typeof module)module.exports=t();else if("function"==typeof define&&define.amd)define([],t);else{var r;r="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:this,r.Baobab=t()}}(function(){var t;return function r(t,e,n){function i(s,a){if(!e[s]){if(!t[s]){var u="function"==typeof require&&require;if(!a&&u)return u(s,!0);if(o)return o(s,!0);var h=new Error("Cannot find module '"+s+"'");throw h.code="MODULE_NOT_FOUND",h}var c=e[s]={exports:{}};t[s][0].call(c.exports,function(r){var e=t[s][1][r];return i(e?e:r)},c,c.exports,r,t,e,n)}return e[s].exports}for(var o="function"==typeof require&&require,s=0;sn;n++)t[n].fn!==r&&i.push(t[n]);return i}var s={once:"boolean",scope:"object"},a=0,u=function(){this._enabled=!0,this.unbindAll()};u.prototype.unbindAll=function(){return this._handlers={},this._handlersAll=[],this._handlersComplex=[],this},u.prototype.on=function(t,r,e){var n,o,u,h,c,l,f;if(i(t)){for(h in t)this.on(h,t[h],r);return this}for("function"==typeof t&&(e=r,r=t,t=null),c=[].concat(t),n=0,o=c.length;o>n;n++){if(h=c[n],f={order:a++,fn:r},"string"==typeof h)this._handlers[h]||(this._handlers[h]=[]),l=this._handlers[h];else if(h instanceof RegExp)l=this._handlersComplex,f.pattern=h;else{if(null!==h)throw Error("Emitter.on: invalid event.");l=this._handlersAll}for(u in e||{})s[u]&&(f[u]=e[u]);f.once&&(f.parent=l),l.push(f)}return this},u.prototype.once=function(){var t=Array.prototype.slice.call(arguments),e=t.length-1;return i(t[e])&&t.length>1?t[e]=r(t[e],{once:!0}):t.push({once:!0}),this.on.apply(this,t)},u.prototype.off=function(t,r){var e,n,s,a;if(1===arguments.length&&"function"==typeof t){r=arguments[0];for(s in this._handlers)this._handlers[s]=o(this._handlers[s],r),0===this._handlers[s].length&&delete this._handlers[s];this._handlersAll=o(this._handlersAll,r),this._handlersComplex=o(this._handlersComplex,r)}else if(1===arguments.length&&"string"==typeof t)delete this._handlers[t];else if(2===arguments.length){var u=[].concat(t);for(e=0,n=u.length;n>e;e++)a=u[e],this._handlers[a]=o(this._handlers[a],r),0===(this._handlers[a]||[]).length&&delete this._handlers[a]}else if(i(t))for(s in t)this.off(s,t[s]);return this},u.prototype.listeners=function(t){var r,e,n,i=this._handlersAll||[],o=!1;if(!t)throw Error("Emitter.listeners: no event provided.");for(i=i.concat(this._handlers[t]||[]),e=0,n=this._handlersComplex.length;n>e;e++)r=this._handlersComplex[e],~t.search(r.pattern)&&(o=!0,i.push(r));return this._handlersAll.length||o?i.sort(function(t,r){return t.order-r.order}):i.slice(0)},u.prototype.emit=function(t,r){if(!this._enabled)return this;if(i(t)){for(var e in t)this.emit(e,t[e]);return this}var n,o,s,a,u,h,c,l=[].concat(t),f=[];for(a=0,h=l.length;h>a;a++){for(o=this.listeners(l[a]),u=0,c=o.length;c>u;u++)s=o[u],n={type:l[a],target:this},arguments.length>1&&(n.data=r),s.fn.call("scope"in s?s.scope:this,n),s.once&&f.push(s);for(u=f.length-1;u>=0;u--)f[u].parent.splice(f[u].parent.indexOf(f[u]),1)}return this},u.prototype.kill=function(){this.unbindAll(),this._handlers=null,this._handlersAll=null,this._handlersComplex=null,this._enabled=!1},u.prototype.disable=function(){return this._enabled=!1,this},u.prototype.enable=function(){return this._enabled=!0,this},u.version="3.0.0","undefined"!=typeof n?("undefined"!=typeof e&&e.exports&&(n=e.exports=u),n.Emitter=u):"function"==typeof t&&t.amd?t("emmett",[],function(){return u}):this.Emitter=u}).call(this)},{}],4:[function(t,r,e){function n(t){return t+"$"+(new Date).getTime()+(""+Math.random()).replace("0.","")}function i(t,r){function e(t){this[t]=function(){var r=this.root[t].apply(this.root,arguments);return r instanceof o?this:r}}if(arguments.length<1&&(t={}),!(this instanceof i))return new i(t,r);if(!d.Object(t)&&!d.Array(t))throw Error("Baobab: invalid data.");if(s.call(this),this.options=h.shallowMerge(p,r),this._transaction={},this._future=void 0,this._cursors={},this.data=h.deepClone(t),this.root=this.select([]),this.facets={},["get","set","unset","update"].forEach(e.bind(this)),!d.Object(this.options.facets))throw Error("Baobab: invalid facets.");for(var n in this.options.facets)this.addFacet(n,this.options.facets[n]);this.mixin=f.baobab(this)}var o=t("./cursor.js"),s=t("emmett"),a=t("./watcher.js"),u=t("./facet.js"),h=t("./helpers.js"),c=t("./update.js"),l=t("./merge.js"),f=t("./mixins.js"),p=t("../defaults.js"),d=t("./type.js");h.inherits(i,s),i.prototype.addFacet=function(t,r){return this.facets[t]=new u(this,r),this},i.prototype.select=function(t){if(!t)throw Error("Baobab.select: invalid path.");if(arguments.length>1&&(t=h.arrayOf(arguments)),!d.Path(t))throw Error("Baobab.select: invalid path.");t=[].concat(t);var r,e=d.ComplexPath(t);e&&(r=h.solvePath(this.data,t,this));var i=t.map(function(t){return d.Function(t)?n("fn"):d.Object(t)?n("ob"):t}).join("|λ|");if(this._cursors[i])return this._cursors[i];var s=new o(this,t,r,i);return this._cursors[i]=s,s},i.prototype.stack=function(t){var r=this;if(!d.Object(t))throw Error("Baobab.update: wrong specification.");return this._transaction=l(t,this._transaction),this.options.autoCommit?this.options.asynchronous?(this._future||(this._future=setTimeout(r.commit.bind(r,null),0)),this):this.commit():this},i.prototype.commit=function(){var t=c(this.data,this._transaction,this.options),r=this.data;return this.data=t.data,this._transaction={},this._future&&(this._future=clearTimeout(this._future)),this.emit("update",{log:t.log,previousState:r}),this},i.prototype.watch=function(t){if(!d.Array(t)||t.some(function(t){return!d.Path(t)}))throw Error("Baobab.watch: invalid paths.");return new a(this,[].concat(t))},i.prototype.release=function(){var t;delete this.data,delete this._transaction;for(t in this._cursors)this._cursors[t].release();delete this._cursors;for(t in this.facets)this.facets[t].release();delete this.facets,this.kill()},i.prototype.toJSON=function(){return this.get()},r.exports=i},{"../defaults.js":2,"./cursor.js":5,"./facet.js":6,"./helpers.js":7,"./merge.js":8,"./mixins.js":9,"./type.js":10,"./update.js":11,"./watcher.js":12,emmett:3}],5:[function(t,r,e){function n(t,r,e,n){function i(t){if(o.isRecording()&&!o.undoing){var r=u.getIn(t,o.solvedPath,o.tree),e=u.deepClone(r);o.archive.add(e)}return o.undoing=!1,o.emit("update")}var o=this;s.call(this),r=r||[],this.tree=t,this.path=r,this.hash=n,this.archive=null,this.undoing=!1,this.complexPath=!!e,this.solvedPath=this.complexPath?e:this.path,this.relevant=void 0!==this.get(),this.updateHandler=function(t){var r=t.data.log,e=t.data.previousState,n=!1;if(o.complexPath&&(o.solvedPath=u.solvePath(o.tree.data,o.path,o.tree)),!o.path.length)return i(e);o.solvedPath&&(n=u.solveUpdate(r,[o.solvedPath]));var s=void 0!==o.get();o.relevant?s&&n?i(e):s||(o.emit("irrelevant"),o.relevant=!1):s&&n&&(o.emit("relevant"),i(e),o.relevant=!0)},this.mixin=a.cursor(this);var h=!1;this._lazyBind=function(){h||(h=!0,o.tree.on("update",o.updateHandler))},this.on=u.before(this._lazyBind,this.on.bind(this)),this.once=u.before(this._lazyBind,this.once.bind(this)),this.complexPath&&this._lazyBind()}function i(t,r,e,n){if(arguments.length>5)throw Error("baobab.Cursor."+t+": too many arguments.");arguments.length<4&&(n=e,e=[]),e=e||[];var i=[].concat(e),o=u.solvePath(this.get(),i,this.tree);if(!o)throw Error("baobab.Cursor."+t+": could not solve dynamic path.");if(r){var s=this.get(o);if(!h[r](s))throw Error("baobab.Cursor."+t+": invalid target.")}var a={};a["$"+t]=n;var c=u.pathObject(o,a);return c}function o(t,r){n.prototype[t]=function(){var e=i.bind(this,t,r).apply(this,arguments);return this.update(e)}}var s=t("emmett"),a=t("./mixins.js"),u=t("./helpers.js"),h=(t("../defaults.js"),t("./type.js"));u.inherits(n,s),n.prototype.isRoot=function(){return!this.path.length},n.prototype.isLeaf=function(){return h.Primitive(this.get())},n.prototype.isBranch=function(){return!this.isLeaf()&&!this.isRoot()},n.prototype.root=function(){return this.tree.root()},n.prototype.select=function(t){if(arguments.length>1&&(t=u.arrayOf(arguments)),!h.Path(t))throw Error("baobab.Cursor.select: invalid path.");return this.tree.select(this.path.concat(t))},n.prototype.up=function(){return this.solvedPath&&this.solvedPath.length?this.tree.select(this.path.slice(0,-1)):null},n.prototype.left=function(){var t=+this.solvedPath[this.solvedPath.length-1];if(isNaN(t))throw Error("baobab.Cursor.left: cannot go left on a non-list type.");return t?this.tree.select(this.solvedPath.slice(0,-1).concat(t-1)):null},n.prototype.leftmost=function(){var t=+this.solvedPath[this.solvedPath.length-1];if(isNaN(t))throw Error("baobab.Cursor.leftmost: cannot go left on a non-list type.");return this.tree.select(this.solvedPath.slice(0,-1).concat(0))},n.prototype.right=function(){var t=+this.solvedPath[this.solvedPath.length-1];if(isNaN(t))throw Error("baobab.Cursor.right: cannot go right on a non-list type.");return t+1===this.up().get().length?null:this.tree.select(this.solvedPath.slice(0,-1).concat(t+1))},n.prototype.rightmost=function(){var t=+this.solvedPath[this.solvedPath.length-1];if(isNaN(t))throw Error("baobab.Cursor.right: cannot go right on a non-list type.");var r=this.up().get();return this.tree.select(this.solvedPath.slice(0,-1).concat(r.length-1))},n.prototype.down=function(){+this.solvedPath[this.solvedPath.length-1];return this.get()instanceof Array?this.tree.select(this.solvedPath.concat(0)):null},n.prototype.get=function(t){arguments.length>1&&(t=u.arrayOf(arguments));var r=this.solvedPath.concat([].concat(t||0===t?t:[]));return u.getIn(this.tree.data,r,this.tree)},o("set"),o("apply"),o("chain"),o("push","Array"),o("unshift","Array"),n.prototype.merge=function(t){if(!h.Object(t))throw Error("baobab.Cursor.merge: trying to merge a non-object.");var r=i.bind(this,"merge","Object").apply(this,arguments);return this.update(r)},n.prototype.unset=function(t){if(void 0===t&&this.isRoot())throw Error("baobab.Cursor.unset: cannot remove root node.");var r=i.bind(this,"unset",null).apply(this,[t,!0]);return this.update(r)},n.prototype.update=function(t,r){if(arguments.length<2)return this.tree.stack(u.pathObject(this.solvedPath,t)),this;var e=[].concat(t),n=u.solvePath(this.get(),e,this.tree);if(!n)throw Error("baobab.Cursor.update: could not solve dynamic path.");return this.tree.stack(u.pathObject(this.solvedPath.concat(n),r)),this},n.prototype.startRecording=function(t){if(t=t||5,1>t)throw Error("baobab.Cursor.startRecording: invalid maximum number of records.");return this.archive?this:(this._lazyBind(),this.archive=u.archive(t),this)},n.prototype.stopRecording=function(){return this.archive=null,this},n.prototype.undo=function(t){if(t=t||1,!this.isRecording())throw Error("baobab.Cursor.undo: cursor is not recording.");if(!h.PositiveInteger(t))throw Error("baobab.Cursor.undo: expecting a positive integer.");var r=this.archive.back(t);if(!r)throw Error("boabab.Cursor.undo: cannot find a relevant record ("+t+" back).");return this.undoing=!0,this.set(r)},n.prototype.isRecording=function(){return!!this.archive},n.prototype.hasHistory=function(){return!(!this.archive||!this.archive.get().length)},n.prototype.getHistory=function(){return this.archive?this.archive.get():[]},n.prototype.release=function(){this.tree.off("update",this.updateHandler),this.hash&&delete this.tree._cursors[this.hash],delete this.tree,delete this.path,delete this.solvedPath,delete this.archive,this.kill()},n.prototype.toJSON=function(){return this.get()},h.Cursor=function(t){return t instanceof n},r.exports=n},{"../defaults.js":2,"./helpers.js":7,"./mixins.js":9,"./type.js":10,emmett:3}],6:[function(t,r,e){function n(t){return t}function i(t,r){function e(t){i[t]=l[t].bind(l)}var i=this,s=null,a=!1,u=r.get||n,h=r.cursors,c=Object.keys(h).map(function(t){return h[t]}),l=new o(t,c);["on","once","release"].forEach(e),this.get=function(){if(a)return s;var r={};for(var e in h)r[e]=t.get(h[e]);return s=u.call(null,r),a=!0,s},this.on("update",function(){a=!1})}{var o=t("./watcher.js");t("./helpers.js")}r.exports=i},{"./helpers.js":7,"./watcher.js":12}],7:[function(t,r,e){(function(e){function n(t){return Array.prototype.slice.call(t)}function i(t,r){return function(){t(),r.apply(null,arguments)}}function o(t,r){var e,n={};for(e in t)n[e]=t[e];for(e in r)n[e]=r[e];return n}function s(t,r){if(t===r)return!0;if("object"!=typeof t||"object"!=typeof r||null===t||null===r)return!1;var e=Object.keys(t),n=Object.keys(r);if(e.length!==n.length)return!1;var i,o;for(i=0,o=e.length;o>i;i++)if(t[e[i]]!==r[e[i]])return!1;return!0}function a(t){var r=t.source,e="";return t.global&&(e+="g"),t.multiline&&(e+="m"),t.ignoreCase&&(e+="i"),t.sticky&&(e+="y"),t.unicode&&(e+="u"),new RegExp(r,e)}function u(t,r){if(!r||"object"!=typeof r||r instanceof Error||"ArrayBuffer"in e&&r instanceof ArrayBuffer)return r;if(w.Array(r)){if(t){var n,i,o=[];for(n=0,i=r.length;i>n;n++)o.push(x(r[n]));return o}return r.slice(0)}if(w.Date(r))return new Date(r.getTime());if(r instanceof RegExp)return a(r);if(w.Object(r)){var s,u={};r.constructor&&r.constructor!==Object&&(u=Object.create(r.constructor.prototype));for(s in r)r.hasOwnProperty(s)&&(u[s]=t?x(r[s]):r[s]);return u}return r}function h(t,r){return function(e){return r(t(e))}}function c(t,r){var e,n;for(e=0,n=t.length;n>e;e++)if(r(t[e]))return t[e]}function l(t,r){var e,n;for(e=0,n=t.length;n>e;e++)if(r(t[e]))return e;return-1}function f(t,r){var e,n=!0;if(!t)return!1;for(e in r)if(w.Object(r[e]))n=n&&f(t[e],r[e]);else if(w.Array(r[e]))n=n&&!!~r[e].indexOf(t[e]);else if(t[e]!==r[e])return!1;return n}function d(t,r){return c(t,function(t){return f(t,r)})}function y(t,r){return l(t,function(t){return f(t,r)})}function g(t,r,e){r=r||[];var n,i,o,s=t;for(i=0,o=r.length;o>i;i++){if(!s)return;if("function"==typeof r[i]){if(!w.Array(s))return;s=c(s,r[i])}else if("object"==typeof r[i])if(e&&"$cursor"in r[i]){if(!w.Path(r[i].$cursor))throw Error("baobab.getIn: $cursor path must be an array.");n=e.get(r[i].$cursor),s=s[n]}else{if(!w.Array(s))return;s=d(s,r[i])}else s=s[r[i]]}return s}function b(t,r,e){var n,i,o,s=[],a=t;for(i=0,o=r.length;o>i;i++){if(!a)return null;if("function"==typeof r[i]){if(!w.Array(a))return;n=l(a,r[i]),s.push(n),a=a[n]}else if("object"==typeof r[i])if(e&&"$cursor"in r[i]){if(!w.Path(r[i].$cursor))throw Error("baobab.getIn: $cursor path must be an array.");p=e.get(r[i].$cursor),s.push(p),a=a[p]}else{if(!w.Array(a))return;n=y(a,r[i]),s.push(n),a=a[n]}else s.push(r[i]),a=a[r[i]]||{}}return s}function v(t,r){var e,n,i,o,s,a,u,h,c;for(e=0,o=r.length;o>e;e++)for(u=r[e],n=0,s=t.length;s>n;n++)for(h=t[n],i=0,a=h.length;a>i&&(c=h[i],c==u[i]);i++)if(i+1===a||i+1===u.length)return!0;return!1}function m(t,r){var e,n=t.length,i={},o=i;for(n||(i=r),e=0;n>e;e++)o[t[e]]=e+1===n?r:{},o=o[t[e]];return i}function _(t,r){t.super_=r;var e=function(){};e.prototype=r.prototype,t.prototype=new e,t.prototype.constructor=t}function j(t){var r=[];return{add:function(e){r.unshift(e),r.length>t&&(r.length=t)},back:function(t){var e=r[t-1];return e&&(r=r.slice(t)),e},get:function(){return r}}}var w=t("./type.js"),$=u.bind(null,!1),x=u.bind(null,!0);r.exports={archive:j,arrayOf:n,before:i,deepClone:x,shallowClone:$,shallowEqual:s,shallowMerge:o,compose:h,getIn:g,inherits:_,pathObject:m,solvePath:b,solveUpdate:v}}).call(this,"undefined"!=typeof global?global:"undefined"!=typeof self?self:"undefined"!=typeof window?window:{})},{"./type.js":10}],8:[function(t,r,e){function n(t,r,e){a.forEach(function(r){e!==r&&delete t[r]}),t[e]=r[e]}function i(t,r){var e,u=o.shallowClone(r||{});a.forEach(function(r){t[r]&&n(u,t,r)}),t.$chain&&(a.slice(0,-1).forEach(function(t){delete u[t]}),u.$apply=u.$apply?o.compose(u.$apply,t.$chain):t.$chain),t.$push&&u.$push?u.$push=s.Array(u.$push)?u.$push.concat(t.$push):[u.$push].concat(t.$push):t.$push&&(u.$push=t.$push),t.$unshift&&u.$unshift?u.$unshift=s.Array(t.$unshift)?t.$unshift.concat(u.$unshift):[t.$unshift].concat(u.$unshift):t.$unshift&&(u.$unshift=t.$unshift);for(e in t)s.Object(t[e])?u[e]=i(t[e],u[e]):"$"!==e[0]&&(u[e]=t[e]);return u}var o=t("./helpers.js"),s=t("./type.js"),a=["$unset","$set","$merge","$apply"];r.exports=i},{"./helpers.js":7,"./type.js":10}],9:[function(t,r,e){var n=t("./type.js");r.exports={baobab:function(t){return{mixins:[{getInitialState:function(){if(this.tree=t,!this.cursor&&!this.cursors)return{};if(this.cursor&&this.cursors)throw Error("baobab.mixin: you cannot have both `component.cursor` and `component.cursors`. Please make up your mind.");if(this.__type=null,this.__updateHandler=function(){this.setState(this.__getCursorData())}.bind(this),this.cursor){if(!n.MixinCursor(this.cursor))throw Error("baobab.mixin.cursor: invalid data (cursor, string, array or function).");n.Function(this.cursor)&&(this.cursor=this.cursor()),n.Cursor(this.cursor)||(this.cursor=t.select(this.cursor)),this.__getCursorData=function(){return{cursor:this.cursor.get()}}.bind(this),this.__type="single"}else if(this.cursors){if(!n.MixinCursors(this.cursors))throw Error("baobab.mixin.cursor: invalid data (object, array or function).");if(n.Function(this.cursors)&&(this.cursors=this.cursors()),n.Array(this.cursors))this.cursors=this.cursors.map(function(r){return n.Cursor(r)?r:t.select(r)}),this.__getCursorData=function(){return{cursors:this.cursors.map(function(t){return t.get()})}}.bind(this),this.__type="array";else{for(var r in this.cursors)n.Cursor(this.cursors[r])||(this.cursors[r]=t.select(this.cursors[r]));this.__getCursorData=function(){var t={};for(r in this.cursors)t[r]=this.cursors[r].get();return{cursors:t}}.bind(this),this.__type="object"}}return this.__getCursorData()},componentDidMount:function(){"single"===this.__type?(this.__watcher=this.tree.watch([this.cursor.path]),this.__watcher.on("update",this.__updateHandler)):"array"===this.__type?(this.__watcher=this.tree.watch(this.cursors.map(function(t){return t.path})),this.__watcher.on("update",this.__updateHandler)):"object"===this.__type&&(this.__watcher=this.tree.watch(Object.keys(this.cursors).map(function(t){return this.cursors[t].path},this)),this.__watcher.on("update",this.__updateHandler))},componentWillUnmount:function(){this.__watcher&&this.__watcher.release()}}].concat(t.options.mixins)}},cursor:function(t){return{mixins:[{getInitialState:function(){return this.cursor=t,this.__updateHandler=function(){this.setState({cursor:this.cursor.get()})}.bind(this),{cursor:this.cursor.get()}},componentDidMount:function(){this.cursor.on("update",this.__updateHandler)},componentWillUnmount:function(){this.cursor.off("update",this.__updateHandler)}}].concat(t.tree.options.mixins)}}}},{"./type.js":10}],10:[function(t,r,e){function n(t,r){return r.some(function(r){return i[r](t)})}var i={};i.Array=function(t){return Array.isArray(t)},i.Object=function(t){return t&&"object"==typeof t&&!Array.isArray(t)&&!(t instanceof Function)},i.String=function(t){return"string"==typeof t},i.Number=function(t){return"number"==typeof t},i.PositiveInteger=function(t){return"number"==typeof t&&t>0&&t%1===0},i.Function=function(t){return"function"==typeof t},i.Primitive=function(t){return"string"==typeof t||"number"==typeof t||"boolean"==typeof t},i.Date=function(t){return t instanceof Date},i.NonScalar=function(t){return i.Object(t)||i.Array(t)},i.Path=function(t){var r=["String","Number","Function","Object"];return i.Array(t)?t.every(function(t){return n(t,r)}):n(t,r)},i.MixinCursor=function(t){return n(t,["String","Number","Array","Function","Cursor"])},i.MixinCursors=function(t){return n(t,["Object","Array","Function"])},i.ComplexPath=function(t){return t.some(function(t){return n(t,["Object","Function"])})},r.exports=i},{}],11:[function(t,r,e){function n(t,r){var e=new Error("baobab.update: "+r+" at path /"+t.slice(1).join("/"));return e.path=t,e}var i=t("./helpers.js"),o=t("./type.js");r.exports=function(t,r,e){if(e=e||{},!o.Object(t)&&!o.Array(t))throw Error("baobab.update: invalid target.");var s={};t={root:i.shallowClone(t)};var a=function(t,r,e,u){e=e||["root"];var h,c,l,f=e.join("|λ|"),p=e[e.length-1],d=Object.keys(r).some(function(t){return!!~["$unset","$set","$apply","$merge","$push","$unshift"].indexOf(t)});if(d){s[f]=!0;for(c in r){if("$unset"===c){var y=e[e.length-2];o.Array(t)?u[y]=t.slice(0,+p).concat(t.slice(+p+1)):(u[y]=i.shallowClone(t),delete u[y][p]);break}if("$set"===c){l=r.$set,t[p]=l;break}if("$apply"===c){if(h=r.$apply,"function"!=typeof h)throw n(e,"using command $apply with a non function");t[p]=h.call(null,t[p]);break}if("$merge"===c){if(l=r.$merge,!o.Object(t[p])||!o.Object(l))throw n(e,"using command $merge with a non object");t[p]=i.shallowMerge(t[p],l);break}if("$push"===c){if(l=r.$push,!o.Array(t[p]))throw n(e,"using command $push to a non array");t[p]=t[p].concat(l)}if("$unshift"===c){if(l=r.$unshift,!o.Array(t[p]))throw n(e,"using command $unshift to a non array");t[p]=[].concat(l).concat(t[p])}}}else for(c in r)t[p][c]="undefined"==typeof t[p][c]?{}:i.shallowClone(t[p][c]),a(t[p],r[c],e.concat(c),t)};return a(t,r),{data:t.root,log:Object.keys(s).map(function(t){return t.split("|λ|").slice(1)})}}},{"./helpers.js":7,"./type.js":10}],12:[function(t,r,e){function n(t,r){function e(){u&&(a=r.map(function(t){return o.solvePath(n.tree.data,t,n.tree)}))}var n=this;i.call(this),this.tree=t;var a=r,u=r.some(s.ComplexPath);this.updateHandler=function(t){var r=o.solveUpdate(t.data.log,a);r&&n.emit("update")},e(),this.tree.on("update",this.updateHandler)}var i=t("emmett"),o=t("./helpers.js"),s=t("./type.js");o.inherits(n,i),n.prototype.release=function(){this.tree.off("update",this.updateHandler),this.tree=null,this.kill()},r.exports=n},{"./helpers.js":7,"./type.js":10,emmett:3}]},{},[1])(1)}); \ No newline at end of file +!function(t){if("object"==typeof exports&&"undefined"!=typeof module)module.exports=t();else if("function"==typeof define&&define.amd)define([],t);else{var r;r="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:this,r.Baobab=t()}}(function(){var t;return function r(t,e,n){function i(s,a){if(!e[s]){if(!t[s]){var u="function"==typeof require&&require;if(!a&&u)return u(s,!0);if(o)return o(s,!0);var h=new Error("Cannot find module '"+s+"'");throw h.code="MODULE_NOT_FOUND",h}var c=e[s]={exports:{}};t[s][0].call(c.exports,function(r){var e=t[s][1][r];return i(e?e:r)},c,c.exports,r,t,e,n)}return e[s].exports}for(var o="function"==typeof require&&require,s=0;sn;n++)t[n].fn!==r&&i.push(t[n]);return i}var s={once:"boolean",scope:"object"},a=0,u=function(){this._enabled=!0,this.unbindAll()};u.prototype.unbindAll=function(){return this._handlers={},this._handlersAll=[],this._handlersComplex=[],this},u.prototype.on=function(t,r,e){var n,o,u,h,c,l,f;if(i(t)){for(h in t)this.on(h,t[h],r);return this}for("function"==typeof t&&(e=r,r=t,t=null),c=[].concat(t),n=0,o=c.length;o>n;n++){if(h=c[n],f={order:a++,fn:r},"string"==typeof h)this._handlers[h]||(this._handlers[h]=[]),l=this._handlers[h];else if(h instanceof RegExp)l=this._handlersComplex,f.pattern=h;else{if(null!==h)throw Error("Emitter.on: invalid event.");l=this._handlersAll}for(u in e||{})s[u]&&(f[u]=e[u]);f.once&&(f.parent=l),l.push(f)}return this},u.prototype.once=function(){var t=Array.prototype.slice.call(arguments),e=t.length-1;return i(t[e])&&t.length>1?t[e]=r(t[e],{once:!0}):t.push({once:!0}),this.on.apply(this,t)},u.prototype.off=function(t,r){var e,n,s,a;if(1===arguments.length&&"function"==typeof t){r=arguments[0];for(s in this._handlers)this._handlers[s]=o(this._handlers[s],r),0===this._handlers[s].length&&delete this._handlers[s];this._handlersAll=o(this._handlersAll,r),this._handlersComplex=o(this._handlersComplex,r)}else if(1===arguments.length&&"string"==typeof t)delete this._handlers[t];else if(2===arguments.length){var u=[].concat(t);for(e=0,n=u.length;n>e;e++)a=u[e],this._handlers[a]=o(this._handlers[a],r),0===(this._handlers[a]||[]).length&&delete this._handlers[a]}else if(i(t))for(s in t)this.off(s,t[s]);return this},u.prototype.listeners=function(t){var r,e,n,i=this._handlersAll||[],o=!1;if(!t)throw Error("Emitter.listeners: no event provided.");for(i=i.concat(this._handlers[t]||[]),e=0,n=this._handlersComplex.length;n>e;e++)r=this._handlersComplex[e],~t.search(r.pattern)&&(o=!0,i.push(r));return this._handlersAll.length||o?i.sort(function(t,r){return t.order-r.order}):i.slice(0)},u.prototype.emit=function(t,r){if(!this._enabled)return this;if(i(t)){for(var e in t)this.emit(e,t[e]);return this}var n,o,s,a,u,h,c,l=[].concat(t),f=[];for(a=0,h=l.length;h>a;a++){for(o=this.listeners(l[a]),u=0,c=o.length;c>u;u++)s=o[u],n={type:l[a],target:this},arguments.length>1&&(n.data=r),s.fn.call("scope"in s?s.scope:this,n),s.once&&f.push(s);for(u=f.length-1;u>=0;u--)f[u].parent.splice(f[u].parent.indexOf(f[u]),1)}return this},u.prototype.kill=function(){this.unbindAll(),this._handlers=null,this._handlersAll=null,this._handlersComplex=null,this._enabled=!1},u.prototype.disable=function(){return this._enabled=!1,this},u.prototype.enable=function(){return this._enabled=!0,this},u.version="3.0.0","undefined"!=typeof n?("undefined"!=typeof e&&e.exports&&(n=e.exports=u),n.Emitter=u):"function"==typeof t&&t.amd?t("emmett",[],function(){return u}):this.Emitter=u}).call(this)},{}],4:[function(t,r,e){function n(t){return t+"$"+(new Date).getTime()+(""+Math.random()).replace("0.","")}function i(t,r){function e(t){this[t]=function(){var r=this.root[t].apply(this.root,arguments);return r instanceof o?this:r}}if(arguments.length<1&&(t={}),!(this instanceof i))return new i(t,r);if(!d.Object(t)&&!d.Array(t))throw Error("Baobab: invalid data.");if(s.call(this),this.options=h.shallowMerge(p,r),this._transaction={},this._future=void 0,this._cursors={},this._identity="[object Baobab]",this.data=h.deepClone(t),this.root=this.select([]),this.facets={},["get","set","unset","update"].forEach(e.bind(this)),!d.Object(this.options.facets))throw Error("Baobab: invalid facets.");for(var n in this.options.facets)this.addFacet(n,this.options.facets[n]);this.mixin=f.baobab(this)}var o=t("./cursor.js"),s=t("emmett"),a=t("./watcher.js"),u=t("./facet.js"),h=t("./helpers.js"),c=t("./update.js"),l=t("./merge.js"),f=t("./mixins.js"),p=t("../defaults.js"),d=t("./type.js");h.inherits(i,s),i.prototype.addFacet=function(t,r){return this.facets[t]=this.createFacet(r),this},i.prototype.createFacet=function(t){return new u(this,t)},i.prototype.select=function(t){if(!t)throw Error("Baobab.select: invalid path.");if(arguments.length>1&&(t=h.arrayOf(arguments)),!d.Path(t))throw Error("Baobab.select: invalid path.");t=[].concat(t);var r,e=d.ComplexPath(t);e&&(r=h.solvePath(this.data,t,this));var i=t.map(function(t){return d.Function(t)?n("fn"):d.Object(t)?n("ob"):t}).join("|λ|");if(this._cursors[i])return this._cursors[i];var s=new o(this,t,r,i);return this._cursors[i]=s,s},i.prototype.stack=function(t){var r=this;if(!d.Object(t))throw Error("Baobab.update: wrong specification.");return this._transaction=l(t,this._transaction),this.options.autoCommit?this.options.asynchronous?(this._future||(this._future=setTimeout(r.commit.bind(r,null),0)),this):this.commit():this},i.prototype.commit=function(){var t=c(this.data,this._transaction,this.options),r=this.data;return this.data=t.data,this._transaction={},this._future&&(this._future=clearTimeout(this._future)),this.emit("update",{log:t.log,previousState:r}),this},i.prototype.watch=function(t){if(!d.Array(t)||t.some(function(t){return!d.Path(t)}))throw Error("Baobab.watch: invalid paths.");return new a(this,[].concat(t))},i.prototype.release=function(){var t;delete this.data,delete this._transaction;for(t in this._cursors)this._cursors[t].release();delete this._cursors;for(t in this.facets)this.facets[t].release();delete this.facets,this.kill()},i.prototype.toJSON=function(){return this.get()},i.prototype.toString=function(){return this._identity},r.exports=i},{"../defaults.js":2,"./cursor.js":5,"./facet.js":6,"./helpers.js":7,"./merge.js":8,"./mixins.js":9,"./type.js":10,"./update.js":11,"./watcher.js":12,emmett:3}],5:[function(t,r,e){function n(t,r,e,n){function i(t){if(o.isRecording()&&!o.undoing){var r=u.getIn(t,o.solvedPath,o.tree),e=u.deepClone(r);o.archive.add(e)}return o.undoing=!1,o.emit("update")}var o=this;s.call(this),r=r||[],this.tree=t,this.path=r,this.hash=n,this.archive=null,this.undoing=!1,this.complexPath=!!e,this.solvedPath=this.complexPath?e:this.path,this.relevant=void 0!==this.get(),this.updateHandler=function(t){var r=t.data.log,e=t.data.previousState,n=!1;if(o.complexPath&&(o.solvedPath=u.solvePath(o.tree.data,o.path,o.tree)),!o.path.length)return i(e);o.solvedPath&&(n=u.solveUpdate(r,[o.solvedPath]));var s=void 0!==o.get();o.relevant?s&&n?i(e):s||(o.emit("irrelevant"),o.relevant=!1):s&&n&&(o.emit("relevant"),i(e),o.relevant=!0)},this.mixin=a.cursor(this);var h=!1;this._lazyBind=function(){h||(h=!0,o.tree.on("update",o.updateHandler))},this.on=u.before(this._lazyBind,this.on.bind(this)),this.once=u.before(this._lazyBind,this.once.bind(this)),this.complexPath&&this._lazyBind()}function i(t,r,e,n){if(arguments.length>5)throw Error("baobab.Cursor."+t+": too many arguments.");arguments.length<4&&(n=e,e=[]),e=e||[];var i=[].concat(e),o=u.solvePath(this.get(),i,this.tree);if(!o)throw Error("baobab.Cursor."+t+": could not solve dynamic path.");if(r){var s=this.get(o);if(!h[r](s))throw Error("baobab.Cursor."+t+": invalid target.")}var a={};a["$"+t]=n;var c=u.pathObject(o,a);return c}function o(t,r){n.prototype[t]=function(){var e=i.bind(this,t,r).apply(this,arguments);return this.update(e)}}var s=t("emmett"),a=t("./mixins.js"),u=t("./helpers.js"),h=(t("../defaults.js"),t("./type.js"));u.inherits(n,s),n.prototype.isRoot=function(){return!this.path.length},n.prototype.isLeaf=function(){return h.Primitive(this.get())},n.prototype.isBranch=function(){return!this.isLeaf()&&!this.isRoot()},n.prototype.root=function(){return this.tree.root()},n.prototype.select=function(t){if(arguments.length>1&&(t=u.arrayOf(arguments)),!h.Path(t))throw Error("baobab.Cursor.select: invalid path.");return this.tree.select(this.path.concat(t))},n.prototype.up=function(){return this.solvedPath&&this.solvedPath.length?this.tree.select(this.path.slice(0,-1)):null},n.prototype.left=function(){var t=+this.solvedPath[this.solvedPath.length-1];if(isNaN(t))throw Error("baobab.Cursor.left: cannot go left on a non-list type.");return t?this.tree.select(this.solvedPath.slice(0,-1).concat(t-1)):null},n.prototype.leftmost=function(){var t=+this.solvedPath[this.solvedPath.length-1];if(isNaN(t))throw Error("baobab.Cursor.leftmost: cannot go left on a non-list type.");return this.tree.select(this.solvedPath.slice(0,-1).concat(0))},n.prototype.right=function(){var t=+this.solvedPath[this.solvedPath.length-1];if(isNaN(t))throw Error("baobab.Cursor.right: cannot go right on a non-list type.");return t+1===this.up().get().length?null:this.tree.select(this.solvedPath.slice(0,-1).concat(t+1))},n.prototype.rightmost=function(){var t=+this.solvedPath[this.solvedPath.length-1];if(isNaN(t))throw Error("baobab.Cursor.right: cannot go right on a non-list type.");var r=this.up().get();return this.tree.select(this.solvedPath.slice(0,-1).concat(r.length-1))},n.prototype.down=function(){+this.solvedPath[this.solvedPath.length-1];return this.get()instanceof Array?this.tree.select(this.solvedPath.concat(0)):null},n.prototype.get=function(t){arguments.length>1&&(t=u.arrayOf(arguments));var r=this.solvedPath.concat([].concat(t||0===t?t:[]));return u.getIn(this.tree.data,r,this.tree)},o("set"),o("apply"),o("chain"),o("push","Array"),o("unshift","Array"),n.prototype.merge=function(t){if(!h.Object(t))throw Error("baobab.Cursor.merge: trying to merge a non-object.");var r=i.bind(this,"merge","Object").apply(this,arguments);return this.update(r)},n.prototype.unset=function(t){if(void 0===t&&this.isRoot())throw Error("baobab.Cursor.unset: cannot remove root node.");var r=i.bind(this,"unset",null).apply(this,[t,!0]);return this.update(r)},n.prototype.update=function(t,r){if(arguments.length<2)return this.tree.stack(u.pathObject(this.solvedPath,t)),this;var e=[].concat(t),n=u.solvePath(this.get(),e,this.tree);if(!n)throw Error("baobab.Cursor.update: could not solve dynamic path.");return this.tree.stack(u.pathObject(this.solvedPath.concat(n),r)),this},n.prototype.startRecording=function(t){if(t=t||5,1>t)throw Error("baobab.Cursor.startRecording: invalid maximum number of records.");return this.archive?this:(this._lazyBind(),this.archive=u.archive(t),this)},n.prototype.stopRecording=function(){return this.archive=null,this},n.prototype.undo=function(t){if(t=t||1,!this.isRecording())throw Error("baobab.Cursor.undo: cursor is not recording.");if(!h.PositiveInteger(t))throw Error("baobab.Cursor.undo: expecting a positive integer.");var r=this.archive.back(t);if(!r)throw Error("boabab.Cursor.undo: cannot find a relevant record ("+t+" back).");return this.undoing=!0,this.set(r)},n.prototype.isRecording=function(){return!!this.archive},n.prototype.hasHistory=function(){return!(!this.archive||!this.archive.get().length)},n.prototype.getHistory=function(){return this.archive?this.archive.get():[]},n.prototype.release=function(){this.tree.off("update",this.updateHandler),this.hash&&delete this.tree._cursors[this.hash],delete this.tree,delete this.path,delete this.solvedPath,delete this.archive,this.kill()},n.prototype.toJSON=function(){return this.get()},h.Cursor=function(t){return t instanceof n},r.exports=n},{"../defaults.js":2,"./helpers.js":7,"./mixins.js":9,"./type.js":10,emmett:3}],6:[function(t,r,e){function n(t){return t}function i(t,r){function e(t){i[t]=l[t].bind(l)}var i=this,s=null,a=!1,u=r.get||n,h=r.cursors,c=Object.keys(h).map(function(t){return h[t]}),l=new o(t,c);["on","once","release"].forEach(e),this.get=function(){if(a)return s;var r={};for(var e in h)r[e]=t.get(h[e]);return s=u.call(null,r),a=!0,s},this.on("update",function(){a=!1})}{var o=t("./watcher.js");t("./helpers.js")}r.exports=i},{"./helpers.js":7,"./watcher.js":12}],7:[function(t,r,e){(function(e){function n(t){return Array.prototype.slice.call(t)}function i(t,r){return function(){t(),r.apply(null,arguments)}}function o(t,r){var e,n={};for(e in t)n[e]=t[e];for(e in r)n[e]=r[e];return n}function s(t,r){if(t===r)return!0;if("object"!=typeof t||"object"!=typeof r||null===t||null===r)return!1;var e=Object.keys(t),n=Object.keys(r);if(e.length!==n.length)return!1;var i,o;for(i=0,o=e.length;o>i;i++)if(t[e[i]]!==r[e[i]])return!1;return!0}function a(t){var r=t.source,e="";return t.global&&(e+="g"),t.multiline&&(e+="m"),t.ignoreCase&&(e+="i"),t.sticky&&(e+="y"),t.unicode&&(e+="u"),new RegExp(r,e)}function u(t,r){if(!r||"object"!=typeof r||r instanceof Error||"ArrayBuffer"in e&&r instanceof ArrayBuffer)return r;if(w.Array(r)){if(t){var n,i,o=[];for(n=0,i=r.length;i>n;n++)o.push(x(r[n]));return o}return r.slice(0)}if(w.Date(r))return new Date(r.getTime());if(r instanceof RegExp)return a(r);if(w.Object(r)){var s,u={};r.constructor&&r.constructor!==Object&&(u=Object.create(r.constructor.prototype));for(s in r)r.hasOwnProperty(s)&&(u[s]=t?x(r[s]):r[s]);return u}return r}function h(t,r){return function(e){return r(t(e))}}function c(t,r){var e,n;for(e=0,n=t.length;n>e;e++)if(r(t[e]))return t[e]}function l(t,r){var e,n;for(e=0,n=t.length;n>e;e++)if(r(t[e]))return e;return-1}function f(t,r){var e,n=!0;if(!t)return!1;for(e in r)if(w.Object(r[e]))n=n&&f(t[e],r[e]);else if(w.Array(r[e]))n=n&&!!~r[e].indexOf(t[e]);else if(t[e]!==r[e])return!1;return n}function d(t,r){return c(t,function(t){return f(t,r)})}function y(t,r){return l(t,function(t){return f(t,r)})}function b(t,r,e){r=r||[];var n,i,o,s=t;for(i=0,o=r.length;o>i;i++){if(!s)return;if("function"==typeof r[i]){if(!w.Array(s))return;s=c(s,r[i])}else if("object"==typeof r[i])if(e&&"$cursor"in r[i]){if(!w.Path(r[i].$cursor))throw Error("baobab.getIn: $cursor path must be an array.");n=e.get(r[i].$cursor),s=s[n]}else{if(!w.Array(s))return;s=d(s,r[i])}else s=s[r[i]]}return s}function g(t,r,e){var n,i,o,s=[],a=t;for(i=0,o=r.length;o>i;i++){if(!a)return null;if("function"==typeof r[i]){if(!w.Array(a))return;n=l(a,r[i]),s.push(n),a=a[n]}else if("object"==typeof r[i])if(e&&"$cursor"in r[i]){if(!w.Path(r[i].$cursor))throw Error("baobab.getIn: $cursor path must be an array.");p=e.get(r[i].$cursor),s.push(p),a=a[p]}else{if(!w.Array(a))return;n=y(a,r[i]),s.push(n),a=a[n]}else s.push(r[i]),a=a[r[i]]||{}}return s}function v(t,r){var e,n,i,o,s,a,u,h,c;for(e=0,o=r.length;o>e;e++)for(u=r[e],n=0,s=t.length;s>n;n++)for(h=t[n],i=0,a=h.length;a>i&&(c=h[i],c==u[i]);i++)if(i+1===a||i+1===u.length)return!0;return!1}function m(t,r){var e,n=t.length,i={},o=i;for(n||(i=r),e=0;n>e;e++)o[t[e]]=e+1===n?r:{},o=o[t[e]];return i}function _(t,r){t.super_=r;var e=function(){};e.prototype=r.prototype,t.prototype=new e,t.prototype.constructor=t}function j(t){var r=[];return{add:function(e){r.unshift(e),r.length>t&&(r.length=t)},back:function(t){var e=r[t-1];return e&&(r=r.slice(t)),e},get:function(){return r}}}var w=t("./type.js"),$=u.bind(null,!1),x=u.bind(null,!0);r.exports={archive:j,arrayOf:n,before:i,deepClone:x,shallowClone:$,shallowEqual:s,shallowMerge:o,compose:h,getIn:b,inherits:_,pathObject:m,solvePath:g,solveUpdate:v}}).call(this,"undefined"!=typeof global?global:"undefined"!=typeof self?self:"undefined"!=typeof window?window:{})},{"./type.js":10}],8:[function(t,r,e){function n(t,r,e){a.forEach(function(r){e!==r&&delete t[r]}),t[e]=r[e]}function i(t,r){var e,u=o.shallowClone(r||{});a.forEach(function(r){t[r]&&n(u,t,r)}),t.$chain&&(a.slice(0,-1).forEach(function(t){delete u[t]}),u.$apply=u.$apply?o.compose(u.$apply,t.$chain):t.$chain),t.$push&&u.$push?u.$push=s.Array(u.$push)?u.$push.concat(t.$push):[u.$push].concat(t.$push):t.$push&&(u.$push=t.$push),t.$unshift&&u.$unshift?u.$unshift=s.Array(t.$unshift)?t.$unshift.concat(u.$unshift):[t.$unshift].concat(u.$unshift):t.$unshift&&(u.$unshift=t.$unshift);for(e in t)s.Object(t[e])?u[e]=i(t[e],u[e]):"$"!==e[0]&&(u[e]=t[e]);return u}var o=t("./helpers.js"),s=t("./type.js"),a=["$unset","$set","$merge","$apply"];r.exports=i},{"./helpers.js":7,"./type.js":10}],9:[function(t,r,e){var n=t("./type.js");r.exports={baobab:function(t){return{mixins:[{getInitialState:function(){if(this.tree=t,!this.cursor&&!this.cursors)return{};if(this.cursor&&this.cursors)throw Error("baobab.mixin: you cannot have both `component.cursor` and `component.cursors`. Please make up your mind.");if(this.__type=null,this.__updateHandler=function(){this.setState(this.__getCursorData())}.bind(this),this.cursor){if(!n.MixinCursor(this.cursor))throw Error("baobab.mixin.cursor: invalid data (cursor, string, array or function).");n.Function(this.cursor)&&(this.cursor=this.cursor()),n.Cursor(this.cursor)||(this.cursor=t.select(this.cursor)),this.__getCursorData=function(){return{cursor:this.cursor.get()}}.bind(this),this.__type="single"}else if(this.cursors){if(!n.MixinCursors(this.cursors))throw Error("baobab.mixin.cursor: invalid data (object, array or function).");if(n.Function(this.cursors)&&(this.cursors=this.cursors()),n.Array(this.cursors))this.cursors=this.cursors.map(function(r){return n.Cursor(r)?r:t.select(r)}),this.__getCursorData=function(){return{cursors:this.cursors.map(function(t){return t.get()})}}.bind(this),this.__type="array";else{for(var r in this.cursors)n.Cursor(this.cursors[r])||(this.cursors[r]=t.select(this.cursors[r]));this.__getCursorData=function(){var t={};for(r in this.cursors)t[r]=this.cursors[r].get();return{cursors:t}}.bind(this),this.__type="object"}}return this.__getCursorData()},componentDidMount:function(){"single"===this.__type?(this.__watcher=this.tree.watch([this.cursor.path]),this.__watcher.on("update",this.__updateHandler)):"array"===this.__type?(this.__watcher=this.tree.watch(this.cursors.map(function(t){return t.path})),this.__watcher.on("update",this.__updateHandler)):"object"===this.__type&&(this.__watcher=this.tree.watch(Object.keys(this.cursors).map(function(t){return this.cursors[t].path},this)),this.__watcher.on("update",this.__updateHandler))},componentWillUnmount:function(){this.__watcher&&this.__watcher.release()}}].concat(t.options.mixins)}},cursor:function(t){return{mixins:[{getInitialState:function(){return this.cursor=t,this.__updateHandler=function(){this.setState({cursor:this.cursor.get()})}.bind(this),{cursor:this.cursor.get()}},componentDidMount:function(){this.cursor.on("update",this.__updateHandler)},componentWillUnmount:function(){this.cursor.off("update",this.__updateHandler)}}].concat(t.tree.options.mixins)}}}},{"./type.js":10}],10:[function(t,r,e){function n(t,r){return r.some(function(r){return i[r](t)})}var i={};i.Array=function(t){return Array.isArray(t)},i.Object=function(t){return t&&"object"==typeof t&&!Array.isArray(t)&&!(t instanceof Function)},i.String=function(t){return"string"==typeof t},i.Number=function(t){return"number"==typeof t},i.PositiveInteger=function(t){return"number"==typeof t&&t>0&&t%1===0},i.Function=function(t){return"function"==typeof t},i.Primitive=function(t){return"string"==typeof t||"number"==typeof t||"boolean"==typeof t},i.Date=function(t){return t instanceof Date},i.NonScalar=function(t){return i.Object(t)||i.Array(t)},i.Path=function(t){var r=["String","Number","Function","Object"];return i.Array(t)?t.every(function(t){return n(t,r)}):n(t,r)},i.MixinCursor=function(t){return n(t,["String","Number","Array","Function","Cursor"])},i.MixinCursors=function(t){return n(t,["Object","Array","Function"])},i.ComplexPath=function(t){return t.some(function(t){return n(t,["Object","Function"])})},r.exports=i},{}],11:[function(t,r,e){function n(t,r){var e=new Error("baobab.update: "+r+" at path /"+t.slice(1).join("/"));return e.path=t,e}var i=t("./helpers.js"),o=t("./type.js");r.exports=function(t,r,e){if(e=e||{},!o.Object(t)&&!o.Array(t))throw Error("baobab.update: invalid target.");var s={};t={root:i.shallowClone(t)};var a=function(t,r,e,u){e=e||["root"];var h,c,l,f=e.join("|λ|"),p=e[e.length-1],d=Object.keys(r).some(function(t){return!!~["$unset","$set","$apply","$merge","$push","$unshift"].indexOf(t)});if(d){s[f]=!0;for(c in r){if("$unset"===c){var y=e[e.length-2];o.Array(t)?u[y]=t.slice(0,+p).concat(t.slice(+p+1)):(u[y]=i.shallowClone(t),delete u[y][p]);break}if("$set"===c){l=r.$set,t[p]=l;break}if("$apply"===c){if(h=r.$apply,"function"!=typeof h)throw n(e,"using command $apply with a non function");t[p]=h.call(null,t[p]);break}if("$merge"===c){if(l=r.$merge,!o.Object(t[p])||!o.Object(l))throw n(e,"using command $merge with a non object");t[p]=i.shallowMerge(t[p],l);break}if("$push"===c){if(l=r.$push,!o.Array(t[p]))throw n(e,"using command $push to a non array");t[p]=t[p].concat(l)}if("$unshift"===c){if(l=r.$unshift,!o.Array(t[p]))throw n(e,"using command $unshift to a non array");t[p]=[].concat(l).concat(t[p])}}}else for(c in r)t[p][c]="undefined"==typeof t[p][c]?{}:i.shallowClone(t[p][c]),a(t[p],r[c],e.concat(c),t)};return a(t,r),{data:t.root,log:Object.keys(s).map(function(t){return t.split("|λ|").slice(1)})}}},{"./helpers.js":7,"./type.js":10}],12:[function(t,r,e){function n(t,r){function e(){u&&(a=r.map(function(t){return o.solvePath(n.tree.data,t,n.tree)}))}var n=this;i.call(this),this.tree=t;var a=r,u=r.some(s.ComplexPath);this.updateHandler=function(t){var r=o.solveUpdate(t.data.log,a);r&&n.emit("update")},e(),this.tree.on("update",this.updateHandler)}var i=t("emmett"),o=t("./helpers.js"),s=t("./type.js");o.inherits(n,i),n.prototype.release=function(){this.tree.off("update",this.updateHandler),this.tree=null,this.kill()},r.exports=n},{"./helpers.js":7,"./type.js":10,emmett:3}]},{},[1])(1)}); \ No newline at end of file diff --git a/src/baobab.js b/src/baobab.js index ebd092e..d1e02c4 100644 --- a/src/baobab.js +++ b/src/baobab.js @@ -44,6 +44,7 @@ function Baobab(initialData, opts) { this._transaction = {}; this._future = undefined; this._cursors = {}; + this._identity = '[object Baobab]'; // Properties this.data = helpers.deepClone(initialData); @@ -77,10 +78,14 @@ helpers.inherits(Baobab, EventEmitter); * Prototype */ Baobab.prototype.addFacet = function(name, definition) { - this.facets[name] = new Facet(this, definition); + this.facets[name] = this.createFacet(definition); return this; }; +Baobab.prototype.createFacet = function(definition) { + return new Facet(this, definition); +}; + Baobab.prototype.select = function(path) { if (!path) throw Error('Baobab.select: invalid path.'); @@ -206,6 +211,10 @@ Baobab.prototype.toJSON = function() { return this.get(); }; +Baobab.prototype.toString = function() { + return this._identity; +}; + /** * Export */ From a1d9578e005f165927c9413e0a5f9cc18416d3f7 Mon Sep 17 00:00:00 2001 From: Yomguithereal Date: Tue, 14 Apr 2015 17:24:47 +0200 Subject: [PATCH 49/73] Removing react mixins from core react integration will now be handled by Yomguithereal/baobab-react related to #161 --- build/baobab.min.js | 2 +- src/baobab.js | 4 - src/cursor.js | 4 - src/mixins.js | 146 ---------------- test/endpoint.js | 1 - test/suites/mixins.js | 396 ------------------------------------------ 6 files changed, 1 insertion(+), 552 deletions(-) delete mode 100644 src/mixins.js delete mode 100644 test/suites/mixins.js diff --git a/build/baobab.min.js b/build/baobab.min.js index 79a7df6..2f170ec 100644 --- a/build/baobab.min.js +++ b/build/baobab.min.js @@ -1,2 +1,2 @@ /* baobab.js - Version: 1.0.0-rc1 - Author: Yomguithereal (Guillaume Plique) */ -!function(t){if("object"==typeof exports&&"undefined"!=typeof module)module.exports=t();else if("function"==typeof define&&define.amd)define([],t);else{var r;r="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:this,r.Baobab=t()}}(function(){var t;return function r(t,e,n){function i(s,a){if(!e[s]){if(!t[s]){var u="function"==typeof require&&require;if(!a&&u)return u(s,!0);if(o)return o(s,!0);var h=new Error("Cannot find module '"+s+"'");throw h.code="MODULE_NOT_FOUND",h}var c=e[s]={exports:{}};t[s][0].call(c.exports,function(r){var e=t[s][1][r];return i(e?e:r)},c,c.exports,r,t,e,n)}return e[s].exports}for(var o="function"==typeof require&&require,s=0;sn;n++)t[n].fn!==r&&i.push(t[n]);return i}var s={once:"boolean",scope:"object"},a=0,u=function(){this._enabled=!0,this.unbindAll()};u.prototype.unbindAll=function(){return this._handlers={},this._handlersAll=[],this._handlersComplex=[],this},u.prototype.on=function(t,r,e){var n,o,u,h,c,l,f;if(i(t)){for(h in t)this.on(h,t[h],r);return this}for("function"==typeof t&&(e=r,r=t,t=null),c=[].concat(t),n=0,o=c.length;o>n;n++){if(h=c[n],f={order:a++,fn:r},"string"==typeof h)this._handlers[h]||(this._handlers[h]=[]),l=this._handlers[h];else if(h instanceof RegExp)l=this._handlersComplex,f.pattern=h;else{if(null!==h)throw Error("Emitter.on: invalid event.");l=this._handlersAll}for(u in e||{})s[u]&&(f[u]=e[u]);f.once&&(f.parent=l),l.push(f)}return this},u.prototype.once=function(){var t=Array.prototype.slice.call(arguments),e=t.length-1;return i(t[e])&&t.length>1?t[e]=r(t[e],{once:!0}):t.push({once:!0}),this.on.apply(this,t)},u.prototype.off=function(t,r){var e,n,s,a;if(1===arguments.length&&"function"==typeof t){r=arguments[0];for(s in this._handlers)this._handlers[s]=o(this._handlers[s],r),0===this._handlers[s].length&&delete this._handlers[s];this._handlersAll=o(this._handlersAll,r),this._handlersComplex=o(this._handlersComplex,r)}else if(1===arguments.length&&"string"==typeof t)delete this._handlers[t];else if(2===arguments.length){var u=[].concat(t);for(e=0,n=u.length;n>e;e++)a=u[e],this._handlers[a]=o(this._handlers[a],r),0===(this._handlers[a]||[]).length&&delete this._handlers[a]}else if(i(t))for(s in t)this.off(s,t[s]);return this},u.prototype.listeners=function(t){var r,e,n,i=this._handlersAll||[],o=!1;if(!t)throw Error("Emitter.listeners: no event provided.");for(i=i.concat(this._handlers[t]||[]),e=0,n=this._handlersComplex.length;n>e;e++)r=this._handlersComplex[e],~t.search(r.pattern)&&(o=!0,i.push(r));return this._handlersAll.length||o?i.sort(function(t,r){return t.order-r.order}):i.slice(0)},u.prototype.emit=function(t,r){if(!this._enabled)return this;if(i(t)){for(var e in t)this.emit(e,t[e]);return this}var n,o,s,a,u,h,c,l=[].concat(t),f=[];for(a=0,h=l.length;h>a;a++){for(o=this.listeners(l[a]),u=0,c=o.length;c>u;u++)s=o[u],n={type:l[a],target:this},arguments.length>1&&(n.data=r),s.fn.call("scope"in s?s.scope:this,n),s.once&&f.push(s);for(u=f.length-1;u>=0;u--)f[u].parent.splice(f[u].parent.indexOf(f[u]),1)}return this},u.prototype.kill=function(){this.unbindAll(),this._handlers=null,this._handlersAll=null,this._handlersComplex=null,this._enabled=!1},u.prototype.disable=function(){return this._enabled=!1,this},u.prototype.enable=function(){return this._enabled=!0,this},u.version="3.0.0","undefined"!=typeof n?("undefined"!=typeof e&&e.exports&&(n=e.exports=u),n.Emitter=u):"function"==typeof t&&t.amd?t("emmett",[],function(){return u}):this.Emitter=u}).call(this)},{}],4:[function(t,r,e){function n(t){return t+"$"+(new Date).getTime()+(""+Math.random()).replace("0.","")}function i(t,r){function e(t){this[t]=function(){var r=this.root[t].apply(this.root,arguments);return r instanceof o?this:r}}if(arguments.length<1&&(t={}),!(this instanceof i))return new i(t,r);if(!d.Object(t)&&!d.Array(t))throw Error("Baobab: invalid data.");if(s.call(this),this.options=h.shallowMerge(p,r),this._transaction={},this._future=void 0,this._cursors={},this._identity="[object Baobab]",this.data=h.deepClone(t),this.root=this.select([]),this.facets={},["get","set","unset","update"].forEach(e.bind(this)),!d.Object(this.options.facets))throw Error("Baobab: invalid facets.");for(var n in this.options.facets)this.addFacet(n,this.options.facets[n]);this.mixin=f.baobab(this)}var o=t("./cursor.js"),s=t("emmett"),a=t("./watcher.js"),u=t("./facet.js"),h=t("./helpers.js"),c=t("./update.js"),l=t("./merge.js"),f=t("./mixins.js"),p=t("../defaults.js"),d=t("./type.js");h.inherits(i,s),i.prototype.addFacet=function(t,r){return this.facets[t]=this.createFacet(r),this},i.prototype.createFacet=function(t){return new u(this,t)},i.prototype.select=function(t){if(!t)throw Error("Baobab.select: invalid path.");if(arguments.length>1&&(t=h.arrayOf(arguments)),!d.Path(t))throw Error("Baobab.select: invalid path.");t=[].concat(t);var r,e=d.ComplexPath(t);e&&(r=h.solvePath(this.data,t,this));var i=t.map(function(t){return d.Function(t)?n("fn"):d.Object(t)?n("ob"):t}).join("|λ|");if(this._cursors[i])return this._cursors[i];var s=new o(this,t,r,i);return this._cursors[i]=s,s},i.prototype.stack=function(t){var r=this;if(!d.Object(t))throw Error("Baobab.update: wrong specification.");return this._transaction=l(t,this._transaction),this.options.autoCommit?this.options.asynchronous?(this._future||(this._future=setTimeout(r.commit.bind(r,null),0)),this):this.commit():this},i.prototype.commit=function(){var t=c(this.data,this._transaction,this.options),r=this.data;return this.data=t.data,this._transaction={},this._future&&(this._future=clearTimeout(this._future)),this.emit("update",{log:t.log,previousState:r}),this},i.prototype.watch=function(t){if(!d.Array(t)||t.some(function(t){return!d.Path(t)}))throw Error("Baobab.watch: invalid paths.");return new a(this,[].concat(t))},i.prototype.release=function(){var t;delete this.data,delete this._transaction;for(t in this._cursors)this._cursors[t].release();delete this._cursors;for(t in this.facets)this.facets[t].release();delete this.facets,this.kill()},i.prototype.toJSON=function(){return this.get()},i.prototype.toString=function(){return this._identity},r.exports=i},{"../defaults.js":2,"./cursor.js":5,"./facet.js":6,"./helpers.js":7,"./merge.js":8,"./mixins.js":9,"./type.js":10,"./update.js":11,"./watcher.js":12,emmett:3}],5:[function(t,r,e){function n(t,r,e,n){function i(t){if(o.isRecording()&&!o.undoing){var r=u.getIn(t,o.solvedPath,o.tree),e=u.deepClone(r);o.archive.add(e)}return o.undoing=!1,o.emit("update")}var o=this;s.call(this),r=r||[],this.tree=t,this.path=r,this.hash=n,this.archive=null,this.undoing=!1,this.complexPath=!!e,this.solvedPath=this.complexPath?e:this.path,this.relevant=void 0!==this.get(),this.updateHandler=function(t){var r=t.data.log,e=t.data.previousState,n=!1;if(o.complexPath&&(o.solvedPath=u.solvePath(o.tree.data,o.path,o.tree)),!o.path.length)return i(e);o.solvedPath&&(n=u.solveUpdate(r,[o.solvedPath]));var s=void 0!==o.get();o.relevant?s&&n?i(e):s||(o.emit("irrelevant"),o.relevant=!1):s&&n&&(o.emit("relevant"),i(e),o.relevant=!0)},this.mixin=a.cursor(this);var h=!1;this._lazyBind=function(){h||(h=!0,o.tree.on("update",o.updateHandler))},this.on=u.before(this._lazyBind,this.on.bind(this)),this.once=u.before(this._lazyBind,this.once.bind(this)),this.complexPath&&this._lazyBind()}function i(t,r,e,n){if(arguments.length>5)throw Error("baobab.Cursor."+t+": too many arguments.");arguments.length<4&&(n=e,e=[]),e=e||[];var i=[].concat(e),o=u.solvePath(this.get(),i,this.tree);if(!o)throw Error("baobab.Cursor."+t+": could not solve dynamic path.");if(r){var s=this.get(o);if(!h[r](s))throw Error("baobab.Cursor."+t+": invalid target.")}var a={};a["$"+t]=n;var c=u.pathObject(o,a);return c}function o(t,r){n.prototype[t]=function(){var e=i.bind(this,t,r).apply(this,arguments);return this.update(e)}}var s=t("emmett"),a=t("./mixins.js"),u=t("./helpers.js"),h=(t("../defaults.js"),t("./type.js"));u.inherits(n,s),n.prototype.isRoot=function(){return!this.path.length},n.prototype.isLeaf=function(){return h.Primitive(this.get())},n.prototype.isBranch=function(){return!this.isLeaf()&&!this.isRoot()},n.prototype.root=function(){return this.tree.root()},n.prototype.select=function(t){if(arguments.length>1&&(t=u.arrayOf(arguments)),!h.Path(t))throw Error("baobab.Cursor.select: invalid path.");return this.tree.select(this.path.concat(t))},n.prototype.up=function(){return this.solvedPath&&this.solvedPath.length?this.tree.select(this.path.slice(0,-1)):null},n.prototype.left=function(){var t=+this.solvedPath[this.solvedPath.length-1];if(isNaN(t))throw Error("baobab.Cursor.left: cannot go left on a non-list type.");return t?this.tree.select(this.solvedPath.slice(0,-1).concat(t-1)):null},n.prototype.leftmost=function(){var t=+this.solvedPath[this.solvedPath.length-1];if(isNaN(t))throw Error("baobab.Cursor.leftmost: cannot go left on a non-list type.");return this.tree.select(this.solvedPath.slice(0,-1).concat(0))},n.prototype.right=function(){var t=+this.solvedPath[this.solvedPath.length-1];if(isNaN(t))throw Error("baobab.Cursor.right: cannot go right on a non-list type.");return t+1===this.up().get().length?null:this.tree.select(this.solvedPath.slice(0,-1).concat(t+1))},n.prototype.rightmost=function(){var t=+this.solvedPath[this.solvedPath.length-1];if(isNaN(t))throw Error("baobab.Cursor.right: cannot go right on a non-list type.");var r=this.up().get();return this.tree.select(this.solvedPath.slice(0,-1).concat(r.length-1))},n.prototype.down=function(){+this.solvedPath[this.solvedPath.length-1];return this.get()instanceof Array?this.tree.select(this.solvedPath.concat(0)):null},n.prototype.get=function(t){arguments.length>1&&(t=u.arrayOf(arguments));var r=this.solvedPath.concat([].concat(t||0===t?t:[]));return u.getIn(this.tree.data,r,this.tree)},o("set"),o("apply"),o("chain"),o("push","Array"),o("unshift","Array"),n.prototype.merge=function(t){if(!h.Object(t))throw Error("baobab.Cursor.merge: trying to merge a non-object.");var r=i.bind(this,"merge","Object").apply(this,arguments);return this.update(r)},n.prototype.unset=function(t){if(void 0===t&&this.isRoot())throw Error("baobab.Cursor.unset: cannot remove root node.");var r=i.bind(this,"unset",null).apply(this,[t,!0]);return this.update(r)},n.prototype.update=function(t,r){if(arguments.length<2)return this.tree.stack(u.pathObject(this.solvedPath,t)),this;var e=[].concat(t),n=u.solvePath(this.get(),e,this.tree);if(!n)throw Error("baobab.Cursor.update: could not solve dynamic path.");return this.tree.stack(u.pathObject(this.solvedPath.concat(n),r)),this},n.prototype.startRecording=function(t){if(t=t||5,1>t)throw Error("baobab.Cursor.startRecording: invalid maximum number of records.");return this.archive?this:(this._lazyBind(),this.archive=u.archive(t),this)},n.prototype.stopRecording=function(){return this.archive=null,this},n.prototype.undo=function(t){if(t=t||1,!this.isRecording())throw Error("baobab.Cursor.undo: cursor is not recording.");if(!h.PositiveInteger(t))throw Error("baobab.Cursor.undo: expecting a positive integer.");var r=this.archive.back(t);if(!r)throw Error("boabab.Cursor.undo: cannot find a relevant record ("+t+" back).");return this.undoing=!0,this.set(r)},n.prototype.isRecording=function(){return!!this.archive},n.prototype.hasHistory=function(){return!(!this.archive||!this.archive.get().length)},n.prototype.getHistory=function(){return this.archive?this.archive.get():[]},n.prototype.release=function(){this.tree.off("update",this.updateHandler),this.hash&&delete this.tree._cursors[this.hash],delete this.tree,delete this.path,delete this.solvedPath,delete this.archive,this.kill()},n.prototype.toJSON=function(){return this.get()},h.Cursor=function(t){return t instanceof n},r.exports=n},{"../defaults.js":2,"./helpers.js":7,"./mixins.js":9,"./type.js":10,emmett:3}],6:[function(t,r,e){function n(t){return t}function i(t,r){function e(t){i[t]=l[t].bind(l)}var i=this,s=null,a=!1,u=r.get||n,h=r.cursors,c=Object.keys(h).map(function(t){return h[t]}),l=new o(t,c);["on","once","release"].forEach(e),this.get=function(){if(a)return s;var r={};for(var e in h)r[e]=t.get(h[e]);return s=u.call(null,r),a=!0,s},this.on("update",function(){a=!1})}{var o=t("./watcher.js");t("./helpers.js")}r.exports=i},{"./helpers.js":7,"./watcher.js":12}],7:[function(t,r,e){(function(e){function n(t){return Array.prototype.slice.call(t)}function i(t,r){return function(){t(),r.apply(null,arguments)}}function o(t,r){var e,n={};for(e in t)n[e]=t[e];for(e in r)n[e]=r[e];return n}function s(t,r){if(t===r)return!0;if("object"!=typeof t||"object"!=typeof r||null===t||null===r)return!1;var e=Object.keys(t),n=Object.keys(r);if(e.length!==n.length)return!1;var i,o;for(i=0,o=e.length;o>i;i++)if(t[e[i]]!==r[e[i]])return!1;return!0}function a(t){var r=t.source,e="";return t.global&&(e+="g"),t.multiline&&(e+="m"),t.ignoreCase&&(e+="i"),t.sticky&&(e+="y"),t.unicode&&(e+="u"),new RegExp(r,e)}function u(t,r){if(!r||"object"!=typeof r||r instanceof Error||"ArrayBuffer"in e&&r instanceof ArrayBuffer)return r;if(w.Array(r)){if(t){var n,i,o=[];for(n=0,i=r.length;i>n;n++)o.push(x(r[n]));return o}return r.slice(0)}if(w.Date(r))return new Date(r.getTime());if(r instanceof RegExp)return a(r);if(w.Object(r)){var s,u={};r.constructor&&r.constructor!==Object&&(u=Object.create(r.constructor.prototype));for(s in r)r.hasOwnProperty(s)&&(u[s]=t?x(r[s]):r[s]);return u}return r}function h(t,r){return function(e){return r(t(e))}}function c(t,r){var e,n;for(e=0,n=t.length;n>e;e++)if(r(t[e]))return t[e]}function l(t,r){var e,n;for(e=0,n=t.length;n>e;e++)if(r(t[e]))return e;return-1}function f(t,r){var e,n=!0;if(!t)return!1;for(e in r)if(w.Object(r[e]))n=n&&f(t[e],r[e]);else if(w.Array(r[e]))n=n&&!!~r[e].indexOf(t[e]);else if(t[e]!==r[e])return!1;return n}function d(t,r){return c(t,function(t){return f(t,r)})}function y(t,r){return l(t,function(t){return f(t,r)})}function b(t,r,e){r=r||[];var n,i,o,s=t;for(i=0,o=r.length;o>i;i++){if(!s)return;if("function"==typeof r[i]){if(!w.Array(s))return;s=c(s,r[i])}else if("object"==typeof r[i])if(e&&"$cursor"in r[i]){if(!w.Path(r[i].$cursor))throw Error("baobab.getIn: $cursor path must be an array.");n=e.get(r[i].$cursor),s=s[n]}else{if(!w.Array(s))return;s=d(s,r[i])}else s=s[r[i]]}return s}function g(t,r,e){var n,i,o,s=[],a=t;for(i=0,o=r.length;o>i;i++){if(!a)return null;if("function"==typeof r[i]){if(!w.Array(a))return;n=l(a,r[i]),s.push(n),a=a[n]}else if("object"==typeof r[i])if(e&&"$cursor"in r[i]){if(!w.Path(r[i].$cursor))throw Error("baobab.getIn: $cursor path must be an array.");p=e.get(r[i].$cursor),s.push(p),a=a[p]}else{if(!w.Array(a))return;n=y(a,r[i]),s.push(n),a=a[n]}else s.push(r[i]),a=a[r[i]]||{}}return s}function v(t,r){var e,n,i,o,s,a,u,h,c;for(e=0,o=r.length;o>e;e++)for(u=r[e],n=0,s=t.length;s>n;n++)for(h=t[n],i=0,a=h.length;a>i&&(c=h[i],c==u[i]);i++)if(i+1===a||i+1===u.length)return!0;return!1}function m(t,r){var e,n=t.length,i={},o=i;for(n||(i=r),e=0;n>e;e++)o[t[e]]=e+1===n?r:{},o=o[t[e]];return i}function _(t,r){t.super_=r;var e=function(){};e.prototype=r.prototype,t.prototype=new e,t.prototype.constructor=t}function j(t){var r=[];return{add:function(e){r.unshift(e),r.length>t&&(r.length=t)},back:function(t){var e=r[t-1];return e&&(r=r.slice(t)),e},get:function(){return r}}}var w=t("./type.js"),$=u.bind(null,!1),x=u.bind(null,!0);r.exports={archive:j,arrayOf:n,before:i,deepClone:x,shallowClone:$,shallowEqual:s,shallowMerge:o,compose:h,getIn:b,inherits:_,pathObject:m,solvePath:g,solveUpdate:v}}).call(this,"undefined"!=typeof global?global:"undefined"!=typeof self?self:"undefined"!=typeof window?window:{})},{"./type.js":10}],8:[function(t,r,e){function n(t,r,e){a.forEach(function(r){e!==r&&delete t[r]}),t[e]=r[e]}function i(t,r){var e,u=o.shallowClone(r||{});a.forEach(function(r){t[r]&&n(u,t,r)}),t.$chain&&(a.slice(0,-1).forEach(function(t){delete u[t]}),u.$apply=u.$apply?o.compose(u.$apply,t.$chain):t.$chain),t.$push&&u.$push?u.$push=s.Array(u.$push)?u.$push.concat(t.$push):[u.$push].concat(t.$push):t.$push&&(u.$push=t.$push),t.$unshift&&u.$unshift?u.$unshift=s.Array(t.$unshift)?t.$unshift.concat(u.$unshift):[t.$unshift].concat(u.$unshift):t.$unshift&&(u.$unshift=t.$unshift);for(e in t)s.Object(t[e])?u[e]=i(t[e],u[e]):"$"!==e[0]&&(u[e]=t[e]);return u}var o=t("./helpers.js"),s=t("./type.js"),a=["$unset","$set","$merge","$apply"];r.exports=i},{"./helpers.js":7,"./type.js":10}],9:[function(t,r,e){var n=t("./type.js");r.exports={baobab:function(t){return{mixins:[{getInitialState:function(){if(this.tree=t,!this.cursor&&!this.cursors)return{};if(this.cursor&&this.cursors)throw Error("baobab.mixin: you cannot have both `component.cursor` and `component.cursors`. Please make up your mind.");if(this.__type=null,this.__updateHandler=function(){this.setState(this.__getCursorData())}.bind(this),this.cursor){if(!n.MixinCursor(this.cursor))throw Error("baobab.mixin.cursor: invalid data (cursor, string, array or function).");n.Function(this.cursor)&&(this.cursor=this.cursor()),n.Cursor(this.cursor)||(this.cursor=t.select(this.cursor)),this.__getCursorData=function(){return{cursor:this.cursor.get()}}.bind(this),this.__type="single"}else if(this.cursors){if(!n.MixinCursors(this.cursors))throw Error("baobab.mixin.cursor: invalid data (object, array or function).");if(n.Function(this.cursors)&&(this.cursors=this.cursors()),n.Array(this.cursors))this.cursors=this.cursors.map(function(r){return n.Cursor(r)?r:t.select(r)}),this.__getCursorData=function(){return{cursors:this.cursors.map(function(t){return t.get()})}}.bind(this),this.__type="array";else{for(var r in this.cursors)n.Cursor(this.cursors[r])||(this.cursors[r]=t.select(this.cursors[r]));this.__getCursorData=function(){var t={};for(r in this.cursors)t[r]=this.cursors[r].get();return{cursors:t}}.bind(this),this.__type="object"}}return this.__getCursorData()},componentDidMount:function(){"single"===this.__type?(this.__watcher=this.tree.watch([this.cursor.path]),this.__watcher.on("update",this.__updateHandler)):"array"===this.__type?(this.__watcher=this.tree.watch(this.cursors.map(function(t){return t.path})),this.__watcher.on("update",this.__updateHandler)):"object"===this.__type&&(this.__watcher=this.tree.watch(Object.keys(this.cursors).map(function(t){return this.cursors[t].path},this)),this.__watcher.on("update",this.__updateHandler))},componentWillUnmount:function(){this.__watcher&&this.__watcher.release()}}].concat(t.options.mixins)}},cursor:function(t){return{mixins:[{getInitialState:function(){return this.cursor=t,this.__updateHandler=function(){this.setState({cursor:this.cursor.get()})}.bind(this),{cursor:this.cursor.get()}},componentDidMount:function(){this.cursor.on("update",this.__updateHandler)},componentWillUnmount:function(){this.cursor.off("update",this.__updateHandler)}}].concat(t.tree.options.mixins)}}}},{"./type.js":10}],10:[function(t,r,e){function n(t,r){return r.some(function(r){return i[r](t)})}var i={};i.Array=function(t){return Array.isArray(t)},i.Object=function(t){return t&&"object"==typeof t&&!Array.isArray(t)&&!(t instanceof Function)},i.String=function(t){return"string"==typeof t},i.Number=function(t){return"number"==typeof t},i.PositiveInteger=function(t){return"number"==typeof t&&t>0&&t%1===0},i.Function=function(t){return"function"==typeof t},i.Primitive=function(t){return"string"==typeof t||"number"==typeof t||"boolean"==typeof t},i.Date=function(t){return t instanceof Date},i.NonScalar=function(t){return i.Object(t)||i.Array(t)},i.Path=function(t){var r=["String","Number","Function","Object"];return i.Array(t)?t.every(function(t){return n(t,r)}):n(t,r)},i.MixinCursor=function(t){return n(t,["String","Number","Array","Function","Cursor"])},i.MixinCursors=function(t){return n(t,["Object","Array","Function"])},i.ComplexPath=function(t){return t.some(function(t){return n(t,["Object","Function"])})},r.exports=i},{}],11:[function(t,r,e){function n(t,r){var e=new Error("baobab.update: "+r+" at path /"+t.slice(1).join("/"));return e.path=t,e}var i=t("./helpers.js"),o=t("./type.js");r.exports=function(t,r,e){if(e=e||{},!o.Object(t)&&!o.Array(t))throw Error("baobab.update: invalid target.");var s={};t={root:i.shallowClone(t)};var a=function(t,r,e,u){e=e||["root"];var h,c,l,f=e.join("|λ|"),p=e[e.length-1],d=Object.keys(r).some(function(t){return!!~["$unset","$set","$apply","$merge","$push","$unshift"].indexOf(t)});if(d){s[f]=!0;for(c in r){if("$unset"===c){var y=e[e.length-2];o.Array(t)?u[y]=t.slice(0,+p).concat(t.slice(+p+1)):(u[y]=i.shallowClone(t),delete u[y][p]);break}if("$set"===c){l=r.$set,t[p]=l;break}if("$apply"===c){if(h=r.$apply,"function"!=typeof h)throw n(e,"using command $apply with a non function");t[p]=h.call(null,t[p]);break}if("$merge"===c){if(l=r.$merge,!o.Object(t[p])||!o.Object(l))throw n(e,"using command $merge with a non object");t[p]=i.shallowMerge(t[p],l);break}if("$push"===c){if(l=r.$push,!o.Array(t[p]))throw n(e,"using command $push to a non array");t[p]=t[p].concat(l)}if("$unshift"===c){if(l=r.$unshift,!o.Array(t[p]))throw n(e,"using command $unshift to a non array");t[p]=[].concat(l).concat(t[p])}}}else for(c in r)t[p][c]="undefined"==typeof t[p][c]?{}:i.shallowClone(t[p][c]),a(t[p],r[c],e.concat(c),t)};return a(t,r),{data:t.root,log:Object.keys(s).map(function(t){return t.split("|λ|").slice(1)})}}},{"./helpers.js":7,"./type.js":10}],12:[function(t,r,e){function n(t,r){function e(){u&&(a=r.map(function(t){return o.solvePath(n.tree.data,t,n.tree)}))}var n=this;i.call(this),this.tree=t;var a=r,u=r.some(s.ComplexPath);this.updateHandler=function(t){var r=o.solveUpdate(t.data.log,a);r&&n.emit("update")},e(),this.tree.on("update",this.updateHandler)}var i=t("emmett"),o=t("./helpers.js"),s=t("./type.js");o.inherits(n,i),n.prototype.release=function(){this.tree.off("update",this.updateHandler),this.tree=null,this.kill()},r.exports=n},{"./helpers.js":7,"./type.js":10,emmett:3}]},{},[1])(1)}); \ No newline at end of file +!function(t){if("object"==typeof exports&&"undefined"!=typeof module)module.exports=t();else if("function"==typeof define&&define.amd)define([],t);else{var e;e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:this,e.Baobab=t()}}(function(){var t;return function e(t,r,n){function o(s,a){if(!r[s]){if(!t[s]){var h="function"==typeof require&&require;if(!a&&h)return h(s,!0);if(i)return i(s,!0);var u=new Error("Cannot find module '"+s+"'");throw u.code="MODULE_NOT_FOUND",u}var c=r[s]={exports:{}};t[s][0].call(c.exports,function(e){var r=t[s][1][e];return o(r?r:e)},c,c.exports,e,t,r,n)}return r[s].exports}for(var i="function"==typeof require&&require,s=0;sn;n++)t[n].fn!==e&&o.push(t[n]);return o}var s={once:"boolean",scope:"object"},a=0,h=function(){this._enabled=!0,this.unbindAll()};h.prototype.unbindAll=function(){return this._handlers={},this._handlersAll=[],this._handlersComplex=[],this},h.prototype.on=function(t,e,r){var n,i,h,u,c,l,f;if(o(t)){for(u in t)this.on(u,t[u],e);return this}for("function"==typeof t&&(r=e,e=t,t=null),c=[].concat(t),n=0,i=c.length;i>n;n++){if(u=c[n],f={order:a++,fn:e},"string"==typeof u)this._handlers[u]||(this._handlers[u]=[]),l=this._handlers[u];else if(u instanceof RegExp)l=this._handlersComplex,f.pattern=u;else{if(null!==u)throw Error("Emitter.on: invalid event.");l=this._handlersAll}for(h in r||{})s[h]&&(f[h]=r[h]);f.once&&(f.parent=l),l.push(f)}return this},h.prototype.once=function(){var t=Array.prototype.slice.call(arguments),r=t.length-1;return o(t[r])&&t.length>1?t[r]=e(t[r],{once:!0}):t.push({once:!0}),this.on.apply(this,t)},h.prototype.off=function(t,e){var r,n,s,a;if(1===arguments.length&&"function"==typeof t){e=arguments[0];for(s in this._handlers)this._handlers[s]=i(this._handlers[s],e),0===this._handlers[s].length&&delete this._handlers[s];this._handlersAll=i(this._handlersAll,e),this._handlersComplex=i(this._handlersComplex,e)}else if(1===arguments.length&&"string"==typeof t)delete this._handlers[t];else if(2===arguments.length){var h=[].concat(t);for(r=0,n=h.length;n>r;r++)a=h[r],this._handlers[a]=i(this._handlers[a],e),0===(this._handlers[a]||[]).length&&delete this._handlers[a]}else if(o(t))for(s in t)this.off(s,t[s]);return this},h.prototype.listeners=function(t){var e,r,n,o=this._handlersAll||[],i=!1;if(!t)throw Error("Emitter.listeners: no event provided.");for(o=o.concat(this._handlers[t]||[]),r=0,n=this._handlersComplex.length;n>r;r++)e=this._handlersComplex[r],~t.search(e.pattern)&&(i=!0,o.push(e));return this._handlersAll.length||i?o.sort(function(t,e){return t.order-e.order}):o.slice(0)},h.prototype.emit=function(t,e){if(!this._enabled)return this;if(o(t)){for(var r in t)this.emit(r,t[r]);return this}var n,i,s,a,h,u,c,l=[].concat(t),f=[];for(a=0,u=l.length;u>a;a++){for(i=this.listeners(l[a]),h=0,c=i.length;c>h;h++)s=i[h],n={type:l[a],target:this},arguments.length>1&&(n.data=e),s.fn.call("scope"in s?s.scope:this,n),s.once&&f.push(s);for(h=f.length-1;h>=0;h--)f[h].parent.splice(f[h].parent.indexOf(f[h]),1)}return this},h.prototype.kill=function(){this.unbindAll(),this._handlers=null,this._handlersAll=null,this._handlersComplex=null,this._enabled=!1},h.prototype.disable=function(){return this._enabled=!1,this},h.prototype.enable=function(){return this._enabled=!0,this},h.version="3.0.0","undefined"!=typeof n?("undefined"!=typeof r&&r.exports&&(n=r.exports=h),n.Emitter=h):"function"==typeof t&&t.amd?t("emmett",[],function(){return h}):this.Emitter=h}).call(this)},{}],4:[function(t,e,r){function n(t){return t+"$"+(new Date).getTime()+(""+Math.random()).replace("0.","")}function o(t,e){function r(t){this[t]=function(){var e=this.root[t].apply(this.root,arguments);return e instanceof i?this:e}}if(arguments.length<1&&(t={}),!(this instanceof o))return new o(t,e);if(!p.Object(t)&&!p.Array(t))throw Error("Baobab: invalid data.");if(s.call(this),this.options=u.shallowMerge(f,e),this._transaction={},this._future=void 0,this._cursors={},this._identity="[object Baobab]",this.data=u.deepClone(t),this.root=this.select([]),this.facets={},["get","set","unset","update"].forEach(r.bind(this)),!p.Object(this.options.facets))throw Error("Baobab: invalid facets.");for(var n in this.options.facets)this.addFacet(n,this.options.facets[n])}var i=t("./cursor.js"),s=t("emmett"),a=t("./watcher.js"),h=t("./facet.js"),u=t("./helpers.js"),c=t("./update.js"),l=t("./merge.js"),f=t("../defaults.js"),p=t("./type.js");u.inherits(o,s),o.prototype.addFacet=function(t,e){return this.facets[t]=this.createFacet(e),this},o.prototype.createFacet=function(t){return new h(this,t)},o.prototype.select=function(t){if(!t)throw Error("Baobab.select: invalid path.");if(arguments.length>1&&(t=u.arrayOf(arguments)),!p.Path(t))throw Error("Baobab.select: invalid path.");t=[].concat(t);var e,r=p.ComplexPath(t);r&&(e=u.solvePath(this.data,t,this));var o=t.map(function(t){return p.Function(t)?n("fn"):p.Object(t)?n("ob"):t}).join("|λ|");if(this._cursors[o])return this._cursors[o];var s=new i(this,t,e,o);return this._cursors[o]=s,s},o.prototype.stack=function(t){var e=this;if(!p.Object(t))throw Error("Baobab.update: wrong specification.");return this._transaction=l(t,this._transaction),this.options.autoCommit?this.options.asynchronous?(this._future||(this._future=setTimeout(e.commit.bind(e,null),0)),this):this.commit():this},o.prototype.commit=function(){var t=c(this.data,this._transaction,this.options),e=this.data;return this.data=t.data,this._transaction={},this._future&&(this._future=clearTimeout(this._future)),this.emit("update",{log:t.log,previousState:e}),this},o.prototype.watch=function(t){if(!p.Array(t)||t.some(function(t){return!p.Path(t)}))throw Error("Baobab.watch: invalid paths.");return new a(this,[].concat(t))},o.prototype.release=function(){var t;delete this.data,delete this._transaction;for(t in this._cursors)this._cursors[t].release();delete this._cursors;for(t in this.facets)this.facets[t].release();delete this.facets,this.kill()},o.prototype.toJSON=function(){return this.get()},o.prototype.toString=function(){return this._identity},e.exports=o},{"../defaults.js":2,"./cursor.js":5,"./facet.js":6,"./helpers.js":7,"./merge.js":8,"./type.js":9,"./update.js":10,"./watcher.js":11,emmett:3}],5:[function(t,e,r){function n(t,e,r,n){function o(t){if(i.isRecording()&&!i.undoing){var e=a.getIn(t,i.solvedPath,i.tree),r=a.deepClone(e);i.archive.add(r)}return i.undoing=!1,i.emit("update")}var i=this;s.call(this),e=e||[],this.tree=t,this.path=e,this.hash=n,this.archive=null,this.undoing=!1,this.complexPath=!!r,this.solvedPath=this.complexPath?r:this.path,this.relevant=void 0!==this.get(),this.updateHandler=function(t){var e=t.data.log,r=t.data.previousState,n=!1;if(i.complexPath&&(i.solvedPath=a.solvePath(i.tree.data,i.path,i.tree)),!i.path.length)return o(r);i.solvedPath&&(n=a.solveUpdate(e,[i.solvedPath]));var s=void 0!==i.get();i.relevant?s&&n?o(r):s||(i.emit("irrelevant"),i.relevant=!1):s&&n&&(i.emit("relevant"),o(r),i.relevant=!0)};var h=!1;this._lazyBind=function(){h||(h=!0,i.tree.on("update",i.updateHandler))},this.on=a.before(this._lazyBind,this.on.bind(this)),this.once=a.before(this._lazyBind,this.once.bind(this)),this.complexPath&&this._lazyBind()}function o(t,e,r,n){if(arguments.length>5)throw Error("baobab.Cursor."+t+": too many arguments.");arguments.length<4&&(n=r,r=[]),r=r||[];var o=[].concat(r),i=a.solvePath(this.get(),o,this.tree);if(!i)throw Error("baobab.Cursor."+t+": could not solve dynamic path.");if(e){var s=this.get(i);if(!h[e](s))throw Error("baobab.Cursor."+t+": invalid target.")}var u={};u["$"+t]=n;var c=a.pathObject(i,u);return c}function i(t,e){n.prototype[t]=function(){var r=o.bind(this,t,e).apply(this,arguments);return this.update(r)}}var s=t("emmett"),a=t("./helpers.js"),h=(t("../defaults.js"),t("./type.js"));a.inherits(n,s),n.prototype.isRoot=function(){return!this.path.length},n.prototype.isLeaf=function(){return h.Primitive(this.get())},n.prototype.isBranch=function(){return!this.isLeaf()&&!this.isRoot()},n.prototype.root=function(){return this.tree.root()},n.prototype.select=function(t){if(arguments.length>1&&(t=a.arrayOf(arguments)),!h.Path(t))throw Error("baobab.Cursor.select: invalid path.");return this.tree.select(this.path.concat(t))},n.prototype.up=function(){return this.solvedPath&&this.solvedPath.length?this.tree.select(this.path.slice(0,-1)):null},n.prototype.left=function(){var t=+this.solvedPath[this.solvedPath.length-1];if(isNaN(t))throw Error("baobab.Cursor.left: cannot go left on a non-list type.");return t?this.tree.select(this.solvedPath.slice(0,-1).concat(t-1)):null},n.prototype.leftmost=function(){var t=+this.solvedPath[this.solvedPath.length-1];if(isNaN(t))throw Error("baobab.Cursor.leftmost: cannot go left on a non-list type.");return this.tree.select(this.solvedPath.slice(0,-1).concat(0))},n.prototype.right=function(){var t=+this.solvedPath[this.solvedPath.length-1];if(isNaN(t))throw Error("baobab.Cursor.right: cannot go right on a non-list type.");return t+1===this.up().get().length?null:this.tree.select(this.solvedPath.slice(0,-1).concat(t+1))},n.prototype.rightmost=function(){var t=+this.solvedPath[this.solvedPath.length-1];if(isNaN(t))throw Error("baobab.Cursor.right: cannot go right on a non-list type.");var e=this.up().get();return this.tree.select(this.solvedPath.slice(0,-1).concat(e.length-1))},n.prototype.down=function(){+this.solvedPath[this.solvedPath.length-1];return this.get()instanceof Array?this.tree.select(this.solvedPath.concat(0)):null},n.prototype.get=function(t){arguments.length>1&&(t=a.arrayOf(arguments));var e=this.solvedPath.concat([].concat(t||0===t?t:[]));return a.getIn(this.tree.data,e,this.tree)},i("set"),i("apply"),i("chain"),i("push","Array"),i("unshift","Array"),n.prototype.merge=function(t){if(!h.Object(t))throw Error("baobab.Cursor.merge: trying to merge a non-object.");var e=o.bind(this,"merge","Object").apply(this,arguments);return this.update(e)},n.prototype.unset=function(t){if(void 0===t&&this.isRoot())throw Error("baobab.Cursor.unset: cannot remove root node.");var e=o.bind(this,"unset",null).apply(this,[t,!0]);return this.update(e)},n.prototype.update=function(t,e){if(arguments.length<2)return this.tree.stack(a.pathObject(this.solvedPath,t)),this;var r=[].concat(t),n=a.solvePath(this.get(),r,this.tree);if(!n)throw Error("baobab.Cursor.update: could not solve dynamic path.");return this.tree.stack(a.pathObject(this.solvedPath.concat(n),e)),this},n.prototype.startRecording=function(t){if(t=t||5,1>t)throw Error("baobab.Cursor.startRecording: invalid maximum number of records.");return this.archive?this:(this._lazyBind(),this.archive=a.archive(t),this)},n.prototype.stopRecording=function(){return this.archive=null,this},n.prototype.undo=function(t){if(t=t||1,!this.isRecording())throw Error("baobab.Cursor.undo: cursor is not recording.");if(!h.PositiveInteger(t))throw Error("baobab.Cursor.undo: expecting a positive integer.");var e=this.archive.back(t);if(!e)throw Error("boabab.Cursor.undo: cannot find a relevant record ("+t+" back).");return this.undoing=!0,this.set(e)},n.prototype.isRecording=function(){return!!this.archive},n.prototype.hasHistory=function(){return!(!this.archive||!this.archive.get().length)},n.prototype.getHistory=function(){return this.archive?this.archive.get():[]},n.prototype.release=function(){this.tree.off("update",this.updateHandler),this.hash&&delete this.tree._cursors[this.hash],delete this.tree,delete this.path,delete this.solvedPath,delete this.archive,this.kill()},n.prototype.toJSON=function(){return this.get()},h.Cursor=function(t){return t instanceof n},e.exports=n},{"../defaults.js":2,"./helpers.js":7,"./type.js":9,emmett:3}],6:[function(t,e,r){function n(t){return t}function o(t,e){function r(t){o[t]=l[t].bind(l)}var o=this,s=null,a=!1,h=e.get||n,u=e.cursors,c=Object.keys(u).map(function(t){return u[t]}),l=new i(t,c);["on","once","release"].forEach(r),this.get=function(){if(a)return s;var e={};for(var r in u)e[r]=t.get(u[r]);return s=h.call(null,e),a=!0,s},this.on("update",function(){a=!1})}{var i=t("./watcher.js");t("./helpers.js")}e.exports=o},{"./helpers.js":7,"./watcher.js":11}],7:[function(t,e,r){(function(r){function n(t){return Array.prototype.slice.call(t)}function o(t,e){return function(){t(),e.apply(null,arguments)}}function i(t,e){var r,n={};for(r in t)n[r]=t[r];for(r in e)n[r]=e[r];return n}function s(t,e){if(t===e)return!0;if("object"!=typeof t||"object"!=typeof e||null===t||null===e)return!1;var r=Object.keys(t),n=Object.keys(e);if(r.length!==n.length)return!1;var o,i;for(o=0,i=r.length;i>o;o++)if(t[r[o]]!==e[r[o]])return!1;return!0}function a(t){var e=t.source,r="";return t.global&&(r+="g"),t.multiline&&(r+="m"),t.ignoreCase&&(r+="i"),t.sticky&&(r+="y"),t.unicode&&(r+="u"),new RegExp(e,r)}function h(t,e){if(!e||"object"!=typeof e||e instanceof Error||"ArrayBuffer"in r&&e instanceof ArrayBuffer)return e;if(_.Array(e)){if(t){var n,o,i=[];for(n=0,o=e.length;o>n;n++)i.push(P(e[n]));return i}return e.slice(0)}if(_.Date(e))return new Date(e.getTime());if(e instanceof RegExp)return a(e);if(_.Object(e)){var s,h={};e.constructor&&e.constructor!==Object&&(h=Object.create(e.constructor.prototype));for(s in e)e.hasOwnProperty(s)&&(h[s]=t?P(e[s]):e[s]);return h}return e}function u(t,e){return function(r){return e(t(r))}}function c(t,e){var r,n;for(r=0,n=t.length;n>r;r++)if(e(t[r]))return t[r]}function l(t,e){var r,n;for(r=0,n=t.length;n>r;r++)if(e(t[r]))return r;return-1}function f(t,e){var r,n=!0;if(!t)return!1;for(r in e)if(_.Object(e[r]))n=n&&f(t[r],e[r]);else if(_.Array(e[r]))n=n&&!!~e[r].indexOf(t[r]);else if(t[r]!==e[r])return!1;return n}function d(t,e){return c(t,function(t){return f(t,e)})}function y(t,e){return l(t,function(t){return f(t,e)})}function g(t,e,r){e=e||[];var n,o,i,s=t;for(o=0,i=e.length;i>o;o++){if(!s)return;if("function"==typeof e[o]){if(!_.Array(s))return;s=c(s,e[o])}else if("object"==typeof e[o])if(r&&"$cursor"in e[o]){if(!_.Path(e[o].$cursor))throw Error("baobab.getIn: $cursor path must be an array.");n=r.get(e[o].$cursor),s=s[n]}else{if(!_.Array(s))return;s=d(s,e[o])}else s=s[e[o]]}return s}function v(t,e,r){var n,o,i,s=[],a=t;for(o=0,i=e.length;i>o;o++){if(!a)return null;if("function"==typeof e[o]){if(!_.Array(a))return;n=l(a,e[o]),s.push(n),a=a[n]}else if("object"==typeof e[o])if(r&&"$cursor"in e[o]){if(!_.Path(e[o].$cursor))throw Error("baobab.getIn: $cursor path must be an array.");p=r.get(e[o].$cursor),s.push(p),a=a[p]}else{if(!_.Array(a))return;n=y(a,e[o]),s.push(n),a=a[n]}else s.push(e[o]),a=a[e[o]]||{}}return s}function b(t,e){var r,n,o,i,s,a,h,u,c;for(r=0,i=e.length;i>r;r++)for(h=e[r],n=0,s=t.length;s>n;n++)for(u=t[n],o=0,a=u.length;a>o&&(c=u[o],c==h[o]);o++)if(o+1===a||o+1===h.length)return!0;return!1}function m(t,e){var r,n=t.length,o={},i=o;for(n||(o=e),r=0;n>r;r++)i[t[r]]=r+1===n?e:{},i=i[t[r]];return o}function j(t,e){t.super_=e;var r=function(){};r.prototype=e.prototype,t.prototype=new r,t.prototype.constructor=t}function w(t){var e=[];return{add:function(r){e.unshift(r),e.length>t&&(e.length=t)},back:function(t){var r=e[t-1];return r&&(e=e.slice(t)),r},get:function(){return e}}}var _=t("./type.js"),$=h.bind(null,!1),P=h.bind(null,!0);e.exports={archive:w,arrayOf:n,before:o,deepClone:P,shallowClone:$,shallowEqual:s,shallowMerge:i,compose:u,getIn:g,inherits:j,pathObject:m,solvePath:v,solveUpdate:b}}).call(this,"undefined"!=typeof global?global:"undefined"!=typeof self?self:"undefined"!=typeof window?window:{})},{"./type.js":9}],8:[function(t,e,r){function n(t,e,r){a.forEach(function(e){r!==e&&delete t[e]}),t[r]=e[r]}function o(t,e){var r,h=i.shallowClone(e||{});a.forEach(function(e){t[e]&&n(h,t,e)}),t.$chain&&(a.slice(0,-1).forEach(function(t){delete h[t]}),h.$apply=h.$apply?i.compose(h.$apply,t.$chain):t.$chain),t.$push&&h.$push?h.$push=s.Array(h.$push)?h.$push.concat(t.$push):[h.$push].concat(t.$push):t.$push&&(h.$push=t.$push),t.$unshift&&h.$unshift?h.$unshift=s.Array(t.$unshift)?t.$unshift.concat(h.$unshift):[t.$unshift].concat(h.$unshift):t.$unshift&&(h.$unshift=t.$unshift);for(r in t)s.Object(t[r])?h[r]=o(t[r],h[r]):"$"!==r[0]&&(h[r]=t[r]);return h}var i=t("./helpers.js"),s=t("./type.js"),a=["$unset","$set","$merge","$apply"];e.exports=o},{"./helpers.js":7,"./type.js":9}],9:[function(t,e,r){function n(t,e){return e.some(function(e){return o[e](t)})}var o={};o.Array=function(t){return Array.isArray(t)},o.Object=function(t){return t&&"object"==typeof t&&!Array.isArray(t)&&!(t instanceof Function)},o.String=function(t){return"string"==typeof t},o.Number=function(t){return"number"==typeof t},o.PositiveInteger=function(t){return"number"==typeof t&&t>0&&t%1===0},o.Function=function(t){return"function"==typeof t},o.Primitive=function(t){return"string"==typeof t||"number"==typeof t||"boolean"==typeof t},o.Date=function(t){return t instanceof Date},o.NonScalar=function(t){return o.Object(t)||o.Array(t)},o.Path=function(t){var e=["String","Number","Function","Object"];return o.Array(t)?t.every(function(t){return n(t,e)}):n(t,e)},o.MixinCursor=function(t){return n(t,["String","Number","Array","Function","Cursor"])},o.MixinCursors=function(t){return n(t,["Object","Array","Function"])},o.ComplexPath=function(t){return t.some(function(t){return n(t,["Object","Function"])})},e.exports=o},{}],10:[function(t,e,r){function n(t,e){var r=new Error("baobab.update: "+e+" at path /"+t.slice(1).join("/"));return r.path=t,r}var o=t("./helpers.js"),i=t("./type.js");e.exports=function(t,e,r){if(r=r||{},!i.Object(t)&&!i.Array(t))throw Error("baobab.update: invalid target.");var s={};t={root:o.shallowClone(t)};var a=function(t,e,r,h){r=r||["root"];var u,c,l,f=r.join("|λ|"),p=r[r.length-1],d=Object.keys(e).some(function(t){return!!~["$unset","$set","$apply","$merge","$push","$unshift"].indexOf(t)});if(d){s[f]=!0;for(c in e){if("$unset"===c){var y=r[r.length-2];i.Array(t)?h[y]=t.slice(0,+p).concat(t.slice(+p+1)):(h[y]=o.shallowClone(t),delete h[y][p]);break}if("$set"===c){l=e.$set,t[p]=l;break}if("$apply"===c){if(u=e.$apply,"function"!=typeof u)throw n(r,"using command $apply with a non function");t[p]=u.call(null,t[p]);break}if("$merge"===c){if(l=e.$merge,!i.Object(t[p])||!i.Object(l))throw n(r,"using command $merge with a non object");t[p]=o.shallowMerge(t[p],l);break}if("$push"===c){if(l=e.$push,!i.Array(t[p]))throw n(r,"using command $push to a non array");t[p]=t[p].concat(l)}if("$unshift"===c){if(l=e.$unshift,!i.Array(t[p]))throw n(r,"using command $unshift to a non array");t[p]=[].concat(l).concat(t[p])}}}else for(c in e)t[p][c]="undefined"==typeof t[p][c]?{}:o.shallowClone(t[p][c]),a(t[p],e[c],r.concat(c),t)};return a(t,e),{data:t.root,log:Object.keys(s).map(function(t){return t.split("|λ|").slice(1)})}}},{"./helpers.js":7,"./type.js":9}],11:[function(t,e,r){function n(t,e){function r(){h&&(a=e.map(function(t){return i.solvePath(n.tree.data,t,n.tree)}))}var n=this;o.call(this),this.tree=t;var a=e,h=e.some(s.ComplexPath);this.updateHandler=function(t){var e=i.solveUpdate(t.data.log,a);e&&n.emit("update")},r(),this.tree.on("update",this.updateHandler)}var o=t("emmett"),i=t("./helpers.js"),s=t("./type.js");i.inherits(n,o),n.prototype.release=function(){this.tree.off("update",this.updateHandler),this.tree=null,this.kill()},e.exports=n},{"./helpers.js":7,"./type.js":9,emmett:3}]},{},[1])(1)}); \ No newline at end of file diff --git a/src/baobab.js b/src/baobab.js index d1e02c4..dd43a1f 100644 --- a/src/baobab.js +++ b/src/baobab.js @@ -11,7 +11,6 @@ var Cursor = require('./cursor.js'), helpers = require('./helpers.js'), update = require('./update.js'), merge = require('./merge.js'), - mixins = require('./mixins.js'), defaults = require('../defaults.js'), type = require('./type.js'); @@ -67,9 +66,6 @@ function Baobab(initialData, opts) { for (var k in this.options.facets) this.addFacet(k, this.options.facets[k]); - - // Mixin - this.mixin = mixins.baobab(this); } helpers.inherits(Baobab, EventEmitter); diff --git a/src/cursor.js b/src/cursor.js index 3a90cb4..45f2291 100644 --- a/src/cursor.js +++ b/src/cursor.js @@ -5,7 +5,6 @@ * Nested selection into a baobab tree. */ var EventEmitter = require('emmett'), - mixins = require('./mixins.js'), helpers = require('./helpers.js'), defaults = require('../defaults.js'), type = require('./type.js'); @@ -90,9 +89,6 @@ function Cursor(tree, path, solvedPath, hash) { } }; - // Making mixin - this.mixin = mixins.cursor(this); - // Lazy binding var bound = false; diff --git a/src/mixins.js b/src/mixins.js deleted file mode 100644 index 9b2e674..0000000 --- a/src/mixins.js +++ /dev/null @@ -1,146 +0,0 @@ -/** - * Baobab React Mixins - * ==================== - * - * Compilation of react mixins designed to deal with cursors integration. - */ -var type = require('./type.js'); - -module.exports = { - baobab: function(baobab) { - return { - - // Run Baobab mixin first to allow mixins to access cursors - mixins: [{ - getInitialState: function() { - - // Binding baobab to instance - this.tree = baobab; - - // Is there any cursors to create? - if (!this.cursor && !this.cursors) - return {}; - - // Is there conflicting definitions? - if (this.cursor && this.cursors) - throw Error('baobab.mixin: you cannot have both ' + - '`component.cursor` and `component.cursors`. Please ' + - 'make up your mind.'); - - // Type - this.__type = null; - - // Making update handler - this.__updateHandler = (function() { - this.setState(this.__getCursorData()); - }).bind(this); - - if (this.cursor) { - if (!type.MixinCursor(this.cursor)) - throw Error('baobab.mixin.cursor: invalid data (cursor, ' + - 'string, array or function).'); - - if (type.Function(this.cursor)) - this.cursor = this.cursor(); - - if (!type.Cursor(this.cursor)) - this.cursor = baobab.select(this.cursor); - - this.__getCursorData = (function() { - return {cursor: this.cursor.get()}; - }).bind(this); - this.__type = 'single'; - } - else if (this.cursors) { - if (!type.MixinCursors(this.cursors)) - throw Error('baobab.mixin.cursor: invalid data (object, array or function).'); - - if (type.Function(this.cursors)) - this.cursors = this.cursors(); - - if (type.Array(this.cursors)) { - this.cursors = this.cursors.map(function(path) { - return type.Cursor(path) ? path : baobab.select(path); - }); - - this.__getCursorData = (function() { - return {cursors: this.cursors.map(function(cursor) { - return cursor.get(); - })}; - }).bind(this); - this.__type = 'array'; - } - else { - for (var k in this.cursors) { - if (!type.Cursor(this.cursors[k])) - this.cursors[k] = baobab.select(this.cursors[k]); - } - - this.__getCursorData = (function() { - var d = {}; - for (k in this.cursors) - d[k] = this.cursors[k].get(); - return {cursors: d}; - }).bind(this); - this.__type = 'object'; - } - } - - return this.__getCursorData(); - }, - componentDidMount: function() { - if (this.__type === 'single') { - this.__watcher = this.tree.watch([this.cursor.path]); - this.__watcher.on('update', this.__updateHandler); - } - else if (this.__type === 'array') { - this.__watcher = this.tree.watch(this.cursors.map(function(c) { - return c.path; - })); - this.__watcher.on('update', this.__updateHandler); - } - else if (this.__type === 'object') { - this.__watcher = this.tree.watch(Object.keys(this.cursors).map(function(k) { - return this.cursors[k].path; - }, this)); - this.__watcher.on('update', this.__updateHandler); - } - }, - componentWillUnmount: function() { - if (this.__watcher) - this.__watcher.release(); - } - }].concat(baobab.options.mixins) - }; - }, - cursor: function(cursor) { - return { - - // Run cursor mixin first to allow mixins to access cursors - mixins: [{ - getInitialState: function() { - - // Binding cursor to instance - this.cursor = cursor; - - // Making update handler - this.__updateHandler = (function() { - this.setState({cursor: this.cursor.get()}); - }).bind(this); - - return {cursor: this.cursor.get()}; - }, - componentDidMount: function() { - - // Listening to updates - this.cursor.on('update', this.__updateHandler); - }, - componentWillUnmount: function() { - - // Unbinding handler - this.cursor.off('update', this.__updateHandler); - } - }].concat(cursor.tree.options.mixins) - }; - } -}; diff --git a/test/endpoint.js b/test/endpoint.js index 165e1d2..fa5017a 100644 --- a/test/endpoint.js +++ b/test/endpoint.js @@ -8,4 +8,3 @@ require('./suites/helpers.js'); require('./suites/baobab.js'); require('./suites/cursor.js'); require('./suites/watcher.js'); -require('./suites/mixins.js'); diff --git a/test/suites/mixins.js b/test/suites/mixins.js deleted file mode 100644 index 49683aa..0000000 --- a/test/suites/mixins.js +++ /dev/null @@ -1,396 +0,0 @@ -/** - * Baobab Mixins Unit Tests - * ========================= - */ -var assert = require('assert'), - React = require('react/addons'), - Baobab = require('../../src/baobab.js'), - jsdom = require('jsdom').jsdom; - -var testMixin = { - getInitialState: function() { - return {greeting: 'Yeah'}; - } -}; - -describe('React Mixins', function() { - - before(function() { - - // Setting jsdom - var dom = jsdom(''); - global.document = dom; - global.window = dom.parentWindow; - - require('react/lib/ExecutionEnvironment').canUseDOM = true; - }); - - after(function() { - delete global.document; - delete global.window; - }); - - describe('Cursor Mixin', function() { - - it('the mixin should work as stated.', function(done) { - var baobab = new Baobab({hello:'world'}), - cursor = baobab.select('hello'), - i = 0; - - var Component = React.createClass({ - mixins: [cursor.mixin], - render: function() { - assert.strictEqual(this.state.cursor, i ? 'john' : 'world'); - i++; - return React.createElement('div', {id: 'cursor'}, this.cursor.get()); - } - }); - - React.render(React.createElement(Component, null), document.body, function() { - assert.strictEqual(document.querySelector('#cursor').textContent, 'world'); - - baobab.set('hello', 'john'); - setTimeout(function() { - assert.strictEqual(document.querySelector('#cursor').textContent, 'john'); - done(); - }, 0); - }); - }); - - it('should allow mixins in options to access the cursors', function () { - var baobab = new Baobab({ - foo: { - bar: [] - } - }, { - mixins: [{ - componentWillMount: function () { - assert.strictEqual(this.cursor.get(), baobab.select('foo', 'bar').get()); - } - }] - }); - - var Component = React.createClass({ - mixins: [baobab.select('foo', 'bar').mixin], - render: function() { - return React.createElement('div', {}, null); - } - }); - - React.render(React.createElement(Component, null), document.body); - }); - }); - - describe('Tree mixin', function() { - - it('should not break if no cursor is passed to the mixin.', function(done) { - var baobab = new Baobab({hello:'world'}); - - var Component = React.createClass({ - mixins: [baobab.mixin], - render: function() { - return React.createElement('div', {id: 'nocursor'}, 'world'); - } - }); - - React.render(React.createElement(Component, null), document.body, function() { - assert.strictEqual(document.querySelector('#nocursor').textContent, 'world'); - done(); - }); - }); - - it('should be possible to pass a single path.', function(done) { - var baobab = new Baobab({hello:'world'}); - - var Component = React.createClass({ - mixins: [baobab.mixin], - cursor: ['hello'], - render: function() { - return React.createElement('div', {id: 'treepath'}, this.cursor.get()); - } - }); - - React.render(React.createElement(Component, null), document.body, function() { - assert.strictEqual(document.querySelector('#treepath').textContent, 'world'); - - baobab.set('hello', 'john'); - setTimeout(function() { - assert.strictEqual(document.querySelector('#treepath').textContent, 'john'); - done(); - }, 0); - }); - }); - - it('should be possible to pass a single cursor.', function(done) { - var baobab = new Baobab({hello:'world'}), - i = 0; - - var Component = React.createClass({ - mixins: [baobab.mixin], - cursor: baobab.select('hello'), - render: function() { - assert.strictEqual(this.state.cursor, i ? 'john' : 'world'); - i++; - return React.createElement('div', {id: 'treecursor'}, this.cursor.get()); - } - }); - - React.render(React.createElement(Component, null), document.body, function() { - assert.strictEqual(document.querySelector('#treecursor').textContent, 'world'); - - baobab.set('hello', 'john'); - setTimeout(function() { - assert.strictEqual(document.querySelector('#treecursor').textContent, 'john'); - done(); - }, 0); - }); - }); - - it('should be possible to pass a function returning a path.', function(done) { - var baobab = new Baobab({hello:'world'}); - - var Component = React.createClass({ - mixins: [baobab.mixin], - cursor: function() { - return [this.props.pathKey]; - }, - render: function() { - return React.createElement('div', {id: 'treepath'}, this.cursor.get()); - } - }); - - React.render(React.createElement(Component, {pathKey: 'hello'}), document.body, function() { - assert.strictEqual(document.querySelector('#treepath').textContent, 'world'); - - baobab.set('hello', 'john'); - setTimeout(function() { - assert.strictEqual(document.querySelector('#treepath').textContent, 'john'); - done(); - }, 0); - }); - }); - - it('should be possible to pass a function returning a single cursor.', function(done) { - var baobab = new Baobab({hello:'world'}); - - var Component = React.createClass({ - mixins: [baobab.mixin], - cursor: function() { - return baobab.select(this.props.pathKey); - }, - render: function() { - return React.createElement('div', {id: 'treepath'}, this.cursor.get()); - } - }); - - React.render(React.createElement(Component, {pathKey: 'hello'}), document.body, function() { - assert.strictEqual(document.querySelector('#treepath').textContent, 'world'); - - baobab.set('hello', 'john'); - setTimeout(function() { - assert.strictEqual(document.querySelector('#treepath').textContent, 'john'); - done(); - }, 0); - }); - }); - - it('should be possible to pass an array of paths.', function(done) { - var baobab = new Baobab({name:'John', surname: 'Talbot'}), - i = 0; - - var Component = React.createClass({ - mixins: [baobab.mixin], - cursors: [['name'], ['surname']], - render: function() { - assert.strictEqual(this.state.cursors[0], i ? 'Jack' : 'John'); - assert.strictEqual(this.state.cursors[1], 'Talbot'); - i++; - return React.createElement('div', {id: 'treepathlist'}, this.cursors[0].get() + ' ' + this.cursors[1].get()); - } - }); - - React.render(React.createElement(Component, null), document.body, function() { - assert.strictEqual(document.querySelector('#treepathlist').textContent, 'John Talbot'); - - baobab.set('name', 'Jack'); - setTimeout(function() { - assert.strictEqual(document.querySelector('#treepathlist').textContent, 'Jack Talbot'); - done(); - }, 0); - }); - }); - - it('should be possible to pass an array of cursors.', function(done) { - var baobab = new Baobab({name:'John', surname: 'Talbot'}); - - var Component = React.createClass({ - mixins: [baobab.mixin], - cursors: [['name'], baobab.select('surname')], - render: function() { - return React.createElement('div', {id: 'treepathcursors'}, this.cursors[0].get() + ' ' + this.cursors[1].get()); - } - }); - - React.render(React.createElement(Component, null), document.body, function() { - assert.strictEqual(document.querySelector('#treepathcursors').textContent, 'John Talbot'); - - baobab.set('name', 'Jack'); - setTimeout(function() { - assert.strictEqual(document.querySelector('#treepathcursors').textContent, 'Jack Talbot'); - done(); - }, 0); - }); - }); - - it('should be possible to pass an object of paths.', function(done) { - var baobab = new Baobab({name:'John', surname: 'Talbot'}), - i = 0; - - var Component = React.createClass({ - mixins: [baobab.mixin], - cursors: { - name: ['name'], - surname: ['surname'] - }, - render: function() { - assert.strictEqual(this.state.cursors.name, i ? 'Jack' : 'John'); - assert.strictEqual(this.state.cursors.surname, 'Talbot'); - i++; - return React.createElement('div', {id: 'treepathobject'}, this.cursors.name.get() + ' ' + this.cursors.surname.get()); - } - }); - - React.render(React.createElement(Component, null), document.body, function() { - assert.strictEqual(document.querySelector('#treepathobject').textContent, 'John Talbot'); - - baobab.set('name', 'Jack'); - setTimeout(function() { - assert.strictEqual(document.querySelector('#treepathobject').textContent, 'Jack Talbot'); - done(); - }, 0); - }); - }); - - it('should be possible to pass an object of cursors.', function(done) { - var baobab = new Baobab({name:'John', surname: 'Talbot'}); - - var Component = React.createClass({ - mixins: [baobab.mixin], - cursors: { - name: ['name'], - surname: baobab.select('surname') - }, - render: function() { - return React.createElement('div', {id: 'treepathoc'}, this.cursors.name.get() + ' ' + this.cursors.surname.get()); - } - }); - - React.render(React.createElement(Component, null), document.body, function() { - assert.strictEqual(document.querySelector('#treepathoc').textContent, 'John Talbot'); - - baobab.set('name', 'Jack'); - setTimeout(function() { - assert.strictEqual(document.querySelector('#treepathoc').textContent, 'Jack Talbot'); - done(); - }, 0); - }); - }); - - it('should be possible to pass a function returning an array of cursors.', function(done) { - var baobab = new Baobab({name:'John', surname: 'Talbot'}); - - var Component = React.createClass({ - mixins: [baobab.mixin], - cursors: function() { - return [[this.props.pathKey1], baobab.select(this.props.pathKey2)]; - }, - render: function() { - return React.createElement('div', {id: 'treepathcursors'}, this.cursors[0].get() + ' ' + this.cursors[1].get()); - } - }); - - React.render(React.createElement(Component, {pathKey1: 'name', pathKey2: 'surname'}), document.body, function() { - assert.strictEqual(document.querySelector('#treepathcursors').textContent, 'John Talbot'); - - baobab.set('name', 'Jack'); - setTimeout(function() { - assert.strictEqual(document.querySelector('#treepathcursors').textContent, 'Jack Talbot'); - done(); - }, 0); - }); - }); - - it('should be possible to pass function returning an object of cursors.', function(done) { - var baobab = new Baobab({name:'John', surname: 'Talbot'}); - - var Component = React.createClass({ - mixins: [baobab.mixin], - cursors: function() { - return { - name: [this.props.pathKey1], - surname: baobab.select(this.props.pathKey2) - }; - }, - render: function() { - return React.createElement('div', {id: 'treepathoc'}, this.cursors.name.get() + ' ' + this.cursors.surname.get()); - } - }); - - React.render(React.createElement(Component, {pathKey1: 'name', pathKey2: 'surname'}), document.body, function() { - assert.strictEqual(document.querySelector('#treepathoc').textContent, 'John Talbot'); - - baobab.set('name', 'Jack'); - setTimeout(function() { - assert.strictEqual(document.querySelector('#treepathoc').textContent, 'Jack Talbot'); - done(); - }, 0); - }); - }); - - it('should be possible to pass custom mixins.', function(done) { - var baobab = new Baobab({name:'John', surname: 'Talbot'}, {mixins: [testMixin]}); - - var Component = React.createClass({ - mixins: [baobab.mixin], - cursor: ['name'], - render: function() { - return React.createElement('div', {id: 'treepathmixin'}, this.state.greeting + ' ' + this.cursor.get()); - } - }); - - React.render(React.createElement(Component, null), document.body, function() { - assert.strictEqual(document.querySelector('#treepathmixin').textContent, 'Yeah John'); - - baobab.set('name', 'Jack'); - setTimeout(function() { - assert.strictEqual(document.querySelector('#treepathmixin').textContent, 'Yeah Jack'); - done(); - }, 0); - }); - }); - - it('should allow mixins in options to access the tree.', function () { - var baobab = new Baobab({ - items: [] - }, { - mixins: [{ - componentWillMount: function () { - assert.strictEqual(this.cursor.get(), baobab.select('items').get()); - } - }] - }); - - var Component = React.createClass({ - mixins: [baobab.mixin], - cursor: ['items'], - render: function() { - return React.createElement('div', {}, null); - } - }); - - React.render(React.createElement(Component, null), document.body); - - }); - - }); -}); From b4479833af802f741be53835ddb2389a4d62eb32 Mon Sep 17 00:00:00 2001 From: Yomguithereal Date: Wed, 15 Apr 2015 10:28:50 +0200 Subject: [PATCH 50/73] Removing now useless dev dependencies --- package.json | 2 -- 1 file changed, 2 deletions(-) diff --git a/package.json b/package.json index ee575ab..15542f4 100644 --- a/package.json +++ b/package.json @@ -15,10 +15,8 @@ "gulp-mocha": "^2.0.0", "gulp-replace": "^0.5.3", "gulp-uglify": "^1.0.2", - "jsdom": "^3.1.0", "lodash": "^3.6.0", "mocha": "^2.0.1", - "react": "^0.13.0", "vinyl-buffer": "^1.0.0", "vinyl-source-stream": "^1.1.0" }, From ee85f538d07f1e200aeb6721926a6312a88d49d1 Mon Sep 17 00:00:00 2001 From: Yomguithereal Date: Wed, 15 Apr 2015 11:20:28 +0200 Subject: [PATCH 51/73] Dropping useless helper --- build/baobab.min.js | 2 +- src/helpers.js | 26 -------------------------- test/suites/helpers.js | 11 ----------- 3 files changed, 1 insertion(+), 38 deletions(-) diff --git a/build/baobab.min.js b/build/baobab.min.js index 2f170ec..0778648 100644 --- a/build/baobab.min.js +++ b/build/baobab.min.js @@ -1,2 +1,2 @@ /* baobab.js - Version: 1.0.0-rc1 - Author: Yomguithereal (Guillaume Plique) */ -!function(t){if("object"==typeof exports&&"undefined"!=typeof module)module.exports=t();else if("function"==typeof define&&define.amd)define([],t);else{var e;e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:this,e.Baobab=t()}}(function(){var t;return function e(t,r,n){function o(s,a){if(!r[s]){if(!t[s]){var h="function"==typeof require&&require;if(!a&&h)return h(s,!0);if(i)return i(s,!0);var u=new Error("Cannot find module '"+s+"'");throw u.code="MODULE_NOT_FOUND",u}var c=r[s]={exports:{}};t[s][0].call(c.exports,function(e){var r=t[s][1][e];return o(r?r:e)},c,c.exports,e,t,r,n)}return r[s].exports}for(var i="function"==typeof require&&require,s=0;sn;n++)t[n].fn!==e&&o.push(t[n]);return o}var s={once:"boolean",scope:"object"},a=0,h=function(){this._enabled=!0,this.unbindAll()};h.prototype.unbindAll=function(){return this._handlers={},this._handlersAll=[],this._handlersComplex=[],this},h.prototype.on=function(t,e,r){var n,i,h,u,c,l,f;if(o(t)){for(u in t)this.on(u,t[u],e);return this}for("function"==typeof t&&(r=e,e=t,t=null),c=[].concat(t),n=0,i=c.length;i>n;n++){if(u=c[n],f={order:a++,fn:e},"string"==typeof u)this._handlers[u]||(this._handlers[u]=[]),l=this._handlers[u];else if(u instanceof RegExp)l=this._handlersComplex,f.pattern=u;else{if(null!==u)throw Error("Emitter.on: invalid event.");l=this._handlersAll}for(h in r||{})s[h]&&(f[h]=r[h]);f.once&&(f.parent=l),l.push(f)}return this},h.prototype.once=function(){var t=Array.prototype.slice.call(arguments),r=t.length-1;return o(t[r])&&t.length>1?t[r]=e(t[r],{once:!0}):t.push({once:!0}),this.on.apply(this,t)},h.prototype.off=function(t,e){var r,n,s,a;if(1===arguments.length&&"function"==typeof t){e=arguments[0];for(s in this._handlers)this._handlers[s]=i(this._handlers[s],e),0===this._handlers[s].length&&delete this._handlers[s];this._handlersAll=i(this._handlersAll,e),this._handlersComplex=i(this._handlersComplex,e)}else if(1===arguments.length&&"string"==typeof t)delete this._handlers[t];else if(2===arguments.length){var h=[].concat(t);for(r=0,n=h.length;n>r;r++)a=h[r],this._handlers[a]=i(this._handlers[a],e),0===(this._handlers[a]||[]).length&&delete this._handlers[a]}else if(o(t))for(s in t)this.off(s,t[s]);return this},h.prototype.listeners=function(t){var e,r,n,o=this._handlersAll||[],i=!1;if(!t)throw Error("Emitter.listeners: no event provided.");for(o=o.concat(this._handlers[t]||[]),r=0,n=this._handlersComplex.length;n>r;r++)e=this._handlersComplex[r],~t.search(e.pattern)&&(i=!0,o.push(e));return this._handlersAll.length||i?o.sort(function(t,e){return t.order-e.order}):o.slice(0)},h.prototype.emit=function(t,e){if(!this._enabled)return this;if(o(t)){for(var r in t)this.emit(r,t[r]);return this}var n,i,s,a,h,u,c,l=[].concat(t),f=[];for(a=0,u=l.length;u>a;a++){for(i=this.listeners(l[a]),h=0,c=i.length;c>h;h++)s=i[h],n={type:l[a],target:this},arguments.length>1&&(n.data=e),s.fn.call("scope"in s?s.scope:this,n),s.once&&f.push(s);for(h=f.length-1;h>=0;h--)f[h].parent.splice(f[h].parent.indexOf(f[h]),1)}return this},h.prototype.kill=function(){this.unbindAll(),this._handlers=null,this._handlersAll=null,this._handlersComplex=null,this._enabled=!1},h.prototype.disable=function(){return this._enabled=!1,this},h.prototype.enable=function(){return this._enabled=!0,this},h.version="3.0.0","undefined"!=typeof n?("undefined"!=typeof r&&r.exports&&(n=r.exports=h),n.Emitter=h):"function"==typeof t&&t.amd?t("emmett",[],function(){return h}):this.Emitter=h}).call(this)},{}],4:[function(t,e,r){function n(t){return t+"$"+(new Date).getTime()+(""+Math.random()).replace("0.","")}function o(t,e){function r(t){this[t]=function(){var e=this.root[t].apply(this.root,arguments);return e instanceof i?this:e}}if(arguments.length<1&&(t={}),!(this instanceof o))return new o(t,e);if(!p.Object(t)&&!p.Array(t))throw Error("Baobab: invalid data.");if(s.call(this),this.options=u.shallowMerge(f,e),this._transaction={},this._future=void 0,this._cursors={},this._identity="[object Baobab]",this.data=u.deepClone(t),this.root=this.select([]),this.facets={},["get","set","unset","update"].forEach(r.bind(this)),!p.Object(this.options.facets))throw Error("Baobab: invalid facets.");for(var n in this.options.facets)this.addFacet(n,this.options.facets[n])}var i=t("./cursor.js"),s=t("emmett"),a=t("./watcher.js"),h=t("./facet.js"),u=t("./helpers.js"),c=t("./update.js"),l=t("./merge.js"),f=t("../defaults.js"),p=t("./type.js");u.inherits(o,s),o.prototype.addFacet=function(t,e){return this.facets[t]=this.createFacet(e),this},o.prototype.createFacet=function(t){return new h(this,t)},o.prototype.select=function(t){if(!t)throw Error("Baobab.select: invalid path.");if(arguments.length>1&&(t=u.arrayOf(arguments)),!p.Path(t))throw Error("Baobab.select: invalid path.");t=[].concat(t);var e,r=p.ComplexPath(t);r&&(e=u.solvePath(this.data,t,this));var o=t.map(function(t){return p.Function(t)?n("fn"):p.Object(t)?n("ob"):t}).join("|λ|");if(this._cursors[o])return this._cursors[o];var s=new i(this,t,e,o);return this._cursors[o]=s,s},o.prototype.stack=function(t){var e=this;if(!p.Object(t))throw Error("Baobab.update: wrong specification.");return this._transaction=l(t,this._transaction),this.options.autoCommit?this.options.asynchronous?(this._future||(this._future=setTimeout(e.commit.bind(e,null),0)),this):this.commit():this},o.prototype.commit=function(){var t=c(this.data,this._transaction,this.options),e=this.data;return this.data=t.data,this._transaction={},this._future&&(this._future=clearTimeout(this._future)),this.emit("update",{log:t.log,previousState:e}),this},o.prototype.watch=function(t){if(!p.Array(t)||t.some(function(t){return!p.Path(t)}))throw Error("Baobab.watch: invalid paths.");return new a(this,[].concat(t))},o.prototype.release=function(){var t;delete this.data,delete this._transaction;for(t in this._cursors)this._cursors[t].release();delete this._cursors;for(t in this.facets)this.facets[t].release();delete this.facets,this.kill()},o.prototype.toJSON=function(){return this.get()},o.prototype.toString=function(){return this._identity},e.exports=o},{"../defaults.js":2,"./cursor.js":5,"./facet.js":6,"./helpers.js":7,"./merge.js":8,"./type.js":9,"./update.js":10,"./watcher.js":11,emmett:3}],5:[function(t,e,r){function n(t,e,r,n){function o(t){if(i.isRecording()&&!i.undoing){var e=a.getIn(t,i.solvedPath,i.tree),r=a.deepClone(e);i.archive.add(r)}return i.undoing=!1,i.emit("update")}var i=this;s.call(this),e=e||[],this.tree=t,this.path=e,this.hash=n,this.archive=null,this.undoing=!1,this.complexPath=!!r,this.solvedPath=this.complexPath?r:this.path,this.relevant=void 0!==this.get(),this.updateHandler=function(t){var e=t.data.log,r=t.data.previousState,n=!1;if(i.complexPath&&(i.solvedPath=a.solvePath(i.tree.data,i.path,i.tree)),!i.path.length)return o(r);i.solvedPath&&(n=a.solveUpdate(e,[i.solvedPath]));var s=void 0!==i.get();i.relevant?s&&n?o(r):s||(i.emit("irrelevant"),i.relevant=!1):s&&n&&(i.emit("relevant"),o(r),i.relevant=!0)};var h=!1;this._lazyBind=function(){h||(h=!0,i.tree.on("update",i.updateHandler))},this.on=a.before(this._lazyBind,this.on.bind(this)),this.once=a.before(this._lazyBind,this.once.bind(this)),this.complexPath&&this._lazyBind()}function o(t,e,r,n){if(arguments.length>5)throw Error("baobab.Cursor."+t+": too many arguments.");arguments.length<4&&(n=r,r=[]),r=r||[];var o=[].concat(r),i=a.solvePath(this.get(),o,this.tree);if(!i)throw Error("baobab.Cursor."+t+": could not solve dynamic path.");if(e){var s=this.get(i);if(!h[e](s))throw Error("baobab.Cursor."+t+": invalid target.")}var u={};u["$"+t]=n;var c=a.pathObject(i,u);return c}function i(t,e){n.prototype[t]=function(){var r=o.bind(this,t,e).apply(this,arguments);return this.update(r)}}var s=t("emmett"),a=t("./helpers.js"),h=(t("../defaults.js"),t("./type.js"));a.inherits(n,s),n.prototype.isRoot=function(){return!this.path.length},n.prototype.isLeaf=function(){return h.Primitive(this.get())},n.prototype.isBranch=function(){return!this.isLeaf()&&!this.isRoot()},n.prototype.root=function(){return this.tree.root()},n.prototype.select=function(t){if(arguments.length>1&&(t=a.arrayOf(arguments)),!h.Path(t))throw Error("baobab.Cursor.select: invalid path.");return this.tree.select(this.path.concat(t))},n.prototype.up=function(){return this.solvedPath&&this.solvedPath.length?this.tree.select(this.path.slice(0,-1)):null},n.prototype.left=function(){var t=+this.solvedPath[this.solvedPath.length-1];if(isNaN(t))throw Error("baobab.Cursor.left: cannot go left on a non-list type.");return t?this.tree.select(this.solvedPath.slice(0,-1).concat(t-1)):null},n.prototype.leftmost=function(){var t=+this.solvedPath[this.solvedPath.length-1];if(isNaN(t))throw Error("baobab.Cursor.leftmost: cannot go left on a non-list type.");return this.tree.select(this.solvedPath.slice(0,-1).concat(0))},n.prototype.right=function(){var t=+this.solvedPath[this.solvedPath.length-1];if(isNaN(t))throw Error("baobab.Cursor.right: cannot go right on a non-list type.");return t+1===this.up().get().length?null:this.tree.select(this.solvedPath.slice(0,-1).concat(t+1))},n.prototype.rightmost=function(){var t=+this.solvedPath[this.solvedPath.length-1];if(isNaN(t))throw Error("baobab.Cursor.right: cannot go right on a non-list type.");var e=this.up().get();return this.tree.select(this.solvedPath.slice(0,-1).concat(e.length-1))},n.prototype.down=function(){+this.solvedPath[this.solvedPath.length-1];return this.get()instanceof Array?this.tree.select(this.solvedPath.concat(0)):null},n.prototype.get=function(t){arguments.length>1&&(t=a.arrayOf(arguments));var e=this.solvedPath.concat([].concat(t||0===t?t:[]));return a.getIn(this.tree.data,e,this.tree)},i("set"),i("apply"),i("chain"),i("push","Array"),i("unshift","Array"),n.prototype.merge=function(t){if(!h.Object(t))throw Error("baobab.Cursor.merge: trying to merge a non-object.");var e=o.bind(this,"merge","Object").apply(this,arguments);return this.update(e)},n.prototype.unset=function(t){if(void 0===t&&this.isRoot())throw Error("baobab.Cursor.unset: cannot remove root node.");var e=o.bind(this,"unset",null).apply(this,[t,!0]);return this.update(e)},n.prototype.update=function(t,e){if(arguments.length<2)return this.tree.stack(a.pathObject(this.solvedPath,t)),this;var r=[].concat(t),n=a.solvePath(this.get(),r,this.tree);if(!n)throw Error("baobab.Cursor.update: could not solve dynamic path.");return this.tree.stack(a.pathObject(this.solvedPath.concat(n),e)),this},n.prototype.startRecording=function(t){if(t=t||5,1>t)throw Error("baobab.Cursor.startRecording: invalid maximum number of records.");return this.archive?this:(this._lazyBind(),this.archive=a.archive(t),this)},n.prototype.stopRecording=function(){return this.archive=null,this},n.prototype.undo=function(t){if(t=t||1,!this.isRecording())throw Error("baobab.Cursor.undo: cursor is not recording.");if(!h.PositiveInteger(t))throw Error("baobab.Cursor.undo: expecting a positive integer.");var e=this.archive.back(t);if(!e)throw Error("boabab.Cursor.undo: cannot find a relevant record ("+t+" back).");return this.undoing=!0,this.set(e)},n.prototype.isRecording=function(){return!!this.archive},n.prototype.hasHistory=function(){return!(!this.archive||!this.archive.get().length)},n.prototype.getHistory=function(){return this.archive?this.archive.get():[]},n.prototype.release=function(){this.tree.off("update",this.updateHandler),this.hash&&delete this.tree._cursors[this.hash],delete this.tree,delete this.path,delete this.solvedPath,delete this.archive,this.kill()},n.prototype.toJSON=function(){return this.get()},h.Cursor=function(t){return t instanceof n},e.exports=n},{"../defaults.js":2,"./helpers.js":7,"./type.js":9,emmett:3}],6:[function(t,e,r){function n(t){return t}function o(t,e){function r(t){o[t]=l[t].bind(l)}var o=this,s=null,a=!1,h=e.get||n,u=e.cursors,c=Object.keys(u).map(function(t){return u[t]}),l=new i(t,c);["on","once","release"].forEach(r),this.get=function(){if(a)return s;var e={};for(var r in u)e[r]=t.get(u[r]);return s=h.call(null,e),a=!0,s},this.on("update",function(){a=!1})}{var i=t("./watcher.js");t("./helpers.js")}e.exports=o},{"./helpers.js":7,"./watcher.js":11}],7:[function(t,e,r){(function(r){function n(t){return Array.prototype.slice.call(t)}function o(t,e){return function(){t(),e.apply(null,arguments)}}function i(t,e){var r,n={};for(r in t)n[r]=t[r];for(r in e)n[r]=e[r];return n}function s(t,e){if(t===e)return!0;if("object"!=typeof t||"object"!=typeof e||null===t||null===e)return!1;var r=Object.keys(t),n=Object.keys(e);if(r.length!==n.length)return!1;var o,i;for(o=0,i=r.length;i>o;o++)if(t[r[o]]!==e[r[o]])return!1;return!0}function a(t){var e=t.source,r="";return t.global&&(r+="g"),t.multiline&&(r+="m"),t.ignoreCase&&(r+="i"),t.sticky&&(r+="y"),t.unicode&&(r+="u"),new RegExp(e,r)}function h(t,e){if(!e||"object"!=typeof e||e instanceof Error||"ArrayBuffer"in r&&e instanceof ArrayBuffer)return e;if(_.Array(e)){if(t){var n,o,i=[];for(n=0,o=e.length;o>n;n++)i.push(P(e[n]));return i}return e.slice(0)}if(_.Date(e))return new Date(e.getTime());if(e instanceof RegExp)return a(e);if(_.Object(e)){var s,h={};e.constructor&&e.constructor!==Object&&(h=Object.create(e.constructor.prototype));for(s in e)e.hasOwnProperty(s)&&(h[s]=t?P(e[s]):e[s]);return h}return e}function u(t,e){return function(r){return e(t(r))}}function c(t,e){var r,n;for(r=0,n=t.length;n>r;r++)if(e(t[r]))return t[r]}function l(t,e){var r,n;for(r=0,n=t.length;n>r;r++)if(e(t[r]))return r;return-1}function f(t,e){var r,n=!0;if(!t)return!1;for(r in e)if(_.Object(e[r]))n=n&&f(t[r],e[r]);else if(_.Array(e[r]))n=n&&!!~e[r].indexOf(t[r]);else if(t[r]!==e[r])return!1;return n}function d(t,e){return c(t,function(t){return f(t,e)})}function y(t,e){return l(t,function(t){return f(t,e)})}function g(t,e,r){e=e||[];var n,o,i,s=t;for(o=0,i=e.length;i>o;o++){if(!s)return;if("function"==typeof e[o]){if(!_.Array(s))return;s=c(s,e[o])}else if("object"==typeof e[o])if(r&&"$cursor"in e[o]){if(!_.Path(e[o].$cursor))throw Error("baobab.getIn: $cursor path must be an array.");n=r.get(e[o].$cursor),s=s[n]}else{if(!_.Array(s))return;s=d(s,e[o])}else s=s[e[o]]}return s}function v(t,e,r){var n,o,i,s=[],a=t;for(o=0,i=e.length;i>o;o++){if(!a)return null;if("function"==typeof e[o]){if(!_.Array(a))return;n=l(a,e[o]),s.push(n),a=a[n]}else if("object"==typeof e[o])if(r&&"$cursor"in e[o]){if(!_.Path(e[o].$cursor))throw Error("baobab.getIn: $cursor path must be an array.");p=r.get(e[o].$cursor),s.push(p),a=a[p]}else{if(!_.Array(a))return;n=y(a,e[o]),s.push(n),a=a[n]}else s.push(e[o]),a=a[e[o]]||{}}return s}function b(t,e){var r,n,o,i,s,a,h,u,c;for(r=0,i=e.length;i>r;r++)for(h=e[r],n=0,s=t.length;s>n;n++)for(u=t[n],o=0,a=u.length;a>o&&(c=u[o],c==h[o]);o++)if(o+1===a||o+1===h.length)return!0;return!1}function m(t,e){var r,n=t.length,o={},i=o;for(n||(o=e),r=0;n>r;r++)i[t[r]]=r+1===n?e:{},i=i[t[r]];return o}function j(t,e){t.super_=e;var r=function(){};r.prototype=e.prototype,t.prototype=new r,t.prototype.constructor=t}function w(t){var e=[];return{add:function(r){e.unshift(r),e.length>t&&(e.length=t)},back:function(t){var r=e[t-1];return r&&(e=e.slice(t)),r},get:function(){return e}}}var _=t("./type.js"),$=h.bind(null,!1),P=h.bind(null,!0);e.exports={archive:w,arrayOf:n,before:o,deepClone:P,shallowClone:$,shallowEqual:s,shallowMerge:i,compose:u,getIn:g,inherits:j,pathObject:m,solvePath:v,solveUpdate:b}}).call(this,"undefined"!=typeof global?global:"undefined"!=typeof self?self:"undefined"!=typeof window?window:{})},{"./type.js":9}],8:[function(t,e,r){function n(t,e,r){a.forEach(function(e){r!==e&&delete t[e]}),t[r]=e[r]}function o(t,e){var r,h=i.shallowClone(e||{});a.forEach(function(e){t[e]&&n(h,t,e)}),t.$chain&&(a.slice(0,-1).forEach(function(t){delete h[t]}),h.$apply=h.$apply?i.compose(h.$apply,t.$chain):t.$chain),t.$push&&h.$push?h.$push=s.Array(h.$push)?h.$push.concat(t.$push):[h.$push].concat(t.$push):t.$push&&(h.$push=t.$push),t.$unshift&&h.$unshift?h.$unshift=s.Array(t.$unshift)?t.$unshift.concat(h.$unshift):[t.$unshift].concat(h.$unshift):t.$unshift&&(h.$unshift=t.$unshift);for(r in t)s.Object(t[r])?h[r]=o(t[r],h[r]):"$"!==r[0]&&(h[r]=t[r]);return h}var i=t("./helpers.js"),s=t("./type.js"),a=["$unset","$set","$merge","$apply"];e.exports=o},{"./helpers.js":7,"./type.js":9}],9:[function(t,e,r){function n(t,e){return e.some(function(e){return o[e](t)})}var o={};o.Array=function(t){return Array.isArray(t)},o.Object=function(t){return t&&"object"==typeof t&&!Array.isArray(t)&&!(t instanceof Function)},o.String=function(t){return"string"==typeof t},o.Number=function(t){return"number"==typeof t},o.PositiveInteger=function(t){return"number"==typeof t&&t>0&&t%1===0},o.Function=function(t){return"function"==typeof t},o.Primitive=function(t){return"string"==typeof t||"number"==typeof t||"boolean"==typeof t},o.Date=function(t){return t instanceof Date},o.NonScalar=function(t){return o.Object(t)||o.Array(t)},o.Path=function(t){var e=["String","Number","Function","Object"];return o.Array(t)?t.every(function(t){return n(t,e)}):n(t,e)},o.MixinCursor=function(t){return n(t,["String","Number","Array","Function","Cursor"])},o.MixinCursors=function(t){return n(t,["Object","Array","Function"])},o.ComplexPath=function(t){return t.some(function(t){return n(t,["Object","Function"])})},e.exports=o},{}],10:[function(t,e,r){function n(t,e){var r=new Error("baobab.update: "+e+" at path /"+t.slice(1).join("/"));return r.path=t,r}var o=t("./helpers.js"),i=t("./type.js");e.exports=function(t,e,r){if(r=r||{},!i.Object(t)&&!i.Array(t))throw Error("baobab.update: invalid target.");var s={};t={root:o.shallowClone(t)};var a=function(t,e,r,h){r=r||["root"];var u,c,l,f=r.join("|λ|"),p=r[r.length-1],d=Object.keys(e).some(function(t){return!!~["$unset","$set","$apply","$merge","$push","$unshift"].indexOf(t)});if(d){s[f]=!0;for(c in e){if("$unset"===c){var y=r[r.length-2];i.Array(t)?h[y]=t.slice(0,+p).concat(t.slice(+p+1)):(h[y]=o.shallowClone(t),delete h[y][p]);break}if("$set"===c){l=e.$set,t[p]=l;break}if("$apply"===c){if(u=e.$apply,"function"!=typeof u)throw n(r,"using command $apply with a non function");t[p]=u.call(null,t[p]);break}if("$merge"===c){if(l=e.$merge,!i.Object(t[p])||!i.Object(l))throw n(r,"using command $merge with a non object");t[p]=o.shallowMerge(t[p],l);break}if("$push"===c){if(l=e.$push,!i.Array(t[p]))throw n(r,"using command $push to a non array");t[p]=t[p].concat(l)}if("$unshift"===c){if(l=e.$unshift,!i.Array(t[p]))throw n(r,"using command $unshift to a non array");t[p]=[].concat(l).concat(t[p])}}}else for(c in e)t[p][c]="undefined"==typeof t[p][c]?{}:o.shallowClone(t[p][c]),a(t[p],e[c],r.concat(c),t)};return a(t,e),{data:t.root,log:Object.keys(s).map(function(t){return t.split("|λ|").slice(1)})}}},{"./helpers.js":7,"./type.js":9}],11:[function(t,e,r){function n(t,e){function r(){h&&(a=e.map(function(t){return i.solvePath(n.tree.data,t,n.tree)}))}var n=this;o.call(this),this.tree=t;var a=e,h=e.some(s.ComplexPath);this.updateHandler=function(t){var e=i.solveUpdate(t.data.log,a);e&&n.emit("update")},r(),this.tree.on("update",this.updateHandler)}var o=t("emmett"),i=t("./helpers.js"),s=t("./type.js");i.inherits(n,o),n.prototype.release=function(){this.tree.off("update",this.updateHandler),this.tree=null,this.kill()},e.exports=n},{"./helpers.js":7,"./type.js":9,emmett:3}]},{},[1])(1)}); \ No newline at end of file +!function(t){if("object"==typeof exports&&"undefined"!=typeof module)module.exports=t();else if("function"==typeof define&&define.amd)define([],t);else{var e;e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:this,e.Baobab=t()}}(function(){var t;return function e(t,r,n){function o(s,a){if(!r[s]){if(!t[s]){var h="function"==typeof require&&require;if(!a&&h)return h(s,!0);if(i)return i(s,!0);var u=new Error("Cannot find module '"+s+"'");throw u.code="MODULE_NOT_FOUND",u}var c=r[s]={exports:{}};t[s][0].call(c.exports,function(e){var r=t[s][1][e];return o(r?r:e)},c,c.exports,e,t,r,n)}return r[s].exports}for(var i="function"==typeof require&&require,s=0;sn;n++)t[n].fn!==e&&o.push(t[n]);return o}var s={once:"boolean",scope:"object"},a=0,h=function(){this._enabled=!0,this.unbindAll()};h.prototype.unbindAll=function(){return this._handlers={},this._handlersAll=[],this._handlersComplex=[],this},h.prototype.on=function(t,e,r){var n,i,h,u,c,l,f;if(o(t)){for(u in t)this.on(u,t[u],e);return this}for("function"==typeof t&&(r=e,e=t,t=null),c=[].concat(t),n=0,i=c.length;i>n;n++){if(u=c[n],f={order:a++,fn:e},"string"==typeof u)this._handlers[u]||(this._handlers[u]=[]),l=this._handlers[u];else if(u instanceof RegExp)l=this._handlersComplex,f.pattern=u;else{if(null!==u)throw Error("Emitter.on: invalid event.");l=this._handlersAll}for(h in r||{})s[h]&&(f[h]=r[h]);f.once&&(f.parent=l),l.push(f)}return this},h.prototype.once=function(){var t=Array.prototype.slice.call(arguments),r=t.length-1;return o(t[r])&&t.length>1?t[r]=e(t[r],{once:!0}):t.push({once:!0}),this.on.apply(this,t)},h.prototype.off=function(t,e){var r,n,s,a;if(1===arguments.length&&"function"==typeof t){e=arguments[0];for(s in this._handlers)this._handlers[s]=i(this._handlers[s],e),0===this._handlers[s].length&&delete this._handlers[s];this._handlersAll=i(this._handlersAll,e),this._handlersComplex=i(this._handlersComplex,e)}else if(1===arguments.length&&"string"==typeof t)delete this._handlers[t];else if(2===arguments.length){var h=[].concat(t);for(r=0,n=h.length;n>r;r++)a=h[r],this._handlers[a]=i(this._handlers[a],e),0===(this._handlers[a]||[]).length&&delete this._handlers[a]}else if(o(t))for(s in t)this.off(s,t[s]);return this},h.prototype.listeners=function(t){var e,r,n,o=this._handlersAll||[],i=!1;if(!t)throw Error("Emitter.listeners: no event provided.");for(o=o.concat(this._handlers[t]||[]),r=0,n=this._handlersComplex.length;n>r;r++)e=this._handlersComplex[r],~t.search(e.pattern)&&(i=!0,o.push(e));return this._handlersAll.length||i?o.sort(function(t,e){return t.order-e.order}):o.slice(0)},h.prototype.emit=function(t,e){if(!this._enabled)return this;if(o(t)){for(var r in t)this.emit(r,t[r]);return this}var n,i,s,a,h,u,c,l=[].concat(t),f=[];for(a=0,u=l.length;u>a;a++){for(i=this.listeners(l[a]),h=0,c=i.length;c>h;h++)s=i[h],n={type:l[a],target:this},arguments.length>1&&(n.data=e),s.fn.call("scope"in s?s.scope:this,n),s.once&&f.push(s);for(h=f.length-1;h>=0;h--)f[h].parent.splice(f[h].parent.indexOf(f[h]),1)}return this},h.prototype.kill=function(){this.unbindAll(),this._handlers=null,this._handlersAll=null,this._handlersComplex=null,this._enabled=!1},h.prototype.disable=function(){return this._enabled=!1,this},h.prototype.enable=function(){return this._enabled=!0,this},h.version="3.0.0","undefined"!=typeof n?("undefined"!=typeof r&&r.exports&&(n=r.exports=h),n.Emitter=h):"function"==typeof t&&t.amd?t("emmett",[],function(){return h}):this.Emitter=h}).call(this)},{}],4:[function(t,e,r){function n(t){return t+"$"+(new Date).getTime()+(""+Math.random()).replace("0.","")}function o(t,e){function r(t){this[t]=function(){var e=this.root[t].apply(this.root,arguments);return e instanceof i?this:e}}if(arguments.length<1&&(t={}),!(this instanceof o))return new o(t,e);if(!p.Object(t)&&!p.Array(t))throw Error("Baobab: invalid data.");if(s.call(this),this.options=u.shallowMerge(f,e),this._transaction={},this._future=void 0,this._cursors={},this._identity="[object Baobab]",this.data=u.deepClone(t),this.root=this.select([]),this.facets={},["get","set","unset","update"].forEach(r.bind(this)),!p.Object(this.options.facets))throw Error("Baobab: invalid facets.");for(var n in this.options.facets)this.addFacet(n,this.options.facets[n])}var i=t("./cursor.js"),s=t("emmett"),a=t("./watcher.js"),h=t("./facet.js"),u=t("./helpers.js"),c=t("./update.js"),l=t("./merge.js"),f=t("../defaults.js"),p=t("./type.js");u.inherits(o,s),o.prototype.addFacet=function(t,e){return this.facets[t]=this.createFacet(e),this},o.prototype.createFacet=function(t){return new h(this,t)},o.prototype.select=function(t){if(!t)throw Error("Baobab.select: invalid path.");if(arguments.length>1&&(t=u.arrayOf(arguments)),!p.Path(t))throw Error("Baobab.select: invalid path.");t=[].concat(t);var e,r=p.ComplexPath(t);r&&(e=u.solvePath(this.data,t,this));var o=t.map(function(t){return p.Function(t)?n("fn"):p.Object(t)?n("ob"):t}).join("|λ|");if(this._cursors[o])return this._cursors[o];var s=new i(this,t,e,o);return this._cursors[o]=s,s},o.prototype.stack=function(t){var e=this;if(!p.Object(t))throw Error("Baobab.update: wrong specification.");return this._transaction=l(t,this._transaction),this.options.autoCommit?this.options.asynchronous?(this._future||(this._future=setTimeout(e.commit.bind(e,null),0)),this):this.commit():this},o.prototype.commit=function(){var t=c(this.data,this._transaction,this.options),e=this.data;return this.data=t.data,this._transaction={},this._future&&(this._future=clearTimeout(this._future)),this.emit("update",{log:t.log,previousState:e}),this},o.prototype.watch=function(t){if(!p.Array(t)||t.some(function(t){return!p.Path(t)}))throw Error("Baobab.watch: invalid paths.");return new a(this,[].concat(t))},o.prototype.release=function(){var t;delete this.data,delete this._transaction;for(t in this._cursors)this._cursors[t].release();delete this._cursors;for(t in this.facets)this.facets[t].release();delete this.facets,this.kill()},o.prototype.toJSON=function(){return this.get()},o.prototype.toString=function(){return this._identity},e.exports=o},{"../defaults.js":2,"./cursor.js":5,"./facet.js":6,"./helpers.js":7,"./merge.js":8,"./type.js":9,"./update.js":10,"./watcher.js":11,emmett:3}],5:[function(t,e,r){function n(t,e,r,n){function o(t){if(i.isRecording()&&!i.undoing){var e=a.getIn(t,i.solvedPath,i.tree),r=a.deepClone(e);i.archive.add(r)}return i.undoing=!1,i.emit("update")}var i=this;s.call(this),e=e||[],this.tree=t,this.path=e,this.hash=n,this.archive=null,this.undoing=!1,this.complexPath=!!r,this.solvedPath=this.complexPath?r:this.path,this.relevant=void 0!==this.get(),this.updateHandler=function(t){var e=t.data.log,r=t.data.previousState,n=!1;if(i.complexPath&&(i.solvedPath=a.solvePath(i.tree.data,i.path,i.tree)),!i.path.length)return o(r);i.solvedPath&&(n=a.solveUpdate(e,[i.solvedPath]));var s=void 0!==i.get();i.relevant?s&&n?o(r):s||(i.emit("irrelevant"),i.relevant=!1):s&&n&&(i.emit("relevant"),o(r),i.relevant=!0)};var h=!1;this._lazyBind=function(){h||(h=!0,i.tree.on("update",i.updateHandler))},this.on=a.before(this._lazyBind,this.on.bind(this)),this.once=a.before(this._lazyBind,this.once.bind(this)),this.complexPath&&this._lazyBind()}function o(t,e,r,n){if(arguments.length>5)throw Error("baobab.Cursor."+t+": too many arguments.");arguments.length<4&&(n=r,r=[]),r=r||[];var o=[].concat(r),i=a.solvePath(this.get(),o,this.tree);if(!i)throw Error("baobab.Cursor."+t+": could not solve dynamic path.");if(e){var s=this.get(i);if(!h[e](s))throw Error("baobab.Cursor."+t+": invalid target.")}var u={};u["$"+t]=n;var c=a.pathObject(i,u);return c}function i(t,e){n.prototype[t]=function(){var r=o.bind(this,t,e).apply(this,arguments);return this.update(r)}}var s=t("emmett"),a=t("./helpers.js"),h=(t("../defaults.js"),t("./type.js"));a.inherits(n,s),n.prototype.isRoot=function(){return!this.path.length},n.prototype.isLeaf=function(){return h.Primitive(this.get())},n.prototype.isBranch=function(){return!this.isLeaf()&&!this.isRoot()},n.prototype.root=function(){return this.tree.root()},n.prototype.select=function(t){if(arguments.length>1&&(t=a.arrayOf(arguments)),!h.Path(t))throw Error("baobab.Cursor.select: invalid path.");return this.tree.select(this.path.concat(t))},n.prototype.up=function(){return this.solvedPath&&this.solvedPath.length?this.tree.select(this.path.slice(0,-1)):null},n.prototype.left=function(){var t=+this.solvedPath[this.solvedPath.length-1];if(isNaN(t))throw Error("baobab.Cursor.left: cannot go left on a non-list type.");return t?this.tree.select(this.solvedPath.slice(0,-1).concat(t-1)):null},n.prototype.leftmost=function(){var t=+this.solvedPath[this.solvedPath.length-1];if(isNaN(t))throw Error("baobab.Cursor.leftmost: cannot go left on a non-list type.");return this.tree.select(this.solvedPath.slice(0,-1).concat(0))},n.prototype.right=function(){var t=+this.solvedPath[this.solvedPath.length-1];if(isNaN(t))throw Error("baobab.Cursor.right: cannot go right on a non-list type.");return t+1===this.up().get().length?null:this.tree.select(this.solvedPath.slice(0,-1).concat(t+1))},n.prototype.rightmost=function(){var t=+this.solvedPath[this.solvedPath.length-1];if(isNaN(t))throw Error("baobab.Cursor.right: cannot go right on a non-list type.");var e=this.up().get();return this.tree.select(this.solvedPath.slice(0,-1).concat(e.length-1))},n.prototype.down=function(){+this.solvedPath[this.solvedPath.length-1];return this.get()instanceof Array?this.tree.select(this.solvedPath.concat(0)):null},n.prototype.get=function(t){arguments.length>1&&(t=a.arrayOf(arguments));var e=this.solvedPath.concat([].concat(t||0===t?t:[]));return a.getIn(this.tree.data,e,this.tree)},i("set"),i("apply"),i("chain"),i("push","Array"),i("unshift","Array"),n.prototype.merge=function(t){if(!h.Object(t))throw Error("baobab.Cursor.merge: trying to merge a non-object.");var e=o.bind(this,"merge","Object").apply(this,arguments);return this.update(e)},n.prototype.unset=function(t){if(void 0===t&&this.isRoot())throw Error("baobab.Cursor.unset: cannot remove root node.");var e=o.bind(this,"unset",null).apply(this,[t,!0]);return this.update(e)},n.prototype.update=function(t,e){if(arguments.length<2)return this.tree.stack(a.pathObject(this.solvedPath,t)),this;var r=[].concat(t),n=a.solvePath(this.get(),r,this.tree);if(!n)throw Error("baobab.Cursor.update: could not solve dynamic path.");return this.tree.stack(a.pathObject(this.solvedPath.concat(n),e)),this},n.prototype.startRecording=function(t){if(t=t||5,1>t)throw Error("baobab.Cursor.startRecording: invalid maximum number of records.");return this.archive?this:(this._lazyBind(),this.archive=a.archive(t),this)},n.prototype.stopRecording=function(){return this.archive=null,this},n.prototype.undo=function(t){if(t=t||1,!this.isRecording())throw Error("baobab.Cursor.undo: cursor is not recording.");if(!h.PositiveInteger(t))throw Error("baobab.Cursor.undo: expecting a positive integer.");var e=this.archive.back(t);if(!e)throw Error("boabab.Cursor.undo: cannot find a relevant record ("+t+" back).");return this.undoing=!0,this.set(e)},n.prototype.isRecording=function(){return!!this.archive},n.prototype.hasHistory=function(){return!(!this.archive||!this.archive.get().length)},n.prototype.getHistory=function(){return this.archive?this.archive.get():[]},n.prototype.release=function(){this.tree.off("update",this.updateHandler),this.hash&&delete this.tree._cursors[this.hash],delete this.tree,delete this.path,delete this.solvedPath,delete this.archive,this.kill()},n.prototype.toJSON=function(){return this.get()},h.Cursor=function(t){return t instanceof n},e.exports=n},{"../defaults.js":2,"./helpers.js":7,"./type.js":9,emmett:3}],6:[function(t,e,r){function n(t){return t}function o(t,e){function r(t){o[t]=l[t].bind(l)}var o=this,s=null,a=!1,h=e.get||n,u=e.cursors,c=Object.keys(u).map(function(t){return u[t]}),l=new i(t,c);["on","once","release"].forEach(r),this.get=function(){if(a)return s;var e={};for(var r in u)e[r]=t.get(u[r]);return s=h.call(null,e),a=!0,s},this.on("update",function(){a=!1})}{var i=t("./watcher.js");t("./helpers.js")}e.exports=o},{"./helpers.js":7,"./watcher.js":11}],7:[function(t,e,r){(function(r){function n(t){return Array.prototype.slice.call(t)}function o(t,e){return function(){t(),e.apply(null,arguments)}}function i(t,e){var r,n={};for(r in t)n[r]=t[r];for(r in e)n[r]=e[r];return n}function s(t){var e=t.source,r="";return t.global&&(r+="g"),t.multiline&&(r+="m"),t.ignoreCase&&(r+="i"),t.sticky&&(r+="y"),t.unicode&&(r+="u"),new RegExp(e,r)}function a(t,e){if(!e||"object"!=typeof e||e instanceof Error||"ArrayBuffer"in r&&e instanceof ArrayBuffer)return e;if(w.Array(e)){if(t){var n,o,i=[];for(n=0,o=e.length;o>n;n++)i.push($(e[n]));return i}return e.slice(0)}if(w.Date(e))return new Date(e.getTime());if(e instanceof RegExp)return s(e);if(w.Object(e)){var a,h={};e.constructor&&e.constructor!==Object&&(h=Object.create(e.constructor.prototype));for(a in e)e.hasOwnProperty(a)&&(h[a]=t?$(e[a]):e[a]);return h}return e}function h(t,e){return function(r){return e(t(r))}}function u(t,e){var r,n;for(r=0,n=t.length;n>r;r++)if(e(t[r]))return t[r]}function c(t,e){var r,n;for(r=0,n=t.length;n>r;r++)if(e(t[r]))return r;return-1}function l(t,e){var r,n=!0;if(!t)return!1;for(r in e)if(w.Object(e[r]))n=n&&l(t[r],e[r]);else if(w.Array(e[r]))n=n&&!!~e[r].indexOf(t[r]);else if(t[r]!==e[r])return!1;return n}function f(t,e){return u(t,function(t){return l(t,e)})}function d(t,e){return c(t,function(t){return l(t,e)})}function y(t,e,r){e=e||[];var n,o,i,s=t;for(o=0,i=e.length;i>o;o++){if(!s)return;if("function"==typeof e[o]){if(!w.Array(s))return;s=u(s,e[o])}else if("object"==typeof e[o])if(r&&"$cursor"in e[o]){if(!w.Path(e[o].$cursor))throw Error("baobab.getIn: $cursor path must be an array.");n=r.get(e[o].$cursor),s=s[n]}else{if(!w.Array(s))return;s=f(s,e[o])}else s=s[e[o]]}return s}function g(t,e,r){var n,o,i,s=[],a=t;for(o=0,i=e.length;i>o;o++){if(!a)return null;if("function"==typeof e[o]){if(!w.Array(a))return;n=c(a,e[o]),s.push(n),a=a[n]}else if("object"==typeof e[o])if(r&&"$cursor"in e[o]){if(!w.Path(e[o].$cursor))throw Error("baobab.getIn: $cursor path must be an array.");p=r.get(e[o].$cursor),s.push(p),a=a[p]}else{if(!w.Array(a))return;n=d(a,e[o]),s.push(n),a=a[n]}else s.push(e[o]),a=a[e[o]]||{}}return s}function v(t,e){var r,n,o,i,s,a,h,u,c;for(r=0,i=e.length;i>r;r++)for(h=e[r],n=0,s=t.length;s>n;n++)for(u=t[n],o=0,a=u.length;a>o&&(c=u[o],c==h[o]);o++)if(o+1===a||o+1===h.length)return!0;return!1}function b(t,e){var r,n=t.length,o={},i=o;for(n||(o=e),r=0;n>r;r++)i[t[r]]=r+1===n?e:{},i=i[t[r]];return o}function m(t,e){t.super_=e;var r=function(){};r.prototype=e.prototype,t.prototype=new r,t.prototype.constructor=t}function j(t){var e=[];return{add:function(r){e.unshift(r),e.length>t&&(e.length=t)},back:function(t){var r=e[t-1];return r&&(e=e.slice(t)),r},get:function(){return e}}}var w=t("./type.js"),_=a.bind(null,!1),$=a.bind(null,!0);e.exports={archive:j,arrayOf:n,before:o,deepClone:$,shallowClone:_,shallowMerge:i,compose:h,getIn:y,inherits:m,pathObject:b,solvePath:g,solveUpdate:v}}).call(this,"undefined"!=typeof global?global:"undefined"!=typeof self?self:"undefined"!=typeof window?window:{})},{"./type.js":9}],8:[function(t,e,r){function n(t,e,r){a.forEach(function(e){r!==e&&delete t[e]}),t[r]=e[r]}function o(t,e){var r,h=i.shallowClone(e||{});a.forEach(function(e){t[e]&&n(h,t,e)}),t.$chain&&(a.slice(0,-1).forEach(function(t){delete h[t]}),h.$apply=h.$apply?i.compose(h.$apply,t.$chain):t.$chain),t.$push&&h.$push?h.$push=s.Array(h.$push)?h.$push.concat(t.$push):[h.$push].concat(t.$push):t.$push&&(h.$push=t.$push),t.$unshift&&h.$unshift?h.$unshift=s.Array(t.$unshift)?t.$unshift.concat(h.$unshift):[t.$unshift].concat(h.$unshift):t.$unshift&&(h.$unshift=t.$unshift);for(r in t)s.Object(t[r])?h[r]=o(t[r],h[r]):"$"!==r[0]&&(h[r]=t[r]);return h}var i=t("./helpers.js"),s=t("./type.js"),a=["$unset","$set","$merge","$apply"];e.exports=o},{"./helpers.js":7,"./type.js":9}],9:[function(t,e,r){function n(t,e){return e.some(function(e){return o[e](t)})}var o={};o.Array=function(t){return Array.isArray(t)},o.Object=function(t){return t&&"object"==typeof t&&!Array.isArray(t)&&!(t instanceof Function)},o.String=function(t){return"string"==typeof t},o.Number=function(t){return"number"==typeof t},o.PositiveInteger=function(t){return"number"==typeof t&&t>0&&t%1===0},o.Function=function(t){return"function"==typeof t},o.Primitive=function(t){return"string"==typeof t||"number"==typeof t||"boolean"==typeof t},o.Date=function(t){return t instanceof Date},o.NonScalar=function(t){return o.Object(t)||o.Array(t)},o.Path=function(t){var e=["String","Number","Function","Object"];return o.Array(t)?t.every(function(t){return n(t,e)}):n(t,e)},o.MixinCursor=function(t){return n(t,["String","Number","Array","Function","Cursor"])},o.MixinCursors=function(t){return n(t,["Object","Array","Function"])},o.ComplexPath=function(t){return t.some(function(t){return n(t,["Object","Function"])})},e.exports=o},{}],10:[function(t,e,r){function n(t,e){var r=new Error("baobab.update: "+e+" at path /"+t.slice(1).join("/"));return r.path=t,r}var o=t("./helpers.js"),i=t("./type.js");e.exports=function(t,e,r){if(r=r||{},!i.Object(t)&&!i.Array(t))throw Error("baobab.update: invalid target.");var s={};t={root:o.shallowClone(t)};var a=function(t,e,r,h){r=r||["root"];var u,c,l,f=r.join("|λ|"),p=r[r.length-1],d=Object.keys(e).some(function(t){return!!~["$unset","$set","$apply","$merge","$push","$unshift"].indexOf(t)});if(d){s[f]=!0;for(c in e){if("$unset"===c){var y=r[r.length-2];i.Array(t)?h[y]=t.slice(0,+p).concat(t.slice(+p+1)):(h[y]=o.shallowClone(t),delete h[y][p]);break}if("$set"===c){l=e.$set,t[p]=l;break}if("$apply"===c){if(u=e.$apply,"function"!=typeof u)throw n(r,"using command $apply with a non function");t[p]=u.call(null,t[p]);break}if("$merge"===c){if(l=e.$merge,!i.Object(t[p])||!i.Object(l))throw n(r,"using command $merge with a non object");t[p]=o.shallowMerge(t[p],l);break}if("$push"===c){if(l=e.$push,!i.Array(t[p]))throw n(r,"using command $push to a non array");t[p]=t[p].concat(l)}if("$unshift"===c){if(l=e.$unshift,!i.Array(t[p]))throw n(r,"using command $unshift to a non array");t[p]=[].concat(l).concat(t[p])}}}else for(c in e)t[p][c]="undefined"==typeof t[p][c]?{}:o.shallowClone(t[p][c]),a(t[p],e[c],r.concat(c),t)};return a(t,e),{data:t.root,log:Object.keys(s).map(function(t){return t.split("|λ|").slice(1)})}}},{"./helpers.js":7,"./type.js":9}],11:[function(t,e,r){function n(t,e){function r(){h&&(a=e.map(function(t){return i.solvePath(n.tree.data,t,n.tree)}))}var n=this;o.call(this),this.tree=t;var a=e,h=e.some(s.ComplexPath);this.updateHandler=function(t){var e=i.solveUpdate(t.data.log,a);e&&n.emit("update")},r(),this.tree.on("update",this.updateHandler)}var o=t("emmett"),i=t("./helpers.js"),s=t("./type.js");i.inherits(n,o),n.prototype.release=function(){this.tree.off("update",this.updateHandler),this.tree=null,this.kill()},e.exports=n},{"./helpers.js":7,"./type.js":9,emmett:3}]},{},[1])(1)}); \ No newline at end of file diff --git a/src/helpers.js b/src/helpers.js index 674a84a..9d1adbc 100644 --- a/src/helpers.js +++ b/src/helpers.js @@ -30,31 +30,6 @@ function shallowMerge(o1, o2) { return o; } -// Shallow equality -function shallowEqual(o1, o2) { - if (o1 === o2) - return true; - - if (typeof o1 !== 'object' || typeof o2 !== 'object' || - o1 === null || o2 === null) - return false; - - var k1 = Object.keys(o1), - k2 = Object.keys(o2); - - if (k1.length !== k2.length) - return false; - - var i, l; - - for (i = 0, l = k1.length; i < l; i++) { - if (o1[k1[i]] !== o2[k1[i]]) - return false; - } - - return true; -} - // Clone a regexp function cloneRegexp(re) { var pattern = re.source, @@ -367,7 +342,6 @@ module.exports = { before: before, deepClone: deepClone, shallowClone: shallowClone, - shallowEqual: shallowEqual, shallowMerge: shallowMerge, compose: compose, getIn: getIn, diff --git a/test/suites/helpers.js b/test/suites/helpers.js index 400c1c5..00a946d 100644 --- a/test/suites/helpers.js +++ b/test/suites/helpers.js @@ -116,17 +116,6 @@ describe('Helpers', function() { }); }); - describe('Shallow equality', function() { - var se = helpers.shallowEqual; - - it('should check equalities correctly.', function() { - assert(se('Hey!', 'Hey!')); - assert(se(0, 0)); - assert(se({hello: 'world'}, {hello: 'world'})); - assert(!se({hello: 'world'}, {hey: 'ho'})); - }); - }); - describe('Update API', function() { it('should be possible to set nested values.', function() { From 8ebd594ef1dbf9ead9dcf5c5461b37f6a80a3ae2 Mon Sep 17 00:00:00 2001 From: Yomguithereal Date: Wed, 15 Apr 2015 15:38:18 +0200 Subject: [PATCH 52/73] Adding an identity to the cursor object --- build/baobab.min.js | 2 +- src/cursor.js | 7 +++++++ 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/build/baobab.min.js b/build/baobab.min.js index 0778648..18abf58 100644 --- a/build/baobab.min.js +++ b/build/baobab.min.js @@ -1,2 +1,2 @@ /* baobab.js - Version: 1.0.0-rc1 - Author: Yomguithereal (Guillaume Plique) */ -!function(t){if("object"==typeof exports&&"undefined"!=typeof module)module.exports=t();else if("function"==typeof define&&define.amd)define([],t);else{var e;e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:this,e.Baobab=t()}}(function(){var t;return function e(t,r,n){function o(s,a){if(!r[s]){if(!t[s]){var h="function"==typeof require&&require;if(!a&&h)return h(s,!0);if(i)return i(s,!0);var u=new Error("Cannot find module '"+s+"'");throw u.code="MODULE_NOT_FOUND",u}var c=r[s]={exports:{}};t[s][0].call(c.exports,function(e){var r=t[s][1][e];return o(r?r:e)},c,c.exports,e,t,r,n)}return r[s].exports}for(var i="function"==typeof require&&require,s=0;sn;n++)t[n].fn!==e&&o.push(t[n]);return o}var s={once:"boolean",scope:"object"},a=0,h=function(){this._enabled=!0,this.unbindAll()};h.prototype.unbindAll=function(){return this._handlers={},this._handlersAll=[],this._handlersComplex=[],this},h.prototype.on=function(t,e,r){var n,i,h,u,c,l,f;if(o(t)){for(u in t)this.on(u,t[u],e);return this}for("function"==typeof t&&(r=e,e=t,t=null),c=[].concat(t),n=0,i=c.length;i>n;n++){if(u=c[n],f={order:a++,fn:e},"string"==typeof u)this._handlers[u]||(this._handlers[u]=[]),l=this._handlers[u];else if(u instanceof RegExp)l=this._handlersComplex,f.pattern=u;else{if(null!==u)throw Error("Emitter.on: invalid event.");l=this._handlersAll}for(h in r||{})s[h]&&(f[h]=r[h]);f.once&&(f.parent=l),l.push(f)}return this},h.prototype.once=function(){var t=Array.prototype.slice.call(arguments),r=t.length-1;return o(t[r])&&t.length>1?t[r]=e(t[r],{once:!0}):t.push({once:!0}),this.on.apply(this,t)},h.prototype.off=function(t,e){var r,n,s,a;if(1===arguments.length&&"function"==typeof t){e=arguments[0];for(s in this._handlers)this._handlers[s]=i(this._handlers[s],e),0===this._handlers[s].length&&delete this._handlers[s];this._handlersAll=i(this._handlersAll,e),this._handlersComplex=i(this._handlersComplex,e)}else if(1===arguments.length&&"string"==typeof t)delete this._handlers[t];else if(2===arguments.length){var h=[].concat(t);for(r=0,n=h.length;n>r;r++)a=h[r],this._handlers[a]=i(this._handlers[a],e),0===(this._handlers[a]||[]).length&&delete this._handlers[a]}else if(o(t))for(s in t)this.off(s,t[s]);return this},h.prototype.listeners=function(t){var e,r,n,o=this._handlersAll||[],i=!1;if(!t)throw Error("Emitter.listeners: no event provided.");for(o=o.concat(this._handlers[t]||[]),r=0,n=this._handlersComplex.length;n>r;r++)e=this._handlersComplex[r],~t.search(e.pattern)&&(i=!0,o.push(e));return this._handlersAll.length||i?o.sort(function(t,e){return t.order-e.order}):o.slice(0)},h.prototype.emit=function(t,e){if(!this._enabled)return this;if(o(t)){for(var r in t)this.emit(r,t[r]);return this}var n,i,s,a,h,u,c,l=[].concat(t),f=[];for(a=0,u=l.length;u>a;a++){for(i=this.listeners(l[a]),h=0,c=i.length;c>h;h++)s=i[h],n={type:l[a],target:this},arguments.length>1&&(n.data=e),s.fn.call("scope"in s?s.scope:this,n),s.once&&f.push(s);for(h=f.length-1;h>=0;h--)f[h].parent.splice(f[h].parent.indexOf(f[h]),1)}return this},h.prototype.kill=function(){this.unbindAll(),this._handlers=null,this._handlersAll=null,this._handlersComplex=null,this._enabled=!1},h.prototype.disable=function(){return this._enabled=!1,this},h.prototype.enable=function(){return this._enabled=!0,this},h.version="3.0.0","undefined"!=typeof n?("undefined"!=typeof r&&r.exports&&(n=r.exports=h),n.Emitter=h):"function"==typeof t&&t.amd?t("emmett",[],function(){return h}):this.Emitter=h}).call(this)},{}],4:[function(t,e,r){function n(t){return t+"$"+(new Date).getTime()+(""+Math.random()).replace("0.","")}function o(t,e){function r(t){this[t]=function(){var e=this.root[t].apply(this.root,arguments);return e instanceof i?this:e}}if(arguments.length<1&&(t={}),!(this instanceof o))return new o(t,e);if(!p.Object(t)&&!p.Array(t))throw Error("Baobab: invalid data.");if(s.call(this),this.options=u.shallowMerge(f,e),this._transaction={},this._future=void 0,this._cursors={},this._identity="[object Baobab]",this.data=u.deepClone(t),this.root=this.select([]),this.facets={},["get","set","unset","update"].forEach(r.bind(this)),!p.Object(this.options.facets))throw Error("Baobab: invalid facets.");for(var n in this.options.facets)this.addFacet(n,this.options.facets[n])}var i=t("./cursor.js"),s=t("emmett"),a=t("./watcher.js"),h=t("./facet.js"),u=t("./helpers.js"),c=t("./update.js"),l=t("./merge.js"),f=t("../defaults.js"),p=t("./type.js");u.inherits(o,s),o.prototype.addFacet=function(t,e){return this.facets[t]=this.createFacet(e),this},o.prototype.createFacet=function(t){return new h(this,t)},o.prototype.select=function(t){if(!t)throw Error("Baobab.select: invalid path.");if(arguments.length>1&&(t=u.arrayOf(arguments)),!p.Path(t))throw Error("Baobab.select: invalid path.");t=[].concat(t);var e,r=p.ComplexPath(t);r&&(e=u.solvePath(this.data,t,this));var o=t.map(function(t){return p.Function(t)?n("fn"):p.Object(t)?n("ob"):t}).join("|λ|");if(this._cursors[o])return this._cursors[o];var s=new i(this,t,e,o);return this._cursors[o]=s,s},o.prototype.stack=function(t){var e=this;if(!p.Object(t))throw Error("Baobab.update: wrong specification.");return this._transaction=l(t,this._transaction),this.options.autoCommit?this.options.asynchronous?(this._future||(this._future=setTimeout(e.commit.bind(e,null),0)),this):this.commit():this},o.prototype.commit=function(){var t=c(this.data,this._transaction,this.options),e=this.data;return this.data=t.data,this._transaction={},this._future&&(this._future=clearTimeout(this._future)),this.emit("update",{log:t.log,previousState:e}),this},o.prototype.watch=function(t){if(!p.Array(t)||t.some(function(t){return!p.Path(t)}))throw Error("Baobab.watch: invalid paths.");return new a(this,[].concat(t))},o.prototype.release=function(){var t;delete this.data,delete this._transaction;for(t in this._cursors)this._cursors[t].release();delete this._cursors;for(t in this.facets)this.facets[t].release();delete this.facets,this.kill()},o.prototype.toJSON=function(){return this.get()},o.prototype.toString=function(){return this._identity},e.exports=o},{"../defaults.js":2,"./cursor.js":5,"./facet.js":6,"./helpers.js":7,"./merge.js":8,"./type.js":9,"./update.js":10,"./watcher.js":11,emmett:3}],5:[function(t,e,r){function n(t,e,r,n){function o(t){if(i.isRecording()&&!i.undoing){var e=a.getIn(t,i.solvedPath,i.tree),r=a.deepClone(e);i.archive.add(r)}return i.undoing=!1,i.emit("update")}var i=this;s.call(this),e=e||[],this.tree=t,this.path=e,this.hash=n,this.archive=null,this.undoing=!1,this.complexPath=!!r,this.solvedPath=this.complexPath?r:this.path,this.relevant=void 0!==this.get(),this.updateHandler=function(t){var e=t.data.log,r=t.data.previousState,n=!1;if(i.complexPath&&(i.solvedPath=a.solvePath(i.tree.data,i.path,i.tree)),!i.path.length)return o(r);i.solvedPath&&(n=a.solveUpdate(e,[i.solvedPath]));var s=void 0!==i.get();i.relevant?s&&n?o(r):s||(i.emit("irrelevant"),i.relevant=!1):s&&n&&(i.emit("relevant"),o(r),i.relevant=!0)};var h=!1;this._lazyBind=function(){h||(h=!0,i.tree.on("update",i.updateHandler))},this.on=a.before(this._lazyBind,this.on.bind(this)),this.once=a.before(this._lazyBind,this.once.bind(this)),this.complexPath&&this._lazyBind()}function o(t,e,r,n){if(arguments.length>5)throw Error("baobab.Cursor."+t+": too many arguments.");arguments.length<4&&(n=r,r=[]),r=r||[];var o=[].concat(r),i=a.solvePath(this.get(),o,this.tree);if(!i)throw Error("baobab.Cursor."+t+": could not solve dynamic path.");if(e){var s=this.get(i);if(!h[e](s))throw Error("baobab.Cursor."+t+": invalid target.")}var u={};u["$"+t]=n;var c=a.pathObject(i,u);return c}function i(t,e){n.prototype[t]=function(){var r=o.bind(this,t,e).apply(this,arguments);return this.update(r)}}var s=t("emmett"),a=t("./helpers.js"),h=(t("../defaults.js"),t("./type.js"));a.inherits(n,s),n.prototype.isRoot=function(){return!this.path.length},n.prototype.isLeaf=function(){return h.Primitive(this.get())},n.prototype.isBranch=function(){return!this.isLeaf()&&!this.isRoot()},n.prototype.root=function(){return this.tree.root()},n.prototype.select=function(t){if(arguments.length>1&&(t=a.arrayOf(arguments)),!h.Path(t))throw Error("baobab.Cursor.select: invalid path.");return this.tree.select(this.path.concat(t))},n.prototype.up=function(){return this.solvedPath&&this.solvedPath.length?this.tree.select(this.path.slice(0,-1)):null},n.prototype.left=function(){var t=+this.solvedPath[this.solvedPath.length-1];if(isNaN(t))throw Error("baobab.Cursor.left: cannot go left on a non-list type.");return t?this.tree.select(this.solvedPath.slice(0,-1).concat(t-1)):null},n.prototype.leftmost=function(){var t=+this.solvedPath[this.solvedPath.length-1];if(isNaN(t))throw Error("baobab.Cursor.leftmost: cannot go left on a non-list type.");return this.tree.select(this.solvedPath.slice(0,-1).concat(0))},n.prototype.right=function(){var t=+this.solvedPath[this.solvedPath.length-1];if(isNaN(t))throw Error("baobab.Cursor.right: cannot go right on a non-list type.");return t+1===this.up().get().length?null:this.tree.select(this.solvedPath.slice(0,-1).concat(t+1))},n.prototype.rightmost=function(){var t=+this.solvedPath[this.solvedPath.length-1];if(isNaN(t))throw Error("baobab.Cursor.right: cannot go right on a non-list type.");var e=this.up().get();return this.tree.select(this.solvedPath.slice(0,-1).concat(e.length-1))},n.prototype.down=function(){+this.solvedPath[this.solvedPath.length-1];return this.get()instanceof Array?this.tree.select(this.solvedPath.concat(0)):null},n.prototype.get=function(t){arguments.length>1&&(t=a.arrayOf(arguments));var e=this.solvedPath.concat([].concat(t||0===t?t:[]));return a.getIn(this.tree.data,e,this.tree)},i("set"),i("apply"),i("chain"),i("push","Array"),i("unshift","Array"),n.prototype.merge=function(t){if(!h.Object(t))throw Error("baobab.Cursor.merge: trying to merge a non-object.");var e=o.bind(this,"merge","Object").apply(this,arguments);return this.update(e)},n.prototype.unset=function(t){if(void 0===t&&this.isRoot())throw Error("baobab.Cursor.unset: cannot remove root node.");var e=o.bind(this,"unset",null).apply(this,[t,!0]);return this.update(e)},n.prototype.update=function(t,e){if(arguments.length<2)return this.tree.stack(a.pathObject(this.solvedPath,t)),this;var r=[].concat(t),n=a.solvePath(this.get(),r,this.tree);if(!n)throw Error("baobab.Cursor.update: could not solve dynamic path.");return this.tree.stack(a.pathObject(this.solvedPath.concat(n),e)),this},n.prototype.startRecording=function(t){if(t=t||5,1>t)throw Error("baobab.Cursor.startRecording: invalid maximum number of records.");return this.archive?this:(this._lazyBind(),this.archive=a.archive(t),this)},n.prototype.stopRecording=function(){return this.archive=null,this},n.prototype.undo=function(t){if(t=t||1,!this.isRecording())throw Error("baobab.Cursor.undo: cursor is not recording.");if(!h.PositiveInteger(t))throw Error("baobab.Cursor.undo: expecting a positive integer.");var e=this.archive.back(t);if(!e)throw Error("boabab.Cursor.undo: cannot find a relevant record ("+t+" back).");return this.undoing=!0,this.set(e)},n.prototype.isRecording=function(){return!!this.archive},n.prototype.hasHistory=function(){return!(!this.archive||!this.archive.get().length)},n.prototype.getHistory=function(){return this.archive?this.archive.get():[]},n.prototype.release=function(){this.tree.off("update",this.updateHandler),this.hash&&delete this.tree._cursors[this.hash],delete this.tree,delete this.path,delete this.solvedPath,delete this.archive,this.kill()},n.prototype.toJSON=function(){return this.get()},h.Cursor=function(t){return t instanceof n},e.exports=n},{"../defaults.js":2,"./helpers.js":7,"./type.js":9,emmett:3}],6:[function(t,e,r){function n(t){return t}function o(t,e){function r(t){o[t]=l[t].bind(l)}var o=this,s=null,a=!1,h=e.get||n,u=e.cursors,c=Object.keys(u).map(function(t){return u[t]}),l=new i(t,c);["on","once","release"].forEach(r),this.get=function(){if(a)return s;var e={};for(var r in u)e[r]=t.get(u[r]);return s=h.call(null,e),a=!0,s},this.on("update",function(){a=!1})}{var i=t("./watcher.js");t("./helpers.js")}e.exports=o},{"./helpers.js":7,"./watcher.js":11}],7:[function(t,e,r){(function(r){function n(t){return Array.prototype.slice.call(t)}function o(t,e){return function(){t(),e.apply(null,arguments)}}function i(t,e){var r,n={};for(r in t)n[r]=t[r];for(r in e)n[r]=e[r];return n}function s(t){var e=t.source,r="";return t.global&&(r+="g"),t.multiline&&(r+="m"),t.ignoreCase&&(r+="i"),t.sticky&&(r+="y"),t.unicode&&(r+="u"),new RegExp(e,r)}function a(t,e){if(!e||"object"!=typeof e||e instanceof Error||"ArrayBuffer"in r&&e instanceof ArrayBuffer)return e;if(w.Array(e)){if(t){var n,o,i=[];for(n=0,o=e.length;o>n;n++)i.push($(e[n]));return i}return e.slice(0)}if(w.Date(e))return new Date(e.getTime());if(e instanceof RegExp)return s(e);if(w.Object(e)){var a,h={};e.constructor&&e.constructor!==Object&&(h=Object.create(e.constructor.prototype));for(a in e)e.hasOwnProperty(a)&&(h[a]=t?$(e[a]):e[a]);return h}return e}function h(t,e){return function(r){return e(t(r))}}function u(t,e){var r,n;for(r=0,n=t.length;n>r;r++)if(e(t[r]))return t[r]}function c(t,e){var r,n;for(r=0,n=t.length;n>r;r++)if(e(t[r]))return r;return-1}function l(t,e){var r,n=!0;if(!t)return!1;for(r in e)if(w.Object(e[r]))n=n&&l(t[r],e[r]);else if(w.Array(e[r]))n=n&&!!~e[r].indexOf(t[r]);else if(t[r]!==e[r])return!1;return n}function f(t,e){return u(t,function(t){return l(t,e)})}function d(t,e){return c(t,function(t){return l(t,e)})}function y(t,e,r){e=e||[];var n,o,i,s=t;for(o=0,i=e.length;i>o;o++){if(!s)return;if("function"==typeof e[o]){if(!w.Array(s))return;s=u(s,e[o])}else if("object"==typeof e[o])if(r&&"$cursor"in e[o]){if(!w.Path(e[o].$cursor))throw Error("baobab.getIn: $cursor path must be an array.");n=r.get(e[o].$cursor),s=s[n]}else{if(!w.Array(s))return;s=f(s,e[o])}else s=s[e[o]]}return s}function g(t,e,r){var n,o,i,s=[],a=t;for(o=0,i=e.length;i>o;o++){if(!a)return null;if("function"==typeof e[o]){if(!w.Array(a))return;n=c(a,e[o]),s.push(n),a=a[n]}else if("object"==typeof e[o])if(r&&"$cursor"in e[o]){if(!w.Path(e[o].$cursor))throw Error("baobab.getIn: $cursor path must be an array.");p=r.get(e[o].$cursor),s.push(p),a=a[p]}else{if(!w.Array(a))return;n=d(a,e[o]),s.push(n),a=a[n]}else s.push(e[o]),a=a[e[o]]||{}}return s}function v(t,e){var r,n,o,i,s,a,h,u,c;for(r=0,i=e.length;i>r;r++)for(h=e[r],n=0,s=t.length;s>n;n++)for(u=t[n],o=0,a=u.length;a>o&&(c=u[o],c==h[o]);o++)if(o+1===a||o+1===h.length)return!0;return!1}function b(t,e){var r,n=t.length,o={},i=o;for(n||(o=e),r=0;n>r;r++)i[t[r]]=r+1===n?e:{},i=i[t[r]];return o}function m(t,e){t.super_=e;var r=function(){};r.prototype=e.prototype,t.prototype=new r,t.prototype.constructor=t}function j(t){var e=[];return{add:function(r){e.unshift(r),e.length>t&&(e.length=t)},back:function(t){var r=e[t-1];return r&&(e=e.slice(t)),r},get:function(){return e}}}var w=t("./type.js"),_=a.bind(null,!1),$=a.bind(null,!0);e.exports={archive:j,arrayOf:n,before:o,deepClone:$,shallowClone:_,shallowMerge:i,compose:h,getIn:y,inherits:m,pathObject:b,solvePath:g,solveUpdate:v}}).call(this,"undefined"!=typeof global?global:"undefined"!=typeof self?self:"undefined"!=typeof window?window:{})},{"./type.js":9}],8:[function(t,e,r){function n(t,e,r){a.forEach(function(e){r!==e&&delete t[e]}),t[r]=e[r]}function o(t,e){var r,h=i.shallowClone(e||{});a.forEach(function(e){t[e]&&n(h,t,e)}),t.$chain&&(a.slice(0,-1).forEach(function(t){delete h[t]}),h.$apply=h.$apply?i.compose(h.$apply,t.$chain):t.$chain),t.$push&&h.$push?h.$push=s.Array(h.$push)?h.$push.concat(t.$push):[h.$push].concat(t.$push):t.$push&&(h.$push=t.$push),t.$unshift&&h.$unshift?h.$unshift=s.Array(t.$unshift)?t.$unshift.concat(h.$unshift):[t.$unshift].concat(h.$unshift):t.$unshift&&(h.$unshift=t.$unshift);for(r in t)s.Object(t[r])?h[r]=o(t[r],h[r]):"$"!==r[0]&&(h[r]=t[r]);return h}var i=t("./helpers.js"),s=t("./type.js"),a=["$unset","$set","$merge","$apply"];e.exports=o},{"./helpers.js":7,"./type.js":9}],9:[function(t,e,r){function n(t,e){return e.some(function(e){return o[e](t)})}var o={};o.Array=function(t){return Array.isArray(t)},o.Object=function(t){return t&&"object"==typeof t&&!Array.isArray(t)&&!(t instanceof Function)},o.String=function(t){return"string"==typeof t},o.Number=function(t){return"number"==typeof t},o.PositiveInteger=function(t){return"number"==typeof t&&t>0&&t%1===0},o.Function=function(t){return"function"==typeof t},o.Primitive=function(t){return"string"==typeof t||"number"==typeof t||"boolean"==typeof t},o.Date=function(t){return t instanceof Date},o.NonScalar=function(t){return o.Object(t)||o.Array(t)},o.Path=function(t){var e=["String","Number","Function","Object"];return o.Array(t)?t.every(function(t){return n(t,e)}):n(t,e)},o.MixinCursor=function(t){return n(t,["String","Number","Array","Function","Cursor"])},o.MixinCursors=function(t){return n(t,["Object","Array","Function"])},o.ComplexPath=function(t){return t.some(function(t){return n(t,["Object","Function"])})},e.exports=o},{}],10:[function(t,e,r){function n(t,e){var r=new Error("baobab.update: "+e+" at path /"+t.slice(1).join("/"));return r.path=t,r}var o=t("./helpers.js"),i=t("./type.js");e.exports=function(t,e,r){if(r=r||{},!i.Object(t)&&!i.Array(t))throw Error("baobab.update: invalid target.");var s={};t={root:o.shallowClone(t)};var a=function(t,e,r,h){r=r||["root"];var u,c,l,f=r.join("|λ|"),p=r[r.length-1],d=Object.keys(e).some(function(t){return!!~["$unset","$set","$apply","$merge","$push","$unshift"].indexOf(t)});if(d){s[f]=!0;for(c in e){if("$unset"===c){var y=r[r.length-2];i.Array(t)?h[y]=t.slice(0,+p).concat(t.slice(+p+1)):(h[y]=o.shallowClone(t),delete h[y][p]);break}if("$set"===c){l=e.$set,t[p]=l;break}if("$apply"===c){if(u=e.$apply,"function"!=typeof u)throw n(r,"using command $apply with a non function");t[p]=u.call(null,t[p]);break}if("$merge"===c){if(l=e.$merge,!i.Object(t[p])||!i.Object(l))throw n(r,"using command $merge with a non object");t[p]=o.shallowMerge(t[p],l);break}if("$push"===c){if(l=e.$push,!i.Array(t[p]))throw n(r,"using command $push to a non array");t[p]=t[p].concat(l)}if("$unshift"===c){if(l=e.$unshift,!i.Array(t[p]))throw n(r,"using command $unshift to a non array");t[p]=[].concat(l).concat(t[p])}}}else for(c in e)t[p][c]="undefined"==typeof t[p][c]?{}:o.shallowClone(t[p][c]),a(t[p],e[c],r.concat(c),t)};return a(t,e),{data:t.root,log:Object.keys(s).map(function(t){return t.split("|λ|").slice(1)})}}},{"./helpers.js":7,"./type.js":9}],11:[function(t,e,r){function n(t,e){function r(){h&&(a=e.map(function(t){return i.solvePath(n.tree.data,t,n.tree)}))}var n=this;o.call(this),this.tree=t;var a=e,h=e.some(s.ComplexPath);this.updateHandler=function(t){var e=i.solveUpdate(t.data.log,a);e&&n.emit("update")},r(),this.tree.on("update",this.updateHandler)}var o=t("emmett"),i=t("./helpers.js"),s=t("./type.js");i.inherits(n,o),n.prototype.release=function(){this.tree.off("update",this.updateHandler),this.tree=null,this.kill()},e.exports=n},{"./helpers.js":7,"./type.js":9,emmett:3}]},{},[1])(1)}); \ No newline at end of file +!function(t){if("object"==typeof exports&&"undefined"!=typeof module)module.exports=t();else if("function"==typeof define&&define.amd)define([],t);else{var e;e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:this,e.Baobab=t()}}(function(){var t;return function e(t,r,n){function o(s,a){if(!r[s]){if(!t[s]){var h="function"==typeof require&&require;if(!a&&h)return h(s,!0);if(i)return i(s,!0);var u=new Error("Cannot find module '"+s+"'");throw u.code="MODULE_NOT_FOUND",u}var c=r[s]={exports:{}};t[s][0].call(c.exports,function(e){var r=t[s][1][e];return o(r?r:e)},c,c.exports,e,t,r,n)}return r[s].exports}for(var i="function"==typeof require&&require,s=0;sn;n++)t[n].fn!==e&&o.push(t[n]);return o}var s={once:"boolean",scope:"object"},a=0,h=function(){this._enabled=!0,this.unbindAll()};h.prototype.unbindAll=function(){return this._handlers={},this._handlersAll=[],this._handlersComplex=[],this},h.prototype.on=function(t,e,r){var n,i,h,u,c,l,f;if(o(t)){for(u in t)this.on(u,t[u],e);return this}for("function"==typeof t&&(r=e,e=t,t=null),c=[].concat(t),n=0,i=c.length;i>n;n++){if(u=c[n],f={order:a++,fn:e},"string"==typeof u)this._handlers[u]||(this._handlers[u]=[]),l=this._handlers[u];else if(u instanceof RegExp)l=this._handlersComplex,f.pattern=u;else{if(null!==u)throw Error("Emitter.on: invalid event.");l=this._handlersAll}for(h in r||{})s[h]&&(f[h]=r[h]);f.once&&(f.parent=l),l.push(f)}return this},h.prototype.once=function(){var t=Array.prototype.slice.call(arguments),r=t.length-1;return o(t[r])&&t.length>1?t[r]=e(t[r],{once:!0}):t.push({once:!0}),this.on.apply(this,t)},h.prototype.off=function(t,e){var r,n,s,a;if(1===arguments.length&&"function"==typeof t){e=arguments[0];for(s in this._handlers)this._handlers[s]=i(this._handlers[s],e),0===this._handlers[s].length&&delete this._handlers[s];this._handlersAll=i(this._handlersAll,e),this._handlersComplex=i(this._handlersComplex,e)}else if(1===arguments.length&&"string"==typeof t)delete this._handlers[t];else if(2===arguments.length){var h=[].concat(t);for(r=0,n=h.length;n>r;r++)a=h[r],this._handlers[a]=i(this._handlers[a],e),0===(this._handlers[a]||[]).length&&delete this._handlers[a]}else if(o(t))for(s in t)this.off(s,t[s]);return this},h.prototype.listeners=function(t){var e,r,n,o=this._handlersAll||[],i=!1;if(!t)throw Error("Emitter.listeners: no event provided.");for(o=o.concat(this._handlers[t]||[]),r=0,n=this._handlersComplex.length;n>r;r++)e=this._handlersComplex[r],~t.search(e.pattern)&&(i=!0,o.push(e));return this._handlersAll.length||i?o.sort(function(t,e){return t.order-e.order}):o.slice(0)},h.prototype.emit=function(t,e){if(!this._enabled)return this;if(o(t)){for(var r in t)this.emit(r,t[r]);return this}var n,i,s,a,h,u,c,l=[].concat(t),f=[];for(a=0,u=l.length;u>a;a++){for(i=this.listeners(l[a]),h=0,c=i.length;c>h;h++)s=i[h],n={type:l[a],target:this},arguments.length>1&&(n.data=e),s.fn.call("scope"in s?s.scope:this,n),s.once&&f.push(s);for(h=f.length-1;h>=0;h--)f[h].parent.splice(f[h].parent.indexOf(f[h]),1)}return this},h.prototype.kill=function(){this.unbindAll(),this._handlers=null,this._handlersAll=null,this._handlersComplex=null,this._enabled=!1},h.prototype.disable=function(){return this._enabled=!1,this},h.prototype.enable=function(){return this._enabled=!0,this},h.version="3.0.0","undefined"!=typeof n?("undefined"!=typeof r&&r.exports&&(n=r.exports=h),n.Emitter=h):"function"==typeof t&&t.amd?t("emmett",[],function(){return h}):this.Emitter=h}).call(this)},{}],4:[function(t,e,r){function n(t){return t+"$"+(new Date).getTime()+(""+Math.random()).replace("0.","")}function o(t,e){function r(t){this[t]=function(){var e=this.root[t].apply(this.root,arguments);return e instanceof i?this:e}}if(arguments.length<1&&(t={}),!(this instanceof o))return new o(t,e);if(!p.Object(t)&&!p.Array(t))throw Error("Baobab: invalid data.");if(s.call(this),this.options=u.shallowMerge(f,e),this._transaction={},this._future=void 0,this._cursors={},this._identity="[object Baobab]",this.data=u.deepClone(t),this.root=this.select([]),this.facets={},["get","set","unset","update"].forEach(r.bind(this)),!p.Object(this.options.facets))throw Error("Baobab: invalid facets.");for(var n in this.options.facets)this.addFacet(n,this.options.facets[n])}var i=t("./cursor.js"),s=t("emmett"),a=t("./watcher.js"),h=t("./facet.js"),u=t("./helpers.js"),c=t("./update.js"),l=t("./merge.js"),f=t("../defaults.js"),p=t("./type.js");u.inherits(o,s),o.prototype.addFacet=function(t,e){return this.facets[t]=this.createFacet(e),this},o.prototype.createFacet=function(t){return new h(this,t)},o.prototype.select=function(t){if(!t)throw Error("Baobab.select: invalid path.");if(arguments.length>1&&(t=u.arrayOf(arguments)),!p.Path(t))throw Error("Baobab.select: invalid path.");t=[].concat(t);var e,r=p.ComplexPath(t);r&&(e=u.solvePath(this.data,t,this));var o=t.map(function(t){return p.Function(t)?n("fn"):p.Object(t)?n("ob"):t}).join("|λ|");if(this._cursors[o])return this._cursors[o];var s=new i(this,t,e,o);return this._cursors[o]=s,s},o.prototype.stack=function(t){var e=this;if(!p.Object(t))throw Error("Baobab.update: wrong specification.");return this._transaction=l(t,this._transaction),this.options.autoCommit?this.options.asynchronous?(this._future||(this._future=setTimeout(e.commit.bind(e,null),0)),this):this.commit():this},o.prototype.commit=function(){var t=c(this.data,this._transaction,this.options),e=this.data;return this.data=t.data,this._transaction={},this._future&&(this._future=clearTimeout(this._future)),this.emit("update",{log:t.log,previousState:e}),this},o.prototype.watch=function(t){if(!p.Array(t)||t.some(function(t){return!p.Path(t)}))throw Error("Baobab.watch: invalid paths.");return new a(this,[].concat(t))},o.prototype.release=function(){var t;delete this.data,delete this._transaction;for(t in this._cursors)this._cursors[t].release();delete this._cursors;for(t in this.facets)this.facets[t].release();delete this.facets,this.kill()},o.prototype.toJSON=function(){return this.get()},o.prototype.toString=function(){return this._identity},e.exports=o},{"../defaults.js":2,"./cursor.js":5,"./facet.js":6,"./helpers.js":7,"./merge.js":8,"./type.js":9,"./update.js":10,"./watcher.js":11,emmett:3}],5:[function(t,e,r){function n(t,e,r,n){function o(t){if(i.isRecording()&&!i.undoing){var e=a.getIn(t,i.solvedPath,i.tree),r=a.deepClone(e);i.archive.add(r)}return i.undoing=!1,i.emit("update")}var i=this;s.call(this),e=e||[],this.tree=t,this.path=e,this.hash=n,this.archive=null,this.undoing=!1,this._identity="[object Cursor]",this.complexPath=!!r,this.solvedPath=this.complexPath?r:this.path,this.relevant=void 0!==this.get(),this.updateHandler=function(t){var e=t.data.log,r=t.data.previousState,n=!1;if(i.complexPath&&(i.solvedPath=a.solvePath(i.tree.data,i.path,i.tree)),!i.path.length)return o(r);i.solvedPath&&(n=a.solveUpdate(e,[i.solvedPath]));var s=void 0!==i.get();i.relevant?s&&n?o(r):s||(i.emit("irrelevant"),i.relevant=!1):s&&n&&(i.emit("relevant"),o(r),i.relevant=!0)};var h=!1;this._lazyBind=function(){h||(h=!0,i.tree.on("update",i.updateHandler))},this.on=a.before(this._lazyBind,this.on.bind(this)),this.once=a.before(this._lazyBind,this.once.bind(this)),this.complexPath&&this._lazyBind()}function o(t,e,r,n){if(arguments.length>5)throw Error("baobab.Cursor."+t+": too many arguments.");arguments.length<4&&(n=r,r=[]),r=r||[];var o=[].concat(r),i=a.solvePath(this.get(),o,this.tree);if(!i)throw Error("baobab.Cursor."+t+": could not solve dynamic path.");if(e){var s=this.get(i);if(!h[e](s))throw Error("baobab.Cursor."+t+": invalid target.")}var u={};u["$"+t]=n;var c=a.pathObject(i,u);return c}function i(t,e){n.prototype[t]=function(){var r=o.bind(this,t,e).apply(this,arguments);return this.update(r)}}var s=t("emmett"),a=t("./helpers.js"),h=(t("../defaults.js"),t("./type.js"));a.inherits(n,s),n.prototype.isRoot=function(){return!this.path.length},n.prototype.isLeaf=function(){return h.Primitive(this.get())},n.prototype.isBranch=function(){return!this.isLeaf()&&!this.isRoot()},n.prototype.root=function(){return this.tree.root()},n.prototype.select=function(t){if(arguments.length>1&&(t=a.arrayOf(arguments)),!h.Path(t))throw Error("baobab.Cursor.select: invalid path.");return this.tree.select(this.path.concat(t))},n.prototype.up=function(){return this.solvedPath&&this.solvedPath.length?this.tree.select(this.path.slice(0,-1)):null},n.prototype.left=function(){var t=+this.solvedPath[this.solvedPath.length-1];if(isNaN(t))throw Error("baobab.Cursor.left: cannot go left on a non-list type.");return t?this.tree.select(this.solvedPath.slice(0,-1).concat(t-1)):null},n.prototype.leftmost=function(){var t=+this.solvedPath[this.solvedPath.length-1];if(isNaN(t))throw Error("baobab.Cursor.leftmost: cannot go left on a non-list type.");return this.tree.select(this.solvedPath.slice(0,-1).concat(0))},n.prototype.right=function(){var t=+this.solvedPath[this.solvedPath.length-1];if(isNaN(t))throw Error("baobab.Cursor.right: cannot go right on a non-list type.");return t+1===this.up().get().length?null:this.tree.select(this.solvedPath.slice(0,-1).concat(t+1))},n.prototype.rightmost=function(){var t=+this.solvedPath[this.solvedPath.length-1];if(isNaN(t))throw Error("baobab.Cursor.right: cannot go right on a non-list type.");var e=this.up().get();return this.tree.select(this.solvedPath.slice(0,-1).concat(e.length-1))},n.prototype.down=function(){+this.solvedPath[this.solvedPath.length-1];return this.get()instanceof Array?this.tree.select(this.solvedPath.concat(0)):null},n.prototype.get=function(t){arguments.length>1&&(t=a.arrayOf(arguments));var e=this.solvedPath.concat([].concat(t||0===t?t:[]));return a.getIn(this.tree.data,e,this.tree)},i("set"),i("apply"),i("chain"),i("push","Array"),i("unshift","Array"),n.prototype.merge=function(t){if(!h.Object(t))throw Error("baobab.Cursor.merge: trying to merge a non-object.");var e=o.bind(this,"merge","Object").apply(this,arguments);return this.update(e)},n.prototype.unset=function(t){if(void 0===t&&this.isRoot())throw Error("baobab.Cursor.unset: cannot remove root node.");var e=o.bind(this,"unset",null).apply(this,[t,!0]);return this.update(e)},n.prototype.update=function(t,e){if(arguments.length<2)return this.tree.stack(a.pathObject(this.solvedPath,t)),this;var r=[].concat(t),n=a.solvePath(this.get(),r,this.tree);if(!n)throw Error("baobab.Cursor.update: could not solve dynamic path.");return this.tree.stack(a.pathObject(this.solvedPath.concat(n),e)),this},n.prototype.startRecording=function(t){if(t=t||5,1>t)throw Error("baobab.Cursor.startRecording: invalid maximum number of records.");return this.archive?this:(this._lazyBind(),this.archive=a.archive(t),this)},n.prototype.stopRecording=function(){return this.archive=null,this},n.prototype.undo=function(t){if(t=t||1,!this.isRecording())throw Error("baobab.Cursor.undo: cursor is not recording.");if(!h.PositiveInteger(t))throw Error("baobab.Cursor.undo: expecting a positive integer.");var e=this.archive.back(t);if(!e)throw Error("boabab.Cursor.undo: cannot find a relevant record ("+t+" back).");return this.undoing=!0,this.set(e)},n.prototype.isRecording=function(){return!!this.archive},n.prototype.hasHistory=function(){return!(!this.archive||!this.archive.get().length)},n.prototype.getHistory=function(){return this.archive?this.archive.get():[]},n.prototype.release=function(){this.tree.off("update",this.updateHandler),this.hash&&delete this.tree._cursors[this.hash],delete this.tree,delete this.path,delete this.solvedPath,delete this.archive,this.kill()},n.prototype.toJSON=function(){return this.get()},n.prototype.toString=function(){return this._identity},h.Cursor=function(t){return t instanceof n},e.exports=n},{"../defaults.js":2,"./helpers.js":7,"./type.js":9,emmett:3}],6:[function(t,e,r){function n(t){return t}function o(t,e){function r(t){o[t]=l[t].bind(l)}var o=this,s=null,a=!1,h=e.get||n,u=e.cursors,c=Object.keys(u).map(function(t){return u[t]}),l=new i(t,c);["on","once","release"].forEach(r),this.get=function(){if(a)return s;var e={};for(var r in u)e[r]=t.get(u[r]);return s=h.call(null,e),a=!0,s},this.on("update",function(){a=!1})}{var i=t("./watcher.js");t("./helpers.js")}e.exports=o},{"./helpers.js":7,"./watcher.js":11}],7:[function(t,e,r){(function(r){function n(t){return Array.prototype.slice.call(t)}function o(t,e){return function(){t(),e.apply(null,arguments)}}function i(t,e){var r,n={};for(r in t)n[r]=t[r];for(r in e)n[r]=e[r];return n}function s(t){var e=t.source,r="";return t.global&&(r+="g"),t.multiline&&(r+="m"),t.ignoreCase&&(r+="i"),t.sticky&&(r+="y"),t.unicode&&(r+="u"),new RegExp(e,r)}function a(t,e){if(!e||"object"!=typeof e||e instanceof Error||"ArrayBuffer"in r&&e instanceof ArrayBuffer)return e;if(w.Array(e)){if(t){var n,o,i=[];for(n=0,o=e.length;o>n;n++)i.push($(e[n]));return i}return e.slice(0)}if(w.Date(e))return new Date(e.getTime());if(e instanceof RegExp)return s(e);if(w.Object(e)){var a,h={};e.constructor&&e.constructor!==Object&&(h=Object.create(e.constructor.prototype));for(a in e)e.hasOwnProperty(a)&&(h[a]=t?$(e[a]):e[a]);return h}return e}function h(t,e){return function(r){return e(t(r))}}function u(t,e){var r,n;for(r=0,n=t.length;n>r;r++)if(e(t[r]))return t[r]}function c(t,e){var r,n;for(r=0,n=t.length;n>r;r++)if(e(t[r]))return r;return-1}function l(t,e){var r,n=!0;if(!t)return!1;for(r in e)if(w.Object(e[r]))n=n&&l(t[r],e[r]);else if(w.Array(e[r]))n=n&&!!~e[r].indexOf(t[r]);else if(t[r]!==e[r])return!1;return n}function f(t,e){return u(t,function(t){return l(t,e)})}function d(t,e){return c(t,function(t){return l(t,e)})}function y(t,e,r){e=e||[];var n,o,i,s=t;for(o=0,i=e.length;i>o;o++){if(!s)return;if("function"==typeof e[o]){if(!w.Array(s))return;s=u(s,e[o])}else if("object"==typeof e[o])if(r&&"$cursor"in e[o]){if(!w.Path(e[o].$cursor))throw Error("baobab.getIn: $cursor path must be an array.");n=r.get(e[o].$cursor),s=s[n]}else{if(!w.Array(s))return;s=f(s,e[o])}else s=s[e[o]]}return s}function g(t,e,r){var n,o,i,s=[],a=t;for(o=0,i=e.length;i>o;o++){if(!a)return null;if("function"==typeof e[o]){if(!w.Array(a))return;n=c(a,e[o]),s.push(n),a=a[n]}else if("object"==typeof e[o])if(r&&"$cursor"in e[o]){if(!w.Path(e[o].$cursor))throw Error("baobab.getIn: $cursor path must be an array.");p=r.get(e[o].$cursor),s.push(p),a=a[p]}else{if(!w.Array(a))return;n=d(a,e[o]),s.push(n),a=a[n]}else s.push(e[o]),a=a[e[o]]||{}}return s}function v(t,e){var r,n,o,i,s,a,h,u,c;for(r=0,i=e.length;i>r;r++)for(h=e[r],n=0,s=t.length;s>n;n++)for(u=t[n],o=0,a=u.length;a>o&&(c=u[o],c==h[o]);o++)if(o+1===a||o+1===h.length)return!0;return!1}function b(t,e){var r,n=t.length,o={},i=o;for(n||(o=e),r=0;n>r;r++)i[t[r]]=r+1===n?e:{},i=i[t[r]];return o}function m(t,e){t.super_=e;var r=function(){};r.prototype=e.prototype,t.prototype=new r,t.prototype.constructor=t}function j(t){var e=[];return{add:function(r){e.unshift(r),e.length>t&&(e.length=t)},back:function(t){var r=e[t-1];return r&&(e=e.slice(t)),r},get:function(){return e}}}var w=t("./type.js"),_=a.bind(null,!1),$=a.bind(null,!0);e.exports={archive:j,arrayOf:n,before:o,deepClone:$,shallowClone:_,shallowMerge:i,compose:h,getIn:y,inherits:m,pathObject:b,solvePath:g,solveUpdate:v}}).call(this,"undefined"!=typeof global?global:"undefined"!=typeof self?self:"undefined"!=typeof window?window:{})},{"./type.js":9}],8:[function(t,e,r){function n(t,e,r){a.forEach(function(e){r!==e&&delete t[e]}),t[r]=e[r]}function o(t,e){var r,h=i.shallowClone(e||{});a.forEach(function(e){t[e]&&n(h,t,e)}),t.$chain&&(a.slice(0,-1).forEach(function(t){delete h[t]}),h.$apply=h.$apply?i.compose(h.$apply,t.$chain):t.$chain),t.$push&&h.$push?h.$push=s.Array(h.$push)?h.$push.concat(t.$push):[h.$push].concat(t.$push):t.$push&&(h.$push=t.$push),t.$unshift&&h.$unshift?h.$unshift=s.Array(t.$unshift)?t.$unshift.concat(h.$unshift):[t.$unshift].concat(h.$unshift):t.$unshift&&(h.$unshift=t.$unshift);for(r in t)s.Object(t[r])?h[r]=o(t[r],h[r]):"$"!==r[0]&&(h[r]=t[r]);return h}var i=t("./helpers.js"),s=t("./type.js"),a=["$unset","$set","$merge","$apply"];e.exports=o},{"./helpers.js":7,"./type.js":9}],9:[function(t,e,r){function n(t,e){return e.some(function(e){return o[e](t)})}var o={};o.Array=function(t){return Array.isArray(t)},o.Object=function(t){return t&&"object"==typeof t&&!Array.isArray(t)&&!(t instanceof Function)},o.String=function(t){return"string"==typeof t},o.Number=function(t){return"number"==typeof t},o.PositiveInteger=function(t){return"number"==typeof t&&t>0&&t%1===0},o.Function=function(t){return"function"==typeof t},o.Primitive=function(t){return"string"==typeof t||"number"==typeof t||"boolean"==typeof t},o.Date=function(t){return t instanceof Date},o.NonScalar=function(t){return o.Object(t)||o.Array(t)},o.Path=function(t){var e=["String","Number","Function","Object"];return o.Array(t)?t.every(function(t){return n(t,e)}):n(t,e)},o.MixinCursor=function(t){return n(t,["String","Number","Array","Function","Cursor"])},o.MixinCursors=function(t){return n(t,["Object","Array","Function"])},o.ComplexPath=function(t){return t.some(function(t){return n(t,["Object","Function"])})},e.exports=o},{}],10:[function(t,e,r){function n(t,e){var r=new Error("baobab.update: "+e+" at path /"+t.slice(1).join("/"));return r.path=t,r}var o=t("./helpers.js"),i=t("./type.js");e.exports=function(t,e,r){if(r=r||{},!i.Object(t)&&!i.Array(t))throw Error("baobab.update: invalid target.");var s={};t={root:o.shallowClone(t)};var a=function(t,e,r,h){r=r||["root"];var u,c,l,f=r.join("|λ|"),p=r[r.length-1],d=Object.keys(e).some(function(t){return!!~["$unset","$set","$apply","$merge","$push","$unshift"].indexOf(t)});if(d){s[f]=!0;for(c in e){if("$unset"===c){var y=r[r.length-2];i.Array(t)?h[y]=t.slice(0,+p).concat(t.slice(+p+1)):(h[y]=o.shallowClone(t),delete h[y][p]);break}if("$set"===c){l=e.$set,t[p]=l;break}if("$apply"===c){if(u=e.$apply,"function"!=typeof u)throw n(r,"using command $apply with a non function");t[p]=u.call(null,t[p]);break}if("$merge"===c){if(l=e.$merge,!i.Object(t[p])||!i.Object(l))throw n(r,"using command $merge with a non object");t[p]=o.shallowMerge(t[p],l);break}if("$push"===c){if(l=e.$push,!i.Array(t[p]))throw n(r,"using command $push to a non array");t[p]=t[p].concat(l)}if("$unshift"===c){if(l=e.$unshift,!i.Array(t[p]))throw n(r,"using command $unshift to a non array");t[p]=[].concat(l).concat(t[p])}}}else for(c in e)t[p][c]="undefined"==typeof t[p][c]?{}:o.shallowClone(t[p][c]),a(t[p],e[c],r.concat(c),t)};return a(t,e),{data:t.root,log:Object.keys(s).map(function(t){return t.split("|λ|").slice(1)})}}},{"./helpers.js":7,"./type.js":9}],11:[function(t,e,r){function n(t,e){function r(){h&&(a=e.map(function(t){return i.solvePath(n.tree.data,t,n.tree)}))}var n=this;o.call(this),this.tree=t;var a=e,h=e.some(s.ComplexPath);this.updateHandler=function(t){var e=i.solveUpdate(t.data.log,a);e&&n.emit("update")},r(),this.tree.on("update",this.updateHandler)}var o=t("emmett"),i=t("./helpers.js"),s=t("./type.js");i.inherits(n,o),n.prototype.release=function(){this.tree.off("update",this.updateHandler),this.tree=null,this.kill()},e.exports=n},{"./helpers.js":7,"./type.js":9,emmett:3}]},{},[1])(1)}); \ No newline at end of file diff --git a/src/cursor.js b/src/cursor.js index 45f2291..a1f5c80 100644 --- a/src/cursor.js +++ b/src/cursor.js @@ -28,6 +28,9 @@ function Cursor(tree, path, solvedPath, hash) { this.archive = null; this.undoing = false; + // Privates + this._identity = '[object Cursor]'; + // Complex path? this.complexPath = !!solvedPath; this.solvedPath = this.complexPath ? solvedPath : this.path; @@ -379,6 +382,10 @@ Cursor.prototype.toJSON = function() { return this.get(); }; +Cursor.prototype.toString = function() { + return this._identity; +}; + type.Cursor = function (value) { return value instanceof Cursor; }; From e9f724977219291ed22688a6e20771e88a35044b Mon Sep 17 00:00:00 2001 From: Yomguithereal Date: Wed, 15 Apr 2015 15:38:55 +0200 Subject: [PATCH 53/73] Removing now useless type.Cursor --- src/cursor.js | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/cursor.js b/src/cursor.js index a1f5c80..ceda3b2 100644 --- a/src/cursor.js +++ b/src/cursor.js @@ -386,10 +386,6 @@ Cursor.prototype.toString = function() { return this._identity; }; -type.Cursor = function (value) { - return value instanceof Cursor; -}; - /** * Export */ From 8f909163860932e2d4e213cc0a868bd53c3ceccf Mon Sep 17 00:00:00 2001 From: Yomguithereal Date: Wed, 15 Apr 2015 15:43:34 +0200 Subject: [PATCH 54/73] Dropping now useless mixins option --- build/baobab.min.js | 2 +- defaults.js | 3 --- 2 files changed, 1 insertion(+), 4 deletions(-) diff --git a/build/baobab.min.js b/build/baobab.min.js index 18abf58..ee954ee 100644 --- a/build/baobab.min.js +++ b/build/baobab.min.js @@ -1,2 +1,2 @@ /* baobab.js - Version: 1.0.0-rc1 - Author: Yomguithereal (Guillaume Plique) */ -!function(t){if("object"==typeof exports&&"undefined"!=typeof module)module.exports=t();else if("function"==typeof define&&define.amd)define([],t);else{var e;e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:this,e.Baobab=t()}}(function(){var t;return function e(t,r,n){function o(s,a){if(!r[s]){if(!t[s]){var h="function"==typeof require&&require;if(!a&&h)return h(s,!0);if(i)return i(s,!0);var u=new Error("Cannot find module '"+s+"'");throw u.code="MODULE_NOT_FOUND",u}var c=r[s]={exports:{}};t[s][0].call(c.exports,function(e){var r=t[s][1][e];return o(r?r:e)},c,c.exports,e,t,r,n)}return r[s].exports}for(var i="function"==typeof require&&require,s=0;sn;n++)t[n].fn!==e&&o.push(t[n]);return o}var s={once:"boolean",scope:"object"},a=0,h=function(){this._enabled=!0,this.unbindAll()};h.prototype.unbindAll=function(){return this._handlers={},this._handlersAll=[],this._handlersComplex=[],this},h.prototype.on=function(t,e,r){var n,i,h,u,c,l,f;if(o(t)){for(u in t)this.on(u,t[u],e);return this}for("function"==typeof t&&(r=e,e=t,t=null),c=[].concat(t),n=0,i=c.length;i>n;n++){if(u=c[n],f={order:a++,fn:e},"string"==typeof u)this._handlers[u]||(this._handlers[u]=[]),l=this._handlers[u];else if(u instanceof RegExp)l=this._handlersComplex,f.pattern=u;else{if(null!==u)throw Error("Emitter.on: invalid event.");l=this._handlersAll}for(h in r||{})s[h]&&(f[h]=r[h]);f.once&&(f.parent=l),l.push(f)}return this},h.prototype.once=function(){var t=Array.prototype.slice.call(arguments),r=t.length-1;return o(t[r])&&t.length>1?t[r]=e(t[r],{once:!0}):t.push({once:!0}),this.on.apply(this,t)},h.prototype.off=function(t,e){var r,n,s,a;if(1===arguments.length&&"function"==typeof t){e=arguments[0];for(s in this._handlers)this._handlers[s]=i(this._handlers[s],e),0===this._handlers[s].length&&delete this._handlers[s];this._handlersAll=i(this._handlersAll,e),this._handlersComplex=i(this._handlersComplex,e)}else if(1===arguments.length&&"string"==typeof t)delete this._handlers[t];else if(2===arguments.length){var h=[].concat(t);for(r=0,n=h.length;n>r;r++)a=h[r],this._handlers[a]=i(this._handlers[a],e),0===(this._handlers[a]||[]).length&&delete this._handlers[a]}else if(o(t))for(s in t)this.off(s,t[s]);return this},h.prototype.listeners=function(t){var e,r,n,o=this._handlersAll||[],i=!1;if(!t)throw Error("Emitter.listeners: no event provided.");for(o=o.concat(this._handlers[t]||[]),r=0,n=this._handlersComplex.length;n>r;r++)e=this._handlersComplex[r],~t.search(e.pattern)&&(i=!0,o.push(e));return this._handlersAll.length||i?o.sort(function(t,e){return t.order-e.order}):o.slice(0)},h.prototype.emit=function(t,e){if(!this._enabled)return this;if(o(t)){for(var r in t)this.emit(r,t[r]);return this}var n,i,s,a,h,u,c,l=[].concat(t),f=[];for(a=0,u=l.length;u>a;a++){for(i=this.listeners(l[a]),h=0,c=i.length;c>h;h++)s=i[h],n={type:l[a],target:this},arguments.length>1&&(n.data=e),s.fn.call("scope"in s?s.scope:this,n),s.once&&f.push(s);for(h=f.length-1;h>=0;h--)f[h].parent.splice(f[h].parent.indexOf(f[h]),1)}return this},h.prototype.kill=function(){this.unbindAll(),this._handlers=null,this._handlersAll=null,this._handlersComplex=null,this._enabled=!1},h.prototype.disable=function(){return this._enabled=!1,this},h.prototype.enable=function(){return this._enabled=!0,this},h.version="3.0.0","undefined"!=typeof n?("undefined"!=typeof r&&r.exports&&(n=r.exports=h),n.Emitter=h):"function"==typeof t&&t.amd?t("emmett",[],function(){return h}):this.Emitter=h}).call(this)},{}],4:[function(t,e,r){function n(t){return t+"$"+(new Date).getTime()+(""+Math.random()).replace("0.","")}function o(t,e){function r(t){this[t]=function(){var e=this.root[t].apply(this.root,arguments);return e instanceof i?this:e}}if(arguments.length<1&&(t={}),!(this instanceof o))return new o(t,e);if(!p.Object(t)&&!p.Array(t))throw Error("Baobab: invalid data.");if(s.call(this),this.options=u.shallowMerge(f,e),this._transaction={},this._future=void 0,this._cursors={},this._identity="[object Baobab]",this.data=u.deepClone(t),this.root=this.select([]),this.facets={},["get","set","unset","update"].forEach(r.bind(this)),!p.Object(this.options.facets))throw Error("Baobab: invalid facets.");for(var n in this.options.facets)this.addFacet(n,this.options.facets[n])}var i=t("./cursor.js"),s=t("emmett"),a=t("./watcher.js"),h=t("./facet.js"),u=t("./helpers.js"),c=t("./update.js"),l=t("./merge.js"),f=t("../defaults.js"),p=t("./type.js");u.inherits(o,s),o.prototype.addFacet=function(t,e){return this.facets[t]=this.createFacet(e),this},o.prototype.createFacet=function(t){return new h(this,t)},o.prototype.select=function(t){if(!t)throw Error("Baobab.select: invalid path.");if(arguments.length>1&&(t=u.arrayOf(arguments)),!p.Path(t))throw Error("Baobab.select: invalid path.");t=[].concat(t);var e,r=p.ComplexPath(t);r&&(e=u.solvePath(this.data,t,this));var o=t.map(function(t){return p.Function(t)?n("fn"):p.Object(t)?n("ob"):t}).join("|λ|");if(this._cursors[o])return this._cursors[o];var s=new i(this,t,e,o);return this._cursors[o]=s,s},o.prototype.stack=function(t){var e=this;if(!p.Object(t))throw Error("Baobab.update: wrong specification.");return this._transaction=l(t,this._transaction),this.options.autoCommit?this.options.asynchronous?(this._future||(this._future=setTimeout(e.commit.bind(e,null),0)),this):this.commit():this},o.prototype.commit=function(){var t=c(this.data,this._transaction,this.options),e=this.data;return this.data=t.data,this._transaction={},this._future&&(this._future=clearTimeout(this._future)),this.emit("update",{log:t.log,previousState:e}),this},o.prototype.watch=function(t){if(!p.Array(t)||t.some(function(t){return!p.Path(t)}))throw Error("Baobab.watch: invalid paths.");return new a(this,[].concat(t))},o.prototype.release=function(){var t;delete this.data,delete this._transaction;for(t in this._cursors)this._cursors[t].release();delete this._cursors;for(t in this.facets)this.facets[t].release();delete this.facets,this.kill()},o.prototype.toJSON=function(){return this.get()},o.prototype.toString=function(){return this._identity},e.exports=o},{"../defaults.js":2,"./cursor.js":5,"./facet.js":6,"./helpers.js":7,"./merge.js":8,"./type.js":9,"./update.js":10,"./watcher.js":11,emmett:3}],5:[function(t,e,r){function n(t,e,r,n){function o(t){if(i.isRecording()&&!i.undoing){var e=a.getIn(t,i.solvedPath,i.tree),r=a.deepClone(e);i.archive.add(r)}return i.undoing=!1,i.emit("update")}var i=this;s.call(this),e=e||[],this.tree=t,this.path=e,this.hash=n,this.archive=null,this.undoing=!1,this._identity="[object Cursor]",this.complexPath=!!r,this.solvedPath=this.complexPath?r:this.path,this.relevant=void 0!==this.get(),this.updateHandler=function(t){var e=t.data.log,r=t.data.previousState,n=!1;if(i.complexPath&&(i.solvedPath=a.solvePath(i.tree.data,i.path,i.tree)),!i.path.length)return o(r);i.solvedPath&&(n=a.solveUpdate(e,[i.solvedPath]));var s=void 0!==i.get();i.relevant?s&&n?o(r):s||(i.emit("irrelevant"),i.relevant=!1):s&&n&&(i.emit("relevant"),o(r),i.relevant=!0)};var h=!1;this._lazyBind=function(){h||(h=!0,i.tree.on("update",i.updateHandler))},this.on=a.before(this._lazyBind,this.on.bind(this)),this.once=a.before(this._lazyBind,this.once.bind(this)),this.complexPath&&this._lazyBind()}function o(t,e,r,n){if(arguments.length>5)throw Error("baobab.Cursor."+t+": too many arguments.");arguments.length<4&&(n=r,r=[]),r=r||[];var o=[].concat(r),i=a.solvePath(this.get(),o,this.tree);if(!i)throw Error("baobab.Cursor."+t+": could not solve dynamic path.");if(e){var s=this.get(i);if(!h[e](s))throw Error("baobab.Cursor."+t+": invalid target.")}var u={};u["$"+t]=n;var c=a.pathObject(i,u);return c}function i(t,e){n.prototype[t]=function(){var r=o.bind(this,t,e).apply(this,arguments);return this.update(r)}}var s=t("emmett"),a=t("./helpers.js"),h=(t("../defaults.js"),t("./type.js"));a.inherits(n,s),n.prototype.isRoot=function(){return!this.path.length},n.prototype.isLeaf=function(){return h.Primitive(this.get())},n.prototype.isBranch=function(){return!this.isLeaf()&&!this.isRoot()},n.prototype.root=function(){return this.tree.root()},n.prototype.select=function(t){if(arguments.length>1&&(t=a.arrayOf(arguments)),!h.Path(t))throw Error("baobab.Cursor.select: invalid path.");return this.tree.select(this.path.concat(t))},n.prototype.up=function(){return this.solvedPath&&this.solvedPath.length?this.tree.select(this.path.slice(0,-1)):null},n.prototype.left=function(){var t=+this.solvedPath[this.solvedPath.length-1];if(isNaN(t))throw Error("baobab.Cursor.left: cannot go left on a non-list type.");return t?this.tree.select(this.solvedPath.slice(0,-1).concat(t-1)):null},n.prototype.leftmost=function(){var t=+this.solvedPath[this.solvedPath.length-1];if(isNaN(t))throw Error("baobab.Cursor.leftmost: cannot go left on a non-list type.");return this.tree.select(this.solvedPath.slice(0,-1).concat(0))},n.prototype.right=function(){var t=+this.solvedPath[this.solvedPath.length-1];if(isNaN(t))throw Error("baobab.Cursor.right: cannot go right on a non-list type.");return t+1===this.up().get().length?null:this.tree.select(this.solvedPath.slice(0,-1).concat(t+1))},n.prototype.rightmost=function(){var t=+this.solvedPath[this.solvedPath.length-1];if(isNaN(t))throw Error("baobab.Cursor.right: cannot go right on a non-list type.");var e=this.up().get();return this.tree.select(this.solvedPath.slice(0,-1).concat(e.length-1))},n.prototype.down=function(){+this.solvedPath[this.solvedPath.length-1];return this.get()instanceof Array?this.tree.select(this.solvedPath.concat(0)):null},n.prototype.get=function(t){arguments.length>1&&(t=a.arrayOf(arguments));var e=this.solvedPath.concat([].concat(t||0===t?t:[]));return a.getIn(this.tree.data,e,this.tree)},i("set"),i("apply"),i("chain"),i("push","Array"),i("unshift","Array"),n.prototype.merge=function(t){if(!h.Object(t))throw Error("baobab.Cursor.merge: trying to merge a non-object.");var e=o.bind(this,"merge","Object").apply(this,arguments);return this.update(e)},n.prototype.unset=function(t){if(void 0===t&&this.isRoot())throw Error("baobab.Cursor.unset: cannot remove root node.");var e=o.bind(this,"unset",null).apply(this,[t,!0]);return this.update(e)},n.prototype.update=function(t,e){if(arguments.length<2)return this.tree.stack(a.pathObject(this.solvedPath,t)),this;var r=[].concat(t),n=a.solvePath(this.get(),r,this.tree);if(!n)throw Error("baobab.Cursor.update: could not solve dynamic path.");return this.tree.stack(a.pathObject(this.solvedPath.concat(n),e)),this},n.prototype.startRecording=function(t){if(t=t||5,1>t)throw Error("baobab.Cursor.startRecording: invalid maximum number of records.");return this.archive?this:(this._lazyBind(),this.archive=a.archive(t),this)},n.prototype.stopRecording=function(){return this.archive=null,this},n.prototype.undo=function(t){if(t=t||1,!this.isRecording())throw Error("baobab.Cursor.undo: cursor is not recording.");if(!h.PositiveInteger(t))throw Error("baobab.Cursor.undo: expecting a positive integer.");var e=this.archive.back(t);if(!e)throw Error("boabab.Cursor.undo: cannot find a relevant record ("+t+" back).");return this.undoing=!0,this.set(e)},n.prototype.isRecording=function(){return!!this.archive},n.prototype.hasHistory=function(){return!(!this.archive||!this.archive.get().length)},n.prototype.getHistory=function(){return this.archive?this.archive.get():[]},n.prototype.release=function(){this.tree.off("update",this.updateHandler),this.hash&&delete this.tree._cursors[this.hash],delete this.tree,delete this.path,delete this.solvedPath,delete this.archive,this.kill()},n.prototype.toJSON=function(){return this.get()},n.prototype.toString=function(){return this._identity},h.Cursor=function(t){return t instanceof n},e.exports=n},{"../defaults.js":2,"./helpers.js":7,"./type.js":9,emmett:3}],6:[function(t,e,r){function n(t){return t}function o(t,e){function r(t){o[t]=l[t].bind(l)}var o=this,s=null,a=!1,h=e.get||n,u=e.cursors,c=Object.keys(u).map(function(t){return u[t]}),l=new i(t,c);["on","once","release"].forEach(r),this.get=function(){if(a)return s;var e={};for(var r in u)e[r]=t.get(u[r]);return s=h.call(null,e),a=!0,s},this.on("update",function(){a=!1})}{var i=t("./watcher.js");t("./helpers.js")}e.exports=o},{"./helpers.js":7,"./watcher.js":11}],7:[function(t,e,r){(function(r){function n(t){return Array.prototype.slice.call(t)}function o(t,e){return function(){t(),e.apply(null,arguments)}}function i(t,e){var r,n={};for(r in t)n[r]=t[r];for(r in e)n[r]=e[r];return n}function s(t){var e=t.source,r="";return t.global&&(r+="g"),t.multiline&&(r+="m"),t.ignoreCase&&(r+="i"),t.sticky&&(r+="y"),t.unicode&&(r+="u"),new RegExp(e,r)}function a(t,e){if(!e||"object"!=typeof e||e instanceof Error||"ArrayBuffer"in r&&e instanceof ArrayBuffer)return e;if(w.Array(e)){if(t){var n,o,i=[];for(n=0,o=e.length;o>n;n++)i.push($(e[n]));return i}return e.slice(0)}if(w.Date(e))return new Date(e.getTime());if(e instanceof RegExp)return s(e);if(w.Object(e)){var a,h={};e.constructor&&e.constructor!==Object&&(h=Object.create(e.constructor.prototype));for(a in e)e.hasOwnProperty(a)&&(h[a]=t?$(e[a]):e[a]);return h}return e}function h(t,e){return function(r){return e(t(r))}}function u(t,e){var r,n;for(r=0,n=t.length;n>r;r++)if(e(t[r]))return t[r]}function c(t,e){var r,n;for(r=0,n=t.length;n>r;r++)if(e(t[r]))return r;return-1}function l(t,e){var r,n=!0;if(!t)return!1;for(r in e)if(w.Object(e[r]))n=n&&l(t[r],e[r]);else if(w.Array(e[r]))n=n&&!!~e[r].indexOf(t[r]);else if(t[r]!==e[r])return!1;return n}function f(t,e){return u(t,function(t){return l(t,e)})}function d(t,e){return c(t,function(t){return l(t,e)})}function y(t,e,r){e=e||[];var n,o,i,s=t;for(o=0,i=e.length;i>o;o++){if(!s)return;if("function"==typeof e[o]){if(!w.Array(s))return;s=u(s,e[o])}else if("object"==typeof e[o])if(r&&"$cursor"in e[o]){if(!w.Path(e[o].$cursor))throw Error("baobab.getIn: $cursor path must be an array.");n=r.get(e[o].$cursor),s=s[n]}else{if(!w.Array(s))return;s=f(s,e[o])}else s=s[e[o]]}return s}function g(t,e,r){var n,o,i,s=[],a=t;for(o=0,i=e.length;i>o;o++){if(!a)return null;if("function"==typeof e[o]){if(!w.Array(a))return;n=c(a,e[o]),s.push(n),a=a[n]}else if("object"==typeof e[o])if(r&&"$cursor"in e[o]){if(!w.Path(e[o].$cursor))throw Error("baobab.getIn: $cursor path must be an array.");p=r.get(e[o].$cursor),s.push(p),a=a[p]}else{if(!w.Array(a))return;n=d(a,e[o]),s.push(n),a=a[n]}else s.push(e[o]),a=a[e[o]]||{}}return s}function v(t,e){var r,n,o,i,s,a,h,u,c;for(r=0,i=e.length;i>r;r++)for(h=e[r],n=0,s=t.length;s>n;n++)for(u=t[n],o=0,a=u.length;a>o&&(c=u[o],c==h[o]);o++)if(o+1===a||o+1===h.length)return!0;return!1}function b(t,e){var r,n=t.length,o={},i=o;for(n||(o=e),r=0;n>r;r++)i[t[r]]=r+1===n?e:{},i=i[t[r]];return o}function m(t,e){t.super_=e;var r=function(){};r.prototype=e.prototype,t.prototype=new r,t.prototype.constructor=t}function j(t){var e=[];return{add:function(r){e.unshift(r),e.length>t&&(e.length=t)},back:function(t){var r=e[t-1];return r&&(e=e.slice(t)),r},get:function(){return e}}}var w=t("./type.js"),_=a.bind(null,!1),$=a.bind(null,!0);e.exports={archive:j,arrayOf:n,before:o,deepClone:$,shallowClone:_,shallowMerge:i,compose:h,getIn:y,inherits:m,pathObject:b,solvePath:g,solveUpdate:v}}).call(this,"undefined"!=typeof global?global:"undefined"!=typeof self?self:"undefined"!=typeof window?window:{})},{"./type.js":9}],8:[function(t,e,r){function n(t,e,r){a.forEach(function(e){r!==e&&delete t[e]}),t[r]=e[r]}function o(t,e){var r,h=i.shallowClone(e||{});a.forEach(function(e){t[e]&&n(h,t,e)}),t.$chain&&(a.slice(0,-1).forEach(function(t){delete h[t]}),h.$apply=h.$apply?i.compose(h.$apply,t.$chain):t.$chain),t.$push&&h.$push?h.$push=s.Array(h.$push)?h.$push.concat(t.$push):[h.$push].concat(t.$push):t.$push&&(h.$push=t.$push),t.$unshift&&h.$unshift?h.$unshift=s.Array(t.$unshift)?t.$unshift.concat(h.$unshift):[t.$unshift].concat(h.$unshift):t.$unshift&&(h.$unshift=t.$unshift);for(r in t)s.Object(t[r])?h[r]=o(t[r],h[r]):"$"!==r[0]&&(h[r]=t[r]);return h}var i=t("./helpers.js"),s=t("./type.js"),a=["$unset","$set","$merge","$apply"];e.exports=o},{"./helpers.js":7,"./type.js":9}],9:[function(t,e,r){function n(t,e){return e.some(function(e){return o[e](t)})}var o={};o.Array=function(t){return Array.isArray(t)},o.Object=function(t){return t&&"object"==typeof t&&!Array.isArray(t)&&!(t instanceof Function)},o.String=function(t){return"string"==typeof t},o.Number=function(t){return"number"==typeof t},o.PositiveInteger=function(t){return"number"==typeof t&&t>0&&t%1===0},o.Function=function(t){return"function"==typeof t},o.Primitive=function(t){return"string"==typeof t||"number"==typeof t||"boolean"==typeof t},o.Date=function(t){return t instanceof Date},o.NonScalar=function(t){return o.Object(t)||o.Array(t)},o.Path=function(t){var e=["String","Number","Function","Object"];return o.Array(t)?t.every(function(t){return n(t,e)}):n(t,e)},o.MixinCursor=function(t){return n(t,["String","Number","Array","Function","Cursor"])},o.MixinCursors=function(t){return n(t,["Object","Array","Function"])},o.ComplexPath=function(t){return t.some(function(t){return n(t,["Object","Function"])})},e.exports=o},{}],10:[function(t,e,r){function n(t,e){var r=new Error("baobab.update: "+e+" at path /"+t.slice(1).join("/"));return r.path=t,r}var o=t("./helpers.js"),i=t("./type.js");e.exports=function(t,e,r){if(r=r||{},!i.Object(t)&&!i.Array(t))throw Error("baobab.update: invalid target.");var s={};t={root:o.shallowClone(t)};var a=function(t,e,r,h){r=r||["root"];var u,c,l,f=r.join("|λ|"),p=r[r.length-1],d=Object.keys(e).some(function(t){return!!~["$unset","$set","$apply","$merge","$push","$unshift"].indexOf(t)});if(d){s[f]=!0;for(c in e){if("$unset"===c){var y=r[r.length-2];i.Array(t)?h[y]=t.slice(0,+p).concat(t.slice(+p+1)):(h[y]=o.shallowClone(t),delete h[y][p]);break}if("$set"===c){l=e.$set,t[p]=l;break}if("$apply"===c){if(u=e.$apply,"function"!=typeof u)throw n(r,"using command $apply with a non function");t[p]=u.call(null,t[p]);break}if("$merge"===c){if(l=e.$merge,!i.Object(t[p])||!i.Object(l))throw n(r,"using command $merge with a non object");t[p]=o.shallowMerge(t[p],l);break}if("$push"===c){if(l=e.$push,!i.Array(t[p]))throw n(r,"using command $push to a non array");t[p]=t[p].concat(l)}if("$unshift"===c){if(l=e.$unshift,!i.Array(t[p]))throw n(r,"using command $unshift to a non array");t[p]=[].concat(l).concat(t[p])}}}else for(c in e)t[p][c]="undefined"==typeof t[p][c]?{}:o.shallowClone(t[p][c]),a(t[p],e[c],r.concat(c),t)};return a(t,e),{data:t.root,log:Object.keys(s).map(function(t){return t.split("|λ|").slice(1)})}}},{"./helpers.js":7,"./type.js":9}],11:[function(t,e,r){function n(t,e){function r(){h&&(a=e.map(function(t){return i.solvePath(n.tree.data,t,n.tree)}))}var n=this;o.call(this),this.tree=t;var a=e,h=e.some(s.ComplexPath);this.updateHandler=function(t){var e=i.solveUpdate(t.data.log,a);e&&n.emit("update")},r(),this.tree.on("update",this.updateHandler)}var o=t("emmett"),i=t("./helpers.js"),s=t("./type.js");i.inherits(n,o),n.prototype.release=function(){this.tree.off("update",this.updateHandler),this.tree=null,this.kill()},e.exports=n},{"./helpers.js":7,"./type.js":9,emmett:3}]},{},[1])(1)}); \ No newline at end of file +!function(t){if("object"==typeof exports&&"undefined"!=typeof module)module.exports=t();else if("function"==typeof define&&define.amd)define([],t);else{var e;e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:this,e.Baobab=t()}}(function(){var t;return function e(t,r,n){function o(s,a){if(!r[s]){if(!t[s]){var h="function"==typeof require&&require;if(!a&&h)return h(s,!0);if(i)return i(s,!0);var u=new Error("Cannot find module '"+s+"'");throw u.code="MODULE_NOT_FOUND",u}var c=r[s]={exports:{}};t[s][0].call(c.exports,function(e){var r=t[s][1][e];return o(r?r:e)},c,c.exports,e,t,r,n)}return r[s].exports}for(var i="function"==typeof require&&require,s=0;sn;n++)t[n].fn!==e&&o.push(t[n]);return o}var s={once:"boolean",scope:"object"},a=0,h=function(){this._enabled=!0,this.unbindAll()};h.prototype.unbindAll=function(){return this._handlers={},this._handlersAll=[],this._handlersComplex=[],this},h.prototype.on=function(t,e,r){var n,i,h,u,c,l,f;if(o(t)){for(u in t)this.on(u,t[u],e);return this}for("function"==typeof t&&(r=e,e=t,t=null),c=[].concat(t),n=0,i=c.length;i>n;n++){if(u=c[n],f={order:a++,fn:e},"string"==typeof u)this._handlers[u]||(this._handlers[u]=[]),l=this._handlers[u];else if(u instanceof RegExp)l=this._handlersComplex,f.pattern=u;else{if(null!==u)throw Error("Emitter.on: invalid event.");l=this._handlersAll}for(h in r||{})s[h]&&(f[h]=r[h]);f.once&&(f.parent=l),l.push(f)}return this},h.prototype.once=function(){var t=Array.prototype.slice.call(arguments),r=t.length-1;return o(t[r])&&t.length>1?t[r]=e(t[r],{once:!0}):t.push({once:!0}),this.on.apply(this,t)},h.prototype.off=function(t,e){var r,n,s,a;if(1===arguments.length&&"function"==typeof t){e=arguments[0];for(s in this._handlers)this._handlers[s]=i(this._handlers[s],e),0===this._handlers[s].length&&delete this._handlers[s];this._handlersAll=i(this._handlersAll,e),this._handlersComplex=i(this._handlersComplex,e)}else if(1===arguments.length&&"string"==typeof t)delete this._handlers[t];else if(2===arguments.length){var h=[].concat(t);for(r=0,n=h.length;n>r;r++)a=h[r],this._handlers[a]=i(this._handlers[a],e),0===(this._handlers[a]||[]).length&&delete this._handlers[a]}else if(o(t))for(s in t)this.off(s,t[s]);return this},h.prototype.listeners=function(t){var e,r,n,o=this._handlersAll||[],i=!1;if(!t)throw Error("Emitter.listeners: no event provided.");for(o=o.concat(this._handlers[t]||[]),r=0,n=this._handlersComplex.length;n>r;r++)e=this._handlersComplex[r],~t.search(e.pattern)&&(i=!0,o.push(e));return this._handlersAll.length||i?o.sort(function(t,e){return t.order-e.order}):o.slice(0)},h.prototype.emit=function(t,e){if(!this._enabled)return this;if(o(t)){for(var r in t)this.emit(r,t[r]);return this}var n,i,s,a,h,u,c,l=[].concat(t),f=[];for(a=0,u=l.length;u>a;a++){for(i=this.listeners(l[a]),h=0,c=i.length;c>h;h++)s=i[h],n={type:l[a],target:this},arguments.length>1&&(n.data=e),s.fn.call("scope"in s?s.scope:this,n),s.once&&f.push(s);for(h=f.length-1;h>=0;h--)f[h].parent.splice(f[h].parent.indexOf(f[h]),1)}return this},h.prototype.kill=function(){this.unbindAll(),this._handlers=null,this._handlersAll=null,this._handlersComplex=null,this._enabled=!1},h.prototype.disable=function(){return this._enabled=!1,this},h.prototype.enable=function(){return this._enabled=!0,this},h.version="3.0.0","undefined"!=typeof n?("undefined"!=typeof r&&r.exports&&(n=r.exports=h),n.Emitter=h):"function"==typeof t&&t.amd?t("emmett",[],function(){return h}):this.Emitter=h}).call(this)},{}],4:[function(t,e,r){function n(t){return t+"$"+(new Date).getTime()+(""+Math.random()).replace("0.","")}function o(t,e){function r(t){this[t]=function(){var e=this.root[t].apply(this.root,arguments);return e instanceof i?this:e}}if(arguments.length<1&&(t={}),!(this instanceof o))return new o(t,e);if(!p.Object(t)&&!p.Array(t))throw Error("Baobab: invalid data.");if(s.call(this),this.options=u.shallowMerge(f,e),this._transaction={},this._future=void 0,this._cursors={},this._identity="[object Baobab]",this.data=u.deepClone(t),this.root=this.select([]),this.facets={},["get","set","unset","update"].forEach(r.bind(this)),!p.Object(this.options.facets))throw Error("Baobab: invalid facets.");for(var n in this.options.facets)this.addFacet(n,this.options.facets[n])}var i=t("./cursor.js"),s=t("emmett"),a=t("./watcher.js"),h=t("./facet.js"),u=t("./helpers.js"),c=t("./update.js"),l=t("./merge.js"),f=t("../defaults.js"),p=t("./type.js");u.inherits(o,s),o.prototype.addFacet=function(t,e){return this.facets[t]=this.createFacet(e),this},o.prototype.createFacet=function(t){return new h(this,t)},o.prototype.select=function(t){if(!t)throw Error("Baobab.select: invalid path.");if(arguments.length>1&&(t=u.arrayOf(arguments)),!p.Path(t))throw Error("Baobab.select: invalid path.");t=[].concat(t);var e,r=p.ComplexPath(t);r&&(e=u.solvePath(this.data,t,this));var o=t.map(function(t){return p.Function(t)?n("fn"):p.Object(t)?n("ob"):t}).join("|λ|");if(this._cursors[o])return this._cursors[o];var s=new i(this,t,e,o);return this._cursors[o]=s,s},o.prototype.stack=function(t){var e=this;if(!p.Object(t))throw Error("Baobab.update: wrong specification.");return this._transaction=l(t,this._transaction),this.options.autoCommit?this.options.asynchronous?(this._future||(this._future=setTimeout(e.commit.bind(e,null),0)),this):this.commit():this},o.prototype.commit=function(){var t=c(this.data,this._transaction,this.options),e=this.data;return this.data=t.data,this._transaction={},this._future&&(this._future=clearTimeout(this._future)),this.emit("update",{log:t.log,previousState:e}),this},o.prototype.watch=function(t){if(!p.Array(t)||t.some(function(t){return!p.Path(t)}))throw Error("Baobab.watch: invalid paths.");return new a(this,[].concat(t))},o.prototype.release=function(){var t;delete this.data,delete this._transaction;for(t in this._cursors)this._cursors[t].release();delete this._cursors;for(t in this.facets)this.facets[t].release();delete this.facets,this.kill()},o.prototype.toJSON=function(){return this.get()},o.prototype.toString=function(){return this._identity},e.exports=o},{"../defaults.js":2,"./cursor.js":5,"./facet.js":6,"./helpers.js":7,"./merge.js":8,"./type.js":9,"./update.js":10,"./watcher.js":11,emmett:3}],5:[function(t,e,r){function n(t,e,r,n){function o(t){if(i.isRecording()&&!i.undoing){var e=a.getIn(t,i.solvedPath,i.tree),r=a.deepClone(e);i.archive.add(r)}return i.undoing=!1,i.emit("update")}var i=this;s.call(this),e=e||[],this.tree=t,this.path=e,this.hash=n,this.archive=null,this.undoing=!1,this._identity="[object Cursor]",this.complexPath=!!r,this.solvedPath=this.complexPath?r:this.path,this.relevant=void 0!==this.get(),this.updateHandler=function(t){var e=t.data.log,r=t.data.previousState,n=!1;if(i.complexPath&&(i.solvedPath=a.solvePath(i.tree.data,i.path,i.tree)),!i.path.length)return o(r);i.solvedPath&&(n=a.solveUpdate(e,[i.solvedPath]));var s=void 0!==i.get();i.relevant?s&&n?o(r):s||(i.emit("irrelevant"),i.relevant=!1):s&&n&&(i.emit("relevant"),o(r),i.relevant=!0)};var h=!1;this._lazyBind=function(){h||(h=!0,i.tree.on("update",i.updateHandler))},this.on=a.before(this._lazyBind,this.on.bind(this)),this.once=a.before(this._lazyBind,this.once.bind(this)),this.complexPath&&this._lazyBind()}function o(t,e,r,n){if(arguments.length>5)throw Error("baobab.Cursor."+t+": too many arguments.");arguments.length<4&&(n=r,r=[]),r=r||[];var o=[].concat(r),i=a.solvePath(this.get(),o,this.tree);if(!i)throw Error("baobab.Cursor."+t+": could not solve dynamic path.");if(e){var s=this.get(i);if(!h[e](s))throw Error("baobab.Cursor."+t+": invalid target.")}var u={};u["$"+t]=n;var c=a.pathObject(i,u);return c}function i(t,e){n.prototype[t]=function(){var r=o.bind(this,t,e).apply(this,arguments);return this.update(r)}}var s=t("emmett"),a=t("./helpers.js"),h=(t("../defaults.js"),t("./type.js"));a.inherits(n,s),n.prototype.isRoot=function(){return!this.path.length},n.prototype.isLeaf=function(){return h.Primitive(this.get())},n.prototype.isBranch=function(){return!this.isLeaf()&&!this.isRoot()},n.prototype.root=function(){return this.tree.root()},n.prototype.select=function(t){if(arguments.length>1&&(t=a.arrayOf(arguments)),!h.Path(t))throw Error("baobab.Cursor.select: invalid path.");return this.tree.select(this.path.concat(t))},n.prototype.up=function(){return this.solvedPath&&this.solvedPath.length?this.tree.select(this.path.slice(0,-1)):null},n.prototype.left=function(){var t=+this.solvedPath[this.solvedPath.length-1];if(isNaN(t))throw Error("baobab.Cursor.left: cannot go left on a non-list type.");return t?this.tree.select(this.solvedPath.slice(0,-1).concat(t-1)):null},n.prototype.leftmost=function(){var t=+this.solvedPath[this.solvedPath.length-1];if(isNaN(t))throw Error("baobab.Cursor.leftmost: cannot go left on a non-list type.");return this.tree.select(this.solvedPath.slice(0,-1).concat(0))},n.prototype.right=function(){var t=+this.solvedPath[this.solvedPath.length-1];if(isNaN(t))throw Error("baobab.Cursor.right: cannot go right on a non-list type.");return t+1===this.up().get().length?null:this.tree.select(this.solvedPath.slice(0,-1).concat(t+1))},n.prototype.rightmost=function(){var t=+this.solvedPath[this.solvedPath.length-1];if(isNaN(t))throw Error("baobab.Cursor.right: cannot go right on a non-list type.");var e=this.up().get();return this.tree.select(this.solvedPath.slice(0,-1).concat(e.length-1))},n.prototype.down=function(){+this.solvedPath[this.solvedPath.length-1];return this.get()instanceof Array?this.tree.select(this.solvedPath.concat(0)):null},n.prototype.get=function(t){arguments.length>1&&(t=a.arrayOf(arguments));var e=this.solvedPath.concat([].concat(t||0===t?t:[]));return a.getIn(this.tree.data,e,this.tree)},i("set"),i("apply"),i("chain"),i("push","Array"),i("unshift","Array"),n.prototype.merge=function(t){if(!h.Object(t))throw Error("baobab.Cursor.merge: trying to merge a non-object.");var e=o.bind(this,"merge","Object").apply(this,arguments);return this.update(e)},n.prototype.unset=function(t){if(void 0===t&&this.isRoot())throw Error("baobab.Cursor.unset: cannot remove root node.");var e=o.bind(this,"unset",null).apply(this,[t,!0]);return this.update(e)},n.prototype.update=function(t,e){if(arguments.length<2)return this.tree.stack(a.pathObject(this.solvedPath,t)),this;var r=[].concat(t),n=a.solvePath(this.get(),r,this.tree);if(!n)throw Error("baobab.Cursor.update: could not solve dynamic path.");return this.tree.stack(a.pathObject(this.solvedPath.concat(n),e)),this},n.prototype.startRecording=function(t){if(t=t||5,1>t)throw Error("baobab.Cursor.startRecording: invalid maximum number of records.");return this.archive?this:(this._lazyBind(),this.archive=a.archive(t),this)},n.prototype.stopRecording=function(){return this.archive=null,this},n.prototype.undo=function(t){if(t=t||1,!this.isRecording())throw Error("baobab.Cursor.undo: cursor is not recording.");if(!h.PositiveInteger(t))throw Error("baobab.Cursor.undo: expecting a positive integer.");var e=this.archive.back(t);if(!e)throw Error("boabab.Cursor.undo: cannot find a relevant record ("+t+" back).");return this.undoing=!0,this.set(e)},n.prototype.isRecording=function(){return!!this.archive},n.prototype.hasHistory=function(){return!(!this.archive||!this.archive.get().length)},n.prototype.getHistory=function(){return this.archive?this.archive.get():[]},n.prototype.release=function(){this.tree.off("update",this.updateHandler),this.hash&&delete this.tree._cursors[this.hash],delete this.tree,delete this.path,delete this.solvedPath,delete this.archive,this.kill()},n.prototype.toJSON=function(){return this.get()},n.prototype.toString=function(){return this._identity},e.exports=n},{"../defaults.js":2,"./helpers.js":7,"./type.js":9,emmett:3}],6:[function(t,e,r){function n(t){return t}function o(t,e){function r(t){o[t]=l[t].bind(l)}var o=this,s=null,a=!1,h=e.get||n,u=e.cursors,c=Object.keys(u).map(function(t){return u[t]}),l=new i(t,c);["on","once","release"].forEach(r),this.get=function(){if(a)return s;var e={};for(var r in u)e[r]=t.get(u[r]);return s=h.call(null,e),a=!0,s},this.on("update",function(){a=!1})}{var i=t("./watcher.js");t("./helpers.js")}e.exports=o},{"./helpers.js":7,"./watcher.js":11}],7:[function(t,e,r){(function(r){function n(t){return Array.prototype.slice.call(t)}function o(t,e){return function(){t(),e.apply(null,arguments)}}function i(t,e){var r,n={};for(r in t)n[r]=t[r];for(r in e)n[r]=e[r];return n}function s(t){var e=t.source,r="";return t.global&&(r+="g"),t.multiline&&(r+="m"),t.ignoreCase&&(r+="i"),t.sticky&&(r+="y"),t.unicode&&(r+="u"),new RegExp(e,r)}function a(t,e){if(!e||"object"!=typeof e||e instanceof Error||"ArrayBuffer"in r&&e instanceof ArrayBuffer)return e;if(w.Array(e)){if(t){var n,o,i=[];for(n=0,o=e.length;o>n;n++)i.push($(e[n]));return i}return e.slice(0)}if(w.Date(e))return new Date(e.getTime());if(e instanceof RegExp)return s(e);if(w.Object(e)){var a,h={};e.constructor&&e.constructor!==Object&&(h=Object.create(e.constructor.prototype));for(a in e)e.hasOwnProperty(a)&&(h[a]=t?$(e[a]):e[a]);return h}return e}function h(t,e){return function(r){return e(t(r))}}function u(t,e){var r,n;for(r=0,n=t.length;n>r;r++)if(e(t[r]))return t[r]}function c(t,e){var r,n;for(r=0,n=t.length;n>r;r++)if(e(t[r]))return r;return-1}function l(t,e){var r,n=!0;if(!t)return!1;for(r in e)if(w.Object(e[r]))n=n&&l(t[r],e[r]);else if(w.Array(e[r]))n=n&&!!~e[r].indexOf(t[r]);else if(t[r]!==e[r])return!1;return n}function f(t,e){return u(t,function(t){return l(t,e)})}function d(t,e){return c(t,function(t){return l(t,e)})}function y(t,e,r){e=e||[];var n,o,i,s=t;for(o=0,i=e.length;i>o;o++){if(!s)return;if("function"==typeof e[o]){if(!w.Array(s))return;s=u(s,e[o])}else if("object"==typeof e[o])if(r&&"$cursor"in e[o]){if(!w.Path(e[o].$cursor))throw Error("baobab.getIn: $cursor path must be an array.");n=r.get(e[o].$cursor),s=s[n]}else{if(!w.Array(s))return;s=f(s,e[o])}else s=s[e[o]]}return s}function g(t,e,r){var n,o,i,s=[],a=t;for(o=0,i=e.length;i>o;o++){if(!a)return null;if("function"==typeof e[o]){if(!w.Array(a))return;n=c(a,e[o]),s.push(n),a=a[n]}else if("object"==typeof e[o])if(r&&"$cursor"in e[o]){if(!w.Path(e[o].$cursor))throw Error("baobab.getIn: $cursor path must be an array.");p=r.get(e[o].$cursor),s.push(p),a=a[p]}else{if(!w.Array(a))return;n=d(a,e[o]),s.push(n),a=a[n]}else s.push(e[o]),a=a[e[o]]||{}}return s}function v(t,e){var r,n,o,i,s,a,h,u,c;for(r=0,i=e.length;i>r;r++)for(h=e[r],n=0,s=t.length;s>n;n++)for(u=t[n],o=0,a=u.length;a>o&&(c=u[o],c==h[o]);o++)if(o+1===a||o+1===h.length)return!0;return!1}function b(t,e){var r,n=t.length,o={},i=o;for(n||(o=e),r=0;n>r;r++)i[t[r]]=r+1===n?e:{},i=i[t[r]];return o}function m(t,e){t.super_=e;var r=function(){};r.prototype=e.prototype,t.prototype=new r,t.prototype.constructor=t}function j(t){var e=[];return{add:function(r){e.unshift(r),e.length>t&&(e.length=t)},back:function(t){var r=e[t-1];return r&&(e=e.slice(t)),r},get:function(){return e}}}var w=t("./type.js"),_=a.bind(null,!1),$=a.bind(null,!0);e.exports={archive:j,arrayOf:n,before:o,deepClone:$,shallowClone:_,shallowMerge:i,compose:h,getIn:y,inherits:m,pathObject:b,solvePath:g,solveUpdate:v}}).call(this,"undefined"!=typeof global?global:"undefined"!=typeof self?self:"undefined"!=typeof window?window:{})},{"./type.js":9}],8:[function(t,e,r){function n(t,e,r){a.forEach(function(e){r!==e&&delete t[e]}),t[r]=e[r]}function o(t,e){var r,h=i.shallowClone(e||{});a.forEach(function(e){t[e]&&n(h,t,e)}),t.$chain&&(a.slice(0,-1).forEach(function(t){delete h[t]}),h.$apply=h.$apply?i.compose(h.$apply,t.$chain):t.$chain),t.$push&&h.$push?h.$push=s.Array(h.$push)?h.$push.concat(t.$push):[h.$push].concat(t.$push):t.$push&&(h.$push=t.$push),t.$unshift&&h.$unshift?h.$unshift=s.Array(t.$unshift)?t.$unshift.concat(h.$unshift):[t.$unshift].concat(h.$unshift):t.$unshift&&(h.$unshift=t.$unshift);for(r in t)s.Object(t[r])?h[r]=o(t[r],h[r]):"$"!==r[0]&&(h[r]=t[r]);return h}var i=t("./helpers.js"),s=t("./type.js"),a=["$unset","$set","$merge","$apply"];e.exports=o},{"./helpers.js":7,"./type.js":9}],9:[function(t,e,r){function n(t,e){return e.some(function(e){return o[e](t)})}var o={};o.Array=function(t){return Array.isArray(t)},o.Object=function(t){return t&&"object"==typeof t&&!Array.isArray(t)&&!(t instanceof Function)},o.String=function(t){return"string"==typeof t},o.Number=function(t){return"number"==typeof t},o.PositiveInteger=function(t){return"number"==typeof t&&t>0&&t%1===0},o.Function=function(t){return"function"==typeof t},o.Primitive=function(t){return"string"==typeof t||"number"==typeof t||"boolean"==typeof t},o.Date=function(t){return t instanceof Date},o.NonScalar=function(t){return o.Object(t)||o.Array(t)},o.Path=function(t){var e=["String","Number","Function","Object"];return o.Array(t)?t.every(function(t){return n(t,e)}):n(t,e)},o.MixinCursor=function(t){return n(t,["String","Number","Array","Function","Cursor"])},o.MixinCursors=function(t){return n(t,["Object","Array","Function"])},o.ComplexPath=function(t){return t.some(function(t){return n(t,["Object","Function"])})},e.exports=o},{}],10:[function(t,e,r){function n(t,e){var r=new Error("baobab.update: "+e+" at path /"+t.slice(1).join("/"));return r.path=t,r}var o=t("./helpers.js"),i=t("./type.js");e.exports=function(t,e,r){if(r=r||{},!i.Object(t)&&!i.Array(t))throw Error("baobab.update: invalid target.");var s={};t={root:o.shallowClone(t)};var a=function(t,e,r,h){r=r||["root"];var u,c,l,f=r.join("|λ|"),p=r[r.length-1],d=Object.keys(e).some(function(t){return!!~["$unset","$set","$apply","$merge","$push","$unshift"].indexOf(t)});if(d){s[f]=!0;for(c in e){if("$unset"===c){var y=r[r.length-2];i.Array(t)?h[y]=t.slice(0,+p).concat(t.slice(+p+1)):(h[y]=o.shallowClone(t),delete h[y][p]);break}if("$set"===c){l=e.$set,t[p]=l;break}if("$apply"===c){if(u=e.$apply,"function"!=typeof u)throw n(r,"using command $apply with a non function");t[p]=u.call(null,t[p]);break}if("$merge"===c){if(l=e.$merge,!i.Object(t[p])||!i.Object(l))throw n(r,"using command $merge with a non object");t[p]=o.shallowMerge(t[p],l);break}if("$push"===c){if(l=e.$push,!i.Array(t[p]))throw n(r,"using command $push to a non array");t[p]=t[p].concat(l)}if("$unshift"===c){if(l=e.$unshift,!i.Array(t[p]))throw n(r,"using command $unshift to a non array");t[p]=[].concat(l).concat(t[p])}}}else for(c in e)t[p][c]="undefined"==typeof t[p][c]?{}:o.shallowClone(t[p][c]),a(t[p],e[c],r.concat(c),t)};return a(t,e),{data:t.root,log:Object.keys(s).map(function(t){return t.split("|λ|").slice(1)})}}},{"./helpers.js":7,"./type.js":9}],11:[function(t,e,r){function n(t,e){function r(){h&&(a=e.map(function(t){return i.solvePath(n.tree.data,t,n.tree)}))}var n=this;o.call(this),this.tree=t;var a=e,h=e.some(s.ComplexPath);this.updateHandler=function(t){var e=i.solveUpdate(t.data.log,a);e&&n.emit("update")},r(),this.tree.on("update",this.updateHandler)}var o=t("emmett"),i=t("./helpers.js"),s=t("./type.js");i.inherits(n,o),n.prototype.release=function(){this.tree.off("update",this.updateHandler),this.tree=null,this.kill()},e.exports=n},{"./helpers.js":7,"./type.js":9,emmett:3}]},{},[1])(1)}); \ No newline at end of file diff --git a/defaults.js b/defaults.js index 5ec615e..184a972 100644 --- a/defaults.js +++ b/defaults.js @@ -14,9 +14,6 @@ module.exports = { // Facets registration facets: {}, - // Collection of react mixins to merge with the tree's ones - mixins: [], - // Validation specifications validate: null }; From 98c04d1b5c43228081013b14c7cd57b1eb238fb4 Mon Sep 17 00:00:00 2001 From: Yomguithereal Date: Wed, 15 Apr 2015 16:13:18 +0200 Subject: [PATCH 55/73] Related to #56 - validation utilities --- build/baobab.min.js | 2 +- defaults.js | 5 +++- src/baobab.js | 19 +++++++++++++- test/suites/baobab.js | 60 +++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 83 insertions(+), 3 deletions(-) diff --git a/build/baobab.min.js b/build/baobab.min.js index ee954ee..855bbb4 100644 --- a/build/baobab.min.js +++ b/build/baobab.min.js @@ -1,2 +1,2 @@ /* baobab.js - Version: 1.0.0-rc1 - Author: Yomguithereal (Guillaume Plique) */ -!function(t){if("object"==typeof exports&&"undefined"!=typeof module)module.exports=t();else if("function"==typeof define&&define.amd)define([],t);else{var e;e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:this,e.Baobab=t()}}(function(){var t;return function e(t,r,n){function o(s,a){if(!r[s]){if(!t[s]){var h="function"==typeof require&&require;if(!a&&h)return h(s,!0);if(i)return i(s,!0);var u=new Error("Cannot find module '"+s+"'");throw u.code="MODULE_NOT_FOUND",u}var c=r[s]={exports:{}};t[s][0].call(c.exports,function(e){var r=t[s][1][e];return o(r?r:e)},c,c.exports,e,t,r,n)}return r[s].exports}for(var i="function"==typeof require&&require,s=0;sn;n++)t[n].fn!==e&&o.push(t[n]);return o}var s={once:"boolean",scope:"object"},a=0,h=function(){this._enabled=!0,this.unbindAll()};h.prototype.unbindAll=function(){return this._handlers={},this._handlersAll=[],this._handlersComplex=[],this},h.prototype.on=function(t,e,r){var n,i,h,u,c,l,f;if(o(t)){for(u in t)this.on(u,t[u],e);return this}for("function"==typeof t&&(r=e,e=t,t=null),c=[].concat(t),n=0,i=c.length;i>n;n++){if(u=c[n],f={order:a++,fn:e},"string"==typeof u)this._handlers[u]||(this._handlers[u]=[]),l=this._handlers[u];else if(u instanceof RegExp)l=this._handlersComplex,f.pattern=u;else{if(null!==u)throw Error("Emitter.on: invalid event.");l=this._handlersAll}for(h in r||{})s[h]&&(f[h]=r[h]);f.once&&(f.parent=l),l.push(f)}return this},h.prototype.once=function(){var t=Array.prototype.slice.call(arguments),r=t.length-1;return o(t[r])&&t.length>1?t[r]=e(t[r],{once:!0}):t.push({once:!0}),this.on.apply(this,t)},h.prototype.off=function(t,e){var r,n,s,a;if(1===arguments.length&&"function"==typeof t){e=arguments[0];for(s in this._handlers)this._handlers[s]=i(this._handlers[s],e),0===this._handlers[s].length&&delete this._handlers[s];this._handlersAll=i(this._handlersAll,e),this._handlersComplex=i(this._handlersComplex,e)}else if(1===arguments.length&&"string"==typeof t)delete this._handlers[t];else if(2===arguments.length){var h=[].concat(t);for(r=0,n=h.length;n>r;r++)a=h[r],this._handlers[a]=i(this._handlers[a],e),0===(this._handlers[a]||[]).length&&delete this._handlers[a]}else if(o(t))for(s in t)this.off(s,t[s]);return this},h.prototype.listeners=function(t){var e,r,n,o=this._handlersAll||[],i=!1;if(!t)throw Error("Emitter.listeners: no event provided.");for(o=o.concat(this._handlers[t]||[]),r=0,n=this._handlersComplex.length;n>r;r++)e=this._handlersComplex[r],~t.search(e.pattern)&&(i=!0,o.push(e));return this._handlersAll.length||i?o.sort(function(t,e){return t.order-e.order}):o.slice(0)},h.prototype.emit=function(t,e){if(!this._enabled)return this;if(o(t)){for(var r in t)this.emit(r,t[r]);return this}var n,i,s,a,h,u,c,l=[].concat(t),f=[];for(a=0,u=l.length;u>a;a++){for(i=this.listeners(l[a]),h=0,c=i.length;c>h;h++)s=i[h],n={type:l[a],target:this},arguments.length>1&&(n.data=e),s.fn.call("scope"in s?s.scope:this,n),s.once&&f.push(s);for(h=f.length-1;h>=0;h--)f[h].parent.splice(f[h].parent.indexOf(f[h]),1)}return this},h.prototype.kill=function(){this.unbindAll(),this._handlers=null,this._handlersAll=null,this._handlersComplex=null,this._enabled=!1},h.prototype.disable=function(){return this._enabled=!1,this},h.prototype.enable=function(){return this._enabled=!0,this},h.version="3.0.0","undefined"!=typeof n?("undefined"!=typeof r&&r.exports&&(n=r.exports=h),n.Emitter=h):"function"==typeof t&&t.amd?t("emmett",[],function(){return h}):this.Emitter=h}).call(this)},{}],4:[function(t,e,r){function n(t){return t+"$"+(new Date).getTime()+(""+Math.random()).replace("0.","")}function o(t,e){function r(t){this[t]=function(){var e=this.root[t].apply(this.root,arguments);return e instanceof i?this:e}}if(arguments.length<1&&(t={}),!(this instanceof o))return new o(t,e);if(!p.Object(t)&&!p.Array(t))throw Error("Baobab: invalid data.");if(s.call(this),this.options=u.shallowMerge(f,e),this._transaction={},this._future=void 0,this._cursors={},this._identity="[object Baobab]",this.data=u.deepClone(t),this.root=this.select([]),this.facets={},["get","set","unset","update"].forEach(r.bind(this)),!p.Object(this.options.facets))throw Error("Baobab: invalid facets.");for(var n in this.options.facets)this.addFacet(n,this.options.facets[n])}var i=t("./cursor.js"),s=t("emmett"),a=t("./watcher.js"),h=t("./facet.js"),u=t("./helpers.js"),c=t("./update.js"),l=t("./merge.js"),f=t("../defaults.js"),p=t("./type.js");u.inherits(o,s),o.prototype.addFacet=function(t,e){return this.facets[t]=this.createFacet(e),this},o.prototype.createFacet=function(t){return new h(this,t)},o.prototype.select=function(t){if(!t)throw Error("Baobab.select: invalid path.");if(arguments.length>1&&(t=u.arrayOf(arguments)),!p.Path(t))throw Error("Baobab.select: invalid path.");t=[].concat(t);var e,r=p.ComplexPath(t);r&&(e=u.solvePath(this.data,t,this));var o=t.map(function(t){return p.Function(t)?n("fn"):p.Object(t)?n("ob"):t}).join("|λ|");if(this._cursors[o])return this._cursors[o];var s=new i(this,t,e,o);return this._cursors[o]=s,s},o.prototype.stack=function(t){var e=this;if(!p.Object(t))throw Error("Baobab.update: wrong specification.");return this._transaction=l(t,this._transaction),this.options.autoCommit?this.options.asynchronous?(this._future||(this._future=setTimeout(e.commit.bind(e,null),0)),this):this.commit():this},o.prototype.commit=function(){var t=c(this.data,this._transaction,this.options),e=this.data;return this.data=t.data,this._transaction={},this._future&&(this._future=clearTimeout(this._future)),this.emit("update",{log:t.log,previousState:e}),this},o.prototype.watch=function(t){if(!p.Array(t)||t.some(function(t){return!p.Path(t)}))throw Error("Baobab.watch: invalid paths.");return new a(this,[].concat(t))},o.prototype.release=function(){var t;delete this.data,delete this._transaction;for(t in this._cursors)this._cursors[t].release();delete this._cursors;for(t in this.facets)this.facets[t].release();delete this.facets,this.kill()},o.prototype.toJSON=function(){return this.get()},o.prototype.toString=function(){return this._identity},e.exports=o},{"../defaults.js":2,"./cursor.js":5,"./facet.js":6,"./helpers.js":7,"./merge.js":8,"./type.js":9,"./update.js":10,"./watcher.js":11,emmett:3}],5:[function(t,e,r){function n(t,e,r,n){function o(t){if(i.isRecording()&&!i.undoing){var e=a.getIn(t,i.solvedPath,i.tree),r=a.deepClone(e);i.archive.add(r)}return i.undoing=!1,i.emit("update")}var i=this;s.call(this),e=e||[],this.tree=t,this.path=e,this.hash=n,this.archive=null,this.undoing=!1,this._identity="[object Cursor]",this.complexPath=!!r,this.solvedPath=this.complexPath?r:this.path,this.relevant=void 0!==this.get(),this.updateHandler=function(t){var e=t.data.log,r=t.data.previousState,n=!1;if(i.complexPath&&(i.solvedPath=a.solvePath(i.tree.data,i.path,i.tree)),!i.path.length)return o(r);i.solvedPath&&(n=a.solveUpdate(e,[i.solvedPath]));var s=void 0!==i.get();i.relevant?s&&n?o(r):s||(i.emit("irrelevant"),i.relevant=!1):s&&n&&(i.emit("relevant"),o(r),i.relevant=!0)};var h=!1;this._lazyBind=function(){h||(h=!0,i.tree.on("update",i.updateHandler))},this.on=a.before(this._lazyBind,this.on.bind(this)),this.once=a.before(this._lazyBind,this.once.bind(this)),this.complexPath&&this._lazyBind()}function o(t,e,r,n){if(arguments.length>5)throw Error("baobab.Cursor."+t+": too many arguments.");arguments.length<4&&(n=r,r=[]),r=r||[];var o=[].concat(r),i=a.solvePath(this.get(),o,this.tree);if(!i)throw Error("baobab.Cursor."+t+": could not solve dynamic path.");if(e){var s=this.get(i);if(!h[e](s))throw Error("baobab.Cursor."+t+": invalid target.")}var u={};u["$"+t]=n;var c=a.pathObject(i,u);return c}function i(t,e){n.prototype[t]=function(){var r=o.bind(this,t,e).apply(this,arguments);return this.update(r)}}var s=t("emmett"),a=t("./helpers.js"),h=(t("../defaults.js"),t("./type.js"));a.inherits(n,s),n.prototype.isRoot=function(){return!this.path.length},n.prototype.isLeaf=function(){return h.Primitive(this.get())},n.prototype.isBranch=function(){return!this.isLeaf()&&!this.isRoot()},n.prototype.root=function(){return this.tree.root()},n.prototype.select=function(t){if(arguments.length>1&&(t=a.arrayOf(arguments)),!h.Path(t))throw Error("baobab.Cursor.select: invalid path.");return this.tree.select(this.path.concat(t))},n.prototype.up=function(){return this.solvedPath&&this.solvedPath.length?this.tree.select(this.path.slice(0,-1)):null},n.prototype.left=function(){var t=+this.solvedPath[this.solvedPath.length-1];if(isNaN(t))throw Error("baobab.Cursor.left: cannot go left on a non-list type.");return t?this.tree.select(this.solvedPath.slice(0,-1).concat(t-1)):null},n.prototype.leftmost=function(){var t=+this.solvedPath[this.solvedPath.length-1];if(isNaN(t))throw Error("baobab.Cursor.leftmost: cannot go left on a non-list type.");return this.tree.select(this.solvedPath.slice(0,-1).concat(0))},n.prototype.right=function(){var t=+this.solvedPath[this.solvedPath.length-1];if(isNaN(t))throw Error("baobab.Cursor.right: cannot go right on a non-list type.");return t+1===this.up().get().length?null:this.tree.select(this.solvedPath.slice(0,-1).concat(t+1))},n.prototype.rightmost=function(){var t=+this.solvedPath[this.solvedPath.length-1];if(isNaN(t))throw Error("baobab.Cursor.right: cannot go right on a non-list type.");var e=this.up().get();return this.tree.select(this.solvedPath.slice(0,-1).concat(e.length-1))},n.prototype.down=function(){+this.solvedPath[this.solvedPath.length-1];return this.get()instanceof Array?this.tree.select(this.solvedPath.concat(0)):null},n.prototype.get=function(t){arguments.length>1&&(t=a.arrayOf(arguments));var e=this.solvedPath.concat([].concat(t||0===t?t:[]));return a.getIn(this.tree.data,e,this.tree)},i("set"),i("apply"),i("chain"),i("push","Array"),i("unshift","Array"),n.prototype.merge=function(t){if(!h.Object(t))throw Error("baobab.Cursor.merge: trying to merge a non-object.");var e=o.bind(this,"merge","Object").apply(this,arguments);return this.update(e)},n.prototype.unset=function(t){if(void 0===t&&this.isRoot())throw Error("baobab.Cursor.unset: cannot remove root node.");var e=o.bind(this,"unset",null).apply(this,[t,!0]);return this.update(e)},n.prototype.update=function(t,e){if(arguments.length<2)return this.tree.stack(a.pathObject(this.solvedPath,t)),this;var r=[].concat(t),n=a.solvePath(this.get(),r,this.tree);if(!n)throw Error("baobab.Cursor.update: could not solve dynamic path.");return this.tree.stack(a.pathObject(this.solvedPath.concat(n),e)),this},n.prototype.startRecording=function(t){if(t=t||5,1>t)throw Error("baobab.Cursor.startRecording: invalid maximum number of records.");return this.archive?this:(this._lazyBind(),this.archive=a.archive(t),this)},n.prototype.stopRecording=function(){return this.archive=null,this},n.prototype.undo=function(t){if(t=t||1,!this.isRecording())throw Error("baobab.Cursor.undo: cursor is not recording.");if(!h.PositiveInteger(t))throw Error("baobab.Cursor.undo: expecting a positive integer.");var e=this.archive.back(t);if(!e)throw Error("boabab.Cursor.undo: cannot find a relevant record ("+t+" back).");return this.undoing=!0,this.set(e)},n.prototype.isRecording=function(){return!!this.archive},n.prototype.hasHistory=function(){return!(!this.archive||!this.archive.get().length)},n.prototype.getHistory=function(){return this.archive?this.archive.get():[]},n.prototype.release=function(){this.tree.off("update",this.updateHandler),this.hash&&delete this.tree._cursors[this.hash],delete this.tree,delete this.path,delete this.solvedPath,delete this.archive,this.kill()},n.prototype.toJSON=function(){return this.get()},n.prototype.toString=function(){return this._identity},e.exports=n},{"../defaults.js":2,"./helpers.js":7,"./type.js":9,emmett:3}],6:[function(t,e,r){function n(t){return t}function o(t,e){function r(t){o[t]=l[t].bind(l)}var o=this,s=null,a=!1,h=e.get||n,u=e.cursors,c=Object.keys(u).map(function(t){return u[t]}),l=new i(t,c);["on","once","release"].forEach(r),this.get=function(){if(a)return s;var e={};for(var r in u)e[r]=t.get(u[r]);return s=h.call(null,e),a=!0,s},this.on("update",function(){a=!1})}{var i=t("./watcher.js");t("./helpers.js")}e.exports=o},{"./helpers.js":7,"./watcher.js":11}],7:[function(t,e,r){(function(r){function n(t){return Array.prototype.slice.call(t)}function o(t,e){return function(){t(),e.apply(null,arguments)}}function i(t,e){var r,n={};for(r in t)n[r]=t[r];for(r in e)n[r]=e[r];return n}function s(t){var e=t.source,r="";return t.global&&(r+="g"),t.multiline&&(r+="m"),t.ignoreCase&&(r+="i"),t.sticky&&(r+="y"),t.unicode&&(r+="u"),new RegExp(e,r)}function a(t,e){if(!e||"object"!=typeof e||e instanceof Error||"ArrayBuffer"in r&&e instanceof ArrayBuffer)return e;if(w.Array(e)){if(t){var n,o,i=[];for(n=0,o=e.length;o>n;n++)i.push($(e[n]));return i}return e.slice(0)}if(w.Date(e))return new Date(e.getTime());if(e instanceof RegExp)return s(e);if(w.Object(e)){var a,h={};e.constructor&&e.constructor!==Object&&(h=Object.create(e.constructor.prototype));for(a in e)e.hasOwnProperty(a)&&(h[a]=t?$(e[a]):e[a]);return h}return e}function h(t,e){return function(r){return e(t(r))}}function u(t,e){var r,n;for(r=0,n=t.length;n>r;r++)if(e(t[r]))return t[r]}function c(t,e){var r,n;for(r=0,n=t.length;n>r;r++)if(e(t[r]))return r;return-1}function l(t,e){var r,n=!0;if(!t)return!1;for(r in e)if(w.Object(e[r]))n=n&&l(t[r],e[r]);else if(w.Array(e[r]))n=n&&!!~e[r].indexOf(t[r]);else if(t[r]!==e[r])return!1;return n}function f(t,e){return u(t,function(t){return l(t,e)})}function d(t,e){return c(t,function(t){return l(t,e)})}function y(t,e,r){e=e||[];var n,o,i,s=t;for(o=0,i=e.length;i>o;o++){if(!s)return;if("function"==typeof e[o]){if(!w.Array(s))return;s=u(s,e[o])}else if("object"==typeof e[o])if(r&&"$cursor"in e[o]){if(!w.Path(e[o].$cursor))throw Error("baobab.getIn: $cursor path must be an array.");n=r.get(e[o].$cursor),s=s[n]}else{if(!w.Array(s))return;s=f(s,e[o])}else s=s[e[o]]}return s}function g(t,e,r){var n,o,i,s=[],a=t;for(o=0,i=e.length;i>o;o++){if(!a)return null;if("function"==typeof e[o]){if(!w.Array(a))return;n=c(a,e[o]),s.push(n),a=a[n]}else if("object"==typeof e[o])if(r&&"$cursor"in e[o]){if(!w.Path(e[o].$cursor))throw Error("baobab.getIn: $cursor path must be an array.");p=r.get(e[o].$cursor),s.push(p),a=a[p]}else{if(!w.Array(a))return;n=d(a,e[o]),s.push(n),a=a[n]}else s.push(e[o]),a=a[e[o]]||{}}return s}function v(t,e){var r,n,o,i,s,a,h,u,c;for(r=0,i=e.length;i>r;r++)for(h=e[r],n=0,s=t.length;s>n;n++)for(u=t[n],o=0,a=u.length;a>o&&(c=u[o],c==h[o]);o++)if(o+1===a||o+1===h.length)return!0;return!1}function b(t,e){var r,n=t.length,o={},i=o;for(n||(o=e),r=0;n>r;r++)i[t[r]]=r+1===n?e:{},i=i[t[r]];return o}function m(t,e){t.super_=e;var r=function(){};r.prototype=e.prototype,t.prototype=new r,t.prototype.constructor=t}function j(t){var e=[];return{add:function(r){e.unshift(r),e.length>t&&(e.length=t)},back:function(t){var r=e[t-1];return r&&(e=e.slice(t)),r},get:function(){return e}}}var w=t("./type.js"),_=a.bind(null,!1),$=a.bind(null,!0);e.exports={archive:j,arrayOf:n,before:o,deepClone:$,shallowClone:_,shallowMerge:i,compose:h,getIn:y,inherits:m,pathObject:b,solvePath:g,solveUpdate:v}}).call(this,"undefined"!=typeof global?global:"undefined"!=typeof self?self:"undefined"!=typeof window?window:{})},{"./type.js":9}],8:[function(t,e,r){function n(t,e,r){a.forEach(function(e){r!==e&&delete t[e]}),t[r]=e[r]}function o(t,e){var r,h=i.shallowClone(e||{});a.forEach(function(e){t[e]&&n(h,t,e)}),t.$chain&&(a.slice(0,-1).forEach(function(t){delete h[t]}),h.$apply=h.$apply?i.compose(h.$apply,t.$chain):t.$chain),t.$push&&h.$push?h.$push=s.Array(h.$push)?h.$push.concat(t.$push):[h.$push].concat(t.$push):t.$push&&(h.$push=t.$push),t.$unshift&&h.$unshift?h.$unshift=s.Array(t.$unshift)?t.$unshift.concat(h.$unshift):[t.$unshift].concat(h.$unshift):t.$unshift&&(h.$unshift=t.$unshift);for(r in t)s.Object(t[r])?h[r]=o(t[r],h[r]):"$"!==r[0]&&(h[r]=t[r]);return h}var i=t("./helpers.js"),s=t("./type.js"),a=["$unset","$set","$merge","$apply"];e.exports=o},{"./helpers.js":7,"./type.js":9}],9:[function(t,e,r){function n(t,e){return e.some(function(e){return o[e](t)})}var o={};o.Array=function(t){return Array.isArray(t)},o.Object=function(t){return t&&"object"==typeof t&&!Array.isArray(t)&&!(t instanceof Function)},o.String=function(t){return"string"==typeof t},o.Number=function(t){return"number"==typeof t},o.PositiveInteger=function(t){return"number"==typeof t&&t>0&&t%1===0},o.Function=function(t){return"function"==typeof t},o.Primitive=function(t){return"string"==typeof t||"number"==typeof t||"boolean"==typeof t},o.Date=function(t){return t instanceof Date},o.NonScalar=function(t){return o.Object(t)||o.Array(t)},o.Path=function(t){var e=["String","Number","Function","Object"];return o.Array(t)?t.every(function(t){return n(t,e)}):n(t,e)},o.MixinCursor=function(t){return n(t,["String","Number","Array","Function","Cursor"])},o.MixinCursors=function(t){return n(t,["Object","Array","Function"])},o.ComplexPath=function(t){return t.some(function(t){return n(t,["Object","Function"])})},e.exports=o},{}],10:[function(t,e,r){function n(t,e){var r=new Error("baobab.update: "+e+" at path /"+t.slice(1).join("/"));return r.path=t,r}var o=t("./helpers.js"),i=t("./type.js");e.exports=function(t,e,r){if(r=r||{},!i.Object(t)&&!i.Array(t))throw Error("baobab.update: invalid target.");var s={};t={root:o.shallowClone(t)};var a=function(t,e,r,h){r=r||["root"];var u,c,l,f=r.join("|λ|"),p=r[r.length-1],d=Object.keys(e).some(function(t){return!!~["$unset","$set","$apply","$merge","$push","$unshift"].indexOf(t)});if(d){s[f]=!0;for(c in e){if("$unset"===c){var y=r[r.length-2];i.Array(t)?h[y]=t.slice(0,+p).concat(t.slice(+p+1)):(h[y]=o.shallowClone(t),delete h[y][p]);break}if("$set"===c){l=e.$set,t[p]=l;break}if("$apply"===c){if(u=e.$apply,"function"!=typeof u)throw n(r,"using command $apply with a non function");t[p]=u.call(null,t[p]);break}if("$merge"===c){if(l=e.$merge,!i.Object(t[p])||!i.Object(l))throw n(r,"using command $merge with a non object");t[p]=o.shallowMerge(t[p],l);break}if("$push"===c){if(l=e.$push,!i.Array(t[p]))throw n(r,"using command $push to a non array");t[p]=t[p].concat(l)}if("$unshift"===c){if(l=e.$unshift,!i.Array(t[p]))throw n(r,"using command $unshift to a non array");t[p]=[].concat(l).concat(t[p])}}}else for(c in e)t[p][c]="undefined"==typeof t[p][c]?{}:o.shallowClone(t[p][c]),a(t[p],e[c],r.concat(c),t)};return a(t,e),{data:t.root,log:Object.keys(s).map(function(t){return t.split("|λ|").slice(1)})}}},{"./helpers.js":7,"./type.js":9}],11:[function(t,e,r){function n(t,e){function r(){h&&(a=e.map(function(t){return i.solvePath(n.tree.data,t,n.tree)}))}var n=this;o.call(this),this.tree=t;var a=e,h=e.some(s.ComplexPath);this.updateHandler=function(t){var e=i.solveUpdate(t.data.log,a);e&&n.emit("update")},r(),this.tree.on("update",this.updateHandler)}var o=t("emmett"),i=t("./helpers.js"),s=t("./type.js");i.inherits(n,o),n.prototype.release=function(){this.tree.off("update",this.updateHandler),this.tree=null,this.kill()},e.exports=n},{"./helpers.js":7,"./type.js":9,emmett:3}]},{},[1])(1)}); \ No newline at end of file +!function(t){if("object"==typeof exports&&"undefined"!=typeof module)module.exports=t();else if("function"==typeof define&&define.amd)define([],t);else{var e;e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:this,e.Baobab=t()}}(function(){var t;return function e(t,r,n){function o(s,a){if(!r[s]){if(!t[s]){var h="function"==typeof require&&require;if(!a&&h)return h(s,!0);if(i)return i(s,!0);var u=new Error("Cannot find module '"+s+"'");throw u.code="MODULE_NOT_FOUND",u}var c=r[s]={exports:{}};t[s][0].call(c.exports,function(e){var r=t[s][1][e];return o(r?r:e)},c,c.exports,e,t,r,n)}return r[s].exports}for(var i="function"==typeof require&&require,s=0;sn;n++)t[n].fn!==e&&o.push(t[n]);return o}var s={once:"boolean",scope:"object"},a=0,h=function(){this._enabled=!0,this.unbindAll()};h.prototype.unbindAll=function(){return this._handlers={},this._handlersAll=[],this._handlersComplex=[],this},h.prototype.on=function(t,e,r){var n,i,h,u,c,l,f;if(o(t)){for(u in t)this.on(u,t[u],e);return this}for("function"==typeof t&&(r=e,e=t,t=null),c=[].concat(t),n=0,i=c.length;i>n;n++){if(u=c[n],f={order:a++,fn:e},"string"==typeof u)this._handlers[u]||(this._handlers[u]=[]),l=this._handlers[u];else if(u instanceof RegExp)l=this._handlersComplex,f.pattern=u;else{if(null!==u)throw Error("Emitter.on: invalid event.");l=this._handlersAll}for(h in r||{})s[h]&&(f[h]=r[h]);f.once&&(f.parent=l),l.push(f)}return this},h.prototype.once=function(){var t=Array.prototype.slice.call(arguments),r=t.length-1;return o(t[r])&&t.length>1?t[r]=e(t[r],{once:!0}):t.push({once:!0}),this.on.apply(this,t)},h.prototype.off=function(t,e){var r,n,s,a;if(1===arguments.length&&"function"==typeof t){e=arguments[0];for(s in this._handlers)this._handlers[s]=i(this._handlers[s],e),0===this._handlers[s].length&&delete this._handlers[s];this._handlersAll=i(this._handlersAll,e),this._handlersComplex=i(this._handlersComplex,e)}else if(1===arguments.length&&"string"==typeof t)delete this._handlers[t];else if(2===arguments.length){var h=[].concat(t);for(r=0,n=h.length;n>r;r++)a=h[r],this._handlers[a]=i(this._handlers[a],e),0===(this._handlers[a]||[]).length&&delete this._handlers[a]}else if(o(t))for(s in t)this.off(s,t[s]);return this},h.prototype.listeners=function(t){var e,r,n,o=this._handlersAll||[],i=!1;if(!t)throw Error("Emitter.listeners: no event provided.");for(o=o.concat(this._handlers[t]||[]),r=0,n=this._handlersComplex.length;n>r;r++)e=this._handlersComplex[r],~t.search(e.pattern)&&(i=!0,o.push(e));return this._handlersAll.length||i?o.sort(function(t,e){return t.order-e.order}):o.slice(0)},h.prototype.emit=function(t,e){if(!this._enabled)return this;if(o(t)){for(var r in t)this.emit(r,t[r]);return this}var n,i,s,a,h,u,c,l=[].concat(t),f=[];for(a=0,u=l.length;u>a;a++){for(i=this.listeners(l[a]),h=0,c=i.length;c>h;h++)s=i[h],n={type:l[a],target:this},arguments.length>1&&(n.data=e),s.fn.call("scope"in s?s.scope:this,n),s.once&&f.push(s);for(h=f.length-1;h>=0;h--)f[h].parent.splice(f[h].parent.indexOf(f[h]),1)}return this},h.prototype.kill=function(){this.unbindAll(),this._handlers=null,this._handlersAll=null,this._handlersComplex=null,this._enabled=!1},h.prototype.disable=function(){return this._enabled=!1,this},h.prototype.enable=function(){return this._enabled=!0,this},h.version="3.0.0","undefined"!=typeof n?("undefined"!=typeof r&&r.exports&&(n=r.exports=h),n.Emitter=h):"function"==typeof t&&t.amd?t("emmett",[],function(){return h}):this.Emitter=h}).call(this)},{}],4:[function(t,e,r){function n(t){return t+"$"+(new Date).getTime()+(""+Math.random()).replace("0.","")}function o(t,e){function r(t){this[t]=function(){var e=this.root[t].apply(this.root,arguments);return e instanceof i?this:e}}if(arguments.length<1&&(t={}),!(this instanceof o))return new o(t,e);if(!p.Object(t)&&!p.Array(t))throw Error("Baobab: invalid data.");if(s.call(this),this.options=u.shallowMerge(f,e),this._transaction={},this._future=void 0,this._cursors={},this._identity="[object Baobab]",this.data=u.deepClone(t),this.root=this.select([]),this.facets={},["get","set","unset","update"].forEach(r.bind(this)),!p.Object(this.options.facets))throw Error("Baobab: invalid facets.");for(var n in this.options.facets)this.addFacet(n,this.options.facets[n])}var i=t("./cursor.js"),s=t("emmett"),a=t("./watcher.js"),h=t("./facet.js"),u=t("./helpers.js"),c=t("./update.js"),l=t("./merge.js"),f=t("../defaults.js"),p=t("./type.js");u.inherits(o,s),o.prototype.addFacet=function(t,e){return this.facets[t]=this.createFacet(e),this},o.prototype.createFacet=function(t){return new h(this,t)},o.prototype.select=function(t){if(!t)throw Error("Baobab.select: invalid path.");if(arguments.length>1&&(t=u.arrayOf(arguments)),!p.Path(t))throw Error("Baobab.select: invalid path.");t=[].concat(t);var e,r=p.ComplexPath(t);r&&(e=u.solvePath(this.data,t,this));var o=t.map(function(t){return p.Function(t)?n("fn"):p.Object(t)?n("ob"):t}).join("|λ|");if(this._cursors[o])return this._cursors[o];var s=new i(this,t,e,o);return this._cursors[o]=s,s},o.prototype.stack=function(t){var e=this;if(!p.Object(t))throw Error("Baobab.update: wrong specification.");return this._transaction=l(t,this._transaction),this.options.autoCommit?this.options.asynchronous?(this._future||(this._future=setTimeout(e.commit.bind(e,null),0)),this):this.commit():this},o.prototype.commit=function(){var t=c(this.data,this._transaction,this.options),e=this.data;this._transaction={},this._future&&(this._future=clearTimeout(this._future));var r=this.options.validate,n=this.options.validationBehaviour;if("function"==typeof r){var o=r.call(this,e,t.data,t.log);if(o instanceof Error&&(this.emit("invalid",{error:o}),"rollback"===n))return this}return this.data=t.data,this.emit("update",{log:t.log,previousState:e}),this},o.prototype.watch=function(t){if(!p.Array(t)||t.some(function(t){return!p.Path(t)}))throw Error("Baobab.watch: invalid paths.");return new a(this,[].concat(t))},o.prototype.release=function(){var t;delete this.data,delete this._transaction;for(t in this._cursors)this._cursors[t].release();delete this._cursors;for(t in this.facets)this.facets[t].release();delete this.facets,this.kill()},o.prototype.toJSON=function(){return this.get()},o.prototype.toString=function(){return this._identity},e.exports=o},{"../defaults.js":2,"./cursor.js":5,"./facet.js":6,"./helpers.js":7,"./merge.js":8,"./type.js":9,"./update.js":10,"./watcher.js":11,emmett:3}],5:[function(t,e,r){function n(t,e,r,n){function o(t){if(i.isRecording()&&!i.undoing){var e=a.getIn(t,i.solvedPath,i.tree),r=a.deepClone(e);i.archive.add(r)}return i.undoing=!1,i.emit("update")}var i=this;s.call(this),e=e||[],this.tree=t,this.path=e,this.hash=n,this.archive=null,this.undoing=!1,this._identity="[object Cursor]",this.complexPath=!!r,this.solvedPath=this.complexPath?r:this.path,this.relevant=void 0!==this.get(),this.updateHandler=function(t){var e=t.data.log,r=t.data.previousState,n=!1;if(i.complexPath&&(i.solvedPath=a.solvePath(i.tree.data,i.path,i.tree)),!i.path.length)return o(r);i.solvedPath&&(n=a.solveUpdate(e,[i.solvedPath]));var s=void 0!==i.get();i.relevant?s&&n?o(r):s||(i.emit("irrelevant"),i.relevant=!1):s&&n&&(i.emit("relevant"),o(r),i.relevant=!0)};var h=!1;this._lazyBind=function(){h||(h=!0,i.tree.on("update",i.updateHandler))},this.on=a.before(this._lazyBind,this.on.bind(this)),this.once=a.before(this._lazyBind,this.once.bind(this)),this.complexPath&&this._lazyBind()}function o(t,e,r,n){if(arguments.length>5)throw Error("baobab.Cursor."+t+": too many arguments.");arguments.length<4&&(n=r,r=[]),r=r||[];var o=[].concat(r),i=a.solvePath(this.get(),o,this.tree);if(!i)throw Error("baobab.Cursor."+t+": could not solve dynamic path.");if(e){var s=this.get(i);if(!h[e](s))throw Error("baobab.Cursor."+t+": invalid target.")}var u={};u["$"+t]=n;var c=a.pathObject(i,u);return c}function i(t,e){n.prototype[t]=function(){var r=o.bind(this,t,e).apply(this,arguments);return this.update(r)}}var s=t("emmett"),a=t("./helpers.js"),h=(t("../defaults.js"),t("./type.js"));a.inherits(n,s),n.prototype.isRoot=function(){return!this.path.length},n.prototype.isLeaf=function(){return h.Primitive(this.get())},n.prototype.isBranch=function(){return!this.isLeaf()&&!this.isRoot()},n.prototype.root=function(){return this.tree.root()},n.prototype.select=function(t){if(arguments.length>1&&(t=a.arrayOf(arguments)),!h.Path(t))throw Error("baobab.Cursor.select: invalid path.");return this.tree.select(this.path.concat(t))},n.prototype.up=function(){return this.solvedPath&&this.solvedPath.length?this.tree.select(this.path.slice(0,-1)):null},n.prototype.left=function(){var t=+this.solvedPath[this.solvedPath.length-1];if(isNaN(t))throw Error("baobab.Cursor.left: cannot go left on a non-list type.");return t?this.tree.select(this.solvedPath.slice(0,-1).concat(t-1)):null},n.prototype.leftmost=function(){var t=+this.solvedPath[this.solvedPath.length-1];if(isNaN(t))throw Error("baobab.Cursor.leftmost: cannot go left on a non-list type.");return this.tree.select(this.solvedPath.slice(0,-1).concat(0))},n.prototype.right=function(){var t=+this.solvedPath[this.solvedPath.length-1];if(isNaN(t))throw Error("baobab.Cursor.right: cannot go right on a non-list type.");return t+1===this.up().get().length?null:this.tree.select(this.solvedPath.slice(0,-1).concat(t+1))},n.prototype.rightmost=function(){var t=+this.solvedPath[this.solvedPath.length-1];if(isNaN(t))throw Error("baobab.Cursor.right: cannot go right on a non-list type.");var e=this.up().get();return this.tree.select(this.solvedPath.slice(0,-1).concat(e.length-1))},n.prototype.down=function(){+this.solvedPath[this.solvedPath.length-1];return this.get()instanceof Array?this.tree.select(this.solvedPath.concat(0)):null},n.prototype.get=function(t){arguments.length>1&&(t=a.arrayOf(arguments));var e=this.solvedPath.concat([].concat(t||0===t?t:[]));return a.getIn(this.tree.data,e,this.tree)},i("set"),i("apply"),i("chain"),i("push","Array"),i("unshift","Array"),n.prototype.merge=function(t){if(!h.Object(t))throw Error("baobab.Cursor.merge: trying to merge a non-object.");var e=o.bind(this,"merge","Object").apply(this,arguments);return this.update(e)},n.prototype.unset=function(t){if(void 0===t&&this.isRoot())throw Error("baobab.Cursor.unset: cannot remove root node.");var e=o.bind(this,"unset",null).apply(this,[t,!0]);return this.update(e)},n.prototype.update=function(t,e){if(arguments.length<2)return this.tree.stack(a.pathObject(this.solvedPath,t)),this;var r=[].concat(t),n=a.solvePath(this.get(),r,this.tree);if(!n)throw Error("baobab.Cursor.update: could not solve dynamic path.");return this.tree.stack(a.pathObject(this.solvedPath.concat(n),e)),this},n.prototype.startRecording=function(t){if(t=t||5,1>t)throw Error("baobab.Cursor.startRecording: invalid maximum number of records.");return this.archive?this:(this._lazyBind(),this.archive=a.archive(t),this)},n.prototype.stopRecording=function(){return this.archive=null,this},n.prototype.undo=function(t){if(t=t||1,!this.isRecording())throw Error("baobab.Cursor.undo: cursor is not recording.");if(!h.PositiveInteger(t))throw Error("baobab.Cursor.undo: expecting a positive integer.");var e=this.archive.back(t);if(!e)throw Error("boabab.Cursor.undo: cannot find a relevant record ("+t+" back).");return this.undoing=!0,this.set(e)},n.prototype.isRecording=function(){return!!this.archive},n.prototype.hasHistory=function(){return!(!this.archive||!this.archive.get().length)},n.prototype.getHistory=function(){return this.archive?this.archive.get():[]},n.prototype.release=function(){this.tree.off("update",this.updateHandler),this.hash&&delete this.tree._cursors[this.hash],delete this.tree,delete this.path,delete this.solvedPath,delete this.archive,this.kill()},n.prototype.toJSON=function(){return this.get()},n.prototype.toString=function(){return this._identity},e.exports=n},{"../defaults.js":2,"./helpers.js":7,"./type.js":9,emmett:3}],6:[function(t,e,r){function n(t){return t}function o(t,e){function r(t){o[t]=l[t].bind(l)}var o=this,s=null,a=!1,h=e.get||n,u=e.cursors,c=Object.keys(u).map(function(t){return u[t]}),l=new i(t,c);["on","once","release"].forEach(r),this.get=function(){if(a)return s;var e={};for(var r in u)e[r]=t.get(u[r]);return s=h.call(null,e),a=!0,s},this.on("update",function(){a=!1})}{var i=t("./watcher.js");t("./helpers.js")}e.exports=o},{"./helpers.js":7,"./watcher.js":11}],7:[function(t,e,r){(function(r){function n(t){return Array.prototype.slice.call(t)}function o(t,e){return function(){t(),e.apply(null,arguments)}}function i(t,e){var r,n={};for(r in t)n[r]=t[r];for(r in e)n[r]=e[r];return n}function s(t){var e=t.source,r="";return t.global&&(r+="g"),t.multiline&&(r+="m"),t.ignoreCase&&(r+="i"),t.sticky&&(r+="y"),t.unicode&&(r+="u"),new RegExp(e,r)}function a(t,e){if(!e||"object"!=typeof e||e instanceof Error||"ArrayBuffer"in r&&e instanceof ArrayBuffer)return e;if(w.Array(e)){if(t){var n,o,i=[];for(n=0,o=e.length;o>n;n++)i.push($(e[n]));return i}return e.slice(0)}if(w.Date(e))return new Date(e.getTime());if(e instanceof RegExp)return s(e);if(w.Object(e)){var a,h={};e.constructor&&e.constructor!==Object&&(h=Object.create(e.constructor.prototype));for(a in e)e.hasOwnProperty(a)&&(h[a]=t?$(e[a]):e[a]);return h}return e}function h(t,e){return function(r){return e(t(r))}}function u(t,e){var r,n;for(r=0,n=t.length;n>r;r++)if(e(t[r]))return t[r]}function c(t,e){var r,n;for(r=0,n=t.length;n>r;r++)if(e(t[r]))return r;return-1}function l(t,e){var r,n=!0;if(!t)return!1;for(r in e)if(w.Object(e[r]))n=n&&l(t[r],e[r]);else if(w.Array(e[r]))n=n&&!!~e[r].indexOf(t[r]);else if(t[r]!==e[r])return!1;return n}function f(t,e){return u(t,function(t){return l(t,e)})}function d(t,e){return c(t,function(t){return l(t,e)})}function y(t,e,r){e=e||[];var n,o,i,s=t;for(o=0,i=e.length;i>o;o++){if(!s)return;if("function"==typeof e[o]){if(!w.Array(s))return;s=u(s,e[o])}else if("object"==typeof e[o])if(r&&"$cursor"in e[o]){if(!w.Path(e[o].$cursor))throw Error("baobab.getIn: $cursor path must be an array.");n=r.get(e[o].$cursor),s=s[n]}else{if(!w.Array(s))return;s=f(s,e[o])}else s=s[e[o]]}return s}function v(t,e,r){var n,o,i,s=[],a=t;for(o=0,i=e.length;i>o;o++){if(!a)return null;if("function"==typeof e[o]){if(!w.Array(a))return;n=c(a,e[o]),s.push(n),a=a[n]}else if("object"==typeof e[o])if(r&&"$cursor"in e[o]){if(!w.Path(e[o].$cursor))throw Error("baobab.getIn: $cursor path must be an array.");p=r.get(e[o].$cursor),s.push(p),a=a[p]}else{if(!w.Array(a))return;n=d(a,e[o]),s.push(n),a=a[n]}else s.push(e[o]),a=a[e[o]]||{}}return s}function g(t,e){var r,n,o,i,s,a,h,u,c;for(r=0,i=e.length;i>r;r++)for(h=e[r],n=0,s=t.length;s>n;n++)for(u=t[n],o=0,a=u.length;a>o&&(c=u[o],c==h[o]);o++)if(o+1===a||o+1===h.length)return!0;return!1}function b(t,e){var r,n=t.length,o={},i=o;for(n||(o=e),r=0;n>r;r++)i[t[r]]=r+1===n?e:{},i=i[t[r]];return o}function m(t,e){t.super_=e;var r=function(){};r.prototype=e.prototype,t.prototype=new r,t.prototype.constructor=t}function j(t){var e=[];return{add:function(r){e.unshift(r),e.length>t&&(e.length=t)},back:function(t){var r=e[t-1];return r&&(e=e.slice(t)),r},get:function(){return e}}}var w=t("./type.js"),_=a.bind(null,!1),$=a.bind(null,!0);e.exports={archive:j,arrayOf:n,before:o,deepClone:$,shallowClone:_,shallowMerge:i,compose:h,getIn:y,inherits:m,pathObject:b,solvePath:v,solveUpdate:g}}).call(this,"undefined"!=typeof global?global:"undefined"!=typeof self?self:"undefined"!=typeof window?window:{})},{"./type.js":9}],8:[function(t,e,r){function n(t,e,r){a.forEach(function(e){r!==e&&delete t[e]}),t[r]=e[r]}function o(t,e){var r,h=i.shallowClone(e||{});a.forEach(function(e){t[e]&&n(h,t,e)}),t.$chain&&(a.slice(0,-1).forEach(function(t){delete h[t]}),h.$apply=h.$apply?i.compose(h.$apply,t.$chain):t.$chain),t.$push&&h.$push?h.$push=s.Array(h.$push)?h.$push.concat(t.$push):[h.$push].concat(t.$push):t.$push&&(h.$push=t.$push),t.$unshift&&h.$unshift?h.$unshift=s.Array(t.$unshift)?t.$unshift.concat(h.$unshift):[t.$unshift].concat(h.$unshift):t.$unshift&&(h.$unshift=t.$unshift);for(r in t)s.Object(t[r])?h[r]=o(t[r],h[r]):"$"!==r[0]&&(h[r]=t[r]);return h}var i=t("./helpers.js"),s=t("./type.js"),a=["$unset","$set","$merge","$apply"];e.exports=o},{"./helpers.js":7,"./type.js":9}],9:[function(t,e,r){function n(t,e){return e.some(function(e){return o[e](t)})}var o={};o.Array=function(t){return Array.isArray(t)},o.Object=function(t){return t&&"object"==typeof t&&!Array.isArray(t)&&!(t instanceof Function)},o.String=function(t){return"string"==typeof t},o.Number=function(t){return"number"==typeof t},o.PositiveInteger=function(t){return"number"==typeof t&&t>0&&t%1===0},o.Function=function(t){return"function"==typeof t},o.Primitive=function(t){return"string"==typeof t||"number"==typeof t||"boolean"==typeof t},o.Date=function(t){return t instanceof Date},o.NonScalar=function(t){return o.Object(t)||o.Array(t)},o.Path=function(t){var e=["String","Number","Function","Object"];return o.Array(t)?t.every(function(t){return n(t,e)}):n(t,e)},o.MixinCursor=function(t){return n(t,["String","Number","Array","Function","Cursor"])},o.MixinCursors=function(t){return n(t,["Object","Array","Function"])},o.ComplexPath=function(t){return t.some(function(t){return n(t,["Object","Function"])})},e.exports=o},{}],10:[function(t,e,r){function n(t,e){var r=new Error("baobab.update: "+e+" at path /"+t.slice(1).join("/"));return r.path=t,r}var o=t("./helpers.js"),i=t("./type.js");e.exports=function(t,e,r){if(r=r||{},!i.Object(t)&&!i.Array(t))throw Error("baobab.update: invalid target.");var s={};t={root:o.shallowClone(t)};var a=function(t,e,r,h){r=r||["root"];var u,c,l,f=r.join("|λ|"),p=r[r.length-1],d=Object.keys(e).some(function(t){return!!~["$unset","$set","$apply","$merge","$push","$unshift"].indexOf(t)});if(d){s[f]=!0;for(c in e){if("$unset"===c){var y=r[r.length-2];i.Array(t)?h[y]=t.slice(0,+p).concat(t.slice(+p+1)):(h[y]=o.shallowClone(t),delete h[y][p]);break}if("$set"===c){l=e.$set,t[p]=l;break}if("$apply"===c){if(u=e.$apply,"function"!=typeof u)throw n(r,"using command $apply with a non function");t[p]=u.call(null,t[p]);break}if("$merge"===c){if(l=e.$merge,!i.Object(t[p])||!i.Object(l))throw n(r,"using command $merge with a non object");t[p]=o.shallowMerge(t[p],l);break}if("$push"===c){if(l=e.$push,!i.Array(t[p]))throw n(r,"using command $push to a non array");t[p]=t[p].concat(l)}if("$unshift"===c){if(l=e.$unshift,!i.Array(t[p]))throw n(r,"using command $unshift to a non array");t[p]=[].concat(l).concat(t[p])}}}else for(c in e)t[p][c]="undefined"==typeof t[p][c]?{}:o.shallowClone(t[p][c]),a(t[p],e[c],r.concat(c),t)};return a(t,e),{data:t.root,log:Object.keys(s).map(function(t){return t.split("|λ|").slice(1)})}}},{"./helpers.js":7,"./type.js":9}],11:[function(t,e,r){function n(t,e){function r(){h&&(a=e.map(function(t){return i.solvePath(n.tree.data,t,n.tree)}))}var n=this;o.call(this),this.tree=t;var a=e,h=e.some(s.ComplexPath);this.updateHandler=function(t){var e=i.solveUpdate(t.data.log,a);e&&n.emit("update")},r(),this.tree.on("update",this.updateHandler)}var o=t("emmett"),i=t("./helpers.js"),s=t("./type.js");i.inherits(n,o),n.prototype.release=function(){this.tree.off("update",this.updateHandler),this.tree=null,this.kill()},e.exports=n},{"./helpers.js":7,"./type.js":9,emmett:3}]},{},[1])(1)}); \ No newline at end of file diff --git a/defaults.js b/defaults.js index 184a972..703cd0b 100644 --- a/defaults.js +++ b/defaults.js @@ -15,5 +15,8 @@ module.exports = { facets: {}, // Validation specifications - validate: null + validate: null, + + // Validation behaviour 'rollback' or 'notify' + validationBehaviour: 'rollback' }; diff --git a/src/baobab.js b/src/baobab.js index dd43a1f..cd12f76 100644 --- a/src/baobab.js +++ b/src/baobab.js @@ -153,7 +153,6 @@ Baobab.prototype.commit = function() { var result = update(this.data, this._transaction, this.options); var oldData = this.data; - this.data = result.data; // Resetting this._transaction = {}; @@ -161,6 +160,24 @@ Baobab.prototype.commit = function() { if (this._future) this._future = clearTimeout(this._future); + // Validate? + var validate = this.options.validate, + behaviour = this.options.validationBehaviour; + + if (typeof validate === 'function') { + var error = validate.call(this, oldData, result.data, result.log); + + if (error instanceof Error) { + this.emit('invalid', {error: error}); + + if (behaviour === 'rollback') + return this; + } + } + + // Switching tree's data + this.data = result.data; + // Baobab-level update event this.emit('update', { log: result.log, diff --git a/test/suites/baobab.js b/test/suites/baobab.js index 630b152..af5bb30 100644 --- a/test/suites/baobab.js +++ b/test/suites/baobab.js @@ -291,5 +291,65 @@ describe('Baobab API', function() { }, 0); }, 0); }); + + it('should be possible to validate the tree and rollback on fail.', function() { + var invalidCount = 0; + + function v(state, nextState, paths) { + assert(this === baobab); + + if (typeof nextState.hello !== 'string') + return new Error('Invalid tree!'); + } + + var baobab = new Baobab({hello: 'world'}, {validate: v, asynchronous: false}); + + baobab.on('invalid', function(e) { + var error = e.data.error; + + assert.strictEqual(error.message, 'Invalid tree!'); + invalidCount++; + }); + + baobab.set('hello', 'John'); + + assert.strictEqual(invalidCount, 0); + assert.strictEqual(baobab.get('hello'), 'John'); + + baobab.set('hello', 4); + + assert.strictEqual(invalidCount, 1); + assert.strictEqual(baobab.get('hello'), 'John'); + }); + + it('should be possible to validate the tree and let the tree update on fail.', function() { + var invalidCount = 0; + + function v(state, nextState, paths) { + assert(this === baobab); + + if (typeof nextState.hello !== 'string') + return new Error('Invalid tree!'); + } + + var baobab = new Baobab({hello: 'world'}, {validate: v, asynchronous: false, validationBehaviour: 'notify'}); + + baobab.on('invalid', function(e) { + var error = e.data.error; + + assert.strictEqual(error.message, 'Invalid tree!'); + invalidCount++; + }); + + baobab.set('hello', 'John'); + + assert.strictEqual(invalidCount, 0); + assert.strictEqual(baobab.get('hello'), 'John'); + + baobab.set('hello', 4); + + assert.strictEqual(invalidCount, 1); + assert.strictEqual(baobab.get('hello'), 4); + }); }); }); From 461a5a628644dda047502382b9afefc074150fbc Mon Sep 17 00:00:00 2001 From: Yomguithereal Date: Thu, 16 Apr 2015 12:37:29 +0200 Subject: [PATCH 56/73] Non-mutative splice helper --- build/baobab.min.js | 2 +- src/helpers.js | 15 +++++++++++- src/update.js | 2 +- test/suites/helpers.js | 53 ++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 69 insertions(+), 3 deletions(-) diff --git a/build/baobab.min.js b/build/baobab.min.js index 855bbb4..82540e6 100644 --- a/build/baobab.min.js +++ b/build/baobab.min.js @@ -1,2 +1,2 @@ /* baobab.js - Version: 1.0.0-rc1 - Author: Yomguithereal (Guillaume Plique) */ -!function(t){if("object"==typeof exports&&"undefined"!=typeof module)module.exports=t();else if("function"==typeof define&&define.amd)define([],t);else{var e;e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:this,e.Baobab=t()}}(function(){var t;return function e(t,r,n){function o(s,a){if(!r[s]){if(!t[s]){var h="function"==typeof require&&require;if(!a&&h)return h(s,!0);if(i)return i(s,!0);var u=new Error("Cannot find module '"+s+"'");throw u.code="MODULE_NOT_FOUND",u}var c=r[s]={exports:{}};t[s][0].call(c.exports,function(e){var r=t[s][1][e];return o(r?r:e)},c,c.exports,e,t,r,n)}return r[s].exports}for(var i="function"==typeof require&&require,s=0;sn;n++)t[n].fn!==e&&o.push(t[n]);return o}var s={once:"boolean",scope:"object"},a=0,h=function(){this._enabled=!0,this.unbindAll()};h.prototype.unbindAll=function(){return this._handlers={},this._handlersAll=[],this._handlersComplex=[],this},h.prototype.on=function(t,e,r){var n,i,h,u,c,l,f;if(o(t)){for(u in t)this.on(u,t[u],e);return this}for("function"==typeof t&&(r=e,e=t,t=null),c=[].concat(t),n=0,i=c.length;i>n;n++){if(u=c[n],f={order:a++,fn:e},"string"==typeof u)this._handlers[u]||(this._handlers[u]=[]),l=this._handlers[u];else if(u instanceof RegExp)l=this._handlersComplex,f.pattern=u;else{if(null!==u)throw Error("Emitter.on: invalid event.");l=this._handlersAll}for(h in r||{})s[h]&&(f[h]=r[h]);f.once&&(f.parent=l),l.push(f)}return this},h.prototype.once=function(){var t=Array.prototype.slice.call(arguments),r=t.length-1;return o(t[r])&&t.length>1?t[r]=e(t[r],{once:!0}):t.push({once:!0}),this.on.apply(this,t)},h.prototype.off=function(t,e){var r,n,s,a;if(1===arguments.length&&"function"==typeof t){e=arguments[0];for(s in this._handlers)this._handlers[s]=i(this._handlers[s],e),0===this._handlers[s].length&&delete this._handlers[s];this._handlersAll=i(this._handlersAll,e),this._handlersComplex=i(this._handlersComplex,e)}else if(1===arguments.length&&"string"==typeof t)delete this._handlers[t];else if(2===arguments.length){var h=[].concat(t);for(r=0,n=h.length;n>r;r++)a=h[r],this._handlers[a]=i(this._handlers[a],e),0===(this._handlers[a]||[]).length&&delete this._handlers[a]}else if(o(t))for(s in t)this.off(s,t[s]);return this},h.prototype.listeners=function(t){var e,r,n,o=this._handlersAll||[],i=!1;if(!t)throw Error("Emitter.listeners: no event provided.");for(o=o.concat(this._handlers[t]||[]),r=0,n=this._handlersComplex.length;n>r;r++)e=this._handlersComplex[r],~t.search(e.pattern)&&(i=!0,o.push(e));return this._handlersAll.length||i?o.sort(function(t,e){return t.order-e.order}):o.slice(0)},h.prototype.emit=function(t,e){if(!this._enabled)return this;if(o(t)){for(var r in t)this.emit(r,t[r]);return this}var n,i,s,a,h,u,c,l=[].concat(t),f=[];for(a=0,u=l.length;u>a;a++){for(i=this.listeners(l[a]),h=0,c=i.length;c>h;h++)s=i[h],n={type:l[a],target:this},arguments.length>1&&(n.data=e),s.fn.call("scope"in s?s.scope:this,n),s.once&&f.push(s);for(h=f.length-1;h>=0;h--)f[h].parent.splice(f[h].parent.indexOf(f[h]),1)}return this},h.prototype.kill=function(){this.unbindAll(),this._handlers=null,this._handlersAll=null,this._handlersComplex=null,this._enabled=!1},h.prototype.disable=function(){return this._enabled=!1,this},h.prototype.enable=function(){return this._enabled=!0,this},h.version="3.0.0","undefined"!=typeof n?("undefined"!=typeof r&&r.exports&&(n=r.exports=h),n.Emitter=h):"function"==typeof t&&t.amd?t("emmett",[],function(){return h}):this.Emitter=h}).call(this)},{}],4:[function(t,e,r){function n(t){return t+"$"+(new Date).getTime()+(""+Math.random()).replace("0.","")}function o(t,e){function r(t){this[t]=function(){var e=this.root[t].apply(this.root,arguments);return e instanceof i?this:e}}if(arguments.length<1&&(t={}),!(this instanceof o))return new o(t,e);if(!p.Object(t)&&!p.Array(t))throw Error("Baobab: invalid data.");if(s.call(this),this.options=u.shallowMerge(f,e),this._transaction={},this._future=void 0,this._cursors={},this._identity="[object Baobab]",this.data=u.deepClone(t),this.root=this.select([]),this.facets={},["get","set","unset","update"].forEach(r.bind(this)),!p.Object(this.options.facets))throw Error("Baobab: invalid facets.");for(var n in this.options.facets)this.addFacet(n,this.options.facets[n])}var i=t("./cursor.js"),s=t("emmett"),a=t("./watcher.js"),h=t("./facet.js"),u=t("./helpers.js"),c=t("./update.js"),l=t("./merge.js"),f=t("../defaults.js"),p=t("./type.js");u.inherits(o,s),o.prototype.addFacet=function(t,e){return this.facets[t]=this.createFacet(e),this},o.prototype.createFacet=function(t){return new h(this,t)},o.prototype.select=function(t){if(!t)throw Error("Baobab.select: invalid path.");if(arguments.length>1&&(t=u.arrayOf(arguments)),!p.Path(t))throw Error("Baobab.select: invalid path.");t=[].concat(t);var e,r=p.ComplexPath(t);r&&(e=u.solvePath(this.data,t,this));var o=t.map(function(t){return p.Function(t)?n("fn"):p.Object(t)?n("ob"):t}).join("|λ|");if(this._cursors[o])return this._cursors[o];var s=new i(this,t,e,o);return this._cursors[o]=s,s},o.prototype.stack=function(t){var e=this;if(!p.Object(t))throw Error("Baobab.update: wrong specification.");return this._transaction=l(t,this._transaction),this.options.autoCommit?this.options.asynchronous?(this._future||(this._future=setTimeout(e.commit.bind(e,null),0)),this):this.commit():this},o.prototype.commit=function(){var t=c(this.data,this._transaction,this.options),e=this.data;this._transaction={},this._future&&(this._future=clearTimeout(this._future));var r=this.options.validate,n=this.options.validationBehaviour;if("function"==typeof r){var o=r.call(this,e,t.data,t.log);if(o instanceof Error&&(this.emit("invalid",{error:o}),"rollback"===n))return this}return this.data=t.data,this.emit("update",{log:t.log,previousState:e}),this},o.prototype.watch=function(t){if(!p.Array(t)||t.some(function(t){return!p.Path(t)}))throw Error("Baobab.watch: invalid paths.");return new a(this,[].concat(t))},o.prototype.release=function(){var t;delete this.data,delete this._transaction;for(t in this._cursors)this._cursors[t].release();delete this._cursors;for(t in this.facets)this.facets[t].release();delete this.facets,this.kill()},o.prototype.toJSON=function(){return this.get()},o.prototype.toString=function(){return this._identity},e.exports=o},{"../defaults.js":2,"./cursor.js":5,"./facet.js":6,"./helpers.js":7,"./merge.js":8,"./type.js":9,"./update.js":10,"./watcher.js":11,emmett:3}],5:[function(t,e,r){function n(t,e,r,n){function o(t){if(i.isRecording()&&!i.undoing){var e=a.getIn(t,i.solvedPath,i.tree),r=a.deepClone(e);i.archive.add(r)}return i.undoing=!1,i.emit("update")}var i=this;s.call(this),e=e||[],this.tree=t,this.path=e,this.hash=n,this.archive=null,this.undoing=!1,this._identity="[object Cursor]",this.complexPath=!!r,this.solvedPath=this.complexPath?r:this.path,this.relevant=void 0!==this.get(),this.updateHandler=function(t){var e=t.data.log,r=t.data.previousState,n=!1;if(i.complexPath&&(i.solvedPath=a.solvePath(i.tree.data,i.path,i.tree)),!i.path.length)return o(r);i.solvedPath&&(n=a.solveUpdate(e,[i.solvedPath]));var s=void 0!==i.get();i.relevant?s&&n?o(r):s||(i.emit("irrelevant"),i.relevant=!1):s&&n&&(i.emit("relevant"),o(r),i.relevant=!0)};var h=!1;this._lazyBind=function(){h||(h=!0,i.tree.on("update",i.updateHandler))},this.on=a.before(this._lazyBind,this.on.bind(this)),this.once=a.before(this._lazyBind,this.once.bind(this)),this.complexPath&&this._lazyBind()}function o(t,e,r,n){if(arguments.length>5)throw Error("baobab.Cursor."+t+": too many arguments.");arguments.length<4&&(n=r,r=[]),r=r||[];var o=[].concat(r),i=a.solvePath(this.get(),o,this.tree);if(!i)throw Error("baobab.Cursor."+t+": could not solve dynamic path.");if(e){var s=this.get(i);if(!h[e](s))throw Error("baobab.Cursor."+t+": invalid target.")}var u={};u["$"+t]=n;var c=a.pathObject(i,u);return c}function i(t,e){n.prototype[t]=function(){var r=o.bind(this,t,e).apply(this,arguments);return this.update(r)}}var s=t("emmett"),a=t("./helpers.js"),h=(t("../defaults.js"),t("./type.js"));a.inherits(n,s),n.prototype.isRoot=function(){return!this.path.length},n.prototype.isLeaf=function(){return h.Primitive(this.get())},n.prototype.isBranch=function(){return!this.isLeaf()&&!this.isRoot()},n.prototype.root=function(){return this.tree.root()},n.prototype.select=function(t){if(arguments.length>1&&(t=a.arrayOf(arguments)),!h.Path(t))throw Error("baobab.Cursor.select: invalid path.");return this.tree.select(this.path.concat(t))},n.prototype.up=function(){return this.solvedPath&&this.solvedPath.length?this.tree.select(this.path.slice(0,-1)):null},n.prototype.left=function(){var t=+this.solvedPath[this.solvedPath.length-1];if(isNaN(t))throw Error("baobab.Cursor.left: cannot go left on a non-list type.");return t?this.tree.select(this.solvedPath.slice(0,-1).concat(t-1)):null},n.prototype.leftmost=function(){var t=+this.solvedPath[this.solvedPath.length-1];if(isNaN(t))throw Error("baobab.Cursor.leftmost: cannot go left on a non-list type.");return this.tree.select(this.solvedPath.slice(0,-1).concat(0))},n.prototype.right=function(){var t=+this.solvedPath[this.solvedPath.length-1];if(isNaN(t))throw Error("baobab.Cursor.right: cannot go right on a non-list type.");return t+1===this.up().get().length?null:this.tree.select(this.solvedPath.slice(0,-1).concat(t+1))},n.prototype.rightmost=function(){var t=+this.solvedPath[this.solvedPath.length-1];if(isNaN(t))throw Error("baobab.Cursor.right: cannot go right on a non-list type.");var e=this.up().get();return this.tree.select(this.solvedPath.slice(0,-1).concat(e.length-1))},n.prototype.down=function(){+this.solvedPath[this.solvedPath.length-1];return this.get()instanceof Array?this.tree.select(this.solvedPath.concat(0)):null},n.prototype.get=function(t){arguments.length>1&&(t=a.arrayOf(arguments));var e=this.solvedPath.concat([].concat(t||0===t?t:[]));return a.getIn(this.tree.data,e,this.tree)},i("set"),i("apply"),i("chain"),i("push","Array"),i("unshift","Array"),n.prototype.merge=function(t){if(!h.Object(t))throw Error("baobab.Cursor.merge: trying to merge a non-object.");var e=o.bind(this,"merge","Object").apply(this,arguments);return this.update(e)},n.prototype.unset=function(t){if(void 0===t&&this.isRoot())throw Error("baobab.Cursor.unset: cannot remove root node.");var e=o.bind(this,"unset",null).apply(this,[t,!0]);return this.update(e)},n.prototype.update=function(t,e){if(arguments.length<2)return this.tree.stack(a.pathObject(this.solvedPath,t)),this;var r=[].concat(t),n=a.solvePath(this.get(),r,this.tree);if(!n)throw Error("baobab.Cursor.update: could not solve dynamic path.");return this.tree.stack(a.pathObject(this.solvedPath.concat(n),e)),this},n.prototype.startRecording=function(t){if(t=t||5,1>t)throw Error("baobab.Cursor.startRecording: invalid maximum number of records.");return this.archive?this:(this._lazyBind(),this.archive=a.archive(t),this)},n.prototype.stopRecording=function(){return this.archive=null,this},n.prototype.undo=function(t){if(t=t||1,!this.isRecording())throw Error("baobab.Cursor.undo: cursor is not recording.");if(!h.PositiveInteger(t))throw Error("baobab.Cursor.undo: expecting a positive integer.");var e=this.archive.back(t);if(!e)throw Error("boabab.Cursor.undo: cannot find a relevant record ("+t+" back).");return this.undoing=!0,this.set(e)},n.prototype.isRecording=function(){return!!this.archive},n.prototype.hasHistory=function(){return!(!this.archive||!this.archive.get().length)},n.prototype.getHistory=function(){return this.archive?this.archive.get():[]},n.prototype.release=function(){this.tree.off("update",this.updateHandler),this.hash&&delete this.tree._cursors[this.hash],delete this.tree,delete this.path,delete this.solvedPath,delete this.archive,this.kill()},n.prototype.toJSON=function(){return this.get()},n.prototype.toString=function(){return this._identity},e.exports=n},{"../defaults.js":2,"./helpers.js":7,"./type.js":9,emmett:3}],6:[function(t,e,r){function n(t){return t}function o(t,e){function r(t){o[t]=l[t].bind(l)}var o=this,s=null,a=!1,h=e.get||n,u=e.cursors,c=Object.keys(u).map(function(t){return u[t]}),l=new i(t,c);["on","once","release"].forEach(r),this.get=function(){if(a)return s;var e={};for(var r in u)e[r]=t.get(u[r]);return s=h.call(null,e),a=!0,s},this.on("update",function(){a=!1})}{var i=t("./watcher.js");t("./helpers.js")}e.exports=o},{"./helpers.js":7,"./watcher.js":11}],7:[function(t,e,r){(function(r){function n(t){return Array.prototype.slice.call(t)}function o(t,e){return function(){t(),e.apply(null,arguments)}}function i(t,e){var r,n={};for(r in t)n[r]=t[r];for(r in e)n[r]=e[r];return n}function s(t){var e=t.source,r="";return t.global&&(r+="g"),t.multiline&&(r+="m"),t.ignoreCase&&(r+="i"),t.sticky&&(r+="y"),t.unicode&&(r+="u"),new RegExp(e,r)}function a(t,e){if(!e||"object"!=typeof e||e instanceof Error||"ArrayBuffer"in r&&e instanceof ArrayBuffer)return e;if(w.Array(e)){if(t){var n,o,i=[];for(n=0,o=e.length;o>n;n++)i.push($(e[n]));return i}return e.slice(0)}if(w.Date(e))return new Date(e.getTime());if(e instanceof RegExp)return s(e);if(w.Object(e)){var a,h={};e.constructor&&e.constructor!==Object&&(h=Object.create(e.constructor.prototype));for(a in e)e.hasOwnProperty(a)&&(h[a]=t?$(e[a]):e[a]);return h}return e}function h(t,e){return function(r){return e(t(r))}}function u(t,e){var r,n;for(r=0,n=t.length;n>r;r++)if(e(t[r]))return t[r]}function c(t,e){var r,n;for(r=0,n=t.length;n>r;r++)if(e(t[r]))return r;return-1}function l(t,e){var r,n=!0;if(!t)return!1;for(r in e)if(w.Object(e[r]))n=n&&l(t[r],e[r]);else if(w.Array(e[r]))n=n&&!!~e[r].indexOf(t[r]);else if(t[r]!==e[r])return!1;return n}function f(t,e){return u(t,function(t){return l(t,e)})}function d(t,e){return c(t,function(t){return l(t,e)})}function y(t,e,r){e=e||[];var n,o,i,s=t;for(o=0,i=e.length;i>o;o++){if(!s)return;if("function"==typeof e[o]){if(!w.Array(s))return;s=u(s,e[o])}else if("object"==typeof e[o])if(r&&"$cursor"in e[o]){if(!w.Path(e[o].$cursor))throw Error("baobab.getIn: $cursor path must be an array.");n=r.get(e[o].$cursor),s=s[n]}else{if(!w.Array(s))return;s=f(s,e[o])}else s=s[e[o]]}return s}function v(t,e,r){var n,o,i,s=[],a=t;for(o=0,i=e.length;i>o;o++){if(!a)return null;if("function"==typeof e[o]){if(!w.Array(a))return;n=c(a,e[o]),s.push(n),a=a[n]}else if("object"==typeof e[o])if(r&&"$cursor"in e[o]){if(!w.Path(e[o].$cursor))throw Error("baobab.getIn: $cursor path must be an array.");p=r.get(e[o].$cursor),s.push(p),a=a[p]}else{if(!w.Array(a))return;n=d(a,e[o]),s.push(n),a=a[n]}else s.push(e[o]),a=a[e[o]]||{}}return s}function g(t,e){var r,n,o,i,s,a,h,u,c;for(r=0,i=e.length;i>r;r++)for(h=e[r],n=0,s=t.length;s>n;n++)for(u=t[n],o=0,a=u.length;a>o&&(c=u[o],c==h[o]);o++)if(o+1===a||o+1===h.length)return!0;return!1}function b(t,e){var r,n=t.length,o={},i=o;for(n||(o=e),r=0;n>r;r++)i[t[r]]=r+1===n?e:{},i=i[t[r]];return o}function m(t,e){t.super_=e;var r=function(){};r.prototype=e.prototype,t.prototype=new r,t.prototype.constructor=t}function j(t){var e=[];return{add:function(r){e.unshift(r),e.length>t&&(e.length=t)},back:function(t){var r=e[t-1];return r&&(e=e.slice(t)),r},get:function(){return e}}}var w=t("./type.js"),_=a.bind(null,!1),$=a.bind(null,!0);e.exports={archive:j,arrayOf:n,before:o,deepClone:$,shallowClone:_,shallowMerge:i,compose:h,getIn:y,inherits:m,pathObject:b,solvePath:v,solveUpdate:g}}).call(this,"undefined"!=typeof global?global:"undefined"!=typeof self?self:"undefined"!=typeof window?window:{})},{"./type.js":9}],8:[function(t,e,r){function n(t,e,r){a.forEach(function(e){r!==e&&delete t[e]}),t[r]=e[r]}function o(t,e){var r,h=i.shallowClone(e||{});a.forEach(function(e){t[e]&&n(h,t,e)}),t.$chain&&(a.slice(0,-1).forEach(function(t){delete h[t]}),h.$apply=h.$apply?i.compose(h.$apply,t.$chain):t.$chain),t.$push&&h.$push?h.$push=s.Array(h.$push)?h.$push.concat(t.$push):[h.$push].concat(t.$push):t.$push&&(h.$push=t.$push),t.$unshift&&h.$unshift?h.$unshift=s.Array(t.$unshift)?t.$unshift.concat(h.$unshift):[t.$unshift].concat(h.$unshift):t.$unshift&&(h.$unshift=t.$unshift);for(r in t)s.Object(t[r])?h[r]=o(t[r],h[r]):"$"!==r[0]&&(h[r]=t[r]);return h}var i=t("./helpers.js"),s=t("./type.js"),a=["$unset","$set","$merge","$apply"];e.exports=o},{"./helpers.js":7,"./type.js":9}],9:[function(t,e,r){function n(t,e){return e.some(function(e){return o[e](t)})}var o={};o.Array=function(t){return Array.isArray(t)},o.Object=function(t){return t&&"object"==typeof t&&!Array.isArray(t)&&!(t instanceof Function)},o.String=function(t){return"string"==typeof t},o.Number=function(t){return"number"==typeof t},o.PositiveInteger=function(t){return"number"==typeof t&&t>0&&t%1===0},o.Function=function(t){return"function"==typeof t},o.Primitive=function(t){return"string"==typeof t||"number"==typeof t||"boolean"==typeof t},o.Date=function(t){return t instanceof Date},o.NonScalar=function(t){return o.Object(t)||o.Array(t)},o.Path=function(t){var e=["String","Number","Function","Object"];return o.Array(t)?t.every(function(t){return n(t,e)}):n(t,e)},o.MixinCursor=function(t){return n(t,["String","Number","Array","Function","Cursor"])},o.MixinCursors=function(t){return n(t,["Object","Array","Function"])},o.ComplexPath=function(t){return t.some(function(t){return n(t,["Object","Function"])})},e.exports=o},{}],10:[function(t,e,r){function n(t,e){var r=new Error("baobab.update: "+e+" at path /"+t.slice(1).join("/"));return r.path=t,r}var o=t("./helpers.js"),i=t("./type.js");e.exports=function(t,e,r){if(r=r||{},!i.Object(t)&&!i.Array(t))throw Error("baobab.update: invalid target.");var s={};t={root:o.shallowClone(t)};var a=function(t,e,r,h){r=r||["root"];var u,c,l,f=r.join("|λ|"),p=r[r.length-1],d=Object.keys(e).some(function(t){return!!~["$unset","$set","$apply","$merge","$push","$unshift"].indexOf(t)});if(d){s[f]=!0;for(c in e){if("$unset"===c){var y=r[r.length-2];i.Array(t)?h[y]=t.slice(0,+p).concat(t.slice(+p+1)):(h[y]=o.shallowClone(t),delete h[y][p]);break}if("$set"===c){l=e.$set,t[p]=l;break}if("$apply"===c){if(u=e.$apply,"function"!=typeof u)throw n(r,"using command $apply with a non function");t[p]=u.call(null,t[p]);break}if("$merge"===c){if(l=e.$merge,!i.Object(t[p])||!i.Object(l))throw n(r,"using command $merge with a non object");t[p]=o.shallowMerge(t[p],l);break}if("$push"===c){if(l=e.$push,!i.Array(t[p]))throw n(r,"using command $push to a non array");t[p]=t[p].concat(l)}if("$unshift"===c){if(l=e.$unshift,!i.Array(t[p]))throw n(r,"using command $unshift to a non array");t[p]=[].concat(l).concat(t[p])}}}else for(c in e)t[p][c]="undefined"==typeof t[p][c]?{}:o.shallowClone(t[p][c]),a(t[p],e[c],r.concat(c),t)};return a(t,e),{data:t.root,log:Object.keys(s).map(function(t){return t.split("|λ|").slice(1)})}}},{"./helpers.js":7,"./type.js":9}],11:[function(t,e,r){function n(t,e){function r(){h&&(a=e.map(function(t){return i.solvePath(n.tree.data,t,n.tree)}))}var n=this;o.call(this),this.tree=t;var a=e,h=e.some(s.ComplexPath);this.updateHandler=function(t){var e=i.solveUpdate(t.data.log,a);e&&n.emit("update")},r(),this.tree.on("update",this.updateHandler)}var o=t("emmett"),i=t("./helpers.js"),s=t("./type.js");i.inherits(n,o),n.prototype.release=function(){this.tree.off("update",this.updateHandler),this.tree=null,this.kill()},e.exports=n},{"./helpers.js":7,"./type.js":9,emmett:3}]},{},[1])(1)}); \ No newline at end of file +!function(t){if("object"==typeof exports&&"undefined"!=typeof module)module.exports=t();else if("function"==typeof define&&define.amd)define([],t);else{var e;e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:this,e.Baobab=t()}}(function(){var t;return function e(t,r,n){function o(s,a){if(!r[s]){if(!t[s]){var h="function"==typeof require&&require;if(!a&&h)return h(s,!0);if(i)return i(s,!0);var u=new Error("Cannot find module '"+s+"'");throw u.code="MODULE_NOT_FOUND",u}var c=r[s]={exports:{}};t[s][0].call(c.exports,function(e){var r=t[s][1][e];return o(r?r:e)},c,c.exports,e,t,r,n)}return r[s].exports}for(var i="function"==typeof require&&require,s=0;sn;n++)t[n].fn!==e&&o.push(t[n]);return o}var s={once:"boolean",scope:"object"},a=0,h=function(){this._enabled=!0,this.unbindAll()};h.prototype.unbindAll=function(){return this._handlers={},this._handlersAll=[],this._handlersComplex=[],this},h.prototype.on=function(t,e,r){var n,i,h,u,c,l,f;if(o(t)){for(u in t)this.on(u,t[u],e);return this}for("function"==typeof t&&(r=e,e=t,t=null),c=[].concat(t),n=0,i=c.length;i>n;n++){if(u=c[n],f={order:a++,fn:e},"string"==typeof u)this._handlers[u]||(this._handlers[u]=[]),l=this._handlers[u];else if(u instanceof RegExp)l=this._handlersComplex,f.pattern=u;else{if(null!==u)throw Error("Emitter.on: invalid event.");l=this._handlersAll}for(h in r||{})s[h]&&(f[h]=r[h]);f.once&&(f.parent=l),l.push(f)}return this},h.prototype.once=function(){var t=Array.prototype.slice.call(arguments),r=t.length-1;return o(t[r])&&t.length>1?t[r]=e(t[r],{once:!0}):t.push({once:!0}),this.on.apply(this,t)},h.prototype.off=function(t,e){var r,n,s,a;if(1===arguments.length&&"function"==typeof t){e=arguments[0];for(s in this._handlers)this._handlers[s]=i(this._handlers[s],e),0===this._handlers[s].length&&delete this._handlers[s];this._handlersAll=i(this._handlersAll,e),this._handlersComplex=i(this._handlersComplex,e)}else if(1===arguments.length&&"string"==typeof t)delete this._handlers[t];else if(2===arguments.length){var h=[].concat(t);for(r=0,n=h.length;n>r;r++)a=h[r],this._handlers[a]=i(this._handlers[a],e),0===(this._handlers[a]||[]).length&&delete this._handlers[a]}else if(o(t))for(s in t)this.off(s,t[s]);return this},h.prototype.listeners=function(t){var e,r,n,o=this._handlersAll||[],i=!1;if(!t)throw Error("Emitter.listeners: no event provided.");for(o=o.concat(this._handlers[t]||[]),r=0,n=this._handlersComplex.length;n>r;r++)e=this._handlersComplex[r],~t.search(e.pattern)&&(i=!0,o.push(e));return this._handlersAll.length||i?o.sort(function(t,e){return t.order-e.order}):o.slice(0)},h.prototype.emit=function(t,e){if(!this._enabled)return this;if(o(t)){for(var r in t)this.emit(r,t[r]);return this}var n,i,s,a,h,u,c,l=[].concat(t),f=[];for(a=0,u=l.length;u>a;a++){for(i=this.listeners(l[a]),h=0,c=i.length;c>h;h++)s=i[h],n={type:l[a],target:this},arguments.length>1&&(n.data=e),s.fn.call("scope"in s?s.scope:this,n),s.once&&f.push(s);for(h=f.length-1;h>=0;h--)f[h].parent.splice(f[h].parent.indexOf(f[h]),1)}return this},h.prototype.kill=function(){this.unbindAll(),this._handlers=null,this._handlersAll=null,this._handlersComplex=null,this._enabled=!1},h.prototype.disable=function(){return this._enabled=!1,this},h.prototype.enable=function(){return this._enabled=!0,this},h.version="3.0.0","undefined"!=typeof n?("undefined"!=typeof r&&r.exports&&(n=r.exports=h),n.Emitter=h):"function"==typeof t&&t.amd?t("emmett",[],function(){return h}):this.Emitter=h}).call(this)},{}],4:[function(t,e,r){function n(t){return t+"$"+(new Date).getTime()+(""+Math.random()).replace("0.","")}function o(t,e){function r(t){this[t]=function(){var e=this.root[t].apply(this.root,arguments);return e instanceof i?this:e}}if(arguments.length<1&&(t={}),!(this instanceof o))return new o(t,e);if(!p.Object(t)&&!p.Array(t))throw Error("Baobab: invalid data.");if(s.call(this),this.options=u.shallowMerge(f,e),this._transaction={},this._future=void 0,this._cursors={},this._identity="[object Baobab]",this.data=u.deepClone(t),this.root=this.select([]),this.facets={},["get","set","unset","update"].forEach(r.bind(this)),!p.Object(this.options.facets))throw Error("Baobab: invalid facets.");for(var n in this.options.facets)this.addFacet(n,this.options.facets[n])}var i=t("./cursor.js"),s=t("emmett"),a=t("./watcher.js"),h=t("./facet.js"),u=t("./helpers.js"),c=t("./update.js"),l=t("./merge.js"),f=t("../defaults.js"),p=t("./type.js");u.inherits(o,s),o.prototype.addFacet=function(t,e){return this.facets[t]=this.createFacet(e),this},o.prototype.createFacet=function(t){return new h(this,t)},o.prototype.select=function(t){if(!t)throw Error("Baobab.select: invalid path.");if(arguments.length>1&&(t=u.arrayOf(arguments)),!p.Path(t))throw Error("Baobab.select: invalid path.");t=[].concat(t);var e,r=p.ComplexPath(t);r&&(e=u.solvePath(this.data,t,this));var o=t.map(function(t){return p.Function(t)?n("fn"):p.Object(t)?n("ob"):t}).join("|λ|");if(this._cursors[o])return this._cursors[o];var s=new i(this,t,e,o);return this._cursors[o]=s,s},o.prototype.stack=function(t){var e=this;if(!p.Object(t))throw Error("Baobab.update: wrong specification.");return this._transaction=l(t,this._transaction),this.options.autoCommit?this.options.asynchronous?(this._future||(this._future=setTimeout(e.commit.bind(e,null),0)),this):this.commit():this},o.prototype.commit=function(){var t=c(this.data,this._transaction,this.options),e=this.data;this._transaction={},this._future&&(this._future=clearTimeout(this._future));var r=this.options.validate,n=this.options.validationBehaviour;if("function"==typeof r){var o=r.call(this,e,t.data,t.log);if(o instanceof Error&&(this.emit("invalid",{error:o}),"rollback"===n))return this}return this.data=t.data,this.emit("update",{log:t.log,previousState:e}),this},o.prototype.watch=function(t){if(!p.Array(t)||t.some(function(t){return!p.Path(t)}))throw Error("Baobab.watch: invalid paths.");return new a(this,[].concat(t))},o.prototype.release=function(){var t;delete this.data,delete this._transaction;for(t in this._cursors)this._cursors[t].release();delete this._cursors;for(t in this.facets)this.facets[t].release();delete this.facets,this.kill()},o.prototype.toJSON=function(){return this.get()},o.prototype.toString=function(){return this._identity},e.exports=o},{"../defaults.js":2,"./cursor.js":5,"./facet.js":6,"./helpers.js":7,"./merge.js":8,"./type.js":9,"./update.js":10,"./watcher.js":11,emmett:3}],5:[function(t,e,r){function n(t,e,r,n){function o(t){if(i.isRecording()&&!i.undoing){var e=a.getIn(t,i.solvedPath,i.tree),r=a.deepClone(e);i.archive.add(r)}return i.undoing=!1,i.emit("update")}var i=this;s.call(this),e=e||[],this.tree=t,this.path=e,this.hash=n,this.archive=null,this.undoing=!1,this._identity="[object Cursor]",this.complexPath=!!r,this.solvedPath=this.complexPath?r:this.path,this.relevant=void 0!==this.get(),this.updateHandler=function(t){var e=t.data.log,r=t.data.previousState,n=!1;if(i.complexPath&&(i.solvedPath=a.solvePath(i.tree.data,i.path,i.tree)),!i.path.length)return o(r);i.solvedPath&&(n=a.solveUpdate(e,[i.solvedPath]));var s=void 0!==i.get();i.relevant?s&&n?o(r):s||(i.emit("irrelevant"),i.relevant=!1):s&&n&&(i.emit("relevant"),o(r),i.relevant=!0)};var h=!1;this._lazyBind=function(){h||(h=!0,i.tree.on("update",i.updateHandler))},this.on=a.before(this._lazyBind,this.on.bind(this)),this.once=a.before(this._lazyBind,this.once.bind(this)),this.complexPath&&this._lazyBind()}function o(t,e,r,n){if(arguments.length>5)throw Error("baobab.Cursor."+t+": too many arguments.");arguments.length<4&&(n=r,r=[]),r=r||[];var o=[].concat(r),i=a.solvePath(this.get(),o,this.tree);if(!i)throw Error("baobab.Cursor."+t+": could not solve dynamic path.");if(e){var s=this.get(i);if(!h[e](s))throw Error("baobab.Cursor."+t+": invalid target.")}var u={};u["$"+t]=n;var c=a.pathObject(i,u);return c}function i(t,e){n.prototype[t]=function(){var r=o.bind(this,t,e).apply(this,arguments);return this.update(r)}}var s=t("emmett"),a=t("./helpers.js"),h=(t("../defaults.js"),t("./type.js"));a.inherits(n,s),n.prototype.isRoot=function(){return!this.path.length},n.prototype.isLeaf=function(){return h.Primitive(this.get())},n.prototype.isBranch=function(){return!this.isLeaf()&&!this.isRoot()},n.prototype.root=function(){return this.tree.root()},n.prototype.select=function(t){if(arguments.length>1&&(t=a.arrayOf(arguments)),!h.Path(t))throw Error("baobab.Cursor.select: invalid path.");return this.tree.select(this.path.concat(t))},n.prototype.up=function(){return this.solvedPath&&this.solvedPath.length?this.tree.select(this.path.slice(0,-1)):null},n.prototype.left=function(){var t=+this.solvedPath[this.solvedPath.length-1];if(isNaN(t))throw Error("baobab.Cursor.left: cannot go left on a non-list type.");return t?this.tree.select(this.solvedPath.slice(0,-1).concat(t-1)):null},n.prototype.leftmost=function(){var t=+this.solvedPath[this.solvedPath.length-1];if(isNaN(t))throw Error("baobab.Cursor.leftmost: cannot go left on a non-list type.");return this.tree.select(this.solvedPath.slice(0,-1).concat(0))},n.prototype.right=function(){var t=+this.solvedPath[this.solvedPath.length-1];if(isNaN(t))throw Error("baobab.Cursor.right: cannot go right on a non-list type.");return t+1===this.up().get().length?null:this.tree.select(this.solvedPath.slice(0,-1).concat(t+1))},n.prototype.rightmost=function(){var t=+this.solvedPath[this.solvedPath.length-1];if(isNaN(t))throw Error("baobab.Cursor.right: cannot go right on a non-list type.");var e=this.up().get();return this.tree.select(this.solvedPath.slice(0,-1).concat(e.length-1))},n.prototype.down=function(){+this.solvedPath[this.solvedPath.length-1];return this.get()instanceof Array?this.tree.select(this.solvedPath.concat(0)):null},n.prototype.get=function(t){arguments.length>1&&(t=a.arrayOf(arguments));var e=this.solvedPath.concat([].concat(t||0===t?t:[]));return a.getIn(this.tree.data,e,this.tree)},i("set"),i("apply"),i("chain"),i("push","Array"),i("unshift","Array"),n.prototype.merge=function(t){if(!h.Object(t))throw Error("baobab.Cursor.merge: trying to merge a non-object.");var e=o.bind(this,"merge","Object").apply(this,arguments);return this.update(e)},n.prototype.unset=function(t){if(void 0===t&&this.isRoot())throw Error("baobab.Cursor.unset: cannot remove root node.");var e=o.bind(this,"unset",null).apply(this,[t,!0]);return this.update(e)},n.prototype.update=function(t,e){if(arguments.length<2)return this.tree.stack(a.pathObject(this.solvedPath,t)),this;var r=[].concat(t),n=a.solvePath(this.get(),r,this.tree);if(!n)throw Error("baobab.Cursor.update: could not solve dynamic path.");return this.tree.stack(a.pathObject(this.solvedPath.concat(n),e)),this},n.prototype.startRecording=function(t){if(t=t||5,1>t)throw Error("baobab.Cursor.startRecording: invalid maximum number of records.");return this.archive?this:(this._lazyBind(),this.archive=a.archive(t),this)},n.prototype.stopRecording=function(){return this.archive=null,this},n.prototype.undo=function(t){if(t=t||1,!this.isRecording())throw Error("baobab.Cursor.undo: cursor is not recording.");if(!h.PositiveInteger(t))throw Error("baobab.Cursor.undo: expecting a positive integer.");var e=this.archive.back(t);if(!e)throw Error("boabab.Cursor.undo: cannot find a relevant record ("+t+" back).");return this.undoing=!0,this.set(e)},n.prototype.isRecording=function(){return!!this.archive},n.prototype.hasHistory=function(){return!(!this.archive||!this.archive.get().length)},n.prototype.getHistory=function(){return this.archive?this.archive.get():[]},n.prototype.release=function(){this.tree.off("update",this.updateHandler),this.hash&&delete this.tree._cursors[this.hash],delete this.tree,delete this.path,delete this.solvedPath,delete this.archive,this.kill()},n.prototype.toJSON=function(){return this.get()},n.prototype.toString=function(){return this._identity},e.exports=n},{"../defaults.js":2,"./helpers.js":7,"./type.js":9,emmett:3}],6:[function(t,e,r){function n(t){return t}function o(t,e){function r(t){o[t]=l[t].bind(l)}var o=this,s=null,a=!1,h=e.get||n,u=e.cursors,c=Object.keys(u).map(function(t){return u[t]}),l=new i(t,c);["on","once","release"].forEach(r),this.get=function(){if(a)return s;var e={};for(var r in u)e[r]=t.get(u[r]);return s=h.call(null,e),a=!0,s},this.on("update",function(){a=!1})}{var i=t("./watcher.js");t("./helpers.js")}e.exports=o},{"./helpers.js":7,"./watcher.js":11}],7:[function(t,e,r){(function(r){function n(t){return Array.prototype.slice.call(t)}function o(t,e){return function(){t(),e.apply(null,arguments)}}function i(t,e,r){var o=n(arguments).slice(3);return e=+e,r=+r,t.slice(0,e).concat(t.slice(e+r).concat(o))}function s(t,e){var r,n={};for(r in t)n[r]=t[r];for(r in e)n[r]=e[r];return n}function a(t){var e=t.source,r="";return t.global&&(r+="g"),t.multiline&&(r+="m"),t.ignoreCase&&(r+="i"),t.sticky&&(r+="y"),t.unicode&&(r+="u"),new RegExp(e,r)}function h(t,e){if(!e||"object"!=typeof e||e instanceof Error||"ArrayBuffer"in r&&e instanceof ArrayBuffer)return e;if(_.Array(e)){if(t){var n,o,i=[];for(n=0,o=e.length;o>n;n++)i.push(P(e[n]));return i}return e.slice(0)}if(_.Date(e))return new Date(e.getTime());if(e instanceof RegExp)return a(e);if(_.Object(e)){var s,h={};e.constructor&&e.constructor!==Object&&(h=Object.create(e.constructor.prototype));for(s in e)e.hasOwnProperty(s)&&(h[s]=t?P(e[s]):e[s]);return h}return e}function u(t,e){return function(r){return e(t(r))}}function c(t,e){var r,n;for(r=0,n=t.length;n>r;r++)if(e(t[r]))return t[r]}function l(t,e){var r,n;for(r=0,n=t.length;n>r;r++)if(e(t[r]))return r;return-1}function f(t,e){var r,n=!0;if(!t)return!1;for(r in e)if(_.Object(e[r]))n=n&&f(t[r],e[r]);else if(_.Array(e[r]))n=n&&!!~e[r].indexOf(t[r]);else if(t[r]!==e[r])return!1;return n}function d(t,e){return c(t,function(t){return f(t,e)})}function y(t,e){return l(t,function(t){return f(t,e)})}function v(t,e,r){e=e||[];var n,o,i,s=t;for(o=0,i=e.length;i>o;o++){if(!s)return;if("function"==typeof e[o]){if(!_.Array(s))return;s=c(s,e[o])}else if("object"==typeof e[o])if(r&&"$cursor"in e[o]){if(!_.Path(e[o].$cursor))throw Error("baobab.getIn: $cursor path must be an array.");n=r.get(e[o].$cursor),s=s[n]}else{if(!_.Array(s))return;s=d(s,e[o])}else s=s[e[o]]}return s}function g(t,e,r){var n,o,i,s=[],a=t;for(o=0,i=e.length;i>o;o++){if(!a)return null;if("function"==typeof e[o]){if(!_.Array(a))return;n=l(a,e[o]),s.push(n),a=a[n]}else if("object"==typeof e[o])if(r&&"$cursor"in e[o]){if(!_.Path(e[o].$cursor))throw Error("baobab.getIn: $cursor path must be an array.");p=r.get(e[o].$cursor),s.push(p),a=a[p]}else{if(!_.Array(a))return;n=y(a,e[o]),s.push(n),a=a[n]}else s.push(e[o]),a=a[e[o]]||{}}return s}function b(t,e){var r,n,o,i,s,a,h,u,c;for(r=0,i=e.length;i>r;r++)for(h=e[r],n=0,s=t.length;s>n;n++)for(u=t[n],o=0,a=u.length;a>o&&(c=u[o],c==h[o]);o++)if(o+1===a||o+1===h.length)return!0;return!1}function m(t,e){var r,n=t.length,o={},i=o;for(n||(o=e),r=0;n>r;r++)i[t[r]]=r+1===n?e:{},i=i[t[r]];return o}function j(t,e){t.super_=e;var r=function(){};r.prototype=e.prototype,t.prototype=new r,t.prototype.constructor=t}function w(t){var e=[];return{add:function(r){e.unshift(r),e.length>t&&(e.length=t)},back:function(t){var r=e[t-1];return r&&(e=e.slice(t)),r},get:function(){return e}}}var _=t("./type.js"),$=h.bind(null,!1),P=h.bind(null,!0);e.exports={archive:w,arrayOf:n,before:o,deepClone:P,shallowClone:$,shallowMerge:s,compose:u,getIn:v,inherits:j,pathObject:m,solvePath:g,solveUpdate:b,splice:i}}).call(this,"undefined"!=typeof global?global:"undefined"!=typeof self?self:"undefined"!=typeof window?window:{})},{"./type.js":9}],8:[function(t,e,r){function n(t,e,r){a.forEach(function(e){r!==e&&delete t[e]}),t[r]=e[r]}function o(t,e){var r,h=i.shallowClone(e||{});a.forEach(function(e){t[e]&&n(h,t,e)}),t.$chain&&(a.slice(0,-1).forEach(function(t){delete h[t]}),h.$apply=h.$apply?i.compose(h.$apply,t.$chain):t.$chain),t.$push&&h.$push?h.$push=s.Array(h.$push)?h.$push.concat(t.$push):[h.$push].concat(t.$push):t.$push&&(h.$push=t.$push),t.$unshift&&h.$unshift?h.$unshift=s.Array(t.$unshift)?t.$unshift.concat(h.$unshift):[t.$unshift].concat(h.$unshift):t.$unshift&&(h.$unshift=t.$unshift);for(r in t)s.Object(t[r])?h[r]=o(t[r],h[r]):"$"!==r[0]&&(h[r]=t[r]);return h}var i=t("./helpers.js"),s=t("./type.js"),a=["$unset","$set","$merge","$apply"];e.exports=o},{"./helpers.js":7,"./type.js":9}],9:[function(t,e,r){function n(t,e){return e.some(function(e){return o[e](t)})}var o={};o.Array=function(t){return Array.isArray(t)},o.Object=function(t){return t&&"object"==typeof t&&!Array.isArray(t)&&!(t instanceof Function)},o.String=function(t){return"string"==typeof t},o.Number=function(t){return"number"==typeof t},o.PositiveInteger=function(t){return"number"==typeof t&&t>0&&t%1===0},o.Function=function(t){return"function"==typeof t},o.Primitive=function(t){return"string"==typeof t||"number"==typeof t||"boolean"==typeof t},o.Date=function(t){return t instanceof Date},o.NonScalar=function(t){return o.Object(t)||o.Array(t)},o.Path=function(t){var e=["String","Number","Function","Object"];return o.Array(t)?t.every(function(t){return n(t,e)}):n(t,e)},o.MixinCursor=function(t){return n(t,["String","Number","Array","Function","Cursor"])},o.MixinCursors=function(t){return n(t,["Object","Array","Function"])},o.ComplexPath=function(t){return t.some(function(t){return n(t,["Object","Function"])})},e.exports=o},{}],10:[function(t,e,r){function n(t,e){var r=new Error("baobab.update: "+e+" at path /"+t.slice(1).join("/"));return r.path=t,r}var o=t("./helpers.js"),i=t("./type.js");e.exports=function(t,e,r){if(r=r||{},!i.Object(t)&&!i.Array(t))throw Error("baobab.update: invalid target.");var s={};t={root:o.shallowClone(t)};var a=function(t,e,r,h){r=r||["root"];var u,c,l,f=r.join("|λ|"),p=r[r.length-1],d=Object.keys(e).some(function(t){return!!~["$unset","$set","$apply","$merge","$push","$unshift"].indexOf(t)});if(d){s[f]=!0;for(c in e){if("$unset"===c){var y=r[r.length-2];i.Array(t)?h[y]=o.splice(h[y],+p,1):(h[y]=o.shallowClone(t),delete h[y][p]);break}if("$set"===c){l=e.$set,t[p]=l;break}if("$apply"===c){if(u=e.$apply,"function"!=typeof u)throw n(r,"using command $apply with a non function");t[p]=u.call(null,t[p]);break}if("$merge"===c){if(l=e.$merge,!i.Object(t[p])||!i.Object(l))throw n(r,"using command $merge with a non object");t[p]=o.shallowMerge(t[p],l);break}if("$push"===c){if(l=e.$push,!i.Array(t[p]))throw n(r,"using command $push to a non array");t[p]=t[p].concat(l)}if("$unshift"===c){if(l=e.$unshift,!i.Array(t[p]))throw n(r,"using command $unshift to a non array");t[p]=[].concat(l).concat(t[p])}}}else for(c in e)t[p][c]="undefined"==typeof t[p][c]?{}:o.shallowClone(t[p][c]),a(t[p],e[c],r.concat(c),t)};return a(t,e),{data:t.root,log:Object.keys(s).map(function(t){return t.split("|λ|").slice(1)})}}},{"./helpers.js":7,"./type.js":9}],11:[function(t,e,r){function n(t,e){function r(){h&&(a=e.map(function(t){return i.solvePath(n.tree.data,t,n.tree)}))}var n=this;o.call(this),this.tree=t;var a=e,h=e.some(s.ComplexPath);this.updateHandler=function(t){var e=i.solveUpdate(t.data.log,a);e&&n.emit("update")},r(),this.tree.on("update",this.updateHandler)}var o=t("emmett"),i=t("./helpers.js"),s=t("./type.js");i.inherits(n,o),n.prototype.release=function(){this.tree.off("update",this.updateHandler),this.tree=null,this.kill()},e.exports=n},{"./helpers.js":7,"./type.js":9,emmett:3}]},{},[1])(1)}); \ No newline at end of file diff --git a/src/helpers.js b/src/helpers.js index 9d1adbc..381f5a7 100644 --- a/src/helpers.js +++ b/src/helpers.js @@ -19,6 +19,18 @@ function before(decorator, fn) { }; } +// Non-mutative splice function +function splice(array, index, nb /* &elements */) { + var elements = arrayOf(arguments).slice(3); + + index = +index; + nb = +nb; + + return array + .slice(0, index) + .concat(array.slice(index + nb).concat(elements)); +} + // Shallow merge function shallowMerge(o1, o2) { var o = {}, @@ -348,5 +360,6 @@ module.exports = { inherits: inherits, pathObject: pathObject, solvePath: solvePath, - solveUpdate: solveUpdate + solveUpdate: solveUpdate, + splice: splice }; diff --git a/src/update.js b/src/update.js index 1075df2..8db6afc 100644 --- a/src/update.js +++ b/src/update.js @@ -52,7 +52,7 @@ module.exports = function(data, spec, opts) { var olderKey = path[path.length - 2]; if (type.Array(o)) { - parent[olderKey] = o.slice(0, +lastKey).concat(o.slice(+lastKey + 1)); + parent[olderKey] = helpers.splice(parent[olderKey], +lastKey, 1); } else { parent[olderKey] = helpers.shallowClone(o); diff --git a/test/suites/helpers.js b/test/suites/helpers.js index 00a946d..4aa908a 100644 --- a/test/suites/helpers.js +++ b/test/suites/helpers.js @@ -10,6 +10,59 @@ var assert = require('assert'), describe('Helpers', function() { + describe('Splice', function() { + var splice = helpers.splice; + + it('should work in a non-mutative fashion.', function() { + var array = ['yellow', 'blue', 'purple']; + + assert.deepEqual( + splice(array, 0, 0), + array + ); + + assert.deepEqual( + splice(array, 0, 1), + ['blue', 'purple'] + ); + + assert.deepEqual( + splice(array, 1, 1), + ['yellow', 'purple'] + ); + + assert.deepEqual( + splice(array, 2, 1), + ['yellow', 'blue'] + ); + + assert.deepEqual( + splice(array, 2, 0), + array + ); + + assert.deepEqual( + splice(array, 1, 2), + ['yellow'] + ); + + assert.deepEqual( + splice(array, 2, 1, 'orange', 'gold'), + ['yellow', 'blue', 'orange', 'gold'] + ); + + assert.deepEqual( + splice(array, 5, 3), + array + ); + + assert.deepEqual( + splice(array, 5, 3, 'orange', 'gold'), + ['yellow', 'blue', 'purple', 'orange', 'gold'] + ); + }); + }); + describe('Composition', function() { it('should be able to compose two simple functions.', function() { From 3b14257991f56473854ca96338ba4bf94be63ce3 Mon Sep 17 00:00:00 2001 From: Yomguithereal Date: Thu, 16 Apr 2015 14:18:11 +0200 Subject: [PATCH 57/73] Refactoring $push and $unshift merging --- build/baobab.min.js | 2 +- src/helpers.js | 2 +- src/merge.js | 20 ++++---------------- 3 files changed, 6 insertions(+), 18 deletions(-) diff --git a/build/baobab.min.js b/build/baobab.min.js index 82540e6..99de643 100644 --- a/build/baobab.min.js +++ b/build/baobab.min.js @@ -1,2 +1,2 @@ /* baobab.js - Version: 1.0.0-rc1 - Author: Yomguithereal (Guillaume Plique) */ -!function(t){if("object"==typeof exports&&"undefined"!=typeof module)module.exports=t();else if("function"==typeof define&&define.amd)define([],t);else{var e;e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:this,e.Baobab=t()}}(function(){var t;return function e(t,r,n){function o(s,a){if(!r[s]){if(!t[s]){var h="function"==typeof require&&require;if(!a&&h)return h(s,!0);if(i)return i(s,!0);var u=new Error("Cannot find module '"+s+"'");throw u.code="MODULE_NOT_FOUND",u}var c=r[s]={exports:{}};t[s][0].call(c.exports,function(e){var r=t[s][1][e];return o(r?r:e)},c,c.exports,e,t,r,n)}return r[s].exports}for(var i="function"==typeof require&&require,s=0;sn;n++)t[n].fn!==e&&o.push(t[n]);return o}var s={once:"boolean",scope:"object"},a=0,h=function(){this._enabled=!0,this.unbindAll()};h.prototype.unbindAll=function(){return this._handlers={},this._handlersAll=[],this._handlersComplex=[],this},h.prototype.on=function(t,e,r){var n,i,h,u,c,l,f;if(o(t)){for(u in t)this.on(u,t[u],e);return this}for("function"==typeof t&&(r=e,e=t,t=null),c=[].concat(t),n=0,i=c.length;i>n;n++){if(u=c[n],f={order:a++,fn:e},"string"==typeof u)this._handlers[u]||(this._handlers[u]=[]),l=this._handlers[u];else if(u instanceof RegExp)l=this._handlersComplex,f.pattern=u;else{if(null!==u)throw Error("Emitter.on: invalid event.");l=this._handlersAll}for(h in r||{})s[h]&&(f[h]=r[h]);f.once&&(f.parent=l),l.push(f)}return this},h.prototype.once=function(){var t=Array.prototype.slice.call(arguments),r=t.length-1;return o(t[r])&&t.length>1?t[r]=e(t[r],{once:!0}):t.push({once:!0}),this.on.apply(this,t)},h.prototype.off=function(t,e){var r,n,s,a;if(1===arguments.length&&"function"==typeof t){e=arguments[0];for(s in this._handlers)this._handlers[s]=i(this._handlers[s],e),0===this._handlers[s].length&&delete this._handlers[s];this._handlersAll=i(this._handlersAll,e),this._handlersComplex=i(this._handlersComplex,e)}else if(1===arguments.length&&"string"==typeof t)delete this._handlers[t];else if(2===arguments.length){var h=[].concat(t);for(r=0,n=h.length;n>r;r++)a=h[r],this._handlers[a]=i(this._handlers[a],e),0===(this._handlers[a]||[]).length&&delete this._handlers[a]}else if(o(t))for(s in t)this.off(s,t[s]);return this},h.prototype.listeners=function(t){var e,r,n,o=this._handlersAll||[],i=!1;if(!t)throw Error("Emitter.listeners: no event provided.");for(o=o.concat(this._handlers[t]||[]),r=0,n=this._handlersComplex.length;n>r;r++)e=this._handlersComplex[r],~t.search(e.pattern)&&(i=!0,o.push(e));return this._handlersAll.length||i?o.sort(function(t,e){return t.order-e.order}):o.slice(0)},h.prototype.emit=function(t,e){if(!this._enabled)return this;if(o(t)){for(var r in t)this.emit(r,t[r]);return this}var n,i,s,a,h,u,c,l=[].concat(t),f=[];for(a=0,u=l.length;u>a;a++){for(i=this.listeners(l[a]),h=0,c=i.length;c>h;h++)s=i[h],n={type:l[a],target:this},arguments.length>1&&(n.data=e),s.fn.call("scope"in s?s.scope:this,n),s.once&&f.push(s);for(h=f.length-1;h>=0;h--)f[h].parent.splice(f[h].parent.indexOf(f[h]),1)}return this},h.prototype.kill=function(){this.unbindAll(),this._handlers=null,this._handlersAll=null,this._handlersComplex=null,this._enabled=!1},h.prototype.disable=function(){return this._enabled=!1,this},h.prototype.enable=function(){return this._enabled=!0,this},h.version="3.0.0","undefined"!=typeof n?("undefined"!=typeof r&&r.exports&&(n=r.exports=h),n.Emitter=h):"function"==typeof t&&t.amd?t("emmett",[],function(){return h}):this.Emitter=h}).call(this)},{}],4:[function(t,e,r){function n(t){return t+"$"+(new Date).getTime()+(""+Math.random()).replace("0.","")}function o(t,e){function r(t){this[t]=function(){var e=this.root[t].apply(this.root,arguments);return e instanceof i?this:e}}if(arguments.length<1&&(t={}),!(this instanceof o))return new o(t,e);if(!p.Object(t)&&!p.Array(t))throw Error("Baobab: invalid data.");if(s.call(this),this.options=u.shallowMerge(f,e),this._transaction={},this._future=void 0,this._cursors={},this._identity="[object Baobab]",this.data=u.deepClone(t),this.root=this.select([]),this.facets={},["get","set","unset","update"].forEach(r.bind(this)),!p.Object(this.options.facets))throw Error("Baobab: invalid facets.");for(var n in this.options.facets)this.addFacet(n,this.options.facets[n])}var i=t("./cursor.js"),s=t("emmett"),a=t("./watcher.js"),h=t("./facet.js"),u=t("./helpers.js"),c=t("./update.js"),l=t("./merge.js"),f=t("../defaults.js"),p=t("./type.js");u.inherits(o,s),o.prototype.addFacet=function(t,e){return this.facets[t]=this.createFacet(e),this},o.prototype.createFacet=function(t){return new h(this,t)},o.prototype.select=function(t){if(!t)throw Error("Baobab.select: invalid path.");if(arguments.length>1&&(t=u.arrayOf(arguments)),!p.Path(t))throw Error("Baobab.select: invalid path.");t=[].concat(t);var e,r=p.ComplexPath(t);r&&(e=u.solvePath(this.data,t,this));var o=t.map(function(t){return p.Function(t)?n("fn"):p.Object(t)?n("ob"):t}).join("|λ|");if(this._cursors[o])return this._cursors[o];var s=new i(this,t,e,o);return this._cursors[o]=s,s},o.prototype.stack=function(t){var e=this;if(!p.Object(t))throw Error("Baobab.update: wrong specification.");return this._transaction=l(t,this._transaction),this.options.autoCommit?this.options.asynchronous?(this._future||(this._future=setTimeout(e.commit.bind(e,null),0)),this):this.commit():this},o.prototype.commit=function(){var t=c(this.data,this._transaction,this.options),e=this.data;this._transaction={},this._future&&(this._future=clearTimeout(this._future));var r=this.options.validate,n=this.options.validationBehaviour;if("function"==typeof r){var o=r.call(this,e,t.data,t.log);if(o instanceof Error&&(this.emit("invalid",{error:o}),"rollback"===n))return this}return this.data=t.data,this.emit("update",{log:t.log,previousState:e}),this},o.prototype.watch=function(t){if(!p.Array(t)||t.some(function(t){return!p.Path(t)}))throw Error("Baobab.watch: invalid paths.");return new a(this,[].concat(t))},o.prototype.release=function(){var t;delete this.data,delete this._transaction;for(t in this._cursors)this._cursors[t].release();delete this._cursors;for(t in this.facets)this.facets[t].release();delete this.facets,this.kill()},o.prototype.toJSON=function(){return this.get()},o.prototype.toString=function(){return this._identity},e.exports=o},{"../defaults.js":2,"./cursor.js":5,"./facet.js":6,"./helpers.js":7,"./merge.js":8,"./type.js":9,"./update.js":10,"./watcher.js":11,emmett:3}],5:[function(t,e,r){function n(t,e,r,n){function o(t){if(i.isRecording()&&!i.undoing){var e=a.getIn(t,i.solvedPath,i.tree),r=a.deepClone(e);i.archive.add(r)}return i.undoing=!1,i.emit("update")}var i=this;s.call(this),e=e||[],this.tree=t,this.path=e,this.hash=n,this.archive=null,this.undoing=!1,this._identity="[object Cursor]",this.complexPath=!!r,this.solvedPath=this.complexPath?r:this.path,this.relevant=void 0!==this.get(),this.updateHandler=function(t){var e=t.data.log,r=t.data.previousState,n=!1;if(i.complexPath&&(i.solvedPath=a.solvePath(i.tree.data,i.path,i.tree)),!i.path.length)return o(r);i.solvedPath&&(n=a.solveUpdate(e,[i.solvedPath]));var s=void 0!==i.get();i.relevant?s&&n?o(r):s||(i.emit("irrelevant"),i.relevant=!1):s&&n&&(i.emit("relevant"),o(r),i.relevant=!0)};var h=!1;this._lazyBind=function(){h||(h=!0,i.tree.on("update",i.updateHandler))},this.on=a.before(this._lazyBind,this.on.bind(this)),this.once=a.before(this._lazyBind,this.once.bind(this)),this.complexPath&&this._lazyBind()}function o(t,e,r,n){if(arguments.length>5)throw Error("baobab.Cursor."+t+": too many arguments.");arguments.length<4&&(n=r,r=[]),r=r||[];var o=[].concat(r),i=a.solvePath(this.get(),o,this.tree);if(!i)throw Error("baobab.Cursor."+t+": could not solve dynamic path.");if(e){var s=this.get(i);if(!h[e](s))throw Error("baobab.Cursor."+t+": invalid target.")}var u={};u["$"+t]=n;var c=a.pathObject(i,u);return c}function i(t,e){n.prototype[t]=function(){var r=o.bind(this,t,e).apply(this,arguments);return this.update(r)}}var s=t("emmett"),a=t("./helpers.js"),h=(t("../defaults.js"),t("./type.js"));a.inherits(n,s),n.prototype.isRoot=function(){return!this.path.length},n.prototype.isLeaf=function(){return h.Primitive(this.get())},n.prototype.isBranch=function(){return!this.isLeaf()&&!this.isRoot()},n.prototype.root=function(){return this.tree.root()},n.prototype.select=function(t){if(arguments.length>1&&(t=a.arrayOf(arguments)),!h.Path(t))throw Error("baobab.Cursor.select: invalid path.");return this.tree.select(this.path.concat(t))},n.prototype.up=function(){return this.solvedPath&&this.solvedPath.length?this.tree.select(this.path.slice(0,-1)):null},n.prototype.left=function(){var t=+this.solvedPath[this.solvedPath.length-1];if(isNaN(t))throw Error("baobab.Cursor.left: cannot go left on a non-list type.");return t?this.tree.select(this.solvedPath.slice(0,-1).concat(t-1)):null},n.prototype.leftmost=function(){var t=+this.solvedPath[this.solvedPath.length-1];if(isNaN(t))throw Error("baobab.Cursor.leftmost: cannot go left on a non-list type.");return this.tree.select(this.solvedPath.slice(0,-1).concat(0))},n.prototype.right=function(){var t=+this.solvedPath[this.solvedPath.length-1];if(isNaN(t))throw Error("baobab.Cursor.right: cannot go right on a non-list type.");return t+1===this.up().get().length?null:this.tree.select(this.solvedPath.slice(0,-1).concat(t+1))},n.prototype.rightmost=function(){var t=+this.solvedPath[this.solvedPath.length-1];if(isNaN(t))throw Error("baobab.Cursor.right: cannot go right on a non-list type.");var e=this.up().get();return this.tree.select(this.solvedPath.slice(0,-1).concat(e.length-1))},n.prototype.down=function(){+this.solvedPath[this.solvedPath.length-1];return this.get()instanceof Array?this.tree.select(this.solvedPath.concat(0)):null},n.prototype.get=function(t){arguments.length>1&&(t=a.arrayOf(arguments));var e=this.solvedPath.concat([].concat(t||0===t?t:[]));return a.getIn(this.tree.data,e,this.tree)},i("set"),i("apply"),i("chain"),i("push","Array"),i("unshift","Array"),n.prototype.merge=function(t){if(!h.Object(t))throw Error("baobab.Cursor.merge: trying to merge a non-object.");var e=o.bind(this,"merge","Object").apply(this,arguments);return this.update(e)},n.prototype.unset=function(t){if(void 0===t&&this.isRoot())throw Error("baobab.Cursor.unset: cannot remove root node.");var e=o.bind(this,"unset",null).apply(this,[t,!0]);return this.update(e)},n.prototype.update=function(t,e){if(arguments.length<2)return this.tree.stack(a.pathObject(this.solvedPath,t)),this;var r=[].concat(t),n=a.solvePath(this.get(),r,this.tree);if(!n)throw Error("baobab.Cursor.update: could not solve dynamic path.");return this.tree.stack(a.pathObject(this.solvedPath.concat(n),e)),this},n.prototype.startRecording=function(t){if(t=t||5,1>t)throw Error("baobab.Cursor.startRecording: invalid maximum number of records.");return this.archive?this:(this._lazyBind(),this.archive=a.archive(t),this)},n.prototype.stopRecording=function(){return this.archive=null,this},n.prototype.undo=function(t){if(t=t||1,!this.isRecording())throw Error("baobab.Cursor.undo: cursor is not recording.");if(!h.PositiveInteger(t))throw Error("baobab.Cursor.undo: expecting a positive integer.");var e=this.archive.back(t);if(!e)throw Error("boabab.Cursor.undo: cannot find a relevant record ("+t+" back).");return this.undoing=!0,this.set(e)},n.prototype.isRecording=function(){return!!this.archive},n.prototype.hasHistory=function(){return!(!this.archive||!this.archive.get().length)},n.prototype.getHistory=function(){return this.archive?this.archive.get():[]},n.prototype.release=function(){this.tree.off("update",this.updateHandler),this.hash&&delete this.tree._cursors[this.hash],delete this.tree,delete this.path,delete this.solvedPath,delete this.archive,this.kill()},n.prototype.toJSON=function(){return this.get()},n.prototype.toString=function(){return this._identity},e.exports=n},{"../defaults.js":2,"./helpers.js":7,"./type.js":9,emmett:3}],6:[function(t,e,r){function n(t){return t}function o(t,e){function r(t){o[t]=l[t].bind(l)}var o=this,s=null,a=!1,h=e.get||n,u=e.cursors,c=Object.keys(u).map(function(t){return u[t]}),l=new i(t,c);["on","once","release"].forEach(r),this.get=function(){if(a)return s;var e={};for(var r in u)e[r]=t.get(u[r]);return s=h.call(null,e),a=!0,s},this.on("update",function(){a=!1})}{var i=t("./watcher.js");t("./helpers.js")}e.exports=o},{"./helpers.js":7,"./watcher.js":11}],7:[function(t,e,r){(function(r){function n(t){return Array.prototype.slice.call(t)}function o(t,e){return function(){t(),e.apply(null,arguments)}}function i(t,e,r){var o=n(arguments).slice(3);return e=+e,r=+r,t.slice(0,e).concat(t.slice(e+r).concat(o))}function s(t,e){var r,n={};for(r in t)n[r]=t[r];for(r in e)n[r]=e[r];return n}function a(t){var e=t.source,r="";return t.global&&(r+="g"),t.multiline&&(r+="m"),t.ignoreCase&&(r+="i"),t.sticky&&(r+="y"),t.unicode&&(r+="u"),new RegExp(e,r)}function h(t,e){if(!e||"object"!=typeof e||e instanceof Error||"ArrayBuffer"in r&&e instanceof ArrayBuffer)return e;if(_.Array(e)){if(t){var n,o,i=[];for(n=0,o=e.length;o>n;n++)i.push(P(e[n]));return i}return e.slice(0)}if(_.Date(e))return new Date(e.getTime());if(e instanceof RegExp)return a(e);if(_.Object(e)){var s,h={};e.constructor&&e.constructor!==Object&&(h=Object.create(e.constructor.prototype));for(s in e)e.hasOwnProperty(s)&&(h[s]=t?P(e[s]):e[s]);return h}return e}function u(t,e){return function(r){return e(t(r))}}function c(t,e){var r,n;for(r=0,n=t.length;n>r;r++)if(e(t[r]))return t[r]}function l(t,e){var r,n;for(r=0,n=t.length;n>r;r++)if(e(t[r]))return r;return-1}function f(t,e){var r,n=!0;if(!t)return!1;for(r in e)if(_.Object(e[r]))n=n&&f(t[r],e[r]);else if(_.Array(e[r]))n=n&&!!~e[r].indexOf(t[r]);else if(t[r]!==e[r])return!1;return n}function d(t,e){return c(t,function(t){return f(t,e)})}function y(t,e){return l(t,function(t){return f(t,e)})}function v(t,e,r){e=e||[];var n,o,i,s=t;for(o=0,i=e.length;i>o;o++){if(!s)return;if("function"==typeof e[o]){if(!_.Array(s))return;s=c(s,e[o])}else if("object"==typeof e[o])if(r&&"$cursor"in e[o]){if(!_.Path(e[o].$cursor))throw Error("baobab.getIn: $cursor path must be an array.");n=r.get(e[o].$cursor),s=s[n]}else{if(!_.Array(s))return;s=d(s,e[o])}else s=s[e[o]]}return s}function g(t,e,r){var n,o,i,s=[],a=t;for(o=0,i=e.length;i>o;o++){if(!a)return null;if("function"==typeof e[o]){if(!_.Array(a))return;n=l(a,e[o]),s.push(n),a=a[n]}else if("object"==typeof e[o])if(r&&"$cursor"in e[o]){if(!_.Path(e[o].$cursor))throw Error("baobab.getIn: $cursor path must be an array.");p=r.get(e[o].$cursor),s.push(p),a=a[p]}else{if(!_.Array(a))return;n=y(a,e[o]),s.push(n),a=a[n]}else s.push(e[o]),a=a[e[o]]||{}}return s}function b(t,e){var r,n,o,i,s,a,h,u,c;for(r=0,i=e.length;i>r;r++)for(h=e[r],n=0,s=t.length;s>n;n++)for(u=t[n],o=0,a=u.length;a>o&&(c=u[o],c==h[o]);o++)if(o+1===a||o+1===h.length)return!0;return!1}function m(t,e){var r,n=t.length,o={},i=o;for(n||(o=e),r=0;n>r;r++)i[t[r]]=r+1===n?e:{},i=i[t[r]];return o}function j(t,e){t.super_=e;var r=function(){};r.prototype=e.prototype,t.prototype=new r,t.prototype.constructor=t}function w(t){var e=[];return{add:function(r){e.unshift(r),e.length>t&&(e.length=t)},back:function(t){var r=e[t-1];return r&&(e=e.slice(t)),r},get:function(){return e}}}var _=t("./type.js"),$=h.bind(null,!1),P=h.bind(null,!0);e.exports={archive:w,arrayOf:n,before:o,deepClone:P,shallowClone:$,shallowMerge:s,compose:u,getIn:v,inherits:j,pathObject:m,solvePath:g,solveUpdate:b,splice:i}}).call(this,"undefined"!=typeof global?global:"undefined"!=typeof self?self:"undefined"!=typeof window?window:{})},{"./type.js":9}],8:[function(t,e,r){function n(t,e,r){a.forEach(function(e){r!==e&&delete t[e]}),t[r]=e[r]}function o(t,e){var r,h=i.shallowClone(e||{});a.forEach(function(e){t[e]&&n(h,t,e)}),t.$chain&&(a.slice(0,-1).forEach(function(t){delete h[t]}),h.$apply=h.$apply?i.compose(h.$apply,t.$chain):t.$chain),t.$push&&h.$push?h.$push=s.Array(h.$push)?h.$push.concat(t.$push):[h.$push].concat(t.$push):t.$push&&(h.$push=t.$push),t.$unshift&&h.$unshift?h.$unshift=s.Array(t.$unshift)?t.$unshift.concat(h.$unshift):[t.$unshift].concat(h.$unshift):t.$unshift&&(h.$unshift=t.$unshift);for(r in t)s.Object(t[r])?h[r]=o(t[r],h[r]):"$"!==r[0]&&(h[r]=t[r]);return h}var i=t("./helpers.js"),s=t("./type.js"),a=["$unset","$set","$merge","$apply"];e.exports=o},{"./helpers.js":7,"./type.js":9}],9:[function(t,e,r){function n(t,e){return e.some(function(e){return o[e](t)})}var o={};o.Array=function(t){return Array.isArray(t)},o.Object=function(t){return t&&"object"==typeof t&&!Array.isArray(t)&&!(t instanceof Function)},o.String=function(t){return"string"==typeof t},o.Number=function(t){return"number"==typeof t},o.PositiveInteger=function(t){return"number"==typeof t&&t>0&&t%1===0},o.Function=function(t){return"function"==typeof t},o.Primitive=function(t){return"string"==typeof t||"number"==typeof t||"boolean"==typeof t},o.Date=function(t){return t instanceof Date},o.NonScalar=function(t){return o.Object(t)||o.Array(t)},o.Path=function(t){var e=["String","Number","Function","Object"];return o.Array(t)?t.every(function(t){return n(t,e)}):n(t,e)},o.MixinCursor=function(t){return n(t,["String","Number","Array","Function","Cursor"])},o.MixinCursors=function(t){return n(t,["Object","Array","Function"])},o.ComplexPath=function(t){return t.some(function(t){return n(t,["Object","Function"])})},e.exports=o},{}],10:[function(t,e,r){function n(t,e){var r=new Error("baobab.update: "+e+" at path /"+t.slice(1).join("/"));return r.path=t,r}var o=t("./helpers.js"),i=t("./type.js");e.exports=function(t,e,r){if(r=r||{},!i.Object(t)&&!i.Array(t))throw Error("baobab.update: invalid target.");var s={};t={root:o.shallowClone(t)};var a=function(t,e,r,h){r=r||["root"];var u,c,l,f=r.join("|λ|"),p=r[r.length-1],d=Object.keys(e).some(function(t){return!!~["$unset","$set","$apply","$merge","$push","$unshift"].indexOf(t)});if(d){s[f]=!0;for(c in e){if("$unset"===c){var y=r[r.length-2];i.Array(t)?h[y]=o.splice(h[y],+p,1):(h[y]=o.shallowClone(t),delete h[y][p]);break}if("$set"===c){l=e.$set,t[p]=l;break}if("$apply"===c){if(u=e.$apply,"function"!=typeof u)throw n(r,"using command $apply with a non function");t[p]=u.call(null,t[p]);break}if("$merge"===c){if(l=e.$merge,!i.Object(t[p])||!i.Object(l))throw n(r,"using command $merge with a non object");t[p]=o.shallowMerge(t[p],l);break}if("$push"===c){if(l=e.$push,!i.Array(t[p]))throw n(r,"using command $push to a non array");t[p]=t[p].concat(l)}if("$unshift"===c){if(l=e.$unshift,!i.Array(t[p]))throw n(r,"using command $unshift to a non array");t[p]=[].concat(l).concat(t[p])}}}else for(c in e)t[p][c]="undefined"==typeof t[p][c]?{}:o.shallowClone(t[p][c]),a(t[p],e[c],r.concat(c),t)};return a(t,e),{data:t.root,log:Object.keys(s).map(function(t){return t.split("|λ|").slice(1)})}}},{"./helpers.js":7,"./type.js":9}],11:[function(t,e,r){function n(t,e){function r(){h&&(a=e.map(function(t){return i.solvePath(n.tree.data,t,n.tree)}))}var n=this;o.call(this),this.tree=t;var a=e,h=e.some(s.ComplexPath);this.updateHandler=function(t){var e=i.solveUpdate(t.data.log,a);e&&n.emit("update")},r(),this.tree.on("update",this.updateHandler)}var o=t("emmett"),i=t("./helpers.js"),s=t("./type.js");i.inherits(n,o),n.prototype.release=function(){this.tree.off("update",this.updateHandler),this.tree=null,this.kill()},e.exports=n},{"./helpers.js":7,"./type.js":9,emmett:3}]},{},[1])(1)}); \ No newline at end of file +!function(t){if("object"==typeof exports&&"undefined"!=typeof module)module.exports=t();else if("function"==typeof define&&define.amd)define([],t);else{var e;e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:this,e.Baobab=t()}}(function(){var t;return function e(t,r,n){function o(s,a){if(!r[s]){if(!t[s]){var h="function"==typeof require&&require;if(!a&&h)return h(s,!0);if(i)return i(s,!0);var u=new Error("Cannot find module '"+s+"'");throw u.code="MODULE_NOT_FOUND",u}var c=r[s]={exports:{}};t[s][0].call(c.exports,function(e){var r=t[s][1][e];return o(r?r:e)},c,c.exports,e,t,r,n)}return r[s].exports}for(var i="function"==typeof require&&require,s=0;sn;n++)t[n].fn!==e&&o.push(t[n]);return o}var s={once:"boolean",scope:"object"},a=0,h=function(){this._enabled=!0,this.unbindAll()};h.prototype.unbindAll=function(){return this._handlers={},this._handlersAll=[],this._handlersComplex=[],this},h.prototype.on=function(t,e,r){var n,i,h,u,c,l,f;if(o(t)){for(u in t)this.on(u,t[u],e);return this}for("function"==typeof t&&(r=e,e=t,t=null),c=[].concat(t),n=0,i=c.length;i>n;n++){if(u=c[n],f={order:a++,fn:e},"string"==typeof u)this._handlers[u]||(this._handlers[u]=[]),l=this._handlers[u];else if(u instanceof RegExp)l=this._handlersComplex,f.pattern=u;else{if(null!==u)throw Error("Emitter.on: invalid event.");l=this._handlersAll}for(h in r||{})s[h]&&(f[h]=r[h]);f.once&&(f.parent=l),l.push(f)}return this},h.prototype.once=function(){var t=Array.prototype.slice.call(arguments),r=t.length-1;return o(t[r])&&t.length>1?t[r]=e(t[r],{once:!0}):t.push({once:!0}),this.on.apply(this,t)},h.prototype.off=function(t,e){var r,n,s,a;if(1===arguments.length&&"function"==typeof t){e=arguments[0];for(s in this._handlers)this._handlers[s]=i(this._handlers[s],e),0===this._handlers[s].length&&delete this._handlers[s];this._handlersAll=i(this._handlersAll,e),this._handlersComplex=i(this._handlersComplex,e)}else if(1===arguments.length&&"string"==typeof t)delete this._handlers[t];else if(2===arguments.length){var h=[].concat(t);for(r=0,n=h.length;n>r;r++)a=h[r],this._handlers[a]=i(this._handlers[a],e),0===(this._handlers[a]||[]).length&&delete this._handlers[a]}else if(o(t))for(s in t)this.off(s,t[s]);return this},h.prototype.listeners=function(t){var e,r,n,o=this._handlersAll||[],i=!1;if(!t)throw Error("Emitter.listeners: no event provided.");for(o=o.concat(this._handlers[t]||[]),r=0,n=this._handlersComplex.length;n>r;r++)e=this._handlersComplex[r],~t.search(e.pattern)&&(i=!0,o.push(e));return this._handlersAll.length||i?o.sort(function(t,e){return t.order-e.order}):o.slice(0)},h.prototype.emit=function(t,e){if(!this._enabled)return this;if(o(t)){for(var r in t)this.emit(r,t[r]);return this}var n,i,s,a,h,u,c,l=[].concat(t),f=[];for(a=0,u=l.length;u>a;a++){for(i=this.listeners(l[a]),h=0,c=i.length;c>h;h++)s=i[h],n={type:l[a],target:this},arguments.length>1&&(n.data=e),s.fn.call("scope"in s?s.scope:this,n),s.once&&f.push(s);for(h=f.length-1;h>=0;h--)f[h].parent.splice(f[h].parent.indexOf(f[h]),1)}return this},h.prototype.kill=function(){this.unbindAll(),this._handlers=null,this._handlersAll=null,this._handlersComplex=null,this._enabled=!1},h.prototype.disable=function(){return this._enabled=!1,this},h.prototype.enable=function(){return this._enabled=!0,this},h.version="3.0.0","undefined"!=typeof n?("undefined"!=typeof r&&r.exports&&(n=r.exports=h),n.Emitter=h):"function"==typeof t&&t.amd?t("emmett",[],function(){return h}):this.Emitter=h}).call(this)},{}],4:[function(t,e,r){function n(t){return t+"$"+(new Date).getTime()+(""+Math.random()).replace("0.","")}function o(t,e){function r(t){this[t]=function(){var e=this.root[t].apply(this.root,arguments);return e instanceof i?this:e}}if(arguments.length<1&&(t={}),!(this instanceof o))return new o(t,e);if(!p.Object(t)&&!p.Array(t))throw Error("Baobab: invalid data.");if(s.call(this),this.options=u.shallowMerge(f,e),this._transaction={},this._future=void 0,this._cursors={},this._identity="[object Baobab]",this.data=u.deepClone(t),this.root=this.select([]),this.facets={},["get","set","unset","update"].forEach(r.bind(this)),!p.Object(this.options.facets))throw Error("Baobab: invalid facets.");for(var n in this.options.facets)this.addFacet(n,this.options.facets[n])}var i=t("./cursor.js"),s=t("emmett"),a=t("./watcher.js"),h=t("./facet.js"),u=t("./helpers.js"),c=t("./update.js"),l=t("./merge.js"),f=t("../defaults.js"),p=t("./type.js");u.inherits(o,s),o.prototype.addFacet=function(t,e){return this.facets[t]=this.createFacet(e),this},o.prototype.createFacet=function(t){return new h(this,t)},o.prototype.select=function(t){if(!t)throw Error("Baobab.select: invalid path.");if(arguments.length>1&&(t=u.arrayOf(arguments)),!p.Path(t))throw Error("Baobab.select: invalid path.");t=[].concat(t);var e,r=p.ComplexPath(t);r&&(e=u.solvePath(this.data,t,this));var o=t.map(function(t){return p.Function(t)?n("fn"):p.Object(t)?n("ob"):t}).join("|λ|");if(this._cursors[o])return this._cursors[o];var s=new i(this,t,e,o);return this._cursors[o]=s,s},o.prototype.stack=function(t){var e=this;if(!p.Object(t))throw Error("Baobab.update: wrong specification.");return this._transaction=l(t,this._transaction),this.options.autoCommit?this.options.asynchronous?(this._future||(this._future=setTimeout(e.commit.bind(e,null),0)),this):this.commit():this},o.prototype.commit=function(){var t=c(this.data,this._transaction,this.options),e=this.data;this._transaction={},this._future&&(this._future=clearTimeout(this._future));var r=this.options.validate,n=this.options.validationBehaviour;if("function"==typeof r){var o=r.call(this,e,t.data,t.log);if(o instanceof Error&&(this.emit("invalid",{error:o}),"rollback"===n))return this}return this.data=t.data,this.emit("update",{log:t.log,previousState:e}),this},o.prototype.watch=function(t){if(!p.Array(t)||t.some(function(t){return!p.Path(t)}))throw Error("Baobab.watch: invalid paths.");return new a(this,[].concat(t))},o.prototype.release=function(){var t;delete this.data,delete this._transaction;for(t in this._cursors)this._cursors[t].release();delete this._cursors;for(t in this.facets)this.facets[t].release();delete this.facets,this.kill()},o.prototype.toJSON=function(){return this.get()},o.prototype.toString=function(){return this._identity},e.exports=o},{"../defaults.js":2,"./cursor.js":5,"./facet.js":6,"./helpers.js":7,"./merge.js":8,"./type.js":9,"./update.js":10,"./watcher.js":11,emmett:3}],5:[function(t,e,r){function n(t,e,r,n){function o(t){if(i.isRecording()&&!i.undoing){var e=a.getIn(t,i.solvedPath,i.tree),r=a.deepClone(e);i.archive.add(r)}return i.undoing=!1,i.emit("update")}var i=this;s.call(this),e=e||[],this.tree=t,this.path=e,this.hash=n,this.archive=null,this.undoing=!1,this._identity="[object Cursor]",this.complexPath=!!r,this.solvedPath=this.complexPath?r:this.path,this.relevant=void 0!==this.get(),this.updateHandler=function(t){var e=t.data.log,r=t.data.previousState,n=!1;if(i.complexPath&&(i.solvedPath=a.solvePath(i.tree.data,i.path,i.tree)),!i.path.length)return o(r);i.solvedPath&&(n=a.solveUpdate(e,[i.solvedPath]));var s=void 0!==i.get();i.relevant?s&&n?o(r):s||(i.emit("irrelevant"),i.relevant=!1):s&&n&&(i.emit("relevant"),o(r),i.relevant=!0)};var h=!1;this._lazyBind=function(){h||(h=!0,i.tree.on("update",i.updateHandler))},this.on=a.before(this._lazyBind,this.on.bind(this)),this.once=a.before(this._lazyBind,this.once.bind(this)),this.complexPath&&this._lazyBind()}function o(t,e,r,n){if(arguments.length>5)throw Error("baobab.Cursor."+t+": too many arguments.");arguments.length<4&&(n=r,r=[]),r=r||[];var o=[].concat(r),i=a.solvePath(this.get(),o,this.tree);if(!i)throw Error("baobab.Cursor."+t+": could not solve dynamic path.");if(e){var s=this.get(i);if(!h[e](s))throw Error("baobab.Cursor."+t+": invalid target.")}var u={};u["$"+t]=n;var c=a.pathObject(i,u);return c}function i(t,e){n.prototype[t]=function(){var r=o.bind(this,t,e).apply(this,arguments);return this.update(r)}}var s=t("emmett"),a=t("./helpers.js"),h=(t("../defaults.js"),t("./type.js"));a.inherits(n,s),n.prototype.isRoot=function(){return!this.path.length},n.prototype.isLeaf=function(){return h.Primitive(this.get())},n.prototype.isBranch=function(){return!this.isLeaf()&&!this.isRoot()},n.prototype.root=function(){return this.tree.root()},n.prototype.select=function(t){if(arguments.length>1&&(t=a.arrayOf(arguments)),!h.Path(t))throw Error("baobab.Cursor.select: invalid path.");return this.tree.select(this.path.concat(t))},n.prototype.up=function(){return this.solvedPath&&this.solvedPath.length?this.tree.select(this.path.slice(0,-1)):null},n.prototype.left=function(){var t=+this.solvedPath[this.solvedPath.length-1];if(isNaN(t))throw Error("baobab.Cursor.left: cannot go left on a non-list type.");return t?this.tree.select(this.solvedPath.slice(0,-1).concat(t-1)):null},n.prototype.leftmost=function(){var t=+this.solvedPath[this.solvedPath.length-1];if(isNaN(t))throw Error("baobab.Cursor.leftmost: cannot go left on a non-list type.");return this.tree.select(this.solvedPath.slice(0,-1).concat(0))},n.prototype.right=function(){var t=+this.solvedPath[this.solvedPath.length-1];if(isNaN(t))throw Error("baobab.Cursor.right: cannot go right on a non-list type.");return t+1===this.up().get().length?null:this.tree.select(this.solvedPath.slice(0,-1).concat(t+1))},n.prototype.rightmost=function(){var t=+this.solvedPath[this.solvedPath.length-1];if(isNaN(t))throw Error("baobab.Cursor.right: cannot go right on a non-list type.");var e=this.up().get();return this.tree.select(this.solvedPath.slice(0,-1).concat(e.length-1))},n.prototype.down=function(){+this.solvedPath[this.solvedPath.length-1];return this.get()instanceof Array?this.tree.select(this.solvedPath.concat(0)):null},n.prototype.get=function(t){arguments.length>1&&(t=a.arrayOf(arguments));var e=this.solvedPath.concat([].concat(t||0===t?t:[]));return a.getIn(this.tree.data,e,this.tree)},i("set"),i("apply"),i("chain"),i("push","Array"),i("unshift","Array"),n.prototype.merge=function(t){if(!h.Object(t))throw Error("baobab.Cursor.merge: trying to merge a non-object.");var e=o.bind(this,"merge","Object").apply(this,arguments);return this.update(e)},n.prototype.unset=function(t){if(void 0===t&&this.isRoot())throw Error("baobab.Cursor.unset: cannot remove root node.");var e=o.bind(this,"unset",null).apply(this,[t,!0]);return this.update(e)},n.prototype.update=function(t,e){if(arguments.length<2)return this.tree.stack(a.pathObject(this.solvedPath,t)),this;var r=[].concat(t),n=a.solvePath(this.get(),r,this.tree);if(!n)throw Error("baobab.Cursor.update: could not solve dynamic path.");return this.tree.stack(a.pathObject(this.solvedPath.concat(n),e)),this},n.prototype.startRecording=function(t){if(t=t||5,1>t)throw Error("baobab.Cursor.startRecording: invalid maximum number of records.");return this.archive?this:(this._lazyBind(),this.archive=a.archive(t),this)},n.prototype.stopRecording=function(){return this.archive=null,this},n.prototype.undo=function(t){if(t=t||1,!this.isRecording())throw Error("baobab.Cursor.undo: cursor is not recording.");if(!h.PositiveInteger(t))throw Error("baobab.Cursor.undo: expecting a positive integer.");var e=this.archive.back(t);if(!e)throw Error("boabab.Cursor.undo: cannot find a relevant record ("+t+" back).");return this.undoing=!0,this.set(e)},n.prototype.isRecording=function(){return!!this.archive},n.prototype.hasHistory=function(){return!(!this.archive||!this.archive.get().length)},n.prototype.getHistory=function(){return this.archive?this.archive.get():[]},n.prototype.release=function(){this.tree.off("update",this.updateHandler),this.hash&&delete this.tree._cursors[this.hash],delete this.tree,delete this.path,delete this.solvedPath,delete this.archive,this.kill()},n.prototype.toJSON=function(){return this.get()},n.prototype.toString=function(){return this._identity},e.exports=n},{"../defaults.js":2,"./helpers.js":7,"./type.js":9,emmett:3}],6:[function(t,e,r){function n(t){return t}function o(t,e){function r(t){o[t]=l[t].bind(l)}var o=this,s=null,a=!1,h=e.get||n,u=e.cursors,c=Object.keys(u).map(function(t){return u[t]}),l=new i(t,c);["on","once","release"].forEach(r),this.get=function(){if(a)return s;var e={};for(var r in u)e[r]=t.get(u[r]);return s=h.call(null,e),a=!0,s},this.on("update",function(){a=!1})}{var i=t("./watcher.js");t("./helpers.js")}e.exports=o},{"./helpers.js":7,"./watcher.js":11}],7:[function(t,e,r){(function(r){function n(t){return Array.prototype.slice.call(t)}function o(t,e){return function(){t(),e.apply(null,arguments)}}function i(t,e,r){var o=n(arguments).slice(3);return e=+e,r=+r,t.slice(0,e).concat(t.slice(e+r).concat(o))}function s(t,e){var r,n={};for(r in t)n[r]=t[r];for(r in e)n[r]=e[r];return n}function a(t){var e=t.source,r="";return t.global&&(r+="g"),t.multiline&&(r+="m"),t.ignoreCase&&(r+="i"),t.sticky&&(r+="y"),t.unicode&&(r+="u"),new RegExp(e,r)}function h(t,e){if(!e||"object"!=typeof e||e instanceof Error||"ArrayBuffer"in r&&e instanceof ArrayBuffer)return e;if(_.Array(e)){if(t){var n,o,i=[];for(n=0,o=e.length;o>n;n++)i.push(P(e[n]));return i}return e.slice(0)}if(_.Date(e))return new Date(e.getTime());if(e instanceof RegExp)return a(e);if(_.Object(e)){var s,h={};e.constructor&&e.constructor!==Object&&(h=Object.create(e.constructor.prototype));for(s in e)e.hasOwnProperty(s)&&(h[s]=t?P(e[s]):e[s]);return h}return e}function u(t,e){return function(r){return e(t(r))}}function c(t,e){var r,n;for(r=0,n=t.length;n>r;r++)if(e(t[r]))return t[r]}function l(t,e){var r,n;for(r=0,n=t.length;n>r;r++)if(e(t[r]))return r;return-1}function f(t,e){var r,n=!0;if(!t)return!1;for(r in e)if(_.Object(e[r]))n=n&&f(t[r],e[r]);else if(_.Array(e[r]))n=n&&!!~e[r].indexOf(t[r]);else if(t[r]!==e[r])return!1;return n}function d(t,e){return c(t,function(t){return f(t,e)})}function y(t,e){return l(t,function(t){return f(t,e)})}function v(t,e,r){e=e||[];var n,o,i,s=t;for(o=0,i=e.length;i>o;o++){if(!s)return;if("function"==typeof e[o]){if(!_.Array(s))return;s=c(s,e[o])}else if("object"==typeof e[o])if(r&&"$cursor"in e[o]){if(!_.Path(e[o].$cursor))throw Error("baobab.getIn: $cursor path must be an array.");n=r.get(e[o].$cursor),s=s[n]}else{if(!_.Array(s))return;s=d(s,e[o])}else s=s[e[o]]}return s}function g(t,e,r){var n,o,i,s=[],a=t;for(o=0,i=e.length;i>o;o++){if(!a)return null;if("function"==typeof e[o]){if(!_.Array(a))return;n=l(a,e[o]),s.push(n),a=a[n]}else if("object"==typeof e[o])if(r&&"$cursor"in e[o]){if(!_.Path(e[o].$cursor))throw Error("baobab.getIn: $cursor path must be an array.");p=r.get(e[o].$cursor),s.push(p),a=a[p]}else{if(!_.Array(a))return;n=y(a,e[o]),s.push(n),a=a[n]}else s.push(e[o]),a=a[e[o]]||{}}return s}function b(t,e){var r,n,o,i,s,a,h,u,c;for(r=0,i=e.length;i>r;r++)for(h=e[r],n=0,s=t.length;s>n;n++)for(u=t[n],o=0,a=u.length;a>o&&(c=u[o],c==h[o]);o++)if(o+1===a||o+1===h.length)return!0;return!1}function m(t,e){var r,n=t.length,o={},i=o;for(n||(o=e),r=0;n>r;r++)i[t[r]]=r+1===n?e:{},i=i[t[r]];return o}function j(t,e){t.super_=e;var r=function(){};r.prototype=e.prototype,t.prototype=new r,t.prototype.constructor=t}function w(t){var e=[];return{add:function(r){e.unshift(r),e.length>t&&(e.length=t)},back:function(t){var r=e[t-1];return r&&(e=e.slice(t)),r},get:function(){return e}}}var _=t("./type.js"),$=h.bind(null,!1),P=h.bind(null,!0);e.exports={archive:w,arrayOf:n,before:o,deepClone:P,shallowClone:$,shallowMerge:s,compose:u,getIn:v,inherits:j,pathObject:m,solvePath:g,solveUpdate:b,splice:i}}).call(this,"undefined"!=typeof global?global:"undefined"!=typeof self?self:"undefined"!=typeof window?window:{})},{"./type.js":9}],8:[function(t,e,r){function n(t,e,r){a.forEach(function(e){r!==e&&delete t[e]}),t[r]=e[r]}function o(t,e){var r,h=i.shallowClone(e||{});a.forEach(function(e){t[e]&&n(h,t,e)}),t.$chain&&(a.slice(0,-1).forEach(function(t){delete h[t]}),h.$apply=h.$apply?i.compose(h.$apply,t.$chain):t.$chain),(t.$push||h.$push)&&(h.$push=[].concat(h.$push||[]).concat(t.$push||[])),(t.$unshift||h.$unshift)&&(h.$unshift=[].concat(t.$unshift||[]).concat(h.$unshift||[]));for(r in t)s.Object(t[r])?h[r]=o(t[r],h[r]):"$"!==r[0]&&(h[r]=t[r]);return h}var i=t("./helpers.js"),s=t("./type.js"),a=["$unset","$set","$merge","$apply"];e.exports=o},{"./helpers.js":7,"./type.js":9}],9:[function(t,e,r){function n(t,e){return e.some(function(e){return o[e](t)})}var o={};o.Array=function(t){return Array.isArray(t)},o.Object=function(t){return t&&"object"==typeof t&&!Array.isArray(t)&&!(t instanceof Function)},o.String=function(t){return"string"==typeof t},o.Number=function(t){return"number"==typeof t},o.PositiveInteger=function(t){return"number"==typeof t&&t>0&&t%1===0},o.Function=function(t){return"function"==typeof t},o.Primitive=function(t){return"string"==typeof t||"number"==typeof t||"boolean"==typeof t},o.Date=function(t){return t instanceof Date},o.NonScalar=function(t){return o.Object(t)||o.Array(t)},o.Path=function(t){var e=["String","Number","Function","Object"];return o.Array(t)?t.every(function(t){return n(t,e)}):n(t,e)},o.MixinCursor=function(t){return n(t,["String","Number","Array","Function","Cursor"])},o.MixinCursors=function(t){return n(t,["Object","Array","Function"])},o.ComplexPath=function(t){return t.some(function(t){return n(t,["Object","Function"])})},e.exports=o},{}],10:[function(t,e,r){function n(t,e){var r=new Error("baobab.update: "+e+" at path /"+t.slice(1).join("/"));return r.path=t,r}var o=t("./helpers.js"),i=t("./type.js");e.exports=function(t,e,r){if(r=r||{},!i.Object(t)&&!i.Array(t))throw Error("baobab.update: invalid target.");var s={};t={root:o.shallowClone(t)};var a=function(t,e,r,h){r=r||["root"];var u,c,l,f=r.join("|λ|"),p=r[r.length-1],d=Object.keys(e).some(function(t){return!!~["$unset","$set","$apply","$merge","$push","$unshift"].indexOf(t)});if(d){s[f]=!0;for(c in e){if("$unset"===c){var y=r[r.length-2];i.Array(t)?h[y]=o.splice(h[y],+p,1):(h[y]=o.shallowClone(t),delete h[y][p]);break}if("$set"===c){l=e.$set,t[p]=l;break}if("$apply"===c){if(u=e.$apply,"function"!=typeof u)throw n(r,"using command $apply with a non function");t[p]=u.call(null,t[p]);break}if("$merge"===c){if(l=e.$merge,!i.Object(t[p])||!i.Object(l))throw n(r,"using command $merge with a non object");t[p]=o.shallowMerge(t[p],l);break}if("$push"===c){if(l=e.$push,!i.Array(t[p]))throw n(r,"using command $push to a non array");t[p]=t[p].concat(l)}if("$unshift"===c){if(l=e.$unshift,!i.Array(t[p]))throw n(r,"using command $unshift to a non array");t[p]=[].concat(l).concat(t[p])}}}else for(c in e)t[p][c]="undefined"==typeof t[p][c]?{}:o.shallowClone(t[p][c]),a(t[p],e[c],r.concat(c),t)};return a(t,e),{data:t.root,log:Object.keys(s).map(function(t){return t.split("|λ|").slice(1)})}}},{"./helpers.js":7,"./type.js":9}],11:[function(t,e,r){function n(t,e){function r(){h&&(a=e.map(function(t){return i.solvePath(n.tree.data,t,n.tree)}))}var n=this;o.call(this),this.tree=t;var a=e,h=e.some(s.ComplexPath);this.updateHandler=function(t){var e=i.solveUpdate(t.data.log,a);e&&n.emit("update")},r(),this.tree.on("update",this.updateHandler)}var o=t("emmett"),i=t("./helpers.js"),s=t("./type.js");i.inherits(n,o),n.prototype.release=function(){this.tree.off("update",this.updateHandler),this.tree=null,this.kill()},e.exports=n},{"./helpers.js":7,"./type.js":9,emmett:3}]},{},[1])(1)}); \ No newline at end of file diff --git a/src/helpers.js b/src/helpers.js index 381f5a7..34aeebc 100644 --- a/src/helpers.js +++ b/src/helpers.js @@ -20,7 +20,7 @@ function before(decorator, fn) { } // Non-mutative splice function -function splice(array, index, nb /* &elements */) { +function splice(array, index, nb /*, &elements */) { var elements = arrayOf(arguments).slice(3); index = +index; diff --git a/src/merge.js b/src/merge.js index feaa55b..3e8fd38 100644 --- a/src/merge.js +++ b/src/merge.js @@ -43,24 +43,12 @@ function merge(a, b) { o.$apply = a.$chain; } - if (a.$push && o.$push) { - if (type.Array(o.$push)) - o.$push = o.$push.concat(a.$push); - else - o.$push = [o.$push].concat(a.$push); - } - else if (a.$push) { - o.$push = a.$push; + if (a.$push || o.$push) { + o.$push = [].concat(o.$push || []).concat(a.$push || []); } - if (a.$unshift && o.$unshift) { - if (type.Array(a.$unshift)) - o.$unshift = a.$unshift.concat(o.$unshift); - else - o.$unshift = [a.$unshift].concat(o.$unshift); - } - else if (a.$unshift) { - o.$unshift = a.$unshift; + if (a.$unshift || o.$unshift) { + o.$unshift = [].concat(a.$unshift || []).concat(o.$unshift || []); } for (k in a) { From aada485fd5d060c38819941fb1fa4445d6480877 Mon Sep 17 00:00:00 2001 From: Yomguithereal Date: Thu, 16 Apr 2015 14:59:25 +0200 Subject: [PATCH 58/73] Building $splice keyword --- build/baobab.min.js | 2 +- src/merge.js | 4 ++++ src/update.js | 26 ++++++++++++++++++-------- test/suites/cursor.js | 8 ++++++++ test/suites/helpers.js | 10 +++------- 5 files changed, 34 insertions(+), 16 deletions(-) diff --git a/build/baobab.min.js b/build/baobab.min.js index 99de643..cbfe3ed 100644 --- a/build/baobab.min.js +++ b/build/baobab.min.js @@ -1,2 +1,2 @@ /* baobab.js - Version: 1.0.0-rc1 - Author: Yomguithereal (Guillaume Plique) */ -!function(t){if("object"==typeof exports&&"undefined"!=typeof module)module.exports=t();else if("function"==typeof define&&define.amd)define([],t);else{var e;e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:this,e.Baobab=t()}}(function(){var t;return function e(t,r,n){function o(s,a){if(!r[s]){if(!t[s]){var h="function"==typeof require&&require;if(!a&&h)return h(s,!0);if(i)return i(s,!0);var u=new Error("Cannot find module '"+s+"'");throw u.code="MODULE_NOT_FOUND",u}var c=r[s]={exports:{}};t[s][0].call(c.exports,function(e){var r=t[s][1][e];return o(r?r:e)},c,c.exports,e,t,r,n)}return r[s].exports}for(var i="function"==typeof require&&require,s=0;sn;n++)t[n].fn!==e&&o.push(t[n]);return o}var s={once:"boolean",scope:"object"},a=0,h=function(){this._enabled=!0,this.unbindAll()};h.prototype.unbindAll=function(){return this._handlers={},this._handlersAll=[],this._handlersComplex=[],this},h.prototype.on=function(t,e,r){var n,i,h,u,c,l,f;if(o(t)){for(u in t)this.on(u,t[u],e);return this}for("function"==typeof t&&(r=e,e=t,t=null),c=[].concat(t),n=0,i=c.length;i>n;n++){if(u=c[n],f={order:a++,fn:e},"string"==typeof u)this._handlers[u]||(this._handlers[u]=[]),l=this._handlers[u];else if(u instanceof RegExp)l=this._handlersComplex,f.pattern=u;else{if(null!==u)throw Error("Emitter.on: invalid event.");l=this._handlersAll}for(h in r||{})s[h]&&(f[h]=r[h]);f.once&&(f.parent=l),l.push(f)}return this},h.prototype.once=function(){var t=Array.prototype.slice.call(arguments),r=t.length-1;return o(t[r])&&t.length>1?t[r]=e(t[r],{once:!0}):t.push({once:!0}),this.on.apply(this,t)},h.prototype.off=function(t,e){var r,n,s,a;if(1===arguments.length&&"function"==typeof t){e=arguments[0];for(s in this._handlers)this._handlers[s]=i(this._handlers[s],e),0===this._handlers[s].length&&delete this._handlers[s];this._handlersAll=i(this._handlersAll,e),this._handlersComplex=i(this._handlersComplex,e)}else if(1===arguments.length&&"string"==typeof t)delete this._handlers[t];else if(2===arguments.length){var h=[].concat(t);for(r=0,n=h.length;n>r;r++)a=h[r],this._handlers[a]=i(this._handlers[a],e),0===(this._handlers[a]||[]).length&&delete this._handlers[a]}else if(o(t))for(s in t)this.off(s,t[s]);return this},h.prototype.listeners=function(t){var e,r,n,o=this._handlersAll||[],i=!1;if(!t)throw Error("Emitter.listeners: no event provided.");for(o=o.concat(this._handlers[t]||[]),r=0,n=this._handlersComplex.length;n>r;r++)e=this._handlersComplex[r],~t.search(e.pattern)&&(i=!0,o.push(e));return this._handlersAll.length||i?o.sort(function(t,e){return t.order-e.order}):o.slice(0)},h.prototype.emit=function(t,e){if(!this._enabled)return this;if(o(t)){for(var r in t)this.emit(r,t[r]);return this}var n,i,s,a,h,u,c,l=[].concat(t),f=[];for(a=0,u=l.length;u>a;a++){for(i=this.listeners(l[a]),h=0,c=i.length;c>h;h++)s=i[h],n={type:l[a],target:this},arguments.length>1&&(n.data=e),s.fn.call("scope"in s?s.scope:this,n),s.once&&f.push(s);for(h=f.length-1;h>=0;h--)f[h].parent.splice(f[h].parent.indexOf(f[h]),1)}return this},h.prototype.kill=function(){this.unbindAll(),this._handlers=null,this._handlersAll=null,this._handlersComplex=null,this._enabled=!1},h.prototype.disable=function(){return this._enabled=!1,this},h.prototype.enable=function(){return this._enabled=!0,this},h.version="3.0.0","undefined"!=typeof n?("undefined"!=typeof r&&r.exports&&(n=r.exports=h),n.Emitter=h):"function"==typeof t&&t.amd?t("emmett",[],function(){return h}):this.Emitter=h}).call(this)},{}],4:[function(t,e,r){function n(t){return t+"$"+(new Date).getTime()+(""+Math.random()).replace("0.","")}function o(t,e){function r(t){this[t]=function(){var e=this.root[t].apply(this.root,arguments);return e instanceof i?this:e}}if(arguments.length<1&&(t={}),!(this instanceof o))return new o(t,e);if(!p.Object(t)&&!p.Array(t))throw Error("Baobab: invalid data.");if(s.call(this),this.options=u.shallowMerge(f,e),this._transaction={},this._future=void 0,this._cursors={},this._identity="[object Baobab]",this.data=u.deepClone(t),this.root=this.select([]),this.facets={},["get","set","unset","update"].forEach(r.bind(this)),!p.Object(this.options.facets))throw Error("Baobab: invalid facets.");for(var n in this.options.facets)this.addFacet(n,this.options.facets[n])}var i=t("./cursor.js"),s=t("emmett"),a=t("./watcher.js"),h=t("./facet.js"),u=t("./helpers.js"),c=t("./update.js"),l=t("./merge.js"),f=t("../defaults.js"),p=t("./type.js");u.inherits(o,s),o.prototype.addFacet=function(t,e){return this.facets[t]=this.createFacet(e),this},o.prototype.createFacet=function(t){return new h(this,t)},o.prototype.select=function(t){if(!t)throw Error("Baobab.select: invalid path.");if(arguments.length>1&&(t=u.arrayOf(arguments)),!p.Path(t))throw Error("Baobab.select: invalid path.");t=[].concat(t);var e,r=p.ComplexPath(t);r&&(e=u.solvePath(this.data,t,this));var o=t.map(function(t){return p.Function(t)?n("fn"):p.Object(t)?n("ob"):t}).join("|λ|");if(this._cursors[o])return this._cursors[o];var s=new i(this,t,e,o);return this._cursors[o]=s,s},o.prototype.stack=function(t){var e=this;if(!p.Object(t))throw Error("Baobab.update: wrong specification.");return this._transaction=l(t,this._transaction),this.options.autoCommit?this.options.asynchronous?(this._future||(this._future=setTimeout(e.commit.bind(e,null),0)),this):this.commit():this},o.prototype.commit=function(){var t=c(this.data,this._transaction,this.options),e=this.data;this._transaction={},this._future&&(this._future=clearTimeout(this._future));var r=this.options.validate,n=this.options.validationBehaviour;if("function"==typeof r){var o=r.call(this,e,t.data,t.log);if(o instanceof Error&&(this.emit("invalid",{error:o}),"rollback"===n))return this}return this.data=t.data,this.emit("update",{log:t.log,previousState:e}),this},o.prototype.watch=function(t){if(!p.Array(t)||t.some(function(t){return!p.Path(t)}))throw Error("Baobab.watch: invalid paths.");return new a(this,[].concat(t))},o.prototype.release=function(){var t;delete this.data,delete this._transaction;for(t in this._cursors)this._cursors[t].release();delete this._cursors;for(t in this.facets)this.facets[t].release();delete this.facets,this.kill()},o.prototype.toJSON=function(){return this.get()},o.prototype.toString=function(){return this._identity},e.exports=o},{"../defaults.js":2,"./cursor.js":5,"./facet.js":6,"./helpers.js":7,"./merge.js":8,"./type.js":9,"./update.js":10,"./watcher.js":11,emmett:3}],5:[function(t,e,r){function n(t,e,r,n){function o(t){if(i.isRecording()&&!i.undoing){var e=a.getIn(t,i.solvedPath,i.tree),r=a.deepClone(e);i.archive.add(r)}return i.undoing=!1,i.emit("update")}var i=this;s.call(this),e=e||[],this.tree=t,this.path=e,this.hash=n,this.archive=null,this.undoing=!1,this._identity="[object Cursor]",this.complexPath=!!r,this.solvedPath=this.complexPath?r:this.path,this.relevant=void 0!==this.get(),this.updateHandler=function(t){var e=t.data.log,r=t.data.previousState,n=!1;if(i.complexPath&&(i.solvedPath=a.solvePath(i.tree.data,i.path,i.tree)),!i.path.length)return o(r);i.solvedPath&&(n=a.solveUpdate(e,[i.solvedPath]));var s=void 0!==i.get();i.relevant?s&&n?o(r):s||(i.emit("irrelevant"),i.relevant=!1):s&&n&&(i.emit("relevant"),o(r),i.relevant=!0)};var h=!1;this._lazyBind=function(){h||(h=!0,i.tree.on("update",i.updateHandler))},this.on=a.before(this._lazyBind,this.on.bind(this)),this.once=a.before(this._lazyBind,this.once.bind(this)),this.complexPath&&this._lazyBind()}function o(t,e,r,n){if(arguments.length>5)throw Error("baobab.Cursor."+t+": too many arguments.");arguments.length<4&&(n=r,r=[]),r=r||[];var o=[].concat(r),i=a.solvePath(this.get(),o,this.tree);if(!i)throw Error("baobab.Cursor."+t+": could not solve dynamic path.");if(e){var s=this.get(i);if(!h[e](s))throw Error("baobab.Cursor."+t+": invalid target.")}var u={};u["$"+t]=n;var c=a.pathObject(i,u);return c}function i(t,e){n.prototype[t]=function(){var r=o.bind(this,t,e).apply(this,arguments);return this.update(r)}}var s=t("emmett"),a=t("./helpers.js"),h=(t("../defaults.js"),t("./type.js"));a.inherits(n,s),n.prototype.isRoot=function(){return!this.path.length},n.prototype.isLeaf=function(){return h.Primitive(this.get())},n.prototype.isBranch=function(){return!this.isLeaf()&&!this.isRoot()},n.prototype.root=function(){return this.tree.root()},n.prototype.select=function(t){if(arguments.length>1&&(t=a.arrayOf(arguments)),!h.Path(t))throw Error("baobab.Cursor.select: invalid path.");return this.tree.select(this.path.concat(t))},n.prototype.up=function(){return this.solvedPath&&this.solvedPath.length?this.tree.select(this.path.slice(0,-1)):null},n.prototype.left=function(){var t=+this.solvedPath[this.solvedPath.length-1];if(isNaN(t))throw Error("baobab.Cursor.left: cannot go left on a non-list type.");return t?this.tree.select(this.solvedPath.slice(0,-1).concat(t-1)):null},n.prototype.leftmost=function(){var t=+this.solvedPath[this.solvedPath.length-1];if(isNaN(t))throw Error("baobab.Cursor.leftmost: cannot go left on a non-list type.");return this.tree.select(this.solvedPath.slice(0,-1).concat(0))},n.prototype.right=function(){var t=+this.solvedPath[this.solvedPath.length-1];if(isNaN(t))throw Error("baobab.Cursor.right: cannot go right on a non-list type.");return t+1===this.up().get().length?null:this.tree.select(this.solvedPath.slice(0,-1).concat(t+1))},n.prototype.rightmost=function(){var t=+this.solvedPath[this.solvedPath.length-1];if(isNaN(t))throw Error("baobab.Cursor.right: cannot go right on a non-list type.");var e=this.up().get();return this.tree.select(this.solvedPath.slice(0,-1).concat(e.length-1))},n.prototype.down=function(){+this.solvedPath[this.solvedPath.length-1];return this.get()instanceof Array?this.tree.select(this.solvedPath.concat(0)):null},n.prototype.get=function(t){arguments.length>1&&(t=a.arrayOf(arguments));var e=this.solvedPath.concat([].concat(t||0===t?t:[]));return a.getIn(this.tree.data,e,this.tree)},i("set"),i("apply"),i("chain"),i("push","Array"),i("unshift","Array"),n.prototype.merge=function(t){if(!h.Object(t))throw Error("baobab.Cursor.merge: trying to merge a non-object.");var e=o.bind(this,"merge","Object").apply(this,arguments);return this.update(e)},n.prototype.unset=function(t){if(void 0===t&&this.isRoot())throw Error("baobab.Cursor.unset: cannot remove root node.");var e=o.bind(this,"unset",null).apply(this,[t,!0]);return this.update(e)},n.prototype.update=function(t,e){if(arguments.length<2)return this.tree.stack(a.pathObject(this.solvedPath,t)),this;var r=[].concat(t),n=a.solvePath(this.get(),r,this.tree);if(!n)throw Error("baobab.Cursor.update: could not solve dynamic path.");return this.tree.stack(a.pathObject(this.solvedPath.concat(n),e)),this},n.prototype.startRecording=function(t){if(t=t||5,1>t)throw Error("baobab.Cursor.startRecording: invalid maximum number of records.");return this.archive?this:(this._lazyBind(),this.archive=a.archive(t),this)},n.prototype.stopRecording=function(){return this.archive=null,this},n.prototype.undo=function(t){if(t=t||1,!this.isRecording())throw Error("baobab.Cursor.undo: cursor is not recording.");if(!h.PositiveInteger(t))throw Error("baobab.Cursor.undo: expecting a positive integer.");var e=this.archive.back(t);if(!e)throw Error("boabab.Cursor.undo: cannot find a relevant record ("+t+" back).");return this.undoing=!0,this.set(e)},n.prototype.isRecording=function(){return!!this.archive},n.prototype.hasHistory=function(){return!(!this.archive||!this.archive.get().length)},n.prototype.getHistory=function(){return this.archive?this.archive.get():[]},n.prototype.release=function(){this.tree.off("update",this.updateHandler),this.hash&&delete this.tree._cursors[this.hash],delete this.tree,delete this.path,delete this.solvedPath,delete this.archive,this.kill()},n.prototype.toJSON=function(){return this.get()},n.prototype.toString=function(){return this._identity},e.exports=n},{"../defaults.js":2,"./helpers.js":7,"./type.js":9,emmett:3}],6:[function(t,e,r){function n(t){return t}function o(t,e){function r(t){o[t]=l[t].bind(l)}var o=this,s=null,a=!1,h=e.get||n,u=e.cursors,c=Object.keys(u).map(function(t){return u[t]}),l=new i(t,c);["on","once","release"].forEach(r),this.get=function(){if(a)return s;var e={};for(var r in u)e[r]=t.get(u[r]);return s=h.call(null,e),a=!0,s},this.on("update",function(){a=!1})}{var i=t("./watcher.js");t("./helpers.js")}e.exports=o},{"./helpers.js":7,"./watcher.js":11}],7:[function(t,e,r){(function(r){function n(t){return Array.prototype.slice.call(t)}function o(t,e){return function(){t(),e.apply(null,arguments)}}function i(t,e,r){var o=n(arguments).slice(3);return e=+e,r=+r,t.slice(0,e).concat(t.slice(e+r).concat(o))}function s(t,e){var r,n={};for(r in t)n[r]=t[r];for(r in e)n[r]=e[r];return n}function a(t){var e=t.source,r="";return t.global&&(r+="g"),t.multiline&&(r+="m"),t.ignoreCase&&(r+="i"),t.sticky&&(r+="y"),t.unicode&&(r+="u"),new RegExp(e,r)}function h(t,e){if(!e||"object"!=typeof e||e instanceof Error||"ArrayBuffer"in r&&e instanceof ArrayBuffer)return e;if(_.Array(e)){if(t){var n,o,i=[];for(n=0,o=e.length;o>n;n++)i.push(P(e[n]));return i}return e.slice(0)}if(_.Date(e))return new Date(e.getTime());if(e instanceof RegExp)return a(e);if(_.Object(e)){var s,h={};e.constructor&&e.constructor!==Object&&(h=Object.create(e.constructor.prototype));for(s in e)e.hasOwnProperty(s)&&(h[s]=t?P(e[s]):e[s]);return h}return e}function u(t,e){return function(r){return e(t(r))}}function c(t,e){var r,n;for(r=0,n=t.length;n>r;r++)if(e(t[r]))return t[r]}function l(t,e){var r,n;for(r=0,n=t.length;n>r;r++)if(e(t[r]))return r;return-1}function f(t,e){var r,n=!0;if(!t)return!1;for(r in e)if(_.Object(e[r]))n=n&&f(t[r],e[r]);else if(_.Array(e[r]))n=n&&!!~e[r].indexOf(t[r]);else if(t[r]!==e[r])return!1;return n}function d(t,e){return c(t,function(t){return f(t,e)})}function y(t,e){return l(t,function(t){return f(t,e)})}function v(t,e,r){e=e||[];var n,o,i,s=t;for(o=0,i=e.length;i>o;o++){if(!s)return;if("function"==typeof e[o]){if(!_.Array(s))return;s=c(s,e[o])}else if("object"==typeof e[o])if(r&&"$cursor"in e[o]){if(!_.Path(e[o].$cursor))throw Error("baobab.getIn: $cursor path must be an array.");n=r.get(e[o].$cursor),s=s[n]}else{if(!_.Array(s))return;s=d(s,e[o])}else s=s[e[o]]}return s}function g(t,e,r){var n,o,i,s=[],a=t;for(o=0,i=e.length;i>o;o++){if(!a)return null;if("function"==typeof e[o]){if(!_.Array(a))return;n=l(a,e[o]),s.push(n),a=a[n]}else if("object"==typeof e[o])if(r&&"$cursor"in e[o]){if(!_.Path(e[o].$cursor))throw Error("baobab.getIn: $cursor path must be an array.");p=r.get(e[o].$cursor),s.push(p),a=a[p]}else{if(!_.Array(a))return;n=y(a,e[o]),s.push(n),a=a[n]}else s.push(e[o]),a=a[e[o]]||{}}return s}function b(t,e){var r,n,o,i,s,a,h,u,c;for(r=0,i=e.length;i>r;r++)for(h=e[r],n=0,s=t.length;s>n;n++)for(u=t[n],o=0,a=u.length;a>o&&(c=u[o],c==h[o]);o++)if(o+1===a||o+1===h.length)return!0;return!1}function m(t,e){var r,n=t.length,o={},i=o;for(n||(o=e),r=0;n>r;r++)i[t[r]]=r+1===n?e:{},i=i[t[r]];return o}function j(t,e){t.super_=e;var r=function(){};r.prototype=e.prototype,t.prototype=new r,t.prototype.constructor=t}function w(t){var e=[];return{add:function(r){e.unshift(r),e.length>t&&(e.length=t)},back:function(t){var r=e[t-1];return r&&(e=e.slice(t)),r},get:function(){return e}}}var _=t("./type.js"),$=h.bind(null,!1),P=h.bind(null,!0);e.exports={archive:w,arrayOf:n,before:o,deepClone:P,shallowClone:$,shallowMerge:s,compose:u,getIn:v,inherits:j,pathObject:m,solvePath:g,solveUpdate:b,splice:i}}).call(this,"undefined"!=typeof global?global:"undefined"!=typeof self?self:"undefined"!=typeof window?window:{})},{"./type.js":9}],8:[function(t,e,r){function n(t,e,r){a.forEach(function(e){r!==e&&delete t[e]}),t[r]=e[r]}function o(t,e){var r,h=i.shallowClone(e||{});a.forEach(function(e){t[e]&&n(h,t,e)}),t.$chain&&(a.slice(0,-1).forEach(function(t){delete h[t]}),h.$apply=h.$apply?i.compose(h.$apply,t.$chain):t.$chain),(t.$push||h.$push)&&(h.$push=[].concat(h.$push||[]).concat(t.$push||[])),(t.$unshift||h.$unshift)&&(h.$unshift=[].concat(t.$unshift||[]).concat(h.$unshift||[]));for(r in t)s.Object(t[r])?h[r]=o(t[r],h[r]):"$"!==r[0]&&(h[r]=t[r]);return h}var i=t("./helpers.js"),s=t("./type.js"),a=["$unset","$set","$merge","$apply"];e.exports=o},{"./helpers.js":7,"./type.js":9}],9:[function(t,e,r){function n(t,e){return e.some(function(e){return o[e](t)})}var o={};o.Array=function(t){return Array.isArray(t)},o.Object=function(t){return t&&"object"==typeof t&&!Array.isArray(t)&&!(t instanceof Function)},o.String=function(t){return"string"==typeof t},o.Number=function(t){return"number"==typeof t},o.PositiveInteger=function(t){return"number"==typeof t&&t>0&&t%1===0},o.Function=function(t){return"function"==typeof t},o.Primitive=function(t){return"string"==typeof t||"number"==typeof t||"boolean"==typeof t},o.Date=function(t){return t instanceof Date},o.NonScalar=function(t){return o.Object(t)||o.Array(t)},o.Path=function(t){var e=["String","Number","Function","Object"];return o.Array(t)?t.every(function(t){return n(t,e)}):n(t,e)},o.MixinCursor=function(t){return n(t,["String","Number","Array","Function","Cursor"])},o.MixinCursors=function(t){return n(t,["Object","Array","Function"])},o.ComplexPath=function(t){return t.some(function(t){return n(t,["Object","Function"])})},e.exports=o},{}],10:[function(t,e,r){function n(t,e){var r=new Error("baobab.update: "+e+" at path /"+t.slice(1).join("/"));return r.path=t,r}var o=t("./helpers.js"),i=t("./type.js");e.exports=function(t,e,r){if(r=r||{},!i.Object(t)&&!i.Array(t))throw Error("baobab.update: invalid target.");var s={};t={root:o.shallowClone(t)};var a=function(t,e,r,h){r=r||["root"];var u,c,l,f=r.join("|λ|"),p=r[r.length-1],d=Object.keys(e).some(function(t){return!!~["$unset","$set","$apply","$merge","$push","$unshift"].indexOf(t)});if(d){s[f]=!0;for(c in e){if("$unset"===c){var y=r[r.length-2];i.Array(t)?h[y]=o.splice(h[y],+p,1):(h[y]=o.shallowClone(t),delete h[y][p]);break}if("$set"===c){l=e.$set,t[p]=l;break}if("$apply"===c){if(u=e.$apply,"function"!=typeof u)throw n(r,"using command $apply with a non function");t[p]=u.call(null,t[p]);break}if("$merge"===c){if(l=e.$merge,!i.Object(t[p])||!i.Object(l))throw n(r,"using command $merge with a non object");t[p]=o.shallowMerge(t[p],l);break}if("$push"===c){if(l=e.$push,!i.Array(t[p]))throw n(r,"using command $push to a non array");t[p]=t[p].concat(l)}if("$unshift"===c){if(l=e.$unshift,!i.Array(t[p]))throw n(r,"using command $unshift to a non array");t[p]=[].concat(l).concat(t[p])}}}else for(c in e)t[p][c]="undefined"==typeof t[p][c]?{}:o.shallowClone(t[p][c]),a(t[p],e[c],r.concat(c),t)};return a(t,e),{data:t.root,log:Object.keys(s).map(function(t){return t.split("|λ|").slice(1)})}}},{"./helpers.js":7,"./type.js":9}],11:[function(t,e,r){function n(t,e){function r(){h&&(a=e.map(function(t){return i.solvePath(n.tree.data,t,n.tree)}))}var n=this;o.call(this),this.tree=t;var a=e,h=e.some(s.ComplexPath);this.updateHandler=function(t){var e=i.solveUpdate(t.data.log,a);e&&n.emit("update")},r(),this.tree.on("update",this.updateHandler)}var o=t("emmett"),i=t("./helpers.js"),s=t("./type.js");i.inherits(n,o),n.prototype.release=function(){this.tree.off("update",this.updateHandler),this.tree=null,this.kill()},e.exports=n},{"./helpers.js":7,"./type.js":9,emmett:3}]},{},[1])(1)}); \ No newline at end of file +!function(t){if("object"==typeof exports&&"undefined"!=typeof module)module.exports=t();else if("function"==typeof define&&define.amd)define([],t);else{var e;e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:this,e.Baobab=t()}}(function(){var t;return function e(t,r,n){function o(s,a){if(!r[s]){if(!t[s]){var h="function"==typeof require&&require;if(!a&&h)return h(s,!0);if(i)return i(s,!0);var u=new Error("Cannot find module '"+s+"'");throw u.code="MODULE_NOT_FOUND",u}var c=r[s]={exports:{}};t[s][0].call(c.exports,function(e){var r=t[s][1][e];return o(r?r:e)},c,c.exports,e,t,r,n)}return r[s].exports}for(var i="function"==typeof require&&require,s=0;sn;n++)t[n].fn!==e&&o.push(t[n]);return o}var s={once:"boolean",scope:"object"},a=0,h=function(){this._enabled=!0,this.unbindAll()};h.prototype.unbindAll=function(){return this._handlers={},this._handlersAll=[],this._handlersComplex=[],this},h.prototype.on=function(t,e,r){var n,i,h,u,c,l,f;if(o(t)){for(u in t)this.on(u,t[u],e);return this}for("function"==typeof t&&(r=e,e=t,t=null),c=[].concat(t),n=0,i=c.length;i>n;n++){if(u=c[n],f={order:a++,fn:e},"string"==typeof u)this._handlers[u]||(this._handlers[u]=[]),l=this._handlers[u];else if(u instanceof RegExp)l=this._handlersComplex,f.pattern=u;else{if(null!==u)throw Error("Emitter.on: invalid event.");l=this._handlersAll}for(h in r||{})s[h]&&(f[h]=r[h]);f.once&&(f.parent=l),l.push(f)}return this},h.prototype.once=function(){var t=Array.prototype.slice.call(arguments),r=t.length-1;return o(t[r])&&t.length>1?t[r]=e(t[r],{once:!0}):t.push({once:!0}),this.on.apply(this,t)},h.prototype.off=function(t,e){var r,n,s,a;if(1===arguments.length&&"function"==typeof t){e=arguments[0];for(s in this._handlers)this._handlers[s]=i(this._handlers[s],e),0===this._handlers[s].length&&delete this._handlers[s];this._handlersAll=i(this._handlersAll,e),this._handlersComplex=i(this._handlersComplex,e)}else if(1===arguments.length&&"string"==typeof t)delete this._handlers[t];else if(2===arguments.length){var h=[].concat(t);for(r=0,n=h.length;n>r;r++)a=h[r],this._handlers[a]=i(this._handlers[a],e),0===(this._handlers[a]||[]).length&&delete this._handlers[a]}else if(o(t))for(s in t)this.off(s,t[s]);return this},h.prototype.listeners=function(t){var e,r,n,o=this._handlersAll||[],i=!1;if(!t)throw Error("Emitter.listeners: no event provided.");for(o=o.concat(this._handlers[t]||[]),r=0,n=this._handlersComplex.length;n>r;r++)e=this._handlersComplex[r],~t.search(e.pattern)&&(i=!0,o.push(e));return this._handlersAll.length||i?o.sort(function(t,e){return t.order-e.order}):o.slice(0)},h.prototype.emit=function(t,e){if(!this._enabled)return this;if(o(t)){for(var r in t)this.emit(r,t[r]);return this}var n,i,s,a,h,u,c,l=[].concat(t),f=[];for(a=0,u=l.length;u>a;a++){for(i=this.listeners(l[a]),h=0,c=i.length;c>h;h++)s=i[h],n={type:l[a],target:this},arguments.length>1&&(n.data=e),s.fn.call("scope"in s?s.scope:this,n),s.once&&f.push(s);for(h=f.length-1;h>=0;h--)f[h].parent.splice(f[h].parent.indexOf(f[h]),1)}return this},h.prototype.kill=function(){this.unbindAll(),this._handlers=null,this._handlersAll=null,this._handlersComplex=null,this._enabled=!1},h.prototype.disable=function(){return this._enabled=!1,this},h.prototype.enable=function(){return this._enabled=!0,this},h.version="3.0.0","undefined"!=typeof n?("undefined"!=typeof r&&r.exports&&(n=r.exports=h),n.Emitter=h):"function"==typeof t&&t.amd?t("emmett",[],function(){return h}):this.Emitter=h}).call(this)},{}],4:[function(t,e,r){function n(t){return t+"$"+(new Date).getTime()+(""+Math.random()).replace("0.","")}function o(t,e){function r(t){this[t]=function(){var e=this.root[t].apply(this.root,arguments);return e instanceof i?this:e}}if(arguments.length<1&&(t={}),!(this instanceof o))return new o(t,e);if(!p.Object(t)&&!p.Array(t))throw Error("Baobab: invalid data.");if(s.call(this),this.options=u.shallowMerge(f,e),this._transaction={},this._future=void 0,this._cursors={},this._identity="[object Baobab]",this.data=u.deepClone(t),this.root=this.select([]),this.facets={},["get","set","unset","update"].forEach(r.bind(this)),!p.Object(this.options.facets))throw Error("Baobab: invalid facets.");for(var n in this.options.facets)this.addFacet(n,this.options.facets[n])}var i=t("./cursor.js"),s=t("emmett"),a=t("./watcher.js"),h=t("./facet.js"),u=t("./helpers.js"),c=t("./update.js"),l=t("./merge.js"),f=t("../defaults.js"),p=t("./type.js");u.inherits(o,s),o.prototype.addFacet=function(t,e){return this.facets[t]=this.createFacet(e),this},o.prototype.createFacet=function(t){return new h(this,t)},o.prototype.select=function(t){if(!t)throw Error("Baobab.select: invalid path.");if(arguments.length>1&&(t=u.arrayOf(arguments)),!p.Path(t))throw Error("Baobab.select: invalid path.");t=[].concat(t);var e,r=p.ComplexPath(t);r&&(e=u.solvePath(this.data,t,this));var o=t.map(function(t){return p.Function(t)?n("fn"):p.Object(t)?n("ob"):t}).join("|λ|");if(this._cursors[o])return this._cursors[o];var s=new i(this,t,e,o);return this._cursors[o]=s,s},o.prototype.stack=function(t){var e=this;if(!p.Object(t))throw Error("Baobab.update: wrong specification.");return this._transaction=l(t,this._transaction),this.options.autoCommit?this.options.asynchronous?(this._future||(this._future=setTimeout(e.commit.bind(e,null),0)),this):this.commit():this},o.prototype.commit=function(){var t=c(this.data,this._transaction,this.options),e=this.data;this._transaction={},this._future&&(this._future=clearTimeout(this._future));var r=this.options.validate,n=this.options.validationBehaviour;if("function"==typeof r){var o=r.call(this,e,t.data,t.log);if(o instanceof Error&&(this.emit("invalid",{error:o}),"rollback"===n))return this}return this.data=t.data,this.emit("update",{log:t.log,previousState:e}),this},o.prototype.watch=function(t){if(!p.Array(t)||t.some(function(t){return!p.Path(t)}))throw Error("Baobab.watch: invalid paths.");return new a(this,[].concat(t))},o.prototype.release=function(){var t;delete this.data,delete this._transaction;for(t in this._cursors)this._cursors[t].release();delete this._cursors;for(t in this.facets)this.facets[t].release();delete this.facets,this.kill()},o.prototype.toJSON=function(){return this.get()},o.prototype.toString=function(){return this._identity},e.exports=o},{"../defaults.js":2,"./cursor.js":5,"./facet.js":6,"./helpers.js":7,"./merge.js":8,"./type.js":9,"./update.js":10,"./watcher.js":11,emmett:3}],5:[function(t,e,r){function n(t,e,r,n){function o(t){if(i.isRecording()&&!i.undoing){var e=a.getIn(t,i.solvedPath,i.tree),r=a.deepClone(e);i.archive.add(r)}return i.undoing=!1,i.emit("update")}var i=this;s.call(this),e=e||[],this.tree=t,this.path=e,this.hash=n,this.archive=null,this.undoing=!1,this._identity="[object Cursor]",this.complexPath=!!r,this.solvedPath=this.complexPath?r:this.path,this.relevant=void 0!==this.get(),this.updateHandler=function(t){var e=t.data.log,r=t.data.previousState,n=!1;if(i.complexPath&&(i.solvedPath=a.solvePath(i.tree.data,i.path,i.tree)),!i.path.length)return o(r);i.solvedPath&&(n=a.solveUpdate(e,[i.solvedPath]));var s=void 0!==i.get();i.relevant?s&&n?o(r):s||(i.emit("irrelevant"),i.relevant=!1):s&&n&&(i.emit("relevant"),o(r),i.relevant=!0)};var h=!1;this._lazyBind=function(){h||(h=!0,i.tree.on("update",i.updateHandler))},this.on=a.before(this._lazyBind,this.on.bind(this)),this.once=a.before(this._lazyBind,this.once.bind(this)),this.complexPath&&this._lazyBind()}function o(t,e,r,n){if(arguments.length>5)throw Error("baobab.Cursor."+t+": too many arguments.");arguments.length<4&&(n=r,r=[]),r=r||[];var o=[].concat(r),i=a.solvePath(this.get(),o,this.tree);if(!i)throw Error("baobab.Cursor."+t+": could not solve dynamic path.");if(e){var s=this.get(i);if(!h[e](s))throw Error("baobab.Cursor."+t+": invalid target.")}var u={};u["$"+t]=n;var c=a.pathObject(i,u);return c}function i(t,e){n.prototype[t]=function(){var r=o.bind(this,t,e).apply(this,arguments);return this.update(r)}}var s=t("emmett"),a=t("./helpers.js"),h=(t("../defaults.js"),t("./type.js"));a.inherits(n,s),n.prototype.isRoot=function(){return!this.path.length},n.prototype.isLeaf=function(){return h.Primitive(this.get())},n.prototype.isBranch=function(){return!this.isLeaf()&&!this.isRoot()},n.prototype.root=function(){return this.tree.root()},n.prototype.select=function(t){if(arguments.length>1&&(t=a.arrayOf(arguments)),!h.Path(t))throw Error("baobab.Cursor.select: invalid path.");return this.tree.select(this.path.concat(t))},n.prototype.up=function(){return this.solvedPath&&this.solvedPath.length?this.tree.select(this.path.slice(0,-1)):null},n.prototype.left=function(){var t=+this.solvedPath[this.solvedPath.length-1];if(isNaN(t))throw Error("baobab.Cursor.left: cannot go left on a non-list type.");return t?this.tree.select(this.solvedPath.slice(0,-1).concat(t-1)):null},n.prototype.leftmost=function(){var t=+this.solvedPath[this.solvedPath.length-1];if(isNaN(t))throw Error("baobab.Cursor.leftmost: cannot go left on a non-list type.");return this.tree.select(this.solvedPath.slice(0,-1).concat(0))},n.prototype.right=function(){var t=+this.solvedPath[this.solvedPath.length-1];if(isNaN(t))throw Error("baobab.Cursor.right: cannot go right on a non-list type.");return t+1===this.up().get().length?null:this.tree.select(this.solvedPath.slice(0,-1).concat(t+1))},n.prototype.rightmost=function(){var t=+this.solvedPath[this.solvedPath.length-1];if(isNaN(t))throw Error("baobab.Cursor.right: cannot go right on a non-list type.");var e=this.up().get();return this.tree.select(this.solvedPath.slice(0,-1).concat(e.length-1))},n.prototype.down=function(){+this.solvedPath[this.solvedPath.length-1];return this.get()instanceof Array?this.tree.select(this.solvedPath.concat(0)):null},n.prototype.get=function(t){arguments.length>1&&(t=a.arrayOf(arguments));var e=this.solvedPath.concat([].concat(t||0===t?t:[]));return a.getIn(this.tree.data,e,this.tree)},i("set"),i("apply"),i("chain"),i("push","Array"),i("unshift","Array"),n.prototype.merge=function(t){if(!h.Object(t))throw Error("baobab.Cursor.merge: trying to merge a non-object.");var e=o.bind(this,"merge","Object").apply(this,arguments);return this.update(e)},n.prototype.unset=function(t){if(void 0===t&&this.isRoot())throw Error("baobab.Cursor.unset: cannot remove root node.");var e=o.bind(this,"unset",null).apply(this,[t,!0]);return this.update(e)},n.prototype.update=function(t,e){if(arguments.length<2)return this.tree.stack(a.pathObject(this.solvedPath,t)),this;var r=[].concat(t),n=a.solvePath(this.get(),r,this.tree);if(!n)throw Error("baobab.Cursor.update: could not solve dynamic path.");return this.tree.stack(a.pathObject(this.solvedPath.concat(n),e)),this},n.prototype.startRecording=function(t){if(t=t||5,1>t)throw Error("baobab.Cursor.startRecording: invalid maximum number of records.");return this.archive?this:(this._lazyBind(),this.archive=a.archive(t),this)},n.prototype.stopRecording=function(){return this.archive=null,this},n.prototype.undo=function(t){if(t=t||1,!this.isRecording())throw Error("baobab.Cursor.undo: cursor is not recording.");if(!h.PositiveInteger(t))throw Error("baobab.Cursor.undo: expecting a positive integer.");var e=this.archive.back(t);if(!e)throw Error("boabab.Cursor.undo: cannot find a relevant record ("+t+" back).");return this.undoing=!0,this.set(e)},n.prototype.isRecording=function(){return!!this.archive},n.prototype.hasHistory=function(){return!(!this.archive||!this.archive.get().length)},n.prototype.getHistory=function(){return this.archive?this.archive.get():[]},n.prototype.release=function(){this.tree.off("update",this.updateHandler),this.hash&&delete this.tree._cursors[this.hash],delete this.tree,delete this.path,delete this.solvedPath,delete this.archive,this.kill()},n.prototype.toJSON=function(){return this.get()},n.prototype.toString=function(){return this._identity},e.exports=n},{"../defaults.js":2,"./helpers.js":7,"./type.js":9,emmett:3}],6:[function(t,e,r){function n(t){return t}function o(t,e){function r(t){o[t]=l[t].bind(l)}var o=this,s=null,a=!1,h=e.get||n,u=e.cursors,c=Object.keys(u).map(function(t){return u[t]}),l=new i(t,c);["on","once","release"].forEach(r),this.get=function(){if(a)return s;var e={};for(var r in u)e[r]=t.get(u[r]);return s=h.call(null,e),a=!0,s},this.on("update",function(){a=!1})}{var i=t("./watcher.js");t("./helpers.js")}e.exports=o},{"./helpers.js":7,"./watcher.js":11}],7:[function(t,e,r){(function(r){function n(t){return Array.prototype.slice.call(t)}function o(t,e){return function(){t(),e.apply(null,arguments)}}function i(t,e,r){var o=n(arguments).slice(3);return e=+e,r=+r,t.slice(0,e).concat(t.slice(e+r).concat(o))}function s(t,e){var r,n={};for(r in t)n[r]=t[r];for(r in e)n[r]=e[r];return n}function a(t){var e=t.source,r="";return t.global&&(r+="g"),t.multiline&&(r+="m"),t.ignoreCase&&(r+="i"),t.sticky&&(r+="y"),t.unicode&&(r+="u"),new RegExp(e,r)}function h(t,e){if(!e||"object"!=typeof e||e instanceof Error||"ArrayBuffer"in r&&e instanceof ArrayBuffer)return e;if(_.Array(e)){if(t){var n,o,i=[];for(n=0,o=e.length;o>n;n++)i.push(P(e[n]));return i}return e.slice(0)}if(_.Date(e))return new Date(e.getTime());if(e instanceof RegExp)return a(e);if(_.Object(e)){var s,h={};e.constructor&&e.constructor!==Object&&(h=Object.create(e.constructor.prototype));for(s in e)e.hasOwnProperty(s)&&(h[s]=t?P(e[s]):e[s]);return h}return e}function u(t,e){return function(r){return e(t(r))}}function c(t,e){var r,n;for(r=0,n=t.length;n>r;r++)if(e(t[r]))return t[r]}function l(t,e){var r,n;for(r=0,n=t.length;n>r;r++)if(e(t[r]))return r;return-1}function f(t,e){var r,n=!0;if(!t)return!1;for(r in e)if(_.Object(e[r]))n=n&&f(t[r],e[r]);else if(_.Array(e[r]))n=n&&!!~e[r].indexOf(t[r]);else if(t[r]!==e[r])return!1;return n}function d(t,e){return c(t,function(t){return f(t,e)})}function y(t,e){return l(t,function(t){return f(t,e)})}function g(t,e,r){e=e||[];var n,o,i,s=t;for(o=0,i=e.length;i>o;o++){if(!s)return;if("function"==typeof e[o]){if(!_.Array(s))return;s=c(s,e[o])}else if("object"==typeof e[o])if(r&&"$cursor"in e[o]){if(!_.Path(e[o].$cursor))throw Error("baobab.getIn: $cursor path must be an array.");n=r.get(e[o].$cursor),s=s[n]}else{if(!_.Array(s))return;s=d(s,e[o])}else s=s[e[o]]}return s}function v(t,e,r){var n,o,i,s=[],a=t;for(o=0,i=e.length;i>o;o++){if(!a)return null;if("function"==typeof e[o]){if(!_.Array(a))return;n=l(a,e[o]),s.push(n),a=a[n]}else if("object"==typeof e[o])if(r&&"$cursor"in e[o]){if(!_.Path(e[o].$cursor))throw Error("baobab.getIn: $cursor path must be an array.");p=r.get(e[o].$cursor),s.push(p),a=a[p]}else{if(!_.Array(a))return;n=y(a,e[o]),s.push(n),a=a[n]}else s.push(e[o]),a=a[e[o]]||{}}return s}function b(t,e){var r,n,o,i,s,a,h,u,c;for(r=0,i=e.length;i>r;r++)for(h=e[r],n=0,s=t.length;s>n;n++)for(u=t[n],o=0,a=u.length;a>o&&(c=u[o],c==h[o]);o++)if(o+1===a||o+1===h.length)return!0;return!1}function m(t,e){var r,n=t.length,o={},i=o;for(n||(o=e),r=0;n>r;r++)i[t[r]]=r+1===n?e:{},i=i[t[r]];return o}function j(t,e){t.super_=e;var r=function(){};r.prototype=e.prototype,t.prototype=new r,t.prototype.constructor=t}function w(t){var e=[];return{add:function(r){e.unshift(r),e.length>t&&(e.length=t)},back:function(t){var r=e[t-1];return r&&(e=e.slice(t)),r},get:function(){return e}}}var _=t("./type.js"),$=h.bind(null,!1),P=h.bind(null,!0);e.exports={archive:w,arrayOf:n,before:o,deepClone:P,shallowClone:$,shallowMerge:s,compose:u,getIn:g,inherits:j,pathObject:m,solvePath:v,solveUpdate:b,splice:i}}).call(this,"undefined"!=typeof global?global:"undefined"!=typeof self?self:"undefined"!=typeof window?window:{})},{"./type.js":9}],8:[function(t,e,r){function n(t,e,r){a.forEach(function(e){r!==e&&delete t[e]}),t[r]=e[r]}function o(t,e){var r,h=i.shallowClone(e||{});a.forEach(function(e){t[e]&&n(h,t,e)}),t.$chain&&(a.slice(0,-1).forEach(function(t){delete h[t]}),h.$apply=h.$apply?i.compose(h.$apply,t.$chain):t.$chain),(t.$splice||h.$splice)&&(h.$splice=[].concat(h.$splice||[]).concat(t.$splice||[])),(t.$push||h.$push)&&(h.$push=[].concat(h.$push||[]).concat(t.$push||[])),(t.$unshift||h.$unshift)&&(h.$unshift=[].concat(t.$unshift||[]).concat(h.$unshift||[]));for(r in t)s.Object(t[r])?h[r]=o(t[r],h[r]):"$"!==r[0]&&(h[r]=t[r]);return h}var i=t("./helpers.js"),s=t("./type.js"),a=["$unset","$set","$merge","$apply"];e.exports=o},{"./helpers.js":7,"./type.js":9}],9:[function(t,e,r){function n(t,e){return e.some(function(e){return o[e](t)})}var o={};o.Array=function(t){return Array.isArray(t)},o.Object=function(t){return t&&"object"==typeof t&&!Array.isArray(t)&&!(t instanceof Function)},o.String=function(t){return"string"==typeof t},o.Number=function(t){return"number"==typeof t},o.PositiveInteger=function(t){return"number"==typeof t&&t>0&&t%1===0},o.Function=function(t){return"function"==typeof t},o.Primitive=function(t){return"string"==typeof t||"number"==typeof t||"boolean"==typeof t},o.Date=function(t){return t instanceof Date},o.NonScalar=function(t){return o.Object(t)||o.Array(t)},o.Path=function(t){var e=["String","Number","Function","Object"];return o.Array(t)?t.every(function(t){return n(t,e)}):n(t,e)},o.MixinCursor=function(t){return n(t,["String","Number","Array","Function","Cursor"])},o.MixinCursors=function(t){return n(t,["Object","Array","Function"])},o.ComplexPath=function(t){return t.some(function(t){return n(t,["Object","Function"])})},e.exports=o},{}],10:[function(t,e,r){function n(t,e){var r=new Error("baobab.update: "+e+" at path /"+t.slice(1).join("/"));return r.path=t,r}var o=t("./helpers.js"),i=t("./type.js");e.exports=function(t,e,r){if(r=r||{},!i.Object(t)&&!i.Array(t))throw Error("baobab.update: invalid target.");var s={};t={root:o.shallowClone(t)};var a=function(t,e,r,h){r=r||["root"];var u,c,l,f=r.join("|λ|"),p=r[r.length-1],d=Object.keys(e).some(function(t){return!!~["$set","$push","$unshift","$splice","$unset","$merge","$apply"].indexOf(t)});if(d){s[f]=!0;for(c in e){if("$unset"===c){var y=r[r.length-2];if(!i.Object(h[y]))throw n(r.slice(0,-1),"using command $unset on a non-object");h[y]=o.shallowClone(t),delete h[y][p];break}if("$set"===c){l=e.$set,t[p]=l;break}if("$apply"===c){if(u=e.$apply,"function"!=typeof u)throw n(r,"using command $apply with a non function");t[p]=u.call(null,t[p]);break}if("$merge"===c){if(l=e.$merge,!i.Object(t[p])||!i.Object(l))throw n(r,"using command $merge with a non object");t[p]=o.shallowMerge(t[p],l);break}if("$splice"===c){if(l=e.$splice,!i.Array(t[p]))throw n(r,"using command $push to a non array");l.forEach(function(e){t[p]=o.splice.apply(null,[t[p]].concat(e))})}if("$push"===c){if(l=e.$push,!i.Array(t[p]))throw n(r,"using command $push to a non array");t[p]=t[p].concat(l)}if("$unshift"===c){if(l=e.$unshift,!i.Array(t[p]))throw n(r,"using command $unshift to a non array");t[p]=[].concat(l).concat(t[p])}}}else for(c in e)t[p][c]="undefined"==typeof t[p][c]?{}:o.shallowClone(t[p][c]),a(t[p],e[c],r.concat(c),t)};return a(t,e),{data:t.root,log:Object.keys(s).map(function(t){return t.split("|λ|").slice(1)})}}},{"./helpers.js":7,"./type.js":9}],11:[function(t,e,r){function n(t,e){function r(){h&&(a=e.map(function(t){return i.solvePath(n.tree.data,t,n.tree)}))}var n=this;o.call(this),this.tree=t;var a=e,h=e.some(s.ComplexPath);this.updateHandler=function(t){var e=i.solveUpdate(t.data.log,a);e&&n.emit("update")},r(),this.tree.on("update",this.updateHandler)}var o=t("emmett"),i=t("./helpers.js"),s=t("./type.js");i.inherits(n,o),n.prototype.release=function(){this.tree.off("update",this.updateHandler),this.tree=null,this.kill()},e.exports=n},{"./helpers.js":7,"./type.js":9,emmett:3}]},{},[1])(1)}); \ No newline at end of file diff --git a/src/merge.js b/src/merge.js index 3e8fd38..06c2f22 100644 --- a/src/merge.js +++ b/src/merge.js @@ -43,6 +43,10 @@ function merge(a, b) { o.$apply = a.$chain; } + if (a.$splice || o.$splice) { + o.$splice = [].concat(o.$splice || []).concat(a.$splice || []); + } + if (a.$push || o.$push) { o.$push = [].concat(o.$push || []).concat(a.$push || []); } diff --git a/src/update.js b/src/update.js index 8db6afc..a5ad012 100644 --- a/src/update.js +++ b/src/update.js @@ -39,7 +39,7 @@ module.exports = function(data, spec, opts) { v; var leafLevel = Object.keys(spec).some(function(k) { - return !!~['$unset', '$set', '$apply', '$merge', '$push', '$unshift'].indexOf(k); + return !!~['$set', '$push', '$unshift', '$splice', '$unset', '$merge', '$apply'].indexOf(k); }); if (leafLevel) { @@ -51,13 +51,11 @@ module.exports = function(data, spec, opts) { if (k === '$unset') { var olderKey = path[path.length - 2]; - if (type.Array(o)) { - parent[olderKey] = helpers.splice(parent[olderKey], +lastKey, 1); - } - else { - parent[olderKey] = helpers.shallowClone(o); - delete parent[olderKey][lastKey]; - } + if (!type.Object(parent[olderKey])) + throw makeError(path.slice(0, -1), 'using command $unset on a non-object'); + + parent[olderKey] = helpers.shallowClone(o); + delete parent[olderKey][lastKey]; break; } @@ -92,6 +90,18 @@ module.exports = function(data, spec, opts) { break; } + // $splice + if (k === '$splice') { + v = spec.$splice; + + if (!type.Array(o[lastKey])) + throw makeError(path, 'using command $push to a non array'); + + v.forEach(function(args) { + o[lastKey] = helpers.splice.apply(null, [o[lastKey]].concat(args)); + }); + } + // $push if (k === '$push') { v = spec.$push; diff --git a/test/suites/cursor.js b/test/suites/cursor.js index f50385d..1f8b71a 100644 --- a/test/suites/cursor.js +++ b/test/suites/cursor.js @@ -261,6 +261,14 @@ describe('Cursor API', function() { cursor.unset(); assert.strictEqual(cursor.get(), undefined); }); + + // it('should be possible to splice an array.', function() { + // var tree = new Baobab({list: [1, 2, 3]}), + // cursor = tree.select('list'); + + // assert.deepEqual(cursor.get(), [1, 2, 3]); + // cursor.splice() + // }); }); }); diff --git a/test/suites/helpers.js b/test/suites/helpers.js index 4aa908a..58e898f 100644 --- a/test/suites/helpers.js +++ b/test/suites/helpers.js @@ -246,15 +246,11 @@ describe('Helpers', function() { assert.deepEqual(o2, {two: 2}); }); - it('should be possible to unset values in an array', function() { + it('should be possible to splice an array.', function() { var o1 = {list: [1, 2, 3]}, - o2 = update(o1, {list: {1: {$unset: true}}}).data; + o2 = update(o1, {list: {$splice: [[0, 1], [1, 1, 4]]}}).data; - assert.deepEqual(o1, {list: [1, 2, 3]}); - assert.deepEqual(o2, {list: [1, 3]}); - - assert.strictEqual(o1.list.length, 3); - assert.strictEqual(o2.list.length, 2); + assert.deepEqual(o2.list, [2, 4]); }); }); }); From 0ebe870f515db7c13c9c3e788f6c96cb3e395503 Mon Sep 17 00:00:00 2001 From: Yomguithereal Date: Thu, 16 Apr 2015 15:14:17 +0200 Subject: [PATCH 59/73] Fixing cursor.merge behavior --- build/baobab.min.js | 2 +- src/cursor.js | 25 +++++++------------------ test/suites/cursor.js | 30 ++++++++---------------------- 3 files changed, 16 insertions(+), 41 deletions(-) diff --git a/build/baobab.min.js b/build/baobab.min.js index cbfe3ed..1f86654 100644 --- a/build/baobab.min.js +++ b/build/baobab.min.js @@ -1,2 +1,2 @@ /* baobab.js - Version: 1.0.0-rc1 - Author: Yomguithereal (Guillaume Plique) */ -!function(t){if("object"==typeof exports&&"undefined"!=typeof module)module.exports=t();else if("function"==typeof define&&define.amd)define([],t);else{var e;e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:this,e.Baobab=t()}}(function(){var t;return function e(t,r,n){function o(s,a){if(!r[s]){if(!t[s]){var h="function"==typeof require&&require;if(!a&&h)return h(s,!0);if(i)return i(s,!0);var u=new Error("Cannot find module '"+s+"'");throw u.code="MODULE_NOT_FOUND",u}var c=r[s]={exports:{}};t[s][0].call(c.exports,function(e){var r=t[s][1][e];return o(r?r:e)},c,c.exports,e,t,r,n)}return r[s].exports}for(var i="function"==typeof require&&require,s=0;sn;n++)t[n].fn!==e&&o.push(t[n]);return o}var s={once:"boolean",scope:"object"},a=0,h=function(){this._enabled=!0,this.unbindAll()};h.prototype.unbindAll=function(){return this._handlers={},this._handlersAll=[],this._handlersComplex=[],this},h.prototype.on=function(t,e,r){var n,i,h,u,c,l,f;if(o(t)){for(u in t)this.on(u,t[u],e);return this}for("function"==typeof t&&(r=e,e=t,t=null),c=[].concat(t),n=0,i=c.length;i>n;n++){if(u=c[n],f={order:a++,fn:e},"string"==typeof u)this._handlers[u]||(this._handlers[u]=[]),l=this._handlers[u];else if(u instanceof RegExp)l=this._handlersComplex,f.pattern=u;else{if(null!==u)throw Error("Emitter.on: invalid event.");l=this._handlersAll}for(h in r||{})s[h]&&(f[h]=r[h]);f.once&&(f.parent=l),l.push(f)}return this},h.prototype.once=function(){var t=Array.prototype.slice.call(arguments),r=t.length-1;return o(t[r])&&t.length>1?t[r]=e(t[r],{once:!0}):t.push({once:!0}),this.on.apply(this,t)},h.prototype.off=function(t,e){var r,n,s,a;if(1===arguments.length&&"function"==typeof t){e=arguments[0];for(s in this._handlers)this._handlers[s]=i(this._handlers[s],e),0===this._handlers[s].length&&delete this._handlers[s];this._handlersAll=i(this._handlersAll,e),this._handlersComplex=i(this._handlersComplex,e)}else if(1===arguments.length&&"string"==typeof t)delete this._handlers[t];else if(2===arguments.length){var h=[].concat(t);for(r=0,n=h.length;n>r;r++)a=h[r],this._handlers[a]=i(this._handlers[a],e),0===(this._handlers[a]||[]).length&&delete this._handlers[a]}else if(o(t))for(s in t)this.off(s,t[s]);return this},h.prototype.listeners=function(t){var e,r,n,o=this._handlersAll||[],i=!1;if(!t)throw Error("Emitter.listeners: no event provided.");for(o=o.concat(this._handlers[t]||[]),r=0,n=this._handlersComplex.length;n>r;r++)e=this._handlersComplex[r],~t.search(e.pattern)&&(i=!0,o.push(e));return this._handlersAll.length||i?o.sort(function(t,e){return t.order-e.order}):o.slice(0)},h.prototype.emit=function(t,e){if(!this._enabled)return this;if(o(t)){for(var r in t)this.emit(r,t[r]);return this}var n,i,s,a,h,u,c,l=[].concat(t),f=[];for(a=0,u=l.length;u>a;a++){for(i=this.listeners(l[a]),h=0,c=i.length;c>h;h++)s=i[h],n={type:l[a],target:this},arguments.length>1&&(n.data=e),s.fn.call("scope"in s?s.scope:this,n),s.once&&f.push(s);for(h=f.length-1;h>=0;h--)f[h].parent.splice(f[h].parent.indexOf(f[h]),1)}return this},h.prototype.kill=function(){this.unbindAll(),this._handlers=null,this._handlersAll=null,this._handlersComplex=null,this._enabled=!1},h.prototype.disable=function(){return this._enabled=!1,this},h.prototype.enable=function(){return this._enabled=!0,this},h.version="3.0.0","undefined"!=typeof n?("undefined"!=typeof r&&r.exports&&(n=r.exports=h),n.Emitter=h):"function"==typeof t&&t.amd?t("emmett",[],function(){return h}):this.Emitter=h}).call(this)},{}],4:[function(t,e,r){function n(t){return t+"$"+(new Date).getTime()+(""+Math.random()).replace("0.","")}function o(t,e){function r(t){this[t]=function(){var e=this.root[t].apply(this.root,arguments);return e instanceof i?this:e}}if(arguments.length<1&&(t={}),!(this instanceof o))return new o(t,e);if(!p.Object(t)&&!p.Array(t))throw Error("Baobab: invalid data.");if(s.call(this),this.options=u.shallowMerge(f,e),this._transaction={},this._future=void 0,this._cursors={},this._identity="[object Baobab]",this.data=u.deepClone(t),this.root=this.select([]),this.facets={},["get","set","unset","update"].forEach(r.bind(this)),!p.Object(this.options.facets))throw Error("Baobab: invalid facets.");for(var n in this.options.facets)this.addFacet(n,this.options.facets[n])}var i=t("./cursor.js"),s=t("emmett"),a=t("./watcher.js"),h=t("./facet.js"),u=t("./helpers.js"),c=t("./update.js"),l=t("./merge.js"),f=t("../defaults.js"),p=t("./type.js");u.inherits(o,s),o.prototype.addFacet=function(t,e){return this.facets[t]=this.createFacet(e),this},o.prototype.createFacet=function(t){return new h(this,t)},o.prototype.select=function(t){if(!t)throw Error("Baobab.select: invalid path.");if(arguments.length>1&&(t=u.arrayOf(arguments)),!p.Path(t))throw Error("Baobab.select: invalid path.");t=[].concat(t);var e,r=p.ComplexPath(t);r&&(e=u.solvePath(this.data,t,this));var o=t.map(function(t){return p.Function(t)?n("fn"):p.Object(t)?n("ob"):t}).join("|λ|");if(this._cursors[o])return this._cursors[o];var s=new i(this,t,e,o);return this._cursors[o]=s,s},o.prototype.stack=function(t){var e=this;if(!p.Object(t))throw Error("Baobab.update: wrong specification.");return this._transaction=l(t,this._transaction),this.options.autoCommit?this.options.asynchronous?(this._future||(this._future=setTimeout(e.commit.bind(e,null),0)),this):this.commit():this},o.prototype.commit=function(){var t=c(this.data,this._transaction,this.options),e=this.data;this._transaction={},this._future&&(this._future=clearTimeout(this._future));var r=this.options.validate,n=this.options.validationBehaviour;if("function"==typeof r){var o=r.call(this,e,t.data,t.log);if(o instanceof Error&&(this.emit("invalid",{error:o}),"rollback"===n))return this}return this.data=t.data,this.emit("update",{log:t.log,previousState:e}),this},o.prototype.watch=function(t){if(!p.Array(t)||t.some(function(t){return!p.Path(t)}))throw Error("Baobab.watch: invalid paths.");return new a(this,[].concat(t))},o.prototype.release=function(){var t;delete this.data,delete this._transaction;for(t in this._cursors)this._cursors[t].release();delete this._cursors;for(t in this.facets)this.facets[t].release();delete this.facets,this.kill()},o.prototype.toJSON=function(){return this.get()},o.prototype.toString=function(){return this._identity},e.exports=o},{"../defaults.js":2,"./cursor.js":5,"./facet.js":6,"./helpers.js":7,"./merge.js":8,"./type.js":9,"./update.js":10,"./watcher.js":11,emmett:3}],5:[function(t,e,r){function n(t,e,r,n){function o(t){if(i.isRecording()&&!i.undoing){var e=a.getIn(t,i.solvedPath,i.tree),r=a.deepClone(e);i.archive.add(r)}return i.undoing=!1,i.emit("update")}var i=this;s.call(this),e=e||[],this.tree=t,this.path=e,this.hash=n,this.archive=null,this.undoing=!1,this._identity="[object Cursor]",this.complexPath=!!r,this.solvedPath=this.complexPath?r:this.path,this.relevant=void 0!==this.get(),this.updateHandler=function(t){var e=t.data.log,r=t.data.previousState,n=!1;if(i.complexPath&&(i.solvedPath=a.solvePath(i.tree.data,i.path,i.tree)),!i.path.length)return o(r);i.solvedPath&&(n=a.solveUpdate(e,[i.solvedPath]));var s=void 0!==i.get();i.relevant?s&&n?o(r):s||(i.emit("irrelevant"),i.relevant=!1):s&&n&&(i.emit("relevant"),o(r),i.relevant=!0)};var h=!1;this._lazyBind=function(){h||(h=!0,i.tree.on("update",i.updateHandler))},this.on=a.before(this._lazyBind,this.on.bind(this)),this.once=a.before(this._lazyBind,this.once.bind(this)),this.complexPath&&this._lazyBind()}function o(t,e,r,n){if(arguments.length>5)throw Error("baobab.Cursor."+t+": too many arguments.");arguments.length<4&&(n=r,r=[]),r=r||[];var o=[].concat(r),i=a.solvePath(this.get(),o,this.tree);if(!i)throw Error("baobab.Cursor."+t+": could not solve dynamic path.");if(e){var s=this.get(i);if(!h[e](s))throw Error("baobab.Cursor."+t+": invalid target.")}var u={};u["$"+t]=n;var c=a.pathObject(i,u);return c}function i(t,e){n.prototype[t]=function(){var r=o.bind(this,t,e).apply(this,arguments);return this.update(r)}}var s=t("emmett"),a=t("./helpers.js"),h=(t("../defaults.js"),t("./type.js"));a.inherits(n,s),n.prototype.isRoot=function(){return!this.path.length},n.prototype.isLeaf=function(){return h.Primitive(this.get())},n.prototype.isBranch=function(){return!this.isLeaf()&&!this.isRoot()},n.prototype.root=function(){return this.tree.root()},n.prototype.select=function(t){if(arguments.length>1&&(t=a.arrayOf(arguments)),!h.Path(t))throw Error("baobab.Cursor.select: invalid path.");return this.tree.select(this.path.concat(t))},n.prototype.up=function(){return this.solvedPath&&this.solvedPath.length?this.tree.select(this.path.slice(0,-1)):null},n.prototype.left=function(){var t=+this.solvedPath[this.solvedPath.length-1];if(isNaN(t))throw Error("baobab.Cursor.left: cannot go left on a non-list type.");return t?this.tree.select(this.solvedPath.slice(0,-1).concat(t-1)):null},n.prototype.leftmost=function(){var t=+this.solvedPath[this.solvedPath.length-1];if(isNaN(t))throw Error("baobab.Cursor.leftmost: cannot go left on a non-list type.");return this.tree.select(this.solvedPath.slice(0,-1).concat(0))},n.prototype.right=function(){var t=+this.solvedPath[this.solvedPath.length-1];if(isNaN(t))throw Error("baobab.Cursor.right: cannot go right on a non-list type.");return t+1===this.up().get().length?null:this.tree.select(this.solvedPath.slice(0,-1).concat(t+1))},n.prototype.rightmost=function(){var t=+this.solvedPath[this.solvedPath.length-1];if(isNaN(t))throw Error("baobab.Cursor.right: cannot go right on a non-list type.");var e=this.up().get();return this.tree.select(this.solvedPath.slice(0,-1).concat(e.length-1))},n.prototype.down=function(){+this.solvedPath[this.solvedPath.length-1];return this.get()instanceof Array?this.tree.select(this.solvedPath.concat(0)):null},n.prototype.get=function(t){arguments.length>1&&(t=a.arrayOf(arguments));var e=this.solvedPath.concat([].concat(t||0===t?t:[]));return a.getIn(this.tree.data,e,this.tree)},i("set"),i("apply"),i("chain"),i("push","Array"),i("unshift","Array"),n.prototype.merge=function(t){if(!h.Object(t))throw Error("baobab.Cursor.merge: trying to merge a non-object.");var e=o.bind(this,"merge","Object").apply(this,arguments);return this.update(e)},n.prototype.unset=function(t){if(void 0===t&&this.isRoot())throw Error("baobab.Cursor.unset: cannot remove root node.");var e=o.bind(this,"unset",null).apply(this,[t,!0]);return this.update(e)},n.prototype.update=function(t,e){if(arguments.length<2)return this.tree.stack(a.pathObject(this.solvedPath,t)),this;var r=[].concat(t),n=a.solvePath(this.get(),r,this.tree);if(!n)throw Error("baobab.Cursor.update: could not solve dynamic path.");return this.tree.stack(a.pathObject(this.solvedPath.concat(n),e)),this},n.prototype.startRecording=function(t){if(t=t||5,1>t)throw Error("baobab.Cursor.startRecording: invalid maximum number of records.");return this.archive?this:(this._lazyBind(),this.archive=a.archive(t),this)},n.prototype.stopRecording=function(){return this.archive=null,this},n.prototype.undo=function(t){if(t=t||1,!this.isRecording())throw Error("baobab.Cursor.undo: cursor is not recording.");if(!h.PositiveInteger(t))throw Error("baobab.Cursor.undo: expecting a positive integer.");var e=this.archive.back(t);if(!e)throw Error("boabab.Cursor.undo: cannot find a relevant record ("+t+" back).");return this.undoing=!0,this.set(e)},n.prototype.isRecording=function(){return!!this.archive},n.prototype.hasHistory=function(){return!(!this.archive||!this.archive.get().length)},n.prototype.getHistory=function(){return this.archive?this.archive.get():[]},n.prototype.release=function(){this.tree.off("update",this.updateHandler),this.hash&&delete this.tree._cursors[this.hash],delete this.tree,delete this.path,delete this.solvedPath,delete this.archive,this.kill()},n.prototype.toJSON=function(){return this.get()},n.prototype.toString=function(){return this._identity},e.exports=n},{"../defaults.js":2,"./helpers.js":7,"./type.js":9,emmett:3}],6:[function(t,e,r){function n(t){return t}function o(t,e){function r(t){o[t]=l[t].bind(l)}var o=this,s=null,a=!1,h=e.get||n,u=e.cursors,c=Object.keys(u).map(function(t){return u[t]}),l=new i(t,c);["on","once","release"].forEach(r),this.get=function(){if(a)return s;var e={};for(var r in u)e[r]=t.get(u[r]);return s=h.call(null,e),a=!0,s},this.on("update",function(){a=!1})}{var i=t("./watcher.js");t("./helpers.js")}e.exports=o},{"./helpers.js":7,"./watcher.js":11}],7:[function(t,e,r){(function(r){function n(t){return Array.prototype.slice.call(t)}function o(t,e){return function(){t(),e.apply(null,arguments)}}function i(t,e,r){var o=n(arguments).slice(3);return e=+e,r=+r,t.slice(0,e).concat(t.slice(e+r).concat(o))}function s(t,e){var r,n={};for(r in t)n[r]=t[r];for(r in e)n[r]=e[r];return n}function a(t){var e=t.source,r="";return t.global&&(r+="g"),t.multiline&&(r+="m"),t.ignoreCase&&(r+="i"),t.sticky&&(r+="y"),t.unicode&&(r+="u"),new RegExp(e,r)}function h(t,e){if(!e||"object"!=typeof e||e instanceof Error||"ArrayBuffer"in r&&e instanceof ArrayBuffer)return e;if(_.Array(e)){if(t){var n,o,i=[];for(n=0,o=e.length;o>n;n++)i.push(P(e[n]));return i}return e.slice(0)}if(_.Date(e))return new Date(e.getTime());if(e instanceof RegExp)return a(e);if(_.Object(e)){var s,h={};e.constructor&&e.constructor!==Object&&(h=Object.create(e.constructor.prototype));for(s in e)e.hasOwnProperty(s)&&(h[s]=t?P(e[s]):e[s]);return h}return e}function u(t,e){return function(r){return e(t(r))}}function c(t,e){var r,n;for(r=0,n=t.length;n>r;r++)if(e(t[r]))return t[r]}function l(t,e){var r,n;for(r=0,n=t.length;n>r;r++)if(e(t[r]))return r;return-1}function f(t,e){var r,n=!0;if(!t)return!1;for(r in e)if(_.Object(e[r]))n=n&&f(t[r],e[r]);else if(_.Array(e[r]))n=n&&!!~e[r].indexOf(t[r]);else if(t[r]!==e[r])return!1;return n}function d(t,e){return c(t,function(t){return f(t,e)})}function y(t,e){return l(t,function(t){return f(t,e)})}function g(t,e,r){e=e||[];var n,o,i,s=t;for(o=0,i=e.length;i>o;o++){if(!s)return;if("function"==typeof e[o]){if(!_.Array(s))return;s=c(s,e[o])}else if("object"==typeof e[o])if(r&&"$cursor"in e[o]){if(!_.Path(e[o].$cursor))throw Error("baobab.getIn: $cursor path must be an array.");n=r.get(e[o].$cursor),s=s[n]}else{if(!_.Array(s))return;s=d(s,e[o])}else s=s[e[o]]}return s}function v(t,e,r){var n,o,i,s=[],a=t;for(o=0,i=e.length;i>o;o++){if(!a)return null;if("function"==typeof e[o]){if(!_.Array(a))return;n=l(a,e[o]),s.push(n),a=a[n]}else if("object"==typeof e[o])if(r&&"$cursor"in e[o]){if(!_.Path(e[o].$cursor))throw Error("baobab.getIn: $cursor path must be an array.");p=r.get(e[o].$cursor),s.push(p),a=a[p]}else{if(!_.Array(a))return;n=y(a,e[o]),s.push(n),a=a[n]}else s.push(e[o]),a=a[e[o]]||{}}return s}function b(t,e){var r,n,o,i,s,a,h,u,c;for(r=0,i=e.length;i>r;r++)for(h=e[r],n=0,s=t.length;s>n;n++)for(u=t[n],o=0,a=u.length;a>o&&(c=u[o],c==h[o]);o++)if(o+1===a||o+1===h.length)return!0;return!1}function m(t,e){var r,n=t.length,o={},i=o;for(n||(o=e),r=0;n>r;r++)i[t[r]]=r+1===n?e:{},i=i[t[r]];return o}function j(t,e){t.super_=e;var r=function(){};r.prototype=e.prototype,t.prototype=new r,t.prototype.constructor=t}function w(t){var e=[];return{add:function(r){e.unshift(r),e.length>t&&(e.length=t)},back:function(t){var r=e[t-1];return r&&(e=e.slice(t)),r},get:function(){return e}}}var _=t("./type.js"),$=h.bind(null,!1),P=h.bind(null,!0);e.exports={archive:w,arrayOf:n,before:o,deepClone:P,shallowClone:$,shallowMerge:s,compose:u,getIn:g,inherits:j,pathObject:m,solvePath:v,solveUpdate:b,splice:i}}).call(this,"undefined"!=typeof global?global:"undefined"!=typeof self?self:"undefined"!=typeof window?window:{})},{"./type.js":9}],8:[function(t,e,r){function n(t,e,r){a.forEach(function(e){r!==e&&delete t[e]}),t[r]=e[r]}function o(t,e){var r,h=i.shallowClone(e||{});a.forEach(function(e){t[e]&&n(h,t,e)}),t.$chain&&(a.slice(0,-1).forEach(function(t){delete h[t]}),h.$apply=h.$apply?i.compose(h.$apply,t.$chain):t.$chain),(t.$splice||h.$splice)&&(h.$splice=[].concat(h.$splice||[]).concat(t.$splice||[])),(t.$push||h.$push)&&(h.$push=[].concat(h.$push||[]).concat(t.$push||[])),(t.$unshift||h.$unshift)&&(h.$unshift=[].concat(t.$unshift||[]).concat(h.$unshift||[]));for(r in t)s.Object(t[r])?h[r]=o(t[r],h[r]):"$"!==r[0]&&(h[r]=t[r]);return h}var i=t("./helpers.js"),s=t("./type.js"),a=["$unset","$set","$merge","$apply"];e.exports=o},{"./helpers.js":7,"./type.js":9}],9:[function(t,e,r){function n(t,e){return e.some(function(e){return o[e](t)})}var o={};o.Array=function(t){return Array.isArray(t)},o.Object=function(t){return t&&"object"==typeof t&&!Array.isArray(t)&&!(t instanceof Function)},o.String=function(t){return"string"==typeof t},o.Number=function(t){return"number"==typeof t},o.PositiveInteger=function(t){return"number"==typeof t&&t>0&&t%1===0},o.Function=function(t){return"function"==typeof t},o.Primitive=function(t){return"string"==typeof t||"number"==typeof t||"boolean"==typeof t},o.Date=function(t){return t instanceof Date},o.NonScalar=function(t){return o.Object(t)||o.Array(t)},o.Path=function(t){var e=["String","Number","Function","Object"];return o.Array(t)?t.every(function(t){return n(t,e)}):n(t,e)},o.MixinCursor=function(t){return n(t,["String","Number","Array","Function","Cursor"])},o.MixinCursors=function(t){return n(t,["Object","Array","Function"])},o.ComplexPath=function(t){return t.some(function(t){return n(t,["Object","Function"])})},e.exports=o},{}],10:[function(t,e,r){function n(t,e){var r=new Error("baobab.update: "+e+" at path /"+t.slice(1).join("/"));return r.path=t,r}var o=t("./helpers.js"),i=t("./type.js");e.exports=function(t,e,r){if(r=r||{},!i.Object(t)&&!i.Array(t))throw Error("baobab.update: invalid target.");var s={};t={root:o.shallowClone(t)};var a=function(t,e,r,h){r=r||["root"];var u,c,l,f=r.join("|λ|"),p=r[r.length-1],d=Object.keys(e).some(function(t){return!!~["$set","$push","$unshift","$splice","$unset","$merge","$apply"].indexOf(t)});if(d){s[f]=!0;for(c in e){if("$unset"===c){var y=r[r.length-2];if(!i.Object(h[y]))throw n(r.slice(0,-1),"using command $unset on a non-object");h[y]=o.shallowClone(t),delete h[y][p];break}if("$set"===c){l=e.$set,t[p]=l;break}if("$apply"===c){if(u=e.$apply,"function"!=typeof u)throw n(r,"using command $apply with a non function");t[p]=u.call(null,t[p]);break}if("$merge"===c){if(l=e.$merge,!i.Object(t[p])||!i.Object(l))throw n(r,"using command $merge with a non object");t[p]=o.shallowMerge(t[p],l);break}if("$splice"===c){if(l=e.$splice,!i.Array(t[p]))throw n(r,"using command $push to a non array");l.forEach(function(e){t[p]=o.splice.apply(null,[t[p]].concat(e))})}if("$push"===c){if(l=e.$push,!i.Array(t[p]))throw n(r,"using command $push to a non array");t[p]=t[p].concat(l)}if("$unshift"===c){if(l=e.$unshift,!i.Array(t[p]))throw n(r,"using command $unshift to a non array");t[p]=[].concat(l).concat(t[p])}}}else for(c in e)t[p][c]="undefined"==typeof t[p][c]?{}:o.shallowClone(t[p][c]),a(t[p],e[c],r.concat(c),t)};return a(t,e),{data:t.root,log:Object.keys(s).map(function(t){return t.split("|λ|").slice(1)})}}},{"./helpers.js":7,"./type.js":9}],11:[function(t,e,r){function n(t,e){function r(){h&&(a=e.map(function(t){return i.solvePath(n.tree.data,t,n.tree)}))}var n=this;o.call(this),this.tree=t;var a=e,h=e.some(s.ComplexPath);this.updateHandler=function(t){var e=i.solveUpdate(t.data.log,a);e&&n.emit("update")},r(),this.tree.on("update",this.updateHandler)}var o=t("emmett"),i=t("./helpers.js"),s=t("./type.js");i.inherits(n,o),n.prototype.release=function(){this.tree.off("update",this.updateHandler),this.tree=null,this.kill()},e.exports=n},{"./helpers.js":7,"./type.js":9,emmett:3}]},{},[1])(1)}); \ No newline at end of file +!function(t){if("object"==typeof exports&&"undefined"!=typeof module)module.exports=t();else if("function"==typeof define&&define.amd)define([],t);else{var e;e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:this,e.Baobab=t()}}(function(){var t;return function e(t,r,n){function o(s,a){if(!r[s]){if(!t[s]){var h="function"==typeof require&&require;if(!a&&h)return h(s,!0);if(i)return i(s,!0);var u=new Error("Cannot find module '"+s+"'");throw u.code="MODULE_NOT_FOUND",u}var c=r[s]={exports:{}};t[s][0].call(c.exports,function(e){var r=t[s][1][e];return o(r?r:e)},c,c.exports,e,t,r,n)}return r[s].exports}for(var i="function"==typeof require&&require,s=0;sn;n++)t[n].fn!==e&&o.push(t[n]);return o}var s={once:"boolean",scope:"object"},a=0,h=function(){this._enabled=!0,this.unbindAll()};h.prototype.unbindAll=function(){return this._handlers={},this._handlersAll=[],this._handlersComplex=[],this},h.prototype.on=function(t,e,r){var n,i,h,u,c,l,f;if(o(t)){for(u in t)this.on(u,t[u],e);return this}for("function"==typeof t&&(r=e,e=t,t=null),c=[].concat(t),n=0,i=c.length;i>n;n++){if(u=c[n],f={order:a++,fn:e},"string"==typeof u)this._handlers[u]||(this._handlers[u]=[]),l=this._handlers[u];else if(u instanceof RegExp)l=this._handlersComplex,f.pattern=u;else{if(null!==u)throw Error("Emitter.on: invalid event.");l=this._handlersAll}for(h in r||{})s[h]&&(f[h]=r[h]);f.once&&(f.parent=l),l.push(f)}return this},h.prototype.once=function(){var t=Array.prototype.slice.call(arguments),r=t.length-1;return o(t[r])&&t.length>1?t[r]=e(t[r],{once:!0}):t.push({once:!0}),this.on.apply(this,t)},h.prototype.off=function(t,e){var r,n,s,a;if(1===arguments.length&&"function"==typeof t){e=arguments[0];for(s in this._handlers)this._handlers[s]=i(this._handlers[s],e),0===this._handlers[s].length&&delete this._handlers[s];this._handlersAll=i(this._handlersAll,e),this._handlersComplex=i(this._handlersComplex,e)}else if(1===arguments.length&&"string"==typeof t)delete this._handlers[t];else if(2===arguments.length){var h=[].concat(t);for(r=0,n=h.length;n>r;r++)a=h[r],this._handlers[a]=i(this._handlers[a],e),0===(this._handlers[a]||[]).length&&delete this._handlers[a]}else if(o(t))for(s in t)this.off(s,t[s]);return this},h.prototype.listeners=function(t){var e,r,n,o=this._handlersAll||[],i=!1;if(!t)throw Error("Emitter.listeners: no event provided.");for(o=o.concat(this._handlers[t]||[]),r=0,n=this._handlersComplex.length;n>r;r++)e=this._handlersComplex[r],~t.search(e.pattern)&&(i=!0,o.push(e));return this._handlersAll.length||i?o.sort(function(t,e){return t.order-e.order}):o.slice(0)},h.prototype.emit=function(t,e){if(!this._enabled)return this;if(o(t)){for(var r in t)this.emit(r,t[r]);return this}var n,i,s,a,h,u,c,l=[].concat(t),f=[];for(a=0,u=l.length;u>a;a++){for(i=this.listeners(l[a]),h=0,c=i.length;c>h;h++)s=i[h],n={type:l[a],target:this},arguments.length>1&&(n.data=e),s.fn.call("scope"in s?s.scope:this,n),s.once&&f.push(s);for(h=f.length-1;h>=0;h--)f[h].parent.splice(f[h].parent.indexOf(f[h]),1)}return this},h.prototype.kill=function(){this.unbindAll(),this._handlers=null,this._handlersAll=null,this._handlersComplex=null,this._enabled=!1},h.prototype.disable=function(){return this._enabled=!1,this},h.prototype.enable=function(){return this._enabled=!0,this},h.version="3.0.0","undefined"!=typeof n?("undefined"!=typeof r&&r.exports&&(n=r.exports=h),n.Emitter=h):"function"==typeof t&&t.amd?t("emmett",[],function(){return h}):this.Emitter=h}).call(this)},{}],4:[function(t,e,r){function n(t){return t+"$"+(new Date).getTime()+(""+Math.random()).replace("0.","")}function o(t,e){function r(t){this[t]=function(){var e=this.root[t].apply(this.root,arguments);return e instanceof i?this:e}}if(arguments.length<1&&(t={}),!(this instanceof o))return new o(t,e);if(!p.Object(t)&&!p.Array(t))throw Error("Baobab: invalid data.");if(s.call(this),this.options=u.shallowMerge(f,e),this._transaction={},this._future=void 0,this._cursors={},this._identity="[object Baobab]",this.data=u.deepClone(t),this.root=this.select([]),this.facets={},["get","set","unset","update"].forEach(r.bind(this)),!p.Object(this.options.facets))throw Error("Baobab: invalid facets.");for(var n in this.options.facets)this.addFacet(n,this.options.facets[n])}var i=t("./cursor.js"),s=t("emmett"),a=t("./watcher.js"),h=t("./facet.js"),u=t("./helpers.js"),c=t("./update.js"),l=t("./merge.js"),f=t("../defaults.js"),p=t("./type.js");u.inherits(o,s),o.prototype.addFacet=function(t,e){return this.facets[t]=this.createFacet(e),this},o.prototype.createFacet=function(t){return new h(this,t)},o.prototype.select=function(t){if(!t)throw Error("Baobab.select: invalid path.");if(arguments.length>1&&(t=u.arrayOf(arguments)),!p.Path(t))throw Error("Baobab.select: invalid path.");t=[].concat(t);var e,r=p.ComplexPath(t);r&&(e=u.solvePath(this.data,t,this));var o=t.map(function(t){return p.Function(t)?n("fn"):p.Object(t)?n("ob"):t}).join("|λ|");if(this._cursors[o])return this._cursors[o];var s=new i(this,t,e,o);return this._cursors[o]=s,s},o.prototype.stack=function(t){var e=this;if(!p.Object(t))throw Error("Baobab.update: wrong specification.");return this._transaction=l(t,this._transaction),this.options.autoCommit?this.options.asynchronous?(this._future||(this._future=setTimeout(e.commit.bind(e,null),0)),this):this.commit():this},o.prototype.commit=function(){var t=c(this.data,this._transaction,this.options),e=this.data;this._transaction={},this._future&&(this._future=clearTimeout(this._future));var r=this.options.validate,n=this.options.validationBehaviour;if("function"==typeof r){var o=r.call(this,e,t.data,t.log);if(o instanceof Error&&(this.emit("invalid",{error:o}),"rollback"===n))return this}return this.data=t.data,this.emit("update",{log:t.log,previousState:e}),this},o.prototype.watch=function(t){if(!p.Array(t)||t.some(function(t){return!p.Path(t)}))throw Error("Baobab.watch: invalid paths.");return new a(this,[].concat(t))},o.prototype.release=function(){var t;delete this.data,delete this._transaction;for(t in this._cursors)this._cursors[t].release();delete this._cursors;for(t in this.facets)this.facets[t].release();delete this.facets,this.kill()},o.prototype.toJSON=function(){return this.get()},o.prototype.toString=function(){return this._identity},e.exports=o},{"../defaults.js":2,"./cursor.js":5,"./facet.js":6,"./helpers.js":7,"./merge.js":8,"./type.js":9,"./update.js":10,"./watcher.js":11,emmett:3}],5:[function(t,e,r){function n(t,e,r,n){function o(t){if(i.isRecording()&&!i.undoing){var e=a.getIn(t,i.solvedPath,i.tree),r=a.deepClone(e);i.archive.add(r)}return i.undoing=!1,i.emit("update")}var i=this;s.call(this),e=e||[],this.tree=t,this.path=e,this.hash=n,this.archive=null,this.undoing=!1,this._identity="[object Cursor]",this.complexPath=!!r,this.solvedPath=this.complexPath?r:this.path,this.relevant=void 0!==this.get(),this.updateHandler=function(t){var e=t.data.log,r=t.data.previousState,n=!1;if(i.complexPath&&(i.solvedPath=a.solvePath(i.tree.data,i.path,i.tree)),!i.path.length)return o(r);i.solvedPath&&(n=a.solveUpdate(e,[i.solvedPath]));var s=void 0!==i.get();i.relevant?s&&n?o(r):s||(i.emit("irrelevant"),i.relevant=!1):s&&n&&(i.emit("relevant"),o(r),i.relevant=!0)};var h=!1;this._lazyBind=function(){h||(h=!0,i.tree.on("update",i.updateHandler))},this.on=a.before(this._lazyBind,this.on.bind(this)),this.once=a.before(this._lazyBind,this.once.bind(this)),this.complexPath&&this._lazyBind()}function o(t,e,r,n){if(arguments.length>5)throw Error("baobab.Cursor."+t+": too many arguments.");if(arguments.length<4&&(n=r,r=[]),r=r||[],e&&!e(n))throw Error("baobab.Cursor."+t+": incorrect value.");var o=[].concat(r),i=a.solvePath(this.get(),o,this.tree);if(!i)throw Error("baobab.Cursor."+t+": could not solve dynamic path.");var s={};s["$"+t]=n;var h=a.pathObject(i,s);return h}function i(t,e){n.prototype[t]=function(){var r=o.bind(this,t,e).apply(this,arguments);return this.update(r)}}var s=t("emmett"),a=t("./helpers.js"),h=(t("../defaults.js"),t("./type.js"));a.inherits(n,s),n.prototype.isRoot=function(){return!this.path.length},n.prototype.isLeaf=function(){return h.Primitive(this.get())},n.prototype.isBranch=function(){return!this.isLeaf()&&!this.isRoot()},n.prototype.root=function(){return this.tree.root()},n.prototype.select=function(t){if(arguments.length>1&&(t=a.arrayOf(arguments)),!h.Path(t))throw Error("baobab.Cursor.select: invalid path.");return this.tree.select(this.path.concat(t))},n.prototype.up=function(){return this.solvedPath&&this.solvedPath.length?this.tree.select(this.path.slice(0,-1)):null},n.prototype.left=function(){var t=+this.solvedPath[this.solvedPath.length-1];if(isNaN(t))throw Error("baobab.Cursor.left: cannot go left on a non-list type.");return t?this.tree.select(this.solvedPath.slice(0,-1).concat(t-1)):null},n.prototype.leftmost=function(){var t=+this.solvedPath[this.solvedPath.length-1];if(isNaN(t))throw Error("baobab.Cursor.leftmost: cannot go left on a non-list type.");return this.tree.select(this.solvedPath.slice(0,-1).concat(0))},n.prototype.right=function(){var t=+this.solvedPath[this.solvedPath.length-1];if(isNaN(t))throw Error("baobab.Cursor.right: cannot go right on a non-list type.");return t+1===this.up().get().length?null:this.tree.select(this.solvedPath.slice(0,-1).concat(t+1))},n.prototype.rightmost=function(){var t=+this.solvedPath[this.solvedPath.length-1];if(isNaN(t))throw Error("baobab.Cursor.right: cannot go right on a non-list type.");var e=this.up().get();return this.tree.select(this.solvedPath.slice(0,-1).concat(e.length-1))},n.prototype.down=function(){+this.solvedPath[this.solvedPath.length-1];return this.get()instanceof Array?this.tree.select(this.solvedPath.concat(0)):null},n.prototype.get=function(t){arguments.length>1&&(t=a.arrayOf(arguments));var e=this.solvedPath.concat([].concat(t||0===t?t:[]));return a.getIn(this.tree.data,e,this.tree)},i("set"),i("apply"),i("chain"),i("push"),i("unshift"),i("merge",h.Object),n.prototype.unset=function(t){if(void 0===t&&this.isRoot())throw Error("baobab.Cursor.unset: cannot remove root node.");var e=o.bind(this,"unset",null).apply(this,[t,!0]);return this.update(e)},n.prototype.update=function(t,e){if(arguments.length<2)return this.tree.stack(a.pathObject(this.solvedPath,t)),this;var r=[].concat(t),n=a.solvePath(this.get(),r,this.tree);if(!n)throw Error("baobab.Cursor.update: could not solve dynamic path.");return this.tree.stack(a.pathObject(this.solvedPath.concat(n),e)),this},n.prototype.startRecording=function(t){if(t=t||5,1>t)throw Error("baobab.Cursor.startRecording: invalid maximum number of records.");return this.archive?this:(this._lazyBind(),this.archive=a.archive(t),this)},n.prototype.stopRecording=function(){return this.archive=null,this},n.prototype.undo=function(t){if(t=t||1,!this.isRecording())throw Error("baobab.Cursor.undo: cursor is not recording.");if(!h.PositiveInteger(t))throw Error("baobab.Cursor.undo: expecting a positive integer.");var e=this.archive.back(t);if(!e)throw Error("boabab.Cursor.undo: cannot find a relevant record ("+t+" back).");return this.undoing=!0,this.set(e)},n.prototype.isRecording=function(){return!!this.archive},n.prototype.hasHistory=function(){return!(!this.archive||!this.archive.get().length)},n.prototype.getHistory=function(){return this.archive?this.archive.get():[]},n.prototype.release=function(){this.tree.off("update",this.updateHandler),this.hash&&delete this.tree._cursors[this.hash],delete this.tree,delete this.path,delete this.solvedPath,delete this.archive,this.kill()},n.prototype.toJSON=function(){return this.get()},n.prototype.toString=function(){return this._identity},e.exports=n},{"../defaults.js":2,"./helpers.js":7,"./type.js":9,emmett:3}],6:[function(t,e,r){function n(t){return t}function o(t,e){function r(t){o[t]=l[t].bind(l)}var o=this,s=null,a=!1,h=e.get||n,u=e.cursors,c=Object.keys(u).map(function(t){return u[t]}),l=new i(t,c);["on","once","release"].forEach(r),this.get=function(){if(a)return s;var e={};for(var r in u)e[r]=t.get(u[r]);return s=h.call(null,e),a=!0,s},this.on("update",function(){a=!1})}{var i=t("./watcher.js");t("./helpers.js")}e.exports=o},{"./helpers.js":7,"./watcher.js":11}],7:[function(t,e,r){(function(r){function n(t){return Array.prototype.slice.call(t)}function o(t,e){return function(){t(),e.apply(null,arguments)}}function i(t,e,r){var o=n(arguments).slice(3);return e=+e,r=+r,t.slice(0,e).concat(t.slice(e+r).concat(o))}function s(t,e){var r,n={};for(r in t)n[r]=t[r];for(r in e)n[r]=e[r];return n}function a(t){var e=t.source,r="";return t.global&&(r+="g"),t.multiline&&(r+="m"),t.ignoreCase&&(r+="i"),t.sticky&&(r+="y"),t.unicode&&(r+="u"),new RegExp(e,r)}function h(t,e){if(!e||"object"!=typeof e||e instanceof Error||"ArrayBuffer"in r&&e instanceof ArrayBuffer)return e;if(_.Array(e)){if(t){var n,o,i=[];for(n=0,o=e.length;o>n;n++)i.push(P(e[n]));return i}return e.slice(0)}if(_.Date(e))return new Date(e.getTime());if(e instanceof RegExp)return a(e);if(_.Object(e)){var s,h={};e.constructor&&e.constructor!==Object&&(h=Object.create(e.constructor.prototype));for(s in e)e.hasOwnProperty(s)&&(h[s]=t?P(e[s]):e[s]);return h}return e}function u(t,e){return function(r){return e(t(r))}}function c(t,e){var r,n;for(r=0,n=t.length;n>r;r++)if(e(t[r]))return t[r]}function l(t,e){var r,n;for(r=0,n=t.length;n>r;r++)if(e(t[r]))return r;return-1}function f(t,e){var r,n=!0;if(!t)return!1;for(r in e)if(_.Object(e[r]))n=n&&f(t[r],e[r]);else if(_.Array(e[r]))n=n&&!!~e[r].indexOf(t[r]);else if(t[r]!==e[r])return!1;return n}function d(t,e){return c(t,function(t){return f(t,e)})}function y(t,e){return l(t,function(t){return f(t,e)})}function v(t,e,r){e=e||[];var n,o,i,s=t;for(o=0,i=e.length;i>o;o++){if(!s)return;if("function"==typeof e[o]){if(!_.Array(s))return;s=c(s,e[o])}else if("object"==typeof e[o])if(r&&"$cursor"in e[o]){if(!_.Path(e[o].$cursor))throw Error("baobab.getIn: $cursor path must be an array.");n=r.get(e[o].$cursor),s=s[n]}else{if(!_.Array(s))return;s=d(s,e[o])}else s=s[e[o]]}return s}function g(t,e,r){var n,o,i,s=[],a=t;for(o=0,i=e.length;i>o;o++){if(!a)return null;if("function"==typeof e[o]){if(!_.Array(a))return;n=l(a,e[o]),s.push(n),a=a[n]}else if("object"==typeof e[o])if(r&&"$cursor"in e[o]){if(!_.Path(e[o].$cursor))throw Error("baobab.getIn: $cursor path must be an array.");p=r.get(e[o].$cursor),s.push(p),a=a[p]}else{if(!_.Array(a))return;n=y(a,e[o]),s.push(n),a=a[n]}else s.push(e[o]),a=a[e[o]]||{}}return s}function b(t,e){var r,n,o,i,s,a,h,u,c;for(r=0,i=e.length;i>r;r++)for(h=e[r],n=0,s=t.length;s>n;n++)for(u=t[n],o=0,a=u.length;a>o&&(c=u[o],c==h[o]);o++)if(o+1===a||o+1===h.length)return!0;return!1}function m(t,e){var r,n=t.length,o={},i=o;for(n||(o=e),r=0;n>r;r++)i[t[r]]=r+1===n?e:{},i=i[t[r]];return o}function j(t,e){t.super_=e;var r=function(){};r.prototype=e.prototype,t.prototype=new r,t.prototype.constructor=t}function w(t){var e=[];return{add:function(r){e.unshift(r),e.length>t&&(e.length=t)},back:function(t){var r=e[t-1];return r&&(e=e.slice(t)),r},get:function(){return e}}}var _=t("./type.js"),$=h.bind(null,!1),P=h.bind(null,!0);e.exports={archive:w,arrayOf:n,before:o,deepClone:P,shallowClone:$,shallowMerge:s,compose:u,getIn:v,inherits:j,pathObject:m,solvePath:g,solveUpdate:b,splice:i}}).call(this,"undefined"!=typeof global?global:"undefined"!=typeof self?self:"undefined"!=typeof window?window:{})},{"./type.js":9}],8:[function(t,e,r){function n(t,e,r){a.forEach(function(e){r!==e&&delete t[e]}),t[r]=e[r]}function o(t,e){var r,h=i.shallowClone(e||{});a.forEach(function(e){t[e]&&n(h,t,e)}),t.$chain&&(a.slice(0,-1).forEach(function(t){delete h[t]}),h.$apply=h.$apply?i.compose(h.$apply,t.$chain):t.$chain),(t.$splice||h.$splice)&&(h.$splice=[].concat(h.$splice||[]).concat(t.$splice||[])),(t.$push||h.$push)&&(h.$push=[].concat(h.$push||[]).concat(t.$push||[])),(t.$unshift||h.$unshift)&&(h.$unshift=[].concat(t.$unshift||[]).concat(h.$unshift||[]));for(r in t)s.Object(t[r])?h[r]=o(t[r],h[r]):"$"!==r[0]&&(h[r]=t[r]);return h}var i=t("./helpers.js"),s=t("./type.js"),a=["$unset","$set","$merge","$apply"];e.exports=o},{"./helpers.js":7,"./type.js":9}],9:[function(t,e,r){function n(t,e){return e.some(function(e){return o[e](t)})}var o={};o.Array=function(t){return Array.isArray(t)},o.Object=function(t){return t&&"object"==typeof t&&!Array.isArray(t)&&!(t instanceof Function)},o.String=function(t){return"string"==typeof t},o.Number=function(t){return"number"==typeof t},o.PositiveInteger=function(t){return"number"==typeof t&&t>0&&t%1===0},o.Function=function(t){return"function"==typeof t},o.Primitive=function(t){return"string"==typeof t||"number"==typeof t||"boolean"==typeof t},o.Date=function(t){return t instanceof Date},o.NonScalar=function(t){return o.Object(t)||o.Array(t)},o.Path=function(t){var e=["String","Number","Function","Object"];return o.Array(t)?t.every(function(t){return n(t,e)}):n(t,e)},o.MixinCursor=function(t){return n(t,["String","Number","Array","Function","Cursor"])},o.MixinCursors=function(t){return n(t,["Object","Array","Function"])},o.ComplexPath=function(t){return t.some(function(t){return n(t,["Object","Function"])})},e.exports=o},{}],10:[function(t,e,r){function n(t,e){var r=new Error("baobab.update: "+e+" at path /"+t.slice(1).join("/"));return r.path=t,r}var o=t("./helpers.js"),i=t("./type.js");e.exports=function(t,e,r){if(r=r||{},!i.Object(t)&&!i.Array(t))throw Error("baobab.update: invalid target.");var s={};t={root:o.shallowClone(t)};var a=function(t,e,r,h){r=r||["root"];var u,c,l,f=r.join("|λ|"),p=r[r.length-1],d=Object.keys(e).some(function(t){return!!~["$set","$push","$unshift","$splice","$unset","$merge","$apply"].indexOf(t)});if(d){s[f]=!0;for(c in e){if("$unset"===c){var y=r[r.length-2];if(!i.Object(h[y]))throw n(r.slice(0,-1),"using command $unset on a non-object");h[y]=o.shallowClone(t),delete h[y][p];break}if("$set"===c){l=e.$set,t[p]=l;break}if("$apply"===c){if(u=e.$apply,"function"!=typeof u)throw n(r,"using command $apply with a non function");t[p]=u.call(null,t[p]);break}if("$merge"===c){if(l=e.$merge,!i.Object(t[p])||!i.Object(l))throw n(r,"using command $merge with a non object");t[p]=o.shallowMerge(t[p],l);break}if("$splice"===c){if(l=e.$splice,!i.Array(t[p]))throw n(r,"using command $push to a non array");l.forEach(function(e){t[p]=o.splice.apply(null,[t[p]].concat(e))})}if("$push"===c){if(l=e.$push,!i.Array(t[p]))throw n(r,"using command $push to a non array");t[p]=t[p].concat(l)}if("$unshift"===c){if(l=e.$unshift,!i.Array(t[p]))throw n(r,"using command $unshift to a non array");t[p]=[].concat(l).concat(t[p])}}}else for(c in e)t[p][c]="undefined"==typeof t[p][c]?{}:o.shallowClone(t[p][c]),a(t[p],e[c],r.concat(c),t)};return a(t,e),{data:t.root,log:Object.keys(s).map(function(t){return t.split("|λ|").slice(1)})}}},{"./helpers.js":7,"./type.js":9}],11:[function(t,e,r){function n(t,e){function r(){h&&(a=e.map(function(t){return i.solvePath(n.tree.data,t,n.tree)}))}var n=this;o.call(this),this.tree=t;var a=e,h=e.some(s.ComplexPath);this.updateHandler=function(t){var e=i.solveUpdate(t.data.log,a);e&&n.emit("update")},r(),this.tree.on("update",this.updateHandler)}var o=t("emmett"),i=t("./helpers.js"),s=t("./type.js");i.inherits(n,o),n.prototype.release=function(){this.tree.off("update",this.updateHandler),this.tree=null,this.kill()},e.exports=n},{"./helpers.js":7,"./type.js":9,emmett:3}]},{},[1])(1)}); \ No newline at end of file diff --git a/src/cursor.js b/src/cursor.js index ceda3b2..cd74ac0 100644 --- a/src/cursor.js +++ b/src/cursor.js @@ -229,19 +229,16 @@ function pathPolymorphism(method, allowedType, key, val) { key = key || []; + // Checking value validity + if (allowedType && !allowedType(val)) + throw Error('baobab.Cursor.' + method + ': incorrect value.'); + var path = [].concat(key), solvedPath = helpers.solvePath(this.get(), path, this.tree); if (!solvedPath) throw Error('baobab.Cursor.' + method + ': could not solve dynamic path.'); - if (allowedType) { - var data = this.get(solvedPath); - - if (!type[allowedType](data)) - throw Error('baobab.Cursor.' + method + ': invalid target.'); - } - var leaf = {}; leaf['$' + method] = val; @@ -261,17 +258,9 @@ function makeUpdateMethod(command, type) { makeUpdateMethod('set'); makeUpdateMethod('apply'); makeUpdateMethod('chain'); -makeUpdateMethod('push', 'Array'); -makeUpdateMethod('unshift', 'Array'); - -Cursor.prototype.merge = function(o) { - if (!type.Object(o)) - throw Error('baobab.Cursor.merge: trying to merge a non-object.'); - - var spec = pathPolymorphism.bind(this, 'merge', 'Object').apply(this, arguments); - - return this.update(spec); -}; +makeUpdateMethod('push'); +makeUpdateMethod('unshift'); +makeUpdateMethod('merge', type.Object); Cursor.prototype.unset = function(key) { if (key === undefined && this.isRoot()) diff --git a/test/suites/cursor.js b/test/suites/cursor.js index 1f8b71a..4ae3896 100644 --- a/test/suites/cursor.js +++ b/test/suites/cursor.js @@ -187,24 +187,6 @@ describe('Cursor API', function() { }, /solve/); }); - it('should throw an error when trying to push to a non-array.', function() { - var baobab = new Baobab(state), - oneCursor = baobab.select('one'); - - assert.throws(function() { - oneCursor.push('test'); - }, /target/); - }); - - it('should throw an error when trying to unshift to a non-array.', function() { - var baobab = new Baobab(state), - oneCursor = baobab.select('one'); - - assert.throws(function() { - oneCursor.unshift('test'); - }, /target/); - }); - it('should be possible to chain mutations.', function(done) { var baobab = new Baobab({number: 1}), inc = function(i) { return i + 1; }; @@ -231,10 +213,6 @@ describe('Cursor API', function() { it('should be possible to shallow merge two objects.', function(done) { var baobab = new Baobab({o: {hello: 'world'}, string: 'test'}); - assert.throws(function() { - baobab.select('test').merge({hello: 'moto'}); - }, /merge/); - var cursor = baobab.select('o'); cursor.merge({hello: 'jarl'}); @@ -269,6 +247,14 @@ describe('Cursor API', function() { // assert.deepEqual(cursor.get(), [1, 2, 3]); // cursor.splice() // }); + + it('should throw errors when updating with wrong values.', function() { + var cursor = (new Baobab()).root; + + assert.throws(function() { + cursor.merge('John'); + }, /value/); + }); }); }); From dbda64015364a8accbe6fc0930144b8393c7aa62 Mon Sep 17 00:00:00 2001 From: Yomguithereal Date: Thu, 16 Apr 2015 15:26:53 +0200 Subject: [PATCH 60/73] Related to #129 - cursor.splice --- build/baobab.min.js | 2 +- src/cursor.js | 14 ++++++++++++-- src/type.js | 5 +++++ test/suites/cursor.js | 32 ++++++++++++++++++++++++++------ 4 files changed, 44 insertions(+), 9 deletions(-) diff --git a/build/baobab.min.js b/build/baobab.min.js index 1f86654..af6d6b4 100644 --- a/build/baobab.min.js +++ b/build/baobab.min.js @@ -1,2 +1,2 @@ /* baobab.js - Version: 1.0.0-rc1 - Author: Yomguithereal (Guillaume Plique) */ -!function(t){if("object"==typeof exports&&"undefined"!=typeof module)module.exports=t();else if("function"==typeof define&&define.amd)define([],t);else{var e;e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:this,e.Baobab=t()}}(function(){var t;return function e(t,r,n){function o(s,a){if(!r[s]){if(!t[s]){var h="function"==typeof require&&require;if(!a&&h)return h(s,!0);if(i)return i(s,!0);var u=new Error("Cannot find module '"+s+"'");throw u.code="MODULE_NOT_FOUND",u}var c=r[s]={exports:{}};t[s][0].call(c.exports,function(e){var r=t[s][1][e];return o(r?r:e)},c,c.exports,e,t,r,n)}return r[s].exports}for(var i="function"==typeof require&&require,s=0;sn;n++)t[n].fn!==e&&o.push(t[n]);return o}var s={once:"boolean",scope:"object"},a=0,h=function(){this._enabled=!0,this.unbindAll()};h.prototype.unbindAll=function(){return this._handlers={},this._handlersAll=[],this._handlersComplex=[],this},h.prototype.on=function(t,e,r){var n,i,h,u,c,l,f;if(o(t)){for(u in t)this.on(u,t[u],e);return this}for("function"==typeof t&&(r=e,e=t,t=null),c=[].concat(t),n=0,i=c.length;i>n;n++){if(u=c[n],f={order:a++,fn:e},"string"==typeof u)this._handlers[u]||(this._handlers[u]=[]),l=this._handlers[u];else if(u instanceof RegExp)l=this._handlersComplex,f.pattern=u;else{if(null!==u)throw Error("Emitter.on: invalid event.");l=this._handlersAll}for(h in r||{})s[h]&&(f[h]=r[h]);f.once&&(f.parent=l),l.push(f)}return this},h.prototype.once=function(){var t=Array.prototype.slice.call(arguments),r=t.length-1;return o(t[r])&&t.length>1?t[r]=e(t[r],{once:!0}):t.push({once:!0}),this.on.apply(this,t)},h.prototype.off=function(t,e){var r,n,s,a;if(1===arguments.length&&"function"==typeof t){e=arguments[0];for(s in this._handlers)this._handlers[s]=i(this._handlers[s],e),0===this._handlers[s].length&&delete this._handlers[s];this._handlersAll=i(this._handlersAll,e),this._handlersComplex=i(this._handlersComplex,e)}else if(1===arguments.length&&"string"==typeof t)delete this._handlers[t];else if(2===arguments.length){var h=[].concat(t);for(r=0,n=h.length;n>r;r++)a=h[r],this._handlers[a]=i(this._handlers[a],e),0===(this._handlers[a]||[]).length&&delete this._handlers[a]}else if(o(t))for(s in t)this.off(s,t[s]);return this},h.prototype.listeners=function(t){var e,r,n,o=this._handlersAll||[],i=!1;if(!t)throw Error("Emitter.listeners: no event provided.");for(o=o.concat(this._handlers[t]||[]),r=0,n=this._handlersComplex.length;n>r;r++)e=this._handlersComplex[r],~t.search(e.pattern)&&(i=!0,o.push(e));return this._handlersAll.length||i?o.sort(function(t,e){return t.order-e.order}):o.slice(0)},h.prototype.emit=function(t,e){if(!this._enabled)return this;if(o(t)){for(var r in t)this.emit(r,t[r]);return this}var n,i,s,a,h,u,c,l=[].concat(t),f=[];for(a=0,u=l.length;u>a;a++){for(i=this.listeners(l[a]),h=0,c=i.length;c>h;h++)s=i[h],n={type:l[a],target:this},arguments.length>1&&(n.data=e),s.fn.call("scope"in s?s.scope:this,n),s.once&&f.push(s);for(h=f.length-1;h>=0;h--)f[h].parent.splice(f[h].parent.indexOf(f[h]),1)}return this},h.prototype.kill=function(){this.unbindAll(),this._handlers=null,this._handlersAll=null,this._handlersComplex=null,this._enabled=!1},h.prototype.disable=function(){return this._enabled=!1,this},h.prototype.enable=function(){return this._enabled=!0,this},h.version="3.0.0","undefined"!=typeof n?("undefined"!=typeof r&&r.exports&&(n=r.exports=h),n.Emitter=h):"function"==typeof t&&t.amd?t("emmett",[],function(){return h}):this.Emitter=h}).call(this)},{}],4:[function(t,e,r){function n(t){return t+"$"+(new Date).getTime()+(""+Math.random()).replace("0.","")}function o(t,e){function r(t){this[t]=function(){var e=this.root[t].apply(this.root,arguments);return e instanceof i?this:e}}if(arguments.length<1&&(t={}),!(this instanceof o))return new o(t,e);if(!p.Object(t)&&!p.Array(t))throw Error("Baobab: invalid data.");if(s.call(this),this.options=u.shallowMerge(f,e),this._transaction={},this._future=void 0,this._cursors={},this._identity="[object Baobab]",this.data=u.deepClone(t),this.root=this.select([]),this.facets={},["get","set","unset","update"].forEach(r.bind(this)),!p.Object(this.options.facets))throw Error("Baobab: invalid facets.");for(var n in this.options.facets)this.addFacet(n,this.options.facets[n])}var i=t("./cursor.js"),s=t("emmett"),a=t("./watcher.js"),h=t("./facet.js"),u=t("./helpers.js"),c=t("./update.js"),l=t("./merge.js"),f=t("../defaults.js"),p=t("./type.js");u.inherits(o,s),o.prototype.addFacet=function(t,e){return this.facets[t]=this.createFacet(e),this},o.prototype.createFacet=function(t){return new h(this,t)},o.prototype.select=function(t){if(!t)throw Error("Baobab.select: invalid path.");if(arguments.length>1&&(t=u.arrayOf(arguments)),!p.Path(t))throw Error("Baobab.select: invalid path.");t=[].concat(t);var e,r=p.ComplexPath(t);r&&(e=u.solvePath(this.data,t,this));var o=t.map(function(t){return p.Function(t)?n("fn"):p.Object(t)?n("ob"):t}).join("|λ|");if(this._cursors[o])return this._cursors[o];var s=new i(this,t,e,o);return this._cursors[o]=s,s},o.prototype.stack=function(t){var e=this;if(!p.Object(t))throw Error("Baobab.update: wrong specification.");return this._transaction=l(t,this._transaction),this.options.autoCommit?this.options.asynchronous?(this._future||(this._future=setTimeout(e.commit.bind(e,null),0)),this):this.commit():this},o.prototype.commit=function(){var t=c(this.data,this._transaction,this.options),e=this.data;this._transaction={},this._future&&(this._future=clearTimeout(this._future));var r=this.options.validate,n=this.options.validationBehaviour;if("function"==typeof r){var o=r.call(this,e,t.data,t.log);if(o instanceof Error&&(this.emit("invalid",{error:o}),"rollback"===n))return this}return this.data=t.data,this.emit("update",{log:t.log,previousState:e}),this},o.prototype.watch=function(t){if(!p.Array(t)||t.some(function(t){return!p.Path(t)}))throw Error("Baobab.watch: invalid paths.");return new a(this,[].concat(t))},o.prototype.release=function(){var t;delete this.data,delete this._transaction;for(t in this._cursors)this._cursors[t].release();delete this._cursors;for(t in this.facets)this.facets[t].release();delete this.facets,this.kill()},o.prototype.toJSON=function(){return this.get()},o.prototype.toString=function(){return this._identity},e.exports=o},{"../defaults.js":2,"./cursor.js":5,"./facet.js":6,"./helpers.js":7,"./merge.js":8,"./type.js":9,"./update.js":10,"./watcher.js":11,emmett:3}],5:[function(t,e,r){function n(t,e,r,n){function o(t){if(i.isRecording()&&!i.undoing){var e=a.getIn(t,i.solvedPath,i.tree),r=a.deepClone(e);i.archive.add(r)}return i.undoing=!1,i.emit("update")}var i=this;s.call(this),e=e||[],this.tree=t,this.path=e,this.hash=n,this.archive=null,this.undoing=!1,this._identity="[object Cursor]",this.complexPath=!!r,this.solvedPath=this.complexPath?r:this.path,this.relevant=void 0!==this.get(),this.updateHandler=function(t){var e=t.data.log,r=t.data.previousState,n=!1;if(i.complexPath&&(i.solvedPath=a.solvePath(i.tree.data,i.path,i.tree)),!i.path.length)return o(r);i.solvedPath&&(n=a.solveUpdate(e,[i.solvedPath]));var s=void 0!==i.get();i.relevant?s&&n?o(r):s||(i.emit("irrelevant"),i.relevant=!1):s&&n&&(i.emit("relevant"),o(r),i.relevant=!0)};var h=!1;this._lazyBind=function(){h||(h=!0,i.tree.on("update",i.updateHandler))},this.on=a.before(this._lazyBind,this.on.bind(this)),this.once=a.before(this._lazyBind,this.once.bind(this)),this.complexPath&&this._lazyBind()}function o(t,e,r,n){if(arguments.length>5)throw Error("baobab.Cursor."+t+": too many arguments.");if(arguments.length<4&&(n=r,r=[]),r=r||[],e&&!e(n))throw Error("baobab.Cursor."+t+": incorrect value.");var o=[].concat(r),i=a.solvePath(this.get(),o,this.tree);if(!i)throw Error("baobab.Cursor."+t+": could not solve dynamic path.");var s={};s["$"+t]=n;var h=a.pathObject(i,s);return h}function i(t,e){n.prototype[t]=function(){var r=o.bind(this,t,e).apply(this,arguments);return this.update(r)}}var s=t("emmett"),a=t("./helpers.js"),h=(t("../defaults.js"),t("./type.js"));a.inherits(n,s),n.prototype.isRoot=function(){return!this.path.length},n.prototype.isLeaf=function(){return h.Primitive(this.get())},n.prototype.isBranch=function(){return!this.isLeaf()&&!this.isRoot()},n.prototype.root=function(){return this.tree.root()},n.prototype.select=function(t){if(arguments.length>1&&(t=a.arrayOf(arguments)),!h.Path(t))throw Error("baobab.Cursor.select: invalid path.");return this.tree.select(this.path.concat(t))},n.prototype.up=function(){return this.solvedPath&&this.solvedPath.length?this.tree.select(this.path.slice(0,-1)):null},n.prototype.left=function(){var t=+this.solvedPath[this.solvedPath.length-1];if(isNaN(t))throw Error("baobab.Cursor.left: cannot go left on a non-list type.");return t?this.tree.select(this.solvedPath.slice(0,-1).concat(t-1)):null},n.prototype.leftmost=function(){var t=+this.solvedPath[this.solvedPath.length-1];if(isNaN(t))throw Error("baobab.Cursor.leftmost: cannot go left on a non-list type.");return this.tree.select(this.solvedPath.slice(0,-1).concat(0))},n.prototype.right=function(){var t=+this.solvedPath[this.solvedPath.length-1];if(isNaN(t))throw Error("baobab.Cursor.right: cannot go right on a non-list type.");return t+1===this.up().get().length?null:this.tree.select(this.solvedPath.slice(0,-1).concat(t+1))},n.prototype.rightmost=function(){var t=+this.solvedPath[this.solvedPath.length-1];if(isNaN(t))throw Error("baobab.Cursor.right: cannot go right on a non-list type.");var e=this.up().get();return this.tree.select(this.solvedPath.slice(0,-1).concat(e.length-1))},n.prototype.down=function(){+this.solvedPath[this.solvedPath.length-1];return this.get()instanceof Array?this.tree.select(this.solvedPath.concat(0)):null},n.prototype.get=function(t){arguments.length>1&&(t=a.arrayOf(arguments));var e=this.solvedPath.concat([].concat(t||0===t?t:[]));return a.getIn(this.tree.data,e,this.tree)},i("set"),i("apply"),i("chain"),i("push"),i("unshift"),i("merge",h.Object),n.prototype.unset=function(t){if(void 0===t&&this.isRoot())throw Error("baobab.Cursor.unset: cannot remove root node.");var e=o.bind(this,"unset",null).apply(this,[t,!0]);return this.update(e)},n.prototype.update=function(t,e){if(arguments.length<2)return this.tree.stack(a.pathObject(this.solvedPath,t)),this;var r=[].concat(t),n=a.solvePath(this.get(),r,this.tree);if(!n)throw Error("baobab.Cursor.update: could not solve dynamic path.");return this.tree.stack(a.pathObject(this.solvedPath.concat(n),e)),this},n.prototype.startRecording=function(t){if(t=t||5,1>t)throw Error("baobab.Cursor.startRecording: invalid maximum number of records.");return this.archive?this:(this._lazyBind(),this.archive=a.archive(t),this)},n.prototype.stopRecording=function(){return this.archive=null,this},n.prototype.undo=function(t){if(t=t||1,!this.isRecording())throw Error("baobab.Cursor.undo: cursor is not recording.");if(!h.PositiveInteger(t))throw Error("baobab.Cursor.undo: expecting a positive integer.");var e=this.archive.back(t);if(!e)throw Error("boabab.Cursor.undo: cannot find a relevant record ("+t+" back).");return this.undoing=!0,this.set(e)},n.prototype.isRecording=function(){return!!this.archive},n.prototype.hasHistory=function(){return!(!this.archive||!this.archive.get().length)},n.prototype.getHistory=function(){return this.archive?this.archive.get():[]},n.prototype.release=function(){this.tree.off("update",this.updateHandler),this.hash&&delete this.tree._cursors[this.hash],delete this.tree,delete this.path,delete this.solvedPath,delete this.archive,this.kill()},n.prototype.toJSON=function(){return this.get()},n.prototype.toString=function(){return this._identity},e.exports=n},{"../defaults.js":2,"./helpers.js":7,"./type.js":9,emmett:3}],6:[function(t,e,r){function n(t){return t}function o(t,e){function r(t){o[t]=l[t].bind(l)}var o=this,s=null,a=!1,h=e.get||n,u=e.cursors,c=Object.keys(u).map(function(t){return u[t]}),l=new i(t,c);["on","once","release"].forEach(r),this.get=function(){if(a)return s;var e={};for(var r in u)e[r]=t.get(u[r]);return s=h.call(null,e),a=!0,s},this.on("update",function(){a=!1})}{var i=t("./watcher.js");t("./helpers.js")}e.exports=o},{"./helpers.js":7,"./watcher.js":11}],7:[function(t,e,r){(function(r){function n(t){return Array.prototype.slice.call(t)}function o(t,e){return function(){t(),e.apply(null,arguments)}}function i(t,e,r){var o=n(arguments).slice(3);return e=+e,r=+r,t.slice(0,e).concat(t.slice(e+r).concat(o))}function s(t,e){var r,n={};for(r in t)n[r]=t[r];for(r in e)n[r]=e[r];return n}function a(t){var e=t.source,r="";return t.global&&(r+="g"),t.multiline&&(r+="m"),t.ignoreCase&&(r+="i"),t.sticky&&(r+="y"),t.unicode&&(r+="u"),new RegExp(e,r)}function h(t,e){if(!e||"object"!=typeof e||e instanceof Error||"ArrayBuffer"in r&&e instanceof ArrayBuffer)return e;if(_.Array(e)){if(t){var n,o,i=[];for(n=0,o=e.length;o>n;n++)i.push(P(e[n]));return i}return e.slice(0)}if(_.Date(e))return new Date(e.getTime());if(e instanceof RegExp)return a(e);if(_.Object(e)){var s,h={};e.constructor&&e.constructor!==Object&&(h=Object.create(e.constructor.prototype));for(s in e)e.hasOwnProperty(s)&&(h[s]=t?P(e[s]):e[s]);return h}return e}function u(t,e){return function(r){return e(t(r))}}function c(t,e){var r,n;for(r=0,n=t.length;n>r;r++)if(e(t[r]))return t[r]}function l(t,e){var r,n;for(r=0,n=t.length;n>r;r++)if(e(t[r]))return r;return-1}function f(t,e){var r,n=!0;if(!t)return!1;for(r in e)if(_.Object(e[r]))n=n&&f(t[r],e[r]);else if(_.Array(e[r]))n=n&&!!~e[r].indexOf(t[r]);else if(t[r]!==e[r])return!1;return n}function d(t,e){return c(t,function(t){return f(t,e)})}function y(t,e){return l(t,function(t){return f(t,e)})}function v(t,e,r){e=e||[];var n,o,i,s=t;for(o=0,i=e.length;i>o;o++){if(!s)return;if("function"==typeof e[o]){if(!_.Array(s))return;s=c(s,e[o])}else if("object"==typeof e[o])if(r&&"$cursor"in e[o]){if(!_.Path(e[o].$cursor))throw Error("baobab.getIn: $cursor path must be an array.");n=r.get(e[o].$cursor),s=s[n]}else{if(!_.Array(s))return;s=d(s,e[o])}else s=s[e[o]]}return s}function g(t,e,r){var n,o,i,s=[],a=t;for(o=0,i=e.length;i>o;o++){if(!a)return null;if("function"==typeof e[o]){if(!_.Array(a))return;n=l(a,e[o]),s.push(n),a=a[n]}else if("object"==typeof e[o])if(r&&"$cursor"in e[o]){if(!_.Path(e[o].$cursor))throw Error("baobab.getIn: $cursor path must be an array.");p=r.get(e[o].$cursor),s.push(p),a=a[p]}else{if(!_.Array(a))return;n=y(a,e[o]),s.push(n),a=a[n]}else s.push(e[o]),a=a[e[o]]||{}}return s}function b(t,e){var r,n,o,i,s,a,h,u,c;for(r=0,i=e.length;i>r;r++)for(h=e[r],n=0,s=t.length;s>n;n++)for(u=t[n],o=0,a=u.length;a>o&&(c=u[o],c==h[o]);o++)if(o+1===a||o+1===h.length)return!0;return!1}function m(t,e){var r,n=t.length,o={},i=o;for(n||(o=e),r=0;n>r;r++)i[t[r]]=r+1===n?e:{},i=i[t[r]];return o}function j(t,e){t.super_=e;var r=function(){};r.prototype=e.prototype,t.prototype=new r,t.prototype.constructor=t}function w(t){var e=[];return{add:function(r){e.unshift(r),e.length>t&&(e.length=t)},back:function(t){var r=e[t-1];return r&&(e=e.slice(t)),r},get:function(){return e}}}var _=t("./type.js"),$=h.bind(null,!1),P=h.bind(null,!0);e.exports={archive:w,arrayOf:n,before:o,deepClone:P,shallowClone:$,shallowMerge:s,compose:u,getIn:v,inherits:j,pathObject:m,solvePath:g,solveUpdate:b,splice:i}}).call(this,"undefined"!=typeof global?global:"undefined"!=typeof self?self:"undefined"!=typeof window?window:{})},{"./type.js":9}],8:[function(t,e,r){function n(t,e,r){a.forEach(function(e){r!==e&&delete t[e]}),t[r]=e[r]}function o(t,e){var r,h=i.shallowClone(e||{});a.forEach(function(e){t[e]&&n(h,t,e)}),t.$chain&&(a.slice(0,-1).forEach(function(t){delete h[t]}),h.$apply=h.$apply?i.compose(h.$apply,t.$chain):t.$chain),(t.$splice||h.$splice)&&(h.$splice=[].concat(h.$splice||[]).concat(t.$splice||[])),(t.$push||h.$push)&&(h.$push=[].concat(h.$push||[]).concat(t.$push||[])),(t.$unshift||h.$unshift)&&(h.$unshift=[].concat(t.$unshift||[]).concat(h.$unshift||[]));for(r in t)s.Object(t[r])?h[r]=o(t[r],h[r]):"$"!==r[0]&&(h[r]=t[r]);return h}var i=t("./helpers.js"),s=t("./type.js"),a=["$unset","$set","$merge","$apply"];e.exports=o},{"./helpers.js":7,"./type.js":9}],9:[function(t,e,r){function n(t,e){return e.some(function(e){return o[e](t)})}var o={};o.Array=function(t){return Array.isArray(t)},o.Object=function(t){return t&&"object"==typeof t&&!Array.isArray(t)&&!(t instanceof Function)},o.String=function(t){return"string"==typeof t},o.Number=function(t){return"number"==typeof t},o.PositiveInteger=function(t){return"number"==typeof t&&t>0&&t%1===0},o.Function=function(t){return"function"==typeof t},o.Primitive=function(t){return"string"==typeof t||"number"==typeof t||"boolean"==typeof t},o.Date=function(t){return t instanceof Date},o.NonScalar=function(t){return o.Object(t)||o.Array(t)},o.Path=function(t){var e=["String","Number","Function","Object"];return o.Array(t)?t.every(function(t){return n(t,e)}):n(t,e)},o.MixinCursor=function(t){return n(t,["String","Number","Array","Function","Cursor"])},o.MixinCursors=function(t){return n(t,["Object","Array","Function"])},o.ComplexPath=function(t){return t.some(function(t){return n(t,["Object","Function"])})},e.exports=o},{}],10:[function(t,e,r){function n(t,e){var r=new Error("baobab.update: "+e+" at path /"+t.slice(1).join("/"));return r.path=t,r}var o=t("./helpers.js"),i=t("./type.js");e.exports=function(t,e,r){if(r=r||{},!i.Object(t)&&!i.Array(t))throw Error("baobab.update: invalid target.");var s={};t={root:o.shallowClone(t)};var a=function(t,e,r,h){r=r||["root"];var u,c,l,f=r.join("|λ|"),p=r[r.length-1],d=Object.keys(e).some(function(t){return!!~["$set","$push","$unshift","$splice","$unset","$merge","$apply"].indexOf(t)});if(d){s[f]=!0;for(c in e){if("$unset"===c){var y=r[r.length-2];if(!i.Object(h[y]))throw n(r.slice(0,-1),"using command $unset on a non-object");h[y]=o.shallowClone(t),delete h[y][p];break}if("$set"===c){l=e.$set,t[p]=l;break}if("$apply"===c){if(u=e.$apply,"function"!=typeof u)throw n(r,"using command $apply with a non function");t[p]=u.call(null,t[p]);break}if("$merge"===c){if(l=e.$merge,!i.Object(t[p])||!i.Object(l))throw n(r,"using command $merge with a non object");t[p]=o.shallowMerge(t[p],l);break}if("$splice"===c){if(l=e.$splice,!i.Array(t[p]))throw n(r,"using command $push to a non array");l.forEach(function(e){t[p]=o.splice.apply(null,[t[p]].concat(e))})}if("$push"===c){if(l=e.$push,!i.Array(t[p]))throw n(r,"using command $push to a non array");t[p]=t[p].concat(l)}if("$unshift"===c){if(l=e.$unshift,!i.Array(t[p]))throw n(r,"using command $unshift to a non array");t[p]=[].concat(l).concat(t[p])}}}else for(c in e)t[p][c]="undefined"==typeof t[p][c]?{}:o.shallowClone(t[p][c]),a(t[p],e[c],r.concat(c),t)};return a(t,e),{data:t.root,log:Object.keys(s).map(function(t){return t.split("|λ|").slice(1)})}}},{"./helpers.js":7,"./type.js":9}],11:[function(t,e,r){function n(t,e){function r(){h&&(a=e.map(function(t){return i.solvePath(n.tree.data,t,n.tree)}))}var n=this;o.call(this),this.tree=t;var a=e,h=e.some(s.ComplexPath);this.updateHandler=function(t){var e=i.solveUpdate(t.data.log,a);e&&n.emit("update")},r(),this.tree.on("update",this.updateHandler)}var o=t("emmett"),i=t("./helpers.js"),s=t("./type.js");i.inherits(n,o),n.prototype.release=function(){this.tree.off("update",this.updateHandler),this.tree=null,this.kill()},e.exports=n},{"./helpers.js":7,"./type.js":9,emmett:3}]},{},[1])(1)}); \ No newline at end of file +!function(t){if("object"==typeof exports&&"undefined"!=typeof module)module.exports=t();else if("function"==typeof define&&define.amd)define([],t);else{var e;e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:this,e.Baobab=t()}}(function(){var t;return function e(t,r,n){function o(s,a){if(!r[s]){if(!t[s]){var h="function"==typeof require&&require;if(!a&&h)return h(s,!0);if(i)return i(s,!0);var u=new Error("Cannot find module '"+s+"'");throw u.code="MODULE_NOT_FOUND",u}var c=r[s]={exports:{}};t[s][0].call(c.exports,function(e){var r=t[s][1][e];return o(r?r:e)},c,c.exports,e,t,r,n)}return r[s].exports}for(var i="function"==typeof require&&require,s=0;sn;n++)t[n].fn!==e&&o.push(t[n]);return o}var s={once:"boolean",scope:"object"},a=0,h=function(){this._enabled=!0,this.unbindAll()};h.prototype.unbindAll=function(){return this._handlers={},this._handlersAll=[],this._handlersComplex=[],this},h.prototype.on=function(t,e,r){var n,i,h,u,c,l,f;if(o(t)){for(u in t)this.on(u,t[u],e);return this}for("function"==typeof t&&(r=e,e=t,t=null),c=[].concat(t),n=0,i=c.length;i>n;n++){if(u=c[n],f={order:a++,fn:e},"string"==typeof u)this._handlers[u]||(this._handlers[u]=[]),l=this._handlers[u];else if(u instanceof RegExp)l=this._handlersComplex,f.pattern=u;else{if(null!==u)throw Error("Emitter.on: invalid event.");l=this._handlersAll}for(h in r||{})s[h]&&(f[h]=r[h]);f.once&&(f.parent=l),l.push(f)}return this},h.prototype.once=function(){var t=Array.prototype.slice.call(arguments),r=t.length-1;return o(t[r])&&t.length>1?t[r]=e(t[r],{once:!0}):t.push({once:!0}),this.on.apply(this,t)},h.prototype.off=function(t,e){var r,n,s,a;if(1===arguments.length&&"function"==typeof t){e=arguments[0];for(s in this._handlers)this._handlers[s]=i(this._handlers[s],e),0===this._handlers[s].length&&delete this._handlers[s];this._handlersAll=i(this._handlersAll,e),this._handlersComplex=i(this._handlersComplex,e)}else if(1===arguments.length&&"string"==typeof t)delete this._handlers[t];else if(2===arguments.length){var h=[].concat(t);for(r=0,n=h.length;n>r;r++)a=h[r],this._handlers[a]=i(this._handlers[a],e),0===(this._handlers[a]||[]).length&&delete this._handlers[a]}else if(o(t))for(s in t)this.off(s,t[s]);return this},h.prototype.listeners=function(t){var e,r,n,o=this._handlersAll||[],i=!1;if(!t)throw Error("Emitter.listeners: no event provided.");for(o=o.concat(this._handlers[t]||[]),r=0,n=this._handlersComplex.length;n>r;r++)e=this._handlersComplex[r],~t.search(e.pattern)&&(i=!0,o.push(e));return this._handlersAll.length||i?o.sort(function(t,e){return t.order-e.order}):o.slice(0)},h.prototype.emit=function(t,e){if(!this._enabled)return this;if(o(t)){for(var r in t)this.emit(r,t[r]);return this}var n,i,s,a,h,u,c,l=[].concat(t),f=[];for(a=0,u=l.length;u>a;a++){for(i=this.listeners(l[a]),h=0,c=i.length;c>h;h++)s=i[h],n={type:l[a],target:this},arguments.length>1&&(n.data=e),s.fn.call("scope"in s?s.scope:this,n),s.once&&f.push(s);for(h=f.length-1;h>=0;h--)f[h].parent.splice(f[h].parent.indexOf(f[h]),1)}return this},h.prototype.kill=function(){this.unbindAll(),this._handlers=null,this._handlersAll=null,this._handlersComplex=null,this._enabled=!1},h.prototype.disable=function(){return this._enabled=!1,this},h.prototype.enable=function(){return this._enabled=!0,this},h.version="3.0.0","undefined"!=typeof n?("undefined"!=typeof r&&r.exports&&(n=r.exports=h),n.Emitter=h):"function"==typeof t&&t.amd?t("emmett",[],function(){return h}):this.Emitter=h}).call(this)},{}],4:[function(t,e,r){function n(t){return t+"$"+(new Date).getTime()+(""+Math.random()).replace("0.","")}function o(t,e){function r(t){this[t]=function(){var e=this.root[t].apply(this.root,arguments);return e instanceof i?this:e}}if(arguments.length<1&&(t={}),!(this instanceof o))return new o(t,e);if(!p.Object(t)&&!p.Array(t))throw Error("Baobab: invalid data.");if(s.call(this),this.options=u.shallowMerge(f,e),this._transaction={},this._future=void 0,this._cursors={},this._identity="[object Baobab]",this.data=u.deepClone(t),this.root=this.select([]),this.facets={},["get","set","unset","update"].forEach(r.bind(this)),!p.Object(this.options.facets))throw Error("Baobab: invalid facets.");for(var n in this.options.facets)this.addFacet(n,this.options.facets[n])}var i=t("./cursor.js"),s=t("emmett"),a=t("./watcher.js"),h=t("./facet.js"),u=t("./helpers.js"),c=t("./update.js"),l=t("./merge.js"),f=t("../defaults.js"),p=t("./type.js");u.inherits(o,s),o.prototype.addFacet=function(t,e){return this.facets[t]=this.createFacet(e),this},o.prototype.createFacet=function(t){return new h(this,t)},o.prototype.select=function(t){if(!t)throw Error("Baobab.select: invalid path.");if(arguments.length>1&&(t=u.arrayOf(arguments)),!p.Path(t))throw Error("Baobab.select: invalid path.");t=[].concat(t);var e,r=p.ComplexPath(t);r&&(e=u.solvePath(this.data,t,this));var o=t.map(function(t){return p.Function(t)?n("fn"):p.Object(t)?n("ob"):t}).join("|λ|");if(this._cursors[o])return this._cursors[o];var s=new i(this,t,e,o);return this._cursors[o]=s,s},o.prototype.stack=function(t){var e=this;if(!p.Object(t))throw Error("Baobab.update: wrong specification.");return this._transaction=l(t,this._transaction),this.options.autoCommit?this.options.asynchronous?(this._future||(this._future=setTimeout(e.commit.bind(e,null),0)),this):this.commit():this},o.prototype.commit=function(){var t=c(this.data,this._transaction,this.options),e=this.data;this._transaction={},this._future&&(this._future=clearTimeout(this._future));var r=this.options.validate,n=this.options.validationBehaviour;if("function"==typeof r){var o=r.call(this,e,t.data,t.log);if(o instanceof Error&&(this.emit("invalid",{error:o}),"rollback"===n))return this}return this.data=t.data,this.emit("update",{log:t.log,previousState:e}),this},o.prototype.watch=function(t){if(!p.Array(t)||t.some(function(t){return!p.Path(t)}))throw Error("Baobab.watch: invalid paths.");return new a(this,[].concat(t))},o.prototype.release=function(){var t;delete this.data,delete this._transaction;for(t in this._cursors)this._cursors[t].release();delete this._cursors;for(t in this.facets)this.facets[t].release();delete this.facets,this.kill()},o.prototype.toJSON=function(){return this.get()},o.prototype.toString=function(){return this._identity},e.exports=o},{"../defaults.js":2,"./cursor.js":5,"./facet.js":6,"./helpers.js":7,"./merge.js":8,"./type.js":9,"./update.js":10,"./watcher.js":11,emmett:3}],5:[function(t,e,r){function n(t,e,r,n){function o(t){if(i.isRecording()&&!i.undoing){var e=a.getIn(t,i.solvedPath,i.tree),r=a.deepClone(e);i.archive.add(r)}return i.undoing=!1,i.emit("update")}var i=this;s.call(this),e=e||[],this.tree=t,this.path=e,this.hash=n,this.archive=null,this.undoing=!1,this._identity="[object Cursor]",this.complexPath=!!r,this.solvedPath=this.complexPath?r:this.path,this.relevant=void 0!==this.get(),this.updateHandler=function(t){var e=t.data.log,r=t.data.previousState,n=!1;if(i.complexPath&&(i.solvedPath=a.solvePath(i.tree.data,i.path,i.tree)),!i.path.length)return o(r);i.solvedPath&&(n=a.solveUpdate(e,[i.solvedPath]));var s=void 0!==i.get();i.relevant?s&&n?o(r):s||(i.emit("irrelevant"),i.relevant=!1):s&&n&&(i.emit("relevant"),o(r),i.relevant=!0)};var h=!1;this._lazyBind=function(){h||(h=!0,i.tree.on("update",i.updateHandler))},this.on=a.before(this._lazyBind,this.on.bind(this)),this.once=a.before(this._lazyBind,this.once.bind(this)),this.complexPath&&this._lazyBind()}function o(t,e,r,n){if(arguments.length>5)throw Error("baobab.Cursor."+t+": too many arguments.");if(arguments.length<4&&(n=r,r=[]),r=r||[],"splice"===t&&!h.Splicer(n)){if(!h.Array(n))throw Error("baobab.Cursor.splice: incorrect value.");n=[n]}if(e&&!e(n))throw Error("baobab.Cursor."+t+": incorrect value.");var o=[].concat(r),i=a.solvePath(this.get(),o,this.tree);if(!i)throw Error("baobab.Cursor."+t+": could not solve dynamic path.");var s={};s["$"+t]=n;var u=a.pathObject(i,s);return u}function i(t,e){n.prototype[t]=function(){var r=o.bind(this,t,e).apply(this,arguments);return this.update(r)}}var s=t("emmett"),a=t("./helpers.js"),h=(t("../defaults.js"),t("./type.js"));a.inherits(n,s),n.prototype.isRoot=function(){return!this.path.length},n.prototype.isLeaf=function(){return h.Primitive(this.get())},n.prototype.isBranch=function(){return!this.isLeaf()&&!this.isRoot()},n.prototype.root=function(){return this.tree.root()},n.prototype.select=function(t){if(arguments.length>1&&(t=a.arrayOf(arguments)),!h.Path(t))throw Error("baobab.Cursor.select: invalid path.");return this.tree.select(this.path.concat(t))},n.prototype.up=function(){return this.solvedPath&&this.solvedPath.length?this.tree.select(this.path.slice(0,-1)):null},n.prototype.left=function(){var t=+this.solvedPath[this.solvedPath.length-1];if(isNaN(t))throw Error("baobab.Cursor.left: cannot go left on a non-list type.");return t?this.tree.select(this.solvedPath.slice(0,-1).concat(t-1)):null},n.prototype.leftmost=function(){var t=+this.solvedPath[this.solvedPath.length-1];if(isNaN(t))throw Error("baobab.Cursor.leftmost: cannot go left on a non-list type.");return this.tree.select(this.solvedPath.slice(0,-1).concat(0))},n.prototype.right=function(){var t=+this.solvedPath[this.solvedPath.length-1];if(isNaN(t))throw Error("baobab.Cursor.right: cannot go right on a non-list type.");return t+1===this.up().get().length?null:this.tree.select(this.solvedPath.slice(0,-1).concat(t+1))},n.prototype.rightmost=function(){var t=+this.solvedPath[this.solvedPath.length-1];if(isNaN(t))throw Error("baobab.Cursor.right: cannot go right on a non-list type.");var e=this.up().get();return this.tree.select(this.solvedPath.slice(0,-1).concat(e.length-1))},n.prototype.down=function(){+this.solvedPath[this.solvedPath.length-1];return this.get()instanceof Array?this.tree.select(this.solvedPath.concat(0)):null},n.prototype.get=function(t){arguments.length>1&&(t=a.arrayOf(arguments));var e=this.solvedPath.concat([].concat(t||0===t?t:[]));return a.getIn(this.tree.data,e,this.tree)},i("set"),i("apply",h.Function),i("chain",h.Function),i("push"),i("unshift"),i("merge",h.Object),i("splice"),n.prototype.unset=function(t){if(void 0===t&&this.isRoot())throw Error("baobab.Cursor.unset: cannot remove root node.");var e=o.bind(this,"unset",null).apply(this,[t,!0]);return this.update(e)},n.prototype.update=function(t,e){if(arguments.length<2)return this.tree.stack(a.pathObject(this.solvedPath,t)),this;var r=[].concat(t),n=a.solvePath(this.get(),r,this.tree);if(!n)throw Error("baobab.Cursor.update: could not solve dynamic path.");return this.tree.stack(a.pathObject(this.solvedPath.concat(n),e)),this},n.prototype.startRecording=function(t){if(t=t||5,1>t)throw Error("baobab.Cursor.startRecording: invalid maximum number of records.");return this.archive?this:(this._lazyBind(),this.archive=a.archive(t),this)},n.prototype.stopRecording=function(){return this.archive=null,this},n.prototype.undo=function(t){if(t=t||1,!this.isRecording())throw Error("baobab.Cursor.undo: cursor is not recording.");if(!h.PositiveInteger(t))throw Error("baobab.Cursor.undo: expecting a positive integer.");var e=this.archive.back(t);if(!e)throw Error("boabab.Cursor.undo: cannot find a relevant record ("+t+" back).");return this.undoing=!0,this.set(e)},n.prototype.isRecording=function(){return!!this.archive},n.prototype.hasHistory=function(){return!(!this.archive||!this.archive.get().length)},n.prototype.getHistory=function(){return this.archive?this.archive.get():[]},n.prototype.release=function(){this.tree.off("update",this.updateHandler),this.hash&&delete this.tree._cursors[this.hash],delete this.tree,delete this.path,delete this.solvedPath,delete this.archive,this.kill()},n.prototype.toJSON=function(){return this.get()},n.prototype.toString=function(){return this._identity},e.exports=n},{"../defaults.js":2,"./helpers.js":7,"./type.js":9,emmett:3}],6:[function(t,e,r){function n(t){return t}function o(t,e){function r(t){o[t]=l[t].bind(l)}var o=this,s=null,a=!1,h=e.get||n,u=e.cursors,c=Object.keys(u).map(function(t){return u[t]}),l=new i(t,c);["on","once","release"].forEach(r),this.get=function(){if(a)return s;var e={};for(var r in u)e[r]=t.get(u[r]);return s=h.call(null,e),a=!0,s},this.on("update",function(){a=!1})}{var i=t("./watcher.js");t("./helpers.js")}e.exports=o},{"./helpers.js":7,"./watcher.js":11}],7:[function(t,e,r){(function(r){function n(t){return Array.prototype.slice.call(t)}function o(t,e){return function(){t(),e.apply(null,arguments)}}function i(t,e,r){var o=n(arguments).slice(3);return e=+e,r=+r,t.slice(0,e).concat(t.slice(e+r).concat(o))}function s(t,e){var r,n={};for(r in t)n[r]=t[r];for(r in e)n[r]=e[r];return n}function a(t){var e=t.source,r="";return t.global&&(r+="g"),t.multiline&&(r+="m"),t.ignoreCase&&(r+="i"),t.sticky&&(r+="y"),t.unicode&&(r+="u"),new RegExp(e,r)}function h(t,e){if(!e||"object"!=typeof e||e instanceof Error||"ArrayBuffer"in r&&e instanceof ArrayBuffer)return e;if(_.Array(e)){if(t){var n,o,i=[];for(n=0,o=e.length;o>n;n++)i.push(P(e[n]));return i}return e.slice(0)}if(_.Date(e))return new Date(e.getTime());if(e instanceof RegExp)return a(e);if(_.Object(e)){var s,h={};e.constructor&&e.constructor!==Object&&(h=Object.create(e.constructor.prototype));for(s in e)e.hasOwnProperty(s)&&(h[s]=t?P(e[s]):e[s]);return h}return e}function u(t,e){return function(r){return e(t(r))}}function c(t,e){var r,n;for(r=0,n=t.length;n>r;r++)if(e(t[r]))return t[r]}function l(t,e){var r,n;for(r=0,n=t.length;n>r;r++)if(e(t[r]))return r;return-1}function f(t,e){var r,n=!0;if(!t)return!1;for(r in e)if(_.Object(e[r]))n=n&&f(t[r],e[r]);else if(_.Array(e[r]))n=n&&!!~e[r].indexOf(t[r]);else if(t[r]!==e[r])return!1;return n}function d(t,e){return c(t,function(t){return f(t,e)})}function y(t,e){return l(t,function(t){return f(t,e)})}function v(t,e,r){e=e||[];var n,o,i,s=t;for(o=0,i=e.length;i>o;o++){if(!s)return;if("function"==typeof e[o]){if(!_.Array(s))return;s=c(s,e[o])}else if("object"==typeof e[o])if(r&&"$cursor"in e[o]){if(!_.Path(e[o].$cursor))throw Error("baobab.getIn: $cursor path must be an array.");n=r.get(e[o].$cursor),s=s[n]}else{if(!_.Array(s))return;s=d(s,e[o])}else s=s[e[o]]}return s}function g(t,e,r){var n,o,i,s=[],a=t;for(o=0,i=e.length;i>o;o++){if(!a)return null;if("function"==typeof e[o]){if(!_.Array(a))return;n=l(a,e[o]),s.push(n),a=a[n]}else if("object"==typeof e[o])if(r&&"$cursor"in e[o]){if(!_.Path(e[o].$cursor))throw Error("baobab.getIn: $cursor path must be an array.");p=r.get(e[o].$cursor),s.push(p),a=a[p]}else{if(!_.Array(a))return;n=y(a,e[o]),s.push(n),a=a[n]}else s.push(e[o]),a=a[e[o]]||{}}return s}function b(t,e){var r,n,o,i,s,a,h,u,c;for(r=0,i=e.length;i>r;r++)for(h=e[r],n=0,s=t.length;s>n;n++)for(u=t[n],o=0,a=u.length;a>o&&(c=u[o],c==h[o]);o++)if(o+1===a||o+1===h.length)return!0;return!1}function m(t,e){var r,n=t.length,o={},i=o;for(n||(o=e),r=0;n>r;r++)i[t[r]]=r+1===n?e:{},i=i[t[r]];return o}function j(t,e){t.super_=e;var r=function(){};r.prototype=e.prototype,t.prototype=new r,t.prototype.constructor=t}function w(t){var e=[];return{add:function(r){e.unshift(r),e.length>t&&(e.length=t)},back:function(t){var r=e[t-1];return r&&(e=e.slice(t)),r},get:function(){return e}}}var _=t("./type.js"),$=h.bind(null,!1),P=h.bind(null,!0);e.exports={archive:w,arrayOf:n,before:o,deepClone:P,shallowClone:$,shallowMerge:s,compose:u,getIn:v,inherits:j,pathObject:m,solvePath:g,solveUpdate:b,splice:i}}).call(this,"undefined"!=typeof global?global:"undefined"!=typeof self?self:"undefined"!=typeof window?window:{})},{"./type.js":9}],8:[function(t,e,r){function n(t,e,r){a.forEach(function(e){r!==e&&delete t[e]}),t[r]=e[r]}function o(t,e){var r,h=i.shallowClone(e||{});a.forEach(function(e){t[e]&&n(h,t,e)}),t.$chain&&(a.slice(0,-1).forEach(function(t){delete h[t]}),h.$apply=h.$apply?i.compose(h.$apply,t.$chain):t.$chain),(t.$splice||h.$splice)&&(h.$splice=[].concat(h.$splice||[]).concat(t.$splice||[])),(t.$push||h.$push)&&(h.$push=[].concat(h.$push||[]).concat(t.$push||[])),(t.$unshift||h.$unshift)&&(h.$unshift=[].concat(t.$unshift||[]).concat(h.$unshift||[]));for(r in t)s.Object(t[r])?h[r]=o(t[r],h[r]):"$"!==r[0]&&(h[r]=t[r]);return h}var i=t("./helpers.js"),s=t("./type.js"),a=["$unset","$set","$merge","$apply"];e.exports=o},{"./helpers.js":7,"./type.js":9}],9:[function(t,e,r){function n(t,e){return e.some(function(e){return o[e](t)})}var o={};o.Array=function(t){return Array.isArray(t)},o.Object=function(t){return t&&"object"==typeof t&&!Array.isArray(t)&&!(t instanceof Function)},o.String=function(t){return"string"==typeof t},o.Number=function(t){return"number"==typeof t},o.PositiveInteger=function(t){return"number"==typeof t&&t>0&&t%1===0},o.Function=function(t){return"function"==typeof t},o.Primitive=function(t){return"string"==typeof t||"number"==typeof t||"boolean"==typeof t},o.Date=function(t){return t instanceof Date},o.NonScalar=function(t){return o.Object(t)||o.Array(t)},o.Splicer=function(t){return o.Array(t)&&t.every(o.Array)},o.Path=function(t){var e=["String","Number","Function","Object"];return o.Array(t)?t.every(function(t){return n(t,e)}):n(t,e)},o.MixinCursor=function(t){return n(t,["String","Number","Array","Function","Cursor"])},o.MixinCursors=function(t){return n(t,["Object","Array","Function"])},o.ComplexPath=function(t){return t.some(function(t){return n(t,["Object","Function"])})},e.exports=o},{}],10:[function(t,e,r){function n(t,e){var r=new Error("baobab.update: "+e+" at path /"+t.slice(1).join("/"));return r.path=t,r}var o=t("./helpers.js"),i=t("./type.js");e.exports=function(t,e,r){if(r=r||{},!i.Object(t)&&!i.Array(t))throw Error("baobab.update: invalid target.");var s={};t={root:o.shallowClone(t)};var a=function(t,e,r,h){r=r||["root"];var u,c,l,f=r.join("|λ|"),p=r[r.length-1],d=Object.keys(e).some(function(t){return!!~["$set","$push","$unshift","$splice","$unset","$merge","$apply"].indexOf(t)});if(d){s[f]=!0;for(c in e){if("$unset"===c){var y=r[r.length-2];if(!i.Object(h[y]))throw n(r.slice(0,-1),"using command $unset on a non-object");h[y]=o.shallowClone(t),delete h[y][p];break}if("$set"===c){l=e.$set,t[p]=l;break}if("$apply"===c){if(u=e.$apply,"function"!=typeof u)throw n(r,"using command $apply with a non function");t[p]=u.call(null,t[p]);break}if("$merge"===c){if(l=e.$merge,!i.Object(t[p])||!i.Object(l))throw n(r,"using command $merge with a non object");t[p]=o.shallowMerge(t[p],l);break}if("$splice"===c){if(l=e.$splice,!i.Array(t[p]))throw n(r,"using command $push to a non array");l.forEach(function(e){t[p]=o.splice.apply(null,[t[p]].concat(e))})}if("$push"===c){if(l=e.$push,!i.Array(t[p]))throw n(r,"using command $push to a non array");t[p]=t[p].concat(l)}if("$unshift"===c){if(l=e.$unshift,!i.Array(t[p]))throw n(r,"using command $unshift to a non array");t[p]=[].concat(l).concat(t[p])}}}else for(c in e)t[p][c]="undefined"==typeof t[p][c]?{}:o.shallowClone(t[p][c]),a(t[p],e[c],r.concat(c),t)};return a(t,e),{data:t.root,log:Object.keys(s).map(function(t){return t.split("|λ|").slice(1)})}}},{"./helpers.js":7,"./type.js":9}],11:[function(t,e,r){function n(t,e){function r(){h&&(a=e.map(function(t){return i.solvePath(n.tree.data,t,n.tree)}))}var n=this;o.call(this),this.tree=t;var a=e,h=e.some(s.ComplexPath);this.updateHandler=function(t){var e=i.solveUpdate(t.data.log,a);e&&n.emit("update")},r(),this.tree.on("update",this.updateHandler)}var o=t("emmett"),i=t("./helpers.js"),s=t("./type.js");i.inherits(n,o),n.prototype.release=function(){this.tree.off("update",this.updateHandler),this.tree=null,this.kill()},e.exports=n},{"./helpers.js":7,"./type.js":9,emmett:3}]},{},[1])(1)}); \ No newline at end of file diff --git a/src/cursor.js b/src/cursor.js index cd74ac0..6428da8 100644 --- a/src/cursor.js +++ b/src/cursor.js @@ -229,6 +229,15 @@ function pathPolymorphism(method, allowedType, key, val) { key = key || []; + // Splice exception + if (method === 'splice' && + !type.Splicer(val)) { + if (type.Array(val)) + val = [val]; + else + throw Error('baobab.Cursor.splice: incorrect value.'); + } + // Checking value validity if (allowedType && !allowedType(val)) throw Error('baobab.Cursor.' + method + ': incorrect value.'); @@ -256,11 +265,12 @@ function makeUpdateMethod(command, type) { } makeUpdateMethod('set'); -makeUpdateMethod('apply'); -makeUpdateMethod('chain'); +makeUpdateMethod('apply', type.Function); +makeUpdateMethod('chain', type.Function); makeUpdateMethod('push'); makeUpdateMethod('unshift'); makeUpdateMethod('merge', type.Object); +makeUpdateMethod('splice'); Cursor.prototype.unset = function(key) { if (key === undefined && this.isRoot()) diff --git a/src/type.js b/src/type.js index 6232c09..2c81b54 100644 --- a/src/type.js +++ b/src/type.js @@ -63,6 +63,11 @@ type.NonScalar = function(value) { return type.Object(value) || type.Array(value); }; +type.Splicer = function(value) { + return type.Array(value) && + value.every(type.Array); +}; + type.Path = function(value) { var allowed = ['String', 'Number', 'Function', 'Object']; diff --git a/test/suites/cursor.js b/test/suites/cursor.js index 4ae3896..4848346 100644 --- a/test/suites/cursor.js +++ b/test/suites/cursor.js @@ -240,13 +240,21 @@ describe('Cursor API', function() { assert.strictEqual(cursor.get(), undefined); }); - // it('should be possible to splice an array.', function() { - // var tree = new Baobab({list: [1, 2, 3]}), - // cursor = tree.select('list'); + it('should be possible to splice an array.', function() { + var tree1 = new Baobab({list: [1, 2, 3]}, {asynchronous: false}), + tree2 = new Baobab(tree1.get(), {asynchronous: false}), + cursor1 = tree1.select('list'), + cursor2 = tree2.select('list'); - // assert.deepEqual(cursor.get(), [1, 2, 3]); - // cursor.splice() - // }); + assert.deepEqual(cursor1.get(), [1, 2, 3]); + + cursor1.splice([[0, 1], [1, 1, 4]]); + cursor2.splice([0, 1]); + cursor2.splice([1, 1, 4]); + + assert.deepEqual(cursor1.get(), [2, 4]); + assert.deepEqual(cursor1.get(), cursor2.get()); + }); it('should throw errors when updating with wrong values.', function() { var cursor = (new Baobab()).root; @@ -254,6 +262,18 @@ describe('Cursor API', function() { assert.throws(function() { cursor.merge('John'); }, /value/); + + assert.throws(function() { + cursor.splice('John'); + }); + + assert.throws(function() { + cursor.apply('John'); + }); + + assert.throws(function() { + cursor.chain('John'); + }); }); }); }); From 31b49b969e68817143136378354180b549b2679f Mon Sep 17 00:00:00 2001 From: Yomguithereal Date: Thu, 16 Apr 2015 15:35:53 +0200 Subject: [PATCH 61/73] Related to #139 - introducing cursor.clearHistory --- build/baobab.min.js | 2 +- src/cursor.js | 17 ++++++++++------- test/suites/cursor.js | 7 ++++--- 3 files changed, 15 insertions(+), 11 deletions(-) diff --git a/build/baobab.min.js b/build/baobab.min.js index af6d6b4..d4c2d02 100644 --- a/build/baobab.min.js +++ b/build/baobab.min.js @@ -1,2 +1,2 @@ /* baobab.js - Version: 1.0.0-rc1 - Author: Yomguithereal (Guillaume Plique) */ -!function(t){if("object"==typeof exports&&"undefined"!=typeof module)module.exports=t();else if("function"==typeof define&&define.amd)define([],t);else{var e;e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:this,e.Baobab=t()}}(function(){var t;return function e(t,r,n){function o(s,a){if(!r[s]){if(!t[s]){var h="function"==typeof require&&require;if(!a&&h)return h(s,!0);if(i)return i(s,!0);var u=new Error("Cannot find module '"+s+"'");throw u.code="MODULE_NOT_FOUND",u}var c=r[s]={exports:{}};t[s][0].call(c.exports,function(e){var r=t[s][1][e];return o(r?r:e)},c,c.exports,e,t,r,n)}return r[s].exports}for(var i="function"==typeof require&&require,s=0;sn;n++)t[n].fn!==e&&o.push(t[n]);return o}var s={once:"boolean",scope:"object"},a=0,h=function(){this._enabled=!0,this.unbindAll()};h.prototype.unbindAll=function(){return this._handlers={},this._handlersAll=[],this._handlersComplex=[],this},h.prototype.on=function(t,e,r){var n,i,h,u,c,l,f;if(o(t)){for(u in t)this.on(u,t[u],e);return this}for("function"==typeof t&&(r=e,e=t,t=null),c=[].concat(t),n=0,i=c.length;i>n;n++){if(u=c[n],f={order:a++,fn:e},"string"==typeof u)this._handlers[u]||(this._handlers[u]=[]),l=this._handlers[u];else if(u instanceof RegExp)l=this._handlersComplex,f.pattern=u;else{if(null!==u)throw Error("Emitter.on: invalid event.");l=this._handlersAll}for(h in r||{})s[h]&&(f[h]=r[h]);f.once&&(f.parent=l),l.push(f)}return this},h.prototype.once=function(){var t=Array.prototype.slice.call(arguments),r=t.length-1;return o(t[r])&&t.length>1?t[r]=e(t[r],{once:!0}):t.push({once:!0}),this.on.apply(this,t)},h.prototype.off=function(t,e){var r,n,s,a;if(1===arguments.length&&"function"==typeof t){e=arguments[0];for(s in this._handlers)this._handlers[s]=i(this._handlers[s],e),0===this._handlers[s].length&&delete this._handlers[s];this._handlersAll=i(this._handlersAll,e),this._handlersComplex=i(this._handlersComplex,e)}else if(1===arguments.length&&"string"==typeof t)delete this._handlers[t];else if(2===arguments.length){var h=[].concat(t);for(r=0,n=h.length;n>r;r++)a=h[r],this._handlers[a]=i(this._handlers[a],e),0===(this._handlers[a]||[]).length&&delete this._handlers[a]}else if(o(t))for(s in t)this.off(s,t[s]);return this},h.prototype.listeners=function(t){var e,r,n,o=this._handlersAll||[],i=!1;if(!t)throw Error("Emitter.listeners: no event provided.");for(o=o.concat(this._handlers[t]||[]),r=0,n=this._handlersComplex.length;n>r;r++)e=this._handlersComplex[r],~t.search(e.pattern)&&(i=!0,o.push(e));return this._handlersAll.length||i?o.sort(function(t,e){return t.order-e.order}):o.slice(0)},h.prototype.emit=function(t,e){if(!this._enabled)return this;if(o(t)){for(var r in t)this.emit(r,t[r]);return this}var n,i,s,a,h,u,c,l=[].concat(t),f=[];for(a=0,u=l.length;u>a;a++){for(i=this.listeners(l[a]),h=0,c=i.length;c>h;h++)s=i[h],n={type:l[a],target:this},arguments.length>1&&(n.data=e),s.fn.call("scope"in s?s.scope:this,n),s.once&&f.push(s);for(h=f.length-1;h>=0;h--)f[h].parent.splice(f[h].parent.indexOf(f[h]),1)}return this},h.prototype.kill=function(){this.unbindAll(),this._handlers=null,this._handlersAll=null,this._handlersComplex=null,this._enabled=!1},h.prototype.disable=function(){return this._enabled=!1,this},h.prototype.enable=function(){return this._enabled=!0,this},h.version="3.0.0","undefined"!=typeof n?("undefined"!=typeof r&&r.exports&&(n=r.exports=h),n.Emitter=h):"function"==typeof t&&t.amd?t("emmett",[],function(){return h}):this.Emitter=h}).call(this)},{}],4:[function(t,e,r){function n(t){return t+"$"+(new Date).getTime()+(""+Math.random()).replace("0.","")}function o(t,e){function r(t){this[t]=function(){var e=this.root[t].apply(this.root,arguments);return e instanceof i?this:e}}if(arguments.length<1&&(t={}),!(this instanceof o))return new o(t,e);if(!p.Object(t)&&!p.Array(t))throw Error("Baobab: invalid data.");if(s.call(this),this.options=u.shallowMerge(f,e),this._transaction={},this._future=void 0,this._cursors={},this._identity="[object Baobab]",this.data=u.deepClone(t),this.root=this.select([]),this.facets={},["get","set","unset","update"].forEach(r.bind(this)),!p.Object(this.options.facets))throw Error("Baobab: invalid facets.");for(var n in this.options.facets)this.addFacet(n,this.options.facets[n])}var i=t("./cursor.js"),s=t("emmett"),a=t("./watcher.js"),h=t("./facet.js"),u=t("./helpers.js"),c=t("./update.js"),l=t("./merge.js"),f=t("../defaults.js"),p=t("./type.js");u.inherits(o,s),o.prototype.addFacet=function(t,e){return this.facets[t]=this.createFacet(e),this},o.prototype.createFacet=function(t){return new h(this,t)},o.prototype.select=function(t){if(!t)throw Error("Baobab.select: invalid path.");if(arguments.length>1&&(t=u.arrayOf(arguments)),!p.Path(t))throw Error("Baobab.select: invalid path.");t=[].concat(t);var e,r=p.ComplexPath(t);r&&(e=u.solvePath(this.data,t,this));var o=t.map(function(t){return p.Function(t)?n("fn"):p.Object(t)?n("ob"):t}).join("|λ|");if(this._cursors[o])return this._cursors[o];var s=new i(this,t,e,o);return this._cursors[o]=s,s},o.prototype.stack=function(t){var e=this;if(!p.Object(t))throw Error("Baobab.update: wrong specification.");return this._transaction=l(t,this._transaction),this.options.autoCommit?this.options.asynchronous?(this._future||(this._future=setTimeout(e.commit.bind(e,null),0)),this):this.commit():this},o.prototype.commit=function(){var t=c(this.data,this._transaction,this.options),e=this.data;this._transaction={},this._future&&(this._future=clearTimeout(this._future));var r=this.options.validate,n=this.options.validationBehaviour;if("function"==typeof r){var o=r.call(this,e,t.data,t.log);if(o instanceof Error&&(this.emit("invalid",{error:o}),"rollback"===n))return this}return this.data=t.data,this.emit("update",{log:t.log,previousState:e}),this},o.prototype.watch=function(t){if(!p.Array(t)||t.some(function(t){return!p.Path(t)}))throw Error("Baobab.watch: invalid paths.");return new a(this,[].concat(t))},o.prototype.release=function(){var t;delete this.data,delete this._transaction;for(t in this._cursors)this._cursors[t].release();delete this._cursors;for(t in this.facets)this.facets[t].release();delete this.facets,this.kill()},o.prototype.toJSON=function(){return this.get()},o.prototype.toString=function(){return this._identity},e.exports=o},{"../defaults.js":2,"./cursor.js":5,"./facet.js":6,"./helpers.js":7,"./merge.js":8,"./type.js":9,"./update.js":10,"./watcher.js":11,emmett:3}],5:[function(t,e,r){function n(t,e,r,n){function o(t){if(i.isRecording()&&!i.undoing){var e=a.getIn(t,i.solvedPath,i.tree),r=a.deepClone(e);i.archive.add(r)}return i.undoing=!1,i.emit("update")}var i=this;s.call(this),e=e||[],this.tree=t,this.path=e,this.hash=n,this.archive=null,this.undoing=!1,this._identity="[object Cursor]",this.complexPath=!!r,this.solvedPath=this.complexPath?r:this.path,this.relevant=void 0!==this.get(),this.updateHandler=function(t){var e=t.data.log,r=t.data.previousState,n=!1;if(i.complexPath&&(i.solvedPath=a.solvePath(i.tree.data,i.path,i.tree)),!i.path.length)return o(r);i.solvedPath&&(n=a.solveUpdate(e,[i.solvedPath]));var s=void 0!==i.get();i.relevant?s&&n?o(r):s||(i.emit("irrelevant"),i.relevant=!1):s&&n&&(i.emit("relevant"),o(r),i.relevant=!0)};var h=!1;this._lazyBind=function(){h||(h=!0,i.tree.on("update",i.updateHandler))},this.on=a.before(this._lazyBind,this.on.bind(this)),this.once=a.before(this._lazyBind,this.once.bind(this)),this.complexPath&&this._lazyBind()}function o(t,e,r,n){if(arguments.length>5)throw Error("baobab.Cursor."+t+": too many arguments.");if(arguments.length<4&&(n=r,r=[]),r=r||[],"splice"===t&&!h.Splicer(n)){if(!h.Array(n))throw Error("baobab.Cursor.splice: incorrect value.");n=[n]}if(e&&!e(n))throw Error("baobab.Cursor."+t+": incorrect value.");var o=[].concat(r),i=a.solvePath(this.get(),o,this.tree);if(!i)throw Error("baobab.Cursor."+t+": could not solve dynamic path.");var s={};s["$"+t]=n;var u=a.pathObject(i,s);return u}function i(t,e){n.prototype[t]=function(){var r=o.bind(this,t,e).apply(this,arguments);return this.update(r)}}var s=t("emmett"),a=t("./helpers.js"),h=(t("../defaults.js"),t("./type.js"));a.inherits(n,s),n.prototype.isRoot=function(){return!this.path.length},n.prototype.isLeaf=function(){return h.Primitive(this.get())},n.prototype.isBranch=function(){return!this.isLeaf()&&!this.isRoot()},n.prototype.root=function(){return this.tree.root()},n.prototype.select=function(t){if(arguments.length>1&&(t=a.arrayOf(arguments)),!h.Path(t))throw Error("baobab.Cursor.select: invalid path.");return this.tree.select(this.path.concat(t))},n.prototype.up=function(){return this.solvedPath&&this.solvedPath.length?this.tree.select(this.path.slice(0,-1)):null},n.prototype.left=function(){var t=+this.solvedPath[this.solvedPath.length-1];if(isNaN(t))throw Error("baobab.Cursor.left: cannot go left on a non-list type.");return t?this.tree.select(this.solvedPath.slice(0,-1).concat(t-1)):null},n.prototype.leftmost=function(){var t=+this.solvedPath[this.solvedPath.length-1];if(isNaN(t))throw Error("baobab.Cursor.leftmost: cannot go left on a non-list type.");return this.tree.select(this.solvedPath.slice(0,-1).concat(0))},n.prototype.right=function(){var t=+this.solvedPath[this.solvedPath.length-1];if(isNaN(t))throw Error("baobab.Cursor.right: cannot go right on a non-list type.");return t+1===this.up().get().length?null:this.tree.select(this.solvedPath.slice(0,-1).concat(t+1))},n.prototype.rightmost=function(){var t=+this.solvedPath[this.solvedPath.length-1];if(isNaN(t))throw Error("baobab.Cursor.right: cannot go right on a non-list type.");var e=this.up().get();return this.tree.select(this.solvedPath.slice(0,-1).concat(e.length-1))},n.prototype.down=function(){+this.solvedPath[this.solvedPath.length-1];return this.get()instanceof Array?this.tree.select(this.solvedPath.concat(0)):null},n.prototype.get=function(t){arguments.length>1&&(t=a.arrayOf(arguments));var e=this.solvedPath.concat([].concat(t||0===t?t:[]));return a.getIn(this.tree.data,e,this.tree)},i("set"),i("apply",h.Function),i("chain",h.Function),i("push"),i("unshift"),i("merge",h.Object),i("splice"),n.prototype.unset=function(t){if(void 0===t&&this.isRoot())throw Error("baobab.Cursor.unset: cannot remove root node.");var e=o.bind(this,"unset",null).apply(this,[t,!0]);return this.update(e)},n.prototype.update=function(t,e){if(arguments.length<2)return this.tree.stack(a.pathObject(this.solvedPath,t)),this;var r=[].concat(t),n=a.solvePath(this.get(),r,this.tree);if(!n)throw Error("baobab.Cursor.update: could not solve dynamic path.");return this.tree.stack(a.pathObject(this.solvedPath.concat(n),e)),this},n.prototype.startRecording=function(t){if(t=t||5,1>t)throw Error("baobab.Cursor.startRecording: invalid maximum number of records.");return this.archive?this:(this._lazyBind(),this.archive=a.archive(t),this)},n.prototype.stopRecording=function(){return this.archive=null,this},n.prototype.undo=function(t){if(t=t||1,!this.isRecording())throw Error("baobab.Cursor.undo: cursor is not recording.");if(!h.PositiveInteger(t))throw Error("baobab.Cursor.undo: expecting a positive integer.");var e=this.archive.back(t);if(!e)throw Error("boabab.Cursor.undo: cannot find a relevant record ("+t+" back).");return this.undoing=!0,this.set(e)},n.prototype.isRecording=function(){return!!this.archive},n.prototype.hasHistory=function(){return!(!this.archive||!this.archive.get().length)},n.prototype.getHistory=function(){return this.archive?this.archive.get():[]},n.prototype.release=function(){this.tree.off("update",this.updateHandler),this.hash&&delete this.tree._cursors[this.hash],delete this.tree,delete this.path,delete this.solvedPath,delete this.archive,this.kill()},n.prototype.toJSON=function(){return this.get()},n.prototype.toString=function(){return this._identity},e.exports=n},{"../defaults.js":2,"./helpers.js":7,"./type.js":9,emmett:3}],6:[function(t,e,r){function n(t){return t}function o(t,e){function r(t){o[t]=l[t].bind(l)}var o=this,s=null,a=!1,h=e.get||n,u=e.cursors,c=Object.keys(u).map(function(t){return u[t]}),l=new i(t,c);["on","once","release"].forEach(r),this.get=function(){if(a)return s;var e={};for(var r in u)e[r]=t.get(u[r]);return s=h.call(null,e),a=!0,s},this.on("update",function(){a=!1})}{var i=t("./watcher.js");t("./helpers.js")}e.exports=o},{"./helpers.js":7,"./watcher.js":11}],7:[function(t,e,r){(function(r){function n(t){return Array.prototype.slice.call(t)}function o(t,e){return function(){t(),e.apply(null,arguments)}}function i(t,e,r){var o=n(arguments).slice(3);return e=+e,r=+r,t.slice(0,e).concat(t.slice(e+r).concat(o))}function s(t,e){var r,n={};for(r in t)n[r]=t[r];for(r in e)n[r]=e[r];return n}function a(t){var e=t.source,r="";return t.global&&(r+="g"),t.multiline&&(r+="m"),t.ignoreCase&&(r+="i"),t.sticky&&(r+="y"),t.unicode&&(r+="u"),new RegExp(e,r)}function h(t,e){if(!e||"object"!=typeof e||e instanceof Error||"ArrayBuffer"in r&&e instanceof ArrayBuffer)return e;if(_.Array(e)){if(t){var n,o,i=[];for(n=0,o=e.length;o>n;n++)i.push(P(e[n]));return i}return e.slice(0)}if(_.Date(e))return new Date(e.getTime());if(e instanceof RegExp)return a(e);if(_.Object(e)){var s,h={};e.constructor&&e.constructor!==Object&&(h=Object.create(e.constructor.prototype));for(s in e)e.hasOwnProperty(s)&&(h[s]=t?P(e[s]):e[s]);return h}return e}function u(t,e){return function(r){return e(t(r))}}function c(t,e){var r,n;for(r=0,n=t.length;n>r;r++)if(e(t[r]))return t[r]}function l(t,e){var r,n;for(r=0,n=t.length;n>r;r++)if(e(t[r]))return r;return-1}function f(t,e){var r,n=!0;if(!t)return!1;for(r in e)if(_.Object(e[r]))n=n&&f(t[r],e[r]);else if(_.Array(e[r]))n=n&&!!~e[r].indexOf(t[r]);else if(t[r]!==e[r])return!1;return n}function d(t,e){return c(t,function(t){return f(t,e)})}function y(t,e){return l(t,function(t){return f(t,e)})}function v(t,e,r){e=e||[];var n,o,i,s=t;for(o=0,i=e.length;i>o;o++){if(!s)return;if("function"==typeof e[o]){if(!_.Array(s))return;s=c(s,e[o])}else if("object"==typeof e[o])if(r&&"$cursor"in e[o]){if(!_.Path(e[o].$cursor))throw Error("baobab.getIn: $cursor path must be an array.");n=r.get(e[o].$cursor),s=s[n]}else{if(!_.Array(s))return;s=d(s,e[o])}else s=s[e[o]]}return s}function g(t,e,r){var n,o,i,s=[],a=t;for(o=0,i=e.length;i>o;o++){if(!a)return null;if("function"==typeof e[o]){if(!_.Array(a))return;n=l(a,e[o]),s.push(n),a=a[n]}else if("object"==typeof e[o])if(r&&"$cursor"in e[o]){if(!_.Path(e[o].$cursor))throw Error("baobab.getIn: $cursor path must be an array.");p=r.get(e[o].$cursor),s.push(p),a=a[p]}else{if(!_.Array(a))return;n=y(a,e[o]),s.push(n),a=a[n]}else s.push(e[o]),a=a[e[o]]||{}}return s}function b(t,e){var r,n,o,i,s,a,h,u,c;for(r=0,i=e.length;i>r;r++)for(h=e[r],n=0,s=t.length;s>n;n++)for(u=t[n],o=0,a=u.length;a>o&&(c=u[o],c==h[o]);o++)if(o+1===a||o+1===h.length)return!0;return!1}function m(t,e){var r,n=t.length,o={},i=o;for(n||(o=e),r=0;n>r;r++)i[t[r]]=r+1===n?e:{},i=i[t[r]];return o}function j(t,e){t.super_=e;var r=function(){};r.prototype=e.prototype,t.prototype=new r,t.prototype.constructor=t}function w(t){var e=[];return{add:function(r){e.unshift(r),e.length>t&&(e.length=t)},back:function(t){var r=e[t-1];return r&&(e=e.slice(t)),r},get:function(){return e}}}var _=t("./type.js"),$=h.bind(null,!1),P=h.bind(null,!0);e.exports={archive:w,arrayOf:n,before:o,deepClone:P,shallowClone:$,shallowMerge:s,compose:u,getIn:v,inherits:j,pathObject:m,solvePath:g,solveUpdate:b,splice:i}}).call(this,"undefined"!=typeof global?global:"undefined"!=typeof self?self:"undefined"!=typeof window?window:{})},{"./type.js":9}],8:[function(t,e,r){function n(t,e,r){a.forEach(function(e){r!==e&&delete t[e]}),t[r]=e[r]}function o(t,e){var r,h=i.shallowClone(e||{});a.forEach(function(e){t[e]&&n(h,t,e)}),t.$chain&&(a.slice(0,-1).forEach(function(t){delete h[t]}),h.$apply=h.$apply?i.compose(h.$apply,t.$chain):t.$chain),(t.$splice||h.$splice)&&(h.$splice=[].concat(h.$splice||[]).concat(t.$splice||[])),(t.$push||h.$push)&&(h.$push=[].concat(h.$push||[]).concat(t.$push||[])),(t.$unshift||h.$unshift)&&(h.$unshift=[].concat(t.$unshift||[]).concat(h.$unshift||[]));for(r in t)s.Object(t[r])?h[r]=o(t[r],h[r]):"$"!==r[0]&&(h[r]=t[r]);return h}var i=t("./helpers.js"),s=t("./type.js"),a=["$unset","$set","$merge","$apply"];e.exports=o},{"./helpers.js":7,"./type.js":9}],9:[function(t,e,r){function n(t,e){return e.some(function(e){return o[e](t)})}var o={};o.Array=function(t){return Array.isArray(t)},o.Object=function(t){return t&&"object"==typeof t&&!Array.isArray(t)&&!(t instanceof Function)},o.String=function(t){return"string"==typeof t},o.Number=function(t){return"number"==typeof t},o.PositiveInteger=function(t){return"number"==typeof t&&t>0&&t%1===0},o.Function=function(t){return"function"==typeof t},o.Primitive=function(t){return"string"==typeof t||"number"==typeof t||"boolean"==typeof t},o.Date=function(t){return t instanceof Date},o.NonScalar=function(t){return o.Object(t)||o.Array(t)},o.Splicer=function(t){return o.Array(t)&&t.every(o.Array)},o.Path=function(t){var e=["String","Number","Function","Object"];return o.Array(t)?t.every(function(t){return n(t,e)}):n(t,e)},o.MixinCursor=function(t){return n(t,["String","Number","Array","Function","Cursor"])},o.MixinCursors=function(t){return n(t,["Object","Array","Function"])},o.ComplexPath=function(t){return t.some(function(t){return n(t,["Object","Function"])})},e.exports=o},{}],10:[function(t,e,r){function n(t,e){var r=new Error("baobab.update: "+e+" at path /"+t.slice(1).join("/"));return r.path=t,r}var o=t("./helpers.js"),i=t("./type.js");e.exports=function(t,e,r){if(r=r||{},!i.Object(t)&&!i.Array(t))throw Error("baobab.update: invalid target.");var s={};t={root:o.shallowClone(t)};var a=function(t,e,r,h){r=r||["root"];var u,c,l,f=r.join("|λ|"),p=r[r.length-1],d=Object.keys(e).some(function(t){return!!~["$set","$push","$unshift","$splice","$unset","$merge","$apply"].indexOf(t)});if(d){s[f]=!0;for(c in e){if("$unset"===c){var y=r[r.length-2];if(!i.Object(h[y]))throw n(r.slice(0,-1),"using command $unset on a non-object");h[y]=o.shallowClone(t),delete h[y][p];break}if("$set"===c){l=e.$set,t[p]=l;break}if("$apply"===c){if(u=e.$apply,"function"!=typeof u)throw n(r,"using command $apply with a non function");t[p]=u.call(null,t[p]);break}if("$merge"===c){if(l=e.$merge,!i.Object(t[p])||!i.Object(l))throw n(r,"using command $merge with a non object");t[p]=o.shallowMerge(t[p],l);break}if("$splice"===c){if(l=e.$splice,!i.Array(t[p]))throw n(r,"using command $push to a non array");l.forEach(function(e){t[p]=o.splice.apply(null,[t[p]].concat(e))})}if("$push"===c){if(l=e.$push,!i.Array(t[p]))throw n(r,"using command $push to a non array");t[p]=t[p].concat(l)}if("$unshift"===c){if(l=e.$unshift,!i.Array(t[p]))throw n(r,"using command $unshift to a non array");t[p]=[].concat(l).concat(t[p])}}}else for(c in e)t[p][c]="undefined"==typeof t[p][c]?{}:o.shallowClone(t[p][c]),a(t[p],e[c],r.concat(c),t)};return a(t,e),{data:t.root,log:Object.keys(s).map(function(t){return t.split("|λ|").slice(1)})}}},{"./helpers.js":7,"./type.js":9}],11:[function(t,e,r){function n(t,e){function r(){h&&(a=e.map(function(t){return i.solvePath(n.tree.data,t,n.tree)}))}var n=this;o.call(this),this.tree=t;var a=e,h=e.some(s.ComplexPath);this.updateHandler=function(t){var e=i.solveUpdate(t.data.log,a);e&&n.emit("update")},r(),this.tree.on("update",this.updateHandler)}var o=t("emmett"),i=t("./helpers.js"),s=t("./type.js");i.inherits(n,o),n.prototype.release=function(){this.tree.off("update",this.updateHandler),this.tree=null,this.kill()},e.exports=n},{"./helpers.js":7,"./type.js":9,emmett:3}]},{},[1])(1)}); \ No newline at end of file +!function(t){if("object"==typeof exports&&"undefined"!=typeof module)module.exports=t();else if("function"==typeof define&&define.amd)define([],t);else{var e;e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:this,e.Baobab=t()}}(function(){var t;return function e(t,r,n){function o(s,a){if(!r[s]){if(!t[s]){var h="function"==typeof require&&require;if(!a&&h)return h(s,!0);if(i)return i(s,!0);var u=new Error("Cannot find module '"+s+"'");throw u.code="MODULE_NOT_FOUND",u}var c=r[s]={exports:{}};t[s][0].call(c.exports,function(e){var r=t[s][1][e];return o(r?r:e)},c,c.exports,e,t,r,n)}return r[s].exports}for(var i="function"==typeof require&&require,s=0;sn;n++)t[n].fn!==e&&o.push(t[n]);return o}var s={once:"boolean",scope:"object"},a=0,h=function(){this._enabled=!0,this.unbindAll()};h.prototype.unbindAll=function(){return this._handlers={},this._handlersAll=[],this._handlersComplex=[],this},h.prototype.on=function(t,e,r){var n,i,h,u,c,l,f;if(o(t)){for(u in t)this.on(u,t[u],e);return this}for("function"==typeof t&&(r=e,e=t,t=null),c=[].concat(t),n=0,i=c.length;i>n;n++){if(u=c[n],f={order:a++,fn:e},"string"==typeof u)this._handlers[u]||(this._handlers[u]=[]),l=this._handlers[u];else if(u instanceof RegExp)l=this._handlersComplex,f.pattern=u;else{if(null!==u)throw Error("Emitter.on: invalid event.");l=this._handlersAll}for(h in r||{})s[h]&&(f[h]=r[h]);f.once&&(f.parent=l),l.push(f)}return this},h.prototype.once=function(){var t=Array.prototype.slice.call(arguments),r=t.length-1;return o(t[r])&&t.length>1?t[r]=e(t[r],{once:!0}):t.push({once:!0}),this.on.apply(this,t)},h.prototype.off=function(t,e){var r,n,s,a;if(1===arguments.length&&"function"==typeof t){e=arguments[0];for(s in this._handlers)this._handlers[s]=i(this._handlers[s],e),0===this._handlers[s].length&&delete this._handlers[s];this._handlersAll=i(this._handlersAll,e),this._handlersComplex=i(this._handlersComplex,e)}else if(1===arguments.length&&"string"==typeof t)delete this._handlers[t];else if(2===arguments.length){var h=[].concat(t);for(r=0,n=h.length;n>r;r++)a=h[r],this._handlers[a]=i(this._handlers[a],e),0===(this._handlers[a]||[]).length&&delete this._handlers[a]}else if(o(t))for(s in t)this.off(s,t[s]);return this},h.prototype.listeners=function(t){var e,r,n,o=this._handlersAll||[],i=!1;if(!t)throw Error("Emitter.listeners: no event provided.");for(o=o.concat(this._handlers[t]||[]),r=0,n=this._handlersComplex.length;n>r;r++)e=this._handlersComplex[r],~t.search(e.pattern)&&(i=!0,o.push(e));return this._handlersAll.length||i?o.sort(function(t,e){return t.order-e.order}):o.slice(0)},h.prototype.emit=function(t,e){if(!this._enabled)return this;if(o(t)){for(var r in t)this.emit(r,t[r]);return this}var n,i,s,a,h,u,c,l=[].concat(t),f=[];for(a=0,u=l.length;u>a;a++){for(i=this.listeners(l[a]),h=0,c=i.length;c>h;h++)s=i[h],n={type:l[a],target:this},arguments.length>1&&(n.data=e),s.fn.call("scope"in s?s.scope:this,n),s.once&&f.push(s);for(h=f.length-1;h>=0;h--)f[h].parent.splice(f[h].parent.indexOf(f[h]),1)}return this},h.prototype.kill=function(){this.unbindAll(),this._handlers=null,this._handlersAll=null,this._handlersComplex=null,this._enabled=!1},h.prototype.disable=function(){return this._enabled=!1,this},h.prototype.enable=function(){return this._enabled=!0,this},h.version="3.0.0","undefined"!=typeof n?("undefined"!=typeof r&&r.exports&&(n=r.exports=h),n.Emitter=h):"function"==typeof t&&t.amd?t("emmett",[],function(){return h}):this.Emitter=h}).call(this)},{}],4:[function(t,e,r){function n(t){return t+"$"+(new Date).getTime()+(""+Math.random()).replace("0.","")}function o(t,e){function r(t){this[t]=function(){var e=this.root[t].apply(this.root,arguments);return e instanceof i?this:e}}if(arguments.length<1&&(t={}),!(this instanceof o))return new o(t,e);if(!p.Object(t)&&!p.Array(t))throw Error("Baobab: invalid data.");if(s.call(this),this.options=u.shallowMerge(f,e),this._transaction={},this._future=void 0,this._cursors={},this._identity="[object Baobab]",this.data=u.deepClone(t),this.root=this.select([]),this.facets={},["get","set","unset","update"].forEach(r.bind(this)),!p.Object(this.options.facets))throw Error("Baobab: invalid facets.");for(var n in this.options.facets)this.addFacet(n,this.options.facets[n])}var i=t("./cursor.js"),s=t("emmett"),a=t("./watcher.js"),h=t("./facet.js"),u=t("./helpers.js"),c=t("./update.js"),l=t("./merge.js"),f=t("../defaults.js"),p=t("./type.js");u.inherits(o,s),o.prototype.addFacet=function(t,e){return this.facets[t]=this.createFacet(e),this},o.prototype.createFacet=function(t){return new h(this,t)},o.prototype.select=function(t){if(!t)throw Error("Baobab.select: invalid path.");if(arguments.length>1&&(t=u.arrayOf(arguments)),!p.Path(t))throw Error("Baobab.select: invalid path.");t=[].concat(t);var e,r=p.ComplexPath(t);r&&(e=u.solvePath(this.data,t,this));var o=t.map(function(t){return p.Function(t)?n("fn"):p.Object(t)?n("ob"):t}).join("|λ|");if(this._cursors[o])return this._cursors[o];var s=new i(this,t,e,o);return this._cursors[o]=s,s},o.prototype.stack=function(t){var e=this;if(!p.Object(t))throw Error("Baobab.update: wrong specification.");return this._transaction=l(t,this._transaction),this.options.autoCommit?this.options.asynchronous?(this._future||(this._future=setTimeout(e.commit.bind(e,null),0)),this):this.commit():this},o.prototype.commit=function(){var t=c(this.data,this._transaction,this.options),e=this.data;this._transaction={},this._future&&(this._future=clearTimeout(this._future));var r=this.options.validate,n=this.options.validationBehaviour;if("function"==typeof r){var o=r.call(this,e,t.data,t.log);if(o instanceof Error&&(this.emit("invalid",{error:o}),"rollback"===n))return this}return this.data=t.data,this.emit("update",{log:t.log,previousState:e}),this},o.prototype.watch=function(t){if(!p.Array(t)||t.some(function(t){return!p.Path(t)}))throw Error("Baobab.watch: invalid paths.");return new a(this,[].concat(t))},o.prototype.release=function(){var t;delete this.data,delete this._transaction;for(t in this._cursors)this._cursors[t].release();delete this._cursors;for(t in this.facets)this.facets[t].release();delete this.facets,this.kill()},o.prototype.toJSON=function(){return this.get()},o.prototype.toString=function(){return this._identity},e.exports=o},{"../defaults.js":2,"./cursor.js":5,"./facet.js":6,"./helpers.js":7,"./merge.js":8,"./type.js":9,"./update.js":10,"./watcher.js":11,emmett:3}],5:[function(t,e,r){function n(t,e,r,n){function o(t){if(i.recording&&!i.undoing){var e=a.getIn(t,i.solvedPath,i.tree),r=a.deepClone(e);i.archive.add(r)}return i.undoing=!1,i.emit("update")}var i=this;s.call(this),e=e||[],this.tree=t,this.path=e,this.hash=n,this.archive=null,this.recording=!1,this.undoing=!1,this._identity="[object Cursor]",this.complexPath=!!r,this.solvedPath=this.complexPath?r:this.path,this.relevant=void 0!==this.get(),this.updateHandler=function(t){var e=t.data.log,r=t.data.previousState,n=!1;if(i.complexPath&&(i.solvedPath=a.solvePath(i.tree.data,i.path,i.tree)),!i.path.length)return o(r);i.solvedPath&&(n=a.solveUpdate(e,[i.solvedPath]));var s=void 0!==i.get();i.relevant?s&&n?o(r):s||(i.emit("irrelevant"),i.relevant=!1):s&&n&&(i.emit("relevant"),o(r),i.relevant=!0)};var h=!1;this._lazyBind=function(){h||(h=!0,i.tree.on("update",i.updateHandler))},this.on=a.before(this._lazyBind,this.on.bind(this)),this.once=a.before(this._lazyBind,this.once.bind(this)),this.complexPath&&this._lazyBind()}function o(t,e,r,n){if(arguments.length>5)throw Error("baobab.Cursor."+t+": too many arguments.");if(arguments.length<4&&(n=r,r=[]),r=r||[],"splice"===t&&!h.Splicer(n)){if(!h.Array(n))throw Error("baobab.Cursor.splice: incorrect value.");n=[n]}if(e&&!e(n))throw Error("baobab.Cursor."+t+": incorrect value.");var o=[].concat(r),i=a.solvePath(this.get(),o,this.tree);if(!i)throw Error("baobab.Cursor."+t+": could not solve dynamic path.");var s={};s["$"+t]=n;var u=a.pathObject(i,s);return u}function i(t,e){n.prototype[t]=function(){var r=o.bind(this,t,e).apply(this,arguments);return this.update(r)}}var s=t("emmett"),a=t("./helpers.js"),h=(t("../defaults.js"),t("./type.js"));a.inherits(n,s),n.prototype.isRoot=function(){return!this.path.length},n.prototype.isLeaf=function(){return h.Primitive(this.get())},n.prototype.isBranch=function(){return!this.isLeaf()&&!this.isRoot()},n.prototype.root=function(){return this.tree.root()},n.prototype.select=function(t){if(arguments.length>1&&(t=a.arrayOf(arguments)),!h.Path(t))throw Error("baobab.Cursor.select: invalid path.");return this.tree.select(this.path.concat(t))},n.prototype.up=function(){return this.solvedPath&&this.solvedPath.length?this.tree.select(this.path.slice(0,-1)):null},n.prototype.left=function(){var t=+this.solvedPath[this.solvedPath.length-1];if(isNaN(t))throw Error("baobab.Cursor.left: cannot go left on a non-list type.");return t?this.tree.select(this.solvedPath.slice(0,-1).concat(t-1)):null},n.prototype.leftmost=function(){var t=+this.solvedPath[this.solvedPath.length-1];if(isNaN(t))throw Error("baobab.Cursor.leftmost: cannot go left on a non-list type.");return this.tree.select(this.solvedPath.slice(0,-1).concat(0))},n.prototype.right=function(){var t=+this.solvedPath[this.solvedPath.length-1];if(isNaN(t))throw Error("baobab.Cursor.right: cannot go right on a non-list type.");return t+1===this.up().get().length?null:this.tree.select(this.solvedPath.slice(0,-1).concat(t+1))},n.prototype.rightmost=function(){var t=+this.solvedPath[this.solvedPath.length-1];if(isNaN(t))throw Error("baobab.Cursor.right: cannot go right on a non-list type.");var e=this.up().get();return this.tree.select(this.solvedPath.slice(0,-1).concat(e.length-1))},n.prototype.down=function(){+this.solvedPath[this.solvedPath.length-1];return this.get()instanceof Array?this.tree.select(this.solvedPath.concat(0)):null},n.prototype.get=function(t){arguments.length>1&&(t=a.arrayOf(arguments));var e=this.solvedPath.concat([].concat(t||0===t?t:[]));return a.getIn(this.tree.data,e,this.tree)},i("set"),i("apply",h.Function),i("chain",h.Function),i("push"),i("unshift"),i("merge",h.Object),i("splice"),n.prototype.unset=function(t){if(void 0===t&&this.isRoot())throw Error("baobab.Cursor.unset: cannot remove root node.");var e=o.bind(this,"unset",null).apply(this,[t,!0]);return this.update(e)},n.prototype.update=function(t,e){if(arguments.length<2)return this.tree.stack(a.pathObject(this.solvedPath,t)),this;var r=[].concat(t),n=a.solvePath(this.get(),r,this.tree);if(!n)throw Error("baobab.Cursor.update: could not solve dynamic path.");return this.tree.stack(a.pathObject(this.solvedPath.concat(n),e)),this},n.prototype.startRecording=function(t){if(t=t||5,1>t)throw Error("baobab.Cursor.startRecording: invalid maximum number of records.");return this.archive?this:(this._lazyBind(),this.archive=a.archive(t),this.recording=!0,this)},n.prototype.stopRecording=function(){return this.recording=!1,this},n.prototype.undo=function(t){if(t=t||1,!this.recording)throw Error("baobab.Cursor.undo: cursor is not recording.");if(!h.PositiveInteger(t))throw Error("baobab.Cursor.undo: expecting a positive integer.");var e=this.archive.back(t);if(!e)throw Error("boabab.Cursor.undo: cannot find a relevant record ("+t+" back).");return this.undoing=!0,this.set(e)},n.prototype.hasHistory=function(){return!(!this.archive||!this.archive.get().length)},n.prototype.getHistory=function(){return this.archive?this.archive.get():[]},n.prototype.clearHistory=function(){return this.archive=null,this},n.prototype.release=function(){this.tree.off("update",this.updateHandler),this.hash&&delete this.tree._cursors[this.hash],delete this.tree,delete this.path,delete this.solvedPath,delete this.archive,this.kill()},n.prototype.toJSON=function(){return this.get()},n.prototype.toString=function(){return this._identity},e.exports=n},{"../defaults.js":2,"./helpers.js":7,"./type.js":9,emmett:3}],6:[function(t,e,r){function n(t){return t}function o(t,e){function r(t){o[t]=l[t].bind(l)}var o=this,s=null,a=!1,h=e.get||n,u=e.cursors,c=Object.keys(u).map(function(t){return u[t]}),l=new i(t,c);["on","once","release"].forEach(r),this.get=function(){if(a)return s;var e={};for(var r in u)e[r]=t.get(u[r]);return s=h.call(null,e),a=!0,s},this.on("update",function(){a=!1})}{var i=t("./watcher.js");t("./helpers.js")}e.exports=o},{"./helpers.js":7,"./watcher.js":11}],7:[function(t,e,r){(function(r){function n(t){return Array.prototype.slice.call(t)}function o(t,e){return function(){t(),e.apply(null,arguments)}}function i(t,e,r){var o=n(arguments).slice(3);return e=+e,r=+r,t.slice(0,e).concat(t.slice(e+r).concat(o))}function s(t,e){var r,n={};for(r in t)n[r]=t[r];for(r in e)n[r]=e[r];return n}function a(t){var e=t.source,r="";return t.global&&(r+="g"),t.multiline&&(r+="m"),t.ignoreCase&&(r+="i"),t.sticky&&(r+="y"),t.unicode&&(r+="u"),new RegExp(e,r)}function h(t,e){if(!e||"object"!=typeof e||e instanceof Error||"ArrayBuffer"in r&&e instanceof ArrayBuffer)return e;if(_.Array(e)){if(t){var n,o,i=[];for(n=0,o=e.length;o>n;n++)i.push(P(e[n]));return i}return e.slice(0)}if(_.Date(e))return new Date(e.getTime());if(e instanceof RegExp)return a(e);if(_.Object(e)){var s,h={};e.constructor&&e.constructor!==Object&&(h=Object.create(e.constructor.prototype));for(s in e)e.hasOwnProperty(s)&&(h[s]=t?P(e[s]):e[s]);return h}return e}function u(t,e){return function(r){return e(t(r))}}function c(t,e){var r,n;for(r=0,n=t.length;n>r;r++)if(e(t[r]))return t[r]}function l(t,e){var r,n;for(r=0,n=t.length;n>r;r++)if(e(t[r]))return r;return-1}function f(t,e){var r,n=!0;if(!t)return!1;for(r in e)if(_.Object(e[r]))n=n&&f(t[r],e[r]);else if(_.Array(e[r]))n=n&&!!~e[r].indexOf(t[r]);else if(t[r]!==e[r])return!1;return n}function d(t,e){return c(t,function(t){return f(t,e)})}function y(t,e){return l(t,function(t){return f(t,e)})}function v(t,e,r){e=e||[];var n,o,i,s=t;for(o=0,i=e.length;i>o;o++){if(!s)return;if("function"==typeof e[o]){if(!_.Array(s))return;s=c(s,e[o])}else if("object"==typeof e[o])if(r&&"$cursor"in e[o]){if(!_.Path(e[o].$cursor))throw Error("baobab.getIn: $cursor path must be an array.");n=r.get(e[o].$cursor),s=s[n]}else{if(!_.Array(s))return;s=d(s,e[o])}else s=s[e[o]]}return s}function g(t,e,r){var n,o,i,s=[],a=t;for(o=0,i=e.length;i>o;o++){if(!a)return null;if("function"==typeof e[o]){if(!_.Array(a))return;n=l(a,e[o]),s.push(n),a=a[n]}else if("object"==typeof e[o])if(r&&"$cursor"in e[o]){if(!_.Path(e[o].$cursor))throw Error("baobab.getIn: $cursor path must be an array.");p=r.get(e[o].$cursor),s.push(p),a=a[p]}else{if(!_.Array(a))return;n=y(a,e[o]),s.push(n),a=a[n]}else s.push(e[o]),a=a[e[o]]||{}}return s}function b(t,e){var r,n,o,i,s,a,h,u,c;for(r=0,i=e.length;i>r;r++)for(h=e[r],n=0,s=t.length;s>n;n++)for(u=t[n],o=0,a=u.length;a>o&&(c=u[o],c==h[o]);o++)if(o+1===a||o+1===h.length)return!0;return!1}function m(t,e){var r,n=t.length,o={},i=o;for(n||(o=e),r=0;n>r;r++)i[t[r]]=r+1===n?e:{},i=i[t[r]];return o}function j(t,e){t.super_=e;var r=function(){};r.prototype=e.prototype,t.prototype=new r,t.prototype.constructor=t}function w(t){var e=[];return{add:function(r){e.unshift(r),e.length>t&&(e.length=t)},back:function(t){var r=e[t-1];return r&&(e=e.slice(t)),r},get:function(){return e}}}var _=t("./type.js"),$=h.bind(null,!1),P=h.bind(null,!0);e.exports={archive:w,arrayOf:n,before:o,deepClone:P,shallowClone:$,shallowMerge:s,compose:u,getIn:v,inherits:j,pathObject:m,solvePath:g,solveUpdate:b,splice:i}}).call(this,"undefined"!=typeof global?global:"undefined"!=typeof self?self:"undefined"!=typeof window?window:{})},{"./type.js":9}],8:[function(t,e,r){function n(t,e,r){a.forEach(function(e){r!==e&&delete t[e]}),t[r]=e[r]}function o(t,e){var r,h=i.shallowClone(e||{});a.forEach(function(e){t[e]&&n(h,t,e)}),t.$chain&&(a.slice(0,-1).forEach(function(t){delete h[t]}),h.$apply=h.$apply?i.compose(h.$apply,t.$chain):t.$chain),(t.$splice||h.$splice)&&(h.$splice=[].concat(h.$splice||[]).concat(t.$splice||[])),(t.$push||h.$push)&&(h.$push=[].concat(h.$push||[]).concat(t.$push||[])),(t.$unshift||h.$unshift)&&(h.$unshift=[].concat(t.$unshift||[]).concat(h.$unshift||[]));for(r in t)s.Object(t[r])?h[r]=o(t[r],h[r]):"$"!==r[0]&&(h[r]=t[r]);return h}var i=t("./helpers.js"),s=t("./type.js"),a=["$unset","$set","$merge","$apply"];e.exports=o},{"./helpers.js":7,"./type.js":9}],9:[function(t,e,r){function n(t,e){return e.some(function(e){return o[e](t)})}var o={};o.Array=function(t){return Array.isArray(t)},o.Object=function(t){return t&&"object"==typeof t&&!Array.isArray(t)&&!(t instanceof Function)},o.String=function(t){return"string"==typeof t},o.Number=function(t){return"number"==typeof t},o.PositiveInteger=function(t){return"number"==typeof t&&t>0&&t%1===0},o.Function=function(t){return"function"==typeof t},o.Primitive=function(t){return"string"==typeof t||"number"==typeof t||"boolean"==typeof t},o.Date=function(t){return t instanceof Date},o.NonScalar=function(t){return o.Object(t)||o.Array(t)},o.Splicer=function(t){return o.Array(t)&&t.every(o.Array)},o.Path=function(t){var e=["String","Number","Function","Object"];return o.Array(t)?t.every(function(t){return n(t,e)}):n(t,e)},o.MixinCursor=function(t){return n(t,["String","Number","Array","Function","Cursor"])},o.MixinCursors=function(t){return n(t,["Object","Array","Function"])},o.ComplexPath=function(t){return t.some(function(t){return n(t,["Object","Function"])})},e.exports=o},{}],10:[function(t,e,r){function n(t,e){var r=new Error("baobab.update: "+e+" at path /"+t.slice(1).join("/"));return r.path=t,r}var o=t("./helpers.js"),i=t("./type.js");e.exports=function(t,e,r){if(r=r||{},!i.Object(t)&&!i.Array(t))throw Error("baobab.update: invalid target.");var s={};t={root:o.shallowClone(t)};var a=function(t,e,r,h){r=r||["root"];var u,c,l,f=r.join("|λ|"),p=r[r.length-1],d=Object.keys(e).some(function(t){return!!~["$set","$push","$unshift","$splice","$unset","$merge","$apply"].indexOf(t)});if(d){s[f]=!0;for(c in e){if("$unset"===c){var y=r[r.length-2];if(!i.Object(h[y]))throw n(r.slice(0,-1),"using command $unset on a non-object");h[y]=o.shallowClone(t),delete h[y][p];break}if("$set"===c){l=e.$set,t[p]=l;break}if("$apply"===c){if(u=e.$apply,"function"!=typeof u)throw n(r,"using command $apply with a non function");t[p]=u.call(null,t[p]);break}if("$merge"===c){if(l=e.$merge,!i.Object(t[p])||!i.Object(l))throw n(r,"using command $merge with a non object");t[p]=o.shallowMerge(t[p],l);break}if("$splice"===c){if(l=e.$splice,!i.Array(t[p]))throw n(r,"using command $push to a non array");l.forEach(function(e){t[p]=o.splice.apply(null,[t[p]].concat(e))})}if("$push"===c){if(l=e.$push,!i.Array(t[p]))throw n(r,"using command $push to a non array");t[p]=t[p].concat(l)}if("$unshift"===c){if(l=e.$unshift,!i.Array(t[p]))throw n(r,"using command $unshift to a non array");t[p]=[].concat(l).concat(t[p])}}}else for(c in e)t[p][c]="undefined"==typeof t[p][c]?{}:o.shallowClone(t[p][c]),a(t[p],e[c],r.concat(c),t)};return a(t,e),{data:t.root,log:Object.keys(s).map(function(t){return t.split("|λ|").slice(1)})}}},{"./helpers.js":7,"./type.js":9}],11:[function(t,e,r){function n(t,e){function r(){h&&(a=e.map(function(t){return i.solvePath(n.tree.data,t,n.tree)}))}var n=this;o.call(this),this.tree=t;var a=e,h=e.some(s.ComplexPath);this.updateHandler=function(t){var e=i.solveUpdate(t.data.log,a);e&&n.emit("update")},r(),this.tree.on("update",this.updateHandler)}var o=t("emmett"),i=t("./helpers.js"),s=t("./type.js");i.inherits(n,o),n.prototype.release=function(){this.tree.off("update",this.updateHandler),this.tree=null,this.kill()},e.exports=n},{"./helpers.js":7,"./type.js":9,emmett:3}]},{},[1])(1)}); \ No newline at end of file diff --git a/src/cursor.js b/src/cursor.js index 6428da8..42fea1a 100644 --- a/src/cursor.js +++ b/src/cursor.js @@ -26,6 +26,7 @@ function Cursor(tree, path, solvedPath, hash) { this.path = path; this.hash = hash; this.archive = null; + this.recording = false; this.undoing = false; // Privates @@ -40,7 +41,7 @@ function Cursor(tree, path, solvedPath, hash) { // Root listeners function update(previousState) { - if (self.isRecording() && !self.undoing) { + if (self.recording && !self.undoing) { // Handle archive var data = helpers.getIn(previousState, self.solvedPath, self.tree), @@ -314,18 +315,19 @@ Cursor.prototype.startRecording = function(maxRecords) { this._lazyBind(); this.archive = helpers.archive(maxRecords); + this.recording = true; return this; }; Cursor.prototype.stopRecording = function() { - this.archive = null; + this.recording = false; return this; }; Cursor.prototype.undo = function(steps) { steps = steps || 1; - if (!this.isRecording()) + if (!this.recording) throw Error('baobab.Cursor.undo: cursor is not recording.'); if (!type.PositiveInteger(steps)) @@ -340,10 +342,6 @@ Cursor.prototype.undo = function(steps) { return this.set(record); }; -Cursor.prototype.isRecording = function() { - return !!this.archive; -}; - Cursor.prototype.hasHistory = function() { return !!(this.archive && this.archive.get().length); }; @@ -352,6 +350,11 @@ Cursor.prototype.getHistory = function() { return this.archive ? this.archive.get() : []; }; +Cursor.prototype.clearHistory = function() { + this.archive = null; + return this; +}; + /** * Releasing */ diff --git a/test/suites/cursor.js b/test/suites/cursor.js index 4848346..22b6aa6 100644 --- a/test/suites/cursor.js +++ b/test/suites/cursor.js @@ -524,13 +524,13 @@ describe('Cursor API', function() { var baobab = new Baobab({item: 1}, {asynchronous: false}), cursor = baobab.select('item'); - assert(!cursor.isRecording()); + assert(!cursor.recording); assert(!cursor.hasHistory()); assert.deepEqual(cursor.getHistory(), []); cursor.startRecording(); - assert(cursor.isRecording()); + assert(cursor.recording); [1, 2, 3, 4, 5, 6].forEach(function() { cursor.apply(function(e) { return e + 1; }); @@ -541,8 +541,9 @@ describe('Cursor API', function() { assert.deepEqual(cursor.getHistory(), [2, 3, 4, 5, 6].reverse()); cursor.stopRecording(); + cursor.clearHistory(); - assert(!cursor.isRecording()); + assert(!cursor.recording); assert(!cursor.hasHistory()); assert.deepEqual(cursor.getHistory(), []); }); From 3d2ce0a2ad794c65cda261e03d8fb1a258316c3d Mon Sep 17 00:00:00 2001 From: Yomguithereal Date: Thu, 16 Apr 2015 17:09:42 +0200 Subject: [PATCH 62/73] Switching to american spelling for behavio{u}r... --- build/baobab.min.js | 2 +- defaults.js | 2 +- src/baobab.js | 4 ++-- test/suites/baobab.js | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/build/baobab.min.js b/build/baobab.min.js index d4c2d02..e9b84b7 100644 --- a/build/baobab.min.js +++ b/build/baobab.min.js @@ -1,2 +1,2 @@ /* baobab.js - Version: 1.0.0-rc1 - Author: Yomguithereal (Guillaume Plique) */ -!function(t){if("object"==typeof exports&&"undefined"!=typeof module)module.exports=t();else if("function"==typeof define&&define.amd)define([],t);else{var e;e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:this,e.Baobab=t()}}(function(){var t;return function e(t,r,n){function o(s,a){if(!r[s]){if(!t[s]){var h="function"==typeof require&&require;if(!a&&h)return h(s,!0);if(i)return i(s,!0);var u=new Error("Cannot find module '"+s+"'");throw u.code="MODULE_NOT_FOUND",u}var c=r[s]={exports:{}};t[s][0].call(c.exports,function(e){var r=t[s][1][e];return o(r?r:e)},c,c.exports,e,t,r,n)}return r[s].exports}for(var i="function"==typeof require&&require,s=0;sn;n++)t[n].fn!==e&&o.push(t[n]);return o}var s={once:"boolean",scope:"object"},a=0,h=function(){this._enabled=!0,this.unbindAll()};h.prototype.unbindAll=function(){return this._handlers={},this._handlersAll=[],this._handlersComplex=[],this},h.prototype.on=function(t,e,r){var n,i,h,u,c,l,f;if(o(t)){for(u in t)this.on(u,t[u],e);return this}for("function"==typeof t&&(r=e,e=t,t=null),c=[].concat(t),n=0,i=c.length;i>n;n++){if(u=c[n],f={order:a++,fn:e},"string"==typeof u)this._handlers[u]||(this._handlers[u]=[]),l=this._handlers[u];else if(u instanceof RegExp)l=this._handlersComplex,f.pattern=u;else{if(null!==u)throw Error("Emitter.on: invalid event.");l=this._handlersAll}for(h in r||{})s[h]&&(f[h]=r[h]);f.once&&(f.parent=l),l.push(f)}return this},h.prototype.once=function(){var t=Array.prototype.slice.call(arguments),r=t.length-1;return o(t[r])&&t.length>1?t[r]=e(t[r],{once:!0}):t.push({once:!0}),this.on.apply(this,t)},h.prototype.off=function(t,e){var r,n,s,a;if(1===arguments.length&&"function"==typeof t){e=arguments[0];for(s in this._handlers)this._handlers[s]=i(this._handlers[s],e),0===this._handlers[s].length&&delete this._handlers[s];this._handlersAll=i(this._handlersAll,e),this._handlersComplex=i(this._handlersComplex,e)}else if(1===arguments.length&&"string"==typeof t)delete this._handlers[t];else if(2===arguments.length){var h=[].concat(t);for(r=0,n=h.length;n>r;r++)a=h[r],this._handlers[a]=i(this._handlers[a],e),0===(this._handlers[a]||[]).length&&delete this._handlers[a]}else if(o(t))for(s in t)this.off(s,t[s]);return this},h.prototype.listeners=function(t){var e,r,n,o=this._handlersAll||[],i=!1;if(!t)throw Error("Emitter.listeners: no event provided.");for(o=o.concat(this._handlers[t]||[]),r=0,n=this._handlersComplex.length;n>r;r++)e=this._handlersComplex[r],~t.search(e.pattern)&&(i=!0,o.push(e));return this._handlersAll.length||i?o.sort(function(t,e){return t.order-e.order}):o.slice(0)},h.prototype.emit=function(t,e){if(!this._enabled)return this;if(o(t)){for(var r in t)this.emit(r,t[r]);return this}var n,i,s,a,h,u,c,l=[].concat(t),f=[];for(a=0,u=l.length;u>a;a++){for(i=this.listeners(l[a]),h=0,c=i.length;c>h;h++)s=i[h],n={type:l[a],target:this},arguments.length>1&&(n.data=e),s.fn.call("scope"in s?s.scope:this,n),s.once&&f.push(s);for(h=f.length-1;h>=0;h--)f[h].parent.splice(f[h].parent.indexOf(f[h]),1)}return this},h.prototype.kill=function(){this.unbindAll(),this._handlers=null,this._handlersAll=null,this._handlersComplex=null,this._enabled=!1},h.prototype.disable=function(){return this._enabled=!1,this},h.prototype.enable=function(){return this._enabled=!0,this},h.version="3.0.0","undefined"!=typeof n?("undefined"!=typeof r&&r.exports&&(n=r.exports=h),n.Emitter=h):"function"==typeof t&&t.amd?t("emmett",[],function(){return h}):this.Emitter=h}).call(this)},{}],4:[function(t,e,r){function n(t){return t+"$"+(new Date).getTime()+(""+Math.random()).replace("0.","")}function o(t,e){function r(t){this[t]=function(){var e=this.root[t].apply(this.root,arguments);return e instanceof i?this:e}}if(arguments.length<1&&(t={}),!(this instanceof o))return new o(t,e);if(!p.Object(t)&&!p.Array(t))throw Error("Baobab: invalid data.");if(s.call(this),this.options=u.shallowMerge(f,e),this._transaction={},this._future=void 0,this._cursors={},this._identity="[object Baobab]",this.data=u.deepClone(t),this.root=this.select([]),this.facets={},["get","set","unset","update"].forEach(r.bind(this)),!p.Object(this.options.facets))throw Error("Baobab: invalid facets.");for(var n in this.options.facets)this.addFacet(n,this.options.facets[n])}var i=t("./cursor.js"),s=t("emmett"),a=t("./watcher.js"),h=t("./facet.js"),u=t("./helpers.js"),c=t("./update.js"),l=t("./merge.js"),f=t("../defaults.js"),p=t("./type.js");u.inherits(o,s),o.prototype.addFacet=function(t,e){return this.facets[t]=this.createFacet(e),this},o.prototype.createFacet=function(t){return new h(this,t)},o.prototype.select=function(t){if(!t)throw Error("Baobab.select: invalid path.");if(arguments.length>1&&(t=u.arrayOf(arguments)),!p.Path(t))throw Error("Baobab.select: invalid path.");t=[].concat(t);var e,r=p.ComplexPath(t);r&&(e=u.solvePath(this.data,t,this));var o=t.map(function(t){return p.Function(t)?n("fn"):p.Object(t)?n("ob"):t}).join("|λ|");if(this._cursors[o])return this._cursors[o];var s=new i(this,t,e,o);return this._cursors[o]=s,s},o.prototype.stack=function(t){var e=this;if(!p.Object(t))throw Error("Baobab.update: wrong specification.");return this._transaction=l(t,this._transaction),this.options.autoCommit?this.options.asynchronous?(this._future||(this._future=setTimeout(e.commit.bind(e,null),0)),this):this.commit():this},o.prototype.commit=function(){var t=c(this.data,this._transaction,this.options),e=this.data;this._transaction={},this._future&&(this._future=clearTimeout(this._future));var r=this.options.validate,n=this.options.validationBehaviour;if("function"==typeof r){var o=r.call(this,e,t.data,t.log);if(o instanceof Error&&(this.emit("invalid",{error:o}),"rollback"===n))return this}return this.data=t.data,this.emit("update",{log:t.log,previousState:e}),this},o.prototype.watch=function(t){if(!p.Array(t)||t.some(function(t){return!p.Path(t)}))throw Error("Baobab.watch: invalid paths.");return new a(this,[].concat(t))},o.prototype.release=function(){var t;delete this.data,delete this._transaction;for(t in this._cursors)this._cursors[t].release();delete this._cursors;for(t in this.facets)this.facets[t].release();delete this.facets,this.kill()},o.prototype.toJSON=function(){return this.get()},o.prototype.toString=function(){return this._identity},e.exports=o},{"../defaults.js":2,"./cursor.js":5,"./facet.js":6,"./helpers.js":7,"./merge.js":8,"./type.js":9,"./update.js":10,"./watcher.js":11,emmett:3}],5:[function(t,e,r){function n(t,e,r,n){function o(t){if(i.recording&&!i.undoing){var e=a.getIn(t,i.solvedPath,i.tree),r=a.deepClone(e);i.archive.add(r)}return i.undoing=!1,i.emit("update")}var i=this;s.call(this),e=e||[],this.tree=t,this.path=e,this.hash=n,this.archive=null,this.recording=!1,this.undoing=!1,this._identity="[object Cursor]",this.complexPath=!!r,this.solvedPath=this.complexPath?r:this.path,this.relevant=void 0!==this.get(),this.updateHandler=function(t){var e=t.data.log,r=t.data.previousState,n=!1;if(i.complexPath&&(i.solvedPath=a.solvePath(i.tree.data,i.path,i.tree)),!i.path.length)return o(r);i.solvedPath&&(n=a.solveUpdate(e,[i.solvedPath]));var s=void 0!==i.get();i.relevant?s&&n?o(r):s||(i.emit("irrelevant"),i.relevant=!1):s&&n&&(i.emit("relevant"),o(r),i.relevant=!0)};var h=!1;this._lazyBind=function(){h||(h=!0,i.tree.on("update",i.updateHandler))},this.on=a.before(this._lazyBind,this.on.bind(this)),this.once=a.before(this._lazyBind,this.once.bind(this)),this.complexPath&&this._lazyBind()}function o(t,e,r,n){if(arguments.length>5)throw Error("baobab.Cursor."+t+": too many arguments.");if(arguments.length<4&&(n=r,r=[]),r=r||[],"splice"===t&&!h.Splicer(n)){if(!h.Array(n))throw Error("baobab.Cursor.splice: incorrect value.");n=[n]}if(e&&!e(n))throw Error("baobab.Cursor."+t+": incorrect value.");var o=[].concat(r),i=a.solvePath(this.get(),o,this.tree);if(!i)throw Error("baobab.Cursor."+t+": could not solve dynamic path.");var s={};s["$"+t]=n;var u=a.pathObject(i,s);return u}function i(t,e){n.prototype[t]=function(){var r=o.bind(this,t,e).apply(this,arguments);return this.update(r)}}var s=t("emmett"),a=t("./helpers.js"),h=(t("../defaults.js"),t("./type.js"));a.inherits(n,s),n.prototype.isRoot=function(){return!this.path.length},n.prototype.isLeaf=function(){return h.Primitive(this.get())},n.prototype.isBranch=function(){return!this.isLeaf()&&!this.isRoot()},n.prototype.root=function(){return this.tree.root()},n.prototype.select=function(t){if(arguments.length>1&&(t=a.arrayOf(arguments)),!h.Path(t))throw Error("baobab.Cursor.select: invalid path.");return this.tree.select(this.path.concat(t))},n.prototype.up=function(){return this.solvedPath&&this.solvedPath.length?this.tree.select(this.path.slice(0,-1)):null},n.prototype.left=function(){var t=+this.solvedPath[this.solvedPath.length-1];if(isNaN(t))throw Error("baobab.Cursor.left: cannot go left on a non-list type.");return t?this.tree.select(this.solvedPath.slice(0,-1).concat(t-1)):null},n.prototype.leftmost=function(){var t=+this.solvedPath[this.solvedPath.length-1];if(isNaN(t))throw Error("baobab.Cursor.leftmost: cannot go left on a non-list type.");return this.tree.select(this.solvedPath.slice(0,-1).concat(0))},n.prototype.right=function(){var t=+this.solvedPath[this.solvedPath.length-1];if(isNaN(t))throw Error("baobab.Cursor.right: cannot go right on a non-list type.");return t+1===this.up().get().length?null:this.tree.select(this.solvedPath.slice(0,-1).concat(t+1))},n.prototype.rightmost=function(){var t=+this.solvedPath[this.solvedPath.length-1];if(isNaN(t))throw Error("baobab.Cursor.right: cannot go right on a non-list type.");var e=this.up().get();return this.tree.select(this.solvedPath.slice(0,-1).concat(e.length-1))},n.prototype.down=function(){+this.solvedPath[this.solvedPath.length-1];return this.get()instanceof Array?this.tree.select(this.solvedPath.concat(0)):null},n.prototype.get=function(t){arguments.length>1&&(t=a.arrayOf(arguments));var e=this.solvedPath.concat([].concat(t||0===t?t:[]));return a.getIn(this.tree.data,e,this.tree)},i("set"),i("apply",h.Function),i("chain",h.Function),i("push"),i("unshift"),i("merge",h.Object),i("splice"),n.prototype.unset=function(t){if(void 0===t&&this.isRoot())throw Error("baobab.Cursor.unset: cannot remove root node.");var e=o.bind(this,"unset",null).apply(this,[t,!0]);return this.update(e)},n.prototype.update=function(t,e){if(arguments.length<2)return this.tree.stack(a.pathObject(this.solvedPath,t)),this;var r=[].concat(t),n=a.solvePath(this.get(),r,this.tree);if(!n)throw Error("baobab.Cursor.update: could not solve dynamic path.");return this.tree.stack(a.pathObject(this.solvedPath.concat(n),e)),this},n.prototype.startRecording=function(t){if(t=t||5,1>t)throw Error("baobab.Cursor.startRecording: invalid maximum number of records.");return this.archive?this:(this._lazyBind(),this.archive=a.archive(t),this.recording=!0,this)},n.prototype.stopRecording=function(){return this.recording=!1,this},n.prototype.undo=function(t){if(t=t||1,!this.recording)throw Error("baobab.Cursor.undo: cursor is not recording.");if(!h.PositiveInteger(t))throw Error("baobab.Cursor.undo: expecting a positive integer.");var e=this.archive.back(t);if(!e)throw Error("boabab.Cursor.undo: cannot find a relevant record ("+t+" back).");return this.undoing=!0,this.set(e)},n.prototype.hasHistory=function(){return!(!this.archive||!this.archive.get().length)},n.prototype.getHistory=function(){return this.archive?this.archive.get():[]},n.prototype.clearHistory=function(){return this.archive=null,this},n.prototype.release=function(){this.tree.off("update",this.updateHandler),this.hash&&delete this.tree._cursors[this.hash],delete this.tree,delete this.path,delete this.solvedPath,delete this.archive,this.kill()},n.prototype.toJSON=function(){return this.get()},n.prototype.toString=function(){return this._identity},e.exports=n},{"../defaults.js":2,"./helpers.js":7,"./type.js":9,emmett:3}],6:[function(t,e,r){function n(t){return t}function o(t,e){function r(t){o[t]=l[t].bind(l)}var o=this,s=null,a=!1,h=e.get||n,u=e.cursors,c=Object.keys(u).map(function(t){return u[t]}),l=new i(t,c);["on","once","release"].forEach(r),this.get=function(){if(a)return s;var e={};for(var r in u)e[r]=t.get(u[r]);return s=h.call(null,e),a=!0,s},this.on("update",function(){a=!1})}{var i=t("./watcher.js");t("./helpers.js")}e.exports=o},{"./helpers.js":7,"./watcher.js":11}],7:[function(t,e,r){(function(r){function n(t){return Array.prototype.slice.call(t)}function o(t,e){return function(){t(),e.apply(null,arguments)}}function i(t,e,r){var o=n(arguments).slice(3);return e=+e,r=+r,t.slice(0,e).concat(t.slice(e+r).concat(o))}function s(t,e){var r,n={};for(r in t)n[r]=t[r];for(r in e)n[r]=e[r];return n}function a(t){var e=t.source,r="";return t.global&&(r+="g"),t.multiline&&(r+="m"),t.ignoreCase&&(r+="i"),t.sticky&&(r+="y"),t.unicode&&(r+="u"),new RegExp(e,r)}function h(t,e){if(!e||"object"!=typeof e||e instanceof Error||"ArrayBuffer"in r&&e instanceof ArrayBuffer)return e;if(_.Array(e)){if(t){var n,o,i=[];for(n=0,o=e.length;o>n;n++)i.push(P(e[n]));return i}return e.slice(0)}if(_.Date(e))return new Date(e.getTime());if(e instanceof RegExp)return a(e);if(_.Object(e)){var s,h={};e.constructor&&e.constructor!==Object&&(h=Object.create(e.constructor.prototype));for(s in e)e.hasOwnProperty(s)&&(h[s]=t?P(e[s]):e[s]);return h}return e}function u(t,e){return function(r){return e(t(r))}}function c(t,e){var r,n;for(r=0,n=t.length;n>r;r++)if(e(t[r]))return t[r]}function l(t,e){var r,n;for(r=0,n=t.length;n>r;r++)if(e(t[r]))return r;return-1}function f(t,e){var r,n=!0;if(!t)return!1;for(r in e)if(_.Object(e[r]))n=n&&f(t[r],e[r]);else if(_.Array(e[r]))n=n&&!!~e[r].indexOf(t[r]);else if(t[r]!==e[r])return!1;return n}function d(t,e){return c(t,function(t){return f(t,e)})}function y(t,e){return l(t,function(t){return f(t,e)})}function v(t,e,r){e=e||[];var n,o,i,s=t;for(o=0,i=e.length;i>o;o++){if(!s)return;if("function"==typeof e[o]){if(!_.Array(s))return;s=c(s,e[o])}else if("object"==typeof e[o])if(r&&"$cursor"in e[o]){if(!_.Path(e[o].$cursor))throw Error("baobab.getIn: $cursor path must be an array.");n=r.get(e[o].$cursor),s=s[n]}else{if(!_.Array(s))return;s=d(s,e[o])}else s=s[e[o]]}return s}function g(t,e,r){var n,o,i,s=[],a=t;for(o=0,i=e.length;i>o;o++){if(!a)return null;if("function"==typeof e[o]){if(!_.Array(a))return;n=l(a,e[o]),s.push(n),a=a[n]}else if("object"==typeof e[o])if(r&&"$cursor"in e[o]){if(!_.Path(e[o].$cursor))throw Error("baobab.getIn: $cursor path must be an array.");p=r.get(e[o].$cursor),s.push(p),a=a[p]}else{if(!_.Array(a))return;n=y(a,e[o]),s.push(n),a=a[n]}else s.push(e[o]),a=a[e[o]]||{}}return s}function b(t,e){var r,n,o,i,s,a,h,u,c;for(r=0,i=e.length;i>r;r++)for(h=e[r],n=0,s=t.length;s>n;n++)for(u=t[n],o=0,a=u.length;a>o&&(c=u[o],c==h[o]);o++)if(o+1===a||o+1===h.length)return!0;return!1}function m(t,e){var r,n=t.length,o={},i=o;for(n||(o=e),r=0;n>r;r++)i[t[r]]=r+1===n?e:{},i=i[t[r]];return o}function j(t,e){t.super_=e;var r=function(){};r.prototype=e.prototype,t.prototype=new r,t.prototype.constructor=t}function w(t){var e=[];return{add:function(r){e.unshift(r),e.length>t&&(e.length=t)},back:function(t){var r=e[t-1];return r&&(e=e.slice(t)),r},get:function(){return e}}}var _=t("./type.js"),$=h.bind(null,!1),P=h.bind(null,!0);e.exports={archive:w,arrayOf:n,before:o,deepClone:P,shallowClone:$,shallowMerge:s,compose:u,getIn:v,inherits:j,pathObject:m,solvePath:g,solveUpdate:b,splice:i}}).call(this,"undefined"!=typeof global?global:"undefined"!=typeof self?self:"undefined"!=typeof window?window:{})},{"./type.js":9}],8:[function(t,e,r){function n(t,e,r){a.forEach(function(e){r!==e&&delete t[e]}),t[r]=e[r]}function o(t,e){var r,h=i.shallowClone(e||{});a.forEach(function(e){t[e]&&n(h,t,e)}),t.$chain&&(a.slice(0,-1).forEach(function(t){delete h[t]}),h.$apply=h.$apply?i.compose(h.$apply,t.$chain):t.$chain),(t.$splice||h.$splice)&&(h.$splice=[].concat(h.$splice||[]).concat(t.$splice||[])),(t.$push||h.$push)&&(h.$push=[].concat(h.$push||[]).concat(t.$push||[])),(t.$unshift||h.$unshift)&&(h.$unshift=[].concat(t.$unshift||[]).concat(h.$unshift||[]));for(r in t)s.Object(t[r])?h[r]=o(t[r],h[r]):"$"!==r[0]&&(h[r]=t[r]);return h}var i=t("./helpers.js"),s=t("./type.js"),a=["$unset","$set","$merge","$apply"];e.exports=o},{"./helpers.js":7,"./type.js":9}],9:[function(t,e,r){function n(t,e){return e.some(function(e){return o[e](t)})}var o={};o.Array=function(t){return Array.isArray(t)},o.Object=function(t){return t&&"object"==typeof t&&!Array.isArray(t)&&!(t instanceof Function)},o.String=function(t){return"string"==typeof t},o.Number=function(t){return"number"==typeof t},o.PositiveInteger=function(t){return"number"==typeof t&&t>0&&t%1===0},o.Function=function(t){return"function"==typeof t},o.Primitive=function(t){return"string"==typeof t||"number"==typeof t||"boolean"==typeof t},o.Date=function(t){return t instanceof Date},o.NonScalar=function(t){return o.Object(t)||o.Array(t)},o.Splicer=function(t){return o.Array(t)&&t.every(o.Array)},o.Path=function(t){var e=["String","Number","Function","Object"];return o.Array(t)?t.every(function(t){return n(t,e)}):n(t,e)},o.MixinCursor=function(t){return n(t,["String","Number","Array","Function","Cursor"])},o.MixinCursors=function(t){return n(t,["Object","Array","Function"])},o.ComplexPath=function(t){return t.some(function(t){return n(t,["Object","Function"])})},e.exports=o},{}],10:[function(t,e,r){function n(t,e){var r=new Error("baobab.update: "+e+" at path /"+t.slice(1).join("/"));return r.path=t,r}var o=t("./helpers.js"),i=t("./type.js");e.exports=function(t,e,r){if(r=r||{},!i.Object(t)&&!i.Array(t))throw Error("baobab.update: invalid target.");var s={};t={root:o.shallowClone(t)};var a=function(t,e,r,h){r=r||["root"];var u,c,l,f=r.join("|λ|"),p=r[r.length-1],d=Object.keys(e).some(function(t){return!!~["$set","$push","$unshift","$splice","$unset","$merge","$apply"].indexOf(t)});if(d){s[f]=!0;for(c in e){if("$unset"===c){var y=r[r.length-2];if(!i.Object(h[y]))throw n(r.slice(0,-1),"using command $unset on a non-object");h[y]=o.shallowClone(t),delete h[y][p];break}if("$set"===c){l=e.$set,t[p]=l;break}if("$apply"===c){if(u=e.$apply,"function"!=typeof u)throw n(r,"using command $apply with a non function");t[p]=u.call(null,t[p]);break}if("$merge"===c){if(l=e.$merge,!i.Object(t[p])||!i.Object(l))throw n(r,"using command $merge with a non object");t[p]=o.shallowMerge(t[p],l);break}if("$splice"===c){if(l=e.$splice,!i.Array(t[p]))throw n(r,"using command $push to a non array");l.forEach(function(e){t[p]=o.splice.apply(null,[t[p]].concat(e))})}if("$push"===c){if(l=e.$push,!i.Array(t[p]))throw n(r,"using command $push to a non array");t[p]=t[p].concat(l)}if("$unshift"===c){if(l=e.$unshift,!i.Array(t[p]))throw n(r,"using command $unshift to a non array");t[p]=[].concat(l).concat(t[p])}}}else for(c in e)t[p][c]="undefined"==typeof t[p][c]?{}:o.shallowClone(t[p][c]),a(t[p],e[c],r.concat(c),t)};return a(t,e),{data:t.root,log:Object.keys(s).map(function(t){return t.split("|λ|").slice(1)})}}},{"./helpers.js":7,"./type.js":9}],11:[function(t,e,r){function n(t,e){function r(){h&&(a=e.map(function(t){return i.solvePath(n.tree.data,t,n.tree)}))}var n=this;o.call(this),this.tree=t;var a=e,h=e.some(s.ComplexPath);this.updateHandler=function(t){var e=i.solveUpdate(t.data.log,a);e&&n.emit("update")},r(),this.tree.on("update",this.updateHandler)}var o=t("emmett"),i=t("./helpers.js"),s=t("./type.js");i.inherits(n,o),n.prototype.release=function(){this.tree.off("update",this.updateHandler),this.tree=null,this.kill()},e.exports=n},{"./helpers.js":7,"./type.js":9,emmett:3}]},{},[1])(1)}); \ No newline at end of file +!function(t){if("object"==typeof exports&&"undefined"!=typeof module)module.exports=t();else if("function"==typeof define&&define.amd)define([],t);else{var e;e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:this,e.Baobab=t()}}(function(){var t;return function e(t,r,n){function o(s,a){if(!r[s]){if(!t[s]){var h="function"==typeof require&&require;if(!a&&h)return h(s,!0);if(i)return i(s,!0);var u=new Error("Cannot find module '"+s+"'");throw u.code="MODULE_NOT_FOUND",u}var c=r[s]={exports:{}};t[s][0].call(c.exports,function(e){var r=t[s][1][e];return o(r?r:e)},c,c.exports,e,t,r,n)}return r[s].exports}for(var i="function"==typeof require&&require,s=0;sn;n++)t[n].fn!==e&&o.push(t[n]);return o}var s={once:"boolean",scope:"object"},a=0,h=function(){this._enabled=!0,this.unbindAll()};h.prototype.unbindAll=function(){return this._handlers={},this._handlersAll=[],this._handlersComplex=[],this},h.prototype.on=function(t,e,r){var n,i,h,u,c,l,f;if(o(t)){for(u in t)this.on(u,t[u],e);return this}for("function"==typeof t&&(r=e,e=t,t=null),c=[].concat(t),n=0,i=c.length;i>n;n++){if(u=c[n],f={order:a++,fn:e},"string"==typeof u)this._handlers[u]||(this._handlers[u]=[]),l=this._handlers[u];else if(u instanceof RegExp)l=this._handlersComplex,f.pattern=u;else{if(null!==u)throw Error("Emitter.on: invalid event.");l=this._handlersAll}for(h in r||{})s[h]&&(f[h]=r[h]);f.once&&(f.parent=l),l.push(f)}return this},h.prototype.once=function(){var t=Array.prototype.slice.call(arguments),r=t.length-1;return o(t[r])&&t.length>1?t[r]=e(t[r],{once:!0}):t.push({once:!0}),this.on.apply(this,t)},h.prototype.off=function(t,e){var r,n,s,a;if(1===arguments.length&&"function"==typeof t){e=arguments[0];for(s in this._handlers)this._handlers[s]=i(this._handlers[s],e),0===this._handlers[s].length&&delete this._handlers[s];this._handlersAll=i(this._handlersAll,e),this._handlersComplex=i(this._handlersComplex,e)}else if(1===arguments.length&&"string"==typeof t)delete this._handlers[t];else if(2===arguments.length){var h=[].concat(t);for(r=0,n=h.length;n>r;r++)a=h[r],this._handlers[a]=i(this._handlers[a],e),0===(this._handlers[a]||[]).length&&delete this._handlers[a]}else if(o(t))for(s in t)this.off(s,t[s]);return this},h.prototype.listeners=function(t){var e,r,n,o=this._handlersAll||[],i=!1;if(!t)throw Error("Emitter.listeners: no event provided.");for(o=o.concat(this._handlers[t]||[]),r=0,n=this._handlersComplex.length;n>r;r++)e=this._handlersComplex[r],~t.search(e.pattern)&&(i=!0,o.push(e));return this._handlersAll.length||i?o.sort(function(t,e){return t.order-e.order}):o.slice(0)},h.prototype.emit=function(t,e){if(!this._enabled)return this;if(o(t)){for(var r in t)this.emit(r,t[r]);return this}var n,i,s,a,h,u,c,l=[].concat(t),f=[];for(a=0,u=l.length;u>a;a++){for(i=this.listeners(l[a]),h=0,c=i.length;c>h;h++)s=i[h],n={type:l[a],target:this},arguments.length>1&&(n.data=e),s.fn.call("scope"in s?s.scope:this,n),s.once&&f.push(s);for(h=f.length-1;h>=0;h--)f[h].parent.splice(f[h].parent.indexOf(f[h]),1)}return this},h.prototype.kill=function(){this.unbindAll(),this._handlers=null,this._handlersAll=null,this._handlersComplex=null,this._enabled=!1},h.prototype.disable=function(){return this._enabled=!1,this},h.prototype.enable=function(){return this._enabled=!0,this},h.version="3.0.0","undefined"!=typeof n?("undefined"!=typeof r&&r.exports&&(n=r.exports=h),n.Emitter=h):"function"==typeof t&&t.amd?t("emmett",[],function(){return h}):this.Emitter=h}).call(this)},{}],4:[function(t,e,r){function n(t){return t+"$"+(new Date).getTime()+(""+Math.random()).replace("0.","")}function o(t,e){function r(t){this[t]=function(){var e=this.root[t].apply(this.root,arguments);return e instanceof i?this:e}}if(arguments.length<1&&(t={}),!(this instanceof o))return new o(t,e);if(!p.Object(t)&&!p.Array(t))throw Error("Baobab: invalid data.");if(s.call(this),this.options=u.shallowMerge(f,e),this._transaction={},this._future=void 0,this._cursors={},this._identity="[object Baobab]",this.data=u.deepClone(t),this.root=this.select([]),this.facets={},["get","set","unset","update"].forEach(r.bind(this)),!p.Object(this.options.facets))throw Error("Baobab: invalid facets.");for(var n in this.options.facets)this.addFacet(n,this.options.facets[n])}var i=t("./cursor.js"),s=t("emmett"),a=t("./watcher.js"),h=t("./facet.js"),u=t("./helpers.js"),c=t("./update.js"),l=t("./merge.js"),f=t("../defaults.js"),p=t("./type.js");u.inherits(o,s),o.prototype.addFacet=function(t,e){return this.facets[t]=this.createFacet(e),this},o.prototype.createFacet=function(t){return new h(this,t)},o.prototype.select=function(t){if(!t)throw Error("Baobab.select: invalid path.");if(arguments.length>1&&(t=u.arrayOf(arguments)),!p.Path(t))throw Error("Baobab.select: invalid path.");t=[].concat(t);var e,r=p.ComplexPath(t);r&&(e=u.solvePath(this.data,t,this));var o=t.map(function(t){return p.Function(t)?n("fn"):p.Object(t)?n("ob"):t}).join("|λ|");if(this._cursors[o])return this._cursors[o];var s=new i(this,t,e,o);return this._cursors[o]=s,s},o.prototype.stack=function(t){var e=this;if(!p.Object(t))throw Error("Baobab.update: wrong specification.");return this._transaction=l(t,this._transaction),this.options.autoCommit?this.options.asynchronous?(this._future||(this._future=setTimeout(e.commit.bind(e,null),0)),this):this.commit():this},o.prototype.commit=function(){var t=c(this.data,this._transaction,this.options),e=this.data;this._transaction={},this._future&&(this._future=clearTimeout(this._future));var r=this.options.validate,n=this.options.validationBehavior;if("function"==typeof r){var o=r.call(this,e,t.data,t.log);if(o instanceof Error&&(this.emit("invalid",{error:o}),"rollback"===n))return this}return this.data=t.data,this.emit("update",{log:t.log,previousState:e}),this},o.prototype.watch=function(t){if(!p.Array(t)||t.some(function(t){return!p.Path(t)}))throw Error("Baobab.watch: invalid paths.");return new a(this,[].concat(t))},o.prototype.release=function(){var t;delete this.data,delete this._transaction;for(t in this._cursors)this._cursors[t].release();delete this._cursors;for(t in this.facets)this.facets[t].release();delete this.facets,this.kill()},o.prototype.toJSON=function(){return this.get()},o.prototype.toString=function(){return this._identity},e.exports=o},{"../defaults.js":2,"./cursor.js":5,"./facet.js":6,"./helpers.js":7,"./merge.js":8,"./type.js":9,"./update.js":10,"./watcher.js":11,emmett:3}],5:[function(t,e,r){function n(t,e,r,n){function o(t){if(i.recording&&!i.undoing){var e=a.getIn(t,i.solvedPath,i.tree),r=a.deepClone(e);i.archive.add(r)}return i.undoing=!1,i.emit("update")}var i=this;s.call(this),e=e||[],this.tree=t,this.path=e,this.hash=n,this.archive=null,this.recording=!1,this.undoing=!1,this._identity="[object Cursor]",this.complexPath=!!r,this.solvedPath=this.complexPath?r:this.path,this.relevant=void 0!==this.get(),this.updateHandler=function(t){var e=t.data.log,r=t.data.previousState,n=!1;if(i.complexPath&&(i.solvedPath=a.solvePath(i.tree.data,i.path,i.tree)),!i.path.length)return o(r);i.solvedPath&&(n=a.solveUpdate(e,[i.solvedPath]));var s=void 0!==i.get();i.relevant?s&&n?o(r):s||(i.emit("irrelevant"),i.relevant=!1):s&&n&&(i.emit("relevant"),o(r),i.relevant=!0)};var h=!1;this._lazyBind=function(){h||(h=!0,i.tree.on("update",i.updateHandler))},this.on=a.before(this._lazyBind,this.on.bind(this)),this.once=a.before(this._lazyBind,this.once.bind(this)),this.complexPath&&this._lazyBind()}function o(t,e,r,n){if(arguments.length>5)throw Error("baobab.Cursor."+t+": too many arguments.");if(arguments.length<4&&(n=r,r=[]),r=r||[],"splice"===t&&!h.Splicer(n)){if(!h.Array(n))throw Error("baobab.Cursor.splice: incorrect value.");n=[n]}if(e&&!e(n))throw Error("baobab.Cursor."+t+": incorrect value.");var o=[].concat(r),i=a.solvePath(this.get(),o,this.tree);if(!i)throw Error("baobab.Cursor."+t+": could not solve dynamic path.");var s={};s["$"+t]=n;var u=a.pathObject(i,s);return u}function i(t,e){n.prototype[t]=function(){var r=o.bind(this,t,e).apply(this,arguments);return this.update(r)}}var s=t("emmett"),a=t("./helpers.js"),h=(t("../defaults.js"),t("./type.js"));a.inherits(n,s),n.prototype.isRoot=function(){return!this.path.length},n.prototype.isLeaf=function(){return h.Primitive(this.get())},n.prototype.isBranch=function(){return!this.isLeaf()&&!this.isRoot()},n.prototype.root=function(){return this.tree.root()},n.prototype.select=function(t){if(arguments.length>1&&(t=a.arrayOf(arguments)),!h.Path(t))throw Error("baobab.Cursor.select: invalid path.");return this.tree.select(this.path.concat(t))},n.prototype.up=function(){return this.solvedPath&&this.solvedPath.length?this.tree.select(this.path.slice(0,-1)):null},n.prototype.left=function(){var t=+this.solvedPath[this.solvedPath.length-1];if(isNaN(t))throw Error("baobab.Cursor.left: cannot go left on a non-list type.");return t?this.tree.select(this.solvedPath.slice(0,-1).concat(t-1)):null},n.prototype.leftmost=function(){var t=+this.solvedPath[this.solvedPath.length-1];if(isNaN(t))throw Error("baobab.Cursor.leftmost: cannot go left on a non-list type.");return this.tree.select(this.solvedPath.slice(0,-1).concat(0))},n.prototype.right=function(){var t=+this.solvedPath[this.solvedPath.length-1];if(isNaN(t))throw Error("baobab.Cursor.right: cannot go right on a non-list type.");return t+1===this.up().get().length?null:this.tree.select(this.solvedPath.slice(0,-1).concat(t+1))},n.prototype.rightmost=function(){var t=+this.solvedPath[this.solvedPath.length-1];if(isNaN(t))throw Error("baobab.Cursor.right: cannot go right on a non-list type.");var e=this.up().get();return this.tree.select(this.solvedPath.slice(0,-1).concat(e.length-1))},n.prototype.down=function(){+this.solvedPath[this.solvedPath.length-1];return this.get()instanceof Array?this.tree.select(this.solvedPath.concat(0)):null},n.prototype.get=function(t){arguments.length>1&&(t=a.arrayOf(arguments));var e=this.solvedPath.concat([].concat(t||0===t?t:[]));return a.getIn(this.tree.data,e,this.tree)},i("set"),i("apply",h.Function),i("chain",h.Function),i("push"),i("unshift"),i("merge",h.Object),i("splice"),n.prototype.unset=function(t){if(void 0===t&&this.isRoot())throw Error("baobab.Cursor.unset: cannot remove root node.");var e=o.bind(this,"unset",null).apply(this,[t,!0]);return this.update(e)},n.prototype.update=function(t,e){if(arguments.length<2)return this.tree.stack(a.pathObject(this.solvedPath,t)),this;var r=[].concat(t),n=a.solvePath(this.get(),r,this.tree);if(!n)throw Error("baobab.Cursor.update: could not solve dynamic path.");return this.tree.stack(a.pathObject(this.solvedPath.concat(n),e)),this},n.prototype.startRecording=function(t){if(t=t||5,1>t)throw Error("baobab.Cursor.startRecording: invalid maximum number of records.");return this.archive?this:(this._lazyBind(),this.archive=a.archive(t),this.recording=!0,this)},n.prototype.stopRecording=function(){return this.recording=!1,this},n.prototype.undo=function(t){if(t=t||1,!this.recording)throw Error("baobab.Cursor.undo: cursor is not recording.");if(!h.PositiveInteger(t))throw Error("baobab.Cursor.undo: expecting a positive integer.");var e=this.archive.back(t);if(!e)throw Error("boabab.Cursor.undo: cannot find a relevant record ("+t+" back).");return this.undoing=!0,this.set(e)},n.prototype.hasHistory=function(){return!(!this.archive||!this.archive.get().length)},n.prototype.getHistory=function(){return this.archive?this.archive.get():[]},n.prototype.clearHistory=function(){return this.archive=null,this},n.prototype.release=function(){this.tree.off("update",this.updateHandler),this.hash&&delete this.tree._cursors[this.hash],delete this.tree,delete this.path,delete this.solvedPath,delete this.archive,this.kill()},n.prototype.toJSON=function(){return this.get()},n.prototype.toString=function(){return this._identity},e.exports=n},{"../defaults.js":2,"./helpers.js":7,"./type.js":9,emmett:3}],6:[function(t,e,r){function n(t){return t}function o(t,e){function r(t){o[t]=l[t].bind(l)}var o=this,s=null,a=!1,h=e.get||n,u=e.cursors,c=Object.keys(u).map(function(t){return u[t]}),l=new i(t,c);["on","once","release"].forEach(r),this.get=function(){if(a)return s;var e={};for(var r in u)e[r]=t.get(u[r]);return s=h.call(null,e),a=!0,s},this.on("update",function(){a=!1})}{var i=t("./watcher.js");t("./helpers.js")}e.exports=o},{"./helpers.js":7,"./watcher.js":11}],7:[function(t,e,r){(function(r){function n(t){return Array.prototype.slice.call(t)}function o(t,e){return function(){t(),e.apply(null,arguments)}}function i(t,e,r){var o=n(arguments).slice(3);return e=+e,r=+r,t.slice(0,e).concat(t.slice(e+r).concat(o))}function s(t,e){var r,n={};for(r in t)n[r]=t[r];for(r in e)n[r]=e[r];return n}function a(t){var e=t.source,r="";return t.global&&(r+="g"),t.multiline&&(r+="m"),t.ignoreCase&&(r+="i"),t.sticky&&(r+="y"),t.unicode&&(r+="u"),new RegExp(e,r)}function h(t,e){if(!e||"object"!=typeof e||e instanceof Error||"ArrayBuffer"in r&&e instanceof ArrayBuffer)return e;if(_.Array(e)){if(t){var n,o,i=[];for(n=0,o=e.length;o>n;n++)i.push(P(e[n]));return i}return e.slice(0)}if(_.Date(e))return new Date(e.getTime());if(e instanceof RegExp)return a(e);if(_.Object(e)){var s,h={};e.constructor&&e.constructor!==Object&&(h=Object.create(e.constructor.prototype));for(s in e)e.hasOwnProperty(s)&&(h[s]=t?P(e[s]):e[s]);return h}return e}function u(t,e){return function(r){return e(t(r))}}function c(t,e){var r,n;for(r=0,n=t.length;n>r;r++)if(e(t[r]))return t[r]}function l(t,e){var r,n;for(r=0,n=t.length;n>r;r++)if(e(t[r]))return r;return-1}function f(t,e){var r,n=!0;if(!t)return!1;for(r in e)if(_.Object(e[r]))n=n&&f(t[r],e[r]);else if(_.Array(e[r]))n=n&&!!~e[r].indexOf(t[r]);else if(t[r]!==e[r])return!1;return n}function d(t,e){return c(t,function(t){return f(t,e)})}function y(t,e){return l(t,function(t){return f(t,e)})}function v(t,e,r){e=e||[];var n,o,i,s=t;for(o=0,i=e.length;i>o;o++){if(!s)return;if("function"==typeof e[o]){if(!_.Array(s))return;s=c(s,e[o])}else if("object"==typeof e[o])if(r&&"$cursor"in e[o]){if(!_.Path(e[o].$cursor))throw Error("baobab.getIn: $cursor path must be an array.");n=r.get(e[o].$cursor),s=s[n]}else{if(!_.Array(s))return;s=d(s,e[o])}else s=s[e[o]]}return s}function g(t,e,r){var n,o,i,s=[],a=t;for(o=0,i=e.length;i>o;o++){if(!a)return null;if("function"==typeof e[o]){if(!_.Array(a))return;n=l(a,e[o]),s.push(n),a=a[n]}else if("object"==typeof e[o])if(r&&"$cursor"in e[o]){if(!_.Path(e[o].$cursor))throw Error("baobab.getIn: $cursor path must be an array.");p=r.get(e[o].$cursor),s.push(p),a=a[p]}else{if(!_.Array(a))return;n=y(a,e[o]),s.push(n),a=a[n]}else s.push(e[o]),a=a[e[o]]||{}}return s}function b(t,e){var r,n,o,i,s,a,h,u,c;for(r=0,i=e.length;i>r;r++)for(h=e[r],n=0,s=t.length;s>n;n++)for(u=t[n],o=0,a=u.length;a>o&&(c=u[o],c==h[o]);o++)if(o+1===a||o+1===h.length)return!0;return!1}function m(t,e){var r,n=t.length,o={},i=o;for(n||(o=e),r=0;n>r;r++)i[t[r]]=r+1===n?e:{},i=i[t[r]];return o}function j(t,e){t.super_=e;var r=function(){};r.prototype=e.prototype,t.prototype=new r,t.prototype.constructor=t}function w(t){var e=[];return{add:function(r){e.unshift(r),e.length>t&&(e.length=t)},back:function(t){var r=e[t-1];return r&&(e=e.slice(t)),r},get:function(){return e}}}var _=t("./type.js"),$=h.bind(null,!1),P=h.bind(null,!0);e.exports={archive:w,arrayOf:n,before:o,deepClone:P,shallowClone:$,shallowMerge:s,compose:u,getIn:v,inherits:j,pathObject:m,solvePath:g,solveUpdate:b,splice:i}}).call(this,"undefined"!=typeof global?global:"undefined"!=typeof self?self:"undefined"!=typeof window?window:{})},{"./type.js":9}],8:[function(t,e,r){function n(t,e,r){a.forEach(function(e){r!==e&&delete t[e]}),t[r]=e[r]}function o(t,e){var r,h=i.shallowClone(e||{});a.forEach(function(e){t[e]&&n(h,t,e)}),t.$chain&&(a.slice(0,-1).forEach(function(t){delete h[t]}),h.$apply=h.$apply?i.compose(h.$apply,t.$chain):t.$chain),(t.$splice||h.$splice)&&(h.$splice=[].concat(h.$splice||[]).concat(t.$splice||[])),(t.$push||h.$push)&&(h.$push=[].concat(h.$push||[]).concat(t.$push||[])),(t.$unshift||h.$unshift)&&(h.$unshift=[].concat(t.$unshift||[]).concat(h.$unshift||[]));for(r in t)s.Object(t[r])?h[r]=o(t[r],h[r]):"$"!==r[0]&&(h[r]=t[r]);return h}var i=t("./helpers.js"),s=t("./type.js"),a=["$unset","$set","$merge","$apply"];e.exports=o},{"./helpers.js":7,"./type.js":9}],9:[function(t,e,r){function n(t,e){return e.some(function(e){return o[e](t)})}var o={};o.Array=function(t){return Array.isArray(t)},o.Object=function(t){return t&&"object"==typeof t&&!Array.isArray(t)&&!(t instanceof Function)},o.String=function(t){return"string"==typeof t},o.Number=function(t){return"number"==typeof t},o.PositiveInteger=function(t){return"number"==typeof t&&t>0&&t%1===0},o.Function=function(t){return"function"==typeof t},o.Primitive=function(t){return"string"==typeof t||"number"==typeof t||"boolean"==typeof t},o.Date=function(t){return t instanceof Date},o.NonScalar=function(t){return o.Object(t)||o.Array(t)},o.Splicer=function(t){return o.Array(t)&&t.every(o.Array)},o.Path=function(t){var e=["String","Number","Function","Object"];return o.Array(t)?t.every(function(t){return n(t,e)}):n(t,e)},o.MixinCursor=function(t){return n(t,["String","Number","Array","Function","Cursor"])},o.MixinCursors=function(t){return n(t,["Object","Array","Function"])},o.ComplexPath=function(t){return t.some(function(t){return n(t,["Object","Function"])})},e.exports=o},{}],10:[function(t,e,r){function n(t,e){var r=new Error("baobab.update: "+e+" at path /"+t.slice(1).join("/"));return r.path=t,r}var o=t("./helpers.js"),i=t("./type.js");e.exports=function(t,e,r){if(r=r||{},!i.Object(t)&&!i.Array(t))throw Error("baobab.update: invalid target.");var s={};t={root:o.shallowClone(t)};var a=function(t,e,r,h){r=r||["root"];var u,c,l,f=r.join("|λ|"),p=r[r.length-1],d=Object.keys(e).some(function(t){return!!~["$set","$push","$unshift","$splice","$unset","$merge","$apply"].indexOf(t)});if(d){s[f]=!0;for(c in e){if("$unset"===c){var y=r[r.length-2];if(!i.Object(h[y]))throw n(r.slice(0,-1),"using command $unset on a non-object");h[y]=o.shallowClone(t),delete h[y][p];break}if("$set"===c){l=e.$set,t[p]=l;break}if("$apply"===c){if(u=e.$apply,"function"!=typeof u)throw n(r,"using command $apply with a non function");t[p]=u.call(null,t[p]);break}if("$merge"===c){if(l=e.$merge,!i.Object(t[p])||!i.Object(l))throw n(r,"using command $merge with a non object");t[p]=o.shallowMerge(t[p],l);break}if("$splice"===c){if(l=e.$splice,!i.Array(t[p]))throw n(r,"using command $push to a non array");l.forEach(function(e){t[p]=o.splice.apply(null,[t[p]].concat(e))})}if("$push"===c){if(l=e.$push,!i.Array(t[p]))throw n(r,"using command $push to a non array");t[p]=t[p].concat(l)}if("$unshift"===c){if(l=e.$unshift,!i.Array(t[p]))throw n(r,"using command $unshift to a non array");t[p]=[].concat(l).concat(t[p])}}}else for(c in e)t[p][c]="undefined"==typeof t[p][c]?{}:o.shallowClone(t[p][c]),a(t[p],e[c],r.concat(c),t)};return a(t,e),{data:t.root,log:Object.keys(s).map(function(t){return t.split("|λ|").slice(1)})}}},{"./helpers.js":7,"./type.js":9}],11:[function(t,e,r){function n(t,e){function r(){h&&(a=e.map(function(t){return i.solvePath(n.tree.data,t,n.tree)}))}var n=this;o.call(this),this.tree=t;var a=e,h=e.some(s.ComplexPath);this.updateHandler=function(t){var e=i.solveUpdate(t.data.log,a);e&&n.emit("update")},r(),this.tree.on("update",this.updateHandler)}var o=t("emmett"),i=t("./helpers.js"),s=t("./type.js");i.inherits(n,o),n.prototype.release=function(){this.tree.off("update",this.updateHandler),this.tree=null,this.kill()},e.exports=n},{"./helpers.js":7,"./type.js":9,emmett:3}]},{},[1])(1)}); \ No newline at end of file diff --git a/defaults.js b/defaults.js index 703cd0b..08a8454 100644 --- a/defaults.js +++ b/defaults.js @@ -18,5 +18,5 @@ module.exports = { validate: null, // Validation behaviour 'rollback' or 'notify' - validationBehaviour: 'rollback' + validationBehavior: 'rollback' }; diff --git a/src/baobab.js b/src/baobab.js index cd12f76..e3d4cdc 100644 --- a/src/baobab.js +++ b/src/baobab.js @@ -162,7 +162,7 @@ Baobab.prototype.commit = function() { // Validate? var validate = this.options.validate, - behaviour = this.options.validationBehaviour; + behavior = this.options.validationBehavior; if (typeof validate === 'function') { var error = validate.call(this, oldData, result.data, result.log); @@ -170,7 +170,7 @@ Baobab.prototype.commit = function() { if (error instanceof Error) { this.emit('invalid', {error: error}); - if (behaviour === 'rollback') + if (behavior === 'rollback') return this; } } diff --git a/test/suites/baobab.js b/test/suites/baobab.js index af5bb30..6b0d028 100644 --- a/test/suites/baobab.js +++ b/test/suites/baobab.js @@ -332,7 +332,7 @@ describe('Baobab API', function() { return new Error('Invalid tree!'); } - var baobab = new Baobab({hello: 'world'}, {validate: v, asynchronous: false, validationBehaviour: 'notify'}); + var baobab = new Baobab({hello: 'world'}, {validate: v, asynchronous: false, validationBehavior: 'notify'}); baobab.on('invalid', function(e) { var error = e.data.error; From a29522cd76cd52d30de273726ab11f99fb689eb0 Mon Sep 17 00:00:00 2001 From: Yomguithereal Date: Thu, 16 Apr 2015 17:52:54 +0200 Subject: [PATCH 63/73] Starting v1 docs --- CHANGELOG.md | 90 ++++++++++++ README.md | 376 +++++++++++++++++++++------------------------------ 2 files changed, 245 insertions(+), 221 deletions(-) create mode 100644 CHANGELOG.md diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 0000000..25ff960 --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,90 @@ +# Changelog + +## v1.0.0 + +* Dropping `cursor.edit` and `cursor.remove` in favor of `cursor.set` and `cursor.unset` polymorphisms. +* Dropping `typology` dependency. +* Dropping options: `clone`, `cloningFunction`, `singletonCursors`, `shiftReferences`, `maxHistory`, `mixins` and `typology`. +* Updated `emmett` to `v3.0.0`. +* Moving react integration to [baobab-react](https://github.com/Yomguithereal/baobab-react). +* Shifting references is now default. +* Adding facets. +* Adding `$splice` keyword and `cursor.splice`. +* Adding `validationBehavior` option. +* Adding `$cursor` paths. +* Adding path polymorphisms to every cursor's setters. +* Reworking history to work at cursor level. +* Reworking validation process. +* Fixing some bugs. + +## v0.4.4 + +* Fixing `cursor.root`. +* Fixing `cursor.release`. +* Fixing build procedure for latest `node` and `browserify` versions. +* I9 support. + +## v0.4.3 + +* Adding React mixins function polymorphisms thanks to **@denisw**. +* Fixing `cursor.chain` thanks to **@jonypawks**. +* Fixing transaction flow issues thanks to **@jmisterka**. + +## v0.4.2 + +* Fixing deep object comparison and dynamic paths matching thanks to **@angus-c**. + +## v0.4.1 + +* Safer cursor update methods. +* Fixing `cursor.chain`. +* Fixing unset behavior when acting on lists. +* Fixing release methods. +* Path polymorphism for `tree/cursor.set`. +* Adding `tree/cursor.root` method. +* Reducing leak risks by making cursors and combinations lazier. + +## v0.4.0 + +* Several webpack-friendly changes. +* Fixing complex paths solving. +* Better `release` methods. +* Tree instantiation minimal polymorphism. +* Shooting gremlins in the head. +* Better internals. +* Implementing the `unset` and `remove` methods. + +## v0.3.2 + +* Bug fixes thanks to **@jacomyal**, **@jondot**. +* Better perfs thanks to **@christianalfoni**. +* `release` method for the tree. + +## v0.3.1 + +* Fixing reference shifting behaviours. +* `release` method for cursors. + +## v0.3.0 + +* Exposing `getIn` helper. +* Merged mixins are now executed after baobab's ones. +* Cursor combinations. +* Cursor data now available through component's state. +* Retrieval and selection sugar with functions and descriptive objects. +* Adding `referenceShifting` option. +* Cursor predicates. +* `$merge` command. +* Various optimizations and bug fixes. + +## v0.2.2 + +* Updating dependencies. +* Fixing several bugs. +* Better unit testing for mixins. +* `mixins` settings. +* Bower support. + +## v0.2.1 + +* Several bug fixes. diff --git a/README.md b/README.md index 69ae637..16d200f 100644 --- a/README.md +++ b/README.md @@ -6,9 +6,11 @@ It is mainly inspired by functional [zippers](http://clojuredocs.org/clojure.zip/zipper) such as Clojure's ones and by [Om](https://github.com/swannodette/om)'s cursors. -It can be paired with **React** easily through [mixins](#react-mixins) to provide a centralized model holding your application's state. +It can be paired with **React** painlessly through mixins or higher order components (available [here](https://github.com/Yomguithereal/baobab-react)) and provide a centralized model holding your application's state. -For a concise introduction about the library and how it can be used by a React/Flux application, you can head toward **@christianalfoni**'s [article](http://christianalfoni.github.io/javascript/2015/02/06/plant-a-baobab-tree-in-your-flux-application.html) on the subject. +For a concise introduction about the library and how it can be used in a React/Flux application, you can head toward **@christianalfoni**'s [article](http://christianalfoni.github.io/javascript/2015/02/06/plant-a-baobab-tree-in-your-flux-application.html) on the subject. + +**Trivia**: A [Baobab](http://en.wikipedia.org/wiki/Adansonia_digitata), or *Adansonia digitata*, is a very big and magnificient African tree. ## Summary @@ -20,17 +22,17 @@ For a concise introduction about the library and how it can be used by a React/F * [Cursors](#cursors) * [Updates](#updates) * [Events](#events) - * [React mixins](#react-mixins) * [Advanced](#advanced) * [Polymorphisms](#polymorphisms) * [Traversal](#traversal) * [Options](#options) + * [Facets](#facets) * [History](#history) * [Update specifications](#update-specifications) * [Chaining mutations](#chaining-mutations) - * [Cursor combinations](#cursor-combinations) - * [Data validation](#data-validation) * [Common pitfalls](#common-pitfalls) +* [Philosophy](#philosophy) +* [Migration](#migration) * [Contribution](#contribution) * [License](#license) @@ -57,12 +59,12 @@ colorsCursor.push('orange'); ## Installation -If you want to use **Baobab** with node.js or browserify, you can use npm. +If you want to use **Baobab** with node.js/io.js or browserify/webpack etc., you can use npm. ```sh npm install baobab -# Or for the latest dev version +# Or if you need the latest dev version npm install git+https://github.com/Yomguithereal/baobab.git ``` @@ -78,13 +80,15 @@ Or install with bower: bower install baobab ``` +The library (as a standalone) currently weights ~20ko minified and ~6ko gzipped. + ## Usage ### Basics #### Instantiation -Creating a *baobab* is as simple as instantiating it with an initial data set (note that only objects or array should be given). +Creating a tree is as simple as instantiating *Baobab* with an initial data set. ```js var Baobab = require('baobab'); @@ -136,6 +140,20 @@ Rather, the tree will stack and merge every update order you give it and will on This enables the tree to perform efficient mutations and to be able to notify any relevant cursors that the data they are watching over has changed. +Note also that the tree will shift the references of the objects it watches over in order to enable "immutabley" comparisons between one version of the state and another (this is especially useful when using things as such as React's pure render [mixin](https://facebook.github.io/react/docs/pure-render-mixin.html)). + +*Example* + +```js +var tree = new Baobab({hello: 'world'}); + +var initialState = tree.get(); +tree.set('hello', 'monde'}); + +// After asynchronous update... +assert(initialState !== tree.get()); +``` + ##### Tree level *Setting a key* @@ -155,64 +173,137 @@ tree.unset('hello'); *Replacing data at cursor* ```js -cursor.edit({hello: 'world'}); +cursor.set({hello: 'world'}); ``` *Setting a key* ```js cursor.set('hello', 'world'); + +// Nested path +cursor.set(['one', 'two'], 'world'); ``` *Removing data at cursor* ```js -cursor.remove(); +cursor.unset(); ``` *Unsetting a key* ```js cursor.unset('hello'); + +// Nested path +cursor.unset(['one', 'two']); ``` *Pushing values* -Obviously this will fail if target data is not an array. +Obviously this will fail if the value watched over by your cursor is not an array. ```js cursor.push('purple'); + +// Pushing several values cursor.push(['purple', 'orange']); + +// At key +cursor.push('list', 'orange') + +// Nested path +cursor.push(['one', 'two'], 'orange'); ``` *Unshifting values* -Obviously this will fail if target data is not an array. +Obviously this will fail if the value watched over by your cursor is not an array. ```js cursor.unshift('purple'); + +// Unshifting several values cursor.unshift(['purple', 'orange']); + +// At key +cursor.unshift('list', 'orange') + +// Nested path +cursor.unshift(['one', 'two'], 'orange'); +``` + +*Splicing an array* + +Obviously this will fail if the value watched over by your cursor is not an array. + +```js +cursor.splice([1, 1]); + +// Applying splice n times with different arguments +cursor.splice([[1, 2], [3, 2, 'hello']]); + +// At key +cursor.splice('list', [1, 1]) + +// Nested path +cursor.splice(['one', 'two'], [1, 1]); ``` *Applying a function* ```js -cursor.apply(function(currentData) { +var inc = function(currentData) { return currentData + 1; -}); +}; + +cursor.apply(inc); + +// At key +cursor.apply('number', inc) + +// Nested path +cursor.apply(['one', 'two'], 'orange'); +``` + +*Chaining functions through composition* + +For more details about this particular point, check [this](#chaining-mutations). + +```js +var inc = function(currentData) { + return currentData + 1; +}; + +cursor.chain(inc); + +// At key +cursor.chain('number', inc) + +// Nested path +cursor.chain(['one', 'two'], 'orange'); ``` *Shallowly merging objects* +Obviously this will fail if the value watched over by your cursor is not an object. + ```js cursor.merge({hello: 'world'}); + +// At key +cursor.merge('object', {hello: 'world'}) + +// Nested path +cursor.apply(['one', 'two'], {hello: 'world'}); ``` #### Events Whenever an update is committed, events are fired to notify relevant parts of the tree that data was changed so that bound elements, React components, for instance, can update. -Note however that only relevant cursors will be notified of data change. +Note however that **only** relevant cursors will be notified of a change. Events can be bound to either the tree or cursors using the `on` method. @@ -255,22 +346,29 @@ johnCursor.set('firstname', 'John the third'); Will fire if the tree is updated. ```js -tree.on('update', fn); +tree.on('update', function(e) { + var affectedPaths = e.data.log, + previousState = e.data.previousState; + + //... +}); ``` *invalid* -Will fire if a data-validation specification was passed at instance and if new data does not abide by those specifications. For more information about this, see the [data validation](#data-validation) part of the documentation. +Will fire if the `validate` function (see [options](#options)) returned an error for the current update. ```js -tree.on('invalid', fn); +tree.on('invalid', function(e) { + console.log(e.data.error); +}); ``` ##### Cursor level *update* -Will fire if data watched by cursor has updated. +Will fire if data watched over by the cursor has updated. ```js cursor.on('update', fn); @@ -286,7 +384,7 @@ cursor.on('irrelevant', fn); *relevant* -Will fire if the cursor is irrelevant but becomes relevant again. +Will fire if the cursor was irrelevant but becomes relevant again. ```js cursor.on('relevant', fn); @@ -296,127 +394,6 @@ cursor.on('relevant', fn); For more information concerning **Baobab**'s event emitting, see the [emmett](https://github.com/jacomyal/emmett) library. -#### React mixins - -A *baobab* tree can easily be used as a UI model keeping the whole application state. - -It is then really simple to bind this centralized model to React components by using the library's built-in mixins. Those will naturally bind components to one or more cursors watching over parts of the main state so they can update only when relevant data has been changed. - -This basically makes the `shouldComponentUpdate` method useless in most of cases and ensures that your components will only re-render if they need to because of data changes. - -##### Tree level - -You can bind a React component to the tree itself and register some handy cursors: - -```jsx -var tree = new Baobab({ - users: ['John', 'Jack'], - information: { - title: 'My fancy App' - } -}); - -// Single cursor -var UserList = React.createClass({ - mixins: [tree.mixin], - cursor: ['users'], - render: function() { - var renderItem = function(name) { - return
  • {name}
  • ; - }; - - // Cursor data is then available either through: - var data = this.cursor.get(); - // Or - var data = this.state.cursor; - - return
      {this.cursor.get().map(renderItem)}
    ; - } -}); - -// Multiple cursors -var UserList = React.createClass({ - mixins: [tree.mixin], - cursors: [['users'], ['information', 'title']], - render: function() { - var renderItem = function(name) { - return
  • {name}
  • ; - }; - - // Cursor data is then available either through: - var data = this.cursors[0].get(); - // Or - var data = this.state.cursors[0]; - - return ( -
    -

    {this.cursors[1].get()}

    -
      {this.cursors[0].get().map(renderItem)}
    -
    - ); - } -}); - -// Better multiple cursors -var UserList = React.createClass({ - mixins: [tree.mixin], - cursors: { - users: ['users'], - title: ['information', 'title'] - }, - render: function() { - var renderItem = function(name) { - return
  • {name}
  • ; - }; - - // Cursor data is then available either through: - var data = this.cursors.users.get(); - // Or - var data = this.state.cursors.users; - - return ( -
    -

    {this.cursors.title.get()}

    -
      {this.cursors.users.get().map(renderItem)}
    -
    - ); - } -}); - -// Cursor(s) can also be specified using a function -// (if you need props, for instance) -var UserListItem = React.createClass({ - mixins: [tree.mixin], - cursor: function() { - return ['users', this.props.index]; - }, - render: function() { - var name = this.cursor.get(); - return
  • {name}
  • ; - } -}); -``` - -##### Cursor level - -Else you can bind a single cursor to a React component - -```jsx -var tree = new Baobab({users: ['John', 'Jack']}), - usersCursor = tree.select('users'); - -var UserList = React.createClass({ - mixins: [usersCursor.mixin], - render: function() { - var renderItem = function(name) { - return
  • {name}
  • ; - }; - - return
      {this.cursor.get().map(renderItem)}
    ; - } -}); -``` - ### Advanced #### Polymorphisms @@ -428,6 +405,7 @@ var tree = new Baobab({ palette: { name: 'fancy', colors: ['blue', 'yellow', 'green'], + currentColor: 1, items: [{id: 'one', value: 'Hey'}, {id: 'two', value: 'Ho'}] } }); @@ -438,10 +416,10 @@ var colorsCursor = tree.select(['palette', 'colors']); var colorsCursor = tree.select('palette').select('colors'); // Retrieving data -colorsCursor.get(1) +colorsCursor.get(1); >>> 'yellow' -paletteCursor.get('colors', 2) +paletteCursor.get('colors', 2); >>> 'green' tree.get('palette', 'colors'); @@ -462,6 +440,17 @@ tree.get('palette', 'colors', function(color) { var complexCursor = tree.select('items', {id: 'one'}, 'value'); tree.get('items', {id: 'one'}, 'value'); >>> 'Hey' + +// Retrieving or selecting data by using the value of another cursor +var currentColorCursor = tree.select('colors', {$cursor: ['currentColor']}); + +var currentColor = tree.get('colors', {$cursor: ['currentColor']}); + +// Creating a blank tree +var blankTree = new Baobab(); + +// You despise "new"? +var tree = Baobab(); ``` #### Traversal @@ -505,12 +494,12 @@ twoCursor.rightmost().get(); var tree = new Baobab({first: {second: 'yeah'}}), cursor = tree.select('first'); -var rootCursor = tree.root(); +var rootCursor = tree.root; // or var rootCursor = cursor.root(); ``` -*Check information about the cursor's location in the tree* +*Checking information about the cursor's location in the tree* ```js cursor.isRoot(); @@ -535,22 +524,33 @@ var baobab = new Baobab( // Options { - maxHistory: 5, - clone: true + autoCommit: false } ) ``` * **autoCommit** *boolean* [`true`]: should the tree auto commit updates or should it let the user do so through the `commit` method? * **asynchronous** *boolean* [`true`]: should the tree delay the update to the next frame or fire them synchronously? -* **clone** *boolean* [`false`]: by default, the tree will give access to references. Set to `true` to clone data when retrieving it from the tree if you feel paranoid and know you might mutate the references by accident or need a cloned object to handle. -* **cloningFunction** *function*: the library's cloning method is minimalist on purpose and won't cover edgy cases. You remain free to pass your own more complex cloning function to the tree if needed. -* **cursorSingletons** *boolean* [`true`]: by default, a *baobab* tree stashes the created cursor so only one would be created by path. You can override this behaviour by setting `cursorSingletons` to `false`. -* **maxHistory** *number* [`0`]: max number of records the tree is allowed to store within its internal history. -* **mixins** *array*: optional mixins to merge with baobab's ones. Recommending the [pure render](http://facebook.github.io/react/docs/pure-render-mixin.html) one from react. -* **shiftReferences** *boolean* [`false`]: tell the tree to shift references of the objects it updates so that functions performing shallow comparisons (such as the one used by the `PureRenderMixin`, for instance), can assess that data changed. -* **typology** *Typology|object*: a custom typology to be used to validate the tree's data. -* **validate** *object*: a [typology](https://github.com/jacomyal/typology) schema ensuring the tree's data is valid. +* **facets** *object*: a collection of facets to register when the tree is istantiated. For more information, see [facets](#facets). +* **validate** *function*: a function in charge of validating the tree whenever it updates. See below for an example of such function. +* **validationBehavior** *string* [`rollback`]: validation behavior of the tree. If `rollback`, the tree won't apply the current update and fire an `invalid` event while `notify` will only emit the event and let the tree enter an invalid state anyway. + +*Validation function* + +```js +function validationFunction(previousState, newState, affectedPaths) { + // Peform validation here and return an error if + // the tree is invalid + if (!valid) + return new Error('Invalid tree because of reasons.'); +} + +var tree = new Baobab({...}, {validate: validationFunction}); +``` + +#### Facets + +WIP #### History @@ -665,72 +665,6 @@ cursor.chain(inc); // will produce 3 ``` -#### Cursor combinations - -At times, you might want to listen to updates concerning a logical combination of cursors. For instance, you might want to know when two cursors both updated or when either one or the other did. - -You can build cursor combination likewise: - -```js -// Simple "or" combination -var combination = cursor1.or(cursor2); - -// Simple "and" combination -var combination = cursor1.and(cursor2); - -// Complex combination -var combination = cursor1.or(cursor2).or(cursor3).and(cursor4); - -// Listening to events -combination.on('update', handler); - -// Releasing a combination to avoid leaks -combination.release(); -``` - -#### Data validation - -Given you pass the correct parameters, a baobab tree is able to check whether its data is valid or not against the supplied specification. - -This specification must be written in the [typology](https://github.com/jacomyal/typology) library's style. - -*Example* - -```js -var baobab = new Baobab( - - // Initial state - { - hello: 'world', - colors: ['yellow', 'blue'], - counters: { - users: 3, - groups: 1 - } - }, - - // Parameters - { - validate: { - hello: '?string', - colors: ['string'], - counters: { - users: 'number', - groups: 'number' - } - } - } -); - -// If one updates the tree and does not respect the validation specification -baobab.set('hello', 42); - -// Then the tree will fire an 'invalid' event containing a list of errors -baobab.on('invalid', function(e) { - console.log(e.data.errors); -}); -``` - #### Common pitfalls *Controlled input state* From 7fcb392cc918a1d426db718bb01d686c90aad516 Mon Sep 17 00:00:00 2001 From: Yomguithereal Date: Thu, 16 Apr 2015 17:54:27 +0200 Subject: [PATCH 64/73] Fun fact --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 16d200f..36c2c13 100644 --- a/README.md +++ b/README.md @@ -10,7 +10,7 @@ It can be paired with **React** painlessly through mixins or higher order compon For a concise introduction about the library and how it can be used in a React/Flux application, you can head toward **@christianalfoni**'s [article](http://christianalfoni.github.io/javascript/2015/02/06/plant-a-baobab-tree-in-your-flux-application.html) on the subject. -**Trivia**: A [Baobab](http://en.wikipedia.org/wiki/Adansonia_digitata), or *Adansonia digitata*, is a very big and magnificient African tree. +**Fun fact**: A [Baobab](http://en.wikipedia.org/wiki/Adansonia_digitata), or *Adansonia digitata*, is a very big and magnificient African tree. ## Summary From 680e85f2a36f1bdc3ea477f43fc9599b8679f0a3 Mon Sep 17 00:00:00 2001 From: Yomguithereal Date: Thu, 16 Apr 2015 20:02:25 +0200 Subject: [PATCH 65/73] Wrapping v1 docs up? --- README.md | 223 +++++++++++++++++++++++++++++++++++++++++++----------- 1 file changed, 178 insertions(+), 45 deletions(-) diff --git a/README.md b/README.md index 36c2c13..8d35e2e 100644 --- a/README.md +++ b/README.md @@ -140,7 +140,7 @@ Rather, the tree will stack and merge every update order you give it and will on This enables the tree to perform efficient mutations and to be able to notify any relevant cursors that the data they are watching over has changed. -Note also that the tree will shift the references of the objects it watches over in order to enable "immutabley" comparisons between one version of the state and another (this is especially useful when using things as such as React's pure render [mixin](https://facebook.github.io/react/docs/pure-render-mixin.html)). +Note also that the tree will shift the references of the objects it stores in order to enable "immutabley" comparisons between one version of the state and another (this is especially useful when using things as such as React's pure render [mixin](https://facebook.github.io/react/docs/pure-render-mixin.html)). *Example* @@ -550,43 +550,172 @@ var tree = new Baobab({...}, {validate: validationFunction}); #### Facets -WIP +Facets can be considered as a "view" upon the data of your tree (a filtered version of an array stored within your tree, for instance). + +They watch over some paths of your tree and will update their cached data only when needed. They can also be listened at like any cursors. + +Facets can be defined at the tree's instantiation likewise: + +```js +var tree = new Baobab( + + // Data + { + projects: [ + { + id: 1, + name: 'Tezcatlipoca', + user: 'John' + }, + { + id: 2, + name: 'Huitzilopochtli', + user: 'John' + }, + { + id: 3, + name: 'Tlaloc', + user: 'Jack' + } + ], + currentProjectId: 1 + }, + + // Options + { + facets: { + + // Name of your facet + currentProject: { + + // Cursors to which your facet is bound + // If any of the paths listed below fire + // an update, so will the facet. + cursors: { + id: ['currentProjectId'], + projects: ['projects'] + }, + get: function(data) { + + // Data is the value of your mapped cursors + + // Just return the wanted value + // Here, we use lodash to return the current's project + // data based on its id + return _.find(data.projects, {id: data.id}); + } + }, + + // Other example + filteredProjects: { + cursors: { + projects: ['projects'] + }, + get: function(data) { + return data.projects.filter(function(p) { + return p.user === 'John'; + }); + } + }, + } + } +) +``` + +You can then access facets' data and listen to their changes thusly: + +```js +var facet = tree.facets.currentProject; + +// Getting value (cached and only computed if needed) +facet.get(); + +// Listening +facet.on('update', function() { + console.log('New value:', facet.get()); +}); +``` #### History -A *baobab* tree, given you instantiate it with the correct option, is able to record *n* of its passed states so you can go back in time whenever you want. +**Baobab** lets you record the state of any cursor so you can seamlessly implement undo/redo features. *Example* ```js -var baobab = new Baobab({name: 'Maria'}, {maxHistory: 1}); +// Asynchronous tree so that examples are simpler +var baobab = new Baobab({colors: ['blue']}, {asynchronous: false}), + cursor = baobab.select('colors'); -baobab.set('name', 'Isabella'); +// Starting to record state, with 10 records maximum +cursor.startRecording(10); -// On next frame, when update has been committed -baobab.get('name') ->>> 'Isabella' -baobab.undo(); -baobab.get('name') ->>> 'Maria' +cursor.push('yellow'); +cursor.push('purple'); +cursor.push('orange'); + +cursor.get(); +>>> ['blue', 'yellow', 'purple', 'orange'] + +cursor.undo(); +cursor.get(); +>>> ['blue', 'yellow', 'purple'] + +cursor.undo(2); +cursor.get(); +>>> ['blue'] ``` -*Related Methods* +*Starting recording* + +Default max number of records is 5. ```js -// Check whether our tree hold records -baobab.hasHistory(); ->>> true +cursor.startRecording(maxNbOfRecords); +``` + +*Stoping recording* -// Retrieving history records -baobab.getHistory(); +```js +cursor.stopRecording(); +``` + +*Undoing* + +```js +cursor.undo(); +cursor.undo(nbOfSteps); +``` + +*Clearing history* + +```js +cursor.clearHistory(); +``` + +*Checking if the cursor has an history* + +```js +cursor.hasHistory(); +``` + +*Checking whether the cursor is currently recording* + +```js +cursor.recording; +``` + +*Retrieving the cursor's history* + +```js +cursor.getHistory(); ``` #### Update specifications -If you ever need to specify complex updates without resetting the whole subtree you are acting on, for readability or performance reasons, you remain free to use **Baobab**'s internal update specifications. +If you ever need to specify complex updates without replacing the whole subtree you are acting on, for readability or performance reasons, you remain free to use **Baobab**'s internal update specifications. -Those are widely inspired by React's immutable [helpers](http://facebook.github.io/react/docs/update.html), themselves inspired by [MongoDB](http://www.mongodb.org/)'s ones and can be used through `tree.update` and `cursor.update`. +Those are widely inspired by React's immutable [helpers](http://facebook.github.io/react/docs/update.html) and can be used through `tree.update` or `cursor.update`. *Specifications* @@ -599,6 +728,7 @@ The available commands are the following and are basically the same as the curso * `$chain` * `$push` * `$unshift` +* `$unshift` * `$merge` * `$unset` @@ -667,32 +797,6 @@ cursor.chain(inc); #### Common pitfalls -*Controlled input state* - -If you need to store a react controlled input's state into a baobab tree, remember you have to commit changes synchronously through the `commit` method if you don't want to observe nasty cursor jumps. - -```jsx -var tree = new Boabab({inputValue: null}); - -var Input = React.createClass({ - mixins: [tree.mixin], - cursor: ['inputValue'], - onChange: function(e) { - var newValue = e.target.value; - - // If one edits the tree normally, i.e. asynchronously, the cursor will hop - this.cursor.edit(newValue); - - // One has to commit synchronously the update for the input to work correctly - this.cursor.edit(newValue); - this.tree.commit(); - }, - render: function() { - return ; - } -}); -``` - *Immutable behaviour* TL;DR: Don't mutate things in your *baobab* tree. Let the tree handle its own mutations. @@ -712,6 +816,35 @@ tree.set('key', o); o.hello = 'other world'; ``` +## Philosophy + +*UIs as pure functions* + +UIs should be, as far as possible, considered as pure functions. **Baobab** is just a way to provide the needed arguments, i.e. the data representing your app's state, to such function. + +Considering your UIs like pure functions comes along with nice things like easy undo/redo features, state storing (just save your tree in the localStorage and here you go) and easy isomorphism. + +*Only data should enter the tree* + +You shouldn't try to shove anything else than raw data into the tree. The tree hasn't been conceived to hold classes or fancy indexes with many circular references and cannot perform its magic on it. But, probably such magic is not desirable for those kind of abstractions anyway. + +That is to say the data you insert into the tree should logically be JSON-serializable else you might be missing the point. + +## Migration + +*From v0.4.x to 1.0.0* + +A lot of changes occurred between `0.4.x` and `1.0.0`. Most notable changes being the following ones: + +* The tree now shift references by default. +* React integration has improved and is now handled by [baobab-react](https://github.com/Yomguithereal/baobab-react). +* `cursor.edit` and `cursor.remove` have been replaced by `cursor.set` and `cursor.unset` single argument polymorphisms. +* A lot of options (now unnecessary) have been dropped. +* Validation is no longer handled by [`typology`](https://github.com/jacomyal/typology) so you can choose you own validation system and so the library can remain lighter. +* Some new features such as: `$splice`, facets and so on... + +For more information, see the [changelog](./CHANGELOG.md). + ## Contribution Contributions are obviously welcome. This project is nothing but experimental and I would cherish some feedback and advice about the library. From f4a4c26baa572116577655227241d1b5943012b2 Mon Sep 17 00:00:00 2001 From: Yomguithereal Date: Thu, 16 Apr 2015 20:19:46 +0200 Subject: [PATCH 66/73] Tweaking docs --- README.md | 40 ++++++++++++++++++++-------------------- 1 file changed, 20 insertions(+), 20 deletions(-) diff --git a/README.md b/README.md index 8d35e2e..cc40436 100644 --- a/README.md +++ b/README.md @@ -6,7 +6,7 @@ It is mainly inspired by functional [zippers](http://clojuredocs.org/clojure.zip/zipper) such as Clojure's ones and by [Om](https://github.com/swannodette/om)'s cursors. -It can be paired with **React** painlessly through mixins or higher order components (available [here](https://github.com/Yomguithereal/baobab-react)) and provide a centralized model holding your application's state. +It aims at providing a centralized model holding an application's state and can be paired with **React** easily through mixins or higher order components (available [here](https://github.com/Yomguithereal/baobab-react)). For a concise introduction about the library and how it can be used in a React/Flux application, you can head toward **@christianalfoni**'s [article](http://christianalfoni.github.io/javascript/2015/02/06/plant-a-baobab-tree-in-your-flux-application.html) on the subject. @@ -77,7 +77,7 @@ If you want to use it in the browser, just include the minified script located [ Or install with bower: ```js -bower install baobab +bower install baobab@1.0.0-rc1 ``` The library (as a standalone) currently weights ~20ko minified and ~6ko gzipped. @@ -136,11 +136,11 @@ var colorCursor = paletteCursor.select('colors'); A *baobab* tree can obviously be updated. However, one has to understand that he won't do it, at least by default, synchronously. -Rather, the tree will stack and merge every update order you give it and will only commit them at the next frame or next tick in node. +Rather, the tree will stack and merge every update order you give it and will only commit them later on. This enables the tree to perform efficient mutations and to be able to notify any relevant cursors that the data they are watching over has changed. -Note also that the tree will shift the references of the objects it stores in order to enable "immutabley" comparisons between one version of the state and another (this is especially useful when using things as such as React's pure render [mixin](https://facebook.github.io/react/docs/pure-render-mixin.html)). +**Important**: Note that the tree will shift the references of the objects it stores in order to enable *immutabley* comparisons between one version of the state and another (this is especially useful when using things as such as React's [PureRenderMixin](https://facebook.github.io/react/docs/pure-render-mixin.html)). *Example* @@ -202,7 +202,7 @@ cursor.unset(['one', 'two']); *Pushing values* -Obviously this will fail if the value watched over by your cursor is not an array. +Obviously this will fail if the value at cursor is not an array. ```js cursor.push('purple'); @@ -219,7 +219,7 @@ cursor.push(['one', 'two'], 'orange'); *Unshifting values* -Obviously this will fail if the value watched over by your cursor is not an array. +Obviously this will fail if the value at cursor is not an array. ```js cursor.unshift('purple'); @@ -236,7 +236,7 @@ cursor.unshift(['one', 'two'], 'orange'); *Splicing an array* -Obviously this will fail if the value watched over by your cursor is not an array. +Obviously this will fail if the value at cursor is not an array. ```js cursor.splice([1, 1]); @@ -287,7 +287,7 @@ cursor.chain(['one', 'two'], 'orange'); *Shallowly merging objects* -Obviously this will fail if the value watched over by your cursor is not an object. +Obviously this will fail if the value at cursor is not an object. ```js cursor.merge({hello: 'world'}); @@ -533,7 +533,7 @@ var baobab = new Baobab( * **asynchronous** *boolean* [`true`]: should the tree delay the update to the next frame or fire them synchronously? * **facets** *object*: a collection of facets to register when the tree is istantiated. For more information, see [facets](#facets). * **validate** *function*: a function in charge of validating the tree whenever it updates. See below for an example of such function. -* **validationBehavior** *string* [`rollback`]: validation behavior of the tree. If `rollback`, the tree won't apply the current update and fire an `invalid` event while `notify` will only emit the event and let the tree enter an invalid state anyway. +* **validationBehavior** *string* [`rollback`]: validation behavior of the tree. If `rollback`, the tree won't apply the current update and fire an `invalid` event while `notify` will only emit the event and let the tree enter the invalid state anyway. *Validation function* @@ -550,9 +550,9 @@ var tree = new Baobab({...}, {validate: validationFunction}); #### Facets -Facets can be considered as a "view" upon the data of your tree (a filtered version of an array stored within your tree, for instance). +Facets can be considered as a "view" on the data of your tree (a filtered version of an array stored within your tree, for instance). -They watch over some paths of your tree and will update their cached data only when needed. They can also be listened at like any cursors. +They watch over some paths of your tree and will update their cached data only when needed. As for cursors, you can also listen to their updates. Facets can be defined at the tree's instantiation likewise: @@ -588,7 +588,7 @@ var tree = new Baobab( // Name of your facet currentProject: { - // Cursors to which your facet is bound + // Cursors bound to your facet // If any of the paths listed below fire // an update, so will the facet. cursors: { @@ -597,7 +597,7 @@ var tree = new Baobab( }, get: function(data) { - // Data is the value of your mapped cursors + // 'data' is the value of your mapped cursors // Just return the wanted value // Here, we use lodash to return the current's project @@ -717,7 +717,7 @@ If you ever need to specify complex updates without replacing the whole subtree Those are widely inspired by React's immutable [helpers](http://facebook.github.io/react/docs/update.html) and can be used through `tree.update` or `cursor.update`. -*Specifications* +**Specifications** Those specifications are described by a JavaScript object that follows the nested structure you are trying to update and applying dollar-prefixed commands at leaf level. @@ -728,7 +728,7 @@ The available commands are the following and are basically the same as the curso * `$chain` * `$push` * `$unshift` -* `$unshift` +* `$splice` * `$merge` * `$unset` @@ -818,13 +818,13 @@ o.hello = 'other world'; ## Philosophy -*UIs as pure functions* +**UIs as pure functions** -UIs should be, as far as possible, considered as pure functions. **Baobab** is just a way to provide the needed arguments, i.e. the data representing your app's state, to such function. +UIs should be, as far as possible, considered as pure functions. Baobab is just a way to provide the needed arguments, i.e. the data representing your app's state, to such a function. -Considering your UIs like pure functions comes along with nice things like easy undo/redo features, state storing (just save your tree in the localStorage and here you go) and easy isomorphism. +Considering your UIs like pure functions comes along with collateral advantages like easy undo/redo features, state storing (just save your tree in the `localStorage` and here you go) and easy isomorphism. -*Only data should enter the tree* +**Only data should enter the tree** You shouldn't try to shove anything else than raw data into the tree. The tree hasn't been conceived to hold classes or fancy indexes with many circular references and cannot perform its magic on it. But, probably such magic is not desirable for those kind of abstractions anyway. @@ -832,7 +832,7 @@ That is to say the data you insert into the tree should logically be JSON-serial ## Migration -*From v0.4.x to 1.0.0* +**From v0.4.x to 1.0.0** A lot of changes occurred between `0.4.x` and `1.0.0`. Most notable changes being the following ones: From 3669f4b3fe7991f23845baa6ff18204d7344941d Mon Sep 17 00:00:00 2001 From: Yomguithereal Date: Thu, 16 Apr 2015 20:20:27 +0200 Subject: [PATCH 67/73] Final precision --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index cc40436..f97a162 100644 --- a/README.md +++ b/README.md @@ -62,7 +62,7 @@ colorsCursor.push('orange'); If you want to use **Baobab** with node.js/io.js or browserify/webpack etc., you can use npm. ```sh -npm install baobab +npm install baobab@1.0.0-rc1 # Or if you need the latest dev version npm install git+https://github.com/Yomguithereal/baobab.git From fdd2358868aed91e7dd8f64e7c778042c3ae8d8c Mon Sep 17 00:00:00 2001 From: Yomguithereal Date: Mon, 20 Apr 2015 17:56:39 +0200 Subject: [PATCH 68/73] Starting facet transition --- src/facet.js | 20 ++++++++++++++++++-- src/type.js | 19 +++++++++++-------- 2 files changed, 29 insertions(+), 10 deletions(-) diff --git a/src/facet.js b/src/facet.js index 53de8ae..08f03f7 100644 --- a/src/facet.js +++ b/src/facet.js @@ -4,8 +4,10 @@ * * Facets enable the user to define views on a given Baobab tree. */ -var Watcher = require('./watcher.js'), - helpers = require('./helpers.js'); +var EventEmitter = require('emmett'), + Watcher = require('./watcher.js'), + helpers = require('./helpers.js'), + type = require('./type.js'); function identity(v) { return v; @@ -14,6 +16,18 @@ function identity(v) { function Facet(tree, definition) { var self = this; + // // Extending event emitter + // EventEmitter.call(this); + + // // Properties + // this.tree = tree; + + + + // ... + + + // Private var data = null, solved = false, @@ -56,4 +70,6 @@ function Facet(tree, definition) { }); } +// helpers.inherits(Facet, EventEmitter); + module.exports = Facet; diff --git a/src/type.js b/src/type.js index 2c81b54..e4a1c39 100644 --- a/src/type.js +++ b/src/type.js @@ -81,18 +81,21 @@ type.Path = function(value) { } }; -type.MixinCursor = function(value) { - return anyOf(value, ['String', 'Number', 'Array', 'Function', 'Cursor']); -}; - -type.MixinCursors = function(value) { - return anyOf(value, ['Object', 'Array', 'Function']); -}; - type.ComplexPath = function(value) { return value.some(function(step) { return anyOf(step, ['Object', 'Function']); }); }; +type.FacetCursors = function(value) { + if (!type.Object(value)) + return false; + + return Object.keys(value).every(function(k) { + var v = value[k]; + + return type.Path(k) || type.Function(k) || k instanceof require('./cursor.js'); + }); +}; + module.exports = type; From 919cc63a1d289a45ca523ba5d962f4f896a4e4b9 Mon Sep 17 00:00:00 2001 From: Yomguithereal Date: Mon, 20 Apr 2015 20:04:38 +0200 Subject: [PATCH 69/73] Fix #172 - merging facets and watcher --- build/baobab.min.js | 2 +- src/baobab.js | 11 -------- src/facet.js | 63 ++++++++++++++++++++++++------------------ src/type.js | 19 +++++++++++-- src/watcher.js | 54 ------------------------------------ test/endpoint.js | 1 - test/suites/baobab.js | 43 ++++++++++++++++++++++++++++ test/suites/watcher.js | 50 --------------------------------- 8 files changed, 97 insertions(+), 146 deletions(-) delete mode 100644 src/watcher.js delete mode 100644 test/suites/watcher.js diff --git a/build/baobab.min.js b/build/baobab.min.js index e9b84b7..d8b9e32 100644 --- a/build/baobab.min.js +++ b/build/baobab.min.js @@ -1,2 +1,2 @@ /* baobab.js - Version: 1.0.0-rc1 - Author: Yomguithereal (Guillaume Plique) */ -!function(t){if("object"==typeof exports&&"undefined"!=typeof module)module.exports=t();else if("function"==typeof define&&define.amd)define([],t);else{var e;e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:this,e.Baobab=t()}}(function(){var t;return function e(t,r,n){function o(s,a){if(!r[s]){if(!t[s]){var h="function"==typeof require&&require;if(!a&&h)return h(s,!0);if(i)return i(s,!0);var u=new Error("Cannot find module '"+s+"'");throw u.code="MODULE_NOT_FOUND",u}var c=r[s]={exports:{}};t[s][0].call(c.exports,function(e){var r=t[s][1][e];return o(r?r:e)},c,c.exports,e,t,r,n)}return r[s].exports}for(var i="function"==typeof require&&require,s=0;sn;n++)t[n].fn!==e&&o.push(t[n]);return o}var s={once:"boolean",scope:"object"},a=0,h=function(){this._enabled=!0,this.unbindAll()};h.prototype.unbindAll=function(){return this._handlers={},this._handlersAll=[],this._handlersComplex=[],this},h.prototype.on=function(t,e,r){var n,i,h,u,c,l,f;if(o(t)){for(u in t)this.on(u,t[u],e);return this}for("function"==typeof t&&(r=e,e=t,t=null),c=[].concat(t),n=0,i=c.length;i>n;n++){if(u=c[n],f={order:a++,fn:e},"string"==typeof u)this._handlers[u]||(this._handlers[u]=[]),l=this._handlers[u];else if(u instanceof RegExp)l=this._handlersComplex,f.pattern=u;else{if(null!==u)throw Error("Emitter.on: invalid event.");l=this._handlersAll}for(h in r||{})s[h]&&(f[h]=r[h]);f.once&&(f.parent=l),l.push(f)}return this},h.prototype.once=function(){var t=Array.prototype.slice.call(arguments),r=t.length-1;return o(t[r])&&t.length>1?t[r]=e(t[r],{once:!0}):t.push({once:!0}),this.on.apply(this,t)},h.prototype.off=function(t,e){var r,n,s,a;if(1===arguments.length&&"function"==typeof t){e=arguments[0];for(s in this._handlers)this._handlers[s]=i(this._handlers[s],e),0===this._handlers[s].length&&delete this._handlers[s];this._handlersAll=i(this._handlersAll,e),this._handlersComplex=i(this._handlersComplex,e)}else if(1===arguments.length&&"string"==typeof t)delete this._handlers[t];else if(2===arguments.length){var h=[].concat(t);for(r=0,n=h.length;n>r;r++)a=h[r],this._handlers[a]=i(this._handlers[a],e),0===(this._handlers[a]||[]).length&&delete this._handlers[a]}else if(o(t))for(s in t)this.off(s,t[s]);return this},h.prototype.listeners=function(t){var e,r,n,o=this._handlersAll||[],i=!1;if(!t)throw Error("Emitter.listeners: no event provided.");for(o=o.concat(this._handlers[t]||[]),r=0,n=this._handlersComplex.length;n>r;r++)e=this._handlersComplex[r],~t.search(e.pattern)&&(i=!0,o.push(e));return this._handlersAll.length||i?o.sort(function(t,e){return t.order-e.order}):o.slice(0)},h.prototype.emit=function(t,e){if(!this._enabled)return this;if(o(t)){for(var r in t)this.emit(r,t[r]);return this}var n,i,s,a,h,u,c,l=[].concat(t),f=[];for(a=0,u=l.length;u>a;a++){for(i=this.listeners(l[a]),h=0,c=i.length;c>h;h++)s=i[h],n={type:l[a],target:this},arguments.length>1&&(n.data=e),s.fn.call("scope"in s?s.scope:this,n),s.once&&f.push(s);for(h=f.length-1;h>=0;h--)f[h].parent.splice(f[h].parent.indexOf(f[h]),1)}return this},h.prototype.kill=function(){this.unbindAll(),this._handlers=null,this._handlersAll=null,this._handlersComplex=null,this._enabled=!1},h.prototype.disable=function(){return this._enabled=!1,this},h.prototype.enable=function(){return this._enabled=!0,this},h.version="3.0.0","undefined"!=typeof n?("undefined"!=typeof r&&r.exports&&(n=r.exports=h),n.Emitter=h):"function"==typeof t&&t.amd?t("emmett",[],function(){return h}):this.Emitter=h}).call(this)},{}],4:[function(t,e,r){function n(t){return t+"$"+(new Date).getTime()+(""+Math.random()).replace("0.","")}function o(t,e){function r(t){this[t]=function(){var e=this.root[t].apply(this.root,arguments);return e instanceof i?this:e}}if(arguments.length<1&&(t={}),!(this instanceof o))return new o(t,e);if(!p.Object(t)&&!p.Array(t))throw Error("Baobab: invalid data.");if(s.call(this),this.options=u.shallowMerge(f,e),this._transaction={},this._future=void 0,this._cursors={},this._identity="[object Baobab]",this.data=u.deepClone(t),this.root=this.select([]),this.facets={},["get","set","unset","update"].forEach(r.bind(this)),!p.Object(this.options.facets))throw Error("Baobab: invalid facets.");for(var n in this.options.facets)this.addFacet(n,this.options.facets[n])}var i=t("./cursor.js"),s=t("emmett"),a=t("./watcher.js"),h=t("./facet.js"),u=t("./helpers.js"),c=t("./update.js"),l=t("./merge.js"),f=t("../defaults.js"),p=t("./type.js");u.inherits(o,s),o.prototype.addFacet=function(t,e){return this.facets[t]=this.createFacet(e),this},o.prototype.createFacet=function(t){return new h(this,t)},o.prototype.select=function(t){if(!t)throw Error("Baobab.select: invalid path.");if(arguments.length>1&&(t=u.arrayOf(arguments)),!p.Path(t))throw Error("Baobab.select: invalid path.");t=[].concat(t);var e,r=p.ComplexPath(t);r&&(e=u.solvePath(this.data,t,this));var o=t.map(function(t){return p.Function(t)?n("fn"):p.Object(t)?n("ob"):t}).join("|λ|");if(this._cursors[o])return this._cursors[o];var s=new i(this,t,e,o);return this._cursors[o]=s,s},o.prototype.stack=function(t){var e=this;if(!p.Object(t))throw Error("Baobab.update: wrong specification.");return this._transaction=l(t,this._transaction),this.options.autoCommit?this.options.asynchronous?(this._future||(this._future=setTimeout(e.commit.bind(e,null),0)),this):this.commit():this},o.prototype.commit=function(){var t=c(this.data,this._transaction,this.options),e=this.data;this._transaction={},this._future&&(this._future=clearTimeout(this._future));var r=this.options.validate,n=this.options.validationBehavior;if("function"==typeof r){var o=r.call(this,e,t.data,t.log);if(o instanceof Error&&(this.emit("invalid",{error:o}),"rollback"===n))return this}return this.data=t.data,this.emit("update",{log:t.log,previousState:e}),this},o.prototype.watch=function(t){if(!p.Array(t)||t.some(function(t){return!p.Path(t)}))throw Error("Baobab.watch: invalid paths.");return new a(this,[].concat(t))},o.prototype.release=function(){var t;delete this.data,delete this._transaction;for(t in this._cursors)this._cursors[t].release();delete this._cursors;for(t in this.facets)this.facets[t].release();delete this.facets,this.kill()},o.prototype.toJSON=function(){return this.get()},o.prototype.toString=function(){return this._identity},e.exports=o},{"../defaults.js":2,"./cursor.js":5,"./facet.js":6,"./helpers.js":7,"./merge.js":8,"./type.js":9,"./update.js":10,"./watcher.js":11,emmett:3}],5:[function(t,e,r){function n(t,e,r,n){function o(t){if(i.recording&&!i.undoing){var e=a.getIn(t,i.solvedPath,i.tree),r=a.deepClone(e);i.archive.add(r)}return i.undoing=!1,i.emit("update")}var i=this;s.call(this),e=e||[],this.tree=t,this.path=e,this.hash=n,this.archive=null,this.recording=!1,this.undoing=!1,this._identity="[object Cursor]",this.complexPath=!!r,this.solvedPath=this.complexPath?r:this.path,this.relevant=void 0!==this.get(),this.updateHandler=function(t){var e=t.data.log,r=t.data.previousState,n=!1;if(i.complexPath&&(i.solvedPath=a.solvePath(i.tree.data,i.path,i.tree)),!i.path.length)return o(r);i.solvedPath&&(n=a.solveUpdate(e,[i.solvedPath]));var s=void 0!==i.get();i.relevant?s&&n?o(r):s||(i.emit("irrelevant"),i.relevant=!1):s&&n&&(i.emit("relevant"),o(r),i.relevant=!0)};var h=!1;this._lazyBind=function(){h||(h=!0,i.tree.on("update",i.updateHandler))},this.on=a.before(this._lazyBind,this.on.bind(this)),this.once=a.before(this._lazyBind,this.once.bind(this)),this.complexPath&&this._lazyBind()}function o(t,e,r,n){if(arguments.length>5)throw Error("baobab.Cursor."+t+": too many arguments.");if(arguments.length<4&&(n=r,r=[]),r=r||[],"splice"===t&&!h.Splicer(n)){if(!h.Array(n))throw Error("baobab.Cursor.splice: incorrect value.");n=[n]}if(e&&!e(n))throw Error("baobab.Cursor."+t+": incorrect value.");var o=[].concat(r),i=a.solvePath(this.get(),o,this.tree);if(!i)throw Error("baobab.Cursor."+t+": could not solve dynamic path.");var s={};s["$"+t]=n;var u=a.pathObject(i,s);return u}function i(t,e){n.prototype[t]=function(){var r=o.bind(this,t,e).apply(this,arguments);return this.update(r)}}var s=t("emmett"),a=t("./helpers.js"),h=(t("../defaults.js"),t("./type.js"));a.inherits(n,s),n.prototype.isRoot=function(){return!this.path.length},n.prototype.isLeaf=function(){return h.Primitive(this.get())},n.prototype.isBranch=function(){return!this.isLeaf()&&!this.isRoot()},n.prototype.root=function(){return this.tree.root()},n.prototype.select=function(t){if(arguments.length>1&&(t=a.arrayOf(arguments)),!h.Path(t))throw Error("baobab.Cursor.select: invalid path.");return this.tree.select(this.path.concat(t))},n.prototype.up=function(){return this.solvedPath&&this.solvedPath.length?this.tree.select(this.path.slice(0,-1)):null},n.prototype.left=function(){var t=+this.solvedPath[this.solvedPath.length-1];if(isNaN(t))throw Error("baobab.Cursor.left: cannot go left on a non-list type.");return t?this.tree.select(this.solvedPath.slice(0,-1).concat(t-1)):null},n.prototype.leftmost=function(){var t=+this.solvedPath[this.solvedPath.length-1];if(isNaN(t))throw Error("baobab.Cursor.leftmost: cannot go left on a non-list type.");return this.tree.select(this.solvedPath.slice(0,-1).concat(0))},n.prototype.right=function(){var t=+this.solvedPath[this.solvedPath.length-1];if(isNaN(t))throw Error("baobab.Cursor.right: cannot go right on a non-list type.");return t+1===this.up().get().length?null:this.tree.select(this.solvedPath.slice(0,-1).concat(t+1))},n.prototype.rightmost=function(){var t=+this.solvedPath[this.solvedPath.length-1];if(isNaN(t))throw Error("baobab.Cursor.right: cannot go right on a non-list type.");var e=this.up().get();return this.tree.select(this.solvedPath.slice(0,-1).concat(e.length-1))},n.prototype.down=function(){+this.solvedPath[this.solvedPath.length-1];return this.get()instanceof Array?this.tree.select(this.solvedPath.concat(0)):null},n.prototype.get=function(t){arguments.length>1&&(t=a.arrayOf(arguments));var e=this.solvedPath.concat([].concat(t||0===t?t:[]));return a.getIn(this.tree.data,e,this.tree)},i("set"),i("apply",h.Function),i("chain",h.Function),i("push"),i("unshift"),i("merge",h.Object),i("splice"),n.prototype.unset=function(t){if(void 0===t&&this.isRoot())throw Error("baobab.Cursor.unset: cannot remove root node.");var e=o.bind(this,"unset",null).apply(this,[t,!0]);return this.update(e)},n.prototype.update=function(t,e){if(arguments.length<2)return this.tree.stack(a.pathObject(this.solvedPath,t)),this;var r=[].concat(t),n=a.solvePath(this.get(),r,this.tree);if(!n)throw Error("baobab.Cursor.update: could not solve dynamic path.");return this.tree.stack(a.pathObject(this.solvedPath.concat(n),e)),this},n.prototype.startRecording=function(t){if(t=t||5,1>t)throw Error("baobab.Cursor.startRecording: invalid maximum number of records.");return this.archive?this:(this._lazyBind(),this.archive=a.archive(t),this.recording=!0,this)},n.prototype.stopRecording=function(){return this.recording=!1,this},n.prototype.undo=function(t){if(t=t||1,!this.recording)throw Error("baobab.Cursor.undo: cursor is not recording.");if(!h.PositiveInteger(t))throw Error("baobab.Cursor.undo: expecting a positive integer.");var e=this.archive.back(t);if(!e)throw Error("boabab.Cursor.undo: cannot find a relevant record ("+t+" back).");return this.undoing=!0,this.set(e)},n.prototype.hasHistory=function(){return!(!this.archive||!this.archive.get().length)},n.prototype.getHistory=function(){return this.archive?this.archive.get():[]},n.prototype.clearHistory=function(){return this.archive=null,this},n.prototype.release=function(){this.tree.off("update",this.updateHandler),this.hash&&delete this.tree._cursors[this.hash],delete this.tree,delete this.path,delete this.solvedPath,delete this.archive,this.kill()},n.prototype.toJSON=function(){return this.get()},n.prototype.toString=function(){return this._identity},e.exports=n},{"../defaults.js":2,"./helpers.js":7,"./type.js":9,emmett:3}],6:[function(t,e,r){function n(t){return t}function o(t,e){function r(t){o[t]=l[t].bind(l)}var o=this,s=null,a=!1,h=e.get||n,u=e.cursors,c=Object.keys(u).map(function(t){return u[t]}),l=new i(t,c);["on","once","release"].forEach(r),this.get=function(){if(a)return s;var e={};for(var r in u)e[r]=t.get(u[r]);return s=h.call(null,e),a=!0,s},this.on("update",function(){a=!1})}{var i=t("./watcher.js");t("./helpers.js")}e.exports=o},{"./helpers.js":7,"./watcher.js":11}],7:[function(t,e,r){(function(r){function n(t){return Array.prototype.slice.call(t)}function o(t,e){return function(){t(),e.apply(null,arguments)}}function i(t,e,r){var o=n(arguments).slice(3);return e=+e,r=+r,t.slice(0,e).concat(t.slice(e+r).concat(o))}function s(t,e){var r,n={};for(r in t)n[r]=t[r];for(r in e)n[r]=e[r];return n}function a(t){var e=t.source,r="";return t.global&&(r+="g"),t.multiline&&(r+="m"),t.ignoreCase&&(r+="i"),t.sticky&&(r+="y"),t.unicode&&(r+="u"),new RegExp(e,r)}function h(t,e){if(!e||"object"!=typeof e||e instanceof Error||"ArrayBuffer"in r&&e instanceof ArrayBuffer)return e;if(_.Array(e)){if(t){var n,o,i=[];for(n=0,o=e.length;o>n;n++)i.push(P(e[n]));return i}return e.slice(0)}if(_.Date(e))return new Date(e.getTime());if(e instanceof RegExp)return a(e);if(_.Object(e)){var s,h={};e.constructor&&e.constructor!==Object&&(h=Object.create(e.constructor.prototype));for(s in e)e.hasOwnProperty(s)&&(h[s]=t?P(e[s]):e[s]);return h}return e}function u(t,e){return function(r){return e(t(r))}}function c(t,e){var r,n;for(r=0,n=t.length;n>r;r++)if(e(t[r]))return t[r]}function l(t,e){var r,n;for(r=0,n=t.length;n>r;r++)if(e(t[r]))return r;return-1}function f(t,e){var r,n=!0;if(!t)return!1;for(r in e)if(_.Object(e[r]))n=n&&f(t[r],e[r]);else if(_.Array(e[r]))n=n&&!!~e[r].indexOf(t[r]);else if(t[r]!==e[r])return!1;return n}function d(t,e){return c(t,function(t){return f(t,e)})}function y(t,e){return l(t,function(t){return f(t,e)})}function v(t,e,r){e=e||[];var n,o,i,s=t;for(o=0,i=e.length;i>o;o++){if(!s)return;if("function"==typeof e[o]){if(!_.Array(s))return;s=c(s,e[o])}else if("object"==typeof e[o])if(r&&"$cursor"in e[o]){if(!_.Path(e[o].$cursor))throw Error("baobab.getIn: $cursor path must be an array.");n=r.get(e[o].$cursor),s=s[n]}else{if(!_.Array(s))return;s=d(s,e[o])}else s=s[e[o]]}return s}function g(t,e,r){var n,o,i,s=[],a=t;for(o=0,i=e.length;i>o;o++){if(!a)return null;if("function"==typeof e[o]){if(!_.Array(a))return;n=l(a,e[o]),s.push(n),a=a[n]}else if("object"==typeof e[o])if(r&&"$cursor"in e[o]){if(!_.Path(e[o].$cursor))throw Error("baobab.getIn: $cursor path must be an array.");p=r.get(e[o].$cursor),s.push(p),a=a[p]}else{if(!_.Array(a))return;n=y(a,e[o]),s.push(n),a=a[n]}else s.push(e[o]),a=a[e[o]]||{}}return s}function b(t,e){var r,n,o,i,s,a,h,u,c;for(r=0,i=e.length;i>r;r++)for(h=e[r],n=0,s=t.length;s>n;n++)for(u=t[n],o=0,a=u.length;a>o&&(c=u[o],c==h[o]);o++)if(o+1===a||o+1===h.length)return!0;return!1}function m(t,e){var r,n=t.length,o={},i=o;for(n||(o=e),r=0;n>r;r++)i[t[r]]=r+1===n?e:{},i=i[t[r]];return o}function j(t,e){t.super_=e;var r=function(){};r.prototype=e.prototype,t.prototype=new r,t.prototype.constructor=t}function w(t){var e=[];return{add:function(r){e.unshift(r),e.length>t&&(e.length=t)},back:function(t){var r=e[t-1];return r&&(e=e.slice(t)),r},get:function(){return e}}}var _=t("./type.js"),$=h.bind(null,!1),P=h.bind(null,!0);e.exports={archive:w,arrayOf:n,before:o,deepClone:P,shallowClone:$,shallowMerge:s,compose:u,getIn:v,inherits:j,pathObject:m,solvePath:g,solveUpdate:b,splice:i}}).call(this,"undefined"!=typeof global?global:"undefined"!=typeof self?self:"undefined"!=typeof window?window:{})},{"./type.js":9}],8:[function(t,e,r){function n(t,e,r){a.forEach(function(e){r!==e&&delete t[e]}),t[r]=e[r]}function o(t,e){var r,h=i.shallowClone(e||{});a.forEach(function(e){t[e]&&n(h,t,e)}),t.$chain&&(a.slice(0,-1).forEach(function(t){delete h[t]}),h.$apply=h.$apply?i.compose(h.$apply,t.$chain):t.$chain),(t.$splice||h.$splice)&&(h.$splice=[].concat(h.$splice||[]).concat(t.$splice||[])),(t.$push||h.$push)&&(h.$push=[].concat(h.$push||[]).concat(t.$push||[])),(t.$unshift||h.$unshift)&&(h.$unshift=[].concat(t.$unshift||[]).concat(h.$unshift||[]));for(r in t)s.Object(t[r])?h[r]=o(t[r],h[r]):"$"!==r[0]&&(h[r]=t[r]);return h}var i=t("./helpers.js"),s=t("./type.js"),a=["$unset","$set","$merge","$apply"];e.exports=o},{"./helpers.js":7,"./type.js":9}],9:[function(t,e,r){function n(t,e){return e.some(function(e){return o[e](t)})}var o={};o.Array=function(t){return Array.isArray(t)},o.Object=function(t){return t&&"object"==typeof t&&!Array.isArray(t)&&!(t instanceof Function)},o.String=function(t){return"string"==typeof t},o.Number=function(t){return"number"==typeof t},o.PositiveInteger=function(t){return"number"==typeof t&&t>0&&t%1===0},o.Function=function(t){return"function"==typeof t},o.Primitive=function(t){return"string"==typeof t||"number"==typeof t||"boolean"==typeof t},o.Date=function(t){return t instanceof Date},o.NonScalar=function(t){return o.Object(t)||o.Array(t)},o.Splicer=function(t){return o.Array(t)&&t.every(o.Array)},o.Path=function(t){var e=["String","Number","Function","Object"];return o.Array(t)?t.every(function(t){return n(t,e)}):n(t,e)},o.MixinCursor=function(t){return n(t,["String","Number","Array","Function","Cursor"])},o.MixinCursors=function(t){return n(t,["Object","Array","Function"])},o.ComplexPath=function(t){return t.some(function(t){return n(t,["Object","Function"])})},e.exports=o},{}],10:[function(t,e,r){function n(t,e){var r=new Error("baobab.update: "+e+" at path /"+t.slice(1).join("/"));return r.path=t,r}var o=t("./helpers.js"),i=t("./type.js");e.exports=function(t,e,r){if(r=r||{},!i.Object(t)&&!i.Array(t))throw Error("baobab.update: invalid target.");var s={};t={root:o.shallowClone(t)};var a=function(t,e,r,h){r=r||["root"];var u,c,l,f=r.join("|λ|"),p=r[r.length-1],d=Object.keys(e).some(function(t){return!!~["$set","$push","$unshift","$splice","$unset","$merge","$apply"].indexOf(t)});if(d){s[f]=!0;for(c in e){if("$unset"===c){var y=r[r.length-2];if(!i.Object(h[y]))throw n(r.slice(0,-1),"using command $unset on a non-object");h[y]=o.shallowClone(t),delete h[y][p];break}if("$set"===c){l=e.$set,t[p]=l;break}if("$apply"===c){if(u=e.$apply,"function"!=typeof u)throw n(r,"using command $apply with a non function");t[p]=u.call(null,t[p]);break}if("$merge"===c){if(l=e.$merge,!i.Object(t[p])||!i.Object(l))throw n(r,"using command $merge with a non object");t[p]=o.shallowMerge(t[p],l);break}if("$splice"===c){if(l=e.$splice,!i.Array(t[p]))throw n(r,"using command $push to a non array");l.forEach(function(e){t[p]=o.splice.apply(null,[t[p]].concat(e))})}if("$push"===c){if(l=e.$push,!i.Array(t[p]))throw n(r,"using command $push to a non array");t[p]=t[p].concat(l)}if("$unshift"===c){if(l=e.$unshift,!i.Array(t[p]))throw n(r,"using command $unshift to a non array");t[p]=[].concat(l).concat(t[p])}}}else for(c in e)t[p][c]="undefined"==typeof t[p][c]?{}:o.shallowClone(t[p][c]),a(t[p],e[c],r.concat(c),t)};return a(t,e),{data:t.root,log:Object.keys(s).map(function(t){return t.split("|λ|").slice(1)})}}},{"./helpers.js":7,"./type.js":9}],11:[function(t,e,r){function n(t,e){function r(){h&&(a=e.map(function(t){return i.solvePath(n.tree.data,t,n.tree)}))}var n=this;o.call(this),this.tree=t;var a=e,h=e.some(s.ComplexPath);this.updateHandler=function(t){var e=i.solveUpdate(t.data.log,a);e&&n.emit("update")},r(),this.tree.on("update",this.updateHandler)}var o=t("emmett"),i=t("./helpers.js"),s=t("./type.js");i.inherits(n,o),n.prototype.release=function(){this.tree.off("update",this.updateHandler),this.tree=null,this.kill()},e.exports=n},{"./helpers.js":7,"./type.js":9,emmett:3}]},{},[1])(1)}); \ No newline at end of file +!function(t){if("object"==typeof exports&&"undefined"!=typeof module)module.exports=t();else if("function"==typeof define&&define.amd)define([],t);else{var e;e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:this,e.Baobab=t()}}(function(){var t;return function e(t,r,n){function o(s,a){if(!r[s]){if(!t[s]){var u="function"==typeof require&&require;if(!a&&u)return u(s,!0);if(i)return i(s,!0);var h=new Error("Cannot find module '"+s+"'");throw h.code="MODULE_NOT_FOUND",h}var c=r[s]={exports:{}};t[s][0].call(c.exports,function(e){var r=t[s][1][e];return o(r?r:e)},c,c.exports,e,t,r,n)}return r[s].exports}for(var i="function"==typeof require&&require,s=0;sn;n++)t[n].fn!==e&&o.push(t[n]);return o}var s={once:"boolean",scope:"object"},a=0,u=function(){this._enabled=!0,this.unbindAll()};u.prototype.unbindAll=function(){return this._handlers={},this._handlersAll=[],this._handlersComplex=[],this},u.prototype.on=function(t,e,r){var n,i,u,h,c,l,f;if(o(t)){for(h in t)this.on(h,t[h],e);return this}for("function"==typeof t&&(r=e,e=t,t=null),c=[].concat(t),n=0,i=c.length;i>n;n++){if(h=c[n],f={order:a++,fn:e},"string"==typeof h)this._handlers[h]||(this._handlers[h]=[]),l=this._handlers[h];else if(h instanceof RegExp)l=this._handlersComplex,f.pattern=h;else{if(null!==h)throw Error("Emitter.on: invalid event.");l=this._handlersAll}for(u in r||{})s[u]&&(f[u]=r[u]);f.once&&(f.parent=l),l.push(f)}return this},u.prototype.once=function(){var t=Array.prototype.slice.call(arguments),r=t.length-1;return o(t[r])&&t.length>1?t[r]=e(t[r],{once:!0}):t.push({once:!0}),this.on.apply(this,t)},u.prototype.off=function(t,e){var r,n,s,a;if(1===arguments.length&&"function"==typeof t){e=arguments[0];for(s in this._handlers)this._handlers[s]=i(this._handlers[s],e),0===this._handlers[s].length&&delete this._handlers[s];this._handlersAll=i(this._handlersAll,e),this._handlersComplex=i(this._handlersComplex,e)}else if(1===arguments.length&&"string"==typeof t)delete this._handlers[t];else if(2===arguments.length){var u=[].concat(t);for(r=0,n=u.length;n>r;r++)a=u[r],this._handlers[a]=i(this._handlers[a],e),0===(this._handlers[a]||[]).length&&delete this._handlers[a]}else if(o(t))for(s in t)this.off(s,t[s]);return this},u.prototype.listeners=function(t){var e,r,n,o=this._handlersAll||[],i=!1;if(!t)throw Error("Emitter.listeners: no event provided.");for(o=o.concat(this._handlers[t]||[]),r=0,n=this._handlersComplex.length;n>r;r++)e=this._handlersComplex[r],~t.search(e.pattern)&&(i=!0,o.push(e));return this._handlersAll.length||i?o.sort(function(t,e){return t.order-e.order}):o.slice(0)},u.prototype.emit=function(t,e){if(!this._enabled)return this;if(o(t)){for(var r in t)this.emit(r,t[r]);return this}var n,i,s,a,u,h,c,l=[].concat(t),f=[];for(a=0,h=l.length;h>a;a++){for(i=this.listeners(l[a]),u=0,c=i.length;c>u;u++)s=i[u],n={type:l[a],target:this},arguments.length>1&&(n.data=e),s.fn.call("scope"in s?s.scope:this,n),s.once&&f.push(s);for(u=f.length-1;u>=0;u--)f[u].parent.splice(f[u].parent.indexOf(f[u]),1)}return this},u.prototype.kill=function(){this.unbindAll(),this._handlers=null,this._handlersAll=null,this._handlersComplex=null,this._enabled=!1},u.prototype.disable=function(){return this._enabled=!1,this},u.prototype.enable=function(){return this._enabled=!0,this},u.version="3.0.0","undefined"!=typeof n?("undefined"!=typeof r&&r.exports&&(n=r.exports=u),n.Emitter=u):"function"==typeof t&&t.amd?t("emmett",[],function(){return u}):this.Emitter=u}).call(this)},{}],4:[function(t,e,r){function n(t){return t+"$"+(new Date).getTime()+(""+Math.random()).replace("0.","")}function o(t,e){function r(t){this[t]=function(){var e=this.root[t].apply(this.root,arguments);return e instanceof i?this:e}}if(arguments.length<1&&(t={}),!(this instanceof o))return new o(t,e);if(!f.Object(t)&&!f.Array(t))throw Error("Baobab: invalid data.");if(s.call(this),this.options=u.shallowMerge(l,e),this._transaction={},this._future=void 0,this._cursors={},this._identity="[object Baobab]",this.data=u.deepClone(t),this.root=this.select([]),this.facets={},["get","set","unset","update"].forEach(r.bind(this)),!f.Object(this.options.facets))throw Error("Baobab: invalid facets.");for(var n in this.options.facets)this.addFacet(n,this.options.facets[n])}var i=t("./cursor.js"),s=t("emmett"),a=t("./facet.js"),u=t("./helpers.js"),h=t("./update.js"),c=t("./merge.js"),l=t("../defaults.js"),f=t("./type.js");u.inherits(o,s),o.prototype.addFacet=function(t,e){return this.facets[t]=this.createFacet(e),this},o.prototype.createFacet=function(t){return new a(this,t)},o.prototype.select=function(t){if(!t)throw Error("Baobab.select: invalid path.");if(arguments.length>1&&(t=u.arrayOf(arguments)),!f.Path(t))throw Error("Baobab.select: invalid path.");t=[].concat(t);var e,r=f.ComplexPath(t);r&&(e=u.solvePath(this.data,t,this));var o=t.map(function(t){return f.Function(t)?n("fn"):f.Object(t)?n("ob"):t}).join("|λ|");if(this._cursors[o])return this._cursors[o];var s=new i(this,t,e,o);return this._cursors[o]=s,s},o.prototype.stack=function(t){var e=this;if(!f.Object(t))throw Error("Baobab.update: wrong specification.");return this._transaction=c(t,this._transaction),this.options.autoCommit?this.options.asynchronous?(this._future||(this._future=setTimeout(e.commit.bind(e,null),0)),this):this.commit():this},o.prototype.commit=function(){var t=h(this.data,this._transaction,this.options),e=this.data;this._transaction={},this._future&&(this._future=clearTimeout(this._future));var r=this.options.validate,n=this.options.validationBehavior;if("function"==typeof r){var o=r.call(this,e,t.data,t.log);if(o instanceof Error&&(this.emit("invalid",{error:o}),"rollback"===n))return this}return this.data=t.data,this.emit("update",{log:t.log,previousState:e}),this},o.prototype.release=function(){var t;delete this.data,delete this._transaction;for(t in this._cursors)this._cursors[t].release();delete this._cursors;for(t in this.facets)this.facets[t].release();delete this.facets,this.kill()},o.prototype.toJSON=function(){return this.get()},o.prototype.toString=function(){return this._identity},e.exports=o},{"../defaults.js":2,"./cursor.js":5,"./facet.js":6,"./helpers.js":7,"./merge.js":8,"./type.js":9,"./update.js":10,emmett:3}],5:[function(t,e,r){function n(t,e,r,n){function o(t){if(i.recording&&!i.undoing){var e=a.getIn(t,i.solvedPath,i.tree),r=a.deepClone(e);i.archive.add(r)}return i.undoing=!1,i.emit("update")}var i=this;s.call(this),e=e||[],this.tree=t,this.path=e,this.hash=n,this.archive=null,this.recording=!1,this.undoing=!1,this._identity="[object Cursor]",this.complexPath=!!r,this.solvedPath=this.complexPath?r:this.path,this.relevant=void 0!==this.get(),this.updateHandler=function(t){var e=t.data.log,r=t.data.previousState,n=!1;if(i.complexPath&&(i.solvedPath=a.solvePath(i.tree.data,i.path,i.tree)),!i.path.length)return o(r);i.solvedPath&&(n=a.solveUpdate(e,[i.solvedPath]));var s=void 0!==i.get();i.relevant?s&&n?o(r):s||(i.emit("irrelevant"),i.relevant=!1):s&&n&&(i.emit("relevant"),o(r),i.relevant=!0)};var u=!1;this._lazyBind=function(){u||(u=!0,i.tree.on("update",i.updateHandler))},this.on=a.before(this._lazyBind,this.on.bind(this)),this.once=a.before(this._lazyBind,this.once.bind(this)),this.complexPath&&this._lazyBind()}function o(t,e,r,n){if(arguments.length>5)throw Error("baobab.Cursor."+t+": too many arguments.");if(arguments.length<4&&(n=r,r=[]),r=r||[],"splice"===t&&!u.Splicer(n)){if(!u.Array(n))throw Error("baobab.Cursor.splice: incorrect value.");n=[n]}if(e&&!e(n))throw Error("baobab.Cursor."+t+": incorrect value.");var o=[].concat(r),i=a.solvePath(this.get(),o,this.tree);if(!i)throw Error("baobab.Cursor."+t+": could not solve dynamic path.");var s={};s["$"+t]=n;var h=a.pathObject(i,s);return h}function i(t,e){n.prototype[t]=function(){var r=o.bind(this,t,e).apply(this,arguments);return this.update(r)}}var s=t("emmett"),a=t("./helpers.js"),u=(t("../defaults.js"),t("./type.js"));a.inherits(n,s),n.prototype.isRoot=function(){return!this.path.length},n.prototype.isLeaf=function(){return u.Primitive(this.get())},n.prototype.isBranch=function(){return!this.isLeaf()&&!this.isRoot()},n.prototype.root=function(){return this.tree.root()},n.prototype.select=function(t){if(arguments.length>1&&(t=a.arrayOf(arguments)),!u.Path(t))throw Error("baobab.Cursor.select: invalid path.");return this.tree.select(this.path.concat(t))},n.prototype.up=function(){return this.solvedPath&&this.solvedPath.length?this.tree.select(this.path.slice(0,-1)):null},n.prototype.left=function(){var t=+this.solvedPath[this.solvedPath.length-1];if(isNaN(t))throw Error("baobab.Cursor.left: cannot go left on a non-list type.");return t?this.tree.select(this.solvedPath.slice(0,-1).concat(t-1)):null},n.prototype.leftmost=function(){var t=+this.solvedPath[this.solvedPath.length-1];if(isNaN(t))throw Error("baobab.Cursor.leftmost: cannot go left on a non-list type.");return this.tree.select(this.solvedPath.slice(0,-1).concat(0))},n.prototype.right=function(){var t=+this.solvedPath[this.solvedPath.length-1];if(isNaN(t))throw Error("baobab.Cursor.right: cannot go right on a non-list type.");return t+1===this.up().get().length?null:this.tree.select(this.solvedPath.slice(0,-1).concat(t+1))},n.prototype.rightmost=function(){var t=+this.solvedPath[this.solvedPath.length-1];if(isNaN(t))throw Error("baobab.Cursor.right: cannot go right on a non-list type.");var e=this.up().get();return this.tree.select(this.solvedPath.slice(0,-1).concat(e.length-1))},n.prototype.down=function(){+this.solvedPath[this.solvedPath.length-1];return this.get()instanceof Array?this.tree.select(this.solvedPath.concat(0)):null},n.prototype.get=function(t){arguments.length>1&&(t=a.arrayOf(arguments));var e=this.solvedPath.concat([].concat(t||0===t?t:[]));return a.getIn(this.tree.data,e,this.tree)},i("set"),i("apply",u.Function),i("chain",u.Function),i("push"),i("unshift"),i("merge",u.Object),i("splice"),n.prototype.unset=function(t){if(void 0===t&&this.isRoot())throw Error("baobab.Cursor.unset: cannot remove root node.");var e=o.bind(this,"unset",null).apply(this,[t,!0]);return this.update(e)},n.prototype.update=function(t,e){if(arguments.length<2)return this.tree.stack(a.pathObject(this.solvedPath,t)),this;var r=[].concat(t),n=a.solvePath(this.get(),r,this.tree);if(!n)throw Error("baobab.Cursor.update: could not solve dynamic path.");return this.tree.stack(a.pathObject(this.solvedPath.concat(n),e)),this},n.prototype.startRecording=function(t){if(t=t||5,1>t)throw Error("baobab.Cursor.startRecording: invalid maximum number of records.");return this.archive?this:(this._lazyBind(),this.archive=a.archive(t),this.recording=!0,this)},n.prototype.stopRecording=function(){return this.recording=!1,this},n.prototype.undo=function(t){if(t=t||1,!this.recording)throw Error("baobab.Cursor.undo: cursor is not recording.");if(!u.PositiveInteger(t))throw Error("baobab.Cursor.undo: expecting a positive integer.");var e=this.archive.back(t);if(!e)throw Error("boabab.Cursor.undo: cannot find a relevant record ("+t+" back).");return this.undoing=!0,this.set(e)},n.prototype.hasHistory=function(){return!(!this.archive||!this.archive.get().length)},n.prototype.getHistory=function(){return this.archive?this.archive.get():[]},n.prototype.clearHistory=function(){return this.archive=null,this},n.prototype.release=function(){this.tree.off("update",this.updateHandler),this.hash&&delete this.tree._cursors[this.hash],delete this.tree,delete this.path,delete this.solvedPath,delete this.archive,this.kill()},n.prototype.toJSON=function(){return this.get()},n.prototype.toString=function(){return this._identity},e.exports=n},{"../defaults.js":2,"./helpers.js":7,"./type.js":9,emmett:3}],6:[function(t,e,r){function n(t){return t}function o(t,e){function r(){d&&(p=f.map(function(t){return s.solvePath(o.tree.data,t,o.tree)}))}var o=this,u=e.cursors,h=!1,c=a.Function(e.get)?e.get:n,l=null;if(!a.FacetCursors(u))throw Error("baobab.Facet: incorrect cursors mapping.");i.call(this),this.tree=t;var f=Object.keys(u).map(function(t){return u[t]}),p=f,d=f.some(a.ComplexPath);this.updateHandler=function(t){s.solveUpdate(t.data.log,p)&&(h=!1,o.emit("update"))},r(),this.tree.on("update",this.updateHandler),this.get=function(){if(h)return l;var e={};for(var r in u)e[r]=t.get(u[r]);return l=c.call(null,e),h=!0,l}}var i=t("emmett"),s=t("./helpers.js"),a=t("./type.js");s.inherits(o,i),o.prototype.release=function(){this.tree.off("update",this.updateHandler),this.tree=null,this.kill()},e.exports=o},{"./helpers.js":7,"./type.js":9,emmett:3}],7:[function(t,e,r){(function(r){function n(t){return Array.prototype.slice.call(t)}function o(t,e){return function(){t(),e.apply(null,arguments)}}function i(t,e,r){var o=n(arguments).slice(3);return e=+e,r=+r,t.slice(0,e).concat(t.slice(e+r).concat(o))}function s(t,e){var r,n={};for(r in t)n[r]=t[r];for(r in e)n[r]=e[r];return n}function a(t){var e=t.source,r="";return t.global&&(r+="g"),t.multiline&&(r+="m"),t.ignoreCase&&(r+="i"),t.sticky&&(r+="y"),t.unicode&&(r+="u"),new RegExp(e,r)}function u(t,e){if(!e||"object"!=typeof e||e instanceof Error||"ArrayBuffer"in r&&e instanceof ArrayBuffer)return e;if(w.Array(e)){if(t){var n,o,i=[];for(n=0,o=e.length;o>n;n++)i.push(P(e[n]));return i}return e.slice(0)}if(w.Date(e))return new Date(e.getTime());if(e instanceof RegExp)return a(e);if(w.Object(e)){var s,u={};e.constructor&&e.constructor!==Object&&(u=Object.create(e.constructor.prototype));for(s in e)e.hasOwnProperty(s)&&(u[s]=t?P(e[s]):e[s]);return u}return e}function h(t,e){return function(r){return e(t(r))}}function c(t,e){var r,n;for(r=0,n=t.length;n>r;r++)if(e(t[r]))return t[r]}function l(t,e){var r,n;for(r=0,n=t.length;n>r;r++)if(e(t[r]))return r;return-1}function f(t,e){var r,n=!0;if(!t)return!1;for(r in e)if(w.Object(e[r]))n=n&&f(t[r],e[r]);else if(w.Array(e[r]))n=n&&!!~e[r].indexOf(t[r]);else if(t[r]!==e[r])return!1;return n}function d(t,e){return c(t,function(t){return f(t,e)})}function y(t,e){return l(t,function(t){return f(t,e)})}function v(t,e,r){e=e||[];var n,o,i,s=t;for(o=0,i=e.length;i>o;o++){if(!s)return;if("function"==typeof e[o]){if(!w.Array(s))return;s=c(s,e[o])}else if("object"==typeof e[o])if(r&&"$cursor"in e[o]){if(!w.Path(e[o].$cursor))throw Error("baobab.getIn: $cursor path must be an array.");n=r.get(e[o].$cursor),s=s[n]}else{if(!w.Array(s))return;s=d(s,e[o])}else s=s[e[o]]}return s}function g(t,e,r){var n,o,i,s=[],a=t;for(o=0,i=e.length;i>o;o++){if(!a)return null;if("function"==typeof e[o]){if(!w.Array(a))return;n=l(a,e[o]),s.push(n),a=a[n]}else if("object"==typeof e[o])if(r&&"$cursor"in e[o]){if(!w.Path(e[o].$cursor))throw Error("baobab.getIn: $cursor path must be an array.");p=r.get(e[o].$cursor),s.push(p),a=a[p]}else{if(!w.Array(a))return;n=y(a,e[o]),s.push(n),a=a[n]}else s.push(e[o]),a=a[e[o]]||{}}return s}function b(t,e){var r,n,o,i,s,a,u,h,c;for(r=0,i=e.length;i>r;r++)for(u=e[r],n=0,s=t.length;s>n;n++)for(h=t[n],o=0,a=h.length;a>o&&(c=h[o],c==u[o]);o++)if(o+1===a||o+1===u.length)return!0;return!1}function m(t,e){var r,n=t.length,o={},i=o;for(n||(o=e),r=0;n>r;r++)i[t[r]]=r+1===n?e:{},i=i[t[r]];return o}function j(t,e){t.super_=e;var r=function(){};r.prototype=e.prototype,t.prototype=new r,t.prototype.constructor=t}function _(t){var e=[];return{add:function(r){e.unshift(r),e.length>t&&(e.length=t)},back:function(t){var r=e[t-1];return r&&(e=e.slice(t)),r},get:function(){return e}}}var w=t("./type.js"),$=u.bind(null,!1),P=u.bind(null,!0);e.exports={archive:_,arrayOf:n,before:o,deepClone:P,shallowClone:$,shallowMerge:s,compose:h,getIn:v,inherits:j,pathObject:m,solvePath:g,solveUpdate:b,splice:i}}).call(this,"undefined"!=typeof global?global:"undefined"!=typeof self?self:"undefined"!=typeof window?window:{})},{"./type.js":9}],8:[function(t,e,r){function n(t,e,r){a.forEach(function(e){r!==e&&delete t[e]}),t[r]=e[r]}function o(t,e){var r,u=i.shallowClone(e||{});a.forEach(function(e){t[e]&&n(u,t,e)}),t.$chain&&(a.slice(0,-1).forEach(function(t){delete u[t]}),u.$apply=u.$apply?i.compose(u.$apply,t.$chain):t.$chain),(t.$splice||u.$splice)&&(u.$splice=[].concat(u.$splice||[]).concat(t.$splice||[])),(t.$push||u.$push)&&(u.$push=[].concat(u.$push||[]).concat(t.$push||[])),(t.$unshift||u.$unshift)&&(u.$unshift=[].concat(t.$unshift||[]).concat(u.$unshift||[]));for(r in t)s.Object(t[r])?u[r]=o(t[r],u[r]):"$"!==r[0]&&(u[r]=t[r]);return u}var i=t("./helpers.js"),s=t("./type.js"),a=["$unset","$set","$merge","$apply"];e.exports=o},{"./helpers.js":7,"./type.js":9}],9:[function(t,e,r){function n(t,e){return e.some(function(e){return o[e](t)})}var o={};o.Array=function(t){return Array.isArray(t)},o.Object=function(t){return t&&"object"==typeof t&&!Array.isArray(t)&&!(t instanceof Function)},o.String=function(t){return"string"==typeof t},o.Number=function(t){return"number"==typeof t},o.PositiveInteger=function(t){return"number"==typeof t&&t>0&&t%1===0},o.Function=function(t){return"function"==typeof t},o.Primitive=function(t){return"string"==typeof t||"number"==typeof t||"boolean"==typeof t},o.Date=function(t){return t instanceof Date},o.NonScalar=function(t){return o.Object(t)||o.Array(t)},o.Splicer=function(t){return o.Array(t)&&t.every(o.Array)},o.Path=function(t){var e=["String","Number","Function","Object"];return o.Array(t)?t.every(function(t){return n(t,e)}):n(t,e)},o.ComplexPath=function(t){return t.some(function(t){return n(t,["Object","Function"])})},o.FacetCursors=function(e){return o.Object(e)?Object.keys(e).every(function(r){var n=e[r];return o.Path(n)||o.Function(n)||n instanceof t("./cursor.js")}):!1},o.FacetFacets=function(e){return o.Object(e)?Object.keys(e).every(function(r){var n=e[r];return"string"==typeof n||n instanceof t("./facet.js")}):!1},e.exports=o},{"./cursor.js":5,"./facet.js":6}],10:[function(t,e,r){function n(t,e){var r=new Error("baobab.update: "+e+" at path /"+t.slice(1).join("/"));return r.path=t,r}var o=t("./helpers.js"),i=t("./type.js");e.exports=function(t,e,r){if(r=r||{},!i.Object(t)&&!i.Array(t))throw Error("baobab.update: invalid target.");var s={};t={root:o.shallowClone(t)};var a=function(t,e,r,u){r=r||["root"];var h,c,l,f=r.join("|λ|"),p=r[r.length-1],d=Object.keys(e).some(function(t){return!!~["$set","$push","$unshift","$splice","$unset","$merge","$apply"].indexOf(t)});if(d){s[f]=!0;for(c in e){if("$unset"===c){var y=r[r.length-2];if(!i.Object(u[y]))throw n(r.slice(0,-1),"using command $unset on a non-object");u[y]=o.shallowClone(t),delete u[y][p];break}if("$set"===c){l=e.$set,t[p]=l;break}if("$apply"===c){if(h=e.$apply,"function"!=typeof h)throw n(r,"using command $apply with a non function");t[p]=h.call(null,t[p]);break}if("$merge"===c){if(l=e.$merge,!i.Object(t[p])||!i.Object(l))throw n(r,"using command $merge with a non object");t[p]=o.shallowMerge(t[p],l);break}if("$splice"===c){if(l=e.$splice,!i.Array(t[p]))throw n(r,"using command $push to a non array");l.forEach(function(e){t[p]=o.splice.apply(null,[t[p]].concat(e))})}if("$push"===c){if(l=e.$push,!i.Array(t[p]))throw n(r,"using command $push to a non array");t[p]=t[p].concat(l)}if("$unshift"===c){if(l=e.$unshift,!i.Array(t[p]))throw n(r,"using command $unshift to a non array");t[p]=[].concat(l).concat(t[p])}}}else for(c in e)t[p][c]="undefined"==typeof t[p][c]?{}:o.shallowClone(t[p][c]),a(t[p],e[c],r.concat(c),t)};return a(t,e),{data:t.root,log:Object.keys(s).map(function(t){return t.split("|λ|").slice(1)})}}},{"./helpers.js":7,"./type.js":9}]},{},[1])(1)}); \ No newline at end of file diff --git a/src/baobab.js b/src/baobab.js index e3d4cdc..a712aea 100644 --- a/src/baobab.js +++ b/src/baobab.js @@ -6,7 +6,6 @@ */ var Cursor = require('./cursor.js'), EventEmitter = require('emmett'), - Watcher = require('./watcher.js'), Facet = require('./facet.js'), helpers = require('./helpers.js'), update = require('./update.js'), @@ -187,16 +186,6 @@ Baobab.prototype.commit = function() { return this; }; -Baobab.prototype.watch = function(paths) { - if (!type.Array(paths) || - paths.some(function(p) { - return !type.Path(p); - })) - throw Error('Baobab.watch: invalid paths.'); - - return new Watcher(this, [].concat(paths)); -}; - Baobab.prototype.release = function() { var k; diff --git a/src/facet.js b/src/facet.js index 08f03f7..777d29a 100644 --- a/src/facet.js +++ b/src/facet.js @@ -5,7 +5,6 @@ * Facets enable the user to define views on a given Baobab tree. */ var EventEmitter = require('emmett'), - Watcher = require('./watcher.js'), helpers = require('./helpers.js'), type = require('./type.js'); @@ -16,38 +15,46 @@ function identity(v) { function Facet(tree, definition) { var self = this; - // // Extending event emitter - // EventEmitter.call(this); - - // // Properties - // this.tree = tree; - - - - // ... + var map = definition.cursors, + solved = false, + solver = type.Function(definition.get) ? definition.get : identity, + data = null; + if (!type.FacetCursors(map)) + throw Error('baobab.Facet: incorrect cursors mapping.'); + // Extending event emitter + EventEmitter.call(this); - // Private - var data = null, - solved = false, - solver = definition.get || identity, - map = definition.cursors; + // Properties + this.tree = tree; + // Path solving var paths = Object.keys(map).map(function(k) { return map[k]; }); - // Watcher - var watcher = new Watcher(tree, paths); + var solvedPaths = paths, + complex = paths.some(type.ComplexPath); - function bind(name) { - self[name] = watcher[name].bind(watcher); + function solvePaths() { + if (complex) + solvedPaths = paths.map(function(p) { + return helpers.solvePath(self.tree.data, p, self.tree); + }); } - ['on', 'once', 'release'].forEach(bind); + this.updateHandler = function(e) { + if (helpers.solveUpdate(e.data.log, solvedPaths)) { + solved = false; + self.emit('update'); + } + }; + + solvePaths(); + this.tree.on('update', this.updateHandler); - // Getting facet data + // Data solving this.get = function() { if (solved) return data; @@ -63,13 +70,15 @@ function Facet(tree, definition) { return data; }; - - // Resetting flag on cursor update - this.on('update', function() { - solved = false; - }); } -// helpers.inherits(Facet, EventEmitter); +helpers.inherits(Facet, EventEmitter); + +Facet.prototype.release = function() { + this.tree.off('update', this.updateHandler); + + this.tree = null; + this.kill(); +}; module.exports = Facet; diff --git a/src/type.js b/src/type.js index e4a1c39..80763aa 100644 --- a/src/type.js +++ b/src/type.js @@ -49,7 +49,9 @@ type.Function = function(value) { }; type.Primitive = function(value) { - return typeof value === 'string' || typeof value === 'number' || typeof value === 'boolean'; + return typeof value === 'string' || + typeof value === 'number' || + typeof value === 'boolean'; }; type.Date = function(value) { @@ -94,8 +96,21 @@ type.FacetCursors = function(value) { return Object.keys(value).every(function(k) { var v = value[k]; - return type.Path(k) || type.Function(k) || k instanceof require('./cursor.js'); + return type.Path(v) || + type.Function(v) || + v instanceof require('./cursor.js'); }); }; +type.FacetFacets = function(value) { + if (!type.Object(value)) + return false; + + return Object.keys(value).every(function(k) { + var v = value[k]; + + return typeof v === 'string' || v instanceof require('./facet.js'); + }); +} + module.exports = type; diff --git a/src/watcher.js b/src/watcher.js deleted file mode 100644 index 5490a4d..0000000 --- a/src/watcher.js +++ /dev/null @@ -1,54 +0,0 @@ -/** - * Baobab Paths Watcher - * ===================== - * - * A simple abstraction that will fire if any watched path updates. - */ -var EventEmitter = require('emmett'), - helpers = require('./helpers.js'), - type = require('./type.js'); - -/** - * Main Class - */ -function Watcher(tree, paths) { - var self = this; - - // Extending event emitter - EventEmitter.call(this); - - // Properties - this.tree = tree; - - // Privates - var solvedPaths = paths, - complex = paths.some(type.ComplexPath); - - function solvePaths() { - if (complex) - solvedPaths = paths.map(function(p) { - return helpers.solvePath(self.tree.data, p, self.tree); - }); - } - - this.updateHandler = function(e) { - var shoudlFire = helpers.solveUpdate(e.data.log, solvedPaths); - - if (shoudlFire) - self.emit('update'); - }; - - solvePaths(); - this.tree.on('update', this.updateHandler); -} - -helpers.inherits(Watcher, EventEmitter); - -Watcher.prototype.release = function() { - this.tree.off('update', this.updateHandler); - - this.tree = null; - this.kill(); -}; - -module.exports = Watcher; diff --git a/test/endpoint.js b/test/endpoint.js index fa5017a..06b133f 100644 --- a/test/endpoint.js +++ b/test/endpoint.js @@ -7,4 +7,3 @@ require('./suites/helpers.js'); require('./suites/baobab.js'); require('./suites/cursor.js'); -require('./suites/watcher.js'); diff --git a/test/suites/baobab.js b/test/suites/baobab.js index 6b0d028..4998985 100644 --- a/test/suites/baobab.js +++ b/test/suites/baobab.js @@ -6,6 +6,7 @@ var assert = require('assert'), state = require('../state.js'), Baobab = require('../../src/baobab.js'), Cursor = require('../../src/cursor.js'), + Facet = require('../../src/facet.js'), async = require('async'), _ = require('lodash'); @@ -195,6 +196,48 @@ describe('Baobab API', function() { var filtered = baobab.facets.filtered, current = baobab.facets.current; + it('baobab.createFacet should return a facet instance.', function() { + var facet = baobab.createFacet({cursors: {list: ['list']}}); + assert(facet instanceof Facet); + facet.release(); + }); + + it('should fire correctly.', function() { + var tree = new Baobab({list: [1, 2, 3], otherlist: [4, 5, 6], unrelated: 0}, {autoCommit: false}), + list = tree.select('list'), + other = tree.select('otherlist'), + unrelated = tree.select('unrelated'); + + var count = 0, + inc = function() {count++;}; + + var facet = tree.createFacet({cursors: {list: ['list'], otherList: ['otherlist']}}); + facet.on('update', inc); + + list.push(4); + tree.commit(); + + assert.strictEqual(count, 1); + + unrelated.set(1); + tree.commit(); + + assert.strictEqual(count, 1); + + other.push(4); + tree.commit(); + + assert.strictEqual(count, 2); + + list.push(5); + other.push(5); + tree.commit(); + + assert.strictEqual(count, 3); + + facet.release(); + }); + it('should be possible to get data from facets.', function() { assert.deepEqual(filtered.get(), [ { diff --git a/test/suites/watcher.js b/test/suites/watcher.js deleted file mode 100644 index 069b30f..0000000 --- a/test/suites/watcher.js +++ /dev/null @@ -1,50 +0,0 @@ -/** - * Baobab Helpers Unit Tests - * ========================== - */ -var assert = require('assert'), - state = require('../state.js'), - Baobab = require('../../src/baobab.js'), - Watcher = require('../../src/watcher.js'); - -describe('Watcher', function() { - var baobab = new Baobab({list: [1, 2, 3], otherlist: [4, 5, 6], unrelated: 0}, {autoCommit: false}), - list = baobab.select('list'), - other = baobab.select('otherlist'), - unrelated = baobab.select('unrelated'); - - it('baobab.watch should return a watcher instance.', function() { - assert(baobab.watch([['list']]) instanceof Watcher); - }); - - it('should fire correctly.', function() { - var count = 0, - inc = function() {count++;}; - - var watcher = baobab.watch([['list'], ['otherlist']]); - watcher.on('update', inc); - - list.push(4); - baobab.commit(); - - assert.strictEqual(count, 1); - - unrelated.set(1); - baobab.commit(); - - assert.strictEqual(count, 1); - - other.push(4); - baobab.commit(); - - assert.strictEqual(count, 2); - - list.push(5); - other.push(5); - baobab.commit(); - - assert.strictEqual(count, 3); - - watcher.release(); - }); -}); From 7b6ac8e77388cc4d482efd6db8c3e084dc10c070 Mon Sep 17 00:00:00 2001 From: Yomguithereal Date: Mon, 20 Apr 2015 20:30:54 +0200 Subject: [PATCH 70/73] Facets enhancement --- build/baobab.min.js | 2 +- src/facet.js | 28 ++++++++++++++++++---------- test/suites/baobab.js | 29 ++++++++++++++++++++++++++++- 3 files changed, 47 insertions(+), 12 deletions(-) diff --git a/build/baobab.min.js b/build/baobab.min.js index d8b9e32..6620077 100644 --- a/build/baobab.min.js +++ b/build/baobab.min.js @@ -1,2 +1,2 @@ /* baobab.js - Version: 1.0.0-rc1 - Author: Yomguithereal (Guillaume Plique) */ -!function(t){if("object"==typeof exports&&"undefined"!=typeof module)module.exports=t();else if("function"==typeof define&&define.amd)define([],t);else{var e;e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:this,e.Baobab=t()}}(function(){var t;return function e(t,r,n){function o(s,a){if(!r[s]){if(!t[s]){var u="function"==typeof require&&require;if(!a&&u)return u(s,!0);if(i)return i(s,!0);var h=new Error("Cannot find module '"+s+"'");throw h.code="MODULE_NOT_FOUND",h}var c=r[s]={exports:{}};t[s][0].call(c.exports,function(e){var r=t[s][1][e];return o(r?r:e)},c,c.exports,e,t,r,n)}return r[s].exports}for(var i="function"==typeof require&&require,s=0;sn;n++)t[n].fn!==e&&o.push(t[n]);return o}var s={once:"boolean",scope:"object"},a=0,u=function(){this._enabled=!0,this.unbindAll()};u.prototype.unbindAll=function(){return this._handlers={},this._handlersAll=[],this._handlersComplex=[],this},u.prototype.on=function(t,e,r){var n,i,u,h,c,l,f;if(o(t)){for(h in t)this.on(h,t[h],e);return this}for("function"==typeof t&&(r=e,e=t,t=null),c=[].concat(t),n=0,i=c.length;i>n;n++){if(h=c[n],f={order:a++,fn:e},"string"==typeof h)this._handlers[h]||(this._handlers[h]=[]),l=this._handlers[h];else if(h instanceof RegExp)l=this._handlersComplex,f.pattern=h;else{if(null!==h)throw Error("Emitter.on: invalid event.");l=this._handlersAll}for(u in r||{})s[u]&&(f[u]=r[u]);f.once&&(f.parent=l),l.push(f)}return this},u.prototype.once=function(){var t=Array.prototype.slice.call(arguments),r=t.length-1;return o(t[r])&&t.length>1?t[r]=e(t[r],{once:!0}):t.push({once:!0}),this.on.apply(this,t)},u.prototype.off=function(t,e){var r,n,s,a;if(1===arguments.length&&"function"==typeof t){e=arguments[0];for(s in this._handlers)this._handlers[s]=i(this._handlers[s],e),0===this._handlers[s].length&&delete this._handlers[s];this._handlersAll=i(this._handlersAll,e),this._handlersComplex=i(this._handlersComplex,e)}else if(1===arguments.length&&"string"==typeof t)delete this._handlers[t];else if(2===arguments.length){var u=[].concat(t);for(r=0,n=u.length;n>r;r++)a=u[r],this._handlers[a]=i(this._handlers[a],e),0===(this._handlers[a]||[]).length&&delete this._handlers[a]}else if(o(t))for(s in t)this.off(s,t[s]);return this},u.prototype.listeners=function(t){var e,r,n,o=this._handlersAll||[],i=!1;if(!t)throw Error("Emitter.listeners: no event provided.");for(o=o.concat(this._handlers[t]||[]),r=0,n=this._handlersComplex.length;n>r;r++)e=this._handlersComplex[r],~t.search(e.pattern)&&(i=!0,o.push(e));return this._handlersAll.length||i?o.sort(function(t,e){return t.order-e.order}):o.slice(0)},u.prototype.emit=function(t,e){if(!this._enabled)return this;if(o(t)){for(var r in t)this.emit(r,t[r]);return this}var n,i,s,a,u,h,c,l=[].concat(t),f=[];for(a=0,h=l.length;h>a;a++){for(i=this.listeners(l[a]),u=0,c=i.length;c>u;u++)s=i[u],n={type:l[a],target:this},arguments.length>1&&(n.data=e),s.fn.call("scope"in s?s.scope:this,n),s.once&&f.push(s);for(u=f.length-1;u>=0;u--)f[u].parent.splice(f[u].parent.indexOf(f[u]),1)}return this},u.prototype.kill=function(){this.unbindAll(),this._handlers=null,this._handlersAll=null,this._handlersComplex=null,this._enabled=!1},u.prototype.disable=function(){return this._enabled=!1,this},u.prototype.enable=function(){return this._enabled=!0,this},u.version="3.0.0","undefined"!=typeof n?("undefined"!=typeof r&&r.exports&&(n=r.exports=u),n.Emitter=u):"function"==typeof t&&t.amd?t("emmett",[],function(){return u}):this.Emitter=u}).call(this)},{}],4:[function(t,e,r){function n(t){return t+"$"+(new Date).getTime()+(""+Math.random()).replace("0.","")}function o(t,e){function r(t){this[t]=function(){var e=this.root[t].apply(this.root,arguments);return e instanceof i?this:e}}if(arguments.length<1&&(t={}),!(this instanceof o))return new o(t,e);if(!f.Object(t)&&!f.Array(t))throw Error("Baobab: invalid data.");if(s.call(this),this.options=u.shallowMerge(l,e),this._transaction={},this._future=void 0,this._cursors={},this._identity="[object Baobab]",this.data=u.deepClone(t),this.root=this.select([]),this.facets={},["get","set","unset","update"].forEach(r.bind(this)),!f.Object(this.options.facets))throw Error("Baobab: invalid facets.");for(var n in this.options.facets)this.addFacet(n,this.options.facets[n])}var i=t("./cursor.js"),s=t("emmett"),a=t("./facet.js"),u=t("./helpers.js"),h=t("./update.js"),c=t("./merge.js"),l=t("../defaults.js"),f=t("./type.js");u.inherits(o,s),o.prototype.addFacet=function(t,e){return this.facets[t]=this.createFacet(e),this},o.prototype.createFacet=function(t){return new a(this,t)},o.prototype.select=function(t){if(!t)throw Error("Baobab.select: invalid path.");if(arguments.length>1&&(t=u.arrayOf(arguments)),!f.Path(t))throw Error("Baobab.select: invalid path.");t=[].concat(t);var e,r=f.ComplexPath(t);r&&(e=u.solvePath(this.data,t,this));var o=t.map(function(t){return f.Function(t)?n("fn"):f.Object(t)?n("ob"):t}).join("|λ|");if(this._cursors[o])return this._cursors[o];var s=new i(this,t,e,o);return this._cursors[o]=s,s},o.prototype.stack=function(t){var e=this;if(!f.Object(t))throw Error("Baobab.update: wrong specification.");return this._transaction=c(t,this._transaction),this.options.autoCommit?this.options.asynchronous?(this._future||(this._future=setTimeout(e.commit.bind(e,null),0)),this):this.commit():this},o.prototype.commit=function(){var t=h(this.data,this._transaction,this.options),e=this.data;this._transaction={},this._future&&(this._future=clearTimeout(this._future));var r=this.options.validate,n=this.options.validationBehavior;if("function"==typeof r){var o=r.call(this,e,t.data,t.log);if(o instanceof Error&&(this.emit("invalid",{error:o}),"rollback"===n))return this}return this.data=t.data,this.emit("update",{log:t.log,previousState:e}),this},o.prototype.release=function(){var t;delete this.data,delete this._transaction;for(t in this._cursors)this._cursors[t].release();delete this._cursors;for(t in this.facets)this.facets[t].release();delete this.facets,this.kill()},o.prototype.toJSON=function(){return this.get()},o.prototype.toString=function(){return this._identity},e.exports=o},{"../defaults.js":2,"./cursor.js":5,"./facet.js":6,"./helpers.js":7,"./merge.js":8,"./type.js":9,"./update.js":10,emmett:3}],5:[function(t,e,r){function n(t,e,r,n){function o(t){if(i.recording&&!i.undoing){var e=a.getIn(t,i.solvedPath,i.tree),r=a.deepClone(e);i.archive.add(r)}return i.undoing=!1,i.emit("update")}var i=this;s.call(this),e=e||[],this.tree=t,this.path=e,this.hash=n,this.archive=null,this.recording=!1,this.undoing=!1,this._identity="[object Cursor]",this.complexPath=!!r,this.solvedPath=this.complexPath?r:this.path,this.relevant=void 0!==this.get(),this.updateHandler=function(t){var e=t.data.log,r=t.data.previousState,n=!1;if(i.complexPath&&(i.solvedPath=a.solvePath(i.tree.data,i.path,i.tree)),!i.path.length)return o(r);i.solvedPath&&(n=a.solveUpdate(e,[i.solvedPath]));var s=void 0!==i.get();i.relevant?s&&n?o(r):s||(i.emit("irrelevant"),i.relevant=!1):s&&n&&(i.emit("relevant"),o(r),i.relevant=!0)};var u=!1;this._lazyBind=function(){u||(u=!0,i.tree.on("update",i.updateHandler))},this.on=a.before(this._lazyBind,this.on.bind(this)),this.once=a.before(this._lazyBind,this.once.bind(this)),this.complexPath&&this._lazyBind()}function o(t,e,r,n){if(arguments.length>5)throw Error("baobab.Cursor."+t+": too many arguments.");if(arguments.length<4&&(n=r,r=[]),r=r||[],"splice"===t&&!u.Splicer(n)){if(!u.Array(n))throw Error("baobab.Cursor.splice: incorrect value.");n=[n]}if(e&&!e(n))throw Error("baobab.Cursor."+t+": incorrect value.");var o=[].concat(r),i=a.solvePath(this.get(),o,this.tree);if(!i)throw Error("baobab.Cursor."+t+": could not solve dynamic path.");var s={};s["$"+t]=n;var h=a.pathObject(i,s);return h}function i(t,e){n.prototype[t]=function(){var r=o.bind(this,t,e).apply(this,arguments);return this.update(r)}}var s=t("emmett"),a=t("./helpers.js"),u=(t("../defaults.js"),t("./type.js"));a.inherits(n,s),n.prototype.isRoot=function(){return!this.path.length},n.prototype.isLeaf=function(){return u.Primitive(this.get())},n.prototype.isBranch=function(){return!this.isLeaf()&&!this.isRoot()},n.prototype.root=function(){return this.tree.root()},n.prototype.select=function(t){if(arguments.length>1&&(t=a.arrayOf(arguments)),!u.Path(t))throw Error("baobab.Cursor.select: invalid path.");return this.tree.select(this.path.concat(t))},n.prototype.up=function(){return this.solvedPath&&this.solvedPath.length?this.tree.select(this.path.slice(0,-1)):null},n.prototype.left=function(){var t=+this.solvedPath[this.solvedPath.length-1];if(isNaN(t))throw Error("baobab.Cursor.left: cannot go left on a non-list type.");return t?this.tree.select(this.solvedPath.slice(0,-1).concat(t-1)):null},n.prototype.leftmost=function(){var t=+this.solvedPath[this.solvedPath.length-1];if(isNaN(t))throw Error("baobab.Cursor.leftmost: cannot go left on a non-list type.");return this.tree.select(this.solvedPath.slice(0,-1).concat(0))},n.prototype.right=function(){var t=+this.solvedPath[this.solvedPath.length-1];if(isNaN(t))throw Error("baobab.Cursor.right: cannot go right on a non-list type.");return t+1===this.up().get().length?null:this.tree.select(this.solvedPath.slice(0,-1).concat(t+1))},n.prototype.rightmost=function(){var t=+this.solvedPath[this.solvedPath.length-1];if(isNaN(t))throw Error("baobab.Cursor.right: cannot go right on a non-list type.");var e=this.up().get();return this.tree.select(this.solvedPath.slice(0,-1).concat(e.length-1))},n.prototype.down=function(){+this.solvedPath[this.solvedPath.length-1];return this.get()instanceof Array?this.tree.select(this.solvedPath.concat(0)):null},n.prototype.get=function(t){arguments.length>1&&(t=a.arrayOf(arguments));var e=this.solvedPath.concat([].concat(t||0===t?t:[]));return a.getIn(this.tree.data,e,this.tree)},i("set"),i("apply",u.Function),i("chain",u.Function),i("push"),i("unshift"),i("merge",u.Object),i("splice"),n.prototype.unset=function(t){if(void 0===t&&this.isRoot())throw Error("baobab.Cursor.unset: cannot remove root node.");var e=o.bind(this,"unset",null).apply(this,[t,!0]);return this.update(e)},n.prototype.update=function(t,e){if(arguments.length<2)return this.tree.stack(a.pathObject(this.solvedPath,t)),this;var r=[].concat(t),n=a.solvePath(this.get(),r,this.tree);if(!n)throw Error("baobab.Cursor.update: could not solve dynamic path.");return this.tree.stack(a.pathObject(this.solvedPath.concat(n),e)),this},n.prototype.startRecording=function(t){if(t=t||5,1>t)throw Error("baobab.Cursor.startRecording: invalid maximum number of records.");return this.archive?this:(this._lazyBind(),this.archive=a.archive(t),this.recording=!0,this)},n.prototype.stopRecording=function(){return this.recording=!1,this},n.prototype.undo=function(t){if(t=t||1,!this.recording)throw Error("baobab.Cursor.undo: cursor is not recording.");if(!u.PositiveInteger(t))throw Error("baobab.Cursor.undo: expecting a positive integer.");var e=this.archive.back(t);if(!e)throw Error("boabab.Cursor.undo: cannot find a relevant record ("+t+" back).");return this.undoing=!0,this.set(e)},n.prototype.hasHistory=function(){return!(!this.archive||!this.archive.get().length)},n.prototype.getHistory=function(){return this.archive?this.archive.get():[]},n.prototype.clearHistory=function(){return this.archive=null,this},n.prototype.release=function(){this.tree.off("update",this.updateHandler),this.hash&&delete this.tree._cursors[this.hash],delete this.tree,delete this.path,delete this.solvedPath,delete this.archive,this.kill()},n.prototype.toJSON=function(){return this.get()},n.prototype.toString=function(){return this._identity},e.exports=n},{"../defaults.js":2,"./helpers.js":7,"./type.js":9,emmett:3}],6:[function(t,e,r){function n(t){return t}function o(t,e){function r(){d&&(p=f.map(function(t){return s.solvePath(o.tree.data,t,o.tree)}))}var o=this,u=e.cursors,h=!1,c=a.Function(e.get)?e.get:n,l=null;if(!a.FacetCursors(u))throw Error("baobab.Facet: incorrect cursors mapping.");i.call(this),this.tree=t;var f=Object.keys(u).map(function(t){return u[t]}),p=f,d=f.some(a.ComplexPath);this.updateHandler=function(t){s.solveUpdate(t.data.log,p)&&(h=!1,o.emit("update"))},r(),this.tree.on("update",this.updateHandler),this.get=function(){if(h)return l;var e={};for(var r in u)e[r]=t.get(u[r]);return l=c.call(null,e),h=!0,l}}var i=t("emmett"),s=t("./helpers.js"),a=t("./type.js");s.inherits(o,i),o.prototype.release=function(){this.tree.off("update",this.updateHandler),this.tree=null,this.kill()},e.exports=o},{"./helpers.js":7,"./type.js":9,emmett:3}],7:[function(t,e,r){(function(r){function n(t){return Array.prototype.slice.call(t)}function o(t,e){return function(){t(),e.apply(null,arguments)}}function i(t,e,r){var o=n(arguments).slice(3);return e=+e,r=+r,t.slice(0,e).concat(t.slice(e+r).concat(o))}function s(t,e){var r,n={};for(r in t)n[r]=t[r];for(r in e)n[r]=e[r];return n}function a(t){var e=t.source,r="";return t.global&&(r+="g"),t.multiline&&(r+="m"),t.ignoreCase&&(r+="i"),t.sticky&&(r+="y"),t.unicode&&(r+="u"),new RegExp(e,r)}function u(t,e){if(!e||"object"!=typeof e||e instanceof Error||"ArrayBuffer"in r&&e instanceof ArrayBuffer)return e;if(w.Array(e)){if(t){var n,o,i=[];for(n=0,o=e.length;o>n;n++)i.push(P(e[n]));return i}return e.slice(0)}if(w.Date(e))return new Date(e.getTime());if(e instanceof RegExp)return a(e);if(w.Object(e)){var s,u={};e.constructor&&e.constructor!==Object&&(u=Object.create(e.constructor.prototype));for(s in e)e.hasOwnProperty(s)&&(u[s]=t?P(e[s]):e[s]);return u}return e}function h(t,e){return function(r){return e(t(r))}}function c(t,e){var r,n;for(r=0,n=t.length;n>r;r++)if(e(t[r]))return t[r]}function l(t,e){var r,n;for(r=0,n=t.length;n>r;r++)if(e(t[r]))return r;return-1}function f(t,e){var r,n=!0;if(!t)return!1;for(r in e)if(w.Object(e[r]))n=n&&f(t[r],e[r]);else if(w.Array(e[r]))n=n&&!!~e[r].indexOf(t[r]);else if(t[r]!==e[r])return!1;return n}function d(t,e){return c(t,function(t){return f(t,e)})}function y(t,e){return l(t,function(t){return f(t,e)})}function v(t,e,r){e=e||[];var n,o,i,s=t;for(o=0,i=e.length;i>o;o++){if(!s)return;if("function"==typeof e[o]){if(!w.Array(s))return;s=c(s,e[o])}else if("object"==typeof e[o])if(r&&"$cursor"in e[o]){if(!w.Path(e[o].$cursor))throw Error("baobab.getIn: $cursor path must be an array.");n=r.get(e[o].$cursor),s=s[n]}else{if(!w.Array(s))return;s=d(s,e[o])}else s=s[e[o]]}return s}function g(t,e,r){var n,o,i,s=[],a=t;for(o=0,i=e.length;i>o;o++){if(!a)return null;if("function"==typeof e[o]){if(!w.Array(a))return;n=l(a,e[o]),s.push(n),a=a[n]}else if("object"==typeof e[o])if(r&&"$cursor"in e[o]){if(!w.Path(e[o].$cursor))throw Error("baobab.getIn: $cursor path must be an array.");p=r.get(e[o].$cursor),s.push(p),a=a[p]}else{if(!w.Array(a))return;n=y(a,e[o]),s.push(n),a=a[n]}else s.push(e[o]),a=a[e[o]]||{}}return s}function b(t,e){var r,n,o,i,s,a,u,h,c;for(r=0,i=e.length;i>r;r++)for(u=e[r],n=0,s=t.length;s>n;n++)for(h=t[n],o=0,a=h.length;a>o&&(c=h[o],c==u[o]);o++)if(o+1===a||o+1===u.length)return!0;return!1}function m(t,e){var r,n=t.length,o={},i=o;for(n||(o=e),r=0;n>r;r++)i[t[r]]=r+1===n?e:{},i=i[t[r]];return o}function j(t,e){t.super_=e;var r=function(){};r.prototype=e.prototype,t.prototype=new r,t.prototype.constructor=t}function _(t){var e=[];return{add:function(r){e.unshift(r),e.length>t&&(e.length=t)},back:function(t){var r=e[t-1];return r&&(e=e.slice(t)),r},get:function(){return e}}}var w=t("./type.js"),$=u.bind(null,!1),P=u.bind(null,!0);e.exports={archive:_,arrayOf:n,before:o,deepClone:P,shallowClone:$,shallowMerge:s,compose:h,getIn:v,inherits:j,pathObject:m,solvePath:g,solveUpdate:b,splice:i}}).call(this,"undefined"!=typeof global?global:"undefined"!=typeof self?self:"undefined"!=typeof window?window:{})},{"./type.js":9}],8:[function(t,e,r){function n(t,e,r){a.forEach(function(e){r!==e&&delete t[e]}),t[r]=e[r]}function o(t,e){var r,u=i.shallowClone(e||{});a.forEach(function(e){t[e]&&n(u,t,e)}),t.$chain&&(a.slice(0,-1).forEach(function(t){delete u[t]}),u.$apply=u.$apply?i.compose(u.$apply,t.$chain):t.$chain),(t.$splice||u.$splice)&&(u.$splice=[].concat(u.$splice||[]).concat(t.$splice||[])),(t.$push||u.$push)&&(u.$push=[].concat(u.$push||[]).concat(t.$push||[])),(t.$unshift||u.$unshift)&&(u.$unshift=[].concat(t.$unshift||[]).concat(u.$unshift||[]));for(r in t)s.Object(t[r])?u[r]=o(t[r],u[r]):"$"!==r[0]&&(u[r]=t[r]);return u}var i=t("./helpers.js"),s=t("./type.js"),a=["$unset","$set","$merge","$apply"];e.exports=o},{"./helpers.js":7,"./type.js":9}],9:[function(t,e,r){function n(t,e){return e.some(function(e){return o[e](t)})}var o={};o.Array=function(t){return Array.isArray(t)},o.Object=function(t){return t&&"object"==typeof t&&!Array.isArray(t)&&!(t instanceof Function)},o.String=function(t){return"string"==typeof t},o.Number=function(t){return"number"==typeof t},o.PositiveInteger=function(t){return"number"==typeof t&&t>0&&t%1===0},o.Function=function(t){return"function"==typeof t},o.Primitive=function(t){return"string"==typeof t||"number"==typeof t||"boolean"==typeof t},o.Date=function(t){return t instanceof Date},o.NonScalar=function(t){return o.Object(t)||o.Array(t)},o.Splicer=function(t){return o.Array(t)&&t.every(o.Array)},o.Path=function(t){var e=["String","Number","Function","Object"];return o.Array(t)?t.every(function(t){return n(t,e)}):n(t,e)},o.ComplexPath=function(t){return t.some(function(t){return n(t,["Object","Function"])})},o.FacetCursors=function(e){return o.Object(e)?Object.keys(e).every(function(r){var n=e[r];return o.Path(n)||o.Function(n)||n instanceof t("./cursor.js")}):!1},o.FacetFacets=function(e){return o.Object(e)?Object.keys(e).every(function(r){var n=e[r];return"string"==typeof n||n instanceof t("./facet.js")}):!1},e.exports=o},{"./cursor.js":5,"./facet.js":6}],10:[function(t,e,r){function n(t,e){var r=new Error("baobab.update: "+e+" at path /"+t.slice(1).join("/"));return r.path=t,r}var o=t("./helpers.js"),i=t("./type.js");e.exports=function(t,e,r){if(r=r||{},!i.Object(t)&&!i.Array(t))throw Error("baobab.update: invalid target.");var s={};t={root:o.shallowClone(t)};var a=function(t,e,r,u){r=r||["root"];var h,c,l,f=r.join("|λ|"),p=r[r.length-1],d=Object.keys(e).some(function(t){return!!~["$set","$push","$unshift","$splice","$unset","$merge","$apply"].indexOf(t)});if(d){s[f]=!0;for(c in e){if("$unset"===c){var y=r[r.length-2];if(!i.Object(u[y]))throw n(r.slice(0,-1),"using command $unset on a non-object");u[y]=o.shallowClone(t),delete u[y][p];break}if("$set"===c){l=e.$set,t[p]=l;break}if("$apply"===c){if(h=e.$apply,"function"!=typeof h)throw n(r,"using command $apply with a non function");t[p]=h.call(null,t[p]);break}if("$merge"===c){if(l=e.$merge,!i.Object(t[p])||!i.Object(l))throw n(r,"using command $merge with a non object");t[p]=o.shallowMerge(t[p],l);break}if("$splice"===c){if(l=e.$splice,!i.Array(t[p]))throw n(r,"using command $push to a non array");l.forEach(function(e){t[p]=o.splice.apply(null,[t[p]].concat(e))})}if("$push"===c){if(l=e.$push,!i.Array(t[p]))throw n(r,"using command $push to a non array");t[p]=t[p].concat(l)}if("$unshift"===c){if(l=e.$unshift,!i.Array(t[p]))throw n(r,"using command $unshift to a non array");t[p]=[].concat(l).concat(t[p])}}}else for(c in e)t[p][c]="undefined"==typeof t[p][c]?{}:o.shallowClone(t[p][c]),a(t[p],e[c],r.concat(c),t)};return a(t,e),{data:t.root,log:Object.keys(s).map(function(t){return t.split("|λ|").slice(1)})}}},{"./helpers.js":7,"./type.js":9}]},{},[1])(1)}); \ No newline at end of file +!function(t){if("object"==typeof exports&&"undefined"!=typeof module)module.exports=t();else if("function"==typeof define&&define.amd)define([],t);else{var e;e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:this,e.Baobab=t()}}(function(){var t;return function e(t,r,n){function o(s,a){if(!r[s]){if(!t[s]){var u="function"==typeof require&&require;if(!a&&u)return u(s,!0);if(i)return i(s,!0);var h=new Error("Cannot find module '"+s+"'");throw h.code="MODULE_NOT_FOUND",h}var c=r[s]={exports:{}};t[s][0].call(c.exports,function(e){var r=t[s][1][e];return o(r?r:e)},c,c.exports,e,t,r,n)}return r[s].exports}for(var i="function"==typeof require&&require,s=0;sn;n++)t[n].fn!==e&&o.push(t[n]);return o}var s={once:"boolean",scope:"object"},a=0,u=function(){this._enabled=!0,this.unbindAll()};u.prototype.unbindAll=function(){return this._handlers={},this._handlersAll=[],this._handlersComplex=[],this},u.prototype.on=function(t,e,r){var n,i,u,h,c,l,f;if(o(t)){for(h in t)this.on(h,t[h],e);return this}for("function"==typeof t&&(r=e,e=t,t=null),c=[].concat(t),n=0,i=c.length;i>n;n++){if(h=c[n],f={order:a++,fn:e},"string"==typeof h)this._handlers[h]||(this._handlers[h]=[]),l=this._handlers[h];else if(h instanceof RegExp)l=this._handlersComplex,f.pattern=h;else{if(null!==h)throw Error("Emitter.on: invalid event.");l=this._handlersAll}for(u in r||{})s[u]&&(f[u]=r[u]);f.once&&(f.parent=l),l.push(f)}return this},u.prototype.once=function(){var t=Array.prototype.slice.call(arguments),r=t.length-1;return o(t[r])&&t.length>1?t[r]=e(t[r],{once:!0}):t.push({once:!0}),this.on.apply(this,t)},u.prototype.off=function(t,e){var r,n,s,a;if(1===arguments.length&&"function"==typeof t){e=arguments[0];for(s in this._handlers)this._handlers[s]=i(this._handlers[s],e),0===this._handlers[s].length&&delete this._handlers[s];this._handlersAll=i(this._handlersAll,e),this._handlersComplex=i(this._handlersComplex,e)}else if(1===arguments.length&&"string"==typeof t)delete this._handlers[t];else if(2===arguments.length){var u=[].concat(t);for(r=0,n=u.length;n>r;r++)a=u[r],this._handlers[a]=i(this._handlers[a],e),0===(this._handlers[a]||[]).length&&delete this._handlers[a]}else if(o(t))for(s in t)this.off(s,t[s]);return this},u.prototype.listeners=function(t){var e,r,n,o=this._handlersAll||[],i=!1;if(!t)throw Error("Emitter.listeners: no event provided.");for(o=o.concat(this._handlers[t]||[]),r=0,n=this._handlersComplex.length;n>r;r++)e=this._handlersComplex[r],~t.search(e.pattern)&&(i=!0,o.push(e));return this._handlersAll.length||i?o.sort(function(t,e){return t.order-e.order}):o.slice(0)},u.prototype.emit=function(t,e){if(!this._enabled)return this;if(o(t)){for(var r in t)this.emit(r,t[r]);return this}var n,i,s,a,u,h,c,l=[].concat(t),f=[];for(a=0,h=l.length;h>a;a++){for(i=this.listeners(l[a]),u=0,c=i.length;c>u;u++)s=i[u],n={type:l[a],target:this},arguments.length>1&&(n.data=e),s.fn.call("scope"in s?s.scope:this,n),s.once&&f.push(s);for(u=f.length-1;u>=0;u--)f[u].parent.splice(f[u].parent.indexOf(f[u]),1)}return this},u.prototype.kill=function(){this.unbindAll(),this._handlers=null,this._handlersAll=null,this._handlersComplex=null,this._enabled=!1},u.prototype.disable=function(){return this._enabled=!1,this},u.prototype.enable=function(){return this._enabled=!0,this},u.version="3.0.0","undefined"!=typeof n?("undefined"!=typeof r&&r.exports&&(n=r.exports=u),n.Emitter=u):"function"==typeof t&&t.amd?t("emmett",[],function(){return u}):this.Emitter=u}).call(this)},{}],4:[function(t,e,r){function n(t){return t+"$"+(new Date).getTime()+(""+Math.random()).replace("0.","")}function o(t,e){function r(t){this[t]=function(){var e=this.root[t].apply(this.root,arguments);return e instanceof i?this:e}}if(arguments.length<1&&(t={}),!(this instanceof o))return new o(t,e);if(!f.Object(t)&&!f.Array(t))throw Error("Baobab: invalid data.");if(s.call(this),this.options=u.shallowMerge(l,e),this._transaction={},this._future=void 0,this._cursors={},this._identity="[object Baobab]",this.data=u.deepClone(t),this.root=this.select([]),this.facets={},["get","set","unset","update"].forEach(r.bind(this)),!f.Object(this.options.facets))throw Error("Baobab: invalid facets.");for(var n in this.options.facets)this.addFacet(n,this.options.facets[n])}var i=t("./cursor.js"),s=t("emmett"),a=t("./facet.js"),u=t("./helpers.js"),h=t("./update.js"),c=t("./merge.js"),l=t("../defaults.js"),f=t("./type.js");u.inherits(o,s),o.prototype.addFacet=function(t,e){return this.facets[t]=this.createFacet(e),this},o.prototype.createFacet=function(t){return new a(this,t)},o.prototype.select=function(t){if(!t)throw Error("Baobab.select: invalid path.");if(arguments.length>1&&(t=u.arrayOf(arguments)),!f.Path(t))throw Error("Baobab.select: invalid path.");t=[].concat(t);var e,r=f.ComplexPath(t);r&&(e=u.solvePath(this.data,t,this));var o=t.map(function(t){return f.Function(t)?n("fn"):f.Object(t)?n("ob"):t}).join("|λ|");if(this._cursors[o])return this._cursors[o];var s=new i(this,t,e,o);return this._cursors[o]=s,s},o.prototype.stack=function(t){var e=this;if(!f.Object(t))throw Error("Baobab.update: wrong specification.");return this._transaction=c(t,this._transaction),this.options.autoCommit?this.options.asynchronous?(this._future||(this._future=setTimeout(e.commit.bind(e,null),0)),this):this.commit():this},o.prototype.commit=function(){var t=h(this.data,this._transaction,this.options),e=this.data;this._transaction={},this._future&&(this._future=clearTimeout(this._future));var r=this.options.validate,n=this.options.validationBehavior;if("function"==typeof r){var o=r.call(this,e,t.data,t.log);if(o instanceof Error&&(this.emit("invalid",{error:o}),"rollback"===n))return this}return this.data=t.data,this.emit("update",{log:t.log,previousState:e}),this},o.prototype.release=function(){var t;delete this.data,delete this._transaction;for(t in this._cursors)this._cursors[t].release();delete this._cursors;for(t in this.facets)this.facets[t].release();delete this.facets,this.kill()},o.prototype.toJSON=function(){return this.get()},o.prototype.toString=function(){return this._identity},e.exports=o},{"../defaults.js":2,"./cursor.js":5,"./facet.js":6,"./helpers.js":7,"./merge.js":8,"./type.js":9,"./update.js":10,emmett:3}],5:[function(t,e,r){function n(t,e,r,n){function o(t){if(i.recording&&!i.undoing){var e=a.getIn(t,i.solvedPath,i.tree),r=a.deepClone(e);i.archive.add(r)}return i.undoing=!1,i.emit("update")}var i=this;s.call(this),e=e||[],this.tree=t,this.path=e,this.hash=n,this.archive=null,this.recording=!1,this.undoing=!1,this._identity="[object Cursor]",this.complexPath=!!r,this.solvedPath=this.complexPath?r:this.path,this.relevant=void 0!==this.get(),this.updateHandler=function(t){var e=t.data.log,r=t.data.previousState,n=!1;if(i.complexPath&&(i.solvedPath=a.solvePath(i.tree.data,i.path,i.tree)),!i.path.length)return o(r);i.solvedPath&&(n=a.solveUpdate(e,[i.solvedPath]));var s=void 0!==i.get();i.relevant?s&&n?o(r):s||(i.emit("irrelevant"),i.relevant=!1):s&&n&&(i.emit("relevant"),o(r),i.relevant=!0)};var u=!1;this._lazyBind=function(){u||(u=!0,i.tree.on("update",i.updateHandler))},this.on=a.before(this._lazyBind,this.on.bind(this)),this.once=a.before(this._lazyBind,this.once.bind(this)),this.complexPath&&this._lazyBind()}function o(t,e,r,n){if(arguments.length>5)throw Error("baobab.Cursor."+t+": too many arguments.");if(arguments.length<4&&(n=r,r=[]),r=r||[],"splice"===t&&!u.Splicer(n)){if(!u.Array(n))throw Error("baobab.Cursor.splice: incorrect value.");n=[n]}if(e&&!e(n))throw Error("baobab.Cursor."+t+": incorrect value.");var o=[].concat(r),i=a.solvePath(this.get(),o,this.tree);if(!i)throw Error("baobab.Cursor."+t+": could not solve dynamic path.");var s={};s["$"+t]=n;var h=a.pathObject(i,s);return h}function i(t,e){n.prototype[t]=function(){var r=o.bind(this,t,e).apply(this,arguments);return this.update(r)}}var s=t("emmett"),a=t("./helpers.js"),u=(t("../defaults.js"),t("./type.js"));a.inherits(n,s),n.prototype.isRoot=function(){return!this.path.length},n.prototype.isLeaf=function(){return u.Primitive(this.get())},n.prototype.isBranch=function(){return!this.isLeaf()&&!this.isRoot()},n.prototype.root=function(){return this.tree.root()},n.prototype.select=function(t){if(arguments.length>1&&(t=a.arrayOf(arguments)),!u.Path(t))throw Error("baobab.Cursor.select: invalid path.");return this.tree.select(this.path.concat(t))},n.prototype.up=function(){return this.solvedPath&&this.solvedPath.length?this.tree.select(this.path.slice(0,-1)):null},n.prototype.left=function(){var t=+this.solvedPath[this.solvedPath.length-1];if(isNaN(t))throw Error("baobab.Cursor.left: cannot go left on a non-list type.");return t?this.tree.select(this.solvedPath.slice(0,-1).concat(t-1)):null},n.prototype.leftmost=function(){var t=+this.solvedPath[this.solvedPath.length-1];if(isNaN(t))throw Error("baobab.Cursor.leftmost: cannot go left on a non-list type.");return this.tree.select(this.solvedPath.slice(0,-1).concat(0))},n.prototype.right=function(){var t=+this.solvedPath[this.solvedPath.length-1];if(isNaN(t))throw Error("baobab.Cursor.right: cannot go right on a non-list type.");return t+1===this.up().get().length?null:this.tree.select(this.solvedPath.slice(0,-1).concat(t+1))},n.prototype.rightmost=function(){var t=+this.solvedPath[this.solvedPath.length-1];if(isNaN(t))throw Error("baobab.Cursor.right: cannot go right on a non-list type.");var e=this.up().get();return this.tree.select(this.solvedPath.slice(0,-1).concat(e.length-1))},n.prototype.down=function(){+this.solvedPath[this.solvedPath.length-1];return this.get()instanceof Array?this.tree.select(this.solvedPath.concat(0)):null},n.prototype.get=function(t){arguments.length>1&&(t=a.arrayOf(arguments));var e=this.solvedPath.concat([].concat(t||0===t?t:[]));return a.getIn(this.tree.data,e,this.tree)},i("set"),i("apply",u.Function),i("chain",u.Function),i("push"),i("unshift"),i("merge",u.Object),i("splice"),n.prototype.unset=function(t){if(void 0===t&&this.isRoot())throw Error("baobab.Cursor.unset: cannot remove root node.");var e=o.bind(this,"unset",null).apply(this,[t,!0]);return this.update(e)},n.prototype.update=function(t,e){if(arguments.length<2)return this.tree.stack(a.pathObject(this.solvedPath,t)),this;var r=[].concat(t),n=a.solvePath(this.get(),r,this.tree);if(!n)throw Error("baobab.Cursor.update: could not solve dynamic path.");return this.tree.stack(a.pathObject(this.solvedPath.concat(n),e)),this},n.prototype.startRecording=function(t){if(t=t||5,1>t)throw Error("baobab.Cursor.startRecording: invalid maximum number of records.");return this.archive?this:(this._lazyBind(),this.archive=a.archive(t),this.recording=!0,this)},n.prototype.stopRecording=function(){return this.recording=!1,this},n.prototype.undo=function(t){if(t=t||1,!this.recording)throw Error("baobab.Cursor.undo: cursor is not recording.");if(!u.PositiveInteger(t))throw Error("baobab.Cursor.undo: expecting a positive integer.");var e=this.archive.back(t);if(!e)throw Error("boabab.Cursor.undo: cannot find a relevant record ("+t+" back).");return this.undoing=!0,this.set(e)},n.prototype.hasHistory=function(){return!(!this.archive||!this.archive.get().length)},n.prototype.getHistory=function(){return this.archive?this.archive.get():[]},n.prototype.clearHistory=function(){return this.archive=null,this},n.prototype.release=function(){this.tree.off("update",this.updateHandler),this.hash&&delete this.tree._cursors[this.hash],delete this.tree,delete this.path,delete this.solvedPath,delete this.archive,this.kill()},n.prototype.toJSON=function(){return this.get()},n.prototype.toString=function(){return this._identity},e.exports=n},{"../defaults.js":2,"./helpers.js":7,"./type.js":9,emmett:3}],6:[function(t,e,r){function n(t,e){function r(){d&&(p=f.map(function(t){return s.solvePath(n.tree.data,t,n.tree)}))}var n=this,u=e.cursors,h=!1,c=e.get,l=null;if(!a.FacetCursors(u))throw Error("baobab.Facet: incorrect cursors mapping.");o.call(this),this.tree=t,this.cursors={};var f=Object.keys(u).map(function(e){return u[e]instanceof i?(this.cursors[e]=u[e],u[e].path):(this.cursors[e]=t.select(u[e]),u[e])},this),p=f,d=f.some(a.ComplexPath);this.updateHandler=function(t){s.solveUpdate(t.data.log,p)&&(h=!1,n.emit("update"))},r(),this.tree.on("update",this.updateHandler),this.get=function(){if(h)return l;var t={};for(var e in n.cursors)t[e]=n.cursors[e].get();return l="function"==typeof c?c.call(null,t):t,h=!0,l}}var o=t("emmett"),i=t("./cursor.js"),s=t("./helpers.js"),a=t("./type.js");s.inherits(n,o),n.prototype.release=function(){this.tree.off("update",this.updateHandler),this.tree=null,this.kill()},e.exports=n},{"./cursor.js":5,"./helpers.js":7,"./type.js":9,emmett:3}],7:[function(t,e,r){(function(r){function n(t){return Array.prototype.slice.call(t)}function o(t,e){return function(){t(),e.apply(null,arguments)}}function i(t,e,r){var o=n(arguments).slice(3);return e=+e,r=+r,t.slice(0,e).concat(t.slice(e+r).concat(o))}function s(t,e){var r,n={};for(r in t)n[r]=t[r];for(r in e)n[r]=e[r];return n}function a(t){var e=t.source,r="";return t.global&&(r+="g"),t.multiline&&(r+="m"),t.ignoreCase&&(r+="i"),t.sticky&&(r+="y"),t.unicode&&(r+="u"),new RegExp(e,r)}function u(t,e){if(!e||"object"!=typeof e||e instanceof Error||"ArrayBuffer"in r&&e instanceof ArrayBuffer)return e;if(w.Array(e)){if(t){var n,o,i=[];for(n=0,o=e.length;o>n;n++)i.push(P(e[n]));return i}return e.slice(0)}if(w.Date(e))return new Date(e.getTime());if(e instanceof RegExp)return a(e);if(w.Object(e)){var s,u={};e.constructor&&e.constructor!==Object&&(u=Object.create(e.constructor.prototype));for(s in e)e.hasOwnProperty(s)&&(u[s]=t?P(e[s]):e[s]);return u}return e}function h(t,e){return function(r){return e(t(r))}}function c(t,e){var r,n;for(r=0,n=t.length;n>r;r++)if(e(t[r]))return t[r]}function l(t,e){var r,n;for(r=0,n=t.length;n>r;r++)if(e(t[r]))return r;return-1}function f(t,e){var r,n=!0;if(!t)return!1;for(r in e)if(w.Object(e[r]))n=n&&f(t[r],e[r]);else if(w.Array(e[r]))n=n&&!!~e[r].indexOf(t[r]);else if(t[r]!==e[r])return!1;return n}function d(t,e){return c(t,function(t){return f(t,e)})}function y(t,e){return l(t,function(t){return f(t,e)})}function v(t,e,r){e=e||[];var n,o,i,s=t;for(o=0,i=e.length;i>o;o++){if(!s)return;if("function"==typeof e[o]){if(!w.Array(s))return;s=c(s,e[o])}else if("object"==typeof e[o])if(r&&"$cursor"in e[o]){if(!w.Path(e[o].$cursor))throw Error("baobab.getIn: $cursor path must be an array.");n=r.get(e[o].$cursor),s=s[n]}else{if(!w.Array(s))return;s=d(s,e[o])}else s=s[e[o]]}return s}function g(t,e,r){var n,o,i,s=[],a=t;for(o=0,i=e.length;i>o;o++){if(!a)return null;if("function"==typeof e[o]){if(!w.Array(a))return;n=l(a,e[o]),s.push(n),a=a[n]}else if("object"==typeof e[o])if(r&&"$cursor"in e[o]){if(!w.Path(e[o].$cursor))throw Error("baobab.getIn: $cursor path must be an array.");p=r.get(e[o].$cursor),s.push(p),a=a[p]}else{if(!w.Array(a))return;n=y(a,e[o]),s.push(n),a=a[n]}else s.push(e[o]),a=a[e[o]]||{}}return s}function b(t,e){var r,n,o,i,s,a,u,h,c;for(r=0,i=e.length;i>r;r++)for(u=e[r],n=0,s=t.length;s>n;n++)for(h=t[n],o=0,a=h.length;a>o&&(c=h[o],c==u[o]);o++)if(o+1===a||o+1===u.length)return!0;return!1}function m(t,e){var r,n=t.length,o={},i=o;for(n||(o=e),r=0;n>r;r++)i[t[r]]=r+1===n?e:{},i=i[t[r]];return o}function j(t,e){t.super_=e;var r=function(){};r.prototype=e.prototype,t.prototype=new r,t.prototype.constructor=t}function _(t){var e=[];return{add:function(r){e.unshift(r),e.length>t&&(e.length=t)},back:function(t){var r=e[t-1];return r&&(e=e.slice(t)),r},get:function(){return e}}}var w=t("./type.js"),$=u.bind(null,!1),P=u.bind(null,!0);e.exports={archive:_,arrayOf:n,before:o,deepClone:P,shallowClone:$,shallowMerge:s,compose:h,getIn:v,inherits:j,pathObject:m,solvePath:g,solveUpdate:b,splice:i}}).call(this,"undefined"!=typeof global?global:"undefined"!=typeof self?self:"undefined"!=typeof window?window:{})},{"./type.js":9}],8:[function(t,e,r){function n(t,e,r){a.forEach(function(e){r!==e&&delete t[e]}),t[r]=e[r]}function o(t,e){var r,u=i.shallowClone(e||{});a.forEach(function(e){t[e]&&n(u,t,e)}),t.$chain&&(a.slice(0,-1).forEach(function(t){delete u[t]}),u.$apply=u.$apply?i.compose(u.$apply,t.$chain):t.$chain),(t.$splice||u.$splice)&&(u.$splice=[].concat(u.$splice||[]).concat(t.$splice||[])),(t.$push||u.$push)&&(u.$push=[].concat(u.$push||[]).concat(t.$push||[])),(t.$unshift||u.$unshift)&&(u.$unshift=[].concat(t.$unshift||[]).concat(u.$unshift||[]));for(r in t)s.Object(t[r])?u[r]=o(t[r],u[r]):"$"!==r[0]&&(u[r]=t[r]);return u}var i=t("./helpers.js"),s=t("./type.js"),a=["$unset","$set","$merge","$apply"];e.exports=o},{"./helpers.js":7,"./type.js":9}],9:[function(t,e,r){function n(t,e){return e.some(function(e){return o[e](t)})}var o={};o.Array=function(t){return Array.isArray(t)},o.Object=function(t){return t&&"object"==typeof t&&!Array.isArray(t)&&!(t instanceof Function)},o.String=function(t){return"string"==typeof t},o.Number=function(t){return"number"==typeof t},o.PositiveInteger=function(t){return"number"==typeof t&&t>0&&t%1===0},o.Function=function(t){return"function"==typeof t},o.Primitive=function(t){return"string"==typeof t||"number"==typeof t||"boolean"==typeof t},o.Date=function(t){return t instanceof Date},o.NonScalar=function(t){return o.Object(t)||o.Array(t)},o.Splicer=function(t){return o.Array(t)&&t.every(o.Array)},o.Path=function(t){var e=["String","Number","Function","Object"];return o.Array(t)?t.every(function(t){return n(t,e)}):n(t,e)},o.ComplexPath=function(t){return t.some(function(t){return n(t,["Object","Function"])})},o.FacetCursors=function(e){return o.Object(e)?Object.keys(e).every(function(r){var n=e[r];return o.Path(n)||o.Function(n)||n instanceof t("./cursor.js")}):!1},o.FacetFacets=function(e){return o.Object(e)?Object.keys(e).every(function(r){var n=e[r];return"string"==typeof n||n instanceof t("./facet.js")}):!1},e.exports=o},{"./cursor.js":5,"./facet.js":6}],10:[function(t,e,r){function n(t,e){var r=new Error("baobab.update: "+e+" at path /"+t.slice(1).join("/"));return r.path=t,r}var o=t("./helpers.js"),i=t("./type.js");e.exports=function(t,e,r){if(r=r||{},!i.Object(t)&&!i.Array(t))throw Error("baobab.update: invalid target.");var s={};t={root:o.shallowClone(t)};var a=function(t,e,r,u){r=r||["root"];var h,c,l,f=r.join("|λ|"),p=r[r.length-1],d=Object.keys(e).some(function(t){return!!~["$set","$push","$unshift","$splice","$unset","$merge","$apply"].indexOf(t)});if(d){s[f]=!0;for(c in e){if("$unset"===c){var y=r[r.length-2];if(!i.Object(u[y]))throw n(r.slice(0,-1),"using command $unset on a non-object");u[y]=o.shallowClone(t),delete u[y][p];break}if("$set"===c){l=e.$set,t[p]=l;break}if("$apply"===c){if(h=e.$apply,"function"!=typeof h)throw n(r,"using command $apply with a non function");t[p]=h.call(null,t[p]);break}if("$merge"===c){if(l=e.$merge,!i.Object(t[p])||!i.Object(l))throw n(r,"using command $merge with a non object");t[p]=o.shallowMerge(t[p],l);break}if("$splice"===c){if(l=e.$splice,!i.Array(t[p]))throw n(r,"using command $push to a non array");l.forEach(function(e){t[p]=o.splice.apply(null,[t[p]].concat(e))})}if("$push"===c){if(l=e.$push,!i.Array(t[p]))throw n(r,"using command $push to a non array");t[p]=t[p].concat(l)}if("$unshift"===c){if(l=e.$unshift,!i.Array(t[p]))throw n(r,"using command $unshift to a non array");t[p]=[].concat(l).concat(t[p])}}}else for(c in e)t[p][c]="undefined"==typeof t[p][c]?{}:o.shallowClone(t[p][c]),a(t[p],e[c],r.concat(c),t)};return a(t,e),{data:t.root,log:Object.keys(s).map(function(t){return t.split("|λ|").slice(1)})}}},{"./helpers.js":7,"./type.js":9}]},{},[1])(1)}); \ No newline at end of file diff --git a/src/facet.js b/src/facet.js index 777d29a..6f405e1 100644 --- a/src/facet.js +++ b/src/facet.js @@ -5,19 +5,16 @@ * Facets enable the user to define views on a given Baobab tree. */ var EventEmitter = require('emmett'), + Cursor = require('./cursor.js'), helpers = require('./helpers.js'), type = require('./type.js'); -function identity(v) { - return v; -} - function Facet(tree, definition) { var self = this; var map = definition.cursors, solved = false, - solver = type.Function(definition.get) ? definition.get : identity, + solver = definition.get, data = null; if (!type.FacetCursors(map)) @@ -28,11 +25,19 @@ function Facet(tree, definition) { // Properties this.tree = tree; + this.cursors = {}; // Path solving var paths = Object.keys(map).map(function(k) { - return map[k]; - }); + if (map[k] instanceof Cursor) { + this.cursors[k] = map[k]; + return map[k].path; + } + else { + this.cursors[k] = tree.select(map[k]); + return map[k]; + } + }, this); var solvedPaths = paths, complex = paths.some(type.ComplexPath); @@ -62,10 +67,13 @@ function Facet(tree, definition) { // Solving var cursorsData = {}; - for (var k in map) - cursorsData[k] = tree.get(map[k]); + for (var k in self.cursors) + cursorsData[k] = self.cursors[k].get(); + + data = typeof solver === 'function' ? + solver.call(null, cursorsData) : + cursorsData; - data = solver.call(null, cursorsData); solved = true; return data; diff --git a/test/suites/baobab.js b/test/suites/baobab.js index 4998985..da9bfa9 100644 --- a/test/suites/baobab.js +++ b/test/suites/baobab.js @@ -163,7 +163,9 @@ describe('Baobab API', function() { user: 'Jack' } ], - currentProjectId: 1 + currentProjectId: 1, + value1: 'Hello', + value2: 'World' }, // Options @@ -202,6 +204,13 @@ describe('Baobab API', function() { facet.release(); }); + it('should fail when creating a facet from incorrect mappings.', function() { + + assert.throws(function() { + baobab.createFacet({cursors: ['wrong']}); + }, /mapping/); + }); + it('should fire correctly.', function() { var tree = new Baobab({list: [1, 2, 3], otherlist: [4, 5, 6], unrelated: 0}, {autoCommit: false}), list = tree.select('list'), @@ -312,6 +321,24 @@ describe('Baobab API', function() { assert.strictEqual(countF, 1); assert.strictEqual(countC, 2); }); + + it('should be possible to pass cursors directly to facets.', function() { + var cursor = baobab.select('value1'); + + var facet = baobab.createFacet({ + cursors: { + value1: cursor, + value2: ['value2'] + } + }); + + assert.deepEqual(facet.get(), { + value1: 'Hello', + value2: 'World' + }); + + facet.release(); + }); }); describe('Options', function() { From afb1e19cbbd2f8c905cb3c7f6279fbeddd817efc Mon Sep 17 00:00:00 2001 From: Yomguithereal Date: Mon, 20 Apr 2015 21:50:17 +0200 Subject: [PATCH 71/73] facet.refresh --- build/baobab.min.js | 2 +- src/facet.js | 89 ++++++++++++++++++++++++++----------------- src/type.js | 1 - test/suites/baobab.js | 19 +++++++++ 4 files changed, 73 insertions(+), 38 deletions(-) diff --git a/build/baobab.min.js b/build/baobab.min.js index 6620077..167f7ed 100644 --- a/build/baobab.min.js +++ b/build/baobab.min.js @@ -1,2 +1,2 @@ /* baobab.js - Version: 1.0.0-rc1 - Author: Yomguithereal (Guillaume Plique) */ -!function(t){if("object"==typeof exports&&"undefined"!=typeof module)module.exports=t();else if("function"==typeof define&&define.amd)define([],t);else{var e;e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:this,e.Baobab=t()}}(function(){var t;return function e(t,r,n){function o(s,a){if(!r[s]){if(!t[s]){var u="function"==typeof require&&require;if(!a&&u)return u(s,!0);if(i)return i(s,!0);var h=new Error("Cannot find module '"+s+"'");throw h.code="MODULE_NOT_FOUND",h}var c=r[s]={exports:{}};t[s][0].call(c.exports,function(e){var r=t[s][1][e];return o(r?r:e)},c,c.exports,e,t,r,n)}return r[s].exports}for(var i="function"==typeof require&&require,s=0;sn;n++)t[n].fn!==e&&o.push(t[n]);return o}var s={once:"boolean",scope:"object"},a=0,u=function(){this._enabled=!0,this.unbindAll()};u.prototype.unbindAll=function(){return this._handlers={},this._handlersAll=[],this._handlersComplex=[],this},u.prototype.on=function(t,e,r){var n,i,u,h,c,l,f;if(o(t)){for(h in t)this.on(h,t[h],e);return this}for("function"==typeof t&&(r=e,e=t,t=null),c=[].concat(t),n=0,i=c.length;i>n;n++){if(h=c[n],f={order:a++,fn:e},"string"==typeof h)this._handlers[h]||(this._handlers[h]=[]),l=this._handlers[h];else if(h instanceof RegExp)l=this._handlersComplex,f.pattern=h;else{if(null!==h)throw Error("Emitter.on: invalid event.");l=this._handlersAll}for(u in r||{})s[u]&&(f[u]=r[u]);f.once&&(f.parent=l),l.push(f)}return this},u.prototype.once=function(){var t=Array.prototype.slice.call(arguments),r=t.length-1;return o(t[r])&&t.length>1?t[r]=e(t[r],{once:!0}):t.push({once:!0}),this.on.apply(this,t)},u.prototype.off=function(t,e){var r,n,s,a;if(1===arguments.length&&"function"==typeof t){e=arguments[0];for(s in this._handlers)this._handlers[s]=i(this._handlers[s],e),0===this._handlers[s].length&&delete this._handlers[s];this._handlersAll=i(this._handlersAll,e),this._handlersComplex=i(this._handlersComplex,e)}else if(1===arguments.length&&"string"==typeof t)delete this._handlers[t];else if(2===arguments.length){var u=[].concat(t);for(r=0,n=u.length;n>r;r++)a=u[r],this._handlers[a]=i(this._handlers[a],e),0===(this._handlers[a]||[]).length&&delete this._handlers[a]}else if(o(t))for(s in t)this.off(s,t[s]);return this},u.prototype.listeners=function(t){var e,r,n,o=this._handlersAll||[],i=!1;if(!t)throw Error("Emitter.listeners: no event provided.");for(o=o.concat(this._handlers[t]||[]),r=0,n=this._handlersComplex.length;n>r;r++)e=this._handlersComplex[r],~t.search(e.pattern)&&(i=!0,o.push(e));return this._handlersAll.length||i?o.sort(function(t,e){return t.order-e.order}):o.slice(0)},u.prototype.emit=function(t,e){if(!this._enabled)return this;if(o(t)){for(var r in t)this.emit(r,t[r]);return this}var n,i,s,a,u,h,c,l=[].concat(t),f=[];for(a=0,h=l.length;h>a;a++){for(i=this.listeners(l[a]),u=0,c=i.length;c>u;u++)s=i[u],n={type:l[a],target:this},arguments.length>1&&(n.data=e),s.fn.call("scope"in s?s.scope:this,n),s.once&&f.push(s);for(u=f.length-1;u>=0;u--)f[u].parent.splice(f[u].parent.indexOf(f[u]),1)}return this},u.prototype.kill=function(){this.unbindAll(),this._handlers=null,this._handlersAll=null,this._handlersComplex=null,this._enabled=!1},u.prototype.disable=function(){return this._enabled=!1,this},u.prototype.enable=function(){return this._enabled=!0,this},u.version="3.0.0","undefined"!=typeof n?("undefined"!=typeof r&&r.exports&&(n=r.exports=u),n.Emitter=u):"function"==typeof t&&t.amd?t("emmett",[],function(){return u}):this.Emitter=u}).call(this)},{}],4:[function(t,e,r){function n(t){return t+"$"+(new Date).getTime()+(""+Math.random()).replace("0.","")}function o(t,e){function r(t){this[t]=function(){var e=this.root[t].apply(this.root,arguments);return e instanceof i?this:e}}if(arguments.length<1&&(t={}),!(this instanceof o))return new o(t,e);if(!f.Object(t)&&!f.Array(t))throw Error("Baobab: invalid data.");if(s.call(this),this.options=u.shallowMerge(l,e),this._transaction={},this._future=void 0,this._cursors={},this._identity="[object Baobab]",this.data=u.deepClone(t),this.root=this.select([]),this.facets={},["get","set","unset","update"].forEach(r.bind(this)),!f.Object(this.options.facets))throw Error("Baobab: invalid facets.");for(var n in this.options.facets)this.addFacet(n,this.options.facets[n])}var i=t("./cursor.js"),s=t("emmett"),a=t("./facet.js"),u=t("./helpers.js"),h=t("./update.js"),c=t("./merge.js"),l=t("../defaults.js"),f=t("./type.js");u.inherits(o,s),o.prototype.addFacet=function(t,e){return this.facets[t]=this.createFacet(e),this},o.prototype.createFacet=function(t){return new a(this,t)},o.prototype.select=function(t){if(!t)throw Error("Baobab.select: invalid path.");if(arguments.length>1&&(t=u.arrayOf(arguments)),!f.Path(t))throw Error("Baobab.select: invalid path.");t=[].concat(t);var e,r=f.ComplexPath(t);r&&(e=u.solvePath(this.data,t,this));var o=t.map(function(t){return f.Function(t)?n("fn"):f.Object(t)?n("ob"):t}).join("|λ|");if(this._cursors[o])return this._cursors[o];var s=new i(this,t,e,o);return this._cursors[o]=s,s},o.prototype.stack=function(t){var e=this;if(!f.Object(t))throw Error("Baobab.update: wrong specification.");return this._transaction=c(t,this._transaction),this.options.autoCommit?this.options.asynchronous?(this._future||(this._future=setTimeout(e.commit.bind(e,null),0)),this):this.commit():this},o.prototype.commit=function(){var t=h(this.data,this._transaction,this.options),e=this.data;this._transaction={},this._future&&(this._future=clearTimeout(this._future));var r=this.options.validate,n=this.options.validationBehavior;if("function"==typeof r){var o=r.call(this,e,t.data,t.log);if(o instanceof Error&&(this.emit("invalid",{error:o}),"rollback"===n))return this}return this.data=t.data,this.emit("update",{log:t.log,previousState:e}),this},o.prototype.release=function(){var t;delete this.data,delete this._transaction;for(t in this._cursors)this._cursors[t].release();delete this._cursors;for(t in this.facets)this.facets[t].release();delete this.facets,this.kill()},o.prototype.toJSON=function(){return this.get()},o.prototype.toString=function(){return this._identity},e.exports=o},{"../defaults.js":2,"./cursor.js":5,"./facet.js":6,"./helpers.js":7,"./merge.js":8,"./type.js":9,"./update.js":10,emmett:3}],5:[function(t,e,r){function n(t,e,r,n){function o(t){if(i.recording&&!i.undoing){var e=a.getIn(t,i.solvedPath,i.tree),r=a.deepClone(e);i.archive.add(r)}return i.undoing=!1,i.emit("update")}var i=this;s.call(this),e=e||[],this.tree=t,this.path=e,this.hash=n,this.archive=null,this.recording=!1,this.undoing=!1,this._identity="[object Cursor]",this.complexPath=!!r,this.solvedPath=this.complexPath?r:this.path,this.relevant=void 0!==this.get(),this.updateHandler=function(t){var e=t.data.log,r=t.data.previousState,n=!1;if(i.complexPath&&(i.solvedPath=a.solvePath(i.tree.data,i.path,i.tree)),!i.path.length)return o(r);i.solvedPath&&(n=a.solveUpdate(e,[i.solvedPath]));var s=void 0!==i.get();i.relevant?s&&n?o(r):s||(i.emit("irrelevant"),i.relevant=!1):s&&n&&(i.emit("relevant"),o(r),i.relevant=!0)};var u=!1;this._lazyBind=function(){u||(u=!0,i.tree.on("update",i.updateHandler))},this.on=a.before(this._lazyBind,this.on.bind(this)),this.once=a.before(this._lazyBind,this.once.bind(this)),this.complexPath&&this._lazyBind()}function o(t,e,r,n){if(arguments.length>5)throw Error("baobab.Cursor."+t+": too many arguments.");if(arguments.length<4&&(n=r,r=[]),r=r||[],"splice"===t&&!u.Splicer(n)){if(!u.Array(n))throw Error("baobab.Cursor.splice: incorrect value.");n=[n]}if(e&&!e(n))throw Error("baobab.Cursor."+t+": incorrect value.");var o=[].concat(r),i=a.solvePath(this.get(),o,this.tree);if(!i)throw Error("baobab.Cursor."+t+": could not solve dynamic path.");var s={};s["$"+t]=n;var h=a.pathObject(i,s);return h}function i(t,e){n.prototype[t]=function(){var r=o.bind(this,t,e).apply(this,arguments);return this.update(r)}}var s=t("emmett"),a=t("./helpers.js"),u=(t("../defaults.js"),t("./type.js"));a.inherits(n,s),n.prototype.isRoot=function(){return!this.path.length},n.prototype.isLeaf=function(){return u.Primitive(this.get())},n.prototype.isBranch=function(){return!this.isLeaf()&&!this.isRoot()},n.prototype.root=function(){return this.tree.root()},n.prototype.select=function(t){if(arguments.length>1&&(t=a.arrayOf(arguments)),!u.Path(t))throw Error("baobab.Cursor.select: invalid path.");return this.tree.select(this.path.concat(t))},n.prototype.up=function(){return this.solvedPath&&this.solvedPath.length?this.tree.select(this.path.slice(0,-1)):null},n.prototype.left=function(){var t=+this.solvedPath[this.solvedPath.length-1];if(isNaN(t))throw Error("baobab.Cursor.left: cannot go left on a non-list type.");return t?this.tree.select(this.solvedPath.slice(0,-1).concat(t-1)):null},n.prototype.leftmost=function(){var t=+this.solvedPath[this.solvedPath.length-1];if(isNaN(t))throw Error("baobab.Cursor.leftmost: cannot go left on a non-list type.");return this.tree.select(this.solvedPath.slice(0,-1).concat(0))},n.prototype.right=function(){var t=+this.solvedPath[this.solvedPath.length-1];if(isNaN(t))throw Error("baobab.Cursor.right: cannot go right on a non-list type.");return t+1===this.up().get().length?null:this.tree.select(this.solvedPath.slice(0,-1).concat(t+1))},n.prototype.rightmost=function(){var t=+this.solvedPath[this.solvedPath.length-1];if(isNaN(t))throw Error("baobab.Cursor.right: cannot go right on a non-list type.");var e=this.up().get();return this.tree.select(this.solvedPath.slice(0,-1).concat(e.length-1))},n.prototype.down=function(){+this.solvedPath[this.solvedPath.length-1];return this.get()instanceof Array?this.tree.select(this.solvedPath.concat(0)):null},n.prototype.get=function(t){arguments.length>1&&(t=a.arrayOf(arguments));var e=this.solvedPath.concat([].concat(t||0===t?t:[]));return a.getIn(this.tree.data,e,this.tree)},i("set"),i("apply",u.Function),i("chain",u.Function),i("push"),i("unshift"),i("merge",u.Object),i("splice"),n.prototype.unset=function(t){if(void 0===t&&this.isRoot())throw Error("baobab.Cursor.unset: cannot remove root node.");var e=o.bind(this,"unset",null).apply(this,[t,!0]);return this.update(e)},n.prototype.update=function(t,e){if(arguments.length<2)return this.tree.stack(a.pathObject(this.solvedPath,t)),this;var r=[].concat(t),n=a.solvePath(this.get(),r,this.tree);if(!n)throw Error("baobab.Cursor.update: could not solve dynamic path.");return this.tree.stack(a.pathObject(this.solvedPath.concat(n),e)),this},n.prototype.startRecording=function(t){if(t=t||5,1>t)throw Error("baobab.Cursor.startRecording: invalid maximum number of records.");return this.archive?this:(this._lazyBind(),this.archive=a.archive(t),this.recording=!0,this)},n.prototype.stopRecording=function(){return this.recording=!1,this},n.prototype.undo=function(t){if(t=t||1,!this.recording)throw Error("baobab.Cursor.undo: cursor is not recording.");if(!u.PositiveInteger(t))throw Error("baobab.Cursor.undo: expecting a positive integer.");var e=this.archive.back(t);if(!e)throw Error("boabab.Cursor.undo: cannot find a relevant record ("+t+" back).");return this.undoing=!0,this.set(e)},n.prototype.hasHistory=function(){return!(!this.archive||!this.archive.get().length)},n.prototype.getHistory=function(){return this.archive?this.archive.get():[]},n.prototype.clearHistory=function(){return this.archive=null,this},n.prototype.release=function(){this.tree.off("update",this.updateHandler),this.hash&&delete this.tree._cursors[this.hash],delete this.tree,delete this.path,delete this.solvedPath,delete this.archive,this.kill()},n.prototype.toJSON=function(){return this.get()},n.prototype.toString=function(){return this._identity},e.exports=n},{"../defaults.js":2,"./helpers.js":7,"./type.js":9,emmett:3}],6:[function(t,e,r){function n(t,e){function r(){d&&(p=f.map(function(t){return s.solvePath(n.tree.data,t,n.tree)}))}var n=this,u=e.cursors,h=!1,c=e.get,l=null;if(!a.FacetCursors(u))throw Error("baobab.Facet: incorrect cursors mapping.");o.call(this),this.tree=t,this.cursors={};var f=Object.keys(u).map(function(e){return u[e]instanceof i?(this.cursors[e]=u[e],u[e].path):(this.cursors[e]=t.select(u[e]),u[e])},this),p=f,d=f.some(a.ComplexPath);this.updateHandler=function(t){s.solveUpdate(t.data.log,p)&&(h=!1,n.emit("update"))},r(),this.tree.on("update",this.updateHandler),this.get=function(){if(h)return l;var t={};for(var e in n.cursors)t[e]=n.cursors[e].get();return l="function"==typeof c?c.call(null,t):t,h=!0,l}}var o=t("emmett"),i=t("./cursor.js"),s=t("./helpers.js"),a=t("./type.js");s.inherits(n,o),n.prototype.release=function(){this.tree.off("update",this.updateHandler),this.tree=null,this.kill()},e.exports=n},{"./cursor.js":5,"./helpers.js":7,"./type.js":9,emmett:3}],7:[function(t,e,r){(function(r){function n(t){return Array.prototype.slice.call(t)}function o(t,e){return function(){t(),e.apply(null,arguments)}}function i(t,e,r){var o=n(arguments).slice(3);return e=+e,r=+r,t.slice(0,e).concat(t.slice(e+r).concat(o))}function s(t,e){var r,n={};for(r in t)n[r]=t[r];for(r in e)n[r]=e[r];return n}function a(t){var e=t.source,r="";return t.global&&(r+="g"),t.multiline&&(r+="m"),t.ignoreCase&&(r+="i"),t.sticky&&(r+="y"),t.unicode&&(r+="u"),new RegExp(e,r)}function u(t,e){if(!e||"object"!=typeof e||e instanceof Error||"ArrayBuffer"in r&&e instanceof ArrayBuffer)return e;if(w.Array(e)){if(t){var n,o,i=[];for(n=0,o=e.length;o>n;n++)i.push(P(e[n]));return i}return e.slice(0)}if(w.Date(e))return new Date(e.getTime());if(e instanceof RegExp)return a(e);if(w.Object(e)){var s,u={};e.constructor&&e.constructor!==Object&&(u=Object.create(e.constructor.prototype));for(s in e)e.hasOwnProperty(s)&&(u[s]=t?P(e[s]):e[s]);return u}return e}function h(t,e){return function(r){return e(t(r))}}function c(t,e){var r,n;for(r=0,n=t.length;n>r;r++)if(e(t[r]))return t[r]}function l(t,e){var r,n;for(r=0,n=t.length;n>r;r++)if(e(t[r]))return r;return-1}function f(t,e){var r,n=!0;if(!t)return!1;for(r in e)if(w.Object(e[r]))n=n&&f(t[r],e[r]);else if(w.Array(e[r]))n=n&&!!~e[r].indexOf(t[r]);else if(t[r]!==e[r])return!1;return n}function d(t,e){return c(t,function(t){return f(t,e)})}function y(t,e){return l(t,function(t){return f(t,e)})}function v(t,e,r){e=e||[];var n,o,i,s=t;for(o=0,i=e.length;i>o;o++){if(!s)return;if("function"==typeof e[o]){if(!w.Array(s))return;s=c(s,e[o])}else if("object"==typeof e[o])if(r&&"$cursor"in e[o]){if(!w.Path(e[o].$cursor))throw Error("baobab.getIn: $cursor path must be an array.");n=r.get(e[o].$cursor),s=s[n]}else{if(!w.Array(s))return;s=d(s,e[o])}else s=s[e[o]]}return s}function g(t,e,r){var n,o,i,s=[],a=t;for(o=0,i=e.length;i>o;o++){if(!a)return null;if("function"==typeof e[o]){if(!w.Array(a))return;n=l(a,e[o]),s.push(n),a=a[n]}else if("object"==typeof e[o])if(r&&"$cursor"in e[o]){if(!w.Path(e[o].$cursor))throw Error("baobab.getIn: $cursor path must be an array.");p=r.get(e[o].$cursor),s.push(p),a=a[p]}else{if(!w.Array(a))return;n=y(a,e[o]),s.push(n),a=a[n]}else s.push(e[o]),a=a[e[o]]||{}}return s}function b(t,e){var r,n,o,i,s,a,u,h,c;for(r=0,i=e.length;i>r;r++)for(u=e[r],n=0,s=t.length;s>n;n++)for(h=t[n],o=0,a=h.length;a>o&&(c=h[o],c==u[o]);o++)if(o+1===a||o+1===u.length)return!0;return!1}function m(t,e){var r,n=t.length,o={},i=o;for(n||(o=e),r=0;n>r;r++)i[t[r]]=r+1===n?e:{},i=i[t[r]];return o}function j(t,e){t.super_=e;var r=function(){};r.prototype=e.prototype,t.prototype=new r,t.prototype.constructor=t}function _(t){var e=[];return{add:function(r){e.unshift(r),e.length>t&&(e.length=t)},back:function(t){var r=e[t-1];return r&&(e=e.slice(t)),r},get:function(){return e}}}var w=t("./type.js"),$=u.bind(null,!1),P=u.bind(null,!0);e.exports={archive:_,arrayOf:n,before:o,deepClone:P,shallowClone:$,shallowMerge:s,compose:h,getIn:v,inherits:j,pathObject:m,solvePath:g,solveUpdate:b,splice:i}}).call(this,"undefined"!=typeof global?global:"undefined"!=typeof self?self:"undefined"!=typeof window?window:{})},{"./type.js":9}],8:[function(t,e,r){function n(t,e,r){a.forEach(function(e){r!==e&&delete t[e]}),t[r]=e[r]}function o(t,e){var r,u=i.shallowClone(e||{});a.forEach(function(e){t[e]&&n(u,t,e)}),t.$chain&&(a.slice(0,-1).forEach(function(t){delete u[t]}),u.$apply=u.$apply?i.compose(u.$apply,t.$chain):t.$chain),(t.$splice||u.$splice)&&(u.$splice=[].concat(u.$splice||[]).concat(t.$splice||[])),(t.$push||u.$push)&&(u.$push=[].concat(u.$push||[]).concat(t.$push||[])),(t.$unshift||u.$unshift)&&(u.$unshift=[].concat(t.$unshift||[]).concat(u.$unshift||[]));for(r in t)s.Object(t[r])?u[r]=o(t[r],u[r]):"$"!==r[0]&&(u[r]=t[r]);return u}var i=t("./helpers.js"),s=t("./type.js"),a=["$unset","$set","$merge","$apply"];e.exports=o},{"./helpers.js":7,"./type.js":9}],9:[function(t,e,r){function n(t,e){return e.some(function(e){return o[e](t)})}var o={};o.Array=function(t){return Array.isArray(t)},o.Object=function(t){return t&&"object"==typeof t&&!Array.isArray(t)&&!(t instanceof Function)},o.String=function(t){return"string"==typeof t},o.Number=function(t){return"number"==typeof t},o.PositiveInteger=function(t){return"number"==typeof t&&t>0&&t%1===0},o.Function=function(t){return"function"==typeof t},o.Primitive=function(t){return"string"==typeof t||"number"==typeof t||"boolean"==typeof t},o.Date=function(t){return t instanceof Date},o.NonScalar=function(t){return o.Object(t)||o.Array(t)},o.Splicer=function(t){return o.Array(t)&&t.every(o.Array)},o.Path=function(t){var e=["String","Number","Function","Object"];return o.Array(t)?t.every(function(t){return n(t,e)}):n(t,e)},o.ComplexPath=function(t){return t.some(function(t){return n(t,["Object","Function"])})},o.FacetCursors=function(e){return o.Object(e)?Object.keys(e).every(function(r){var n=e[r];return o.Path(n)||o.Function(n)||n instanceof t("./cursor.js")}):!1},o.FacetFacets=function(e){return o.Object(e)?Object.keys(e).every(function(r){var n=e[r];return"string"==typeof n||n instanceof t("./facet.js")}):!1},e.exports=o},{"./cursor.js":5,"./facet.js":6}],10:[function(t,e,r){function n(t,e){var r=new Error("baobab.update: "+e+" at path /"+t.slice(1).join("/"));return r.path=t,r}var o=t("./helpers.js"),i=t("./type.js");e.exports=function(t,e,r){if(r=r||{},!i.Object(t)&&!i.Array(t))throw Error("baobab.update: invalid target.");var s={};t={root:o.shallowClone(t)};var a=function(t,e,r,u){r=r||["root"];var h,c,l,f=r.join("|λ|"),p=r[r.length-1],d=Object.keys(e).some(function(t){return!!~["$set","$push","$unshift","$splice","$unset","$merge","$apply"].indexOf(t)});if(d){s[f]=!0;for(c in e){if("$unset"===c){var y=r[r.length-2];if(!i.Object(u[y]))throw n(r.slice(0,-1),"using command $unset on a non-object");u[y]=o.shallowClone(t),delete u[y][p];break}if("$set"===c){l=e.$set,t[p]=l;break}if("$apply"===c){if(h=e.$apply,"function"!=typeof h)throw n(r,"using command $apply with a non function");t[p]=h.call(null,t[p]);break}if("$merge"===c){if(l=e.$merge,!i.Object(t[p])||!i.Object(l))throw n(r,"using command $merge with a non object");t[p]=o.shallowMerge(t[p],l);break}if("$splice"===c){if(l=e.$splice,!i.Array(t[p]))throw n(r,"using command $push to a non array");l.forEach(function(e){t[p]=o.splice.apply(null,[t[p]].concat(e))})}if("$push"===c){if(l=e.$push,!i.Array(t[p]))throw n(r,"using command $push to a non array");t[p]=t[p].concat(l)}if("$unshift"===c){if(l=e.$unshift,!i.Array(t[p]))throw n(r,"using command $unshift to a non array");t[p]=[].concat(l).concat(t[p])}}}else for(c in e)t[p][c]="undefined"==typeof t[p][c]?{}:o.shallowClone(t[p][c]),a(t[p],e[c],r.concat(c),t)};return a(t,e),{data:t.root,log:Object.keys(s).map(function(t){return t.split("|λ|").slice(1)})}}},{"./helpers.js":7,"./type.js":9}]},{},[1])(1)}); \ No newline at end of file +!function(t){if("object"==typeof exports&&"undefined"!=typeof module)module.exports=t();else if("function"==typeof define&&define.amd)define([],t);else{var e;e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:this,e.Baobab=t()}}(function(){var t;return function e(t,r,n){function o(s,a){if(!r[s]){if(!t[s]){var u="function"==typeof require&&require;if(!a&&u)return u(s,!0);if(i)return i(s,!0);var h=new Error("Cannot find module '"+s+"'");throw h.code="MODULE_NOT_FOUND",h}var c=r[s]={exports:{}};t[s][0].call(c.exports,function(e){var r=t[s][1][e];return o(r?r:e)},c,c.exports,e,t,r,n)}return r[s].exports}for(var i="function"==typeof require&&require,s=0;sn;n++)t[n].fn!==e&&o.push(t[n]);return o}var s={once:"boolean",scope:"object"},a=0,u=function(){this._enabled=!0,this.unbindAll()};u.prototype.unbindAll=function(){return this._handlers={},this._handlersAll=[],this._handlersComplex=[],this},u.prototype.on=function(t,e,r){var n,i,u,h,c,l,f;if(o(t)){for(h in t)this.on(h,t[h],e);return this}for("function"==typeof t&&(r=e,e=t,t=null),c=[].concat(t),n=0,i=c.length;i>n;n++){if(h=c[n],f={order:a++,fn:e},"string"==typeof h)this._handlers[h]||(this._handlers[h]=[]),l=this._handlers[h];else if(h instanceof RegExp)l=this._handlersComplex,f.pattern=h;else{if(null!==h)throw Error("Emitter.on: invalid event.");l=this._handlersAll}for(u in r||{})s[u]&&(f[u]=r[u]);f.once&&(f.parent=l),l.push(f)}return this},u.prototype.once=function(){var t=Array.prototype.slice.call(arguments),r=t.length-1;return o(t[r])&&t.length>1?t[r]=e(t[r],{once:!0}):t.push({once:!0}),this.on.apply(this,t)},u.prototype.off=function(t,e){var r,n,s,a;if(1===arguments.length&&"function"==typeof t){e=arguments[0];for(s in this._handlers)this._handlers[s]=i(this._handlers[s],e),0===this._handlers[s].length&&delete this._handlers[s];this._handlersAll=i(this._handlersAll,e),this._handlersComplex=i(this._handlersComplex,e)}else if(1===arguments.length&&"string"==typeof t)delete this._handlers[t];else if(2===arguments.length){var u=[].concat(t);for(r=0,n=u.length;n>r;r++)a=u[r],this._handlers[a]=i(this._handlers[a],e),0===(this._handlers[a]||[]).length&&delete this._handlers[a]}else if(o(t))for(s in t)this.off(s,t[s]);return this},u.prototype.listeners=function(t){var e,r,n,o=this._handlersAll||[],i=!1;if(!t)throw Error("Emitter.listeners: no event provided.");for(o=o.concat(this._handlers[t]||[]),r=0,n=this._handlersComplex.length;n>r;r++)e=this._handlersComplex[r],~t.search(e.pattern)&&(i=!0,o.push(e));return this._handlersAll.length||i?o.sort(function(t,e){return t.order-e.order}):o.slice(0)},u.prototype.emit=function(t,e){if(!this._enabled)return this;if(o(t)){for(var r in t)this.emit(r,t[r]);return this}var n,i,s,a,u,h,c,l=[].concat(t),f=[];for(a=0,h=l.length;h>a;a++){for(i=this.listeners(l[a]),u=0,c=i.length;c>u;u++)s=i[u],n={type:l[a],target:this},arguments.length>1&&(n.data=e),s.fn.call("scope"in s?s.scope:this,n),s.once&&f.push(s);for(u=f.length-1;u>=0;u--)f[u].parent.splice(f[u].parent.indexOf(f[u]),1)}return this},u.prototype.kill=function(){this.unbindAll(),this._handlers=null,this._handlersAll=null,this._handlersComplex=null,this._enabled=!1},u.prototype.disable=function(){return this._enabled=!1,this},u.prototype.enable=function(){return this._enabled=!0,this},u.version="3.0.0","undefined"!=typeof n?("undefined"!=typeof r&&r.exports&&(n=r.exports=u),n.Emitter=u):"function"==typeof t&&t.amd?t("emmett",[],function(){return u}):this.Emitter=u}).call(this)},{}],4:[function(t,e,r){function n(t){return t+"$"+(new Date).getTime()+(""+Math.random()).replace("0.","")}function o(t,e){function r(t){this[t]=function(){var e=this.root[t].apply(this.root,arguments);return e instanceof i?this:e}}if(arguments.length<1&&(t={}),!(this instanceof o))return new o(t,e);if(!f.Object(t)&&!f.Array(t))throw Error("Baobab: invalid data.");if(s.call(this),this.options=u.shallowMerge(l,e),this._transaction={},this._future=void 0,this._cursors={},this._identity="[object Baobab]",this.data=u.deepClone(t),this.root=this.select([]),this.facets={},["get","set","unset","update"].forEach(r.bind(this)),!f.Object(this.options.facets))throw Error("Baobab: invalid facets.");for(var n in this.options.facets)this.addFacet(n,this.options.facets[n])}var i=t("./cursor.js"),s=t("emmett"),a=t("./facet.js"),u=t("./helpers.js"),h=t("./update.js"),c=t("./merge.js"),l=t("../defaults.js"),f=t("./type.js");u.inherits(o,s),o.prototype.addFacet=function(t,e){return this.facets[t]=this.createFacet(e),this},o.prototype.createFacet=function(t){return new a(this,t)},o.prototype.select=function(t){if(!t)throw Error("Baobab.select: invalid path.");if(arguments.length>1&&(t=u.arrayOf(arguments)),!f.Path(t))throw Error("Baobab.select: invalid path.");t=[].concat(t);var e,r=f.ComplexPath(t);r&&(e=u.solvePath(this.data,t,this));var o=t.map(function(t){return f.Function(t)?n("fn"):f.Object(t)?n("ob"):t}).join("|λ|");if(this._cursors[o])return this._cursors[o];var s=new i(this,t,e,o);return this._cursors[o]=s,s},o.prototype.stack=function(t){var e=this;if(!f.Object(t))throw Error("Baobab.update: wrong specification.");return this._transaction=c(t,this._transaction),this.options.autoCommit?this.options.asynchronous?(this._future||(this._future=setTimeout(e.commit.bind(e,null),0)),this):this.commit():this},o.prototype.commit=function(){var t=h(this.data,this._transaction,this.options),e=this.data;this._transaction={},this._future&&(this._future=clearTimeout(this._future));var r=this.options.validate,n=this.options.validationBehavior;if("function"==typeof r){var o=r.call(this,e,t.data,t.log);if(o instanceof Error&&(this.emit("invalid",{error:o}),"rollback"===n))return this}return this.data=t.data,this.emit("update",{log:t.log,previousState:e}),this},o.prototype.release=function(){var t;delete this.data,delete this._transaction;for(t in this._cursors)this._cursors[t].release();delete this._cursors;for(t in this.facets)this.facets[t].release();delete this.facets,this.kill()},o.prototype.toJSON=function(){return this.get()},o.prototype.toString=function(){return this._identity},e.exports=o},{"../defaults.js":2,"./cursor.js":5,"./facet.js":6,"./helpers.js":7,"./merge.js":8,"./type.js":9,"./update.js":10,emmett:3}],5:[function(t,e,r){function n(t,e,r,n){function o(t){if(i.recording&&!i.undoing){var e=a.getIn(t,i.solvedPath,i.tree),r=a.deepClone(e);i.archive.add(r)}return i.undoing=!1,i.emit("update")}var i=this;s.call(this),e=e||[],this.tree=t,this.path=e,this.hash=n,this.archive=null,this.recording=!1,this.undoing=!1,this._identity="[object Cursor]",this.complexPath=!!r,this.solvedPath=this.complexPath?r:this.path,this.relevant=void 0!==this.get(),this.updateHandler=function(t){var e=t.data.log,r=t.data.previousState,n=!1;if(i.complexPath&&(i.solvedPath=a.solvePath(i.tree.data,i.path,i.tree)),!i.path.length)return o(r);i.solvedPath&&(n=a.solveUpdate(e,[i.solvedPath]));var s=void 0!==i.get();i.relevant?s&&n?o(r):s||(i.emit("irrelevant"),i.relevant=!1):s&&n&&(i.emit("relevant"),o(r),i.relevant=!0)};var u=!1;this._lazyBind=function(){u||(u=!0,i.tree.on("update",i.updateHandler))},this.on=a.before(this._lazyBind,this.on.bind(this)),this.once=a.before(this._lazyBind,this.once.bind(this)),this.complexPath&&this._lazyBind()}function o(t,e,r,n){if(arguments.length>5)throw Error("baobab.Cursor."+t+": too many arguments.");if(arguments.length<4&&(n=r,r=[]),r=r||[],"splice"===t&&!u.Splicer(n)){if(!u.Array(n))throw Error("baobab.Cursor.splice: incorrect value.");n=[n]}if(e&&!e(n))throw Error("baobab.Cursor."+t+": incorrect value.");var o=[].concat(r),i=a.solvePath(this.get(),o,this.tree);if(!i)throw Error("baobab.Cursor."+t+": could not solve dynamic path.");var s={};s["$"+t]=n;var h=a.pathObject(i,s);return h}function i(t,e){n.prototype[t]=function(){var r=o.bind(this,t,e).apply(this,arguments);return this.update(r)}}var s=t("emmett"),a=t("./helpers.js"),u=(t("../defaults.js"),t("./type.js"));a.inherits(n,s),n.prototype.isRoot=function(){return!this.path.length},n.prototype.isLeaf=function(){return u.Primitive(this.get())},n.prototype.isBranch=function(){return!this.isLeaf()&&!this.isRoot()},n.prototype.root=function(){return this.tree.root()},n.prototype.select=function(t){if(arguments.length>1&&(t=a.arrayOf(arguments)),!u.Path(t))throw Error("baobab.Cursor.select: invalid path.");return this.tree.select(this.path.concat(t))},n.prototype.up=function(){return this.solvedPath&&this.solvedPath.length?this.tree.select(this.path.slice(0,-1)):null},n.prototype.left=function(){var t=+this.solvedPath[this.solvedPath.length-1];if(isNaN(t))throw Error("baobab.Cursor.left: cannot go left on a non-list type.");return t?this.tree.select(this.solvedPath.slice(0,-1).concat(t-1)):null},n.prototype.leftmost=function(){var t=+this.solvedPath[this.solvedPath.length-1];if(isNaN(t))throw Error("baobab.Cursor.leftmost: cannot go left on a non-list type.");return this.tree.select(this.solvedPath.slice(0,-1).concat(0))},n.prototype.right=function(){var t=+this.solvedPath[this.solvedPath.length-1];if(isNaN(t))throw Error("baobab.Cursor.right: cannot go right on a non-list type.");return t+1===this.up().get().length?null:this.tree.select(this.solvedPath.slice(0,-1).concat(t+1))},n.prototype.rightmost=function(){var t=+this.solvedPath[this.solvedPath.length-1];if(isNaN(t))throw Error("baobab.Cursor.right: cannot go right on a non-list type.");var e=this.up().get();return this.tree.select(this.solvedPath.slice(0,-1).concat(e.length-1))},n.prototype.down=function(){+this.solvedPath[this.solvedPath.length-1];return this.get()instanceof Array?this.tree.select(this.solvedPath.concat(0)):null},n.prototype.get=function(t){arguments.length>1&&(t=a.arrayOf(arguments));var e=this.solvedPath.concat([].concat(t||0===t?t:[]));return a.getIn(this.tree.data,e,this.tree)},i("set"),i("apply",u.Function),i("chain",u.Function),i("push"),i("unshift"),i("merge",u.Object),i("splice"),n.prototype.unset=function(t){if(void 0===t&&this.isRoot())throw Error("baobab.Cursor.unset: cannot remove root node.");var e=o.bind(this,"unset",null).apply(this,[t,!0]);return this.update(e)},n.prototype.update=function(t,e){if(arguments.length<2)return this.tree.stack(a.pathObject(this.solvedPath,t)),this;var r=[].concat(t),n=a.solvePath(this.get(),r,this.tree);if(!n)throw Error("baobab.Cursor.update: could not solve dynamic path.");return this.tree.stack(a.pathObject(this.solvedPath.concat(n),e)),this},n.prototype.startRecording=function(t){if(t=t||5,1>t)throw Error("baobab.Cursor.startRecording: invalid maximum number of records.");return this.archive?this:(this._lazyBind(),this.archive=a.archive(t),this.recording=!0,this)},n.prototype.stopRecording=function(){return this.recording=!1,this},n.prototype.undo=function(t){if(t=t||1,!this.recording)throw Error("baobab.Cursor.undo: cursor is not recording.");if(!u.PositiveInteger(t))throw Error("baobab.Cursor.undo: expecting a positive integer.");var e=this.archive.back(t);if(!e)throw Error("boabab.Cursor.undo: cannot find a relevant record ("+t+" back).");return this.undoing=!0,this.set(e)},n.prototype.hasHistory=function(){return!(!this.archive||!this.archive.get().length)},n.prototype.getHistory=function(){return this.archive?this.archive.get():[]},n.prototype.clearHistory=function(){return this.archive=null,this},n.prototype.release=function(){this.tree.off("update",this.updateHandler),this.hash&&delete this.tree._cursors[this.hash],delete this.tree,delete this.path,delete this.solvedPath,delete this.archive,this.kill()},n.prototype.toJSON=function(){return this.get()},n.prototype.toString=function(){return this._identity},e.exports=n},{"../defaults.js":2,"./helpers.js":7,"./type.js":9,emmett:3}],6:[function(t,e,r){function n(t,e,r){var n=this,u=!1,h=e.cursors,c="function"==typeof e.cursors,l=e.get,f=null;o.call(this),this.tree=t,this.cursors=null,this.refresh=function(){if(c||!this.cursors){u=!1;var e=h;if(c&&(e=h.call(r)),!a.FacetCursors(e))throw Error("baobab.Facet: incorrect cursors mapping.");this.cursors={},Object.keys(e).forEach(function(r){if(e[r]instanceof i)return void(n.cursors[r]=e[r]);if(a.Path(e[r]))return void(n.cursors[r]=t.select(e[r]));throw Error("baobab.Facet: invalid path returned by function in cursors mapping.")})}},this.get=function(){if(u)return f;var t={};for(var e in n.cursors)t[e]=n.cursors[e].get();return f="function"==typeof l?l.call(null,t):t,u=!0,f},this.updateHandler=function(t){var e=Object.keys(n.cursors).map(function(t){return n.cursors[t].solvedPath});s.solveUpdate(t.data.log,e)&&(u=!1,n.emit("update"))},this.refresh(),this.tree.on("update",this.updateHandler)}var o=t("emmett"),i=t("./cursor.js"),s=t("./helpers.js"),a=t("./type.js");s.inherits(n,o),n.prototype.release=function(){this.tree.off("update",this.updateHandler),this.tree=null,this.cursors=null,this.kill()},e.exports=n},{"./cursor.js":5,"./helpers.js":7,"./type.js":9,emmett:3}],7:[function(t,e,r){(function(r){function n(t){return Array.prototype.slice.call(t)}function o(t,e){return function(){t(),e.apply(null,arguments)}}function i(t,e,r){var o=n(arguments).slice(3);return e=+e,r=+r,t.slice(0,e).concat(t.slice(e+r).concat(o))}function s(t,e){var r,n={};for(r in t)n[r]=t[r];for(r in e)n[r]=e[r];return n}function a(t){var e=t.source,r="";return t.global&&(r+="g"),t.multiline&&(r+="m"),t.ignoreCase&&(r+="i"),t.sticky&&(r+="y"),t.unicode&&(r+="u"),new RegExp(e,r)}function u(t,e){if(!e||"object"!=typeof e||e instanceof Error||"ArrayBuffer"in r&&e instanceof ArrayBuffer)return e;if(w.Array(e)){if(t){var n,o,i=[];for(n=0,o=e.length;o>n;n++)i.push(P(e[n]));return i}return e.slice(0)}if(w.Date(e))return new Date(e.getTime());if(e instanceof RegExp)return a(e);if(w.Object(e)){var s,u={};e.constructor&&e.constructor!==Object&&(u=Object.create(e.constructor.prototype));for(s in e)e.hasOwnProperty(s)&&(u[s]=t?P(e[s]):e[s]);return u}return e}function h(t,e){return function(r){return e(t(r))}}function c(t,e){var r,n;for(r=0,n=t.length;n>r;r++)if(e(t[r]))return t[r]}function l(t,e){var r,n;for(r=0,n=t.length;n>r;r++)if(e(t[r]))return r;return-1}function f(t,e){var r,n=!0;if(!t)return!1;for(r in e)if(w.Object(e[r]))n=n&&f(t[r],e[r]);else if(w.Array(e[r]))n=n&&!!~e[r].indexOf(t[r]);else if(t[r]!==e[r])return!1;return n}function d(t,e){return c(t,function(t){return f(t,e)})}function y(t,e){return l(t,function(t){return f(t,e)})}function v(t,e,r){e=e||[];var n,o,i,s=t;for(o=0,i=e.length;i>o;o++){if(!s)return;if("function"==typeof e[o]){if(!w.Array(s))return;s=c(s,e[o])}else if("object"==typeof e[o])if(r&&"$cursor"in e[o]){if(!w.Path(e[o].$cursor))throw Error("baobab.getIn: $cursor path must be an array.");n=r.get(e[o].$cursor),s=s[n]}else{if(!w.Array(s))return;s=d(s,e[o])}else s=s[e[o]]}return s}function g(t,e,r){var n,o,i,s=[],a=t;for(o=0,i=e.length;i>o;o++){if(!a)return null;if("function"==typeof e[o]){if(!w.Array(a))return;n=l(a,e[o]),s.push(n),a=a[n]}else if("object"==typeof e[o])if(r&&"$cursor"in e[o]){if(!w.Path(e[o].$cursor))throw Error("baobab.getIn: $cursor path must be an array.");p=r.get(e[o].$cursor),s.push(p),a=a[p]}else{if(!w.Array(a))return;n=y(a,e[o]),s.push(n),a=a[n]}else s.push(e[o]),a=a[e[o]]||{}}return s}function b(t,e){var r,n,o,i,s,a,u,h,c;for(r=0,i=e.length;i>r;r++)for(u=e[r],n=0,s=t.length;s>n;n++)for(h=t[n],o=0,a=h.length;a>o&&(c=h[o],c==u[o]);o++)if(o+1===a||o+1===u.length)return!0;return!1}function m(t,e){var r,n=t.length,o={},i=o;for(n||(o=e),r=0;n>r;r++)i[t[r]]=r+1===n?e:{},i=i[t[r]];return o}function j(t,e){t.super_=e;var r=function(){};r.prototype=e.prototype,t.prototype=new r,t.prototype.constructor=t}function _(t){var e=[];return{add:function(r){e.unshift(r),e.length>t&&(e.length=t)},back:function(t){var r=e[t-1];return r&&(e=e.slice(t)),r},get:function(){return e}}}var w=t("./type.js"),$=u.bind(null,!1),P=u.bind(null,!0);e.exports={archive:_,arrayOf:n,before:o,deepClone:P,shallowClone:$,shallowMerge:s,compose:h,getIn:v,inherits:j,pathObject:m,solvePath:g,solveUpdate:b,splice:i}}).call(this,"undefined"!=typeof global?global:"undefined"!=typeof self?self:"undefined"!=typeof window?window:{})},{"./type.js":9}],8:[function(t,e,r){function n(t,e,r){a.forEach(function(e){r!==e&&delete t[e]}),t[r]=e[r]}function o(t,e){var r,u=i.shallowClone(e||{});a.forEach(function(e){t[e]&&n(u,t,e)}),t.$chain&&(a.slice(0,-1).forEach(function(t){delete u[t]}),u.$apply=u.$apply?i.compose(u.$apply,t.$chain):t.$chain),(t.$splice||u.$splice)&&(u.$splice=[].concat(u.$splice||[]).concat(t.$splice||[])),(t.$push||u.$push)&&(u.$push=[].concat(u.$push||[]).concat(t.$push||[])),(t.$unshift||u.$unshift)&&(u.$unshift=[].concat(t.$unshift||[]).concat(u.$unshift||[]));for(r in t)s.Object(t[r])?u[r]=o(t[r],u[r]):"$"!==r[0]&&(u[r]=t[r]);return u}var i=t("./helpers.js"),s=t("./type.js"),a=["$unset","$set","$merge","$apply"];e.exports=o},{"./helpers.js":7,"./type.js":9}],9:[function(t,e,r){function n(t,e){return e.some(function(e){return o[e](t)})}var o={};o.Array=function(t){return Array.isArray(t)},o.Object=function(t){return t&&"object"==typeof t&&!Array.isArray(t)&&!(t instanceof Function)},o.String=function(t){return"string"==typeof t},o.Number=function(t){return"number"==typeof t},o.PositiveInteger=function(t){return"number"==typeof t&&t>0&&t%1===0},o.Function=function(t){return"function"==typeof t},o.Primitive=function(t){return"string"==typeof t||"number"==typeof t||"boolean"==typeof t},o.Date=function(t){return t instanceof Date},o.NonScalar=function(t){return o.Object(t)||o.Array(t)},o.Splicer=function(t){return o.Array(t)&&t.every(o.Array)},o.Path=function(t){var e=["String","Number","Function","Object"];return o.Array(t)?t.every(function(t){return n(t,e)}):n(t,e)},o.ComplexPath=function(t){return t.some(function(t){return n(t,["Object","Function"])})},o.FacetCursors=function(e){return o.Object(e)?Object.keys(e).every(function(r){var n=e[r];return o.Path(n)||n instanceof t("./cursor.js")}):!1},o.FacetFacets=function(e){return o.Object(e)?Object.keys(e).every(function(r){var n=e[r];return"string"==typeof n||n instanceof t("./facet.js")}):!1},e.exports=o},{"./cursor.js":5,"./facet.js":6}],10:[function(t,e,r){function n(t,e){var r=new Error("baobab.update: "+e+" at path /"+t.slice(1).join("/"));return r.path=t,r}var o=t("./helpers.js"),i=t("./type.js");e.exports=function(t,e,r){if(r=r||{},!i.Object(t)&&!i.Array(t))throw Error("baobab.update: invalid target.");var s={};t={root:o.shallowClone(t)};var a=function(t,e,r,u){r=r||["root"];var h,c,l,f=r.join("|λ|"),p=r[r.length-1],d=Object.keys(e).some(function(t){return!!~["$set","$push","$unshift","$splice","$unset","$merge","$apply"].indexOf(t)});if(d){s[f]=!0;for(c in e){if("$unset"===c){var y=r[r.length-2];if(!i.Object(u[y]))throw n(r.slice(0,-1),"using command $unset on a non-object");u[y]=o.shallowClone(t),delete u[y][p];break}if("$set"===c){l=e.$set,t[p]=l;break}if("$apply"===c){if(h=e.$apply,"function"!=typeof h)throw n(r,"using command $apply with a non function");t[p]=h.call(null,t[p]);break}if("$merge"===c){if(l=e.$merge,!i.Object(t[p])||!i.Object(l))throw n(r,"using command $merge with a non object");t[p]=o.shallowMerge(t[p],l);break}if("$splice"===c){if(l=e.$splice,!i.Array(t[p]))throw n(r,"using command $push to a non array");l.forEach(function(e){t[p]=o.splice.apply(null,[t[p]].concat(e))})}if("$push"===c){if(l=e.$push,!i.Array(t[p]))throw n(r,"using command $push to a non array");t[p]=t[p].concat(l)}if("$unshift"===c){if(l=e.$unshift,!i.Array(t[p]))throw n(r,"using command $unshift to a non array");t[p]=[].concat(l).concat(t[p])}}}else for(c in e)t[p][c]="undefined"==typeof t[p][c]?{}:o.shallowClone(t[p][c]),a(t[p],e[c],r.concat(c),t)};return a(t,e),{data:t.root,log:Object.keys(s).map(function(t){return t.split("|λ|").slice(1)})}}},{"./helpers.js":7,"./type.js":9}]},{},[1])(1)}); \ No newline at end of file diff --git a/src/facet.js b/src/facet.js index 6f405e1..ce06d9b 100644 --- a/src/facet.js +++ b/src/facet.js @@ -9,55 +9,55 @@ var EventEmitter = require('emmett'), helpers = require('./helpers.js'), type = require('./type.js'); -function Facet(tree, definition) { +function Facet(tree, definition, scope) { var self = this; - var map = definition.cursors, - solved = false, - solver = definition.get, + var solved = false, + mapping = definition.cursors, + complex = typeof definition.cursors === 'function', + getter = definition.get, data = null; - if (!type.FacetCursors(map)) - throw Error('baobab.Facet: incorrect cursors mapping.'); - // Extending event emitter EventEmitter.call(this); // Properties this.tree = tree; - this.cursors = {}; + this.cursors = null; - // Path solving - var paths = Object.keys(map).map(function(k) { - if (map[k] instanceof Cursor) { - this.cursors[k] = map[k]; - return map[k].path; - } - else { - this.cursors[k] = tree.select(map[k]); - return map[k]; - } - }, this); + // Refreshing the internal mapping + this.refresh = function() { + if (!complex && this.cursors) + return; - var solvedPaths = paths, - complex = paths.some(type.ComplexPath); + solved = false; - function solvePaths() { - if (complex) - solvedPaths = paths.map(function(p) { - return helpers.solvePath(self.tree.data, p, self.tree); - }); - } + var solvedMapping = mapping; - this.updateHandler = function(e) { - if (helpers.solveUpdate(e.data.log, solvedPaths)) { - solved = false; - self.emit('update'); + if (complex) { + solvedMapping = mapping.call(scope); } - }; - solvePaths(); - this.tree.on('update', this.updateHandler); + if (!type.FacetCursors(solvedMapping)) + throw Error('baobab.Facet: incorrect cursors mapping.'); + + this.cursors = {}; + + Object.keys(solvedMapping).forEach(function(k) { + + if (solvedMapping[k] instanceof Cursor) { + self.cursors[k] = solvedMapping[k]; + return; + } + + if (type.Path(solvedMapping[k])) { + self.cursors[k] = tree.select(solvedMapping[k]); + return; + } + + throw Error('baobab.Facet: invalid path returned by function in cursors mapping.'); + }); + }; // Data solving this.get = function() { @@ -70,14 +70,30 @@ function Facet(tree, definition) { for (var k in self.cursors) cursorsData[k] = self.cursors[k].get(); - data = typeof solver === 'function' ? - solver.call(null, cursorsData) : + data = typeof getter === 'function' ? + getter.call(null, cursorsData) : cursorsData; solved = true; return data; }; + + // Tracking the tree's updates + this.updateHandler = function(e) { + var paths = Object.keys(self.cursors).map(function(k) { + return self.cursors[k].solvedPath; + }) + + if (helpers.solveUpdate(e.data.log, paths)) { + solved = false; + self.emit('update'); + } + }; + + // Init routine + this.refresh(); + this.tree.on('update', this.updateHandler); } helpers.inherits(Facet, EventEmitter); @@ -86,6 +102,7 @@ Facet.prototype.release = function() { this.tree.off('update', this.updateHandler); this.tree = null; + this.cursors = null; this.kill(); }; diff --git a/src/type.js b/src/type.js index 80763aa..87f7304 100644 --- a/src/type.js +++ b/src/type.js @@ -97,7 +97,6 @@ type.FacetCursors = function(value) { var v = value[k]; return type.Path(v) || - type.Function(v) || v instanceof require('./cursor.js'); }); }; diff --git a/test/suites/baobab.js b/test/suites/baobab.js index da9bfa9..4facac4 100644 --- a/test/suites/baobab.js +++ b/test/suites/baobab.js @@ -339,6 +339,25 @@ describe('Baobab API', function() { facet.release(); }); + + it('should be possible to solve cursors mapping with a function.', function() { + var pointer = 'value1'; + + var facet = baobab.createFacet({ + cursors: function() { + return {value: [pointer]}; + } + }); + + assert.deepEqual(facet.get(), {value: 'Hello'}); + + pointer = 'value2'; + facet.refresh(); + + assert.deepEqual(facet.get(), {value: 'World'}); + + facet.release(); + }); }); describe('Options', function() { From 1147e9c32d15e0f9c1571853fa91c9cf21b5129a Mon Sep 17 00:00:00 2001 From: Yomguithereal Date: Mon, 20 Apr 2015 22:30:23 +0200 Subject: [PATCH 72/73] Facets - the yo dawg update --- build/baobab.min.js | 2 +- src/facet.js | 98 ++++++++++++++++++++++++++++++++----------- src/type.js | 3 +- test/suites/baobab.js | 28 +++++++++++++ 4 files changed, 104 insertions(+), 27 deletions(-) diff --git a/build/baobab.min.js b/build/baobab.min.js index 167f7ed..6a53552 100644 --- a/build/baobab.min.js +++ b/build/baobab.min.js @@ -1,2 +1,2 @@ /* baobab.js - Version: 1.0.0-rc1 - Author: Yomguithereal (Guillaume Plique) */ -!function(t){if("object"==typeof exports&&"undefined"!=typeof module)module.exports=t();else if("function"==typeof define&&define.amd)define([],t);else{var e;e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:this,e.Baobab=t()}}(function(){var t;return function e(t,r,n){function o(s,a){if(!r[s]){if(!t[s]){var u="function"==typeof require&&require;if(!a&&u)return u(s,!0);if(i)return i(s,!0);var h=new Error("Cannot find module '"+s+"'");throw h.code="MODULE_NOT_FOUND",h}var c=r[s]={exports:{}};t[s][0].call(c.exports,function(e){var r=t[s][1][e];return o(r?r:e)},c,c.exports,e,t,r,n)}return r[s].exports}for(var i="function"==typeof require&&require,s=0;sn;n++)t[n].fn!==e&&o.push(t[n]);return o}var s={once:"boolean",scope:"object"},a=0,u=function(){this._enabled=!0,this.unbindAll()};u.prototype.unbindAll=function(){return this._handlers={},this._handlersAll=[],this._handlersComplex=[],this},u.prototype.on=function(t,e,r){var n,i,u,h,c,l,f;if(o(t)){for(h in t)this.on(h,t[h],e);return this}for("function"==typeof t&&(r=e,e=t,t=null),c=[].concat(t),n=0,i=c.length;i>n;n++){if(h=c[n],f={order:a++,fn:e},"string"==typeof h)this._handlers[h]||(this._handlers[h]=[]),l=this._handlers[h];else if(h instanceof RegExp)l=this._handlersComplex,f.pattern=h;else{if(null!==h)throw Error("Emitter.on: invalid event.");l=this._handlersAll}for(u in r||{})s[u]&&(f[u]=r[u]);f.once&&(f.parent=l),l.push(f)}return this},u.prototype.once=function(){var t=Array.prototype.slice.call(arguments),r=t.length-1;return o(t[r])&&t.length>1?t[r]=e(t[r],{once:!0}):t.push({once:!0}),this.on.apply(this,t)},u.prototype.off=function(t,e){var r,n,s,a;if(1===arguments.length&&"function"==typeof t){e=arguments[0];for(s in this._handlers)this._handlers[s]=i(this._handlers[s],e),0===this._handlers[s].length&&delete this._handlers[s];this._handlersAll=i(this._handlersAll,e),this._handlersComplex=i(this._handlersComplex,e)}else if(1===arguments.length&&"string"==typeof t)delete this._handlers[t];else if(2===arguments.length){var u=[].concat(t);for(r=0,n=u.length;n>r;r++)a=u[r],this._handlers[a]=i(this._handlers[a],e),0===(this._handlers[a]||[]).length&&delete this._handlers[a]}else if(o(t))for(s in t)this.off(s,t[s]);return this},u.prototype.listeners=function(t){var e,r,n,o=this._handlersAll||[],i=!1;if(!t)throw Error("Emitter.listeners: no event provided.");for(o=o.concat(this._handlers[t]||[]),r=0,n=this._handlersComplex.length;n>r;r++)e=this._handlersComplex[r],~t.search(e.pattern)&&(i=!0,o.push(e));return this._handlersAll.length||i?o.sort(function(t,e){return t.order-e.order}):o.slice(0)},u.prototype.emit=function(t,e){if(!this._enabled)return this;if(o(t)){for(var r in t)this.emit(r,t[r]);return this}var n,i,s,a,u,h,c,l=[].concat(t),f=[];for(a=0,h=l.length;h>a;a++){for(i=this.listeners(l[a]),u=0,c=i.length;c>u;u++)s=i[u],n={type:l[a],target:this},arguments.length>1&&(n.data=e),s.fn.call("scope"in s?s.scope:this,n),s.once&&f.push(s);for(u=f.length-1;u>=0;u--)f[u].parent.splice(f[u].parent.indexOf(f[u]),1)}return this},u.prototype.kill=function(){this.unbindAll(),this._handlers=null,this._handlersAll=null,this._handlersComplex=null,this._enabled=!1},u.prototype.disable=function(){return this._enabled=!1,this},u.prototype.enable=function(){return this._enabled=!0,this},u.version="3.0.0","undefined"!=typeof n?("undefined"!=typeof r&&r.exports&&(n=r.exports=u),n.Emitter=u):"function"==typeof t&&t.amd?t("emmett",[],function(){return u}):this.Emitter=u}).call(this)},{}],4:[function(t,e,r){function n(t){return t+"$"+(new Date).getTime()+(""+Math.random()).replace("0.","")}function o(t,e){function r(t){this[t]=function(){var e=this.root[t].apply(this.root,arguments);return e instanceof i?this:e}}if(arguments.length<1&&(t={}),!(this instanceof o))return new o(t,e);if(!f.Object(t)&&!f.Array(t))throw Error("Baobab: invalid data.");if(s.call(this),this.options=u.shallowMerge(l,e),this._transaction={},this._future=void 0,this._cursors={},this._identity="[object Baobab]",this.data=u.deepClone(t),this.root=this.select([]),this.facets={},["get","set","unset","update"].forEach(r.bind(this)),!f.Object(this.options.facets))throw Error("Baobab: invalid facets.");for(var n in this.options.facets)this.addFacet(n,this.options.facets[n])}var i=t("./cursor.js"),s=t("emmett"),a=t("./facet.js"),u=t("./helpers.js"),h=t("./update.js"),c=t("./merge.js"),l=t("../defaults.js"),f=t("./type.js");u.inherits(o,s),o.prototype.addFacet=function(t,e){return this.facets[t]=this.createFacet(e),this},o.prototype.createFacet=function(t){return new a(this,t)},o.prototype.select=function(t){if(!t)throw Error("Baobab.select: invalid path.");if(arguments.length>1&&(t=u.arrayOf(arguments)),!f.Path(t))throw Error("Baobab.select: invalid path.");t=[].concat(t);var e,r=f.ComplexPath(t);r&&(e=u.solvePath(this.data,t,this));var o=t.map(function(t){return f.Function(t)?n("fn"):f.Object(t)?n("ob"):t}).join("|λ|");if(this._cursors[o])return this._cursors[o];var s=new i(this,t,e,o);return this._cursors[o]=s,s},o.prototype.stack=function(t){var e=this;if(!f.Object(t))throw Error("Baobab.update: wrong specification.");return this._transaction=c(t,this._transaction),this.options.autoCommit?this.options.asynchronous?(this._future||(this._future=setTimeout(e.commit.bind(e,null),0)),this):this.commit():this},o.prototype.commit=function(){var t=h(this.data,this._transaction,this.options),e=this.data;this._transaction={},this._future&&(this._future=clearTimeout(this._future));var r=this.options.validate,n=this.options.validationBehavior;if("function"==typeof r){var o=r.call(this,e,t.data,t.log);if(o instanceof Error&&(this.emit("invalid",{error:o}),"rollback"===n))return this}return this.data=t.data,this.emit("update",{log:t.log,previousState:e}),this},o.prototype.release=function(){var t;delete this.data,delete this._transaction;for(t in this._cursors)this._cursors[t].release();delete this._cursors;for(t in this.facets)this.facets[t].release();delete this.facets,this.kill()},o.prototype.toJSON=function(){return this.get()},o.prototype.toString=function(){return this._identity},e.exports=o},{"../defaults.js":2,"./cursor.js":5,"./facet.js":6,"./helpers.js":7,"./merge.js":8,"./type.js":9,"./update.js":10,emmett:3}],5:[function(t,e,r){function n(t,e,r,n){function o(t){if(i.recording&&!i.undoing){var e=a.getIn(t,i.solvedPath,i.tree),r=a.deepClone(e);i.archive.add(r)}return i.undoing=!1,i.emit("update")}var i=this;s.call(this),e=e||[],this.tree=t,this.path=e,this.hash=n,this.archive=null,this.recording=!1,this.undoing=!1,this._identity="[object Cursor]",this.complexPath=!!r,this.solvedPath=this.complexPath?r:this.path,this.relevant=void 0!==this.get(),this.updateHandler=function(t){var e=t.data.log,r=t.data.previousState,n=!1;if(i.complexPath&&(i.solvedPath=a.solvePath(i.tree.data,i.path,i.tree)),!i.path.length)return o(r);i.solvedPath&&(n=a.solveUpdate(e,[i.solvedPath]));var s=void 0!==i.get();i.relevant?s&&n?o(r):s||(i.emit("irrelevant"),i.relevant=!1):s&&n&&(i.emit("relevant"),o(r),i.relevant=!0)};var u=!1;this._lazyBind=function(){u||(u=!0,i.tree.on("update",i.updateHandler))},this.on=a.before(this._lazyBind,this.on.bind(this)),this.once=a.before(this._lazyBind,this.once.bind(this)),this.complexPath&&this._lazyBind()}function o(t,e,r,n){if(arguments.length>5)throw Error("baobab.Cursor."+t+": too many arguments.");if(arguments.length<4&&(n=r,r=[]),r=r||[],"splice"===t&&!u.Splicer(n)){if(!u.Array(n))throw Error("baobab.Cursor.splice: incorrect value.");n=[n]}if(e&&!e(n))throw Error("baobab.Cursor."+t+": incorrect value.");var o=[].concat(r),i=a.solvePath(this.get(),o,this.tree);if(!i)throw Error("baobab.Cursor."+t+": could not solve dynamic path.");var s={};s["$"+t]=n;var h=a.pathObject(i,s);return h}function i(t,e){n.prototype[t]=function(){var r=o.bind(this,t,e).apply(this,arguments);return this.update(r)}}var s=t("emmett"),a=t("./helpers.js"),u=(t("../defaults.js"),t("./type.js"));a.inherits(n,s),n.prototype.isRoot=function(){return!this.path.length},n.prototype.isLeaf=function(){return u.Primitive(this.get())},n.prototype.isBranch=function(){return!this.isLeaf()&&!this.isRoot()},n.prototype.root=function(){return this.tree.root()},n.prototype.select=function(t){if(arguments.length>1&&(t=a.arrayOf(arguments)),!u.Path(t))throw Error("baobab.Cursor.select: invalid path.");return this.tree.select(this.path.concat(t))},n.prototype.up=function(){return this.solvedPath&&this.solvedPath.length?this.tree.select(this.path.slice(0,-1)):null},n.prototype.left=function(){var t=+this.solvedPath[this.solvedPath.length-1];if(isNaN(t))throw Error("baobab.Cursor.left: cannot go left on a non-list type.");return t?this.tree.select(this.solvedPath.slice(0,-1).concat(t-1)):null},n.prototype.leftmost=function(){var t=+this.solvedPath[this.solvedPath.length-1];if(isNaN(t))throw Error("baobab.Cursor.leftmost: cannot go left on a non-list type.");return this.tree.select(this.solvedPath.slice(0,-1).concat(0))},n.prototype.right=function(){var t=+this.solvedPath[this.solvedPath.length-1];if(isNaN(t))throw Error("baobab.Cursor.right: cannot go right on a non-list type.");return t+1===this.up().get().length?null:this.tree.select(this.solvedPath.slice(0,-1).concat(t+1))},n.prototype.rightmost=function(){var t=+this.solvedPath[this.solvedPath.length-1];if(isNaN(t))throw Error("baobab.Cursor.right: cannot go right on a non-list type.");var e=this.up().get();return this.tree.select(this.solvedPath.slice(0,-1).concat(e.length-1))},n.prototype.down=function(){+this.solvedPath[this.solvedPath.length-1];return this.get()instanceof Array?this.tree.select(this.solvedPath.concat(0)):null},n.prototype.get=function(t){arguments.length>1&&(t=a.arrayOf(arguments));var e=this.solvedPath.concat([].concat(t||0===t?t:[]));return a.getIn(this.tree.data,e,this.tree)},i("set"),i("apply",u.Function),i("chain",u.Function),i("push"),i("unshift"),i("merge",u.Object),i("splice"),n.prototype.unset=function(t){if(void 0===t&&this.isRoot())throw Error("baobab.Cursor.unset: cannot remove root node.");var e=o.bind(this,"unset",null).apply(this,[t,!0]);return this.update(e)},n.prototype.update=function(t,e){if(arguments.length<2)return this.tree.stack(a.pathObject(this.solvedPath,t)),this;var r=[].concat(t),n=a.solvePath(this.get(),r,this.tree);if(!n)throw Error("baobab.Cursor.update: could not solve dynamic path.");return this.tree.stack(a.pathObject(this.solvedPath.concat(n),e)),this},n.prototype.startRecording=function(t){if(t=t||5,1>t)throw Error("baobab.Cursor.startRecording: invalid maximum number of records.");return this.archive?this:(this._lazyBind(),this.archive=a.archive(t),this.recording=!0,this)},n.prototype.stopRecording=function(){return this.recording=!1,this},n.prototype.undo=function(t){if(t=t||1,!this.recording)throw Error("baobab.Cursor.undo: cursor is not recording.");if(!u.PositiveInteger(t))throw Error("baobab.Cursor.undo: expecting a positive integer.");var e=this.archive.back(t);if(!e)throw Error("boabab.Cursor.undo: cannot find a relevant record ("+t+" back).");return this.undoing=!0,this.set(e)},n.prototype.hasHistory=function(){return!(!this.archive||!this.archive.get().length)},n.prototype.getHistory=function(){return this.archive?this.archive.get():[]},n.prototype.clearHistory=function(){return this.archive=null,this},n.prototype.release=function(){this.tree.off("update",this.updateHandler),this.hash&&delete this.tree._cursors[this.hash],delete this.tree,delete this.path,delete this.solvedPath,delete this.archive,this.kill()},n.prototype.toJSON=function(){return this.get()},n.prototype.toString=function(){return this._identity},e.exports=n},{"../defaults.js":2,"./helpers.js":7,"./type.js":9,emmett:3}],6:[function(t,e,r){function n(t,e,r){var n=this,u=!1,h=e.cursors,c="function"==typeof e.cursors,l=e.get,f=null;o.call(this),this.tree=t,this.cursors=null,this.refresh=function(){if(c||!this.cursors){u=!1;var e=h;if(c&&(e=h.call(r)),!a.FacetCursors(e))throw Error("baobab.Facet: incorrect cursors mapping.");this.cursors={},Object.keys(e).forEach(function(r){if(e[r]instanceof i)return void(n.cursors[r]=e[r]);if(a.Path(e[r]))return void(n.cursors[r]=t.select(e[r]));throw Error("baobab.Facet: invalid path returned by function in cursors mapping.")})}},this.get=function(){if(u)return f;var t={};for(var e in n.cursors)t[e]=n.cursors[e].get();return f="function"==typeof l?l.call(null,t):t,u=!0,f},this.updateHandler=function(t){var e=Object.keys(n.cursors).map(function(t){return n.cursors[t].solvedPath});s.solveUpdate(t.data.log,e)&&(u=!1,n.emit("update"))},this.refresh(),this.tree.on("update",this.updateHandler)}var o=t("emmett"),i=t("./cursor.js"),s=t("./helpers.js"),a=t("./type.js");s.inherits(n,o),n.prototype.release=function(){this.tree.off("update",this.updateHandler),this.tree=null,this.cursors=null,this.kill()},e.exports=n},{"./cursor.js":5,"./helpers.js":7,"./type.js":9,emmett:3}],7:[function(t,e,r){(function(r){function n(t){return Array.prototype.slice.call(t)}function o(t,e){return function(){t(),e.apply(null,arguments)}}function i(t,e,r){var o=n(arguments).slice(3);return e=+e,r=+r,t.slice(0,e).concat(t.slice(e+r).concat(o))}function s(t,e){var r,n={};for(r in t)n[r]=t[r];for(r in e)n[r]=e[r];return n}function a(t){var e=t.source,r="";return t.global&&(r+="g"),t.multiline&&(r+="m"),t.ignoreCase&&(r+="i"),t.sticky&&(r+="y"),t.unicode&&(r+="u"),new RegExp(e,r)}function u(t,e){if(!e||"object"!=typeof e||e instanceof Error||"ArrayBuffer"in r&&e instanceof ArrayBuffer)return e;if(w.Array(e)){if(t){var n,o,i=[];for(n=0,o=e.length;o>n;n++)i.push(P(e[n]));return i}return e.slice(0)}if(w.Date(e))return new Date(e.getTime());if(e instanceof RegExp)return a(e);if(w.Object(e)){var s,u={};e.constructor&&e.constructor!==Object&&(u=Object.create(e.constructor.prototype));for(s in e)e.hasOwnProperty(s)&&(u[s]=t?P(e[s]):e[s]);return u}return e}function h(t,e){return function(r){return e(t(r))}}function c(t,e){var r,n;for(r=0,n=t.length;n>r;r++)if(e(t[r]))return t[r]}function l(t,e){var r,n;for(r=0,n=t.length;n>r;r++)if(e(t[r]))return r;return-1}function f(t,e){var r,n=!0;if(!t)return!1;for(r in e)if(w.Object(e[r]))n=n&&f(t[r],e[r]);else if(w.Array(e[r]))n=n&&!!~e[r].indexOf(t[r]);else if(t[r]!==e[r])return!1;return n}function d(t,e){return c(t,function(t){return f(t,e)})}function y(t,e){return l(t,function(t){return f(t,e)})}function v(t,e,r){e=e||[];var n,o,i,s=t;for(o=0,i=e.length;i>o;o++){if(!s)return;if("function"==typeof e[o]){if(!w.Array(s))return;s=c(s,e[o])}else if("object"==typeof e[o])if(r&&"$cursor"in e[o]){if(!w.Path(e[o].$cursor))throw Error("baobab.getIn: $cursor path must be an array.");n=r.get(e[o].$cursor),s=s[n]}else{if(!w.Array(s))return;s=d(s,e[o])}else s=s[e[o]]}return s}function g(t,e,r){var n,o,i,s=[],a=t;for(o=0,i=e.length;i>o;o++){if(!a)return null;if("function"==typeof e[o]){if(!w.Array(a))return;n=l(a,e[o]),s.push(n),a=a[n]}else if("object"==typeof e[o])if(r&&"$cursor"in e[o]){if(!w.Path(e[o].$cursor))throw Error("baobab.getIn: $cursor path must be an array.");p=r.get(e[o].$cursor),s.push(p),a=a[p]}else{if(!w.Array(a))return;n=y(a,e[o]),s.push(n),a=a[n]}else s.push(e[o]),a=a[e[o]]||{}}return s}function b(t,e){var r,n,o,i,s,a,u,h,c;for(r=0,i=e.length;i>r;r++)for(u=e[r],n=0,s=t.length;s>n;n++)for(h=t[n],o=0,a=h.length;a>o&&(c=h[o],c==u[o]);o++)if(o+1===a||o+1===u.length)return!0;return!1}function m(t,e){var r,n=t.length,o={},i=o;for(n||(o=e),r=0;n>r;r++)i[t[r]]=r+1===n?e:{},i=i[t[r]];return o}function j(t,e){t.super_=e;var r=function(){};r.prototype=e.prototype,t.prototype=new r,t.prototype.constructor=t}function _(t){var e=[];return{add:function(r){e.unshift(r),e.length>t&&(e.length=t)},back:function(t){var r=e[t-1];return r&&(e=e.slice(t)),r},get:function(){return e}}}var w=t("./type.js"),$=u.bind(null,!1),P=u.bind(null,!0);e.exports={archive:_,arrayOf:n,before:o,deepClone:P,shallowClone:$,shallowMerge:s,compose:h,getIn:v,inherits:j,pathObject:m,solvePath:g,solveUpdate:b,splice:i}}).call(this,"undefined"!=typeof global?global:"undefined"!=typeof self?self:"undefined"!=typeof window?window:{})},{"./type.js":9}],8:[function(t,e,r){function n(t,e,r){a.forEach(function(e){r!==e&&delete t[e]}),t[r]=e[r]}function o(t,e){var r,u=i.shallowClone(e||{});a.forEach(function(e){t[e]&&n(u,t,e)}),t.$chain&&(a.slice(0,-1).forEach(function(t){delete u[t]}),u.$apply=u.$apply?i.compose(u.$apply,t.$chain):t.$chain),(t.$splice||u.$splice)&&(u.$splice=[].concat(u.$splice||[]).concat(t.$splice||[])),(t.$push||u.$push)&&(u.$push=[].concat(u.$push||[]).concat(t.$push||[])),(t.$unshift||u.$unshift)&&(u.$unshift=[].concat(t.$unshift||[]).concat(u.$unshift||[]));for(r in t)s.Object(t[r])?u[r]=o(t[r],u[r]):"$"!==r[0]&&(u[r]=t[r]);return u}var i=t("./helpers.js"),s=t("./type.js"),a=["$unset","$set","$merge","$apply"];e.exports=o},{"./helpers.js":7,"./type.js":9}],9:[function(t,e,r){function n(t,e){return e.some(function(e){return o[e](t)})}var o={};o.Array=function(t){return Array.isArray(t)},o.Object=function(t){return t&&"object"==typeof t&&!Array.isArray(t)&&!(t instanceof Function)},o.String=function(t){return"string"==typeof t},o.Number=function(t){return"number"==typeof t},o.PositiveInteger=function(t){return"number"==typeof t&&t>0&&t%1===0},o.Function=function(t){return"function"==typeof t},o.Primitive=function(t){return"string"==typeof t||"number"==typeof t||"boolean"==typeof t},o.Date=function(t){return t instanceof Date},o.NonScalar=function(t){return o.Object(t)||o.Array(t)},o.Splicer=function(t){return o.Array(t)&&t.every(o.Array)},o.Path=function(t){var e=["String","Number","Function","Object"];return o.Array(t)?t.every(function(t){return n(t,e)}):n(t,e)},o.ComplexPath=function(t){return t.some(function(t){return n(t,["Object","Function"])})},o.FacetCursors=function(e){return o.Object(e)?Object.keys(e).every(function(r){var n=e[r];return o.Path(n)||n instanceof t("./cursor.js")}):!1},o.FacetFacets=function(e){return o.Object(e)?Object.keys(e).every(function(r){var n=e[r];return"string"==typeof n||n instanceof t("./facet.js")}):!1},e.exports=o},{"./cursor.js":5,"./facet.js":6}],10:[function(t,e,r){function n(t,e){var r=new Error("baobab.update: "+e+" at path /"+t.slice(1).join("/"));return r.path=t,r}var o=t("./helpers.js"),i=t("./type.js");e.exports=function(t,e,r){if(r=r||{},!i.Object(t)&&!i.Array(t))throw Error("baobab.update: invalid target.");var s={};t={root:o.shallowClone(t)};var a=function(t,e,r,u){r=r||["root"];var h,c,l,f=r.join("|λ|"),p=r[r.length-1],d=Object.keys(e).some(function(t){return!!~["$set","$push","$unshift","$splice","$unset","$merge","$apply"].indexOf(t)});if(d){s[f]=!0;for(c in e){if("$unset"===c){var y=r[r.length-2];if(!i.Object(u[y]))throw n(r.slice(0,-1),"using command $unset on a non-object");u[y]=o.shallowClone(t),delete u[y][p];break}if("$set"===c){l=e.$set,t[p]=l;break}if("$apply"===c){if(h=e.$apply,"function"!=typeof h)throw n(r,"using command $apply with a non function");t[p]=h.call(null,t[p]);break}if("$merge"===c){if(l=e.$merge,!i.Object(t[p])||!i.Object(l))throw n(r,"using command $merge with a non object");t[p]=o.shallowMerge(t[p],l);break}if("$splice"===c){if(l=e.$splice,!i.Array(t[p]))throw n(r,"using command $push to a non array");l.forEach(function(e){t[p]=o.splice.apply(null,[t[p]].concat(e))})}if("$push"===c){if(l=e.$push,!i.Array(t[p]))throw n(r,"using command $push to a non array");t[p]=t[p].concat(l)}if("$unshift"===c){if(l=e.$unshift,!i.Array(t[p]))throw n(r,"using command $unshift to a non array");t[p]=[].concat(l).concat(t[p])}}}else for(c in e)t[p][c]="undefined"==typeof t[p][c]?{}:o.shallowClone(t[p][c]),a(t[p],e[c],r.concat(c),t)};return a(t,e),{data:t.root,log:Object.keys(s).map(function(t){return t.split("|λ|").slice(1)})}}},{"./helpers.js":7,"./type.js":9}]},{},[1])(1)}); \ No newline at end of file +!function(t){if("object"==typeof exports&&"undefined"!=typeof module)module.exports=t();else if("function"==typeof define&&define.amd)define([],t);else{var e;e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:this,e.Baobab=t()}}(function(){var t;return function e(t,r,n){function o(s,a){if(!r[s]){if(!t[s]){var u="function"==typeof require&&require;if(!a&&u)return u(s,!0);if(i)return i(s,!0);var c=new Error("Cannot find module '"+s+"'");throw c.code="MODULE_NOT_FOUND",c}var h=r[s]={exports:{}};t[s][0].call(h.exports,function(e){var r=t[s][1][e];return o(r?r:e)},h,h.exports,e,t,r,n)}return r[s].exports}for(var i="function"==typeof require&&require,s=0;sn;n++)t[n].fn!==e&&o.push(t[n]);return o}var s={once:"boolean",scope:"object"},a=0,u=function(){this._enabled=!0,this.unbindAll()};u.prototype.unbindAll=function(){return this._handlers={},this._handlersAll=[],this._handlersComplex=[],this},u.prototype.on=function(t,e,r){var n,i,u,c,h,l,f;if(o(t)){for(c in t)this.on(c,t[c],e);return this}for("function"==typeof t&&(r=e,e=t,t=null),h=[].concat(t),n=0,i=h.length;i>n;n++){if(c=h[n],f={order:a++,fn:e},"string"==typeof c)this._handlers[c]||(this._handlers[c]=[]),l=this._handlers[c];else if(c instanceof RegExp)l=this._handlersComplex,f.pattern=c;else{if(null!==c)throw Error("Emitter.on: invalid event.");l=this._handlersAll}for(u in r||{})s[u]&&(f[u]=r[u]);f.once&&(f.parent=l),l.push(f)}return this},u.prototype.once=function(){var t=Array.prototype.slice.call(arguments),r=t.length-1;return o(t[r])&&t.length>1?t[r]=e(t[r],{once:!0}):t.push({once:!0}),this.on.apply(this,t)},u.prototype.off=function(t,e){var r,n,s,a;if(1===arguments.length&&"function"==typeof t){e=arguments[0];for(s in this._handlers)this._handlers[s]=i(this._handlers[s],e),0===this._handlers[s].length&&delete this._handlers[s];this._handlersAll=i(this._handlersAll,e),this._handlersComplex=i(this._handlersComplex,e)}else if(1===arguments.length&&"string"==typeof t)delete this._handlers[t];else if(2===arguments.length){var u=[].concat(t);for(r=0,n=u.length;n>r;r++)a=u[r],this._handlers[a]=i(this._handlers[a],e),0===(this._handlers[a]||[]).length&&delete this._handlers[a]}else if(o(t))for(s in t)this.off(s,t[s]);return this},u.prototype.listeners=function(t){var e,r,n,o=this._handlersAll||[],i=!1;if(!t)throw Error("Emitter.listeners: no event provided.");for(o=o.concat(this._handlers[t]||[]),r=0,n=this._handlersComplex.length;n>r;r++)e=this._handlersComplex[r],~t.search(e.pattern)&&(i=!0,o.push(e));return this._handlersAll.length||i?o.sort(function(t,e){return t.order-e.order}):o.slice(0)},u.prototype.emit=function(t,e){if(!this._enabled)return this;if(o(t)){for(var r in t)this.emit(r,t[r]);return this}var n,i,s,a,u,c,h,l=[].concat(t),f=[];for(a=0,c=l.length;c>a;a++){for(i=this.listeners(l[a]),u=0,h=i.length;h>u;u++)s=i[u],n={type:l[a],target:this},arguments.length>1&&(n.data=e),s.fn.call("scope"in s?s.scope:this,n),s.once&&f.push(s);for(u=f.length-1;u>=0;u--)f[u].parent.splice(f[u].parent.indexOf(f[u]),1)}return this},u.prototype.kill=function(){this.unbindAll(),this._handlers=null,this._handlersAll=null,this._handlersComplex=null,this._enabled=!1},u.prototype.disable=function(){return this._enabled=!1,this},u.prototype.enable=function(){return this._enabled=!0,this},u.version="3.0.0","undefined"!=typeof n?("undefined"!=typeof r&&r.exports&&(n=r.exports=u),n.Emitter=u):"function"==typeof t&&t.amd?t("emmett",[],function(){return u}):this.Emitter=u}).call(this)},{}],4:[function(t,e,r){function n(t){return t+"$"+(new Date).getTime()+(""+Math.random()).replace("0.","")}function o(t,e){function r(t){this[t]=function(){var e=this.root[t].apply(this.root,arguments);return e instanceof i?this:e}}if(arguments.length<1&&(t={}),!(this instanceof o))return new o(t,e);if(!f.Object(t)&&!f.Array(t))throw Error("Baobab: invalid data.");if(s.call(this),this.options=u.shallowMerge(l,e),this._transaction={},this._future=void 0,this._cursors={},this._identity="[object Baobab]",this.data=u.deepClone(t),this.root=this.select([]),this.facets={},["get","set","unset","update"].forEach(r.bind(this)),!f.Object(this.options.facets))throw Error("Baobab: invalid facets.");for(var n in this.options.facets)this.addFacet(n,this.options.facets[n])}var i=t("./cursor.js"),s=t("emmett"),a=t("./facet.js"),u=t("./helpers.js"),c=t("./update.js"),h=t("./merge.js"),l=t("../defaults.js"),f=t("./type.js");u.inherits(o,s),o.prototype.addFacet=function(t,e){return this.facets[t]=this.createFacet(e),this},o.prototype.createFacet=function(t){return new a(this,t)},o.prototype.select=function(t){if(!t)throw Error("Baobab.select: invalid path.");if(arguments.length>1&&(t=u.arrayOf(arguments)),!f.Path(t))throw Error("Baobab.select: invalid path.");t=[].concat(t);var e,r=f.ComplexPath(t);r&&(e=u.solvePath(this.data,t,this));var o=t.map(function(t){return f.Function(t)?n("fn"):f.Object(t)?n("ob"):t}).join("|λ|");if(this._cursors[o])return this._cursors[o];var s=new i(this,t,e,o);return this._cursors[o]=s,s},o.prototype.stack=function(t){var e=this;if(!f.Object(t))throw Error("Baobab.update: wrong specification.");return this._transaction=h(t,this._transaction),this.options.autoCommit?this.options.asynchronous?(this._future||(this._future=setTimeout(e.commit.bind(e,null),0)),this):this.commit():this},o.prototype.commit=function(){var t=c(this.data,this._transaction,this.options),e=this.data;this._transaction={},this._future&&(this._future=clearTimeout(this._future));var r=this.options.validate,n=this.options.validationBehavior;if("function"==typeof r){var o=r.call(this,e,t.data,t.log);if(o instanceof Error&&(this.emit("invalid",{error:o}),"rollback"===n))return this}return this.data=t.data,this.emit("update",{log:t.log,previousState:e}),this},o.prototype.release=function(){var t;delete this.data,delete this._transaction;for(t in this._cursors)this._cursors[t].release();delete this._cursors;for(t in this.facets)this.facets[t].release();delete this.facets,this.kill()},o.prototype.toJSON=function(){return this.get()},o.prototype.toString=function(){return this._identity},e.exports=o},{"../defaults.js":2,"./cursor.js":5,"./facet.js":6,"./helpers.js":7,"./merge.js":8,"./type.js":9,"./update.js":10,emmett:3}],5:[function(t,e,r){function n(t,e,r,n){function o(t){if(i.recording&&!i.undoing){var e=a.getIn(t,i.solvedPath,i.tree),r=a.deepClone(e);i.archive.add(r)}return i.undoing=!1,i.emit("update")}var i=this;s.call(this),e=e||[],this.tree=t,this.path=e,this.hash=n,this.archive=null,this.recording=!1,this.undoing=!1,this._identity="[object Cursor]",this.complexPath=!!r,this.solvedPath=this.complexPath?r:this.path,this.relevant=void 0!==this.get(),this.updateHandler=function(t){var e=t.data.log,r=t.data.previousState,n=!1;if(i.complexPath&&(i.solvedPath=a.solvePath(i.tree.data,i.path,i.tree)),!i.path.length)return o(r);i.solvedPath&&(n=a.solveUpdate(e,[i.solvedPath]));var s=void 0!==i.get();i.relevant?s&&n?o(r):s||(i.emit("irrelevant"),i.relevant=!1):s&&n&&(i.emit("relevant"),o(r),i.relevant=!0)};var u=!1;this._lazyBind=function(){u||(u=!0,i.tree.on("update",i.updateHandler))},this.on=a.before(this._lazyBind,this.on.bind(this)),this.once=a.before(this._lazyBind,this.once.bind(this)),this.complexPath&&this._lazyBind()}function o(t,e,r,n){if(arguments.length>5)throw Error("baobab.Cursor."+t+": too many arguments.");if(arguments.length<4&&(n=r,r=[]),r=r||[],"splice"===t&&!u.Splicer(n)){if(!u.Array(n))throw Error("baobab.Cursor.splice: incorrect value.");n=[n]}if(e&&!e(n))throw Error("baobab.Cursor."+t+": incorrect value.");var o=[].concat(r),i=a.solvePath(this.get(),o,this.tree);if(!i)throw Error("baobab.Cursor."+t+": could not solve dynamic path.");var s={};s["$"+t]=n;var c=a.pathObject(i,s);return c}function i(t,e){n.prototype[t]=function(){var r=o.bind(this,t,e).apply(this,arguments);return this.update(r)}}var s=t("emmett"),a=t("./helpers.js"),u=(t("../defaults.js"),t("./type.js"));a.inherits(n,s),n.prototype.isRoot=function(){return!this.path.length},n.prototype.isLeaf=function(){return u.Primitive(this.get())},n.prototype.isBranch=function(){return!this.isLeaf()&&!this.isRoot()},n.prototype.root=function(){return this.tree.root()},n.prototype.select=function(t){if(arguments.length>1&&(t=a.arrayOf(arguments)),!u.Path(t))throw Error("baobab.Cursor.select: invalid path.");return this.tree.select(this.path.concat(t))},n.prototype.up=function(){return this.solvedPath&&this.solvedPath.length?this.tree.select(this.path.slice(0,-1)):null},n.prototype.left=function(){var t=+this.solvedPath[this.solvedPath.length-1];if(isNaN(t))throw Error("baobab.Cursor.left: cannot go left on a non-list type.");return t?this.tree.select(this.solvedPath.slice(0,-1).concat(t-1)):null},n.prototype.leftmost=function(){var t=+this.solvedPath[this.solvedPath.length-1];if(isNaN(t))throw Error("baobab.Cursor.leftmost: cannot go left on a non-list type.");return this.tree.select(this.solvedPath.slice(0,-1).concat(0))},n.prototype.right=function(){var t=+this.solvedPath[this.solvedPath.length-1];if(isNaN(t))throw Error("baobab.Cursor.right: cannot go right on a non-list type.");return t+1===this.up().get().length?null:this.tree.select(this.solvedPath.slice(0,-1).concat(t+1))},n.prototype.rightmost=function(){var t=+this.solvedPath[this.solvedPath.length-1];if(isNaN(t))throw Error("baobab.Cursor.right: cannot go right on a non-list type.");var e=this.up().get();return this.tree.select(this.solvedPath.slice(0,-1).concat(e.length-1))},n.prototype.down=function(){+this.solvedPath[this.solvedPath.length-1];return this.get()instanceof Array?this.tree.select(this.solvedPath.concat(0)):null},n.prototype.get=function(t){arguments.length>1&&(t=a.arrayOf(arguments));var e=this.solvedPath.concat([].concat(t||0===t?t:[]));return a.getIn(this.tree.data,e,this.tree)},i("set"),i("apply",u.Function),i("chain",u.Function),i("push"),i("unshift"),i("merge",u.Object),i("splice"),n.prototype.unset=function(t){if(void 0===t&&this.isRoot())throw Error("baobab.Cursor.unset: cannot remove root node.");var e=o.bind(this,"unset",null).apply(this,[t,!0]);return this.update(e)},n.prototype.update=function(t,e){if(arguments.length<2)return this.tree.stack(a.pathObject(this.solvedPath,t)),this;var r=[].concat(t),n=a.solvePath(this.get(),r,this.tree);if(!n)throw Error("baobab.Cursor.update: could not solve dynamic path.");return this.tree.stack(a.pathObject(this.solvedPath.concat(n),e)),this},n.prototype.startRecording=function(t){if(t=t||5,1>t)throw Error("baobab.Cursor.startRecording: invalid maximum number of records.");return this.archive?this:(this._lazyBind(),this.archive=a.archive(t),this.recording=!0,this)},n.prototype.stopRecording=function(){return this.recording=!1,this},n.prototype.undo=function(t){if(t=t||1,!this.recording)throw Error("baobab.Cursor.undo: cursor is not recording.");if(!u.PositiveInteger(t))throw Error("baobab.Cursor.undo: expecting a positive integer.");var e=this.archive.back(t);if(!e)throw Error("boabab.Cursor.undo: cannot find a relevant record ("+t+" back).");return this.undoing=!0,this.set(e)},n.prototype.hasHistory=function(){return!(!this.archive||!this.archive.get().length)},n.prototype.getHistory=function(){return this.archive?this.archive.get():[]},n.prototype.clearHistory=function(){return this.archive=null,this},n.prototype.release=function(){this.tree.off("update",this.updateHandler),this.hash&&delete this.tree._cursors[this.hash],delete this.tree,delete this.path,delete this.solvedPath,delete this.archive,this.kill()},n.prototype.toJSON=function(){return this.get()},n.prototype.toString=function(){return this._identity},e.exports=n},{"../defaults.js":2,"./helpers.js":7,"./type.js":9,emmett:3}],6:[function(t,e,r){function n(t,e,r){function u(e,o,s,u){if(e||h){l=!1;var f=o;if(e&&(f=o.call(r)),!u(f))throw Error("baobab.Facet: incorrect "+s+" mapping.");c[s]={},Object.keys(f).forEach(function(e){if("cursors"===s){if(f[e]instanceof i)return void(c.cursors[e]=f[e]);if(a.Path(f[e]))return void(c.cursors[e]=t.select(f[e]))}else{if(f[e]instanceof n)return void(c.facets[e]=f[e]);if("string"==typeof f[e]){if(c.facets[e]=t.facets[f[e]],!c.facets)throw Error('baobab.Facet: unkown "'+f[e]+'" facet in facets mapping.');return}}throw Error("baobab.Facet: invalid value returned by function in "+s+" mapping.")})}}var c=this,h=!0,l=!1,f=e.get;o.call(this),this.tree=t,this.cursors={},this.facets={};var p=e.cursors,d=e.facets,y="function"==typeof e.cursors,v="function"==typeof e.facets;this.refresh=function(){p&&u(y,p,"cursors",a.FacetCursors),d&&u(v,d,"facets",a.FacetFacets)},this.get=function(){if(l)return e;var t,e={};for(t in c.facets)e[t]=c.facets[t].get();for(t in c.cursors)e[t]=c.cursors[t].get();return e="function"==typeof f?f.call(null,e):e,l=!0,e},this.updateHandler=function(t){var e=Object.keys(c.cursors).map(function(t){return c.cursors[t].solvedPath});s.solveUpdate(t.data.log,e)&&(l=!1,c.emit("update"))},this.refresh(),this.tree.on("update",this.updateHandler),h=!1}var o=t("emmett"),i=t("./cursor.js"),s=t("./helpers.js"),a=t("./type.js");s.inherits(n,o),n.prototype.release=function(){this.tree.off("update",this.updateHandler),this.tree=null,this.cursors=null,this.facets=null,this.kill()},e.exports=n},{"./cursor.js":5,"./helpers.js":7,"./type.js":9,emmett:3}],7:[function(t,e,r){(function(r){function n(t){return Array.prototype.slice.call(t)}function o(t,e){return function(){t(),e.apply(null,arguments)}}function i(t,e,r){var o=n(arguments).slice(3);return e=+e,r=+r,t.slice(0,e).concat(t.slice(e+r).concat(o))}function s(t,e){var r,n={};for(r in t)n[r]=t[r];for(r in e)n[r]=e[r];return n}function a(t){var e=t.source,r="";return t.global&&(r+="g"),t.multiline&&(r+="m"),t.ignoreCase&&(r+="i"),t.sticky&&(r+="y"),t.unicode&&(r+="u"),new RegExp(e,r)}function u(t,e){if(!e||"object"!=typeof e||e instanceof Error||"ArrayBuffer"in r&&e instanceof ArrayBuffer)return e;if(w.Array(e)){if(t){var n,o,i=[];for(n=0,o=e.length;o>n;n++)i.push(P(e[n]));return i}return e.slice(0)}if(w.Date(e))return new Date(e.getTime());if(e instanceof RegExp)return a(e);if(w.Object(e)){var s,u={};e.constructor&&e.constructor!==Object&&(u=Object.create(e.constructor.prototype));for(s in e)e.hasOwnProperty(s)&&(u[s]=t?P(e[s]):e[s]);return u}return e}function c(t,e){return function(r){return e(t(r))}}function h(t,e){var r,n;for(r=0,n=t.length;n>r;r++)if(e(t[r]))return t[r]}function l(t,e){var r,n;for(r=0,n=t.length;n>r;r++)if(e(t[r]))return r;return-1}function f(t,e){var r,n=!0;if(!t)return!1;for(r in e)if(w.Object(e[r]))n=n&&f(t[r],e[r]);else if(w.Array(e[r]))n=n&&!!~e[r].indexOf(t[r]);else if(t[r]!==e[r])return!1;return n}function d(t,e){return h(t,function(t){return f(t,e)})}function y(t,e){return l(t,function(t){return f(t,e)})}function v(t,e,r){e=e||[];var n,o,i,s=t;for(o=0,i=e.length;i>o;o++){if(!s)return;if("function"==typeof e[o]){if(!w.Array(s))return;s=h(s,e[o])}else if("object"==typeof e[o])if(r&&"$cursor"in e[o]){if(!w.Path(e[o].$cursor))throw Error("baobab.getIn: $cursor path must be an array.");n=r.get(e[o].$cursor),s=s[n]}else{if(!w.Array(s))return;s=d(s,e[o])}else s=s[e[o]]}return s}function g(t,e,r){var n,o,i,s=[],a=t;for(o=0,i=e.length;i>o;o++){if(!a)return null;if("function"==typeof e[o]){if(!w.Array(a))return;n=l(a,e[o]),s.push(n),a=a[n]}else if("object"==typeof e[o])if(r&&"$cursor"in e[o]){if(!w.Path(e[o].$cursor))throw Error("baobab.getIn: $cursor path must be an array.");p=r.get(e[o].$cursor),s.push(p),a=a[p]}else{if(!w.Array(a))return;n=y(a,e[o]),s.push(n),a=a[n]}else s.push(e[o]),a=a[e[o]]||{}}return s}function b(t,e){var r,n,o,i,s,a,u,c,h;for(r=0,i=e.length;i>r;r++)for(u=e[r],n=0,s=t.length;s>n;n++)for(c=t[n],o=0,a=c.length;a>o&&(h=c[o],h==u[o]);o++)if(o+1===a||o+1===u.length)return!0;return!1}function m(t,e){var r,n=t.length,o={},i=o;for(n||(o=e),r=0;n>r;r++)i[t[r]]=r+1===n?e:{},i=i[t[r]];return o}function j(t,e){t.super_=e;var r=function(){};r.prototype=e.prototype,t.prototype=new r,t.prototype.constructor=t}function _(t){var e=[];return{add:function(r){e.unshift(r),e.length>t&&(e.length=t)},back:function(t){var r=e[t-1];return r&&(e=e.slice(t)),r},get:function(){return e}}}var w=t("./type.js"),$=u.bind(null,!1),P=u.bind(null,!0);e.exports={archive:_,arrayOf:n,before:o,deepClone:P,shallowClone:$,shallowMerge:s,compose:c,getIn:v,inherits:j,pathObject:m,solvePath:g,solveUpdate:b,splice:i}}).call(this,"undefined"!=typeof global?global:"undefined"!=typeof self?self:"undefined"!=typeof window?window:{})},{"./type.js":9}],8:[function(t,e,r){function n(t,e,r){a.forEach(function(e){r!==e&&delete t[e]}),t[r]=e[r]}function o(t,e){var r,u=i.shallowClone(e||{});a.forEach(function(e){t[e]&&n(u,t,e)}),t.$chain&&(a.slice(0,-1).forEach(function(t){delete u[t]}),u.$apply=u.$apply?i.compose(u.$apply,t.$chain):t.$chain),(t.$splice||u.$splice)&&(u.$splice=[].concat(u.$splice||[]).concat(t.$splice||[])),(t.$push||u.$push)&&(u.$push=[].concat(u.$push||[]).concat(t.$push||[])),(t.$unshift||u.$unshift)&&(u.$unshift=[].concat(t.$unshift||[]).concat(u.$unshift||[]));for(r in t)s.Object(t[r])?u[r]=o(t[r],u[r]):"$"!==r[0]&&(u[r]=t[r]);return u}var i=t("./helpers.js"),s=t("./type.js"),a=["$unset","$set","$merge","$apply"];e.exports=o},{"./helpers.js":7,"./type.js":9}],9:[function(t,e,r){function n(t,e){return e.some(function(e){return o[e](t)})}var o={};o.Array=function(t){return Array.isArray(t)},o.Object=function(t){return t&&"object"==typeof t&&!Array.isArray(t)&&!(t instanceof Function)},o.String=function(t){return"string"==typeof t},o.Number=function(t){return"number"==typeof t},o.PositiveInteger=function(t){return"number"==typeof t&&t>0&&t%1===0},o.Function=function(t){return"function"==typeof t},o.Primitive=function(t){return"string"==typeof t||"number"==typeof t||"boolean"==typeof t},o.Date=function(t){return t instanceof Date},o.NonScalar=function(t){return o.Object(t)||o.Array(t)},o.Splicer=function(t){return o.Array(t)&&t.every(o.Array)},o.Path=function(t){var e=["String","Number","Function","Object"];return o.Array(t)?t.every(function(t){return n(t,e)}):n(t,e)},o.ComplexPath=function(t){return t.some(function(t){return n(t,["Object","Function"])})},o.FacetCursors=function(e){return o.Object(e)?Object.keys(e).every(function(r){var n=e[r];return o.Path(n)||n instanceof t("./cursor.js")}):!1},o.FacetFacets=function(e){return o.Object(e)?Object.keys(e).every(function(r){var n=e[r];return"string"==typeof n||n instanceof t("./facet.js")}):!1},e.exports=o},{"./cursor.js":5,"./facet.js":6}],10:[function(t,e,r){function n(t,e){var r=new Error("baobab.update: "+e+" at path /"+t.slice(1).join("/"));return r.path=t,r}var o=t("./helpers.js"),i=t("./type.js");e.exports=function(t,e,r){if(r=r||{},!i.Object(t)&&!i.Array(t))throw Error("baobab.update: invalid target.");var s={};t={root:o.shallowClone(t)};var a=function(t,e,r,u){r=r||["root"];var c,h,l,f=r.join("|λ|"),p=r[r.length-1],d=Object.keys(e).some(function(t){return!!~["$set","$push","$unshift","$splice","$unset","$merge","$apply"].indexOf(t)});if(d){s[f]=!0;for(h in e){if("$unset"===h){var y=r[r.length-2];if(!i.Object(u[y]))throw n(r.slice(0,-1),"using command $unset on a non-object");u[y]=o.shallowClone(t),delete u[y][p];break}if("$set"===h){l=e.$set,t[p]=l;break}if("$apply"===h){if(c=e.$apply,"function"!=typeof c)throw n(r,"using command $apply with a non function");t[p]=c.call(null,t[p]);break}if("$merge"===h){if(l=e.$merge,!i.Object(t[p])||!i.Object(l))throw n(r,"using command $merge with a non object");t[p]=o.shallowMerge(t[p],l);break}if("$splice"===h){if(l=e.$splice,!i.Array(t[p]))throw n(r,"using command $push to a non array");l.forEach(function(e){t[p]=o.splice.apply(null,[t[p]].concat(e))})}if("$push"===h){if(l=e.$push,!i.Array(t[p]))throw n(r,"using command $push to a non array");t[p]=t[p].concat(l)}if("$unshift"===h){if(l=e.$unshift,!i.Array(t[p]))throw n(r,"using command $unshift to a non array");t[p]=[].concat(l).concat(t[p])}}}else for(h in e)t[p][h]="undefined"==typeof t[p][h]?{}:o.shallowClone(t[p][h]),a(t[p],e[h],r.concat(h),t)};return a(t,e),{data:t.root,log:Object.keys(s).map(function(t){return t.split("|λ|").slice(1)})}}},{"./helpers.js":7,"./type.js":9}]},{},[1])(1)}); \ No newline at end of file diff --git a/src/facet.js b/src/facet.js index ce06d9b..d7a30c7 100644 --- a/src/facet.js +++ b/src/facet.js @@ -12,9 +12,8 @@ var EventEmitter = require('emmett'), function Facet(tree, definition, scope) { var self = this; - var solved = false, - mapping = definition.cursors, - complex = typeof definition.cursors === 'function', + var firstTime = true, + solved = false, getter = definition.get, data = null; @@ -23,40 +22,81 @@ function Facet(tree, definition, scope) { // Properties this.tree = tree; - this.cursors = null; + this.cursors = {}; + this.facets = {}; + + var cursorsMapping = definition.cursors, + facetsMapping = definition.facets, + complexCursors = typeof definition.cursors === 'function', + complexFacets = typeof definition.facets === 'function'; // Refreshing the internal mapping - this.refresh = function() { - if (!complex && this.cursors) + function refresh(complexity, targetMapping, targetProperty, mappingType) { + if (!complexity && !firstTime) return; solved = false; - var solvedMapping = mapping; + var solvedMapping = targetMapping; - if (complex) { - solvedMapping = mapping.call(scope); - } + if (complexity) + solvedMapping = targetMapping.call(scope); - if (!type.FacetCursors(solvedMapping)) - throw Error('baobab.Facet: incorrect cursors mapping.'); + if (!mappingType(solvedMapping)) + throw Error('baobab.Facet: incorrect ' + targetProperty + ' mapping.'); - this.cursors = {}; + self[targetProperty] = {}; Object.keys(solvedMapping).forEach(function(k) { - if (solvedMapping[k] instanceof Cursor) { - self.cursors[k] = solvedMapping[k]; - return; + if (targetProperty === 'cursors') { + if (solvedMapping[k] instanceof Cursor) { + self.cursors[k] = solvedMapping[k]; + return; + } + + if (type.Path(solvedMapping[k])) { + self.cursors[k] = tree.select(solvedMapping[k]); + return; + } } - if (type.Path(solvedMapping[k])) { - self.cursors[k] = tree.select(solvedMapping[k]); - return; + else { + if (solvedMapping[k] instanceof Facet) { + self.facets[k] = solvedMapping[k]; + return; + } + + if (typeof solvedMapping[k] === 'string') { + self.facets[k] = tree.facets[solvedMapping[k]]; + + if (!self.facets) + throw Error('baobab.Facet: unkown "' + solvedMapping[k] + '" facet in facets mapping.'); + return; + } } - throw Error('baobab.Facet: invalid path returned by function in cursors mapping.'); + throw Error('baobab.Facet: invalid value returned by function in ' + targetProperty + ' mapping.'); }); + } + + this.refresh = function() { + + if (cursorsMapping) + refresh( + complexCursors, + cursorsMapping, + 'cursors', + type.FacetCursors + ); + + if (facetsMapping) + refresh( + complexFacets, + facetsMapping, + 'facets', + type.FacetFacets + ); }; // Data solving @@ -65,14 +105,19 @@ function Facet(tree, definition, scope) { return data; // Solving - var cursorsData = {}; + var data = {}, + k; + + for (k in self.facets) + data[k] = self.facets[k].get(); - for (var k in self.cursors) - cursorsData[k] = self.cursors[k].get(); + for (k in self.cursors) + data[k] = self.cursors[k].get(); + // Applying getter data = typeof getter === 'function' ? - getter.call(null, cursorsData) : - cursorsData; + getter.call(null, data) : + data; solved = true; @@ -94,6 +139,8 @@ function Facet(tree, definition, scope) { // Init routine this.refresh(); this.tree.on('update', this.updateHandler); + + firstTime = false; } helpers.inherits(Facet, EventEmitter); @@ -103,6 +150,7 @@ Facet.prototype.release = function() { this.tree = null; this.cursors = null; + this.facets = null; this.kill(); }; diff --git a/src/type.js b/src/type.js index 87f7304..d742215 100644 --- a/src/type.js +++ b/src/type.js @@ -108,7 +108,8 @@ type.FacetFacets = function(value) { return Object.keys(value).every(function(k) { var v = value[k]; - return typeof v === 'string' || v instanceof require('./facet.js'); + return typeof v === 'string' || + v instanceof require('./facet.js'); }); } diff --git a/test/suites/baobab.js b/test/suites/baobab.js index 4facac4..9794ced 100644 --- a/test/suites/baobab.js +++ b/test/suites/baobab.js @@ -358,6 +358,34 @@ describe('Baobab API', function() { facet.release(); }); + + it('should be possible to base facets on other facets, yo dawg.', function() { + var facet = baobab.createFacet({facets: {value: 'current'}}), + value2 = baobab.createFacet({cursors: {value: 'value2'}}); + + assert.deepEqual(facet.get(), { + value: { + id: 2, + name: 'Huitzilopochtli', + user: 'John' + } + }); + + facet.release(); + + facet = baobab.createFacet({facets: {value2: value2}, cursors: {value1: ['value1']}}); + + assert.deepEqual(facet.get(), { + value1: 'Hello', + value2: { + value: 'World' + } + }); + + facet.release(); + + + }); }); describe('Options', function() { From 70d907453e9797a1551d1709b9868e8c005ac1ca Mon Sep 17 00:00:00 2001 From: Yomguithereal Date: Mon, 20 Apr 2015 22:34:38 +0200 Subject: [PATCH 73/73] Bump 1.0.0-rc2 --- bower.json | 2 +- build/baobab.min.js | 4 ++-- index.js | 2 +- package.json | 2 +- test/suites/baobab.js | 2 -- 5 files changed, 5 insertions(+), 7 deletions(-) diff --git a/bower.json b/bower.json index 3097923..5af7b9e 100644 --- a/bower.json +++ b/bower.json @@ -1,7 +1,7 @@ { "name": "baobab", "main": "build/baobab.min.js", - "version": "1.0.0-rc1", + "version": "1.0.0-rc2", "homepage": "https://github.com/Yomguithereal/baobab", "author": { "name": "Guillaume Plique", diff --git a/build/baobab.min.js b/build/baobab.min.js index 6a53552..ea1589e 100644 --- a/build/baobab.min.js +++ b/build/baobab.min.js @@ -1,2 +1,2 @@ -/* baobab.js - Version: 1.0.0-rc1 - Author: Yomguithereal (Guillaume Plique) */ -!function(t){if("object"==typeof exports&&"undefined"!=typeof module)module.exports=t();else if("function"==typeof define&&define.amd)define([],t);else{var e;e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:this,e.Baobab=t()}}(function(){var t;return function e(t,r,n){function o(s,a){if(!r[s]){if(!t[s]){var u="function"==typeof require&&require;if(!a&&u)return u(s,!0);if(i)return i(s,!0);var c=new Error("Cannot find module '"+s+"'");throw c.code="MODULE_NOT_FOUND",c}var h=r[s]={exports:{}};t[s][0].call(h.exports,function(e){var r=t[s][1][e];return o(r?r:e)},h,h.exports,e,t,r,n)}return r[s].exports}for(var i="function"==typeof require&&require,s=0;sn;n++)t[n].fn!==e&&o.push(t[n]);return o}var s={once:"boolean",scope:"object"},a=0,u=function(){this._enabled=!0,this.unbindAll()};u.prototype.unbindAll=function(){return this._handlers={},this._handlersAll=[],this._handlersComplex=[],this},u.prototype.on=function(t,e,r){var n,i,u,c,h,l,f;if(o(t)){for(c in t)this.on(c,t[c],e);return this}for("function"==typeof t&&(r=e,e=t,t=null),h=[].concat(t),n=0,i=h.length;i>n;n++){if(c=h[n],f={order:a++,fn:e},"string"==typeof c)this._handlers[c]||(this._handlers[c]=[]),l=this._handlers[c];else if(c instanceof RegExp)l=this._handlersComplex,f.pattern=c;else{if(null!==c)throw Error("Emitter.on: invalid event.");l=this._handlersAll}for(u in r||{})s[u]&&(f[u]=r[u]);f.once&&(f.parent=l),l.push(f)}return this},u.prototype.once=function(){var t=Array.prototype.slice.call(arguments),r=t.length-1;return o(t[r])&&t.length>1?t[r]=e(t[r],{once:!0}):t.push({once:!0}),this.on.apply(this,t)},u.prototype.off=function(t,e){var r,n,s,a;if(1===arguments.length&&"function"==typeof t){e=arguments[0];for(s in this._handlers)this._handlers[s]=i(this._handlers[s],e),0===this._handlers[s].length&&delete this._handlers[s];this._handlersAll=i(this._handlersAll,e),this._handlersComplex=i(this._handlersComplex,e)}else if(1===arguments.length&&"string"==typeof t)delete this._handlers[t];else if(2===arguments.length){var u=[].concat(t);for(r=0,n=u.length;n>r;r++)a=u[r],this._handlers[a]=i(this._handlers[a],e),0===(this._handlers[a]||[]).length&&delete this._handlers[a]}else if(o(t))for(s in t)this.off(s,t[s]);return this},u.prototype.listeners=function(t){var e,r,n,o=this._handlersAll||[],i=!1;if(!t)throw Error("Emitter.listeners: no event provided.");for(o=o.concat(this._handlers[t]||[]),r=0,n=this._handlersComplex.length;n>r;r++)e=this._handlersComplex[r],~t.search(e.pattern)&&(i=!0,o.push(e));return this._handlersAll.length||i?o.sort(function(t,e){return t.order-e.order}):o.slice(0)},u.prototype.emit=function(t,e){if(!this._enabled)return this;if(o(t)){for(var r in t)this.emit(r,t[r]);return this}var n,i,s,a,u,c,h,l=[].concat(t),f=[];for(a=0,c=l.length;c>a;a++){for(i=this.listeners(l[a]),u=0,h=i.length;h>u;u++)s=i[u],n={type:l[a],target:this},arguments.length>1&&(n.data=e),s.fn.call("scope"in s?s.scope:this,n),s.once&&f.push(s);for(u=f.length-1;u>=0;u--)f[u].parent.splice(f[u].parent.indexOf(f[u]),1)}return this},u.prototype.kill=function(){this.unbindAll(),this._handlers=null,this._handlersAll=null,this._handlersComplex=null,this._enabled=!1},u.prototype.disable=function(){return this._enabled=!1,this},u.prototype.enable=function(){return this._enabled=!0,this},u.version="3.0.0","undefined"!=typeof n?("undefined"!=typeof r&&r.exports&&(n=r.exports=u),n.Emitter=u):"function"==typeof t&&t.amd?t("emmett",[],function(){return u}):this.Emitter=u}).call(this)},{}],4:[function(t,e,r){function n(t){return t+"$"+(new Date).getTime()+(""+Math.random()).replace("0.","")}function o(t,e){function r(t){this[t]=function(){var e=this.root[t].apply(this.root,arguments);return e instanceof i?this:e}}if(arguments.length<1&&(t={}),!(this instanceof o))return new o(t,e);if(!f.Object(t)&&!f.Array(t))throw Error("Baobab: invalid data.");if(s.call(this),this.options=u.shallowMerge(l,e),this._transaction={},this._future=void 0,this._cursors={},this._identity="[object Baobab]",this.data=u.deepClone(t),this.root=this.select([]),this.facets={},["get","set","unset","update"].forEach(r.bind(this)),!f.Object(this.options.facets))throw Error("Baobab: invalid facets.");for(var n in this.options.facets)this.addFacet(n,this.options.facets[n])}var i=t("./cursor.js"),s=t("emmett"),a=t("./facet.js"),u=t("./helpers.js"),c=t("./update.js"),h=t("./merge.js"),l=t("../defaults.js"),f=t("./type.js");u.inherits(o,s),o.prototype.addFacet=function(t,e){return this.facets[t]=this.createFacet(e),this},o.prototype.createFacet=function(t){return new a(this,t)},o.prototype.select=function(t){if(!t)throw Error("Baobab.select: invalid path.");if(arguments.length>1&&(t=u.arrayOf(arguments)),!f.Path(t))throw Error("Baobab.select: invalid path.");t=[].concat(t);var e,r=f.ComplexPath(t);r&&(e=u.solvePath(this.data,t,this));var o=t.map(function(t){return f.Function(t)?n("fn"):f.Object(t)?n("ob"):t}).join("|λ|");if(this._cursors[o])return this._cursors[o];var s=new i(this,t,e,o);return this._cursors[o]=s,s},o.prototype.stack=function(t){var e=this;if(!f.Object(t))throw Error("Baobab.update: wrong specification.");return this._transaction=h(t,this._transaction),this.options.autoCommit?this.options.asynchronous?(this._future||(this._future=setTimeout(e.commit.bind(e,null),0)),this):this.commit():this},o.prototype.commit=function(){var t=c(this.data,this._transaction,this.options),e=this.data;this._transaction={},this._future&&(this._future=clearTimeout(this._future));var r=this.options.validate,n=this.options.validationBehavior;if("function"==typeof r){var o=r.call(this,e,t.data,t.log);if(o instanceof Error&&(this.emit("invalid",{error:o}),"rollback"===n))return this}return this.data=t.data,this.emit("update",{log:t.log,previousState:e}),this},o.prototype.release=function(){var t;delete this.data,delete this._transaction;for(t in this._cursors)this._cursors[t].release();delete this._cursors;for(t in this.facets)this.facets[t].release();delete this.facets,this.kill()},o.prototype.toJSON=function(){return this.get()},o.prototype.toString=function(){return this._identity},e.exports=o},{"../defaults.js":2,"./cursor.js":5,"./facet.js":6,"./helpers.js":7,"./merge.js":8,"./type.js":9,"./update.js":10,emmett:3}],5:[function(t,e,r){function n(t,e,r,n){function o(t){if(i.recording&&!i.undoing){var e=a.getIn(t,i.solvedPath,i.tree),r=a.deepClone(e);i.archive.add(r)}return i.undoing=!1,i.emit("update")}var i=this;s.call(this),e=e||[],this.tree=t,this.path=e,this.hash=n,this.archive=null,this.recording=!1,this.undoing=!1,this._identity="[object Cursor]",this.complexPath=!!r,this.solvedPath=this.complexPath?r:this.path,this.relevant=void 0!==this.get(),this.updateHandler=function(t){var e=t.data.log,r=t.data.previousState,n=!1;if(i.complexPath&&(i.solvedPath=a.solvePath(i.tree.data,i.path,i.tree)),!i.path.length)return o(r);i.solvedPath&&(n=a.solveUpdate(e,[i.solvedPath]));var s=void 0!==i.get();i.relevant?s&&n?o(r):s||(i.emit("irrelevant"),i.relevant=!1):s&&n&&(i.emit("relevant"),o(r),i.relevant=!0)};var u=!1;this._lazyBind=function(){u||(u=!0,i.tree.on("update",i.updateHandler))},this.on=a.before(this._lazyBind,this.on.bind(this)),this.once=a.before(this._lazyBind,this.once.bind(this)),this.complexPath&&this._lazyBind()}function o(t,e,r,n){if(arguments.length>5)throw Error("baobab.Cursor."+t+": too many arguments.");if(arguments.length<4&&(n=r,r=[]),r=r||[],"splice"===t&&!u.Splicer(n)){if(!u.Array(n))throw Error("baobab.Cursor.splice: incorrect value.");n=[n]}if(e&&!e(n))throw Error("baobab.Cursor."+t+": incorrect value.");var o=[].concat(r),i=a.solvePath(this.get(),o,this.tree);if(!i)throw Error("baobab.Cursor."+t+": could not solve dynamic path.");var s={};s["$"+t]=n;var c=a.pathObject(i,s);return c}function i(t,e){n.prototype[t]=function(){var r=o.bind(this,t,e).apply(this,arguments);return this.update(r)}}var s=t("emmett"),a=t("./helpers.js"),u=(t("../defaults.js"),t("./type.js"));a.inherits(n,s),n.prototype.isRoot=function(){return!this.path.length},n.prototype.isLeaf=function(){return u.Primitive(this.get())},n.prototype.isBranch=function(){return!this.isLeaf()&&!this.isRoot()},n.prototype.root=function(){return this.tree.root()},n.prototype.select=function(t){if(arguments.length>1&&(t=a.arrayOf(arguments)),!u.Path(t))throw Error("baobab.Cursor.select: invalid path.");return this.tree.select(this.path.concat(t))},n.prototype.up=function(){return this.solvedPath&&this.solvedPath.length?this.tree.select(this.path.slice(0,-1)):null},n.prototype.left=function(){var t=+this.solvedPath[this.solvedPath.length-1];if(isNaN(t))throw Error("baobab.Cursor.left: cannot go left on a non-list type.");return t?this.tree.select(this.solvedPath.slice(0,-1).concat(t-1)):null},n.prototype.leftmost=function(){var t=+this.solvedPath[this.solvedPath.length-1];if(isNaN(t))throw Error("baobab.Cursor.leftmost: cannot go left on a non-list type.");return this.tree.select(this.solvedPath.slice(0,-1).concat(0))},n.prototype.right=function(){var t=+this.solvedPath[this.solvedPath.length-1];if(isNaN(t))throw Error("baobab.Cursor.right: cannot go right on a non-list type.");return t+1===this.up().get().length?null:this.tree.select(this.solvedPath.slice(0,-1).concat(t+1))},n.prototype.rightmost=function(){var t=+this.solvedPath[this.solvedPath.length-1];if(isNaN(t))throw Error("baobab.Cursor.right: cannot go right on a non-list type.");var e=this.up().get();return this.tree.select(this.solvedPath.slice(0,-1).concat(e.length-1))},n.prototype.down=function(){+this.solvedPath[this.solvedPath.length-1];return this.get()instanceof Array?this.tree.select(this.solvedPath.concat(0)):null},n.prototype.get=function(t){arguments.length>1&&(t=a.arrayOf(arguments));var e=this.solvedPath.concat([].concat(t||0===t?t:[]));return a.getIn(this.tree.data,e,this.tree)},i("set"),i("apply",u.Function),i("chain",u.Function),i("push"),i("unshift"),i("merge",u.Object),i("splice"),n.prototype.unset=function(t){if(void 0===t&&this.isRoot())throw Error("baobab.Cursor.unset: cannot remove root node.");var e=o.bind(this,"unset",null).apply(this,[t,!0]);return this.update(e)},n.prototype.update=function(t,e){if(arguments.length<2)return this.tree.stack(a.pathObject(this.solvedPath,t)),this;var r=[].concat(t),n=a.solvePath(this.get(),r,this.tree);if(!n)throw Error("baobab.Cursor.update: could not solve dynamic path.");return this.tree.stack(a.pathObject(this.solvedPath.concat(n),e)),this},n.prototype.startRecording=function(t){if(t=t||5,1>t)throw Error("baobab.Cursor.startRecording: invalid maximum number of records.");return this.archive?this:(this._lazyBind(),this.archive=a.archive(t),this.recording=!0,this)},n.prototype.stopRecording=function(){return this.recording=!1,this},n.prototype.undo=function(t){if(t=t||1,!this.recording)throw Error("baobab.Cursor.undo: cursor is not recording.");if(!u.PositiveInteger(t))throw Error("baobab.Cursor.undo: expecting a positive integer.");var e=this.archive.back(t);if(!e)throw Error("boabab.Cursor.undo: cannot find a relevant record ("+t+" back).");return this.undoing=!0,this.set(e)},n.prototype.hasHistory=function(){return!(!this.archive||!this.archive.get().length)},n.prototype.getHistory=function(){return this.archive?this.archive.get():[]},n.prototype.clearHistory=function(){return this.archive=null,this},n.prototype.release=function(){this.tree.off("update",this.updateHandler),this.hash&&delete this.tree._cursors[this.hash],delete this.tree,delete this.path,delete this.solvedPath,delete this.archive,this.kill()},n.prototype.toJSON=function(){return this.get()},n.prototype.toString=function(){return this._identity},e.exports=n},{"../defaults.js":2,"./helpers.js":7,"./type.js":9,emmett:3}],6:[function(t,e,r){function n(t,e,r){function u(e,o,s,u){if(e||h){l=!1;var f=o;if(e&&(f=o.call(r)),!u(f))throw Error("baobab.Facet: incorrect "+s+" mapping.");c[s]={},Object.keys(f).forEach(function(e){if("cursors"===s){if(f[e]instanceof i)return void(c.cursors[e]=f[e]);if(a.Path(f[e]))return void(c.cursors[e]=t.select(f[e]))}else{if(f[e]instanceof n)return void(c.facets[e]=f[e]);if("string"==typeof f[e]){if(c.facets[e]=t.facets[f[e]],!c.facets)throw Error('baobab.Facet: unkown "'+f[e]+'" facet in facets mapping.');return}}throw Error("baobab.Facet: invalid value returned by function in "+s+" mapping.")})}}var c=this,h=!0,l=!1,f=e.get;o.call(this),this.tree=t,this.cursors={},this.facets={};var p=e.cursors,d=e.facets,y="function"==typeof e.cursors,v="function"==typeof e.facets;this.refresh=function(){p&&u(y,p,"cursors",a.FacetCursors),d&&u(v,d,"facets",a.FacetFacets)},this.get=function(){if(l)return e;var t,e={};for(t in c.facets)e[t]=c.facets[t].get();for(t in c.cursors)e[t]=c.cursors[t].get();return e="function"==typeof f?f.call(null,e):e,l=!0,e},this.updateHandler=function(t){var e=Object.keys(c.cursors).map(function(t){return c.cursors[t].solvedPath});s.solveUpdate(t.data.log,e)&&(l=!1,c.emit("update"))},this.refresh(),this.tree.on("update",this.updateHandler),h=!1}var o=t("emmett"),i=t("./cursor.js"),s=t("./helpers.js"),a=t("./type.js");s.inherits(n,o),n.prototype.release=function(){this.tree.off("update",this.updateHandler),this.tree=null,this.cursors=null,this.facets=null,this.kill()},e.exports=n},{"./cursor.js":5,"./helpers.js":7,"./type.js":9,emmett:3}],7:[function(t,e,r){(function(r){function n(t){return Array.prototype.slice.call(t)}function o(t,e){return function(){t(),e.apply(null,arguments)}}function i(t,e,r){var o=n(arguments).slice(3);return e=+e,r=+r,t.slice(0,e).concat(t.slice(e+r).concat(o))}function s(t,e){var r,n={};for(r in t)n[r]=t[r];for(r in e)n[r]=e[r];return n}function a(t){var e=t.source,r="";return t.global&&(r+="g"),t.multiline&&(r+="m"),t.ignoreCase&&(r+="i"),t.sticky&&(r+="y"),t.unicode&&(r+="u"),new RegExp(e,r)}function u(t,e){if(!e||"object"!=typeof e||e instanceof Error||"ArrayBuffer"in r&&e instanceof ArrayBuffer)return e;if(w.Array(e)){if(t){var n,o,i=[];for(n=0,o=e.length;o>n;n++)i.push(P(e[n]));return i}return e.slice(0)}if(w.Date(e))return new Date(e.getTime());if(e instanceof RegExp)return a(e);if(w.Object(e)){var s,u={};e.constructor&&e.constructor!==Object&&(u=Object.create(e.constructor.prototype));for(s in e)e.hasOwnProperty(s)&&(u[s]=t?P(e[s]):e[s]);return u}return e}function c(t,e){return function(r){return e(t(r))}}function h(t,e){var r,n;for(r=0,n=t.length;n>r;r++)if(e(t[r]))return t[r]}function l(t,e){var r,n;for(r=0,n=t.length;n>r;r++)if(e(t[r]))return r;return-1}function f(t,e){var r,n=!0;if(!t)return!1;for(r in e)if(w.Object(e[r]))n=n&&f(t[r],e[r]);else if(w.Array(e[r]))n=n&&!!~e[r].indexOf(t[r]);else if(t[r]!==e[r])return!1;return n}function d(t,e){return h(t,function(t){return f(t,e)})}function y(t,e){return l(t,function(t){return f(t,e)})}function v(t,e,r){e=e||[];var n,o,i,s=t;for(o=0,i=e.length;i>o;o++){if(!s)return;if("function"==typeof e[o]){if(!w.Array(s))return;s=h(s,e[o])}else if("object"==typeof e[o])if(r&&"$cursor"in e[o]){if(!w.Path(e[o].$cursor))throw Error("baobab.getIn: $cursor path must be an array.");n=r.get(e[o].$cursor),s=s[n]}else{if(!w.Array(s))return;s=d(s,e[o])}else s=s[e[o]]}return s}function g(t,e,r){var n,o,i,s=[],a=t;for(o=0,i=e.length;i>o;o++){if(!a)return null;if("function"==typeof e[o]){if(!w.Array(a))return;n=l(a,e[o]),s.push(n),a=a[n]}else if("object"==typeof e[o])if(r&&"$cursor"in e[o]){if(!w.Path(e[o].$cursor))throw Error("baobab.getIn: $cursor path must be an array.");p=r.get(e[o].$cursor),s.push(p),a=a[p]}else{if(!w.Array(a))return;n=y(a,e[o]),s.push(n),a=a[n]}else s.push(e[o]),a=a[e[o]]||{}}return s}function b(t,e){var r,n,o,i,s,a,u,c,h;for(r=0,i=e.length;i>r;r++)for(u=e[r],n=0,s=t.length;s>n;n++)for(c=t[n],o=0,a=c.length;a>o&&(h=c[o],h==u[o]);o++)if(o+1===a||o+1===u.length)return!0;return!1}function m(t,e){var r,n=t.length,o={},i=o;for(n||(o=e),r=0;n>r;r++)i[t[r]]=r+1===n?e:{},i=i[t[r]];return o}function j(t,e){t.super_=e;var r=function(){};r.prototype=e.prototype,t.prototype=new r,t.prototype.constructor=t}function _(t){var e=[];return{add:function(r){e.unshift(r),e.length>t&&(e.length=t)},back:function(t){var r=e[t-1];return r&&(e=e.slice(t)),r},get:function(){return e}}}var w=t("./type.js"),$=u.bind(null,!1),P=u.bind(null,!0);e.exports={archive:_,arrayOf:n,before:o,deepClone:P,shallowClone:$,shallowMerge:s,compose:c,getIn:v,inherits:j,pathObject:m,solvePath:g,solveUpdate:b,splice:i}}).call(this,"undefined"!=typeof global?global:"undefined"!=typeof self?self:"undefined"!=typeof window?window:{})},{"./type.js":9}],8:[function(t,e,r){function n(t,e,r){a.forEach(function(e){r!==e&&delete t[e]}),t[r]=e[r]}function o(t,e){var r,u=i.shallowClone(e||{});a.forEach(function(e){t[e]&&n(u,t,e)}),t.$chain&&(a.slice(0,-1).forEach(function(t){delete u[t]}),u.$apply=u.$apply?i.compose(u.$apply,t.$chain):t.$chain),(t.$splice||u.$splice)&&(u.$splice=[].concat(u.$splice||[]).concat(t.$splice||[])),(t.$push||u.$push)&&(u.$push=[].concat(u.$push||[]).concat(t.$push||[])),(t.$unshift||u.$unshift)&&(u.$unshift=[].concat(t.$unshift||[]).concat(u.$unshift||[]));for(r in t)s.Object(t[r])?u[r]=o(t[r],u[r]):"$"!==r[0]&&(u[r]=t[r]);return u}var i=t("./helpers.js"),s=t("./type.js"),a=["$unset","$set","$merge","$apply"];e.exports=o},{"./helpers.js":7,"./type.js":9}],9:[function(t,e,r){function n(t,e){return e.some(function(e){return o[e](t)})}var o={};o.Array=function(t){return Array.isArray(t)},o.Object=function(t){return t&&"object"==typeof t&&!Array.isArray(t)&&!(t instanceof Function)},o.String=function(t){return"string"==typeof t},o.Number=function(t){return"number"==typeof t},o.PositiveInteger=function(t){return"number"==typeof t&&t>0&&t%1===0},o.Function=function(t){return"function"==typeof t},o.Primitive=function(t){return"string"==typeof t||"number"==typeof t||"boolean"==typeof t},o.Date=function(t){return t instanceof Date},o.NonScalar=function(t){return o.Object(t)||o.Array(t)},o.Splicer=function(t){return o.Array(t)&&t.every(o.Array)},o.Path=function(t){var e=["String","Number","Function","Object"];return o.Array(t)?t.every(function(t){return n(t,e)}):n(t,e)},o.ComplexPath=function(t){return t.some(function(t){return n(t,["Object","Function"])})},o.FacetCursors=function(e){return o.Object(e)?Object.keys(e).every(function(r){var n=e[r];return o.Path(n)||n instanceof t("./cursor.js")}):!1},o.FacetFacets=function(e){return o.Object(e)?Object.keys(e).every(function(r){var n=e[r];return"string"==typeof n||n instanceof t("./facet.js")}):!1},e.exports=o},{"./cursor.js":5,"./facet.js":6}],10:[function(t,e,r){function n(t,e){var r=new Error("baobab.update: "+e+" at path /"+t.slice(1).join("/"));return r.path=t,r}var o=t("./helpers.js"),i=t("./type.js");e.exports=function(t,e,r){if(r=r||{},!i.Object(t)&&!i.Array(t))throw Error("baobab.update: invalid target.");var s={};t={root:o.shallowClone(t)};var a=function(t,e,r,u){r=r||["root"];var c,h,l,f=r.join("|λ|"),p=r[r.length-1],d=Object.keys(e).some(function(t){return!!~["$set","$push","$unshift","$splice","$unset","$merge","$apply"].indexOf(t)});if(d){s[f]=!0;for(h in e){if("$unset"===h){var y=r[r.length-2];if(!i.Object(u[y]))throw n(r.slice(0,-1),"using command $unset on a non-object");u[y]=o.shallowClone(t),delete u[y][p];break}if("$set"===h){l=e.$set,t[p]=l;break}if("$apply"===h){if(c=e.$apply,"function"!=typeof c)throw n(r,"using command $apply with a non function");t[p]=c.call(null,t[p]);break}if("$merge"===h){if(l=e.$merge,!i.Object(t[p])||!i.Object(l))throw n(r,"using command $merge with a non object");t[p]=o.shallowMerge(t[p],l);break}if("$splice"===h){if(l=e.$splice,!i.Array(t[p]))throw n(r,"using command $push to a non array");l.forEach(function(e){t[p]=o.splice.apply(null,[t[p]].concat(e))})}if("$push"===h){if(l=e.$push,!i.Array(t[p]))throw n(r,"using command $push to a non array");t[p]=t[p].concat(l)}if("$unshift"===h){if(l=e.$unshift,!i.Array(t[p]))throw n(r,"using command $unshift to a non array");t[p]=[].concat(l).concat(t[p])}}}else for(h in e)t[p][h]="undefined"==typeof t[p][h]?{}:o.shallowClone(t[p][h]),a(t[p],e[h],r.concat(h),t)};return a(t,e),{data:t.root,log:Object.keys(s).map(function(t){return t.split("|λ|").slice(1)})}}},{"./helpers.js":7,"./type.js":9}]},{},[1])(1)}); \ No newline at end of file +/* baobab.js - Version: 1.0.0-rc2 - Author: Yomguithereal (Guillaume Plique) */ +!function(t){if("object"==typeof exports&&"undefined"!=typeof module)module.exports=t();else if("function"==typeof define&&define.amd)define([],t);else{var e;e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:this,e.Baobab=t()}}(function(){var t;return function e(t,r,n){function o(s,a){if(!r[s]){if(!t[s]){var u="function"==typeof require&&require;if(!a&&u)return u(s,!0);if(i)return i(s,!0);var c=new Error("Cannot find module '"+s+"'");throw c.code="MODULE_NOT_FOUND",c}var h=r[s]={exports:{}};t[s][0].call(h.exports,function(e){var r=t[s][1][e];return o(r?r:e)},h,h.exports,e,t,r,n)}return r[s].exports}for(var i="function"==typeof require&&require,s=0;sn;n++)t[n].fn!==e&&o.push(t[n]);return o}var s={once:"boolean",scope:"object"},a=0,u=function(){this._enabled=!0,this.unbindAll()};u.prototype.unbindAll=function(){return this._handlers={},this._handlersAll=[],this._handlersComplex=[],this},u.prototype.on=function(t,e,r){var n,i,u,c,h,l,f;if(o(t)){for(c in t)this.on(c,t[c],e);return this}for("function"==typeof t&&(r=e,e=t,t=null),h=[].concat(t),n=0,i=h.length;i>n;n++){if(c=h[n],f={order:a++,fn:e},"string"==typeof c)this._handlers[c]||(this._handlers[c]=[]),l=this._handlers[c];else if(c instanceof RegExp)l=this._handlersComplex,f.pattern=c;else{if(null!==c)throw Error("Emitter.on: invalid event.");l=this._handlersAll}for(u in r||{})s[u]&&(f[u]=r[u]);f.once&&(f.parent=l),l.push(f)}return this},u.prototype.once=function(){var t=Array.prototype.slice.call(arguments),r=t.length-1;return o(t[r])&&t.length>1?t[r]=e(t[r],{once:!0}):t.push({once:!0}),this.on.apply(this,t)},u.prototype.off=function(t,e){var r,n,s,a;if(1===arguments.length&&"function"==typeof t){e=arguments[0];for(s in this._handlers)this._handlers[s]=i(this._handlers[s],e),0===this._handlers[s].length&&delete this._handlers[s];this._handlersAll=i(this._handlersAll,e),this._handlersComplex=i(this._handlersComplex,e)}else if(1===arguments.length&&"string"==typeof t)delete this._handlers[t];else if(2===arguments.length){var u=[].concat(t);for(r=0,n=u.length;n>r;r++)a=u[r],this._handlers[a]=i(this._handlers[a],e),0===(this._handlers[a]||[]).length&&delete this._handlers[a]}else if(o(t))for(s in t)this.off(s,t[s]);return this},u.prototype.listeners=function(t){var e,r,n,o=this._handlersAll||[],i=!1;if(!t)throw Error("Emitter.listeners: no event provided.");for(o=o.concat(this._handlers[t]||[]),r=0,n=this._handlersComplex.length;n>r;r++)e=this._handlersComplex[r],~t.search(e.pattern)&&(i=!0,o.push(e));return this._handlersAll.length||i?o.sort(function(t,e){return t.order-e.order}):o.slice(0)},u.prototype.emit=function(t,e){if(!this._enabled)return this;if(o(t)){for(var r in t)this.emit(r,t[r]);return this}var n,i,s,a,u,c,h,l=[].concat(t),f=[];for(a=0,c=l.length;c>a;a++){for(i=this.listeners(l[a]),u=0,h=i.length;h>u;u++)s=i[u],n={type:l[a],target:this},arguments.length>1&&(n.data=e),s.fn.call("scope"in s?s.scope:this,n),s.once&&f.push(s);for(u=f.length-1;u>=0;u--)f[u].parent.splice(f[u].parent.indexOf(f[u]),1)}return this},u.prototype.kill=function(){this.unbindAll(),this._handlers=null,this._handlersAll=null,this._handlersComplex=null,this._enabled=!1},u.prototype.disable=function(){return this._enabled=!1,this},u.prototype.enable=function(){return this._enabled=!0,this},u.version="3.0.0","undefined"!=typeof n?("undefined"!=typeof r&&r.exports&&(n=r.exports=u),n.Emitter=u):"function"==typeof t&&t.amd?t("emmett",[],function(){return u}):this.Emitter=u}).call(this)},{}],4:[function(t,e,r){function n(t){return t+"$"+(new Date).getTime()+(""+Math.random()).replace("0.","")}function o(t,e){function r(t){this[t]=function(){var e=this.root[t].apply(this.root,arguments);return e instanceof i?this:e}}if(arguments.length<1&&(t={}),!(this instanceof o))return new o(t,e);if(!f.Object(t)&&!f.Array(t))throw Error("Baobab: invalid data.");if(s.call(this),this.options=u.shallowMerge(l,e),this._transaction={},this._future=void 0,this._cursors={},this._identity="[object Baobab]",this.data=u.deepClone(t),this.root=this.select([]),this.facets={},["get","set","unset","update"].forEach(r.bind(this)),!f.Object(this.options.facets))throw Error("Baobab: invalid facets.");for(var n in this.options.facets)this.addFacet(n,this.options.facets[n])}var i=t("./cursor.js"),s=t("emmett"),a=t("./facet.js"),u=t("./helpers.js"),c=t("./update.js"),h=t("./merge.js"),l=t("../defaults.js"),f=t("./type.js");u.inherits(o,s),o.prototype.addFacet=function(t,e){return this.facets[t]=this.createFacet(e),this},o.prototype.createFacet=function(t){return new a(this,t)},o.prototype.select=function(t){if(!t)throw Error("Baobab.select: invalid path.");if(arguments.length>1&&(t=u.arrayOf(arguments)),!f.Path(t))throw Error("Baobab.select: invalid path.");t=[].concat(t);var e,r=f.ComplexPath(t);r&&(e=u.solvePath(this.data,t,this));var o=t.map(function(t){return f.Function(t)?n("fn"):f.Object(t)?n("ob"):t}).join("|λ|");if(this._cursors[o])return this._cursors[o];var s=new i(this,t,e,o);return this._cursors[o]=s,s},o.prototype.stack=function(t){var e=this;if(!f.Object(t))throw Error("Baobab.update: wrong specification.");return this._transaction=h(t,this._transaction),this.options.autoCommit?this.options.asynchronous?(this._future||(this._future=setTimeout(e.commit.bind(e,null),0)),this):this.commit():this},o.prototype.commit=function(){var t=c(this.data,this._transaction,this.options),e=this.data;this._transaction={},this._future&&(this._future=clearTimeout(this._future));var r=this.options.validate,n=this.options.validationBehavior;if("function"==typeof r){var o=r.call(this,e,t.data,t.log);if(o instanceof Error&&(this.emit("invalid",{error:o}),"rollback"===n))return this}return this.data=t.data,this.emit("update",{log:t.log,previousState:e}),this},o.prototype.release=function(){var t;delete this.data,delete this._transaction;for(t in this._cursors)this._cursors[t].release();delete this._cursors;for(t in this.facets)this.facets[t].release();delete this.facets,this.kill()},o.prototype.toJSON=function(){return this.get()},o.prototype.toString=function(){return this._identity},e.exports=o},{"../defaults.js":2,"./cursor.js":5,"./facet.js":6,"./helpers.js":7,"./merge.js":8,"./type.js":9,"./update.js":10,emmett:3}],5:[function(t,e,r){function n(t,e,r,n){function o(t){if(i.recording&&!i.undoing){var e=a.getIn(t,i.solvedPath,i.tree),r=a.deepClone(e);i.archive.add(r)}return i.undoing=!1,i.emit("update")}var i=this;s.call(this),e=e||[],this.tree=t,this.path=e,this.hash=n,this.archive=null,this.recording=!1,this.undoing=!1,this._identity="[object Cursor]",this.complexPath=!!r,this.solvedPath=this.complexPath?r:this.path,this.relevant=void 0!==this.get(),this.updateHandler=function(t){var e=t.data.log,r=t.data.previousState,n=!1;if(i.complexPath&&(i.solvedPath=a.solvePath(i.tree.data,i.path,i.tree)),!i.path.length)return o(r);i.solvedPath&&(n=a.solveUpdate(e,[i.solvedPath]));var s=void 0!==i.get();i.relevant?s&&n?o(r):s||(i.emit("irrelevant"),i.relevant=!1):s&&n&&(i.emit("relevant"),o(r),i.relevant=!0)};var u=!1;this._lazyBind=function(){u||(u=!0,i.tree.on("update",i.updateHandler))},this.on=a.before(this._lazyBind,this.on.bind(this)),this.once=a.before(this._lazyBind,this.once.bind(this)),this.complexPath&&this._lazyBind()}function o(t,e,r,n){if(arguments.length>5)throw Error("baobab.Cursor."+t+": too many arguments.");if(arguments.length<4&&(n=r,r=[]),r=r||[],"splice"===t&&!u.Splicer(n)){if(!u.Array(n))throw Error("baobab.Cursor.splice: incorrect value.");n=[n]}if(e&&!e(n))throw Error("baobab.Cursor."+t+": incorrect value.");var o=[].concat(r),i=a.solvePath(this.get(),o,this.tree);if(!i)throw Error("baobab.Cursor."+t+": could not solve dynamic path.");var s={};s["$"+t]=n;var c=a.pathObject(i,s);return c}function i(t,e){n.prototype[t]=function(){var r=o.bind(this,t,e).apply(this,arguments);return this.update(r)}}var s=t("emmett"),a=t("./helpers.js"),u=(t("../defaults.js"),t("./type.js"));a.inherits(n,s),n.prototype.isRoot=function(){return!this.path.length},n.prototype.isLeaf=function(){return u.Primitive(this.get())},n.prototype.isBranch=function(){return!this.isLeaf()&&!this.isRoot()},n.prototype.root=function(){return this.tree.root()},n.prototype.select=function(t){if(arguments.length>1&&(t=a.arrayOf(arguments)),!u.Path(t))throw Error("baobab.Cursor.select: invalid path.");return this.tree.select(this.path.concat(t))},n.prototype.up=function(){return this.solvedPath&&this.solvedPath.length?this.tree.select(this.path.slice(0,-1)):null},n.prototype.left=function(){var t=+this.solvedPath[this.solvedPath.length-1];if(isNaN(t))throw Error("baobab.Cursor.left: cannot go left on a non-list type.");return t?this.tree.select(this.solvedPath.slice(0,-1).concat(t-1)):null},n.prototype.leftmost=function(){var t=+this.solvedPath[this.solvedPath.length-1];if(isNaN(t))throw Error("baobab.Cursor.leftmost: cannot go left on a non-list type.");return this.tree.select(this.solvedPath.slice(0,-1).concat(0))},n.prototype.right=function(){var t=+this.solvedPath[this.solvedPath.length-1];if(isNaN(t))throw Error("baobab.Cursor.right: cannot go right on a non-list type.");return t+1===this.up().get().length?null:this.tree.select(this.solvedPath.slice(0,-1).concat(t+1))},n.prototype.rightmost=function(){var t=+this.solvedPath[this.solvedPath.length-1];if(isNaN(t))throw Error("baobab.Cursor.right: cannot go right on a non-list type.");var e=this.up().get();return this.tree.select(this.solvedPath.slice(0,-1).concat(e.length-1))},n.prototype.down=function(){+this.solvedPath[this.solvedPath.length-1];return this.get()instanceof Array?this.tree.select(this.solvedPath.concat(0)):null},n.prototype.get=function(t){arguments.length>1&&(t=a.arrayOf(arguments));var e=this.solvedPath.concat([].concat(t||0===t?t:[]));return a.getIn(this.tree.data,e,this.tree)},i("set"),i("apply",u.Function),i("chain",u.Function),i("push"),i("unshift"),i("merge",u.Object),i("splice"),n.prototype.unset=function(t){if(void 0===t&&this.isRoot())throw Error("baobab.Cursor.unset: cannot remove root node.");var e=o.bind(this,"unset",null).apply(this,[t,!0]);return this.update(e)},n.prototype.update=function(t,e){if(arguments.length<2)return this.tree.stack(a.pathObject(this.solvedPath,t)),this;var r=[].concat(t),n=a.solvePath(this.get(),r,this.tree);if(!n)throw Error("baobab.Cursor.update: could not solve dynamic path.");return this.tree.stack(a.pathObject(this.solvedPath.concat(n),e)),this},n.prototype.startRecording=function(t){if(t=t||5,1>t)throw Error("baobab.Cursor.startRecording: invalid maximum number of records.");return this.archive?this:(this._lazyBind(),this.archive=a.archive(t),this.recording=!0,this)},n.prototype.stopRecording=function(){return this.recording=!1,this},n.prototype.undo=function(t){if(t=t||1,!this.recording)throw Error("baobab.Cursor.undo: cursor is not recording.");if(!u.PositiveInteger(t))throw Error("baobab.Cursor.undo: expecting a positive integer.");var e=this.archive.back(t);if(!e)throw Error("boabab.Cursor.undo: cannot find a relevant record ("+t+" back).");return this.undoing=!0,this.set(e)},n.prototype.hasHistory=function(){return!(!this.archive||!this.archive.get().length)},n.prototype.getHistory=function(){return this.archive?this.archive.get():[]},n.prototype.clearHistory=function(){return this.archive=null,this},n.prototype.release=function(){this.tree.off("update",this.updateHandler),this.hash&&delete this.tree._cursors[this.hash],delete this.tree,delete this.path,delete this.solvedPath,delete this.archive,this.kill()},n.prototype.toJSON=function(){return this.get()},n.prototype.toString=function(){return this._identity},e.exports=n},{"../defaults.js":2,"./helpers.js":7,"./type.js":9,emmett:3}],6:[function(t,e,r){function n(t,e,r){function u(e,o,s,u){if(e||h){l=!1;var f=o;if(e&&(f=o.call(r)),!u(f))throw Error("baobab.Facet: incorrect "+s+" mapping.");c[s]={},Object.keys(f).forEach(function(e){if("cursors"===s){if(f[e]instanceof i)return void(c.cursors[e]=f[e]);if(a.Path(f[e]))return void(c.cursors[e]=t.select(f[e]))}else{if(f[e]instanceof n)return void(c.facets[e]=f[e]);if("string"==typeof f[e]){if(c.facets[e]=t.facets[f[e]],!c.facets)throw Error('baobab.Facet: unkown "'+f[e]+'" facet in facets mapping.');return}}throw Error("baobab.Facet: invalid value returned by function in "+s+" mapping.")})}}var c=this,h=!0,l=!1,f=e.get;o.call(this),this.tree=t,this.cursors={},this.facets={};var p=e.cursors,d=e.facets,y="function"==typeof e.cursors,v="function"==typeof e.facets;this.refresh=function(){p&&u(y,p,"cursors",a.FacetCursors),d&&u(v,d,"facets",a.FacetFacets)},this.get=function(){if(l)return e;var t,e={};for(t in c.facets)e[t]=c.facets[t].get();for(t in c.cursors)e[t]=c.cursors[t].get();return e="function"==typeof f?f.call(null,e):e,l=!0,e},this.updateHandler=function(t){var e=Object.keys(c.cursors).map(function(t){return c.cursors[t].solvedPath});s.solveUpdate(t.data.log,e)&&(l=!1,c.emit("update"))},this.refresh(),this.tree.on("update",this.updateHandler),h=!1}var o=t("emmett"),i=t("./cursor.js"),s=t("./helpers.js"),a=t("./type.js");s.inherits(n,o),n.prototype.release=function(){this.tree.off("update",this.updateHandler),this.tree=null,this.cursors=null,this.facets=null,this.kill()},e.exports=n},{"./cursor.js":5,"./helpers.js":7,"./type.js":9,emmett:3}],7:[function(t,e,r){(function(r){function n(t){return Array.prototype.slice.call(t)}function o(t,e){return function(){t(),e.apply(null,arguments)}}function i(t,e,r){var o=n(arguments).slice(3);return e=+e,r=+r,t.slice(0,e).concat(t.slice(e+r).concat(o))}function s(t,e){var r,n={};for(r in t)n[r]=t[r];for(r in e)n[r]=e[r];return n}function a(t){var e=t.source,r="";return t.global&&(r+="g"),t.multiline&&(r+="m"),t.ignoreCase&&(r+="i"),t.sticky&&(r+="y"),t.unicode&&(r+="u"),new RegExp(e,r)}function u(t,e){if(!e||"object"!=typeof e||e instanceof Error||"ArrayBuffer"in r&&e instanceof ArrayBuffer)return e;if(w.Array(e)){if(t){var n,o,i=[];for(n=0,o=e.length;o>n;n++)i.push(P(e[n]));return i}return e.slice(0)}if(w.Date(e))return new Date(e.getTime());if(e instanceof RegExp)return a(e);if(w.Object(e)){var s,u={};e.constructor&&e.constructor!==Object&&(u=Object.create(e.constructor.prototype));for(s in e)e.hasOwnProperty(s)&&(u[s]=t?P(e[s]):e[s]);return u}return e}function c(t,e){return function(r){return e(t(r))}}function h(t,e){var r,n;for(r=0,n=t.length;n>r;r++)if(e(t[r]))return t[r]}function l(t,e){var r,n;for(r=0,n=t.length;n>r;r++)if(e(t[r]))return r;return-1}function f(t,e){var r,n=!0;if(!t)return!1;for(r in e)if(w.Object(e[r]))n=n&&f(t[r],e[r]);else if(w.Array(e[r]))n=n&&!!~e[r].indexOf(t[r]);else if(t[r]!==e[r])return!1;return n}function d(t,e){return h(t,function(t){return f(t,e)})}function y(t,e){return l(t,function(t){return f(t,e)})}function v(t,e,r){e=e||[];var n,o,i,s=t;for(o=0,i=e.length;i>o;o++){if(!s)return;if("function"==typeof e[o]){if(!w.Array(s))return;s=h(s,e[o])}else if("object"==typeof e[o])if(r&&"$cursor"in e[o]){if(!w.Path(e[o].$cursor))throw Error("baobab.getIn: $cursor path must be an array.");n=r.get(e[o].$cursor),s=s[n]}else{if(!w.Array(s))return;s=d(s,e[o])}else s=s[e[o]]}return s}function g(t,e,r){var n,o,i,s=[],a=t;for(o=0,i=e.length;i>o;o++){if(!a)return null;if("function"==typeof e[o]){if(!w.Array(a))return;n=l(a,e[o]),s.push(n),a=a[n]}else if("object"==typeof e[o])if(r&&"$cursor"in e[o]){if(!w.Path(e[o].$cursor))throw Error("baobab.getIn: $cursor path must be an array.");p=r.get(e[o].$cursor),s.push(p),a=a[p]}else{if(!w.Array(a))return;n=y(a,e[o]),s.push(n),a=a[n]}else s.push(e[o]),a=a[e[o]]||{}}return s}function b(t,e){var r,n,o,i,s,a,u,c,h;for(r=0,i=e.length;i>r;r++)for(u=e[r],n=0,s=t.length;s>n;n++)for(c=t[n],o=0,a=c.length;a>o&&(h=c[o],h==u[o]);o++)if(o+1===a||o+1===u.length)return!0;return!1}function m(t,e){var r,n=t.length,o={},i=o;for(n||(o=e),r=0;n>r;r++)i[t[r]]=r+1===n?e:{},i=i[t[r]];return o}function j(t,e){t.super_=e;var r=function(){};r.prototype=e.prototype,t.prototype=new r,t.prototype.constructor=t}function _(t){var e=[];return{add:function(r){e.unshift(r),e.length>t&&(e.length=t)},back:function(t){var r=e[t-1];return r&&(e=e.slice(t)),r},get:function(){return e}}}var w=t("./type.js"),$=u.bind(null,!1),P=u.bind(null,!0);e.exports={archive:_,arrayOf:n,before:o,deepClone:P,shallowClone:$,shallowMerge:s,compose:c,getIn:v,inherits:j,pathObject:m,solvePath:g,solveUpdate:b,splice:i}}).call(this,"undefined"!=typeof global?global:"undefined"!=typeof self?self:"undefined"!=typeof window?window:{})},{"./type.js":9}],8:[function(t,e,r){function n(t,e,r){a.forEach(function(e){r!==e&&delete t[e]}),t[r]=e[r]}function o(t,e){var r,u=i.shallowClone(e||{});a.forEach(function(e){t[e]&&n(u,t,e)}),t.$chain&&(a.slice(0,-1).forEach(function(t){delete u[t]}),u.$apply=u.$apply?i.compose(u.$apply,t.$chain):t.$chain),(t.$splice||u.$splice)&&(u.$splice=[].concat(u.$splice||[]).concat(t.$splice||[])),(t.$push||u.$push)&&(u.$push=[].concat(u.$push||[]).concat(t.$push||[])),(t.$unshift||u.$unshift)&&(u.$unshift=[].concat(t.$unshift||[]).concat(u.$unshift||[]));for(r in t)s.Object(t[r])?u[r]=o(t[r],u[r]):"$"!==r[0]&&(u[r]=t[r]);return u}var i=t("./helpers.js"),s=t("./type.js"),a=["$unset","$set","$merge","$apply"];e.exports=o},{"./helpers.js":7,"./type.js":9}],9:[function(t,e,r){function n(t,e){return e.some(function(e){return o[e](t)})}var o={};o.Array=function(t){return Array.isArray(t)},o.Object=function(t){return t&&"object"==typeof t&&!Array.isArray(t)&&!(t instanceof Function)},o.String=function(t){return"string"==typeof t},o.Number=function(t){return"number"==typeof t},o.PositiveInteger=function(t){return"number"==typeof t&&t>0&&t%1===0},o.Function=function(t){return"function"==typeof t},o.Primitive=function(t){return"string"==typeof t||"number"==typeof t||"boolean"==typeof t},o.Date=function(t){return t instanceof Date},o.NonScalar=function(t){return o.Object(t)||o.Array(t)},o.Splicer=function(t){return o.Array(t)&&t.every(o.Array)},o.Path=function(t){var e=["String","Number","Function","Object"];return o.Array(t)?t.every(function(t){return n(t,e)}):n(t,e)},o.ComplexPath=function(t){return t.some(function(t){return n(t,["Object","Function"])})},o.FacetCursors=function(e){return o.Object(e)?Object.keys(e).every(function(r){var n=e[r];return o.Path(n)||n instanceof t("./cursor.js")}):!1},o.FacetFacets=function(e){return o.Object(e)?Object.keys(e).every(function(r){var n=e[r];return"string"==typeof n||n instanceof t("./facet.js")}):!1},e.exports=o},{"./cursor.js":5,"./facet.js":6}],10:[function(t,e,r){function n(t,e){var r=new Error("baobab.update: "+e+" at path /"+t.slice(1).join("/"));return r.path=t,r}var o=t("./helpers.js"),i=t("./type.js");e.exports=function(t,e,r){if(r=r||{},!i.Object(t)&&!i.Array(t))throw Error("baobab.update: invalid target.");var s={};t={root:o.shallowClone(t)};var a=function(t,e,r,u){r=r||["root"];var c,h,l,f=r.join("|λ|"),p=r[r.length-1],d=Object.keys(e).some(function(t){return!!~["$set","$push","$unshift","$splice","$unset","$merge","$apply"].indexOf(t)});if(d){s[f]=!0;for(h in e){if("$unset"===h){var y=r[r.length-2];if(!i.Object(u[y]))throw n(r.slice(0,-1),"using command $unset on a non-object");u[y]=o.shallowClone(t),delete u[y][p];break}if("$set"===h){l=e.$set,t[p]=l;break}if("$apply"===h){if(c=e.$apply,"function"!=typeof c)throw n(r,"using command $apply with a non function");t[p]=c.call(null,t[p]);break}if("$merge"===h){if(l=e.$merge,!i.Object(t[p])||!i.Object(l))throw n(r,"using command $merge with a non object");t[p]=o.shallowMerge(t[p],l);break}if("$splice"===h){if(l=e.$splice,!i.Array(t[p]))throw n(r,"using command $push to a non array");l.forEach(function(e){t[p]=o.splice.apply(null,[t[p]].concat(e))})}if("$push"===h){if(l=e.$push,!i.Array(t[p]))throw n(r,"using command $push to a non array");t[p]=t[p].concat(l)}if("$unshift"===h){if(l=e.$unshift,!i.Array(t[p]))throw n(r,"using command $unshift to a non array");t[p]=[].concat(l).concat(t[p])}}}else for(h in e)t[p][h]="undefined"==typeof t[p][h]?{}:o.shallowClone(t[p][h]),a(t[p],e[h],r.concat(h),t)};return a(t,e),{data:t.root,log:Object.keys(s).map(function(t){return t.split("|λ|").slice(1)})}}},{"./helpers.js":7,"./type.js":9}]},{},[1])(1)}); \ No newline at end of file diff --git a/index.js b/index.js index ba9f056..0063a8b 100644 --- a/index.js +++ b/index.js @@ -9,7 +9,7 @@ var Baobab = require('./src/baobab.js'), // Non-writable version Object.defineProperty(Baobab, 'version', { - value: '1.0.0-rc1' + value: '1.0.0-rc2' }); // Exposing helpers diff --git a/package.json b/package.json index 15542f4..8b6b0bb 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "baobab", - "version": "1.0.0-rc1", + "version": "1.0.0-rc2", "description": "JavaScript data tree with cursors.", "main": "index.js", "dependencies": { diff --git a/test/suites/baobab.js b/test/suites/baobab.js index 9794ced..f209d22 100644 --- a/test/suites/baobab.js +++ b/test/suites/baobab.js @@ -383,8 +383,6 @@ describe('Baobab API', function() { }); facet.release(); - - }); });