···1616 subscribe,
1717} from 'wonka';
18181919+import { useClient } from '../context';
2020+1921export const useSource = <T>(source: Source<T>, init: T): T =>
2022 useSubscription(
2123 useMemo((): Subscription<T> => {
2224 let hasUpdate = false;
2325 let currentValue: T = init;
24262727+ // Wrap the source and track its `currentValue`
2528 const updateValue = pipe(
2629 source,
2730 onPush(value => {
···3033 );
31343235 return {
3636+ // getCurrentValue may be implemented by subscribing to the
3737+ // given source and immediately unsubscribing. Only synchronous
3838+ // values will therefore reach our `onPush` callback.
3339 getCurrentValue(): T {
3440 if (!hasUpdate) publish(updateValue).unsubscribe();
3541 return currentValue;
3642 },
4343+ // subscribe is just a regular subscription, but it also tracks
4444+ // `hasUpdate`. If we're subscribed and receive a new value we
4545+ // set `hasUpdate` to avoid `getCurrentValue` trying to subscribe
4646+ // again.
3747 subscribe(onValue: () => void): Unsubscribe {
3848 hasUpdate = true;
3949 const { unsubscribe } = pipe(updateValue, subscribe(onValue));
···4757 );
48584959export const useBehaviourSubject = <T>(value: T) => {
6060+ const client = useClient();
6161+5062 const state = useMemo((): [Source<T>, (value: T) => void] => {
5163 let prevValue = value;
5264···5668 map(() => prevValue)
5769 );
58707171+ // This turns the subject into a behaviour subject that returns
7272+ // the last known value (or the initial value) synchronously
5973 const source = concat([prevValue$, subject.source]);
60746175 const next = (value: T) => {
6262- subject.next((prevValue = value));
7676+ // We can use the latest known value to also deduplicate next calls.
7777+ if (value !== prevValue) {
7878+ subject.next((prevValue = value));
7979+ }
6380 };
64816582 return [source, next];
6683 }, []);
67848585+ // NOTE: This is a special case for client-side suspense.
8686+ // We can't trigger suspense inside an effect but only in the render function.
8787+ // So we "deopt" to not using an effect if the client is in suspense-mode.
6888 useEffect(() => {
6969- state[1](value);
8989+ if (!client.suspense) state[1](value);
7090 }, [state, value]);
9191+9292+ if (client.suspense) state[1](value);
71937294 return state;
7395};