state-in-url 0.2.7 → 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/dist/index.cjs +1 -1
- package/dist/index.mjs +1 -1
- package/dist/urlstate/state.d.ts +2 -2
- package/dist/urlstate/useUrlState/useUrlState.d.ts +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -28,7 +28,6 @@
|
|
|
28
28
|
|
|
29
29
|
|
|
30
30
|
<a href="https://state-in-url-asmyshlyaev177.vercel.app/" target="_blank">DEMO</a> |
|
|
31
|
-
<a href="https://stackblitz.com/~/github.com/asmyshlyaev177/state-in-url?file=packages%2Fexample-nextjs%2Fsrc%2Fapp%2FForm.tsx" target="_blank">Demo on Stackblitz</a> |
|
|
32
31
|
<a href ="https://codesandbox.io/p/github/asmyshlyaev177/state-in-url/main?layout=%257B%2522sidebarPanel%2522%253A%2522EXPLORER%2522%252C%2522rootPanelGroup%2522%253A%257B%2522direction%2522%253A%2522horizontal%2522%252C%2522contentType%2522%253A%2522UNKNOWN%2522%252C%2522type%2522%253A%2522PANEL_GROUP%2522%252C%2522id%2522%253A%2522ROOT_LAYOUT%2522%252C%2522panels%2522%253A%255B%257B%2522type%2522%253A%2522PANEL_GROUP%2522%252C%2522contentType%2522%253A%2522UNKNOWN%2522%252C%2522direction%2522%253A%2522vertical%2522%252C%2522id%2522%253A%2522clyk5bd9y00062v6jspcfrkx7%2522%252C%2522sizes%2522%253A%255B100%252C0%255D%252C%2522panels%2522%253A%255B%257B%2522type%2522%253A%2522PANEL_GROUP%2522%252C%2522contentType%2522%253A%2522EDITOR%2522%252C%2522direction%2522%253A%2522horizontal%2522%252C%2522id%2522%253A%2522EDITOR%2522%252C%2522panels%2522%253A%255B%257B%2522type%2522%253A%2522PANEL%2522%252C%2522contentType%2522%253A%2522EDITOR%2522%252C%2522id%2522%253A%2522clyk5bd9x00022v6jyg71cr9e%2522%257D%255D%257D%252C%257B%2522type%2522%253A%2522PANEL_GROUP%2522%252C%2522contentType%2522%253A%2522SHELLS%2522%252C%2522direction%2522%253A%2522horizontal%2522%252C%2522id%2522%253A%2522SHELLS%2522%252C%2522panels%2522%253A%255B%257B%2522type%2522%253A%2522PANEL%2522%252C%2522contentType%2522%253A%2522SHELLS%2522%252C%2522id%2522%253A%2522clyk5bd9x00042v6jsos2y043%2522%257D%255D%257D%255D%257D%252C%257B%2522type%2522%253A%2522PANEL_GROUP%2522%252C%2522contentType%2522%253A%2522DEVTOOLS%2522%252C%2522direction%2522%253A%2522vertical%2522%252C%2522id%2522%253A%2522DEVTOOLS%2522%252C%2522panels%2522%253A%255B%257B%2522type%2522%253A%2522PANEL%2522%252C%2522contentType%2522%253A%2522DEVTOOLS%2522%252C%2522id%2522%253A%2522clyk5bd9x00052v6j5r632b12%2522%257D%255D%257D%255D%252C%2522sizes%2522%253A%255B50%252C50%255D%257D%252C%2522tabbedPanels%2522%253A%257B%2522clyk5bd9x00022v6jyg71cr9e%2522%253A%257B%2522tabs%2522%253A%255B%257B%2522id%2522%253A%2522clyk5bd9w00012v6j83rq3bvo%2522%252C%2522mode%2522%253A%2522permanent%2522%252C%2522type%2522%253A%2522FILE%2522%252C%2522filepath%2522%253A%2522%252FREADME.md%2522%252C%2522state%2522%253A%2522IDLE%2522%257D%255D%252C%2522id%2522%253A%2522clyk5bd9x00022v6jyg71cr9e%2522%252C%2522activeTabId%2522%253A%2522clyk5bd9w00012v6j83rq3bvo%2522%257D%252C%2522clyk5bd9x00052v6j5r632b12%2522%253A%257B%2522id%2522%253A%2522clyk5bd9x00052v6j5r632b12%2522%252C%2522activeTabId%2522%253A%2522clyk5bdjx000b2v6jfc8ae464%2522%252C%2522tabs%2522%253A%255B%257B%2522type%2522%253A%2522SETUP_TASKS%2522%252C%2522id%2522%253A%2522clyk5bdjx000b2v6jfc8ae464%2522%252C%2522mode%2522%253A%2522permanent%2522%257D%252C%257B%2522type%2522%253A%2522UNASSIGNED_PORT%2522%252C%2522port%2522%253A2222%252C%2522id%2522%253A%2522clyk5cjbo004d2v6j3u55k74g%2522%252C%2522mode%2522%253A%2522permanent%2522%257D%252C%257B%2522type%2522%253A%2522ENV_SETUP%2522%252C%2522id%2522%253A%2522clyk5h8dp000r2v6j0r7kc7qq%2522%252C%2522mode%2522%253A%2522permanent%2522%257D%255D%257D%252C%2522clyk5bd9x00042v6jsos2y043%2522%253A%257B%2522id%2522%253A%2522clyk5bd9x00042v6jsos2y043%2522%252C%2522activeTabId%2522%253A%2522clyk5cbuv001q2v6joegrxxv6%2522%252C%2522tabs%2522%253A%255B%257B%2522id%2522%253A%2522clyk5bd9x00032v6jtfhj316o%2522%252C%2522mode%2522%253A%2522permanent%2522%252C%2522type%2522%253A%2522NEW_TERMINAL%2522%257D%252C%257B%2522type%2522%253A%2522TASK_LOG%2522%252C%2522taskId%2522%253A%2522dev%2522%252C%2522id%2522%253A%2522clyk5cbuv001q2v6joegrxxv6%2522%252C%2522mode%2522%253A%2522permanent%2522%257D%252C%257B%2522type%2522%253A%2522TASK_LOG%2522%252C%2522taskId%2522%253A%2522cleanupDist%2522%252C%2522id%2522%253A%2522clyk5dgvo005i2v6jj950sxft%2522%252C%2522mode%2522%253A%2522permanent%2522%257D%255D%257D%257D%252C%2522showDevtools%2522%253Atrue%252C%2522showShells%2522%253Atrue%252C%2522showSidebar%2522%253Atrue%252C%2522sidebarPanelSize%2522%253A15%257D" target="_blank">Demo on Codesandbox</a>
|
|
33
32
|
|
|
34
33
|
|
|
@@ -275,6 +274,7 @@ function SettingsComponent() {
|
|
|
275
274
|
- Use TypeScript for enhanced type safety and autocomplete
|
|
276
275
|
- Avoid storing sensitive information in URL parameters
|
|
277
276
|
- Use `updateState` for frequent updates and `updateUrl` to sync changes to url
|
|
277
|
+
- Use this [extension](https://marketplace.visualstudio.com/items?itemName=yoavbls.pretty-ts-errors) for readable TS errors
|
|
278
278
|
|
|
279
279
|
## Gothas
|
|
280
280
|
|
package/dist/index.cjs
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports,"__esModule",{value:!0});var t=require("react"),e=require("next/navigation");function n(t){return t&&"object"==typeof t&&"default"in t?t:{default:t}}var r=n(t);const c={string:"◖",boolean:"🗵",null:"∙null",undefined:"∙undefined",number:"∓",date:"⏲"},o=t=>{const e=null===t,n=Array.isArray(t),r=t instanceof Date;return(e?"null":r&&"date")||n&&"array"||!e&&!r&&!n&&"object"==typeof t&&"object"||typeof t},s=()=>"undefined"==typeof window,u=t=>new URLSearchParams("string"==typeof t?t:t?.toString?.()||""),a=(t,e)=>JSON.stringify(t)===JSON.stringify(e);function i(t){switch(o(t)){case"function":case"symbol":return"";case"date":return c.date+t.toISOString();case"string":return
|
|
1
|
+
"use strict";Object.defineProperty(exports,"__esModule",{value:!0});var t=require("react"),e=require("next/navigation");function n(t){return t&&"object"==typeof t&&"default"in t?t:{default:t}}var r=n(t);const c={string:"◖",boolean:"🗵",null:"∙null",undefined:"∙undefined",number:"∓",date:"⏲"},o=t=>{const e=null===t,n=Array.isArray(t),r=t instanceof Date;return(e?"null":r&&"date")||n&&"array"||!e&&!r&&!n&&"object"==typeof t&&"object"||typeof t},s=()=>"undefined"==typeof window,u=t=>new URLSearchParams("string"==typeof t?t:t?.toString?.()||""),a=(t,e)=>JSON.stringify(t)===JSON.stringify(e);function i(t){switch(o(t)){case"function":case"symbol":return"";case"date":return c.date+t.toISOString();case"string":return`${c.string}${encodeURIComponent(t)}`;case"number":return c.number+String(t);case"boolean":return c.boolean+String(t);case"object":case"array":return JSON.stringify(t,f).replaceAll('"',"'");case"null":return c.null;case"undefined":return c.undefined;default:return String(t)}}function l(t,e){return function(t,e){try{return JSON.parse(t,g)}catch{const n=d(t);return n!==p?n:e}}(t.replaceAll("'",'"'),e)}const f=(t,e)=>{const n=o(e);return t&&"object"!==n&&"array"!==n?i(e):e},d=t=>t===c.null?null:t!==c.undefined?t?.startsWith?.(c.number)?Number.parseFloat(t.replace(c.number,"")):t?.startsWith?.(c.boolean)?!!t.includes("true"):t?.startsWith?.(c.date)?new Date(t.slice(1)):t?.startsWith?.(c.string)?decodeURIComponent(t).replace(/^◖/,""):p:void 0,p=Symbol("isError"),g=(t,e)=>{const n="string"==typeof e,r=n&&d(e);return r===p?e:t&&n?r:e};const y=(t,e)=>{const n="string"==typeof e,r=n&&l(e?.replaceAll?.("'",'"'));return t&&n?r:e};function b(t,e){try{return JSON.parse(t,y)}catch{const n=d(t);return n!==p?n:e}}function S(t,e,n){const r=u(n);return Object.entries(t||{}).forEach((([t,n])=>{const c=e?.[t];JSON.stringify(n)!==JSON.stringify(c)&&r.set(t,i(n))})),r.toString()}function w(t,e){return{...e||{},...Object.fromEntries([...u(t).entries()].map((([t,n])=>{const r=e?.[t];return[t,l(n,r)??r]})))}}function h(t){const e=r.default.useCallback((function(e,n){return"object"===o(e)?S(e,t,n):""}),[t]);return{parse:r.default.useCallback((function(e){return w(e,t)}),[t]),stringify:e}}const m=new WeakMap,O=new WeakMap,j={get:function(t){return m.get(t)},set:function(t,e){m.set(t,e)}};exports.decode=l,exports.decodeState=w,exports.encode=i,exports.encodeState=S,exports.useUrlEncode=h,exports.useUrlState=function(t,n){const{state:c,getState:o,setState:u,stringify:i}=function(t){const e=r.default.useRef(t),{parse:n,stringify:c}=h(e.current),[o,u]=r.default.useState((()=>{const t=j.get(e.current),r=n(s()?"":window.location.search);return t||(j.set(e.current,r),r)})),i=r.default.useCallback((t=>{const n=j.get(e.current)||e.current;if("function"==typeof t){const r=t(n);if(a(n,r))return;j.set(e.current,r),(O.get(e.current)||[]).forEach((t=>{t()}))}else{if(a(n,t))return;j.set(e.current,t),(O.get(e.current)||[]).forEach((t=>{t()}))}}),[]);return r.default.useInsertionEffect((()=>{const t=O.get(e.current)||[],r=()=>{u(j.get(e.current)||e.current)};O.set(e.current,t.concat(r));const c=()=>{const t=n(window.location.search);i(t)},o="popstate";return window.addEventListener(o,c),()=>{const t=O.get(e.current)||[];O.set(e.current,t.filter((t=>t!==r))),window.removeEventListener(o,c)}}),[i]),{state:o,getState:r.default.useCallback((()=>j.get(e.current)||e.current),[]),setState:i,stringify:c}}(s()?function(t,e){return{...e,...b(JSON.stringify(t),e)}}(n,t):t),l=e.useRouter(),f=r.default.useCallback(((t,e)=>{const n=window.location.search,r=`${window.location.pathname}${n.length&&!n.includes("?")?"?":""}${n}`;let c,s;"function"==typeof t?(c=t(o()),s=i(c)):(c=t??o(),s=i(c)),u(c);const a=`${window.location.pathname}${s.length?"?":""}${s}`;if(r!==a){const{replace:t,...n}=e||{};l[t?"replace":"push"](a,{scroll:!1,...n})}}),[l,i,o]);return{updateState:u,updateUrl:f,state:c}};
|
package/dist/index.mjs
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import t from"react";import{useRouter as e}from"next/navigation";const n={string:"◖",boolean:"🗵",null:"∙null",undefined:"∙undefined",number:"∓",date:"⏲"},r=t=>{const e=null===t,n=Array.isArray(t),r=t instanceof Date;return(e?"null":r&&"date")||n&&"array"||!e&&!r&&!n&&"object"==typeof t&&"object"||typeof t},c=()=>"undefined"==typeof window,o=t=>new URLSearchParams("string"==typeof t?t:t?.toString?.()||""),s=(t,e)=>JSON.stringify(t)===JSON.stringify(e);function
|
|
1
|
+
import t from"react";import{useRouter as e}from"next/navigation";const n={string:"◖",boolean:"🗵",null:"∙null",undefined:"∙undefined",number:"∓",date:"⏲"},r=t=>{const e=null===t,n=Array.isArray(t),r=t instanceof Date;return(e?"null":r&&"date")||n&&"array"||!e&&!r&&!n&&"object"==typeof t&&"object"||typeof t},c=()=>"undefined"==typeof window,o=t=>new URLSearchParams("string"==typeof t?t:t?.toString?.()||""),s=(t,e)=>JSON.stringify(t)===JSON.stringify(e);function u(t){switch(r(t)){case"function":case"symbol":return"";case"date":return n.date+t.toISOString();case"string":return`${n.string}${encodeURIComponent(t)}`;case"number":return n.number+String(t);case"boolean":return n.boolean+String(t);case"object":case"array":return JSON.stringify(t,i).replaceAll('"',"'");case"null":return n.null;case"undefined":return n.undefined;default:return String(t)}}function a(t,e){return function(t,e){try{return JSON.parse(t,g)}catch{const n=l(t);return n!==f?n:e}}(t.replaceAll("'",'"'),e)}const i=(t,e)=>{const n=r(e);return t&&"object"!==n&&"array"!==n?u(e):e},l=t=>t===n.null?null:t!==n.undefined?t?.startsWith?.(n.number)?Number.parseFloat(t.replace(n.number,"")):t?.startsWith?.(n.boolean)?!!t.includes("true"):t?.startsWith?.(n.date)?new Date(t.slice(1)):t?.startsWith?.(n.string)?decodeURIComponent(t).replace(/^◖/,""):f:void 0,f=Symbol("isError"),g=(t,e)=>{const n="string"==typeof e,r=n&&l(e);return r===f?e:t&&n?r:e};const d=(t,e)=>{const n="string"==typeof e,r=n&&a(e?.replaceAll?.("'",'"'));return t&&n?r:e};function p(t,e){try{return JSON.parse(t,d)}catch{const n=l(t);return n!==f?n:e}}function y(t,e,n){const r=o(n);return Object.entries(t||{}).forEach((([t,n])=>{const c=e?.[t];JSON.stringify(n)!==JSON.stringify(c)&&r.set(t,u(n))})),r.toString()}function b(t,e){return{...e||{},...Object.fromEntries([...o(t).entries()].map((([t,n])=>{const r=e?.[t];return[t,a(n,r)??r]})))}}function S(e){const n=t.useCallback((function(t,n){return"object"===r(t)?y(t,e,n):""}),[e]);return{parse:t.useCallback((function(t){return b(t,e)}),[e]),stringify:n}}const w=new WeakMap,m=new WeakMap,h={get:function(t){return w.get(t)},set:function(t,e){w.set(t,e)}};function O(n,r){const{state:o,getState:u,setState:a,stringify:i}=function(e){const n=t.useRef(e),{parse:r,stringify:o}=S(n.current),[u,a]=t.useState((()=>{const t=h.get(n.current),e=r(c()?"":window.location.search);return t||(h.set(n.current,e),e)})),i=t.useCallback((t=>{const e=h.get(n.current)||n.current;if("function"==typeof t){const r=t(e);if(s(e,r))return;h.set(n.current,r),(m.get(n.current)||[]).forEach((t=>{t()}))}else{if(s(e,t))return;h.set(n.current,t),(m.get(n.current)||[]).forEach((t=>{t()}))}}),[]);return t.useInsertionEffect((()=>{const t=m.get(n.current)||[],e=()=>{a(h.get(n.current)||n.current)};m.set(n.current,t.concat(e));const c=()=>{const t=r(window.location.search);i(t)},o="popstate";return window.addEventListener(o,c),()=>{const t=m.get(n.current)||[];m.set(n.current,t.filter((t=>t!==e))),window.removeEventListener(o,c)}}),[i]),{state:u,getState:t.useCallback((()=>h.get(n.current)||n.current),[]),setState:i,stringify:o}}(c()?function(t,e){return{...e,...p(JSON.stringify(t),e)}}(r,n):n),l=e(),f=t.useCallback(((t,e)=>{const n=window.location.search,r=`${window.location.pathname}${n.length&&!n.includes("?")?"?":""}${n}`;let c,o;"function"==typeof t?(c=t(u()),o=i(c)):(c=t??u(),o=i(c)),a(c);const s=`${window.location.pathname}${o.length?"?":""}${o}`;if(r!==s){const{replace:t,...n}=e||{};l[t?"replace":"push"](s,{scroll:!1,...n})}}),[l,i,u]);return{updateState:a,updateUrl:f,state:o}}export{a as decode,b as decodeState,u as encode,y as encodeState,S as useUrlEncode,O as useUrlState};
|
package/dist/urlstate/state.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { type JSONCompatible } from './utils';
|
|
1
|
+
import { type DeepReadonly, type JSONCompatible } from './utils';
|
|
2
2
|
export declare function useState<T extends JSONCompatible>(defaultState: T): {
|
|
3
3
|
state: T;
|
|
4
4
|
getState: () => T;
|
|
5
|
-
setState: (value: T | ((currState: T) => T)) => void;
|
|
5
|
+
setState: (value: T | DeepReadonly<T> | ((currState: T) => T)) => void;
|
|
6
6
|
stringify: (state: T, paramsToKeep?: string | URLSearchParams | undefined) => string;
|
|
7
7
|
};
|
|
@@ -29,7 +29,7 @@ export declare function useUrlState<T extends JSONCompatible>(defaultState: T, s
|
|
|
29
29
|
*
|
|
30
30
|
* * Github {@link https://github.com/asmyshlyaev177/state-in-url/tree/main/packages/urlstate/useUrlState#updatestate}
|
|
31
31
|
*/
|
|
32
|
-
updateState: (value: T | ((currState: T) => T)) => void;
|
|
32
|
+
updateState: (value: T | DeepReadonly<T> | ((currState: T) => T)) => void;
|
|
33
33
|
/**
|
|
34
34
|
* * Example:
|
|
35
35
|
* ```ts
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "state-in-url",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "1.0.0",
|
|
4
4
|
"description": "Library to store state in browser URL, includes hook for NextJS, hook for pure React, and low level helpers.",
|
|
5
5
|
"homepage": "https://github.com/asmyshlyaev177/state-in-url#readme",
|
|
6
6
|
"keywords": [
|