Files
2026-05-27 23:29:53 +01:00

131 lines
3.4 KiB
Markdown

# 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
```ts
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
```ts
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
```ts
type MemoryCacheErrorCode =
| 'CACHE_MEMORY_INVALID_KEY'
| 'CACHE_MEMORY_CAPACITY_EXCEEDED'
function registerMemoryCacheErrorCodes(): void
```
---
## File layout
```text
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`.