within-ts

Cache

Memoize expensive calls with TTL

Memoize expensive calls with TTL.

The problem

Caching is a common requirement, but implementing it correctly involves repetitive boilerplate:

const cache = new Map()

async function getUser(id: string) {
  if (cache.has(id)) return cache.get(id)
  const user = await db.query("SELECT * FROM users WHERE id = $1", [id])
  cache.set(id, user)
  setTimeout(() => cache.delete(id), 5 * 60 * 1000) // TTL
  return user
}

Now multiply this for every cacheable function. You also want: cache hit/miss logging and the ability to disable caching in tests.

The solution

Cache.memoize wraps any function with caching:

import { Cache } from "within-ts"

const getUser = Cache.memoize((id: string) => db.findUser(id), {
  ttl: "5m",
})

const user = await getUser("123")   // cache miss — calls db.findUser
const user2 = await getUser("123")  // cache hit — returns cached

For complex arguments (Dates, objects, class instances), provide a key function that turns args into a cache key string:

const getReport = Cache.memoize(
  (date: Date, filters: Filters) => generateReport(date, filters),
  {
    ttl: "1h",
    key: (date, filters) => `${date.toISOString()}:${filters.type}`,
  },
)

In-memory storage. No class definition needed — Cache is a plain utility like Result.

On this page