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 = async ({ 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(
({ state }, query) => {
state.query = query
},
filter(({ state }) => state.query.length > 2),
debounce(200),
async ({ state, effects }) => {
state.isSearching = true
state.searchResult = await effects.getSearchResult(state.query)
state.isSearching = false
}
)export const state = statemachine({
UNAUTHENTICATED: {
SIGN_IN: () => ({ current: 'AUTHENTICATING' })
},
AUTHENTICATING: {}
})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()
})