UNPKG

nuqs

Version:

Type-safe search params state manager for React - Like useState, but stored in the URL query string

79 lines (77 loc) 2.84 kB
import { debounceController, globalThrottleQueue } from "./debounce-CmqzOOem.js"; import { debug, renderQueryString } from "./context-BWo_DoaC.js"; import { resetQueues } from "./reset-BmRuoRYl.js"; import { markHistoryAsPatched, shouldPatchHistory } from "./patch-history-VL_JehFX.js"; import { startTransition, useCallback, useEffect, useOptimistic } from "react"; import { useRouter, useSearchParams } from "next/navigation.js"; //#region src/adapters/next/impl.app.ts const NUM_HISTORY_CALLS_PER_UPDATE = 3; let mutex = 0; function onPopState() { mutex = 0; resetQueues(); } function onHistoryStateUpdate() { mutex--; if (mutex <= 0) { mutex = 0; queueMicrotask(resetQueues); } } function patchHistory() { if (!shouldPatchHistory("next/app")) return; const originalReplaceState = history.replaceState; const originalPushState = history.pushState; history.replaceState = function nuqs_replaceState(state, title, url) { onHistoryStateUpdate(); return originalReplaceState.call(history, state, title, url); }; history.pushState = function nuqs_pushState(state, title, url) { onHistoryStateUpdate(); return originalPushState.call(history, state, title, url); }; markHistoryAsPatched("next/app"); } function NavigationSpy() { useEffect(() => { patchHistory(); window.addEventListener("popstate", onPopState); return () => window.removeEventListener("popstate", onPopState); }, []); return null; } function useNuqsNextAppRouterAdapter() { const router = useRouter(); const searchParams = useSearchParams(); const [optimisticSearchParams, setOptimisticSearchParams] = useOptimistic(searchParams); const updateUrl = useCallback((search, options) => { const queuedThrottledKeys = globalThrottleQueue.reset(); const resetKeysToSync = queuedThrottledKeys.concat(Array.from(debounceController.queuedQuerySync.all.keys())); startTransition(() => { if (!options.shallow) { setOptimisticSearchParams(search); for (const key of resetKeysToSync) debounceController.queuedQuerySync.emit(key); } const url = renderURL(search); debug("[nuqs next/app] Updating url: %s", url); const updateMethod = options.history === "push" ? history.pushState : history.replaceState; mutex = NUM_HISTORY_CALLS_PER_UPDATE; updateMethod.call(history, null, "", url); if (options.scroll) window.scrollTo(0, 0); if (!options.shallow) router.replace(url, { scroll: false }); }); }, []); return { searchParams: optimisticSearchParams, updateUrl, rateLimitFactor: NUM_HISTORY_CALLS_PER_UPDATE, autoResetQueueOnUpdate: false }; } function renderURL(search) { const { origin, pathname, hash } = location; return origin + pathname + renderQueryString(search) + hash; } //#endregion export { NavigationSpy, useNuqsNextAppRouterAdapter }; //# sourceMappingURL=impl.app-H50vLAJE.js.map