// 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 type { Has, Tag } from "../Has/index.js" import { mergeEnvironments } from "../Has/index.js" import type { UnionToIntersection } from "../Utils/index.js" import * as X from "./core.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 }) => X.Sync ) => X.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) ) } export const accessServicesTM = []>(...s: SS) => ( f: ( ...a: { [k in keyof SS]: [SS[k]] extends [Tag] ? T : unknown } ) => X.Sync ) => X.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)) ) export function accessServicesT[]>(...s: SS) { return ( f: ( ...a: { [k in keyof SS]: [SS[k]] extends [Tag] ? T : unknown } ) => B ) => X.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)) ) } /** * 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 ) => X.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) ) } /** * Access a service with the required Service Entry */ export function accessServiceM(s: Tag) { return (f: (a: T) => X.Sync) => X.accessM((r: Has) => f(r[s.key as any])) } /** * Access a service with the required Service Entry */ export function accessService(s: Tag) { return (f: (a: T) => B) => accessServiceM(s)((a) => X.succeed(f(a))) } /** * Access a service with the required Service Entry */ export function service(s: Tag) { return accessServiceM(s)((a) => X.succeed(a)) } /** * Provides the service with the required Service Entry */ export function provideServiceM(_: Tag) { return (f: X.Sync) => (ma: X.Sync, E1, A1>): X.Sync => X.accessM((r: R & R1) => X.chain_(f, (t) => X.provideAll_(ma, mergeEnvironments(_, r, t))) ) } /** * Provides the service with the required Service Entry */ export function provideService(_: Tag) { return (f: T) => (ma: X.Sync, E1, A1>): X.Sync => provideServiceM(_)(X.succeed(f))(ma) } /** * Replaces the service with the required Service Entry */ export function replaceServiceM(_: Tag, f: (_: T) => X.Sync) { return ( ma: X.Sync, E1, A1> ): X.Sync, E | E1, A1> => accessServiceM(_)((t) => provideServiceM(_)(f(t))(ma)) } /** * Replaces the service with the required Service Entry */ export function replaceServiceM_( ma: X.Sync, E1, A1>, _: Tag, f: (_: T) => X.Sync ): X.Sync, E | E1, A1> { return accessServiceM(_)((t) => provideServiceM(_)(f(t))(ma)) } /** * Replaces the service with the required Service Entry */ export function replaceService(_: Tag, f: (_: T) => T) { return (ma: X.Sync, E1, A1>): X.Sync, E1, A1> => accessServiceM(_)((t) => provideServiceM(_)(X.succeed(f(t)))(ma)) } /** * Replaces the service with the required Service Entry */ export function replaceService_( ma: X.Sync, E1, A1>, _: Tag, f: (_: T) => T ): X.Sync, E1, A1> { return accessServiceM(_)((t) => provideServiceM(_)(X.succeed(f(t)))(ma)) }