mirror of
https://github.com/CherryHQ/cherry-studio.git
synced 2026-01-07 05:39:05 +08:00
refactor: merge messageThunk.v2.ts into messageThunk.ts
Remove the confusing V2 naming from message thunk functions to avoid conflicts with the upcoming real V2 data refactoring. Changes: - Inline V2 function implementations directly into messageThunk.ts - Replace V2 function calls with direct dbService calls - Remove messageThunk.v2.ts file - Remove misleading "V2 DATA&UI REFACTORING" header comments The V2 suffix was originally added for agent session support, not for a data layer refactoring. This cleanup clears the naming space for the actual V2 refactoring work.
This commit is contained in:
parent
078cf39313
commit
ca2b0ac28d
@ -81,9 +81,7 @@ const AgentSessionMessages: React.FC<Props> = ({ agentId, sessionId }) => {
|
||||
|
||||
// Listen for send message events to auto-scroll to bottom
|
||||
useEffect(() => {
|
||||
const unsubscribes = [
|
||||
EventEmitter.on(EVENT_NAMES.SEND_MESSAGE, scrollToBottom)
|
||||
]
|
||||
const unsubscribes = [EventEmitter.on(EVENT_NAMES.SEND_MESSAGE, scrollToBottom)]
|
||||
return () => unsubscribes.forEach((unsub) => unsub())
|
||||
}, [scrollToBottom])
|
||||
|
||||
|
||||
@ -162,7 +162,7 @@ const Messages: React.FC<MessagesProps> = ({ assistant, topic, setActiveTopic, o
|
||||
|
||||
const { message: clearMessage } = getUserMessage({ assistant, topic, type: 'clear' })
|
||||
dispatch(newMessagesActions.addMessage({ topicId: topic.id, message: clearMessage }))
|
||||
await saveMessageAndBlocksToDB(clearMessage, [])
|
||||
await saveMessageAndBlocksToDB(topic.id, clearMessage, [])
|
||||
|
||||
scrollToBottom()
|
||||
} finally {
|
||||
|
||||
@ -19,6 +19,7 @@ import { AiSdkToChunkAdapter } from '@renderer/aiCore/chunk/AiSdkToChunkAdapter'
|
||||
import { AgentApiClient } from '@renderer/api/agent'
|
||||
import db from '@renderer/databases'
|
||||
import { fetchMessagesSummary, transformMessagesAndFetch } from '@renderer/services/ApiService'
|
||||
import { dbService } from '@renderer/services/db'
|
||||
import { DbService } from '@renderer/services/db/DbService'
|
||||
import FileManager from '@renderer/services/FileManager'
|
||||
import { BlockManager } from '@renderer/services/messageStreaming/BlockManager'
|
||||
@ -57,18 +58,18 @@ import { mutate } from 'swr'
|
||||
import type { AppDispatch, RootState } from '../index'
|
||||
import { removeManyBlocks, updateOneBlock, upsertManyBlocks, upsertOneBlock } from '../messageBlock'
|
||||
import { newMessagesActions, selectMessagesForTopic } from '../newMessage'
|
||||
import {
|
||||
bulkAddBlocksV2,
|
||||
clearMessagesFromDBV2,
|
||||
deleteMessageFromDBV2,
|
||||
deleteMessagesFromDBV2,
|
||||
loadTopicMessagesThunkV2,
|
||||
saveMessageAndBlocksToDBV2,
|
||||
updateBlocksV2,
|
||||
updateFileCountV2,
|
||||
updateMessageV2,
|
||||
updateSingleBlockV2
|
||||
} from './messageThunk.v2'
|
||||
// import {
|
||||
// bulkAddBlocksV2,
|
||||
// clearMessagesFromDBV2,
|
||||
// deleteMessageFromDBV2,
|
||||
// deleteMessagesFromDBV2,
|
||||
// loadTopicMessagesThunkV2,
|
||||
// saveMessageAndBlocksToDBV2,
|
||||
// updateBlocksV2,
|
||||
// updateFileCountV2,
|
||||
// updateMessageV2,
|
||||
// updateSingleBlockV2
|
||||
// } from './messageThunk.v2'
|
||||
|
||||
const logger = loggerService.withContext('MessageThunk')
|
||||
|
||||
@ -363,9 +364,9 @@ const createAgentMessageStream = async (
|
||||
return createSSEReadableStream(response.body, signal)
|
||||
}
|
||||
// TODO: 后续可以将db操作移到Listener Middleware中
|
||||
export const saveMessageAndBlocksToDB = async (message: Message, blocks: MessageBlock[], messageIndex: number = -1) => {
|
||||
return saveMessageAndBlocksToDBV2(message.topicId, message, blocks, messageIndex)
|
||||
}
|
||||
// export const saveMessageAndBlocksToDB = async (message: Message, blocks: MessageBlock[], messageIndex: number = -1) => {
|
||||
// return saveMessageAndBlocksToDBV2(message.topicId, message, blocks, messageIndex)
|
||||
// }
|
||||
|
||||
const updateExistingMessageAndBlocksInDB = async (
|
||||
updatedMessage: Partial<Message> & Pick<Message, 'id' | 'topicId'>,
|
||||
@ -374,7 +375,7 @@ const updateExistingMessageAndBlocksInDB = async (
|
||||
try {
|
||||
// Always update blocks if provided
|
||||
if (updatedBlocks.length > 0) {
|
||||
await updateBlocksV2(updatedBlocks)
|
||||
await updateBlocks(updatedBlocks)
|
||||
}
|
||||
|
||||
// Check if there are message properties to update beyond id and topicId
|
||||
@ -386,7 +387,7 @@ const updateExistingMessageAndBlocksInDB = async (
|
||||
return acc
|
||||
}, {})
|
||||
|
||||
await updateMessageV2(updatedMessage.topicId, updatedMessage.id, messageUpdatesPayload)
|
||||
await updateMessage(updatedMessage.topicId, updatedMessage.id, messageUpdatesPayload)
|
||||
|
||||
store.dispatch(updateTopicUpdatedAt({ topicId: updatedMessage.topicId }))
|
||||
}
|
||||
@ -432,7 +433,7 @@ const getBlockThrottler = (id: string) => {
|
||||
})
|
||||
|
||||
blockUpdateRafs.set(id, rafId)
|
||||
await updateSingleBlockV2(id, blockUpdate)
|
||||
await updateSingleBlock(id, blockUpdate)
|
||||
}, 150)
|
||||
|
||||
blockUpdateThrottlers.set(id, throttler)
|
||||
@ -893,7 +894,7 @@ export const sendMessage =
|
||||
userMessage.agentSessionId = activeAgentSession.agentSessionId
|
||||
}
|
||||
|
||||
await saveMessageAndBlocksToDB(userMessage, userMessageBlocks)
|
||||
await saveMessageAndBlocksToDB(topicId, userMessage, userMessageBlocks)
|
||||
dispatch(newMessagesActions.addMessage({ topicId, message: userMessage }))
|
||||
if (userMessageBlocks.length > 0) {
|
||||
dispatch(upsertManyBlocks(userMessageBlocks))
|
||||
@ -911,7 +912,7 @@ export const sendMessage =
|
||||
if (activeAgentSession.agentSessionId && !assistantMessage.agentSessionId) {
|
||||
assistantMessage.agentSessionId = activeAgentSession.agentSessionId
|
||||
}
|
||||
await saveMessageAndBlocksToDB(assistantMessage, [])
|
||||
await saveMessageAndBlocksToDB(topicId, assistantMessage, [])
|
||||
dispatch(newMessagesActions.addMessage({ topicId, message: assistantMessage }))
|
||||
|
||||
queue.add(async () => {
|
||||
@ -934,7 +935,7 @@ export const sendMessage =
|
||||
model: assistant.model,
|
||||
traceId: userMessage.traceId
|
||||
})
|
||||
await saveMessageAndBlocksToDB(assistantMessage, [])
|
||||
await saveMessageAndBlocksToDB(topicId, assistantMessage, [])
|
||||
dispatch(newMessagesActions.addMessage({ topicId, message: assistantMessage }))
|
||||
|
||||
queue.add(async () => {
|
||||
@ -1000,11 +1001,11 @@ export const loadAgentSessionMessagesThunk =
|
||||
* Loads messages and their blocks for a specific topic from the database
|
||||
* and updates the Redux store.
|
||||
*/
|
||||
export const loadTopicMessagesThunk =
|
||||
(topicId: string, forceReload: boolean = false) =>
|
||||
async (dispatch: AppDispatch, getState: () => RootState) => {
|
||||
return loadTopicMessagesThunkV2(topicId, forceReload)(dispatch, getState)
|
||||
}
|
||||
// export const loadTopicMessagesThunk =
|
||||
// (topicId: string, forceReload: boolean = false) =>
|
||||
// async (dispatch: AppDispatch, getState: () => RootState) => {
|
||||
// return loadTopicMessagesThunkV2(topicId, forceReload)(dispatch, getState)
|
||||
// }
|
||||
|
||||
/**
|
||||
* Thunk to delete a single message and its associated blocks.
|
||||
@ -1023,7 +1024,7 @@ export const deleteSingleMessageThunk =
|
||||
try {
|
||||
dispatch(newMessagesActions.removeMessage({ topicId, messageId }))
|
||||
cleanupMultipleBlocks(dispatch, blockIdsToDelete)
|
||||
await deleteMessageFromDBV2(topicId, messageId)
|
||||
await deleteMessageFromDB(topicId, messageId)
|
||||
} catch (error) {
|
||||
logger.error(`[deleteSingleMessage] Failed to delete message ${messageId}:`, error as Error)
|
||||
}
|
||||
@ -1062,7 +1063,7 @@ export const deleteMessageGroupThunk =
|
||||
try {
|
||||
dispatch(newMessagesActions.removeMessagesByAskId({ topicId, askId }))
|
||||
cleanupMultipleBlocks(dispatch, blockIdsToDelete)
|
||||
await deleteMessagesFromDBV2(topicId, messageIdsToDelete)
|
||||
await deleteMessagesFromDB(topicId, messageIdsToDelete)
|
||||
} catch (error) {
|
||||
logger.error(`[deleteMessageGroup] Failed to delete messages with askId ${askId}:`, error as Error)
|
||||
}
|
||||
@ -1087,7 +1088,7 @@ export const clearTopicMessagesThunk =
|
||||
|
||||
dispatch(newMessagesActions.clearTopicMessages(topicId))
|
||||
cleanupMultipleBlocks(dispatch, blockIdsToDelete)
|
||||
await clearMessagesFromDBV2(topicId)
|
||||
await clearMessagesFromDB(topicId)
|
||||
} catch (error) {
|
||||
logger.error(`[clearTopicMessagesThunk] Failed to clear messages for topic ${topicId}:`, error as Error)
|
||||
}
|
||||
@ -1408,7 +1409,7 @@ export const updateTranslationBlockThunk =
|
||||
// 更新Redux状态
|
||||
dispatch(updateOneBlock({ id: blockId, changes }))
|
||||
|
||||
await updateSingleBlockV2(blockId, changes)
|
||||
await updateSingleBlock(blockId, changes)
|
||||
// Logger.log(`[updateTranslationBlockThunk] Successfully updated translation block ${blockId}.`)
|
||||
} catch (error) {
|
||||
logger.error(`[updateTranslationBlockThunk] Failed to update translation block ${blockId}:`, error as Error)
|
||||
@ -1479,7 +1480,7 @@ export const appendAssistantResponseThunk =
|
||||
const insertAtIndex = existingMessageIndex !== -1 ? existingMessageIndex + 1 : currentTopicMessageIds.length
|
||||
|
||||
// 4. Update Database (Save the stub to the topic's message list)
|
||||
await saveMessageAndBlocksToDB(newAssistantMessageStub, [], insertAtIndex)
|
||||
await saveMessageAndBlocksToDB(topicId, newAssistantMessageStub, [], insertAtIndex)
|
||||
|
||||
dispatch(
|
||||
newMessagesActions.insertMessageAtIndex({ topicId, message: newAssistantMessageStub, index: insertAtIndex })
|
||||
@ -1631,12 +1632,12 @@ export const cloneMessagesToNewTopicThunk =
|
||||
|
||||
// Add the NEW blocks
|
||||
if (clonedBlocks.length > 0) {
|
||||
await bulkAddBlocksV2(clonedBlocks)
|
||||
await bulkAddBlocks(clonedBlocks)
|
||||
}
|
||||
// Update file counts
|
||||
const uniqueFiles = [...new Map(filesToUpdateCount.map((f) => [f.id, f])).values()]
|
||||
for (const file of uniqueFiles) {
|
||||
await updateFileCountV2(file.id, 1, false)
|
||||
await updateFileCount(file.id, 1, false)
|
||||
}
|
||||
})
|
||||
|
||||
@ -1690,11 +1691,11 @@ export const updateMessageAndBlocksThunk =
|
||||
}
|
||||
// Update message properties if provided
|
||||
if (messageUpdates && Object.keys(messageUpdates).length > 0 && messageId) {
|
||||
await updateMessageV2(topicId, messageId, messageUpdates)
|
||||
await updateMessage(topicId, messageId, messageUpdates)
|
||||
}
|
||||
// Update blocks if provided
|
||||
if (blockUpdatesList.length > 0) {
|
||||
await updateBlocksV2(blockUpdatesList)
|
||||
await updateBlocks(blockUpdatesList)
|
||||
}
|
||||
|
||||
dispatch(updateTopicUpdatedAt({ topicId }))
|
||||
@ -1748,3 +1749,197 @@ export const removeBlocksThunk =
|
||||
throw error
|
||||
}
|
||||
}
|
||||
|
||||
//以下内容从原 messageThunk.v2.ts 迁移过来,原文件已经删除
|
||||
//原因:v2.ts并不是v2数据重构的一部分,而相关命名对v2重构造成重大误解,故两文件合并,以消除误解
|
||||
|
||||
/**
|
||||
* Load messages for a topic using unified DbService
|
||||
*/
|
||||
export const loadTopicMessagesThunk =
|
||||
(topicId: string, forceReload: boolean = false) =>
|
||||
async (dispatch: AppDispatch, getState: () => RootState) => {
|
||||
const state = getState()
|
||||
|
||||
dispatch(newMessagesActions.setCurrentTopicId(topicId))
|
||||
|
||||
// Skip if already cached and not forcing reload
|
||||
if (!forceReload && state.messages.messageIdsByTopic[topicId]) {
|
||||
return
|
||||
}
|
||||
|
||||
try {
|
||||
dispatch(newMessagesActions.setTopicLoading({ topicId, loading: true }))
|
||||
|
||||
// Unified call - no need to check isAgentSessionTopicId
|
||||
const { messages, blocks } = await dbService.fetchMessages(topicId)
|
||||
|
||||
logger.silly('Loaded messages via DbService', {
|
||||
topicId,
|
||||
messageCount: messages.length,
|
||||
blockCount: blocks.length
|
||||
})
|
||||
|
||||
// Update Redux state with fetched data
|
||||
if (blocks.length > 0) {
|
||||
dispatch(upsertManyBlocks(blocks))
|
||||
}
|
||||
dispatch(newMessagesActions.messagesReceived({ topicId, messages }))
|
||||
} catch (error) {
|
||||
logger.error(`Failed to load messages for topic ${topicId}:`, error as Error)
|
||||
// Could dispatch an error action here if needed
|
||||
} finally {
|
||||
dispatch(newMessagesActions.setTopicLoading({ topicId, loading: false }))
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get raw topic data using unified DbService
|
||||
* Returns topic with messages array
|
||||
*/
|
||||
export const getRawTopic = async (topicId: string): Promise<{ id: string; messages: Message[] } | undefined> => {
|
||||
try {
|
||||
const rawTopic = await dbService.getRawTopic(topicId)
|
||||
logger.silly('Retrieved raw topic via DbService', { topicId, found: !!rawTopic })
|
||||
return rawTopic
|
||||
} catch (error) {
|
||||
logger.error('Failed to get raw topic:', { topicId, error })
|
||||
return undefined
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Update file reference count
|
||||
* Only applies to Dexie data source, no-op for agent sessions
|
||||
*/
|
||||
export const updateFileCount = async (fileId: string, delta: number, deleteIfZero: boolean = false): Promise<void> => {
|
||||
try {
|
||||
// Pass all parameters to dbService, including deleteIfZero
|
||||
await dbService.updateFileCount(fileId, delta, deleteIfZero)
|
||||
logger.silly('Updated file count', { fileId, delta, deleteIfZero })
|
||||
} catch (error) {
|
||||
logger.error('Failed to update file count:', { fileId, delta, error })
|
||||
throw error
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete a single message from database
|
||||
*/
|
||||
export const deleteMessageFromDB = async (topicId: string, messageId: string): Promise<void> => {
|
||||
try {
|
||||
await dbService.deleteMessage(topicId, messageId)
|
||||
logger.silly('Deleted message via DbService', { topicId, messageId })
|
||||
} catch (error) {
|
||||
logger.error('Failed to delete message:', { topicId, messageId, error })
|
||||
throw error
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete multiple messages from database
|
||||
*/
|
||||
export const deleteMessagesFromDB = async (topicId: string, messageIds: string[]): Promise<void> => {
|
||||
try {
|
||||
await dbService.deleteMessages(topicId, messageIds)
|
||||
logger.silly('Deleted messages via DbService', { topicId, count: messageIds.length })
|
||||
} catch (error) {
|
||||
logger.error('Failed to delete messages:', { topicId, messageIds, error })
|
||||
throw error
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Clear all messages from a topic
|
||||
*/
|
||||
export const clearMessagesFromDB = async (topicId: string): Promise<void> => {
|
||||
try {
|
||||
await dbService.clearMessages(topicId)
|
||||
logger.silly('Cleared all messages via DbService', { topicId })
|
||||
} catch (error) {
|
||||
logger.error('Failed to clear messages:', { topicId, error })
|
||||
throw error
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Save a message and its blocks to database
|
||||
* Uses unified interface, no need for isAgentSessionTopicId check
|
||||
*/
|
||||
export const saveMessageAndBlocksToDB = async (
|
||||
topicId: string,
|
||||
message: Message,
|
||||
blocks: MessageBlock[],
|
||||
messageIndex: number = -1
|
||||
): Promise<void> => {
|
||||
try {
|
||||
const blockIds = blocks.map((block) => block.id)
|
||||
const shouldSyncBlocks =
|
||||
blockIds.length > 0 && (!message.blocks || blockIds.some((id, index) => message.blocks?.[index] !== id))
|
||||
|
||||
const messageWithBlocks = shouldSyncBlocks ? { ...message, blocks: blockIds } : message
|
||||
// Direct call without conditional logic, now with messageIndex
|
||||
await dbService.appendMessage(topicId, messageWithBlocks, blocks, messageIndex)
|
||||
logger.silly('Saved message and blocks via DbService', {
|
||||
topicId,
|
||||
messageId: message.id,
|
||||
blockCount: blocks.length,
|
||||
messageIndex
|
||||
})
|
||||
} catch (error) {
|
||||
logger.error('Failed to save message and blocks:', { topicId, messageId: message.id, error })
|
||||
throw error
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Update a message in the database
|
||||
*/
|
||||
export const updateMessage = async (topicId: string, messageId: string, updates: Partial<Message>): Promise<void> => {
|
||||
try {
|
||||
await dbService.updateMessage(topicId, messageId, updates)
|
||||
logger.silly('Updated message via DbService', { topicId, messageId })
|
||||
} catch (error) {
|
||||
logger.error('Failed to update message:', { topicId, messageId, error })
|
||||
throw error
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Update a single message block
|
||||
*/
|
||||
export const updateSingleBlock = async (blockId: string, updates: Partial<MessageBlock>): Promise<void> => {
|
||||
try {
|
||||
await dbService.updateSingleBlock(blockId, updates)
|
||||
logger.silly('Updated single block via DbService', { blockId })
|
||||
} catch (error) {
|
||||
logger.error('Failed to update single block:', { blockId, error })
|
||||
throw error
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Bulk add message blocks (for new blocks)
|
||||
*/
|
||||
export const bulkAddBlocks = async (blocks: MessageBlock[]): Promise<void> => {
|
||||
try {
|
||||
await dbService.bulkAddBlocks(blocks)
|
||||
logger.silly('Bulk added blocks via DbService', { count: blocks.length })
|
||||
} catch (error) {
|
||||
logger.error('Failed to bulk add blocks:', { count: blocks.length, error })
|
||||
throw error
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Update multiple message blocks (upsert operation)
|
||||
*/
|
||||
export const updateBlocks = async (blocks: MessageBlock[]): Promise<void> => {
|
||||
try {
|
||||
await dbService.updateBlocks(blocks)
|
||||
logger.silly('Updated blocks via DbService', { count: blocks.length })
|
||||
} catch (error) {
|
||||
logger.error('Failed to update blocks:', { count: blocks.length, error })
|
||||
throw error
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,249 +0,0 @@
|
||||
/**
|
||||
* @deprecated Scheduled for removal in v2.0.0
|
||||
* --------------------------------------------------------------------------
|
||||
* ⚠️ NOTICE: V2 DATA&UI REFACTORING (by 0xfullex)
|
||||
* --------------------------------------------------------------------------
|
||||
* STOP: Feature PRs affecting this file are currently BLOCKED.
|
||||
* Only critical bug fixes are accepted during this migration phase.
|
||||
*
|
||||
* This file is being refactored to v2 standards.
|
||||
* Any non-critical changes will conflict with the ongoing work.
|
||||
*
|
||||
* 🔗 Context & Status:
|
||||
* - Contribution Hold: https://github.com/CherryHQ/cherry-studio/issues/10954
|
||||
* - v2 Refactor PR : https://github.com/CherryHQ/cherry-studio/pull/10162
|
||||
* --------------------------------------------------------------------------
|
||||
*/
|
||||
/**
|
||||
* V2 implementations of message thunk functions using the unified DbService
|
||||
* These implementations will be gradually rolled out using feature flags
|
||||
*/
|
||||
|
||||
import { loggerService } from '@logger'
|
||||
import { dbService } from '@renderer/services/db'
|
||||
import type { Message, MessageBlock } from '@renderer/types/newMessage'
|
||||
|
||||
import type { AppDispatch, RootState } from '../index'
|
||||
import { upsertManyBlocks } from '../messageBlock'
|
||||
import { newMessagesActions } from '../newMessage'
|
||||
|
||||
const logger = loggerService.withContext('MessageThunkV2')
|
||||
|
||||
// =================================================================
|
||||
// Phase 2.1 - Batch 1: Read-only operations (lowest risk)
|
||||
// =================================================================
|
||||
|
||||
/**
|
||||
* Load messages for a topic using unified DbService
|
||||
* This is the V2 implementation that will replace the original
|
||||
*/
|
||||
export const loadTopicMessagesThunkV2 =
|
||||
(topicId: string, forceReload: boolean = false) =>
|
||||
async (dispatch: AppDispatch, getState: () => RootState) => {
|
||||
const state = getState()
|
||||
|
||||
dispatch(newMessagesActions.setCurrentTopicId(topicId))
|
||||
|
||||
// Skip if already cached and not forcing reload
|
||||
if (!forceReload && state.messages.messageIdsByTopic[topicId]) {
|
||||
return
|
||||
}
|
||||
|
||||
try {
|
||||
dispatch(newMessagesActions.setTopicLoading({ topicId, loading: true }))
|
||||
|
||||
// Unified call - no need to check isAgentSessionTopicId
|
||||
const { messages, blocks } = await dbService.fetchMessages(topicId)
|
||||
|
||||
logger.silly('Loaded messages via DbService', {
|
||||
topicId,
|
||||
messageCount: messages.length,
|
||||
blockCount: blocks.length
|
||||
})
|
||||
|
||||
// Update Redux state with fetched data
|
||||
if (blocks.length > 0) {
|
||||
dispatch(upsertManyBlocks(blocks))
|
||||
}
|
||||
dispatch(newMessagesActions.messagesReceived({ topicId, messages }))
|
||||
} catch (error) {
|
||||
logger.error(`Failed to load messages for topic ${topicId}:`, error as Error)
|
||||
// Could dispatch an error action here if needed
|
||||
} finally {
|
||||
dispatch(newMessagesActions.setTopicLoading({ topicId, loading: false }))
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get raw topic data using unified DbService
|
||||
* Returns topic with messages array
|
||||
*/
|
||||
export const getRawTopicV2 = async (topicId: string): Promise<{ id: string; messages: Message[] } | undefined> => {
|
||||
try {
|
||||
const rawTopic = await dbService.getRawTopic(topicId)
|
||||
logger.silly('Retrieved raw topic via DbService', { topicId, found: !!rawTopic })
|
||||
return rawTopic
|
||||
} catch (error) {
|
||||
logger.error('Failed to get raw topic:', { topicId, error })
|
||||
return undefined
|
||||
}
|
||||
}
|
||||
|
||||
// =================================================================
|
||||
// Phase 2.2 - Batch 2: Helper functions
|
||||
// =================================================================
|
||||
|
||||
/**
|
||||
* Update file reference count
|
||||
* Only applies to Dexie data source, no-op for agent sessions
|
||||
*/
|
||||
export const updateFileCountV2 = async (
|
||||
fileId: string,
|
||||
delta: number,
|
||||
deleteIfZero: boolean = false
|
||||
): Promise<void> => {
|
||||
try {
|
||||
// Pass all parameters to dbService, including deleteIfZero
|
||||
await dbService.updateFileCount(fileId, delta, deleteIfZero)
|
||||
logger.silly('Updated file count', { fileId, delta, deleteIfZero })
|
||||
} catch (error) {
|
||||
logger.error('Failed to update file count:', { fileId, delta, error })
|
||||
throw error
|
||||
}
|
||||
}
|
||||
|
||||
// =================================================================
|
||||
// Phase 2.3 - Batch 3: Delete operations
|
||||
// =================================================================
|
||||
|
||||
/**
|
||||
* Delete a single message from database
|
||||
*/
|
||||
export const deleteMessageFromDBV2 = async (topicId: string, messageId: string): Promise<void> => {
|
||||
try {
|
||||
await dbService.deleteMessage(topicId, messageId)
|
||||
logger.silly('Deleted message via DbService', { topicId, messageId })
|
||||
} catch (error) {
|
||||
logger.error('Failed to delete message:', { topicId, messageId, error })
|
||||
throw error
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete multiple messages from database
|
||||
*/
|
||||
export const deleteMessagesFromDBV2 = async (topicId: string, messageIds: string[]): Promise<void> => {
|
||||
try {
|
||||
await dbService.deleteMessages(topicId, messageIds)
|
||||
logger.silly('Deleted messages via DbService', { topicId, count: messageIds.length })
|
||||
} catch (error) {
|
||||
logger.error('Failed to delete messages:', { topicId, messageIds, error })
|
||||
throw error
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Clear all messages from a topic
|
||||
*/
|
||||
export const clearMessagesFromDBV2 = async (topicId: string): Promise<void> => {
|
||||
try {
|
||||
await dbService.clearMessages(topicId)
|
||||
logger.silly('Cleared all messages via DbService', { topicId })
|
||||
} catch (error) {
|
||||
logger.error('Failed to clear messages:', { topicId, error })
|
||||
throw error
|
||||
}
|
||||
}
|
||||
|
||||
// =================================================================
|
||||
// Phase 2.4 - Batch 4: Complex write operations
|
||||
// =================================================================
|
||||
|
||||
/**
|
||||
* Save a message and its blocks to database
|
||||
* Uses unified interface, no need for isAgentSessionTopicId check
|
||||
*/
|
||||
export const saveMessageAndBlocksToDBV2 = async (
|
||||
topicId: string,
|
||||
message: Message,
|
||||
blocks: MessageBlock[],
|
||||
messageIndex: number = -1
|
||||
): Promise<void> => {
|
||||
try {
|
||||
const blockIds = blocks.map((block) => block.id)
|
||||
const shouldSyncBlocks =
|
||||
blockIds.length > 0 && (!message.blocks || blockIds.some((id, index) => message.blocks?.[index] !== id))
|
||||
|
||||
const messageWithBlocks = shouldSyncBlocks ? { ...message, blocks: blockIds } : message
|
||||
// Direct call without conditional logic, now with messageIndex
|
||||
await dbService.appendMessage(topicId, messageWithBlocks, blocks, messageIndex)
|
||||
logger.silly('Saved message and blocks via DbService', {
|
||||
topicId,
|
||||
messageId: message.id,
|
||||
blockCount: blocks.length,
|
||||
messageIndex
|
||||
})
|
||||
} catch (error) {
|
||||
logger.error('Failed to save message and blocks:', { topicId, messageId: message.id, error })
|
||||
throw error
|
||||
}
|
||||
}
|
||||
|
||||
// Note: sendMessageV2 would be implemented here but it's more complex
|
||||
// and would require more of the supporting code from messageThunk.ts
|
||||
|
||||
// =================================================================
|
||||
// Phase 2.5 - Batch 5: Update operations
|
||||
// =================================================================
|
||||
|
||||
/**
|
||||
* Update a message in the database
|
||||
*/
|
||||
export const updateMessageV2 = async (topicId: string, messageId: string, updates: Partial<Message>): Promise<void> => {
|
||||
try {
|
||||
await dbService.updateMessage(topicId, messageId, updates)
|
||||
logger.silly('Updated message via DbService', { topicId, messageId })
|
||||
} catch (error) {
|
||||
logger.error('Failed to update message:', { topicId, messageId, error })
|
||||
throw error
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Update a single message block
|
||||
*/
|
||||
export const updateSingleBlockV2 = async (blockId: string, updates: Partial<MessageBlock>): Promise<void> => {
|
||||
try {
|
||||
await dbService.updateSingleBlock(blockId, updates)
|
||||
logger.silly('Updated single block via DbService', { blockId })
|
||||
} catch (error) {
|
||||
logger.error('Failed to update single block:', { blockId, error })
|
||||
throw error
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Bulk add message blocks (for new blocks)
|
||||
*/
|
||||
export const bulkAddBlocksV2 = async (blocks: MessageBlock[]): Promise<void> => {
|
||||
try {
|
||||
await dbService.bulkAddBlocks(blocks)
|
||||
logger.silly('Bulk added blocks via DbService', { count: blocks.length })
|
||||
} catch (error) {
|
||||
logger.error('Failed to bulk add blocks:', { count: blocks.length, error })
|
||||
throw error
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Update multiple message blocks (upsert operation)
|
||||
*/
|
||||
export const updateBlocksV2 = async (blocks: MessageBlock[]): Promise<void> => {
|
||||
try {
|
||||
await dbService.updateBlocks(blocks)
|
||||
logger.silly('Updated blocks via DbService', { count: blocks.length })
|
||||
} catch (error) {
|
||||
logger.error('Failed to update blocks:', { count: blocks.length, error })
|
||||
throw error
|
||||
}
|
||||
}
|
||||
Loading…
Reference in New Issue
Block a user