es6-lenses
v0.4.1
Published
Functional lenses for ES6
Downloads
1
Maintainers
Readme
ES6 Lenses changelog
Proxy-powered functional lenses for ECMAScript 2015+ & TypeScript projects (try it in your browser now!)
// Install: `npm i --save es6-lenses`
const {lens, _} = require("es6-lenses")
const obj = {x: {y: 1}, z: 2}
// Flow / TypeScript alternative:
// lens((_: typeof obj) => _.x.y)
const xy = lens(_.x.y)
// Lenses can be called (== .get):
xy(obj) // 1
xy.get(obj) // 1
// Set deep-clones the modified paths:
xy.set(obj, 10) // {x: {y: 10}, z: 2}
// Shorthand selectors are also functions:
[{x: 1}, {x: 2}].map(_.x) // [1, 2]
// Lenses can create nested structures:
const y_z = lens([_.x.y, {z: _.z}])
y_z.get(obj) // ['y', {z: 'z'}]
y_z.set(obj, ['yy', {z: 'zz'}])
// {x: {y: 'yy'}, z: 'zz'}
Note: .set
deeply clones objects (and is Immutable.Map-aware), while .mutate
attempts to modify them in-place.
About lenses
- Functional Lenses, How Do They Work
- Lenses with Immutable.js
- Great pre-existing lens libraries (see npmjs):
- https://github.com/DrBoolean/lenses
- https://github.com/calmm-js/partial.lenses
- https://github.com/roman01la/js-lenses
- https://github.com/fantasyland/fantasy-lenses
- https://github.com/tomasdeml/lenticular.ts
- https://github.com/beezee/statelens
About Proxies
Metaprogramming in ES6:
- http://www.2ality.com/2014/12/es6-proxies.html
- https://ponyfoo.com/articles/es6-proxy-traps-in-depth
- https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Meta_programming
Proxy docs:
- https://github.com/tvcutsem/harmony-reflect/blob/master/doc/traps.md
- https://github.com/Microsoft/TypeScript/blob/master/lib/lib.es2015.proxy.d.ts
TODO
- Support filtered / mapped semantics:
lens(_ => _.addresses.map(_ => _.zipCode)).mapped.update(toUpperCase)
- More examples about tuple / object inputs & outputs.
- More tests, especially re/ integration with Immutable (cover interaction w/ Record)
Bundling with rollup
Notes:
- Can't down-compile to ES5 as we're using ES6's Proxy
- UglifyJS might require a special ES6-friendly branch: please report any success :-)
Setup:
Prerequisite:
npm --save-dev rollup npm --save-dev rollup-watch npm --save-dev rollup-plugin-typescript npm --save-dev rollup-plugin-node-resolve
Config (
rollup.config.js
):import typescript from 'rollup-plugin-typescript'; import nodeResolve from 'rollup-plugin-node-resolve'; export default { entry: './main.ts', format: 'iife', dest: 'out.js', sourceMap: true, plugins: [ nodeResolve({jsnext: true, main: true}), typescript({ typescript: require('typescript') }), ] }
Add the following scripts to your
package.json
:{ "scripts": { "rollup": "rollup -c", "rollup:w": "rollup -c -w" }, ... }
Build with
npm run rollup
, continuously rebuild withnpm run rollup:w
Develop
npm i
npm start