-
Notifications
You must be signed in to change notification settings - Fork 12
refactor(services): demo network as observable #1814
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: dev
Are you sure you want to change the base?
Conversation
| network$ = store$.pipe( | ||
| map(state => selectCurrentNetwork(state)), | ||
| distinctUntilChanged() | ||
| ); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Network, which comes from Redux store, injected as Observable to service. No coupling to Redux, could come from any source.
| from( | ||
| Promise.all([ | ||
| this.stacksTransactionsService.getPendingTransactions(address, signal), | ||
| this.marketDataService.getMarketData(stxAsset, signal), | ||
| ]) | ||
| ), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Wraps Promises as Observable
| return res.data; | ||
| }; | ||
|
|
||
| return this.settings.network$.pipe( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If network$ emits change event, then refetch
| export function useObservable<T>(observable: Observable<T>): T { | ||
| const store = useMemo(() => { | ||
| let currentValue: T; | ||
| const subscribe = (onChange: (value: any) => void) => { | ||
| const sub = observable.subscribe(value => { | ||
| currentValue = value; | ||
| onChange(value); | ||
| }); | ||
| return () => sub.unsubscribe(); | ||
| }; | ||
| const getSnapshot = () => currentValue; | ||
| return { subscribe, getSnapshot }; | ||
| }, [observable]); | ||
|
|
||
| return useSyncExternalStore(store.subscribe, store.getSnapshot); | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
To greatest extent possible, I'd want to avoid exposing the concept of Observables to the react app, interfacing only with hooks.
If services expose Observables, however, we would need some way to bind to them. Hence this hook.
This is the hard part imo, and where there is biggest scope for errors/bugs from stale closures etc.
d8a794f to
641a48c
Compare
|
This looks like a good thing for us to try although complicated and there is a learning curve with RxJS. Perhaps it's something to come after finalisation of the We are at a junction now where we need to delegate service data manipulation somewhere and using observables could help us with that goal, especially if it helps us move towards websockets. I just wonder is it a bit complex to do immediately now based on our goals. It could be a good idea to just do it and get it over with |
641a48c to
69b0106
Compare
|
Leather Web Build 69b0106 → https://pr-1814-leather-web.wallet-6d1.workers.dev |
|
Leather Extension build 69b0106 — Extension build, Test report, Storybook, Chromatic |
Making this PR as a demo of conversation earlier with @alexp3y @edgarkhanzadian.
This demos how a push-based approach could work.
network$is a stream of events that updates. Consumers listen for changes, removing need to list deps array in useQuery to tell it to refetch.This could equally be built with web standard
EventEmitters, but it lacks the tooling to easily compose together multiple streams, as comes with Rxjs (an implementation of a soon-to-be web standard)