Multiple cache storage backend implementations optimized for different use cases and performance requirements.
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();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" });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();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
});// 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();
}
}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;
}// 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