focalize

0.2.3 • Public • Published

Focalize

Functional Lenses for Javascript

Focalize provides a composable set of functionality to handle immutable data updates.

Example

In order to update state immutably we might use the object spread operator and map / reduce over arrays as follows:

// vanilla-reducer.js
export const reducer = (state = {}, action) => {
  switch (action.type) {
    case 'FIRE':
      return {
        ...state,
        departments: (state.departments || []).map(department => ({
          ...department,
          employees: (department.employees || []).map(employee =>
            (employee.staffId === event.staffId) ? ({
              ...employee,
              terminated: true
            }) : employee)
        }))
      });
    default:
      return state;
  }
};

Focalize increases readibility by providing a composable API that can be used to both query and update data immutably. The same example using Focalize becomes.

// lensed-reducer.js
import { prop, select, every, compose } from 'focalize';
 
export const reducer = (state = {}, action) => {
  switch (action.type) {
    case 'FIRE':
      return compose(
        prop('terminated'),
        select(employee => employee.staffId === event.staffId),
        prop('employees'),
        every(),
        prop('department')
      ).set(state, true);
    default:
      return state;
  }
};

Also note that in the top example if the employee does not exist or is already terminated we still end up with a new state object.

Focalize performs updates economically, we retain the existing objects if no changes are required, and hence we can use state === result to check for changes.

import { reducer as lensedReducer } from './lensed-reducer';
 
const state = {
  departments: [
    {
      name: 'Research',
      employees: [
        {
          staffId: '101',
          name: 'Francis',
          terminated: false
        },
        {
          staffId: '123'
          name: 'Bob',
          terminated: true
        }
      ]
    }
  ]
};
 
// Bob already terminated, no changes required
assert(lensedReducer(state, {
  type: 'FIRE',
  staffId: '123'
}) === state); // => OK!

For more examples see the test folder for basic and advanced usage as well as usage for each operator.

References

Package Sidebar

Install

npm i focalize

Weekly Downloads

2

Version

0.2.3

License

MIT

Last publish

Collaborators

  • stuartwakefield