import type { NewStoredViewer, SignageViewerStore, StoredViewer, ViewerChanges, } from "../../src/server/store/types.js"; export interface MemoryViewerStore extends SignageViewerStore { readonly viewers: Map; /** Test-only: how many times a viewer row was actually written, which is what heartbeat * coalescing exists to keep small. */ readonly viewerWrites: { count: number }; } export function createMemoryViewerStore( options: { readonly now?: () => Date } = {}, ): MemoryViewerStore { const now = options.now ?? (() => new Date()); const viewers = new Map(); const viewerWrites = { count: 0 }; return { deleteViewer(viewerId: string): Promise { viewers.delete(viewerId); return Promise.resolve(); }, findViewer(viewerId: string): Promise { return Promise.resolve(viewers.get(viewerId)); }, findViewerByKey(viewerKey: string): Promise { for (const viewer of viewers.values()) { if (viewer.viewerKey === viewerKey) { return Promise.resolve(viewer); } } return Promise.resolve(undefined); }, insertViewer(viewer: NewStoredViewer): Promise { viewerWrites.count += 1; viewers.set(viewer.id, { ...viewer, createdAt: now(), lastError: null, lastSeenAt: null }); return Promise.resolve(); }, listViewers(): Promise { return Promise.resolve( [...viewers.values()].sort((left, right) => left.name.localeCompare(right.name)), ); }, updateViewer(viewerId: string, changes: ViewerChanges): Promise { const viewer = viewers.get(viewerId); if (!viewer) { return Promise.resolve(); } viewerWrites.count += 1; const next: Record = { ...viewer }; for (const [key, value] of Object.entries(changes)) { if (value !== undefined) { next[key] = value; } } viewers.set(viewerId, next as unknown as StoredViewer); return Promise.resolve(); }, viewers, viewerWrites, }; }