import { useMemo } from "react";
import { useRoute } from "./useRoute";
import { buildQueryString, parseQueryString } from "./utils/queryString";
export function useQuery(controller) {
    const { blockers, storage } = controller;
    const route = useRoute(controller.storage);
    return useMemo(() => {
        const currentQuery = parseQueryString(route.queryString ?? "");
        const setQuery = async (query, { merge = true, push = false, force = false } = {}) => {
            function getNextRoute() {
                const prevRoute = storage.getRoute();
                const prevQuery = parseQueryString(prevRoute.queryString ?? "");
                const nextQuery = merge ? { ...prevQuery, ...query } : query;
                const nextRoute = {
                    queryString: buildQueryString(nextQuery),
                };
                return nextRoute;
            }
            if (!force) {
                const blocked = await blockers.isBlocking(getNextRoute());
                if (blocked) {
                    return;
                }
            }
            // We have to build it again here.
            // In case there are multiple route changes in parallel, with `merge: true`,
            // and because blocker is async,
            // we may need to rebuild the next route right before sending it to storage,
            // as `prevRoute = storage.getRoute()` may have changed in the meantime.
            const nextRoute = getNextRoute();
            if (push) {
                storage.pushRoute(nextRoute);
            }
            else {
                storage.replaceRoute(nextRoute);
            }
        };
        return [currentQuery, setQuery];
    }, [route.queryString, storage, blockers]);
}
//# sourceMappingURL=useQuery.jsx.map