Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Conversation

@kyranjamie
Copy link
Collaborator

@kyranjamie kyranjamie commented Nov 17, 2025

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)

Comment on lines +11 to +14
network$ = store$.pipe(
map(state => selectCurrentNetwork(state)),
distinctUntilChanged()
);
Copy link
Collaborator Author

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.

Comment on lines 125 to 130
from(
Promise.all([
this.stacksTransactionsService.getPendingTransactions(address, signal),
this.marketDataService.getMarketData(stxAsset, signal),
])
),
Copy link
Collaborator Author

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(
Copy link
Collaborator Author

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

Comment on lines +32 to +47
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);
}
Copy link
Collaborator Author

@kyranjamie kyranjamie Nov 17, 2025

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.

@kyranjamie kyranjamie force-pushed the experimental/observable-stx-balance branch 4 times, most recently from d8a794f to 641a48c Compare November 18, 2025 08:56
@pete-watters
Copy link
Contributor

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 state package?

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

@kyranjamie kyranjamie force-pushed the experimental/observable-stx-balance branch from 641a48c to 69b0106 Compare November 26, 2025 13:42
@leather-bot
Copy link
Contributor

leather-bot commented Nov 26, 2025

Leather Web Build 69b0106https://pr-1814-leather-web.wallet-6d1.workers.dev

@leather-bot
Copy link
Contributor

leather-bot commented Nov 26, 2025

Leather Extension build 69b0106Extension build, Test report, Storybook, Chromatic

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants