<ROut, E, RIn>(
build: (
memoMap: MemoMap,
scope: Scope.Scope
) => Effect<Context.Context<ROut>, E, RIn>
): Layer<ROut, E, RIn>Constructs a Layer from a function that uses a MemoMap and Scope to
build the layer.
Details
The function receives a MemoMap for memoization and a Scope for resource management.
A child scope is created, and if the build fails, the child scope is closed.
Example (Constructing a layer from a build function)
import { Context, Effect, Layer } from "effect"
class Database extends Context.Service<Database, {
readonly query: (sql: string) => Effect.Effect<string>
}>()("Database") {}
const databaseLayer = Layer.fromBuild(() =>
Effect.sync(() =>
Context.make(Database, {
query: (sql: string) => Effect.succeed("result")
})
)
)export const const fromBuild: <ROut, E, RIn>(
build: (
memoMap: MemoMap,
scope: Scope.Scope
) => Effect<Context.Context<ROut>, E, RIn>
) => Layer<ROut, E, RIn>
Constructs a Layer from a function that uses a MemoMap and Scope to
build the layer.
Details
The function receives a MemoMap for memoization and a Scope for resource management.
A child scope is created, and if the build fails, the child scope is closed.
Example (Constructing a layer from a build function)
import { Context, Effect, Layer } from "effect"
class Database extends Context.Service<Database, {
readonly query: (sql: string) => Effect.Effect<string>
}>()("Database") {}
const databaseLayer = Layer.fromBuild(() =>
Effect.sync(() =>
Context.make(Database, {
query: (sql: string) => Effect.succeed("result")
})
)
)
fromBuild = <function (type parameter) ROut in <ROut, E, RIn>(build: (memoMap: MemoMap, scope: Scope.Scope) => Effect<Context.Context<ROut>, E, RIn>): Layer<ROut, E, RIn>ROut, function (type parameter) E in <ROut, E, RIn>(build: (memoMap: MemoMap, scope: Scope.Scope) => Effect<Context.Context<ROut>, E, RIn>): Layer<ROut, E, RIn>E, function (type parameter) RIn in <ROut, E, RIn>(build: (memoMap: MemoMap, scope: Scope.Scope) => Effect<Context.Context<ROut>, E, RIn>): Layer<ROut, E, RIn>RIn>(
build: (
memoMap: MemoMap,
scope: Scope.Scope
) => Effect<Context.Context<ROut>, E, RIn>
build: (
memoMap: MemoMap(parameter) 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: MemoMap,
scope: Scope.Scope(parameter) scope: {
strategy: "sequential" | "parallel";
state: State.Open | State.Closed | State.Empty;
}
scope: import ScopeScope.Scope
) => import EffectEffect<import ContextContext.type Context.Context = /*unresolved*/ anyContext<function (type parameter) ROut in <ROut, E, RIn>(build: (memoMap: MemoMap, scope: Scope.Scope) => Effect<Context.Context<ROut>, E, RIn>): Layer<ROut, E, RIn>ROut>, function (type parameter) E in <ROut, E, RIn>(build: (memoMap: MemoMap, scope: Scope.Scope) => Effect<Context.Context<ROut>, E, RIn>): Layer<ROut, E, RIn>E, function (type parameter) RIn in <ROut, E, RIn>(build: (memoMap: MemoMap, scope: Scope.Scope) => Effect<Context.Context<ROut>, E, RIn>): Layer<ROut, E, RIn>RIn>
): 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) ROut in <ROut, E, RIn>(build: (memoMap: MemoMap, scope: Scope.Scope) => Effect<Context.Context<ROut>, E, RIn>): Layer<ROut, E, RIn>ROut, function (type parameter) E in <ROut, E, RIn>(build: (memoMap: MemoMap, scope: Scope.Scope) => Effect<Context.Context<ROut>, E, RIn>): Layer<ROut, E, RIn>E, function (type parameter) RIn in <ROut, E, RIn>(build: (memoMap: MemoMap, scope: Scope.Scope) => Effect<Context.Context<ROut>, E, RIn>): Layer<ROut, E, RIn>RIn> =>
const fromBuildUnsafe: <ROut, E, RIn>(
build: (
memoMap: MemoMap,
scope: Scope.Scope
) => Effect<Context.Context<ROut>, E, RIn>
) => Layer<ROut, E, RIn>
fromBuildUnsafe((memoMap: MemoMap(parameter) 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: MemoMap, scope: Scope.Scope(parameter) scope: {
strategy: "sequential" | "parallel";
state: State.Open | State.Closed | State.Empty;
}
scope: import ScopeScope.Scope) => {
const const layerScope: Scope.Closeableconst layerScope: {
strategy: "sequential" | "parallel";
state: State.Open | State.Closed | State.Empty;
}
layerScope = import ScopeScope.const forkUnsafe: (
scope: Scope,
finalizerStrategy?: "sequential" | "parallel"
) => Closeable
Creates a closeable child scope synchronously and registers it with a parent scope.
When to use
Use when a child scope must be created synchronously and the caller controls
both parent and child scope lifetimes.
Details
Closing the parent closes the child with the same exit value, and closing the
child detaches it from the parent. The optional finalizer strategy configures
the child scope and defaults to "sequential" when omitted.
Example (Creating a child scope synchronously)
import { Console, Effect, Exit, Scope } from "effect"
const program = Effect.gen(function*() {
const parentScope = Scope.makeUnsafe("sequential")
const childScope = Scope.forkUnsafe(parentScope, "parallel")
// Add finalizers to both scopes
yield* Scope.addFinalizer(parentScope, Console.log("Parent cleanup"))
yield* Scope.addFinalizer(childScope, Console.log("Child cleanup"))
// Close child first, then parent
yield* Scope.close(childScope, Exit.void)
yield* Scope.close(parentScope, Exit.void)
})
forkUnsafe(scope: Scope.Scope(parameter) scope: {
strategy: "sequential" | "parallel";
state: State.Open | State.Closed | State.Empty;
}
scope)
return import internalEffectinternalEffect.const onExit: {
<A, E, XE = never, XR = never>(
f: (
exit: Exit.Exit<A, E>
) => Effect.Effect<void, XE, XR>
): <R>(
self: Effect.Effect<A, E, R>
) => Effect.Effect<A, E | XE, R | XR>
<A, E, R, XE = never, XR = never>(
self: Effect.Effect<A, E, R>,
f: (
exit: Exit.Exit<A, E>
) => Effect.Effect<void, XE, XR>
): Effect.Effect<A, E | XE, R | XR>
}
onExit(
build: (
memoMap: MemoMap,
scope: Scope.Scope
) => Effect<Context.Context<ROut>, E, RIn>
build(memoMap: MemoMap(parameter) 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, const layerScope: Scope.Closeableconst layerScope: {
strategy: "sequential" | "parallel";
state: State.Open | State.Closed | State.Empty;
}
layerScope),
(exit: Exit.Exit<Context.Context<ROut>, E>exit) => exit: Exit.Exit<Context.Context<ROut>, E>exit._tag === "Failure" ? import ScopeScope.const close: <A, E>(
self: Scope,
exit: Exit<A, E>
) => Effect<void>
Closes a scope and runs its registered finalizers.
When to use
Use to close a scope manually with a specific exit value.
Details
Finalizers run in the scope's configured order and receive the supplied
Exit.
Example (Running scope finalizers)
import { Console, Effect, Exit, Scope } from "effect"
const resourceManagement = Effect.gen(function*() {
const scope = yield* Scope.make("sequential")
// Add multiple finalizers
yield* Scope.addFinalizer(scope, Console.log("Close database connection"))
yield* Scope.addFinalizer(scope, Console.log("Close file handle"))
yield* Scope.addFinalizer(scope, Console.log("Release memory"))
// Do some work...
yield* Console.log("Performing operations...")
// Close scope - finalizers run in reverse order of registration
yield* Scope.close(scope, Exit.succeed("Success!"))
// Output: "Release memory", "Close file handle", "Close database connection"
})
close(const layerScope: Scope.Closeableconst layerScope: {
strategy: "sequential" | "parallel";
state: State.Open | State.Closed | State.Empty;
}
layerScope, exit: Exit.Failure<Context.Context<ROut>, E>(parameter) exit: {
_tag: "Failure";
cause: Cause.Cause<E>;
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;
}
exit) : import internalEffectinternalEffect.const void: Effect<void, never, never>(alias) const void: {
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;
}
void
)
})