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:
58
src/stores/utils/requestDedupe.ts
Normal file
58
src/stores/utils/requestDedupe.ts
Normal 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;
|
||||
};
|
||||
}
|
||||
Reference in New Issue
Block a user