nuqs
Version:
78 lines (77 loc) • 3.46 kB
JavaScript
"use client";
import { t as debug } from "../debug-CH5E3t0A.js";
import { c as renderQueryString, n as createAdapterProvider } from "../context-Mu913OAK.js";
import { t as resetQueues } from "../reset-Cwe7SWyj.js";
import { n as filterSearchParams } from "../key-isolation-Em0NBdl2.js";
import { i as patchHistory, n as historyUpdateMarker, t as getHistorySyncEmitter } from "../patch-history-Bze7i4qB.js";
import { createContext, createElement, useContext, useEffect, useMemo, useRef, useSyncExternalStore } from "react";
//#region src/adapters/react.ts
const emitter = getHistorySyncEmitter("react");
function generateUpdateUrlFn(fullPageNavigationOnShallowFalseUpdates) {
return function updateUrl(search, options) {
const url = new URL(location.href);
url.search = renderQueryString(search);
debug(20, "react", url);
if (fullPageNavigationOnShallowFalseUpdates && options.shallow === false) (options.history === "push" ? location.assign : location.replace).call(location, url);
else (options.history === "push" ? history.pushState : history.replaceState).call(history, history.state, historyUpdateMarker, url);
emitter.emit("update", search);
if (options.scroll === true) window.scrollTo({ top: 0 });
};
}
const NuqsReactAdapterContext = createContext({ fullPageNavigationOnShallowFalseUpdates: false });
function subscribe(onStoreChange) {
emitter.on("update", onStoreChange);
window.addEventListener("popstate", onStoreChange);
return () => {
emitter.off("update", onStoreChange);
window.removeEventListener("popstate", onStoreChange);
};
}
function QueueReset() {
useEffect(() => {
window.addEventListener("popstate", resetQueues);
return () => window.removeEventListener("popstate", resetQueues);
}, []);
return null;
}
function useNuqsReactAdapter(watchKeys) {
const { fullPageNavigationOnShallowFalseUpdates, serverSearch } = useContext(NuqsReactAdapterContext);
const cache = useRef(null);
function snapshot(source) {
const filteredSearch = filterSearchParams(new URLSearchParams(source), watchKeys, false);
const key = filteredSearch.toString();
if (cache.current?.key === key) return cache.current.search;
cache.current = {
key,
search: filteredSearch
};
return filteredSearch;
}
return {
searchParams: useSyncExternalStore(subscribe, () => snapshot(location.search), () => snapshot(serverSearch ?? "")),
updateUrl: useMemo(() => generateUpdateUrlFn(fullPageNavigationOnShallowFalseUpdates), [fullPageNavigationOnShallowFalseUpdates])
};
}
const NuqsReactAdapter = createAdapterProvider(useNuqsReactAdapter);
function NuqsAdapter({ children, fullPageNavigationOnShallowFalseUpdates = false, serverSearch, ...adapterProps }) {
return createElement(NuqsReactAdapterContext.Provider, { value: {
fullPageNavigationOnShallowFalseUpdates,
serverSearch
} }, createElement(NuqsReactAdapter, {
...adapterProps,
children: [createElement(QueueReset, { key: "nuqs-adapter-queue-reset" }), children]
}));
}
/**
* Opt-in to syncing shallow updates of the URL with the useOptimisticSearchParams hook.
*
* By default, the useOptimisticSearchParams hook will only react to internal nuqs updates.
* If third party code updates the History API directly, use this function to
* enable useOptimisticSearchParams to react to those changes.
*/
function enableHistorySync() {
patchHistory(emitter, "react");
}
//#endregion
export { NuqsAdapter, enableHistorySync };
//# sourceMappingURL=react.js.map