export const LayerTypeId = Symbol.for("@effect/core/Layer") export type LayerTypeId = typeof LayerTypeId export const _RIn = Symbol.for("@effect/core/Layer/RIn") export type _RIn = typeof _RIn export const _E = Symbol.for("@effect/core/Layer/E") export type _E = typeof _E export const _ROut = Symbol.for("@effect/core/Layer/ROut") export type _ROut = typeof _ROut /** * A `Layer` describes how to build one or more services in your * application. Services can be injected into effects via `Effect.provide`. * Effects can require services via `Effect.service`. * * Layer can be thought of as recipes for producing bundles of services, given * their dependencies (other services). * * Construction of services can be effectful and utilize resources that must be * acquired and safely released when the services are done being utilized. * * By default layers are shared, meaning that if the same layer is used twice * the layer will only be allocated a single time. * * Because of their excellent composition properties, layers are the idiomatic * way in Effect-TS to create services that depend on other services. * * @tsplus type effect/core/io/Layer */ export interface Layer { readonly [_RIn]: () => RIn readonly [_E]: () => E readonly [_ROut]: (_: ROut) => void readonly [LayerTypeId]: LayerTypeId } /** * @tsplus type effect/core/io/Layer.Ops */ export interface LayerOps { $: LayerAspects } export const Layer: LayerOps = { $: {} } /** * @tsplus unify effect/core/io/Layer */ export function unifyLayer>( self: X ): Layer< [X] extends [{ [_RIn]: () => infer RIn }] ? RIn : never, [X] extends [{ [_E]: () => infer E }] ? E : never, [X] extends [{ [_ROut]: (_: infer ROut) => void }] ? ROut : never > { return self } /** * @tsplus type effect/core/io/Layer.Aspects */ export interface LayerAspects {} export abstract class LayerAbstract implements Layer { readonly [_RIn]!: () => RIn readonly [_E]!: () => E readonly [_ROut]!: () => ROut readonly [LayerTypeId]: LayerTypeId = LayerTypeId } export type Instruction = | ILayerApply | ILayerExtendScope | ILayerFold | ILayerFresh | ILayerScoped | ILayerSuspend | ILayerTo | ILayerZipWithPar export class ILayerApply implements Layer { readonly _tag = "LayerApply" readonly [_RIn]!: () => RIn readonly [_E]!: () => E readonly [_ROut]!: () => ROut readonly [LayerTypeId]: LayerTypeId = LayerTypeId constructor(readonly self: Effect>) {} } export class ILayerExtendScope implements Layer { readonly _tag = "LayerExtendScope" readonly [_RIn]!: () => RIn | Scope readonly [_E]!: () => E readonly [_ROut]!: () => ROut readonly [LayerTypeId]: LayerTypeId = LayerTypeId constructor(readonly self: Layer) {} } export class ILayerFold implements Layer { readonly _tag = "LayerFold" readonly [_RIn]!: () => RIn | RIn2 | RIn3 readonly [_E]!: () => E2 | E3 readonly [_ROut]!: () => ROut2 | ROut3 readonly [LayerTypeId]: LayerTypeId = LayerTypeId constructor( readonly self: Layer, readonly failure: (cause: Cause) => Layer, readonly success: (r: Env) => Layer ) {} } export class ILayerFresh implements Layer { readonly _tag = "LayerFresh" readonly [_RIn]!: () => RIn readonly [_E]!: () => E readonly [_ROut]!: () => ROut readonly [LayerTypeId]: LayerTypeId = LayerTypeId constructor(readonly self: Layer) {} } export class ILayerScoped extends LayerAbstract, E, ROut> { readonly _tag = "LayerScoped" constructor(readonly self: Effect>) { super() } } export class ILayerSuspend implements Layer { readonly _tag = "LayerSuspend" readonly [_RIn]!: () => RIn readonly [_E]!: () => E readonly [_ROut]!: () => ROut readonly [LayerTypeId]: LayerTypeId = LayerTypeId constructor(readonly self: () => Layer) {} } export class ILayerTo implements Layer { readonly _tag = "LayerTo" readonly [_RIn]!: () => RIn readonly [_E]!: () => E | E1 readonly [_ROut]!: () => ROut1 readonly [LayerTypeId]: LayerTypeId = LayerTypeId constructor( readonly self: Layer, readonly that: Layer ) {} } export class ILayerZipWithPar< RIn, E, ROut, RIn1, E1, ROut2, ROut3 > implements Layer { readonly _tag = "LayerZipWithPar" readonly [_RIn]!: () => RIn | RIn1 readonly [_E]!: () => E | E1 readonly [_ROut]!: () => ROut3 readonly [LayerTypeId]: LayerTypeId = LayerTypeId constructor( readonly self: Layer, readonly that: Layer, readonly f: (s: Env, t: Env) => Env ) {} } /** * @tsplus macro identity */ export function instruction(self: Layer): Instruction { // @ts-expect-error return self }