State management with Redux is really nice. But it can get convoluted really quickly. It's almost like a pub/sub may do the trick, but that's missing modules, immutability, etc. Well it's hybrid time!
- To manage state with a simple pub/sub pattern
 - To improve upon the pub/sub with unidirectional data flow
 - For State to return a new state (pure function)
 - Message filtering can be applied without a 
switchstatement (you create your own event$type) - To allow for manipulation of deeply nested state properties through use of strings 
{'my[index]deeply.nests.state': 'new value'}(we're sending this to substate to not mutate the state, but make a new copy (Flux-y)! - Maintain a small size
 
- (if using modules) 
import { myInstance } from 'myFile' - Components will register one or more methods to rerender themselves using your instance (see instantiation)  using 
myInstance.on('STATE_UPDATED', rerender)per method - Components take UI event ("click", "focus", etc) and pass it off to a Handler/Reducer
 - The Handler/Reducer figures out what should change in the state (it does not update the state directly).  It also figures out if/what 
$typeshould be sent to the Pub/Sub module - The Handler/Reducer will then 
emitUPDATE_STATEto the Pub/Sub module - The Pub/Sub module will create a new state and will 
emitSTATE_UPDATEDor the specified$typeto the Components. - The Components will digest the new State using the method(s) registered in step 2
 - If you want a deep clone pass in 
$deep: trueinto the state on emit. ORdefaultDeep: truein the options. 
npm install substate --save- copy and paste from 
index.jsinto a<script>or external js file 
substate is a class so you call it like so
myFile.js
import { substate } from 'substate';
Then you instantiate it as such
export const myInstance = new substate({options});
substate accepts an options object as an optional parameter. These are the possible options
| Option | Desc | Default | 
|---|---|---|
| name | name of the instance | 'substateInstance' | 
| currentState | index of state to start on | 0 | 
| stateStorage | array of all the states | [ ] | 
| state | object containing the initial state | null | 
| defaultDeep | default to deep cloning the state everytime | false | 
| beforeUpdate[ ] | array of middleware before state is updated.Has access to substate instance and action | [] | 
| afterUpdate[ ] | array of middleware for after state is updated. Has access to substate instance | [] | 
@paramoptional method parameter@param*required method parameter
| Method | Desc | Returns | 
|---|---|---|
| getState | get a state @param* - index of state needed | 
state | 
| getcurrentState | get the current state | current state object | 
| getProp | get a prop from current state @param* - string path to prop | 
property you request | 
| changeState | change the version of the state @param* - {requestedState: index of state, action: (optional name of event to emit)} | 
emits action parameter event or 'STATE_CHANGED' event with the new current state | 
| resetState | resets the stateStorage array to an empty array | 
emits 'STATE_RESET' | 
@paramoptional method parameter@param*required method parameter@param[num]order of method parameter
| Method | Desc | 
|---|---|
| on | @param1* STRING of event name to listen to. @param2* FUNC handler to execute when this event you listen to happens | 
| off | @param1* STRING of event name to remove handler from. @param2* FUNC to remove from the execution queue | 
| emit | @param1* STRING event name  @param2 object of data to pass into your handler event from 'on' method | 
| Event | Desc | Returns | 
|---|---|---|
| 'UPDATE_STATE' | updates the entire state with the object passed in | updated state | 
| 'CHANGE_STATE' | fires changeState method above requires same @params | 
emits 'STATE_CHANGED' | 
note: the object of data that is passed, cannot have a key called '$type'
| Method | Event | Custom Event | Next | 
|---|---|---|---|
| emit | 'UPDATE_STATE' | @param2 is an object:   {$type: 'MY_CUSTOM_EVENT'} | 
Will update/change state. The $type property will then be emitted so you can listen to it like substateInstance.on('MY_CUSTOM_EVENT', func) | 
Basically to utilitze a custom event, you still need to use UPDATE_STATE but the data object needs a $type with an event name you want the State to emit when updated
- better dev instructions and console warnings/errors
 - seemless compatibility with infernojs, preactjs, stenciljs
 - demos demos demos
 - better documentation