fix(import): refresh sidebar message count after incremental import

After incremental import via Electron IPC, the sidebar session list
showed stale message counts. Three contributing gaps:

1. The chat:incrementalImport IPC handler did not notify the renderer
   to refresh the session list (unlike the API route which calls
   notifySessionListChanged). Added win.webContents.send('api:importCompleted')
   to trigger the Sidebar's existing onImportCompleted listener.

2. The postImportHook in worker adapters was async (due to dynamic
   import()) but the caller did not await it, causing a race condition
   where loadSessions() could read stale overview cache before
   computeAndSetOverviewCache() finished. Converted to static import
   making the hook synchronous, and updated the type to void | Promise<void>
   with await at call sites in both incremental-importer and
   streaming-importer.

3. The @imported handlers on group-chat and private-chat pages only
   refreshed local analysis data without calling sessionStore.loadSessions().
   Added the call so the sidebar updates immediately on the client side.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
CEQ151andClaude Opus 4.8 authored and digua committed 2026-06-03 10:20:28 +08:00
1 parent 6e016837bc
commit 185e88ba3e
7 files changed
+22 -10

No files matched your search

+2
View File
@@ -225,6 +225,8 @@ export function registerChatHandlers(ctx: IpcContext): void {
console.error('[IpcMain] Failed to incrementally generate session index:', e)
}
worker.invalidateAnalysisCache(sessionId).catch(() => {})
// 通知渲染进程刷新会话列表(与 API 路由的 notifySessionListChanged 保持一致)
win.webContents.send('api:importCompleted')
}
return result
@@ -11,6 +11,7 @@ import {
BetterSqliteAdapter,
analyzeIncrementalImport as sharedAnalyze,
incrementalImport as sharedImport,
computeAndSetOverviewCache,
} from '@openchatlab/node-runtime'
import type {
IncrementalImportDeps,
@@ -39,9 +40,8 @@ function buildDeps(requestId: string): IncrementalImportDeps {
onProgress(progress) {
sendProgress(requestId, progress)
},
async postImportHook(_db, sessionId) {
postImportHook(_db, sessionId) {
try {
const { computeAndSetOverviewCache } = await import('@openchatlab/node-runtime')
const dbPath = getDbPath(sessionId)
const rawDb = new Database(dbPath)
computeAndSetOverviewCache(new BetterSqliteAdapter(rawDb), sessionId, getCacheDir())
@@ -15,6 +15,7 @@ import {
analyzeNewImport as sharedAnalyzeNewImport,
streamParseFileInfo as sharedStreamParseFileInfo,
TEMP_DB_SCHEMA,
computeAndSetOverviewCache,
} from '@openchatlab/node-runtime'
import type { StreamImportDeps, StreamImportResult, ImportLogger } from '@openchatlab/node-runtime'
import { sendProgress, generateSessionId, getDbPath, createDatabaseWithoutIndexes } from './utils'
@@ -87,9 +88,8 @@ function buildStreamImportDeps(requestId: string): StreamImportDeps {
sendProgress(requestId, progress)
},
logger: buildElectronLogger(),
async postImportHook(_db, sessionId) {
postImportHook(_db, sessionId) {
try {
const { computeAndSetOverviewCache } = await import('@openchatlab/node-runtime')
const dbPath = getDbPath(sessionId)
const rawDb = new Database(dbPath)
computeAndSetOverviewCache(new BetterSqliteAdapter(rawDb), sessionId, getCacheDir())
@@ -64,7 +64,7 @@ export interface IncrementalImportDeps {
openDatabase(sessionId: string, readonly?: boolean): DatabaseAdapter
onProgress: ImportProgressCallback
/** Optional hook after incremental import (e.g. update overview cache). */
postImportHook?: (db: DatabaseAdapter, sessionId: string) => void
postImportHook?: (db: DatabaseAdapter, sessionId: string) => void | Promise<void>
}
// ==================== Internal helpers ====================
@@ -383,7 +383,7 @@ export async function incrementalImport(
// Post-import hook (e.g. overview cache)
try {
deps.postImportHook?.(db, sessionId)
await deps.postImportHook?.(db, sessionId)
} catch {
/* non-fatal */
}
@@ -74,7 +74,7 @@ export interface StreamImportDeps {
/** Optional perf/diagnostic logger */
logger?: ImportLogger
/** Optional hook after import completes (e.g. write overview cache) */
postImportHook?: (db: DatabaseAdapter, sessionId: string) => void
postImportHook?: (db: DatabaseAdapter, sessionId: string) => void | Promise<void>
/** Generate a session ID. Defaults to timestamp + random. */
generateSessionId?: () => string
}
@@ -520,7 +520,7 @@ async function streamImportSingle(
// Post-import hook (e.g. overview cache)
try {
deps.postImportHook?.(db, sessionId)
await deps.postImportHook?.(db, sessionId)
if (deps.postImportHook) logger?.perf('Post-import hook done', totalMessageCount)
} catch {
/* non-fatal */
+6 -1
View File
@@ -294,7 +294,12 @@ const filteredMemberCount = computed(() => {
v-model="showIncrementalImportModal"
:session-id="currentSessionId"
:session-name="session.name"
@imported="loadData"
@imported="
() => {
loadData()
sessionStore.loadSessions()
}
"
/>
<!-- 导出聊天记录弹窗 -->
+6 -1
View File
@@ -304,7 +304,12 @@ const otherMemberAvatar = computed(() => {
v-model="showIncrementalImportModal"
:session-id="currentSessionId"
:session-name="session.name"
@imported="loadAnalysisData"
@imported="
() => {
loadAnalysisData()
sessionStore.loadSessions()
}
"
/>
<!-- 导出聊天记录弹窗 -->