0.1.3 • Published 7 years ago

copal v0.1.3

Weekly downloads
2
License
MIT
Repository
github
Last release
7 years ago

Copal

Why?

  • Stripped down simplicty
  • Pure functional composable code
  • No boilerplate
  • Async is built in
  • Easy to unit test

Simple app

const actions = {
  initialise: a => a.map(s => ({value:1})),
  increment: a => a.map(s => ({ value:s.value + 1 })),
  decrement: a => a.map(s => ({ value:s.value - 1 }))
}

const render = (state, actions) => {
  return <div>
    <button onClick={actions.increment} > UP </button>
    <button onClick={actions.decrement} > DOWN </button>
    <p>{state.value}</p> 
  </div>
}

export const App = copal(render, actions )

Handling async

const AsyncSideEffect = (state, actions) => {
  return Delay(1000).then( actions.increment )
}

const actions = {
  increment: a => a.map(s => ({ value:s.value + 1 })),
  async: a => a.addEffect(AsyncSideEffect)
}

Architecture

Copal is much like Redux only simpler. All the examples here use React to render but in therory its not limited to just react.

There are just two concepts in Copal actions and effects. Both are functions.

Copal

Actions

Are pure functions that take the current app state and update it much like reducers in redux. However they differ slighlty in that they can also return a list of side effects to be run. This is a crutial diffrence as it means its easy follow that when Action A happens it will change the state like this AND trigger these side effects. As these functions are pure unit testing them is easy. These functions will make up the core of your app.

Effects

Are where all the untidy side effects and async stuff takes place. They recive the app state and the actions which they can call. Unlike redux there is no need to dipatch an 'Action' object you can just call the action functions direclty. Effects should not really contain any app logic. The view is just a special kind of effect that is called every action.

Wait!

What with the a, map and addEffect

actions are effectivly functions that take this form

({ state:{}, effects:[]}) => ({ state:{}, effects:[]} )

In its raw form working with this structure is a bit clumsy. Wrapping it in a helper takes the pain away but still keeps it pure.

  • map: accepts a function that updates the app state
  • addEffect: adds an effect to the list of effects
  • chain: composes actions together
  • log: prints the current state and effects list
  • fold: returns the raw data. (only really needed for testing)

Examples

Counter

Edit Copal - counter

Todo

Edit Copal - todo

Reddit client

Edit Copal - reddit

0.1.3

7 years ago

0.1.2

7 years ago

0.1.1

7 years ago

0.1.0

7 years ago