Comparing version 0.8.0 to 0.9.0
# Changelog | ||
## 0.9.0 | ||
- `get` has been renamed `graft`. `fetch` is now `get`. This change is | ||
designed to make the API feel more like an ES6 map. | ||
## 0.8.0 | ||
@@ -4,0 +9,0 @@ |
@@ -1,2 +0,2 @@ | ||
module.exports=function(t){function r(n){if(e[n])return e[n].exports;var i=e[n]={exports:{},id:n,loaded:!1};return t[n].call(i.exports,i,i.exports,r),i.loaded=!0,i.exports}var e={};return r.m=t,r.c=e,r.p="",r(0)}([function(t,r,e){function n(t){this._path=[],this._root=this,this._state=t}var i=e(4),o=e(5),u=e(2);n.prototype={getPath:function(t){return t?this._path.concat(t):this._path},commit:function(t){this._root._state=t},get:function(t){return Object.create(this,{_path:{value:this.getPath(t)}})},set:function(t,r){1===arguments.length&&(r=arguments[0],t=void 0),this.commit(i(this._state,this.getPath(t),r))},remove:function(t){this.commit(o(this._state,this.getPath(t)))},fetch:function(t,r){var e=this.get(t).valueOf();return void 0===e?r:e},keys:function(){return Object.keys(this.valueOf()||{})},values:function(){return this.keys().map(this.fetch,this)},valueOf:function(){return u(this._state,this.getPath())},toJSON:function(){return this.valueOf()},is:function(t){return t.valueOf()==this.valueOf()},find:function(){return this.filter.apply(this,arguments)[0]}};var s=["map","reduce","filter","forEach"];s.forEach(function(t){n.prototype[t]=function(){var r;return(r=this.values())[t].apply(r,arguments)}}),t.exports=n},function(t,r,e){t.exports=function(t){if(Array.isArray(t))return t.slice();var r={};for(var e in t)r[e]=t[e];return r}},function(t,r,e){var n=e(3);t.exports=function(t,r){for(var e=!0;e;){u=s=void 0,e=!1;var i=t,o=r,u=o[0],s=o.slice(1);if(!u)return i;if(n(i,o)===!1)return void 0;if(!s.length)return i[u];t=i[u],r=s,e=!0}}},function(t,r,e){t.exports=function(t,r){var e=!0;t:for(;e;){o=u=s=a=void 0,e=!1;var n=t,i=r,o=i[0],u=i.slice(1),s=void 0!==n,a=s&&o in n;if(u.length){if(a){t=n[o],r=u,e=!0;continue t}return!1}return a}}},function(t,r,e){var n=e(1),i=e(2);t.exports=function o(t,r,e){if(i(t,r)===e)return t;var u=r[0],s=r.slice(1),a=n(t);return s.length?a[u]=o(u in a?a[u]:{},s,e):a[u]=e,a}},function(t,r,e){var n=e(1),i=e(3);t.exports=function o(t,r){if(i(t,r)===!1)return t;var e=r[0],u=r.slice(1),s=n(t);return u.length?s[e]=o(t[e],u):delete s[e],s}}]); | ||
module.exports=function(t){function n(e){if(r[e])return r[e].exports;var i=r[e]={exports:{},id:e,loaded:!1};return t[e].call(i.exports,i,i.exports,n),i.loaded=!0,i.exports}var r={};return n.m=t,n.c=r,n.p="",n(0)}([function(t,n,r){function e(t){this._path=[],this._root=this,this._state=t}var i=r(4),u=r(5),o=r(2);e.prototype={getPath:function(t){return t?this._path.concat(t):this._path},commit:function(t){this._root._state=t},get:function(t){function n(n,r){return t.apply(this,arguments)}return n.toString=function(){return t.toString()},n}(function(t,n){return o(this._state,this.getPath(t),n)}),set:function(t,n){1===arguments.length&&(n=arguments[0],t=void 0),this.commit(i(this._state,this.getPath(t),n))},remove:function(t){this.commit(u(this._state,this.getPath(t)))},graft:function(t){return Object.create(this,{_path:{value:this.getPath(t)}})},keys:function(){return Object.keys(this.valueOf()||{})},values:function(){var t=this;return this.keys().map(function(n){return t.get(n)})},valueOf:function(){return o(this._state,this.getPath())},toJSON:function(){return this.valueOf()},is:function(t){return t.valueOf()==this.valueOf()},find:function(){return this.filter.apply(this,arguments)[0]}};var s=["map","reduce","filter","forEach"];s.forEach(function(t){e.prototype[t]=function(){var n;return(n=this.values())[t].apply(n,arguments)}}),t.exports=e},function(t,n,r){t.exports=function(t){if(Array.isArray(t))return t.slice();var n={};for(var r in t)n[r]=t[r];return n}},function(t,n,r){var e=r(3);t.exports=function(t,n,r){for(var i=!0;i;){a=f=void 0,i=!1;var u=t,o=n,s=r,a=o[0],f=o.slice(1);if(!a)return u;if(e(u,o)===!1)return s;if(!f.length)return u[a];t=u[a],n=f,i=!0}}},function(t,n,r){t.exports=function(t,n){var r=!0;t:for(;r;){u=o=s=a=void 0,r=!1;var e=t,i=n,u=i[0],o=i.slice(1),s=void 0!==e,a=s&&u in e;if(o.length){if(a){t=e[u],n=o,r=!0;continue t}return!1}return a}}},function(t,n,r){var e=r(1),i=r(2);t.exports=function u(t,n,r){if(i(t,n)===r)return t;var o=n[0],s=n.slice(1),a=e(t);return s.length?a[o]=u(o in a?a[o]:{},s,r):a[o]=r,a}},function(t,n,r){var e=r(1),i=r(3);t.exports=function u(t,n){if(i(t,n)===!1)return t;var r=n[0],o=n.slice(1),s=e(t);return o.length?s[r]=u(t[r],o):delete s[r],s}}]); | ||
//# sourceMappingURL=Foliage.js.map |
@@ -25,3 +25,3 @@ var Webpack = require('webpack') | ||
reporters: isIntegration ? [ 'progress', 'coverage' ] : [ 'progress' ], | ||
reporters: isIntegration ? [ 'progress', 'coverage' ] : [ 'spec' ], | ||
@@ -28,0 +28,0 @@ coverageReporter: { |
{ | ||
"name": "foliage", | ||
"version": "0.8.0", | ||
"version": "0.9.0", | ||
"description": "A cursor like tree data structure.", | ||
@@ -8,3 +8,3 @@ "main": "dist/Foliage.js", | ||
"coveralls": "CONTINUOUS_INTEGRATION=true npm test && coveralls < coverage/report-lcov/lcov.info", | ||
"prepublish": "NODE_ENV=production webpack -p", | ||
"prepublish": "./scripts/prepublish", | ||
"test": "NODE_ENV=test karma start", | ||
@@ -18,3 +18,4 @@ "test:once": "CONTINUOUS_INTEGRATION=true npm test" | ||
"license": "MIT", | ||
"dependencies": {}, | ||
"dependencies": { | ||
}, | ||
"devDependencies": { | ||
@@ -36,2 +37,3 @@ "babel": "^5.x.x", | ||
"karma-sourcemap-loader": "^0.3.4", | ||
"karma-spec-reporter": "0.0.19", | ||
"karma-webpack": "^1.3.1", | ||
@@ -38,0 +40,0 @@ "source-map-loader": "^0.1.3", |
@@ -12,22 +12,11 @@ [![NPM](https://nodei.co/npm/foliage.png?compact=true)](https://npmjs.org/package/foliage) | ||
Foliage is lightweight tree 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. It compromises on robustness | ||
and purity for the benefit of build size. | ||
Foliage is lightweight tree that operates on a tree of JavaScript | ||
primitives. It is inspired by many Cursors libraries/frameworks (see | ||
[prior art](#prior-art)), | ||
however it is not nearly as ambitious. Specifically, it sacrifices | ||
robustness and purity for the benefit of build size. | ||
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. | ||
## Goals | ||
1. Easier testing. Decouple React components from rest of app. Our | ||
Flux-like framework, | ||
[Microcosm](https://github.com/vigetlabs/microcosm), keeps all | ||
state in a single app instance. It can be troublesome to pass down | ||
this context to child components that need to modify state. Foliage | ||
1. Easier testing. Decouple React components from rest of app. Foliage | ||
makes it easier to "branch" off a subset of data while still having | ||
@@ -48,11 +37,21 @@ the ability to reference the root. | ||
Foliage accepts a seed: | ||
Foliage can retrieve and set data similarly to an ES6 map | ||
```javascript | ||
let plant = new Foliage({ berries: true }) | ||
// retrieve state | ||
plant.get('berries') // true | ||
// set state | ||
plant.set('berries', false) | ||
// remove state | ||
plant.remove('berries') | ||
``` | ||
## Querying records | ||
### Working with subsets of data | ||
`get` pulls data out of a "plant." | ||
`graft` will clone an instance of Foliage and place a cursor to a | ||
point within its tree: | ||
@@ -62,14 +61,5 @@ ```javascript | ||
plant.get('berries').valueOf() // => true | ||
plant.graft('berries').valueOf() // => true | ||
``` | ||
Take out that `valueOf` must be called to retrieve the value out of a | ||
plant. This is because `get` returns a `branch`. Now let's dig into | ||
that. | ||
## Branches | ||
Calling `get` returns a `branch`. Technically, this is called a | ||
`cursor`, but let's keep with the dendrology theme. | ||
```javascript | ||
@@ -83,3 +73,3 @@ let oak = new Foliage({ | ||
let squirrels = oak.get('squirrels') | ||
let squirrels = oak.graft('squirrels') | ||
``` | ||
@@ -94,3 +84,3 @@ | ||
squirrels.set(['squeakem', 'weight'], 5) | ||
oak.get(['squirrels', 'squeakem', 'weight']).valueOf() // => 5 | ||
oak.get(['squirrels', 'squeakem', 'weight']) // => 5 | ||
``` | ||
@@ -97,0 +87,0 @@ |
@@ -17,3 +17,3 @@ import Foliage from '../Foliage' | ||
let plant = new Foliage({ first: [ 1, 2, 3] }) | ||
let query = plant.get('first') | ||
let query = plant.graft('first') | ||
@@ -35,3 +35,3 @@ query.map(incr).should.eql([ 2, 3, 4]) | ||
let plant = new Foliage({ first: [ 1, 2, 3] }) | ||
let query = plant.get('first') | ||
let query = plant.graft('first') | ||
@@ -70,3 +70,3 @@ query.reduce(sum, 0).should.eql(6) | ||
let plant = new Foliage({ first: [ 1, 2, 3, 4] }) | ||
let query = plant.get('first') | ||
let query = plant.graft('first') | ||
@@ -73,0 +73,0 @@ query.find(even).should.eql(2) |
@@ -8,4 +8,4 @@ import Foliage from '../Foliage' | ||
let a = plant.get('foo') | ||
let b = plant.get('foo') | ||
let a = plant.graft('foo') | ||
let b = plant.graft('foo') | ||
@@ -19,5 +19,5 @@ a.is(b).should.equal(true) | ||
a.get('foo').is(b.get('foo')).should.equal(true) | ||
a.graft('foo').is(b.graft('foo')).should.equal(true) | ||
}) | ||
}) |
@@ -8,29 +8,5 @@ import Foliage from '../Foliage' | ||
describe('Foliage::get', function() { | ||
it ('returns cursor to a given pathway', function() { | ||
let plant = new Foliage(shallow) | ||
let query = plant.get('first') | ||
query.getPath().should.eql(['first']) | ||
}) | ||
it ('returns a nested given value', function() { | ||
let plant = new Foliage(deep) | ||
plant.get(['first', 'second']).valueOf().should.equal(2) | ||
}) | ||
it ('nests keys from the results of previous queries', function() { | ||
let plant = new Foliage(deep) | ||
let first = plant.get('first') | ||
let second = first.get('second') | ||
second.valueOf().should.equal(2) | ||
}) | ||
}) | ||
describe('Foliage::fetched', function() { | ||
it ('returns a given value', function() { | ||
let plant = new Foliage(shallow) | ||
plant.fetch('first').should.equal(1) | ||
plant.get('first').should.equal(1) | ||
}) | ||
@@ -40,3 +16,3 @@ | ||
let plant = new Foliage() | ||
plant.fetch('first', 'fiz').should.equal('fiz') | ||
plant.get('first', 'fiz').should.equal('fiz') | ||
}) | ||
@@ -50,3 +26,3 @@ }) | ||
plant.set('first', 'modified') | ||
plant.get('first').valueOf().should.equal('modified') | ||
plant.get('first').should.equal('modified') | ||
}) | ||
@@ -56,3 +32,3 @@ | ||
let plant = new Foliage({ fiz: 'buz'}) | ||
let query = plant.get('fiz') | ||
let query = plant.graft('fiz') | ||
@@ -62,3 +38,3 @@ query.set('foo') | ||
plant.get('fiz').valueOf().should.equal('foo') | ||
plant.get('fiz').should.equal('foo') | ||
}) | ||
@@ -68,7 +44,7 @@ | ||
let plant = new Foliage(deep) | ||
let query = plant.get('first') | ||
let query = plant.graft('first') | ||
query.set('second', 'modified') | ||
plant.get([ 'first', 'second' ]).valueOf().should.equal('modified') | ||
plant.get([ 'first', 'second' ]).should.equal('modified') | ||
}) | ||
@@ -78,7 +54,7 @@ | ||
let plant = new Foliage() | ||
let query = plant.get('first') | ||
let query = plant.graft('first') | ||
query.set('second', 'modified') | ||
plant.get([ 'first', 'second' ]).valueOf().should.equal('modified') | ||
plant.get([ 'first', 'second' ]).should.equal('modified') | ||
}) | ||
@@ -88,7 +64,7 @@ | ||
let plant = new Foliage() | ||
let query = plant.get('first') | ||
let query = plant.graft('first') | ||
query.set('second', 'modified') | ||
plant.get([ 'first', 'second' ]).valueOf().should.equal('modified') | ||
plant.get([ 'first', 'second' ]).should.equal('modified') | ||
}) | ||
@@ -109,3 +85,3 @@ | ||
let plant = new Foliage(deep) | ||
let query = plant.get('first') | ||
let query = plant.graft('first') | ||
@@ -130,3 +106,3 @@ query.remove('second') | ||
describe('when a cursor is empty', function() { | ||
let cursor = plant.get('fiz') | ||
let cursor = plant.graft('fiz') | ||
@@ -143,2 +119,26 @@ it ('returns an empty list when asking for keys', function() { | ||
describe('Foliage::graft', function() { | ||
it ('returns cursor to a given pathway', function() { | ||
let plant = new Foliage(shallow) | ||
let query = plant.graft('first') | ||
query.getPath().should.eql(['first']) | ||
}) | ||
it ('returns a nested given value', function() { | ||
let plant = new Foliage(deep) | ||
plant.graft(['first', 'second']).valueOf().should.equal(2) | ||
}) | ||
it ('nests keys from the results of previous queries', function() { | ||
let plant = new Foliage(deep) | ||
let first = plant.graft('first') | ||
let second = first.graft('second') | ||
second.get().should.equal(2) | ||
}) | ||
}) | ||
describe('Foliage::toJSON', function() { | ||
@@ -154,3 +154,3 @@ let data = [1,2,3,4] | ||
let plant = new Foliage({ first: data }) | ||
let query = plant.get('first') | ||
let query = plant.graft('first') | ||
@@ -157,0 +157,0 @@ query.toJSON().should.equal(data) |
@@ -13,3 +13,3 @@ import Foliage from '../Foliage' | ||
let oak = new Oak() | ||
let acorn = oak.get('acorns') | ||
let acorn = oak.graft('acorns') | ||
@@ -16,0 +16,0 @@ acorn.test().should.equal(true) |
@@ -25,6 +25,4 @@ /** | ||
get(key) { | ||
return Object.create(this, { | ||
_path : { value: this.getPath(key) } | ||
}) | ||
get(key, fallback) { | ||
return get(this._state, this.getPath(key), fallback) | ||
}, | ||
@@ -45,5 +43,6 @@ | ||
fetch(key, fallback) { | ||
let val = this.get(key).valueOf() | ||
return val === undefined ? fallback : val | ||
graft(key) { | ||
return Object.create(this, { | ||
_path : { value: this.getPath(key) } | ||
}) | ||
}, | ||
@@ -56,3 +55,3 @@ | ||
values() { | ||
return this.keys().map(this.fetch, this) | ||
return this.keys().map(i => this.get(i)) | ||
}, | ||
@@ -59,0 +58,0 @@ |
@@ -9,3 +9,3 @@ /** | ||
module.exports = function get (obj, keys) { | ||
module.exports = function get (obj, keys, fallback) { | ||
let [ head, ...tail ] = keys | ||
@@ -18,3 +18,3 @@ | ||
if (has(obj, keys) === false) { | ||
return undefined | ||
return fallback | ||
} | ||
@@ -21,0 +21,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
39754
26
19
99