Closed Jopie64 closed 4 years ago
I'm not sure what the thrust of this issue is. The Svelte store contract is documented here https://svelte.dev/docs#Store_contract which also describes the interoperability with RxJS Observables.
@Jopie64 The "Reactive stores" RFC (#5) was resolved, and the store contract in Svelte v3 reflects the current state of things.
Hi,
Out of interest I read part of the Svelte RFC particulary about state management. There I read about objections of using TC39 observables as store. In this issue I hope I can nuance those objections a bit.
The most basic mode of observables is that they simply are a placeholder of a function (not state) which is called when you subscribe it. This makes them cold by default, yes. But you can simply make an instance of an observable that represents current state.
new BehaviorSubject('current state')
acts very much like thewritable
example. You can also make cold observables hot and let them act like having state by using theshareReplay(1)
operator.Not when they are hot (based on subject) Furthermore, this is up to the developer whether he wants it to act in this way. A dev using TC39 observables should know the difference between hot and cold observables. Actually, Observable is just a contract, which can behave like how a dev wants it to behave. They can behave exactly like stores in this RFC.
A completed observable simply doesn't emit new values. Svelte can ignore this concept. Also a dev can choose to never complete an observable. Also I don't understand what you mean by 'do not have concept of time'? State is usually something that changes over time. Completing simply means it doesn't change any longer...
When observables are used to represent current state (behavior), errors are (usually) redundant yes. Svelte can ignore that like 'completed'.
In that case, the observable is usually not used as a behavior in templates (directly), but more as an async task like promise that can return a stream of values. The nice thing is that in that case they can be converted to a behavior later because they have the same contract. Also because the different usages share the same contract, they share the same rich set of operators too.
As an example, the 'derived store' example could be rewritten using a single existing operator:
combineLatest
. A redux store can be rewritten like this:const store$ = action$.pipe(scan((state, action) => reduce(state, action))
Where action$ can be amerge()
of different action emitters.I like the idea that the different modes can be modelled the same, so code and ideas can be shared, and devs have to know less to be able to interact with more frameworks.