refactor(core): introduce EventBus and refactor store infrastructure
- Add EventBus for decoupled event-driven communication between services - Add EventSubscriber component for centralized event handling - Add requestDedupe utility for shared request deduplication - Refactor api/wsService to use eventBus instead of direct router navigation - Extract MessageMapper.toCachedMessages for consistent message mapping - Remove deprecated BaseManager and CacheBus classes - Improve @mention rendering with memberMap support in segment rendering - Update hooks to use useRef instead of useState for fetch tracking
This commit is contained in:
31
src/core/events/EventBus.ts
Normal file
31
src/core/events/EventBus.ts
Normal file
@@ -0,0 +1,31 @@
|
||||
type Subscriber<T> = (event: T) => void;
|
||||
|
||||
export type AppEvent =
|
||||
| { type: 'NAVIGATE'; payload: { path: string; params?: Record<string, any> } }
|
||||
| { type: 'NAVIGATE_BACK' }
|
||||
| { type: 'SHOW_VERIFICATION_MODAL' }
|
||||
| { type: 'VIBRATE'; payload: { type: 'message' | 'group_message' | 'call' } }
|
||||
| { type: 'SHOW_TOAST'; payload: { message: string; type: 'success' | 'error' | 'info' } }
|
||||
| { type: 'AUTH_LOGOUT' }
|
||||
| { type: 'AUTH_LOGIN'; payload: { userId: string } };
|
||||
|
||||
class EventBusClass {
|
||||
private subscribers: Set<Subscriber<AppEvent>> = new Set();
|
||||
|
||||
emit(event: AppEvent): void {
|
||||
this.subscribers.forEach(subscriber => {
|
||||
try {
|
||||
subscriber(event);
|
||||
} catch (error) {
|
||||
console.error('[EventBus] Subscriber error:', error);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
subscribe(subscriber: Subscriber<AppEvent>): () => void {
|
||||
this.subscribers.add(subscriber);
|
||||
return () => this.subscribers.delete(subscriber);
|
||||
}
|
||||
}
|
||||
|
||||
export const eventBus = new EventBusClass();
|
||||
2
src/core/events/index.ts
Normal file
2
src/core/events/index.ts
Normal file
@@ -0,0 +1,2 @@
|
||||
export { eventBus, type AppEvent } from './EventBus';
|
||||
export { useEventBus } from './useEventBus';
|
||||
8
src/core/events/useEventBus.ts
Normal file
8
src/core/events/useEventBus.ts
Normal file
@@ -0,0 +1,8 @@
|
||||
import { useEffect } from 'react';
|
||||
import { eventBus, AppEvent } from './EventBus';
|
||||
|
||||
export function useEventBus(handler: (event: AppEvent) => void): void {
|
||||
useEffect(() => {
|
||||
return eventBus.subscribe(handler);
|
||||
}, [handler]);
|
||||
}
|
||||
@@ -6,6 +6,7 @@
|
||||
|
||||
import { messageRepository, userCacheRepository, CachedMessage } from '@/database';
|
||||
import { wsClient, WSEventType } from '../../data/datasources/WSClient';
|
||||
import { MessageMapper } from '@/data/mappers';
|
||||
import {
|
||||
Message,
|
||||
Conversation,
|
||||
@@ -50,7 +51,7 @@ interface ReadStateRecord {
|
||||
timestamp: number;
|
||||
version: number;
|
||||
lastReadSeq: number;
|
||||
clearTimer?: NodeJS.Timeout;
|
||||
clearTimer?: ReturnType<typeof setTimeout>;
|
||||
}
|
||||
|
||||
class ProcessMessageUseCase {
|
||||
@@ -596,16 +597,9 @@ class ProcessMessageUseCase {
|
||||
);
|
||||
|
||||
// 保存到本地
|
||||
await messageRepository.saveMessagesBatch(serverMessages.map((m: any) => ({
|
||||
id: m.id,
|
||||
conversationId: m.conversation_id || conversationId,
|
||||
senderId: m.sender_id,
|
||||
seq: m.seq,
|
||||
segments: m.segments || [],
|
||||
createdAt: m.created_at,
|
||||
status: m.status || 'normal',
|
||||
isRead: false,
|
||||
})));
|
||||
await messageRepository.saveMessagesBatch(
|
||||
MessageMapper.toCachedMessages(serverMessages, conversationId)
|
||||
);
|
||||
|
||||
return serverMessages;
|
||||
}
|
||||
@@ -639,17 +633,9 @@ class ProcessMessageUseCase {
|
||||
})
|
||||
);
|
||||
|
||||
// 保存到本地
|
||||
await messageRepository.saveMessagesBatch(messages.map((m: any) => ({
|
||||
id: m.id,
|
||||
conversationId: m.conversation_id || conversationId,
|
||||
senderId: m.sender_id,
|
||||
seq: m.seq,
|
||||
segments: m.segments || [],
|
||||
createdAt: m.created_at,
|
||||
status: m.status || 'normal',
|
||||
isRead: false,
|
||||
})));
|
||||
await messageRepository.saveMessagesBatch(
|
||||
MessageMapper.toCachedMessages(response.messages, conversationId)
|
||||
);
|
||||
|
||||
return messages;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user