developit / developit/unistore

selective subscribe and state await

Open
#19 3 comments 2 reactions 0 assignees View on GitHub
enhancement question
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.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.