re-rxjs / react-rxjs

React bindings for RxJS
https://react-rxjs.org
MIT License
553 stars 20 forks source link

PoC: resource-based subscriptions #106

Closed voliva closed 4 years ago

voliva commented 4 years ago

Following some internal discussion we've been having, I'd like to raise this proposal which uses a resource-based approach, following the line of react's docs for concurrent patterns.

The idea is that we let the consumer decide when they want to subscribe and unsubscribe from a stream, and use that subscription to read values from it.

Something worth noting is that this can be achieved in a separate package, that uses the streams created by bind, so it could be considered as a potential framework on top of react-rxjs.

It's a PoC - it passes all the tests from connectObservable except for the ones that deal with subscriptions/unsubscriptions (they don't apply). We need to think if this makes sense in the "core" library, try for factory observables and think of more edge cases.

josepot commented 4 years ago

I like the idea of having a "secondary" package with this API. Although, I think that @react-rxjs/resource would be to @react-rxjs what react-router-config is to react-router. Meaning that this is not the API that we would want to promote, because its a lot less ergonomic and reactive. However, it does have its use-cases and it would be a very valuable addition.

A couple of thoughts about this, though:

We should probably create a @react-rxjs/internals package from where we would expose things like: SUSPENSE, the internal shareLatest, defaultStart and others (the nested dict, etc). That package would purposely not adhere to semver, as its only meant for exposing some implementation details for our packages. That would allow for @react-rxjs/resource not to have any sort of dependency on @react-rxjs/core, which would enable a better API that's also more consistent with core. For instance, instead of this:

import { bind } from "@react-rxjs/core"
import { createSubscription } from "@react-rxjs/resource"

const [, shareObservable$] = bind(someColdObservable$.pipe(startWith(0)))
const sub = createSubscription(shareObservable$)

we would be able to do this:

import { createSubscription } from "@react-rxjs/resource"

const [sub, shareObservable$] = createSubscription(someColdObservable$.pipe(startWith(0));
voliva commented 4 years ago

Agreed - It's a path we might want to explore, but for now we will focus in the current release and research this later on.