UNPKG

state-in-url

Version:

Store state in URL as in object, types and structure are preserved, with TS validation. Same API as React.useState, wthout any hasssle or boilerplate. Next.js@14-15, react-router@6-7, and remix@2.

2 lines (1 loc) 1.43 kB
"use strict";var T=require("react");var _=require("../constants/constants.js");var k=require("../useInsertionEffect.js");var C=require("../useSharedState/useSharedState.js");var I=require("../useUrlEncode/useUrlEncode.js");var o=require("../utils.js");function P(t){return t&&t.__esModule?t:{default:t}}var v=P(T);let s;let r;function b(t,a,w,S){const{parse:c,stringify:l}=I.useUrlEncode(t);const{state:g,getState:i,setState:n}=C.useSharedState(t,()=>w?.({parse:c})||t);k.useInsertionEffect(()=>{const e=()=>{n(c(o.filterUnknownParamsClient(t,o.getSearch())))};window.addEventListener(o.popstateEv,e);return()=>{window.removeEventListener(o.popstateEv,e)}},[]);const u=v.default.useCallback((e,E)=>{const d=typeof e==="function"?e(i(),t):{...i(),...e};const f=l(d,o.getOtherParams(t,window.location.search));const p=y(window.location.pathname,S);const h=`${p}${f.length?"?":""}${f}${window.location.hash}`;const U=`${p}${window.location.search}${window.location.hash}`;if(h===U)return;n(d);const{replace:$,...q}=E||{};clearTimeout(s);s=void 0;r={router:a,method:$?"replace":"push",url:h,opts:q};s=setTimeout(()=>{if(r){r.router[r.method](r.url,r.opts);r=void 0}s=void 0},_.TIMEOUT)},[a,l,i]);const m=v.default.useCallback(e=>{n(t);u(t,e)},[u,n]);return{updateState:n,updateUrl:u,state:g,reset:m,getState:i,pendingUrlUpdate:()=>s!==void 0}}function y(t,a){if(!a||a==="/"){return t}return t.slice(a.length)}exports.useUrlStateBase=b;