@molecule/api-cache-memory
v1.0.1
Published
In-memory cache provider for molecule.dev.
Readme
@molecule/api-cache-memory
Auto-generated, AI-first package reference for the molecule.dev ecosystem. It is written to be read by coding agents as much as by people, and is generated from this package's source — edit
src/index.tsJSDoc, not this file.
In-memory cache provider for molecule.dev.
A simple, zero-dependency cache provider for development and testing. Not suitable for production multi-instance deployments.
Type
provider
Installation
npm install @molecule/api-cache-memory @molecule/api-cacheAPI
Interfaces
CacheEntry
A cached entry with optional TTL and tags.
interface CacheEntry<T = unknown> {
value: T
expiresAt?: number
tags?: string[]
}CacheOptions
Cache entry options.
interface CacheOptions {
/**
* Time-to-live in seconds.
*/
ttl?: number
/**
* Tags for cache invalidation.
*/
tags?: string[]
}CacheProvider
Cache provider interface.
All cache providers must implement this interface.
interface CacheProvider {
/**
* Gets a value from the cache.
*
* @param key - Cache key
*/
get<T = unknown>(key: string): Promise<T | undefined>
/**
* Sets a value in the cache.
*
* @param key - Cache key
* @param value - Value to cache
* @param options - Cache options (ttl, tags)
*/
set<T = unknown>(key: string, value: T, options?: CacheOptions): Promise<void>
/**
* Deletes a value from the cache.
*
* @param key - Cache key
* @returns true if the key existed and was deleted
*/
delete(key: string): Promise<boolean>
/**
* Checks if a key exists in the cache.
*
* @param key - Cache key
*/
has(key: string): Promise<boolean>
/**
* Gets multiple values from the cache.
*
* @param keys - Array of cache keys
*/
getMany?<T = unknown>(keys: string[]): Promise<Map<string, T>>
/**
* Sets multiple values in the cache.
*
* @param entries - Array of [key, value] pairs
* @param options - Cache options applied to all entries
*/
setMany?<T = unknown>(entries: Array<[string, T]>, options?: CacheOptions): Promise<void>
/**
* Deletes multiple values from the cache.
*
* @param keys - Array of cache keys
*/
deleteMany?(keys: string[]): Promise<number>
/**
* Invalidates all cache entries with the given tag.
*
* @param tag - Tag to invalidate
*/
invalidateTag?(tag: string): Promise<void>
/**
* Clears all cache entries.
*/
clear?(): Promise<void>
/**
* Closes the cache connection.
*/
close?(): Promise<void>
/**
* Gets or sets a value using a factory function.
*
* @param key - Cache key
* @param factory - Function to generate the value if not cached
* @param options - Cache options
*/
getOrSet?<T = unknown>(key: string, factory: () => Promise<T>, options?: CacheOptions): Promise<T>
}MemoryOptions
Options for creating an in-memory cache provider.
interface MemoryOptions {
/**
* Maximum number of entries to store (LRU eviction).
*/
maxSize?: number
/**
* Default TTL in seconds.
*/
defaultTtl?: number
/**
* Interval in ms for cleaning up expired entries.
*/
cleanupInterval?: number
}Functions
createProvider(options)
Creates an in-memory cache provider with LRU eviction, TTL expiration, and tag-based invalidation. Suitable for development and single-instance deployments — not recommended for multi-instance production.
function createProvider(options?: MemoryOptions): CacheProvideroptions— Memory cache options (max size, default TTL, cleanup interval).
Returns: A CacheProvider backed by an in-memory Map.
Constants
provider
The provider implementation.
const provider: CacheProviderCore Interface
Implements @molecule/api-cache interface.
Bond Wiring
Setup function to register this provider with the core interface:
import { setProvider } from '@molecule/api-cache'
import { provider } from '@molecule/api-cache-memory'
export function setupCacheMemory(): void {
setProvider(provider)
}Injection Notes
Requirements
Peer dependencies:
@molecule/api-cache^1.0.1
Runtime Dependencies
@molecule/api-cache
E2E Tests
Integration checklist — exercise the REAL behavior end-to-end (drive the app action that reads/writes this cache in the live preview, no mocks), adapt each item to this app's actual screens/flows, and check every box off one by one. A box you can't check is an integration bug to fix — not a skip:
- [ ]
getOrSet(key, factory, options)computes ONCE on a miss and serves the cached copy afterward: drive the same screen/endpoint twice withinCacheOptions.ttland confirm the expensive factory (DB/upstream call) runs only on the FIRST load — the second read returns the cached value without re-running it. - [ ]
set(key, value)thenget<T>(key)round-trips the same value back into the app (the cached data renders identically to the source data). - [ ] Deletion reflects a miss: after
delete(key),has(key)isfalseandget(key)returnsundefined, so the app recomputes fresh from source instead of serving the removed entry. - [ ] TTL expiry refetches: once
CacheOptions.ttlseconds elapse, the next read recomputes fresh data — a stale value is NEVER served past its TTL. - [ ] A write that changes the underlying record invalidates its key (via
delete()or a re-set()) so the very next read reflects the change — the app never serves a stale cached copy after an update. - [ ] AUTHORIZATION: a per-user or per-tenant value is cached under a key that
INCLUDES the user/tenant id (
user:123:profile, never a globalprofile). Load user A's data, then user B's — B must receive B's own data, never A's cached copy. A shared key for per-user data is a cross-user data leak, not an optimization. - [ ] A cache backend failure or miss DEGRADES to computing from source: the request still succeeds (getProvider()/get() unavailable falls back to the real query) rather than erroring the whole request.
