UNPKG

mutoid

Version:

Reactive library for data fetching, caching, state management

130 lines (129 loc) 4.79 kB
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;