developit / developit/unistore
selective subscribe and state await
- Dominant language
- JavaScript
- Stars
- 2.8k
- Forks
- 134
- PR merge metrics
- No merged PRs in 30d
Description
I would like to suggest adding these. They are very common use cases and for each and every redux-like lib i use i usually end up having to write it again. But these aren't edge-cases. To get a ping when a certain slice of state changes is something one would use all the time. Basically, if `connect` can do it, why can't the user?
The other use case would be being able to await state without having to collect and manage unsubscribes.
```js
function subscribe(selector, callback) {
let state = selector(store.getState())
return store.subscribe(() => {
let selected = selector(store.getState()),
old = state
if (typeof selected === 'object' && !Array.isArray(selected)) {
selected = Object.entries(selected).reduce(
(acc, [key, value]) =>
(state[key] !== value ? { ...acc, [key]: value } : acc),
state,
)
}
if (state !== selected) callback((state = selected), old)
})
}
function awaitState(selector, condition) {
return new Promise(resolve => {
const unsub = subscribe(selector, props => {
const result = condition(props)
if (result) unsub() || resolve(result)
})
})
}
// Example #1: await a truthy slice of state
const worker = await awaitState(state =>
state.collections.workers, workers => workers.find(ID))
// Example #2: responding to state changes
const unsub = subscribe(state =>
state.workers[ID].alive, () => console.log("state changed"))
// Example #3: responding to mapped state changes
const unsub = subscribe(state =>
({ alive: state.workers[ID].alive, running: state.globals.running }),
({ alive, running }) => console.log(alive, running)
)
```
Contributor guide
No contributing guide indexed for this repository
Assessment
This issue has not been assessed yet.