import { LRUCache } from 'lru-cache';
/**
 * Correctness-first process-local cache defaults.
 *
 * The cache is always bounded, never returns stale values, and does not extend
 * an entry's life merely because it was read. Durable/cross-process state must
 * continue to live in SQLite or an atomic on-disk snapshot.
 */
export function createMemoryCache(options) {
    if (!Number.isSafeInteger(options.max) || options.max < 1) {
        throw new Error('memory cache max must be a positive integer');
    }
    if (!Number.isFinite(options.ttlMs) || options.ttlMs <= 0) {
        throw new Error('memory cache ttlMs must be positive');
    }
    return new LRUCache({
        max: options.max,
        ttl: options.ttlMs,
        allowStale: false,
        updateAgeOnGet: false,
        updateAgeOnHas: false,
        ttlAutopurge: false,
        // A supplied deterministic clock must be read on every operation; the
        // library's 1ms cached-now optimization follows wall time, not that clock.
        ttlResolution: options.now ? 0 : 1,
        fetchMethod: options.fetchMethod
            ? async (key, staleValue) => options.fetchMethod(key, staleValue)
            : undefined,
        perf: options.now ? { now: options.now } : undefined,
    });
}
