<
I,
E,
R,
X,
const Preload extends boolean = never,
SE = never,
SR = never
>(
layer: Layer.Layer<I, E, R>,
options?:
| {
readonly idleTimeToLive?: Duration.Input | undefined
readonly preload?: Preload | undefined
readonly invalidationSchedule?:
| Schedule.Schedule<X, unknown, SE, SR>
| undefined
}
| undefined
): Effect.Effect<
LayerRef<I, E>,
[Preload] extends [true] ? E : never,
Scope.Scope | R | SR
>Creates a LayerRef from a Layer.
When to use
Use when you have one layer-built resource that should be shared, optionally kept alive while idle, and refreshed on demand.
Details
The layer is built lazily on first use unless preload is true.
idleTimeToLive keeps the context cached after it stops being used, and
invalidationSchedule can periodically invalidate it. When preload is
true, scheduled invalidation also reacquires the context.
Gotchas
Invalidation does not revoke contexts already borrowed by active scopes; those contexts remain usable until their scopes close.
Example (Sharing one layer-built service)
import { Context, Effect, Layer, LayerRef } from "effect"
class Database extends Context.Service<Database, {
readonly query: Effect.Effect<string>
}>()("Database") {}
const databaseLayer = Layer.succeed(Database, {
query: Effect.succeed("result")
})
const query = Effect.gen(function*() {
const database = yield* Database
return yield* database.query
})
const program = Effect.scoped(
Effect.gen(function*() {
const ref = yield* LayerRef.make(databaseLayer, {
idleTimeToLive: "5 seconds"
})
const result = yield* Effect.provide(query, ref.get)
yield* ref.invalidate
return result
})
)export const const make: <
I,
E,
R,
X,
Preload extends boolean = never,
SE = never,
SR = never
>(
layer: Layer.Layer<I, E, R>,
options?:
| {
readonly idleTimeToLive?:
| Duration.Input
| undefined
readonly preload?: Preload | undefined
readonly invalidationSchedule?:
| Schedule.Schedule<X, unknown, SE, SR>
| undefined
}
| undefined
) => Effect.Effect<
LayerRef<I, E>,
[Preload] extends [true] ? E : never,
Scope.Scope | R | SR
>
Creates a LayerRef from a Layer.
When to use
Use when you have one layer-built resource that should be shared, optionally
kept alive while idle, and refreshed on demand.
Details
The layer is built lazily on first use unless preload is true.
idleTimeToLive keeps the context cached after it stops being used, and
invalidationSchedule can periodically invalidate it. When preload is
true, scheduled invalidation also reacquires the context.
Gotchas
Invalidation does not revoke contexts already borrowed by active scopes; those
contexts remain usable until their scopes close.
Example (Sharing one layer-built service)
import { Context, Effect, Layer, LayerRef } from "effect"
class Database extends Context.Service<Database, {
readonly query: Effect.Effect<string>
}>()("Database") {}
const databaseLayer = Layer.succeed(Database, {
query: Effect.succeed("result")
})
const query = Effect.gen(function*() {
const database = yield* Database
return yield* database.query
})
const program = Effect.scoped(
Effect.gen(function*() {
const ref = yield* LayerRef.make(databaseLayer, {
idleTimeToLive: "5 seconds"
})
const result = yield* Effect.provide(query, ref.get)
yield* ref.invalidate
return result
})
)
make = import EffectEffect.const fnUntraced: <Effect.Effect<any, [Preload] extends [true] ? E : never, Scope.Scope | R | SR>, LayerRef<I, E>, [layer: Layer.Layer<I, E, R>, options?: {
readonly idleTimeToLive?: Duration.Input | undefined;
readonly preload?: Preload | undefined;
readonly invalidationSchedule?: Schedule.Schedule<X, unknown, SE, SR> | undefined;
} | undefined]>(body: (this: unassigned, layer: Layer.Layer<I, E, R>, options?: {
readonly idleTimeToLive?: Duration.Input | undefined;
readonly preload?: Preload | undefined;
readonly invalidationSchedule?: Schedule.Schedule<X, unknown, SE, SR> | undefined;
} | undefined) => Generator<...>) => <I, E, R, X, const Preload extends boolean = never, SE = never, SR = never>(layer: Layer.Layer<...>, options?: {
readonly idleTimeToLive?: Duration.Input | undefined;
readonly preload?: Preload | undefined;
readonly invalidationSchedule?: Schedule.Schedule<X, unknown, SE, SR> | undefined;
} | undefined) => Effect.Effect<...> (+41 overloads)
fnUntraced(
function*<function (type parameter) I in <I, E, R, X, const Preload extends boolean = never, SE = never, SR = never>(layer: Layer.Layer<I, E, R>, options?: {
readonly idleTimeToLive?: Duration.Input | undefined;
readonly preload?: Preload | undefined;
readonly invalidationSchedule?: Schedule.Schedule<X, unknown, SE, SR> | undefined;
} | undefined): Effect.fn.Return<LayerRef<I, E>, [Preload] extends [true] ? E : never, Scope.Scope | R | SR>
I, function (type parameter) E in <I, E, R, X, const Preload extends boolean = never, SE = never, SR = never>(layer: Layer.Layer<I, E, R>, options?: {
readonly idleTimeToLive?: Duration.Input | undefined;
readonly preload?: Preload | undefined;
readonly invalidationSchedule?: Schedule.Schedule<X, unknown, SE, SR> | undefined;
} | undefined): Effect.fn.Return<LayerRef<I, E>, [Preload] extends [true] ? E : never, Scope.Scope | R | SR>
E, function (type parameter) R in <I, E, R, X, const Preload extends boolean = never, SE = never, SR = never>(layer: Layer.Layer<I, E, R>, options?: {
readonly idleTimeToLive?: Duration.Input | undefined;
readonly preload?: Preload | undefined;
readonly invalidationSchedule?: Schedule.Schedule<X, unknown, SE, SR> | undefined;
} | undefined): Effect.fn.Return<LayerRef<I, E>, [Preload] extends [true] ? E : never, Scope.Scope | R | SR>
R, function (type parameter) X in <I, E, R, X, const Preload extends boolean = never, SE = never, SR = never>(layer: Layer.Layer<I, E, R>, options?: {
readonly idleTimeToLive?: Duration.Input | undefined;
readonly preload?: Preload | undefined;
readonly invalidationSchedule?: Schedule.Schedule<X, unknown, SE, SR> | undefined;
} | undefined): Effect.fn.Return<LayerRef<I, E>, [Preload] extends [true] ? E : never, Scope.Scope | R | SR>
X, const function (type parameter) Preload in <I, E, R, X, const Preload extends boolean = never, SE = never, SR = never>(layer: Layer.Layer<I, E, R>, options?: {
readonly idleTimeToLive?: Duration.Input | undefined;
readonly preload?: Preload | undefined;
readonly invalidationSchedule?: Schedule.Schedule<X, unknown, SE, SR> | undefined;
} | undefined): Effect.fn.Return<LayerRef<I, E>, [Preload] extends [true] ? E : never, Scope.Scope | R | SR>
Preload extends boolean = never, function (type parameter) SE in <I, E, R, X, const Preload extends boolean = never, SE = never, SR = never>(layer: Layer.Layer<I, E, R>, options?: {
readonly idleTimeToLive?: Duration.Input | undefined;
readonly preload?: Preload | undefined;
readonly invalidationSchedule?: Schedule.Schedule<X, unknown, SE, SR> | undefined;
} | undefined): Effect.fn.Return<LayerRef<I, E>, [Preload] extends [true] ? E : never, Scope.Scope | R | SR>
SE = never, function (type parameter) SR in <I, E, R, X, const Preload extends boolean = never, SE = never, SR = never>(layer: Layer.Layer<I, E, R>, options?: {
readonly idleTimeToLive?: Duration.Input | undefined;
readonly preload?: Preload | undefined;
readonly invalidationSchedule?: Schedule.Schedule<X, unknown, SE, SR> | undefined;
} | undefined): Effect.fn.Return<LayerRef<I, E>, [Preload] extends [true] ? E : never, Scope.Scope | R | SR>
SR = never>(
layer: Layer.Layer<I, E, R>(parameter) layer: {
build: (memoMap: MemoMap, scope: Scope.Scope) => Effect<Context.Context<I>, E, R>;
pipe: { <A>(this: A): A; <A, B = never>(this: A, ab: (_: A) => B): B; <A, B = never, C = never>(this: A, ab: (_: A) => B, bc: (_: B) => C): C; <A, B = never, C = never, D = never>(this: A, ab: (_: A) => B, bc: (_: B) => C, cd: (_: C) => D): D; <…;
}
layer: import LayerLayer.interface Layer<in ROut, out E = never, out RIn = never>A Layer describes how to build one or more services for dependency injection.
When to use
Use to model construction of application services for dependency injection,
especially when services have dependencies, can fail during construction, or
need scoped setup and release.
Details
A Layer<ROut, E, RIn> represents ROut as the services this layer
provides, E as the possible errors during layer construction, and RIn as
the services this layer requires as dependencies.
Layer<function (type parameter) I in <I, E, R, X, const Preload extends boolean = never, SE = never, SR = never>(layer: Layer.Layer<I, E, R>, options?: {
readonly idleTimeToLive?: Duration.Input | undefined;
readonly preload?: Preload | undefined;
readonly invalidationSchedule?: Schedule.Schedule<X, unknown, SE, SR> | undefined;
} | undefined): Effect.fn.Return<LayerRef<I, E>, [Preload] extends [true] ? E : never, Scope.Scope | R | SR>
I, function (type parameter) E in <I, E, R, X, const Preload extends boolean = never, SE = never, SR = never>(layer: Layer.Layer<I, E, R>, options?: {
readonly idleTimeToLive?: Duration.Input | undefined;
readonly preload?: Preload | undefined;
readonly invalidationSchedule?: Schedule.Schedule<X, unknown, SE, SR> | undefined;
} | undefined): Effect.fn.Return<LayerRef<I, E>, [Preload] extends [true] ? E : never, Scope.Scope | R | SR>
E, function (type parameter) R in <I, E, R, X, const Preload extends boolean = never, SE = never, SR = never>(layer: Layer.Layer<I, E, R>, options?: {
readonly idleTimeToLive?: Duration.Input | undefined;
readonly preload?: Preload | undefined;
readonly invalidationSchedule?: Schedule.Schedule<X, unknown, SE, SR> | undefined;
} | undefined): Effect.fn.Return<LayerRef<I, E>, [Preload] extends [true] ? E : never, Scope.Scope | R | SR>
R>,
options: | {
readonly idleTimeToLive?:
| Duration.Input
| undefined
readonly preload?: Preload | undefined
readonly invalidationSchedule?:
| Schedule.Schedule<X, unknown, SE, SR>
| undefined
}
| undefined
options?: {
/**
* Duration to keep the resource alive after it is no longer used.
*/
readonly idleTimeToLive?: Duration.Input | undefinedDuration to keep the resource alive after it is no longer used.
idleTimeToLive?: import DurationDuration.type Input =
| number
| bigint
| Duration.Duration
| readonly [seconds: number, nanos: number]
| `${number} nano`
| `${number} nanos`
| `${number} micro`
| `${number} micros`
| `${number} milli`
| `${number} millis`
| `${number} second`
| `${number} seconds`
| `${number} minute`
| `${number} minutes`
| `${number} hour`
| `${number} hours`
| `${number} day`
| `${number} days`
| `${number} week`
| `${number} weeks`
| "Infinity"
| "-Infinity"
| Duration.DurationObject
Valid input types that can be converted to a Duration.
When to use
Use when an API should accept any value that Effect can convert into a
Duration, including existing durations, millisecond numbers, nanosecond
bigints, high-resolution tuples, duration strings, infinity strings, or
duration objects.
Details
String inputs accept values like "10 seconds", "500 millis",
"Infinity", and "-Infinity". Finite fractional values that are
normalized to nanoseconds are rounded to the nearest nanosecond, with ties
away from zero.
Input | undefined
/**
* Whether to acquire the resource during creation.
*/
readonly preload?: Preload | undefinedWhether to acquire the resource during creation.
preload?: function (type parameter) Preload in <I, E, R, X, const Preload extends boolean = never, SE = never, SR = never>(layer: Layer.Layer<I, E, R>, options?: {
readonly idleTimeToLive?: Duration.Input | undefined;
readonly preload?: Preload | undefined;
readonly invalidationSchedule?: Schedule.Schedule<X, unknown, SE, SR> | undefined;
} | undefined): Effect.fn.Return<LayerRef<I, E>, [Preload] extends [true] ? E : never, Scope.Scope | R | SR>
Preload | undefined
/**
* Schedule used to invalidate the cached resource. When `preload` is
* `true`, each scheduled invalidation also reacquires the resource.
*/
readonly invalidationSchedule?: | Schedule.Schedule<X, unknown, SE, SR>
| undefined
Schedule used to invalidate the cached resource. When preload is
true, each scheduled invalidation also reacquires the resource.
invalidationSchedule?: import ScheduleSchedule.interface Schedule<out Output, in Input = unknown, out Error = never, out Env = never>A Schedule defines a strategy for repeating or retrying effects based on some policy.
Example (Defining retry and repeat schedules)
import { Console, Data, Effect, Schedule } from "effect"
class NetworkError extends Data.TaggedError("NetworkError")<{
readonly attempt: number
}> {}
// Basic retry schedule - retry up to 3 times with exponential backoff
const retrySchedule = Schedule.max([
Schedule.exponential("100 millis"),
Schedule.recurs(3)
])
// Basic repeat schedule - repeat every 30 seconds forever
const repeatSchedule: Schedule.Schedule<number, unknown, never> = Schedule
.spaced("30 seconds")
const program = Effect.gen(function*() {
let attempts = 0
const result1 = yield* Effect.retry(
Effect.gen(function*() {
attempts++
if (attempts < 3) {
return yield* Effect.fail(new NetworkError({ attempt: attempts }))
}
return "Success"
}),
retrySchedule
)
console.log(result1) // "Success"
yield* Console.log("heartbeat").pipe(
Effect.repeat(repeatSchedule.pipe(Schedule.upTo({ times: 5 })))
)
})
The Schedule namespace contains types and utilities for working with schedules.
Schedule<function (type parameter) X in <I, E, R, X, const Preload extends boolean = never, SE = never, SR = never>(layer: Layer.Layer<I, E, R>, options?: {
readonly idleTimeToLive?: Duration.Input | undefined;
readonly preload?: Preload | undefined;
readonly invalidationSchedule?: Schedule.Schedule<X, unknown, SE, SR> | undefined;
} | undefined): Effect.fn.Return<LayerRef<I, E>, [Preload] extends [true] ? E : never, Scope.Scope | R | SR>
X, unknown, function (type parameter) SE in <I, E, R, X, const Preload extends boolean = never, SE = never, SR = never>(layer: Layer.Layer<I, E, R>, options?: {
readonly idleTimeToLive?: Duration.Input | undefined;
readonly preload?: Preload | undefined;
readonly invalidationSchedule?: Schedule.Schedule<X, unknown, SE, SR> | undefined;
} | undefined): Effect.fn.Return<LayerRef<I, E>, [Preload] extends [true] ? E : never, Scope.Scope | R | SR>
SE, function (type parameter) SR in <I, E, R, X, const Preload extends boolean = never, SE = never, SR = never>(layer: Layer.Layer<I, E, R>, options?: {
readonly idleTimeToLive?: Duration.Input | undefined;
readonly preload?: Preload | undefined;
readonly invalidationSchedule?: Schedule.Schedule<X, unknown, SE, SR> | undefined;
} | undefined): Effect.fn.Return<LayerRef<I, E>, [Preload] extends [true] ? E : never, Scope.Scope | R | SR>
SR> | undefined
} | undefined
): import EffectEffect.fn.type fn.Return<A, E = never, R = never> = Generator<Effect.Effect<any, E, R>, A, any>Generator return type accepted by
fn
and
fnUntraced
.
When to use
Use when you need to annotate the return type of a generator body while
keeping the produced function's Effect return type inferred.
Example (Annotating an Effect function)
import { Effect } from "effect"
const f = Effect.fnUntraced(function*(
value: string
): Effect.fn.Return<number> {
return yield* Effect.succeed(value.length)
})
// ┌─── Effect.Effect<number>
// ▼
const program = f("hello")
Example (Annotating a parametric Effect function)
import { Effect } from "effect"
const f = Effect.fnUntraced(function*<A>(
value: A
): Effect.fn.Return<A> {
return yield* Effect.succeed(value)
})
// ┌─── Effect.Effect<string>
// ▼
const program = f("hello")
Return<
interface LayerRef<in out I, in out E = never>A refreshable reference to a single layer-built service context.
When to use
Use when you want to share one scoped layer resource across many users while
retaining the ability to invalidate it and rebuild it later.
Details
A LayerRef is the unkeyed counterpart to a layer cache: it lazily builds the
layer on first use, reuses the resulting context while it is borrowed or kept
idle, and can invalidate the cached context so the next use rebuilds it.
LayerRef<function (type parameter) I in <I, E, R, X, const Preload extends boolean = never, SE = never, SR = never>(layer: Layer.Layer<I, E, R>, options?: {
readonly idleTimeToLive?: Duration.Input | undefined;
readonly preload?: Preload | undefined;
readonly invalidationSchedule?: Schedule.Schedule<X, unknown, SE, SR> | undefined;
} | undefined): Effect.fn.Return<LayerRef<I, E>, [Preload] extends [true] ? E : never, Scope.Scope | R | SR>
I, function (type parameter) E in <I, E, R, X, const Preload extends boolean = never, SE = never, SR = never>(layer: Layer.Layer<I, E, R>, options?: {
readonly idleTimeToLive?: Duration.Input | undefined;
readonly preload?: Preload | undefined;
readonly invalidationSchedule?: Schedule.Schedule<X, unknown, SE, SR> | undefined;
} | undefined): Effect.fn.Return<LayerRef<I, E>, [Preload] extends [true] ? E : never, Scope.Scope | R | SR>
E>,
[function (type parameter) Preload in <I, E, R, X, const Preload extends boolean = never, SE = never, SR = never>(layer: Layer.Layer<I, E, R>, options?: {
readonly idleTimeToLive?: Duration.Input | undefined;
readonly preload?: Preload | undefined;
readonly invalidationSchedule?: Schedule.Schedule<X, unknown, SE, SR> | undefined;
} | undefined): Effect.fn.Return<LayerRef<I, E>, [Preload] extends [true] ? E : never, Scope.Scope | R | SR>
Preload] extends [true] ? function (type parameter) E in <I, E, R, X, const Preload extends boolean = never, SE = never, SR = never>(layer: Layer.Layer<I, E, R>, options?: {
readonly idleTimeToLive?: Duration.Input | undefined;
readonly preload?: Preload | undefined;
readonly invalidationSchedule?: Schedule.Schedule<X, unknown, SE, SR> | undefined;
} | undefined): Effect.fn.Return<LayerRef<I, E>, [Preload] extends [true] ? E : never, Scope.Scope | R | SR>
E : never,
import ScopeScope.Scope | function (type parameter) R in <I, E, R, X, const Preload extends boolean = never, SE = never, SR = never>(layer: Layer.Layer<I, E, R>, options?: {
readonly idleTimeToLive?: Duration.Input | undefined;
readonly preload?: Preload | undefined;
readonly invalidationSchedule?: Schedule.Schedule<X, unknown, SE, SR> | undefined;
} | undefined): Effect.fn.Return<LayerRef<I, E>, [Preload] extends [true] ? E : never, Scope.Scope | R | SR>
R | function (type parameter) SR in <I, E, R, X, const Preload extends boolean = never, SE = never, SR = never>(layer: Layer.Layer<I, E, R>, options?: {
readonly idleTimeToLive?: Duration.Input | undefined;
readonly preload?: Preload | undefined;
readonly invalidationSchedule?: Schedule.Schedule<X, unknown, SE, SR> | undefined;
} | undefined): Effect.fn.Return<LayerRef<I, E>, [Preload] extends [true] ? E : never, Scope.Scope | R | SR>
SR
> {
const const context: Context.Context<never>const context: {
mapUnsafe: ReadonlyMap<string, any>;
mutable: boolean;
pipe: { <A>(this: A): A; <A, B = never>(this: A, ab: (_: A) => B): B; <A, B = never, C = never>(this: A, ab: (_: A) => B, bc: (_: B) => C): C; <A, B = never, C = never, D = never>(this: A, ab: (_: A) => B, bc: (_: B) => C, cd: (_: C) => D): D; <…;
toString: () => string;
toJSON: () => unknown;
}
context = yield* import EffectEffect.const context: <R = never>() => Effect<
Context.Context<R>,
never,
R
>
Returns the complete context.
When to use
Use to read the complete Context available to the current effect.
Details
This function allows you to access all services that are currently available
in the effect's environment. This can be useful for debugging, introspection,
or when you need to pass the entire context to another function.
Example (Reading the full context)
import { Console, Context, Effect, Option } from "effect"
const Logger = Context.Service<{
log: (msg: string) => void
}>("Logger")
const Database = Context.Service<{
query: (sql: string) => string
}>("Database")
const program = Effect.gen(function*() {
const allServices = yield* Effect.context()
// Check if specific services are available
const loggerOption = Context.getOption(allServices, Logger)
const databaseOption = Context.getOption(allServices, Database)
yield* Console.log(`Logger available: ${Option.isSome(loggerOption)}`)
yield* Console.log(`Database available: ${Option.isSome(databaseOption)}`)
})
const context = Context.make(Logger, { log: console.log })
.pipe(Context.add(Database, { query: () => "result" }))
const provided = Effect.provideContext(program, context)
context<never>()
const const memoMap: Layer.MemoMapconst memoMap: {
get: <RIn, E, ROut>(layer: Layer<ROut, E, RIn>, scope: Scope.Scope) => Effect<Context.Context<ROut>, E, RIn> | undefined;
getOrElseMemoize: <RIn, E, ROut>(layer: Layer<ROut, E, RIn>, scope: Scope.Scope, build: (memoMap: MemoMap, scope: Scope.Scope) => Effect<Context.Context<ROut>, E, RIn>) => Effect<Context.Context<ROut>, E, RIn>;
}
memoMap = import LayerLayer.class CurrentMemoMapclass CurrentMemoMap {
key: Identifier;
Service: {
get: <RIn, E, ROut>(layer: Layer<ROut, E, RIn>, scope: Scope.Scope) => Effect<Context.Context<ROut>, E, RIn> | undefined;
getOrElseMemoize: <RIn, E, ROut>(layer: Layer<ROut, E, RIn>, scope: Scope.Scope, build: (memoMap: MemoMap, scope: Scope.Scope) => Effect<Context.Context<ROut>, E, RIn>) => Effect<Context.Context<ROut>, E, RIn>;
};
forkOrCreate: <Services>(self: Context.Context<Services>) => MemoMap;
of: (this: void, self: Layer.MemoMap) => Layer.MemoMap;
context: (self: Layer.MemoMap) => Context.Context<Layer.CurrentMemoMap>;
use: (f: (service: Layer.MemoMap) => Effect.Effect<A, E, R>) => Effect.Effect<A, E, Layer.CurrentMemoMap | R>;
useSync: (f: (service: Layer.MemoMap) => A) => Effect.Effect<A, never, Layer.CurrentMemoMap>;
Identifier: Identifier;
stack: string | undefined;
pipe: { <A>(this: A): A; <A, B = never>(this: A, ab: (_: A) => B): B; <A, B = never, C = never>(this: A, ab: (_: A) => B, bc: (_: B) => C): C; <A, B = never, C = never, D = never>(this: A, ab: (_: A) => B, bc: (_: B) => C, cd: (_: C) => D): D; <…;
toString: () => string;
toJSON: () => unknown;
}
Context service for the current MemoMap used in layer construction.
When to use
Use when building custom layer operations that need to access the current
memoization map from the fiber context.
Details
This service wraps a MemoMap as a Context.Service, making it available
for dependency injection during layer construction.
CurrentMemoMap.CurrentMemoMap.forkOrCreate<Services>(self: Context.Context<Services>): MemoMapforkOrCreate(const context: Context.Context<never>const context: {
mapUnsafe: ReadonlyMap<string, any>;
mutable: boolean;
pipe: { <A>(this: A): A; <A, B = never>(this: A, ab: (_: A) => B): B; <A, B = never, C = never>(this: A, ab: (_: A) => B, bc: (_: B) => C): C; <A, B = never, C = never, D = never>(this: A, ab: (_: A) => B, bc: (_: B) => C, cd: (_: C) => D): D; <…;
toString: () => string;
toJSON: () => unknown;
}
context)
const const rcRef: RcRef.RcRef<
Context.Context<I>,
E
>
const rcRef: {
pipe: { <A>(this: A): A; <A, B = never>(this: A, ab: (_: A) => B): B; <A, B = never, C = never>(this: A, ab: (_: A) => B, bc: (_: B) => C): C; <A, B = never, C = never, D = never>(this: A, ab: (_: A) => B, bc: (_: B) => C, cd: (_: C) => D): D; <…;
}
rcRef = yield* import RcRefRcRef.const make: <A, E, R>(options: {
readonly acquire: Effect.Effect<A, E, R>
readonly idleTimeToLive?:
| Duration.Input
| undefined
}) => Effect.Effect<RcRef<A, E>, never, R | Scope>
Creates an RcRef from an acquire effect.
When to use
Use to create a lazily acquired, reference-counted resource from an acquire
effect.
Details
The resource is acquired lazily on the first get and shared by subsequent
gets while it remains cached. Each get adds a reference to the current
Scope. When the last reference is released, the resource is closed
immediately by default, or after idleTimeToLive when that option is
provided.
Example (Creating a reference-counted resource)
import { Effect, RcRef } from "effect"
Effect.gen(function*() {
const ref = yield* RcRef.make({
acquire: Effect.acquireRelease(
Effect.succeed("foo"),
() => Effect.log("release foo")
)
})
// will only acquire the resource once, and release it
// when the scope is closed
yield* RcRef.get(ref).pipe(
Effect.andThen(RcRef.get(ref)),
Effect.scoped
)
})
make({
acquire: Effect.Effect<
Context.Context<I>,
E,
Scope.Scope | R
>
(property) acquire: {
pipe: { <A>(this: A): A; <A, B = never>(this: A, ab: (_: A) => B): B; <A, B = never, C = never>(this: A, ab: (_: A) => B, bc: (_: B) => C): C; <A, B = never, C = never, D = never>(this: A, ab: (_: A) => B, bc: (_: B) => C, cd: (_: C) => D): D; <…;
toString: () => string;
toJSON: () => unknown;
}
acquire: import EffectEffect.const contextWith: <R, A, E, R2>(
f: (
context: Context.Context<R>
) => Effect<A, E, R2>
) => Effect<A, E, R | R2>
Transforms the current context using the provided function.
When to use
Use to derive an effect from the complete Context.
Details
This function allows you to access the complete context and perform
computations based on all available services. This is useful when you need
to conditionally execute logic based on what services are available.
Example (Deriving values from the context)
import { Console, Context, Effect, Option } from "effect"
const Logger = Context.Service<{
log: (msg: string) => void
}>("Logger")
const Cache = Context.Service<{
get: (key: string) => string | null
}>("Cache")
const program = Effect.contextWith((services) => {
const cacheOption = Context.getOption(services, Cache)
const hasCache = Option.isSome(cacheOption)
if (hasCache) {
return Effect.gen(function*() {
const cache = yield* Effect.service(Cache)
yield* Console.log("Using cached data")
return cache.get("user:123") || "default"
})
} else {
return Effect.gen(function*() {
yield* Console.log("No cache available, using fallback")
return "fallback data"
})
}
})
const withCache = Effect.provideService(program, Cache, {
get: () => "cached_value"
})
contextWith((_: Context.Context<Scope.Scope>(parameter) _: {
mapUnsafe: ReadonlyMap<string, any>;
mutable: boolean;
pipe: { <A>(this: A): A; <A, B = never>(this: A, ab: (_: A) => B): B; <A, B = never, C = never>(this: A, ab: (_: A) => B, bc: (_: B) => C): C; <A, B = never, C = never, D = never>(this: A, ab: (_: A) => B, bc: (_: B) => C, cd: (_: C) => D): D; <…;
toString: () => string;
toJSON: () => unknown;
}
_: import ContextContext.interface Context<in Services>Immutable collection of service implementations used for dependency
injection in Effect programs.
Details
The type parameter tracks the service identifiers available in the context.
At runtime, services are stored by each key's string key.
Example (Creating a context with multiple services)
import { Context } from "effect"
// Create a context with multiple services
const Logger = Context.Service<{ log: (msg: string) => void }>("Logger")
const Database = Context.Service<{ query: (sql: string) => string }>(
"Database"
)
const context = Context.make(Logger, {
log: (msg: string) => console.log(msg)
})
.pipe(Context.add(Database, { query: (sql) => `Result: ${sql}` }))
Context<import ScopeScope.Scope>) =>
import LayerLayer.const buildWithMemoMap: {
(memoMap: MemoMap, scope: Scope.Scope): <
RIn,
E,
ROut
>(
self: Layer<ROut, E, RIn>
) => Effect<Context.Context<ROut>, E, RIn>
<RIn, E, ROut>(
self: Layer<ROut, E, RIn>,
memoMap: MemoMap,
scope: Scope.Scope
): Effect<Context.Context<ROut>, E, RIn>
}
buildWithMemoMap(layer: Layer.Layer<I, E, R>(parameter) layer: {
build: (memoMap: MemoMap, scope: Scope.Scope) => Effect<Context.Context<I>, E, R>;
pipe: { <A>(this: A): A; <A, B = never>(this: A, ab: (_: A) => B): B; <A, B = never, C = never>(this: A, ab: (_: A) => B, bc: (_: B) => C): C; <A, B = never, C = never, D = never>(this: A, ab: (_: A) => B, bc: (_: B) => C, cd: (_: C) => D): D; <…;
}
layer, const memoMap: Layer.MemoMapconst memoMap: {
get: <RIn, E, ROut>(layer: Layer<ROut, E, RIn>, scope: Scope.Scope) => Effect<Context.Context<ROut>, E, RIn> | undefined;
getOrElseMemoize: <RIn, E, ROut>(layer: Layer<ROut, E, RIn>, scope: Scope.Scope, build: (memoMap: MemoMap, scope: Scope.Scope) => Effect<Context.Context<ROut>, E, RIn>) => Effect<Context.Context<ROut>, E, RIn>;
}
memoMap, import ContextContext.const get: {
<Services, I extends Services, S>(
service: Key<I, S>
): (self: Context<Services>) => S
<Services, I extends Services, S>(
self: Context<Services>,
service: Key<I, S>
): S
}
get(_: Context.Context<Scope.Scope>(parameter) _: {
mapUnsafe: ReadonlyMap<string, any>;
mutable: boolean;
pipe: { <A>(this: A): A; <A, B = never>(this: A, ab: (_: A) => B): B; <A, B = never, C = never>(this: A, ab: (_: A) => B, bc: (_: B) => C): C; <A, B = never, C = never, D = never>(this: A, ab: (_: A) => B, bc: (_: B) => C, cd: (_: C) => D): D; <…;
toString: () => string;
toJSON: () => unknown;
}
_, import ScopeScope.const Scope: Context.Service<Scope, Scope>const Scope: {
key: string;
Service: {
strategy: "sequential" | "parallel";
state: State.Open | State.Closed | State.Empty;
};
of: (this: void, self: Scope.Scope) => Scope.Scope;
context: (self: Scope.Scope) => Context.Context<Scope.Scope>;
use: (f: (service: Scope.Scope) => Effect.Effect<A, E, R>) => Effect.Effect<A, E, Scope.Scope | R>;
useSync: (f: (service: Scope.Scope) => A) => Effect.Effect<A, never, Scope.Scope>;
Identifier: Identifier;
stack: string | undefined;
pipe: { <A>(this: A): A; <A, B = never>(this: A, ab: (_: A) => B): B; <A, B = never, C = never>(this: A, ab: (_: A) => B, bc: (_: B) => C): C; <A, B = never, C = never, D = never>(this: A, ab: (_: A) => B, bc: (_: B) => C, cd: (_: C) => D): D; <…;
toString: () => string;
toJSON: () => unknown;
}
A Scope represents a context where resources can be acquired and
automatically cleaned up when the scope is closed. Scopes can use
either sequential or parallel finalization strategies.
Example (Managing scoped resources)
import { Effect, Exit, Scope } from "effect"
const program = Effect.gen(function*() {
const scope = yield* Scope.make("sequential")
// Scope has a strategy and state
console.log(scope.strategy) // "sequential"
console.log(scope.state._tag) // "Open"
// Close the scope
yield* Scope.close(scope, Exit.void)
console.log(scope.state._tag) // "Closed"
})
Service tag for the active resource lifetime.
When to use
Use to access the active lifetime when registering finalizers or sharing
resources with the surrounding scope.
Example (Accessing the scope service)
import { Effect, Scope } from "effect"
const program = Effect.gen(function*() {
// Access the scope from the context
const scope = yield* Scope.Scope
// Use the scope for resource management
yield* Scope.addFinalizer(scope, Effect.log("Cleanup"))
})
// Provide a scope to the program
const scoped = Effect.scoped(program)
Scope))
),
idleTimeToLive?: Duration.Input | undefinedWhen the reference count reaches zero, the resource will be released
after this duration.
idleTimeToLive: options: | {
readonly idleTimeToLive?:
| Duration.Input
| undefined
readonly preload?: Preload | undefined
readonly invalidationSchedule?:
| Schedule.Schedule<X, unknown, SE, SR>
| undefined
}
| undefined
options?.idleTimeToLive?: Duration.Input | undefinedDuration to keep the resource alive after it is no longer used.
idleTimeToLive
})
const const refresh: Effect.Effect<
void,
E,
never
>
const refresh: {
pipe: { <A>(this: A): A; <A, B = never>(this: A, ab: (_: A) => B): B; <A, B = never, C = never>(this: A, ab: (_: A) => B, bc: (_: B) => C): C; <A, B = never, C = never, D = never>(this: A, ab: (_: A) => B, bc: (_: B) => C, cd: (_: C) => D): D; <…;
toString: () => string;
toJSON: () => unknown;
}
refresh = import RcRefRcRef.const invalidate: <A, E>(
self: RcRef<A, E>
) => Effect.Effect<void>
Invalidates the currently cached resource, if one has been acquired.
When to use
Use to force future RcRef.get calls to acquire a fresh resource when the
currently cached resource should no longer be reused.
Details
After invalidation, the next get acquires a fresh resource.
Gotchas
Invalidation does not revoke resources already borrowed by active scopes;
those remain usable until their scopes close.
invalidate(const rcRef: RcRef.RcRef<
Context.Context<I>,
E
>
const rcRef: {
pipe: { <A>(this: A): A; <A, B = never>(this: A, ab: (_: A) => B): B; <A, B = never, C = never>(this: A, ab: (_: A) => B, bc: (_: B) => C): C; <A, B = never, C = never, D = never>(this: A, ab: (_: A) => B, bc: (_: B) => C, cd: (_: C) => D): D; <…;
}
rcRef).Pipeable.pipe<Effect.Effect<void, never, never>, Effect.Effect<Context.Context<I>, E, never>, Effect.Effect<void, E, never>>(this: Effect.Effect<void, never, never>, ab: (_: Effect.Effect<void, never, never>) => Effect.Effect<Context.Context<I>, E, never>, bc: (_: Effect.Effect<Context.Context<I>, E, never>) => Effect.Effect<void, E, never>): Effect.Effect<void, E, never> (+21 overloads)pipe(
import EffectEffect.const andThen: {
<A, B, E2, R2>(
f: (a: A) => Effect<B, E2, R2>
): <E, R>(
self: Effect<A, E, R>
) => Effect<B, E | E2, R | R2>
<B, E2, R2>(f: Effect<B, E2, R2>): <A, E, R>(
self: Effect<A, E, R>
) => Effect<B, E | E2, R | R2>
<A, E, R, B, E2, R2>(
self: Effect<A, E, R>,
f: (a: A) => Effect<B, E2, R2>
): Effect<B, E | E2, R | R2>
<A, E, R, B, E2, R2>(
self: Effect<A, E, R>,
f: Effect<B, E2, R2>
): Effect<B, E | E2, R | R2>
}
andThen(import EffectEffect.const scoped: <A, E, R>(
self: Effect<A, E, R>
) => Effect<A, E, Exclude<R, Scope>>
Runs an effect with a scope that closes when the effect completes.
When to use
Use to acquire scoped resources for the duration of a single workflow.
Details
Finalizers for resources acquired inside the workflow run as soon as the
workflow completes, whether by success, failure, or interruption.
Example (Running a scoped acquisition)
import { Console, Effect } from "effect"
const resource = Effect.acquireRelease(
Console.log("Acquiring resource").pipe(Effect.as("resource")),
() => Console.log("Releasing resource")
)
const program = Effect.scoped(
Effect.gen(function*() {
const res = yield* resource
yield* Console.log(`Using ${res}`)
return res
})
)
Effect.runFork(program)
// Output: "Acquiring resource"
// Output: "Using resource"
// Output: "Releasing resource"
scoped(import RcRefRcRef.const get: <A, E>(
self: RcRef<A, E>
) => Effect.Effect<A, E, Scope>
Gets the value from an RcRef, acquiring it first if needed.
When to use
Use to borrow the current resource within a Scope, acquiring it first if
necessary.
Details
The reference count is incremented for the current Scope, and a release
finalizer is added to that scope. When the current scope closes, the
reference is released; the resource is closed when the final reference is
released, subject to any configured idle time-to-live.
Example (Sharing one acquired value)
import { Effect, RcRef } from "effect"
const program = Effect.gen(function*() {
// Create an RcRef with a resource
const ref = yield* RcRef.make({
acquire: Effect.acquireRelease(
Effect.succeed("shared resource"),
(resource) => Effect.log(`Releasing ${resource}`)
)
})
// Get the value from the RcRef
const value1 = yield* RcRef.get(ref)
const value2 = yield* RcRef.get(ref)
// Both values are the same instance
console.log(value1 === value2) // true
return value1
})
get(const rcRef: RcRef.RcRef<
Context.Context<I>,
E
>
const rcRef: {
pipe: { <A>(this: A): A; <A, B = never>(this: A, ab: (_: A) => B): B; <A, B = never, C = never>(this: A, ab: (_: A) => B, bc: (_: B) => C): C; <A, B = never, C = never, D = never>(this: A, ab: (_: A) => B, bc: (_: B) => C, cd: (_: C) => D): D; <…;
}
rcRef))),
import EffectEffect.const asVoid: <A, E, R>(
self: Effect<A, E, R>
) => Effect<void, E, R>
Maps the success value of an Effect to void, preserving failures.
Example (Discarding success values)
import { Effect } from "effect"
const program = Effect.asVoid(Effect.succeed(42))
Effect.runPromise(program).then(console.log)
// undefined (void)
asVoid
)
if (options: | {
readonly idleTimeToLive?:
| Duration.Input
| undefined
readonly preload?: Preload | undefined
readonly invalidationSchedule?:
| Schedule.Schedule<X, unknown, SE, SR>
| undefined
}
| undefined
options?.preload?: Preload | undefinedWhether to acquire the resource during creation.
preload) {
yield* const refresh: Effect.Effect<
void,
E,
never
>
const refresh: {
pipe: { <A>(this: A): A; <A, B = never>(this: A, ab: (_: A) => B): B; <A, B = never, C = never>(this: A, ab: (_: A) => B, bc: (_: B) => C): C; <A, B = never, C = never, D = never>(this: A, ab: (_: A) => B, bc: (_: B) => C, cd: (_: C) => D): D; <…;
toString: () => string;
toJSON: () => unknown;
}
refresh as import EffectEffect.interface Effect<out A, out E = never, out R = never>The Effect interface defines a value that lazily describes a workflow or
job. The workflow requires some context R, and may fail with an error of
type E, or succeed with a value of type A.
When to use
Use when you need to represent a lazy, composable workflow that can require
services, fail with a typed error, or succeed with a typed value.
Details
Effect values model resourceful interaction with the outside world,
including synchronous, asynchronous, concurrent, and parallel interaction.
They use a fiber-based concurrency model, with built-in support for
scheduling, fine-grained interruption, structured concurrency, and high
scalability.
To run an Effect value, you need a Runtime, which is a type that is
capable of executing Effect values.
Effect<void>
}
if (options: | {
readonly idleTimeToLive?:
| Duration.Input
| undefined
readonly preload?: Preload | undefined
readonly invalidationSchedule?:
| Schedule.Schedule<X, unknown, SE, SR>
| undefined
}
| undefined
options?.invalidationSchedule?: | Schedule.Schedule<X, unknown, SE, SR>
| undefined
Schedule used to invalidate the cached resource. When preload is
true, each scheduled invalidation also reacquires the resource.
invalidationSchedule) {
const const onRefresh: Effect.Effect<
void,
E,
never
>
const onRefresh: {
pipe: { <A>(this: A): A; <A, B = never>(this: A, ab: (_: A) => B): B; <A, B = never, C = never>(this: A, ab: (_: A) => B, bc: (_: B) => C): C; <A, B = never, C = never, D = never>(this: A, ab: (_: A) => B, bc: (_: B) => C, cd: (_: C) => D): D; <…;
toString: () => string;
toJSON: () => unknown;
}
onRefresh = options: | {
readonly idleTimeToLive?:
| Duration.Input
| undefined
readonly preload?: Preload | undefined
readonly invalidationSchedule?:
| Schedule.Schedule<X, unknown, SE, SR>
| undefined
}
| undefined
options.preload?: Preload | undefinedWhether to acquire the resource during creation.
preload ? const refresh: Effect.Effect<
void,
E,
never
>
const refresh: {
pipe: { <A>(this: A): A; <A, B = never>(this: A, ab: (_: A) => B): B; <A, B = never, C = never>(this: A, ab: (_: A) => B, bc: (_: B) => C): C; <A, B = never, C = never, D = never>(this: A, ab: (_: A) => B, bc: (_: B) => C, cd: (_: C) => D): D; <…;
toString: () => string;
toJSON: () => unknown;
}
refresh : import RcRefRcRef.const invalidate: <A, E>(
self: RcRef<A, E>
) => Effect.Effect<void>
Invalidates the currently cached resource, if one has been acquired.
When to use
Use to force future RcRef.get calls to acquire a fresh resource when the
currently cached resource should no longer be reused.
Details
After invalidation, the next get acquires a fresh resource.
Gotchas
Invalidation does not revoke resources already borrowed by active scopes;
those remain usable until their scopes close.
invalidate(const rcRef: RcRef.RcRef<
Context.Context<I>,
E
>
const rcRef: {
pipe: { <A>(this: A): A; <A, B = never>(this: A, ab: (_: A) => B): B; <A, B = never, C = never>(this: A, ab: (_: A) => B, bc: (_: B) => C): C; <A, B = never, C = never, D = never>(this: A, ab: (_: A) => B, bc: (_: B) => C, cd: (_: C) => D): D; <…;
}
rcRef)
yield* const onRefresh: Effect.Effect<
void,
E,
never
>
const onRefresh: {
pipe: { <A>(this: A): A; <A, B = never>(this: A, ab: (_: A) => B): B; <A, B = never, C = never>(this: A, ab: (_: A) => B, bc: (_: B) => C): C; <A, B = never, C = never, D = never>(this: A, ab: (_: A) => B, bc: (_: B) => C, cd: (_: C) => D): D; <…;
toString: () => string;
toJSON: () => unknown;
}
onRefresh.Pipeable.pipe<Effect.Effect<void, E, never>, Effect.Effect<void, never, never>, Effect.Effect<X, never, SR>, Effect.Effect<Fiber<X, never>, never, Scope.Scope | SR>>(this: Effect.Effect<...>, ab: (_: Effect.Effect<void, E, never>) => Effect.Effect<void, never, never>, bc: (_: Effect.Effect<void, never, never>) => Effect.Effect<X, never, SR>, cd: (_: Effect.Effect<X, never, SR>) => Effect.Effect<Fiber<X, never>, never, Scope.Scope | SR>): Effect.Effect<...> (+21 overloads)pipe(
import EffectEffect.const ignoreCause: <
Arg extends
| Effect<any, any, any>
| {
readonly log?:
| boolean
| Severity
| undefined
readonly message?: string | undefined
}
| undefined = {
readonly log?: boolean | Severity | undefined
readonly message?: string | undefined
}
>(
effectOrOptions?: Arg,
options?:
| {
readonly log?:
| boolean
| Severity
| undefined
readonly message?: string | undefined
}
| undefined
) => [Arg] extends [
Effect<infer _A, infer _E, infer _R>
]
? Effect<void, never, _R>
: <A, E, R>(
self: Effect<A, E, R>
) => Effect<void, never, R>
Ignores the effect's failure cause, including defects and interruptions.
When to use
Use when a best-effort effect should never fail, even from defects or
interruption, and optional cause logging is enough.
Details
Use the log option to emit the full
Cause
when the effect fails,
and message to prepend a custom log message.
Example (Ignoring failures and logging causes)
import { Effect } from "effect"
const task = Effect.fail("boom")
const program = task.pipe(Effect.ignoreCause)
const programLog = task.pipe(Effect.ignoreCause({ log: true, message: "Ignoring failure cause" }))
ignoreCause,
import EffectEffect.const schedule: {
<Output, Error, Env>(
schedule: Schedule<
Output,
unknown,
Error,
Env
>
): <A, E, R>(
self: Effect<A, E, R>
) => Effect<Output, E, R | Env>
<A, E, R, Output, Error, Env>(
self: Effect<A, E, R>,
schedule: Schedule<
Output,
unknown,
Error,
Env
>
): Effect<Output, E, R | Env>
}
schedule(options: | {
readonly idleTimeToLive?:
| Duration.Input
| undefined
readonly preload?: Preload | undefined
readonly invalidationSchedule?:
| Schedule.Schedule<X, unknown, SE, SR>
| undefined
}
| undefined
options.invalidationSchedule?: | Schedule.Schedule<X, unknown, SE, SR>
| undefined
(property) invalidationSchedule?: {
pipe: { <A>(this: A): A; <A, B = never>(this: A, ab: (_: A) => B): B; <A, B = never, C = never>(this: A, ab: (_: A) => B, bc: (_: B) => C): C; <A, B = never, C = never, D = never>(this: A, ab: (_: A) => B, bc: (_: B) => C, cd: (_: C) => D): D; <…;
}
Schedule used to invalidate the cached resource. When preload is
true, each scheduled invalidation also reacquires the resource.
invalidationSchedule),
import EffectEffect.const forkScoped: <
Arg extends
| Effect<any, any, any>
| {
readonly startImmediately?:
| boolean
| undefined
readonly uninterruptible?:
| boolean
| "inherit"
| undefined
}
| undefined = {
readonly startImmediately?:
| boolean
| undefined
readonly uninterruptible?:
| boolean
| "inherit"
| undefined
}
>(
effectOrOptions?: Arg,
options?:
| {
readonly startImmediately?:
| boolean
| undefined
readonly uninterruptible?:
| boolean
| "inherit"
| undefined
}
| undefined
) => [Arg] extends [
Effect<infer _A, infer _E, infer _R>
]
? Effect<Fiber<_A, _E>, never, _R | Scope>
: <A, E, R>(
self: Effect<A, E, R>
) => Effect<Fiber<A, E>, never, R | Scope>
Forks the fiber in a Scope, interrupting it when the scope is closed.
Example (Forking into the current scope)
import { Effect } from "effect"
const backgroundTask = Effect.gen(function*() {
yield* Effect.sleep("5 seconds")
yield* Effect.log("Background task completed")
return "result"
})
const program = Effect.scoped(
Effect.gen(function*() {
const fiber = yield* backgroundTask.pipe(Effect.forkScoped)
// or fork a fiber that starts immediately:
yield* backgroundTask.pipe(Effect.forkScoped({ startImmediately: true }))
yield* Effect.log("Task forked in scope")
yield* Effect.sleep("1 second")
// Fiber will be interrupted when scope closes
return "scope completed"
})
)
forkScoped
)
}
return identity<LayerRef<I, any>>(a: LayerRef<I, any>): LayerRef<I, any>Returns its input argument unchanged.
When to use
Use to return a value unchanged where a function is required.
Example (Returning the same value)
import { identity } from "effect"
import * as assert from "node:assert"
assert.deepStrictEqual(identity(5), 5)
identity<interface LayerRef<in out I, in out E = never>A refreshable reference to a single layer-built service context.
When to use
Use when you want to share one scoped layer resource across many users while
retaining the ability to invalidate it and rebuild it later.
Details
A LayerRef is the unkeyed counterpart to a layer cache: it lazily builds the
layer on first use, reuses the resulting context while it is borrowed or kept
idle, and can invalidate the cached context so the next use rebuilds it.
LayerRef<function (type parameter) I in <I, E, R, X, const Preload extends boolean = never, SE = never, SR = never>(layer: Layer.Layer<I, E, R>, options?: {
readonly idleTimeToLive?: Duration.Input | undefined;
readonly preload?: Preload | undefined;
readonly invalidationSchedule?: Schedule.Schedule<X, unknown, SE, SR> | undefined;
} | undefined): Effect.fn.Return<LayerRef<I, E>, [Preload] extends [true] ? E : never, Scope.Scope | R | SR>
I, any>>({
[const TypeId: "~effect/LayerRef"TypeId]: const TypeId: "~effect/LayerRef"TypeId,
LayerRef<I, any>.rcRef: RcRef.RcRef<Context.Context<I>, E>(property) LayerRef<I, any>.rcRef: {
pipe: { <A>(this: A): A; <A, B = never>(this: A, ab: (_: A) => B): B; <A, B = never, C = never>(this: A, ab: (_: A) => B, bc: (_: B) => C): C; <A, B = never, C = never, D = never>(this: A, ab: (_: A) => B, bc: (_: B) => C, cd: (_: C) => D): D; <…;
}
The underlying reference-counted cache that stores the built context.
rcRef,
LayerRef<I, any>.get: Layer.Layer<I, E, never>(property) LayerRef<I, any>.get: {
build: (memoMap: MemoMap, scope: Scope.Scope) => Effect<Context.Context<I>, E, never>;
pipe: { <A>(this: A): A; <A, B = never>(this: A, ab: (_: A) => B): B; <A, B = never, C = never>(this: A, ab: (_: A) => B, bc: (_: B) => C): C; <A, B = never, C = never, D = never>(this: A, ab: (_: A) => B, bc: (_: B) => C, cd: (_: C) => D): D; <…;
}
Layer that provides the currently cached context, acquiring it if needed.
get: import LayerLayer.const effectContext: <A, E, R>(
effect: Effect<Context.Context<A>, E, R>
) => Layer<A, E, Exclude<R, Scope.Scope>>
Constructs a layer from an effect that produces all services in a Context.
When to use
Use when you need a Layer that effectfully constructs a Context with
multiple services.
Details
This allows you to create a Layer from an effectful computation that
returns multiple services. The Effect is executed in the scope of the
layer.
Example (Creating a layer from an effectful context)
import { Context, Effect, Layer } from "effect"
class Database extends Context.Service<
Database,
{ readonly query: (sql: string) => Effect.Effect<string> }
>()("Database") {}
const layer = Layer.effectContext(
Effect.succeed(Context.make(Database, {
query: (sql: string) => Effect.succeed(`Query: ${sql}`)
}))
)
effectContext(import RcRefRcRef.const get: <A, E>(
self: RcRef<A, E>
) => Effect.Effect<A, E, Scope>
Gets the value from an RcRef, acquiring it first if needed.
When to use
Use to borrow the current resource within a Scope, acquiring it first if
necessary.
Details
The reference count is incremented for the current Scope, and a release
finalizer is added to that scope. When the current scope closes, the
reference is released; the resource is closed when the final reference is
released, subject to any configured idle time-to-live.
Example (Sharing one acquired value)
import { Effect, RcRef } from "effect"
const program = Effect.gen(function*() {
// Create an RcRef with a resource
const ref = yield* RcRef.make({
acquire: Effect.acquireRelease(
Effect.succeed("shared resource"),
(resource) => Effect.log(`Releasing ${resource}`)
)
})
// Get the value from the RcRef
const value1 = yield* RcRef.get(ref)
const value2 = yield* RcRef.get(ref)
// Both values are the same instance
console.log(value1 === value2) // true
return value1
})
get(const rcRef: RcRef.RcRef<
Context.Context<I>,
E
>
const rcRef: {
pipe: { <A>(this: A): A; <A, B = never>(this: A, ab: (_: A) => B): B; <A, B = never, C = never>(this: A, ab: (_: A) => B, bc: (_: B) => C): C; <A, B = never, C = never, D = never>(this: A, ab: (_: A) => B, bc: (_: B) => C, cd: (_: C) => D): D; <…;
}
rcRef)),
LayerRef<I, any>.contextEffect: Effect.Effect<Context.Context<I>, E, Scope.Scope>(property) LayerRef<I, any>.contextEffect: {
pipe: { <A>(this: A): A; <A, B = never>(this: A, ab: (_: A) => B): B; <A, B = never, C = never>(this: A, ab: (_: A) => B, bc: (_: B) => C): C; <A, B = never, C = never, D = never>(this: A, ab: (_: A) => B, bc: (_: B) => C, cd: (_: C) => D): D; <…;
toString: () => string;
toJSON: () => unknown;
}
Scoped effect that retrieves the currently cached context, acquiring it if needed.
contextEffect: import RcRefRcRef.const get: <A, E>(
self: RcRef<A, E>
) => Effect.Effect<A, E, Scope>
Gets the value from an RcRef, acquiring it first if needed.
When to use
Use to borrow the current resource within a Scope, acquiring it first if
necessary.
Details
The reference count is incremented for the current Scope, and a release
finalizer is added to that scope. When the current scope closes, the
reference is released; the resource is closed when the final reference is
released, subject to any configured idle time-to-live.
Example (Sharing one acquired value)
import { Effect, RcRef } from "effect"
const program = Effect.gen(function*() {
// Create an RcRef with a resource
const ref = yield* RcRef.make({
acquire: Effect.acquireRelease(
Effect.succeed("shared resource"),
(resource) => Effect.log(`Releasing ${resource}`)
)
})
// Get the value from the RcRef
const value1 = yield* RcRef.get(ref)
const value2 = yield* RcRef.get(ref)
// Both values are the same instance
console.log(value1 === value2) // true
return value1
})
get(const rcRef: RcRef.RcRef<
Context.Context<I>,
E
>
const rcRef: {
pipe: { <A>(this: A): A; <A, B = never>(this: A, ab: (_: A) => B): B; <A, B = never, C = never>(this: A, ab: (_: A) => B, bc: (_: B) => C): C; <A, B = never, C = never, D = never>(this: A, ab: (_: A) => B, bc: (_: B) => C, cd: (_: C) => D): D; <…;
}
rcRef),
LayerRef<in out I, in out E = never>.invalidate: Effect.Effect<void, never, never>(property) LayerRef<in out I, in out E = never>.invalidate: {
pipe: { <A>(this: A): A; <A, B = never>(this: A, ab: (_: A) => B): B; <A, B = never, C = never>(this: A, ab: (_: A) => B, bc: (_: B) => C): C; <A, B = never, C = never, D = never>(this: A, ab: (_: A) => B, bc: (_: B) => C, cd: (_: C) => D): D; <…;
toString: () => string;
toJSON: () => unknown;
}
Invalidates the cached context so the next use rebuilds the layer.
invalidate: import RcRefRcRef.const invalidate: <A, E>(
self: RcRef<A, E>
) => Effect.Effect<void>
Invalidates the currently cached resource, if one has been acquired.
When to use
Use to force future RcRef.get calls to acquire a fresh resource when the
currently cached resource should no longer be reused.
Details
After invalidation, the next get acquires a fresh resource.
Gotchas
Invalidation does not revoke resources already borrowed by active scopes;
those remain usable until their scopes close.
invalidate(const rcRef: RcRef.RcRef<
Context.Context<I>,
E
>
const rcRef: {
pipe: { <A>(this: A): A; <A, B = never>(this: A, ab: (_: A) => B): B; <A, B = never, C = never>(this: A, ab: (_: A) => B, bc: (_: B) => C): C; <A, B = never, C = never, D = never>(this: A, ab: (_: A) => B, bc: (_: B) => C, cd: (_: C) => D): D; <…;
}
rcRef),
LayerRef<I, any>.refresh: Effect.Effect<void, E, never>(property) LayerRef<I, any>.refresh: {
pipe: { <A>(this: A): A; <A, B = never>(this: A, ab: (_: A) => B): B; <A, B = never, C = never>(this: A, ab: (_: A) => B, bc: (_: B) => C): C; <A, B = never, C = never, D = never>(this: A, ab: (_: A) => B, bc: (_: B) => C, cd: (_: C) => D): D; <…;
toString: () => string;
toJSON: () => unknown;
}
Invalidates the cached context so the next use rebuilds the layer, and
reacquires it.
refresh
})
}
)