Hyperlinkv0.8.0-beta.28

LayerRef

LayerRef.Serviceconsteffect/LayerRef.ts:303
<Self>(): <
  const Id extends string,
  I,
  E,
  R,
  X,
  const Deps extends ReadonlyArray<Layer.Layer<any, any, any>> = [],
  const Preload extends boolean = never,
  SE = never,
  SR = never
>(
  id: Id,
  options: {
    readonly layer: Layer.Layer<I, E, R>
    readonly dependencies?: Deps | undefined
    readonly idleTimeToLive?: Duration.Input | undefined
    readonly preload?: Preload | undefined
    readonly invalidationSchedule?:
      | Schedule.Schedule<X, unknown, SE, SR>
      | undefined
  }
) => TagClass<
  Self,
  Id,
  I,
  E,
  R | SR,
  [Preload] extends [true] ? E : never,
  Deps[number]
>

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)

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")
})

class DatabaseRef extends LayerRef.Service<DatabaseRef>()("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)
)
servicesmake
Source effect/LayerRef.ts:30375 lines
export const Service = <Self>() =>
<
  const Id extends string,
  I,
  E,
  R,
  X,
  const Deps extends ReadonlyArray<Layer.Layer<any, any, any>> = [],
  const Preload extends boolean = never,
  SE = never,
  SR = never
>(
  id: Id,
  options: {
    /**
     * Layer used to build the cached context.
     */
    readonly layer: Layer.Layer<I, E, R>
    /**
     * 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<X, unknown, SE, SR> | undefined
  }
): TagClass<
  Self,
  Id,
  I,
  E,
  R | SR,
  [Preload] extends [true] ? E : never,
  Deps[number]
> => {
  const Err = globalThis.Error as any
  const limit = getStackTraceLimit()
  setStackTraceLimit(2)
  const creationError = new Err()
  setStackTraceLimit(limit)

  function TagClass() {}
  const TagClass_ = TagClass as any as Mutable<TagClass<Self, Id, any, any, any, any, any>>
  Object.setPrototypeOf(TagClass, Object.getPrototypeOf(Context.Service<Self, any>(id)))
  TagClass.key = id
  Object.defineProperty(TagClass, "stack", {
    get() {
      return creationError.stack
    }
  })

  TagClass_.layerNoDeps = Layer.effect(TagClass_)(
    make(options.layer, options)
  )
  TagClass_.layer = options.dependencies && options.dependencies.length > 0 ?
    Layer.provide(TagClass_.layerNoDeps, options.dependencies as any) :
    TagClass_.layerNoDeps

  TagClass_.get = Layer.unwrap(TagClass_.useSync((ref) => ref.get))
  TagClass_.contextEffect = TagClass_.use((ref) => ref.contextEffect)
  TagClass_.invalidate = TagClass_.use((ref) => ref.invalidate)
  TagClass_.refresh = TagClass_.use((ref) => ref.refresh)

  return TagClass as any
}