refactor(core): introduce EventBus and refactor store infrastructure
All checks were successful
Frontend CI / build-and-push-web (push) Successful in 2m46s
Frontend CI / ota-android (push) Successful in 10m34s
Frontend CI / build-android-apk (push) Successful in 1h15m8s

- 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:
lafay
2026-04-12 18:14:29 +08:00
parent 4b5ce1ba21
commit 6610d2f173
28 changed files with 378 additions and 512 deletions

View File

@@ -0,0 +1,58 @@
import type { StoreApi } from 'zustand';
export interface PendingRequestsSlice {
pendingRequests: Map<string, Promise<any>>;
getPendingRequest: <T>(key: string) => Promise<T> | undefined;
setPendingRequest: <T>(key: string, request: Promise<T>) => void;
deletePendingRequest: (key: string) => void;
clearPendingRequests: () => void;
}
export function createPendingRequestsSlice(
set: (partial: any) => void,
get: () => any
): PendingRequestsSlice {
return {
pendingRequests: new Map(),
getPendingRequest: <T>(key: string) => {
return get().pendingRequests.get(key) as Promise<T> | undefined;
},
setPendingRequest: <T>(key: string, request: Promise<T>) => {
set((state: { pendingRequests: Map<string, Promise<any>> }) => {
const newPendingRequests = new Map(state.pendingRequests);
newPendingRequests.set(key, request);
return { pendingRequests: newPendingRequests };
});
},
deletePendingRequest: (key: string) => {
set((state: { pendingRequests: Map<string, Promise<any>> }) => {
const newPendingRequests = new Map(state.pendingRequests);
newPendingRequests.delete(key);
return { pendingRequests: newPendingRequests };
});
},
clearPendingRequests: () => {
set({ pendingRequests: new Map() });
},
};
}
export function createDedupe<TStore extends PendingRequestsSlice>(
getStore: () => StoreApi<TStore>
) {
return async function dedupe<T>(key: string, fetcher: () => Promise<T>): Promise<T> {
const store = getStore().getState();
const pending = store.getPendingRequest<T>(key);
if (pending) return pending;
const request = fetcher().finally(() => {
getStore().getState().deletePendingRequest(key);
});
store.setPendingRequest(key, request);
return request;
};
}