ui : reuse the conversation load read for sibling info

Opening a conversation read every message from the database twice: once
in loadConversation for the active path, once in ChatMessages for the
sibling map. Hand the freshly read array over once so the chat screen
builds sibling info from it, and set the conversation and its messages
in one sync block so effects never see the new conversation paired with
the previous one's messages.

Assisted-by: pi:zai-org/GLM-5.3
This commit is contained in:
Aleksander Grygier
2026-09-06 00:32:35 +02:00
parent 504870c4ec
commit eb07addfa5
2 changed files with 37 additions and 18 deletions
@@ -97,9 +97,17 @@
const conversation = conversationsStore.activeConversation;
if (conversation) {
conversationsStore.getConversationMessages(conversation.id).then((messages) => {
allConversationMessages = messages;
});
// reuse the array loadConversation just read, when present; branch
// actions fall through to a fresh fetch
const preloaded = conversationsStore.consumeLastLoadedMessages(conversation.id);
if (preloaded) {
allConversationMessages = preloaded;
} else {
conversationsStore.getConversationMessages(conversation.id).then((messages) => {
allConversationMessages = messages;
});
}
} else {
allConversationMessages = [];
}
@@ -52,6 +52,13 @@ class ConversationsStore implements ConversationsPreferencesHost {
/** In-flight init run; shared by concurrent callers, reset on failure to allow retry */
private initPromise: Promise<void> | null = null;
/**
* Messages loadConversation just read, handed off once so the chat
* screen can reuse them for sibling info instead of re-fetching the
* whole conversation a second time.
*/
private lastLoadedMessages: { convId: string; messages: DatabaseMessage[] } | null = null;
/**
* Memo of the last findMessageIndex() lookup. Streaming calls it once per
* chunk for the same message, so a validated cache hit keeps that O(1)
@@ -239,6 +246,17 @@ class ConversationsStore implements ConversationsPreferencesHost {
this.preferences.resetPending();
}
/** One-shot handoff of the messages the last loadConversation read. */
consumeLastLoadedMessages(convId: string): DatabaseMessage[] | null {
if (this.lastLoadedMessages?.convId !== convId) return null;
const messages = this.lastLoadedMessages.messages;
this.lastLoadedMessages = null;
return messages;
}
/**
* Creates a new conversation and navigates to it
* @param name - Optional name for the conversation
@@ -512,22 +530,15 @@ class ConversationsStore implements ConversationsPreferencesHost {
// it doesn't belong to this conversation.
this.preferences.pendingCwd = null;
const allMessages = await DatabaseService.getConversationMessages(convId);
// set conversation and messages in one sync block so effects never see
// the new conversation with the previous conversation's messages
this.lastLoadedMessages = { convId, messages: allMessages };
this.activeConversation = conversation;
if (conversation.currNode) {
const allMessages = await DatabaseService.getConversationMessages(convId);
const filteredMessages = filterByLeafNodeId(
allMessages,
conversation.currNode,
false
) as DatabaseMessage[];
this.activeMessages = filteredMessages;
} else {
const messages = await DatabaseService.getConversationMessages(convId);
this.activeMessages = messages;
}
this.activeMessages = conversation.currNode
? (filterByLeafNodeId(allMessages, conversation.currNode, false) as DatabaseMessage[])
: allMessages;
return true;
} catch (error) {