Hyperlinkv0.8.0-beta.28

ScopedCache

ScopedCache.makeWithconsteffect/ScopedCache.ts:132
<
  Key,
  A,
  E = never,
  R = never,
  ServiceMode extends "lookup" | "construction" = never
>(options: {
  readonly lookup: (key: Key) => Effect.Effect<A, E, R | Scope.Scope>
  readonly capacity: number
  readonly timeToLive?:
    | ((exit: Exit.Exit<A, E>, key: Key) => Duration.Input)
    | undefined
  readonly requireServicesAt?: ServiceMode | undefined
}): Effect.Effect<
  ScopedCache<
    Key,
    A,
    E,
    "lookup" extends ServiceMode ? Exclude<R, Scope.Scope> : never
  >,
  never,
  ("lookup" extends ServiceMode ? never : R) | Scope.Scope
>

Creates a ScopedCache from a lookup function, maximum capacity, and a time-to-live function computed from each lookup exit and key.

When to use

Use when you need a scoped cache whose entry lifetime depends on each lookup result or key.

Details

The cache must be constructed in a Scope. Each lookup runs in its own entry scope, and that scope is closed when the entry expires, is invalidated, is evicted by capacity, or when the cache's owning scope closes. requireServicesAt controls whether lookup services are captured at construction time or required when lookup operations run.

constructorsmake
export const makeWith = <
  Key,
  A,
  E = never,
  R = never,
  ServiceMode extends "lookup" | "construction" = never
>(options: {
  readonly lookup: (key: Key) => Effect.Effect<A, E, R | Scope.Scope>
  readonly capacity: number
  readonly timeToLive?: ((exit: Exit.Exit<A, E>, key: Key) => Duration.Input) | undefined
  readonly requireServicesAt?: ServiceMode | undefined
}): Effect.Effect<
  ScopedCache<Key, A, E, "lookup" extends ServiceMode ? Exclude<R, Scope.Scope> : never>,
  never,
  ("lookup" extends ServiceMode ? never : R) | Scope.Scope
> =>
  effect.contextWith((context: Context.Context<any>) => {
    const scope = Context.get(context, Scope.Scope)
    const self = Object.create(Proto)
    self.lookup = (key: Key): Effect.Effect<A, E> =>
      effect.updateContext(
        options.lookup(key),
        (input) => Context.merge(context, input)
      )
    const map = MutableHashMap.empty<Key, Entry<A, E>>()
    self.state = { _tag: "Open", map }
    self.capacity = options.capacity
    self.timeToLive = options.timeToLive
      ? (exit: Exit.Exit<A, E>, key: Key) => Duration.fromInputUnsafe(options.timeToLive!(exit, key))
      : defaultTimeToLive
    return effect.as(
      Scope.addFinalizer(
        scope,
        core.withFiber((fiber) => {
          self.state = { _tag: "Closed" }
          return invalidateAllImpl(fiber, map)
        })
      ),
      self
    )
  })
Referenced by 1 symbols