Files
grimoire/src/hooks/useRelayState.ts
2025-12-14 12:00:55 +01:00

81 lines
2.3 KiB
TypeScript

import { useEffect } from "react";
import { useAtom } from "jotai";
import { grimoireStateAtom } from "@/core/state";
import relayStateManager from "@/services/relay-state-manager";
import type { AuthPreference, RelayState } from "@/types/relay-state";
import { normalizeRelayURL } from "@/lib/relay-url";
/**
* Hook for accessing and managing global relay state
*/
export function useRelayState() {
const [state, setState] = useAtom(grimoireStateAtom);
// Subscribe to relay state manager updates
useEffect(() => {
// Initialize state immediately if not set (before subscription)
setState((prev) => {
if (prev.relayState) return prev;
return {
...prev,
relayState: relayStateManager.getState(),
};
});
// Subscribe to updates
const unsubscribe = relayStateManager.subscribe((relayState) => {
setState((prev) => ({
...prev,
relayState,
}));
});
return unsubscribe;
// Only depend on setState - it's stable from Jotai
// Don't include state.relayState to avoid re-subscription loops
}, [setState]);
const relayState = state.relayState;
return {
// Current state
relayState,
relays: relayState?.relays || {},
pendingChallenges: relayState?.pendingChallenges || [],
authPreferences: relayState?.authPreferences || {},
// Get single relay state
getRelay: (url: string): RelayState | undefined => {
const normalizedUrl = normalizeRelayURL(url);
return relayState?.relays[normalizedUrl];
},
// Get auth preference
getAuthPreference: async (
url: string,
): Promise<AuthPreference | undefined> => {
return await relayStateManager.getAuthPreference(url);
},
// Set auth preference
setAuthPreference: async (url: string, preference: AuthPreference) => {
await relayStateManager.setAuthPreference(url, preference);
},
// Authenticate with relay
authenticateRelay: async (url: string) => {
await relayStateManager.authenticateRelay(url);
},
// Reject auth for relay
rejectAuth: (url: string, rememberForSession = true) => {
relayStateManager.rejectAuth(url, rememberForSession);
},
// Ensure relay is monitored
ensureRelayMonitored: (url: string) => {
relayStateManager.ensureRelayMonitored(url);
},
};
}