SPB Git

spb/zyquo-cloud-web Public MIT

Zyquo Cloud Web — every cloud model, one beautiful chat, entirely in your browser.

TypeScript 81.9% CSS 8.9% JavaScript 7.5% Shell 1.1% HTML 0.6%
2.2 KB · 64 lines typescript
Raw Blame History
1/*2 *  conversations.ts3 *  Zyquo Cloud Web4 *5 *  Author: Simon-Pierre Boucher6 *  Mail: contact@spboucher.ai7 *8 *  Conversation persistence — IndexedDB (namespace zyquo.cloud.web), one9 *  record per conversation, autosaved on every mutation by the store layer.10 *  Includes schema versioning/migration for stored records.11 */1213import type { Conversation } from '../types'14import { dbClear, dbDelete, dbGetAll, dbPut, STORE_CONVERSATIONS } from './db'1516/** Bump when the stored Conversation shape changes; migrate() upgrades old records. */17const SCHEMA_VERSION = 11819interface StoredConversation extends Conversation {20  schemaVersion?: number21}2223/** Upgrades a stored record from any older schema to the current one. */24function migrate(record: StoredConversation): Conversation {25  const version = record.schemaVersion ?? 126  // v1 is current — future migrations chain here (v1 → v2 → …).27  void version28  const { schemaVersion: _schemaVersion, ...conversation } = record29  return {30    ...conversation,31    parameters: conversation.parameters ?? {},32    messages: conversation.messages ?? [],33    pinned: conversation.pinned ?? false,34    hasAutoTitle: conversation.hasAutoTitle ?? true,35  }36}3738/** All conversations, newest-first by updatedAt. */39export async function loadConversations(): Promise<Conversation[]> {40  const records = await dbGetAll<StoredConversation>(STORE_CONVERSATIONS)41  return records.map(migrate).sort((a, b) => b.updatedAt - a.updatedAt)42}4344export async function saveConversation(conversation: Conversation): Promise<void> {45  const record: StoredConversation = { ...conversation, schemaVersion: SCHEMA_VERSION }46  await dbPut(STORE_CONVERSATIONS, record)47}4849export async function deleteConversation(id: string): Promise<void> {50  await dbDelete(STORE_CONVERSATIONS, id)51}5253export async function clearConversations(): Promise<void> {54  await dbClear(STORE_CONVERSATIONS)55}5657/** Case-insensitive search across titles and all message text. */58export function matchesSearch(conversation: Conversation, query: string): boolean {59  const q = query.trim().toLowerCase()60  if (q === '') return true61  if (conversation.title.toLowerCase().includes(q)) return true62  return conversation.messages.some((message) => message.text.toLowerCase().includes(q))63}64