import { useCallback, useEffect, useRef, useState } from 'react'; type Listener = (value: T) => void; type StoreMap = Map>; class Store { private state: T; private listeners = new Set>(); constructor(initialState: T) { this.state = initialState; } getState(): T { return this.state; } setState(newState: T) { this.state = newState; this.listeners.forEach(listener => listener(this.state)); } subscribe(listener: Listener): () => void { this.listeners.add(listener); return () => { this.listeners.delete(listener); }; } } class GlobalStoreManager { private static globalStores: StoreMap = new Map(); static getStore(namespace: string): Store | null { return this.globalStores.has(namespace) ? (this.globalStores.get(namespace) as Store) : null; } static setStore(namespace: string, store: Store) { this.globalStores.set(namespace, store); } } export function useGlobalStore(namespace: string, initialState?: T): Store { let store = GlobalStoreManager.getStore(namespace); if (!store) { if (!initialState) { throw new Error('initialState is required when creating a new store'); } store = new Store(initialState); GlobalStoreManager.setStore(namespace, store); } return useRef(store).current; } export function useLocalStore(initialState: T): Store { return useRef(new Store(initialState)).current; } export function useStoreState(store: Store, key: K): readonly [T[K], (newValue: T[K]) => void] { const selector = useCallback((state: T) => state[key], [key]); const [localState, setLocalState] = useState(selector(store.getState())); useEffect(() => { const listener = (newState: T) => { setLocalState(selector(newState)); }; return store.subscribe(listener); }, [store, selector]); return [ localState, (newValue: T[K]) => { store.setState({ ...store.getState(), [key]: newValue, }); }, ] as const; }