Overmind
frictionless state management
Last updated
{
isAuthenticating: false,
dashboard: {
issues: [],
selectedIssueId: null,
},
user: null,
form: new Form()
}export const fetchItems = async () {
const response = await fetch('/api/items')
return response.json()
}
}export const loadApp = ({ state, effects }) => {
state.items = await effects.api.fetchItems()
}export const getItems = async ({ state, effects }) => {
state.isLoadingItems = true
state.items = await effects.api.fetchItems()
state.isLoadingItems = false
}export const search = pipe(
mutate(({ state }, query) => {
state.query = query
}),
filter((_, query) => query.length > 2),
debounce(200),
mutate(async ({ state, effects }, query) => {
state.isSearching = true
state.searchResult = await effects.getSearchResult(query)
state.isSearching = false
})
)const loginChart = {
initial: 'LOGIN',
states: {
LOGIN: {
on: {
changeUsername: null,
changePassword: null,
login: 'AUTHENTICATING'
}
},
AUTHENTICATING: {
on: {
resolveUser: 'AUTHENTICATED',
rejectUser: 'ERROR'
}
},
AUTHENTICATED: {
on: {
logout: 'LOGIN'
}
},
ERROR: {
on: {
tryAgain: 'LOGIN'
}
}
}
}export const state = {
mode: statemachine({
initial: 'unauthenticated',
states: {
unauthenticated: ['authenticating'],
authenticating: ['unauthenticated', 'authenticated'],
authenticated: ['unauthenticating'],
unauthenticating: ['unauthenticated', 'authenticated']
}
}),
user: null,
error: null
}class LoginForm() {
private username = ''
private password = ''
private validationError = ''
changeUsername(username) {
this.username = username
}
changePassword(password) {
if (!password.match([0-9]) {
this.validationError = 'You need some numbers in your password'
}
this.password = password
}
isValid() {
return Boolean(this.username && this.password)
}
}
export const state = {
loginForm: new LoginForm()
}import { createOvermindMock } from 'overmind'
import { config } from './'
test('should get items', async () => {
const overmind = createOvermindMock(config, {
api: {
fetchItems: () => Promise.resolve([{ id: 0, title: "foo" }])
}
})
await overmind.actions.getItems()
expect(overmind.mutations).toMatchSnapshot()
})