// ets_tracing: off /** * Copyright 2020 Michael Arnaldi and the Matechs Garage Contributors. */ import * as A from "../Collections/Immutable/Array/index.js" import * as R from "../Collections/Immutable/Dictionary/index.js" import * as core from "../Effect/core.js" import type { Effect } from "../Effect/effect.js" import type { Has, Tag } from "../Has/index.js" import { mergeEnvironments } from "../Has/index.js" import { accessCallTrace } from "../Tracing/index.js" import type { UnionToIntersection } from "../Utils/index.js" /** * Access a record of services with the required Service Entries */ export function accessServicesM>>(s: SS) { return ( f: (a: { [k in keyof SS]: [SS[k]] extends [Tag] ? T : unknown }) => Effect, __trace?: string ) => core.accessM( ( r: UnionToIntersection< { [k in keyof SS]: [SS[k]] extends [Tag] ? Has : unknown }[keyof SS] > ) => f(R.map_(s, (v) => r[v.key]) as any), __trace ) } /** * Access a tuple of services with the required Service Entries monadically */ export function accessServicesTM[]>(...s: SS) { return ( f: ( ...a: { [k in keyof SS]: [SS[k]] extends [Tag] ? T : unknown } ) => Effect, __trace?: string ) => core.accessM( ( r: UnionToIntersection< { [k in keyof SS]: [SS[k]] extends [Tag] ? Has : never }[keyof SS & number] > ) => f(...(A.map_(s, (v) => r[v.key]) as any)), __trace ) } /** * Access a tuple of services with the required Service Entries */ export function accessServicesT[]>(...s: SS) { return ( f: ( ...a: { [k in keyof SS]: [SS[k]] extends [Tag] ? T : unknown } ) => B, __trace?: string ) => core.access( ( r: UnionToIntersection< { [k in keyof SS]: [SS[k]] extends [Tag] ? Has : never }[keyof SS & number] > ) => f(...(A.map_(s, (v) => r[v.key]) as any)), __trace ) } /** * Access a record of services with the required Service Entries */ export function accessServices>>(s: SS) { return ( f: (a: { [k in keyof SS]: [SS[k]] extends [Tag] ? T : unknown }) => B, __trace?: string ) => core.access( ( r: UnionToIntersection< { [k in keyof SS]: [SS[k]] extends [Tag] ? Has : unknown }[keyof SS] > ) => f(R.map_(s, (v) => r[v.key]) as any), __trace ) } /** * Access a service with the required Service Entry */ export function accessServiceM(s: Tag) { return (f: (a: T) => Effect, __trace?: string) => core.accessM((r: Has) => f(r[s.key as any]), __trace) } /** * Access a service with the required Service Entry */ export function accessService(s: Tag) { return (f: (a: T) => B, __trace?: string) => accessServiceM(s)((a) => core.succeed(f(a)), __trace) } /** * Accesses the specified service in the environment of the effect. */ export function service(s: Tag, __trace?: string) { return accessServiceM(s)(core.succeed, __trace) } /** * Accesses the specified services in the environment of the effect. * * @ets_trace call */ export function services[]>(...s: Ts) { return core.access( ( r: UnionToIntersection< { [k in keyof Ts]: [Ts[k]] extends [Tag] ? Has : never }[number] > ): Readonly<{ [k in keyof Ts]: [Ts[k]] extends [Tag] ? T : never }> => s.map((tag) => tag.read(r as any)) as any, accessCallTrace() ) } /** * Provides the service with the required Service Entry */ export function provideServiceM(_: Tag) { return (service: Effect, __trace?: string) => (ma: Effect, E1, A1>): Effect => core.accessM((r: R & R1) => core.chain_(service, (t) => core.provideAll_(ma, mergeEnvironments(_, r, t), __trace) ) ) } /** * Provides the service with the required Service Entry */ export function provideServiceM_( ma: Effect, E1, A1>, _: Tag, service: Effect, __trace?: string ): Effect { return core.accessM((r: R & R1) => core.chain_(service, (t) => core.provideAll_(ma, mergeEnvironments(_, r, t), __trace) ) ) } /** * Provides the service with the required Service Entry */ export function provideService(_: Tag) { return (service: T, __trace?: string) => (ma: Effect, E1, A1>): Effect => provideServiceM(_)(core.succeed(service), __trace)(ma) } /** * Provides the service with the required Service Entry */ export function provideService_( ma: Effect, E1, A1>, _: Tag, service: T, __trace?: string ): Effect { return provideServiceM(_)(core.succeed(service), __trace)(ma) } /** * Replaces the service with the required Service Entry */ export function replaceServiceM( _: Tag, f: (_: T) => Effect, __trace?: string ) { return ( ma: Effect, E1, A1> ): Effect, E | E1, A1> => accessServiceM(_)((t) => provideServiceM(_)(f(t), __trace)(ma)) } /** * Replaces the service with the required Service Entry */ export function replaceServiceM_( ma: Effect, E1, A1>, _: Tag, f: (_: T) => Effect, __trace?: string ): Effect, E | E1, A1> { return accessServiceM(_)((t) => provideServiceM(_)(f(t), __trace)(ma)) } /** * Replaces the service with the required Service Entry * * @ets_data_first replaceService_ */ export function replaceService(_: Tag, f: (_: T) => T, __trace?: string) { return (ma: Effect, E1, A1>): Effect, E1, A1> => replaceService_(ma, _, f, __trace) } /** * Replaces the service with the required Service Entry */ export function replaceService_( ma: Effect, E1, A1>, _: Tag, f: (_: T) => T, __trace?: string ): Effect, E1, A1> { return accessServiceM(_)((t) => provideServiceM(_)( core.succeedWith(() => f(t)), __trace )(ma) ) }