🤑 @epic-web/cachified
A simple API to make your app faster.
Cachified allows you to cache values with support for time-to-live (ttl), stale-while-revalidate (swr), cache value validation, batching, and type-safety.
npm install @epic-web/cachified
Watch the talk "Caching for Cash 🤑" on EpicWeb.dev:
Install
npm install @epic-web/cachified
# yarn add @epic-web/cachifiedUsage
import { LRUCache } from 'lru-cache'; import { cachified, CacheEntry, Cache, totalTtl } from '@epic-web/cachified'; /* lru cache is not part of this package but a simple non-persistent cache */ const lruInstance = new LRUCache<string, CacheEntry>({ max: 1000 }); const lru: Cache = { set(key, value) { const ttl = totalTtl(value?.metadata); return lruInstance.set(key, value, { ttl: ttl === Infinity ? undefined : ttl, start: value?.metadata?.createdTime, }); }, get(key) { return lruInstance.get(key); }, delete(key) { return lruInstance.delete(key); }, }; function getUserById(userId: number) { return cachified({ key: `user-${userId}`, cache: lru, async getFreshValue() { /* Normally we want to either use a type-safe API or `checkValue` but to keep this example simple we work with `any` */ const response = await fetch( `https://jsonplaceholder.typicode.com/users/${userId}`, ); return response.json(); }, /* 5 minutes until cache gets invalid * Optional, defaults to Infinity */ ttl: 300_000, }); } // Let's get through some calls of `getUserById`: console.log(await getUserById(1)); // > logs the user with ID 1 // Cache was empty, `getFreshValue` got invoked and fetched the user-data that // is now cached for 5 minutes // 2 minutes later console.log(await getUserById(1)); // > logs the exact same user-data // Cache was filled an valid. `getFreshValue` was not invoked // 10 minutes later console.log(await getUserById(1)); // > logs the user with ID 1 that might have updated fields // Cache timed out, `getFreshValue` got invoked to fetch a fresh copy of the user // that now replaces current cache entry and is cached for 5 minutes
Options
"interface CachifiedOptions {
/**
* Required
*
* The key this value is cached by
* Must be unique for each value
*/
key: string;
/**
* Required
*
* Cache implementation to use
*
* Must conform with signature
* - set(key: string, value: object): void | Promise
* - get(key: string): object | Promise