Skip to content

ochafik/es6-lenses

Repository files navigation

ES6 Lenses Build Status npm version 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

About Proxies

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 with npm run rollup:w

Develop

npm i
npm start