/** * RefAdapter is an abstraction over [Ref](./Ref.ts.md) and [Adapter](./Adapter.ts.md) * @since 0.11.0 */ import { identity } from 'fp-ts/function' import { Functor4 } from 'fp-ts/Functor' import { Profunctor4 } from 'fp-ts/Profunctor' import { fst, snd } from 'fp-ts/Tuple2' import * as A from './Adapter' import * as E from './Env' import { pipe } from './function' import * as RS from './ReaderStream' import * as Ref from './Ref' /** * RefAdapter is an abstraction of Refs that will output an Adapter to send and receive events through. * It utilizes the output of its Ref instead of the input so you will not find any combinators for * updating the Adapter in-place. This allows for creating a Functor + Profunctor instances * @since 0.11.0 * @category Model */ export interface RefAdapter extends Ref.Ref> {} /** * @since 0.12.0 * @category Combinator */ export function sendEvent(event: A) { return (ra: RefAdapter): E.Env => pipe( ra.get, E.chainIOK( ([send]) => () => send(event), ), ) } /** * @since 0.11.0 * @category Combinator */ export function getSendEvent(ra: RefAdapter): E.Env void> { return pipe(ra.get, E.map(fst)) } /** * @since 0.11.0 * @category Combinator */ export function getEvents(ra: RefAdapter): RS.ReaderStream { return pipe(ra.get, E.map(snd), RS.fromEnv, RS.chainStreamK(identity)) } /** * @since 0.12.0 * @category Combinator */ export function listenToEvents(f: (value: A) => E.Env) { return (ra: RefAdapter): RS.ReaderStream => pipe(ra, getEvents, RS.chainEnvK(f)) } /** * @since 0.11.0 * @category Combinator */ export function map(f: (value: A) => B) { return (ra: RefAdapter): RefAdapter => pipe(ra, Ref.map(A.map(f))) } /** * @since 0.11.0 * @category Combinator */ export function local(f: (value: A) => B) { return (ra: RefAdapter): RefAdapter => pipe(ra, Ref.map(A.local(f))) } /** * @since 0.11.0 * @category Combinator */ export const promap = (f: (value: B) => A, g: (value: C) => D) => (adapter: RefAdapter): RefAdapter => pipe(adapter, local(f), map(g)) /** * @since 0.11.0 * @category URI */ export const URI = '@typed/fp/RefAdapter' /** * @since 0.11.0 * @category URI */ export type URI = typeof URI declare module 'fp-ts/HKT' { export interface URItoKind4 { [URI]: RefAdapter } } declare module './HKT' { export interface URItoVariance { [URI]: V & V } } /** * @since 0.11.0 * @category Instance */ export const Functor: Functor4 = { map, } /** * @since 0.11.0 * @category Instance */ export const Profunctor: Profunctor4 = { map, promap, } /** * @since 0.13.5 * @category Instance */ export function wrap(ra: RefAdapter) { return { ...ra, sendEvent: (event: A) => pipe(ra, sendEvent(event)), getSendEvent: getSendEvent(ra), events: getEvents(ra), listenToEvents: (f: (value: B) => E.Env) => pipe(ra, listenToEvents(f)), } as const }