Skip to content

Instantly share code, notes, and snippets.

@vslinko
Last active August 20, 2016 20:15
Show Gist options
  • Star 3 You must be signed in to star a gist
  • Fork 2 You must be signed in to fork a gist
  • Save vslinko/cab24085f029def8997b to your computer and use it in GitHub Desktop.
Save vslinko/cab24085f029def8997b to your computer and use it in GitHub Desktop.
minimal flux
/* @flow */
type State = Object
type Action = {type: string | void}
type AsyncAction = (performAction: FluxPerformFunction, state: State) => void
type ActionCreator = () => Action | AsyncAction
type StoreFunction = (state: State, action: Action) => State
type StoreDefinition = {name: string, store: StoreFunction}
type CombineStoresFunction = (stores: Array<StoreDefinition>) => StoreFunction
type FluxListener = (state: State) => void
type FluxUnsubscribe = () => void
type FluxHydro = {state: State, listeners: Array<FluxListener>}
type FluxDehydrateFunction = () => FluxHydro
type FluxHydrateFuntion = (hydro: FluxHydro) => void
type FluxSubscribeFunction = (listener: FluxListener) => FluxUnsubscribe
type FluxPerformFunction = (action: Action | AsyncAction) => void
type Flux = {subscribe: FluxSubscribeFunction, perform: FluxPerformFunction, dehydrate: FluxDehydrateFunction, hydrate: FluxHydrateFuntion}
type FluxCreator = (store: StoreFunction) => Flux
function syncActionCreator(): Action {
return {
type: 'ACTION_TYPE'
}
}
function asyncActionCreator(): AsyncAction {
return function asyncAction(performAction: FluxPerformFunction, state: State): void {
performAction(syncActionCreator())
}
}
function itemsStore(state: State = {}, action: Action): State {
switch (action.type) {
default:
return state
}
}
function combineStores(stores: Array<StoreDefinition>): StoreFunction {
return function combinedStore(state: State, action: Action): State {
return stores.reduce((acc, storeDefinition) => {
acc[storeDefinition.name] = storeDefinition.store(state[storeDefinition.name], action)
return acc
}, {})
}
}
function createFlux(store: StoreFunction): Flux {
var state: State = store({}, {type: undefined})
var listeners: Array<FluxListener> = []
function subscribe(listener: FluxListener): function {
listeners.push(listener)
listener(state)
return function() {
listeners = listeners.filter(l => l !== listener)
}
}
function dispatch(action: Action): void {
state = store(state, action)
listeners.forEach(listener => listener(state))
}
function perform(action: Action | AsyncAction): void {
return typeof action === 'function'
? action(perform, state)
: dispatch(action)
}
function dehydrate() {
var hydro = {state, listeners}
state = {}
listeners = []
return hydro
}
function hydrate(hydro = {}) {
state = hydro.state || {}
listeners = hydro.listeners || []
}
return {
subscribe,
perform,
hydrate,
dehydrate,
}
}
var combinedStore = combineStores([
{name: 'items', store: itemsStore},
])
var flux = createFlux(combinedStore)
flux.perform(asyncActionCreator())
var unsubscribe = flux.subscribe(state => {
console.log(state)
})
unsubscribe()
var hydro = flux.dehydrate()
flux.hydrate(hydro)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment