ScopedCache.ts
ScopedCache.ts overview
Section titled “ScopedCache.ts overview”Caches values that need scoped resource management.
Each cached entry owns its own Scope, so resources opened while creating a
value stay alive while that entry is cached and are released when the entry is
removed. A ScopedCache also belongs to an outer scope, which closes all
remaining entries when the cache is closed. Lookups for the same missing key
share one in-progress effect, and entries can expire, be refreshed, be
invalidated, or be evicted by capacity limits.
Since v4.0.0
Exports Grouped by Category
Section titled “Exports Grouped by Category”combinators
Section titled “combinators”entries
Section titled “entries”Retrieves all key-value pairs from the cache as an array. This function only returns entries with successfully resolved values, filtering out any failed lookups or expired entries.
When to use
Use to inspect the currently successful cached key-value pairs without running cache lookups.
Gotchas
Expired entries are removed and their scopes are closed while filtering.
See
keysfor retrieving only cached keysvaluesfor retrieving only cached values
Signature
declare const entries: <Key, A, E, R>(self: ScopedCache<Key, A, E, R>) => Effect.Effect<Array<[Key, A]>>Since v4.0.0
Gets the value for a key, running the cache lookup when no unexpired entry is present.
When to use
Use to retrieve a scoped cached value by key when a missing or expired entry should run the cache lookup and share the in-flight lookup with concurrent callers.
Details
Concurrent get calls for the same key share the same in-flight lookup.
Successful and failed lookup exits are cached according to the configured
TTL. If the cache is closed, the effect is interrupted.
See
getOptionfor reading only when an unexpired entry is already cachedgetSuccessfor inspecting an already-completed successful entryrefreshfor forcing a new lookup
Signature
declare const get: { <Key, A>(key: Key): <E, R>(self: ScopedCache<Key, A, E, R>) => Effect.Effect<A, E, R> <Key, A, E, R>(self: ScopedCache<Key, A, E, R>, key: Key): Effect.Effect<A, E, R>}Since v4.0.0
getOption
Section titled “getOption”Reads an existing unexpired cache entry without running the lookup function.
When to use
Use to read a scoped value only when it is already cached, without starting the lookup for missing or expired keys.
Details
Returns Option.none when the key is absent or expired. If an entry exists,
the effect waits for its cached result and returns Option.some(value) on
success, or fails with the cached lookup error.
See
getfor running the lookup on missing or expired keysgetSuccessfor inspecting only already-completed successful entries
Signature
declare const getOption: { <Key, A>(key: Key): <E, R>(self: ScopedCache<Key, A, E, R>) => Effect.Effect<Option.Option<A>, E> <Key, A, E, R>(self: ScopedCache<Key, A, E, R>, key: Key): Effect.Effect<Option.Option<A>, E>}Since v4.0.0
getSuccess
Section titled “getSuccess”Retrieves the value associated with the specified key from the cache, only if it contains a resolved successful value.
When to use
Use to inspect an already-completed successful scoped cache entry without running or awaiting the lookup effect.
Details
Returns Option.some for a resolved successful entry. Returns Option.none
for missing, expired, failed, or still-pending entries.
See
getfor awaiting or starting the lookup effectgetOptionfor awaiting an already-cached entry without starting a lookup
Signature
declare const getSuccess: { <Key, A, R>(key: Key): <E>(self: ScopedCache<Key, A, E, R>) => Effect.Effect<Option.Option<A>> <Key, A, E, R>(self: ScopedCache<Key, A, E, R>, key: Key): Effect.Effect<Option.Option<A>>}Since v4.0.0
Checks whether the cache contains an entry for the specified key.
When to use
Use to test whether an unexpired entry exists for a key without running the cache lookup.
Details
This does not start lookups and does not refresh access order. Expired entries are treated as absent and their scopes are closed while checking. If the cache is closed, the effect is interrupted.
See
getOptionfor reading an existing cached entrygetfor running the lookup on missing or expired keys
Signature
declare const has: { <Key, A>(key: Key): <E, R>(self: ScopedCache<Key, A, E, R>) => Effect.Effect<boolean> <Key, A, E, R>(self: ScopedCache<Key, A, E, R>, key: Key): Effect.Effect<boolean>}Since v4.0.0
invalidate
Section titled “invalidate”Removes the entry associated with a key and closes its entry scope.
When to use
Use to remove a single key from a scoped cache and release any resources owned by that entry before a later lookup computes it again.
Details
If the key is absent, this is a no-op.
Gotchas
If the cache is closed, the effect is interrupted.
See
refreshfor replacing a key by running a new lookup immediatelyinvalidateWhenfor invalidating only when a cached value matches a predicateinvalidateAllfor removing every cached entry
Signature
declare const invalidate: { <Key, A>(key: Key): <E, R>(self: ScopedCache<Key, A, E, R>) => Effect.Effect<void> <Key, A, E, R>(self: ScopedCache<Key, A, E, R>, key: Key): Effect.Effect<void>}Since v4.0.0
invalidateAll
Section titled “invalidateAll”Removes every entry from the cache and closes each entry scope.
When to use
Use to clear a scoped cache and release resources owned by all cached entries.
Details
If the cache is closed, the effect is interrupted.
See
invalidatefor removing one cached entry
Signature
declare const invalidateAll: <Key, A, E, R>(self: ScopedCache<Key, A, E, R>) => Effect.Effect<void>Since v4.0.0
invalidateWhen
Section titled “invalidateWhen”Invalidates the entry associated with the specified key in the cache when the predicate returns true for the cached value.
When to use
Use to remove an already-cached scoped value only when the successful cached value satisfies a predicate.
Details
Returns true only when a successful cached value matches and is removed. It
returns false for absent, expired, failed, or non-matching entries.
Gotchas
A matching invalidation closes the entry scope and releases its resources.
See
invalidatefor unconditional removal by key
Signature
declare const invalidateWhen: { <Key, A>(key: Key, f: Predicate.Predicate<A>): <E, R>(self: ScopedCache<Key, A, E, R>) => Effect.Effect<boolean> <Key, A, E, R>(self: ScopedCache<Key, A, E, R>, key: Key, f: Predicate.Predicate<A>): Effect.Effect<boolean>}Since v4.0.0
Retrieves all active keys from the cache, automatically filtering out expired entries.
When to use
Use to inspect currently cached unexpired keys without running cache lookups.
Gotchas
Expired entries are removed and their scopes are closed while filtering.
See
entriesfor retrieving successful cached key-value pairsvaluesfor retrieving only successfully cached values
Signature
declare const keys: <Key, A, E, R>(self: ScopedCache<Key, A, E, R>) => Effect.Effect<Array<Key>>Since v4.0.0
refresh
Section titled “refresh”Forces a refresh of the value associated with the specified key in the cache.
When to use
Use to recompute a scoped cache entry immediately, even when an unexpired value is already cached.
Details
It will always invoke the lookup function to construct a new value, overwriting any existing value for that key.
See
getfor reusing an unexpired entry before running the lookupinvalidatefor removing an entry without recomputing it
Signature
declare const refresh: { <Key, A>(key: Key): <E, R>(self: ScopedCache<Key, A, E, R>) => Effect.Effect<A, E, R> <Key, A, E, R>(self: ScopedCache<Key, A, E, R>, key: Key): Effect.Effect<A, E, R>}Since v4.0.0
Sets a successful value for a key without running the lookup function.
When to use
Use to seed or overwrite a scoped cache entry with an already available successful value.
Details
This replaces and closes any existing entry scope for the key, applies the cache’s TTL using a successful exit for the value, and may evict older entries if the cache capacity is exceeded.
See
getfor reading or computing a cached valuerefreshfor replacing an entry by running the lookup function
Signature
declare const set: { <Key, A>(key: Key, value: A): <E, R>(self: ScopedCache<Key, A, E, R>) => Effect.Effect<void> <Key, A, E, R>(self: ScopedCache<Key, A, E, R>, key: Key, value: A): Effect.Effect<void>}Since v4.0.0
Retrieves the approximate number of entries in the cache.
When to use
Use to inspect how many entries are currently stored in the scoped cache.
Gotchas
Note that expired entries are counted until they are accessed and removed. The size reflects the current number of entries stored, not the number of valid entries.
Signature
declare const size: <Key, A, E, R>(self: ScopedCache<Key, A, E, R>) => Effect.Effect<number>Since v4.0.0
values
Section titled “values”Retrieves all successfully cached values from the cache, excluding failed lookups and expired entries.
When to use
Use to inspect currently successful cached values without running cache lookups.
Gotchas
Expired entries are removed and their scopes are closed while filtering.
See
entriesfor retrieving successful cached key-value pairskeysfor retrieving only cached keys
Signature
declare const values: <Key, A, E, R>(self: ScopedCache<Key, A, E, R>) => Effect.Effect<Array<A>>Since v4.0.0
constructors
Section titled “constructors”Creates a ScopedCache with a fixed time-to-live for every lookup result.
When to use
Use to create a scoped cache when every cached lookup result should share the same lifetime.
Details
This is the constant-TTL variant of makeWith: values are acquired by the
lookup effect in per-entry scopes, capacity can evict older entries, and
entry scopes are closed when entries expire, are invalidated, are evicted, or
when the cache’s owning scope closes.
See
makeWithfor computing time-to-live from each lookup result and key
Signature
declare const make: <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?: 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>Since v2.0.0
makeWith
Section titled “makeWith”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.
See
makefor creating a scoped cache with one fixed time-to-live
Signature
declare 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>Since v2.0.0
models
Section titled “models”Entry (interface)
Section titled “Entry (interface)”A single scoped cache entry.
When to use
Use when inspecting the open state of a ScopedCache and you need the stored
deferred result, entry scope, or expiration timestamp for a key.
Details
The entry contains the deferred lookup result shared by readers, the scope that owns resources acquired while computing the value, and an optional expiration time in milliseconds. Removing the entry closes its scope.
See
Statefor the open/closed cache state that stores entries by key
Signature
export interface Entry<A, E> { expiresAt: number | undefined readonly deferred: Deferred.Deferred<A, E> readonly scope: Scope.Closeable}Since v4.0.0
ScopedCache (interface)
Section titled “ScopedCache (interface)”A scoped cache whose values are acquired by a lookup effect and stored in per-entry scopes.
When to use
Use to cache values that acquire scoped resources and must release those resources when entries expire, are evicted, or are invalidated.
Details
Concurrent requests for the same key share the same in-flight lookup. Entries can expire based on the lookup exit, are evicted when capacity is exceeded, and release their entry scopes when invalidated, evicted, expired, or when the cache’s owning scope closes.
See
makefor creating a scoped cache with a fixed time-to-livemakeWithfor creating a scoped cache with dynamic time-to-live
Signature
export interface ScopedCache<in out Key, in out A, in out E = never, out R = never> extends Pipeable { readonly [TypeId]: typeof TypeId state: State<Key, A, E> readonly capacity: number readonly lookup: (key: Key) => Effect.Effect<A, E, R | Scope.Scope> readonly timeToLive: (exit: Exit.Exit<A, E>, key: Key) => Duration.Duration}Since v2.0.0
State (type alias)
Section titled “State (type alias)”Represents whether a ScopedCache is open or closed.
When to use
Use when inspecting the low-level lifecycle state of a scoped cache.
Details
Open stores cached entries in access order for reuse and eviction.
Closed means the owning scope has closed and the cache can no longer
perform lookup operations.
Signature
type State<K, A, E> = | { readonly _tag: "Open" readonly map: MutableHashMap.MutableHashMap<K, Entry<A, E>> } | { readonly _tag: "Closed" }Since v4.0.0