Comparing version 0.0.1 to 0.1.0
@@ -1,2 +0,2 @@ | ||
module.exports=function(t){function e(n){if(r[n])return r[n].exports;var o=r[n]={exports:{},id:n,loaded:!1};return t[n].call(o.exports,o,o.exports,e),o.loaded=!0,o.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},o=function(t,e){if(!(t instanceof e))throw new TypeError("Cannot call a class as a function")},u=r(1),i=n(u),s=function(){function t(e,r){o(this,t),this._value=e,this._parent=r}return t.prototype.get=function(t,e){return i.get(this._value,t,e)},t.prototype.set=function(t,e){this._value=i.assoc(this._value,t,e)},t.prototype.branch=function(e,r){return new t(this.get(e,r),this)},t.prototype.trunk=function(){return this._parent?this._parent.trunk():this},t.prototype.keys=function(){return Object.keys(this._value)},t.prototype.values=function(){var t=this;return this.keys().map(function(e){return t.get(e)},this)},t.prototype.map=function(t,e){return this.values().map(t,e)},t.prototype.filter=function(t){return this.values().filter(t)},t.prototype.find=function(t){return this.filter(t)[0]},t.prototype.reduce=function(t,e,r){return this.values().reduce(t,e,r)},t.prototype.value=function(){return this.valueOf()},t.prototype.valueOf=function(){return this._value},t.prototype.is=function(t){return this.valueOf()===t.valueOf()},t}();t.exports=s},function(t){t.exports=require("sprout-data")}]); | ||
module.exports=function(t){function e(n){if(r[n])return r[n].exports;var u=r[n]={exports:{},id:n,loaded:!1};return t[n].call(u.exports,u,u.exports,e),u.loaded=!0,u.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},u=r(4),s=n(u);t.exports=s},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(){for(var t=arguments.length,e=Array(t),r=0;t>r;r++)e[r]=arguments[r];return this.filter.apply(this,e)[0]}};e.forEach(function(t){r[t]=function(){for(var e,r=arguments.length,n=Array(r),u=0;r>u;u++)n[u]=arguments[u];return(e=this.values())[t].apply(e,n)}}),t.exports=r},function(t){t.exports=require("sprout-data")},function(t,e,r){"use strict";function n(t,e){this._keys=[].concat(t),this._source=e}var u=function(t){return t&&t.__esModule?t["default"]:t},s=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},o=r(1),i=u(o),a=r(2),c=u(a);t.exports=n,n.prototype=s({},i,{query:function(t){return t?this._keys.concat(t):this._keys},get:function(t){return new n(this.query(t),this._source)},set:function(t,e){this._source.set(this.query(t),e)},remove:function(t,e){this._source.remove(this.query(t),e)},trunk:function(){return this._source},valueOf:function(){return c.get(this._source.valueOf(),this.query())}})},function(t,e,r){"use strict";function n(t){this._state=t}var u=function(t){return t&&t.__esModule?t["default"]:t},s=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},o=r(3),i=u(o),a=r(1),c=u(a),f=r(2),h=u(f);t.exports=n,n.prototype=s({},c,{get:function(t){return new i(t,this)},set:function(t,e){this._state=h.assoc(this._state,t,e)},remove:function(t){this._state=h.dissoc(this._state,t)},trunk:function(){return this},valueOf:function(){return this._state}})}]); | ||
//# sourceMappingURL=Foliage.js.map |
@@ -35,3 +35,3 @@ var Webpack = require('webpack') | ||
webpack: { | ||
devtool : '#eval-source-map', | ||
devtool : 'inline-source-map', | ||
plugins : webpack_config.plugins, | ||
@@ -38,0 +38,0 @@ resolve : webpack_config.resolve, |
{ | ||
"name": "foliage", | ||
"version": "0.0.1", | ||
"version": "0.1.0", | ||
"description": "A cursor like tree data structure on top of sprout.", | ||
@@ -5,0 +5,0 @@ "main": "dist/Foliage.js", |
@@ -12,2 +12,93 @@ [![NPM](https://nodei.co/npm/foliage.png?compact=true)](https://npmjs.org/package/foliage) | ||
More to come... | ||
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). | ||
In more practical terms, Foliage is a thin layer on top of [`sprout`](https://github.com/herrstucki/sprout). | ||
## What problems does it attempt to solve? | ||
1. 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 makes it easier to "branch" off a subset of data while still having the ability to reference the root. | ||
2. Data traversal. It is simpler to run queries for specific records on objects, with a query like data.users[params.id]. However JavaScript objects aren't good at enumeration. Foliage provides some helpers out of the box for this. | ||
3. It is small. Foliage isn't trying to do too much or be too smart. Like [Microcosm](https://github.com/vigetlabs/microcosm), it will be embedded in other tools and should be as small as possible. | ||
## Opinions | ||
1. Keep a naming convention similar to ES6 maps | ||
## Working with Foliage | ||
Foliage accepts a seed: | ||
```javascript | ||
let plant = new Folage({ berries: true }) | ||
``` | ||
## Querying records | ||
`get` pulls data out of a "plant." | ||
```javascript | ||
let plant = new Folage({ berries: true }) | ||
plant.get('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 | ||
let oak = new Folage({ | ||
squirrels: { | ||
squeakem: { weight: 2, height: 12 } | ||
chatters: { weight: 5, height: 8 } | ||
} | ||
}) | ||
let squirrels = oak.get('squirrels') | ||
``` | ||
In this example, `squirrels` is a subset of `oak` focused on the | ||
`squirrels` key. Under the hood, they point to the same underlying | ||
data. This means if you `set` in `squirrel`, `oak` will be modified as | ||
well: | ||
```javascript | ||
squirrels.set(['squeakem', 'weight'], 5) | ||
oak.get(['squirrels', 'squeakem', 'weight']).valueOf() // => 5 | ||
``` | ||
A couple of things are going on here. First, `set` is used to modify | ||
data. It maps directly to | ||
[`sprout`'s `assoc` method](https://github.com/herrstucki/sprout#assocobj-path-value-path2-value2-). Second, | ||
both `get` and `set` accept an array of keys. When given an array, | ||
they will traverse the tree for the leaf value instead of just | ||
returning the key from the most immediate level. | ||
## Phoning home | ||
All branches have a reference to their parent. No matter how branched, | ||
the `trunk` can be found: | ||
```javascript | ||
let plant = new Foliage({ fizz: 'buzz' }) | ||
let fiz = plant.get('fiz') | ||
assert(fiz.trunk() === plant) | ||
``` | ||
## Prior art | ||
There is nothing novel about Foliage, and probably slightly flawed in | ||
it's mimicking of: | ||
- http://omniscientjs.github.io/ | ||
- https://github.com/omniscientjs/immstruct | ||
- https://github.com/omcljs/om | ||
- http://yquem.inria.fr/~huet/PUBLIC/zip.pdf | ||
- https://github.com/dustingetz/react-cursor | ||
- https://github.com/Yomguithereal/baobab |
@@ -1,66 +0,3 @@ | ||
/** | ||
* Foliage | ||
*/ | ||
import Foliage from './Foliage' | ||
import sprout from 'sprout-data' | ||
export default class Foliage { | ||
constructor(value, parent) { | ||
this._value = value | ||
this._parent = parent | ||
} | ||
get(key, fallback) { | ||
return sprout.get(this._value, key, fallback) | ||
} | ||
set(key, value) { | ||
this._value = sprout.assoc(this._value, key, value) | ||
} | ||
branch(key, fallback) { | ||
return new Foliage(this.get(key, fallback), this) | ||
} | ||
trunk() { | ||
return this._parent ? this._parent.trunk() : this | ||
} | ||
keys() { | ||
return Object.keys(this._value) | ||
} | ||
values() { | ||
return this.keys().map(key => this.get(key), this) | ||
} | ||
map(fn, scope) { | ||
return this.values().map(fn, scope) | ||
} | ||
filter(fn) { | ||
return this.values().filter(fn) | ||
} | ||
find(fn) { | ||
return this.filter(fn)[0] | ||
} | ||
reduce(fn, initial, scope) { | ||
return this.values().reduce(fn, initial, scope) | ||
} | ||
value() { | ||
return this.valueOf() | ||
} | ||
valueOf() { | ||
return this._value | ||
} | ||
is(branch) { | ||
return this.valueOf() === branch.valueOf() | ||
} | ||
} | ||
export default Foliage |
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
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
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
30844
18
286
104
1