import { useCallback, useEffect, useState } from 'react'; import Resync from 'resync-javascript'; import { loadingModel } from '../store/loadingModel'; import { useShallow } from 'zustand/shallow'; /** * Hook for accessing the Resync singleton instance * Provides a React-friendly interface to Resync functionality */ export const useResync = () => { // loaded when config is loaded const [loaded, setLoaded] = useState(false); const loading = loadingModel(useShallow((state) => state.loading)); // loadFailed when config fails to load const [loadFailed, setLoadFailed] = useState(false); useEffect(() => { Resync.subscribe(() => { setLoaded(true); if (Resync?.loadFailed) { setLoadFailed(true); } if (!Resync.isLoading) { loadingModel.setState({ loading: false }); } }); }, [loading]); useEffect(() => { if (!Resync?.isLoading && Resync.ready) { setLoaded(true); loadingModel.setState({ loading: false }); } }, []); useEffect(() => { if (Resync?.loadFailed) { setLoadFailed(true); // reload the config and subscribe to the new config Resync.reload(); loadingModel.setState({ loading: true }); } }, []); // Content methods const getContent = useCallback(() => { if (!loaded) { return null; } return Resync.getContent(); }, [loaded]); const getContentByName = useCallback( (name: string) => { if (!loaded) { return null; } const allContent = Resync.getContent(); return allContent?.find((item) => item.name === name) || null; }, [loaded] ); // User methods const logInUser = useCallback( ( userId: string, metadata?: { email?: string; name?: string; phone?: string; language?: string; age?: number; gender?: string; country?: string; } ) => { loadingModel.setState({ loading: true }); Resync.logInUser(userId, metadata).finally(() => { loadingModel.setState({ loading: false }); }); }, [] ); const logOutUser = useCallback(() => { loadingModel.setState({ loading: true }); Resync.logout().finally(() => { loadingModel.setState({ loading: false }); }); }, []); const setClient = useCallback((client: string) => { Resync.setClient(client); }, []); const setUserAttributes = useCallback( (data: { email?: string; name?: string; phone?: string; language?: string; age?: number; gender?: string; country?: string; attributes?: Record; }) => { Resync.setUserAttributes(data); }, [] ); // Experiment methods const getVariant = useCallback( (experimentName: string) => { if (!loaded) { return null; } return Resync.getVariant(experimentName); }, [loaded] ); // Analytics methods const logEvent = useCallback( (event: { eventId: string; logId?: string; metadata?: Record; }) => { Resync.logEvent(event); }, [] ); // Config methods const getConfig = useCallback( (key: string) => { if (!loaded) { return null; } return Resync.getConfig(key); }, [loaded] ); const subscribe = useCallback((callback: () => void) => { Resync.subscribe(callback); }, []); const unsubscribe = useCallback((callback: () => void) => { Resync.unsubscribe(callback); }, []); return { // Content getContent, getContentByName, // User logInUser, logOutUser, setClient, setUserAttributes, // Experiments getVariant, // Analytics logEvent, // recordConversion, // Config getConfig, subscribe, unsubscribe, // Utilities loadFailed, isLoading: loading, loaded, }; }; export default useResync;