In-memory caching module for Medusa with TTL support and wildcard invalidation
npx @tessl/cli install tessl/npm-medusajs--cache-inmemory@2.10.0Medusa in-memory cache module provides a simple, Map-based cache store with TTL (time-to-live) functionality for the Medusa e-commerce framework. Designed for development and testing environments, it offers automatic expiration management and pattern-based cache invalidation.
npm install @medusajs/cache-inmemoryimport { initialize } from "@medusajs/cache-inmemory";For CommonJS:
const { initialize } = require("@medusajs/cache-inmemory");import { initialize } from "@medusajs/cache-inmemory";
// Initialize cache service with default 30-second TTL
const cache = await initialize({});
// Initialize cache service with custom TTL
const customCache = await initialize({ ttl: 60 });
// Basic operations
await cache.set("user:123", { name: "Alice", age: 30 });
const user = await cache.get("user:123"); // { name: "Alice", age: 30 }
// TTL-based expiration (data expires after TTL seconds)
await cache.set("temp:data", "temporary", 5); // expires in 5 seconds
// Pattern-based invalidation
await cache.set("products:electronics:1", { name: "Laptop" });
await cache.set("products:electronics:2", { name: "Phone" });
await cache.set("products:books:1", { name: "Novel" });
// Remove all electronics products
await cache.invalidate("products:electronics:*");
// Clear entire cache
await cache.clear();The in-memory cache is built around these key components:
Core functionality for storing and retrieving cached data with automatic expiration.
/**
* Main cache service class implementing ICacheService interface
*/
class InMemoryCacheService {
constructor(
deps: InjectedDependencies,
options?: InMemoryCacheModuleOptions
);
/**
* Retrieve data from the cache
* @param key - Cache key to retrieve
* @returns Promise resolving to cached data or null if not found/expired
*/
get<T>(key: string): Promise<T | null>;
/**
* Store data in the cache with optional TTL
* @param key - Cache key under which to store the data
* @param data - Data to be stored in the cache
* @param ttl - Time to live in seconds (defaults to configured TTL). If 0, operation is ignored.
*/
set<T>(key: string, data: T, ttl?: number): Promise<void>;
}Remove specific cache entries or bulk invalidation using wildcard patterns.
/**
* Delete data from the cache
* Supports wildcard (*) pattern matching for bulk operations
* @param key - Cache key or pattern (e.g., "user:*", "*:active")
*/
invalidate(key: string): Promise<void>;
/**
* Delete the entire cache
* Clears all stored data and timeout references
*/
clear(): Promise<void>;Bootstrap the cache module within the Medusa framework.
/**
* Initialize the cache module with optional configuration
* @param options - Module configuration options or external module declaration
* @returns Promise resolving to ICacheService instance
*/
function initialize(
options?: InMemoryCacheModuleOptions | ExternalModuleDeclaration
): Promise<ICacheService>;/**
* Configuration options for the in-memory cache module
*/
interface InMemoryCacheModuleOptions {
/** Time to keep data in cache (in seconds) */
ttl?: number;
}
/**
* Internal cache record structure
*/
interface CacheRecord<T> {
/** The cached data */
data: T;
/** Expiration timestamp in milliseconds */
expire: number;
}
/**
* Dependency injection container (empty for this module)
*/
type InjectedDependencies = {}import { initialize } from "@medusajs/cache-inmemory";
const cache = await initialize({ ttl: 300 }); // 5-minute TTL
// Store user data
await cache.set("user:alice", {
id: "alice",
name: "Alice Johnson",
preferences: { theme: "dark" }
});
// Retrieve user data
const user = await cache.get<User>("user:alice");
if (user) {
console.log(`Welcome back, ${user.name}!`);
}import { initialize } from "@medusajs/cache-inmemory";
const cache = await initialize({});
// Store temporary data with custom expiration
await cache.set("session:abc123", { userId: "alice" }, 3600); // 1 hour
await cache.set("rate-limit:api", { count: 1 }, 60); // 1 minuteimport { initialize } from "@medusajs/cache-inmemory";
const cache = await initialize({});
// Store related data
await cache.set("products:category:electronics:1", laptop);
await cache.set("products:category:electronics:2", phone);
await cache.set("products:category:books:1", novel);
await cache.set("products:featured:electronics:1", laptop);
// Invalidate all electronics products
await cache.invalidate("products:category:electronics:*");
// Invalidate all featured items
await cache.invalidate("products:featured:*");
// Invalidate specific pattern
await cache.invalidate("products:*:electronics:*");import { initialize } from "@medusajs/cache-inmemory";
// Initialize as Medusa module
const cacheService = await initialize({
ttl: 600 // 10-minute default TTL
});
// Use in your Medusa service
class MyService {
constructor({ cacheService }) {
this.cache = cacheService;
}
async getCachedData(key: string) {
return await this.cache.get(key);
}
}The cache methods are designed to fail gracefully:
get() returns null for non-existent or expired keysset() with TTL of 0 is ignored (no-op)invalidate() safely handles non-existent keys