state-in-url 4.1.1 → 4.1.2
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 +4 -3
- package/dist/constants/constants.d.ts +1 -0
- package/dist/constants/constants.mjs +1 -1
- package/dist/constants/index.mjs +1 -1
- package/dist/next/useUrlState/useUrlState.mjs +1 -1
- package/dist/useSharedState/useSharedState.mjs +1 -1
- package/dist/useUrlStateBase/useUrlStateBase.mjs +1 -1
- package/dist/utils.d.ts +2 -1
- package/dist/utils.mjs +1 -1
- package/package.json +8 -2
package/README.md
CHANGED
|
@@ -45,9 +45,9 @@ Add a ⭐️ and <a href="https://github.com/asmyshlyaev177" target="_blank">fol
|
|
|
45
45
|
Will appreciate you feedback/opinion on [discussions](https://github.com/asmyshlyaev177/state-in-url/discussions/1)
|
|
46
46
|
|
|
47
47
|
Share if it useful for you.
|
|
48
|
-
[FB](https://www.facebook.com/sharer.php?u=https://github.com/asmyshlyaev177/state-in-url)
|
|
49
|
-
[LinkedIn](https://www.linkedin.com/sharing/share-offsite/?url=https://github.com/asmyshlyaev177/state-in-url)
|
|
50
48
|
[X.com](https://twitter.com/intent/tweet?&url=https://github.com/asmyshlyaev177/state-in-url)
|
|
49
|
+
[LinkedIn](https://www.linkedin.com/sharing/share-offsite/?url=https://github.com/asmyshlyaev177/state-in-url)
|
|
50
|
+
[FB](https://www.facebook.com/sharer.php?u=https://github.com/asmyshlyaev177/state-in-url)
|
|
51
51
|
[VK](http://vk.com/share.php?url=https://github.com/asmyshlyaev177/state-in-url)
|
|
52
52
|
|
|
53
53
|
<hr />
|
|
@@ -56,7 +56,7 @@ Share if it useful for you.
|
|
|
56
56
|
|
|
57
57
|
## Why use `state-in-url`?
|
|
58
58
|
|
|
59
|
-
Store any user state in query parameters; imagine JSON in a browser URL
|
|
59
|
+
Store any user state in query parameters; imagine JSON in a browser URL. All of it with keeping types and structure of data, e.g. numbers will be decoded as numbers not strings, dates as dates, etc, objects and arrays supported.
|
|
60
60
|
Dead simple, fast, and with static Typescript validation. Deep links, aka URL synchronization, made easy.
|
|
61
61
|
|
|
62
62
|
Contains `useUrlState` hook for Next.js and react-router, and helpers for anything else on JS.
|
|
@@ -70,6 +70,7 @@ This library is a good alternative for NUQS.
|
|
|
70
70
|
### Use cases
|
|
71
71
|
|
|
72
72
|
- Store unsaved user forms or page filters in URL
|
|
73
|
+
- Sycn URL with React state
|
|
73
74
|
- Just sync data between unrelated client components without touching URI
|
|
74
75
|
- Shareable URLs with application state (Deep linking, URL state synchronization)
|
|
75
76
|
- Easy state persistence across page reloads
|
|
@@ -1 +1 @@
|
|
|
1
|
-
const
|
|
1
|
+
import{isSafari as e}from"../utils.mjs";const d={date:"⏲",undefined:"∙undefined"},n=e?330:70;export{d as SYMBOLS,n as TIMEOUT};
|
package/dist/constants/index.mjs
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export{SYMBOLS}from"./constants.mjs";
|
|
1
|
+
export{SYMBOLS,TIMEOUT}from"./constants.mjs";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{useRouter as e,useSearchParams as t}from"next/navigation";import a from"react";import{parseSPObj as r}from"../../parseSPObj.mjs";import{useUrlStateBase as s}from"../../useUrlStateBase/useUrlStateBase.mjs";import{routerHistory as l,isSSR as o,filterUnknownParams as c,filterUnknownParamsClient as u}from"../../utils.mjs";function i(i,p){const n="defaultState"in i?i.defaultState:i,f="defaultState"in i?i.searchParams:p?.searchParams,S="defaultState"in i?i.useHistory:p?.useHistory,d="defaultState"in i?{scroll:i.scroll,replace:i.replace}:{scroll:p?.scroll,replace:p?.replace},j=void 0===S||S?l:e(),{state:U,updateState:b,updateUrl:g,reset:P,getState:h}=s(n,j,(({parse:e})=>o
|
|
1
|
+
import{useRouter as e,useSearchParams as t}from"next/navigation";import a from"react";import{parseSPObj as r}from"../../parseSPObj.mjs";import{useUrlStateBase as s}from"../../useUrlStateBase/useUrlStateBase.mjs";import{routerHistory as l,isSSR as o,filterUnknownParams as c,filterUnknownParamsClient as u}from"../../utils.mjs";function i(i,p){const n="defaultState"in i?i.defaultState:i,f="defaultState"in i?i.searchParams:p?.searchParams,S="defaultState"in i?i.useHistory:p?.useHistory,d="defaultState"in i?{scroll:i.scroll,replace:i.replace}:{scroll:p?.scroll,replace:p?.replace},j=void 0===S||S?l:e(),{state:U,updateState:b,updateUrl:g,reset:P,getState:h}=s(n,j,(({parse:e})=>o?r(c(n,f),n):e(u(n)))),k=a.useMemo((()=>({...m,...d})),[]),v=a.useCallback(((e,t)=>g(e,{...k,...t})),[g]),x=t();a.useEffect((()=>{b(c(n,r(Object.fromEntries([...x.entries()]),n)))}),[x]);const y=a.useCallback((e=>{P({...k,...e})}),[P]);return{setState:b,updateState:b,setUrl:v,updateUrl:v,urlState:U,state:U,reset:y,getState:h}}const m={replace:!0,scroll:!1};export{i as useUrlState};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import t from"react";import{stateMap as r,subscribers as e}from"../subscribers.mjs";import{useInsertionEffect as n}from"../useInsertionEffect.mjs";import{isSSR as u,isEqual as c}from"../utils.mjs";function s(s,o){const f=t.useRef(s),[a,i]=t.useState((()=>{if(u
|
|
1
|
+
import t from"react";import{stateMap as r,subscribers as e}from"../subscribers.mjs";import{useInsertionEffect as n}from"../useInsertionEffect.mjs";import{isSSR as u,isEqual as c}from"../utils.mjs";function s(s,o){const f=t.useRef(s),[a,i]=t.useState((()=>{if(u)return o?o?.():f.current;const t=r.get(f.current);if(t)return t;{const t=o?.()||f.current;return r.set(f.current,t),t}})),m=t.useCallback((t=>{const n=r.get(f.current),u="function"==typeof t?t(n):{...n,...t};c(n,u)||(r.set(f.current,u),e.get(f.current).forEach((t=>t())))}),[]);n((()=>{const t=e.add(f.current,(()=>{i(r.get(f.current)||f.current)}));return()=>{t()}}),[]);return{state:a,getState:t.useCallback((()=>r.get(f.current)||f.current),[]),setState:m}}export{s as useSharedState};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import e from"react";import{
|
|
1
|
+
import e from"react";import{TIMEOUT as t}from"../constants/constants.mjs";import{useInsertionEffect as o}from"../useInsertionEffect.mjs";import{useSharedState as r}from"../useSharedState/useSharedState.mjs";import{useUrlEncode as n}from"../useUrlEncode/useUrlEncode.mjs";import{filterUnknownParamsClient as s}from"../utils.mjs";function a(a,i,u){const{parse:m,stringify:l}=n(a),{state:p,getState:d,setState:f}=r(a,(()=>u?.({parse:m})||a)),h=e.useRef(void 0);o((()=>{const e=()=>{const e=m(s(a));f(e)};return window.addEventListener(c,e),()=>{window.removeEventListener(c,e),clearTimeout(h.current)}}),[f]);const w=e.useRef([]),S=e.useCallback(((e,o)=>{const r="function"==typeof e?e(d()):e?{...d(),...e}:d(),n=l(r,function(e){const t=Object.keys(e),o=window.location.search,r=new URLSearchParams(o),n=new URLSearchParams;return r.forEach(((e,o)=>!t.includes(o)&&n.set(o,e))),n}(a)),s=`${window.location.pathname}${n.length?"?":""}${n}${window.location.hash}`;if(s===`${window.location.pathname}${window.location.search}${window.location.hash}`)return;let c;f(r);const u=o?.replace;delete o?.replace,w.current.push([u?"replace":"push",s,o]),clearTimeout(h.current),h.current=setTimeout((()=>{queueMicrotask((()=>{for(;w.current.length;){const e=w.current.shift();e&&e?.[1]!==c?.[1]&&(c=e)}const[e,t,o]=c||{};c=void 0,e&&i[e](t,o)}))}),t)}),[i,l,d]),$=e.useCallback((e=>{S(a,e)}),[S]);return{updateState:f,updateUrl:S,state:p,reset:$,getState:d}}const c="popstate";export{a as useUrlStateBase};
|
package/dist/utils.d.ts
CHANGED
|
@@ -10,7 +10,7 @@ export type Type = "string" | "date" | "boolean" | "number" | "bigint" | "undefi
|
|
|
10
10
|
export declare const typeOf: (val: unknown) => Type;
|
|
11
11
|
export declare const isPrimitive: (val: unknown) => val is Simple;
|
|
12
12
|
export type Simple = string | Date | boolean | number | null | undefined | Function | symbol;
|
|
13
|
-
export declare const isSSR:
|
|
13
|
+
export declare const isSSR: boolean;
|
|
14
14
|
export type JSON = null | boolean | Date | number | string | {
|
|
15
15
|
[prop: string]: JSON | JSON[];
|
|
16
16
|
};
|
|
@@ -31,3 +31,4 @@ export interface Router {
|
|
|
31
31
|
replace: (href: string, opts: object) => void;
|
|
32
32
|
}
|
|
33
33
|
export declare const routerHistory: Router;
|
|
34
|
+
export declare const isSafari: boolean;
|
package/dist/utils.mjs
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
const t=t=>{const
|
|
1
|
+
const t=t=>{const e=typeof t,n=null===t,r=Array.isArray(t),o=t instanceof Date;return(n?"null":o&&"date")||r&&"array"||!n&&!o&&!r&&"object"===e&&"object"||e},e="undefined"==typeof window,n=t=>new URLSearchParams("string"==typeof t?r(t):t?.toString?.()||""),r=t=>t.split("?")?.[1]||t||"",o=(t,e)=>JSON.stringify(t)===JSON.stringify(e);function i(t){const e=new URLSearchParams;return c(t,[...new URLSearchParams(window.location.search).entries()]).forEach((([t,n])=>e.set(t,n))),e.toString()}function s(t,e){return Object.fromEntries(c(t,Object.entries(e||{})))}function c(t,e){const n=Object.keys(t),r=[];for(let t=0;t<e.length;t++)n.includes(e[t]?.[0])&&r.push([e[t][0].replace(/\+/g," "),e[t][1]]);return r}function a(t,e){const n=Object.assign({},t);return Object.entries(t).forEach((([r])=>{const o=r,i=void 0!==e[o];n[o]=i?e[o]:t[o]})),n}const u={push:t=>{window&&window.history.pushState(null,"",t)},replace:t=>{window&&window.history.replaceState(null,"",t)}},l=/apple/i.test(!e&&navigator?.userAgent||"");export{a as assignValue,c as filterUnknown,s as filterUnknownParams,i as filterUnknownParamsClient,n as getParams,o as isEqual,e as isSSR,l as isSafari,u as routerHistory,t as typeOf};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "state-in-url",
|
|
3
|
-
"version": "4.1.
|
|
3
|
+
"version": "4.1.2",
|
|
4
4
|
"description": "Easily share complex state objects between unrelated React components, preserve types and structure, with TS validation. Deep links and url state synchronization wthout any hasssle or boilerplate.",
|
|
5
5
|
"homepage": "https://state-in-url.dev",
|
|
6
6
|
"repository": {
|
|
@@ -202,6 +202,12 @@
|
|
|
202
202
|
],
|
|
203
203
|
"command": "cd packages/example-nextjs14 && npm run build"
|
|
204
204
|
},
|
|
205
|
+
"build:demo:tests": {
|
|
206
|
+
"dependencies": [
|
|
207
|
+
"build"
|
|
208
|
+
],
|
|
209
|
+
"command": "cd packages/example-nextjs14 && npx cross-env TEST=true npm run build"
|
|
210
|
+
},
|
|
205
211
|
"start:demo": {
|
|
206
212
|
"dependencies": [
|
|
207
213
|
"build:demo"
|
|
@@ -272,7 +278,7 @@
|
|
|
272
278
|
"dependencies": [
|
|
273
279
|
"build",
|
|
274
280
|
"build:react",
|
|
275
|
-
"build:demo",
|
|
281
|
+
"build:demo:tests",
|
|
276
282
|
"build:next15",
|
|
277
283
|
"build:router6"
|
|
278
284
|
]
|