A tiny (69 lines of code¹) JavaScript state management class.
¹ sans comments and empty lines
npm i @small-tech/state
// @ts-check
import State from '@small-tech/state'
const state = new State({
UNKNOWN: {},
OK: {},
NOT_OK: {}
})
The first state is set as the default state.
It’s recommended that you use the State
class by subclassing it.
This will enable you to:
-
Get language intelligence for your states.
-
Let you store cross-state context by adding custom properties to your subclass.
-
Add behaviour to states (e.g., to render an HTML component based on the current state).
-
Persist your custom state instances to JavaScript Database (JSDB) (e.g., for use in Kitten apps).
e.g.,
// @ts-check
class StatusState extends State {
constructor(name) {
super()
this.states = {
UNKNOWN: { text: 'Unknown' },
OK: { text: 'OK' },
NOT_OK: { text: 'Not OK' }
})
this.state = this.states.UNKNOWN
this.name = name
}
render () {
const html = String.raw
return html`<div>${this.name} Status: ${this.state.text)}</div>`
}
}
const status = new StatusState('Sync')
status.set(status.states.OK)
console.log(status.render())
Would output:
<div>Sync Status: OK</div>
💡 Note that we are not passing the states as an argument to
super()
but instead settingthis.states = { … }
separately on the next line. And, even though the setter forstates
sets the first key as the default, we are still manually settingthis.state
also. This is to ensure you will get language intelligence/auto-completion for your states and for the current state in your editor if it uses the TypeScript language server.
state.is(state.states.UNKNOWN) // true
state.set(state.states.OK)
state.is(state.states.OK) // true
state.state // {}
state.state === state.states.OK // true
state.is(state.states.OK) // (same as above)
state.set(state.states.NOT_OK, { error: 'This is just not ok.' })
state.states.NOT_OK.error // 'This is just not ok.'
state.state.error // (same as above)
The states object you get back from myStateInstance.states
is actually a proxy that guards you against making the following mistakes (by throwing an error):
- Attempt to access a non-existent state (throws
TypeError
). - Attempt to directly create a state or directly set the context of a state after initialisation (throws
Error
). Use theset()
method, instead, for both these actions.
Similarly, trying to set the states
object once it has already been set will throw an error.
See Domain.
npm run test
npm run coverage
Small Technology Foundation is a tiny, independent not-for-profit.
We exist in part thanks to patronage by people like you. If you share our vision and want to support our work, please become a patron or donate to us today and help us continue to exist.
© 2021-present Aral Balkan, Small Technology Foundation.