-
Notifications
You must be signed in to change notification settings - Fork 0
Loading State
Ivan Kasenkov edited this page Aug 31, 2021
·
3 revisions
ksLoading.ts
import {
Option,
Stream,
Transformer,
ksConcat,
ksMap,
ksOf,
ksScan,
ksSwitch,
none,
some,
} from '@keiii/k-stream';
export type LoadingState<T> = {
loading: boolean;
response: Option<T>;
};
const initialState: LoadingState<never> = {
loading: false,
response: none,
};
const patch = <A>(
currentState: LoadingState<A>,
patchState: Partial<LoadingState<A>>,
): LoadingState<A> => {
return {
...currentState,
...patchState,
};
};
const loadingTrue = ksOf({ loading: true } as const);
const loadedResponse = <A>(b: A): LoadingState<A> => {
return {
loading: false,
response: some(b),
};
};
/**
* Transform a stream of requests into a stream of a state with loading indicator.
*/
export const ksLoading = <A, B>(
project: (a: A) => Stream<B>,
): Transformer<A, LoadingState<B>> => {
return stream => {
return stream
.pipe(
ksSwitch(a => {
return ksConcat(
loadingTrue, // set the loading indicator as "true" before loading
project(a).pipe(ksMap(loadedResponse)), // and concatenate with response
);
}),
)
.pipe(
ksScan<Partial<LoadingState<B>>, LoadingState<B>>(patch, initialState),
);
};
};