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.11 kB
JavaScript
import{SYMBOLS as n}from"../constants/constants.mjs";import{typeOf as u}from"../utils.mjs";const y=/['"]/g;const m={"'":"%27",'"':"'"};const O=/'|%27/g;const S={"'":'"',"%27":"'"};const g=new RegExp(`^(${n.undefined}|${n.date})`);function l(t){if(typeof t==="function"||typeof t==="symbol")return"";if(b(t)){return t}return JSON.stringify(t,i).replace(y,r=>m[r])}function i(t,r){const e=u(r);if(e!=="object"&&e!=="array"){return s(r)}if(e==="object"){const o=r;const c={};for(const f of Object.keys(o)){c[f]=i(t,o[f])}return c}if(e==="array"){return r.map(o=>i(t,o))}return r}const s=t=>{switch(u(t)){case"date":return n.date+new Date(t).toISOString();case"undefined":return n.undefined;default:return t}};function v(t,r){return d(t.replace(O,e=>S[e]),r)}function d(t,r){try{return JSON.parse(t,a)}catch{return r}}function a(t,r){return typeof r==="string"?p(r):r}const p=t=>{if(t===n.undefined)return void 0;if(t?.startsWith?.(n.date))return new Date(t.slice(1));return t};const b=t=>g.test(String(t));export{v as decode,p as decodePrimitive,l as encode,s as encodePrimitive,d as parseJSON,a as reviver};