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:
@@ -10,6 +10,9 @@ import { authService } from '../../services/authService';
|
||||
import { userCacheRepository } from '@/database';
|
||||
import { useUserManagerStore } from './userStore';
|
||||
import { createCacheEntry, isCacheExpired, DEFAULT_TTL } from '../utils/cache';
|
||||
import { createDedupe } from '../utils/requestDedupe';
|
||||
|
||||
const dedupe = createDedupe(() => useUserManagerStore);
|
||||
|
||||
// ==================== UserManager 类 ====================
|
||||
|
||||
@@ -37,7 +40,7 @@ class UserManager {
|
||||
}
|
||||
}
|
||||
|
||||
return this.dedupe('users:current', async () => {
|
||||
return dedupe('users:current', async () => {
|
||||
const user = await authService.fetchCurrentUserFromAPI();
|
||||
const newEntry = createCacheEntry(user, DEFAULT_TTL.USER);
|
||||
store.setCurrentUserEntry(newEntry);
|
||||
@@ -51,7 +54,7 @@ class UserManager {
|
||||
}
|
||||
|
||||
private refreshCurrentUserInBackground(): void {
|
||||
this.dedupe('users:current:bg', async () => {
|
||||
dedupe('users:current:bg', async () => {
|
||||
const store = useUserManagerStore.getState();
|
||||
const user = await authService.fetchCurrentUserFromAPI();
|
||||
const newEntry = createCacheEntry(user, DEFAULT_TTL.USER);
|
||||
@@ -90,7 +93,7 @@ class UserManager {
|
||||
}
|
||||
}
|
||||
|
||||
return this.dedupe(`users:detail:${userId}`, async () => {
|
||||
return dedupe(`users:detail:${userId}`, async () => {
|
||||
const store = useUserManagerStore.getState();
|
||||
const user = await authService.fetchUserByIdFromAPI(userId);
|
||||
const newEntry = createCacheEntry(user, DEFAULT_TTL.USER);
|
||||
@@ -104,7 +107,7 @@ class UserManager {
|
||||
}
|
||||
|
||||
private refreshUserByIdInBackground(userId: string): void {
|
||||
this.dedupe(`users:detail:bg:${userId}`, async () => {
|
||||
dedupe(`users:detail:bg:${userId}`, async () => {
|
||||
const store = useUserManagerStore.getState();
|
||||
const user = await authService.fetchUserByIdFromAPI(userId);
|
||||
const newEntry = createCacheEntry(user, DEFAULT_TTL.USER);
|
||||
@@ -122,18 +125,6 @@ class UserManager {
|
||||
invalidateUsers(): void {
|
||||
useUserManagerStore.getState().invalidateAll();
|
||||
}
|
||||
|
||||
private async dedupe<T>(key: string, fetcher: () => Promise<T>): Promise<T> {
|
||||
const store = useUserManagerStore.getState();
|
||||
const pending = store.getPendingRequest<T>(key);
|
||||
if (pending) return pending;
|
||||
|
||||
const request = fetcher().finally(() => {
|
||||
useUserManagerStore.getState().deletePendingRequest(key);
|
||||
});
|
||||
store.setPendingRequest(key, request);
|
||||
return request;
|
||||
}
|
||||
}
|
||||
|
||||
export const userManager = new UserManager();
|
||||
|
||||
Reference in New Issue
Block a user