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) 2.38 kB
const c=n=>{if(n===null)return"null";const e=typeof n;if(e!=="object")return e;if(Array.isArray(n))return"array";if(n instanceof Date)return"date";return"object"};const w=n=>{const e=c(n);return e!=="object"&&e!=="array"};const i=typeof window==="undefined";const y=n=>{if(n instanceof URLSearchParams){return n}if(typeof n==="string"){const e=n.indexOf("?");return new URLSearchParams(e===-1?n:n.slice(e+1))}return new URLSearchParams};const p=(n,e)=>{if(n.length!==e.length)return false;return n.every((r,o)=>a(r,e[o]))};const h=(n,e)=>{const r=Object.keys(n);const o=Object.keys(e);if(r.length!==o.length)return false;return r.every(t=>a(n[t],e[t]))};const a=(n,e)=>{if(n===e)return true;if(n==null||e==null)return false;const r=c(n);const o=c(e);if(r!==o)return false;if(w(n))return false;if(r==="array"){return p(n,e)}if(r==="object"){return h(n,e)}return JSON.stringify(n)===JSON.stringify(e)};function S(n,e){const r=new URLSearchParams;const o=f(n,[...new URLSearchParams(e||"").entries()]);for(const[t,s]of o){r.set(t,s)}return r.toString()}function g(n,e){const r=e instanceof URLSearchParams?[...e.entries()]:Object.entries(e||{});return Object.fromEntries(f(n,r))}function f(n,e){const r=Object.keys(n);const o=[];for(let t=0;t<e.length;t++){if(r.includes(e[t]?.[0])){o.push([e[t][0].replace(/\+/g," "),e[t][1]])}}return o}function b(n,e){const r=Object.assign({},n);for(const[o]of Object.entries(n)){const t=o;const s=e[t]!==void 0;r[t]=s?e[t]:n[t]}return r}const m={push:n=>{if(typeof window!=="undefined"){window.history.pushState(null,"",n)}},replace:n=>{if(typeof window!=="undefined"){window.history.replaceState(null,"",n)}}};const j=/apple/i.test(!i&&navigator?.userAgent||"");const u="popstate";function O(){return i?"":window.location.search}const l=new Set;let d=false;function v(){if(d||i)return;d=true;for(const n of["pushState","replaceState"]){const e=window.history[n];window.history[n]=function r(...o){const t=e.apply(this,o);for(const s of[...l])s();return t}}}function P(n){if(i)return()=>void 0;v();l.add(n);window.addEventListener(u,n);return()=>{l.delete(n);window.removeEventListener(u,n)}}export{b as assignValue,f as filterUnknown,g as filterUnknownParams,S as filterUnknownParamsClient,y as getParams,O as getSearch,a as isEqual,w as isPrimitive,i as isSSR,j as isSafari,u as popstateEv,m as routerHistory,P as subscribeToUrl,c as typeOf};