26 Home en
Svinokot edited this page 12 months ago

Lens

LensJs implement the concept of a functional programming, where the data structure has the form of a directed graph (from the root to the leaves).

Each node of the graph of LensJs does not contain data, but only provides an interface and performs addressing in the graph. This also means that the structure of the graph depends on the structure of the data itself.

The contents

Instalation

  • Git git clone http://git.vovikilelik.com/Clu/lens-js.git

  • Npm npm i @vovikilelik/lens-js

Using with HTML

<script type="module" src="lens-js.js"></script>

// or

<script type="module">
    import { Lens } from './lens-js.js';

    /* your code here */
</script>

Using with NPM

import { Lens } from '@vovikilelik/lens-js';

Introduction

  • Creation root store
export const lens = LensUtils.createLens({ /* default data */ });
  • Getting deep structure
const deep = lens.go('deep');
const deeper = deep.go('deeper');
  • Singleton pattern able to use for each other node
import {lens} from 'store';
export default lens.go('deep');
  • Catching changes
const callback = ({ current, diffs }) => console.log(current.value);
lens.attach(callback);
lens.set('Hello!') // console: Hello!
  • Extending
class MyLens extends Lens {
  doRequest(addr) {
    myFetch(addr).then(response => this.set(response));
  }
}

const foo = lens.go('foo', MyLens);
foo.doRequest('https://');
  • Live-transforming
import {transform} from 'lens-utils';

const toHex = transform(
  v => `#${v.toString(16)}`,
  v => parseInt(v.substring(1), 16);
);

const hex = lens.go('color').chain(toHex);
hex.set('#aabbcc');

Comparation with Redux and MobX/MST

Not contrast but nearly

No reducers

LensJs does not deed in redusers or same because it merge data automatically

Redux:

enum ActionType {
  hello;
}

const getHelloAction = (value) => ({
  type: ActionType.hello,
  value
});

const reducer = (state, {type, value}) {
  switch(type) {
    case ActionType.hello:
      return { world: value };

      default: return state;
  }
}

...
dispatch(getHelloAction('Hello!'));

LensJs:

lens.go('world').set('Hello!');

More scalability

Every lens node is root of own subtree. It give passibility to make components whitch is not assign with main form.

Redux:

const Cat = ({ cat }) => <div>{cat.ribbon.color}</div>;
const mapStateToProps = (state, ownProps) =>
  ({cat: state.cats[ownProps.name]});
export default connect(Cat, mapStateToProps);

LensJs:

export const Cat = ({ lens }) => {
  const [ cat ] = useLens(lens);
  return <div>{cat.ribbon.color}</div>;
}

No overcode

It means that lensJs is easier than others (in default)

MobX/MST:

/* Ribbon store */
export const Ribbon = type
  .model("Ribbon", {
    color: type.string
  })
  .actions(self => ({
    setColor(value) {
      self.color = value;
    },
  }));
  
/* Cat store */
export const Cat = type
  .model("Cat", {
    ribbon: type.reference(Ribbon)
  });

LensJs:

const cat = cats.go('murzik');
const ribbon = cat.go('ribbon');