Skip to content

Instantly share code, notes, and snippets.

@lmatteis
Created May 21, 2018 22:45
Show Gist options
  • Save lmatteis/2aa06a1e2e7e52acd317e71b40b245b0 to your computer and use it in GitHub Desktop.
Save lmatteis/2aa06a1e2e7e52acd317e71b40b245b0 to your computer and use it in GitHub Desktop.
import { Machine } from 'xstate'
const UPDATE = '@@statechart/UPDATE'
export function getStatechart(state) {
return state.statechart
}
export function createStatechartMiddleware(statechart) {
const machine = Machine(statechart)
const validEvents = machine.events
const statechartMiddleware = store => next => (action) => {
if (validEvents.includes(action.type)) {
const result = next(action)
const state = store.getState()
const currentStatechart = getStatechart(state)
const nextMachine = machine.transition(currentStatechart, action, state)
// BEWARE: each store.dispatch call will block, and call this
// middleware again, causing some earlier unwanted dispatches.
// should group the dispatches into 1 so it doesn't recursively
// call this middleware for each dispatch.
// To avoid this, we use setImmediate
// run actions
nextMachine.actions.forEach(actionType => (
next({
type: actionType,
payload: action.payload,
})
))
next({ type: UPDATE, payload: nextMachine.value })
return result
}
return next(action)
}
function statechartReducer(state = machine.initialState, action) {
if (action.type === UPDATE) {
return action.payload
}
return state
}
return {
statechartMiddleware,
machine,
statechartReducer,
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment