UNPKG

veffect

Version:

powerful TypeScript validation library built on the robust foundation of Effect combining exceptional type safety, high performance, and developer experience. Taking inspiration from Effect's functional principles, VEffect delivers a balanced approach tha

1,084 lines (996 loc) 32.3 kB
/** * A `Layer<ROut, E, RIn>` 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 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 type { LogLevel } from "./LogLevel.js" import type * as Option from "./Option.js" import type { Pipeable } from "./Pipeable.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 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<in ROut, out E = never, out RIn = never> extends Layer.Variance<ROut, E, RIn>, Pipeable {} /** * @since 2.0.0 */ export declare namespace Layer { /** * @since 2.0.0 * @category models */ export interface Variance<in ROut, out E, out RIn> { readonly [LayerTypeId]: { readonly _ROut: Types.Contravariant<ROut> readonly _E: Types.Covariant<E> readonly _RIn: Types.Covariant<RIn> } } /** * @since 2.0.0 * @category type-level */ export type Context<T extends Layer<never, any, any>> = [T] extends [Layer<infer _ROut, infer _E, infer _RIn>] ? _RIn : never /** * @since 2.0.0 * @category type-level */ export type Error<T extends Layer<never, any, any>> = [T] extends [Layer<infer _ROut, infer _E, infer _RIn>] ? _E : never /** * @since 2.0.0 * @category type-level */ export type Success<T extends Layer<never, any, any>> = [T] extends [Layer<infer _ROut, infer _E, infer _RIn>] ? _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: <RIn, E, ROut>( layer: Layer<ROut, E, RIn>, scope: Scope.Scope ) => Effect.Effect<Context.Context<ROut>, E, RIn> } /** * 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<unknown, unknown, unknown> = 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: <RIn, E, ROut>(self: Layer<ROut, E, RIn>) => boolean = internal.isFresh /** * Builds a layer into a scoped value. * * @since 2.0.0 * @category destructors */ export const build: <RIn, E, ROut>( self: Layer<ROut, E, RIn> ) => Effect.Effect<Context.Context<ROut>, 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: { (scope: Scope.Scope): <RIn, E, ROut>(self: Layer<ROut, E, RIn>) => Effect.Effect<Context.Context<ROut>, E, RIn> <RIn, E, ROut>(self: Layer<ROut, E, RIn>, scope: Scope.Scope): Effect.Effect<Context.Context<ROut>, E, RIn> } = internal.buildWithScope /** * Recovers from all errors. * * @since 2.0.0 * @category error handling */ export const catchAll: { <E, RIn2, E2, ROut2>( onError: (error: E) => Layer<ROut2, E2, RIn2> ): <RIn, ROut>(self: Layer<ROut, E, RIn>) => Layer<ROut & ROut2, E2, RIn2 | RIn> <RIn, E, ROut, RIn2, E2, ROut2>( self: Layer<ROut, E, RIn>, onError: (error: E) => Layer<ROut2, E2, RIn2> ): Layer<ROut & ROut2, E2, RIn | RIn2> } = internal.catchAll /** * Recovers from all errors. * * @since 2.0.0 * @category error handling */ export const catchAllCause: { <E, RIn2, E2, ROut2>( onError: (cause: Cause.Cause<E>) => Layer<ROut2, E2, RIn2> ): <RIn, ROut>(self: Layer<ROut, E, RIn>) => Layer<ROut & ROut2, E2, RIn2 | RIn> <RIn, E, ROut, RIn2, E2, ROut22>( self: Layer<ROut, E, RIn>, onError: (cause: Cause.Cause<E>) => Layer<ROut22, E2, RIn2> ): Layer<ROut & ROut22, E2, RIn | RIn2> } = internal.catchAllCause /** * Constructs a `Layer` that passes along the specified context as an * output. * * @since 2.0.0 * @category constructors */ export const context: <R>() => Layer<R, never, R> = internal.context /** * Constructs a layer that dies with the specified defect. * * @since 2.0.0 * @category constructors */ export const die: (defect: unknown) => Layer<unknown> = internal.die /** * Constructs a layer that dies with the specified defect. * * @since 2.0.0 * @category constructors */ export const dieSync: (evaluate: LazyArg<unknown>) => Layer<unknown> = internal.dieSync /** * Replaces the layer's output with `void` and includes the layer only for its * side-effects. * * @since 2.0.0 * @category mapping */ export const discard: <RIn, E, ROut>(self: Layer<ROut, E, RIn>) => Layer<never, E, RIn> = internal.discard /** * Constructs a layer from the specified effect. * * @since 2.0.0 * @category constructors */ export const effect: { <T extends Context.Tag<any, any>>( tag: T ): <E, R>(effect: Effect.Effect<Context.Tag.Service<T>, E, R>) => Layer<Context.Tag.Identifier<T>, E, R> <T extends Context.Tag<any, any>, E, R>( tag: T, effect: Effect.Effect<Context.Tag.Service<T>, E, R> ): Layer<Context.Tag.Identifier<T>, E, R> } = internal.fromEffect /** * Constructs a layer from the specified effect discarding it's output. * * @since 2.0.0 * @category constructors */ export const effectDiscard: <X, E, R>(effect: Effect.Effect<X, E, R>) => Layer<never, E, R> = 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: <A, E, R>(effect: Effect.Effect<Context.Context<A>, E, R>) => Layer<A, E, R> = internal.fromEffectContext /** * A Layer that constructs an empty Context. * * @since 2.0.0 * @category constructors */ export const empty: Layer<never> = 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: <RIn, E, ROut>(self: Layer<ROut, E, RIn>) => Layer<ROut, E, Scope.Scope | RIn> = internal.extendScope /** * Constructs a layer that fails with the specified error. * * @since 2.0.0 * @category constructors */ export const fail: <E>(error: E) => Layer<unknown, E> = internal.fail /** * Constructs a layer that fails with the specified error. * * @since 2.0.0 * @category constructors */ export const failSync: <E>(evaluate: LazyArg<E>) => Layer<unknown, E> = internal.failSync /** * Constructs a layer that fails with the specified cause. * * @since 2.0.0 * @category constructors */ export const failCause: <E>(cause: Cause.Cause<E>) => Layer<unknown, E> = internal.failCause /** * Constructs a layer that fails with the specified cause. * * @since 2.0.0 * @category constructors */ export const failCauseSync: <E>(evaluate: LazyArg<Cause.Cause<E>>) => Layer<unknown, E> = internal.failCauseSync /** * Constructs a layer dynamically based on the output of this layer. * * @since 2.0.0 * @category sequencing */ export const flatMap: { <A, A2, E2, R2>( f: (context: Context.Context<A>) => Layer<A2, E2, R2> ): <E, R>(self: Layer<A, E, R>) => Layer<A2, E2 | E, R2 | R> <A, E, R, A2, E2, R2>( self: Layer<A, E, R>, f: (context: Context.Context<A>) => Layer<A2, E2, R2> ): Layer<A2, E | E2, R | R2> } = internal.flatMap /** * Flattens layers nested in the context of an effect. * * @since 2.0.0 * @category sequencing */ export const flatten: { <I, A, E2, R2>(tag: Context.Tag<I, Layer<A, E2, R2>>): <E, R>(self: Layer<I, E, R>) => Layer<A, E2 | E, R2 | R> <I, E, R, A, E2, R2>(self: Layer<I, E, R>, tag: Context.Tag<I, Layer<A, E2, R2>>): Layer<A, E | E2, R | R2> } = internal.flatten /** * Creates a fresh version of this layer that will not be shared. * * @since 2.0.0 * @category utils */ export const fresh: <A, E, R>(self: Layer<A, E, R>) => Layer<A, E, R> = internal.fresh const fromFunction: <A extends Context.Tag<any, any>, B extends Context.Tag<any, any>>( tagA: A, tagB: B, f: (a: Context.Tag.Service<A>) => Context.Tag.Service<B> ) => Layer<Context.Tag.Identifier<B>, never, Context.Tag.Identifier<A>> = 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: <RIn, E, ROut>(self: Layer<ROut, E, RIn>) => Effect.Effect<never, E, RIn> = internal.launch /** * Returns a new layer whose output is mapped by the specified function. * * @since 2.0.0 * @category mapping */ export const map: { <A, B>(f: (context: Context.Context<A>) => Context.Context<B>): <E, R>(self: Layer<A, E, R>) => Layer<B, E, R> <A, E, R, B>(self: Layer<A, E, R>, f: (context: Context.Context<A>) => Context.Context<B>): Layer<B, E, R> } = internal.map /** * Returns a layer with its error channel mapped using the specified function. * * @since 2.0.0 * @category mapping */ export const mapError: { <E, E2>(f: (error: E) => E2): <A, R>(self: Layer<A, E, R>) => Layer<A, E2, R> <A, E, R, E2>(self: Layer<A, E, R>, f: (error: E) => E2): Layer<A, E2, R> } = 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: { <E, A2, E2, R2, A, A3, E3, R3>( options: { readonly onFailure: (error: E) => Layer<A2, E2, R2> readonly onSuccess: (context: Context.Context<A>) => Layer<A3, E3, R3> } ): <R>(self: Layer<A, E, R>) => Layer<A2 & A3, E2 | E3, R2 | R3 | R> <A, E, R, A2, E2, R2, A3, E3, R3>( self: Layer<A, E, R>, options: { readonly onFailure: (error: E) => Layer<A2, E2, R2> readonly onSuccess: (context: Context.Context<A>) => Layer<A3, E3, R3> } ): Layer<A2 & A3, E2 | E3, R | R2 | R3> } = 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: { <E, A2, E2, R2, A, A3, E3, R3>( options: { readonly onFailure: (cause: Cause.Cause<E>) => Layer<A2, E2, R2> readonly onSuccess: (context: Context.Context<A>) => Layer<A3, E3, R3> } ): <R>(self: Layer<A, E, R>) => Layer<A2 & A3, E2 | E3, R2 | R3 | R> <A, E, R, A2, E2, R2, A3, E3, R3>( self: Layer<A, E, R>, options: { readonly onFailure: (cause: Cause.Cause<E>) => Layer<A2, E2, R2> readonly onSuccess: (context: Context.Context<A>) => Layer<A3, E3, R3> } ): Layer<A2 & A3, E2 | E3, R | R2 | R3> } = 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: <RIn, E, ROut>( self: Layer<ROut, E, RIn> ) => Effect.Effect<Layer<ROut, E, RIn>, 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: { <RIn2, E2, ROut2>( that: Layer<ROut2, E2, RIn2> ): <RIn, E1, ROut>(self: Layer<ROut, E1, RIn>) => Layer<ROut2 | ROut, E2 | E1, RIn2 | RIn> <RIn, E1, ROut, RIn2, E2, ROut2>( self: Layer<ROut, E1, RIn>, that: Layer<ROut2, E2, RIn2> ): Layer<ROut | ROut2, E1 | E2, RIn | RIn2> } = 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: <Layers extends [Layer<never, any, any>, ...Array<Layer<never, any, any>>]>( ...layers: Layers ) => Layer< { [k in keyof Layers]: Layer.Success<Layers[k]> }[number], { [k in keyof Layers]: Layer.Error<Layers[k]> }[number], { [k in keyof Layers]: Layer.Context<Layers[k]> }[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: <A, E, R>(self: Layer<A, E, R>) => Layer<A, never, R> = 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: { <A2, E2, R2>(that: LazyArg<Layer<A2, E2, R2>>): <A, E, R>(self: Layer<A, E, R>) => Layer<A & A2, E2 | E, R2 | R> <A, E, R, A2, E2, R2>(self: Layer<A, E, R>, that: LazyArg<Layer<A2, E2, R2>>): Layer<A & A2, E | E2, R | R2> } = 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: <RIn, E, ROut>(self: Layer<ROut, E, RIn>) => Layer<RIn | ROut, E, RIn> = 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: { <A extends Context.Tag<any, any>, B extends Context.Tag<any, any>>( tagA: A, tagB: B, f: (a: Context.Tag.Service<A>) => Context.Tag.Service<B> ): <RIn, E>(self: Layer<Context.Tag.Identifier<A>, E, RIn>) => Layer<Context.Tag.Identifier<B>, E, RIn> <RIn, E, A extends Context.Tag<any, any>, B extends Context.Tag<any, any>>( self: Layer<Context.Tag.Identifier<A>, E, RIn>, tagA: A, tagB: B, f: (a: Context.Tag.Service<A>) => Context.Tag.Service<B> ): Layer<Context.Tag.Identifier<B>, E, RIn> } = internal.project /** * @since 2.0.0 * @category utils */ export const locallyEffect: { <RIn, E, ROut, RIn2, E2, ROut2>( f: (_: Effect.Effect<RIn, E, Context.Context<ROut>>) => Effect.Effect<RIn2, E2, Context.Context<ROut2>> ): (self: Layer<ROut, E, RIn>) => Layer<ROut2, E2, RIn2> <RIn, E, ROut, RIn2, E2, ROut2>( self: Layer<ROut, E, RIn>, f: (_: Effect.Effect<RIn, E, Context.Context<ROut>>) => Effect.Effect<RIn2, E2, Context.Context<ROut2>> ): Layer<ROut2, E2, RIn2> } = internal.locallyEffect /** * @since 2.0.0 * @category utils */ export const locally: { <X>( ref: FiberRef<X>, value: X ): <A, E, R>(self: Layer<A, E, R>) => Layer<A, E, R> <A, E, R, X>( self: Layer<A, E, R>, ref: FiberRef<X>, value: X ): Layer<A, E, R> } = internal.fiberRefLocally /** * @since 2.0.0 * @category utils */ export const locallyWith: { <X>(ref: FiberRef<X>, value: (_: X) => X): <A, E, R>(self: Layer<A, E, R>) => Layer<A, E, R> <A, E, R, X>(self: Layer<A, E, R>, ref: FiberRef<X>, value: (_: X) => X): Layer<A, E, R> } = internal.fiberRefLocallyWith /** * @since 2.0.0 * @category utils */ export const locallyScoped: <A>(self: FiberRef<A>, value: A) => Layer<never> = internal.fiberRefLocallyScoped /** * @since 2.0.0 * @category utils */ export const fiberRefLocallyScopedWith: <A>(self: FiberRef<A>, value: (_: A) => A) => Layer<never> = internal.fiberRefLocallyScopedWith /** * Retries constructing this layer according to the specified schedule. * * @since 2.0.0 * @category retrying */ export const retry: { <X, E, RIn2>( schedule: Schedule.Schedule<X, E, RIn2> ): <ROut, RIn>(self: Layer<ROut, E, RIn>) => Layer<ROut, E, RIn2 | RIn> <ROut, E, RIn, X, RIn2>( self: Layer<ROut, E, RIn>, schedule: Schedule.Schedule<X, E, RIn2> ): Layer<ROut, E, RIn | RIn2> } = 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<Scope.CloseableScope> = internal.scope /** * Constructs a layer from the specified scoped effect. * * @since 2.0.0 * @category constructors */ export const scoped: { <T extends Context.Tag<any, any>>( tag: T ): <E, R>( effect: Effect.Effect<Context.Tag.Service<T>, E, R> ) => Layer<Context.Tag.Identifier<T>, E, Exclude<R, Scope.Scope>> <T extends Context.Tag<any, any>, E, R>( tag: T, effect: Effect.Effect<Context.Tag.Service<T>, E, R> ): Layer<Context.Tag.Identifier<T>, E, Exclude<R, Scope.Scope>> } = internal.scoped /** * Constructs a layer from the specified scoped effect. * * @since 2.0.0 * @category constructors */ export const scopedDiscard: <X, E, R>(effect: Effect.Effect<X, E, R>) => Layer<never, E, Exclude<R, Scope.Scope>> = 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: <A, E, R>( effect: Effect.Effect<Context.Context<A>, E, R> ) => Layer<A, E, Exclude<R, Scope.Scope>> = internal.scopedContext /** * Constructs a layer that accesses and returns the specified service from the * context. * * @since 2.0.0 * @category constructors */ export const service: <T extends Context.Tag<any, any>>( tag: T ) => Layer<Context.Tag.Identifier<T>, never, Context.Tag.Identifier<T>> = internal.service /** * Constructs a layer from the specified value. * * @since 2.0.0 * @category constructors */ export const succeed: { <T extends Context.Tag<any, any>>( tag: T ): (resource: Context.Tag.Service<T>) => Layer<Context.Tag.Identifier<T>> <T extends Context.Tag<any, any>>( tag: T, resource: Context.Tag.Service<T> ): Layer<Context.Tag.Identifier<T>> } = 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: <A>(context: Context.Context<A>) => Layer<A> = 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: <RIn, E, ROut>(evaluate: LazyArg<Layer<ROut, E, RIn>>) => Layer<ROut, E, RIn> = internal.suspend /** * Lazily constructs a layer from the specified value. * * @since 2.0.0 * @category constructors */ export const sync: { <T extends Context.Tag<any, any>>( tag: T ): (evaluate: LazyArg<Context.Tag.Service<T>>) => Layer<Context.Tag.Identifier<T>> <T extends Context.Tag<any, any>>( tag: T, evaluate: LazyArg<Context.Tag.Service<T>> ): Layer<Context.Tag.Identifier<T>> } = 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: <A>(evaluate: LazyArg<Context.Context<A>>) => Layer<A> = internal.syncContext /** * Performs the specified effect if this layer succeeds. * * @since 2.0.0 * @category sequencing */ export const tap: { <ROut, XR extends ROut, RIn2, E2, X>( f: (context: Context.Context<XR>) => Effect.Effect<X, E2, RIn2> ): <RIn, E>(self: Layer<ROut, E, RIn>) => Layer<ROut, E2 | E, RIn2 | RIn> <RIn, E, ROut, XR extends ROut, RIn2, E2, X>( self: Layer<ROut, E, RIn>, f: (context: Context.Context<XR>) => Effect.Effect<X, E2, RIn2> ): Layer<ROut, E | E2, RIn | RIn2> } = internal.tap /** * Performs the specified effect if this layer fails. * * @since 2.0.0 * @category sequencing */ export const tapError: { <E, XE extends E, RIn2, E2, X>( f: (e: XE) => Effect.Effect<X, E2, RIn2> ): <RIn, ROut>(self: Layer<ROut, E, RIn>) => Layer<ROut, E | E2, RIn2 | RIn> <RIn, E, XE extends E, ROut, RIn2, E2, X>( self: Layer<ROut, E, RIn>, f: (e: XE) => Effect.Effect<X, E2, RIn2> ): Layer<ROut, E | E2, RIn | RIn2> } = internal.tapError /** * Performs the specified effect if this layer fails. * * @since 2.0.0 * @category sequencing */ export const tapErrorCause: { <E, XE extends E, RIn2, E2, X>( f: (cause: Cause.Cause<XE>) => Effect.Effect<X, E2, RIn2> ): <RIn, ROut>(self: Layer<ROut, E, RIn>) => Layer<ROut, E | E2, RIn2 | RIn> <RIn, E, XE extends E, ROut, RIn2, E2, X>( self: Layer<ROut, E, RIn>, f: (cause: Cause.Cause<XE>) => Effect.Effect<X, E2, RIn2> ): Layer<ROut, E | E2, RIn | RIn2> } = 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: <RIn, E, ROut>( self: Layer<ROut, E, RIn> ) => Effect.Effect<Runtime.Runtime<ROut>, 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: { ( memoMap: MemoMap ): <RIn, E, ROut>(self: Layer<ROut, E, RIn>) => Effect.Effect<Runtime.Runtime<ROut>, E, Scope.Scope | RIn> <RIn, E, ROut>( self: Layer<ROut, E, RIn>, memoMap: MemoMap ): Effect.Effect<Runtime.Runtime<ROut>, 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: { <RIn, E, ROut>( self: Layer<ROut, E, RIn> ): <RIn2, E2, ROut2>(that: Layer<ROut2, E2, RIn2>) => Layer<ROut2, E | E2, RIn | Exclude<RIn2, ROut>> <RIn2, E2, ROut2, RIn, E, ROut>( that: Layer<ROut2, E2, RIn2>, self: Layer<ROut, E, RIn> ): Layer<ROut2, E2 | E, RIn | Exclude<RIn2, ROut>> } = 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: { <RIn, E, ROut>( self: Layer<ROut, E, RIn> ): <RIn2, E2, ROut2>(that: Layer<ROut2, E2, RIn2>) => Layer<ROut | ROut2, E | E2, RIn | Exclude<RIn2, ROut>> <RIn2, E2, ROut2, RIn, E, ROut>( that: Layer<ROut2, E2, RIn2>, self: Layer<ROut, E, RIn> ): Layer<ROut2 | ROut, E2 | E, RIn | Exclude<RIn2, ROut>> } = 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: { <B, E2, R2, A, C>( that: Layer<B, E2, R2>, f: (a: Context.Context<A>, b: Context.Context<B>) => Context.Context<C> ): <E, R>(self: Layer<A, E, R>) => Layer<C, E2 | E, R2 | R> <A, E, R, B, E2, R2, C>( self: Layer<A, E, R>, that: Layer<B, E2, R2>, f: (a: Context.Context<A>, b: Context.Context<B>) => Context.Context<C> ): Layer<C, E | E2, R | R2> } = internal.zipWith /** * @since 2.0.0 * @category utils */ export const unwrapEffect: <A, E1, R1, E, R>(self: Effect.Effect<Layer<A, E1, R1>, E, R>) => Layer<A, E | E1, R | R1> = internal.unwrapEffect /** * @since 2.0.0 * @category utils */ export const unwrapScoped: <A, E1, R1, E, R>( self: Effect.Effect<Layer<A, E1, R1>, E, R> ) => Layer<A, E | E1, R1 | Exclude<R, Scope.Scope>> = internal.unwrapScoped /** * @since 2.0.0 * @category clock */ export const setClock: <A extends Clock.Clock>(clock: A) => Layer<never> = <A extends Clock.Clock>( clock: A ): Layer<never> => 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<never> = circularLayer.setConfigProvider /** * Adds the provided span to the span stack. * * @since 2.0.0 * @category tracing */ export const parentSpan: (span: Tracer.ParentSpan) => Layer<Tracer.ParentSpan> = circularLayer.parentSpan /** * @since 2.0.0 * @category requests & batching */ export const setRequestBatching: (requestBatching: boolean) => Layer<never> = ( requestBatching: boolean ) => scopedDiscard( fiberRuntime.fiberRefLocallyScoped(core.currentRequestBatching, requestBatching) ) /** * @since 2.0.0 * @category requests & batching */ export const setRequestCaching: (requestCaching: boolean) => Layer<never> = ( requestCaching: boolean ) => scopedDiscard( fiberRuntime.fiberRefLocallyScoped(query.currentCacheEnabled, requestCaching) ) /** * @since 2.0.0 * @category requests & batching */ export const setRequestCache: { <E, R>( cache: Effect.Effect<Request.Cache, E, R> ): Layer<never, E, Exclude<R, Scope.Scope>> ( cache: Request.Cache ): Layer<never> } = (<E, R>(cache: Request.Cache | Effect.Effect<Request.Cache, E, R>) => 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<never> = ( scheduler: Scheduler.Scheduler ): Layer<never> => 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?: { readonly attributes?: Record<string, unknown> | undefined readonly links?: ReadonlyArray<Tracer.SpanLink> | undefined readonly parent?: Tracer.ParentSpan | undefined readonly root?: boolean | undefined readonly context?: Context.Context<never> | undefined readonly onEnd?: | ((span: Tracer.Span, exit: Exit.Exit<unknown, unknown>) => Effect.Effect<void>) | undefined } ) => Layer<Tracer.ParentSpan> = circularLayer.span /** * Create a Layer that sets the current Tracer * * @since 2.0.0 * @category tracing */ export const setTracer: (tracer: Tracer.Tracer) => Layer<never> = circularLayer.setTracer /** * @since 2.0.0 * @category tracing */ export const setTracerEnabled: (enabled: boolean) => Layer<never> = (enabled: boolean) => scopedDiscard( fiberRuntime.fiberRefLocallyScoped(core.currentTracerEnabled, enabled) ) /** * @since 2.0.0 * @category tracing */ export const setTracerTiming: (enabled: boolean) => Layer<never> = (enabled: boolean) => scopedDiscard( fiberRuntime.fiberRefLocallyScoped(core.currentTracerTimingEnabled, enabled) ) /** * @since 2.0.0 * @category logging */ export const setUnhandledErrorLogLevel: (level: Option.Option<LogLevel>) => Layer<never> = ( level: Option.Option<LogLevel> ): Layer<never> => scopedDiscard( fiberRuntime.fiberRefLocallyScoped(core.currentUnhandledErrorLogLevel, level) ) /** * @since 2.0.0 * @category tracing */ export const withSpan: { ( name: string, options?: { readonly attributes?: Record<string, unknown> | undefined readonly links?: ReadonlyArray<Tracer.SpanLink> | undefined readonly parent?: Tracer.ParentSpan | undefined readonly root?: boolean | undefined readonly context?: Context.Context<never> | undefined readonly onEnd?: | ((span: Tracer.Span, exit: Exit.Exit<unknown, unknown>) => Effect.Effect<void>) | undefined } ): <A, E, R>(self: Layer<A, E, R>) => Layer<A, E, Exclude<R, Tracer.ParentSpan>> <A, E, R>( self: Layer<A, E, R>, name: string, options?: { readonly attributes?: Record<string, unknown> | undefined readonly links?: ReadonlyArray<Tracer.SpanLink> | undefined readonly parent?: Tracer.ParentSpan | undefined readonly root?: boolean | undefined readonly context?: Context.Context<never> | undefined readonly onEnd?: | ((span: Tracer.Span, exit: Exit.Exit<unknown, unknown>) => Effect.Effect<void>) | undefined } ): Layer<A, E, Exclude<R, Tracer.ParentSpan>> } = internal.withSpan /** * @since 2.0.0 * @category tracing */ export const withParentSpan: { (span: Tracer.ParentSpan): <A, E, R>(self: Layer<A, E, R>) => Layer<A, E, Exclude<R, Tracer.ParentSpan>> <A, E, R>(self: Layer<A, E, R>, span: Tracer.ParentSpan): Layer<A, E, Exclude<R, Tracer.ParentSpan>> } = 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<MemoMap> = 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: { ( memoMap: MemoMap, scope: Scope.Scope ): <RIn, E, ROut>(self: Layer<ROut, E, RIn>) => Effect.Effect<Context.Context<ROut>, E, RIn> <RIn, E, ROut>( self: Layer<ROut, E, RIn>, memoMap: MemoMap, scope: Scope.Scope ): Effect.Effect<Context.Context<ROut>, E, RIn> } = internal.buildWithMemoMap