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