From f38637c824bd0e243710c1530be908438772a096 Mon Sep 17 00:00:00 2001 From: semantic-release-bot Date: Sun, 10 Nov 2024 11:04:49 +0000 Subject: [PATCH] chore(release): 4.0.6 [skip ci] ## [4.0.6](https://github.com/asmyshlyaev177/state-in-url/compare/v4.0.5...v4.0.6) (2024-11-10) ### Bug Fixes * use first argument for `defaultState` and second as object with other options ([b896d5f](https://github.com/asmyshlyaev177/state-in-url/commit/b896d5f0bc7b33ba036612a5dada69315609fb2c)) --- CHANGELOG.md | 7 ++ dist/next/useUrlState/useUrlState.d.ts | 84 +++++++------------ dist/next/useUrlState/useUrlState.mjs | 2 +- .../react-router/useUrlState/useUrlState.d.ts | 82 ++++++++---------- dist/react-router/useUrlState/useUrlState.mjs | 2 +- dist/utils.d.ts | 2 +- dist/utils.mjs | 2 +- package.json | 2 +- 8 files changed, 77 insertions(+), 106 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 09d1d93..0fe3587 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,10 @@ +## [4.0.6](https://github.com/asmyshlyaev177/state-in-url/compare/v4.0.5...v4.0.6) (2024-11-10) + + +### Bug Fixes + +* use first argument for `defaultState` and second as object with other options ([b896d5f](https://github.com/asmyshlyaev177/state-in-url/commit/b896d5f0bc7b33ba036612a5dada69315609fb2c)) + ## [4.0.5](https://github.com/asmyshlyaev177/state-in-url/compare/v4.0.4...v4.0.5) (2024-11-09) diff --git a/dist/next/useUrlState/useUrlState.d.ts b/dist/next/useUrlState/useUrlState.d.ts index b934e76..41b85bf 100644 --- a/dist/next/useUrlState/useUrlState.d.ts +++ b/dist/next/useUrlState/useUrlState.d.ts @@ -1,18 +1,32 @@ -import { useRouter } from "next/navigation"; import { type JSONCompatible } from "../../utils"; +/** + * @deprecated . + * * use format `useUrlState(defaultState, { ...otherParams })` + * + * . + */ +export declare function useUrlState({ defaultState: T, searchParams, replace, scroll, useHistory, }: OldParams): { + state: T; + urlState: T; + updateState: (value: Partial | ((currState: T) => T)) => void; + setState: (value: Partial | ((currState: T) => T)) => void; + updateUrl: (value?: Partial | ((currState: T) => T)) => void; + setUrl: (value?: Partial | ((currState: T) => T)) => void; +}; /** * NextJS hook. Returns `urlState`, `setState`, and `setUrl` functions * * @param {JSONCompatible} [defaultState] Fallback (default) values for state - * @param {?SearchParams} [searchParams] searchParams from Next server component - * @param {boolean} [useHistory] use window.history for navigation, no _rsc requests https://github.com/vercel/next.js/discussions/59167 + * @param {Object} params - Object with other parameters + * @param {?SearchParams} params.searchParams searchParams from Next server component + * @param {boolean} params.useHistory use window.history for navigation, default true, no _rsc requests https://github.com/vercel/next.js/discussions/59167 * * * Example: * ```ts * export const form = { name: '', age: 0 }; - * const { urlState, setState, setUrl } = useUrlState({ defaultState: form }); - * // for nextjs seerver components - * // const { urlState, setState, setUrl } = useUrlState({ defaultState: form, searchParams }); + * const { urlState, setState, setUrl } = useUrlState(form); + * // for nextjs server components + * const { urlState, setState, setUrl } = useUrlState(form, { searchParams }); * * setState({ name: 'test' }); * // by default it's uses router.push with scroll: false @@ -23,56 +37,22 @@ import { type JSONCompatible } from "../../utils"; * * * Docs {@link https://github.com/asmyshlyaev177/state-in-url/tree/master/packages/urlstate/next/useUrlState#api} */ -export declare function useUrlState({ defaultState, searchParams, useHistory, ...opts }: { +export declare function useUrlState(defaultState: T, params?: Params): { + urlState: T; + setState: (value: Partial | ((currState: T) => T)) => void; + setUrl: (value?: Partial | ((currState: T) => T)) => void; +}; +interface OldParams { defaultState: T; searchParams?: object; replace?: boolean; scroll?: boolean; useHistory?: boolean; -}): { - /** - * * Example: - * ```ts - * setState({ name: 'test' }); - * // or - * setState(curr => ({ ...curr, name: 'test' }) ); - * ``` - * - * * Docs {@link https://github.com/asmyshlyaev177/state-in-url/tree/master/packages/urlstate/next/useUrlState#updatestate} - */ - setState: (value: Partial | ((currState: T) => T)) => void; - /** - * @deprecated use `setState` - */ - updateState: (value: Partial | ((currState: T) => T)) => void; - /** - * * Example: - * ```ts - * setUrl({ name: 'test' }); - * // or - * setUrl(curr => ({ ...curr, name: 'test' }), { replace: true, scroll: false } ); - * ``` - * - * * Docs {@link https://github.com/asmyshlyaev177/state-in-url/tree/master/packages/urlstate/next/useUrlState#updateurl} - */ - setUrl: (value?: Parameters<(value?: Partial | ((currState: T) => T) | undefined, options?: import("../../useUrlStateBase/useUrlStateBase").Options) => void>[0], options?: Options) => void; - /** - * @deprecated use `setUrl` - */ - updateUrl: (value?: Parameters<(value?: Partial | ((currState: T) => T) | undefined, options?: import("../../useUrlStateBase/useUrlStateBase").Options) => void>[0], options?: Options) => void; - /** - * State object. Don't mutate directly, use `setState` or `setUrl` - */ - urlState: T; - /** - * @deprecated use `urlState` - */ - state: T; - getState: () => T; -}; -type Router = ReturnType; -type RouterOptions = NonNullable[1] | Parameters[1]>; -interface Options extends RouterOptions { - replace?: boolean; } +type Params = { + searchParams?: object; + replace?: boolean; + scroll?: boolean; + useHistory?: boolean; +}; export {}; diff --git a/dist/next/useUrlState/useUrlState.mjs b/dist/next/useUrlState/useUrlState.mjs index 60ba70c..7f59318 100644 --- a/dist/next/useUrlState/useUrlState.mjs +++ b/dist/next/useUrlState/useUrlState.mjs @@ -1 +1 @@ -import{useRouter as t,useSearchParams as e}from"next/navigation";import r from"react";import{parseSPObj as a}from"../../parseSPObj.mjs";import{useUrlStateBase as s}from"../../useUrlStateBase/useUrlStateBase.mjs";import{routerHistory as o,isSSR as m,filterUnknownParams as u,filterUnknownParamsClient as i}from"../../utils.mjs";function l({defaultState:l,searchParams:c,useHistory:f,...n}){const S=void 0===f||f?o:t(),{state:d,updateState:j,updateUrl:U,getState:b}=s(l,S,(({parse:t})=>m()?a(u(l,c),l):t(i(l)))),g=r.useCallback(((t,e)=>U(t,{...p,...n,...e})),[U,n]),v=e();return r.useEffect((()=>{j(u(l,a(Object.fromEntries([...v.entries()]),l)))}),[v]),{setState:j,updateState:j,setUrl:g,updateUrl:g,urlState:d,state:d,getState:b}}const p={replace:!0,scroll:!1};export{l as useUrlState}; +import{useRouter as t,useSearchParams as e}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,m){const f="defaultState"in i?i.defaultState:i,n="defaultState"in i?i.searchParams:m?.searchParams,S="defaultState"in i?i.useHistory:m?.useHistory,d="defaultState"in i?{scroll:i.scroll,replace:i.replace}:{scroll:m?.scroll,replace:m?.replace},j=void 0===S||S?l:t(),{state:U,updateState:b,updateUrl:g,getState:P}=s(f,j,(({parse:t})=>o()?r(c(f,n),f):t(u(f)))),h=a.useCallback(((t,e)=>g(t,{...p,...d,...e})),[g,d]),v=e();return a.useEffect((()=>{b(c(f,r(Object.fromEntries([...v.entries()]),f)))}),[v]),{setState:b,updateState:b,setUrl:h,updateUrl:h,urlState:U,state:U,getState:P}}const p={replace:!0,scroll:!1};export{i as useUrlState}; diff --git a/dist/react-router/useUrlState/useUrlState.d.ts b/dist/react-router/useUrlState/useUrlState.d.ts index c05dd0c..3602062 100644 --- a/dist/react-router/useUrlState/useUrlState.d.ts +++ b/dist/react-router/useUrlState/useUrlState.d.ts @@ -1,15 +1,30 @@ import { type NavigateOptions } from "react-router-dom"; import { type JSONCompatible } from "../../utils"; +/** + * @deprecated . + * * use format `useUrlState(defaultState, { ...otherParams })` + * + * . + */ +export declare function useUrlState({ defaultState: T, searchParams, replace, useHistory, }: OldParams): { + state: T; + urlState: T; + updateState: (value: Partial | ((currState: T) => T)) => void; + setState: (value: Partial | ((currState: T) => T)) => void; + updateUrl: (value?: Partial | ((currState: T) => T)) => void; + setUrl: (value?: Partial | ((currState: T) => T)) => void; +}; /** * React-router hook. Returns `urlState`, `setState`, and `setUrl` functions * * @param {JSONCompatible} [defaultState] Fallback (default) values for state - * @param {NavigateOptions} [NavigateOptions] See type from `react-router-dom` - * @param {boolean} [useHistory] use window.history for navigation + * @param {Object} params - Object with other parameters + * @param {NavigateOptions} params.NavigateOptions See type from `react-router-dom` + * @param {boolean} params.useHistory use window.history for navigation * * Example: * ```ts * export const form = { name: '', age: 0 }; - * const { urlState, setState, setUrl } = useUrlState({ defaultState: form, replace: false, preventScrollReset: false }); + * const { urlState, setState, setUrl } = useUrlState(form, { replace: false, preventScrollReset: false }); * * setState({ name: 'test' }); * setUrl({ name: 'test' }, { replace: true }); @@ -19,51 +34,20 @@ import { type JSONCompatible } from "../../utils"; * * * Docs {@link https://github.com/asmyshlyaev177/state-in-url/tree/master/packages/urlstate/react-router/useUrlState#api} */ -export declare function useUrlState({ defaultState, useHistory, ...initOpts }: { - defaultState: T; - useHistory?: boolean; -} & NavigateOptions): { - /** - * * Example: - * ```ts - * setState({ name: 'test' }); - * // or - * setState(curr => ({ ...curr, name: 'test' }) ); - * // can pass optional React-Router `NavigateOptions` - * setState(curr => ({ ...curr, name: 'test', preventScrollReset: false }) ); - * ``` - * - * * Docs {@link https://github.com/asmyshlyaev177/state-in-url/tree/master/packages/urlstate/react-router/useUrlState#updatestate} - */ - setState: (value: Partial | ((currState: T) => T)) => void; - /** - * @deprecated use `setState` - */ - updateState: (value: Partial | ((currState: T) => T)) => void; - /** - * * Example: - * ```ts - * setUrl({ name: 'test' }); - * // or - * setUrl(curr => ({ ...curr, name: 'test' }), { replace: true } ); - * // can pass optional React-Router `NavigateOptions` - * setState(curr => ({ ...curr, name: 'test', preventScrollReset: false }) ); - * ``` - * - * * Docs {@link https://github.com/asmyshlyaev177/state-in-url/tree/master/packages/urlstate/react-router/useUrlState#updateurl} - */ - setUrl: (value?: Parameters<(value?: Partial | ((currState: T) => T) | undefined, options?: import("../../useUrlStateBase/useUrlStateBase").Options) => void>[0], options?: NavigateOptions) => void; - /** - * @deprecated use `setUrl` - */ - updateUrl: (value?: Parameters<(value?: Partial | ((currState: T) => T) | undefined, options?: import("../../useUrlStateBase/useUrlStateBase").Options) => void>[0], options?: NavigateOptions) => void; - /** - * State object. Don't mutate directly, use `setState` or `setUrl` - */ +export declare function useUrlState(defaultState: T, params?: Params): { urlState: T; - /** - * @deprecated use `urlState` - */ - state: T; - getState: () => T; + setState: (value: Partial | ((currState: T) => T)) => void; + setUrl: (value?: Partial | ((currState: T) => T)) => void; }; +type OldParams = { + defaultState: T; + useHistory?: boolean; + searchParams?: object; + replace?: boolean; +} & NavigateOptions; +interface Params extends NavigateOptions { + useHistory?: boolean; + searchParams?: object; + replace?: boolean; +} +export {}; diff --git a/dist/react-router/useUrlState/useUrlState.mjs b/dist/react-router/useUrlState/useUrlState.mjs index 984889f..7915dde 100644 --- a/dist/react-router/useUrlState/useUrlState.mjs +++ b/dist/react-router/useUrlState/useUrlState.mjs @@ -1 +1 @@ -import t from"react";import{useNavigate as e,useSearchParams as r}from"react-router-dom";import{parseSPObj as a}from"../../parseSPObj.mjs";import{useUrlStateBase as s}from"../../useUrlStateBase/useUrlStateBase.mjs";import{routerHistory as o,filterUnknownParamsClient as u,assignValue as m,filterUnknownParams as p}from"../../utils.mjs";function l({defaultState:l,useHistory:S,...f}){const i=e(),n=t.useMemo((()=>S?o:{replace:(t,e)=>i(t,{...c,...f,...e}),push:(t,e)=>i(t,{...c,...f,...e})}),[i,f]),{state:d,updateState:j,updateUrl:U,getState:b}=s(l,n,(({parse:t})=>t(u(l)))),g=t.useCallback(((t,e)=>U(t,{...c,...f,...e})),[f]),[B]=r();return t.useEffect((()=>{j(m(l,d,p(l,a(Object.fromEntries([...B.entries()]),l))))}),[B]),{setState:j,updateState:j,setUrl:g,updateUrl:g,urlState:d,state:d,getState:b}}const c={replace:!0,preventScrollReset:!0};export{l as useUrlState}; +import e from"react";import{useNavigate as t,useSearchParams as r}from"react-router-dom";import{parseSPObj as a}from"../../parseSPObj.mjs";import{useUrlStateBase as s}from"../../useUrlStateBase/useUrlStateBase.mjs";import{routerHistory as l,filterUnknownParamsClient as o,assignValue as p,filterUnknownParams as u}from"../../utils.mjs";function c(c,m){const n="defaultState"in c?c.defaultState:c,i="defaultState"in c?c.useHistory:m?.useHistory,f="defaultState"in c?{replace:c.replace,preventScrollReset:c.preventScrollReset}:{replace:m?.replace,preventScrollReset:m?.preventScrollReset},d=t(),j=e.useMemo((()=>i?l:{replace:(e,t)=>d(e,{...S,...f,...t}),push:(e,t)=>d(e,{...S,...f,...t})}),[d,f]),{state:v,updateState:R,updateUrl:U,getState:b}=s(n,j,(({parse:e})=>e(o(n)))),g=e.useCallback(((e,t)=>U(e,{...S,...f,...t})),[f]),[y]=r();return e.useEffect((()=>{R(p(n,u(n,a(Object.fromEntries([...y.entries()]),n))))}),[y]),{setState:R,updateState:R,setUrl:g,updateUrl:g,urlState:v,state:v,getState:b}}const S={replace:!0,preventScrollReset:!0};export{c as useUrlState}; diff --git a/dist/utils.d.ts b/dist/utils.d.ts index 7bc3d22..a22e8f2 100644 --- a/dist/utils.d.ts +++ b/dist/utils.d.ts @@ -22,7 +22,7 @@ export type UnknownObj = object | { export declare const isEqual: (val1: unknown, val2: unknown) => boolean; export declare function filterUnknownParamsClient(shape: T): string; export declare function filterUnknownParams(shape: T, searchParams?: object): T; -export declare function assignValue(shape: T, curr: Partial, newVal: Partial): T; +export declare function assignValue(shape: T, newVal: Partial): T; export interface Router { push: (href: string, opts: object) => void; replace: (href: string, opts: object) => void; diff --git a/dist/utils.mjs b/dist/utils.mjs index 904f4f8..3601ff1 100644 --- a/dist/utils.mjs +++ b/dist/utils.mjs @@ -1 +1 @@ -const t=t=>{const n=typeof t,e=null===t,r=Array.isArray(t),o=t instanceof Date;return(e?"null":o&&"date")||r&&"array"||!e&&!o&&!r&&"object"===n&&"object"||n},n=()=>"undefined"==typeof window,e=t=>new URLSearchParams("string"==typeof t?r(t):t?.toString?.()||""),r=t=>t.split("?")?.[1]||t||"",o=(t,n)=>JSON.stringify(t)===JSON.stringify(n);function i(t){const n=new URLSearchParams;return s(t,[...new URLSearchParams(window.location.search).entries()]).forEach((([t,e])=>n.set(t,e))),n.toString()}function c(t,n){return Object.fromEntries(s(t,Object.entries(n||{})))}function s(t,n){const e=Object.keys(t);return n.filter((([t])=>e.includes(t))).map((([t,n])=>[t.replaceAll("+"," "),n]))}function a(t,n,e){const r=Object.assign({},t,n);return Object.entries(t).forEach((([n])=>{const o=n,i=void 0!==e[o];r[o]=i?e[o]:t[o]})),r}const l={push:t=>{window&&window.history.pushState(null,"",t)},replace:t=>{window&&window.history.replaceState(null,"",t)}};export{a as assignValue,c as filterUnknownParams,i as filterUnknownParamsClient,e as getParams,o as isEqual,n as isSSR,l as routerHistory,t as typeOf}; +const t=t=>{const n=typeof t,e=null===t,r=Array.isArray(t),o=t instanceof Date;return(e?"null":o&&"date")||r&&"array"||!e&&!o&&!r&&"object"===n&&"object"||n},n=()=>"undefined"==typeof window,e=t=>new URLSearchParams("string"==typeof t?r(t):t?.toString?.()||""),r=t=>t.split("?")?.[1]||t||"",o=(t,n)=>JSON.stringify(t)===JSON.stringify(n);function i(t){const n=new URLSearchParams;return s(t,[...new URLSearchParams(window.location.search).entries()]).forEach((([t,e])=>n.set(t,e))),n.toString()}function c(t,n){return Object.fromEntries(s(t,Object.entries(n||{})))}function s(t,n){const e=Object.keys(t);return n.filter((([t])=>e.includes(t))).map((([t,n])=>[t.replaceAll("+"," "),n]))}function a(t,n){const e=Object.assign({},t);return Object.entries(t).forEach((([r])=>{const o=r,i=void 0!==n[o];e[o]=i?n[o]:t[o]})),e}const l={push:t=>{window&&window.history.pushState(null,"",t)},replace:t=>{window&&window.history.replaceState(null,"",t)}};export{a as assignValue,c as filterUnknownParams,i as filterUnknownParamsClient,e as getParams,o as isEqual,n as isSSR,l as routerHistory,t as typeOf}; diff --git a/package.json b/package.json index be3fb0c..e11561a 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "state-in-url", - "version": "4.0.5", + "version": "4.0.6", "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.", "homepage": "https://state-in-url.dev", "repository": {