import { useCallback, useEffect, useRef } from 'react';
import { useLocation } from 'react-router';
import {} from 'recoil-sync';
/**
 * Setup the URL sync for the application. This is used to sync Recoil state with the URL query params.
 *
 * @param basename router basename
 */
export default function useUrlSync() {
    const location = useLocation();
    const locationSubscribers = useRef([]);
    useEffect(() => {
        for (const subscriber of locationSubscribers.current) {
            subscriber();
        }
    }, [location]);
    /**
     * Custom URL query param serializer. This is used by
     * the RecoilURLSync component to convert a variable value into a URL query param
     */
    const urlSerializer = useCallback((val) => {
        if (val === undefined || val === null) {
            return '';
        }
        if (['string', 'number', 'boolean'].includes(typeof val)) {
            return String(val);
        }
        return JSON.stringify(val);
    }, []);
    /**
     * Custom URL query param deserializer. This is used by
     * the RecoilURLSync component to convert a URL query param into a variable value
     */
    const urlDeserializer = useCallback((val) => {
        if (val === '') {
            return undefined;
        }
        try {
            return JSON.parse(val);
        }
        catch (_a) {
            return val;
        }
    }, []);
    /**
     * Custom URL change listener which utilises the location to listen for changes. This is used by the
     * RecoilURLSync component to listen for changes to the URL and trigger Variables with QueryParamStore updates.
     *
     * This is required as by default the library only listens for 'popstate' events which are not triggered when
     * the URL is changed programmatically via history.push.
     */
    const listenChangeURL = useCallback((handler) => {
        locationSubscribers.current.push(handler);
        return () => {
            locationSubscribers.current = locationSubscribers.current.filter((item) => item !== handler);
        };
    }, []);
    return {
        browserInterface: {
            listenChangeURL,
        },
        deserialize: urlDeserializer,
        location: { part: 'queryParams' },
        serialize: urlSerializer,
    };
}
//# sourceMappingURL=use-url-sync.js.map