File size: 8,684 Bytes
6b9d0d8
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
```mermaid

sequenceDiagram

    participant Store as πŸ—„οΈ Stores

    participant DbSvc as βš™οΈ DatabaseService

    participant Dexie as πŸ“¦ Dexie ORM

    participant IDB as πŸ’Ύ IndexedDB



    Note over DbSvc: Stateless service - all methods static<br/>Database: "LlamacppWebui"



    %% ═══════════════════════════════════════════════════════════════════════════

    Note over Store,IDB: πŸ“Š SCHEMA

    %% ═══════════════════════════════════════════════════════════════════════════



    rect rgb(240, 248, 255)

        Note over IDB: conversations table:<br/>id (PK), lastModified, currNode, name

    end



    rect rgb(255, 248, 240)

        Note over IDB: messages table:<br/>id (PK), convId (FK), type, role, timestamp,<br/>parent, children[], content, thinking,<br/>toolCalls, extra[], model, timings

    end



    %% ═══════════════════════════════════════════════════════════════════════════

    Note over Store,IDB: πŸ’¬ CONVERSATIONS CRUD

    %% ═══════════════════════════════════════════════════════════════════════════



    Store->>DbSvc: createConversation(name)

    activate DbSvc

    DbSvc->>DbSvc: Generate UUID

    DbSvc->>Dexie: db.conversations.add({id, name, lastModified, currNode: ""})

    Dexie->>IDB: INSERT

    IDB-->>Dexie: success

    DbSvc-->>Store: DatabaseConversation

    deactivate DbSvc



    Store->>DbSvc: getConversation(convId)

    DbSvc->>Dexie: db.conversations.get(convId)

    Dexie->>IDB: SELECT WHERE id = ?

    IDB-->>DbSvc: DatabaseConversation



    Store->>DbSvc: getAllConversations()

    DbSvc->>Dexie: db.conversations.orderBy('lastModified').reverse().toArray()

    Dexie->>IDB: SELECT ORDER BY lastModified DESC

    IDB-->>DbSvc: DatabaseConversation[]



    Store->>DbSvc: updateConversation(convId, updates)

    DbSvc->>Dexie: db.conversations.update(convId, {...updates, lastModified})

    Dexie->>IDB: UPDATE



    Store->>DbSvc: deleteConversation(convId)

    activate DbSvc

    DbSvc->>Dexie: db.conversations.delete(convId)

    Dexie->>IDB: DELETE FROM conversations

    DbSvc->>Dexie: db.messages.where('convId').equals(convId).delete()

    Dexie->>IDB: DELETE FROM messages WHERE convId = ?

    deactivate DbSvc



    %% ═══════════════════════════════════════════════════════════════════════════

    Note over Store,IDB: πŸ“ MESSAGES CRUD

    %% ═══════════════════════════════════════════════════════════════════════════



    Store->>DbSvc: createRootMessage(convId)

    activate DbSvc

    DbSvc->>DbSvc: Create root message {type: "root", parent: null}

    DbSvc->>Dexie: db.messages.add(rootMsg)

    Dexie->>IDB: INSERT

    DbSvc-->>Store: rootMessageId

    deactivate DbSvc



    Store->>DbSvc: createSystemMessage(convId, content, parentId)

    activate DbSvc

    DbSvc->>DbSvc: Create message {role: "system", parent: parentId}

    DbSvc->>Dexie: db.messages.add(systemMsg)

    Dexie->>IDB: INSERT

    DbSvc-->>Store: DatabaseMessage

    deactivate DbSvc



    Store->>DbSvc: createMessageBranch(message, parentId)

    activate DbSvc

    DbSvc->>DbSvc: Generate UUID for new message

    DbSvc->>Dexie: db.messages.add({...message, id, parent: parentId})

    Dexie->>IDB: INSERT message



    alt parentId exists

        DbSvc->>Dexie: db.messages.get(parentId)

        Dexie->>IDB: SELECT parent

        DbSvc->>DbSvc: parent.children.push(newId)

        DbSvc->>Dexie: db.messages.update(parentId, {children})

        Dexie->>IDB: UPDATE parent.children

    end



    DbSvc->>Dexie: db.conversations.update(convId, {currNode: newId})

    Dexie->>IDB: UPDATE conversation.currNode

    DbSvc-->>Store: DatabaseMessage

    deactivate DbSvc



    Store->>DbSvc: getConversationMessages(convId)

    DbSvc->>Dexie: db.messages.where('convId').equals(convId).toArray()

    Dexie->>IDB: SELECT WHERE convId = ?

    IDB-->>DbSvc: DatabaseMessage[]



    Store->>DbSvc: updateMessage(msgId, updates)

    DbSvc->>Dexie: db.messages.update(msgId, updates)

    Dexie->>IDB: UPDATE



    Store->>DbSvc: deleteMessage(msgId)

    DbSvc->>Dexie: db.messages.delete(msgId)

    Dexie->>IDB: DELETE



    %% ═══════════════════════════════════════════════════════════════════════════

    Note over Store,IDB: 🌳 BRANCHING OPERATIONS

    %% ═══════════════════════════════════════════════════════════════════════════



    Store->>DbSvc: updateCurrentNode(convId, nodeId)

    DbSvc->>Dexie: db.conversations.update(convId, {currNode: nodeId, lastModified})

    Dexie->>IDB: UPDATE



    Store->>DbSvc: deleteMessageCascading(msgId)

    activate DbSvc

    DbSvc->>DbSvc: findDescendantMessages(msgId, allMessages)

    Note right of DbSvc: Recursively find all children

    loop each descendant

        DbSvc->>Dexie: db.messages.delete(descendantId)

        Dexie->>IDB: DELETE

    end

    DbSvc->>Dexie: db.messages.delete(msgId)

    Dexie->>IDB: DELETE target message



    alt target message has a parent

        DbSvc->>Dexie: db.messages.get(parentId)

        DbSvc->>DbSvc: parent.children.filter(id !== msgId)

        DbSvc->>Dexie: db.messages.update(parentId, {children})

        Note right of DbSvc: Remove deleted message from parent's children[]

    end

    deactivate DbSvc



    %% ═══════════════════════════════════════════════════════════════════════════

    Note over Store,IDB: πŸ“₯ IMPORT

    %% ═══════════════════════════════════════════════════════════════════════════



    Store->>DbSvc: importConversations(data)

    activate DbSvc

    loop each conversation in data

        DbSvc->>Dexie: db.conversations.get(conv.id)

        alt conversation already exists

            Note right of DbSvc: Skip duplicate (keep existing)

        else conversation is new

            DbSvc->>Dexie: db.conversations.add(conversation)

            Dexie->>IDB: INSERT conversation

            loop each message

                DbSvc->>Dexie: db.messages.add(message)

                Dexie->>IDB: INSERT message

            end

        end

    end

    deactivate DbSvc



    %% ═══════════════════════════════════════════════════════════════════════════

    Note over Store,IDB: πŸ”— MESSAGE TREE UTILITIES

    %% ═══════════════════════════════════════════════════════════════════════════



    Note over DbSvc: Used by stores (imported from utils):



    rect rgb(240, 255, 240)

        Note over DbSvc: filterByLeafNodeId(messages, leafId)<br/>β†’ Returns path from root to leaf<br/>β†’ Used to display current branch

    end



    rect rgb(240, 255, 240)

        Note over DbSvc: findLeafNode(startId, messages)<br/>β†’ Traverse to deepest child<br/>β†’ Used for branch navigation

    end



    rect rgb(240, 255, 240)

        Note over DbSvc: findDescendantMessages(msgId, messages)<br/>β†’ Find all children recursively<br/>β†’ Used for cascading deletes

    end

```