import { LocalStorage } from "@raycast/api"; import { randomUUID } from "node:crypto"; import { getPreferences } from "./preferences"; import type { PlaceholderMapping, SessionMode, VelumSession } from "./types"; const SESSIONS_STORAGE_KEY = "velum.sessions.v1"; const ACTIVE_SESSION_STORAGE_KEY = "velum.sessions.active.v1"; function nowIso(): string { return new Date().toISOString(); } function dayKey(date = new Date()): string { return date.toISOString().slice(0, 10); } function sessionSort(a: VelumSession, b: VelumSession): number { return Date.parse(b.updatedAt) - Date.parse(a.updatedAt); } async function saveSessions(sessions: VelumSession[]): Promise { const maxSessions = getPreferences().maxSessions; const pruned = [...sessions].sort(sessionSort).slice(0, maxSessions); await LocalStorage.setItem(SESSIONS_STORAGE_KEY, JSON.stringify(pruned)); const activeId = await getActiveSessionId(); if (activeId && !pruned.some((session) => session.id === activeId)) { await LocalStorage.setItem(ACTIVE_SESSION_STORAGE_KEY, pruned[0]?.id ?? ""); } } export async function listSessions(): Promise { const raw = await LocalStorage.getItem(SESSIONS_STORAGE_KEY); if (!raw) { return []; } try { return (JSON.parse(raw) as VelumSession[]).sort(sessionSort); } catch { await LocalStorage.removeItem(SESSIONS_STORAGE_KEY); return []; } } export async function getActiveSessionId(): Promise { const id = await LocalStorage.getItem(ACTIVE_SESSION_STORAGE_KEY); return id || undefined; } export async function setActiveSession(id: string): Promise { await LocalStorage.setItem(ACTIVE_SESSION_STORAGE_KEY, id); } export async function createSession(name?: string): Promise { const timestamp = nowIso(); const session: VelumSession = { id: randomUUID(), name: name || `Sitzung ${new Date().toLocaleString()}`, createdAt: timestamp, updatedAt: timestamp, mapping: {}, }; const sessions = await listSessions(); await saveSessions([session, ...sessions]); await setActiveSession(session.id); return session; } export async function getSession( id: string, ): Promise { const sessions = await listSessions(); return sessions.find((session) => session.id === id); } export async function getActiveSession(): Promise { const sessions = await listSessions(); const activeId = await getActiveSessionId(); const active = sessions.find((session) => session.id === activeId); if (active) { return active; } return createSession(); } export async function resolveSessionForMode( mode: SessionMode, ): Promise { if (mode === "new-each-request") { return createSession(`Anfrage ${new Date().toLocaleString()}`); } if (mode === "daily") { const name = `Tag ${dayKey()}`; const existing = (await listSessions()).find( (session) => session.name === name, ); if (existing) { await setActiveSession(existing.id); return existing; } return createSession(name); } return getActiveSession(); } export async function resolveDefaultSession(): Promise { return resolveSessionForMode(getPreferences().sessionMode); } export async function updateSessionMapping( id: string, mapping: PlaceholderMapping, entityTypes?: string[], ): Promise { const sessions = await listSessions(); const timestamp = nowIso(); const index = sessions.findIndex((session) => session.id === id); if (index === -1) { const created: VelumSession = { id, name: `Sitzung ${new Date().toLocaleString()}`, createdAt: timestamp, updatedAt: timestamp, mapping, entityTypes, }; await saveSessions([created, ...sessions]); return created; } const updated: VelumSession = { ...sessions[index], mapping, entityTypes, updatedAt: timestamp, }; const next = [...sessions]; next[index] = updated; await saveSessions(next); return updated; } export async function renameSession(id: string, name: string): Promise { const sessions = await listSessions(); await saveSessions( sessions.map((session) => session.id === id ? { ...session, name: name.trim() || session.name, updatedAt: nowIso() } : session, ), ); } export async function clearSessionMapping(id: string): Promise { const sessions = await listSessions(); await saveSessions( sessions.map((session) => session.id === id ? { ...session, mapping: {}, updatedAt: nowIso() } : session, ), ); } export async function deleteSession(id: string): Promise { const sessions = await listSessions(); const next = sessions.filter((session) => session.id !== id); await saveSessions(next); const activeId = await getActiveSessionId(); if (activeId === id) { if (next[0]) { await setActiveSession(next[0].id); } else { await LocalStorage.removeItem(ACTIVE_SESSION_STORAGE_KEY); } } } export async function deleteAllSessions(): Promise { await LocalStorage.removeItem(SESSIONS_STORAGE_KEY); await LocalStorage.removeItem(ACTIVE_SESSION_STORAGE_KEY); } export function countMappingEntries(mapping: PlaceholderMapping): number { return Object.keys(mapping).length; }