File size: 2,341 Bytes
6337686
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
import { zip } from 'lodash-es'
import { ChatMessageModel, BotId } from '@/lib/bots/bing/types'
import { Storage } from '../storage'

/**
 * conversations:$botId => Conversation[]
 * conversation:$botId:$cid:messages => ChatMessageModel[]
 */

interface Conversation {
  id: string
  createdAt: number
}

type ConversationWithMessages = Conversation & { messages: ChatMessageModel[] }

async function loadHistoryConversations(botId: BotId): Promise<Conversation[]> {
  const key = `conversations:${botId}`
  const { [key]: value } = await Storage.get(key)
  return value || []
}

async function deleteHistoryConversation(botId: BotId, cid: string) {
  const conversations = await loadHistoryConversations(botId)
  const newConversations = conversations.filter((c) => c.id !== cid)
  await Storage.set({ [`conversations:${botId}`]: newConversations })
}

async function loadConversationMessages(botId: BotId, cid: string): Promise<ChatMessageModel[]> {
  const key = `conversation:${botId}:${cid}:messages`
  const { [key]: value } = await Storage.get(key)
  return value || []
}

export async function setConversationMessages(botId: BotId, cid: string, messages: ChatMessageModel[]) {
  const conversations = await loadHistoryConversations(botId)
  if (!conversations.some((c) => c.id === cid)) {
    conversations.unshift({ id: cid, createdAt: Date.now() })
    await Storage.set({ [`conversations:${botId}`]: conversations })
  }
  const key = `conversation:${botId}:${cid}:messages`
  await Storage.set({ [key]: messages })
}

export async function loadHistoryMessages(botId: BotId): Promise<ConversationWithMessages[]> {
  const conversations = await loadHistoryConversations(botId)
  const messagesList = await Promise.all(conversations.map((c) => loadConversationMessages(botId, c.id)))
  return zip(conversations, messagesList).map(([c, messages]) => ({
    id: c!.id,
    createdAt: c!.createdAt,
    messages: messages!,
  }))
}

export async function deleteHistoryMessage(botId: BotId, conversationId: string, messageId: string) {
  const messages = await loadConversationMessages(botId, conversationId)
  const newMessages = messages.filter((m) => m.id !== messageId)
  await setConversationMessages(botId, conversationId, newMessages)
  if (!newMessages.length) {
    await deleteHistoryConversation(botId, conversationId)
  }
}