<
Key,
A,
E = never,
R = never,
ServiceMode extends "lookup" | "construction" = never
>(options: {
readonly lookup: (key: Key) => Effect.Effect<A, E, R>
readonly capacity: number
readonly timeToLive?: Duration.Input | undefined
readonly requireServicesAt?: ServiceMode | undefined
}): Effect.Effect<
Cache<Key, A, E, "lookup" extends ServiceMode ? R : never>,
never,
"lookup" extends ServiceMode ? never : R
>Creates a cache with a fixed time-to-live for all entries.
Details
This is the basic cache constructor where all entries share the same TTL. The lookup function will be called when a key is not found or has expired.
Example (Creating a basic cache)
import { Cache, Effect } from "effect"
// Basic cache with string keys
const program = Effect.gen(function*() {
const cache = yield* Cache.make<string, number>({
capacity: 100,
lookup: (key) => Effect.succeed(key.length)
})
const result1 = yield* Cache.get(cache, "hello")
const result2 = yield* Cache.get(cache, "world")
console.log({ result1, result2 }) // { result1: 5, result2: 5 }
})Example (Creating a cache with TTL)
import { Cache, Effect } from "effect"
const program = Effect.gen(function*() {
const users = new Map([
[123, { name: "Ada", email: "[email protected]" }],
[456, { name: "Grace", email: "[email protected]" }]
])
const cache = yield* Cache.make<
number,
{ name: string; email: string },
string
>({
capacity: 500,
lookup: (userId) =>
Effect.suspend(() => {
const user = users.get(userId)
return user === undefined
? Effect.fail(`User ${userId} not found`)
: Effect.succeed(user)
}),
timeToLive: "15 minutes"
})
const user1 = yield* Cache.get(cache, 123)
console.log(user1) // { name: "Ada", email: "[email protected]" }
const user2 = yield* Cache.get(cache, 123)
console.log(user2) // { name: "Ada", email: "[email protected]" }
})export const const make: <
Key,
A,
E = never,
R = never,
ServiceMode extends
| "lookup"
| "construction" = never
>(options: {
readonly lookup: (
key: Key
) => Effect.Effect<A, E, R>
readonly capacity: number
readonly timeToLive?: Duration.Input | undefined
readonly requireServicesAt?:
| ServiceMode
| undefined
}) => Effect.Effect<
Cache<
Key,
A,
E,
"lookup" extends ServiceMode ? R : never
>,
never,
"lookup" extends ServiceMode ? never : R
>
Creates a cache with a fixed time-to-live for all entries.
Details
This is the basic cache constructor where all entries share the same TTL.
The lookup function will be called when a key is not found or has expired.
Example (Creating a basic cache)
import { Cache, Effect } from "effect"
// Basic cache with string keys
const program = Effect.gen(function*() {
const cache = yield* Cache.make<string, number>({
capacity: 100,
lookup: (key) => Effect.succeed(key.length)
})
const result1 = yield* Cache.get(cache, "hello")
const result2 = yield* Cache.get(cache, "world")
console.log({ result1, result2 }) // { result1: 5, result2: 5 }
})
Example (Creating a cache with TTL)
import { Cache, Effect } from "effect"
const program = Effect.gen(function*() {
const users = new Map([
[123, { name: "Ada", email: "[email protected]" }],
[456, { name: "Grace", email: "[email protected]" }]
])
const cache = yield* Cache.make<
number,
{ name: string; email: string },
string
>({
capacity: 500,
lookup: (userId) =>
Effect.suspend(() => {
const user = users.get(userId)
return user === undefined
? Effect.fail(`User ${userId} not found`)
: Effect.succeed(user)
}),
timeToLive: "15 minutes"
})
const user1 = yield* Cache.get(cache, 123)
console.log(user1) // { name: "Ada", email: "[email protected]" }
const user2 = yield* Cache.get(cache, 123)
console.log(user2) // { name: "Ada", email: "[email protected]" }
})
make = <
function (type parameter) Key in <Key, A, E = never, R = never, ServiceMode extends "lookup" | "construction" = never>(options: {
readonly lookup: (key: Key) => Effect.Effect<A, E, R>;
readonly capacity: number;
readonly timeToLive?: Duration.Input | undefined;
readonly requireServicesAt?: ServiceMode | undefined;
}): Effect.Effect<Cache<Key, A, E, "lookup" extends ServiceMode ? R : never>, never, "lookup" extends ServiceMode ? never : R>
Key,
function (type parameter) A in <Key, A, E = never, R = never, ServiceMode extends "lookup" | "construction" = never>(options: {
readonly lookup: (key: Key) => Effect.Effect<A, E, R>;
readonly capacity: number;
readonly timeToLive?: Duration.Input | undefined;
readonly requireServicesAt?: ServiceMode | undefined;
}): Effect.Effect<Cache<Key, A, E, "lookup" extends ServiceMode ? R : never>, never, "lookup" extends ServiceMode ? never : R>
A,
function (type parameter) E in <Key, A, E = never, R = never, ServiceMode extends "lookup" | "construction" = never>(options: {
readonly lookup: (key: Key) => Effect.Effect<A, E, R>;
readonly capacity: number;
readonly timeToLive?: Duration.Input | undefined;
readonly requireServicesAt?: ServiceMode | undefined;
}): Effect.Effect<Cache<Key, A, E, "lookup" extends ServiceMode ? R : never>, never, "lookup" extends ServiceMode ? never : R>
E = never,
function (type parameter) R in <Key, A, E = never, R = never, ServiceMode extends "lookup" | "construction" = never>(options: {
readonly lookup: (key: Key) => Effect.Effect<A, E, R>;
readonly capacity: number;
readonly timeToLive?: Duration.Input | undefined;
readonly requireServicesAt?: ServiceMode | undefined;
}): Effect.Effect<Cache<Key, A, E, "lookup" extends ServiceMode ? R : never>, never, "lookup" extends ServiceMode ? never : R>
R = never,
function (type parameter) ServiceMode in <Key, A, E = never, R = never, ServiceMode extends "lookup" | "construction" = never>(options: {
readonly lookup: (key: Key) => Effect.Effect<A, E, R>;
readonly capacity: number;
readonly timeToLive?: Duration.Input | undefined;
readonly requireServicesAt?: ServiceMode | undefined;
}): Effect.Effect<Cache<Key, A, E, "lookup" extends ServiceMode ? R : never>, never, "lookup" extends ServiceMode ? never : R>
ServiceMode extends "lookup" | "construction" = never
>(
options: {
readonly lookup: (
key: Key
) => Effect.Effect<A, E, R>
readonly capacity: number
readonly timeToLive?: Duration.Input | undefined
readonly requireServicesAt?:
| ServiceMode
| undefined
}
options: {
readonly lookup: (key: Key) => Effect.Effect<A, E, R>lookup: (key: Keykey: function (type parameter) Key in <Key, A, E = never, R = never, ServiceMode extends "lookup" | "construction" = never>(options: {
readonly lookup: (key: Key) => Effect.Effect<A, E, R>;
readonly capacity: number;
readonly timeToLive?: Duration.Input | undefined;
readonly requireServicesAt?: ServiceMode | undefined;
}): Effect.Effect<Cache<Key, A, E, "lookup" extends ServiceMode ? R : never>, never, "lookup" extends ServiceMode ? never : R>
Key) => import EffectEffect.interface Effect<out A, out E = never, out R = never>The Effect interface defines a value that lazily describes a workflow or
job. The workflow requires some context R, and may fail with an error of
type E, or succeed with a value of type A.
When to use
Use when you need to represent a lazy, composable workflow that can require
services, fail with a typed error, or succeed with a typed value.
Details
Effect values model resourceful interaction with the outside world,
including synchronous, asynchronous, concurrent, and parallel interaction.
They use a fiber-based concurrency model, with built-in support for
scheduling, fine-grained interruption, structured concurrency, and high
scalability.
To run an Effect value, you need a Runtime, which is a type that is
capable of executing Effect values.
Effect<function (type parameter) A in <Key, A, E = never, R = never, ServiceMode extends "lookup" | "construction" = never>(options: {
readonly lookup: (key: Key) => Effect.Effect<A, E, R>;
readonly capacity: number;
readonly timeToLive?: Duration.Input | undefined;
readonly requireServicesAt?: ServiceMode | undefined;
}): Effect.Effect<Cache<Key, A, E, "lookup" extends ServiceMode ? R : never>, never, "lookup" extends ServiceMode ? never : R>
A, function (type parameter) E in <Key, A, E = never, R = never, ServiceMode extends "lookup" | "construction" = never>(options: {
readonly lookup: (key: Key) => Effect.Effect<A, E, R>;
readonly capacity: number;
readonly timeToLive?: Duration.Input | undefined;
readonly requireServicesAt?: ServiceMode | undefined;
}): Effect.Effect<Cache<Key, A, E, "lookup" extends ServiceMode ? R : never>, never, "lookup" extends ServiceMode ? never : R>
E, function (type parameter) R in <Key, A, E = never, R = never, ServiceMode extends "lookup" | "construction" = never>(options: {
readonly lookup: (key: Key) => Effect.Effect<A, E, R>;
readonly capacity: number;
readonly timeToLive?: Duration.Input | undefined;
readonly requireServicesAt?: ServiceMode | undefined;
}): Effect.Effect<Cache<Key, A, E, "lookup" extends ServiceMode ? R : never>, never, "lookup" extends ServiceMode ? never : R>
R>
readonly capacity: numbercapacity: number
readonly timeToLive?: Duration.Input | undefinedtimeToLive?: import DurationDuration.type Input =
| number
| bigint
| Duration.Duration
| readonly [seconds: number, nanos: number]
| `${number} nano`
| `${number} nanos`
| `${number} micro`
| `${number} micros`
| `${number} milli`
| `${number} millis`
| `${number} second`
| `${number} seconds`
| `${number} minute`
| `${number} minutes`
| `${number} hour`
| `${number} hours`
| `${number} day`
| `${number} days`
| `${number} week`
| `${number} weeks`
| "Infinity"
| "-Infinity"
| Duration.DurationObject
Valid input types that can be converted to a Duration.
When to use
Use when an API should accept any value that Effect can convert into a
Duration, including existing durations, millisecond numbers, nanosecond
bigints, high-resolution tuples, duration strings, infinity strings, or
duration objects.
Details
String inputs accept values like "10 seconds", "500 millis",
"Infinity", and "-Infinity". Finite fractional values that are
normalized to nanoseconds are rounded to the nearest nanosecond, with ties
away from zero.
Input | undefined
readonly requireServicesAt?: ServiceMode | undefinedrequireServicesAt?: function (type parameter) ServiceMode in <Key, A, E = never, R = never, ServiceMode extends "lookup" | "construction" = never>(options: {
readonly lookup: (key: Key) => Effect.Effect<A, E, R>;
readonly capacity: number;
readonly timeToLive?: Duration.Input | undefined;
readonly requireServicesAt?: ServiceMode | undefined;
}): Effect.Effect<Cache<Key, A, E, "lookup" extends ServiceMode ? R : never>, never, "lookup" extends ServiceMode ? never : R>
ServiceMode | undefined
}
): import EffectEffect.interface Effect<out A, out E = never, out R = never>The Effect interface defines a value that lazily describes a workflow or
job. The workflow requires some context R, and may fail with an error of
type E, or succeed with a value of type A.
When to use
Use when you need to represent a lazy, composable workflow that can require
services, fail with a typed error, or succeed with a typed value.
Details
Effect values model resourceful interaction with the outside world,
including synchronous, asynchronous, concurrent, and parallel interaction.
They use a fiber-based concurrency model, with built-in support for
scheduling, fine-grained interruption, structured concurrency, and high
scalability.
To run an Effect value, you need a Runtime, which is a type that is
capable of executing Effect values.
Effect<
interface Cache<in out Key, in out A, in out E = never, out R = never>A cache interface that provides a mutable key-value store with automatic TTL management,
capacity limits, and lookup functions for cache misses.
Example (Creating a basic cache)
import { Cache, Effect } from "effect"
// Basic cache with string keys and number values
const program = Effect.gen(function*() {
const cache = yield* Cache.make<string, number>({
capacity: 100,
lookup: (key: string) => Effect.succeed(key.length)
})
// Cache operations
const value1 = yield* Cache.get(cache, "hello") // 5
const value2 = yield* Cache.get(cache, "world") // 5
const value3 = yield* Cache.get(cache, "hello") // 5 (cached)
return [value1, value2, value3]
})
Example (Handling lookup failures)
import { Cache, Effect } from "effect"
// Cache with error handling
const program = Effect.gen(function*() {
const cache = yield* Cache.make<string, number, string>({
capacity: 10,
lookup: (key: string) =>
key === "error"
? Effect.fail("Lookup failed")
: Effect.succeed(key.length)
})
// Handle successful and failed lookups
const success = yield* Cache.get(cache, "test") // 4
const failure = yield* Effect.exit(Cache.get(cache, "error")) // Exit.fail
return { success, failure }
})
Example (Using complex keys with TTL)
import { Cache, Data, Duration, Effect } from "effect"
// Cache with complex key types and TTL
class UserId extends Data.Class<{ id: number }> {}
const program = Effect.gen(function*() {
const userCache = yield* Cache.make<UserId, string>({
capacity: 1000,
lookup: (userId: UserId) => Effect.succeed(`User-${userId.id}`),
timeToLive: Duration.minutes(5)
})
const userId = new UserId({ id: 123 })
const userName = yield* Cache.get(userCache, userId)
return userName // "User-123"
})
Cache<function (type parameter) Key in <Key, A, E = never, R = never, ServiceMode extends "lookup" | "construction" = never>(options: {
readonly lookup: (key: Key) => Effect.Effect<A, E, R>;
readonly capacity: number;
readonly timeToLive?: Duration.Input | undefined;
readonly requireServicesAt?: ServiceMode | undefined;
}): Effect.Effect<Cache<Key, A, E, "lookup" extends ServiceMode ? R : never>, never, "lookup" extends ServiceMode ? never : R>
Key, function (type parameter) A in <Key, A, E = never, R = never, ServiceMode extends "lookup" | "construction" = never>(options: {
readonly lookup: (key: Key) => Effect.Effect<A, E, R>;
readonly capacity: number;
readonly timeToLive?: Duration.Input | undefined;
readonly requireServicesAt?: ServiceMode | undefined;
}): Effect.Effect<Cache<Key, A, E, "lookup" extends ServiceMode ? R : never>, never, "lookup" extends ServiceMode ? never : R>
A, function (type parameter) E in <Key, A, E = never, R = never, ServiceMode extends "lookup" | "construction" = never>(options: {
readonly lookup: (key: Key) => Effect.Effect<A, E, R>;
readonly capacity: number;
readonly timeToLive?: Duration.Input | undefined;
readonly requireServicesAt?: ServiceMode | undefined;
}): Effect.Effect<Cache<Key, A, E, "lookup" extends ServiceMode ? R : never>, never, "lookup" extends ServiceMode ? never : R>
E, "lookup" extends function (type parameter) ServiceMode in <Key, A, E = never, R = never, ServiceMode extends "lookup" | "construction" = never>(options: {
readonly lookup: (key: Key) => Effect.Effect<A, E, R>;
readonly capacity: number;
readonly timeToLive?: Duration.Input | undefined;
readonly requireServicesAt?: ServiceMode | undefined;
}): Effect.Effect<Cache<Key, A, E, "lookup" extends ServiceMode ? R : never>, never, "lookup" extends ServiceMode ? never : R>
ServiceMode ? function (type parameter) R in <Key, A, E = never, R = never, ServiceMode extends "lookup" | "construction" = never>(options: {
readonly lookup: (key: Key) => Effect.Effect<A, E, R>;
readonly capacity: number;
readonly timeToLive?: Duration.Input | undefined;
readonly requireServicesAt?: ServiceMode | undefined;
}): Effect.Effect<Cache<Key, A, E, "lookup" extends ServiceMode ? R : never>, never, "lookup" extends ServiceMode ? never : R>
R : never>,
never,
"lookup" extends function (type parameter) ServiceMode in <Key, A, E = never, R = never, ServiceMode extends "lookup" | "construction" = never>(options: {
readonly lookup: (key: Key) => Effect.Effect<A, E, R>;
readonly capacity: number;
readonly timeToLive?: Duration.Input | undefined;
readonly requireServicesAt?: ServiceMode | undefined;
}): Effect.Effect<Cache<Key, A, E, "lookup" extends ServiceMode ? R : never>, never, "lookup" extends ServiceMode ? never : R>
ServiceMode ? never : function (type parameter) R in <Key, A, E = never, R = never, ServiceMode extends "lookup" | "construction" = never>(options: {
readonly lookup: (key: Key) => Effect.Effect<A, E, R>;
readonly capacity: number;
readonly timeToLive?: Duration.Input | undefined;
readonly requireServicesAt?: ServiceMode | undefined;
}): Effect.Effect<Cache<Key, A, E, "lookup" extends ServiceMode ? R : never>, never, "lookup" extends ServiceMode ? never : R>
R
> =>
const makeWith: <
Key,
A,
E = never,
R = never,
ServiceMode extends
| "lookup"
| "construction" = never
>(
lookup: (key: Key) => Effect.Effect<A, E, R>,
options: {
readonly capacity: number
readonly timeToLive?:
| ((
exit: Exit.Exit<A, E>,
key: Key
) => Duration.Input)
| undefined
readonly requireServicesAt?:
| ServiceMode
| undefined
}
) => Effect.Effect<
Cache<
Key,
A,
E,
"lookup" extends ServiceMode ? R : never
>,
never,
"lookup" extends ServiceMode ? never : R
>
Creates a cache with dynamic time-to-live based on the result and key.
When to use
Use when you need different cache entry lifetimes based on the lookup result
or key characteristics.
Details
The timeToLive function receives both the exit result and the key, allowing
for flexible TTL policies based on success/failure state and key characteristics.
Example (Configuring dynamic time to live)
import { Cache, Effect, Exit } from "effect"
// Cache with TTL based on computed value
const userCache = Effect.gen(function*() {
const cache = yield* Cache.makeWith(
(id: number) => Effect.succeed({ id, active: id % 2 === 0 }),
{
capacity: 1000,
timeToLive(exit) {
if (Exit.isSuccess(exit)) {
const user = exit.value
return user.active ? "1 hour" : "5 minutes"
}
return "30 seconds"
}
}
)
return cache
})
makeWith<function (type parameter) Key in <Key, A, E = never, R = never, ServiceMode extends "lookup" | "construction" = never>(options: {
readonly lookup: (key: Key) => Effect.Effect<A, E, R>;
readonly capacity: number;
readonly timeToLive?: Duration.Input | undefined;
readonly requireServicesAt?: ServiceMode | undefined;
}): Effect.Effect<Cache<Key, A, E, "lookup" extends ServiceMode ? R : never>, never, "lookup" extends ServiceMode ? never : R>
Key, function (type parameter) A in <Key, A, E = never, R = never, ServiceMode extends "lookup" | "construction" = never>(options: {
readonly lookup: (key: Key) => Effect.Effect<A, E, R>;
readonly capacity: number;
readonly timeToLive?: Duration.Input | undefined;
readonly requireServicesAt?: ServiceMode | undefined;
}): Effect.Effect<Cache<Key, A, E, "lookup" extends ServiceMode ? R : never>, never, "lookup" extends ServiceMode ? never : R>
A, function (type parameter) E in <Key, A, E = never, R = never, ServiceMode extends "lookup" | "construction" = never>(options: {
readonly lookup: (key: Key) => Effect.Effect<A, E, R>;
readonly capacity: number;
readonly timeToLive?: Duration.Input | undefined;
readonly requireServicesAt?: ServiceMode | undefined;
}): Effect.Effect<Cache<Key, A, E, "lookup" extends ServiceMode ? R : never>, never, "lookup" extends ServiceMode ? never : R>
E, function (type parameter) R in <Key, A, E = never, R = never, ServiceMode extends "lookup" | "construction" = never>(options: {
readonly lookup: (key: Key) => Effect.Effect<A, E, R>;
readonly capacity: number;
readonly timeToLive?: Duration.Input | undefined;
readonly requireServicesAt?: ServiceMode | undefined;
}): Effect.Effect<Cache<Key, A, E, "lookup" extends ServiceMode ? R : never>, never, "lookup" extends ServiceMode ? never : R>
R, function (type parameter) ServiceMode in <Key, A, E = never, R = never, ServiceMode extends "lookup" | "construction" = never>(options: {
readonly lookup: (key: Key) => Effect.Effect<A, E, R>;
readonly capacity: number;
readonly timeToLive?: Duration.Input | undefined;
readonly requireServicesAt?: ServiceMode | undefined;
}): Effect.Effect<Cache<Key, A, E, "lookup" extends ServiceMode ? R : never>, never, "lookup" extends ServiceMode ? never : R>
ServiceMode>(options: {
readonly lookup: (
key: Key
) => Effect.Effect<A, E, R>
readonly capacity: number
readonly timeToLive?: Duration.Input | undefined
readonly requireServicesAt?:
| ServiceMode
| undefined
}
options.lookup: (key: Key) => Effect.Effect<A, E, R>lookup, {
...options: {
readonly lookup: (
key: Key
) => Effect.Effect<A, E, R>
readonly capacity: number
readonly timeToLive?: Duration.Input | undefined
readonly requireServicesAt?:
| ServiceMode
| undefined
}
options,
timeToLive?: | (<A, E>(
_: Exit.Exit<A, E>,
_key: unknown
) => Duration.Duration)
| (() => Duration.Input)
timeToLive: options: {
readonly lookup: (
key: Key
) => Effect.Effect<A, E, R>
readonly capacity: number
readonly timeToLive?: Duration.Input | undefined
readonly requireServicesAt?:
| ServiceMode
| undefined
}
options.timeToLive?: Duration.Input | undefinedtimeToLive ? () => options: {
readonly lookup: (
key: Key
) => Effect.Effect<A, E, R>
readonly capacity: number
readonly timeToLive?: Duration.Input | undefined
readonly requireServicesAt?:
| ServiceMode
| undefined
}
options.timeToLive?: Duration.Input | undefinedtimeToLive! : const defaultTimeToLive: <A, E>(
_: Exit.Exit<A, E>,
_key: unknown
) => Duration.Duration
defaultTimeToLive
})