import Dexie, { type Table } from "dexie"; export const HISTORY_CAP = 50; export type VoiceRecord = { id?: number; name: string; blob: Blob; sampleRate: number; durationMs: number; createdAt: number; isFavorite: boolean; }; export type SpeakerRef = { letter: "A" | "B" | "C" | "D"; voiceId: number }; export type HistoryRecord = { id?: number; text: string; modelId: string; voiceId?: number; language?: string; params: Record; audioBlob: Blob; createdAt: number; kind?: "single" | "dialog"; seedUsed?: number; speakers?: SpeakerRef[]; }; class DB extends Dexie { voices!: Table; history!: Table; constructor() { super("chatterbox-voice-studio"); this.version(1).stores({ voices: "++id, name, createdAt, isFavorite", history: "++id, createdAt", }); this.version(2).stores({ voices: "++id, name, createdAt, isFavorite", history: "++id, createdAt", }).upgrade(async (tx) => { // Backfill new fields on existing rows so listings stay consistent. await tx.table("history").toCollection().modify((r: HistoryRecord) => { if (!r.kind) r.kind = "single"; }); }); } } export const db = new DB(); export async function addVoice( v: Omit & Partial>, ): Promise { return db.voices.add({ ...v, isFavorite: v.isFavorite ?? false, createdAt: Date.now(), }); } export async function listVoices(): Promise { return db.voices.orderBy("createdAt").reverse().toArray(); } export async function deleteVoice(id: number): Promise { await db.voices.delete(id); } export async function setFavorite(id: number, fav: boolean): Promise { await db.voices.update(id, { isFavorite: fav }); } export async function addHistory( h: Omit, ): Promise { const id = await db.history.add({ ...h, createdAt: Date.now() }); const count = await db.history.count(); if (count > HISTORY_CAP) { const overflow = count - HISTORY_CAP; const oldest = await db.history.orderBy("createdAt").limit(overflow).primaryKeys(); await db.history.bulkDelete(oldest); } return id; } export async function listHistory(): Promise { return db.history.orderBy("createdAt").reverse().toArray(); } export async function clearHistory(): Promise { await db.history.clear(); }