Skip to content

Instantly share code, notes, and snippets.

@m3g4p0p
Last active September 29, 2016 22:22
Show Gist options
  • Save m3g4p0p/3868275f3f4410fa2bb651c15a4be5e4 to your computer and use it in GitHub Desktop.
Save m3g4p0p/3868275f3f4410fa2bb651c15a4be5e4 to your computer and use it in GitHub Desktop.
A state container that allows calling actions directly on the container instance
;(function init (global) {
'use strict'
// Constructor function, initialise states and actions
global.Container = function constructor (initialState) {
this._states = initialState === undefined ? [] : [initialState]
this._actions = {}
}
// Get the current state
Container.prototype.$get = function get () {
return this._states[this._states.length - 1]
}
// Reset the states array
Container.prototype.$clear = function clear () {
this._states = []
}
// Revert the last state change
Container.prototype.$undo = function undo () {
return this._states.pop()
}
// Register a dedicated reducer to an action, which again is
// specified by the function name
Container.prototype.$register = function register (reducer) {
const name = reducer.name
// Push the new reducer to the corresponding action
this._actions[name] = this._actions[name] || []
this._actions[name].push(reducer)
// The action can be dispatched by calling it directly on
// the container instance
this[name] = this[name] || function action (...args) {
// Reduce the state by passing it along the reducers
const newState = this
._actions[name]
.reduce((currentState, currentReducer) =>
currentReducer.call(this, currentState, ...args),
this.$get()
)
// Push and return the new state
this._states.push(newState)
return newState
}
// When registering a new reducer, another function to
// unregister it gets returned
return function unregister () {
this._actions[name].splice(this._actions[name].indexOf(reducer), 1)
}.bind(this)
}
// Shorthand factory
global.contain = function contain (initialState) {
return new Container(initialState)
}
})(typeof global === 'undefined' ? window : global)
@m3g4p0p
Copy link
Author

m3g4p0p commented Sep 29, 2016

ez-state

JavaScript Style Guide

Idea

Basically just a convenient shorthand for dispatching actions.

Usage

// Initialise container
const counter = contain(0)

// Register actions/reducers
const add = counter.$register(function ADD (state, n) {
  return state + n
})

const add2times = counter.$register(function ADD (state, n) {
  return state + (n * 2)
})

const substract = counter.$register(function SUBSTRACT (state, n) {
  return state - n
})

// Dispatch actions
counter.ADD(1)
counter.ADD(2)
counter.SUBSTRACT(1)

// Unregister reducers
add()
add2times()
substract()

// Logs [ 0, 3, 9, 8 ]
console.log(counter._states)

License

MIT

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment