or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

docs

cache-management.mdcache-storage.mdfragment-matching.mdindex.mdoptimistic-updates.mdstore-operations.md
tile.json

cache-storage.mddocs/

Cache Storage

Multiple cache storage backend implementations optimized for different use cases and performance requirements.

Capabilities

ObjectCache

Basic object-based cache implementation using plain JavaScript objects for data storage.

/**
 * Basic cache implementation using plain JavaScript objects
 * Simple and fast for most use cases
 * No dependency tracking or advanced features
 */
class ObjectCache implements NormalizedCache {
  /**
   * Creates new object-based cache
   * @param data - Optional initial data to populate cache
   */
  constructor(protected data?: NormalizedCacheObject);

  /**
   * Returns raw cache data as object
   * @returns Complete cache data object
   */
  toObject(): NormalizedCacheObject;

  /**
   * Retrieves data by ID
   * @param dataId - Unique identifier for data
   * @returns Store object or undefined
   */
  get(dataId: string): StoreObject;

  /**
   * Stores data with given ID
   * @param dataId - Unique identifier for data
   * @param value - Store object to cache
   */
  set(dataId: string, value: StoreObject): void;

  /**
   * Removes data by ID
   * @param dataId - Unique identifier for data to remove
   */
  delete(dataId: string): void;

  /**
   * Clears all data from cache
   */
  clear(): void;

  /**
   * Replaces entire cache contents
   * @param newData - New data to replace cache contents
   */
  replace(newData: NormalizedCacheObject): void;
}

Usage Example:

import { ObjectCache } from "apollo-cache-inmemory";

// Create cache with initial data
const cache = new ObjectCache({
  "User:1": {
    id: "1",
    name: "Alice",
    __typename: "User"
  }
});

// Basic operations
cache.set("User:2", { id: "2", name: "Bob", __typename: "User" });
const user = cache.get("User:1");
cache.delete("User:2");
cache.clear();

DepTrackingCache

Advanced cache implementation with dependency tracking for optimized invalidation and performance.

/**
 * Cache implementation with dependency tracking
 * Uses optimism library for memoization and smart invalidation
 * Better performance for repeated reads but higher memory usage
 */
class DepTrackingCache implements NormalizedCache {
  /**
   * Creates dependency tracking cache
   * @param data - Optional initial data to populate cache
   */
  constructor(private data?: NormalizedCacheObject);

  /**
   * Returns cache data as object
   * @returns Complete cache data object
   */
  toObject(): NormalizedCacheObject;

  /**
   * Retrieves data by ID with dependency tracking
   * @param dataId - Unique identifier for data
   * @returns Store object or undefined
   */
  get(dataId: string): StoreObject;

  /**
   * Sets data and marks dependencies as dirty if changed
   * @param dataId - Unique identifier for data
   * @param value - Store object to cache (optional for deletion)
   */
  set(dataId: string, value?: StoreObject): void;

  /**
   * Removes data and marks dependencies as dirty
   * @param dataId - Unique identifier for data to remove
   */
  delete(dataId: string): void;

  /**
   * Clears all data and dependencies
   */
  clear(): void;

  /**
   * Replaces cache contents with smart dependency invalidation
   * @param newData - New data to replace cache contents
   */
  replace(newData: NormalizedCacheObject | null): void;
}

Usage Example:

import { DepTrackingCache } from "apollo-cache-inmemory";

const cache = new DepTrackingCache();

// Dependency tracking automatically optimizes repeated reads
cache.set("User:1", { id: "1", name: "Alice", __typename: "User" });

// First read establishes dependency
const user1 = cache.get("User:1"); 

// Subsequent reads are optimized
const user1Again = cache.get("User:1"); // Uses cached computation

// Setting new value invalidates dependent computations
cache.set("User:1", { id: "1", name: "Alice Updated", __typename: "User" });

MapCache

Map-based cache implementation using JavaScript Map for better performance with large datasets.

/**
 * Cache implementation using JavaScript Map
 * Better performance for large datasets and frequent operations
 * Requires Object.entries polyfill for older environments
 */
class MapCache implements NormalizedCache {
  /**
   * Creates Map-based cache
   * @param data - Optional initial data object to populate cache
   */
  constructor(data?: NormalizedCacheObject);

  /**
   * Retrieves data by ID from Map
   * @param dataId - Unique identifier for data
   * @returns Store object or undefined
   */
  get(dataId: string): StoreObject;

  /**
   * Stores data in Map with string key
   * @param dataId - Unique identifier for data
   * @param value - Store object to cache
   */
  set(dataId: string, value: StoreObject): void;

  /**
   * Removes data from Map
   * @param dataId - Unique identifier for data to remove
   */
  delete(dataId: string): void;

  /**
   * Clears all entries from Map
   */
  clear(): void;

  /**
   * Converts Map contents to plain object
   * @returns Object representation of cache data
   */
  toObject(): NormalizedCacheObject;

  /**
   * Replaces Map contents with new data
   * @param newData - New data object to populate Map
   */
  replace(newData: NormalizedCacheObject): void;
}

Usage Example:

import { MapCache } from "apollo-cache-inmemory";

const cache = new MapCache();

// Map-based operations (better for large datasets)
cache.set("User:1", { id: "1", name: "Alice", __typename: "User" });
cache.set("Post:100", { id: "100", title: "Hello", __typename: "Post" });

// Efficient lookups even with thousands of entries
const user = cache.get("User:1");

// Convert to object for serialization
const cacheSnapshot = cache.toObject();

Cache Factory Functions

Utility functions for creating cache instances with different implementations.

/**
 * Factory function for creating ObjectCache instances
 * Exported from './objectCache' - conflicts with DepTrackingCache version
 * @param seed - Optional initial data to populate cache
 * @returns New ObjectCache instance
 */
function defaultNormalizedCacheFactory(
  seed?: NormalizedCacheObject
): NormalizedCache; // from objectCache.ts

/**
 * Factory function for creating DepTrackingCache instances  
 * Exported from './depTrackingCache' - conflicts with ObjectCache version
 * The actual export depends on import resolution order
 * @param seed - Optional initial data to populate cache
 * @returns New DepTrackingCache instance
 */
function defaultNormalizedCacheFactory(
  seed?: NormalizedCacheObject
): NormalizedCache; // from depTrackingCache.ts

/**
 * Factory function for creating MapCache instances
 * @param seed - Optional initial data to populate cache
 * @returns New MapCache instance
 */
function mapNormalizedCacheFactory(
  seed?: NormalizedCacheObject
): NormalizedCache;

Usage Example:

import { 
  defaultNormalizedCacheFactory,
  mapNormalizedCacheFactory 
} from "apollo-cache-inmemory";

// Create different cache types
const objectCache = defaultNormalizedCacheFactory();
const mapCache = mapNormalizedCacheFactory();

// Use with InMemoryCache
const cache = new InMemoryCache({
  resultCaching: false // Uses ObjectCache
});

const optimizedCache = new InMemoryCache({
  resultCaching: true // Uses DepTrackingCache
});

Performance Characteristics

ObjectCache

  • Best for: Simple applications, development, testing
  • Memory usage: Low
  • Read performance: Fast
  • Write performance: Fast
  • Advanced features: None

DepTrackingCache

  • Best for: Production apps with repeated queries, complex UIs
  • Memory usage: Higher (stores dependencies)
  • Read performance: Very fast (memoized)
  • Write performance: Moderate (dependency invalidation)
  • Advanced features: Automatic memoization, smart invalidation

MapCache

  • Best for: Large datasets, many cache entries
  • Memory usage: Moderate
  • Read performance: Excellent (Map lookups)
  • Write performance: Excellent (Map operations)
  • Advanced features: Better garbage collection, iteration support

Cache Selection Guide

// Choose cache implementation based on needs

// Simple apps - use ObjectCache
const basicCache = new InMemoryCache({
  resultCaching: false // Uses ObjectCache internally
});

// Production apps with repeated queries - use DepTrackingCache  
const productionCache = new InMemoryCache({
  resultCaching: true // Uses DepTrackingCache internally
});

// Large datasets - consider MapCache for custom implementations
class CustomMapCache extends InMemoryCache {
  constructor(config) {
    super(config);
    // Override internal cache with MapCache
    this.data = new MapCache();
  }
}

Types

interface NormalizedCache {
  get(dataId: string): StoreObject;
  set(dataId: string, value: StoreObject): void;
  delete(dataId: string): void;
  clear(): void;
  toObject(): NormalizedCacheObject;
  replace(newData: NormalizedCacheObject): void;
}

interface NormalizedCacheObject {
  [dataId: string]: StoreObject | undefined;
}

interface StoreObject {
  __typename?: string;
  [storeFieldKey: string]: StoreValue;
}

type StoreValue = 
  | number
  | string
  | boolean
  | null
  | undefined
  | StoreObject
  | StoreValue[]
  | IdValue;

interface IdValue {
  type: "id";
  id: string;
  generated: boolean;
}

Custom Cache Implementation

// Implement custom cache for specific requirements
class CustomCache implements NormalizedCache {
  private storage = new Map<string, StoreObject>();
  
  get(dataId: string): StoreObject {
    return this.storage.get(dataId);
  }
  
  set(dataId: string, value: StoreObject): void {
    this.storage.set(dataId, value);
    // Add custom logic (e.g., persistence, compression)
  }
  
  delete(dataId: string): void {
    this.storage.delete(dataId);
  }
  
  clear(): void {
    this.storage.clear();
  }
  
  toObject(): NormalizedCacheObject {
    const obj: NormalizedCacheObject = {};
    this.storage.forEach((value, key) => {
      obj[key] = value;
    });
    return obj;
  }
  
  replace(newData: NormalizedCacheObject): void {
    this.clear();
    Object.entries(newData).forEach(([key, value]) => {
      if (value !== undefined) {
        this.set(key, value);
      }
    });
  }
}

// Use custom cache with InMemoryCache
const cache = new InMemoryCache();
// Note: Direct cache replacement requires extending InMemoryCache