Comparing version 0.2.0 to 0.3.0
# Changelog | ||
## 0.3.0 | ||
- Committing new values now causes a change event that will bubble up the tree | ||
- Calling `set` with one argument will assume the query for the cursor as the key | ||
## 0.2.0 | ||
- Add toJSON methods | ||
- Removed internal Cursor class. Foliage all the way down... | ||
- Removed internal Cursor class. Foliage all the way down... This means that `React.PropTypes.instanceOf(Foliage` now works consistently. | ||
@@ -8,0 +13,0 @@ ## 0.1.0 |
@@ -1,2 +0,2 @@ | ||
module.exports=function(t){function e(n){if(r[n])return r[n].exports;var s=r[n]={exports:{},id:n,loaded:!1};return t[n].call(s.exports,s,s.exports,e),s.loaded=!0,s.exports}var r={};return e.m=t,e.c=r,e.p="",e(0)}([function(t,e,r){"use strict";var n=function(t){return t&&t.__esModule?t["default"]:t},s=r(1),u=n(s);t.exports=u},function(t,e,r){"use strict";function n(t,e,r){this._state=t,this._keys=e?[].concat(e):[],this._source=r||this}var s=function(t){return t&&t.__esModule?t["default"]:t},u=Object.assign||function(t){for(var e=1;e<arguments.length;e++){var r=arguments[e];for(var n in r)Object.prototype.hasOwnProperty.call(r,n)&&(t[n]=r[n])}return t},i=r(2),o=s(i),a=r(3),c=s(a);t.exports=n,n.prototype=u({},o,{state:function(){return this.isTrunk()?this._state:this._source.state()},query:function(t){return t?this._keys.concat(t):this._keys},get:function(t){return new n(this.state(),this.query(t),this._source)},commit:function(t){this.trunk()._state=t},set:function(t,e){var r=c.assoc(this.state(),this.query(t),e);this.commit(r)},remove:function(t){var e=c.dissoc(this.state(),this.query(t));this.commit(e)},trunk:function(){return this._source},isTrunk:function(){return this._source===this},valueOf:function(){var t=this.state();return this._keys.length?c.get(t,this.query()):t},toJSON:function(){return this.valueOf()}})},function(t){"use strict";var e=["map","reduce","filter","some","every"],r={values:function(){var t=this.valueOf();return Object.keys(t).map(function(e){return t[e]})},find:function(){return this.filter.apply(this,arguments)[0]}};e.forEach(function(t){r[t]=function(){for(var e,r=arguments.length,n=Array(r),s=0;r>s;s++)n[s]=arguments[s];return(e=this.values())[t].apply(e,n)}}),t.exports=r},function(t){t.exports=require("sprout-data")}]); | ||
module.exports=function(t){function e(s){if(r[s])return r[s].exports;var n=r[s]={exports:{},id:s,loaded:!1};return t[s].call(n.exports,n,n.exports,e),n.loaded=!0,n.exports}var r={};return e.m=t,e.c=r,e.p="",e(0)}([function(t,e,r){"use strict";var s=function(t){return t&&t.__esModule?t["default"]:t},n=r(1),u=s(n);t.exports=u},function(t,e,r){"use strict";function s(t,e,r){f.decorate(this),this._state=t,this._keys=e?[].concat(e):[],this._source=r||this}var n=function(t){return t&&t.__esModule?t["default"]:t},u=Object.assign||function(t){for(var e=1;e<arguments.length;e++){var r=arguments[e];for(var s in r)Object.prototype.hasOwnProperty.call(r,s)&&(t[s]=r[s])}return t},i=r(2),o=n(i),a=r(4),c=n(a),h=r(3),f=n(h);t.exports=s,s.prototype=u({state:function(){return this.isTrunk()?this._state:this._source.state()},query:function(t){return t?this._keys.concat(t):this._keys},get:function(t){return new s(this.state(),this.query(t),this._source)},_bubble:function(){this.volley(),this.isTrunk()===!1&&this._source.volley()},commit:function(t){this.trunk()._state=t,this._bubble()},set:function(t,e){var r=void 0;r=1===arguments.length?c.assoc(this.state(),this.query(),t):c.assoc(this.state(),this.query(t),e),this.commit(r)},remove:function(t){var e=c.dissoc(this.state(),this.query(t));this.commit(e)},trunk:function(){return this._source},isTrunk:function(){return this._source===this},valueOf:function(){var t=this.state();return this._keys.length?c.get(t,this.query()):t},toJSON:function(){return this.valueOf()}},o)},function(t){"use strict";var e=["map","reduce","filter","some","every"],r={values:function(){var t=this.valueOf();return Object.keys(t).map(function(e){return t[e]})},find:function(){return this.filter.apply(this,arguments)[0]}};e.forEach(function(t){r[t]=function(){for(var e,r=arguments.length,s=Array(r),n=0;r>n;n++)s[n]=arguments[n];return(e=this.values())[t].apply(e,s)}}),t.exports=r},function(t){t.exports=require("diode")},function(t){t.exports=require("sprout-data")}]); | ||
//# sourceMappingURL=Foliage.js.map |
@@ -13,2 +13,7 @@ # API Cheatsheet | ||
Events | ||
+--------------+ | ||
listen - Add a change callback to a trunk or cursor | ||
ignore - Remove a change callback | ||
Dereferencing | ||
@@ -15,0 +20,0 @@ +--------------+ |
{ | ||
"name": "foliage", | ||
"version": "0.2.0", | ||
"version": "0.3.0", | ||
"description": "A cursor like tree data structure on top of sprout.", | ||
@@ -18,2 +18,3 @@ "main": "dist/Foliage.js", | ||
"dependencies": { | ||
"diode": "^4.0.0", | ||
"sprout-data": "^0.2.1" | ||
@@ -20,0 +21,0 @@ }, |
@@ -12,5 +12,15 @@ [![NPM](https://nodei.co/npm/foliage.png?compact=true)](https://npmjs.org/package/foliage) | ||
Foliage is lightweight tree data structure modeled loosely after [Om's Cursor](https://github.com/omcljs/om/wiki/Cursors) and [OmniscientJS's `immstruct`](https://github.com/omniscientjs/immstruct). | ||
Foliage is lightweight | ||
[zipper](http://en.wikipedia.org/wiki/Zipper_%28data_structure%29) | ||
that operates on a tree of JavaScript primitives. It is modeled | ||
loosely on [Om's Cursor](https://github.com/omcljs/om/wiki/Cursors) | ||
and | ||
[OmniscientJS's `immstruct`](https://github.com/omniscientjs/immstruct), | ||
however it is not nearly as ambitious. | ||
In more practical terms, Foliage is a thin layer on top of [`sprout`](https://github.com/herrstucki/sprout). | ||
Foliage makes it easier to work with data in component-oriented | ||
frameworks such as React by allowing data to be passed around in terms | ||
of references to locations in a global application state object. This | ||
means that state can be maintained in a single location, however that | ||
entire structure isn't necessary for an individual component. | ||
@@ -26,2 +36,4 @@ ## What problems does it attempt to solve? | ||
1. Keep a naming convention similar to ES6 maps | ||
2. Keep it small. There are plenty of other Cursors-like | ||
libraries. See [Prior Art](#prior-art) | ||
@@ -33,3 +45,3 @@ ## Working with Foliage | ||
```javascript | ||
let plant = new Folage({ berries: true }) | ||
let plant = new Foliage({ berries: true }) | ||
``` | ||
@@ -42,3 +54,3 @@ | ||
```javascript | ||
let plant = new Folage({ berries: true }) | ||
let plant = new Foliage({ berries: true }) | ||
@@ -58,3 +70,3 @@ plant.get('berries').valueOf() // => true | ||
```javascript | ||
let oak = new Folage({ | ||
let oak = new Foliage({ | ||
squirrels: { | ||
@@ -98,2 +110,19 @@ squeakem: { weight: 2, height: 12 } | ||
## Listening to changes | ||
All points in a Foliage publish events when they change: | ||
```javascript | ||
let plant = new Foliage({ fizz: 'buzz' }) | ||
let branch = plant.get('fiz') | ||
plant.listen(() => console.log('plant changed!')) | ||
branch.listen(() => console.log('branch changed!')) | ||
branch.set('new value') | ||
// => branch changed! | ||
// => plant changed! | ||
``` | ||
## Prior art | ||
@@ -100,0 +129,0 @@ |
@@ -39,2 +39,12 @@ import Foliage, { Cursor } from '../index' | ||
it ('assumes a single argument sets the entire state', function() { | ||
let plant = new Foliage({ fiz: 'buz'}) | ||
let query = plant.get('fiz') | ||
query.set('foo') | ||
query.valueOf().should.equal('foo') | ||
plant.get('fiz').valueOf().should.equal('foo') | ||
}) | ||
it ('sets the original state from a cursor', function() { | ||
@@ -48,2 +58,32 @@ let plant = new Foliage(deep) | ||
}) | ||
it ('triggers a change event on the cursor', function(done) { | ||
let plant = new Foliage(deep) | ||
let query = plant.get('first') | ||
query.listen(done) | ||
query.set('second', 'modified') | ||
}) | ||
it ('triggers a change event on the parent', function(done) { | ||
let plant = new Foliage(deep) | ||
let query = plant.get('first') | ||
plant.listen(done) | ||
query.set('second', 'modified') | ||
}) | ||
it ('does not trigger a change event on siblings', function(done) { | ||
let plant = new Foliage({ first: 'first', second: 'second' }) | ||
let a = plant.get('first') | ||
let b = plant.get('second') | ||
b.listen(function() { | ||
throw "Sibling should not have triggered event" | ||
}) | ||
a.listen(done) | ||
a.set('modified') | ||
}) | ||
}) | ||
@@ -50,0 +90,0 @@ |
@@ -7,2 +7,3 @@ /** | ||
import sprout from 'sprout-data' | ||
import Diode from 'diode' | ||
@@ -12,2 +13,4 @@ export default Foliage | ||
function Foliage (state, keys, source) { | ||
Diode.decorate(this) | ||
this._state = state | ||
@@ -20,4 +23,2 @@ this._keys = keys ? [].concat(keys) : [] | ||
...enumeration, | ||
state() { | ||
@@ -35,8 +36,24 @@ return this.isTrunk() ? this._state : this._source.state() | ||
_bubble() { | ||
this.volley() | ||
if (this.isTrunk() === false) { | ||
this._source.volley() | ||
} | ||
}, | ||
commit(state) { | ||
this.trunk()._state = state | ||
this._bubble() | ||
}, | ||
set(key, value) { | ||
let mod = sprout.assoc(this.state(), this.query(key), value) | ||
let mod; | ||
if (arguments.length === 1) { | ||
mod = sprout.assoc(this.state(), this.query(), key) | ||
} else { | ||
mod = sprout.assoc(this.state(), this.query(key), value) | ||
} | ||
this.commit(mod) | ||
@@ -65,4 +82,5 @@ }, | ||
return this.valueOf() | ||
} | ||
}, | ||
...enumeration | ||
} |
@@ -26,2 +26,3 @@ var Webpack = require('webpack') | ||
externals: { | ||
'diode': 'diode', | ||
'sprout-data': 'sprout-data' | ||
@@ -28,0 +29,0 @@ }, |
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
34148
337
132
2
+ Addeddiode@^4.0.0
+ Addeddiode@4.4.0(transitive)