CANT inc. state management system.
This is a fast, tiny and smart state management system. Based on simplest principles: you have a state and you can watch for the state changes. Was born during working on innet.
watch-state inspired by async-await pattern, you can image it like this:
state count = 0
watch {
console.log(count)
}
Firefox | Chrome | Safari | Opera | Edge |
---|---|---|---|---|
45+ | 49+ | 9+ | 36+ | 13+ |
Firefox | Chrome | Safari | Opera |
---|---|---|---|
87+ | 90+ | 9+ | 62+ |
You can transpile it supporting old browsers, but the performance decreases.
npm
npm i watch-state
yarn
yarn add watch-state
Use watchState
to get any class from the library.
const {
Watch,
State,
Cache,
} = watchState
You can create an instance of State
and watch its value.
import { Watch, State } from 'watch-state'
const count = new State(0)
new Watch(() => console.log(count.value))
// console.log(0)
count.value++
// console.log(1)
count.value++
// console.log(2)
You can check if the watching ran first by update
argument.
const count = new State(0)
new Watch(update => {
console.log(update, count.value)
})
// console.log(false, 0)
count.value++
// console.log(true, 1)
count.value++
// console.log(true, 2)
As example, you can watch a state once
const count = new State(0)
new Watch(update => {
if (!update) {
// Watch this value
count.value
} else {
// React on changes
console.log('The value was changed')
}
})
count.value++
// console.log('The value was changed')
count.value++
// nothing happenes
You can run watchers of a state with update
method.
const count = new State(0)
new Watch(() => {
console.log(count.value)
})
// console.log(0)
count.update()
// console.log(0)
You can run a watcher even when it's states are not updated.
const count = new State(0)
const watcher = new Watch(() => {
console.log(count.value)
})
// console.log(0)
watcher.update()
// console.log(0)
You can stop watching by destroy
method of Watch
.
const count = new State(0)
const watcher = new Watch(() => {
console.log(count.value)
})
// console.log(0)
count.value++
// console.log(1)
watcher.destroy()
count.value++
// nothing happens
You can subscribe on destroy or update of watcher
const count = new State(0)
const watcher = new Watch(() => {
console.log('count', count.value)
// the order does not matter
onDestroy(() => console.log('destructor'))
})
// console.log('count', 0)
count.value++
// console.log('destructor')
// console.log('count', 1)
watcher.destroy()
// console.log('destructor')
watcher.destroy()
count.value++
// nothing happens
You can use Watch
inside a watcher.
Each watcher reacts on that states which used only inside it.
const watching = new State(true)
const state = new State(0)
let test = 0
new Watch(() => {
test++
if (watching.value) {
new Watch(() => {
console.log(state.value)
})
}
})
// console.log(0), test = 1
state.value++
// console.log(1), test = 1
watching.value = false
// test = 2
state.value++
// nothing happens
You can cache computed state.
The watcher will not be triggered while new result is the same.
const name = new State('Foo')
const surname = new State('Bar')
const fullName = new Cache(() => (
`${name.value} ${surname.value[0]}`
))
new Watch(() => {
console.log(fullName.value)
})
// console.log('Foo B')
surname.value = 'Baz'
// nothing happens
surname.value = 'Quux'
// console.log('Foo Q')
You can force update the cache by update
method.
fullName.update()
// console.log('Foo Q')
Cache will be immediately updated only if a watcher looks after the cache.
You can use destroy
and onDestroy
like you do it on a watcher.
fullName.destroy()
The computing will be triggered only when a state inside the cache will be changed. So you can modify data only when it's needed.
const list = new State(['foo', 'bar', 'baz'])
const sortedList = new Cache(() => {
console.log('computing')
return [...list.value].sort()
})
// nothing happens
const value = sortedList.value
// console.log('computing')
console.log(sortedList.value)
// console.log(['bar', 'baz', 'foo'])
console.log(value === sortedList.value)
// console.log(true)
list.value = ['b', 'c', 'a']
// nothing happens
console.log(sortedList.value)
// console.log('computing')
// console.log(['a', 'b', 'c'])
You can create event function with createEvent
import { State, createEvent } from 'watch-state'
const count = new State(0)
const increase = createEvent(() => {
console.log(count.value++)
})
new Watch(() => console.log(count.value))
// console.log(0)
increase()
// console.log(1)
increase()
// console.log(2)
Generic of State
const key = new State<string | number>()
key.value = false
// error, you can use only string or number
Generic of Cache
new Cache<string>(() => false)
// error, target of cache should return string
You can check a performance test with MobX, Effector, Storeon, Mazzard and Redux. Clone the repo, install packages and run this command
npm run speed
You can find more tools here
If you find a bug or have a suggestion, please file an issue on GitHub