/** * Creates refreshable references to a single layer-built service context. * * A `LayerRef` builds one `Layer` into a cached `Context`, exposes it * back as a layer or scoped effect, and supports invalidation so later users can * acquire a fresh context. * * @stability unstable * @since 4.0.0 */ import * as Context from "./Context.ts"; import type * as Duration from "./Duration.ts"; import * as Effect from "./Effect.ts"; import * as Layer from "./Layer.ts"; import * as RcRef from "./RcRef.ts"; import type * as Schedule from "./Schedule.ts"; import * as Scope from "./Scope.ts"; declare const TypeId = "~effect/LayerRef"; /** * 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. * * @see {@link make} for constructing a `LayerRef` from a layer * @see {@link Service} for defining a `LayerRef` as a service class * * @stability unstable * @category models * @since 4.0.0 */ export interface LayerRef { readonly [TypeId]: typeof TypeId; /** * The underlying reference-counted cache that stores the built context. */ readonly rcRef: RcRef.RcRef, E>; /** * Layer that provides the currently cached context, acquiring it if needed. */ readonly get: Layer.Layer; /** * Scoped effect that retrieves the currently cached context, acquiring it if needed. */ readonly contextEffect: Effect.Effect, E, Scope.Scope>; /** * Invalidates the cached context so the next use rebuilds the layer. */ readonly invalidate: Effect.Effect; /** * Invalidates the cached context so the next use rebuilds the layer, and * reacquires it. */ readonly refresh: Effect.Effect; } /** * 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) * * ```ts import.meta.vitest * import { Context, Effect, Layer, LayerRef } from "effect" * * class Database extends Context.Service * }>()("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 * }) * ) * * await Effect.runPromise(program) // => "result" * ``` * * @see {@link Service} for defining a reusable service class around a `LayerRef` * * @stability unstable * @category constructors * @since 4.0.0 */ export declare const make: (layer: Layer.Layer, options?: { /** * Duration to keep the resource alive after it is no longer used. */ readonly idleTimeToLive?: Duration.Input | undefined; /** * Whether to acquire the resource during creation. */ readonly preload?: Preload | undefined; /** * Schedule used to invalidate the cached resource. When `preload` is * `true`, each scheduled invalidation also reacquires the resource. */ readonly invalidationSchedule?: Schedule.Schedule | undefined; } | undefined) => Effect.Effect, [Preload] extends [true] ? E : never, R | SR | Scope.Scope>; /** * Service class shape produced by `LayerRef.Service`. * * **When to use** * * Use as the public type for classes returned by `LayerRef.Service` when an API * needs to accept, return, or alias the generated service class and its static * helpers. * * **Details** * * It combines a `Context.Service` tag for the `LayerRef` with default layers and * helper accessors for retrieving, using, and invalidating the cached resource. * * @see {@link Service} for creating concrete `LayerRef` service classes * * @stability unstable * @category services * @since 4.0.0 */ export interface TagClass> extends Context.ServiceClass> { /** * Default layer for the `LayerRef` service, with dependencies applied. */ readonly layer: Layer.Layer ? _E : never) | LE, Exclude ? _A : never)> | (Deps extends Layer.Layer ? _R : never)>; /** * Default layer for the `LayerRef` service without provided dependencies. */ readonly layerNoDeps: Layer.Layer; /** * Layer that provides the currently cached context, requiring this service. */ readonly get: Layer.Layer; /** * Scoped effect that retrieves the currently cached context through this service. */ readonly contextEffect: Effect.Effect, E, Scope.Scope | Self>; /** * Invalidates the cached context through this service. */ readonly invalidate: Effect.Effect; /** * Invalidates the cached context through this service, and reacquires it. */ readonly refresh: Effect.Effect; } /** * Creates a service class for a `LayerRef`. * * **When to use** * * Use when you want to name a shared layer reference as an application service * and expose static helpers for providing, retrieving, and invalidating it. * * **Details** * * The returned class is a `Context.Service` whose value is a `LayerRef`. It also * includes `.layer`, `.layerNoDeps`, `.get`, `.contextEffect`, and `.invalidate` * helpers so callers do not need to access the `LayerRef` value directly. * * **Example** (Defining a refreshable service) * * ```ts import.meta.vitest * import { Context, Effect, Layer, LayerRef } from "effect" * * class Database extends Context.Service * }>()("Database") {} * * const databaseLayer = Layer.succeed(Database, { * query: Effect.succeed("result") * }) * * class DatabaseRef extends LayerRef.Service()("DatabaseRef", { * layer: databaseLayer, * preload: true * }) {} * * const program = Effect.gen(function*() { * const database = yield* Database * return yield* database.query * }).pipe( * Effect.provide(DatabaseRef.get), * Effect.provide(DatabaseRef.layer) * ) * * await Effect.runPromise(program) // => "result" * ``` * * @see {@link make} for creating a `LayerRef` value without defining a service class * * @stability unstable * @category services * @since 4.0.0 */ export declare const Service: () => > = [], const Preload extends boolean = never, SE = never, SR = never>(id: Id, options: { /** * Layer used to build the cached context. */ readonly layer: Layer.Layer; /** * Layers used to satisfy dependencies of the `LayerRef` service layer. */ readonly dependencies?: Deps | undefined; /** * Duration to keep the resource alive after it is no longer used. */ readonly idleTimeToLive?: Duration.Input | undefined; /** * Whether to acquire the resource during creation. */ readonly preload?: Preload | undefined; /** * Schedule used to invalidate the cached resource. When `preload` is * `true`, each scheduled invalidation also reacquires the resource. */ readonly invalidationSchedule?: Schedule.Schedule | undefined; }) => TagClass; export {}; //# sourceMappingURL=LayerRef.d.ts.map