@@ -6,6 +6,7 @@ import { filterByLeafNodeId, findLeafNode, findDescendantMessages } from '$lib/u
66import { browser } from '$app/environment' ;
77import { goto } from '$app/navigation' ;
88import { extractPartialThinking } from '$lib/utils/thinking' ;
9+ import { toast } from 'svelte-sonner' ;
910
1011/**
1112 * ChatStore - Central state management for chat conversations and AI interactions
@@ -1004,6 +1005,87 @@ class ChatStore {
10041005 URL . revokeObjectURL ( url ) ;
10051006 }
10061007
1008+ /**
1009+ * Exports all conversations with their messages as a JSON file
1010+ */
1011+ async exportAllConversations ( ) : Promise < void > {
1012+ try {
1013+ const allConversations = await DatabaseStore . getAllConversations ( ) ;
1014+ if ( allConversations . length === 0 ) {
1015+ throw new Error ( 'No conversations to export' ) ;
1016+ }
1017+
1018+ const allData = await Promise . all (
1019+ allConversations . map ( async ( conv ) => {
1020+ const messages = await DatabaseStore . getConversationMessages ( conv . id ) ;
1021+ return { conv, messages } ;
1022+ } )
1023+ ) ;
1024+
1025+ const blob = new Blob ( [ JSON . stringify ( allData , null , 2 ) ] , {
1026+ type : 'application/json'
1027+ } ) ;
1028+ const url = URL . createObjectURL ( blob ) ;
1029+ const a = document . createElement ( 'a' ) ;
1030+ a . href = url ;
1031+ a . download = `all_conversations_${ new Date ( ) . toISOString ( ) . split ( 'T' ) [ 0 ] } .json` ;
1032+ document . body . appendChild ( a ) ;
1033+ a . click ( ) ;
1034+ document . body . removeChild ( a ) ;
1035+ URL . revokeObjectURL ( url ) ;
1036+
1037+ toast . success ( `All conversations (${ allConversations . length } ) prepared for download` ) ;
1038+ } catch ( err ) {
1039+ console . error ( 'Failed to export conversations:' , err ) ;
1040+ throw err ;
1041+ }
1042+ }
1043+
1044+ /**
1045+ * Imports conversations from a JSON file
1046+ * Uses DatabaseStore for safe, encapsulated data access
1047+ */
1048+ async importAllConversations ( ) : Promise < void > {
1049+ return new Promise ( ( resolve , reject ) => {
1050+ const input = document . createElement ( 'input' ) ;
1051+ input . type = 'file' ;
1052+ input . accept = '.json' ;
1053+
1054+ input . onchange = async ( e ) => {
1055+ const file = ( e . target as HTMLInputElement ) ?. files ?. [ 0 ] ;
1056+ if ( ! file ) {
1057+ reject ( new Error ( 'No file selected' ) ) ;
1058+ return ;
1059+ }
1060+
1061+ try {
1062+ const text = await file . text ( ) ;
1063+ const importedData : { conv : DatabaseConversation ; messages : DatabaseMessage [ ] } [ ] =
1064+ JSON . parse ( text ) ;
1065+
1066+ if ( ! Array . isArray ( importedData ) ) {
1067+ throw new Error ( 'Invalid file format: expected array of conversations' ) ;
1068+ }
1069+
1070+ const result = await DatabaseStore . importConversations ( importedData ) ;
1071+
1072+ // Refresh UI
1073+ await this . loadConversations ( ) ;
1074+
1075+ toast . success ( `Imported ${ result . imported } conversation(s), skipped ${ result . skipped } ` ) ;
1076+
1077+ resolve ( undefined ) ;
1078+ } catch ( err : unknown ) {
1079+ const message = err instanceof Error ? err . message : 'Unknown error' ;
1080+ console . error ( 'Failed to import conversations:' , err ) ;
1081+ reject ( new Error ( `Import failed: ${ message } ` ) ) ;
1082+ }
1083+ } ;
1084+
1085+ input . click ( ) ;
1086+ } ) ;
1087+ }
1088+
10071089 /**
10081090 * Deletes a conversation and all its messages
10091091 * @param convId - The conversation ID to delete
@@ -1481,6 +1563,8 @@ export const maxContextError = () => chatStore.maxContextError;
14811563
14821564export const createConversation = chatStore . createConversation . bind ( chatStore ) ;
14831565export const downloadConversation = chatStore . downloadConversation . bind ( chatStore ) ;
1566+ export const exportAllConversations = chatStore . exportAllConversations . bind ( chatStore ) ;
1567+ export const importAllConversations = chatStore . importAllConversations . bind ( chatStore ) ;
14841568export const deleteConversation = chatStore . deleteConversation . bind ( chatStore ) ;
14851569export const sendMessage = chatStore . sendMessage . bind ( chatStore ) ;
14861570export const gracefulStop = chatStore . gracefulStop . bind ( chatStore ) ;
0 commit comments