react-magic-search-params 2.1.2 → 2.2.3

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 CHANGED
@@ -54,6 +54,18 @@ updateParams({ newParams: { tags: 'react' } });
54
54
  clearParams({ keepMandatoryParams: true });
55
55
  ```
56
56
 
57
+ If you have ambiguous optional unions (for example `boolean | ''`), use `coerceParams`:
58
+
59
+ ```tsx
60
+ const { getParams } = useMagicSearchParams({
61
+ mandatory: { page: 1, page_size: 50 },
62
+ optional: { only_unmapped: '' as boolean | '' },
63
+ coerceParams: { only_unmapped: 'boolean' },
64
+ });
65
+
66
+ const { only_unmapped } = getParams({ convert: true });
67
+ ```
68
+
57
69
  ## API
58
70
 
59
71
  - `getParams({ convert?: boolean })`
package/dist/index.cjs CHANGED
@@ -1 +1 @@
1
- "use strict";var V=Object.defineProperty;var ie=Object.getOwnPropertyDescriptor;var ue=Object.getOwnPropertyNames;var me=Object.prototype.hasOwnProperty;var Pe=(m,d)=>{for(var g in d)V(m,g,{get:d[g],enumerable:!0})},le=(m,d,g,p)=>{if(d&&typeof d=="object"||typeof d=="function")for(let y of ue(d))!me.call(m,y)&&y!==g&&V(m,y,{get:()=>d[y],enumerable:!(p=ie(d,y))||p.enumerable});return m};var pe=m=>le(V({},"__esModule",{value:!0}),m);var ge={};Pe(ge,{useMagicSearchParams:()=>Y});module.exports=pe(ge);var Q=require("react-router-dom"),P=require("react"),Y=({mandatory:m={},optional:d={},defaultParams:g={},arraySerialization:p="csv",forceParams:y={},omitParamsByValues:q=[],codecs:F={},historyMode:E="push",resetOnChange:G={},paginationStrategy:w,unknownParamsPolicy:A="drop"})=>{let[i,L]=(0,Q.useSearchParams)(),j=(0,P.useRef)({}),U=(0,P.useRef)({}),I=(0,P.useCallback)((e,r)=>{L(e,{replace:(r??E)==="replace"})},[L,E]),l=(0,P.useMemo)(()=>({...m,...d}),[m,d]),J=(0,P.useMemo)(()=>Array.from(Object.keys(l)),[l]),v=(0,P.useCallback)(e=>Object.prototype.hasOwnProperty.call(l,e),[l]),X=e=>!Array.isArray(l[e])||p==="csv"?i.get(e):p==="repeat"?i.getAll(e):i.getAll(`${e}[]`),B=(0,P.useCallback)(()=>{if(A==="drop")return[];let e=[];for(let[r,a]of i.entries()){let s=r.endsWith("[]")?r.replace("[]",""):r;v(s)||e.push([r,a])}return e},[A,i,v]),H=(0,P.useCallback)(e=>{if(A==="drop")return e;let r=new URLSearchParams(e.toString()),a=B();for(let[s,t]of a)r.append(s,t);return r},[A,B]),_=(e,r)=>Array.isArray(e)&&Array.isArray(r)?e.length!==r.length?!1:e.every((a,s)=>a===r[s]):e===r,C=(0,P.useMemo)(()=>Object.keys(l).filter(e=>Array.isArray(l[e])),[l]),Z=(e,r)=>{let a={...e};return C.length===0||C.forEach(s=>{let t=[];switch(p){case"csv":{t=(i.get(s)||"").split(",").map(o=>o.trim()).filter(Boolean);break}case"repeat":{let n=i.getAll(s);t=n.length>0?n:[];break}case"brackets":{let n=i.getAll(`${s}[]`);t=n.length>0?n:[];break}default:t=(i.get(s)??"").split(",").map(o=>o.trim()).filter(Boolean)}if(r[s]!==void 0){let n=r[s],o=[];typeof n=="string"?o=t.includes(n)?t.filter(u=>u!==n):[...t,n]:Array.isArray(n)?o=Array.from(new Set([...n.map(String)])):o=t,a[s]=o}}),a},O=e=>{let r=new URLSearchParams,a=Object.keys(e);for(let s of a){let t=F[s];if(t?.serialize){let n=t.serialize(e[s],{key:s});if(n==null)continue;if(Array.isArray(n))if(Array.isArray(l[s]))if(p==="csv")r.set(s,n.join(","));else if(p==="repeat")for(let o of n)r.append(s,String(o));else for(let o of n)r.append(`${s}[]`,String(o));else n.length>0&&r.set(s,String(n[0]));else r.set(s,String(n));continue}if(Array.isArray(l[s])){let n=e[s];switch(p){case"csv":{r.set(s,n.join(","));break}case"repeat":{for(let o of n)r.append(s,String(o));break}case"brackets":{for(let o of n)r.append(`${s}[]`,String(o));break}default:r.set(s,n.join(","))}}else r.set(s,String(e[s]))}return r},h=(e,r)=>Object.prototype.hasOwnProperty.call(m,e)?m[e]:Object.prototype.hasOwnProperty.call(g,e)?g[e]:r,W=({paramsForced:e,compareParams:r})=>Object.entries(e).every(([s,t])=>r[s]===t),x=e=>{let r=X(e),a=F[e];if(a?.parse)return a.parse(r,{key:e,searchParams:i});if(typeof l[e]=="number"){let s=Number.parseInt(String(r??""),10);if(Number.isNaN(s)){let t=h(e,0);return typeof t=="number"?t:0}return s}return typeof l[e]=="boolean"?String(r)==="true":Array.isArray(l[e])?p==="csv"?String(r??"").split(",").filter(Boolean):Array.isArray(r)?r:r?[r]:[]:Array.isArray(r)?r[0]??"":r??""},$=(e,r)=>{if(Array.isArray(l[e])){if(p==="brackets"){let t=i.getAll(`${e}[]`),n=O({[e]:t}).toString();return decodeURIComponent(n)}if(p==="csv"){let t=i.getAll(e),n=O({[e]:t}).toString();return decodeURIComponent(n)}let s=i.getAll(e);return O({[e]:s}).toString()}return r[e]},z=e=>{let r={};for(let[a,s]of e.entries())if(a.endsWith("[]")){let t=a.replace("[]","");r[t]?r[t].push(s):r[t]=[s]}else r[a]?Array.isArray(r[a])?r[a].push(s):r[a]=[r[a],s]:r[a]=s;return r},S=(0,P.useMemo)(()=>p==="brackets"?z(i):Object.fromEntries(i.entries()),[i,p]),M=({convert:e=!0}={})=>Object.keys(S).reduce((a,s)=>{if(Object.prototype.hasOwnProperty.call(l,s)){let t=p==="brackets"?s.replace("[]",""):s;a[t]=e===!0?x(t):$(s,S)}return a},{}),K=(e,r)=>{let a=String(e);return r?.convert!==!1?x(a):$(a,S)},ee=e=>e==null||typeof e!="object"?!1:Object.prototype.hasOwnProperty.call(e,"newParams")||Object.prototype.hasOwnProperty.call(e,"keepParams")||Object.prototype.hasOwnProperty.call(e,"historyMode"),re=e=>{let r=M({convert:!0});if(typeof e=="function"){let a=e(r);return ee(a)?{newParams:typeof a.newParams=="function"?a.newParams(r):a.newParams??{},keepParams:a.keepParams??{},historyMode:a.historyMode}:{newParams:a,keepParams:{},historyMode:void 0}}return e?{newParams:typeof e.newParams=="function"?e.newParams(r):e.newParams??{},keepParams:e.keepParams??{},historyMode:e.historyMode}:{newParams:{},keepParams:{},historyMode:void 0}},se=({currentParams:e,newParams:r,keepParams:a})=>{let s={...r},t={...a};for(let[n,o]of Object.entries(G))if(!(!o||o.length===0||!Object.prototype.hasOwnProperty.call(s,n)||_(s[n],e[n]))){for(let c of o)if(!Object.prototype.hasOwnProperty.call(y,c)){if(Object.prototype.hasOwnProperty.call(m,c)){s[c]=m[c],delete t[c];continue}if(Object.prototype.hasOwnProperty.call(g,c)){s[c]=g[c],delete t[c];continue}delete s[c],t[c]=!1}}return{newParams:s,keepParams:t}},ae=(e,r)=>{let a=M(),s=Object.entries(e).filter(([o])=>!Array.isArray(l[o])),t=Object.assign({...a,...Object.fromEntries(s)},y),n=Object.keys(t).reduce((o,u)=>{if(Object.prototype.hasOwnProperty.call(r,u)&&r[u]===!1)return o;let c=t[u],b=typeof c=="string"&&q.includes(c);return c!=null&&c!==""&&!b&&(o[u]=c),o},{});return{...m,...n}},te=e=>J.reduce((a,s)=>(Object.prototype.hasOwnProperty.call(e,s)&&(a[s]=e[s]),a),{}),ne=()=>{let e=C.length>0,r=M({convert:e});return Object.keys(r).reduce((s,t)=>(Object.prototype.hasOwnProperty.call(m,t)&&(s[t]=r[t]),s),{})},D=({keepMandatoryParams:e=!0,historyMode:r}={})=>{let a=O({...m,...e&&{...ne()},...y}),s=H(a);I(s,r)},f=e=>{let r=re(e),a=M({convert:!0}),s=se({currentParams:a,newParams:r.newParams,keepParams:r.keepParams}),t=s.newParams,n=s.keepParams;if(Object.keys(t).length===0&&Object.keys(n).length===0){D({historyMode:r.historyMode});return}let o=ae(t,n),u=Z(o,t),c=te(u),b=O(c),T=H(b);I(T,r.historyMode)},k=w?.mode==="page"?w:void 0,R=w?.mode==="offset"?w:void 0,N=w?.mode==="cursor"?w:void 0,oe={mode:w?.mode??"page",next:e=>{let r=w?.mode??"page";if(r==="cursor"){let n=N?.cursorKey??"cursor";typeof e=="string"&&f({newParams:{[n]:e}});return}if(r==="offset"){let n=R?.offsetKey??"offset",o=R?.limitKey??"limit",u=Number(K(n,{convert:!0})??0),c=Number(K(o,{convert:!0})??h(String(o),10)),b=Number.isFinite(u)?u:0,T=Number.isFinite(c)&&c>0?c:10;f({newParams:{[n]:b+T}});return}let a=k?k.pageKey??"page":"page",s=Number(K(a,{convert:!0})??h(String(a),1)),t=Number.isFinite(s)&&s>0?s:1;f({newParams:{[a]:t+1}})},prev:()=>{let e=w?.mode??"page";if(e==="cursor"){let t=N?.cursorKey??"cursor";f({keepParams:{[t]:!1}});return}if(e==="offset"){let t=R?.offsetKey??"offset",n=R?.limitKey??"limit",o=Number(K(t,{convert:!0})??0),u=Number(K(n,{convert:!0})??h(String(n),10)),c=Number.isFinite(o)?o:0,b=Number.isFinite(u)&&u>0?u:10;f({newParams:{[t]:Math.max(0,c-b)}});return}let r=k?k.pageKey??"page":"page",a=Number(K(r,{convert:!0})??h(String(r),1)),s=Number.isFinite(a)&&a>0?a:1;f({newParams:{[r]:Math.max(1,s-1)}})},reset:()=>{let e=w?.mode??"page";if(e==="cursor"){let s=N?.cursorKey??"cursor";f({keepParams:{[s]:!1}});return}if(e==="offset"){let s=R?.offsetKey??"offset",t=Number(h(String(s),0));f({newParams:{[s]:Number.isFinite(t)?t:0}});return}let r=k?k.pageKey??"page":"page",a=Number(h(String(r),1));f({newParams:{[r]:Number.isFinite(a)&&a>0?a:1}})},setCursor:e=>{let a=(w?.mode??"page")==="cursor"?N?.cursorKey??"cursor":"cursor";if(e==null||e===""){f({keepParams:{[a]:!1}});return}f({newParams:{[a]:e}})}},ce=(0,P.useCallback)((e,r)=>{let a=String(e);return j.current[a]=r,()=>{delete j.current[a],delete U.current[a]}},[]);return(0,P.useEffect)(()=>{for(let[e,r]of Object.entries(j.current)){let a=v(e)?x(e):i.get(e),s=U.current[e]??null;if(!_(a,s))for(let t of r)t({key:e,previousValue:s,currentValue:a});U.current[e]=a}},[S,v,i]),(0,P.useEffect)(()=>{let e=Object.keys(g),r=Object.keys(y);if(e.length===0&&r.length===0)return;function a(){let s=O(g).toString(),t=M(),n=O(t).toString();if(!W({paramsForced:y,compareParams:t})){f({newParams:{...g,...y}});return}let u=W({paramsForced:y,compareParams:g});if(e.length>0&&u){if(s===n)return;f({newParams:g})}}a()},[]),{searchParams:i,updateParams:f,clearParams:D,getParams:M,getParam:K,onChange:ce,pagination:oe}};0&&(module.exports={useMagicSearchParams});
1
+ "use strict";var V=Object.defineProperty;var ue=Object.getOwnPropertyDescriptor;var Pe=Object.getOwnPropertyNames;var pe=Object.prototype.hasOwnProperty;var fe=(u,d)=>{for(var l in d)V(u,l,{get:d[l],enumerable:!0})},le=(u,d,l,p)=>{if(d&&typeof d=="object"||typeof d=="function")for(let y of Pe(d))!pe.call(u,y)&&y!==l&&V(u,y,{get:()=>d[y],enumerable:!(p=ue(d,y))||p.enumerable});return u};var ge=u=>le(V({},"__esModule",{value:!0}),u);var ye={};fe(ye,{useMagicSearchParams:()=>G});module.exports=ge(ye);var q=require("react-router-dom"),P=require("react"),G=({mandatory:u={},optional:d={},defaultParams:l={},arraySerialization:p="csv",forceParams:y={},omitParamsByValues:J=[],coerceParams:F={},codecs:E={},historyMode:L="push",resetOnChange:X={},paginationStrategy:w,unknownParamsPolicy:A="drop"})=>{let[i,I]=(0,q.useSearchParams)(),T=(0,P.useRef)({}),j=(0,P.useRef)({}),B=(0,P.useCallback)((r,e)=>{I(r,{replace:(e??L)==="replace"})},[I,L]),f=(0,P.useMemo)(()=>({...u,...d}),[u,d]),Z=(0,P.useMemo)(()=>Array.from(Object.keys(f)),[f]),N=(0,P.useCallback)(r=>Object.prototype.hasOwnProperty.call(f,r),[f]),z=r=>!Array.isArray(f[r])||p==="csv"?i.get(r):p==="repeat"?i.getAll(r):i.getAll(`${r}[]`),H=(0,P.useCallback)(()=>{if(A==="drop")return[];let r=[];for(let[e,a]of i.entries()){let s=e.endsWith("[]")?e.replace("[]",""):e;N(s)||r.push([e,a])}return r},[A,i,N]),_=(0,P.useCallback)(r=>{if(A==="drop")return r;let e=new URLSearchParams(r.toString()),a=H();for(let[s,t]of a)e.append(s,t);return e},[A,H]),W=(r,e)=>Array.isArray(r)&&Array.isArray(e)?r.length!==e.length?!1:r.every((a,s)=>a===e[s]):r===e,x=(0,P.useMemo)(()=>Object.keys(f).filter(r=>Array.isArray(f[r])),[f]),ee=(r,e)=>{let a={...r};return x.length===0||x.forEach(s=>{let t=[];switch(p){case"csv":{t=(i.get(s)||"").split(",").map(o=>o.trim()).filter(Boolean);break}case"repeat":{let n=i.getAll(s);t=n.length>0?n:[];break}case"brackets":{let n=i.getAll(`${s}[]`);t=n.length>0?n:[];break}default:t=(i.get(s)??"").split(",").map(o=>o.trim()).filter(Boolean)}if(e[s]!==void 0){let n=e[s],o=[];typeof n=="string"?o=t.includes(n)?t.filter(m=>m!==n):[...t,n]:Array.isArray(n)?o=Array.from(new Set([...n.map(String)])):o=t,a[s]=o}}),a},b=r=>{let e=new URLSearchParams,a=Object.keys(r);for(let s of a){let t=E[s];if(t?.serialize){let n=t.serialize(r[s],{key:s});if(n==null)continue;if(Array.isArray(n))if(Array.isArray(f[s]))if(p==="csv")e.set(s,n.join(","));else if(p==="repeat")for(let o of n)e.append(s,String(o));else for(let o of n)e.append(`${s}[]`,String(o));else n.length>0&&e.set(s,String(n[0]));else e.set(s,String(n));continue}if(Array.isArray(f[s])){let n=r[s];switch(p){case"csv":{e.set(s,n.join(","));break}case"repeat":{for(let o of n)e.append(s,String(o));break}case"brackets":{for(let o of n)e.append(`${s}[]`,String(o));break}default:e.set(s,n.join(","))}}else e.set(s,String(r[s]))}return e},O=(r,e)=>Object.prototype.hasOwnProperty.call(u,r)?u[r]:Object.prototype.hasOwnProperty.call(l,r)?l[r]:e,$=({paramsForced:r,compareParams:e})=>Object.entries(r).every(([s,t])=>e[s]===t),U=r=>{let e=z(r),a=E[r];if(a?.parse)return a.parse(e,{key:r,searchParams:i});let s=F[r];if(s==="number"){let t=Number.parseInt(String(e??""),10);if(Number.isNaN(t)){let n=O(r,0);return typeof n=="number"?n:0}return t}if(s==="boolean")return String(e)==="true";if(s==="array")return p==="csv"?String(e??"").split(",").filter(Boolean):Array.isArray(e)?e:e?[e]:[];if(s==="string")return Array.isArray(e)?e[0]??"":e??"";if(typeof f[r]=="number"){let t=Number.parseInt(String(e??""),10);if(Number.isNaN(t)){let n=O(r,0);return typeof n=="number"?n:0}return t}return typeof f[r]=="boolean"?String(e)==="true":Array.isArray(f[r])?p==="csv"?String(e??"").split(",").filter(Boolean):Array.isArray(e)?e:e?[e]:[]:Array.isArray(e)?e[0]??"":e??""},D=(r,e)=>{let a=F[r];if(!a)return e;if(a==="boolean")return typeof e=="boolean"?e:String(e??"")==="true";if(a==="number"){if(typeof e=="number"&&Number.isFinite(e))return e;let s=Number.parseInt(String(e??""),10);if(Number.isNaN(s)){let t=O(r,0);return typeof t=="number"?t:0}return s}return a==="array"?Array.isArray(e)?e:e==null||e===""?[]:[String(e)]:a==="string"?Array.isArray(e)?e[0]??"":e==null?"":String(e):e},Q=(r,e)=>{if(Array.isArray(f[r])){if(p==="brackets"){let t=i.getAll(`${r}[]`),n=b({[r]:t}).toString();return decodeURIComponent(n)}if(p==="csv"){let t=i.getAll(r),n=b({[r]:t}).toString();return decodeURIComponent(n)}let s=i.getAll(r);return b({[r]:s}).toString()}return e[r]},re=r=>{let e={};for(let[a,s]of r.entries())if(a.endsWith("[]")){let t=a.replace("[]","");e[t]?e[t].push(s):e[t]=[s]}else e[a]?Array.isArray(e[a])?e[a].push(s):e[a]=[e[a],s]:e[a]=s;return e},S=(0,P.useMemo)(()=>p==="brackets"?re(i):Object.fromEntries(i.entries()),[i,p]),M=({convert:r=!0}={})=>Object.keys(S).reduce((a,s)=>{if(Object.prototype.hasOwnProperty.call(f,s)){let t=p==="brackets"?s.replace("[]",""):s;if(r===!0){let n=U(t);a[t]=D(t,n)}else a[t]=Q(s,S)}return a},{}),K=(r,e)=>{let a=String(r);return e?.convert!==!1?D(a,U(a)):Q(a,S)},se=r=>r==null||typeof r!="object"?!1:Object.prototype.hasOwnProperty.call(r,"newParams")||Object.prototype.hasOwnProperty.call(r,"keepParams")||Object.prototype.hasOwnProperty.call(r,"historyMode"),ae=r=>{let e=M({convert:!0});if(typeof r=="function"){let a=r(e);return se(a)?{newParams:typeof a.newParams=="function"?a.newParams(e):a.newParams??{},keepParams:a.keepParams??{},historyMode:a.historyMode}:{newParams:a,keepParams:{},historyMode:void 0}}return r?{newParams:typeof r.newParams=="function"?r.newParams(e):r.newParams??{},keepParams:r.keepParams??{},historyMode:r.historyMode}:{newParams:{},keepParams:{},historyMode:void 0}},te=({currentParams:r,newParams:e,keepParams:a})=>{let s={...e},t={...a};for(let[n,o]of Object.entries(X))if(!(!o||o.length===0||!Object.prototype.hasOwnProperty.call(s,n)||W(s[n],r[n]))){for(let c of o)if(!Object.prototype.hasOwnProperty.call(y,c)){if(Object.prototype.hasOwnProperty.call(u,c)){s[c]=u[c],delete t[c];continue}if(Object.prototype.hasOwnProperty.call(l,c)){s[c]=l[c],delete t[c];continue}delete s[c],t[c]=!1}}return{newParams:s,keepParams:t}},ne=(r,e)=>{let a=M(),s=Object.entries(r).filter(([o])=>!Array.isArray(f[o])),t=Object.assign({...a,...Object.fromEntries(s)},y),n=Object.keys(t).reduce((o,m)=>{if(Object.prototype.hasOwnProperty.call(e,m)&&e[m]===!1)return o;let c=t[m],h=typeof c=="string"&&J.includes(c);return c!=null&&c!==""&&!h&&(o[m]=c),o},{});return{...u,...n}},oe=r=>Z.reduce((a,s)=>(Object.prototype.hasOwnProperty.call(r,s)&&(a[s]=r[s]),a),{}),ce=()=>{let r=x.length>0,e=M({convert:r});return Object.keys(e).reduce((s,t)=>(Object.prototype.hasOwnProperty.call(u,t)&&(s[t]=e[t]),s),{})},Y=({keepMandatoryParams:r=!0,historyMode:e}={})=>{let a=b({...u,...r&&{...ce()},...y}),s=_(a);B(s,e)},g=r=>{let e=ae(r),a=M({convert:!0}),s=te({currentParams:a,newParams:e.newParams,keepParams:e.keepParams}),t=s.newParams,n=s.keepParams;if(Object.keys(t).length===0&&Object.keys(n).length===0){Y({historyMode:e.historyMode});return}let o=ne(t,n),m=ee(o,t),c=oe(m),h=b(c),v=_(h);B(v,e.historyMode)},k=w?.mode==="page"?w:void 0,R=w?.mode==="offset"?w:void 0,C=w?.mode==="cursor"?w:void 0,ie={mode:w?.mode??"page",next:r=>{let e=w?.mode??"page";if(e==="cursor"){let n=C?.cursorKey??"cursor";typeof r=="string"&&g({newParams:{[n]:r}});return}if(e==="offset"){let n=R?.offsetKey??"offset",o=R?.limitKey??"limit",m=Number(K(n,{convert:!0})??0),c=Number(K(o,{convert:!0})??O(String(o),10)),h=Number.isFinite(m)?m:0,v=Number.isFinite(c)&&c>0?c:10;g({newParams:{[n]:h+v}});return}let a=k?k.pageKey??"page":"page",s=Number(K(a,{convert:!0})??O(String(a),1)),t=Number.isFinite(s)&&s>0?s:1;g({newParams:{[a]:t+1}})},prev:()=>{let r=w?.mode??"page";if(r==="cursor"){let t=C?.cursorKey??"cursor";g({keepParams:{[t]:!1}});return}if(r==="offset"){let t=R?.offsetKey??"offset",n=R?.limitKey??"limit",o=Number(K(t,{convert:!0})??0),m=Number(K(n,{convert:!0})??O(String(n),10)),c=Number.isFinite(o)?o:0,h=Number.isFinite(m)&&m>0?m:10;g({newParams:{[t]:Math.max(0,c-h)}});return}let e=k?k.pageKey??"page":"page",a=Number(K(e,{convert:!0})??O(String(e),1)),s=Number.isFinite(a)&&a>0?a:1;g({newParams:{[e]:Math.max(1,s-1)}})},reset:()=>{let r=w?.mode??"page";if(r==="cursor"){let s=C?.cursorKey??"cursor";g({keepParams:{[s]:!1}});return}if(r==="offset"){let s=R?.offsetKey??"offset",t=Number(O(String(s),0));g({newParams:{[s]:Number.isFinite(t)?t:0}});return}let e=k?k.pageKey??"page":"page",a=Number(O(String(e),1));g({newParams:{[e]:Number.isFinite(a)&&a>0?a:1}})},setCursor:r=>{let a=(w?.mode??"page")==="cursor"?C?.cursorKey??"cursor":"cursor";if(r==null||r===""){g({keepParams:{[a]:!1}});return}g({newParams:{[a]:r}})}},me=(0,P.useCallback)((r,e)=>{let a=String(r);return T.current[a]=e,()=>{delete T.current[a],delete j.current[a]}},[]);return(0,P.useEffect)(()=>{for(let[r,e]of Object.entries(T.current)){let a=N(r)?U(r):i.get(r),s=j.current[r]??null;if(!W(a,s))for(let t of e)t({key:r,previousValue:s,currentValue:a});j.current[r]=a}},[S,N,i]),(0,P.useEffect)(()=>{let r=Object.keys(l),e=Object.keys(y);if(r.length===0&&e.length===0)return;function a(){let s=b(l).toString(),t=M(),n=b(t).toString();if(!$({paramsForced:y,compareParams:t})){g({newParams:{...l,...y}});return}let m=$({paramsForced:y,compareParams:l});if(r.length>0&&m){if(s===n)return;g({newParams:l})}}a()},[]),{searchParams:i,updateParams:g,clearParams:Y,getParams:M,getParam:K,onChange:me,pagination:ie}};0&&(module.exports={useMagicSearchParams});
package/dist/index.d.mts CHANGED
@@ -20,6 +20,8 @@ type ParamCodecs<TParams extends Record<string, unknown>> = Partial<{
20
20
  [K in keyof TParams]: ParamCodec<TParams[K]>;
21
21
  }>;
22
22
  type ParamKey<TParams extends Record<string, unknown>> = Extract<keyof TParams, string>;
23
+ type CoerceParamType = 'string' | 'number' | 'boolean' | 'array';
24
+ type CoerceParams<TParams extends Record<string, unknown>> = Partial<Record<ParamKey<TParams>, CoerceParamType>>;
23
25
  type PaginationStrategy<TParams extends Record<string, unknown>> = {
24
26
  mode: 'page';
25
27
  pageKey?: ParamKey<TParams>;
@@ -53,6 +55,7 @@ interface UseMagicSearchParamsOptions<M extends Record<string, unknown>, O exten
53
55
  forceParams?: Partial<MergeParams<M, O>>;
54
56
  arraySerialization?: 'csv' | 'repeat' | 'brackets';
55
57
  omitParamsByValues?: Array<OmitParamValue>;
58
+ coerceParams?: CoerceParams<MergeParams<M, O>>;
56
59
  codecs?: ParamCodecs<MergeParams<M, O>>;
57
60
  historyMode?: HistoryMode;
58
61
  resetOnChange?: ResetOnChangeRules<MergeParams<M, O>>;
@@ -67,7 +70,7 @@ Generic hook to handle search parameters in the URL
67
70
  @param forceParams - Parameters forced into the URL regardless of user input
68
71
  @param omitParamsByValues - Parameters omitted if they have specific values
69
72
  */
70
- declare const useMagicSearchParams: <M extends Record<string, unknown> & CommonParams, O extends Record<string, unknown>>({ mandatory, optional, defaultParams, arraySerialization, forceParams, omitParamsByValues, codecs, historyMode, resetOnChange, paginationStrategy, unknownParamsPolicy }: UseMagicSearchParamsOptions<M, O>) => {
73
+ declare const useMagicSearchParams: <M extends Record<string, unknown> & CommonParams, O extends Record<string, unknown>>({ mandatory, optional, defaultParams, arraySerialization, forceParams, omitParamsByValues, coerceParams, codecs, historyMode, resetOnChange, paginationStrategy, unknownParamsPolicy }: UseMagicSearchParamsOptions<M, O>) => {
71
74
  searchParams: URLSearchParams;
72
75
  updateParams: (input?: {
73
76
  newParams?: Partial<MergeParams<M, O>> | ((current: MergeParams<M, O>) => Partial<MergeParams<M, O>>);
@@ -98,4 +101,4 @@ declare const useMagicSearchParams: <M extends Record<string, unknown> & CommonP
98
101
  };
99
102
  };
100
103
 
101
- export { type BuiltInOmitParamValue, type HistoryMode, type OmitParamValue, type OnChangeEvent, type PaginationStrategy, type ParamCodec, type ResetOnChangeRules, type UnknownParamsPolicy, type UseMagicSearchParamsOptions, useMagicSearchParams };
104
+ export { type BuiltInOmitParamValue, type CoerceParamType, type CoerceParams, type HistoryMode, type OmitParamValue, type OnChangeEvent, type PaginationStrategy, type ParamCodec, type ResetOnChangeRules, type UnknownParamsPolicy, type UseMagicSearchParamsOptions, useMagicSearchParams };
package/dist/index.d.ts CHANGED
@@ -20,6 +20,8 @@ type ParamCodecs<TParams extends Record<string, unknown>> = Partial<{
20
20
  [K in keyof TParams]: ParamCodec<TParams[K]>;
21
21
  }>;
22
22
  type ParamKey<TParams extends Record<string, unknown>> = Extract<keyof TParams, string>;
23
+ type CoerceParamType = 'string' | 'number' | 'boolean' | 'array';
24
+ type CoerceParams<TParams extends Record<string, unknown>> = Partial<Record<ParamKey<TParams>, CoerceParamType>>;
23
25
  type PaginationStrategy<TParams extends Record<string, unknown>> = {
24
26
  mode: 'page';
25
27
  pageKey?: ParamKey<TParams>;
@@ -53,6 +55,7 @@ interface UseMagicSearchParamsOptions<M extends Record<string, unknown>, O exten
53
55
  forceParams?: Partial<MergeParams<M, O>>;
54
56
  arraySerialization?: 'csv' | 'repeat' | 'brackets';
55
57
  omitParamsByValues?: Array<OmitParamValue>;
58
+ coerceParams?: CoerceParams<MergeParams<M, O>>;
56
59
  codecs?: ParamCodecs<MergeParams<M, O>>;
57
60
  historyMode?: HistoryMode;
58
61
  resetOnChange?: ResetOnChangeRules<MergeParams<M, O>>;
@@ -67,7 +70,7 @@ Generic hook to handle search parameters in the URL
67
70
  @param forceParams - Parameters forced into the URL regardless of user input
68
71
  @param omitParamsByValues - Parameters omitted if they have specific values
69
72
  */
70
- declare const useMagicSearchParams: <M extends Record<string, unknown> & CommonParams, O extends Record<string, unknown>>({ mandatory, optional, defaultParams, arraySerialization, forceParams, omitParamsByValues, codecs, historyMode, resetOnChange, paginationStrategy, unknownParamsPolicy }: UseMagicSearchParamsOptions<M, O>) => {
73
+ declare const useMagicSearchParams: <M extends Record<string, unknown> & CommonParams, O extends Record<string, unknown>>({ mandatory, optional, defaultParams, arraySerialization, forceParams, omitParamsByValues, coerceParams, codecs, historyMode, resetOnChange, paginationStrategy, unknownParamsPolicy }: UseMagicSearchParamsOptions<M, O>) => {
71
74
  searchParams: URLSearchParams;
72
75
  updateParams: (input?: {
73
76
  newParams?: Partial<MergeParams<M, O>> | ((current: MergeParams<M, O>) => Partial<MergeParams<M, O>>);
@@ -98,4 +101,4 @@ declare const useMagicSearchParams: <M extends Record<string, unknown> & CommonP
98
101
  };
99
102
  };
100
103
 
101
- export { type BuiltInOmitParamValue, type HistoryMode, type OmitParamValue, type OnChangeEvent, type PaginationStrategy, type ParamCodec, type ResetOnChangeRules, type UnknownParamsPolicy, type UseMagicSearchParamsOptions, useMagicSearchParams };
104
+ export { type BuiltInOmitParamValue, type CoerceParamType, type CoerceParams, type HistoryMode, type OmitParamValue, type OnChangeEvent, type PaginationStrategy, type ParamCodec, type ResetOnChangeRules, type UnknownParamsPolicy, type UseMagicSearchParamsOptions, useMagicSearchParams };
package/dist/index.js CHANGED
@@ -1 +1 @@
1
- import{useSearchParams as ie}from"react-router-dom";import{useMemo as N,useEffect as Q,useRef as Y,useCallback as k}from"react";var ue=({mandatory:g={},optional:V={},defaultParams:f={},arraySerialization:l="csv",forceParams:y={},omitParamsByValues:q=[],codecs:F={},historyMode:E="push",resetOnChange:G={},paginationStrategy:p,unknownParamsPolicy:R="drop"})=>{let[i,L]=ie(),j=Y({}),U=Y({}),I=k((e,r)=>{L(e,{replace:(r??E)==="replace"})},[L,E]),m=N(()=>({...g,...V}),[g,V]),J=N(()=>Array.from(Object.keys(m)),[m]),A=k(e=>Object.prototype.hasOwnProperty.call(m,e),[m]),X=e=>!Array.isArray(m[e])||l==="csv"?i.get(e):l==="repeat"?i.getAll(e):i.getAll(`${e}[]`),B=k(()=>{if(R==="drop")return[];let e=[];for(let[r,a]of i.entries()){let s=r.endsWith("[]")?r.replace("[]",""):r;A(s)||e.push([r,a])}return e},[R,i,A]),H=k(e=>{if(R==="drop")return e;let r=new URLSearchParams(e.toString()),a=B();for(let[s,t]of a)r.append(s,t);return r},[R,B]),_=(e,r)=>Array.isArray(e)&&Array.isArray(r)?e.length!==r.length?!1:e.every((a,s)=>a===r[s]):e===r,C=N(()=>Object.keys(m).filter(e=>Array.isArray(m[e])),[m]),Z=(e,r)=>{let a={...e};return C.length===0||C.forEach(s=>{let t=[];switch(l){case"csv":{t=(i.get(s)||"").split(",").map(o=>o.trim()).filter(Boolean);break}case"repeat":{let n=i.getAll(s);t=n.length>0?n:[];break}case"brackets":{let n=i.getAll(`${s}[]`);t=n.length>0?n:[];break}default:t=(i.get(s)??"").split(",").map(o=>o.trim()).filter(Boolean)}if(r[s]!==void 0){let n=r[s],o=[];typeof n=="string"?o=t.includes(n)?t.filter(u=>u!==n):[...t,n]:Array.isArray(n)?o=Array.from(new Set([...n.map(String)])):o=t,a[s]=o}}),a},d=e=>{let r=new URLSearchParams,a=Object.keys(e);for(let s of a){let t=F[s];if(t?.serialize){let n=t.serialize(e[s],{key:s});if(n==null)continue;if(Array.isArray(n))if(Array.isArray(m[s]))if(l==="csv")r.set(s,n.join(","));else if(l==="repeat")for(let o of n)r.append(s,String(o));else for(let o of n)r.append(`${s}[]`,String(o));else n.length>0&&r.set(s,String(n[0]));else r.set(s,String(n));continue}if(Array.isArray(m[s])){let n=e[s];switch(l){case"csv":{r.set(s,n.join(","));break}case"repeat":{for(let o of n)r.append(s,String(o));break}case"brackets":{for(let o of n)r.append(`${s}[]`,String(o));break}default:r.set(s,n.join(","))}}else r.set(s,String(e[s]))}return r},w=(e,r)=>Object.prototype.hasOwnProperty.call(g,e)?g[e]:Object.prototype.hasOwnProperty.call(f,e)?f[e]:r,W=({paramsForced:e,compareParams:r})=>Object.entries(e).every(([s,t])=>r[s]===t),x=e=>{let r=X(e),a=F[e];if(a?.parse)return a.parse(r,{key:e,searchParams:i});if(typeof m[e]=="number"){let s=Number.parseInt(String(r??""),10);if(Number.isNaN(s)){let t=w(e,0);return typeof t=="number"?t:0}return s}return typeof m[e]=="boolean"?String(r)==="true":Array.isArray(m[e])?l==="csv"?String(r??"").split(",").filter(Boolean):Array.isArray(r)?r:r?[r]:[]:Array.isArray(r)?r[0]??"":r??""},$=(e,r)=>{if(Array.isArray(m[e])){if(l==="brackets"){let t=i.getAll(`${e}[]`),n=d({[e]:t}).toString();return decodeURIComponent(n)}if(l==="csv"){let t=i.getAll(e),n=d({[e]:t}).toString();return decodeURIComponent(n)}let s=i.getAll(e);return d({[e]:s}).toString()}return r[e]},z=e=>{let r={};for(let[a,s]of e.entries())if(a.endsWith("[]")){let t=a.replace("[]","");r[t]?r[t].push(s):r[t]=[s]}else r[a]?Array.isArray(r[a])?r[a].push(s):r[a]=[r[a],s]:r[a]=s;return r},v=N(()=>l==="brackets"?z(i):Object.fromEntries(i.entries()),[i,l]),K=({convert:e=!0}={})=>Object.keys(v).reduce((a,s)=>{if(Object.prototype.hasOwnProperty.call(m,s)){let t=l==="brackets"?s.replace("[]",""):s;a[t]=e===!0?x(t):$(s,v)}return a},{}),O=(e,r)=>{let a=String(e);return r?.convert!==!1?x(a):$(a,v)},ee=e=>e==null||typeof e!="object"?!1:Object.prototype.hasOwnProperty.call(e,"newParams")||Object.prototype.hasOwnProperty.call(e,"keepParams")||Object.prototype.hasOwnProperty.call(e,"historyMode"),re=e=>{let r=K({convert:!0});if(typeof e=="function"){let a=e(r);return ee(a)?{newParams:typeof a.newParams=="function"?a.newParams(r):a.newParams??{},keepParams:a.keepParams??{},historyMode:a.historyMode}:{newParams:a,keepParams:{},historyMode:void 0}}return e?{newParams:typeof e.newParams=="function"?e.newParams(r):e.newParams??{},keepParams:e.keepParams??{},historyMode:e.historyMode}:{newParams:{},keepParams:{},historyMode:void 0}},se=({currentParams:e,newParams:r,keepParams:a})=>{let s={...r},t={...a};for(let[n,o]of Object.entries(G))if(!(!o||o.length===0||!Object.prototype.hasOwnProperty.call(s,n)||_(s[n],e[n]))){for(let c of o)if(!Object.prototype.hasOwnProperty.call(y,c)){if(Object.prototype.hasOwnProperty.call(g,c)){s[c]=g[c],delete t[c];continue}if(Object.prototype.hasOwnProperty.call(f,c)){s[c]=f[c],delete t[c];continue}delete s[c],t[c]=!1}}return{newParams:s,keepParams:t}},ae=(e,r)=>{let a=K(),s=Object.entries(e).filter(([o])=>!Array.isArray(m[o])),t=Object.assign({...a,...Object.fromEntries(s)},y),n=Object.keys(t).reduce((o,u)=>{if(Object.prototype.hasOwnProperty.call(r,u)&&r[u]===!1)return o;let c=t[u],h=typeof c=="string"&&q.includes(c);return c!=null&&c!==""&&!h&&(o[u]=c),o},{});return{...g,...n}},te=e=>J.reduce((a,s)=>(Object.prototype.hasOwnProperty.call(e,s)&&(a[s]=e[s]),a),{}),ne=()=>{let e=C.length>0,r=K({convert:e});return Object.keys(r).reduce((s,t)=>(Object.prototype.hasOwnProperty.call(g,t)&&(s[t]=r[t]),s),{})},D=({keepMandatoryParams:e=!0,historyMode:r}={})=>{let a=d({...g,...e&&{...ne()},...y}),s=H(a);I(s,r)},P=e=>{let r=re(e),a=K({convert:!0}),s=se({currentParams:a,newParams:r.newParams,keepParams:r.keepParams}),t=s.newParams,n=s.keepParams;if(Object.keys(t).length===0&&Object.keys(n).length===0){D({historyMode:r.historyMode});return}let o=ae(t,n),u=Z(o,t),c=te(u),h=d(c),T=H(h);I(T,r.historyMode)},b=p?.mode==="page"?p:void 0,M=p?.mode==="offset"?p:void 0,S=p?.mode==="cursor"?p:void 0,oe={mode:p?.mode??"page",next:e=>{let r=p?.mode??"page";if(r==="cursor"){let n=S?.cursorKey??"cursor";typeof e=="string"&&P({newParams:{[n]:e}});return}if(r==="offset"){let n=M?.offsetKey??"offset",o=M?.limitKey??"limit",u=Number(O(n,{convert:!0})??0),c=Number(O(o,{convert:!0})??w(String(o),10)),h=Number.isFinite(u)?u:0,T=Number.isFinite(c)&&c>0?c:10;P({newParams:{[n]:h+T}});return}let a=b?b.pageKey??"page":"page",s=Number(O(a,{convert:!0})??w(String(a),1)),t=Number.isFinite(s)&&s>0?s:1;P({newParams:{[a]:t+1}})},prev:()=>{let e=p?.mode??"page";if(e==="cursor"){let t=S?.cursorKey??"cursor";P({keepParams:{[t]:!1}});return}if(e==="offset"){let t=M?.offsetKey??"offset",n=M?.limitKey??"limit",o=Number(O(t,{convert:!0})??0),u=Number(O(n,{convert:!0})??w(String(n),10)),c=Number.isFinite(o)?o:0,h=Number.isFinite(u)&&u>0?u:10;P({newParams:{[t]:Math.max(0,c-h)}});return}let r=b?b.pageKey??"page":"page",a=Number(O(r,{convert:!0})??w(String(r),1)),s=Number.isFinite(a)&&a>0?a:1;P({newParams:{[r]:Math.max(1,s-1)}})},reset:()=>{let e=p?.mode??"page";if(e==="cursor"){let s=S?.cursorKey??"cursor";P({keepParams:{[s]:!1}});return}if(e==="offset"){let s=M?.offsetKey??"offset",t=Number(w(String(s),0));P({newParams:{[s]:Number.isFinite(t)?t:0}});return}let r=b?b.pageKey??"page":"page",a=Number(w(String(r),1));P({newParams:{[r]:Number.isFinite(a)&&a>0?a:1}})},setCursor:e=>{let a=(p?.mode??"page")==="cursor"?S?.cursorKey??"cursor":"cursor";if(e==null||e===""){P({keepParams:{[a]:!1}});return}P({newParams:{[a]:e}})}},ce=k((e,r)=>{let a=String(e);return j.current[a]=r,()=>{delete j.current[a],delete U.current[a]}},[]);return Q(()=>{for(let[e,r]of Object.entries(j.current)){let a=A(e)?x(e):i.get(e),s=U.current[e]??null;if(!_(a,s))for(let t of r)t({key:e,previousValue:s,currentValue:a});U.current[e]=a}},[v,A,i]),Q(()=>{let e=Object.keys(f),r=Object.keys(y);if(e.length===0&&r.length===0)return;function a(){let s=d(f).toString(),t=K(),n=d(t).toString();if(!W({paramsForced:y,compareParams:t})){P({newParams:{...f,...y}});return}let u=W({paramsForced:y,compareParams:f});if(e.length>0&&u){if(s===n)return;P({newParams:f})}}a()},[]),{searchParams:i,updateParams:P,clearParams:D,getParams:K,getParam:O,onChange:ce,pagination:oe}};export{ue as useMagicSearchParams};
1
+ import{useSearchParams as ue}from"react-router-dom";import{useMemo as C,useEffect as q,useRef as G,useCallback as k}from"react";var Pe=({mandatory:l={},optional:V={},defaultParams:g={},arraySerialization:p="csv",forceParams:d={},omitParamsByValues:J=[],coerceParams:F={},codecs:E={},historyMode:L="push",resetOnChange:X={},paginationStrategy:f,unknownParamsPolicy:R="drop"})=>{let[i,I]=ue(),T=G({}),j=G({}),B=k((r,e)=>{I(r,{replace:(e??L)==="replace"})},[I,L]),u=C(()=>({...l,...V}),[l,V]),Z=C(()=>Array.from(Object.keys(u)),[u]),A=k(r=>Object.prototype.hasOwnProperty.call(u,r),[u]),z=r=>!Array.isArray(u[r])||p==="csv"?i.get(r):p==="repeat"?i.getAll(r):i.getAll(`${r}[]`),H=k(()=>{if(R==="drop")return[];let r=[];for(let[e,a]of i.entries()){let s=e.endsWith("[]")?e.replace("[]",""):e;A(s)||r.push([e,a])}return r},[R,i,A]),_=k(r=>{if(R==="drop")return r;let e=new URLSearchParams(r.toString()),a=H();for(let[s,t]of a)e.append(s,t);return e},[R,H]),W=(r,e)=>Array.isArray(r)&&Array.isArray(e)?r.length!==e.length?!1:r.every((a,s)=>a===e[s]):r===e,x=C(()=>Object.keys(u).filter(r=>Array.isArray(u[r])),[u]),ee=(r,e)=>{let a={...r};return x.length===0||x.forEach(s=>{let t=[];switch(p){case"csv":{t=(i.get(s)||"").split(",").map(o=>o.trim()).filter(Boolean);break}case"repeat":{let n=i.getAll(s);t=n.length>0?n:[];break}case"brackets":{let n=i.getAll(`${s}[]`);t=n.length>0?n:[];break}default:t=(i.get(s)??"").split(",").map(o=>o.trim()).filter(Boolean)}if(e[s]!==void 0){let n=e[s],o=[];typeof n=="string"?o=t.includes(n)?t.filter(m=>m!==n):[...t,n]:Array.isArray(n)?o=Array.from(new Set([...n.map(String)])):o=t,a[s]=o}}),a},w=r=>{let e=new URLSearchParams,a=Object.keys(r);for(let s of a){let t=E[s];if(t?.serialize){let n=t.serialize(r[s],{key:s});if(n==null)continue;if(Array.isArray(n))if(Array.isArray(u[s]))if(p==="csv")e.set(s,n.join(","));else if(p==="repeat")for(let o of n)e.append(s,String(o));else for(let o of n)e.append(`${s}[]`,String(o));else n.length>0&&e.set(s,String(n[0]));else e.set(s,String(n));continue}if(Array.isArray(u[s])){let n=r[s];switch(p){case"csv":{e.set(s,n.join(","));break}case"repeat":{for(let o of n)e.append(s,String(o));break}case"brackets":{for(let o of n)e.append(`${s}[]`,String(o));break}default:e.set(s,n.join(","))}}else e.set(s,String(r[s]))}return e},y=(r,e)=>Object.prototype.hasOwnProperty.call(l,r)?l[r]:Object.prototype.hasOwnProperty.call(g,r)?g[r]:e,$=({paramsForced:r,compareParams:e})=>Object.entries(r).every(([s,t])=>e[s]===t),U=r=>{let e=z(r),a=E[r];if(a?.parse)return a.parse(e,{key:r,searchParams:i});let s=F[r];if(s==="number"){let t=Number.parseInt(String(e??""),10);if(Number.isNaN(t)){let n=y(r,0);return typeof n=="number"?n:0}return t}if(s==="boolean")return String(e)==="true";if(s==="array")return p==="csv"?String(e??"").split(",").filter(Boolean):Array.isArray(e)?e:e?[e]:[];if(s==="string")return Array.isArray(e)?e[0]??"":e??"";if(typeof u[r]=="number"){let t=Number.parseInt(String(e??""),10);if(Number.isNaN(t)){let n=y(r,0);return typeof n=="number"?n:0}return t}return typeof u[r]=="boolean"?String(e)==="true":Array.isArray(u[r])?p==="csv"?String(e??"").split(",").filter(Boolean):Array.isArray(e)?e:e?[e]:[]:Array.isArray(e)?e[0]??"":e??""},D=(r,e)=>{let a=F[r];if(!a)return e;if(a==="boolean")return typeof e=="boolean"?e:String(e??"")==="true";if(a==="number"){if(typeof e=="number"&&Number.isFinite(e))return e;let s=Number.parseInt(String(e??""),10);if(Number.isNaN(s)){let t=y(r,0);return typeof t=="number"?t:0}return s}return a==="array"?Array.isArray(e)?e:e==null||e===""?[]:[String(e)]:a==="string"?Array.isArray(e)?e[0]??"":e==null?"":String(e):e},Q=(r,e)=>{if(Array.isArray(u[r])){if(p==="brackets"){let t=i.getAll(`${r}[]`),n=w({[r]:t}).toString();return decodeURIComponent(n)}if(p==="csv"){let t=i.getAll(r),n=w({[r]:t}).toString();return decodeURIComponent(n)}let s=i.getAll(r);return w({[r]:s}).toString()}return e[r]},re=r=>{let e={};for(let[a,s]of r.entries())if(a.endsWith("[]")){let t=a.replace("[]","");e[t]?e[t].push(s):e[t]=[s]}else e[a]?Array.isArray(e[a])?e[a].push(s):e[a]=[e[a],s]:e[a]=s;return e},N=C(()=>p==="brackets"?re(i):Object.fromEntries(i.entries()),[i,p]),K=({convert:r=!0}={})=>Object.keys(N).reduce((a,s)=>{if(Object.prototype.hasOwnProperty.call(u,s)){let t=p==="brackets"?s.replace("[]",""):s;if(r===!0){let n=U(t);a[t]=D(t,n)}else a[t]=Q(s,N)}return a},{}),O=(r,e)=>{let a=String(r);return e?.convert!==!1?D(a,U(a)):Q(a,N)},se=r=>r==null||typeof r!="object"?!1:Object.prototype.hasOwnProperty.call(r,"newParams")||Object.prototype.hasOwnProperty.call(r,"keepParams")||Object.prototype.hasOwnProperty.call(r,"historyMode"),ae=r=>{let e=K({convert:!0});if(typeof r=="function"){let a=r(e);return se(a)?{newParams:typeof a.newParams=="function"?a.newParams(e):a.newParams??{},keepParams:a.keepParams??{},historyMode:a.historyMode}:{newParams:a,keepParams:{},historyMode:void 0}}return r?{newParams:typeof r.newParams=="function"?r.newParams(e):r.newParams??{},keepParams:r.keepParams??{},historyMode:r.historyMode}:{newParams:{},keepParams:{},historyMode:void 0}},te=({currentParams:r,newParams:e,keepParams:a})=>{let s={...e},t={...a};for(let[n,o]of Object.entries(X))if(!(!o||o.length===0||!Object.prototype.hasOwnProperty.call(s,n)||W(s[n],r[n]))){for(let c of o)if(!Object.prototype.hasOwnProperty.call(d,c)){if(Object.prototype.hasOwnProperty.call(l,c)){s[c]=l[c],delete t[c];continue}if(Object.prototype.hasOwnProperty.call(g,c)){s[c]=g[c],delete t[c];continue}delete s[c],t[c]=!1}}return{newParams:s,keepParams:t}},ne=(r,e)=>{let a=K(),s=Object.entries(r).filter(([o])=>!Array.isArray(u[o])),t=Object.assign({...a,...Object.fromEntries(s)},d),n=Object.keys(t).reduce((o,m)=>{if(Object.prototype.hasOwnProperty.call(e,m)&&e[m]===!1)return o;let c=t[m],b=typeof c=="string"&&J.includes(c);return c!=null&&c!==""&&!b&&(o[m]=c),o},{});return{...l,...n}},oe=r=>Z.reduce((a,s)=>(Object.prototype.hasOwnProperty.call(r,s)&&(a[s]=r[s]),a),{}),ce=()=>{let r=x.length>0,e=K({convert:r});return Object.keys(e).reduce((s,t)=>(Object.prototype.hasOwnProperty.call(l,t)&&(s[t]=e[t]),s),{})},Y=({keepMandatoryParams:r=!0,historyMode:e}={})=>{let a=w({...l,...r&&{...ce()},...d}),s=_(a);B(s,e)},P=r=>{let e=ae(r),a=K({convert:!0}),s=te({currentParams:a,newParams:e.newParams,keepParams:e.keepParams}),t=s.newParams,n=s.keepParams;if(Object.keys(t).length===0&&Object.keys(n).length===0){Y({historyMode:e.historyMode});return}let o=ne(t,n),m=ee(o,t),c=oe(m),b=w(c),v=_(b);B(v,e.historyMode)},h=f?.mode==="page"?f:void 0,M=f?.mode==="offset"?f:void 0,S=f?.mode==="cursor"?f:void 0,ie={mode:f?.mode??"page",next:r=>{let e=f?.mode??"page";if(e==="cursor"){let n=S?.cursorKey??"cursor";typeof r=="string"&&P({newParams:{[n]:r}});return}if(e==="offset"){let n=M?.offsetKey??"offset",o=M?.limitKey??"limit",m=Number(O(n,{convert:!0})??0),c=Number(O(o,{convert:!0})??y(String(o),10)),b=Number.isFinite(m)?m:0,v=Number.isFinite(c)&&c>0?c:10;P({newParams:{[n]:b+v}});return}let a=h?h.pageKey??"page":"page",s=Number(O(a,{convert:!0})??y(String(a),1)),t=Number.isFinite(s)&&s>0?s:1;P({newParams:{[a]:t+1}})},prev:()=>{let r=f?.mode??"page";if(r==="cursor"){let t=S?.cursorKey??"cursor";P({keepParams:{[t]:!1}});return}if(r==="offset"){let t=M?.offsetKey??"offset",n=M?.limitKey??"limit",o=Number(O(t,{convert:!0})??0),m=Number(O(n,{convert:!0})??y(String(n),10)),c=Number.isFinite(o)?o:0,b=Number.isFinite(m)&&m>0?m:10;P({newParams:{[t]:Math.max(0,c-b)}});return}let e=h?h.pageKey??"page":"page",a=Number(O(e,{convert:!0})??y(String(e),1)),s=Number.isFinite(a)&&a>0?a:1;P({newParams:{[e]:Math.max(1,s-1)}})},reset:()=>{let r=f?.mode??"page";if(r==="cursor"){let s=S?.cursorKey??"cursor";P({keepParams:{[s]:!1}});return}if(r==="offset"){let s=M?.offsetKey??"offset",t=Number(y(String(s),0));P({newParams:{[s]:Number.isFinite(t)?t:0}});return}let e=h?h.pageKey??"page":"page",a=Number(y(String(e),1));P({newParams:{[e]:Number.isFinite(a)&&a>0?a:1}})},setCursor:r=>{let a=(f?.mode??"page")==="cursor"?S?.cursorKey??"cursor":"cursor";if(r==null||r===""){P({keepParams:{[a]:!1}});return}P({newParams:{[a]:r}})}},me=k((r,e)=>{let a=String(r);return T.current[a]=e,()=>{delete T.current[a],delete j.current[a]}},[]);return q(()=>{for(let[r,e]of Object.entries(T.current)){let a=A(r)?U(r):i.get(r),s=j.current[r]??null;if(!W(a,s))for(let t of e)t({key:r,previousValue:s,currentValue:a});j.current[r]=a}},[N,A,i]),q(()=>{let r=Object.keys(g),e=Object.keys(d);if(r.length===0&&e.length===0)return;function a(){let s=w(g).toString(),t=K(),n=w(t).toString();if(!$({paramsForced:d,compareParams:t})){P({newParams:{...g,...d}});return}let m=$({paramsForced:d,compareParams:g});if(r.length>0&&m){if(s===n)return;P({newParams:g})}}a()},[]),{searchParams:i,updateParams:P,clearParams:Y,getParams:K,getParam:O,onChange:me,pagination:ie}};export{Pe as useMagicSearchParams};
package/package.json CHANGED
@@ -24,7 +24,7 @@
24
24
  "pagination",
25
25
  "sorting"
26
26
  ],
27
- "version": "2.1.2",
27
+ "version": "2.2.3",
28
28
  "private": false,
29
29
  "license": "MIT",
30
30
  "main": "dist/index.cjs",
@@ -45,12 +45,14 @@
45
45
  "typecheck": "tsc --noEmit",
46
46
  "build": "tsup",
47
47
  "test": "vitest run --environment jsdom",
48
+ "test:dist": "vitest run --environment jsdom test/useMagicSearchParams.dist.test.tsx",
48
49
  "test:watch": "vitest --environment jsdom",
49
50
  "lint": "tsc --noEmit",
50
51
  "prepare": "tsup",
52
+ "prepublishOnly": "pnpm run typecheck && pnpm test && pnpm run build && pnpm run test:dist",
51
53
  "size": "size-limit",
52
54
  "analyze": "size-limit --why",
53
- "prepack": "node -e \"const fs=require('fs');fs.copyFileSync('README.md','.README.repo.md');fs.copyFileSync('README_NPM.md','README.md');\"",
55
+ "prepack": "pnpm run build && node -e \"const fs=require('fs');fs.copyFileSync('README.md','.README.repo.md');fs.copyFileSync('README_NPM.md','README.md');\"",
54
56
  "postpack": "node -e \"const fs=require('fs');if(fs.existsSync('.README.repo.md')){fs.copyFileSync('.README.repo.md','README.md');fs.unlinkSync('.README.repo.md');}\""
55
57
  },
56
58
  "peerDependencies": {