/** * In-memory settings provider fixture: the smallest real subclass of the seam, * used by the base-class behavior suite in place of a file- or network-backed * provider. Kept in `tests/` because production providers live in their own * packages. */ import { Settings, type SettingsNamespace } from '../src/index.ts' /** In-memory provider exposing the protected seam hooks to tests. */ export class MemorySettings extends Settings { /** Raw document the provider "storage" currently holds. */ doc: Record /** Every persist() call observed, in order. */ persisted: Array<{ ns: SettingsNamespace; section: Record }> = [] /** When false, update() must reject before reaching persist(). */ writableFlag: boolean /** Artificial persist latency so tests can interleave concurrent updates. */ persistDelayMs: number constructor(ctx: ConstructorParameters[0], options?: { doc?: Record writable?: boolean persistDelayMs?: number }) { super(ctx) this.doc = structuredClone(options?.doc ?? {}) this.writableFlag = options?.writable ?? true this.persistDelayMs = options?.persistDelayMs ?? 0 } get writable(): boolean { return this.writableFlag } protected load(): Promise> { return Promise.resolve(structuredClone(this.doc)) } protected async persist(ns: SettingsNamespace, section: Record): Promise { if (this.persistDelayMs > 0) { await new Promise(resolve => setTimeout(resolve, this.persistDelayMs)) } this.persisted.push({ ns, section: structuredClone(section) }) this.doc[ns] = structuredClone(section) } /** Simulate an external storage change reaching the provider. */ pushExternal(doc: Record): void { this.doc = structuredClone(doc) this.publish(structuredClone(doc)) } }