3.4 KiB
OpenSpec Change: enterprise-server-cache-memory
- Change ID: enterprise-server-cache-memory
- Package:
@suaveplan/cache-memory - Category: server/data
- Target path:
server/data/cache-memory - Status: PROPOSED
- Date: 2026-04-24
- Reference spec:
/mnt/s/web/suaveplan/enterprise/cache-memory.md
Summary
Deliver @suaveplan/cache-memory on the genesis branch from scratch at enterprise quality. The package provides a zero-dependency, in-process LRU + TTL cache adapter implementing the same interface contract as @suaveplan/cache-redis. It is the primary testing stand-in and the default cache for single-server deployments. Genesis ships with a doubly-linked-list LRU eviction algorithm, injectable Clock for deterministic time testing, Zod-validated options, OTel counters/histograms, structured logging, and 100% test coverage via property-based tests.
Current-state audit (genesis)
Does not exist on genesis — fresh build.
Available workspace deps on genesis
| Package | Role |
|---|---|
@suaveplan/error (workspace:^) |
Typed error codes for CACHE_MEMORY.* |
@suaveplan/types (workspace:^) |
StorageLike, LoggerLike, Clock |
@suaveplan/logger (workspace:^) |
Structured logs |
zod (catalog:forms) |
Options validation |
@opentelemetry/api (catalog:observability) |
Counters + histograms |
tslib (catalog:build) |
Runtime helpers |
Public API surface
Adapter
class MemoryCacheAdapter {
constructor(options?: MemoryCacheOptions)
get(key: string): Promise<Uint8Array | undefined>
set(key: string, value: Uint8Array, ttlMs?: number): Promise<void>
delete(key: string): Promise<boolean>
has(key: string): Promise<boolean>
list(prefix?: string): Promise<string[]>
clear(): Promise<void>
ttl(key: string): Promise<number | undefined>
size(): number
stats(): CacheStats
}
function createMemoryCacheAdapter(options?: MemoryCacheOptions): MemoryCacheAdapter
Options + types
interface MemoryCacheOptions {
maxSize?: number // max number of entries, default: 1000
defaultTtlMs?: number // default TTL when none supplied; undefined = no expiry
clock?: Clock // injectable for testing
logger?: LoggerLike
}
interface CacheStats {
hits: number
misses: number
evictions: number
size: number
hitRate: number
}
const MemoryCacheOptionsSchema: z.ZodSchema<MemoryCacheOptions>
Error codes
type MemoryCacheErrorCode =
| 'CACHE_MEMORY_INVALID_KEY'
| 'CACHE_MEMORY_CAPACITY_EXCEEDED'
function registerMemoryCacheErrorCodes(): void
File layout
server/data/cache-memory/
package.json
tsconfig.json
vitest.config.ts
src/
index.ts
error-codes.ts
constants/
index.ts
types/
cache-memory.types.ts
cache-memory.types.md
adapter/
memory-cache-adapter/
memory-cache-adapter.ts
memory-cache-adapter.md
memory-cache-adapter.types.ts
memory-cache-adapter.test.ts
index.ts
lru/
lru-cache/
lru-cache.ts
lru-cache.md
lru-cache.test.ts
index.ts
tests/
property.test.ts
Impact
Downstream consumers: testing utilities, unit-test doubles for packages that depend on cache-redis. Universal helper — no Node.js IO, pure in-process.
Prerequisites on Verdaccio: @suaveplan/error, @suaveplan/types, @suaveplan/logger.