import type { ConversationSnapshot, ConversationSummary } from "./types"; const MAX_CONVERSATIONS = 20; function isSnapshot(value: unknown): value is ConversationSnapshot { const snapshot = value as ConversationSnapshot; return ( snapshot?.schemaVersion === 1 && typeof snapshot.sessionId === "string" && snapshot.sessionId.length > 0 && typeof snapshot.title === "string" && Array.isArray(snapshot.messages) && typeof snapshot.createdAt === "number" && typeof snapshot.updatedAt === "number" ); } export function parseArchive(raw: string | null): ConversationSnapshot[] { if (!raw) { return []; } try { const parsed = JSON.parse(raw) as unknown; if (!Array.isArray(parsed)) { return []; } return parsed.filter(isSnapshot); } catch { return []; } } export function serializeArchive(snapshots: ConversationSnapshot[]): string { return JSON.stringify(limitArchive(snapshots)); } export function upsertSnapshot( snapshots: ConversationSnapshot[], snapshot: ConversationSnapshot, ): ConversationSnapshot[] { const next = snapshots.filter( (item) => item.sessionId !== snapshot.sessionId, ); next.push(snapshot); return limitArchive(next); } export function findSnapshot( snapshots: ConversationSnapshot[], sessionId: string | null, ): ConversationSnapshot | null { if (!sessionId) { return null; } return snapshots.find((item) => item.sessionId === sessionId) ?? null; } export function listArchivedConversations( snapshots: ConversationSnapshot[], activeSessionId: string | null, ): ConversationSummary[] { return snapshots .filter((snapshot) => snapshot.sessionId !== activeSessionId) .sort((a, b) => b.updatedAt - a.updatedAt) .map((snapshot) => ({ sessionId: snapshot.sessionId, title: snapshot.title, updatedAt: snapshot.updatedAt, })); } export function clearArchived( snapshots: ConversationSnapshot[], activeSessionId: string | null, ): ConversationSnapshot[] { return snapshots.filter((snapshot) => snapshot.sessionId === activeSessionId); } function limitArchive( snapshots: ConversationSnapshot[], ): ConversationSnapshot[] { return [...snapshots] .sort((a, b) => b.updatedAt - a.updatedAt) .slice(0, MAX_CONVERSATIONS); }