Standalone Caching Utilities

0.1.4 · active · verified Wed Apr 22

ocache is a JavaScript/TypeScript library providing robust caching utilities for functions and HTTP handlers. It supports common caching strategies such as time-to-live (TTL), stale-while-revalidate (SWR), and multi-tier caching. Currently at version 0.1.4, it is under active development by the unjs organization, suggesting a focus on modularity and integration within their ecosystem, although it is designed to be standalone. Key differentiators include built-in request deduplication for cached functions, automatic HTTP response caching with `etag` and `last-modified` support, and a flexible multi-tier caching mechanism that allows for layered cache storage. The project appears to follow a rapid release cadence for minor enhancements and performance improvements, typical for libraries in their early 0.x development phase, with type definitions included for TypeScript users.

Common errors

Warnings

Install

Imports

Quickstart

This example demonstrates defining a cached function with TTL and stale-while-revalidate, showing how it deduplicates requests, serves cached data, and can be explicitly invalidated.

import { defineCachedFunction } from "ocache";

const cachedFetch = defineCachedFunction(
  async (url: string) => {
    console.log(`Fetching data for: ${url}`);
    const res = await fetch(url);
    if (!res.ok) {
      throw new Error(`HTTP error! Status: ${res.status}`);
    }
    return res.json();
  },
  {
    maxAge: 10, // Cache for 10 seconds
    name: "api-fetch", // Identifier for cache keys
    swr: true, // Enable stale-while-revalidate
    staleMaxAge: 60 // Serve stale content for up to 60 seconds while revalidating
  },
);

async function runExample() {
  console.log('--- First call ---');
  const data1 = await cachedFetch("https://jsonplaceholder.typicode.com/todos/1");
  console.log('Data 1:', data1.title);

  console.log('\n--- Second call (should be cached) ---');
  const data2 = await cachedFetch("https://jsonplaceholder.typicode.com/todos/1");
  console.log('Data 2:', data2.title);

  // Wait for cache to become stale but still valid for SWR
  console.log('\n--- Waiting for cache to expire... ---');
  await new Promise(resolve => setTimeout(resolve, 11 * 1000));

  console.log('\n--- Third call (should trigger revalidation and serve stale first) ---');
  const data3 = await cachedFetch("https://jsonplaceholder.typicode.com/todos/1");
  console.log('Data 3 (potentially stale, revalidating in background):', data3.title);

  // Invalidate specific cache entry
  console.log('\n--- Invalidating cache for todos/1 ---');
  await cachedFetch.invalidate("https://jsonplaceholder.typicode.com/todos/1");

  console.log('\n--- Fourth call (after invalidation, should re-fetch) ---');
  const data4 = await cachedFetch("https://jsonplaceholder.typicode.com/todos/1");
  console.log('Data 4:', data4.title);
}

runExample().catch(console.error);

view raw JSON →