feat: 移除特性标志相关代码,简化消息存储逻辑
This commit is contained in:
@@ -6,6 +6,3 @@ CSLOGGER_MAIN_LEVEL=info
|
|||||||
CSLOGGER_RENDERER_LEVEL=info
|
CSLOGGER_RENDERER_LEVEL=info
|
||||||
#CSLOGGER_MAIN_SHOW_MODULES=
|
#CSLOGGER_MAIN_SHOW_MODULES=
|
||||||
#CSLOGGER_RENDERER_SHOW_MODULES=
|
#CSLOGGER_RENDERER_SHOW_MODULES=
|
||||||
|
|
||||||
# Feature Flags (must be prefixed with VITE_ to be accessible in renderer)
|
|
||||||
# VITE_USE_UNIFIED_DB_SERVICE=true # Enable unified DB service for chat/agent sessions
|
|
||||||
|
|||||||
@@ -1,80 +0,0 @@
|
|||||||
import { loggerService } from '@logger'
|
|
||||||
|
|
||||||
const logger = loggerService.withContext('Feature Flag')
|
|
||||||
/**
|
|
||||||
* Feature flags for controlling gradual rollout of new features
|
|
||||||
* These flags can be toggled to enable/disable features without code changes
|
|
||||||
*/
|
|
||||||
|
|
||||||
interface FeatureFlags {
|
|
||||||
/**
|
|
||||||
* Enable unified database service for both regular chats and agent sessions
|
|
||||||
* When enabled, uses the new DbService facade pattern
|
|
||||||
* When disabled, uses the original implementation with conditional checks
|
|
||||||
*/
|
|
||||||
USE_UNIFIED_DB_SERVICE: boolean
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Default feature flag values
|
|
||||||
* Set to false initially for safe rollout
|
|
||||||
*/
|
|
||||||
export const featureFlags: FeatureFlags = {
|
|
||||||
USE_UNIFIED_DB_SERVICE: false
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Override feature flags from environment or local storage
|
|
||||||
* Priority order (highest to lowest):
|
|
||||||
* 1. localStorage (runtime overrides)
|
|
||||||
* 2. Environment variables (build-time config)
|
|
||||||
* 3. Default values
|
|
||||||
*/
|
|
||||||
export function initializeFeatureFlags(): void {
|
|
||||||
// First, check environment variables (build-time configuration)
|
|
||||||
// In Vite, env vars must be prefixed with VITE_ to be exposed to the client
|
|
||||||
// Usage: VITE_USE_UNIFIED_DB_SERVICE=true yarn dev
|
|
||||||
if (import.meta.env?.VITE_USE_UNIFIED_DB_SERVICE === 'true') {
|
|
||||||
featureFlags.USE_UNIFIED_DB_SERVICE = true
|
|
||||||
}
|
|
||||||
|
|
||||||
// Then check localStorage for runtime overrides (higher priority)
|
|
||||||
// This allows toggling features without rebuilding
|
|
||||||
try {
|
|
||||||
const localOverrides = localStorage.getItem('featureFlags')
|
|
||||||
if (localOverrides) {
|
|
||||||
const overrides = JSON.parse(localOverrides)
|
|
||||||
Object.keys(overrides).forEach((key) => {
|
|
||||||
if (key in featureFlags) {
|
|
||||||
featureFlags[key as keyof FeatureFlags] = overrides[key]
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
} catch (e) {
|
|
||||||
logger.warn('Failed to parse feature flags from localStorage:', e as Error)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Update a feature flag value at runtime
|
|
||||||
* Useful for A/B testing or gradual rollout
|
|
||||||
*/
|
|
||||||
export function setFeatureFlag(flag: keyof FeatureFlags, value: boolean): void {
|
|
||||||
featureFlags[flag] = value
|
|
||||||
|
|
||||||
// Persist to localStorage for consistency across app restarts
|
|
||||||
const currentFlags = localStorage.getItem('featureFlags')
|
|
||||||
const flags = currentFlags ? JSON.parse(currentFlags) : {}
|
|
||||||
flags[flag] = value
|
|
||||||
localStorage.setItem('featureFlags', JSON.stringify(flags))
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get current value of a feature flag
|
|
||||||
*/
|
|
||||||
export function getFeatureFlag(flag: keyof FeatureFlags): boolean {
|
|
||||||
return featureFlags[flag]
|
|
||||||
}
|
|
||||||
|
|
||||||
// Initialize on import
|
|
||||||
initializeFeatureFlags()
|
|
||||||
@@ -6,7 +6,7 @@ import { ToolTitle } from './GenericTools'
|
|||||||
import type { MultiEditToolInput, MultiEditToolOutput } from './types'
|
import type { MultiEditToolInput, MultiEditToolOutput } from './types'
|
||||||
import { AgentToolsType } from './types'
|
import { AgentToolsType } from './types'
|
||||||
|
|
||||||
export function MultiEditTool({ input, output }: { input: MultiEditToolInput; output?: MultiEditToolOutput }) {
|
export function MultiEditTool({ input }: { input: MultiEditToolInput; output?: MultiEditToolOutput }) {
|
||||||
return (
|
return (
|
||||||
<AccordionItem
|
<AccordionItem
|
||||||
key={AgentToolsType.MultiEdit}
|
key={AgentToolsType.MultiEdit}
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
import { loggerService } from '@logger'
|
import { loggerService } from '@logger'
|
||||||
import { AiSdkToChunkAdapter } from '@renderer/aiCore/chunk/AiSdkToChunkAdapter'
|
import { AiSdkToChunkAdapter } from '@renderer/aiCore/chunk/AiSdkToChunkAdapter'
|
||||||
import { AgentApiClient } from '@renderer/api/agent'
|
import { AgentApiClient } from '@renderer/api/agent'
|
||||||
import { featureFlags } from '@renderer/config/featureFlags'
|
|
||||||
import db from '@renderer/databases'
|
import db from '@renderer/databases'
|
||||||
import { fetchMessagesSummary } from '@renderer/services/ApiService'
|
import { fetchMessagesSummary } from '@renderer/services/ApiService'
|
||||||
import { DbService } from '@renderer/services/db/DbService'
|
import { DbService } from '@renderer/services/db/DbService'
|
||||||
@@ -350,46 +349,7 @@ const createAgentMessageStream = async (
|
|||||||
}
|
}
|
||||||
// TODO: 后续可以将db操作移到Listener Middleware中
|
// TODO: 后续可以将db操作移到Listener Middleware中
|
||||||
export const saveMessageAndBlocksToDB = async (message: Message, blocks: MessageBlock[], messageIndex: number = -1) => {
|
export const saveMessageAndBlocksToDB = async (message: Message, blocks: MessageBlock[], messageIndex: number = -1) => {
|
||||||
// Use V2 implementation if feature flag is enabled
|
return saveMessageAndBlocksToDBV2(message.topicId, message, blocks, messageIndex)
|
||||||
if (featureFlags.USE_UNIFIED_DB_SERVICE) {
|
|
||||||
return saveMessageAndBlocksToDBV2(message.topicId, message, blocks, messageIndex)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Original implementation
|
|
||||||
try {
|
|
||||||
if (isAgentSessionTopicId(message.topicId)) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
if (blocks.length > 0) {
|
|
||||||
// Use V2 implementation if feature flag is enabled
|
|
||||||
if (featureFlags.USE_UNIFIED_DB_SERVICE) {
|
|
||||||
await updateBlocksV2(blocks)
|
|
||||||
} else {
|
|
||||||
await db.message_blocks.bulkPut(blocks)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
const topic = await db.topics.get(message.topicId)
|
|
||||||
if (topic) {
|
|
||||||
const _messageIndex = topic.messages.findIndex((m) => m.id === message.id)
|
|
||||||
const updatedMessages = [...topic.messages]
|
|
||||||
|
|
||||||
if (_messageIndex !== -1) {
|
|
||||||
updatedMessages[_messageIndex] = message
|
|
||||||
} else {
|
|
||||||
if (messageIndex !== -1) {
|
|
||||||
updatedMessages.splice(messageIndex, 0, message)
|
|
||||||
} else {
|
|
||||||
updatedMessages.push(message)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
await db.topics.update(message.topicId, { messages: updatedMessages })
|
|
||||||
store.dispatch(updateTopicUpdatedAt({ topicId: message.topicId }))
|
|
||||||
} else {
|
|
||||||
logger.error(`[saveMessageAndBlocksToDB] Topic ${message.topicId} not found.`)
|
|
||||||
}
|
|
||||||
} catch (error) {
|
|
||||||
logger.error(`[saveMessageAndBlocksToDB] Failed to save message ${message.id}:`, error as Error)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const updateExistingMessageAndBlocksInDB = async (
|
const updateExistingMessageAndBlocksInDB = async (
|
||||||
@@ -399,43 +359,19 @@ const updateExistingMessageAndBlocksInDB = async (
|
|||||||
try {
|
try {
|
||||||
// Always update blocks if provided
|
// Always update blocks if provided
|
||||||
if (updatedBlocks.length > 0) {
|
if (updatedBlocks.length > 0) {
|
||||||
if (featureFlags.USE_UNIFIED_DB_SERVICE) {
|
await updateBlocksV2(updatedBlocks)
|
||||||
await updateBlocksV2(updatedBlocks)
|
|
||||||
} else {
|
|
||||||
await db.transaction('rw', db.topics, db.message_blocks, async () => {
|
|
||||||
await db.message_blocks.bulkPut(updatedBlocks)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check if there are message properties to update beyond id and topicId
|
// Check if there are message properties to update beyond id and topicId
|
||||||
const messageKeysToUpdate = Object.keys(updatedMessage).filter((key) => key !== 'id' && key !== 'topicId')
|
const messageKeysToUpdate = Object.keys(updatedMessage).filter((key) => key !== 'id' && key !== 'topicId')
|
||||||
|
|
||||||
if (messageKeysToUpdate.length > 0) {
|
if (messageKeysToUpdate.length > 0) {
|
||||||
if (featureFlags.USE_UNIFIED_DB_SERVICE) {
|
const messageUpdatesPayload = messageKeysToUpdate.reduce<Partial<Message>>((acc, key) => {
|
||||||
const messageUpdatesPayload = messageKeysToUpdate.reduce<Partial<Message>>((acc, key) => {
|
acc[key] = updatedMessage[key]
|
||||||
acc[key] = updatedMessage[key]
|
return acc
|
||||||
return acc
|
}, {})
|
||||||
}, {})
|
|
||||||
|
|
||||||
await updateMessageV2(updatedMessage.topicId, updatedMessage.id, messageUpdatesPayload)
|
await updateMessageV2(updatedMessage.topicId, updatedMessage.id, messageUpdatesPayload)
|
||||||
} else {
|
|
||||||
// 使用 where().modify() 进行原子更新
|
|
||||||
await db.topics
|
|
||||||
.where('id')
|
|
||||||
.equals(updatedMessage.topicId)
|
|
||||||
.modify((topic) => {
|
|
||||||
if (!topic) return
|
|
||||||
|
|
||||||
const messageIndex = topic.messages.findIndex((m) => m.id === updatedMessage.id)
|
|
||||||
if (messageIndex !== -1) {
|
|
||||||
// 直接在原对象上更新需要修改的属性
|
|
||||||
messageKeysToUpdate.forEach((key) => {
|
|
||||||
topic.messages[messageIndex][key] = updatedMessage[key]
|
|
||||||
})
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
store.dispatch(updateTopicUpdatedAt({ topicId: updatedMessage.topicId }))
|
store.dispatch(updateTopicUpdatedAt({ topicId: updatedMessage.topicId }))
|
||||||
}
|
}
|
||||||
@@ -481,12 +417,7 @@ const getBlockThrottler = (id: string) => {
|
|||||||
})
|
})
|
||||||
|
|
||||||
blockUpdateRafs.set(id, rafId)
|
blockUpdateRafs.set(id, rafId)
|
||||||
// Use V2 implementation if feature flag is enabled
|
await updateSingleBlockV2(id, blockUpdate)
|
||||||
if (featureFlags.USE_UNIFIED_DB_SERVICE) {
|
|
||||||
await updateSingleBlockV2(id, blockUpdate)
|
|
||||||
} else {
|
|
||||||
await db.message_blocks.update(id, blockUpdate)
|
|
||||||
}
|
|
||||||
}, 150)
|
}, 150)
|
||||||
|
|
||||||
blockUpdateThrottlers.set(id, throttler)
|
blockUpdateThrottlers.set(id, throttler)
|
||||||
@@ -1023,57 +954,7 @@ export const loadAgentSessionMessagesThunk =
|
|||||||
export const loadTopicMessagesThunk =
|
export const loadTopicMessagesThunk =
|
||||||
(topicId: string, forceReload: boolean = false) =>
|
(topicId: string, forceReload: boolean = false) =>
|
||||||
async (dispatch: AppDispatch, getState: () => RootState) => {
|
async (dispatch: AppDispatch, getState: () => RootState) => {
|
||||||
// Use V2 implementation if feature flag is enabled
|
return loadTopicMessagesThunkV2(topicId, forceReload)(dispatch, getState)
|
||||||
if (featureFlags.USE_UNIFIED_DB_SERVICE) {
|
|
||||||
return loadTopicMessagesThunkV2(topicId, forceReload)(dispatch, getState)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Original implementation
|
|
||||||
const state = getState()
|
|
||||||
const topicMessagesExist = !!state.messages.messageIdsByTopic[topicId]
|
|
||||||
dispatch(newMessagesActions.setCurrentTopicId(topicId))
|
|
||||||
|
|
||||||
// Check if it's an agent session topic
|
|
||||||
if (isAgentSessionTopicId(topicId)) {
|
|
||||||
if (topicMessagesExist && !forceReload) {
|
|
||||||
return // Keep existing messages in memory
|
|
||||||
}
|
|
||||||
// Load from agent backend instead of local DB
|
|
||||||
const sessionId = topicId.replace('agent-session:', '')
|
|
||||||
return dispatch(loadAgentSessionMessagesThunk(sessionId))
|
|
||||||
}
|
|
||||||
|
|
||||||
if (topicMessagesExist && !forceReload) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
const topic = await db.topics.get(topicId)
|
|
||||||
if (!topic) {
|
|
||||||
await db.topics.add({ id: topicId, messages: [] })
|
|
||||||
}
|
|
||||||
|
|
||||||
const messagesFromDB = topic?.messages || []
|
|
||||||
|
|
||||||
if (messagesFromDB.length > 0) {
|
|
||||||
const messageIds = messagesFromDB.map((m) => m.id)
|
|
||||||
const blocks = await db.message_blocks.where('messageId').anyOf(messageIds).toArray()
|
|
||||||
|
|
||||||
if (blocks && blocks.length > 0) {
|
|
||||||
dispatch(upsertManyBlocks(blocks))
|
|
||||||
}
|
|
||||||
const messagesWithBlockIds = messagesFromDB.map((m) => ({
|
|
||||||
...m,
|
|
||||||
blocks: m.blocks?.map(String) || []
|
|
||||||
}))
|
|
||||||
dispatch(newMessagesActions.messagesReceived({ topicId, messages: messagesWithBlockIds }))
|
|
||||||
} else {
|
|
||||||
dispatch(newMessagesActions.messagesReceived({ topicId, messages: [] }))
|
|
||||||
}
|
|
||||||
} catch (error: any) {
|
|
||||||
logger.error(`[loadTopicMessagesThunk] Failed to load messages for topic ${topicId}:`, error)
|
|
||||||
// dispatch(newMessagesActions.setTopicLoading({ topicId, loading: false }))
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -1093,20 +974,7 @@ export const deleteSingleMessageThunk =
|
|||||||
try {
|
try {
|
||||||
dispatch(newMessagesActions.removeMessage({ topicId, messageId }))
|
dispatch(newMessagesActions.removeMessage({ topicId, messageId }))
|
||||||
cleanupMultipleBlocks(dispatch, blockIdsToDelete)
|
cleanupMultipleBlocks(dispatch, blockIdsToDelete)
|
||||||
|
await deleteMessageFromDBV2(topicId, messageId)
|
||||||
// Use V2 implementation if feature flag is enabled
|
|
||||||
if (featureFlags.USE_UNIFIED_DB_SERVICE) {
|
|
||||||
await deleteMessageFromDBV2(topicId, messageId)
|
|
||||||
} else {
|
|
||||||
// Original implementation
|
|
||||||
await db.message_blocks.bulkDelete(blockIdsToDelete)
|
|
||||||
const topic = await db.topics.get(topicId)
|
|
||||||
if (topic) {
|
|
||||||
const finalMessagesToSave = selectMessagesForTopic(getState(), topicId)
|
|
||||||
await db.topics.update(topicId, { messages: finalMessagesToSave })
|
|
||||||
dispatch(updateTopicUpdatedAt({ topicId }))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
logger.error(`[deleteSingleMessage] Failed to delete message ${messageId}:`, error as Error)
|
logger.error(`[deleteSingleMessage] Failed to delete message ${messageId}:`, error as Error)
|
||||||
}
|
}
|
||||||
@@ -1145,20 +1013,7 @@ export const deleteMessageGroupThunk =
|
|||||||
try {
|
try {
|
||||||
dispatch(newMessagesActions.removeMessagesByAskId({ topicId, askId }))
|
dispatch(newMessagesActions.removeMessagesByAskId({ topicId, askId }))
|
||||||
cleanupMultipleBlocks(dispatch, blockIdsToDelete)
|
cleanupMultipleBlocks(dispatch, blockIdsToDelete)
|
||||||
|
await deleteMessagesFromDBV2(topicId, messageIdsToDelete)
|
||||||
// Use V2 implementation if feature flag is enabled
|
|
||||||
if (featureFlags.USE_UNIFIED_DB_SERVICE) {
|
|
||||||
await deleteMessagesFromDBV2(topicId, messageIdsToDelete)
|
|
||||||
} else {
|
|
||||||
// Original implementation
|
|
||||||
await db.message_blocks.bulkDelete(blockIdsToDelete)
|
|
||||||
const topic = await db.topics.get(topicId)
|
|
||||||
if (topic) {
|
|
||||||
const finalMessagesToSave = selectMessagesForTopic(getState(), topicId)
|
|
||||||
await db.topics.update(topicId, { messages: finalMessagesToSave })
|
|
||||||
dispatch(updateTopicUpdatedAt({ topicId }))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
logger.error(`[deleteMessageGroup] Failed to delete messages with askId ${askId}:`, error as Error)
|
logger.error(`[deleteMessageGroup] Failed to delete messages with askId ${askId}:`, error as Error)
|
||||||
}
|
}
|
||||||
@@ -1183,18 +1038,7 @@ export const clearTopicMessagesThunk =
|
|||||||
|
|
||||||
dispatch(newMessagesActions.clearTopicMessages(topicId))
|
dispatch(newMessagesActions.clearTopicMessages(topicId))
|
||||||
cleanupMultipleBlocks(dispatch, blockIdsToDelete)
|
cleanupMultipleBlocks(dispatch, blockIdsToDelete)
|
||||||
|
await clearMessagesFromDBV2(topicId)
|
||||||
// Use V2 implementation if feature flag is enabled
|
|
||||||
if (featureFlags.USE_UNIFIED_DB_SERVICE) {
|
|
||||||
await clearMessagesFromDBV2(topicId)
|
|
||||||
} else {
|
|
||||||
// Original implementation
|
|
||||||
await db.topics.update(topicId, { messages: [] })
|
|
||||||
dispatch(updateTopicUpdatedAt({ topicId }))
|
|
||||||
if (blockIdsToDelete.length > 0) {
|
|
||||||
await db.message_blocks.bulkDelete(blockIdsToDelete)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
logger.error(`[clearTopicMessagesThunk] Failed to clear messages for topic ${topicId}:`, error as Error)
|
logger.error(`[clearTopicMessagesThunk] Failed to clear messages for topic ${topicId}:`, error as Error)
|
||||||
}
|
}
|
||||||
@@ -1515,13 +1359,7 @@ export const updateTranslationBlockThunk =
|
|||||||
// 更新Redux状态
|
// 更新Redux状态
|
||||||
dispatch(updateOneBlock({ id: blockId, changes }))
|
dispatch(updateOneBlock({ id: blockId, changes }))
|
||||||
|
|
||||||
// 更新数据库
|
await updateSingleBlockV2(blockId, changes)
|
||||||
// Use V2 implementation if feature flag is enabled
|
|
||||||
if (featureFlags.USE_UNIFIED_DB_SERVICE) {
|
|
||||||
await updateSingleBlockV2(blockId, changes)
|
|
||||||
} else {
|
|
||||||
await db.message_blocks.update(blockId, changes)
|
|
||||||
}
|
|
||||||
// Logger.log(`[updateTranslationBlockThunk] Successfully updated translation block ${blockId}.`)
|
// Logger.log(`[updateTranslationBlockThunk] Successfully updated translation block ${blockId}.`)
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
logger.error(`[updateTranslationBlockThunk] Failed to update translation block ${blockId}:`, error as Error)
|
logger.error(`[updateTranslationBlockThunk] Failed to update translation block ${blockId}:`, error as Error)
|
||||||
@@ -1734,33 +1572,12 @@ export const cloneMessagesToNewTopicThunk =
|
|||||||
|
|
||||||
// Add the NEW blocks
|
// Add the NEW blocks
|
||||||
if (clonedBlocks.length > 0) {
|
if (clonedBlocks.length > 0) {
|
||||||
// Use V2 implementation if feature flag is enabled
|
await bulkAddBlocksV2(clonedBlocks)
|
||||||
if (featureFlags.USE_UNIFIED_DB_SERVICE) {
|
|
||||||
await bulkAddBlocksV2(clonedBlocks)
|
|
||||||
} else {
|
|
||||||
await db.message_blocks.bulkAdd(clonedBlocks)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
// Update file counts
|
// Update file counts
|
||||||
const uniqueFiles = [...new Map(filesToUpdateCount.map((f) => [f.id, f])).values()]
|
const uniqueFiles = [...new Map(filesToUpdateCount.map((f) => [f.id, f])).values()]
|
||||||
if (featureFlags.USE_UNIFIED_DB_SERVICE) {
|
for (const file of uniqueFiles) {
|
||||||
// Use V2 implementation for file count updates
|
await updateFileCountV2(file.id, 1, false)
|
||||||
for (const file of uniqueFiles) {
|
|
||||||
await updateFileCountV2(file.id, 1, false)
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
// Original implementation
|
|
||||||
for (const file of uniqueFiles) {
|
|
||||||
await db.files
|
|
||||||
.where('id')
|
|
||||||
.equals(file.id)
|
|
||||||
.modify((f) => {
|
|
||||||
if (f) {
|
|
||||||
// Ensure file exists before modifying
|
|
||||||
f.count = (f.count || 0) + 1
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
@@ -1812,47 +1629,13 @@ export const updateMessageAndBlocksThunk =
|
|||||||
if (blockUpdatesList.length > 0) {
|
if (blockUpdatesList.length > 0) {
|
||||||
dispatch(upsertManyBlocks(blockUpdatesList))
|
dispatch(upsertManyBlocks(blockUpdatesList))
|
||||||
}
|
}
|
||||||
|
// Update message properties if provided
|
||||||
// 2. 更新数据库 (在事务中)
|
if (messageUpdates && Object.keys(messageUpdates).length > 0 && messageId) {
|
||||||
// Use V2 implementation if feature flag is enabled
|
await updateMessageV2(topicId, messageId, messageUpdates)
|
||||||
if (featureFlags.USE_UNIFIED_DB_SERVICE) {
|
}
|
||||||
// Update message properties if provided
|
// Update blocks if provided
|
||||||
if (messageUpdates && Object.keys(messageUpdates).length > 0 && messageId) {
|
if (blockUpdatesList.length > 0) {
|
||||||
await updateMessageV2(topicId, messageId, messageUpdates)
|
await updateBlocksV2(blockUpdatesList)
|
||||||
}
|
|
||||||
// Update blocks if provided
|
|
||||||
if (blockUpdatesList.length > 0) {
|
|
||||||
await updateBlocksV2(blockUpdatesList)
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
// Original implementation with transaction
|
|
||||||
await db.transaction('rw', db.topics, db.message_blocks, async () => {
|
|
||||||
// Only update topic.messages if there were actual message changes
|
|
||||||
if (messageUpdates && Object.keys(messageUpdates).length > 0) {
|
|
||||||
const topic = await db.topics.get(topicId)
|
|
||||||
if (topic && topic.messages) {
|
|
||||||
const messageIndex = topic.messages.findIndex((m) => m.id === messageId)
|
|
||||||
if (messageIndex !== -1) {
|
|
||||||
Object.assign(topic.messages[messageIndex], messageUpdates)
|
|
||||||
await db.topics.update(topicId, { messages: topic.messages })
|
|
||||||
} else {
|
|
||||||
logger.error(
|
|
||||||
`[updateMessageAndBlocksThunk] Message ${messageId} not found in DB topic ${topicId} for property update.`
|
|
||||||
)
|
|
||||||
throw new Error(`Message ${messageId} not found in DB topic ${topicId} for property update.`)
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
logger.error(
|
|
||||||
`[updateMessageAndBlocksThunk] Topic ${topicId} not found or empty for message property update.`
|
|
||||||
)
|
|
||||||
throw new Error(`Topic ${topicId} not found or empty for message property update.`)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (blockUpdatesList.length > 0) {
|
|
||||||
await db.message_blocks.bulkPut(blockUpdatesList)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
dispatch(updateTopicUpdatedAt({ topicId }))
|
dispatch(updateTopicUpdatedAt({ topicId }))
|
||||||
|
|||||||
Reference in New Issue
Block a user