{"id":17312,"library":"ocache","title":"Standalone Caching Utilities","description":"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.","status":"active","version":"0.1.4","language":"javascript","source_language":"en","source_url":"https://github.com/unjs/ocache","tags":["javascript","typescript"],"install":[{"cmd":"npm install ocache","lang":"bash","label":"npm"},{"cmd":"yarn add ocache","lang":"bash","label":"yarn"},{"cmd":"pnpm add ocache","lang":"bash","label":"pnpm"}],"dependencies":[],"imports":[{"note":"ocache is designed for ESM environments, using `require` might lead to issues or require specific build configurations. Use named imports from the main package entry point.","wrong":"const defineCachedFunction = require('ocache').defineCachedFunction;","symbol":"defineCachedFunction","correct":"import { defineCachedFunction } from 'ocache';"},{"note":"All major utilities are exported directly from the main 'ocache' package.","wrong":"import defineCachedHandler from 'ocache/handler';","symbol":"defineCachedHandler","correct":"import { defineCachedHandler } from 'ocache';"},{"note":"Use the full `invalidateCache` name for the standalone invalidation utility. Cached functions also have an instance `.invalidate()` method.","wrong":"import { invalidate } from 'ocache';","symbol":"invalidateCache","correct":"import { invalidateCache } from 'ocache';"}],"quickstart":{"code":"import { defineCachedFunction } from \"ocache\";\n\nconst cachedFetch = defineCachedFunction(\n  async (url: string) => {\n    console.log(`Fetching data for: ${url}`);\n    const res = await fetch(url);\n    if (!res.ok) {\n      throw new Error(`HTTP error! Status: ${res.status}`);\n    }\n    return res.json();\n  },\n  {\n    maxAge: 10, // Cache for 10 seconds\n    name: \"api-fetch\", // Identifier for cache keys\n    swr: true, // Enable stale-while-revalidate\n    staleMaxAge: 60 // Serve stale content for up to 60 seconds while revalidating\n  },\n);\n\nasync function runExample() {\n  console.log('--- First call ---');\n  const data1 = await cachedFetch(\"https://jsonplaceholder.typicode.com/todos/1\");\n  console.log('Data 1:', data1.title);\n\n  console.log('\\n--- Second call (should be cached) ---');\n  const data2 = await cachedFetch(\"https://jsonplaceholder.typicode.com/todos/1\");\n  console.log('Data 2:', data2.title);\n\n  // Wait for cache to become stale but still valid for SWR\n  console.log('\\n--- Waiting for cache to expire... ---');\n  await new Promise(resolve => setTimeout(resolve, 11 * 1000));\n\n  console.log('\\n--- Third call (should trigger revalidation and serve stale first) ---');\n  const data3 = await cachedFetch(\"https://jsonplaceholder.typicode.com/todos/1\");\n  console.log('Data 3 (potentially stale, revalidating in background):', data3.title);\n\n  // Invalidate specific cache entry\n  console.log('\\n--- Invalidating cache for todos/1 ---');\n  await cachedFetch.invalidate(\"https://jsonplaceholder.typicode.com/todos/1\");\n\n  console.log('\\n--- Fourth call (after invalidation, should re-fetch) ---');\n  const data4 = await cachedFetch(\"https://jsonplaceholder.typicode.com/todos/1\");\n  console.log('Data 4:', data4.title);\n}\n\nrunExample().catch(console.error);\n","lang":"typescript","description":"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."},"warnings":[{"fix":"Always review the changelog when updating any `0.x` version of ocache to understand potential API or behavioral changes.","message":"ocache is currently in `0.x` versioning, which implies that breaking changes could be introduced in minor releases without strict adherence to semantic versioning until a `1.0.0` release. Users should carefully review release notes for `0.x` updates.","severity":"gotcha","affected_versions":">=0.1.0"},{"fix":"If providing a custom `getKey` option, test it thoroughly to ensure it produces the expected cache keys for all relevant inputs. If not provided, the default key generation (based on function name and stringified arguments) should be sufficient for most primitive arguments.","message":"When using `defineCachedFunction`, ensure your `getKey` function (if custom) consistently returns a unique key for distinct inputs. Incorrect key generation will lead to unintended cache hits or misses.","severity":"gotcha","affected_versions":">=0.1.0"},{"fix":"Review the usage of `staleMaxAge` in your caching options. If you previously had custom logic for stale content, consider whether `ocache`'s built-in `staleMaxAge` now covers your needs.","message":"The `staleMaxAge` option was introduced and refined in `v0.1.3`. For users upgrading from earlier `0.1.x` versions, the behavior related to serving stale content while revalidating might change or become active for the first time.","severity":"breaking","affected_versions":"<0.1.3"},{"fix":"Understand the read/write behavior of multi-tier caching. Ensure all tiers are robust and capable of handling write operations. Monitor performance for write-heavy workloads with many tiers.","message":"Multi-tier caching (`base: string[]`) processes reads by trying each prefix in order and using the first hit, but writes to *all* prefixes. This can lead to increased write overhead and potential inconsistencies if tiers are not properly managed or if a write fails on one tier.","severity":"gotcha","affected_versions":">=0.1.3"},{"fix":"Verify that your server environment correctly handles standard Web Fetch API `Request` and `Response` objects. Test caching behavior extensively in your target deployment environment, especially for header-based optimizations like `etag` and `last-modified`.","message":"HTTP handler caching with `defineCachedHandler` relies on `event.req` being a standard Request object or similar. In non-standard environments, the `etag` and `last-modified` headers might not behave as expected or could require polyfills/adaptations.","severity":"gotcha","affected_versions":">=0.1.0"}],"env_vars":null,"last_verified":"2026-04-22T00:00:00.000Z","next_check":"2026-07-21T00:00:00.000Z","problems":[{"fix":"Ensure that the environment in which `defineCachedHandler` is used (e.g., a serverless function context) provides an event object compatible with standard `Request` objects, specifically `event.req.headers`. You might need to adapt your handler to parse headers from a different property or format.","cause":"The `event` object passed to the handler does not contain a standard `req` property or `req` is not a valid `Request` object with headers.","error":"TypeError: Cannot read properties of undefined (reading 'headers') when using defineCachedHandler"},{"fix":"Check your `getKey` function (if custom) for consistency. Increase `maxAge` for testing. Verify `shouldBypassCache` option to ensure it's not unintentionally skipping the cache. Also, ensure that the cache storage is correctly configured and accessible.","cause":"The cache key is not being generated consistently, or the `maxAge` is too low, or `shouldBypassCache` is inadvertently returning `true`.","error":"Cache entry not found or always re-fetching despite maxAge being set."},{"fix":"Ensure your project is configured for ESM (e.g., `\"type\": \"module\"` in `package.json`) and use `import { defineCachedFunction } from 'ocache';`. If you must use CommonJS, consider transpilation or using a bundler that handles ESM conversion.","cause":"Attempting to use `require()` for an ESM-only package or an environment that doesn't correctly resolve ESM imports.","error":"SyntaxError: Named export 'defineCachedFunction' not found. The requested module 'ocache' does not provide an export named 'defineCachedFunction'"}],"ecosystem":"npm","meta_description":null}