mutoid
Version:
Reactive library for data fetching, caching, state management
130 lines (129 loc) • 4.79 kB
JavaScript
import { chainFirst as chainFirst_ } from 'fp-ts/Chain';
import * as R from 'fp-ts/Reader';
import { flow, identity, pipe } from 'fp-ts/function';
import * as RXoP from 'rxjs/operators';
import * as OR from './ObservableResource';
// -------------------------------------------------------------------------------------
// constructors
// -------------------------------------------------------------------------------------
export const fromObservableResource = R.of;
export const init = () => OR.init;
export const submitted = () => OR.submitted;
export const done = flow(OR.done, fromObservableResource);
export const doneObservable = flow(OR.doneObservable, fromObservableResource);
export const fail = flow(OR.fail, fromObservableResource);
export const failObservable = flow(OR.failObservable, fromObservableResource);
export const ask = () => OR.done;
export const askTypeOf = () => OR.done;
export const asks = f => flow(OR.done, OR.map(f));
export const fromReader = ma => flow(ma, OR.done);
export const fromTask = ma => () => OR.fromTask(ma);
export const fromReaderTaskEither = rte => flow(rte, OR.fromTaskEither);
export const fromObservable = ma => () => OR.doneObservable(ma);
export const fromReaderObservableEither = (e) => flow(e, OR.fromObservableEither);
export const fromIO = ma => () => OR.doneIO(ma);
export const fromAjax = flow(OR.fromAjax, fromObservableResource);
export const of = done;
// -------------------------------------------------------------------------------------
// destructors
// -------------------------------------------------------------------------------------
export const toMutation = (mapTo) => (ros) => flow(ros, c => c.pipe(RXoP.map(mapTo)));
export const fetchToMutationEffectR = (mapTo) => (rork) => (r) => (...i) => pipe(rork(...i)(r), o => (s) => o.pipe(RXoP.map(mapTo(s))));
// -------------------------------------------------------------------------------------
// instances
// -------------------------------------------------------------------------------------
/* istanbul ignore next */
const _map = (fa, f) => pipe(fa, map(f));
/* istanbul ignore next */
const _ap = (fab, fa) => pipe(fab, ap(fa));
/* istanbul ignore next */
const _chain = (ma, f) => pipe(ma, chain(f));
/* istanbul ignore next */
const _bimap = (fea, f, g) => pipe(fea, bimap(f, g));
/* istanbul ignore next */
const _mapLeft = (fea, f) => pipe(fea, mapLeft(f));
export const URI = 'ReaderObservableResource';
export const Functor = {
URI,
map: _map,
};
export const Apply = {
URI,
map: _map,
ap: _ap,
};
export const Applicative = {
URI,
map: _map,
ap: _ap,
of,
};
export const Chain = {
URI,
map: _map,
ap: _ap,
chain: _chain,
};
export const Monad = {
URI,
map: _map,
ap: _ap,
of,
chain: _chain,
};
export const Bifunctor = {
URI,
bimap: _bimap,
mapLeft: _mapLeft,
};
export const MonadTask = {
URI,
map: _map,
of,
ap: _ap,
chain: _chain,
fromIO,
fromTask,
};
export const MonadObservable = {
URI,
map: _map,
of,
ap: _ap,
chain: _chain,
fromIO,
fromObservable,
fromTask,
};
// -------------------------------------------------------------------------------------
// type class members
// -------------------------------------------------------------------------------------
export const map = f => fa => flow(fa, OR.map(f));
export const bimap = (f, g) => fea => r => OR.bimap(f, g)(fea(r));
export const mapLeft = f => fea => r => OR.mapLeft(f)(fea(r));
export const ap = fa => fab => r => pipe(fab(r), OR.ap(fa(r)));
export const chainW = (f) => (ma) => r => pipe(ma(r), OR.chainW(a => f(a)(r)));
export const chain = chainW;
export const flatten = chain(identity);
// -------------------------------------------------------------------------------------
// combinators
// -------------------------------------------------------------------------------------
export const local = R.local;
export function swap(ma) {
return flow(ma, OR.swap);
}
export const chainFirst = chainFirst_(Chain);
export const chainFirstW = chainFirst;
export function orElseW(onLeft) {
return ma => r => OR.orElseW(e => onLeft(e)(r))(ma(r));
}
export const orElse = orElseW;
export const filterOrElseW = (predicate, onFalse) => chainW(a => (predicate(a) ? done(a) : fail(onFalse(a))));
export const filterOrElse = filterOrElseW;
// -------------------------------------------------------------------------------------
// utils
// -------------------------------------------------------------------------------------
export const Do = of({});
export const bindTo = (name) => map(a => ({ [name]: a }));
export const bind = (name, f) => chain(a => pipe(f(a), map(b => ({ ...a, [name]: b }))));
export const bindW = bind;