@small-tech/state
v3.0.2
Published
A tiny JavaScript state management class.
Downloads
8
Readme
@small-tech/state
A tiny (69 lines of code¹) JavaScript state management class.
¹ sans comments and empty lines
Install
npm i @small-tech/state
Usage
Basic usage
// @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.
State subclasses
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.
Check state
state.is(state.states.UNKNOWN) // true
Change state (without updating the context)
state.set(state.states.OK)
state.is(state.states.OK) // true
Get the current state
state.state // {}
state.state === state.states.OK // true
state.is(state.states.OK) // (same as above)
Change state (and update the context)
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)
Guards
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.
Real-world use
See Domain.
Tests
npm run test
Coverage
npm run coverage
Like this? Fund us!
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.
Copyright
© 2021-present Aral Balkan, Small Technology Foundation.