/** * A `Layer` describes how to build one or more services in your * application. Services can be injected into effects via * `Effect.provideService`. 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. * * @since 2.0.0 */ import type * as Cause from "./Cause.js" import type * as Clock from "./Clock.js" import type { ConfigProvider } from "./ConfigProvider.js" import * as Context from "./Context.js" import type * as Effect from "./Effect.js" import type * as Exit from "./Exit.js" import type { FiberRef } from "./FiberRef.js" import { dual, type LazyArg } from "./Function.js" import { clockTag } from "./internal/clock.js" import * as core from "./internal/core.js" import * as defaultServices from "./internal/defaultServices.js" import * as fiberRuntime from "./internal/fiberRuntime.js" import * as internal from "./internal/layer.js" import * as circularLayer from "./internal/layer/circular.js" import * as query from "./internal/query.js" import { randomTag } from "./internal/random.js" import type { LogLevel } from "./LogLevel.js" import type * as Option from "./Option.js" import type { Pipeable } from "./Pipeable.js" import type * as Random from "./Random.js" import type * as Request from "./Request.js" import type * as Runtime from "./Runtime.js" import type * as Schedule from "./Schedule.js" import * as Scheduler from "./Scheduler.js" import type * as Scope from "./Scope.js" import type * as Stream from "./Stream.js" import type * as Tracer from "./Tracer.js" import type * as Types from "./Types.js" /** * @since 2.0.0 * @category symbols */ export const LayerTypeId: unique symbol = internal.LayerTypeId /** * @since 2.0.0 * @category symbols */ export type LayerTypeId = typeof LayerTypeId /** * @since 2.0.0 * @category models */ export interface Layer extends Layer.Variance, Pipeable {} /** * @since 2.0.0 */ export declare namespace Layer { /** * @since 2.0.0 * @category models */ export interface Variance { readonly [LayerTypeId]: { readonly _ROut: Types.Contravariant readonly _E: Types.Covariant readonly _RIn: Types.Covariant } } /** * @since 3.9.0 * @category type-level */ export interface Any { readonly [LayerTypeId]: { readonly _ROut: Types.Contravariant readonly _E: Types.Covariant readonly _RIn: Types.Covariant } } /** * @since 2.0.0 * @category type-level */ export type Context = [T] extends [Layer] ? _RIn : never /** * @since 2.0.0 * @category type-level */ export type Error = [T] extends [Layer] ? _E : never /** * @since 2.0.0 * @category type-level */ export type Success = [T] extends [Layer] ? _ROut : never } /** * @since 2.0.0 * @category symbols */ export const MemoMapTypeId: unique symbol = internal.MemoMapTypeId /** * @since 2.0.0 * @category symbols */ export type MemoMapTypeId = typeof MemoMapTypeId /** * @since 2.0.0 * @category models */ export interface MemoMap { readonly [MemoMapTypeId]: MemoMapTypeId /** @internal */ readonly getOrElseMemoize: ( layer: Layer, scope: Scope.Scope ) => Effect.Effect, E, RIn> } /** * @since 3.13.0 * @category models */ export interface CurrentMemoMap { readonly _: unique symbol } /** * @since 3.13.0 * @category models */ export const CurrentMemoMap: Context.Reference = internal.CurrentMemoMap /** * Returns `true` if the specified value is a `Layer`, `false` otherwise. * * @since 2.0.0 * @category getters */ export const isLayer: (u: unknown) => u is Layer = internal.isLayer /** * Returns `true` if the specified `Layer` is a fresh version that will not be * shared, `false` otherwise. * * @since 2.0.0 * @category getters */ export const isFresh: (self: Layer) => boolean = internal.isFresh /** * @since 3.3.0 * @category tracing */ export const annotateLogs: { /** * @since 3.3.0 * @category tracing */ (key: string, value: unknown): (self: Layer) => Layer /** * @since 3.3.0 * @category tracing */ (values: Record): (self: Layer) => Layer /** * @since 3.3.0 * @category tracing */ (self: Layer, key: string, value: unknown): Layer /** * @since 3.3.0 * @category tracing */ (self: Layer, values: Record): Layer } = internal.annotateLogs /** * @since 3.3.0 * @category tracing */ export const annotateSpans: { /** * @since 3.3.0 * @category tracing */ (key: string, value: unknown): (self: Layer) => Layer /** * @since 3.3.0 * @category tracing */ (values: Record): (self: Layer) => Layer /** * @since 3.3.0 * @category tracing */ (self: Layer, key: string, value: unknown): Layer /** * @since 3.3.0 * @category tracing */ (self: Layer, values: Record): Layer } = internal.annotateSpans /** * Builds a layer into a scoped value. * * @since 2.0.0 * @category destructors */ export const build: ( self: Layer ) => Effect.Effect, E, Scope.Scope | RIn> = internal.build /** * Builds a layer into an `Effect` value. Any resources associated with this * layer will be released when the specified scope is closed unless their scope * has been extended. This allows building layers where the lifetime of some of * the services output by the layer exceed the lifetime of the effect the * layer is provided to. * * @since 2.0.0 * @category destructors */ export const buildWithScope: { /** * Builds a layer into an `Effect` value. Any resources associated with this * layer will be released when the specified scope is closed unless their scope * has been extended. This allows building layers where the lifetime of some of * the services output by the layer exceed the lifetime of the effect the * layer is provided to. * * @since 2.0.0 * @category destructors */ (scope: Scope.Scope): (self: Layer) => Effect.Effect, E, RIn> /** * Builds a layer into an `Effect` value. Any resources associated with this * layer will be released when the specified scope is closed unless their scope * has been extended. This allows building layers where the lifetime of some of * the services output by the layer exceed the lifetime of the effect the * layer is provided to. * * @since 2.0.0 * @category destructors */ (self: Layer, scope: Scope.Scope): Effect.Effect, E, RIn> } = internal.buildWithScope /** * Recovers from all errors. * * @since 2.0.0 * @category error handling */ export const catchAll: { /** * Recovers from all errors. * * @since 2.0.0 * @category error handling */ (onError: (error: E) => Layer): (self: Layer) => Layer /** * Recovers from all errors. * * @since 2.0.0 * @category error handling */ (self: Layer, onError: (error: E) => Layer): Layer } = internal.catchAll /** * Recovers from all errors. * * @since 2.0.0 * @category error handling */ export const catchAllCause: { /** * Recovers from all errors. * * @since 2.0.0 * @category error handling */ (onError: (cause: Cause.Cause) => Layer): (self: Layer) => Layer /** * Recovers from all errors. * * @since 2.0.0 * @category error handling */ ( self: Layer, onError: (cause: Cause.Cause) => Layer ): Layer } = internal.catchAllCause /** * Constructs a `Layer` that passes along the specified context as an * output. * * @since 2.0.0 * @category constructors */ export const context: () => Layer = internal.context /** * Constructs a layer that dies with the specified defect. * * @since 2.0.0 * @category constructors */ export const die: (defect: unknown) => Layer = internal.die /** * Constructs a layer that dies with the specified defect. * * @since 2.0.0 * @category constructors */ export const dieSync: (evaluate: LazyArg) => Layer = internal.dieSync /** * Replaces the layer's output with `never` and includes the layer only for its * side-effects. * * @since 2.0.0 * @category mapping */ export const discard: (self: Layer) => Layer = internal.discard /** * Constructs a layer from the specified effect. * * @since 2.0.0 * @category constructors */ export const effect: { /** * Constructs a layer from the specified effect. * * @since 2.0.0 * @category constructors */ (tag: Context.Tag): (effect: Effect.Effect, E, R>) => Layer /** * Constructs a layer from the specified effect. * * @since 2.0.0 * @category constructors */ (tag: Context.Tag, effect: Effect.Effect, E, R>): Layer } = internal.fromEffect /** * Constructs a layer from the specified effect, discarding its output. * * @since 2.0.0 * @category constructors */ export const effectDiscard: (effect: Effect.Effect) => Layer = internal.fromEffectDiscard /** * Constructs a layer from the specified effect, which must return one or more * services. * * @since 2.0.0 * @category constructors */ export const effectContext: (effect: Effect.Effect, E, R>) => Layer = internal.fromEffectContext /** * A Layer that constructs an empty Context. * * @since 2.0.0 * @category constructors */ export const empty: Layer = internal.empty /** * Extends the scope of this layer, returning a new layer that when provided * to an effect will not immediately release its associated resources when * that effect completes execution but instead when the scope the resulting * effect depends on is closed. * * @since 2.0.0 * @category utils */ export const extendScope: (self: Layer) => Layer = internal.extendScope /** * Constructs a layer that fails with the specified error. * * @since 2.0.0 * @category constructors */ export const fail: (error: E) => Layer = internal.fail /** * Constructs a layer that fails with the specified error. * * @since 2.0.0 * @category constructors */ export const failSync: (evaluate: LazyArg) => Layer = internal.failSync /** * Constructs a layer that fails with the specified cause. * * @since 2.0.0 * @category constructors */ export const failCause: (cause: Cause.Cause) => Layer = internal.failCause /** * Constructs a layer that fails with the specified cause. * * @since 2.0.0 * @category constructors */ export const failCauseSync: (evaluate: LazyArg>) => Layer = internal.failCauseSync /** * Constructs a layer dynamically based on the output of this layer. * * @since 2.0.0 * @category sequencing */ export const flatMap: { /** * Constructs a layer dynamically based on the output of this layer. * * @since 2.0.0 * @category sequencing */ (f: (context: Context.Context) => Layer): (self: Layer) => Layer /** * Constructs a layer dynamically based on the output of this layer. * * @since 2.0.0 * @category sequencing */ ( self: Layer, f: (context: Context.Context) => Layer ): Layer } = internal.flatMap /** * Flattens layers nested in the context of an effect. * * @since 2.0.0 * @category sequencing */ export const flatten: { /** * Flattens layers nested in the context of an effect. * * @since 2.0.0 * @category sequencing */ (tag: Context.Tag>): (self: Layer) => Layer /** * Flattens layers nested in the context of an effect. * * @since 2.0.0 * @category sequencing */ (self: Layer, tag: Context.Tag>): Layer } = internal.flatten /** * Creates a fresh version of this layer that will not be shared. * * @since 2.0.0 * @category utils */ export const fresh: (self: Layer) => Layer = internal.fresh /** * @since 3.17.0 * @category Testing */ export type PartialEffectful = Types.Simplify< & { [ K in keyof A as A[K] extends | Effect.Effect | Stream.Stream | ((...args: any) => Effect.Effect | Stream.Stream) ? K : never ]?: A[K] } & { [ K in keyof A as A[K] extends | Effect.Effect | Stream.Stream | ((...args: any) => Effect.Effect | Stream.Stream) ? never : K ]: A[K] } > /** * Creates a mock layer for testing purposes. You can provide a partial * implementation of the service, and any methods not provided will * throw an `UnimplementedError` defect when called. * * **Example** * * ```ts * import { Context, Effect, Layer } from "effect" * * class MyService extends Context.Tag("MyService")< * MyService, * { * one: Effect.Effect * two(): Effect.Effect * } * >() {} * * const MyServiceTest = Layer.mock(MyService, { * two: () => Effect.succeed(2) * }) * ``` * * @since 3.17.0 * @category Testing */ export const mock: { /** * Creates a mock layer for testing purposes. You can provide a partial * implementation of the service, and any methods not provided will * throw an `UnimplementedError` defect when called. * * **Example** * * ```ts * import { Context, Effect, Layer } from "effect" * * class MyService extends Context.Tag("MyService")< * MyService, * { * one: Effect.Effect * two(): Effect.Effect * } * >() {} * * const MyServiceTest = Layer.mock(MyService, { * two: () => Effect.succeed(2) * }) * ``` * * @since 3.17.0 * @category Testing */ (tag: Context.Tag): (service: PartialEffectful) => Layer /** * Creates a mock layer for testing purposes. You can provide a partial * implementation of the service, and any methods not provided will * throw an `UnimplementedError` defect when called. * * **Example** * * ```ts * import { Context, Effect, Layer } from "effect" * * class MyService extends Context.Tag("MyService")< * MyService, * { * one: Effect.Effect * two(): Effect.Effect * } * >() {} * * const MyServiceTest = Layer.mock(MyService, { * two: () => Effect.succeed(2) * }) * ``` * * @since 3.17.0 * @category Testing */ (tag: Context.Tag, service: PartialEffectful): Layer } = internal.mock const fromFunction: ( tagA: Context.Tag, tagB: Context.Tag, f: (a: Types.NoInfer) => Types.NoInfer ) => Layer = internal.fromFunction export { /** * Constructs a layer from the context using the specified function. * * @since 2.0.0 * @category constructors */ fromFunction as function } /** * Builds this layer and uses it until it is interrupted. This is useful when * your entire application is a layer, such as an HTTP server. * * @since 2.0.0 * @category conversions */ export const launch: (self: Layer) => Effect.Effect = internal.launch /** * Returns a new layer whose output is mapped by the specified function. * * @since 2.0.0 * @category mapping */ export const map: { /** * Returns a new layer whose output is mapped by the specified function. * * @since 2.0.0 * @category mapping */ (f: (context: Context.Context) => Context.Context): (self: Layer) => Layer /** * Returns a new layer whose output is mapped by the specified function. * * @since 2.0.0 * @category mapping */ ( self: Layer, f: (context: Context.Context) => Context.Context ): Layer } = internal.map /** * Returns a layer with its error channel mapped using the specified function. * * @since 2.0.0 * @category mapping */ export const mapError: { /** * Returns a layer with its error channel mapped using the specified function. * * @since 2.0.0 * @category mapping */ (f: (error: E) => E2): (self: Layer) => Layer /** * Returns a layer with its error channel mapped using the specified function. * * @since 2.0.0 * @category mapping */ (self: Layer, f: (error: E) => E2): Layer } = internal.mapError /** * Feeds the error or output services of this layer into the input of either * the specified `failure` or `success` layers, resulting in a new layer with * the inputs of this layer, and the error or outputs of the specified layer. * * @since 2.0.0 * @category folding */ export const match: { /** * Feeds the error or output services of this layer into the input of either * the specified `failure` or `success` layers, resulting in a new layer with * the inputs of this layer, and the error or outputs of the specified layer. * * @since 2.0.0 * @category folding */ ( options: { readonly onFailure: (error: E) => Layer readonly onSuccess: (context: Context.Context) => Layer } ): (self: Layer) => Layer /** * Feeds the error or output services of this layer into the input of either * the specified `failure` or `success` layers, resulting in a new layer with * the inputs of this layer, and the error or outputs of the specified layer. * * @since 2.0.0 * @category folding */ ( self: Layer, options: { readonly onFailure: (error: E) => Layer readonly onSuccess: (context: Context.Context) => Layer } ): Layer } = internal.match /** * Feeds the error or output services of this layer into the input of either * the specified `failure` or `success` layers, resulting in a new layer with * the inputs of this layer, and the error or outputs of the specified layer. * * @since 2.0.0 * @category folding */ export const matchCause: { /** * Feeds the error or output services of this layer into the input of either * the specified `failure` or `success` layers, resulting in a new layer with * the inputs of this layer, and the error or outputs of the specified layer. * * @since 2.0.0 * @category folding */ ( options: { readonly onFailure: (cause: Cause.Cause) => Layer readonly onSuccess: (context: Context.Context) => Layer } ): (self: Layer) => Layer /** * Feeds the error or output services of this layer into the input of either * the specified `failure` or `success` layers, resulting in a new layer with * the inputs of this layer, and the error or outputs of the specified layer. * * @since 2.0.0 * @category folding */ ( self: Layer, options: { readonly onFailure: (cause: Cause.Cause) => Layer readonly onSuccess: (context: Context.Context) => Layer } ): Layer } = internal.matchCause /** * Returns a scoped effect that, if evaluated, will return the lazily computed * result of this layer. * * @since 2.0.0 * @category utils */ export const memoize: ( self: Layer ) => Effect.Effect, never, Scope.Scope> = internal.memoize /** * Merges this layer with the specified layer concurrently, producing a new layer with combined input and output types. * * @since 2.0.0 * @category zipping */ export const merge: { /** * Merges this layer with the specified layer concurrently, producing a new layer with combined input and output types. * * @since 2.0.0 * @category zipping */ (that: Layer): (self: Layer) => Layer /** * Merges this layer with the specified layer concurrently, producing a new layer with combined input and output types. * * @since 2.0.0 * @category zipping */ (self: Layer, that: Layer): Layer } = internal.merge /** * Combines all the provided layers concurrently, creating a new layer with merged input, error, and output types. * * @since 2.0.0 * @category zipping */ export const mergeAll: , ...Array>]>( ...layers: Layers ) => Layer< { [k in keyof Layers]: Layer.Success }[number], { [k in keyof Layers]: Layer.Error }[number], { [k in keyof Layers]: Layer.Context }[number] > = internal.mergeAll /** * Translates effect failure into death of the fiber, making all failures * unchecked and not a part of the type of the layer. * * @since 2.0.0 * @category error handling */ export const orDie: (self: Layer) => Layer = internal.orDie /** * Executes this layer and returns its output, if it succeeds, but otherwise * executes the specified layer. * * @since 2.0.0 * @category error handling */ export const orElse: { /** * Executes this layer and returns its output, if it succeeds, but otherwise * executes the specified layer. * * @since 2.0.0 * @category error handling */ (that: LazyArg>): (self: Layer) => Layer /** * Executes this layer and returns its output, if it succeeds, but otherwise * executes the specified layer. * * @since 2.0.0 * @category error handling */ (self: Layer, that: LazyArg>): Layer } = internal.orElse /** * Returns a new layer that produces the outputs of this layer but also * passes through the inputs. * * @since 2.0.0 * @category utils */ export const passthrough: (self: Layer) => Layer = internal.passthrough /** * Projects out part of one of the services output by this layer using the * specified function. * * @since 2.0.0 * @category utils */ export const project: { /** * Projects out part of one of the services output by this layer using the * specified function. * * @since 2.0.0 * @category utils */ ( tagA: Context.Tag, tagB: Context.Tag, f: (a: Types.NoInfer) => Types.NoInfer ): (self: Layer) => Layer /** * Projects out part of one of the services output by this layer using the * specified function. * * @since 2.0.0 * @category utils */ ( self: Layer, tagA: Context.Tag, tagB: Context.Tag, f: (a: Types.NoInfer) => Types.NoInfer ): Layer } = internal.project /** * @since 2.0.0 * @category utils */ export const locallyEffect: { /** * @since 2.0.0 * @category utils */ ( f: (_: Effect.Effect>) => Effect.Effect> ): (self: Layer) => Layer /** * @since 2.0.0 * @category utils */ ( self: Layer, f: (_: Effect.Effect>) => Effect.Effect> ): Layer } = internal.locallyEffect /** * @since 2.0.0 * @category utils */ export const locally: { /** * @since 2.0.0 * @category utils */ (ref: FiberRef, value: X): (self: Layer) => Layer /** * @since 2.0.0 * @category utils */ (self: Layer, ref: FiberRef, value: X): Layer } = internal.fiberRefLocally /** * @since 2.0.0 * @category utils */ export const locallyWith: { /** * @since 2.0.0 * @category utils */ (ref: FiberRef, value: (_: X) => X): (self: Layer) => Layer /** * @since 2.0.0 * @category utils */ (self: Layer, ref: FiberRef, value: (_: X) => X): Layer } = internal.fiberRefLocallyWith /** * @since 2.0.0 * @category utils */ export const locallyScoped: (self: FiberRef, value: A) => Layer = internal.fiberRefLocallyScoped /** * @since 2.0.0 * @category utils */ export const fiberRefLocallyScopedWith: (self: FiberRef, value: (_: A) => A) => Layer = internal.fiberRefLocallyScopedWith /** * Retries constructing this layer according to the specified schedule. * * @since 2.0.0 * @category retrying */ export const retry: { /** * Retries constructing this layer according to the specified schedule. * * @since 2.0.0 * @category retrying */ (schedule: Schedule.Schedule, RIn2>): (self: Layer) => Layer /** * Retries constructing this layer according to the specified schedule. * * @since 2.0.0 * @category retrying */ (self: Layer, schedule: Schedule.Schedule): Layer } = internal.retry /** * A layer that constructs a scope and closes it when the workflow the layer * is provided to completes execution, whether by success, failure, or * interruption. This can be used to close a scope when providing a layer to a * workflow. * * @since 2.0.0 * @category constructors */ export const scope: Layer = internal.scope /** * Constructs a layer from the specified scoped effect. * * @since 2.0.0 * @category constructors */ export const scoped: { /** * Constructs a layer from the specified scoped effect. * * @since 2.0.0 * @category constructors */ (tag: Context.Tag): (effect: Effect.Effect, E, R>) => Layer> /** * Constructs a layer from the specified scoped effect. * * @since 2.0.0 * @category constructors */ (tag: Context.Tag, effect: Effect.Effect, E, R>): Layer> } = internal.scoped /** * Constructs a layer from the specified scoped effect. * * @since 2.0.0 * @category constructors */ export const scopedDiscard: (effect: Effect.Effect) => Layer> = internal.scopedDiscard /** * Constructs a layer from the specified scoped effect, which must return one * or more services. * * @since 2.0.0 * @category constructors */ export const scopedContext: ( effect: Effect.Effect, E, R> ) => Layer> = internal.scopedContext /** * Constructs a layer that accesses and returns the specified service from the * context. * * @since 2.0.0 * @category constructors */ export const service: (tag: Context.Tag) => Layer = internal.service /** * Constructs a layer from the specified value. * * @since 2.0.0 * @category constructors */ export const succeed: { /** * Constructs a layer from the specified value. * * @since 2.0.0 * @category constructors */ (tag: Context.Tag): (resource: Types.NoInfer) => Layer /** * Constructs a layer from the specified value. * * @since 2.0.0 * @category constructors */ (tag: Context.Tag, resource: Types.NoInfer): Layer } = internal.succeed /** * Constructs a layer from the specified value, which must return one or more * services. * * @since 2.0.0 * @category constructors */ export const succeedContext: (context: Context.Context) => Layer = internal.succeedContext /** * Lazily constructs a layer. This is useful to avoid infinite recursion when * creating layers that refer to themselves. * * @since 2.0.0 * @category constructors */ export const suspend: (evaluate: LazyArg>) => Layer = internal.suspend /** * Lazily constructs a layer from the specified value. * * @since 2.0.0 * @category constructors */ export const sync: { /** * Lazily constructs a layer from the specified value. * * @since 2.0.0 * @category constructors */ (tag: Context.Tag): (evaluate: LazyArg>) => Layer /** * Lazily constructs a layer from the specified value. * * @since 2.0.0 * @category constructors */ (tag: Context.Tag, evaluate: LazyArg>): Layer } = internal.sync /** * Lazily constructs a layer from the specified value, which must return one or more * services. * * @since 2.0.0 * @category constructors */ export const syncContext: (evaluate: LazyArg>) => Layer = internal.syncContext /** * Performs the specified effect if this layer succeeds. * * @since 2.0.0 * @category sequencing */ export const tap: { /** * Performs the specified effect if this layer succeeds. * * @since 2.0.0 * @category sequencing */ (f: (context: Context.Context) => Effect.Effect): (self: Layer) => Layer /** * Performs the specified effect if this layer succeeds. * * @since 2.0.0 * @category sequencing */ ( self: Layer, f: (context: Context.Context) => Effect.Effect ): Layer } = internal.tap /** * Performs the specified effect if this layer fails. * * @since 2.0.0 * @category sequencing */ export const tapError: { /** * Performs the specified effect if this layer fails. * * @since 2.0.0 * @category sequencing */ (f: (e: XE) => Effect.Effect): (self: Layer) => Layer /** * Performs the specified effect if this layer fails. * * @since 2.0.0 * @category sequencing */ (self: Layer, f: (e: XE) => Effect.Effect): Layer } = internal.tapError /** * Performs the specified effect if this layer fails. * * @since 2.0.0 * @category sequencing */ export const tapErrorCause: { /** * Performs the specified effect if this layer fails. * * @since 2.0.0 * @category sequencing */ (f: (cause: Cause.Cause) => Effect.Effect): (self: Layer) => Layer /** * Performs the specified effect if this layer fails. * * @since 2.0.0 * @category sequencing */ ( self: Layer, f: (cause: Cause.Cause) => Effect.Effect ): Layer } = internal.tapErrorCause /** * Converts a layer that requires no services into a scoped runtime, which can * be used to execute effects. * * @since 2.0.0 * @category conversions */ export const toRuntime: ( self: Layer ) => Effect.Effect, E, Scope.Scope | RIn> = internal.toRuntime /** * Converts a layer that requires no services into a scoped runtime, which can * be used to execute effects. * * @since 2.0.0 * @category conversions */ export const toRuntimeWithMemoMap: { /** * Converts a layer that requires no services into a scoped runtime, which can * be used to execute effects. * * @since 2.0.0 * @category conversions */ (memoMap: MemoMap): (self: Layer) => Effect.Effect, E, Scope.Scope | RIn> /** * Converts a layer that requires no services into a scoped runtime, which can * be used to execute effects. * * @since 2.0.0 * @category conversions */ (self: Layer, memoMap: MemoMap): Effect.Effect, E, Scope.Scope | RIn> } = internal.toRuntimeWithMemoMap /** * Feeds the output services of this builder into the input of the specified * builder, resulting in a new builder with the inputs of this builder as * well as any leftover inputs, and the outputs of the specified builder. * * @since 2.0.0 * @category utils */ export const provide: { /** * Feeds the output services of this builder into the input of the specified * builder, resulting in a new builder with the inputs of this builder as * well as any leftover inputs, and the outputs of the specified builder. * * @since 2.0.0 * @category utils */ (that: Layer): (self: Layer) => Layer> /** * Feeds the output services of this builder into the input of the specified * builder, resulting in a new builder with the inputs of this builder as * well as any leftover inputs, and the outputs of the specified builder. * * @since 2.0.0 * @category utils */ ]>(that: Layers): ( self: Layer ) => Layer< A, E | { [k in keyof Layers]: Layer.Error }[number], | { [k in keyof Layers]: Layer.Context }[number] | Exclude }[number]> > /** * Feeds the output services of this builder into the input of the specified * builder, resulting in a new builder with the inputs of this builder as * well as any leftover inputs, and the outputs of the specified builder. * * @since 2.0.0 * @category utils */ (self: Layer, that: Layer): Layer> /** * Feeds the output services of this builder into the input of the specified * builder, resulting in a new builder with the inputs of this builder as * well as any leftover inputs, and the outputs of the specified builder. * * @since 2.0.0 * @category utils */ ]>(self: Layer, that: Layers): Layer< A, E | { [k in keyof Layers]: Layer.Error }[number], | { [k in keyof Layers]: Layer.Context }[number] | Exclude }[number]> > } = internal.provide /** * Feeds the output services of this layer into the input of the specified * layer, resulting in a new layer with the inputs of this layer, and the * outputs of both layers. * * @since 2.0.0 * @category utils */ export const provideMerge: { /** * Feeds the output services of this layer into the input of the specified * layer, resulting in a new layer with the inputs of this layer, and the * outputs of both layers. * * @since 2.0.0 * @category utils */ (self: Layer): (that: Layer) => Layer> /** * Feeds the output services of this layer into the input of the specified * layer, resulting in a new layer with the inputs of this layer, and the * outputs of both layers. * * @since 2.0.0 * @category utils */ (that: Layer, self: Layer): Layer> } = internal.provideMerge /** * Combines this layer with the specified layer concurrently, creating a new layer with merged input types and * combined output types using the provided function. * * @since 2.0.0 * @category zipping */ export const zipWith: { /** * Combines this layer with the specified layer concurrently, creating a new layer with merged input types and * combined output types using the provided function. * * @since 2.0.0 * @category zipping */ ( that: Layer, f: (a: Context.Context, b: Context.Context) => Context.Context ): (self: Layer) => Layer /** * Combines this layer with the specified layer concurrently, creating a new layer with merged input types and * combined output types using the provided function. * * @since 2.0.0 * @category zipping */ ( self: Layer, that: Layer, f: (a: Context.Context, b: Context.Context) => Context.Context ): Layer } = internal.zipWith /** * @since 2.0.0 * @category utils */ export const unwrapEffect: (self: Effect.Effect, E, R>) => Layer = internal.unwrapEffect /** * @since 2.0.0 * @category utils */ export const unwrapScoped: ( self: Effect.Effect, E, R> ) => Layer> = internal.unwrapScoped /** * @since 2.0.0 * @category clock */ export const setClock: (clock: A) => Layer = ( clock: A ): Layer => scopedDiscard( fiberRuntime.fiberRefLocallyScopedWith(defaultServices.currentServices, Context.add(clockTag, clock)) ) /** * Sets the current `ConfigProvider`. * * @since 2.0.0 * @category config */ export const setConfigProvider: (configProvider: ConfigProvider) => Layer = circularLayer.setConfigProvider /** * Adds the provided span to the span stack. * * @since 2.0.0 * @category tracing */ export const parentSpan: (span: Tracer.AnySpan) => Layer = circularLayer.parentSpan /** * @since 3.15.0 * @category Random */ export const setRandom = (random: A): Layer => scopedDiscard( fiberRuntime.fiberRefLocallyScopedWith(defaultServices.currentServices, Context.add(randomTag, random)) ) /** * @since 2.0.0 * @category requests & batching */ export const setRequestBatching: (requestBatching: boolean) => Layer = ( requestBatching: boolean ) => scopedDiscard( fiberRuntime.fiberRefLocallyScoped(core.currentRequestBatching, requestBatching) ) /** * @since 2.0.0 * @category requests & batching */ export const setRequestCaching: (requestCaching: boolean) => Layer = ( requestCaching: boolean ) => scopedDiscard( fiberRuntime.fiberRefLocallyScoped(query.currentCacheEnabled, requestCaching) ) /** * @since 2.0.0 * @category requests & batching */ export const setRequestCache: { /** * @since 2.0.0 * @category requests & batching */ (cache: Effect.Effect): Layer> /** * @since 2.0.0 * @category requests & batching */ (cache: Request.Cache): Layer } = ((cache: Request.Cache | Effect.Effect) => scopedDiscard( core.isEffect(cache) ? core.flatMap(cache, (x) => fiberRuntime.fiberRefLocallyScoped(query.currentCache as any, x)) : fiberRuntime.fiberRefLocallyScoped(query.currentCache as any, cache) )) as any /** * @since 2.0.0 * @category scheduler */ export const setScheduler: (scheduler: Scheduler.Scheduler) => Layer = ( scheduler: Scheduler.Scheduler ): Layer => scopedDiscard( fiberRuntime.fiberRefLocallyScoped(Scheduler.currentScheduler, scheduler) ) /** * Create and add a span to the current span stack. * * The span is ended when the Layer is released. * * @since 2.0.0 * @category tracing */ export const span: ( name: string, options?: Tracer.SpanOptions & { readonly onEnd?: | ((span: Tracer.Span, exit: Exit.Exit) => Effect.Effect) | undefined } ) => Layer = circularLayer.span /** * Create a Layer that sets the current Tracer * * @since 2.0.0 * @category tracing */ export const setTracer: (tracer: Tracer.Tracer) => Layer = circularLayer.setTracer /** * @since 2.0.0 * @category tracing */ export const setTracerEnabled: (enabled: boolean) => Layer = (enabled: boolean) => scopedDiscard( fiberRuntime.fiberRefLocallyScoped(core.currentTracerEnabled, enabled) ) /** * @since 2.0.0 * @category tracing */ export const setTracerTiming: (enabled: boolean) => Layer = (enabled: boolean) => scopedDiscard( fiberRuntime.fiberRefLocallyScoped(core.currentTracerTimingEnabled, enabled) ) /** * @since 2.0.0 * @category logging */ export const setUnhandledErrorLogLevel: (level: Option.Option) => Layer = ( level: Option.Option ): Layer => scopedDiscard( fiberRuntime.fiberRefLocallyScoped(core.currentUnhandledErrorLogLevel, level) ) /** * @since 3.17.0 * @category logging */ export const setVersionMismatchErrorLogLevel: (level: Option.Option) => Layer = ( level: Option.Option ): Layer => scopedDiscard( fiberRuntime.fiberRefLocallyScoped(core.currentVersionMismatchErrorLogLevel, level) ) /** * @since 2.0.0 * @category tracing */ export const withSpan: { /** * @since 2.0.0 * @category tracing */ ( name: string, options?: Tracer.SpanOptions & { readonly onEnd?: | ((span: Tracer.Span, exit: Exit.Exit) => Effect.Effect) | undefined } ): (self: Layer) => Layer> /** * @since 2.0.0 * @category tracing */ ( self: Layer, name: string, options?: Tracer.SpanOptions & { readonly onEnd?: | ((span: Tracer.Span, exit: Exit.Exit) => Effect.Effect) | undefined } ): Layer> } = internal.withSpan /** * @since 2.0.0 * @category tracing */ export const withParentSpan: { /** * @since 2.0.0 * @category tracing */ (span: Tracer.AnySpan): (self: Layer) => Layer> /** * @since 2.0.0 * @category tracing */ (self: Layer, span: Tracer.AnySpan): Layer> } = internal.withParentSpan // ----------------------------------------------------------------------------- // memo map // ----------------------------------------------------------------------------- /** * Constructs a `MemoMap` that can be used to build additional layers. * * @since 2.0.0 * @category memo map */ export const makeMemoMap: Effect.Effect = internal.makeMemoMap /** * Builds a layer into an `Effect` value, using the specified `MemoMap` to memoize * the layer construction. * * @since 2.0.0 * @category memo map */ export const buildWithMemoMap: { /** * Builds a layer into an `Effect` value, using the specified `MemoMap` to memoize * the layer construction. * * @since 2.0.0 * @category memo map */ (memoMap: MemoMap, scope: Scope.Scope): (self: Layer) => Effect.Effect, E, RIn> /** * Builds a layer into an `Effect` value, using the specified `MemoMap` to memoize * the layer construction. * * @since 2.0.0 * @category memo map */ (self: Layer, memoMap: MemoMap, scope: Scope.Scope): Effect.Effect, E, RIn> } = internal.buildWithMemoMap /** * Updates a service in the context with a new implementation. * * **Details** * * This function modifies the existing implementation of a service in the * context. It retrieves the current service, applies the provided * transformation function `f`, and replaces the old service with the * transformed one. * * **When to Use** * * This is useful for adapting or extending a service's behavior during the * creation of a layer. * * @since 3.13.0 * @category utils */ export const updateService = dual< /** * Updates a service in the context with a new implementation. * * **Details** * * This function modifies the existing implementation of a service in the * context. It retrieves the current service, applies the provided * transformation function `f`, and replaces the old service with the * transformed one. * * **When to Use** * * This is useful for adapting or extending a service's behavior during the * creation of a layer. * * @since 3.13.0 * @category utils */ (tag: Context.Tag, f: (a: A) => A) => (layer: Layer) => Layer, /** * Updates a service in the context with a new implementation. * * **Details** * * This function modifies the existing implementation of a service in the * context. It retrieves the current service, applies the provided * transformation function `f`, and replaces the old service with the * transformed one. * * **When to Use** * * This is useful for adapting or extending a service's behavior during the * creation of a layer. * * @since 3.13.0 * @category utils */ (layer: Layer, tag: Context.Tag, f: (a: A) => A) => Layer >(3, (layer, tag, f) => provide( layer, map(context(), (c) => Context.add(c, tag, f(Context.unsafeGet(c, tag)))) ))