Logos DX
    Preparing search index...

    Function memoize

    • Memoizes an async function with intelligent caching, LRU eviction, and stale-while-revalidate.

      What it does:

      • Caches async function results with configurable TTL
      • Deduplicates concurrent calls with the same arguments (thundering herd protection)
      • LRU eviction when cache reaches maxSize
      • Optional stale-while-revalidate pattern for fast responses with fresh data
      • Pluggable cache adapters (Map by default, Redis/Memcached via custom adapters)
      • Background cleanup of expired entries
      • WeakRef support for memory-sensitive scenarios

      When to use:

      • Expensive async operations (database queries, API calls, computations)
      • Functions called frequently with the same arguments
      • Need to prevent duplicate concurrent executions
      • Want fast responses with eventually-fresh data (stale-while-revalidate)

      Performance notes:

      • Cache hit path is optimized for minimal allocations
      • Default key generation: O(n) in argument structure size
      • For hot paths, provide custom generateKey extracting only discriminating fields

      Type Parameters

      Parameters

      Returns EnhancedMemoizedFunction<T>

      Enhanced memoized function with cache management methods

      // Basic usage
      const fetchUser = async (id: string) => database.users.findById(id);
      const getUser = memoize(fetchUser);

      // Three concurrent calls → one database query
      const [user1, user2, user3] = await Promise.all([
      getUser("42"),
      getUser("42"),
      getUser("42")
      ]);
      // With stale-while-revalidate
      const fetchPrices = async (symbol: string) => api.getPrice(symbol);
      const getPrice = memoize(fetchPrices, {
      ttl: 60000, // Expire after 1 minute
      staleIn: 30000, // Consider stale after 30 seconds
      staleTimeout: 1000 // Wait max 1 second for fresh data
      });

      // Returns stale data immediately if fresh fetch takes > 1 second
      const price = await getPrice("AAPL");
      // With custom key and cache management
      const search = async (query: string, opts: SearchOptions) => api.search(query, opts);
      const memoizedSearch = memoize(search, {
      generateKey: (query) => query, // Only cache by query, ignore opts
      maxSize: 100,
      ttl: 300000 // 5 minutes
      });

      // Cache management
      memoizedSearch.cache.stats(); // { hits: 10, misses: 3, hitRate: 0.77, ... }
      memoizedSearch.cache.clear(); // Clear all cached results
      memoizedSearch.cache.delete(someKey); // Remove specific entry
      // Conditional caching - bypass cache for specific requests
      const fetchData = async (url: string, opts?: { bustCache?: boolean }) => api.get(url);
      const smartFetch = memoize(fetchData, {
      shouldCache: (url, opts) => !opts?.bustCache,
      ttl: 60000
      });

      // This call uses cache
      await smartFetch('/api/data');

      // This call bypasses cache and executes directly (still deduped)
      await smartFetch('/api/data', { bustCache: true });